MATLAB:脚本与输出参数相关的函数

时间:2013-11-29 09:03:56

标签: matlab function return-value workspace

我有一个脚本,由于运行时间过长而可能会中止,之后会继续。我们假设看起来有点像这样:

data = []; % can't preallocate as I don't know the number of entries yet here...
while(1)
   % ...
   data = [data; someNewEntry];
end

关于它的好处是,当作为脚本运行时,每当我中止它时,我在te工作区中都有变量data

但是我想把它转换成一个函数,因为脚本有很多变量,并且用它来填满我的工作区。我们假设我现在将其转换为:

function data = myFnc()
data = []; % can't preallocate as I don't know the number of entries yet here...
while(1)
   % ...
   data = [data; someNewEntry];
end

问题nnow是:当我中止该功能时,我正在丢失data中已经为此做出的所有条目。如何解决此问题并在中止函数时返回当前向量data?我想出的唯一可能的解决方案就是在for-loop中使用类似的东西:

if(nargout == 1)
   assignin('caller','data', data);
end

但不知怎的,我不太喜欢这种做法。但好吧,对我来说似乎没问题。但有一点仍然让我烦恼:使用它时我总是将数据分配给workspace-var data,因为我不知道如何获取调用者的输出变量的名称(即{{1 }} - >它将是bla = myFnc(),因此bla)。我知道有matlab函数assignin('caller','bla', data);但我找不到输出变量的等价物。 非常感谢提前!

3 个答案:

答案 0 :(得分:3)

我可以想到2个推荐的解决方案:

<强> 1。中断功能而不会丢失工作区

正如我所描述的here,如果你总是打开

,这应该不是问题
`dbstop if error`

<强> 2。经常保存变量

使用您的assignin解决方案,您已经接近,因为它将变量“保存”到基础工作区。但是,这仍然不是存储变量的非常安全的空间。因此我建议用以下方法保存它们:

save data data

如果第二个选项太过性能杀手,那么你可以每1000次迭代就做一次。

答案 1 :(得分:1)

一种解决方案可能是使用全局变量。使用简单计数器的示例:

function data = myFnc()

global data; % make it a global
if isempty(data) % not yet initialized
    data = [];
end

i = 1;
while(i < 10)
   pause(1)
   disp(i)
   data = [data, i];
   i = i + 1;
end

然后在命令行上,您必须执行global data一次,然后才能访问已保存的状态。快速测试,我在运行时用CTRL + C中止了程序:

>> clear
>> clear global
>> x = myFnc();
     1
     2
     3
     4
Operation terminated by user during myFnc (line 10)
>> x
Undefined function or variable 'x'.
>> data
Undefined function or variable 'data'.
>> global data
>> data
data =
     1     2     3     4

通常不建议使用全局变量,但有时它们可​​能很有用。我有时使用全局变量来缓存昂贵的计算,这样每次启动Matlab时它只需要计算一次:

global data;
if isempty(data)
    data = expensive_calculation();
end

对于复杂的程序,可能有更简洁的方法将一些状态从一次迭代保存到另一次迭代(实现一些对象?,将状态对象从一次迭代传递到另一次迭代?,保存到文件?),但对于一些快速和脏脚本,使用全局变量可能是最简单的方法。

答案 2 :(得分:1)

另一个选择是使用MATLAB参考类型变量。例如,您可以使用containers.Map,如下所示:

m = containers.Map();
myFcn(m);
% Later, after hitting CTRL-C
m('data') % get latest value

使用这样的函数:

function myFcn(map)
data = [];
while true
    data = [data, rand()];
    map('data') = data;
end