Example #1
0
    def ℰ(self):

        if self.__equilibrium__ is None:
            if self.features["with-aggregate-states"]:
                arguments_ = {
                    "e": [(e, 0) for e in self.model.symbols["exogenous"]],
                    "s": [(e, 0) for e in self.model.symbols["states"]],
                    "x": [(e, 0) for e in self.model.symbols["controls"]],
                    "m": [(e, 0) for e in self.symbols["exogenous"]],
                    "S": [(e, 0) for e in self.symbols["states"]],
                    "X": [(e, 0) for e in self.symbols["aggregate"]],
                    "m_1": [(e, 1) for e in self.symbols["exogenous"]],
                    "S_1": [(e, 1) for e in self.symbols["states"]],
                    "X_1": [(e, 1) for e in self.symbols["aggregate"]],
                    "p": self.symbols["parameters"],
                }
            else:
                arguments_ = {
                    "e": [(e, 0) for e in self.model.symbols["exogenous"]],
                    "s": [(e, 0) for e in self.model.symbols["states"]],
                    "x": [(e, 0) for e in self.model.symbols["controls"]],
                    "m": [(e, 0) for e in self.symbols["exogenous"]],
                    "X": [(e, 0) for e in self.symbols["aggregate"]],
                    "m_1": [(e, 1) for e in self.symbols["exogenous"]],
                    "X_1": [(e, 1) for e in self.symbols["aggregate"]],
                    "p": self.symbols["parameters"],
                }

            vars = sum([[e[0] for e in h]
                        for h in [*arguments_.values()][:-1]], [])

            arguments = {
                k: [dolang.symbolic.stringify_symbol(e) for e in v]
                for k, v in arguments_.items()
            }

            preamble = {}  # for now

            from dolang.symbolic import sanitize, stringify

            eqs = parse_string(self.data["equilibrium"],
                               start="equation_block")
            eqs = sanitize(eqs, variables=vars)
            eqs = stringify(eqs)
            content = {}
            for i, eq in enumerate(eqs.children):
                lhs, rhs = eq.children
                content[f"eq_{i}"] = "({1})-({0})".format(
                    str_expression(lhs), str_expression(rhs))

            fff = FlatFunctionFactory(preamble, content, arguments,
                                      "equilibrium")
            _, gufun = dolang.function_compiler.make_method_from_factory(
                fff, debug=self.debug)
            from dolang.vectorize import standard_function

            self.__equilibrium__ = standard_function(gufun, len(content))

        return self.__equilibrium__
Example #2
0
    def check(self):

        from dolang.symbolic import remove_timing, parse_string, str_expression

        p = self.data.get("projection")
        if p is None:
            raise AggregateException("Missing 'projection section'.")
        else:
            exo = self.model.symbols["exogenous"]
            proj = []
            eqs = parse_string(p, start="assignment_block")
            for eq in eqs.children:
                lhs, _ = eq.children
                lhs = remove_timing(lhs)
                lhs = str_expression(lhs)
                proj.append(lhs)

            exo_in_proj = [e for e in exo if e in proj]
            diff = set(proj).difference(set(exo_in_proj))
            if diff:
                raise AggregateException(
                    f"Some projected values were not defined as exogenous in the agent's program: {', '.join(diff)}."
                )

        t = self.data.get("transition")
        states = self.symbols.get("states")
        if t is not None and states is None:
            raise AggregateException(
                f"Aggregate transition equations are defined, whereas no aggregate state is filled in."
            )
        elif t is None and states is not None:
            raise AggregateException(
                f"Aggregate states are defined, whereas no transition equation is filled in."
            )
        elif t is not None and states is not None:
            trans = []
            eqs = parse_string(t, start="assignment_block")
            for eq in eqs.children:
                lhs, _ = eq.children
                lhs = remove_timing(lhs)
                lhs = str_expression(lhs)
                trans.append(lhs)

            states_in_trans = [e for e in states if e in trans]
            trans_in_states = [e for e in trans if e in states]
            diff = set(trans).difference(set(states_in_trans))
            if diff:
                raise AggregateException(
                    f"Some variables defined in transition equations are not filled in aggregate states: {', '.join(diff)}."
                )

            diff = set(states).difference(set(trans_in_states))
            if diff:
                raise AggregateException(
                    f"Some aggregate states do not have transition equations filled in: {', '.join(diff)}."
                )
