├── .gitignore ├── _notebook_repo ├── .gitignore └── README.md ├── lectures ├── _static │ ├── banner.png │ ├── pdfs │ │ ├── pi2.pdf │ │ ├── 3ndp.pdf │ │ ├── ECTA6180.pdf │ │ ├── firenze.pdf │ │ ├── aiyagari_obit.pdf │ │ ├── course_notes.pdf │ │ ├── new-branch-10.png │ │ ├── iteration_notes.pdf │ │ └── time_series_book.pdf │ ├── figures │ │ ├── kg.png │ │ ├── kg0.png │ │ ├── tsh.png │ │ ├── ci_1.png │ │ ├── ci_2.png │ │ ├── ci_3.png │ │ ├── ci_4.png │ │ ├── ci_5.png │ │ ├── ci_6.png │ │ ├── ci_7.png │ │ ├── ci_8.png │ │ ├── graph.png │ │ ├── tsh0.png │ │ ├── ci_5_1.png │ │ ├── ci_6_2.png │ │ ├── ci_6_3.png │ │ ├── ci_7_2.png │ │ ├── git-pull.png │ │ ├── graph2.png │ │ ├── graph3.png │ │ ├── graph4.png │ │ ├── repl_1.png │ │ ├── repl_2.png │ │ ├── tsh_hg.png │ │ ├── codecov_1.png │ │ ├── codecov_2.png │ │ ├── codecov_3.png │ │ ├── codecov_4.png │ │ ├── codecov_5.png │ │ ├── codecov_6.png │ │ ├── codecov_7.png │ │ ├── codecov_8.png │ │ ├── debugger_1.png │ │ ├── debugger_2.png │ │ ├── git-branch.png │ │ ├── git-clone.png │ │ ├── git-collab.png │ │ ├── git-issue.png │ │ ├── git-review.png │ │ ├── judd_fig1.png │ │ ├── judd_fig2.png │ │ ├── julia-path.png │ │ ├── juno-docs.png │ │ ├── juno-plots.png │ │ ├── kalman_ex3.png │ │ ├── kl_ex1_fig.png │ │ ├── kl_ex2_fig.png │ │ ├── nb2_julia.png │ │ ├── nb3_julia.png │ │ ├── nb4_julia.png │ │ ├── nb5_julia.png │ │ ├── nb6_julia.png │ │ ├── nb7_julia.png │ │ ├── new-branch.png │ │ ├── travis-log.png │ │ ├── vfi_vs_pfi.png │ │ ├── web_graph.png │ │ ├── col_pol_bij1.png │ │ ├── col_pol_bij2.png │ │ ├── ensemble_mean.png │ │ ├── git-add-local.png │ │ ├── git-create-pr.png │ │ ├── git-dropdown.png │ │ ├── git-edit-fork.png │ │ ├── git-issue-tab.png │ │ ├── git-makerepo.png │ │ ├── git-pr-branch.png │ │ ├── git-pr-edits.png │ │ ├── git-pr-expost.png │ │ ├── git-quick-pr.png │ │ ├── git-repo-list.png │ │ ├── git-review-2.png │ │ ├── git-settings.png │ │ ├── ifp_histogram.png │ │ ├── ifp_policies.png │ │ ├── julia_term_1.png │ │ ├── lae_marginals.png │ │ ├── matsuyama_14.png │ │ ├── mc_ex1_plot.png │ │ ├── mccall_resw_c.png │ │ ├── new-branch-10.png │ │ ├── new-branch-11.png │ │ ├── new-branch-2.png │ │ ├── new-branch-3.png │ │ ├── new-branch-4.png │ │ ├── new-branch-5.png │ │ ├── new-branch-6.png │ │ ├── new-branch-7.png │ │ ├── new-branch-8.png │ │ ├── new-branch-9.png │ │ ├── periodogram1.png │ │ ├── repeatexample.png │ │ ├── testing-dir.png │ │ ├── testing-fork.png │ │ ├── testing-git1.png │ │ ├── testing-git2.png │ │ ├── testing-pr2.png │ │ ├── vs-code-clone.png │ │ ├── vscode_plots.png │ │ ├── vscode_repl_1.png │ │ ├── wald_dec_rule.png │ │ ├── git-clone-fork.png │ │ ├── git-create-pr-2.png │ │ ├── git-fork-button.png │ │ ├── git-lfs-dialog.png │ │ ├── git-new-branch.png │ │ ├── hamilton_graph.png │ │ ├── ifp_agg_savings.png │ │ ├── kg_small_theta.png │ │ ├── orth_proj_def1.png │ │ ├── orth_proj_def2.png │ │ ├── orth_proj_def3.png │ │ ├── orth_proj_thm1.png │ │ ├── orth_proj_thm2.png │ │ ├── orth_proj_thm3.png │ │ ├── schelling_fig1.png │ │ ├── schelling_fig2.png │ │ ├── schelling_fig3.png │ │ ├── schelling_fig4.png │ │ ├── solution_og_ex2.png │ │ ├── test_program_1.png │ │ ├── testing-commit.png │ │ ├── testing-output.png │ │ ├── travis-progress.png │ │ ├── travis-settings.png │ │ ├── travis-trigger.png │ │ ├── vs-code-edits-1.png │ │ ├── vs-code-edits-2.png │ │ ├── vs-code-edits-3.png │ │ ├── vs-code-edits-4.png │ │ ├── vs-code-edits-5.png │ │ ├── vs-code-edits-6.png │ │ ├── vs-code-edits-7.png │ │ ├── vs-code-edits-8.png │ │ ├── vs-code-edits-9.png │ │ ├── vscode_intro_0.png │ │ ├── vscode_intro_1.png │ │ ├── vscode_intro_2.png │ │ ├── vscode_intro_3.png │ │ ├── vscode_intro_4.png │ │ ├── vscode_intro_5.png │ │ ├── vscode_intro_6.png │ │ ├── vscode_intro_7.png │ │ ├── vscode_latex_1.png │ │ ├── vscode_latex_2.png │ │ ├── docker-hello-world.png │ │ ├── docker-jlab-full.png │ │ ├── docker-jupyter-lab.png │ │ ├── git-desktop-commit.png │ │ ├── git-desktop-intro.png │ │ ├── git-fork-changes.png │ │ ├── git-fork-history.png │ │ ├── git-makerepo-full.png │ │ ├── git-merge-commit.png │ │ ├── git-merge-conflict.png │ │ ├── git-revert-commit.png │ │ ├── julia_formatter_1.png │ │ ├── julia_formatter_2.png │ │ ├── juno-workspace-1.png │ │ ├── jupyterlab_first.png │ │ ├── mc_aperiodicity1.png │ │ ├── mc_aperiodicity2.png │ │ ├── mc_irreducibility1.png │ │ ├── mc_irreducibility2.png │ │ ├── mccall_resw_alpha.png │ │ ├── mccall_resw_beta.png │ │ ├── mpe_vs_monopolist.png │ │ ├── new_package_vscode.png │ │ ├── sine-screenshot-2.png │ │ ├── solution_lqc_ex1.png │ │ ├── solution_lqc_ex2.png │ │ ├── solution_lss_ex1.png │ │ ├── solution_lss_ex2.png │ │ ├── solution_mass_ex2.png │ │ ├── solution_statd_ex1.png │ │ ├── solution_statd_ex2.png │ │ ├── starting_nb_julia.png │ │ ├── testing-notebook.png │ │ ├── vs-code-done-clone.png │ │ ├── vs-code-edits-10.png │ │ ├── vs-code-edits-11.png │ │ ├── vs-code-edits-12.png │ │ ├── vs-code-edits-13.png │ │ ├── vs-code-edits-14.png │ │ ├── vs-code-edits-15.png │ │ ├── vs-code-edits-16.png │ │ ├── vscode_add_package.png │ │ ├── vscode_jl_function.png │ │ ├── vscode_jupyter_1.png │ │ ├── vscode_jupyter_2.png │ │ ├── vscode_jupyter_3.png │ │ ├── window_smoothing.png │ │ ├── arellano_bond_prices.png │ │ ├── arellano_time_series.png │ │ ├── arellano_value_funcs.png │ │ ├── atom-merge-conflict.png │ │ ├── col_pol_composition.png │ │ ├── docker-basic-command.png │ │ ├── finite_dp_simple_og.png │ │ ├── git-desktop-commit2.png │ │ ├── git-pr-modification.png │ │ ├── juno-standard-layout.png │ │ ├── new_package_vscode_2.png │ │ ├── new_package_vscode_3.png │ │ ├── new_package_vscode_4.png │ │ ├── solution_lqc_ex3_g1.png │ │ ├── solution_lqc_ex3_g10.png │ │ ├── solution_lqc_ex3_g50.png │ │ ├── testing-atom-package.png │ │ ├── testing-expectations.png │ │ ├── uncertainty_traps_45.png │ │ ├── uncertainty_traps_mu.png │ │ ├── vscode_add_package_2.png │ │ ├── vscode_file_created.png │ │ ├── vscode_jl_function_2.png │ │ ├── vscode_julia_kernel.png │ │ ├── vscode_package_added.png │ │ ├── vscode_run_package_1.png │ │ ├── vscode_run_package_2.png │ │ ├── vscode_run_package_3.png │ │ ├── vscode_run_package_4.png │ │ ├── vscode_run_package_5.png │ │ ├── vscode_run_package_6.png │ │ ├── ar_smoothed_periodogram.png │ │ ├── arellano_bond_prices_2.png │ │ ├── arellano_default_probs.png │ │ ├── career_solutions_ex1_jl.png │ │ ├── career_solutions_ex3_jl.png │ │ ├── covariance_stationary.png │ │ ├── lake_distribution_wages.png │ │ ├── new_package_vscode_4_2.png │ │ ├── new_package_vscode_4_3.png │ │ ├── paths_and_stationarity.png │ │ ├── testing-atom-manifest.png │ │ ├── testing-repo-settings.png │ │ ├── uncertainty_traps_sim.png │ │ ├── docker-packages-preinstalled.png │ │ └── vscode_jupyter_kernel_execute.png │ ├── qe-logo-large.png │ ├── lectures-favicon.ico │ ├── quantecon-logo-transparent.png │ ├── code │ │ ├── julia_essentials │ │ │ └── us_cities.txt │ │ └── linear_models │ │ │ └── paths_and_hist.jl │ └── includes │ │ └── header.raw ├── getting_started_julia │ └── us_cities.txt ├── zreferences.md ├── intro.md ├── status.md ├── Project.toml ├── troubleshooting.md ├── _toc.yml ├── _config.yml ├── tools_and_techniques │ └── differentiable_simulation.jl ├── more_julia │ └── data_statistical_packages.md ├── multi_agent_models │ ├── schelling.md │ └── aiyagari.md ├── about_lectures.md └── introduction_dynamics │ ├── scalar_dynam.md │ └── short_path.md ├── .JuliaFormatter.toml ├── requirements.txt ├── .github ├── dependabot.yml ├── workflows │ ├── format.yml │ ├── cache.yml │ ├── ci.yml │ └── publish.yml └── copilot-instructions.md ├── format_all_directory.sh ├── prompts ├── enzyme_test.jl ├── simulation_prompt.md └── differentiation.md ├── format_myst.jl ├── wsl.md ├── AGENTS.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | _build 2 | us_cities.txt 3 | .DS_Store 4 | .vscode 5 | -------------------------------------------------------------------------------- /_notebook_repo/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | **/.ipynb_checkpoints 3 | .vscode/settings.json -------------------------------------------------------------------------------- /lectures/_static/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/banner.png -------------------------------------------------------------------------------- /lectures/_static/pdfs/pi2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/pdfs/pi2.pdf -------------------------------------------------------------------------------- /.JuliaFormatter.toml: -------------------------------------------------------------------------------- 1 | style = "sciml" 2 | margin = 80 3 | yas_style_nesting = true 4 | annotate_untyped_fields_with_any = false -------------------------------------------------------------------------------- /lectures/_static/figures/kg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/kg.png -------------------------------------------------------------------------------- /lectures/_static/figures/kg0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/kg0.png -------------------------------------------------------------------------------- /lectures/_static/figures/tsh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/tsh.png -------------------------------------------------------------------------------- /lectures/_static/pdfs/3ndp.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/pdfs/3ndp.pdf -------------------------------------------------------------------------------- /lectures/_static/figures/ci_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/ci_1.png -------------------------------------------------------------------------------- /lectures/_static/figures/ci_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/ci_2.png -------------------------------------------------------------------------------- /lectures/_static/figures/ci_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/ci_3.png -------------------------------------------------------------------------------- /lectures/_static/figures/ci_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/ci_4.png -------------------------------------------------------------------------------- /lectures/_static/figures/ci_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/ci_5.png -------------------------------------------------------------------------------- /lectures/_static/figures/ci_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/ci_6.png -------------------------------------------------------------------------------- /lectures/_static/figures/ci_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/ci_7.png -------------------------------------------------------------------------------- /lectures/_static/figures/ci_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/ci_8.png -------------------------------------------------------------------------------- /lectures/_static/figures/graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/graph.png -------------------------------------------------------------------------------- /lectures/_static/figures/tsh0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/tsh0.png -------------------------------------------------------------------------------- /lectures/_static/pdfs/ECTA6180.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/pdfs/ECTA6180.pdf -------------------------------------------------------------------------------- /lectures/_static/pdfs/firenze.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/pdfs/firenze.pdf -------------------------------------------------------------------------------- /lectures/_static/qe-logo-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/qe-logo-large.png -------------------------------------------------------------------------------- /lectures/_static/figures/ci_5_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/ci_5_1.png -------------------------------------------------------------------------------- /lectures/_static/figures/ci_6_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/ci_6_2.png -------------------------------------------------------------------------------- /lectures/_static/figures/ci_6_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/ci_6_3.png -------------------------------------------------------------------------------- /lectures/_static/figures/ci_7_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/ci_7_2.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-pull.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-pull.png -------------------------------------------------------------------------------- /lectures/_static/figures/graph2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/graph2.png -------------------------------------------------------------------------------- /lectures/_static/figures/graph3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/graph3.png -------------------------------------------------------------------------------- /lectures/_static/figures/graph4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/graph4.png -------------------------------------------------------------------------------- /lectures/_static/figures/repl_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/repl_1.png -------------------------------------------------------------------------------- /lectures/_static/figures/repl_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/repl_2.png -------------------------------------------------------------------------------- /lectures/_static/figures/tsh_hg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/tsh_hg.png -------------------------------------------------------------------------------- /lectures/_static/lectures-favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/lectures-favicon.ico -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | jupyter-book==0.15.1 2 | quantecon-book-theme==0.7.1 3 | sphinx-tojupyter==0.3.0 4 | sphinxext.rediraffe==0.2.7 5 | pip -------------------------------------------------------------------------------- /lectures/_static/figures/codecov_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/codecov_1.png -------------------------------------------------------------------------------- /lectures/_static/figures/codecov_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/codecov_2.png -------------------------------------------------------------------------------- /lectures/_static/figures/codecov_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/codecov_3.png -------------------------------------------------------------------------------- /lectures/_static/figures/codecov_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/codecov_4.png -------------------------------------------------------------------------------- /lectures/_static/figures/codecov_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/codecov_5.png -------------------------------------------------------------------------------- /lectures/_static/figures/codecov_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/codecov_6.png -------------------------------------------------------------------------------- /lectures/_static/figures/codecov_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/codecov_7.png -------------------------------------------------------------------------------- /lectures/_static/figures/codecov_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/codecov_8.png -------------------------------------------------------------------------------- /lectures/_static/figures/debugger_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/debugger_1.png -------------------------------------------------------------------------------- /lectures/_static/figures/debugger_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/debugger_2.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-branch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-branch.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-clone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-clone.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-collab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-collab.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-issue.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-issue.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-review.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-review.png -------------------------------------------------------------------------------- /lectures/_static/figures/judd_fig1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/judd_fig1.png -------------------------------------------------------------------------------- /lectures/_static/figures/judd_fig2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/judd_fig2.png -------------------------------------------------------------------------------- /lectures/_static/figures/julia-path.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/julia-path.png -------------------------------------------------------------------------------- /lectures/_static/figures/juno-docs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/juno-docs.png -------------------------------------------------------------------------------- /lectures/_static/figures/juno-plots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/juno-plots.png -------------------------------------------------------------------------------- /lectures/_static/figures/kalman_ex3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/kalman_ex3.png -------------------------------------------------------------------------------- /lectures/_static/figures/kl_ex1_fig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/kl_ex1_fig.png -------------------------------------------------------------------------------- /lectures/_static/figures/kl_ex2_fig.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/kl_ex2_fig.png -------------------------------------------------------------------------------- /lectures/_static/figures/nb2_julia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/nb2_julia.png -------------------------------------------------------------------------------- /lectures/_static/figures/nb3_julia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/nb3_julia.png -------------------------------------------------------------------------------- /lectures/_static/figures/nb4_julia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/nb4_julia.png -------------------------------------------------------------------------------- /lectures/_static/figures/nb5_julia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/nb5_julia.png -------------------------------------------------------------------------------- /lectures/_static/figures/nb6_julia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/nb6_julia.png -------------------------------------------------------------------------------- /lectures/_static/figures/nb7_julia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/nb7_julia.png -------------------------------------------------------------------------------- /lectures/_static/figures/new-branch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/new-branch.png -------------------------------------------------------------------------------- /lectures/_static/figures/travis-log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/travis-log.png -------------------------------------------------------------------------------- /lectures/_static/figures/vfi_vs_pfi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vfi_vs_pfi.png -------------------------------------------------------------------------------- /lectures/_static/figures/web_graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/web_graph.png -------------------------------------------------------------------------------- /lectures/_static/pdfs/aiyagari_obit.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/pdfs/aiyagari_obit.pdf -------------------------------------------------------------------------------- /lectures/_static/pdfs/course_notes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/pdfs/course_notes.pdf -------------------------------------------------------------------------------- /lectures/_static/pdfs/new-branch-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/pdfs/new-branch-10.png -------------------------------------------------------------------------------- /lectures/_static/figures/col_pol_bij1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/col_pol_bij1.png -------------------------------------------------------------------------------- /lectures/_static/figures/col_pol_bij2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/col_pol_bij2.png -------------------------------------------------------------------------------- /lectures/_static/figures/ensemble_mean.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/ensemble_mean.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-add-local.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-add-local.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-create-pr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-create-pr.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-dropdown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-dropdown.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-edit-fork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-edit-fork.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-issue-tab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-issue-tab.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-makerepo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-makerepo.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-pr-branch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-pr-branch.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-pr-edits.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-pr-edits.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-pr-expost.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-pr-expost.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-quick-pr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-quick-pr.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-repo-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-repo-list.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-review-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-review-2.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-settings.png -------------------------------------------------------------------------------- /lectures/_static/figures/ifp_histogram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/ifp_histogram.png -------------------------------------------------------------------------------- /lectures/_static/figures/ifp_policies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/ifp_policies.png -------------------------------------------------------------------------------- /lectures/_static/figures/julia_term_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/julia_term_1.png -------------------------------------------------------------------------------- /lectures/_static/figures/lae_marginals.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/lae_marginals.png -------------------------------------------------------------------------------- /lectures/_static/figures/matsuyama_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/matsuyama_14.png -------------------------------------------------------------------------------- /lectures/_static/figures/mc_ex1_plot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/mc_ex1_plot.png -------------------------------------------------------------------------------- /lectures/_static/figures/mccall_resw_c.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/mccall_resw_c.png -------------------------------------------------------------------------------- /lectures/_static/figures/new-branch-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/new-branch-10.png -------------------------------------------------------------------------------- /lectures/_static/figures/new-branch-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/new-branch-11.png -------------------------------------------------------------------------------- /lectures/_static/figures/new-branch-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/new-branch-2.png -------------------------------------------------------------------------------- /lectures/_static/figures/new-branch-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/new-branch-3.png -------------------------------------------------------------------------------- /lectures/_static/figures/new-branch-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/new-branch-4.png -------------------------------------------------------------------------------- /lectures/_static/figures/new-branch-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/new-branch-5.png -------------------------------------------------------------------------------- /lectures/_static/figures/new-branch-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/new-branch-6.png -------------------------------------------------------------------------------- /lectures/_static/figures/new-branch-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/new-branch-7.png -------------------------------------------------------------------------------- /lectures/_static/figures/new-branch-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/new-branch-8.png -------------------------------------------------------------------------------- /lectures/_static/figures/new-branch-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/new-branch-9.png -------------------------------------------------------------------------------- /lectures/_static/figures/periodogram1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/periodogram1.png -------------------------------------------------------------------------------- /lectures/_static/figures/repeatexample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/repeatexample.png -------------------------------------------------------------------------------- /lectures/_static/figures/testing-dir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/testing-dir.png -------------------------------------------------------------------------------- /lectures/_static/figures/testing-fork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/testing-fork.png -------------------------------------------------------------------------------- /lectures/_static/figures/testing-git1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/testing-git1.png -------------------------------------------------------------------------------- /lectures/_static/figures/testing-git2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/testing-git2.png -------------------------------------------------------------------------------- /lectures/_static/figures/testing-pr2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/testing-pr2.png -------------------------------------------------------------------------------- /lectures/_static/figures/vs-code-clone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vs-code-clone.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_plots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_plots.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_repl_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_repl_1.png -------------------------------------------------------------------------------- /lectures/_static/figures/wald_dec_rule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/wald_dec_rule.png -------------------------------------------------------------------------------- /lectures/_static/pdfs/iteration_notes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/pdfs/iteration_notes.pdf -------------------------------------------------------------------------------- /lectures/_static/pdfs/time_series_book.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/pdfs/time_series_book.pdf -------------------------------------------------------------------------------- /lectures/_static/figures/git-clone-fork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-clone-fork.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-create-pr-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-create-pr-2.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-fork-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-fork-button.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-lfs-dialog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-lfs-dialog.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-new-branch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-new-branch.png -------------------------------------------------------------------------------- /lectures/_static/figures/hamilton_graph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/hamilton_graph.png -------------------------------------------------------------------------------- /lectures/_static/figures/ifp_agg_savings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/ifp_agg_savings.png -------------------------------------------------------------------------------- /lectures/_static/figures/kg_small_theta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/kg_small_theta.png -------------------------------------------------------------------------------- /lectures/_static/figures/orth_proj_def1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/orth_proj_def1.png -------------------------------------------------------------------------------- /lectures/_static/figures/orth_proj_def2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/orth_proj_def2.png -------------------------------------------------------------------------------- /lectures/_static/figures/orth_proj_def3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/orth_proj_def3.png -------------------------------------------------------------------------------- /lectures/_static/figures/orth_proj_thm1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/orth_proj_thm1.png -------------------------------------------------------------------------------- /lectures/_static/figures/orth_proj_thm2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/orth_proj_thm2.png -------------------------------------------------------------------------------- /lectures/_static/figures/orth_proj_thm3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/orth_proj_thm3.png -------------------------------------------------------------------------------- /lectures/_static/figures/schelling_fig1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/schelling_fig1.png -------------------------------------------------------------------------------- /lectures/_static/figures/schelling_fig2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/schelling_fig2.png -------------------------------------------------------------------------------- /lectures/_static/figures/schelling_fig3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/schelling_fig3.png -------------------------------------------------------------------------------- /lectures/_static/figures/schelling_fig4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/schelling_fig4.png -------------------------------------------------------------------------------- /lectures/_static/figures/solution_og_ex2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/solution_og_ex2.png -------------------------------------------------------------------------------- /lectures/_static/figures/test_program_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/test_program_1.png -------------------------------------------------------------------------------- /lectures/_static/figures/testing-commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/testing-commit.png -------------------------------------------------------------------------------- /lectures/_static/figures/testing-output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/testing-output.png -------------------------------------------------------------------------------- /lectures/_static/figures/travis-progress.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/travis-progress.png -------------------------------------------------------------------------------- /lectures/_static/figures/travis-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/travis-settings.png -------------------------------------------------------------------------------- /lectures/_static/figures/travis-trigger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/travis-trigger.png -------------------------------------------------------------------------------- /lectures/_static/figures/vs-code-edits-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vs-code-edits-1.png -------------------------------------------------------------------------------- /lectures/_static/figures/vs-code-edits-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vs-code-edits-2.png -------------------------------------------------------------------------------- /lectures/_static/figures/vs-code-edits-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vs-code-edits-3.png -------------------------------------------------------------------------------- /lectures/_static/figures/vs-code-edits-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vs-code-edits-4.png -------------------------------------------------------------------------------- /lectures/_static/figures/vs-code-edits-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vs-code-edits-5.png -------------------------------------------------------------------------------- /lectures/_static/figures/vs-code-edits-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vs-code-edits-6.png -------------------------------------------------------------------------------- /lectures/_static/figures/vs-code-edits-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vs-code-edits-7.png -------------------------------------------------------------------------------- /lectures/_static/figures/vs-code-edits-8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vs-code-edits-8.png -------------------------------------------------------------------------------- /lectures/_static/figures/vs-code-edits-9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vs-code-edits-9.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_intro_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_intro_0.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_intro_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_intro_1.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_intro_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_intro_2.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_intro_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_intro_3.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_intro_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_intro_4.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_intro_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_intro_5.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_intro_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_intro_6.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_intro_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_intro_7.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_latex_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_latex_1.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_latex_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_latex_2.png -------------------------------------------------------------------------------- /lectures/_static/figures/docker-hello-world.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/docker-hello-world.png -------------------------------------------------------------------------------- /lectures/_static/figures/docker-jlab-full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/docker-jlab-full.png -------------------------------------------------------------------------------- /lectures/_static/figures/docker-jupyter-lab.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/docker-jupyter-lab.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-desktop-commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-desktop-commit.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-desktop-intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-desktop-intro.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-fork-changes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-fork-changes.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-fork-history.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-fork-history.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-makerepo-full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-makerepo-full.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-merge-commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-merge-commit.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-merge-conflict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-merge-conflict.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-revert-commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-revert-commit.png -------------------------------------------------------------------------------- /lectures/_static/figures/julia_formatter_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/julia_formatter_1.png -------------------------------------------------------------------------------- /lectures/_static/figures/julia_formatter_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/julia_formatter_2.png -------------------------------------------------------------------------------- /lectures/_static/figures/juno-workspace-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/juno-workspace-1.png -------------------------------------------------------------------------------- /lectures/_static/figures/jupyterlab_first.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/jupyterlab_first.png -------------------------------------------------------------------------------- /lectures/_static/figures/mc_aperiodicity1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/mc_aperiodicity1.png -------------------------------------------------------------------------------- /lectures/_static/figures/mc_aperiodicity2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/mc_aperiodicity2.png -------------------------------------------------------------------------------- /lectures/_static/figures/mc_irreducibility1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/mc_irreducibility1.png -------------------------------------------------------------------------------- /lectures/_static/figures/mc_irreducibility2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/mc_irreducibility2.png -------------------------------------------------------------------------------- /lectures/_static/figures/mccall_resw_alpha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/mccall_resw_alpha.png -------------------------------------------------------------------------------- /lectures/_static/figures/mccall_resw_beta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/mccall_resw_beta.png -------------------------------------------------------------------------------- /lectures/_static/figures/mpe_vs_monopolist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/mpe_vs_monopolist.png -------------------------------------------------------------------------------- /lectures/_static/figures/new_package_vscode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/new_package_vscode.png -------------------------------------------------------------------------------- /lectures/_static/figures/sine-screenshot-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/sine-screenshot-2.png -------------------------------------------------------------------------------- /lectures/_static/figures/solution_lqc_ex1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/solution_lqc_ex1.png -------------------------------------------------------------------------------- /lectures/_static/figures/solution_lqc_ex2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/solution_lqc_ex2.png -------------------------------------------------------------------------------- /lectures/_static/figures/solution_lss_ex1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/solution_lss_ex1.png -------------------------------------------------------------------------------- /lectures/_static/figures/solution_lss_ex2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/solution_lss_ex2.png -------------------------------------------------------------------------------- /lectures/_static/figures/solution_mass_ex2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/solution_mass_ex2.png -------------------------------------------------------------------------------- /lectures/_static/figures/solution_statd_ex1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/solution_statd_ex1.png -------------------------------------------------------------------------------- /lectures/_static/figures/solution_statd_ex2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/solution_statd_ex2.png -------------------------------------------------------------------------------- /lectures/_static/figures/starting_nb_julia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/starting_nb_julia.png -------------------------------------------------------------------------------- /lectures/_static/figures/testing-notebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/testing-notebook.png -------------------------------------------------------------------------------- /lectures/_static/figures/vs-code-done-clone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vs-code-done-clone.png -------------------------------------------------------------------------------- /lectures/_static/figures/vs-code-edits-10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vs-code-edits-10.png -------------------------------------------------------------------------------- /lectures/_static/figures/vs-code-edits-11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vs-code-edits-11.png -------------------------------------------------------------------------------- /lectures/_static/figures/vs-code-edits-12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vs-code-edits-12.png -------------------------------------------------------------------------------- /lectures/_static/figures/vs-code-edits-13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vs-code-edits-13.png -------------------------------------------------------------------------------- /lectures/_static/figures/vs-code-edits-14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vs-code-edits-14.png -------------------------------------------------------------------------------- /lectures/_static/figures/vs-code-edits-15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vs-code-edits-15.png -------------------------------------------------------------------------------- /lectures/_static/figures/vs-code-edits-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vs-code-edits-16.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_add_package.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_add_package.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_jl_function.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_jl_function.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_jupyter_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_jupyter_1.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_jupyter_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_jupyter_2.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_jupyter_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_jupyter_3.png -------------------------------------------------------------------------------- /lectures/_static/figures/window_smoothing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/window_smoothing.png -------------------------------------------------------------------------------- /lectures/_static/quantecon-logo-transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/quantecon-logo-transparent.png -------------------------------------------------------------------------------- /lectures/_static/figures/arellano_bond_prices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/arellano_bond_prices.png -------------------------------------------------------------------------------- /lectures/_static/figures/arellano_time_series.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/arellano_time_series.png -------------------------------------------------------------------------------- /lectures/_static/figures/arellano_value_funcs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/arellano_value_funcs.png -------------------------------------------------------------------------------- /lectures/_static/figures/atom-merge-conflict.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/atom-merge-conflict.png -------------------------------------------------------------------------------- /lectures/_static/figures/col_pol_composition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/col_pol_composition.png -------------------------------------------------------------------------------- /lectures/_static/figures/docker-basic-command.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/docker-basic-command.png -------------------------------------------------------------------------------- /lectures/_static/figures/finite_dp_simple_og.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/finite_dp_simple_og.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-desktop-commit2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-desktop-commit2.png -------------------------------------------------------------------------------- /lectures/_static/figures/git-pr-modification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/git-pr-modification.png -------------------------------------------------------------------------------- /lectures/_static/figures/juno-standard-layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/juno-standard-layout.png -------------------------------------------------------------------------------- /lectures/_static/figures/new_package_vscode_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/new_package_vscode_2.png -------------------------------------------------------------------------------- /lectures/_static/figures/new_package_vscode_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/new_package_vscode_3.png -------------------------------------------------------------------------------- /lectures/_static/figures/new_package_vscode_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/new_package_vscode_4.png -------------------------------------------------------------------------------- /lectures/_static/figures/solution_lqc_ex3_g1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/solution_lqc_ex3_g1.png -------------------------------------------------------------------------------- /lectures/_static/figures/solution_lqc_ex3_g10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/solution_lqc_ex3_g10.png -------------------------------------------------------------------------------- /lectures/_static/figures/solution_lqc_ex3_g50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/solution_lqc_ex3_g50.png -------------------------------------------------------------------------------- /lectures/_static/figures/testing-atom-package.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/testing-atom-package.png -------------------------------------------------------------------------------- /lectures/_static/figures/testing-expectations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/testing-expectations.png -------------------------------------------------------------------------------- /lectures/_static/figures/uncertainty_traps_45.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/uncertainty_traps_45.png -------------------------------------------------------------------------------- /lectures/_static/figures/uncertainty_traps_mu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/uncertainty_traps_mu.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_add_package_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_add_package_2.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_file_created.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_file_created.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_jl_function_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_jl_function_2.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_julia_kernel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_julia_kernel.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_package_added.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_package_added.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_run_package_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_run_package_1.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_run_package_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_run_package_2.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_run_package_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_run_package_3.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_run_package_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_run_package_4.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_run_package_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_run_package_5.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_run_package_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_run_package_6.png -------------------------------------------------------------------------------- /lectures/_static/figures/ar_smoothed_periodogram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/ar_smoothed_periodogram.png -------------------------------------------------------------------------------- /lectures/_static/figures/arellano_bond_prices_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/arellano_bond_prices_2.png -------------------------------------------------------------------------------- /lectures/_static/figures/arellano_default_probs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/arellano_default_probs.png -------------------------------------------------------------------------------- /lectures/_static/figures/career_solutions_ex1_jl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/career_solutions_ex1_jl.png -------------------------------------------------------------------------------- /lectures/_static/figures/career_solutions_ex3_jl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/career_solutions_ex3_jl.png -------------------------------------------------------------------------------- /lectures/_static/figures/covariance_stationary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/covariance_stationary.png -------------------------------------------------------------------------------- /lectures/_static/figures/lake_distribution_wages.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/lake_distribution_wages.png -------------------------------------------------------------------------------- /lectures/_static/figures/new_package_vscode_4_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/new_package_vscode_4_2.png -------------------------------------------------------------------------------- /lectures/_static/figures/new_package_vscode_4_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/new_package_vscode_4_3.png -------------------------------------------------------------------------------- /lectures/_static/figures/paths_and_stationarity.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/paths_and_stationarity.png -------------------------------------------------------------------------------- /lectures/_static/figures/testing-atom-manifest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/testing-atom-manifest.png -------------------------------------------------------------------------------- /lectures/_static/figures/testing-repo-settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/testing-repo-settings.png -------------------------------------------------------------------------------- /lectures/_static/figures/uncertainty_traps_sim.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/uncertainty_traps_sim.png -------------------------------------------------------------------------------- /lectures/_static/figures/docker-packages-preinstalled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/docker-packages-preinstalled.png -------------------------------------------------------------------------------- /lectures/_static/figures/vscode_jupyter_kernel_execute.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/QuantEcon/lecture-julia.myst/main/lectures/_static/figures/vscode_jupyter_kernel_execute.png -------------------------------------------------------------------------------- /lectures/getting_started_julia/us_cities.txt: -------------------------------------------------------------------------------- 1 | new york: 8244910 2 | los angeles: 3819702 3 | chicago: 2707120 4 | houston: 2145146 5 | philadelphia: 1536471 6 | phoenix: 1469471 7 | san antonio: 1359758 8 | san diego: 1326179 9 | dallas: 1223229 -------------------------------------------------------------------------------- /lectures/_static/code/julia_essentials/us_cities.txt: -------------------------------------------------------------------------------- 1 | new york: 8244910 2 | los angeles: 3819702 3 | chicago: 2707120 4 | houston: 2145146 5 | philadelphia: 1536471 6 | phoenix: 1469471 7 | san antonio: 1359758 8 | san diego: 1326179 9 | dallas: 1223229 10 | -------------------------------------------------------------------------------- /lectures/_static/includes/header.raw: -------------------------------------------------------------------------------- 1 | .. raw:: html 2 | 3 |
4 | 5 | QuantEcon 6 | 7 |
8 | -------------------------------------------------------------------------------- /lectures/zreferences.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Julia 8 | language: julia 9 | name: julia-1.12 10 | --- 11 | 12 | (references)= 13 | # References 14 | 15 | ```{bibliography} _static/quant-econ.bib 16 | ``` 17 | 18 | -------------------------------------------------------------------------------- /lectures/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Python 3 8 | language: python 9 | name: python3 10 | --- 11 | 12 | # Quantitative Economics with Julia 13 | 14 | This website presents a set of lectures on quantitative economic modeling. 15 | 16 | ```{tableofcontents} 17 | ``` -------------------------------------------------------------------------------- /_notebook_repo/README.md: -------------------------------------------------------------------------------- 1 | # lecture-julia.notebooks 2 | 3 | [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/QuantEcon/lecture-julia.notebooks/main) 4 | 5 | Notebooks for https://julia.quantecon.org 6 | 7 | - [Lecture source](https://github.com/QuantEcon/lecture-julia.myst) 8 | - [README source code](https://github.com/QuantEcon/lecture-julia.myst/blob/main/_notebook_repo/README.md) 9 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: github-actions 9 | directory: / 10 | commit-message: 11 | prefix: ⬆️ 12 | schedule: 13 | interval: weekly 14 | -------------------------------------------------------------------------------- /lectures/status.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Julia 8 | language: julia 9 | name: julia-1.12 10 | --- 11 | 12 | # Execution Statistics 13 | 14 | This table contains the latest execution statistics. 15 | 16 | ```{nb-exec-table} 17 | ``` 18 | 19 | These lectures are built on `linux` instances through `github actions` so are 20 | executed using the following [hardware specifications](https://docs.github.com/en/actions/reference/specifications-for-github-hosted-runners#supported-runners-and-hardware-resources) -------------------------------------------------------------------------------- /format_all_directory.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Check if at least one argument is given 4 | if [ "$#" -lt 1 ]; then 5 | echo "Usage: $0 path/to/md/files/ [use_replacements]" 6 | exit 1 7 | fi 8 | 9 | # Directory containing markdown files, ensuring it has a trailing slash 10 | dir_path="${1%/}/" 11 | 12 | # Optional use_replacements flag, default to "false" if not provided 13 | use_replacements=${2:-false} 14 | 15 | # Loop over all .md files in the given directory 16 | for file_path in ${dir_path}*.md; do 17 | # Only process regular files 18 | if [ -f "$file_path" ]; then 19 | # Call the Julia script with the current .md file and the use_replacements flag 20 | julia format_myst.jl "$file_path" $use_replacements 21 | fi 22 | done 23 | -------------------------------------------------------------------------------- /lectures/_static/code/linear_models/paths_and_hist.jl: -------------------------------------------------------------------------------- 1 | using Plots 2 | gr(fmt=:png); 3 | using QuantEcon 4 | 5 | phi_1, phi_2, phi_3, phi_4 = 0.5, -0.2, 0, 0.5 6 | sigma = 0.1 7 | 8 | A = [phi_1 phi_2 phi_3 phi_4 9 | 1.0 0.0 0.0 0.0 10 | 0.0 1.0 0.0 0.0 11 | 0.0 0.0 1.0 0.0] 12 | 13 | C = [sigma 0.0 0.0 0.0]' 14 | G = [1.0 0.0 0.0 0.0] 15 | 16 | T = 30 17 | ar = LSS(A, C, G, mu_0=ones(4)) 18 | 19 | ymin, ymax = -0.8, 1.25 20 | 21 | ys = [] 22 | yTs = [] 23 | 24 | for i=1:20 25 | x, y = simulate(ar, T+15) 26 | y = vec(y) 27 | push!(ys, y) 28 | push!(yTs, y[T]) 29 | end 30 | p1 = plot(ys, linewidth=1, alpha=0.5) 31 | scatter!(fill(T, length(yTs)), yTs, color=:black) 32 | plot!(ylims=(ymin, ymax), xticks=[], ylabel="y_t") 33 | vline!([T], color=:black, legend=:none) 34 | annotate!(T+1, -0.8, "T") 35 | 36 | p2 = histogram(yTs, bins=16, normed=true, orientation=:h, alpha=0.5) 37 | plot!(ylims=(ymin, ymax)) 38 | plot(p1, p2, layout=2, legend=:none) 39 | -------------------------------------------------------------------------------- /.github/workflows/format.yml: -------------------------------------------------------------------------------- 1 | name: Format Markdown Files 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - 'skip-for-now' # - '*' 7 | 8 | jobs: 9 | format: 10 | if: '! github.event.pull_request.draft' 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Checkout repository 15 | uses: actions/checkout@v6 16 | 17 | - name: Setup Julia 18 | uses: julia-actions/setup-julia@v2 19 | with: 20 | version: 1.12.3 21 | 22 | - name: Install JuliaFormatter.jl 23 | run: julia -e 'import Pkg; Pkg.add("JuliaFormatter")' 24 | 25 | - name: Get Changed Files 26 | id: changed_files 27 | uses: tj-actions/changed-files@v47.0.1 28 | with: 29 | files: | 30 | **/*.md 31 | 32 | - name: Format Markdown Files 33 | run: | 34 | for file in ${{ steps.changed_files.outputs.all_changed_files }}; do 35 | julia format_myst.jl "$file" 36 | done 37 | env: 38 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 39 | 40 | - name: Commit changes 41 | run: | 42 | git config --local user.email "action@github.com" 43 | git config --local user.name "GitHub Action" 44 | git add . 45 | git diff-index --quiet HEAD || git commit -m "Apply formatting to Markdown files" 46 | env: 47 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 48 | 49 | - name: Push changes 50 | uses: ad-m/github-push-action@master 51 | with: 52 | github_token: ${{ secrets.GITHUB_TOKEN }} 53 | branch: ${{ github.head_ref }} 54 | -------------------------------------------------------------------------------- /.github/workflows/cache.yml: -------------------------------------------------------------------------------- 1 | name: Build Cache 2 | on: 3 | push: 4 | branches: 5 | - main 6 | schedule: 7 | # Run monthly to avoid stale cache 8 | - cron: '0 0 1 * *' 9 | jobs: 10 | cache: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout 14 | uses: actions/checkout@v6 15 | - name: Set up Python 16 | uses: actions/setup-python@v6 17 | with: 18 | python-version: 3.11 19 | - name: Install Python Dependencies 20 | run: | 21 | pip install -r requirements.txt 22 | - name: Install LaTeX dependencies 23 | run: | 24 | sudo apt-get -qq update 25 | sudo apt-get install -y \ 26 | texlive-latex-recommended \ 27 | texlive-latex-extra \ 28 | texlive-fonts-recommended \ 29 | texlive-fonts-extra \ 30 | texlive-xetex \ 31 | latexmk \ 32 | xindy \ 33 | texlive-luatex \ 34 | dvipng \ 35 | ghostscript \ 36 | cm-super 37 | - name: Set up Julia 38 | uses: julia-actions/setup-julia@v2 39 | with: 40 | version: 1.12.3 41 | - name: Install IJulia and Setup Project 42 | shell: bash 43 | run: | 44 | julia -e 'using Pkg; Pkg.add("IJulia");' 45 | julia --project=lectures --threads auto -e 'using Pkg; Pkg.instantiate();' 46 | - name: Build HTML 47 | shell: bash -l {0} 48 | run: | 49 | jb build lectures --path-output ./ 50 | - name: Upload the "_build" folder (cache) 51 | uses: actions/upload-artifact@v6 52 | with: 53 | name: build-cache 54 | path: _build 55 | include-hidden-files: true 56 | -------------------------------------------------------------------------------- /prompts/enzyme_test.jl: -------------------------------------------------------------------------------- 1 | using Enzyme, LinearAlgebra, EnzymeTestUtils 2 | 3 | # 1. Define the Cache Struct 4 | struct SimCache{T} 5 | tmp_vec::Vector{T} 6 | tmp_mat::Matrix{T} 7 | end 8 | 9 | # Helper to build it (good for users) 10 | function alloc_cache(n) 11 | SimCache(zeros(n), zeros(n, n)) 12 | end 13 | 14 | # 2. The In-Place Function 15 | # Order: out, x (input), cache (buffers) 16 | function simulate!(out, x, cache::SimCache) 17 | # unpack for clarity 18 | tmp = cache.tmp_vec 19 | 20 | # Example: Intermediate computation that needs a buffer 21 | # If we didn't have cache, this line would allocate 22 | @. tmp = x * x + 2 23 | 24 | # Write to out 25 | @. out = tmp^2 26 | return nothing 27 | end 28 | 29 | # 3. Setup for Enzyme 30 | n = 100 31 | x = rand(n) 32 | out = zeros(n) 33 | cache = alloc_cache(n) 34 | 35 | # Create "Shadows" (gradients) 36 | # Enzyme.make_zero creates a structural copy with all zeros 37 | dx = Enzyme.make_zero(x) 38 | dout = Enzyme.make_zero(out) # "Seed" for the gradient (e.g., set to 1s if scalar) 39 | dcache = Enzyme.make_zero(cache) # The shadow workspace! 40 | 41 | # Initialize the seed (e.g., we want gradient of sum(out)) 42 | dout .= 1.0 43 | 44 | # 4. The Call 45 | # Note: We pass Duplicated for the cache because it is MUTATED. 46 | autodiff(Reverse, simulate!, 47 | Duplicated(out, dout), 48 | Duplicated(x, dx), 49 | Duplicated(cache, dcache) 50 | ) 51 | 52 | 53 | # 1. Setup Data 54 | x = randn(10) 55 | out = zeros(10) 56 | cache = alloc_cache(10) # User-defined helper to build cache struct 57 | 58 | # 2. Test Gradient of `x` 59 | # We use `test_reverse` to compare AD against Finite Differences. 60 | # Note: `out` and `cache` are mutated, so they MUST be Duplicated. 61 | test_reverse(simulate!, Const, 62 | (out, Duplicated), # Mutated Output 63 | (x, Duplicated), # Input (Active for differentiation) 64 | (cache, Duplicated) # Mutated Workspace 65 | ) 66 | 67 | test_forward(simulate!, Const, 68 | (out, Duplicated), 69 | (x, Duplicated), 70 | (cache, Duplicated) 71 | ) -------------------------------------------------------------------------------- /prompts/simulation_prompt.md: -------------------------------------------------------------------------------- 1 | # Background and Guidelines 2 | I am trying to add lecture notes which show differentiable simulation in Julia using Enzyme.jl. We will add these to various lectures when they are complete. 3 | 4 | You are an expert Julia developer specializing in high-performance computing, zero-allocation patterns, and auto-differentiation. When writing code, prioritize strict memory management and in-place operations. Adhere to the following guidelines`: 5 | - See ./AGENTS.md for more details and look at programming patterns in the code examples as required. 6 | - Read ./prompts/differentiation.md for specific Enzyme.jl coding patterns and inplace. 7 | - You can create a .jl file and then run it with `julia --project=lectures ...` since that project and manifest file are already set up with Enzyme and all dependencies. 8 | - Do not add new dependencies unless absolutely necessary. 9 | - Our primary AD target is Enzyme.jl. 10 | - However, it has some constraints on usage. In particular, it does not support allocation inside of differentiable functions (e.g., avoids garbage collection). See ./prompts/differentiation.md for specific coding patterns to follow when writing Enzyme-differentiable Julia code. 11 | 12 | # Notation for Linear State Space Models 13 | If using a LSS, the math notation/formulation is as follows: 14 | $$ 15 | x_{t+1} = A x_t + C w_{t+1} 16 | y_t = G x_t + H v_t 17 | $$ 18 | where 19 | - w_{t+1} ~ N(0, I 20 | - v_t ~ N(0, I). 21 | - x_t \in R^N 22 | - y_t \in R^M 23 | - w_{t+1} \in R^K 24 | - v_t \in R^L. 25 | - A \in R^{N x N}, C \in R^{N x K}, G \in R^{M x N}, H \in R^{M x L}. 26 | - In cases with an initial prior x_0 ~ N(mu_0, Sigma_0) if normal 27 | 28 | # Task 29 | ### STEP 1: 30 | I want to show first code for an inplace simulation of a LSS model. Write a function with signature 31 | ```julia 32 | simulate_lss!(x, y, A, C, G, H, x_0, w, v) 33 | ``` 34 | - The simulation length is implicit in the `w` and `v`. i.e., T = length(w) and I believe that v is then of size T+1 35 | - The output `x` and `y` are preallocated arrays of size (N, T+1) and (M, T+1) respectively. Organize the column vs. row ordering to ensure cache contiguity. 36 | I do not believe it needs a cache in this case since it would modify the `x` and `y` in place. 37 | - When you have that function write a simple example with $N = 3, M = 2, K = 2, L = 2$ and $T = 10$ where you either randomly choose the matrices or pick something reasonable (start with small `C` and `H` to avoid dominating noise). Draw the random normal shocks with `randn`. 38 | - Use plots to show the output of the `x` and `y` time series. 39 | 40 | Let me know when you have written this as a nice, clean jl file in ./lectures/more_julia/differentiable_simulation.jl 41 | -------------------------------------------------------------------------------- /lectures/Project.toml: -------------------------------------------------------------------------------- 1 | name = "quantecon-notebooks-julia" 2 | version = "0.10.0" 3 | authors = ["quantecon "] 4 | 5 | [deps] 6 | Arpack = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97" 7 | BandedMatrices = "aae01518-5342-5314-be14-df237901396f" 8 | BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" 9 | ControlSystems = "a6e380b2-a6ca-5380-bf3e-84a91bcd477e" 10 | DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" 11 | DataInterpolations = "82cc6244-b520-54b8-b5a6-8a565e85f1d0" 12 | Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" 13 | Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" 14 | EnzymeTestUtils = "12d8515a-0907-448a-8884-5fe00fdf1c5a" 15 | FastGaussQuadrature = "442a2c76-b920-505d-bb47-c5924d526838" 16 | FixedPointAcceleration = "817d07cb-a79a-5c30-9a31-890123675176" 17 | ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" 18 | Graphs = "86223c79-3864-5bf0-83f7-82e725a168b6" 19 | IncompleteLU = "40713840-3770-5561-ab4c-a76e7d0d7895" 20 | Integrals = "de52edbc-65ea-441a-8357-d3a637375a31" 21 | Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" 22 | IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153" 23 | KernelDensity = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" 24 | LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" 25 | Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" 26 | LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" 27 | LinearMaps = "7a12625a-238d-50fd-b39a-03d52299707e" 28 | LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" 29 | LoopVectorization = "bdcacae8-1622-11e9-2a5c-532679323890" 30 | MatrixEquations = "99c1a7ee-ab34-5fd5-8076-27c950a045f4" 31 | NLsolve = "2774e3e8-f4cf-5e23-947b-6d7e65073b56" 32 | NonlinearSolve = "8913a72c-1f9b-4ce2-8d82-65094dcecaec" 33 | Optim = "429524aa-4258-5aef-a3af-852621145aeb" 34 | Optimization = "7f7a1694-90dd-40f0-9382-eb1efda571ba" 35 | OptimizationOptimJL = "36348300-93cb-4f02-beb5-3c3902f8871e" 36 | OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" 37 | Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" 38 | Polynomials = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" 39 | Preconditioners = "af69fa37-3177-5a40-98ee-561f696e4fcd" 40 | QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" 41 | QuantEcon = "fcd29c91-0bd7-5a09-975d-7ac3f643a60c" 42 | Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" 43 | Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" 44 | SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" 45 | SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" 46 | StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" 47 | Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" 48 | StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd" 49 | StochasticDiffEq = "789caeaf-c7a9-5a7d-9973-96adeb23e2a0" 50 | Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" 51 | Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" 52 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Build Project [using jupyter-book] 2 | on: [pull_request] 3 | jobs: 4 | build: 5 | if: '! github.event.pull_request.draft' 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: Checkout 9 | uses: actions/checkout@v6 10 | - name: Set up Python 11 | uses: actions/setup-python@v6 12 | with: 13 | python-version: 3.11 14 | - name: Install Python Dependencies 15 | run: | 16 | pip install -r requirements.txt 17 | - name: Install LaTeX dependencies 18 | run: | 19 | sudo apt-get -qq update 20 | sudo apt-get install -y \ 21 | texlive-latex-recommended \ 22 | texlive-latex-extra \ 23 | texlive-fonts-recommended \ 24 | texlive-fonts-extra \ 25 | texlive-xetex \ 26 | latexmk \ 27 | xindy \ 28 | texlive-luatex \ 29 | dvipng \ 30 | ghostscript \ 31 | cm-super 32 | - name: Set up Julia 33 | uses: julia-actions/setup-julia@v2 34 | with: 35 | version: 1.12.3 36 | - name: Install IJulia and Setup Project 37 | shell: bash 38 | run: | 39 | julia -e 'using Pkg; Pkg.add("IJulia");' 40 | julia --project=lectures --threads auto -e 'using Pkg; Pkg.instantiate();' 41 | # Download Jupyter Book Cache 42 | - name: Download "build" folder (cache) 43 | uses: dawidd6/action-download-artifact@v11 44 | with: 45 | workflow: cache.yml 46 | branch: main 47 | name: build-cache 48 | path: _build 49 | # Build Assets (Download Notebooks and PDF via LaTeX) 50 | # - name: Build PDF from LaTeX 51 | # shell: bash -l {0} 52 | # run: | 53 | # jb build lectures --builder pdflatex --path-output ./ -n --keep-going 54 | # mkdir -p _build/html/_pdf 55 | # cp -u _build/latex/*.pdf _build/html/_pdf 56 | - name: Build Download Notebooks (sphinx-tojupyter) 57 | shell: bash -l {0} 58 | run: | 59 | jb build lectures --path-output ./ --builder=custom --custom-builder=jupyter -W --keep-going 60 | mkdir -p _build/html/_notebooks 61 | rsync -r _build/jupyter/ _build/html/_notebooks/ 62 | # Build HTML (Website) 63 | - name: Build HTML 64 | shell: bash -l {0} 65 | run: | 66 | jb build lectures --path-output ./ 67 | - name: Save Build as Artifact 68 | uses: actions/upload-artifact@v6 69 | with: 70 | name: _build 71 | path: _build 72 | - name: Preview Deploy to Netlify 73 | uses: nwtgck/actions-netlify@v3.0.0 74 | with: 75 | publish-dir: '_build/html/' 76 | production-branch: master 77 | github-token: ${{ secrets.GITHUB_TOKEN }} 78 | deploy-message: "Preview Deploy from GitHub Actions" 79 | env: 80 | NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} 81 | NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} 82 | -------------------------------------------------------------------------------- /lectures/troubleshooting.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Julia 8 | language: julia 9 | name: julia-1.12 10 | --- 11 | 12 | (troubleshooting)= 13 | ```{raw} html 14 |
15 | 16 | QuantEcon 17 | 18 |
19 | ``` 20 | 21 | # Troubleshooting 22 | 23 | ```{contents} Contents 24 | :depth: 2 25 | ``` 26 | 27 | This troubleshooting page is to help ensure you software environment is setup correctly 28 | to run this lecture set locally on your machine. 29 | 30 | ## Resetting your Lectures 31 | 32 | Using VS Code, you can easily revert back individual lectures, all of the lectures, or get updated versions of the lecture notes. 33 | 34 | See the lecture on [setting up your environment](reset_notebooks) for more. 35 | 36 | If the `Project.toml` or `Manifest.toml` files are modified, then you may want to redo the [instantiation](install_packages) step to ensure you have the correct versions. 37 | 38 | 39 | (reset_julia)= 40 | ## Fixing Your Local Environment 41 | 42 | If packages are misbehaving, you may want to simply [reset the lectures](reset_notebooks) or at least the `Project.toml` and `Manifest.toml` files from the lecture notes, and then redo the [instantiation](install_packages) step This will fix nearly every problem. 43 | 44 | However, if you are still having issues you could delete the entire `.julia` directory for your users, and then redo the installation of packages as well as `] add IJulia`. It is fast for recent versions of Julia. 45 | 46 | The directory is located in your user directory (e.g. `~/.julia` on MacOS and Linux, and `C:\Users\YOURUSERNAME\.julia` on Windows) or you can find this directory by running `DEPOT_PATH[1]` in a Julia REPL. 47 | 48 | ## Upgrading Julia 49 | 50 | You should be able to upgrade Julia by simply 51 | - Installing the latest release from the [Julia website](https://julialang.org/downloads/). 52 | - Uninstalling your old release (so that the VS Code extension only uses the newest version) 53 | - And, finally, you will need to redo the `] add IJulia` [installation step](intro_repl) to ensure that Jupyter knows how to find the new version. 54 | 55 | ```{warning} 56 | While upgrading Julia will typically work with the notebooks, there may be upgrades where a particular lecture has problems. Make sure that you have [updated your notebooks](reset_notebooks) in case bug fixes were made, and post an issue to the [GitHub source for these lectures](https://github.com/QuantEcon/lecture-julia.myst/issues). 57 | ``` 58 | 59 | ## Reporting an Issue 60 | 61 | One way to give feedback is to raise an issue through our [issue tracker](https://github.com/QuantEcon/lecture-julia.myst/issues). 62 | 63 | Please be as specific as possible. Tell us where the problem is and as much 64 | detail about your local set up as you can provide. 65 | 66 | Another feedback option is to use our [discourse forum](https://discourse.quantecon.org/). 67 | 68 | Finally, you can provide direct feedback to [contact@quantecon.org](mailto:contact@quantecon.org) 69 | 70 | -------------------------------------------------------------------------------- /lectures/_toc.yml: -------------------------------------------------------------------------------- 1 | format: jb-book 2 | root: intro 3 | parts: 4 | - caption: Getting Started with Julia 5 | numbered: true 6 | chapters: 7 | - file: getting_started_julia/getting_started 8 | - file: getting_started_julia/julia_by_example 9 | - file: getting_started_julia/julia_essentials 10 | - file: getting_started_julia/fundamental_types 11 | - file: getting_started_julia/introduction_to_types 12 | - caption: Package Ecosystem 13 | numbered: true 14 | chapters: 15 | - file: more_julia/generic_programming 16 | - file: more_julia/auto_differentiation 17 | - file: more_julia/quadrature_interpolation 18 | - file: more_julia/data_statistical_packages 19 | - file: more_julia/optimization_solver_packages 20 | - caption: Software Engineering 21 | numbered: true 22 | chapters: 23 | - file: software_engineering/tools_editors 24 | - file: software_engineering/version_control 25 | - file: software_engineering/testing 26 | - file: software_engineering/need_for_speed 27 | - caption: Tools and Techniques 28 | numbered: true 29 | chapters: 30 | - file: tools_and_techniques/geom_series 31 | - file: tools_and_techniques/linear_algebra 32 | - file: tools_and_techniques/orth_proj 33 | - file: tools_and_techniques/lln_clt 34 | - file: tools_and_techniques/stationary_densities 35 | - file: tools_and_techniques/numerical_linear_algebra 36 | - file: tools_and_techniques/iterative_methods_sparsity 37 | - file: tools_and_techniques/differentiable_dynamics 38 | - caption: Introduction to Dynamics 39 | numbered: true 40 | chapters: 41 | - file: introduction_dynamics/scalar_dynam 42 | - file: introduction_dynamics/ar1_processes 43 | - file: introduction_dynamics/finite_markov 44 | - file: introduction_dynamics/linear_models 45 | - file: introduction_dynamics/wealth_dynamics 46 | - file: introduction_dynamics/kalman 47 | - file: introduction_dynamics/short_path 48 | - caption: Dynamic Programming 49 | numbered: true 50 | chapters: 51 | - file: dynamic_programming/mccall_model 52 | - file: dynamic_programming/mccall_model_with_separation 53 | - file: dynamic_programming/wald_friedman 54 | - file: dynamic_programming/odu 55 | - file: dynamic_programming/career 56 | - file: dynamic_programming/jv 57 | - file: dynamic_programming/optgrowth 58 | - file: dynamic_programming/coleman_policy_iter 59 | - file: dynamic_programming/egm_policy_iter 60 | - file: dynamic_programming/lqcontrol 61 | - file: dynamic_programming/perm_income 62 | - file: dynamic_programming/perm_income_cons 63 | - file: dynamic_programming/smoothing 64 | - file: dynamic_programming/ifp 65 | - file: dynamic_programming/robustness 66 | - file: dynamic_programming/discrete_dp 67 | - caption: Modeling in Continuous Time 68 | numbered: true 69 | chapters: 70 | - file: continuous_time/seir_model 71 | - file: continuous_time/covid_sde 72 | - caption: Multiple Agent Models 73 | numbered: true 74 | chapters: 75 | - file: multi_agent_models/schelling 76 | - file: multi_agent_models/lake_model 77 | - file: multi_agent_models/rational_expectations 78 | - file: multi_agent_models/markov_perf 79 | - file: multi_agent_models/markov_asset 80 | - file: multi_agent_models/lucas_model 81 | - file: multi_agent_models/harrison_kreps 82 | - file: multi_agent_models/uncertainty_traps 83 | - file: multi_agent_models/aiyagari 84 | - file: multi_agent_models/arellano 85 | - file: multi_agent_models/matsuyama 86 | - caption: Other 87 | numbered: true 88 | chapters: 89 | - file: about_lectures 90 | - file: troubleshooting 91 | - file: zreferences 92 | - file: status 93 | -------------------------------------------------------------------------------- /lectures/_config.yml: -------------------------------------------------------------------------------- 1 | title: Quantitative Economics with Julia 2 | author: Jesse Perla & Thomas J. Sargent & John Stachurski 3 | logo: _static/qe-logo-large.png 4 | description: This website presents a set of lectures on quantitative economic modeling, designed and written by Jesse Perla, Thomas J. Sargent and John Stachurski. The language instruction is Julia. 5 | 6 | execute: 7 | execute_notebooks: "cache" 8 | timeout: 600 9 | 10 | bibtex_bibfiles: 11 | - _static/quant-econ.bib 12 | 13 | html: 14 | baseurl: https://julia.quantecon.org/ 15 | 16 | latex: 17 | latex_documents: 18 | targetname: quantecon-julia.tex 19 | 20 | sphinx: 21 | extra_extensions: [sphinx_multitoc_numbering, sphinxext.rediraffe, sphinx_tojupyter] 22 | config: 23 | nb_mime_priority_overrides: [ 24 | # HTML 25 | ['html', 'application/vnd.jupyter.widget-view+json', 10], 26 | ['html', 'application/javascript', 20], 27 | ['html', 'text/html', 30], 28 | ['html', 'text/latex', 40], 29 | ['html', 'image/svg+xml', 50], 30 | ['html', 'image/png', 60], 31 | ['html', 'image/jpeg', 70], 32 | ['html', 'text/markdown', 80], 33 | ['html', 'text/plain', 90], 34 | # Jupyter Notebooks 35 | ['jupyter', 'application/vnd.jupyter.widget-view+json', 10], 36 | ['jupyter', 'application/javascript', 20], 37 | ['jupyter', 'text/html', 30], 38 | ['jupyter', 'text/latex', 40], 39 | ['jupyter', 'image/svg+xml', 50], 40 | ['jupyter', 'image/png', 60], 41 | ['jupyter', 'image/jpeg', 70], 42 | ['jupyter', 'text/markdown', 80], 43 | ['jupyter', 'text/plain', 90], 44 | # LaTeX 45 | ['latex', 'text/latex', 10], 46 | ['latex', 'application/pdf', 20], 47 | ['latex', 'image/png', 30], 48 | ['latex', 'image/jpeg', 40], 49 | ['latex', 'text/markdown', 50], 50 | ['latex', 'text/plain', 60], 51 | # Link Checker 52 | ['linkcheck', 'text/plain', 10], 53 | ] 54 | highlight_language: julia 55 | html_favicon: _static/lectures-favicon.ico 56 | html_theme: quantecon_book_theme 57 | html_static_path: ['_static'] 58 | html_theme_options: 59 | authors: 60 | - name: Jesse Perla 61 | url: https://www.jesseperla.com 62 | - name: Thomas J. Sargent 63 | url: http://www.tomsargent.com/ 64 | - name: John Stachurski 65 | url: https://johnstachurski.net/ 66 | dark_logo: quantecon-logo-transparent.png 67 | header_organisation_url: https://quantecon.org 68 | header_organisation: QuantEcon 69 | repository_url: https://github.com/quantecon/lecture-julia.myst 70 | repository_branch: main 71 | nb_repository_url: https://github.com/quantecon/lecture-julia.notebooks 72 | nb_branch: main 73 | twitter: quantecon 74 | twitter_logo_url: https://assets.quantecon.org/img/qe-twitter-logo.png 75 | og_logo_url: https://assets.quantecon.org/img/qe-og-logo.png 76 | description: This website presents a set of lectures on quantitative economic modeling, designed and written by Jesse Perla, Thomas J. Sargent and John Stachurski. The language instruction is Julia. 77 | keywords: Julia, QuantEcon, Quantitative Economics, Economics, Sloan, Alfred P. Sloan Foundation, Tom J. Sargent, John Stachurski 78 | analytics: 79 | google_analytics_id: G-3PCWRLGWND 80 | launch_buttons: 81 | colab_url: https://colab.research.google.com 82 | mathjax3_config: 83 | tex: 84 | macros: 85 | "argmax" : "arg\\,max" 86 | "argmin" : "arg\\,min" 87 | mathjax_path: https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js 88 | rediraffe_redirects: 89 | index_toc.md: intro.md 90 | tojupyter_default_lang: julia 91 | tojupyter_lang_synonyms: ['julia-1.12'] 92 | tojupyter_static_file_path: ["source/_static", "_static"] 93 | tojupyter_target_html: true 94 | tojupyter_urlpath: "https://julia.quantecon.org/" 95 | tojupyter_image_urlpath: "https://julia.quantecon.org/_static/" 96 | tojupyter_kernels: 97 | julia: 98 | kernelspec: 99 | display_name: Julia 100 | language: julia 101 | name: julia-1.12 102 | tojupyter_images_markdown: true 103 | -------------------------------------------------------------------------------- /format_myst.jl: -------------------------------------------------------------------------------- 1 | # Utility to run JuliaFormatter.jl on the julia code within myst markdown files 2 | # Written for CLI acccess: for example, call it with 3 | # julia format_myst.jl lectures/getting_started_julia/getting_started.md 4 | 5 | # Test with the following examples: 6 | # format_myst("lectures/getting_started_julia/getting_started.md", "lectures/getting_started_julia/getting_started2.md") 7 | # format_myst!("lectures/getting_started_julia/getting_started.md") 8 | using JuliaFormatter 9 | 10 | # Substrings with unicode don't work very well 11 | substring(str, start, stop) = str[nextind(str, 0, start):nextind(str, 0, stop)] 12 | 13 | # inplace modification 14 | function format_myst!(input_file_path, extra_replacements = false, 15 | ignore_errors = false) 16 | format_myst(input_file_path, input_file_path, extra_replacements, ignore_errors) 17 | end 18 | function format_myst(input_file_path, output_file_path, extra_replacements = false, 19 | ignore_errors = false) 20 | # It has one capturing group which corresponds to the code inside the block 21 | code_block_pattern = r"(```{code-cell} julia\n)([\s\S]*?)(\n```)" 22 | 23 | # Extract config files/etc. Requires a .JuliaFormatter.toml file 24 | config_file = JuliaFormatter.find_config_file(".") 25 | style = pop!(config_file, "style") 26 | config = Dict(Symbol(a) => b for (a, b) in config_file) 27 | 28 | function format_code_block(m) 29 | try 30 | # m is the whole match, including the start and end markers 31 | block_length = length(m) 32 | start_marker = substring(m, 1, 21) # length of ```{code-cell} julia\n 33 | code = String(substring(m, 22, block_length - 4)) 34 | end_marker = substring(m, block_length - 3, block_length) 35 | 36 | # don't transform if it has myst tags 37 | if substring(code, 1, min(length(code), 3)) == "---" 38 | return m 39 | end 40 | 41 | # Use Julia Formatter and the loaded style file 42 | transformed_code = format_text(code, style; config...) 43 | 44 | # Return the new block 45 | return start_marker * transformed_code * end_marker 46 | catch e 47 | println("Failed to format code block:") 48 | print(m) 49 | if ignore_errors 50 | return m # i.e., don't change anything 51 | else 52 | throw(e) 53 | end 54 | end 55 | end 56 | 57 | # Additional replacements are optional. This may be useful when replacing variable names to make it easier to type in ascii 58 | replacements = Dict("α" => "alpha", "β" => "beta", "γ" => "gamma", "≤" => "<=", 59 | "≥" => ">=", "Σ" => "Sigma", "σ" => "sigma","μ"=>"mu","ϕ"=>"phi","ψ"=>"psi","ϵ"=>"epsilon", 60 | "δ"=>"delta","θ" => "theta","ζ"=>"zeta","X̄" => "X_bar","p̄" => "p_bar","x̂" => "x_hat","λ"=>"lambda", 61 | "ρ"=>"rho","u′" => "u_prime" , "f′"=>"f_prime"," ∂u∂c"=>"dudc","Π"=>"Pi","π"=>"pi","ξ"=>"xi","c̄"=>"c_bar", 62 | "w̄"=>"w_bar","Θ" => "Theta", "Ξ" =>"Xi", "Q̃" => "Q_tilde","R̃" => "R_tilde","Ã" => "A_tilde", "B̃" => "B_tilde", 63 | "P̃" => "P_tilde","F̃" => "F_tilde","d̃" => "d_tilde") 64 | 65 | # Replace the code blocks in the content and handle exceptions 66 | try 67 | # Read in the file 68 | file_content = read(input_file_path, String) 69 | 70 | new_content = replace(file_content, 71 | code_block_pattern => format_code_block) 72 | 73 | if extra_replacements # optional 74 | new_content = replace(new_content, replacements...) 75 | end 76 | 77 | open(output_file_path, "w") do f 78 | write(f, new_content) 79 | end 80 | return true 81 | catch e 82 | println("Failed to process the markdown file at $input_file_path") 83 | print(e) 84 | return false 85 | end 86 | end 87 | 88 | if length(ARGS) == 0 89 | println("Please provide a file path to a myst markdown file") 90 | exit(1) 91 | else 92 | use_extra_replacements = length(ARGS) > 1 && ARGS[2] == "true" 93 | print("Replacing file at $(ARGS[1]) with formatted version. Additional replacements = $use_extra_replacements\n") 94 | success = format_myst!(ARGS[1],use_extra_replacements) 95 | success || exit(1) 96 | end -------------------------------------------------------------------------------- /lectures/tools_and_techniques/differentiable_simulation.jl: -------------------------------------------------------------------------------- 1 | using LinearAlgebra, Random, Plots, Test, Enzyme, Statistics 2 | 3 | struct LSS{TA, TC, TG, TH} 4 | A::TA 5 | C::TC 6 | G::TG 7 | H::TH 8 | end 9 | 10 | # state and observation paths are stored column-wise for cache-friendly access 11 | function simulate_lss!(x, y, model::LSS, x_0, w, v) 12 | (; A, C, G, H) = model 13 | N, x_cols = size(x) 14 | M, y_cols = size(y) 15 | T = size(w, 2) 16 | 17 | @assert size(A) == (N, N) 18 | @assert size(C, 1) == N 19 | @assert size(G) == (M, N) 20 | @assert size(H, 1) == M 21 | @assert size(w, 1) == size(C, 2) 22 | @assert size(v, 1) == size(H, 2) 23 | @assert size(v, 2) == T + 1 24 | @assert x_cols == T + 1 25 | @assert y_cols == T + 1 26 | @assert length(x_0) == N 27 | 28 | # Enzyme has challenges with activity analysis on broadcasting assignments 29 | @inbounds for i in 1:N 30 | x[i, 1] = x_0[i] 31 | end 32 | 33 | @inbounds for t in 1:T 34 | @views mul!(x[:, t + 1], A, x[:, t]) 35 | # x_{t+1} = A x_t + C w_{t+1}; (1.0, 1.0) adds C w_{t+1} into the existing A x_t 36 | @views mul!(x[:, t + 1], C, w[:, t], 1.0, 1.0) 37 | 38 | @views mul!(y[:, t], G, x[:, t]) 39 | # y_t = G x_t + H v_t; (1.0, 1.0) accumulates H v_t into the G x_t buffer 40 | @views mul!(y[:, t], H, v[:, t], 1.0, 1.0) 41 | end 42 | 43 | @views mul!(y[:, T + 1], G, x[:, T + 1]) 44 | # y_{T+1} = G x_{T+1} + H v_{T+1} 45 | @views mul!(y[:, T + 1], H, v[:, T + 1], 1.0, 1.0) 46 | 47 | return nothing 48 | end 49 | 50 | function mean_first_observation(x, y, model, x_0, w, v) 51 | simulate_lss!(x, y, model, x_0, w, v) 52 | out = mean(@view y[1, :]) 53 | return out 54 | end 55 | 56 | Random.seed!(1234) 57 | 58 | N = 3 59 | M = 2 60 | K = 2 61 | L = 2 62 | T = 10 63 | 64 | A = [0.8 0.1 0.0 65 | 0.0 0.7 0.1 66 | 0.0 0.0 0.6] 67 | C = 0.1 .* randn(N, K) 68 | G = [1.0 0.0 0.0 69 | 0.0 1.0 0.3] 70 | H = 0.05 .* randn(M, L) 71 | model = LSS(A, C, G, H) 72 | 73 | x_0 = randn(N) 74 | w = randn(K, T) 75 | v = randn(L, T + 1) 76 | 77 | x = zeros(N, T + 1) 78 | y = zeros(M, T + 1) 79 | 80 | simulate_lss!(x, y, model, x_0, w, v) 81 | 82 | # Forward-mode sensitivity of full state/observation paths to w[1] 83 | x_w = zeros(N, T + 1) 84 | y_w = zeros(M, T + 1) 85 | dx_w = Enzyme.make_zero(x_w) 86 | dy_w = Enzyme.make_zero(y_w) 87 | dw = Enzyme.make_zero(w) 88 | dw[1] = one(eltype(w)) 89 | autodiff( 90 | Forward, 91 | simulate_lss!, 92 | Duplicated(x_w, dx_w), 93 | Duplicated(y_w, dy_w), 94 | Const(model), 95 | Const(x_0), 96 | Duplicated(w, dw), 97 | Const(v), 98 | ) 99 | 100 | dw_rev = zero(w) 101 | x_rev = zeros(N, T + 1) 102 | y_rev = zeros(M, T + 1) 103 | dx_rev = Enzyme.make_zero(x_rev) 104 | dy_rev = Enzyme.make_zero(y_rev) 105 | 106 | autodiff( 107 | Reverse, 108 | mean_first_observation, 109 | Duplicated(x_rev, dx_rev), 110 | Duplicated(y_rev, dy_rev), 111 | Const(model), 112 | Const(x_0), 113 | Duplicated(w, dw_rev), 114 | Const(v), 115 | ) 116 | 117 | @test all(isfinite, dw_rev) 118 | 119 | @testset "batch tangents for A" begin 120 | x_batch = zeros(N, T + 1) 121 | y_batch = zeros(M, T + 1) 122 | dxs = (Enzyme.make_zero(x_batch), Enzyme.make_zero(x_batch)) 123 | dys = (Enzyme.make_zero(y_batch), Enzyme.make_zero(y_batch)) 124 | dmodels = (Enzyme.make_zero(model), Enzyme.make_zero(model)) 125 | dmodels[1].A[1] = one(eltype(A)) 126 | dmodels[2].A[2] = one(eltype(A)) 127 | 128 | autodiff( 129 | Forward, 130 | simulate_lss!, 131 | BatchDuplicated(x_batch, dxs), 132 | BatchDuplicated(y_batch, dys), 133 | BatchDuplicated(model, dmodels), 134 | Const(x_0), 135 | Const(w), 136 | Const(v), 137 | ) 138 | 139 | @test maximum(abs, dxs[1]) > 0 140 | @test maximum(abs, dys[1]) > 0 141 | end 142 | 143 | time = 0:T 144 | fig_states = plot( 145 | time, 146 | x', 147 | lw = 2, 148 | xlabel = "t", 149 | ylabel = "state", 150 | label = ["x1", "x2", "x3"], 151 | title = "State Paths", 152 | ) 153 | 154 | fig_observations = plot( 155 | time, 156 | y', 157 | lw = 2, 158 | xlabel = "t", 159 | ylabel = "observation", 160 | label = ["y1", "y2"], 161 | title = "Observation Paths", 162 | ) 163 | 164 | display(fig_states) 165 | display(fig_observations) 166 | -------------------------------------------------------------------------------- /wsl.md: -------------------------------------------------------------------------------- 1 | # WSL Editor Setup 2 | Editing on Windows is not entirely supported due to python/sphinx issues. Instead, on Windows use WSL with VS Code. 3 | 4 | ## Setup WSL and VS Code 5 | 6 | 1. To get "Ubuntu on Windows" and other linux kernels see [instructions](https://docs.microsoft.com/en-us/windows/wsl/install-win10). 7 | 8 | - Fresh install quick path (PowerShell as Administrator): 9 | ``` 10 | wsl --install -d Ubuntu 11 | ``` 12 | - **Note:** When typing your UNIX password during setup, nothing will appear on screen. This is normal — just type and press Enter. 13 | 14 | - If installation fails, ensure required features are enabled (Powershell as administrator): 15 | ``` 16 | dism /online /get-features /format:table | findstr /i "Microsoft-Windows-Subsystem-Linux" 17 | dism /online /get-features /format:table | findstr /i "VirtualMachinePlatform" 18 | ``` 19 | - If either is Disabled, enable and reboot: 20 | 21 | ``` 22 | dism /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart 23 | dism /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart 24 | 25 | ``` 26 | 27 | 2. Install [VSCode](https://code.visualstudio.com/) with remote WSL support on windows 28 | - See [VS Code Remote Editing](https://code.visualstudio.com/docs/remote/remote-overview) 29 | - [VS Code Remote WSL](https://code.visualstudio.com/docs/remote/wsl#_opening-a-terminal-in-wsl) 30 | 3. Clone this repository using VS Code on Windows 31 | 4. After you open it, choose `> WSL: Reopen in WSL Window` from the command palette (Ctrl+Shift+P) if you have setup WSL/etc. properly 32 | - If you are successful, the bottom left corner of VS Code will show `>< WSL:Ubuntu>` 33 | - Now any terminals you run should be the linux ubuntu terminals 34 | 35 | 5. Assuming you have `git` installed and setup properly on windows, to get git credentials integrated, in a windows terminal (i.e. not in WSL) run 36 | ``` 37 | git config --global credential.helper wincred 38 | ``` 39 | - Then in a WSL terminal (within VS Code or otherwise), 40 | ``` 41 | git config --global user.email "you@example.com" 42 | git config --global user.name "Your Name" 43 | git config --global credential.helper "/mnt/c/Program\ Files/Git/mingw64/libexec/git-core/git-credential-wincred.exe" 44 | ``` 45 | - (See more details in [Sharing Credentials](https://code.visualstudio.com/docs/remote/troubleshooting#_sharing-git-credentials-between-windows-and-wsl) ) 46 | 47 | 48 | ## Setup Linux Packages/etc. 49 | 50 | 1. Start within your home directory in linux or in a WSL terminal 51 | 52 | 2. In a WSL terminal, Go to your home directory and make sure key dependencies are installed 53 | ```bash 54 | cd ~ 55 | sudo apt update 56 | sudo apt-get upgrade 57 | sudo apt install make gcc unzip 58 | sudo apt-get update 59 | sudo apt install -y libxt6 libxrender1 libgl1 libgl1-mesa-dri libqt5widgets5 60 | ``` 61 | 3. Install conda with the updated version of 62 | ``` 63 | wget https://repo.anaconda.com/archive/Anaconda3-2024.06-1-Linux-x86_64.sh 64 | bash Anaconda3-2024.06-1-Linux-x86_64.sh 65 | ``` 66 | - accept default paths 67 | - accept licensing terms 68 | - *IMPORTANT* Manually choose `yes` to have it do the `conda init` 69 | 4. Install julia with [juliaup](https://github.com/JuliaLang/juliaup?tab=readme-ov-file#mac-linux-and-freebsd) 70 | ```bash 71 | curl -fsSL https://install.julialang.org | sh 72 | ``` 73 | 5. Install key VSCode extensions (which are a separate set of installations for WSL vs. Windows) 74 | - Search for `python, julia, MyST-Markdown, Jupyter` and if you have support `GitHub Copilot, GitHub Copilot Chat` 75 | - Usually requires restart VS Code 76 | 6. In a terminal, create a virtual environment for conda and install packages 77 | ```bash 78 | conda create -n lecture-julia.myst python=3.11 79 | conda activate lecture-julia.myst 80 | pip install -r requirements.txt 81 | ``` 82 | 7. Can try `> Python: Select Interpreter` and choose the `lecture-julia.myst` environment to make it automatic, but it does not always work. 83 | 8. Start a WSL terminal, make sure that the `lecture-julia.myst` is activated (and use `conda activate lecture-julia.myst` if not) then 84 | - Start `julia`, which be in your global environment with nothing installed. Can check with `]st` 85 | - Then install the Julia jupyter kernel with `] add IJulia` 86 | 9. Install the Julia packages required for the lecture notes, running in a terminal (assuming still at the root) 87 | ```bash 88 | julia --project=lectures --threads auto -e 'using Pkg; Pkg.instantiate();' 89 | ``` 90 | - This should take 10-15 minutes the first time. 91 | 92 | At this point, you should be ready to follow the instructions in the main [README.md](./README.md) 93 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Build & Publish to GH pages 2 | on: 3 | push: 4 | tags: 5 | - 'publish*' 6 | jobs: 7 | publish: 8 | if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') 9 | runs-on: ubuntu-latest 10 | steps: 11 | - name: Checkout 12 | uses: actions/checkout@v6 13 | - name: Set up Python 14 | uses: actions/setup-python@v6 15 | with: 16 | python-version: 3.11 17 | - name: Install Python Dependencies 18 | run: | 19 | pip install -r requirements.txt 20 | - name: Install LaTeX dependencies 21 | run: | 22 | sudo apt-get -qq update 23 | sudo apt-get install -y \ 24 | texlive-latex-recommended \ 25 | texlive-latex-extra \ 26 | texlive-fonts-recommended \ 27 | texlive-fonts-extra \ 28 | texlive-xetex \ 29 | latexmk \ 30 | xindy \ 31 | texlive-luatex \ 32 | dvipng \ 33 | ghostscript \ 34 | cm-super 35 | - name: Set up Julia 36 | uses: julia-actions/setup-julia@v2 37 | with: 38 | version: 1.12.3 39 | - name: Install IJulia and Setup Project 40 | shell: bash 41 | run: | 42 | julia -e 'using Pkg; Pkg.add("IJulia");' 43 | julia --project=lectures --threads auto -e 'using Pkg; Pkg.instantiate();' 44 | # Download Jupyter Book Cache 45 | - name: Download "build" folder (cache) 46 | uses: dawidd6/action-download-artifact@v11 47 | with: 48 | workflow: cache.yml 49 | branch: main 50 | name: build-cache 51 | path: _build 52 | # Build Assets (Download Notebooks and PDF via LaTeX) 53 | # - name: Build PDF from LaTeX 54 | # shell: bash -l {0} 55 | # run: | 56 | # jb build lectures --builder pdflatex --path-output ./ -n --keep-going 57 | # mkdir -p _build/html/_pdf 58 | # cp -u _build/latex/*.pdf _build/html/_pdf 59 | - name: Build Download Notebooks (sphinx-tojupyter) 60 | shell: bash -l {0} 61 | run: | 62 | jb build lectures --path-output ./ --builder=custom --custom-builder=jupyter 63 | zip -r download-notebooks.zip _build/jupyter 64 | - uses: actions/upload-artifact@v6 65 | with: 66 | name: download-notebooks 67 | path: download-notebooks.zip 68 | - name: Copy Download Notebooks for GH-PAGES 69 | shell: bash -l {0} 70 | run: | 71 | mkdir -p _build/html/_notebooks 72 | rsync -r _build/jupyter/ _build/html/_notebooks/ 73 | # Build Website 74 | - name: Build HTML 75 | shell: bash -l {0} 76 | run: | 77 | jb build lectures --path-output ./ 78 | # Create HTML archive for release assets 79 | - name: Create HTML archive 80 | shell: bash -l {0} 81 | run: | 82 | tar -czf lecture-julia-html-${{ github.ref_name }}.tar.gz -C _build/html . 83 | sha256sum lecture-julia-html-${{ github.ref_name }}.tar.gz > html-checksum.txt 84 | 85 | # Create metadata manifest 86 | cat > html-manifest.json << EOF 87 | { 88 | "tag": "${{ github.ref_name }}", 89 | "commit": "${{ github.sha }}", 90 | "timestamp": "$(date -Iseconds)", 91 | "size_mb": $(du -sm _build/html | cut -f1), 92 | "file_count": $(find _build/html -type f | wc -l) 93 | } 94 | EOF 95 | - name: Upload archives to release 96 | uses: softprops/action-gh-release@v2 97 | with: 98 | files: | 99 | lecture-julia-html-${{ github.ref_name }}.tar.gz 100 | html-checksum.txt 101 | html-manifest.json 102 | env: 103 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 104 | - name: Deploy website to gh-pages 105 | uses: peaceiris/actions-gh-pages@v4 106 | with: 107 | github_token: ${{ secrets.GITHUB_TOKEN }} 108 | publish_dir: _build/html/ 109 | cname: julia.quantecon.org 110 | - name: Upload "_build" folder (cache) 111 | uses: actions/upload-artifact@v6 112 | with: 113 | name: build-publish 114 | path: _build 115 | # Sync Download Notebooks 116 | - name: Prepare lecture-julia.notebooks sync 117 | shell: bash 118 | run: | 119 | mkdir -p _build/lecture-julia.notebooks 120 | cp -a _notebook_repo/. _build/lecture-julia.notebooks 121 | cp -a _build/jupyter/. _build/lecture-julia.notebooks 122 | rm -rf _build/lecture-julia.notebooks/_static 123 | rm -rf _build/lecture-julia.notebooks/_panels_static 124 | cp lectures/Project.toml _build/lecture-julia.notebooks 125 | cp lectures/Manifest.toml _build/lecture-julia.notebooks 126 | ls -a _build/lecture-julia.notebooks 127 | - name: Commit notebooks to lecture-julia.notebooks 128 | shell: bash -l {0} 129 | env: 130 | QE_SERVICES_PAT: ${{ secrets.QUANTECON_SERVICES_PAT }} 131 | run: | 132 | git clone https://quantecon-services:$QE_SERVICES_PAT@github.com/quantecon/lecture-julia.notebooks 133 | cp -r _build/lecture-julia.notebooks/. lecture-julia.notebooks 134 | cd lecture-julia.notebooks 135 | git config user.name "QuantEcon Services" 136 | git config user.email "admin@quantecon.org" 137 | git add --all 138 | git commit -m "auto publishing updates to notebooks" 139 | git push origin main 140 | -------------------------------------------------------------------------------- /.github/copilot-instructions.md: -------------------------------------------------------------------------------- 1 | # Project Instructions for AI Coding Tools 2 | 3 | This repository builds the QuantEcon Julia lectures using JupyterBook + MyST Markdown + MyST-NB execution. 4 | AI coding tools working in this repo should follow these guidelines for consistent formatting, structure, and execution. 5 | 6 | ------------------------------------------------------------------------------ 7 | 8 | ## 1. Code Style and Formatting Conventions 9 | 10 | Follow the QuantEcon `style.md` guide strictly: 11 | 12 | - Use the conventions described in: 13 | https://github.com/QuantEcon/lecture-julia.myst/blob/main/style.md 14 | - Maintain consistent Julia formatting, including: 15 | - Non-mutating vs. mutating naming (`f` vs. `f!`) 16 | - Explicit `using` statements 17 | - Avoid global variables in notebooks 18 | - Reproducibility via fixed seeds 19 | - When editing MyST Markdown: 20 | - Use fenced code blocks with correct language identifiers 21 | - Do not mix Markdown and code execution in ambiguous ways 22 | - Preserve section structure, callouts, and MyST directives 23 | - Never use `begin` blocks for function definitions. Use either short-form or standard `function ... end` syntax. 24 | - Don't use `&&` when a conditional would be clearer. Prefer `if phi > remaining; continue;end` to `phi > remaining && continue` 25 | 26 | If unsure about style, imitate existing notebooks in `lectures/`. 27 | 28 | ------------------------------------------------------------------------------ 29 | 30 | ## 2. Repository Structure Expectations 31 | 32 | Maintain the existing layout: 33 | 34 | lectures/ 35 | topic_1/ 36 | notebook_1.md 37 | notebook_2.md 38 | topic_2/ 39 | notebook_3.md 40 | intro.md 41 | Manifest.toml 42 | Project.toml 43 | _config.yml 44 | _toc.yml 45 | style.md 46 | requirements.txt 47 | 48 | 49 | The requirements.txt file is for the jupyterbook dependencies, not the lecture notes themselves. 50 | Do not introduce new directory structures without explicit instruction. 51 | 52 | ------------------------------------------------------------------------------ 53 | 54 | ## 3. Environment Setup for Notebook Execution 55 | 56 | AI tools may compile or test notebooks using the following: 57 | 58 | 1. Activate the Python environment: 59 | 60 | source .venv/bin/activate 61 | 62 | 2. Build the JupyterBook: 63 | 64 | jb build lectures 65 | 66 | 3. Inspect failures: 67 | The JupyterBook warnings will include file paths like: 68 | 69 | /path/to/notebook.md: WARNING: Executing notebook failed 70 | Reports saved in: 71 | lectures/_build/html/reports//.err.log 72 | 73 | AI suggestions should reference these logs when debugging notebook execution. 74 | 75 | To run Julia directly with the correct environment: 76 | 77 | ``` 78 | julia --project=lectures 79 | ``` 80 | 81 | Do not manually add in importing code for packages in a lecture (i.e., `import Pkg; Pkg.activate(joinpath(@__DIR__, ".."))` etc.) as it will be correctly activated by either jupyterbook or your activation of the julia environment with `julia --project=lectures`. 82 | 83 | ------------------------------------------------------------------------------ 84 | 85 | ## 4. Expectations for Notebook Editing 86 | 87 | ### Julia Code Cells 88 | - Produce idiomatic, stable, predictable Julia. 89 | - Avoid unnecessary refactoring. 90 | - Use broadcasting, comprehensions, and vectorization when appropriate. 91 | - Prioritize clarity and reproducibility. 92 | 93 | ### MyST Notebook Cells 94 | - Preserve mystnb execution blocks. 95 | - Preserve input/output tags (e.g., hide-output, remove-input). 96 | - Maintain anchors, index directives, labels, and roles. 97 | - Do not introduce unsupported Jupyter features. 98 | 99 | ------------------------------------------------------------------------------ 100 | 101 | ## 5. Documentation and Text Edits 102 | 103 | AI-generated text must: 104 | - Keep the pedagogical tone of existing QuantEcon lectures. 105 | - Use clean mathematical notation: 106 | - Inline math: $x_t = \\rho x_{t-1} + \\sigma \\varepsilon_t$ 107 | - Display math: $$ ... $$ 108 | - Prefer concise explanations and avoid verbosity. 109 | 110 | ------------------------------------------------------------------------------ 111 | 112 | ## 6. Commit Behavior 113 | 114 | AI tools should: 115 | - Keep commits small and targeted. 116 | - Avoid mass rewrites. 117 | - Maintain full compatibility with the JupyterBook build. 118 | 119 | ------------------------------------------------------------------------------ 120 | 121 | ## 7. Good Default Behaviors for AI Tools 122 | 123 | When uncertain: 124 | - Follow patterns already present in similar notebooks. 125 | - Test execution with `jb build lectures`. 126 | - Refer to the style guide. 127 | - Prefer conservative, minimally invasive edits. 128 | - Prioritize correctness of executed notebooks. 129 | 130 | ------------------------------------------------------------------------------ 131 | 132 | ## 8. Allowed Tasks 133 | 134 | AI tools may: 135 | - Fix failing notebook cells. 136 | - Improve explanations, math, and MyST structure. 137 | - Propose small utility Julia functions. 138 | - Improve clarity or reproducibility. 139 | 140 | ------------------------------------------------------------------------------ 141 | 142 | ## 9. Tasks to Avoid 143 | 144 | AI tools should not: 145 | - Change folder structure. 146 | - Modify `_config.yml` unless asked. 147 | - Convert markdown notebooks back to `.ipynb`. 148 | - Reorder large sections or rewrite whole lectures. 149 | - Add new dependencies without explicit instruction. 150 | 151 | ------------------------------------------------------------------------------ 152 | 153 | ## 10. Reference Materials 154 | 155 | - Style guide: 156 | https://github.com/QuantEcon/lecture-julia.myst/blob/main/style.md 157 | 158 | - MyST-NB docs: 159 | https://myst-nb.readthedocs.io/ 160 | 161 | - QuantEcon Julia documentation. 162 | 163 | ------------------------------------------------------------------------------ 164 | 165 | These instructions apply to all AI coding assistants operating in this repository. -------------------------------------------------------------------------------- /AGENTS.md: -------------------------------------------------------------------------------- 1 | # Project Instructions for AI Coding Tools 2 | 3 | This repository builds the QuantEcon Julia lectures using JupyterBook + MyST Markdown + MyST-NB execution. 4 | AI coding tools working in this repo should follow these guidelines for consistent formatting, structure, and execution. 5 | 6 | ------------------------------------------------------------------------------ 7 | 8 | ## 1. Code Style and Formatting Conventions 9 | 10 | Follow the QuantEcon `style.md` guide strictly: 11 | 12 | - Use the conventions described in: 13 | https://github.com/QuantEcon/lecture-julia.myst/blob/main/style.md 14 | - Maintain consistent Julia formatting, including: 15 | - Non-mutating vs. mutating naming (`f` vs. `f!`) 16 | - Explicit `using` statements 17 | - Avoid global variables in notebooks 18 | - Reproducibility via fixed seeds 19 | - When editing MyST Markdown: 20 | - Use fenced code blocks with correct language identifiers 21 | - Do not mix Markdown and code execution in ambiguous ways 22 | - Preserve section structure, callouts, and MyST directives 23 | - Never use `begin` blocks for function definitions. Use either short-form or standard `function ... end` syntax. 24 | - Don't use `&&` when a conditional would be clearer. Prefer `if phi > remaining; continue;end` to `phi > remaining && continue` 25 | 26 | If unsure about style, imitate existing notebooks in `lectures/`. 27 | 28 | ------------------------------------------------------------------------------ 29 | 30 | ## 2. Repository Structure Expectations 31 | 32 | Maintain the existing layout: 33 | 34 | lectures/ 35 | topic_1/ 36 | notebook_1.md 37 | notebook_2.md 38 | topic_2/ 39 | notebook_3.md 40 | intro.md 41 | Manifest.toml 42 | Project.toml 43 | _config.yml 44 | _toc.yml 45 | style.md 46 | requirements.txt 47 | 48 | 49 | The requirements.txt file is for the jupyterbook dependencies, not the lecture notes themselves. 50 | Do not introduce new directory structures without explicit instruction. 51 | 52 | ------------------------------------------------------------------------------ 53 | 54 | ## 3. Environment Setup for Notebook Execution 55 | 56 | AI tools may compile or test notebooks using the following: 57 | 58 | 1. Activate the Python environment: 59 | 60 | source .venv/bin/activate 61 | 62 | 2. Build the JupyterBook: 63 | 64 | jb build lectures 65 | 66 | 3. Inspect failures: 67 | The JupyterBook warnings will include file paths like: 68 | 69 | /path/to/notebook.md: WARNING: Executing notebook failed 70 | Reports saved in: 71 | lectures/_build/html/reports//.err.log 72 | 73 | AI suggestions should reference these logs when debugging notebook execution. 74 | 75 | To run Julia directly with the correct environment: 76 | 77 | ``` 78 | julia --project=lectures 79 | ``` 80 | 81 | Do not manually add in importing code for packages in a lecture (i.e., `import Pkg; Pkg.activate(joinpath(@__DIR__, ".."))` etc.) as it will be correctly activated by either jupyterbook or your activation of the julia environment with `julia --project=lectures`. 82 | 83 | ------------------------------------------------------------------------------ 84 | 85 | ## 4. Expectations for Notebook Editing 86 | 87 | ### Julia Code Cells 88 | - Produce idiomatic, stable, predictable Julia. 89 | - Avoid unnecessary refactoring. 90 | - Use broadcasting, comprehensions, and vectorization when appropriate. 91 | - Prioritize clarity and reproducibility. 92 | 93 | ### MyST Notebook Cells 94 | - Preserve mystnb execution blocks. 95 | - Preserve input/output tags (e.g., hide-output, remove-input). 96 | - Maintain anchors, index directives, labels, and roles. 97 | - Do not introduce unsupported Jupyter features. 98 | 99 | ------------------------------------------------------------------------------ 100 | 101 | ## 5. Documentation and Text Edits 102 | 103 | AI-generated text must: 104 | - Keep the pedagogical tone of existing QuantEcon lectures. 105 | - Use clean mathematical notation: 106 | - Inline math: $x_t = \\rho x_{t-1} + \\sigma \\varepsilon_t$ 107 | - Display math: $$ ... $$ 108 | - Prefer concise explanations and avoid verbosity. 109 | 110 | ------------------------------------------------------------------------------ 111 | 112 | ## 6. Commit Behavior 113 | 114 | AI tools should: 115 | - Keep commits small and targeted. 116 | - Avoid mass rewrites. 117 | - Maintain full compatibility with the JupyterBook build. 118 | 119 | ------------------------------------------------------------------------------ 120 | 121 | ## 7. Good Default Behaviors for AI Tools 122 | 123 | When uncertain: 124 | - Follow patterns already present in similar notebooks. 125 | - Test execution with `jb build lectures`. 126 | - Activate with `.venv` first if it exists. 127 | - Refer to the style guide. 128 | - Prefer conservative, minimally invasive edits. 129 | - Prioritize correctness of executed notebooks. 130 | 131 | ------------------------------------------------------------------------------ 132 | 133 | ## 8. Allowed Tasks 134 | 135 | AI tools may: 136 | - Fix failing notebook cells. 137 | - Improve explanations, math, and MyST structure. 138 | - Propose small utility Julia functions. 139 | - Improve clarity or reproducibility. 140 | 141 | ------------------------------------------------------------------------------ 142 | 143 | ## 9. Tasks to Avoid 144 | 145 | AI tools should not: 146 | - Change folder structure. 147 | - Modify `_config.yml` unless asked. 148 | - Convert markdown notebooks back to `.ipynb`. 149 | - Reorder large sections or rewrite whole lectures. 150 | - Add new dependencies without explicit instruction. 151 | 152 | ------------------------------------------------------------------------------ 153 | 154 | ## 10. Reference Materials 155 | 156 | - Style guide: 157 | https://github.com/QuantEcon/lecture-julia.myst/blob/main/style.md 158 | 159 | - MyST-NB docs: 160 | https://myst-nb.readthedocs.io/ 161 | 162 | - QuantEcon Julia documentation. 163 | 164 | ------------------------------------------------------------------------------ 165 | 166 | These instructions apply to all AI coding assistants operating in this repository. -------------------------------------------------------------------------------- /lectures/more_julia/data_statistical_packages.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Julia 8 | language: julia 9 | name: julia-1.12 10 | --- 11 | 12 | (data_statistical_packages)= 13 | ```{raw} html 14 |
15 | 16 | QuantEcon 17 | 18 |
19 | ``` 20 | 21 | # General, Data, and Statistics Packages 22 | 23 | ```{contents} Contents 24 | :depth: 2 25 | ``` 26 | 27 | ## Overview 28 | 29 | This lecture explores some of the key packages for working with data and doing statistics in Julia. 30 | 31 | In particular, we will examine the `DataFrame` object in detail (i.e., construction, manipulation, querying, visualization, and nuances like missing data). 32 | 33 | While Julia is not an ideal language for pure cookie-cutter statistical analysis, it has many useful packages to provide those tools as part of a more general solution. 34 | 35 | This list is not exhaustive, and others can be found in organizations such as [JuliaStats](https://github.com/JuliaStats), [JuliaData](https://github.com/JuliaData/), and [QueryVerse](https://github.com/queryverse). 36 | 37 | 38 | ```{code-cell} julia 39 | --- 40 | tags: [hide-output] 41 | --- 42 | using LinearAlgebra, Statistics, DataFrames 43 | ``` 44 | 45 | ## DataFrames 46 | 47 | A useful package for working with data is [DataFrames.jl](https://github.com/JuliaStats/DataFrames.jl). 48 | 49 | The most important data type provided is a `DataFrame`, a two dimensional array for storing heterogeneous data. 50 | 51 | Although data can be heterogeneous within a `DataFrame`, the contents of the columns must be homogeneous 52 | (of the same type). 53 | 54 | This is analogous to a `data.frame` in R, a `DataFrame` in Pandas (Python) or, more loosely, a spreadsheet in Excel. 55 | 56 | There are a few different ways to create a DataFrame. 57 | 58 | ### Constructing and Accessing a DataFrame 59 | 60 | The first is to set up columns and construct a dataframe by assigning names 61 | 62 | ```{code-cell} julia 63 | using DataFrames 64 | 65 | # note use of missing 66 | commodities = ["crude", "gas", "gold", "silver"] 67 | last_price = [4.2, 11.3, 12.1, missing] 68 | df = DataFrame(commod = commodities, price = last_price) 69 | ``` 70 | 71 | Columns of the `DataFrame` can be accessed by name using `df.col`, as below 72 | 73 | ```{code-cell} julia 74 | df.price 75 | ``` 76 | 77 | Note that the type of this array has values `Union{Missing, Float64}` since it was created with a `missing` value. 78 | 79 | ```{code-cell} julia 80 | df.commod 81 | ``` 82 | 83 | The `DataFrames.jl` package provides a number of methods for acting on `DataFrame`'s, such as `describe`. 84 | 85 | ```{code-cell} julia 86 | DataFrames.describe(df) 87 | ``` 88 | 89 | While often data will be generated all at once, or read from a file, you can add to a `DataFrame` by providing the key parameters. 90 | 91 | ```{code-cell} julia 92 | nt = (commod = "nickel", price = 5.1) 93 | push!(df, nt) 94 | ``` 95 | 96 | Named tuples can also be used to construct a `DataFrame`, and have it properly deduce all types. 97 | 98 | ```{code-cell} julia 99 | nt = (t = 1, col1 = 3.0) 100 | df2 = DataFrame([nt]) 101 | push!(df2, (t = 2, col1 = 4.0)) 102 | ``` 103 | 104 | In order to modify a column, access the mutating version by the symbol `df[!, :col]`. 105 | 106 | ```{code-cell} julia 107 | df[!, :price] 108 | ``` 109 | 110 | Which allows modifications, like other mutating `!` functions in julia. 111 | 112 | ```{code-cell} julia 113 | df[!, :price] *= 2.0 # double prices 114 | ``` 115 | 116 | As discussed in the next section, note that the {ref}`fundamental types `, is propagated, i.e. `missing * 2 === missing`. 117 | 118 | ### Working with Missing 119 | 120 | As we discussed in {ref}`fundamental types `, the semantics of `missing` are that mathematical operations will not silently ignore it. 121 | 122 | In order to allow `missing` in a column, you can create/load the `DataFrame` 123 | from a source with `missing`'s, or call `allowmissing!` on a column. 124 | 125 | ```{code-cell} julia 126 | allowmissing!(df2, :col1) # necessary to add in a for col1 127 | push!(df2, (t = 3, col1 = missing)) 128 | push!(df2, (t = 4, col1 = 5.1)) 129 | ``` 130 | 131 | We can see the propagation of `missing` to caller functions, as well as a way to efficiently calculate with non-missing data. 132 | 133 | ```{code-cell} julia 134 | @show mean(df2.col1) 135 | @show mean(skipmissing(df2.col1)) 136 | ``` 137 | 138 | And to replace the `missing` 139 | 140 | ```{code-cell} julia 141 | df2.col1 .= coalesce.(df2.col1, 0.0) # replace all missing with 0.0 142 | ``` 143 | 144 | ### Manipulating and Transforming DataFrames 145 | 146 | One way to do an additional calculation with a `DataFrame` is to use the `@transform` macro from `DataFramesMeta.jl`. 147 | 148 | The following are code only blocks, which would require installation of the packages in a separate environment. 149 | 150 | ```{code-block} julia 151 | using DataFramesMeta 152 | f(x) = x^2 153 | df2 = @transform(df2, :col2=f.(:col1)) 154 | ``` 155 | 156 | ### Categorical Data 157 | 158 | For data that is [categorical](https://juliadata.github.io/DataFrames.jl/stable/man/categorical/) 159 | 160 | ```{code-block} julia 161 | using CategoricalArrays 162 | id = [1, 2, 3, 4] 163 | y = ["old", "young", "young", "old"] 164 | y = CategoricalArray(y) 165 | df = DataFrame(id = id, y = y) 166 | ``` 167 | 168 | ```{code-block} julia 169 | levels(df.y) 170 | ``` 171 | 172 | ### Visualization, Querying, and Plots 173 | 174 | The `DataFrame` (and similar types that fulfill a standard generic interface) can fit into a variety of packages. 175 | 176 | One set of them is the [QueryVerse](https://github.com/queryverse). 177 | 178 | **Note:** The QueryVerse, in the same spirit as R's tidyverse, makes heavy use of the pipeline syntax `|>`. 179 | 180 | ## Statistics and Econometrics 181 | 182 | While Julia is not intended as a replacement for R, Stata, and similar specialty languages, it has a growing number of packages aimed at statistics and econometrics. 183 | 184 | Many of the packages live in the [JuliaStats organization](https://github.com/JuliaStats/). 185 | 186 | A few to point out 187 | 188 | * [StatsBase](https://github.com/JuliaStats/StatsBase.jl) has basic statistical functions such as geometric and harmonic means, auto-correlations, robust statistics, etc. 189 | * [StatsFuns](https://github.com/JuliaStats/StatsFuns.jl) has a variety of mathematical functions and constants such as pdf and cdf of many distributions, softmax, etc. 190 | 191 | ### General Linear Models 192 | 193 | To run linear regressions and similar statistics, use the [GLM](http://juliastats.github.io/GLM.jl/latest/) package. 194 | 195 | ```{code-block} julia 196 | using GLM 197 | 198 | x = randn(100) 199 | y = 0.9 .* x + 0.5 * rand(100) 200 | df = DataFrame(x = x, y = y) 201 | ols = lm(@formula(y~x), df) # R-style notation 202 | ``` 203 | 204 | To display the results in a useful tables for LaTeX and the REPL, use 205 | [RegressionTables](https://github.com/jmboehm/RegressionTables.jl/) for output 206 | similar to the Stata package esttab and the R package stargazer. 207 | 208 | ```{code-block} julia 209 | using RegressionTables 210 | regtable(ols) 211 | # regtable(ols, renderSettings = latexOutput()) # for LaTex output 212 | ``` -------------------------------------------------------------------------------- /lectures/multi_agent_models/schelling.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Julia 8 | language: julia 9 | name: julia-1.12 10 | --- 11 | (schelling)= 12 | ```{raw} html 13 |
14 | 15 | QuantEcon 16 | 17 |
18 | ``` 19 | 20 | # Schelling's Segregation Model 21 | 22 | ```{index} single: Schelling Segregation Model 23 | ``` 24 | 25 | ```{index} single: Models; Schelling's Segregation Model 26 | ``` 27 | 28 | ```{contents} Contents 29 | :depth: 2 30 | ``` 31 | 32 | ## Overview 33 | 34 | In 1969, Thomas C. Schelling developed a simple but striking model of racial segregation {cite}`Schelling1969`. 35 | 36 | His model studies the dynamics of racially mixed neighborhoods. 37 | 38 | Like much of Schelling's work, the model shows how local interactions can lead to surprising aggregate structure. 39 | 40 | In particular, it shows that relatively mild preference for neighbors of similar race can lead in aggregate to the collapse of mixed neighborhoods, and high levels of segregation. 41 | 42 | In recognition of this and other research, Schelling was awarded the 2005 Nobel Prize in Economic Sciences (joint with Robert Aumann). 43 | 44 | In this lecture we (in fact you) will build and run a version of Schelling's model. 45 | 46 | ## The Model 47 | 48 | We will cover a variation of Schelling's model that is easy to program and captures the main idea. 49 | 50 | Suppose we have two types of people: orange people and green people. 51 | 52 | For the purpose of this lecture, we will assume there are 250 of each type. 53 | 54 | These agents all live on a single unit square. 55 | 56 | The location of an agent is just a point $(x, y)$, where $0 < x, y < 1$. 57 | 58 | ### Preferences 59 | 60 | We will say that an agent is *happy* if half or more of her 10 nearest neighbors are of the same type. 61 | 62 | Here 'nearest' is in terms of [Euclidean distance](https://en.wikipedia.org/wiki/Euclidean_distance). 63 | 64 | An agent who is not happy is called *unhappy*. 65 | 66 | An important point here is that agents are not averse to living in mixed areas. 67 | 68 | They are perfectly happy if half their neighbors are of the other color. 69 | 70 | ### Behavior 71 | 72 | Initially, agents are mixed together (integrated). 73 | 74 | In particular, the initial location of each agent is an independent draw from a bivariate uniform distribution on $S = (0, 1)^2$. 75 | 76 | Now, cycling through the set of all agents, each agent is now given the chance to stay or move. 77 | 78 | We assume that each agent will stay put if they are happy and move if unhappy. 79 | 80 | The algorithm for moving is as follows 81 | 82 | 1. Draw a random location in $S$ 83 | 1. If happy at new location, move there 84 | 1. Else, go to step 1 85 | 86 | In this way, we cycle continuously through the agents, moving as required. 87 | 88 | We continue to cycle until no one wishes to move. 89 | 90 | ## Results 91 | 92 | Let's have a look at the results we got when we coded and ran this model. 93 | 94 | As discussed above, agents are initially mixed randomly together 95 | 96 | ```{figure} /_static/figures/schelling_fig1.png 97 | 98 | ``` 99 | 100 | But after several cycles they become segregated into distinct regions 101 | 102 | ```{figure} /_static/figures/schelling_fig2.png 103 | 104 | ``` 105 | 106 | ```{figure} /_static/figures/schelling_fig3.png 107 | 108 | ``` 109 | 110 | ```{figure} /_static/figures/schelling_fig4.png 111 | 112 | ``` 113 | 114 | In this instance, the program terminated after 4 cycles through the set of 115 | agents, indicating that all agents had reached a state of happiness. 116 | 117 | What is striking about the pictures is how rapidly racial integration breaks down. 118 | 119 | This is despite the fact that people in the model don't actually mind living mixed with the other type. 120 | 121 | Even with these preferences, the outcome is a high degree of segregation. 122 | 123 | ## Exercises 124 | 125 | (schelling_ex1)= 126 | ### Exercise 1 127 | 128 | Implement and run this simulation for yourself. 129 | 130 | Use 250 agents of each type. 131 | 132 | ## Solutions 133 | 134 | ### Exercise 1 135 | 136 | Here's one solution that does the job we want. If you feel like a 137 | further exercise you can probably speed up some of the computations and 138 | then increase the number of agents. 139 | 140 | 141 | 142 | ```{code-cell} julia 143 | --- 144 | tags: [remove-cell] 145 | --- 146 | using Test, Random 147 | ``` 148 | 149 | ```{code-cell} julia 150 | using Plots, LinearAlgebra, Statistics 151 | 152 | ``` 153 | 154 | ```{code-cell} julia 155 | --- 156 | tags: [remove-cell] 157 | --- 158 | Random.seed!(42); 159 | ``` 160 | 161 | ```{code-cell} julia 162 | Agent(; kind, location = rand(2)) = (; kind, location) 163 | 164 | draw_location!(a) = a.location .= rand(2) 165 | 166 | # distance is just 2 norm: uses our subtraction function 167 | get_distance(a, agent) = norm(a.location - agent.location) 168 | 169 | function is_happy(a) 170 | distances = [(get_distance(a, agent), agent) for agent in agents] 171 | sort!(distances) 172 | neighbors = [agent for (d, agent) in distances[1:neighborhood_size]] 173 | share = mean(isequal(a.kind), other.kind for other in neighbors) 174 | 175 | # can also do 176 | # share = mean(isequal(a.kind), 177 | # first(agents[idx]) for idx in 178 | # partialsortperm(get_distance.(Ref(a), agents), 179 | # 1:neighborhood_size)) 180 | 181 | return share >= preference 182 | end 183 | 184 | function update!(a) 185 | # If not happy, then randomly choose new locations until happy. 186 | while !is_happy(a) 187 | draw_location!(a) 188 | end 189 | end 190 | 191 | function plot_distribution(agents) 192 | x_vals_0, y_vals_0 = zeros(0), zeros(0) 193 | x_vals_1, y_vals_1 = zeros(0), zeros(0) 194 | 195 | # obtain locations of each type 196 | for agent in agents 197 | x, y = agent.location 198 | if agent.kind == 0 199 | push!(x_vals_0, x) 200 | push!(y_vals_0, y) 201 | else 202 | push!(x_vals_1, x) 203 | push!(y_vals_1, y) 204 | end 205 | end 206 | 207 | p = scatter(x_vals_0, y_vals_0, color = :orange, markersize = 8, 208 | alpha = 0.6) 209 | scatter!(x_vals_1, y_vals_1, color = :green, markersize = 8, alpha = 0.6) 210 | return plot!(legend = :none) 211 | end 212 | ``` 213 | 214 | ```{code-cell} julia 215 | num_of_type_0 = 250 216 | num_of_type_1 = 250 217 | neighborhood_size = 10 # Number of agents regarded as neighbors 218 | preference = 0.5 # Want their kind to make at least this share of the neighborhood 219 | 220 | # Create a list of agents 221 | agents = vcat([Agent(kind = 0) for i in 1:num_of_type_0], 222 | [Agent(kind = 1) for i in 1:num_of_type_1]) 223 | 224 | plot_array = Any[] 225 | 226 | # loop until none wishes to move 227 | while true 228 | push!(plot_array, plot_distribution(agents)) 229 | no_one_moved = true 230 | for agent in agents 231 | old_location = copy(agent.location) 232 | update!(agent) 233 | if norm(old_location - agent.location) ≉ 0 234 | no_one_moved = false 235 | end 236 | end 237 | if no_one_moved 238 | break 239 | end 240 | end 241 | n = length(plot_array) 242 | plot(plot_array..., 243 | layout = (n, 1), 244 | size = (600, 400n), 245 | title = reshape(["Cycle $i" for i in 1:n], 1, n)) 246 | ``` 247 | 248 | ```{code-cell} julia 249 | --- 250 | tags: [remove-cell] 251 | --- 252 | @test sum(agent.kind for agent in agents) == 250 253 | ``` 254 | 255 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # lecture-julia.myst 2 | 3 | Source for julia.quantecon.org and notebooks in https://github.com/QuantEcon/lecture-julia.notebooks 4 | 5 | To contribute, you can use GitHub's online editor for small changes, and do a full local installation for large ones. 6 | 7 | See https://github.com/QuantEcon/lecture-julia.myst/blob/main/style.md for some basic coding standards. 8 | 9 | ## Online Editor 10 | 11 | On this website hit `.` to enter into the web editor. From this, you can submit suggested patches and fix typos. This will help you create a [pull request](https://quantecon.github.io/lecture-julia.myst/software_engineering/version_control.html#collaboration-via-pull-request) for maintainers here to examine. 12 | 13 | ## Local Development 14 | 15 | It is straightforward to install the Jupyter Book and Julia software necessary for more significant changes. For Windows support, it is best to use WSL. See `[WSL Setup Instructions](./wsl.md)` for more details. 16 | 17 | ### Setup 18 | 19 | 1. [Install Julia, Conda, and VS Code](https://quantecon.github.io/lecture-julia.myst/getting_started_julia/getting_started.html) following the documentation for using these notes. 20 | 2. Modify [VS Code settings](https://quantecon.github.io/lecture-julia.myst/software_engineering/tools_editors.html#optional-extensions-and-settings) and consider [additional extensions](https://quantecon.github.io/lecture-julia.myst/software_engineering/tools_editors.html#optional-extensions). Some others to consider are the [MyST-Markdown](https://github.com/executablebooks/myst-vs-code) and [Spell Checking](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker) extensions. You will also likely want the Python and Jupyter extensions installed 21 | 3. Ensure that [Git](https://quantecon.github.io/lecture-julia.myst/software_engineering/version_control.html#setup) is set up correctly. In particular, this ensures that Windows users use the Linux end-of-line characters. 22 | 4. Clone this repository (in VS Code, you can use `` then `Clone` then `Clone from GitHub` then choose the repo as `https://github.com/QuantEcon/lecture-julia.myst`). 23 | 24 | 6. Open this repository in VS Code. If you cloned in a separate terminal, navigate to the directory and type `code .` 25 | 26 | 7. Start a VS Code terminal with ```` or through any other method. Create a conda environment. 27 | 28 | ```bash 29 | conda create -n lecture-julia.myst python=3.11 30 | conda activate lecture-julia.myst 31 | pip install -r requirements.txt 32 | ``` 33 | 34 | This will install all the Jupyter Book packages required to edit and build the lectures. 35 | 36 | 8. Set the default interpreter for VS Code's Python extension to be the conda environment 37 | - Press `` then `Python: Select Interpreter`. 38 | - Choose the interpreter with `lecture-julia.myst` which should now be automatically activated in the terminal. 39 | - If the interpreter does not show up in the drop-down, close and reopen VS Code, then try again. Alternatively, you can run this step at the end of the setup process. 40 | - Whenever reopening VS Code, re-run `conda activate lecture-julia.myst` to ensure the environment remains active. 41 | 9. Ensure that IJulia is installed for the main Julia environment 42 | - Ensure you have the conda environment activated with `conda activate lecture-julia.myst` 43 | - To do this, run `julia` in the terminal and then `] add IJulia` in the Julia REPL. You will want to do this in the main environment and not the `lectures` environment, as used below. 44 | 10. Install the Julia packages required for the lecture notes. 45 | 46 | ```bash 47 | julia --project=lectures --threads auto -e 'using Pkg; Pkg.instantiate();' 48 | ``` 49 | 50 | 51 | **(Optional) REPL Integration** 52 | With [MyST-Markdown](https://github.com/executablebooks/myst-vs-code) and [Julia](https://marketplace.visualstudio.com/items?itemName=julialang.language-julia) installed, you can ensure that pressing `` on lines of code are sent to a Julia REPL. 53 | 1. Open Key Bindings with ``. 54 | 2. Search for the `Julia: Send Current Line or Selection to REPL` binding. 55 | 3. Right Click on the key binding with `juliamarkdown` on it, and choose `Change When Expression`, and change `juliamarkdown` to just `markdown`. 56 | 57 | 58 | ## Executing Code in Markdown Files 59 | If you installed the REPL Integration above, then in a `.md` file, 60 | 61 | 1. Start a Julia REPL with `> Julia: Start REPL`. 62 | 2. Activate the project file in the REPL with `] activate lectures`. 63 | 3. Then, assuming that you set up the keybindings above, you can send a line of code in the markdown to the REPL with ``. 64 | 65 | Code can be executed line by line, or you can select a chunk of code and execute it. 66 | 67 | ## Executing Intermediate Code in Jupyter Notebooks 68 | From a built jupyterbook, you can navigate to the `.ipynb` used for the generation. The files are located in `lectures/_build/jupyter_execute/dynamic_programming/mccall_model.ipynb` etc. 69 | 70 | There are two options: 71 | 72 | 1. With the Julia vscode extension installed, open the file and run code cells. 73 | - The formatting will be incorrect, but the code will be. 74 | - The first time you run this you may need to choose the kernel. Assuming you installed with juliaup, you should be able to choose `Julia` as the kernel and the juliaup installed julia version 75 | - This will automatically activate the appropriate project and manifest file. 76 | 2. With your conda environment activated, go `cd lectures` then `jupyter lab` 77 | - Navigate to the files in jupyter itself. Because you ran this in the environment with the `Project.toml` and `Manifest.toml` files, the environment should be activated correctly. 78 | - If you have any issues, it is likely that you need to activate the environment in the terminal, or that you have note done the `] add IJulia` step from a julia REPL (whihc must be done in the default environment, i.e. not activated in `lectures`). 79 | 80 | ## Example Operations 81 | ### Building the lectures 82 | To do a full build of the lectures: 83 | 84 | ```bash 85 | jupyter-book build lectures 86 | ``` 87 | 88 | or 89 | 90 | ```bash 91 | jb build lectures 92 | ``` 93 | 94 | This will take a while. But it will populate your cache, so future iteration is faster. 95 | 106 | 107 | ### Cleaning Lectures 108 | To clean up (i.e., delete the build) 109 | 110 | ```bash 111 | jupyter-book clean lectures 112 | ``` 113 | 114 | or 115 | 116 | ```bash 117 | jb clean lectures 118 | ``` 119 | 120 | and to clean the `execution` cache you can use 121 | 122 | ```bash 123 | jb clean lectures --all 124 | ``` 125 | ### Debugging Generated Content 126 | 127 | After execution, you can find the generated `.ipynb` and `.jl` files in `_build/jupyter_execute` for each lecture. 128 | - To see errors, you can open these in JupyterLab, the Jupyter support within VS Code, etc. 129 | - If using the Julia REPL in VS Code, make sure to do `] activate lectures` prior to testing to ensure the packages are activated. This is not necessary when opening in Jupyter. 130 | 131 | ## Formatting code 132 | Julia code blocks in the myst `.md` files can be formatted using a script in this folder. To manually do so, insure you have the `] add JuliaFormatter` within your default julia environment, then call on the commandline like 133 | 134 | ```bash 135 | julia format_myst.jl lectures/getting_started_julia/getting_started.md 136 | ``` 137 | 138 | As a helper, you can call a shell script to do it for an entire folder 139 | 140 | ```bash 141 | bash format_all_directory.sh lectures/dynamic_programming 142 | ``` 143 | 144 | or to also do the unicode substitutions 145 | 146 | ```bash 147 | bash format_all_directory.sh lectures/dynamic_programming true 148 | ``` -------------------------------------------------------------------------------- /prompts/differentiation.md: -------------------------------------------------------------------------------- 1 | # Instructions for Differentiable Code 2 | In general write clean code without worrying about small performance changes. However, in some cases we need to maintain strict control over memory allocations, especially if I mention you should use Enzyme. 3 | 4 | In that case, you are an expert Julia developer specializing in high-performance computing and zero-allocation patterns. When writing code, prioritize strict memory management and in-place operations. Adhere to the following guidelines`: 5 | 6 | Our main target will be Enzyme.jl and occasionally ForwardDiff.jl. 7 | 8 | ## Enzyme.jl Guidelines 9 | - See https://enzymead.github.io/Enzyme.jl/dev/ for enzyme documentation 10 | - In cases when you need to write custom rules, EnzymeTestUtils provides a way to test against FiniteDiff automatically. 11 | - See https://enzymead.github.io/Enzyme.jl/dev/api/#EnzymeTestUtils.test_forward-Tuple%7BAny,%20Any,%20Vararg%7BAny%7D%7D 12 | - https://enzymead.github.io/Enzyme.jl/dev/api/#EnzymeTestUtils.test_reverse-Tuple{Any,%20Any,%20Vararg{Any}} 13 | - You need to write inplace code without allocations. See `Inplace Coding Guidelines` below 14 | - Functions should be written to be type-stable 15 | - You will need to preallocate any buffers and pass as arguments. 16 | 17 | ## Enzyme & Buffer Conventions 18 | When writing the Enzyme Differentiable Julia code, adhere to these SciML/Enzyme patterns: 19 | 20 | 1. **Function Signature:** `function name!(out, inputs..., params, cache)`. Place the `cache` (workspace) argument last. 21 | 2. **Cache Structs:** Do not pass individual arrays for buffers. Create a `struct NameCache` to hold all pre-allocated temporary arrays. 22 | 3. **Enzyme Compatibility:** * Ensure the code is compatible with `Enzyme.autodiff`. 23 | * Assume the user will pass `Duplicated(cache, d_cache)` for the workspace. 24 | * The `cache` struct must contain mutable fields (Arrays) that match the precision of the inputs. 25 | 4. **No Internal Allocation:** Strictly use the fields in `cache` for all intermediate vector/matrix operations. 26 | 5. **Use make_zero**: Use `Enzyme.make_zero(x)` to create shadow copies for gradients of inputs/outputs/cache rather than manual allocation. 27 | 6. **Enzyme Assignment Loops** Sometimes Enzyme hits an Activity Analysis issues with assignment, for example instad of `x[:,1] .= x_0` or equivalent things with view, it needs. In that case you can use manual loop for assignment, but put a comment to explain why 28 | ```julia 29 | # Enzyme has challenges with activity analysis on broadcasting assignments 30 | @inbounds for i in 1:N 31 | x[i, 1] = x_0[i] 32 | end 33 | ``` 34 | 35 | 36 | Follow the coding pattern in this example, for example. 37 | ``` 38 | using Enzyme, LinearAlgebra 39 | 40 | # 1. Define the Cache Struct 41 | struct SimCache{T} 42 | tmp_vec::Vector{T} 43 | tmp_mat::Matrix{T} 44 | end 45 | 46 | # Helper to build it (good for users) 47 | alloc_cache(n) = SimCache(zeros(n), zeros(n, n)) 48 | 49 | # 2. The In-Place Function 50 | # Order: out, x (input), cache (buffers) 51 | function simulate!(out, x, cache::SimCache) 52 | # unpack for clarity 53 | tmp = cache.tmp_vec 54 | 55 | # Example: Intermediate computation that needs a buffer 56 | # If we didn't have cache, this line would allocate 57 | @. tmp = x * x + 2 58 | 59 | # Write to out 60 | @. out = tmp^2 61 | return nothing 62 | end 63 | 64 | # 3. Setup for Enzyme 65 | n = 100 66 | x = rand(n) 67 | out = zeros(n) 68 | cache = alloc_cache(n) 69 | 70 | # Create "Shadows" (gradients) 71 | # Enzyme.make_zero creates a structural copy with all zeros 72 | dx = Enzyme.make_zero(x) 73 | dout = Enzyme.make_zero(out) # "Seed" for the gradient (e.g., set to 1s if scalar) 74 | dcache = Enzyme.make_zero(cache) # The shadow workspace! 75 | 76 | # Initialize the seed (e.g., we want gradient of sum(out)) 77 | dout .= 1.0 78 | 79 | # 4. The Call 80 | # Note: We pass Duplicated for the cache because it is MUTATED. 81 | autodiff(Reverse, simulate!, 82 | Duplicated(out, dout), 83 | Duplicated(x, dx), 84 | Duplicated(cache, dcache) 85 | ) 86 | ``` 87 | 88 | ### Testing to ensure Type Safety and No Allocations 89 | - For any Enzyme-differentiable function, you should add asserts during development to ensure type stability and no allocations. 90 | - With the `Test` package, you can use `@inferred` to check type stability and `@allocated` to check allocations. 91 | 92 | For example: 93 | 94 | ```julia 95 | using Test 96 | 97 | function stable_func(x) 98 | return x * 2.0 99 | end 100 | 101 | function unstable_func(x) 102 | # Returns Int if x > 0, Float64 otherwise (Type Unstable!) 103 | x > 0 ? 1 : 1.0 104 | end 105 | 106 | @testset "Type Stability" begin 107 | x = 1.0 108 | 109 | # PASSES: Compiler infers Float64, actual is Float64 110 | @inferred stable_func(x) 111 | 112 | # FAILS: Compiler infers Union{Float64, Int64}, actual is one of them 113 | # Throws: "return type Union{Float64, Int64} does not match inferred type..." 114 | @inferred unstable_func(x) 115 | end 116 | function compute!(out, x) 117 | # Example: Allocation-free operation 118 | out .= x .* 2 119 | return nothing 120 | end 121 | 122 | @testset "Allocations" begin 123 | out = zeros(10) 124 | x = rand(10) 125 | 126 | # 1. WARMUP: Run once to force compilation 127 | compute!(out, x) 128 | 129 | # 2. ASSERT: Check allocations are exactly 0 130 | # Note: We interpolate arguments ($) inside benchmark tools, 131 | # but strictly speaking @allocated just runs the expression. 132 | allocs = @allocated compute!(out, x) 133 | 134 | @test allocs == 0 135 | end 136 | ``` 137 | 138 | 139 | ### Testing with Finite Differences 140 | In cases where a custom rule is required, or there is a concern that gradients may be incorrect, use EnzymeTestUtils to compare against finite differences. Follow this example, which extends the above code. 141 | 142 | Even if you only care about the gradient of `x`, you **must** mark the `out` and `cache` arguments as `Duplicated` because they are mutated. 143 | 144 | **Example: Testing Reverse Mode** 145 | ```julia 146 | using Enzyme, EnzymeTestUtils, Test 147 | 148 | # 1. Setup Data 149 | x = randn(10) 150 | out = zeros(10) 151 | cache = alloc_cache(10) # User-defined helper to build cache struct 152 | 153 | # 2. Test Gradient of `x` 154 | # We use `test_reverse` to compare AD against Finite Differences. 155 | # Note: `out` and `cache` are mutated, so they MUST be Duplicated. 156 | test_reverse(simulate!, Const, 157 | (out, Duplicated), # Mutated Output 158 | (x, Duplicated), # Input (Active for differentiation) 159 | (cache, Duplicated) # Mutated Workspace 160 | ) 161 | # Test Tangent of `x` 162 | test_forward(simulate!, Const, 163 | (out, Duplicated), 164 | (x, Duplicated), 165 | (cache, Duplicated) 166 | ) 167 | ``` 168 | 169 | # Inplace Coding Guidelines 170 | 171 | In that case, you are an expert Julia developer specializing in high-performance computing and zero-allocation patterns. When writing code, prioritize strict memory management and in-place operations. Adhere to the following guidelines: 172 | 173 | ### 1. Matrix Multiplication (`mul!`) 174 | Avoid `*` for matrix operations when a destination buffer exists. Use `LinearAlgebra.mul!`. 175 | - **Matrix-Matrix:** `mul!(C, A, B)` computes $C = AB$ overwriting $C$. 176 | - **Matrix-Vector:** `mul!(y, A, x)` computes $y = Ax$ overwriting $y$. 177 | - **5-Argument Interface:** Use `mul!(Y, A, B, \alpha, \beta)` to compute $Y = \alpha AB + \beta Y$. This is a "muladd" operation that avoids allocating a temporary buffer for $AB$ before adding it to $Y$. 178 | 179 | ### 2. In-Place Linear Solves (`ldiv!`) 180 | Avoid `\` (backslash) inside hot loops. 181 | - Pre-factorize matrices (e.g., LU, Cholesky) outside the loop: `F = lu(A)` or `F = cholesky(A)`. 182 | - Use `ldiv!(F, b)` to solve $Ax=b$ in-place, overwriting vector `b` with the solution. 183 | - Use `ldiv!(y, F, x)` if you need to keep `x` intact and write the solution to `y`. 184 | 185 | ### 3. Quadratic Forms (`dot`) 186 | Avoid `x' * A * x` or `(x' * A) * y`. These create temporary vector allocations. 187 | - Use the 3-argument dot product: `dot(x, A, y)` computes $x^T A y$ without allocating the intermediate vector $Ay$. 188 | - For quadratic forms $x^T A x$, use `dot(x, A, x)`. 189 | 190 | ### 4. Symmetrization (Kalman Filters/Covariances) 191 | In algorithms like Kalman filtering, numerical errors destroy symmetry. 192 | - **Preferred:** Wrap the matrix in `Symmetric(A)` or `Hermitian(A)` rather than forcing data movement. 193 | - **In-Place Enforcement:** If you must materialize the symmetric matrix (e.g., before a LAPACK call that accesses the full matrix), calculate one triangle and copy it to the other using `LinearAlgebra.copytri!(A, 'U')` (copies Upper to Lower) or `'L'` (Lower to Upper). 194 | - **Averaging:** If you specifically need $A \leftarrow (A + A^T)/2$ to average errors, use an explicit loop or broadcast into a pre-allocated buffer to avoid creating a new matrix. 195 | 196 | ### 5. Array Views 197 | Slicing arrays (`A[1:5, :]`) creates a copy. 198 | - Use macros: `@views A[1:5, :]` creates a `SubArray` view automatically. 199 | - Use function calls: `view(A, :, 1)` for specific programmatic control. 200 | - **Caveat:** Be careful with views in dense linear algebra (BLAS); if the memory stride is non-unit, performance may degrade. However, strictly for avoiding allocation, views are required. 201 | - Organize algorithms around column vs. row access patterns to maximize contiguous memory access when using views. 202 | 203 | ### 6. Transposition 204 | Avoid `B = A'` unless it is a wrapper type without materialization. 205 | - Use `transpose!(B, A)` or `adjoint!(B, A)` to move data into a pre-allocated buffer `B`. 206 | 207 | ### 7. Broadcasting and `map!` 208 | - Use `@.` when possible for clarity 209 | - Use `broadcast!(f, dest, args...)` or the syntactic sugar `dest .= f.(args...)` to fuse operations and write directly to `dest`. 210 | - Use `map!(f, dest, src)` for element-wise mapping. 211 | 212 | ### 8. General "Buffer" Management 213 | - When using Enzyme, use in-place variant `f!(out, x)` if there is a vector to be returned. Put the last argument as mutable buffers where required. 214 | - Pass pre-allocated "workspace" vectors/matrices into functions as arguments rather than creating them inside the function body. 215 | -------------------------------------------------------------------------------- /lectures/about_lectures.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Julia 8 | language: julia 9 | name: julia-1.12 10 | --- 11 | 12 | (about)= 13 | # About these Lectures 14 | 15 | ## Overview 16 | 17 | Programming, mathematics and statistics are powerful tools for analyzing the functioning of economies. 18 | 19 | This lecture series provides a hands-on instruction manual. 20 | 21 | Topics include 22 | 23 | - algorithms and numerical methods for studying economic problems, 24 | - related mathematical and statistical concepts, and 25 | - basics of coding skills and software engineering. 26 | 27 | The intended audience is undergraduate students, graduate students and 28 | researchers in economics, finance and related fields. 29 | 30 | ## Julia 31 | 32 | The coding language for this lecture series is Julia. 33 | 34 | Note that there's also a related set of [Python lectures](https://python.quantecon.org). 35 | 36 | In terms of the differences, 37 | 38 | * Python is a general purpose language featuring a huge user community in the sciences and an outstanding scientific and general ecosystem. 39 | * Julia is a more focused language primarily used in technical and scientific computing, with an outstanding ecosystem for cutting-edge methods and algorithms. 40 | 41 | Both are modern, open source, high productivity languages with all the key features needed for 42 | high performance computing. 43 | 44 | While Julia has many features of a general purpose language, its specialization makes it much closer to 45 | using Matlab or Fortran than using a general purpose language - giving it an advantage in being closer 46 | to both mathematical notation and direct implementation of mathematical abstractions. 47 | 48 | Julia has both a large number of useful, well written libraries and many incomplete poorly maintained proofs of concept. 49 | 50 | A major advantage of Julia libraries is that, because Julia itself is sufficiently fast, there is less need to mix in low level languages like C and Fortran. 51 | 52 | As a result, most Julia libraries are written exclusively in Julia. 53 | 54 | Not only does this make the libraries more portable, it makes them much easier to dive into, read, learn from and modify. 55 | 56 | ### A Word of Caution 57 | 58 | The disadvantage of specialization is that Julia tends to be used by domain experts, and consequently 59 | the ecosystem and language for non-mathematical/non-scientific computing tasks is inferior to Python. 60 | 61 | Another disadvantage is that, since it tends to be used by experts and is on the cutting edge, the tooling is 62 | much more fragile and rudimentary than Matlab. 63 | 64 | Thankfully, with the v1.x release of Julia the fragility no longer applies to the language itself - now stable and 65 | carefully managed for [version compatibility](https://semver.org/). However, casual users should 66 | not expect the development tools to quite as stable, or to be comparable to Matlab. 67 | 68 | Nevertheless, the end-result will always be elegant and grounded in mathematical notation and abstractions. 69 | 70 | ## Advantages of Julia 71 | 72 | Despite the short-term cautions, Julia has both immediate and long-run advantages. 73 | 74 | The advantages of the language itself show clearly in the high quality packages, such as 75 | 76 | - Differential Equations: [DifferentialEquations.jl](http://docs.juliadiffeq.org/latest/) 77 | - Function approximation and manipulation: [ApproxFun.jl](https://github.com/JuliaApproximation/ApproxFun.jl) 78 | - Interval Constraint Programming and rigorous root finding: [IntervalRootFinding.jl](https://github.com/JuliaIntervals/IntervalRootFinding.jl) 79 | - GPUs: [CuArrays.jl](https://github.com/JuliaGPU/CuArrays.jl) 80 | - Linear algebra for large-systems (e.g. structured matrices, matrix-free methods, etc.): [IterativeSolvers.jl](https://juliamath.github.io/IterativeSolvers.jl/dev/), [BlockBandedMatrices.jl](https://github.com/JuliaMatrices/BlockBandedMatrices.jl), [InfiniteLinearAlgebra.jl](https://github.com/JuliaMatrices/InfiniteLinearAlgebra.jl), and many others 81 | - Automatic differentiation: [ForwardDiff.jl](https://github.com/JuliaDiff/ForwardDiff.jl) and [Enzyme.jl](https://github.com/EnzymeAD/Enzyme.jl) 82 | 83 | These are in addition to the many mundane but essential packages available. While there are examples of these packages in other languages, no 84 | other language can achieve the combination of performance, mathematical notation, and composition that Julia provides. 85 | 86 | The composition of packages is especially important, and is made possible through Julia's use of something called [multiple-dispatch](https://en.wikipedia.org/wiki/Multiple_dispatch). 87 | 88 | ## Open Source 89 | 90 | All the computing environments we work with are free and open source. 91 | 92 | This means that you, your coauthors and your students can install them and their libraries on all of your computers without cost or concern about licenses. 93 | 94 | Another advantage of open source libraries is that you can read them and learn 95 | how they work. 96 | 97 | For example, let’s say you want to know exactly how [Distributions.jl](https://github.com/JuliaStats/Distributions.jl) implements mean of the exponential function 98 | 99 | No problem: You can go ahead and [read the code](https://github.com/JuliaStats/Distributions.jl/blob/master/src/univariate/continuous/exponential.jl#L56). 100 | 101 | This goes even further since most of Julia is written in Julia. For example, you could see the code for how the standard library calculates the [eigenvalues of a triangular matrix](https://github.com/JuliaLang/julia/blob/master/stdlib/LinearAlgebra/src/triangular.jl#L2594) or calculates the [mean of a range](https://github.com/JuliaLang/julia/blob/master/stdlib/Statistics/src/Statistics.jl#L162) 102 | 103 | Those two examples also provide examples where the "multiple dispatch" allows exploitation of the structure of a problem, leading to specialized algorithms (e.g. if the user calls `eigvals` on a matrix that happens to be triangular, it just needs to return the diagonal). 104 | 105 | While dipping into external code libraries takes a bit of coding maturity, it’s very useful for 106 | 107 | 1. helping you understand the details of a particular implementation, and 108 | 1. building your programming skills by showing you code written by first rate programmers. 109 | 110 | Also, you can modify the library to suit your needs: if the functionality provided is not exactly what you want, you are free to change it. 111 | 112 | Another, more philosophical advantage of open source software is that it conforms to the [scientific ideal of reproducibility](https://en.wikipedia.org/wiki/Scientific_method). 113 | 114 | ## How about Other Languages? 115 | 116 | But why don't you use language XYZ? 117 | 118 | ### MATLAB 119 | 120 | While MATLAB has many nice features, it's starting to show its age. 121 | 122 | It can no longer match Python or Julia in terms of performance and design. 123 | 124 | MATLAB is also proprietary, which comes with its own set of disadvantages. 125 | 126 | In particular, the Achilles Heel of Matlab is its lack of a package management 127 | system, which means that either you need to (1) rely on Matlab's own packages, which 128 | are mostly written for engineers and not economists; (2) write the code 129 | yourself; or (3) use unreliable and manual ways to share code (e.g. email or downloading a zip). 130 | 131 | If you are a structural engineer or designing a microcontroller, then Matlab provides a coherent set of packages that takes care of all of your needs. 132 | 133 | For economists, on the other hand, the expansion in complexity of numerical methods, the need for researchers to 134 | collaborate on code, fix bugs, deploy improvements, and have dependencies (i.e. packages relying on other packges) has increased past what Matlab can handle. 135 | 136 | Given what’s available now, it’s hard to find any good reasons to invest in MATLAB. 137 | 138 | Incidentally, if you decide to jump from MATLAB to Julia, [this cheat-sheet](http://cheatsheets.quantecon.org/) will be useful. 139 | 140 | ### R 141 | 142 | [R](https://cran.r-project.org/) is a very useful open source statistical environment and programming language 143 | 144 | Its primary strength is its [vast collection](https://cran.r-project.org/web/packages) of extension packages 145 | 146 | Julia is more general purpose than R and hence a better fit for this course 147 | 148 | ### C / C++ / Fortran? 149 | 150 | Isn’t Fortran / C / C++ faster than Julia? In which case it must be better, right? 151 | 152 | For the same algorithms, as a compiled language Julia can often achieve a similar level of performance to those languages. 153 | 154 | But even when it doesn't, keep in mind that the correct objective function to minimize: total time = development time + execution time 155 | 156 | In assessing this trade off, it’s necessary to bear in mind that 157 | 158 | - Your time is a far more valuable resource than the computer’s time. 159 | - Languages like Julia are much faster to write and debug in. 160 | - In any one program, the vast majority of CPU time will be spent iterating over just a few lines of your code. 161 | 162 | The other issue with all three languages, as with Matlab, is the lack of a package management system. Collaborating on C++ or Fortran packages and distributing code between researchers is difficult, and many 163 | of the criticisms of matlab equally apply. 164 | 165 | Finally, the first-order question of performance is which algorithm you are using, and whether it exploits the structure of the problem. The right algorithm in Matlab or Python is typically faster than the wrong 166 | algorithm in Fortran - and the right algorithm in Fortran and Julia can be made roughly comparable. 167 | 168 | When considering the performance advantages, remember that the design and package system of Julia make it easy to try out algorithms that exploit structure of the problem. We will investigate this more in {ref}`Introductory Examples ` 169 | 170 | #### Last Word 171 | 172 | Writing your entire program in Fortran / C / C++ is best thought of as “premature optimization” 173 | 174 | On this topic we quote the godfather: 175 | 176 | [](https://en.wikipedia.org/wiki/Donald_Knuth)> We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. – Donald Knuth 177 | 178 | But, to put the final part of the quote 179 | 180 | [](https://en.wikipedia.org/wiki/Donald_Knuth)> ... Yet we should not pass up our opportunities in that critical 3%. – Donald Knuth 181 | 182 | Julia is an excellent language to attain those last few percent, without having to resort to C or Fortran code and mix languages in your project 183 | 184 | ## Credits 185 | 186 | These lectures have benefited greatly from comments and suggestions from our 187 | colleagues, students and friends. Special thanks are due to our sponsoring 188 | organization the Alfred P. Sloan Foundation and our research assistants Chase 189 | Coleman, Spencer Lyon and Matthew McKay for innumerable contributions to the 190 | code library and functioning of the website. 191 | 192 | We also thank [Andrij Stachurski](http://drdrij.com/) for his great web 193 | skills, and the many others who have contributed suggestions, bug fixes or 194 | improvements. They include but are not limited to Anmol Bhandari, Long Bui, 195 | Jeong-Hun Choi, David Evans, Xiaojun Guan, Shunsuke Hori, Chenghan Hou, Doc-Jin Jang, Adam Jozefiak, 196 | Qingyin Ma, Akira Matsushita, Tomohito Okabe, Daisuke Oyama, David Pugh, Alex 197 | Olssen, Nathan Palmer, Pooya Rashidi Ravari, Arnav Sood, Bill Tubbs, Dawie van Lill, Natasha Watkins, Pablo Winant, Kaan Yolsever, James Yu, and Yixiao 198 | Zhou. 199 | 200 | -------------------------------------------------------------------------------- /lectures/multi_agent_models/aiyagari.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Julia 8 | language: julia 9 | name: julia-1.12 10 | --- 11 | 12 | (aiyagari)= 13 | ```{raw} html 14 |
15 | 16 | QuantEcon 17 | 18 |
19 | ``` 20 | 21 | # The Aiyagari Model 22 | 23 | ```{contents} Contents 24 | :depth: 2 25 | ``` 26 | 27 | ## Overview 28 | 29 | In this lecture we describe the structure of a class of models that build on work by Truman Bewley {cite}`Bewley1977`. 30 | 31 | ```{only} html 32 | We begin by discussing an example of a Bewley model due to Rao Aiyagari. 33 | ``` 34 | 35 | ```{only} latex 36 | We begin by discussing an example of a Bewley model due to [Rao Aiyagari](https://lectures.quantecon.org/_downloads/aiyagari_obit.pdf). 37 | ``` 38 | 39 | The model features 40 | 41 | * Heterogeneous agents. 42 | * A single exogenous vehicle for borrowing and lending. 43 | * Limits on amounts individual agents may borrow. 44 | 45 | The Aiyagari model has been used to investigate many topics, including 46 | 47 | * precautionary savings and the effect of liquidity constraints {cite}`Aiyagari1994` 48 | * risk sharing and asset pricing {cite}`Heaton1996` 49 | * the shape of the wealth distribution {cite}`benhabib2015` 50 | * etc., etc., etc. 51 | 52 | ### References 53 | 54 | The primary reference for this lecture is {cite}`Aiyagari1994`. 55 | 56 | A textbook treatment is available in chapter 18 of {cite}`Ljungqvist2012`. 57 | 58 | A continuous time version of the model by SeHyoun Ahn and Benjamin Moll can be found [here](http://nbviewer.jupyter.org/github/QuantEcon/QuantEcon.notebooks/blob/master/aiyagari_continuous_time.ipynb). 59 | 60 | ## The Economy 61 | 62 | ### Households 63 | 64 | Infinitely lived households / consumers face idiosyncratic income shocks. 65 | 66 | A unit interval of *ex ante* identical households face a common borrowing constraint. 67 | 68 | The savings problem faced by a typical household is 69 | 70 | $$ 71 | \max \mathbb E \sum_{t=0}^{\infty} \beta^t u(c_t) 72 | $$ 73 | 74 | subject to 75 | 76 | $$ 77 | a_{t+1} + c_t \leq w z_t + (1 + r) a_t 78 | \quad 79 | c_t \geq 0, 80 | \quad \text{and} \quad 81 | a_t \geq -B 82 | $$ 83 | 84 | where 85 | 86 | * $c_t$ is current consumption 87 | * $a_t$ is assets 88 | * $z_t$ is an exogenous component of labor income capturing stochastic unemployment risk, etc. 89 | * $w$ is a wage rate 90 | * $r$ is a net interest rate 91 | * $B$ is the maximum amount that the agent is allowed to borrow 92 | 93 | The exogenous process $\{z_t\}$ follows a finite state Markov chain with given stochastic matrix $P$. 94 | 95 | The wage and interest rate are fixed over time. 96 | 97 | In this simple version of the model, households supply labor inelastically because they do not value leisure. 98 | 99 | ## Firms 100 | 101 | Firms produce output by hiring capital and labor. 102 | 103 | Firms act competitively and face constant returns to scale. 104 | 105 | Since returns to scale are constant the number of firms does not matter. 106 | 107 | Hence we can consider a single (but nonetheless competitive) representative firm. 108 | 109 | The firm's output is 110 | 111 | $$ 112 | Y_t = A K_t^{\alpha} N^{1 - \alpha} 113 | $$ 114 | 115 | where 116 | 117 | * $A$ and $\alpha$ are parameters with $A > 0$ and $\alpha \in (0, 1)$ 118 | * $K_t$ is aggregate capital 119 | * $N$ is total labor supply (which is constant in this simple version of the model) 120 | 121 | The firm's problem is 122 | 123 | $$ 124 | max_{K, N} \left\{ A K_t^{\alpha} N^{1 - \alpha} - (r + \delta) K - w N \right\} 125 | $$ 126 | 127 | The parameter $\delta$ is the depreciation rate. 128 | 129 | From the first-order condition with respect to capital, the firm's inverse demand for capital is 130 | 131 | ```{math} 132 | :label: aiy_rgk 133 | 134 | r = A \alpha \left( \frac{N}{K} \right)^{1 - \alpha} - \delta 135 | ``` 136 | 137 | Using this expression and the firm's first-order condition for labor, we can pin down 138 | the equilibrium wage rate as a function of $r$ as 139 | 140 | ```{math} 141 | :label: aiy_wgr 142 | 143 | w(r) = A (1 - \alpha) (A \alpha / (r + \delta))^{\alpha / (1 - \alpha)} 144 | ``` 145 | 146 | ### Equilibrium 147 | 148 | We construct a *stationary rational expectations equilibrium* (SREE). 149 | 150 | In such an equilibrium 151 | 152 | * prices induce behavior that generates aggregate quantities consistent with the prices 153 | * aggregate quantities and prices are constant over time 154 | 155 | In more detail, an SREE lists a set of prices, savings and production policies such that 156 | 157 | * households want to choose the specified savings policies taking the prices as given 158 | * firms maximize profits taking the same prices as given 159 | * the resulting aggregate quantities are consistent with the prices; in particular, the demand for capital equals the supply 160 | * aggregate quantities (defined as cross-sectional averages) are constant 161 | 162 | In practice, once parameter values are set, we can check for an SREE by the following steps 163 | 164 | 1. pick a proposed quantity $K$ for aggregate capital 165 | 1. determine corresponding prices, with interest rate $r$ determined by {eq}`aiy_rgk` and a wage rate $w(r)$ as given in {eq}`aiy_wgr` 166 | 1. determine the common optimal savings policy of the households given these prices 167 | 1. compute aggregate capital as the mean of steady state capital given this savings policy 168 | 169 | If this final quantity agrees with $K$ then we have a SREE. 170 | 171 | ## Code 172 | 173 | Let's look at how we might compute such an equilibrium in practice. 174 | 175 | To solve the household's dynamic programming problem we'll use the [DiscreteDP](https://github.com/QuantEcon/QuantEcon.jl/blob/master/src/markov/ddp.jl) type from [QuantEcon.jl](http://quantecon.org/quantecon-jl). 176 | 177 | Our first task is the least exciting one: write code that maps parameters for a household problem into the `R` and `Q` matrices needed to generate an instance of `DiscreteDP`. 178 | 179 | Below is a piece of boilerplate code that does just this. 180 | 181 | In reading the code, the following information will be helpful 182 | 183 | * `R` needs to be a matrix where `R[s, a]` is the reward at state `s` under action `a`. 184 | * `Q` needs to be a three dimensional array where `Q[s, a, s']` is the probability of transitioning to state `s'` when the current state is `s` and the current action is `a`. 185 | 186 | (For a detailed discussion of `DiscreteDP` see {doc}`this lecture <../dynamic_programming/discrete_dp>`) 187 | 188 | Here we take the state to be $s_t := (a_t, z_t)$, where $a_t$ is assets and $z_t$ is the shock. 189 | 190 | The action is the choice of next period asset level $a_{t+1}$. 191 | 192 | The object also includes a default set of parameters that we'll adopt unless otherwise specified. 193 | 194 | 195 | 196 | ```{code-cell} julia 197 | using LinearAlgebra, Statistics 198 | using LaTeXStrings, Plots, QuantEcon 199 | ``` 200 | 201 | ```{code-cell} julia 202 | --- 203 | tags: [remove-cell] 204 | --- 205 | using Test, Random 206 | ``` 207 | 208 | ```{code-cell} julia 209 | function Household(; r = 0.01, 210 | w = 1.0, 211 | sigma = 1.0, 212 | beta = 0.96, 213 | z_chain = MarkovChain([0.9 0.1; 0.1 0.9], [0.1; 1.0]), 214 | a_min = 1e-10, 215 | a_max = 18.0, 216 | a_size = 200, 217 | a_vals = range(a_min, a_max, length = a_size), 218 | # -Inf is the utility of dying (0 consumption) 219 | u = sigma == 1 ? x -> log(x) : 220 | x -> (x^(1 - sigma) - 1) / (1 - sigma)) 221 | 222 | # Create grids 223 | z_size = length(z_chain.state_values) 224 | n = a_size * z_size 225 | s_vals = gridmake(a_vals, z_chain.state_values) 226 | s_i_vals = gridmake(1:a_size, 1:z_size) 227 | 228 | # Fill in the Q and R 229 | Q = zeros(n, a_size, n) 230 | for next_s_i in 1:size(Q, 3) 231 | for a_i in 1:size(Q, 2) 232 | for s_i in 1:size(Q, 1) 233 | z_i = s_i_vals[s_i, 2] 234 | next_z_i = s_i_vals[next_s_i, 2] 235 | next_a_i = s_i_vals[next_s_i, 1] 236 | if next_a_i == a_i 237 | Q[s_i, a_i, next_s_i] = z_chain.p[z_i, next_z_i] 238 | end 239 | end 240 | end 241 | end 242 | 243 | R = fill(-Inf, n, a_size) 244 | for new_a_i in 1:size(R, 2) 245 | a_new = a_vals[new_a_i] 246 | for s_i in 1:size(R, 1) 247 | a = s_vals[s_i, 1] 248 | z = s_vals[s_i, 2] 249 | c = w * z + (1 + r) * a - a_new 250 | if c > 0 251 | R[s_i, new_a_i] = u(c) 252 | end 253 | end 254 | end 255 | return (; r, w, sigma, beta, z_chain, a_min, a_max, a_size, a_vals, z_size, 256 | n, s_vals, s_i_vals, u, R, Q) 257 | end 258 | ``` 259 | 260 | As a first example of what we can do, let's compute and plot an optimal accumulation policy at fixed prices 261 | 262 | ```{code-cell} julia 263 | --- 264 | tags: [remove-cell] 265 | --- 266 | Random.seed!(42); 267 | ``` 268 | 269 | ```{code-cell} julia 270 | # Create an instance of Household 271 | am = Household(; a_max = 20.0, r = 0.03, w = 0.956) 272 | 273 | # Use the instance to build a discrete dynamic program 274 | am_ddp = DiscreteDP(am.R, am.Q, am.beta) 275 | 276 | # Solve using policy function iteration 277 | results = solve(am_ddp, PFI) 278 | 279 | # Simplify names 280 | (; z_size, a_size, n, a_vals) = am 281 | z_vals = am.z_chain.state_values 282 | 283 | # Get all optimal actions across the set of 284 | # a indices with z fixed in each column 285 | a_star = reshape([a_vals[results.sigma[s_i]] for s_i in 1:n], a_size, z_size) 286 | 287 | labels = [L"z = %$(z_vals[1])" L"z = %$(z_vals[2])"] 288 | plot(a_vals, a_star, label = labels, lw = 2, alpha = 0.6) 289 | plot!(a_vals, a_vals, label = "", color = :black, linestyle = :dash) 290 | plot!(xlabel = "current assets", ylabel = "next period assets", grid = false) 291 | ``` 292 | 293 | ```{code-cell} julia 294 | --- 295 | tags: [remove-cell] 296 | --- 297 | @testset begin 298 | @test a_vals[4] ≈ 0.3015075377869347 299 | @test a_star[4] ≈ 0.2010050252246231 300 | @test results.v[4] ≈ -27.48291672016239 301 | @test z_vals ≈ [0.1, 1.0] 302 | end 303 | ``` 304 | 305 | The plot shows asset accumulation policies at different values of the exogenous state. 306 | 307 | Now we want to calculate the equilibrium. 308 | 309 | Let's do this visually as a first pass. 310 | 311 | The following code draws aggregate supply and demand curves. 312 | 313 | The intersection gives equilibrium interest rates and capital 314 | 315 | ```{code-cell} julia 316 | --- 317 | tags: [remove-cell] 318 | --- 319 | Random.seed!(42); 320 | ``` 321 | 322 | ```{code-cell} julia 323 | 324 | # Calculate supply of capital for a given r 325 | function prices_to_capital_stock(r; beta, A, N, alpha, delta, a_max) 326 | # Create an instance of Household given the parameters 327 | 328 | # Calculate the equilibrium wages 329 | w = A * (1 - alpha) * (A * alpha / (r + delta))^(alpha / (1 - alpha)) 330 | am = Household(; beta, a_max, w, r) 331 | 332 | aiyagari_ddp = DiscreteDP(am.R, am.Q, am.beta) 333 | 334 | # Compute the optimal policy 335 | results = solve(aiyagari_ddp, PFI) 336 | 337 | # Compute the stationary distribution 338 | stationary_probs = stationary_distributions(results.mc)[:, 1][1] 339 | 340 | # Return K 341 | K = dot(am.s_vals[:, 1], stationary_probs) 342 | 343 | # Return capital 344 | return K 345 | end 346 | 347 | # Inverse Demand for capital 348 | function r_inverse_demand(K; A, N, alpha, delta) 349 | return A * alpha * (N / K)^(1 - alpha) - delta 350 | end 351 | 352 | # Create a grid of r values at which to compute demand and supply of capital 353 | r_vals = range(0.005, 0.04, length = 20) 354 | 355 | # Firms' parameters 356 | A = 1 357 | N = 1 358 | alpha = 0.33 359 | beta = 0.96 360 | delta = 0.05 361 | a_max = 20.0 362 | 363 | prices_to_capital_stock(r_vals[1]; A, N, alpha, beta, delta, a_max) 364 | 365 | # Compute supply of capital 366 | k_vals = prices_to_capital_stock.(r_vals; A, N, alpha, beta, delta, a_max) 367 | 368 | r_inverse_demand_vals = r_inverse_demand.(k_vals; A, N, alpha, delta) 369 | 370 | # Plot against demand for capital by firms 371 | labels = ["demand for capital" "supply of capital"] 372 | plot(k_vals, [r_inverse_demand_vals r_vals], label = labels, lw = 2, 373 | alpha = 0.6) 374 | plot!(xlabel = "capital", ylabel = "interest rate", xlim = (2, 14), 375 | ylim = (0.0, 0.1)) 376 | ``` -------------------------------------------------------------------------------- /lectures/introduction_dynamics/scalar_dynam.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Julia 8 | language: julia 9 | name: julia-1.12 10 | --- 11 | 12 | (scalar_dynam)= 13 | ```{raw} html 14 |
15 | 16 | QuantEcon 17 | 18 |
19 | ``` 20 | 21 | # {index}`Dynamics in One Dimension ` 22 | 23 | ```{contents} Contents 24 | :depth: 2 25 | ``` 26 | 27 | ## Overview 28 | 29 | In this lecture we give a quick introduction to discrete time dynamics in one 30 | dimension. 31 | 32 | In one-dimensional models, the state of the system is described by a single variable. 33 | 34 | Although most interesting dynamic models have two or more state variables, the 35 | one-dimensional setting is a good place to learn the foundations of dynamics and build 36 | intuition. 37 | 38 | We'll use the following packages: 39 | 40 | ```{code-cell} julia 41 | using LaTeXStrings, LinearAlgebra, Plots 42 | ``` 43 | 44 | ## Some Definitions 45 | 46 | This section sets out the objects of interest and the kinds of properties we study. 47 | 48 | ### Difference Equations 49 | 50 | A **time homogeneous first order difference equation** is an equation of the 51 | form 52 | 53 | ```{math} 54 | :label: sdsod 55 | 56 | x_{t+1} = g(x_t) 57 | ``` 58 | 59 | where $g$ is a function from some subset $S$ of $\mathbb R$ to itself. 60 | 61 | Here $S$ is called the **state space** and $x$ is called the **state variable**. 62 | 63 | In the definition, 64 | 65 | * time homogeneity means that $g$ is the same at each time $t$ 66 | * first order means dependence on only one lag (i.e., earlier states such as $x_{t-1}$ do not enter into {eq}`sdsod`). 67 | 68 | If $x_0 \in S$ is given, then {eq}`sdsod` recursively defines the sequence 69 | 70 | ```{math} 71 | :label: sdstraj 72 | 73 | x_0, \quad 74 | x_1 = g(x_0), \quad 75 | x_2 = g(x_1) = g(g(x_0)), \quad \text{etc.} 76 | ``` 77 | 78 | This sequence is called the **trajectory** of $x_0$ under $g$. 79 | 80 | If we define $g^n$ to be $n$ compositions of $g$ with itself, then we can write the trajectory more simply as $x_t = g^t(x_0)$ for $t \geq 0$. 81 | 82 | ### Example: A Linear Model 83 | 84 | One simple example is the **linear difference equation** 85 | 86 | $$ 87 | x_{t+1} = a x_t + b, \qquad S = \mathbb R 88 | $$ 89 | 90 | where $a, b$ are fixed constants. 91 | 92 | In this case, given $x_0$, the trajectory {eq}`sdstraj` is 93 | 94 | ```{math} 95 | :label: sdslinmodpath 96 | 97 | x_0, \quad 98 | a x_0 + b, \quad 99 | a^2 x_0 + a b + b, \quad \text{etc.} 100 | ``` 101 | 102 | Continuing in this way, and using our knowledge of {doc}`geometric series <../tools_and_techniques/geom_series>`, we find that, for any $t \geq 0$, 103 | 104 | ```{math} 105 | :label: sdslinmod 106 | 107 | x_t = a^t x_0 + b \frac{1 - a^t}{1 - a} 108 | ``` 109 | 110 | This is about all we need to know about the linear model. 111 | 112 | We have an exact expression for $x_t$ for all $t$ and hence a full 113 | understanding of the dynamics. 114 | 115 | Notice in particular that $|a| < 1$, then, by {eq}`sdslinmod`, we have 116 | 117 | ```{math} 118 | :label: sdslinmodc 119 | 120 | x_t \to \frac{b}{1 - a} \text{ as } t \to \infty 121 | ``` 122 | 123 | regardless of $x_0$ 124 | 125 | This is an example of what is called global stability, a topic we return to 126 | below. 127 | 128 | ### Example: A Nonlinear Model 129 | 130 | In the linear example above, we obtained an exact analytical expression for $x_t$ 131 | in terms of arbitrary $t$ and $x_0$. 132 | 133 | This made analysis of dynamics very easy. 134 | 135 | When models are nonlinear, however, the situation can be quite different. 136 | 137 | For example, consider the law of motion for the Solow growth model, a simplified version of which is 138 | 139 | ```{math} 140 | :label: solow_lom2 141 | 142 | k_{t+1} = s z k_t^{\alpha} + (1 - \delta) k_t 143 | ``` 144 | 145 | Here $k$ is capital stock and $s, z, \alpha, \delta$ are positive 146 | parameters with $0 < \alpha, \delta < 1$. 147 | 148 | If you try to iterate like we did in {eq}`sdslinmodpath`, you will find that 149 | the algebra gets messy quickly. 150 | 151 | Analyzing the dynamics of this model requires a different method (see below). 152 | 153 | ### Stability 154 | 155 | A **steady state** of the difference equation $x_{t+1} = g(x_t)$ is a 156 | point $x^*$ in $S$ such that $x^* = g(x^*)$. 157 | 158 | In other words, $x^*$ is a **fixed point** of the function $g$ in 159 | $S$. 160 | 161 | For example, for the linear model $x_{t+1} = a x_t + b$, you can use the 162 | definition to check that 163 | 164 | * $x^* := b/(1-a)$ is a steady state whenever $a \not= 1$. 165 | * if $a = 1$ and $b=0$, then every $x \in \mathbb R$ is a 166 | steady state. 167 | * if $a = 1$ and $b \not= 0$, then the linear model has no steady 168 | state in $\mathbb R$. 169 | 170 | A steady state $x^*$ of $x_{t+1} = g(x_t)$ is called 171 | **globally stable** if, for all $x_0 \in S$, 172 | 173 | $$ 174 | x_t = g^t(x_0) \to x^* \text{ as } t \to \infty 175 | $$ 176 | 177 | For example, in the linear model $x_{t+1} = a x_t + b$ with $a 178 | \not= 1$, the steady state $x^*$ 179 | 180 | * is globally stable if $|a| < 1$ and 181 | * fails to be globally stable otherwise. 182 | 183 | This follows directly from {eq}`sdslinmod`. 184 | 185 | A steady state $x^*$ of $x_{t+1} = g(x_t)$ is called 186 | **locally stable** if there exists an $\epsilon > 0$ such that 187 | 188 | $$ 189 | | x_0 - x^* | < \epsilon 190 | \; \implies \; 191 | x_t = g^t(x_0) \to x^* \text{ as } t \to \infty 192 | $$ 193 | 194 | Obviously every globally stable steady state is also locally stable. 195 | 196 | We will see examples below where the converse is not true. 197 | 198 | ## Graphical Analysis 199 | 200 | As we saw above, analyzing the dynamics for nonlinear models is nontrivial. 201 | 202 | There is no single way to tackle all nonlinear models. 203 | 204 | However, there is one technique for one-dimensional models that provides a 205 | great deal of intuition. 206 | 207 | This is a graphical approach based on **45 degree diagrams**. 208 | 209 | Let's look at an example: the Solow model with dynamics given in {eq}`solow_lom2`. 210 | 211 | We begin with some plotting code that you can ignore at first reading. 212 | 213 | The function of the code is to produce 45 degree diagrams and time series 214 | plots. 215 | 216 | ```{code-cell} julia 217 | # Iterates a function from an initial condition 218 | function iterate_map(f, x0, T) 219 | x = zeros(T + 1) 220 | x[1] = x0 221 | for t in 2:(T + 1) 222 | x[t] = f(x[t - 1]) 223 | end 224 | return x 225 | end 226 | 227 | function plot45(f, xmin, xmax, x0, T; num_points = 100, label = L"g(k)", 228 | xlabel = "k") 229 | # Plot the function and the 45 degree line 230 | x_grid = range(xmin, xmax, num_points) 231 | plt = plot(x_grid, f.(x_grid); xlim = (xmin, xmax), ylim = (xmin, xmax), 232 | linecolor = :black, lw = 2, label) 233 | plot!(x_grid, x_grid; linecolor = :blue, lw = 2, label = nothing) 234 | 235 | # Iterate map and add ticks 236 | x = iterate_map(f, x0, T) 237 | xticks!(x, [L"%$(xlabel)_{%$i}" for i in 0:T]) 238 | yticks!(x, [L"%$(xlabel)_{%$i}" for i in 0:T]) 239 | 240 | # Plot arrows and dashes 241 | for i in 1:T 242 | plot!([x[i], x[i]], [x[i], x[i + 1]], arrow = :closed, linecolor = :black, 243 | alpha = 0.5, label = nothing) 244 | plot!([x[i], x[i + 1]], [x[i + 1], x[i + 1]], arrow = :closed, 245 | linecolor = :black, alpha = 0.5, label = nothing) 246 | plot!([x[i + 1], x[i + 1]], [0, x[i + 1]], linestyle = :dash, 247 | linecolor = :black, alpha = 0.5, label = nothing) 248 | end 249 | plot!([x[1], x[1]], [0, x[1]], linestyle = :dash, linecolor = :black, 250 | alpha = 0.5, label = nothing) 251 | end 252 | 253 | function ts_plot(f, x0, T; xlabel = L"t", label = L"k_t") 254 | x = iterate_map(f, x0, T) 255 | plot(0:T, x; xlabel, label) 256 | plot!(0:T, x; seriestype = :scatter, mc = :blue, alpha = 0.7, label = nothing) 257 | end 258 | ``` 259 | 260 | Let's create a 45 degree diagram for the Solow model with a fixed set of 261 | parameters 262 | 263 | ```{code-cell} julia 264 | p = (A = 2, s = 0.3, alpha = 0.3, delta = 0.4, xmin = 0, xmax = 4) 265 | ``` 266 | 267 | Here's the update function corresponding to the model. 268 | 269 | ```{code-cell} julia 270 | g(k; p) = p.A * p.s * k^p.alpha + (1 - p.delta) * k 271 | ``` 272 | 273 | Here is the 45 degree plot. 274 | 275 | ```{code-cell} julia 276 | plot45(k -> g(k; p), p.xmin, p.xmax, 0, 6) 277 | ``` 278 | 279 | The plot shows the function $g$ and the 45 degree line. 280 | 281 | Think of $k_t$ as a value on the horizontal axis. 282 | 283 | To calculate $k_{t+1}$, we can use the graph of $g$ to see its 284 | value on the vertical axis. 285 | 286 | Clearly, 287 | 288 | * If $g$ lies above the 45 degree line at this point, then we have $k_{t+1} > k_t$. 289 | * If $g$ lies below the 45 degree line at this point, then we have $k_{t+1} < k_t$. 290 | * If $g$ hits the 45 degree line at this point, then we have $k_{t+1} = k_t$, so $k_t$ is a steady state. 291 | 292 | For the Solow model, there are two steady states when $S = \mathbb R_+ = 293 | [0, \infty)$. 294 | 295 | * the origin $k=0$ 296 | * the unique positive number such that $k = s z k^{\alpha} + (1 - \delta) k$. 297 | 298 | By using some algebra, we can show that in the second case, the steady state is 299 | 300 | $$ 301 | k^* = \left( \frac{sz}{\delta} \right)^{1/(1-\alpha)} 302 | $$ 303 | 304 | ### Trajectories 305 | 306 | By the preceding discussion, in regions where $g$ lies above the 45 degree line, we know that the trajectory is increasing. 307 | 308 | The next figure traces out a trajectory in such a region so we can see this more clearly. 309 | 310 | The initial condition is $k_0 = 0.25$. 311 | 312 | ```{code-cell} julia 313 | k0 = 0.25 314 | plot45(k -> g(k; p), p.xmin, p.xmax, k0, 5) 315 | ``` 316 | 317 | We can plot the time series of capital corresponding to the figure above as 318 | follows: 319 | 320 | ```{code-cell} julia 321 | ts_plot(k -> g(k; p), k0, 5) 322 | ``` 323 | 324 | Here's a somewhat longer view: 325 | 326 | ```{code-cell} julia 327 | ts_plot(k -> g(k; p), k0, 20) 328 | ``` 329 | 330 | When capital stock is higher than the unique positive steady state, we see that 331 | it declines: 332 | 333 | ```{code-cell} julia 334 | k0 = 2.95 335 | plot45(k -> g(k; p), p.xmin, p.xmax, k0, 5) 336 | ``` 337 | 338 | Here is the time series: 339 | 340 | ```{code-cell} julia 341 | ts_plot(k -> g(k; p), k0, 8) 342 | ``` 343 | 344 | ### Complex Dynamics 345 | 346 | The Solow model is nonlinear but still generates very regular dynamics. 347 | 348 | One model that generates irregular dynamics is the **quadratic map** 349 | 350 | $$ 351 | g(x) = 4 x (1 - x), 352 | \qquad x \in [0, 1] 353 | $$ 354 | 355 | Let's have a look at the 45 degree diagram. 356 | 357 | ```{code-cell} julia 358 | xmin, xmax = 0, 1 359 | g(k) = 4 * k * (1 - k) 360 | x0 = 0.3 361 | plot45(g, xmin, xmax, 0.1, 0) 362 | ``` 363 | 364 | Now let's look at a typical trajectory. 365 | 366 | ```{code-cell} julia 367 | plot45(g, xmin, xmax, 0.1, 6) 368 | ``` 369 | 370 | Notice how irregular it is. 371 | 372 | Here is the corresponding time series plot. 373 | 374 | ```{code-cell} julia 375 | ts_plot(g, x0, 6) 376 | ``` 377 | 378 | The irregularity is even clearer over a longer time horizon: 379 | 380 | ```{code-cell} julia 381 | ts_plot(g, x0, 20) 382 | ``` 383 | 384 | ## Exercises 385 | ### Exercise 1 386 | 387 | Consider again the linear model $x_{t+1} = a x_t + b$ with $a 388 | \not=1$. 389 | 390 | The unique steady state is $b / (1 - a)$. 391 | 392 | The steady state is globally stable if $|a| < 1$. 393 | 394 | Try to illustrate this graphically by looking at a range of initial conditions. 395 | 396 | What differences do you notice in the cases $a \in (-1, 0)$ and $a 397 | \in (0, 1)$? 398 | 399 | Use $a=0.5$ and then $a=-0.5$ and study the trajectories 400 | 401 | Set $b=1$ throughout. 402 | 403 | ## Solutions 404 | 405 | ### Exercise 1 406 | We will start with the case $a=0.5$. 407 | 408 | Let's set up the model and plotting region: 409 | 410 | ```{code-cell} julia 411 | q = (a = 0.5, b = 1, xmin = -1, xmax = 3) 412 | g(k; q) = q.a * k + q.b 413 | ``` 414 | 415 | Now let's plot a trajectory: 416 | 417 | ```{code-cell} julia 418 | x0 = -0.5 419 | plot45(k -> g(k; q), q.xmin, q.xmax, x0, 5) 420 | ``` 421 | 422 | Here is the corresponding time series, which converges towards the steady 423 | state. 424 | 425 | ```{code-cell} julia 426 | ts_plot(k -> g(k; q), x0, 10) 427 | ``` 428 | 429 | Now let's try $a=-0.5$ and see what differences we observe. 430 | 431 | Let's set up the model and plotting region: 432 | 433 | ```{code-cell} julia 434 | r = (a = -0.5, b = 1, xmin = -1, xmax = 3) 435 | g(k; r) = r.a * k + r.b 436 | ``` 437 | 438 | Now let's plot a trajectory: 439 | 440 | ```{code-cell} julia 441 | x0 = -0.5 442 | plot45(k -> g(k; r), r.xmin, r.xmax, x0, 5) 443 | ``` 444 | 445 | Here is the corresponding time series, which converges towards the steady 446 | state. 447 | 448 | ```{code-cell} julia 449 | ts_plot(k -> g(k; r), x0, 10) 450 | ``` 451 | 452 | Once again, we have convergence to the steady state but the nature of 453 | convergence differs. 454 | 455 | In particular, the time series jumps from above the steady state to below it 456 | and back again. 457 | 458 | In the current context, the series is said to exhibit **damped oscillations**. 459 | -------------------------------------------------------------------------------- /lectures/introduction_dynamics/short_path.md: -------------------------------------------------------------------------------- 1 | --- 2 | jupytext: 3 | text_representation: 4 | extension: .md 5 | format_name: myst 6 | kernelspec: 7 | display_name: Julia 8 | language: julia 9 | name: julia-1.12 10 | --- 11 | 12 | (short_path)= 13 | ```{raw} html 14 |
15 | 16 | QuantEcon 17 | 18 |
19 | ``` 20 | 21 | # Shortest Paths 22 | 23 | ```{index} single: Dynamic Programming; Shortest Paths 24 | ``` 25 | 26 | ```{contents} Contents 27 | :depth: 2 28 | ``` 29 | 30 | ## Overview 31 | 32 | The shortest path problem is a [classic problem](https://en.wikipedia.org/wiki/Shortest_path) in mathematics and computer science with applications in 33 | 34 | * Economics (sequential decision making, analysis of social networks, etc.) 35 | * Operations research and transportation 36 | * Robotics and artificial intelligence 37 | * Telecommunication network design and routing 38 | * etc., etc. 39 | 40 | Variations of the methods we discuss in this lecture are used millions of times every day, in applications such as 41 | 42 | * Google Maps 43 | * routing packets on the internet 44 | 45 | For us, the shortest path problem also provides a nice introduction to the logic of **dynamic programming**. 46 | 47 | Dynamic programming is an extremely powerful optimization technique that we apply in many lectures on this site. 48 | 49 | ## Outline of the Problem 50 | 51 | The shortest path problem is one of finding how to traverse a [graph](https://en.wikipedia.org/wiki/Graph_%28mathematics%29) from one specified node to another at minimum cost. 52 | 53 | Consider the following graph 54 | 55 | ```{figure} /_static/figures/graph.png 56 | :width: 100% 57 | ``` 58 | 59 | We wish to travel from node (vertex) A to node G at minimum cost. 60 | 61 | * Arrows (edges) indicate the movements we can take. 62 | * Numbers on edges indicate the cost of traveling that edge. 63 | 64 | Possible interpretations of the graph include 65 | 66 | * Minimum cost for supplier to reach a destination. 67 | * Routing of packets on the internet (minimize time). 68 | * Etc., etc. 69 | 70 | For this simple graph, a quick scan of the edges shows that the optimal paths are 71 | 72 | * A, C, F, G at cost 8 73 | 74 | ```{figure} /_static/figures/graph4.png 75 | :width: 100% 76 | ``` 77 | 78 | * A, D, F, G at cost 8 79 | 80 | ```{figure} /_static/figures/graph3.png 81 | :width: 100% 82 | ``` 83 | 84 | ## Finding Least-Cost Paths 85 | 86 | For large graphs we need a systematic solution. 87 | 88 | Let $J(v)$ denote the minimum cost-to-go from node $v$, understood as the total cost from $v$ if we take the best route. 89 | 90 | Suppose that we know $J(v)$ for each node $v$, as shown below for the graph from the preceding example 91 | 92 | ```{figure} /_static/figures/graph2.png 93 | :width: 100% 94 | ``` 95 | 96 | Note that $J(G) = 0$. 97 | 98 | The best path can now be found as follows 99 | 100 | * Start at A. 101 | * From node v, move to any node that solves 102 | 103 | ```{math} 104 | :label: spprebell 105 | 106 | \min_{w \in F_v} \{ c(v, w) + J(w) \} 107 | ``` 108 | 109 | where 110 | 111 | * $F_v$ is the set of nodes that can be reached from $v$ in one step 112 | * $c(v, w)$ is the cost of traveling from $v$ to $w$ 113 | 114 | Hence, if we know the function $J$, then finding the best path is almost trivial. 115 | 116 | But how to find $J$? 117 | 118 | Some thought will convince you that, for every node $v$, 119 | the function $J$ satisfies 120 | 121 | ```{math} 122 | :label: spbell 123 | 124 | J(v) = \min_{w \in F_v} \{ c(v, w) + J(w) \} 125 | ``` 126 | 127 | This is known as the *Bellman equation*, after the mathematician Richard Bellman. 128 | 129 | ## Solving for $J$ 130 | 131 | The standard algorithm for finding $J$ is to start with 132 | 133 | ```{math} 134 | :label: spguess 135 | 136 | J_0(v) = M \text{ if } v \not= \text{ destination, else } J_0(v) = 0 137 | ``` 138 | 139 | where $M$ is some large number. 140 | 141 | Now we use the following algorithm 142 | 143 | 1. Set $n = 0$. 144 | 1. Set $J_{n+1} (v) = \min_{w \in F_v} \{ c(v, w) + J_n(w) \}$ for all $v$. 145 | 1. If $J_{n+1}$ and $J_n$ are not equal then increment $n$, go to 2. 146 | 147 | In general, this sequence converges to $J$---the proof is omitted. 148 | 149 | ## Exercises 150 | 151 | (short_path_ex1)= 152 | ### Exercise 1 153 | 154 | Use the algorithm given above to find the optimal path (and its cost) for the 155 | following graph. 156 | 157 | The graph is **directed**: from each node you may move only to the destinations 158 | listed in its adjacency list (e.g., you can travel from `0` to `1`, but not from 159 | `1` back to `0` unless that edge is explicitly listed). Treat node `0` as the 160 | start and node `99` as the destination. As an extension, you can symmetrize the 161 | edges to create an undirected version and compare the resulting path and cost. 162 | 163 | 164 | ```{code-cell} julia 165 | using LinearAlgebra, Statistics 166 | ``` 167 | 168 | ```{code-cell} julia 169 | --- 170 | tags: [remove-cell] 171 | --- 172 | using Test 173 | ``` 174 | 175 | ```{code-cell} julia 176 | graph = Dict(zip(0:99, 177 | [ 178 | [(14, 72.21), (8, 11.11), (1, 0.04)], 179 | [(13, 64.94), (6, 20.59), (46, 1247.25)], 180 | [(45, 1561.45), (31, 166.8), (66, 54.18)], 181 | [(11, 42.43), (6, 2.06), (20, 133.65)], 182 | [(7, 1.02), (5, 0.73), (75, 3706.67)], 183 | [(11, 34.54), (7, 3.33), (45, 1382.97)], 184 | [(10, 13.1), (9, 0.72), (31, 63.17)], 185 | [(10, 5.85), (9, 3.15), (50, 478.14)], 186 | [(12, 3.18), (11, 7.45), (69, 577.91)], 187 | [(20, 16.53), (13, 4.42), (70, 2454.28)], 188 | [(16, 25.16), (12, 1.87), (89, 5352.79)], 189 | [(20, 65.08), (18, 37.55), (94, 4961.32)], 190 | [(28, 170.04), (24, 34.32), (84, 3914.62)], 191 | [(40, 475.33), (38, 236.33), (60, 2135.95)], 192 | [(24, 38.65), (16, 2.7), (67, 1878.96)], 193 | [(18, 2.57), (17, 1.01), (91, 3597.11)], 194 | [(38, 278.71), (19, 3.49), (36, 392.92)], 195 | [(23, 26.45), (22, 24.78), (76, 783.29)], 196 | [(28, 55.84), (23, 16.23), (91, 3363.17)], 197 | [(28, 70.54), (20, 0.24), (26, 20.09)], 198 | [(33, 145.8), (24, 9.81), (98, 3523.33)], 199 | [(31, 27.06), (28, 36.65), (56, 626.04)], 200 | [(40, 124.22), (39, 136.32), (72, 1447.22)], 201 | [(33, 22.37), (26, 2.66), (52, 336.73)], 202 | [(28, 14.25), (26, 1.8), (66, 875.19)], 203 | [(35, 45.55), (32, 36.58), (70, 1343.63)], 204 | [(42, 122.0), (27, 0.01), (47, 135.78)], 205 | [(43, 246.24), (35, 48.1), (65, 480.55)], 206 | [(36, 15.52), (34, 21.79), (82, 2538.18)], 207 | [(33, 12.61), (32, 4.22), (64, 635.52)], 208 | [(35, 13.95), (33, 5.61), (98, 2616.03)], 209 | [(44, 125.88), (36, 20.44), (98, 3350.98)], 210 | [(35, 1.46), (34, 3.33), (97, 2613.92)], 211 | [(47, 111.54), (41, 3.23), (81, 1854.73)], 212 | [(48, 129.45), (42, 51.52), (73, 1075.38)], 213 | [(50, 78.81), (41, 2.09), (52, 17.57)], 214 | [(57, 260.46), (54, 101.08), (71, 1171.6)], 215 | [(46, 80.49), (38, 0.36), (75, 269.97)], 216 | [(42, 8.78), (40, 1.79), (93, 2767.85)], 217 | [(41, 1.34), (40, 0.95), (50, 39.88)], 218 | [(54, 53.46), (47, 28.57), (75, 548.68)], 219 | [(54, 162.24), (46, 0.28), (53, 18.23)], 220 | [(72, 437.49), (47, 10.08), (59, 141.86)], 221 | [(60, 116.23), (54, 95.06), (98, 2984.83)], 222 | [(47, 2.14), (46, 1.56), (91, 807.39)], 223 | [(49, 15.51), (47, 3.68), (58, 79.93)], 224 | [(67, 65.48), (57, 27.5), (52, 22.68)], 225 | [(61, 172.64), (56, 49.31), (50, 2.82)], 226 | [(60, 66.44), (59, 34.52), (99, 2564.12)], 227 | [(56, 10.89), (50, 0.51), (78, 53.79)], 228 | [(55, 20.1), (53, 1.38), (85, 251.76)], 229 | [(60, 73.79), (59, 23.67), (98, 2110.67)], 230 | [(66, 123.03), (64, 102.41), (94, 1471.8)], 231 | [(67, 88.35), (56, 4.33), (72, 22.85)], 232 | [(73, 238.61), (59, 24.3), (88, 967.59)], 233 | [(64, 60.8), (57, 2.13), (84, 86.09)], 234 | [(61, 11.06), (57, 0.02), (76, 197.03)], 235 | [(60, 7.01), (58, 0.46), (86, 701.09)], 236 | [(65, 34.32), (64, 29.85), (83, 556.7)], 237 | [(71, 0.67), (60, 0.72), (90, 820.66)], 238 | [(67, 1.63), (65, 4.76), (76, 48.03)], 239 | [(64, 4.88), (63, 0.95), (98, 1057.59)], 240 | [(76, 38.43), (64, 2.94), (91, 132.23)], 241 | [(75, 56.34), (72, 70.08), (66, 4.43)], 242 | [(76, 11.98), (65, 0.3), (80, 47.73)], 243 | [(73, 33.23), (66, 0.64), (94, 594.93)], 244 | [(73, 37.53), (68, 2.66), (98, 395.63)], 245 | [(70, 0.98), (68, 0.09), (82, 153.53)], 246 | [(71, 1.66), (70, 3.35), (94, 232.1)], 247 | [(73, 8.99), (70, 0.06), (99, 247.8)], 248 | [(73, 8.37), (72, 1.5), (76, 27.18)], 249 | [(91, 284.64), (74, 8.86), (89, 104.5)], 250 | [(92, 133.06), (84, 102.77), (76, 15.32)], 251 | [(90, 243.0), (76, 1.4), (83, 52.22)], 252 | [(78, 8.08), (76, 0.52), (81, 1.07)], 253 | [(77, 1.19), (76, 0.81), (92, 68.53)], 254 | [(78, 2.36), (77, 0.45), (85, 13.18)], 255 | [(86, 64.32), (78, 0.98), (80, 8.94)], 256 | [(81, 2.59), (98, 355.9)], 257 | [(91, 22.35), (85, 1.45), (81, 0.09)], 258 | [(98, 264.34), (88, 28.78), (92, 121.87)], 259 | [(92, 99.89), (89, 39.52), (94, 99.78)], 260 | [(93, 11.99), (88, 28.05), (91, 47.44)], 261 | [(88, 5.78), (86, 8.75), (94, 114.95)], 262 | [(98, 121.05), (94, 30.41), (89, 19.14)], 263 | [(89, 4.9), (87, 2.66), (97, 94.51)], 264 | [(97, 85.09)], 265 | [(92, 21.23), (91, 11.14), (88, 0.21)], 266 | [(98, 6.12), (91, 6.83), (93, 1.31)], 267 | [(99, 82.12), (97, 36.97)], 268 | [(99, 50.99), (94, 10.47), (96, 23.53)], 269 | [(97, 22.17)], 270 | [(99, 34.68), (97, 11.24), (96, 10.83)], 271 | [(99, 32.77), (97, 6.71), (94, 0.19)], 272 | [(96, 2.03), (98, 5.91)], 273 | [(99, 0.27), (98, 6.17)], 274 | [(99, 5.87), (97, 0.43), (98, 3.32)], 275 | [(98, 0.3)], 276 | [(99, 0.33)], 277 | [(99, 0.0)], 278 | ])) 279 | ``` 280 | 281 | The cost from node 68 to node 71 is 1.66 and so on. 282 | 283 | ## Solutions 284 | 285 | ### Exercise 1 286 | 287 | ```{code-cell} julia 288 | function value_iteration(graph; dest = maximum(keys(graph))) 289 | J = Dict(node => (node == dest ? 0.0 : Inf) for node in keys(graph)) 290 | updated = true 291 | while updated 292 | updated = false 293 | for (node, edges) in graph 294 | node == dest && continue 295 | best = minimum(cost + J[child] for (child, cost) in edges) 296 | if best != J[node] 297 | J[node] = best 298 | updated = true 299 | end 300 | end 301 | end 302 | return J 303 | end 304 | 305 | function best_path(J, graph; start = minimum(keys(graph)), dest = maximum(keys(graph))) 306 | path = Int[] 307 | cost = 0.0 308 | current = start 309 | while current != dest 310 | push!(path, current) 311 | edges = graph[current] 312 | next_node, edge_cost = edges[1] 313 | best_total = edge_cost + J[next_node] 314 | for (child, c) in Iterators.drop(edges, 1) 315 | total = c + J[child] 316 | if total < best_total 317 | best_total = total 318 | next_node = child 319 | edge_cost = c 320 | end 321 | end 322 | current = next_node 323 | cost += edge_cost 324 | end 325 | push!(path, dest) 326 | return path, cost 327 | end 328 | 329 | J = value_iteration(graph) 330 | path, total_cost = best_path(J, graph) 331 | total_cost = round(total_cost; digits = 2) 332 | 333 | for node in path 334 | println("node $node") 335 | end 336 | println("Cost: $total_cost") 337 | ``` 338 | 339 | ```{code-cell} julia 340 | --- 341 | tags: [remove-cell] 342 | --- 343 | sum_costs = 0.0 344 | current_location, destination = extrema(keys(graph)) 345 | while current_location != destination 346 | println("node $current_location") 347 | running_min = 1e10 348 | minimizer_dest = Inf 349 | minimizer_cost = 1e10 350 | for (dest, cost) in graph[current_location] 351 | cost_of_path = cost + J[dest] 352 | if cost_of_path < running_min 353 | running_min = cost_of_path 354 | minimizer_cost = cost 355 | minimizer_dest = dest 356 | end 357 | end 358 | 359 | current_location = minimizer_dest 360 | sum_costs += minimizer_cost 361 | end 362 | 363 | sum_costs = round(sum_costs, digits = 2) 364 | 365 | @test sum_costs ≈ 160.55 366 | ``` 367 | --------------------------------------------------------------------------------