通过外部应用程序调用函数而不打开 Matlab 的新实例

Posted

技术标签:

【中文标题】通过外部应用程序调用函数而不打开 Matlab 的新实例【英文标题】:Call a function by an external application without opening a new instance of Matlab 【发布时间】:2013-09-17 21:00:03 【问题描述】:

有没有办法从外部调用 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(但只是在最坏的情况下)。

【问题讨论】:

这是 SO 上的 an example,它使用终端多路复用器 tmux 在已经运行的 matlab 会话上附加一个进程。 @Magla :似乎是 Linux 的完美解决方案,当我可以将我的接口移植到 Linux 时,我一定会尝试它。目前我仅限于 Windows,并尝试在此处找到临时解决方案。 另一个名为screen的软件,与tmux相反,可以通过cygwin执行(参见cygwin.com/ml/cygwin-announce/2013-06/msg00026.html 【参考方案1】:

基于@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

使用cmd 运行这个.exe-文件:

cd myCurrentDirectory && myfunction.exe parameter1 parameter2

请注意,参数现在作为字符串传递,因此需要调整原始 .m-文件。

补充说明:

我猜Matlab仍然需要安装在系统上,不过 没有必要运行它。 不知道这个方法分别限制到什么程度 基础功能。 与问题中给出的初始方法相比,加速是 相对较小

【讨论】:

【参考方案2】:

在此处公开的几种方法中,有一种解决方法可以减少多个 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 个函数调用。

【讨论】:

您建议的基本问题是,例如第二个函数调用由第一个调用的参数确定。并且两次调用之间的输出和输入由另一个应用程序处理。【参考方案3】:

我喜欢 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;

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

【讨论】:

好方法!我必须进行一些必要的编辑才能使其工作,1)我无法使用!isfile 命令,2)每次迭代后都必须删除输入文件。看看我的编辑,然后我接受答案。 同行审稿人拒绝了我的编辑,我不知道为什么。但是像这样你的答案是行不通的。 @thewaywalk - 是的,我在写答案时没有在我的电脑上安装 matlab,所以无法检查语法 - 它更多地是为了说明想法,而不是一个工作示例。我很高兴这种方法奏效了!【参考方案4】:

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

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

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

为了完整起见,我将提到 MATLAB 还可以直接从 Java 调用 has an undocumented interface - 但是,由于它没有记录,因此很难正确处理,并且可能会发生变化跨版本,所以你不应该依赖它。


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

【讨论】:

以上是关于通过外部应用程序调用函数而不打开 Matlab 的新实例的主要内容,如果未能解决你的问题,请参考以下文章

C - 从外部进程调用函数而不导出函数

详解MATLAB的函数system(),并利用它实现在MATLAB中运行(调用)外部exe程序

如何在从 Matlab 调用的 mex 函数中使用 Matlab 引擎

matlab怎么调用函数

MATLAB调用simulink时出现如下错误

使用调用外部函数的函数加载由 MATLAB Coder 生成的 DLL