2016-09-18 136 views
3

使用MATLAB python engine時出現問題。從python生成MATLAB代碼

我想近似解決微分方程(使用類似MATLAB中的ode45功能)從Python,但問題是,ODE近似需要ODE功能規範,我似乎無法從MATLAB的Python引擎創建。

它可以很好地調用Python的MATLAB函數,比如isprime,但似乎沒有辦法在Python中指定MATLAB函數。

因此,我的問題是; 有沒有從Python生成MATLAB函數代碼的方法,或者是從Python中指定MATLAB函數的方法?

+0

使用SciPy的可能性? 'scipy.integrate.ode(f).set_integrator('dopri5')' –

+0

@JamesK它必須是MATLAB,因爲我想給用戶一個解算器/庫的選擇。 – Ezbob

回答

1

odefun passed to ode45, according to docs, has to be a function handle

解決ODE

Y」 =2噸

使用的[0,5]的時間間隔和初始條件Y0 = 0

tspan = [0 5]; 
y0 = 0; 
[t,y] = ode45(@(t,y) 2*t, tspan, y0); 

@(t,y) 2*t返回一個匿名函數的函數句柄。

不幸的是,function handles are listed as one of datatypes unsupported in MATLAB <-> Python conversion

不支持的MATLAB類型以下MATLAB數據類型不被MATLAB引擎API用於Python支持:

  • 範疇陣列
  • char數組(M -by-N)
  • 單元陣列(M-by-N)
  • 功能句柄
  • 稀疏陣列
  • 結構陣列
  • MATLAB值的物體(手柄和值類的討論,參見手柄和值類的比較)
  • 非MATLAB對象(如Java®對象)

總之,似乎沒有直接的做法它。

潛在解決方法可能涉及engine.workspaceengine.eval的某種組合,如Use MATLAB Engine Workspace in Python示例中所示。

engine.evalfirst demo

解決方法:

import matlab.engine 
import matplotlib.pyplot as plt 

e = matlab.engine.start_matlab() 
tr, yr = e.eval('ode45(@(t,y) 2*t, [0 5], 0)', nargout=2) 
plt.plot(tr, yr) 
plt.show() 

通過這樣做,可以避免通過MATLAB/Python的屏障功能,通過手柄。你傳遞字符串(字節)並讓MATLAB在那裏評估它。返回的是純數字數組。之後,您可以對結果向量進行操作,例如,繪製它們。

Matplotlib result

由於傳遞參數作爲文字會很快變得疼痛,engine.workspace可以用來避免它:

import matlab.engine 
import matplotlib.pyplot as plt 

e = matlab.engine.start_matlab() 
e.workspace['tspan'] = matlab.double([0.0, 5.0]) 
e.workspace['y0'] = 0.0 
tr, yr = e.eval('ode45(@(t,y) 2*t, tspan, y0)', nargout=2) 
plt.plot(tr, yr) 
plt.show()