Exemple #1
0
    def check(self):

        defaults = {
            'name': 'anonymous',
            'init_values': {},
            'parameters_values': {},
            'covariances': sympy.Matrix(),
            'variables_ordering': [],
            'parameters_ordering': [],
            'shocks_ordering': []
        }
        from collections import OrderedDict as odict
        equations_groups = odict()
        for i, eq in enumerate(self['equations']):
            eq.tags['eq_number'] = i
            if 'eq_type' in eq.tags:
                g = eq.tags['eq_type']
                if g not in equations_groups:
                    equations_groups[g] = []
                equations_groups[g].append(eq)

        self['equations_groups'] = equations_groups

        for k in defaults:
            if k not in self:
                self[k] = defaults[k]

        if not self.get('equations'):
            raise Exception('No equations specified')

        for n, eq in enumerate(self['equations']):
            if not isinstance(eq, Equation):
                self['equations'][n] = Equation(eq, 0)
Exemple #2
0
def solve_recursive_block(equations):
    from dolo.symbolic.symbolic import Equation
    system = {eq.lhs: eq.rhs for eq in equations}
    from dolo.misc.triangular_solver import solve_triangular_system
    sol = solve_triangular_system(system)
    solved_equations = [Equation(eq.lhs, sol[eq.lhs]) for eq in equations]
    return solved_equations
Exemple #3
0
    def build_lagrangian(self):
        vars = list(self.base_model.variables)

        if self.instrument_equation != None and self.instrument_equation.tags.has_key(
                'ramsey_instrument'):
            ramsey_instrument = [
                v for v in vars
                if v.name == self.instrument_equation.tags['ramsey_instrument']
            ]
            ramsey_instrument = ramsey_instrument[0]
            self.equations.remove(self.instrument_equation)
            vars.remove(ramsey_instrument)

        # first we create one multiplicator by equation
        n_eq = len(self.equations)
        lambdas = []
        for i in range(n_eq):
            v = Variable('Lambda_' + str(i + 1), 0)
            self.variables_ordering.append(v)
            lambdas.append(v)
        t_cur = self.objective + sum(
            [self.equations[i].gap * lambdas[i] for i in range(n_eq)])
        t_fut = time_shift(t_cur, +1)
        t_past = time_shift(t_cur, -1)
        beta = self.discount
        lagrangian = 1 / beta * t_past + t_cur + beta * t_fut
        self.lagrangian = lagrangian

        print 'There are ' + str(len(self.equations)) + 'equations'
        print 'There are ' + str(len(vars)) + 'variables'

        if self.instrument_equation != None and self.instrument_equation.tags.has_key(
                'ramsey_instrument'):
            #            vars = [ramsey_instrument] + vars
            eq = lagrangian.diff(ramsey_instrument)
            eq = Equation(eq, 0).tag(name='Derivative of lagrangian w.r.t : ' +
                                     str(ramsey_instrument))
            eq.tags.update(self.instrument_equation.tags)
            self.equations.append(eq)

        for v in vars:
            if v in self.ignored_variables:
                pass
            eq = lagrangian.diff(v)
            eq = Equation(eq, 0).tag(name='Derivative of lagrangian w.r.t : ' +
                                     str(v))
            self.equations.append(eq)
Exemple #4
0
def portfolios_to_deterministic(model, pf_names):

    #######
    #######

    import re
    regex = re.compile('.*<=(.*)<=.*')
    for i, eq in enumerate(model.equations_groups['arbitrage']):
        from dolo.symbolic.symbolic import Variable, Equation
        m = regex.match(eq.tags['complementarity'])
        vs = m.group(1).strip()
        if vs in pf_names:
            v = Variable(vs)
            neq = Equation(v, 0)
            neq.tag(**eq.tags)
            model.equations_groups['arbitrage'][i] = neq

    print('Warning : initial model changed')
    model.update()

    return model
def portfolios_to_deterministic(model,pf_names):

    #######
    #######

    import re
    regex = re.compile('.*<=(.*)<=.*')
    for i,eq in enumerate(model.equations_groups['arbitrage']):
        from dolo.symbolic.symbolic import Variable, Equation
        m = regex.match(eq.tags['complementarity'])
        vs = m.group(1).strip()
        if vs in pf_names:
            v = Variable(vs)
            neq = Equation(v,0)
            neq.tag(**eq.tags)
            model.equations_groups['arbitrage'][i] = neq

    print('Warning : initial model changed')
    model.update()

    return model
Exemple #6
0
def parse_yaml_text(txt, verbose=False):
    '''
Imports the content of a modfile into the current interpreter scope
'''
    txt = txt.replace('..', '-')
    txt = txt.replace('--', '-')
    txt = txt.replace('^', '**')
    raw_dict = yaml.load(txt)

    if verbose == True:
        print('YAML file successfully parsed')

    declarations = raw_dict['declarations']
    # check
    if 'controls' in declarations:
        variables_groups = OrderedDict()
        known_types = [
            'states', 'controls', 'expectations', 'auxiliary', 'auxiliary_2'
        ]
        for vtype in known_types:
            if vtype in declarations:
                variables_groups[vtype] = [
                    Variable(vn, 0) for vn in declarations[vtype]
                ]
        variables_ordering = sum(variables_groups.values(), [])
    else:
        vnames = declarations['variables']
        variables_ordering = [Variable(vn, 0) for vn in vnames]
        variables_groups = None

    parameters_ordering = [Parameter(vn) for vn in declarations['parameters']]

    shocks_ordering = [Shock(vn, 0) for vn in declarations['shocks']]

    context = [
        (s.name, s)
        for s in variables_ordering + parameters_ordering + shocks_ordering
    ]
    context = dict(context)

    # add some common functions
    for f in [
            sympy.log, sympy.exp, sympy.sin, sympy.cos, sympy.tan, sympy.asin,
            sympy.acos, sympy.atan, sympy.sinh, sympy.cosh, sympy.tanh,
            sympy.pi
    ]:
        context[str(f)] = f
    context['sqrt'] = sympy.sqrt

    import re
    # we recognize two kinds of equations:
    # lhs = rhs
    # lhs | comp where comp is a complementarity condition

    equations = []
    equations_groups = OrderedDict()
    raw_equations = raw_dict['equations']
    if isinstance(raw_equations,
                  dict):  # tests whether there are groups of equations
        for groupname in raw_equations.keys():
            equations_groups[groupname] = []
            for raw_eq in raw_equations[
                    groupname]:  # Modfile is supposed to represent a global model. TODO: change it
                teqg = raw_eq.split('|')
                teq = teqg[0]
                if '=' in teq:
                    lhs, rhs = str.split(teq, '=')
                else:
                    lhs = teq
                    rhs = '0'
                try:
                    lhs = eval(lhs, context)
                    rhs = eval(rhs, context)
                except Exception as e:
                    print('Error parsing equation : ' + teq)
                    print str(e)
                    raise e

                eq = Equation(lhs, rhs)
                eq.tag(eq_type=groupname)
                if len(teqg) > 1:
                    comp = teqg[1]
                    eq.tag(complementarity=comp)
                equations.append(eq)
                #equations_groups[groupname].append( eq )
    else:
        for teq in raw_equations:
            if '=' in teq:
                lhs, rhs = str.split(teq, '=')
            else:
                lhs = teq
                rhs = '0'
            try:
                lhs = eval(lhs, context)
                rhs = eval(rhs, context)
            except Exception as e:
                print('Error parsing equations : ' + teq)
                print str(e)
            eq = Equation(lhs, rhs)
            equations.append(eq)
        equations_groups = None

    parameters_values = {}
    init_values = {}
    covariances = None
    if 'calibration' in raw_dict:
        calibration = raw_dict['calibration']
        if 'parameters' in calibration:
            parameters_values = [
                (Parameter(k), eval(str(v), context))
                for k, v in calibration['parameters'].iteritems()
            ]
            parameters_values = dict(parameters_values)
        #steady_state = raw_dict['steady_state']
        if 'steady_state' in calibration:
            init_values = [
                (Variable(vn, 0), eval(str(value), context))
                for vn, value in calibration['steady_state'].iteritems()
            ]
            init_values = dict(init_values)
        if 'covariances' in calibration:
            context['sympy'] = sympy
            covariances = eval(
                'sympy.Matrix({0})'.format(calibration['covariances']),
                context)
        else:
            covariances = None  # to avoid importing numpy

    model_dict = {
        'variables_ordering': variables_ordering,
        'parameters_ordering': parameters_ordering,
        'shocks_ordering': shocks_ordering,
        'variables_groups': variables_groups,
        'equations_groups': equations_groups,
        'equations': equations,
        'parameters_values': parameters_values,
        'init_values': init_values,
        'covariances': covariances
    }

    if 'model_type' in raw_dict:
        model_dict['model_type'] = raw_dict['model_type']
    model_dict['original_data'] = raw_dict

    model = Model(**model_dict)
    model.check_consistency(auto_remove_variables=False)
    return model
