Skip to content
Snippets Groups Projects
Select Git revision
  • 12b8a915e9d2c29cea2a88528579d2422cceef22
  • master default protected
  • 6.x protected
  • madysson
  • 5.x protected
  • asm
  • time-varying-information-set
  • 4.6 protected
  • dynare_minreal
  • dragonfly
  • various_fixes
  • 4.5 protected
  • clang+openmp
  • exo_steady_state
  • declare_vars_in_model_block
  • julia
  • error_msg_undeclared_model_vars
  • static_aux_vars
  • slice
  • aux_func
  • penalty
  • 6.4 protected
  • 6.3 protected
  • 6.2 protected
  • 6.1 protected
  • 6.0 protected
  • 6-beta2 protected
  • 6-beta1 protected
  • 5.5 protected
  • 5.4 protected
  • 5.3 protected
  • 5.2 protected
  • 5.1 protected
  • 5.0 protected
  • 5.0-rc1 protected
  • 4.7-beta3 protected
  • 4.7-beta2 protected
  • 4.7-beta1 protected
  • 4.6.4 protected
  • 4.6.3 protected
  • 4.6.2 protected
41 results

forw_subst_builder.cpp

Blame
  • forw_subst_builder.cpp 4.19 KiB
    // Copyright (C) 2006-2011, Ondra Kamenik
    
    
    #include "forw_subst_builder.h"
    
    using namespace ogdyn;
    
    ForwSubstBuilder::ForwSubstBuilder(DynareModel& m)
    	: model(m)
    {
    	info.num_new_terms -= model.getParser().getTree().get_num_op();
    
    	// go through all equations
    	int neq = model.eqs.nformulas();
    	for (int i = 0; i < neq; i++) {
    		int ft = model.eqs.formula(i);
    		int mlead, mlag;
    		model.termspan(ft, mlead, mlag);
    		// if equation is too forward looking
    		if (mlead > 1) {
    			info.num_affected_equations++;
    			// break it to non-linear terms
    			unordered_set<int> nlt = model.get_nonlinear_subterms(ft);
    			int j = 0; // indexes subterms
    			// and make substitutions for all these non-linear subterms
    			for (unordered_set<int>::const_iterator it = nlt.begin();
    				 it != nlt.end(); ++it, ++j)
    				substitute_for_term(*it, i, j);
    		}
    	}
    	// unassign all variables with lead greater than 1
    	unassign_gt_1_leads();
    
    	// forget the derivatives in the tree because some variables could
    	// have been unassigned
    	model.eqs.getTree().forget_derivative_maps();
    
    	info.num_new_terms += model.getParser().getTree().get_num_op();
    }
    
    void ForwSubstBuilder::substitute_for_term(int t, int i, int j)
    {
    	int mlead, mlag;
    	model.termspan(t, mlead, mlag);
    	if (mlead > 1) {
    		info.num_subst_terms++;
    		// Example for comments: let t = f(x(+4))
    		// first make lagsubst be substitution setting f(x(+4)) to f(x(+1))
    		// this is lag = -3 (1-mlead)
    		map<int,int> lagsubst;
            unordered_set<int> nult = model.eqs.nulary_of_term(t);// make copy of nult!
    		model.variable_shift_map(nult, 1-mlead, lagsubst);
    		int lagt = model.eqs.add_substitution(t, lagsubst);
    
            // now maxlead of lagt is +1
            // add AUXLD_*_*_1 = f(x(+1)) to the model
            char name[100];
            sprintf(name, "AUXLD_%d_%d_%d", i, j, 1);
            model.atoms.register_uniq_endo(name);
            info.num_aux_variables++;
            const char* ss = model.atoms.get_name_storage().query(name);
            int auxt = model.eqs.add_nulary(name);
            model.eqs.add_formula(model.eqs.add_binary(ogp::MINUS, auxt, lagt));
            aux_map.insert(Tsubstmap::value_type(ss, lagt));
    		// now add variables and equations
    		// AUXLD_*_*_2 = AUXLD_*_*_1(+1) through
    		// AUXLD_*_*_{mlead-1} = AUXLD_*_*_{mlead-2}(+1)
    		for (int ll = 1; ll <= mlead-2; ll++) {
    			// create AUXLD_*_*_{ll}(+1)
    			sprintf(name, "AUXLD_%d_%d_%d(+1)", i, j, ll);
    			int lastauxt_lead = model.eqs.add_nulary(name);
    			// create AUXLD_*_*{ll+1}
    			sprintf(name, "AUXLD_%d_%d_%d", i, j, ll+1);
    			model.atoms.register_uniq_endo(name);
    			info.num_aux_variables++;
    			ss = model.atoms.get_name_storage().query(name);
    			auxt = model.eqs.add_nulary(name);
    			// add AUXLD_*_*_{ll+1} = AUXLD_*_*_{ll}(+1)
    			model.eqs.add_formula(model.eqs.add_binary(ogp::MINUS, auxt, lastauxt_lead));
    			// add substitution to the map; todo: this
    			// works well because in the context where
    			// aux_map is used the timing doesn't matter,
    			// however, it is misleading, needs to be
    			// changed
    			aux_map.insert(Tsubstmap::value_type(ss, lagt));
    		}
    
    		// now we have to substitute AUXLD_*_*{mlead-1}(+1) for t
            sprintf(name, "AUXLD_%d_%d_%d", i, j, mlead-1);
            ss = model.atoms.get_name_storage().query(name);
    		model.substitute_atom_for_term(ss, +1, t);
    	}
    }
    
    void ForwSubstBuilder::unassign_gt_1_leads(const char* name)
    {
    	const char* ss = model.atoms.get_name_storage().query(name);
    	int mlead, mlag;
    	model.atoms.varspan(name, mlead, mlag);
    	for (int ll = 2; ll <= mlead; ll++) {
    		int t = model.atoms.index(ss, ll);
    		if (t != -1)
    			model.atoms.unassign_variable(ss, ll, t);
    	}
    }
    
    void ForwSubstBuilder::unassign_gt_1_leads()
    {
    	const vector<const char*>& endovars = model.atoms.get_endovars();
    	for (unsigned int i = 0; i < endovars.size(); i++)
    		unassign_gt_1_leads(endovars[i]);
    	const vector<const char*>& exovars = model.atoms.get_exovars();
    	for (unsigned int i = 0; i < exovars.size(); i++)
    		unassign_gt_1_leads(exovars[i]);	
    }
    
    ForwSubstBuilder::ForwSubstBuilder(const ForwSubstBuilder& b, DynareModel& m)
    	: model(m)
    {
    	for (Tsubstmap::const_iterator it = b.aux_map.begin();
    		 it != b.aux_map.end(); ++it) {
    		const char* ss = m.atoms.get_name_storage().query((*it).first);
    		aux_map.insert(Tsubstmap::value_type(ss, (*it).second));
    	}
    }