Example #3
0
    def projection(self):  # , m: 'n_e', y: "n_y", p: "n_p"):

        # TODO:
        # behaves in a very misleading way if wrong number of argument is supplied
        #  if no aggregate states, projection(m,x) (instead of projection(m,x,p)) returns zeros

        if self.__projection__ is None:
            if self.features["with-aggregate-states"]:
                arguments_ = {
                    "m": [(e, 0) for e in self.symbols["exogenous"]],
                    "S": [(e, 0) for e in self.symbols["states"]],
                    "X": [(e, 0) for e in self.symbols["aggregate"]],
                    "p": self.symbols["parameters"],
                }
            else:
                arguments_ = {
                    "m": [(e, 0) for e in self.symbols["exogenous"]],
                    "X": [(e, 0) for e in self.symbols["aggregate"]],
                    "p": self.symbols["parameters"],
                }

            vars = sum([[e[0] for e in h]
                        for h in [*arguments_.values()][:-1]], [])

            arguments = {
                k: [dolang.symbolic.stringify_symbol(e) for e in v]
                for k, v in arguments_.items()
            }

            preamble = {}  # for now

            from dolang.symbolic import sanitize, stringify

            eqs = parse_string(self.data["projection"],
                               start="assignment_block")
            eqs = sanitize(eqs, variables=vars)
            eqs = stringify(eqs)

            content = {}
            for eq in eqs.children:
                lhs, rhs = eq.children
                content[str_expression(lhs)] = str_expression(rhs)

            fff = FlatFunctionFactory(preamble, content, arguments,
                                      "equilibrium")
            _, gufun = dolang.function_compiler.make_method_from_factory(
                fff, debug=self.debug)

            from dolang.vectorize import standard_function

            self.__projection__ = standard_function(gufun, len(content))

        return self.__projection__
Example #4
0
    def 𝒢(self):

        if (self.__transition__ is
                None) and self.features["with-aggregate-states"]:
            arguments_ = {
                "m_m1": [(e, -1) for e in self.symbols["exogenous"]],
                "S_m1": [(e, -1) for e in self.symbols["states"]],
                "X_m1": [(e, -1) for e in self.symbols["aggregate"]],
                "m": [(e, 0) for e in self.symbols["exogenous"]],
                "p": self.symbols["parameters"],
            }

            vars = sum([[e[0] for e in h]
                        for h in [*arguments_.values()][:-1]], [])

            arguments = {
                k: [dolang.symbolic.stringify_symbol(e) for e in v]
                for k, v in arguments_.items()
            }

            preamble = {}  # for now

            from dolang.symbolic import (
                sanitize,
                parse_string,
                str_expression,
                stringify,
            )

            eqs = parse_string(self.data["transition"],
                               start="assignment_block")
            eqs = sanitize(eqs, variables=vars)
            eqs = stringify(eqs)

            content = {}
            for i, eq in enumerate(eqs.children):
                lhs, rhs = eq.children
                content[str_expression(lhs)] = str_expression(rhs)

            from dolang.factory import FlatFunctionFactory

            fff = FlatFunctionFactory(preamble, content, arguments,
                                      "transition")

            _, gufun = dolang.function_compiler.make_method_from_factory(
                fff, debug=self.debug)

            from dolang.vectorize import standard_function

            self.__transition__ = standard_function(gufun, len(content))

        return self.__transition__
Example #5
0
    def get_calibration(self):

        from dolang.symbolic import remove_timing

        import copy

        calibration = dict()
        for k, v in self.data.get("calibration", {}).items():
            if v.tag == "tag:yaml.org,2002:str":

                expr = parse_string(v)
                expr = remove_timing(expr)
                expr = str_expression(expr)
            else:
                expr = float(v.value)
            kk = remove_timing(parse_string(k))
            kk = str_expression(kk)

            calibration[kk] = expr

        from dolang.triangular_solver import solve_triangular_system

        return solve_triangular_system(calibration)
