rootScalar function

RootScalarResult rootScalar(
  1. double f(
    1. double
    ), {
  2. RootScalarMethod? method,
  3. List<double>? bracket,
  4. double? x0,
  5. double? x1,
  6. double fprime(
    1. double
    )?,
  7. double xtol = 2e-12,
  8. double rtol = 8.881784197001252e-16,
  9. int maxIter = 100,
})

Find a root of the scalar function f, like scipy.optimize.root_scalar.

  • f : function of one variable
  • method : algorithm. The default is RootScalarMethod.brentq when bracket is given, RootScalarMethod.newton when fprime is given and RootScalarMethod.secant otherwise
  • bracket : interval [a, b] with f(a) and f(b) of opposite signs, for bisect and brentq
  • x0, x1 : initial guesses, for newton and secant
  • fprime : derivative of f, for newton
  • xtol, rtol : the root is accepted when the step is smaller than xtol + rtol * |root|
  • maxIter : maximum number of iterations

Returns

References

  1. "scipy.optimize.root_scalar". https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.root_scalar.html. Retrieved 2026-10-13.
  2. R. P. Brent, "Algorithms for Minimization Without Derivatives", Prentice-Hall, 1973, chapter 4.
  3. "brentq.c". https://github.com/scipy/scipy/blob/main/scipy/optimize/Zeros/brentq.c. Retrieved 2026-10-13.

Examples

var r = rootScalar((x) => x * x - 2, bracket: [0.0, 2.0]);

print(r.root);

/* output:
1.4142135623731364
*/

Implementation

RootScalarResult rootScalar(
  double Function(double) f, {
  RootScalarMethod? method,
  List<double>? bracket,
  double? x0,
  double? x1,
  double Function(double)? fprime,
  double xtol = 2e-12,
  double rtol = 8.881784197001252e-16,
  int maxIter = 100,
}) {
  method ??= bracket != null
      ? RootScalarMethod.brentq
      : fprime != null
          ? RootScalarMethod.newton
          : RootScalarMethod.secant;

  if (xtol <= 0 || rtol < 0) {
    throw FormatException('xtol must be > 0 and rtol >= 0');
  }
  if (maxIter < 1) {
    throw FormatException('maxIter must be >= 1, got $maxIter');
  }

  switch (method) {
    case RootScalarMethod.bisect:
    case RootScalarMethod.brentq:
      if (bracket == null || bracket.length != 2) {
        throw FormatException('$method needs a bracket [a, b]');
      }
      return method == RootScalarMethod.bisect
          ? _bisect(f, bracket[0], bracket[1], xtol, rtol, maxIter)
          : _brentq(f, bracket[0], bracket[1], xtol, rtol, maxIter);
    case RootScalarMethod.newton:
      if (x0 == null || fprime == null) {
        throw FormatException('newton needs x0 and fprime');
      }
      return _newton(f, fprime, x0, xtol, rtol, maxIter);
    case RootScalarMethod.secant:
      if (x0 == null) {
        throw FormatException('secant needs x0');
      }
      return _secant(f, x0, x1, xtol, rtol, maxIter);
  }
}