Function tool::core::numerical_algorithms::newton_method [−][src]
pub fn newton_method<T, A>(
start_value: List<T>,
newton_method_function: impl Fn(&List<T>, &A) -> List<T>,
newton_method_derivative: impl Fn(&List<T>, &A) -> List<T>,
newton_method_arguments: A
) -> List<T> where
T: RealField + NumCast,
A: NewtonMethodArguments,
Expand description
Newton’s method algorithm.
Definition
Newton’s method is an algorithm to find the approximated value of the exact solution of a variable in an equation that cannot be isolated from other terms. The algorithm consist in this,
loop: next_value = old_value - function(old_value, *args) / derivative(old_value, *args) if abs(next_value - old_value) < threshold: break
Newton’s method function is expressed by moving all terms of the equation to one side to find
f(x) = 0
. The newton method’s derivative is the derivative of this function. The threshold
is the accepted residual between the estimated value and the exact solution. old_value
is a
initial guess of the solution.
Newton’s method is only guaranteed to converge if certain conditions are met (see
this).
The maximum number of iterations is bounded to assume the algorithm could not converge.
Usage
In order to use this Newton’s method implementaton, your need to:
- create a struct to hold the arguments
*args
to be sent to both the function and the derivative of the Newton’s method - add the trait
NewtonMethodArguments
to your struct - create the function of the Newton’s method
- create the derivative of the Newton’s method
This implementation uses List
for input and output to allow component-wise computations.
Example
use tool::{List, newton_method, NewtonMethodArguments, pows}; /// The struct that holds your arguments to be sent to the Newton's method's function and /// derivative. There you can define as many arguments as you want. pub struct MyArguments { some_value: f64, } /// We add the trait to your struct. impl NewtonMethodArguments for MyArguments {} /// Function of the Newton's method equation: /// /// f(x) = 100 - x ^ 4 - x * MyArguments.some_value = 0 pub fn newton_method_function( values: &List<f64>, args: &MyArguments, ) -> List<f64> { (-pows(values, 4)).add_scalar(100.) - values * args.some_value } /// Derivative of the Newton's method equation: /// /// f'(x) = - 4 * x ^ 3 - MyArguments.some_value pub fn newton_method_derivative( values: &List<f64>, args: &MyArguments, ) -> List<f64> { (- 4. * pows(values, 3)).add_scalar(-args.some_value) } // Initialize parameters. let initial_values = List::<f64>::zeros(3); let args = MyArguments { some_value: 12.0 }; // Calling the Newton's method. let results = newton_method( initial_values, newton_method_function, newton_method_derivative, args, );