Shocks.cc 8.64 KB
Newer Older
sebastien's avatar
sebastien committed
1
/*
sebastien's avatar
sebastien committed
2
 * Copyright (C) 2003-2009 Dynare Team
sebastien's avatar
sebastien committed
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 *
 * 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/>.
 */

20
using namespace std;
sebastien's avatar
sebastien committed
21

22
23
#include <cassert>
#include <cstdlib>
sebastien's avatar
sebastien committed
24
25
#include <iostream>

26
27
#include "Shocks.hh"

sebastien's avatar
sebastien committed
28
AbstractShocksStatement::AbstractShocksStatement(bool mshocks_arg,
29
30
31
32
33
34
                                                 const det_shocks_type &det_shocks_arg,
                                                 const var_and_std_shocks_type &var_shocks_arg,
                                                 const var_and_std_shocks_type &std_shocks_arg,
                                                 const covar_and_corr_shocks_type &covar_shocks_arg,
                                                 const covar_and_corr_shocks_type &corr_shocks_arg,
                                                 const SymbolTable &symbol_table_arg) :
sebastien's avatar
sebastien committed
35
36
37
38
39
40
41
  mshocks(mshocks_arg),
  det_shocks(det_shocks_arg),
  var_shocks(var_shocks_arg),
  std_shocks(std_shocks_arg),
  covar_shocks(covar_shocks_arg),
  corr_shocks(corr_shocks_arg),
  symbol_table(symbol_table_arg)
42
43
44
{
}

sebastien's avatar
sebastien committed
45
46
void
AbstractShocksStatement::writeDetShocks(ostream &output) const
47
{
sebastien's avatar
sebastien committed
48
  int exo_det_length = 0;
49

sebastien's avatar
sebastien committed
50
51
52
  for(det_shocks_type::const_iterator it = det_shocks.begin();
      it != det_shocks.end(); it++)
    {
sebastien's avatar
sebastien committed
53
      int id = symbol_table.getTypeSpecificID(it->first) + 1;
sebastien's avatar
sebastien committed
54
55
      bool exo_det = (symbol_table.getType(it->first) == eExogenousDet);
      int set_shocks_index = ((int) mshocks) + 2 * ((int) exo_det);
56

sebastien's avatar
sebastien committed
57
58
59
60
      for (unsigned int i = 0; i < it->second.size(); i++)
        {
          const int &period1 = it->second[i].period1;
          const int &period2 = it->second[i].period2;
sebastien's avatar
sebastien committed
61
          const NodeID value = it->second[i].value;
sebastien's avatar
sebastien committed
62
63

          if (period1 == period2)
sebastien's avatar
sebastien committed
64
65
66
67
68
69
            {
              output << "set_shocks(" << set_shocks_index << "," << period1
                     << ", " << id << ", ";
              value->writeOutput(output);
              output << ");" << endl;
            }
sebastien's avatar
sebastien committed
70
          else
sebastien's avatar
sebastien committed
71
72
73
74
75
76
            {
              output << "set_shocks(" << set_shocks_index << "," << period1
                     << ":" << period2 << ", " << id << ", ";
              value->writeOutput(output);
              output << ");" << endl;
            }
sebastien's avatar
sebastien committed
77
78
79
80
81
82

          if (exo_det && (period2 > exo_det_length))
            exo_det_length = period2;
        }
    }
  output << "M_.exo_det_length = " << exo_det_length << ";\n";
83
84
}

sebastien's avatar
sebastien committed
85
86
void
AbstractShocksStatement::writeVarAndStdShocks(ostream &output) const
87
{
sebastien's avatar
sebastien committed
88
  var_and_std_shocks_type::const_iterator it;
89

sebastien's avatar
sebastien committed
90
  for(it = var_shocks.begin(); it != var_shocks.end(); it++)
91
    {
sebastien's avatar
sebastien committed
92
      int id = symbol_table.getTypeSpecificID(it->first) + 1;
sebastien's avatar
sebastien committed
93
94
95
96
      const NodeID value = it->second;
      output << "M_.Sigma_e(" << id << ", " << id << ") = ";
      value->writeOutput(output);
      output << ";" << endl;
97
    }
sebastien's avatar
sebastien committed
98
99

  for(it = std_shocks.begin(); it != std_shocks.end(); it++)
100
    {
sebastien's avatar
sebastien committed
101
      int id = symbol_table.getTypeSpecificID(it->first) + 1;
sebastien's avatar
sebastien committed
102
103
104
105
      const NodeID value = it->second;
      output << "M_.Sigma_e(" << id << ", " << id << ") = (";
      value->writeOutput(output);
      output << ")^2;" << endl;
106
107
108
    }
}

sebastien's avatar
sebastien committed
109
110
void
AbstractShocksStatement::writeCovarAndCorrShocks(ostream &output) const
111
{
sebastien's avatar
sebastien committed
112
113
114
  covar_and_corr_shocks_type::const_iterator it;

  for(it = covar_shocks.begin(); it != covar_shocks.end(); it++)
115
    {
sebastien's avatar
sebastien committed
116
117
      int id1 = symbol_table.getTypeSpecificID(it->first.first) + 1;
      int id2 = symbol_table.getTypeSpecificID(it->first.second) + 1;
sebastien's avatar
sebastien committed
118
119
120
121
      const NodeID value = it->second;
      output << "M_.Sigma_e(" << id1 << ", " << id2 << ") = ";
      value->writeOutput(output);
      output << "; M_.Sigma_e(" << id2 << ", " << id1 << ") = M_.Sigma_e("
sebastien's avatar
sebastien committed
122
             << id1 << ", " << id2 << ");\n";
123
    }
sebastien's avatar
sebastien committed
124
125

  for(it = corr_shocks.begin(); it != corr_shocks.end(); it++)
126
    {
sebastien's avatar
sebastien committed
127
128
      int id1 = symbol_table.getTypeSpecificID(it->first.first) + 1;
      int id2 = symbol_table.getTypeSpecificID(it->first.second) + 1;
sebastien's avatar
sebastien committed
129
130
131
132
      const NodeID value = it->second;
      output << "M_.Sigma_e(" << id1 << ", " << id2 << ") = ";
      value->writeOutput(output);
      output << "*sqrt(M_.Sigma_e(" << id1 << ", " << id1 << ")*M_.Sigma_e("
133
             << id2 << ", " << id2 << ")); M_.Sigma_e(" << id2 << ", "
sebastien's avatar
sebastien committed
134
             << id1 << ") = M_.Sigma_e(" << id1 << ", " << id2 << ");\n";
135
136
137
138
    }
}


