dynare/dynare++/integ/cc/vector_function.cweb

179 lines
4.8 KiB
Plaintext

@q $Id: vector_function.cweb 431 2005-08-16 15:41:01Z kamenik $ @>
@q Copyright 2005, Ondra Kamenik @>
@ This is {\tt vector\_function.cpp} file
@c
#include "vector_function.h"
#include <dynlapack.h>
#include <cmath>
#include <cstring>
#include <algorithm>
@<|ParameterSignal| constructor code@>;
@<|ParameterSignal| copy constructor code@>;
@<|ParameterSignal::signalAfter| code@>;
@<|VectorFunctionSet| constructor 1 code@>;
@<|VectorFunctionSet| constructor 2 code@>;
@<|VectorFunctionSet| destructor code@>;
@<|GaussConverterFunction| constructor code 1@>;
@<|GaussConverterFunction| constructor code 2@>;
@<|GaussConverterFunction| copy constructor code@>;
@<|GaussConverterFunction::eval| code@>;
@<|GaussConverterFunction::multiplier| code@>;
@<|GaussConverterFunction::calcCholeskyFactor| code@>;
@ Just an easy constructor of sequence of booleans defaulting to
change everywhere.
@<|ParameterSignal| constructor code@>=
ParameterSignal::ParameterSignal(int n)
: data(new bool[n]), num(n)
{
for (int i = 0; i < num; i++)
data[i] = true;
}
@
@<|ParameterSignal| copy constructor code@>=
ParameterSignal::ParameterSignal(const ParameterSignal& sig)
: data(new bool[sig.num]), num(sig.num)
{
memcpy(data, sig.data, num);
}
@ This sets |false| (no change) before a given parameter, and |true|
(change) after the given parameter (including).
@<|ParameterSignal::signalAfter| code@>=
void ParameterSignal::signalAfter(int l)
{
for (int i = 0; i < std::min(l,num); i++)
data[i] = false;
for (int i = l; i < num; i++)
data[i] = true;
}
@ This constructs a function set hardcopying also the first.
@<|VectorFunctionSet| constructor 1 code@>=
VectorFunctionSet::VectorFunctionSet(const VectorFunction& f, int n)
: funcs(n), first_shallow(false)
{
for (int i = 0; i < n; i++)
funcs[i] = f.clone();
}
@ This constructs a function set with shallow copy in the first and
hard copies in others.
@<|VectorFunctionSet| constructor 2 code@>=
VectorFunctionSet::VectorFunctionSet(VectorFunction& f, int n)
: funcs(n), first_shallow(true)
{
if (n > 0)
funcs[0] = &f;
for (int i = 1; i < n; i++)
funcs[i] = f.clone();
}
@ This deletes the functions. The first is deleted only if it was not
a shallow copy.
@<|VectorFunctionSet| destructor code@>=
VectorFunctionSet::~VectorFunctionSet()
{
unsigned int start = first_shallow ? 1 : 0;
for (unsigned int i = start; i < funcs.size(); i++)
delete funcs[i];
}
@ Here we construct the object from the given function $f$ and given
variance-covariance matrix $\Sigma=$|vcov|. The matrix $A$ is
calculated as lower triangular and yields $\Sigma=AA^T$.
@<|GaussConverterFunction| constructor code 1@>=
GaussConverterFunction::GaussConverterFunction(VectorFunction& f, const GeneralMatrix& vcov)
: VectorFunction(f), func(&f), delete_flag(false), A(vcov.numRows(), vcov.numRows()),
multiplier(calcMultiplier())
{
// todo: raise if |A.numRows() != indim()|
calcCholeskyFactor(vcov);
}
@ Here we construct the object in the same way, however we mark the
function as to be deleted.
@<|GaussConverterFunction| constructor code 2@>=
GaussConverterFunction::GaussConverterFunction(VectorFunction* f, const GeneralMatrix& vcov)
: VectorFunction(*f), func(f), delete_flag(true), A(vcov.numRows(), vcov.numRows()),
multiplier(calcMultiplier())
{
// todo: raise if |A.numRows() != indim()|
calcCholeskyFactor(vcov);
}
@
@<|GaussConverterFunction| copy constructor code@>=
GaussConverterFunction::GaussConverterFunction(const GaussConverterFunction& f)
: VectorFunction(f), func(f.func->clone()), delete_flag(true), A(f.A),
multiplier(f.multiplier)
{
}
@ Here we evaluate the function
$g(y)={1\over\sqrt{\pi^n}}f\left(\sqrt{2}Ay\right)$. Since the matrix $A$ is lower
triangular, the change signal for the function $f$ will look like
$(0,\ldots,0,1,\ldots,1)$ where the first $1$ is in the same position
as the first change in the given signal |sig| of the input
$y=$|point|.
@<|GaussConverterFunction::eval| code@>=
void GaussConverterFunction::eval(const Vector& point, const ParameterSignal& sig, Vector& out)
{
ParameterSignal s(sig);
int i = 0;
while (i < indim() && !sig[i])
i++;
s.signalAfter(i);
Vector x(indim());
x.zeros();
A.multaVec(x, point);
x.mult(sqrt(2.0));
func->eval(x, s, out);
out.mult(multiplier);
}
@ This returns $1\over\sqrt{\pi^n}$.
@<|GaussConverterFunction::multiplier| code@>=
double GaussConverterFunction::calcMultiplier() const
{
return sqrt(pow(M_PI, -1*indim()));
}
@
@<|GaussConverterFunction::calcCholeskyFactor| code@>=
void GaussConverterFunction::calcCholeskyFactor(const GeneralMatrix& vcov)
{
A = vcov;
lapack_int rows = A.numRows();
for (int i = 0; i < rows; i++)
for (int j = i+1; j < rows; j++)
A.get(i,j) = 0.0;
lapack_int info;
dpotrf("L", &rows, A.base(), &rows, &info);
// todo: raise if |info!=1|
}
@ End of {\tt vector\_function.cpp} file