def compile_function(equations, args, parms, max_order, return_function=True): var_order = args sols = [] for eq in equations: ndt = DerivativesTree(eq, ref_var_list=var_order) ndt.compute_nth_order_children(max_order) sols.append(ndt) dyn_subs_dict = dict() for i, v in enumerate(args): dyn_subs_dict[v] = 'x_' + str(i) for i, p in enumerate(parms): dyn_subs_dict[p] = 'p_' + str(i) preamble_l = [ ' x_{i} = x[{i}] # {v}'.format(i=i, v=v) for i, v in enumerate(args) ] preamble_l += [ ' p_{i} = p[{i}] # {p}'.format(i=i, p=p) for i, p in enumerate(parms) ] preamble = str.join('\n', preamble_l) dyn_printer = DicPrinter(dyn_subs_dict) txt = """def dynamic_function(x, p): # # # import numpy as np from numpy import exp, log {preamble} f = [] residual = np.zeros({neq},dtype=np.float64); """ gs = str.join(', ', [('f' + str(i)) for i in range(1, (max_order + 1))]) txt = txt.format(gs=gs, fname='noname', neq=len(equations), preamble=preamble) for i in range(len(sols)): ndt = sols[i] eq = ndt.expr rhs = dyn_printer.doprint_numpy(eq) txt += ' residual[{0}] = {1}\n'.format(i, rhs) txt += ' f.append(residual)\n' for current_order in range(1, (max_order + 1)): if current_order == 1: matrix_name = "Jacobian" elif current_order == 2: matrix_name = "Hessian" else: matrix_name = "{0}_th order".format(current_order) txt += """ # # {matrix_name} matrix # """.format(orderr=current_order + 1, matrix_name=matrix_name) if current_order == 2: txt.format(matrix_name="Hessian") elif current_order == 1: txt.format(matrix_name="Jacobian") #nnzd = self.NNZDerivatives(current_order) n_cols = (len(var_order), ) * current_order n_cols = ','.join([str(s) for s in n_cols]) txt += " f{order} = np.zeros( ({n_eq}, {n_cols}), dtype=np.float64 )\n".format( order=current_order, n_eq=len(equations), n_cols=n_cols) for n in range(len(sols)): ndt = sols[n] l = ndt.list_nth_order_children(current_order) for nd in l: # here we compute indices where we write the derivatives indices = nd.compute_index_set(var_order) rhs = dyn_printer.doprint_numpy(nd.expr) i0 = indices[0] i_col_s = ','.join([str(nn) for nn in i0]) indices.remove(i0) i_col_s_ref = i_col_s txt += ' f{order}[{i_eq},{i_col}] = {value}\n'.format( order=current_order, i_eq=n, i_col=i_col_s, value=rhs) for ind in indices: i += 1 i_col_s = ','.join([str(nn) for nn in ind]) txt += ' f{order}[{i_eq},{i_col}] = f{order}[{i_eq},{i_col_ref}] \n'.format( order=current_order, i_eq=n, i_col=i_col_s, i_col_ref=i_col_s_ref) txt += " f.append(f{order})\n".format(order=current_order) txt += " return f\n" txt = txt.replace('^', '**') if return_function: exec txt dynamic_function.__source__ = txt return dynamic_function else: return txt
def compute_static_mfile(self, max_order=1): print "Computing static .m file at order {0}.".format(max_order) DerivativesTree.symbol_type = Variable model = self.model var_order = model.variables # TODO create a log system sols = [] i = 0 for eq in model.equations: i += 1 l = [tv for tv in eq.atoms() if isinstance(tv, Variable)] expr = eq.gap for tv in l: if tv.lag != 0: expr = expr.subs(tv, tv.P) ndt = DerivativesTree(expr) ndt.compute_nth_order_children(max_order) sols.append(ndt) self.static_derivatives = sols stat_subs_dict = self.static_substitution_list() stat_printer = DicPrinter(stat_subs_dict) txt = """function [residual, {gs}] = {fname}_static(y, x, params, it_) % % Status : Computes static model for Dynare % % Warning : this file is generated automatically by Dynare % from model file (.mod) % % Model equations % residual = zeros({neq}, 1); """ gs = str.join(", ", [("g" + str(i)) for i in range(1, (max_order + 1))]) txt = txt.format(gs=gs, fname=model.fname, neq=len(model.equations)) for i in range(len(sols)): ndt = sols[i] eq = ndt.expr rhs = stat_printer.doprint_matlab(eq) txt += " residual({0}) = {1};\n".format(i + 1, rhs) for current_order in range(1, (max_order + 1)): if current_order == 1: matrix_name = "Jacobian" elif current_order == 2: matrix_name = "Hessian" else: matrix_name = "{0}_th order".format(current_order) txt += """ if nargout >= {orderr} g{order} = zeros({n_rows}, {n_cols}); % % {matrix_name} matrix % \n""".format( order=current_order, orderr=current_order + 1, n_rows=len(model.equations), n_cols=len(var_order) ** current_order, matrix_name=matrix_name, ) if current_order == 2: txt.format(matrix_name="Hessian") # What is the equivalent of NNZ for static files ? nnzd = self.NNZStaticDerivatives(current_order) if True: for n in range(len(sols)): ndt = sols[n] l = ndt.list_nth_order_children(current_order) for nd in l: # here we compute indices where we write the derivatives indices = nd.compute_index_set_matlab(var_order) rhs = stat_printer.doprint_matlab(nd.expr) # rhs = comp.dyn_tabify_expression(nd.expr) i0 = indices[0] indices.remove(i0) txt += " g{order}({0},{1}) = {2};\n".format(n + 1, i0, rhs, order=current_order) for ind in indices: txt += " g{order}({0},{1}) = g{order}({0},{2});\n".format( n + 1, ind, i0, order=current_order ) else: print "to be implemented" txt += """ end """ f = file(model.fname + "_static.m", "w") f.write(txt) f.close() return txt
def compute_dynamic_mfile(self, max_order=2): print "Computing dynamic .m file at order {0}.".format(max_order) DerivativesTree.symbol_type = TSymbol model = self.model var_order = model.dyn_var_order + model.shocks # TODO create a log system t = [] t.append(time.time()) sols = [] i = 0 for eq in model.equations: i += 1 ndt = DerivativesTree(eq.gap) ndt.compute_nth_order_children(max_order) sols.append(ndt) t.append(time.time()) self.dynamic_derivatives = sols dyn_subs_dict = self.dynamic_substitution_list() dyn_printer = DicPrinter(dyn_subs_dict) txt = """function [residual, {gs}] = {fname}_dynamic(y, x, params, it_) % % Status : Computes dynamic model for Dynare % % Warning : this file is generated automatically by Dynare % from model file (.mod) % % Model equations % residual = zeros({neq}, 1); """ gs = str.join(", ", [("g" + str(i)) for i in range(1, (max_order + 1))]) txt = txt.format(gs=gs, fname=model.fname, neq=len(model.equations)) t.append(time.time()) for i in range(len(sols)): ndt = sols[i] eq = ndt.expr rhs = dyn_printer.doprint_matlab(eq) txt += " residual({0}) = {1};\n".format(i + 1, rhs) t.append(time.time()) for current_order in range(1, (max_order + 1)): if current_order == 1: matrix_name = "Jacobian" elif current_order == 2: matrix_name = "Hessian" else: matrix_name = "{0}_th order".format(current_order) txt += """ if nargout >= {orderr} % % {matrix_name} matrix % """.format( orderr=current_order + 1, matrix_name=matrix_name ) if current_order == 2: txt.format(matrix_name="Hessian") elif current_order == 1: txt.format(matrix_name="Jacobian") t.append(time.time()) nnzd = self.NNZDerivatives(current_order) if True: # we write full matrices ... txt += " v{order} = zeros({nnzd}, 3);\n".format(order=current_order, nnzd=nnzd) i = 0 for n in range(len(sols)): ndt = sols[n] l = ndt.list_nth_order_children(current_order) for nd in l: i += 1 # here we compute indices where we write the derivatives indices = nd.compute_index_set_matlab(var_order) rhs = dyn_printer.doprint_matlab(nd.expr) i0 = indices[0] indices.remove(i0) i_ref = i txt += " v{order}({i},:) = [{i_eq}, {i_col}, {value}] ;\n".format( order=current_order, i=i, i_eq=n + 1, i_col=i0, value=rhs ) for ind in indices: i += 1 txt += " v{order}({i},:) = [{i_eq}, {i_col}, v{order}({i_ref},3)];\n".format( order=current_order, i=i, i_eq=n + 1, i_col=ind, i_ref=i_ref ) txt += " g{order} = sparse(v{order}(:,1),v{order}(:,2),v{order}(:,3),{n_rows},{n_cols});\n".format( order=current_order, n_rows=len(model.equations), n_cols=len(var_order) ** current_order ) else: # ... or sparse matrices print "to be implemented" txt += """ end """ t.append(time.time()) f = file(model.fname + "_dynamic.m", "w") f.write(txt) f.close() return txt
def compile_function(equations, args, parms, max_order, return_function=True): var_order = args sols = [] for eq in equations: ndt = DerivativesTree(eq, ref_var_list=var_order) ndt.compute_nth_order_children(max_order) sols.append(ndt) dyn_subs_dict = dict() for i,v in enumerate(args): dyn_subs_dict[v] = 'x_' + str(i) for i,p in enumerate(parms): dyn_subs_dict[p] = 'p_' + str(i) preamble_l = [' x_{i} = x[{i}] # {v}'.format(i=i,v=v) for i,v in enumerate(args)] preamble_l += [' p_{i} = p[{i}] # {p}'.format(i=i,p=p) for i,p in enumerate(parms)] preamble = str.join('\n',preamble_l) dyn_printer = DicPrinter(dyn_subs_dict) txt = """def dynamic_function(x, p): # # # import numpy as np from numpy import exp, log {preamble} f = [] residual = np.zeros({neq},dtype=np.float64); """ gs = str.join(', ',[('f'+str(i)) for i in range(1,(max_order+1))]) txt = txt.format(gs=gs,fname='noname',neq=len(equations), preamble=preamble) for i in range(len(sols)): ndt = sols[i] eq = ndt.expr rhs = dyn_printer.doprint_numpy(eq) txt += ' residual[{0}] = {1}\n'.format(i,rhs ) txt += ' f.append(residual)\n' for current_order in range(1,(max_order+1)): if current_order == 1: matrix_name = "Jacobian" elif current_order == 2: matrix_name = "Hessian" else: matrix_name = "{0}_th order".format(current_order) txt += """ # # {matrix_name} matrix # """.format(orderr=current_order+1,matrix_name=matrix_name) if current_order == 2: txt.format(matrix_name="Hessian") elif current_order == 1: txt.format(matrix_name="Jacobian") #nnzd = self.NNZDerivatives(current_order) n_cols = (len(var_order),)*current_order n_cols = ','.join( [str(s) for s in n_cols] ) txt += " f{order} = np.zeros( ({n_eq}, {n_cols}), dtype=np.float64 )\n".format(order=current_order,n_eq=len(equations), n_cols=n_cols ) for n in range(len(sols)): ndt = sols[n] l = ndt.list_nth_order_children(current_order) for nd in l: # here we compute indices where we write the derivatives indices = nd.compute_index_set(var_order) rhs = dyn_printer.doprint_numpy(nd.expr) i0 = indices[0] i_col_s = ','.join([str(nn) for nn in i0]) indices.remove(i0) i_col_s_ref = i_col_s txt += ' f{order}[{i_eq},{i_col}] = {value}\n'.format(order=current_order,i_eq=n,i_col=i_col_s,value=rhs) for ind in indices: i += 1 i_col_s = ','.join([str(nn) for nn in ind]) txt += ' f{order}[{i_eq},{i_col}] = f{order}[{i_eq},{i_col_ref}] \n'.format(order=current_order,i_eq = n,i_col=i_col_s,i_col_ref = i_col_s_ref) txt += " f.append(f{order})\n".format(order=current_order) txt += " return f\n" txt = txt.replace('^','**') if return_function: exec txt dynamic_function.__source__ = txt return dynamic_function else: return txt
def compute_static_mfile(self, max_order=1): print "Computing static .m file at order {0}.".format(max_order) DerivativesTree.symbol_type = Variable model = self.model var_order = model.variables # TODO create a log system sols = [] i = 0 for eq in model.equations: i += 1 l = [tv for tv in eq.atoms() if isinstance(tv, Variable)] expr = eq.gap for tv in l: if tv.lag != 0: expr = expr.subs(tv, tv.P) ndt = DerivativesTree(expr) ndt.compute_nth_order_children(max_order) sols.append(ndt) self.static_derivatives = sols stat_subs_dict = self.static_substitution_list() stat_printer = DicPrinter(stat_subs_dict) txt = """function [residual, {gs}] = {fname}_static(y, x, params, it_) % % Status : Computes static model for Dynare % % Warning : this file is generated automatically by Dynare % from model file (.mod) % % Model equations % residual = zeros({neq}, 1); """ gs = str.join(', ', [('g' + str(i)) for i in range(1, (max_order + 1))]) txt = txt.format(gs=gs, fname=model.fname, neq=len(model.equations)) for i in range(len(sols)): ndt = sols[i] eq = ndt.expr rhs = stat_printer.doprint_matlab(eq) txt += ' residual({0}) = {1};\n'.format(i + 1, rhs) for current_order in range(1, (max_order + 1)): if current_order == 1: matrix_name = "Jacobian" elif current_order == 2: matrix_name = "Hessian" else: matrix_name = "{0}_th order".format(current_order) txt += """ if nargout >= {orderr} g{order} = zeros({n_rows}, {n_cols}); % % {matrix_name} matrix % \n""".format(order=current_order, orderr=current_order + 1, n_rows=len(model.equations), n_cols=len(var_order)**current_order, matrix_name=matrix_name) if current_order == 2: txt.format(matrix_name="Hessian") # What is the equivalent of NNZ for static files ? nnzd = self.NNZStaticDerivatives(current_order) if True: for n in range(len(sols)): ndt = sols[n] l = ndt.list_nth_order_children(current_order) for nd in l: # here we compute indices where we write the derivatives indices = nd.compute_index_set_matlab(var_order) rhs = stat_printer.doprint_matlab(nd.expr) #rhs = comp.dyn_tabify_expression(nd.expr) i0 = indices[0] indices.remove(i0) txt += ' g{order}({0},{1}) = {2};\n'.format( n + 1, i0, rhs, order=current_order) for ind in indices: txt += ' g{order}({0},{1}) = g{order}({0},{2});\n'.format( n + 1, ind, i0, order=current_order) else: print 'to be implemented' txt += """ end """ f = file(model.fname + '_static.m', 'w') f.write(txt) f.close() return txt
def compute_dynamic_mfile(self, max_order=2): print "Computing dynamic .m file at order {0}.".format(max_order) DerivativesTree.symbol_type = TSymbol model = self.model var_order = model.dyn_var_order + model.shocks # TODO create a log system t = [] t.append(time.time()) sols = [] i = 0 for eq in model.equations: i += 1 ndt = DerivativesTree(eq.gap) ndt.compute_nth_order_children(max_order) sols.append(ndt) t.append(time.time()) self.dynamic_derivatives = sols dyn_subs_dict = self.dynamic_substitution_list() dyn_printer = DicPrinter(dyn_subs_dict) txt = """function [residual, {gs}] = {fname}_dynamic(y, x, params, it_) % % Status : Computes dynamic model for Dynare % % Warning : this file is generated automatically by Dynare % from model file (.mod) % % Model equations % residual = zeros({neq}, 1); """ gs = str.join(', ', [('g' + str(i)) for i in range(1, (max_order + 1))]) txt = txt.format(gs=gs, fname=model.fname, neq=len(model.equations)) t.append(time.time()) for i in range(len(sols)): ndt = sols[i] eq = ndt.expr rhs = dyn_printer.doprint_matlab(eq) txt += ' residual({0}) = {1};\n'.format(i + 1, rhs) t.append(time.time()) for current_order in range(1, (max_order + 1)): if current_order == 1: matrix_name = "Jacobian" elif current_order == 2: matrix_name = "Hessian" else: matrix_name = "{0}_th order".format(current_order) txt += """ if nargout >= {orderr} % % {matrix_name} matrix % """.format(orderr=current_order + 1, matrix_name=matrix_name) if current_order == 2: txt.format(matrix_name="Hessian") elif current_order == 1: txt.format(matrix_name="Jacobian") t.append(time.time()) nnzd = self.NNZDerivatives(current_order) if True: # we write full matrices ... txt += " v{order} = zeros({nnzd}, 3);\n".format( order=current_order, nnzd=nnzd) i = 0 for n in range(len(sols)): ndt = sols[n] l = ndt.list_nth_order_children(current_order) for nd in l: i += 1 # here we compute indices where we write the derivatives indices = nd.compute_index_set_matlab(var_order) rhs = dyn_printer.doprint_matlab(nd.expr) i0 = indices[0] indices.remove(i0) i_ref = i txt += ' v{order}({i},:) = [{i_eq}, {i_col}, {value}] ;\n'.format( order=current_order, i=i, i_eq=n + 1, i_col=i0, value=rhs) for ind in indices: i += 1 txt += ' v{order}({i},:) = [{i_eq}, {i_col}, v{order}({i_ref},3)];\n'.format( order=current_order, i=i, i_eq=n + 1, i_col=ind, i_ref=i_ref) txt += ' g{order} = sparse(v{order}(:,1),v{order}(:,2),v{order}(:,3),{n_rows},{n_cols});\n'.format( order=current_order, n_rows=len(model.equations), n_cols=len(var_order)**current_order) else: # ... or sparse matrices print 'to be implemented' txt += """ end """ t.append(time.time()) f = file(model.fname + '_dynamic.m', 'w') f.write(txt) f.close() return txt