Exemple #7
0
def parse_dynare_text(txt, add_model=True, full_output=False, debug=False):
    '''
    Imports the content of a modfile into the current interpreter scope
    '''
    # here we call "instruction group", a string finishing by a semicolon
    # an "instruction group" can have several lines
    # a line can be
    # - a comment //...
    # - an old-style tag //$...
    # - a new-style tag [key1='value1',..]
    # - macro-instruction @#...
    # A Modfile contains several blocks (in this order) :
    # - an initblock defining variables, exovariables, parameters, initialization
    #   inside the initblock the order of declaration doesn't matter
    # - a model block with two special lines (model; end;)
    # - optional blocks (like endval, shocks)
    #    seperated by free matlab instructions in any order;
    # - all other instructions are ignored

    otxt = txt
    otxt = otxt.replace("\r\n", "\n")
    otxt = otxt.replace("^", "**")

    # first, we remove end-of-line comments : they are definitely lost
    regex = re.compile("(.+)//[^#](.*)")

    def remove_end_comment(line):
        res = regex.search(line)
        if res:
            l = res.groups(1)[0]
            return (l)
        else:
            return line

    txt = str.join("\n", map(remove_end_comment, otxt.split("\n")))

    name_regex = re.compile("//\s*fname\s*=\s*'(.*)'")
    m = name_regex.search(txt)
    if m:
        fname = m.group(1)
    else:
        fname = None

    instruction_groups = [Instruction_group(s) for s in txt.split(";")]

    instructions = [ig.instruction for ig in instruction_groups]

    if debug:
        print('Elementary instructions')
        for i in instruction_groups:
            print(i)

    try:
        imodel = [
            re.compile('model(\(.*\)|)').match(e) is not None
            for e in instructions
        ]
        imodel = imodel.index(True)
        #imodel = instructions.index("model") #this doesn't work for "MODEL"
        iend = instructions.index("end")
        model_block = instruction_groups[imodel:(iend + 1)]
        init_block = instruction_groups[0:imodel]
    except:
        raise Exception('Model block could not be found.')

    next_instructions = instructions[(iend + 1):]
    next_instruction_groups = instruction_groups[(iend + 1):]

    if 'initval' in next_instructions:
        iinitval = next_instructions.index('initval')
        iend = next_instructions.index('end', iinitval)
        matlab_block_1 = next_instruction_groups[0:iinitval]
        initval_block = next_instruction_groups[iinitval:(iend + 1)]
        next_instruction_groups = next_instruction_groups[(iend + 1):]
        next_instructions = next_instructions[(iend + 1):]
    else:
        initval_block = None
        matlab_block_1 = None

    if 'endval' in next_instructions:
        iendval = next_instructions.index('endval')
        iend = next_instructions.index('end', iendval)
        matlab_block_2 = next_instruction_groups[0:iendval]
        endval_block = next_instruction_groups[iendval:(iend + 1)]
        next_instruction_groups = next_instruction_groups[(iend + 1):]
        next_instructions = next_instructions[(iend + 1):]
    else:
        endval_block = None
        matlab_block_2 = None

    # TODO : currently shocks block needs to follow initval, this restriction should be removed
    if 'shocks' in next_instructions:
        ishocks = next_instructions.index('shocks')
        iend = next_instructions.index('end', ishocks)
        matlab_block_3 = next_instruction_groups[0:ishocks]
        shocks_block = next_instruction_groups[ishocks:(iend + 1)]
        next_instruction_groups = next_instruction_groups[(iend + 1):]
        next_instructions = next_instructions[(iend + 1):]
    else:
        shocks_block = None
        matlab_block_3 = None

    try:
        init_regex = re.compile("(parameters |var |varexo |)(.*)")
        var_names = []
        varexo_names = []
        parameters_names = []
        declarations = {}
        for ig in init_block:
            if ig.instruction != '':
                m = init_regex.match(ig.instruction)
                if not m:
                    raise Exception("Unexpected instruction in init block : " +
                                    str(ig.instruction))
                if m.group(1) == '':
                    [lhs, rhs] = m.group(2).split("=")
                    lhs = lhs.strip()
                    rhs = rhs.strip()
                    declarations[lhs] = rhs
                else:
                    arg = m.group(2).replace(",", " ")
                    names = [vn.strip() for vn in arg.split()]
                    if m.group(1).strip() == 'var':
                        dest = var_names
                    elif m.group(1).strip() == 'varexo':
                        dest = varexo_names
                    elif m.group(1).strip() == 'parameters':
                        dest = parameters_names
                    for n in names:
                        if not n in dest:
                            dest.append(n)
                        else:
                            raise Exception(
                                "symbol %s has already been defined".format(n))
    except Exception as e:
        raise Exception('Init block could not be read : ' + str(e))
    # the following instruction set the variables "variables","shocks","parameters"

    variables = []
    for vn in var_names:
        v = Variable(vn)
        variables.append(v)

    shocks = []
    for vn in varexo_names:
        s = Shock(vn)
        shocks.append(s)

    parameters = []
    for vn in parameters_names:
        p = Parameter(vn)
        parameters.append(p)

    parse_dict = dict()
    for v in variables + shocks + parameters:
        parse_dict[v.name] = v

    special_symbols = [
        sympy.exp, sympy.log, sympy.sin, sympy.cos, sympy.atan, sympy.tan
    ]
    for s in special_symbols:
        parse_dict[str(s)] = s
    parse_dict['sqrt'] = sympy.sqrt

    # Read parameters values
    parameters_values = {}
    for p in declarations:
        try:
            rhs = eval(declarations[p], parse_dict)
        except Exception as e:
            Exception("Impossible to evaluate parameter value : " + str(e))
        try:
            lhs = eval(p, parse_dict)
        except Exception as e:
            # here we could declare p
            raise e
        parameters_values[lhs] = rhs

    # Now we read the model block
    model_tags = model_block[0].tags
    equations = []
    for ig in model_block[1:-1]:
        if ig.instruction != '':
            teq = ig.instruction.replace('^', "**")
            if '=' in teq:
                teqlhs, teqrhs = teq.split("=")
            else:
                teqlhs = teq
                teqrhs = '0'
            eqlhs = eval(teqlhs, parse_dict)
            eqrhs = eval(teqrhs, parse_dict)
            eq = Equation(eqlhs, eqrhs)
            eq.tags.update(ig.tags)
            #        if eq.tags.has_key('name'):
            #            eq.tags[] = ig.tags['name']
            equations.append(eq)

    # Now we read the initval block
    init_values = {}
    if initval_block != None:
        for ig in initval_block[1:-1]:
            if len(ig.instruction.strip()) > 0:
                try:
                    [lhs, rhs] = ig.instruction.split("=")
                except Exception as e:
                    print(ig.instruction)
                    raise e
                init_values[eval(lhs, parse_dict)] = eval(rhs, parse_dict)

    # Now we read the endval block
    # I don't really care about the endval block !

    end_values = {}
    if endval_block != None:
        for ig in endval_block[1:-1]:
            [lhs, rhs] = ig.instruction.split("=")
            end_values[eval(lhs)] = eval(rhs)

    # Now we read the shocks block
    covariances = None
    if shocks_block != None:
        covariances = sympy.zeros(len(shocks))
        regex1 = re.compile("var (.*?),(.*?)=(.*)|var (.*?)=(.*)")
        for ig in shocks_block[1:-1]:
            m = regex1.match(ig.instruction)
            if not m:
                raise Exception("unrecognized instruction in block shocks : " +
                                str(ig.instruction))
            if m.group(1) != None:
                varname1 = m.group(1).strip()
                varname2 = m.group(2).strip()
                value = m.group(3).strip().replace("^", "**")
            elif m.group(4) != None:
                varname1 = m.group(4).strip()
                varname2 = varname1
                value = m.group(5).strip().replace("^", "**")
            i = varexo_names.index(varname1)
            j = varexo_names.index(varname2)
            covariances[i, j] = eval(value, parse_dict)
            covariances[j, i] = eval(value, parse_dict)

    calibration = {}
    calibration.update(parameters_values)
    calibration.update(init_values)
    symbols = {
        'variables': variables,
        'shocks': shocks,
        'parameters': parameters
    }

    from dolo.symbolic.model import SModel
    model = SModel({'dynare_block': equations}, symbols, calibration,
                   covariances)
    return model
