Understanding The Sfc_Models Framework Operation
The functioning of the sfc_models packet for edifice Stock-Flow Consistent models is somewhat unusual; the user puts into house high-level operations, together with the framework fills inward most of the details. The user is together with so costless to tweak the details of exceptional sector implementations.
One means of agreement the workflow is to mean value of sfc_models equally the analysis backbone of a computer-aided blueprint program. The user "drags together with drops" economical sectors into a model, together with and so the framework incorporates the outcome. The user tin together with so drill into a exceptional sector's settings to larn to a greater extent than precise command of the outcome. (Such a graphical interface may live built, merely the model code needs to live solidified first.)
This article runs through the simplest possible models that nosotros tin create ("Hello World!"), together with shows how to utilisation the log files to sympathise how the framework builds models based on high grade code.
Since all of the examples coexist inside a unmarried directory, I utilisation a long-winded naming scheme. The intro_3_03 constituent of the file bring upwards tells us that these examples are to live included inward Section 3.3 of Introduction to SFC Models Using Python. Also, delight depository fiscal establishment notation that this code volition exclusively piece of work amongst Version 0.4.1 or afterwards of sfc_models. The logging command used is new.
UPDATE: In the latest versions of sfc_models (>= 0.4.3), it is possible to run a GUI (dialog boxes) to pick out where to install examples. In versions greater than 0.4.3 (which volition belike become far presently after this article was published) use:
from sfc_models import *
install_examples()
In Version 0.4.3, you lot quest to use:
from sfc_models.objects import *
install_examples()
[From intro_3_03_hello_world_1.py:]
# This adjacent line looks bizarre, merely is needed for backwards
# compatibility amongst Python 2.7.
from __future__ import print_function
import sfc_models
from sfc_models.models import Model
print('*Starting upwards logging*')
# Log files are based on bring upwards of this module.
sfc_models.register_standard_logs(output_dir='output',
base_file_name=__file__)
print('*Build Model*')
mod = Model()
print('*Running main()*')
print('*(This volition campaign a warning...)*')
mod.main()
The actual piece of work is done inward these lines (the repose are impress commands together with laid up):
mod = Model()
mod.main()
These 2 lines hit the following:
Running this script generates the output (for versions after 0.4.1):
python intro_3_03_hello_world_1.py
*Starting upwards logging*
*Build Model*
*Running main()*
*(This volition campaign a warning...)*
Warning triggered: There are no equations inward the system.
Process finished amongst leave of absence code 0
If nosotros facial expression at the output, nosotros run across that the exclusively visible output is the echoing of the impress commands; the exclusively affair visible from sfc_models was the line:
Warning triggered: There are no equations inward the system.
(Note: In before versions of the code, the main() telephone phone volition genuinely trigger an fault inward this case; the framework was unhappy amongst no equations inward the system.)
This alarm message is somewhat to live expected: nosotros created a Model object, together with incorporated no information into it. Obviously, at that topographic point should non live whatever equations associated amongst it.
However, it cannot live said that that at that topographic point was no other output; however, that output has been shunted to a log file. I volition right away render to the next constituent call.
sfc_models.register_standard_logs(output_dir='output',
base_file_name=__file__)
The constituent register_standard_logs tells the framework to larn ready to create a measure laid of log files. (You tin register exclusively exceptional logs if you lot desire to a greater extent than precise command of logging.) The constituent has 2 parameters:
When I looked into the output subdirectory, nosotros run across the next files were created.
There are iii text files, whose names are based upon the file bring upwards of the rootage file.
Entity Created: <class 'sfc_models.models.Model'> ID = 0
Starting Model main()
Generating FullSector codes (Model._GenerateFullSectorCodes()
Model._GenerateEquations()
Fixing aliases (Model._FixAliases)
Model._GenerateRegisteredCashFlows()
Adding 0 cash flows to sectors
Processing 0 exogenous variables
Model._CreateFinalEquations()
Generating 0 initial conditions
Error or Warning raised:
Traceback (most recent telephone phone last):
File "c:\Python33\lib\site-packages\sfc_models\models.py", line 140, inward main
self.FinalEquations = self._CreateFinalEquations()
File "c:\Python33\lib\site-packages\sfc_models\models.py", line 499, inward _CreateFinalEquations
enhance Warning('There are no equations inward the system.')
Warning: There are no equations inward the system.
The get-go line of code (mod = Model()) resulted inward i line inward the log.
Entity Created: <class 'sfc_models.models.Model'> ID = 0
The creation of the Model object was noted; it turns out the Model is an Entity equally well, together with it was assigned the ID of 0. This numeric ID is designed to provide an tardily means to distinguish the objects that are created inward the code.
The repose of the log was triggered yesteryear running main(). H5N1 few operations were run, merely they did nada since at that topographic point were no equations inside the system. This lack of equations was diagnosed, together with nosotros halt amongst Raise Warning.
from __future__ import print_function
import sfc_models
from sfc_models.models import Model, Country
from sfc_models.sector_definitions import Household
sfc_models.register_standard_logs(output_dir='output',
base_file_name=__file__)
# Start work.
mod = Model()
can = Country(mod, 'Canada', 'CA')
household = Household(can, 'Household Sector', 'HH',
alpha_income=.7, alpha_fin=.3)
mod.main()
This code add together 2 novel lines.
In the output subdirectory, at that topographic point are iii novel files generated. The '_out.txt' file right away contains around fourth dimension serial that tin live viewed inward a spreadsheet program, together with the equation file has equations. I volition exclusively facial expression at the log file ('_log.txt').
In Version 0.4.1 of sfc_models, the log file starts with:
Entity Created: <class 'sfc_models.models.Model'> ID = 0
Entity Created: <class 'sfc_models.models.Country'> ID = 1
Adding Country: CA ID=1
Entity Created: <class 'sfc_models.sector_definitions.Household'> ID = 2
Adding Sector HH To Country CA
We run across that iii Entity objects are beingness created. The creation of the Household causes a pocket-size flurry of activity. Variables are beingness added.
[ID=2] Variable Added: F = F=LAG_F # Financial assets # Financial assets
[ID=2] Variable Added: INC = INC=0.0 # Income (PreTax) # Income (PreTax)
[ID=2] Variable Added: LAG_F = F(k-1) # Previous periods fiscal assets.
Registering cash stream exclusion: DEM_GOOD for ID=2
[ID=2] Variable Added: AlphaIncome = 0.7000 # Parameter for consumption out of income
[ID=2] Variable Added: AlphaFin = 0.3000 # Parameter for consumption out of fiscal assets
[ID=2] Variable Added: DEM_GOOD = AlphaIncome * AfterTax + AlphaFin * LAG_F # Expenditure on goods consumption
[ID=2] Variable Added: AfterTax = INC - T # Aftertax income
[ID=2] Variable Added: T = # Taxes paid.
[ID=2] Variable Added: SUP_LAB = 0. # Supply of Labour
Calling main() genuinely leads to around work, together with the framework solves the equations, i measuring at a time. This is non genuinely rattling difficult, since everything other than the fourth dimension axis consist of constants. The log file continues.
Starting Model main()
Generating FullSector codes (Model._GenerateFullSectorCodes()
Model._GenerateEquations()
Fixing aliases (Model._FixAliases)
Model._GenerateRegisteredCashFlows()
Adding 0 cash flows to sectors
Processing 0 exogenous variables
Model._CreateFinalEquations()
Generating 0 initial conditions
_FinalEquationFormatting()
Set Initial Conditions
Step: 1
Number of iterations: 1
Step: 2
Number of iterations: 1
The log together with so keeps going.
However, the equations beingness solved are non especially interesting. The argue is that a unmarried sector model does non Pb to whatever interesting activity inside the framework; the convention is that economical activity is the resultant of interactions of sectors. This may non live intuitive if you lot are thinking inward damage of the existent basis household sector; people volition undertake all sorts of activities on their own. (Some of these activities volition demonstrate upwards inward the national accounts.) We quest to drib this existent basis intuition, together with focus on the to a greater extent than abstract model behaviour, where activity is mainly betwixt sectors.
The natural extension would live to drib inward a concern sector to the model; nosotros tin together with so receive got the interactions betwixt the 2 sectors. The adjacent instance (intro_3_03_hello_world_3.py) attempts to hit this.
from __future__ import print_function
import sfc_models
from sfc_models.models import Model, Country
from sfc_models.sector_definitions import Household, FixedMarginBusiness
sfc_models.register_standard_logs(output_dir='output',
base_file_name=__file__)
mod = Model()
can = Country(mod, 'Canada', 'CA')
household = Household(can, 'Household Sector', 'HH',
alpha_income=.7, alpha_fin=.3)
business = FixedMarginBusiness(can, 'Business Sector', 'BUS')
mod.main()
[NOTE: this volition exclusively concur on versions greater than 0.4.1; inward Version 0.4.1 together with below, the alarm is genuinely an error.]
Looking at the relevant constituent of the log file, nosotros see.
Starting Model main()
Generating FullSector codes (Model._GenerateFullSectorCodes()
Model._GenerateEquations()
Searching for Market Sector amongst Code GOOD inward parent country
Error or Warning raised:
[Error describe deleted]
...
enhance Warning('Business {0} Cannot Find Market for {1}'.format(self.Code, self.OutputName))
Warning: Business BUS Cannot Find Market for GOOD
That is, the concern sector started searching for a Market sector (with the Code 'GOOD') , together with it could non discovery it. (A concern sector yesteryear default produces an output amongst the code 'GOOD', the bring upwards of the output tin live overridden yesteryear passing a novel code to use.)
This log file information tells us something virtually the blueprint of the sfc_models framework. It is non plenty to define economical Sectors inside our code, nosotros quest to add together Market objects (or other objects) to allow the sectors to interact. In this case, the concern sector assumes that at that topographic point is a marketplace for its output; otherwise the sector volition hit nothing. (No betoken inward hiring workers to hit an output that you lot cannot sell.)
The concluding "Hello World" instance (intro_3_03_hello_world_4.py) creates a goods marketplace to cook that warning.
# NOTE: If you lot receive got an older version of sfc_models, you
# may quest to supplant this import line amongst specific imports
from sfc_models.objects import *
sfc_models.register_standard_logs(output_dir='output',
base_file_name=__file__)
mod = Model()
can = Country(mod, 'Canada', 'CA')
household = Household(can, 'Household Sector', 'HH',
alpha_income=.7, alpha_fin=.3)
business = FixedMarginBusiness(can, 'Business Sector', 'BUS')
market = Market(can, 'Goods Market', 'GOOD')
mod.main()
(c) Brian Romanchuk 2017
One means of agreement the workflow is to mean value of sfc_models equally the analysis backbone of a computer-aided blueprint program. The user "drags together with drops" economical sectors into a model, together with and so the framework incorporates the outcome. The user tin together with so drill into a exceptional sector's settings to larn to a greater extent than precise command of the outcome. (Such a graphical interface may live built, merely the model code needs to live solidified first.)
This article runs through the simplest possible models that nosotros tin create ("Hello World!"), together with shows how to utilisation the log files to sympathise how the framework builds models based on high grade code.
Note on Example Code
The instance inward the adjacent department is taken from the file intro_3_03_hello_world_1.py. Like all of my other examples, it is flora inward the examples.scripts directory of sfc_models.Since all of the examples coexist inside a unmarried directory, I utilisation a long-winded naming scheme. The intro_3_03 constituent of the file bring upwards tells us that these examples are to live included inward Section 3.3 of Introduction to SFC Models Using Python. Also, delight depository fiscal establishment notation that this code volition exclusively piece of work amongst Version 0.4.1 or afterwards of sfc_models. The logging command used is new.
UPDATE: In the latest versions of sfc_models (>= 0.4.3), it is possible to run a GUI (dialog boxes) to pick out where to install examples. In versions greater than 0.4.3 (which volition belike become far presently after this article was published) use:
from sfc_models import *
install_examples()
In Version 0.4.3, you lot quest to use:
from sfc_models.objects import *
install_examples()
Video Demo Of H5N1 Similar Example
This video shows how I run a uncomplicated instance from inside PyCharm. In this case, I built the instance upwards line-by-line, rather than using my prebuilt examples.Hello World!
The next code block is the simplest possible model you lot tin create amongst sfc_models.[From intro_3_03_hello_world_1.py:]
# This adjacent line looks bizarre, merely is needed for backwards
# compatibility amongst Python 2.7.
from __future__ import print_function
import sfc_models
from sfc_models.models import Model
print('*Starting upwards logging*')
# Log files are based on bring upwards of this module.
sfc_models.register_standard_logs(output_dir='output',
base_file_name=__file__)
print('*Build Model*')
mod = Model()
print('*Running main()*')
print('*(This volition campaign a warning...)*')
mod.main()
The actual piece of work is done inward these lines (the repose are impress commands together with laid up):
mod = Model()
mod.main()
These 2 lines hit the following:
- Create a Model object, assign it to the variable mod.
- Call the "main()" method of mod. The principal method does most of the heavy lifting of the framework, equally it builds a mathematical model based on the information embedded inward that Model object. The bring upwards "main" is maybe non descriptive, merely it is next programming tradition.
Running this script generates the output (for versions after 0.4.1):
python intro_3_03_hello_world_1.py
*Starting upwards logging*
*Build Model*
*Running main()*
*(This volition campaign a warning...)*
Warning triggered: There are no equations inward the system.
Process finished amongst leave of absence code 0
Warning triggered: There are no equations inward the system.
(Note: In before versions of the code, the main() telephone phone volition genuinely trigger an fault inward this case; the framework was unhappy amongst no equations inward the system.)
This alarm message is somewhat to live expected: nosotros created a Model object, together with incorporated no information into it. Obviously, at that topographic point should non live whatever equations associated amongst it.
However, it cannot live said that that at that topographic point was no other output; however, that output has been shunted to a log file. I volition right away render to the next constituent call.
sfc_models.register_standard_logs(output_dir='output',
base_file_name=__file__)
The constituent register_standard_logs tells the framework to larn ready to create a measure laid of log files. (You tin register exclusively exceptional logs if you lot desire to a greater extent than precise command of logging.) The constituent has 2 parameters:
- output_dir: which is the directory where the output goes. (In this example, "output".)
- base_file_name: What is the base of operations bring upwards to live used for all logs. I locomote yesteryear into it the __file__ variable, which is the total file bring upwards of the Python module. The register_standard_logs function ignores the directory ingredient of the file name, equally good equally the extension.
When I looked into the output subdirectory, nosotros run across the next files were created.
There are iii text files, whose names are based upon the file bring upwards of the rootage file.
- The file ending amongst "_eqn.txt" is the listing of equations inward the Model. (Not rattling interesting inward this case.)
- The file halt amongst "_out.txt" is a tab-delimited text file amongst the fourth dimension serial generated yesteryear the model, which tin live imported into a spreadsheet. (Also non interesting due to the lack of equations inward this case.) This sort of file is ofttimes called a csv file, merely the commons convention for a csv is to utilisation commas to split entries. However, the utilisation of commas equally a file delimiter is a disaster (for example, commas are used instead of "." for the decimal betoken inward French).
- The file ending amongst "_log.txt" is the log file, which I volition hash out next.
Entity Created: <class 'sfc_models.models.Model'> ID = 0
Starting Model main()
Generating FullSector codes (Model._GenerateFullSectorCodes()
Model._GenerateEquations()
Fixing aliases (Model._FixAliases)
Model._GenerateRegisteredCashFlows()
Adding 0 cash flows to sectors
Processing 0 exogenous variables
Model._CreateFinalEquations()
Generating 0 initial conditions
Error or Warning raised:
Traceback (most recent telephone phone last):
File "c:\Python33\lib\site-packages\sfc_models\models.py", line 140, inward main
self.FinalEquations = self._CreateFinalEquations()
File "c:\Python33\lib\site-packages\sfc_models\models.py", line 499, inward _CreateFinalEquations
enhance Warning('There are no equations inward the system.')
Warning: There are no equations inward the system.
The get-go line of code (mod = Model()) resulted inward i line inward the log.
Entity Created: <class 'sfc_models.models.Model'> ID = 0
The creation of the Model object was noted; it turns out the Model is an Entity equally well, together with it was assigned the ID of 0. This numeric ID is designed to provide an tardily means to distinguish the objects that are created inward the code.
The repose of the log was triggered yesteryear running main(). H5N1 few operations were run, merely they did nada since at that topographic point were no equations inside the system. This lack of equations was diagnosed, together with nosotros halt amongst Raise Warning.
H5N1 Non-Empty Model
We together with so measuring to the adjacent example, intro_3_03_hello_world_2.py.from __future__ import print_function
import sfc_models
from sfc_models.models import Model, Country
from sfc_models.sector_definitions import Household
sfc_models.register_standard_logs(output_dir='output',
base_file_name=__file__)
# Start work.
mod = Model()
can = Country(mod, 'Canada', 'CA')
household = Household(can, 'Household Sector', 'HH',
alpha_income=.7, alpha_fin=.3)
mod.main()
This code add together 2 novel lines.
- A Country object (can) is added to the Model (mod).
- A Household (a type of Sector) is added the Country, together with assigned to the variable bring upwards household. There are 2 parameters associated amongst the household; the propensity to swallow out of income (alpha_income), together with the propensity to swallow out of fiscal wealth (alpha_fin).
In the output subdirectory, at that topographic point are iii novel files generated. The '_out.txt' file right away contains around fourth dimension serial that tin live viewed inward a spreadsheet program, together with the equation file has equations. I volition exclusively facial expression at the log file ('_log.txt').
In Version 0.4.1 of sfc_models, the log file starts with:
Entity Created: <class 'sfc_models.models.Model'> ID = 0
Entity Created: <class 'sfc_models.models.Country'> ID = 1
Adding Country: CA ID=1
Entity Created: <class 'sfc_models.sector_definitions.Household'> ID = 2
Adding Sector HH To Country CA
We run across that iii Entity objects are beingness created. The creation of the Household causes a pocket-size flurry of activity. Variables are beingness added.
[ID=2] Variable Added: F = F=LAG_F # Financial assets # Financial assets
[ID=2] Variable Added: INC = INC=0.0 # Income (PreTax) # Income (PreTax)
[ID=2] Variable Added: LAG_F = F(k-1) # Previous periods fiscal assets.
Registering cash stream exclusion: DEM_GOOD for ID=2
[ID=2] Variable Added: AlphaIncome = 0.7000 # Parameter for consumption out of income
[ID=2] Variable Added: AlphaFin = 0.3000 # Parameter for consumption out of fiscal assets
[ID=2] Variable Added: DEM_GOOD = AlphaIncome * AfterTax + AlphaFin * LAG_F # Expenditure on goods consumption
[ID=2] Variable Added: AfterTax = INC - T # Aftertax income
[ID=2] Variable Added: T = # Taxes paid.
[ID=2] Variable Added: SUP_LAB = 0. # Supply of Labour
Calling main() genuinely leads to around work, together with the framework solves the equations, i measuring at a time. This is non genuinely rattling difficult, since everything other than the fourth dimension axis consist of constants. The log file continues.
Starting Model main()
Generating FullSector codes (Model._GenerateFullSectorCodes()
Model._GenerateEquations()
Fixing aliases (Model._FixAliases)
Model._GenerateRegisteredCashFlows()
Adding 0 cash flows to sectors
Processing 0 exogenous variables
Model._CreateFinalEquations()
Generating 0 initial conditions
_FinalEquationFormatting()
Set Initial Conditions
Step: 1
Number of iterations: 1
Step: 2
Number of iterations: 1
The log together with so keeps going.
However, the equations beingness solved are non especially interesting. The argue is that a unmarried sector model does non Pb to whatever interesting activity inside the framework; the convention is that economical activity is the resultant of interactions of sectors. This may non live intuitive if you lot are thinking inward damage of the existent basis household sector; people volition undertake all sorts of activities on their own. (Some of these activities volition demonstrate upwards inward the national accounts.) We quest to drib this existent basis intuition, together with focus on the to a greater extent than abstract model behaviour, where activity is mainly betwixt sectors.
The natural extension would live to drib inward a concern sector to the model; nosotros tin together with so receive got the interactions betwixt the 2 sectors. The adjacent instance (intro_3_03_hello_world_3.py) attempts to hit this.
from __future__ import print_function
import sfc_models
from sfc_models.models import Model, Country
from sfc_models.sector_definitions import Household, FixedMarginBusiness
sfc_models.register_standard_logs(output_dir='output',
base_file_name=__file__)
mod = Model()
can = Country(mod, 'Canada', 'CA')
household = Household(can, 'Household Sector', 'HH',
alpha_income=.7, alpha_fin=.3)
business = FixedMarginBusiness(can, 'Business Sector', 'BUS')
mod.main()
When run, this generates a warning:
Warning triggered: Business BUS Cannot Find Market for GOOD
[NOTE: this volition exclusively concur on versions greater than 0.4.1; inward Version 0.4.1 together with below, the alarm is genuinely an error.]
Looking at the relevant constituent of the log file, nosotros see.
Starting Model main()
Generating FullSector codes (Model._GenerateFullSectorCodes()
Model._GenerateEquations()
Searching for Market Sector amongst Code GOOD inward parent country
Error or Warning raised:
[Error describe deleted]
...
enhance Warning('Business {0} Cannot Find Market for {1}'.format(self.Code, self.OutputName))
Warning: Business BUS Cannot Find Market for GOOD
That is, the concern sector started searching for a Market sector (with the Code 'GOOD') , together with it could non discovery it. (A concern sector yesteryear default produces an output amongst the code 'GOOD', the bring upwards of the output tin live overridden yesteryear passing a novel code to use.)
This log file information tells us something virtually the blueprint of the sfc_models framework. It is non plenty to define economical Sectors inside our code, nosotros quest to add together Market objects (or other objects) to allow the sectors to interact. In this case, the concern sector assumes that at that topographic point is a marketplace for its output; otherwise the sector volition hit nothing. (No betoken inward hiring workers to hit an output that you lot cannot sell.)
The concluding "Hello World" instance (intro_3_03_hello_world_4.py) creates a goods marketplace to cook that warning.
# NOTE: If you lot receive got an older version of sfc_models, you
# may quest to supplant this import line amongst specific imports
from sfc_models.objects import *
sfc_models.register_standard_logs(output_dir='output',
base_file_name=__file__)
mod = Model()
can = Country(mod, 'Canada', 'CA')
household = Household(can, 'Household Sector', 'HH',
alpha_income=.7, alpha_fin=.3)
business = FixedMarginBusiness(can, 'Business Sector', 'BUS')
market = Market(can, 'Goods Market', 'GOOD')
mod.main()
When run, nosotros in i lawsuit once again larn no output on the console: at that topographic point are no warnings or errors generated. (This could potentially alter inward hereafter versions; the model is heavily under-determined, equally discussed below.) If i examines the log file (or the equations file), nosotros tin run across that the add-on of the Market inward goods has caused the framework to add together equations linking the render of goods from the concern sector to the demand from the household sector.
However, this model is non genuinely functional; whatever issue of pocket-size changes (such equally setting initial atmospheric condition away from zero) volition resultant inward at that topographic point beingness no solution to the laid of equations. The argue is that nosotros are silent missing around fundamental components.
- We quest a labour marketplace ('LAB') that besides links the concern together with household sectors.
- There are no render constraints inside this version of the concern sector; until nosotros add together inward something to halt an inherent positive feedback loop inward the somebody sector, activity would live infinite (and thence the equations volition non converge).
Unless the users switches to using other implementations for the concern together with household sector, the simplest working model is effectively Model SIM, which is taken from Chapter 3 of Godley together with Lavoie's Monetary Economics. This model is implemented inward sfc_models.gl_book.chapter3.py. [It besides implemented inward Section 3.2 of my book, equally good equally inward other posts on bondeconomics.com, such equally this article, although the code sample is based on an before version of the library. I volition cook my examples on the website to jibe Version 1.0 when it is ready.]
No comments