De Help-pagina van FindRoot
zegt:
“Standaard gebruikt FindRoot de methode van Newton (Newton-Raphson) om een niet-lineair systeem op te lossen”
(of een niet-lineaire vergelijking veronderstel ik). Desalniettemin is er iets voor mij verborgen in het FindRoot
commando. Beschouw de functie
f[x]:=Exp[1 - x] - 1,
waarvan de Newton-iteratiefunctie
Nf[x_]:=E^(-1 + x) (-1 + E^(1 - x)) + x
Itereren met deze functie met NestList
verkrijgt u de reeks waarden geproduceerd door de methode van Newton. De Newton-methode voor grote waarden van de initiële schatting vertoont een langzame convergentie voor dit probleem. Als we $ x_0 = 10 $ nemen, krijgen we:
NestList[Nf, 10., 8] (* {10., -8092.08, -8091.08, -8090.08, -8089.08, -8088.08, -8087.08, -8086.08, -8085.08} *)
waar we de langzame convergentie. Een plot van de functie Nf[x]
helpt om het gedrag van de methode te begrijpen. Maar het nemen van
Module[{s = 0, e = 0}, {FindRoot[f[x], {x, 10.}, StepMonitor :> s++, EvaluationMonitor :> e++], "Steps" -> s, "Evaluations" -> e}]
produceert
{{x -> 1.}, "Steps" -> 7, "Evaluations" -> 11}
waarbij slechts 7 stappen nodig zijn om de oplossing $ x = 1 $. Waarom levert FindRoot
dit resultaat op ?. Het is duidelijk dat FindRoot
niet de standaard Newton-methode gebruikt, nietwaar? Kan iemand mij helpen? Bedankt.
Reacties
- Zie hier en hier
Antwoord
Standaard FindRoot
gebruikt de "LineSearch"
-methode voor stapsgewijze controle zoals beschreven in de tutorial tutorial/UnconstrainedOptimizationLineSearchMethods
. De standaardinstellingen zijn
FindRoot[Exp[1 - x] - 1, {x, 10.}, Method -> {"Newton", "StepControl" -> {"LineSearch", "CurvatureFactor" -> Automatic, "DecreaseFactor" -> 1/10000, "MaxRelativeStepSize" -> 10, Method -> Automatic}}]
Gebruik geen stapbesturing om de methode van Newton min of meer exact te krijgen. FindRoot
beperkt nog steeds de maximale stapgrootte (de eerste stap in het onderstaande geval wordt afgekapt tot 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: kon niet convergeren naar de gevraagde nauwkeurigheid of precisie binnen 100 iteraties. >>
(* {{x -> -1.07713}, "Steps" -> 100, "Evaluations" -> 101} *)
U kunt de opties
StepMonitor :> Print[{x}], EvaluationMonitor :> Print[x]
gebruiken om de stappen en evaluaties te volgen. Of u kunt gebruik FindRootPlot
in het "Optimization`UnconstrainedProblems`"
pakket. (Let goed op de gele stippen die een evaluatie aanduiden die geen stap is.)
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]
Reacties
- Anders gezegd:
FindRoot[]
gebruikt een gedempte versie van Newton-Raphson, want zonder de demping zullen slechte keuzes van startwaarden vaker leiden tot divergentie. De demping zorgt ervoor dat de iteraties minder snel wild worden.