def parse_yaml_text(txt,verbose=False):
    '''
Imports the content of a modfile into the current interpreter scope
'''
    txt = txt.replace('..','-')
    txt = txt.replace('--','-')
    txt = txt.replace('^','**')
    raw_dict = yaml.load(txt)

    if verbose == True:
        print('YAML file successfully parsed')

    declarations = raw_dict['declarations']
    # check
    if 'controls' in declarations:
        variables_groups = OrderedDict()
        known_types = ['states','controls','expectations','auxiliary','auxiliary_2']
        for vtype in known_types:
            if vtype in declarations:
                variables_groups[vtype] = [Variable(vn,0) for vn in declarations[vtype]]
        variables_ordering = sum(variables_groups.values(),[])
    else:
        vnames = declarations['variables']
        variables_ordering = [Variable(vn,0) for vn in vnames]
        variables_groups = None
        
    parameters_ordering = [Parameter(vn) for vn in declarations['parameters']]
    
    shocks_ordering = [Shock(vn,0) for vn in declarations['shocks']]

    context = [(s.name,s) for s in variables_ordering + parameters_ordering + shocks_ordering]
    context = dict(context)

    # add some common functions
    for f in [sympy.log, sympy.exp,
              sympy.sin, sympy.cos, sympy.tan,
              sympy.asin, sympy.acos, sympy.atan,
              sympy.sinh, sympy.cosh, sympy.tanh,
              sympy.pi]:
        context[str(f)] = f
    context['sqrt'] = sympy.sqrt

    import re
    # we recognize two kinds of equations:
    # lhs = rhs
    # lhs | comp where comp is a complementarity condition

    equations = []
    equations_groups = OrderedDict()
    raw_equations = raw_dict['equations']
    if isinstance(raw_equations,dict): # tests whether there are groups of equations
        for groupname in raw_equations.keys():
            equations_groups[groupname] = []
            for raw_eq in raw_equations[groupname]: # Modfile is supposed to represent a global model. TODO: change it
                teqg = raw_eq.split('|')
                teq = teqg[0]
                if '=' in teq:
                    lhs,rhs = str.split(teq,'=')
                else:
                    lhs = teq
                    rhs = '0'
                try:
                    lhs = eval(lhs,context)
                    rhs = eval(rhs,context)
                except Exception as e:
                    print('Error parsing equation : ' + teq)
                    print str(e)
                    raise e

                eq = Equation(lhs,rhs)
                eq.tag(eq_type=groupname)
                if len(teqg)>1:
                    comp = teqg[1]
                    eq.tag(complementarity=comp)
                equations.append(eq)
                #equations_groups[groupname].append( eq )
    else:
        for teq in raw_equations:
            if '=' in teq:
                lhs,rhs = str.split(teq,'=')
            else:
                lhs = teq
                rhs = '0'
            try:
                lhs = eval(lhs,context)
                rhs = eval(rhs,context)
            except Exception as e:
                print('Error parsing equations : ' + teq)
                print str(e)
            eq = Equation(lhs,rhs)
            equations.append(eq)
        equations_groups = None

    parameters_values = {}
    init_values = {}
    covariances = None
    if 'calibration' in raw_dict:
        calibration = raw_dict['calibration']
        if 'parameters' in calibration:
            parameters_values = [ (Parameter(k), eval(str(v),context)) for k,v in calibration['parameters'].iteritems() ]
            parameters_values = dict(parameters_values)
        #steady_state = raw_dict['steady_state']
        if 'steady_state' in calibration:
            init_values = [ (Variable(vn,0), eval(str(value),context)) for vn,value in calibration['steady_state'].iteritems() ]
            init_values = dict(init_values)
        if 'covariances' in calibration:
            context['sympy'] = sympy
            covariances = eval('sympy.Matrix({0})'.format( calibration['covariances'] ), context)
        else:
            covariances = None # to avoid importing numpy

    model_dict = {
        'variables_ordering': variables_ordering,
        'parameters_ordering': parameters_ordering,
        'shocks_ordering': shocks_ordering,
        'variables_groups': variables_groups,
        'equations_groups': equations_groups,
        'equations': equations,
        'parameters_values': parameters_values,
        'init_values': init_values,
        'covariances': covariances
    }

    if 'model_type' in raw_dict:
        model_dict['model_type'] = raw_dict['model_type']
    model_dict['original_data'] = raw_dict
    
    model = Model(**model_dict)
    model.check_consistency(auto_remove_variables=False)
    return model
