287 lines
9.0 KiB
Plaintext
287 lines
9.0 KiB
Plaintext
@q $Id: quasi_mcarlo.hweb 431 2005-08-16 15:41:01Z kamenik $ @>
|
|
@q Copyright 2005, Ondra Kamenik @>
|
|
|
|
@*2 Quasi Monte Carlo quadrature. This is {\tt quasi\_mcarlo.h} file.
|
|
|
|
This defines quasi Monte Carlo quadratures for cube and for a function
|
|
multiplied by normal density. The quadrature for a cube is named
|
|
|QMCarloCubeQuadrature| and integrates:
|
|
$$\int_{\langle 0,1\rangle^n}f(x){\rm d}x$$
|
|
The quadrature for a function of normally distributed parameters is
|
|
named |QMCarloNormalQuadrature| and integrates:
|
|
$${1\over\sqrt{(2\pi)^n}}\int_{(-\infty,\infty)^n}f(x)e^{-{1\over 2}x^Tx}{\rm d}x$$
|
|
|
|
For a cube we define |qmcpit| as iterator of |QMCarloCubeQuadrature|,
|
|
and for the normal density multiplied function we define |qmcnpit| as
|
|
iterator of |QMCarloNormalQuadrature|.
|
|
|
|
The quasi Monte Carlo method generates low discrepancy points with
|
|
equal weights. The one dimensional low discrepancy sequences are
|
|
generated by |RadicalInverse| class, the sequences are combined for
|
|
higher dimensions by |HaltonSequence| class. The Halton sequence can
|
|
use a permutation scheme; |PermutattionScheme| is an abstract class
|
|
for all permutaton schemes. We have three implementations:
|
|
|WarnockPerScheme|, |ReversePerScheme|, and |IdentityPerScheme|.
|
|
|
|
@s PermutationScheme int
|
|
@s RadicalInverse int
|
|
@s HaltonSequence int
|
|
@s QMCSpecification int
|
|
@s qmcpit int
|
|
@s QMCarloCubeQuadrature int
|
|
@s qmcnpit int
|
|
@s QMCarloNormalQuadrature int
|
|
@s WarnockPerScheme int
|
|
@s ReversePerScheme int
|
|
@s IdentityPerScheme int
|
|
|
|
@c
|
|
#ifndef QUASI_MCARLO_H
|
|
#define QUASI_MCARLO_H
|
|
|
|
#include "int_sequence.h"
|
|
#include "quadrature.h"
|
|
|
|
#include "Vector.h"
|
|
|
|
#include <vector>
|
|
|
|
@<|PermutationScheme| class declaration@>;
|
|
@<|RadicalInverse| class declaration@>;
|
|
@<|HaltonSequence| class declaration@>;
|
|
@<|QMCSpecification| class declaration@>;
|
|
@<|qmcpit| class declaration@>;
|
|
@<|QMCarloCubeQuadrature| class declaration@>;
|
|
@<|qmcnpit| class declaration@>;
|
|
@<|QMCarloNormalQuadrature| class declaration@>;
|
|
@<|WarnockPerScheme| class declaration@>;
|
|
@<|ReversePerScheme| class declaration@>;
|
|
@<|IdentityPerScheme| class declaration@>;
|
|
|
|
#endif
|
|
|
|
@ This abstract class declares |permute| method which permutes
|
|
coefficient |c| having index of |i| fro the base |base| and returns
|
|
the permuted coefficient which must be in $0,\ldots,base-1$.
|
|
|
|
@<|PermutationScheme| class declaration@>=
|
|
class PermutationScheme {
|
|
public:@;
|
|
PermutationScheme()@+ {}
|
|
virtual ~PermutationScheme()@+ {}
|
|
virtual int permute(int i, int base, int c) const =0;
|
|
};
|
|
|
|
|
|
@ This class represents an integer number |num| as
|
|
$c_0+c_1b+c_2b^2+\ldots+c_jb^j$, where $b$ is |base| and
|
|
$c_0,\ldots,c_j$ is stored in |coeff|. The size of |IntSequence| coeff
|
|
does not grow with growing |num|, but is fixed from the very beginning
|
|
and is set according to supplied maximum |maxn|.
|
|
|
|
The basic method is |eval| which evaluates the |RadicalInverse| with a
|
|
given permutation scheme and returns the point, and |increase| which
|
|
increases |num| and recalculates the coefficients.
|
|
|
|
@<|RadicalInverse| class declaration@>=
|
|
class RadicalInverse {
|
|
int num;
|
|
int base;
|
|
int maxn;
|
|
int j;
|
|
IntSequence coeff;
|
|
public:@;
|
|
RadicalInverse(int n, int b, int mxn);
|
|
RadicalInverse(const RadicalInverse& ri)
|
|
: num(ri.num), base(ri.base), maxn(ri.maxn), j(ri.j), coeff(ri.coeff)@+ {}
|
|
const RadicalInverse& operator=(const RadicalInverse& radi)
|
|
{
|
|
num = radi.num; base = radi.base; maxn = radi.maxn;
|
|
j = radi.j; coeff = radi.coeff;
|
|
return *this;
|
|
}
|
|
double eval(const PermutationScheme& p) const;
|
|
void increase();
|
|
void print() const;
|
|
};
|
|
|
|
@ This is a vector of |RadicalInverse|s, each |RadicalInverse| has a
|
|
different prime as its base. The static members |primes| and
|
|
|num_primes| define a precalculated array of primes. The |increase|
|
|
method of the class increases indices in all |RadicalInverse|s and
|
|
sets point |pt| to contain the points in each dimension.
|
|
|
|
@<|HaltonSequence| class declaration@>=
|
|
class HaltonSequence {
|
|
private:@;
|
|
static int primes[];
|
|
static int num_primes;
|
|
protected:@;
|
|
int num;
|
|
int maxn;
|
|
vector<RadicalInverse> ri;
|
|
const PermutationScheme& per;
|
|
Vector pt;
|
|
public:@;
|
|
HaltonSequence(int n, int mxn, int dim, const PermutationScheme& p);
|
|
HaltonSequence(const HaltonSequence& hs)
|
|
: num(hs.num), maxn(hs.maxn), ri(hs.ri), per(hs.per), pt(hs.pt)@+ {}
|
|
const HaltonSequence& operator=(const HaltonSequence& hs);
|
|
void increase();
|
|
const Vector& point() const
|
|
{@+ return pt;@+}
|
|
const int getNum() const
|
|
{@+ return num;@+}
|
|
void print() const;
|
|
protected:@;
|
|
void eval();
|
|
};
|
|
|
|
@ This is a specification of quasi Monte Carlo quadrature. It consists
|
|
of dimension |dim|, number of points (or level) |lev|, and the
|
|
permutation scheme. This class is common to all quasi Monte Carlo
|
|
classes.
|
|
|
|
@<|QMCSpecification| class declaration@>=
|
|
class QMCSpecification {
|
|
protected:@;
|
|
int dim;
|
|
int lev;
|
|
const PermutationScheme& per_scheme;
|
|
public:@;
|
|
QMCSpecification(int d, int l, const PermutationScheme& p)
|
|
: dim(d), lev(l), per_scheme(p)@+ {}
|
|
virtual ~QMCSpecification() {}
|
|
int dimen() const
|
|
{@+ return dim;@+}
|
|
int level() const
|
|
{@+ return lev;@+}
|
|
const PermutationScheme& getPerScheme() const
|
|
{@+ return per_scheme;@+}
|
|
};
|
|
|
|
|
|
@ This is an iterator for quasi Monte Carlo over a cube
|
|
|QMCarloCubeQuadrature|. The iterator maintains |HaltonSequence| of
|
|
the same dimension as given by the specification. An iterator can be
|
|
constructed from a given number |n|, or by a copy constructor. For
|
|
technical reasons, there is also an empty constructor; for that
|
|
reason, every member is a pointer.
|
|
|
|
@<|qmcpit| class declaration@>=
|
|
class qmcpit {
|
|
protected:@;
|
|
const QMCSpecification* spec;
|
|
HaltonSequence* halton;
|
|
ParameterSignal* sig;
|
|
public:@;
|
|
qmcpit();
|
|
qmcpit(const QMCSpecification& s, int n);
|
|
qmcpit(const qmcpit& qpit);
|
|
~qmcpit();
|
|
bool operator==(const qmcpit& qpit) const;
|
|
bool operator!=(const qmcpit& qpit) const
|
|
{@+ return ! operator==(qpit);@+}
|
|
const qmcpit& operator=(const qmcpit& qpit);
|
|
qmcpit& operator++();
|
|
const ParameterSignal& signal() const
|
|
{@+ return *sig;@+}
|
|
const Vector& point() const
|
|
{@+ return halton->point();@+}
|
|
double weight() const;
|
|
void print() const
|
|
{@+ halton->print();@+}
|
|
};
|
|
|
|
@ This is an easy declaration of quasi Monte Carlo quadrature for a
|
|
cube. Everything important has been done in its iterator |qmcpit|, so
|
|
we only inherit from general |Quadrature| and reimplement |begin| and
|
|
|numEvals|.
|
|
|
|
@<|QMCarloCubeQuadrature| class declaration@>=
|
|
class QMCarloCubeQuadrature : public QuadratureImpl<qmcpit>, public QMCSpecification {
|
|
public:@;
|
|
QMCarloCubeQuadrature(int d, int l, const PermutationScheme& p)
|
|
: QuadratureImpl<qmcpit>(d), QMCSpecification(d, l, p)@+ {}
|
|
virtual ~QMCarloCubeQuadrature()@+ {}
|
|
int numEvals(int l) const
|
|
{@+ return l;@+}
|
|
protected:@;
|
|
qmcpit begin(int ti, int tn, int lev) const
|
|
{@+ return qmcpit(*this, ti*level()/tn + 1);@+}
|
|
};
|
|
|
|
@ This is an iterator for |QMCarloNormalQuadrature|. It is equivalent
|
|
to an iterator for quasi Monte Carlo cube quadrature but a point. The
|
|
point is obtained from a point of |QMCarloCubeQuadrature| by a
|
|
transformation $\langle
|
|
0,1\rangle\rightarrow\langle-\infty,\infty\rangle$ aplied to all
|
|
dimensions. The transformation yields a normal distribution from a
|
|
uniform distribution on $\langle0,1\rangle$. It is in fact
|
|
|NormalICDF|.
|
|
|
|
@<|qmcnpit| class declaration@>=
|
|
class qmcnpit : public qmcpit {
|
|
protected:@;
|
|
Vector* pnt;
|
|
public:@;
|
|
qmcnpit();
|
|
qmcnpit(const QMCSpecification& spec, int n);
|
|
qmcnpit(const qmcnpit& qpit);
|
|
~qmcnpit();
|
|
bool operator==(const qmcnpit& qpit) const
|
|
{@+ return qmcpit::operator==(qpit);@+}
|
|
bool operator!=(const qmcnpit& qpit) const
|
|
{@+ return ! operator==(qpit);@+}
|
|
const qmcnpit& operator=(const qmcnpit& qpit);
|
|
qmcnpit& operator++();
|
|
const ParameterSignal& signal() const
|
|
{@+ return *sig;@+}
|
|
const Vector& point() const
|
|
{@+ return *pnt;@+}
|
|
void print() const
|
|
{@+ halton->print();pnt->print();@+}
|
|
};
|
|
|
|
@ This is an easy declaration of quasi Monte Carlo quadrature for a
|
|
cube. Everything important has been done in its iterator |qmcnpit|, so
|
|
we only inherit from general |Quadrature| and reimplement |begin| and
|
|
|numEvals|.
|
|
|
|
@<|QMCarloNormalQuadrature| class declaration@>=
|
|
class QMCarloNormalQuadrature : public QuadratureImpl<qmcnpit>, public QMCSpecification {
|
|
public:@;
|
|
QMCarloNormalQuadrature(int d, int l, const PermutationScheme& p)
|
|
: QuadratureImpl<qmcnpit>(d), QMCSpecification(d, l, p)@+ {}
|
|
virtual ~QMCarloNormalQuadrature()@+ {}
|
|
int numEvals(int l) const
|
|
{@+ return l;@+}
|
|
protected:@;
|
|
qmcnpit begin(int ti, int tn, int lev) const
|
|
{@+ return qmcnpit(*this, ti*level()/tn + 1);@+}
|
|
};
|
|
|
|
@ Declares Warnock permutation scheme.
|
|
@<|WarnockPerScheme| class declaration@>=
|
|
class WarnockPerScheme : public PermutationScheme {
|
|
public:@;
|
|
int permute(int i, int base, int c) const;
|
|
};
|
|
|
|
@ Declares reverse permutation scheme.
|
|
@<|ReversePerScheme| class declaration@>=
|
|
class ReversePerScheme : public PermutationScheme {
|
|
public:@;
|
|
int permute(int i, int base, int c) const;
|
|
};
|
|
|
|
@ Declares no permutation (identity) scheme.
|
|
@<|IdentityPerScheme| class declaration@>=
|
|
class IdentityPerScheme : public PermutationScheme {
|
|
public:@;
|
|
int permute(int i, int base, int c) const
|
|
{@+ return c;@+}
|
|
};
|
|
|
|
@ End of {\tt quasi\_mcarlo.h} file
|