Notes to accompany version 0.2.0 of my re-implementation of FSIC. To all intents and purposes these changes are backward compatible with version 0.1.0 from an earlier post. The only change which isn’t strictly backward compatible is to the handling of the status and iterations attributes ([4]) below). However, there’s rarely any reason for the user to modify these directly. Version 0.2.0 changes are essentially backward compatible.

1. Support for tab completion in interactive settings
2. Use copy() to duplicate model instances
3. Features to ease manual edits to model definitions
4. Treatment of status and iterations attributes now consistent with that of the economic variables

The examples below use a simplified five-equation version of Godley and Lavoie’s (2007) Model SIM, abstracting away the mechanisms that equalise demand and supply as well as the treatment of the labour market. See the first part of one of my earlier posts for details of the original model.

## Setup

### Model

In this five-equation model, consumption $\left( C \right)$ in time $t$ is a function of disposable income $\left( YD \right)$ and past accumulated wealth $\left( H \right)$. The propensities to consume out of each are $\alpha_1$ and $\alpha_2$, respectively:

Disposable income is national income, $Y$ (here, implicitly equal to household wage income), less taxes $\left( T \right)$:

National income is consumption plus government expenditure, $G$. The economy is closed, and with no investment:

Taxes are levied as a fixed proportion $\left( \theta \right)$ of income:

Households accumulate savings (wealth) over time from the difference between ingoings (income) and outgoings (expenditure):

### Implementation

In FSIC, generate the accompanying class definition as follows (see my earlier post for more details about the syntax and workflow):

## Features

Having constructed an example model, we can take a look at the changes in version 0.2.0. As mentioned above, all but one of these changes is backward compatible. The last one isn’t strictly so but the use cases in which this matters are obscure enough for it not to be a problem in most situations.

### 1. Support for tab completion in interactive settings

Object attributes that point to variable names (e.g. model.C, model.G) are generated dynamically on instantiation. A new custom __dir__() magic method in the base class for models includes the variable names (as well as attributes like span, names, status and iterations) when passing a model object to dir().

['C', 'CHECK', 'CODE', 'ENDOGENOUS', 'ERRORS',
'NAMES', 'PARAMETERS', 'T', 'Y', 'YD',
'alpha_1', 'alpha_2', 'copy', 'iterations', 'names',
'solve', 'solve_period', 'solve_t', 'span', 'status',
'theta', 'values']


### 2. Use copy() to duplicate model instances

Having set up a new model instance with data and parameters, we might want to run different scenarios as separate instances. Rather than generate the model from scratch each time, use copy() to create duplicate instances with the same state (values). The class also supports the copy() and deepcopy() functions from the standard library copy module.

array([[ 0.        , 38.46153068, 47.92898039, 55.93990487, 62.71838627],
[ 0.        , 48.07691335, 59.91123828, 69.92488908, 78.39797772]])


### 3. Features to ease manual edits to model definitions

FSIC makes it easier to define models and generate valid Python code with supporting features (embedded in the base class) for economic modelling. The code so generated defines a derived class that can be edited further, for example, to:

1. change the economic relationships in the model
2. add/remove variables, including those used to check for solution convergence each period
3. add other behaviour e.g. new controls with keyword arguments

As below, the original code is accessible either by:

1. inspecting the CODE attribute of a class definition created with build_model()
2. using build_model_definition() to return the code as a string (and avoid the exec() call that makes the class available during a Python session)

The code above is valid Python code and thus editable to, for example:

1. remove extraneous variable lists like the ERRORS attribute
• delete the ERRORS attribute (equally, you could define new lists of variables)
• edit the (new) NAMES attribute definition to exclude ERRORS (it’s just a list: you can write in lists of strings directly if you want)
• NAMES is important because it’s what the model uses to dynamically generate variables
2. (arbitrarily) reduce the list of variables to be checked for convergence during solution
• CHECK is the other new attribute and defines the names of the variables to test for convergence in solution each period
3. extend the bottom-level _evaluate() function signature with a keyword argument to apply exogenous adjustments to household consumption expenditure (with a new line of code in the function body)
• you can pass keyword arguments down the stack to _evaluate() from any of the solve methods:

The new code is below. Alternatively, see the diff between the code above and below here.

array([[99.7516991 , 99.78989923, 99.82222242, 99.84957282, 99.87271546],
[99.7516991 , 90.17453275, 91.68614743, 92.96520534, 94.04749008]])


### 4. Treatment of status and iterations attributes is now consistent with that of the economic variables

Now, as with the economic variables in a model, there’s protection around the status and iterations attributes to preserve:

• their type as NumPy arrays and, by extension, their shape
• the dtype (variable type) of the arrays
['-' '-' '-' '-' '-']
[-1 -1 -1 -1 -1]

['.' '.' '.' '.' '.']
[ 0 -1  0 -1  0]


See here for this post as a Jupyter notebook along with supporting Python code.

## References

Godley, W., Lavoie, M. (2007) Monetary economics: An integrated approach to credit, money, income, production and wealth, Palgrave Macmillan