给现有文档增加了一堆例子:与其他语言的显著差异 · Julia中文文档
其他的 Matlab vs julia
-
Learn X in Y Minutes
-
MATLAB–Python–Julia cheatsheet — Cheatsheets by QuantEcon documentation
-
Rosetta Code
Note:
- 相对于文档,这里简单分了下类
- 有些条目较长,对条目进行了拆分与合并
- 输出放在注释里
- matlab:2014b x64
- julia:1.4.2 x64
julia 与 Matlab 的差异
线性代数
构造与拼接向量、多维数组
-
在 Julia 中
[x, y, z]
将始终构造一个包含x
、y
和z
的 3 元数组。
即:julia 不会自动展开数组
matlab[1, 2, 3] % 1 2 3 [1, [0 0], 3] % 1 0 0 3
julia
[1, 2, 3] # 3-element Array{Int64,1}: # 1 # 2 # 3 [1 2 3] # 1×3 Array{Int64,2}: # 1 2 3 [1, [0 0], 3] # 3-element Array{Any,1}: # 1 # [0 0] # 3 [1 [0 0] 3] # 1×4 Array{Int64,2}: # 1 0 0 3
【相似之处】数组的构造 与 数组的拼接
-
要在第一个维度「垂直列」中连接元素,请使用
vcat(x, y, z)
或用分号分隔[x; y; z]
matlab[1; 2; 3] % 1 % 2 % 3 a = [1 2]; [a; a; a] % 1 2 % 1 2 % 1 2
julia
[1; 2; 3] # 3-element Array{Int64,1}: # 1 # 2 # 3 a = [1 2]; vcat(a, a, a) # 3×2 Array{Int64,2}: # 1 2 # 1 2 # 1 2 [a; a; a] # 3×2 Array{Int64,2}: # 1 2 # 1 2 # 1 2
-
要在第二个维度「水平行」中连接元素,请使用
hcat(x, y, z)
或用空格分隔[x y z]
matlab[1 2 3] % 1 2 3 a = [1 2]; [a a a] % 1 2 1 2 1 2
julia
[1 2 3] # 1×3 Array{Int64,2}: # 1 2 3 a = [1 2]; hcat(a, a, a) # 1×6 Array{Int64,2}: # 1 2 1 2 1 2 [a a a] # 1×6 Array{Int64,2}: # 1 2 1 2 1 2
-
要在前两个维度中连接元素构造分块矩阵,请使用
hvcat
或组合使用空格和分号[a b; c d]
matlab[1 2; 3 4] % 1 2 % 3 4 a = [1 2]; b = [3 4]; [a a; b b] % 1 2 1 2 % 3 4 3 4
julia
[1 2; 3 4] # 2×2 Array{Int64,2}: # 1 2 # 3 4 a = [1 2]; b = [3 4]; [a a; b b] # 2×4 Array{Int64,2}: # 1 2 1 2 # 3 4 3 4 hvcat((4,4), a..., a..., b..., b...) # 2×4 Array{Int64,2}: # 1 2 1 2 # 3 4 3 4
-
-
Julia 拥有真正的一维数组
N-element Array{Float64,1}
,列向量的大小为 N,而不是 Nx1。
例如:rand(N)
创建一个一维数组。
matlabrand(3) % 0.8147 0.9134 0.2785 % 0.9058 0.6324 0.5469 % 0.1270 0.0975 0.9575 rand(3, 1) % 0.4218 % 0.9157 % 0.7922
julia
rand(3) # 3-element Array{Float64,1}: # 0.4672600683116248 # 0.09169094140222867 # 0.4042011717217615 rand(3, 1) # 3×1 Array{Float64,2}: # 0.06339164760309646 # 0.9777149900468021 # 0.6649767538620179 rand(3, 3) # 3×3 Array{Float64,2}: # 0.587354 0.422352 0.439107 # 0.528044 0.872661 0.374443 # 0.207286 0.356782 0.861222
数组索引
-
Julia 数组使用方括号
A[i, j]
进行索引
matlaba = [1 2 3; 4 5 6] % 1 2 3 % 4 5 6 a(1, 1) % 1
julia
a = [1 2 3; 4 5 6] # 2×3 Array{Int64,2}: # 1 2 3 # 4 5 6 a[1, 1] # 1
展开数组
-
类似于提取(或「解引用」)元胞数组的所有元素的操作。例如 MATLAB 中的
horzcat(A{:})
在 Julia 中是使用 splat 运算符(...
)编写的:hcat(A...)
。
matlabc = {1 2 3; 4 5 6} % [1] [2] [3] % [4] [5] [6] horzcat(c{:}) % 1 4 2 5 3 6
julia
a = [1 2 3; 4 5 6] # 2×3 Array{Int64,2}: # 1 2 3 # 4 5 6 hcat(a...) # 1×6 Array{Int64,2}: # 1 4 2 5 3 6
范围
-
在 Julia 中用
a:b
和a:b:c
来构造AbstractRange
对象。
matlab1:5 % 1 2 3 4 5 1:2:10 % 1 3 5 7 9
julia
collect(1:5) # 5-element Array{Int64,1}: # 1 # 2 # 3 # 4 # 5 1:2:10 # 1:2:9 collect(1:2:10) # 5-element Array{Int64,1}: # 1 # 3 # 5 # 7 # 9
数组的运算
-
在 Julia 中,像
sum
、prod
和max
等函数,以单参数调用时,即使数组A
是多维数组,规约操作也会逐元素进行。
matlaba = [1 2 3; 4 5 6] % 1 2 3 % 4 5 6 sum(a) % 5 7 9 prod(a) % 4 10 18 max(a) % 4 5 6
julia
a = [1 2 3; 4 5 6] # 2×3 Array{Int64,2}: # 1 2 3 # 4 5 6 sum(a) # 21 sum(a; dims=1) # 1×3 Array{Int64,2}: # 5 7 9 prod(a) # 720 prod(a; dims=1) # 1×3 Array{Int64,2}: # 4 10 18 max(a...) # 6 maximum(a; dims=1) # 1×3 Array{Int64,2}: # 4 5 6
-
在 Julia 中,如果 A 和 B 是数组,像
A == B
这样的逻辑比较运算符不会返回布尔值数组。
相反地,请使用A .== B
。对于其他的像<
、>
这样的的比较运算符同理。
matlaba = [1 2 3]; b = [4 5 6]; a == b % 0 0 0 all(a == b) % 0
julia
a = [1 2 3]; b = [4 5 6]; a == b # false a .== b # 1×3 BitArray{2}: # 0 0 0 all(a .== b) # false
-
在 Julia 中,运算符
&
、|
和⊻
(xor)进行按位操作,分别与 MATLAB 中的and
、or
和xor
等价,并且优先级与 Python 的按位运算符相似(不像 C)。
他们可以对标量运算或者数组中逐元素运算,可以用来合并逻辑数组。
matlaba = [true true false false] % 1 1 0 0 b = [true false true false] % 1 0 1 0 a & b % and(a, b) % 1 0 0 0 a | b % or(a, b) % 1 1 1 0 xor(a, a) % 0 0 0 0
julia
a = [true true false false] # 1×4 Array{Bool,2}: # 1 1 0 0 b = [true false true false] # 1×4 Array{Bool,2}: # 1 0 1 0 a .& b # 1×4 BitArray{2}: # 1 0 0 0 a .| b # 1×4 BitArray{2}: # 1 1 1 0 a .⊻ a # xor.(a, a) # 1×4 BitArray{2}: # 0 0 0 0
-
注意运算顺序的区别:括号可能是必要的。
例如:选择 A 中等于 1 或 2 的元素可使用(A .== 1) .| (A .== 2)
matlabA = [1 2 3 4]; (A == 1) | (A == 2) % 1 1 0 0 A( (A == 1) | (A == 2) ) % 1 2
julia
A = [1 2 3 4]; (A .== 1) .| (A .== 2) # 1×4 BitArray{2}: # 1 1 0 0 A[ (A .== 1) .| (A .== 2) ] # 2-element Array{Int64,1}: # 1 # 2 filter(y -> y==1 || y==2, A) # 2-element Array{Int64,1}: # 1 # 2
in-place 修改
-
在 MATLAB 中,删除不需要的值的惯用方法是使用逻辑索引
如表达式x(x>3)
或语句x(x>3) = []
来 in-place 修改 x
Julia 提供了更高阶的函数filter
和filter!
允许用户编写filter(z->z>3, x)
和filter!(z->z>3, x)
来代替相应直译x[x.>3]
和x = x[x.>3]
。
使用filter!
可以减少临时数组的使用
matlabA = [1 2 3 4]; A(A>3) % 4 A(A>3) = [] % A = 1 2 3
julia
A = [1, 2, 3, 4] # 4-element Array{Int64,1}: # 1 # 2 # 3 # 4 filter(y -> y > 3, A) # 1-element Array{Int64,1}: # 4 A # 4-element Array{Int64,1}: # 1 # 2 # 3 # 4 filter!(y -> y > 3, A) # 1-element Array{Int64,1}: # 4 A # 1-element Array{Int64,1}: # 4
变量赋值
-
Julia 的数组在赋值给另一个变量时不发生复制。
执行A = B
后,改变 B 中元素也会修改 A。 -
Julia 的值在向函数传递时不发生复制。
如果某个函数修改了数组,这一修改对调用者是可见的。
matlaba = [1 2 3] % a = 1 2 3 b = a % b = 1 2 3 b(2) = 0 % b = 1 0 3 a % a = 1 2 3
julia
a = [1 2 3] # 1×3 Array{Int64,2}: # 1 2 3 b = a # 1×3 Array{Int64,2}: # 1 2 3 b[2] = 0 # 0 a # 1×3 Array{Int64,2}: # 1 0 3 c = copy(a) # 1×3 Array{Int64,2}: # 1 0 3 c[2] = -1 # -1 c # 1×3 Array{Int64,2}: # 1 -1 3 a # 1×3 Array{Int64,2}: # 1 0 3
-
Julia 不会在赋值语句中自动增长数组。
而在 MATLAB 中a(4) = 3.2
可以创建数组a = [0 0 0 3.2]
而a(5) = 7
可以将它增长为a = [0 0 0 3.2 7]
在 julia 中,如果 a 的长度小于 5 或者是第一次使用标识符 a,则相应的语句a[5] = 7
会抛出错误
Julia 使用push!
和append!
来增长 Vector,它们比 MATLAB 的a(end+1) = val
更高效
matlaba = []; a(4) = 3.2 % a = 0 0 0 3.2000 a(5) = 7 % a = 0 0 0 0 7 a(end+1) = 10 % a = 0 0 0 0 7 10
julia
a = []; a[4] # ERROR: BoundsError: attempt to access 0-element Array{Any,1} at index [4] # Stacktrace... append!(a, [0 0 0]) # 3-element Array{Any,1}: # 0 # 0 # 0 push!(a, 3.2) # 4-element Array{Any,1}: # 0 # 0 # 0 # 3.2 push!(a, 7) # 5-element Array{Any,1}: # 0 # 0 # 0 # 3.2 # 7 push!(a, 10) # 6-element Array{Any,1}: # 0 # 0 # 0 # 3.2 # 7 # 10 a # 6-element Array{Any,1}: # 0 # 0 # 0 # 3.2 # 7 # 10
杂项
-
虚数单位 \sqrt{-1} 在 Julia 中表示为
im
,而不是在 MATLAB 中的 i 或 j
matlabsqrt(-1) % 0.0000 + 1.0000i i % 0.0000 + 1.0000i j % 0.0000 + 1.0000i i * i % -1 i * j % -1 i * i == sqrt(-1) % 0
julia
sqrt(-1) # ERROR: DomainError with -1.0: # sqrt will only return a complex result if called with a complex argument. Try sqrt(Complex(x)). # Stacktrace... sqrt(Complex(-1)) # 0.0 + 1.0im sqrt(-1 + 0im) # 0.0 + 1.0im im # im 1im # 0 + 1im im * im # -1 + 0im im * im == Complex(-1) # true
-
在 Julia 中,没有小数点的数字字面量(例如 42)会创建整数而不是浮点数
Julia 也支持任意大整数字面量。
因此,某些操作(如2^-1
)将抛出 domain error,因为结果不是整数
更多解释请参阅常见问题中有关 domain errors 的条目
【注:截止 2020/07/08,2^-1 == 0.5
有 bug】julia
42 # 42 typeof(42) # Int64 42.0 # 42.0 typeof(42.0) # Float64 big"42" # 42 typeof(big"42") # BigInt # domain errors 见上一个示例
函数
函数的参数
-
在 Julia 中,集合的元素可以使用 splat 运算符
...
来作为参数传递给函数,如xs=[1,2]; f(xs...)
juliaa = [1 2 3] # 1×3 Array{Int64,2}: # 1 2 3 println(a) # [1 2 3] println(a...) # 123
-
在 Julia 中不存在 MATLAB 的 nargout,它通常在 MATLAB 中用于根据返回值的数量执行可选工作。 取而代之的是,用户可以使用可选参数和关键字参数来实现类似的功能。
matlab:subtract.m
ref: Number of function output arguments - MATLAB nargoutfunction [dif,absdif] = subtract(y,x) dif = y-x; if nargout > 1 disp('Calculating absolute value') absdif = abs(dif); end end
matlab
subtract(5, 10) % -5 [diff, adiff] = subtract(10, 5) % Calculating absolute value % diff = -5 % adiff = 5
julia
function subtract(y, x; absdif = false) dif = y - x if absdif println("Calculating absolute value") dif, abs(dif) else dif end end # subtract (generic function with 1 method) subtract(5, 10) # -5 subtract(5, 10; absdif=true) # Calculating absolute value # (-5, 5)
函数的返回值
- 在 Julia 中,能返回多个值并将其赋值为元组,例如 (a, b) = (1, 2) 或 a, b = 1, 2
- Julia 中的函数返回其最后一个表达式或 return 关键字的值而无需在函数定义中列出要返回的变量的名称(有关详细信息,请参阅 return 关键字)
- 在 Julia 中,调用无参数的函数时必须使用小括号,例如
rand()
juliafunction f1() print("func 1: ") 1, 2, 3 end # f1 (generic function with 1 method) f1() # func 1: (1, 2, 3) ans # (1, 2, 3)
脚本、代码风格
- Julia 脚本可以包含任意数量的函数,并且在加载文件时,所有定义都将在外部可见
可以从当前工作目录之外的文件加载函数定义 - Julia 不鼓励使用分号来结束语句
语句的结果不会自动打印(除了在 REPL 中),并且代码的一行不必使用分号结尾
println
或者@printf
能用来打印特定输出 - 在 Julia 中,
...
不用于延续代码行。不同的是,Julia 中不完整的表达式会自动延续到下一行 - 在 Julia 和 MATLAB 中,变量 ans 被设置为交互式会话中提交的最后一个表达式的值
在 Julia 中与 MATLAB 不同的是,当 Julia 代码以非交互式模式运行时并不会设置 ans - 在 Julia 中,每个模块有自身的全局作用域/命名空间,而在 MATLAB 中只有一个全局作用域
内置函数、关键字
struct
- Julia 的 struct 不支持在运行时动态地添加字段,这与 MATLAB 的 class 不同。如需支持,请使用 Dict
svd
-
Julia 的 svd 将奇异值作为向量而非密集对角矩阵返回
matlabA = [2 0 2; 0 1 0; 0 0 0]; [U,S,V] = svd(A); S % 2.8284 0 0 % 0 1.0000 0 % 0 0 0
julia
using LinearAlgebra A = [2 0 2; 0 1 0; 0 0 0]; F = svd(A); F.S # 3-element Array{Float64,1}: # 2.8284271247461903 # 1.0 # 0.0 Diagonal(F.S) # 3×3 Diagonal{Float64,Array{Float64,1}}: # 2.82843 ⋅ ⋅ # ⋅ 1.0 ⋅ # ⋅ ⋅ 0.0
adjoint
- 在 julia 中,转置函数
adjoint
计算矩阵的共轭转置
而 MATLAB 中adjoint
计算伴随矩阵(adjugate matrix)的转置
【注:2014 版 MATLAB 会报错说 “未定义与 ‘double’ 类型的输入参数相对应的函数 ‘adjoint’”】
ref: - Julia: How can we compute the adjoint or classical adjoint (Linear Algebra)? - Stack Overflow