@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
