Hvordan kan jeg få løsningen av komplisert ligning?
Innledning
Oppdater 6/2014
Opprinnelig fant Jeg tre løsninger; nå er det seks. Jeg trodde jeg visste at det var tre fordi rasjonalisering av ligningen resulterer i et polynom av grad 24 og NSolve
finner 24 røtter og eliminerer deretter røtter som ikke var nuller av den opprinnelige ligningen. Det viser seg at ligningen var plagsom ut fra tallets synspunkt, og jeg savnet tre.
Andre modifikasjoner:
-
det virker mer naturlig å bruke
Rationalize
for å konvertere koeffisientene til eksakte tall i dette tilfellet ennSetPrecision
. -
På samme måte erstattet jeg
First @ eq
medSubtract @@ eq
.
Rasjonalisere ligningen
man bør huske på at i henhold til dokumentasjonen på NSolve
NSolve
omhandler primært med lineære og polynomiske ligninger.
ops ligning er en algebraisk ligning som kan omdannes til en polynomligning, som NSolve
kan da løse lett. Siden NSolve
ikke gjør dette alene, må vi rasjonalisere ” for hånd.”Rasjonalisering har en tendens til å introdusere fremmede løsninger, så vi må sjekke svarene returnert av NSolve
. De noe ekle koeffisientene til eq
gjør det vanskeligere, siden i rasjonalisering eq
fører avrundingsfeil til at noen av kvadratrotene ikke avbryter som de burde. Vi kan fikse det ved å sette presisjonen til eq
til Infinity
.
vi kan finne kvadratrotene i et uttrykk expr
med
DeleteDuplicates @ Cases, Infinity]
For hver kvadratrot kan vi multiplisere expr
med uttrykket med kvadratroten erstattet av sin negative og forenkle.
nedenfor er resultatet av å bruke metoden til funksjonen oppnådd ved å erstatte Equal
i eq
med Subtract
med Apply
(@@
). Vi kan løse ligningen nøyaktig.
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}}*)
det er noen signifikante forskjeller mellom de to løsningene:
(ζ /. rootsRat) - (ζ /. rootsRatExact) // Abs // Max(* 3.15226*10^-10*)
Velger røttene til den oppgitte ligningen
Update: Her er hvor jeg savnet noen nuller.
jeg brukte Pick
for å velge røtter der den opprinnelige ligningen eq
har en liten verdi, mindre enn en liten terskel, si 10^-1
. Vi kan sjekke senere at hver er en rot, men jeg sjekket ikke for andre røtter. De opprinnelige røttene var:
rootsEq = Pick < 10^-1 /. rootsRat](* {{ζ -> -3.78042 - 5.50655 I}, {ζ -> -3.20562 + 5.39914 I}, {ζ -> 6.98478 + 0.493405 I}}*)
disse tilsvarer røttene 7, 9 og 20 i rootsRat
:
Position < 10^-1 &)](* {{7}, {9}, {20}}*)
hvis jeg sjekker den nøyaktige ligningen for nuller med PossibleZeroQ
, får jeg flere røtter:
Position(* {{1}, {7}, {9}, {14}, {20}, {21}}*)
tar evig på disse potensielle røttene, eller i det minste lenger enn jeg var villig til å vente.]
Interessant er disse ekstra røttene knyttet til forskjellene mellom resultatene returnert av NSolve
og Solve
:
Position, _?Positive](* {{1}, {2}, {3}, {14}, {21}, {22}, {23}, {24}}*)
La oss la våre nye røtter være følgende, og vi kan sjekke 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}}*)
Sjekker
først ser at ikke så bra ut for de nye tilleggene:
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 å evaluere ligningen med maskinpresisjon.
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}*)
advarselen ser ikke ut til å være signifikant. Bumping opp $MaxExtraPrecision
til 2000
produserer fortsatt advarsel og nuller med nøyaktighet rundt 2020
til 2040
. Hvis de er nuller, vil N
sannsynligvis alltid produsere advarselen, siden ikke kan ha en
Precision
(annet enn MachinePrecision
).