Bisection Method

/**
 *
 * @file
 * @brief Find real roots of a function in a specified interval [a, b], where f(a)*f(b) < 0
 *
 * @details Given a function f(x) and an interval [a, b], where f(a) * f(b) < 0, find an approximation of the root
 * by calculating the middle m = (a + b) / 2, checking f(m) * f(a) and f(m) * f(b) and then by choosing the
 * negative product that means Bolzano's theorem is applied,, define the new interval with these points. Repeat until
 * we get the precision we want [Wikipedia](https://en.wikipedia.org/wiki/Bisection_method)
 *
 * @author [ggkogkou](https://github.com/ggkogkou)
 *
 */

const findRoot = (a, b, func, numberOfIterations) => {
  // Check if a given  real value belongs to the function's domain
  const belongsToDomain = (x, f) => {
    const res = f(x)
    return !Number.isNaN(res)
  }
  if (!belongsToDomain(a, func) || !belongsToDomain(b, func)) throw Error("Given interval is not a valid subset of function's domain")

  // Bolzano theorem
  const hasRoot = (a, b, func) => {
    return func(a) * func(b) < 0
  }
  if (hasRoot(a, b, func) === false) { throw Error('Product f(a)*f(b) has to be negative so that Bolzano theorem is applied') }

  // Declare m
  const m = (a + b) / 2

  // Recursion terminal condition
  if (numberOfIterations === 0) { return m }

  // Find the products of f(m) and f(a), f(b)
  const fm = func(m)
  const prod1 = fm * func(a)
  const prod2 = fm * func(b)

  // Depending on the sign of the products above, decide which position will m fill (a's or b's)
  if (prod1 > 0 && prod2 < 0) return findRoot(m, b, func, --numberOfIterations)
  else if (prod1 < 0 && prod2 > 0) return findRoot(a, m, func, --numberOfIterations)
  else throw Error('Unexpected behavior')
}

export { findRoot }
Algerlogo

Β© Alger 2022

About us

We are a group of programmers helping each other build new things, whether it be writing complex encryption programs, or simple ciphers. Our goal is to work together to document and model beautiful, helpful and interesting algorithms using code. We are an open-source community - anyone can contribute. We check each other's work, communicate and collaborate to solve problems. We strive to be welcoming, respectful, yet make sure that our code follows the latest programming guidelines.