2008-02-03 11:28:36 +01:00
/*
* Copyright ( C ) 2003 - 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/>.
*/
# ifndef _VARIABLETABLE_HH
# define _VARIABLETABLE_HH
using namespace std ;
# include <map>
# include <vector>
# include "SymbolTable.hh"
//! Used to keep track of variables in the sense of the models, i.e. pairs (symbol, lead/lag)
/*! Warning: some methods access variables through the tuple (type, symbol_id, lag), but internally the class uses a lexicographic order over (type, lag, symbol_id) */
class VariableTable
{
private :
//! A reference to the symbol table
const SymbolTable & symbol_table ;
//! A variable is a tuple (type, lag, symbol_id)
2008-08-24 12:54:20 +02:00
/*! Warning: don't change the order of elements in the tuple, since this determines the lexicographic ordering in computeDynJacobianCols() */
2008-10-17 12:20:19 +02:00
typedef pair < pair < SymbolType , int > , int > var_key_type ;
2008-02-03 11:28:36 +01:00
typedef map < var_key_type , int > variable_table_type ;
//! Maps a tuple (type, lag, symbol_id) to a variable ID
variable_table_type variable_table ;
typedef map < int , var_key_type > inv_variable_table_type ;
//! Maps a variable ID to a tuple (type, lag, symbol_id)
inv_variable_table_type inv_variable_table ;
2008-08-24 12:54:20 +02:00
2008-02-03 11:28:36 +01:00
//! Number of dynamic endogenous variables inside the model block
int var_endo_nbr ;
//! Number of dynamic exogenous variables inside the model block
int var_exo_nbr ;
//! Number of dynamic deterministic exogenous variables inside the model block
int var_exo_det_nbr ;
2008-08-24 12:54:20 +02:00
//! Contains the columns indices for the dynamic jacobian (indexed by variable IDs)
vector < int > dyn_jacobian_cols_table ;
public :
VariableTable ( const SymbolTable & symbol_table_arg ) ;
2008-02-03 11:28:36 +01:00
//! Maximum lag over all types of variables (positive value)
int max_lag ;
//! Maximum lead over all types of variables
int max_lead ;
//! Maximum lag over endogenous variables (positive value)
int max_endo_lag ;
//! Maximum lead over endogenous variables
int max_endo_lead ;
//! Maximum lag over exogenous variables (positive value)
int max_exo_lag ;
//! Maximum lead over exogenous variables
int max_exo_lead ;
//! Maximum lag over deterministic exogenous variables (positive value)
int max_exo_det_lag ;
//! Maximum lead over deterministic exogenous variables
int max_exo_det_lead ;
//! Thrown when trying to access an unknown variable by (type, symb_id, lag)
class UnknownVariableKeyException
{
public :
2008-10-17 12:20:19 +02:00
SymbolType type ;
2008-02-03 11:28:36 +01:00
int symb_id , lag ;
2008-10-17 12:20:19 +02:00
UnknownVariableKeyException ( SymbolType type_arg , int symb_id_arg , int lag_arg ) : type ( type_arg ) , symb_id ( symb_id_arg ) , lag ( lag_arg ) { }
2008-02-03 11:28:36 +01:00
} ;
//! Thrown when trying to access an unknown variable by var_id
class UnknownVariableIDException
{
public :
//! Variable ID
int id ;
UnknownVariableIDException ( int id_arg ) : id ( id_arg ) { }
} ;
2008-08-24 12:54:20 +02:00
//! Thrown when getDynJacobianCol() called before computeDynJacobianCols()
class DynJacobianColsNotYetComputedException
2008-02-03 11:28:36 +01:00
{
} ;
2008-08-24 12:54:20 +02:00
//! Thrown when computeDynJacobianCols() or addVariable() called after computeDynJacobianCols()
class DynJacobianColsAlreadyComputedException
2008-02-03 11:28:36 +01:00
{
} ;
//! Adds a variable in the table, and returns its (newly allocated) variable ID
/*! Also works if the variable already exists */
2008-10-17 12:20:19 +02:00
int addVariable ( SymbolType type , int symb_id , int lag ) throw ( DynJacobianColsAlreadyComputedException ) ;
2008-02-03 11:28:36 +01:00
//! Return variable ID
2008-10-17 12:20:19 +02:00
inline int getID ( SymbolType type , int symb_id , int lag ) const throw ( UnknownVariableKeyException ) ;
2008-02-03 11:28:36 +01:00
//! Return lag of variable
inline int getLag ( int var_id ) const throw ( UnknownVariableIDException ) ;
//! Return symbol ID of variable
inline int getSymbolID ( int var_id ) const throw ( UnknownVariableIDException ) ;
//! Get variable type
2008-10-17 12:20:19 +02:00
inline SymbolType getType ( int var_id ) const throw ( UnknownVariableIDException ) ;
2008-02-03 11:28:36 +01:00
//! Get number of variables
inline int size ( ) const ;
2008-08-24 12:54:20 +02:00
//! Get column index in dynamic jacobian
inline int getDynJacobianCol ( int var_id ) const throw ( DynJacobianColsNotYetComputedException , UnknownVariableIDException ) ;
//! Computes column indices in dynamic jacobian
void computeDynJacobianCols ( ) throw ( DynJacobianColsAlreadyComputedException ) ;
//! Get the number of columns of dynamic jacobian (depending on whether we compute derivatives w.r. to exogenous)
inline int getDynJacobianColsNbr ( bool computeJacobianExo ) const ;
2008-02-03 11:28:36 +01:00
} ;
inline int
2008-08-24 12:54:20 +02:00
VariableTable : : getDynJacobianCol ( int var_id ) const throw ( DynJacobianColsNotYetComputedException , UnknownVariableIDException )
2008-02-03 11:28:36 +01:00
{
2008-08-24 12:54:20 +02:00
if ( dyn_jacobian_cols_table . size ( ) = = 0 )
throw DynJacobianColsNotYetComputedException ( ) ;
2008-02-03 11:28:36 +01:00
if ( var_id < 0 | | var_id > = size ( ) )
throw UnknownVariableIDException ( var_id ) ;
2008-08-24 12:54:20 +02:00
return dyn_jacobian_cols_table [ var_id ] ;
2008-02-03 11:28:36 +01:00
}
inline int
2008-10-17 12:20:19 +02:00
VariableTable : : getID ( SymbolType type , int symb_id , int lag ) const throw ( UnknownVariableKeyException )
2008-02-03 11:28:36 +01:00
{
variable_table_type : : const_iterator it = variable_table . find ( make_pair ( make_pair ( type , lag ) , symb_id ) ) ;
if ( it = = variable_table . end ( ) )
throw UnknownVariableKeyException ( type , symb_id , lag ) ;
else
return it - > second ;
}
2008-10-17 12:20:19 +02:00
inline SymbolType
2008-02-03 11:28:36 +01:00
VariableTable : : getType ( int var_id ) const throw ( UnknownVariableIDException )
{
inv_variable_table_type : : const_iterator it = inv_variable_table . find ( var_id ) ;
if ( it ! = inv_variable_table . end ( ) )
return it - > second . first . first ;
else
throw UnknownVariableIDException ( var_id ) ;
}
inline int
VariableTable : : getSymbolID ( int var_id ) const throw ( UnknownVariableIDException )
{
inv_variable_table_type : : const_iterator it = inv_variable_table . find ( var_id ) ;
if ( it ! = inv_variable_table . end ( ) )
return it - > second . second ;
else
throw UnknownVariableIDException ( var_id ) ;
}
inline int
VariableTable : : getLag ( int var_id ) const throw ( UnknownVariableIDException )
{
inv_variable_table_type : : const_iterator it = inv_variable_table . find ( var_id ) ;
if ( it ! = inv_variable_table . end ( ) )
return it - > second . first . second ;
else
throw UnknownVariableIDException ( var_id ) ;
}
inline int
VariableTable : : size ( ) const
{
return variable_table . size ( ) ;
}
inline int
2008-08-24 12:54:20 +02:00
VariableTable : : getDynJacobianColsNbr ( bool computeJacobianExo ) const
2008-02-03 11:28:36 +01:00
{
2008-08-24 12:54:20 +02:00
if ( computeJacobianExo )
return var_endo_nbr + symbol_table . exo_nbr + symbol_table . exo_det_nbr ;
else
return var_endo_nbr ;
2008-02-03 11:28:36 +01:00
}
# endif