Getting Started

The purpose of the present Getting Started section is to give a quick overview of the main objects, methods and functions of the Python iode library. To get a more detailed presentation of all capabilities of iode, read the next sections of the tutorial.

The API Reference section of the documentation give you the list of all objects, methods and functions with their individual documentation and examples.

The Equivalence IODE Report Commands and IODE Python section contains equivalence tables between the IODE report syntax and the Python iode syntax.

To use the Python iode library, the first thing to do is to import objects and functions you need from it:

[473]:
import numpy as np
import pandas as pd
import larray as la

from copy import copy
from iode import (SAMPLE_DATA_DIR, comments, equations, identities, lists, scalars,
                  tables, variables, Equation, Scalar, Table, EqMethod, Sample, NA)

To know the version of the iode library installed on your machine, type:

[474]:
from iode import __version__
__version__
[474]:
'7.0.0'

To print the documentation of an object, method or function in a Python interactive console, use the help() function:

[475]:
# ---- print documentation of a function or method ----
help(equations.load)
Help on method load in module iode.iode_database.abstract_database:

load(filepath: str) method of iode.iode_database.equations_database.Equations instance
    Load objects stored in file 'filepath' into the current database.
    Erase the database before to load the file.

    Parameters
    ----------
    filepath: str
        path to the file to load

    Examples
    --------
    >>> from iode import comments, equations, identities, lists, tables, scalars, variables
    >>> from iode import SAMPLE_DATA_DIR
    >>> comments.load(f"{SAMPLE_DATA_DIR}/fun.cmt")         # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
    Loading .../fun.cmt
    317 objects loaded

    >>> equations.load(f"{SAMPLE_DATA_DIR}/fun.eqs")        # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
    Loading .../fun.eqs
    274 objects loaded

    >>> identities.load(f"{SAMPLE_DATA_DIR}/fun.idt")       # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
    Loading .../fun.idt
    48 objects loaded

    >>> lists.load(f"{SAMPLE_DATA_DIR}/fun.lst")            # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
    Loading .../fun.lst
    17 objects loaded

    >>> tables.load(f"{SAMPLE_DATA_DIR}/fun.tbl")           # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
    Loading .../fun.tbl
    46 objects loaded

    >>> scalars.load(f"{SAMPLE_DATA_DIR}/fun.scl")          # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
    Loading .../fun.scl
    161 objects loaded

    >>> variables.load(f"{SAMPLE_DATA_DIR}/fun.var")        # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
    Loading .../fun.var
    394 objects loaded

Load IODE objects

To load IODE objects from a binary file (i.e. with extension .cmt, .eqs, .idt, .lst, .scl, .tbl, .var) or from an ASCII file (i.e. with extension .ac, .ae, .ai, .al, .as, .at, .av), use the load() method of the corresponding object. For example:

[476]:
# ---- load equations, identities, scalars and variables ----
# Note: test binary and ASCII 'fun' files are located in the 'SAMPLE_DATA_DIR'
#       directory of the 'iode' package
comments.load(f"{SAMPLE_DATA_DIR}/fun.cmt")
equations.load(f"{SAMPLE_DATA_DIR}/fun.eqs")
identities.load(f"{SAMPLE_DATA_DIR}/fun.idt")
lists.load(f"{SAMPLE_DATA_DIR}/fun.lst")
scalars.load(f"{SAMPLE_DATA_DIR}/fun.scl")
tables.load(f"{SAMPLE_DATA_DIR}/fun.tbl")
variables.load(f"{SAMPLE_DATA_DIR}/fun.var")

# ---- print the number of objects present in the above workspaces ----
len(comments), len(equations), len(identities), len(lists), len(scalars), len(tables), len(variables)
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.cmt
317 objects loaded
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.eqs
274 objects loaded
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.idt
48 objects loaded
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.lst
17 objects loaded
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.scl
161 objects loaded
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.tbl
46 objects loaded
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.var
394 objects loaded
[476]:
(317, 274, 48, 17, 161, 46, 394)

Save IODE objects

To save the content of a workspace (or a subset of a workspace), use the save() method:

[477]:
# ---- save workspace (or subset) ----
# save the whole workspace
equations.save('equations.eqs')

# save only a subset of the global variables workspace
vars_subset = variables[["ACAF", "ACAG", "AQC", "BQY", "BVY"]]
vars_subset.save('variables_subset.av')

print("Check content of the variables_subset.av file:\n")
with open("variables_subset.av", "r") as f:
    print(f.read())
print()
Saving c:\usr\Projects\iode-1\doc\source\tutorial\equations.eqs
274 objects saved
Saving c:\usr\Projects\iode-1\doc\source\tutorial\variables_subset.av
Check content of the variables_subset.av file:

sample 1960Y1 2015Y1
ACAF na na na na na na na na na na 1.2130001 5.2020001 9.184 8.0790005 11.332 13.518001 15.784 16.544001 21.489 20.281 21.277 32.417999 24.446999 27.025002 24.504 27.560999 25.542 27.499001 25.353001 17.165001 23.771 26.240999 30.159 34.661999 8.1610022 -13.130997 32.171001 39.935799 29.645657 13.530404919696 10.0466107922005 2.86792273645546 -0.929212509051645 -6.09156498756888 -14.5820944628981 -26.5387895697886 -28.9872879825975 -33.3784257842954 -38.4095177823974 -37.4635096412738 -37.8274288322944 -44.5447926335432 -55.5592898172187 -68.8946543226201 -83.3406251108009 -96.4104198284833
ACAG na na na na na na na na na na -11.028999 -15.847 -19.288002 -21.814999 -25.447002 -24.618999 -27.770998 -28.839001 -29.434998 -30.411001 -30.353001 -41.060997 -31.178001 -32.604 -30.237003 -38.061001 -31.939999 -35.59 -37.238003 -25.991001 -28.1721855713507 -30.934 -40.285999 -43.157997 -16.029003 -41.845993 -40.237 -32.93 -38.345695 -39.8581741316036 -41.534786567348 18.9398011359783 19.9808148751188 21.0205021787734 22.0664755229642 23.1079621640615 24.1296371451098 25.1609090496654 26.1921114843413 27.2299551185986 28.2539289782105 29.2846003640349 30.3239611503116 31.3701388106954 32.4202988291984 33.469601344881
AQC 0.21753037 0.21544869 0.22228125 0.22953896 0.23653506 0.24732406 0.26255098 0.26907021 0.27206925 0.27986595 0.29396999 0.31906503 0.3426649 0.36655167 0.42489415 0.49478459 0.53812659 0.5841772 0.61441606 0.64528418 0.68947881 0.73596764 0.77532566 0.82384807 0.85829282 0.90006256 0.92794591 0.93221092 0.92874223 0.9445076 1 1.0628064 1.1102825 1.1532652 1.1571276 1.1616869 1.1580297 1.201328 1.2031082 1.34296996567459 1.33860285536454 1.37918824681718 1.40881646814855 1.4197045826264 1.40065205989326 1.39697298498842 1.39806354127729 1.40791333507892 1.42564487943834 1.44633167140609 1.46286836974508 1.4822736109441 1.51366597504599 1.55803878946449 1.61318116991651 1.67429057570213
BQY 31.777023 30.852692 30.352686 27.369537 26.937241 35.434574 37.147881 39.505711 42.182659 43.180264 53.083984 49.670918 53.546627 49.331879 50.91983 49.630653 53.96249 40.783443 35.963261 12.621698 -9.930582 -11.615362 -44.158623 -48.221375 -43.152462 -57.944221 -35.790237 -21.710344 -20.180235 -11.333452 -34.099998 -1.2597286 -13.746386 52.161541 66.625153 91.089355 104.67634 113.51928 116.18705 117.908447093342 119.955089852255 121.37741690021 121.700965506023 122.433025255743 124.490157052046 127.572355095553 129.818419511458 131.31355487699 132.020462612763 132.709142263746 133.959190039522 135.075585222668 135.597702367503 135.753159667506 135.968846903397 136.672483513679
BVY 7.1999998 7.0999999 7.1000004 6.6000004 6.8000002 9.3999996 10.3 11.3 12.4 13.3 17.200001 17 19.5 19.200001 22.300001 24.4 28.5 23.099998 21.299999 7.7999992 -6.3999977 -7.9000015 -32.100002 -37.099998 -34.900002 -49.699997 -31.799999 -19.700005 -18.699997 -10.987999 -34.099997 -1.3000031 -14.699997 58.100002 75.900002 105.5 123.2 135.6192 140.73978 144.858781845561 150.053352305841 155.895061264049 160.228327009897 164.690028964993 169.072563292021 173.128489782561 176.73460923165 180.338756120558 184.785317603043 189.533437819158 194.344845745399 199.148256821389 204.263448922459 210.010481935745 216.588822212895 224.043770177584


Working with workspaces

To get the list of objects names present in a workspace, use the names attribute of the workspace. For example:

[478]:
# get the list of all IODE lists
lists.names
[478]:
['COPY',
 'COPY0',
 'COPY1',
 'ENDO',
 'ENDO0',
 'ENDO1',
 'ENVI',
 'IDT',
 'MAINEQ',
 'MYLIST',
 'TOTAL',
 'TOTAL0',
 'TOTAL1',
 'XENVI',
 'XSCENARIO',
 '_SCAL',
 '_SEARCH']

To check if a name is present in a workspace, use the in operator. For example:

[479]:
if 'ENVI' in lists:
    print("The 'ENVI' IODE list exists")
else:
    print("'ENVI' IODE list not found")
The 'ENVI' IODE list exists

To iterate over names of a workspace, simply use the Python syntax for the for loop:

[480]:
print("Iterate over all IODE lists names in the Lists workspace:")
for name in lists:
    print(name)
Iterate over all IODE lists names in the Lists workspace:
COPY
COPY0
COPY1
ENDO
ENDO0
ENDO1
ENVI
IDT
MAINEQ
MYLIST
TOTAL
TOTAL0
TOTAL1
XENVI
XSCENARIO
_SCAL
_SEARCH

To get the current used sample for the Variables, use the sample attribute of the variables workspace:

[481]:
# current used sample
variables.sample
[481]:
Sample("1960Y1:2015Y1")

Get - add - update - delete IODE object(s)

In a similar way to Python dictionaries, you can get, add, update and delete IODE objects in a workspace using the [] operator.

  • To extract an IODE object from a workspace, use the syntax: my_obj = workspace[name].

  • To add an IODE object to a workspace, use the syntax: workspace[new_name] = new_obj.

  • To update an IODE object in a workspace, use the syntax: workspace[name] = new_value.

  • To delete an IODE object from a workspace, use the syntax: del workspace[name].

To add or update IODE objects using:

Comments

Add one comment:

[482]:
comments["NEW"] = "A new comment"
comments["NEW"]
[482]:
'A new comment'

Update a comment:

[483]:
comments["NEW"] = "New Value"
comments["NEW"]
[483]:
'New Value'

Update multiple comments at once:

[484]:
# 1) using a dict of values
values = {"AOUC": "Updated AOUC from dict", "ACAF": "Updated ACAF from dict",
          "ACAG": "Updated ACAG from dict"}
comments["ACAF, ACAG, AOUC"] = values
comments["ACAF, ACAG, AOUC"]
[484]:
Workspace: Comments
nb comments: 3
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.cmt

name           comments
ACAF    Updated ACAF from dict
ACAG    Updated ACAG from dict
AOUC    Updated AOUC from dict
[485]:
# 2) using another Comments database (subset)
comments_subset = comments["ACAF, ACAG, AOUC"].copy()
comments_subset["ACAF"] = "Updated ACAF from another iode Comments database"
comments_subset["ACAG"] = "Updated ACAG from another iode Comments database"
comments_subset["AOUC"] = "Updated AOUC from another iode Comments database"
comments["ACAF, ACAG, AOUC"] = comments_subset
comments["ACAF, ACAG, AOUC"]
[485]:
Workspace: Comments
nb comments: 3
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.cmt

name                        comments
ACAF    Updated ACAF from another iode Comments database
ACAG    Updated ACAG from another iode Comments database
AOUC    Updated AOUC from another iode Comments database

Delete a comment:

[486]:
comments.get_names("A*")
[486]:
['ACAF', 'ACAG', 'AOUC', 'AQC']
[487]:
del comments["ACAF"]
comments.get_names("A*")
[487]:
['ACAG', 'AOUC', 'AQC']

Equations

Add one equation:

[488]:
equations["TEST"] = "TEST := 0"
equations["TEST"]
[488]:
Equation(endogenous = 'TEST',
         lec = 'TEST := 0',
         method = 'LSQ',
         from_period = '1960Y1',
         to_period = '2015Y1')

Update an equation:

[489]:
equations["ACAF"]
[489]:
Equation(endogenous = 'ACAF',
         lec = '(ACAF/VAF[-1]) :=acaf1+acaf2*GOSF[-1]+\nacaf4*(TIME=1995)',
         method = 'LSQ',
         from_period = '1980Y1',
         to_period = '1996Y1',
         block = 'ACAF',
         tests = {corr = 1,
                  dw = 2.32935,
                  fstat = 32.2732,
                  loglik = 83.8075,
                  meany = 0.00818467,
                  r2 = 0.821761,
                  r2adj = 0.796299,
                  ssres = 5.19945e-05,
                  stderr = 0.00192715,
                  stderrp = 23.5458,
                  stdev = 0.0042699},
         date = '12-06-1998')
[490]:
# update only the LEC
equations["ACAF"] = "(ACAF/VAF[-1]) := acaf1 + acaf2 * GOSF[-1] + acaf4 * (TIME=1995)"
equations["ACAF"]
[490]:
Equation(endogenous = 'ACAF',
         lec = '(ACAF/VAF[-1]) := acaf1 + acaf2 * GOSF[-1] + acaf4 * (TIME=1995)',
         method = 'LSQ',
         from_period = '1980Y1',
         to_period = '1996Y1',
         block = 'ACAF')
[491]:
# update block and sample of a block of equations to estimation (dictionary)
estim_sample = "2000Y1:2010Y1"
block = "ACAF; ACAG; AOUC"
for eq_name in block.split(';'):
    equations[eq_name] = {"sample": estim_sample, "block": block}

