我使用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,但使参数列表与模型内容独立。
生成长方程的代码:
然后,当我想要模拟这个模型时,我可以使用来自.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所对应的输入中。我不想失去这个功能,也不想跟踪顺序等信息,更不想一个一个地调用我的函数。
eval
会导致文档化的性能下降,因为JIT编译器对于eval
命令被禁用了。考虑到它们在大量实例化或数据处理中的广泛使用,这几乎从来没有一个值得做出的权衡。 - sco1