Stránka nápovědy FindRoot
říká:
„ve výchozím nastavení používá FindRoot k řešení nelineárního systému Newtonovu metodu (Newton-Raphson)“
(nebo předpokládám nelineární rovnici). Nicméně v příkazu FindRoot
je pro mě něco skrytého. Zvažte funkci
f[x]:=Exp[1 - x] - 1,
jehož iterační funkce Newton je
Nf[x_]:=E^(-1 + x) (-1 + E^(1 - x)) + x
Iterace s touto funkcí pomocí NestList
získáte posloupnost hodnot vytvořených Newtonovou metodou. Newtonova metoda pro velké hodnoty počátečního odhadu představuje pomalou konvergenci tohoto problému. Vezmeme-li $ x_0 = 10 $, dostaneme:
NestList[Nf, 10., 8] (* {10., -8092.08, -8091.08, -8090.08, -8089.08, -8088.08, -8087.08, -8086.08, -8085.08} *)
kde můžeme vidět pomalá konvergence. Graf funkce Nf[x]
pomáhá pochopit chování metody. Ale přijetí
Module[{s = 0, e = 0}, {FindRoot[f[x], {x, 10.}, StepMonitor :> s++, EvaluationMonitor :> e++], "Steps" -> s, "Evaluations" -> e}]
vytvoří
{{x -> 1.}, "Steps" -> 7, "Evaluations" -> 11}
k získání řešení stačí pouze 7 kroků $ x = 1 $. Proč FindRoot
vytváří tento výsledek ?. Je zřejmé, že FindRoot
nepoužívá standardní Newtonovu metodu, že? Může mi někdo pomoci? Děkujeme.
Komentáře
- Viz zde a zde
Odpovědět
Ve výchozím nastavení FindRoot
používá "LineSearch"
metodu krokového ovládání popsanou v tutoriálu tutorial/UnconstrainedOptimizationLineSearchMethods
. Výchozí nastavení jsou
FindRoot[Exp[1 - x] - 1, {x, 10.}, Method -> {"Newton", "StepControl" -> {"LineSearch", "CurvatureFactor" -> Automatic, "DecreaseFactor" -> 1/10000, "MaxRelativeStepSize" -> 10, Method -> Automatic}}]
Chcete-li Newtonovu metodu získat víceméně přesně, nepoužívejte žádné krokové ovládání. FindRoot
stále omezuje maximální velikost kroku (první krok v níže uvedeném případě je zkrácen na x == -100.
):
Module[{s = 0, e = 0}, {FindRoot[Exp[1 - x] - 1, {x, 10.}, Method -> {"Newton", "StepControl" -> None}, StepMonitor :> s++, EvaluationMonitor :> e++], "Steps" -> s, "Evaluations" -> e}]
FindRoot :: cvmit: Nepodařilo se konvergovat na požadovanou přesnost nebo přesnost do 100 iterací. >>
(* {{x -> -1.07713}, "Steps" -> 100, "Evaluations" -> 101} *)
Pomocí možností
StepMonitor :> Print[{x}], EvaluationMonitor :> Print[x]
můžete sledovat kroky a hodnocení. Nebo můžete použijte FindRootPlot
v balíčku "Optimization`UnconstrainedProblems`"
. (Pečlivě hledejte žluté tečky označující hodnocení, které není krokem.)
Needs["Optimization`UnconstrainedProblems`"] FindRootPlot[Exp[1 - x] - 1, {x, 10.}, PlotRange -> All]
FindRootPlot[Exp[1 - x] - 1, {x, 10.}, Method -> {"Newton", "StepControl" -> None}, PlotRange -> All]
Komentáře
- Jinými slovy:
FindRoot[]
používá tlumenou verzi Newton-Raphsona, protože bez tlumení bude špatná volba počátečních hodnot častěji vést k odchylkám. Díky tlumení jsou iterace méně pravděpodobné, že se stanou divokými.