避免在 matlab 函数中求值

Avoiding eval in matlab function

我使用matlab中的符号工具箱来生成一些很长的符号表达式。然后我使用 matlabFunction 生成一个函数文件。 假设有三个参数:p1、p2 和 p3。 我有一个包含字符串 {'p1'、'p2'、'p3'} 的单元格。 在模型的推导中,我在循环中使用 eval 从中生成符号变量 p1、p2 和 p3,并将它们堆叠在向量 par 中。 然后在 matlabFunction 中,我指定 par 作为输入。 此外,我将单元格字符串保存在 .mat 文件中。

然后当我想模拟这个模型时,我可以使用 .mat 文件中的 30 个可用参数及其值中的那个字符串单元格构造这个参数数组。

优点:如果我将一个参数添加到 .我可以改变顺序,乱七八糟,但旧型号仍然有效。 坏处: 把东西转成函数文件导致这个错误(psi是参数之一):

错误:文件:f_derive_model.m 行:96 列:5 "psi" 以前似乎用作函数或 命令,与它在这里作为一个名称的使用相冲突 多变的。 此错误的可能原因是您忘记了 初始化变量,或者你已经初始化了它 隐式使用 load 或 eval.

显然正在进行一些不必要的检查,因为变量将在 eval 语句中初始化。

问题:如何避免 eval 但保持参数列表独立于模型内容。

推导长方程的代码:

% Model parameters
mdl.parameters = {'mp','mb','lp','lb','g','d','mP','mM','k','kt'};    

par = [];

for i=1:length(mdl.parameters)
    eval(strcat(mdl.parameters{i}, '=sym(''', mdl.parameters{i}, "');"));
    eval(sprintf(['par = [par;' mdl.parameters{i} '];']));
    end

%% Calculate stuff

matlabFunction(MM,'file',[modelName '_mass'],'vars',{par},'outputs',{'M'});

使用生成文件的代码:

    getparams
    load('m3d_1')

    par = [];
    for i=1:length(mdl.parameters)
        eval(sprintf(['par = [par;params.' mdl.parameters{i} '];']));
    end

看看如何,只要我指定正确的值,例如 params.mp,它总是被分配给与 par 向量中的符号变量 mp 对应的输入。我不想丢失它并且必须跟踪顺序等等,我也不想用所有参数一个一个地调用我的函数。

实际上,即使 "public opinion" 确认最好避免使用 eval 函数,我也认为您的方法没有任何问题。另一种方法是使用 assignin 函数,如下所示:

% use 'caller' instead of 'base' if this code runs within a function

for i = 1:numel(mdl.parameters)
    var_name = mdl.parameters{i};
    assignin('base',var_name,sym(var_name));
end

在第二种情况下(关于 par 变量的情况)我会改用 getfield 函数:

par_len = numel(mdl.parameters);
par = cell(par_len,1);

for i = 1:par_len
    par{i} = getfield(params,mdl.parameters{i});
end

或者,或者,这种方法:

par_len = numel(mdl.parameters);
par = cell(par_len,1);

for i = 1:par_len
    par{i} = params.(mdl.parameters{i});
end