相关疑难解决方法(0)

Matlab函数处理工作区shenanigans

简而言之:是否有一种优雅的方式来限制匿名函数的范围,或者在这个例子中是否有Matlab破坏?

我有一个函数创建一个在管网解算器中使用的函数句柄.它接受一个网络状态作为输入,其中包括有关管道及其连接的信息(如果必须,还包括边和顶点),构造一个大字符串,在函数形式时将返回一个大矩阵,并"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, ';']);
Run Code Online (Sandbox Code Playgroud)

这个函数按预期工作,但每当我需要保存包含此函数句柄的后续数据结构时,它需要一个可笑的内存量(150MB) - 巧合的是在创建此函数时整个Matlab工作区(~~) 150MB).这个函数处理的变量需要来自getPipeEquations工作区并不是特别大,但是当我检查函数句柄时,更疯狂的是:

>> f = functions(Network.jacobianFun)
f = 

     function: [1x8323 char]
         type: 'anonymous'
         file: '...\pkg\+adv\+pipe\getPipeEquations.m'
    workspace: {2x1 cell}
Run Code Online (Sandbox Code Playgroud)

...工作区字段包含getPipeEquations具有的所有内容(顺便说一句,它不是整个Matlab工作区).

如果我改为将eval语句移动到子函数以试图强制范围,则句柄将更加紧凑(~1MB):

function Jv = getJacobianHandle(Jv_str,listConnected,areaPipes,endNodes,D,L,g,dz)
eval(['Jv = @(v,f,rho)', Jv_str, ';']);
Run Code Online (Sandbox Code Playgroud)

这是预期的行为吗?是否有更优雅的方式来限制此匿名函数的范围?

作为附录,当我多次运行包含此函数的模拟时,清除工作空间变得非常缓慢,这可能与Matlab处理函数及其工作空间有关,也可能与之无关.

matlab closures scope eval anonymous-function

11
推荐指数
1
解决办法
1595
查看次数

标签 统计

anonymous-function ×1

closures ×1

eval ×1

matlab ×1

scope ×1