ModFile.cc 7.06 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
 * Copyright (C) 2006-2008 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/>.
 */

20
#include <cstdlib>
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
#include <iostream>
#include <fstream>

#include "ModFile.hh"

ModFile::ModFile() : expressions_tree(symbol_table, num_constants),
                     model_tree(symbol_table, num_constants),
                     linear(false)
{
}

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

void
ModFile::addStatement(Statement *st)
{
  statements.push_back(st);
}

void
ModFile::checkPass()
{
  for(vector<Statement *>::iterator it = statements.begin();
      it != statements.end(); it++)
    (*it)->checkPass(mod_file_struct);

52
53
54
55
  // 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
56
57
58
59
60
61
  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;

62
63
64
65
  // Allow empty model only when doing a standalone BVAR estimation
  if (model_tree.equation_number() == 0
      && (mod_file_struct.check_present
          || mod_file_struct.simul_present
sebastien's avatar
sebastien committed
66
67
68
69
70
71
72
          || stochastic_statement_present))
    {
      cerr << "ERROR: At least one model equation must be declared!" << endl;
      exit(-1);
    }

  if (mod_file_struct.simul_present && stochastic_statement_present)
73
    {
sebastien's avatar
sebastien committed
74
      cerr << "ERROR: A .mod file cannot contain both a simul command and one of {stoch_simul, estimation, forecast, osr, ramsey_policy}" << endl;
75
76
77
      exit(-1);
    }

78
79
80
81
82
83
84
85
86
  /*
    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)
           && model_tree.equation_number() == 0)
      && (model_tree.equation_number() != symbol_table.endo_nbr))
87
    {
sebastien's avatar
sebastien committed
88
      cerr << "ERROR: There are " << model_tree.equation_number() << " equations but " << symbol_table.endo_nbr << " endogenous variables!" << endl;
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
      exit(-1);
    }
}

void
ModFile::computingPass()
{
  // Mod file may have no equation (for example in a standalone BVAR estimation)
  if (model_tree.equation_number() > 0)
    {
      // Set things to compute
      if (mod_file_struct.simul_present)
        model_tree.computeJacobian = true;
      else
        {
          if (mod_file_struct.order_option < 1 || mod_file_struct.order_option > 3)
            {
              cerr << "Incorrect order option..." << endl;
              exit(-1);
            }
          model_tree.computeJacobianExo = true;
          if (mod_file_struct.order_option >= 2)
            model_tree.computeHessian = true;
          if (mod_file_struct.order_option == 3)
            model_tree.computeThirdDerivatives = true;
        }

      model_tree.computingPass(global_eval_context);
    }

  for(vector<Statement *>::iterator it = statements.begin();
      it != statements.end(); it++)
    (*it)->computingPass();
}

void
ModFile::writeOutputFiles(const string &basename, bool clear_all) const
{
  ofstream mOutputFile;

  if (basename.size())
    {
      string fname(basename);
sebastien's avatar
sebastien committed
132
      fname += ".m";
133
134
135
      mOutputFile.open(fname.c_str(), ios::out | ios::binary);
      if (!mOutputFile.is_open())
        {
sebastien's avatar
sebastien committed
136
          cerr << "ERROR: Can't open file " << fname
137
138
139
140
141
142
               << " for writing" << endl;
          exit(-1);
        }
    }
  else
    {
sebastien's avatar
sebastien committed
143
      cerr << "ERROR: Missing file name" << endl;
144
145
146
      exit(-1);
    }

sebastien's avatar
sebastien committed
147
148
149
150
151
  mOutputFile << "%" << endl
              << "% Status : main Dynare file " << endl
              << "%" << endl
              << "% Warning : this file is generated automatically by Dynare" << endl
              << "%           from model file (.mod)" << endl << endl;
152
153
154
155
156
157
158
159
160

  if (clear_all)
    mOutputFile << "clear all" << endl;
  mOutputFile << "tic;" << endl;
  mOutputFile << "global M_ oo_ exedet_ exdet_ recur_ recurs_ " << endl;
  mOutputFile << "global options_ endval_" << endl;
  mOutputFile << "global ys0_ recurs0_ ex0_ ct_" << endl;
  mOutputFile << "options_ = [];" << endl;
  mOutputFile << "M_.fname = '" << basename << "';" << endl;
sebastien's avatar
sebastien committed
161
162
163
  mOutputFile << "%" << endl;
  mOutputFile << "% Some global variables initialization" << endl;
  mOutputFile << "%" << endl;
164
  mOutputFile << "global_initialization;" << endl;
165
166
167
168
169
  mOutputFile << "diary off;" << endl
              << "warning_old_state = warning;" << endl
              << "warning off;" << endl
              << "delete " << basename << ".log;" << endl
              << "warning warning_old_state" << endl;
170
  mOutputFile << "logname_ = '" << basename << ".log';" << endl;
171
  mOutputFile << "diary " << basename << ".log" << endl;
172
  mOutputFile << "options_.model_mode = " << model_tree.mode << ";\n";
173
174
175
176
177
178


  if (model_tree.equation_number() > 0)
    {
      if (model_tree.mode == eDLLMode)
        {
sebastien's avatar
sebastien committed
179
          mOutputFile << "if exist('" << basename << "_static.c')" << endl;
180
          mOutputFile << "   clear " << basename << "_static" << endl;
sebastien's avatar
sebastien committed
181
          mOutputFile << "   mex -O " << basename << "_static.c" << endl;
182
          mOutputFile << "end" << endl;
sebastien's avatar
sebastien committed
183
          mOutputFile << "if exist('" << basename << "_dynamic.c')" << endl;
184
          mOutputFile << "   clear " << basename << "_dynamic" << endl;
sebastien's avatar
sebastien committed
185
          mOutputFile << "   mex -O " << basename << "_dynamic.c" << endl;
186
187
188
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
          mOutputFile << "end" << endl;
        }
      else
        {
          mOutputFile << "erase_compiled_function('" + basename +"_static');" << endl;
          mOutputFile << "erase_compiled_function('" + basename +"_dynamic');" << endl;
        }
    }

  cout << "Processing outputs ..." << endl;

  symbol_table.writeOutput(mOutputFile);

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

  if (model_tree.equation_number() > 0)
    {
      model_tree.writeOutput(mOutputFile);
      model_tree.writeStaticFile(basename);
      model_tree.writeDynamicFile(basename);
    }

  // Print statements
  for(vector<Statement *>::const_iterator it = statements.begin();
      it != statements.end(); it++)
    (*it)->writeOutput(mOutputFile, basename);

214
  mOutputFile << "save('" << basename << "_results.mat', 'oo_');" << endl;
215
216
  mOutputFile << "diary off" << endl;

217
  mOutputFile << endl << "disp(['Total computing time : ' dynsec2hms(toc) ]);" << endl;
218
219
  mOutputFile.close();
}