def solve_portfolio_model(model, pf_names, order=1):

    pf_model = model

    from dolo import Variable, Parameter, Equation
    import re

    n_states = len(pf_model['variables_groups']['states'])
    states = pf_model['variables_groups']['states']
    steady_states = [Parameter(v.name+'_bar') for v in pf_model['variables_groups']['states']]
    n_pfs = len(pf_names)

    pf_vars = [Variable(v) for v in pf_names]
    res_vars = [Variable('res_'+str(i)) for i in range(n_pfs)]


    pf_parms = [Parameter('K_'+str(i)) for i in range(n_pfs)]
    pf_dparms = [[Parameter('K_'+str(i)+'_'+str(j)) for j in range(n_states)] for i in range(n_pfs)]

    from sympy import Matrix

    # creation of the new model

    import copy
    print('Warning: initial model has been changed.')
    new_model = copy.copy(pf_model)
    new_model['variables_groups']['controls']+=res_vars

    new_model['parameters_ordering'].extend(steady_states)
    for p in pf_parms + Matrix(pf_dparms)[:]:
        new_model['parameters_ordering'].append(p)
        new_model.parameters_values[p] = 0

    compregex = re.compile('(.*)<=(.*)<=(.*)')
    to_be_added = []

    expressions = Matrix(pf_parms) + Matrix(pf_dparms)*( Matrix(states) - Matrix(steady_states))

    for eq in new_model['equations_groups']['arbitrage']:
        if 'complementarity' in eq.tags:
            tg = eq.tags['complementarity']
            [lhs,mhs,rhs] = compregex.match(tg).groups()
            mhs = new_model.eval_string(mhs)
        else:
            mhs = None
        if mhs in pf_vars:

            i = pf_vars.index(mhs)
            eq_n = eq.tags['eq_number']
            neq = Equation(mhs, expressions[i])
            neq.tag(**eq.tags)
            new_model['equations'][eq_n] = neq
            eq_res = Equation(eq.gap, res_vars[i])
            eq_res.tag(eq_type='arbitrage')
            to_be_added.append(eq_res)

    new_model['equations'].extend(to_be_added)
    new_model.check()
    new_model.check_consistency(verbose=True)
    print(new_model.parameters)

    print(len(new_model['equations']))
    print(len(new_model.equations))
    print(len(new_model['equations_groups']['arbitrage']))

    print('parameters_ordering')
    print(new_model['parameters_ordering'])
    print(new_model.parameters)


    # now, we need to solve for the optimal portfolio coefficients
    from dolo.numeric.perturbations_to_states import approximate_controls

    dr = approximate_controls(new_model)
    print('ok')

    import numpy

    n_controls = len(model['variables_groups']['controls'])

    def constant_residuals(x):
        for i in range(n_pfs):
            p = pf_parms[i]
            v = pf_vars[i]
            new_model.parameters_values[p] = x[i]
            new_model.init_values[v] = x[i]
        [X_bar, X_s, X_ss] = approximate_controls(new_model, order=2, return_dr=False)
        return X_bar[n_controls-n_pfs:n_controls]

    x0 = numpy.zeros(n_pfs)

    from dolo.numeric.solver import solver
    portfolios_0 = solver(constant_residuals, x0)

    print('Zero order portfolios : ')
    print(portfolios_0)

    print('Zero order: Final error:')
    print(constant_residuals(portfolios_0))

    def dynamic_residuals(X, return_dr=False):
        x = X[:,0]
        dx = X[:,1:]
        for i in range(n_pfs):
            p = pf_parms[i]
            v = pf_vars[i]
            model.parameters_values[p] = x[i]
            model.init_values[v] = x[i]
            for j in range(n_states):
                model.parameters_values[pf_dparms[i][j]] = dx[i,j]
        if return_dr:
            dr = approximate_controls(new_model, order=2)
            return dr
        else:
            [X_bar, X_s, X_ss, X_sss] = approximate_controls(new_model, order=3, return_dr=False)
            crit = numpy.column_stack([
                X_bar[n_controls-n_pfs:n_controls],
                X_s[n_controls-n_pfs:n_controls,:],
            ])
            return crit



    y0 = numpy.column_stack([x0, numpy.zeros((n_pfs, n_states))])
    print('Initial error:')
    print(dynamic_residuals(y0))
    portfolios_1 = solver(dynamic_residuals, y0)

    print('First order portfolios : ')
    print(portfolios_1)

    print('Final error:')
    print(dynamic_residuals(portfolios_1))

    dr = dynamic_residuals(portfolios_1, return_dr=True)

    return dr
Exemple #10
0
def parse_yaml_text(txt,verbose=False, compiler=None):
    '''
Imports the content of a modfile into the current interpreter scope
'''
    txt = txt.replace('..','-')
    txt = txt.replace('--','-')
    txt = txt.replace('^','**')
    txt = txt.replace('equilibrium:','arbitrage:')
    txt = txt.replace('_|_','|')
    raw_dict = yaml.load(txt)

    if verbose == True:
        print('YAML file successfully parsed')

    declarations = raw_dict['declarations']
    # check
    variables_groups = OrderedDict()
    for vtype in declarations.keys():
        if vtype not in ('shocks','parameters'):
            variables_groups[vtype] = [Variable(vn) for vn in declarations[vtype]]
    variables_ordering = sum(variables_groups.values(),[])
