def test_simple_solve(self): x0 = np.array([0.5,0.5,0.5,0.5]) lb = np.array([0.0,0.6,0.0,0.0]) ub = np.array([1.0,1.0,1.0,0.4]) fval = np.array([ 0.5, 0.5, 0.1,0.5 ]) jac = np.array([ [1.0,0.2,0.1,0.0], [1.0,0.2,0.1,0.0], [0.0,1.0,0.2,0.0], [0.1,1.0,0.2,0.1] ]) N = 10 d = len(fval) from dolo.numeric.solver import solver sol_fsolve = solver(josephy, x0, method='fsolve') sol_lmmcp = solver(josephy, x0, method='lmmcp') from numpy.testing import assert_almost_equal assert_almost_equal(sol_fsolve, sol_lmmcp)
def find_steady_state(model, e, force_values=None): ''' Finds the steady state corresponding to exogenous shocks :math:`e`. :param model: an "fga" model. :param e: a vector with the value for the exogenous shocks. :param force_values: (optional) a vector where finite values override the equilibrium conditions. For instance a vector :math:`[0,nan,nan]` would impose that the first state must be equal to 0, while the two next ones, will be determined by the model equations. This is useful, when the deterministic model has a unit root. :return: a list containing a vector for the steady-states and the corresponding steady controls. ''' s0 = model.calibration['states'] x0 = model.calibration['controls'] p = model.calibration['parameters'] z = numpy.concatenate([s0, x0]) e = numpy.atleast_2d(e.ravel()).T if force_values is not None: inds = numpy.where( numpy.isfinite( force_values ) )[0] vals = force_values[inds] def fobj(z): s = numpy.atleast_2d( z[:len(s0)] ).T x = numpy.atleast_2d( z[len(s0):] ).T S = model.functions['transition'](s,x,e,p) if force_values is not None: S[inds,0] = vals r = model.functions['arbitrage'](s,x,s,x,p) res = numpy.concatenate([S-s, r]) return res from dolo.numeric.solver import solver steady_state = solver(fobj, z, method='fsolve') return [steady_state[:len(s0)], steady_state[len(s0):]]
def test_solver(self): from dolo.numeric.solver import solver x0=np.array( [1.25, 0.00, 0.00, 0.50] ) lb=np.array( [0.00, 0.00, 0.00, 0.00] ) ub=np.array( [1e20, 1e20, 1e20, 1e20] ) resp = solver(josephy, x0, lb, ub, verbose=True, jac=Djosephy) sol = np.array([1.224746243, -0.0000, 0.0000, 0.5000]) assert( abs(sol - resp).max()<1e-6 )
def test_simple_solve(self): x0 = np.array([0.5, 0.5, 0.5, 0.5]) lb = np.array([0.0, 0.6, 0.0, 0.0]) ub = np.array([1.0, 1.0, 1.0, 0.4]) fval = np.array([0.5, 0.5, 0.1, 0.5]) jac = np.array([[1.0, 0.2, 0.1, 0.0], [1.0, 0.2, 0.1, 0.0], [0.0, 1.0, 0.2, 0.0], [0.1, 1.0, 0.2, 0.1]]) N = 10 d = len(fval) from dolo.numeric.solver import solver sol_fsolve = solver(josephy, x0, method='fsolve') sol_lmmcp = solver(josephy, x0, method='lmmcp') from numpy.testing import assert_almost_equal assert_almost_equal(sol_fsolve, sol_lmmcp)
def test_solver(self): from dolo.numeric.solver import solver fun = lambda x: -josephy(x) dfun = lambda x: -Djosephy(x) x0=np.array( [1.25, 0.00, 0.00, 0.50] ) lb=np.array( [0.00, 0.00, 0.00, 0.00] ) ub=np.array( [1e20, 1e20, 1e20, 1e20] ) resp = solver( fun, x0, lb, ub, verbose=True, jac=dfun, method='lmmcp') sol = np.array([1.22474487, -0.0000, 0.0000, 0.5000]) assert( abs(sol - resp).max()<1e-6 )
def solve_for_steady_state(self,y0=None): import numpy as np from dolo.numeric.solver import solver [y,x,params] = [np.array(e) for e in self.read_calibration() ] if y0 == None: y0 = np.array(y) else: y0 = np.array(y0) f_static = self.compiler.compute_static_pfile(max_order=0) # TODO: use derivatives... fobj = lambda z: f_static(z,x,params)[0] try: opts = {'eps1': 1e-12, 'eps2': 1e-20} sol = solver(fobj,y0,method='lmmcp',options=opts) return sol except Exception as e: print('The steady-state could not be found.') raise e
def solve_for_steady_state(self, y0=None): import numpy as np from dolo.numeric.solver import solver [y, x, params] = [np.array(e) for e in self.read_calibration()] if y0 == None: y0 = np.array(y) else: y0 = np.array(y0) f_static = self.compiler.compute_static_pfile( max_order=0) # TODO: use derivatives... fobj = lambda z: f_static(z, x, params)[0] try: opts = {'eps1': 1e-12, 'eps2': 1e-20} sol = solver(fobj, y0, method='lmmcp', options=opts) return sol except Exception as e: print 'The steady-state could not be found.' raise e
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 global_solve(model, bounds=None, initial_dr=None, interp_type='smolyak', pert_order=2, T=200, n_s=2, N_e=40, maxit=500, polish=True, memory_hungry=True, smolyak_order=3, interp_orders=None): [y,x,parms] = model.read_calibration() sigma = model.read_covariances() if initial_dr == None: initial_dr = approximate_controls(model, order=pert_order, substitute_auxiliary=True, solve_systems=True) if bounds == None: 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, ]) if interp_orders == None: interp_orders = [5]*bounds.shape[1] if interp_type == 'smolyak': from dolo.numeric.smolyak import SmolyakGrid sg = SmolyakGrid( bounds, smolyak_order ) elif interp_type == 'spline': polish = False from dolo.numeric.interpolation import SplineInterpolation sg = SplineInterpolation( bounds[0,:], bounds[1,:], interp_orders ) elif interp_type == 'linear': from dolo.numeric.interpolation import MLinInterpolation sg = MLinInterpolation( bounds[0,:], bounds[1,:], interp_orders ) xinit = initial_dr(sg.grid) xinit = xinit.real # just in case... from dolo.compiler.compiler_global import GlobalCompiler, time_iteration, stochastic_residuals_2, stochastic_residuals_3 gc = GlobalCompiler(model, substitute_auxiliary=True, solve_systems=True) from dolo.numeric.quantization import quantization_weights # number of shocks [weights,epsilons] = quantization_weights(N_e, sigma) dr = time_iteration(sg.grid, sg, xinit, gc.f, gc.g, parms, epsilons, weights, maxit=maxit, nmaxit=50 ) if polish: # this will only work with smolyak from dolo.compiler.compiler_global import GlobalCompiler, time_iteration, stochastic_residuals_2, stochastic_residuals_3 from dolo.numeric.solver import solver xinit = dr(dr.grid) dr.fit_values(xinit) shape = dr.theta.shape theta_0 = dr.theta.copy().flatten() if memory_hungry: fobj = lambda t: stochastic_residuals_3(dr.grid, t, dr, gc.f, gc.g, parms, epsilons, weights, shape, no_deriv=True)[0] dfobj = lambda t: stochastic_residuals_3(dr.grid, t, dr, gc.f, gc.g, parms, epsilons, weights, shape)[1] else : fobj = lambda t: stochastic_residuals_2(dr.grid, t, dr, gc.f, gc.g, parms, epsilons, weights, shape, no_deriv=True) dfobj = lambda t: stochastic_residuals_2(dr.grid, t, dr, gc.f, gc.g, parms, epsilons, weights, shape)[1] theta = solver(fobj, theta_0, jac=dfobj, verbose=True) dr.theta = theta.reshape(shape) return dr
def time_iteration(grid, interp, xinit, f, g, parms, epsilons, weights, x_bounds=None, options={}, serial_grid=True, verbose=True, method='lmmcp', maxit=500, nmaxit=5, backsteps=10, hook=None): from dolo.numeric.solver import solver from dolo.numeric.newton import newton_solver if serial_grid: #fun = lambda x: step_residual(grid, x, interp, f, g, parms, epsilons, weights, x_bounds=x_bounds, with_derivatives=False)[0] #dfun = lambda x: step_residual(grid, x, interp, f, g, parms, epsilons, weights, x_bounds=x_bounds)[1] fun = lambda x: step_residual(grid, x, interp, f, g, parms, epsilons, weights, x_bounds=x_bounds) else: fun = lambda x: step_residual(grid, x, interp, f, g, parms, epsilons, weights, x_bounds=x_bounds, serial_grid=False, with_derivatives=False)[0] dfun = lambda x: step_residual(grid, x, interp, f, g, parms, epsilons, weights, x_bounds=x_bounds, serial_grid=False)[1] # tol = 1e-8 ## import time t1 = time.time() err = 1 x0 = xinit it = 0 verbit = True if verbose=='full' else False if x_bounds: [lb,ub] = x_bounds(grid,parms) else: lb = None ub = None if verbose: s = "|Iteration\t|\tStep\t\t\t|\tTime (s)\t|" nnn = len(s.replace('\t',' '*4)) print('-'*nnn) print(s) print('-'*nnn) while err > tol and it < maxit: t_start = time.time() it +=1 interp.fit_values(x0) if serial_grid: [x,nit] = newton_solver(fun,x0,lb=lb,ub=ub,infos=True, backsteps=backsteps, maxit=nmaxit) else: x = solver(fun, x0, lb=lb, ub=ub, method=method, jac=dfun, verbose=verbit, options=options) nit = 0 # we restrict the solution to lie inside the boundaries if x_bounds: x = np.maximum(np.minimum(ub,x),lb) # res = abs(fun(x)).max() err = abs(x-x0).max() t_finish = time.time() elapsed = t_finish - t_start if verbose: print("\t\t{}\t|\t{:e}\t|\t{:f}\t|\t{}".format(it,err,elapsed,nit)) x0 = x0 + (x-x0) if hook: hook(interp,it,err) if False in np.isfinite(x0): print('iteration {} failed : non finite value') return [x0, x] if it == maxit: import warnings warnings.warn(UserWarning("Maximum number of iterations reached")) t2 = time.time() print('Elapsed: {}'.format(t2 - t1)) return interp
def time_iteration( grid, interp, xinit, f, g, parms, epsilons, weights, x_bounds=None, options={}, serial_grid=True, verbose=True, method="lmmcp", maxit=500, nmaxit=5, backsteps=10, hook=None, ): from dolo.numeric.solver import solver from dolo.numeric.newton import newton_solver if serial_grid: # fun = lambda x: step_residual(grid, x, interp, f, g, parms, epsilons, weights, x_bounds=x_bounds, with_derivatives=False)[0] # dfun = lambda x: step_residual(grid, x, interp, f, g, parms, epsilons, weights, x_bounds=x_bounds)[1] fun = lambda x: step_residual(grid, x, interp, f, g, parms, epsilons, weights, x_bounds=x_bounds) else: fun = lambda x: step_residual( grid, x, interp, f, g, parms, epsilons, weights, x_bounds=x_bounds, serial_grid=False, with_derivatives=False, )[0] dfun = lambda x: step_residual( grid, x, interp, f, g, parms, epsilons, weights, x_bounds=x_bounds, serial_grid=False )[1] # tol = 1e-8 ## import time t1 = time.time() err = 1 x0 = xinit it = 0 verbit = True if verbose == "full" else False if x_bounds: [lb, ub] = x_bounds(grid, parms) else: lb = None ub = None if verbose: s = "|Iteration\t|\tStep\t\t\t|\tTime (s)\t|" nnn = len(s.replace("\t", " " * 4)) print("-" * nnn) print(s) print("-" * nnn) while err > tol and it < maxit: t_start = time.time() it += 1 interp.fit_values(x0) if serial_grid: [x, nit] = newton_solver(fun, x0, lb=lb, ub=ub, infos=True, backsteps=backsteps, maxit=nmaxit) else: x = solver(fun, x0, lb=lb, ub=ub, method=method, jac=dfun, verbose=verbit, options=options) nit = 0 # we restrict the solution to lie inside the boundaries if x_bounds: x = np.maximum(np.minimum(ub, x), lb) # res = abs(fun(x)).max() err = abs(x - x0).max() t_finish = time.time() elapsed = t_finish - t_start if verbose: print("\t\t{}\t|\t{:e}\t|\t{:f}\t|\t{}".format(it, err, elapsed, nit)) x0 = x0 + (x - x0) if hook: hook(interp, it, err) if False in np.isfinite(x0): print("iteration {} failed : non finite value") return [x0, x] if it == maxit: import warnings warnings.warn(UserWarning("Maximum number of iterations reached")) t2 = time.time() print("Elapsed: {}".format(t2 - t1)) return interp
def deterministic_solve(model, shocks=None, T=100, use_pandas=True, ignore_constraints=False, start_s=None, verbose=False): ''' Computes a perfect foresight simulation using a stacked-time algorithm. :param model: an "fga" model :param shocks: a :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. :param T: the horizon for the perfect foresight simulation :param use_pandas: if True, returns a pandas dataframe, else the simulation matrix :param ignore_constraints: if True, complementarity constraintes are ignored. :return: 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( (shocks.shape[0], T)) epsilons[:,:shocks.shape[1]] = shocks epsilons[:,shocks.shape[1:]] = shocks[:,-1:] # final initial and final steady-states consistent with exogenous shocks start = find_steady_state( model, numpy.atleast_2d(epsilons[:,0:1]), force_values=start_s) final = find_steady_state( model, numpy.atleast_2d(epsilons[:,-1:])) start_s = start[0] final_x = final[1] final = numpy.concatenate( final ) start = numpy.concatenate( start ) p = model.calibration['parameters'] initial_guess = numpy.concatenate( [start*(1-l) + final*l for l in linspace(0.0,1.0,T+1)] ) initial_guess = initial_guess.reshape( (-1, n_s + n_x)).T 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=1) - lb.min(axis=1) ) test2 = max( ub.max(axis=1) - ub.min(axis=1) ) 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() dfobj = lambda vec: det_residual(model, vec.reshape(sh), start_s, final_x, epsilons)[1].reshape((nn,nn)) from dolo.numeric.solver import solver if not ignore_constraints: sol = solver(fobj, initial_guess, jac=dfobj, lb=lower_bound, ub=upper_bound, method='ncpsolve', serial_problem=False, verbose=verbose ) else: sol = solver(fobj, initial_guess, jac=dfobj, method='fsolve', serial_problem=False, verbose=verbose ) if use_pandas: import pandas colnames = model.symbols['states'] + model.symbols['controls'] + model.symbols['auxiliary'] # compute auxiliaries y = model.functions['auxiliary'](sol[:n_s,:], sol[n_s:,:], p) sol = numpy.row_stack([sol,y]) ts = pandas.DataFrame(sol.T, columns=colnames) return ts else: return sol
def test_serial_problems(self): from numpy import inf import numpy fun = lambda x: [-josephy(x), -Djosephy(x)] x0=np.array( [1.25, 0.01, 0.01, 0.50] ) lb=np.array( [0.00, 0.00, 0.00, 0.00] ) ub=np.array( [inf, inf, inf, inf] ) resp = ncpsolve(fun, lb, ub, x0, tol=1e-15) sol = np.array( [ 1.22474487e+00, 0.00000000e+00, 3.60543164e-17, 5.00000000e-01]) from numpy.testing import assert_almost_equal, assert_equal assert_almost_equal(sol, resp) N = 10 d = len(x0) serial_sol_check = np.zeros((d,N)) for n in range(N): serial_sol_check[:,n] = resp[0] s_x0 = np.column_stack([x0]*N) s_lb = np.column_stack([lb]*N) s_ub = np.column_stack([ub]*N) def serial_fun(xvec, deriv=None): resp = np.zeros( (d,N) ) if deriv=='serial': dresp = np.zeros( (d,d,N) ) elif deriv=='full': dresp = np.zeros( (d,N,d,N) ) for n in range(N): [v, dv] = fun(xvec[:,n]) resp[:,n] = v if deriv=='serial': dresp[:,:,n] = dv elif deriv=='full': dresp[:,n,:,n] = dv # if deriv=='full': # dresp = dresp.swapaxes(0,2).swapaxes(1,3) if deriv is None: return resp else: return [resp, dresp] serial_fun_val = lambda x: serial_fun(x) serial_fun_serial_jac = lambda x: serial_fun(x,deriv='serial')[1] serial_fun_full_jac = lambda x: serial_fun(x,deriv='full')[1] from dolo.numeric.solver import solver print("Serial Bounded solution : ncpsolve") serial_sol_with_bounds_without_jac = solver( serial_fun_val, s_x0, lb=s_lb, ub=s_ub, method='ncpsolve', serial_problem=True) print("Serial Bounded solution (with jacobian) : ncpsolve") serial_sol_with_bounds_with_jac = solver( serial_fun_val, s_x0, s_lb, s_ub, jac=serial_fun_serial_jac, method='ncpsolve', serial_problem=True) print("Bounded solution : ncpsolve") sol_with_bounds_without_jac = solver( serial_fun_val, s_x0, s_lb, s_ub, method='ncpsolve', serial_problem=False) print("Bounded solution (with jacobian) : ncpsolve") sol_with_bounds_with_jac = solver( serial_fun_val, s_x0, s_lb, s_ub, jac=serial_fun_full_jac, method='ncpsolve', serial_problem=False) print("Serial Unbounded solution : ncpsolve") serial_sol_without_bounds_without_jac = solver( serial_fun_val, s_x0, method='newton', serial_problem=True) print("Unbounded solution : fsolve") sol_without_bounds_without_jac = solver( serial_fun_val, s_x0, method='fsolve', serial_problem=False) print("Unbounded solution (with jacobian) : fsolve") sol_without_bounds = solver( serial_fun_val, s_x0, jac=serial_fun_full_jac, method='fsolve', serial_problem=False) print("Unbounded solution : lmmcp") sol_without_bounds = solver( serial_fun_val, s_x0, jac=serial_fun_full_jac, method='lmmcp', serial_problem=False)
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 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 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=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, 0) for v in pf_names] res_vars = [Variable('res_' + str(i), 0) 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.check() 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() # now, we need to solve for the optimal portfolio coefficients from dolo.numeric.perturbations_to_states import approximate_controls 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] 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] 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=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 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_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 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 test_serial_problems(self): from numpy import inf import numpy fun = lambda x: [-josephy(x), -Djosephy(x)] x0 = np.array([1.25, 0.01, 0.01, 0.50]) lb = np.array([0.00, 0.00, 0.00, 0.00]) ub = np.array([inf, inf, inf, inf]) resp = ncpsolve(fun, lb, ub, x0, tol=1e-15) sol = np.array( [1.22474487e+00, 0.00000000e+00, 3.60543164e-17, 5.00000000e-01]) from numpy.testing import assert_almost_equal, assert_equal assert_almost_equal(sol, resp) N = 10 d = len(x0) serial_sol_check = np.zeros((d, N)) for n in range(N): serial_sol_check[:, n] = resp[0] s_x0 = np.column_stack([x0] * N) s_lb = np.column_stack([lb] * N) s_ub = np.column_stack([ub] * N) def serial_fun(xvec, deriv=None): resp = np.zeros((d, N)) if deriv == 'serial': dresp = np.zeros((d, d, N)) elif deriv == 'full': dresp = np.zeros((d, N, d, N)) for n in range(N): [v, dv] = fun(xvec[:, n]) resp[:, n] = v if deriv == 'serial': dresp[:, :, n] = dv elif deriv == 'full': dresp[:, n, :, n] = dv # if deriv=='full': # dresp = dresp.swapaxes(0,2).swapaxes(1,3) if deriv is None: return resp else: return [resp, dresp] serial_fun_val = lambda x: serial_fun(x) serial_fun_serial_jac = lambda x: serial_fun(x, deriv='serial')[1] serial_fun_full_jac = lambda x: serial_fun(x, deriv='full')[1] from dolo.numeric.solver import solver print("Serial Bounded solution : ncpsolve") serial_sol_with_bounds_without_jac = solver(serial_fun_val, s_x0, lb=s_lb, ub=s_ub, method='ncpsolve', serial_problem=True) print("Serial Bounded solution (with jacobian) : ncpsolve") serial_sol_with_bounds_with_jac = solver(serial_fun_val, s_x0, s_lb, s_ub, jac=serial_fun_serial_jac, method='ncpsolve', serial_problem=True) print("Bounded solution : ncpsolve") sol_with_bounds_without_jac = solver(serial_fun_val, s_x0, s_lb, s_ub, method='ncpsolve', serial_problem=False) print("Bounded solution (with jacobian) : ncpsolve") sol_with_bounds_with_jac = solver(serial_fun_val, s_x0, s_lb, s_ub, jac=serial_fun_full_jac, method='ncpsolve', serial_problem=False) print("Serial Unbounded solution : ncpsolve") serial_sol_without_bounds_without_jac = solver(serial_fun_val, s_x0, method='newton', serial_problem=True) print("Unbounded solution : fsolve") sol_without_bounds_without_jac = solver(serial_fun_val, s_x0, method='fsolve', serial_problem=False) print("Unbounded solution (with jacobian) : fsolve") sol_without_bounds = solver(serial_fun_val, s_x0, jac=serial_fun_full_jac, method='fsolve', serial_problem=False) print("Unbounded solution : lmmcp") sol_without_bounds = solver(serial_fun_val, s_x0, jac=serial_fun_full_jac, method='lmmcp', serial_problem=False)
def time_iteration(grid, dr, xinit, f, g, parms, epsilons, weights, x_bounds=None, tol = 1e-8, serial_grid=True, numdiff=True, verbose=True, method='ncpsolve', maxit=500, nmaxit=5, backsteps=10, hook=None, options={}): from dolo.numeric.solver import solver import time if numdiff == True: fun = lambda x: step_residual(grid, x, dr, f, g, parms, epsilons, weights, x_bounds=x_bounds, with_derivatives=False) else: fun = lambda x: step_residual(grid, x, dr, f, g, parms, epsilons, weights, x_bounds=x_bounds) ## t1 = time.time() err = 1 x0 = xinit it = 0 verbit = True if verbose=='full' else False if x_bounds: lb = x_bounds[0](grid,parms) ub = x_bounds[1](grid,parms) else: lb = None ub = None if verbose: headline = '{0:^5} | {1:10} | {2:8} | {3:8} | {4:3} |'.format( 'N',' Error', 'Gain','Time', 'nit' ) stars = '-'*len(headline) print(stars) print(headline) print(stars) err_0 = 1 while err > tol and it < maxit: t_start = time.time() it +=1 dr.set_values(x0) [x,nit] = solver(fun, x0, lb=lb, ub=ub, method=method, infos=True, verbose=verbit, serial_problem=True) err = abs(x-x0).max() err_SA = err/err_0 err_0 = err t_finish = time.time() elapsed = t_finish - t_start if verbose: print('{0:5} | {1:10.3e} | {2:8.3f} | {3:8.3f} | {4:3} |'.format( it, err, err_SA, elapsed, nit )) x0 = x0 + (x-x0) if hook: hook(dr,it,err) if False in np.isfinite(x0): print('iteration {} failed : non finite value') return [x0, x] if it == maxit: import warnings warnings.warn(UserWarning("Maximum number of iterations reached")) t2 = time.time() if verbose: print('Elapsed: {}'.format(t2 - t1)) return dr