def test_denhaan_errors(): from dolo import yaml_import from dolo.algos.time_iteration import time_iteration as global_solve model = yaml_import('examples/models/rbc.yaml') from dolo.algos.perturbations import approximate_controls dr = approximate_controls(model) dr_global = global_solve(model, interp_type='smolyak', smolyak_order=4, verbose=False) sigma = model.covariances model.sigma = sigma from dolo.algos.accuracy import denhaanerrors denerr_1 = denhaanerrors(model, dr) denerr_2 = denhaanerrors(model, dr_global) print(denerr_1) print(denerr_2) print(denerr_2['max_errors'][0]) assert (max(denerr_2['max_errors']) < 10 - 7 ) # errors with solyak colocations at order 4 are very small
def test_omega_errors(): from dolo import yaml_import from dolo.algos.time_iteration import time_iteration as global_solve model = yaml_import('examples/models/rbc.yaml') from dolo.algos.perturbations import approximate_controls dr = approximate_controls(model) dr_global = global_solve(model, smolyak_order=3, verbose=False, pert_order=1) sigma = model.covariances model.sigma = sigma s_0 = dr.S_bar from dolo.algos.accuracy import omega res_1 = omega(model, dr, orders=[10, 10], time_discount=0.96) res_2 = omega(model, dr_global) print(res_1) print(res_2)
def test_denhaan_errors(): from dolo import yaml_import from dolo.algos.time_iteration import time_iteration as global_solve model = yaml_import('examples/models/rbc.yaml') from dolo.algos.perturbations import approximate_controls dr = approximate_controls(model) dr_global = global_solve(model, interp_type='smolyak', smolyak_order=4, verbose=False) sigma = model.covariances model.sigma = sigma from dolo.algos.accuracy import denhaanerrors denerr_1 = denhaanerrors(model, dr) denerr_2 = denhaanerrors(model, dr_global) print(denerr_1) print(denerr_2) print(denerr_2['max_errors'][0]) assert( max(denerr_2['max_errors']) < 10-7) # errors with solyak colocations at order 4 are very small
def test_omega_errors(): from dolo import yaml_import from dolo.algos.time_iteration import time_iteration as global_solve model = yaml_import('examples/models/rbc.yaml') from dolo.algos.perturbations import approximate_controls dr = approximate_controls(model) dr_global = global_solve(model, smolyak_order=3, verbose=False, pert_order=1) sigma = model.covariances model.sigma = sigma s_0 = dr.S_bar from dolo.algos.accuracy import omega res_1 = omega( model, dr, orders=[10,10], time_discount=0.96) res_2 = omega( model, dr_global) print(res_1) print(res_2)
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 if __name__ == '__main__': from dolo import * model = yaml_import("/home/pablo/Documents/Research/Thesis/chapter_1/code/portfolios.yaml") model.set_calibration(dumb=1) from dolo.algos.perturbations import approximate_controls dr = approximate_controls(model) print(dr)
def time_iteration(model, bounds=None, verbose=False, initial_dr=None, pert_order=1, with_complementarities=True, interp_type='smolyak', smolyak_order=3, interp_orders=None, maxit=500, tol=1e-8, integration='gauss-hermite', integration_orders=None, T=200, n_s=3, hook=None): """Finds a global solution for ``model`` using backward time-iteration. Parameters: ----------- model: NumericModel "fg" or "fga" model to be solved bounds: ndarray boundaries for approximations. First row contains minimum values. Second row contains maximum values. verbose: boolean if True, display iterations initial_dr: decision rule initial guess for the decision rule pert_order: {1} if no initial guess is supplied, the perturbation solution at order ``pert_order`` is used as initial guess with_complementarities: boolean (True) if False, complementarity conditions are ignored interp_type: {`smolyak`, `spline`} type of interpolation to use for future controls smolyak_orders: int parameter ``l`` for Smolyak interpolation interp_orders: 1d array-like list of integers specifying the number of nods in each dimension if ``interp_type="spline" `` Returns: -------- decision rule object (SmolyakGrid or MultivariateSplines) """ def vprint(t): if verbose: print(t) parms = model.calibration['parameters'] sigma = model.covariances if initial_dr == None: if pert_order == 1: from dolo.algos.perturbations import approximate_controls initial_dr = approximate_controls(model) if pert_order > 1: raise Exception("Perturbation order > 1 not supported (yet).") if interp_type == 'perturbations': return initial_dr if bounds is not None: pass elif model.options and 'approximation_space' in model.options: vprint('Using bounds specified by model') approx = model.options['approximation_space'] a = approx['a'] b = approx['b'] bounds = numpy.row_stack([a, b]) bounds = numpy.array(bounds, dtype=float) else: vprint('Using asymptotic bounds given by first 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, ]) 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) if integration == 'optimal_quantization': from dolo.numeric.discretization import quantization_nodes # number of shocks [epsilons, weights] = quantization_nodes(N_e, sigma) elif integration == 'gauss-hermite': from dolo.numeric.discretization 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') # TODO: transpose grid = dr.grid xinit = initial_dr(grid) xinit = xinit.real # just in case... from dolo.algos.convert import get_fg_functions f, g = get_fg_functions(model) import time fun = lambda x: step_residual(grid, x, dr, f, g, parms, epsilons, weights) ## t1 = time.time() err = 1 x0 = xinit it = 0 verbit = True if verbose == 'full' else False if with_complementarities: lbfun = model.functions['arbitrage_lb'] ubfun = model.functions['arbitrage_ub'] lb = lbfun(grid, parms) ub = ubfun(grid, parms) else: lb = None ub = None if verbose: headline = '|{0:^4} | {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) from dolo.numeric.optimize.newton import serial_newton, SerialDifferentiableFunction from dolo.numeric.optimize.ncpsolve import ncpsolve sdfun = SerialDifferentiableFunction(fun) if with_complementarities: [x, nit] = ncpsolve(sdfun, lb, ub, x0, verbose=verbit) else: [x, nit] = serial_newton(sdfun, x0, verbose=verbit) 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:4} | {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(stars) print('Elapsed: {} seconds.'.format(t2 - t1)) print(stars) return dr
def time_iteration(model, bounds=None, verbose=False, initial_dr=None, pert_order=1, with_complementarities=True, interp_type='smolyak', smolyak_order=3, interp_orders=None, maxit=500, tol=1e-8, integration='gauss-hermite', integration_orders=None, T=200, n_s=3, hook=None): """Finds a global solution for ``model`` using backward time-iteration. Parameters: ----------- model: NumericModel "fg" or "fga" model to be solved bounds: ndarray boundaries for approximations. First row contains minimum values. Second row contains maximum values. verbose: boolean if True, display iterations initial_dr: decision rule initial guess for the decision rule pert_order: {1} if no initial guess is supplied, the perturbation solution at order ``pert_order`` is used as initial guess with_complementarities: boolean (True) if False, complementarity conditions are ignored interp_type: {`smolyak`, `spline`} type of interpolation to use for future controls smolyak_orders: int parameter ``l`` for Smolyak interpolation interp_orders: 1d array-like list of integers specifying the number of nods in each dimension if ``interp_type="spline" `` Returns: -------- decision rule object (SmolyakGrid or MultivariateSplines) """ def vprint(t): if verbose: print(t) parms = model.calibration['parameters'] sigma = model.covariances if initial_dr == None: if pert_order==1: from dolo.algos.perturbations import approximate_controls initial_dr = approximate_controls(model) if pert_order>1: raise Exception("Perturbation order > 1 not supported (yet).") if interp_type == 'perturbations': return initial_dr if bounds is not None: pass elif model.options and 'approximation_space' in model.options: vprint('Using bounds specified by model') approx = model.options['approximation_space'] a = approx['a'] b = approx['b'] bounds = numpy.row_stack([a, b]) bounds = numpy.array(bounds, dtype=float) else: vprint('Using asymptotic bounds given by first 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, ]) 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) if integration == 'optimal_quantization': from dolo.numeric.discretization import quantization_nodes # number of shocks [epsilons, weights] = quantization_nodes(N_e, sigma) elif integration == 'gauss-hermite': from dolo.numeric.discretization 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') # TODO: transpose grid = dr.grid xinit = initial_dr(grid) xinit = xinit.real # just in case... from dolo.algos.convert import get_fg_functions f,g = get_fg_functions(model) import time fun = lambda x: step_residual(grid, x, dr, f, g, parms, epsilons, weights) ## t1 = time.time() err = 1 x0 = xinit it = 0 verbit = True if verbose=='full' else False if with_complementarities: lbfun = model.functions['arbitrage_lb'] ubfun = model.functions['arbitrage_ub'] lb = lbfun(grid, parms) ub = ubfun(grid, parms) else: lb = None ub = None if verbose: headline = '|{0:^4} | {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) from dolo.numeric.optimize.newton import serial_newton, SerialDifferentiableFunction from dolo.numeric.optimize.ncpsolve import ncpsolve sdfun = SerialDifferentiableFunction(fun) if with_complementarities: [x,nit] = ncpsolve(sdfun, lb, ub, x0, verbose=verbit) else: [x,nit] = serial_newton(sdfun, x0, verbose=verbit) 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:4} | {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(stars) print('Elapsed: {} seconds.'.format(t2 - t1)) print(stars) return dr