AnyMath 文档
Notebook

结合使用Julia、MATLAB和Python解决工程问题

导言

现代工程师和科学家很少局限于一种编程语言。 数值计算基于MATLAB,数据分析基于Python,高性能计算基于Julia。 但是,如果你把它们结合起来,而不是选择它们呢?

Engee计算环境允许您直接在单个脚本中运行Julia、MATLAB和Python代码,在不同语言之间快速交换数据。 在这个例子中,我们将展示它是如何工作的:在Julia中创建一个矩阵,在MATLAB中处理它,将它保存到a。mat文件,然后使用NumPy—all分析结果,而不会超出一个环境。

加入图书馆

在这个例子中,我们将需要以下库:

  • MATLAB -直接从Julia运行MATLAB命令和函数,允许您在环境之间共享变量
  • MAT -用于读取和写入文件。mat作为离线数据转换器工作,而无需运行MATLAB本身。
  • PyCall -对于来自Julia的Python脚本和库,具有语言之间的自动类型转换。
In [ ]:
using MATLAB, MAT, PyCall

从Julia调用MATLAB

执行MATLAB命令

该脚本将在MATLAB核心内执行。

In [ ]:
mat"""
a = 10;
b = 20;
c = a + b;
disp(c);
"""
>> >> >> >> >> >>     30

调用MATLAB函数

有一个文件:

% myfunc.m\
\
function y = myfunc(x)\
 y = x.^2 + 1;\
end

让我们使用命令执行MATLAB脚本 mxcall()我们将显示结果。

In [ ]:
result = mxcall(:myfunc, 1, 5)
println(result)
26

数据传输Julia→MATLAB

@mput 将Julia变量放在MATLAB工作区中。

In [ ]:
x = [1,2,3,4,5]

@mput x

mat"""
y = x.^2;
disp(y)
"""
>> >> >> >>     1
    4
    9
   16
   25

现在MATLAB看到变量 x.

多个变量
In [ ]:
a = 10
b = 20

@mput a b
mat"""
c = a + b;
disp(c)
"""
>> >> >> >>    30

获取MATLAB→Julia数据

@mget 提取MATLAB变量并将其放置在Julia工作区中。

In [ ]:
mat"""
x = 42;
"""

@mget x

println(x)
42.0
获取数组
In [ ]:
mat"""
A = magic(3);
"""

@mget A

println(A)
[8.0 1.0 6.0; 3.0 5.0 7.0; 4.0 9.0 2.0]

同时数据传输

In [ ]:
x = [1.0, 2.0, 3.0]

@mput x

mat"""
y = sin(x);
z = cos(x);
"""

@mget y z

println(y)
println(z)
[0.8414709848078965, 0.9092974268256817, 0.1411200080598672]
[0.5403023058681398, -0.4161468365471424, -0.9899924966004454]
矩阵的转移
In [ ]:
A = rand(5,5)
@mput A
mat"""
B = inv(A);
"""
@mget B
println(B)
[-5.221370437657235 4.536689829822023 1.7853694400555051 -1.7555803059084987 2.5459703018696143; -2.656223457338815 2.6954496614608283 1.9527633720615352 -0.7726425993370551 0.3924611199505691; 1.1298133336804967 0.13971945565486266 -1.0208263947545195 -0.09726994177272896 -0.013276362895074445; 8.019040759955885 -7.849628311451011 -2.63590807356968 2.136718238044462 -1.7078887483116802; 3.268552864160139 -3.710816487781914 -1.5021042004828817 2.4835666024648373 -1.7450236032972575]

不使用宏的数据交换

通过 put_variable()get_variable()

In [ ]:
x = 10

put_variable(:x, x)

mat"""
y = x^2;
"""

y = get_variable(:y)

println(y) 
100

通过插值 $

In [ ]:
x = 10

mat"""
y = $x^2;
"""

y = get_variable(:y)

println(y)  
100

通过 mxcall()

In [ ]:
x = 10
y = mxcall(:sqrt, 1, x)
println(y)

MATLAB中的模拟:

y = sqrt(10);

通过显式会话 MSession

In [ ]:
s = MSession()
put_variable(s, :x, 10)
eval_string(s, "y = x^2;")
y = get_mvariable(s, :y)
println(y)
close(s)
MxArray(Ptr{Nothing}(0x000077b0f43c39e0), true)
mkdir: cannot create directory ‘/user/.MathWorks’: Permission denied

使用内置的MATLAB表达式

In [ ]:
y = mxcall(:power, 1, 10, 2)
println(y) 

