dynare/dynare++/integ/cc/quasi_mcarlo.hweb

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