Example #6
0
    def equations(self):
        import yaml.nodes

        if self.__equations__ is None:

            vars = self.variables + [*self.definitions.keys()]

            d = dict()
            for g, v in self.data["equations"].items():

                # new style
                if isinstance(v, yaml.nodes.ScalarNode):
                    assert v.style == "|"
                    if g in ("arbitrage", ):
                        start = "complementarity_block"
                    else:
                        start = "assignment_block"
                    eqs = parse_string(v, start=start)
                    eqs = sanitize(eqs, variables=vars)
                    eq_list = eqs.children
                # old style
                else:
                    eq_list = []
                    for eq_string in v:
                        start = "equation"  # it should be assignment
                        eq = parse_string(eq_string, start=start)
                        eq = sanitize(eq, variables=vars)
                        eq_list.append(eq)

                if g in ("arbitrage", ):
                    ll = []  # List[str]
                    ll_lb = []  # List[str]
                    ll_ub = []  # List[str]
                    with_complementarity = False
                    for i, eq in enumerate(eq_list):
                        if eq.data == "double_complementarity":
                            v = eq.children[1].children[1].children[
                                0].children[0].value
                            t = int(eq.children[1].children[1].children[1].
                                    children[0].value)
                            expected = (
                                self.symbols["controls"][i],
                                0,
                            )  # TODO raise nice error message
                            if (v, t) != expected:
                                raise Exception(
                                    f"Incorrect variable in complementarity: expected {expected}. Found {(v,t)}"
                                )
                            ll_lb.append(
                                str_expression(eq.children[1].children[0]))
                            ll_ub.append(
                                str_expression(eq.children[1].children[2]))
                            eq = eq.children[0]
                            with_complementarity = True
                        else:
                            ll_lb.append("-inf")
                            ll_ub.append("inf")
                        from dolang.symbolic import list_symbols

                        # syms = list_symbols(eq)
                        ll.append(str_expression(eq))
                    d[g] = ll
                    if with_complementarity:
                        d[g + "_lb"] = ll_lb
                        d[g + "_ub"] = ll_ub
                else:
                    # TODO: we should check here that equations are well specified
                    d[g] = [str_expression(e) for e in eq_list]

            # if "controls_lb" not in d:
            #     for ind, g in enumerate(("controls_lb", "controls_ub")):
            #         eqs = []
            #         for i, eq in enumerate(d['arbitrage']):
            #             if "⟂" not in eq:
            #                 if ind == 0:
            #                     eq = "-inf"
            #                 else:
            #                     eq = "inf"
            #             else:
            #                 comp = eq.split("⟂")[1].strip()
            #                 v = self.symbols["controls"][i]
            #                 eq = decode_complementarity(comp, v+"[t]")[ind]
            #             eqs.append(eq)
            #         d[g] = eqs

            self.__equations__ = d

        return self.__equations__
Example #7
0
    def get_calibration(self):

        # if self.__calibration__ is None:

        from dolang.symbolic import remove_timing

        import copy

        symbols = self.symbols
        calibration = dict()
        for k, v in self.data.get("calibration", {}).items():
            if v.tag == "tag:yaml.org,2002:str":

                expr = parse_string(v)
                expr = remove_timing(expr)
                expr = str_expression(expr)
            else:
                expr = float(v.value)
            kk = remove_timing(parse_string(k))
            kk = str_expression(kk)

            calibration[kk] = expr

        definitions = self.definitions

        initial_values = {
            "exogenous": 0,
            "expectations": 0,
            "values": 0,
            "controls": float("nan"),
            "states": float("nan"),
        }

        # variables defined by a model equation default to using these definitions
        initialized_from_model = {
            "values": "value",
            "expectations": "expectation",
            "direct_responses": "direct_response",
        }
        for k, v in definitions.items():
            kk = remove_timing(k)
            if kk not in calibration:
                if isinstance(v, str):
                    vv = remove_timing(v)
                else:
                    vv = v
                calibration[kk] = vv

        for symbol_group in symbols:
            if symbol_group not in initialized_from_model.keys():
                if symbol_group in initial_values:
                    default = initial_values[symbol_group]
                else:
                    default = float("nan")
                for s in symbols[symbol_group]:
                    if s not in calibration:
                        calibration[s] = default

        from dolang.triangular_solver import solve_triangular_system

        return solve_triangular_system(calibration)
