File: vector_function.hh

package info (click to toggle)
dynare 4.6.3-4
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 74,896 kB
  • sloc: cpp: 98,057; ansic: 28,929; pascal: 13,844; sh: 5,947; objc: 4,236; yacc: 4,215; makefile: 2,583; lex: 1,534; fortran: 877; python: 647; ruby: 291; lisp: 152; xml: 22
file content (186 lines) | stat: -rw-r--r-- 6,007 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/*
 * 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
 * along with Dynare.  If not, see <http://www.gnu.org/licenses/>.
 */

// Vector function.

/* 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.

   From the signalling reason, and from other reasons, the function evaluation
   is not const. */

#ifndef VECTOR_FUNCTION_H
#define VECTOR_FUNCTION_H

#include "Vector.hh"
#include "GeneralMatrix.hh"

#include <vector>
#include <memory>

/* 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.

   ‘true’ means that a parameter was changed. */

class ParameterSignal
{
protected:
  std::vector<bool> data;
public:
  ParameterSignal(int n);
  ParameterSignal(const ParameterSignal &sig) = default;
  ~ParameterSignal() = default;
  void signalAfter(int l);
  bool
  operator[](int i) const
  {
    return data[i];
  }
  std::vector<bool>::reference
  operator[](int i)
  {
    return data[i];
  }
};

/* 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.

   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. */

class VectorFunction
{
protected:
  int in_dim;
  int out_dim;
public:
  VectorFunction(int idim, int odim)
    : in_dim(idim), out_dim(odim)
  {
  }
  VectorFunction(const VectorFunction &func) = default;
  virtual ~VectorFunction() = default;
  virtual std::unique_ptr<VectorFunction> clone() const = 0;
  virtual void eval(const Vector &point, const ParameterSignal &sig, Vector &out) = 0;
  int
  indim() const
  {
    return in_dim;
  }
  int
  outdim() const
  {
    return out_dim;
  }
};

/* 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.

   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). */

class VectorFunctionSet
{
private:
  // Stores the hard copies made by the class
  std::vector<std::unique_ptr<VectorFunction>> func_copies;
protected:
  std::vector<VectorFunction *> funcs;
public:
  VectorFunctionSet(const VectorFunction &f, int n);
  VectorFunctionSet(VectorFunction &f, int n);
  ~VectorFunctionSet() = default;
  VectorFunction &
  getFunc(int i)
  {
    return *(funcs[i]);
  }
  int
  getNum() const
  {
    return funcs.size();
  }
};

/* 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
   stored in a std::unique_ptr. The second constructor takes a smart pointer to
   the function and in that case the class takes ownership of f. */

class GaussConverterFunction : public VectorFunction
{
private:
  std::unique_ptr<VectorFunction> func_storage;
protected:
  VectorFunction *func;
  GeneralMatrix A;
  double multiplier;
public:
  GaussConverterFunction(VectorFunction &f, const GeneralMatrix &vcov);
  GaussConverterFunction(std::unique_ptr<VectorFunction> f, const GeneralMatrix &vcov);
  GaussConverterFunction(const GaussConverterFunction &f);
  ~GaussConverterFunction() override = default;
  std::unique_ptr<VectorFunction>
  clone() const override
  {
    return std::make_unique<GaussConverterFunction>(*this);
  }
  void eval(const Vector &point, const ParameterSignal &sig, Vector &out) override;
private:
  double calcMultiplier() const;
  void calcCholeskyFactor(const GeneralMatrix &vcov);
};

#endif