Skip to main content

scivex_optim/roots/
mod.rs

1//! Root-finding algorithms for scalar functions.
2//!
3//! Find `x` such that `f(x) = 0`.
4
5mod bisection;
6mod brent;
7mod newton;
8
9pub use bisection::bisection;
10pub use brent::brent_root;
11pub use newton::newton;
12
13use scivex_core::Float;
14
15/// Result of a root-finding algorithm.
16///
17/// # Examples
18///
19/// ```
20/// # use scivex_optim::prelude::*;
21/// let result = bisection(|x: f64| x * x - 2.0, 1.0, 2.0, &RootOptions::default()).unwrap();
22/// assert!(result.converged);
23/// assert!((result.root - std::f64::consts::SQRT_2).abs() < 1e-10);
24/// ```
25#[cfg_attr(
26    feature = "serde-support",
27    derive(serde::Serialize, serde::Deserialize)
28)]
29#[derive(Debug, Clone)]
30pub struct RootResult<T: Float> {
31    /// The estimated root.
32    pub root: T,
33    /// The function value at the root: `f(root)`.
34    pub f_root: T,
35    /// Number of iterations performed.
36    pub iterations: usize,
37    /// Whether the algorithm converged within tolerances.
38    pub converged: bool,
39}
40
41/// Options controlling root-finding algorithms.
42///
43/// # Examples
44///
45/// ```
46/// # use scivex_optim::prelude::*;
47/// let opts = RootOptions {
48///     xtol: 1e-8,
49///     ftol: 1e-8,
50///     max_iter: 50,
51/// };
52/// let result = bisection(|x: f64| x * x - 2.0, 1.0, 2.0, &opts).unwrap();
53/// assert!(result.converged);
54/// ```
55#[cfg_attr(
56    feature = "serde-support",
57    derive(serde::Serialize, serde::Deserialize)
58)]
59#[derive(Debug, Clone)]
60pub struct RootOptions<T: Float> {
61    /// Tolerance on the root position.
62    pub xtol: T,
63    /// Tolerance on the function value.
64    pub ftol: T,
65    /// Maximum number of iterations.
66    pub max_iter: usize,
67}
68
69impl<T: Float> Default for RootOptions<T> {
70    fn default() -> Self {
71        Self {
72            xtol: T::from_f64(1e-12),
73            ftol: T::from_f64(1e-12),
74            max_iter: 100,
75        }
76    }
77}