在matlab函数中避免使用eval

时间:2017-12-11 13:45:41

标签: matlab function eval

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

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

优点:如果我添加一个参数,则无需跟踪不同的参数。我可以改变顺序,乱七八糟,但旧款仍然有用。 坏处: 将事物转换为函数文件会导致此错误(psi是参数之一):

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

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

问题:如何避免使用eval,但保持参数列表不依赖于模型。

导出长方程的代码:

^                 // Start of the string
(?=.*[a-zA-Z])    // Does it have a character?
[a-zA-Z\d]*       // The rest should be alphanumeric
$                 // End of the string

使用生成的文件的代码:

% 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'});

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

1 个答案:

答案 0 :(得分:1)

实际上,即使公众舆论"确认避免使用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