Wie kann ich die Lösung einer komplizierten Gleichung erhalten?

Einführung

Update 6/2014

Ursprünglich habe ich drei Lösungen gefunden; jetzt sind es sechs. Ich dachte, ich wüsste, dass es drei gibt, weil die Rationalisierung der Gleichung zu einem Polynom vom Grad 24 führt und NSolve 24 Wurzeln findet und dann Wurzeln eliminiert, die keine Nullen der ursprünglichen Gleichung waren. Es stellt sich heraus, dass die Gleichung aus numerischer Sicht problematisch war und ich drei verpasst habe.

Andere Modifikationen:

  • Es scheint natürlicher zu sein, Rationalize zu verwenden, um die Koeffizienten in diesem Fall in exakte Zahlen umzuwandeln, als SetPrecision .

  • Ebenso habe ich First @ eq durch Subtract @@ eq ersetzt.

Rationalisieren Sie die Gleichung

Man sollte bedenken, dass gemäß der Dokumentation über NSolve

NSolve beschäftigt sich hauptsächlich mit linearen und polynomischen Gleichungen.

Die OP-Gleichung ist eine algebraische Gleichung, die in eine Polynomgleichung umgewandelt werden kann, die NSolve dann leicht lösen kann. Da NSolve dies nicht alleine tut, müssen wir “von Hand” rationalisieren.” Rationalisierung führt tendenziell zu Fremdlösungen, daher müssen wir die von NSolve zurückgegebenen Antworten überprüfen. Die etwas fiesen Koeffizienten von eq erschweren es, da bei der Rationalisierung von eq ein Rundungsfehler dazu führt, dass einige der Quadratwurzeln nicht wie gewünscht aufgehoben werden. Wir können das beheben, indem wir die Genauigkeit von eq auf Infinity .

Wir können die Quadratwurzeln in einem Ausdruck expr mit

DeleteDuplicates @ Cases, Infinity]

Dann können wir für jede Quadratwurzel expr mit dem Ausdruck multiplizieren, wobei die Quadratwurzel durch ihr Negativ ersetzt und vereinfacht wird.

Unten ist das Ergebnis der Anwendung der Methode auf die Funktion, die durch Ersetzen von Equal in eq durch Subtract durch Apply (@@) erhalten wird. Wir können die Gleichung genau lösen.

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}}*)

Es gibt einige signifikante Unterschiede zwischen den beiden Lösungen:

(ζ /. rootsRat) - (ζ /. rootsRatExact) // Abs // Max(* 3.15226*10^-10*)

Auswählen der Wurzeln der gegebenen Gleichung

Update: Hier habe ich einige Nullen verpasst.

Ich habe Pick verwendet, um Wurzeln auszuwählen, bei denen die ursprüngliche Gleichung eq einen kleinen Wert hat, der unter einem kleinen Schwellenwert liegt, z. B. 10^-1. Wir können später überprüfen, ob jeder eine Wurzel ist, aber ich habe nicht nach anderen Wurzeln gesucht. Die ursprünglichen Wurzeln waren:

rootsEq = Pick < 10^-1 /. rootsRat](* {{ζ -> -3.78042 - 5.50655 I}, {ζ -> -3.20562 + 5.39914 I}, {ζ -> 6.98478 + 0.493405 I}}*)

Diese entsprechen den Wurzeln 7, 9 und 20 in rootsRat:

Position < 10^-1 &)](* {{7}, {9}, {20}}*)

Wenn ich die genaue Gleichung mit PossibleZeroQ auf Nullen überprüfe, erhalte ich mehr Wurzeln:

Position(* {{1}, {7}, {9}, {14}, {20}, {21}}*)

dauert ewig auf diesen potenziellen Wurzeln, oder zumindest länger als ich bereit war zu warten.]

Interessanterweise hängen diese zusätzlichen Wurzeln mit den Unterschieden zwischen den von NSolve und Solve:

Position, _?Positive](* {{1}, {2}, {3}, {14}, {21}, {22}, {23}, {24}}*)

Lassen Sie uns unsere neuen Wurzeln die folgenden sein und wir können sie unten überprüfen:

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}}*)

Checks

At sieht für die Neuzugänge zunächst nicht allzu gut aus:

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} *)*)

Das Problem besteht darin, die Gleichung mit Maschinenpräzision zu bewerten.

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}*)

Die Warnung scheint nicht signifikant zu sein. Das Anstoßen von $MaxExtraPrecision auf 2000 erzeugt immer noch die Warnung und Nullen mit Genauigkeiten um 2020 bis 2040. Wenn es sich um Nullen handelt, erzeugt N wahrscheinlich immer die Warnung, da keine Precision (außer MachinePrecision) haben kann.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.