blob: a95e5cbda6c58a95e9152dd6475bd78def2516bc [file] [log] [blame]
<?xml version="1.0"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<document url="random.html">
<properties>
<title>The Commons Math User Guide - Data Generation</title>
</properties>
<body>
<section name="2 Data Generation">
<subsection name="2.1 Overview"
href="overview">
<p>
Utilities in package <a href="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/random/package-summary.html">
o.a.c.m.legacy.random</a> often uses an underlying "source of randomness": A pseudo-random
number generator (PRNG) that produces sequences of numbers that are uniformly distributed
within their range.
Commons Math depends on <a href="http://commons.apache.org/rng">Commons RNG</a> for the
PRNG implementations.
</p>
</subsection>
<subsection name="2.2 Correlated random vectors"
href="vectors">
<p>
Some algorithms require random vectors instead of random scalars.
When the components of these vectors are uncorrelated, they may be generated
simply one at a time and packed together in the vector.
</p>
<p>
When the components are correlated however, generating them is more difficult.
The <a href="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/random/CorrelatedVectorFactory.html">
CorrelatedVectorFactory</a> class provides this service.
In this case, a complete covariance matrix must be provided (instead of a
simple standard deviations vector) gathering both the variance and the
correlation information of the probability law.
</p>
<p>
The main use for correlated random vector generation is for Monte-Carlo
simulation of physical problems with several variables, for example to
generate error vectors to be added to a nominal vector. A particularly
common case is when the generated vector should be drawn from a <a
href="http://en.wikipedia.org/wiki/Multivariate_normal_distribution">
Multivariate Normal Distribution</a>.
</p>
<p>
Generating random vectors from a bivariate normal distribution:
<source>
import java.util.function.Supplier;
import org.apache.commons.rng.UniformRandomProvider;
import org.apache.commons.rng.RandomSource;
// Import common PRNG interface and factory class that instantiates the PRNG.
// Create (and possibly seed) a PRNG.
long seed = 17399225432L; // Fixed seed means same results every time
UniformRandomProvider rng = RandomSource.create(RandomSource.MT, seed);
// Create a a factory of correlated vectors.
CorrelatedVectorFactory factory = new CorrelatedVectorFactory(mean, covariance, 1e-12);
Supplier&lt;double[]&gt; generator = factory.gaussian(rng);
// Use the generator to generate correlated vectors.
double[] randomVector = generator.get();
... </source>
The <code>mean</code> argument is a <code>double[]</code> array holding the means
of the random vector components. In the bivariate case, it must have length 2.
The <code>covariance</code> argument is a <code>RealMatrix</code>, which has to
be 2 x 2.
The main diagonal elements are the variances of the vector components and the
off-diagonal elements are the covariances.
For example, if the means are 1 and 2 respectively, and the desired standard deviations
are 3 and 4, respectively, then we need to use
<source>
double[] mean = {1, 2};
double[][] cov = {{9, c}, {c, 16}};
RealMatrix covariance = MatrixUtils.createRealMatrix(cov);
</source>
where "c" is the desired covariance. If you are starting with a desired correlation,
you need to translate this to a covariance by multiplying it by the product of the
standard deviations. For example, if you want to generate data that will give Pearson's
R of 0.5, you would use c = 3 * 4 * 0.5 = 6.
</p>
</subsection>
<subsection name="2.3 Low discrepancy sequences"
href="lowdiscrepancy">
<p>
There exist several quasi-random sequences with the property that for all values of N, the subsequence
x<sub>1</sub>, ..., x<sub>N</sub> has low discrepancy, which results in equi-distributed samples.
While their quasi-randomness makes them unsuitable for most applications (i.e. the sequence of values
is completely deterministic), their unique properties give them an important advantage for quasi-Monte Carlo simulations.<br/>
Currently, the following low-discrepancy sequences are supported:
<ul>
<li><a href="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/random/SobolSequenceGenerator.html">
Sobol sequence</a> (pre-configured up to dimension 1000)</li>
<li><a href="../commons-math-docs/apidocs/org/apache/commons/math4/legacy/random/HaltonSequenceGenerator.html">
Halton sequence</a> (pre-configured up to dimension 40)</li>
</ul>
<source>
// Create a Sobol sequence generator for 2-dimensional vectors
RandomVectorGenerator generator = new SobolSequence(2);
// Use the generator to generate vectors
double[] randomVector = generator.nextVector();
... </source>
The figure below illustrates the unique properties of low-discrepancy sequences when
generating N samples in the interval [0, 1]. Roughly speaking, such sequences "fill"
the respective space more evenly which leads to faster convergence in quasi-Monte Carlo
simulations.<br/>
<img src="../images/userguide/low_discrepancy_sequences.png"
alt="Comparison of low-discrepancy sequences"/>
</p>
</subsection>
</section>
</body>
</document>