Usando a solução de uma equação diferencial em dois comandos de plotagem separados em Mathematica
-
19-09-2019 - |
Pergunta
Eu encontrei um problema ao tentar usar a resposta de um NDSOLVE em dois comandos de plotagem separados. Para ilustrar o problema, usarei uma equação diferencial simples e apenas um comando da plotagem. Se eu escrever algo assim:
{Plot[x[t], {t, 0, 10}], x[4]}
/. NDSolve[{x'[s] == - x[s], x[0] == 1}, x, {s, 0, 10}]
Ele resolve a equação e calcula x [4] sem nenhum problema, mas o enredo fica vazio, e eu não tenho idéia do porquê.
No meu problema real, minha equação é um sistema bastante complicado para várias funções e, em vez de x [4 Eu desenho um gráfico paramétrico das funções resolvidas. Eu finalmente pretendo incluir tudo isso em um Manipular declaração então eu não quero o NDSOLVE A declaração para aparecer mais de uma vez (leva muito tempo) e não posso simplesmente calculá -la com antecedência (pois possui muitos parâmetros).
EDIT: Gostaria de esclarecer e expandir minha pergunta: o que eu realmente quero fazer é incluir minha declaração de plotagem em um Manipular declaração da seguinte maneira:
Manipulate[{Plot[x[t], {t, 0, 10}], x[4]}
/. NDSolve[{x'[s] == - a*x[s], x[0] == 1}, x, {s, 0, 10}]
,{{a,1},0,5}]
Desde que apenas o Manipular A instrução dá valor ao parâmetro uma, Não posso calcular a resposta para o NDSOLVE antecipadamente. Além disso, como meu sistema de equações real é muito complicado e não linear, não posso usar a função simbólica Dsolve.
Desculpe se não estava claro antes.
Solução
Seu problema é que a plot [] faz algumas coisas engraçadas para tornar a plotagem mais conveniente, e uma das coisas que ele faz é simplesmente plotar as coisas que não pode avaliar numericamente. Então, na expressão que você postou,
Plot[x[t], {t, 0, 10}]
Apenas vai em frente e avalia antes da Fazendo a substituição da regra com a solução do NDSOLVE, produzindo um objeto gráfico de um gráfico vazio. Esse objeto gráfico não contém referência a X, portanto, não há nada a substituir.
Você deseja garantir que a substituição seja feita antes da plotagem. Se você também deseja garantir que a substituição possa ser feita em vários lugares, você deseja armazenar a solução em uma variável.
sol = NDSolve[{x'[s] == - x[s], x[0] == 1}, x, {s, 0, 10}];
{Plot[Evaluate[x[t] /. sol], {t, 0, 10}], x[4] /. sol}
A avaliação [] no gráfico garante que o Mathematica faça apenas a substituição uma vez, em vez de uma vez por cada ponto da plotagem. Não é importante para uma simples substituição de regra como essa, mas é um bom hábito usá -lo, caso você queira planejar algo mais complicado.
Para fazer isso funcionar de maneira manipulada, a maneira simples é usar com [], que é uma das construções de escopo da Mathematica; É o único a usar onde você deseja apenas substituir algo sem usá -lo como variável, você pode mudar.
Por exemplo,
Manipulate[
With[{sol = NDSolve[{x'[s] == - x[s], x[0] == 1}, x, {s, 0, 10}]},
{Plot[x[t] /. sol // Evaluate, {t, 0, 10}, PlotRange -> {0, 1}],
x[4] /. sol}],
{{a, 1}, {0, 5}}]
Use a opção Plotrange para manter o eixo y fixo; Caso contrário, as coisas saltarão de maneira feia como o valor de uma alteração. Quando você faz coisas mais complexas com manipular, há várias opções para controlar a velocidade das atualizações, o que pode ser importante se sua ODE for complicada o suficiente para demorar um pouco para resolver.
Outras dicas
Enquanto isso, encontrei outra maneira de fazer isso. É menos elegante, mas usa apenas uma substituição, então pensei em postá -lo aqui também.
A idéia é usar Aguarde no Enredo Portanto, não seria avaliado, faça a substituição da regra e depois Lançamento, pouco antes do Manipular.
Manipulate[ReleaseHold[
Hold[ {Plot[x[t], {t, 0, 10}, PlotRange -> {0, 1}], x[4]} ]
/.NDSolve[{x'[s] == -a x[s], x[0] == 1}, x, {s, 0, 10}]
], {{a, 1}, 0, 5}]