2015-07-07 14 views
6

Ho una domanda generale che descriverò nel contesto di una situazione più concreta.Risolutore ODE da Lagrangian/Variational Methods in C++

Se si vuole trovare la dinamica di un doppio pendolo, si può matematicamente derivare le equazioni dei moti, riscrivere le ODE per avere una forma speciale utile per il calcolo numerico e risolvere le ODE usando, diciamo, odeint in C++ (vedere un esempio di questo su overflow dello stack https://stackoverflow.com/a/30582741).

Ora immagina di voler fare lo stesso per n pendula accoppiata (n nota in fase di esecuzione). Questo ci impone di scrivere una cosiddetta Lagrangiana (energia cinetica - energia potenziale) e diversi derivati ​​di queste funzioni saranno le ODE che dobbiamo risolvere. Inoltre queste ODE devono essere riscritte in un formato adatto per odeint. Questo può per generale essere difficile da fare a mano.

In programmi come Mathematica e Maple, questo è in realtà abbastanza semplice. Si può ricavare esplicitamente le ODE necessarie dalla lagrangiana e il risolutore ODE non ha bisogno che noi mettiamo le equazioni in una forma speciale (vedi esempio in matematica qui https://mathematica.stackexchange.com/a/84279).

È possibile fare una cosa del genere in C++ senza passare troppi problemi?

Potenziale Approccio:

Un potenziale approccio potrebbe essere quello di utilizzare il pacchetto C++ ginac. Questo può aiutarci a ricavare analiticamente le ODE. Ma non so come riscrivere le espressioni provenienti da ginac, in una forma adatta per il calcolo numerico in odeint. Qualche idea?

+1

Per n noto solo in fase di esecuzione, temo che si stiano affrontando difficoltà quasi impossibili. Se conosci n al momento della compilazione, penso che potresti ottenere un simile calcolo basato su modelli di differenziazione e espressione automatici. Dal mio controllo (superficiale) di ginac penso che questa libreria sia basata anche su modelli di espressioni, quindi avrebbe bisogno di n in fase di compilazione. – mariomulansky

+0

@mariomulansky Grazie mille per il commento. Per ora sarei felice se potessi farlo in tempo di compilazione. Come posso utilizzare i modelli di espressione per convertire l'output ginac in un formato che odeint comprende? Esiste qualche modo standard semplice? – Heidar

+1

Non ho esperienza con GiNaC, quindi non posso essere di grande aiuto. Tuttavia, leggendo di più attraverso il loro tutorial, mi viene in mente che potresti essere in grado di costruire un'espressione in fase di runtime, differenziarla e valutare il risultato. Quindi il mio primo commento sopra potrebbe essere errato. Cercare di scrivere il Langragian come espressione GiNaC, differenziarlo e usare le espressioni risultanti nel rhs per i suoni odeint sembra un approccio fattibile. Se riuscirai a farlo funzionare, sarei molto interessato al codice. Forse puoi condividerlo sul github di odeint: https://github.com/headmyshoulder/odeint-v2 – mariomulansky

risposta

1

Il termine intertia banale aiuta nel senso che è necessario calcolare solo dV/dq e non dT/dp. odeint fornisce una versione dell'integratore simplettico che si aspetta solo dV/dq e presuppone che dT/dp sia banale come nel tuo caso. Tuttavia, è ancora necessario ottenere una derivata.