Generate MATLAB code from python
<p>I have a problem when using the <a href="http://se.mathworks.com/help/matlab/matlab-engine-for-python.html" rel="nofollow">MATLAB python engine</a>.</p>

<p>I want to get approximated solutions to ODEs (using something like the <code>ode45</code> function in MATLAB) from Python, but the problem is that ODE approximation requires an ODE function specification that I can't seem to create from the MATLAB Python engine.</p>

<p>It works fine calling MATLAB functions, such as <code>isprime</code>, from Python but there seems to be no way of specifying a MATLAB function in Python.</p>

<p>My question is therefore;
Are there any way of generating MATLAB function code from Python or is a way to specify MATLAB functions from Python? </p>

<p><a href="https://www.mathworks.com/help/matlab/ref/ode45.html" rel="nofollow"><code>odefun</code> passed to <code>ode45</code>, according to docs, has to be a function handle</a>.</p>

<blockquote>
  <p>Solve the ODE</p>
  
  <p>y' = 2t</p>
  
  <p>Use a time interval of [0,5] and the initial condition y0 = 0.</p>
</blockquote>

<pre><code>tspan = [0 5];
y0 = 0;
[t,y] = ode45(@(t,y) 2*t, tspan, y0);
</code></pre>

<p><code>@(t,y) 2*t</code> returns a function handle to anonymous function.</p>

<p>Unfortunately, <a href="http://www.mathworks.com/help/matlab/matlab_external/handle-data-returned-from-matlab-to-python.html" rel="nofollow">function handles are listed as one of datatypes unsupported in MATLAB &lt;-> Python conversion</a>:</p>

<blockquote>
  <p><strong>Unsupported MATLAB Types The following MATLAB data types are not supported by the MATLAB Engine API for Python:</strong></p>
  
  <ul>
  <li>Categorical array</li>
  <li>char array (M-by-N)</li>
  <li>Cell array (M-by-N)</li>
  <li><strong>Function handle</strong></li>
  <li>Sparse array</li>
  <li>Structure array</li>
  <li>Table</li>
  <li>MATLAB value objects (for a discussion of handle and value classes see Comparison of Handle and Value Classes)</li>
  <li>Non-MATLAB objects (such as JavaÂ® objects)</li>
  </ul>
</blockquote>

<p>To sum up, it seems like there is no straightforward way of doing it.</p>

<p>Potential workaround may involve some combination of <code>engine.workspace</code> and <code>engine.eval</code>, as shown in <a href="http://www.mathworks.com/help/matlab/matlab_external/use-the-matlab-engine-workspace-in-python.html" rel="nofollow">Use MATLAB Engine Workspace in Python</a> example.</p>

<p>Workaround with <code>engine.eval</code> (<a href="https://www.mathworks.com/help/matlab/ref/ode45.html" rel="nofollow">first demo</a>):</p>

<pre><code>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()
</code></pre>

<p>By doing so, you avoid passing function handle via MATLAB/Python barrier. You pass string (bytes) and allow MATLAB to evaluate it there. What's returned is pure numeric arrays. After that, you may operate on result vectors, e.g. plot them.</p>

<p><a href="http://i.stack.imgur.com/DI2il.png" rel="nofollow"><img src="http://i.stack.imgur.com/DI2il.png" alt="Matplotlib result"></a></p>

<p>Since passing arguments as literals would quickly became pain, <code>engine.workspace</code> may be used to avoid it:</p>

<pre><code>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()
</code></pre>

python matlab python-3.x