Exemplo n.º 1
0
def solve_risky_ss(model, X_bar, X_s, verbose=False):

    import numpy
    from dolo.compiler.function_compiler import compile_function
    import time
    from dolo.compiler.compiler_functions import simple_global_representation

    parms = model.calibration['parameters']
    sigma = model.calibration['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 = model.calibration['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])])

    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]
Exemplo n.º 2
0
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]
Exemplo n.º 3
0
    def process_output(self, solution_order=False, fname=None):

        from dolo.compiler.compiler_functions import simple_global_representation
        data = simple_global_representation(self.model, solve_systems=True)

#        print data['a_eqs']
#        print data['f_eqs']
        dmodel = self.model
        model = dmodel

        f_eqs = data['f_eqs']
        g_eqs = data['g_eqs']

        g_eqs = [map_function_to_expression(lambda x: timeshift(x,1),eq) for eq in g_eqs]

#        h_eqs = data['h_eqs']
        auxiliaries = data['auxiliaries']
        states = data['states']
        controls = data['controls']

        shocks = dmodel.shocks
#        exp_vars = data['exp_vars']
        #inf_bounds = data['inf_bounds']
        #sup_bounds = data['sup_bounds']


        controls_f = [v(1) for v in controls]
        states_f = [v(1) for v in states]
        shocks_f = [v(1) for v in shocks]

        sub_list = dict()
#        for i,v in enumerate(exp_vars):
#            sub_list[v] = 'z(:,{0})'.format(i+1)

        for i,v in enumerate(controls):
            sub_list[v] = 'x(:,{0})'.format(i+1)
            sub_list[v(1)] = 'xnext(:,{0})'.format(i+1)

        for i,v in enumerate(states):
            sub_list[v] = 's(:,{0})'.format(i+1)
            sub_list[v(1)] = 'snext(:,{0})'.format(i+1)

        for i,v in enumerate(dmodel.shocks):
            sub_list[v] = 'e(:,{0})'.format(i+1)
            sub_list[v(1)] = 'enext(:,{0})'.format(i+1)

        for i,v in enumerate(dmodel.parameters):
            sub_list[v] = 'p({0})'.format(i+1)




        text = '''function [model] = get_model()
    model = model_info;
    model.f = @f;
    model.g = @g;
    model.a = @a;
end

function [out1,out2,out3,out4,out5] = f(s,x,snext,xnext,enext,p)
    n = size(s,1);
{eq_fun_block}
end

function [out1,out2,out3] = g(s,x,e,p)
    n = size(s,1);
{state_trans_block}
end

function [out1,out2,out3] = a(s,x,p)
    n = size(s,1);
{aux_block}
end

function [out1] = model_info() % informations about the model
{model_info}
end
'''

        from dolo.compiler.common import DicPrinter

        dp = DicPrinter(sub_list)

        def write_eqs(eq_l,outname='out1',ntabs=0):
            eq_block = '  ' * ntabs + '{0} = zeros(n,{1});'.format(outname,len(eq_l))
            for i,eq in enumerate(eq_l):
                eq_block += '\n' + '  ' * ntabs + '{0}(:,{1}) = {2};'.format( outname,  i+1,  dp.doprint_matlab(eq,vectorize=True) )
            return eq_block

        def write_der_eqs(eq_l,v_l,lhs,ntabs=0):
            eq_block = '  ' * ntabs + '{lhs} = zeros(n,{0},{1});'.format(len(eq_l),len(v_l),lhs=lhs)
            eq_l_d = eqdiff(eq_l,v_l)
            for i,eqq in enumerate(eq_l_d):
                for j,eq in enumerate(eqq):
                    s = dp.doprint_matlab( eq, vectorize=True )
                    eq_block += '\n' + '  ' * ntabs + '{lhs}(:,{0},{1}) = {2}; % d eq_{eq_n} w.r.t. {vname}'.format(i+1,j+1,s,lhs=lhs,eq_n=i+1,vname=str(v_l[j]) )
            return eq_block

