# 常用易混淆函数
# min 与 minimum 区别
min的函数声明:min(x, y, ...)例如:
min(2, 5, 1) # 返回 1minimum的函数声明:# 返回集合中最小元素 minimum(itr; [init]) # 对集合元素调用函数 f,并返回最小结果 minimum(f, itr; [init]) minimum(A::AbstractArray; dims) minimum(f, A::AbstractArray; dims)例如:
x = [1 3 5; 2 -4 6] #= 2×3 Matrix{Int64}: 1 3 5 2 -4 6 =# minimum(x) # 返回 -4,等价于 min(x...) minimum(x, dims=1) # 维度 1 上的最小值 #= 1×3 Matrix{Int64}: 1 -4 5 =# minimum(x, dims=2) # 维度 2 上的最小值 #= 2×1 Matrix{Int64}: 1 -4 =# minimum(abs, x, dims=2) # 维度 2 上的取绝对值最小值 #= 2×1 Matrix{Int64}: 1 2 =#
同理,max和maximum也是如此。
# && 与 & 区别
在 Julia 中,&&表示短路与(逻辑运算),&表示按位与(按位运算)。而在 Matlab 中,&&表示短路与(逻辑运算),&表示逻辑与,而bitand表示按位与(按位运算)。
# 报错:要求 bool 表达式
1 && 2
# ERROR: TypeError: non-boolean (Int64) used in boolean context
(1!=0) && (2!=0)
# true
# 按位运算,等价于Matlab的 bitand(1,2)
1 & 2
# 0
同理,在 Julia 中,||表示短路或(逻辑运算),|表示按位或(按位运算)。而在 Matlab 中,||表示短路或(逻辑运算),|表示逻辑或,而bitor才表示按位或(按位运算)。
# / 与 \ 区别
对于标量而言,/表示除法,\表示反向除法。例如:
5/2
# 2.5
5\2
# 0.4
5\2 == 2/5
# true
对于矩阵而言:
A / B 表示求解关于 X 的线性方程组 A = X*B。计算结果等同于
A*inv(B),但性能更高。A = Float64[1 4 5; 3 9 2] B = Float64[1 4 2; 3 4 2; 8 7 1] X = A/B #= 2×3 Matrix{Float64}: -0.65 3.75 -1.2 3.25 -2.75 1.0 =# A*inv(B) #= 2×3 Matrix{Float64}: -0.65 3.75 -1.2 3.25 -2.75 1.0 =#A \ B 表示求解关系 X 的线性方程组 A*X = B。计算结果等同
inv(A)*B,但性能更高。A = [1 0; 1 -2] B = [32; -4] X = A\B #= 2-element Vector{Float64}: 32.0 18.0 =# inv(A)*B #= 2-element Vector{Float64}: 32.0 18.0 =#
# 向量与行/列矩阵的区别
与 MATLAB 不同,Julia 在概念上就明确区分向量、行矩阵、列矩阵,且它们之间不支持自动转换,需要通过函数来显示转换。
# 向量与矩阵的声明
向量的声明为:
# 向量
v = [1,2,3]
#=
3-element Vector{Int64}:
1
2
3
=#
行矩阵的声明为:
# 行矩阵
r = [1 2 3]
#=
1×3 Matrix{Int64}:
1 2 3
=#
列矩阵的声明为:
# 列矩阵
c = [1;2;3;;] # 注意:末尾有2个分号
#=
3×1 Matrix{Int64}:
1
2
3
=#
矩阵的声明为:
# 2x3 矩阵
m = [1 2 3; 4 5 6]
#=
2×3 Matrix{Int64}:
1 2 3
4 5 6
=#
# 向量与矩阵的转换
向量与矩阵、多维数组之间,可以使用reshape、vec、collect等函数来实现相互转换。但是需要用户了解该行为背后究竟是数据拷贝还是引用,以免与预期行为不一致。具体可以参见各函数的帮助。
注,在 Julia 终端中,输入?函数名即可查看该函数的详细说明。
reshape转换使用
reshape可以改变数组维度,值得注意的是,转换前后的两个数组共享相同的底层数据。# 向量转矩阵 v = [1,2,3] v2 = reshape(v, 1,3) #= 1×3 Matrix{Int64}: 1 2 3 =# v2[1] = 10 # 由于 v2 与 v 共享相同的底层数据,所以 v 的数据也被改变 v #= 3-element Vector{Int64}: 10 2 3 =#vec转换使用
vec可以将数组转为一维向量,值得注意的是,转换前后的两个数组共享相同的底层数据。r = [1 2 3] r2 = vec(r) #= 3-element Vector{Int64}: 1 2 3 =# r2[1]=10 # 由于 r2 与 r 共享相同的底层数据,所以 r 的数据也被改变 r #= 1×3 Matrix{Int64}: 10 2 3 =#collect转换使用
collect可以将集合转为数组,如范围表达式转为向量。值得注意的是,collect会拷贝一份数据。x=1:3 x2=collect(x) #= 3-element Vector{Int64}: 1 2 3 =# x2[1]=10 # 由于 x2 是 x 的一份拷贝,所以x2改变,x不受影响 x # 1:3
# 转置、共轭、共轭转置的区别
在 Julia 中,存在共轭转换、转置、共轭等三种情况,包括:
- 共轭转置:
'、adjoint - 转置:
transpose - 共轭:
conj
# 共轭转置与转置的区别
对于实数矩阵,共轭转置与转置效果相同,例如:
# 实数矩阵
x=[1 2;3 4]
#=
2×2 Matrix{Int64}:
1 2
3 4
=#
# 共轭转置
x'
#=
2×2 adjoint(::Matrix{Int64}) with eltype Int64:
1 3
2 4
=#
# 转置
transpose(x)
#=
2×2 transpose(::Matrix{Int64}) with eltype Int64:
1 3
2 4
=#
对于复数矩阵,共轭转置与转置差异较大,例如:
A = reshape([x + im*x for x in 1:4], 2, 2)
#=
2×2 Matrix{Complex{Int64}}:
1+1im 3+3im
2+2im 4+4im
=#
# 共轭转置
A'
#=
2×2 adjoint(::Matrix{Complex{Int64}}) with eltype Complex{Int64}:
1-1im 2-2im
3-3im 4-4im
=#
# 转置
transpose(A)
#=
2×2 transpose(::Matrix{Complex{Int64}}) with eltype Complex{Int64}:
1+1im 2+2im
3+3im 4+4im
=#
# 共轭转置与共轭的区别
对于标量,共轭转置与共轭效果相同,例如:
x = 1+2im
# 共轭转置
x'
# 1 - 2im
# 共轭
conj(x)
# 1 - 2im
对于矩阵,共轭转置与共轭差异较大,例如:
A = reshape([x + im*x for x in 1:4], 2, 2)
#=
2×2 Matrix{Complex{Int64}}:
1+1im 3+3im
2+2im 4+4im
=#
# 共轭转置
A'
#=
2×2 adjoint(::Matrix{Complex{Int64}}) with eltype Complex{Int64}:
1-1im 2-2im
3-3im 4-4im
=#
# 共轭
conj(A)
#=
2×2 Matrix{Complex{Int64}}:
1-1im 3-3im
2-2im 4-4im
=#
# 拷贝 or 引用
对于共轭转置,转换后数组与转换前数组,两者共享相同的底层数据。
A = reshape([x + im*x for x in 1:4], 2, 2) #= 2×2 Matrix{Complex{Int64}}: 1+1im 3+3im 2+2im 4+4im =# B = A' # 共轭转置 #= 2×2 adjoint(::Matrix{Complex{Int64}}) with eltype Complex{Int64}: 1-1im 2-2im 3-3im 4-4im =# B[1,2]=10 # 修改 B 中元素,此时 A 也会被修改 A #= 2×2 Matrix{Complex{Int64}}: 1+1im 3+3im 10+0im 4+4im =#对于转置,转换后数组与转换前数组,两者共享相同的底层数据。
A = reshape([x + im*x for x in 1:4], 2, 2) #= 2×2 Matrix{Complex{Int64}}: 1+1im 3+3im 2+2im 4+4im =# B=transpose(A) # 转置 #= 2×2 transpose(::Matrix{Complex{Int64}}) with eltype Complex{Int64}: 1+1im 2+2im 3+3im 4+4im =# B[1,2]=10 # 修改 B 中元素,此时 A 也会被修改 A #= 2×2 Matrix{Complex{Int64}}: 1+1im 3+3im 10+0im 4+4im =#对于共轭,输入是实数还是复数,两者表现不一致,值得注意。
对于实数共轭,转换后数组与转换前数组,两者共享相同的底层数据。
x=[1 2 ;3 4] #= 2×2 Matrix{Int64}: 1 2 3 4 =# y = conj(x) # 实数共轭,此时是数据引用 #= 2×2 Matrix{Int64}: 1 2 3 4 =# y[1,2]=10 # 修改 y 中元素,x 也会被改变 10 x #= 2×2 Matrix{Int64}: 1 10 3 4 =#对于复数共轭,转换后数组与转换前数组,不共享底层数据,即数据拷贝。
x = ComplexF64[1 2; 3 4] #= 2×2 Matrix{ComplexF64}: 1.0+0.0im 2.0+0.0im 3.0+0.0im 4.0+0.0im =# y=conj(x) # 复数共轭,此时是数据拷贝 y[1,2]=10 # 修改 y 中元素,x 不会被改变 x #= 2×2 Matrix{ComplexF64}: 1.0+0.0im 2.0+0.0im 3.0+0.0im 4.0+0.0im =#