(equations["ACAF"].sample, equations["ACAG"].sample, equations["AOUC"].sample)
[491]:
(Sample("2000Y1:2010Y1"), Sample("2000Y1:2010Y1"), Sample("2000Y1:2010Y1"))
[492]:
(equations["ACAF"].block, equations["ACAG"].block, equations["AOUC"].block)
[492]:
('ACAF; ACAG; AOUC', 'ACAF; ACAG; AOUC', 'ACAF; ACAG; AOUC')
[493]:
# update lec, method, sample and block
equations["ACAF"].lec = "(ACAF/VAF[-1]) := acaf2 * GOSF[-1] + acaf4 * (TIME=1995)"
equations["ACAF"].method = EqMethod.MAX_LIKELIHOOD
# new equation sample is from 1990Y1 to the last year of Variables
equations["ACAF"].sample = "1990Y1:"
equations["ACAF"].block = "ACAF"
equations["ACAF"]
[493]:
Equation(endogenous = 'ACAF',
         lec = '(ACAF/VAF[-1]) := acaf2 * GOSF[-1] + acaf4 * (TIME=1995)',
         method = 'MAX_LIKELIHOOD',
         from_period = '1990Y1',
         to_period = '2015Y1',
         block = 'ACAF')

Update multiple equations at once:

[494]:
# 1) using a dict of values
eq_ACAF = Equation("ACAF", "(ACAF/VAF[-1]) :=acaf1+acaf2*GOSF[-1]+ acaf4*(TIME=1995)",
                   method=EqMethod.ZELLNER, from_period='1980Y1', to_period='1996Y1')
eq_ACAG = Equation("ACAG", "ACAG := ACAG[-1]+r VBBP[-1]+(0.006*VBBP[-1]*(TIME=2001)-0.008*(TIME=2008))",
                   method=EqMethod.ZELLNER, from_period='1980Y1', to_period='1996Y1')
eq_AOUC = Equation("AOUC", "AOUC:=((WCRH/QL)/(WCRH/QL)[1990Y1])*(VAFF/(VM+VAFF))[-1]+PM*(VM/(VAFF+VM))[-1]",
                   method=EqMethod.ZELLNER, from_period='1980Y1', to_period='1996Y1')
values = {"ACAF": eq_ACAF, "ACAG": eq_ACAG, "AOUC": eq_AOUC}
equations["ACAF, ACAG, AOUC"] = values
equations["ACAF, ACAG, AOUC"]
[494]:
Workspace: Equations
nb equations: 3
filename: c:\usr\Projects\iode-1\doc\source\tutorial\equations.eqs

name                                         lec                                         method     sample      block   fstat   r2adj     dw    loglik  date
ACAF    (ACAF/VAF[-1]) :=acaf1+acaf2*GOSF[-1]+ acaf4*(TIME=1995)                        ZELLNER 1980Y1:1996Y1           0.0000  0.0000  0.0000  0.0000
ACAG    ACAG := ACAG[-1]+r VBBP[-1]+(0.006*VBBP[-1]*(TIME=2001)-0.008*(TIME=2008))      ZELLNER 1980Y1:1996Y1           0.0000  0.0000  0.0000  0.0000
AOUC    AOUC:=((WCRH/QL)/(WCRH/QL)[1990Y1])*(VAFF/(VM+VAFF))[-1]+PM*(VM/(VAFF+VM))[-1]  ZELLNER 1980Y1:1996Y1           0.0000  0.0000  0.0000  0.0000
[495]:
# 2) using another Equations database (subset)
equations_subset = equations["ACAF, ACAG, AOUC"].copy()
equations_subset["ACAF"].method = EqMethod.MAX_LIKELIHOOD
equations_subset["ACAG"].method = EqMethod.MAX_LIKELIHOOD
equations_subset["AOUC"].method = EqMethod.MAX_LIKELIHOOD
equations["ACAF, ACAG, AOUC"] = equations_subset
equations["ACAF, ACAG, AOUC"]
[495]:
Workspace: Equations
nb equations: 3
filename: c:\usr\Projects\iode-1\doc\source\tutorial\equations.eqs

name                                         lec                                            method          sample      block   fstat   r2adj     dw    loglik  date
ACAF    (ACAF/VAF[-1]) :=acaf1+acaf2*GOSF[-1]+ acaf4*(TIME=1995)                        MAX_LIKELIHOOD  1980Y1:1996Y1           0.0000  0.0000  0.0000  0.0000
ACAG    ACAG := ACAG[-1]+r VBBP[-1]+(0.006*VBBP[-1]*(TIME=2001)-0.008*(TIME=2008))      MAX_LIKELIHOOD  1980Y1:1996Y1           0.0000  0.0000  0.0000  0.0000
AOUC    AOUC:=((WCRH/QL)/(WCRH/QL)[1990Y1])*(VAFF/(VM+VAFF))[-1]+PM*(VM/(VAFF+VM))[-1]  MAX_LIKELIHOOD  1980Y1:1996Y1           0.0000  0.0000  0.0000  0.0000

Delete an equation:

[496]:
equations.get_names("A*")
[496]:
['ACAF', 'ACAG', 'AOUC']
[497]:
del equations["ACAF"]
equations.get_names("A*")
[497]:
['ACAG', 'AOUC']

Identities

Add one identity:

[498]:
identities["BDY"] = "YN - YK"
identities["BDY"]
[498]:
Identity('YN - YK')

Update an identity:

[499]:
identities["AOUC"]
[499]:
Identity('((WCRH/QL)/(WCRH/QL)[1990Y1])*(VAFF/(VM+VAFF))[-1]+PM*(VM/(VM+VAFF))[-1]')
[500]:
identities["AOUC"] = '(WCRH / WCRH[1990Y1]) * (VAFF / (VM+VAFF))[-1] + PM * (VM / (VM+VAFF))[-1]'
identities["AOUC"]
[500]:
Identity('(WCRH / WCRH[1990Y1]) * (VAFF / (VM+VAFF))[-1] + PM * (VM / (VM+VAFF))[-1]')

Update multiple identities at once:

[501]:
# 1) using a dict of values
values = {"GAP2": "0.9 * 100*(QAFF_/(Q_F+Q_I))", "GAP_": "0.9 * 100*((QAF_/Q_F)-1)",
          "GOSFR": "0.9 * (GOSF/VAF_)"}
identities["GAP2, GAP_, GOSFR"] = values
identities["GAP2, GAP_, GOSFR"]
[501]:
Workspace: Identities
nb identities: 3
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.idt

 name            identities
GAP2    0.9 * 100*(QAFF_/(Q_F+Q_I))
GAP_    0.9 * 100*((QAF_/Q_F)-1)
GOSFR   0.9 * (GOSF/VAF_)
[502]:
# 2) using another Identities database (subset)
identities_subset = identities["GAP2, GAP_, GOSFR"].copy()
identities_subset["GAP2"] = "0.7 * 100*(QAFF_/(Q_F+Q_I))"
identities_subset["GAP_"] = "0.7 * 100*((QAF_/Q_F)-1)"
identities_subset["GOSFR"] = "0.7 * (GOSF/VAF_)"
identities["GAP2, GAP_, GOSFR"] = identities_subset
identities["GAP2, GAP_, GOSFR"]
[502]:
Workspace: Identities
nb identities: 3
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.idt

 name            identities
GAP2    0.7 * 100*(QAFF_/(Q_F+Q_I))
GAP_    0.7 * 100*((QAF_/Q_F)-1)
GOSFR   0.7 * (GOSF/VAF_)

Delete an identity:

[503]:
identities.get_names("W*")
[503]:
['W', 'WBGR', 'WCRH', 'WMINR', 'WO']
[504]:
del identities["W"]
identities.get_names("W*")
[504]:
['WBGR', 'WCRH', 'WMINR', 'WO']

Lists

Add one list:

[505]:
# --- by passing a string
lists["A_VAR"] = "ACAF;ACAG;AOUC;AOUC_;AQC"
lists["A_VAR"]
[505]:
['ACAF', 'ACAG', 'AOUC', 'AOUC_', 'AQC']
[506]:
# --- by passing a Python list
b_vars = variables.get_names("B*")
b_vars
[506]:
['BENEF', 'BQY', 'BRUGP', 'BVY']
[507]:
lists["B_VAR"] = b_vars
lists["B_VAR"]
[507]:
['BENEF', 'BQY', 'BRUGP', 'BVY']

Update a list:

[508]:
# --- by passing a string
lists["A_VAR"] = "ACAF;ACAG;AOUC;AQC"
lists["A_VAR"]
[508]:
['ACAF', 'ACAG', 'AOUC', 'AQC']
[509]:
# --- by passing a Python list
b_y_vars = variables.get_names("B*Y")
b_y_vars
[509]:
['BQY', 'BVY']
[510]:
lists["B_VAR"] = b_y_vars
lists["B_VAR"]
[510]:
['BQY', 'BVY']

Update multiple lists at once:

[511]:
# 1) using a dict of values
values = {"ENVI": "PWMAB; PWMS; PWXAB; PWXS; QWXAB; QWXS; POIL; NATY",
          "IDT": "FLGR; KL; PROD; QL; RDEBT; RENT; RLBER; SBGX; WCRH; IUGR; SBGXR; WBGR; YSFICR",
          "MAINEQ": "NFYH; KNFF; PC; PXAB; PMAB; QXAB; QMAB"}
lists["ENVI, IDT, MAINEQ"] = values
lists["ENVI, IDT, MAINEQ"]
[511]:
Workspace: Lists
nb lists: 3
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.lst
description: Modèle fun

 name                                       lists
ENVI    PWMAB; PWMS; PWXAB; PWXS; QWXAB; QWXS; POIL; NATY
IDT     FLGR; KL; PROD; QL; RDEBT; RENT; RLBER; SBGX; WCRH; IUGR; SBGXR; WBGR; YSFICR
MAINEQ  NFYH; KNFF; PC; PXAB; PMAB; QXAB; QMAB
[512]:
# 2) using another Lists database (subset)
lists_subset = lists["ENVI, IDT, MAINEQ"].copy()
lists_subset["ENVI"] = "PWXAB; PWXS; QWXAB; QWXS"
lists_subset["IDT"] = "PROD; QL; RDEBT; RENT; RLBER; SBGX; WCRH; IUGR; SBGXR"
lists_subset["MAINEQ"] = "PC; PXAB; PMAB"
lists["ENVI, IDT, MAINEQ"] = lists_subset
lists["ENVI, IDT, MAINEQ"]
[512]:
Workspace: Lists
nb lists: 3
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.lst
description: Modèle fun

 name                           lists
ENVI    PWXAB; PWXS; QWXAB; QWXS
IDT     PROD; QL; RDEBT; RENT; RLBER; SBGX; WCRH; IUGR; SBGXR
MAINEQ  PC; PXAB; PMAB

Delete a list:

[513]:
lists.get_names("C*")
[513]:
['COPY', 'COPY0', 'COPY1']
[514]:
del lists["COPY"]
lists.get_names("C*")
[514]:
['COPY0', 'COPY1']

Scalars

Add one scalar:

[515]:
# 1. default relax to 1.0
scalars["a0"] = 0.1
scalars["a0"]
[515]:
Scalar(0.1, 1, na)
[516]:
# 2. value + relax
scalars["a1"] = 0.1, 0.9
scalars["a1"]
[516]:
Scalar(0.1, 0.9, na)

Update a scalar:

[517]:
scalars["acaf1"]
[517]:
Scalar(0.0157684, 1, 0.00136871)
[518]:
# only update the value
scalars["acaf1"] = 0.8
scalars["acaf1"]
[518]:
Scalar(0.8, 1, na)
[519]:
# update value and relax (tuple)
scalars["acaf2"] = 0.8, 0.9
scalars["acaf2"]
[519]:
Scalar(0.8, 0.9, na)
[520]:
# update value and relax (list)
scalars["acaf2"] = (0.7, 0.8)
scalars["acaf2"]
[520]:
Scalar(0.7, 0.8, na)
[521]:
# update value and relax (dictionary)
scalars["acaf3"] = {"relax": 0.9, "value": 0.8}
scalars["acaf3"]
[521]:
Scalar(0.8, 0.9, na)
[522]:
# update value and/or relax (Scalar object)
# NOTE: the standard deviation (std) cannot be changed manually
scalars["acaf4"]
[522]:
Scalar(-0.00850518, 1, 0.0020833)
[523]:
scalars["acaf4"].value = 0.8
scalars["acaf4"].relax = 0.9
scalars["acaf4"]
[523]:
Scalar(0.8, 0.9, na)

Update multiple scalars at once:

[524]:
# 1) using a dict of values
values = {"acaf1": 0.016, "acaf2": (-8.e-04, 0.9), "acaf3": Scalar(2.5)}
scalars["acaf1, acaf2, acaf3"] = values
scalars["acaf1, acaf2, acaf3"]
[524]:
Workspace: Scalars
nb scalars: 3
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.scl

 name    value  relax   std
acaf1    0.0160 1.0000   na
acaf2   -0.0008 0.9000   na
acaf3    2.5000 1.0000   na
[525]:
# 2) using another Scalars database (subset)
scalars_subset = scalars["acaf1, acaf2, acaf3"].copy()
scalars_subset["acaf1"] = 0.02
scalars_subset["acaf2"] = (-5.e-04, 0.94)
scalars_subset["acaf3"] = Scalar(2.9)
scalars["acaf1, acaf2, acaf3"] = scalars_subset
scalars["acaf1, acaf2, acaf3"]
[525]:
Workspace: Scalars
nb scalars: 3
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.scl

 name    value  relax   std
acaf1    0.0200 1.0000   na
acaf2   -0.0005 0.9400   na
acaf3    2.9000 1.0000   na

Delete a scalar:

[526]:
scalars.get_names("a*")
[526]:
['a0', 'a1', 'acaf1', 'acaf2', 'acaf3', 'acaf4']
[527]:
del scalars["acaf4"]
scalars.get_names("a*")
[527]:
['a0', 'a1', 'acaf1', 'acaf2', 'acaf3']

Tables

Create an add a new table:

[528]:
# 1. specify list of line titles and list of LEC expressions
lines_titles = ["GOSG:", "YDTG:", "DTH:", "DTF:", "IT:", "YSSG+COTRES:", "RIDG:", "OCUG:"]
lines_lecs = ["GOSG", "YDTG", "DTH", "DTF", "IT", "YSSG+COTRES", "RIDG", "OCUG"]
tables["TABLE_CELL_LECS"] = {"nb_columns": 2, "table_title": "New Table", "lecs_or_vars": lines_lecs,
                             "lines_titles": lines_titles, "mode": True, "files": True, "date": True}
