Come posso ottenere la soluzione di un’equazione complicata?
Introduzione
Aggiornamento 6/2014
Originariamente, ho trovato tre soluzioni; ora sono sei. Pensavo di sapere che ce n’erano tre perché razionalizzare l’equazione si traduce in un polinomio di grado 24 e NSolve
trova 24 radici e quindi elimina le radici che non erano zeri dell’equazione originale. Si scopre che l’equazione era problematica dal punto di vista dei numeri e ne ho persi tre.
Altre modifiche:
-
Sembra più naturale usare
Rationalize
per convertire i coefficienti in numeri esatti in questo caso rispetto aSetPrecision
. -
Allo stesso modo ho sostituito
First @ eq
conSubtract @@ eq
.
Razionalizzare l’equazione
Si dovrebbe tenere presente che secondo la documentazione su NSolve
NSolve
si occupa principalmente di equazioni lineari e polinomiali.
L’equazione dell’OP è un’equazione algebrica che può essere trasformata in un’equazione polinomiale, che NSolve
può quindi risolvere facilmente. Dal momento che NSolve
non lo fa da solo, dobbiamo razionalizzare ” a mano.”La razionalizzazione tende a introdurre soluzioni estranee, quindi dobbiamo controllare le risposte restituite da NSolve
. I coefficienti un po ‘ cattivi di eq
rendono più difficile, poiché nella razionalizzazione di eq
, l’errore di arrotondamento porta ad alcune delle radici quadrate che non si annullano come dovrebbero. Possiamo risolverlo impostando la precisione di eq
su Infinity
.
Possiamo trovare le radici quadrate in un’espressioneexpr
con
DeleteDuplicates @ Cases, Infinity]
Quindi per ogni radice quadrata, possiamo moltiplicare expr
per l’espressione con la radice quadrata sostituita dal suo negativo e semplificare.
Di seguito è riportato il risultato dell’applicazione del metodo alla funzione ottenuta sostituendo Equal
in eq
di Subtract
con Apply
(@@
). Possiamo risolvere l’equazione esattamente.
eqExact = Rationalize;rationalized = Simplify @ Fold &, eqExact, DeleteDuplicates@Cases, Infinity]];rootsRatExact = Solve;rootsRat = NSolve(* 24 roots {{ζ -> -24559.6 + 24559.6 I}, <<22>>, {ζ -> 24559.6 - 24559.7 I}}*)
Ci sono alcune differenze significative tra le due soluzioni:
(ζ /. rootsRat) - (ζ /. rootsRatExact) // Abs // Max(* 3.15226*10^-10*)
Selezione delle radici dell’equazione data
Aggiornamento: qui è dove ho perso alcuni zeri.
Ho usato Pick
per selezionare le radici in cui l’equazione originale eq
ha un valore piccolo, inferiore a una piccola soglia, ad esempio 10^-1
. Possiamo controllare più tardi che ognuno è una radice, ma non ho controllato per altre radici. Le radici originali erano:
rootsEq = Pick < 10^-1 /. rootsRat](* {{ζ -> -3.78042 - 5.50655 I}, {ζ -> -3.20562 + 5.39914 I}, {ζ -> 6.98478 + 0.493405 I}}*)
Questi corrispondono alle radici 7, 9 e 20 in rootsRat
:
Position < 10^-1 &)](* {{7}, {9}, {20}}*)
Se controllo l’equazione esatta per gli zeri con PossibleZeroQ
, ottengo più radici:
Position(* {{1}, {7}, {9}, {14}, {20}, {21}}*)
prende per sempre su queste potenziali radici, o almeno più a lungo di quanto ero disposto ad aspettare.]
è Interessante notare che, queste radici sono connessi alle differenze tra i risultati restituiti da NSolve
e Solve
:
Position, _?Positive](* {{1}, {2}, {3}, {14}, {21}, {22}, {23}, {24}}*)
Lasciamo il nostro nuovo radici, è il seguente e siamo in grado di controllare sotto di loro:
rootsEqNew = Pick];rootsEqNew // N(* {{ζ -> -24559.6 + 24559.6 I}, {ζ -> -3.78042 - 5.50655 I}, {ζ -> -3.20562 + 5.39914 I}, {ζ -> -0.0832786 - 722.827 I}, {ζ -> 6.98478 + 0.493405 I}, {ζ -> 722.642 - 0.100823 I}}*)
Controlli
In un primo momento, a non sembrare troppo buono per le nuove aggiunte:
eqExact /. rootsEqNew // N(* { 0. + 9.7614*10^12 I, (* {1} *) -1.49012*10^-8 + 3.91155*10^-8 I, (* {7} *) -1.39698*10^-8 - 3.63216*10^-8 I, (* {9} *) -2. + 1536. I, (* {14} *) 1.49012*10^-8 + 1.11759*10^-8 I, (* {20} *) 0. + 1024. I} (* {21} *)*)
Il problema è che nel valutare l’equazione con la precisione di una macchina.
N(* N::meprec warning about $MaxExtraPrecision being reached *)(* {0``69.62973568978663 + 0``69.69302870899077 I, 0``90.5174054423328 + 0``90.55817837498498 I, 0``90.50250822096415 + 0``90.54414468499085 I, 0``80.1824915073549 + 0``79.76650578675965 I, 0``90.47483650216002 + 0``90.49782363232914 I, 0``80.17292602755023 + 0``79.76710897249409 I}*)
L’avviso non sembra significativo. L’aumento da $MaxExtraPrecision
a 2000
produce ancora l’avviso e gli zeri con precisioni comprese tra 2020
e 2040
. Se sono zeri, N
probabilmente produrrà sempre l’avviso, poiché non può avere un
Precision
(diverso da MachinePrecision
).