EconForge / dolo.py

Economic modelling in python
BSD 2-Clause "Simplified" License
98 stars 72 forks source link

Exp not correctly accounted for in complementarity condition #214

Closed NormannR closed 3 years ago

NormannR commented 3 years ago

I encounter a bug when trying to import the following yaml file using the yaml_import function

name: Consumption Savings

symbols:
    states: [a]
    exogenous: [r, w, e]
    parameters: [beta, B, a_max]
    controls: [i]

definitions: |
    c[t] = (1+r[t])*a[t] +  w[t]*exp(e[t]) - i[t]

equations:

    arbitrage: |
        1-beta*(1+r[t+1])*c[t]/c[t+1] ⟂ -B <= i[t] <= (1+r[t])*a[t]+w[t]*exp(e[t])

    transition: |
        a[t] = i[t-1]

calibration:

    beta: 0.99
    B: 1e-10
    a_max: 200.
    a: 1
    i: a

    K: 40
    alpha: 0.36
    A: 1
    N: 1
    delta: 0.025
    r: alpha*(N/K)^(1-alpha) - delta
    w: (1-alpha)*(K/N)^(alpha)

domain:
    a: [-B, a_max]

exogenous:  
    r,w: !ConstantProcess
        μ: [r, w]
    e: !VAR1
        ρ: 0.95
        Σ: [[0.06^2]]

options:
    grid:
        !Cartesian
        orders: [30]

I get the following error

Traceback (most recent call last):
  File "dolo/tests/test_complementarity_exp.py", line 6, in <module>
    yaml_import('exp_bug.yaml')
  File "/home/normann/Dropbox/Pablo/dolo.py/dolo/compiler/model_import.py", line 33, in yaml_import
    return Model(data, check=check)
  File "/home/normann/Dropbox/Pablo/dolo.py/dolo/compiler/model.py", line 514, in __init__
    self.x_bounds
  File "/home/normann/Dropbox/Pablo/dolo.py/dolo/compiler/model.py", line 734, in x_bounds
    if 'controls_ub' in self.functions:
  File "/home/normann/Dropbox/Pablo/dolo.py/dolo/compiler/model.py", line 599, in functions
    self.__compile_functions__()
  File "/home/normann/Dropbox/Pablo/dolo.py/dolo/compiler/model.py", line 586, in __compile_functions__
    fff, vectorize=True, debug=debug)
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/dolang/function_compiler.py", line 87, in make_method_from_factory
    [fty], signature, target='parallel', nopython=True)(fun)
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/np/ufunc/decorators.py", line 179, in wrap
    guvec.add(fty)
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/np/ufunc/ufuncbuilder.py", line 213, in add
    self.nb_func, targetoptions, sig)
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/np/ufunc/ufuncbuilder.py", line 144, in _compile_element_wise_function
    cres = nb_func.compile(sig, **targetoptions)
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/np/ufunc/ufuncbuilder.py", line 93, in compile
    return self._compile_core(sig, flags, locals)
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/np/ufunc/ufuncbuilder.py", line 128, in _compile_core
    flags=flags, locals=locals)
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/core/compiler.py", line 627, in compile_extra
    return pipeline.compile_extra(func)
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/core/compiler.py", line 363, in compile_extra
    return self._compile_bytecode()
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/core/compiler.py", line 425, in _compile_bytecode
    return self._compile_core()
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/core/compiler.py", line 405, in _compile_core
    raise e
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/core/compiler.py", line 396, in _compile_core
    pm.run(self.state)
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/core/compiler_machinery.py", line 341, in run
    raise patched_exception
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/core/compiler_machinery.py", line 332, in run
    self._runPass(idx, pass_inst, state)
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/core/compiler_lock.py", line 32, in _acquire_compile_lock
    return func(*args, **kwargs)
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/core/compiler_machinery.py", line 291, in _runPass
    mutated |= check(pss.run_pass, internal_state)
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/core/compiler_machinery.py", line 264, in check
    mangled = func(compiler_state)
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/core/typed_passes.py", line 98, in run_pass
    raise_errors=self._raise_errors)
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/core/typed_passes.py", line 69, in type_inference_stage
    infer.build_constraint()
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/core/typeinfer.py", line 1024, in build_constraint
    self.constrain_statement(inst)
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/core/typeinfer.py", line 1368, in constrain_statement
    self.typeof_assign(inst)
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/core/typeinfer.py", line 1439, in typeof_assign
    self.typeof_global(inst, inst.target, value)
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/core/typeinfer.py", line 1540, in typeof_global
    typ = self.resolve_value_type(inst, gvar.value)
  File "/home/normann/.cache/pypoetry/virtualenvs/dolo-9_XxIsCN-py3.7/lib/python3.7/site-packages/numba/core/typeinfer.py", line 1460, in resolve_value_type
    raise TypingError(msg, loc=inst.loc)
numba.core.errors.TypingError: Failed in nopython mode pipeline (step: nopython frontend)
NameError: name 'exp_' is not defined
albop commented 3 years ago

Interesting ! If you look at model.equations, just before model.functions is actually called, you see: {'arbitrage': ['1 - ((((beta)*(1 + r[t+1]))*(c[t]))/(c[t+1]))', 'e[t]'], 'arbitrage_lb': ['-(B)', '-inf'], 'arbitrage_ub': ['(1 + r[t])*(a[t]) + (w[t])*(exp)', 'inf'], 'transition': ['a[t] = i[t-1]']} so it looks like at that stage, the complementarity is already parsed incorrectly.

albop commented 3 years ago

OK, now this is clearly a dolang issue. Step to reproduce:

import dolang.symbolic
eq = dolang.symbolic.parse_string("1-beta*(1+r[t+1])*c[t]/c[t+1] ⟂ -B <= i[t] <= (1+r[t])*a[t]+w[t]*exp(e[t])", start="complementarity_block")
dolang.symbolic.str_expression(eq)

results in

['1 - ((((beta)*(1 + r[t+1]))*(c[t]))/(c[t+1])) ⟂ -(B) <= i[t] <= (1 + r[t])*(a[t]) + (w[t])*(exp)',
 'e[t]']
albop commented 3 years ago

Fixed in dolang.