Hoe kom ik aan de oplossing van een gecompliceerde vergelijking?
Inleiding
Update 6/2014
oorspronkelijk vond ik drie oplossingen; nu zijn het er zes. Ik dacht dat ik wist dat er drie waren omdat het rationaliseren van de vergelijking resulteert in een veelterm van graad 24 en NSolve
24 wortels vindt en dan wortels elimineert die geen nullen van de oorspronkelijke vergelijking waren. Het blijkt dat de vergelijking lastig was vanuit het oogpunt van numeriek en ik heb er drie gemist.
overige wijzigingen:
-
het lijkt in dit geval natuurlijker om
Rationalize
te gebruiken om de coëfficiënten om te zetten in exacte getallen danSetPrecision
. -
ook heb ik
First @ eq
vervangen doorSubtract @@ eq
.
rationaliseer de vergelijking
men moet in gedachten houden dat volgens de documentatie op NSolve
NSolve
behandelt voornamelijk lineaire en polynomiale vergelijkingen.
de op-vergelijking is een algebraïsche vergelijking die kan worden omgezet in een veeltermvergelijking, die NSolve
dan gemakkelijk kan oplossen. Aangezien NSolve
dit niet alleen doet, moeten we “handmatig” rationaliseren.”Rationalisatie heeft de neiging om vreemde oplossingen in te voeren, dus moeten we de antwoorden die met NSolve
worden gegeven, controleren. De enigszins vervelende coëfficiënten van eq
maken het moeilijker, omdat bij het rationaliseren van eq
de afrondingsfout ertoe leidt dat sommige van de vierkantswortels niet naar behoren worden opgeheven. We kunnen dat oplossen door de precisie van eq
in te stellen op Infinity
.
we kunnen de vierkantswortels vinden in een uitdrukking expr
met
DeleteDuplicates @ Cases, Infinity]
dan kunnen we voor elke vierkantswortel expr
vermenigvuldigen met de uitdrukking met de vierkantswortel vervangen door zijn negatief en vereenvoudigen.
hieronder is het resultaat van de toepassing van de methode op de functie die wordt verkregen door Equal
in eq
te vervangen door Subtract
door Apply
(@@
). We kunnen de vergelijking precies oplossen.
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}}*)
er zijn enkele significante verschillen tussen de twee oplossingen:
(ζ /. rootsRat) - (ζ /. rootsRatExact) // Abs // Max(* 3.15226*10^-10*)
het selecteren van de wortels van de gegeven vergelijking
Update: hier is waar ik een aantal nullen gemist.
ik heb Pick
gebruikt om wortels te selecteren waarbij de oorspronkelijke vergelijking eq
een kleine waarde heeft, minder dan een kleine drempel, bijvoorbeeld 10^-1
. We kunnen later controleren dat elk een wortel is, maar ik heb niet gekeken naar andere wortels. De oorspronkelijke wortels waren:
rootsEq = Pick < 10^-1 /. rootsRat](* {{ζ -> -3.78042 - 5.50655 I}, {ζ -> -3.20562 + 5.39914 I}, {ζ -> 6.98478 + 0.493405 I}}*)
deze komen overeen met wortels 7, 9, en 20 in rootsRat
:
Position < 10^-1 &)](* {{7}, {9}, {20}}*)
als ik de exacte vergelijking voor nullen met PossibleZeroQ
controleer, krijg ik meer wortels:
Position(* {{1}, {7}, {9}, {14}, {20}, {21}}*)
duurt eeuwig op deze potentiële wortels, of in ieder geval langer dan ik bereid was om te wachten.]
interessant is dat deze extra wortels verband houden met de verschillen tussen de resultaten van NSolve
en Solve
:
Position, _?Positive](* {{1}, {2}, {3}, {14}, {21}, {22}, {23}, {24}}*)
laten we onze nieuwe roots zijn de volgende en we kunnen ze hieronder controleren:
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}}*)
controles
in het begin ziet at er niet goed uit voor de nieuwe toevoegingen:
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} *)*)
het probleem is bij het evalueren van de vergelijking met machine precisie.
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}*)
de waarschuwing lijkt niet significant te zijn. Een stijging van $MaxExtraPrecision
tot 2000
geeft nog steeds de waarschuwing en nullen met een nauwkeurigheid van 2020
tot 2040
. Als het nullen zijn, zal N
waarschijnlijk altijd de waarschuwing geven, omdat geen
Precision
(anders dan MachinePrecision
) kan hebben.