La página de ayuda de FindRoot
dice:
«de forma predeterminada, FindRoot utiliza el método de Newton (Newton-Raphson) para resolver un sistema no lineal»
(o una ecuación no lineal, supongo). Sin embargo, hay algo oculto para mí en el comando FindRoot
. Considere la función
f[x]:=Exp[1 - x] - 1,
cuya función de iteración de Newton es
Nf[x_]:=E^(-1 + x) (-1 + E^(1 - x)) + x
Iterando con esta función usando NestList
se obtiene la secuencia de valores producida por el método de Newton. El método de Newton para valores grandes de la suposición inicial presenta una convergencia lenta para este problema. Tomando $ x_0 = 10 $ obtenemos:
NestList[Nf, 10., 8] (* {10., -8092.08, -8091.08, -8090.08, -8089.08, -8088.08, -8087.08, -8086.08, -8085.08} *)
donde podemos ver el convergencia lenta. Un gráfico de la función Nf[x]
ayuda a comprender el comportamiento del método. Pero tomar
Module[{s = 0, e = 0}, {FindRoot[f[x], {x, 10.}, StepMonitor :> s++, EvaluationMonitor :> e++], "Steps" -> s, "Evaluations" -> e}]
produce
{{x -> 1.}, "Steps" -> 7, "Evaluations" -> 11}
y solo necesita 7 pasos para obtener la solución $ x = 1 $. ¿Por qué FindRoot
produce este resultado ?. Obviamente, FindRoot
no está usando el método estándar de Newton, ¿no es así? ¿Alguien puede ayudarme? Gracias.
Comentarios
- Consulte aquí y aquí
Responder
De forma predeterminada FindRoot
usa el "LineSearch"
método de control de pasos como se describe en el tutorial tutorial/UnconstrainedOptimizationLineSearchMethods
. La configuración predeterminada es
FindRoot[Exp[1 - x] - 1, {x, 10.}, Method -> {"Newton", "StepControl" -> {"LineSearch", "CurvatureFactor" -> Automatic, "DecreaseFactor" -> 1/10000, "MaxRelativeStepSize" -> 10, Method -> Automatic}}]
Para obtener el método de Newton de manera más o menos exacta, no use ningún control de pasos. Sin embargo, FindRoot
aún limita el tamaño máximo de paso (el primer paso en el caso siguiente se trunca a 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: no se pudo converger a la precisión solicitada en 100 iteraciones. >>
(* {{x -> -1.07713}, "Steps" -> 100, "Evaluations" -> 101} *)
Puede utilizar las opciones
StepMonitor :> Print[{x}], EvaluationMonitor :> Print[x]
para supervisar los pasos y las evaluaciones. O puede use FindRootPlot
en el paquete "Optimization`UnconstrainedProblems`"
(busque cuidadosamente los puntos amarillos que indican una evaluación que no es un paso).
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]
Comentarios
- Dicho de otra manera:
FindRoot[]
está usando una versión amortiguada de Newton-Raphson, ya que sin la amortiguación, las malas elecciones de los valores iniciales resultarán más a menudo en divergencia. La amortiguación hace que sea menos probable que las iteraciones se vuelvan locas.