Example #1
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, use_pandas=True):

    '''
    :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.
    '''


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



    calib = cmodel.calibration

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

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

    if s0 is None:
        s0 = numpy.array( calib['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

    fun = cmodel.functions

    if cmodel.model_type == 'fga':
        ff = fun['arbitrage']
        gg = fun['transition']
        aa = fun['auxiliary']
        g = lambda s,x,e,p : gg(s,x,aa(s,x,p),e,p)
        f = lambda s,x,e,S,X,p : ff(s,x,aa(s,x,p),S,X,aa(S,X,p),p)
    else:
        f = cmodel.functions['arbitrage']
        g = cmodel.functions['transition']


    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, f, 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 = g(s,x,epsilons,parms)

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

    from numpy import any,isnan,all

    if not 'auxiliary' in fun: # TODO: find a better test than this
        l = [s_simul, x_simul]
        varnames = cmodel.symbols['states'] = cmodel.symbols['controls']
    else:
        aux = fun['auxiliary']
        n_s = s_simul.shape[0]
        n_x = x_simul.shape[0]
        a_simul = aux( 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]
        varnames = cmodel.symbols['states'] + cmodel.symbols['controls'] + cmodel.symbols['auxiliary']
    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,:]

        if use_pandas:
            import pandas
            ts = pandas.DataFrame(simul.T, columns=varnames)
            return ts

    return simul
Example #2
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,
             use_pandas=True):
    '''
    :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.
    '''

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

    calib = cmodel.calibration

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

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

    if s0 is None:
        s0 = numpy.array(calib['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

    fun = cmodel.functions

    if cmodel.model_type == 'fga':
        ff = fun['arbitrage']
        gg = fun['transition']
        aa = fun['auxiliary']
        g = lambda s, x, e, p: gg(s, x, aa(s, x, p), e, p)
        f = lambda s, x, e, S, X, p: ff(s, x, aa(s, x, p), S, X, aa(S, X, p), p
                                        )
    else:
        f = cmodel.functions['arbitrage']
        g = cmodel.functions['transition']

    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, f, 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 = g(s, x, epsilons, parms)

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

    from numpy import any, isnan, all

    if not 'auxiliary' in fun:  # TODO: find a better test than this
        l = [s_simul, x_simul]
        varnames = cmodel.symbols['states'] = cmodel.symbols['controls']
    else:
        aux = fun['auxiliary']
        n_s = s_simul.shape[0]
        n_x = x_simul.shape[0]
        a_simul = aux(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]
        varnames = cmodel.symbols['states'] + cmodel.symbols[
            'controls'] + cmodel.symbols['auxiliary']
    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, :]

        if use_pandas:
            import pandas
            ts = pandas.DataFrame(simul.T, columns=varnames)
            return ts

    return simul
Example #3
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