Pergunta

Eu tenho algumas equações diferenciais que eu preciso resolver usando MATLAB a ODE solucionadores de problemas.Enquanto as equações diferenciais em si são bastante simples, eles dependem de um monte de "constantes".Estas constantes não são universais, e precisam ser fornecido pelo chamador.

Um exemplo ODE deste tipo seria:

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

Onde j, k e l são constantes e x é uma variável.

A maneira de eu ter sido resolver estes até agora é usar uma função que leva em todos os valores iniciais e todos os valores das constantes (dos quais existem cerca de 10) como argumentos e, em seguida, chama interior "passo", uma função que leva um vetor de forma que o MATLAB espera para que a ODE solucionadores de problemas.Então...

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

No entanto, como o número de variáveis e o tamanho do código aumenta, isso se torna menos e menos elegante, e resulta em uma porra-perto ilegível confusão de código.Então, o que eu gostaria de fazer é mover a função de passo de cada sistema em um arquivo de conta própria, sem ter de a) passe as constantes da função de passo no vetor de entrada ou b) utilizar variáveis globais.Existe alguma maneira razoável de fazer isso, ou eu deveria chupá-lo e escrever o feio código?

Foi útil?

Solução

Gostaria de sugerir a criação de "gerador" funções para cada sistema de Edos você quer resolver (com base no Loren sugestão para fazer uso de funções anônimas).Eis o que pode parecer, para o seu exemplo:

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

Cada gerador de função pode aceitar um conjunto de parâmetros de entrada e usá-los para criar uma função anônima, retornando a identificador de função como uma saída do gerador de função.Aqui está como você pode, em seguida, usá-lo:

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

Outras dicas

Eu não vejo como o seu código, como está escrito, pode trabalhar desde que ninguém liga ou pontos para someFunctionStep.Deve ser a primeira entrada para ode15s?

Em qualquer caso, você pode escrever um separado someFunctionStep função que leva varargin ou entradas.E, em seguida, criar uma função anônima com as constantes.Passar em ode15s.

--Loren

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top