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

Newton’s method algorithm.

Definition

Newton’s method is an algorithm to find the approximated value to the exact solution of a variable in an equation that cannot be isolated from other terms. The algorithm consist in this algorithm:

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 found by moving all terms of the equation to one side to find f(x) = 0. The newton method 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 on the solution. Newton’s method is only guaranteed to converge if certain conditions are met (see this). The maximum number of iteration is bounded to assume the algorithm does not converge.

Usage

In order to use this Newton’s method implementaton, your need to:

  • create a public struct to hold the arguments *args to be sent to both function and derivative of the Newton’s method
  • add the implementation of the trait NewtonMethodArguments to your struct
  • create the function of the Newton’s method
  • create the derivative of the Newton’s method

This implementation is for input and output list of float.

Example

// The struct that contains your arguments for the Newton's method's function and derivative
pub struct CustomNewtonMethodArguments<'a> {
    some_other_value: &'a f64,
}

// A simple constructor for your struct
impl<'a> CustomNewtonMethodArguments<'a> {
    fn new(some_other_value: &'a f64) -> Self {
        CustomNewtonMethodArguments {some_other_value}
    }
}

// The implementation of the trait to your struct
impl<'a> tool::NewtonMethodArguments for CustomNewtonMethodArguments<'a> {}

// Newton's method's function: f(x) = 100 - x ** 4 - x * some_other_value = 0
pub fn newton_method_function(
    value: &tool::List<f64>,
    newton_method_arguments: &CustomNewtonMethodArguments,
) -> tool::List<f64> {
    (-tool::pow(value, 4)).add_scalar(100.) - value * *newton_method_arguments.some_other_value
}

// Newton's method's function: f'(x) = - 4 * x ** 3 - some_other_value
pub fn newton_method_derivative(
    value: &tool::List<f64>,
    newton_method_arguments: &CustomNewtonMethodArguments,
) ->tool::List<f64> {
    (- 4. * tool::pow(value, 3)).add_scalar(-newton_method_arguments.some_other_value)
}

// The call of the Newton's method
let my_initial_vector = tool::List::<f64>::zeros(3);
let some_other_value = 12.;

let result = tool::newton_method(
    my_initial_vector,
    newton_method_function,
    newton_method_derivative,
    CustomNewtonMethodArguments::new(&some_other_value),
);