2008-02-03 11:28:36 +01:00
|
|
|
/*
|
2023-02-28 15:33:24 +01:00
|
|
|
* Copyright © 2003-2023 Dynare Team
|
2008-02-03 11:28:36 +01:00
|
|
|
*
|
|
|
|
* 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 16:52:20 +02:00
|
|
|
* along with Dynare. If not, see <https://www.gnu.org/licenses/>.
|
2008-02-03 11:28:36 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <algorithm>
|
2009-11-09 12:03:18 +01:00
|
|
|
#include <cassert>
|
2023-11-30 15:28:57 +01:00
|
|
|
#include <iostream>
|
|
|
|
#include <sstream>
|
2019-04-23 14:51:14 +02:00
|
|
|
#pragma GCC diagnostic push
|
|
|
|
#pragma GCC diagnostic ignored "-Wold-style-cast"
|
2017-02-02 15:09:43 +01:00
|
|
|
#include <boost/algorithm/string/replace.hpp>
|
2019-04-23 14:51:14 +02:00
|
|
|
#pragma GCC diagnostic pop
|
2019-01-15 11:08:47 +01:00
|
|
|
#include <utility>
|
2008-02-03 11:28:36 +01:00
|
|
|
|
|
|
|
#include "SymbolTable.hh"
|
|
|
|
|
2009-09-30 17:10:31 +02:00
|
|
|
int
|
2023-11-30 15:28:57 +01:00
|
|
|
SymbolTable::addSymbol(const string& name, SymbolType type, const string& tex_name,
|
|
|
|
const vector<pair<string, string>>& partition_value) noexcept(false)
|
2008-02-03 11:28:36 +01:00
|
|
|
{
|
2009-02-27 13:19:25 +01:00
|
|
|
if (frozen)
|
|
|
|
throw FrozenException();
|
|
|
|
|
2008-02-03 11:28:36 +01:00
|
|
|
if (exists(name))
|
2008-06-28 13:20:45 +02:00
|
|
|
{
|
2009-02-27 13:19:25 +01:00
|
|
|
if (type_table[getID(name)] == type)
|
2023-11-30 15:28:57 +01:00
|
|
|
throw AlreadyDeclaredException {name, true};
|
2008-06-28 13:20:45 +02:00
|
|
|
else
|
2023-11-30 15:28:57 +01:00
|
|
|
throw AlreadyDeclaredException {name, false};
|
2008-06-28 13:20:45 +02:00
|
|
|
}
|
2008-02-03 11:28:36 +01:00
|
|
|
|
2013-12-10 11:39:41 +01:00
|
|
|
string final_tex_name = tex_name;
|
|
|
|
if (final_tex_name.empty())
|
|
|
|
{
|
|
|
|
final_tex_name = name;
|
|
|
|
size_t pos = 0;
|
|
|
|
while ((pos = final_tex_name.find('_', pos)) != string::npos)
|
|
|
|
{
|
2019-04-03 16:32:52 +02:00
|
|
|
final_tex_name.insert(pos, R"(\)");
|
2013-12-10 11:39:41 +01:00
|
|
|
pos += 2;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-24 17:38:54 +02:00
|
|
|
string final_long_name = name;
|
|
|
|
bool non_long_name_partition_exists = false;
|
2023-11-30 15:28:57 +01:00
|
|
|
for (const auto& it : partition_value)
|
2018-07-31 11:48:08 +02:00
|
|
|
if (it.first == "long_name")
|
|
|
|
final_long_name = it.second;
|
|
|
|
else
|
|
|
|
non_long_name_partition_exists = true;
|
2013-12-10 11:39:41 +01:00
|
|
|
|
2017-09-12 14:01:25 +02:00
|
|
|
int id = symbol_table.size();
|
2009-02-27 13:19:25 +01:00
|
|
|
|
|
|
|
symbol_table[name] = id;
|
|
|
|
type_table.push_back(type);
|
|
|
|
name_table.push_back(name);
|
2013-12-10 11:39:41 +01:00
|
|
|
tex_name_table.push_back(final_tex_name);
|
|
|
|
long_name_table.push_back(final_long_name);
|
2016-06-24 17:38:54 +02:00
|
|
|
if (non_long_name_partition_exists)
|
|
|
|
{
|
|
|
|
map<string, string> pmv;
|
2023-11-30 15:28:57 +01:00
|
|
|
for (const auto& it : partition_value)
|
2018-07-31 11:48:08 +02:00
|
|
|
pmv[it.first] = it.second;
|
2016-06-24 17:38:54 +02:00
|
|
|
partition_value_map[id] = pmv;
|
|
|
|
}
|
2009-09-30 17:10:31 +02:00
|
|
|
return id;
|
2009-02-27 13:19:25 +01:00
|
|
|
}
|
|
|
|
|
2009-09-30 17:10:31 +02:00
|
|
|
int
|
2023-11-30 15:28:57 +01:00
|
|
|
SymbolTable::addSymbol(const string& name, SymbolType type) noexcept(false)
|
2009-04-30 15:14:33 +02:00
|
|
|
{
|
2018-07-31 11:48:08 +02:00
|
|
|
return addSymbol(name, type, "", {});
|
2009-04-30 15:14:33 +02:00
|
|
|
}
|
|
|
|
|
2009-02-27 13:19:25 +01:00
|
|
|
void
|
2018-06-04 12:50:53 +02:00
|
|
|
SymbolTable::freeze() noexcept(false)
|
2009-02-27 13:19:25 +01:00
|
|
|
{
|
|
|
|
if (frozen)
|
|
|
|
throw FrozenException();
|
2008-02-03 11:28:36 +01:00
|
|
|
|
2009-02-27 13:19:25 +01:00
|
|
|
frozen = true;
|
|
|
|
|
2019-04-23 11:07:32 +02:00
|
|
|
for (int i = 0; i < static_cast<int>(symbol_table.size()); i++)
|
2008-02-03 11:28:36 +01:00
|
|
|
{
|
2009-02-27 13:19:25 +01:00
|
|
|
int tsi;
|
2009-12-16 18:13:23 +01:00
|
|
|
switch (getType(i))
|
2009-02-27 13:19:25 +01:00
|
|
|
{
|
2018-07-17 18:34:07 +02:00
|
|
|
case SymbolType::endogenous:
|
2009-02-27 13:19:25 +01:00
|
|
|
tsi = endo_ids.size();
|
|
|
|
endo_ids.push_back(i);
|
|
|
|
break;
|
2018-07-17 18:34:07 +02:00
|
|
|
case SymbolType::exogenous:
|
2009-02-27 13:19:25 +01:00
|
|
|
tsi = exo_ids.size();
|
|
|
|
exo_ids.push_back(i);
|
|
|
|
break;
|
2018-07-17 18:34:07 +02:00
|
|
|
case SymbolType::exogenousDet:
|
2009-02-27 13:19:25 +01:00
|
|
|
tsi = exo_det_ids.size();
|
|
|
|
exo_det_ids.push_back(i);
|
|
|
|
break;
|
2018-07-17 18:34:07 +02:00
|
|
|
case SymbolType::parameter:
|
2009-02-27 13:19:25 +01:00
|
|
|
tsi = param_ids.size();
|
|
|
|
param_ids.push_back(i);
|
|
|
|
break;
|
|
|
|
default:
|
2020-09-23 17:02:25 +02:00
|
|
|
continue;
|
2009-02-27 13:19:25 +01:00
|
|
|
}
|
2020-09-23 17:02:25 +02:00
|
|
|
type_specific_ids[i] = tsi;
|
2009-02-27 13:19:25 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-02 15:09:43 +01:00
|
|
|
void
|
|
|
|
SymbolTable::unfreeze()
|
|
|
|
{
|
|
|
|
frozen = false;
|
|
|
|
endo_ids.clear();
|
|
|
|
exo_ids.clear();
|
|
|
|
exo_det_ids.clear();
|
|
|
|
param_ids.clear();
|
|
|
|
type_specific_ids.clear();
|
|
|
|
}
|
|
|
|
|
2009-02-27 13:19:25 +01:00
|
|
|
void
|
2018-06-04 12:50:53 +02:00
|
|
|
SymbolTable::changeType(int id, SymbolType newtype) noexcept(false)
|
2009-02-27 13:19:25 +01:00
|
|
|
{
|
|
|
|
if (frozen)
|
|
|
|
throw FrozenException();
|
|
|
|
|
2017-09-12 14:16:29 +02:00
|
|
|
validateSymbID(id);
|
2009-02-27 13:19:25 +01:00
|
|
|
|
|
|
|
type_table[id] = newtype;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2018-06-04 12:50:53 +02:00
|
|
|
SymbolTable::getID(SymbolType type, int tsid) const noexcept(false)
|
2009-02-27 13:19:25 +01:00
|
|
|
{
|
|
|
|
if (!frozen)
|
|
|
|
throw NotYetFrozenException();
|
|
|
|
|
2009-12-16 18:13:23 +01:00
|
|
|
switch (type)
|
2009-02-27 13:19:25 +01:00
|
|
|
{
|
2018-07-17 18:34:07 +02:00
|
|
|
case SymbolType::endogenous:
|
2019-04-23 11:07:32 +02:00
|
|
|
if (tsid < 0 || tsid >= static_cast<int>(endo_ids.size()))
|
2023-11-30 15:28:57 +01:00
|
|
|
throw UnknownTypeSpecificIDException {tsid, type};
|
2009-02-27 13:19:25 +01:00
|
|
|
else
|
|
|
|
return endo_ids[tsid];
|
2018-07-17 18:34:07 +02:00
|
|
|
case SymbolType::exogenous:
|
2019-04-23 11:07:32 +02:00
|
|
|
if (tsid < 0 || tsid >= static_cast<int>(exo_ids.size()))
|
2023-11-30 15:28:57 +01:00
|
|
|
throw UnknownTypeSpecificIDException {tsid, type};
|
2009-02-27 13:19:25 +01:00
|
|
|
else
|
|
|
|
return exo_ids[tsid];
|
2018-07-17 18:34:07 +02:00
|
|
|
case SymbolType::exogenousDet:
|
2019-04-23 11:07:32 +02:00
|
|
|
if (tsid < 0 || tsid >= static_cast<int>(exo_det_ids.size()))
|
2023-11-30 15:28:57 +01:00
|
|
|
throw UnknownTypeSpecificIDException {tsid, type};
|
2009-02-27 13:19:25 +01:00
|
|
|
else
|
|
|
|
return exo_det_ids[tsid];
|
2018-07-17 18:34:07 +02:00
|
|
|
case SymbolType::parameter:
|
2019-04-23 11:07:32 +02:00
|
|
|
if (tsid < 0 || tsid >= static_cast<int>(param_ids.size()))
|
2023-11-30 15:28:57 +01:00
|
|
|
throw UnknownTypeSpecificIDException {tsid, type};
|
2009-02-27 13:19:25 +01:00
|
|
|
else
|
|
|
|
return param_ids[tsid];
|
|
|
|
default:
|
2023-11-30 15:28:57 +01:00
|
|
|
throw UnknownTypeSpecificIDException {tsid, type};
|
2008-02-03 11:28:36 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-04 14:17:36 +02:00
|
|
|
map<string, map<int, string>>
|
2018-07-18 16:58:16 +02:00
|
|
|
SymbolTable::getPartitionsForType(SymbolType st) const noexcept(false)
|
2016-02-26 16:23:39 +01:00
|
|
|
{
|
2018-06-04 14:17:36 +02:00
|
|
|
map<string, map<int, string>> partitions;
|
2023-11-30 15:28:57 +01:00
|
|
|
for (const auto& it : partition_value_map)
|
2018-06-04 12:26:16 +02:00
|
|
|
if (getType(it.first) == st)
|
2023-11-30 15:28:57 +01:00
|
|
|
for (const auto& it1 : it.second)
|
2022-05-04 14:42:03 +02:00
|
|
|
partitions[it1.first][it.first] = it1.second;
|
2016-06-24 17:38:54 +02:00
|
|
|
return partitions;
|
2016-02-26 16:23:39 +01:00
|
|
|
}
|
|
|
|
|
2008-02-03 11:28:36 +01:00
|
|
|
void
|
2023-11-30 15:28:57 +01:00
|
|
|
SymbolTable::writeOutput(ostream& output) const noexcept(false)
|
2008-02-03 11:28:36 +01:00
|
|
|
{
|
2009-02-27 13:19:25 +01:00
|
|
|
if (!frozen)
|
|
|
|
throw NotYetFrozenException();
|
|
|
|
|
|
|
|
if (exo_nbr() > 0)
|
2008-02-03 11:28:36 +01:00
|
|
|
{
|
2017-10-10 10:05:59 +02:00
|
|
|
output << "M_.exo_names = cell(" << exo_nbr() << ",1);" << endl;
|
|
|
|
output << "M_.exo_names_tex = cell(" << exo_nbr() << ",1);" << endl;
|
|
|
|
output << "M_.exo_names_long = cell(" << exo_nbr() << ",1);" << endl;
|
|
|
|
for (int id = 0; id < exo_nbr(); id++)
|
2023-11-30 15:28:57 +01:00
|
|
|
output << "M_.exo_names(" << id + 1 << ") = {'" << getName(exo_ids[id]) << "'};" << endl
|
|
|
|
<< "M_.exo_names_tex(" << id + 1 << ") = {'" << getTeXName(exo_ids[id]) << "'};"
|
|
|
|
<< endl
|
|
|
|
<< "M_.exo_names_long(" << id + 1 << ") = {'" << getLongName(exo_ids[id]) << "'};"
|
|
|
|
<< endl;
|
|
|
|
for (auto& partition : getPartitionsForType(SymbolType::exogenous))
|
2019-12-16 19:42:59 +01:00
|
|
|
if (partition.first != "long_name")
|
2016-06-24 17:38:54 +02:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
output << "M_.exo_partitions." << partition.first << " = { ";
|
2016-06-24 17:38:54 +02:00
|
|
|
for (int id = 0; id < exo_nbr(); id++)
|
|
|
|
{
|
|
|
|
output << "'";
|
2023-11-30 15:28:57 +01:00
|
|
|
if (auto it1 = partition.second.find(exo_ids[id]); it1 != partition.second.end())
|
2016-06-24 17:38:54 +02:00
|
|
|
output << it1->second;
|
|
|
|
output << "' ";
|
|
|
|
}
|
|
|
|
output << "};" << endl;
|
2019-12-16 19:42:59 +01:00
|
|
|
if (partition.first == "status")
|
2019-03-07 15:24:42 +01:00
|
|
|
output << "M_ = set_observed_exogenous_variables(M_);" << endl;
|
2019-12-16 19:42:59 +01:00
|
|
|
if (partition.first == "used")
|
2019-03-14 11:01:22 +01:00
|
|
|
output << "M_ = set_exogenous_variables_for_simulation(M_);" << endl;
|
2016-06-24 17:38:54 +02:00
|
|
|
}
|
2008-02-03 11:28:36 +01:00
|
|
|
}
|
2019-04-29 23:26:07 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
output << "M_.exo_names = {};" << endl;
|
|
|
|
output << "M_.exo_names_tex = {};" << endl;
|
|
|
|
output << "M_.exo_names_long = {};" << endl;
|
|
|
|
}
|
2016-02-26 16:23:39 +01:00
|
|
|
|
2009-02-27 13:19:25 +01:00
|
|
|
if (exo_det_nbr() > 0)
|
2008-02-03 11:28:36 +01:00
|
|
|
{
|
2017-10-10 10:05:59 +02:00
|
|
|
output << "M_.exo_det_names = cell(" << exo_det_nbr() << ",1);" << endl;
|
|
|
|
output << "M_.exo_det_names_tex = cell(" << exo_det_nbr() << ",1);" << endl;
|
|
|
|
output << "M_.exo_det_names_long = cell(" << exo_det_nbr() << ",1);" << endl;
|
|
|
|
for (int id = 0; id < exo_det_nbr(); id++)
|
2023-11-30 15:28:57 +01:00
|
|
|
output << "M_.exo_det_names(" << id + 1 << ") = {'" << getName(exo_det_ids[id]) << "'};"
|
|
|
|
<< endl
|
|
|
|
<< "M_.exo_det_names_tex(" << id + 1 << ") = {'" << getTeXName(exo_det_ids[id])
|
|
|
|
<< "'};" << endl
|
|
|
|
<< "M_.exo_det_names_long(" << id + 1 << ") = {'" << getLongName(exo_det_ids[id])
|
|
|
|
<< "'};" << endl;
|
2016-06-24 17:38:54 +02:00
|
|
|
output << "M_.exo_det_partitions = struct();" << endl;
|
2023-11-30 15:28:57 +01:00
|
|
|
for (auto& partition : getPartitionsForType(SymbolType::exogenousDet))
|
2019-12-16 19:42:59 +01:00
|
|
|
if (partition.first != "long_name")
|
2016-06-24 17:38:54 +02:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
output << "M_.exo_det_partitions." << partition.first << " = { ";
|
2016-06-24 17:38:54 +02:00
|
|
|
for (int id = 0; id < exo_det_nbr(); id++)
|
|
|
|
{
|
|
|
|
output << "'";
|
2019-12-16 19:42:59 +01:00
|
|
|
if (auto it1 = partition.second.find(exo_det_ids[id]);
|
|
|
|
it1 != partition.second.end())
|
2016-06-24 17:38:54 +02:00
|
|
|
output << it1->second;
|
|
|
|
output << "' ";
|
|
|
|
}
|
|
|
|
output << "};" << endl;
|
|
|
|
}
|
2008-02-03 11:28:36 +01:00
|
|
|
}
|
2016-02-26 16:23:39 +01:00
|
|
|
|
2009-02-27 13:19:25 +01:00
|
|
|
if (endo_nbr() > 0)
|
2008-02-03 11:28:36 +01:00
|
|
|
{
|
2017-10-10 10:05:59 +02:00
|
|
|
output << "M_.endo_names = cell(" << endo_nbr() << ",1);" << endl;
|
|
|
|
output << "M_.endo_names_tex = cell(" << endo_nbr() << ",1);" << endl;
|
|
|
|
output << "M_.endo_names_long = cell(" << endo_nbr() << ",1);" << endl;
|
|
|
|
for (int id = 0; id < endo_nbr(); id++)
|
2023-11-30 15:28:57 +01:00
|
|
|
output << "M_.endo_names(" << id + 1 << ") = {'" << getName(endo_ids[id]) << "'};" << endl
|
|
|
|
<< "M_.endo_names_tex(" << id + 1 << ") = {'" << getTeXName(endo_ids[id]) << "'};"
|
|
|
|
<< endl
|
|
|
|
<< "M_.endo_names_long(" << id + 1 << ") = {'" << getLongName(endo_ids[id]) << "'};"
|
|
|
|
<< endl;
|
2016-06-24 17:38:54 +02:00
|
|
|
output << "M_.endo_partitions = struct();" << endl;
|
2023-11-30 15:28:57 +01:00
|
|
|
for (auto& partition : getPartitionsForType(SymbolType::endogenous))
|
2019-12-16 19:42:59 +01:00
|
|
|
if (partition.first != "long_name")
|
2016-06-24 17:38:54 +02:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
output << "M_.endo_partitions." << partition.first << " = { ";
|
2016-06-24 17:38:54 +02:00
|
|
|
for (int id = 0; id < endo_nbr(); id++)
|
|
|
|
{
|
|
|
|
output << "'";
|
2023-11-30 15:28:57 +01:00
|
|
|
if (auto it1 = partition.second.find(endo_ids[id]); it1 != partition.second.end())
|
2016-06-24 17:38:54 +02:00
|
|
|
output << it1->second;
|
|
|
|
output << "' ";
|
|
|
|
}
|
2017-06-01 19:58:32 +02:00
|
|
|
output << "};" << endl;
|
2016-06-24 17:38:54 +02:00
|
|
|
}
|
2008-02-03 11:28:36 +01:00
|
|
|
}
|
2016-02-26 16:23:39 +01:00
|
|
|
|
2009-02-27 13:19:25 +01:00
|
|
|
if (param_nbr() > 0)
|
2008-02-03 11:28:36 +01:00
|
|
|
{
|
2017-10-10 10:05:59 +02:00
|
|
|
output << "M_.param_names = cell(" << param_nbr() << ",1);" << endl;
|
|
|
|
output << "M_.param_names_tex = cell(" << param_nbr() << ",1);" << endl;
|
|
|
|
output << "M_.param_names_long = cell(" << param_nbr() << ",1);" << endl;
|
|
|
|
for (int id = 0; id < param_nbr(); id++)
|
2008-02-03 11:28:36 +01:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
output << "M_.param_names(" << id + 1 << ") = {'" << getName(param_ids[id]) << "'};"
|
|
|
|
<< endl
|
|
|
|
<< "M_.param_names_tex(" << id + 1 << ") = {'" << getTeXName(param_ids[id])
|
|
|
|
<< "'};" << endl
|
|
|
|
<< "M_.param_names_long(" << id + 1 << ") = {'" << getLongName(param_ids[id])
|
|
|
|
<< "'};" << endl;
|
2010-06-21 18:40:36 +02:00
|
|
|
if (getName(param_ids[id]) == "dsge_prior_weight")
|
|
|
|
output << "options_.dsge_var = 1;" << endl;
|
2016-06-23 15:59:35 +02:00
|
|
|
}
|
2016-06-24 17:38:54 +02:00
|
|
|
output << "M_.param_partitions = struct();" << endl;
|
2023-11-30 15:28:57 +01:00
|
|
|
for (auto& partition : getPartitionsForType(SymbolType::parameter))
|
2019-12-16 19:42:59 +01:00
|
|
|
if (partition.first != "long_name")
|
2016-06-24 17:38:54 +02:00
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
output << "M_.param_partitions." << partition.first << " = { ";
|
2016-06-24 17:38:54 +02:00
|
|
|
for (int id = 0; id < param_nbr(); id++)
|
|
|
|
{
|
|
|
|
output << "'";
|
2023-11-30 15:28:57 +01:00
|
|
|
if (auto it1 = partition.second.find(param_ids[id]); it1 != partition.second.end())
|
2016-06-24 17:38:54 +02:00
|
|
|
output << it1->second;
|
|
|
|
output << "' ";
|
|
|
|
}
|
|
|
|
output << "};" << endl;
|
|
|
|
}
|
2008-02-03 11:28:36 +01:00
|
|
|
}
|
2019-04-29 23:26:07 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
output << "M_.param_names = {};" << endl;
|
|
|
|
output << "M_.param_names_tex = {};" << endl;
|
|
|
|
output << "M_.param_names_long = {};" << endl;
|
|
|
|
}
|
2008-02-03 11:28:36 +01:00
|
|
|
|
2009-02-27 13:19:25 +01:00
|
|
|
output << "M_.exo_det_nbr = " << exo_det_nbr() << ";" << endl
|
|
|
|
<< "M_.exo_nbr = " << exo_nbr() << ";" << endl
|
|
|
|
<< "M_.endo_nbr = " << endo_nbr() << ";" << endl
|
|
|
|
<< "M_.param_nbr = " << param_nbr() << ";" << endl;
|
2008-02-03 11:28:36 +01:00
|
|
|
|
2009-09-30 17:10:31 +02:00
|
|
|
// Write the auxiliary variable table
|
2010-04-23 18:36:51 +02:00
|
|
|
output << "M_.orig_endo_nbr = " << orig_endo_nbr() << ";" << endl;
|
Fixes for ticket #57
preprocessor:
* add a field "M_.orig_endo_nbr" containing the nbr of endogenous before adding aux vars
* always provide "M_.aux_vars" (define it to "[]" when there is no aux var)
* rename "M_.aux_vars().orig_endo_index" to "M_.aux_vars().orig_index"
M-files:
* for commands which accept a list of variables (stoch_simul, osr, estimation, dynasave, dynatype, datatomfile), when no variable is given, use only the set of original endogenous (without aux vars) as the default
* when displaying the decision rule, when there is aux vars in the state variables, replace them by their original name (with the right lag)
* in "steady", don't display aux vars
* special exception for ramsey policy: all vars (including aux vars) are displayed, because the system of aux vars from ramsey policy is not compatible with the aux vars from the preprocessor
git-svn-id: https://www.dynare.org/svn/dynare/trunk@3166 ac1d8469-bf42-47a9-8791-bf33cf982152
2009-11-25 11:22:39 +01:00
|
|
|
if (aux_vars.size() == 0)
|
|
|
|
output << "M_.aux_vars = [];" << endl;
|
|
|
|
else
|
2019-04-23 11:07:32 +02:00
|
|
|
for (int i = 0; i < static_cast<int>(aux_vars.size()); i++)
|
Fixes for ticket #57
preprocessor:
* add a field "M_.orig_endo_nbr" containing the nbr of endogenous before adding aux vars
* always provide "M_.aux_vars" (define it to "[]" when there is no aux var)
* rename "M_.aux_vars().orig_endo_index" to "M_.aux_vars().orig_index"
M-files:
* for commands which accept a list of variables (stoch_simul, osr, estimation, dynasave, dynatype, datatomfile), when no variable is given, use only the set of original endogenous (without aux vars) as the default
* when displaying the decision rule, when there is aux vars in the state variables, replace them by their original name (with the right lag)
* in "steady", don't display aux vars
* special exception for ramsey policy: all vars (including aux vars) are displayed, because the system of aux vars from ramsey policy is not compatible with the aux vars from the preprocessor
git-svn-id: https://www.dynare.org/svn/dynare/trunk@3166 ac1d8469-bf42-47a9-8791-bf33cf982152
2009-11-25 11:22:39 +01:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
output << "M_.aux_vars(" << i + 1
|
|
|
|
<< ").endo_index = " << getTypeSpecificID(aux_vars[i].symb_id) + 1 << ";" << endl
|
|
|
|
<< "M_.aux_vars(" << i + 1 << ").type = " << aux_vars[i].get_type_id() << ";"
|
|
|
|
<< endl;
|
2022-07-20 14:32:57 +02:00
|
|
|
switch (aux_vars[i].type)
|
Fixes for ticket #57
preprocessor:
* add a field "M_.orig_endo_nbr" containing the nbr of endogenous before adding aux vars
* always provide "M_.aux_vars" (define it to "[]" when there is no aux var)
* rename "M_.aux_vars().orig_endo_index" to "M_.aux_vars().orig_index"
M-files:
* for commands which accept a list of variables (stoch_simul, osr, estimation, dynasave, dynatype, datatomfile), when no variable is given, use only the set of original endogenous (without aux vars) as the default
* when displaying the decision rule, when there is aux vars in the state variables, replace them by their original name (with the right lag)
* in "steady", don't display aux vars
* special exception for ramsey policy: all vars (including aux vars) are displayed, because the system of aux vars from ramsey policy is not compatible with the aux vars from the preprocessor
git-svn-id: https://www.dynare.org/svn/dynare/trunk@3166 ac1d8469-bf42-47a9-8791-bf33cf982152
2009-11-25 11:22:39 +01:00
|
|
|
{
|
2018-07-17 17:38:26 +02:00
|
|
|
case AuxVarType::endoLead:
|
|
|
|
case AuxVarType::exoLead:
|
2022-01-28 15:36:04 +01:00
|
|
|
case AuxVarType::expectation:
|
|
|
|
case AuxVarType::pacExpectation:
|
|
|
|
case AuxVarType::pacTargetNonstationary:
|
Fixes for ticket #57
preprocessor:
* add a field "M_.orig_endo_nbr" containing the nbr of endogenous before adding aux vars
* always provide "M_.aux_vars" (define it to "[]" when there is no aux var)
* rename "M_.aux_vars().orig_endo_index" to "M_.aux_vars().orig_index"
M-files:
* for commands which accept a list of variables (stoch_simul, osr, estimation, dynasave, dynatype, datatomfile), when no variable is given, use only the set of original endogenous (without aux vars) as the default
* when displaying the decision rule, when there is aux vars in the state variables, replace them by their original name (with the right lag)
* in "steady", don't display aux vars
* special exception for ramsey policy: all vars (including aux vars) are displayed, because the system of aux vars from ramsey policy is not compatible with the aux vars from the preprocessor
git-svn-id: https://www.dynare.org/svn/dynare/trunk@3166 ac1d8469-bf42-47a9-8791-bf33cf982152
2009-11-25 11:22:39 +01:00
|
|
|
break;
|
2018-07-17 17:38:26 +02:00
|
|
|
case AuxVarType::endoLag:
|
|
|
|
case AuxVarType::exoLag:
|
2022-03-30 17:40:01 +02:00
|
|
|
case AuxVarType::logTransform:
|
2022-01-28 15:36:04 +01:00
|
|
|
case AuxVarType::diffLag:
|
|
|
|
case AuxVarType::diffLead:
|
|
|
|
case AuxVarType::diffForward:
|
2023-11-30 15:28:57 +01:00
|
|
|
output << "M_.aux_vars(" << i + 1
|
|
|
|
<< ").orig_index = " << getTypeSpecificID(aux_vars[i].orig_symb_id.value()) + 1
|
|
|
|
<< ";" << endl
|
|
|
|
<< "M_.aux_vars(" << i + 1
|
|
|
|
<< ").orig_lead_lag = " << aux_vars[i].orig_lead_lag.value() << ";" << endl;
|
Fixes for ticket #57
preprocessor:
* add a field "M_.orig_endo_nbr" containing the nbr of endogenous before adding aux vars
* always provide "M_.aux_vars" (define it to "[]" when there is no aux var)
* rename "M_.aux_vars().orig_endo_index" to "M_.aux_vars().orig_index"
M-files:
* for commands which accept a list of variables (stoch_simul, osr, estimation, dynasave, dynatype, datatomfile), when no variable is given, use only the set of original endogenous (without aux vars) as the default
* when displaying the decision rule, when there is aux vars in the state variables, replace them by their original name (with the right lag)
* in "steady", don't display aux vars
* special exception for ramsey policy: all vars (including aux vars) are displayed, because the system of aux vars from ramsey policy is not compatible with the aux vars from the preprocessor
git-svn-id: https://www.dynare.org/svn/dynare/trunk@3166 ac1d8469-bf42-47a9-8791-bf33cf982152
2009-11-25 11:22:39 +01:00
|
|
|
break;
|
2018-07-17 17:38:26 +02:00
|
|
|
case AuxVarType::unaryOp:
|
2023-11-30 15:28:57 +01:00
|
|
|
output << "M_.aux_vars(" << i + 1 << ").unary_op = '" << aux_vars[i].unary_op << "';"
|
|
|
|
<< endl;
|
2022-05-17 23:17:06 +02:00
|
|
|
[[fallthrough]];
|
2022-01-28 15:36:04 +01:00
|
|
|
case AuxVarType::diff:
|
2022-07-20 14:32:57 +02:00
|
|
|
if (aux_vars[i].orig_symb_id)
|
2023-11-30 15:28:57 +01:00
|
|
|
output << "M_.aux_vars(" << i + 1
|
|
|
|
<< ").orig_index = " << getTypeSpecificID(*aux_vars[i].orig_symb_id) + 1 << ";"
|
|
|
|
<< endl
|
|
|
|
<< "M_.aux_vars(" << i + 1
|
|
|
|
<< ").orig_lead_lag = " << aux_vars[i].orig_lead_lag.value() << ";" << endl;
|
2018-06-07 12:53:00 +02:00
|
|
|
break;
|
2018-07-17 17:38:26 +02:00
|
|
|
case AuxVarType::multiplier:
|
2023-11-30 15:28:57 +01:00
|
|
|
output << "M_.aux_vars(" << i + 1
|
|
|
|
<< ").eq_nbr = " << aux_vars[i].equation_number_for_multiplier + 1 << ";"
|
|
|
|
<< endl;
|
2011-03-21 18:40:57 +01:00
|
|
|
break;
|
Fixes for ticket #57
preprocessor:
* add a field "M_.orig_endo_nbr" containing the nbr of endogenous before adding aux vars
* always provide "M_.aux_vars" (define it to "[]" when there is no aux var)
* rename "M_.aux_vars().orig_endo_index" to "M_.aux_vars().orig_index"
M-files:
* for commands which accept a list of variables (stoch_simul, osr, estimation, dynasave, dynatype, datatomfile), when no variable is given, use only the set of original endogenous (without aux vars) as the default
* when displaying the decision rule, when there is aux vars in the state variables, replace them by their original name (with the right lag)
* in "steady", don't display aux vars
* special exception for ramsey policy: all vars (including aux vars) are displayed, because the system of aux vars from ramsey policy is not compatible with the aux vars from the preprocessor
git-svn-id: https://www.dynare.org/svn/dynare/trunk@3166 ac1d8469-bf42-47a9-8791-bf33cf982152
2009-11-25 11:22:39 +01:00
|
|
|
}
|
2019-12-19 16:58:26 +01:00
|
|
|
|
2023-11-30 15:28:57 +01:00
|
|
|
if (expr_t orig_expr = aux_vars[i].expr_node; orig_expr)
|
2019-12-19 16:58:26 +01:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
output << "M_.aux_vars(" << i + 1 << ").orig_expr = '";
|
2019-12-19 16:58:26 +01:00
|
|
|
orig_expr->writeJsonOutput(output, {}, {});
|
|
|
|
output << "';" << endl;
|
|
|
|
}
|
Fixes for ticket #57
preprocessor:
* add a field "M_.orig_endo_nbr" containing the nbr of endogenous before adding aux vars
* always provide "M_.aux_vars" (define it to "[]" when there is no aux var)
* rename "M_.aux_vars().orig_endo_index" to "M_.aux_vars().orig_index"
M-files:
* for commands which accept a list of variables (stoch_simul, osr, estimation, dynasave, dynatype, datatomfile), when no variable is given, use only the set of original endogenous (without aux vars) as the default
* when displaying the decision rule, when there is aux vars in the state variables, replace them by their original name (with the right lag)
* in "steady", don't display aux vars
* special exception for ramsey policy: all vars (including aux vars) are displayed, because the system of aux vars from ramsey policy is not compatible with the aux vars from the preprocessor
git-svn-id: https://www.dynare.org/svn/dynare/trunk@3166 ac1d8469-bf42-47a9-8791-bf33cf982152
2009-11-25 11:22:39 +01:00
|
|
|
}
|
2009-11-09 12:03:18 +01:00
|
|
|
|
|
|
|
if (predeterminedNbr() > 0)
|
|
|
|
{
|
|
|
|
output << "M_.predetermined_variables = [ ";
|
2018-06-04 12:26:16 +02:00
|
|
|
for (int predetermined_variable : predetermined_variables)
|
2023-11-30 15:28:57 +01:00
|
|
|
output << getTypeSpecificID(predetermined_variable) + 1 << " ";
|
2009-11-09 12:03:18 +01:00
|
|
|
output << "];" << endl;
|
|
|
|
}
|
2010-04-14 15:03:41 +02:00
|
|
|
|
|
|
|
if (observedVariablesNbr() > 0)
|
|
|
|
{
|
2017-10-10 10:05:59 +02:00
|
|
|
output << "options_.varobs = cell(" << observedVariablesNbr() << ", 1);" << endl;
|
2023-11-30 15:28:57 +01:00
|
|
|
for (int ic {1}; int it : varobs)
|
2022-06-03 16:24:26 +02:00
|
|
|
output << "options_.varobs(" << ic++ << ") = {'" << getName(it) << "'};" << endl;
|
2015-07-23 18:10:44 +02:00
|
|
|
|
2010-06-11 19:18:16 +02:00
|
|
|
output << "options_.varobs_id = [ ";
|
2018-06-04 12:26:16 +02:00
|
|
|
for (int varob : varobs)
|
2023-11-30 15:28:57 +01:00
|
|
|
output << getTypeSpecificID(varob) + 1 << " ";
|
|
|
|
output << " ];" << endl;
|
2010-04-14 15:03:41 +02:00
|
|
|
}
|
2016-10-13 18:19:38 +02:00
|
|
|
|
|
|
|
if (observedExogenousVariablesNbr() > 0)
|
|
|
|
{
|
|
|
|
output << "options_.varexobs = cell(1);" << endl;
|
2023-11-30 15:28:57 +01:00
|
|
|
for (int ic {1}; int it : varexobs)
|
2022-06-03 16:24:26 +02:00
|
|
|
output << "options_.varexobs(" << ic++ << ") = {'" << getName(it) << "'};" << endl;
|
2016-10-13 18:19:38 +02:00
|
|
|
|
|
|
|
output << "options_.varexobs_id = [ ";
|
2018-06-04 12:26:16 +02:00
|
|
|
for (int varexob : varexobs)
|
2023-11-30 15:28:57 +01:00
|
|
|
output << getTypeSpecificID(varexob) + 1 << " ";
|
|
|
|
output << " ];" << endl;
|
2016-10-13 18:19:38 +02:00
|
|
|
}
|
2009-09-30 17:10:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2018-06-04 12:50:53 +02:00
|
|
|
SymbolTable::addLeadAuxiliaryVarInternal(bool endo, int index, expr_t expr_arg) noexcept(false)
|
2009-09-30 17:10:31 +02:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
string varname {(endo ? "AUX_ENDO_LEAD_" : "AUX_EXO_LEAD_") + to_string(index)};
|
2009-09-30 17:10:31 +02:00
|
|
|
int symb_id;
|
|
|
|
try
|
|
|
|
{
|
2022-06-02 10:50:21 +02:00
|
|
|
symb_id = addSymbol(varname, SymbolType::endogenous);
|
2009-09-30 17:10:31 +02:00
|
|
|
}
|
2023-11-30 15:28:57 +01:00
|
|
|
catch (AlreadyDeclaredException& e)
|
2009-09-30 17:10:31 +02:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
cerr << "ERROR: you should rename your variable called " << varname
|
|
|
|
<< ", this name is internally used by Dynare" << endl;
|
2009-09-30 17:10:31 +02:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
2023-11-30 15:28:57 +01:00
|
|
|
aux_vars.emplace_back(symb_id, (endo ? AuxVarType::endoLead : AuxVarType::exoLead), 0, 0, 0, 0,
|
|
|
|
expr_arg, "");
|
2009-09-30 17:10:31 +02:00
|
|
|
|
|
|
|
return symb_id;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2023-11-30 15:28:57 +01:00
|
|
|
SymbolTable::addLagAuxiliaryVarInternal(bool endo, int orig_symb_id, int orig_lead_lag,
|
|
|
|
expr_t expr_arg) noexcept(false)
|
2009-09-30 17:10:31 +02:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
string varname {(endo ? "AUX_ENDO_LAG_" : "AUX_EXO_LAG_") + to_string(orig_symb_id) + "_"
|
|
|
|
+ to_string(-orig_lead_lag)};
|
2009-09-30 17:10:31 +02:00
|
|
|
int symb_id;
|
|
|
|
try
|
|
|
|
{
|
2022-06-02 10:50:21 +02:00
|
|
|
symb_id = addSymbol(varname, SymbolType::endogenous);
|
2009-09-30 17:10:31 +02:00
|
|
|
}
|
2023-11-30 15:28:57 +01:00
|
|
|
catch (AlreadyDeclaredException& e)
|
2009-09-30 17:10:31 +02:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
cerr << "ERROR: you should rename your variable called " << varname
|
|
|
|
<< ", this name is internally used by Dynare" << endl;
|
2009-09-30 17:10:31 +02:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
2023-11-30 15:28:57 +01:00
|
|
|
aux_vars.emplace_back(symb_id, (endo ? AuxVarType::endoLag : AuxVarType::exoLag), orig_symb_id,
|
|
|
|
orig_lead_lag, 0, 0, expr_arg, "");
|
2009-09-30 17:10:31 +02:00
|
|
|
|
|
|
|
return symb_id;
|
2008-02-03 11:28:36 +01:00
|
|
|
}
|
2009-10-07 16:07:13 +02:00
|
|
|
|
2009-10-07 18:34:42 +02:00
|
|
|
int
|
2018-06-04 12:50:53 +02:00
|
|
|
SymbolTable::addEndoLeadAuxiliaryVar(int index, expr_t expr_arg) noexcept(false)
|
2009-10-07 18:34:42 +02:00
|
|
|
{
|
2016-03-18 14:55:14 +01:00
|
|
|
return addLeadAuxiliaryVarInternal(true, index, expr_arg);
|
2009-10-07 18:34:42 +02:00
|
|
|
}
|
|
|
|
|
2009-10-07 16:07:13 +02:00
|
|
|
int
|
2023-11-30 15:28:57 +01:00
|
|
|
SymbolTable::addEndoLagAuxiliaryVar(int orig_symb_id, int orig_lead_lag,
|
|
|
|
expr_t expr_arg) noexcept(false)
|
2009-10-07 16:07:13 +02:00
|
|
|
{
|
2016-03-18 14:55:14 +01:00
|
|
|
return addLagAuxiliaryVarInternal(true, orig_symb_id, orig_lead_lag, expr_arg);
|
2009-10-07 16:07:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2018-06-04 12:50:53 +02:00
|
|
|
SymbolTable::addExoLeadAuxiliaryVar(int index, expr_t expr_arg) noexcept(false)
|
2009-10-07 16:07:13 +02:00
|
|
|
{
|
2016-03-18 14:55:14 +01:00
|
|
|
return addLeadAuxiliaryVarInternal(false, index, expr_arg);
|
2009-10-07 16:07:13 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
2023-11-30 15:28:57 +01:00
|
|
|
SymbolTable::addExoLagAuxiliaryVar(int orig_symb_id, int orig_lead_lag,
|
|
|
|
expr_t expr_arg) noexcept(false)
|
2009-10-07 16:07:13 +02:00
|
|
|
{
|
2016-03-18 14:55:14 +01:00
|
|
|
return addLagAuxiliaryVarInternal(false, orig_symb_id, orig_lead_lag, expr_arg);
|
2009-10-07 16:07:13 +02:00
|
|
|
}
|
2009-10-29 18:16:10 +01:00
|
|
|
|
|
|
|
int
|
2023-11-30 15:28:57 +01:00
|
|
|
SymbolTable::addExpectationAuxiliaryVar(int information_set, int index,
|
|
|
|
expr_t expr_arg) noexcept(false)
|
2009-10-29 18:16:10 +01:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
string varname {"AUX_EXPECT_"s + (information_set < 0 ? "LAG" : "LEAD") + "_"
|
|
|
|
+ to_string(abs(information_set)) + "_" + to_string(index)};
|
2009-10-29 18:16:10 +01:00
|
|
|
int symb_id;
|
|
|
|
try
|
|
|
|
{
|
2022-06-02 10:50:21 +02:00
|
|
|
symb_id = addSymbol(varname, SymbolType::endogenous);
|
2009-10-29 18:16:10 +01:00
|
|
|
}
|
2023-11-30 15:28:57 +01:00
|
|
|
catch (AlreadyDeclaredException& e)
|
2009-10-29 18:16:10 +01:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
cerr << "ERROR: you should rename your variable called " << varname
|
|
|
|
<< ", this name is internally used by Dynare" << endl;
|
2009-10-29 18:16:10 +01:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
2018-10-15 11:59:15 +02:00
|
|
|
aux_vars.emplace_back(symb_id, AuxVarType::expectation, 0, 0, 0, information_set, expr_arg, "");
|
2011-03-21 18:40:57 +01:00
|
|
|
|
|
|
|
return symb_id;
|
|
|
|
}
|
|
|
|
|
2022-03-30 17:40:01 +02:00
|
|
|
int
|
2023-11-30 15:28:57 +01:00
|
|
|
SymbolTable::addLogTransformAuxiliaryVar(int orig_symb_id, int orig_lead_lag,
|
|
|
|
expr_t expr_arg) noexcept(false)
|
2022-03-30 17:40:01 +02:00
|
|
|
{
|
|
|
|
string varname = "LOG_" + getName(orig_symb_id);
|
|
|
|
int symb_id;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
symb_id = addSymbol(varname, SymbolType::endogenous);
|
|
|
|
}
|
2023-11-30 15:28:57 +01:00
|
|
|
catch (AlreadyDeclaredException& e)
|
2022-03-30 17:40:01 +02:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
cerr << "ERROR: you should rename your variable called " << varname
|
|
|
|
<< ", it conflicts with the auxiliary variable created for representing the log of "
|
|
|
|
<< getName(orig_symb_id) << endl;
|
2022-03-30 17:40:01 +02:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
2023-11-30 15:28:57 +01:00
|
|
|
aux_vars.emplace_back(symb_id, AuxVarType::logTransform, orig_symb_id, orig_lead_lag, 0, 0,
|
|
|
|
expr_arg, "");
|
2022-03-30 17:40:01 +02:00
|
|
|
|
|
|
|
return symb_id;
|
|
|
|
}
|
|
|
|
|
2018-05-15 14:18:42 +02:00
|
|
|
int
|
2023-11-30 15:28:57 +01:00
|
|
|
SymbolTable::addDiffLagAuxiliaryVar(int index, expr_t expr_arg, int orig_symb_id,
|
|
|
|
int orig_lag) noexcept(false)
|
2018-05-15 14:18:42 +02:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
string varname {"AUX_DIFF_LAG_" + to_string(index)};
|
2018-05-15 14:18:42 +02:00
|
|
|
int symb_id;
|
|
|
|
try
|
|
|
|
{
|
2022-06-02 10:50:21 +02:00
|
|
|
symb_id = addSymbol(varname, SymbolType::endogenous);
|
2018-05-15 14:18:42 +02:00
|
|
|
}
|
2023-11-30 15:28:57 +01:00
|
|
|
catch (AlreadyDeclaredException& e)
|
2018-05-15 14:18:42 +02:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
cerr << "ERROR: you should rename your variable called " << varname
|
|
|
|
<< ", this name is internally used by Dynare" << endl;
|
2018-05-15 14:18:42 +02:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
2018-10-15 11:59:15 +02:00
|
|
|
aux_vars.emplace_back(symb_id, AuxVarType::diffLag, orig_symb_id, orig_lag, 0, 0, expr_arg, "");
|
2018-05-15 14:18:42 +02:00
|
|
|
|
|
|
|
return symb_id;
|
|
|
|
}
|
|
|
|
|
2019-02-15 12:52:46 +01:00
|
|
|
int
|
2023-11-30 15:28:57 +01:00
|
|
|
SymbolTable::addDiffLeadAuxiliaryVar(int index, expr_t expr_arg, int orig_symb_id,
|
|
|
|
int orig_lead) noexcept(false)
|
2019-02-15 12:52:46 +01:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
string varname {"AUX_DIFF_LEAD_" + to_string(index)};
|
2019-02-15 12:52:46 +01:00
|
|
|
int symb_id;
|
|
|
|
try
|
|
|
|
{
|
2022-06-02 10:50:21 +02:00
|
|
|
symb_id = addSymbol(varname, SymbolType::endogenous);
|
2019-02-15 12:52:46 +01:00
|
|
|
}
|
2023-11-30 15:28:57 +01:00
|
|
|
catch (AlreadyDeclaredException& e)
|
2019-02-15 12:52:46 +01:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
cerr << "ERROR: you should rename your variable called " << varname
|
|
|
|
<< ", this name is internally used by Dynare" << endl;
|
2019-02-15 12:52:46 +01:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
aux_vars.emplace_back(symb_id, AuxVarType::diffLead, orig_symb_id, orig_lead, 0, 0, expr_arg, "");
|
|
|
|
|
|
|
|
return symb_id;
|
|
|
|
}
|
|
|
|
|
2018-01-30 10:06:56 +01:00
|
|
|
int
|
2023-11-30 15:28:57 +01:00
|
|
|
SymbolTable::addDiffAuxiliaryVar(int index, expr_t expr_arg, optional<int> orig_symb_id,
|
|
|
|
optional<int> orig_lag) noexcept(false)
|
2018-01-30 10:06:56 +01:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
string varname {"AUX_DIFF_" + to_string(index)};
|
2018-01-30 10:06:56 +01:00
|
|
|
int symb_id;
|
|
|
|
try
|
|
|
|
{
|
2022-06-02 10:50:21 +02:00
|
|
|
symb_id = addSymbol(varname, SymbolType::endogenous);
|
2018-01-30 10:06:56 +01:00
|
|
|
}
|
2023-11-30 15:28:57 +01:00
|
|
|
catch (AlreadyDeclaredException& e)
|
2018-01-30 10:06:56 +01:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
cerr << "ERROR: you should rename your variable called " << varname
|
|
|
|
<< ", this name is internally used by Dynare" << endl;
|
2018-01-30 10:06:56 +01:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
2023-11-30 15:28:57 +01:00
|
|
|
aux_vars.emplace_back(symb_id, AuxVarType::diff, move(orig_symb_id), move(orig_lag), 0, 0,
|
|
|
|
expr_arg, "");
|
2018-01-30 10:06:56 +01:00
|
|
|
|
|
|
|
return symb_id;
|
|
|
|
}
|
|
|
|
|
2018-05-30 16:48:08 +02:00
|
|
|
int
|
2023-11-30 15:28:57 +01:00
|
|
|
SymbolTable::addUnaryOpAuxiliaryVar(int index, expr_t expr_arg, string unary_op,
|
|
|
|
optional<int> orig_symb_id,
|
|
|
|
optional<int> orig_lag) noexcept(false)
|
2018-05-30 16:48:08 +02:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
string varname {"AUX_UOP_" + to_string(index)};
|
2018-05-30 16:48:08 +02:00
|
|
|
int symb_id;
|
|
|
|
try
|
|
|
|
{
|
2022-06-02 10:50:21 +02:00
|
|
|
symb_id = addSymbol(varname, SymbolType::endogenous);
|
2018-05-30 16:48:08 +02:00
|
|
|
}
|
2023-11-30 15:28:57 +01:00
|
|
|
catch (AlreadyDeclaredException& e)
|
2018-05-30 16:48:08 +02:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
cerr << "ERROR: you should rename your variable called " << varname
|
|
|
|
<< ", this name is internally used by Dynare" << endl;
|
2018-05-30 16:48:08 +02:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
2023-11-30 15:28:57 +01:00
|
|
|
aux_vars.emplace_back(symb_id, AuxVarType::unaryOp, move(orig_symb_id), move(orig_lag), 0, 0,
|
|
|
|
expr_arg, unary_op);
|
2018-05-30 16:48:08 +02:00
|
|
|
|
|
|
|
return symb_id;
|
|
|
|
}
|
|
|
|
|
2011-03-21 18:40:57 +01:00
|
|
|
int
|
2018-06-04 12:50:53 +02:00
|
|
|
SymbolTable::addMultiplierAuxiliaryVar(int index) noexcept(false)
|
2011-03-21 18:40:57 +01:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
string varname {"MULT_" + to_string(index + 1)};
|
2011-03-21 18:40:57 +01:00
|
|
|
int symb_id;
|
|
|
|
try
|
|
|
|
{
|
2022-06-02 10:50:21 +02:00
|
|
|
symb_id = addSymbol(varname, SymbolType::endogenous);
|
2011-03-21 18:40:57 +01:00
|
|
|
}
|
2023-11-30 15:28:57 +01:00
|
|
|
catch (AlreadyDeclaredException& e)
|
2011-03-21 18:40:57 +01:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
cerr << "ERROR: you should rename your variable called " << varname
|
|
|
|
<< ", this name is internally used by Dynare" << endl;
|
2011-03-21 18:40:57 +01:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2009-10-29 18:16:10 +01:00
|
|
|
|
2018-10-15 11:59:15 +02:00
|
|
|
aux_vars.emplace_back(symb_id, AuxVarType::multiplier, 0, 0, index, 0, nullptr, "");
|
2009-10-29 18:16:10 +01:00
|
|
|
return symb_id;
|
|
|
|
}
|
2009-11-09 12:03:18 +01:00
|
|
|
|
2013-04-25 18:09:31 +02:00
|
|
|
int
|
2023-11-30 15:28:57 +01:00
|
|
|
SymbolTable::addDiffForwardAuxiliaryVar(int orig_symb_id, int orig_lead_lag,
|
|
|
|
expr_t expr_arg) noexcept(false)
|
2013-04-25 18:09:31 +02:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
string varname {"AUX_DIFF_FWRD_" + to_string(orig_symb_id + 1)};
|
2013-04-25 18:09:31 +02:00
|
|
|
int symb_id;
|
|
|
|
try
|
|
|
|
{
|
2022-06-02 10:50:21 +02:00
|
|
|
symb_id = addSymbol(varname, SymbolType::endogenous);
|
2013-04-25 18:09:31 +02:00
|
|
|
}
|
2023-11-30 15:28:57 +01:00
|
|
|
catch (AlreadyDeclaredException& e)
|
2013-04-25 18:09:31 +02:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
cerr << "ERROR: you should rename your variable called " << varname
|
|
|
|
<< ", this name is internally used by Dynare" << endl;
|
2013-04-25 18:09:31 +02:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
2023-11-30 15:28:57 +01:00
|
|
|
aux_vars.emplace_back(symb_id, AuxVarType::diffForward, orig_symb_id, orig_lead_lag, 0, 0,
|
|
|
|
expr_arg, "");
|
2013-04-25 18:09:31 +02:00
|
|
|
return symb_id;
|
|
|
|
}
|
|
|
|
|
2021-11-17 12:15:49 +01:00
|
|
|
int
|
2023-11-30 15:28:57 +01:00
|
|
|
SymbolTable::addPacExpectationAuxiliaryVar(const string& name, expr_t expr_arg)
|
2021-11-17 12:15:49 +01:00
|
|
|
{
|
|
|
|
int symb_id;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
symb_id = addSymbol(name, SymbolType::endogenous);
|
|
|
|
}
|
2023-11-30 15:28:57 +01:00
|
|
|
catch (AlreadyDeclaredException& e)
|
2021-11-17 12:15:49 +01:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
cerr << "ERROR: the variable/parameter '" << name
|
|
|
|
<< "' conflicts with a variable that will be generated for a 'pac_expectation' "
|
|
|
|
"expression. Please rename it."
|
|
|
|
<< endl;
|
2021-11-17 12:15:49 +01:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
aux_vars.emplace_back(symb_id, AuxVarType::pacExpectation, 0, 0, 0, 0, expr_arg, "");
|
|
|
|
return symb_id;
|
|
|
|
}
|
|
|
|
|
2021-10-26 18:06:26 +02:00
|
|
|
int
|
2023-11-30 15:28:57 +01:00
|
|
|
SymbolTable::addPacTargetNonstationaryAuxiliaryVar(const string& name, expr_t expr_arg)
|
2021-10-26 18:06:26 +02:00
|
|
|
{
|
|
|
|
int symb_id;
|
|
|
|
try
|
|
|
|
{
|
|
|
|
symb_id = addSymbol(name, SymbolType::endogenous);
|
|
|
|
}
|
2023-11-30 15:28:57 +01:00
|
|
|
catch (AlreadyDeclaredException& e)
|
2021-10-26 18:06:26 +02:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
cerr << "ERROR: the variable/parameter '" << name
|
|
|
|
<< "' conflicts with a variable that will be generated for a 'pac_target_nonstationary' "
|
|
|
|
"expression. Please rename it."
|
|
|
|
<< endl;
|
2021-10-26 18:06:26 +02:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
|
|
|
|
|
|
|
aux_vars.emplace_back(symb_id, AuxVarType::pacTargetNonstationary, 0, 0, 0, 0, expr_arg, "");
|
|
|
|
return symb_id;
|
|
|
|
}
|
|
|
|
|
2011-02-04 16:25:38 +01:00
|
|
|
int
|
2018-06-04 12:50:53 +02:00
|
|
|
SymbolTable::searchAuxiliaryVars(int orig_symb_id, int orig_lead_lag) const noexcept(false)
|
2010-09-10 11:43:48 +02:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
for (const auto& aux_var : aux_vars)
|
2022-07-20 14:32:57 +02:00
|
|
|
if ((aux_var.type == AuxVarType::endoLag || aux_var.type == AuxVarType::exoLag)
|
|
|
|
&& aux_var.orig_symb_id == orig_symb_id && aux_var.orig_lead_lag == orig_lead_lag)
|
|
|
|
return aux_var.symb_id;
|
2023-11-30 15:28:57 +01:00
|
|
|
throw SearchFailedException {orig_symb_id, orig_lead_lag};
|
2010-09-10 11:43:48 +02:00
|
|
|
}
|
|
|
|
|
2018-02-15 17:06:30 +01:00
|
|
|
int
|
2022-07-20 14:32:57 +02:00
|
|
|
SymbolTable::getOrigSymbIdForAuxVar(int aux_var_symb_id_arg) const noexcept(false)
|
2018-02-15 17:06:30 +01:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
for (const auto& aux_var : aux_vars)
|
|
|
|
if ((aux_var.type == AuxVarType::endoLag || aux_var.type == AuxVarType::exoLag
|
|
|
|
|| aux_var.type == AuxVarType::diff || aux_var.type == AuxVarType::diffLag
|
|
|
|
|| aux_var.type == AuxVarType::diffLead || aux_var.type == AuxVarType::diffForward
|
2022-07-20 14:32:57 +02:00
|
|
|
|| aux_var.type == AuxVarType::unaryOp)
|
|
|
|
&& aux_var.symb_id == aux_var_symb_id_arg)
|
2023-04-11 14:21:17 +02:00
|
|
|
{
|
|
|
|
if (optional<int> r = aux_var.orig_symb_id; r)
|
|
|
|
return *r;
|
|
|
|
else
|
2023-11-30 15:28:57 +01:00
|
|
|
throw UnknownSymbolIDException {
|
|
|
|
aux_var_symb_id_arg}; // Some diff and unaryOp auxvars have orig_symb_id unset
|
2023-04-11 14:21:17 +02:00
|
|
|
}
|
2023-11-30 15:28:57 +01:00
|
|
|
throw UnknownSymbolIDException {aux_var_symb_id_arg};
|
2018-02-15 17:06:30 +01:00
|
|
|
}
|
|
|
|
|
2022-01-27 18:38:25 +01:00
|
|
|
pair<int, int>
|
|
|
|
SymbolTable::unrollDiffLeadLagChain(int symb_id, int lag) const noexcept(false)
|
2018-09-07 10:56:40 +02:00
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
for (const auto& aux_var : aux_vars)
|
2022-07-20 14:32:57 +02:00
|
|
|
if (aux_var.symb_id == symb_id)
|
|
|
|
if (aux_var.type == AuxVarType::diffLag || aux_var.type == AuxVarType::diffLead)
|
2022-01-27 18:38:25 +01:00
|
|
|
{
|
2022-07-20 14:32:57 +02:00
|
|
|
auto [orig_symb_id, orig_lag] = unrollDiffLeadLagChain(aux_var.orig_symb_id.value(), lag);
|
2023-11-30 15:28:57 +01:00
|
|
|
return {orig_symb_id, orig_lag + aux_var.orig_lead_lag.value()};
|
2022-01-27 18:38:25 +01:00
|
|
|
}
|
2023-11-30 15:28:57 +01:00
|
|
|
return {symb_id, lag};
|
2018-09-07 10:56:40 +02:00
|
|
|
}
|
|
|
|
|
2009-11-09 12:03:18 +01:00
|
|
|
void
|
2018-06-04 12:50:53 +02:00
|
|
|
SymbolTable::markPredetermined(int symb_id) noexcept(false)
|
2009-11-09 12:03:18 +01:00
|
|
|
{
|
2017-09-12 14:16:29 +02:00
|
|
|
validateSymbID(symb_id);
|
|
|
|
|
2009-11-09 12:03:18 +01:00
|
|
|
if (frozen)
|
|
|
|
throw FrozenException();
|
|
|
|
|
2018-07-17 18:34:07 +02:00
|
|
|
assert(getType(symb_id) == SymbolType::endogenous);
|
2009-11-09 12:03:18 +01:00
|
|
|
|
|
|
|
predetermined_variables.insert(symb_id);
|
|
|
|
}
|
|
|
|
|
2022-03-30 17:40:01 +02:00
|
|
|
void
|
|
|
|
SymbolTable::markWithLogTransform(int symb_id) noexcept(false)
|
|
|
|
{
|
|
|
|
validateSymbID(symb_id);
|
|
|
|
|
|
|
|
if (frozen)
|
|
|
|
throw FrozenException();
|
|
|
|
|
|
|
|
assert(getType(symb_id) == SymbolType::endogenous);
|
|
|
|
|
|
|
|
with_log_transform.insert(symb_id);
|
|
|
|
}
|
|
|
|
|
2009-11-09 12:03:18 +01:00
|
|
|
bool
|
2018-06-04 12:50:53 +02:00
|
|
|
SymbolTable::isPredetermined(int symb_id) const noexcept(false)
|
2009-11-09 12:03:18 +01:00
|
|
|
{
|
2017-09-12 14:16:29 +02:00
|
|
|
validateSymbID(symb_id);
|
2022-05-04 16:01:34 +02:00
|
|
|
return predetermined_variables.contains(symb_id);
|
2009-11-09 12:03:18 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
SymbolTable::predeterminedNbr() const
|
|
|
|
{
|
2022-05-04 14:42:03 +02:00
|
|
|
return predetermined_variables.size();
|
2009-11-09 12:03:18 +01:00
|
|
|
}
|
2010-04-14 15:03:41 +02:00
|
|
|
|
|
|
|
void
|
2018-06-04 12:50:53 +02:00
|
|
|
SymbolTable::addObservedVariable(int symb_id) noexcept(false)
|
2010-04-14 15:03:41 +02:00
|
|
|
{
|
2017-09-12 14:16:29 +02:00
|
|
|
validateSymbID(symb_id);
|
2018-07-17 18:34:07 +02:00
|
|
|
assert(getType(symb_id) == SymbolType::endogenous);
|
2010-04-14 15:03:41 +02:00
|
|
|
varobs.push_back(symb_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
SymbolTable::observedVariablesNbr() const
|
|
|
|
{
|
2019-04-23 11:07:32 +02:00
|
|
|
return static_cast<int>(varobs.size());
|
2010-04-14 15:03:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
SymbolTable::isObservedVariable(int symb_id) const
|
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
return find(varobs.begin(), varobs.end(), symb_id) != varobs.end();
|
2010-04-14 15:03:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
SymbolTable::getObservedVariableIndex(int symb_id) const
|
|
|
|
{
|
2018-06-04 15:03:26 +02:00
|
|
|
auto it = find(varobs.begin(), varobs.end(), symb_id);
|
2010-04-14 15:03:41 +02:00
|
|
|
assert(it != varobs.end());
|
2019-04-23 11:07:32 +02:00
|
|
|
return static_cast<int>(it - varobs.begin());
|
2010-04-14 15:03:41 +02:00
|
|
|
}
|
2010-10-15 19:05:16 +02:00
|
|
|
|
2016-10-13 18:19:38 +02:00
|
|
|
void
|
2018-06-04 12:50:53 +02:00
|
|
|
SymbolTable::addObservedExogenousVariable(int symb_id) noexcept(false)
|
2016-10-13 18:19:38 +02:00
|
|
|
{
|
2017-09-13 18:34:02 +02:00
|
|
|
validateSymbID(symb_id);
|
2018-07-17 18:34:07 +02:00
|
|
|
assert(getType(symb_id) != SymbolType::endogenous);
|
2016-10-13 18:19:38 +02:00
|
|
|
varexobs.push_back(symb_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
SymbolTable::observedExogenousVariablesNbr() const
|
|
|
|
{
|
2019-04-23 11:07:32 +02:00
|
|
|
return static_cast<int>(varexobs.size());
|
2016-10-13 18:19:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
SymbolTable::isObservedExogenousVariable(int symb_id) const
|
|
|
|
{
|
2019-12-16 19:42:59 +01:00
|
|
|
return find(varexobs.begin(), varexobs.end(), symb_id) != varexobs.end();
|
2016-10-13 18:19:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
SymbolTable::getObservedExogenousVariableIndex(int symb_id) const
|
|
|
|
{
|
2018-06-04 15:03:26 +02:00
|
|
|
auto it = find(varexobs.begin(), varexobs.end(), symb_id);
|
2016-10-13 18:19:38 +02:00
|
|
|
assert(it != varexobs.end());
|
2019-04-23 11:07:32 +02:00
|
|
|
return static_cast<int>(it - varexobs.begin());
|
2016-10-13 18:19:38 +02:00
|
|
|
}
|
|
|
|
|
2023-11-30 15:28:57 +01:00
|
|
|
vector<int>
|
2010-10-15 19:05:16 +02:00
|
|
|
SymbolTable::getTrendVarIds() const
|
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
vector<int> trendVars;
|
|
|
|
for (const auto& it : symbol_table)
|
2018-07-17 18:34:07 +02:00
|
|
|
if (getType(it.second) == SymbolType::trend || getType(it.second) == SymbolType::logTrend)
|
2018-06-04 12:26:16 +02:00
|
|
|
trendVars.push_back(it.second);
|
2010-10-15 19:05:16 +02:00
|
|
|
return trendVars;
|
|
|
|
}
|
2012-10-31 15:23:02 +01:00
|
|
|
|
|
|
|
set<int>
|
|
|
|
SymbolTable::getExogenous() const
|
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
set<int> exogs;
|
|
|
|
for (const auto& it : symbol_table)
|
2018-07-17 18:34:07 +02:00
|
|
|
if (getType(it.second) == SymbolType::exogenous)
|
2018-06-04 12:26:16 +02:00
|
|
|
exogs.insert(it.second);
|
2012-10-31 15:23:02 +01:00
|
|
|
return exogs;
|
|
|
|
}
|
|
|
|
|
2016-10-14 16:35:15 +02:00
|
|
|
set<int>
|
|
|
|
SymbolTable::getObservedExogenous() const
|
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
set<int> oexogs;
|
|
|
|
for (const auto& it : symbol_table)
|
2018-07-17 18:34:07 +02:00
|
|
|
if (getType(it.second) == SymbolType::exogenous)
|
2018-06-04 12:26:16 +02:00
|
|
|
if (isObservedExogenousVariable(it.second))
|
|
|
|
oexogs.insert(it.second);
|
2016-10-14 16:35:15 +02:00
|
|
|
return oexogs;
|
|
|
|
}
|
|
|
|
|
2012-10-31 15:23:02 +01:00
|
|
|
set<int>
|
|
|
|
SymbolTable::getEndogenous() const
|
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
set<int> endogs;
|
|
|
|
for (const auto& it : symbol_table)
|
2018-07-17 18:34:07 +02:00
|
|
|
if (getType(it.second) == SymbolType::endogenous)
|
2018-06-04 12:26:16 +02:00
|
|
|
endogs.insert(it.second);
|
2012-10-31 15:23:02 +01:00
|
|
|
return endogs;
|
|
|
|
}
|
2014-02-24 17:27:19 +01:00
|
|
|
|
|
|
|
bool
|
|
|
|
SymbolTable::isAuxiliaryVariable(int symb_id) const
|
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
return any_of(aux_vars.begin(), aux_vars.end(),
|
|
|
|
[=](const auto& av) { return av.symb_id == symb_id; });
|
2014-02-24 17:27:19 +01:00
|
|
|
}
|
|
|
|
|
2019-03-15 14:06:02 +01:00
|
|
|
bool
|
|
|
|
SymbolTable::isDiffAuxiliaryVariable(int symb_id) const
|
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
return any_of(aux_vars.begin(), aux_vars.end(), [=](const auto& av) {
|
|
|
|
return av.symb_id == symb_id
|
|
|
|
&& (av.type == AuxVarType::diff || av.type == AuxVarType::diffLag
|
|
|
|
|| av.type == AuxVarType::diffLead);
|
|
|
|
});
|
2019-03-15 14:06:02 +01:00
|
|
|
}
|
|
|
|
|
2014-02-24 17:27:19 +01:00
|
|
|
set<int>
|
|
|
|
SymbolTable::getOrigEndogenous() const
|
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
set<int> origendogs;
|
|
|
|
for (const auto& it : symbol_table)
|
2018-07-17 18:34:07 +02:00
|
|
|
if (getType(it.second) == SymbolType::endogenous && !isAuxiliaryVariable(it.second))
|
2018-06-04 12:26:16 +02:00
|
|
|
origendogs.insert(it.second);
|
2014-02-24 17:27:19 +01:00
|
|
|
return origendogs;
|
|
|
|
}
|
2015-07-21 17:47:56 +02:00
|
|
|
|
2017-02-02 15:09:43 +01:00
|
|
|
void
|
2023-11-30 15:28:57 +01:00
|
|
|
SymbolTable::writeJsonOutput(ostream& output) const
|
2017-02-27 15:40:34 +01:00
|
|
|
{
|
2019-04-03 16:32:52 +02:00
|
|
|
output << R"("endogenous": )";
|
2017-02-27 15:40:34 +01:00
|
|
|
writeJsonVarVector(output, endo_ids);
|
2017-02-02 15:09:43 +01:00
|
|
|
|
2019-04-03 16:32:52 +02:00
|
|
|
output << R"(, "exogenous":)";
|
2017-02-27 15:40:34 +01:00
|
|
|
writeJsonVarVector(output, exo_ids);
|
2017-02-02 15:09:43 +01:00
|
|
|
|
2019-04-03 16:32:52 +02:00
|
|
|
output << R"(, "exogenous_deterministic": )";
|
2017-02-27 15:40:34 +01:00
|
|
|
writeJsonVarVector(output, exo_det_ids);
|
2017-02-02 15:09:43 +01:00
|
|
|
|
2019-04-03 16:32:52 +02:00
|
|
|
output << R"(, "parameters": )";
|
2017-02-27 15:40:34 +01:00
|
|
|
writeJsonVarVector(output, param_ids);
|
2020-06-29 11:10:35 +02:00
|
|
|
|
|
|
|
if (observedVariablesNbr() > 0)
|
|
|
|
{
|
|
|
|
output << R"(, "varobs": [)";
|
|
|
|
for (size_t i = 0; i < varobs.size(); i++)
|
2023-11-30 15:28:57 +01:00
|
|
|
{
|
|
|
|
if (i != 0)
|
|
|
|
output << ", ";
|
|
|
|
output << R"(")" << getName(varobs[i]) << R"(")";
|
|
|
|
}
|
2020-06-29 11:10:35 +02:00
|
|
|
output << "]" << endl;
|
2023-11-30 15:28:57 +01:00
|
|
|
|
2020-06-29 11:10:35 +02:00
|
|
|
output << R"(, "varobs_ids": [)";
|
|
|
|
for (size_t i = 0; i < varobs.size(); i++)
|
2023-11-30 15:28:57 +01:00
|
|
|
{
|
|
|
|
if (i != 0)
|
|
|
|
output << ", ";
|
|
|
|
output << getTypeSpecificID(varobs[i]) + 1;
|
|
|
|
}
|
2020-06-29 11:10:35 +02:00
|
|
|
output << "]" << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (observedExogenousVariablesNbr() > 0)
|
|
|
|
{
|
|
|
|
output << R"(, "varexobs": [)";
|
|
|
|
for (size_t i = 0; i < varexobs.size(); i++)
|
2023-11-30 15:28:57 +01:00
|
|
|
{
|
|
|
|
if (i != 0)
|
|
|
|
output << ", ";
|
|
|
|
output << R"(")" << getName(varexobs[i]) << R"(")";
|
|
|
|
}
|
2020-06-29 11:10:35 +02:00
|
|
|
output << "]" << endl;
|
2023-11-30 15:28:57 +01:00
|
|
|
|
2020-06-29 11:10:35 +02:00
|
|
|
output << R"(, "varexobs_ids": [)";
|
|
|
|
for (size_t i = 0; i < varexobs.size(); i++)
|
2023-11-30 15:28:57 +01:00
|
|
|
{
|
|
|
|
if (i != 0)
|
|
|
|
output << ", ";
|
|
|
|
output << getTypeSpecificID(varexobs[i]) + 1;
|
|
|
|
}
|
2020-06-29 11:10:35 +02:00
|
|
|
output << "]" << endl;
|
|
|
|
}
|
2021-10-08 09:26:49 +02:00
|
|
|
// Write the auxiliary variable table
|
|
|
|
output << R"(, "orig_endo_nbr": )" << orig_endo_nbr() << endl;
|
|
|
|
if (aux_vars.size() == 0)
|
|
|
|
output << R"(, "aux_vars": [])";
|
|
|
|
else
|
|
|
|
{
|
|
|
|
output << R"(, "aux_vars": [)" << endl;
|
|
|
|
for (int i = 0; i < static_cast<int>(aux_vars.size()); i++)
|
2023-11-30 15:28:57 +01:00
|
|
|
{
|
|
|
|
if (i != 0)
|
|
|
|
output << ", ";
|
|
|
|
output << R"({"endo_index": )" << getTypeSpecificID(aux_vars[i].symb_id) + 1
|
|
|
|
<< R"(, "type": )" << aux_vars[i].get_type_id();
|
|
|
|
switch (aux_vars[i].type)
|
|
|
|
{
|
|
|
|
case AuxVarType::endoLead:
|
|
|
|
case AuxVarType::exoLead:
|
|
|
|
case AuxVarType::expectation:
|
|
|
|
case AuxVarType::pacExpectation:
|
2022-01-28 15:36:04 +01:00
|
|
|
case AuxVarType::pacTargetNonstationary:
|
2023-11-30 15:28:57 +01:00
|
|
|
break;
|
|
|
|
case AuxVarType::endoLag:
|
|
|
|
case AuxVarType::exoLag:
|
2022-03-30 17:40:01 +02:00
|
|
|
case AuxVarType::logTransform:
|
2023-11-30 15:28:57 +01:00
|
|
|
case AuxVarType::diffLag:
|
|
|
|
case AuxVarType::diffLead:
|
|
|
|
case AuxVarType::diffForward:
|
|
|
|
output << R"(, "orig_index": )"
|
|
|
|
<< getTypeSpecificID(aux_vars[i].orig_symb_id.value()) + 1
|
|
|
|
<< R"(, "orig_lead_lag": )" << aux_vars[i].orig_lead_lag.value();
|
|
|
|
break;
|
|
|
|
case AuxVarType::unaryOp:
|
2022-07-20 14:32:57 +02:00
|
|
|
output << R"(, "unary_op": ")" << aux_vars[i].unary_op << R"(")";
|
2022-05-17 23:17:06 +02:00
|
|
|
[[fallthrough]];
|
2022-01-28 15:36:04 +01:00
|
|
|
case AuxVarType::diff:
|
2023-11-30 15:28:57 +01:00
|
|
|
if (aux_vars[i].orig_symb_id)
|
|
|
|
output << R"(, "orig_index": )" << getTypeSpecificID(*aux_vars[i].orig_symb_id) + 1
|
|
|
|
<< R"(, "orig_lead_lag": )" << aux_vars[i].orig_lead_lag.value();
|
|
|
|
break;
|
|
|
|
case AuxVarType::multiplier:
|
|
|
|
output << R"(, "eq_nbr": )" << aux_vars[i].equation_number_for_multiplier + 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (expr_t orig_expr = aux_vars[i].expr_node; orig_expr)
|
|
|
|
{
|
|
|
|
output << R"(, "orig_expr": ")";
|
|
|
|
orig_expr->writeJsonOutput(output, {}, {});
|
|
|
|
output << R"(")";
|
|
|
|
}
|
|
|
|
output << '}' << endl;
|
|
|
|
}
|
2021-10-08 09:26:49 +02:00
|
|
|
output << "]" << endl;
|
|
|
|
}
|
2017-02-02 15:09:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2023-11-30 15:28:57 +01:00
|
|
|
SymbolTable::writeJsonVarVector(ostream& output, const vector<int>& varvec) const
|
2017-02-02 15:09:43 +01:00
|
|
|
{
|
|
|
|
output << "[";
|
2017-02-20 12:18:11 +01:00
|
|
|
for (size_t i = 0; i < varvec.size(); i++)
|
2017-02-02 15:09:43 +01:00
|
|
|
{
|
2017-02-27 15:40:34 +01:00
|
|
|
if (i != 0)
|
|
|
|
output << ", ";
|
|
|
|
output << "{"
|
2019-04-03 16:32:52 +02:00
|
|
|
<< R"("name":")" << getName(varvec[i]) << R"(", )"
|
2023-11-30 15:28:57 +01:00
|
|
|
<< R"("texName":")" << boost::replace_all_copy(getTeXName(varvec[i]), R"(\)", R"(\\)")
|
|
|
|
<< R"(", )"
|
|
|
|
<< R"("longName":")"
|
|
|
|
<< boost::replace_all_copy(getLongName(varvec[i]), R"(\)", R"(\\)") << R"("})" << endl;
|
2017-02-02 15:09:43 +01:00
|
|
|
}
|
2017-02-27 15:40:34 +01:00
|
|
|
output << "]" << endl;
|
2017-02-02 15:09:43 +01:00
|
|
|
}
|
2019-03-20 17:54:23 +01:00
|
|
|
|
|
|
|
int
|
|
|
|
SymbolTable::getUltimateOrigSymbID(int symb_id) const
|
|
|
|
{
|
|
|
|
while (isAuxiliaryVariable(symb_id))
|
|
|
|
try
|
|
|
|
{
|
|
|
|
symb_id = getOrigSymbIdForAuxVar(symb_id);
|
|
|
|
}
|
2023-11-30 15:28:57 +01:00
|
|
|
catch (UnknownSymbolIDException&)
|
2019-03-20 17:54:23 +01:00
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return symb_id;
|
|
|
|
}
|
2020-01-06 18:26:35 +01:00
|
|
|
|
2022-05-16 15:23:35 +02:00
|
|
|
optional<int>
|
2020-01-06 18:26:35 +01:00
|
|
|
SymbolTable::getEquationNumberForMultiplier(int symb_id) const
|
|
|
|
{
|
2023-11-30 15:28:57 +01:00
|
|
|
for (const auto& aux_var : aux_vars)
|
2022-07-20 14:32:57 +02:00
|
|
|
if (aux_var.symb_id == symb_id && aux_var.type == AuxVarType::multiplier)
|
|
|
|
return aux_var.equation_number_for_multiplier;
|
2022-05-16 15:23:35 +02:00
|
|
|
return nullopt;
|
2020-01-06 18:26:35 +01:00
|
|
|
}
|
2022-03-30 17:40:01 +02:00
|
|
|
|
2023-11-30 15:28:57 +01:00
|
|
|
const set<int>&
|
2022-03-30 17:40:01 +02:00
|
|
|
SymbolTable::getVariablesWithLogTransform() const
|
|
|
|
{
|
|
|
|
return with_log_transform;
|
|
|
|
}
|
Ramsey: write derivatives of static model w.r.t. Lagrange multipliers in a new file
The computing of the Ramsey steady state relies on the fact that Lagrange
multipliers appear linearly in the system to be solved. Instead of directly
solving for the Lagrange multipliers along with the other variables,
dyn_ramsey_static.m reduces the size of the problem by always computing the
value of the multipliers that minimizes the residuals, given the other
variables (using a minimum norm solution, easy to compute because of the
linearity property). That function thus needs the derivatives of the optimality
FOCs with respect to the multipliers. The problem is that, when multipliers
appear in an auxiliary variable related to a lead/lag, then those derivatives
need to be retrieved by a chain rule derivation, which cannot be easily done
with the regular static file.
This commit implements the creation of a new file,
ramsey_multipliers_static_g1.{m,mex}, that provides exactly the needed
derivatives w.r.t. Lagrange multipliers through chain rule derivation.
Ref. dynare#633, dynare#1119, dynare#1133
2023-03-24 18:58:12 +01:00
|
|
|
|
|
|
|
set<int>
|
|
|
|
SymbolTable::getLagrangeMultipliers() const
|
|
|
|
{
|
|
|
|
set<int> r;
|
2023-11-30 15:28:57 +01:00
|
|
|
for (const auto& aux_var : aux_vars)
|
Ramsey: write derivatives of static model w.r.t. Lagrange multipliers in a new file
The computing of the Ramsey steady state relies on the fact that Lagrange
multipliers appear linearly in the system to be solved. Instead of directly
solving for the Lagrange multipliers along with the other variables,
dyn_ramsey_static.m reduces the size of the problem by always computing the
value of the multipliers that minimizes the residuals, given the other
variables (using a minimum norm solution, easy to compute because of the
linearity property). That function thus needs the derivatives of the optimality
FOCs with respect to the multipliers. The problem is that, when multipliers
appear in an auxiliary variable related to a lead/lag, then those derivatives
need to be retrieved by a chain rule derivation, which cannot be easily done
with the regular static file.
This commit implements the creation of a new file,
ramsey_multipliers_static_g1.{m,mex}, that provides exactly the needed
derivatives w.r.t. Lagrange multipliers through chain rule derivation.
Ref. dynare#633, dynare#1119, dynare#1133
2023-03-24 18:58:12 +01:00
|
|
|
if (aux_var.type == AuxVarType::multiplier)
|
|
|
|
r.insert(aux_var.symb_id);
|
|
|
|
return r;
|
|
|
|
}
|