2009-10-15 94 views
3

我有一些微分方程需要使用MATLAB的ODE解算器來解決。雖然微分方程本身非常簡單,但它們依賴於很多「常量」。這些常量不是通用的,需要由調用者提供。如何解決ODE不使用嵌套函數?

這種的一個例子ODE將是:

dx/dt = -j * (k + x) ./ (l + x) 

式中,j,k和l是常數,x是可變的。

到目前爲止,我一直在解決這些問題的方法是使用一個函數,它將所有初始值和所有常量(其中大約有10個)的值作爲參數,然後調用一個內部「步驟」函數,它採用MATLAB期望的ODE解算器形式的向量。所以......

function [outputVector] = someFunction(x, y, j, k, l, m, n, o) 
    function [output] = someFunctionStep(t, inputVector) 
     x = inputVector(1); 
     y = inputVector(2); 
     dx = -j .* (k + x) ./ (l + x); 
     dy = -m .* (n + y) ./ (o + y); 
     output = [dx;dy] 
    end 
    outputVector = ode15s(@someFunctionStep, [0, endTime], [x,y]); 
end 

然而,隨着變量的數目和代碼大小的增加,這變得越來越優雅,導致代碼該死的 - 近不可讀的混亂。所以,我想要做的是將每個系統的step函數移動到它自己的文件中,而不必將常量傳遞給輸入向量中的step函數,或者b)使用全局變量。有沒有這樣做的合理方式,或者我應該把它吸起來,寫出醜陋的代碼?

回答

3

我建議您要解決常微分方程的每個系統創建特定的「發電機」功能(基於Loren's suggestion要利用anonymous functions)。這裏有一個可能看起來像你的例子:

function odeFcn = makeODE(j,k,l,m,n,o) 
    odeFcn = @(t,y) [-j*(k+y(1))/(l+y(1)); -m*(n+y(2))/(o+y(2))]; 
end 

每臺發電機的功能將接受一組輸入參數,並使用它們來創建一個匿名函數,返回function handle從發電機功能的輸出。以下是如何使用它:

outputVector = ode15s(makeODE(a,b,c,d,e,f), [0,endTime], [x,y]); 
+0

這看起來好多了!謝謝! – 2009-10-16 13:53:18

4

我不明白你寫的代碼是如何工作的,因爲沒有人會調用或指向someFunctionStep。這應該是ode15s的第一個輸入嗎?

在任何情況下,您都可以編寫一個單獨的someFunctionStep函數,該函數需要varargin或輸入。然後用常量創建一個匿名函數。將它傳遞給ode15s。

--Loren

+0

是的,它應該是ode15s的第一個參數。現在修復。 – 2009-10-15 15:22:08