Arrays 在Matlab中为ODE求解器将大型数组分解为多个有意义的变量
我正在尝试改进使用Matlab/倍频程ode解算器模拟动态系统的方法,更具体地说,就是将主要变量数组拆分为更小、更具意义/可读性的变量的方法 我实现ode45调用的odefun的标准方法如下(一个简单的示例): 它以前对我帮助很大,但随着问题的复杂性增加(60多个州),第2、3和6步(以及在某种程度上第4步)变得难以管理且重复 更具体地说,每当我添加一个新变量时,我会在3或4个地方传播信息。我可以将每个变量的步骤2、3和4捆绑在一起,这是一个改进,因为这样信息将位于两个位置(开始和结束)。尽管如此,我的目标仍然是将所有内容放在一个位置,而不必明确地担心索引问题 以下是我所想的伪代码,我尝试采用更面向对象的方法:Arrays 在Matlab中为ODE求解器将大型数组分解为多个有意义的变量,arrays,matlab,oop,organization,Arrays,Matlab,Oop,Organization,我正在尝试改进使用Matlab/倍频程ode解算器模拟动态系统的方法,更具体地说,就是将主要变量数组拆分为更小、更具意义/可读性的变量的方法 我实现ode45调用的odefun的标准方法如下(一个简单的示例): 它以前对我帮助很大,但随着问题的复杂性增加(60多个州),第2、3和6步(以及在某种程度上第4步)变得难以管理且重复 更具体地说,每当我添加一个新变量时,我会在3或4个地方传播信息。我可以将每个变量的步骤2、3和4捆绑在一起,这是一个改进,因为这样信息将位于两个位置(开始和结束)。尽管如
%%( some place before the call to the ode solver)
% new position representation
newstate.name="pos"
newstate.size=3;
newstate.alt_names={"x","y","z"}; % or alternatively, nothing
newstate.derivative="vel";
state_organizer.add(newstate);
% new velocity representation
newstate.name="vel";
newstate.size=3;
newstate.alt_names={"u","v","w"};
newstate.derivative="a";
state_organizer.add(newstate);
function d_states=model_I_would_prefer(t,states,state_organizer)
% 1- parameter definition (the same as before)
% does 2,3 and (possibly)4 without having to worry about indexes
state_organizer.extract(states);
% 5- dynamics ( the same as before)
% does the same as 6
state_organizer.update_derivatives(d_states);
end
在一种有指针的语言中,这样做很简单。可能是这样的:
% encoding the velocity state
newstate.variable_ptr=&vel;
newstate.derivative_ptr=&a
...
% extracting from the main state array ( states)
for each state in state_organizer
*(state.variable_ptr)=states(state.index)
end
...
% transferring to array d_states
for each state in state_organizer
d_states(state.index)=*(state.derivative_ptr)
end
% adding a state ( vel)
organizer.state(n).index=organizer.last_index+(1:size);
organizer.state(n).derivative='a';
organizer.state(n).name='vel';
organizer.last_index=organizer.last_index+size;
...
% step 6 ( similar in essence to step 2)
for each state in organizer
eval(['d_states(' organizer.state(k).index ')=' organizer.state(k).derivative ';'])
end
Matlab没有指针(,但是每个变量都需要在一个对象内)。一种替代方法是使用函数“eval”,但它看起来是这样的:
% encoding the velocity state
newstate.variable_ptr=&vel;
newstate.derivative_ptr=&a
...
% extracting from the main state array ( states)
for each state in state_organizer
*(state.variable_ptr)=states(state.index)
end
...
% transferring to array d_states
for each state in state_organizer
d_states(state.index)=*(state.derivative_ptr)
end
% adding a state ( vel)
organizer.state(n).index=organizer.last_index+(1:size);
organizer.state(n).derivative='a';
organizer.state(n).name='vel';
organizer.last_index=organizer.last_index+size;
...
% step 6 ( similar in essence to step 2)
for each state in organizer
eval(['d_states(' organizer.state(k).index ')=' organizer.state(k).derivative ';'])
end
考虑到这一点和我的目标(每个州的信息放在一个地方,自动索引),我的主要问题是:
如果我正确理解您的需求,那么问题在于步骤2和步骤4中的硬编码数字1、2和3。在函数中提供它们作为输入将使函数具有足够的通用性,从而可用于更大类别的模型 说: 您还可以将
nx、ny、nz
包装成一个数组(速度也是如此),然后说pos\u ind
n_pos = numel(pos_ind);
nx = pos_ind(1);
ny = pos_ind(2);
nz = pos_ind(3);
然后,在调用函数并将它们作为输入添加之前,您只需定义
pos_ind
和vel_ind
。您可以根据具体问题进行适当的调整 谢谢你的回复,但这不是我的主要问题。这些硬编码数字通常非常具体、小且不可变(例如,速度向量为3DOF)。我会制作和编辑,试图使它更清楚,我很抱歉,如果我是混淆。