tables["TABLE_CELL_LECS"]
[528]:
DIVIS | 1              |
TITLE |         "New Table"
----- | ----------------------------
CELL  | ""             |     "#S"
----- | ----------------------------
CELL  | "GOSG:"        |        GOSG
CELL  | "YDTG:"        |        YDTG
CELL  | "DTH:"         |         DTH
CELL  | "DTF:"         |         DTF
CELL  | "IT:"          |          IT
CELL  | "YSSG+COTRES:" | YSSG+COTRES
CELL  | "RIDG:"        |        RIDG
CELL  | "OCUG:"        |        OCUG
----- | ----------------------------
MODE  |
FILES |
DATE  |

nb lines: 16
nb columns: 2
language: 'ENGLISH'
gridx: 'MAJOR'
gridy: 'MAJOR'
graph_axis: 'VALUES'
graph_alignment: 'LEFT'
[529]:
# 2. specify list of variables
vars_list = ["GOSG", "YDTG", "DTH", "DTF", "IT", "YSSG", "COTRES", "RIDG", "OCUG", "$ENVI"]
tables["TABLE_VARS"] = {"nb_columns": 2, "table_title": "New Table", "lecs_or_vars": vars_list,
                        "mode": True, "files": True, "date": True}
tables["TABLE_VARS"]
[529]:
DIVIS | 1                                                                    |
TITLE |                                  "New Table"
----- | -----------------------------------------------------------------------------
CELL  | ""                                                                   |  "#S"
----- | -----------------------------------------------------------------------------
CELL  | "Bruto exploitatie-overschot: overheid (= afschrijvingen)."          |   GOSG
CELL  | "Overheid: geïnde indirecte belastingen."                            |   YDTG
CELL  | "Totale overheid: directe belasting van de gezinnen."                |    DTH
CELL  | "Totale overheid: directe vennootschapsbelasting."                   |    DTF
CELL  | "Totale indirecte belastingen."                                      |     IT
CELL  | "Globale overheid: ontvangen sociale zekerheidsbijdragen."           |   YSSG
CELL  | "Cotisation de responsabilisation."                                  | COTRES
CELL  | "Overheid: inkomen uit vermogen."                                    |   RIDG
CELL  | "Globale overheid: saldo van de ontvangen lopendeoverdrachten."      |   OCUG
CELL  | "Index wereldprijs - uitvoer van niet-energieprodukten, inUSD."      |  PWXAB
CELL  | "Index wereldprijs - uitvoer van diensten, in USD."                  |   PWXS
CELL  | "Indicator van het volume van de wereldvraag naar goederen,1985=1."  |  QWXAB
CELL  | "Indicator van het volume van de wereldvraag naar diensten,1985=1."  |   QWXS
----- | -----------------------------------------------------------------------------
MODE  |
FILES |
DATE  |

nb lines: 21
nb columns: 2
language: 'ENGLISH'
gridx: 'MAJOR'
gridy: 'MAJOR'
graph_axis: 'VALUES'
graph_alignment: 'LEFT'

Update a table:

[530]:
tables["TABLE_CELL_LECS"]
[530]:
DIVIS | 1              |
TITLE |         "New Table"
----- | ----------------------------
CELL  | ""             |     "#S"
----- | ----------------------------
CELL  | "GOSG:"        |        GOSG
CELL  | "YDTG:"        |        YDTG
CELL  | "DTH:"         |         DTH
CELL  | "DTF:"         |         DTF
CELL  | "IT:"          |          IT
CELL  | "YSSG+COTRES:" | YSSG+COTRES
CELL  | "RIDG:"        |        RIDG
CELL  | "OCUG:"        |        OCUG
----- | ----------------------------
MODE  |
FILES |
DATE  |

nb lines: 16
nb columns: 2
language: 'ENGLISH'
gridx: 'MAJOR'
gridy: 'MAJOR'
graph_axis: 'VALUES'
graph_alignment: 'LEFT'
[531]:
tables["TABLE_CELL_LECS"].graph_axis
[531]:
'VALUES'
[532]:
from iode import TableGraphAxis
# set graph axis type
tables["TABLE_CELL_LECS"].graph_axis = TableGraphAxis.SEMILOG
tables["TABLE_CELL_LECS"].graph_axis
[532]:
'SEMILOG'
[533]:
# get the first line
tables["TABLE_CELL_LECS"][0]
[533]:
New Table
[534]:
# get the last line
tables["TABLE_CELL_LECS"][-1]
[534]:
<DATE>
[535]:
# delete last line
del tables["TABLE_CELL_LECS"][-1]
tables["TABLE_CELL_LECS"]
[535]:
DIVIS | 1              |
TITLE |         "New Table"
----- | ----------------------------
CELL  | ""             |     "#S"
----- | ----------------------------
CELL  | "GOSG:"        |        GOSG
CELL  | "YDTG:"        |        YDTG
CELL  | "DTH:"         |         DTH
CELL  | "DTF:"         |         DTF
CELL  | "IT:"          |          IT
CELL  | "YSSG+COTRES:" | YSSG+COTRES
CELL  | "RIDG:"        |        RIDG
CELL  | "OCUG:"        |        OCUG
----- | ----------------------------
MODE  |
FILES |

nb lines: 15
nb columns: 2
language: 'ENGLISH'
gridx: 'MAJOR'
gridy: 'MAJOR'
graph_axis: 'SEMILOG'
graph_alignment: 'LEFT'
[536]:
# get index of line containing YSSG+COTRES
index = tables["TABLE_CELL_LECS"].index("YSSG+COTRES")
index
[536]:
9
[537]:
tables["TABLE_CELL_LECS"][index]
[537]:
('"YSSG+COTRES:"', 'YSSG+COTRES')
[538]:
# get line type
tables["TABLE_CELL_LECS"][index].line_type
[538]:
'CELL'
[539]:
# get line graph type
tables["TABLE_CELL_LECS"][index].graph_type
[539]:
'LINE'
[540]:
# know if axis is left
tables["TABLE_CELL_LECS"][index].axis_left
[540]:
True
[541]:
# update cells
# double quotes "    -> STRING cell
# no double quotes   -> LEC cell
tables["TABLE_CELL_LECS"][index] = ('"YSSG:"', 'YSSG')
tables["TABLE_CELL_LECS"][index]
[541]:
('"YSSG:"', 'YSSG')
[542]:
# insert a new title line surrounded by two separator lines
tables["TABLE_CELL_LECS"].insert(index + 1, '-')
tables["TABLE_CELL_LECS"].insert(index + 2, "New Title")
tables["TABLE_CELL_LECS"].insert(index + 3, '-')
tables["TABLE_CELL_LECS"]
[542]:
DIVIS | 1       |
TITLE |  "New Table"
----- | --------------
CELL  | ""      | "#S"
----- | --------------
CELL  | "GOSG:" | GOSG
CELL  | "YDTG:" | YDTG
CELL  | "DTH:"  |  DTH
CELL  | "DTF:"  |  DTF
CELL  | "IT:"   |   IT
CELL  | "YSSG:" | YSSG
----- | --------------
TITLE |  "New Title"
----- | --------------
CELL  | "RIDG:" | RIDG
CELL  | "OCUG:" | OCUG
----- | --------------
MODE  |
FILES |

nb lines: 18
nb columns: 2
language: 'ENGLISH'
gridx: 'MAJOR'
gridy: 'MAJOR'
graph_axis: 'SEMILOG'
graph_alignment: 'LEFT'
[543]:
# append a new sepatator line
tables["TABLE_CELL_LECS"] += '-'
tables["TABLE_CELL_LECS"]
[543]:
DIVIS | 1       |
TITLE |  "New Table"
----- | --------------
CELL  | ""      | "#S"
----- | --------------
CELL  | "GOSG:" | GOSG
CELL  | "YDTG:" | YDTG
CELL  | "DTH:"  |  DTH
CELL  | "DTF:"  |  DTF
CELL  | "IT:"   |   IT
CELL  | "YSSG:" | YSSG
----- | --------------
TITLE |  "New Title"
----- | --------------
CELL  | "RIDG:" | RIDG
CELL  | "OCUG:" | OCUG
----- | --------------
MODE  |
FILES |
----- | --------------

nb lines: 19
nb columns: 2
language: 'ENGLISH'
gridx: 'MAJOR'
gridy: 'MAJOR'
graph_axis: 'SEMILOG'
graph_alignment: 'LEFT'

Update multiple tables at once:

[544]:
# 1) using a dict of values
table_C8_1 = tables["C8_1"].copy()
table_C8_1.title = table_C8_1.title + " (copy)"
table_C8_2 = tables["C8_2"].copy()
table_C8_2.title = table_C8_2.title + " (copy)"
table_C8_3 = tables["C8_3"].copy()
table_C8_3.title = table_C8_3.title + " (copy)"

values = {"C8_1": table_C8_1, "C8_2": table_C8_2, "C8_3": table_C8_3}
tables["C8_1, C8_2, C8_3"] = values
tables["C8_1, C8_2, C8_3"]
[544]:
Workspace: Tables
nb tables: 3
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.tbl

name                   table titles
C8_1    Déterminants de l'output potentiel (copy)
C8_2    Déterminants de la productivité (copy)
C8_3    Output gap (copy)
[545]:
# 2) using another tables database (subset)
tables_subset = tables["C8_1, C8_2, C8_3"].copy()
tables_subset["C8_1"].title = tables_subset["C8_1"].title.replace("(copy)", "(detached subset)")
tables_subset["C8_2"].title = tables_subset["C8_2"].title.replace("(copy)", "(detached subset)")
tables_subset["C8_3"].title = tables_subset["C8_3"].title.replace("(copy)", "(detached subset)")

tables["C8_1, C8_2, C8_3"] = tables_subset
tables["C8_1, C8_2, C8_3"]
[545]:
Workspace: Tables
nb tables: 3
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.tbl

name                        table titles
C8_1    Déterminants de l'output potentiel (detached subset)
C8_2    Déterminants de la productivité (detached subset)
C8_3    Output gap (detached subset)

Delete a table:

[546]:
tables.get_names("G*")
[546]:
['GAP', 'GDP', 'GFR', 'GFRLEVEL', 'GFRPC', 'GROWTH']
[547]:
del tables["GFRLEVEL"]
tables.get_names("G*")
[547]:
['GAP', 'GDP', 'GFR', 'GFRPC', 'GROWTH']

Variables

Get variable:

[548]:
# get the value for a single period -> float
variables["ACAF", "1990Y1"]
[548]:
23.771
[549]:
# get the values for all periods -> Variables
variables["ACAF"]
[549]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1960Y1:2015Y1
mode: LEVEL

name    1960Y1  1961Y1  1962Y1  1963Y1  1964Y1  1965Y1  ...     2009Y1  2010Y1  2011Y1  2012Y1  2013Y1  2014Y1  2015Y1
ACAF        na      na      na      na      na      na  ...     -37.46  -37.83  -44.54  -55.56  -68.89  -83.34  -96.41
[550]:
# get the values for a range of periods -> Variables
variables["ACAF", "1990Y1:2000Y1"]
[550]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1990Y1:2000Y1
mode: LEVEL

name    1990Y1  1991Y1  1992Y1  1993Y1  1994Y1  1995Y1  1996Y1  1997Y1  1998Y1  1999Y1  2000Y1
ACAF     23.77   26.24   30.16   34.66    8.16  -13.13   32.17   39.94   29.65   13.53   10.05
[551]:
# get the values for a list non-contiguous periods -> pandas Series
variables["ACAF", ["1990Y1", "1995Y1", "2000Y1"]]
[551]:
time
1990Y1    23.771000
1995Y1   -13.130997
2000Y1    10.046611
Name: ACAF, dtype: float64

Get values for a single period:

[552]:
variables[:, "1990Y1"]
[552]:
Workspace: Variables
nb variables: 394
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1990Y1:1990Y1
mode: LEVEL

 name   1990Y1
ACAF     23.77
ACAG    -28.17
AOUC      1.00
AOUC_     0.94
AQC       1.00
...        ...
ZJ        1.09
ZKF       0.81
ZKFO      1.00
ZX        0.00
ZZF_      0.69

or equivalently:

[553]:
variables["*", "1990Y1"]
[553]:
Workspace: Variables
nb variables: 394
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1990Y1:1990Y1
mode: LEVEL

 name   1990Y1
ACAF     23.77
ACAG    -28.17
AOUC      1.00
AOUC_     0.94
AQC       1.00
...        ...
ZJ        1.09
ZKF       0.81
ZKFO      1.00
ZX        0.00
ZZF_      0.69

Add one variable:

[554]:
# 1) same value for all periods
# NOTE: you can also use NA from iode to set a variable value to NaN
variables["A0"] = np.nan
variables["A0"]
[554]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1960Y1:2015Y1
mode: LEVEL

name    1960Y1  1961Y1  1962Y1  1963Y1  1964Y1  1965Y1  ...     2009Y1  2010Y1  2011Y1  2012Y1  2013Y1  2014Y1  2015Y1
A0          na      na      na      na      na      na  ...         na      na      na      na      na      na      na
[555]:
# 2) LEC expression
variables["A1"] = "t + 10"
variables["A1"]
[555]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1960Y1:2015Y1
mode: LEVEL

name    1960Y1  1961Y1  1962Y1  1963Y1  1964Y1  1965Y1  ...     2009Y1  2010Y1  2011Y1  2012Y1  2013Y1  2014Y1  2015Y1
A1       10.00   11.00   12.00   13.00   14.00   15.00  ...      59.00   60.00   61.00   62.00   63.00   64.00   65.00
[556]:
# 3) list of values for each period
values = list(range(variables.nb_periods))
values[0] = NA
values[-1] = np.nan
variables["A2"] = values
variables["A2"]
[556]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1960Y1:2015Y1
mode: LEVEL

name    1960Y1  1961Y1  1962Y1  1963Y1  1964Y1  1965Y1  ...     2009Y1  2010Y1  2011Y1  2012Y1  2013Y1  2014Y1  2015Y1
A2          na    1.00    2.00    3.00    4.00    5.00  ...      49.00   50.00   51.00   52.00   53.00   54.00      na
[557]:
# 4) Variables object
variables["A5"] = variables["ACAF"]
variables["A5"]
[557]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1960Y1:2015Y1
mode: LEVEL