#    else:
#        vnames = declarations['variables']
#        variables_ordering = [Variable(vn) for vn in vnames]
#        variables_groups = None

    parameters_ordering = [Parameter(vn) for vn in declarations['parameters']]
    shocks_ordering = [Shock(vn) for vn in declarations['shocks']]

    context = [(s.name,s) for s in variables_ordering + parameters_ordering + shocks_ordering]
    context = dict(context)

    from dolo.symbolic.symbolic import timeshift as TS


    # add some common functions
    for f in [sympy.log, sympy.exp,
              sympy.sin, sympy.cos, sympy.tan,
              sympy.asin, sympy.acos, sympy.atan,
              sympy.sinh, sympy.cosh, sympy.tanh,
              sympy.pi, sympy.sign]:
        context[str(f)] = f
    context['sqrt'] = sympy.sqrt

    context['TS'] = TS
    if 'horrible_hack' in raw_dict:
        tt = raw_dict['horrible_hack']
        exec(tt, context)


    import re
    # we recognize two kinds of equations:
    # lhs = rhs
    # lhs | comp where comp is a complementarity condition

    equations = []
    equations_groups = OrderedDict()
    raw_equations = raw_dict['equations']
    if not isinstance(raw_equations,dict):
        raw_dict['model_type'] = 'dynare'
        raw_equations = {'dynare_block': raw_equations}
    if True: # tests whether there are groups of equations
        for groupname in raw_equations.keys():
            equations_groups[groupname] = []
            for raw_eq in raw_equations[groupname]: # Modfile is supposed to represent a global model. TODO: change it
                teqg = raw_eq.split('|')
                teq = teqg[0]
                if '=' in teq:
                    lhs,rhs = str.split(teq,'=')
                else:
                    lhs = teq
                    rhs = '0'
                try:
                    lhs = eval(lhs,context)
                    rhs = eval(rhs,context)
                except Exception as e:
                    print('Error parsing equation : ' + teq)
                    print( str(e) )
                    raise e

                eq = Equation(lhs,rhs)
                eq.tag(eq_type=groupname)
                if len(teqg)>1:
                    comp = teqg[1]
                    eq.tag(complementarity=comp)
                equations.append(eq)
                equations_groups[groupname].append( eq )
    else:
        for teq in raw_equations:
            if '=' in teq:
                lhs,rhs = str.split(teq,'=')
            else:
                lhs = teq
                rhs = '0'
            try:
                lhs = eval(lhs,context)
                rhs = eval(rhs,context)
            except Exception as e:
                print('Error parsing equations : ' + teq)
                print(str(e))
            eq = Equation(lhs,rhs)
            equations.append(eq)
        equations_groups = None

    parameters_values = {}
    init_values = {}
    covariances = None
    if 'calibration' in raw_dict:
        calibration = raw_dict['calibration']
        if 'parameters' in calibration:
            parameters_values = [ (Parameter(k), eval(str(v),context)) for k,v in iteritems(calibration['parameters']) ]
            parameters_values = dict(parameters_values)
        #steady_state = raw_dict['steady_state']
        if 'steady_state' in calibration:
            init_values = [ (Variable(vn), eval(str(value),context)) for vn,value in iteritems(calibration['steady_state']) ]
            init_values = dict(init_values)
        if 'covariances' in calibration:
            context['sympy'] = sympy
            covariances = eval('sympy.Matrix({0})'.format( calibration['covariances'] ), context)
        else:
            covariances = None # to avoid importing numpy

    symbols = variables_groups

    symbols['shocks'] = shocks_ordering
    symbols['parameters'] = parameters_ordering

    calibration_s = {}
    calibration_s.update(parameters_values)
    calibration_s.update(init_values)

    from dolo.symbolic.model import SModel

    model = SModel( equations_groups, symbols, calibration_s, covariances )
    model.__data__ = raw_dict



    return model
Exemple #11
0
                    print('Impossible to evaluate : \n' + str(t))
                    raise e
            residuals[gname] = [float(eq.gap.subs(dd)) for eq in geqs]
        return residuals
    else:
        stateq = [eq.gap.subs(dd) for eq in model.equations]
        residuals = [float(eq) for eq in stateq]
        return residuals


def print_residuals(model):
    residuals = compute_residuals(model)

    print('\n{:*^90}\n'.format('Residuals'))
    for category in residuals.keys():
        res = residuals[category]
        print category
        for i, eq in enumerate(model['equations_groups'][category]):
            print('\t{:03.4f}\t:\t{}'.format(res[i], eq))


if __name__ == '__main__':

    from dolo.symbolic.symbolic import Variable, Equation

    v = Variable('v', 0)

    eq = Equation(v**2, v(1) - v(-1))

    d = Model(equations=[eq])
Exemple #12
0
def parse_yaml_text(txt, verbose=False, compiler=None):
    '''
Imports the content of a modfile into the current interpreter scope
'''
    txt = txt.replace('..', '-')
    txt = txt.replace('--', '-')
    txt = txt.replace('^', '**')
    txt = txt.replace('equilibrium:', 'arbitrage:')
    txt = txt.replace('_|_', '|')
    raw_dict = yaml.load(txt)

    if verbose == True:
        print('YAML file successfully parsed')

    declarations = raw_dict['declarations']
    # check
    variables_groups = OrderedDict()
    for vtype in declarations.keys():
        if vtype not in ('shocks', 'parameters'):
            variables_groups[vtype] = [
                Variable(vn) for vn in declarations[vtype]
            ]
    variables_ordering = sum(variables_groups.values(), [])
    #    else:
    #        vnames = declarations['variables']
    #        variables_ordering = [Variable(vn) for vn in vnames]
    #        variables_groups = None

    parameters_ordering = [Parameter(vn) for vn in declarations['parameters']]
    shocks_ordering = [Shock(vn) for vn in declarations['shocks']]

    context = [
        (s.name, s)
        for s in variables_ordering + parameters_ordering + shocks_ordering
    ]
    context = dict(context)

    from dolo.symbolic.symbolic import timeshift as TS

    # add some common functions
    for f in [
            sympy.log, sympy.exp, sympy.sin, sympy.cos, sympy.tan, sympy.asin,
            sympy.acos, sympy.atan, sympy.sinh, sympy.cosh, sympy.tanh,
            sympy.pi, sympy.sign
    ]:
        context[str(f)] = f
    context['sqrt'] = sympy.sqrt

    context['TS'] = TS
    if 'horrible_hack' in raw_dict:
        tt = raw_dict['horrible_hack']
        exec(tt, context)

    import re
    # we recognize two kinds of equations:
    # lhs = rhs
    # lhs | comp where comp is a complementarity condition

    equations = []
    equations_groups = OrderedDict()
    raw_equations = raw_dict['equations']
    if not isinstance(raw_equations, dict):
        raw_dict['model_type'] = 'dynare'
        raw_equations = {'dynare_block': raw_equations}
    if True:  # tests whether there are groups of equations
        for groupname in raw_equations.keys():
            equations_groups[groupname] = []
            for raw_eq in raw_equations[
                    groupname]:  # Modfile is supposed to represent a global model. TODO: change it
                teqg = raw_eq.split('|')
                teq = teqg[0]
                if '=' in teq:
                    lhs, rhs = str.split(teq, '=')
                else:
                    lhs = teq
                    rhs = '0'
                try:
                    lhs = eval(lhs, context)
                    rhs = eval(rhs, context)
                except Exception as e:
                    print('Error parsing equation : ' + teq)
                    print(str(e))
                    raise e

                eq = Equation(lhs, rhs)
                eq.tag(eq_type=groupname)
                if len(teqg) > 1:
                    comp = teqg[1]
                    eq.tag(complementarity=comp)
                equations.append(eq)
                equations_groups[groupname].append(eq)
    else:
        for teq in raw_equations:
            if '=' in teq:
                lhs, rhs = str.split(teq, '=')
            else:
                lhs = teq
                rhs = '0'
            try:
                lhs = eval(lhs, context)
                rhs = eval(rhs, context)
            except Exception as e:
                print('Error parsing equations : ' + teq)
                print(str(e))
            eq = Equation(lhs, rhs)
            equations.append(eq)
        equations_groups = None

    parameters_values = {}
    init_values = {}
    covariances = None
    if 'calibration' in raw_dict:
        calibration = raw_dict['calibration']
        if 'parameters' in calibration:
            parameters_values = [
                (Parameter(k), eval(str(v), context))
                for k, v in iteritems(calibration['parameters'])
            ]
            parameters_values = dict(parameters_values)
        #steady_state = raw_dict['steady_state']
        if 'steady_state' in calibration:
            init_values = [
                (Variable(vn), eval(str(value), context))
                for vn, value in iteritems(calibration['steady_state'])
            ]
            init_values = dict(init_values)
        if 'covariances' in calibration:
            context['sympy'] = sympy
            covariances = eval(
                'sympy.Matrix({0})'.format(calibration['covariances']),
                context)
        else:
            covariances = None  # to avoid importing numpy

    symbols = variables_groups

    symbols['shocks'] = shocks_ordering
    symbols['parameters'] = parameters_ordering

    calibration_s = {}
    calibration_s.update(parameters_values)
    calibration_s.update(init_values)

    from dolo.symbolic.model import SModel

    model = SModel(equations_groups, symbols, calibration_s, covariances)
    model.__data__ = raw_dict

    return model
