ModFile.cc 8.43 KB
Newer Older
sebastien's avatar
sebastien committed
1
/*
sebastien's avatar
trunk:    
sebastien committed
2
 * Copyright (C) 2006-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
#include <cstdlib>
sebastien's avatar
sebastien committed
21
22
#include <iostream>
#include <fstream>
23
#include <typeinfo>
24
25
#include "ModFile.hh"

sebastien's avatar
sebastien committed
26
ModFile::ModFile() : expressions_tree(symbol_table, num_constants),
sebastien's avatar
sebastien committed
27
28
                     static_model(symbol_table, num_constants),
                     dynamic_model(symbol_table, num_constants),
sebastien's avatar
sebastien committed
29
                     linear(false)
30
31
{
}
sebastien's avatar
sebastien committed
32
33
34
35
36
37
38
39

ModFile::~ModFile()
{
  for(vector<Statement *>::iterator it = statements.begin();
      it != statements.end(); it++)
    delete (*it);
}

40
41
42
void
ModFile::evalAllExpressions()
{
sebastien's avatar
sebastien committed
43
  cout << "Evaluating expressions...";
44

sebastien's avatar
sebastien committed
45
46
  // Loop over all statements, and fill global eval context if relevant
  for(vector<Statement *>::const_iterator it = statements.begin(); it != statements.end(); it++)
47
    {
sebastien's avatar
sebastien committed
48
49
50
51
52
53
54
55
56
57
58
      InitParamStatement *ips = dynamic_cast<InitParamStatement *>(*it);
      if (ips)
        ips->fillEvalContext(global_eval_context);

      InitOrEndValStatement *ies = dynamic_cast<InitOrEndValStatement *>(*it);
      if (ies)
        ies->fillEvalContext(global_eval_context);

      LoadParamsAndSteadyStateStatement *lpass = dynamic_cast<LoadParamsAndSteadyStateStatement *>(*it);
      if (lpass)
        lpass->fillEvalContext(global_eval_context);
59
    }
sebastien's avatar
sebastien committed
60
61

  // Evaluate model local variables
sebastien's avatar
sebastien committed
62
  dynamic_model.fillEvalContext(global_eval_context);
sebastien's avatar
sebastien committed
63
64
65
66
67

  cout << "done" << endl;

  // Check if some symbols are not initialized, and give them a zero value then
  for(int id = 0; id <= symbol_table.maxID(); id++)
68
    {
sebastien's avatar
sebastien committed
69
70
71
72
      SymbolType type = symbol_table.getType(id);
      if ((type == eEndogenous || type == eExogenous || type == eExogenousDet
          || type == eParameter || type == eModelLocalVariable)
          && global_eval_context.find(id) == global_eval_context.end())
73
        {
sebastien's avatar
sebastien committed
74
75
          cerr << "WARNING: can't find a numeric initial value for " << symbol_table.getName(id) << ", using zero" << endl;
          global_eval_context[id] = 0;
76
77
78
79
        }
    }
}

sebastien's avatar
sebastien committed
80
81
82
83
84
85
void
ModFile::addStatement(Statement *st)
{
  statements.push_back(st);
}

sebastien's avatar
sebastien committed
86
87
88
89
90
91
92
void
ModFile::checkPass()
{
  for(vector<Statement *>::iterator it = statements.begin();
      it != statements.end(); it++)
    (*it)->checkPass(mod_file_struct);

93
94
95
96
  // If order option has not been set, default to 2
  if (!mod_file_struct.order_option)
    mod_file_struct.order_option = 2;

sebastien's avatar
sebastien committed
97
98
99
100
101
102
  bool stochastic_statement_present = mod_file_struct.stoch_simul_present
    || mod_file_struct.estimation_present
    || mod_file_struct.forecast_present
    || mod_file_struct.osr_present
    || mod_file_struct.ramsey_policy_present;

103
  // Allow empty model only when doing a standalone BVAR estimation
sebastien's avatar
sebastien committed
104
  if (dynamic_model.equation_number() == 0
105
106
      && (mod_file_struct.check_present
          || mod_file_struct.simul_present
sebastien's avatar
sebastien committed
107
108
109
          || stochastic_statement_present))
    {
      cerr << "ERROR: At least one model equation must be declared!" << endl;
110
      exit(EXIT_FAILURE);
sebastien's avatar
sebastien committed
111
112
    }

113
  if (mod_file_struct.simul_present && stochastic_statement_present)
114
    {
sebastien's avatar
sebastien committed
115
      cerr << "ERROR: A .mod file cannot contain both a simul command and one of {stoch_simul, estimation, forecast, osr, ramsey_policy}" << endl;
116
      exit(EXIT_FAILURE);
117
118
    }

sebastien's avatar
sebastien committed
119
120
121
  // Freeze the symbol table
  symbol_table.freeze();

122
123
124
125
126
127
128
  /*
    Enforce the same number of equations and endogenous, except in two cases:
    - ramsey_policy is used
    - a BVAR command is used and there is no equation (standalone BVAR estimation)
  */
  if (!mod_file_struct.ramsey_policy_present
      && !((mod_file_struct.bvar_density_present || mod_file_struct.bvar_forecast_present)
sebastien's avatar
sebastien committed
129
130
           && dynamic_model.equation_number() == 0)
      && (dynamic_model.equation_number() != symbol_table.endo_nbr()))
