1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
//! The solver has been designed to operate on a user defined model.
//! To define such a model, the user must adapt the problem through the implementation of the [Model] trait.
//!
//! # Implementation
//!
//! Don't hesitate to check the [Model] trait documentation !
//!
//! If you want your model to raise errors and the rootfinding algorithm to react properly to it,
//! check the [error::ModelError] enum documentation.
//!
//! # Motivations
//!
//! ## Access to additional computed values
//!
//! An usual rootfinding algorithm operates on a mathematical function `f(iteratives) -> residuals`.
//! The solver attempts to find `iteratives` such that `norm(f(iteratives)) < tolerance`.
//!
//! However, in real life cases, the model computes other quantities that are the main focus of the end-user of the solver.
//! In fact, the `residuals` parameters have often few to no significations,
//! the user being mostly interested by other quantities.
//!
//! With most available solvers, computing the other quantities requires another function call to extract them.
//! This extra function call being made with the `iteratives` values found by the solver.
//!
//! ## Solver state differentiation
//!
//! A rootfinding algorithm will call several times a given model at different steps of the resolution process.
//!
//! For example, it calls a model to evaluate the residuals and will also call the model to evaluate the jacobian matrix.
//! During this different steps, one can want to have different behaviors in :
//! - the error handling
//! - the computation process
//!
//! *Error handling differentiation*:
//!
//! If a computation outside of the validity domain is performed during the convergence process,
//! the solver could recover from it and the final solution could still be in the validity domain.
//! If an error is raised during this computation, the program would abort.
//! Hence the potential need for the user to want to handle errors differently at different steps of the resolution process.
//!
//! *Computation process differentiation*:
//!
//! To speed-up computation, one can cache results that can be reused during the evaluation of the jacobian.
//! For rootfinding algorithm working with finite differantiation, the interesting cached results would be the one from the reference point.
//!
//! # Quick & easy adaptation from user defined function
//!
//! In practice, in most of the case, the user's problem is defined through a function or a closure.
//! A mecanism has been provided to implement the [Model] trait automatically given a user defined function.
//!
//! To ease the adaptation of a function to the required trait,
//! the following structs are provided :
//! - [UserModelFromFunction]: to work with a function defining the problem, finite-difference will be used
//! - [UserModelFromFunctionAndJacobian]: to work with two functions, one for the model and one for the jacobian
//! - [UserModelFromClosure]: to work with a closure defining the problem, finite-difference will be used
//! - [UserModelFromClosureAndJacobian]: to work with two closures, one for the model and one for the jacobian
mod error;
mod model_definition;
mod model_from_closure;
mod model_from_func;
pub use error::ModelError;
pub use model_definition::Model;
pub use model_from_closure::{UserModelFromClosure, UserModelFromClosureAndJacobian};
pub use model_from_func::{UserModelFromFunction, UserModelFromFunctionAndJacobian};