Commit 6dc87072 authored by sebastien's avatar sebastien
Browse files

trunk preprocessor:

* created a distinct expression tree for the static model (thus giving better sharing of sub-expressions and better computation of temporary terms for the static model)
* for that purpose, created StaticModel and DynamicModel classes (ModelTree still persists, but only contains code shared between StaticModel and DynamicModel)
* removed sparse static file (to be later replaced by new algorithm for steady state computation on large models)


git-svn-id: https://www.dynare.org/svn/dynare/trunk@2592 ac1d8469-bf42-47a9-8791-bf33cf982152
parent 025fb5ae
...@@ -33,22 +33,8 @@ function [x,info] = dynare_solve(func,x,jacobian_flag,varargin) ...@@ -33,22 +33,8 @@ function [x,info] = dynare_solve(func,x,jacobian_flag,varargin)
% You should have received a copy of the GNU General Public License % You should have received a copy of the GNU General Public License
% along with Dynare. If not, see <http://www.gnu.org/licenses/>. % along with Dynare. If not, see <http://www.gnu.org/licenses/>.
global options_ M_ global options_
exist_block_structure=isfield(M_,'block_structure');
%disp(['exist_block_structure = ' int2str(exist_block_structure)]);
if exist_block_structure
%block decomposition is inplemented
[x, info]= feval([M_.fname '_static']);
%size(x)
%info
if info<=0
error('solve_one_boundary has failed in block %d\n',-info/10);
else
info = 0;
end;
return;
end;
options_ = set_default_option(options_,'solve_algo',2); options_ = set_default_option(options_,'solve_algo',2);
info = 0; info = 0;
if options_.solve_algo == 0 if options_.solve_algo == 0
......
...@@ -49,21 +49,6 @@ enum BlockType ...@@ -49,21 +49,6 @@ enum BlockType
SIMULTAN = 3 //<! Simultaneous time unseparable block SIMULTAN = 3 //<! Simultaneous time unseparable block
}; };
/*enum BlockSimulationType
{
UNKNOWN = -1, //!< Unknown simulation type
EVALUATE_FORWARD = 0, //!< Simple evaluation, normalized variable on left-hand side, forward
EVALUATE_BACKWARD = 1, //!< Simple evaluation, normalized variable on left-hand side, backward
SOLVE_FORWARD_SIMPLE = 2, //!< Block of one equation, newton solver needed, forward
SOLVE_BACKWARD_SIMPLE = 3, //!< Block of one equation, newton solver needed, backward
SOLVE_TWO_BOUNDARIES_SIMPLE = 4, //!< Block of one equation, newton solver needed, forward & ackward
SOLVE_FORWARD_COMPLETE = 5, //!< Block of several equations, newton solver needed, forward
SOLVE_BACKWARD_COMPLETE = 6, //!< Block of several equations, newton solver needed, backward
SOLVE_TWO_BOUNDARIES_COMPLETE = 7, //!< Block of several equations, newton solver needed, forward and backwar
EVALUATE_FORWARD_R = 8, //!< Simple evaluation, normalized variable on right-hand side, forward
EVALUATE_BACKWARD_R = 9 //!< Simple evaluation, normalized variable on right-hand side, backward
};
*/
enum BlockSimulationType enum BlockSimulationType
{ {
UNKNOWN, //!< Unknown simulation type UNKNOWN, //!< Unknown simulation type
...@@ -131,4 +116,9 @@ enum BinaryOpcode ...@@ -131,4 +116,9 @@ enum BinaryOpcode
oDifferent oDifferent
}; };
enum TrinaryOpcode
{
oNormcdf
};
#endif #endif
...@@ -38,19 +38,6 @@ SteadyStatement::writeOutput(ostream &output, const string &basename) const ...@@ -38,19 +38,6 @@ SteadyStatement::writeOutput(ostream &output, const string &basename) const
output << "steady;\n"; output << "steady;\n";
} }
SteadySparseStatement::SteadySparseStatement(const OptionsList &options_list_arg) :
options_list(options_list_arg)
{
}
void
SteadySparseStatement::writeOutput(ostream &output, const string &basename) const
{
options_list.writeOutput(output);
//output << basename << "_static;\n";
output << "steady;\n";
}
CheckStatement::CheckStatement(const OptionsList &options_list_arg) : CheckStatement::CheckStatement(const OptionsList &options_list_arg) :
options_list(options_list_arg) options_list(options_list_arg)
{ {
...@@ -914,7 +901,7 @@ ModelComparisonStatement::writeOutput(ostream &output, const string &basename) c ...@@ -914,7 +901,7 @@ ModelComparisonStatement::writeOutput(ostream &output, const string &basename) c
output << "model_comparison(ModelNames_,ModelPriors_,oo_,options_,M_.fname);" << endl; output << "model_comparison(ModelNames_,ModelPriors_,oo_,options_,M_.fname);" << endl;
} }
PlannerObjectiveStatement::PlannerObjectiveStatement(ModelTree *model_tree_arg) : PlannerObjectiveStatement::PlannerObjectiveStatement(StaticModel *model_tree_arg) :
model_tree(model_tree_arg) model_tree(model_tree_arg)
{ {
} }
...@@ -938,7 +925,7 @@ void ...@@ -938,7 +925,7 @@ void
PlannerObjectiveStatement::computingPass() PlannerObjectiveStatement::computingPass()
{ {
model_tree->computeStaticHessian = true; model_tree->computeStaticHessian = true;
model_tree->computingPass(eval_context_type(), false); model_tree->computingPass(false);
} }
void void
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include "SymbolList.hh" #include "SymbolList.hh"
#include "SymbolTable.hh" #include "SymbolTable.hh"
#include "Statement.hh" #include "Statement.hh"
#include "ModelTree.hh" #include "StaticModel.hh"
class SteadyStatement : public Statement class SteadyStatement : public Statement
{ {
...@@ -36,15 +36,6 @@ public: ...@@ -36,15 +36,6 @@ public:
virtual void writeOutput(ostream &output, const string &basename) const; virtual void writeOutput(ostream &output, const string &basename) const;
}; };
class SteadySparseStatement : public Statement
{
private:
const OptionsList options_list;
public:
SteadySparseStatement(const OptionsList &options_list_arg);
virtual void writeOutput(ostream &output, const string &basename) const;
};
class CheckStatement : public Statement class CheckStatement : public Statement
{ {
private: private:
...@@ -409,12 +400,12 @@ public: ...@@ -409,12 +400,12 @@ public:
class PlannerObjectiveStatement : public Statement class PlannerObjectiveStatement : public Statement
{ {
private: private:
ModelTree *model_tree; StaticModel *model_tree;
public: public:
//! Constructor //! Constructor
/*! \param model_tree_arg the model tree used to store the objective function. /*! \param model_tree_arg the model tree used to store the objective function.
It is owned by the PlannerObjectiveStatement, and will be deleted by its destructor */ It is owned by the PlannerObjectiveStatement, and will be deleted by its destructor */
PlannerObjectiveStatement(ModelTree *model_tree_arg); PlannerObjectiveStatement(StaticModel *model_tree_arg);
virtual ~PlannerObjectiveStatement(); virtual ~PlannerObjectiveStatement();
/*! \todo check there are only endogenous variables at the current period in the objective /*! \todo check there are only endogenous variables at the current period in the objective
(no exogenous, no lead/lag) */ (no exogenous, no lead/lag) */
......
...@@ -75,8 +75,8 @@ DataTree::AddPlus(NodeID iArg1, NodeID iArg2) ...@@ -75,8 +75,8 @@ DataTree::AddPlus(NodeID iArg1, NodeID iArg2)
{ {
// Simplify x+(-y) in x-y // Simplify x+(-y) in x-y
UnaryOpNode *uarg2 = dynamic_cast<UnaryOpNode *>(iArg2); UnaryOpNode *uarg2 = dynamic_cast<UnaryOpNode *>(iArg2);
if (uarg2 != NULL && uarg2->op_code == oUminus) if (uarg2 != NULL && uarg2->get_op_code() == oUminus)
return AddMinus(iArg1, uarg2->arg); return AddMinus(iArg1, uarg2->get_arg());
// To treat commutativity of "+" // To treat commutativity of "+"
// Nodes iArg1 and iArg2 are sorted by index // Nodes iArg1 and iArg2 are sorted by index
...@@ -116,8 +116,8 @@ DataTree::AddUMinus(NodeID iArg1) ...@@ -116,8 +116,8 @@ DataTree::AddUMinus(NodeID iArg1)
{ {
// Simplify -(-x) in x // Simplify -(-x) in x
UnaryOpNode *uarg = dynamic_cast<UnaryOpNode *>(iArg1); UnaryOpNode *uarg = dynamic_cast<UnaryOpNode *>(iArg1);
if (uarg != NULL && uarg->op_code == oUminus) if (uarg != NULL && uarg->get_op_code() == oUminus)
return uarg->arg; return uarg->get_arg();
return AddUnaryOp(oUminus, iArg1); return AddUnaryOp(oUminus, iArg1);
} }
......
This diff is collapsed.
/*
* Copyright (C) 2003-2009 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 _DYNAMICMODEL_HH
#define _DYNAMICMODEL_HH
using namespace std;
#include "StaticModel.hh"
#include "BlockTriangular.hh"
//! Stores a dynamic model
class DynamicModel : public ModelTree
{
private:
//! Writes dynamic model file (Matlab version)
void writeDynamicMFile(const string &dynamic_basename) const;
//! Writes dynamic model file (C version)
/*! \todo add third derivatives handling */
void writeDynamicCFile(const string &dynamic_basename) const;
//! Writes dynamic model file when SparseDLL option is on
void writeSparseDynamicMFile(const string &dynamic_basename, const string &basename, const int mode) const;
//! Writes the dynamic model equations and its derivatives
/*! \todo add third derivatives handling in C output */
void writeDynamicModel(ostream &DynamicOutput) const;
//! Writes the Block reordred structure of the model in M output
void writeModelEquationsOrdered_M(Model_Block *ModelBlock, const string &dynamic_basename) const;
//! Writes the code of the Block reordred structure of the model in virtual machine bytecode
void writeModelEquationsCodeOrdered(const string file_name, const Model_Block *ModelBlock, const string bin_basename, ExprNodeOutputType output_type, map_idx_type map_idx) const;
//! Computes jacobian and prepares for equation normalization
/*! Using values from initval/endval blocks and parameter initializations:
- computes the jacobian for the model w.r. to contemporaneous variables
- removes edges of the incidence matrix when derivative w.r. to the corresponding variable is too close to zero (below the cutoff)
*/
void evaluateJacobian(const eval_context_type &eval_context, jacob_map *j_m);
void BlockLinear(Model_Block *ModelBlock);
string reform(string name) const;
map_idx_type map_idx;
//! Build The incidence matrix form the modeltree
void BuildIncidenceMatrix();
void computeTemporaryTermsOrdered(int order, Model_Block *ModelBlock);
//! Write derivative code of an equation w.r. to a variable
void compileDerivative(ofstream &code_file, int eq, int symb_id, int lag, ExprNodeOutputType output_type, map_idx_type &map_idx) const;
public:
DynamicModel(SymbolTable &symbol_table_arg, NumericalConstants &num_constants);
//! Absolute value under which a number is considered to be zero
double cutoff;
//! The weight of the Markowitz criteria to determine the pivot in the linear solver (simul_NG1 from simulate.cc)
double markowitz;
//! the file containing the model and the derivatives code
ofstream code_file;
//! Whether dynamic Jacobian (w.r. to endogenous) should be written
bool computeJacobian;
//! Whether dynamic Jacobian (w.r. to endogenous and exogenous) should be written
bool computeJacobianExo;
//! Whether dynamic Hessian (w.r. to endogenous and exogenous) should be written
bool computeHessian;
//! Whether dynamic third order derivatives (w.r. to endogenous and exogenous) should be written
bool computeThirdDerivatives;
//! Execute computations (variable sorting + derivation)
/*! You must set computeJacobian, computeJacobianExo, computeHessian and computeThirdDerivatives to correct values before calling this function
\param no_tmp_terms if true, no temporary terms will be computed in the dynamic files */
void computingPass(const eval_context_type &eval_context, bool no_tmp_terms);
//! Writes model initialization and lead/lag incidence matrix to output
void writeOutput(ostream &output) const;
//! Complete set to block decompose the model
BlockTriangular block_triangular;
//! Adds informations for simulation in a binary file
void Write_Inf_To_Bin_File(const string &dynamic_basename, const string &bin_basename,
const int &num, int &u_count_int, bool &file_open, bool is_two_boundaries) const;
//! Writes dynamic model file
void writeDynamicFile(const string &basename) const;
//! Converts to static model (only the equations)
/*! It assumes that the static model given in argument has just been allocated */
void toStatic(StaticModel &static_model) const;
};
#endif
...@@ -99,6 +99,7 @@ ExprNode::writeOutput(ostream &output) ...@@ -99,6 +99,7 @@ ExprNode::writeOutput(ostream &output)
writeOutput(output, oMatlabOutsideModel, temporary_terms_type()); writeOutput(output, oMatlabOutsideModel, temporary_terms_type());
} }
NumConstNode::NumConstNode(DataTree &datatree_arg, int id_arg) : NumConstNode::NumConstNode(DataTree &datatree_arg, int id_arg) :
ExprNode(datatree_arg), ExprNode(datatree_arg),
id(id_arg) id(id_arg)
...@@ -115,7 +116,6 @@ NumConstNode::computeDerivative(int varID) ...@@ -115,7 +116,6 @@ NumConstNode::computeDerivative(int varID)
return datatree.Zero; return datatree.Zero;
} }
void void
NumConstNode::collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const NumConstNode::collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const
{ {
...@@ -158,7 +158,6 @@ NumConstNode::compile(ofstream &CompileCode, bool lhs_rhs, ExprNodeOutputType ou ...@@ -158,7 +158,6 @@ NumConstNode::compile(ofstream &CompileCode, bool lhs_rhs, ExprNodeOutputType ou
CompileCode.write(reinterpret_cast<char *>(&vard),sizeof(vard)); CompileCode.write(reinterpret_cast<char *>(&vard),sizeof(vard));
} }
void void
NumConstNode::collectEndogenous(set<pair<int, int> > &result) const NumConstNode::collectEndogenous(set<pair<int, int> > &result) const
{ {
...@@ -169,6 +168,12 @@ NumConstNode::collectExogenous(set<pair<int, int> > &result) const ...@@ -169,6 +168,12 @@ NumConstNode::collectExogenous(set<pair<int, int> > &result) const
{ {
} }
NodeID
NumConstNode::toStatic(DataTree &static_datatree) const
{
return static_datatree.AddNumConstant(datatree.num_constants.get(id));
}
VariableNode::VariableNode(DataTree &datatree_arg, int symb_id_arg, int lag_arg) : VariableNode::VariableNode(DataTree &datatree_arg, int symb_id_arg, int lag_arg) :
ExprNode(datatree_arg), ExprNode(datatree_arg),
...@@ -479,7 +484,6 @@ VariableNode::compile(ofstream &CompileCode, bool lhs_rhs, ExprNodeOutputType ou ...@@ -479,7 +484,6 @@ VariableNode::compile(ofstream &CompileCode, bool lhs_rhs, ExprNodeOutputType ou
} }
} }
void void
VariableNode::computeTemporaryTerms(map<NodeID, int> &reference_count, VariableNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
temporary_terms_type &temporary_terms, temporary_terms_type &temporary_terms,
...@@ -493,9 +497,6 @@ VariableNode::computeTemporaryTerms(map<NodeID, int> &reference_count, ...@@ -493,9 +497,6 @@ VariableNode::computeTemporaryTerms(map<NodeID, int> &reference_count,
datatree.local_variables_table[symb_id]->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx); datatree.local_variables_table[symb_id]->computeTemporaryTerms(reference_count, temporary_terms, first_occurence, Curr_block, ModelBlock, equation, map_idx);
} }
void void
VariableNode::collectEndogenous(set<pair<int, int> > &result) const VariableNode::collectEndogenous(set<pair<int, int> > &result) const
{ {
...@@ -514,6 +515,12 @@ VariableNode::collectExogenous(set<pair<int, int> > &result) const ...@@ -514,6 +515,12 @@ VariableNode::collectExogenous(set<pair<int, int> > &result) const
datatree.local_variables_table[symb_id]->collectExogenous(result); datatree.local_variables_table[symb_id]->collectExogenous(result);
} }
NodeID
VariableNode::toStatic(DataTree &static_datatree) const
{
return static_datatree.AddVariable(datatree.symbol_table.getName(symb_id));
}
UnaryOpNode::UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const NodeID arg_arg) : UnaryOpNode::UnaryOpNode(DataTree &datatree_arg, UnaryOpcode op_code_arg, const NodeID arg_arg) :
ExprNode(datatree_arg), ExprNode(datatree_arg),
...@@ -923,6 +930,49 @@ UnaryOpNode::collectExogenous(set<pair<int, int> > &result) const ...@@ -923,6 +930,49 @@ UnaryOpNode::collectExogenous(set<pair<int, int> > &result) const
arg->collectExogenous(result); arg->collectExogenous(result);
} }
NodeID
UnaryOpNode::toStatic(DataTree &static_datatree) const
{
NodeID sarg = arg->toStatic(static_datatree);
switch(op_code)
{
case oUminus:
return static_datatree.AddUMinus(sarg);
case oExp:
return static_datatree.AddExp(sarg);
case oLog:
return static_datatree.AddLog(sarg);
case oLog10:
return static_datatree.AddLog10(sarg);
case oCos:
return static_datatree.AddCos(sarg);
case oSin:
return static_datatree.AddSin(sarg);
case oTan:
return static_datatree.AddTan(sarg);
case oAcos:
return static_datatree.AddACos(sarg);
case oAsin:
return static_datatree.AddASin(sarg);
case oAtan:
return static_datatree.AddATan(sarg);
case oCosh:
return static_datatree.AddCosH(sarg);
case oSinh:
return static_datatree.AddSinH(sarg);
case oTanh:
return static_datatree.AddTanH(sarg);
case oAcosh:
return static_datatree.AddACosH(sarg);
case oAsinh:
return static_datatree.AddASinH(sarg);
case oAtanh:
return static_datatree.AddATanH(sarg);
case oSqrt:
return static_datatree.AddSqRt(sarg);
}
}
BinaryOpNode::BinaryOpNode(DataTree &datatree_arg, const NodeID arg1_arg, BinaryOpNode::BinaryOpNode(DataTree &datatree_arg, const NodeID arg1_arg,
BinaryOpcode op_code_arg, const NodeID arg2_arg) : BinaryOpcode op_code_arg, const NodeID arg2_arg) :
...@@ -1405,6 +1455,45 @@ BinaryOpNode::collectExogenous(set<pair<int, int> > &result) const ...@@ -1405,6 +1455,45 @@ BinaryOpNode::collectExogenous(set<pair<int, int> > &result) const
arg2->collectExogenous(result); arg2->collectExogenous(result);
} }
NodeID
BinaryOpNode::toStatic(DataTree &static_datatree) const
{
NodeID sarg1 = arg1->toStatic(static_datatree);
NodeID sarg2 = arg2->toStatic(static_datatree);
switch(op_code)
{
case oPlus:
return static_datatree.AddPlus(sarg1, sarg2);
case oMinus:
return static_datatree.AddMinus(sarg1, sarg2);
case oTimes:
return static_datatree.AddTimes(sarg1, sarg2);
case oDivide:
return static_datatree.AddDivide(sarg1, sarg2);
case oPower:
return static_datatree.AddPower(sarg1, sarg2);
case oEqual:
return static_datatree.AddEqual(sarg1, sarg2);
case oMax:
return static_datatree.AddMaX(sarg1, sarg2);
case oMin:
return static_datatree.AddMin(sarg1, sarg2);
case oLess:
return static_datatree.AddLess(sarg1, sarg2);
case oGreater:
return static_datatree.AddGreater(sarg1, sarg2);
case oLessEqual:
return static_datatree.AddLessEqual(sarg1, sarg2);
case oGreaterEqual:
return static_datatree.AddGreaterEqual(sarg1, sarg2);
case oEqualEqual:
return static_datatree.AddEqualEqual(sarg1, sarg2);
case oDifferent:
return static_datatree.AddDifferent(sarg1, sarg2);
}
}
TrinaryOpNode::TrinaryOpNode(DataTree &datatree_arg, const NodeID arg1_arg, TrinaryOpNode::TrinaryOpNode(DataTree &datatree_arg, const NodeID arg1_arg,
TrinaryOpcode op_code_arg, const NodeID arg2_arg, const NodeID arg3_arg) : TrinaryOpcode op_code_arg, const NodeID arg2_arg, const NodeID arg3_arg) :
ExprNode(datatree_arg), ExprNode(datatree_arg),
...@@ -1697,6 +1786,19 @@ TrinaryOpNode::collectExogenous(set<pair<int, int> > &result) const ...@@ -1697,6 +1786,19 @@ TrinaryOpNode::collectExogenous(set<pair<int, int> > &result) const
arg3->collectExogenous(result); arg3->collectExogenous(result);
} }
NodeID
TrinaryOpNode::toStatic(DataTree &static_datatree) const
{
NodeID sarg1 = arg1->toStatic(static_datatree);
NodeID sarg2 = arg2->toStatic(static_datatree);
NodeID sarg3 = arg2->toStatic(static_datatree);
switch(op_code)
{
case oNormcdf:
return static_datatree.AddNormcdf(sarg1, sarg2, sarg3);
}
}
UnknownFunctionNode::UnknownFunctionNode(DataTree &datatree_arg, UnknownFunctionNode::UnknownFunctionNode(DataTree &datatree_arg,
int symb_id_arg, int symb_id_arg,
...@@ -1792,3 +1894,13 @@ UnknownFunctionNode::compile(ofstream &CompileCode, bool lhs_rhs, ExprNodeOutput ...@@ -1792,3 +1894,13 @@ UnknownFunctionNode::compile(ofstream &CompileCode, bool lhs_rhs, ExprNodeOutput
cerr << "UnknownFunctionNode::compile: operation impossible!" << endl; cerr << "UnknownFunctionNode::compile: operation impossible!" << endl;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
NodeID
UnknownFunctionNode::toStatic(DataTree &static_datatree) const
{
vector<NodeID> static_arguments;
for(vector<NodeID>::const_iterator it = arguments.begin();
it != arguments.end(); it++)
static_arguments.push_back((*it)->toStatic(static_datatree));
return static_datatree.AddUnknownFunction(datatree.symbol_table.getName(symb_id), static_arguments);
}
...@@ -86,7 +86,7 @@ typedef map<int, double> eval_context_type; ...@@ -86,7 +86,7 @@ typedef map<int, double> eval_context_type;
class ExprNode class ExprNode
{ {
friend class DataTree; friend class DataTree;
friend class ModelTree; friend class DynamicModel;
friend class ExprNodeLess; friend class ExprNodeLess;
friend class NumConstNode; friend class NumConstNode;
friend class VariableNode; friend class VariableNode;
...@@ -159,6 +159,12 @@ public: ...@@ -159,6 +159,12 @@ public:
virtual double eval(const eval_context_type &eval_context) const throw (EvalException) = 0; virtual double eval(const eval_context_type &eval_context) const throw (EvalException) = 0;
virtual void compile(ofstream &CompileCode, bool lhs_rhs, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const = 0; virtual void compile(ofstream &CompileCode, bool lhs_rhs, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const = 0;
//! Creates a static version of this node
/*!
This method duplicates the current node by creating a similar node from which all leads/lags have been stripped,
adds the result in the static_datatree argument (and not in the original datatree), and returns it.
*/
virtual NodeID toStatic(DataTree &static_datatree) const = 0;
}; };
//! Object used to compare two nodes (using their indexes) //! Object used to compare two nodes (using their indexes)
...@@ -186,6 +192,7 @@ public: ...@@ -186,6 +192,7 @@ public:
virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const; virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const;
virtual double eval(const eval_context_type &eval_context) const throw (EvalException); virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
virtual void compile(ofstream &CompileCode, bool lhs_rhs, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const; virtual void compile(ofstream &CompileCode, bool lhs_rhs, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const;
virtual NodeID toStatic(DataTree &static_datatree) const;
}; };
//! Symbol or variable node //! Symbol or variable node
...@@ -214,12 +221,12 @@ public: ...@@ -214,12 +221,12 @@ public:
virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const; virtual void collectTemporary_terms(const temporary_terms_type &temporary_terms, Model_Block *ModelBlock, int Curr_Block) const;
virtual double eval(const eval_context_type &eval_context) const throw (EvalException); virtual double eval(const eval_context_type &eval_context) const throw (EvalException);
virtual void compile(ofstream &CompileCode, bool lhs_rhs, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const; virtual void compile(ofstream &CompileCode, bool lhs_rhs, ExprNodeOutputType output_type, const temporary_terms_type &temporary_terms, map_idx_type &map_idx) const;
virtual NodeID toStatic(DataTree &static_datatree) const;
}; };
//! Unary operator node //! Unary operator node
class UnaryOpNode : public ExprNode class UnaryOpNode : public ExprNode
{ {
friend class DataTree;