{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# IODE Python Tutorial\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 1. Introduction and Setup\n", "\n", "First, we will import the necessary libraries and check our IODE version." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "IODE version: 7.0.0\n", "Help on method load in module iode.iode_python:\n", "\n", "load(filepath: 'str') method of pyiode.iode_python.Equations instance\n", " load(self, filepath: str)\n", " \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 SAMPLE_DATA_DIR\n", " >>> from iode import comments, variables\n", " >>> comments.load(f\"{SAMPLE_DATA_DIR}/fun.cmt\")\n", " >>> len(comments)\n", " 317\n", " \n", " >>> variables.load(f\"{SAMPLE_DATA_DIR}/fun.var\")\n", " >>> len(variables)\n", " 394\n", "\n", "Equations.load() documentation:\n", "None\n" ] } ], "source": [ "import numpy as np\n", "import pandas as pd\n", "import larray as la\n", "import iode as io\n", "\n", "# Check IODE version\n", "print(f\"IODE version: {io.__version__}\")\n", "\n", "# Display documentation for a specific function\n", "print(f\"Equations.load() documentation:\\n{help(io.equations.load)}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2. Loading and Exploring Data\n", "\n", "IODE works with different types of data: equations, identities, scalars, and variables." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Number of equations: 274\n", "Number of identities: 48\n", "Number of scalars: 161\n", "Number of variables: 394\n", "\n", "All equation names:\n", "['ACAF', 'ACAG', 'AOUC', 'BENEF', 'BQY', 'BRUGP', 'BVY', 'CGU', 'COEFON', 'COTRES', 'DEBT', 'DPU', 'DPUF', 'DPUG', 'DPUGO', 'DPUH', 'DPUU', 'DTF', 'DTH', 'DTH1', 'DTH1C', 'EX', 'EXC', 'EXCC', 'FLF', 'FLG', 'FLGR', 'GAP', 'GOSF', 'GOSG', 'GOSH', 'GOSH_', 'IDF', 'IDG', 'IDH', 'IFU', 'IHU', 'IT', 'ITCEE', 'ITCR', 'ITD', 'ITEP', 'ITF', 'ITF5', 'ITFC', 'ITFGI', 'ITFGO', 'ITFQ', 'ITGR', 'ITI5R', 'ITIFR', 'ITIGR', 'ITM', 'ITMQ', 'ITMQR', 'ITNQ', 'ITON', 'ITONQ', 'ITPL', 'ITPR', 'ITPS', 'ITT', 'IUG', 'KL', 'KLFHP', 'KN5', 'KNF', 'KNFF', 'KNFFY', 'KNFY', 'KNI', 'KNIY', 'NATY', 'NFY', 'NFYH', 'OCUF', 'OCUG', 'OCUH', 'PAF_', 'PAG', 'PAH', 'PBBP', 'PBNP', 'PC', 'PC_', 'PDPUG', 'PFI', 'PFI_', 'PFND', 'PG', 'PI5', 'PIF', 'PIG', 'PKF', 'PM', 'PMAB', 'PME', 'PMS', 'PMT', 'POIL', 'PQOG', 'PROD', 'PW3', 'PWBG', 'PWMAB', 'PWMS', 'PWXAB', 'PWXS', 'PX', 'PXAB', 'PXB', 'PXE', 'PXS', 'PXT', 'QAF', 'QAFF', 'QAFF_', 'QAF_', 'QAG', 'QAH', 'QAI', 'QAI_', 'QAT', 'QAT_', 'QBBP', 'QBBPPOT_', 'QBBP_B', 'QBBP_P', 'QBNP', 'QC', 'QC_', 'QFND', 'QG', 'QGO', 'QI', 'QI5', 'QIF', 'QIG', 'QL', 'QM', 'QMAB', 'QME', 'QMS', 'QMT', 'QOUG', 'QQMAB_', 'QS', 'QS_', 'QWXAB', 'QWXS', 'QWXSS', 'QX', 'QXAB', 'QXB', 'QXE', 'QXS', 'QXT', 'Q_F', 'Q_I', 'RDEBT', 'RENT', 'RIDG', 'RIDGG', 'RIPBE', 'RLBE', 'RSBE', 'SBF', 'SBF3L', 'SBG', 'SBGX', 'SBH', 'SF', 'SG', 'SH', 'SSF', 'SSF3', 'SSF3L', 'SSF3P', 'SSFDOM', 'SSFF', 'SSFFIC', 'SSFFX', 'SSFG', 'SSH', 'SSH3GP', 'SSH3O', 'SSH3P', 'SSH3W', 'SSH3WA', 'SSH3WW', 'SSH3ZA', 'SSH3ZW', 'SSHFF', 'SUB', 'SUBCEE', 'TFPFHP_', 'TWG', 'TWGP', 'ULCP', 'UY', 'VAF', 'VAFF', 'VAFF_', 'VAF_', 'VAG', 'VAH', 'VAI', 'VAI_', 'VAMARE', 'VAT', 'VAT_', 'VBBP', 'VBBP_B', 'VBBP_P', 'VBNP', 'VBNP_B', 'VBNP_I', 'VBNP_P', 'VC', 'VC_', 'VI', 'VI5', 'VIF', 'VM', 'VMAB', 'VME', 'VMK', 'VMN', 'VMS', 'VMT', 'VS', 'VS_', 'VX', 'VXAB', 'VXB', 'VXE', 'VXK', 'VXN', 'VXS', 'VXT', 'W', 'WBF', 'WBF_', 'WBG', 'WBGO', 'WBGP', 'WBU', 'WBU_', 'WCF', 'WCF_', 'WCRH', 'WDOM', 'WG', 'WIND', 'WIND_', 'WLCP', 'WMIN', 'WNF', 'WNF_', 'YDH', 'YDH_', 'YDTG', 'YIDG', 'YK', 'YN', 'YSEFP', 'YSEFT1', 'YSEFT2', 'YSFIC', 'YSSF', 'YSSG', 'ZF', 'ZJ', 'ZZF_']\n", "\n", "Does 'ACAF' equation exist? True\n", "\n", "Current Variables sample: 1960Y1:2015Y1\n" ] } ], "source": [ "# Load sample data\n", "io.equations.load(f\"{io.SAMPLE_DATA_DIR}/fun.eqs\")\n", "io.identities.load(f\"{io.SAMPLE_DATA_DIR}/fun.idt\")\n", "io.scalars.load(f\"{io.SAMPLE_DATA_DIR}/fun.scl\")\n", "io.variables.load(f\"{io.SAMPLE_DATA_DIR}/fun.var\")\n", "\n", "# Explore the loaded data\n", "print(f\"Number of equations: {len(io.equations)}\")\n", "print(f\"Number of identities: {len(io.identities)}\")\n", "print(f\"Number of scalars: {len(io.scalars)}\")\n", "print(f\"Number of variables: {len(io.variables)}\")\n", "\n", "# List all equation names\n", "print(f\"\\nAll equation names:\\n{io.equations.names}\")\n", "\n", "# Check for a specific equation\n", "print(f\"\\nDoes 'ACAF' equation exist? {'ACAF' in io.equations}\")\n", "\n", "# Get the current sample period for variables\n", "print(f\"\\nCurrent Variables sample: {io.variables.sample}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Working with Subsets\n", "\n", "IODE allows you to subset variables using patterns." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Variables in the subset:\n", "ACAF\n", "ACAG\n", "AOUC\n", "AOUC_\n", "AQC\n", "GAP_\n", "GOSH_\n", "PAF_\n", "PC_\n", "PFI_\n", "PROIHP_\n", "QAFF_\n", "QAF_\n", "QAI_\n", "QAT_\n", "QBBPPOT_\n", "QC_\n", "QQMAB_\n", "QS_\n", "TFPFHP_\n", "VAFF_\n", "VAF_\n", "VAI_\n", "VAT_\n", "VC_\n", "VS_\n", "WBF_\n", "WBU_\n", "WCF_\n", "WIND_\n", "WNF_\n", "YDH_\n", "ZZF_\n" ] } ], "source": [ "# Create a subset of variables starting with 'A' or ending with '_'\n", "vars_subset = io.variables[\"A*;*_\"]\n", "\n", "print(\"Variables in the subset:\")\n", "for name in vars_subset:\n", " print(name)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 3. Working with Equations and Variables\n", "\n", "Let us explore how to manipulate equations and variables in IODE." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Get a specific equation\n", "eq_ACAF = io.equations[\"ACAF\"]\n", "print(f\"ACAF equation:\\n{eq_ACAF}\\n\")\n", "\n", "# Add a new equation\n", "io.equations[\"NEW_EQ\"] = \"NEW_EQ := 2 * X + Y\"\n", "print(f\"Added NEW_EQ: {io.equations['NEW_EQ']}\\n\")\n", "\n", "# Delete an equation\n", "del io.equations[\"NEW_EQ\"]\n", "print(f\"'NEW_EQ' removed: {'NEW_EQ' not in io.equations}\\n\")\n", "\n", "# Get a whole variable\n", "print(f\"Variable 'ACAF':\\n{io.variables['ACAF']}\\n\")\n", "\n", "# Get a variable for a specific period\n", "print(f\"ACAF in 2000Y1: {io.variables['ACAF', '2000Y1']}\\n\")\n", "\n", "# Get a variable for a range of periods\n", "print(f\"ACAF from 2000Y1 to 2010Y1:\\n{io.variables['ACAF', '2000Y1:2010Y1']}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 4. Estimating Coefficients\n", "\n", "IODE provides tools for estimating coefficients of equations. Let us look at how to do this for a single equation and for a block of equations." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Examine an equation before estimation\n", "print(f\"ACAF equation LEC: {io.equations['ACAF'].lec}\")\n", "print(f\"ACAF coefficients: {io.equations['ACAF'].coefficients}\")\n", "print(f\"ACAF variables: {io.equations['ACAF'].variables}\\n\")\n", "\n", "# Reset coefficients\n", "for name in io.equations['ACAF'].coefficients:\n", " io.scalars[name] = 0., 1.\n", "\n", "# Estimate the equation\n", "io.equations.estimate(\"1980Y1\", \"1996Y1\", \"ACAF\")\n", "\n", "# Check results\n", "for coef in ['acaf1', 'acaf2', 'acaf4']:\n", " print(f\"Estimated value for {coef}: {io.scalars[coef]}\")\n", "\n", "print(\"\\nNow let's estimate a block of equations...\\n\")\n", "\n", "# Prepare a block of equations\n", "block = \"ACAF;DPUH\"\n", "for name in block.split(\";\"):\n", " io.equations[name] = {\"block\": block, \"method\": \"LSQ\"}\n", "\n", "# Estimate the block\n", "io.equations.estimate(\"1980Y1\", \"1996Y1\", block)\n", "\n", "# Check results\n", "for coef in ['acaf1', 'acaf2', 'acaf4', 'dpuh_1', 'dpuh_2']:\n", " print(f\"Estimated value for {coef}: {io.scalars[coef]}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 5. Simulation\n", "\n", "IODE provides powerful simulation capabilities." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Create a Simulation instance\n", "simu = io.Simulation(sort_algorithm=io.SimulationSort.BOTH, \n", " initialization_method=io.SimulationInitialization.TM1)\n", "\n", "# Display simulation parameters\n", "print(f\"Simulation parameters:\")\n", "print(f\"Convergence threshold: {simu.convergence_threshold}\")\n", "print(f\"Relaxation factor: {simu.rel}\")\n", "print(f\"Max iterations: {simu.max_nb_iterations}\")\n", "print(f\"Sort algorithm: {simu.sort_algorithm}\")\n", "print(f\"Initialization method: {simu.initialization_method}\")\n", "print(f\"Debug mode: {simu.debug}\")\n", "print(f\"Number of passes: {simu.nb_passes}\")\n", "print(f\"Debug Newton: {simu.debug_newton}\\n\")\n", "\n", "# Prepare for simulation\n", "print(f\"Exogenous variable 'UY': {io.equations['UY'].lec}\")\n", "print(f\"Endogenous variable 'XNATY': {io.identities['XNATY']}\\n\")\n", "\n", "# Reset values of exogenous variable\n", "io.variables[\"UY\", \"2000Y1:2015Y1\"] = 0.0\n", "\n", "print(f\"UY before simulation:\\n{io.variables['UY']}\\n\")\n", "\n", "# Run the simulation\n", "simu.model_simulate(\"2000Y1\", \"2015Y1\")\n", "\n", "print(f\"UY after simulation:\\n{io.variables['UY']}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 6. Data Conversion and Export\n", "\n", "IODE allows for easy conversion between its data structures and common Python data structures like pandas DataFrames and LArrays." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Convert IODE data to pandas DataFrames\n", "df_eqs = io.equations.to_frame()\n", "df_scl = io.scalars.to_frame()\n", "df_vars = io.variables.to_frame()\n", "\n", "print(\"Equations as DataFrame:\")\n", "print(df_eqs.head())\n", "\n", "print(\"\\nScalars as DataFrame:\")\n", "print(df_scl.head())\n", "\n", "print(\"\\nVariables as DataFrame:\")\n", "print(df_vars.head())\n", "\n", "# Convert IODE variables to LArray Array\n", "arr_vars = io.variables.to_array()\n", "print(\"\\nVariables as LArray:\")\n", "print(arr_vars)\n", "\n", "# Converting back to IODE structures\n", "io.equations.from_frame(df_eqs)\n", "io.scalars.from_frame(df_scl)\n", "io.variables.from_frame(df_vars)\n", "io.variables.from_array(arr_vars)\n", "\n", "print(\"\\nData converted back to IODE structures\")\n", "\n", "# Saving IODE data\n", "io.equations.save('equations.eqs') # Save all equations\n", "vars_subset.save('variables_subset.av') # Save a subset of variables\n", "\n", "print(\"\\nSaved equations and variable subset. Contents of variables_subset.av:\")\n", "with open(\"variables_subset.av\", \"r\") as f:\n", " print(f.read())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 7. Advanced IODE Commands\n", "\n", "The Python interface also allows for direct execution of commands not yet available in the Python API and for running complex sequences of operations." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Execute individual IODE commands\n", "print(\"Executing individual IODE commands:\")\n", "io.execute_command(\"$WsClearVar\")\n", "io.execute_command(\"$WsSample 2000Y1 2005Y1\")\n", "io.execute_command(\"$DataCalcVar A t+1\")\n", "io.execute_command(\"$DataCalcVar B t-1\")\n", "io.execute_command(\"$DataCalcVar C A/B\")\n", "io.execute_command(\"$DataCalcVar D grt A\")\n", "io.execute_command(\"$WsSaveVar test_var.av\")\n", "\n", "print(\"\\nIODE commands executed. Contents of test_var.av:\")\n", "with open(\"test_var.av\", \"r\") as f:\n", " print(f.read())\n", "\n", "# Execute an IODE report\n", "print(\"\\nNow, let's execute an IODE 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", "io.execute_report(\"create_var.rep\", [\"A\", \"B\", \"C\", \"D\"])\n", "\n", "print(\"IODE report executed. Updated contents of test_var.av:\")\n", "with open(\"test_var.av\", \"r\") as f:\n", " print(f.read())" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.9.19" } }, "nbformat": 4, "nbformat_minor": 4 }