@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 @<|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 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, public QMCSpecification { public:@; QMCarloCubeQuadrature(int d, int l, const PermutationScheme& p) : QuadratureImpl(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, public QMCSpecification { public:@; QMCarloNormalQuadrature(int d, int l, const PermutationScheme& p) : QuadratureImpl(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