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
67
68
69
use crateScalar;
use ;
use ;
/// Safeguarded secant iteration for a scalar equation `f(x) = 0`.
///
/// The secant through the two most recently evaluated points proposes each
/// trial. Non-finite, out-of-bracket, and non-advancing proposals fall back to
/// bisection. After two trials that fail to halve the bracket, the next trial
/// is a bisection. This retains a sign-changing interval even when ordinary
/// secant iteration would diverge.
///
/// The callback must be deterministic, continuous on the interval, and finite
/// at every evaluated point. Endpoint values must have opposite signs unless
/// one is exactly zero. Convergence means an exact zero or a bracket width
/// at most `absolute + relative * abs(best_endpoint)`, not a small step.
/// The returned estimate is the evaluated endpoint with the smaller absolute
/// residual. Each iteration evaluates one trial. Limits return a clean
/// [`RootResult`]; invalid inputs and callback failures return [`RootError`].
///
/// # Backends
///
/// Scalar `f64` and `f32`; no linear-algebra backend or optional feature.
///
/// # Example
///
/// ```
/// use basin::SecantRoot;
/// use std::convert::Infallible;
/// let root = SecantRoot::new(0.0, 2.0)
/// .solve(|x| Ok::<_, Infallible>(x * x - 2.0)).unwrap();
/// assert!(root.converged());
/// assert!((root.root() - 2.0_f64.sqrt()).abs() < 1e-10);
/// ```
///
/// # References
///
/// SciPy 1.16.3, `scipy.optimize.newton`, secant update. Basin adds explicit
/// bracketing and bisection safeguards and uses bracket-based termination.
/// <https://docs.scipy.org/doc/scipy-1.16.3/reference/generated/scipy.optimize.newton.html>