simpson function

double simpson(
  1. Function f,
  2. double a,
  3. double b, [
  4. double step = 0.0001,
])

Approximates the definite integral of a function using Simpson's Rule.

The f parameter represents the function to be integrated. The a and b parameters define the interval of integration. The step parameter defines the step size and defaults to 0.0001 if not provided.

Example:

// Example function: f(x) = x^2
double functionToEvaluate(double x) => x * x;

double result = simpson(functionToEvaluate, 0, 2);
print(result); // Output: 2.6666666666666665 (approximate value of the integral of x^2 from 0 to 2).

Implementation

double simpson(Function f, double a, double b, [double step = 0.0001]) {
  /// Returns the value of the function [f] evaluated at [x].
  /// If the value is NaN, tries to evaluate [f] slightly to the left or right based on [side].
  double getValue(Function f, double x, int side) {
    double v = f(x);
    double d = 0.000000000001;
    if (v.isNaN) {
      v = f(side == 1 ? x + d : x - d);
    }
    return v;
  }

  // Calculate the number of intervals
  int n = (b - a) ~/ step;
  // Simpson's rule requires an even number of intervals. If it's not, then add 1
  if (n % 2 != 0) n++;
  // Get the interval size
  double dx = (b - a) / n;
  // Get x0
  double retVal = getValue(f, a, 1);

  // Get the middle part 4x1+2x2+4x3 ...
  bool even = false;
  double xi = a + dx;
  double c, k;
  for (int i = 1; i < n; i++) {
    c = even ? 2 : 4;
    k = c * getValue(f, xi, 1);
    retVal += k;
    // Flip the even flag
    even = !even;
    // Increment xi
    xi += dx;
  }

  // Add xn
  return (retVal + getValue(f, xi, 2)) * (dx / 3);
}