Python的擴展接口[3] -> Matlab引擎 -> 使用 Python 調用 Matlab 程序
Python - Matlab
目錄
- Python-Matlab 引擎
- Python-Matlab 數組
- Python-Matlab 基本操作
- Python-Matlab 調用 m 文件
Matlab的官方文檔中介紹了Matlab與其余編程語言之間的引擎接口,其中包括對於Python開放的引擎API,可參考官方教程,其中包括引擎安裝,基本使用,以及Python與Matlab之間的數據類型轉換及交互。
除了使用官網的Matlab引擎來驅動Matlab外,還可以使用第三方包mlab來進行連接或直接使用win32com的dispatch來進行控制,但目前mlab僅支持Python 2的版本。
1 Python-Matlab引擎 / Pyhton-Matlab Engine
首先,需要確保Matlab及Python的配置和安裝,利用Matlab提供的setup.py文件安裝Python的引擎包,安裝步驟及過程如下,
1. 確保安裝可用的Python和Matlab,且兩者版本對應,如32位的Matlab需對應32位的Python,同時還需查看Matlab支持的Python版本(目前2015a版支持的Python版本為2.7/3.3/3.4);
2. 添加Python目錄到環境變量(如果未添加);
3. 獲取Matlab文件夾目錄,可通過Matlab命令行窗口輸入matlabroot命令返回;
4. 安裝引擎,Windows利用下面的命令(此處路徑可能需要修改)進行安裝,此處可能需要管理員權限運行。
1 cd C:\Program Files\MATLAB\R2015a\extern\engines\python 2 python setup.py install 3 pause
2 Python-Matlab數組 / Pyhton-Matlab Array
在Python中,如果需要創建一個Matlab的數組,也可以通過Matlab引擎API來完成,主要數據類型如下圖顯示。
下面介紹數組的基本使用,其基本使用方法與numpy類似,但是reshape()函數略有不同,
1 import matlab.engine 2 3 # Basic usage 4 int_8 = matlab.int8([1, 2, 3, 4, 5, 6]) 5 print(int_8) # [[1, 2, 3, 4, 5, 6]] 6 print(int_8.size) # (1, 6) 7 int_8.reshape((2, 3)) # reshape function is different from numpy 8 print(int_8) # [[1, 3, 5], [2, 4, 6]] 9 10 double = matlab.double([[1, 2, 3], [4, 5, 6]]) 11 print(double) # [[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]] 12 print(double[0]) # [1.0, 2.0, 3.0] 13 print(double[1][2]) # 6.0
對於數組的切片,Matlab的array與Python的list也有所不同,官網給出的解釋在於,Matlab數組切片返回的是一個視圖,而不是像Python中返回一個淺拷貝。
1 # Slice array 2 py = [[1, 2, 3], [4, 5, 6]] 3 mt = matlab.int32([[1, 2, 3], [4, 5, 6]]) 4 py[0] = py[0][::-1] 5 mt[0] = mt[0][::-1] 6 # Slicing a Matlab array returns a view instead of a shallow copy 7 print(py) # [[3, 2, 1], [4, 5, 6]] 8 print(mt) # [[3, 2, 3], [4, 5, 6]]
3 Python-Matlab基本操作 / Pyhton-Matlab Basic Operation
Python還可以通過引擎完成對Matlab的一些基本操作與控制。
完整代碼
1 import matlab.engine 2 3 eng = matlab.engine.start_matlab() 4 5 print(eng.sqrt(4.)) # 2.0 6 eng.plot(matlab.int32([1, 2, 3, 4]), matlab.int32([1, 2, 3, 4])) 7 8 eng.eval("hold on", nargout=0) 9 eng.eval("plot([4, 3, 2, 1], [1, 2, 3, 4])", nargout=0) 10 11 eng.eval("x = 3", nargout=0) 12 eng.eval("y = 41", nargout=0) 13 eng.eval("z = [213, 123]", nargout=0) 14 print(eng.workspace) 15 print(eng.workspace[‘x‘], eng.workspace[‘z‘]) 16 """ 17 Name Size Bytes Class Attributes 18 19 x 1x1 8 double 20 y 1x1 8 double 21 z 1x2 16 double 22 23 3.0 [[213.0,123.0]] 24 """ 25 26 input("Press Enter to exit.") 27 eng.quit()View Code
分段解釋
1 import matlab.engine 2 3 eng = matlab.engine.start_matlab()
首先導入需要的包並生成實例,此處調用sqrt()函數計算,得到結果,還可以利用引擎實例調用plot函數進行畫圖,但需要註意的是,傳入的參數需要是Matlab類型參數。
1 print(eng.sqrt(4.)) # 2.0 2 eng.plot(matlab.int32([1, 2, 3, 4]), matlab.int32([1, 2, 3, 4]))
當我們需要執行某些Matlab命令時,可以利用eval函數對其進行輸入,下面的方法畫出了另外一條直線,其中nargout參數為設置輸出返回參數的數量,默認為1。無參數返回時需要設置為0。
1 eng.eval("hold on", nargout=0) 2 eng.eval("plot([4, 3, 2, 1], [1, 2, 3, 4])", nargout=0) 3 4 eng.eval("x = 3", nargout=0) 5 eng.eval("y = 41", nargout=0) 6 eng.eval("z = [213, 123]", nargout=0) 7 print(eng.workspace) 8 print(eng.workspace[‘x‘], eng.workspace[‘z‘]) 9 """ 10 Name Size Bytes Class Attributes 11 12 x 1x1 8 double 13 y 1x1 8 double 14 z 1x2 16 double 15 16 3.0 [[213.0,123.0]] 17 """ 18 19 input("Press Enter to exit.") 20 eng.quit()
4 Python-Matlab調用m文件 / Pyhton-Matlab Call m File
下面介紹如何使用Python調用m來進行計算並獲得返回結果,首先定義以下的m文件,在被調用的m文件中再調用下一個m文件,使用的m文件如下,
定義入口函數callentry,接收兩個參數,隨後對兩個參數分別在內部進行加和乘操作,再調用外部另一個m文件的callsub函數進行相減操作,將返回的結果保存在數組r中返回。
callentry.m 代碼
function [x, y, z] = callentry(a, b); x = add(a, b) y = mul(a, b) z = callsub(a, b) end function l = mul(m, n); l=m*n; end function l = add(m, n); l=m+n; end
callsub.m 代碼
function r = callsub(a, b); r = a-b; end
在Python中,運行如下代碼,
1 import matlab.engine 2 3 eng = matlab.engine.start_matlab() 4 print(eng.callentry(7.7, 2.1, nargout=3)) 5 eng.quit()
Note: 值得註意的是,此處需要設置nargout參數,當未設置時默認為1,即默認只返回1個參數,當知道Matlab返回參數的數量時,通過nargout進行設置來獲取所有需要的參數。無參數返回時請設為0。
在第一次運行生成實例時會較慢,因為需要啟動Matlab引擎,最終得到輸出如下,可以看到,Matlab的console界面顯示的結果在Python中也會輸出,最後得到的結果是列表形式的Python數據。
x = 9.8000 y = 16.1700 z = 5.6000 r = 9.8000 16.1700 5.6000 (9.8, 16.17, 5.6)
Python的擴展接口[3] -> Matlab引擎 -> 使用 Python 調用 Matlab 程序