name    1960Y1  1961Y1  1962Y1  1963Y1  1964Y1  1965Y1  ...     2009Y1  2010Y1  2011Y1  2012Y1  2013Y1  2014Y1  2015Y1
A5          na      na      na      na      na      na  ...     -37.46  -37.83  -44.54  -55.56  -68.89  -83.34  -96.41

Update a variable.

Set one value of a variable for a specific period:

[558]:
variables["ACAG", "1990Y1"]
[558]:
-28.1721855713507
[559]:
variables["ACAG", "1990Y1"] = -28.2
variables["ACAG", "1990Y1"]
[559]:
-28.2

Update all values of a variable:

[560]:
variables["ACAF"]
[560]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1960Y1:2015Y1
mode: LEVEL

name    1960Y1  1961Y1  1962Y1  1963Y1  1964Y1  1965Y1  ...     2009Y1  2010Y1  2011Y1  2012Y1  2013Y1  2014Y1  2015Y1
ACAF        na      na      na      na      na      na  ...     -37.46  -37.83  -44.54  -55.56  -68.89  -83.34  -96.41
[561]:
# 1) same value for all periods
variables["ACAF"] = np.nan
variables["ACAF"]
[561]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1960Y1:2015Y1
mode: LEVEL

name    1960Y1  1961Y1  1962Y1  1963Y1  1964Y1  1965Y1  ...     2009Y1  2010Y1  2011Y1  2012Y1  2013Y1  2014Y1  2015Y1
ACAF        na      na      na      na      na      na  ...         na      na      na      na      na      na      na
[562]:
# 2) LEC expression
variables["ACAF"] = "t + 10"
variables["ACAF"]
[562]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1960Y1:2015Y1
mode: LEVEL

name    1960Y1  1961Y1  1962Y1  1963Y1  1964Y1  1965Y1  ...     2009Y1  2010Y1  2011Y1  2012Y1  2013Y1  2014Y1  2015Y1
ACAF     10.00   11.00   12.00   13.00   14.00   15.00  ...      59.00   60.00   61.00   62.00   63.00   64.00   65.00
[563]:
# 3) list of values for each period
values = list(range(variables.nb_periods))
values[0] = NA
values[-1] = np.nan
variables["ACAF"] = values
variables["ACAF"]
[563]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1960Y1:2015Y1
mode: LEVEL

name    1960Y1  1961Y1  1962Y1  1963Y1  1964Y1  1965Y1  ...     2009Y1  2010Y1  2011Y1  2012Y1  2013Y1  2014Y1  2015Y1
ACAF        na    1.00    2.00    3.00    4.00    5.00  ...      49.00   50.00   51.00   52.00   53.00   54.00      na
[564]:
# 4) Variables object
variables["AQC"]
[564]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1960Y1:2015Y1
mode: LEVEL

name    1960Y1  1961Y1  1962Y1  1963Y1  1964Y1  1965Y1  ...     2009Y1  2010Y1  2011Y1  2012Y1  2013Y1  2014Y1  2015Y1
AQC       0.22    0.22    0.22    0.23    0.24    0.25  ...       1.45    1.46    1.48    1.51    1.56    1.61    1.67
[565]:
variables["ACAF"] = variables["AQC"]
variables["ACAF"]
[565]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1960Y1:2015Y1
mode: LEVEL

name    1960Y1  1961Y1  1962Y1  1963Y1  1964Y1  1965Y1  ...     2009Y1  2010Y1  2011Y1  2012Y1  2013Y1  2014Y1  2015Y1
ACAF      0.22    0.22    0.22    0.23    0.24    0.25  ...       1.45    1.46    1.48    1.51    1.56    1.61    1.67

Set the values for range of (contiguous) periods:

[566]:
# 1) variable[t:t+x] = same value for all periods
variables["ACAF", "1991Y1:1995Y1"] = 0.0
variables["ACAF", "1991Y1:1995Y1"]
[566]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1991Y1:1995Y1
mode: LEVEL

name    1991Y1  1992Y1  1993Y1  1994Y1  1995Y1
ACAF      0.00    0.00    0.00    0.00    0.00
[567]:
# 2) variable[t:t+x] = LEC expression
variables["ACAF", "1991Y1:1995Y1"] = "t + 10"
variables["ACAF", "1991Y1:1995Y1"]
[567]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1991Y1:1995Y1
mode: LEVEL

name    1991Y1  1992Y1  1993Y1  1994Y1  1995Y1
ACAF     41.00   42.00   43.00   44.00   45.00
[568]:
# 3) variable[t:t+x] = list of values for each period
values = [1.0, NA, 3.0, np.nan, 5.0]
variables["ACAF", "1991Y1:1995Y1"] = values
variables["ACAF", "1991Y1:1995Y1"]
[568]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1991Y1:1995Y1
mode: LEVEL

name    1991Y1  1992Y1  1993Y1  1994Y1  1995Y1
ACAF      1.00      na    3.00      na    5.00
[569]:
# 4) variable[t:t+x] = Variables object
variables["AQC", "1991Y1:1995Y1"]
[569]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1991Y1:1995Y1
mode: LEVEL

name    1991Y1  1992Y1  1993Y1  1994Y1  1995Y1
AQC       1.06    1.11    1.15    1.16    1.16
[570]:
variables["ACAF", "1991Y1:1995Y1"] = variables["AQC", "1991Y1:1995Y1"]
variables["ACAF", "1991Y1:1995Y1"]
[570]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1991Y1:1995Y1
mode: LEVEL

name    1991Y1  1992Y1  1993Y1  1994Y1  1995Y1
ACAF      1.06    1.11    1.15    1.16    1.16

Set the values for a list of non-contiguous periods:

[571]:
values = [1.0, 3.0, 5.0]
variables["ACAF", ["1991Y1", "1993Y1", "1995Y1"]] = values
variables["ACAF", ["1991Y1", "1993Y1", "1995Y1"]]
[571]:
time
1991Y1    1.0
1993Y1    3.0
1995Y1    5.0
Name: ACAF, dtype: float64

Update multiple variables at once:

[572]:
# 1) using a string
variables["ACAF, ACAG, AOUC", "1991Y1:1995Y1"] = "t + 1"
variables["ACAF, ACAG, AOUC", "1991Y1:1995Y1"]
[572]:
Workspace: Variables
nb variables: 3
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1991Y1:1995Y1
mode: LEVEL

name    1991Y1  1992Y1  1993Y1  1994Y1  1995Y1
ACAF     32.00   33.00   34.00   35.00   36.00
ACAG     32.00   33.00   34.00   35.00   36.00
AOUC     32.00   33.00   34.00   35.00   36.00
[573]:
# 2) using a dict of values
periods = ["1991Y1", "1992Y1", "1993Y1", "1994Y1", "1995Y1"]
values = {"ACAF": "ACAF * 1.05",
          "ACAG": [np.nan, -39.96, -42.88, -16.33, -41.16],
          "AOUC": pd.Series([1.023, np.nan, 1.046, np.nan, 1.064], index=periods)}
variables["ACAF, ACAG, AOUC", "1991Y1:1995Y1"] = values
variables["ACAF, ACAG, AOUC", "1991Y1:1995Y1"]

c:\soft\Miniconda3\Lib\site-packages\iode\iode_database\variables_database.py:1119: FutureWarning: Series.__getitem__ treating keys as positions is deprecated. In a future version, integer keys will always be treated as labels (consistent with DataFrame behavior). To access a value by position, use `ser.iloc[pos]`
  self._cython_instance._update_variable(name, pos, values, key_periods)
[573]:
Workspace: Variables
nb variables: 3
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1991Y1:1995Y1
mode: LEVEL

name    1991Y1  1992Y1  1993Y1  1994Y1  1995Y1
ACAF     33.60   34.65   35.70   36.75   37.80
ACAG        na  -39.96  -42.88  -16.33  -41.16
AOUC      1.02      na    1.05      na    1.06
[574]:
# 3) using another variables database (subset)
variables_subset = variables["ACAF, ACAG, AOUC", "1991Y1:1995Y1"].copy()
variables_subset["ACAF"] = [1991, 1992, 1993, 1994, 1995]
variables_subset["ACAG"] = [1996, 1997, 1998, 1999, 2000]
variables_subset["AOUC"] = [2001, 2002, 2003, 2004, 2005]
variables["ACAF, ACAG, AOUC", "1991Y1:1995Y1"] = variables_subset
variables["ACAF, ACAG, AOUC", "1991Y1:1995Y1"]
[574]:
Workspace: Variables
nb variables: 3
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1991Y1:1995Y1
mode: LEVEL

name     1991Y1  1992Y1  1993Y1  1994Y1  1995Y1
ACAF    1991.00 1992.00 1993.00 1994.00 1995.00
ACAG    1996.00 1997.00 1998.00 1999.00 2000.00
AOUC    2001.00 2002.00 2003.00 2004.00 2005.00

Delete a variable:

[575]:
variables.get_names("A*")
[575]:
['A0', 'A1', 'A2', 'A5', 'ACAF', 'ACAG', 'AOUC', 'AOUC_', 'AQC']
[576]:
del variables["ACAF"]
variables.get_names("A*")
[576]:
['A0', 'A1', 'A2', 'A5', 'ACAG', 'AOUC', 'AOUC_', 'AQC']

Workspace subsets

IODE workspaces can contains a lot objects and it can be sometimes easier to work on a subset of the objects present in a workspace. To get a subset of an IODE workspace, a pattern can be passed to the [] operator. A (sub-)pattern is a list of characters representing a group of object names. It includes some special characters which have a special meaning:

  • * : any character sequence, even empty

  • ? : any character (one and only one)

  • @ : any alphanumerical char [A-Za-z0-9]

  • & : any non alphanumerical char

  • | : any alphanumeric character or none at the beginning and end of a string

  • ! : any non-alphanumeric character or none at the beginning and end of a string

  • \ : escape the next character

The pattern can contain sub-patterns, as well as, object names. The sub-patterns and object names are separated by a separator character which is either:

  • a whitespace ' '

  • a comma ,

  • a semi-colon ;

  • a tabulation \t

  • a newline \n

Note that the pattern can contain references to IODE lists which are prefixed with the symbol $.

Note

When an IODE object is added, updated or deleted from a subset of a workspace, the change is also applied to the global workspace. For example, if an equation is added to the subset of the equations workspace, the the change is also applied to the global equations database.

To create an isolate subset of a workspace, use the copy method. This method returns a new workspace in which each object is a copy of the original object from the global workspace. Any change made to the copied subset will not be applied to the global workspace. This can be useful for example if you want to save previous values of scalars before estimating an equation or a block of equations and then restore the original values if the estimated values are not satisfying.

Comments - Equations - Identities - Lists - Scalars - Tables

Let’s first begin by reloading the example workspace for all IODE types:

[577]:
comments.load(f"{SAMPLE_DATA_DIR}/fun.cmt")
equations.load(f"{SAMPLE_DATA_DIR}/fun.eqs")
identities.load(f"{SAMPLE_DATA_DIR}/fun.idt")
lists.load(f"{SAMPLE_DATA_DIR}/fun.lst")
scalars.load(f"{SAMPLE_DATA_DIR}/fun.scl")
tables.load(f"{SAMPLE_DATA_DIR}/fun.tbl")
variables.load(f"{SAMPLE_DATA_DIR}/fun.var")
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.cmt
317 objects loaded
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.eqs
274 objects loaded
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.idt
48 objects loaded
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.lst
17 objects loaded
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.scl
161 objects loaded
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.tbl
46 objects loaded
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.var
394 objects loaded
[578]:
# 1) get subset using a pattern
comments_subset = comments["A*"]
comments_subset.names
[578]:
['ACAF', 'ACAG', 'AOUC', 'AQC']
[579]:
# 2) add a comment to the subset
comments_subset["A0"] = "New Comment"
comments_subset["A0"]
[579]:
'New Comment'
[580]:
# --> new comment also appears in the global workspace
"A0" in comments, comments["A0"]
[580]:
(True, 'New Comment')
[581]:
# 3) update a comment in the subset
comments_subset["A0"] = "Updated Comment"
comments_subset["A0"]
[581]:
'Updated Comment'
[582]:
# --> comment is also updated in the global workspace
comments["A0"]
[582]:
'Updated Comment'
[583]:
# delete comment from the subset
del comments_subset["A0"]
comments_subset.names
[583]:
['ACAF', 'ACAG', 'AOUC', 'AQC']
[584]:
# NOTE: the comment has also been deleted from the global database
"A0" in comments
[584]:
False
[585]:
comments.get_names("A*")
[585]:
['ACAF', 'ACAG', 'AOUC', 'AQC']

Variables

[586]:
# 1) get subset using a pattern
vars_subset = variables["A*"]
vars_subset.names
[586]:
['ACAF', 'ACAG', 'AOUC', 'AOUC_', 'AQC']
[587]:
# get the values for a specific period -> Variables
variables["A*", "1990Y1"]
[587]:
Workspace: Variables
nb variables: 5
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1990Y1:1990Y1
mode: LEVEL

 name   1990Y1
ACAF     23.77
ACAG    -28.17
AOUC      1.00
AOUC_     0.94
AQC       1.00
[588]:
# get the variable values for range of periods -> Variables
variables["A*", "1990Y1:2000Y1"]
[588]:
Workspace: Variables
nb variables: 5
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1990Y1:2000Y1
mode: LEVEL

 name   1990Y1  1991Y1  1992Y1  1993Y1  1994Y1  1995Y1  1996Y1  1997Y1  1998Y1  1999Y1  2000Y1
ACAF     23.77   26.24   30.16   34.66    8.16  -13.13   32.17   39.94   29.65   13.53   10.05
ACAG    -28.17  -30.93  -40.29  -43.16  -16.03  -41.85  -40.24  -32.93  -38.35  -39.86  -41.53
AOUC      1.00    1.02    1.03    1.03    1.05    1.05    1.05    1.08    1.09    1.11    1.12
AOUC_     0.94    0.96    0.97    0.98    0.99    1.00    1.00    1.03    1.04    1.08    1.10
AQC       1.00    1.06    1.11    1.15    1.16    1.16    1.16    1.20    1.20    1.34    1.34
[589]:
# get the variable values for a list of non-contiguous periods -> pandas DataFrame
variables["A*", ["1990Y1", "1995Y1", "2000Y1"]]
[589]:
time 1990Y1 1995Y1 2000Y1
variables
ACAF 23.771000 -13.130997 10.046611
ACAG -28.172186 -41.845993 -41.534787
AOUC 1.000000 1.049891 1.116238
AOUC_ 0.937359 0.995263 1.101957
AQC 1.000000 1.161687 1.338603
[590]:
# 2) add a variable to the subset
vars_subset["A0"] = np.nan
vars_subset["A0"]
[590]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1960Y1:2015Y1
mode: LEVEL

