2019-06-19 14:34:30 +02:00
|
|
|
|
/*
|
|
|
|
|
* Copyright © 2005 Ondra Kamenik
|
|
|
|
|
* Copyright © 2019 Dynare Team
|
|
|
|
|
*
|
|
|
|
|
* This file is part of Dynare.
|
|
|
|
|
*
|
|
|
|
|
* Dynare is free software: you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
* (at your option) any later version.
|
|
|
|
|
*
|
|
|
|
|
* Dynare is distributed in the hope that it will be useful,
|
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
2021-06-09 17:33:48 +02:00
|
|
|
|
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
2019-06-19 14:34:30 +02:00
|
|
|
|
*/
|
2019-01-04 17:27:23 +01:00
|
|
|
|
|
|
|
|
|
// Vector function.
|
|
|
|
|
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* This file defines interface for functions taking a vector as an input and
|
|
|
|
|
returning a vector (with a different size) as an output. We are also
|
|
|
|
|
introducing a parameter signalling; it is a boolean vector which tracks
|
|
|
|
|
parameters which were changed from the previous call. The VectorFunction
|
|
|
|
|
implementation can exploit this information and evaluate the function more
|
|
|
|
|
efficiently. The information can be completely ignored.
|
2019-01-04 17:27:23 +01:00
|
|
|
|
|
2019-06-19 17:33:01 +02:00
|
|
|
|
From the signalling reason, and from other reasons, the function evaluation
|
|
|
|
|
is not const. */
|
2019-01-04 17:27:23 +01:00
|
|
|
|
|
|
|
|
|
#ifndef VECTOR_FUNCTION_H
|
|
|
|
|
#define VECTOR_FUNCTION_H
|
|
|
|
|
|
2019-01-08 17:12:05 +01:00
|
|
|
|
#include "Vector.hh"
|
|
|
|
|
#include "GeneralMatrix.hh"
|
2019-01-04 17:27:23 +01:00
|
|
|
|
|
|
|
|
|
#include <vector>
|
2019-01-14 16:09:49 +01:00
|
|
|
|
#include <memory>
|
2019-01-04 17:27:23 +01:00
|
|
|
|
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* This is a simple class representing a vector of booleans. The items night be
|
|
|
|
|
retrieved or changed, or can be set ‘true’ after some point. This is useful
|
|
|
|
|
when we multiply the vector with lower triangular matrix.
|
2019-01-04 17:27:23 +01:00
|
|
|
|
|
2019-06-19 17:33:01 +02:00
|
|
|
|
‘true’ means that a parameter was changed. */
|
2019-01-04 17:27:23 +01:00
|
|
|
|
|
|
|
|
|
class ParameterSignal
|
|
|
|
|
{
|
|
|
|
|
protected:
|
2019-01-14 16:09:49 +01:00
|
|
|
|
std::vector<bool> data;
|
2019-01-04 17:27:23 +01:00
|
|
|
|
public:
|
|
|
|
|
ParameterSignal(int n);
|
2019-01-14 16:09:49 +01:00
|
|
|
|
ParameterSignal(const ParameterSignal &sig) = default;
|
|
|
|
|
~ParameterSignal() = default;
|
2019-01-04 17:27:23 +01:00
|
|
|
|
void signalAfter(int l);
|
2019-01-14 16:09:49 +01:00
|
|
|
|
bool
|
2019-01-04 17:27:23 +01:00
|
|
|
|
operator[](int i) const
|
|
|
|
|
{
|
|
|
|
|
return data[i];
|
|
|
|
|
}
|
2019-01-14 16:09:49 +01:00
|
|
|
|
std::vector<bool>::reference
|
2019-01-04 17:27:23 +01:00
|
|
|
|
operator[](int i)
|
|
|
|
|
{
|
|
|
|
|
return data[i];
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* This is the abstract class for vector function. At this level of abstraction
|
|
|
|
|
we only need to know size of input vector and a size of output vector.
|
2019-01-04 17:27:23 +01:00
|
|
|
|
|
2019-06-19 17:33:01 +02:00
|
|
|
|
The important thing here is a clone method, we will need to make hard copies
|
|
|
|
|
of vector functions since the evaluations are not const. The hardcopies
|
|
|
|
|
apply for parallelization. */
|
2019-01-04 17:27:23 +01:00
|
|
|
|
|
|
|
|
|
class VectorFunction
|
|
|
|
|
{
|
|
|
|
|
protected:
|
|
|
|
|
int in_dim;
|
|
|
|
|
int out_dim;
|
|
|
|
|
public:
|
|
|
|
|
VectorFunction(int idim, int odim)
|
|
|
|
|
: in_dim(idim), out_dim(odim)
|
|
|
|
|
{
|
|
|
|
|
}
|
2019-01-14 16:09:49 +01:00
|
|
|
|
VectorFunction(const VectorFunction &func) = default;
|
|
|
|
|
virtual ~VectorFunction() = default;
|
|
|
|
|
virtual std::unique_ptr<VectorFunction> clone() const = 0;
|
2019-01-04 17:27:23 +01:00
|
|
|
|
virtual void eval(const Vector &point, const ParameterSignal &sig, Vector &out) = 0;
|
|
|
|
|
int
|
|
|
|
|
indim() const
|
|
|
|
|
{
|
|
|
|
|
return in_dim;
|
|
|
|
|
}
|
|
|
|
|
int
|
|
|
|
|
outdim() const
|
|
|
|
|
{
|
|
|
|
|
return out_dim;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* This makes ‘n’ copies of VectorFunction. The first constructor make exactly
|
|
|
|
|
‘n’ new copies, the second constructor copies only the pointer to the first
|
|
|
|
|
and others are hard (real) copies.
|
2019-01-04 17:27:23 +01:00
|
|
|
|
|
2019-06-19 17:33:01 +02:00
|
|
|
|
The class is useful for making a given number of copies at once, and this
|
|
|
|
|
set can be reused many times if we need mupliple copis of the function (for
|
|
|
|
|
example for paralelizing the code). */
|
2019-01-04 17:27:23 +01:00
|
|
|
|
|
|
|
|
|
class VectorFunctionSet
|
|
|
|
|
{
|
2019-01-14 16:09:49 +01:00
|
|
|
|
private:
|
|
|
|
|
// Stores the hard copies made by the class
|
|
|
|
|
std::vector<std::unique_ptr<VectorFunction>> func_copies;
|
2019-01-04 17:27:23 +01:00
|
|
|
|
protected:
|
|
|
|
|
std::vector<VectorFunction *> funcs;
|
|
|
|
|
public:
|
|
|
|
|
VectorFunctionSet(const VectorFunction &f, int n);
|
|
|
|
|
VectorFunctionSet(VectorFunction &f, int n);
|
2019-01-14 16:09:49 +01:00
|
|
|
|
~VectorFunctionSet() = default;
|
2019-01-04 17:27:23 +01:00
|
|
|
|
VectorFunction &
|
|
|
|
|
getFunc(int i)
|
|
|
|
|
{
|
|
|
|
|
return *(funcs[i]);
|
|
|
|
|
}
|
|
|
|
|
int
|
|
|
|
|
getNum() const
|
|
|
|
|
{
|
|
|
|
|
return funcs.size();
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2019-06-19 17:33:01 +02:00
|
|
|
|
/* This class wraps another VectorFunction to allow integration of a function
|
|
|
|
|
through normally distributed inputs. Namely, if one wants to integrate
|
|
|
|
|
|
|
|
|
|
1
|
|
|
|
|
─────────── ∫ f(x)e^{−½xᵀ|Σ|⁻¹x}dx
|
|
|
|
|
√{(2π)ⁿ|Σ|}
|
|
|
|
|
|
|
|
|
|
then if we write Σ=AAᵀ and x=√2·Ay, we get integral
|
|
|
|
|
|
|
|
|
|
1 1
|
|
|
|
|
─────────── ∫ f(√2·Ay)e^{−½yᵀy} √(2ⁿ)|A|dy = ───── ∫ f(√2·Ay)e^{−½yᵀy}dy
|
|
|
|
|
√{(2π)ⁿ|Σ|} √(πⁿ)
|
|
|
|
|
|
|
|
|
|
which means that a given function f we have to wrap to yield a function
|
|
|
|
|
|
|
|
|
|
g(y) = 1/√(πⁿ) f(√2·Ay).
|
|
|
|
|
|
|
|
|
|
This is exactly what this class is doing. This transformation is useful
|
|
|
|
|
since the Gauss-Hermite points and weights are defined for weighting
|
|
|
|
|
function e^{−y²}, so this transformation allows using Gauss-Hermite
|
|
|
|
|
quadratures seemlessly in a context of integration through normally
|
|
|
|
|
distributed inputs.
|
|
|
|
|
|
|
|
|
|
The class maintains a pointer to the function f. When the object is
|
|
|
|
|
constructed by the first constructor, the f is assumed to be owned by the
|
|
|
|
|
caller. If the object of this class is copied, then f is copied and hence
|
2019-01-14 16:09:49 +01:00
|
|
|
|
stored in a std::unique_ptr. The second constructor takes a smart pointer to
|
2019-06-19 17:33:01 +02:00
|
|
|
|
the function and in that case the class takes ownership of f. */
|
2019-01-04 17:27:23 +01:00
|
|
|
|
|
|
|
|
|
class GaussConverterFunction : public VectorFunction
|
|
|
|
|
{
|
2019-01-14 16:09:49 +01:00
|
|
|
|
private:
|
|
|
|
|
std::unique_ptr<VectorFunction> func_storage;
|
2019-01-04 17:27:23 +01:00
|
|
|
|
protected:
|
|
|
|
|
VectorFunction *func;
|
|
|
|
|
GeneralMatrix A;
|
|
|
|
|
double multiplier;
|
|
|
|
|
public:
|
|
|
|
|
GaussConverterFunction(VectorFunction &f, const GeneralMatrix &vcov);
|
2019-01-14 16:09:49 +01:00
|
|
|
|
GaussConverterFunction(std::unique_ptr<VectorFunction> f, const GeneralMatrix &vcov);
|
2019-01-04 17:27:23 +01:00
|
|
|
|
GaussConverterFunction(const GaussConverterFunction &f);
|
2019-01-14 16:09:49 +01:00
|
|
|
|
~GaussConverterFunction() override = default;
|
|
|
|
|
std::unique_ptr<VectorFunction>
|
2019-01-09 16:26:42 +01:00
|
|
|
|
clone() const override
|
2019-01-04 17:27:23 +01:00
|
|
|
|
{
|
2019-01-14 16:09:49 +01:00
|
|
|
|
return std::make_unique<GaussConverterFunction>(*this);
|
2019-01-04 17:27:23 +01:00
|
|
|
|
}
|
2019-01-09 16:26:42 +01:00
|
|
|
|
void eval(const Vector &point, const ParameterSignal &sig, Vector &out) override;
|
2019-01-04 17:27:23 +01:00
|
|
|
|
private:
|
|
|
|
|
double calcMultiplier() const;
|
|
|
|
|
void calcCholeskyFactor(const GeneralMatrix &vcov);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif
|