/*
* (c) Copyright Christian P. Fries, Germany. All rights reserved. Contact: email@christianfries.com.
*
* Created on 06.09.2015
*/
package net.finmath.integration;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import net.finmath.compatibility.java.util.function.DoubleUnaryOperator;
import net.finmath.interpolation.RationalFunctionInterpolation;
import net.finmath.interpolation.RationalFunctionInterpolation.ExtrapolationMethod;
import net.finmath.interpolation.RationalFunctionInterpolation.InterpolationMethod;
/**
* @author Christian Fries
*
*/
public class TrapezoidalRealIntegratorTest {
private AbstractRealIntegral integral;
@Before
public void setUp() {
final double lowerBound = 1.0;
final double upperBound = 5.0;
final int numberOfEvaluationPoints = 10000;
integral = new TrapezoidalRealIntegrator(lowerBound, upperBound, numberOfEvaluationPoints);
}
@Test
public void testCos() {
DoubleUnaryOperator integrand = new DoubleUnaryOperator() {
@Override
public double applyAsDouble(double x) {
return Math.cos(x);
}
};
DoubleUnaryOperator integralAnalytic = new DoubleUnaryOperator() {
@Override
public double applyAsDouble(double x) {
return Math.sin(x);
}
};
double value = integral.integrate(integrand);
double valueAnalytic = integralAnalytic.applyAsDouble(integral.getUpperBound())-integralAnalytic.applyAsDouble(integral.getLowerBound());
double error = value-valueAnalytic;
System.out.println("Result: " + value + ". \tError: " + error);
Assert.assertEquals("Integreation error.", 0.0, error, 1E-7);
}
@Test
public void testCubic() {
DoubleUnaryOperator integrand = new DoubleUnaryOperator() {
public double applyAsDouble(double x) {
return 2 * x * x - x;
}
};
DoubleUnaryOperator integralAnalytic = new DoubleUnaryOperator() {
public double applyAsDouble(double x) {
return 2 * x * x * x / 3 - x * x / 2;
}
};
double value = integral.integrate(integrand);
double valueAnalytic = integralAnalytic.applyAsDouble(integral.getUpperBound())-integralAnalytic.applyAsDouble(integral.getLowerBound());
double error = value-valueAnalytic;
System.out.println("Result: " + value + ". \tError: " + error);
Assert.assertEquals("Integreation error.", 0.0, error, 2.5E-7);
}
@Test
public void testWithInterpolationFunction() {
double[] points = { 0.0, 0.1, 0.5, 1.0, 2.0, 5.0, 10.0 };
double[] values = { 1.0, 2.1, 3.5, 1.0, 4.0, 1.0, 7.0 };
RationalFunctionInterpolation interpolation = new RationalFunctionInterpolation(points, values, InterpolationMethod.LINEAR, ExtrapolationMethod.CONSTANT);
double[] evaluationPoints = points;
AbstractRealIntegral trapezoidalRealIntegrator = new TrapezoidalRealIntegrator(0.75, 3.5, evaluationPoints);
AbstractRealIntegral simpsonRealIntegrator = new SimpsonRealIntegrator(0.75, 3.5, 2000);
/*
* Trapezoidal integration of the piece-wise linear function is exact, if we use points as integration points.
* Simpson's rule is using an equi-distant discretization and is not exact.
*/
double valueTrapezoidal = trapezoidalRealIntegrator.integrate(interpolation);
double valueSimpsons = simpsonRealIntegrator.integrate(interpolation);
Assert.assertEquals("Difference of trapezoidal and Simpson's rule", 0.0, valueSimpsons-valueTrapezoidal, 0.000001);
}
}