name    1960Y1  1961Y1  1962Y1  1963Y1  1964Y1  1965Y1  ...     2009Y1  2010Y1  2011Y1  2012Y1  2013Y1  2014Y1  2015Y1
A0          na      na      na      na      na      na  ...         na      na      na      na      na      na      na
[591]:
# --> new variable also appears in the global workspace
"A0" in variables
[591]:
True
[592]:
variables["A0"]
[592]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1960Y1:2015Y1
mode: LEVEL

name    1960Y1  1961Y1  1962Y1  1963Y1  1964Y1  1965Y1  ...     2009Y1  2010Y1  2011Y1  2012Y1  2013Y1  2014Y1  2015Y1
A0          na      na      na      na      na      na  ...         na      na      na      na      na      na      na
[593]:
# 3) update a variable in the subset
vars_subset["A0"] = 0.0
vars_subset["A0"]
[593]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1960Y1:2015Y1
mode: LEVEL

name    1960Y1  1961Y1  1962Y1  1963Y1  1964Y1  1965Y1  ...     2009Y1  2010Y1  2011Y1  2012Y1  2013Y1  2014Y1  2015Y1
A0        0.00    0.00    0.00    0.00    0.00    0.00  ...       0.00    0.00    0.00    0.00    0.00    0.00    0.00
[594]:
# --> variable is also updated in the global workspace
variables["A0"]
[594]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1960Y1:2015Y1
mode: LEVEL

name    1960Y1  1961Y1  1962Y1  1963Y1  1964Y1  1965Y1  ...     2009Y1  2010Y1  2011Y1  2012Y1  2013Y1  2014Y1  2015Y1
A0        0.00    0.00    0.00    0.00    0.00    0.00  ...       0.00    0.00    0.00    0.00    0.00    0.00    0.00
[595]:
# delete one variable from a subset of the global database
del vars_subset["A0"]
"A0" in vars_subset
[595]:
False
[596]:
# NOTE: the variable has also been deleted from the global database
"A0" in variables
[596]:
False

It is also possible to work on subset over names and periods:

[597]:
# 1) get subset over names and periods -> Variables
vars_subset = variables["A*", "1991Y1:1995Y1"]
vars_subset.names
[597]:
['ACAF', 'ACAG', 'AOUC', 'AOUC_', 'AQC']
[598]:
vars_subset
[598]:
Workspace: Variables
nb variables: 5
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1991Y1:1995Y1
mode: LEVEL

 name   1991Y1  1992Y1  1993Y1  1994Y1  1995Y1
ACAF     26.24   30.16   34.66    8.16  -13.13
ACAG    -30.93  -40.29  -43.16  -16.03  -41.85
AOUC      1.02    1.03    1.03    1.05    1.05
AOUC_     0.96    0.97    0.98    0.99    1.00
AQC       1.06    1.11    1.15    1.16    1.16
[599]:
# 2) update a variable in the subset
vars_subset["ACAF"] = 1.0
vars_subset["ACAF"]
[599]:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1991Y1:1995Y1
mode: LEVEL

name    1991Y1  1992Y1  1993Y1  1994Y1  1995Y1
ACAF      1.00    1.00    1.00    1.00    1.00
[600]:
# --> variable is also updated in the global workspace
variables["ACAF", "1991Y1"]
[600]:
1.0
[601]:
variables["ACAF", "1995Y1"]
[601]:
1.0

Note

Selecting non-contiguous periods will return a pandas object, not a Variables object. This is because the IODE Variables workspace is designed to work with contiguous periods. The pandas object is not a view of the Variables workspace, but a copy of the data. Modifying a value of the pandas object will not affect the Variables workspace.

[602]:
df_vars_subset = variables["A*", ["1990Y1", "1995Y1", "2000Y1"]]
df_vars_subset
[602]:
time 1990Y1 1995Y1 2000Y1
variables
ACAF 23.771000 1.000000 10.046611
ACAG -28.172186 -41.845993 -41.534787
AOUC 1.000000 1.049891 1.116238
AOUC_ 0.937359 0.995263 1.101957
AQC 1.000000 1.161687 1.338603

IODE Objects

Execute Identities

To execute an identity, use the execute() method of the identities workspace:

[603]:
identities.load(f"{SAMPLE_DATA_DIR}/fun.idt")
variables.load(f"{SAMPLE_DATA_DIR}/fun.var")

print(identities["GAP_"])
print(identities["GAP2"])

# reset variables GAP_ and GAP2
variables["GAP_"] = 0.
variables["GAP2"] = 0.
variables["GAP_;GAP2"]

Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.idt
48 objects loaded
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.var
394 objects loaded
100*((QAF_/Q_F)-1)
100*(QAFF_/(Q_F+Q_I))
[603]:
Workspace: Variables
nb variables: 2
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1960Y1:2015Y1
mode: LEVEL

name    1960Y1  1961Y1  1962Y1  1963Y1  1964Y1  1965Y1  ...     2009Y1  2010Y1  2011Y1  2012Y1  2013Y1  2014Y1  2015Y1
GAP2      0.00    0.00    0.00    0.00    0.00    0.00  ...       0.00    0.00    0.00    0.00    0.00    0.00    0.00
GAP_      0.00    0.00    0.00    0.00    0.00    0.00  ...       0.00    0.00    0.00    0.00    0.00    0.00    0.00
[604]:
# compute GAP_ and GAP2 (assuming Scalars and Variables are already loaded)
identities.execute("GAP_;GAP2")
variables["GAP_;GAP2"]
[604]:
Workspace: Variables
nb variables: 2
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1960Y1:2015Y1
mode: LEVEL

name    1960Y1  1961Y1  1962Y1  1963Y1  1964Y1  1965Y1  ...     2009Y1  2010Y1  2011Y1  2012Y1  2013Y1  2014Y1  2015Y1
GAP2     96.93   97.40   98.37   97.71  100.88  100.63  ...     100.85  100.54  101.36  102.19  102.50  102.15  101.59
GAP_     -3.20   -3.98   -2.12   -2.65   -0.23   -0.65  ...       1.96    1.61    2.61    3.61    4.06    3.78    3.24
[605]:
# compute GAP_ and GAP2 over a subset of the sample
variables["GAP_"] = 0.
variables["GAP2"] = 0.
identities.execute("GAP_;GAP2", "2000Y1", "2005Y1")
variables["GAP_;GAP2", "1998Y1:2007Y1"]
[605]:
Workspace: Variables
nb variables: 2
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1998Y1:2007Y1
mode: LEVEL

name    1998Y1  1999Y1  2000Y1  2001Y1  2002Y1  2003Y1  2004Y1  2005Y1  2006Y1  2007Y1
GAP2      0.00    0.00  104.61  103.06  102.17  102.82  104.47  104.36    0.00    0.00
GAP_      0.00    0.00    4.51    3.31    2.62    3.46    5.48    5.58    0.00    0.00

IODE Table

Create An IODE Table

To create an IODE table, you can either:

  1. Call the Table constructor without any argument. This will create an empty table with two columns. Then you can add lines using the += operator or the insert() method (see next section).

[606]:
# empty table
table = Table()
table
[606]:
DIVIS | 1 |
TITLE |
----- | --------
CELL  |   | "#S"
----- | --------

nb lines: 4
nb columns: 2
language: 'ENGLISH'
gridx: 'MAJOR'
gridy: 'MAJOR'
graph_axis: 'VALUES'
graph_alignment: 'LEFT'
  1. Call the Table constructor with a title and a list of variables. This list can contain IODE list(s) referenced with a $ symbol. In that case, the IODE list(s) will be expanded to its (their) content. For each row, if an IODE comment with the same name as the variable exists, the value of the comment will be used in the left column. If the comment does not exist, the name of the variable will be used. The boolean arguments mode, files and date can be used to append the corresponding special lines to the table. These three lines are used when the table is computed (according to a generalized sample):

[607]:
# content of the IODE list 'ENVI'
lists["ENVI"]
[607]:
['EX',
 'PWMAB',
 'PWMS',
 'PWXAB',
 'PWXS',
 'QWXAB',
 'QWXS',
 'POIL',
 'NATY',
 'TFPFHP_']
[608]:
# create a table using a list of variables
# NOTE: the list of variables can contain IODE list(s).
#       The IODE list(s) must be referenced using the '$' symbol
table_title = "Table example with variables only"
lines_vars = ["GOSG", "YDTG", "DTH", "DTF", "IT", "YSSG", "COTRES", "RIDG", "OCUG", "$ENVI"]
table = Table(2, table_title, lines_vars, mode=True, files=True, date=True)
table
[608]:
DIVIS | 1                                                                    |
TITLE |                      "Table example with variables only"
----- | ------------------------------------------------------------------------------
CELL  |                                                                      |   "#S"
----- | ------------------------------------------------------------------------------
CELL  | "Bruto exploitatie-overschot: overheid (= afschrijvingen)."          |    GOSG
CELL  | "Overheid: geïnde indirecte belastingen."                            |    YDTG
CELL  | "Totale overheid: directe belasting van de gezinnen."                |     DTH
CELL  | "Totale overheid: directe vennootschapsbelasting."                   |     DTF
CELL  | "Totale indirecte belastingen."                                      |      IT
CELL  | "Globale overheid: ontvangen sociale zekerheidsbijdragen."           |    YSSG
CELL  | "Cotisation de responsabilisation."                                  |  COTRES
CELL  | "Overheid: inkomen uit vermogen."                                    |    RIDG
CELL  | "Globale overheid: saldo van de ontvangen lopendeoverdrachten."      |    OCUG
CELL  | "Wisselkoers van de USD t.o.v. de BEF (jaargemiddelde)."             |      EX
CELL  | "Index wereldprijs - invoer van niet-energieprodukten, inUSD."       |   PWMAB
CELL  | "Index wereldprijs - invoer van diensten, in USD."                   |    PWMS
CELL  | "Index wereldprijs - uitvoer van niet-energieprodukten, inUSD."      |   PWXAB
CELL  | "Index wereldprijs - uitvoer van diensten, in USD."                  |    PWXS
CELL  | "Indicator van het volume van de wereldvraag naar goederen,1985=1."  |   QWXAB
CELL  | "Indicator van het volume van de wereldvraag naar diensten,1985=1."  |    QWXS
CELL  | "Brent olieprijs (USD per barrel)."                                  |    POIL
CELL  | "Totale beroepsbevolking (jaargemiddelde)."                          |    NATY
CELL  | "TFPFHP_"                                                            | TFPFHP_
----- | ------------------------------------------------------------------------------
MODE  |
FILES |
DATE  |

nb lines: 27
nb columns: 2
language: 'ENGLISH'
gridx: 'MAJOR'
gridy: 'MAJOR'
graph_axis: 'VALUES'
graph_alignment: 'LEFT'
[609]:
# variables or LEC expressions can be also passed as a single string
lines_vars = "GOSG;YDTG;DTH;DTF;IT;YSSG;COTRES;RIDG;OCUG;$ENVI"
table_title = "Table example with all variables passed as a single string"
table = Table(2, table_title, lines_vars, mode=True, files=True, date=True)
table
[609]:
DIVIS | 1                                                                    |
TITLE |          "Table example with all variables passed as a single string"
----- | ------------------------------------------------------------------------------
CELL  |                                                                      |   "#S"
----- | ------------------------------------------------------------------------------
CELL  | "Bruto exploitatie-overschot: overheid (= afschrijvingen)."          |    GOSG
CELL  | "Overheid: geïnde indirecte belastingen."                            |    YDTG
CELL  | "Totale overheid: directe belasting van de gezinnen."                |     DTH
CELL  | "Totale overheid: directe vennootschapsbelasting."                   |     DTF
CELL  | "Totale indirecte belastingen."                                      |      IT
CELL  | "Globale overheid: ontvangen sociale zekerheidsbijdragen."           |    YSSG
CELL  | "Cotisation de responsabilisation."                                  |  COTRES
CELL  | "Overheid: inkomen uit vermogen."                                    |    RIDG
CELL  | "Globale overheid: saldo van de ontvangen lopendeoverdrachten."      |    OCUG
CELL  | "Wisselkoers van de USD t.o.v. de BEF (jaargemiddelde)."             |      EX
CELL  | "Index wereldprijs - invoer van niet-energieprodukten, inUSD."       |   PWMAB
CELL  | "Index wereldprijs - invoer van diensten, in USD."                   |    PWMS
CELL  | "Index wereldprijs - uitvoer van niet-energieprodukten, inUSD."      |   PWXAB
CELL  | "Index wereldprijs - uitvoer van diensten, in USD."                  |    PWXS
CELL  | "Indicator van het volume van de wereldvraag naar goederen,1985=1."  |   QWXAB
CELL  | "Indicator van het volume van de wereldvraag naar diensten,1985=1."  |    QWXS
CELL  | "Brent olieprijs (USD per barrel)."                                  |    POIL
CELL  | "Totale beroepsbevolking (jaargemiddelde)."                          |    NATY
CELL  | "TFPFHP_"                                                            | TFPFHP_
----- | ------------------------------------------------------------------------------
MODE  |
FILES |
DATE  |

nb lines: 27
nb columns: 2
language: 'ENGLISH'
gridx: 'MAJOR'
gridy: 'MAJOR'
graph_axis: 'VALUES'
graph_alignment: 'LEFT'
  1. Call the Table constructor with a title, a list of line titles (left column) and a list of the variables names or LEC expressions (right column):