Exemple #13
0
def solve_portfolio_model(model, pf_names, order=2, guess=None):

    from dolo.compiler.compiler_python import GModel
    if isinstance(model, GModel):
        model = model.model

    pf_model = model

    from dolo import Variable, Parameter, Equation
    import re

    n_states = len(pf_model.symbols_s['states'])
    states = pf_model.symbols_s['states']
    steady_states = [
        Parameter(v.name + '_bar') for v in pf_model.symbols_s['states']
    ]
    n_pfs = len(pf_names)

    pf_vars = [Variable(v) for v in pf_names]
    res_vars = [Variable('res_' + str(i)) for i in range(n_pfs)]

    pf_parms = [Parameter('K_' + str(i)) for i in range(n_pfs)]
    pf_dparms = [[
        Parameter('K_' + str(i) + '_' + str(j)) for j in range(n_states)
    ] for i in range(n_pfs)]

    from sympy import Matrix

    # creation of the new model

    import copy

    new_model = copy.copy(pf_model)

    new_model.symbols_s['controls'] += res_vars
    for v in res_vars + pf_vars:
        new_model.calibration_s[v] = 0

    new_model.symbols_s['parameters'].extend(steady_states)
    for p in pf_parms + Matrix(pf_dparms)[:]:
        new_model.symbols_s['parameters'].append(p)
        new_model.calibration_s[p] = 0

    compregex = re.compile('(.*)<=(.*)<=(.*)')

    to_be_added_1 = []
    to_be_added_2 = []

    expressions = Matrix(pf_parms) + Matrix(pf_dparms) * (
        Matrix(states) - Matrix(steady_states))

    for n, eq in enumerate(new_model.equations_groups['arbitrage']):
        if 'complementarity' in eq.tags:
            tg = eq.tags['complementarity']
            [lhs, mhs, rhs] = compregex.match(tg).groups()
            mhs = new_model.eval_string(mhs)
        else:
            mhs = None
        if mhs in pf_vars:
            i = pf_vars.index(mhs)
            neq = Equation(mhs, expressions[i])
            neq.tag(**eq.tags)
            eq_res = Equation(eq.gap, res_vars[i])
            eq_res.tag(eq_type='arbitrage')
            to_be_added_2.append(eq_res)
            new_model.equations_groups['arbitrage'][n] = neq
            to_be_added_1.append(neq)

    # new_model.equations_groups['arbitrage'].extend(to_be_added_1)
    new_model.equations_groups['arbitrage'].extend(to_be_added_2)
    new_model.update()

    print("number of equations {}".format(len(new_model.equations)))
    print("number of arbitrage equations {}".format(
        len(new_model.equations_groups['arbitrage'])))

    print('parameters_ordering')
    print("number of parameters {}".format(new_model.symbols['parameters']))
    print("number of parameters {}".format(new_model.parameters))

    # now, we need to solve for the optimal portfolio coefficients
    from dolo.numeric.perturbations_to_states import approximate_controls

    dr = approximate_controls(new_model)
    print('ok')

    import numpy

    n_controls = len(model.symbols_s['controls'])

    def constant_residuals(x, return_dr=False):
        d = {}
        for i in range(n_pfs):
            p = pf_parms[i]
            v = pf_vars[i]
            d[p] = x[i]
            d[v] = x[i]
        new_model.set_calibration(d)
        # new_model.parameters_values[p] = x[i]
        # new_model.init_values[v] = x[i]
        if return_dr:
            dr = approximate_controls(new_model, order=1, return_dr=True)
            return dr
        X_bar, X_s, X_ss = approximate_controls(new_model,
                                                order=2,
                                                return_dr=False)

        return X_bar[n_controls - n_pfs:n_controls]

    if guess is not None:
        x0 = numpy.array(guess)
    else:
        x0 = numpy.zeros(n_pfs)

    from dolo.numeric.solver import solver
    portfolios_0 = solver(constant_residuals, x0)

    print('Zero order portfolios: {}'.format(portfolios_0))
    print('Zero order portfolios: Final error: {}'.format(
        constant_residuals(portfolios_0)))

    if order == 1:
        dr = constant_residuals(portfolios_0, return_dr=True)
        return dr

    def dynamic_residuals(X, return_dr=False):
        x = X[:, 0]
        dx = X[:, 1:]
        d = {}
        for i in range(n_pfs):
            p = pf_parms[i]
            v = pf_vars[i]
            d[p] = x[i]
            d[v] = x[i]
            for j in range(n_states):
                d[pf_dparms[i][j]] = dx[i, j]
        new_model.set_calibration(d)
        if return_dr:
            dr = approximate_controls(new_model, order=2)
            return dr
        else:
            [X_bar, X_s, X_ss, X_sss] = approximate_controls(new_model,
                                                             order=3,
                                                             return_dr=False)
            crit = numpy.column_stack([
                X_bar[n_controls - n_pfs:n_controls],
                X_s[n_controls - n_pfs:n_controls, :],
            ])
            return crit

    y0 = numpy.column_stack([x0, numpy.zeros((n_pfs, n_states))])
    print('Initial error:')
    print(dynamic_residuals(y0))
    portfolios_1 = solver(dynamic_residuals, y0)

    print('First order portfolios : ')
    print(portfolios_1)

    print('Final error:')
    print(dynamic_residuals(portfolios_1))

    dr = dynamic_residuals(portfolios_1, return_dr=True)

    return dr