Example #8
0
    def definitions(self):

        from yaml import ScalarNode

        if self.__definitions__ is None:

            # at this stage, basic_symbols doesn't contain auxiliaries
            basic_symbols = self.symbols
            vars = sum(
                [
                    basic_symbols[k]
                    for k in basic_symbols.keys() if k != "parameters"
                ],
                [],
            )

            # # auxiliaries = [remove_timing(parse_string(k)) for k in self.data.get('definitions', {})]
            # # auxiliaries = [str_expression(e) for e in auxiliaries]
            # # symbols['auxiliaries'] = auxiliaries

            if "definitions" not in self.data:
                self.__definitions__ = {}
                # self.__symbols__['auxiliaries'] = []

            elif isinstance(self.data["definitions"], ScalarNode):

                definitions = {}

                # new-style
                from lark import Token

                def_block_tree = parse_string(self.data["definitions"],
                                              start="assignment_block")
                def_block_tree = sanitize(
                    def_block_tree
                )  # just to replace (v,) by (v,0) # TODO: remove

                auxiliaries = []
                for eq_tree in def_block_tree.children:
                    lhs, rhs = eq_tree.children
                    tok_name: Token = lhs.children[0].children[0]
                    tok_date: Token = lhs.children[1].children[0]
                    name = tok_name.value
                    date = int(tok_date.value)
                    if name in vars:
                        raise Exception(
                            f"definitions:{tok_name.line}:{tok_name.column}: Auxiliary variable '{name}'' already defined."
                        )
                    if date != 0:
                        raise Exception(
                            f"definitions:{tok_name.line}:{tok_name.column}: Auxiliary variable '{name}' must be defined at date 't'."
                        )
                    # here we could check some stuff
                    from dolang import list_symbols

                    syms = list_symbols(rhs)
                    for p in syms.parameters:
                        if p in vars:
                            raise Exception(
                                f"definitions:{tok_name.line}: Symbol '{p}' is defined as a variable. Can't appear as a parameter."
                            )
                        if p not in self.symbols["parameters"]:
                            raise Exception(
                                f"definitions:{tok_name.line}: Paremeter '{p}' must be defined as a model symbol."
                            )
                    for v in syms.variables:
                        if v[0] not in vars:
                            raise Exception(
                                f"definitions:{tok_name.line}: Variable '{v[0]}[t]' is not defined."
                            )
                    auxiliaries.append(name)
                    vars.append(name)

                    definitions[str_expression(lhs)] = str_expression(rhs)

                self.__symbols__["auxiliaries"] = auxiliaries
                self.__definitions__ = definitions

            else:

                # old style
                from dolang.symbolic import remove_timing

                auxiliaries = [
                    remove_timing(parse_string(k))
                    for k in self.data.get("definitions", {})
                ]
                auxiliaries = [str_expression(e) for e in auxiliaries]
                self.__symbols__["auxiliaries"] = auxiliaries
                vars = self.variables
                auxs = []

                definitions = self.data["definitions"]
                d = dict()
                for i in range(len(definitions.value)):

                    kk = definitions.value[i][0]
                    if self.__compat__:
                        k = parse_string(kk.value)
                        if k.data == "symbol":
                            # TODO: warn that definitions should be timed
                            from dolang.grammar import create_variable

                            k = create_variable(k.children[0].value, 0)
                    else:
                        k = parse_string(kk.value, start="variable")
                    k = sanitize(k, variables=vars)

                    assert k.children[1].children[0].value == "0"

                    vv = definitions.value[i][1]
                    v = parse_string(vv, start="formula")
                    v = sanitize(v, variables=vars)
                    v = str_expression(v)

                    key = str_expression(k)
                    vars.append(key)
                    d[key] = v
                    auxs.append(remove_timing(key))

                self.__symbols__["auxiliaries"] = auxs
                self.__definitions__ = d

        return self.__definitions__