[610]:
table_title = "Table example with titles on the left and LEC expressions on the right"
# left column
lines_titles = ["GOSG:", "YDTG:", "DTH:", "DTF:", "IT:", "YSSG+COTRES:", "RIDG:", "OCUG:"]
# right column
lines_lecs = ["GOSG", "YDTG", "DTH", "DTF", "IT", "YSSG+COTRES", "RIDG", "OCUG"]
table = Table(2, table_title, lines_lecs, lines_titles, True, True, True)
table
[610]:
DIVIS | 1              |
TITLE | "Table example with titles on the left and LEC expressions on the right"
----- | ------------------------------------------------------------------------
CELL  |                |     "#S"
----- | ------------------------------------------------------------------------
CELL  | "GOSG:"        |        GOSG
CELL  | "YDTG:"        |        YDTG
CELL  | "DTH:"         |         DTH
CELL  | "DTF:"         |         DTF
CELL  | "IT:"          |          IT
CELL  | "YSSG+COTRES:" | YSSG+COTRES
CELL  | "RIDG:"        |        RIDG
CELL  | "OCUG:"        |        OCUG
----- | ------------------------------------------------------------------------
MODE  |
FILES |
DATE  |

nb lines: 16
nb columns: 2
language: 'ENGLISH'
gridx: 'MAJOR'
gridy: 'MAJOR'
graph_axis: 'VALUES'
graph_alignment: 'LEFT'

Get/Update The Divider Line

To update the divider line, use the divider attribute:

[611]:
# the default divider is 1
table.divider
[611]:
('1', '')
[612]:
# update the divider to multiply all values of the
# right column by 100 (e.g. to get percentage values)
table.divider = ('1', '1e-2')
table.divider
[612]:
('1', '1e-2')

Find The Position Of A Line

To find the position of a line in an IODE table, use the index(str) method:

[613]:
# find the index of the TITLE or CELL line containing RIDG
index = table.index("RIDG")
index
[613]:
10

Get/Update Content Of Lines

To get or update the content of a line, use the [index] operator:

[614]:
table[4]
[614]:
('"GOSG:"', 'GOSG')

Negative indices can be used to get or update the content of a line from the end of the table:

[615]:
# content of the last line
table[-1]
[615]:
<DATE>

Append Lines

To append a line to an IODE table, use the += operator:

[616]:
from iode import TableLineType

table = Table()

# append a title line
table += "Dummy Table"

# append a separator line
table += '-'

# append a line with cells
# NOTE: line containing double quotes " -> assumed to be a STRING cell
#       line without double quotes      -> assumed to be a LEC cell
table += ('"RIDG:"', 'RIDG')

# append a separator line (other way to do it)
table += TableLineType.SEP

# append a special MODE line
table += TableLineType.MODE

# append a special FILES line
table += TableLineType.FILES

# append a special DATE line
table += TableLineType.DATE

table
[616]:
DIVIS | 1       |
TITLE |
----- | --------------
CELL  |         | "#S"
----- | --------------
TITLE | "Dummy Table"
----- | --------------
CELL  | "RIDG:" | RIDG
----- | --------------
MODE  |
FILES |
DATE  |

nb lines: 11
nb columns: 2
language: 'ENGLISH'
gridx: 'MAJOR'
gridy: 'MAJOR'
graph_axis: 'VALUES'
graph_alignment: 'LEFT'

Insert Lines

To insert a line at a specific index, use the insert(index, value) method:

[617]:
# insert a CELL line before the RIDG line
index = table.index("RIDG")
table.insert(index, ('"OCUG:"', 'OCUG'))

# insert a CELL line after the RIDG line
index = table.index("RIDG")
table.insert(index + 1, ('"GOSG:"', 'GOSG'))

# insert a separator after the GOSG line
index = table.index("GOSG")
index += 1
table.insert(index, '-')

# insert a title line after the separator line
index += 1
table.insert(index, "New Title")

# insert a separator line after the title line
index += 1
table.insert(index, TableLineType.SEP)

table
[617]:
DIVIS | 1       |
TITLE |
----- | --------------
CELL  |         | "#S"
----- | --------------
TITLE | "Dummy Table"
----- | --------------
CELL  | "OCUG:" | OCUG
CELL  | "RIDG:" | RIDG
CELL  | "GOSG:" | GOSG
----- | --------------
TITLE |  "New Title"
----- | --------------
----- | --------------
MODE  |
FILES |
DATE  |

nb lines: 16
nb columns: 2
language: 'ENGLISH'
gridx: 'MAJOR'
gridy: 'MAJOR'
graph_axis: 'VALUES'
graph_alignment: 'LEFT'

Delete Lines

To delete a line, use the del keyword:

[618]:
index = table.index("New Title")

# delete the title line
del table[index]

table
[618]:
DIVIS | 1       |
TITLE |
----- | --------------
CELL  |         | "#S"
----- | --------------
TITLE | "Dummy Table"
----- | --------------
CELL  | "OCUG:" | OCUG
CELL  | "RIDG:" | RIDG
CELL  | "GOSG:" | GOSG
----- | --------------
----- | --------------
----- | --------------
MODE  |
FILES |
DATE  |

nb lines: 15
nb columns: 2
language: 'ENGLISH'
gridx: 'MAJOR'
gridy: 'MAJOR'
graph_axis: 'VALUES'
graph_alignment: 'LEFT'

Negative indices can be used to delete lines from the end of the table:

[619]:
# delete the last line
del table[-1]

table
[619]:
DIVIS | 1       |
TITLE |
----- | --------------
CELL  |         | "#S"
----- | --------------
TITLE | "Dummy Table"
----- | --------------
CELL  | "OCUG:" | OCUG
CELL  | "RIDG:" | RIDG
CELL  | "GOSG:" | GOSG
----- | --------------
----- | --------------
----- | --------------
MODE  |
FILES |

nb lines: 14
nb columns: 2
language: 'ENGLISH'
gridx: 'MAJOR'
gridy: 'MAJOR'
graph_axis: 'VALUES'
graph_alignment: 'LEFT'

Get Variables And Scalars Referenced In Equations, Identities And Tables

To get the list of scalars (coefficients) and variables referenced in equations, use the coefficients and variables properties of the Equation class or the coefficients and variables properties of the equations workspace:

[620]:
equations["A*"]
c:\soft\Miniconda3\Lib\site-packages\iode\time\sample.py:240: UserWarning: 'sample' is not defined
  return self._cython_instance.__str__()
[620]:
Workspace: Equations
nb equations: 3
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.eqs

name                                         lec                                        method      sample      block    fstat  r2adj     dw     loglik    date
ACAF    (ACAF/VAF[-1]) :=acaf1+acaf2*GOSF[-1]+ acaf4*(TIME=1995)                           LSQ  1980Y1:1996Y1    ACAF   32.2732 0.7963  2.3293  83.8075 12-06-1998
ACAG    ACAG := ACAG[-1]+r VBBP[-1]+(0.006*VBBP[-1]*(TIME=2001)-0.008*(TIME=2008))         LSQ           None    ACAG    0.0000 0.0000  0.0000   0.0000
AOUC    AOUC:=((WCRH/QL)/(WCRH/QL)[1990Y1])*(VAFF/(VM+VAFF))[-1]+PM*(VM/(VAFF+VM))[-1]     LSQ           None    AOUC    0.0000 0.0000  0.0000   0.0000
[621]:
equations["A*"].coefficients
[621]:
['acaf1', 'acaf2', 'acaf4']
[622]:
equations["A*"].variables
[622]:
['ACAF',
 'ACAG',
 'AOUC',
 'GOSF',
 'PM',
 'QL',
 'TIME',
 'VAF',
 'VAFF',
 'VBBP',
 'VM',
 'WCRH']
[623]:
eq_ACAF = equations["ACAF"]
eq_ACAF
[623]:
Equation(endogenous = 'ACAF',
         lec = '(ACAF/VAF[-1]) :=acaf1+acaf2*GOSF[-1]+\nacaf4*(TIME=1995)',
         method = 'LSQ',
         from_period = '1980Y1',
         to_period = '1996Y1',
         block = 'ACAF',
         tests = {corr = 1,
                  dw = 2.32935,
                  fstat = 32.2732,
                  loglik = 83.8075,
                  meany = 0.00818467,
                  r2 = 0.821761,
                  r2adj = 0.796299,
                  ssres = 5.19945e-05,
                  stderr = 0.00192715,
                  stderrp = 23.5458,
                  stdev = 0.0042699},
         date = '12-06-1998')
[624]:
eq_ACAF.coefficients
[624]:
['acaf1', 'acaf2', 'acaf4']
[625]:
eq_ACAF.variables
[625]:
['ACAF', 'VAF', 'GOSF', 'TIME']

To get the list of scalars (coefficients) and variables referenced in identities, use the coefficients and variables properties of the Identity class or the coefficients and variables properties of the identities workspace:

[626]:
identities["A*;N*"]
[626]:
Workspace: Identities
nb identities: 4
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.idt

 name                                               identities
AOUC    ((WCRH/QL)/(WCRH/QL)[1990Y1])*(VAFF/(VM+VAFF))[-1]+PM*(VM/(VM+VAFF))[-1]
AOUC_   exp(ln(((WCF/NFYH)/QL)+PKF/(QAFF/KNFFY))*(QAFF/(QX+QAFF)+.05)[-1]+ln PM*(QM/ (QAFF+QM)-0.05)[-1])
NAWRU   1-exp((gamma2+gamma3*ln(W/ZJ)[-1]+gamma4*ln(WMIN/ZJ))/ gamma_)
NFYHO   1
[627]:
identities["A*;N*"].coefficients
[627]:
['gamma2', 'gamma3', 'gamma4', 'gamma_']
[628]:
identities["A*;N*"].variables
[628]:
['KNFFY',
 'NFYH',
 'PKF',
 'PM',
 'QAFF',
 'QL',
 'QM',
 'QX',
 'VAFF',
 'VM',
 'W',
 'WCF',
 'WCRH',
 'WMIN',
 'ZJ']
[629]:
idt_NAWRU = identities["NAWRU"]
idt_NAWRU
[629]:
Identity('1-exp((gamma2+gamma3*ln(W/ZJ)[-1]+gamma4*ln(WMIN/ZJ))/
gamma_)')
[630]:
idt_NAWRU.coefficients
[630]:
['gamma2', 'gamma3', 'gamma4', 'gamma_']
[631]:
idt_NAWRU.variables
[631]:
['W', 'ZJ', 'WMIN']

To get the list of scalars (coefficients) and variables referenced in tables, use the coefficients and variables properties of the Table class or the coefficients and variables properties of the tables workspace:

[632]:
tables["A*"]
[632]:
Workspace: Tables
nb tables: 2
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.tbl

  name             table titles
ANAKNFF Déterminants de la croissance de K
ANAPRIX Analyse des prix
[633]:
tables["ANAKNFF"]
[633]:
DIVIS |                                  1 |
TITLE |                "Déterminants de la croissance de K"
----- | ------------------------------------------------------------------
CELL  |                                    |              "#s"
----- | ------------------------------------------------------------------
CELL  | "Croissance de K "                 |                      dln KNFF
CELL  | "Output gap "                      |    knff1*ln (QAFF_/(Q_F+Q_I))
CELL  | "Rentabilité "                     |          knf2*ln mavg(3,RENT)
CELL  | "Croissance anticipée de l'output" | 0.416*mavg(4,dln QAFF_)+0.023

nb lines: 8
nb columns: 2
language: 'ENGLISH'
gridx: 'MAJOR'
gridy: 'MAJOR'
graph_axis: 'VALUES'
graph_alignment: 'LEFT'
[634]:
tables["ANAPRIX"]
[634]:
DIVIS | 1                            |
TITLE |                        "Analyse des prix"
----- | ---------------------------------------------------------------
CELL  |                              |               "#s"
----- | ---------------------------------------------------------------
CELL  | "GAP_"                       |                             GAP_
CELL  | "dln (PC/(1+ITCR))-dln AOUC" | 100*(dln (PC/(1+ITCR))-dln AOUC)

nb lines: 6
nb columns: 2
language: 'ENGLISH'
gridx: 'MAJOR'
gridy: 'MAJOR'
graph_axis: 'VALUES'
graph_alignment: 'LEFT'
[635]:
tables["A*"].coefficients
[635]:
['knf2', 'knff1']
[636]:
tables["A*"].variables
[636]:
['AOUC', 'GAP_', 'ITCR', 'KNFF', 'PC', 'QAFF_', 'Q_F', 'Q_I', 'RENT']
[637]:
table_ANAKNFF = tables["ANAKNFF"]
table_ANAKNFF
[637]:
DIVIS |                                  1 |
TITLE |                "Déterminants de la croissance de K"
----- | ------------------------------------------------------------------
CELL  |                                    |              "#s"
----- | ------------------------------------------------------------------
CELL  | "Croissance de K "                 |                      dln KNFF
CELL  | "Output gap "                      |    knff1*ln (QAFF_/(Q_F+Q_I))
CELL  | "Rentabilité "                     |          knf2*ln mavg(3,RENT)
CELL  | "Croissance anticipée de l'output" | 0.416*mavg(4,dln QAFF_)+0.023

nb lines: 8
nb columns: 2
language: 'ENGLISH'
gridx: 'MAJOR'
gridy: 'MAJOR'
graph_axis: 'VALUES'
graph_alignment: 'LEFT'
[638]:
table_ANAKNFF.coefficients
[638]:
['knf2', 'knff1']
[639]:
table_ANAKNFF.variables
[639]:
['KNFF', 'QAFF_', 'Q_F', 'Q_I', 'RENT']

Get IODE Objects Referenced In Other IODE Objects

To get the list of IODE objects referenced in another IODE object, use the search method. For instance, it can be used to get the list of equations containing a specific scalar or variable:

[640]:
# list of equations containing the scalar 'acaf1'
eq_list = equations.search("acaf1")
print("equations containing the scalar 'acaf1':", eq_list)

# list of equations containing the variable 'AOUC'
eq_list = equations.search("AOUC")
print("equations containing the variable 'AOUC':", eq_list)

# list of equations containing either the variable 'ACAF', 'ACAG' or 'AOUC'
eq_set = set()
for var in ["ACAF", "ACAG", "AOUC"]:
    eq_set |= set(equations.search(var))
eq_list = sorted(list(eq_set))
print("equations containing the variables 'ACAF', 'ACAG' or 'AOUC':\n", eq_list)
equations containing the scalar 'acaf1': ['ACAF']
equations containing the variable 'AOUC': ['AOUC', 'PC', 'PIF', 'PXS', 'QXAB']
equations containing the variables 'ACAF', 'ACAG' or 'AOUC':
 ['ACAF', 'ACAG', 'AOUC', 'FLF', 'FLG', 'PC', 'PIF', 'PXS', 'QXAB']

Get Words Referenced In IODE Objects

