finMath.net

Random Numbers - Inversion of the Distribution Function

Theoretical Background

The experiments on this page where part of a lecture on the Monte-Carlo methods using pseudo and quasi random numbers, see youtu.be/H6StBxcIDPI.

Getting Started

Checkout finmath-experiments from git and run maven (mvn or mvnw) from its directory. See Getting Started for details.

Experiment 1-2: Random Numbers - Inversion of the Distribution Function

Run the following experiment from your JShell (which was launched from finmath-experiments).

Experiment 1

The following will create an array of uniform distributed random numbers using a quasi random number generator (van-der-Corput Sequence or Halton sequence with base 2).

It then applied the inverse of the cummulated distribution function of the normal distribution to it, to generate normal distributed (quasi) random numbers.

JShell:

				import net.finmath.plots.Plots;
		
				var uniformSequence = new net.finmath.randomnumbers.VanDerCorputSequence(2);
		
				List<Double> valuesNormal = new ArrayList<>();
				List<Double> valuesUniform = new ArrayList<>();
				for(int i = 0; i<100000; i++) {
					double uniform = uniformSequence.getAsDouble();
		
					double normal = net.finmath.functions.NormalDistribution.inverseCumulativeDistribution(uniform);
		
					valuesUniform.add(uniform);
					valuesNormal.add(normal);
				}
		
				Plots.createHistogram(valuesUniform, 100, 4.0).setTitle("Uniform from VanDerCorput").show();
		
				Plots.createHistogram(valuesNormal, 100, 4.0).setTitle("Normal via ICDF from VanDerCorput").show();
			

Experiment 2

The following will create an array of uniform distributed random numbers using a pseudo random number generator (Mersenne Twister).

It then applied the inverse of the cummulated distribution function of the normal distribution to it, to generate normal distributed (pseudo) random numbers.

JShell:

				import net.finmath.plots.Plots;
		
				var uniformSequence = new net.finmath.randomnumbers.MersenneTwister(3216);
		
				List<Double> valuesNormal = new ArrayList<>();
				List<Double> valuesUniform = new ArrayList<>();
				for(int i = 0; i<100000; i++) {
					double uniform = uniformSequence.getAsDouble();
		
					double normal = net.finmath.functions.NormalDistribution.inverseCumulativeDistribution(uniform);
		
					valuesUniform.add(uniform);
					valuesNormal.add(normal);
				}
		
				Plots.createHistogram(valuesUniform, 100, 4.0).setTitle("Uniform from MersenneTwister").show();
		
				Plots.createHistogram(valuesNormal, 100, 4.0).setTitle("Normal via ICDF from MersenneTwister").show();
			

Summary (Experiments 1-2)

We have created normal distributed random numbers by applying the ICDF to a sequence of uniform distributed random numbers.

The sequence generated form a quasi random sequence has a much smoother distribution - as expected - since the quasi random number sequence is more evenly distributed (to keep the discrepancy of the sequence low).

Note however that pseudo random number sequence do have advantages in higher dimensions.

Where to continue

You may continue with