Exemple #14
0
def solve_portfolio_model(model, pf_names, order=1):

    pf_model = model

    from dolo import Variable, Parameter, Equation
    import re

    n_states = len(pf_model['variables_groups']['states'])
    states = pf_model['variables_groups']['states']
    steady_states = [
        Parameter(v.name + '_bar')
        for v in pf_model['variables_groups']['states']
    ]
    n_pfs = len(pf_names)

    pf_vars = [Variable(v, 0) for v in pf_names]
    res_vars = [Variable('res_' + str(i), 0) for i in range(n_pfs)]

    pf_parms = [Parameter('K_' + str(i)) for i in range(n_pfs)]
    pf_dparms = [[
        Parameter('K_' + str(i) + '_' + str(j)) for j in range(n_states)
    ] for i in range(n_pfs)]

    from sympy import Matrix

    # creation of the new model

    import copy
    print('Warning: initial model has been changed.')
    new_model = copy.copy(pf_model)
    new_model['variables_groups']['controls'] += res_vars
    new_model.check()

    for p in pf_parms + Matrix(pf_dparms)[:]:
        new_model['parameters_ordering'].append(p)
        new_model.parameters_values[p] = 0

    compregex = re.compile('(.*)<=(.*)<=(.*)')
    to_be_added = []

    expressions = Matrix(pf_parms) + Matrix(pf_dparms) * (
        Matrix(states) - Matrix(steady_states))

    for eq in new_model['equations_groups']['arbitrage']:
        if 'complementarity' in eq.tags:
            tg = eq.tags['complementarity']
            [lhs, mhs, rhs] = compregex.match(tg).groups()
            mhs = new_model.eval_string(mhs)
        else:
            mhs = None
        if mhs in pf_vars:

            i = pf_vars.index(mhs)
            eq_n = eq.tags['eq_number']
            neq = Equation(mhs, expressions[i])
            neq.tag(**eq.tags)
            new_model['equations'][eq_n] = neq
            eq_res = Equation(eq.gap, res_vars[i])
            eq_res.tag(eq_type='arbitrage')
            to_be_added.append(eq_res)

    new_model['equations'].extend(to_be_added)
    new_model.check()
    new_model.check_consistency()

    # now, we need to solve for the optimal portfolio coefficients
    from dolo.numeric.perturbations_to_states import approximate_controls

    import numpy

    n_controls = len(model['variables_groups']['controls'])

    def constant_residuals(x):
        for i in range(n_pfs):
            p = pf_parms[i]
            v = pf_vars[i]
            model.parameters_values[p] = x[i]
            model.init_values[v] = x[i]
        [X_bar, X_s, X_ss] = approximate_controls(new_model,
                                                  order=2,
                                                  return_dr=False)
        return X_bar[n_controls - n_pfs:n_controls]

    x0 = numpy.zeros(n_pfs)

    from dolo.numeric.solver import solver
    portfolios_0 = solver(constant_residuals, x0)

    print('Zero order portfolios : ')
    print(portfolios_0)

    print('Zero order: Final error:')
    print(constant_residuals(portfolios_0))

    def dynamic_residuals(X, return_dr=False):
        x = X[:, 0]
        dx = X[:, 1:]
        for i in range(n_pfs):
            p = pf_parms[i]
            v = pf_vars[i]
            model.parameters_values[p] = x[i]
            model.init_values[v] = x[i]
            for j in range(n_states):
                model.parameters_values[pf_dparms[i][j]] = dx[i, j]
        if return_dr:
            dr = approximate_controls(new_model, order=2, return_dr=True)
            return dr
        else:
            [X_bar, X_s, X_ss, X_sss] = approximate_controls(new_model,
                                                             order=3,
                                                             return_dr=False)
            crit = numpy.column_stack([
                X_bar[n_controls - n_pfs:n_controls],
                X_s[n_controls - n_pfs:n_controls, :],
            ])
            return crit

    y0 = numpy.column_stack([x0, numpy.zeros((n_pfs, n_states))])
    print('Initial error:')
    print(dynamic_residuals(y0))
    portfolios_1 = solver(dynamic_residuals, y0)

    print('First order portfolios : ')
    print(portfolios_1)

    print('Final error:')
    print(dynamic_residuals(portfolios_1))

    dr = dynamic_residuals(portfolios_1, return_dr=True)

    return dr
Exemple #15
0
    def read_model(self):

        if self.__transformed_model__:
            return self.__transformed_model__


        dmodel = SModel(**self.model) # copy the model
        dmodel.check_consistency(auto_remove_variables=False)

        def_eqs = [eq for eq in dmodel.equations if eq.tags['eq_type'] in ('def', 'auxiliary')]

        from dolo.symbolic.symbolic import map_function_to_expression
        from dolo.symbolic.symbolic import Variable
        def timeshift(v,n):
            if isinstance(v,Variable):
                return v(n)
            else:
                return v

        import sympy

        #### build substitution dict
        def_dict = {}
        for eq in def_eqs:
            v = eq.lhs
            rhs = sympy.sympify( eq.rhs )
            def_dict[v] = rhs
            def_dict[v(1)] = map_function_to_expression( lambda x: timeshift(x,1), rhs)

        new_equations = []
        tbr = []
        for i,eq in enumerate(dmodel.equations) :
            if not ('def' == eq.tags['eq_type']):
                lhs = sympy.sympify( eq.lhs ).subs(def_dict)
                rhs = sympy.sympify( eq.rhs ).subs(def_dict)
                neq = Equation(lhs,rhs).tag(**eq.tags)
                new_equations.append( neq )

        dmodel['equations'] = new_equations
        dmodel.check_consistency()



        f_eqs = [eq for eq in dmodel.equations if eq.tags['eq_type'] in ('f','arbitrage')]
        g_eqs = [eq for eq in dmodel.equations if eq.tags['eq_type'] in ('g','transition')]
        h_eqs = [eq for eq in dmodel.equations if eq.tags['eq_type'] in ('h','expectation')]



        states_vars = [eq.lhs for eq in g_eqs]
        exp_vars =  [eq.lhs for eq in h_eqs]
        controls = set(dmodel.variables) - set(states_vars + exp_vars)
        controls = list(controls)

        states_vars = [v for v in dmodel.variables if v in states_vars]
        exp_vars = [v for v in dmodel.variables if v in exp_vars]
        controls = [v for v in dmodel.variables if v in controls]


        # now we remove the left side of equations
        f_eqs = [eq.gap for eq in f_eqs]
        g_eqs = [eq.rhs for eq in g_eqs]
        h_eqs = [eq.rhs for eq in h_eqs]

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


    #    sub_list[v] = v.name

        # read complementarity conditions
        compcond = {}
        of_eqs = [eq for eq in dmodel.equations if eq.tags['eq_type'] in ('f','arbitrage')]
        locals = {}
        import sympy
        locals['inf'] = sympy.Symbol('inf')
        locals['log'] = sympy.log # this should be more generic
        locals['exp'] = sympy.exp

        for v in dmodel.variables + dmodel.parameters:
            locals[v.name] = v
        import re
        compregex = re.compile('(.*)<=(.*)<=(.*)')
        for eq in of_eqs:
            tg = eq.tags['complementarity']
            [lhs,mhs,rhs] = compregex.match(tg).groups()
            [lhs,mhs,rhs] = [dmodel.eval_string(x) for x in [lhs,mhs,rhs] ]
            compcond[mhs] = (lhs,rhs)

        complementarities = [compcond[v] for v in controls]

        inf_bounds = [c[0] for c in complementarities]
        sup_bounds = [c[1] for c in complementarities]

        data = {
            'f_eqs': f_eqs,
            'g_eqs': g_eqs,
            'h_eqs': h_eqs,
            'controls': controls,
            'states_vars': states_vars,
            'exp_vars': exp_vars,
            'inf_bounds': inf_bounds,
            'sup_bounds': sup_bounds
        }

        self.__transformed_model__ = data # cache computation

        return data
