You are on page 1of 11

Computational Lab in Physics:

Numerical Integration

x n 1

 f ( x ')dx '   x f ( L  k x)


L k 0

Steven Kornreich
www.beachlook.com
Integration procedure:
 We will need to define an operator
which will
 take as input
 a function
 limits of integration

 possibly, desired accuracy

 give as output the result of integrating


the function between the two limits

2
From Calculus:
x n 1

 f ( x ')dx '   x f ( L  k x) 


L k 0

 Rectangular rule:
 Evaluate the function at
the left endpoint of each
interval.
 Multiply by the width of
the interval.
 Equivalent to sum of
rectangular areas. 3
Alternate: Midpoint rule
x n 1

 f ( x ')dx '   x f ( L  (k  0.5)x)


L k 0

 Midpoint rule.
 Evaluate the function at the left
endpoint of each interval.
 Multiply by the width of the interval.
 Equivalent to sum of rectangular
areas, but has a better discrete error
behavior.

4
A first Implementation: Procedural

int main() {
#include <iostream>
double loLimit, upLimit;
#include <cmath>
int nIntervals;
using namespace std; cout << "Enter lower limit and upper
limit" << endl;
double square(double aX) { cin >> loLimit >> upLimit;
return aX*aX; cout << "Enter number of intervals"
} << endl;
cin >> nIntervals;
double integrate(double aLeftLimit, double aRightLimit, cout << "Integral of x^2 from 0 to 1
int aNumberOfIntervals, double integrand(double)) { ="
<<
double dx = (aRightLimit - aLeftLimit)/aNumberOfIntervals; integrate(loLimit,upLimit,nIntervals,
double x = aLeftLimit; square) << endl;
double sum = 0;
for (int i=0; i<aNumberOfIntervals; ++i) {
return 0;
sum+= integrand(x+dx); // eval function at right endpoint, increase
sum }
x+=dx; // increase lower limit
}
return sum*dx;
}
5
Implementing code with a desired
accuracy.
int main() {
double loLimit, upLimit, epsilon, result;
int nIntervals;
cout << "Enter lower limit and upper limit" << endl;
cin >> loLimit >> upLimit;
cout << "Enter initial number of intervals, and maximum allowed error" << endl;
cin >> nIntervals >> epsilon;

double oldResult = 1.0e30; // large number, at least iterate once


int maximumIterations = 25;
for (int j=0; j<maximumIterations; ++j) {
result = integrate(loLimit,upLimit,nIntervals,square);
// if accuracy is reached, end the loop
if (fabs(result-oldResult)<epsilon) break;

//update result and increase number of intervals


oldResult = result;
nIntervals*=2;
}

cout << "Integral of x^2 from "


<< loLimit << " to " << upLimit
<< " = " << result << " +/- " << fabs(result-oldResult) << endl;
return 0; 6
Using a class: IntegralCalculator.hh
#ifndef IntegralCalculator_hh
#define IntegralCalculator_hh

class IntegralCalculator {

public:
IntegralCalculator(double aIntegrandFunction(double));
void setNumberOfIntervals(int aNumberOfIntervals)
{mNumberOfIntervals=aNumberOfIntervals;}
void setLeftLimit(int val) {mLeftLimit=val;}
void setRightLimit(int val) {mRightLimit=val;}
void readInputData();
void integrate();
void print();

int numberOfIntervals() {return mNumberOfIntervals;}


int leftLimit() {return mLeftLimit;}
int rightLimit() {return mRightLimit;}
int result() {return mResult;}

private:
int mNumberOfIntervals;
double mLeftLimit;
double mRightLimit;
double mResult;
double (*mIntegrandFunction) (double);
};
7
#endif
The source file: IntegralCalculator.cc

#include "IntegralCalculator.hh"
void IntegralCalculator::integrate() {
#include <iostream>
double dx = (mRightLimit -
#include <cmath> mLeftLimit)/mNumberOfIntervals;
double x = mLeftLimit;
using namespace std; double sum = 0;
for (int i=0; i<mNumberOfIntervals; ++i) {
IntegralCalculator::IntegralCalculator(double sum+= mIntegrandFunction(x+dx);
aIntegrandFunction(double)) {
x+=dx; // increase lower limit
mIntegrandFunction = aIntegrandFunction;
}
}
mResult = sum*dx;
void IntegralCalculator::readInputData() {
double loLimit, upLimit;
}
int nIntervals;
cout << "Enter lower limit and upper limit" << endl;
void IntegralCalculator::print() {
cin >> loLimit >> upLimit;
cout << "Integral of your function from "
cout << "Enter number of intervals" << endl;
<< mLeftLimit << " to " << mRightLimit
cin >> nIntervals;
<< " = " << mResult << endl;
setLeftLimit(loLimit);
}
setRightLimit(upLimit);
setNumberOfIntervals(nIntervals);
return;
}

8
The new main() using the class.
#include "IntegralCalculator.hh"

double square(double aX) {

return aX*aX;
}

int main() {

IntegralCalculator IC1(square);
IC1.readInputData();
IC1.integrate();
IC1.print();

return 0;
}

9
Compiling and linking with a class
 Compiling the class to create a
machine readable object file:
 g++ IntegralCalculator.cc –c
 Compiling the file containing the main
function and linking with the
previously created object file:
 g++ integWithClass.cc –o integWithClass
IntegralCalculator.o

10
For Homework: Numerical Integration
Chapter 13, Section 13.4

 Assigment 1 Complete the coding of the IntegratorCalculator class


using the midpoint rule. Verify the convergence should be quadratic
in the step length. In particular, plot graphs of the error against
the inverse of the number of points, n, for the integral of x3 from 0
to 1 for both the midpoint rule and the rectangle rule.
 Assignment 2 Replace the midpoint rule by the Simpson rule, and
determine graphically the order of error of this procedure.
R
x n 1   xi  xi 1  
 f ( x)dx    f ( xi )  4 f   f ( xi 1 ) 
L
6 i 0   2  
 Asignment 5 Write a program to take the integral of the
numerically evaluated derivative function you wrote in the previous
homework, use it for the function x4 to show that you recover the
original function.
11

You might also like