sebastien's avatar
sebastien committed
139
140
141
142
143
144
145
146
ShocksStatement::ShocksStatement(const det_shocks_type &det_shocks_arg,
                                 const var_and_std_shocks_type &var_shocks_arg,
                                 const var_and_std_shocks_type &std_shocks_arg,
                                 const covar_and_corr_shocks_type &covar_shocks_arg,
                                 const covar_and_corr_shocks_type &corr_shocks_arg,
                                 const SymbolTable &symbol_table_arg) :
  AbstractShocksStatement(false, det_shocks_arg, var_shocks_arg, std_shocks_arg,
                          covar_shocks_arg, corr_shocks_arg, symbol_table_arg)
147
148
149
{
}

sebastien's avatar
sebastien committed
150
void
sebastien's avatar
sebastien committed
151
ShocksStatement::writeOutput(ostream &output, const string &basename) const
152
{
sebastien's avatar
sebastien committed
153
154
155
  output << "%" << endl
         << "% SHOCKS instructions" << endl
         << "%" << endl;
156

sebastien's avatar
sebastien committed
157
  // Write instruction that initializes a shock
sebastien's avatar
sebastien committed
158
  output << "make_ex_;" << endl;
sebastien's avatar
sebastien committed
159
160
161
162

  writeDetShocks(output);
  writeVarAndStdShocks(output);
  writeCovarAndCorrShocks(output);
163
164
}

sebastien's avatar
sebastien committed
165
166
167
168
169
170
171
172
MShocksStatement::MShocksStatement(const det_shocks_type &det_shocks_arg,
                                   const var_and_std_shocks_type &var_shocks_arg,
                                   const var_and_std_shocks_type &std_shocks_arg,
                                   const covar_and_corr_shocks_type &covar_shocks_arg,
                                   const covar_and_corr_shocks_type &corr_shocks_arg,
                                   const SymbolTable &symbol_table_arg) :
  AbstractShocksStatement(true, det_shocks_arg, var_shocks_arg, std_shocks_arg,
                          covar_shocks_arg, corr_shocks_arg, symbol_table_arg)
173
174
175
{
}

sebastien's avatar
sebastien committed
176
void
sebastien's avatar
sebastien committed
177
MShocksStatement::writeOutput(ostream &output, const string &basename) const
178
{
sebastien's avatar
sebastien committed
179
180
181
  output << "%" << endl
         << "% SHOCKS instructions" << endl
         << "%" << endl;
182

sebastien's avatar
sebastien committed
183
  // Write instruction that initializes a shock
sebastien's avatar
sebastien committed
184
  output << "make_ex_;" << endl;
185

sebastien's avatar
sebastien committed
186
187
188
  writeDetShocks(output);
  writeVarAndStdShocks(output);
  writeCovarAndCorrShocks(output);
189
}
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242

ConditionalForecastPathsStatement::ConditionalForecastPathsStatement(const AbstractShocksStatement::det_shocks_type &paths_arg, const SymbolTable &symbol_table_arg) :
  paths(paths_arg),
  symbol_table(symbol_table_arg),
  path_length(-1)
{
}

void
ConditionalForecastPathsStatement::checkPass(ModFileStructure &mod_file_struct)
{
  for(AbstractShocksStatement::det_shocks_type::const_iterator it = paths.begin();
      it != paths.end(); it++)
    {
      int this_path_length = 0;
      const vector<AbstractShocksStatement::DetShockElement> &elems = it->second;
      for(int i = 0; i < (int) elems.size(); i++)
        // Period1 < Period2, as enforced in ParsingDriver::add_period()
        this_path_length = max(this_path_length, elems[i].period2);
      if (path_length == -1)
        path_length = this_path_length;
      else if (path_length != this_path_length)
        {
          cerr << "conditional_forecast_paths: all constrained paths must have the same length!" << endl;
          exit(EXIT_FAILURE);
        }
    }
}

void
ConditionalForecastPathsStatement::writeOutput(ostream &output, const string &basename) const
{
  assert(path_length > 0);
  output << "constrained_vars_ = [];" << endl
         << "constrained_paths_ = zeros(" << paths.size() << ", " << path_length << ");" << endl;

  int k = 1;

  for(AbstractShocksStatement::det_shocks_type::const_iterator it = paths.begin();
      it != paths.end(); it++)
    {
      output << "constrained_vars_ = strvcat(constrained_vars_, '" << it->first << "');" << endl;
      const vector<AbstractShocksStatement::DetShockElement> &elems = it->second;
      for(int i = 0; i < (int) elems.size(); i++)
        for(int j = elems[i].period1; j <= elems[i].period2; j++)
          {
            output << "constrained_paths_(" << k << "," << j << ")=";
            elems[i].value->writeOutput(output);
            output << ";" << endl;
          }
      k++;
    }
}