def test_denhaan_errors(self): from dolo.misc.yamlfile import yaml_import from dolo.numeric.global_solve import global_solve model = yaml_import('examples/global_models/rbc.yaml') from dolo.compiler.compiler_global import CModel from dolo.numeric.perturbations_to_states import approximate_controls dr = approximate_controls(model) dr_global = global_solve(model, smolyak_order=4, verbose=False, pert_order=1, method='newton', polish=True) sigma = model.calibration['covariances'] model.sigma = sigma s_0 = dr.S_bar from dolo.numeric.error_measures import denhaanerrors [error_1, error_2] = denhaanerrors(model, dr, s_0) [error_1_glob, error_2_glob] = denhaanerrors(model, dr_global, s_0) print(error_1) print(error_1_glob) assert (max(error_1_glob) < 10 - 7 ) # errors with solyak colocations at order 4 are very small assert (max(error_2_glob) < 10 - 7)
def test_denhaan_errors(self): from dolo.misc.yamlfile import yaml_import from dolo.numeric.global_solve import global_solve model = yaml_import('examples/global_models/rbc.yaml') from dolo.compiler.compiler_global import CModel from dolo.numeric.perturbations_to_states import approximate_controls dr = approximate_controls(model) dr_global = global_solve(model, smolyak_order=4, verbose=False, pert_order=1, method='newton', polish=True) sigma = model.calibration['covariances'] model.sigma = sigma s_0 = dr.S_bar from dolo.numeric.error_measures import denhaanerrors [error_1, error_2] = denhaanerrors(model, dr, s_0) [error_1_glob, error_2_glob] = denhaanerrors(model, dr_global, s_0) print(error_1) print(error_1_glob) assert( max(error_1_glob) < 10-7) # errors with solyak colocations at order 4 are very small assert( max(error_2_glob) < 10-7)
def constant_residuals(x, return_dr=False): d = {} for i in range(n_pfs): p = pf_parms[i] v = pf_vars[i] d[p] = x[i] d[v] = x[i] new_model.set_calibration(d) # new_model.parameters_values[p] = x[i] # new_model.init_values[v] = x[i] if return_dr: dr = approximate_controls(new_model, order=1, return_dr=True) return dr X_bar, X_s, X_ss = approximate_controls(new_model, order=2, return_dr=False) return X_bar[n_controls-n_pfs:n_controls]
def test_perturbation(self): # This solves the optimal growth example at second order # and computes the second order correction to the steady-state # We test that both the statefree method and the perturbation to states # yield the same result. from dolo.misc.yamlfile import yaml_import model = yaml_import('../examples/global_models/optimal_growth.yaml') from dolo.numeric.perturbations_to_states import approximate_controls [Xbar, X_s,X_ss] = approximate_controls(model,2) state_perturb = Xbar from dolo.numeric.perturbations import solve_decision_rule dr = solve_decision_rule(model) statefree_perturb = dr['ys'] + dr['g_ss']/2.0 ctls = model['variables_groups']['controls'] + model['variables_groups']['expectations'] ctls_ind = [model.variables.index(v) for v in ctls] # the two methods should yield exactly the same result from numpy.testing import assert_almost_equal A = statefree_perturb[ctls_ind] B = state_perturb assert_almost_equal(A, B)
def test_omega_errors(self): from dolo.misc.yamlfile import yaml_import from dolo.numeric.global_solve import global_solve model = yaml_import('examples/global_models/rbc.yaml') from dolo.compiler.converter import GModel_fg_from_fga model = GModel_fg_from_fga( model ) from dolo.numeric.perturbations_to_states import approximate_controls dr = approximate_controls(model) dr_global = global_solve(model, smolyak_order=4, verbose=False, pert_order=1, method='newton', polish=True) sigma = model.calibration['covariances'] # cmodel = CModel(model) model.sigma = sigma s_0 = dr.S_bar from dolo.numeric.error_measures import omega res = omega( dr, model, dr_global.bounds, [10,10], time_weight=[50, 0.96,s_0])
def test_perturbation(self): # This solves the optimal growth example at second order # and computes the second order correction to the steady-state # We test that both the statefree method and the perturbation to states # yield the same result. from dolo.misc.yamlfile import yaml_import model = yaml_import('../examples/global_models/optimal_growth.yaml') from dolo.numeric.perturbations_to_states import approximate_controls [Xbar, X_s, X_ss] = approximate_controls(model, 2) state_perturb = Xbar from dolo.numeric.perturbations import solve_decision_rule dr = solve_decision_rule(model) statefree_perturb = dr['ys'] + dr['g_ss'] / 2.0 ctls = model['variables_groups']['controls'] + model[ 'variables_groups']['expectations'] ctls_ind = [model.variables.index(v) for v in ctls] # the two methods should yield exactly the same result from numpy.testing import assert_almost_equal A = statefree_perturb[ctls_ind] B = state_perturb assert_almost_equal(A, B)
def test_second_order_accuracy(self): # This solves the optimal growth example at second order # and computes the second order correction to the steady-state # We test that both the statefree method and the perturbation to states # yield the same result. from dolo.misc.yamlfile import yaml_import model = yaml_import('examples/global_models/rbc.yaml', compiler=None) from dolo.numeric.perturbations import solve_decision_rule from dolo.numeric.perturbations_to_states import approximate_controls coeffs = approximate_controls(model, order=2, return_dr=False) state_perturb = coeffs[0] dr = solve_decision_rule(model) statefree_perturb = dr['ys'] + dr['g_ss'] / 2.0 ctls = model.symbols_s['controls'] ctls_ind = [model.variables.index(v) for v in ctls] # the two methods should yield exactly the same result from numpy.testing import assert_almost_equal A = statefree_perturb[ctls_ind] B = state_perturb assert_almost_equal(A, B) # we compare the risk-adjusted constants
def test_second_order_accuracy(self): # This solves the optimal growth example at second order # and computes the second order correction to the steady-state # We test that both the statefree method and the perturbation to states # yield the same result. from dolo.misc.yamlfile import yaml_import model = yaml_import('examples/global_models/rbc.yaml', compiler=None) from dolo.numeric.perturbations import solve_decision_rule from dolo.numeric.perturbations_to_states import approximate_controls coeffs = approximate_controls(model,order=2, return_dr=False) state_perturb = coeffs[0] dr = solve_decision_rule(model) statefree_perturb = dr['ys'] + dr['g_ss']/2.0 ctls = model.symbols_s['controls'] ctls_ind = [model.variables.index(v) for v in ctls] # the two methods should yield exactly the same result from numpy.testing import assert_almost_equal A = statefree_perturb[ctls_ind] B = state_perturb assert_almost_equal(A, B) # we compare the risk-adjusted constants
def test_omega_errors(self): from dolo.misc.yamlfile import yaml_import from dolo.numeric.global_solve import global_solve model = yaml_import('examples/global_models/rbc.yaml') from dolo.compiler.converter import GModel_fg_from_fga model = GModel_fg_from_fga(model) from dolo.numeric.perturbations_to_states import approximate_controls dr = approximate_controls(model) dr_global = global_solve(model, smolyak_order=4, verbose=False, pert_order=1, method='newton', polish=True) sigma = model.calibration['covariances'] # cmodel = CModel(model) model.sigma = sigma s_0 = dr.S_bar from dolo.numeric.error_measures import omega res = omega(dr, model, dr_global.bounds, [10, 10], time_weight=[50, 0.96, s_0])
def constant_residuals(x): for i in range(n_pfs): p = pf_parms[i] v = pf_vars[i] new_model.parameters_values[p] = x[i] new_model.init_values[v] = x[i] [X_bar, X_s, X_ss] = approximate_controls(new_model, order=2, return_dr=False) return X_bar[n_controls-n_pfs:n_controls]
def constant_residuals(x, return_dr=False): d = {} for i in range(n_pfs): p = pf_parms[i] v = pf_vars[i] d[p] = x[i] d[v] = x[i] new_model.set_calibration(d) # new_model.parameters_values[p] = x[i] # new_model.init_values[v] = x[i] if return_dr: dr = approximate_controls(new_model, order=1, return_dr=True) return dr X_bar, X_s, X_ss = approximate_controls(new_model, order=2, return_dr=False) return X_bar[n_controls - n_pfs:n_controls]
def constant_residuals(x): for i in range(n_pfs): p = pf_parms[i] v = pf_vars[i] model.parameters_values[p] = x[i] model.init_values[v] = x[i] [X_bar, X_s, X_ss] = approximate_controls(new_model, order=2, return_dr=False) return X_bar[n_controls - n_pfs:n_controls]
def solve_model_around_risky_ss(model, verbose=False, return_dr=True, initial_sol=None): #model = yaml_import(filename) if initial_sol == None: if 'model_type' in model and model['model_type'] == 'portfolios': print( 'This is a portfolio model ! Converting to deterministic one.') from portfolio_perturbation import portfolios_to_deterministic model = portfolios_to_deterministic(model, ['x_1', 'x_2']) model.check() from dolo.numeric.perturbations_to_states import approximate_controls perturb_sol = approximate_controls(model, order=1, return_dr=False, substitute_auxiliary=True) [X_bar, X_s] = perturb_sol else: perturb_sol = initial_sol [X_bar, X_s] = perturb_sol # reduce X_s to the real controls (remove auxiliary variables X_s = X_s[:len(model['variables_groups']['controls']), :] X_bar = X_bar[:len(model['variables_groups']['controls'])] X_bar = numpy.array(X_bar) if abs(X_s.imag).max() < 1e-10: X_s = X_s.real else: raise (Exception('Complex decision rule')) print('Perturbation solution found') #print model.parameters #exit() X_bar_1 = X_bar X_s_1 = X_s #model = yaml_import(filename) #from dolo.symbolic.symbolic import Parameter [S_bar, X_bar, X_s, P] = solve_risky_ss(model, X_bar, X_s, verbose=verbose) if return_dr: cdr = CDR([S_bar, X_bar, X_s]) # cdr.P = P return cdr return [S_bar, X_bar, X_s, P]
def dynamic_residuals(X, return_dr=False): x = X[:,0] dx = X[:,1:] for i in range(n_pfs): p = pf_parms[i] v = pf_vars[i] model.parameters_values[p] = x[i] model.init_values[v] = x[i] for j in range(n_states): model.parameters_values[pf_dparms[i][j]] = dx[i,j] if return_dr: dr = approximate_controls(new_model, order=2) return dr else: [X_bar, X_s, X_ss, X_sss] = approximate_controls(new_model, order=3, return_dr=False) crit = numpy.column_stack([ X_bar[n_controls-n_pfs:n_controls], X_s[n_controls-n_pfs:n_controls,:], ]) return crit
def test_higher_order_perturbation(self): # This solves the optimal growth example at second order # and computes the second order correction to the steady-state # We test that both the statefree method and the perturbation to states # yield the same result. from dolo.misc.yamlfile import yaml_import model = yaml_import('../examples/global_models/optimal_growth.yaml') from dolo.numeric.perturbations_to_states import approximate_controls [Xbar, X_s, X_ss, X_sss] = approximate_controls(model, 3)
def test_higher_order_perturbation(self): # This solves the optimal growth example at second order # and computes the second order correction to the steady-state # We test that both the statefree method and the perturbation to states # yield the same result. from dolo.misc.yamlfile import yaml_import model = yaml_import('../examples/global_models/optimal_growth.yaml') from dolo.numeric.perturbations_to_states import approximate_controls [Xbar,X_s,X_ss,X_sss] = approximate_controls(model,3)
def dynamic_residuals(X, return_dr=False): x = X[:,0] dx = X[:,1:] d = {} for i in range(n_pfs): p = pf_parms[i] v = pf_vars[i] d[p] = x[i] d[v] = x[i] for j in range(n_states): d[pf_dparms[i][j]] = dx[i,j] new_model.set_calibration(d) if return_dr: dr = approximate_controls(new_model, order=2) return dr else: [X_bar, X_s, X_ss, X_sss] = approximate_controls(new_model, order=3, return_dr=False) crit = numpy.column_stack([ X_bar[n_controls-n_pfs:n_controls], X_s[n_controls-n_pfs:n_controls,:], ]) return crit
def dynamic_residuals(X, return_dr=False): x = X[:, 0] dx = X[:, 1:] for i in range(n_pfs): p = pf_parms[i] v = pf_vars[i] model.parameters_values[p] = x[i] model.init_values[v] = x[i] for j in range(n_states): model.parameters_values[pf_dparms[i][j]] = dx[i, j] if return_dr: dr = approximate_controls(new_model, order=2, return_dr=True) return dr else: [X_bar, X_s, X_ss, X_sss] = approximate_controls(new_model, order=3, return_dr=False) crit = numpy.column_stack([ X_bar[n_controls - n_pfs:n_controls], X_s[n_controls - n_pfs:n_controls, :], ]) return crit
def dynamic_residuals(X, return_dr=False): x = X[:, 0] dx = X[:, 1:] d = {} for i in range(n_pfs): p = pf_parms[i] v = pf_vars[i] d[p] = x[i] d[v] = x[i] for j in range(n_states): d[pf_dparms[i][j]] = dx[i, j] new_model.set_calibration(d) if return_dr: dr = approximate_controls(new_model, order=2) return dr else: [X_bar, X_s, X_ss, X_sss] = approximate_controls(new_model, order=3, return_dr=False) crit = numpy.column_stack([ X_bar[n_controls - n_pfs:n_controls], X_s[n_controls - n_pfs:n_controls, :], ]) return crit
def solve_model_around_risky_ss(model, verbose=False, return_dr=True, initial_sol=None): #model = yaml_import(filename) if initial_sol == None: if 'model_type' in model and model['model_type'] == 'portfolios': print('This is a portfolio model ! Converting to deterministic one.') from dolo.algos.portfolio_perturbation import portfolios_to_deterministic model = portfolios_to_deterministic(model,['x_1','x_2']) model.check() from dolo.numeric.perturbations_to_states import approximate_controls perturb_sol = approximate_controls(model, order = 1, return_dr=False) [X_bar,X_s] = perturb_sol else: perturb_sol = initial_sol [X_bar,X_s] = perturb_sol # reduce X_s to the real controls (remove auxiliary variables X_s = X_s[:len(model['variables_groups']['controls']),:] X_bar = X_bar[:len(model['variables_groups']['controls'])] X_bar = numpy.array(X_bar) if abs(X_s.imag).max() < 1e-10: X_s = X_s.real else: raise( Exception('Complex decision rule') ) print('Perturbation solution found') #print model.parameters #exit() X_bar_1 = X_bar X_s_1 = X_s #model = yaml_import(filename) #from dolo.symbolic.symbolic import Parameter [S_bar, X_bar, X_s, P] = solve_risky_ss(model, X_bar, X_s, verbose=verbose) if return_dr: cdr = CDR([S_bar, X_bar, X_s]) # cdr.P = P return cdr return [S_bar, X_bar, X_s, P]
z0 = z1 print('finished in {} iterations'.format(it)) return [x0,z0] from dolo import yaml_import from dolo.numeric.perturbations_to_states import approximate_controls model = yaml_import('../../../examples/global_models/rbc_fgah.yaml') dr_pert = approximate_controls(model, order=1, substitute_auxiliary=True) print(dr_pert.X_bar) from dolo.numeric.interpolation.smolyak import SmolyakGrid from dolo.numeric.global_solve import global_solve dr_smol = global_solve(model, smolyak_order=2, maxit=2, polish=True) smin = dr_smol.bounds[0,:] smax = dr_smol.bounds[1,:] dr_x = SmolyakGrid( smin, smax, 3)
def global_solve(model, bounds=None, verbose=False, initial_dr=None, pert_order=2, interp_type='smolyak', smolyak_order=3, interp_orders=None, maxit=500, numdiff=True, polish=True, tol=1e-8, integration='gauss-hermite', integration_orders=[], compiler='numpy', memory_hungry=True, T=200, n_s=2, N_e=40 ): def vprint(t): if verbose: print(t) [y, x, parms] = model.read_calibration() sigma = model.read_covariances() if initial_dr == None: initial_dr = approximate_controls(model, order=pert_order) if interp_type == 'perturbations': return initial_dr if bounds is not None: pass elif 'approximation' in model['original_data']: vprint('Using bounds specified by model') # this should be moved to the compiler ssmin = model['original_data']['approximation']['bounds']['smin'] ssmax = model['original_data']['approximation']['bounds']['smax'] ssmin = [model.eval_string(str(e)) for e in ssmin] ssmax = [model.eval_string(str(e)) for e in ssmax] ssmin = [model.eval_string(str(e)) for e in ssmin] ssmax = [model.eval_string(str(e)) for e in ssmax] [y, x, p] = model.read_calibration() d = {v: y[i] for i, v in enumerate(model.variables)} d.update({v: p[i] for i, v in enumerate(model.parameters)}) smin = [expr.subs(d) for expr in ssmin] smax = [expr.subs(d) for expr in ssmax] smin = numpy.array(smin, dtype=numpy.float) smax = numpy.array(smax, dtype=numpy.float) bounds = numpy.row_stack([smin, smax]) bounds = numpy.array(bounds, dtype=float) else: vprint('Using bounds given by second order solution.') from dolo.numeric.timeseries import asymptotic_variance # this will work only if initial_dr is a Taylor expansion Q = asymptotic_variance(initial_dr.A.real, initial_dr.B.real, initial_dr.sigma, T=T) devs = numpy.sqrt(numpy.diag(Q)) bounds = numpy.row_stack([ initial_dr.S_bar - devs * n_s, initial_dr.S_bar + devs * n_s, ]) smin = bounds[0, :] smax = bounds[1, :] if interp_orders == None: interp_orders = [5] * bounds.shape[1] if interp_type == 'smolyak': from dolo.numeric.interpolation.smolyak import SmolyakGrid dr = SmolyakGrid(bounds[0, :], bounds[1, :], smolyak_order) elif interp_type == 'spline': from dolo.numeric.interpolation.splines import MultivariateSplines dr = MultivariateSplines(bounds[0, :], bounds[1, :], interp_orders) elif interp_type == 'multilinear': from dolo.numeric.interpolation.multilinear import MultilinearInterpolator dr = MultilinearInterpolator(bounds[0, :], bounds[1, :], interp_orders) elif interp_type == 'sparse_linear': from dolo.numeric.interpolation.interpolation import SparseLinear dr = SparseLinear(bounds[0, :], bounds[1, :], smolyak_order) elif interp_type == 'linear': from dolo.numeric.interpolation.interpolation import LinearTriangulation, TriangulatedDomain, RectangularDomain rec = RectangularDomain(smin, smax, interp_orders) domain = TriangulatedDomain(rec.grid) dr = LinearTriangulation(domain) from dolo.compiler.compiler_global import CModel cm = CModel(model, solve_systems=True, compiler=compiler) cm = cm.as_type('fg') if integration == 'optimal_quantization': from dolo.numeric.quantization import quantization_nodes # number of shocks [epsilons, weights] = quantization_nodes(N_e, sigma) elif integration == 'gauss-hermite': from dolo.numeric.quadrature import gauss_hermite_nodes if not integration_orders: integration_orders = [3] * sigma.shape[0] [epsilons, weights] = gauss_hermite_nodes(integration_orders, sigma) vprint('Starting time iteration') from dolo.numeric.global_solution import time_iteration from dolo.numeric.global_solution import stochastic_residuals_2, stochastic_residuals_3 xinit = initial_dr(dr.grid) xinit = xinit.real # just in case... dr = time_iteration(dr.grid, dr, xinit, cm.f, cm.g, parms, epsilons, weights, x_bounds=cm.x_bounds, maxit=maxit, tol=tol, nmaxit=50, numdiff=numdiff, verbose=verbose) if polish and interp_type == 'smolyak': # this works with smolyak only vprint('\nStarting global optimization') import time t1 = time.time() if cm.x_bounds is not None: lb = cm.x_bounds[0](dr.grid, parms) ub = cm.x_bounds[1](dr.grid, parms) else: lb = None ub = None xinit = dr(dr.grid) dr.set_values(xinit) shape = xinit.shape if not memory_hungry: fobj = lambda t: stochastic_residuals_3(dr.grid, t, dr, cm.f, cm.g, parms, epsilons, weights, shape, deriv=False) dfobj = lambda t: stochastic_residuals_3(dr.grid, t, dr, cm.f, cm.g, parms, epsilons, weights, shape, deriv=True)[1] else: fobj = lambda t: stochastic_residuals_2(dr.grid, t, dr, cm.f, cm.g, parms, epsilons, weights, shape, deriv=False) dfobj = lambda t: stochastic_residuals_2(dr.grid, t, dr, cm.f, cm.g, parms, epsilons, weights, shape, deriv=True)[1] from dolo.numeric.solver import solver x = solver(fobj, xinit, lb=lb, ub=ub, jac=dfobj, verbose=verbose, method='ncpsolve', serial_problem=False) dr.set_values(x) # just in case t2 = time.time() # test solution res = stochastic_residuals_2(dr.grid, x, dr, cm.f, cm.g, parms, epsilons, weights, shape, deriv=False) if numpy.isinf(res.flatten()).sum() > 0: raise ( Exception('Non finite values in residuals.')) vprint('Finished in {} s'.format(t2 - t1)) return dr
def test_perturbation_3(self): from dolo.misc.yamlfile import yaml_import from dolo.numeric.perturbations_to_states import approximate_controls model = yaml_import('examples/global_models/rbc.yaml') dr = approximate_controls(model, order=3)
def solve_portfolio_model(model, pf_names, order=1): pf_model = model from dolo import Variable, Parameter, Equation import re n_states = len(pf_model['variables_groups']['states']) states = pf_model['variables_groups']['states'] steady_states = [Parameter(v.name+'_bar') for v in pf_model['variables_groups']['states']] n_pfs = len(pf_names) pf_vars = [Variable(v) for v in pf_names] res_vars = [Variable('res_'+str(i)) for i in range(n_pfs)] pf_parms = [Parameter('K_'+str(i)) for i in range(n_pfs)] pf_dparms = [[Parameter('K_'+str(i)+'_'+str(j)) for j in range(n_states)] for i in range(n_pfs)] from sympy import Matrix # creation of the new model import copy print('Warning: initial model has been changed.') new_model = copy.copy(pf_model) new_model['variables_groups']['controls']+=res_vars new_model['parameters_ordering'].extend(steady_states) for p in pf_parms + Matrix(pf_dparms)[:]: new_model['parameters_ordering'].append(p) new_model.parameters_values[p] = 0 compregex = re.compile('(.*)<=(.*)<=(.*)') to_be_added = [] expressions = Matrix(pf_parms) + Matrix(pf_dparms)*( Matrix(states) - Matrix(steady_states)) for eq in new_model['equations_groups']['arbitrage']: if 'complementarity' in eq.tags: tg = eq.tags['complementarity'] [lhs,mhs,rhs] = compregex.match(tg).groups() mhs = new_model.eval_string(mhs) else: mhs = None if mhs in pf_vars: i = pf_vars.index(mhs) eq_n = eq.tags['eq_number'] neq = Equation(mhs, expressions[i]) neq.tag(**eq.tags) new_model['equations'][eq_n] = neq eq_res = Equation(eq.gap, res_vars[i]) eq_res.tag(eq_type='arbitrage') to_be_added.append(eq_res) new_model['equations'].extend(to_be_added) new_model.check() new_model.check_consistency(verbose=True) print(new_model.parameters) print(len(new_model['equations'])) print(len(new_model.equations)) print(len(new_model['equations_groups']['arbitrage'])) print('parameters_ordering') print(new_model['parameters_ordering']) print(new_model.parameters) # now, we need to solve for the optimal portfolio coefficients from dolo.numeric.perturbations_to_states import approximate_controls dr = approximate_controls(new_model) print('ok') import numpy n_controls = len(model['variables_groups']['controls']) def constant_residuals(x): for i in range(n_pfs): p = pf_parms[i] v = pf_vars[i] new_model.parameters_values[p] = x[i] new_model.init_values[v] = x[i] [X_bar, X_s, X_ss] = approximate_controls(new_model, order=2, return_dr=False) return X_bar[n_controls-n_pfs:n_controls] x0 = numpy.zeros(n_pfs) from dolo.numeric.solver import solver portfolios_0 = solver(constant_residuals, x0) print('Zero order portfolios : ') print(portfolios_0) print('Zero order: Final error:') print(constant_residuals(portfolios_0)) def dynamic_residuals(X, return_dr=False): x = X[:,0] dx = X[:,1:] for i in range(n_pfs): p = pf_parms[i] v = pf_vars[i] model.parameters_values[p] = x[i] model.init_values[v] = x[i] for j in range(n_states): model.parameters_values[pf_dparms[i][j]] = dx[i,j] if return_dr: dr = approximate_controls(new_model, order=2) return dr else: [X_bar, X_s, X_ss, X_sss] = approximate_controls(new_model, order=3, return_dr=False) crit = numpy.column_stack([ X_bar[n_controls-n_pfs:n_controls], X_s[n_controls-n_pfs:n_controls,:], ]) return crit y0 = numpy.column_stack([x0, numpy.zeros((n_pfs, n_states))]) print('Initial error:') print(dynamic_residuals(y0)) portfolios_1 = solver(dynamic_residuals, y0) print('First order portfolios : ') print(portfolios_1) print('Final error:') print(dynamic_residuals(portfolios_1)) dr = dynamic_residuals(portfolios_1, return_dr=True) return dr
def solve_portfolio_model(model, pf_names, order=2, guess=None): from dolo.compiler.compiler_python import GModel if isinstance(model, GModel): model = model.model pf_model = model from dolo import Variable, Parameter, Equation import re n_states = len(pf_model.symbols_s['states']) states = pf_model.symbols_s['states'] steady_states = [ Parameter(v.name + '_bar') for v in pf_model.symbols_s['states'] ] n_pfs = len(pf_names) pf_vars = [Variable(v) for v in pf_names] res_vars = [Variable('res_' + str(i)) for i in range(n_pfs)] pf_parms = [Parameter('K_' + str(i)) for i in range(n_pfs)] pf_dparms = [[ Parameter('K_' + str(i) + '_' + str(j)) for j in range(n_states) ] for i in range(n_pfs)] from sympy import Matrix # creation of the new model import copy new_model = copy.copy(pf_model) new_model.symbols_s['controls'] += res_vars for v in res_vars + pf_vars: new_model.calibration_s[v] = 0 new_model.symbols_s['parameters'].extend(steady_states) for p in pf_parms + Matrix(pf_dparms)[:]: new_model.symbols_s['parameters'].append(p) new_model.calibration_s[p] = 0 compregex = re.compile('(.*)<=(.*)<=(.*)') to_be_added_1 = [] to_be_added_2 = [] expressions = Matrix(pf_parms) + Matrix(pf_dparms) * ( Matrix(states) - Matrix(steady_states)) for n, eq in enumerate(new_model.equations_groups['arbitrage']): if 'complementarity' in eq.tags: tg = eq.tags['complementarity'] [lhs, mhs, rhs] = compregex.match(tg).groups() mhs = new_model.eval_string(mhs) else: mhs = None if mhs in pf_vars: i = pf_vars.index(mhs) neq = Equation(mhs, expressions[i]) neq.tag(**eq.tags) eq_res = Equation(eq.gap, res_vars[i]) eq_res.tag(eq_type='arbitrage') to_be_added_2.append(eq_res) new_model.equations_groups['arbitrage'][n] = neq to_be_added_1.append(neq) # new_model.equations_groups['arbitrage'].extend(to_be_added_1) new_model.equations_groups['arbitrage'].extend(to_be_added_2) new_model.update() print("number of equations {}".format(len(new_model.equations))) print("number of arbitrage equations {}".format( len(new_model.equations_groups['arbitrage']))) print('parameters_ordering') print("number of parameters {}".format(new_model.symbols['parameters'])) print("number of parameters {}".format(new_model.parameters)) # now, we need to solve for the optimal portfolio coefficients from dolo.numeric.perturbations_to_states import approximate_controls dr = approximate_controls(new_model) print('ok') import numpy n_controls = len(model.symbols_s['controls']) def constant_residuals(x, return_dr=False): d = {} for i in range(n_pfs): p = pf_parms[i] v = pf_vars[i] d[p] = x[i] d[v] = x[i] new_model.set_calibration(d) # new_model.parameters_values[p] = x[i] # new_model.init_values[v] = x[i] if return_dr: dr = approximate_controls(new_model, order=1, return_dr=True) return dr X_bar, X_s, X_ss = approximate_controls(new_model, order=2, return_dr=False) return X_bar[n_controls - n_pfs:n_controls] if guess is not None: x0 = numpy.array(guess) else: x0 = numpy.zeros(n_pfs) from dolo.numeric.solver import solver portfolios_0 = solver(constant_residuals, x0) print('Zero order portfolios: {}'.format(portfolios_0)) print('Zero order portfolios: Final error: {}'.format( constant_residuals(portfolios_0))) if order == 1: dr = constant_residuals(portfolios_0, return_dr=True) return dr def dynamic_residuals(X, return_dr=False): x = X[:, 0] dx = X[:, 1:] d = {} for i in range(n_pfs): p = pf_parms[i] v = pf_vars[i] d[p] = x[i] d[v] = x[i] for j in range(n_states): d[pf_dparms[i][j]] = dx[i, j] new_model.set_calibration(d) if return_dr: dr = approximate_controls(new_model, order=2) return dr else: [X_bar, X_s, X_ss, X_sss] = approximate_controls(new_model, order=3, return_dr=False) crit = numpy.column_stack([ X_bar[n_controls - n_pfs:n_controls], X_s[n_controls - n_pfs:n_controls, :], ]) return crit y0 = numpy.column_stack([x0, numpy.zeros((n_pfs, n_states))]) print('Initial error:') print(dynamic_residuals(y0)) portfolios_1 = solver(dynamic_residuals, y0) print('First order portfolios : ') print(portfolios_1) print('Final error:') print(dynamic_residuals(portfolios_1)) dr = dynamic_residuals(portfolios_1, return_dr=True) return dr
def solve_portfolio_model(model, pf_names, order=2, guess=None): from dolo.compiler.compiler_python import GModel if isinstance(model, GModel): model = model.model pf_model = model from dolo import Variable, Parameter, Equation import re n_states = len(pf_model.symbols_s['states']) states = pf_model.symbols_s['states'] steady_states = [Parameter(v.name+'_bar') for v in pf_model.symbols_s['states']] n_pfs = len(pf_names) pf_vars = [Variable(v) for v in pf_names] res_vars = [Variable('res_'+str(i)) for i in range(n_pfs)] pf_parms = [Parameter('K_'+str(i)) for i in range(n_pfs)] pf_dparms = [[Parameter('K_'+str(i)+'_'+str(j)) for j in range(n_states)] for i in range(n_pfs)] from sympy import Matrix # creation of the new model import copy new_model = copy.copy(pf_model) new_model.symbols_s['controls'] += res_vars for v in res_vars + pf_vars: new_model.calibration_s[v] = 0 new_model.symbols_s['parameters'].extend(steady_states) for p in pf_parms + Matrix(pf_dparms)[:]: new_model.symbols_s['parameters'].append(p) new_model.calibration_s[p] = 0 compregex = re.compile('(.*)<=(.*)<=(.*)') to_be_added_1 = [] to_be_added_2 = [] expressions = Matrix(pf_parms) + Matrix(pf_dparms)*( Matrix(states) - Matrix(steady_states)) for n,eq in enumerate(new_model.equations_groups['arbitrage']): if 'complementarity' in eq.tags: tg = eq.tags['complementarity'] [lhs,mhs,rhs] = compregex.match(tg).groups() mhs = new_model.eval_string(mhs) else: mhs = None if mhs in pf_vars: i = pf_vars.index(mhs) neq = Equation(mhs, expressions[i]) neq.tag(**eq.tags) eq_res = Equation(eq.gap, res_vars[i]) eq_res.tag(eq_type='arbitrage') to_be_added_2.append(eq_res) new_model.equations_groups['arbitrage'][n] = neq to_be_added_1.append(neq) # new_model.equations_groups['arbitrage'].extend(to_be_added_1) new_model.equations_groups['arbitrage'].extend(to_be_added_2) new_model.update() print("number of equations {}".format(len(new_model.equations))) print("number of arbitrage equations {}".format( len(new_model.equations_groups['arbitrage'])) ) print('parameters_ordering') print("number of parameters {}".format(new_model.symbols['parameters'])) print("number of parameters {}".format(new_model.parameters)) # now, we need to solve for the optimal portfolio coefficients from dolo.numeric.perturbations_to_states import approximate_controls dr = approximate_controls(new_model) print('ok') import numpy n_controls = len(model.symbols_s['controls']) def constant_residuals(x, return_dr=False): d = {} for i in range(n_pfs): p = pf_parms[i] v = pf_vars[i] d[p] = x[i] d[v] = x[i] new_model.set_calibration(d) # new_model.parameters_values[p] = x[i] # new_model.init_values[v] = x[i] if return_dr: dr = approximate_controls(new_model, order=1, return_dr=True) return dr X_bar, X_s, X_ss = approximate_controls(new_model, order=2, return_dr=False) return X_bar[n_controls-n_pfs:n_controls] if guess is not None: x0 = numpy.array(guess) else: x0 = numpy.zeros(n_pfs) from dolo.numeric.solver import solver portfolios_0 = solver(constant_residuals, x0) print('Zero order portfolios: {}'.format(portfolios_0)) print('Zero order portfolios: Final error: {}'.format( constant_residuals(portfolios_0) )) if order == 1: dr = constant_residuals(portfolios_0, return_dr=True) return dr def dynamic_residuals(X, return_dr=False): x = X[:,0] dx = X[:,1:] d = {} for i in range(n_pfs): p = pf_parms[i] v = pf_vars[i] d[p] = x[i] d[v] = x[i] for j in range(n_states): d[pf_dparms[i][j]] = dx[i,j] new_model.set_calibration(d) if return_dr: dr = approximate_controls(new_model, order=2) return dr else: [X_bar, X_s, X_ss, X_sss] = approximate_controls(new_model, order=3, return_dr=False) crit = numpy.column_stack([ X_bar[n_controls-n_pfs:n_controls], X_s[n_controls-n_pfs:n_controls,:], ]) return crit y0 = numpy.column_stack([x0, numpy.zeros((n_pfs, n_states))]) print('Initial error:') print(dynamic_residuals(y0)) portfolios_1 = solver(dynamic_residuals, y0) print('First order portfolios : ') print(portfolios_1) print('Final error:') print(dynamic_residuals(portfolios_1)) dr = dynamic_residuals(portfolios_1, return_dr=True) return dr
print(err, err2) x0 = x1 z0 = z1 print('finished in {} iterations'.format(it)) return [x0, z0] from dolo import yaml_import from dolo.numeric.perturbations_to_states import approximate_controls model = yaml_import('../../../examples/global_models/rbc_fgah.yaml') dr_pert = approximate_controls(model, order=1, substitute_auxiliary=True) print(dr_pert.X_bar) from dolo.numeric.interpolation.smolyak import SmolyakGrid from dolo.numeric.global_solve import global_solve dr_smol = global_solve(model, smolyak_order=2, maxit=2, polish=True) smin = dr_smol.bounds[0, :] smax = dr_smol.bounds[1, :] dr_x = SmolyakGrid(smin, smax, 3) dr_h = SmolyakGrid(smin, smax, 3) grid = dr_x.grid
def process_output_recs(self, solution_order=False, fname=None): data = self.read_model() dmodel = self.model model = dmodel f_eqs = data['f_eqs'] g_eqs = data['g_eqs'] h_eqs = data['h_eqs'] states_vars = data['states_vars'] controls = data['controls'] 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_vars] 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_vars): 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) for i,v in enumerate(dmodel.parameters): sub_list[v] = 'p({0})'.format(i+1) import sympy sub_list[sympy.Symbol('inf')] = 'Inf' text = '''function [out1,out2,out3,out4,out5] = {mfname}(flag,s,x,z,e,snext,xnext,p,out); output = struct('F',1,'Js',0,'Jx',0,'Jsn',0,'Jxn',0,'Jz',0,'hmult',0); if nargin == 9 output = catstruct(output,out); voidcell = cell(1,5); [out1,out2,out3,out4,out5] = voidcell{{:}}; else if nargout >= 2, output.Js = 1; end if nargout >= 3, output.Jx = 1; end if nargout >= 4 if strcmpi(flag, 'f') output.Jz = 1; else output.Jsn = 1; end end if nargout >= 5, output.Jxn = 1; end end switch flag case 'b'; n = size(s,1); {eq_bounds_block} case 'f'; n = size(s,1); {eq_fun_block} case 'g'; n = size(s,1); {state_trans_block} case 'h'; n = size(snext,1); {exp_fun_block} case 'e'; out1 = []; case 'model'; % 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 if output.F {0} end % df/ds if output.Js {1} end % df/dx if output.Jx {2} end % df/dz if output.Jz {3} end '''.format( write_eqs(f_eqs,'out1',3), write_der_eqs(f_eqs,states_vars,'out2',3), write_der_eqs(f_eqs,controls,'out3',3), write_der_eqs(f_eqs,exp_vars,'out4',3) ) eq_g_block = ''' % g if output.F {0} end if output.Js {1} end if output.Jx {2} end '''.format( write_eqs(g_eqs,'out1',3), write_der_eqs(g_eqs,states_vars,'out2',3), write_der_eqs(g_eqs,controls,'out3',3) ) eq_h_block = ''' %h if output.F {0} end if output.Js {1} end if output.Jx {2} end if output.Jsn {3} end if output.Jxn {4} end '''.format( write_eqs(h_eqs,'out1',3), write_der_eqs(h_eqs,states_vars,'out2',3), write_der_eqs(h_eqs,controls,'out3',3), write_der_eqs(h_eqs,states_f,'out4',3), write_der_eqs(h_eqs,controls_f,'out5',3) ) # 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.s_ss = {s_ss}; mod.x_ss = {x_ss}; mod.params = {params_values}; '''.format( 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) 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)) 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, exp_fun_block=eq_h_block, # solution = solution, model_info = model_info ) return text
def process_output(self, solution_order=False, fname=None): from dolo.numeric.perturbations_to_states import simple_global_representation data = simple_global_representation(self.model, substitute_auxiliary=True, keep_auxiliary=True, 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'] # 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] 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) 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,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.compiler 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,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
if __name__ == '__main__': from dolo.misc.yamlfile import yaml_import from dolo.numeric.perturbations_to_states import approximate_controls from dolo.numeric.global_solve import global_solve model = yaml_import( 'examples/global_models/rbc_fgah.yaml') model_bis = yaml_import( 'examples/global_models/rbc.yaml') print(model) print(model) dr_pert = approximate_controls(model_bis) cm = CModel_fgah(model) cm_fg = cm.as_type('fg') import time t = time.time() for n in range(10): global_solve(model_bis, initial_dr=dr_pert, polish=False, interp_type='multilinear') s = time.time() print('Elapsed : {}'.format(s-t) )
def process_output(self, solution_order=False, fname=None): from dolo.numeric.perturbations_to_states import simple_global_representation data = simple_global_representation(self.model, substitute_auxiliary=True, keep_auxiliary=True, 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'] # 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] 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) 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,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.compiler 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,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
def test_perturbation_3(self): from dolo.misc.yamlfile import yaml_import from dolo.numeric.perturbations_to_states import approximate_controls model = yaml_import('examples/global_models/rbc.yaml') dr = approximate_controls(model,order=3)