Added test of density of BrownianMotion.
@@ -8,6 +8,7 @@ package net.finmath.montecarlo;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Collection;
+import java.util.function.DoubleUnaryOperator;
import org.junit.Assert;
import org.junit.Test;
@@ -47,6 +48,39 @@ public class BrownianMotionTest {
this.randomVariableFactory = randomVariableFactory;
}
+ /**
+ * This test compares the numerical sampled density (from a histogram) of the Brownian motion W(T)
+ * with the analytic density.
+ */
+ @Test
+ public void testDensity() {
+ int seed = 3141;
+ int numberOfFactors = 1;
+ int numberOfPaths = 10000000;
+ TimeDiscretizationInterface timeDiscretization = new TimeDiscretization(0, 10, 1.0);
+ BrownianMotionInterface brownianMotion = new BrownianMotion(timeDiscretization, numberOfFactors, numberOfPaths, seed, randomVariableFactory);
+
+ RandomVariableInterface brownianMotionAtTime = brownianMotion.getBrownianIncrement(0, 0);
+ for(int timeIndex=1; timeIndex<timeDiscretization.getNumberOfTimeSteps(); timeIndex++) {
+ double[] intervalPoints = (new TimeDiscretization(-2, 101, 4.0/100)).getAsDoubleArray();
+ double[] histOfNormalFromBM = brownianMotionAtTime.getHistogram(intervalPoints);
+
+ double time = brownianMotionAtTime.getFiltrationTime();
+ DoubleUnaryOperator densityAnalytic = x -> { return Math.exp(-x*x/2.0/time) / Math.sqrt(2 * Math.PI * time); };
+
+ for(int i=0; i<intervalPoints.length-1; i++) {
+ double center = (intervalPoints[i+1]+intervalPoints[i])/2.0;
+ double size = intervalPoints[i+1]-intervalPoints[i];
+
+ double density = histOfNormalFromBM[i+1] / size;
+ double densityAnalyt = densityAnalytic.applyAsDouble(center);
+
+ Assert.assertEquals("Density", densityAnalyt, density, 5E-3);
+ }
+ brownianMotionAtTime = brownianMotionAtTime.add(brownianMotion.getBrownianIncrement(timeIndex, 0));
+ }
+ }
+
@Test
public void testScalarValuedBrownianMotionTerminalDistribution() {
// The parameters
