├── .conda
├── bld.bat
├── build.sh
└── meta.yaml
├── .github
├── CODEOWNERS
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── enhancement.md
│ └── feature_request.md
├── pull_request_template.md
└── workflows
│ └── continuous-integration-workflow.yml
├── .gitignore
├── .pre-commit-config.yaml
├── .readthedocs.yaml
├── LICENSE
├── MANIFEST.in
├── README.rst
├── codecov.yml
├── development
├── documentation
│ └── scalability
│ │ ├── run_single_scalability_exercise.py
│ │ └── scalability_setup.py
└── testing
│ ├── __init__.py
│ ├── conftest.py
│ ├── notifications.py
│ ├── regression.py
│ ├── test_cli.py
│ └── testing_pull_request.py
├── docs
├── Makefile
├── _static
│ ├── cscubs-2019
│ │ ├── paper.pdf
│ │ ├── presentation.pdf
│ │ └── sources.zip
│ ├── css
│ │ └── custom.css
│ ├── funding
│ │ └── Becker_Sebastian_Arbeitsprogramm.pdf
│ ├── images
│ │ ├── Logo_DIW_Berlin.svg
│ │ ├── Logo_TRA1.png
│ │ ├── OSE_logo_RGB.svg
│ │ ├── UNI_Bonn_Logo_Standard_RZ_RGB.svg
│ │ ├── algorithm_value_function_iteration.svg
│ │ ├── book.svg
│ │ ├── books.svg
│ │ ├── coding.svg
│ │ ├── computer.svg
│ │ ├── dividers.svg
│ │ ├── edit.svg
│ │ ├── event_tree.svg
│ │ ├── gears.svg
│ │ ├── graduate-cap.svg
│ │ ├── light-bulb.svg
│ │ ├── note.svg
│ │ ├── number-blocks.svg
│ │ ├── peoples.svg
│ │ ├── research.svg
│ │ ├── respy-logo.svg
│ │ ├── road.svg
│ │ ├── study.svg
│ │ └── timing_events.svg
│ ├── respy.mplstyle
│ └── thesis_proposals
│ │ ├── Salience_and_human_capital.pdf
│ │ └── Sparsity_and_human_capital.pdf
├── _templates
│ ├── custom-about-us.html
│ └── custom-intro.html
├── about_us.rst
├── conf.py
├── development
│ ├── contributing_to_respy.rst
│ ├── index.rst
│ ├── releases.rst
│ ├── roadmap.rst
│ └── template_for_tutorials.rst
├── explanations
│ ├── bib.rst
│ ├── calibration.rst
│ ├── computational_implementation.rst
│ ├── economic_model.rst
│ ├── glossary.rst
│ ├── implementation_kw94.rst
│ ├── index.rst
│ ├── introduction.rst
│ ├── mathematical_framework.rst
│ ├── notation.rst
│ ├── parameterization.rst
│ ├── recommended_reading.rst
│ └── refs.bib
├── how_to_guides
│ ├── how_to_covariates.ipynb
│ ├── how_to_example_models.rst
│ ├── how_to_finite_mixture.ipynb
│ ├── how_to_hyperbolic_discounting.ipynb
│ ├── how_to_initial_conditions.ipynb
│ ├── how_to_likelihood.ipynb
│ ├── how_to_msm.ipynb
│ ├── how_to_msm_estimation_exercise.ipynb
│ ├── how_to_numerical_integration.ipynb
│ ├── how_to_simulation.ipynb
│ ├── how_to_specify_model.ipynb
│ └── index.rst
├── index.rst
├── projects
│ ├── _numerical_integration.py
│ ├── estimating-keane-and-wolpin-1997-msm.ipynb
│ ├── index.rst
│ ├── keane-and-wolpin-1994.ipynb
│ ├── numerical_integration.ipynb
│ ├── research_papers.rst
│ └── theses.rst
├── reference_guides
│ ├── index.rst
│ ├── randomness_and_reproducibility.rst
│ ├── scalability.ipynb
│ └── state_space.rst
├── release_notes.rst
├── rtd_environment.yml
└── tutorials
│ ├── index.rst
│ ├── installation.rst
│ ├── robinson_crusoe.ipynb
│ ├── tutorial_exogenous_processes.ipynb
│ ├── tutorial_experience.ipynb
│ ├── tutorial_impatient_robinson.ipynb
│ ├── tutorial_observables.ipynb
│ └── tutorial_params_options_simulate.ipynb
├── environment.yml
├── respy
├── __init__.py
├── _numba.py
├── conditional_draws.py
├── config.py
├── conftest.py
├── data.py
├── exogenous_processes.py
├── interface.py
├── interpolate.py
├── likelihood.py
├── method_of_simulated_moments.py
├── parallelization.py
├── pre_processing
│ ├── __init__.py
│ ├── base_params.csv
│ ├── data_checking.py
│ ├── lagged_choice_params.csv
│ ├── model_checking.py
│ ├── model_processing.py
│ ├── process_covariates.py
│ └── specification_helpers.py
├── shared.py
├── simulate.py
├── solve.py
├── state_space.py
└── tests
│ ├── __init__.py
│ ├── _former_code.py
│ ├── random_model.py
│ ├── resources
│ ├── conditional_draws_fixture.pickle
│ ├── kw_2000.csv
│ ├── kw_2000.yaml
│ ├── kw_2000_table_1_whites_choice_probabilities.csv
│ ├── kw_2000_table_2_blacks_choice_probabilities.csv
│ ├── kw_2000_table_3_wage_fit_blacks.csv
│ ├── kw_2000_table_3_wage_fit_whites.csv
│ ├── kw_2000_table_5_school_attainment.csv
│ ├── kw_2000_table_a3_type_probabilities.csv
│ ├── kw_94_one.csv
│ ├── kw_94_one.yaml
│ ├── kw_94_table_6.csv
│ ├── kw_94_three.csv
│ ├── kw_94_three.yaml
│ ├── kw_94_two.csv
│ ├── kw_94_two.yaml
│ ├── kw_94_wp_table_2_1.csv
│ ├── kw_94_wp_table_2_2.csv
│ ├── kw_94_wp_table_2_3.csv
│ ├── kw_97_basic.csv
│ ├── kw_97_basic.yaml
│ ├── kw_97_basic_respy.csv
│ ├── kw_97_basic_respy.yaml
│ ├── kw_97_data.csv
│ ├── kw_97_extended.csv
│ ├── kw_97_extended.yaml
│ ├── kw_97_extended_respy.csv
│ ├── kw_97_extended_respy.yaml
│ ├── regression_vault.pickle
│ ├── robinson_crusoe_basic.csv
│ ├── robinson_crusoe_basic.yaml
│ ├── robinson_crusoe_extended.csv
│ ├── robinson_crusoe_extended.yaml
│ ├── robinson_crusoe_with_observed_characteristics.csv
│ └── robinson_crusoe_with_observed_characteristics.yaml
│ ├── test_conditional_draws.py
│ ├── test_exogenous_processes.py
│ ├── test_flexible_choices.py
│ ├── test_integration.py
│ ├── test_interface.py
│ ├── test_interpolate.py
│ ├── test_likelihood.py
│ ├── test_method_of_simulated_moments.py
│ ├── test_model_processing.py
│ ├── test_parallelization.py
│ ├── test_process_covariates.py
│ ├── test_randomness.py
│ ├── test_regression.py
│ ├── test_replication_kw_94.py
│ ├── test_replication_kw_97.py
│ ├── test_simulate.py
│ ├── test_simulate
│ ├── test_apply_law_of_motion_1_in.csv
│ ├── test_apply_law_of_motion_1_optim_paras.yaml
│ ├── test_apply_law_of_motion_1_out.csv
│ ├── test_apply_law_of_motion_2_in.csv
│ ├── test_apply_law_of_motion_2_optim_paras.yaml
│ └── test_apply_law_of_motion_2_out.csv
│ ├── test_solve.py
│ └── utils.py
├── setup.cfg
├── setup.py
└── tox.ini
/.conda/bld.bat:
--------------------------------------------------------------------------------
1 | "%PYTHON%" setup.py install
2 | if errorlevel 1 exit 1
3 |
--------------------------------------------------------------------------------
/.conda/build.sh:
--------------------------------------------------------------------------------
1 | $PYTHON setup.py install # Python command to install the script.
2 |
--------------------------------------------------------------------------------
/.conda/meta.yaml:
--------------------------------------------------------------------------------
1 | {% set data = load_setup_py_data() %}
2 |
3 | package:
4 | name: respy
5 | version: {{ data.get('version') }}
6 |
7 | source:
8 | # git_url is nice in that it won't capture devenv stuff. However, it only captures
9 | # committed code, so pay attention.
10 | git_url: ../
11 |
12 | build:
13 | number: 0
14 | noarch: python
15 |
16 | requirements:
17 | host:
18 | - python >=3.7
19 | run:
20 | - python >=3.7
21 | - click
22 | - estimagic >=0.1.2
23 | - hypothesis
24 | - joblib
25 | - fastparquet
26 | - mkl
27 | - numba >=0.42
28 | - numpy>=1.21.0
29 | - pandas >=0.24
30 | - pytest
31 | - python-snappy
32 | - pyyaml
33 | - scipy
34 | test:
35 | requires:
36 | - pytest
37 | - pytest-xdist
38 | commands:
39 | - pytest -n auto
40 | source_files:
41 | - respy
42 | - tox.ini
43 |
44 | about:
45 | home: {{ data.get('url') }}
46 | license: {{ data.get('license') }}
47 | license_file: LICENSE
48 | summary: {{ data.get('description') }}
49 | dev_url: https://github.com/OpenSourceEconomics/respy
50 | doc_url: {{ data.get('url') }}
51 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # CODEOWNERS are explained in
2 | # https://help.github.com/en/github/creating-cloning-and-archiving-repositories/
3 | # about-code-owners
4 |
5 | # These owners will be the default owners for everything in the repo. Unless a later
6 | # match takes precedence, global owners will be requested for review when someone opens
7 | # a pull request.
8 | * @mo2561057
9 |
10 | # Owners responsible for the documentation.
11 | /docs/ @amageh
12 |
13 | # Owners responsible for the method of simulated moments.
14 | respy/msm.py @mo2561057 @amageh
15 |
16 | # Owners responsible for the state space.
17 | respy/state_space.py @mo2561057
18 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve.
4 | title: ''
5 | labels: bug
6 | assignees: ''
7 |
8 | ---
9 |
10 | * respy version used, if any:
11 | * Python version, if any:
12 | * Operating System:
13 |
14 | ### Describe the bug
15 |
16 | A clear and concise description of what the bug is.
17 |
18 | ### To reproduce
19 |
20 | Steps to reproduce the behavior:
21 |
22 | 1. Go to '...'
23 | 2. Click on '....'
24 | 3. Scroll down to '....'
25 | 4. See error
26 |
27 | ### Expected behavior
28 |
29 | A clear and concise description of what you expected to happen.
30 |
31 | ### Screenshots
32 |
33 | If applicable, add screenshots to help explain your problem.
34 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/enhancement.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Enhancement
3 | about: Enhance an existing component.
4 | title: ''
5 | labels: enhancement
6 | assignees: ''
7 |
8 | ---
9 |
10 | * respy version used, if any:
11 | * Python version, if any:
12 | * Operating System:
13 |
14 | ### What would you like to enhance and why? Is it related to an issue/problem?
15 |
16 | A clear and concise description of the current implementation and its limitations.
17 |
18 | ### Describe the solution you'd like
19 |
20 | A clear and concise description of what you want to happen.
21 |
22 | ### Describe alternatives you've considered
23 |
24 | A clear and concise description of any alternative solutions or features you've
25 | considered and why you have discarded them.
26 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project.
4 | title: ''
5 | labels: feature-request
6 | assignees: ''
7 |
8 | ---
9 |
10 | * respy version used, if any:
11 | * Python version, if any:
12 | * Operating System:
13 |
14 | ### Is your feature request related to a problem? Please describe.
15 |
16 | A clear and concise description of what the problem is.
17 |
18 | ### Describe the solution you'd like
19 |
20 | A clear and concise description of what you want to happen.
21 |
22 | ### Describe alternatives you've considered
23 |
24 | A clear and concise description of any alternative solutions or features you've
25 | considered and why you have discarded them.
26 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ### Current behavior
2 |
3 | What is the current state?
4 |
5 | ### Desired behavior
6 |
7 | What do you want to achieve?
8 |
9 | ### Solution / Implementation
10 |
11 | What is your solution?
12 |
13 | ### Todo
14 |
15 | - [ ] Review whether the documentation needs to be updated.
16 | - [ ] Document PR in release_notes.rst.
17 |
--------------------------------------------------------------------------------
/.github/workflows/continuous-integration-workflow.yml:
--------------------------------------------------------------------------------
1 | name: Continuous Integration Workflow
2 | on:
3 | push:
4 | branches:
5 | - main
6 | pull_request:
7 | branches:
8 | - '*'
9 |
10 | env:
11 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
12 |
13 | jobs:
14 |
15 | run-tests:
16 |
17 | name: Run tests for ${{ matrix.os }} on ${{ matrix.python-version }}
18 | runs-on: ${{ matrix.os }}
19 | strategy:
20 | fail-fast: false
21 | matrix:
22 | os: ['ubuntu-latest', 'macos-latest', 'windows-latest']
23 | python-version: ['3.7', '3.8']
24 |
25 | steps:
26 | - uses: actions/checkout@v2
27 | - uses: conda-incubator/setup-miniconda@v2
28 | with:
29 | auto-update-conda: true
30 | python-version: ${{ matrix.python-version }}
31 |
32 | - name: Install core dependencies.
33 | shell: bash -l {0}
34 | run: conda install -c conda-forge tox-conda
35 |
36 | ###############################################################################
37 | # tox-conda fixes on Windows (https://github.com/tox-dev/tox-conda/issues/37) #
38 | ###############################################################################
39 |
40 | - name: Install fixes for Python 3+ on Windows
41 | if: runner.os == 'Windows'
42 | shell: bash -l {0}
43 | run: conda install -c conda-forge -c opensourceeconomics conda-build estimagic matplotlib python-snappy
44 |
45 | ###############
46 | # Test Matrix #
47 | ###############
48 |
49 | # Unit tests.
50 |
51 | - name: Run unit tests and doctests.
52 | shell: bash -l {0}
53 | run: tox -e pytest -- -m "not slow and not integration and not end_to_end" --cov=./ --cov-report=xml -n auto
54 |
55 | - name: Upload coverage report
56 | if: runner.os == 'Linux' && matrix.python-version == '3.8'
57 | shell: bash -l {0}
58 | run: bash <(curl -s https://codecov.io/bash) -F unit -c
59 |
60 | # Integration tests.
61 |
62 | - name: Run integration tests.
63 | shell: bash -l {0}
64 | run: tox -e pytest -- -m "not slow and integration" --cov=./ --cov-report=xml -n auto
65 |
66 | - name: Upload coverage report
67 | if: runner.os == 'Linux' && matrix.python-version == '3.8'
68 | shell: bash -l {0}
69 | run: bash <(curl -s https://codecov.io/bash) -F integration -c
70 |
71 | # End-to-end tests.
72 |
73 | - name: Run end_to_end tests.
74 | shell: bash -l {0}
75 | run: tox -e pytest -- -m "not slow and end_to_end" --cov=./ --cov-report=xml -n auto
76 |
77 | - name: Upload coverage report
78 | if: runner.os == 'Linux' && matrix.python-version == '3.8'
79 | shell: bash -l {0}
80 | run: bash <(curl -s https://codecov.io/bash) -F end_to_end -c
81 |
82 | ##################################
83 | # Validate codecov configuration #
84 | ##################################
85 |
86 | - name: Validate codecov.yml
87 | if: runner.os == 'Linux' && matrix.python-version == '3.8'
88 | shell: bash -l {0}
89 | run: cat codecov.yml | curl --data-binary @- https://codecov.io/validate
90 |
91 |
92 | pre-commit:
93 |
94 | name: Run pre-commit.
95 | runs-on: ubuntu-latest
96 |
97 | steps:
98 | - uses: actions/checkout@v2
99 |
100 | - name: Set up Python 3.8
101 | uses: actions/setup-python@v1
102 | with:
103 | python-version: 3.8
104 |
105 | - name: Install dependencies
106 | run: pip install tox
107 |
108 | - name: Run pre-commit
109 | run: tox -e pre-commit
110 |
111 |
112 | docs:
113 |
114 | name: Run documentation.
115 | runs-on: ubuntu-latest
116 |
117 | steps:
118 | - uses: actions/checkout@v2
119 | - uses: conda-incubator/setup-miniconda@v2
120 | with:
121 | auto-update-conda: true
122 | python-version: 3.8
123 |
124 | - name: Install core dependencies.
125 | shell: bash -l {0}
126 | run: conda install -c conda-forge tox-conda
127 |
128 | - name: Build docs
129 | shell: bash -l {0}
130 | run: tox -e sphinx
131 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore folders.
2 | .cache/
3 | .hypothesis/
4 | .idea/
5 | .ipynb_checkpoints/
6 | .tox/
7 | .vscode/
8 | __pycache__/
9 | __tutorial__/
10 | dist/
11 | docs/_build/
12 | docs/_generated/
13 | .respy/
14 |
15 | # Ignore files.
16 | .coverage
17 | pytestdebug.log
18 | *.sublime-project
19 | *.sublime-workspace
20 | *.egg-info
21 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | repos:
2 | - repo: https://github.com/pre-commit/pre-commit-hooks
3 | rev: v4.0.1
4 | hooks:
5 | - id: check-added-large-files
6 | args: ['--maxkb=100']
7 | - id: check-merge-conflict
8 | - id: check-yaml
9 | exclude: meta.yaml
10 | - id: debug-statements
11 | - id: end-of-file-fixer
12 | - repo: https://github.com/asottile/pyupgrade
13 | rev: v2.26.0
14 | hooks:
15 | - id: pyupgrade
16 | args: [--py36-plus]
17 | - repo: https://github.com/asottile/reorder_python_imports
18 | rev: v2.6.0
19 | hooks:
20 | - id: reorder-python-imports
21 | - repo: https://github.com/psf/black
22 | rev: 22.3.0
23 | hooks:
24 | - id: black
25 | - repo: https://github.com/asottile/blacken-docs
26 | rev: v1.12.1
27 | hooks:
28 | - id: blacken-docs
29 | additional_dependencies: [black]
30 | - repo: https://github.com/PyCQA/flake8
31 | rev: 3.9.2
32 | hooks:
33 | - id: flake8
34 | additional_dependencies: [
35 | flake8-alfred,
36 | flake8-bugbear,
37 | flake8-builtins,
38 | flake8-comprehensions,
39 | flake8-docstrings,
40 | flake8-eradicate,
41 | flake8-print,
42 | flake8-pytest-style,
43 | flake8-todo,
44 | flake8-unused-arguments,
45 | pep8-naming,
46 | pydocstyle,
47 | Pygments,
48 | ]
49 | - repo: https://github.com/PyCQA/doc8
50 | rev: 0.9.0
51 | hooks:
52 | - id: doc8
53 | # - repo: https://github.com/codespell-project/codespell
54 | # rev: v1.17.1
55 | # hooks:
56 | # - id: codespell
57 | # - repo: https://github.com/mgedmin/check-manifest
58 | # rev: '0.41'
59 | # hooks:
60 | # - id: check-manifest
61 | - repo: meta
62 | hooks:
63 | - id: check-hooks-apply
64 | - id: check-useless-excludes
65 | # - id: identity # Prints all files passed to pre-commits. Debugging.
66 |
--------------------------------------------------------------------------------
/.readthedocs.yaml:
--------------------------------------------------------------------------------
1 | version: 2
2 |
3 | build:
4 | image: latest
5 |
6 | python:
7 | version: 3.8
8 |
9 | conda:
10 | environment: docs/rtd_environment.yml
11 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015-2020
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this
6 | software and associated documentation files (the "Software"), to deal in the Software
7 | without restriction, including without limitation the rights to use, copy, modify,
8 | merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
9 | permit persons to whom the Software is furnished to do so, subject to the following
10 | conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all copies or
13 | substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
16 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
17 | PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
19 | OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 | OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | # The MANIFEST.in specifies which files are copied over from a temporary directory to
2 | # site-packages after ``pip install``. Examples can be found here:
3 | # https://www.reddit.com/r/Python/comments/40s8qw/simplify_your_manifestin_commands/ and
4 | # https://blog.ionelmc.ro/presentations/packaging.
5 |
6 | # Test what is included in the package by running ``python setup.py sdist`` and inspect
7 | # the tarball.
8 |
9 | include CHANGES.rst
10 | include CITATION
11 | include LICENSE
12 | include README.rst
13 | include tox.ini
14 | include *.sh
15 | include *.yaml
16 | include *.yml
17 |
18 | graft .conda
19 | graft respy
20 |
21 | prune development
22 | prune docs
23 |
24 | global-exclude __pycache__
25 | global-exclude .ipynb_checkpoints
26 | global-exclude *.py[co]
27 | global-exclude *-checkpoint.ipynb
28 |
--------------------------------------------------------------------------------
/codecov.yml:
--------------------------------------------------------------------------------
1 | codecov:
2 | branch: main
3 |
4 | coverage:
5 | precision: 2
6 | round: down
7 | range: 80...100
8 | status:
9 | project:
10 | default:
11 | threshold: 1%
12 | patch:
13 | default:
14 | threshold: 5%
15 | unit:
16 | flags:
17 | - unit
18 | integration:
19 | flags:
20 | - integration
21 | end_to_end:
22 | flags:
23 | - end_to_end
24 |
25 | ignore:
26 | - ".tox/**/*"
27 | - "setup.py"
28 | - "respy/conftest.py"
29 | - "respy/tests/**/*"
30 | - "development/**/*"
31 | - "docs/**/*"
32 |
--------------------------------------------------------------------------------
/development/documentation/scalability/run_single_scalability_exercise.py:
--------------------------------------------------------------------------------
1 | import datetime as dt
2 | import json
3 | import os
4 | import sys
5 |
6 |
7 | def main():
8 | """Evaluate the criterion function multiple times for a scalability report.
9 |
10 | The criterion function is evaluated ``maxfun``-times. The number of threads used is
11 | limited by environment variables. **respy** has to be imported after the environment
12 | variables are set as Numpy, Numba and others load them at import time.
13 |
14 | """
15 | model = sys.argv[1]
16 | maxfun = int(sys.argv[2])
17 | n_threads = int(sys.argv[3])
18 |
19 | # Validate input.
20 | assert maxfun >= 0, "Maximum number of function evaluations cannot be negative."
21 | assert n_threads >= 1 or n_threads == -1, (
22 | "Use -1 to impose no restrictions on maximum number of threads or choose a "
23 | "number higher than zero."
24 | )
25 |
26 | # Set number of threads
27 | os.environ["NUMBA_NUM_THREADS"] = f"{n_threads}"
28 | os.environ["MKL_NUM_THREADS"] = f"{n_threads}"
29 | os.environ["OMP_NUM_THREADS"] = f"{n_threads}"
30 | os.environ["NUMEXPR_NUM_THREADS"] = f"{n_threads}"
31 |
32 | # Late import of respy to ensure that environment variables are read by Numpy, etc..
33 | import respy as rp
34 |
35 | # Get model
36 | params, options = rp.get_example_model(model, with_data=False)
37 |
38 | # Simulate the data
39 | simulate = rp.get_simulate_func(params, options)
40 | df = simulate(params)
41 |
42 | # Get the criterion function and the parameter vector.
43 | crit_func = rp.get_log_like_func(params, options, df)
44 |
45 | # Run the estimation
46 | start = dt.datetime.now()
47 |
48 | for _ in range(maxfun):
49 | crit_func(params)
50 |
51 | end = dt.datetime.now()
52 |
53 | # Aggregate information
54 | output = {
55 | "model": model,
56 | "maxfun": maxfun,
57 | "n_threads": n_threads,
58 | "start": str(start),
59 | "end": str(end),
60 | "duration": str(end - start),
61 | }
62 |
63 | # Save time to file
64 | with open("scalability_results.txt", "a+") as file:
65 | file.write(json.dumps(output))
66 | file.write("\n")
67 |
68 |
69 | if __name__ == "__main__":
70 | main()
71 |
--------------------------------------------------------------------------------
/development/documentation/scalability/scalability_setup.py:
--------------------------------------------------------------------------------
1 | import subprocess
2 | from pathlib import Path
3 |
4 |
5 | def main():
6 | """Run the scalability exercise.
7 |
8 | Define the model, a list with different number of threads and a maximum number of
9 | function evaluations.
10 |
11 | """
12 | model = "kw_97_basic"
13 | maxfun = 3
14 |
15 | filepath = Path(__file__).resolve().parent / "run_single_scalability_exercise.py"
16 |
17 | # Run Python
18 | for n_threads in [2, 4, 6, 8, 10, 12, 14]:
19 | subprocess.check_call(
20 | ["python", str(filepath), model, str(maxfun), str(n_threads)]
21 | )
22 |
23 |
24 | if __name__ == "__main__":
25 | main()
26 |
--------------------------------------------------------------------------------
/development/testing/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenSourceEconomics/respy/91e8a193fb7d5cf7212c15e50ae43f810bb9b1eb/development/testing/__init__.py
--------------------------------------------------------------------------------
/development/testing/conftest.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | import pytest
4 |
5 |
6 | @pytest.fixture(autouse=True)
7 | def _fresh_directory(tmp_path):
8 | """Each test is executed in a fresh directory."""
9 | os.chdir(tmp_path)
10 |
--------------------------------------------------------------------------------
/development/testing/notifications.py:
--------------------------------------------------------------------------------
1 | import json
2 | import os
3 | import socket
4 | import sys
5 | import warnings
6 | from pathlib import Path
7 |
8 | import apprise
9 |
10 | RECIPIENTS = {"socrates": "janos.gabler@gmail.com", "abacus": "traabe92@gmail.com"}
11 |
12 |
13 | def send_notification(title, body):
14 | """Send notification."""
15 | hostname = socket.gethostname()
16 |
17 | recipient = RECIPIENTS.get(hostname, "eisenhauer@policy-lab.org")
18 |
19 | # This allows to run the scripts even when no notification can be send.
20 | home = Path(os.environ.get("HOME") or os.environ.get("HOMEPATH"))
21 | credentials = home / ".credentials"
22 |
23 | if not credentials.exists():
24 | warnings.warn("No configuration file for notifications available.")
25 | sys.exit(0)
26 |
27 | credentials = json.loads(credentials.read_text())
28 | message_header = {
29 | "domain": "gmail.com",
30 | "to": recipient,
31 | "name": "respy",
32 | **credentials,
33 | }
34 | service = "mailto://{username}:{password}@{domain}?to={to}&name={name}"
35 |
36 | apobj = apprise.Apprise()
37 | apobj.add(service.format(**message_header))
38 | apobj.notify(title=title, body=body)
39 |
--------------------------------------------------------------------------------
/development/testing/regression.py:
--------------------------------------------------------------------------------
1 | """Create, run or investigate regression checks."""
2 | import pickle
3 | import socket
4 |
5 | import click
6 | import numpy as np
7 |
8 | from respy.config import TEST_RESOURCES_DIR
9 | from respy.config import TOL_REGRESSION_TESTS
10 | from respy.tests.random_model import generate_random_model
11 | from respy.tests.test_regression import compute_log_likelihood
12 | from respy.tests.test_regression import load_regression_tests
13 |
14 | CONTEXT_SETTINGS = {"help_option_names": ["-h", "--help"]}
15 |
16 |
17 | def _prepare_message(idx_failures):
18 | hostname = socket.gethostname()
19 | subject = " respy: Regression Testing"
20 | if idx_failures:
21 | message = (
22 | f"Failure during regression testing @{hostname} for test(s): "
23 | f"{idx_failures}."
24 | )
25 | else:
26 | message = f"Regression testing is completed on @{hostname}."
27 |
28 | return subject, message
29 |
30 |
31 | def run_regression_tests(n_tests, strict, notification):
32 | """Run regression tests.
33 |
34 | Parameters
35 | ----------
36 | n_tests : int
37 | Number of tests to run. If None, all are run.
38 | strict : bool, default False
39 | Early failure on error.
40 | notification : bool, default True
41 | Send notification with test report.
42 |
43 | """
44 | tests = load_regression_tests()
45 | tests = tests[: n_tests + 1]
46 |
47 | results = [_check_single(test, strict) for test in tests]
48 | idx_failures = [i for i, x in enumerate(results) if not x]
49 |
50 | if idx_failures:
51 | click.secho(f"Failures: {idx_failures}", fg="red")
52 | else:
53 | click.secho("Tests succeeded.", fg="green")
54 |
55 | subject, message = _prepare_message(idx_failures)
56 |
57 | if notification:
58 | from development.testing.notifications import send_notification
59 |
60 | send_notification(subject, message)
61 |
62 |
63 | def create_regression_tests(n_tests, save):
64 | """Create a regression vault.
65 |
66 | Parameters
67 | ----------
68 | n_tests : int
69 | How many tests are in the vault.
70 | save : bool, default True
71 | Flag for saving new tests to disk.
72 |
73 | """
74 | tests = [_create_single(i) for i in range(n_tests)]
75 |
76 | if save:
77 | with open(TEST_RESOURCES_DIR / "regression_vault.pickle", "wb") as p:
78 | pickle.dump(tests, p)
79 |
80 |
81 | def investigate_regression_test(idx):
82 | """Investigate regression tests."""
83 | tests = load_regression_tests()
84 | params, options, exp_val = tests[idx]
85 |
86 | crit_val = compute_log_likelihood(params, options)
87 |
88 | assert np.isclose(
89 | crit_val, exp_val, rtol=TOL_REGRESSION_TESTS, atol=TOL_REGRESSION_TESTS
90 | )
91 |
92 |
93 | def _check_single(test, strict):
94 | """Check a single test."""
95 | params, options, exp_val = test
96 |
97 | try:
98 | crit_val = compute_log_likelihood(params, options)
99 | is_success = np.isclose(
100 | crit_val, exp_val, rtol=TOL_REGRESSION_TESTS, atol=TOL_REGRESSION_TESTS
101 | )
102 | except Exception:
103 | is_success = False
104 |
105 | if strict is True:
106 | assert is_success, "Failed regression test."
107 |
108 | return is_success
109 |
110 |
111 | def _create_single(idx):
112 | """Create a single test."""
113 | np.random.seed(idx)
114 |
115 | params, options = generate_random_model()
116 |
117 | crit_val = compute_log_likelihood(params, options)
118 |
119 | if not isinstance(crit_val, float):
120 | raise AssertionError(" ... value of criterion function too large.")
121 |
122 | return params, options, crit_val
123 |
124 |
125 | @click.group(context_settings=CONTEXT_SETTINGS)
126 | def cli():
127 | """CLI manager for regression tests."""
128 | pass
129 |
130 |
131 | @cli.command()
132 | @click.argument("number_of_tests", type=int)
133 | @click.option("--strict", is_flag=True, help="Immediate termination on failure.")
134 | @click.option("--notification/--no-notification", default=True, help="Send report.")
135 | def run(number_of_tests, strict, notification):
136 | """Run a number of regression tests."""
137 | run_regression_tests(
138 | n_tests=number_of_tests, strict=strict, notification=notification
139 | )
140 |
141 |
142 | @cli.command()
143 | @click.argument("number_of_test", type=int)
144 | def investigate(number_of_test):
145 | """Investigate a single regression test."""
146 | investigate_regression_test(number_of_test)
147 |
148 |
149 | @cli.command()
150 | @click.argument("number_of_tests", type=int)
151 | @click.option("--save/--no-save", default=True, help="Saves new tests on disk.")
152 | def create(number_of_tests, save):
153 | """Create a new collection of regression tests."""
154 | create_regression_tests(n_tests=number_of_tests, save=save)
155 |
156 |
157 | if __name__ == "__main__":
158 | cli()
159 |
--------------------------------------------------------------------------------
/development/testing/test_cli.py:
--------------------------------------------------------------------------------
1 | from click.testing import CliRunner
2 | from testing.regression import create
3 | from testing.regression import investigate
4 | from testing.regression import run
5 |
6 |
7 | def test_investigate():
8 | runner = CliRunner()
9 | result = runner.invoke(investigate, ["0"])
10 |
11 | assert result.exit_code == 0
12 |
13 |
14 | def test_run():
15 | runner = CliRunner()
16 | result = runner.invoke(run, ["0", "--no-notification"])
17 |
18 | assert result.exit_code == 0
19 |
20 |
21 | def test_create():
22 | runner = CliRunner()
23 | result = runner.invoke(create, ["1", "--no-save"])
24 |
25 | assert result.exit_code == 0
26 |
--------------------------------------------------------------------------------
/development/testing/testing_pull_request.py:
--------------------------------------------------------------------------------
1 | """Run a series of tests that are required for any pull request to be merged."""
2 | import socket
3 |
4 | import click
5 | from click.testing import CliRunner
6 | from testing.regression import run
7 |
8 | import respy as rp
9 |
10 |
11 | def run_pull_request_tests():
12 | is_short_run = socket.gethostname() in ["abacus", "socrates"]
13 |
14 | click.secho("Starting pytest", fg="green")
15 | rp.test()
16 | click.secho("Stopping pytest", fg="green")
17 |
18 | n_tests = 50 if is_short_run else 1000
19 |
20 | runner = CliRunner()
21 |
22 | click.secho("Starting regression test.", fg="green")
23 | runner.invoke(run, [str(n_tests), "--strict"])
24 | click.secho("Stopping regression test.", fg="green")
25 |
26 |
27 | def main():
28 | """Run tests for validating pull request."""
29 | run_pull_request_tests()
30 |
31 |
32 | if __name__ == "__main__":
33 | main()
34 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # You can set these variables from the command line.
2 | SPHINXOPTS = -a
3 | SPHINXBUILD = sphinx-build
4 | SOURCEDIR = .
5 | BUILDDIR = _build
6 |
7 | # Put it first so that "make" without argument is like "make help".
8 | help:
9 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
10 |
11 | .PHONY: help Makefile
12 |
13 | # Catch-all target: route all unknown targets to Sphinx using the new
14 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
15 | %: Makefile
16 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
17 | livehtml:
18 | sphinx-autobuild -b html -i "*.respy.*" -i "**.ipynb_checkpoints" $(SPHINXOPTS) $(SOURCEDIR) $(BUILDDIR)/html
19 |
--------------------------------------------------------------------------------
/docs/_static/cscubs-2019/paper.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenSourceEconomics/respy/91e8a193fb7d5cf7212c15e50ae43f810bb9b1eb/docs/_static/cscubs-2019/paper.pdf
--------------------------------------------------------------------------------
/docs/_static/cscubs-2019/presentation.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenSourceEconomics/respy/91e8a193fb7d5cf7212c15e50ae43f810bb9b1eb/docs/_static/cscubs-2019/presentation.pdf
--------------------------------------------------------------------------------
/docs/_static/cscubs-2019/sources.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenSourceEconomics/respy/91e8a193fb7d5cf7212c15e50ae43f810bb9b1eb/docs/_static/cscubs-2019/sources.zip
--------------------------------------------------------------------------------
/docs/_static/css/custom.css:
--------------------------------------------------------------------------------
1 | div.prompt {
2 | display: none;
3 | }
4 |
5 | /* General */
6 |
7 | h1, h2, h3, h4, h5 {
8 | color: #004385 !important;
9 | }
10 |
11 | h1, h2 {
12 | text-align: center;
13 | }
14 |
15 | /*a {
16 | color: #0C619F !important;
17 | }*/
18 |
19 | a:hover {
20 | color: #187FB9 !important;
21 | }
22 |
23 | a:active {
24 | color: #187FB9 !important;
25 | }
26 |
27 | a.headerlink {
28 | color: #004385 !important;
29 | }
30 |
31 | a.headerlink:hover {
32 | color: #fff !important;
33 | background-color: #187FB9 !important;
34 | }
35 |
36 | /* color for naigation bar when item has been selected */
37 | .navbar-light .navbar-nav .active>.nav-link {
38 | color: #187FB9 !important;
39 | }
40 |
41 | /* color for sidebar item when it has been selected */
42 |
43 | .bd-sidebar .nav .active > a {
44 | color: #187FB9 !important;
45 | }
46 |
47 | /* toc on right of page, color when item is selected */
48 | .toc-entry > .nav-link.active {
49 | color: #187FB9;
50 | border-left: 2px solid #187FB9;
51 | }
52 |
53 | /* Getting started index page */
54 |
55 | .intro-card {
56 | padding: 40px 10px 20px 10px;
57 | margin: 10px 0px;
58 | max-height: 85%;
59 |
60 | }
61 |
62 | .intro-card .card-text {
63 | margin: 20px 0px;
64 |
65 | }
66 |
67 | .card-img-top + .card-body {
68 | padding-top: 0;
69 | }
70 |
71 | div.index-container {
72 | padding-bottom: 20px;
73 | }
74 |
75 | a.index-link {
76 | color: #333;
77 | text-decoration: none;
78 | }
79 |
80 | /* reference to user guide */
81 | .gs-torefguide {
82 | align-items: center;
83 | font-size: 0.9rem;
84 | }
85 |
86 | .gs-torefguide .badge {
87 | background-color: #004C8D;
88 | margin: 10px 10px 10px 0px;
89 | padding: 5px;
90 | }
91 |
92 | .gs-torefguide a {
93 | margin-left: 5px;
94 | color: #004C8D;
95 | border-bottom: 1px solid #fff79c;
96 | box-shadow: 0px -15px 0px #fff79c inset;
97 | }
98 |
99 | .gs-torefguide p {
100 | margin-top: 1rem;
101 | }
102 |
103 | .gs-torefguide a:hover {
104 | margin-left: 5px;
105 | color: grey;
106 | text-decoration: none;
107 | border-bottom: 1px solid #b2ff80f3;
108 | box-shadow: 0px -15px 0px #b2ff80f3 inset;
109 | }
110 |
111 | .blue { color: #004C8D; }
112 |
113 | .boldblue {
114 | font-weight: bold;
115 | color: #004C8D;
116 | }
117 |
118 | .centerblue {
119 | text-align: center;
120 | color: #004C8D;
121 | }
122 |
123 | .orange { color: orange; }
124 |
125 | .verbatimblue {
126 | font-weight: verbatim;
127 | color: #004C8D;
128 | }
129 |
130 | .boldcenterblue {
131 | font-weight: bold;
132 | text-align: center;
133 | color: #004C8D;
134 | }
135 |
136 | /* card tweaks */
137 |
138 | .shadow {
139 | box-shadow: 0 .5rem 0 rgba(0,0,0,.15) !important;
140 | transition: transform 0.2s, box-shadow 0.2s;
141 | }
142 |
143 | .shadow:hover {
144 | box-shadow: 0.3rem 0.7rem 0 rgba(0,0,0,.2) !important;
145 | transform: translate(-0.3rem,-0.2rem);
146 | transition: transform 0.2s, box-shadow 0.2s;
147 | }
148 |
149 | .card-header {
150 | font-weight: bold;
151 | font-size: 1.1em;
152 | display: flex;
153 | justify-content: center;
154 | align-items: center;
155 | min-height: 78px
156 | }
157 |
158 | .col, .col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col-auto, .col-lg, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-auto, .col-md, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md-auto, .col-sm, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-auto, .col-xl, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, .col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl-auto {
159 | padding: 15px;
160 | }
161 |
--------------------------------------------------------------------------------
/docs/_static/funding/Becker_Sebastian_Arbeitsprogramm.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenSourceEconomics/respy/91e8a193fb7d5cf7212c15e50ae43f810bb9b1eb/docs/_static/funding/Becker_Sebastian_Arbeitsprogramm.pdf
--------------------------------------------------------------------------------
/docs/_static/images/Logo_DIW_Berlin.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/_static/images/Logo_TRA1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenSourceEconomics/respy/91e8a193fb7d5cf7212c15e50ae43f810bb9b1eb/docs/_static/images/Logo_TRA1.png
--------------------------------------------------------------------------------
/docs/_static/images/UNI_Bonn_Logo_Standard_RZ_RGB.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/_static/images/book.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
19 |
--------------------------------------------------------------------------------
/docs/_static/images/books.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/_static/images/coding.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
24 |
--------------------------------------------------------------------------------
/docs/_static/images/dividers.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
59 |
--------------------------------------------------------------------------------
/docs/_static/images/edit.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
56 |
--------------------------------------------------------------------------------
/docs/_static/images/graduate-cap.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
49 |
--------------------------------------------------------------------------------
/docs/_static/images/light-bulb.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
34 |
--------------------------------------------------------------------------------
/docs/_static/images/note.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
57 |
--------------------------------------------------------------------------------
/docs/_static/images/number-blocks.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
57 |
--------------------------------------------------------------------------------
/docs/_static/images/research.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
52 |
--------------------------------------------------------------------------------
/docs/_static/images/road.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
111 |
--------------------------------------------------------------------------------
/docs/_static/images/study.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
54 |
--------------------------------------------------------------------------------
/docs/_static/respy.mplstyle:
--------------------------------------------------------------------------------
1 | lines.linewidth : 3 # line width in points
2 | font.size : 12
3 | axes.axisbelow : True # Draw axis grid lines and ticks below patches (True); above
4 | # patches but below lines ('line'); or above all (False).
5 | # Forces grid lines below figures.
6 | legend.frameon : False # Legend patch transparency.
7 | legend.scatterpoints : 3 # Number of scatter points in legend.
8 | figure.autolayout : true # Same as plt.tight_layout().
9 |
--------------------------------------------------------------------------------
/docs/_static/thesis_proposals/Salience_and_human_capital.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenSourceEconomics/respy/91e8a193fb7d5cf7212c15e50ae43f810bb9b1eb/docs/_static/thesis_proposals/Salience_and_human_capital.pdf
--------------------------------------------------------------------------------
/docs/_static/thesis_proposals/Sparsity_and_human_capital.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/OpenSourceEconomics/respy/91e8a193fb7d5cf7212c15e50ae43f810bb9b1eb/docs/_static/thesis_proposals/Sparsity_and_human_capital.pdf
--------------------------------------------------------------------------------
/docs/_templates/custom-about-us.html:
--------------------------------------------------------------------------------
1 |
2 | respy is developed and maintained by members of Open Source Economics.
3 | If you would like to contribute, you can check out our
4 | website and find us on
5 | GitHub.
6 | Your contributions are welcome!
7 |
2 |
3 | respy is developed and maintained by members of Open Source Economics.
4 | If you would like to contribute, you can check out our
5 | website and find us on
6 | GitHub.
7 | Your contributions are welcome!
97 |
98 |
99 |
100 |
101 | .. toctree::
102 | :maxdepth: 1
103 | :hidden:
104 |
105 | ../release_notes
106 | contributing_to_respy
107 | releases
108 | roadmap
109 | template_for_tutorials
110 |
--------------------------------------------------------------------------------
/docs/development/releases.rst:
--------------------------------------------------------------------------------
1 | Releases
2 | ========
3 |
4 | What is the new version number?
5 | -------------------------------
6 |
7 | The version number depends on the severity of the changes and adheres to `semantic
8 | versioning `_. The format is ... Increment
9 |
10 | 1. version when you make incompatible API changes,
11 | 2. version when you add functionality in a backwards compatible manner, and
12 | 3. version when you make backwards compatible bug fixes.
13 |
14 | You can create development releases which are allowed to be deleted, once a new version
15 | is released. Append ``dev0`` to the version string. Do not separate the string with a
16 | dash or another dot because ``conda`` will complain about the format.
17 |
18 |
19 | How to release a new version?
20 | -----------------------------
21 |
22 | 1. At first, we can draft a release on Github. Go to
23 | https://github.com/OpenSourceEconomics/respy/releases and click on "Draft a new
24 | release". Fill in the new version number as a tag and title. You can write a summary
25 | for the release, but also do it later. Important: Only save the draft. Do not
26 | publish, yet.
27 |
28 | 2. Second, we need to create a final PR to prepare everything for the new version. The
29 | name of the PR and the commit message will be "Release vx.y.z". We need to
30 |
31 | - use ``bumpversion part `` to increment the correct part of
32 | the version number in all files.
33 | - update information in ``CHANGES.rst`` to have summary of the changes which
34 | can also be posted in the Github repository under the tag.
35 |
36 | 3. Run
37 |
38 | .. code-block:: bash
39 |
40 | $ conda build .
41 |
42 | and check whether you can actually build a new version. If you experience errors, fix
43 | them here. Depending on whether you allowed automatic upload to Anaconda, the release
44 | appears under your account. Feel free to delete it.
45 |
46 | 4. Merge the PR into main.
47 |
48 | 5. After that, revisit the draft of the release. Make sure everything is fine. Now, you
49 | click on "Publish release" which creates a version tag on the latest commit of the
50 | specified branch. Make sure to target the master branch.
51 |
52 | 6. Check out the tag in your local repository and run
53 |
54 | .. code-block:: bash
55 |
56 | $ conda build . --user OpenSourceEconomics
57 |
58 | In case automatic upload is disabled, copy the path to the built package and type
59 |
60 | .. code-block:: bash
61 |
62 | $ anaconda upload --user OpenSourceEconomics
63 |
64 | 6. Visit `Anaconda.org `_ and check
65 | whether the release is available.
66 |
67 | 7. Spread the word!
68 |
--------------------------------------------------------------------------------
/docs/development/roadmap.rst:
--------------------------------------------------------------------------------
1 | .. _roadmap:
2 |
3 | Roadmap
4 | =======
5 |
6 | We aim for improvements to **respy** in Economics, Statistics, and Numerical Methods.
7 |
8 | Economics and Statistics
9 | ------------------------
10 |
11 | All topics listed here can be tackled as part of a bachelor or master thesis. If you are
12 | interested, please contact us!
13 |
14 | Explore Simulation Based Estimation
15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16 |
17 | We want to add simulation based estimation to **respy** and compare the accuracy of
18 | parameters estimated with maximum likelihood and simulation based methods. As **respy**
19 | already has the ability to simulate data, it would be very simple to implement method of
20 | simulated moments or indirect inference estimation. As part of this project, we could
21 | also experiments with approaches that make the criterion function smooth and therefore
22 | allow the use of fast optimizers. A starting point could be `Frazier, Oka and Zhu (2019)
23 | `_
24 |
25 | CCP and the Estimation of Nonseparable Dynamic Modes
26 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27 |
28 | In a recent paper `Kristensen, Nesheim, and de Paulo (2015)
29 | `_ generalize the conditional
30 | choice probabilities (CCP) estimator (`Hotz, Miller (1993)
31 | `_) to non-separable economic models. However,
32 | they are still missing an empirical application of their method as a proof of concept.
33 | The **respy** package offers a suitable starting point.
34 |
35 | Estimate a model by Approximate Bayesian Computation (ABC)
36 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
37 |
38 | Use the `ABCpy package `_ and **respy**'s
39 | simulation capabilities to estimate the model via ABC. Compare it against other
40 | estimation methods in terms of computational burden and precision of the estimates.
41 |
42 | Sparse Maximization and Human Capital Investment
43 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
44 |
45 | Gabaix (2014) proposes a fully tractable, unifying theory of limited attention in
46 | decision-making. The idea is that the decision-maker pays less or no attention to some
47 | features of the situation. A potential application of sparse maximization is human
48 | capital investment, since young individuals could (partially or even fully) neglect some
49 | relevant features, which could tilt their choices. This may imply that a considerable
50 | share of the US labor force is miss-allocated. For more information check out the
51 | :download:`full description
52 | <../_static/thesis_proposals/Sparsity_and_human_capital.pdf>`
53 |
54 | Salience Theory and Human Capital Investment
55 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
56 |
57 | Bordalo, Gennaioli and Shleifer (2013) propose a unifying theory of salience in
58 | decision-making. An attribute is salient when it “stands out” relative to the
59 | alternative choices. A potential application of salience theory is human capital
60 | investment, since young individuals could attach disproportionately high attention to
61 | professions with salient returns, which could tilt their choices. For more information
62 | check out the :download:`full description
63 | <../_static/thesis_proposals/Salience_and_human_capital.pdf>`
64 |
65 | Numerical Methods
66 | -----------------
67 |
68 | Improve numerical integration
69 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
70 |
71 | We use numerical integration to calculate value functions and choice probabilities in
72 | the maximum likelihood estimation. Currently we use a smoothed Monte-Carlo integration
73 | for both. For a thesis a student could explore how the accuracy and speed of the
74 | integrals changes with the following strategies:
75 |
76 | - Use a GHK simulator instead of current Monte-Carlo integration.
77 | - Use Gaussian quadrature for choice probabilities.
78 | - Allow for restrictions on the correlation structure of the shocks that make it
79 | possible to reduce the dimensionality of the integrals.
80 |
81 | Starting points are the following papers:
82 |
83 | - `Skrainka and Judd (2011) `_
84 | - `Dunnet (1989) `_
85 |
86 | Benchmark Different Optimizers
87 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
88 |
89 | Explore the speed and reliability of local and global optimizers for maximum likelihood
90 | estimation of the model. The results should be transferable to other estimation problems
91 | with a noisy criterion function. Most relevant optimizers should already be implemented
92 | in ``estimagic``. Otherwise they can be added easily.
93 |
94 | Approximate Dynamic Programming (ADP)
95 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
96 |
97 | We want to explore the usefulness of ADP techniques for solving large scale structural
98 | economic models. The seminal references is `Powell (2011)
99 | `_.
100 |
--------------------------------------------------------------------------------
/docs/development/template_for_tutorials.rst:
--------------------------------------------------------------------------------
1 | .. _template_for_tutorials:
2 |
3 | Template for tutorials
4 | ======================
5 |
6 | *This document should serve as a template for all tutorials. If something is not covered
7 | in here, please extend it.*
8 |
9 | In order to get started on a tutorial, please refer to the other :ref:`tutorials` to get
10 | a feel of the structure and language you should use so your tutorial is aligned with the
11 | rest of the documentation. Check out this `checklist
12 | `_ as an
13 | additional resource to guide you through the writing process.
14 |
15 | Goal
16 | ----
17 |
18 | Describe the goal and what the user should have learned by the end of this
19 | tutorial.
20 |
21 |
22 | Steps
23 | -----
24 |
25 | Tutorials should be structured as clearly defined, sequential steps to reaching the
26 | specified goal.
27 |
28 | The tutorials should be short, focused, and concise. This means you might have to omit
29 | background information that you consider helpful for understanding the underlying code
30 | and theory. If you want to guide the user to further material like related
31 | :ref:`explanations`, :ref:`how_to_guides`, and :ref:`reference_guides`, use the
32 | following buttons.
33 |
34 | .. raw:: html
35 |
36 |
37 | To explanations
38 |
39 | A more extended explanation to the economic model is provided in :ref:`economic_model`.
40 |
41 | .. raw:: html
42 |
43 |
44 |
--------------------------------------------------------------------------------
/docs/explanations/bib.rst:
--------------------------------------------------------------------------------
1 | Bibliography
2 | ============
3 |
4 | .. bibliography:: refs.bib
5 | :all:
6 | :style: plain
7 |
--------------------------------------------------------------------------------
/docs/explanations/economic_model.rst:
--------------------------------------------------------------------------------
1 | .. _economic_model:
2 |
3 | Economic Model
4 | ==============
5 |
6 | .. role:: boldblue
7 |
8 | To illustrate the usage of **respy** in solving :boldblue:`finite-horizon
9 | discrete choice dynamic programming` (DCDP) problems we will present the basic
10 | setup of the human capital model as conceptualized in Keane and Wolpin
11 | (1997, :cite:`Keane.1997`).
12 |
13 | --------------------------------------------------------------------------------
14 |
15 | .. rst-class:: centerblue
16 |
17 | The promise: **respy** will become your preferred tool
18 | to develop, solve, estimate, and explore models within the EKW framework
19 |
20 | --------------------------------------------------------------------------------
21 |
22 | At time t = 1,...,T each individual observes the state of the economic environment
23 | :math:`s_{t} \in \mathcal{S}_t` and chooses an action :math:`a_t` from the set of
24 | admissible actions :math:`\mathcal{A}`. The decision has two consequences:
25 |
26 | - Individuals receive per-period utility :math:`u_a(\cdot)` associated with the
27 | chosen alternative :math:`a_t \in \mathcal{A}`. [#]_
28 | - The economy evolves from :math:`s_{t}` to :math:`s_{t+1}`.
29 |
30 | Individuals are :boldblue:`forward-looking` and so do not simply choose the
31 | alternative with the highest immediate per-period utility. Instead, they take
32 | future consequences of their actions into account and implement a
33 | :boldblue:`policy` :math:`\pi \equiv (a_1^{\pi}(s_1), \dots, a_T^{\pi}(s_T))`.
34 | A policy is a collection of :boldblue:`decision rules` :math:`a_t^{\pi}(s_t)`
35 | that prescribe an action for any possible state :math:`s_t`. The implementation
36 | of a policy generates a sequence of per-period utilities that depends on the
37 | :boldblue:`objective transition probability distribution` :math:`p_t(s_t, a_t)`
38 | for the evolution of state :math:`s_{t}` to :math:`s_{t+1}` induced by the model.
39 | Individuals entertain :boldblue:`rational expectations` (Muth, 1961,
40 | :cite:`Muth.1961`) so their subjective beliefs about the future agree with the
41 | objective transition probabilities of the model.
42 |
43 | :ref:`timing_events` depicts the timing of events in the model for two generic
44 | periods. At the beginning of period t, an individual fully learns about the
45 | immediate per-period utility of each alternative, chooses one of them, and
46 | receives its immediate utility. Then the state evolves from :math:`s_t` to
47 | :math:`s_{t+1}` and the process is repeated in :math:`t+1`.
48 |
49 | .. _timing_events:
50 |
51 | .. figure:: ../_static/images/timing_events.svg
52 | :width: 650
53 | :alt: Illustration timing of events
54 |
55 | Timing of events
56 |
57 | Individuals face :boldblue:`uncertainty` (Gilboa, 2009, :cite:`Gilboa.2009`)
58 | and discount future per-period utilities by an exponential discount factor
59 | :math:`0 < \delta < 1` that parameterizes their time preference. Per-period
60 | utilities are time-separable (Samuelson, 1937, :cite:`Samuelson.1937`).
61 | Given an initial state :math:`s_1` individuals implement the policy :math:`\pi`
62 | from the set of all feasible policies :math:`\Pi` that :boldblue:`maximizes the
63 | expected total discounted utilities` over all :math:`T` periods.
64 |
65 | .. math::
66 |
67 | \underset{\pi \in \Pi}{\max} \, \mathbb{E}_{p^{\pi}} \left[ \sum_{t = 1}^T
68 | \delta^{t - 1} u(s_t, a_t^{\pi}(s_t)) \right],
69 |
70 | where :math:`\mathbb{E}_{p^{\pi}}[\cdot]` denotes the expectation operator under
71 | the probability measure :math:`p^{\pi}`. The decision problem is dynamic in the
72 | sense that expected inter-temporal per-period utilities at a certain period
73 | :math:`t` are influenced by past choices.
74 |
75 | .. raw:: html
76 |
77 |
79 | To Explanation
80 |
The operationalization of the model allows to proceed with the calibration as
81 | described in
82 | Mathematical Framework
83 |
84 |
85 |
86 | .. rubric:: Footnotes
87 |
88 | .. [#] For notational convenience we will omit the subscript :math:`a` whenever
89 | possible.
90 |
--------------------------------------------------------------------------------
/docs/explanations/implementation_kw94.rst:
--------------------------------------------------------------------------------
1 | .. implementation_kw94:
2 |
3 | Model in Keane and Wolpin (1994)
4 | ================================
5 |
6 | The explanations section of this documentation gives a detailed outline
7 | of the economic modeling components and the mathematical framework in
8 | Eckstein-Keane-Wolpin models using the example of Keane and Wolpin
9 | (1997, :cite:`Keane.1997`). In the documentation, you will often another model
10 | specification rooted in the publication Keane and Wolpin
11 | (1994, :cite:`Keane.1994`). This model constitutes a similar but simpler version
12 | of the model. We give a brief overview of the reward functions and components
13 | distinctive to this specification here. Note that the underlying economic and
14 | mathematical framework remains the same.
15 |
16 | --------------------------------------------------------------------------------
17 |
18 | .. raw:: html
19 |
20 |
22 | To Explanations
23 |
Find the economic model and mathematical framework in the
24 | Explanations
25 |
26 |
27 | --------------------------------------------------------------------------------
28 |
29 | The model from Keane and Wolpin (1994, :cite:`Keane.1994`) is characterized by four
30 | distinct choices. At each point in time :math:`t \in \{0, ...,39\}` individuals decide
31 | between :math:`a \in \{1,2,3,4\}` mutually exclusive alternatives:
32 | working in occupation *A*, working in occupation *B* ($a=1,2$), investing in
33 | *education* ($a=3$), or staying *home* ($a=4$). The alternatives are associated
34 | with the rewards:
35 |
36 | .. math::
37 |
38 | \text{Occupation A: } R_1(t) &= w_{1t} = r_{1}exp\{\alpha_{1} + \beta_{1,1}h_{t}
39 | + \gamma_{1,1}k_{1t} + \gamma_{1,2}k^2_{1t} + \gamma_{1,7}k_{2t}
40 | + \gamma_{2,8}k^2_{2t} + \epsilon_{1t}\} \nonumber \\
41 | \text{Occupation B: } R_2(t) &= w_{2t} =
42 | r_{2}exp\{\alpha_{2} + \beta_{2,1}h_{t} + \gamma_{2,1}k_{2t}
43 | + \gamma_{2,2}k^2_{2t} + \gamma_{2,7}k_{1t} + \gamma_{2,8}k^2_{1t}
44 | + \epsilon_{2t}\} \nonumber \\
45 | \text{School: }R_3(t) &= \alpha_3 + \beta_{tc}I(h_t \geq 12)
46 | + \beta_{rc}(1-d_3(t-1)) + \epsilon_{3t}, \nonumber \\
47 | \text{Home: }R_4(t) &= \alpha_4 + \epsilon_{4t}
48 |
49 |
50 | These rewards enter the alternative specific value functions of individuals. In these
51 | equations :math:`h(t)` denotes schooling in period :math:`t` and :math:`k_{at}` denotes
52 | work experience from sector :math:`A` or :math:`B` (:math:`a=1,2`). The reward for
53 | schooling includes an indicator :math:`I(h_t \geq 12)` which is connected to the cost of
54 | schooling after 12 periods (i.e. post-secondary schooling costs) and component that
55 | captures costs of returning to school when the choice in the previous period was
56 | something else. Aside from the parameters connected to these various components, each
57 | reward function also contains a constant and an alternative specific shock. The skill
58 | price in occupations is denoted by :math:`r_{a}`, it is set to 1 in this model. [#]_
59 |
60 |
61 | The model from Keane and Wolpin (1994, :cite:`Keane.1994`) is not a complete
62 | subset of the model outlined in the explanations. The most important deviations are:
63 |
64 | - The model includes an additional squared experience term with parameter
65 | :math:`\gamma_{2,8}` for experience in the other occupation.
66 |
67 | - It also does not include unobserved heterogeneity i.e. types. Here we thus
68 | define :math:`\alpha_{a}` as the constant for alternative :math:`a`.
69 |
70 | - We do not distinguish between different levels of post-secondary education.
71 | The parameters :math:`\beta_{tc}` and :math:`\beta_{tr}` are thus not enumerated.
72 |
73 |
74 | .. rubric:: Footnotes
75 |
76 | .. [#] Note that the reward functions are not only time but also individual specific.
77 | A subscript for individuals is left out for simplicity.
78 |
--------------------------------------------------------------------------------
/docs/explanations/introduction.rst:
--------------------------------------------------------------------------------
1 | .. _what_is_respy:
2 |
3 | What is respy?
4 | ==============
5 |
6 | **respy** is an open source framework written in Python for the simulation and
7 | estimation of some finite-horizon discrete choice dynamic programming (DCDP) models.
8 | In comparison to simple reduced-form analysis, these models allow the estimation
9 | of structural parameters which reflect agents' preferences and beliefs by assuming
10 | that agents are forward-looking and maximize expected intertemporal payoffs.
11 | Over the last decades, finite-horizon DCDP models have become a popular tool to
12 | answer research questions in areas of economics such as
13 | labor economics, industrial organization, economic demography, health economics,
14 | development economics, political economy, and marketing.
15 |
16 | What makes **respy** powerful is that it allows to build and solve structural
17 | models in weeks or months whose development previously took years. The design
18 | of **respy** allows the researcher to flexibly add the following components to
19 | her model.
20 |
21 | - Any number of discrete choices (e.g., working alternatives, schooling, home
22 | production, retirement) where each choice may yield a wage, may allow for
23 | experience accumulation and can be constrained by time, a maximum amount of
24 | accumulated experience or other characteristics.
25 | - Condition the decision of individuals on its previous choices or their labor
26 | market history.
27 | - Adding a finite mixture with any number of subgroups to account for
28 | unobserved heterogeneity among individuals as developed by Keane and Wolpin
29 | (1997, :cite:`Keane.1997`).
30 | - Any number of time-constant observed state variables (e.g., ability measures
31 | (Bhuller et al., 2020, :cite:`Bhuller.2020`), race (Keane and Wolpin, 2000,
32 | :cite:`Keane.2000`), demographic variables) found in the data.
33 | - Correct the estimation for measurement error in wages, either using a Kalman
34 | filter in maximum likelihood estimation or by adding the measurement error
35 | in simulation based approaches.
36 |
37 |
38 | As is common with structural economic models, finite-horizon DCDP models oftentimes
39 | rely on strong assumptions regarding unobservable state variables and error terms
40 | (see Aguirregabiria and Mira, 2010, :cite:`Aguirregabiria.2010`, p. 40 for a list
41 | of assumptions used in standard finite-horizon DCDP models).
42 | **respy** focuses on the estimation of so-called **Eckstein-Keane-Wolpin (EKW) models**.
43 | In accordance with Aguirregabiria and Mira (2010, :cite:`Aguirregabiria.2010`)
44 | , we classify a DCDP model as an EKW model if it departures from standard
45 | DCDP modeling by relaxing at least one of the following assumptions:
46 |
47 | 1. The one-period utility function does not have to be *additively separable* in
48 | its observable and unobservable components but can instead feature different
49 | compositions, e. g. multiplicative separability.
50 |
51 | 2. Observable payoff variables can be *choice-censored* and the value of the payoff
52 | variable does not have to be independent of the error term :math:`\epsilon`,
53 | conditional on the values of the decision and observable state variables.
54 |
55 | 3. *Permanent unobserved heterogeneity* is allowed to exist, i. e. the unobserved
56 | state variables do not have to be independently and identically distributed
57 | over agent and over time. As an example, the seminal work of Keane and Wolpin
58 | (1997, :cite:`Keane.1997`) introduces permanent unobserved heterogeneity by
59 | assigning each individual to one of four types.
60 |
61 | 4. Unobservables may be *correlated across choice alternatives*, i. e. unobserved
62 | state variables do not have to be independent across alternatives.
63 |
64 | .. raw:: html
65 |
66 |
73 |
--------------------------------------------------------------------------------
/docs/explanations/notation.rst:
--------------------------------------------------------------------------------
1 | Notation
2 | ========
3 |
4 | The following table summarizes the notation in order of their appearance.
5 |
6 | .. csv-table:: Table of Notation
7 | :header: "Symbol", "Explanation"
8 | :widths: 30, 70
9 |
10 |
11 | ":math:`s_t`", "state space at time :math:`t`"
12 | ":math:`s_t`", "state space at time :math:`t`"
13 | ":math:`\mathcal{S}_t`", "set of admissible states at time :math:`t`"
14 | ":math:`a_t`", "chosen alternative at time :math:`t`"
15 | ":math:`\mathcal{A}`", "set of feasible alternatives"
16 | ":math:`\pi`", "particular policy"
17 | ":math:`\Pi`", "set of implementable policies"
18 | ":math:`a_t^{\pi}(\cdot)`", "state-dependent decision rule under :math:`\pi`"
19 | ":math:`p_t(\cdot)`", "transition probability distribution for state :math:`s_{t+1}`"
20 | ":math:`\mathbb{E}_{p}[\cdot]`", "expectation under probability measure p"
21 | ":math:`\mathcal{J}`", "set of types"
22 | ":math:`e_{j,a}`", "skill endowment of type j in alternative a"
23 | ":math:`h_t`", "years of completed schooling at :math:`t`"
24 | ":math:`\bf{k}_{t}`", "vector of work-experience at :math:`t`"
25 | ":math:`\bf{\epsilon}`", "vector of productivity shocks"
26 | ":math:`r_a`", "market equilibrium rental price in alternative a"
27 | ":math:`x_a(\cdot)`", "occupation-specific skill level"
28 | ":math:`\Gamma_a(\cdot)`", "deterministic component of occupation-specific skill level"
29 | ":math:`\bar{u}_a`", "observable part per-period utility"
30 | ":math:`\bar{s}_t`", "observable part state-space"
31 | ":math:`\mathcal{D}`", "data structure"
32 | ":math:`M_D`", "moments of observed data"
33 | ":math:`M_S(\theta)`", "moments of simulated data under :math:`\theta`"
34 |
--------------------------------------------------------------------------------
/docs/explanations/parameterization.rst:
--------------------------------------------------------------------------------
1 | .. _parameterization:
2 |
3 | Parameterization
4 | ================
5 |
6 | .. raw:: html
7 |
8 |
10 | To Explanation
11 |
The following table keeps track of the parameterization for the computational
12 | implementation introduced in
13 | Computational Implementation
14 |
15 |
16 | The wildcard {civilian} means either "blue" or "white".
17 |
18 | .. csv-table:: Table of Parameterization
19 | :header: "Parameter", "State variable in **respy**", "Explanation"
20 | :widths: 20, 35, 45
21 |
22 | ":math:`\delta`", "delta", "discount factor"
23 | ":math:`e_{1,a}`", "type_1", "deviation for type 1 from type 0 in a"
24 | ":math:`e_{2,a}`", "type_2", "deviation for type 2 from type 0 in a"
25 | ":math:`e_{3,a}`", "type_3", "deviation for type 3 from type 0 in a"
26 | "", "**Common parameters**", ""
27 | ":math:`\alpha_a`", "constant", "log of rental price if the base skill endowment of type 0 is normalized to 0 (wage)"
28 | ":math:`\vartheta_1`", "common_hs_graduate", "common return to high school degree (non pecuniary)"
29 | ":math:`\vartheta_2`", "common_co_graduate", "common return to college degree (non pecuniary)"
30 | ":math:`\vartheta_3`", "common_hs_graduate", "effect of leaving the military early (after one year)"
31 | "", "**Schooling-related**", ""
32 | ":math:`\beta_{a,1}`", "exp_school", "linear return to an additional year of schooling (wage)"
33 | ":math:`\beta_{a,2}`", "exp_school", "skill premium of having finished high school (wage)"
34 | ":math:`\beta_{a,3}`", "exp_school", "skill premium of having finished college (wage)"
35 | ":math:`\beta_{tc_1}`", "hs_graduate", "net tuition costs college (non pecuniary)"
36 | ":math:`\beta_{tc_2}`", "co_graduate", "additional tuition costs graduate school (non pecuniary)"
37 | ":math:`\beta_{rc_1}`", "returns_to_high_school", "reward for going back to high school"
38 | ":math:`\beta_{rc_2}`", "returns_to_college", "reward for going back to college"
39 | "", "**Experience-related**", ""
40 | ":math:`\gamma_{a,1}`", "exp_{civilian}_collar", "return to experience, same sector, linear (wage)"
41 | ":math:`\gamma_{a,2}`", "exp_{civilian}_collar_square", "return to experience, same sector, quadratic (divided by 100) (wage)"
42 | ":math:`\gamma_{a,3}`", "any_exp_{civilian}_collar", "return for any experience in same sector"
43 | ":math:`\gamma_{a,4}`", "period", "linear age effect (wage)"
44 | ":math:`\gamma_{a,5}`", "is_minor", "effect of being a minor (wage)"
45 | ":math:`\gamma_{a,6}`", "work_{civilian}_collar_lagged", "effect of being a minor (wage)"
46 | ":math:`\gamma_{a,7}`", "exp_{civilian}_collar", "return to experience, other civilian sector, linear (wage)"
47 | ":math:`\gamma_{3,1}`", "exp_military", "return to experience, same sector, linear (wage)"
48 | ":math:`\gamma_{3,2}`", "exp_military_square", "return to experience, same sector, quadratic (divided by 100) (wage)"
49 | ":math:`\gamma_{3,3}`", "any_exp_military", "return to having any military experience"
50 | ":math:`\gamma_{3,4}`", "period", "linear age effect"
51 | ":math:`\gamma_{3,5}`", "is_minor", "effect of being a minor"
52 | ":math:`\gamma_{4,4}`", "period", "linear age effect"
53 | ":math:`\gamma_{4,5}`", "is_minor", "effect of being a minor"
54 | ":math:`\gamma_{5,4}`", "is_young_adult", "additional value of staying home if aged 18-20"
55 | ":math:`\gamma_{5,5}`", "is_adult", "additional value of staying home if 21 or older"
56 | "", "**Mobility and search**", ""
57 | ":math:`c_{a,1}`", "not_exp_{civilian}_collar_lagged", "reward of switching to a from other occupation (non pecuniary)"
58 | ":math:`c_{a,2}`", "not_any_exp_{civilian}_collar", "reward of working in a for the first time (non pecuniary)"
59 | ":math:`c_{3,2}`", "not_any_exp_military", "reward of being in the military sector for the first time (non pecuniary)"
60 |
--------------------------------------------------------------------------------
/docs/explanations/recommended_reading.rst:
--------------------------------------------------------------------------------
1 | Recommended Reading
2 | ===================
3 |
4 | To gain a deeper understanding of the underlying economic model and the mathematical
5 | methods used for solving and estimating this model as well as obtaining a small
6 | overview of the relevant literature we suggest the following supplementary material
7 | depending on your current state of prior knowledge.
8 |
9 | Before jumping right into reading the original papers (Keane and Wolpin 1994; 1997) it
10 | can be very helpful to refresh your knowledge on discrete choice dynamic programming.
11 |
12 | #. **Discrete Choice Methods with Simulation** (Kenneth Train, 2009, :cite:`Train.2009`)
13 | This book gives a concise introduction to static discrete choice models and the
14 | difficulties encountered in their estimation.
15 |
16 | #. **Economic Dynamics: Theory and Computation** (John Stachurski, 2009,
17 | :cite:`Stachurski.2009`)
18 | In the first part of this book one finds a succinct introduction to deterministic and
19 | probabilistic dynamical systems. In particular, the topics Finite state Markov chains
20 | and Finite state dynamic programming are elucidated.
21 |
22 | #. **The Structural Estimation of Behavioral Models: Discrete Choice Dynamic Programming
23 | Methods and Applications** (Keane, Wolpin and Todd, 2011, :cite:`Keane.2011`) In this
24 | handbook chapter discrete choice dynamic programming models are introduced including
25 | some applications in the field of labor economics.
26 |
27 | #. **Dynamic discrete choice structural models: A survey** (Aguirregabiria and Mira,
28 | 2010, :cite:`Aguirregabiria.2010`) In this comprehensive survey a more mathematically
29 | rigorous treatment of the subject is given.
30 |
31 |
32 | Core References
33 | ---------------
34 |
35 | The following studies served as the foundations of **respy** and are implemented as
36 | exmaple models in the package.
37 |
38 | * Keane, M. P. and Wolpin, K. I. (1994). `The Solution and Estimation of Discrete Choice
39 | Dynamic Programming Models by Simulation and Interpolation: Monte Carlo Evidence
40 | `_. *The Review of Economics and Statistics*, 76(4):
41 | 648-672.
42 |
43 |
44 | * Keane, M. P., & Wolpin, K. I. (1997). `The Career Decisions of Young Men
45 | `_. *Journal of Political Economy*,
46 | 105(3), 473-522.
47 |
48 | * Keane, M. P., & Wolpin, K. I. (2000). `Eliminating Race Differences in School Attainment and
49 | Labor Market Success `_.
50 | *Journal of Labor Economics*, 18(4), 614-652.
51 |
52 |
53 | .. raw:: html
54 |
55 |
62 |
--------------------------------------------------------------------------------
/docs/how_to_guides/how_to_numerical_integration.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "source": [
6 | "# Numerical Integration\n",
7 | "\n",
8 | "One important component of the solution to the DCDP problem in **respy** models is numerical integration. A bottleneck in solving and estimating the model is the solution of the expected value function, the so-called $EMax(\\cdot)$. Solving the $EMax(\\cdot)$ requires us to solve a multi-dimensional integral at every point in the state space. The integrated value function does not have an analytical solution and thus requires the application of numerical methods.\n",
9 | "\n",
10 | "As the models become more complex, the computational burden increases as adding new features to the model increases the required number of function evaluations, which are the costly operation in numerical integration. Numerical integration usually uses monte carlo simulation. Results from applied mathematics, however, suggest methods that are more efficient and thus enable a performance increase. For the same number of function evaluations (and hence computational cost) quasi-Monte Carlo methods achieve a significantly higher accuracy. **respy** thus enables users to select between various methods for the numerical approximation of the $EMax(\\cdot)$. The numerical integration is controlled in the `options` of a specified model.\n"
11 | ],
12 | "metadata": {}
13 | },
14 | {
15 | "cell_type": "code",
16 | "execution_count": 2,
17 | "source": [
18 | "import respy as rp\r\n",
19 | "_, options = rp.get_example_model(\"kw_94_one\", with_data=False)"
20 | ],
21 | "outputs": [],
22 | "metadata": {}
23 | },
24 | {
25 | "cell_type": "markdown",
26 | "source": [
27 | "## Numerical integration method\n",
28 | "\n",
29 | "The option `monte_carlo_sequence` controls how points are drawn.\n",
30 | "\n",
31 | "- `random`: Points are drawn randomly (crude Monte Carlo).\n",
32 | "- `sobol` or `halton`: Points are drawn from low-discrepancy sequences (superiority in coverage). This means a given approximation error can be achieved with less points."
33 | ],
34 | "metadata": {}
35 | },
36 | {
37 | "cell_type": "markdown",
38 | "source": [
39 | "
\r\n",
40 | "**Note**: **respy** relies on [chaospy](https://chaospy.readthedocs.io/en/master) for the `sobol` and `halton` sequence. You need to install it in addition to **respy**.\r\n",
41 | "
45 |
46 |
47 | We also maintain a list of replicated models from some research papers to validate
48 | **respy** against specific implementations and to showcase **respy**'s flexibility.
49 | You can additionally find projects exploring specific components of the implementation
50 | of Eckstein-Keane-Wolpin models.
51 |
52 | .. raw:: html
53 |
54 |
81 |
82 |
83 |
84 |
85 | .. toctree::
86 | :maxdepth: 1
87 | :hidden:
88 |
89 | research_papers
90 | theses
91 | keane-and-wolpin-1994
92 | estimating-keane-and-wolpin-1997-msm
93 | numerical_integration
94 |
--------------------------------------------------------------------------------
/docs/projects/research_papers.rst:
--------------------------------------------------------------------------------
1 | Research papers
2 | ===============
3 |
4 | Here is a list of research papers using **respy**.
5 |
6 | ----
7 |
8 | Eisenhauer, P., Janys, L. and Gabler, J. (2021). `Structural models for policy-making:
9 | Coping with parametric uncertainty `_. *Working Paper*.
10 |
11 | The ex-ante evaluation of policies using structural microeconometric models is based
12 | on estimated parameters as a stand-in for the truth. This practice ignores uncertainty
13 | in the counterfactual policy predictions of the model. We develop an approach that deals
14 | with parametric uncertainty and properly frames model-informed
15 | policy-making as a decision problem under uncertainty. We use the seminal human
16 | capital investment model by Keane and Wolpin (1997) as a well-known, influential,
17 | and empirically-grounded test case. We document considerable uncertainty in their
18 | policy predictions and highlight the resulting policy recommendations from using
19 | different formal rules on decision-making under uncertainty.
20 |
21 | Contact: `@peisenha `_, `@LJanys
22 | `_, `@janosg
23 | `_
24 |
25 | ----
26 |
27 | Bhuller, M., Eisenhauer, P. and Mendel, M. (2020). The Option Value of Education.
28 | *Working Paper*.
29 |
30 | We provide a comprehensive account of the returns to education using Norwegian
31 | population panel data with nearly career-long earnings histories. We use variation
32 | induced by a mandatory schooling reform for an instrumental variables strategy as
33 | well as the validation of a full structural model. We discuss the trade-offs between
34 | the two approaches. Using the structural model, we go beyond the standard return
35 | concepts such as Mincer returns and the internal rate of return. This allows us to
36 | account for the sequential resolution of uncertainty and nonlinearities in the
37 | returns to education. Both give rise to option values as each additional year of
38 | schooling provides information about the value of different schooling choices and
39 | new opportunities become available. We are thus able to estimate the true return to
40 | education and find an important role for option values.
41 |
42 | Contact: `@peisenha `_, `@mo2561057
43 | `_
44 |
45 | ----
46 |
47 | Eisenhauer, P. and Suchy, R. (2020). Robust Human Capital Investment under Risk and
48 | Ambiguity. *Working Paper*.
49 |
50 | We build on the prototypical life cycle model of human capital investment Keane and
51 | Wolpin (1994) and study individual decision-making under risk as well as ambiguity.
52 | Individuals fear model misspecification and seek robust decisions that work well
53 | over a whole range of models about their economic environment. We describe the
54 | individual's decision problem as a robust Markov decision process. Our Monte Carlo
55 | analysis indicates that the empirical finding of large psychic cost of schooling is
56 | in part due to model misspecification by econometricians who only analyze individual
57 | investment decisions under risk. This changes the mechanisms driving schooling
58 | decisions and affects the ex ante evaluation of tuition policies.
59 |
60 | Contact: `@peisenha `_, `@rafaelsuchy
61 | `_
62 |
63 | ----
64 |
65 | Eisenhauer, P. (2019). `The Approximate Solution of Finite-Horizon Discrete Choice
66 | Dynamic Programming Models: Revisiting Keane & Wolpin (1994)
67 | `_. *Journal of Applied Econometrics, 34* (1),
68 | 149-154.
69 |
70 | The estimation of finite‐horizon discrete‐choice dynamic programming (DCDP) models
71 | is computationally expensive. This limits their realism and impedes verification and
72 | validation efforts. `Keane and Wolpin (Review of Economics and Statistics, 1994,
73 | 76(4), 648–672) `_ propose an interpolation method
74 | that ameliorates the computational burden but introduces approximation error. I
75 | describe their approach in detail, successfully recompute their original quality
76 | diagnostics, and provide some additional insights that underscore the trade‐off
77 | between computation time and the accuracy of estimation results.
78 |
79 | Contact: `@peisenha `_
80 |
--------------------------------------------------------------------------------
/docs/reference_guides/index.rst:
--------------------------------------------------------------------------------
1 | .. _reference_guides:
2 |
3 | Reference Guides
4 | ================
5 |
6 | Reference Guides explain how **respy** is implemented. If you want to contribute to
7 | **respy** or if you are simply interested in the inner workings, you will find this
8 | section helpful. They assume you are already familiar with using **respy**.
9 |
10 |
11 | .. raw:: html
12 |
13 |