use crate::core::math::Scalar;
use super::common::{Combined, Separate, Settings, hybrid, root_builders};
use super::{RootError, RootResult};
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct HalleyRoot<F: Scalar = f64> {
settings: Settings<F>,
}
impl<F: Scalar> HalleyRoot<F> {
pub fn new(lower: F, upper: F) -> Self {
Self {
settings: Settings::new(lower, upper),
}
}
root_builders!();
pub fn with_initial_guess(mut self, x: F) -> Self {
self.settings.guess = Some(x);
self
}
pub fn solve<C, D, DD, E>(
&self,
function: C,
derivative: D,
second_derivative: DD,
) -> Result<RootResult<F>, RootError<E, F>>
where
C: FnMut(F) -> Result<F, E>,
D: FnMut(F) -> Result<F, E>,
DD: FnMut(F) -> Result<F, E>,
{
hybrid(
&self.settings,
Separate {
function,
derivative,
second: Some(second_derivative),
},
true,
)
}
pub fn solve_combined<C, E>(
&self,
mut function: C,
) -> Result<RootResult<F>, RootError<E, F>>
where
C: FnMut(F) -> Result<(F, F, F), E>,
{
hybrid(
&self.settings,
Combined(|x| function(x).map(|(v, d, dd)| (v, d, Some(dd)))),
true,
)
}
}