Julia系列:编程初步
Julia中有两种向量,一种是类型统一的,另一种则可包含不同类型的变量,例如下面两个向量都是允许存在的
aNum = [1,2,3] # 类型为 3-element Vector{Int64}
aAny = [1.0, 1, "one"] # 类型为 3-element Vector{Any}
Julia通过方括号索引,下标从1开始
aNum[1] # 1
aAny[3] # "one"
由于向量中允许插入不同的数据类型,所以自然支持向量的嵌套
aMat = [[1,2], [3,4]] # 类型为 2-element Vector{Vector{Int64}}
在科学计算中,最重要的自然是数值向量。在Julia中,对于维度以及嵌套类型相同的向量,就可以自由地进行计算。但需要注意,如果想对所有元素执行相同的函数操作,必须在运算符前或者函数后面添加一个.
,比如
sin(aNum) # ❌报错
sin.(aNum) # 正确
aNum * aNum # ❌报错,因为两个都是列向量,没法做矩阵乘法
aNum .* aNum # 元素之间一对一的乘法
aNum + 1 # ❌报错,aNum和1的维度不同,无法相加
aNum .+ 1 # 得到[2, 3, 4]
Julia中,通过a:b:c
,可以生成从a到c生成间隔为b的等差数列,一般在循环时比较常用。例如
for i in 1:2:10
print(i, " ")
end
# 1 3 5 7 9
这种数列可以参与到向量计算中,如果在计算时破坏了其等差数列的特征,那么将自动转换为向量,此外通过collect函数,也可以将数列转为向量
aRange = 1:2:5
sin.(aRange) # 类型变为 3-element Vector{Float64}:
collect(aRange) # 类型变为向量
尽管向量嵌套也可以起到矩阵的作用,但Julia为矩阵设计了一套专门的生成方案。
在矩阵中,行间元素用空格隔开,列间元素用分号隔开;而由逗号生成的向量,则默认为列向量。下面生成一个 1 × 3 1\times3 1×3的矩阵,其实就是行向量,则可与前面的列向量做矩阵乘法
m1 = [1 2 3] # 1×3 Matrix{Int64}
m1 * aNum # 返回值 14
数列的表达式也可以被应用在矩阵中
[1:5 1:5] # 生成5行2列矩阵
[1:5; 1:5] # 生成10行1列矩阵
[1:5, 1:5] # 生成两个Range组成的向量
对于一列数据,Julia会称之为向量;如果有行有列,则会升级为矩阵;随着嵌套层级进一步增加,就会升级为数组。可以理解为,向量是一维数组,矩阵是二维数组。
Julia提供了一些函数,用以生成常用的数组,比较常用的有
分别用于生成全零向量、全一向量、[0,1]
区间的随机变量、服从标准正态分布的随机变量。这四个函数的输入参数均为数据类型T
和各数组维度,T默认为浮点数,维度默认为1。
zeros(3,3,3) # 返回值类型 3×3×3 Array{Float64, 3}
ones() # 返回值 1
如果想定制矩阵中的值,可以用fill
函数,其输入值分别是填充值和维度
julia> fill("Hi", 2,2)
2×2 Matrix{String}:
"Hi" "Hi"
"Hi" "Hi"
对于布尔代数,特别提供了连个函数用于生成全真或者全假的函数,二者的输入参数均为维度
Juli提供了一些基本的函数,用于检测数组的信息
k = 1
下表中,k
均为可选参数,省略时将返回所有维度的情况。
函数 | 返回值 | 备注 |
---|---|---|
eltype(aNum) | Int64 | 返回数据类型 |
length(aNum) | 3 | 数组长度 |
ndims(aNum) | 1 | 数组维度 |
size(aNum,k) | 3 | 第k个维度的元素个数 |
axes(aNum,k) | Base.OneTo(3) | 第k维有效索引 |
eachindex(aNum) | Base.OneTo(3) | 一个访问 A 中每一个位置的高效迭代器 |
stride(aNum,k) | 1 | 在第 k 维上的间隔 |
此外,更改数组维度也是必要需求,用函数reshape
完成
reshape(aNum, 1, 3) # 返回1x3矩阵 1 2 3
通过fill!
函数,可以更改数组中所有值
fill!(aNum, 0) # aNum变成[0,0,0]
如果在函数结尾出现了感叹号,那么说明函数输入的参数可能会在调用后发生变化。fill!并不仅仅返回一个更改后的数组,同时也将aNum的值改变了。Julia的这个规范可以说非常贴心了。