MATLAB中的模拟:

power(10,2)

调用MATLAB脚本

有一个文件:

% script1.m

x = 100;
y = x^2;

disp(y)

In [ ]:
mat"""
run('script1.m');
"""
>> >> >>        10000

In [ ]:
mat"""
script1
"""
>> >> >>        10000

保存MAT文件

朱莉娅→垫

In [ ]:
A = rand(100,100)
matwrite("data.mat", Dict("A" => A))

然后,在MATLAB中,您可以这样做:

In [ ]:
mat"""
load('data.mat')
"""

MATLAB→Julia

In [ ]:
data = matread("data.mat")
A = data["A"]
Out[0]:
100×100 Matrix{Float64}:
 0.187665    0.536775   0.559974   …  0.497759   0.370136   0.217892
 0.498748    0.802852   0.447108      0.137034   0.986267   0.0492607
 0.692961    0.585268   0.0409884     0.675473   0.352056   0.832218
 0.16713     0.523383   0.488701      0.64212    0.339589   0.0828162
 0.994572    0.0283767  0.932887      0.29104    0.573378   0.11291
 0.287387    0.787492   0.92626    …  0.312808   0.13772    0.796877
 0.930736    0.39265    0.133021      0.536968   0.665237   0.768994
 0.185316    0.0128372  0.846072      0.494333   0.36337    0.151129
 0.137108    0.0811613  0.612712      0.913359   0.0901814  0.639056
 0.257916    0.267885   0.0811315     0.309257   0.806105   0.982611
 0.153683    0.480328   0.330206   …  0.0230829  0.440528   0.584395
 0.147242    0.830841   0.611354      0.913737   0.175778   0.294328
 0.141859    0.259777   0.473815      0.391229   0.448802   0.783275
 ⋮                                 ⋱                        
 0.491116    0.22047    0.914381      0.403631   0.572556   0.680288
 0.31416     0.0558817  0.119846      0.58611    0.976843   0.402179
 0.523465    0.549084   0.292965   …  0.947264   0.593057   0.0757108
 0.505689    0.569463   0.271353      0.840848   0.613332   0.429195
 0.00443699  0.777516   0.928007      0.125124   0.702318   0.947103
 0.506735    0.841525   0.632436      0.389265   0.0218632  0.830129
 0.540411    0.701873   0.806918      0.588761   0.540034   0.473754
 0.643525    0.979437   0.540921   …  0.850907   0.661718   0.224936
 0.225163    0.693345   0.953538      0.0294944  0.0242852  0.983359
 0.80467     0.069913   0.223371      0.771978   0.675066   0.482565
 0.174844    0.123621   0.549536      0.146337   0.701713   0.917493
 0.962306    0.950703   0.678788      0.394894   0.0613499  0.605355

从Julia调用Python

执行Python脚本

In [ ]:
py"""
x = 10
y = 20
z = x + y
print(z)
"""
30

获得结果

In [ ]:
result = py"z"
println(result)

调用Python函数

有一个文件:

# mymodule.py

def square(x):
return x*x

In [ ]:
pushfirst!(PyVector(pyimport("sys")."path"), ".")
mod = pyimport("mymodule")
result = mod.square(5)
println(result)
25

数据传输Julia→Python

In [ ]:
a = [1,2,3,4]
py"""
a = $a
"""

Python现在看到向量 x.

NumPy矩阵的传递

In [ ]:
A = rand(3,3)
py"""
A = $A
"""

PyCall自动转换数组。

获取Python→Julia数据

In [ ]:
py"""
import numpy as np
A = np.random.rand(3,3)
"""

A = py"A"
println(A)
[0.6654948909047511 0.3864146000126685 0.6323793133576465; 0.44635742775821485 0.751622525464147 0.12916692842936617; 0.2232885178400401 0.5449276484095866 0.18403058713001075]

直接使用NumPy

