dynare/dynare++/integ/cc/product.cweb

214 lines
4.8 KiB
Plaintext

@q $Id: product.cweb 431 2005-08-16 15:41:01Z kamenik $ @>
@q Copyright 2005, Ondra Kamenik @>
@ This is {\tt product.cpp} file.
@c
#include "product.h"
#include "symmetry.h"
@<|prodpit| empty constructor@>;
@<|prodpit| regular constructor@>;
@<|prodpit| copy constructor@>;
@<|prodpit| destructor@>;
@<|prodpit::operator==| code@>;
@<|prodpit::operator=| code@>;
@<|prodpit::operator++| code@>;
@<|prodpit::setPointAndWeight| code@>;
@<|prodpit::print| code@>;
@<|ProductQuadrature| constructor@>;
@<|ProductQuadrature::begin| code@>;
@<|ProductQuadrature::designLevelForEvals| code@>;
@
@<|prodpit| empty constructor@>=
prodpit::prodpit()
: prodq(NULL), level(0), npoints(0), jseq(NULL),
end_flag(true), sig(NULL), p(NULL)
{
}
@ This constructs a product iterator corresponding to index $(j0,0\ldots,0)$.
@<|prodpit| regular constructor@>=
prodpit::prodpit(const ProductQuadrature& q, int j0, int l)
: prodq(&q), level(l), npoints(q.uquad.numPoints(l)), jseq(new IntSequence(q.dimen(), 0)),
end_flag(false), sig(new ParameterSignal(q.dimen())), p(new Vector(q.dimen()))
{
if (j0 < npoints) {
(*jseq)[0] = j0;
setPointAndWeight();
} else {
end_flag = true;
}
}
@ Copy constructor, clear.
@<|prodpit| copy constructor@>=
prodpit::prodpit(const prodpit& ppit)
: prodq(ppit.prodq), level(ppit.level), npoints(ppit.npoints),
end_flag(ppit.end_flag), w(ppit.w)
{
if (ppit.jseq)
jseq = new IntSequence(*(ppit.jseq));
else
jseq = NULL;
if (ppit.sig)
sig = new ParameterSignal(*(ppit.sig));
else
sig = NULL;
if (ppit.p)
p = new Vector(*(ppit.p));
else
p = NULL;
}
@
@<|prodpit| destructor@>=
prodpit::~prodpit()
{
if (jseq)
delete jseq;
if (sig)
delete sig;
if (p)
delete p;
}
@
@<|prodpit::operator==| code@>=
bool prodpit::operator==(const prodpit& ppit) const
{
bool ret = true;
ret = ret & prodq == ppit.prodq;
ret = ret & end_flag == ppit.end_flag;
ret = ret & ((jseq==NULL && ppit.jseq==NULL) ||
(jseq!=NULL && ppit.jseq!=NULL && *jseq == *(ppit.jseq)));
return ret;
}
@
@<|prodpit::operator=| code@>=
const prodpit& prodpit::operator=(const prodpit& ppit)
{
prodq = ppit.prodq;
end_flag = ppit.end_flag;
w = ppit.w;
if (jseq)
delete jseq;
if (sig)
delete sig;
if (p)
delete p;
if (ppit.jseq)
jseq = new IntSequence(*(ppit.jseq));
else
jseq = NULL;
if (ppit.sig)
sig = new ParameterSignal(*(ppit.sig));
else
sig = NULL;
if (ppit.p)
p = new Vector(*(ppit.p));
else
p = NULL;
return *this;
}
@
@<|prodpit::operator++| code@>=
prodpit& prodpit::operator++()
{
// todo: throw if |prodq==NULL| or |jseq==NULL| or |sig==NULL| or |end_flag==true|
int i = prodq->dimen()-1;
(*jseq)[i]++;
while (i >= 0 && (*jseq)[i] == npoints) {
(*jseq)[i] = 0;
i--;
if (i >= 0)
(*jseq)[i]++;
}
sig->signalAfter(std::max(i,0));
if (i == -1)
end_flag = true;
if (! end_flag)
setPointAndWeight();
return *this;
}
@ This calculates the weight and sets point coordinates from the indices.
@<|prodpit::setPointAndWeight| code@>=
void prodpit::setPointAndWeight()
{
// todo: raise if |prodq==NULL| or |jseq==NULL| or |sig==NULL| or
// |p==NULL| or |end_flag==true|
w = 1.0;
for (int i = 0; i < prodq->dimen(); i++) {
(*p)[i] = (prodq->uquad).point(level, (*jseq)[i]);
w* = (prodq->uquad).weight(level, (*jseq)[i]);
}
}
@ Debug print.
@<|prodpit::print| code@>=
void prodpit::print() const
{
printf("j=[");
for (int i = 0; i < prodq->dimen(); i++)
printf("%2d ", (*jseq)[i]);
printf("] %+4.3f*(",w);
for (int i = 0; i < prodq->dimen()-1; i++)
printf("%+4.3f ", (*p)[i]);
printf("%+4.3f)\n",(*p)[prodq->dimen()-1]);
}
@
@<|ProductQuadrature| constructor@>=
ProductQuadrature::ProductQuadrature(int d, const OneDQuadrature& uq)
: QuadratureImpl<prodpit>(d), uquad(uq)
{
// todo: check |d>=1|
}
@ This calls |prodpit| constructor to return an iterator which points
approximatelly at |ti|-th portion out of |tn| portions. First we find
out how many points are in the level, and then construct an interator
$(j0,0,\ldots,0)$ where $j0=$|ti*npoints/tn|.
@<|ProductQuadrature::begin| code@>=
prodpit ProductQuadrature::begin(int ti, int tn, int l) const
{
// todo: raise is |l<dimen()|
// todo: check |l<=uquad.numLevels()|
int npoints = uquad.numPoints(l);
return prodpit(*this, ti*npoints/tn, l);
}
@ This just starts at the first level and goes to a higher level as
long as a number of evaluations (which is $n_k^d$ for $k$ being the
level) is less than the given number of evaluations.
@<|ProductQuadrature::designLevelForEvals| code@>=
void ProductQuadrature::designLevelForEvals(int max_evals, int& lev, int& evals) const
{
int last_evals;
evals = 1;
lev = 1;
do {
lev++;
last_evals = evals;
evals = numEvals(lev);
} while (lev < uquad.numLevels()-2 && evals < max_evals);
lev--;
evals = last_evals;
}
@ End of {\tt product.cpp} file