在MATLAB和Python之間建個接口,從Python中調用MATLAB腳本或者是MATLAB的函數。內容不是很難,畢竟現成的接口已經有了,在這兒記錄一下API使用的一些事項。html
注:本篇使用的是MATLAB R2017a,windows 10系統。java
https://www.mathworks.com/help/matlab/matlab-engine-for-python.html
https://www.mathworks.com/help/matlab/matlab_external/get-started-with-matlab-engine-for-python.htmlpython
MATLAB在安裝的過程當中已經準備好了相關文檔。根據教程,首先要找到root\R2017a\extern\engines\python文件夾。這裏的root指的是MATLAB安裝的根目錄。對於筆者的電腦,個人全路徑就是C:\Program Files\MATLAB\R2017a\extern\engines\python。打開這個文件夾,能夠看見下面這幾個文件。
其中setup.py是咱們想要用的文件。定位到它以後,咱們在command window裏面轉到這個文件夾,而後執行安裝。(啓動command window的時候必須是管理員模式,不然可能會報「沒有權限」的錯誤)編程
cd C:\Program Files\MATLAB\R2017a\extern\engines\python python setup.py install
不出差錯的話,到這裏安裝過程就結束了。若是你使用的是Python的虛擬環境,那麼記得在安裝前先將虛擬環境啓動。windows
這個API調用很是簡單。在Python中,導入以下兩個module就能實現MATLAB的所有控制:後端
import matlab import matlab.engine
其中,matlab包含的是一些數據形式,好比int8,int16之類。matlab.engine負責程序的啓動。markdown
engine = matlab.engine.start_matlab() # Start MATLAB process engine = matlab.engine.start_matlab("-desktop") # Start MATLAB process with graphic UI
上面兩行代碼,第一行指示MATLAB在後端運行;第二行則會啓動MATLAB的圖形界面窗口。調用任何MATLAB函數都經過engine變量來實現。筆者本身調用了一些聲音工具箱中的函數,一點問題都沒有。函數
>>> engine.sqrt(2.) 1.4142135623730951
筆者本身嘗試的時候遇到不少變量類型不正確這樣的提示,由於MATLAB函數對於輸入數據的類型有着比較嚴格的要求,好比log2對於int8類型輸入就會報錯。double類型是MATLAB裏面用得最多的數據型,因此通常能夠將python的數據轉成MATLAB兼容的double類型來解決問題。舉個例子,Python的list類型變量只需加上matlab.double就能夠完成轉換。工具
>>> engine.sqrt([1.,2.,3.,4.,5.]) # Some error >>> engine.sqrt(matlab.double([1.,2.,3.,4.,5.])) matlab.double([[1.0,1.4142135623730951,1.7320508075688772,2.0,2.23606797749979]])
調用腳本和自定義函數的過程也幾乎同樣,也是從變量engine中去調用。值得注意的是,須要保證你的函數或腳本就在當前的工做路徑下,不然engine會找不到文件而報錯。網站
比方說,筆者當前的工做路徑下有兩個文件:gaussian_pulse.m和py_matlab.py。
gaussian_pulse.m中的內容是這樣的:
function out = gaussian_pulse(fs, fc, repeat) N = 882; t = 0:1/fs:(N-1)/fs; yi = gauspuls(t,fc,1/8); temp = yi; for i = 1:repeat-1 temp = cat(2, temp,yi); end out = temp; end
在py_matlab.py中,我定義了engine並調用這個函數:
engine = matlab.engine.start_matlab() signal = engine.gaussian_pulse(matlab.double([44100]), matlab.double([3000]), matlab.double([5]))
注意到每個輸入參數我都強制性進行了轉換確保萬無一失。加上方括號也是由於MATLAB的格式需求。
默認狀況下,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!
在MATLAB裏面邏輯值是true與false,可是在Python裏面它們是大寫的True和False。畢竟咱們仍是在Python環境下編程,因此若是調用某個函數須要用到邏輯值,遵循Python的書寫格式。
官方文檔裏還有一些其餘很是好的教程,包括標準輸出/錯誤信息重導向、句柄的使用、畫圖等等。鑑於筆者時間緣由這些沒有涉及到,有須要的朋友能夠從筆者在開篇提供的網站中找到答案。