More generally, the search method can also be used to get the list of IODE objects containing a specific word or pattern. For instance, it can be used to get the list of comments and tables containing a specific word:

[641]:
# list of comments containing the word 'Croissance'
cmt_list = comments.search("Croissance")
print("comments containing the word 'Croissance':\n", cmt_list)

# list of tables containing the word 'Croissance'
tbl_list = tables.search("Croissance")
print("tables containing the word 'Croissance':\n", tbl_list)
comments containing the word 'Croissance':
 ['XNATY', 'XPOIL', 'XPWMAB', 'XPWXAB', 'XQWXSS', 'XTFP']
tables containing the word 'Croissance':
 ['ANAKNFF', 'C8_5', 'C9_1', 'C9_4', 'T1', 'XQBBP']

Arithmetic Operations On Variables

[642]:
# reload variables to start from a clean state
variables.load(f"{SAMPLE_DATA_DIR}/fun.var")

# select a subset of variables for the examples below
vars_subset = variables["A*", "1991Y1:1995Y1"]
vars_subset
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.var
394 objects loaded
[642]:
Workspace: Variables
nb variables: 5
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1991Y1:1995Y1
mode: LEVEL

 name   1991Y1  1992Y1  1993Y1  1994Y1  1995Y1
ACAF     26.24   30.16   34.66    8.16  -13.13
ACAG    -30.93  -40.29  -43.16  -16.03  -41.85
AOUC      1.02    1.03    1.03    1.05    1.05
AOUC_     0.96    0.97    0.98    0.99    1.00
AQC       1.06    1.11    1.15    1.16    1.16

With a float

[643]:
# add a scalar to all values of a subset of variables
new_vars_subset = vars_subset + 2.0
new_vars_subset
[643]:
Workspace: Variables
nb variables: 5
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1991Y1:1995Y1
mode: LEVEL

 name   1991Y1  1992Y1  1993Y1  1994Y1  1995Y1
ACAF     28.24   32.16   36.66   10.16  -11.13
ACAG    -28.93  -38.29  -41.16  -14.03  -39.85
AOUC      3.02    3.03    3.03    3.05    3.05
AOUC_     2.96    2.97    2.98    2.99    3.00
AQC       3.06    3.11    3.15    3.16    3.16

Between (Subsets Of) Variables Objects

[644]:
# add two subsets of variables
new_vars_subset = vars_subset + vars_subset
new_vars_subset
[644]:
Workspace: Variables
nb variables: 5
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1991Y1:1995Y1
mode: LEVEL

 name   1991Y1  1992Y1  1993Y1  1994Y1  1995Y1
ACAF     52.48   60.32   69.32   16.32  -26.26
ACAG    -61.87  -80.57  -86.32  -32.06  -83.69
AOUC      2.05    2.06    2.06    2.09    2.10
AOUC_     1.93    1.95    1.96    1.98    1.99
AQC       2.13    2.22    2.31    2.31    2.32

With pandas Series or DataFrame

See the Arithmetic Operations On Variables With pandas Series And DataFrames section from the IODE and pandas tutorial for more details.

With larray Arrays

See the Arithmetic Operations On Variables With larray Array objects section from the IODE and larray tutorial for more details.

With numpy ndarrays

See the Arithmetic Operations On Variables With numpy ndarray objects section from the IODE and numpy tutorial for more details.

Computed Tables

To compute a table according to a generalized sample and extra files, use the Table.compute method of the IODE table objects:

Calling compute(generalized_sample, extra_files, nb_decimals, quiet) computes the values corresponding to LEC expressions in cells.

The values are calculated for given a generalized sample. This sample contains the following information:

  • the sampling of the periods to take into account

  • the operations to be performed on the periods

  • the list of files involved in the computation of the table

  • the operations to be performed between files

  • the repetition factor

The syntax of the generalized sample follows the rules described below. The syntax of a period:

  • a period is indicated as in LEC: yyPpp or yyyyPpp where yyyy indicates the year, P the periodicity and pp the sub-period (e.g. 1990Y1)

  • a period can be shifted n periods to the left or right using the operators <n and >n

  • when used with a zero argument, the shift operators have a special meaning:

    • <0 means “first period of the year”

    • >0 means “last period of the year”

  • the special periods ‘BOS’, ‘EOS’ and ‘NOW’ can be used to represent the beginning or end of the current sample or the current period (PC clock)

  • the special periods ‘BOS1’, ‘EOS1’ and ‘NOW1’ are equivalent to the previous ones, except that they are moved to the first sub-period of the year of ‘BOS’, ‘EOS’ and ‘NOW’ respectively (if NOW = 2012M5, NOW1 = 2012M1)

  • each period is separated from the next by a semicolon

  • a period or group of periods can be repeated: simply place the colon character (:) after the definition of the column or group of columns, followed by the desired number of repetitions. Repetitions are made with an increment of one period, unless followed by an asterisk and a value. This value is then the repeat increment. It can be negative, in which case the periods are presented in decreasing order

  • the repeat, increment and shift can be the words PER (or P) or SUB (or S), which respectively indicate the number of periods in a year of the current sample and the current sub-period

  • the file definition is optional and is enclosed in square brackets. It applies to all preceding period definitions.

The following file operations are possible:

  • absolute value: [1]

  • difference: [1-2]

  • difference in percent: [1/2]

  • sum: [1+2]

  • average: [1~2] or [1^2].

