2009-10-15 5 views
3

J'ai quelques équations différentielles que je dois résoudre en utilisant les solveurs ODE de MATLAB. Alors que les équations différentielles elles-mêmes sont assez simples, elles dépendent de beaucoup de «constantes». Ces constantes ne sont pas universelles et doivent être fournies par l'appelant.Comment puis-je résoudre un ODE sans utiliser de fonctions imbriquées?

Un exemple ODE de ce type serait:

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

j, k et l sont des constantes et x est une variable. La façon dont j'ai résolu ces problèmes jusqu'ici est d'utiliser une fonction qui prend en compte toutes les valeurs initiales et toutes les valeurs des constantes (il y en a environ 10), puis appelle un "pas" interne fonction qui prend un vecteur de la forme que MATLAB attend pour ses solveurs ODE. Alors ...

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 

Cependant, comme le nombre de variables et la taille du code augmente, cela devient de moins en moins élégant et des résultats dans un désordre sacrément-près illisible de code. Donc, ce que je voudrais faire est de déplacer la fonction d'étape pour chaque système dans un fichier qui lui est propre sans avoir a) passer les constantes à la fonction d'étape dans le vecteur d'entrée ou b) utiliser des variables globales. Y a-t-il un moyen raisonnable de le faire, ou devrais-je juste le sucer et écrire le code laid?

Répondre

3

Je suggère la création de fonctions « générateur » spécifiques pour chaque système d'équations que vous voulez résoudre (basées sur Loren's suggestion d'utiliser anonymous functions). Voilà ce qu'on pourrait ressembler à votre exemple:

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 

Chaque fonction générateur accepterait un ensemble de paramètres d'entrée et de les utiliser pour créer une fonction anonyme, renvoyant le function handle comme une sortie de la fonction de générateur. Voici comment vous pouvez l'utiliser:

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

Cela ressemble beaucoup mieux! Merci! –

4

Je ne vois pas comment votre code, tel qu'il est écrit, peut fonctionner puisque personne ne l'appelle ou ne pointe vers someFunctionStep. Est-ce que ça devrait être la première entrée à ode15s?

Dans tous les cas, vous pouvez écrire une fonction someFunctionStep séparée qui prend varargin ou des entrées. Et puis créez une fonction anonyme avec les constantes. Passez cela en ode15s.

--Loren

+0

Oui, ce devrait être le premier argument de ode15s. Fixé maintenant –

Questions connexes