2016-09-18 6 views
3

Ich habe ein Problem bei der Verwendung der MATLAB python engine.Erzeuge MATLAB-Code von Python

Ich möchte Näherungslösungen für ODEs (mit etwas wie die ode45 Funktion in MATLAB) von Python, aber das Problem ist, dass ODE-Näherung eine ODE-Funktionsspezifikation erfordert, die ich nicht von der MATLAB Python-Engine erstellen kann .

Es funktioniert einwandfrei MATLAB-Funktionen, wie isprime, von Python aufrufen, aber es scheint keine Möglichkeit zu geben, eine MATLAB-Funktion in Python anzugeben.

Meine Frage ist daher; Gibt es eine Möglichkeit, MATLAB-Funktionscode aus Python zu generieren, oder gibt es eine Möglichkeit, MATLAB-Funktionen von Python aus anzugeben?

+0

ist eine Möglichkeit, mit scipy? 'scipy.integrate.ode (f) .set_integrator ('dopri5')' –

+0

@JamesK Es muss MATLAB sein, da ich dem Benutzer eine Auswahl von Solvern/Bibliotheken geben möchte. – Ezbob

Antwort

1

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

Löse das ODE

y‘= 2t

Verwenden ein Zeitintervall von [0,5], und die Anfangsbedingung y0 = 0.

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

@(t,y) 2*t kehrt ein Funktionshandle zur anonymen Funktion.

Leider function handles are listed as one of datatypes unsupported in MATLAB <-> Python conversion:

Nicht unterstützte MATLAB Typen Die folgenden MATLAB Datentypen werden nicht durch die MATLAB Engine API für Python unterstützt:

  • Categorical Array
  • char array (M -von-N)
  • Zellenanordnung (M-mal-N)
  • Funktionsgriff
  • Sparse-Array
  • Struktur Array
  • Tabelle
  • MATLAB Wertobjekte (für eine Diskussion von Griff und Wertklassen Vergleich Griff und Wertklassen sehen)
  • Nicht MATLAB-Objekte (wie Java® Objekte)

zusammenzufassen, um, wie es scheint, gibt es keine einfache Möglichkeit, zu tun ist, es.

Mögliche Abhilfe kann eine Kombination von engine.workspace und engine.eval, wie in Use MATLAB Engine Workspace in Python Beispiel gezeigt.

Behelfslösung mit engine.eval (first 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() 

Auf diese Weise vermeiden Sie vorbei Funktionsgriff über MATLAB/Python-Schranke. Sie übergeben die Zeichenfolge (Bytes) und erlauben MATLAB, sie dort auszuwerten.Was zurückgegeben wird, sind reine numerische Arrays. Danach können Sie mit Ergebnisvektoren arbeiten, z. plotte sie.

Matplotlib result

Da Argumente als Literale vorbei schnell Schmerzen wurden würde, kann engine.workspace es zu vermeiden, verwendet werden:

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()