Python调用MATLAB文件

参考官方教程
官方教程汇总

环境

  • Python 3.5或者Python 2.7
  • MATLAB R2018a
  • Ubuntu 16.04

安装步骤

参考这里安装MATLAB-engine

  • 在 Windows 系统中
1
2
cd "matlabroot\extern\engines\python"
python setup.py install
  • 在 Linux 系统中
1
2
cd "matlabroot/extern/engines/python"
python setup.py install

在Python终端中运行:

1
2
import matlab.engine
eng = matlab.engine.start_matlab()

安装报错:

1
/usr/lib/x86_64-linux-gnu/libstdc++.so.6: version `GLIBCXX_3.4.22' not found

这是因为当前版本的libstdc++.so.6缺少GLIBCXX_3.4.22.查看当前版本的GLIBCXX命令为,

1
strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep GLIBCXX


安装libstec++,

1
sudo apt-get install libstdc++6

如果未解决:

1
2
3
4
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:

1
strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 | grep GLIBCXX

调用MATLAB的m文件

参考官方教程

从 MATLAB 函数返回输出参数

您可以直接调用任何 MATLAB® 函数并将结果返回到 Python®。例如,要确定某个数是否为质数,请使用该引擎调用 isprime 函数。

1
2
3
4
5
import matlab.engine
eng = matlab.engine.start_matlab()
tf = eng.isprime(37)
print(tf)
True

从 MATLAB 函数返回多个输出参数

当使用引擎调用函数时,默认情况下该引擎会返回单个输出参数。如果您知道函数可能返回多个参数,请使用 nargout 参数指定输出参数的数量。
要确定两个数的最大公分母,请使用 gcd 函数。设置 nargout 以从 gcd 返回三个输出参数。

1
2
3
4
5
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 帮助浏览器。

1
2
3
import matlab.engine
eng = matlab.engine.start_matlab()
eng.doc(nargout=0)

MATLAB doc 函数将打开浏览器,但不会返回输出参数。如果您没有指定 nargout=0,引擎将报告错误。

停止执行函数

要停止执行 MATLAB 函数,请按 Ctrl+C。控制权将返回给 Python。

调用自定义m文件

参考官方教程

调用脚本

在您的当前文件夹中名为triarea.m的文件中创建一个 MATLAB 脚本。

1
2
3
b = 5;
h = 3;
a = 0.5*(b.* h)

保存该文件后,启动 Python 并调用该脚本。

1
2
3
4
5
import matlab.engine
eng = matlab.engine.start_matlab()
eng.triarea(nargout=0)
a =
7.5000

指定nargout=0。尽管脚本会打印输出,但它不会向 Python 返回任何输出参数。

调用函数

要编辑文件,请打开 MATLAB 编辑器。
在Python中运行

1
eng.edit('triarea',nargout=0)

添加语句

1
2
function a = triarea(b,h)
a = 0.5*(b.* h);

通过引擎调用新的 triarea 函数。

1
2
3
ret = eng.triarea(1.0,5.0)
print(ret)
2.5

triarea 函数仅返回一个输出参数,因此无需指定 nargout。

MATLAB变量与Python变量

numpy array

triarea.m 文件中的内容

1
2
function a = triarea(A, db)
a = real(ifft2(fft2(A).*fft2(db,size(A,1),size(A,2))));

首先,将numpy array 转为MATLAB的double形式:

1
2
3
4
5
6
7
# 将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,也可在终端打印

1
fprintf(class(obs_im_gam))

使用报错

报错1

1
MatlabExecutionError: Undefined function 'triarea' for input arguments of type 'double'.

一般是因为当前路径有问题,可在spyder下却换路径后,运行

1
2
3
eng.exit
import matlab.engine
eng = matlab.engine.start_matlab()

但是,若在pycharm下不容易切换路径,所以,正确的做法是在MATLAB中添加正确路径。

------ 本文结束------
坚持原创技术分享,您的支持将鼓励我继续创作!

欢迎关注我的其它发布渠道