5

有没有办法从外部调用 Matlab 函数,特别是通过 Windows cmd(还有 Linux 终端、LUA 脚本等),而无需每次都打开一个新的 Matlab 实例?

例如在cmd

matlab -sd myCurrentDirectory -r "function(parameters)" -nodesktop -nosplash -nojvm

相对较快地打开一个新的 Matlab 实例并执行我的函数。这个简化的 matlab 提示的打开和关闭大约需要 2 秒(无需计算) - 因此 4000 次执行需要超过 2 小时。我想避免这种情况,因为被调用的函数总是位于同一个工作区中。可以总是在同一个实例中完成吗?

我已经做了一些研究,发现了MATLAB COM Automation Server的可能性,但对我来说似乎很复杂,我没有看到使它适用于我的案例的基本步骤。有什么建议吗?

我不熟悉,c/c++/c#但我正在考虑使用python(但只是在最坏的情况下)。

4

4 回答 4

3

基于@Ilya Kobelevskiy 的无效但经过深思熟虑的想法,这里是最终的解决方法:

 function pipeConnection(numIterations,inputFile)

 for i=1:numIterations

 while(exist('inputfile','file'))

     load inputfile;
     % read inputfile -> inputdata
     output = myFunction(inputdata);

     delete('inputfile');
 end

 % Write output to file
 % Call external application to process output data
 % generate new inputfile 

 end;

另一个方便的解决方案是编译 Matlab 函数的可执行文件:

mcc -m myfunction

使用以下命令运行此.exe文件cmd

cd myCurrentDirectory && myfunction.exe parameter1 parameter2

请注意,参数现在作为字符串传递,并且.m需要考虑到调整原始文件。

进一步说明:

  • 我想 Matlab 仍然需要安装在系统上,尽管没有必要运行它。
  • 我不知道这种方法分别限制了底层函数的复杂性有多远。
  • 与问题中给出的初始方法相比,加速相对较小
于 2013-09-13T17:25:17.873 回答
1

如果您使用您描述的方式从命令行启动 MATLAB -r,那么它将始终按照您的描述启动一个新实例。我不相信有办法解决这个问题。

如果您从 C/C++ 应用程序调用 MATLAB,MATLAB 会提供MATLAB 引擎接口,该接口将连接到任何正在运行的 MATLAB 实例。

否则,您提到的 MATLAB 自动化服务器接口是正确的方法。如果您发现它很复杂,我建议您发布一个单独的问题,详细说明您尝试过的内容以及遇到的困难。

为了完整起见,我将提到 MATLAB 也 一个 未记录的 接口,可以直接从 Java 调用 - 但是,由于它是未记录的,因此很难正确处理,并且可能会在版本之间发生变化,因此您不应该依赖它。


编辑:从 R2014b 开始,MATLAB 提供了 MATLAB Engine for Python,您可以通过它从 Python 脚本自动化 MATLAB。从 R2016b 开始,还有 MATLAB Engine for Java。如果有人以前考虑过上面提到的未记录的 Java 技术,那么现在这就是要走的路。

于 2013-09-13T08:56:53.797 回答
1

在此处公开的几种方法中,有一种解决方法可以减少多个 matlab 调用的执行时间。这个想法是在 matlab 会话中多次运行自定义函数。

例如,myRand.m函数定义为

function r = myRand(a,b)
r = a + (b-a).*rand;

在 matlab 命令窗口中,我们生成这样的单行命令

S = [1:5; 1:5; 101:105];
cmd_str = sprintf('B(%d) = myRand(%d,%d);', S)

它生成以下命令字符串B(1) = myRand(1,101);B(2) = myRand(2,102);B(3) = myRand(3,103);B(4) = myRand(4,104);B(5) = myRand(5,105);,该字符串在单个 matlab 会话中执行

matlab -nojvm -nodesktop -nosplash -r "copy_the_command_string_here";

其中一个限制是您需要连续运行 4000 个函数调用。

于 2013-09-13T11:04:20.790 回答
1

我喜欢 Magla 提出的方法,但鉴于您在评论中说明的约束,可以改进它以在一个 matlab 会话中仍然运行单个函数。

想法是管道输入和输出。对于输入,您可以检查某个输入文件是否存在,如果存在,则从中读取您的函数的输入,执行工作,将输出写入另一个文件以指示脚本/函数处理结果,它的 matlab 函数已完成并正在等待下一个输入。

使用磁盘文件实现非常简单,通过内存磁盘(即,在 RAM 中打开输入/输出文件)可能会进行一些努力。

function pipeConnection(numIterations,inputFile,outputFile)

for i=1:numIterations

while(!isfile(inputFile))
sleep(50);
end;

% Read inputs

output = YourFunction(x,y,z);

% Write output to file, go to next iteration

end;
return;

如果开始时迭代次数未知,您也可以在输入文件中编码退出条件,而不是立即指定迭代次数。

于 2013-09-13T21:16:37.397 回答