In this exercise, you should implement classes that provide a reasonably flexible framework for Monte-Carlo integration in arbitrary dimensions.
The framework should be flexible enough to allow
-
integration of different functions f : Rn → R
-
flexible specification of the integration domains using a transformation from [0,1]n to a subset of Rn
-
flexible use for different random number generators
For convenience, we provide the interfaces that define the framework. You can find these interfaces in the package
info.quantlab.numericalmethods.lecture.montecarlo.integration
of the project numerical-methods-lecture
, see github.com/qntlb/numerical-methods-lecture. This project is already defined as a Maven dependency to this project. This project is pre-configured and "knows" these interfaces.
Integrand
IntegrationDomain
Integrator
MonteCarloIntegratorFactory
See the package info.quantlab.numericalmethods.lecture.montecarlo.integration
The MonteCarloIntegratorFactory
's method requires a class implementing a RandomNumberGenerator
. This interface and some classes implementing this interface can be found in the package
info.quantlab.numericalmethods.lecture.randomnumbers
- Objects implementing
Integrand
provide a function f : A → R defined on a domain A ⊂ Rn. - Objects implementing
IntegrationDomain
provide a bijective function g : [0,1]n → A that transforms the integration domain and the determinant of the derivative (Jacobi matrix) dg/dx. - Objects implementing
Integrator
provide the integral ∫A f(z) dz using substitution z = f(x).
You may use the classes providing random number generators that will be or were developed during the lecture, e.g.,
RandomNumberGeneratorFrom1D
MersenneTwister
The exercise consists of two separate tasks.
To complete your task:
-
- Implement a class implementing the interface
Integrator
that performs a general Monte-Carlo integration of arbitrary functions on general domains.
- Implement a class implementing the interface
The function to integrate will be provided to the integrator's method integrate
as an object implementing the interface Integrand
.
The integration domain will be provided to the integrator's method integrate
as an object implementing the interface IntegrationDomain
.
-
- Implement a class implementing the interface
MonteCarloIntegratorFactory
that allows creating an object of the class that you have implemented in 1). Note: theMonteCarloIntegratorFactory
simply calls the constructor of your class.
- Implement a class implementing the interface
-
- To allow us to test you implementation, complete the implementation of the method
getMonteCarloIntegratorFactory
ofMonteCarloIntegrationAssignmentSolution
. This allows the creation of an object of yourMonteCarloIntegratorFactory
. Our unit tests will use this to test your code.
- To allow us to test you implementation, complete the implementation of the method
-
- Feel free to create your own UnitTests and JavaDoc documentation.
Suggestion: you may test your integrator with different random number generators, e.g. MersenneTwister
via
final long seed = 3141;
RandomNumberGenerator randomNumberGenerator = new RandomNumberGeneratorFrom1D(new MersenneTwister(seed), domain.getDimension());
or a HaltonSequence
.
Note: As known from the lecture, using a 1-dimensional quasi-random number sequence in a d-dimensional integration will lead to wrong results. Hence, it makes usage of your integrator safer, if you explcitly require that the dimension of the domain matches the dimension of the random number sequence (an throw IllegalArgumentException
if not), such that the user has to explicitly use RandomNumberGeneratorFrom1D
when appropriate. You could however allow that an n-dimension sequence is used for a d-dimensional domain if n>d.
-
- Complete the method
getIntegral
ofMonteCarloIntegrationAssignmentSolution
. Use your Monte-Carlo integrator with approximately 1 million sample points to calculate the integral.
- Complete the method
To complete your task:
-
- Implement a class implementing the interface
Integrator
that performs a general (composite) Simpson's rule integration in d dimension of arbitrary functions on general domains.
- Implement a class implementing the interface
The function to integrate will be provided to the integrator's method integrate
as an object implementing the interface Integrand
.
The integration domain will be provided to the integrator's method integrate
as an object implementing the interface IntegrationDomain
.
-
- Implement a class implementing the interface
IntegratorFactory
that allows creating an object of the class that you have implemented in 1). Note: theIntegratorFactory
simply calls the constructor of your class.
- Implement a class implementing the interface
-
- To allow us to test you implementation, complete the implementation of the method
getSimpsonsIntegratorFactory
ofMonteCarloIntegrationAssignment
. This allows the creation of an object of yourIntegratorFactory
. Our unit tests will use this to test your code.
- To allow us to test you implementation, complete the implementation of the method
-
- Feel free to create your own UnitTests and JavaDoc documentation.
-
Note that your Simpson's integral and your Monte-Carlo integral only operator on [0,1]^d (the object implementing the Domain will provide you with the transformation).
-
Your Simpson's integrator should accept the
numberOfValuationPoints
as an argument. This should be the minimum total number of valuation points. Since the Simpsons rule uses an odd number of points in every dimension, you may use the following code to round this number appropriately tonumberOfSamplePointsEffective
, usingnumberOfSamplePointsPerDimension
per dimension.
int dimension = integrationDomain.getDimension();
int numberOfValuationPointsPerDimension = 2 * (int) (Math.ceil(Math.pow(numberOfValuationPoints, 1.0/dimension))/2) + 1;
int numberOfValuationPointsEffective = (int) Math.pow(numberOfValuationPointsPerDimension, dimension);
- You might realise that you need to think a bit to find a short algorithm to implement the Simpsons integration in arbitrary dimensions. It is possible to create a fairly short implementation if you implement a multi-index
index
- an array of lengthdimension
where each entry runs from0
tonumberOfSamplePointsPerDimension-1
.
Task 4 (optional): Use your MonteCarloIntegrator with an RandomNumberGenerator generating a low-discrepancy in d dimensions.
Since the random number generator is an input to your implementation of the MonteCarloIntegrator interface, it should be possible to feed in low discrepancy sequences (given that they implement the RandomNumberGeneratorRandomNumberGenerator
interface).
Conduct a an experiment using low discrepancy sequence to perform the Monte-Carlo integration and compare the integration error to that of using a pseudo random number sequence.
We encourage you to write your own unit tests.
This project offers the opportunity to explore Monte-Carlo integration in more detail for those interested. Here are a few suggestions:
-
Explore the dependency on the dimension: Consider the integration of x → product(i=0,...,d-1) sin(xi) for 0 < xi < π. The value of the integral is 2^d. This is an d-dimensional integral. For this function, compare the accuracy of Monte-Carlo integration and Simpsons integration with d = 1, 2, 4, 8 using for example n = 5^8 = 390625 sample points.
-
Explore the dependency on the smoothness of the function: Consider the integration of (x0,x1) → x02 + x12 < 1.0 ? 1.0 : 0.0 for 0 < xi < 1. The analytic value of this integral π. For this function, compare the accuracy of Monte-Carlo integration and Simpsons integration using n = 101^2 = 10201 sample points.