def solve_portfolio_model(model, pf_names, order=2, guess=None):

    from dolo.compiler.compiler_python import GModel
    if isinstance(model, GModel):
        model = model.model

    pf_model = model

    from dolo import Variable, Parameter, Equation
    import re

    n_states = len(pf_model.symbols_s['states'])
    states = pf_model.symbols_s['states']
    steady_states = [Parameter(v.name+'_bar') for v in pf_model.symbols_s['states']]
    n_pfs = len(pf_names)

    pf_vars = [Variable(v) for v in pf_names]
    res_vars = [Variable('res_'+str(i)) for i in range(n_pfs)]


    pf_parms = [Parameter('K_'+str(i)) for i in range(n_pfs)]
    pf_dparms = [[Parameter('K_'+str(i)+'_'+str(j)) for j in range(n_states)] for i in range(n_pfs)]

    from sympy import Matrix

    # creation of the new model

    import copy

    new_model = copy.copy(pf_model)

    new_model.symbols_s['controls'] += res_vars
    for v in res_vars + pf_vars:
        new_model.calibration_s[v] = 0


    new_model.symbols_s['parameters'].extend(steady_states)
    for p in pf_parms + Matrix(pf_dparms)[:]:
        new_model.symbols_s['parameters'].append(p)
        new_model.calibration_s[p] = 0

    compregex = re.compile('(.*)<=(.*)<=(.*)')

    to_be_added_1 = []
    to_be_added_2 = []

    expressions = Matrix(pf_parms) + Matrix(pf_dparms)*( Matrix(states) - Matrix(steady_states))

    for n,eq in enumerate(new_model.equations_groups['arbitrage']):
        if 'complementarity' in eq.tags:
            tg = eq.tags['complementarity']
            [lhs,mhs,rhs] = compregex.match(tg).groups()
            mhs = new_model.eval_string(mhs)
        else:
            mhs = None
        if mhs in pf_vars:
            i = pf_vars.index(mhs)
            neq = Equation(mhs, expressions[i])
            neq.tag(**eq.tags)
            eq_res = Equation(eq.gap, res_vars[i])
            eq_res.tag(eq_type='arbitrage')
            to_be_added_2.append(eq_res)
            new_model.equations_groups['arbitrage'][n] = neq
            to_be_added_1.append(neq)

    # new_model.equations_groups['arbitrage'].extend(to_be_added_1)
    new_model.equations_groups['arbitrage'].extend(to_be_added_2)
    new_model.update()

    print("number of equations {}".format(len(new_model.equations)))
    print("number of arbitrage equations {}".format( len(new_model.equations_groups['arbitrage'])) )

    print('parameters_ordering')
    print("number of parameters {}".format(new_model.symbols['parameters']))
    print("number of parameters {}".format(new_model.parameters))


    # now, we need to solve for the optimal portfolio coefficients
    from dolo.numeric.perturbations_to_states import approximate_controls

    dr = approximate_controls(new_model)
    print('ok')

    import numpy

    n_controls = len(model.symbols_s['controls'])

    def constant_residuals(x, return_dr=False):
        d = {}
        for i in range(n_pfs):
            p = pf_parms[i]
            v = pf_vars[i]
            d[p] = x[i]
            d[v] = x[i]
        new_model.set_calibration(d)
            # new_model.parameters_values[p] = x[i]
            # new_model.init_values[v] = x[i]
        if return_dr:
            dr = approximate_controls(new_model, order=1, return_dr=True)
            return dr
        X_bar, X_s, X_ss = approximate_controls(new_model, order=2, return_dr=False)

        return X_bar[n_controls-n_pfs:n_controls]


    if guess is not None:
        x0 = numpy.array(guess)
    else:
        x0 = numpy.zeros(n_pfs)


    from dolo.numeric.solver import solver
    portfolios_0 = solver(constant_residuals, x0)

    print('Zero order portfolios: {}'.format(portfolios_0))
    print('Zero order portfolios: Final error: {}'.format( constant_residuals(portfolios_0) ))

    if order == 1:
        dr = constant_residuals(portfolios_0, return_dr=True)
        return dr

    def dynamic_residuals(X, return_dr=False):
        x = X[:,0]
        dx = X[:,1:]
        d = {}
        for i in range(n_pfs):
            p = pf_parms[i]
            v = pf_vars[i]
            d[p] = x[i]
            d[v] = x[i]
            for j in range(n_states):
                d[pf_dparms[i][j]] = dx[i,j]
        new_model.set_calibration(d)
        if return_dr:
            dr = approximate_controls(new_model, order=2)
            return dr
        else:
            [X_bar, X_s, X_ss, X_sss] = approximate_controls(new_model, order=3, return_dr=False)
            crit = numpy.column_stack([
                X_bar[n_controls-n_pfs:n_controls],
                X_s[n_controls-n_pfs:n_controls,:],
            ])
            return crit



    y0 = numpy.column_stack([x0, numpy.zeros((n_pfs, n_states))])
    print('Initial error:')
    print(dynamic_residuals(y0))
    portfolios_1 = solver(dynamic_residuals, y0)

    print('First order portfolios : ')
    print(portfolios_1)

    print('Final error:')
    print(dynamic_residuals(portfolios_1))

    dr = dynamic_residuals(portfolios_1, return_dr=True)

    return dr