我有一個用於計算酸性變化的ODE。一切工作都很好,只要酸度達到臨界點時我就想改變常數。它應該是我想模擬的某種不可逆轉的效果。在特定條件下用標誌改變ODE計算中的常數
我的常量來自一個結構文件(c)我在ODE函數中加載一次。
[Time,Results] = ode15s(@(x, c) f1(x, c),[0 c.length],x0,options);
主要的問題我這裏是不會告訴Matlab來改變常數,但記得如果在模擬過程中已經發生過一次。所以Matlab應該採用不可逆轉的常數而不是我在開始時提供的常數。
我想寫一個在ODE運行時保存的標誌和一個if
條件,「如果標誌存在,改變常量」。怎麼做?
更新我: 問題就迎刃而解了
這裏第一個自己的解決方案,它不是拋光和需要結構文件的方法。這意味着,事件應該突然改變的常量必須是結構文件,這些結構文件將ODE函數交給應該評估的函數(請參閱上面的ODE語法)。該函數接受的輸入是這樣的:
function [OUTPUT] = f1(t, x, c)
% So here, the constants all start with c. followed by the variable name. (because they are structs instead of globals)
%% write a flag when that event happens
if c.someODEevent <= 999 && exist ('flag.txt') == 0
dlmwrite ('flag.txt',1);
end
%% next iteration will either write the flag again or not. more importantly, if it exists, the constant will change because of this.
if exist ('flag.txt') == 2
c.changingconstant = c.changingconstant/2;
end
end
請看Horchlers樣的回答,你必須要小心,這樣的步驟可能引入不準確,你必須要小心檢查,如果你的代碼做什麼是應該去做。
謝謝,我擔心可能需要調用兩個ODE函數。我試圖避免它,但沒有更簡單的方法?我試圖不讓一個已經複雜的腳本變得更復雜。 – Easyquestionsonly 2015-02-11 13:03:01
常量im傳遞是必要的,因爲我需要使常量在Excel工作表中可編輯,在matlab工作空間中導入爲變量,並最終將它們轉換爲結構體以傳入函數。整個原因是爲了避免在編輯腳本時使用matlab並避免使用大量內存的全局變量(這些常量必須被至少兩個函數所知)。看到這裏:http://stackoverflow.com/questions/27218341/what-is-the-best-way-to-pass-lots-of-constants-and-workspace-variables-to-an-fso – Easyquestionsonly 2015-02-11 13:06:07
@Easyquestionsonly:除非你想要不準確並且可能完全錯誤的結果,否則沒有別的辦法。是的,你[不應該使用全局變量](http://mathworks.com/matlabcentral/answers/51946-systematic-do-not-use-global-don-t-use-eval)。你給出的鏈接是'fsolve' - 目標函數只有一個必需的輸入。 ODE求解器,例如'ode15s',有兩個。如果'c'是一個固定參數或一組參數,那麼它們應該作爲第三個參數傳遞。請參閱我的[本答案](http://stackoverflow.com/a/16681767/2278029),其中'n'作爲參數傳遞給集成函數'f'。 – horchler 2015-02-11 18:20:23