Hvordan kan jeg få løsningen af kompliceret ligning?
introduktion
opdatering 6/2014
oprindeligt fandt jeg tre løsninger; nu er det seks. Jeg troede, jeg vidste, at der var tre, fordi rationalisering af ligningen resulterer i et polynom af grad 24 og NSolve
finder 24 rødder og eliminerer derefter rødder, der ikke var nuller af den oprindelige ligning. Det viser sig, at ligningen var besværlig ud fra numerics synspunkt, og jeg savnede tre.
andre ændringer:
-
det forekommer mere naturligt at bruge
Rationalize
til at konvertere koefficienterne til nøjagtige tal i dette tilfælde endSetPrecision
. -
ligeledes erstattede jeg
First @ eq
medSubtract @@ eq
.
rationalisere ligningen
man skal huske på, at ifølge dokumentationen på NSolve
NSolve
beskæftiger sig primært med lineære og polynomiske ligninger.
OP ‘ s ligning er en algebraisk ligning, der kan omdannes til en polynomligning, som NSolve
derefter let kan løse. Da NSolve
ikke gør dette alene, er vi nødt til at rationalisere “for hånd.”Rationalisering har tendens til at indføre fremmede løsninger, så vi er nødt til at kontrollere de svar, der er returneret af NSolve
. De noget grimme koefficienter på eq
gør det sværere, da afrundingsfejl i rationalisering eq
fører til, at nogle af kvadratrødderne ikke annullerer som de burde. Vi kan løse det ved at indstille præcisionen af eq
til Infinity
.
vi kan finde kvadratrødderne i et udtryk expr
med
DeleteDuplicates @ Cases, Infinity]
så for hver kvadratrod kan vi multiplicere expr
med udtrykket med kvadratroden erstattet af dets negative og forenkle.
nedenfor er resultatet af at anvende metoden til funktionen opnået ved at erstatte Equal
i eq
med Subtract
med Apply
(@@
). Vi kan løse ligningen nøjagtigt.
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}}*)
der er nogle signifikante forskelle mellem de to løsninger:
(ζ /. rootsRat) - (ζ /. rootsRatExact) // Abs // Max(* 3.15226*10^-10*)
valg af rødderne af den givne ligning
opdatering: her er hvor jeg savnede nogle nuller.
jeg brugte Pick
til at vælge rødder, hvor den oprindelige ligning eq
har en lille værdi, mindre end en lille tærskel, siger 10^-1
. Vi kan senere kontrollere, at hver er en rod, men jeg kontrollerede ikke for andre rødder. De oprindelige rødder var:
rootsEq = Pick < 10^-1 /. rootsRat](* {{ζ -> -3.78042 - 5.50655 I}, {ζ -> -3.20562 + 5.39914 I}, {ζ -> 6.98478 + 0.493405 I}}*)
disse svarer til rødder 7, 9, og 20 i rootsRat
:
Position < 10^-1 &)](* {{7}, {9}, {20}}*)
hvis jeg tjekker den nøjagtige ligning for nuller med PossibleZeroQ
, får jeg flere rødder:
Position(* {{1}, {7}, {9}, {14}, {20}, {21}}*)
tager for evigt på disse potentielle rødder, eller i det mindste længere end jeg var villig til at vente.]
interessant nok er disse yderligere rødder forbundet med forskellene mellem resultaterne returneret af NSolve
ogSolve
:
Position, _?Positive](* {{1}, {2}, {3}, {14}, {21}, {22}, {23}, {24}}*)
lad os lade vores nye rødder være følgende, og vi kan tjekke dem nedenfor:
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}}*)
kontrol
først ser at ikke for godt ud til de nye tilføjelser:
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} *)*)
problemet er at evaluere ligningen med maskinens præcision.
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}*)
advarslen ser ikke ud til at være signifikant. Bumping op $MaxExtraPrecision
til 2000
producerer stadig advarslen og nuller med nøjagtigheder omkring 2020
til 2040
. Hvis de er nuller, vil N
sandsynligvis altid producere advarslen, da ikke kan have en
Precision
(bortset fra MachinePrecision
).