def test_interpolation_time(self): d = 3 l = 5 n_x = 1 N = 1000 from numpy import column_stack, minimum, maximum smin = [-1]*d smax = [1]*d from dolo.numeric.interpolation.smolyak import SmolyakGrid sg = SmolyakGrid(smin,smax,l) print(sg.grid.shape) from numpy import exp values = column_stack( [sg.grid[:,0] + exp(sg.grid[:,0])]*n_x ) print(values.shape) sg.set_values(values) from numpy import random points = random.rand( d*N ) points = minimum(points,1) points = maximum(points,-1) points = points.reshape( (N,d) ) # I need to add the corners of the grid ! import time t = time.time() for i in range(10): test1 = sg(points) s = time.time() print('Smolyak : {}'.format(s-t))
def test_interpolation_time(self): d = 3 l = 5 n_x = 1 N = 1000 from numpy import column_stack, minimum, maximum smin = [-1] * d smax = [1] * d from dolo.numeric.interpolation.smolyak import SmolyakGrid sg = SmolyakGrid(smin, smax, l) print(sg.grid.shape) from numpy import exp values = column_stack([sg.grid[:, 0] + exp(sg.grid[:, 0])] * n_x) print(values.shape) sg.set_values(values) from numpy import random points = random.rand(d * N) points = minimum(points, 1) points = maximum(points, -1) points = points.reshape((N, d)) # I need to add the corners of the grid ! import time t = time.time() for i in range(10): test1 = sg(points) s = time.time() print('Smolyak : {}'.format(s - t))
def test_smolyak(self): import numpy f = lambda x: numpy.column_stack([ x[:,0] * x[:,1]**0.5, x[:,1] * x[:,1] - x[:,0] * x[:,0] ]) smin = [0.5,0.1], smax = [2,3] bounds = numpy.row_stack([smin,smax]) from dolo.numeric.interpolation.smolyak import SmolyakGrid sg = SmolyakGrid(smin,smax,3) values = f(sg.grid) sg.set_values(values) theta_0 = sg.theta.copy() def fobj(theta): sg.theta = theta return sg(sg.grid) fobj(theta_0)
def test_smolyak_plot_3d(selfs): import numpy from dolo.numeric.interpolation.smolyak import SmolyakGrid bounds = numpy.column_stack([[-1, 1]] * 3) sg = SmolyakGrid(bounds[0, :], bounds[1, :], 3) sg.plot_grid()
def test_interpolation_time(self): d = 3 l = 5 n_x = 1 N = 1000 from numpy import row_stack, minimum, maximum smin = [-1]*d smax = [1]*d from dolo.numeric.interpolation.smolyak import SmolyakGrid sg = SmolyakGrid(smin,smax,l) from numpy import exp values = row_stack( [sg.grid[0,:] + exp(sg.grid[1,:])]*n_x ) sg.set_values(values) from numpy import random points = random.rand( d*N ) points = minimum(points,1) points = maximum(points,-1) points = points.reshape( (d,N) ) # I need to add the corners of the grid ! import time t = time.time() for i in range(10): test1 = sg(points) s = time.time() print('Smolyak : {}'.format(s-t)) from dolo.numeric.interpolation.interpolation import SparseLinear sp = SparseLinear(smin,smax,l) xvalues = sg(sp.grid) sp.set_values(xvalues) t = time.time() for i in range(10): test2 = sp(points) s = time.time() print('Sparse linear : {}'.format(s-t)) import numpy if False in numpy.isfinite(test2): print('Problem')
def test_interpolation_time(self): d = 3 l = 5 n_x = 1 N = 1000 from numpy import row_stack, minimum, maximum smin = [-1] * d smax = [1] * d from dolo.numeric.interpolation.smolyak import SmolyakGrid sg = SmolyakGrid(smin, smax, l) from numpy import exp values = row_stack([sg.grid[0, :] + exp(sg.grid[1, :])] * n_x) sg.set_values(values) from numpy import random points = random.rand(d * N) points = minimum(points, 1) points = maximum(points, -1) points = points.reshape((d, N)) # I need to add the corners of the grid ! import time t = time.time() for i in range(10): test1 = sg(points) s = time.time() print('Smolyak : {}'.format(s - t)) from dolo.numeric.interpolation.interpolation import SparseLinear sp = SparseLinear(smin, smax, l) xvalues = sg(sp.grid) sp.set_values(xvalues) t = time.time() for i in range(10): test2 = sp(points) s = time.time() print('Sparse linear : {}'.format(s - t)) import numpy if False in numpy.isfinite(test2): print('Problem')
def __init__(self, smin, smax, l): from dolo.numeric.interpolation.smolyak import SmolyakGrid sg = SmolyakGrid(smin, smax, l) self.smin = array(smin) self.smax = array(smax) self.bounds = row_stack([smin, smax]) vertices = cartesian(zip(smin, smax)).T self.grid = column_stack([sg.grid, vertices])
def test_smolyak(self): import numpy f = lambda x: numpy.column_stack( [x[:, 0] * x[:, 1]**0.5, x[:, 1] * x[:, 1] - x[:, 0] * x[:, 0]]) a = [0.5, 0.1] b = [2, 3] bounds = numpy.row_stack([a, b]) from dolo.numeric.interpolation.smolyak import SmolyakGrid sg = SmolyakGrid(a, b, 3) values = f(sg.grid) sg.set_values(values) assert (abs(sg(sg.grid) - values).max() < 1e-8)
def test_smolyak_2(self): import numpy from dolo.numeric.interpolation.smolyak import SmolyakGrid d = 5 l = 4 bounds = numpy.row_stack([[-0.5] * d, [0.7] * d]) sg = SmolyakGrid(bounds[0, :], bounds[1, :], l) f = lambda x: numpy.row_stack( [x[:, 0] * x[:, 1], x[:, 1] * x[:, 1] - x[:, 0] * x[:, 0]]) values = f(sg.grid) import time t = time.time() for i in range(5): sg.set_values(sg.grid) val = sg(sg.grid) s = time.time() print(s - t)
def test_smolyak_2(self): import numpy from dolo.numeric.interpolation.smolyak import SmolyakGrid d = 5 l = 4 bounds = numpy.row_stack([[-0.5] * d, [0.7] * d]) sg = SmolyakGrid(bounds[0, :], bounds[1, :], l) f = lambda x: numpy.row_stack([x[0, :] * x[1, :], x[1, :] * x[1, :] - x[0, :] * x[0, :]]) values = f(sg.grid) import time t = time.time() for i in range(5): sg.set_values(sg.grid) val = sg(sg.grid) s = time.time() print(s - t)
def test_smolyak(self): import numpy f = lambda x: numpy.column_stack([ x[:,0] * x[:,1]**0.5, x[:,1] * x[:,1] - x[:,0] * x[:,0] ]) a = [0.5,0.1] b = [2,3] bounds = numpy.row_stack([a,b]) from dolo.numeric.interpolation.smolyak import SmolyakGrid sg = SmolyakGrid(a,b,3) values = f(sg.grid) sg.set_values(values) assert( abs( sg(sg.grid) - values ).max()<1e-8 )
def test_smolyak(self): import numpy f = lambda x: numpy.row_stack( [x[0, :] * x[1, :]**0.5, x[1, :] * x[1, :] - x[0, :] * x[0, :]]) smin = [0.5, 0.1], smax = [2, 3] bounds = numpy.row_stack([smin, smax]) from dolo.numeric.interpolation.smolyak import SmolyakGrid sg = SmolyakGrid(smin, smax, 3) values = f(sg.grid) sg.set_values(values) theta_0 = sg.theta.copy() def fobj(theta): sg.theta = theta return sg(sg.grid) fobj(theta_0)
def create_interpolator(grid, interp_method=None): if interp_method is None: interp_method = grid.interpolation if grid.__class__.__name__ == 'SmolyakGrid': if interp_method is not None and interp_method not in ('chebychev', 'polynomial'): raise Exception( "Interpolation method '{}' is not implemented for Smolyak grids." .format(interp_method)) from dolo.numeric.interpolation.smolyak import SmolyakGrid dr = SmolyakGrid(grid.a, grid.b, grid.mu) elif grid.__class__.__name__ == 'CartesianGrid': if interp_method is not None and interp_method not in ( 'spline', 'cspline', ' splines', 'csplines'): raise Exception( "Interpolation method '{}' is not implemented for Cartesian grids." .format(interp_method)) from dolo.numeric.interpolation.splines import MultivariateSplines dr = MultivariateSplines(grid.a, grid.b, grid.orders) else: raise Exception("Unknown grid type '{}'.".format(grid)) return dr
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 xh_init = dr_pert(dr_x.grid) n_x = len(model['variables_groups']['controls']) dr_x.set_values( xh_init[:n_x,:] ) dr_h.set_values( xh_init[n_x:,:] ) #phi = MultilinearInterpolator( smin, smax, [10,10]) #psi = MultilinearInterpolator( smin, smax, [10,10])
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
]) #( sqrt( x[0,:]**2 + x[1,:]**2 + x[2,:]**2 + x[3,:]**2 + x[4,:]**2) )**(1-gamma)/1-gamma # ( sqrt( reduce(sum, [x[i,:]**2 for i in range(d)], zeros(x[0,:].shape) ) ) )**(1-gamma)/1-gamma #fun = lambda x: x[0,:] from dolo.numeric.interpolation.interpolation import RectangularDomain dom = RectangularDomain(smin,smax,[50]*d) vals = fun(dom.grid) # exit() # if False: from dolo.numeric.interpolation.smolyak import SmolyakGrid sg = SmolyakGrid(smin, smax, 4) sg.set_values( fun(sg.grid)) tstart = time.time() vals_sg = sg(dom.grid) tend = time.time() # print('Elapsed (smolyak) : {}'.format(tend-tstart)) t1 = time.time() sp = MultivariateSplines(smin,smax,orders) t2 = time.time() sp.set_values( fun(sp.grid)) t3 = time.time() vals_sp = sp.interpolate(dom.grid) t4 = time.time()
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, inner_maxit=10, integration='gauss-hermite', integration_orders=None, T=200, n_s=3, hook=None): ''' Finds a global solution for ``model`` using backward time-iteration. This algorithm iterates on the residuals of the arbitrage equations 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 nodes in each dimension if ``interp_type="spline" `` Returns ------- decision rule : approximated solution ''' def vprint(t): if verbose: print(t) parms = model.calibration['parameters'] sigma = model.covariances if initial_dr is None: if pert_order == 1: 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 = np.row_stack([a, b]) bounds = np.array(bounds, dtype=float) if interp_orders is None: interp_orders = approx.get('orders', [5] * bounds.shape[1]) 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 = np.sqrt(np.diag(Q)) bounds = np.row_stack([ initial_dr.S_bar - devs * n_s, initial_dr.S_bar + devs * n_s, ]) if interp_orders is 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) 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... f = model.functions['arbitrage'] g = model.functions['transition'] # define objective function (residuals of arbitrage equations) def fun(x): return 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['controls_lb'] ubfun = model.functions['controls_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} |' headline = headline.format('N', ' Error', 'Gain', 'Time', 'nit') stars = '-'*len(headline) print(stars) print(headline) print(stars) # format string for within loop fmt_str = '|{0:4} | {1:10.3e} | {2:8.3f} | {3:8.3f} | {4:3} |' err_0 = 1 while err > tol and it < maxit: # update counters t_start = time.time() it += 1 # update interpolation coefficients (NOTE: filters through `fun`) dr.set_values(x0) # Derivative of objective function sdfun = SerialDifferentiableFunction(fun) # Apply solver with current decision rule for controls if with_complementarities: [x, nit] = ncpsolve(sdfun, lb, ub, x0, verbose=verbit, maxit=inner_maxit) else: [x, nit] = serial_newton(sdfun, x0, verbose=verbit) # update error and print if `verbose` 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(fmt_str.format(it, err, err_SA, elapsed, nit)) # Update control vector x0[:] = x # x0 = x0 + (x-x0) # call user supplied hook, if any if hook: hook(dr, it, err) # warn and bail if we get inf 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")) # compute final fime and do final printout if `verbose` t2 = time.time() if verbose: print(stars) print('Elapsed: {} seconds.'.format(t2 - t1)) print(stars) return dr
def interpolation(self, d): from itertools import product import numpy from numpy import array, column_stack from dolo.numeric.interpolation.multilinear import multilinear_interpolation smin = array([0.0] * d) smax = array([1.0] * d) orders = numpy.array([4, 3, 5, 6, 3], dtype=numpy.int) orders = orders[:d] grid = column_stack([ e for e in product(*[ numpy.linspace(smin[i], smax[i], orders[i]) for i in range(d) ]) ]) finer_grid = column_stack( [e for e in product(*[numpy.linspace(0, 1, 10)] * d)]) if d == 1: f = lambda g: numpy.row_stack([2 * g[0, :]]) elif d == 2: f = lambda g: numpy.row_stack([ g[0, :] * g[1, :], ]) elif d == 3: f = lambda g: numpy.row_stack([ (g[0, :] - g[1, :]) * g[2, :], ]) elif d == 4: f = lambda g: numpy.row_stack([(g[3, :] - g[1, :]) * (g[2, :] - g[0, :])]) # values = f(grid) finer_grid = numpy.ascontiguousarray(finer_grid) interpolated_values = multilinear_interpolation( smin, smax, orders, values, finer_grid) from dolo.numeric.interpolation.smolyak import SmolyakGrid sg = SmolyakGrid(smin, smax, 3) sg.set_values(f(sg.grid)) smol_values = sg(finer_grid) true_values = f(finer_grid) err_0 = abs(true_values - smol_values).max() err_1 = abs(true_values - interpolated_values).max() # both errors should be 0, because interpolated function is a 2d order polynomial assert_almost_equal(err_1, 0) from dolo.numeric.interpolation.multilinear import MultilinearInterpolator mul_interp = MultilinearInterpolator(smin, smax, orders) mul_interp.set_values(f(mul_interp.grid)) interpolated_values_2 = mul_interp(finer_grid) err_3 = (abs(interpolated_values - interpolated_values_2)) assert_almost_equal(err_3, 0)
def interpolation(self, d): from itertools import product import numpy from numpy import array, column_stack from dolo.numeric.interpolation.multilinear import multilinear_interpolation smin = array([0.0]*d) smax = array([1.0]*d) orders = numpy.array( [4,3,5,6,3], dtype=numpy.int ) orders = orders[:d] grid = column_stack( [e for e in product(*[numpy.linspace(smin[i],smax[i],orders[i]) for i in range(d)])]) finer_grid = column_stack( [e for e in product(*[numpy.linspace(0,1,10)]*d) ] ) if d == 1: f = lambda g: numpy.row_stack([ 2*g[0,:] ]) elif d == 2: f = lambda g: numpy.row_stack([ g[0,:] * g[1,:], ]) elif d == 3: f = lambda g: numpy.row_stack([ (g[0,:] - g[1,:]) * g[2,:], ]) elif d== 4: f = lambda g: numpy.row_stack([ (g[3,:] - g[1,:]) * (g[2,:] - g[0,:]) ]) # values = f( grid ) finer_grid = numpy.ascontiguousarray(finer_grid) interpolated_values = multilinear_interpolation(smin, smax, orders, values, finer_grid) from dolo.numeric.interpolation.smolyak import SmolyakGrid sg = SmolyakGrid( smin, smax ,3) sg.set_values( f(sg.grid) ) smol_values = sg(finer_grid) true_values = f(finer_grid) err_0 = abs(true_values - smol_values).max() err_1 = abs(true_values - interpolated_values).max() # both errors should be 0, because interpolated function is a 2d order polynomial assert_almost_equal(err_1,0) from dolo.numeric.interpolation.multilinear import MultilinearInterpolator mul_interp = MultilinearInterpolator(smin,smax,orders) mul_interp.set_values( f( mul_interp.grid) ) interpolated_values_2 = mul_interp( finer_grid ) err_3 = (abs(interpolated_values- interpolated_values_2)) assert_almost_equal(err_3,0)
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 xh_init = dr_pert(dr_x.grid) n_x = len(model['variables_groups']['controls']) dr_x.set_values(xh_init[:n_x, :]) dr_h.set_values(xh_init[n_x:, :]) #phi = MultilinearInterpolator( smin, smax, [10,10]) #psi = MultilinearInterpolator( smin, smax, [10,10]) import numpy
def generatebenchmarkdata(m, n): seedarr = [54321, 456789, 9876512, 7919820, 10397531] folder = "results" samplearr = ["mc", "lhs", "so", "sg", "splitlhs"] # samplearr = ["lhs","sg","splitlhs"] # samplearr = ["lhs","splitlhs"] # samplearr = ["splitlhs"] from apprentice import tools from pyDOE import lhs import apprentice ts = 2 farr = getfarr() for fname in farr: dim = getdim(fname) minarr, maxarr = getbox(fname) npoints = ts * tools.numCoeffsRapp(dim, [int(m), int(n)]) print(npoints) for sample in samplearr: for numex, ex in enumerate( ["exp1", "exp2", "exp3", "exp4", "exp5"]): seed = seedarr[numex] np.random.seed(seed) if (sample == "mc"): Xperdim = () for d in range(dim): Xperdim = Xperdim + (np.random.rand(npoints, ) * (maxarr[d] - minarr[d]) + minarr[d], ) X = np.column_stack(Xperdim) formatStr = "{0:0%db}" % (dim) for d in range(2**dim): binArr = [int(x) for x in formatStr.format(d)[0:]] val = [] for i in range(dim): if (binArr[i] == 0): val.append(minarr[i]) else: val.append(maxarr[i]) X[d] = val elif (sample == "sg"): from dolo.numeric.interpolation.smolyak import SmolyakGrid s = 0 l = 1 while (s < npoints): sg = SmolyakGrid(a=minarr, b=maxarr, l=l) s = sg.grid.shape[0] l += 1 X = sg.grid elif (sample == "so"): X = my_i4_sobol_generate(dim, npoints, seed) s = apprentice.Scaler(np.array(X, dtype=np.float64), a=minarr, b=maxarr) X = s.scaledPoints elif (sample == "lhs"): X = lhs(dim, samples=npoints, criterion='maximin') s = apprentice.Scaler(np.array(X, dtype=np.float64), a=minarr, b=maxarr) X = s.scaledPoints elif (sample == "splitlhs"): epsarr = [] for d in range(dim): #epsarr.append((maxarr[d] - minarr[d])/10) epsarr.append(10**-6) facepoints = int( 2 * tools.numCoeffsRapp(dim - 1, [int(m), int(n)])) insidepoints = int(npoints - facepoints) Xmain = np.empty([0, dim]) # Generate inside points minarrinside = [] maxarrinside = [] for d in range(dim): minarrinside.append(minarr[d] + epsarr[d]) maxarrinside.append(maxarr[d] - epsarr[d]) X = lhs(dim, samples=insidepoints, criterion='maximin') s = apprentice.Scaler(np.array(X, dtype=np.float64), a=minarrinside, b=maxarrinside) X = s.scaledPoints Xmain = np.vstack((Xmain, X)) #Generate face points perfacepoints = int(np.ceil(facepoints / (2 * dim))) index = 0 for d in range(dim): for e in [minarr[d], maxarr[d]]: index += 1 np.random.seed(seed + index * 100) X = lhs(dim, samples=perfacepoints, criterion='maximin') minarrface = np.empty(shape=dim, dtype=np.float64) maxarrface = np.empty(shape=dim, dtype=np.float64) for p in range(dim): if (p == d): if e == maxarr[d]: minarrface[p] = e - epsarr[d] maxarrface[p] = e else: minarrface[p] = e maxarrface[p] = e + epsarr[d] else: minarrface[p] = minarr[p] maxarrface[p] = maxarr[p] s = apprentice.Scaler(np.array(X, dtype=np.float64), a=minarrface, b=maxarrface) X = s.scaledPoints Xmain = np.vstack((Xmain, X)) Xmain = np.unique(Xmain, axis=0) X = Xmain formatStr = "{0:0%db}" % (dim) for d in range(2**dim): binArr = [int(x) for x in formatStr.format(d)[0:]] val = [] for i in range(dim): if (binArr[i] == 0): val.append(minarr[i]) else: val.append(maxarr[i]) X[d] = val if not os.path.exists(folder + "/" + ex + '/benchmarkdata'): os.makedirs(folder + "/" + ex + '/benchmarkdata', exist_ok=True) for noise in ["0", "10-2", "10-4", "10-6"]: noisestr, noisepct = getnoiseinfo(noise) Y = getData(X, fn=fname, noisepct=noisepct, seed=seed) outfile = "%s/%s/benchmarkdata/%s%s_%s.txt" % ( folder, ex, fname, noisestr, sample) print(outfile) np.savetxt(outfile, np.hstack((X, Y.T)), delimiter=",") if (sample == "sg"): break
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