Пример #1
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)}."
                )
Пример #2
0
def test_remove_timing():
    from dolang.symbolic import parse_string, remove_timing

    e = parse_string("sin(a(1)+b+f(1)+f(4)+a[t+1])")
    assert isinstance(e, Tree)
    s = to_source(e)
    rr = remove_timing(s)
    assert rr == "sin(a + b + f + f + a)"
Пример #3
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)
Пример #4
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)
Пример #5
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__