个人理解:通过Python去调用matlab的含义是指,通过在Python中导入matlab包(及matlab引擎),然后调用包中的构造函数去创建变量,并编写调用matlab包中的函数的代码(Python可能没有这些函数,或者在Python的调用格式不同),最终实现相应目的的一个过程。
调用matlab引擎首先需要在电脑上安装MATLAB,无法在只有 MATLAB Runtime 的机器上运行 MATLAB 引擎。matlab 包中包含以下内容:
其中,引擎提供了调用 MATLAB 的函数,数组类则提供了函数来创建 Python 对象形式的 MATLAB 数组。
在创建一个引擎后使用 matlab.engine 调用 MATLAB 函数,在 Python 中通过调用数组类型的构造函数来创建 MATLAB 数组,例如使用 matlab.double 创建双精度值数组。
下表显示了 matlab 包的结构:
包 | 函数或类 | 说明 |
---|---|---|
matlab.engine | start_matlab() | Python 函数,用于创建 MatlabEngine 对象,并将其附加到新的 MATLAB 进程 |
matlab.engine | MatlabEngine | Python 类,用于提供调用 MATLAB 函数的方法 |
matlab.engine | FutureResult | Python 类,用于保留以异步方式调用的 MATLAB 函数的结果 |
matlab | double | Python 类,用于保留 double 类型的 MATLAB 数组 |
matlab | single | Python 类,用于保留 single 类型的 MATLAB 数组 |
matlab | int8 | Python 类,用于保留 int8 类型的 MATLAB 数组 |
matlab | int16 | Python 类,用于保留 int16 类型的 MATLAB 数组 |
matlab | int32 | Python 类,用于保留 int32 类型的 MATLAB 数组 |
matlab | int64 | Python 类,用于保留 int64 类型的 MATLAB 数组 |
matlab | uint8 | Python 类,用于保留 uint8 类型的 MATLAB 数组 |
matlab | uint16 | Python 类,用于保留 uint16 类型的 MATLAB 数组 |
matlab | uint32 | Python 类,用于保留 uint32 类型的 MATLAB 数组 |
matlab | uint64 | Python 类,用于保留 uint64 类型的 MATLAB 数组 |
matlab | logical | Python 类,用于保留 logical 类型的 MATLAB 数组 |
matlab | object | Python 类,用于保留 MATLAB 对象的句柄 |
调用前在python中先写入
import matlab
import matlab.engine
其中matlab是用来做数据转换等工作,matlab.engine是用来调用函数的。
engine = matlab.engine.start_matlab() # 指示MATLAB在后端运行
engine = matlab.engine.start_matlab("-desktop") # 启动MATLAB的图形界面窗口
matlab.engine.start_matlab用于启动用于 Python 的 MATLAB 引擎。调用任何MATLAB函数都通过engine变量来实现。所有要送给python中调用的matlab的数据,需要使用matlab(就是刚刚import的)转换。
即使单单只是数值,若需要传送给matlab,则也需要用Python的list或者tuple在外进行包装才可以。例如:
import matlab
import matlab.engine
eng=matlab.engine.start_matlab()
a=matlab.double(10) #会报错
b=matlab.double([10]) #正确
MATLAB函数对于输入数据的类型有着比较严格的要求,比如log2对于int8类型输入就会报错。例如:
import matlab
import matlab.engine
eng=matlab.engine.start_matlab()
a=matlab.int8([1,4])
print(eng.log2(a))
上述代码会报错。而double类型是MATLAB里面用得最多的数据型,所以一般可以将python的数据转成MATLAB兼容的double类型来解决问题。例如:
import matlab
import matlab.engine
eng=matlab.engine.start_matlab()
b=matlab.double([1,4])
print(eng.log2(b))
输出如下:
[[0.0,2.0]]
调用脚本和自定义函数的过程也是从变量engine中去调用,需要保证该函数或脚本就在当前的工作路径下,否则engine会找不到文件而报错。
默认情况下,API认为接收函数返回结果的参数有1个。这会导致没有返回值的函数在被调用时报错:“Too many output arguments”或是其他类似的信息。可以通过人为指定输出参数为0个来避免这样的错误:
>>> playblocking(player) # playblocking is a MATLAB function with no returns
Error using playblocking
Too many output arguments
>>> playblocking(player, nargout=0)
# Success!
在Python使用的逻辑值是大写的True和False,如果调用某个函数需要用到逻辑值,需要遵循Python的书写格式。
1、从 MATLAB 函数返回输出参数。可以直接调用任何 MATLAB函数并将结果返回到 Python。例如,下面的代码用于确定某个数是否为质数:
import matlab.engine
eng=matlab.engine.start_matlab()
tf=eng.isprime(31)
print(tf)
输出如下:
True
2、当使用引擎调用函数时,默认情况下该引擎只会返回一个输出参数。如果函数可能返回多个参数,请使用 nargout 参数指定输出参数的数量。例如要确定两个数的最大公约数,请使用 gcd 函数(请在matlab中输入doc gcd获取函数的帮助文档)。设置 nargout 以从 gcd 返回三个输出参数nargout=3。
t=eng.gcd(100,80,nargout=3)
print(t)
输出如下:
(20, 1, -1)
3、如果函数不返回任何参数,则必须将 nargout 设为 0。例如通过 Python 打开 MATLAB 帮助浏览器:
eng.doc(nargout=0)
运行后MATLAB doc 函数将打开帮助浏览器,但不会返回输出参数。如果没有指定 nargout=0,引擎将报告错误。
matlab Python包提供数组类以将 MATLAB 数值类型的数组表示为 Python 变量,以便 MATLAB 数组可以在 Python 和 MATLAB 之间传递。
1、在 Python 中创建 MATLAB 数组。通过从 matlab Python 包中调用构造函数(例如 matlab.double、matlab.int32等)在 Python 会话中创建 MATLAB 数值数组。构造函数的名称表示 MATLAB 数值类型。可以将 MATLAB 数组作为输入参数传递给由用于 Python 的 MATLAB 引擎 API 调用的函数。当 MATLAB 函数将数值数组作为输出参数返回时,引擎会将该数组返回到 Python。
通过使用包含数字的可选 initializer 输入参数初始化数组。initializer 必须是 Python 序列类型,例如 list、tuple 或其他序列类型。可选的 size 输入参数根据序列来设置数组大小。通过指定 initializer 包含多个数字序列或通过指定 size 为多维来创建多维数组。通过将可选的 is_complex 输入参数设置为 True,可以创建复数 MATLAB 数组。matlab 包提供了下表中列出的 MATLAB 数组构造函数:
matlab 类 | Python 中的构造函数调用 |
---|---|
matlab.double | matlab.double(initializer=None, size=None, is_complex=False) |
matlab.single | matlab.single(initializer=None, size=None, is_complex=False) |
matlab.int8 | matlab.int8(initializer=None, size=None, is_complex=False) |
matlab.logical | matlab.logical(initializer=None, size=None)c |
matlab.object | 没有构造函数。当函数返回的是 MATLAB 对象的句柄或值对象时,引擎会将 matlab.object 返回给 Python。 |
上表未列出全部matlab数组构造函数,全表见此链接。
示例代码如下:
import matlab
import matlab.engine
eng=matlab.engine.start_matlab()
a=matlab.int8([1,2,3,4],size=(2,2),is_complex=True)
print(a)
输出如下:
[[(1+0j),(3+0j)],[(2+0j),(4+0j)]]
当创建具有 N 个元素的数组时,数组大小为 1×N,因为它是 MATLAB 数组。
import matlab.engine
A=matlab.int8([1,2,3,4,5])
print(A.size)
输出如下:
(1, 5)
上述代码使用包含五个数字的 Python list 进行初始化。MATLAB 数组大小为 1×5,由 tuple (1,5) 指示。
2、Python 中的 MATLAB 数组属性和方法。所有使用 matlab 包构造函数创建的 MATLAB 数组都具有下表中列出的属性和方法。
属性或方法 | 用途 |
---|---|
size | 数组大小返回为 tuple |
reshape(size) | 按照序列 size 的指定重构数组 |
import matlab
import matlab.engine
eng=matlab.engine.start_matlab()
a=matlab.int8([1,2,3,4])
a.reshape((4,1))
print(a)
输出如下:
[[1],[2],[3],[4]]
3、Python 中的多维 MATLAB 数组。在 Python 中可以创建任何数值类型的多维 MATLAB 数组。下面的代码使用两个 Python list 变量创建一个 2×5 MATLAB 双精度数组。
import matlab.engine
A=matlab.double([[1,2,3,4,5],[6,7,8,9,10]])
print(A)
输出如下:
[[1.0,2.0,3.0,4.0,5.0],[6.0,7.0,8.0,9.0,10.0]]
A 的 size 属性显示它是 2×5 数组。
4、就像对 Python list 和 tuple 变量进行索引一样,也可以对 MATLAB 数组进行索引。如:
import matlab.engine
A=matlab.int8([1,2,3,4,5])
print(A[0])
输出如下:
[1,2,3,4,5]
上述输出是由于MATLAB 数组的大小为 (1,5),因此,A[0] 是 [1,2,3,4,5]。
print(A[0][2])
输出如下:
3
注意Python 索引是从 0 开始的。当在 Python 会话中访问 MATLAB 数组的元素时,请使用从 0 开始的索引。如对多维 MATLAB 数组进行索引:
import matlab.engine
A=matlab.int8([[1,2,3,4,5],[6,7,8,9,10]])
print(A[1][2])
输出如下:
8
5、像对 Python list 和 tuple 变量进行切片一样,同样也可以对 MATLAB 数组进行切片。例如:
import matlab.engine
A=matlab.int8([1,2,3,4,5])
print(A[0][1:4])
输出如下:
[2,3,4]
可以将数据分配到一个切片。以下代码显示从 Python list 到一个数组切片的分配。
import matlab.engine
A=matlab.int8([[1,2,3,4,5],[6,7,8,9,10]])
A[0]=[10,20,30,40,50]
print(A)
输出如下:
[[10,20,30,40,50],[6,7,8,9,10]]
可以为分配指定切片,如:
import matlab.engine
A=matlab.int8([1,2,3,4,5,6,7,8])
A[0][2:4]=[40,50]
A[0][6:8]=[80,90]
print(A)
输出如下:
[[1,2,40,50,5,6,80,90]]
6、使用 reshape 方法在 Python 中重构 MATLAB 数组。输入参数 size 必须是保留元素数量的一个序列。例如使用 reshape 将 1×9 MATLAB 数组更改为 3×3:
import matlab.engine
A=matlab.int8([1,2,3,4,5,6,7,8,9])
A.reshape((3,3))
print(A)
输出如下:
[[1,4,7],[2,5,8],[3,6,9]]
下面说明如何在 Python中创建 MATLAB数组并将其作为输入参数传递给 MATLAB sqrt 函数。
下面的代码是从 Python list 创建一个 MATLAB 数组,并对该数组调用 sqrt 函数:
import matlab.engine
eng=matlab.engine.start_matlab()
a=matlab.double([1,4,9,16])
b=eng.sqrt(a)
print(b)
输出如下:
[[1.0,2.0,3.0,4.0]]
引擎返回 b,它是 1×5 的 matlab.double 数组。
下面的代码使用magic 函数将一个二维 matlab.double 数组返回给 Python。使用 for 循环分行打印数组中的每行:
a=eng.magic(6)
for x in a:
print(x)
输出如下:
[35.0,1.0,6.0,26.0,19.0,24.0]
[3.0,32.0,7.0,21.0,23.0,25.0]
[31.0,9.0,2.0,22.0,27.0,20.0]
[8.0,28.0,33.0,17.0,10.0,15.0]
[30.0,5.0,34.0,12.0,14.0,16.0]
[4.0,36.0,29.0,13.0,18.0,11.0]
1、启动用于 Python 的 MATLAB 引擎。首先在操作系统提示符下启动 Python;然后将 matlab.engine 包导入您的 Python 会话中。之后通过调用 start_matlab 启动新的 MATLAB进程。start_matlab 函数返回 Python 对象 eng,您可以通过该对象传递数据和调用由 MATLAB 执行的函数。
import matlab.engine
eng = matlab.engine.start_matlab()
2、可以运行多个引擎,每个引擎启动自己的 MATLAB 进程并与之通信:
eng1 = matlab.engine.start_matlab()
eng2 = matlab.engine.start_matlab()
3、调用 exit 或 quit 函数可以停止引擎:
eng.quit()
如果在引擎仍在运行的情况下退出 Python,Python 会自动停止引擎及其 MATLAB 进程。
4、使用启动选项启动引擎。随桌面启动 MATLAB:
eng = matlab.engine.start_matlab("-desktop")
可以使用单个字符串定义多个启动选项。例如,启动桌面并将数值显示格式设置为 short。
eng = matlab.engine.start_matlab("-desktop -r 'format short'")
也可以在启动引擎后启动桌面:
import matlab.engine
eng = matlab.engine.start_matlab()
eng.desktop(nargout=0)
1、python中调用matlab
2、如何在Python中调用MATLAB
3、用于 Python 的 MATLAB 引擎 API 快速入门
4、从 Python 调用 MATLAB
5、通过 Python 调用 MATLAB 函数
6、MATLAB 数组作为 Python 变量
7、启动和停止用于 Python 的 MATLAB 引擎