{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Getting Started\n", "\n", "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.\n", "To get a more detailed presentation of all capabilities of `iode`, read the next sections of the tutorial.\n", "\n", "The [Installation](../install.rst#installation) section describes how to install the `iode` library and the `iode-gui` graphical user interface and their dependencies.\n", "\n", "The [Introduction](../introduction.rst#introduction) section gives a brief overview of the concepts of the `IODE` tool.\n", " \n", "The [The LEC Language](../lec_language.rst#the-lec-language) section describes the *LEC* language (\"*Langage Econométrique Condensé*\"), which is the scripting language used in the `IODE` tool to define *equations*, *identities* or any mathematical expressions to be evaluated.\n", "\n", "The [API Reference](../api.rst#api-reference) section of the documentation give you the list of all objects, methods and functions with their individual documentation and examples.\n", "\n", "The [Equivalence IODE Report Commands and IODE Python](../equivalence.rst#equivalence-iode-report-commands-and-iode-python) section contains *equivalence tables* between the IODE report syntax and the Python `iode` syntax." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To use the Python `iode` library, the first thing to do is to import objects and functions you need from it:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", "import larray as la\n", "\n", "from iode import SAMPLE_DATA_DIR, NA" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To know the version of the `iode` library installed on your machine, type:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'7.0.6'" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from iode import __version__\n", "__version__" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To print the documentation of an object, method or function in a Python interactive console, use the `help()` function:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Help on method load in module iode.iode_database.abstract_database:\n", "\n", "load(filepath: str) method of iode.iode_database.equations_database.Equations instance\n", " Load objects stored in file 'filepath' into the current database.\n", " Erase the database before to load the file.\n", "\n", " Parameters\n", " ----------\n", " filepath: str\n", " path to the file to load\n", "\n", " Examples\n", " --------\n", " >>> from iode import comments, equations, identities, lists, tables, scalars, variables\n", " >>> from iode import SAMPLE_DATA_DIR\n", " >>> comments.load(f\"{SAMPLE_DATA_DIR}/fun.cmt\") # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE\n", " Loading .../fun.cmt\n", " 317 objects loaded\n", "\n", " >>> equations.load(f\"{SAMPLE_DATA_DIR}/fun.eqs\") # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE\n", " Loading .../fun.eqs\n", " 274 objects loaded\n", "\n", " >>> identities.load(f\"{SAMPLE_DATA_DIR}/fun.idt\") # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE\n", " Loading .../fun.idt\n", " 48 objects loaded\n", "\n", " >>> lists.load(f\"{SAMPLE_DATA_DIR}/fun.lst\") # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE\n", " Loading .../fun.lst\n", " 17 objects loaded\n", "\n", " >>> tables.load(f\"{SAMPLE_DATA_DIR}/fun.tbl\") # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE\n", " Loading .../fun.tbl\n", " 46 objects loaded\n", "\n", " >>> scalars.load(f\"{SAMPLE_DATA_DIR}/fun.scl\") # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE\n", " Loading .../fun.scl\n", " 161 objects loaded\n", "\n", " >>> variables.load(f\"{SAMPLE_DATA_DIR}/fun.var\") # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE\n", " Loading .../fun.var\n", " 394 objects loaded\n", "\n" ] } ], "source": [ "from iode import equations\n", "\n", "# ---- print documentation of a function or method ----\n", "help(equations.load)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## IODE Objects\n", "\n", "A model is a system of *equations*, which are formulas involving *variables*, numerical time series defined over a given period, with a specific frequency (annual, quarterly, etc.). \n", "The *equations* may contain coefficients (possibly estimated) which are dimensionless *variables*, called *Scalars*.\n", "\n", "The *variables* themselves are not always obtained as such, but most often result from calculations based on other *variables*, possibly coming from several sources. These calculations can be, for example, sector aggregation or a geographic dimension. The formulas used to generate those *variables* are called *identities*.\n", "\n", "The name given to each *variable* generally does not allow its content to be indicated with sufficient precision. IODE allows the creation of *comments* whose name will be identical to that of the *variables* they define. These *comments* are simply free text.\n", "\n", "When *variables* are available, it is often useful to present them in the form of tables or charts. \n", "IODE allows the construction of special *tables* for this purpose. Those *tables* do not contain numerical values, but formulas and text. Then, these can be \"*computed*\" so as to obtain numerical tables (called *computed tables*) or charts. This approach is very efficient: the same table can be reused to print different versions of the *variables* (after simulating a scenario, for example). These *tables* can also be used to compare different scenarios or variants of a model by loading different files containing the same *variables*.\n", "\n", "There is no notion of a model as an object in IODE: a model is simply a *list* of equations. \n", "To avoid the tedious work of re-encoding *lists*, these are managed as standalone objects and saved in list files. *Lists* are also used in formulas to shorten writing, or passed as parameters to *IODE functions*, etc.\n", "\n", "Each object of one of the seven types is identified by a name of up to 20 characters. They always start with a letter or an underscore '_'. Their names are written in lowercase for *scalars* and in uppercase for other objects (so as to distinguish *scalars* and *variables* in *LEC* formulas)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Comment\n", "\n", "IODE *Comments* are free text. They are used to document other IODE objects." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Enterprises: received capital transfers'" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cmt_ACAF = \"Enterprises: received capital transfers\"\n", "cmt_ACAF" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Equation\n", "\n", "An *equation* represents an equality mixing *variables* and *scalars* (coefficients) and is part of a model. \n", "Each equation is composed of the following elements:\n", "\n", "- the *LEC* form (the formula scripting language in IODE)\n", "- a free comment (title of the Table)\n", "- the method by which it was estimated (if applicable)\n", "- the possible estimation period\n", "- the names of equations estimated simultaneously (block)\n", "- the instruments used for the estimation\n", "\n", "All these definition elements are present in each equation, but may be left empty if not applicable.\n", "\n", "The name of an equation is that of its endogenous variable. An equation can never be renamed, \n", "but it can be deleted and redefined with a new name.\n", "\n", "To create an equation, you can use the constructor method of the [Equation](../_generated/iode.Equation.rst#iode.Equation) class:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "nbsphinx": "hidden" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.cmt\n", "317 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.eqs\n", "274 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.idt\n", "48 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.lst\n", "17 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.scl\n", "161 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.tbl\n", "46 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.var\n", "394 objects loaded\n" ] } ], "source": [ "# ---- hidden cell -> required to run the estimation of the equation below ----\n", "from iode import comments, equations, identities, lists, scalars, tables, variables\n", "\n", "comments.load(f\"{SAMPLE_DATA_DIR}/fun.cmt\")\n", "equations.load(f\"{SAMPLE_DATA_DIR}/fun.eqs\")\n", "identities.load(f\"{SAMPLE_DATA_DIR}/fun.idt\")\n", "lists.load(f\"{SAMPLE_DATA_DIR}/fun.lst\")\n", "scalars.load(f\"{SAMPLE_DATA_DIR}/fun.scl\")\n", "tables.load(f\"{SAMPLE_DATA_DIR}/fun.tbl\")\n", "variables.load(f\"{SAMPLE_DATA_DIR}/fun.var\")" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Equation(endogenous = 'ACAF',\n", " lec = '(ACAF / VAF[-1]) := acaf1 + acaf2 * GOSF[-1] + acaf4 * (TIME=1995)',\n", " method = 'LSQ',\n", " from_period = '1960Y1',\n", " to_period = '2015Y1')" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from iode import Equation, variables\n", "# initialize the sample (range of periods) of the 'variables' workspace\n", "variables.sample = \"1960Y1:2015Y1\"\n", "# create a new equation\n", "eq_ACAF = Equation(\"ACAF\", \"(ACAF / VAF[-1]) := acaf1 + acaf2 * GOSF[-1] + acaf4 * (TIME=1995)\")\n", "eq_ACAF" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To access and modify the elements of an equation, you can use the following attributes:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'ACAF'" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# endogenous variables of the equation \n", "# (= equation's name)\n", "eq_ACAF.endogenous" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "**Warning**: the *endogenous* variable of an equation is the name of the equation itself and cannot be changed:\n", "\n", "
" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Error: property 'endogenous' of 'Equation' object has no setter\n" ] } ], "source": [ "try:\n", " eq_ACAF.endogenous = \"ACAF_\"\n", "except AttributeError as e:\n", " print(f\"Error: {e}\")" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'(ACAF / VAF[-1]) := acaf1 + acaf2 * GOSF[-1] + acaf4 * (TIME=1995)'" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# LEC form of the equation\n", "eq_ACAF.lec" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'ACAF / VAF[-1] := acaf1 + acaf2 * GOSF[-1] + acaf4 * (TIME=1995)'" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eq_ACAF.lec = \"ACAF / VAF[-1] := acaf1 + acaf2 * GOSF[-1] + acaf4 * (TIME=1995)\"\n", "eq_ACAF.lec" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'LSQ'" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# estimation method of the equation\n", "eq_ACAF.method" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'MAX_LIKELIHOOD'" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from iode import EqMethod\n", "eq_ACAF.method = EqMethod.MAX_LIKELIHOOD\n", "eq_ACAF.method" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Sample(\"1960Y1:2015Y1\")" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# range of periods for which the equation is estimated\n", "# By default, it is the sample of the 'variables' workspace\n", "eq_ACAF.sample" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Sample(\"1980Y1:1996Y1\")" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eq_ACAF.sample = \"1980Y1:1996Y1\"\n", "eq_ACAF.sample" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "''" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# block of equations to which the equation belongs\n", "# A block of equations is a group of equations that are estimated together\n", "eq_ACAF.block" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'ACAF;DPUH'" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eq_ACAF.block = \"ACAF;DPUH\"\n", "eq_ACAF.block" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "''" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# comment associated with the equation\n", "eq_ACAF.comment" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Enterprises: received capital transfers'" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eq_ACAF.comment = cmt_ACAF\n", "eq_ACAF.comment" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "''" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# instruments associated with the equation\n", "eq_ACAF.instruments" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['GOSF', 'VAF']" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eq_ACAF.instruments = [\"GOSF\", \"VAF\"]\n", "eq_ACAF.instruments" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'corr': 0.0,\n", " 'dw': 0.0,\n", " 'fstat': 0.0,\n", " 'loglik': 0.0,\n", " 'meany': 0.0,\n", " 'r2': 0.0,\n", " 'r2adj': 0.0,\n", " 'ssres': 0.0,\n", " 'stderr': 0.0,\n", " 'stderrp': 0.0,\n", " 'stdev': 0.0}" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# tests evaluated during the estimation of the equation\n", "eq_ACAF.tests" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "**Warning**: the *tests* associated with an equation are set during the estimation process and cannot be modified manually.\n", "\n", "
" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Error: property 'tests' of 'Equation' object has no setter\n" ] } ], "source": [ "try:\n", " eq_ACAF.tests = [1.0, 2.32935, 32.2732, 83.8075, 0.00818467, 0.821761, 0.796299,\n", " 5.19945e-05, 0.00192715, 23.5458, 0.0042699]\n", "except AttributeError as e:\n", " print(f\"Error: {e}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "**Warning**: in the same way, the *date* attribute of an equation is updated during the estimation process and cannot be modified manually.\n", "\n", "
" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "''" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# last date of estimation of the equation\n", "eq_ACAF.date" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Error: property 'date' of 'Equation' object has no setter\n" ] } ], "source": [ "try:\n", " eq_ACAF.date = \"04-06-2025\"\n", "except AttributeError as e:\n", " print(f\"Error: {e}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To get the list of *scalars* (*coefficients*) and *variables* referenced in an Equation, use the [coefficients](../_generated/iode.Equation.coefficients.rst#iode.Equation.coefficients) and [variables](../_generated/iode.Equation.variables.rst#iode.Equation.variables) properties of the [Equation](../_generated/iode.Equation.rst#iode.Equation) class:" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['acaf1', 'acaf2', 'acaf4']" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eq_ACAF.coefficients" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['ACAF', 'VAF', 'GOSF', 'TIME']" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eq_ACAF.variables" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To split an equation into its left-hand side and its right-hand side, use the [split_equation](../_generated/iode.Equation.split_equation.rst#iode.Equation.split_equation) method of the [Equation](../_generated/iode.Equation.rst#iode.Equation) class:" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "left-hand side: ACAF / VAF[-1]\n", "right-hand side: acaf1 + acaf2 * GOSF[-1] + acaf4 * (TIME=1995)\n" ] } ], "source": [ "left, right = eq_ACAF.split_equation()\n", "print(\"left-hand side: \", left)\n", "print(\"right-hand side:\", right)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To estimate the an equation, use the [estimate](../_generated/iode.Equation.estimate.rst#iode.Equation.estimate) method of the [Equation](../_generated/iode.Equation.rst#iode.Equation) class.\n", "\n", "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.\n", "\n", "The tests resulting from the last estimation are saved as scalars. \n", "The same applies to residuals, left-hand and right-hand members of equations.\n", "\n", "Saved tests (as scalars) have the following names:\n", "\n", "- `e0_n` : number of sample periods \n", "- `e0_k` : number of estimated coefficients \n", "- `e0_stdev` : std dev of residuals \n", "- `e0_meany` : mean of Y \n", "- `e0_ssres` : sum of squares of residuals \n", "- `e0_stderr` : std error \n", "- `e0_stderrp` : std error percent (in %) \n", "- `e0_fstat` : F-Stat \n", "- `e0_r2` : R square \n", "- `e0_r2adj` : adjusted R-squared \n", "- `e0_dw` : Durbin-Watson \n", "- `e0_loglik` : Log Likelihood\n", "\n", "Calculated series are saved in special variables:\n", "\n", "- `_YCALC0` : right-hand side of the equation\n", "- `_YOBS0` : left-hand side of the equation\n", "- `_YRES0` : residuals of the equation\n", "\n", "Outside the estimation sample, the series values are `NA` (Not Available):" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Estimating : iteration 1 (||eps|| = 0.0566493)\n", "Estimating : iteration 2 (||eps|| = 0.0594508)\n", "Estimating : iteration 3 (||eps|| = 0.0117815)\n", "Estimating : iteration 4 (||eps|| = 0.00240163)\n", "Estimating : iteration 5 (||eps|| = 0.000492758)\n", "Estimating : iteration 6 (||eps|| = 0.000101281)\n", "Estimating : iteration 7 (||eps|| = 2.08105e-05)\n", "Estimating : iteration 8 (||eps|| = 4.27624e-06)\n", "Estimating : iteration 9 (||eps|| = 8.78712e-07)\n", "Solution reached after 9 iteration(s). Creating results file ...\n" ] }, { "data": { "text/plain": [ "True" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "success = eq_ACAF.estimate(\"1980Y1\", \"2000Y1\")\n", "success" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{'corr': 1.0,\n", " 'dw': 1.8939709663391113,\n", " 'fstat': 34.6290397644043,\n", " 'loglik': 158.13970947265625,\n", " 'meany': 0.007528899237513542,\n", " 'r2': 0.7937153577804565,\n", " 'r2adj': 0.7707948684692383,\n", " 'ssres': 7.38456001272425e-05,\n", " 'stderr': 0.002025471068918705,\n", " 'stderrp': 26.902618408203125,\n", " 'stdev': 0.004230715800076723}" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eq_ACAF.tests" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'19-03-2026'" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eq_ACAF.date" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Identity\n", "\n", "An *identity* is an expression written in the *LEC* language that allows the construction of a \n", "new statistical series based on already defined series. In general, *identities* are executed\n", "in groups to create or update a set of *variables*. *Identities* can be executed for a specific \n", "range of periods, or for all periods defined in the workspace.\n", "\n", "*Identities* should not be confused with *equations*. They are not part of a model.\n", "\n", "To create an *identity*, you can use the constructor method of the [Identity](../_generated/iode.Identity.rst#iode.Identity) class:" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Identity('1 - exp((gamma2 + gamma3 * ln(W/ZJ)[-1] + gamma4 * ln(WMIN/ZJ)) / gamma_)')" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from iode import Identity\n", "idt = Identity(\"1 - exp((gamma2 + gamma3 * ln(W/ZJ)[-1] + gamma4 * ln(WMIN/ZJ)) / gamma_)\")\n", "idt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To get the list of *scalars* (*coefficients*) and *variables* referenced in an identity, use the [coefficients](../_generated/iode.Identity.coefficients.rst#iode.Identity.coefficients) and [variables](../_generated/iode.Identity.variables.rst#iode.Identity.variables) properties of the [Identity](../_generated/iode.Identity.rst#iode.Identity) class:" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['gamma2', 'gamma3', 'gamma4', 'gamma_']" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "idt.coefficients" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['W', 'ZJ', 'WMIN']" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "idt.variables" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### List\n", "\n", "IODE *Lists* are either free text (like IODE *comments*) or a Python list. \n", "They are used to simplify writing in various circumstances:\n", "\n", "- list of equations defining a model\n", "- list of tables to print\n", "- any argument of a function (such as print period)\n", "- macro in an equation, identity, or table\n", "- etc." ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['ACAF', 'ACAG', 'AOUC', 'AOUC_', 'AQC']" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "A_VARS = [\"ACAF\", \"ACAG\", \"AOUC\", \"AOUC_\", \"AQC\"]\n", "A_VARS" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Scalar\n", "\n", "*Scalars* are essentially estimated coefficients of econometric *equations*. \n", "For this reason, each scalar contains in its definition:\n", "\n", "- its *value*\n", "- the *relaxation* parameter, set to 0 to lock the coefficient during estimation\n", "- its *standard deviation*, result of the last estimation\n", "\n", "Only the *values* of the *scalars* are relevant when calculating a *LEC* expression. \n", "The other two values (relaxation and standard deviation) are only meaningful for estimation.\n", "\n", "The names of *scalars* must be in lowercase so that *variables* are distinct from *scalars* in *LEC* formulas.\n", "\n", "To create a *scalar*, you can use the constructor method of the [Scalar](../_generated/iode.Scalar.rst#iode.Scalar) class:\n" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Scalar(0.9, 1, na)" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import numpy as np\n", "from iode import Scalar\n", "\n", "# default relax\n", "scalar = Scalar(0.9)\n", "scalar" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Scalar(0.9, 0.8, na)" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# specific value and relax\n", "scalar = Scalar(0.9, 0.8)\n", "scalar" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Scalar(na, 1, na)" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# Python nan are converted to IODE NA\n", "scalar = Scalar(np.nan)\n", "scalar" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Error: Expected 'value' to be a finite number\n" ] } ], "source": [ "# Python inf are not accepted\n", "try:\n", " scalar = Scalar(np.inf)\n", "except ValueError as e:\n", " print(f\"Error: {e}\")" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Error: Expected 'relax' value between 0.0 and 1.0\n" ] } ], "source": [ "# relax must be between 0.0 and 1.0\n", "try:\n", " scalar = Scalar(0.9, 1.1)\n", "except ValueError as e:\n", " print(f\"Error: {e}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To access and modify the *value* and *relax* of a *scalar*, use the following attributes:" ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "nan" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "scalar.value" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.95" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "scalar.value = 0.95\n", "scalar.value" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.0" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "scalar.relax" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.85" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "scalar.relax = 0.85\n", "scalar.relax" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To access *standard deviation* of a *scalar*, use the *std* attribute:" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "nan" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "scalar.std" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "**Warning**: the *standard deviation* of a *scalar* is set during the estimation process and cannot be modified manually.\n", "\n", "
" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Error: property 'std' of 'Scalar' object has no setter\n" ] } ], "source": [ "try:\n", " scalar.std = 0.001369\n", "except AttributeError as e:\n", " print(f\"Error: {e}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Table\n", "\n", "One of the most frequently performed operations during a simulation exercise is the display of tables of results and charts. \n", "\n", "Each IODE *table* is a set of lines. A line is composed of two parts (in general):\n", "\n", "- a *text* part, which will be the title of the line\n", "- a *formula* part, which will allow the calculation of the numerical values to be placed in the *computed table*:\n", "\n", ">\n", "> TABLE TITLE \n", "> \n", "> Gross National Product GNP \n", "> Unemployment UL \n", "> External Balance X-I\n", ">\n", "\n", "The lines are actually of several types: \n", "\n", "- *TITLE* lines (centered on the page width), \n", "- *CELL* lines (title + formula), \n", "- *SEPARATOR* lines\n", "- *MODE* lines\n", "- *FILES* lines\n", "- *DATE* lines\n", "\n", "A table is designed to be \"*computed*\" over different periods, described by a \"*generalized sample*\" \n", "such as:\n", "\n", ">\n", "> 1980Y1:10 --> 10 observations from 1980Y1\n", "> 1980Y1, 1985Y1, 1990:5 --> 1980, 1985, then 5 observations from 1990Y1\n", "> 80/79:5 --> 5 growth rates from 1980\n", "> ...\n", ">\n", "\n", "It can also contain values from different files:\n", "\n", ">\n", "> (1990:5)[1,2,1-2] --> values from 1990 to 1994 for files\n", "> 1, 2, and for the difference between the two files.\n", ">\n", "\n", "The *computed table* can be:\n", "\n", "- displayed on screen\n", "- printed\n", "- exported as a chart\n", "- exported to a file (in CSV, HTML, ...)\n", "- (Python) converted to a Pandas DataFrame or an larray Array\n", "\n", "*Tables* can very well be used in a project that does not include an econometric model: \n", "the only information used by tables are *variables* and possibly *scalars*." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Create A Table\n", "\n", "To create an IODE table, you can either: \n", "\n", "1. Call the [Table](../_generated/iode.Table.rst#iode.Table) constructor without any argument. This will create an empty table with two columns. Then you can add lines using the [+= operator](../_generated/iode.Table.__iadd__.rst) or the [insert()](../_generated/iode.Table.insert.rst#iode.Table.insert) method (see next section)." ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DIVIS | 1 | \n", "TITLE | \n", "----- | --------\n", "CELL | | \"#S\"\n", "----- | --------\n", "\n", "nb lines: 4\n", "nb columns: 2\n", "language: 'ENGLISH'\n", "gridx: 'MAJOR'\n", "gridy: 'MAJOR'\n", "graph_axis: 'VALUES'\n", "graph_alignment: 'LEFT'" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from iode import Table\n", "\n", "# empty table\n", "table = Table()\n", "table" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "2. Call the [Table](../_generated/iode.Table.rst#iode.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*):" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['EX',\n", " 'PWMAB',\n", " 'PWMS',\n", " 'PWXAB',\n", " 'PWXS',\n", " 'QWXAB',\n", " 'QWXS',\n", " 'POIL',\n", " 'NATY',\n", " 'TFPFHP_']" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# content of the IODE list 'ENVI'\n", "lists[\"ENVI\"]" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DIVIS | 1 | \n", "TITLE | \"Table example with variables only\" \n", "----- | ------------------------------------------------------------------------------\n", "CELL | | \"#S\" \n", "----- | ------------------------------------------------------------------------------\n", "CELL | \"Bruto exploitatie-overschot: overheid (= afschrijvingen).\" | GOSG\n", "CELL | \"Overheid: geïnde indirecte belastingen.\" | YDTG\n", "CELL | \"Totale overheid: directe belasting van de gezinnen.\" | DTH\n", "CELL | \"Totale overheid: directe vennootschapsbelasting.\" | DTF\n", "CELL | \"Totale indirecte belastingen.\" | IT\n", "CELL | \"Globale overheid: ontvangen sociale zekerheidsbijdragen.\" | YSSG\n", "CELL | \"Cotisation de responsabilisation.\" | COTRES\n", "CELL | \"Overheid: inkomen uit vermogen.\" | RIDG\n", "CELL | \"Globale overheid: saldo van de ontvangen lopendeoverdrachten.\" | OCUG\n", "CELL | \"Wisselkoers van de USD t.o.v. de BEF (jaargemiddelde).\" | EX\n", "CELL | \"Index wereldprijs - invoer van niet-energieprodukten, inUSD.\" | PWMAB\n", "CELL | \"Index wereldprijs - invoer van diensten, in USD.\" | PWMS\n", "CELL | \"Index wereldprijs - uitvoer van niet-energieprodukten, inUSD.\" | PWXAB\n", "CELL | \"Index wereldprijs - uitvoer van diensten, in USD.\" | PWXS\n", "CELL | \"Indicator van het volume van de wereldvraag naar goederen,1985=1.\" | QWXAB\n", "CELL | \"Indicator van het volume van de wereldvraag naar diensten,1985=1.\" | QWXS\n", "CELL | \"Brent olieprijs (USD per barrel).\" | POIL\n", "CELL | \"Totale beroepsbevolking (jaargemiddelde).\" | NATY\n", "CELL | \"TFPFHP_\" | TFPFHP_\n", "----- | ------------------------------------------------------------------------------\n", "MODE | \n", "FILES | \n", "DATE | \n", "\n", "nb lines: 27\n", "nb columns: 2\n", "language: 'ENGLISH'\n", "gridx: 'MAJOR'\n", "gridy: 'MAJOR'\n", "graph_axis: 'VALUES'\n", "graph_alignment: 'LEFT'" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# create a table using a list of variables\n", "# NOTE: the list of variables can contain IODE list(s). \n", "# The IODE list(s) must be referenced using the '$' symbol\n", "table_title = \"Table example with variables only\"\n", "lines_vars = [\"GOSG\", \"YDTG\", \"DTH\", \"DTF\", \"IT\", \"YSSG\", \"COTRES\", \"RIDG\", \"OCUG\", \"$ENVI\"]\n", "table = Table(2, table_title, lines_vars, mode=True, files=True, date=True)\n", "table" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DIVIS | 1 | \n", "TITLE | \"Table example with all variables passed as a single string\" \n", "----- | ------------------------------------------------------------------------------\n", "CELL | | \"#S\" \n", "----- | ------------------------------------------------------------------------------\n", "CELL | \"Bruto exploitatie-overschot: overheid (= afschrijvingen).\" | GOSG\n", "CELL | \"Overheid: geïnde indirecte belastingen.\" | YDTG\n", "CELL | \"Totale overheid: directe belasting van de gezinnen.\" | DTH\n", "CELL | \"Totale overheid: directe vennootschapsbelasting.\" | DTF\n", "CELL | \"Totale indirecte belastingen.\" | IT\n", "CELL | \"Globale overheid: ontvangen sociale zekerheidsbijdragen.\" | YSSG\n", "CELL | \"Cotisation de responsabilisation.\" | COTRES\n", "CELL | \"Overheid: inkomen uit vermogen.\" | RIDG\n", "CELL | \"Globale overheid: saldo van de ontvangen lopendeoverdrachten.\" | OCUG\n", "CELL | \"Wisselkoers van de USD t.o.v. de BEF (jaargemiddelde).\" | EX\n", "CELL | \"Index wereldprijs - invoer van niet-energieprodukten, inUSD.\" | PWMAB\n", "CELL | \"Index wereldprijs - invoer van diensten, in USD.\" | PWMS\n", "CELL | \"Index wereldprijs - uitvoer van niet-energieprodukten, inUSD.\" | PWXAB\n", "CELL | \"Index wereldprijs - uitvoer van diensten, in USD.\" | PWXS\n", "CELL | \"Indicator van het volume van de wereldvraag naar goederen,1985=1.\" | QWXAB\n", "CELL | \"Indicator van het volume van de wereldvraag naar diensten,1985=1.\" | QWXS\n", "CELL | \"Brent olieprijs (USD per barrel).\" | POIL\n", "CELL | \"Totale beroepsbevolking (jaargemiddelde).\" | NATY\n", "CELL | \"TFPFHP_\" | TFPFHP_\n", "----- | ------------------------------------------------------------------------------\n", "MODE | \n", "FILES | \n", "DATE | \n", "\n", "nb lines: 27\n", "nb columns: 2\n", "language: 'ENGLISH'\n", "gridx: 'MAJOR'\n", "gridy: 'MAJOR'\n", "graph_axis: 'VALUES'\n", "graph_alignment: 'LEFT'" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# variables or LEC expressions can be also passed as a single string\n", "lines_vars = \"GOSG;YDTG;DTH;DTF;IT;YSSG;COTRES;RIDG;OCUG;$ENVI\"\n", "table_title = \"Table example with all variables passed as a single string\"\n", "table = Table(2, table_title, lines_vars, mode=True, files=True, date=True)\n", "table" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "3. Call the [Table](../_generated/iode.Table.rst#iode.Table) constructor with a title, a list of line titles (left column) and a list of the variables names or LEC expressions (right column):" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DIVIS | 1 | \n", "TITLE | \"Table example with titles on the left and LEC expressions on the right\"\n", "----- | ------------------------------------------------------------------------\n", "CELL | | \"#S\" \n", "----- | ------------------------------------------------------------------------\n", "CELL | \"GOSG:\" | GOSG\n", "CELL | \"YDTG:\" | YDTG\n", "CELL | \"DTH:\" | DTH\n", "CELL | \"DTF:\" | DTF\n", "CELL | \"IT:\" | IT\n", "CELL | \"YSSG+COTRES:\" | YSSG+COTRES\n", "CELL | \"RIDG:\" | RIDG\n", "CELL | \"OCUG:\" | OCUG\n", "----- | ------------------------------------------------------------------------\n", "MODE | \n", "FILES | \n", "DATE | \n", "\n", "nb lines: 16\n", "nb columns: 2\n", "language: 'ENGLISH'\n", "gridx: 'MAJOR'\n", "gridy: 'MAJOR'\n", "graph_axis: 'VALUES'\n", "graph_alignment: 'LEFT'" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "table_title = \"Table example with titles on the left and LEC expressions on the right\"\n", "# left column\n", "lines_titles = [\"GOSG:\", \"YDTG:\", \"DTH:\", \"DTF:\", \"IT:\", \"YSSG+COTRES:\", \"RIDG:\", \"OCUG:\"]\n", "# right column\n", "lines_lecs = [\"GOSG\", \"YDTG\", \"DTH\", \"DTF\", \"IT\", \"YSSG+COTRES\", \"RIDG\", \"OCUG\"]\n", "table = Table(2, table_title, lines_lecs, lines_titles, True, True, True)\n", "table" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Get/Update The Divider Line\n", "\n", "To update the divider line, use the [divider](../_generated/iode.Table.divider.rst#iode.Table.divider) attribute:" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('1', '')" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# the default divider is 1\n", "table.divider" ] }, { "cell_type": "code", "execution_count": 52, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('1', '1e-2')" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# update the divider to multiply all values of the \n", "# right column by 100 (e.g. to get percentage values)\n", "table.divider = ('1', '1e-2')\n", "table.divider" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Find The Position Of A Line\n", "\n", "To find the position of a line in an IODE table, use the [index(str)](../_generated/iode.Table.index.rst#iode.Table.index) method:" ] }, { "cell_type": "code", "execution_count": 53, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "10" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# find the index of the TITLE or CELL line containing RIDG\n", "index = table.index(\"RIDG\")\n", "index" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Get/Update Content Of Lines\n", "\n", "To get or update the content of a line, use the [[index]](../_generated/iode.Table.__setitem__.rst) operator:" ] }, { "cell_type": "code", "execution_count": 54, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('\"GOSG:\"', 'GOSG')" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "table[4]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Negative indices can be used to get or update the content of a line from the end of the table:" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# content of the last line\n", "table[-1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Append Lines\n", "\n", "To append a line to an IODE table, use the [+= operator](../_generated/iode.Table.__iadd__.rst):" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DIVIS | 1 | \n", "TITLE | \n", "----- | --------------\n", "CELL | | \"#S\"\n", "----- | --------------\n", "TITLE | \"Dummy Table\" \n", "----- | --------------\n", "CELL | \"RIDG:\" | RIDG\n", "----- | --------------\n", "MODE | \n", "FILES | \n", "DATE | \n", "\n", "nb lines: 11\n", "nb columns: 2\n", "language: 'ENGLISH'\n", "gridx: 'MAJOR'\n", "gridy: 'MAJOR'\n", "graph_axis: 'VALUES'\n", "graph_alignment: 'LEFT'" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from iode import TableLineType\n", "\n", "table = Table()\n", "\n", "# append a title line\n", "table += \"Dummy Table\"\n", "\n", "# append a separator line\n", "table += '-'\n", "\n", "# append a line with cells\n", "# NOTE: line containing double quotes \" -> assumed to be a STRING cell\n", "# line without double quotes -> assumed to be a LEC cell\n", "table += ('\"RIDG:\"', 'RIDG')\n", "\n", "# append a separator line (other way to do it)\n", "table += TableLineType.SEP\n", "\n", "# append a special MODE line\n", "table += TableLineType.MODE\n", "\n", "# append a special FILES line\n", "table += TableLineType.FILES\n", "\n", "# append a special DATE line\n", "table += TableLineType.DATE\n", "\n", "table" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Insert Lines\n", "\n", "To insert a line at a specific index, use the [insert(index, value)](../_generated/iode.Table.insert.rst#iode.Table.insert) method:" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DIVIS | 1 | \n", "TITLE | \n", "----- | --------------\n", "CELL | | \"#S\"\n", "----- | --------------\n", "TITLE | \"Dummy Table\" \n", "----- | --------------\n", "CELL | \"OCUG:\" | OCUG\n", "CELL | \"RIDG:\" | RIDG\n", "CELL | \"GOSG:\" | GOSG\n", "----- | --------------\n", "TITLE | \"New Title\" \n", "----- | --------------\n", "----- | --------------\n", "MODE | \n", "FILES | \n", "DATE | \n", "\n", "nb lines: 16\n", "nb columns: 2\n", "language: 'ENGLISH'\n", "gridx: 'MAJOR'\n", "gridy: 'MAJOR'\n", "graph_axis: 'VALUES'\n", "graph_alignment: 'LEFT'" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# insert a CELL line before the RIDG line\n", "index = table.index(\"RIDG\")\n", "table.insert(index, ('\"OCUG:\"', 'OCUG'))\n", "\n", "# insert a CELL line after the RIDG line\n", "index = table.index(\"RIDG\")\n", "table.insert(index + 1, ('\"GOSG:\"', 'GOSG'))\n", "\n", "# insert a separator after the GOSG line\n", "index = table.index(\"GOSG\")\n", "index += 1\n", "table.insert(index, '-')\n", "\n", "# insert a title line after the separator line\n", "index += 1\n", "table.insert(index, \"New Title\")\n", "\n", "# insert a separator line after the title line\n", "index += 1\n", "table.insert(index, TableLineType.SEP)\n", "\n", "table" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Delete Lines\n", "\n", "To delete a line, use the [del keyword](../_generated/iode.Table.__delitem__.rst):" ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DIVIS | 1 | \n", "TITLE | \n", "----- | --------------\n", "CELL | | \"#S\"\n", "----- | --------------\n", "TITLE | \"Dummy Table\" \n", "----- | --------------\n", "CELL | \"OCUG:\" | OCUG\n", "CELL | \"RIDG:\" | RIDG\n", "CELL | \"GOSG:\" | GOSG\n", "----- | --------------\n", "----- | --------------\n", "----- | --------------\n", "MODE | \n", "FILES | \n", "DATE | \n", "\n", "nb lines: 15\n", "nb columns: 2\n", "language: 'ENGLISH'\n", "gridx: 'MAJOR'\n", "gridy: 'MAJOR'\n", "graph_axis: 'VALUES'\n", "graph_alignment: 'LEFT'" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "index = table.index(\"New Title\")\n", "\n", "# delete the title line\n", "del table[index]\n", "\n", "table" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Negative indices can be used to delete lines from the end of the table:" ] }, { "cell_type": "code", "execution_count": 59, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DIVIS | 1 | \n", "TITLE | \n", "----- | --------------\n", "CELL | | \"#S\"\n", "----- | --------------\n", "TITLE | \"Dummy Table\" \n", "----- | --------------\n", "CELL | \"OCUG:\" | OCUG\n", "CELL | \"RIDG:\" | RIDG\n", "CELL | \"GOSG:\" | GOSG\n", "----- | --------------\n", "----- | --------------\n", "----- | --------------\n", "MODE | \n", "FILES | \n", "\n", "nb lines: 14\n", "nb columns: 2\n", "language: 'ENGLISH'\n", "gridx: 'MAJOR'\n", "gridy: 'MAJOR'\n", "graph_axis: 'VALUES'\n", "graph_alignment: 'LEFT'" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# delete the last line\n", "del table[-1]\n", "\n", "table" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Get the coefficients and variables of a table\n", "\n", "To get the list of *scalars* (*coefficients*) and *variables* referenced in a *table*, use the [coefficients](../_generated/iode.Table.coefficients.rst#iode.Table.coefficients) and [variables](../_generated/iode.Table.variables.rst#iode.Table.variables) properties of the [Table](../_generated/iode.Table.rst#iode.Table) class:" ] }, { "cell_type": "code", "execution_count": 60, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[]" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "table.coefficients" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['GOSG', 'OCUG', 'RIDG']" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "table.variables" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Plotting\n", "\n", "To plot a *table*, use the [plot](../_generated/iode.Table.plot.rst#iode.Table.plot) method:" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DIVIS | 1 | \n", "TITLE | \"Table for plotting\" \n", "----- | -------------------------------------------------------------------------\n", "CELL | | \"#S\" \n", "----- | -------------------------------------------------------------------------\n", "CELL | \"GOSG\" | GOSG\n", "CELL | \"Bruto exploitatie-overschot: overheid (= afschrijvingen).\" | YDTG\n", "CELL | \"DTH\" | DTH\n", "CELL | \"Totale overheid: directe belasting van de gezinnen.\" | DTF\n", "CELL | \"IT\" | IT\n", "CELL | \"Totale indirecte belastingen.\" | YSSG+COTRES\n", "CELL | \"RIDG\" | RIDG\n", "CELL | \"Overheid: inkomen uit vermogen.\" | OCUG\n", "----- | -------------------------------------------------------------------------\n", "MODE | \n", "FILES | \n", "DATE | \n", "\n", "nb lines: 16\n", "nb columns: 2\n", "language: 'ENGLISH'\n", "gridx: 'MAJOR'\n", "gridy: 'MAJOR'\n", "graph_axis: 'VALUES'\n", "graph_alignment: 'LEFT'" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# variables or LEC expressions can be also passed as a single string\n", "table_title = \"Table for plotting\"\n", "# left column\n", "lines_titles = [\"GOSG\", \"YDTG\", \"DTH\", \"DTF\", \"IT\", \"YSSG+COTRES\", \"RIDG\", \"OCUG\"]\n", "# right column\n", "lines_lecs = [\"GOSG\", \"YDTG\", \"DTH\", \"DTF\", \"IT\", \"YSSG+COTRES\", \"RIDG\", \"OCUG\"]\n", "table = Table(2, table_title, lines_lecs, lines_titles, True, True, True)\n", "table" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [ { "data": { "image/png": "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jdL69evL7VzFtX79ejqfCMEB2Hu9ErHr1gFw/dRRAHSOen777TeTY05nGj+crmaubP5js7Y984YZStmjM1ds2b6RXMvHkpKSUrYXUkG6detGUFAQYHxG33vvPZ5++mmioqIKPCYzMxNLS8vyKuI9y8HBAQcHhzsnLCFPT88yy7ssKaXIzs7GwuKe+dV+X8jIyCi1vErj2bl48SK//vpriWq77kZ4uLGlpVevXiZreJenzMxMbG1tsbW9NeXV7a/vxMrK6p79DFtbW9O/f3/mz5/PY489VjYnUfeI119/Xfn6+qoLFy5o23bt2qUAdenSJZO0r776qgoMDFRKKbV8+XJlZWWVJ78uXbqoESNGKKWUmj59uqpbt26eNLVr11YzZ87MtzxpaWkqISFB+7lw4YICVHx8vMrOzi7zn8zMTPXzzz+rzMzMcjlficqWkqgM05yVmuqksq//q+3/dc5M9Wnfp9Sen1blOXbB3wtUw+CG6r87/muy/UxojFowYotaPX1/nmPi4+MVoBISEvK8T6mpqerEiRMqNTW16A/bPWDw4MGqV69eJtt27NihABUbG6uUUioiIkIBavXq1ap9+/bK2tpaffvtt2rq1KmqcePGJsfOnTtX+fr6KqWUmjp1qgJMfrZu3aqUUurIkSOqY8eOysbGRrm6uqphw4apGzduFFrW48ePq+7duyt7e3vl7u6uXnrpJRUXF6eUUmrr1q3K0tJS7dixQ0v/6aefKjc3N+1z2759ezVy5Eg1cuRIpdfrlaurq5o0aZIyGAzaMb6+vmru3Lna6/Pnz6uePXsqe3t75ejoqJ5//nkVExOj7c99Dwq73rffflvVqVNH2draqho1aqj33ntPZWRkKKWUCgoKynNcUFCQUkopQK1du1Y738WLF1Xfvn2Vs7OzcnV1VT179lQRERGF3jellPryyy9VzZo1laWlpapbt6767rvvtH0vvPCC6tevn0n6jIwM5ebmpr799lullFIGg0F9/PHHqkaNGsrGxkY98sgj6v/+7/+09Fu3blWACgkJUc2bN1eWlpbqzz//VIcPH1YdOnRQDg4OytHRUTVr1kwdOHBAO27nzp2qXbt2ytbWVjk7O6snnnhCXbt2TXu/Ro0apd566y3l4uKiPDw81NSpU03KWdj7U9h9LYrC8j516pQC1MmTJ02OmT17tvL19dWeqcKe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g3cv3X0+JTlvMdjb21O79q25/Jo3b45er2fJkiV89NFHJulyMzMzQ93W7JuZmXnH8ymlCmymKGi7wWCgR48efPzxx3n25W5qzRldfu3aNa5du5anzMVRUDkLK39+9u7dywsvvMD7779PYGAger2eVatWMXv27GKVx2Aw5Nv0A1C5cmWsrKxMpq7I3b3j9vLefg0DBgygffv2xMbGsmnTJmxsbLSRiDmjwdevX0+VKlVM8rG2tjZ5ffv9njZtGv3792f9+vX88ccfTJ06lVWrVvHMM88UqRP67QN0dDqdVp7Sen/yU5S8vby86NixIytWrKB169asXLmSESNGaGmL+swW9Izmvvacc+aeCeD999+nT58+eY67PRDLKXdJVKpUKU/3oqioqEIDF4CXXnqJRYsW5bvvhx9+YOzYscyePZuAgAAcHR355JNP2LdvX6F5BgUFMXr0aEJCQli9ejXvvfcemzZtonXr1nf9LOUo7u+LOz0DRS3H7e9Pfp/XHMX5PBb2DOW4du0alStXLrTMJVWhgV1RHnqdTse0adOYNm1agWlsbGyYP38+8+fPLzCNq6sr33//fUmKKQqSE9i5G/8ajjgcSkrCdez0ztRomvcvsJzArnHlxibb05IySU/JAh04uxd95FOBdDqwuv9q/nQ6HWZmZlqNdUEqV65MTEyMyZfd7XNiWVlZ5akNq1+/PkuXLiU5OVn7Rbpr1y7MzMyoWzfvRNIAzZo146effqJ69eoFjrQMDw9n7NixLFmyhB9++IFBgwaxZcsWk76ROX9Z535dp04dkz++cpczKiqKCxcuaDU3J06cICEhAX9//3zLkN/17tq1C19fXyZNmqRtu702NL/jbtesWTNWr16Nu7u71tf2drkD9Bz+/v7s3LmTQYMGadt2795tcg1t2rTBx8eH1atX88cff/D8889jZWUFGO+DtbU1UVFRtG/fvtAy5qdu3brUrVuXsWPH8uKLLxIUFMQzzzzDI488wpYtW/Id9V8URXl/inJfS5o3GAPid955hxdffJHw8HBeeOEFbV9RntmSatasGWFhYfm+3wVdz7Jly0hNTdWCoNs/C/lp2rQpJ06cMNnm7e19x7nvCno+Af766y/atGnD66+/rm27vaapsPI0bdqUiRMnEhAQoAVUOc/Syy+/XKR8SlNhz0Bx6fV6PDw82L9/P48//jgA2dnZHDp0SJu2524/j7mFh4eTlpZG06ZN7yqfgtwTgyfE/cfMkAHxkcYXN2vsjm8zTl/i/3hHzPP5hXr8qnEpuEaVGplsj48x1tY5uthgYZX3i/5BlZ6ernU/OHnyJKNGjSIpKYkePXoUelyHDh2Ii4tj1qxZhIeH88UXX/DHH3+YpKlevTpHjhwhLCyMK1eukJmZyYABA7CxsWHw4MEcO3aMrVu3MmrUKAYOHFjgIKKRI0dy7do1XnzxRfbv38+5c+fYuHEjr7zyCtnZ2WRnZzNw4ECeeOIJXn75ZYKCgjh27FieWrELFy4wbtw4wsLCWLlyJfPnz2fMmDH5nrNLly7aAIC///6b/fv3M2jQINq3b19gk01+11u7dm2ioqJYtWoV4eHhfP7556xduzbPcRERERw+fJgrV66Qnp6eJ+8BAwZQqVIlevXqxV9//UVERATbt29nzJgxeZYuzO2tt94iODiYRYsWcebMGebMmcOaNWtMOmzrdDr69+/PokWL2LRpEy+99JK2z9HRkQkTJjB27FiWLl1KeHg4hw4d4osvvmDp0qUFnjc1NZU33niDbdu2cf78eXbt2sWBAwe0wGjixIkcOHCA119/nSNHjnDq1CkWLlzIlStXCswzt6K8PwXd14kTJ5oEuiXJG6BPnz4kJiby2muv0bFjR5MalDs9s3djypQpfPfdd0ybNo3jx49z8uRJrRYrP/3798fMzIyhQ4dy4sQJfv/9dz799NM7nicwMJA9e/aYlPdum2Jr167NwYMH2bBhA6dPn2by5MkcOHCg0HJEREQwceJE9uzZw/nz59m4cSOnT5/WnqWpU6eycuVKpk6dysmTJzl69CizZs264/WVhsKegZIYNWoUM2fO5JdffiEsLIwxY8YQHx+v/fFc0s9jfv766y9q1qxp0jTcuXPnUmtFlMBOlIhDWrQ2IhYHd9JTkok4fBCABu065UmfmZ2prRHr72Za66I1w3o+XCtOhISE4OXlhZeXF61atdJGqhY2ahCMNUFffvklX3zxBY0bN2b//v15RtoNGzYMPz8/rT/Nrl27sLOzY8OGDVy7do2WLVvy3HPP3fGXibe3N7t27SI7O5vAwEAaNmzImDFj0Ov1mJmZMX36dCIjI/nqq68A4wj0r7/+mvfee8+kdmHQoEGkpqby6KOPMnLkSEaNGsXw4cPzPWfOjPcuLi60a9eOLl26ULNmTVavXl1gOfO73l69ejF27FjeeOMNmjRpwu7du5k8ebLJcc8++yzdunWjY8eOVK5cmZUrV+bJ287Ojh07dlCtWjX69OmDv78/r7zyCqmpqYXWkPTu3Zt58+bxySef0KBBAxYvXkxQUFCe93fAgAGcOHGCKlWq5OmT9+GHHzJlyhRmzpyJv78/gYGBrFu3jho1ahR4XnNzc65evcqgQYOoW7cuffv2pXv37loNXd26ddm4cSP//PMPjz76KAEBAfzyyy9Frt0qyvtT0H2Njo4utE9XUd97JycnevTowT///KP1Scxxp2f2bgQGBvLbb7+xadMmWrZsSevWrZkzZw6+vnnXxAbjfIvr1q3jxIkTNG3alEmTJuXbRHy7J598EktLS231pNLwn//8hz59+tCvXz9atWrF1atXTWrv8mNnZ8epU6d49tlnqVu3LsOHD+eNN97Qmj07dOjA//3f//Hrr7/SpEkTOnXqdMem3dJS2DNQEjm1f4MGDSIgIAAHBwcCAwNNmthL8nnMz8qVKxk2bJjJtvDw8CL/cXUnOlXSTgAPmcTERPR6PQkJCYX+Mi8tBoOBdevW0aNHj7v+ZVTaDAYDh5b+l+bnF0O1AHglhGPbNrNh4We4Va3G4E+/yNNXIexaGM+tew5HS0d2vbjLZP+uH89wePMFHulYlcf75W0SLOzep6WlERERQY0aNfLt4yIqXocOHWjSpEm5T7YqxP3syy+/5JdffmHDhg0VXZQKt3jxYj788MNCa8hLm8FgwN/fn759+/Lhhx+WWr7Hjh2jc+fOnD59ulgrYxTnu06mJxclok+JNP7H0zj659Qu4zw+fm0ez7fz8+l444oTdVzq5Nl/LfrmiFiv+69fnBBClIXhw4cTHx/PjRs3ynVZsXvNhQsX+P3332nQoEGZnienqbl9+/akp6ezYMECIiIitBk4SsulS5f47rvvynS5MwnsRIk45wR23k1ISUwg6phxYES9tvl3Kg27ZpxOw8817/Qy8dHJALhKYCeEEICxT13ugT8Pq2bNmlGlShWCg4PL9DxmZmYEBwczYcIElFI0bNiQzZs3Fzhgq6Ryr2tfViSwE8VnyMY59eboQu+m/HvqOMpgoJKPLy6e3vkecireOILWz8U0sMtIy+LGtTRAArsH1bZt2yq6CEKI+1RcXFy5nMfHx4ddu3aVy7nK2r3VeUvcH66excKQhrK0g0p1uXzOOGTes3b+U2YopTh9zdgUW8+1nsm+nIETto6W2DjI4vZCCCHE3ZDAThRf9GHjv56NwMycyxHG0a4eNfKf2ykuNY749HjMdGbUcq5lsi+nGfZhWnFCCCGEKCsS2Ili0+UEdl5NUEpx+dzNwK5m/oFdTv+66k7VsbEwHc2TM3BCmmGFEEKIuyd97ETxXToMgPJuQtLVK6QmJqAzM6OSb/V8k59LOAeQp7YO4FpOjZ0EdkIIIcRdkxo7UTxKweVjxv97NtaaYd2qVsPSyjrfQ84nGgdaVHeqnmffrRGxD9fkxEIIIURZkMBOFE9yHLqMJBQ6cK1JbIRx4ERB/evgVmBXQ286O3dWRjaJV4zrokqNnRBCCHH3JLATxXPN2KyaauUGFta5+tflbWbNEZkQCYCvk+myO9eik1EKbOwtsXOyKpvyCiGEEA8RCexE8VyLACDZyh2lFDFnjdOYeNSsk2/ylMwUYlNjgbyB3ZWLSQBU8nHId7WKB92QIUPQ6XTodDosLS3x8PCga9eufPvttxgMBrZt26btL+gnODhYS3f9+vU856hevbos5SWEEA8RGTwhiudmjV2ytQfmsTGk3kjE3MIC9xr519hFJkYC4Grjit7adAmVKxduBnZVHcquvPe4bt26ERQURHZ2NpcvXyYkJIQxY8bw448/8vPPPxMdHa2lHTNmDImJiQQFBWnb9Hp9uS26LYQQ4t4ngZ0onvibNXbW7iSfMU5j4l69FhaW+U8uXNjAiSsXbwBQyefhXQfR2toaT09PAKpUqUKzZs1o3bo1nTt35rvvvuPVV1/V0tra2pKenq6lF0IIIW4ngZ0oHq3Gzp0bNwM7r7r1CkxeUP86ZVC3mmJLucZOKUVqVmqp5lkUtha2pdKk3KlTJxo3bsyaNWtMAjshhBDiTiSwE8Wj9bHzIPrUzcCujl+ByXOaYm8P7BKvppGZlo2ZhQ5nz9Kd6iQ1K5VWK1qVap5Fsa//PuwsS+da6tWrx5EjR4p1TNWqVfNsS0lJKZXyCCGEuD9IYCeKLvU6pF4DIMnchbjzxiDPu07BNXZaU6y+usn2qzdr69y8HTA3lzE8t1NKFbv276+//sLR0bRZu0OHDqVYKiGEEPc6CexE0d3sX6fs3UlOTMaQnY29swuOlSrnm9ygDEQkGI+5vY9dXE7/ujIYOGFrYcu+/uU/oMDWwrbU8jp58iQ1atS4c8JcatSogbOzs8k2Cwv5iAshxMNEfuuLorvZvw6X6qRfjQPAs3bdAmuWLt64SEpWClZmVnmaYuPO5wycKP3ATqfTlVqTaEX4888/OXr0KGPHjq3oogghhLjPSGAniu5m/zpca5J25goAHjULXnEiLN7YB6+2S20szG49asqgiDmXAIBnTX2+xz4s0tPTiYmJMZnuZObMmTz99NMMGjSooosnhBDiPiOBnSi6K2cAUK61SL9m7NhfaGB3zRjY+bmYDq6Iv5xCekoWFpZmuD3Ec9gBhISE4OXlhYWFBS4uLjRu3JjPP/+cwYMHY2YmfQ+FEEIUjwR2ouiuGAO1DKfqZCbuAApfIzanxs7P1TSwy6mtc6/u9FAPnAgODiY4OLhY6fPToUMHlFL57ouMjCx+wYQQQty3Ht5vVVE8Smk1drFp9gA4uLph7+xS4CGnrxmXG6vrUtdkuzTDCiGEEGVDAjtRNImXICMJdObEXjVO/nv7MmIHYg4wcstIfg3/letp17mUfAnIp8YuPCewcyqHggshhBAPD2mKFUVzsxkW15pcvtm8l7sZVinFjH0zOHv9LDsu7qCyrXEKFG97b5ysbgVwacmZxMcYJ82VGjshhBCidEmNnSiaOGOzKpX9iI0IB0xr7I5eOcrZ62exMrPCycqJuFTjdCh1XU2bYc8fuwqAi6cdto5W5VBwIYQQ4uEhgZ0omps1djdsq3Pt3wuAcQ67HD+d+QmAwOqB/N7ndwbXH4yrjStP1XzKJJszBy4DULu5e3mUWgghhHioSFOsKJqbNXbnrlkDYO3mjp2TsSk1OTOZPyL+AODZus+it9YzoeUEJrScYJJF6o0Mok4YlySr09KjvEouhBBCPDSKXWOXmppqsrD4+fPn+eyzz9i4cWOpFkzcY67cDOyirgNgX/XWShI7Lu4gNSuV6k7VaeberMAswv+ORRkUlas54uJpX6bFFUIIIR5GxQ7sevXqxXfffQfA9evXadWqFbNnz6ZXr14sXLiw1Aso7gHJVyA5lkyDGefPGFefsK9STdu9NWorAJ2rdS504fqzobGA1NYJIYQQZaXYgd3ff//N448/DsCPP/6Ih4cH58+f57vvvuPzzz8v9QKKe8C5bQCct2hEdmYmTu4eWOmN89dlZmfy179/AdCxWscCs8hMzyb65jQnNR6pVLblFUIIIR5SxQ7sUlJScHR0BGDjxo306dMHMzMzWrduzfnz50u9gOIeEP4nABcwjoKt0aS5VjN34PIBkjKTcLNxo1GlRgVmEX32OoZshYOLNXp327Ivs8ijevXqfPbZZxVdjBIJDg7G2dn5rvKIjIxEp9Nx+PDhAtNs27YNnU7H9evX7+pct5d32rRpNGnS5K7yLE9Dhgyhd+/ed5VHad3LwhTlPX3QlMd9LQ0dOnTgzTffrOhiPJSKHdjVrl2bn3/+mQsXLrBhwwaeeOIJAGJjY3FykglnHzhKwdnNAFzNMPaLq+xbU9ud0wzbwacDZrqCH6eLp+IBqFrPpdDm2oeBTqcr9GfIkCF3PP7nn38ul7I+SHx8fIiOjqZhw4blfu4JEyawZcuWMj/Pg/xs5BdsVuR7Kgq3Zs0aPvzww4ouxkOp2KNip0yZQv/+/Rk7diydOnUiICAAMNbeNW3atNQLKCrY5WOQdBks7bh6+QYAblWrERlmXF5sf8x+ANpVbVdoNhfDcgI71zIs7P0hOjpa+//q1auZMmUKYWFh2jZbW6nRzC0jI6NU8jE3N8fT07NU8iouBwcHHBwcCtyfkZGBlZXM61hcFfmeisK5usrv+opS7Bq75557jqioKA4ePMiGDRu07Z07d2bu3LmlWjhxDzhrrGVIr/IYSdeMkwu7VqkKQEpmChEJxsEUj1R+pMAs0pIzibtgDAqr1it4bdmHhaenp/aj1+vR6XQm21asWEGtWrWwsrLCz8+PZcuWacdWr14dgGeeeQadTqe9Dg8Pp1evXnh4eODg4EDLli3ZvHlzoeVISEhg+PDhuLu74+TkRKdOnfjnn38KPebo0aN06tQJW1tb3NzcGD58OElJSQBs2LABGxubPE1Eo0ePpn379trr3bt3065dO2xtbfHx8WH06NEkJyebXONHH33EkCFD0Ov1DBs2TNu3YcMG/P39cXBwoFu3biZBMkBQUBD+/v7Y2NhQr149vvzyS21ffs12v//+O3Xr1sXW1paOHTsSeXNVleIKDg6mWrVq2NnZ8cwzz3D16lWT/bc3xebUPs2cORNvb2/q1jXOCfnvv//Sr18/XFxccHNzo1evXnnK9O2339KgQQOsra3x8vLijTfe0O4b5H02ANatW0fz5s2xsbGhZs2avP/++2RlZd3xut5//33t+RgxYoRJkK2UYtasWdSsWRNbW1saN27Mjz/+WGBeV69e5cUXX6Rq1arY2dnRqFEjVq5caZLmxx9/pFGjRtrz1aVLF5KTk5k2bRpLly7ll19+0Wq2t23bluc9zWmm3LJlCy1atMDOzo42bdqY/OEE8NFHH+Hu7o6joyOvvvoq//3vfwtsKjcYDFStWpVFixaZbP/777/R6XScO3cOgDlz5tCoUSPs7e3x8fHh9ddf1z4bcKt5/k7P8O2K8oze6TOVn6Lcg8I+T9OmTcu3xSE4OBjI2xRbvXp1ZsyYwSuvvIKjoyPVqlXjq6++0vbnvJdr1qyhY8eO2NnZ0bhxY/bs2VOsa73TeR4KqoTOnDmjQkJCVEpKilJKKYPBUNKs7gsJCQkKUAkJCeVyvuzsbPXzzz+r7OzscjlfgVa8oNRUJ/XvTx+pT/s+pRaNGKiV7e+Yv1XD4Iaqw+oOhWYRfihWLRixRS2ftrdERSjs3qempqoTJ06o1NRUbZvBYFDZycnl/lOSz0BQUJDS6/Xa6zVr1ihLS0v1xRdfqLCwMDV79mxlbm6u/vzzT6WUUrGxsQpQQUFBKjo6WsXGxiqllDp8+LBatGiROnLkiDp9+rSaNGmSsrGxUefPn9fy9vX1VXPnztXuUdu2bVWPHj3UgQMH1OnTp9X48eOVm5ubunr1ar5lTU5OVt7e3qpPnz7q6NGjasuWLapGjRpq8ODBSimlsrKylIeHh/r666+1Y3K2LV68WCml1JEjR5SDg4OaO3euOn36tNq1a5dq2rSpGjJkiEk5nZyc1CeffKLOnDmjzpw5o4KCgpSlpaXq0qWLOnDggAoNDVX+/v6qf//+2nFfffWV8vLyUj/99JM6d+6c+umnn5Srq6sKDg5WSikVERGhAHXo0CGllFJRUVHK2tpajRkzRp06dUp9//33ysPDQwEqPj5eyzfnfhdk7969SqfTqZkzZ6qwsDA1b9485ezsbPK+Tp06VTVu3Fh7PXjwYOXg4KAGDhyojh07po4ePaqSk5NVnTp11CuvvKKOHDmiTpw4ofr376/8/PxUenq6UkqpL7/8UtnY2KjPPvtMhYWFqf3792vvaUHPRkhIiHJyclLBwcEqPDxcbdy4UVWvXl1NmzatwGvKKV+/fv3UsWPH1G+//aYqV66s3n33XS3Nu+++q+rVq6dCQkJUeHi4CgoKUtbW1mrbtm1KKaW2bt1qci8vXryoPvnkE3Xo0CEVHh6uPv/8c2Vubq727jX+Xrh06ZKysLBQc+bMUREREerIkSPqiy++UDdu3FA3btxQffv2Vd26dVPR0dEqOjpapaen53lPc87ZqlUrtW3bNnX8+HH1+OOPqzZt2mjl/v7775WNjY369ttvVVhYmHr//feVk5OTyftzu/Hjx6vHHnssz7aAgADt9dy5c9Wff/6pzp07p7Zs2aL8/PzUa6+9pu0vyjN8u6I8o0X5TN2uKPfgTp+nGzduaO9FdHS0+vTTT5WdnZ06evSoUkqp9u3bqzFjxmj5+fr6KldXV/XFF1+oM2fOqJkzZyozMzN18uRJpdStz2e9evXUb7/9psLCwtRzzz2nfH19VWZmZpGv9U7nuV/l911XkGIHdleuXFGdOnVSOp1OmZmZqfDwcKWUUq+88ooaN25c8Ut7n3hoA7sFjyo11UkdWfmZ+rTvU+qHDydpZVt+YrlqGNxQvbbptUKz2LfunFowYovaHHy8REUobmCXnZysTvjVK/ef7OTkYl/b7YFdmzZt1LBhw0zSPP/88+rJJ5/UXgNq7dq1d8y7fv36av78+drr3IHdli1blJOTk0pLSzM5platWloQdruvvvpKubi4qKSkJG3b+vXrlZmZmYqJiVFKKTV69GjVqVMnbf+GDRuUlZWVunbtmlJKqYEDB6rhw4eb5PvXX38pMzMz7T309fVVvXv3NkkTFBSkAHX27Flt2xdffKE8PDy01z4+PmrFihUmx3344Yfal+/tQcDEiROVv7+/SUD+zjvv5Ans/Pz81Jo1a/K9J0op9eKLL6pu3bqZbOvXr98dAzsPDw8tYFNKqW+++Ub5+fmZlCc9PV3Z2tqqDRs2KKWU8vb2VpMmTSqwLPk9G48//riaMWOGybZly5YpLy+vAvMZPHiwcnV1Vcm5numFCxcqBwcHlZ2drZKSkpSNjY3avXu3yXFDhw5VL774olIqb2CXnyeffFKNHz9eKaVUaGioAlRkZGSBZerVq5fJtoICu82bN2tp1q9frwDt+WrVqpUaOXKkST5t27YtNLD7+++/lU6n08qWnZ2tqlSpor744osCj/nhhx+Um5ub9rooz/DtivKMFuUzdbui3IM7fZ5y27Nnj7KxsVGrV6/WtuUX2L300kvaa4PBoNzd3dXChQuVUrfey9x/GB4/flwBWlBW1N8fhZ3nflWcwK7YTbFjx47F0tKSqKgo7OzstO39+vUjJCSk2DWG4h5mMEB8JABXb2QD4FbVR9t96topAOq51is0m2v/Gpsj3KoU3MdIGJ08eZK2bduabGvbti0nT54s9Ljk5GTefvtt6tevj7OzMw4ODpw6dYqoqKh804eGhpKUlISbm5vW/8vBwYGIiAjCw8MLLFvjxo2xt781uXTbtm0xGAxaU9eAAQPYtm0bly5dAmD58uU8+eSTuLi4aOcNDg42OWdgYCAGg4GIiAgt3xYtWuQ5v52dHbVq3Vqf2MvLi9hY49yIcXFxXLhwgaFDh5rk/dFHHxV6Pa1btzYZzJPTZzi3U6dO8cwzz+SbR04+tx+XXz63a9SokUm/utDQUM6ePYujo6NWfldXV9LS0ggPDyc2NpZLly7RuXPnO+adW2hoKB988IHJfRk2bBjR0dEmk83frnHjxia/4wMCAkhKSuLChQucOHGCtLQ0unbtapLvd999V+D9zs7OZvr06TzyyCPac7dx40btGW3cuDGdO3emUaNGPP/88yxZsoT4+PhiXWuORx651TXEy8sLQHtWwsLCePTRR03S3/76dk2bNqVevXpa0/H27duJjY2lb9++WpqtW7fStWtXqlSpgqOjI4MGDeLq1asmzYSFPcP5KcozWtTPVG53ugfF+TxFRUXRu3dvJkyYYHI/8pP7fcnpgnL79Rf23hX1WotyngdZsQdPbNy4kQ0bNlC1alWT7XXq1JHpTh40STGQlQZmFlyLuw5ApVwrTuQEdv5u/oVmc/WS8Rebm3f5BHY6W1v8/g4tl3Pdft5Syee2UcNKqTuOJH7rrbfYsGEDn376KbVr18bW1pbnnnuuwIEHBoMBLy8vtm3blmdfQdOKFFaOnO2PPvootWrVYtWqVbz22musXbuWoKAgk/OOGDGC0aNH58mjWrVbk17nDh5zWFpa5jmnUkrLF2DJkiW0atXKJJ25uXmB11MaSprP7ddoMBho3rw5y5cvz5O2cuXKmJmVbGlvg8HA+++/T58+ffLss7GxKXZ+Op1Ou9/r16+nSpUqJvutra3zPW727NnMnTuXzz77TOuL9uabb2rPqLm5OZs2bWL37t1s3LiR+fPnM2nSJPbt20eNGjWKVcbcz0rOs5lT5tzbchTlPRwwYAArVqzgv//9LytWrCAwMJBKlYxzcp4/f54nn3yS//znP3z44Ye4urqyc+dOhg4dSmZmZr7lyilHYecuSrmK+pm6XWH3oKifp+TkZHr27ElAQAAffPDBHcua3/Xnfl9uT3P7e1fUay3KeR5kxQ7skpOTTf6Ky3HlypUCP9DiPnXN2CkYvQ9XTl8AwPVmjV2WyuLMdePIWH/XggO7rIxsEmKNtQKuVcpnGTGdTocun2f0fuDv78/OnTsZNGiQtm337t34+9+6x5aWlmRnZ5sc99dffzFkyBCtZikpKanQgQDNmjUjJiYGCwsLk072halfvz5Lly4lOTlZC0p27dqFmZmZ1vkfoH///ixfvpyqVatiZmbGU089ZXLe48ePU7t27SKds6g8PDyoUqUK586dY8CAAUW+ntunBtm7d2+xz12/fv08x5Ukn2bNmrF69WptsEJ+qlevzpYtW+jYMf/JwPN7Npo1a0ZYWFix7/k///xDamqqNkp77969ODg4ULVqVVxcXLC2tiYqKspkYExh/vrrL3r16sVLL70EGL+kz5w5Y/Js63Q62rZtS9u2bZkyZQq+vr6sXbuWcePGYWVllefaSsLPz4/9+/czcOBAbdvBgwfveFz//v157733CA0N5ccffzRZaengwYNkZWUxe/ZsLQD/4Ycf7rqsRXlGS/KZutM9KMrnSSnFSy+9hMFgYNmyZeUyjVVZ/f540BT7T8B27dppS4rBrUj4k08+KfCXjbhPXTNWbac7VufGlTgA3KoYA7u47DiyDFk4WjlSxaFKgVnEx6SgFNjYW2LnJNM53Mlbb71FcHAwixYt4syZM8yZM4c1a9YwYcIELU3Ol3tMTIzWVFW7dm3WrFnD4cOH+eeff+jfv3+hf6F26dKFgIAAevfuzYYNG4iMjGT37t289957BX7JDRgwABsbGwYPHsyxY8fYunUro0aNYuDAgXh4eJik+/vvv5k+fTrPPfecSa3QO++8w549exg5ciSHDx/mzJkz/Prrr4waNepubx3Tpk1j5syZzJs3j9OnT3P06FGCgoKYM2dOvun/85//EB4ezrhx4wgLC2PFihXaiL7c6tWrx9q1aws87+jRowkJCWHWrFmcPn2aBQsWlKhbyoABA6hUqRK9evXir7/+IiIigu3btzNmzBguXryoXePs2bP5/PPPOXPmDH///Tfz58/X8sjv2ZgyZQrfffcd06ZN4/jx45w8eZLVq1fz3nvvFVqejIwMhg4dyokTJ/jjjz+YOnUqb7zxBmZmZjg6OjJhwgTGjh3L0qVLCQ8P59ChQ3zxxRcsXbo03/xq166t1cidPHmSESNGEBMTo+3ft28fM2bM4ODBg0RFRbFmzRri4uK0wK969eocOXKEsLAwrly5YlITVhyjRo3im2++YenSpZw5c4aPPvqII0eO3DEwqVGjBm3atGHo0KFkZWXRq1cvbV+tWrXIyspi/vz5nDt3jmXLluUZRVsSRXlGS/KZKso9uNPnadq0aWzevJnFixeTlJRETEwMMTExpKam3vV1F6S0fn907tyZBQsWlFEpK16xA7tPPvmExYsX0717dzIyMnj77bdp2LAhO3bs4OOPPy5WXjt27KBHjx54e3vnO7HmkCFD8gylbt26tUma9PR0Ro0aRaVKlbC3t6dnz57aL8Ec8fHxDBw4EL1ej16vZ+DAgff8rN33hJs1dueSKwPg4l0VW0djTcK/2f8Cxv51hf1CvHrJ2L/O1dv+oZ+YuCh69+7NvHnz+OSTT2jQoAGLFy8mKCiIDh06aGlmz57Npk2b8PHx0eaOnDt3Li4uLrRp04YePXoQGBhIs2bNCjyPTqfj999/p127drzyyivUrVuXF154gcjISJMgLTc7Ozs2bNjAtWvXaNmyJc8991y+vyDr1KlDy5YtOXLkSJ6/9h955BG2b9/OmTNnePzxx2natCmTJ0/W+tLcjVdffZWvv/6a4OBgGjVqRPv27QkODi6wGa9atWr89NNPrFu3jsaNG7No0SJmzJiRJ11YWBgJCQkFnrd169Z8/fXXzJ8/nyZNmrBx48Y7Bk35sbOzY8eOHVSrVo0+ffrg7+/PK6+8QmpqqlaDN3jwYD777DO+/PJLGjRowNNPP82ZM2e0PPJ7NgIDA/ntt9/YtGkTLVu2pHXr1syZMwdfX998y5Gjc+fO1KlTh3bt2tG3b1969OjBtGnTtP0ffvghU6ZMYebMmfj7+xMYGMi6desKvN+TJ0+mWbNmBAYG0qFDBzw9PU0mHHZycmLHjh08+eST1K1bl/fee4/Zs2fTvXt3AIYNG4afnx8tWrSgcuXK7Nq1q9j3GIwB9MSJE5kwYQLNmjUjIiKCIUOGFKlZesCAAfzzzz/06dPHZL7JJk2aMGfOHD7++GMaNmzI8uXLmTlzZonKl1tRntGSfKaKcg/u9Hnavn07SUlJtGnTBi8vL+1n9erVd33dBSmt3x/h4eFcuXKljEpZ8XSqBB1EYmJiWLhwIaGhoRgMBpo1a8bIkSOLfXP/+OMPdu3aRbNmzXj22WdZu3atyQd9yJAhXL582aSPjpWVlcnEh6+99hrr1q0jODgYNzc3xo8fz7Vr1wgNDdX6AnTv3p2LFy9qc9kMHz6c6tWrs27duiKXNTExEb1eT0JCQrmssGEwGFi3bh09evQocd+au/Z/Q+D4Wtam9eFcRBytn32Btn2NVe8vr36ZvzP+5tVGrzKm2ZgCs9j101kOb4qiUYeqtHuhboHpClPYvU9LSyMiIoIaNWqUqL+QEEJ07doVT09PkzkjHzZyD+5txfmuK3YfOzBOsPr++++XqHC5de/eXftrrCDW1tYFziyekJDAN998w7Jly+jSpQsA33//PT4+PmzevJnAwEBOnjxJSEgIe/fu1TqBLlmyhICAAMLCwvDz87vr63hgXTtHWrY556OMk636tX5M23U+yzhQpql74auNXLuUMyK2fPrXCSFEYVJSUli0aBGBgYGYm5uzcuVKNm/ezKZNmyq6aOVG7sGDrdiB3Y4dOwrd365d4UtLFde2bdtwd3fH2dmZ9u3bM336dNzd3QHj0OfMzExtvVoAb29vGjZsyO7duwkMDGTPnj3o9XqTkT2tW7dGr9eze/duCewKohRciyT8hhvZ2QbcqlajUrXqAFxNvcpVw1V06GhcuXEhWSiuXsxpipWpToQQFS+nG8JHH31Eeno6fn5+/PTTT1rlwMNA7sGDrdiBXe6+Pjly950qjVFLObp3787zzz+Pr68vERERTJ48mU6dOhEaGoq1tTUxMTFYWVlpc2Tl8PDw0DrlxsTEaIFgbu7u7iYdd2+Xnp5Oenq69joxMREwNpGWx7Dp3MO7K0TKNczSEzibZOy4XKdVG60sh2IPAVBLXwtHS8cCy5h4JZXkhAzMzHS4VrEr8bU8TMPUhRBly9bW9o7L7T3o5B482Iod2N0+YWRmZiaHDh1i8uTJTJ8+vdQKBsZJj3M0bNiQFi1a4Ovry/r16/OdkynH7fNt5ddp/05zg82cOTPf5uY//vgj3+leysr69evL7Vy5uSWdoq2CCynOAFy8kar1Sfwj9Q8AXFNdC+2nmHzRArDFwimLkA2/l7gshU2iKoQQQohbih3Y6fX6PNu6du2KtbU1Y8eOJTS07CaG9fLywtfXVxsF5unpSUZGBvHx8Sa1drGxsbRp00ZLc/ny5Tx5xcXFFTj6D2DixImMGzdOe52YmIiPjw/du3cvt8ET69ev56mnnqqQwRO637cRm25PerYFlja2PDtoCGY3B6Os+n0VpEOvFr14utbTBeaxddkp4omhwaPVad2jVoHp7iSntlQIIYQQhSu1iKFy5craskJl5erVq1y4cEEbfdu8eXMsLS1NOnxGR0dz7NgxLbALCAggISGB/fv3a2n27dtHQkKCliY/1tbWODk5mfwAmJmZldtPeZ9P+8nOQHfsJy4mG4P4qvXqY2FpiZmZGQYMhMUb3+cm7k0KzSf6rHGKCO86LqVyL4QQQghRuGLX2B05csTktVKK6Oho/ve//9G4ccEd6fOTlJTE2bNntdcREREcPnwYV1dXXF1dmTZtGs8++yxeXl5ERkby7rvvUqlSJW12fb1ez9ChQxk/fjxubm64uroyYcIEGjVqpHUC9ff3p1u3bgwbNozFixcDxulOnn76aRk4UZBTv0FaAlGZxtm9fRrcWncv6kYUmYZMrLDC28G7wCySr6eTEJcKOvCq7VzWJRZCCCEEJQjsmjRpku/6dq1bt+bbb78tVl4HDx40Wa0ip+lz8ODBLFy4kKNHj/Ldd99x/fp1vLy86NixI6tXr8bR0VE7Zu7cuVhYWNC3b19SU1Pp3LkzwcHBJuvZLV++nNGjR2ujZ3v27PlAzzp91/5ZhUHBv8mOQLZJYBd+3bgAdGXzypjpCq5Ju3T2OgCVqjpgbVuiWXWEEEIIUUzF/saNiIgweW1mZkblypVLNDlshw4dCl3keMOGDXfMw8bGhvnz55ssq3M7V1dXvv/++2KX76GkFPx7kPAbbqRnZGNla4d79Zra7rPXjTWs7mZ5RxrnduHENQCq1HEpNJ0QQgghSk+xA7s7LUMj7nPJV7h2PY2Q6CYANOr0hDZoAm7V2LmbFxzYKYPi/DHjpMa+Dd3KrqxCCCGEMFGkwO7zzz8vcoajR48ucWHEPSDuFJtiapNhsKBKvfo83n+wye6iBHZxF26QkpiBpbU53nWcy7K097UhQ4Zw/fp1fvnll0LTDR48ON/F6YUQQojbFSmwmzt3bpEy0+l0Etjd51KijnAxxTgatvvI8ZhbWGr7Mg2ZRCZGAoUHdpFHjbV1Pv6umFvKiNY7iY6O1v6/evVqpkyZYjLCPPdi40IIIURhihTY3d6vTjy4Io4cBnRUdrNF7246z9+FxAtkGbKws7DDWedcYB7nj14BwLeRNMMWRe61kPV6PTqdrsD1kYUQQojCyHBFYSIi3Fh7VNOvZp59OQMnauhroMvOf9WO1BsZxJ6/AVRc/zqlFFkZ5b8MmYWVWaGrmQghhBBlrUSB3cWLF/n111+JiooiIyPDZN+cOXNKpWCi/Bmys4mMzQbMqdk8IM/+M9eNK37Ucq4FV/PP49KZ6wC4ettjr7cuo5IWLivDwFdjtpf7eYfPa4+ltfmdEwohhBBlpNiB3ZYtW+jZsyc1atQgLCyMhg0bEhkZiVKKZs2alUUZRTn598g+0rPNsTXPxLN5xzz7Qy8bl4trVKlRgYHdvzcDuyoyaEIIIYQod8UO7CZOnMj48eP54IMPcHR05KeffsLd3Z0BAwbQrVu3siijKCcHfv4BgFquaZjZmq4JnJ6dzj+x/wDwqMejHA07mm8el05fB8C7bsXNX2dhZcbwee0r5LxCCCFERSp2YHfy5ElWrlxpPNjCgtTUVBwcHPjggw/o1asXr732WqkXUpS9i6eOE3HqLDoUjzZwzrP/SNwRMgwZVLatjK+TL0fJG9ilJWdy9VISQIVOc6LT6aRJVAghxEOp2FUM9vb2pKenA+Dt7U14eLi278qVK6VXMlGudq82rszRyDkGF++qefbvj9kPQAvPFgUOELh05joocPG0w87JqszKKoQQQoj8FbvGrnXr1uzatYv69evz1FNPMX78eI4ePcqaNWto3bp1WZRRlLGUxAQunDDWwLWqFAUOvfKk2R9tDOwe9Xy0wHxyBk7IpMRCCCFExSh2YDdnzhySkozNbdOmTSMpKYnVq1dTu3btIk9kLO4tl06fAsDV0RwnywywN518OCUzhaNXjIFfYYHdxVPxAFSpwP5195P8VpMYMmQIQ4YMKfeyCCGEeDAUO7D78MMPeemll1BKYWdnx5dfflkW5RLl6N9TxwGo4pRp3OBgGtjtvrSbTEMmVRyq4OPog1IqTx4piRlc/dcY8Ffxk8BOCCGEqAjF7mN39epVnnrqKapWrcr48eM5fPhwGRRLlKdLYScBqGKXaNxwW2C36fwmALpU61Jg/7p/Txtr69yqOEj/OiGEEKKCFDuw+/XXX4mJiWHq1KmEhobSvHlz6tevz4wZM4iMjCyDIoqylJWRweVzxomHvS1urlnqcGspsYzsDHZc3AFAF98uBeZz8eQ1AKrWk9o6IYQQoqKUaOItZ2dnhg8fzrZt2zh//jwvv/wyy5Yto3bt2qVdPlHGYs6dITsrCzsnPc7q5qhm+8ra/r3Re0nKTMLd1p1HKj9SYD4Xw4w1dhLYCSGEEBXnrmZUzczM5ODBg+zbt4/IyEg8PDzufJC4p2jNsLVqoNMB5tZgc2ty4j+j/gSgU7VOmOnyf1wS4lJJvJKGmZlORsQKIYQQFahEgd3WrVsZNmwYHh4eDB48GEdHR9atW8eFCxdKu3yijMVGGOch9PRyM25w8IBc/ej+jv0bgMeqPFZgHpFHjDV9nrX0WNmUaPlhIYQQQpSCYn8LV61alatXrxIYGMjixYvp0aMHNjY2ZVE2UQ6uXDgPQCXnmwMeHG41w15Pu05EQgQAjSs3LjCPiH/iAKjRuFIZlVIIIYQQRVHswG7KlCk8//zzuLhIX6r7XVZmJtcuXQSgkuPNKUxyDZw4cuUIANWdquNs45xvHmlJmdrExDWbVM43jRBCCCHKR7EDu+HDh5dFOUQFiL90EWUwYG1nj6PuhnFjroETh2MPA9DEvUmBeUQevYJS4FbVAadKtmVYWiGEEELcyV0NnhD3tytRkQBUquaLLtnYnJq7xu6fuH+Awpthzx02HldTmmHvedWrV+ezzz4r8fGRkZHodLq7nrty2rRpNGnSRHs9ZMgQevfufVd5lqcOHTrw5ptv3lUewcHBODs7l0p5CrJt2zZ0Oh3Xr18v0/MIIe4tEtg9xOJy+tf5VIeky8aNNycnzjJkacuINancJN/j05IyOX/sKgC1mrnnm0bkpdPpCv2505JiOp2On3/+uVzKmpuPjw/R0dE0bNiwVPOdN29evsurlabSCkrvVfkFm23atCE6Ohq9Xp//QUKIB5IMYXyI3aqxqw5Ra40bbwZ2oZdDSc1KxdHSkZrONfM9/mxoLIZsRSUfB9yqOJRDiR8M0dHR2v9Xr17NlClTCAsL07bZ2t6bTdrm5uZ4enqWer53CjwyMjKwspLVTIrLysqqTN4vIcS9TWrsHmJXom7W2FXzheRY40YHD7IMWcw6MAuAwBqBBc5fF7YvBoB6rb3KvrAPEE9PT+1Hr9ej0+lMtq1YsYJatWphZWWFn58fy5Yt046tXr06AM888ww6nU57HR4eTq9evfDw8MDBwYGWLVuyefPmQsuRkJDA8OHDcXd3x8nJiU6dOvHPP/8UmP72Wq+cpr4tW7bQokUL7OzsaNOmjUmQCvC///0PDw8PHB0dGTp0KGlpaSb7b2+K7dChA2+88Qbjxo2jUqVKdO3aFYATJ07w5JNP4uDggIeHBwMHDuTKlSvacQaDgY8//pjatWtjbW1NtWrVmD59OgA1atQAoGnTpuh0Ojp06KAdFxQUhL+/PzY2NtSrV69I619nZWXxxhtv4OzsjJubG++9957JGsoZGRm8/fbbVKlSBXt7e1q1asW2bdsKzK8o79+XX35JnTp1sLGxwcPDg+eee067f9u3b2fevHlarW9kZGSeptic5t8NGzbg7++Pg4MD3bp1M/lDIysri9GjR2vX9c477zB48GCT90cpxaxZs6hZsya2trY0btyYH3/8Udtf1OdCCFE2JLB7SKWnJHPjqrF/XCV3N0jMWU7MnZWnVnI6/jR6az2jm47O9/jMJB2xkTfQmemo0/LemphaKUVmWlq5/+T+Yi+ptWvXMmbMGMaPH8+xY8cYMWIEL7/8Mlu3bgXgwIEDgDEYiY6O1l4nJSXx5JNPsnnzZg4dOkRgYCA9evQgKiqqwHv01FNPERMTw++//05oaCjNmjWjc+fOXLt2rVhlnjRpErNnz+bgwYNYWFjwyiuvaPt++OEHpk6dyvTp0zl48CBeXl5FCpyWLl2KhYUFu3btYvHixURHR9O+fXuaNGnCwYMHCQkJ4fLly/Tt21c7ZuLEiXz88cdMnjyZEydOsGLFCm3S9P379wOwefNmoqOjWbNmDQBLlixh0qRJTJ8+nZMnTzJjxgwmT57M0qVLi1S+ffv28fnnnzN37ly+/vprbf/LL7/Mrl27WLVqFUeOHOH555+nW7dunDlzJt/87vT+HTx4kNGjR/PBBx8QFhZGSEgI7dq1A4xN2QEBAQwbNozo6Giio6Px8fHJ9zwpKSl8+umnLFu2jB07dhAVFcWECRO0/R9//DHLly8nKCiIXbt2kZiYmKfZ/7333iMoKIiFCxdy/Phxxo4dy0svvcT27dtN0hX2XAghyo40xT6krl40Tibt4OKKzZlfIDsd3Gqj9L58/+drAIxpNgYXm/yntUmLNT46Pv6u2DndW81kWenpfD74uXI/7+ilP2J5l3M6fvrppwwZMoTXX38dgHHjxrF3714+/fRTOnbsSOXKxlHLzs7OJs1sjRs3pnHjW4NcPvroI9auXcuvv/7KG2+8kec8W7du5ejRo8TGxmJtba2d++eff+bHH38s1uj36dOn0759ewD++9//8tRTT5GWloaNjQ2fffYZr7zyCq+++qpWrs2bN+eptbtd7dq1mTVrlvZ6ypQpNGvWjBkzZmjbvv32W3x8fDh9+jReXl7MmzePBQsWMHjwYABq1arFY48ZJ9bOuW9ubm4m9+3DDz9k9uzZ9OnTBzDW7J04cYLFixdr+eTHx8eHuXPnotPp8PPz4+jRo8ydO5dhw4YRHh7OypUruXjxIt7e3gBMmDCBkJAQgoKCTK4hx53ev6ioKOzt7Xn66adxdHTE19eXpk2bAsambCsrK+zs7O7Y9JqZmcmiRYuoVasWAG+88QYffPCBtn/+/PlMnDiRZ555BoAFCxbw+++/a/uTk5OZM2cOf/75JwEBAQDUrFmTnTt3snjxYu05gMKfCyFE2ZHA7iEVH/0vAK7eVWHfIuPGVv/hfNIFLiVfwtLMkqdqPFXg8WlXjY9OtfquZV7Wh8nJkyfzBFVt27Zl3rx5hR6XnJzM+++/z2+//calS5fIysoiNTW1wBq70NBQkpKScHNzM9memppKeHh4scr8yCO31hD28jI2y8fGxlKtWjVOnjzJf/7zH5P0AQEBWg1kQVq0aJGnvFu3bsXBIW9fzvDwcK5fv056ejqdO3cucrnj4uK4cOECQ4cOZdiwYdr2rKysO/b7a926NbpcK7QEBAQwe/ZssrOz+fvvv1FKUbduXZNj0tPT89zvHHd6/7p27Yqvry81a9akW7dudOvWjWeeeQY7O7siXy+AnZ2dFtSB8f2KjTV2w0hISODy5cs8+uij2n5zc3OaN2+OwWAAjM3haWlpWvN4joyMDC3QzFHYcyGEKDsS2D2kciYmdrEzwLVzxvVhG7/I7nO/AtDUvSl2lvl/aWRnGciINwegit+9N1G1hbU1o5f+eOeEZXDe0pA7YABjs+nt22731ltvsWHDBj799FNq166Nra0tzz33HBkZGfmmNxgMeHl55dvvq7jTcFhaWuYpe04gUFL29vYmrw0GAz169ODjjz/Ok9bLy4tz584V+xw5ZVyyZAmtWrUy2Wdubl7s/HLna25uTmhoaJ588gtM4c7vn6OjI3///Tfbtm1j48aNTJkyhWnTpnHgwIFivV+53yswvl+3dyHI7/nLfW0A69evp0qVKibprG97/sviuRBC3JkEdg+pa/8aAzvXzJs1Ok1eAmsH9kTvASDAO6DAY2PP30Bl67BxsMTN277AdBVFp9PddZNoRfH392fnzp0MGjRI27Z79278/f2115aWlmRnZ5sc99dffzFkyBCtCS0pKYnIyMgCz9OsWTNiYmKwsLDQBmCUBX9/f/bu3WtyPXv37i12Ps2aNeOnn36ievXqWFjk/bVVp04dbG1t2bJli9bsm1vOqNrc983Dw4MqVapw7tw5BgwYUKzy3H4Ne/fupU6dOpibm9O0aVOys7OJjY3l8ccfL1J+RXn/LCws6NKlC126dGHq1Kk4Ozvz559/0qdPH6ysrPI8E8Wl1+vx8PBg//79Wrmzs7M5dOiQNu9g/fr1sba2JioqyqTZVQhx75DA7iGlNcUmHzc+BX7dyTRkciDG2Bm/sMDu37B4AKrUdUZnVnhNkiiet956i759+2oDGdatW8eaNWtMRkhWr16dLVu20LZtW6ytrXFxcaF27dqsWbOGHj16oNPpmDx5cqG1I126dCEgIIDevXvz8ccf4+fnx6VLl/j999/p3bt3nqbQkhozZgyDBw+mRYsWPPbYYyxfvpzjx49Ts2b+U+gUZOTIkSxZsoQXX3yRt956i0qVKnH27FlWrVrFkiVLsLGx4Z133uHtt9/GysqKtm3bEhcXx/Hjxxk6dCju7u7Y2toSEhJC1apVsbGxQa/XM23aNEaPHo2TkxPdu3cnPT2dgwcPEh8fz7hx4wosz4ULFxg3bhwjRozg77//Zv78+cyePRuAunXrMmDAAAYNGsTs2bNp2rQpV65c4c8//6RRo0Y8+eSTefK70/v322+/ce7cOdq1a4eLiwu///47BoMBPz8/wPhM7Nu3j8jISBwcHHB1LVkXiVGjRjFz5kxq165NvXr1mD9/PvHx8VqNm6OjIxMmTGDs2LEYDAYee+wxEhMT2b17Nw4ODoX2S8xt//79DBo0iC1btuSp+RNC3B0ZFfsQMmRncz3mEgCuKhos7cDnUY7GHSU5Mxlna2f8Xf0LPP7f09cB8K7rXA6lfbj07t2befPm8cknn9CgQQMWL15MUFCQyfQcs2fPZtOmTfj4+Gj9mubOnYuLiwtt2rShR48eBAYG0qxZswLPo9Pp+P3332nXrh2vvPIKdevW5YUXXiAyMlIbSVoa+vXrx5QpU3jnnXdo3rw558+f57XXXit2Pt7e3uzatYvs7GwCAwNp2LAhY8aMQa/XY2Zm/DU2efJkxo8fz5QpU/D396dfv35a/zELCws+//xzFi9ejLe3N7169QLg1Vdf5euvvyY4OJhGjRrRvn17goODtelRCjJo0CBSU1N59NFHGTlyJKNGjTLpGxkUFMSgQYMYP348fn5+9OzZk3379hU4WvVO75+zszNr1qyhU6dO+Pv7s2jRIlauXEmDBg0A4+AMc3Nz6tevT+XKlQvsW3kn77zzDi+++CKDBg0iICAABwcHAgMDTQY8fPjhh0yZMoWZM2fi7+9PYGAg69atu+M9yy0lJYWwsDAyMzNLVE4hRMF0qjTmaHgIJCYmotfrSUhIwMnJqczPZzAYWLduHT169NC+uEpLfMwlvh0zHAsLM0bX3o6uTld46Ue+P/E9Hx/4mE4+nZjXKf/O+hlpWXwz4S8MWYoXpj6Km1fZT0xc2L1PS0sjIiKCGjVqyGg7IUqZwWDA39+fvn378uGHH1Z0cYR4aBXnu06aYh9C8ZeMzbAutgZ0OqBWJwAuJRtr8ao5FTxq7eLJeAxZCnM7A87u9+YKCUKIkjl//jwbN26kffv2pKens2DBAiIiIujfv39FF00IUUTSFPsQuvavcQ47F7ObE9HW6gjApSRjYOdlX/BKEhFHjTP921bOuuNITSHE/cXMzIzg4GBatmxJ27ZtOXr0KJs3bzYZvCOEuLdJjd1D6FrOwAnLJHCtCZXrAbcCuyoO+XdmVgbF+ZuBnY17VjmUVAhRnnx8fNi1a1dFF0MIcRcksHsIXTlnXLPR1SoFnvgcbta8/ZtkDPi8HbzzPe7y+URSb2RiZWOOtevdTa0ghBBCiNInTbEPGYMhm7io8wB41GsMft0BSMpIIjEjESg4sIs4bKyt86nvik6eHCGEEOKeI1/PD5n4S5fIylZY6rJx6fiaVluXM3BCb63H3jLvpMPKoDh9IAaAWs0ql1+BhRBCCFFkEtg9ZGLPHAOgsk0SuipNtO05/eu87fOvrYsOTyDpWjpWNub4Nsp/vUshhBBCVCwJ7B4yl0+EAuDuCNhX0rbn9K8raOBE2H5jbV3NZu5YWJZ8HU0hhBBClB0J7B4ycRFnAXD3Nm1O1aY6ccg71Ul2poHwUOMM/nUfLb1VCYQQQghRuiSwe4gopbgcY5y7zr2Wn8m+6ORoIP8au7N/x5KekoWDizVV6rqUfUGFEEIIUSIS2D1EEuNiSc80YIaBSv6PAhCVGMXb299m0/lNQP597I5tvwhAg8e9MTOTSYlLy5AhQ9DpdOh0OiwsLKhWrRqvvfYa8fHxWprq1avz2WefmbzOOcbW1pbq1avTt29f/vzzz3zP8dNPP9GpUydcXFyws7PDz8+PV155hUOHDpX15QkhhKgAFRrY7dixgx49euDt7Y1Op+Pnn3822a+UYtq0aXh7e2Nra0uHDh04fvy4SZr09HRGjRpFpUqVsLe3p2fPnly8eNEkTXx8PAMHDkSv16PX6xk4cCDXr18v46u790SfPgFAJZtkzG8OnAg+HswfkX9oaW6f6iQu6gYx5xIxM9Ph3zb/gRWi5Lp160Z0dDSRkZF8/fXXrFu3jtdff73QYz744AOio6MJCwvju+++w9nZmS5dujB9+nSTdO+88w79+vWjSZMm/Prrrxw/fpyvvvqKWrVq8e6775blZQkhhKggFTpBcXJyMo0bN+bll1/m2WefzbN/1qxZzJkzh+DgYOrWrctHH31E165dCQsLw9HREYA333yTdevWsWrVKtzc3Bg/fjxPP/00oaGhmJsbO/n379+fixcvEhISAsDw4cMZOHAg69atK7+LrWhXw7n4xyIAqjqmgbMvAKfjTwPgbudObefa1HSuaXLY8Z3Gvnc1m1XGXm9djgV+OFhbW+Pp6QlA1apV6devH8HBwYUe4+joqB1TrVo12rVrh5eXF1OmTOG5557Dz8+PvXv3MmvWLObNm8fo0aO1Y2vUqEH79u1RSpXZNQkhhKg4FRrYde/ene7du+e7TynFZ599xqRJk+jTpw8AS5cuxcPDgxUrVjBixAgSEhL45ptvWLZsGV26dAHg+++/x8fHh82bNxMYGMjJkycJCQlh7969tGrVCoAlS5YQEBBAWFgYfn5++Z7/gZKRDMFPcyHKC7DDp05tMDPDoAyciT8DwOIui6ntUtvkMINBce6QcdCEf5uC14+91yilUJmGcj+vztLsrtbPPXfuHCEhIVhaWhb72DFjxvDhhx/yyy+/8Pbbb7Ny5UocHBwKrP2TdX6FEOLBdM8uKRYREUFMTAxPPPGEts3a2pr27duze/duRowYQWhoKJmZmSZpvL29adiwIbt37yYwMJA9e/ag1+u1oA6gdevW6PV6du/eXWBgl56eTnp6uvY6MdG4KoPBYMBgKPugIeccpXKuXfNJjY/jWkYt0IH34PkYDAYu3rhISlYKlmaW+Dj65DlXTHiCcQkxW3O8auvzlKk87kNJzqMyDVyasruMSlMw7w/aoLMq3lQwv/32Gw4ODmRnZ5OWlgbAnDlzin1uV1dX3N3diYyMBOD06dPUrFkTC4tbH/E5c+YwZcoU7fW///6LXq8v9rmEEELcu+7ZwC4mxjhvmoeH6fQaHh4enD9/XktjZWWFi4tLnjQ5x8fExODu7p4nf3d3dy1NfmbOnMn777+fZ/sff/yBnZ1d8S7mLqxfv/6ujrfJjKfzidlcTDF+gVvpXdm0/S8ATmaeBKCSrhIh60PyHHv9lDVghblzGr//kbccd1u2okpJSSmX81SEjh07snDhQlJSUvj66685ffo0o0aNKlFeSimTmrjba+VeeeUVevbsyb59+3jppZekOVYIIR5A92xgl+P2L6fbv7zyc6cvuKLkM3HiRMaNG6e9TkxMxMfHh+7du+Pk5FTU4peYwWBg/fr1PPXUU5iZlXyMi+7XN9AZMrigqwtAg9Zt6dCjBwCXjlyCf6C5b3N6tO1hcpxSipWh+4FUHn+qMbWa3QqOS6tsRZVTW1pUOkszvD9oU0alKfy8xWVvb0/t2sYm8M8//5yOHTvy/vvv8+GHHxYrn6tXrxIXF0eNGjUAqFOnDjt37iQzM1Nr2nV2dsbZ2TnP4CIhhBAPjnt2upOczuG316rFxsZqtXienp5kZGSYTA+RX5rLly/nyT8uLi5PbWBu1tbWODk5mfwAmJmZldvPXZ8v5gi6wytQCiJTjatM+DRopO0/c93Yv87PxS/PsYlxaSTEpmJmocO3YaXSL1sJ7kVR6XQ6zKzMy/2nNPqtTZ06lU8//ZRLly4V67h58+ZhZmZG7969AXjxxRdJSkriyy+/vOsyCSGEuH/cs4FdjRo18PT0ZNOmTdq2jIwMtm/fTps2xtqY5s2bY2lpaZImOjqaY8eOaWkCAgJISEhg//79Wpp9+/aRkJCgpXkgKQUb3wMUFz17kXA1HitbW3wfaaolyRk4Udelbp7DY84lAOBZQ4+VzT1fsfvA6NChAw0aNGDGjBkFprlx4wYxMTFcuHCBHTt2MHz4cD766COmT5+u1f4FBAQwfvx4xo8fz7hx49i5cyfnz59n7969fPPNN8bgtxxqW4UQQpSvCv3GTkpK4uzZs9rriIgIDh8+jKurK9WqVePNN99kxowZ1KlThzp16jBjxgzs7Ozo378/AHq9nqFDhzJ+/Hjc3NxwdXVlwoQJNGrUSBsl6+/vT7du3Rg2bBiLFy8GjNOdPP300w/2iNiTv0LkX2Bhw9HU2sB+/Nq0w8rGllPXTvHVka84n2jsq1jXNW9gFxeVBEBlX8fyLLUAxo0bx8svv8w777yT7/4pU6YwZcoUrKys8PT0pHXr1mzZsoWOHTuapPv000959NFHWbhwId9++y0pKSl4eHjQrl079uzZUy5dCoQQQpSvCg3sDh48aPJllNOnbfDgwQQHB/P222+TmprK66+/Tnx8PK1atWLjxo3aHHYAc+fOxcLCgr59+5Kamkrnzp0JDg7W5rADWL58OaNHj9ZGz/bs2ZMFCxaU01VWgMxU2PAeAGktRnLm+8MANOpkvP4Fhxaw/eJ2AOq41MHNxi1PFnFRxn5t7tUksCsrBc1X179/f+2Pl5xRrjluf30nffv2pW/fviUonRBCiPtRhQZ2HTp0KHRknk6nY9q0aUybNq3ANDY2NsyfP5/58+cXmMbV1ZXvv//+bop6fznwDSREgVNVTps1JStzP5WqVcezlrFmLqem7t1W79K7du88fcMMBsWVCzdr7CSwE0IIIe4b0snmQXT65tQlbcdw/tgxAOq2aotOpyPbkM3FJOOoyPZV22NrYZvn8PiYZLIyDVham+PsXn5TuwghhBDi7khg96DJSoeLBwAwVG9H1LF/APB9pAkAsSmxZBmysDCzwMMu/1HBV6JuAFDJxwGdmaxQIIQQQtwvJLB70PwbCllpYO9O7A0daclJWNvZa82wF25cAKCKQxXMzfJfJSH2ZmAnzbBCCCHE/UXmsXjQRO4y/uvbhvNHjbV1Pg0aYXZzMElOYFfVsWqeQzPTs9m/7hyndkcDEtgJIYQQ9xupsXvQRBqXC6P6Y5w/cggA30a35q7L6V9X1SFvYBe2L4bDmy+QkZaNUyUbqtXPO1pWCCGEEPcuqbF7kGRlwAXjRMwZXi35N8y4lmtO/zq4VWPn4+iT5/Dos9cBaNShKo/1rYOZ9K8TQggh7itSY/cgiT0BWalg40xUTCqG7CycPbxw9vTWkhTWFJuz2kT1Rm4S1AkhhBD3Iamxe5DEnTL+69GAc4cOAlCjaQt0Oh03Mm4QlxLHxRvGptjba+xSEjNIvJJmPLyGrEgghBBC3I+kxu5BcjOwU5X8iMgV2J24eoJeP/ei1y+9SMwwrihxex+7yxHG2joXL3us7SzLsdCiogwZMoTevXvfVR7BwcE4OzsXmmbatGk0adKkWPmWpGw6nY6ff/65WMfczx626xVCFI0Edg+SWGNgd0XnTdK1q1hYWZPgrmNIyBDiUuNMktpZmk48HHPOGPB51pTauvJy4cIFhg4dire3N1ZWVvj6+jJmzBiuXr1a0UUrsn79+nH69OlSz3fevHkFLrkmjKKjo+nevTtgXGpOp9Nx+PDhii2UEKLCSWD3IIk7CcC5OOMybVUbNGTyvqmkZqXSyrMVUwOmYmdhxzO1n8lzaE7/Os+a+vIr70Ps3LlztGjRgtOnT7Ny5UrOnj3LokWL2LJlCwEBAVy7dq1Mz5+ZmVkq+dja2uLu7l4qeeWm1+vvWBP4sPP09MTa2rqii1Fqz5IQonRIYPegyEiBeOMasNExxgmGz+njiUyMpLJtZWZ3mM1zdZ9j5ws7eb/N+yaHZmVkExt5s8auhgR25WHkyJFYWVmxceNG2rdvT7Vq1ejevTubN2/m33//ZdKkSQBMnDiR1q1b5zn+kUceYerUqdrroKAg/P39sbGxoV69enz55ZfavpzanB9++IEOHTpgY2Njsnbyp59+ipeXF25ubowcOdLkizojI4O3336bKlWqYG9vT6tWrdi2bZu2P7+m2P/97394eHjg6OjI0KFDSUtLK/b9ub0ptkOHDowePZq3334bV1dXPD09C11DGuCDDz7Aw8NDq8X66aefaNCgAdbW1lSvXp3Zs2ebpK9evTofffQRgwYNwsHBAV9fX3755Rfi4uLo1asXDg4ONGrUiIMHD5oct3v3btq1a4etrS0+Pj6MHj2a5ORkk3xnzJjBK6+8gqOjI9WqVeOrr74qtOzVq1fns88+M9nWpEkTk2vO3RRbo0YNAJo2bYpOp6NDhw558jQYDFStWpVFixaZbP/777/R6XScO3cOgISEBIYPH467uztOTk506tSJf/75R0uf07T+7bffUrNmTaytrVFKodPpWLx4MU8//TR2dnb4+/uzZ88ezp49S4cOHbC3tycgIIDw8HCT8y9cuJBatWphZWWFn58fy5YtM9l/6tQpHnvsMWxsbKhfvz6bN2/O0wz977//0q9fP1xcXHBzc6NXr15ERkZq+3Oep8KedSEeFBLYPSiunAYU2LkRe9E4QGJD2m4ApgRMQW9tDNgszS3R6UxHvF48FU9WpgEHF2tcvO7/tWGVUmRkZJT7j1KqSOW7du0aGzZs4PXXX8fW1nStXk9PTwYMGMDq1atRSjFgwAD27dtn8mV4/Phxjh49yoABAwBYsmQJkyZNYvr06Zw8eZIZM2YwefJkli5dapL3O++8w+jRozl58iSBgYEAbN26lfDwcLZu3crSpUsJDg42aQJ9+eWX2bVrF6tWreLIkSM8//zzdOvWjTNnzuR7bT/88ANTp05l+vTpHDx4EC8vL5MgE2Dbtm3odDqTL96iWLp0Kfb29uzbt49Zs2bxwQcfsGnTpjzplFKMGTOGb775hp07d9KkSRNCQ0Pp27cvL7zwAkePHmXatGlMnjw5T3Pv3Llzadu2LYcOHeKpp55i4MCBDBo0iJdeeom///6b2rVrM2jQIO29Pnr0KIGBgfTp04cjR46wevVqdu7cyRtvvGGS7+zZs2nRogWHDh3i9ddf57XXXuPUqVPFuv7C7N9vnOZo8+bNREdHs2bNmjxpzMzMeOGFF1i+fLnJ9hUrVhAQEEDNmjVRSvHUU08RExPD77//TmhoKM2aNaNz584mtchnz57lhx9+4KeffjJp/v3www8ZNGgQhw8fpl69evTv358RI0YwceJELSDOfW/Wrl3LmDFjGD9+PMeOHWPEiBG8/PLLbN26FTAGo71798bOzo59+/bx1VdfaX/05EhJSaFjx444ODiwY8cOdu7ciYODA926dSMjI0NLd6dnXYgHhYyKfVDcHDiRqvfnxhVjf7p4x0zGNR9HB58OhR567h9j+hqNK+cJ+u5HmZmZzJgxo9zP++6772JlZXXHdGfOnEEphb+/f777/f39iY+PJy4ujoYNG/LII4+wYsUKJk+eDMDy5ctp2bIldesal4n78MMPmT17Nn369AGMtTcnTpxg8eLFDB48WMv3zTff1NLkcHFxYcGCBZibm1OvXj2eeuoptmzZwrBhwwgPD2flypVcvHgRb2/jlDkTJkwgJCSEoKCgfO/xZ599xiuvvMKrr74KwEcffcTmzZtNau3s7Ozw8/PD0rJ4g3Ry11LWqVOHBQsWsGXLFrp27aqlycrKYtCgQRw8eJBdu3ZRtapxkNCcOXPo3Lmzdg/r1q3LiRMn+OSTTxgyZIh2/JNPPsmIESMAmDJlCgsXLqRly5Y8//zzgDE4DggI4PLly3h6evLJJ5/Qv39/3nzzTa1cn3/+Oe3bt2fhwoXY2Nho+b7++utaHnPnzmXbtm3Uq1evWPegIJUrVwbAzc0NT0/PAtMNGDCAOXPmcP78eXx9fTEYDKxatYp3330XMAY/R48eJTY2Vmvm/fTTT/n555/58ccfGT58OGCsyV22bJl23hwvv/wyffv2NblXkydP1v6QGDNmDC+//LKW/tNPP2XIkCHavRk3bhx79+7l008/pWPHjmzcuJHw8HC2bdumXdf06dNN3vNVq1ZhZmbG119/rf3+CgoKwtnZmW3btvHEE08AhT/rQjxIpMbuQRFr7F93WWf8Iku0y+SdxyfxcsOXCzsKg0EReeQKADUaVyrbMooiyakNyvmSGjBggFbLopRi5cqVWm1dXFycNgjDwcFB+/noo4/yNHm1aNEiz7kaNGiAufmtNYO9vLyIjY0FjE10Sinq1q1rkvf27dvz5J3j5MmTBAQEmGy7/fWjjz7KqVOnqFKlSpHvCRgDu9xylzXH2LFj2bNnD3/99ZcW1OWUq23btiZp27Zty5kzZ8jOzs73HB4eHgA0atQoz7ac84aGhhIcHGxyfwIDAzEYDEREROSbr06nw9PTM0/Zy0PTpk2pV68eK1euBGD79u3ExsZqwVhoaChJSUm4ubmZXFNERITJe+7r65snqIOi3b+0tDQSE41dPwp6X06eNP4+CwsLw8fHxyRYffTRR03Sh4aGcvbsWRwdHbXyurq6kpaWZlLmwp51IR4kUmP3IEiNh5PrADiaYvzFdV2fzdM1n77joZfPJZB6IxMrWwu86zqXZSnLjaWlpVYDUd7nLYratWuj0+k4ceJEvlN6nDp1ChcXFypVMgba/fv357///S9///03qampXLhwgRdeeAEwNlWBsTm2VatWJvnk/hIDsLe3v2OZdTqdlqfBYMDc3JzQ0NA8eTk4OBTpWktTYWXN0bVrV1auXMmGDRu04BfQ+oDlll/Tee5z5KTPb1vuezRixAhGjx6dJ69q1aoVq+y5mZmZ5SlfafUHGzBgACtWrOC///0vK1asIDAwUHvWDAYDXl5eJv0oc+TuS5nfswTFv3+5t+XI/V7l977dzmAw0Lx58zxNzIBJ8Fnc90CI+5UEdve77ExY2R+uhYOjF6evGjttO1ermmdKk/yc+8dYW+fb0A1z8wejAlen0xWpSbSiuLm50bVrV7788kvGjh1r0s8uJiaG5cuXM2jQIO0LrWrVqrRr147ly5eTmppKly5dtNoQDw8PqlSpwrlz50wCmdLQtGlTsrOziY2N5fHHHy/SMf7+/uzdu5dBgwZp2/bu3Vuq5SpMz5496dGjB/3798fc3FwLgOvXr8/OnTtN0u7evZu6devmCVqLo1mzZhw/fpzatWvfVblvV7lyZaKjo7XXiYmJJjWAt8t53nPXPhakf//+vPfee4SGhvLjjz+ycOFCbV+zZs2IiYnBwsKC6tWrl/wCisjf35+dO3eaPC+7d+/WuinUq1ePqKgoLl++rD3zBw4cMMmjWbNmrF69WhvsIcTD7sH4Jn+YndsGUbvByhHV//9IjjYGao0atLnjoUopIg4b+9fVbJK3WUWUnQULFpCenk5gYCA7duzgwoULhISE0LVrV6pUqcL06dNN0g8YMIBVq1bxf//3f7z00ksm+6ZNm8bMmTOZN28ep0+f5ujRowQFBTFnzpy7KmPdunUZMGAAgwYNYs2aNURERHDgwAE+/vhjfv/993yPGTNmDN9++y3ffvstp0+fZurUqRw/ftwkzf79+6lXrx7//vvvXZWvIM888wzLli3j5Zdf5scffwRg/PjxbNmyhQ8//JDTp0+zdOlSFixYwIQJE+7qXO+88w579uxh5MiRHD58mDNnzvDrr78yatSou8q3U6dOLFu2jL/++otjx44xePDgQgNQd3d3bG1tCQkJ4fLlyyQkJBSYtkaNGrRp04ahQ4eSlZVFr169tH1dunQhICCA3r17s2HDBiIjI9m9ezfvvfdentHApeGtt94iODiYRYsWcebMGebMmcOaNWu096Vr167UqlWLwYMHc+TIEXbt2qUNnsjdVaFSpUr06tWLv/76i4iICLZv386YMWO4eHMgWVFMnDjRJMAU4n4lgd397ppxigJqdeCMmQV2xplO6NC8xx0Pjf//9u48Oooy3//4u7rT3Uk6SWchCwESdggEBFFAREDFBQRkHHcv6oh6VURwuY781Bn1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3G53q1xHRESkvTslnrFraGggMjKSN954g1/84hfB7bNmzSIrK4sVK1Y0O+ZgPXbdunWjvLz8uJ/zqq6uJicnh7KyMsrLy6moqKC4uPiIjw8PDyc6OjoY8GJjYykrK6OysrLFYzIzM5kwYQIRERHHVTs09qB98MEHXHLJJa22pFhcXJyesRMRETmMU6LHzm63M2zYMJYtW9Yk2C1btoxLL730oMc4HI6D9nJZLJbjDjMul4vhw5vOb1dRUcGOHTuCt1LLysrYvn07Y8aMwePxkJWVRW5uLiNGjOC8884jLKz5r66srIzc3FzcbjeGYeD1etm1axd5eXls2rSJvLw8rrzyyqMeBdySE/FdHOl1RERE5PBOiWAHcM899zBt2jTOOOMMzjrrLP73f/+XXbt2cdttt4W6NKCx123YsGHB94FAgIqKCnr16oXFYiEzM5NAIHDIkBMfH098fHyz7Xv37uWdd95h//79LFq0iOHDh9O7d2969uyp0CQiItKBnDLB7qqrrqK0tJTHHnuMwsJCMjMzWbp0Kenp6aEu7Ygdawjr0qULt956K0uWLCE7O5vVq1ezevVqkpOTOeecc+jXrx82m+3wJxIREZE27ZQJdgB33HEHd9xxR6jLCAm73c4VV1zBli1b2LZtG9nZ2RQXF/Pmm29it9sZNWoUZ599tgKeiIhIO3ZKBbtTnWEYDBgwgAEDBnDBBRewevVqvvvuOyorK1m+fDnr1q1j8ODB1NfX4/f7ueiii07IYAsRERFpHQp2p6jIyEjOO+88zj33XDZv3szHH39MdXU1X331VbBNdXU11157bausLiEiIiLHT8HuFGcYBpmZmfTr14+cnBxycnKIiIhgw4YN7Nixg3/+859ccsklBx2FKyIiIm2L/loLADabjczMTDIzMwHo3r07r7/+Ohs2bKCkpISrrrpKc8iJiIi0cZrrQg5qwIABXHPNNYSHh7N3714WLFhwVJMoi4iISOtTj520qF+/ftx66628+uqrlJWV8eKLL9K5c2cyMjKarMohIiIibYN67OSQ4uPjmT59Or179wagsLCQzz77jOzsbN58803y8vIIBAIhrlJERERAPXZyBJxOJ//xH/9BTU0NP/zwQ3B5suzsbLKzs3G5XAwePJihQ4cedOULERERaR0KdnLEoqKiOOOMMzj99NN5/fXXiYiIIDs7m8rK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XXffvn3NegNFRETk+CnYtQEul4vExES2bdvGt99+y6WXXtqszYIFC5gyZQqJiYmHPd+GDRsA6Ny580H3m6bJnXfeydtvv81nn33WLEj26NGDlJQUli1bFtzW0NDAihUrgreBhw0bhs1ma9KmsLCQTZs2BducddZZVFZW8s033wTbrFmzhsrKyma3k0VEROT46VbsSVRTU9Ok1yw3N5esrCzi4+NJS0vjjTfeIDExkbS0NDZu3MisWbOYOnVqkwEJ0Njz9sUXX7B06dJm11i1ahWrV6/m3HPPxeVysXbtWu6++26mTJlCWlraQeuaMWMGr732Gu+++y7R0dHBnjmXy0VERASGYTB79mzmzp1Lnz596NOnD3PnziUyMpJrr7022Hb69Once++9JCQkEB8fz3333cegQYMYP348ABkZGVx88cXccsstvPzyywDceuutTJo0iX79+h3/FywiIiJNhXRMbgf3+eefm0Cz1w033GCapmk+88wzZteuXU2bzWampaWZDz30kOnxeJqdZ86cOWbXrl1Nv9/fbN+6devMESNGmC6XywwPDzf79etn/va3vzVra2tbrOtgNQHmwoULg20CgYD529/+1kxJSTEdDoc5ZswYc+PGjU3OU1dXZ955551mfHy8GRERYU6aNMnctWtXkzalpaXmddddZ0ZHR5vR0dHmddddZ5aXlx/5lygiIiJHzDBN0wxRphQRERGRE0jP2ImIiIh0EAp2IiIiIh2Egp2IiIhIB6FgJyIiItJBKNiJiIiIdBAKdiIiIiIdhIKdiIiISAehYCciIiLSQSjYdXA33ngjU6dOPa5zLF++HMMwqKioOCE1iYiIyMmhtWI7uGeeeQYtLiIiInJqULDroPx+P4Zh4HK5Ql2KiIiItBLdim0jxo0bx5133smdd95JbGwsCQkJPPTQQ8HetoaGBu6//366dOmC0+lkxIgRLF++PHj8okWLiI2N5Z///CcDBgzA4XCQn5/f7Fasx+PhrrvuIikpifDwcEaPHs3atWub1LJ06VL69u1LREQE5557Lnl5eU325+fnM3nyZOLi4nA6nQwcOJClS5eerK9GREREjpCCXRvyyiuvEBYWxpo1a3j22Wd56qmnmD9/PgC/+tWv+Oqrr1i8eDHff/89V1xxBRdffDHbtm0LHu92u5k3bx7z589n8+bNJCUlNbvG/fffz1tvvcUrr7zC+vXr6d27NxdddBFlZWUA7N69m8suu4yJEyeSlZXFzTffzAMPPNDkHDNmzMDj8fDFF1+wceNGnnjiCaKiok7iNyMiIiJHxJQ2YezYsWZGRoYZCASC237961+bGRkZ5vbt203DMMy9e/c2Oeb8888358yZY5qmaS5cuNAEzKysrCZtbrjhBvPSSy81TdM0a2pqTJvNZv7tb38L7m9oaDBTU1PNJ5980jRN05wzZ85B6wDM8vJy0zRNc9CgQeYjjzxywj67iIiInBh6xq4NGTlyJIZhBN+fddZZ/PGPf+Tbb7/FNE369u3bpL3H4yEhISH43m63M3jw4BbPv2PHDrxeL2effXZwm81mY/jw4WzZsgWALVu2HLSOn7rrrru4/fbb+eSTTxg/fjy//OUvD3ldERERaR0Kdu2E1Wpl3bp1WK3WJtt/egs0IiKiSSD7OfPA83o/b2OaZnCbeQQjaG+++WYuuugiPvjgAz755BPmzZvHH//4R2bOnHnEn0dEREROPD1j14asXr262fs+ffowdOhQ/H4/JSUl9O7du8krJSXliM/fu3dv7HY7K1euDG7zer18++23ZGRkADBgwICD1vFz3bp147bbbuPtt9/m3nvv5c9//vPRfFQRERE5CRTs2pDdu3dzzz33kJOTw9///neee+45Zs2aRd++fbnuuuu4/vrrefvtt8nNzWXt2rU88cQTRzUa1el0cvvtt/Nf//VffPTRR2RnZ3PLLbfgdruZPn06ALfddhs7duwI1vHaa6+xaNGiJueZPXs2H3/8Mbm5uaxfv57PPvssGAxFREQkdHQrtg25/vrrqaurY/jw4VitVmbOnMmtt94KwMKFC3n88ce599572bt3LwkJCZx11llMnDjxqK7x+9//nkAgwLRp06iuruaMM87g448/Ji4uDoC0tDTeeust7r77bl544QWGDx/O3Llzuemmm4Ln8Pv9zJgxgz179hATE8PFF1/MU089deK+CBERETkmhnkkD1XJSTdu3DiGDBnC008/HepSREREpJ3SrVgRERGRDkLBTkRERKSD0K1YERERkQ5CPXYiIiIiHYSCnYiIiEgHoWAnIiIi0kEo2ImIiIh0EAp2IiIiIh2Egp2IiIhIB6FgJyIiItJBKNiJiIiIdBAKdiIiIiIdxP8HJ7+Pap+OrQgAAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "table.plot()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Variable\n", "\n", "*Variables* are series of numbers.\n", "\n", "All *variables* from the \"*variables*\" workspace are defined over the same range of periods (sample). \n", "If observations are missing, they take the special value `NA` (Not Available) \n", "(displayed as `--` in the graphical user interface).\n", "\n", "Their names must be in uppercase so that *variables* are distinct from *scalars* in *LEC* formulas.\n", "\n", "There is no `Variable` class in the Python `iode` library. Instead, a *variable* is represented by a subset of the *variables* workspace with one unique *variable*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Computed Tables\n", "\n", "To compute a table according to a *generalized sample* and *extra files*, use the [Table.compute](../_generated/iode.Table.compute.rst#iode.Table.compute) method of the IODE table objects:\n", "\n", "Calling `compute(generalized_sample, extra_files, nb_decimals, quiet)` computes the values corresponding to LEC expressions in cells.\n", " \n", "The values are calculated for given a *generalized sample*. This sample contains the following information:\n", " \n", " * the sampling of the periods to take into account \n", " * the operations to be performed on the periods\n", " * the list of files involved in the computation of the table\n", " * the operations to be performed between files\n", " * the repetition factor\n", " \n", "The syntax of the *generalized sample* follows the rules described below. The syntax of a period: \n", " \n", " * a period is indicated as in LEC: `yyPpp` or `yyyyPpp` where *yyyy* indicates the year, \n", " *P* the periodicity and *pp* the sub-period (e.g. 1990Y1) \n", " * a period can be shifted n periods to the left or right using the operators `n` \n", " * when used with a zero argument, the shift operators have a special meaning: \n", " - `<0` means \"first period of the year\" \n", " - `>0` means \"last period of the year\" \n", " * the special periods 'BOS', 'EOS' and 'NOW' can be used to represent the beginning \n", " or end of the current sample or the current period (PC clock)\n", " * the special periods 'BOS1', 'EOS1' and 'NOW1' are equivalent to the previous ones, \n", " except that they are moved to the first sub-period of the year of 'BOS', 'EOS' and \n", " 'NOW' respectively (if NOW = 2012M5, NOW1 = 2012M1)\n", " * each period is separated from the next by a semicolon \n", " * a period or group of periods can be repeated: simply place the colon character (`:`) after \n", " the definition of the column or group of columns, followed by the desired number of repetitions. \n", " Repetitions are made with an increment of one period, unless followed by an asterisk and a value. \n", " This value is then the repeat increment. It can be negative, in which case the periods are \n", " presented in decreasing order\n", " * the repeat, increment and shift can be the words PER (or P) or SUB (or S), which respectively indicate \n", " the number of periods in a year of the current sample and the current sub-period\n", " * the file definition is optional and is enclosed in square brackets. \n", " It applies to all preceding period definitions.\n", " \n", "The following file operations are possible:\n", " \n", " * absolute value: [1] \n", " * difference: [1-2] \n", " * difference in percent: [1/2] \n", " * sum: [1+2] \n", " * average: [1~2] or [1^2]. \n", " \n", "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:\n", " \n", " * value: (75) \n", " * growth rate over one or more periods: (75/74, 75/70) \n", " * average growth rate: (75//70) \n", " * difference: (75-74, 75-70) \n", " * average difference: (75--70) \n", " * average: (75~74) or (75^74) \n", " * sum of consecutive periods: (70Q1+70Q4) \n", " * index or base value: (76=70) \n", " \n", "Repetition can be performed with an increment greater than 1 or less than 0: \n", "simply place a star followed by the step after the number of repetitions (70:3*5 = 70, 75, 80).\n", " \n", "Generalized sample examples:\n", "\n", "```\n", "70; 75; 80:6 = 70:3*5; 81:5 = 70; 75; 80; 81; 82; 83; 84; 85\n", "70/69:2 = 70/69; 71/70\n", "(70; 70-69):2 = 70; 70-69; 71; 71-70;\n", "70[1,2]:2*5 = 70[1]; 70[2]; 75[1]; 75[2]\n", "(70;75)[1,2-1] = 70[1]; 75[1]; 70[2-1]; 75[2-1]\n", "(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]\n", "2000Y1>5 = 2005Y1\n", "1999M1>12 = 2000M1\n", "EOS<1 = 2019Y1 (if EOS == 2020Y1)\n", "BOS<1 = 1959Y1 (if BOS == 1960Y1)\n", "EOS<4:5*-1 =2016;2017;2018;2019;2020 (if EOS = 2020Y1)\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Examples" ] }, { "cell_type": "code", "execution_count": 64, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DIVIS | 1 | \n", "TITLE | \"Table example with titles on the left and LEC expressions on the right\"\n", "----- | ------------------------------------------------------------------------\n", "CELL | | \"#S\" \n", "----- | ------------------------------------------------------------------------\n", "CELL | \"GOSG:\" | GOSG\n", "CELL | \"YDTG:\" | YDTG\n", "CELL | \"DTH:\" | DTH\n", "CELL | \"DTF:\" | DTF\n", "CELL | \"IT:\" | IT\n", "CELL | \"YSSG+COTRES:\" | YSSG+COTRES\n", "CELL | \"RIDG:\" | RIDG\n", "CELL | \"OCUG:\" | OCUG\n", "----- | ------------------------------------------------------------------------\n", "MODE | \n", "FILES | \n", "DATE | \n", "\n", "nb lines: 16\n", "nb columns: 2\n", "language: 'ENGLISH'\n", "gridx: 'MAJOR'\n", "gridy: 'MAJOR'\n", "graph_axis: 'VALUES'\n", "graph_alignment: 'LEFT'" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "table_title = \"Table example with titles on the left and LEC expressions on the right\"\n", "# left column\n", "lines_titles = [\"GOSG:\", \"YDTG:\", \"DTH:\", \"DTF:\", \"IT:\", \"YSSG+COTRES:\", \"RIDG:\", \"OCUG:\"]\n", "# right column\n", "lines_lecs = [\"GOSG\", \"YDTG\", \"DTH\", \"DTF\", \"IT\", \"YSSG+COTRES\", \"RIDG\", \"OCUG\"]\n", "table = Table(2, table_title, lines_lecs, lines_titles, True, True, True)\n", "table" ] }, { "cell_type": "code", "execution_count": 65, "metadata": {}, "outputs": [ { "data": { "text/plain": [ " line title \\ period[file] | 2000 | 2001 | 2002 | 2003 | 2004 | 2005 \n", "----------------------------------------------------------------------------------------------------\n", "GOSG: | 32.7013 | 34.5183 | 35.9341 | 37.3602 | 39.0778 | 40.6990\n", "YDTG: | 1841.7930 | 1913.4770 | 1999.8462 | 2042.4147 | 2097.7328 | 2094.7998\n", "DTH: | 1477.3851 | 1539.1702 | 1614.1974 | 1661.0073 | 1697.6353 | 1690.1593\n", "DTF: | 364.4079 | 374.3072 | 385.6475 | 381.4071 | 400.0916 | 404.6382\n", "IT: | 1146.7131 | 1202.9021 | 1242.0110 | 1288.0103 | 1342.8635 | 1401.3764\n", "YSSG+COTRES: | 1680.2238 | 1752.5931 | 1818.5073 | 1891.1969 | 1932.6684 | 1970.2945\n", "RIDG: | 98.7683 | 104.2563 | 108.5322 | 112.8396 | 118.0272 | 122.9238\n", "OCUG: | -120.7692 | -127.4797 | -132.7081 | -137.9749 | -144.3181 | -150.3054" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# simple time series (current workspace) - 6 observations - 4 decimals\n", "computed_table = table.compute(\"2000:6\", nb_decimals=4)\n", "computed_table" ] }, { "cell_type": "code", "execution_count": 66, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['GOSG:', 'YDTG:', 'DTH:', 'DTF:', 'IT:', 'YSSG+COTRES:', 'RIDG:', 'OCUG:']" ] }, "execution_count": 66, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get lines of the computed table\n", "computed_table.lines" ] }, { "cell_type": "code", "execution_count": 67, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['2000', '2001', '2002', '2003', '2004', '2005']" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get columns of the computed table\n", "computed_table.columns" ] }, { "cell_type": "code", "execution_count": 68, "metadata": {}, "outputs": [ { "data": { "text/plain": [ " line title \\ period[file] | 2010 | 2010/2009 | 2011 | 2011/2010 | 2012 | 2012/2011 | 2013 | 2013/2012 | 2014 | 2014/2013\n", "------------------------------------------------------------------------------------------------------------------------------------------\n", "GOSG: | 47.36 | 2.40 | 48.81 | 3.07 | 50.73 | 3.94 | 53.07 | 4.62 | 55.74 | 5.02\n", "YDTG: | 2456.29 | 3.16 | 2554.61 | 4.00 | 2681.32 | 4.96 | 2832.01 | 5.62 | 2998.33 | 5.87\n", "DTH: | 1999.96 | 3.38 | 2083.70 | 4.19 | 2193.41 | 5.26 | 2326.45 | 6.07 | 2477.09 | 6.47\n", "DTF: | 456.33 | 2.17 | 470.90 | 3.19 | 487.91 | 3.61 | 505.56 | 3.62 | 521.24 | 3.10\n", "IT: | 1688.71 | 2.49 | 1752.86 | 3.80 | 1830.30 | 4.42 | 1918.71 | 4.83 | 2012.81 | 4.90\n", "YSSG+COTRES: | 2370.44 | 2.94 | 2448.77 | 3.30 | 2551.46 | 4.19 | 2680.09 | 5.04 | 2824.22 | 5.38\n", "RIDG: | 143.04 | 2.40 | 147.42 | 3.07 | 153.22 | 3.94 | 160.30 | 4.62 | 168.34 | 5.02\n", "OCUG: | -174.90 | 2.40 | -180.26 | 3.07 | -187.36 | 3.94 | -196.01 | 4.62 | -205.84 | 5.02" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# two time series (current workspace) - 5 observations - 2 decimals (default)\n", "computed_table = table.compute(\"(2010;2010/2009):5\")\n", "computed_table" ] }, { "cell_type": "code", "execution_count": 69, "metadata": {}, "outputs": [ { "data": { "text/plain": [ " line title \\ period[file] | 2010[1] | 2010[2] | 2011[1] | 2011[2] | 2012[1] | 2012[2] | 2013[1] | 2013[2] | 2014[1] | 2014[2]\n", "--------------------------------------------------------------------------------------------------------------------------------\n", "GOSG: | 47.36 | 47.36 | 48.81 | 48.81 | 50.73 | 50.73 | 53.07 | 53.07 | 55.74 | 55.74\n", "YDTG: | 2456.29 | 2456.29 | 2554.61 | 2554.61 | 2681.32 | 2681.32 | 2832.01 | 2832.01 | 2998.33 | 2998.33\n", "DTH: | 1999.96 | 1999.96 | 2083.70 | 2083.70 | 2193.41 | 2193.41 | 2326.45 | 2326.45 | 2477.09 | 2477.09\n", "DTF: | 456.33 | 456.33 | 470.90 | 470.90 | 487.91 | 487.91 | 505.56 | 505.56 | 521.24 | 521.24\n", "IT: | 1688.71 | 1688.71 | 1752.86 | 1752.86 | 1830.30 | 1830.30 | 1918.71 | 1918.71 | 2012.81 | 2012.81\n", "YSSG+COTRES: | 2370.44 | 2370.44 | 2448.77 | 2448.77 | 2551.46 | 2551.46 | 2680.09 | 2680.09 | 2824.22 | 2824.22\n", "RIDG: | 143.04 | 143.04 | 147.42 | 147.42 | 153.22 | 153.22 | 160.30 | 160.30 | 168.34 | 168.34\n", "OCUG: | -174.90 | -174.90 | -180.26 | -180.26 | -187.36 | -187.36 | -196.01 | -196.01 | -205.84 | -205.84" ] }, "execution_count": 69, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from pathlib import Path\n", "\n", "# simple time series (current workspace + one extra file) - 5 observations - 2 decimals (default)\n", "sample_data_dir = Path(SAMPLE_DATA_DIR)\n", "computed_table = table.compute(\"2010[1;2]:5\", extra_files=sample_data_dir/\"ref.av\", quiet=True)\n", "computed_table" ] }, { "cell_type": "code", "execution_count": 70, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['c:\\\\soft\\\\miniconda3\\\\Lib\\\\site-packages\\\\iode\\\\tests\\\\data\\\\fun.var',\n", " 'C:\\\\soft\\\\miniconda3\\\\Lib\\\\site-packages\\\\iode\\\\tests\\\\data\\\\ref.av']" ] }, "execution_count": 70, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get the list of files used to compute the table \n", "# (the first file represents the current workspace)\n", "computed_table.files" ] }, { "cell_type": "code", "execution_count": 71, "metadata": {}, "outputs": [ { "data": { "text/plain": [ " line title \\ period[file] | 2010[1] | 2010[2] | 2010[3] | 2010[4] | 2010[5]\n", "------------------------------------------------------------------------------\n", "GOSG: | 47.36 | 47.36 | 47.36 | 47.36 | --\n", "YDTG: | 2456.29 | 2456.29 | 2456.29 | 2456.29 | --\n", "DTH: | 1999.96 | 1999.96 | 1999.96 | 1999.96 | --\n", "DTF: | 456.33 | 456.33 | 456.33 | 456.33 | --\n", "IT: | 1688.71 | 1688.71 | 1688.71 | 1688.71 | --\n", "YSSG+COTRES: | 2370.44 | 2370.44 | 2370.44 | 2370.44 | --\n", "RIDG: | 143.04 | 143.04 | 143.04 | 143.04 | --\n", "OCUG: | -174.90 | -174.90 | -174.90 | -174.90 | --" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# simple time series (current workspace + 4 extra files) - 5 observations - 2 decimals (default)\n", "extra_files = [sample_data_dir / \"ref.av\", sample_data_dir / \"fun.av\", \n", " sample_data_dir / \"fun2.av\", sample_data_dir / \"a.var\"]\n", "computed_table = table.compute(\"2010[1;2;3;4;5]:1\", extra_files=extra_files, quiet=True)\n", "computed_table" ] }, { "cell_type": "code", "execution_count": 72, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['c:\\\\soft\\\\miniconda3\\\\Lib\\\\site-packages\\\\iode\\\\tests\\\\data\\\\fun.var',\n", " 'C:\\\\soft\\\\miniconda3\\\\Lib\\\\site-packages\\\\iode\\\\tests\\\\data\\\\ref.av',\n", " 'C:\\\\soft\\\\miniconda3\\\\Lib\\\\site-packages\\\\iode\\\\tests\\\\data\\\\fun.av',\n", " 'C:\\\\soft\\\\miniconda3\\\\Lib\\\\site-packages\\\\iode\\\\tests\\\\data\\\\fun2.av',\n", " 'c:\\\\soft\\\\miniconda3\\\\Lib\\\\site-packages\\\\iode\\\\tests\\\\data\\\\a.var']" ] }, "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get the list of files used to compute the table\n", "# (the first file represents the current workspace)\n", "computed_table.files" ] }, { "cell_type": "code", "execution_count": 73, "metadata": {}, "outputs": [ { "data": { "text/plain": [ " line title \\ period[file] | 2000[1] | 2002[1] | 2004//2003[1] | 2006[1] | 2006[2] | 2008[1+2] | 2010/2009[1^2]\n", "-----------------------------------------------------------------------------------------------------------------\n", "GOSG: | 32.70 | 35.93 | 4.60 | 41.58 | 41.58 | 89.12 | 2.40\n", "YDTG: | 1841.79 | 1999.85 | 2.71 | 2114.74 | 2114.74 | 4601.22 | 3.16\n", "DTH: | 1477.39 | 1614.20 | 2.21 | 1682.03 | 1682.03 | 3712.45 | 3.38\n", "DTF: | 364.41 | 385.65 | 4.90 | 432.72 | 432.72 | 888.77 | 2.17\n", "IT: | 1146.71 | 1242.01 | 4.26 | 1450.29 | 1450.29 | 3185.22 | 2.49\n", "YSSG+COTRES: | 1680.22 | 1818.51 | 2.19 | 2035.67 | 2035.67 | 4472.09 | 2.94\n", "RIDG: | 98.77 | 108.53 | 4.60 | 125.59 | 125.59 | 269.19 | 2.40\n", "OCUG: | -120.77 | -132.71 | 4.60 | -153.56 | -153.56 | -329.15 | 2.40" ] }, "execution_count": 73, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# multiple patterns (current workspace + 1 extra file) - 6 observations - 2 decimals (default)\n", "extra_files = sample_data_dir / \"ref.av\"\n", "generalized_sample = \"2000;2002;2004//2003;2006[1;2];2008[1+2];2010/2009[1^2]\"\n", "computed_table = table.compute(generalized_sample, extra_files)\n", "computed_table" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Plotting\n", "\n", "To plot a computed table, you can use the [plot](../_generated/iode.ComputedTable.plot.rst#iode.ComputedTable.plot) method of the IODE table objects:" ] }, { "cell_type": "code", "execution_count": 74, "metadata": {}, "outputs": [ { "data": { "image/png": "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6XFD+g0oPl2McUPGobu+u8tAvERE1L6xZ5T8obm/d34NdaNGjYIQDd9OavPmzU2uIzg4GCtXrsTKlSsbLBMdHY133323RXX0psdHPI7MzExc3f1qfjAQERGRVzFZEBEREQUAhjoiIqJOIC8vD/PmzUN6ejqCg4ORkJCAyy+/HK+99prTFb07duzA1VdfjaioKAQHB2PgwIF4/vnnXYZx+e677zB69GhER0cjNDQUGRkZmDVrFmpq6obdEkIod3GKjIxEeHg4+vfvj3nz5jmdU0/ewVBHREQU4P744w8MHjwYW7ZswbJly7B37158/fXXePjhh5GZmYmvv/4aAPDJJ59g5MiR6Nq1K7777jscOXIE8+bNw9KlS/GnP/1JOWXq4MGDmDRpEi655BJs374dBw4cwMqVK6HVapUBnIUQmDFjBubOnYurr74aW7Zswf79+/Hyyy8jJCQETz/9tN/aI1AF1rgYRERE5OL++++HRqPB7t27ERYWpkwfOHAgbrjhBtug95WVuPvuuzF16lSsWbNGKXPXXXchISEBU6dOxb///W/cfPPN2Lp1K5KSkpThwwCgZ8+emDhxovJ+w4YNWL9+PT777DNMnTpVmd6jRw+MGTOm0XPqqWXYU0dERNQCQghUmWv88vAkEBUWFmLLli144IEHnAKdI0mSsGXLFhQWFmLRokUu86dMmYJevXrhgw8+AGAb2D83Nxfbt29vcLsffPABevfu7RTo6m+z1rZt2yBJErKyspq9X+SKPXVEREQtYLRY0e/xpkdpaAuHnpqA0KDmfYX//vvvEEK4jM0aGxuL6upqAMADDzyA6OhoALbxXd3p06cPjh2z3VbypptuwubNmzFy5EgkJiZi+PDhGDNmDG677TblrkvHjh1z2eb8+fPxxhtvAAAMBgNOnz4NwHbHhN69e0Or1TZrn8g99tQRERF1AvXvgPHzzz9j37596N+/P0wmkzK9oV5Ax3umq9VqrF27FqdPn8by5cuRnJyMpUuXon///sjNzW1wm4899hj27duHxx9/HBUVFcr0oUOH4siRI+jSpUur97MzY08dERFRC4Ro1Tj01AS/bbu50tPTIUkSjhw54jS9R48etnWFhAAAevXqBQA4fPiw29toHjlyBP369XOa1qVLF8ycORMzZ87E008/jV69euG1117Dk08+iYyMDJdtxsXFIS4u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5ZX4448/8M033+CGG27AwYMHccUVV+Dvf/+70zYce+NiYmKwb98+7Nu3DwaDAWazWZnXv39/hIeHIzw8HP379wcA5b3jNMDWI9rSXj7HddSvX3O88MIL2LdvH7Zu3YoLL7wQL7zwgtv73P/www/Kvu7btw+bN29W5jWn7R588EF88803Ldy7OuypIyIiagGNToe5b33ot223aDmNBhqN+6/+AQMGYMCAAXjggQfw448/4oorrsD333+P0aNHAwC0Wi2uuOIKXHHFFfjLX/6Cp59+Gk899RQeffRRZGRkAACOHDmCCy+8EACgVquVAFR/m19++SUsFgsA4MyZMxg1ahT27dunzHc8xNmrVy8cPny40f2Ki4uDwWBwurjD0ZEjRyBJkse9YYmJiUhPT0d6ejr+7//+D4MHD8aQIUPQr18/p3Ldu3eHwWBocD2NtV1QUJBHdWoMe+qIiIhaQJIkaIOD/fJobc9VU2pDS2VlZaNlampqUF1djcGDB6NPnz745z//qfTuNSY1NVUJS6mpqQCgvHecBgAzZszAsWPH8Nlnn7msRwiB0tJSqFQqTJ8+He+//74ylEgto9GIVatWYcKECYiOjm7W/ruTnp6OG264AYsXL27xOmo5tp03MdQRERF1Yvfddx/+/ve/4z//+Q+ys7Oxa9cu3HbbbYiLi8OIESMAAKNGjcLq1auxZ88eZGVl4csvv8Rf//pXjB49GpGRkcrQKUePHsVll12Gzz//HMePH1eGMzl//jzUanWL6jd9+nTcfPPNuOWWW/DMM89g9+7dyM7OxhdffIGxY8fiu+++AwAsXboUiYmJGDduHL766ivk5ORg+/btmDBhAiwWC/71r3+1uq0WLlyIzMxM7N6922l6fn4+8vLynB61PZFNtR0AvPLKKxgzZkyr68dQR0RE1ImNHTsWu3btwk033YRevXrhhhtuQHBwML755hvExMQAACZMmIC33noL48ePR9++ffHQQw9hwoQJ+Pe//62sZ/jw4dizZw969+6NBx54AP369cOll16KDz74AC+88ALuu+++FtVPkiS8//77WLFiBT755BOMHDkSF1xwAZYsWYJp06YpY8bFxsZi165dGD16NO655x706NED06dPR48ePfDLL784XbTRUgMHDsTYsWPx+OOPO03v3bs3kpKSnB579uwB0Ly2KygowIkTJ1pd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ZPjw4QCA33//3Sv7QOQXvj2Fr2OTZVk88MADIjk5WRw7dszt/MTERPHcc88p00wmk9uTeDds2KCUOXv2rNsLJX766SelzK5du9rlhRK+ahNH7f1CCV+2yenTp0VGRob405/+5PZqx/bCH78ntU6dOiUAiO+++857O+QFvmqT7OxsceDAAeWxefNmAUB8+OGHIicnp4330jP+/D3JzMwUAER2drYX94jItxjqPHDfffcJvV4vtm3b5nQZfFVVlVLm2WefFXq9Xnz88cfiwIED4pZbbnF7uX3Xrl3F119/LX799Vdx1VVXuR3S5IILLhA7d+4UO3fuFAMHDmyXQ5r4sk2ys7PF3r17xZNPPinCw8PF3r17xd69e9vdMAS+apMzZ86I9PR0cdVVV4nTp087bau98VWb/PTTT2LlypVi7969IisrS3z77bfi8ssvFz179hTV1dU+3+/G+PL/jqOTJ0+226tffdUmO3bsECtWrBB79+4Vf/zxh9iwYYNITk4WU6dO9fk+E3kTQ50HALh9rF27Vikjy7J44oknRGJiotDpdOLKK68UBw4ccFqP0WgUDz74oIiOjhYhISFi8uTJ4tSpU05lCgsLxa233ioiIiJERESEuPXWW0VxcbEP9tIzvmyTWbNmud1We+uB8VWbrF27tsFttTe+apP9+/eL0aNHi+joaKHT6URaWpq49957xenTp321q83my/87jtpzqPNVm+zZs0cMGzZM6PV6ERwcLHr37i2eeOIJUVlZ6atdJWoTkhBCePNwLhERERH5Hi+UICIiIgoADHVEREREAYChjoiIiCgAMNQRERERBQCGOiIiIqIAwFBHREREFAAY6oiIiIgCAEMdERERUQBgqCMiF7Nnz8a1117bqnVs27YNkiShpKTEK3UiIqLGafxdASJqf1566SXwZjNERB0LQx0RKaxWKyRJgl6v93dViIjIQzz8StSBjRo1Cg8++CAefPBBGAwGxMTE4G9/+5vSy2Y2m/HII4+gS5cuCAsLw7Bhw7Bt2zZl+XXr1sFgMOCLL75Av379oNPpkJ2d7XL41WQyYe7cuYiPj0dwcDAuv/xy/PLLL051+fLLL9GrVy+EhIRg9OjRyMrKcpqfnZ2NKVOmICoqCmFhYejfvz++/PLLtmoaIqJOh6GOqIN76623oNFo8NNPP+Hll1/GCy+8gDfeeAMAcPvtt+M///kP1q9fj/379+Omm27CxIkTcfz4cWX5qqoqPPPMM3jjjTdw8OBBxMfHu2zjkUcewUcffYS33noLv/76K9LT0zFhwgQUFRUBAHJycnD99dfj6quvxr59+3DXXXfhL3/5i9M6HnjgAZhMJmzfvh0HDhzAc889h/Dw8DZsGSKiTkYQUYc1cuRI0bdvXyHLsjLt0UcfFX379hW///67kCRJnDlzxmmZMWPGiMWLFwshhFi7dq0AIPbt2+dUZtasWWLatGlCCCEqKiqEVqsV7733njLfbDaL5ORksXz5ciGEEIsXL3ZbDwCiuLhYCCHEwIEDxZIlS7y270RE5Izn1BF1cMOHD4ckScr7ESNG4Pnnn8fu3bshhECvXr2cyptMJsTExCjvg4KCcMEFFzS4/hMnTsBiseCyyy5Tpmm1WgwdOhSHDx8GABw+fNhtPRzNnTsX9913H7Zs2YKxY8fihhtuaHS7RETkGYY6ogCmVquxZ88eqNVqp+mOhz1DQkKcwlh9wn5+Xv0yQghlmmjGlbJ33XUXJkyYgI0bN2LLli145pln8Pzzz+Ohhx5q9v4QEVHDeE4dUQe3a9cul/cZGRkYPHgwrFYr8vPzkZ6e7vRITExs9vrT09MRFBSEH3/8UZlmsViwe/du9O3bFwDQr18/t/WoLyUlBffeey8+/vhjLFy4EK+//ronu0pERI1gqCPq4HJycrBgwQIcPXoUH3zwAVauXIl58+ahV69euPXWW3Hbbbfh448/xsmTJ/HLL7/gueee8+iq07CwMNx33334n//5H2zatAmHDh3C3XffjaqqKtx5550AgHvvvRcnTpxQ6vH+++9j3bp1TuuZP38+Nm/ejJMnT+LXX3/Ft99+q4RCIiJqPR5+JergbrvtNhiNRgwdOhRqtRoPPfQQ5syZAwBYu3Ytnn76aSxcuBBnzpxBTEwMRowYgauvvtqjbTz77LOQZRkzZ85EeXk5hgwZgs2bNyMqKgoA0K1bN3z00Ud4+OGHsWrVKgwdOhTLli3DHXfcoazDarXigQcewOnTpxEZGYmJEyfihRde8F5DEBF1cpJozskwRNQujRo1ChdeeCFefPFFf1eFiIj8jIdfiYiIiAIAQx0RERFRAODhVyIiIqIAwJ46IiIiogDAUEdEREQUABjqiIiIiAIAQx0RERFRAGCoIyIiIgoADHVEREREAYChjoiIiCgAMNQRERERBQCGOiIiIqIA8P8B8XKp1Qi8Oy8AAAAASUVORK5CYII=", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 74, "metadata": {}, "output_type": "execute_result" } ], "source": [ "computed_table = table.compute(\"2000:6\", nb_decimals=4)\n", "computed_table.plot()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Working with workspaces\n", "\n", "As we seen above, `IODE` operates on objects of 7 different types:\n", "\n", "- **comments**\n", "- **equations**\n", "- **identities**\n", "- **lists**\n", "- **scalars**\n", "- **tables**\n", "- **variables**\n", "\n", "These are grouped into 7 dictionaries called `workspaces`. " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Load workspaces\n", "\n", "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()](../_generated/iode.Comments.load.rst#iode.Comments.load) method of the corresponding object. For example:" ] }, { "cell_type": "code", "execution_count": 75, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.cmt\n", "317 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.eqs\n", "274 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.idt\n", "48 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.lst\n", "17 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.scl\n", "161 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.tbl\n", "46 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.var\n", "394 objects loaded\n" ] }, { "data": { "text/plain": [ "(317, 274, 48, 17, 161, 46, 394)" ] }, "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# ---- load equations, identities, scalars and variables ----\n", "from iode import comments, equations, identities, lists, scalars, tables, variables\n", "\n", "# Note: test binary and ASCII 'fun' files are located in the 'SAMPLE_DATA_DIR' \n", "# directory of the 'iode' package\n", "comments.load(f\"{SAMPLE_DATA_DIR}/fun.cmt\")\n", "equations.load(f\"{SAMPLE_DATA_DIR}/fun.eqs\")\n", "identities.load(f\"{SAMPLE_DATA_DIR}/fun.idt\")\n", "lists.load(f\"{SAMPLE_DATA_DIR}/fun.lst\")\n", "scalars.load(f\"{SAMPLE_DATA_DIR}/fun.scl\")\n", "tables.load(f\"{SAMPLE_DATA_DIR}/fun.tbl\")\n", "variables.load(f\"{SAMPLE_DATA_DIR}/fun.var\")\n", "\n", "# ---- print the number of objects present in the above workspaces ----\n", "len(comments), len(equations), len(identities), len(lists), len(scalars), len(tables), len(variables)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Explore workspaces\n", "\n", "To get the list of objects names present in a workspace, use the [names](../_generated/iode.Comments.names.rst#iode.Comments.names) attribute of the workspace. \n", "For example:" ] }, { "cell_type": "code", "execution_count": 76, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['COPY',\n", " 'COPY0',\n", " 'COPY1',\n", " 'ENDO',\n", " 'ENDO0',\n", " 'ENDO1',\n", " 'ENVI',\n", " 'IDT',\n", " 'MAINEQ',\n", " 'MYLIST',\n", " 'TOTAL',\n", " 'TOTAL0',\n", " 'TOTAL1',\n", " 'XENVI',\n", " 'XSCENARIO',\n", " '_SCAL',\n", " '_SEARCH']" ] }, "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get the list of all IODE lists\n", "lists.names" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To check if a name is present in a workspace, use the `in` operator. \n", "For example:" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The 'ENVI' IODE list exists\n" ] } ], "source": [ "if 'ENVI' in lists:\n", " print(\"The 'ENVI' IODE list exists\")\n", "else:\n", " print(\"'ENVI' IODE list not found\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To iterate over names of a workspace, simply use the Python syntax for the *for loop*:" ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Iterate over all IODE lists names in the Lists workspace:\n", "COPY\n", "COPY0\n", "COPY1\n", "ENDO\n", "ENDO0\n", "ENDO1\n", "ENVI\n", "IDT\n", "MAINEQ\n", "MYLIST\n", "TOTAL\n", "TOTAL0\n", "TOTAL1\n", "XENVI\n", "XSCENARIO\n", "_SCAL\n", "_SEARCH\n" ] } ], "source": [ "print(\"Iterate over all IODE lists names in the Lists workspace:\")\n", "for name in lists:\n", " print(name)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To get the current used sample for the Variables, use the [sample](../_generated/iode.Variables.sample.rst#iode.Variables.sample) attribute of the [variables](../_generated/iode.Variables.rst#iode.Variables) workspace:" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Sample(\"1960Y1:2015Y1\")" ] }, "execution_count": 79, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# current used sample\n", "variables.sample" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Save workspaces\n", "\n", "To save the content of a workspace (or a subset of a workspace), use the [save()](../_generated/iode.Variables.save.rst#iode.Variables.save) method:" ] }, { "cell_type": "code", "execution_count": 80, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Saving equations.eqs\n", "274 objects saved\n", "Saving variables_subset.av\n", "Check content of the variables_subset.av file:\n", "\n", "sample 1960Y1 2015Y1\n", "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 \n", "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 \n", "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 \n", "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 \n", "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 \n", "\n", "\n" ] } ], "source": [ "# ---- save workspace (or subset) ----\n", "# save the whole workspace\n", "equations.save('equations.eqs')\n", "\n", "# save only a subset of the global variables workspace\n", "vars_subset = variables[[\"ACAF\", \"ACAG\", \"AQC\", \"BQY\", \"BVY\"]]\n", "vars_subset.save('variables_subset.av') \n", "\n", "print(\"Check content of the variables_subset.av file:\\n\")\n", "with open(\"variables_subset.av\", \"r\") as f:\n", " print(f.read())\n", "print()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Workspace subsets\n", "\n", "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. \n", "A (sub-)`pattern` is a list of characters representing a group of object names. It includes some special characters which have a special meaning:\n", "\n", "* `*` : any character sequence, even empty\n", "* `?` : any character (one and only one)\n", "* `@` : any alphanumerical char [A-Za-z0-9]\n", "* `&` : any non alphanumerical char\n", "* `|` : any alphanumeric character or none at the beginning and end of a string \n", "* `!` : any non-alphanumeric character or none at the beginning and end of a string \n", "* `\\` : escape the next character\n", "\n", "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:\n", "\n", "* a whitespace `' '`\n", "* a comma `,`\n", "* a semi-colon `;`\n", "* a tabulation `\\t`\n", "* a newline `\\n`\n", "\n", "Note that the *pattern* can contain references to IODE lists which are prefixed with the symbol `$`:" ] }, { "cell_type": "code", "execution_count": 81, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 33\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1960Y1:2015Y1\n", "mode: LEVEL\n", "\n", " name\t1960Y1\t1961Y1\t1962Y1\t1963Y1\t1964Y1\t...\t 2010Y1 \t 2011Y1 \t 2012Y1 \t 2013Y1 \t 2014Y1 \t 2015Y1 \n", "ACAF \t na\t na\t na\t na\t na\t...\t -37.83\t -44.54\t -55.56\t -68.89\t -83.34\t -96.41\n", "ACAG \t na\t na\t na\t na\t na\t...\t 28.25\t 29.28\t 30.32\t 31.37\t 32.42\t 33.47\n", "AOUC \t na\t 0.25\t 0.25\t 0.26\t 0.28\t...\t 1.31\t 1.33\t 1.36\t 1.39\t 1.42\t 1.46\n", "AOUC_\t na\t na\t na\t na\t na\t...\t 1.25\t 1.27\t 1.30\t 1.34\t 1.37\t 1.41\n", "AQC \t 0.22\t 0.22\t 0.22\t 0.23\t 0.24\t...\t 1.46\t 1.48\t 1.51\t 1.56\t 1.61\t 1.67\n", "... \t ...\t ...\t ...\t ...\t ...\t...\t ...\t ...\t ...\t ...\t ...\t ...\n", "WCF_ \t193.41\t205.78\t226.79\t250.05\t286.84\t...\t 5170.60\t 5340.61\t 5577.10\t 5872.12\t 6199.43\t 6531.10\n", "WIND_\t 69.98\t 72.09\t 75.96\t 78.14\t 82.12\t...\t 1301.03\t 1338.25\t 1389.28\t 1455.12\t 1532.45\t 1615.10\n", "WNF_ \t156.39\t164.81\t181.95\t198.53\t224.50\t...\t 3249.75\t 3356.81\t 3505.67\t 3691.39\t 3897.45\t 4106.27\n", "YDH_ \t439.50\t462.93\t493.99\t530.13\t587.08\t...\t10995.83\t11398.84\t11895.99\t12481.62\t13127.32\t13792.13\n", "ZZF_ \t 0.69\t 0.69\t 0.69\t 0.69\t 0.69\t...\t 0.69\t 0.69\t 0.69\t 0.69\t 0.69\t 0.69" ] }, "execution_count": 81, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vars_subset = variables[\"A*;*_\"]\n", "vars_subset" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['EX',\n", " 'PWMAB',\n", " 'PWMS',\n", " 'PWXAB',\n", " 'PWXS',\n", " 'QWXAB',\n", " 'QWXS',\n", " 'POIL',\n", " 'NATY',\n", " 'TFPFHP_']" ] }, "execution_count": 82, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lists[\"ENVI\"]" ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 15\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1960Y1:2015Y1\n", "mode: LEVEL\n", "\n", " name \t1960Y1\t1961Y1\t1962Y1\t1963Y1\t1964Y1\t...\t2010Y1\t2011Y1\t2012Y1\t2013Y1\t2014Y1\t2015Y1\n", "ACAF \t na\t na\t na\t na\t na\t...\t-37.83\t-44.54\t-55.56\t-68.89\t-83.34\t-96.41\n", "ACAG \t na\t na\t na\t na\t na\t...\t 28.25\t 29.28\t 30.32\t 31.37\t 32.42\t 33.47\n", "AOUC \t na\t 0.25\t 0.25\t 0.26\t 0.28\t...\t 1.31\t 1.33\t 1.36\t 1.39\t 1.42\t 1.46\n", "AOUC_ \t na\t na\t na\t na\t na\t...\t 1.25\t 1.27\t 1.30\t 1.34\t 1.37\t 1.41\n", "AQC \t 0.22\t 0.22\t 0.22\t 0.23\t 0.24\t...\t 1.46\t 1.48\t 1.51\t 1.56\t 1.61\t 1.67\n", "... \t ...\t ...\t ...\t ...\t ...\t...\t ...\t ...\t ...\t ...\t ...\t ...\n", "PWXAB \t 0.23\t 0.23\t 0.23\t 0.23\t 0.23\t...\t 1.44\t 1.46\t 1.49\t 1.51\t 1.54\t 1.57\n", "PWXS \t 0.21\t 0.21\t 0.21\t 0.21\t 0.21\t...\t 1.70\t 1.73\t 1.76\t 1.79\t 1.82\t 1.85\n", "QWXAB \t 0.44\t 0.44\t 0.44\t 0.44\t 0.44\t...\t 4.38\t 4.63\t 4.88\t 5.15\t 5.43\t 5.73\n", "QWXS \t 0.55\t 0.55\t 0.55\t 0.55\t 0.55\t...\t 1.77\t 1.83\t 1.88\t 1.94\t 2.00\t 2.06\n", "TFPFHP_\t 0.39\t 0.40\t 0.42\t 0.43\t 0.44\t...\t 1.10\t 1.11\t 1.12\t 1.13\t 1.14\t 1.15" ] }, "execution_count": 83, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vars_subset = variables[\"A*;$ENVI\"]\n", "vars_subset" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Get - add - update - delete objects in a workspaces\n", "\n", "In a similar way to Python dictionaries, you can [get](../_generated/iode.Equations.__getitem__.rst), [add](../_generated/iode.Equations.__setitem__.rst), [update](../_generated/iode.Equations.__setitem__.rst) and [delete](../_generated/iode.Equations.__delitem__.rst) IODE objects in a workspace using the `[]` operator.\n", "\n", "* To extract an IODE object from a workspace, use the syntax: `my_obj = workspace[name]`.\n", "* To add an IODE object to a workspace, use the syntax: `workspace[new_name] = new_obj`.\n", "* To update an IODE object in a workspace, use the syntax: `workspace[name] = new_value`.\n", "* To delete an IODE object from a workspace, use the syntax: `del workspace[name]`.\n", "\n", "To add or update IODE objects using:\n", "\n", "* a pandas Series or DataFrame, see the [pandas tutorial](./pandas.ipynb).\n", "* an larray Array, see the [larray tutorial](./larray.ipynb).\n", "* a numpy ndarray, see the [numpy tutorial](./numpy.ipynb)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Comments" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Add one comment:" ] }, { "cell_type": "code", "execution_count": 84, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'A new comment'" ] }, "execution_count": 84, "metadata": {}, "output_type": "execute_result" } ], "source": [ "comments[\"NEW\"] = \"A new comment\"\n", "comments[\"NEW\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Update a comment:" ] }, { "cell_type": "code", "execution_count": 85, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'New Value'" ] }, "execution_count": 85, "metadata": {}, "output_type": "execute_result" } ], "source": [ "comments[\"NEW\"] = \"New Value\"\n", "comments[\"NEW\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Update multiple comments at once:" ] }, { "cell_type": "code", "execution_count": 86, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Comments\n", "nb comments: 3\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.cmt\n", "\n", "name\t comments \n", "ACAF\tUpdated ACAF from dict\n", "ACAG\tUpdated ACAG from dict\n", "AOUC\tUpdated AOUC from dict" ] }, "execution_count": 86, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 1) using a dict of values\n", "values = {\"AOUC\": \"Updated AOUC from dict\", \"ACAF\": \"Updated ACAF from dict\", \n", " \"ACAG\": \"Updated ACAG from dict\"}\n", "comments[\"ACAF, ACAG, AOUC\"] = values\n", "comments[\"ACAF, ACAG, AOUC\"]" ] }, { "cell_type": "code", "execution_count": 87, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Comments\n", "nb comments: 3\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.cmt\n", "\n", "name\t comments \n", "ACAF\tUpdated ACAF from another iode Comments database\n", "ACAG\tUpdated ACAG from another iode Comments database\n", "AOUC\tUpdated AOUC from another iode Comments database" ] }, "execution_count": 87, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 2) using another Comments database (subset)\n", "comments_subset = comments[\"ACAF, ACAG, AOUC\"].copy()\n", "comments_subset[\"ACAF\"] = \"Updated ACAF from another iode Comments database\"\n", "comments_subset[\"ACAG\"] = \"Updated ACAG from another iode Comments database\"\n", "comments_subset[\"AOUC\"] = \"Updated AOUC from another iode Comments database\"\n", "comments[\"ACAF, ACAG, AOUC\"] = comments_subset\n", "comments[\"ACAF, ACAG, AOUC\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Delete a comment:" ] }, { "cell_type": "code", "execution_count": 88, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['ACAF', 'ACAG', 'AOUC', 'AQC']" ] }, "execution_count": 88, "metadata": {}, "output_type": "execute_result" } ], "source": [ "comments.get_names(\"A*\")" ] }, { "cell_type": "code", "execution_count": 89, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['ACAG', 'AOUC', 'AQC']" ] }, "execution_count": 89, "metadata": {}, "output_type": "execute_result" } ], "source": [ "del comments[\"ACAF\"]\n", "comments.get_names(\"A*\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Equations" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Add one equation:" ] }, { "cell_type": "code", "execution_count": 90, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Equation(endogenous = 'TEST',\n", " lec = 'TEST := 0',\n", " method = 'LSQ',\n", " from_period = '1960Y1',\n", " to_period = '2015Y1')" ] }, "execution_count": 90, "metadata": {}, "output_type": "execute_result" } ], "source": [ "equations[\"TEST\"] = \"TEST := 0\"\n", "equations[\"TEST\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Update an equation:" ] }, { "cell_type": "code", "execution_count": 91, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Equation(endogenous = 'ACAF',\n", " lec = '(ACAF/VAF[-1]) :=acaf1+acaf2*GOSF[-1]+\\nacaf4*(TIME=1995)',\n", " method = 'LSQ',\n", " from_period = '1980Y1',\n", " to_period = '1996Y1',\n", " block = 'ACAF',\n", " tests = {corr = 1,\n", " dw = 2.32935,\n", " fstat = 32.2732,\n", " loglik = 83.8075,\n", " meany = 0.00818467,\n", " r2 = 0.821761,\n", " r2adj = 0.796299,\n", " ssres = 5.19945e-05,\n", " stderr = 0.00192715,\n", " stderrp = 23.5458,\n", " stdev = 0.0042699},\n", " date = '12-06-1998')" ] }, "execution_count": 91, "metadata": {}, "output_type": "execute_result" } ], "source": [ "equations[\"ACAF\"]" ] }, { "cell_type": "code", "execution_count": 92, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Equation(endogenous = 'ACAF',\n", " lec = '(ACAF/VAF[-1]) := acaf1 + acaf2 * GOSF[-1] + acaf4 * (TIME=1995)',\n", " method = 'LSQ',\n", " from_period = '1980Y1',\n", " to_period = '1996Y1',\n", " block = 'ACAF',\n", " tests = {corr = 1,\n", " dw = 2.32935,\n", " fstat = 32.2732,\n", " loglik = 83.8075,\n", " meany = 0.00818467,\n", " r2 = 0.821761,\n", " r2adj = 0.796299,\n", " ssres = 5.19945e-05,\n", " stderr = 0.00192715,\n", " stderrp = 23.5458,\n", " stdev = 0.0042699},\n", " date = '12-06-1998')" ] }, "execution_count": 92, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# update only the LEC\n", "equations[\"ACAF\"] = \"(ACAF/VAF[-1]) := acaf1 + acaf2 * GOSF[-1] + acaf4 * (TIME=1995)\"\n", "equations[\"ACAF\"]" ] }, { "cell_type": "code", "execution_count": 93, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(Sample(\"2000Y1:2010Y1\"), Sample(\"2000Y1:2010Y1\"), Sample(\"2000Y1:2010Y1\"))" ] }, "execution_count": 93, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# update block and sample of a block of equations to estimation (dictionary)\n", "estim_sample = \"2000Y1:2010Y1\"\n", "block = \"ACAF; ACAG; AOUC\"\n", "for eq_name in block.split(';'):\n", " equations[eq_name] = {\"sample\": estim_sample, \"block\": block}\n", "\n", "(equations[\"ACAF\"].sample, equations[\"ACAG\"].sample, equations[\"AOUC\"].sample)" ] }, { "cell_type": "code", "execution_count": 94, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('ACAF; ACAG; AOUC', 'ACAF; ACAG; AOUC', 'ACAF; ACAG; AOUC')" ] }, "execution_count": 94, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(equations[\"ACAF\"].block, equations[\"ACAG\"].block, equations[\"AOUC\"].block)" ] }, { "cell_type": "code", "execution_count": 95, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Equation(endogenous = 'ACAF',\n", " lec = '(ACAF/VAF[-1]) := acaf2 * GOSF[-1] + acaf4 * (TIME=1995)',\n", " method = 'MAX_LIKELIHOOD',\n", " from_period = '1990Y1',\n", " to_period = '2015Y1',\n", " block = 'ACAF',\n", " tests = {corr = 1,\n", " dw = 2.32935,\n", " fstat = 32.2732,\n", " loglik = 83.8075,\n", " meany = 0.00818467,\n", " r2 = 0.821761,\n", " r2adj = 0.796299,\n", " ssres = 5.19945e-05,\n", " stderr = 0.00192715,\n", " stderrp = 23.5458,\n", " stdev = 0.0042699},\n", " date = '12-06-1998')" ] }, "execution_count": 95, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# update lec, method, sample and block\n", "eq = equations[\"ACAF\"]\n", "eq.lec = \"(ACAF/VAF[-1]) := acaf2 * GOSF[-1] + acaf4 * (TIME=1995)\"\n", "eq.method = EqMethod.MAX_LIKELIHOOD\n", "eq.sample = \"1990Y1:2015Y1\"\n", "eq.block = \"ACAF\"\n", "equations[\"ACAF\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Update multiple equations at once:" ] }, { "cell_type": "code", "execution_count": 96, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Equations\n", "nb equations: 3\n", "filename: c:\\usr\\Projects\\iode-1\\doc\\source\\tutorial\\equations.eqs\n", "\n", "name\t lec \t method\t sample \tblock\tfstat \tr2adj \t dw \tloglik\tdate\n", "ACAF\t(ACAF/VAF[-1]) :=acaf1+acaf2*GOSF[-1]+ acaf4*(TIME=1995) \tZELLNER\t1980Y1:1996Y1\t \t0.0000\t0.0000\t0.0000\t0.0000\t \n", "ACAG\tACAG := ACAG[-1]+r VBBP[-1]+(0.006*VBBP[-1]*(TIME=2001)-0.008*(TIME=2008)) \tZELLNER\t1980Y1:1996Y1\t \t0.0000\t0.0000\t0.0000\t0.0000\t \n", "AOUC\tAOUC:=((WCRH/QL)/(WCRH/QL)[1990Y1])*(VAFF/(VM+VAFF))[-1]+PM*(VM/(VAFF+VM))[-1]\tZELLNER\t1980Y1:1996Y1\t \t0.0000\t0.0000\t0.0000\t0.0000\t " ] }, "execution_count": 96, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 1) using a dict of values\n", "eq_ACAF = Equation(\"ACAF\", \"(ACAF/VAF[-1]) :=acaf1+acaf2*GOSF[-1]+ acaf4*(TIME=1995)\", \n", " method=EqMethod.ZELLNER, from_period='1980Y1', to_period='1996Y1')\n", "eq_ACAG = Equation(\"ACAG\", \"ACAG := ACAG[-1]+r VBBP[-1]+(0.006*VBBP[-1]*(TIME=2001)-0.008*(TIME=2008))\", \n", " method=EqMethod.ZELLNER, from_period='1980Y1', to_period='1996Y1')\n", "eq_AOUC = Equation(\"AOUC\", \"AOUC:=((WCRH/QL)/(WCRH/QL)[1990Y1])*(VAFF/(VM+VAFF))[-1]+PM*(VM/(VAFF+VM))[-1]\", \n", " method=EqMethod.ZELLNER, from_period='1980Y1', to_period='1996Y1')\n", "values = {\"ACAF\": eq_ACAF, \"ACAG\": eq_ACAG, \"AOUC\": eq_AOUC}\n", "equations[\"ACAF, ACAG, AOUC\"] = values\n", "equations[\"ACAF, ACAG, AOUC\"]" ] }, { "cell_type": "code", "execution_count": 97, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Equations\n", "nb equations: 3\n", "filename: c:\\usr\\Projects\\iode-1\\doc\\source\\tutorial\\equations.eqs\n", "\n", "name\t lec \t method \t sample \tblock\tfstat \tr2adj \t dw \tloglik\tdate\n", "ACAF\t(ACAF/VAF[-1]) :=acaf1+acaf2*GOSF[-1]+ acaf4*(TIME=1995) \tMAX_LIKELIHOOD\t1980Y1:1996Y1\t \t0.0000\t0.0000\t0.0000\t0.0000\t \n", "ACAG\tACAG := ACAG[-1]+r VBBP[-1]+(0.006*VBBP[-1]*(TIME=2001)-0.008*(TIME=2008)) \tMAX_LIKELIHOOD\t1980Y1:1996Y1\t \t0.0000\t0.0000\t0.0000\t0.0000\t \n", "AOUC\tAOUC:=((WCRH/QL)/(WCRH/QL)[1990Y1])*(VAFF/(VM+VAFF))[-1]+PM*(VM/(VAFF+VM))[-1]\tMAX_LIKELIHOOD\t1980Y1:1996Y1\t \t0.0000\t0.0000\t0.0000\t0.0000\t " ] }, "execution_count": 97, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 2) using another Equations database (subset)\n", "equations_subset = equations[\"ACAF, ACAG, AOUC\"].copy()\n", "for eq_name in equations_subset.names:\n", " equations_subset[eq_name].method = EqMethod.MAX_LIKELIHOOD\n", "equations[\"ACAF, ACAG, AOUC\"] = equations_subset\n", "equations[\"ACAF, ACAG, AOUC\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Delete an equation:" ] }, { "cell_type": "code", "execution_count": 98, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['ACAF', 'ACAG', 'AOUC']" ] }, "execution_count": 98, "metadata": {}, "output_type": "execute_result" } ], "source": [ "equations.get_names(\"A*\")" ] }, { "cell_type": "code", "execution_count": 99, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['ACAG', 'AOUC']" ] }, "execution_count": 99, "metadata": {}, "output_type": "execute_result" } ], "source": [ "del equations[\"ACAF\"]\n", "equations.get_names(\"A*\")" ] }, { "cell_type": "code", "execution_count": 100, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "c:\\soft\\Miniconda3\\Lib\\site-packages\\iode\\objects\\equation.py:1277: UserWarning: 'sample' is not defined\n", " return self._cy_equation._repr_()\n" ] }, { "data": { "text/plain": [ "Equation(endogenous = 'DEBT',\n", " lec = 'd DEBT := OCP-FLG',\n", " method = 'LSQ',\n", " comment = ' ',\n", " block = 'DEBT')" ] }, "execution_count": 100, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# store an equation in a Python variable\n", "eq = equations[\"DEBT\"]\n", "eq" ] }, { "cell_type": "code", "execution_count": 101, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 101, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# then delete it from the database\n", "del equations[\"DEBT\"]\n", "\"DEBT\" in equations" ] }, { "cell_type": "code", "execution_count": 102, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Equation(endogenous = 'DEBT',\n", " lec = 'd DEBT := OCP-FLG',\n", " method = 'LSQ',\n", " comment = ' ',\n", " block = 'DEBT')" ] }, "execution_count": 102, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# NOTE: the Python variable 'eq' still contains the equation object\n", "eq" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Identities" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Add one identity:" ] }, { "cell_type": "code", "execution_count": 103, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Identity('YN - YK')" ] }, "execution_count": 103, "metadata": {}, "output_type": "execute_result" } ], "source": [ "identities[\"BDY\"] = \"YN - YK\"\n", "identities[\"BDY\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Update an identity:" ] }, { "cell_type": "code", "execution_count": 104, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Identity('((WCRH/QL)/(WCRH/QL)[1990Y1])*(VAFF/(VM+VAFF))[-1]+PM*(VM/(VM+VAFF))[-1]')" ] }, "execution_count": 104, "metadata": {}, "output_type": "execute_result" } ], "source": [ "identities[\"AOUC\"]" ] }, { "cell_type": "code", "execution_count": 105, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Identity('(WCRH / WCRH[1990Y1]) * (VAFF / (VM+VAFF))[-1] + PM * (VM / (VM+VAFF))[-1]')" ] }, "execution_count": 105, "metadata": {}, "output_type": "execute_result" } ], "source": [ "identities[\"AOUC\"] = '(WCRH / WCRH[1990Y1]) * (VAFF / (VM+VAFF))[-1] + PM * (VM / (VM+VAFF))[-1]'\n", "identities[\"AOUC\"]" ] }, { "cell_type": "code", "execution_count": 106, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Identity('(WCRH / WCRH[1990Y1]) * (VAFF / (VM+VAFF))[-1]')" ] }, "execution_count": 106, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# or equivalently\n", "idt = identities[\"AOUC\"]\n", "idt.lec = \"(WCRH / WCRH[1990Y1]) * (VAFF / (VM+VAFF))[-1]\"\n", "identities[\"AOUC\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Update multiple identities at once:" ] }, { "cell_type": "code", "execution_count": 107, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Identities\n", "nb identities: 3\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.idt\n", "\n", " name\t identities \n", "GAP2 \t0.9 * 100*(QAFF_/(Q_F+Q_I))\n", "GAP_ \t0.9 * 100*((QAF_/Q_F)-1) \n", "GOSFR\t0.9 * (GOSF/VAF_) " ] }, "execution_count": 107, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 1) using a dict of values\n", "values = {\"GAP2\": \"0.9 * 100*(QAFF_/(Q_F+Q_I))\", \"GAP_\": \"0.9 * 100*((QAF_/Q_F)-1)\", \n", " \"GOSFR\": \"0.9 * (GOSF/VAF_)\"}\n", "identities[\"GAP2, GAP_, GOSFR\"] = values\n", "identities[\"GAP2, GAP_, GOSFR\"]" ] }, { "cell_type": "code", "execution_count": 108, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Identities\n", "nb identities: 3\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.idt\n", "\n", " name\t identities \n", "GAP2 \t0.7 * 100*(QAFF_/(Q_F+Q_I))\n", "GAP_ \t0.7 * 100*((QAF_/Q_F)-1) \n", "GOSFR\t0.7 * (GOSF/VAF_) " ] }, "execution_count": 108, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 2) using another Identities database (subset)\n", "identities_subset = identities[\"GAP2, GAP_, GOSFR\"].copy()\n", "identities_subset[\"GAP2\"] = \"0.7 * 100*(QAFF_/(Q_F+Q_I))\"\n", "identities_subset[\"GAP_\"] = \"0.7 * 100*((QAF_/Q_F)-1)\"\n", "identities_subset[\"GOSFR\"] = \"0.7 * (GOSF/VAF_)\"\n", "identities[\"GAP2, GAP_, GOSFR\"] = identities_subset\n", "identities[\"GAP2, GAP_, GOSFR\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Delete an identity:" ] }, { "cell_type": "code", "execution_count": 109, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['W', 'WBGR', 'WCRH', 'WMINR', 'WO']" ] }, "execution_count": 109, "metadata": {}, "output_type": "execute_result" } ], "source": [ "identities.get_names(\"W*\")" ] }, { "cell_type": "code", "execution_count": 110, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['WBGR', 'WCRH', 'WMINR', 'WO']" ] }, "execution_count": 110, "metadata": {}, "output_type": "execute_result" } ], "source": [ "del identities[\"W\"]\n", "identities.get_names(\"W*\")" ] }, { "cell_type": "code", "execution_count": 111, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Identity('YN - YK')" ] }, "execution_count": 111, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# create a new identity and store it in a Python variable\n", "idt = Identity(\"YN - YK\")\n", "idt" ] }, { "cell_type": "code", "execution_count": 112, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Identity('YN - YK')" ] }, "execution_count": 112, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "# add it to the database\n", "identities[\"NEW_IDT\"] = idt\n", "identities[\"NEW_IDT\"]" ] }, { "cell_type": "code", "execution_count": 113, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 113, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "# then delete it from the database\n", "del identities[\"NEW_IDT\"]\n", "\"NEW_IDT\" in identities" ] }, { "cell_type": "code", "execution_count": 114, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Identity('YN - YK')" ] }, "execution_count": 114, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# NOTE: the Python variable 'idt' still contains the identity object\n", "idt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Lists" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Add one list:" ] }, { "cell_type": "code", "execution_count": 115, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['ACAF', 'ACAG', 'AOUC', 'AOUC_', 'AQC']" ] }, "execution_count": 115, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# --- by passing a string\n", "lists[\"A_VAR\"] = \"ACAF;ACAG;AOUC;AOUC_;AQC\"\n", "lists[\"A_VAR\"]" ] }, { "cell_type": "code", "execution_count": 116, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['BENEF', 'BQY', 'BRUGP', 'BVY']" ] }, "execution_count": 116, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# --- by passing a Python list\n", "b_vars = variables.get_names(\"B*\")\n", "b_vars" ] }, { "cell_type": "code", "execution_count": 117, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['BENEF', 'BQY', 'BRUGP', 'BVY']" ] }, "execution_count": 117, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lists[\"B_VAR\"] = b_vars\n", "lists[\"B_VAR\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Update a list:" ] }, { "cell_type": "code", "execution_count": 118, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['ACAF', 'ACAG', 'AOUC', 'AQC']" ] }, "execution_count": 118, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# --- by passing a string\n", "lists[\"A_VAR\"] = \"ACAF;ACAG;AOUC;AQC\"\n", "lists[\"A_VAR\"]" ] }, { "cell_type": "code", "execution_count": 119, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['BQY', 'BVY']" ] }, "execution_count": 119, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# --- by passing a Python list\n", "b_y_vars = variables.get_names(\"B*Y\")\n", "b_y_vars" ] }, { "cell_type": "code", "execution_count": 120, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['BQY', 'BVY']" ] }, "execution_count": 120, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lists[\"B_VAR\"] = b_y_vars\n", "lists[\"B_VAR\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Update multiple lists at once:" ] }, { "cell_type": "code", "execution_count": 121, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Lists\n", "nb lists: 3\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.lst\n", "description: Modèle fun \n", "\n", " name \t lists \n", "ENVI \tPWMAB; PWMS; PWXAB; PWXS; QWXAB; QWXS; POIL; NATY \n", "IDT \tFLGR; KL; PROD; QL; RDEBT; RENT; RLBER; SBGX; WCRH; IUGR; SBGXR; WBGR; YSFICR\n", "MAINEQ\tNFYH; KNFF; PC; PXAB; PMAB; QXAB; QMAB " ] }, "execution_count": 121, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 1) using a dict of values\n", "values = {\"ENVI\": \"PWMAB; PWMS; PWXAB; PWXS; QWXAB; QWXS; POIL; NATY\",\n", " \"IDT\": \"FLGR; KL; PROD; QL; RDEBT; RENT; RLBER; SBGX; WCRH; IUGR; SBGXR; WBGR; YSFICR\",\n", " \"MAINEQ\": \"NFYH; KNFF; PC; PXAB; PMAB; QXAB; QMAB\"}\n", "lists[\"ENVI, IDT, MAINEQ\"] = values\n", "lists[\"ENVI, IDT, MAINEQ\"]" ] }, { "cell_type": "code", "execution_count": 122, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Lists\n", "nb lists: 3\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.lst\n", "description: Modèle fun \n", "\n", " name \t lists \n", "ENVI \tPWXAB; PWXS; QWXAB; QWXS \n", "IDT \tPROD; QL; RDEBT; RENT; RLBER; SBGX; WCRH; IUGR; SBGXR\n", "MAINEQ\tPC; PXAB; PMAB " ] }, "execution_count": 122, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 2) using another Lists database (subset)\n", "lists_subset = lists[\"ENVI, IDT, MAINEQ\"].copy()\n", "lists_subset[\"ENVI\"] = \"PWXAB; PWXS; QWXAB; QWXS\"\n", "lists_subset[\"IDT\"] = \"PROD; QL; RDEBT; RENT; RLBER; SBGX; WCRH; IUGR; SBGXR\"\n", "lists_subset[\"MAINEQ\"] = \"PC; PXAB; PMAB\"\n", "lists[\"ENVI, IDT, MAINEQ\"] = lists_subset\n", "lists[\"ENVI, IDT, MAINEQ\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Delete a list:" ] }, { "cell_type": "code", "execution_count": 123, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['COPY', 'COPY0', 'COPY1']" ] }, "execution_count": 123, "metadata": {}, "output_type": "execute_result" } ], "source": [ "lists.get_names(\"C*\")" ] }, { "cell_type": "code", "execution_count": 124, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['COPY0', 'COPY1']" ] }, "execution_count": 124, "metadata": {}, "output_type": "execute_result" } ], "source": [ "del lists[\"COPY\"]\n", "lists.get_names(\"C*\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Scalars" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Add one scalar:" ] }, { "cell_type": "code", "execution_count": 125, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Scalar(0.1, 1, na)" ] }, "execution_count": 125, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 1. default relax to 1.0\n", "scalars[\"a0\"] = 0.1\n", "scalars[\"a0\"]" ] }, { "cell_type": "code", "execution_count": 126, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Scalar(0.1, 0.9, na)" ] }, "execution_count": 126, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 2. value + relax\n", "scalars[\"a1\"] = 0.1, 0.9\n", "scalars[\"a1\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Update a scalar:" ] }, { "cell_type": "code", "execution_count": 127, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Scalar(0.0157684, 1, 0.00136871)" ] }, "execution_count": 127, "metadata": {}, "output_type": "execute_result" } ], "source": [ "scalars[\"acaf1\"]" ] }, { "cell_type": "code", "execution_count": 128, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Scalar(0.8, 1, na)" ] }, "execution_count": 128, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# only update the value\n", "scalars[\"acaf1\"] = 0.8\n", "scalars[\"acaf1\"]" ] }, { "cell_type": "code", "execution_count": 129, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Scalar(0.8, 0.9, na)" ] }, "execution_count": 129, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# update value and relax (tuple)\n", "scalars[\"acaf2\"] = 0.8, 0.9\n", "scalars[\"acaf2\"]" ] }, { "cell_type": "code", "execution_count": 130, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Scalar(0.7, 0.8, na)" ] }, "execution_count": 130, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# update value and relax (list)\n", "scalars[\"acaf2\"] = (0.7, 0.8)\n", "scalars[\"acaf2\"]" ] }, { "cell_type": "code", "execution_count": 131, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Scalar(0.8, 0.9, na)" ] }, "execution_count": 131, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# update value and relax (dictionary)\n", "scalars[\"acaf3\"] = {\"relax\": 0.9, \"value\": 0.8}\n", "scalars[\"acaf3\"]" ] }, { "cell_type": "code", "execution_count": 132, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Scalar(-0.00850518, 1, 0.0020833)" ] }, "execution_count": 132, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# update value and/or relax (Scalar object)\n", "# NOTE: the standard deviation (std) cannot be changed manually\n", "scalars[\"acaf4\"]" ] }, { "cell_type": "code", "execution_count": 133, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Scalar(0.8, 0.9, na)" ] }, "execution_count": 133, "metadata": {}, "output_type": "execute_result" } ], "source": [ "scl = scalars[\"acaf4\"]\n", "scl.value = 0.8\n", "scl.relax = 0.9\n", "scalars[\"acaf4\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Update multiple scalars at once:" ] }, { "cell_type": "code", "execution_count": 134, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Scalars\n", "nb scalars: 3\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.scl\n", "\n", " name\t value \trelax \tstd\n", "acaf1\t 0.0160\t1.0000\t na\n", "acaf2\t-0.0008\t0.9000\t na\n", "acaf3\t 2.5000\t1.0000\t na" ] }, "execution_count": 134, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 1) using a dict of values\n", "values = {\"acaf1\": 0.016, \"acaf2\": (-8.e-04, 0.9), \"acaf3\": Scalar(2.5)}\n", "scalars[\"acaf1, acaf2, acaf3\"] = values\n", "scalars[\"acaf1, acaf2, acaf3\"]" ] }, { "cell_type": "code", "execution_count": 135, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Scalars\n", "nb scalars: 3\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.scl\n", "\n", " name\t value \trelax \tstd\n", "acaf1\t 0.0200\t1.0000\t na\n", "acaf2\t-0.0005\t0.9400\t na\n", "acaf3\t 2.9000\t1.0000\t na" ] }, "execution_count": 135, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 2) using another Scalars database (subset)\n", "scalars_subset = scalars[\"acaf1, acaf2, acaf3\"].copy()\n", "scalars_subset[\"acaf1\"] = 0.02\n", "scalars_subset[\"acaf2\"] = (-5.e-04, 0.94)\n", "scalars_subset[\"acaf3\"] = Scalar(2.9)\n", "scalars[\"acaf1, acaf2, acaf3\"] = scalars_subset\n", "scalars[\"acaf1, acaf2, acaf3\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Delete a scalar:" ] }, { "cell_type": "code", "execution_count": 136, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['a0', 'a1', 'acaf1', 'acaf2', 'acaf3', 'acaf4']" ] }, "execution_count": 136, "metadata": {}, "output_type": "execute_result" } ], "source": [ "scalars.get_names(\"a*\")" ] }, { "cell_type": "code", "execution_count": 137, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['a0', 'a1', 'acaf1', 'acaf2', 'acaf3']" ] }, "execution_count": 137, "metadata": {}, "output_type": "execute_result" } ], "source": [ "del scalars[\"acaf4\"]\n", "scalars.get_names(\"a*\")" ] }, { "cell_type": "code", "execution_count": 138, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Scalar(0.201117, 1, 0.375671)" ] }, "execution_count": 138, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# store a scalar in a Python variable\n", "scl = scalars[\"zkf1\"]\n", "scl" ] }, { "cell_type": "code", "execution_count": 139, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 139, "metadata": {}, "output_type": "execute_result" } ], "source": [ " \n", "# then delete it from the database\n", "del scalars[\"zkf1\"]\n", "\"zkf1\" in scalars" ] }, { "cell_type": "code", "execution_count": 140, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Scalar(0.201117, 1, 0.375671)" ] }, "execution_count": 140, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "# NOTE: the Python variable 'scl' still contains the scalar object\n", "scl" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Tables" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create an add a new table:" ] }, { "cell_type": "code", "execution_count": 141, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DIVIS | 1 | \n", "TITLE | \"New Table\" \n", "----- | ----------------------------\n", "CELL | | \"#S\" \n", "----- | ----------------------------\n", "CELL | \"GOSG:\" | GOSG\n", "CELL | \"YDTG:\" | YDTG\n", "CELL | \"DTH:\" | DTH\n", "CELL | \"DTF:\" | DTF\n", "CELL | \"IT:\" | IT\n", "CELL | \"YSSG+COTRES:\" | YSSG+COTRES\n", "CELL | \"RIDG:\" | RIDG\n", "CELL | \"OCUG:\" | OCUG\n", "----- | ----------------------------\n", "MODE | \n", "FILES | \n", "DATE | \n", "\n", "nb lines: 16\n", "nb columns: 2\n", "language: 'ENGLISH'\n", "gridx: 'MAJOR'\n", "gridy: 'MAJOR'\n", "graph_axis: 'VALUES'\n", "graph_alignment: 'LEFT'" ] }, "execution_count": 141, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 1. specify list of line titles and list of LEC expressions\n", "lines_titles = [\"GOSG:\", \"YDTG:\", \"DTH:\", \"DTF:\", \"IT:\", \"YSSG+COTRES:\", \"RIDG:\", \"OCUG:\"]\n", "lines_lecs = [\"GOSG\", \"YDTG\", \"DTH\", \"DTF\", \"IT\", \"YSSG+COTRES\", \"RIDG\", \"OCUG\"]\n", "tables[\"TABLE_CELL_LECS\"] = {\"nb_columns\": 2, \"table_title\": \"New Table\", \"lecs_or_vars\": lines_lecs,\n", " \"lines_titles\": lines_titles, \"mode\": True, \"files\": True, \"date\": True}\n", "tables[\"TABLE_CELL_LECS\"]" ] }, { "cell_type": "code", "execution_count": 142, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DIVIS | 1 | \n", "TITLE | \"New Table\" \n", "----- | -----------------------------------------------------------------------------\n", "CELL | | \"#S\" \n", "----- | -----------------------------------------------------------------------------\n", "CELL | \"Bruto exploitatie-overschot: overheid (= afschrijvingen).\" | GOSG\n", "CELL | \"Overheid: geïnde indirecte belastingen.\" | YDTG\n", "CELL | \"Totale overheid: directe belasting van de gezinnen.\" | DTH\n", "CELL | \"Totale overheid: directe vennootschapsbelasting.\" | DTF\n", "CELL | \"Totale indirecte belastingen.\" | IT\n", "CELL | \"Globale overheid: ontvangen sociale zekerheidsbijdragen.\" | YSSG\n", "CELL | \"Cotisation de responsabilisation.\" | COTRES\n", "CELL | \"Overheid: inkomen uit vermogen.\" | RIDG\n", "CELL | \"Globale overheid: saldo van de ontvangen lopendeoverdrachten.\" | OCUG\n", "CELL | \"Index wereldprijs - uitvoer van niet-energieprodukten, inUSD.\" | PWXAB\n", "CELL | \"Index wereldprijs - uitvoer van diensten, in USD.\" | PWXS\n", "CELL | \"Indicator van het volume van de wereldvraag naar goederen,1985=1.\" | QWXAB\n", "CELL | \"Indicator van het volume van de wereldvraag naar diensten,1985=1.\" | QWXS\n", "----- | -----------------------------------------------------------------------------\n", "MODE | \n", "FILES | \n", "DATE | \n", "\n", "nb lines: 21\n", "nb columns: 2\n", "language: 'ENGLISH'\n", "gridx: 'MAJOR'\n", "gridy: 'MAJOR'\n", "graph_axis: 'VALUES'\n", "graph_alignment: 'LEFT'" ] }, "execution_count": 142, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 2. specify list of variables\n", "vars_list = [\"GOSG\", \"YDTG\", \"DTH\", \"DTF\", \"IT\", \"YSSG\", \"COTRES\", \"RIDG\", \"OCUG\", \"$ENVI\"]\n", "tables[\"TABLE_VARS\"] = {\"nb_columns\": 2, \"table_title\": \"New Table\", \"lecs_or_vars\": vars_list,\n", " \"mode\": True, \"files\": True, \"date\": True}\n", "tables[\"TABLE_VARS\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Update a table:" ] }, { "cell_type": "code", "execution_count": 143, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DIVIS | 1 | \n", "TITLE | \"New Table\" \n", "----- | ----------------------------\n", "CELL | | \"#S\" \n", "----- | ----------------------------\n", "CELL | \"GOSG:\" | GOSG\n", "CELL | \"YDTG:\" | YDTG\n", "CELL | \"DTH:\" | DTH\n", "CELL | \"DTF:\" | DTF\n", "CELL | \"IT:\" | IT\n", "CELL | \"YSSG+COTRES:\" | YSSG+COTRES\n", "CELL | \"RIDG:\" | RIDG\n", "CELL | \"OCUG:\" | OCUG\n", "----- | ----------------------------\n", "MODE | \n", "FILES | \n", "DATE | \n", "\n", "nb lines: 16\n", "nb columns: 2\n", "language: 'ENGLISH'\n", "gridx: 'MAJOR'\n", "gridy: 'MAJOR'\n", "graph_axis: 'VALUES'\n", "graph_alignment: 'LEFT'" ] }, "execution_count": 143, "metadata": {}, "output_type": "execute_result" } ], "source": [ "table = tables[\"TABLE_CELL_LECS\"]\n", "table " ] }, { "cell_type": "code", "execution_count": 144, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'VALUES'" ] }, "execution_count": 144, "metadata": {}, "output_type": "execute_result" } ], "source": [ "table.graph_axis" ] }, { "cell_type": "code", "execution_count": 145, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'SEMILOG'" ] }, "execution_count": 145, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from iode import TableGraphAxis\n", "# set graph axis type\n", "table.graph_axis = TableGraphAxis.SEMILOG\n", "table.graph_axis" ] }, { "cell_type": "code", "execution_count": 146, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "New Table" ] }, "execution_count": 146, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get the first line\n", "table[0]" ] }, { "cell_type": "code", "execution_count": 147, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 147, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get the last line\n", "table[-1]" ] }, { "cell_type": "code", "execution_count": 148, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DIVIS | 1 | \n", "TITLE | \"New Table\" \n", "----- | ----------------------------\n", "CELL | | \"#S\" \n", "----- | ----------------------------\n", "CELL | \"GOSG:\" | GOSG\n", "CELL | \"YDTG:\" | YDTG\n", "CELL | \"DTH:\" | DTH\n", "CELL | \"DTF:\" | DTF\n", "CELL | \"IT:\" | IT\n", "CELL | \"YSSG+COTRES:\" | YSSG+COTRES\n", "CELL | \"RIDG:\" | RIDG\n", "CELL | \"OCUG:\" | OCUG\n", "----- | ----------------------------\n", "MODE | \n", "FILES | \n", "\n", "nb lines: 15\n", "nb columns: 2\n", "language: 'ENGLISH'\n", "gridx: 'MAJOR'\n", "gridy: 'MAJOR'\n", "graph_axis: 'SEMILOG'\n", "graph_alignment: 'LEFT'" ] }, "execution_count": 148, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# delete last line\n", "del table[-1]\n", "table" ] }, { "cell_type": "code", "execution_count": 149, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "9" ] }, "execution_count": 149, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get index of line containing YSSG+COTRES\n", "index = table.index(\"YSSG+COTRES\")\n", "index" ] }, { "cell_type": "code", "execution_count": 150, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('\"YSSG+COTRES:\"', 'YSSG+COTRES')" ] }, "execution_count": 150, "metadata": {}, "output_type": "execute_result" } ], "source": [ "table[index]" ] }, { "cell_type": "code", "execution_count": 151, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'CELL'" ] }, "execution_count": 151, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get line type\n", "table[index].line_type" ] }, { "cell_type": "code", "execution_count": 152, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'LINE'" ] }, "execution_count": 152, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get line graph type\n", "table[index].graph_type" ] }, { "cell_type": "code", "execution_count": 153, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 153, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# know if axis is left\n", "table[index].axis_left" ] }, { "cell_type": "code", "execution_count": 154, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "('\"YSSG:\"', 'YSSG')" ] }, "execution_count": 154, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# update cells\n", "# double quotes \" -> STRING cell\n", "# no double quotes -> LEC cell\n", "table[index] = ('\"YSSG:\"', 'YSSG')\n", "table[index]" ] }, { "cell_type": "code", "execution_count": 155, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DIVIS | 1 | \n", "TITLE | \"New Table\" \n", "----- | --------------\n", "CELL | | \"#S\"\n", "----- | --------------\n", "CELL | \"GOSG:\" | GOSG\n", "CELL | \"YDTG:\" | YDTG\n", "CELL | \"DTH:\" | DTH\n", "CELL | \"DTF:\" | DTF\n", "CELL | \"IT:\" | IT\n", "CELL | \"YSSG:\" | YSSG\n", "----- | --------------\n", "TITLE | \"New Title\" \n", "----- | --------------\n", "CELL | \"RIDG:\" | RIDG\n", "CELL | \"OCUG:\" | OCUG\n", "----- | --------------\n", "MODE | \n", "FILES | \n", "\n", "nb lines: 18\n", "nb columns: 2\n", "language: 'ENGLISH'\n", "gridx: 'MAJOR'\n", "gridy: 'MAJOR'\n", "graph_axis: 'SEMILOG'\n", "graph_alignment: 'LEFT'" ] }, "execution_count": 155, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# insert a new title line surrounded by two separator lines\n", "table.insert(index + 1, '-')\n", "table.insert(index + 2, \"New Title\")\n", "table.insert(index + 3, '-')\n", "table" ] }, { "cell_type": "code", "execution_count": 156, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DIVIS | 1 | \n", "TITLE | \"New Table\" \n", "----- | --------------\n", "CELL | | \"#S\"\n", "----- | --------------\n", "CELL | \"GOSG:\" | GOSG\n", "CELL | \"YDTG:\" | YDTG\n", "CELL | \"DTH:\" | DTH\n", "CELL | \"DTF:\" | DTF\n", "CELL | \"IT:\" | IT\n", "CELL | \"YSSG:\" | YSSG\n", "----- | --------------\n", "TITLE | \"New Title\" \n", "----- | --------------\n", "CELL | \"RIDG:\" | RIDG\n", "CELL | \"OCUG:\" | OCUG\n", "----- | --------------\n", "MODE | \n", "FILES | \n", "----- | --------------\n", "\n", "nb lines: 19\n", "nb columns: 2\n", "language: 'ENGLISH'\n", "gridx: 'MAJOR'\n", "gridy: 'MAJOR'\n", "graph_axis: 'SEMILOG'\n", "graph_alignment: 'LEFT'" ] }, "execution_count": 156, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# append a new sepatator line\n", "table += '-'\n", "table" ] }, { "cell_type": "code", "execution_count": 157, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DIVIS | 1 | \n", "TITLE | \"New Table\" \n", "----- | --------------\n", "CELL | | \"#S\"\n", "----- | --------------\n", "CELL | \"GOSG:\" | GOSG\n", "CELL | \"YDTG:\" | YDTG\n", "CELL | \"DTH:\" | DTH\n", "CELL | \"DTF:\" | DTF\n", "CELL | \"IT:\" | IT\n", "CELL | \"YSSG:\" | YSSG\n", "----- | --------------\n", "TITLE | \"New Title\" \n", "----- | --------------\n", "CELL | \"RIDG:\" | RIDG\n", "CELL | \"OCUG:\" | OCUG\n", "----- | --------------\n", "MODE | \n", "FILES | \n", "----- | --------------\n", "\n", "nb lines: 19\n", "nb columns: 2\n", "language: 'ENGLISH'\n", "gridx: 'MAJOR'\n", "gridy: 'MAJOR'\n", "graph_axis: 'SEMILOG'\n", "graph_alignment: 'LEFT'" ] }, "execution_count": 157, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tables[\"TABLE_CELL_LECS\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Update multiple tables at once:" ] }, { "cell_type": "code", "execution_count": 158, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Tables\n", "nb tables: 3\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.tbl\n", "\n", "name\t table titles \n", "C8_1\tDéterminants de l'output potentiel (copy)\n", "C8_2\tDéterminants de la productivité (copy) \n", "C8_3\tOutput gap (copy) " ] }, "execution_count": 158, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 1) using a dict of values\n", "table_C8_1 = tables[\"C8_1\"].copy()\n", "table_C8_1.title = table_C8_1.title + \" (copy)\"\n", "table_C8_2 = tables[\"C8_2\"].copy()\n", "table_C8_2.title = table_C8_2.title + \" (copy)\"\n", "table_C8_3 = tables[\"C8_3\"].copy()\n", "table_C8_3.title = table_C8_3.title + \" (copy)\"\n", "\n", "values = {\"C8_1\": table_C8_1, \"C8_2\": table_C8_2, \"C8_3\": table_C8_3}\n", "tables[\"C8_1, C8_2, C8_3\"] = values\n", "tables[\"C8_1, C8_2, C8_3\"]" ] }, { "cell_type": "code", "execution_count": 159, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Tables\n", "nb tables: 3\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.tbl\n", "\n", "name\t table titles \n", "C8_1\tDéterminants de l'output potentiel (detached subset)\n", "C8_2\tDéterminants de la productivité (detached subset) \n", "C8_3\tOutput gap (detached subset) " ] }, "execution_count": 159, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 2) using another tables database (subset)\n", "tables_subset = tables[\"C8_1, C8_2, C8_3\"].copy()\n", "for tbl_name in tables_subset.names:\n", " title = tables_subset[tbl_name].title\n", " tables_subset[tbl_name].title = title.replace(\"(copy)\", \"(detached subset)\")\n", "tables[\"C8_1, C8_2, C8_3\"] = tables_subset\n", "tables[\"C8_1, C8_2, C8_3\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Delete a table:" ] }, { "cell_type": "code", "execution_count": 160, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['GAP', 'GDP', 'GFR', 'GFRLEVEL', 'GFRPC', 'GROWTH']" ] }, "execution_count": 160, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tables.get_names(\"G*\")" ] }, { "cell_type": "code", "execution_count": 161, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['GAP', 'GDP', 'GFR', 'GFRPC', 'GROWTH']" ] }, "execution_count": 161, "metadata": {}, "output_type": "execute_result" } ], "source": [ "del tables[\"GFRLEVEL\"]\n", "tables.get_names(\"G*\")" ] }, { "cell_type": "code", "execution_count": 162, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DIVIS | 1 | \n", "TITLE | \"Principaux indicateurs : montants absolus\" \n", "----- | -----------------------------------------------------------\n", "CELL | \" \" | \"#s\" \n", "----- | -----------------------------------------------------------\n", "CELL | \"1. Demande globale\" | \n", "CELL | \" Consommation privée\" | QC\n", "CELL | \" Consommation publique\" | QG\n", "CELL | \" Formation brute de capital fixe\" | QI\n", "CELL | \" - Entreprises\" | QIF\n", "CELL | \" - Etat\" | QIG\n", "CELL | \" - Logements\" | QI5\n", "CELL | \" Exportations de biens et services\" | QX\n", "CELL | \" Importations de biens et services\" | QM\n", "CELL | \" Produit Intérieur Brut\" | QBBP\n", "CELL | \" Produit National Brut\" | QBNP\n", "CELL | \"2. Marché du travail\" | \n", "CELL | \" Emploi total\" | NATY-UY\n", "CELL | \" Entreprises\" | NFY+NIY\n", "CELL | \" Etat\" | NGY\n", "CELL | \"3. Prix, salaires et revenus\" | \n", "CELL | \" Salaire coût horaire\" | WCRH\n", "CELL | \" Salaire coût réel horaire\" | WCRH/PC\n", "CELL | \" Déflateur de la consommation privée\" | PC\n", "CELL | \" Coûts salariaux unitaires (apparents)\" | WCRH/PROD\n", "CELL | \" Coûts salariaux unitaires (techn.)\" | WCRH/QL\n", "CELL | \" Prix des importations\" | PM\n", "CELL | \" Coûts totaux par unité produite \" | AOUC\n", "CELL | \" Prix des exportations de biens\" | PXAB\n", "CELL | \" Termes de l'échange (PX/PM)\" | PX/PM\n", "CELL | \" Revenu disponible réel des ménages\" | YDH/PC\n", "CELL | \"4. Entreprises\" | \n", "CELL | \" Valeur ajoutée (prix constants)\" | QAF_\n", "CELL | \" Déflateur de la valeur ajoutée\" | PAF_\n", "CELL | \" Valeur ajoutée potentielle\" | Q_F\n", "CELL | \" Stock de capital\" | KNFY\n", "CELL | \"5. Productivités du travail\" | \n", "CELL | \" Productivité horaire apparente\" | PROD\n", "CELL | \" Productivité horaire technique\" | QL\n", "CELL | \" Productivité par tête \" | QAF_/(NFY)\n", "----- | -----------------------------------------------------------\n", "MODE | \n", "FILES | \n", "DATE | \n", "\n", "nb lines: 43\n", "nb columns: 2\n", "language: 'ENGLISH'\n", "gridx: 'MAJOR'\n", "gridy: 'MAJOR'\n", "graph_axis: 'VALUES'\n", "graph_alignment: 'LEFT'" ] }, "execution_count": 162, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# store a table in a Python variable\n", "tbl = tables[\"MULT1FR\"]\n", "tbl" ] }, { "cell_type": "code", "execution_count": 163, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 163, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "# then delete it from the database\n", "del tables[\"MULT1FR\"]\n", "\"MULT1FR\" in tables" ] }, { "cell_type": "code", "execution_count": 164, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "DIVIS | 1 | \n", "TITLE | \"Principaux indicateurs : montants absolus\" \n", "----- | -----------------------------------------------------------\n", "CELL | \" \" | \"#s\" \n", "----- | -----------------------------------------------------------\n", "CELL | \"1. Demande globale\" | \n", "CELL | \" Consommation privée\" | QC\n", "CELL | \" Consommation publique\" | QG\n", "CELL | \" Formation brute de capital fixe\" | QI\n", "CELL | \" - Entreprises\" | QIF\n", "CELL | \" - Etat\" | QIG\n", "CELL | \" - Logements\" | QI5\n", "CELL | \" Exportations de biens et services\" | QX\n", "CELL | \" Importations de biens et services\" | QM\n", "CELL | \" Produit Intérieur Brut\" | QBBP\n", "CELL | \" Produit National Brut\" | QBNP\n", "CELL | \"2. Marché du travail\" | \n", "CELL | \" Emploi total\" | NATY-UY\n", "CELL | \" Entreprises\" | NFY+NIY\n", "CELL | \" Etat\" | NGY\n", "CELL | \"3. Prix, salaires et revenus\" | \n", "CELL | \" Salaire coût horaire\" | WCRH\n", "CELL | \" Salaire coût réel horaire\" | WCRH/PC\n", "CELL | \" Déflateur de la consommation privée\" | PC\n", "CELL | \" Coûts salariaux unitaires (apparents)\" | WCRH/PROD\n", "CELL | \" Coûts salariaux unitaires (techn.)\" | WCRH/QL\n", "CELL | \" Prix des importations\" | PM\n", "CELL | \" Coûts totaux par unité produite \" | AOUC\n", "CELL | \" Prix des exportations de biens\" | PXAB\n", "CELL | \" Termes de l'échange (PX/PM)\" | PX/PM\n", "CELL | \" Revenu disponible réel des ménages\" | YDH/PC\n", "CELL | \"4. Entreprises\" | \n", "CELL | \" Valeur ajoutée (prix constants)\" | QAF_\n", "CELL | \" Déflateur de la valeur ajoutée\" | PAF_\n", "CELL | \" Valeur ajoutée potentielle\" | Q_F\n", "CELL | \" Stock de capital\" | KNFY\n", "CELL | \"5. Productivités du travail\" | \n", "CELL | \" Productivité horaire apparente\" | PROD\n", "CELL | \" Productivité horaire technique\" | QL\n", "CELL | \" Productivité par tête \" | QAF_/(NFY)\n", "----- | -----------------------------------------------------------\n", "MODE | \n", "FILES | \n", "DATE | \n", "\n", "nb lines: 43\n", "nb columns: 2\n", "language: 'ENGLISH'\n", "gridx: 'MAJOR'\n", "gridy: 'MAJOR'\n", "graph_axis: 'VALUES'\n", "graph_alignment: 'LEFT'" ] }, "execution_count": 164, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "# NOTE: the Python variable 'tbl' still contains the table object\n", "tbl" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Variables" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Get variable:" ] }, { "cell_type": "code", "execution_count": 165, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "23.771" ] }, "execution_count": 165, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get the value for a single period -> float \n", "variables[\"ACAF\", \"1990Y1\"]" ] }, { "cell_type": "code", "execution_count": 166, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1960Y1:2015Y1\n", "mode: LEVEL\n", "\n", "name\t1960Y1\t1961Y1\t1962Y1\t1963Y1\t1964Y1\t1965Y1\t...\t2009Y1\t2010Y1\t2011Y1\t2012Y1\t2013Y1\t2014Y1\t2015Y1\n", "ACAF\t na\t na\t na\t na\t na\t na\t...\t-37.46\t-37.83\t-44.54\t-55.56\t-68.89\t-83.34\t-96.41" ] }, "execution_count": 166, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get the values for all periods -> Variables\n", "variables[\"ACAF\"]" ] }, { "cell_type": "code", "execution_count": 167, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1990Y1:2000Y1\n", "mode: LEVEL\n", "\n", "name\t1990Y1\t1991Y1\t1992Y1\t1993Y1\t1994Y1\t1995Y1\t1996Y1\t1997Y1\t1998Y1\t1999Y1\t2000Y1\n", "ACAF\t 23.77\t 26.24\t 30.16\t 34.66\t 8.16\t-13.13\t 32.17\t 39.94\t 29.65\t 13.53\t 10.05" ] }, "execution_count": 167, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get the values for a range of periods -> Variables\n", "variables[\"ACAF\", \"1990Y1:2000Y1\"]" ] }, { "cell_type": "code", "execution_count": 168, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "time\n", "1990Y1 23.771000\n", "1995Y1 -13.130997\n", "2000Y1 10.046611\n", "Name: ACAF, dtype: float64" ] }, "execution_count": 168, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get the values for a list non-contiguous periods -> pandas Series \n", "variables[\"ACAF\", [\"1990Y1\", \"1995Y1\", \"2000Y1\"]]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Get values for a single period:" ] }, { "cell_type": "code", "execution_count": 169, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 394\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1990Y1:1990Y1\n", "mode: LEVEL\n", "\n", " name\t1990Y1\n", "ACAF \t 23.77\n", "ACAG \t-28.17\n", "AOUC \t 1.00\n", "AOUC_\t 0.94\n", "AQC \t 1.00\n", "... \t ...\n", "ZJ \t 1.09\n", "ZKF \t 0.81\n", "ZKFO \t 1.00\n", "ZX \t 0.00\n", "ZZF_ \t 0.69" ] }, "execution_count": 169, "metadata": {}, "output_type": "execute_result" } ], "source": [ "variables[:, \"1990Y1\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or equivalently:" ] }, { "cell_type": "code", "execution_count": 170, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 394\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1990Y1:1990Y1\n", "mode: LEVEL\n", "\n", " name\t1990Y1\n", "ACAF \t 23.77\n", "ACAG \t-28.17\n", "AOUC \t 1.00\n", "AOUC_\t 0.94\n", "AQC \t 1.00\n", "... \t ...\n", "ZJ \t 1.09\n", "ZKF \t 0.81\n", "ZKFO \t 1.00\n", "ZX \t 0.00\n", "ZZF_ \t 0.69" ] }, "execution_count": 170, "metadata": {}, "output_type": "execute_result" } ], "source": [ "variables[\"*\", \"1990Y1\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Add one variable:" ] }, { "cell_type": "code", "execution_count": 171, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1960Y1:2015Y1\n", "mode: LEVEL\n", "\n", "name\t1960Y1\t1961Y1\t1962Y1\t1963Y1\t1964Y1\t1965Y1\t...\t2009Y1\t2010Y1\t2011Y1\t2012Y1\t2013Y1\t2014Y1\t2015Y1\n", "A0 \t na\t na\t na\t na\t na\t na\t...\t na\t na\t na\t na\t na\t na\t na" ] }, "execution_count": 171, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 1) same value for all periods\n", "# NOTE: you can also use NA from iode to set a variable value to NaN\n", "variables[\"A0\"] = np.nan \n", "variables[\"A0\"]" ] }, { "cell_type": "code", "execution_count": 172, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1960Y1:2015Y1\n", "mode: LEVEL\n", "\n", "name\t1960Y1\t1961Y1\t1962Y1\t1963Y1\t1964Y1\t1965Y1\t...\t2009Y1\t2010Y1\t2011Y1\t2012Y1\t2013Y1\t2014Y1\t2015Y1\n", "A1 \t 10.00\t 11.00\t 12.00\t 13.00\t 14.00\t 15.00\t...\t 59.00\t 60.00\t 61.00\t 62.00\t 63.00\t 64.00\t 65.00" ] }, "execution_count": 172, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 2) LEC expression\n", "variables[\"A1\"] = \"t + 10\"\n", "variables[\"A1\"] " ] }, { "cell_type": "code", "execution_count": 173, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1960Y1:2015Y1\n", "mode: LEVEL\n", "\n", "name\t1960Y1\t1961Y1\t1962Y1\t1963Y1\t1964Y1\t1965Y1\t...\t2009Y1\t2010Y1\t2011Y1\t2012Y1\t2013Y1\t2014Y1\t2015Y1\n", "A2 \t na\t 1.00\t 2.00\t 3.00\t 4.00\t 5.00\t...\t 49.00\t 50.00\t 51.00\t 52.00\t 53.00\t 54.00\t na" ] }, "execution_count": 173, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 3) list of values for each period\n", "values = list(range(variables.nb_periods))\n", "values[0] = NA\n", "values[-1] = np.nan\n", "variables[\"A2\"] = values\n", "variables[\"A2\"] " ] }, { "cell_type": "code", "execution_count": 174, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1960Y1:2015Y1\n", "mode: LEVEL\n", "\n", "name\t1960Y1\t1961Y1\t1962Y1\t1963Y1\t1964Y1\t1965Y1\t...\t2009Y1\t2010Y1\t2011Y1\t2012Y1\t2013Y1\t2014Y1\t2015Y1\n", "A5 \t na\t na\t na\t na\t na\t na\t...\t-37.46\t-37.83\t-44.54\t-55.56\t-68.89\t-83.34\t-96.41" ] }, "execution_count": 174, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 4) Variables object\n", "variables[\"A5\"] = variables[\"ACAF\"]\n", "variables[\"A5\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Update a variable.\n", "\n", "Set one value of a variable for a specific period:" ] }, { "cell_type": "code", "execution_count": 175, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "-28.1721855713507" ] }, "execution_count": 175, "metadata": {}, "output_type": "execute_result" } ], "source": [ "variables[\"ACAG\", \"1990Y1\"]" ] }, { "cell_type": "code", "execution_count": 176, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "-28.2" ] }, "execution_count": 176, "metadata": {}, "output_type": "execute_result" } ], "source": [ "variables[\"ACAG\", \"1990Y1\"] = -28.2\n", "variables[\"ACAG\", \"1990Y1\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Update all values of a variable:" ] }, { "cell_type": "code", "execution_count": 177, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1960Y1:2015Y1\n", "mode: LEVEL\n", "\n", "name\t1960Y1\t1961Y1\t1962Y1\t1963Y1\t1964Y1\t1965Y1\t...\t2009Y1\t2010Y1\t2011Y1\t2012Y1\t2013Y1\t2014Y1\t2015Y1\n", "ACAF\t na\t na\t na\t na\t na\t na\t...\t-37.46\t-37.83\t-44.54\t-55.56\t-68.89\t-83.34\t-96.41" ] }, "execution_count": 177, "metadata": {}, "output_type": "execute_result" } ], "source": [ "variables[\"ACAF\"] " ] }, { "cell_type": "code", "execution_count": 178, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1960Y1:2015Y1\n", "mode: LEVEL\n", "\n", "name\t1960Y1\t1961Y1\t1962Y1\t1963Y1\t1964Y1\t1965Y1\t...\t2009Y1\t2010Y1\t2011Y1\t2012Y1\t2013Y1\t2014Y1\t2015Y1\n", "ACAF\t na\t na\t na\t na\t na\t na\t...\t na\t na\t na\t na\t na\t na\t na" ] }, "execution_count": 178, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 1) same value for all periods\n", "variables[\"ACAF\"] = np.nan\n", "variables[\"ACAF\"] " ] }, { "cell_type": "code", "execution_count": 179, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1960Y1:2015Y1\n", "mode: LEVEL\n", "\n", "name\t1960Y1\t1961Y1\t1962Y1\t1963Y1\t1964Y1\t1965Y1\t...\t2009Y1\t2010Y1\t2011Y1\t2012Y1\t2013Y1\t2014Y1\t2015Y1\n", "ACAF\t 10.00\t 11.00\t 12.00\t 13.00\t 14.00\t 15.00\t...\t 59.00\t 60.00\t 61.00\t 62.00\t 63.00\t 64.00\t 65.00" ] }, "execution_count": 179, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 2) LEC expression\n", "variables[\"ACAF\"] = \"t + 10\"\n", "variables[\"ACAF\"] " ] }, { "cell_type": "code", "execution_count": 180, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1960Y1:2015Y1\n", "mode: LEVEL\n", "\n", "name\t1960Y1\t1961Y1\t1962Y1\t1963Y1\t1964Y1\t1965Y1\t...\t2009Y1\t2010Y1\t2011Y1\t2012Y1\t2013Y1\t2014Y1\t2015Y1\n", "ACAF\t na\t 1.00\t 2.00\t 3.00\t 4.00\t 5.00\t...\t 49.00\t 50.00\t 51.00\t 52.00\t 53.00\t 54.00\t na" ] }, "execution_count": 180, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 3) list of values for each period\n", "values = list(range(variables.nb_periods))\n", "values[0] = NA\n", "values[-1] = np.nan\n", "variables[\"ACAF\"] = values\n", "variables[\"ACAF\"] " ] }, { "cell_type": "code", "execution_count": 181, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1960Y1:2015Y1\n", "mode: LEVEL\n", "\n", "name\t1960Y1\t1961Y1\t1962Y1\t1963Y1\t1964Y1\t1965Y1\t...\t2009Y1\t2010Y1\t2011Y1\t2012Y1\t2013Y1\t2014Y1\t2015Y1\n", "AQC \t 0.22\t 0.22\t 0.22\t 0.23\t 0.24\t 0.25\t...\t 1.45\t 1.46\t 1.48\t 1.51\t 1.56\t 1.61\t 1.67" ] }, "execution_count": 181, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 4) Variables object\n", "variables[\"AQC\"]" ] }, { "cell_type": "code", "execution_count": 182, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1960Y1:2015Y1\n", "mode: LEVEL\n", "\n", "name\t1960Y1\t1961Y1\t1962Y1\t1963Y1\t1964Y1\t1965Y1\t...\t2009Y1\t2010Y1\t2011Y1\t2012Y1\t2013Y1\t2014Y1\t2015Y1\n", "ACAF\t 0.22\t 0.22\t 0.22\t 0.23\t 0.24\t 0.25\t...\t 1.45\t 1.46\t 1.48\t 1.51\t 1.56\t 1.61\t 1.67" ] }, "execution_count": 182, "metadata": {}, "output_type": "execute_result" } ], "source": [ "variables[\"ACAF\"] = variables[\"AQC\"]\n", "variables[\"ACAF\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Set the values for range of (contiguous) periods:" ] }, { "cell_type": "code", "execution_count": 183, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1991Y1:1995Y1\n", "mode: LEVEL\n", "\n", "name\t1991Y1\t1992Y1\t1993Y1\t1994Y1\t1995Y1\n", "ACAF\t 0.00\t 0.00\t 0.00\t 0.00\t 0.00" ] }, "execution_count": 183, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 1) variable[t:t+x] = same value for all periods\n", "variables[\"ACAF\", \"1991Y1:1995Y1\"] = 0.0\n", "variables[\"ACAF\", \"1991Y1:1995Y1\"]" ] }, { "cell_type": "code", "execution_count": 184, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1991Y1:1995Y1\n", "mode: LEVEL\n", "\n", "name\t1991Y1\t1992Y1\t1993Y1\t1994Y1\t1995Y1\n", "ACAF\t 41.00\t 42.00\t 43.00\t 44.00\t 45.00" ] }, "execution_count": 184, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 2) variable[t:t+x] = LEC expression\n", "variables[\"ACAF\", \"1991Y1:1995Y1\"] = \"t + 10\"\n", "variables[\"ACAF\", \"1991Y1:1995Y1\"]" ] }, { "cell_type": "code", "execution_count": 185, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1991Y1:1995Y1\n", "mode: LEVEL\n", "\n", "name\t1991Y1\t1992Y1\t1993Y1\t1994Y1\t1995Y1\n", "ACAF\t 1.00\t na\t 3.00\t na\t 5.00" ] }, "execution_count": 185, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 3) variable[t:t+x] = list of values for each period\n", "values = [1.0, NA, 3.0, np.nan, 5.0]\n", "variables[\"ACAF\", \"1991Y1:1995Y1\"] = values\n", "variables[\"ACAF\", \"1991Y1:1995Y1\"]" ] }, { "cell_type": "code", "execution_count": 186, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1991Y1:1995Y1\n", "mode: LEVEL\n", "\n", "name\t1991Y1\t1992Y1\t1993Y1\t1994Y1\t1995Y1\n", "AQC \t 1.06\t 1.11\t 1.15\t 1.16\t 1.16" ] }, "execution_count": 186, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 4) variable[t:t+x] = Variables object\n", "variables[\"AQC\", \"1991Y1:1995Y1\"]" ] }, { "cell_type": "code", "execution_count": 187, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1991Y1:1995Y1\n", "mode: LEVEL\n", "\n", "name\t1991Y1\t1992Y1\t1993Y1\t1994Y1\t1995Y1\n", "ACAF\t 1.06\t 1.11\t 1.15\t 1.16\t 1.16" ] }, "execution_count": 187, "metadata": {}, "output_type": "execute_result" } ], "source": [ "variables[\"ACAF\", \"1991Y1:1995Y1\"] = variables[\"AQC\", \"1991Y1:1995Y1\"]\n", "variables[\"ACAF\", \"1991Y1:1995Y1\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Set the values for a list of non-contiguous periods:" ] }, { "cell_type": "code", "execution_count": 188, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "time\n", "1991Y1 1.0\n", "1993Y1 3.0\n", "1995Y1 5.0\n", "Name: ACAF, dtype: float64" ] }, "execution_count": 188, "metadata": {}, "output_type": "execute_result" } ], "source": [ "values = [1.0, 3.0, 5.0]\n", "variables[\"ACAF\", [\"1991Y1\", \"1993Y1\", \"1995Y1\"]] = values\n", "variables[\"ACAF\", [\"1991Y1\", \"1993Y1\", \"1995Y1\"]]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Update multiple variables at once:" ] }, { "cell_type": "code", "execution_count": 189, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 3\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1991Y1:1995Y1\n", "mode: LEVEL\n", "\n", "name\t1991Y1\t1992Y1\t1993Y1\t1994Y1\t1995Y1\n", "ACAF\t 32.00\t 33.00\t 34.00\t 35.00\t 36.00\n", "ACAG\t 32.00\t 33.00\t 34.00\t 35.00\t 36.00\n", "AOUC\t 32.00\t 33.00\t 34.00\t 35.00\t 36.00" ] }, "execution_count": 189, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 1) using a string\n", "variables[\"ACAF, ACAG, AOUC\", \"1991Y1:1995Y1\"] = \"t + 1\"\n", "variables[\"ACAF, ACAG, AOUC\", \"1991Y1:1995Y1\"]" ] }, { "cell_type": "code", "execution_count": 190, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "c:\\soft\\Miniconda3\\Lib\\site-packages\\iode\\iode_database\\variables_database.py:1131: 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]`\n", " self._cy_database._update_variable(name, pos, values, key_periods)\n" ] }, { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 3\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1991Y1:1995Y1\n", "mode: LEVEL\n", "\n", "name\t1991Y1\t1992Y1\t1993Y1\t1994Y1\t1995Y1\n", "ACAF\t 33.60\t 34.65\t 35.70\t 36.75\t 37.80\n", "ACAG\t na\t-39.96\t-42.88\t-16.33\t-41.16\n", "AOUC\t 1.02\t na\t 1.05\t na\t 1.06" ] }, "execution_count": 190, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 2) using a dict of values\n", "periods = [\"1991Y1\", \"1992Y1\", \"1993Y1\", \"1994Y1\", \"1995Y1\"]\n", "values = {\"ACAF\": \"ACAF * 1.05\",\n", " \"ACAG\": [np.nan, -39.96, -42.88, -16.33, -41.16],\n", " \"AOUC\": pd.Series([1.023, np.nan, 1.046, np.nan, 1.064], index=periods)}\n", "variables[\"ACAF, ACAG, AOUC\", \"1991Y1:1995Y1\"] = values\n", "variables[\"ACAF, ACAG, AOUC\", \"1991Y1:1995Y1\"]\n" ] }, { "cell_type": "code", "execution_count": 191, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 3\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1991Y1:1995Y1\n", "mode: LEVEL\n", "\n", "name\t 1991Y1\t 1992Y1\t 1993Y1\t 1994Y1\t 1995Y1\n", "ACAF\t1991.00\t1992.00\t1993.00\t1994.00\t1995.00\n", "ACAG\t1996.00\t1997.00\t1998.00\t1999.00\t2000.00\n", "AOUC\t2001.00\t2002.00\t2003.00\t2004.00\t2005.00" ] }, "execution_count": 191, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 3) using another variables database (subset)\n", "variables_subset = variables[\"ACAF, ACAG, AOUC\", \"1991Y1:1995Y1\"].copy()\n", "variables_subset[\"ACAF\"] = [1991, 1992, 1993, 1994, 1995]\n", "variables_subset[\"ACAG\"] = [1996, 1997, 1998, 1999, 2000]\n", "variables_subset[\"AOUC\"] = [2001, 2002, 2003, 2004, 2005]\n", "variables[\"ACAF, ACAG, AOUC\", \"1991Y1:1995Y1\"] = variables_subset\n", "variables[\"ACAF, ACAG, AOUC\", \"1991Y1:1995Y1\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Delete a variable:" ] }, { "cell_type": "code", "execution_count": 192, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['A0', 'A1', 'A2', 'A5', 'ACAF', 'ACAG', 'AOUC', 'AOUC_', 'AQC']" ] }, "execution_count": 192, "metadata": {}, "output_type": "execute_result" } ], "source": [ "variables.get_names(\"A*\")" ] }, { "cell_type": "code", "execution_count": 193, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['A0', 'A1', 'A2', 'A5', 'ACAG', 'AOUC', 'AOUC_', 'AQC']" ] }, "execution_count": 193, "metadata": {}, "output_type": "execute_result" } ], "source": [ "del variables[\"ACAF\"]\n", "variables.get_names(\"A*\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Get - add - update - delete objects in workspace subsets\n", "\n", "
\n", "\n", "**Note**\n", "\n", "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.\n", "\n", "To create an isolate subset of a workspace, use the [copy](../_generated/iode.Equations.copy.rst#iode.Equations.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.\n", "\n", "
\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Comments - Equations - Identities - Lists - Scalars - Tables" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's first begin by reloading the example workspace for all IODE types:" ] }, { "cell_type": "code", "execution_count": 194, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.cmt\n", "317 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.eqs\n", "274 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.idt\n", "48 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.lst\n", "17 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.scl\n", "161 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.tbl\n", "46 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.var\n", "394 objects loaded\n" ] } ], "source": [ "comments.load(f\"{SAMPLE_DATA_DIR}/fun.cmt\")\n", "equations.load(f\"{SAMPLE_DATA_DIR}/fun.eqs\")\n", "identities.load(f\"{SAMPLE_DATA_DIR}/fun.idt\")\n", "lists.load(f\"{SAMPLE_DATA_DIR}/fun.lst\")\n", "scalars.load(f\"{SAMPLE_DATA_DIR}/fun.scl\")\n", "tables.load(f\"{SAMPLE_DATA_DIR}/fun.tbl\")\n", "variables.load(f\"{SAMPLE_DATA_DIR}/fun.var\")" ] }, { "cell_type": "code", "execution_count": 195, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['ACAF', 'ACAG', 'AOUC', 'AQC']" ] }, "execution_count": 195, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 1) get subset using a pattern\n", "comments_subset = comments[\"A*\"]\n", "comments_subset.names" ] }, { "cell_type": "code", "execution_count": 196, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'New Comment'" ] }, "execution_count": 196, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 2) add a comment to the subset\n", "comments_subset[\"A0\"] = \"New Comment\"\n", "comments_subset[\"A0\"]" ] }, { "cell_type": "code", "execution_count": 197, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(True, 'New Comment')" ] }, "execution_count": 197, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# --> new comment also appears in the global workspace\n", "\"A0\" in comments, comments[\"A0\"]" ] }, { "cell_type": "code", "execution_count": 198, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Updated Comment'" ] }, "execution_count": 198, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 3) update a comment in the subset\n", "comments_subset[\"A0\"] = \"Updated Comment\"\n", "comments_subset[\"A0\"]" ] }, { "cell_type": "code", "execution_count": 199, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'Updated Comment'" ] }, "execution_count": 199, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# --> comment is also updated in the global workspace\n", "comments[\"A0\"]" ] }, { "cell_type": "code", "execution_count": 200, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['ACAF', 'ACAG', 'AOUC', 'AQC']" ] }, "execution_count": 200, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# delete comment from the subset\n", "del comments_subset[\"A0\"]\n", "comments_subset.names" ] }, { "cell_type": "code", "execution_count": 201, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 201, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# NOTE: the comment has also been deleted from the global database\n", "\"A0\" in comments" ] }, { "cell_type": "code", "execution_count": 202, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['ACAF', 'ACAG', 'AOUC', 'AQC']" ] }, "execution_count": 202, "metadata": {}, "output_type": "execute_result" } ], "source": [ "comments.get_names(\"A*\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Variables" ] }, { "cell_type": "code", "execution_count": 203, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['ACAF', 'ACAG', 'AOUC', 'AOUC_', 'AQC']" ] }, "execution_count": 203, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 1) get subset using a pattern\n", "vars_subset = variables[\"A*\"]\n", "vars_subset.names" ] }, { "cell_type": "code", "execution_count": 204, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 5\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1990Y1:1990Y1\n", "mode: LEVEL\n", "\n", " name\t1990Y1\n", "ACAF \t 23.77\n", "ACAG \t-28.17\n", "AOUC \t 1.00\n", "AOUC_\t 0.94\n", "AQC \t 1.00" ] }, "execution_count": 204, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get the values for a specific period -> Variables\n", "variables[\"A*\", \"1990Y1\"]" ] }, { "cell_type": "code", "execution_count": 205, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 5\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1990Y1:2000Y1\n", "mode: LEVEL\n", "\n", " name\t1990Y1\t1991Y1\t1992Y1\t1993Y1\t1994Y1\t1995Y1\t1996Y1\t1997Y1\t1998Y1\t1999Y1\t2000Y1\n", "ACAF \t 23.77\t 26.24\t 30.16\t 34.66\t 8.16\t-13.13\t 32.17\t 39.94\t 29.65\t 13.53\t 10.05\n", "ACAG \t-28.17\t-30.93\t-40.29\t-43.16\t-16.03\t-41.85\t-40.24\t-32.93\t-38.35\t-39.86\t-41.53\n", "AOUC \t 1.00\t 1.02\t 1.03\t 1.03\t 1.05\t 1.05\t 1.05\t 1.08\t 1.09\t 1.11\t 1.12\n", "AOUC_\t 0.94\t 0.96\t 0.97\t 0.98\t 0.99\t 1.00\t 1.00\t 1.03\t 1.04\t 1.08\t 1.10\n", "AQC \t 1.00\t 1.06\t 1.11\t 1.15\t 1.16\t 1.16\t 1.16\t 1.20\t 1.20\t 1.34\t 1.34" ] }, "execution_count": 205, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get the variable values for range of periods -> Variables\n", "variables[\"A*\", \"1990Y1:2000Y1\"]" ] }, { "cell_type": "code", "execution_count": 206, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
time1990Y11995Y12000Y1
variables
ACAF23.771000-13.13099710.046611
ACAG-28.172186-41.845993-41.534787
AOUC1.0000001.0498911.116238
AOUC_0.9373590.9952631.101957
AQC1.0000001.1616871.338603
\n", "
" ], "text/plain": [ "time 1990Y1 1995Y1 2000Y1\n", "variables \n", "ACAF 23.771000 -13.130997 10.046611\n", "ACAG -28.172186 -41.845993 -41.534787\n", "AOUC 1.000000 1.049891 1.116238\n", "AOUC_ 0.937359 0.995263 1.101957\n", "AQC 1.000000 1.161687 1.338603" ] }, "execution_count": 206, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# get the variable values for a list of non-contiguous periods -> pandas DataFrame\n", "variables[\"A*\", [\"1990Y1\", \"1995Y1\", \"2000Y1\"]]" ] }, { "cell_type": "code", "execution_count": 207, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1960Y1:2015Y1\n", "mode: LEVEL\n", "\n", "name\t1960Y1\t1961Y1\t1962Y1\t1963Y1\t1964Y1\t1965Y1\t...\t2009Y1\t2010Y1\t2011Y1\t2012Y1\t2013Y1\t2014Y1\t2015Y1\n", "A0 \t na\t na\t na\t na\t na\t na\t...\t na\t na\t na\t na\t na\t na\t na" ] }, "execution_count": 207, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 2) add a variable to the subset\n", "vars_subset[\"A0\"] = np.nan\n", "vars_subset[\"A0\"] " ] }, { "cell_type": "code", "execution_count": 208, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 208, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# --> new variable also appears in the global workspace\n", "\"A0\" in variables " ] }, { "cell_type": "code", "execution_count": 209, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1960Y1:2015Y1\n", "mode: LEVEL\n", "\n", "name\t1960Y1\t1961Y1\t1962Y1\t1963Y1\t1964Y1\t1965Y1\t...\t2009Y1\t2010Y1\t2011Y1\t2012Y1\t2013Y1\t2014Y1\t2015Y1\n", "A0 \t na\t na\t na\t na\t na\t na\t...\t na\t na\t na\t na\t na\t na\t na" ] }, "execution_count": 209, "metadata": {}, "output_type": "execute_result" } ], "source": [ "variables[\"A0\"]" ] }, { "cell_type": "code", "execution_count": 210, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1960Y1:2015Y1\n", "mode: LEVEL\n", "\n", "name\t1960Y1\t1961Y1\t1962Y1\t1963Y1\t1964Y1\t1965Y1\t...\t2009Y1\t2010Y1\t2011Y1\t2012Y1\t2013Y1\t2014Y1\t2015Y1\n", "A0 \t 0.00\t 0.00\t 0.00\t 0.00\t 0.00\t 0.00\t...\t 0.00\t 0.00\t 0.00\t 0.00\t 0.00\t 0.00\t 0.00" ] }, "execution_count": 210, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 3) update a variable in the subset\n", "vars_subset[\"A0\"] = 0.0\n", "vars_subset[\"A0\"] " ] }, { "cell_type": "code", "execution_count": 211, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1960Y1:2015Y1\n", "mode: LEVEL\n", "\n", "name\t1960Y1\t1961Y1\t1962Y1\t1963Y1\t1964Y1\t1965Y1\t...\t2009Y1\t2010Y1\t2011Y1\t2012Y1\t2013Y1\t2014Y1\t2015Y1\n", "A0 \t 0.00\t 0.00\t 0.00\t 0.00\t 0.00\t 0.00\t...\t 0.00\t 0.00\t 0.00\t 0.00\t 0.00\t 0.00\t 0.00" ] }, "execution_count": 211, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# --> variable is also updated in the global workspace\n", "variables[\"A0\"] " ] }, { "cell_type": "code", "execution_count": 212, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 212, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# delete one variable from a subset of the global database\n", "del vars_subset[\"A0\"]\n", "\"A0\" in vars_subset" ] }, { "cell_type": "code", "execution_count": 213, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "False" ] }, "execution_count": 213, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# NOTE: the variable has also been deleted from the global database\n", "\"A0\" in variables" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is also possible to work on subset over names and periods:" ] }, { "cell_type": "code", "execution_count": 214, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['ACAF', 'ACAG', 'AOUC', 'AOUC_', 'AQC']" ] }, "execution_count": 214, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 1) get subset over names and periods -> Variables\n", "vars_subset = variables[\"A*\", \"1991Y1:1995Y1\"]\n", "vars_subset.names" ] }, { "cell_type": "code", "execution_count": 215, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 5\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1991Y1:1995Y1\n", "mode: LEVEL\n", "\n", " name\t1991Y1\t1992Y1\t1993Y1\t1994Y1\t1995Y1\n", "ACAF \t 26.24\t 30.16\t 34.66\t 8.16\t-13.13\n", "ACAG \t-30.93\t-40.29\t-43.16\t-16.03\t-41.85\n", "AOUC \t 1.02\t 1.03\t 1.03\t 1.05\t 1.05\n", "AOUC_\t 0.96\t 0.97\t 0.98\t 0.99\t 1.00\n", "AQC \t 1.06\t 1.11\t 1.15\t 1.16\t 1.16" ] }, "execution_count": 215, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vars_subset" ] }, { "cell_type": "code", "execution_count": 216, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1991Y1:1995Y1\n", "mode: LEVEL\n", "\n", "name\t1991Y1\t1992Y1\t1993Y1\t1994Y1\t1995Y1\n", "ACAF\t 1.00\t 1.00\t 1.00\t 1.00\t 1.00" ] }, "execution_count": 216, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# 2) update a variable in the subset\n", "vars_subset[\"ACAF\"] = 1.0\n", "vars_subset[\"ACAF\"]" ] }, { "cell_type": "code", "execution_count": 217, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.0" ] }, "execution_count": 217, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# --> variable is also updated in the global workspace\n", "variables[\"ACAF\", \"1991Y1\"]" ] }, { "cell_type": "code", "execution_count": 218, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "1.0" ] }, "execution_count": 218, "metadata": {}, "output_type": "execute_result" } ], "source": [ "variables[\"ACAF\", \"1995Y1\"]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "**Note**\n", "\n", "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.\n", "\n", "
\n" ] }, { "cell_type": "code", "execution_count": 219, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
time1990Y11995Y12000Y1
variables
ACAF23.7710001.00000010.046611
ACAG-28.172186-41.845993-41.534787
AOUC1.0000001.0498911.116238
AOUC_0.9373590.9952631.101957
AQC1.0000001.1616871.338603
\n", "
" ], "text/plain": [ "time 1990Y1 1995Y1 2000Y1\n", "variables \n", "ACAF 23.771000 1.000000 10.046611\n", "ACAG -28.172186 -41.845993 -41.534787\n", "AOUC 1.000000 1.049891 1.116238\n", "AOUC_ 0.937359 0.995263 1.101957\n", "AQC 1.000000 1.161687 1.338603" ] }, "execution_count": 219, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_vars_subset = variables[\"A*\", [\"1990Y1\", \"1995Y1\", \"2000Y1\"]]\n", "df_vars_subset" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Get Scalars And Variables Referenced In The Equations, Identities And Tables Workspaces" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To get the list of *scalars* (*coefficients*) and *variables* referenced in identities, use the [coefficients](../_generated/iode.Equations.coefficients.rst#iode.Equations.coefficients) and [variables](../_generated/iode.Equations.variables.rst#iode.Equations.variables) properties of the [equations](../_generated/iode.Equations.rst#iode.Equations) workspace:" ] }, { "cell_type": "code", "execution_count": 220, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "c:\\soft\\Miniconda3\\Lib\\site-packages\\iode\\time\\sample.py:241: UserWarning: 'sample' is not defined\n", " return self._cy_sample.__str__()\n" ] }, { "data": { "text/plain": [ "Workspace: Equations\n", "nb equations: 3\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.eqs\n", "\n", "name\t lec \tmethod\t sample \tblock\t fstat \tr2adj \t dw \t loglik\t date \n", "ACAF\t(ACAF/VAF[-1]) :=acaf1+acaf2*GOSF[-1]+ acaf4*(TIME=1995) \t LSQ\t1980Y1:1996Y1\t ACAF\t32.2732\t0.7963\t2.3293\t83.8075\t12-06-1998\n", "ACAG\tACAG := ACAG[-1]+r VBBP[-1]+(0.006*VBBP[-1]*(TIME=2001)-0.008*(TIME=2008)) \t LSQ\t None\t ACAG\t 0.0000\t0.0000\t0.0000\t 0.0000\t \n", "AOUC\tAOUC:=((WCRH/QL)/(WCRH/QL)[1990Y1])*(VAFF/(VM+VAFF))[-1]+PM*(VM/(VAFF+VM))[-1]\t LSQ\t None\t AOUC\t 0.0000\t0.0000\t0.0000\t 0.0000\t " ] }, "execution_count": 220, "metadata": {}, "output_type": "execute_result" } ], "source": [ "equations[\"A*\"]" ] }, { "cell_type": "code", "execution_count": 221, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['acaf1', 'acaf2', 'acaf4']" ] }, "execution_count": 221, "metadata": {}, "output_type": "execute_result" } ], "source": [ "equations[\"A*\"].coefficients" ] }, { "cell_type": "code", "execution_count": 222, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['ACAF',\n", " 'ACAG',\n", " 'AOUC',\n", " 'GOSF',\n", " 'PM',\n", " 'QL',\n", " 'TIME',\n", " 'VAF',\n", " 'VAFF',\n", " 'VBBP',\n", " 'VM',\n", " 'WCRH']" ] }, "execution_count": 222, "metadata": {}, "output_type": "execute_result" } ], "source": [ "equations[\"A*\"].variables" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To get the list of *scalars* (*coefficients*) and *variables* referenced in identities, use the [coefficients](../_generated/iode.Identities.coefficients.rst#iode.Identities.coefficients) and [variables](../_generated/iode.Identities.variables.rst#iode.Identities.variables) properties of the [identities](../_generated/iode.Identities.rst#iode.Identities) workspace:" ] }, { "cell_type": "code", "execution_count": 223, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Identities\n", "nb identities: 4\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.idt\n", "\n", " name\t identities \n", "AOUC \t((WCRH/QL)/(WCRH/QL)[1990Y1])*(VAFF/(VM+VAFF))[-1]+PM*(VM/(VM+VAFF))[-1] \n", "AOUC_\texp(ln(((WCF/NFYH)/QL)+PKF/(QAFF/KNFFY))*(QAFF/(QX+QAFF)+.05)[-1]+ln PM*(QM/ (QAFF+QM)-0.05)[-1])\n", "NAWRU\t1-exp((gamma2+gamma3*ln(W/ZJ)[-1]+gamma4*ln(WMIN/ZJ))/ gamma_) \n", "NFYHO\t1 " ] }, "execution_count": 223, "metadata": {}, "output_type": "execute_result" } ], "source": [ "identities[\"A*;N*\"]" ] }, { "cell_type": "code", "execution_count": 224, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['gamma2', 'gamma3', 'gamma4', 'gamma_']" ] }, "execution_count": 224, "metadata": {}, "output_type": "execute_result" } ], "source": [ "identities[\"A*;N*\"].coefficients" ] }, { "cell_type": "code", "execution_count": 225, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['KNFFY',\n", " 'NFYH',\n", " 'PKF',\n", " 'PM',\n", " 'QAFF',\n", " 'QL',\n", " 'QM',\n", " 'QX',\n", " 'VAFF',\n", " 'VM',\n", " 'W',\n", " 'WCF',\n", " 'WCRH',\n", " 'WMIN',\n", " 'ZJ']" ] }, "execution_count": 225, "metadata": {}, "output_type": "execute_result" } ], "source": [ "identities[\"A*;N*\"].variables" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To get the list of *scalars* (*coefficients*) and *variables* referenced in identities, use the [coefficients](../_generated/iode.Tables.coefficients.rst#iode.Tables.coefficients) and [variables](../_generated/iode.Tables.variables.rst#iode.Tables.variables) properties of the [tables](../_generated/iode.Tables.rst#iode.Tables) workspace:" ] }, { "cell_type": "code", "execution_count": 226, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Tables\n", "nb tables: 19\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.tbl\n", "\n", " name \t table titles \n", "ANAKNFF\tDéterminants de la croissance de K \n", "ANAPRIX\tAnalyse des prix \n", "C8_1 \tDéterminants de l'output potentiel \n", "C8_10 \tCoin salarial parafiscal \n", "C8_11 \tPropension moyenne à épargner \n", "... \t... \n", "C8_9 \tPrix à la consommation et index \n", "C9_1 \tCroissance et marchés à l'exportation\n", "C9_2 \tCompétitivité et termes d'échange \n", "C9_3 \tProductivité totale des facteurs \n", "C9_4 \tTaux d'intérêt et croissance " ] }, "execution_count": 226, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tables[\"A*;C*\"]" ] }, { "cell_type": "code", "execution_count": 227, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['knf2', 'knff1']" ] }, "execution_count": 227, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tables[\"A*;C*\"].coefficients" ] }, { "cell_type": "code", "execution_count": 228, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['AOUC',\n", " 'AOUC_',\n", " 'EX',\n", " 'GAP_',\n", " 'ITCR',\n", " 'KLFHP',\n", " 'KNFF',\n", " 'NFY',\n", " 'NFYH',\n", " 'NIY',\n", " 'PC',\n", " 'PKF',\n", " 'PM',\n", " 'PROD',\n", " 'PWXAB',\n", " 'PX',\n", " 'QAFF',\n", " 'QAFF_',\n", " 'QBBP',\n", " 'QWXAB',\n", " 'QWXSS',\n", " 'QXAB',\n", " 'Q_F',\n", " 'Q_I',\n", " 'RENT',\n", " 'RLBER',\n", " 'SSFF',\n", " 'SSHFF',\n", " 'TFPFHP_',\n", " 'VAF_',\n", " 'VC',\n", " 'WBF_',\n", " 'WCF_',\n", " 'WCRH',\n", " 'WNF_',\n", " 'YDH',\n", " 'ZJ']" ] }, "execution_count": 228, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tables[\"A*;C*\"].variables" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Get Words Referenced In IODE Objects\n", "\n", "More generally, the [search](../_generated/iode.Equations.search.rst#iode.Equations.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:" ] }, { "cell_type": "code", "execution_count": 229, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "equations containing the scalar 'acaf1': ['ACAF']\n", "equations containing the variable 'AOUC': ['AOUC', 'PC', 'PIF', 'PXS', 'QXAB']\n", "equations containing the variables 'ACAF', 'ACAG' or 'AOUC':\n", " ['ACAF', 'ACAG', 'AOUC', 'FLF', 'FLG', 'PC', 'PIF', 'PXS', 'QXAB']\n" ] } ], "source": [ "# list of equations containing the scalar 'acaf1'\n", "eq_list = equations.search(\"acaf1\")\n", "print(\"equations containing the scalar 'acaf1':\", eq_list)\n", "\n", "# list of equations containing the variable 'AOUC'\n", "eq_list = equations.search(\"AOUC\")\n", "print(\"equations containing the variable 'AOUC':\", eq_list)\n", "\n", "# list of equations containing either the variable 'ACAF', 'ACAG' or 'AOUC'\n", "eq_set = set()\n", "for var in [\"ACAF\", \"ACAG\", \"AOUC\"]:\n", " eq_set |= set(equations.search(var))\n", "eq_list = sorted(list(eq_set))\n", "print(\"equations containing the variables 'ACAF', 'ACAG' or 'AOUC':\\n\", eq_list)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Get IODE Objects Referenced In Other IODE Objects\n", "\n", "To get the list of IODE objects referenced in another IODE object, use the [search](../_generated/iode.Equations.search.rst#iode.Equations.search) method. For instance, it can be used to get the list of equations containing a specific scalar or variable:" ] }, { "cell_type": "code", "execution_count": 230, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "comments containing the word 'Croissance':\n", " ['XNATY', 'XPOIL', 'XPWMAB', 'XPWXAB', 'XQWXSS', 'XTFP']\n", "tables containing the word 'Croissance':\n", " ['ANAKNFF', 'C8_5', 'C9_1', 'C9_4', 'T1', 'XQBBP']\n" ] } ], "source": [ "# list of comments containing the word 'Croissance'\n", "cmt_list = comments.search(\"Croissance\")\n", "print(\"comments containing the word 'Croissance':\\n\", cmt_list)\n", "\n", "# list of tables containing the word 'Croissance'\n", "tbl_list = tables.search(\"Croissance\")\n", "print(\"tables containing the word 'Croissance':\\n\", tbl_list)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Plotting Variables\n", "\n", "To plot *variables*, you can use the [plot](../_generated/iode.Variables.plot.rst#iode.Variables.plot) method of the [variables](../_generated/iode.Variables.rst#iode.Variables) workspace:" ] }, { "cell_type": "code", "execution_count": 231, "metadata": {}, "outputs": [ { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/plain": [ "" ] }, "execution_count": 231, "metadata": {}, "output_type": "execute_result" } ], "source": [ "vars_subset = variables[\"AOUC;AOUC_;AQC\"]\n", "vars_subset.plot()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Execute Identities\n", "\n", "To execute an identity, use the [execute()](../_generated/iode.Identities.execute.rst#iode.Identities.execute) method of the [identities](../_generated/iode.Identities.rst#iode.Identities) workspace:" ] }, { "cell_type": "code", "execution_count": 232, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.idt\n", "48 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.var\n", "394 objects loaded\n", "100*((QAF_/Q_F)-1)\n", "100*(QAFF_/(Q_F+Q_I))\n" ] }, { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 2\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1960Y1:2015Y1\n", "mode: LEVEL\n", "\n", "name\t1960Y1\t1961Y1\t1962Y1\t1963Y1\t1964Y1\t1965Y1\t...\t2009Y1\t2010Y1\t2011Y1\t2012Y1\t2013Y1\t2014Y1\t2015Y1\n", "GAP2\t 0.00\t 0.00\t 0.00\t 0.00\t 0.00\t 0.00\t...\t 0.00\t 0.00\t 0.00\t 0.00\t 0.00\t 0.00\t 0.00\n", "GAP_\t 0.00\t 0.00\t 0.00\t 0.00\t 0.00\t 0.00\t...\t 0.00\t 0.00\t 0.00\t 0.00\t 0.00\t 0.00\t 0.00" ] }, "execution_count": 232, "metadata": {}, "output_type": "execute_result" } ], "source": [ "identities.load(f\"{SAMPLE_DATA_DIR}/fun.idt\")\n", "variables.load(f\"{SAMPLE_DATA_DIR}/fun.var\")\n", "\n", "print(identities[\"GAP_\"])\n", "print(identities[\"GAP2\"])\n", "\n", "# reset variables GAP_ and GAP2\n", "variables[\"GAP_\"] = 0.\n", "variables[\"GAP2\"] = 0. \n", "variables[\"GAP_;GAP2\"] \n" ] }, { "cell_type": "code", "execution_count": 233, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 2\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1960Y1:2015Y1\n", "mode: LEVEL\n", "\n", "name\t1960Y1\t1961Y1\t1962Y1\t1963Y1\t1964Y1\t1965Y1\t...\t2009Y1\t2010Y1\t2011Y1\t2012Y1\t2013Y1\t2014Y1\t2015Y1\n", "GAP2\t 96.93\t 97.40\t 98.37\t 97.71\t100.88\t100.63\t...\t100.85\t100.54\t101.36\t102.19\t102.50\t102.15\t101.59\n", "GAP_\t -3.20\t -3.98\t -2.12\t -2.65\t -0.23\t -0.65\t...\t 1.96\t 1.61\t 2.61\t 3.61\t 4.06\t 3.78\t 3.24" ] }, "execution_count": 233, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# compute GAP_ and GAP2 (assuming Scalars and Variables are already loaded)\n", "identities.execute(\"GAP_;GAP2\")\n", "variables[\"GAP_;GAP2\"] " ] }, { "cell_type": "code", "execution_count": 234, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 2\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1998Y1:2007Y1\n", "mode: LEVEL\n", "\n", "name\t1998Y1\t1999Y1\t2000Y1\t2001Y1\t2002Y1\t2003Y1\t2004Y1\t2005Y1\t2006Y1\t2007Y1\n", "GAP2\t 0.00\t 0.00\t104.61\t103.06\t102.17\t102.82\t104.47\t104.36\t 0.00\t 0.00\n", "GAP_\t 0.00\t 0.00\t 4.51\t 3.31\t 2.62\t 3.46\t 5.48\t 5.58\t 0.00\t 0.00" ] }, "execution_count": 234, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# compute GAP_ and GAP2 over a subset of the sample\n", "variables[\"GAP_\"] = 0.\n", "variables[\"GAP2\"] = 0.\n", "identities.execute(\"GAP_;GAP2\", \"2000Y1\", \"2005Y1\")\n", "variables[\"GAP_;GAP2\", \"1998Y1:2007Y1\"] " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Arithmetic Operations On Variables" ] }, { "cell_type": "code", "execution_count": 235, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.var\n", "394 objects loaded\n" ] }, { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 5\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1991Y1:1995Y1\n", "mode: LEVEL\n", "\n", " name\t1991Y1\t1992Y1\t1993Y1\t1994Y1\t1995Y1\n", "ACAF \t 26.24\t 30.16\t 34.66\t 8.16\t-13.13\n", "ACAG \t-30.93\t-40.29\t-43.16\t-16.03\t-41.85\n", "AOUC \t 1.02\t 1.03\t 1.03\t 1.05\t 1.05\n", "AOUC_\t 0.96\t 0.97\t 0.98\t 0.99\t 1.00\n", "AQC \t 1.06\t 1.11\t 1.15\t 1.16\t 1.16" ] }, "execution_count": 235, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# reload variables to start from a clean state\n", "variables.load(f\"{SAMPLE_DATA_DIR}/fun.var\")\n", "\n", "# select a subset of variables for the examples below\n", "vars_subset = variables[\"A*\", \"1991Y1:1995Y1\"]\n", "vars_subset" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### With a float" ] }, { "cell_type": "code", "execution_count": 236, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 5\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1991Y1:1995Y1\n", "mode: LEVEL\n", "\n", " name\t1991Y1\t1992Y1\t1993Y1\t1994Y1\t1995Y1\n", "ACAF \t 28.24\t 32.16\t 36.66\t 10.16\t-11.13\n", "ACAG \t-28.93\t-38.29\t-41.16\t-14.03\t-39.85\n", "AOUC \t 3.02\t 3.03\t 3.03\t 3.05\t 3.05\n", "AOUC_\t 2.96\t 2.97\t 2.98\t 2.99\t 3.00\n", "AQC \t 3.06\t 3.11\t 3.15\t 3.16\t 3.16" ] }, "execution_count": 236, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# add a scalar to all values of a subset of variables\n", "new_vars_subset = vars_subset + 2.0\n", "new_vars_subset" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Between (Subsets Of) Variables Objects" ] }, { "cell_type": "code", "execution_count": 237, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Workspace: Variables\n", "nb variables: 5\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1991Y1:1995Y1\n", "mode: LEVEL\n", "\n", " name\t1991Y1\t1992Y1\t1993Y1\t1994Y1\t1995Y1\n", "ACAF \t 52.48\t 60.32\t 69.32\t 16.32\t-26.26\n", "ACAG \t-61.87\t-80.57\t-86.32\t-32.06\t-83.69\n", "AOUC \t 2.05\t 2.06\t 2.06\t 2.09\t 2.10\n", "AOUC_\t 1.93\t 1.95\t 1.96\t 1.98\t 1.99\n", "AQC \t 2.13\t 2.22\t 2.31\t 2.31\t 2.32" ] }, "execution_count": 237, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# add two subsets of variables\n", "new_vars_subset = vars_subset + vars_subset\n", "new_vars_subset" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### With pandas Series or DataFrame\n", "\n", "See the `Arithmetic Operations On Variables With pandas Series And DataFrames` section from the [IODE and pandas](pandas.ipynb) tutorial for more details." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### With larray Arrays\n", "\n", "See the `Arithmetic Operations On Variables With larray Array objects` section from the [IODE and larray](larray.ipynb) tutorial for more details." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### With numpy ndarrays\n", "\n", "See the `Arithmetic Operations On Variables With numpy ndarray objects` section from the [IODE and numpy](numpy.ipynb) tutorial for more details." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Estimation\n", "\n", "To estimate either one equation or a block of equations, use the [estimate](../_generated/iode.Equation.estimate.rst#iode.Equation.estimate) method of the [Equation](../_generated/iode.Equation.rst#iode.Equation) class or the [estimate](../_generated/iode.Equations.estimate.rst#iode.Equations.estimate) method of the [Equations](../_generated/iode.Equations.rst#iode.Equations) workspace:\n", "\n", "Calling the `estimate(from_period, to_period, list_eqs, quiet)` method estimates an equation or a block of equations in the specified periods range.\n", "\n", "At the end of the estimation process, certain variables and scalars are automatically created \n", "if the process has converged. These variables and scalars can be used for computational purposes and, \n", "as they are part of the global workspace, can be saved for future use.\n", "\n", "The tests resulting from the last estimation are saved as scalars. The same applies to residuals, \n", "left-hand and right-hand members of equations.\n", "\n", "Saved tests (as scalars) have the following names (`e_*` for the equation of the block):\n", "\n", " * `e_n` : number of sample periods \n", " * `e_k` : number of estimated coefficients \n", " * `e_stdev` : std dev of residuals \n", " * `e_meany` : mean of Y \n", " * `e_ssres` : sum of squares of residuals \n", " * `e_stderr` : std error \n", " * `e_stderrp` : std error percent (in %) \n", " * `e_fstat` : F-Stat \n", " * `e_r2` : R square \n", " * `e_r2adj` : adjusted R-squared \n", " * `e_dw` : Durbin-Watson \n", " * `e_loglik` : Log Likelihood \n", "\n", "Calculated series are saved in special variables:\n", "\n", " * `_YCALC` : right-hand side of the equation in the block\n", " * `_YOBS` : left-hand side of the equation in the block \n", " * `_YRES` : residuals of the equation of the block \n", "\n", "Outside the estimation sample, the series values are `NA`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's start by reloading all workspaces:" ] }, { "cell_type": "code", "execution_count": 238, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.cmt\n", "317 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.eqs\n", "274 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.idt\n", "48 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.lst\n", "17 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.scl\n", "161 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.tbl\n", "46 objects loaded\n", "Loading C:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data/fun.var\n", "394 objects loaded\n" ] } ], "source": [ "comments.load(f\"{SAMPLE_DATA_DIR}/fun.cmt\")\n", "equations.load(f\"{SAMPLE_DATA_DIR}/fun.eqs\")\n", "identities.load(f\"{SAMPLE_DATA_DIR}/fun.idt\")\n", "lists.load(f\"{SAMPLE_DATA_DIR}/fun.lst\")\n", "scalars.load(f\"{SAMPLE_DATA_DIR}/fun.scl\")\n", "tables.load(f\"{SAMPLE_DATA_DIR}/fun.tbl\")\n", "variables.load(f\"{SAMPLE_DATA_DIR}/fun.var\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Example for one equation:" ] }, { "cell_type": "code", "execution_count": 239, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ACAF equation LEC: (ACAF/VAF[-1]) :=acaf1+acaf2*GOSF[-1]+\n", "acaf4*(TIME=1995)\n", "ACAF equations coefficients (= scalars): ['acaf1', 'acaf2', 'acaf4']\n", "ACAF equations variables: ['ACAF', 'VAF', 'GOSF', 'TIME']\n", "scalars names in scalars_copy: ['acaf1', 'acaf2', 'acaf4']\n", "Estimating : iteration 1 (||eps|| = 0.173205)\n", "Estimating : iteration 2 (||eps|| = 5.16075e-09)\n", "Solution reached after 2 iteration(s). Creating results file ...\n", "Estimating : iteration 1 (||eps|| = 7.05003e-13)\n", "Solution reached after 1 iteration(s). Creating results file ...\n", "Equation estimation success: True\n", "Resulting values for the coefficient 'acaf1': Scalar(0.0157705, 1, 0.00136949)\n", "Resulting values for the coefficient 'acaf2': Scalar(-7.96505e-06, 1, 1.48247e-06)\n", "Resulting values for the coefficient 'acaf4': Scalar(-0.0085027, 1, 0.00208257)\n" ] } ], "source": [ "# ---- estimate coefficients of one equation ----\n", "print(f\"ACAF equation LEC: {equations['ACAF'].lec}\")\n", "print(f\"ACAF equations coefficients (= scalars): {equations['ACAF'].coefficients}\")\n", "print(f\"ACAF equations variables: {equations['ACAF'].variables}\")\n", "\n", "# copy the original values of the coefficients into an isolated scalars workspace\n", "# Useful to restore the original values if the estimation process didn't go well\n", "scalars_copy = scalars[equations['ACAF'].coefficients].copy()\n", "print(f\"scalars names in scalars_copy: {scalars_copy.names}\")\n", "\n", "# reset scalars\n", "for name in equations['ACAF'].coefficients:\n", " scalars[name] = 0., 1.\n", "\n", "# estimate the 'ACAF' equation for the periods ranging from '1980Y1' to '1996Y1'\n", "success = equations.estimate(\"1980Y1\", \"1996Y1\", \"ACAF\")\n", "# or equivalently\n", "success = equations[\"ACAF\"].estimate(\"1980Y1\", \"1996Y1\")\n", "print(f\"Equation estimation success: {success}\")\n", "\n", "print(f\"Resulting values for the coefficient 'acaf1': {scalars['acaf1']}\")\n", "print(f\"Resulting values for the coefficient 'acaf2': {scalars['acaf2']}\")\n", "print(f\"Resulting values for the coefficient 'acaf4': {scalars['acaf4']}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Example for a block of equations:" ] }, { "cell_type": "code", "execution_count": 240, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ACAF equation LEC: (ACAF/VAF[-1]) :=acaf1+acaf2*GOSF[-1]+\n", "acaf4*(TIME=1995)\n", "ACAF equations coefficients (= scalars): ['acaf1', 'acaf2', 'acaf4']\n", "ACAF equations variables: ['ACAF', 'VAF', 'GOSF', 'TIME']\n", "DPUH equation LEC: dln (DPUH/DPUHO):=dpuh_1+dpuh_2*dln(IHU/PI5)+dln PC\n", "DPUH equations coefficients (= scalars): ['dpuh_1', 'dpuh_2']\n", "DPUH equations variables: ['DPUH', 'DPUHO', 'IHU', 'PI5', 'PC']\n", "scalars names in scalars_copy: ['acaf1', 'acaf2', 'acaf4', 'dpuh_1', 'dpuh_2']\n", "Estimating : iteration 1 (||eps|| = 0.223607)\n", "Estimating : iteration 2 (||eps|| = 5.16075e-09)\n", "Solution reached after 2 iteration(s). Creating results file ...\n", "Estimating : iteration 1 (||eps|| = 4.38565e-12)\n", "Solution reached after 1 iteration(s). Creating results file ...\n", "Block estimation success: True\n", "Resulting values for the coefficient 'acaf1': Scalar(0.0157705, 1, 0.00136079)\n", "Resulting values for the coefficient 'acaf2': Scalar(-7.96505e-06, 1, 1.47188e-06)\n", "Resulting values for the coefficient 'acaf4': Scalar(-0.0085027, 1, 0.00206603)\n", "Resulting values for the coefficient 'dpuh_1': Scalar(0.0109855, 1, 0.00481857)\n", "Resulting values for the coefficient 'dpuh_2': Scalar(0.0574893, 1, 0.0368951)\n" ] } ], "source": [ "# ---- estimate a block of equations ----\n", "print(f\"ACAF equation LEC: {equations['ACAF'].lec}\")\n", "print(f\"ACAF equations coefficients (= scalars): {equations['ACAF'].coefficients}\")\n", "print(f\"ACAF equations variables: {equations['ACAF'].variables}\")\n", "print(f\"DPUH equation LEC: {equations['DPUH'].lec}\")\n", "print(f\"DPUH equations coefficients (= scalars): {equations['DPUH'].coefficients}\")\n", "print(f\"DPUH equations variables: {equations['DPUH'].variables}\")\n", "\n", "# copy the original values of the coefficients into an isolated scalars workspace\n", "# Useful to restore the original values if the estimation process didn't go well\n", "scalars_names = equations['ACAF'].coefficients + equations['DPUH'].coefficients\n", "scalars_names = list(set(scalars_names)) # removed duplicates\n", "scalars_copy = scalars[scalars_names].copy()\n", "print(f\"scalars names in scalars_copy: {scalars_copy.names}\")\n", "\n", "# reset scalars\n", "for name in equations['ACAF'].coefficients:\n", " scalars[name] = 0., 1.\n", "for name in equations['DPUH'].coefficients:\n", " scalars[name] = 0., 1.\n", "\n", "# prepare equations (same block and method)\n", "block = \"ACAF;DPUH\"\n", "for name in block.split(\";\"):\n", " equations[name] = {\"block\": block, \"method\": \"LSQ\"}\n", "\n", "# estimation the block 'ACAF;DPUH' for the periods ranging from '1980Y1' to '1996Y1'\n", "success = equations.estimate(\"1980Y1\", \"1996Y1\", block)\n", "print(f\"Block estimation success: {success}\")\n", "\n", "print(f\"Resulting values for the coefficient 'acaf1': {scalars['acaf1']}\")\n", "print(f\"Resulting values for the coefficient 'acaf2': {scalars['acaf2']}\")\n", "print(f\"Resulting values for the coefficient 'acaf4': {scalars['acaf4']}\")\n", "print(f\"Resulting values for the coefficient 'dpuh_1': {scalars['dpuh_1']}\")\n", "print(f\"Resulting values for the coefficient 'dpuh_2': {scalars['dpuh_2']}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Simulation\n", "\n", "To simulate a model, you must create and initialize an instance of the [Simulation](../_generated/iode.Simulation.rst#iode.Simulation) class.\n", "\n", "### Models\n", "\n", "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:\n", "\n", "```\n", "BLOC1 : A, B, C, D\n", "BLOC2 : X, Y\n", "BLOC3 : C1, C2, C3, C4\n", "BLOC4 : X_A1, X_A2, X_A3\n", "BLOC5 : R1, R2, R3, S_12\n", "MODSIM : $BLOC1, $BLOC2, $BLOC3, $BLOC4, $BLOC5\n", "```\n", "\n", "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.\n", " \n", "### Exchange Endo-Exo\n", "\n", "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.\n", "See the documentation of the [model_exchange](../_generated/iode.Simulation.model_exchange.rst#iode.Simulation.model_exchange) method.\n", "\n", "### Newton-Raphson Algorithm\n", "\n", "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:\n", " \n", "$$\n", "X = a + \\frac{b}{X + 1}\n", "$$\n", " \n", "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:\n", " \n", "$$\n", "(X - a) * (X + 1) = b\n", "$$\n", " \n", "
\n", "Warning:\n", "\n", "a) 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.\n", " \n", "b) 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.\n", "
\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Examples" ] }, { "cell_type": "code", "execution_count": 241, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "possible sort algorithms: ['CONNEX', 'BOTH', 'NONE']\n" ] } ], "source": [ "from iode import SimulationSort\n", "\n", "print(f\"possible sort algorithms: {[member.name for member in SimulationSort]}\")" ] }, { "cell_type": "code", "execution_count": 242, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "possible initialization methods: ['TM1', 'TM1_A', 'EXTRA', 'EXTRA_A', 'ASIS', 'TM1_NA', 'EXTRA_NA']\n" ] } ], "source": [ "from iode import SimulationInitialization\n", "\n", "print(f\"possible initialization methods: {[member.name for member in SimulationInitialization]}\")" ] }, { "cell_type": "code", "execution_count": 243, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "--- Simulation ---\n", "convergence_threshold = 0.001\n", "relax = 1.0\n", "max_nb_iterations = 100\n", "sort_algorithm = BOTH (Connex compon. + Triangulation)\n", "initialization_method = TM1 (Y := Y[-1], if Y null or NA)\n", "debug = False\n", "nb_passes = 5\n", "debug_newton = False\n", "------------------\n" ] } ], "source": [ "from iode import Simulation\n", "\n", "# create and initialize a Simulation instance\n", "simu = Simulation(sort_algorithm=SimulationSort.BOTH, initialization_method=SimulationInitialization.TM1)\n", "print(simu)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To run the simulation, call the [Simulation.model_simulate](../_generated/iode.Simulation.model_simulate.rst#iode.Simulation.model_simulate) method:" ] }, { "cell_type": "code", "execution_count": 244, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "exogenous variable 'UY': UY := NATY-NDOMY-NIY-NGY-(EFXY-EFMY)-NFY\n", "endogenous variable 'XNATY': grt NATY\n", "exogenous variable 'UY' before simulation:\n", "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1998Y1:2005Y1\n", "mode: LEVEL\n", "\n", "name\t1998Y1\t1999Y1\t2000Y1\t2001Y1\t2002Y1\t2003Y1\t2004Y1\t2005Y1\n", "UY \t671.46\t647.39\t 0.00\t 0.00\t 0.00\t 0.00\t 0.00\t 0.00\n", "\n", "Simulation success: True\n", "exogenous variable 'UY' after simulation:\n", "Workspace: Variables\n", "nb variables: 1\n", "filename: c:\\soft\\miniconda3\\Lib\\site-packages\\iode\\tests\\data\\fun.var\n", "description: Modèle fun - Simulation 1 \n", "sample: 1998Y1:2005Y1\n", "mode: LEVEL\n", "\n", "name\t1998Y1\t1999Y1\t2000Y1\t2001Y1\t2002Y1\t2003Y1\t2004Y1\t2005Y1\n", "UY \t671.46\t647.39\t624.18\t645.05\t661.61\t676.56\t680.90\t682.99\n", "\n" ] } ], "source": [ "print(f\"exogenous variable 'UY': {equations['UY'].lec}\")\n", "print(f\"endogenous variable 'XNATY': {identities['XNATY']}\")\n", "# reset values of exogenous variable\n", "variables[\"UY\", \"2000Y1:2015Y1\"] = 0.0\n", "\n", "print(f\"exogenous variable 'UY' before simulation:\\n{variables['UY', '1998Y1:2005Y1']}\")\n", "\n", "# run the simulation for the periods range '2000Y1' to '2015Y1'\n", "success = simu.model_simulate(\"2000Y1\", \"2015Y1\", quiet=True)\n", "print(f\"Simulation success: {success}\")\n", "\n", "print(f\"exogenous variable 'UY' after simulation:\\n{variables['UY', '1998Y1:2005Y1']}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Import/Export IODE workspaces from/to pandas Series and DataFrame\n", "\n", "To import / export the content of the `comments`, `identities` and `lists` workspaces from/to a pandas Series object, use the [from_series()](../_generated/iode.Comments.from_series.rst#iode.Comments.from_series) and [to_series()](../_generated/iode.Comments.to_series.rst#iode.Comments.to_series) methods. \n", "\n", "Alternatively, you can use the [series](../_generated/iode.Comments.series.rst#iode.Comments.series) property to export the content of the `comments`, `identities` and `lists` workspaces to a pandas Series object.\n", "\n", "For the examples, see the [pandas tutorial](pandas.ipynb)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Import/Export IODE Variables workspace from/to numpy ndarray\n", "\n", "To import / export the content of the `Variables` workspace (or a subset of it) from/to a numpy ndarray object, use the [from_numpy](../_generated/iode.Variables.from_numpy.rst#iode.Variables.from_numpy) and [to_numpy](../_generated/iode.Variables.to_numpy.rst#iode.Variables.to_numpy) methods.\n", "\n", "For the examples, see the [numpy tutorial](numpy.ipynb)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Import/Export the Variables workspace from/to LArray Array\n", "\n", "To import / export the content of the `variables` workspaces from/to an LArray Array object, use the [from_array()](../_generated/iode.Variables.from_array.rst#iode.Variables.from_array) and [to_array()](../_generated/iode.Variables.to_array.rst#iode.Variables.to_array) methods.\n", "\n", "For the examples, see the [larray tutorial](larray.ipynb)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Execute IODE report commands/files\n", "\n", "To run an IODE command, use the [execute_command()](../_generated/iode.execute_command.rst#iode.execute_command) function:" ] }, { "cell_type": "code", "execution_count": 245, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Execute IODE commands (useful for IODE functions and commands not yet ported to Python):\n", "iode> $WsClearVar\n", "iode> $WsSample 2000Y1 2005Y1\n", "iode> $DataCalcVar A t+1\n", "iode> $DataCalcVar B t-1\n", "iode> $DataCalcVar C A/B\n", "iode> $DataCalcVar D grt A\n", "iode> $WsSaveVar test_var.av\n", "Saving test_var.av\n", "sample 2000Y1 2005Y1\n", "A 1 2 3 4 5 6 \n", "B -1 0 1 2 3 4 \n", "C -1 na 3 2 1.66666666666667 1.5 \n", "D na 100 50 33.3333333333333 25 20 \n", "\n" ] } ], "source": [ "from iode import execute_command\n", "\n", "# ---- execute IODE commands ----\n", "print(\"Execute IODE commands (useful for IODE functions and commands not yet ported to Python):\")\n", "execute_command(\"$WsClearVar\")\n", "execute_command(\"$WsSample 2000Y1 2005Y1\")\n", "execute_command(\"$DataCalcVar A t+1\")\n", "execute_command(\"$DataCalcVar B t-1\")\n", "execute_command(\"$DataCalcVar C A/B\")\n", "execute_command(\"$DataCalcVar D grt A\")\n", "execute_command(\"$WsSaveVar test_var.av\")\n", "with open(\"test_var.av\", \"r\") as f:\n", " print(f.read())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To run an entire IODE report (i.e. file with the '.rep' extension), call the [execute_report()](../_generated/iode.execute_report.rst#iode.execute_report) function:" ] }, { "cell_type": "code", "execution_count": 246, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Execute an IODE report -> execute_report()\n", "iode> $WsClearVar\n", "iode> $WsSample 2000Y1 2005Y1\n", "iode> $DataCalcVar A t+1\n", "iode> $DataCalcVar B t-1\n", "iode> $DataCalcVar C A/B\n", "iode> $DataCalcVar D grt A\n", "iode> $WsSaveVar test_var.av\n", "Saving test_var.av\n", "sample 2000Y1 2005Y1\n", "A 1 2 3 4 5 6 \n", "B -1 0 1 2 3 4 \n", "C -1 na 3 2 1.66666666666667 1.5 \n", "D na 100 50 33.3333333333333 25 20 \n", "\n" ] } ], "source": [ "from iode import execute_report\n", "\n", "# ---- execute IODE reports ----\n", "print(\"Execute an IODE report -> execute_report()\")\n", "with open(\"create_var.rep\", \"w\") as f:\n", " f.write(\"$WsClearVar\\n\")\n", " f.write(\"$WsSample 2000Y1 2005Y1\\n\")\n", " f.write(\"$DataCalcVar %1% t+1 \\n\")\n", " f.write(\"$DataCalcVar %2% t-1 \\n\")\n", " f.write(\"$DataCalcVar %3% %1%/%2%\\n\")\n", " f.write(\"$DataCalcVar %4% grt %1% \\n\")\n", " f.write(\"$WsSaveVar test_var.av\\n\")\n", "\n", "execute_report(\"create_var.rep\", [\"A\", \"B\", \"C\", \"D\"])\n", "\n", "with open(\"test_var.av\", \"r\") as f:\n", " print(f.read())\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Graphical User Interface\n", "\n", "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()](../_generated/iode.view_workspace.rst#iode.view_workspace) to open the GUI." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Content of a Python script:\n", "\n", "```python\n", "from iode import view_workspace, ...\n", "\n", "... code here ...\n", "\n", "# To view the workspace, you can use the following command:\n", "view_workspace()\n", "\n", "# To open the graphical user interface showing the files \n", "# from a specific directory, pass the path to the directory \n", "# as an argument:\n", "view_workspace(\"path/to/your/directory\")\n", "\n", "... code here ...\n", "```" ] } ], "metadata": { "kernelspec": { "display_name": "base", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.14.3" } }, "nbformat": 4, "nbformat_minor": 2 }