环境
- Python 3.5或者Python 2.7
- MATLAB R2018a
- Ubuntu 16.04
安装步骤
参考这里安装MATLAB-engine
在 Windows 或者 Linux 系统中
cd matlabroot/extern/engines/python
python setup.py install
在Python终端中运行:
import matlab.engine
eng = matlab.engine.start_matlab()
安装报错:
/usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.22' not found
这是因为当前版本的libstdc++.so.6缺少GLIBCXX_3.4.22.查看当前版本的GLIBCXX命令为,
strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep GLIBCXX
安装libstec++,
sudo apt-get install libstdc++6
如果未解决:
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
运行命令,发现当前版本一包含GLIBCXX_3.4.22:
strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep GLIBCXX
调用MATLAB的m文件
参考官方教程
从 MATLAB 函数返回输出参数
您可以直接调用任何 MATLAB® 函数并将结果返回到 Python®。例如,要确定某个数是否为质数,请使用该引擎调用 isprime 函数。
import matlab.engine
eng = matlab.engine.start_matlab()
tf = eng.isprime(37)
print(tf)
True
从 MATLAB 函数返回多个输出参数
当使用引擎调用函数时,默认情况下该引擎会返回单个输出参数。如果您知道函数可能返回多个参数,请使用 nargout 参数指定输出参数的数量。
要确定两个数的最大公分母,请使用 gcd 函数。设置 nargout 以从 gcd 返回三个输出参数。
import matlab.engine
eng = matlab.engine.start_matlab()
t = eng.gcd(100.0,80.0,nargout=3)
print(t)
(20.0, 1.0, -1.0)
不从 MATLAB 函数返回任何输出参数
有些 MATLAB 函数不会返回任何输出参数。如果函数不返回任何参数,则将 nargout 设为 0。
通过 Python 打开 MATLAB 帮助浏览器。
import matlab.engine
eng = matlab.engine.start_matlab()
eng.doc(nargout=0)
MATLAB doc 函数将打开浏览器,但不会返回输出参数。如果您没有指定 nargout=0,引擎将报告错误。
停止执行函数
要停止执行 MATLAB 函数,请按 Ctrl+C。控制权将返回给 Python。
调用自定义m文件
参考官方教程
调用脚本
在您的当前文件夹中名为triarea.m
的文件中创建一个 MATLAB 脚本。
b = 5;
h = 3;
a = 0.5*(b.* h)
保存该文件后,启动 Python 并调用该脚本。
import matlab.engine
eng = matlab.engine.start_matlab()
eng.triarea(nargout=0)
a =
7.5000
指定nargout=0
。尽管脚本会打印输出,但它不会向 Python 返回任何输出参数。
调用函数
要编辑文件,请打开 MATLAB 编辑器。
在Python中运行
eng.edit('triarea',nargout=0)
添加语句
function a = triarea(b,h)
a = 0.5*(b.* h);
通过引擎调用新的 triarea 函数。
ret = eng.triarea(1.0,5.0)
print(ret)
2.5
triarea 函数仅返回一个输出参数,因此无需指定 nargout。
MATLAB变量与Python变量
numpy array
triarea.m 文件中的内容
function a = triarea(A, db)
a = real(ifft2(fft2(A).*fft2(db,size(A,1),size(A,2))));
首先,将numpy array 转为MATLAB的double形式:
# 将numpy array db 与 obs_grad_scale[str(s)] 转为matlab.double形式
db_ = matlab.double(db.tolist())
A = matlab.double(obs_grad_scale[str(s)].tolist())
# 传入自定义的triarea函数
ret = eng.triarea(A, db_)
# 将matlab.double形式转回numpy array形式
obs_grad_scale[str(s)] = np.array(ret)
调试方法
可以使用fprintf
来进行打印m文件的中间输出变量,运行Pycharm即可打印,或者在终端打开Spyder,也可在终端打印
fprintf(class(obs_im_gam))
使用报错
报错1
MatlabExecutionError: Undefined function 'triarea' for input arguments of type 'double'.
一般是因为当前路径有问题,可在spyder
下却换路径后,运行
eng.exit
import matlab.engine
eng = matlab.engine.start_matlab()
但是,若在pycharm下不容易切换路径,所以,正确的做法是在MATLAB
中添加正确路径。
One more thing
更多关于人工智能、Python、C++、计算机等知识,欢迎访问我的个人博客进行交流, 点这里~~