sebastien's avatar
sebastien committed
131
    {
sebastien's avatar
sebastien committed
132
      cerr << "ERROR: There are " << dynamic_model.equation_number() << " equations but " << symbol_table.endo_nbr() << " endogenous variables!" << endl;
133
      exit(EXIT_FAILURE);
sebastien's avatar
sebastien committed
134
    }
sebastien's avatar
sebastien committed
135
136

  cout << "Found " << dynamic_model.equation_number() << " equation(s)." << endl;
sebastien's avatar
sebastien committed
137
}
sebastien's avatar
sebastien committed
138

sebastien's avatar
sebastien committed
139
void
140
ModFile::computingPass(bool no_tmp_terms)
sebastien's avatar
sebastien committed
141
{
142
  // Mod file may have no equation (for example in a standalone BVAR estimation)
sebastien's avatar
sebastien committed
143
  if (dynamic_model.equation_number() > 0)
sebastien's avatar
sebastien committed
144
    {
sebastien's avatar
sebastien committed
145
146
      // Compute static model and its derivatives
      dynamic_model.toStatic(static_model);
147
      static_model.computingPass(mod_file_struct.steady_block_mfs_option, false, no_tmp_terms);
sebastien's avatar
sebastien committed
148
149

      // Set things to compute for dynamic model
ferhat's avatar
ferhat committed
150

151
      if (mod_file_struct.simul_present)
sebastien's avatar
sebastien committed
152
        dynamic_model.computingPass(false, false, false, false, global_eval_context, no_tmp_terms);
153
      else
sebastien's avatar
sebastien committed
154
        {
155
156
          if (mod_file_struct.order_option < 1 || mod_file_struct.order_option > 3)
            {
157
              cerr << "ERROR: Incorrect order option..." << endl;
158
              exit(EXIT_FAILURE);
159
            }
160
161
          bool hessian = mod_file_struct.order_option >= 2;
          bool thirdDerivatives = mod_file_struct.order_option == 3;
sebastien's avatar
sebastien committed
162
163
          bool paramsDerivatives = mod_file_struct.identification_present;
          dynamic_model.computingPass(true, hessian, thirdDerivatives, paramsDerivatives, global_eval_context, no_tmp_terms);
sebastien's avatar
sebastien committed
164
        }
165
    }
166

sebastien's avatar
sebastien committed
167
168
169
  for(vector<Statement *>::iterator it = statements.begin();
      it != statements.end(); it++)
    (*it)->computingPass();
sebastien's avatar
sebastien committed
170
171
}

