Lean Bisection Method
A practical implementation of the bisection root-finding algorithm in Lean 4 using Float arithmetic and Algebra on Real-valued Functions.
Overview
The bisection method is a robust numerical algorithm for finding roots of continuous functions. This implementation provides:
- Float-based computation for practical numerical results
- Configurable parameters (tolerance, max iterations (optional))
- Comprehensive error handling with detailed result types
- Built-in test functions for common mathematical equations and more complex trigonometric functions and algebraic equations
Implementation
The complete implementation using float arithmetic: src/bisection.lean
Core Components
The implementation includes:
BisectionResult- Result type with success/error casesBisectionConfig- Configuration for tolerance and iteration limitsbisection- Main loopfindRoot- Convenient wrapper function- Built-in test functions, examples and so on
Usage
Running the Implementation
# Execute the bisection.lean file directly
cd LeanBisection
lake env lean --run src/bisection.lean
# Or build the Lake package
lake build
Example Usage
The file contains ready-to-run examples:
-- Built-in test functions
def testFunction1 (x : Float) : Float := x * x - 2.0 -- √2
def testFunction2 (x : Float) : Float := x * x * x - x - 1.0 -- cubic
def testFunction3 (x : Float) : Float := Float.sin x -- π
-- Execute with #eval!
#eval! findRoot testFunction1 1.0 2.0 -- Finds √2 ≈ 1.414
#eval! findRoot testFunction2 1.0 2.0 -- Finds cubic root ≈ 1.325
#eval! findRoot testFunction3 3.0 4.0 -- Finds π ≈ 3.142
Custom Functions
-- Define your own function
def myFunction (x : Float) : Float := x * x - 5.0
-- Find the root
#eval! findRoot myFunction 2.0 3.0 -- Finds √5 ≈ 2.236
-- With custom configuration
let config : BisectionConfig := { tolerance := 1e-15, maxIterations := 2000 }
#eval! bisection myFunction 2.0 3.0 config
How It Works
The bisection method finds roots by:
- Validate bounds: Check that
a < bandf(a)andf(b)have opposite signs - Iterate: Repeatedly bisect the interval
[a,b]at the midpoint - Converge: Stop when the interval is smaller than tolerance or function value is near and/or equal zero
Chemistry Applications
The bisection method is particularly useful for solving equations of state in chemical engineering. See src/chemistry_examples.lean for examples.
Compressibility Factor (Z)
The compressibility factor Z relates real gas behavior to ideal gas behavior via: PV = ZnRT
Van der Waals Equation
For the van der Waals equation of state, Z satisfies: Z³ - (1 + B)Z² + AZ - AB = 0
where A = aP/(RT)² and B = bP/(RT)
-- Van der Waals equation solver
def vanDerWaalsEquation (A B : Float) (Z : Float) : Float :=
Z * Z * Z - (1.0 + B) * Z * Z + A * Z - A * B
-- Example: Calculate Z for nitrogen at reduced conditions
def nitrogenExample : Option Float :=
let A := 0.42 -- Reduced parameter aP/(RT)²
let B := 0.08 -- Reduced parameter bP/(RT)
let equation := vanDerWaalsEquation A B
bisectionCore equation 0.1 2.0 0.0001 100
#eval nitrogenExample -- Returns compressibility factor
Redlich-Kwong Equation
For the Redlich-Kwong equation: Z³ - Z² + (A - B - B²)Z - AB = 0
def redlichKwongEquation (A B : Float) (Z : Float) : Float :=
Z * Z * Z - Z * Z + (A - B - B * B) * Z - A * B
def redlichKwongExample : Option Float :=
let A := 0.5
let B := 0.08
let equation := redlichKwongEquation A B
bisectionCore equation 0.1 2.0 0.0001 100
Goals
This implementation aims at performing practical and complex numerical computations in Lean and ensure results formally verified without a "human-in-the-loop"
Future Work
- Generic types: Currently extending the code beyond Floats to handle other numeric types
- Formal proofs: Add mathematical verification using proofs for code correctness
- Performance: Optimize for faster execution
Requirements
- Lean 4: Any recent version (tested with v4.25.0-rc2)
- Lake: For package management