EconForge / dolo.py

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

Nununiform grids #228

Open albop opened 3 years ago

albop commented 3 years ago

The decision rule object has had the ability for a while to interpolate on nonuniform cartesian grids, as long as it is supported by interpolation.py (currently multilinear is supported, cubic upcoming). But there is no way to specify a nonuniform spline in the yaml file. A very simple syntax could be as follows:

domain:   # unchanged
    z: [-2*sig_z/(1-rho^2)^0.5,  2*sig_z/(1-rho^2)^0.5]
    k: [ kss*0.5, kss*1.5]

options:
    grid:
        z: 40
        k: [kss*0.5, kss*0.6, kss*0.8, kss*0.9, kss, kss*1.1, kss*1.2, kss*1.3, kss*1.4, kss*0.1.5]

The arguments of grid, would be represented as a DiscretizationScheme, which would then be applied to the domain object. Arguments could be either a float (as for z) or an array. To avoid complications, one possibility could be to introduce a new discretization option, meant to eventually supersede options:grid. So it would be:

options:
    discretization: !DiscretizationScheme
        z: 40
        k: [kss*0.5, kss*0.6, kss*0.8, kss*0.9, kss, kss*1.1, kss*1.2, kss*1.3, kss*1.4, kss*0.1.5]

At a later stage, we could introduce a language to construct arrays, with concatenation (easy) or comprehension (tricky but feasible).

albop commented 3 years ago

One afterthought. A complementary change, would be to have an interpolation option. It would become:

options:
    discretization: !DiscretizationScheme
        z: 40
        k: [kss*0.5, kss*0.6, kss*0.8, kss*0.9, kss, kss*1.1, kss*1.2, kss*1.3, kss*1.4, kss*0.1.5]
    interpolation: cubic

This would seem to make a lot of sense.

albop commented 3 years ago

Second afterthought: the nice part of this structure, is that, once the arrays are constructed, all logic can be handled by the python object. Also, it doesn't involve complicated structures. As a result, discretization and interpolation could become natural options of all global solution methods, without inolving complex dictionary inheritance at all.

albop commented 3 years ago

Another question is whether the discretization scheme should use absolute or relative coordinates and how to choose which to use. For instance, the above example could be reformulated as:

options:
    discretization: !DiscretizationScheme
        z: 40   # this is implicilty relative, it requires the domain to have finite bounds
        k:  !RScale # relative scale
           - [0.5, 0.6, 0.8, 0.9, 1.1, 1.2, 1.3, 1.4, 0.15]
    interpolation: cubic

Another, heavy option, would be to find a way to denote upper bound of variables. For instance ^k could be the minimum of k domain and k^ would be the maximum. So the scale would be:

options:
    discretization: !DiscretizationScheme
        z: 40   # this is implicilty relative, it requires the domain to have finite bounds
        k:   [^k+0.5*(k^-^k), ^k+0.6*(k^-^k)]

which is super explicit, transparent, and, ahem, annoying.

albop commented 3 years ago
options:
    discretization: !DiscretizationScheme
        z: 40   # this is implicilty relative, it requires the domain to have finite bounds
        k:  !RScale # relative scale
           - [0.5, 0.6, 0.8, 0.9, 1.1, 1.2, 1.3, 1.4, 0.15]
    interpolation: !Special
       type: cubic
       extrapolation:
           up: !LinearBound
                   intercept: 1
                   slope: (r-1)
           down: !VerticalBound
                  value: 0