Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Avhz RustQuant Bisection Method

From Leeroopedia


Knowledge Sources
Domains Numerical_Methods, Mathematics
Last Updated 2026-02-07 19:00 GMT

Overview

Concrete implementation of the Bisection root-finding algorithm provided by the RustQuant library.

Description

The Bisection struct implements the classic bisection method for finding roots of continuous functions. The algorithm works by repeatedly halving an interval that is known to contain a root (identified by a sign change in the function values at the endpoints). At each step, the midpoint is evaluated and the sub-interval that still brackets the root is selected. This guarantees convergence at a linear rate, reducing the interval width by half on every iteration.

The implementation follows a two-phase approach. The solve() method first performs a bracket-search phase: starting from the initial guess, it expands the search interval using a growth factor of 1.6, alternating expansion direction via a flip-flop mechanism, until it finds endpoints where y_min * y_max <= 0 (a sign change). Once a valid bracket is established, it delegates to solve_impl() which executes the core bisection loop. The search is oriented so that f > 0 lies at root + dx, and in each iteration dx is halved. The loop terminates when |dx| < accuracy or when f(x_mid) is close to zero (using RootfinderData::close).

The struct is generic over the objective function F: Fn(f64) -> f64 and implements the Rootfinder trait. The derivative() method returns 0.0 since bisection does not require derivative information. The maximum number of iterations is inherited from the trait constant MAX_ITERATIONS = 1000.

Usage

Use the Bisection method when you need a simple, reliable, and guaranteed-to-converge root finder. It is the safest choice when the function is continuous and you can identify a bracket, but it converges more slowly than Brent's method or Newton-Raphson. It is well-suited for situations where robustness is more important than speed, or as a baseline reference implementation.

Code Reference

Source Location

Signature

pub struct Bisection<F>
where
    F: Fn(f64) -> f64,
{
    function: F,
    guess: f64,
    data: RootfinderData,
}

impl<F> Bisection<F>
where
    F: Fn(f64) -> f64,
{
    pub fn new(function: F, guess: f64, data: RootfinderData) -> Self;
}

impl<F> Rootfinder<F> for Bisection<F>
where
    F: Fn(f64) -> f64,
{
    fn value(&self, x: f64) -> f64;
    fn derivative(&self, _: f64) -> f64;  // returns 0.0 (not used)
    fn solve_impl(&mut self) -> f64;
    fn solve(&mut self) -> f64;
}

Import

use RustQuant::math::rootfinding::{Bisection, RootfinderData, Rootfinder};

I/O Contract

Inputs

Name Type Required Description
function F: Fn(f64) -> f64 Yes The objective function whose root is sought
guess f64 Yes Initial guess for the root location
data RootfinderData Yes Configuration containing accuracy, step size, bounds, and interval enforcement flag

Outputs

Name Type Description
root f64 The computed root of the objective function, or 0.0 if maximum iterations exceeded

Usage Examples

use RustQuant::math::rootfinding::{Bisection, RootfinderData, Rootfinder};
use std::f64::consts::SQRT_2;

// Define the objective function: f(x) = x^2 - 2
let f = |x: f64| x.powi(2) - 2.0;

// Create root-finder configuration:
//   accuracy = 1e-15, step_size = 1e-5,
//   lower_bound = 0.0, upper_bound = 2.0,
//   interval_enforced = true
let data = RootfinderData::new(1e-15, 1e-5, 0.0, 2.0, true);

// Construct the Bisection solver with initial guess = 1.0
let mut solver = Bisection::new(f, 1.0, data);
let root = solver.solve();

// root is approximately sqrt(2)
assert!((root - SQRT_2).abs() < 1e-15);

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment