<p>我浏览了一下代码,我不认为所有的<a href="https://github.com/ewiger/mlab/blob/master/README.rst" rel="nofollow noreferrer">README</a>文件及其文档都与实际实现的内容匹配。它似乎主要是从原始的<a href="http://mlabwrap.sourceforge.net/" rel="nofollow noreferrer">^{<cd1>}</a>项目复制的。在</p>
<p>这令人困惑,因为<code>mlabwrap</code>是使用<a href="https://docs.python.org/2/extending/extending.html" rel="nofollow noreferrer">C extension module</a>与{a4}交互来实现的。然而,<code>mlab</code>代码似乎已经用纯Python实现代替了这一部分,作为MATLAB桥的后端。它来自<a href="https://code.google.com/p/danapeerlab/source/browse/trunk/freecell/depends/common/python/" rel="nofollow noreferrer">"Dana Pe'er Lab"</a>,根据平台的不同,它使用两种不同的方法与MATLAB交互(Windows上的<a href="http://www.mathworks.com/help/matlab/call-matlab-com-automation-server.html" rel="nofollow noreferrer">COM/ActiveX</a>和Linux/Mac上的<a href="https://docs.python.org/2/library/subprocess.html#subprocess.Popen" rel="nofollow noreferrer">pipes</a>)。在</p>
<hr/>
<p>既然我们了解了后端是如何实现的,那么就可以开始查看导入错误了。在</p>
<p>注意:Linux/Mac部分的代码<a href="https://github.com/ewiger/mlab/blob/master/src/mlab/matlabpipe.py#L50" rel="nofollow noreferrer">tries to find</a>是MATLAB可执行文件中一些硬编码的固定位置,并允许在不同版本之间进行选择。在</p>
<p>然而,您在Windows上工作,并且代码并没有真正实现在这个平台的MATLAB版本之间进行选择的任何方式(因此所有的方法,如<code>discover_location</code>和{<cd5>}在Windows上都是无用的)。最后,COM对象是<a href="https://github.com/ewiger/mlab/blob/master/src/mlab/matlabcom.py#L57" rel="nofollow noreferrer">created as</a>:</p>
<pre><code>self.client = win32com.client.Dispatch('matlab.application')
</code></pre>
<p>作为<a href="http://www.mathworks.com/help/matlab/matlab_external/specifying-a-shared-or-dedicated-server.html" rel="nofollow noreferrer">explained here</a>,ProgID <code>matlab.application</code>不是特定于版本的,它将简单地使用<a href="http://www.mathworks.com/help/matlab/matlab_external/creating-the-server-manually.html" rel="nofollow noreferrer">registered</a>作为默认的matlabcom服务器。我们可以显式地指定我们想要的MATLAB版本(假设您有多个安装),例如<code>matlab.application.8.3</code>将选择matlabr2014a</p>
<p>所以要修复代码,IMO最简单的方法就是去掉所有关于多个MATLAB版本的逻辑(在<a href="https://github.com/ewiger/mlab/blob/master/src/mlab/mlabraw.py" rel="nofollow noreferrer">Windows part of the code</a>中),让它按原样创建matlabcom对象。我没有尝试过,但我不认为这太牵扯。。。祝你好运!在</p>
<hr/>
<h2>编辑:</h2>
<p>我下载了这个模块,并设法让它在Windows上运行(我使用的是python2.7.6和matlabr2014a)。以下是更改:</p>
^{pr2}$
<p>首先,我添加了缺少的<code>find_available_releases</code>函数。我这样做是为了让它报告所有的MATLAB版本都是可用的(就像我上面解释的,这并不重要,因为COM对象的创建方式)。一个更好的修复方法是使用Windows注册表检测已安装/注册的MATLAB版本(检查键<code>HKCR\Matlab.Application.X.Y</code>,并在<code>HKCR\CLSID</code>中跟踪它们的CLSID)。这样你就可以真正地选择和选择运行哪个版本。在</p>
<p>我还修复了两个不相关的错误(一个是作者忘记了函数的返回值,另一个是不必要地创建了两次包装器对象)。在</p>
<p>注意:在测试期间,每次调用脚本时不启动/关闭MATLAB实例可能会更快。这就是为什么我在<code>close</code>函数中注释了<code>self.eval('quit();')</code>。这样,您就可以使用<code>matlab.exe -automation</code>(只执行一次),然后在不关闭会话的情况下重复使用会话。完成后只需终止进程:)</p>
<p>下面是一个Python示例来测试模块(我还展示了与NumPy/SciPy/Matplotlib的比较):</p>
<h3>试验_mlab.py公司</h3>
<pre class="lang-python prettyprint-override"><code># could be anything from: latest_release, R2014b, ..., R2006a
# makes no difference :)
from mlab.releases import R2014a as matlab
# show MATLAB version
print "MATLAB version: ", matlab.version()
print matlab.matlabroot()
# compute SVD of a NumPy array
import numpy as np
A = np.random.rand(5, 5)
U, S, V = matlab.svd(A, nout=3)
print "S = \n", matlab.diag(S)
# compare MATLAB's SVD against Scipy's SVD
U, S, V = np.linalg.svd(A)
print S
# 3d plot in MATLAB
X, Y, Z = matlab.peaks(nout=3)
matlab.figure(1)
matlab.surf(X, Y, Z)
matlab.title('Peaks')
matlab.xlabel('X')
matlab.ylabel('Y')
matlab.zlabel('Z')
# compare against matplotlib surface plot
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.gca(projection='3d')
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap='jet')
ax.view_init(30.0, 232.5)
plt.title('Peaks')
plt.xlabel('X')
plt.ylabel('Y')
ax.set_zlabel('Z')
plt.show()
</code></pre>
<p>以下是我得到的输出:</p>
<pre><code>C:\>python test_mlab.py
MATLAB version: 8.3.0.532 (R2014a)
C:\Program Files\MATLAB\R2014a
S =
[[ 2.41632007]
[ 0.78527851]
[ 0.44582117]
[ 0.29086795]
[ 0.00552422]]
[ 2.41632007 0.78527851 0.44582117 0.29086795 0.00552422]
</code></pre>
<p><img src="https://i.stack.imgur.com/T1DKe.png" alt="matlab_peaks_surf"/>
<img src="https://i.stack.imgur.com/TdJuT.png" alt="matplotlib_peaks_surf"/></p>
<hr/>
<h2>编辑2:</h2>
<p>以上更改已被<a href="https://github.com/ewiger/mlab/pull/3" rel="nofollow noreferrer">accepted</a>合并为<code>mlab</code>。在</p>