Beispiel #1
0
    def test_denhaan_errors(self):

        from dolo.misc.yamlfile import yaml_import
        from dolo.numeric.global_solve import global_solve

        model = yaml_import('examples/global_models/rbc.yaml')


        from dolo.compiler.compiler_global import CModel
        from dolo.numeric.perturbations_to_states import approximate_controls

        dr = approximate_controls(model)
        dr_global = global_solve(model, smolyak_order=4, verbose=False, pert_order=1)


        sigma = model.read_covariances()

        cmodel = CModel(model)
        cmodel.sigma = sigma

        s_0 = dr.S_bar

        from dolo.numeric.error_measures import denhaanerrors

        [error_1, error_2] = denhaanerrors(cmodel, dr, s_0)
        [error_1_glob, error_2_glob] = denhaanerrors(cmodel, dr_global, s_0)

        print(error_1)
        print(error_1_glob)
        assert( max(error_1_glob) < 10-7) # errors with solyak colocations at order 4 are very small
        assert( max(error_2_glob) < 10-7)
Beispiel #2
0
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
Beispiel #3
0
        pyplot.xlabel(state)


if __name__ == '__main__':
    from dolo import yaml_import, approximate_controls
    model = yaml_import('../../examples/global_models/capital.yaml')

    dr = approximate_controls(model)

    [y, x, parms] = model.read_calibration()
    sigma = model.read_covariances()

    from dolo.compiler.compiler_global import CModel

    import numpy
    cmodel = CModel(model)
    s0 = numpy.atleast_2d(dr.S_bar).T
    horizon = 50

    simul = simulate(cmodel,
                     dr,
                     s0,
                     sigma,
                     n_exp=500,
                     parms=parms,
                     seed=1,
                     horizon=horizon)

    from dolo.numeric.quantization import quantization_nodes
    N = 80
    [x, w] = quantization_nodes(N, sigma)
Beispiel #4
0
def simulate(cmodel, dr, s0=None, sigma=None, n_exp=0, horizon=40, parms=None, seed=1, discard=False, stack_series=True,
             solve_expectations=False, nodes=None, weights=None):

    '''
    :param cmodel: compiled model
    :param dr: decision rule
    :param s0: initial state where all simulations start
    :param sigma: covariance matrix of the normal multivariate distribution describing the random shocks
    :param n_exp: number of draws to simulate. Use 0 for impulse-response functions
    :param horizon: horizon for the simulation
    :param parms: (vector) value for the parameters of the model
    :param seed: used to initialize the random number generator. Use it to replicate exact same results among simulations
    :param discard: (default: False) if True, then all simulations containing at least one non finite value are discarded
    :param stack_series: return simulated series for different types of variables separately (in a list)
    :return: a ``n_s x n_exp x horizon`` array where ``n_s`` is the number of states. The second dimension is omitted if
    n_exp = 0.
    '''

    from dolo.compiler.compiler_global import CModel
    from dolo.symbolic.model import Model

    if isinstance(cmodel, Model):
        from dolo.symbolic.model import Model
        model = cmodel
        cmodel = CModel(model)
        [y,x,parms] = model.read_calibration()
    else:
        cmodel = cmodel.as_type('fg')

    if n_exp ==0:
        irf = True
        n_exp = 1
    else:
        irf = False



    calib = cmodel.model.calibration

    if parms is None:
        parms = numpy.array( calib['parameters'] ) # TODO : remove reference to symbolic model

    if sigma is None:
        sigma = numpy.array( calib['sigma'] )

    if s0 is None:
        s0 = numpy.array( calib['steady_state']['states'] )

    s0 = numpy.atleast_2d(s0.flatten()).T

    x0 = dr(s0)

    s_simul = numpy.zeros( (s0.shape[0],n_exp,horizon) )
    x_simul = numpy.zeros( (x0.shape[0],n_exp,horizon) )

    s_simul[:,:,0] = s0
    x_simul[:,:,0] = x0

    numpy.random.seed(seed)

    for i in range(horizon):
        mean = numpy.zeros(sigma.shape[0])
        if irf:
            epsilons = numpy.zeros( (sigma.shape[0],1) )
        else:
            epsilons = numpy.random.multivariate_normal(mean, sigma, n_exp).T
        s = s_simul[:,:,i]

        x = dr(s)

        if solve_expectations:
            from dolo.numeric.solver import solver
            from dolo.numeric.newton import newton_solver

            fobj = lambda t: step_residual(s, t, dr, cmodel.f, cmodel.g, parms, nodes, weights, with_derivatives=False) #
#            x = solver(fobj, x,  serial_problem=True)
            x = newton_solver(fobj, x, numdiff=True)

        x_simul[:,:,i] = x

        ss = cmodel.g(s,x,epsilons,parms)

        if i<(horizon-1):
            s_simul[:,:,i+1] = ss

    from numpy import any,isnan,all

    if not hasattr(cmodel,'__a__'): # TODO: find a better test than this
        l = [s_simul, x_simul]
    else:
        n_s = s_simul.shape[0]
        n_x = x_simul.shape[0]
        a_simul = cmodel.a( s_simul.reshape((n_s,n_exp*horizon)), x_simul.reshape( (n_x,n_exp*horizon) ), parms)
        n_a = a_simul.shape[0]
        a_simul = a_simul.reshape(n_a,n_exp,horizon)
        l = [s_simul, x_simul, a_simul]

    if not stack_series:
        return l

    else:
        simul = numpy.row_stack(l)

    if discard:
        iA = -isnan(x_simul)
        valid = all( all( iA, axis=0 ), axis=1 )
        simul = simul[:,valid,:]
        n_kept = s_simul.shape[1]
        if n_exp > n_kept:
            print( 'Discarded {}/{}'.format(n_exp-n_kept,n_exp))

    if irf:
        simul = simul[:,0,:]

    return simul
Beispiel #5
0
bounds[:, 1] += s0[1]
print('bounds')
print bounds

P = eigs[1]

sg = SmolyakGrid(bounds, 5, P)

[y, x, parms] = model.read_calibration()

xinit = dr(sg.grid)
sg.fit_values(xinit)

from dolo.compiler.compiler_global import CModel, time_iteration, deterministic_residuals

gc = CModel(model)

res = deterministic_residuals(sg.grid, xinit, sg, gc.f, gc.g, dr.sigma, parms)

n_e = 5
epsilons = np.zeros((1, n_e))
weights = np.ones(n_e) / n_e

dr_smol = time_iteration(sg.grid,
                         sg,
                         xinit,
                         gc.f,
                         gc.g,
                         parms,
                         epsilons,
                         weights,