In [ ]:
np = pyimport("numpy")
x = np.linspace(0, 10, 100)
println(x)
[0.0, 0.10101010101010101, 0.20202020202020202, 0.30303030303030304, 0.40404040404040403, 0.5050505050505051, 0.6060606060606061, 0.7070707070707071, 0.8080808080808081, 0.9090909090909091, 1.0101010101010102, 1.1111111111111112, 1.2121212121212122, 1.3131313131313131, 1.4141414141414141, 1.5151515151515151, 1.6161616161616161, 1.7171717171717171, 1.8181818181818181, 1.9191919191919191, 2.0202020202020203, 2.121212121212121, 2.2222222222222223, 2.323232323232323, 2.4242424242424243, 2.525252525252525, 2.6262626262626263, 2.727272727272727, 2.8282828282828283, 2.929292929292929, 3.0303030303030303, 3.131313131313131, 3.2323232323232323, 3.3333333333333335, 3.4343434343434343, 3.5353535353535355, 3.6363636363636362, 3.7373737373737375, 3.8383838383838382, 3.9393939393939394, 4.040404040404041, 4.141414141414141, 4.242424242424242, 4.343434343434343, 4.444444444444445, 4.545454545454545, 4.646464646464646, 4.747474747474747, 4.848484848484849, 4.94949494949495, 5.05050505050505, 5.151515151515151, 5.252525252525253, 5.353535353535354, 5.454545454545454, 5.555555555555555, 5.656565656565657, 5.757575757575758, 5.858585858585858, 5.959595959595959, 6.0606060606060606, 6.161616161616162, 6.262626262626262, 6.363636363636363, 6.4646464646464645, 6.565656565656566, 6.666666666666667, 6.767676767676767, 6.8686868686868685, 6.96969696969697, 7.070707070707071, 7.171717171717171, 7.2727272727272725, 7.373737373737374, 7.474747474747475, 7.575757575757575, 7.6767676767676765, 7.777777777777778, 7.878787878787879, 7.979797979797979, 8.080808080808081, 8.181818181818182, 8.282828282828282, 8.383838383838384, 8.484848484848484, 8.585858585858587, 8.686868686868687, 8.787878787878787, 8.88888888888889, 8.98989898989899, 9.09090909090909, 9.191919191919192, 9.292929292929292, 9.393939393939394, 9.494949494949495, 9.595959595959595, 9.696969696969697, 9.797979797979798, 9.8989898989899, 10.0]

NumPy+Julia-数组

In [ ]:
A = rand(100)
np.mean(A)
Out[0]:
0.4975610444322162

三种语言之间的数据传输

Julia↔MATLAB↔Python

朱莉娅:

In [ ]:
x = rand(100)
@mput x

MATLAB的:

In [ ]:
mat"""
y = fft(x);
save('fft.mat','y')
"""

朱莉娅:

In [ ]:
d = matread("fft.mat")
y = d["y"]
Out[0]:
100×1 Matrix{ComplexF64}:
  50.313741254263505 + 0.0im
 -1.5771407887055269 + 2.124727170787205im
 -1.2688118432157607 + 0.05402836822868018im
   2.004984078494711 - 1.3179735416202203im
 -0.8416332361392718 + 1.717682921499197im
   -0.92602810124836 + 3.5138264917159967im
   1.593016731074605 - 0.7439815251896407im
 0.46384142685195917 + 3.8454495764527im
  1.0924993653124653 - 3.905545719219579im
  0.7162821343272152 + 1.4136618648658554im
 -0.6796169943349781 + 0.7628501552265539im
 -3.4342798941532124 - 0.5686610086095321im
 -2.3822899937223627 + 0.03900956219344409im
                     ⋮
 -2.3822899937223627 - 0.03900956219344409im
 -3.4342798941532124 + 0.5686610086095321im
 -0.6796169943349781 - 0.7628501552265539im
  0.7162821343272152 - 1.4136618648658554im
  1.0924993653124653 + 3.905545719219579im
 0.46384142685195917 - 3.8454495764527im
   1.593016731074605 + 0.7439815251896407im
   -0.92602810124836 - 3.5138264917159967im
 -0.8416332361392718 - 1.717682921499197im
   2.004984078494711 + 1.3179735416202203im
 -1.2688118432157607 - 0.05402836822868018im
 -1.5771407887055269 - 2.124727170787205im

巨蟒:

In [ ]:
np = pyimport("numpy")
py_y = PyObject(y)
meanval = np.mean(abs.(y))
Out[0]:
2.972701599598033

在同一个Julia脚本中调用MATLAB和Python

In [ ]:
x = 1:10
@mput x

mat"""
y = x.^2;
"""

@mget y

np = pyimport("numpy")
avg = np.mean(y)

println(avg)
38.5

在这里,数据流经链:Julia→MATLAB→Julia→Python→Julia,这是科学计算和数据分析的典型场景之一。

结论

我们已经看到,Engee计算环境能够无缝地将三个语言宇宙集成到一个计算过程中,这使我们能够使用不同的编程语言联合工程社区,提供一个现成的平台,使MATLAB兼容的计算、Python脚本和高性能Julia代码协同工作,而无需手动配置语言间桥梁。