Miten saan monimutkaisen yhtälön ratkaisun?
Johdanto
päivitys 6/2014
alun perin löysin kolme ratkaisua, nyt niitä on kuusi. Luulin tietäväni, että niitä on kolme, koska järkeistämällä yhtälöstä saadaan polynomi, jonka aste on 24 ja NSolve
, löydetään 24 juurta ja poistetaan sitten juuret, jotka eivät olleet alkuperäisen yhtälön nollia. Kävi ilmi, että yhtälö oli hankala numerotiedon näkökulmasta ja minulta jäi kolme väliin.
muut muutokset:
-
tuntuu luonnollisemmalta käyttää
Rationalize
kertoimia tässä tapauksessa täsmällisiksi luvuiksi kuinSetPrecision
. -
samoin korvasin
First @ eq
Subtract @@ eq
.
järkeistää yhtälö
on pidettävä mielessä, että dokumentaation mukaan NSolve
NSolve
käsittelee ensisijaisesti lineaarisia ja polynomiyhtälöitä.
OP: n yhtälö on algebrallinen yhtälö, joka voidaan muuttaa polynomiyhtälöksi, jonka NSolve
voi sitten ratkaista helposti. Koska NSolve
ei tee tätä yksin, meidän on järkeistettävä ” käsin.”Rationalisoinnilla on taipumus ottaa käyttöön vieraita ratkaisuja, joten on tarkistettava NSolve
mennessä palautetut vastaukset. Hieman ikävät kertoimet eq
vaikeuttavat, sillä järkeistettäessä eq
pyöristysvirhe johtaa siihen, että osa neliöjuurista ei kumoa kuten pitäisi. Voimme korjata sen asettamalla tarkkuuden eq
tasolle Infinity
.
voimme löytää neliöjuuret lausekkeessa expr
, jossa
DeleteDuplicates @ Cases, Infinity]
sitten jokaiselle neliöjuurelle voimme kertoa expr
lausekkeella, jossa neliöjuuri korvataan sen negatiivisella ja yksinkertaistetaan.
alla on tulos menetelmän soveltamisesta funktioon, joka saadaan korvaamalla Equal
eq
Subtract
Apply
(@@
). Voimme ratkaista yhtälön tasan.
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}}*)
näiden kahden ratkaisun välillä on joitakin merkittäviä eroja:
(ζ /. rootsRat) - (ζ /. rootsRatExact) // Abs // Max(* 3.15226*10^-10*)
valitaan annetun yhtälön juuret
päivitys: tässä kohtaa jäin nollille.
valitsin Pick
juurekset, joilla alkuperäinen yhtälö eq
on pieni arvo, pienempi kuin jokin pieni kynnys, vaikkapa 10^-1
. Voimme tarkistaa myöhemmin, että jokainen on juuri, mutta en tarkistanut muita juuria. Alkuperäiset juuret olivat:
rootsEq = Pick < 10^-1 /. rootsRat](* {{ζ -> -3.78042 - 5.50655 I}, {ζ -> -3.20562 + 5.39914 I}, {ζ -> 6.98478 + 0.493405 I}}*)
nämä vastaavat juuret 7, 9, ja 20 vuonna rootsRat
:
Position < 10^-1 &)](* {{7}, {9}, {20}}*)
jos tarkistan tarkan yhtälön nollille, joilla on PossibleZeroQ
, saan lisää juuria:
Position(* {{1}, {7}, {9}, {14}, {20}, {21}}*)
kestää ikuisuuden näissä mahdollisissa juurissa, tai ainakin kauemmin kuin olin valmis odottamaan.]
mielenkiintoista on, että nämä lisäjuuret liittyvät NSolve
: n palauttamien tulosten eroihin ja Solve
:
Position, _?Positive](* {{1}, {2}, {3}, {14}, {21}, {22}, {23}, {24}}*)
Let ‘ s let our new roots be the following and we can check them below:
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
aluksi, at ei näytä liian hyvältä uusille lisäyksille:
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} *)*)
ongelmana on yhtälön arviointi konetarkkuudella.
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}*)
varoitus ei vaikuta merkittävältä. Korotus $MaxExtraPrecision
arvoon 2000
tuottaa edelleen varoituksen ja nollat, joiden tarkkuus on noin 2020
arvoon 2040
. Jos ne ovat nollia, N
todennäköisesti tuottaa aina varoituksen, koska ei voi olla
Precision
(muu kuin MachinePrecision
).