Computes the definite integral of a function using Simpson's first rule.

You're viewing an older version of this page (#386). View the current version.

View versions (1)

Interface

#include <codecogs/maths/calculus/quadrature/simpson.h>

using namespace Maths::Calculus::Quadrature;

Overview

This module computes the area beneath either a user supplied function or a set of discrete points, using an approximation which assumes the function is shaped as a parabola between each two consecutive points.

The background derivation of Simpon's first rule is given here:

Consider a four times differentiable function f:I \subset \mathbb{R} \rightarrow \mathbb{R}, two distinct abscissas a < b \in I and a positive integer n. Then the following approximation holds:

\int_a^b f(x) \mathrm{d}x \approx \frac{h}{3}
\left[f(a) + f(b) + 4\sum_{k=1}^n f\left(a + (2k - 1)h\right) + 
2\sum_{k=1}^{n-1} f(a + 2kh)\right],
(8)

where \displaystyle h = \frac{b-a}{2n}, with an error bound of:

\epsilon \leq \frac{(b-a)^5}{2880n^4} \sup_{x \in [a,b]} \left|\frac{d^4}{dx^4}f(x)\right|.
(9)

This is a quadrature formula known as Simpson's rule. From the formula of the error bound you may notice that e.g. if one doubles the number of points n, the approximation error is decreased sixteen times. This rule approximates the area under f between a and b by the area under a quadratic polynomial P as seen in the following image, where m is the midpoint between a and b.

1/SimpsonsRule-378.gif

Below you will find examples that show how to use each version of the function and the error estimates in each case. Generally this module provides better estimates than using the trapezoidal rule as implemented in trapezoidal. To convince yourself, compare the approximations generated by this module with the estimates given by the trapezoidal rule module.

References

Example 1

GPL Licence — free for non commercial use. See Licence details.

FUNCTION

simpson

This version is to be used when you wish to pass the function to integrate as an argument, instead of passing an array with its values at distinct points.

Example 1

In what follows an approximation is found for the definite integral

\int_1^3 \sin x \,dx
(10)

and the absolute error from its actual value is estimated.

#include <codecogs/maths/calculus/quadrature/simpson.h>
#include <stdio.h>
#include <math.h>

// number of points
#define N 100

// function to integrate
double f(double x)
{
  return sin(x);
}

// the primitive of f, to estimate errors
double pf(double x)
{
  return -cos(x);
}

int main()
{
  // compute the approximate area
  double fi = Maths::Calculus::Quadrature::simpson(N, f, 1, 3),

  // use the Leibniz-Newton formula to find a more precise estimate
  realfi = pf(3) - pf(1); // uses the Leibniz-Newton formula

  // display problem data
  printf("      f(x) = sin(x)\n");
  printf("    points = %d\n\n", N);

  // display the result and error estimate
  printf("   I(1, 3) = %.15lf\n", fi);
  printf("real value = %.15lf\n", realfi);
  printf("     error = %.15lf\n\n", fabs(fi - realfi));

  return 0;
}

Output

f(x) = sin(x)
    points = 100

   I(1, 3) = 1.530294803828911
real value = 1.530294802468585
     error = 0.000000001360326

Parameters

n
the number of sample points of the function f, from which to approximate (must be even)
f
the function to integrate
a
the inferior limit of integration
b
the superior limit of integration

Returns

The definite integral of the given function from a to b.

FUNCTION

simpson

This version is to be used when the function is not known analytically, but a table with its values at equally spaced abscissas is available.

Example 1

The code below gives an approximation for the definite integral

\int_1^{1.3} \sqrt{x} \,dx
(11)

and estimates the absolute error from its actual value.

#include <codecogs/maths/calculus/quadrature/simpson.h>
#include <stdio.h>
#include <math.h>

// the primitive of g, to estimate errors
double pf(double x)
{
  return 2*sqrt(x*x*x)/3;
}

int main()
{
  // values of the function at equally spaced abscissas
  double ordinates[7] = {1, 1.0247, 1.04881, 
  1.07238, 1.09544, 1.11803, 1.14017},

  // compute the approximate area
  fi = Maths::Calculus::Quadrature::simpson(7, ordinates, 1, 1.3),

  // use the Leibniz-Newton formula to find a more precise estimate
  realfi = pf(1.3) - pf(1); // uses the Leibniz-Newton formula

  // display problem data
  printf("      f(x) = sqrt(x)\n");
  printf("    points = 7\n\n");

  // display the result and error estimate
  printf(" I(1, 1.3) = %.15lf\n", fi);
  printf("real value = %.15lf\n", realfi);
  printf("     error = %.15lf\n\n", fabs(fi - realfi));

  return 0;
}

Output

f(x) = sqrt(x)
    points = 7

 I(1, 1.3) = 0.321485166666667
real value = 0.321485368419253
     error = 0.000000201752586

Parameters

n
the number of sample points of the function f, from which to approximate (must be odd)
values
an array with the value of the function at equally spaced abscissas
a
the inferior limit of integration
b
the superior limit of integration

Returns

The definite integral of the given function from a to b.