#        eq_bounds_block = write_eqs(inf_bounds,ntabs=2)
#        eq_bounds_block += '\n'
#        eq_bounds_block += write_eqs(sup_bounds,'out2',ntabs=2)

        eq_f_block = '''
    % f
{0}

if nargout >= 2

    % df/ds
{1}

    % df/dx
{2}

    % df/dsnext
{3}

    % df/dxnext
{4}

end

        '''.format( write_eqs(f_eqs,'out1',3),
                    write_der_eqs(f_eqs,states,'out2',3),
                    write_der_eqs(f_eqs,controls,'out3',3),
                    write_der_eqs(f_eqs,states_f,'out4',3),
                    write_der_eqs(f_eqs,controls_f,'out5',3),
                    write_der_eqs(f_eqs, shocks_f, 'out6',3)
#                    write_der_eqs(f_eqs,exp_vars,'out4',3)
            )

        eq_g_block = '''
    % g

{0}

if nargout >=2
    % dg/ds
    {1}
    % dg/dx
    {2}
end
        '''.format( write_eqs(g_eqs,'out1',3),
                    write_der_eqs(g_eqs,states,'out2',3),
                    write_der_eqs(g_eqs,controls,'out3',3)
            )

        if 'a_eqs' in data:
            a_eqs = data['a_eqs']
            eq_a_block =  '''
    % a

{0}

if nargout >=2
    % da/ds
    {1}
    % da/dx
    {2}
end
                    '''.format( write_eqs(a_eqs,'out1',3),
                                write_der_eqs(a_eqs,states,'out2',3),
                                write_der_eqs(a_eqs,controls,'out3',3)
                        )
        else:
            eq_a_block = ''

        # if not with_param_names:
        #    eq_h_block = 's=snext;\nx=xnext;\n'+eq_h_block

        # param_def = 'p = [ ' + str.join(',',[p.name for p in dmodel.parameters])  + '];'

        from dolo.misc.matlab import value_to_mat

        # read model informations
        [y,x,params_values] = model.read_calibration()
        #params_values = '[' + str.join(  ',', [ str( p ) for p in params] ) + '];'
        vvs = model.variables
        s_ss = [ y[vvs.index(v)] for v in model['variables_groups']['states'] ]
        x_ss = [ y[vvs.index(v)] for v in model['variables_groups']['controls'] ]

        model_info = '''
    mod = struct;
    mod.states = {states};
    mod.controls = {controls};
    mod.auxiliaries = {auxiliaries};
    mod.parameters = {parameters};
    mod.shocks = {shocks};
    mod.s_ss = {s_ss};
    mod.x_ss = {x_ss};
    mod.params = {params_values};
'''.format(
    states = '{{ {} }}'.format(str.join(',', ["'{}'".format(v) for v in states])),
    controls = '{{ {} }}'.format(str.join(',', ["'{}'".format(v) for v in controls])),
    auxiliaries = '{{ {} }}'.format(str.join(',', ["'{}'".format(v) for v in auxiliaries])),
    parameters = '{{ {} }}'.format(str.join(',', ["'{}'".format(v) for v in model.parameters])),
    shocks = '{{ {} }}'.format(str.join(',', ["'{}'".format(v) for v in model.shocks])),
    s_ss = value_to_mat(s_ss),
    x_ss = value_to_mat(x_ss),
    params_values = value_to_mat(params_values)
)
        if solution_order:
            from dolo.numeric.perturbations_to_states import approximate_controls

            ZZ = approximate_controls(self.model,order=solution_order, return_dr=False)
            n_c = len(controls)

            ZZ = [np.array(e) for e in ZZ]
            ZZ = [e[:n_c,...] for e in ZZ] # keep only control vars. (x) not expectations (h)

            solution = "    mod.X = cell({0},1);\n".format(len(ZZ))
            for i,zz in enumerate(ZZ):
                solution += "    mod.X{{{0}}} = {1};\n".format(i+1,value_to_mat(zz.real))
            model_info += solution
        model_info += '    out1 = mod;\n'

        text = text.format(
#            eq_bounds_block = eq_bounds_block,
            mfname = fname if fname else 'mf_' + model.fname,
            eq_fun_block=eq_f_block,
            state_trans_block=eq_g_block,
            aux_block=eq_a_block,
#            exp_fun_block=eq_h_block,
#            solution = solution,
            model_info = model_info
        )

        return text