sebastien's avatar
sebastien committed
172
void
sebastien's avatar
sebastien committed
173
ModFile::writeOutputFiles(const string &basename, bool clear_all) const
sebastien's avatar
sebastien committed
174
175
176
177
178
179
{
  ofstream mOutputFile;

  if (basename.size())
    {
      string fname(basename);
sebastien's avatar
sebastien committed
180
      fname += ".m";
sebastien's avatar
sebastien committed
181
182
183
      mOutputFile.open(fname.c_str(), ios::out | ios::binary);
      if (!mOutputFile.is_open())
        {
sebastien's avatar
sebastien committed
184
          cerr << "ERROR: Can't open file " << fname
sebastien's avatar
sebastien committed
185
               << " for writing" << endl;
186
          exit(EXIT_FAILURE);
sebastien's avatar
sebastien committed
187
188
189
190
        }
    }
  else
    {
sebastien's avatar
sebastien committed
191
      cerr << "ERROR: Missing file name" << endl;
192
      exit(EXIT_FAILURE);
sebastien's avatar
sebastien committed
193
194
    }

sebastien's avatar
sebastien committed
195
196
197
198
199
  mOutputFile << "%" << endl
              << "% Status : main Dynare file " << endl
              << "%" << endl
              << "% Warning : this file is generated automatically by Dynare" << endl
              << "%           from model file (.mod)" << endl << endl;
sebastien's avatar
sebastien committed
200
201
202

  if (clear_all)
    mOutputFile << "clear all" << endl;
203
204
205
206
207
208
209
210
211
212
213

  mOutputFile << "tic;" << endl
              << "global M_ oo_ options_" << endl
              << "global ys0_ ex0_ ct_" << endl
              << "options_ = [];" << endl
              << "M_.fname = '" << basename << "';" << endl
              << "%" << endl
              << "% Some global variables initialization" << endl
              << "%" << endl
              << "global_initialization;" << endl
              << "diary off;" << endl
214
215
216
              << "warning_old_state = warning;" << endl
              << "warning off;" << endl
              << "delete " << basename << ".log;" << endl
217
218
              << "warning warning_old_state" << endl
              << "logname_ = '" << basename << ".log';" << endl
219
              << "diary " << basename << ".log" << endl;
220

221
  cout << "Processing outputs ...";
222

sebastien's avatar
sebastien committed
223
224
225
226
227
  symbol_table.writeOutput(mOutputFile);

  if (linear == 1)
    mOutputFile << "options_.linear = 1;" << endl;

sebastien's avatar
sebastien committed
228
  if (dynamic_model.equation_number() > 0)
229
    {
230
231
      dynamic_model.writeOutput(mOutputFile, basename);
      static_model.writeOutput(mOutputFile);
232
    }
sebastien's avatar
sebastien committed
233
234

  // Print statements
sebastien's avatar
sebastien committed
235
  for(vector<Statement *>::const_iterator it = statements.begin();
sebastien's avatar
sebastien committed
236
      it != statements.end(); it++)
sebastien's avatar
sebastien committed
237
    (*it)->writeOutput(mOutputFile, basename);
sebastien's avatar
sebastien committed
238

239
240
  if (dynamic_model.equation_number() > 0)
    dynamic_model.writeOutputPostComputing(mOutputFile, basename);
241

242
243
244
  mOutputFile << "save('" << basename << "_results.mat', 'oo_', 'M_', 'options_');" << endl
              << "diary off" << endl
              << endl << "disp(['Total computing time : ' dynsec2hms(toc) ]);" << endl;
sebastien's avatar
sebastien committed
245
246

  mOutputFile.close();
247

248
249
250
251
252
253
254
255
  // Create static and dynamic files
  if (dynamic_model.equation_number() > 0)
    {
      static_model.writeStaticFile(basename);
      dynamic_model.writeDynamicFile(basename);
      dynamic_model.writeParamsDerivativesFile(basename);
    }

256
  cout << "done" << endl;
sebastien's avatar
sebastien committed
257
}