我想提高我模擬用Matlab /倍頻ODE求解動力系統的方法,更具體的我的變量主陣列分割成更小,更有意義的方式/可讀的變量。打破一個大陣分成幾個有意義的變量在Matlab的ODE求解器
我實施由ODE45稱爲odefun的標準方式是如下(一個簡單的例子):
function d_states=model_as_I_usually_do(t,states)
% 1- parameter definition
m=1;
k=2;
% 2- index definition
pos_i=1:3; %position
vel_i=pos_i(end)+(1:3); %velocity
% 3- extracting data from states vector
pos=states(pos_i);
vel=states(vel_i);
% 4- even more specific renaming for convenince
x=pos(1);y=pos(2);z=pos(3);
u=vel(1);v=vel(2);w=vel(3);
% 5- dynamics
F=[1,1,1]';
a=F/m-k/m*[x y^2 z^3]'; %some equations
% 6- filling output (derivative) vector
d_states(pos_i)=vel;
d_states(vel_i)=a;
end
它之前幫我很多,但步驟2,3和6(以及在一定程度上4)隨着問題的複雜性增加(60多個州),變得難以管理和重複性管理。
更具體地說,每當我添加一個新的變量,我在3或4個地方傳播信息。我可以將步驟2,3和4捆綁在一起,代替每個變量,這是一個改進,因爲那時信息將在2個位置(開始和結束)。儘管如此,我的目標是將所有內容都放在1個位置,不必擔心索引
以下是我心中的一個僞代碼,我嘗試遵循更多面向對象的方法:
%%(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
Matlab的不具有指針(it has handles,但隨後每一個變量將需要一個對象內)。一個替代方法是使用功能「EVAL」,not a good one,但它應該是這樣的:
% 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/Octave中實現類似的東西? (不考慮Simulink)。
- 是否有替代方法可以做得更好(更有組織或更可行)?例如,使用字典或自動生成M文件。
- 與1和2相同,但考慮其他語言或資源,如python(我正在考慮切換到它)或C++。
感謝您的回覆,但這不是我的主要問題。那些硬編碼的數字通常是非常具體的,小而不可變的(例如速度矢量的3DOF)。我會編輯和編輯以便更加清晰,如果我感到困惑,我很抱歉。 – guivenca