[自用]通过Python调用matlab

文章目录

  • 1 通过Python调用matlab函数
  • 2 MATLAB 数组作为 Python 变量
  • 3 在Python中使用matlab数组
  • 4 启动和停止用于 Python 的 MATLAB 引擎
  • 参考文献


个人理解:通过Python去调用matlab的含义是指,通过在Python中导入matlab包(及matlab引擎),然后调用包中的构造函数去创建变量,并编写调用matlab包中的函数的代码(Python可能没有这些函数,或者在Python的调用格式不同),最终实现相应目的的一个过程。

调用matlab引擎首先需要在电脑上安装MATLAB,无法在只有 MATLAB Runtime 的机器上运行 MATLAB 引擎。matlab 包中包含以下内容:

  • 用于 Python 的 MATLAB 引擎 API
  • Python 中的一组 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 通过Python调用matlab函数

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,引擎将报告错误。

2 MATLAB 数组作为 Python 变量

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]]

3 在Python中使用matlab数组

下面说明如何在 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]

4 启动和停止用于 Python 的 MATLAB 引擎

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 引擎

你可能感兴趣的:(Python,Prony,MATLAB)