In short:有没有一种优雅的方法来限制匿名函数的范围,或者Matlab在这个例子中被破坏了?
我有一个函数可以创建要在管网求解器中使用的函数句柄。它将网络状态作为输入,其中包括有关管道及其连接的信息(或者如果必须的话,还可以包括边和顶点),构造一个大字符串,该字符串在函数形式时将返回一个大矩阵,并“评估”该字符串以创建句柄。
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 拥有的所有内容(顺便说一下,not整个 Matlab 工作区)。
如果我将 eval 语句移至子函数以尝试强制作用域,则句柄将保存得更紧凑(~1MB):
function Jv = getJacobianHandle(Jv_str,listConnected,areaPipes,endNodes,D,L,g,dz)
eval(['Jv = @(v,f,rho)', Jv_str, ';']);
这是预期的行为吗?有没有更优雅的方法来限制这个匿名函数的范围?
作为附录,当我多次运行包含此函数的模拟时,清理工作区变得非常慢,这可能与 Matlab 对函数及其工作区的处理有关,也可能无关。