Julia编程基础

技术背景

Julia目前来说算是一个比较冷门的编程语言,主要是因为它所针对的应用场景实在是比较有限,Julia更注重于科学计算领域的应用。而Julia最大的特点,就是官方所宣传的:拥有C的性能,且可以像Python一样便捷的开发。这对于科学计算领域来说确实是一件好事,目前也有一些科学领域的应用,但是毕竟赶了个晚集。在生态上必然是没有Python丰富,而又缺少C语言的受众基础,所以现在甚至知道的人也并不多。但是这并不影响我们用不同的编程语言,去做一些场景更加契合的应用。本文主要介绍Julia编程语言的基本使用与安装。

Julia的安装与配置

在Ubuntu上安装Julia

我们需要先从官网下载一个installer进行安装:

$ curl -fsSL https://install.julialang.org | sh

info: downloading installer
Welcome to Julia!

This will download and install the official Julia Language distribution
and its version manager Juliaup.

Juliaup will be installed into the Juliaup home directory, located at:

  /home/dechin/.juliaup

The julia, juliaup and other commands will be added to
Juliaup's bin directory, located at:

  /home/dechin/.juliaup/bin

This path will then be added to your PATH environment variable by
modifying the profile files located at:

  /home/dechin/.bashrc
  /home/dechin/.profile
  /home/dechin/.zshrc

Julia will look for a new version of Juliaup itself every 1440 minutes when you start julia.

You can uninstall at any time with juliaup self uninstall and these
changes will be reverted.

✔ Do you want to install with these default configuration choices? · Proceed with installation

Now installing Juliaup
Installing Julia 1.10.0+0.x64.linux.gnu
Configured the default Julia version to be 'release'.
Julia was successfully installed on your system.

Depending on which shell you are using, run one of the following
commands to reload the PATH environment variable:

  . /home/dechin/.bashrc
  . /home/dechin/.profile
  . /home/dechin/.zshrc

安装完成后,如果在terminal里面输入julia并回车,可以看到如下界面:

$ julia
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.4.1
 _/ |\__'_|_|_|\__'_|  |  Ubuntu ⛬  julia/1.4.1+dfsg-1
|__/                   |

julia> π
π = 3.1415926535897...

julia> exit()

Julia的终端界面跟Python的非常类似,但是多了一些比较人性化的操作。比如我们输入\pi然后按一下Tab键,终端上面的这几个字符就会变成π,这个操作支持所有的希腊字母。退出Julia的终端,使用的是exit()命令。

配置镜像源

由于国内网络环境的问题,一般情况下建议是配置一个国内的镜像源,这样在安装第三方库的时候不会网络受限。

export JULIA_PKG_SERVER="https://pkg.julialang.org"

安装第三方Package

这里以CUDA.jl的安装为例,先加载Pkg包管理工具,然后在Julia的终端中使用Pkg.add("CUDA")即可自动完成安装。

julia> import Pkg; Pkg.add("CUDA")
...
Downloaded artifact: CUDA_Runtime
Precompiling project...
  64 dependencies successfully precompiled in 77 seconds. 5 already precompiled.

安装完成后,可以直接using CUDA来进行调用:

julia> using CUDA

julia> CUDA.versioninfo()
CUDA runtime 12.3, artifact installation
CUDA driver 12.3
NVIDIA driver 525.147.5, originally for CUDA 12.0

CUDA libraries: 
- CUBLAS: 12.3.4
- CURAND: 10.3.4
- CUFFT: 11.0.12
- CUSOLVER: 11.5.4
- CUSPARSE: 12.2.0
- CUPTI: 21.0.0
- NVML: 12.0.0+525.147.5

Julia packages: 
- CUDA: 5.1.2
- CUDA_Driver_jll: 0.7.0+1
- CUDA_Runtime_jll: 0.10.1+0

Toolchain:
- Julia: 1.10.0
- LLVM: 15.0.7

2 devices:
  0: Quadro RTX 4000 (sm_75, 6.826 GiB / 8.000 GiB available)
  1: Quadro RTX 4000 (sm_75, 7.779 GiB / 8.000 GiB available)

Vim插件

一般情况下用VSCode和Atom+Juno这两种IDE进行Julia编程的会多一些,我个人倾向于使用VSCode,这里就不过多的介绍相关的安装方法,一般应用商城里面都会有。但是这里介绍一个有意思的Julia-Vim插件,这个插件可以在使用Vim编辑.jl文件时,起到一个类似于Julia终端的操作,比如Tab自动生成希腊字母。

如果网络条件好的话,可以直接从julia-vim的github仓库下载。网络条件不好的话,可以在国内的Gitee的这个同步仓库中下载和安装相关插件:

$ git clone https://gitee.com/mirrors_JuliaEditorSupport/julia-vim.git
$ mkdir -p ~/.vim
$ cp -R julia-vim/* ~/.vim

下载完以后可以用vim打开一个.jl的文件,然后输入如下字符串:

\beta

再按一下Tab,就会变成:

β

Julia的Hello World

对于每一个新学习编程语言的人来说,第一个程序总是一个Hello World。Julia的Hello World跟Python的非常类似,语法简单,不需要定义main函数:

## print_func.jl
w = "World"
println("Hello $(w)!")

运行方式是在Bash终端下使用Julia xxx.jl来执行:

$ julia print_func.jl 
Hello World!

基本数据类型

单变量数据类型

单变量我们主要就是关注Int整数、Float浮点数和String字符串这些基本类型,在Julia中可以使用typeof函数来查看一个变量的数据类型:

x = 10
println("$(x): $(typeof(x))")

x = 0x10
println("$(x): $(typeof(x))")

x = 10.
println("$(x): $(typeof(x))")

x = "10."
println("$(x): $(typeof(x))")

x = typemax(Int64) + 1
println("$(x): $(typeof(x))")

x = BigInt(typemax(Int64)) + 1
println("$(x): $(typeof(x))")

在不指定数据类型的情况下,默认一般都是用的64位整数和64位浮点数,上述代码的运行结果如下:

10: Int64
16: UInt8
10.0: Float64
10.: String
-9223372036854775808: Int64
9223372036854775808: BigInt

但是我们也可以通过指定数据类型来定义一个数据:

x::Int8 = 10
println("$(x): $(typeof(x))")

这样一来,我们就得到一个Int8类型的整形变量:

10: Int8

数组和矩阵

Julia的数组定义起来跟Python的列表非常的相似,但是这里需要注意的是,在定义数组时,元素之间加不加逗号,得到的结果完全是不一样的:

x = [1, 2, 3]
println("$(x): $(typeof(x)), $(size(x))")

x = [1 2 3]
println("$(x): $(typeof(x)), $(size(x))")

x = [[1], [2], [3]]
println("$(x): $(typeof(x)), $(size(x))")

运行结果如下:

[1, 2, 3]: Vector{Int64}, (3,)
[1 2 3]: Matrix{Int64}, (1, 3)
[[1], [2], [3]]: Vector{Vector{Int64}}, (3,)

除了逗号的这个区别之外,Julia中的size函数返回的是这个数组的shape,而Python的Numpy中的size函数返回的是这个数组的元素的总个数,而shape就是通过shape参量来返回的。

基础运算

一门语言的基础运算,无非就是加减乘除、求余数和求商,这里就简单的介绍一下:

y = 3.
z = 2

res = y + z
println("$(res): $(typeof(res))")

res = y - z
println("$(res): $(typeof(res))")

res = z * z
println("$(res): $(typeof(res))")

res = z / z
println("$(res): $(typeof(res))")

res = z ÷ y
println("$(res): $(typeof(res))")

res = z % y
println("$(res): $(typeof(res))")

说来也奇怪,在Python中我们定义整除用的是两条斜杠://,而Julia里面用/÷两个不同的符号来进行区分。说起来我还真不知道怎么在键盘上翘楚这个除以号,在Julia的终端窗口里面可以用类似于latex的语法来定义,先输入\div,然后按Tab键,就可以输出这样的一个符号,想来是有一点点特立独行。上述代码的输出结果如下:

5.0: Float64
1.0: Float64
4: Int64
1.0: Float64
0.0: Float64
2.0: Float64

在不同类型的变量进行计算时,Julia会自动将其转化为同类型计算,这一点跟Python也是一致的,但是据说类型转换也会消耗一定的时间。类似于单变量的操作,接下来看看多变量数组的基础运算功能。在对数组进行操作时,我们需要在操作符号前加上一个.,比如.+,就表示对每一个数组元素进行加法的操作,具体示例如下所示:

x = [1, 2, 3]
y = 3.
z = 2

res = x .+ z
println("$(res): $(typeof(res))")

res = x .- y
println("$(res): $(typeof(res))")

res = x .* x
println("$(res): $(typeof(res))")

res = x ./ y
println("$(res): $(typeof(res))")

res = float(x) .^ -z
println("$(res): $(typeof(res))")

输出的结果为:

[3, 4, 5]: Vector{Int64}
[-2.0, -1.0, 0.0]: Vector{Float64}
[1, 4, 9]: Vector{Int64}
[0.3333333333333333, 0.6666666666666666, 1.0]: Vector{Float64}
[1.0, 0.25, 0.1111111111111111]: Vector{Float64}

这里又是跟Python不一样的地方,在Python中我们对数组操作时,并不需要加上额外的符号。并且,在Julia中的指数用的是latex中常用的^符号,而不是Python中的**符号。

判断与循环

复合表达式

首先说一个Julia中特别的复合表达式,这个跟Python中的lambda函数还不一样,这个功能只是把一些冗余的代码整合到一行,然后将所有的结果输出给一个变量,仅此而已。

res = begin x=2; y=3; x+y end
println("$(x): $(typeof(x))")
println("$(y): $(typeof(y))")
println("$(res): $(typeof(res))")

比较关键的是,这里复合表达式中所定义的变量,在整个变量空间中都是可见的,这是一个显著的区别,上述代码的输出结果如下:

2: Int64
3: Int64
5: Int64

条件判断

Julia的If条件判断在形式上跟Python也是很相似的,但是这里没有了冒号,多了一个end收尾,并且多层判断用的是elseif而不是elif。

x = 2.
y = 3

if x < y
    println("x is less than y")
elseif x > y
    println("x is greater than y")
else
    println("x is equal to y")
end

输出结果如下:

x is less than y

循环

一般编程都要关注一下while循环和for循环,但是这里我们仅关注一下for循环,因为相对而言for循环的可优化空间会更大一些,比如Jax中专门针对for循环的优化fori_loop这种。下面是第一种写法,类似于Python中的range函数:

for i = 1:3
    println(i)
end

输出结果如下:

1
2
3

这里关于变量空间还有一个比较特殊的情况,就是for循环中使用到的变量,在循环外是不可调用的。

for i = 1:3
    println(i)
end

println(i)

在上面这个案例中,for循环体内定义了i这个变量,但是在for循环外部打印的时候,就会报错:

1
2
3
ERROR: LoadError: UndefVarError: `i` not defined
Stacktrace:
 [1] top-level scope
   @ ~/tools/julia/tests/print_func.jl:5
in expression starting at /home/dechin/tools/julia/tests/print_func.jl:5

跟Python非常类似的,可以用in的语法来判断一个元素是否在某个数组内:

for i in [1,4,0]
    println(i)
end

输出结果如下:

1
4
0

而因为Julia对希腊字母的支持,所以我们可以用这种更加数学的方式来表达:

for i ∈ [1,4,0]
    println(i ∈ [2,4] ? 1 : 0)
end

输入这个符号也跟Latex语法保持一致,输入\in再按一下Tab即可。这个循环体中用到了一个比较简洁的判断语句,直接使用condition ?即可表示if condition,然后跟着的是Task while condition: Task while not condition。上述代码的输出结果如下:

0
1
0

这个程序遍历[1,4,0]这个数组,然后判断每一个元素是否属于[2,4]的数组内容,满足条件的话输出1,不满足条件就输出0

函数与变量

Julia的函数使用function关键字进行封装,并以end收尾,整体来说跟Python的def关键字的用法很相似。

x = 2.
y = 3

function test(x, y)
    if x < y
        println("x is less than y")
    elseif x > y
        println("x is greater than y")
    else
        println("x is equal to y")
    end
end

test(x, y)

输出结果为:

x is less than y

而Julia为了更加契合数学形式的定义,也支持了这种更方便的直接调用的方法:

x = 2.
y = 3

test(x, y) = println(x < y ? "x is less than y"    :
                     x > y ? "x is greater than y" : "x is equal to y")

test(x, y)

可以发现这个函数的功能跟前面多个判断语句的函数定义是一致的:

x is less than y

总结概要

本文介绍了Julia这一主要面向自然科学的编程语言的基本安装与使用,建议读者最好在熟练使用Python的前提下再阅读本文。如果是对Python的语法非常熟悉的人,应该很容易看懂本文并初步掌握Julia的基本语法和使用逻辑。Julia最吸引人的地方在于他简单如Python的语法,但兼具了C++和Fortran的高性能。但是缺点也非常明显,作为一门新的编程语言,受众又少,没有太多的轮子可以用。但是反过来想,也很适合用来开发一些新的轮子。

版权声明

本文首发链接为:https://www.cnblogs.com/dechinphy/p/julia-basic.html

作者ID:DechinPhy

更多原著文章:https://www.cnblogs.com/dechinphy/

请博主喝咖啡:https://www.cnblogs.com/dechinphy/gallery/image/379634.html

参考链接

  1. https://cn.julialang.org/JuliaZH.jl/latest/
posted @ 2024-01-22 19:11  DECHIN  阅读(196)  评论(1编辑  收藏  举报