def solve_risky_ss(model, X_bar, X_s, verbose=False): import numpy from dolo.compiler.function_compiler import compile_function import time from dolo.compiler.compiler_functions import simple_global_representation parms = model.calibration['parameters'] sigma = model.calibration['covariances'] sgm = simple_global_representation(model) states = sgm['states'] controls = sgm['controls'] shocks = sgm['shocks'] parameters = sgm['parameters'] f_eqs = sgm['f_eqs'] g_eqs = sgm['g_eqs'] g_args = [s(-1) for s in states] + [c(-1) for c in controls] + shocks f_args = states + controls + [v(1) for v in states] + [v(1) for v in controls] p_args = parameters g_fun = compile_function(g_eqs, g_args, p_args, 2) f_fun = compile_function(f_eqs, f_args, p_args, 3) epsilons_0 = np.zeros((sigma.shape[0])) from numpy import dot from dolo.numeric.tensor import sdot, mdot def residuals(X, sigma, parms, g_fun, f_fun): import numpy dummy_x = X[0:1, 0] X_bar = X[1:, 0] S_bar = X[0, 1:] X_s = X[1:, 1:] [n_x, n_s] = X_s.shape n_e = sigma.shape[0] xx = np.concatenate([S_bar, X_bar, epsilons_0]) [g_0, g_1, g_2] = g_fun(xx, parms) [f_0, f_1, f_2, f_3] = f_fun(np.concatenate([S_bar, X_bar, S_bar, X_bar]), parms) res_g = g_0 - S_bar # g is a first order function g_s = g_1[:, :n_s] g_x = g_1[:, n_s:n_s + n_x] g_e = g_1[:, n_s + n_x:] g_se = g_2[:, :n_s, n_s + n_x:] g_xe = g_2[:, n_s:n_s + n_x, n_s + n_x:] # S(s,e) = g(s,x,e) S_s = g_s + dot(g_x, X_s) S_e = g_e S_se = g_se + mdot(g_xe, [X_s, numpy.eye(n_e)]) # V(s,e) = [ g(s,x,e) ; x( g(s,x,e) ) ] V_s = np.row_stack([S_s, dot(X_s, S_s)]) # *** V_e = np.row_stack([S_e, dot(X_s, S_e)]) V_se = np.row_stack([S_se, dot(X_s, S_se)]) # v(s) = [s, x(s)] v_s = np.row_stack([numpy.eye(n_s), X_s]) # W(s,e) = [xx(s,e); yy(s,e)] W_s = np.row_stack([v_s, V_s]) #return nn = n_s + n_x f_v = f_1[:, :nn] f_V = f_1[:, nn:] f_1V = f_2[:, :, nn:] f_VV = f_2[:, nn:, nn:] f_1VV = f_3[:, :, nn:, nn:] # E = lambda v: np.tensordot(v, sigma, axes=((2,3),(0,1)) ) # expectation operator F = f_0 + 0.5 * np.tensordot( mdot(f_VV, [V_e, V_e]), sigma, axes=((1, 2), (0, 1))) F_s = sdot(f_1, W_s) f_see = mdot(f_1VV, [W_s, V_e, V_e]) + 2 * mdot(f_VV, [V_se, V_e]) F_s += 0.5 * np.tensordot(f_see, sigma, axes=( (2, 3), (0, 1))) # second order correction resp = np.row_stack( [np.concatenate([dummy_x, res_g]), np.column_stack([F, F_s])]) return resp # S_bar = s_fun_init( numpy.atleast_2d(X_bar).T ,parms).flatten() # S_bar = S_bar.flatten() S_bar = model.calibration['states'] S_bar = np.array(S_bar) X0 = np.row_stack( [np.concatenate([np.zeros(1), S_bar]), np.column_stack([X_bar, X_s])]) fobj = lambda X: residuals(X, sigma, parms, g_fun, f_fun) if verbose: val = fobj(X0) print('val') print(val) # exit() t = time.time() sol = solver(fobj, X0, method='lmmcp', verbose=verbose, options={ 'preprocess': False, 'eps1': 1e-15, 'eps2': 1e-15 }) if verbose: print('initial guess') print(X0) print('solution') print sol print('initial residuals') print(fobj(X0)) print('residuals') print fobj(sol) s = time.time() if verbose: print('Elapsed : {0}'.format(s - t)) #sol = solver(fobj,X0, method='fsolve', verbose=True, options={'preprocessor':False}) norm = lambda x: numpy.linalg.norm(x, numpy.inf) if verbose: print("Initial error: {0}".format(norm(fobj(X0)))) print("Final error: {0}".format(norm(fobj(sol)))) print("Solution") print(sol) X_bar = sol[1:, 0] S_bar = sol[0, 1:] X_s = sol[1:, 1:] # compute transitions n_s = len(states) n_x = len(controls) [g, dg, junk] = g_fun(np.concatenate([S_bar, X_bar, epsilons_0]), parms) g_s = dg[:, :n_s] g_x = dg[:, n_s:n_s + n_x] P = g_s + dot(g_x, X_s) if verbose: eigenvalues = numpy.linalg.eigvals(P) print eigenvalues eigenvalues = [abs(e) for e in eigenvalues] eigenvalues.sort() print(eigenvalues) return [S_bar, X_bar, X_s, P]
def solve_risky_ss(model, X_bar, X_s, verbose=False): import numpy from dolo.compiler.compiling import compile_function import time from dolo.compiler.compiler_functions import simple_global_representation [y,x,parms] = model.read_calibration() sigma = model.read_covariances() sgm = simple_global_representation(model) states = sgm['states'] controls = sgm['controls'] shocks = sgm['shocks'] parameters = sgm['parameters'] f_eqs = sgm['f_eqs'] g_eqs = sgm['g_eqs'] g_args = [s(-1) for s in states] + [c(-1) for c in controls] + shocks f_args = states + controls + [v(1) for v in states] + [v(1) for v in controls] p_args = parameters g_fun = compile_function(g_eqs, g_args, p_args, 2) f_fun = compile_function(f_eqs, f_args, p_args, 3) epsilons_0 = np.zeros((sigma.shape[0])) from numpy import dot from dolo.numeric.tensor import sdot,mdot def residuals(X, sigma, parms, g_fun, f_fun): import numpy dummy_x = X[0:1,0] X_bar = X[1:,0] S_bar = X[0,1:] X_s = X[1:,1:] [n_x,n_s] = X_s.shape n_e = sigma.shape[0] xx = np.concatenate([S_bar, X_bar, epsilons_0]) [g_0, g_1, g_2] = g_fun(xx, parms) [f_0,f_1,f_2,f_3] = f_fun( np.concatenate([S_bar, X_bar, S_bar, X_bar]), parms) res_g = g_0 - S_bar # g is a first order function g_s = g_1[:,:n_s] g_x = g_1[:,n_s:n_s+n_x] g_e = g_1[:,n_s+n_x:] g_se = g_2[:,:n_s,n_s+n_x:] g_xe = g_2[:, n_s:n_s+n_x, n_s+n_x:] # S(s,e) = g(s,x,e) S_s = g_s + dot(g_x, X_s) S_e = g_e S_se = g_se + mdot(g_xe,[X_s, numpy.eye(n_e)]) # V(s,e) = [ g(s,x,e) ; x( g(s,x,e) ) ] V_s = np.row_stack([ S_s, dot( X_s, S_s ) ]) # *** V_e = np.row_stack([ S_e, dot( X_s, S_e ) ]) V_se = np.row_stack([ S_se, dot( X_s, S_se ) ]) # v(s) = [s, x(s)] v_s = np.row_stack([ numpy.eye(n_s), X_s ]) # W(s,e) = [xx(s,e); yy(s,e)] W_s = np.row_stack([ v_s, V_s ]) #return nn = n_s + n_x f_v = f_1[:,:nn] f_V = f_1[:,nn:] f_1V = f_2[:,:,nn:] f_VV = f_2[:,nn:,nn:] f_1VV = f_3[:,:,nn:,nn:] # E = lambda v: np.tensordot(v, sigma, axes=((2,3),(0,1)) ) # expectation operator F = f_0 + 0.5*np.tensordot( mdot(f_VV,[V_e,V_e]), sigma, axes=((1,2),(0,1)) ) F_s = sdot(f_1, W_s) f_see = mdot(f_1VV, [W_s, V_e, V_e]) + 2*mdot(f_VV, [V_se, V_e]) F_s += 0.5 * np.tensordot(f_see, sigma, axes=((2,3),(0,1)) ) # second order correction resp = np.row_stack([ np.concatenate([dummy_x,res_g]), np.column_stack([F,F_s]) ]) return resp # S_bar = s_fun_init( numpy.atleast_2d(X_bar).T ,parms).flatten() # S_bar = S_bar.flatten() S_bar = [ y[i] for i,v in enumerate(model.variables) if v in model['variables_groups']['states'] ] S_bar = np.array(S_bar) X0 = np.row_stack([ np.concatenate([np.zeros(1),S_bar]), np.column_stack([X_bar,X_s]) ]) from dolo.numeric.solver import solver fobj = lambda X: residuals(X, sigma, parms, g_fun, f_fun) if verbose: val = fobj(X0) print('val') print(val) # exit() t = time.time() sol = solver(fobj,X0, method='lmmcp', verbose=verbose, options={'preprocess':False, 'eps1':1e-15, 'eps2': 1e-15}) if verbose: print('initial guess') print(X0) print('solution') print sol print('initial residuals') print(fobj(X0)) print('residuals') print fobj(sol) s = time.time() if verbose: print('Elapsed : {0}'.format(s-t)) #sol = solver(fobj,X0, method='fsolve', verbose=True, options={'preprocessor':False}) norm = lambda x: numpy.linalg.norm(x,numpy.inf) if verbose: print( "Initial error: {0}".format( norm( fobj(X0)) ) ) print( "Final error: {0}".format( norm( fobj(sol) ) ) ) print("Solution") print(sol) X_bar = sol[1:,0] S_bar = sol[0,1:] X_s = sol[1:,1:] # compute transitions n_s = len(states) n_x = len(controls) [g, dg, junk] = g_fun( np.concatenate( [S_bar, X_bar, epsilons_0] ), parms) g_s = dg[:,:n_s] g_x = dg[:,n_s:n_s+n_x] P = g_s + dot(g_x, X_s) if verbose: eigenvalues = numpy.linalg.eigvals(P) print eigenvalues eigenvalues = [abs(e) for e in eigenvalues] eigenvalues.sort() print(eigenvalues) return [S_bar, X_bar, X_s, P]
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