How can I solve an ODE without using nested functions?

穿精又带淫゛_ 提交于 2019-12-01 23:42:39

问题


I have some differential equations that I need to solve using MATLAB's ODE solvers. While the differential equations themselves are fairly simple, they depend on a lot of "constants". These constants aren't universal, and need to be supplied by the caller.

An example ODE of this sort would be:

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

Where j, k and l are constants and x is a variable.

The way I have been solving these so far is to use a function that takes in all the initial values and all the values of the constants (of which there are around 10) as arguments and then calls an inner "step" function which takes a vector of the form that MATLAB expects for it's ODE solvers. So...

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

However, as the number of variables and the code size increases, this becomes less and less elegant and results in a damn-near unreadable mess of code. So, what I'd like to do is to move the step function for each system into a file of its own without having to a) pass the constants to the step function in the input vector or b) use global variables. Is there any reasonable way of doing this, or should I just suck it up and write the ugly code?


回答1:


I would suggest creating specific "generator" functions for each system of ODEs you want to solve (based on Loren's suggestion to make use of anonymous functions). Here's what one might look like for your example:

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

Each generator function would accept a set of input parameters and use them to create an anonymous function, returning the function handle as an output from the generator function. Here's how you can then use it:

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



回答2:


I don't see how your code, as written, can work since no one ever calls or points to someFunctionStep. Should that be the first input to ode15s?

In any case, you can write a separate someFunctionStep function that takes varargin or inputs. And then create an anonymous function with the constants. Pass that into ode15s.

--Loren



来源:https://stackoverflow.com/questions/1572268/how-can-i-solve-an-ode-without-using-nested-functions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!