The file [1] always refers to the current workspace. Extra files (if passed as argument) are numerated from 2 to 5. The following period operations are possible:

  • value: (75)

  • growth rate over one or more periods: (75/74, 75/70)

  • average growth rate: (75//70)

  • difference: (75-74, 75-70)

  • average difference: (75–70)

  • average: (75~74) or (75^74)

  • sum of consecutive periods: (70Q1+70Q4)

  • index or base value: (76=70)

Repetition can be performed with an increment greater than 1 or less than 0: simply place a star followed by the step after the number of repetitions (70:3*5 = 70, 75, 80).

Generalized sample examples:

70; 75; 80:6 = 70:3*5; 81:5 = 70; 75; 80; 81; 82; 83; 84; 85
70/69:2 = 70/69; 71/70
(70; 70-69):2 = 70; 70-69; 71; 71-70;
70[1,2]:2*5 = 70[1]; 70[2]; 75[1]; 75[2]
(70;75)[1,2-1] = 70[1]; 75[1]; 70[2-1]; 75[2-1]
(70;75;(80; 80/79):2)[1,2] = 70[1]; 70[2]; 75[1]; 75[2]; 80[1]; 80[2]; 80/79[1]; 80/79[2] 81[1]; 8[2]; 8180[1]; 81/80[2]
2000Y1>5 = 2005Y1
1999M1>12 = 2000M1
EOS<1 = 2019Y1                         (if EOS == 2020Y1)
BOS<1 = 1959Y1                         (if BOS == 1960Y1)
EOS<4:5*-1 =2016;2017;2018;2019;2020   (if EOS = 2020Y1)

Examples

[645]:
tables["C8_1"]
[645]:
DIVIS | 1                                  |
TITLE |      "Déterminants de l'output potentiel"
----- | ---------------------------------------------
CELL  |                                    |   "#s"
----- | ---------------------------------------------
CELL  | "Output potentiel"                 |  Q_F+Q_I
CELL  | "Stock de capital"                 | KNFF[-1]
CELL  | "Intensité de capital"             |    KLFHP
CELL  | "Productivité totale des facteurs" |  TFPFHP_

nb lines: 8
nb columns: 2
language: 'ENGLISH'
gridx: 'MAJOR'
gridy: 'MAJOR'
graph_axis: 'VALUES'
graph_alignment: 'LEFT'
[646]:
# simple time series (current workspace) - 6 observations - 4 decimals
computed_table = tables["C8_1"].compute("2000:6", nb_decimals=4)
computed_table
[646]:
   line title \ period[file]     |     00    |     01    |     02    |     03    |     04    |     05
---------------------------------------------------------------------------------------------------------
Output potentiel                 | 5495.2128 | 5627.8589 | 5748.7804 | 5857.9529 | 5966.1999 | 6103.6318
Stock de capital                 | 8083.5517 | 8359.8908 | 8647.9354 | 8910.3393 | 9175.8106 | 9468.8865
Intensité de capital             |    0.5032 |    0.4896 |    0.4758 |    0.4623 |    0.4481 |    0.4349
Productivité totale des facteurs |    0.9938 |    1.0037 |    1.0137 |    1.0239 |    1.0341 |    1.0445
[647]:
# get lines of the computed table
computed_table.lines
[647]:
['Output potentiel',
 'Stock de capital',
 'Intensité de capital',
 'Productivité totale des facteurs']
[648]:
# get columns of the computed table
computed_table.columns
[648]:
['00', '01', '02', '03', '04', '05']
[649]:
# two time series (current workspace) - 5 observations - 2 decimals (default)
computed_table = tables["C8_1"].compute("(2010;2010/2009):5")
computed_table
[649]:
   line title \ period[file]     |    10    | 10/09 |    11    | 11/10 |    12    | 12/11 |    13    | 13/12 |    14    | 14/13
--------------------------------------------------------------------------------------------------------------------------------
Output potentiel                 |  6936.11 |  1.74 |  7045.34 |  1.57 |  7161.54 |  1.65 |  7302.29 |  1.97 |  7460.12 |  2.16
Stock de capital                 | 11293.85 |  2.82 | 11525.01 |  2.05 | 11736.78 |  1.84 | 11975.49 |  2.03 | 12263.95 |  2.41
Intensité de capital             |     0.39 | -2.17 |     0.38 | -2.05 |     0.37 | -1.91 |     0.36 | -1.86 |     0.36 | -1.90
Productivité totale des facteurs |     1.10 |  1.00 |     1.11 |  1.00 |     1.12 |  1.00 |     1.13 |  1.00 |     1.14 |  1.00
[650]:
from pathlib import Path

# simple time series (current workspace + one extra file) - 5 observations - 2 decimals (default)
sample_data_dir = Path(SAMPLE_DATA_DIR)
computed_table = tables["C8_1"].compute("2010[1;2]:5", extra_files=sample_data_dir/"ref.av", quiet=True)
computed_table
[650]:
   line title \ period[file]     |  10[1]   |  10[2]   |  11[1]   |  11[2]   |  12[1]   |  12[2]   |  13[1]   |  13[2]   |  14[1]   |  14[2]
-----------------------------------------------------------------------------------------------------------------------------------------------
Output potentiel                 |  6936.11 |  6797.39 |  7045.34 |  6904.44 |  7161.54 |  7018.31 |  7302.29 |  7156.24 |  7460.12 |  7310.91
Stock de capital                 | 11293.85 | 11067.97 | 11525.01 | 11294.51 | 11736.78 | 11502.05 | 11975.49 | 11735.98 | 12263.95 | 12018.67
Intensité de capital             |     0.39 |     0.38 |     0.38 |     0.37 |     0.37 |     0.36 |     0.36 |     0.36 |     0.36 |     0.35
Productivité totale des facteurs |     1.10 |     1.08 |     1.11 |     1.09 |     1.12 |     1.10 |     1.13 |     1.11 |     1.14 |     1.12
[651]:
# get the list of files used to compute the table
# (the first file represents the current workspace)
computed_table.files
[651]:
['c:\\soft\\Miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var',
 'c:\\soft\\Miniconda3\\Lib\\site-packages\\iode\\tests\\data\\ref.av']
[652]:
# simple time series (current workspace + 4 extra files) - 5 observations - 2 decimals (default)
extra_files = [sample_data_dir / "ref.av", sample_data_dir / "fun.av",
               sample_data_dir / "fun2.av", sample_data_dir / "a.var"]
computed_table = tables["C8_1"].compute("2010[1;2;3;4;5]:1", extra_files=extra_files, quiet=True)
computed_table
[652]:
   line title \ period[file]     |  10[1]   |  10[2]   |  10[3]   |  10[4]   | 10[5]
-------------------------------------------------------------------------------------
Output potentiel                 |  6936.11 |  6797.39 |  6936.11 |  6936.11 |    --
Stock de capital                 | 11293.85 | 11067.97 | 11293.85 | 11293.85 |    --
Intensité de capital             |     0.39 |     0.38 |     0.39 |     0.39 |    --
Productivité totale des facteurs |     1.10 |     1.08 |     1.10 |     1.10 |    --
[653]:
# get the list of files used to compute the table
# (the first file represents the current workspace)
computed_table.files
[653]:
['c:\\soft\\Miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var',
 'c:\\soft\\Miniconda3\\Lib\\site-packages\\iode\\tests\\data\\ref.av',
 'c:\\soft\\Miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.av',
 'c:\\soft\\Miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun2.av',
 'c:\\soft\\Miniconda3\\Lib\\site-packages\\iode\\tests\\data\\a.var']

Estimation

To estimate either one equation or a block of equations, use the estimate method of the Equation class or the estimate method of the Equations workspace:

Calling the estimate(from_period, to_period, list_eqs, quiet) method estimates an equation or a block of equations in the specified periods range.

At the end of the estimation process, certain variables and scalars are automatically created if the process has converged. These variables and scalars can be used for computational purposes and, as they are part of the global workspace, can be saved for future use.

The tests resulting from the last estimation are saved as scalars. The same applies to residuals, left-hand and right-hand members of equations.

Saved tests (as scalars) have the following names (e<ith>_* for the equation of the block):

  • e<ith>_n : number of sample periods

  • e<ith>_k : number of estimated coefficients

  • e<ith>_stdev : std dev of residuals

  • e<ith>_meany : mean of Y

  • e<ith>_ssres : sum of squares of residuals

  • e<ith>_stderr : std error

  • e<ith>_stderrp : std error percent (in %)

  • e<ith>_fstat : F-Stat

  • e<ith>_r2 : R square

  • e<ith>_r2adj : adjusted R-squared

  • e<ith>_dw : Durbin-Watson

  • e<ith>_loglik : Log Likelihood

Calculated series are saved in special variables:

  • _YCALC<i> : right-hand side of the equation in the block

  • _YOBS<i> : left-hand side of the equation in the block

  • _YRES<i> : residuals of the equation of the block

Outside the estimation sample, the series values are NA.

Let’s start by reloading all workspaces:

[654]:
comments.load(f"{SAMPLE_DATA_DIR}/fun.cmt")
equations.load(f"{SAMPLE_DATA_DIR}/fun.eqs")
identities.load(f"{SAMPLE_DATA_DIR}/fun.idt")
lists.load(f"{SAMPLE_DATA_DIR}/fun.lst")
scalars.load(f"{SAMPLE_DATA_DIR}/fun.scl")
tables.load(f"{SAMPLE_DATA_DIR}/fun.tbl")
variables.load(f"{SAMPLE_DATA_DIR}/fun.var")
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.cmt
317 objects loaded
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.eqs
274 objects loaded
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.idt
48 objects loaded
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.lst
17 objects loaded
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.scl
161 objects loaded
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.tbl
46 objects loaded
Loading C:\soft\Miniconda3\Lib\site-packages\iode\tests\data/fun.var
394 objects loaded

Example for one equation:

[655]:
# ---- estimate coefficients of one equation ----
print(f"ACAF equation LEC: {equations['ACAF'].lec}")
print(f"ACAF equations coefficients (= scalars): {equations['ACAF'].coefficients}")
print(f"ACAF equations variables: {equations['ACAF'].variables}")

# copy the original values of the coefficients into an isolated scalars workspace
# Useful to restore the original values if the estimation process didn't go well
scalars_copy = scalars[equations['ACAF'].coefficients].copy()
print(f"scalars names in scalars_copy: {scalars_copy.names}")

# reset scalars
for name in equations['ACAF'].coefficients:
    scalars[name] = 0., 1.

# estimate the 'ACAF' equation for the periods ranging from '1980Y1' to '1996Y1'
success = equations.estimate("1980Y1", "1996Y1", "ACAF")
# or equivalently
success = equations["ACAF"].estimate("1980Y1", "1996Y1")
print(f"Equation estimation success: {success}")

print(f"Resulting values for the coefficient 'acaf1': {scalars['acaf1']}")
print(f"Resulting values for the coefficient 'acaf2': {scalars['acaf2']}")
print(f"Resulting values for the coefficient 'acaf4': {scalars['acaf4']}")
ACAF equation LEC: (ACAF/VAF[-1]) :=acaf1+acaf2*GOSF[-1]+
acaf4*(TIME=1995)
ACAF equations coefficients (= scalars): ['acaf1', 'acaf2', 'acaf4']
ACAF equations variables: ['ACAF', 'VAF', 'GOSF', 'TIME']
scalars names in scalars_copy: ['acaf1', 'acaf2', 'acaf4']
Estimating : iteration 1 (||eps|| = 0.173205)

Estimating : iteration 2 (||eps|| = 5.16075e-09)

Solution reached after 2 iteration(s). Creating results file ...

Estimating : iteration 1 (||eps|| = 7.05003e-13)

Solution reached after 1 iteration(s). Creating results file ...

Equation estimation success: True
Resulting values for the coefficient 'acaf1': Scalar(0.0157705, 1, 0.00136949)
Resulting values for the coefficient 'acaf2': Scalar(-7.96505e-06, 1, 1.48247e-06)
Resulting values for the coefficient 'acaf4': Scalar(-0.0085027, 1, 0.00208257)

Example for a block of equations:

[656]:
# ---- estimate a block of equations ----
print(f"ACAF equation LEC: {equations['ACAF'].lec}")
print(f"ACAF equations coefficients (= scalars): {equations['ACAF'].coefficients}")
print(f"ACAF equations variables: {equations['ACAF'].variables}")
print(f"DPUH equation LEC: {equations['DPUH'].lec}")
print(f"DPUH equations coefficients (= scalars): {equations['DPUH'].coefficients}")
print(f"DPUH equations variables: {equations['DPUH'].variables}")

# copy the original values of the coefficients into an isolated scalars workspace
# Useful to restore the original values if the estimation process didn't go well
scalars_names = equations['ACAF'].coefficients + equations['DPUH'].coefficients
scalars_names = list(set(scalars_names))   # removed duplicates
scalars_copy = scalars[scalars_names].copy()
print(f"scalars names in scalars_copy: {scalars_copy.names}")

# reset scalars
for name in equations['ACAF'].coefficients:
    scalars[name] = 0., 1.
for name in equations['DPUH'].coefficients:
    scalars[name] = 0., 1.

# prepare equations (same block and method)
block = "ACAF;DPUH"
for name in block.split(";"):
    equations[name] = {"block": block, "method": "LSQ"}

# estimation the block 'ACAF;DPUH' for the periods ranging from '1980Y1' to '1996Y1'
success = equations.estimate("1980Y1", "1996Y1", block)
print(f"Block estimation success: {success}")

print(f"Resulting values for the coefficient 'acaf1': {scalars['acaf1']}")
print(f"Resulting values for the coefficient 'acaf2': {scalars['acaf2']}")
print(f"Resulting values for the coefficient 'acaf4': {scalars['acaf4']}")
print(f"Resulting values for the coefficient 'dpuh_1': {scalars['dpuh_1']}")
print(f"Resulting values for the coefficient 'dpuh_2': {scalars['dpuh_2']}")
ACAF equation LEC: (ACAF/VAF[-1]) :=acaf1+acaf2*GOSF[-1]+
acaf4*(TIME=1995)
ACAF equations coefficients (= scalars): ['acaf1', 'acaf2', 'acaf4']
ACAF equations variables: ['ACAF', 'VAF', 'GOSF', 'TIME']
DPUH equation LEC: dln (DPUH/DPUHO):=dpuh_1+dpuh_2*dln(IHU/PI5)+dln PC
DPUH equations coefficients (= scalars): ['dpuh_1', 'dpuh_2']
DPUH equations variables: ['DPUH', 'DPUHO', 'IHU', 'PI5', 'PC']
scalars names in scalars_copy: ['acaf1', 'acaf2', 'acaf4', 'dpuh_1', 'dpuh_2']
Estimating : iteration 1 (||eps|| = 0.223607)

Estimating : iteration 2 (||eps|| = 5.16075e-09)

Solution reached after 2 iteration(s). Creating results file ...

Estimating : iteration 1 (||eps|| = 4.38565e-12)

Solution reached after 1 iteration(s). Creating results file ...

Block estimation success: True
Resulting values for the coefficient 'acaf1': Scalar(0.0157705, 1, 0.00136079)
Resulting values for the coefficient 'acaf2': Scalar(-7.96505e-06, 1, 1.47188e-06)
Resulting values for the coefficient 'acaf4': Scalar(-0.0085027, 1, 0.00206603)
Resulting values for the coefficient 'dpuh_1': Scalar(0.0109855, 1, 0.00481857)
Resulting values for the coefficient 'dpuh_2': Scalar(0.0574893, 1, 0.0368951)

Simulation

To simulate a model, you must create and initialize an instance of the Simulation class.

Models

IN IODE, a model is simply a list of equations. No other construction is necessary: in this way, to modify a model, the only thing to do is to modify the list that defines it. For example, if a model is logically divided into 5 blocks, 5 lists of equations will be defined:

BLOC1 : A, B, C, D
BLOC2 : X, Y
BLOC3 : C1, C2, C3, C4
BLOC4 : X_A1, X_A2, X_A3
BLOC5 : R1, R2, R3, S_12
MODSIM : $BLOC1, $BLOC2, $BLOC3, $BLOC4, $BLOC5

To simulate a model, all equations of the model must have been loaded or created. In addition, all the variables and scalars used in the model equations must have been loaded or created. Values of exogenous variables and of scalar cannot be NA (Not Available) over the simulation periods.

Exchange Endo-Exo

It is possible to set endogenous-exogenous pairs for goal seeking. For each pair, the status of the variables is exchanged: endogenous becomes exogenous and vice versa. This enables the model to be run through known endogenous values and to deduce the necessary values for the associated exogenous variables. The exogenous variables take on the value calculated over the entire workspace period. See the documentation of the model_exchange method.

Newton-Raphson Algorithm

When an equation is not explicitly defined in terms of its endogen, or when the endogen appears several times in the equation, the simulation algorithm tries to solve the equation using a Newton method. If this method fails, a secant method is used to find a solution to the equation. However, there is no guarantee that a solution will be found in every case. Non-continuous functions (singularities) such as:

\[X = a + \frac{b}{X + 1}\]

may be impossible to solve around their singular point. For this type of problem, the only solution is to modify the form of the equation:

\[(X - a) * (X + 1) = b\]

Warning:

  1. As the endogenous variable of an equation carries the name of the equation, it is not possible to place in a model two equations with the same endogenous variable.

  2. The order in which equations are introduced in the lists can influence the behavior of the simulation algorithm. As this is a Gauss-Seidel algorithm, the information calculated is used directly in the rest of the calculation. If X depends on Y, it’s better to place Y before X in the list of equations.

Examples

[657]:
from iode import SimulationSort

print(f"possible sort algorithms: {[member.name for member in SimulationSort]}")
possible sort algorithms: ['CONNEX', 'BOTH', 'NONE']
[658]:
from iode import SimulationInitialization

print(f"possible initialization methods: {[member.name for member in SimulationInitialization]}")
possible initialization methods: ['TM1', 'TM1_A', 'EXTRA', 'EXTRA_A', 'ASIS', 'TM1_NA', 'EXTRA_NA']
[659]:
from iode import Simulation

# create and initialize a Simulation instance
simu = Simulation(sort_algorithm=SimulationSort.BOTH, initialization_method=SimulationInitialization.TM1)
print(simu)
--- Simulation ---
convergence_threshold = 0.001
relax = 1.0
max_nb_iterations = 100
sort_algorithm = BOTH (Connex compon. + Triangulation)
initialization_method = TM1 (Y := Y[-1], if Y null or NA)
debug = False
nb_passes = 5
debug_newton = False
------------------

To run the simulation, call the Simulation.model_simulate method:

[660]:
print(f"exogenous variable 'UY': {equations['UY'].lec}")
print(f"endogenous variable 'XNATY': {identities['XNATY']}")
# reset values of exogenous variable
variables["UY", "2000Y1:2015Y1"] = 0.0

print(f"exogenous variable 'UY' before simulation:\n{variables['UY', '1998Y1:2005Y1']}")

# run the simulation for the periods range '2000Y1' to '2015Y1'
success = simu.model_simulate("2000Y1", "2015Y1", quiet=True)
print(f"Simulation success: {success}")

print(f"exogenous variable 'UY' after simulation:\n{variables['UY', '1998Y1:2005Y1']}")
exogenous variable 'UY': UY := NATY-NDOMY-NIY-NGY-(EFXY-EFMY)-NFY
endogenous variable 'XNATY': grt NATY
exogenous variable 'UY' before simulation:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1998Y1:2005Y1
mode: LEVEL

name    1998Y1  1999Y1  2000Y1  2001Y1  2002Y1  2003Y1  2004Y1  2005Y1
UY      671.46  647.39    0.00    0.00    0.00    0.00    0.00    0.00

Simulation success: True
exogenous variable 'UY' after simulation:
Workspace: Variables
nb variables: 1
filename: c:\soft\Miniconda3\Lib\site-packages\iode\tests\data\fun.var
description: Modèle fun - Simulation 1
sample: 1998Y1:2005Y1
mode: LEVEL

name    1998Y1  1999Y1  2000Y1  2001Y1  2002Y1  2003Y1  2004Y1  2005Y1
UY      671.46  647.39  624.18  645.05  661.61  676.56  680.90  682.99

Import/Export IODE workspaces from/to pandas Series and DataFrame

To import / export the content of the comments, identities and lists workspaces from/to a pandas Series object, use the from_series() and to_series() methods.

Alternatively, you can use the series property to export the content of the comments, identities and lists workspaces to a pandas Series object.

For the examples, see the pandas tutorial.

Import/Export IODE Variables workspace from/to numpy ndarray

To import / export the content of the Variables workspace (or a subset of it) from/to a numpy ndarray object, use the from_numpy and to_numpy methods.

For the examples, see the numpy tutorial.

Import/Export the Variables workspace from/to LArray Array

To import / export the content of the variables workspaces from/to an LArray Array object, use the from_array() and to_array() methods.

For the examples, see the larray tutorial.

Execute IODE report commands/files

To run an IODE command, use the execute_command() function:

[661]:
from iode import execute_command

# ---- execute IODE commands ----
print("Execute IODE commands (useful for IODE functions and commands not yet ported to Python):")
execute_command("$WsClearVar")
execute_command("$WsSample 2000Y1 2005Y1")
execute_command("$DataCalcVar A t+1")
execute_command("$DataCalcVar B t-1")
execute_command("$DataCalcVar C A/B")
execute_command("$DataCalcVar D grt A")
execute_command("$WsSaveVar test_var.av")
with open("test_var.av", "r") as f:
    print(f.read())
Execute IODE commands (useful for IODE functions and commands not yet ported to Python):
Saving test_var.av
sample 2000Y1 2005Y1
A 1 2 3 4 5 6
B -1 0 1 2 3 4
C -1 na 3 2 1.66666666666667 1.5
D na 100 50 33.3333333333333 25 20

To run an entire IODE report (i.e. file with the ‘.rep’ extension), call the execute_report() function:

[662]:
from iode import execute_report

# ---- execute IODE reports ----
print("Execute an IODE report -> execute_report()")
with open("create_var.rep", "w") as f:
    f.write("$WsClearVar\n")
    f.write("$WsSample 2000Y1 2005Y1\n")
    f.write("$DataCalcVar %1% t+1 \n")
    f.write("$DataCalcVar %2% t-1 \n")
    f.write("$DataCalcVar %3% %1%/%2%\n")
    f.write("$DataCalcVar %4% grt %1% \n")
    f.write("$WsSaveVar test_var.av\n")

execute_report("create_var.rep", ["A", "B", "C", "D"])

with open("test_var.av", "r") as f:
    print(f.read())

Execute an IODE report -> execute_report()
Saving test_var.av
sample 2000Y1 2005Y1
A 1 2 3 4 5 6
B -1 0 1 2 3 4
C -1 na 3 2 1.66666666666667 1.5
D na 100 50 33.3333333333333 25 20

Graphical User Interface

It is possible to run the graphical user interface to view the content of the IODE workspace from any line of a Python script. Simply call the function view_workspace() to open the GUI.

Content of a Python script:

from iode import view_workspace, ...

... code here ...

# To view the workspace, you can use the following command:
view_workspace()

# To open the graphical user interface showing the files
# from a specific directory, pass the path to the directory
# as an argument:
view_workspace("path/to/your/directory")

... code here ...