简而言之:有没有一种优雅的方法来限制匿名函数的范围,或者这是Matlab在这个例子中的问题?
我有一个函数,它创建一个函数句柄,用于管道网络求解器。它将Network状态作为输入,其中包括有关管道及其连接的信息(如果必须,即边缘和顶点),构造一个大字符串,该字符串在函数形式下返回大矩阵,并"evals"该字符串以创建句柄。
function [Jv,...] = getPipeEquations(Network)
... %// some stuff happens here
Jv_str = ['[listConnected(~endNodes,:)',...
' .* areaPipes(~endNodes,:);\n',...
anotherLongString,']'];
Jv_str = sprintf(Jv_str); %// This makes debugging the string easier
eval(['Jv = @(v,f,rho)', Jv_str, ';']);
这个函数按预期工作,但是每当我需要保存包含这个函数句柄的后续数据结构时,它需要消耗非常大的内存(150MB),巧合的是,这正好与此函数创建时Matlab工作区的大小(~150MB)相同。从getPipeEquations工作区所需的这个函数句柄的变量并不特别大,但更糟糕的是,当我检查函数句柄时:
>> f = functions(Network.jacobianFun)
f =
function: [1x8323 char]
type: 'anonymous'
file: '...\pkg\+adv\+pipe\getPipeEquations.m'
workspace: {2x1 cell}
工作区字段包含了getPipeEquations中的所有内容(顺便说一句,这并不是整个Matlab工作区)。
如果我将eval语句移动到一个子函数中,试图强制使用范围,则句柄将更紧凑地保存(约1MB):
function Jv = getJacobianHandle(Jv_str,listConnected,areaPipes,endNodes,D,L,g,dz)
eval(['Jv = @(v,f,rho)', Jv_str, ';']);
这是预期行为吗?有没有更优雅的方法限制这个匿名函数的范围?
另外,当我多次运行包括这个函数的模拟时,清除工作区变得非常缓慢,这可能与Matlab处理该函数及其工作区有关,也可能不相关。
evalin('base', ...)
吗?那有什么不同吗? - John Colby