def read_model(self): if self.__transformed_model__: return self.__transformed_model__ dmodel = SModel(**self.model) # copy the model dmodel.check_consistency(auto_remove_variables=False) def_eqs = [eq for eq in dmodel.equations if eq.tags['eq_type'] in ('def', 'auxiliary')] from dolo.symbolic.symbolic import map_function_to_expression from dolo.symbolic.symbolic import Variable def timeshift(v,n): if isinstance(v,Variable): return v(n) else: return v import sympy #### build substitution dict def_dict = {} for eq in def_eqs: v = eq.lhs rhs = sympy.sympify( eq.rhs ) def_dict[v] = rhs def_dict[v(1)] = map_function_to_expression( lambda x: timeshift(x,1), rhs) new_equations = [] tbr = [] for i,eq in enumerate(dmodel.equations) : if not ('def' == eq.tags['eq_type']): lhs = sympy.sympify( eq.lhs ).subs(def_dict) rhs = sympy.sympify( eq.rhs ).subs(def_dict) neq = Equation(lhs,rhs).tag(**eq.tags) new_equations.append( neq ) dmodel['equations'] = new_equations dmodel.check_consistency() f_eqs = [eq for eq in dmodel.equations if eq.tags['eq_type'] in ('f','arbitrage')] g_eqs = [eq for eq in dmodel.equations if eq.tags['eq_type'] in ('g','transition')] h_eqs = [eq for eq in dmodel.equations if eq.tags['eq_type'] in ('h','expectation')] states_vars = [eq.lhs for eq in g_eqs] exp_vars = [eq.lhs for eq in h_eqs] controls = set(dmodel.variables) - set(states_vars + exp_vars) controls = list(controls) states_vars = [v for v in dmodel.variables if v in states_vars] exp_vars = [v for v in dmodel.variables if v in exp_vars] controls = [v for v in dmodel.variables if v in controls] # now we remove the left side of equations f_eqs = [eq.gap for eq in f_eqs] g_eqs = [eq.rhs for eq in g_eqs] h_eqs = [eq.rhs for eq in h_eqs] g_eqs = [map_function_to_expression(lambda x: timeshift(x,1),eq) for eq in g_eqs] #h_eqs = [map_function_to_expression(lambda x: timeshift(x,-1),eq) for eq in h_eqs] #no # sub_list[v] = v.name # read complementarity conditions compcond = {} of_eqs = [eq for eq in dmodel.equations if eq.tags['eq_type'] in ('f','arbitrage')] locals = {} import sympy locals['inf'] = sympy.Symbol('inf') locals['log'] = sympy.log # this should be more generic locals['exp'] = sympy.exp for v in dmodel.variables + dmodel.parameters: locals[v.name] = v import re compregex = re.compile('(.*)<=(.*)<=(.*)') for eq in of_eqs: tg = eq.tags['complementarity'] [lhs,mhs,rhs] = compregex.match(tg).groups() [lhs,mhs,rhs] = [dmodel.eval_string(x) for x in [lhs,mhs,rhs] ] compcond[mhs] = (lhs,rhs) complementarities = [compcond[v] for v in controls] inf_bounds = [c[0] for c in complementarities] sup_bounds = [c[1] for c in complementarities] data = { 'f_eqs': f_eqs, 'g_eqs': g_eqs, 'h_eqs': h_eqs, 'controls': controls, 'states_vars': states_vars, 'exp_vars': exp_vars, 'inf_bounds': inf_bounds, 'sup_bounds': sup_bounds } self.__transformed_model__ = data # cache computation return data
def read_model(self): import re import sympy from dolo.symbolic.symbolic import map_function_to_expression from dolo.symbolic.symbolic import Variable if self.__transformed_model__: return self.__transformed_model__ dmodel = SModel(**self.model) # copy the model dmodel.check_consistency(auto_remove_variables=False) def_eqs = [eq for eq in dmodel.equations if eq.tags['eq_type'] in ('def', 'auxiliary')] def timeshift(v,n): if isinstance(v,Variable): return v(n) else: return v # Build substitution dict def_dict = {} for eq in def_eqs: v = eq.lhs rhs = sympy.sympify(eq.rhs) def_dict[v] = rhs def_dict[v(1)] = map_function_to_expression(lambda x: timeshift(x,1), rhs) new_equations = [] tbr = [] for i,eq in enumerate(dmodel.equations) : if not ('def' == eq.tags['eq_type']): lhs = sympy.sympify( eq.lhs ).subs(def_dict) rhs = sympy.sympify( eq.rhs ).subs(def_dict) neq = Equation(lhs,rhs).tag(**eq.tags) new_equations.append(neq) dmodel['equations'] = new_equations dmodel.check_consistency() f_eqs = [eq for eq in dmodel.equations if eq.tags['eq_type'] in ('f','arbitrage','equilibrium')] g_eqs = [eq for eq in dmodel.equations if eq.tags['eq_type'] in ('g','transition')] h_eqs = [eq for eq in dmodel.equations if eq.tags['eq_type'] in ('h','expectation')] hm_eqs = [eq for eq in dmodel.equations if eq.tags['eq_type'] in ('h','expectation_mult')] # Need to understand the need for 'h' e_eqs = [eq for eq in dmodel.equations if eq.tags['eq_type'] in ('e','equation_error')] states_vars = [eq.lhs for eq in g_eqs] exp_vars = [eq.lhs for eq in h_eqs] controls = set(dmodel.variables) - set(states_vars + exp_vars) controls = list(controls) states_vars = [v for v in dmodel.variables if v in states_vars] exp_vars = [v for v in dmodel.variables if v in exp_vars] controls = [v for v in dmodel.variables if v in controls] # Remove the left-hand side of equations f_eqs = [eq.gap for eq in f_eqs] g_eqs = [eq.rhs for eq in g_eqs] h_eqs = [eq.rhs for eq in h_eqs] hm_eqs = [eq.rhs for eq in hm_eqs] e_eqs = [eq.lhs for eq in e_eqs] g_eqs = [map_function_to_expression(lambda x: timeshift(x,1),eq) for eq in g_eqs] #h_eqs = [map_function_to_expression(lambda x: timeshift(x,-1),eq) for eq in h_eqs] #no # sub_list[v] = v.name # Read complementarity conditions compcond = {} of_eqs = [eq for eq in dmodel.equations if eq.tags['eq_type'] in ('f','arbitrage','equilibrium')] locals = {} locals['inf'] = sympy.Symbol('inf') locals['log'] = sympy.log locals['exp'] = sympy.exp for v in dmodel.variables + dmodel.parameters: locals[v.name] = v compregex = re.compile('(.*)<=(.*)<=(.*)') for eq in of_eqs: tg = eq.tags['complementarity'] [lhs,mhs,rhs] = compregex.match(tg).groups() [lhs,mhs,rhs] = [dmodel.eval_string(x) for x in [lhs,mhs,rhs]] compcond[mhs] = (lhs,rhs) complementarities = [compcond[v] for v in controls] inf_bounds = [c[0] for c in complementarities] sup_bounds = [c[1] for c in complementarities] data = {'f_eqs': f_eqs, 'g_eqs': g_eqs, 'h_eqs': h_eqs, 'hm_eqs': hm_eqs, 'e_eqs':e_eqs, 'controls': controls, 'states_vars': states_vars, 'exp_vars': exp_vars, 'inf_bounds': inf_bounds, 'sup_bounds': sup_bounds} self.__transformed_model__ = data # cache computation return data
def process_output(self, solution_order=False, fname=None): from dolo.compiler.compiler_functions import simple_global_representation data = simple_global_representation(self.model, solve_systems=True) # print data['a_eqs'] # print data['f_eqs'] dmodel = self.model model = dmodel f_eqs = data['f_eqs'] g_eqs = data['g_eqs'] g_eqs = [map_function_to_expression(lambda x: timeshift(x,1),eq) for eq in g_eqs] # h_eqs = data['h_eqs'] auxiliaries = data['auxiliaries'] states = data['states'] controls = data['controls'] shocks = dmodel.shocks # exp_vars = data['exp_vars'] #inf_bounds = data['inf_bounds'] #sup_bounds = data['sup_bounds'] controls_f = [v(1) for v in controls] states_f = [v(1) for v in states] shocks_f = [v(1) for v in shocks] sub_list = dict() # for i,v in enumerate(exp_vars): # sub_list[v] = 'z(:,{0})'.format(i+1) for i,v in enumerate(controls): sub_list[v] = 'x(:,{0})'.format(i+1) sub_list[v(1)] = 'xnext(:,{0})'.format(i+1) for i,v in enumerate(states): sub_list[v] = 's(:,{0})'.format(i+1) sub_list[v(1)] = 'snext(:,{0})'.format(i+1) for i,v in enumerate(dmodel.shocks): sub_list[v] = 'e(:,{0})'.format(i+1) sub_list[v(1)] = 'enext(:,{0})'.format(i+1) for i,v in enumerate(dmodel.parameters): sub_list[v] = 'p({0})'.format(i+1) text = '''function [model] = get_model() model = model_info; model.f = @f; model.g = @g; model.a = @a; end function [out1,out2,out3,out4,out5] = f(s,x,snext,xnext,enext,p) n = size(s,1); {eq_fun_block} end function [out1,out2,out3] = g(s,x,e,p) n = size(s,1); {state_trans_block} end function [out1,out2,out3] = a(s,x,p) n = size(s,1); {aux_block} end function [out1] = model_info() % informations about the model {model_info} end ''' from dolo.compiler.common import DicPrinter dp = DicPrinter(sub_list) def write_eqs(eq_l,outname='out1',ntabs=0): eq_block = ' ' * ntabs + '{0} = zeros(n,{1});'.format(outname,len(eq_l)) for i,eq in enumerate(eq_l): eq_block += '\n' + ' ' * ntabs + '{0}(:,{1}) = {2};'.format( outname, i+1, dp.doprint_matlab(eq,vectorize=True) ) return eq_block def write_der_eqs(eq_l,v_l,lhs,ntabs=0): eq_block = ' ' * ntabs + '{lhs} = zeros(n,{0},{1});'.format(len(eq_l),len(v_l),lhs=lhs) eq_l_d = eqdiff(eq_l,v_l) for i,eqq in enumerate(eq_l_d): for j,eq in enumerate(eqq): s = dp.doprint_matlab( eq, vectorize=True ) eq_block += '\n' + ' ' * ntabs + '{lhs}(:,{0},{1}) = {2}; % d eq_{eq_n} w.r.t. {vname}'.format(i+1,j+1,s,lhs=lhs,eq_n=i+1,vname=str(v_l[j]) ) return eq_block # eq_bounds_block = write_eqs(inf_bounds,ntabs=2) # eq_bounds_block += '\n' # eq_bounds_block += write_eqs(sup_bounds,'out2',ntabs=2) eq_f_block = ''' % f {0} if nargout >= 2 % df/ds {1} % df/dx {2} % df/dsnext {3} % df/dxnext {4} end '''.format( write_eqs(f_eqs,'out1',3), write_der_eqs(f_eqs,states,'out2',3), write_der_eqs(f_eqs,controls,'out3',3), write_der_eqs(f_eqs,states_f,'out4',3), write_der_eqs(f_eqs,controls_f,'out5',3), write_der_eqs(f_eqs, shocks_f, 'out6',3) # write_der_eqs(f_eqs,exp_vars,'out4',3) ) eq_g_block = ''' % g {0} if nargout >=2 % dg/ds {1} % dg/dx {2} end '''.format( write_eqs(g_eqs,'out1',3), write_der_eqs(g_eqs,states,'out2',3), write_der_eqs(g_eqs,controls,'out3',3) ) if 'a_eqs' in data: a_eqs = data['a_eqs'] eq_a_block = ''' % a {0} if nargout >=2 % da/ds {1} % da/dx {2} end '''.format( write_eqs(a_eqs,'out1',3), write_der_eqs(a_eqs,states,'out2',3), write_der_eqs(a_eqs,controls,'out3',3) ) else: eq_a_block = '' # if not with_param_names: # eq_h_block = 's=snext;\nx=xnext;\n'+eq_h_block # param_def = 'p = [ ' + str.join(',',[p.name for p in dmodel.parameters]) + '];' from dolo.misc.matlab import value_to_mat # read model informations [y,x,params_values] = model.read_calibration() #params_values = '[' + str.join( ',', [ str( p ) for p in params] ) + '];' vvs = model.variables s_ss = [ y[vvs.index(v)] for v in model['variables_groups']['states'] ] x_ss = [ y[vvs.index(v)] for v in model['variables_groups']['controls'] ] model_info = ''' mod = struct; mod.states = {states}; mod.controls = {controls}; mod.auxiliaries = {auxiliaries}; mod.parameters = {parameters}; mod.shocks = {shocks}; mod.s_ss = {s_ss}; mod.x_ss = {x_ss}; mod.params = {params_values}; '''.format( states = '{{ {} }}'.format(str.join(',', ["'{}'".format(v) for v in states])), controls = '{{ {} }}'.format(str.join(',', ["'{}'".format(v) for v in controls])), auxiliaries = '{{ {} }}'.format(str.join(',', ["'{}'".format(v) for v in auxiliaries])), parameters = '{{ {} }}'.format(str.join(',', ["'{}'".format(v) for v in model.parameters])), shocks = '{{ {} }}'.format(str.join(',', ["'{}'".format(v) for v in model.shocks])), s_ss = value_to_mat(s_ss), x_ss = value_to_mat(x_ss), params_values = value_to_mat(params_values) ) if solution_order: from dolo.numeric.perturbations_to_states import approximate_controls ZZ = approximate_controls(self.model,order=solution_order, return_dr=False) n_c = len(controls) ZZ = [np.array(e) for e in ZZ] ZZ = [e[:n_c,...] for e in ZZ] # keep only control vars. (x) not expectations (h) solution = " mod.X = cell({0},1);\n".format(len(ZZ)) for i,zz in enumerate(ZZ): solution += " mod.X{{{0}}} = {1};\n".format(i+1,value_to_mat(zz.real)) model_info += solution model_info += ' out1 = mod;\n' text = text.format( # eq_bounds_block = eq_bounds_block, mfname = fname if fname else 'mf_' + model.fname, eq_fun_block=eq_f_block, state_trans_block=eq_g_block, aux_block=eq_a_block, # exp_fun_block=eq_h_block, # solution = solution, model_info = model_info ) return text