jak uzyskać rozwiązanie skomplikowanego równania?
wprowadzenie
aktualizacja 6/2014
pierwotnie znalazłem trzy rozwiązania; teraz jest sześć. Myślałem, że wiem, że są trzy, ponieważ racjonalizacja równania skutkuje wielomianem stopnia 24 i NSolve
znajduje 24 pierwiastki, a następnie eliminuje pierwiastki, które nie były zerami pierwotnego równania. Okazuje się, że równanie było kłopotliwe z punktu widzenia liczb i przegapiłem trzy.
inne modyfikacje:
-
bardziej naturalne wydaje się użycie
Rationalize
do przeliczenia współczynników na dokładne liczby w tym przypadku niżSetPrecision
. -
podobnie zamieniłem
First @ eq
naSubtract @@ eq
.
racjonalizacji równania
należy pamiętać, że zgodnie z dokumentacją na NSolve
NSolve
zajmuje się głównie równaniami liniowymi i wielomianowymi.
równanie OP jest równaniem algebraicznym, które można przekształcić w równanie wielomianowe, które NSolve
może następnie łatwo rozwiązać. Ponieważ NSolve
nie robi tego sam, musimy zracjonalizować ” ręcznie.”Racjonalizacja ma tendencję do wprowadzania obcych rozwiązań, więc musimy sprawdzić odpowiedzi zwracane przez NSolve
. Nieco paskudne współczynniki eq
utrudniają to, ponieważ w racjonalizacji eq
błąd zaokrąglania prowadzi do tego, że niektóre pierwiastki kwadratowe nie anulują się tak, jak powinny. Możemy to naprawić, ustawiając precyzję eq
na Infinity
.
możemy znaleźć pierwiastki kwadratowe w wyrażeniu expr
z
DeleteDuplicates @ Cases, Infinity]
wtedy dla każdego pierwiastka kwadratowego możemy pomnożyć expr
przez wyrażenie z pierwiastkiem kwadratowym zastąpionym przez jego ujemny i uprościć.
Poniżej znajduje się wynik zastosowania metody do funkcji uzyskanej przez zastąpienie Equal
w eq
przez Subtract
z Apply
(@@
). Możemy dokładnie rozwiązać równanie.
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}}*)
istnieją pewne znaczące różnice między tymi dwoma rozwiązaniami:
(ζ /. rootsRat) - (ζ /. rootsRatExact) // Abs // Max(* 3.15226*10^-10*)
Wybieranie pierwiastków podanego równania
Update: tutaj przegapiłem kilka zer.
użyłem Pick
, aby wybrać pierwiastki, przy których oryginalne równanie eq
ma małą wartość, mniejszą niż jakiś mały próg, powiedzmy 10^-1
. Później możemy sprawdzić, że każdy jest korzeniem, ale nie sprawdziłem innych korzeni. Pierwotnymi korzeniami były:
rootsEq = Pick < 10^-1 /. rootsRat](* {{ζ -> -3.78042 - 5.50655 I}, {ζ -> -3.20562 + 5.39914 I}, {ζ -> 6.98478 + 0.493405 I}}*)
odpowiadają one korzeniom 7, 9 i 20 w rootsRat
:
Position < 10^-1 &)](* {{7}, {9}, {20}}*)
jeśli sprawdzam dokładne równanie dla zer z PossibleZeroQ
, dostaję więcej pierwiastków:
Position(* {{1}, {7}, {9}, {14}, {20}, {21}}*)
trwa wieczność na tych potencjalnych korzeni, a przynajmniej dłużej niż byłem skłonny czekać.]
co ciekawe, te dodatkowe korzenie są związane z różnicami między wynikami zwracanymi przez NSolve
i Solve
:
Position, _?Positive](* {{1}, {2}, {3}, {14}, {21}, {22}, {23}, {24}}*)
niech nasze nowe korzenie będą następujące i możemy je sprawdzić poniżej:
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}}*)
sprawdza
na początku at nie wygląda zbyt dobrze dla nowych dodatków:
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} *)*)
problem polega na ocenie równania z precyzją maszyny.
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}*)
ostrzeżenie nie wydaje się być istotne. Podskakiwanie $MaxExtraPrecision
do 2000
nadal powoduje Ostrzeżenie i zera z dokładnością około 2020
do 2040
. Jeśli są to zera, N
prawdopodobnie zawsze wyświetli ostrzeżenie, ponieważ nie może mieć
Precision
(innego niż MachinePrecision
).