Domanda

Ho alcune equazioni differenziali che ho bisogno di risolvere usando risolutori ODE di MATLAB. Mentre il equazioni differenziali stessi sono abbastanza semplici, essi dipendono da un sacco di "costanti". Queste costanti non sono universali, e devono essere forniti dal chiamante.

Un esempio ODE di questo tipo potrebbe essere:

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

Dove j, k e l sono costanti e x è una variabile.

Il modo in cui ho stato risolvere questi finora è quello di utilizzare una funzione che prende in tutti i valori iniziali e tutti i valori delle costanti (di cui ci sono circa 10) come argomenti e poi chiama una funzione interna "step" che prende un vettore della forma che si aspetta MATLAB per esso è risolutori ODE. Quindi ...

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

Tuttavia, poiché il numero di variabili e gli aumenti la dimensione del codice, questo diventa sempre meno elegante e si traduce in un pasticcio dannare-vicino illeggibile di codice. Allora, che cosa mi piacerebbe fare è di spostare la funzione passaggio per ogni sistema in un file a sé stante, senza dover a) superare le costanti alla funzione passo nella vettore di ingresso oppure b) utilizzare le variabili globali. C'è un modo ragionevole di fare questo, o devo solo aspirare e scrivere il codice brutto?

È stato utile?

Soluzione

Vorrei suggerire la creazione di funzioni specifiche "generatore" per ciascun sistema di ODE si vuole risolvere (sulla base di suggerimento di Loren a fare uso di funzioni anonime ). Ecco quello che si potrebbe apparire come per il tuo esempio:

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

Ogni funzione del generatore avrebbe accettato una serie di parametri di input e li usa per creare una funzione anonima, restituendo la funzione maniglia come uscita dalla funzione generatore. Ecco come è possibile usarlo:

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

Altri suggerimenti

Non vedo come il codice, come scritto, può lavorare dal momento che nessuno ha mai chiamate o punti per someFunctionStep. Se questo dovesse essere il primo ingresso a ode15s?

In ogni caso, è possibile scrivere una funzione someFunctionStep separato che prende varargin o ingressi. E quindi creare una funzione anonima con le costanti. Passare che in ode15s.

- Loren

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top