@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 #include #include #include @<|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