Optimization Algorithms for Numerical Problems in TheAlgorithms/Python: A Complete Guide

TheAlgorithms/Python repository contains deterministic root-finding methods, iterative gradient-based minimizers, and stochastic global search algorithms to solve numerical optimization problems.

The TheAlgorithms/Python open-source repository provides a comprehensive collection of optimization algorithms for numerical problems, ranging from classic root-finding techniques to modern machine learning optimizers. These implementations offer dependency-light, well-documented solutions for function minimization, root-finding, and linear system solving, with most requiring only the Python standard library and NumPy.

Root-Finding Algorithms

The repository implements several deterministic methods for finding zeros of continuous functions, each with distinct convergence properties and derivative requirements.

Bisection Method

The bisection method guarantees convergence for continuous functions by repeatedly halving an interval [a, b] where the function changes sign. Implemented in maths/numerical_analysis/bisection.py, this robust algorithm requires only that f(a) and f(b) have opposite signs.

from maths.numerical_analysis.bisection import bisection

# Find a root of f(x) = x**3 - 1 in the interval [-5, 5]

root = bisection(lambda x: x**3 - 1, -5, 5)
print(f"Bisection root ≈ {root:.6f}")

A simplified educational variant exists in maths/numerical_analysis/bisection_2.py, demonstrating the same interval-halving principle with fixed-step iterations.

Newton-Raphson Method

For faster convergence when derivatives are available, the Newton-Raphson method uses first-order Taylor expansion via the update rule xₙ₊₁ = xₙ – f(xₙ)/f'(xₙ). This achieves quadratic convergence near simple roots. The implementation in maths/numerical_analysis/newton_raphson.py accepts both the function and its derivative as callable arguments.

from maths.numerical_analysis.newton_raphson import newton_raphson

def f(x): return x**2 - 5*x + 6          # Roots at x=2 and x=3

def f_prime(x): return 2*x - 5

root, err, steps = newton_raphson(f, f_prime, start=0.0)
print(f"Newton-Raphson root ≈ {root:.6f}, error = {err:.2e}, steps = {steps}")

Secant Method

When derivatives are unavailable or expensive to compute, the secant method provides a derivative-free alternative. Implemented in maths/numerical_analysis/secant_method.py, this algorithm approximates the slope using two previous points, offering superlinear convergence without requiring explicit derivative functions.

Unconstrained Minimization Algorithms

For optimization problems requiring function minimization, the repository provides both deterministic gradient-based methods and stochastic global search strategies.

Gradient Descent

The gradient descent implementation in machine_learning/gradient_descent.py minimizes smooth convex functions using the update rule θ ← θ – α·∇J(θ). The run_gradient_descent() function accepts feature matrices, target vectors, and hyperparameters including learning rate alpha and iteration count.

import numpy as np
from machine_learning.gradient_descent import run_gradient_descent

# Simple linear regression: minimise J(θ) = (1/2m) Σ (θ·x_i - y_i)^2

X = np.array([[1], [2], [3], [4]])   # feature column

y = np.array([2, 4, 6, 8])           # target

theta_initial = np.zeros((1,))        # start at 0

theta_opt = run_gradient_descent(X, y, theta_initial, alpha=0.01, iters=1000)
print(f"Optimised θ = {theta_opt}")

A specialized variant for linear regression appears in machine_learning/linear_regression.py, implementing steep gradient descent tailored for least-squares problems.

Conjugate Gradient

For solving symmetric positive-definite linear systems without explicit matrix inversion, the conjugate gradient method in linear_algebra/src/conjugate_gradient.py builds conjugate directions for faster convergence than standard gradient descent. The conjugate_gradient() function solves Ax = b iteratively with configurable tolerance and maximum iterations.

import numpy as np
from linear_algebra.src.conjugate_gradient import conjugate_gradient

# Symmetric positive-definite matrix A

A = np.array([[4, 1], [1, 3]], dtype=float)
b = np.array([1, 2], dtype=float)

x_solution = conjugate_gradient(A, b, tol=1e-8, max_iter=100)
print(f"Solution x = {x_solution}")

Simulated Annealing

For non-convex or multimodal landscapes, simulated annealing in searches/simulated_annealing.py provides probabilistic global optimization. This algorithm mimics thermodynamic cooling, accepting uphill moves with temperature-dependent probability to escape local minima.

from searches.simulated_annealing import simulated_annealing

def rastrigin(state):
    """Classic multimodal test function (minimise to 0)."""
    import math
    n = len(state)
    return 10*n + sum(x**2 - 10*math.cos(2*math.pi*x) for x in state)

# Initial random state in [-5.12, 5.12]^2

initial_state = [4.0, -3.5]

best_state, best_val = simulated_annealing(
    prob=rastrigin,
    init_state=initial_state,
    max_iter=2000,
    start_temp=100.0,
    find_max=False,
    visualization=False,
)

print(f"Best state {best_state} with value {best_val:.4f}")

Algorithm Architecture and Design Patterns

All optimization algorithms in the repository follow a consistent modular structure:

  • Pure-function cores – Numerical routines like bisection(), newton_raphson(), and conjugate_gradient() are implemented as plain functions accepting problem definitions (callables, bounds, matrices) and optional hyper-parameters.
  • Docstring test harnesses – Each file contains doctests serving as both usage examples and unit tests, ensuring correctness without external testing frameworks.
  • Minimal dependencies – Beyond the Python standard library, only NumPy is required for vectorized operations in gradient descent and conjugate gradient methods, maintaining portability across environments.

Summary

  • TheAlgorithms/Python provides deterministic root-finding via bisection, Newton-Raphson, and secant methods in maths/numerical_analysis/.
  • Gradient-based minimization includes general-purpose gradient descent (machine_learning/gradient_descent.py) and conjugate gradient solvers (linear_algebra/src/conjugate_gradient.py).
  • Stochastic global search is available through simulated annealing (searches/simulated_annealing.py) for escaping local minima in multimodal functions.
  • All implementations emphasize educational clarity with pure functions, comprehensive docstrings, and minimal external dependencies.

Frequently Asked Questions

What is the difference between the Newton-Raphson and Secant methods?

The Newton-Raphson method requires explicit derivative functions and achieves quadratic convergence, while the Secant method approximates derivatives using finite differences between two previous points. According to the source code in maths/numerical_analysis/, Newton-Raphson converges faster but demands that you provide f_prime, whereas Secant works when derivatives are unavailable or expensive to compute.

When should I use Simulated Annealing instead of Gradient Descent?

Use simulated annealing (available in searches/simulated_annealing.py) when optimizing non-convex, multimodal, or noisy objective functions where gradient descent might get trapped in local minima. Gradient descent in machine_learning/gradient_descent.py is preferable for smooth, convex functions where computational efficiency and deterministic convergence are required.

Does the repository require external libraries to run these algorithms?

Most optimization algorithms rely only on the Python standard library. However, gradient descent (machine_learning/gradient_descent.py) and conjugate gradient (linear_algebra/src/conjugate_gradient.py) implementations require NumPy for vectorized matrix operations, as indicated by their import statements and type hints.

How does the Conjugate Gradient method improve upon standard Gradient Descent?

The conjugate gradient method implemented in linear_algebra/src/conjugate_gradient.py solves symmetric positive-definite linear systems by generating conjugate (A-orthogonal) directions rather than following the gradient directly. This approach typically converges in at most n steps for an n×n system, whereas standard gradient descent may require many more iterations to reach the same tolerance level.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →