def approximate_controls(model, verbose=False, steady_state=None, eigmax=1.0, solve_steady_state=False, order=1): """Compute first order approximation of optimal controls Parameters: ----------- model: NumericModel Model to be solved verbose: boolean If True: displays number of contracting eigenvalues steady_state: ndarray Use supplied steady-state value to compute the approximation. The routine doesn't check whether it is really a solution or not. solve_steady_state: boolean Use nonlinear solver to find the steady-state orders: {1} Approximation order. (Currently, only first order is supported). Returns: -------- TaylorExpansion: Decision Rule for the optimal controls around the steady-state. """ if order>1: raise Exception("Not implemented.") # get steady_state import numpy # if model.model_type == 'fga': # model = GModel_fg_from_fga(model) # g = model.functions['transition'] # f = model.functions['arbitrage'] from dolo.algos.convert import get_fg_functions [f,g] = get_fg_functions(model) if steady_state is not None: calib = steady_state else: calib = model.calibration if solve_steady_state: from dolo.algos.steady_state import find_deterministic_equilibrium calib = find_deterministic_equilibrium(model) p = calib['parameters'] s = calib['states'] x = calib['controls'] e = calib['shocks'] if model.covariances is not None: sigma = model.covariances else: sigma = numpy.zeros((len(e), len(e))) from numpy.linalg import solve l = g(s,x,e,p, diff=True) [junk, g_s, g_x, g_e] = l[:4] # [el[0,...] for el in l[:4]] l = f(s,x,e,s,x,p, diff=True) [res, f_s, f_x, f_e, f_S, f_X] = l #[el[0,...] for el in l[:6]] n_s = g_s.shape[0] # number of controls n_x = g_x.shape[1] # number of states n_e = g_e.shape[1] n_v = n_s + n_x A = row_stack([ column_stack( [ eye(n_s), zeros((n_s,n_x)) ] ), column_stack( [ -f_S , -f_X ] ) ]) B = row_stack([ column_stack( [ g_s, g_x ] ), column_stack( [ f_s, f_x ] ) ]) from dolo.numeric.extern.qz import qzordered [S,T,Q,Z,eigval] = qzordered(A,B,n_s) Q = Q.real # is it really necessary ? Z = Z.real diag_S = numpy.diag(S) diag_T = numpy.diag(T) # Check Blanchard=Kahn conditions n_big_one = sum(eigval>eigmax) n_expected = n_x if verbose: print( "There are {} eigenvalues greater than {}. Expected: {}.".format( n_big_one, eigmax, n_x ) ) if n_expected != n_big_one: raise BlanchardKahnError(n_big_one, n_expected) tol_geneigvals = 1e-10 try: assert( sum( (abs( diag_S ) < tol_geneigvals) * (abs(diag_T) < tol_geneigvals) ) == 0) except Exception as e: print e print(numpy.column_stack([diag_S, diag_T])) # raise GeneralizedEigenvaluesError(diag_S, diag_T) Z11 = Z[:n_s,:n_s] Z12 = Z[:n_s,n_s:] Z21 = Z[n_s:,:n_s] Z22 = Z[n_s:,n_s:] S11 = S[:n_s,:n_s] T11 = T[:n_s,:n_s] # first order solution C = solve(Z11.T, Z21.T).T P = np.dot(solve(S11.T, Z11.T).T , solve(Z11.T, T11.T).T ) Q = g_e s = s.ravel() x = x.ravel() A = g_s + dot( g_x, C ) B = g_e dr = CDR([s, x, C]) dr.A = A dr.B = B dr.sigma = sigma return dr
def deterministic_solve(model, shocks=None, start_states=None, T=100, ignore_constraints=False, maxit=100, initial_guess=None, verbose=False, tol=1e-6): ''' Computes a perfect foresight simulation using a stacked-time algorithm. The initial state is specified either by providing a series of exogenous shocks and assuming the model is initially in equilibrium with the first value of the shock, or by specifying an initial value for the states. Parameters ---------- model: NumericModel "fg" or "fga" model to be solved shocks: ndarray :math:`n_e\\times N` matrix containing :math:`N` realizations of the shocks. :math:`N` must be smaller than :math:`T`. The exogenous process is assumed to remain constant and equal to its last value after `N` periods. start_states: ndarray or dict a vector with the value of initial states, or a calibration dictionary with the initial values of states and controls T: int horizon for the perfect foresight simulation maxit: int maximum number of iteration for the nonlinear solver verbose: boolean if True, the solver displays iterations tol: float stopping criterium for the nonlinear solver ignore_constraints: bool if True, complementarity constraints are ignored. Returns ------- pandas dataframe: a dataframe with T+1 observations of the model variables along the simulation (states, controls, auxiliaries). The first observation is the steady-state corresponding to the first value of the shocks. The simulation should return to a steady-state corresponding to the last value of the exogenous shocks. ''' # TODO: # if model.model_type == 'fga': # from dolo.compiler.converter import GModel_fg_from_fga # model = GModel_fg_from_fga(model) # definitions n_s = len(model.calibration['states']) n_x = len(model.calibration['controls']) if shocks == None: shocks = numpy.zeros((len(model.calibration['shocks']), 1)) # until last period, exogenous shock takes its last value epsilons = numpy.zeros((T + 1, shocks.shape[1])) epsilons[:(shocks.shape[0] - 1), :] = shocks[1:, :] epsilons[(shocks.shape[0] - 1):, :] = shocks[-1:, :] # final initial and final steady-states consistent with exogenous shocks if isinstance(start_states, dict): # at least that part is clear start_equilibrium = start_states start_s = start_equilibrium['states'] start_x = start_equilibrium['controls'] final_s = start_equilibrium['states'] final_x = start_equilibrium['controls'] elif isinstance(start_states, numpy.ndarray): start_s = start_states start_x = model.calibration['controls'] final_s = model.calibration['states'] final_x = model.calibration['controls'] else: # raise Exception("You must compute initial calibration yourself") final_dict = { model.symbols['shocks'][i]: shocks[i, -1] for i in range(len(model.symbols['shocks'])) } start_dict = { model.symbols['shocks'][i]: shocks[i, 0] for i in range(len(model.symbols['shocks'])) } start_calib = find_deterministic_equilibrium(model, constraints=start_dict) final_calib = find_deterministic_equilibrium(model, constraints=start_dict) start_s = start_calib['states'] start_x = start_calib['controls'] final_s = final_calib['states'] final_x = final_calib['controls'] # if start_constraints: # ### we ignore start_constraints # start_dict.update(start_constraints) # final_equilibrium = start_constraints.copy() # else: # final_equilibrium = find_deterministic_equilibrium( model, constraints=final_dict) # final_s = final_equilibrium['states'] # final_x = final_equilibrium['controls'] # start_s = start_states # start_x = final_x #TODO: for start_x, it should be possible to use first order guess final = numpy.concatenate([final_s, final_x]) start = numpy.concatenate([start_s, start_x]) if verbose == True: print("Initial states : {}".format(start_s)) print("Final controls : {}".format(final_x)) p = model.calibration['parameters'] if initial_guess is None: initial_guess = numpy.row_stack( [start * (1 - l) + final * l for l in linspace(0.0, 1.0, T + 1)]) else: from pandas import DataFrame if isinstance(initial_guess, DataFrame): initial_guess = array(initial_guess).T.copy() initial_guess = initial_guess[:, :n_s + n_x] initial_guess[0, :n_s] = start_s initial_guess[-1, n_s:] = final_x sh = initial_guess.shape if model.x_bounds and not ignore_constraints: initial_states = initial_guess[:, :n_s] [lb, ub] = [u(initial_states, p) for u in model.x_bounds] lower_bound = initial_guess * 0 - numpy.inf lower_bound[:, n_s:] = lb upper_bound = initial_guess * 0 + numpy.inf upper_bound[:, n_s:] = ub test1 = max(lb.max(axis=0) - lb.min(axis=0)) test2 = max(ub.max(axis=0) - ub.min(axis=0)) if test1 > 0.00000001 or test2 > 0.00000001: raise Exception( "Not implemented: perfect foresight solution requires that controls have constant bounds." ) else: ignore_constraints = True lower_bound = None upper_bound = None nn = sh[0] * sh[1] fobj = lambda vec: det_residual(model, vec.reshape(sh), start_s, final_x, epsilons)[0].ravel() if not ignore_constraints: from dolo.numeric.optimize.ncpsolve import ncpsolve ff = lambda vec: det_residual(model, vec.reshape(sh), start_s, final_x, epsilons, jactype='sparse') from dolo.numeric.optimize.newton import newton x0 = initial_guess.ravel() sol, nit = ncpsolve(ff, lower_bound.ravel(), upper_bound.ravel(), initial_guess.ravel(), verbose=verbose, maxit=maxit, tol=tol, jactype='sparse') sol = sol.reshape(sh) else: from scipy.optimize import root from numpy import array # ff = lambda vec: det_residual(model, vec.reshape(sh), start_s, final_x, epsilons, jactype='full') ff = lambda vec: det_residual( model, vec.reshape( sh), start_s, final_x, epsilons, diff=False).ravel() x0 = initial_guess.ravel() sol = root(ff, x0, jac=False) res = ff(sol.x) sol = sol.x.reshape(sh) import pandas if 'auxiliary' in model.functions: colnames = model.symbols['states'] + model.symbols[ 'controls'] + model.symbols['auxiliaries'] # compute auxiliaries y = model.functions['auxiliary'](sol[:, :n_s], sol[:, n_s:], p) sol = numpy.column_stack([sol, y]) else: colnames = model.symbols['states'] + model.symbols['controls'] sol = numpy.column_stack([sol, epsilons]) colnames = colnames + model.symbols['shocks'] ts = pandas.DataFrame(sol, columns=colnames) return ts
def deterministic_solve(model, shocks=None, start_states=None, T=100, ignore_constraints=False, maxit=100, initial_guess=None, verbose=False, tol=1e-6): ''' Computes a perfect foresight simulation using a stacked-time algorithm. The initial state is specified either by providing a series of exogenous shocks and assuming the model is initially in equilibrium with the first value of the shock, or by specifying an initial value for the states. Parameters ---------- model: NumericModel "fg" or "fga" model to be solved shocks: ndarray :math:`n_e\\times N` matrix containing :math:`N` realizations of the shocks. :math:`N` must be smaller than :math:`T`. The exogenous process is assumed to remain constant and equal to its last value after `N` periods. start_states: ndarray or dict a vector with the value of initial states, or a calibration dictionary with the initial values of states and controls T: int horizon for the perfect foresight simulation maxit: int maximum number of iteration for the nonlinear solver verbose: boolean if True, the solver displays iterations tol: float stopping criterium for the nonlinear solver ignore_constraints: bool if True, complementarity constraints are ignored. Returns ------- pandas dataframe: a dataframe with T+1 observations of the model variables along the simulation (states, controls, auxiliaries). The first observation is the steady-state corresponding to the first value of the shocks. The simulation should return to a steady-state corresponding to the last value of the exogenous shocks. ''' # TODO: # if model.model_type == 'fga': # from dolo.compiler.converter import GModel_fg_from_fga # model = GModel_fg_from_fga(model) # definitions n_s = len(model.calibration['states']) n_x = len(model.calibration['controls']) if shocks == None: shocks = numpy.zeros( (len(model.calibration['shocks']),1)) # until last period, exogenous shock takes its last value epsilons = numpy.zeros( (T+1, shocks.shape[1])) epsilons[:(shocks.shape[0]-1),:] = shocks[1:,:] epsilons[(shocks.shape[0]-1):,:] = shocks[-1:,:] # final initial and final steady-states consistent with exogenous shocks if isinstance(start_states,dict): # at least that part is clear start_equilibrium = start_states start_s = start_equilibrium['states'] start_x = start_equilibrium['controls'] final_s = start_equilibrium['states'] final_x = start_equilibrium['controls'] elif isinstance(start_states, numpy.ndarray): start_s = start_states start_x = model.calibration['controls'] final_s = model.calibration['states'] final_x = model.calibration['controls'] else: # raise Exception("You must compute initial calibration yourself") final_dict = {model.symbols['shocks'][i]: shocks[i,-1] for i in range(len(model.symbols['shocks']))} start_dict = {model.symbols['shocks'][i]: shocks[i,0] for i in range(len(model.symbols['shocks']))} start_calib = find_deterministic_equilibrium( model, constraints=start_dict) final_calib = find_deterministic_equilibrium( model, constraints=start_dict) start_s = start_calib['states'] start_x = start_calib['controls'] final_s = final_calib['states'] final_x = final_calib['controls'] # if start_constraints: # ### we ignore start_constraints # start_dict.update(start_constraints) # final_equilibrium = start_constraints.copy() # else: # final_equilibrium = find_deterministic_equilibrium( model, constraints=final_dict) # final_s = final_equilibrium['states'] # final_x = final_equilibrium['controls'] # start_s = start_states # start_x = final_x #TODO: for start_x, it should be possible to use first order guess final = numpy.concatenate( [final_s, final_x] ) start = numpy.concatenate( [start_s, start_x] ) if verbose==True: print("Initial states : {}".format(start_s)) print("Final controls : {}".format(final_x)) p = model.calibration['parameters'] if initial_guess is None: initial_guess = numpy.row_stack( [start*(1-l) + final*l for l in linspace(0.0,1.0,T+1)] ) else: from pandas import DataFrame if isinstance( initial_guess, DataFrame ): initial_guess = array( initial_guess ).T.copy() initial_guess = initial_guess[:,:n_s+n_x] initial_guess[0,:n_s] = start_s initial_guess[-1,n_s:] = final_x sh = initial_guess.shape if model.x_bounds and not ignore_constraints: initial_states = initial_guess[:,:n_s] [lb, ub] = [ u( initial_states, p ) for u in model.x_bounds] lower_bound = initial_guess*0 - numpy.inf lower_bound[:, n_s:] = lb upper_bound = initial_guess*0 + numpy.inf upper_bound[:, n_s:] = ub test1 = max( lb.max(axis=0) - lb.min(axis=0) ) test2 = max( ub.max(axis=0) - ub.min(axis=0) ) if test1 >0.00000001 or test2>0.00000001: raise Exception("Not implemented: perfect foresight solution requires that controls have constant bounds.") else: ignore_constraints=True lower_bound = None upper_bound = None nn = sh[0]*sh[1] fobj = lambda vec: det_residual(model, vec.reshape(sh), start_s, final_x, epsilons)[0].ravel() if not ignore_constraints: from dolo.numeric.optimize.ncpsolve import ncpsolve ff = lambda vec: det_residual(model, vec.reshape(sh), start_s, final_x, epsilons, jactype='sparse') from dolo.numeric.optimize.newton import newton x0 = initial_guess.ravel() sol, nit = ncpsolve(ff, lower_bound.ravel(), upper_bound.ravel(), initial_guess.ravel(), verbose=verbose, maxit=maxit, tol=tol, jactype='sparse') sol = sol.reshape(sh) else: from scipy.optimize import root from numpy import array # ff = lambda vec: det_residual(model, vec.reshape(sh), start_s, final_x, epsilons, jactype='full') ff = lambda vec: det_residual(model, vec.reshape(sh), start_s, final_x, epsilons, diff=False).ravel() x0 = initial_guess.ravel() sol = root(ff, x0, jac=False) res = ff(sol.x) sol = sol.x.reshape(sh) import pandas if 'auxiliary' in model.functions: colnames = model.symbols['states'] + model.symbols['controls'] + model.symbols['auxiliaries'] # compute auxiliaries y = model.functions['auxiliary'](sol[:,:n_s], sol[:,n_s:], p) sol = numpy.column_stack([sol,y]) else: colnames = model.symbols['states'] + model.symbols['controls'] sol = numpy.column_stack([sol,epsilons]) colnames = colnames + model.symbols['shocks'] ts = pandas.DataFrame(sol, columns=colnames) return ts
g = model.functions['transition'] e_z = atleast_2d(linspace(0.0, 0.0, 10)).T start_s = model.calibration['states'].copy() start_s[0] = 1.5 import time #sol1 = deterministic_solve(model, shocks=e_z, T=50, use_pandas=True, ignore_constraints=True, start_s=start_s) #sol1 = deterministic_solve(model, T=50, use_pandas=True, ignore_constraints=True, start_s=start_s) from dolo.algos.steady_state import find_deterministic_equilibrium calib = find_deterministic_equilibrium(model) t2 = time.time() sol1 = deterministic_solve(model, start_states=start_s, T=50, use_pandas=True, ignore_constraints=False, verbose=True) t3 = time.time() t1 = time.time() sol2 = deterministic_solve(model,
e_z = atleast_2d( linspace(0.0, 0.0, 10) ).T start_s = model.calibration['states'].copy() start_s[0] = 1.5 import time #sol1 = deterministic_solve(model, shocks=e_z, T=50, use_pandas=True, ignore_constraints=True, start_s=start_s) #sol1 = deterministic_solve(model, T=50, use_pandas=True, ignore_constraints=True, start_s=start_s) from dolo.algos.steady_state import find_deterministic_equilibrium calib = find_deterministic_equilibrium(model) t2 = time.time() sol1 = deterministic_solve(model, start_states=start_s, T=50, use_pandas=True, ignore_constraints=False, verbose=True) t3 = time.time() t1 = time.time() sol2 = deterministic_solve(model, start_states=start_s, T=50, use_pandas=True, ignore_constraints=True, verbose=True) t2 = time.time()