diff --git a/.JuliaFormatter.toml b/.JuliaFormatter.toml index 309ba66c..6a50b834 100644 --- a/.JuliaFormatter.toml +++ b/.JuliaFormatter.toml @@ -1,4 +1,4 @@ style = "sciml" -margin = 84 +margin = 80 yas_style_nesting = true annotate_untyped_fields_with_any = false \ No newline at end of file diff --git a/.github/workflows/cache.yml b/.github/workflows/cache.yml index c2b500b5..67bdcd61 100644 --- a/.github/workflows/cache.yml +++ b/.github/workflows/cache.yml @@ -3,6 +3,9 @@ on: push: branches: - main + schedule: + # Run monthly to avoid stale cache + - cron: '0 0 1 * *' jobs: cache: runs-on: ubuntu-latest @@ -12,7 +15,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 with: - python-version: 3.9 + python-version: 3.11 - name: Install Python Dependencies run: | pip install -r requirements.txt @@ -34,7 +37,7 @@ jobs: - name: Set up Julia uses: julia-actions/setup-julia@v1 with: - version: 1.9 + version: 1.10.0 - name: Install IJulia and Setup Project shell: bash run: | diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 02f21aba..66e57904 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 with: - python-version: 3.9 + python-version: 3.11 - name: Install Python Dependencies run: | pip install -r requirements.txt @@ -32,7 +32,7 @@ jobs: - name: Set up Julia uses: julia-actions/setup-julia@v1 with: - version: 1.9 + version: 1.10.0 - name: Install IJulia and Setup Project shell: bash run: | diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index df510876..30f3087e 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -17,7 +17,7 @@ jobs: - name: Setup Julia uses: julia-actions/setup-julia@v1 with: - version: 1.9 + version: 1.10.0 - name: Install JuliaFormatter.jl run: julia -e 'import Pkg; Pkg.add("JuliaFormatter")' diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 4168e38f..dad8ec55 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -13,7 +13,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v2 with: - python-version: 3.9 + python-version: 3.11 - name: Install Python Dependencies run: | pip install -r requirements.txt @@ -35,7 +35,7 @@ jobs: - name: Set up Julia uses: julia-actions/setup-julia@v1 with: - version: 1.9 + version: 1.10.0 - name: Install IJulia and Setup Project shell: bash run: | diff --git a/.gitignore b/.gitignore index e00f5c0b..b23096d0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ _build -us_cities.txt \ No newline at end of file +us_cities.txt +.DS_Store +.vscode diff --git a/README.md b/README.md index fe71ad3d..13c53b4b 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ It is straightforward to install the Jupyter Book and Julia software necessary f 7. Start a VS Code terminal with ```` or through any other method. Create a conda environment. ```bash - conda create -n lecture-julia.myst python=3.9 + conda create -n lecture-julia.myst python=3.11 conda activate lecture-julia.myst pip install -r requirements.txt ``` @@ -58,17 +58,17 @@ julia format_myst.jl lectures/getting_started_julia/getting_started.md ``` As a helper, you can call a shell script to do it for an entire folder + ```bash bash format_all_directory.sh lectures/dynamic_programming ``` + or to also do the unicode substitutions + ```bash bash format_all_directory.sh lectures/dynamic_programming true ``` -Alternatively, the formatter will run automatically when a pull-request is made - - **(Optional) REPL Integration** 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. 1. Open Key Bindings with ``. @@ -84,6 +84,7 @@ If you installed the REPL Integration above, then in a `.md` file, 3. Then, assuming that you set up the keybindings above, you can send a line of code in the markdown to the REPL with ``. Code can be executed line by line, or you can select a chunk of code and execute it. + ## Example Operations ### Building the lectures To do a full build of the lectures: @@ -100,7 +101,7 @@ jb build lectures This will take a while. But it will populate your cache, so future iteration is faster. -On Windows, if you get the following error: +It is suggested to use WSL on Windows On Windows, if you get the following error: ``` ImportError: DLL load failed while importing win32api: The specified procedure could not be found. @@ -132,5 +133,4 @@ jb clean lectures --all After execution, you can find the generated `.ipynb` and `.jl` files in `_build/jupyter_execute` for each lecture. - To see errors, you can open these in JupyterLab, the Jupyter support within VS Code, etc. -- 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. -- Finally, the code is written using interactive scoping, so `include(_build/jupyter_execute/dynamic_programming/mccall_model.jl)` etc. may not work. However, `shift-enter` within VS Code to the REPL will work, and you can execute these with [SoftGlobalScope.jl](https://github.com/stevengj/SoftGlobalScope.jl) if strictly required. +- 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. \ No newline at end of file diff --git a/format_myst.jl b/format_myst.jl index 0e24e1dd..fcf44d03 100644 --- a/format_myst.jl +++ b/format_myst.jl @@ -58,7 +58,9 @@ function format_myst(input_file_path, output_file_path, extra_replacements = fal replacements = Dict("α" => "alpha", "β" => "beta", "γ" => "gamma", "≤" => "<=", "≥" => ">=", "Σ" => "Sigma", "σ" => "sigma","μ"=>"mu","ϕ"=>"phi","ψ"=>"psi","ϵ"=>"epsilon", "δ"=>"delta","θ" => "theta","ζ"=>"zeta","X̄" => "X_bar","p̄" => "p_bar","x̂" => "x_hat","λ"=>"lambda", - "ρ"=>"rho","u′" => "u_prime" , "f′"=>"f_prime"," ∂u∂c"=>"dudc","Π"=>"Pi","π"=>"pi"," ξ"=>"Xi","c̄"=>"c_bar","w̄"=>"w_bar") + "ρ"=>"rho","u′" => "u_prime" , "f′"=>"f_prime"," ∂u∂c"=>"dudc","Π"=>"Pi","π"=>"pi","ξ"=>"xi","c̄"=>"c_bar", + "w̄"=>"w_bar","Θ" => "Theta", "Ξ" =>"Xi", "Q̃" => "Q_tilde","R̃" => "R_tilde","Ã" => "A_tilde", "B̃" => "B_tilde", + "P̃" => "P_tilde","F̃" => "F_tilde","d̃" => "d_tilde") # Replace the code blocks in the content and handle exceptions try diff --git a/lectures/Manifest.toml b/lectures/Manifest.toml index 05cdb251..40cf09b2 100644 --- a/lectures/Manifest.toml +++ b/lectures/Manifest.toml @@ -1,19 +1,19 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.9.1" +julia_version = "1.10.0" manifest_format = "2.0" -project_hash = "426ee44181a1827c854acad97427614830a3ef74" +project_hash = "bbafb0ad34fec16511b07a132895ce6672068cfe" [[deps.ADTypes]] -git-tree-sha1 = "dcfdf328328f2645531c4ddebf841228aef74130" +git-tree-sha1 = "41c37aa88889c171f1300ceac1313c06e891d245" uuid = "47edcb42-4c32-4615-8424-f2b9edc5f35b" -version = "0.1.3" +version = "0.2.6" [[deps.AMD]] -deps = ["Libdl", "LinearAlgebra", "SparseArrays", "Test"] -git-tree-sha1 = "00163dc02b882ca5ec032400b919e5f5011dbd31" +deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse_jll"] +git-tree-sha1 = "45a1272e3f809d36431e57ab22703c6896b8908f" uuid = "14f7f29c-3bd6-536c-9a0b-7339e30b5a3e" -version = "0.5.0" +version = "0.5.3" [[deps.ASL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -22,20 +22,21 @@ uuid = "ae81ac8f-d209-56e5-92de-9978fef736f9" version = "0.1.3+0" [[deps.AbstractAlgebra]] -deps = ["GroupsCore", "InteractiveUtils", "LinearAlgebra", "MacroTools", "Markdown", "Random", "RandomExtensions", "SparseArrays", "Test"] -git-tree-sha1 = "29e65c331f97db9189ef00a4c7aed8127c2fd2d4" +deps = ["GroupsCore", "InteractiveUtils", "LinearAlgebra", "MacroTools", "Preferences", "Random", "RandomExtensions", "SparseArrays", "Test"] +git-tree-sha1 = "d7832de8cf7af26abac741f10372080ac6cb73df" uuid = "c3fe647b-3220-5bb0-a1ea-a7954cac585d" -version = "0.27.10" +version = "0.34.7" [[deps.AbstractFFTs]] deps = ["LinearAlgebra"] -git-tree-sha1 = "16b6dbc4cf7caee4e1e75c49485ec67b667098a0" +git-tree-sha1 = "d92ad398961a3ed262d8bf04a1a2b8340f915fef" uuid = "621f4979-c628-5d54-868e-fcf4e3e8185c" -version = "1.3.1" -weakdeps = ["ChainRulesCore"] +version = "1.5.0" +weakdeps = ["ChainRulesCore", "Test"] [deps.AbstractFFTs.extensions] AbstractFFTsChainRulesCoreExt = "ChainRulesCore" + AbstractFFTsTestExt = "Test" [[deps.AbstractTrees]] git-tree-sha1 = "faa260e4cb5aba097a73fab382dd4b5819d8ec8c" @@ -44,9 +45,9 @@ version = "0.4.4" [[deps.Adapt]] deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "76289dc51920fdc6e0013c872ba9551d54961c24" +git-tree-sha1 = "cde29ddf7e5726c9fb511f340244ea3481267608" uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "3.6.2" +version = "3.7.2" weakdeps = ["StaticArrays"] [deps.Adapt.extensions] @@ -82,9 +83,9 @@ version = "3.5.1+1" [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra", "Requires", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "d3f758863a47ceef2248d136657cb9c033603641" +git-tree-sha1 = "bbec08a37f8722786d87bedf84eae19c020c4efa" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.4.8" +version = "7.7.0" [deps.ArrayInterface.extensions] ArrayInterfaceBandedMatricesExt = "BandedMatrices" @@ -102,27 +103,19 @@ version = "7.4.8" StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" -[[deps.ArrayInterfaceCore]] -deps = ["LinearAlgebra", "SnoopPrecompile", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "e5f08b5689b1aad068e01751889f2f615c7db36d" -uuid = "30b0a656-2188-435a-8636-2ec0e6a096e2" -version = "0.1.29" - [[deps.ArrayLayouts]] -deps = ["FillArrays", "LinearAlgebra", "SparseArrays"] -git-tree-sha1 = "4aff5fa660eb95c2e0deb6bcdabe4d9a96bc4667" +deps = ["FillArrays", "LinearAlgebra"] +git-tree-sha1 = "b08a4043e1c14096ef8efe4dd97e07de5cacf240" uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" -version = "0.8.18" +version = "1.4.5" +weakdeps = ["SparseArrays"] + + [deps.ArrayLayouts.extensions] + ArrayLayoutsSparseArraysExt = "SparseArrays" [[deps.Artifacts]] uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" -[[deps.Atomix]] -deps = ["UnsafeAtomics"] -git-tree-sha1 = "c06a868224ecba914baa6942988e2f2aade419be" -uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" -version = "0.1.0" - [[deps.AxisAlgorithms]] deps = ["LinearAlgebra", "Random", "SparseArrays", "WoodburyMatrices"] git-tree-sha1 = "66771c8d21c8ff5e3a93379480a2307ac36863f7" @@ -130,29 +123,33 @@ uuid = "13072b0f-2c55-5437-9ae7-d433b7a33950" version = "1.0.1" [[deps.BandedMatrices]] -deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra", "SnoopPrecompile", "SparseArrays"] -git-tree-sha1 = "6ef8fc1d77b60f41041d59ce61ef9eb41ed97a83" +deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra", "PrecompileTools"] +git-tree-sha1 = "27baf04c642465b4289179f29bb7127f0673d4f1" uuid = "aae01518-5342-5314-be14-df237901396f" -version = "0.17.18" +version = "1.4.0" +weakdeps = ["SparseArrays"] + + [deps.BandedMatrices.extensions] + BandedMatricesSparseArraysExt = "SparseArrays" [[deps.Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" [[deps.BenchmarkTools]] deps = ["JSON", "Logging", "Printf", "Profile", "Statistics", "UUIDs"] -git-tree-sha1 = "d9a9701b899b30332bbcb3e1679c41cce81fb0e8" +git-tree-sha1 = "f1f03a9fa24271160ed7e73051fba3c1a759b53f" uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" -version = "1.3.2" +version = "1.4.0" [[deps.Bijections]] -git-tree-sha1 = "fe4f8c5ee7f76f2198d5c2a06d3961c249cce7bd" +git-tree-sha1 = "c9b163bd832e023571e86d0b90d9de92a9879088" uuid = "e2ed5e7c-b2de-5872-ae92-c73ca462fb04" -version = "0.1.4" +version = "0.1.6" [[deps.BitFlags]] -git-tree-sha1 = "43b1a4a8f797c1cddadf60499a8a077d4af2cd2d" +git-tree-sha1 = "2dc09997850d68179b69dafb58ae806167a32b1b" uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" -version = "0.1.7" +version = "0.1.8" [[deps.BitTwiddlingConvenienceFunctions]] deps = ["Static"] @@ -160,51 +157,23 @@ git-tree-sha1 = "0c5f81f47bbbcf4aea7b2959135713459170798b" uuid = "62783981-4cbd-42fc-bca8-16325de8dc4b" version = "0.1.5" -[[deps.BlackBoxOptim]] -deps = ["CPUTime", "Compat", "Distributed", "Distributions", "HTTP", "JSON", "LinearAlgebra", "Printf", "Random", "SpatialIndexing", "StatsBase"] -git-tree-sha1 = "136079f37e3514ec691926093924b591a8842f5d" -uuid = "a134a8b2-14d6-55f6-9291-3336d3ab0209" -version = "0.6.2" - -[[deps.BlockArrays]] -deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra"] -git-tree-sha1 = "3b15c61bcece7c426ea641d143c808ace3661973" -uuid = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" -version = "0.16.25" - -[[deps.BlockBandedMatrices]] -deps = ["ArrayLayouts", "BandedMatrices", "BlockArrays", "FillArrays", "LinearAlgebra", "MatrixFactorizations", "SparseArrays", "Statistics"] -git-tree-sha1 = "f389a2752664c4103f9c481b4766d7eed78ad85b" -uuid = "ffab5731-97b5-5995-9138-79e8c1846df0" -version = "0.11.10" - [[deps.Bzip2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] git-tree-sha1 = "19a35467a82e236ff51bc17a3a44b69ef35185a2" uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" version = "1.0.8+0" -[[deps.CEnum]] -git-tree-sha1 = "eb4cb44a499229b3b8426dcfb5dd85333951ff90" -uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" -version = "0.4.2" - [[deps.CPUSummary]] deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] -git-tree-sha1 = "89e0654ed8c7aebad6d5ad235d6242c2d737a928" +git-tree-sha1 = "601f7e7b3d36f18790e2caf83a882d88e9b71ff1" uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" -version = "0.2.3" - -[[deps.CPUTime]] -git-tree-sha1 = "2dcc50ea6a0a1ef6440d6eecd0fe3813e5671f45" -uuid = "a9c8d775-2e2e-55fc-8582-045d282d599e" -version = "1.0.0" +version = "0.2.4" [[deps.CSV]] deps = ["CodecZlib", "Dates", "FilePathsBase", "InlineStrings", "Mmap", "Parsers", "PooledArrays", "PrecompileTools", "SentinelArrays", "Tables", "Unicode", "WeakRefStrings", "WorkerUtilities"] -git-tree-sha1 = "44dbf560808d49041989b8a96cae4cffbeb7966a" +git-tree-sha1 = "679e69c611fff422038e9e21e270c4197d49d918" uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b" -version = "0.10.11" +version = "0.10.12" [[deps.Cairo_jll]] deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] @@ -241,17 +210,15 @@ git-tree-sha1 = "8c4920235f6c561e401dfe569beb8b924adad003" uuid = "8be319e6-bccf-4806-a6f7-6fae938471bc" version = "0.5.0" -[[deps.ChainRules]] -deps = ["Adapt", "ChainRulesCore", "Compat", "Distributed", "GPUArraysCore", "IrrationalConstants", "LinearAlgebra", "Random", "RealDot", "SparseArrays", "Statistics", "StructArrays"] -git-tree-sha1 = "82e2d776be8bef478792d6cba65b06b16952f8ba" -uuid = "082447d4-558c-5d27-93f4-14fc19e9eca2" -version = "1.50.0" - [[deps.ChainRulesCore]] -deps = ["Compat", "LinearAlgebra", "SparseArrays"] -git-tree-sha1 = "e30f2f4e20f7f186dc36529910beaedc60cfa644" +deps = ["Compat", "LinearAlgebra"] +git-tree-sha1 = "2118cb2765f8197b08e5958cdd17c165427425ee" uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.16.0" +version = "1.19.0" +weakdeps = ["SparseArrays"] + + [deps.ChainRulesCore.extensions] + ChainRulesCoreSparseArraysExt = "SparseArrays" [[deps.CloseOpenIntervals]] deps = ["Static", "StaticArrayInterface"] @@ -261,27 +228,27 @@ version = "0.1.12" [[deps.Clustering]] deps = ["Distances", "LinearAlgebra", "NearestNeighbors", "Printf", "Random", "SparseArrays", "Statistics", "StatsBase"] -git-tree-sha1 = "a6e6ce44a1e0a781772fc795fb7343b1925e9898" +git-tree-sha1 = "407f38961ac11a6e14b2df7095a2577f7cb7cb1b" uuid = "aaaa29a8-35af-508c-8bc3-b662a17a0fe5" -version = "0.15.2" +version = "0.15.6" [[deps.CodecBzip2]] deps = ["Bzip2_jll", "Libdl", "TranscodingStreams"] -git-tree-sha1 = "2e62a725210ce3c3c2e1a3080190e7ca491f18d7" +git-tree-sha1 = "c0ae2a86b162fb5d7acc65269b469ff5b8a73594" uuid = "523fee87-0ab8-5b00-afb7-3ecf72e48cfd" -version = "0.7.2" +version = "0.8.1" [[deps.CodecZlib]] deps = ["TranscodingStreams", "Zlib_jll"] -git-tree-sha1 = "9c209fb7536406834aa938fb149964b985de6c83" +git-tree-sha1 = "cd67fc487743b2f0fd4380d4cbd3a24660d0eec8" uuid = "944b1d66-785c-5afd-91f1-9de20f533193" -version = "0.7.1" +version = "0.7.3" [[deps.ColorSchemes]] deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] -git-tree-sha1 = "be6ab11021cd29f0344d5c4357b163af05a48cba" +git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" -version = "3.21.0" +version = "3.24.0" [[deps.ColorTypes]] deps = ["FixedPointNumbers", "Random"] @@ -290,10 +257,14 @@ uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" version = "0.11.4" [[deps.ColorVectorSpace]] -deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "SpecialFunctions", "Statistics", "TensorCore"] -git-tree-sha1 = "600cc5508d66b78aae350f7accdb58763ac18589" +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" -version = "0.9.10" +version = "0.10.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" [[deps.Colors]] deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] @@ -319,9 +290,9 @@ version = "0.3.0" [[deps.Compat]] deps = ["UUIDs"] -git-tree-sha1 = "7a60c856b9fa189eb34f5f8a6f6b5529b7942957" +git-tree-sha1 = "886826d76ea9e72b35fcd000e535588f7b60f21d" uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.6.1" +version = "4.10.1" weakdeps = ["Dates", "LinearAlgebra"] [deps.Compat.extensions] @@ -330,24 +301,29 @@ weakdeps = ["Dates", "LinearAlgebra"] [[deps.CompilerSupportLibraries_jll]] deps = ["Artifacts", "Libdl"] uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.0.2+0" +version = "1.0.5+1" [[deps.CompositeTypes]] git-tree-sha1 = "02d2316b7ffceff992f3096ae48c7829a8aa0638" uuid = "b152e2b5-7a66-4b01-a709-34e65c35f657" version = "0.1.3" +[[deps.ConcreteStructs]] +git-tree-sha1 = "f749037478283d372048690eb3b5f92a79432b34" +uuid = "2569d6c7-a4a2-43d3-a901-331e8e4be471" +version = "0.2.3" + [[deps.ConcurrentUtilities]] deps = ["Serialization", "Sockets"] -git-tree-sha1 = "96d823b94ba8d187a6d8f0826e731195a74b90e9" +git-tree-sha1 = "8cfa272e8bdedfa88b6aefbbca7c19f1befac519" uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" -version = "2.2.0" +version = "2.3.0" [[deps.ConstructionBase]] deps = ["LinearAlgebra"] -git-tree-sha1 = "738fec4d684a9a6ee9598a8bfee305b26831f28c" +git-tree-sha1 = "c53fc348ca4d40d7b371e71fd52251839080cbc9" uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.5.2" +version = "1.5.4" weakdeps = ["IntervalSets", "StaticArrays"] [deps.ConstructionBase.extensions] @@ -372,9 +348,9 @@ version = "4.1.1" [[deps.DSP]] deps = ["Compat", "FFTW", "IterTools", "LinearAlgebra", "Polynomials", "Random", "Reexport", "SpecialFunctions", "Statistics"] -git-tree-sha1 = "da8b06f89fce9996443010ef92572b193f8dca1f" +git-tree-sha1 = "f7f4319567fe769debfcf7f8c03d8da1dd4e2fb0" uuid = "717857b8-e6f2-59f4-9121-6e50c889abd2" -version = "0.7.8" +version = "0.7.9" [[deps.DataAPI]] git-tree-sha1 = "8da84edb865b0b5b0100c0666a9bc9a0b71c553c" @@ -382,40 +358,41 @@ uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" version = "1.15.0" [[deps.DataFrames]] -deps = ["Compat", "DataAPI", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrettyTables", "Printf", "REPL", "Random", "Reexport", "SentinelArrays", "SnoopPrecompile", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] -git-tree-sha1 = "aa51303df86f8626a962fccb878430cdb0a97eee" +deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "REPL", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] +git-tree-sha1 = "04c738083f29f86e62c8afc341f0967d8717bdb8" uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "1.5.0" +version = "1.6.1" [[deps.DataFramesMeta]] deps = ["Chain", "DataFrames", "MacroTools", "OrderedCollections", "Reexport"] -git-tree-sha1 = "7f13b2f9fa5fc843a06596f1cc917ed1a3d6740b" +git-tree-sha1 = "6970958074cd09727b9200685b8631b034c0eb16" uuid = "1313f7d8-7da2-5740-9ea0-a2ca25f37964" -version = "0.14.0" +version = "0.14.1" [[deps.DataInterpolations]] -deps = ["LinearAlgebra", "RecipesBase", "RecursiveArrayTools", "Reexport", "Requires"] -git-tree-sha1 = "e52a7c2388471ca6e7e6dcd68c98073f378b8967" +deps = ["LinearAlgebra", "PrettyTables", "RecipesBase", "Reexport", "Requires"] +git-tree-sha1 = "99f979d5e9b67c2aeee701c3683037ac8d75bdd6" uuid = "82cc6244-b520-54b8-b5a6-8a565e85f1d0" -version = "4.0.1" +version = "4.6.0" [deps.DataInterpolations.extensions] DataInterpolationsChainRulesCoreExt = "ChainRulesCore" - DataInterpolationsOptimExt = "Optim" + DataInterpolationsOptimExt = ["ForwardDiff", "Optim"] DataInterpolationsRegularizationToolsExt = "RegularizationTools" DataInterpolationsSymbolicsExt = "Symbolics" [deps.DataInterpolations.weakdeps] ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" Optim = "429524aa-4258-5aef-a3af-852621145aeb" RegularizationTools = "29dad682-9a27-4bc3-9c72-016788665182" Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" [[deps.DataStructures]] deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "d1fff3a548102f48987a52a2e0d114fa97d730f0" +git-tree-sha1 = "3dbd312d370723b6bb43ba9d02fc36abade4518d" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.13" +version = "0.18.15" [[deps.DataValueInterfaces]] git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" @@ -439,13 +416,15 @@ uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" version = "1.9.1" [[deps.DiffEqBase]] -deps = ["ArrayInterface", "ChainRulesCore", "DataStructures", "DocStringExtensions", "EnumX", "FastBroadcast", "ForwardDiff", "FunctionWrappers", "FunctionWrappersWrappers", "LinearAlgebra", "Logging", "Markdown", "MuladdMacro", "Parameters", "PreallocationTools", "Printf", "RecursiveArrayTools", "Reexport", "Requires", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Static", "StaticArraysCore", "Statistics", "Tricks", "TruncatedStacktraces", "ZygoteRules"] -git-tree-sha1 = "0a7dd11dd243a1f8c71f72f2e5fd54c0bfdeaaab" +deps = ["ArrayInterface", "DataStructures", "DocStringExtensions", "EnumX", "EnzymeCore", "FastBroadcast", "ForwardDiff", "FunctionWrappers", "FunctionWrappersWrappers", "LinearAlgebra", "Logging", "Markdown", "MuladdMacro", "Parameters", "PreallocationTools", "PrecompileTools", "Printf", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Static", "StaticArraysCore", "Statistics", "Tricks", "TruncatedStacktraces"] +git-tree-sha1 = "044648af911974c3928058c1f8c83f159dece274" uuid = "2b5f629d-d688-5b77-993f-72d75c75574e" -version = "6.125.1" +version = "6.145.6" [deps.DiffEqBase.extensions] + DiffEqBaseChainRulesCoreExt = "ChainRulesCore" DiffEqBaseDistributionsExt = "Distributions" + DiffEqBaseEnzymeExt = ["ChainRulesCore", "Enzyme"] DiffEqBaseGeneralizedGeneratedExt = "GeneralizedGenerated" DiffEqBaseMPIExt = "MPI" DiffEqBaseMeasurementsExt = "Measurements" @@ -453,10 +432,11 @@ version = "6.125.1" DiffEqBaseReverseDiffExt = "ReverseDiff" DiffEqBaseTrackerExt = "Tracker" DiffEqBaseUnitfulExt = "Unitful" - DiffEqBaseZygoteExt = "Zygote" [deps.DiffEqBase.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" GeneralizedGenerated = "6b9d7cbe-bcb9-11e9-073f-15a7a543e2eb" MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" @@ -464,13 +444,12 @@ version = "6.125.1" ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" - Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" [[deps.DiffEqNoiseProcess]] deps = ["DiffEqBase", "Distributions", "GPUArraysCore", "LinearAlgebra", "Markdown", "Optim", "PoissonRandom", "QuadGK", "Random", "Random123", "RandomNumbers", "RecipesBase", "RecursiveArrayTools", "Requires", "ResettableStacks", "SciMLBase", "StaticArraysCore", "Statistics"] -git-tree-sha1 = "50f82e2a705a544af539acc6a03674a4d7eee1d8" +git-tree-sha1 = "319377c927a4aa1f491228b2ac23f3554a3497c6" uuid = "77a26b50-5914-5dd7-bc55-306e6241c503" -version = "5.17.1" +version = "5.20.0" [deps.DiffEqNoiseProcess.extensions] DiffEqNoiseProcessReverseDiffExt = "ReverseDiff" @@ -478,12 +457,6 @@ version = "5.17.1" [deps.DiffEqNoiseProcess.weakdeps] ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" -[[deps.DiffEqOperators]] -deps = ["BandedMatrices", "BlockBandedMatrices", "DiffEqBase", "DomainSets", "ForwardDiff", "LazyArrays", "LazyBandedMatrices", "LinearAlgebra", "LoopVectorization", "NNlib", "Requires", "RuntimeGeneratedFunctions", "SciMLBase", "SparseArrays", "SparseDiffTools", "StaticArrays", "SuiteSparse"] -git-tree-sha1 = "ef0f24d69406bf85092c843691ab2ae3b2e34b77" -uuid = "9fdde737-9c7f-55bf-ade8-46b3f136cc48" -version = "4.45.0" - [[deps.DiffResults]] deps = ["StaticArraysCore"] git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" @@ -497,28 +470,35 @@ uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" version = "1.15.1" [[deps.Distances]] -deps = ["LinearAlgebra", "SparseArrays", "Statistics", "StatsAPI"] -git-tree-sha1 = "49eba9ad9f7ead780bfb7ee319f962c811c6d3b2" +deps = ["LinearAlgebra", "Statistics", "StatsAPI"] +git-tree-sha1 = "66c4c81f259586e8f002eacebc177e1fb06363b0" uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.10.8" +version = "0.10.11" +weakdeps = ["ChainRulesCore", "SparseArrays"] + + [deps.Distances.extensions] + DistancesChainRulesCoreExt = "ChainRulesCore" + DistancesSparseArraysExt = "SparseArrays" [[deps.Distributed]] deps = ["Random", "Serialization", "Sockets"] uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" [[deps.Distributions]] -deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SparseArrays", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns", "Test"] -git-tree-sha1 = "c72970914c8a21b36bbc244e9df0ed1834a0360b" +deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] +git-tree-sha1 = "9242eec9b7e2e14f9952e8ea1c7e31a50501d587" uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.25.95" +version = "0.25.104" [deps.Distributions.extensions] DistributionsChainRulesCoreExt = "ChainRulesCore" DistributionsDensityInterfaceExt = "DensityInterface" + DistributionsTestExt = "Test" [deps.Distributions.weakdeps] ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.DocStringExtensions]] deps = ["LibGit2"] @@ -528,9 +508,9 @@ version = "0.9.3" [[deps.DomainSets]] deps = ["CompositeTypes", "IntervalSets", "LinearAlgebra", "Random", "StaticArrays", "Statistics"] -git-tree-sha1 = "988e2db482abeb69efc76ae8b6eba2e93805ee70" +git-tree-sha1 = "51b4b84d33ec5e0955b55ff4b748b99ce2c3faa9" uuid = "5b8099bc-c8ec-5219-889f-1d9e522a28bf" -version = "0.5.15" +version = "0.6.7" [[deps.Downloads]] deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] @@ -544,38 +524,56 @@ uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" version = "0.6.8" [[deps.DynamicPolynomials]] -deps = ["DataStructures", "Future", "LinearAlgebra", "MultivariatePolynomials", "MutableArithmetics", "Pkg", "Reexport", "Test"] -git-tree-sha1 = "8b84876e31fa39479050e2d3395c4b3b210db8b0" +deps = ["Future", "LinearAlgebra", "MultivariatePolynomials", "MutableArithmetics", "Pkg", "Reexport", "Test"] +git-tree-sha1 = "fea68c84ba262b121754539e6ea0546146515d4f" uuid = "7c1d4256-1411-5781-91ec-d7bc3513ac07" -version = "0.4.6" +version = "0.5.3" [[deps.EnumX]] git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" version = "1.0.4" +[[deps.EnzymeCore]] +deps = ["Adapt"] +git-tree-sha1 = "2efe862de93cd87f620ad6ac9c9e3f83f1b2841b" +uuid = "f151be2c-9106-41f4-ab19-57ee4f262869" +version = "0.6.4" + +[[deps.EpollShim_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8e9441ee83492030ace98f9789a654a6d0b1f643" +uuid = "2702e6a9-849d-5ed8-8c21-79e8b8f9ee43" +version = "0.0.20230411+0" + +[[deps.ExceptionUnwrapping]] +deps = ["Test"] +git-tree-sha1 = "dcb08a0d93ec0b1cdc4af184b26b591e9695423a" +uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" +version = "0.1.10" + [[deps.Expat_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "bad72f730e9e91c08d9427d5e8db95478a3c323d" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "4558ab818dcceaab612d1bb8c19cee87eda2b83c" uuid = "2e619515-83b5-522b-bb60-26c02a35a201" -version = "2.4.8+0" +version = "2.5.0+0" [[deps.Expectations]] deps = ["Distributions", "FastGaussQuadrature", "LinearAlgebra", "SpecialFunctions"] -git-tree-sha1 = "539c415ad6693bb7792be05a3e51e010c6795d95" +git-tree-sha1 = "5b46996cf6fc4ad19d1122884c36faa62ed0a7d2" uuid = "2fe49d83-0758-5602-8f54-1f90ad0d522b" -version = "1.9.0" +version = "1.9.2" [[deps.ExponentialUtilities]] -deps = ["Adapt", "ArrayInterface", "GPUArraysCore", "GenericSchur", "LinearAlgebra", "Printf", "SnoopPrecompile", "SparseArrays", "libblastrampoline_jll"] -git-tree-sha1 = "fb7dbef7d2631e2d02c49e2750f7447648b0ec9b" +deps = ["Adapt", "ArrayInterface", "GPUArraysCore", "GenericSchur", "LinearAlgebra", "PrecompileTools", "Printf", "SparseArrays", "libblastrampoline_jll"] +git-tree-sha1 = "602e4585bcbd5a25bc06f514724593d13ff9e862" uuid = "d4d017d3-3776-5f7e-afef-a10c40355c18" -version = "1.24.0" +version = "1.25.0" [[deps.ExprTools]] -git-tree-sha1 = "c1d06d129da9f55715c6c212866f5b1bddc5fa00" +git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" -version = "0.1.9" +version = "0.1.10" [[deps.FFMPEG]] deps = ["FFMPEG_jll"] @@ -584,16 +582,16 @@ uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" version = "0.4.1" [[deps.FFMPEG_jll]] -deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Pkg", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] -git-tree-sha1 = "74faea50c1d007c85837327f6775bea60b5492dd" +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "466d45dc38e15794ec7d5d63ec03d776a9aff36e" uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" -version = "4.4.2+2" +version = "4.4.4+1" [[deps.FFTW]] deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] -git-tree-sha1 = "06bf20fcecd258eccf9a6ef7b99856a4dfe7b64c" +git-tree-sha1 = "ec22cbbcd01cba8f41eecd7d44aac1f23ee985e3" uuid = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" -version = "1.7.0" +version = "1.7.2" [[deps.FFTW_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -603,9 +601,9 @@ version = "3.3.10+0" [[deps.FastBroadcast]] deps = ["ArrayInterface", "LinearAlgebra", "Polyester", "Static", "StaticArrayInterface", "StrideArraysCore"] -git-tree-sha1 = "d1248fceea0b26493fd33e8e9e8c553270da03bd" +git-tree-sha1 = "a6e756a880fc419c8b41592010aebe6a5ce09136" uuid = "7034ab61-46d4-4ed7-9d0f-46aef9175898" -version = "0.2.5" +version = "0.2.8" [[deps.FastClosures]] git-tree-sha1 = "acebe244d53ee1b461970f8910c235b259e772ef" @@ -614,60 +612,78 @@ version = "0.3.2" [[deps.FastGaussQuadrature]] deps = ["LinearAlgebra", "SpecialFunctions", "StaticArrays"] -git-tree-sha1 = "0f478d8bad6f52573fb7658a263af61f3d96e43a" +git-tree-sha1 = "8ef0363cffeedb7e73339b664ce6d33cc278a3c4" uuid = "442a2c76-b920-505d-bb47-c5924d526838" -version = "0.5.1" +version = "1.0.1" [[deps.FastLapackInterface]] deps = ["LinearAlgebra"] -git-tree-sha1 = "c1293a93193f0ae94be7cf338d33e162c39d8788" +git-tree-sha1 = "b12f05108e405dadcc2aff0008db7f831374e051" uuid = "29a986be-02c6-4525-aec4-84b980013641" -version = "1.2.9" +version = "2.0.0" [[deps.FileIO]] deps = ["Pkg", "Requires", "UUIDs"] -git-tree-sha1 = "299dc33549f68299137e51e6d49a13b5b1da9673" +git-tree-sha1 = "c5c28c245101bd59154f649e19b038d15901b5dc" uuid = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" -version = "1.16.1" +version = "1.16.2" [[deps.FilePathsBase]] deps = ["Compat", "Dates", "Mmap", "Printf", "Test", "UUIDs"] -git-tree-sha1 = "e27c4ebe80e8699540f2d6c805cc12203b614f12" +git-tree-sha1 = "9f00e42f8d99fdde64d40c8ea5d14269a2e2c1aa" uuid = "48062228-2e41-5def-b9a4-89aafe57970f" -version = "0.9.20" +version = "0.9.21" [[deps.FileWatching]] uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" [[deps.FillArrays]] -deps = ["LinearAlgebra", "Random", "SparseArrays", "Statistics"] -git-tree-sha1 = "7072f1e3e5a8be51d525d64f63d3ec1287ff2790" +deps = ["LinearAlgebra", "Random"] +git-tree-sha1 = "5b93957f6dcd33fc343044af3d48c215be2562f1" uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "0.13.11" +version = "1.9.3" +weakdeps = ["PDMats", "SparseArrays", "Statistics"] + + [deps.FillArrays.extensions] + FillArraysPDMatsExt = "PDMats" + FillArraysSparseArraysExt = "SparseArrays" + FillArraysStatisticsExt = "Statistics" [[deps.FiniteDiff]] deps = ["ArrayInterface", "LinearAlgebra", "Requires", "Setfield", "SparseArrays"] -git-tree-sha1 = "c6e4a1fbe73b31a3dea94b1da449503b8830c306" +git-tree-sha1 = "73d1214fec245096717847c62d389a5d2ac86504" uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" -version = "2.21.1" -weakdeps = ["BandedMatrices", "BlockBandedMatrices", "StaticArrays"] +version = "2.22.0" [deps.FiniteDiff.extensions] FiniteDiffBandedMatricesExt = "BandedMatrices" FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" FiniteDiffStaticArraysExt = "StaticArrays" + [deps.FiniteDiff.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + [[deps.FixedEffectModels]] -deps = ["DataFrames", "FixedEffects", "LinearAlgebra", "Printf", "Reexport", "Statistics", "StatsAPI", "StatsBase", "StatsFuns", "StatsModels", "Tables", "Vcov"] -git-tree-sha1 = "0c5a7774a7c74deb05a9ff09cc62f1803bb3cfdf" +deps = ["DataFrames", "FixedEffects", "LinearAlgebra", "PrecompileTools", "Printf", "Reexport", "Statistics", "StatsAPI", "StatsBase", "StatsFuns", "StatsModels", "Tables", "Vcov"] +git-tree-sha1 = "8659900a184c342a61c12508c875e9ad4a123777" uuid = "9d5cd8c9-2029-5cab-9928-427838db53e3" -version = "1.8.0" +version = "1.11.0" [[deps.FixedEffects]] -deps = ["GroupedArrays", "LinearAlgebra", "Printf", "Requires", "StatsBase"] -git-tree-sha1 = "c59a77e2f138d1253df164a233be056615f331c3" +deps = ["GroupedArrays", "LinearAlgebra", "Printf", "StatsBase"] +git-tree-sha1 = "4b5de96c36ac13f37cb7c2bfbdecd39d1b5ead5f" uuid = "c8885935-8500-56a7-9867-7708b20db0eb" -version = "2.1.2" +version = "2.3.0" + + [deps.FixedEffects.extensions] + CUDAExt = "CUDA" + MetalExt = "Metal" + + [deps.FixedEffects.weakdeps] + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + Metal = "dde4c033-4e86-420c-a63e-0dd931031962" [[deps.FixedPointNumbers]] deps = ["Statistics"] @@ -689,19 +705,19 @@ version = "0.4.2" [[deps.ForwardDiff]] deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] -git-tree-sha1 = "00e252f4d706b3d55a8863432e742bf5717b498d" +git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "0.10.35" +version = "0.10.36" weakdeps = ["StaticArrays"] [deps.ForwardDiff.extensions] ForwardDiffStaticArraysExt = "StaticArrays" [[deps.FreeType2_jll]] -deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] -git-tree-sha1 = "87eb71354d8ec1a96d4a7636bd57a7347dde3ef9" +deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "d8db6a5a2fe1381c1ea4ef2cab7c69c2de7f9ea0" uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" -version = "2.10.4+0" +version = "2.13.1+0" [[deps.FriBidi_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -725,22 +741,16 @@ deps = ["Random"] uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" [[deps.GLFW_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pkg", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"] -git-tree-sha1 = "d972031d28c8c8d9d7b41a536ad7bb0c2579caca" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll"] +git-tree-sha1 = "ff38ba61beff76b8f4acad8ab0c97ef73bb670cb" uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" -version = "3.3.8+0" +version = "3.3.9+0" [[deps.GLM]] deps = ["Distributions", "LinearAlgebra", "Printf", "Reexport", "SparseArrays", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns", "StatsModels"] -git-tree-sha1 = "97829cfda0df99ddaeaafb5b370d6cab87b7013e" +git-tree-sha1 = "273bd1cd30768a2fddfa3fd63bbc746ed7249e5f" uuid = "38e38edf-8417-5370-95a0-9cbb8c7f171a" -version = "1.8.3" - -[[deps.GPUArrays]] -deps = ["Adapt", "GPUArraysCore", "LLVM", "LinearAlgebra", "Printf", "Random", "Reexport", "Serialization", "Statistics"] -git-tree-sha1 = "a3351bc577a6b49297248aadc23a4add1097c2ac" -uuid = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" -version = "8.7.1" +version = "1.9.0" [[deps.GPUArraysCore]] deps = ["Adapt"] @@ -750,15 +760,15 @@ version = "0.1.5" [[deps.GR]] deps = ["Artifacts", "Base64", "DelimitedFiles", "Downloads", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Pkg", "Preferences", "Printf", "Random", "Serialization", "Sockets", "TOML", "Tar", "Test", "UUIDs", "p7zip_jll"] -git-tree-sha1 = "8b8a2fd4536ece6e554168c21860b6820a8a83db" +git-tree-sha1 = "27442171f28c952804dede8ff72828a96f2bfc1f" uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" -version = "0.72.7" +version = "0.72.10" [[deps.GR_jll]] -deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Qt5Base_jll", "Zlib_jll", "libpng_jll"] -git-tree-sha1 = "19fad9cd9ae44847fe842558a744748084a722d1" +deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "FreeType2_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Qt6Base_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "025d171a2847f616becc0f84c8dc62fe18f0f6dd" uuid = "d2c73de3-f751-5644-a686-071e5b155ba9" -version = "0.72.7+0" +version = "0.72.10+0" [[deps.GenericSchur]] deps = ["LinearAlgebra", "Printf"] @@ -773,10 +783,10 @@ uuid = "78b55507-aeef-58d4-861c-77aaff3498b1" version = "0.21.0+0" [[deps.Glib_jll]] -deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Pkg", "Zlib_jll"] -git-tree-sha1 = "d3b3624125c1474292d0d8ed0f65554ac37ddb23" +deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] +git-tree-sha1 = "e94c92c7bf4819685eb80186d51c43e71d4afa17" uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" -version = "2.74.0+2" +version = "2.76.5+0" [[deps.Graphite2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -786,9 +796,9 @@ version = "1.3.14+0" [[deps.Graphs]] deps = ["ArnoldiMethod", "Compat", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] -git-tree-sha1 = "1cf1d7dcb4bc32d7b4a5add4232db3750c27ecb4" +git-tree-sha1 = "899050ace26649433ef1af25bc17a815b3db52b7" uuid = "86223c79-3864-5bf0-83f7-82e725a168b6" -version = "1.8.0" +version = "1.9.0" [[deps.Grisu]] git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" @@ -796,10 +806,10 @@ uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" version = "1.0.2" [[deps.Groebner]] -deps = ["AbstractAlgebra", "Combinatorics", "Logging", "MultivariatePolynomials", "Primes", "Random"] -git-tree-sha1 = "47f0f03eddecd7ad59c42b1dd46d5f42916aff63" +deps = ["AbstractAlgebra", "Combinatorics", "ExprTools", "Logging", "MultivariatePolynomials", "PrecompileTools", "PrettyTables", "Primes", "Printf", "Random", "SIMD", "TimerOutputs"] +git-tree-sha1 = "6b505ef15e55bdc5bb3ddbcfebdff1c9e67081e8" uuid = "0b43b601-686d-58a3-8a1c-6623616c7cd4" -version = "0.2.11" +version = "0.5.1" [[deps.GroupedArrays]] deps = ["DataAPI", "Missings"] @@ -809,15 +819,15 @@ version = "0.3.3" [[deps.GroupsCore]] deps = ["Markdown", "Random"] -git-tree-sha1 = "9e1a5e9f3b81ad6a5c613d181664a0efc6fe6dd7" +git-tree-sha1 = "6df9cd6ee79fc59feab33f63a1b3c9e95e2461d5" uuid = "d5909c97-4eac-4ecc-a3dc-fdd0858a4120" -version = "0.4.0" +version = "0.4.2" [[deps.HTTP]] -deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] -git-tree-sha1 = "5e77dbf117412d4f164a464d610ee6050cc75272" +deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] +git-tree-sha1 = "abbbb9ec3afd783a7cbd82ef01dcd088ea051398" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.9.6" +version = "1.10.1" [[deps.HarfBuzz_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] @@ -827,27 +837,21 @@ version = "2.8.1+1" [[deps.HostCPUFeatures]] deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Static"] -git-tree-sha1 = "734fd90dd2f920a2f1921d5388dcebe805b262dc" +git-tree-sha1 = "eb8fed28f4994600e29beef49744639d985a04b2" uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" -version = "0.1.14" +version = "0.1.16" [[deps.Hwloc_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "2982b2ec1cb2e2d04b2893e211d29e1e30f8abf4" +git-tree-sha1 = "ca0f6bf568b4bfc807e7537f081c81e35ceca114" uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" -version = "2.9.1+0" +version = "2.10.0+0" [[deps.HypergeometricFunctions]] deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] -git-tree-sha1 = "0ec02c648befc2f94156eaef13b0f38106212f3f" +git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" -version = "0.3.17" - -[[deps.IRTools]] -deps = ["InteractiveUtils", "MacroTools", "Test"] -git-tree-sha1 = "eac00994ce3229a464c2847e956d77a2c64ad3a5" -uuid = "7869d1d1-7146-5819-86e3-90919afe41df" -version = "0.4.10" +version = "0.3.23" [[deps.IfElse]] git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" @@ -861,9 +865,9 @@ uuid = "40713840-3770-5561-ab4c-a76e7d0d7895" version = "0.2.1" [[deps.Inflate]] -git-tree-sha1 = "5cd07aab533df5170988219191dfad0519391428" +git-tree-sha1 = "ea8031dea4aff6bd41f1df8f2fdfb25b33626381" uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" -version = "0.1.3" +version = "0.1.4" [[deps.InlineStrings]] deps = ["Parsers"] @@ -872,15 +876,15 @@ uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" version = "1.4.0" [[deps.IntegerMathUtils]] -git-tree-sha1 = "70f65ced5129d36dbf200b07c51ea8a955294660" +git-tree-sha1 = "b8ffb903da9f7b8cf695a8bead8e01814aa24b30" uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" -version = "0.1.1" +version = "0.1.2" [[deps.IntelOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "0cb9352ef2e01574eeebdb102948a58740dcaf83" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "5fdf2fe6724d8caabf43b557b84ce53f3b7e2f6b" uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2023.1.0+0" +version = "2024.0.2+0" [[deps.InteractiveUtils]] deps = ["Markdown"] @@ -893,10 +897,14 @@ uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" version = "0.14.7" [[deps.IntervalSets]] -deps = ["Dates", "Random", "Statistics"] -git-tree-sha1 = "3f91cd3f56ea48d4d2a75c2a65455c5fc74fa347" +deps = ["Dates", "Random"] +git-tree-sha1 = "3d8866c029dd6b16e69e0d4a939c4dfcb98fac47" uuid = "8197267c-284f-5f27-9208-e0e47529a953" -version = "0.7.3" +version = "0.7.8" +weakdeps = ["Statistics"] + + [deps.IntervalSets.extensions] + IntervalSetsStatisticsExt = "Statistics" [[deps.InvertedIndices]] git-tree-sha1 = "0dc7b50b8d436461be01300fd8cd45aa0274b038" @@ -905,15 +913,15 @@ version = "1.3.0" [[deps.Ipopt]] deps = ["Ipopt_jll", "LinearAlgebra", "MathOptInterface", "OpenBLAS32_jll", "PrecompileTools"] -git-tree-sha1 = "fdb3430a3b7b909bcb5abf9439d61450f49e3e2c" +git-tree-sha1 = "481caf9195288ec5a1968582a8bc14735575ef81" uuid = "b6b21f68-93f8-5de0-b562-5493be1d77c9" -version = "1.4.1" +version = "1.5.1" [[deps.Ipopt_jll]] deps = ["ASL_jll", "Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "MUMPS_seq_jll", "SPRAL_jll", "libblastrampoline_jll"] -git-tree-sha1 = "10aed0bc185360eef63ef34bc02d0bd7c26409d1" +git-tree-sha1 = "f06a7fd68e29c8acc96483d6f163dab58626c4b5" uuid = "9cc047cb-c261-5740-88fc-0cf96f7bdcc7" -version = "300.1400.1300+0" +version = "300.1400.1302+0" [[deps.IrrationalConstants]] git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" @@ -921,9 +929,9 @@ uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" version = "0.2.2" [[deps.IterTools]] -git-tree-sha1 = "4ced6667f9974fc5c5943fa5e2ef1ca43ea9e450" +git-tree-sha1 = "42d5f897009e7ff2cf88db414a389e5ed1bdd023" uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e" -version = "1.8.0" +version = "1.10.0" [[deps.IterableTables]] deps = ["DataValues", "IteratorInterfaceExtensions", "Requires", "TableTraits", "TableTraitsUtils"] @@ -933,9 +941,9 @@ version = "1.0.0" [[deps.IterativeSolvers]] deps = ["LinearAlgebra", "Printf", "Random", "RecipesBase", "SparseArrays"] -git-tree-sha1 = "1169632f425f79429f245113b775a0e3d121457c" +git-tree-sha1 = "b435d190ef8369cf4d79cc9dd5fba88ba0165307" uuid = "42fd0dbc-a981-5370-80f2-aaf504508153" -version = "0.9.2" +version = "0.9.3" [[deps.IteratorInterfaceExtensions]] git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" @@ -944,15 +952,15 @@ version = "1.0.0" [[deps.JLFzf]] deps = ["Pipe", "REPL", "Random", "fzf_jll"] -git-tree-sha1 = "f377670cda23b6b7c1c0b3893e37451c5c1a2185" +git-tree-sha1 = "a53ebe394b71470c7f97c2e7e170d51df21b17af" uuid = "1019f520-868f-41f5-a6de-eb00f4b6a39c" -version = "0.1.5" +version = "0.1.7" [[deps.JLLWrappers]] -deps = ["Preferences"] -git-tree-sha1 = "abc9885a7ca2052a736a600f7fa66209f96506e1" +deps = ["Artifacts", "Preferences"] +git-tree-sha1 = "7e5d6779a1e09a36db2a7b6cff50942a0a7d0fca" uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" -version = "1.4.1" +version = "1.5.0" [[deps.JSON]] deps = ["Dates", "Mmap", "Parsers", "Unicode"] @@ -962,51 +970,49 @@ version = "0.21.4" [[deps.JpegTurbo_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "6f2675ef130a300a112286de91973805fcc5ffbc" +git-tree-sha1 = "60b1194df0a3298f460063de985eae7b01bc011a" uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" -version = "2.1.91+0" +version = "3.0.1+0" [[deps.JuMP]] -deps = ["LinearAlgebra", "MathOptInterface", "MutableArithmetics", "OrderedCollections", "Printf", "SnoopPrecompile", "SparseArrays"] -git-tree-sha1 = "3e4a73edf2ca1bfe97f1fc86eb4364f95ef0fccd" +deps = ["LinearAlgebra", "MacroTools", "MathOptInterface", "MutableArithmetics", "OrderedCollections", "PrecompileTools", "Printf", "SparseArrays"] +git-tree-sha1 = "769d01cf0d3d1f3e59594cc43c8b319b36d7c2a3" uuid = "4076af6c-e467-56ae-b986-b466b2749572" -version = "1.11.1" +version = "1.18.0" + + [deps.JuMP.extensions] + JuMPDimensionalDataExt = "DimensionalData" + + [deps.JuMP.weakdeps] + DimensionalData = "0703355e-b756-11e9-17c0-8b28908087d0" [[deps.JumpProcesses]] -deps = ["ArrayInterface", "DataStructures", "DiffEqBase", "DocStringExtensions", "FunctionWrappers", "Graphs", "LinearAlgebra", "Markdown", "PoissonRandom", "Random", "RandomNumbers", "RecursiveArrayTools", "Reexport", "SciMLBase", "StaticArrays", "TreeViews", "UnPack"] -git-tree-sha1 = "50bd271af7f6cc23be7d24c8c4804809bb5d05ae" +deps = ["ArrayInterface", "DataStructures", "DiffEqBase", "DocStringExtensions", "FunctionWrappers", "Graphs", "LinearAlgebra", "Markdown", "PoissonRandom", "Random", "RandomNumbers", "RecursiveArrayTools", "Reexport", "SciMLBase", "StaticArrays", "UnPack"] +git-tree-sha1 = "c451feb97251965a9fe40bacd62551a72cc5902c" uuid = "ccbc3e58-028d-4f4c-8cd5-9ae44345cda5" -version = "9.6.3" +version = "9.10.1" +weakdeps = ["FastBroadcast"] + + [deps.JumpProcesses.extensions] + JumpProcessFastBroadcastExt = "FastBroadcast" [[deps.KLU]] deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse_jll"] -git-tree-sha1 = "764164ed65c30738750965d55652db9c94c59bfe" +git-tree-sha1 = "884c2968c2e8e7e6bf5956af88cb46aa745c854b" uuid = "ef3ab10e-7fda-4108-b977-705223b18434" -version = "0.4.0" - -[[deps.KernelAbstractions]] -deps = ["Adapt", "Atomix", "InteractiveUtils", "LinearAlgebra", "MacroTools", "PrecompileTools", "SparseArrays", "StaticArrays", "UUIDs", "UnsafeAtomics", "UnsafeAtomicsLLVM"] -git-tree-sha1 = "47be64f040a7ece575c2b5f53ca6da7b548d69f4" -uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.4" +version = "0.4.1" [[deps.KernelDensity]] deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] -git-tree-sha1 = "90442c50e202a5cdf21a7899c66b240fdef14035" +git-tree-sha1 = "fee018a29b60733876eb557804b5b109dd3dd8a7" uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" -version = "0.6.7" +version = "0.6.8" [[deps.Krylov]] deps = ["LinearAlgebra", "Printf", "SparseArrays"] -git-tree-sha1 = "0356a64062656b0cbb43c504ad5de338251f4bda" +git-tree-sha1 = "8a6837ec02fe5fb3def1abc907bb802ef11a0729" uuid = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7" -version = "0.9.1" - -[[deps.KrylovKit]] -deps = ["ChainRulesCore", "GPUArraysCore", "LinearAlgebra", "Printf"] -git-tree-sha1 = "1a5e1d9941c783b0119897d29f2eb665d876ecf3" -uuid = "0b1a1467-8014-51b9-945f-bf0ae24f4b77" -version = "0.6.0" +version = "0.9.5" [[deps.LAME_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -1020,23 +1026,11 @@ git-tree-sha1 = "bf36f528eec6634efc60d7ec062008f171071434" uuid = "88015f11-f218-50d7-93a8-a6af411a945d" version = "3.0.0+1" -[[deps.LLVM]] -deps = ["CEnum", "LLVMExtra_jll", "Libdl", "Printf", "Unicode"] -git-tree-sha1 = "5007c1421563108110bbd57f63d8ad4565808818" -uuid = "929cbde3-209d-540e-8aea-75f648917ca0" -version = "5.2.0" - -[[deps.LLVMExtra_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "1222116d7313cdefecf3d45a2bc1a89c4e7c9217" -uuid = "dad2f222-ce93-54a1-a47d-0025e8a3acab" -version = "0.0.22+0" - [[deps.LLVMOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "f689897ccbe049adb19a065c495e75f372ecd42b" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "d986ce2d884d49126836ea94ed5bfb0f12679713" uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" -version = "15.0.4+0" +version = "15.0.7+0" [[deps.LZO_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -1045,15 +1039,15 @@ uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" version = "2.10.1+0" [[deps.LaTeXStrings]] -git-tree-sha1 = "f2355693d6778a178ade15952b7ac47a4ff97996" +git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" -version = "1.3.0" +version = "1.3.1" [[deps.LabelledArrays]] deps = ["ArrayInterface", "ChainRulesCore", "ForwardDiff", "LinearAlgebra", "MacroTools", "PreallocationTools", "RecursiveArrayTools", "StaticArrays"] -git-tree-sha1 = "cd04158424635efd05ff38d5f55843397b7416a9" +git-tree-sha1 = "f12f2225c999886b69273f84713d1b9cb66faace" uuid = "2ee39098-c373-598a-b85f-a56591580800" -version = "1.14.0" +version = "1.15.0" [[deps.LambertW]] git-tree-sha1 = "c5ffc834de5d61d00d2b0e18c96267cffc21f648" @@ -1062,27 +1056,23 @@ version = "0.4.6" [[deps.Latexify]] deps = ["Formatting", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Printf", "Requires"] -git-tree-sha1 = "8c57307b5d9bb3be1ff2da469063628631d4d51e" +git-tree-sha1 = "f428ae552340899a935973270b8d98e5a31c49fe" uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" -version = "0.15.21" +version = "0.16.1" [deps.Latexify.extensions] DataFramesExt = "DataFrames" - DiffEqBiologicalExt = "DiffEqBiological" - ParameterizedFunctionsExt = "DiffEqBase" SymEngineExt = "SymEngine" [deps.Latexify.weakdeps] DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" - DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e" - DiffEqBiological = "eb300fae-53e8-50a0-950c-e21f52c2b7e0" SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8" [[deps.LayoutPointers]] deps = ["ArrayInterface", "LinearAlgebra", "ManualMemory", "SIMDTypes", "Static", "StaticArrayInterface"] -git-tree-sha1 = "88b8f66b604da079a627b6fb2860d3704a6729a1" +git-tree-sha1 = "62edfee3211981241b57ff1cedf4d74d79519277" uuid = "10f19ff3-798f-405d-979b-55457f8fc047" -version = "0.1.14" +version = "0.1.15" [[deps.Lazy]] deps = ["MacroTools"] @@ -1091,27 +1081,19 @@ uuid = "50d2b5c4-7a5e-59d5-8109-a42b560f39c0" version = "0.15.1" [[deps.LazyArrays]] -deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra", "MacroTools", "MatrixFactorizations", "SparseArrays", "StaticArrays"] -git-tree-sha1 = "7402f6be1a28a05516c6881596879e6d18d28039" +deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra", "MacroTools", "MatrixFactorizations", "SparseArrays"] +git-tree-sha1 = "9cfca23ab83b0dfac93cb1a1ef3331ab9fe596a5" uuid = "5078a376-72f3-5289-bfd5-ec5146d43c02" -version = "0.22.18" +version = "1.8.3" +weakdeps = ["StaticArrays"] + + [deps.LazyArrays.extensions] + LazyArraysStaticArraysExt = "StaticArrays" [[deps.LazyArtifacts]] deps = ["Artifacts", "Pkg"] uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" -[[deps.LazyBandedMatrices]] -deps = ["ArrayLayouts", "BandedMatrices", "BlockArrays", "BlockBandedMatrices", "FillArrays", "LazyArrays", "LinearAlgebra", "MatrixFactorizations", "SparseArrays", "StaticArrays"] -git-tree-sha1 = "034d371419140f14a986ab7325d11f90f30b0c6d" -uuid = "d7e5e226-e90b-4449-9968-0f923699bf6f" -version = "0.7.17" - -[[deps.LeastSquaresOptim]] -deps = ["FiniteDiff", "ForwardDiff", "LinearAlgebra", "Optim", "Printf", "SparseArrays", "Statistics", "SuiteSparse"] -git-tree-sha1 = "cef2dd16402718cf5f412e610813e2ec20d94a64" -uuid = "0fc2ff8b-aaa3-5acd-a817-1944a5e08891" -version = "0.8.4" - [[deps.LevyArea]] deps = ["LinearAlgebra", "Random", "SpecialFunctions"] git-tree-sha1 = "56513a09b8e0ae6485f34401ea9e2f31357958ec" @@ -1121,21 +1103,26 @@ version = "1.0.0" [[deps.LibCURL]] deps = ["LibCURL_jll", "MozillaCACerts_jll"] uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" -version = "0.6.3" +version = "0.6.4" [[deps.LibCURL_jll]] deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "7.84.0+0" +version = "8.4.0+0" [[deps.LibGit2]] -deps = ["Base64", "NetworkOptions", "Printf", "SHA"] +deps = ["Base64", "LibGit2_jll", "NetworkOptions", "Printf", "SHA"] uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" +[[deps.LibGit2_jll]] +deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"] +uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" +version = "1.6.4+0" + [[deps.LibSSH2_jll]] deps = ["Artifacts", "Libdl", "MbedTLS_jll"] uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.10.2+0" +version = "1.11.0+1" [[deps.Libdl]] uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" @@ -1165,10 +1152,10 @@ uuid = "7add5ba3-2f88-524e-9cd5-f83b8a55f7b8" version = "1.42.0+0" [[deps.Libiconv_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "c7cb1f5d892775ba13767a87c7ada0b980ea0a71" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "f9557a255370125b405568f9767d6d195822a175" uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" -version = "1.16.1+2" +version = "1.17.0+0" [[deps.Libmount_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -1177,10 +1164,10 @@ uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" version = "2.35.0+0" [[deps.Libtiff_jll]] -deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "Pkg", "Zlib_jll", "Zstd_jll"] -git-tree-sha1 = "3eb79b0ca5764d4799c06699573fd8f533259713" +deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] +git-tree-sha1 = "2da088d113af58221c52828a80378e16be7d037a" uuid = "89763e89-9b03-5906-acba-b20f662cd828" -version = "4.4.0+0" +version = "4.5.1+1" [[deps.Libuuid_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -1190,9 +1177,9 @@ version = "2.36.0+0" [[deps.LimitedLDLFactorizations]] deps = ["AMD", "LinearAlgebra", "SparseArrays"] -git-tree-sha1 = "422ddab7cac3f51acc5ae23c96e710d07df9a73e" +git-tree-sha1 = "07b3c94ba4decdd855770beddeab9187be03d6b8" uuid = "f5a24dde-3ab7-510b-b81b-6a72c6098d3b" -version = "0.5.0" +version = "0.5.1" [[deps.LineSearches]] deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] @@ -1205,32 +1192,57 @@ deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [[deps.LinearMaps]] -deps = ["LinearAlgebra", "SparseArrays", "Statistics"] -git-tree-sha1 = "a1348b9b7c87d45fa859314d56e8a87ace20561e" +deps = ["LinearAlgebra"] +git-tree-sha1 = "9df2ab050ffefe870a09c7b6afdb0cde381703f2" uuid = "7a12625a-238d-50fd-b39a-03d52299707e" -version = "3.10.1" -weakdeps = ["ChainRulesCore"] +version = "3.11.1" +weakdeps = ["ChainRulesCore", "SparseArrays", "Statistics"] [deps.LinearMaps.extensions] LinearMapsChainRulesCoreExt = "ChainRulesCore" + LinearMapsSparseArraysExt = "SparseArrays" + LinearMapsStatisticsExt = "Statistics" [[deps.LinearSolve]] -deps = ["ArrayInterface", "DocStringExtensions", "EnumX", "FastLapackInterface", "GPUArraysCore", "IterativeSolvers", "KLU", "Krylov", "KrylovKit", "LinearAlgebra", "Preferences", "RecursiveFactorization", "Reexport", "SciMLBase", "SciMLOperators", "Setfield", "SnoopPrecompile", "SparseArrays", "Sparspak", "SuiteSparse", "UnPack"] -git-tree-sha1 = "4a4f8cc7a59fadbb02d1852d1e0cef5dca3a9460" +deps = ["ArrayInterface", "ConcreteStructs", "DocStringExtensions", "EnumX", "FastLapackInterface", "GPUArraysCore", "InteractiveUtils", "KLU", "Krylov", "Libdl", "LinearAlgebra", "MKL_jll", "PrecompileTools", "Preferences", "RecursiveFactorization", "Reexport", "SciMLBase", "SciMLOperators", "Setfield", "SparseArrays", "Sparspak", "StaticArraysCore", "UnPack"] +git-tree-sha1 = "97dc499678d50d989f1a74170840808641ce9880" uuid = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" -version = "1.42.0" +version = "2.22.0" [deps.LinearSolve.extensions] - LinearSolveHYPRE = "HYPRE" + LinearSolveBandedMatricesExt = "BandedMatrices" + LinearSolveBlockDiagonalsExt = "BlockDiagonals" + LinearSolveCUDAExt = "CUDA" + LinearSolveEnzymeExt = ["Enzyme", "EnzymeCore"] + LinearSolveFastAlmostBandedMatricesExt = ["FastAlmostBandedMatrices"] + LinearSolveHYPREExt = "HYPRE" + LinearSolveIterativeSolversExt = "IterativeSolvers" + LinearSolveKernelAbstractionsExt = "KernelAbstractions" + LinearSolveKrylovKitExt = "KrylovKit" + LinearSolveMetalExt = "Metal" + LinearSolvePardisoExt = "Pardiso" + LinearSolveRecursiveArrayToolsExt = "RecursiveArrayTools" [deps.LinearSolve.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + BlockDiagonals = "0a1fb500-61f7-11e9-3c65-f5ef3456f9f0" + CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" + FastAlmostBandedMatrices = "9d29842c-ecb8-4973-b1e9-a27b1157504e" HYPRE = "b5ffcf37-a2bd-41ab-a3da-4bd9bc8ad771" + IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153" + KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" + KrylovKit = "0b1a1467-8014-51b9-945f-bf0ae24f4b77" + Metal = "dde4c033-4e86-420c-a63e-0dd931031962" + Pardiso = "46dd5b70-b6fb-5a00-ae2d-e8fea33afaf2" + RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" [[deps.LogExpFunctions]] deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "c3ce8e7420b3a6e071e0fe4745f5d4300e37b13f" +git-tree-sha1 = "7d6dd4e9212aebaeed356de34ccf262a3cd415aa" uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.24" +version = "0.3.26" [deps.LogExpFunctions.extensions] LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" @@ -1247,15 +1259,15 @@ uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" [[deps.LoggingExtras]] deps = ["Dates", "Logging"] -git-tree-sha1 = "cedb76b37bc5a6c702ade66be44f831fa23c681e" +git-tree-sha1 = "c1dd6d7978c12545b4179fb6153b9250c96b0075" uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" -version = "1.0.0" +version = "1.0.3" [[deps.LoopVectorization]] -deps = ["ArrayInterface", "ArrayInterfaceCore", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] -git-tree-sha1 = "3bb62b5003bc7d2d49f26663484267dc49fa1bf5" +deps = ["ArrayInterface", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] +git-tree-sha1 = "fc712dd664097440f19a91a704299cca02134ca0" uuid = "bdcacae8-1622-11e9-2a5c-532679323890" -version = "0.12.159" +version = "0.12.168" weakdeps = ["ChainRulesCore", "ForwardDiff", "SpecialFunctions"] [deps.LoopVectorization.extensions] @@ -1269,22 +1281,22 @@ uuid = "d00139f3-1899-568f-a2f0-47f597d42d70" version = "5.1.2+0" [[deps.MKL_jll]] -deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "Pkg"] -git-tree-sha1 = "2ce8695e1e699b68702c03402672a69f54b8aca9" +deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "72dc3cf284559eb8f53aa593fe62cb33f83ed0c0" uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2022.2.0+0" +version = "2024.0.0+0" [[deps.MUMPS_seq_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "METIS_jll", "libblastrampoline_jll"] -git-tree-sha1 = "fcf680f6feb85014723f9754ef560173d4a30843" +git-tree-sha1 = "24dd34802044008ef9a596de32d63f3c9ddb7802" uuid = "d7ed1dd3-d0ae-5e8e-bfb4-87a502085b8d" -version = "500.600.0+0" +version = "500.600.100+0" [[deps.MacroTools]] deps = ["Markdown", "Random"] -git-tree-sha1 = "42324d08725e200c23d4dfb549e0d5d89dede2d2" +git-tree-sha1 = "b211c553c199c111d998ecdaf7623d1b89b69f93" uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.10" +version = "0.5.12" [[deps.ManualMemory]] git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" @@ -1297,32 +1309,32 @@ uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" [[deps.MathOptInterface]] deps = ["BenchmarkTools", "CodecBzip2", "CodecZlib", "DataStructures", "ForwardDiff", "JSON", "LinearAlgebra", "MutableArithmetics", "NaNMath", "OrderedCollections", "PrecompileTools", "Printf", "SparseArrays", "SpecialFunctions", "Test", "Unicode"] -git-tree-sha1 = "19a3636968e802918f8891d729c74bd64dff6d00" +git-tree-sha1 = "d2a140e551c9ec9028483e3c7d1244f417567ac0" uuid = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" -version = "1.17.1" - -[[deps.MathProgBase]] -deps = ["LinearAlgebra", "SparseArrays"] -git-tree-sha1 = "9abbe463a1e9fc507f12a69e7f29346c2cdc472c" -uuid = "fdba3010-5040-5b88-9595-932c9decdf73" -version = "0.7.8" +version = "1.24.0" [[deps.MatrixFactorizations]] deps = ["ArrayLayouts", "LinearAlgebra", "Printf", "Random"] -git-tree-sha1 = "0ff59b4b9024ab9a736db1ad902d2b1b48441c19" +git-tree-sha1 = "78f6e33434939b0ac9ba1df81e6d005ee85a7396" uuid = "a3b82374-2e81-5b9e-98ce-41277c0e4c87" -version = "0.9.6" +version = "2.1.0" + +[[deps.MaybeInplace]] +deps = ["ArrayInterface", "LinearAlgebra", "MacroTools", "SparseArrays"] +git-tree-sha1 = "a85c6a98c9e5a2a7046bc1bb89f28a3241e1de4d" +uuid = "bb5d69b7-63fc-4a16-80bd-7e42200c7bdb" +version = "0.1.1" [[deps.MbedTLS]] -deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "Random", "Sockets"] -git-tree-sha1 = "03a9b9718f5682ecb107ac9f7308991db4ce395b" +deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] +git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" uuid = "739be429-bea8-5141-9913-cc70e7f3736d" -version = "1.1.7" +version = "1.1.9" [[deps.MbedTLS_jll]] deps = ["Artifacts", "Libdl"] uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.2+0" +version = "2.28.2+1" [[deps.Measures]] git-tree-sha1 = "c13304c81eec1ed3af7fc20e75fb6b26092a1102" @@ -1346,7 +1358,7 @@ version = "0.7.7" [[deps.MozillaCACerts_jll]] uuid = "14a3606d-f60d-562e-9121-12d972cd8159" -version = "2022.10.11" +version = "2023.1.10" [[deps.MuladdMacro]] git-tree-sha1 = "cac9cc5499c25554cba55cd3c30543cff5ca4fab" @@ -1355,9 +1367,9 @@ version = "0.2.4" [[deps.MultivariatePolynomials]] deps = ["ChainRulesCore", "DataStructures", "LinearAlgebra", "MutableArithmetics"] -git-tree-sha1 = "eaa98afe2033ffc0629f9d0d83961d66a021dfcc" +git-tree-sha1 = "6ffb234d6d7c866a75c1879d2099049d3a35a83a" uuid = "102ac46a-7ee4-5c85-9060-abc95bfdeaa3" -version = "0.4.7" +version = "0.5.3" [[deps.MultivariateStats]] deps = ["Arpack", "LinearAlgebra", "SparseArrays", "Statistics", "StatsAPI", "StatsBase"] @@ -1367,9 +1379,9 @@ version = "0.10.2" [[deps.MutableArithmetics]] deps = ["LinearAlgebra", "SparseArrays", "Test"] -git-tree-sha1 = "964cb1a7069723727025ae295408747a0b36a854" +git-tree-sha1 = "806eea990fb41f9b36f1253e5697aa645bf6a9f8" uuid = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" -version = "1.3.0" +version = "1.4.0" [[deps.NLSolversBase]] deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"] @@ -1378,10 +1390,14 @@ uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" version = "7.8.3" [[deps.NLopt]] -deps = ["MathOptInterface", "MathProgBase", "NLopt_jll"] -git-tree-sha1 = "5a7e32c569200a8a03c3d55d286254b0321cd262" +deps = ["NLopt_jll"] +git-tree-sha1 = "19d2a1c8a3c5b5a459f54a10e54de630c4a05701" uuid = "76087f3c-5699-56af-9a33-bf431cd00edd" -version = "0.6.5" +version = "1.0.0" +weakdeps = ["MathOptInterface"] + + [deps.NLopt.extensions] + NLoptMathOptInterfaceExt = ["MathOptInterface"] [[deps.NLopt_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -1395,18 +1411,6 @@ git-tree-sha1 = "019f12e9a1a7880459d0173c182e6a99365d7ac1" uuid = "2774e3e8-f4cf-5e23-947b-6d7e65073b56" version = "4.5.1" -[[deps.NNlib]] -deps = ["Adapt", "Atomix", "ChainRulesCore", "GPUArraysCore", "KernelAbstractions", "LinearAlgebra", "Pkg", "Random", "Requires", "Statistics"] -git-tree-sha1 = "99e6dbb50d8a96702dc60954569e9fe7291cc55d" -uuid = "872c559c-99b0-510c-b3b7-b6c96a88d5cd" -version = "0.8.20" - - [deps.NNlib.extensions] - NNlibAMDGPUExt = "AMDGPU" - - [deps.NNlib.weakdeps] - AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" - [[deps.NaNMath]] deps = ["OpenLibm_jll"] git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" @@ -1415,30 +1419,57 @@ version = "1.0.2" [[deps.NearestNeighbors]] deps = ["Distances", "StaticArrays"] -git-tree-sha1 = "2c3726ceb3388917602169bed973dbc97f1b51a8" +git-tree-sha1 = "ded64ff6d4fdd1cb68dfcbb818c69e144a5b2e4c" uuid = "b8a86587-4115-5ab1-83bc-aa920d37bbce" -version = "0.4.13" +version = "0.4.16" [[deps.NetworkOptions]] uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" version = "1.2.0" [[deps.NonlinearSolve]] -deps = ["ArrayInterface", "DiffEqBase", "EnumX", "FiniteDiff", "ForwardDiff", "LinearAlgebra", "LinearSolve", "RecursiveArrayTools", "Reexport", "SciMLBase", "SimpleNonlinearSolve", "SnoopPrecompile", "SparseArrays", "SparseDiffTools", "StaticArraysCore", "UnPack"] -git-tree-sha1 = "a6000c813371cd3cd9cbbdf8a356fc3a97138d92" +deps = ["ADTypes", "ArrayInterface", "ConcreteStructs", "DiffEqBase", "EnumX", "FastBroadcast", "FastClosures", "FiniteDiff", "ForwardDiff", "LazyArrays", "LineSearches", "LinearAlgebra", "LinearSolve", "MaybeInplace", "PrecompileTools", "Printf", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "SimpleNonlinearSolve", "SparseArrays", "SparseDiffTools", "StaticArrays", "UnPack"] +git-tree-sha1 = "72b036b728461272ae1b1c3f7096cb4c319d8793" uuid = "8913a72c-1f9b-4ce2-8d82-65094dcecaec" -version = "1.6.0" +version = "3.4.0" + + [deps.NonlinearSolve.extensions] + NonlinearSolveBandedMatricesExt = "BandedMatrices" + NonlinearSolveFastLevenbergMarquardtExt = "FastLevenbergMarquardt" + NonlinearSolveFixedPointAccelerationExt = "FixedPointAcceleration" + NonlinearSolveLeastSquaresOptimExt = "LeastSquaresOptim" + NonlinearSolveMINPACKExt = "MINPACK" + NonlinearSolveNLsolveExt = "NLsolve" + NonlinearSolveSIAMFANLEquationsExt = "SIAMFANLEquations" + NonlinearSolveSpeedMappingExt = "SpeedMapping" + NonlinearSolveSymbolicsExt = "Symbolics" + NonlinearSolveZygoteExt = "Zygote" + + [deps.NonlinearSolve.weakdeps] + BandedMatrices = "aae01518-5342-5314-be14-df237901396f" + FastLevenbergMarquardt = "7a0df574-e128-4d35-8cbd-3d84502bf7ce" + FixedPointAcceleration = "817d07cb-a79a-5c30-9a31-890123675176" + LeastSquaresOptim = "0fc2ff8b-aaa3-5acd-a817-1944a5e08891" + MINPACK = "4854310b-de5a-5eb6-a2a5-c1dee2bd17f9" + NLsolve = "2774e3e8-f4cf-5e23-947b-6d7e65073b56" + SIAMFANLEquations = "084e46ad-d928-497d-ad5e-07fa361a48c4" + SpeedMapping = "f1835b91-879b-4a3f-a438-e4baacf14412" + Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" + Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" [[deps.Observables]] -git-tree-sha1 = "6862738f9796b3edc1c09d0890afce4eca9e7e93" +git-tree-sha1 = "7438a59546cf62428fc9d1bc94729146d37a7225" uuid = "510215fc-4207-5dde-b226-833fc4488ee2" -version = "0.5.4" +version = "0.5.5" [[deps.OffsetArrays]] -deps = ["Adapt"] -git-tree-sha1 = "82d7c9e310fe55aa54996e6f7f94674e2a38fcb4" +git-tree-sha1 = "6a731f2b5c03157418a20c12195eb4b74c8f8621" uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "1.12.9" +version = "1.13.0" +weakdeps = ["Adapt"] + + [deps.OffsetArrays.extensions] + OffsetArraysAdaptExt = "Adapt" [[deps.Ogg_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -1447,20 +1478,20 @@ uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" version = "1.3.5+1" [[deps.OpenBLAS32_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "2fb9ee2dc14d555a6df2a714b86b7125178344c2" +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6065c4cff8fee6c6770b277af45d5082baacdba1" uuid = "656ef2d0-ae68-5445-9ca0-591084a874a2" -version = "0.3.21+0" +version = "0.3.24+0" [[deps.OpenBLAS_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.21+4" +version = "0.3.23+2" [[deps.OpenLibm_jll]] deps = ["Artifacts", "Libdl"] uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.1+0" +version = "0.8.1+2" [[deps.OpenSSL]] deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"] @@ -1470,9 +1501,9 @@ version = "1.4.1" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1aa4b74f80b01c6bc2b89992b861b5f210e665b5" +git-tree-sha1 = "cc6e1927ac521b659af340e0ca45828a3ffc748f" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "1.1.21+0" +version = "3.0.12+0" [[deps.OpenSpecFun_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] @@ -1482,9 +1513,9 @@ version = "0.5.5+0" [[deps.Optim]] deps = ["Compat", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] -git-tree-sha1 = "e3a6546c1577bfd701771b477b794a52949e7594" +git-tree-sha1 = "01f85d9269b13fedc61e63cc72ee2213565f7a72" uuid = "429524aa-4258-5aef-a3af-852621145aeb" -version = "1.7.6" +version = "1.7.8" [[deps.Opus_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -1493,26 +1524,32 @@ uuid = "91d4177d-7536-5919-b921-800302f37372" version = "1.3.2+0" [[deps.OrderedCollections]] -git-tree-sha1 = "d321bf2de576bf25ec4d3e4360faca399afca282" +git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.6.0" +version = "1.6.3" [[deps.OrdinaryDiffEq]] -deps = ["Adapt", "ArrayInterface", "DataStructures", "DiffEqBase", "DocStringExtensions", "ExponentialUtilities", "FastBroadcast", "FastClosures", "FiniteDiff", "ForwardDiff", "FunctionWrappersWrappers", "IfElse", "LineSearches", "LinearAlgebra", "LinearSolve", "Logging", "LoopVectorization", "MacroTools", "MuladdMacro", "NLsolve", "NonlinearSolve", "Polyester", "PreallocationTools", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLNLSolve", "SimpleNonlinearSolve", "SimpleUnPack", "SparseArrays", "SparseDiffTools", "StaticArrayInterface", "StaticArrays", "TruncatedStacktraces"] -git-tree-sha1 = "6ffebfa8971546bace3fc312f9a703795f79f5b9" +deps = ["ADTypes", "Adapt", "ArrayInterface", "DataStructures", "DiffEqBase", "DocStringExtensions", "ExponentialUtilities", "FastBroadcast", "FastClosures", "FillArrays", "FiniteDiff", "ForwardDiff", "FunctionWrappersWrappers", "IfElse", "InteractiveUtils", "LineSearches", "LinearAlgebra", "LinearSolve", "Logging", "LoopVectorization", "MacroTools", "MuladdMacro", "NonlinearSolve", "Polyester", "PreallocationTools", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "SimpleNonlinearSolve", "SimpleUnPack", "SparseArrays", "SparseDiffTools", "StaticArrayInterface", "StaticArrays", "TruncatedStacktraces"] +git-tree-sha1 = "e50bc309307871b5f2ec10075c4faf8ca018068f" uuid = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" -version = "6.51.2" +version = "6.67.0" [[deps.PCRE2_jll]] deps = ["Artifacts", "Libdl"] uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" -version = "10.42.0+0" +version = "10.42.0+1" [[deps.PDMats]] deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "67eae2738d63117a196f497d7db789821bce61d1" +git-tree-sha1 = "949347156c25054de2db3b166c52ac4728cbad65" uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" -version = "0.11.17" +version = "0.11.31" + +[[deps.PackageExtensionCompat]] +git-tree-sha1 = "fb28e33b8a95c4cee25ce296c817d89cc2e53518" +uuid = "65ce6f38-6b18-4e1d-a461-8949797d7930" +version = "1.0.2" +weakdeps = ["Requires", "TOML"] [[deps.Parameters]] deps = ["OrderedCollections", "UnPack"] @@ -1522,9 +1559,9 @@ version = "0.12.3" [[deps.Parsers]] deps = ["Dates", "PrecompileTools", "UUIDs"] -git-tree-sha1 = "a5aef8d4a6e8d81f171b2bd4be5265b01384c74c" +git-tree-sha1 = "8489905bcdbcfac64d1daa51ca07c0d8f0283821" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "2.5.10" +version = "2.8.1" [[deps.Pipe]] git-tree-sha1 = "6842804e7867b115ca9de748a0cf6b364523c16d" @@ -1540,7 +1577,7 @@ version = "0.42.2+0" [[deps.Pkg]] deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.9.0" +version = "1.10.0" [[deps.PlotThemes]] deps = ["PlotUtils", "Statistics"] @@ -1550,15 +1587,15 @@ version = "3.1.0" [[deps.PlotUtils]] deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "Statistics"] -git-tree-sha1 = "f92e1315dadf8c46561fb9396e525f7200cdc227" +git-tree-sha1 = "862942baf5663da528f66d24996eb6da85218e76" uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" -version = "1.3.5" +version = "1.4.0" [[deps.Plots]] deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "JLFzf", "JSON", "LaTeXStrings", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "PrecompileTools", "Preferences", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "RelocatableFolders", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "UUIDs", "UnicodeFun", "UnitfulLatexify", "Unzip"] -git-tree-sha1 = "ceb1ec8d4fbeb02f8817004837d924583707951b" +git-tree-sha1 = "ccee59c6e48e6f2edf8a5b64dc817b6729f99eb5" uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" -version = "1.38.15" +version = "1.39.0" [deps.Plots.extensions] FileIOExt = "FileIO" @@ -1582,9 +1619,9 @@ version = "0.4.4" [[deps.Polyester]] deps = ["ArrayInterface", "BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "ManualMemory", "PolyesterWeave", "Requires", "Static", "StaticArrayInterface", "StrideArraysCore", "ThreadingUtilities"] -git-tree-sha1 = "0fe4e7c4d8ff4c70bfa507f0dd96fa161b115777" +git-tree-sha1 = "fca25670784a1ae44546bcb17288218310af2778" uuid = "f517fe37-dbe3-4b94-8317-1923a5111588" -version = "0.7.3" +version = "0.7.9" [[deps.PolyesterWeave]] deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] @@ -1593,26 +1630,28 @@ uuid = "1d0040c9-8b98-4ee7-8388-3f51789ca0ad" version = "0.2.1" [[deps.Polynomials]] -deps = ["LinearAlgebra", "RecipesBase"] -git-tree-sha1 = "3aa2bb4982e575acd7583f01531f241af077b163" +deps = ["LinearAlgebra", "RecipesBase", "Setfield", "SparseArrays"] +git-tree-sha1 = "a9c7a523d5ed375be3983db190f6a5874ae9286d" uuid = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" -version = "3.2.13" +version = "4.0.6" [deps.Polynomials.extensions] PolynomialsChainRulesCoreExt = "ChainRulesCore" + PolynomialsFFTWExt = "FFTW" PolynomialsMakieCoreExt = "MakieCore" PolynomialsMutableArithmeticsExt = "MutableArithmetics" [deps.Polynomials.weakdeps] ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" [[deps.PooledArrays]] deps = ["DataAPI", "Future"] -git-tree-sha1 = "a6062fe4063cdafe78f4a0a81cfffb89721b30e7" +git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3" uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" -version = "1.4.2" +version = "1.4.3" [[deps.PositiveFactorizations]] deps = ["LinearAlgebra"] @@ -1621,10 +1660,10 @@ uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" version = "0.2.4" [[deps.PreallocationTools]] -deps = ["Adapt", "ArrayInterface", "ForwardDiff", "Requires"] -git-tree-sha1 = "f739b1b3cc7b9949af3b35089931f2b58c289163" +deps = ["Adapt", "ArrayInterface", "ForwardDiff"] +git-tree-sha1 = "64bb68f76f789f5fe5930a80af310f19cdafeaed" uuid = "d236fae5-4411-538c-8e31-a6e3d9e00b46" -version = "0.4.12" +version = "0.4.17" [deps.PreallocationTools.extensions] PreallocationToolsReverseDiffExt = "ReverseDiff" @@ -1634,33 +1673,33 @@ version = "0.4.12" [[deps.PrecompileTools]] deps = ["Preferences"] -git-tree-sha1 = "9673d39decc5feece56ef3940e5dafba15ba0f81" +git-tree-sha1 = "03b4c25b43cb84cee5c90aa9b5ea0a78fd848d2f" uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" -version = "1.1.2" +version = "1.2.0" [[deps.Preconditioners]] deps = ["AlgebraicMultigrid", "LimitedLDLFactorizations", "LinearAlgebra", "SparseArrays"] -git-tree-sha1 = "00187593573e2bbc3c9d8b1f0488f324e6be30b2" +git-tree-sha1 = "a02fc23058e6264b0f73523e99e2dd1a20232dff" uuid = "af69fa37-3177-5a40-98ee-561f696e4fcd" -version = "0.6.0" +version = "0.6.1" [[deps.Preferences]] deps = ["TOML"] -git-tree-sha1 = "7eb1686b4f04b82f96ed7a4ea5890a4f0c7a09f1" +git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.4.0" +version = "1.4.1" [[deps.PrettyTables]] -deps = ["Crayons", "Formatting", "LaTeXStrings", "Markdown", "Reexport", "StringManipulation", "Tables"] -git-tree-sha1 = "213579618ec1f42dea7dd637a42785a608b1ea9c" +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "88b895d13d53b5577fd53379d913b9ab9ac82660" uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "2.2.4" +version = "2.3.1" [[deps.Primes]] deps = ["IntegerMathUtils"] -git-tree-sha1 = "311a2aa90a64076ea0fac2ad7492e914e6feeb81" +git-tree-sha1 = "1d05623b5952aed1307bf8b43bec8b8d1ef94b6e" uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" -version = "0.5.3" +version = "0.5.5" [[deps.Printf]] deps = ["Unicode"] @@ -1672,27 +1711,27 @@ uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" [[deps.ProgressMeter]] deps = ["Distributed", "Printf"] -git-tree-sha1 = "d7a7aef8f8f2d537104f170139553b14dfe39fe9" +git-tree-sha1 = "00099623ffee15972c16111bcf84c58a0051257c" uuid = "92933f4c-e287-5a05-a399-4b506db050ca" -version = "1.7.2" +version = "1.9.0" -[[deps.Qt5Base_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Pkg", "Xorg_libXext_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "xkbcommon_jll"] -git-tree-sha1 = "0c03844e2231e12fda4d0086fd7cbe4098ee8dc5" -uuid = "ea2cea3b-5b76-57ae-a6ef-0a8af62496e1" -version = "5.15.3+2" +[[deps.Qt6Base_jll]] +deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Vulkan_Loader_jll", "Xorg_libSM_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_cursor_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "libinput_jll", "xkbcommon_jll"] +git-tree-sha1 = "37b7bb7aabf9a085e0044307e1717436117f2b3b" +uuid = "c0090381-4147-56d7-9ebc-da0b1113ec56" +version = "6.5.3+1" [[deps.QuadGK]] deps = ["DataStructures", "LinearAlgebra"] -git-tree-sha1 = "6ec7ac8412e83d57e313393220879ede1740f9ee" +git-tree-sha1 = "9ebcd48c498668c7fa0e97a9cae873fbee7bfee1" uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.8.2" +version = "2.9.1" [[deps.QuantEcon]] deps = ["DSP", "DataStructures", "Distributions", "FFTW", "Graphs", "LinearAlgebra", "Markdown", "NLopt", "Optim", "Pkg", "Primes", "Random", "SparseArrays", "SpecialFunctions", "Statistics", "StatsBase", "Test"] -git-tree-sha1 = "4f989614763519b089f4127063c1795d7a412753" +git-tree-sha1 = "034293b29fdbcae73aeb7ca0b2755e693f04701b" uuid = "fcd29c91-0bd7-5a09-975d-7ac3f643a60c" -version = "0.16.5" +version = "0.16.6" [[deps.Query]] deps = ["DataValues", "IterableTables", "MacroTools", "QueryOperators", "Statistics"] @@ -1723,20 +1762,20 @@ deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" [[deps.Random]] -deps = ["SHA", "Serialization"] +deps = ["SHA"] uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" [[deps.Random123]] deps = ["Random", "RandomNumbers"] -git-tree-sha1 = "552f30e847641591ba3f39fd1bed559b9deb0ef3" +git-tree-sha1 = "c860e84651f58ce240dd79e5d9e055d55234c35a" uuid = "74087812-796a-5b5d-8853-05524746bad3" -version = "1.6.1" +version = "1.6.2" [[deps.RandomExtensions]] deps = ["Random", "SparseArrays"] -git-tree-sha1 = "062986376ce6d394b23d5d90f01d81426113a3c9" +git-tree-sha1 = "b8a399e95663485820000f26b6a43c794e166a49" uuid = "fb686558-2515-59ef-acaa-46db3789a887" -version = "0.4.3" +version = "0.4.4" [[deps.RandomNumbers]] deps = ["Random", "Requires"] @@ -1754,12 +1793,6 @@ weakdeps = ["FixedPointNumbers"] [deps.Ratios.extensions] RatiosFixedPointNumbersExt = "FixedPointNumbers" -[[deps.RealDot]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "9f0a1b71baaf7650f4fa8a1d168c7fb6ee41f0c9" -uuid = "c1ae055f-0cd5-4b69-90a6-9a35b1a98df9" -version = "0.1.0" - [[deps.RecipesBase]] deps = ["PrecompileTools"] git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" @@ -1773,26 +1806,30 @@ uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c" version = "0.6.12" [[deps.RecursiveArrayTools]] -deps = ["Adapt", "ArrayInterface", "DocStringExtensions", "GPUArraysCore", "IteratorInterfaceExtensions", "LinearAlgebra", "RecipesBase", "Requires", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables"] -git-tree-sha1 = "02ef02926f30d53b94be443bfaea010c47f6b556" +deps = ["Adapt", "ArrayInterface", "DocStringExtensions", "GPUArraysCore", "IteratorInterfaceExtensions", "LinearAlgebra", "RecipesBase", "Requires", "SparseArrays", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables"] +git-tree-sha1 = "27ee1c03e732c488ecce1a25f0d7da9b5d936574" uuid = "731186ca-8d62-57ce-b412-fbd966d074cd" -version = "2.38.5" +version = "3.3.3" [deps.RecursiveArrayTools.extensions] + RecursiveArrayToolsFastBroadcastExt = "FastBroadcast" RecursiveArrayToolsMeasurementsExt = "Measurements" + RecursiveArrayToolsMonteCarloMeasurementsExt = "MonteCarloMeasurements" RecursiveArrayToolsTrackerExt = "Tracker" RecursiveArrayToolsZygoteExt = "Zygote" [deps.RecursiveArrayTools.weakdeps] + FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" + MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca" Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" [[deps.RecursiveFactorization]] -deps = ["LinearAlgebra", "LoopVectorization", "Polyester", "SnoopPrecompile", "StrideArraysCore", "TriangularSolve"] -git-tree-sha1 = "9088515ad915c99026beb5436d0a09cd8c18163e" +deps = ["LinearAlgebra", "LoopVectorization", "Polyester", "PrecompileTools", "StrideArraysCore", "TriangularSolve"] +git-tree-sha1 = "8bc86c78c7d8e2a5fe559e3721c0f9c9e303b2ed" uuid = "f2c3362d-daeb-58d1-803e-2bc74f2840b4" -version = "0.2.18" +version = "0.2.21" [[deps.Reexport]] git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" @@ -1800,16 +1837,28 @@ uuid = "189a3867-3050-52da-a836-e630ba90ab69" version = "1.2.2" [[deps.RegressionTables]] -deps = ["Compat", "Distributions", "FixedEffectModels", "Formatting", "GLM", "Statistics", "StatsBase", "StatsModels", "UnPack"] -git-tree-sha1 = "129bad054effa2b5cb3e2cded441ad316f918b2e" +deps = ["Distributions", "Formatting", "Statistics", "StatsAPI", "StatsBase", "StatsModels"] +git-tree-sha1 = "06c8c14778b921c7d0d588b57315efc6624ab883" uuid = "d519eb52-b820-54da-95a6-98e1306fdade" -version = "0.5.9" +version = "0.6.1" + + [deps.RegressionTables.extensions] + RegressionTablesFixedEffectModelsExt = "FixedEffectModels" + RegressionTablesGLFixedEffectModelsExt = "GLFixedEffectModels" + RegressionTablesGLMExt = "GLM" + RegressionTablesMixedModelsExt = "MixedModels" + + [deps.RegressionTables.weakdeps] + FixedEffectModels = "9d5cd8c9-2029-5cab-9928-427838db53e3" + GLFixedEffectModels = "bafb0ae5-e5f5-5100-81b6-6a55d777c812" + GLM = "38e38edf-8417-5370-95a0-9cbb8c7f171a" + MixedModels = "ff71e718-51f3-5ec2-a782-8ffcbfa3c316" [[deps.RelocatableFolders]] deps = ["SHA", "Scratch"] -git-tree-sha1 = "90bc7a7c96410424509e4263e277e43250c05691" +git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" -version = "1.0.0" +version = "1.0.1" [[deps.Requires]] deps = ["UUIDs"] @@ -1837,30 +1886,38 @@ version = "0.4.0+0" [[deps.Roots]] deps = ["ChainRulesCore", "CommonSolve", "Printf", "Setfield"] -git-tree-sha1 = "de432823e8aab4dd1a985be4be768f95acf152d4" +git-tree-sha1 = "0f1d92463a020321983d04c110f476c274bafe2e" uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -version = "2.0.17" +version = "2.0.22" [deps.Roots.extensions] RootsForwardDiffExt = "ForwardDiff" RootsIntervalRootFindingExt = "IntervalRootFinding" RootsSymPyExt = "SymPy" + RootsSymPyPythonCallExt = "SymPyPythonCall" [deps.Roots.weakdeps] ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" IntervalRootFinding = "d2bf35a9-74e0-55ec-b149-d360ff49b807" SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" + SymPyPythonCall = "bc8888f7-b21e-4b7c-a06a-5d9c9496438c" [[deps.RuntimeGeneratedFunctions]] deps = ["ExprTools", "SHA", "Serialization"] -git-tree-sha1 = "237edc1563bbf078629b4f8d194bd334e97907cf" +git-tree-sha1 = "6aacc5eefe8415f47b3e34214c1d79d2674a0ba2" uuid = "7e49a35a-f44a-4d26-94aa-eba1b4ca6b47" -version = "0.5.11" +version = "0.5.12" [[deps.SHA]] uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" version = "0.7.0" +[[deps.SIMD]] +deps = ["PrecompileTools"] +git-tree-sha1 = "d8911cc125da009051fb35322415641d02d9e37f" +uuid = "fdea26ae-647d-5447-a871-4b548cad5224" +version = "3.4.6" + [[deps.SIMDTypes]] git-tree-sha1 = "330289636fb8107c5f32088d2741e9fd7a061a5c" uuid = "94e857df-77ce-4151-89e5-788b33177be4" @@ -1868,45 +1925,56 @@ version = "0.1.0" [[deps.SLEEFPirates]] deps = ["IfElse", "Static", "VectorizationBase"] -git-tree-sha1 = "4b8586aece42bee682399c4c4aee95446aa5cd19" +git-tree-sha1 = "3aac6d68c5e57449f5b9b865c9ba50ac2970c4cf" uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" -version = "0.6.39" +version = "0.6.42" [[deps.SPRAL_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "Libdl", "METIS_jll", "libblastrampoline_jll"] -git-tree-sha1 = "6dc840d44f2081ac112d29f1d7b9446054d6e763" +git-tree-sha1 = "d1ca34081034a9c6903cfbe068a952a739c2aa5c" uuid = "319450e9-13b8-58e8-aa9f-8fd1420848ab" -version = "2023.3.29+0" +version = "2023.8.2+0" [[deps.SciMLBase]] -deps = ["ADTypes", "ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "PrecompileTools", "Preferences", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables", "TruncatedStacktraces"] -git-tree-sha1 = "ddf57a23d610d30d0c4bd01132f4646a2a77d171" +deps = ["ADTypes", "ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "FillArrays", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "PrecompileTools", "Preferences", "Printf", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables", "TruncatedStacktraces"] +git-tree-sha1 = "09324a0ae70c52a45b91b236c62065f78b099c37" uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" -version = "1.92.5" - -[[deps.SciMLNLSolve]] -deps = ["DiffEqBase", "LineSearches", "NLsolve", "Reexport", "SciMLBase"] -git-tree-sha1 = "2d00015fa0a190220dc5605406b85073f6634391" -uuid = "e9a6253c-8580-4d32-9898-8661bb511710" -version = "0.1.7" +version = "2.15.2" + + [deps.SciMLBase.extensions] + SciMLBaseChainRulesCoreExt = "ChainRulesCore" + SciMLBasePartialFunctionsExt = "PartialFunctions" + SciMLBasePyCallExt = "PyCall" + SciMLBasePythonCallExt = "PythonCall" + SciMLBaseRCallExt = "RCall" + SciMLBaseZygoteExt = "Zygote" + + [deps.SciMLBase.weakdeps] + ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + PartialFunctions = "570af359-4316-4cb7-8c74-252c00c2016b" + PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" + PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d" + RCall = "6f49c342-dc21-5d91-9882-a32aef131414" + Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" [[deps.SciMLOperators]] deps = ["ArrayInterface", "DocStringExtensions", "Lazy", "LinearAlgebra", "Setfield", "SparseArrays", "StaticArraysCore", "Tricks"] -git-tree-sha1 = "6a657a73322170eec86fb427661dbee079b85bff" +git-tree-sha1 = "51ae235ff058a64815e0a2c34b1db7578a06813d" uuid = "c0aeaf25-5076-4817-a8d5-81caf7dfa961" -version = "0.2.12" +version = "0.3.7" [[deps.Scratch]] deps = ["Dates"] -git-tree-sha1 = "30449ee12237627992a99d5e30ae63e4d78cd24a" +git-tree-sha1 = "3bac05bc7e74a75fd9cba4295cde4045d9fe2386" uuid = "6c6a2e73-6563-6170-7368-637461726353" -version = "1.2.0" +version = "1.2.1" [[deps.SentinelArrays]] deps = ["Dates", "Random"] -git-tree-sha1 = "04bdff0b09c65ff3e06a05e3eb7b120223da3d39" +git-tree-sha1 = "0e7508ff27ba32f26cd459474ca2ede1bc10991f" uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" -version = "1.4.0" +version = "1.4.1" [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" @@ -1938,14 +2006,16 @@ uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" version = "1.1.0" [[deps.SimpleNonlinearSolve]] -deps = ["ArrayInterface", "DiffEqBase", "FiniteDiff", "ForwardDiff", "LinearAlgebra", "PrecompileTools", "Reexport", "Requires", "SciMLBase", "StaticArraysCore"] -git-tree-sha1 = "7c55a3e65aad4ce6e610409cdd564b8d590b9726" +deps = ["ADTypes", "ArrayInterface", "ConcreteStructs", "DiffEqBase", "FiniteDiff", "ForwardDiff", "LinearAlgebra", "MaybeInplace", "PrecompileTools", "Reexport", "SciMLBase", "StaticArraysCore"] +git-tree-sha1 = "8d672bd91dc432fb286b6d4bcf1a5dc417e932a3" uuid = "727e6d20-b764-4bd8-a329-72de5adea6c7" -version = "0.1.15" -weakdeps = ["NNlib"] +version = "1.2.0" [deps.SimpleNonlinearSolve.extensions] - SimpleBatchedNonlinearSolveExt = "NNlib" + SimpleNonlinearSolvePolyesterForwardDiffExt = "PolyesterForwardDiff" + + [deps.SimpleNonlinearSolve.weakdeps] + PolyesterForwardDiff = "98d1487c-24ca-40b6-b7ab-df2af84e126b" [[deps.SimpleTraits]] deps = ["InteractiveUtils", "MacroTools"] @@ -1958,30 +2028,35 @@ git-tree-sha1 = "58e6353e72cde29b90a69527e56df1b5c3d8c437" uuid = "ce78b400-467f-4804-87d8-8f486da07d0a" version = "1.1.0" -[[deps.SnoopPrecompile]] -deps = ["Preferences"] -git-tree-sha1 = "e760a70afdcd461cf01a575947738d359234665c" -uuid = "66db9d55-30c0-4569-8b51-7e840670fc0c" -version = "1.0.3" - [[deps.Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" [[deps.SortingAlgorithms]] deps = ["DataStructures"] -git-tree-sha1 = "a4ada03f999bd01b3a25dcaa30b2d929fe537e00" +git-tree-sha1 = "66e0a8e672a0bdfca2c3f5937efb8538b9ddc085" uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "1.1.0" +version = "1.2.1" [[deps.SparseArrays]] deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" +version = "1.10.0" [[deps.SparseDiffTools]] -deps = ["Adapt", "ArrayInterface", "Compat", "DataStructures", "FiniteDiff", "ForwardDiff", "Graphs", "LinearAlgebra", "Requires", "SparseArrays", "StaticArrays", "VertexSafeGraphs"] -git-tree-sha1 = "e19ac47477c9a8fcca06dab5e5471417d5d9d723" +deps = ["ADTypes", "Adapt", "ArrayInterface", "Compat", "DataStructures", "FiniteDiff", "ForwardDiff", "Graphs", "LinearAlgebra", "PackageExtensionCompat", "Random", "Reexport", "SciMLOperators", "Setfield", "SparseArrays", "StaticArrayInterface", "StaticArrays", "Tricks", "UnPack", "VertexSafeGraphs"] +git-tree-sha1 = "c281e11db4eacb36a292a054bac83c5a0aca2a26" uuid = "47a9eef4-7e08-11e9-0b38-333d64bd3804" -version = "1.31.0" +version = "2.15.0" + + [deps.SparseDiffTools.extensions] + SparseDiffToolsEnzymeExt = "Enzyme" + SparseDiffToolsSymbolicsExt = "Symbolics" + SparseDiffToolsZygoteExt = "Zygote" + + [deps.SparseDiffTools.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" + Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" [[deps.Sparspak]] deps = ["Libdl", "LinearAlgebra", "Logging", "OffsetArrays", "Printf", "SparseArrays", "Test"] @@ -1989,16 +2064,11 @@ git-tree-sha1 = "342cf4b449c299d8d1ceaf00b7a49f4fbc7940e7" uuid = "e56a9233-b9d6-4f03-8d0f-1825330902ac" version = "0.3.9" -[[deps.SpatialIndexing]] -git-tree-sha1 = "bacf5065cd7c0d6449b8bba6fa8e75b3087356b0" -uuid = "d4ead438-fe20-5cc5-a293-4fd39a41b74c" -version = "0.1.5" - [[deps.SpecialFunctions]] deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "ef28127915f4229c971eb43f3fc075dd3fe91880" +git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.2.0" +version = "2.3.1" weakdeps = ["ChainRulesCore"] [deps.SpecialFunctions.extensions] @@ -2006,15 +2076,15 @@ weakdeps = ["ChainRulesCore"] [[deps.Static]] deps = ["IfElse"] -git-tree-sha1 = "dbde6766fc677423598138a5951269432b0fcc90" +git-tree-sha1 = "f295e0a1da4ca425659c57441bcb59abb035a4bc" uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" -version = "0.8.7" +version = "0.8.8" [[deps.StaticArrayInterface]] -deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "Requires", "SnoopPrecompile", "SparseArrays", "Static", "SuiteSparse"] -git-tree-sha1 = "33040351d2403b84afce74dae2e22d3f5b18edcb" +deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Requires", "SparseArrays", "Static", "SuiteSparse"] +git-tree-sha1 = "5d66818a39bb04bf328e92bc933ec5b4ee88e436" uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" -version = "1.4.0" +version = "1.5.0" weakdeps = ["OffsetArrays", "StaticArrays"] [deps.StaticArrayInterface.extensions] @@ -2022,32 +2092,37 @@ weakdeps = ["OffsetArrays", "StaticArrays"] StaticArrayInterfaceStaticArraysExt = "StaticArrays" [[deps.StaticArrays]] -deps = ["LinearAlgebra", "Random", "StaticArraysCore", "Statistics"] -git-tree-sha1 = "832afbae2a45b4ae7e831f86965469a24d1d8a83" +deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] +git-tree-sha1 = "4e17a790909b17f7bf1496e3aec138cf01b60b3b" uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.5.26" +version = "1.9.0" +weakdeps = ["ChainRulesCore", "Statistics"] + + [deps.StaticArrays.extensions] + StaticArraysChainRulesCoreExt = "ChainRulesCore" + StaticArraysStatisticsExt = "Statistics" [[deps.StaticArraysCore]] -git-tree-sha1 = "6b7ba252635a5eff6a0b0664a41ee140a1c9e72a" +git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.0" +version = "1.4.2" [[deps.Statistics]] deps = ["LinearAlgebra", "SparseArrays"] uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -version = "1.9.0" +version = "1.10.0" [[deps.StatsAPI]] deps = ["LinearAlgebra"] -git-tree-sha1 = "45a7769a04a3cf80da1c1c7c60caf932e6f4c9f7" +git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" -version = "1.6.0" +version = "1.7.0" [[deps.StatsBase]] deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] -git-tree-sha1 = "d1bf48bfcc554a3761a133fe3a9bb01488e06916" +git-tree-sha1 = "1d77abd07f617c4868c33d4f5b9e1dbb2643c9cf" uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -version = "0.33.21" +version = "0.34.2" [[deps.StatsFuns]] deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] @@ -2064,72 +2139,81 @@ version = "1.3.0" InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" [[deps.StatsModels]] -deps = ["DataAPI", "DataStructures", "LinearAlgebra", "Printf", "REPL", "ShiftedArrays", "SparseArrays", "StatsBase", "StatsFuns", "Tables"] -git-tree-sha1 = "a5e15f27abd2692ccb61a99e0854dfb7d48017db" +deps = ["DataAPI", "DataStructures", "LinearAlgebra", "Printf", "REPL", "ShiftedArrays", "SparseArrays", "StatsAPI", "StatsBase", "StatsFuns", "Tables"] +git-tree-sha1 = "5cf6c4583533ee38639f73b880f35fc85f2941e0" uuid = "3eaba693-59b7-5ba5-a881-562e759f1c8d" -version = "0.6.33" +version = "0.7.3" [[deps.StatsPlots]] deps = ["AbstractFFTs", "Clustering", "DataStructures", "Distributions", "Interpolations", "KernelDensity", "LinearAlgebra", "MultivariateStats", "NaNMath", "Observables", "Plots", "RecipesBase", "RecipesPipeline", "Reexport", "StatsBase", "TableOperations", "Tables", "Widgets"] -git-tree-sha1 = "14ef622cf28b05e38f8af1de57bc9142b03fbfe3" +git-tree-sha1 = "9115a29e6c2cf66cf213ccc17ffd61e27e743b24" uuid = "f3b207a7-027a-5e70-b257-86293d7955fd" -version = "0.15.5" +version = "0.15.6" [[deps.StochasticDiffEq]] -deps = ["Adapt", "ArrayInterface", "DataStructures", "DiffEqBase", "DiffEqNoiseProcess", "DocStringExtensions", "FillArrays", "FiniteDiff", "ForwardDiff", "JumpProcesses", "LevyArea", "LinearAlgebra", "Logging", "MuladdMacro", "NLsolve", "OrdinaryDiffEq", "Random", "RandomNumbers", "RecursiveArrayTools", "Reexport", "SciMLBase", "SparseArrays", "SparseDiffTools", "StaticArrays", "UnPack"] -git-tree-sha1 = "073da86200349ddf4ef8bc3e3f3acd62e1d554f7" +deps = ["Adapt", "ArrayInterface", "DataStructures", "DiffEqBase", "DiffEqNoiseProcess", "DocStringExtensions", "FiniteDiff", "ForwardDiff", "JumpProcesses", "LevyArea", "LinearAlgebra", "Logging", "MuladdMacro", "NLsolve", "OrdinaryDiffEq", "Random", "RandomNumbers", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "SparseArrays", "SparseDiffTools", "StaticArrays", "UnPack"] +git-tree-sha1 = "753219de57ac7aab0feb88871d3c51e0eb5e3b03" uuid = "789caeaf-c7a9-5a7d-9973-96adeb23e2a0" -version = "6.60.0" +version = "6.64.0" [[deps.StrideArraysCore]] deps = ["ArrayInterface", "CloseOpenIntervals", "IfElse", "LayoutPointers", "ManualMemory", "SIMDTypes", "Static", "StaticArrayInterface", "ThreadingUtilities"] -git-tree-sha1 = "602a8bef17c744f1de965979398597dfa50e1a2f" +git-tree-sha1 = "d6415f66f3d89c615929af907fdc6a3e17af0d8c" uuid = "7792a7ef-975c-4747-a70f-980b88e8d1da" -version = "0.4.15" +version = "0.5.2" [[deps.StringManipulation]] -git-tree-sha1 = "46da2434b41f41ac3594ee9816ce5541c6096123" +deps = ["PrecompileTools"] +git-tree-sha1 = "a04cabe79c5f01f4d723cc6704070ada0b9d46d5" uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" -version = "0.3.0" - -[[deps.StructArrays]] -deps = ["Adapt", "DataAPI", "GPUArraysCore", "StaticArraysCore", "Tables"] -git-tree-sha1 = "521a0e828e98bb69042fec1809c1b5a680eb7389" -uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" -version = "0.6.15" +version = "0.3.4" [[deps.SuiteSparse]] deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" [[deps.SuiteSparse_jll]] -deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] +deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "5.10.1+6" +version = "7.2.1+1" [[deps.SymbolicIndexingInterface]] -deps = ["DocStringExtensions"] -git-tree-sha1 = "f8ab052bfcbdb9b48fad2c80c873aa0d0344dfe5" +git-tree-sha1 = "9336430df9a96f7d85268304b6c3b93f92fb7ff2" uuid = "2efcf032-c050-4f8e-a9bb-153293bab1f5" -version = "0.2.2" +version = "0.3.2" [[deps.SymbolicUtils]] -deps = ["AbstractTrees", "Bijections", "ChainRulesCore", "Combinatorics", "ConstructionBase", "DataStructures", "DocStringExtensions", "DynamicPolynomials", "IfElse", "LabelledArrays", "LinearAlgebra", "MultivariatePolynomials", "NaNMath", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "TimerOutputs", "Unityper"] -git-tree-sha1 = "5cb1f963f82e7b81305102dd69472fcd3e0e1483" +deps = ["AbstractTrees", "Bijections", "ChainRulesCore", "Combinatorics", "ConstructionBase", "DataStructures", "DocStringExtensions", "DynamicPolynomials", "IfElse", "LabelledArrays", "LinearAlgebra", "MultivariatePolynomials", "NaNMath", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicIndexingInterface", "TimerOutputs", "Unityper"] +git-tree-sha1 = "849b1dfb1680a9e9f2c6023f79a49b694fb6d0da" uuid = "d1185830-fcd6-423d-90d6-eec64667417b" -version = "1.0.5" +version = "1.5.0" [[deps.Symbolics]] -deps = ["ArrayInterface", "ConstructionBase", "DataStructures", "DiffRules", "Distributions", "DocStringExtensions", "DomainSets", "Groebner", "IfElse", "LaTeXStrings", "LambertW", "Latexify", "Libdl", "LinearAlgebra", "MacroTools", "Markdown", "NaNMath", "RecipesBase", "Reexport", "Requires", "RuntimeGeneratedFunctions", "SciMLBase", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicUtils", "TreeViews"] -git-tree-sha1 = "fce1fd0b13f860128c8b8aab0bab475eeeeb7994" +deps = ["ArrayInterface", "Bijections", "ConstructionBase", "DataStructures", "DiffRules", "Distributions", "DocStringExtensions", "DomainSets", "DynamicPolynomials", "Groebner", "IfElse", "LaTeXStrings", "LambertW", "Latexify", "Libdl", "LinearAlgebra", "LogExpFunctions", "MacroTools", "Markdown", "NaNMath", "PrecompileTools", "RecipesBase", "Reexport", "Requires", "RuntimeGeneratedFunctions", "SciMLBase", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicIndexingInterface", "SymbolicUtils"] +git-tree-sha1 = "29856d1168412550fcd74f76ea5560bc2cac06ee" uuid = "0c5d862f-8b57-4792-8d23-62f2024744c7" -version = "5.1.0" +version = "5.15.1" + + [deps.Symbolics.extensions] + SymbolicsPreallocationToolsExt = ["ForwardDiff", "PreallocationTools"] + SymbolicsSymPyExt = "SymPy" + + [deps.Symbolics.weakdeps] + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + PreallocationTools = "d236fae5-4411-538c-8e31-a6e3d9e00b46" + SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" [[deps.TOML]] deps = ["Dates"] uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" version = "1.0.3" +[[deps.TZJData]] +deps = ["Artifacts"] +git-tree-sha1 = "d39314cdbaf5b90a047db33858626f8d1cc973e1" +uuid = "dc5dba14-91b3-4cab-a142-028a31da12f7" +version = "1.0.0+2023c" + [[deps.TableOperations]] deps = ["SentinelArrays", "Tables", "Test"] git-tree-sha1 = "e383c87cf2a1dc41fa30c093b2a19877c83e1bc1" @@ -2137,10 +2221,10 @@ uuid = "ab02a1b2-a7df-11e8-156e-fb1833f50b87" version = "1.2.0" [[deps.TableShowUtils]] -deps = ["DataValues", "Dates", "JSON", "Markdown", "Test"] -git-tree-sha1 = "14c54e1e96431fb87f0d2f5983f090f1b9d06457" +deps = ["DataValues", "Dates", "JSON", "Markdown", "Unicode"] +git-tree-sha1 = "2a41a3dedda21ed1184a47caab56ed9304e9a038" uuid = "5e66a065-1f0a-5976-b372-e0b8c017ca10" -version = "0.2.5" +version = "0.2.6" [[deps.TableTraits]] deps = ["IteratorInterfaceExtensions"] @@ -2155,10 +2239,10 @@ uuid = "382cd787-c1b6-5bf2-a167-d5b971a19bda" version = "1.0.2" [[deps.Tables]] -deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits", "Test"] -git-tree-sha1 = "1544b926975372da01227b382066ab70e574a3ec" +deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] +git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "1.10.1" +version = "1.11.1" [[deps.Tar]] deps = ["ArgTools", "SHA"] @@ -2177,15 +2261,19 @@ uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.ThreadingUtilities]] deps = ["ManualMemory"] -git-tree-sha1 = "c97f60dd4f2331e1a495527f80d242501d2f9865" +git-tree-sha1 = "eda08f7e9818eb53661b3deb74e3159460dfbc27" uuid = "8290d209-cae3-49c0-8002-c8c24d57dab5" -version = "0.5.1" +version = "0.5.2" [[deps.TimeZones]] -deps = ["Dates", "Downloads", "InlineStrings", "LazyArtifacts", "Mocking", "Printf", "RecipesBase", "Scratch", "Unicode"] -git-tree-sha1 = "cdaa0c2a4449724aded839550eca7d7240bb6938" +deps = ["Artifacts", "Dates", "Downloads", "InlineStrings", "LazyArtifacts", "Mocking", "Printf", "Scratch", "TZJData", "Unicode", "p7zip_jll"] +git-tree-sha1 = "89e64d61ef3cd9e80f7fc12b7d13db2d75a23c03" uuid = "f269a46b-ccf7-5d73-abea-4c690281aa53" -version = "1.10.0" +version = "1.13.0" +weakdeps = ["RecipesBase"] + + [deps.TimeZones.extensions] + TimeZonesRecipesBaseExt = "RecipesBase" [[deps.TimerOutputs]] deps = ["ExprTools", "Printf"] @@ -2194,38 +2282,35 @@ uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" version = "0.5.23" [[deps.TranscodingStreams]] -deps = ["Random", "Test"] -git-tree-sha1 = "9a6ae7ed916312b41236fcef7e0af564ef934769" +git-tree-sha1 = "1fbeaaca45801b4ba17c251dd8603ef24801dd84" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.9.13" +version = "0.10.2" +weakdeps = ["Random", "Test"] -[[deps.TreeViews]] -deps = ["Test"] -git-tree-sha1 = "8d0d7a3fe2f30d6a7f833a5f19f7c7a5b396eae6" -uuid = "a2a6695c-b41b-5b7d-aed9-dbfdeacea5d7" -version = "0.3.0" + [deps.TranscodingStreams.extensions] + TestExt = ["Test", "Random"] [[deps.TriangularSolve]] deps = ["CloseOpenIntervals", "IfElse", "LayoutPointers", "LinearAlgebra", "LoopVectorization", "Polyester", "Static", "VectorizationBase"] -git-tree-sha1 = "31eedbc0b6d07c08a700e26d31298ac27ef330eb" +git-tree-sha1 = "fadebab77bf3ae041f77346dd1c290173da5a443" uuid = "d5829a12-d9aa-46ab-831f-fb7c9ab06edf" -version = "0.1.19" +version = "0.1.20" [[deps.Tricks]] -git-tree-sha1 = "aadb748be58b492045b4f56166b5188aa63ce549" +git-tree-sha1 = "eae1bb484cd63b36999ee58be2de6c178105112f" uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" -version = "0.1.7" +version = "0.1.8" [[deps.TruncatedStacktraces]] deps = ["InteractiveUtils", "MacroTools", "Preferences"] -git-tree-sha1 = "7bc1632a4eafbe9bd94cf1a784a9a4eb5e040a91" +git-tree-sha1 = "ea3e54c2bdde39062abf5a9758a23735558705e1" uuid = "781d530d-4396-4725-bb49-402e4bee1e77" -version = "1.3.0" +version = "1.4.0" [[deps.URIs]] -git-tree-sha1 = "074f993b0ca030848b897beff716d93aca60f06a" +git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b" uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" -version = "1.4.2" +version = "1.5.1" [[deps.UUIDs]] deps = ["Random", "SHA"] @@ -2246,15 +2331,17 @@ uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" version = "0.4.1" [[deps.Unitful]] -deps = ["ConstructionBase", "Dates", "LinearAlgebra", "Random"] -git-tree-sha1 = "ba4aa36b2d5c98d6ed1f149da916b3ba46527b2b" +deps = ["Dates", "LinearAlgebra", "Random"] +git-tree-sha1 = "3c793be6df9dd77a0cf49d80984ef9ff996948fa" uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" -version = "1.14.0" +version = "1.19.0" [deps.Unitful.extensions] + ConstructionBaseUnitfulExt = "ConstructionBase" InverseFunctionsUnitfulExt = "InverseFunctions" [deps.Unitful.weakdeps] + ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" [[deps.UnitfulLatexify]] @@ -2265,20 +2352,9 @@ version = "1.6.3" [[deps.Unityper]] deps = ["ConstructionBase"] -git-tree-sha1 = "d5f4ec8c22db63bd3ccb239f640e895cfde145aa" +git-tree-sha1 = "25008b734a03736c41e2a7dc314ecb95bd6bbdb0" uuid = "a7c27f48-0311-42f6-a7f8-2c11e75eb415" -version = "0.1.2" - -[[deps.UnsafeAtomics]] -git-tree-sha1 = "6331ac3440856ea1988316b46045303bef658278" -uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" -version = "0.2.1" - -[[deps.UnsafeAtomicsLLVM]] -deps = ["LLVM", "UnsafeAtomics"] -git-tree-sha1 = "ea37e6066bf194ab78f4e747f5245261f17a7175" -uuid = "d80eeb9a-aca5-4d75-85e5-170c8b632249" -version = "0.1.2" +version = "0.1.6" [[deps.Unzip]] git-tree-sha1 = "ca0969166a028236229f63514992fc073799bb78" @@ -2287,15 +2363,15 @@ version = "0.2.0" [[deps.Vcov]] deps = ["Combinatorics", "GroupedArrays", "LinearAlgebra", "StatsAPI", "StatsBase", "Tables"] -git-tree-sha1 = "7391d297ff5bff38c7158f0e04aaf2f4974b74ba" +git-tree-sha1 = "22491492d601448b0fef54afe8a5bdfd67282965" uuid = "ec2bfdc2-55df-4fc9-b9ae-4958c2cf2486" -version = "0.7.1" +version = "0.8.1" [[deps.VectorizationBase]] deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] -git-tree-sha1 = "b182207d4af54ac64cbc71797765068fdeff475d" +git-tree-sha1 = "7209df901e6ed7489fe9b7aa3e46fb788e15db85" uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" -version = "0.21.64" +version = "0.21.65" [[deps.VertexSafeGraphs]] deps = ["Graphs"] @@ -2303,17 +2379,23 @@ git-tree-sha1 = "8351f8d73d7e880bfc042a8b6922684ebeafb35c" uuid = "19fa3120-7c27-5ec5-8db8-b0b0aa330d6f" version = "0.2.0" +[[deps.Vulkan_Loader_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Wayland_jll", "Xorg_libX11_jll", "Xorg_libXrandr_jll", "xkbcommon_jll"] +git-tree-sha1 = "2f0486047a07670caad3a81a075d2e518acc5c59" +uuid = "a44049a8-05dd-5a78-86c9-5fde0876e88c" +version = "1.3.243+0" + [[deps.Wayland_jll]] -deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg", "XML2_jll"] -git-tree-sha1 = "ed8d92d9774b077c53e1da50fd81a36af3744c1c" +deps = ["Artifacts", "EpollShim_jll", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg", "XML2_jll"] +git-tree-sha1 = "7558e29847e99bc3f04d6569e82d0f5c54460703" uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89" -version = "1.21.0+0" +version = "1.21.0+1" [[deps.Wayland_protocols_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "4528479aa01ee1b3b4cd0e6faef0e04cf16466da" +git-tree-sha1 = "93f43ab61b16ddfb2fd3bb13b3ce241cafb0e6c9" uuid = "2381bf8a-dfd0-557d-9999-79630e7b1b91" -version = "1.25.0+0" +version = "1.31.0+0" [[deps.WeakRefStrings]] deps = ["DataAPI", "InlineStrings", "Parsers"] @@ -2329,9 +2411,9 @@ version = "0.6.6" [[deps.WoodburyMatrices]] deps = ["LinearAlgebra", "SparseArrays"] -git-tree-sha1 = "de67fa59e33ad156a590055375a30b23c40299d3" +git-tree-sha1 = "5f24e158cf4cee437052371455fe361f526da062" uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" -version = "0.5.5" +version = "0.5.6" [[deps.WorkerUtilities]] git-tree-sha1 = "cd1659ba0d57b71a464a29e64dbc67cfe83d54e7" @@ -2339,10 +2421,10 @@ uuid = "76eceee3-57b5-4d4a-8e66-0e911cebbf60" version = "1.6.1" [[deps.XML2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Pkg", "Zlib_jll"] -git-tree-sha1 = "93c41695bc1c08c46c5899f4fe06d6ead504bb73" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] +git-tree-sha1 = "801cbe47eae69adc50f36c3caec4758d2650741b" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.10.3+0" +version = "2.12.2+0" [[deps.XSLT_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "Pkg", "XML2_jll", "Zlib_jll"] @@ -2350,17 +2432,35 @@ git-tree-sha1 = "91844873c4085240b95e795f692c4cec4d805f8a" uuid = "aed1982a-8fda-507f-9586-7b0439959a61" version = "1.1.34+0" +[[deps.XZ_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "522b8414d40c4cbbab8dee346ac3a09f9768f25d" +uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" +version = "5.4.5+0" + +[[deps.Xorg_libICE_jll]] +deps = ["Libdl", "Pkg"] +git-tree-sha1 = "e5becd4411063bdcac16be8b66fc2f9f6f1e8fe5" +uuid = "f67eecfb-183a-506d-b269-f58e52b52d7c" +version = "1.0.10+1" + +[[deps.Xorg_libSM_jll]] +deps = ["Libdl", "Pkg", "Xorg_libICE_jll"] +git-tree-sha1 = "4a9d9e4c180e1e8119b5ffc224a7b59d3a7f7e18" +uuid = "c834827a-8449-5923-a945-d239c165b7dd" +version = "1.2.3+0" + [[deps.Xorg_libX11_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] -git-tree-sha1 = "5be649d550f3f4b95308bf0183b82e2582876527" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] +git-tree-sha1 = "afead5aba5aa507ad5a3bf01f58f82c8d1403495" uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" -version = "1.6.9+4" +version = "1.8.6+0" [[deps.Xorg_libXau_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "4e490d5c960c314f33885790ed410ff3a94ce67e" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6035850dcc70518ca32f012e46015b9beeda49d8" uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" -version = "1.0.9+4" +version = "1.0.11+0" [[deps.Xorg_libXcursor_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] @@ -2369,10 +2469,10 @@ uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" version = "1.2.0+4" [[deps.Xorg_libXdmcp_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "4fe47bd2247248125c428978740e18a681372dd4" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "34d526d318358a859d7de23da945578e8e8727b7" uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" -version = "1.1.3+4" +version = "1.1.4+0" [[deps.Xorg_libXext_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] @@ -2411,22 +2511,28 @@ uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" version = "0.9.10+4" [[deps.Xorg_libpthread_stubs_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "6783737e45d3c59a4a4c4091f5f88cdcf0908cbb" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8fdda4c692503d44d04a0603d9ac0982054635f9" uuid = "14d82f49-176c-5ed1-bb49-ad3f5cbd8c74" -version = "0.1.0+3" +version = "0.1.1+0" [[deps.Xorg_libxcb_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] -git-tree-sha1 = "daf17f441228e7a3833846cd048892861cff16d6" +deps = ["Artifacts", "JLLWrappers", "Libdl", "XSLT_jll", "Xorg_libXau_jll", "Xorg_libXdmcp_jll", "Xorg_libpthread_stubs_jll"] +git-tree-sha1 = "b4bfde5d5b652e22b9c790ad00af08b6d042b97d" uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" -version = "1.13.0+3" +version = "1.15.0+0" [[deps.Xorg_libxkbfile_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libX11_jll"] -git-tree-sha1 = "926af861744212db0eb001d9e40b5d16292080b2" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "730eeca102434283c50ccf7d1ecdadf521a765a4" uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a" -version = "1.1.0+4" +version = "1.1.2+0" + +[[deps.Xorg_xcb_util_cursor_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_jll", "Xorg_xcb_util_renderutil_jll"] +git-tree-sha1 = "04341cb870f29dcd5e39055f895c39d016e18ccd" +uuid = "e920d4aa-a673-5f3a-b3d7-f755a4d47c43" +version = "0.1.4+0" [[deps.Xorg_xcb_util_image_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xcb_util_jll"] @@ -2459,27 +2565,27 @@ uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361" version = "0.4.1+1" [[deps.Xorg_xkbcomp_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_libxkbfile_jll"] -git-tree-sha1 = "4bcbf660f6c2e714f87e960a171b119d06ee163b" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxkbfile_jll"] +git-tree-sha1 = "330f955bc41bb8f5270a369c473fc4a5a4e4d3cb" uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4" -version = "1.4.2+4" +version = "1.4.6+0" [[deps.Xorg_xkeyboard_config_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Xorg_xkbcomp_jll"] -git-tree-sha1 = "5c8424f8a67c3f2209646d4425f3d415fee5931d" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xkbcomp_jll"] +git-tree-sha1 = "691634e5453ad362044e2ad653e79f3ee3bb98c3" uuid = "33bec58e-1273-512f-9401-5d533626f822" -version = "2.27.0+4" +version = "2.39.0+0" [[deps.Xorg_xtrans_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "79c31e7844f6ecf779705fbc12146eb190b7d845" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "e92a1a012a10506618f10b7047e478403a046c77" uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" -version = "1.4.0+3" +version = "1.5.0+0" [[deps.Zlib_jll]] deps = ["Libdl"] uuid = "83775a58-1f1d-513f-b197-d71354ab007a" -version = "1.2.13+0" +version = "1.2.13+1" [[deps.Zstd_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -2487,33 +2593,23 @@ git-tree-sha1 = "49ce682769cd5de6c72dcf1b94ed7790cd08974c" uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" version = "1.5.5+0" -[[deps.Zygote]] -deps = ["AbstractFFTs", "ChainRules", "ChainRulesCore", "DiffRules", "Distributed", "FillArrays", "ForwardDiff", "GPUArrays", "GPUArraysCore", "IRTools", "InteractiveUtils", "LinearAlgebra", "LogExpFunctions", "MacroTools", "NaNMath", "PrecompileTools", "Random", "Requires", "SparseArrays", "SpecialFunctions", "Statistics", "ZygoteRules"] -git-tree-sha1 = "5be3ddb88fc992a7d8ea96c3f10a49a7e98ebc7b" -uuid = "e88e6eb3-aa80-5325-afca-941959d7151f" -version = "0.6.62" - - [deps.Zygote.extensions] - ZygoteColorsExt = "Colors" - ZygoteDistancesExt = "Distances" - ZygoteTrackerExt = "Tracker" - - [deps.Zygote.weakdeps] - Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" - Distances = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" - -[[deps.ZygoteRules]] -deps = ["ChainRulesCore", "MacroTools"] -git-tree-sha1 = "977aed5d006b840e2e40c0b48984f7463109046d" -uuid = "700de1a5-db45-46bc-99cf-38207098b444" -version = "0.2.3" +[[deps.eudev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "gperf_jll"] +git-tree-sha1 = "431b678a28ebb559d224c0b6b6d01afce87c51ba" +uuid = "35ca27e7-8b34-5b7f-bca9-bdc33f59eb06" +version = "3.2.9+0" [[deps.fzf_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "868e669ccb12ba16eaf50cb2957ee2ff61261c56" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a68c9655fbe6dfcab3d972808f1aafec151ce3f8" uuid = "214eeab7-80f7-51ab-84ad-2988db7cef09" -version = "0.29.0+0" +version = "0.43.0+0" + +[[deps.gperf_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "3516a5630f741c9eecb3720b1ec9d8edc3ecc033" +uuid = "1a1c6b14-54f6-533d-8383-74cd7377aa70" +version = "3.1.1+0" [[deps.libaom_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -2530,7 +2626,13 @@ version = "0.15.1+0" [[deps.libblastrampoline_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.8.0+0" +version = "5.8.0+1" + +[[deps.libevdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "141fe65dc3efabb0b1d5ba74e91f6ad26f84cc22" +uuid = "2db6ffa8-e38f-5e21-84af-90c45d0032cc" +version = "1.11.0+0" [[deps.libfdk_aac_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -2538,11 +2640,17 @@ git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" version = "2.0.2+0" +[[deps.libinput_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "eudev_jll", "libevdev_jll", "mtdev_jll"] +git-tree-sha1 = "ad50e5b90f222cfe78aa3d5183a20a12de1322ce" +uuid = "36db933b-70db-51c0-b978-0f229ee0e533" +version = "1.18.0+0" + [[deps.libpng_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] -git-tree-sha1 = "94d180a6d2b5e55e447e2d27a29ed04fe79eb30c" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "93284c28274d9e75218a416c65ec49d0e0fcdf3d" uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" -version = "1.6.38+0" +version = "1.6.40+0" [[deps.libvorbis_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] @@ -2550,15 +2658,21 @@ git-tree-sha1 = "b910cb81ef3fe6e78bf6acee440bda86fd6ae00c" uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" version = "1.3.7+1" +[[deps.mtdev_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] +git-tree-sha1 = "814e154bdb7be91d78b6802843f76b6ece642f11" +uuid = "009596ad-96f7-51b1-9f1b-5ce2d5e8a71e" +version = "1.1.6+0" + [[deps.nghttp2_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.48.0+0" +version = "1.52.0+1" [[deps.p7zip_jll]] deps = ["Artifacts", "Libdl"] uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.4.0+0" +version = "17.4.0+2" [[deps.x264_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -2574,6 +2688,6 @@ version = "3.5.0+0" [[deps.xkbcommon_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg", "Wayland_jll", "Wayland_protocols_jll", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"] -git-tree-sha1 = "9ebfc140cc56e8c2156a15ceac2f0302e327ac0a" +git-tree-sha1 = "9c304562909ab2bab0262639bd4f444d7bc2be37" uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd" -version = "1.4.1+0" +version = "1.4.1+1" diff --git a/lectures/Project.toml b/lectures/Project.toml index b1987bf5..1e00c810 100644 --- a/lectures/Project.toml +++ b/lectures/Project.toml @@ -1,17 +1,15 @@ name = "quantecon-notebooks-julia" authors = ["quantecon "] -version = "0.8.1" +version = "0.10.0" [deps] Arpack = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97" BandedMatrices = "aae01518-5342-5314-be14-df237901396f" BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" -BlackBoxOptim = "a134a8b2-14d6-55f6-9291-3336d3ab0209" CategoricalArrays = "324d7699-5711-5eae-9e2f-1d82baa6b597" DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" DataFramesMeta = "1313f7d8-7da2-5740-9ea0-a2ca25f37964" DataInterpolations = "82cc6244-b520-54b8-b5a6-8a565e85f1d0" -DiffEqOperators = "9fdde737-9c7f-55bf-ade8-46b3f136cc48" Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" Expectations = "2fe49d83-0758-5602-8f54-1f90ad0d522b" FastGaussQuadrature = "442a2c76-b920-505d-bb47-c5924d526838" @@ -27,7 +25,6 @@ JuMP = "4076af6c-e467-56ae-b986-b466b2749572" KernelDensity = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" LaTeXStrings = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" Latexify = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" -LeastSquaresOptim = "0fc2ff8b-aaa3-5acd-a817-1944a5e08891" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" LinearMaps = "7a12625a-238d-50fd-b39a-03d52299707e" LoopVectorization = "bdcacae8-1622-11e9-2a5c-532679323890" @@ -54,4 +51,3 @@ StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd" StochasticDiffEq = "789caeaf-c7a9-5a7d-9973-96adeb23e2a0" Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" -Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" diff --git a/lectures/_config.yml b/lectures/_config.yml index 2298f5f0..33c4da49 100644 --- a/lectures/_config.yml +++ b/lectures/_config.yml @@ -56,6 +56,14 @@ sphinx: html_theme: quantecon_book_theme html_static_path: ['_static'] html_theme_options: + authors: + - name: Jesse Perla + url: https://www.jesseperla.com + - name: Thomas J. Sargent + url: http://www.tomsargent.com/ + - name: John Stachurski + url: https://johnstachurski.net/ + dark_logo: quantecon-logo-transparent.png header_organisation_url: https://quantecon.org header_organisation: QuantEcon repository_url: https://github.com/quantecon/lecture-julia.myst @@ -80,7 +88,7 @@ sphinx: rediraffe_redirects: index_toc.md: intro.md tojupyter_default_lang: julia - tojupyter_lang_synonyms: ['julia-1.9'] + tojupyter_lang_synonyms: ['julia-1.10'] tojupyter_static_file_path: ["source/_static", "_static"] tojupyter_target_html: true tojupyter_urlpath: "https://julia.quantecon.org/" @@ -90,5 +98,5 @@ sphinx: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 tojupyter_images_markdown: true diff --git a/lectures/_static/quantecon-logo-transparent.png b/lectures/_static/quantecon-logo-transparent.png new file mode 100644 index 00000000..e9ead46c Binary files /dev/null and b/lectures/_static/quantecon-logo-transparent.png differ diff --git a/lectures/about_lectures.md b/lectures/about_lectures.md index 0adf01a8..bce53881 100644 --- a/lectures/about_lectures.md +++ b/lectures/about_lectures.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (about)= diff --git a/lectures/continuous_time/covid_sde.md b/lectures/continuous_time/covid_sde.md index c0576465..84f5e253 100644 --- a/lectures/continuous_time/covid_sde.md +++ b/lectures/continuous_time/covid_sde.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (covid_sde)= @@ -604,5 +604,4 @@ In this case, there are significant differences between the early and late death This bleak simulation has assumed that no individuals has long-term immunity and that there will be no medical advancements on that time horizon - both of which are unlikely to be true. -Nevertheless, it suggests that the timing of lifting lockdown has a more profound impact after 18 months if we allow stochastic shocks imperfect immunity. - +Nevertheless, it suggests that the timing of lifting lockdown has a more profound impact after 18 months if we allow stochastic shocks imperfect immunity. \ No newline at end of file diff --git a/lectures/continuous_time/seir_model.md b/lectures/continuous_time/seir_model.md index c36fdb06..c0a36aa9 100644 --- a/lectures/continuous_time/seir_model.md +++ b/lectures/continuous_time/seir_model.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (seir_model)= @@ -517,4 +517,3 @@ Despite its richness, the model above is fully deterministic. The policy $\bar{ One way that randomness can lead to aggregate fluctuations is the granularity that comes through the discreteness of individuals. This topic, the connection between SDEs and the Langevin equations typically used in the approximation of chemical reactions in well-mixed media is explored in further lectures on continuous time Markov chains. Instead, in the {doc}`next lecture `, we will concentrate on randomness that comes from aggregate changes in behavior or policy. - diff --git a/lectures/dynamic_programming/career.md b/lectures/dynamic_programming/career.md index 3427a329..d850e558 100644 --- a/lectures/dynamic_programming/career.md +++ b/lectures/dynamic_programming/career.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (career)= diff --git a/lectures/dynamic_programming/coleman_policy_iter.md b/lectures/dynamic_programming/coleman_policy_iter.md index 2139ff21..cd1de243 100644 --- a/lectures/dynamic_programming/coleman_policy_iter.md +++ b/lectures/dynamic_programming/coleman_policy_iter.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (coleman_policy_iter)= diff --git a/lectures/dynamic_programming/discrete_dp.md b/lectures/dynamic_programming/discrete_dp.md index 0e0c5857..b7df784b 100644 --- a/lectures/dynamic_programming/discrete_dp.md +++ b/lectures/dynamic_programming/discrete_dp.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (discrete_dp)= diff --git a/lectures/dynamic_programming/egm_policy_iter.md b/lectures/dynamic_programming/egm_policy_iter.md index c5327d6b..35d64061 100644 --- a/lectures/dynamic_programming/egm_policy_iter.md +++ b/lectures/dynamic_programming/egm_policy_iter.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (egm_policy_iter)= diff --git a/lectures/dynamic_programming/ifp.md b/lectures/dynamic_programming/ifp.md index 5b38c984..29a60008 100644 --- a/lectures/dynamic_programming/ifp.md +++ b/lectures/dynamic_programming/ifp.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (ifp)= diff --git a/lectures/dynamic_programming/jv.md b/lectures/dynamic_programming/jv.md index f103f6f5..58485e32 100644 --- a/lectures/dynamic_programming/jv.md +++ b/lectures/dynamic_programming/jv.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (jv)= diff --git a/lectures/dynamic_programming/lqcontrol.md b/lectures/dynamic_programming/lqcontrol.md index 2e0e97a8..7867f5e7 100644 --- a/lectures/dynamic_programming/lqcontrol.md +++ b/lectures/dynamic_programming/lqcontrol.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (lqc)= diff --git a/lectures/dynamic_programming/mccall_model.md b/lectures/dynamic_programming/mccall_model.md index e9f2a3cd..40cc4285 100644 --- a/lectures/dynamic_programming/mccall_model.md +++ b/lectures/dynamic_programming/mccall_model.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (mccall)= diff --git a/lectures/dynamic_programming/mccall_model_with_separation.md b/lectures/dynamic_programming/mccall_model_with_separation.md index 357e3438..a1a05ff3 100644 --- a/lectures/dynamic_programming/mccall_model_with_separation.md +++ b/lectures/dynamic_programming/mccall_model_with_separation.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (mccall_with_sep)= diff --git a/lectures/dynamic_programming/odu.md b/lectures/dynamic_programming/odu.md index 0abca506..08db5a86 100644 --- a/lectures/dynamic_programming/odu.md +++ b/lectures/dynamic_programming/odu.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (odu)= diff --git a/lectures/dynamic_programming/optgrowth.md b/lectures/dynamic_programming/optgrowth.md index 1afcbc65..94ec3f62 100644 --- a/lectures/dynamic_programming/optgrowth.md +++ b/lectures/dynamic_programming/optgrowth.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (optgrowth)= diff --git a/lectures/dynamic_programming/perm_income.md b/lectures/dynamic_programming/perm_income.md index 1fa228e1..765ddcd6 100644 --- a/lectures/dynamic_programming/perm_income.md +++ b/lectures/dynamic_programming/perm_income.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (perm_income)= diff --git a/lectures/dynamic_programming/perm_income_cons.md b/lectures/dynamic_programming/perm_income_cons.md index 6b880d27..e4accdf0 100644 --- a/lectures/dynamic_programming/perm_income_cons.md +++ b/lectures/dynamic_programming/perm_income_cons.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (perm_income_cons)= diff --git a/lectures/dynamic_programming/robustness.md b/lectures/dynamic_programming/robustness.md index 38ed5ab9..37ef6fb0 100644 --- a/lectures/dynamic_programming/robustness.md +++ b/lectures/dynamic_programming/robustness.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (rob)= diff --git a/lectures/dynamic_programming/smoothing.md b/lectures/dynamic_programming/smoothing.md index 4fe147b0..31514075 100644 --- a/lectures/dynamic_programming/smoothing.md +++ b/lectures/dynamic_programming/smoothing.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (smoothing)= diff --git a/lectures/dynamic_programming/wald_friedman.md b/lectures/dynamic_programming/wald_friedman.md index 3413dd26..033f5382 100644 --- a/lectures/dynamic_programming/wald_friedman.md +++ b/lectures/dynamic_programming/wald_friedman.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (wald_friedman)= @@ -509,7 +509,7 @@ function simulation(problem) return return_output ? (alpha, beta, outcomes, costs, trials) : nothing end -function Problem(d0 = Beta(1, 1), d1 = Beta(9, 9), +function Problem(;d0 = Beta(1, 1), d1 = Beta(9, 9), L0 = 2, L1 = 2, c = 0.2, p = 0.5, n = 100, return_output = false) @@ -524,7 +524,7 @@ tags: [remove-cell] @testset "Verifying Output" begin Random.seed!(0) (;d0, d1, L0, L1, c) = Problem() - alpha, beta, outcomes, costs, trials = simulation(Problem(return_output = true)) + alpha, beta, outcomes, costs, trials = simulation(Problem(;return_output = true)) #test alpha ≈ 0.57428237 #test beta ≈ 0.352510338 choices = first.(choice.((clamp(beta - eps(), 0, 1), @@ -551,7 +551,7 @@ tags: [remove-cell] @testset "Comparative Statics" begin Random.seed!(0) (;d0, d1, L0, L1, c) = Problem() - alpha, beta, outcomes, costs, trials = simulation(Problem(c = 2c, return_output = true)) + alpha, beta, outcomes, costs, trials = simulation(Problem(;c = 2c, return_output = true)) #test alpha ≈ 0.53551172 atol = 1e-3 #test beta ≈ 0.41244737 atol = 1e-3 #test mean(outcomes) ≈ 0.39 atol = 1e-2 @@ -582,7 +582,7 @@ Before you look, think about what will happen: ```{code-cell} julia Random.seed!(0); -simulation(Problem(c = 0.4)); +simulation(Problem(;c = 0.4)); ``` Notice what happens? diff --git a/lectures/dynamic_programming_squared/amss.md b/lectures/dynamic_programming_squared/amss.md index e9fee44a..5ae14997 100644 --- a/lectures/dynamic_programming_squared/amss.md +++ b/lectures/dynamic_programming_squared/amss.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (opt_tax_amss)= @@ -44,11 +44,6 @@ In this lecture, we We begin with an introduction to the model. - -```{code-cell} julia -using LinearAlgebra, Statistics -``` - ## Competitive Equilibrium with Distorting Taxes Many but not all features of the economy are identical to those of {doc}`the Lucas-Stokey economy <../dynamic_programming_squared/opt_tax_recur>`. @@ -390,13 +385,15 @@ on optimal taxation with state-contingent debt sequential allocation implementa --- tags: [remove-cell] --- -using Test, Random +using Test ``` ```{code-cell} julia --- tags: [output_scroll] --- + +using LinearAlgebra, Statistics, Random using QuantEcon, NLsolve, NLopt import QuantEcon.simulate @@ -404,10 +401,10 @@ import QuantEcon.simulate mutable struct Model{TF <: AbstractFloat, TM <: AbstractMatrix{TF}, TV <: AbstractVector{TF}} - β::TF - Π::TM + beta::TF + Pi::TM G::TV - Θ::TV + Theta::TV transfers::Bool U::Function Uc::Function @@ -417,7 +414,6 @@ mutable struct Model{TF <: AbstractFloat, n_less_than_one::Bool end - struct SequentialAllocation{TP <: Model, TI <: Integer, TV <: AbstractVector} @@ -426,19 +422,18 @@ struct SequentialAllocation{TP <: Model, S::TI cFB::TV nFB::TV - ΞFB::TV + XiFB::TV zFB::TV end - function SequentialAllocation(model::Model) - β, Π, G, Θ = model.β, model.Π, model.G, model.Θ - mc = MarkovChain(Π) - S = size(Π, 1) # Number of states + beta, Pi, G, Theta = model.beta, model.Pi, model.G, model.Theta + mc = MarkovChain(Pi) + S = size(Pi, 1) # Number of states # Now find the first best allocation - cFB, nFB, ΞFB, zFB = find_first_best(model, S, 1) + cFB, nFB, XiFB, zFB = find_first_best(model, S, 1) - return SequentialAllocation(model, mc, S, cFB, nFB, ΞFB, zFB) + return SequentialAllocation(model, mc, S, cFB, nFB, XiFB, zFB) end @@ -446,13 +441,13 @@ function find_first_best(model::Model, S::Integer, version::Integer) if version != 1 && version != 2 throw(ArgumentError("version must be 1 or 2")) end - β, Θ, Uc, Un, G, Π = - model.β, model.Θ, model.Uc, model.Un, model.G, model.Π + beta, Theta, Uc, Un, G, Pi = + model.beta, model.Theta, model.Uc, model.Un, model.G, model.Pi function res!(out, z) c = z[1:S] n = z[S+1:end] - out[1:S] = Θ .* Uc.(c, n) + Un.(c, n) - out[S+1:end] = Θ .* n .- c .- G + out[1:S] = Theta .* Uc.(c, n) + Un.(c, n) + out[S+1:end] = Theta .* n .- c .- G end res = nlsolve(res!, 0.5 * ones(2 * S)) @@ -463,32 +458,32 @@ function find_first_best(model::Model, S::Integer, version::Integer) if version == 1 cFB = res.zero[1:S] nFB = res.zero[S+1:end] - ΞFB = Uc(cFB, nFB) # Multiplier on the resource constraint - zFB = vcat(cFB, nFB, ΞFB) - return cFB, nFB, ΞFB, zFB + XiFB = Uc(cFB, nFB) # Multiplier on the resource constraint + zFB = vcat(cFB, nFB, XiFB) + return cFB, nFB, XiFB, zFB elseif version == 2 cFB = res.zero[1:S] nFB = res.zero[S+1:end] IFB = Uc(cFB, nFB) .* cFB + Un(cFB, nFB) .* nFB - xFB = \(LinearAlgebra.I - β * Π, IFB) + xFB = \(LinearAlgebra.I - beta * Pi, IFB) zFB = [vcat(cFB[s], xFB[s], xFB) for s in 1:S] return cFB, nFB, IFB, xFB, zFB end end -function time1_allocation(pas::SequentialAllocation, μ::Real) +function time1_allocation(pas::SequentialAllocation, mu::Real) model, S = pas.model, pas.S - Θ, β, Π, G, Uc, Ucc, Un, Unn = - model.Θ, model.β, model.Π, model.G, + Theta, beta, Pi, G, Uc, Ucc, Un, Unn = + model.Theta, model.beta, model.Pi, model.G, model.Uc, model.Ucc, model.Un, model.Unn function FOC!(out, z::Vector) c = z[1:S] n = z[S+1:2S] - Ξ = z[2S+1:end] - out[1:S] = Uc.(c, n) - μ * (Ucc.(c, n) .* c + Uc.(c, n)) - Ξ # FOC c - out[S+1:2S] = Un.(c, n) - μ * (Unn(c, n) .* n .+ Un.(c, n)) + Θ .* Ξ # FOC n - out[2S+1:end] = Θ .* n - c .- G # resource constraint + Xi = z[2S+1:end] + out[1:S] = Uc.(c, n) - mu * (Ucc.(c, n) .* c + Uc.(c, n)) - Xi # FOC c + out[S+1:2S] = Un.(c, n) - mu * (Unn(c, n) .* n .+ Un.(c, n)) + Theta .* Xi # FOC n + out[2S+1:end] = Theta .* n - c .- G # resource constraint return out end # Find the root of the FOC @@ -497,35 +492,35 @@ function time1_allocation(pas::SequentialAllocation, μ::Real) error("Could not find LS allocation.") end z = res.zero - c, n, Ξ = z[1:S], z[S+1:2S], z[2S+1:end] + c, n, Xi = z[1:S], z[S+1:2S], z[2S+1:end] # Now compute x I = Uc(c, n) .* c + Un(c, n) .* n - x = \(LinearAlgebra.I - β * model.Π, I) - return c, n, x, Ξ + x = \(LinearAlgebra.I - beta * model.Pi, I) + return c, n, x, Xi end function time0_allocation(pas::SequentialAllocation, B_::AbstractFloat, s_0::Integer) model = pas.model - Π, Θ, G, β = model.Π, model.Θ, model.G, model.β + Pi, Theta, G, beta = model.Pi, model.Theta, model.G, model.beta Uc, Ucc, Un, Unn = model.Uc, model.Ucc, model.Un, model.Unn # First order conditions of planner's problem function FOC!(out, z) - μ, c, n, Ξ = z[1], z[2], z[3], z[4] - xprime = time1_allocation(pas, μ)[3] + mu, c, n, Xi = z[1], z[2], z[3], z[4] + xprime = time1_allocation(pas, mu)[3] out .= vcat( - Uc(c, n) .* (c - B_) + Un(c, n) .* n + β * dot(Π[s_0, :], xprime), - Uc(c, n) .- μ * (Ucc(c, n) .* (c - B_) + Uc(c, n)) .- Ξ, - Un(c, n) .- μ * (Unn(c, n) .* n + Un(c, n)) + Θ[s_0] .* Ξ, - (Θ .* n .- c .- G)[s_0] + Uc(c, n) .* (c - B_) + Un(c, n) .* n + beta * dot(Pi[s_0, :], xprime), + Uc(c, n) .- mu * (Ucc(c, n) .* (c - B_) + Uc(c, n)) .- Xi, + Un(c, n) .- mu * (Unn(c, n) .* n + Un(c, n)) + Theta[s_0] .* Xi, + (Theta .* n .- c .- G)[s_0] ) end # Find root - res = nlsolve(FOC!, [0.0, pas.cFB[s_0], pas.nFB[s_0], pas.ΞFB[s_0]]) + res = nlsolve(FOC!, [0.0, pas.cFB[s_0], pas.nFB[s_0], pas.XiFB[s_0]]) if res.f_converged == false error("Could not find time 0 LS allocation.") end @@ -533,18 +528,18 @@ function time0_allocation(pas::SequentialAllocation, end -function time1_value(pas::SequentialAllocation, μ::Real) +function time1_value(pas::SequentialAllocation, mu::Real) model = pas.model - c, n, x, Ξ = time1_allocation(pas, μ) + c, n, x, Xi = time1_allocation(pas, mu) U_val = model.U.(c, n) - V = \(LinearAlgebra.I - model.β*model.Π, U_val) + V = \(LinearAlgebra.I - model.beta*model.Pi, U_val) return c, n, x, V end -function Τ(model::Model, c::Union{Real,Vector}, n::Union{Real,Vector}) +function Omega(model::Model, c::Union{Real,Vector}, n::Union{Real,Vector}) Uc, Un = model.Uc.(c, n), model.Un.(c, n) - return 1. .+ Un./(model.Θ .* Uc) + return 1. .+ Un./(model.Theta .* Uc) end @@ -554,7 +549,7 @@ function simulate(pas::SequentialAllocation, sHist::Union{Vector, Nothing}=nothing) model = pas.model - Π, β, Uc = model.Π, model.β, model.Uc + Pi, beta, Uc = model.Pi, model.beta, model.Uc if isnothing(sHist) sHist = QuantEcon.simulate(pas.mc, T, init=s_0) @@ -562,26 +557,26 @@ function simulate(pas::SequentialAllocation, cHist = zeros(T) nHist = zeros(T) Bhist = zeros(T) - ΤHist = zeros(T) - μHist = zeros(T) + OmegaHist = zeros(T) + muHist = zeros(T) RHist = zeros(T-1) # time 0 - μ, cHist[1], nHist[1], _ = time0_allocation(pas, B_, s_0) - ΤHist[1] = Τ(pas.model, cHist[1], nHist[1])[s_0] + mu, cHist[1], nHist[1], _ = time0_allocation(pas, B_, s_0) + OmegaHist[1] = Omega(pas.model, cHist[1], nHist[1])[s_0] Bhist[1] = B_ - μHist[1] = μ + muHist[1] = mu # time 1 onward for t in 2:T - c, n, x, Ξ = time1_allocation(pas,μ) + c, n, x, Xi = time1_allocation(pas,mu) u_c = Uc(c,n) s = sHist[t] - ΤHist[t] = Τ(pas.model, c, n)[s] - Eu_c = dot(Π[sHist[t-1],:], u_c) + OmegaHist[t] = Omega(pas.model, c, n)[s] + Eu_c = dot(Pi[sHist[t-1],:], u_c) cHist[t], nHist[t], Bhist[t] = c[s], n[s], x[s] / u_c[s] - RHist[t-1] = Uc(cHist[t-1], nHist[t-1]) / (β * Eu_c) - μHist[t] = μ + RHist[t-1] = Uc(cHist[t-1], nHist[t-1]) / (beta * Eu_c) + muHist[t] = mu end - return cHist, nHist, Bhist, ΤHist, sHist, μHist, RHist + return cHist, nHist, Bhist, OmegaHist, sHist, muHist, RHist end @@ -603,7 +598,7 @@ end function BellmanEquation(model::Model, xgrid::AbstractVector, policies0::Vector) - S = size(model.Π, 1) # number of states + S = size(model.Pi, 1) # number of states xbar = [minimum(xgrid), maximum(xgrid)] time_0 = false cf, nf, xprimef = policies0 @@ -618,19 +613,19 @@ function get_policies_time1(T::BellmanEquation, i_x::Integer, x::AbstractFloat, s::Integer, Vf::AbstractArray) model, S = T.model, T.S - β, Θ, G, Π = model.β, model.Θ, model.G, model.Π + beta, Theta, G, Pi = model.beta, model.Theta, model.G, model.Pi U, Uc, Un = model.U, model.Uc, model.Un function objf(z::Vector, grad) c, xprime = z[1], z[2:end] n=c+G[s] Vprime = [Vf[sprime](xprime[sprime]) for sprime in 1:S] - return -(U(c, n) + β * dot(Π[s, :], Vprime)) + return -(U(c, n) + beta * dot(Pi[s, :], Vprime)) end function cons(z::Vector, grad) c, xprime = z[1], z[2:end] n=c+G[s] - return x - Uc(c, n) * c - Un(c, n) * n - β * dot(Π[s, :], xprime) + return x - Uc(c, n) * c - Un(c, n) * n - beta * dot(Pi[s, :], xprime) end lb = vcat(0, T.xbar[1] * ones(S)) ub = vcat(1 - G[s], T.xbar[2] * ones(S)) @@ -657,18 +652,18 @@ end function get_policies_time0(T::BellmanEquation, B_::AbstractFloat, s0::Integer, Vf::Array) model, S = T.model, T.S - β, Θ, G, Π = model.β, model.Θ, model.G, model.Π + beta, Theta, G, Pi = model.beta, model.Theta, model.G, model.Pi U, Uc, Un = model.U, model.Uc, model.Un function objf(z, grad) c, xprime = z[1], z[2:end] n = c+G[s0] Vprime = [Vf[sprime](xprime[sprime]) for sprime in 1:S] - return -(U(c, n) + β * dot(Π[s0, :], Vprime)) + return -(U(c, n) + beta * dot(Pi[s0, :], Vprime)) end function cons(z::Vector, grad) c, xprime = z[1], z[2:end] n = c + G[s0] - return -Uc(c, n) * (c - B_) - Un(c, n) * n - β * dot(Π[s0, :], xprime) + return -Uc(c, n) * (c - B_) - Un(c, n) * n - beta * dot(Pi[s0, :], xprime) end lb = vcat(0, T.xbar[1] * ones(S)) ub = vcat(1-G[s0], T.xbar[2] * ones(S)) @@ -962,6 +957,7 @@ The recursive formulation is implemented as follows ```{code-cell} julia +# Interpolations.jl doesn't support irregular grids for splines using DataInterpolations mutable struct BellmanEquation_Recursive{TP <: Model, TI <: Integer, TR <: Real} @@ -976,74 +972,76 @@ mutable struct BellmanEquation_Recursive{TP <: Model, TI <: Integer, TR <: Real} zFB::Vector{Vector{TR}} end - struct RecursiveAllocation{TP <: Model, - TI <: Integer, - TVg <: AbstractVector, - TT <: Tuple} + TI <: Integer, + TVg <: AbstractVector, + TT <: Tuple} model::TP mc::MarkovChain S::TI T::BellmanEquation_Recursive - μgrid::TVg + mugrid::TVg xgrid::TVg Vf::Array policies::TT end - -function RecursiveAllocation(model::Model, μgrid::AbstractArray) +function RecursiveAllocation(model::Model, mugrid::AbstractArray) G = model.G - S = size(model.Π, 1) # number of states - mc = MarkovChain(model.Π) + S = size(model.Pi, 1) # number of states + mc = MarkovChain(model.Pi) # now find the first best allocation - Vf, policies, T, xgrid = solve_time1_bellman(model, μgrid) + Vf, policies, T, xgrid = solve_time1_bellman(model, mugrid) T.time_0 = true # Bellman equation now solves time 0 problem - return RecursiveAllocation(model, mc, S, T, μgrid, xgrid, Vf, policies) + return RecursiveAllocation(model, mc, S, T, mugrid, xgrid, Vf, policies) end - -function solve_time1_bellman(model::Model{TR}, μgrid::AbstractArray) where {TR <: Real} - Π = model.Π - S = size(model.Π, 1) +function solve_time1_bellman(model::Model{TR}, + mugrid::AbstractArray) where {TR <: Real} + Pi = model.Pi + S = size(model.Pi, 1) # First get initial fit from lucas stockey solution. # Need to change things to be ex_ante PP = SequentialAllocation(model) function incomplete_allocation(PP::SequentialAllocation, - μ_::AbstractFloat, - s_::Integer) - c, n, x, V = time1_value(PP, μ_) - return c, n, dot(Π[s_, :], x), dot(Π[s_, :], V) + mu_::AbstractFloat, + s_::Integer) + c, n, x, V = time1_value(PP, mu_) + return c, n, dot(Pi[s_, :], x), dot(Pi[s_, :], V) end cf = Array{Function}(undef, S, S) nf = Array{Function}(undef, S, S) xprimef = Array{Function}(undef, S, S) Vf = Vector{Function}(undef, S) - xgrid = Array{TR}(undef, S, length(μgrid)) + xgrid = Array{TR}(undef, S, length(mugrid)) for s_ in 1:S - c = Array{TR}(undef, length(μgrid), S) - n = Array{TR}(undef, length(μgrid), S) - x = Array{TR}(undef, length(μgrid)) - V = Array{TR}(undef, length(μgrid)) - for (i_μ, μ) in enumerate(μgrid) - c[i_μ, :], n[i_μ, :], x[i_μ], V[i_μ] = - incomplete_allocation(PP, μ, s_) + c = Array{TR}(undef, length(mugrid), S) + n = Array{TR}(undef, length(mugrid), S) + x = Array{TR}(undef, length(mugrid)) + V = Array{TR}(undef, length(mugrid)) + for (i_mu, mu) in enumerate(mugrid) + c[i_mu, :], n[i_mu, :], x[i_mu], V[i_mu] = incomplete_allocation(PP, + mu, + s_) end xprimes = repeat(x, 1, S) xgrid[s_, :] = x - for sprime = 1:S - splc = CubicSpline(c[:, sprime][end:-1:1], x[end:-1:1]) - spln = CubicSpline(n[:, sprime][end:-1:1], x[end:-1:1]) - splx = CubicSpline(xprimes[:, sprime][end:-1:1], x[end:-1:1]) + for sprime in 1:S + splc = CubicSpline(c[:, sprime][end:-1:1], x[end:-1:1]; + extrapolate = true) + spln = CubicSpline(n[:, sprime][end:-1:1], x[end:-1:1]; + extrapolate = true) + splx = CubicSpline(xprimes[:, sprime][end:-1:1], x[end:-1:1]; + extrapolate = true) cf[s_, sprime] = y -> splc(y) nf[s_, sprime] = y -> spln(y) xprimef[s_, sprime] = y -> splx(y) end - splV = CubicSpline(V[end:-1:1], x[end:-1:1]) + splV = CubicSpline(V[end:-1:1], x[end:-1:1]; extrapolate = true) Vf[s_] = y -> splV(y) end @@ -1051,7 +1049,7 @@ function solve_time1_bellman(model::Model{TR}, μgrid::AbstractArray) where {TR # Create xgrid xbar = [maximum(minimum(xgrid)), minimum(maximum(xgrid))] - xgrid = range(xbar[1], xbar[2], length = length(μgrid)) + xgrid = range(xbar[1], xbar[2], length = length(mugrid)) # Now iterate on Bellman equation T = BellmanEquation_Recursive(model, xgrid, policies) @@ -1061,9 +1059,11 @@ function solve_time1_bellman(model::Model{TR}, μgrid::AbstractArray) where {TR Vfnew, policies = fit_policy_function(T, PF, xgrid) diff = 0.0 - for s=1:S - diff = max(diff, maximum(abs, (Vf[s].(xgrid) - Vfnew[s].(xgrid)) ./ - Vf[s].(xgrid))) + for s in 1:S + diff = max(diff, + maximum(abs, + (Vf[s].(xgrid) - Vfnew[s].(xgrid)) ./ + Vf[s].(xgrid))) end println("diff = $diff") @@ -1073,10 +1073,11 @@ function solve_time1_bellman(model::Model{TR}, μgrid::AbstractArray) where {TR return Vf, policies, T, xgrid end - function fit_policy_function(T::BellmanEquation_Recursive, PF::Function, - xgrid::AbstractVector{TF}) where {TF <: AbstractFloat} + xgrid::AbstractVector{TF}) where { + TF <: + AbstractFloat} S = T.S # preallocation PFvec = Array{TF}(undef, 4S + 1, length(xgrid)) @@ -1090,9 +1091,9 @@ function fit_policy_function(T::BellmanEquation_Recursive, for (i_x, x) in enumerate(xgrid) PFvec[:, i_x] = PF(i_x, x, s_) end - splV = CubicSpline(PFvec[1,:], xgrid) + splV = CubicSpline(PFvec[1, :], xgrid) Vf[s_] = y -> splV(y) - for sprime=1:S + for sprime in 1:S splc = CubicSpline(PFvec[1 + sprime, :], xgrid) spln = CubicSpline(PFvec[1 + S + sprime, :], xgrid) splxprime = CubicSpline(PFvec[1 + 2S + sprime, :], xgrid) @@ -1107,18 +1108,16 @@ function fit_policy_function(T::BellmanEquation_Recursive, return Vf, policies end - function Tau(pab::RecursiveAllocation, - c::AbstractArray, - n::AbstractArray) + c::AbstractArray, + n::AbstractArray) model = pab.model Uc, Un = model.Uc(c, n), model.Un(c, n) - return 1. .+ Un ./ (model.Θ .* Uc) + return 1.0 .+ Un ./ (model.Theta .* Uc) end Tau(pab::RecursiveAllocation, c::Real, n::Real) = Tau(pab, [c], [n]) - function time0_allocation(pab::RecursiveAllocation, B_::Real, s0::Integer) T, Vf = pab.T, pab.Vf xbar = T.xbar @@ -1128,12 +1127,14 @@ function time0_allocation(pab::RecursiveAllocation, B_::Real, s0::Integer) return c0, n0, xprime0, T0 end - function simulate(pab::RecursiveAllocation, B_::TF, s_0::Integer, T::Integer, - sHist::Vector=simulate(pab.mc, T, init=s_0)) where {TF <: AbstractFloat} + sHist::Vector = simulate(pab.mc, T, init = s_0)) where { + TF <: + AbstractFloat + } model, mc, Vf, S = pab.model, pab.mc, pab.Vf, pab.S - Π, Uc = model.Π, model.Uc + Pi, Uc = model.Pi, model.Uc cf, nf, xprimef, TTf = pab.policies cHist = Array{TF}(undef, T) @@ -1142,45 +1143,45 @@ function simulate(pab::RecursiveAllocation, xHist = Array{TF}(undef, T) TauHist = Array{TF}(undef, T) THist = Array{TF}(undef, T) - μHist = Array{TF}(undef, T) + muHist = Array{TF}(undef, T) #time0 - cHist[1], nHist[1], xHist[1], THist[1] = time0_allocation(pab, B_, s_0) + cHist[1], nHist[1], xHist[1], THist[1] = time0_allocation(pab, B_, s_0) TauHist[1] = Tau(pab, cHist[1], nHist[1])[s_0] Bhist[1] = B_ - μHist[1] = Vf[s_0](xHist[1]) + muHist[1] = Vf[s_0](xHist[1]) #time 1 onward for t in 2:T - s_, x, s = sHist[t-1], xHist[t-1], sHist[t] + s_, x, s = sHist[t - 1], xHist[t - 1], sHist[t] c = Array{TF}(undef, S) n = Array{TF}(undef, S) xprime = Array{TF}(undef, S) TT = Array{TF}(undef, S) - for sprime=1:S - c[sprime], n[sprime], xprime[sprime], TT[sprime] = - cf[s_, sprime](x), nf[s_, sprime](x), - xprimef[s_, sprime](x), TTf[s_, sprime](x) + for sprime in 1:S + c[sprime], n[sprime], xprime[sprime], TT[sprime] = cf[s_, sprime](x), + nf[s_, sprime](x), + xprimef[s_, + sprime](x), + TTf[s_, sprime](x) end Tau_val = Tau(pab, c, n)[s] u_c = Uc(c, n) - Eu_c = dot(Π[s_, :], u_c) + Eu_c = dot(Pi[s_, :], u_c) - μHist[t] = Vf[s](xprime[s]) + muHist[t] = Vf[s](xprime[s]) - cHist[t], nHist[t], Bhist[t], TauHist[t] = c[s], n[s], x/Eu_c, Tau_val + cHist[t], nHist[t], Bhist[t], TauHist[t] = c[s], n[s], x / Eu_c, Tau_val xHist[t], THist[t] = xprime[s], TT[s] end - return cHist, nHist, Bhist, xHist, TauHist, THist, μHist, sHist + return cHist, nHist, Bhist, xHist, TauHist, THist, muHist, sHist end - function BellmanEquation_Recursive(model::Model{TF}, xgrid::AbstractVector{TF}, policies0::Array) where {TF <: AbstractFloat} - - S = size(model.Π, 1) # number of states + S = size(model.Pi, 1) # number of states xbar = [minimum(xgrid), maximum(xgrid)] time_0 = false z0 = Array{Array}(undef, length(xgrid), S) @@ -1190,18 +1191,18 @@ function BellmanEquation_Recursive(model::Model{TF}, cs = Array{TF}(undef, S) ns = Array{TF}(undef, S) xprimes = Array{TF}(undef, S) - for j = 1:S - cs[j], ns[j], xprimes[j] = cf[s, j](x), nf[s, j](x), xprimef[s, j](x) + for j in 1:S + cs[j], ns[j], xprimes[j] = cf[s, j](x), nf[s, j](x), + xprimef[s, j](x) end z0[i_x, s] = vcat(cs, ns, xprimes, zeros(S)) end end cFB, nFB, IFB, xFB, zFB = find_first_best(model, S, 2) - return BellmanEquation_Recursive(model, S, xbar, time_0, z0, cFB, nFB, xFB, zFB) + return BellmanEquation_Recursive(model, S, xbar, time_0, z0, cFB, nFB, xFB, + zFB) end - - function get_policies_time1(T::BellmanEquation_Recursive, i_x::Integer, x::Real, @@ -1209,44 +1210,45 @@ function get_policies_time1(T::BellmanEquation_Recursive, Vf::AbstractArray{Function}, xbar::AbstractVector) model, S = T.model, T.S - β, Θ, G, Π = model.β, model.Θ, model.G, model.Π - U,Uc,Un = model.U, model.Uc, model.Un + beta, Theta, G, Pi = model.beta, model.Theta, model.G, model.Pi + U, Uc, Un = model.U, model.Uc, model.Un - S_possible = sum(Π[s_, :].>0) - sprimei_possible = findall(Π[s_, :].>0) + S_possible = sum(Pi[s_, :] .> 0) + sprimei_possible = findall(Pi[s_, :] .> 0) function objf(z, grad) - c, xprime = z[1:S_possible], z[S_possible+1:2S_possible] - n = (c .+ G[sprimei_possible]) ./ Θ[sprimei_possible] + c, xprime = z[1:S_possible], z[(S_possible + 1):(2S_possible)] + n = (c .+ G[sprimei_possible]) ./ Theta[sprimei_possible] Vprime = [Vf[sprimei_possible[si]](xprime[si]) for si in 1:S_possible] - return -dot(Π[s_, sprimei_possible], U.(c, n) + β * Vprime) + return -dot(Pi[s_, sprimei_possible], U.(c, n) + beta * Vprime) end function cons(out, z, grad) - c, xprime, TT = - z[1:S_possible], z[S_possible + 1:2S_possible], z[2S_possible + 1:3S_possible] - n = (c .+ G[sprimei_possible]) ./ Θ[sprimei_possible] + c, xprime, TT = z[1:S_possible], z[(S_possible + 1):(2S_possible)], + z[(2S_possible + 1):(3S_possible)] + n = (c .+ G[sprimei_possible]) ./ Theta[sprimei_possible] u_c = Uc.(c, n) - Eu_c = dot(Π[s_, sprimei_possible], u_c) - out .= x * u_c/Eu_c - u_c .* (c - TT) - Un(c, n) .* n - β * xprime + Eu_c = dot(Pi[s_, sprimei_possible], u_c) + out .= x * u_c / Eu_c - u_c .* (c - TT) - Un(c, n) .* n - beta * xprime end function cons_no_trans(out, z, grad) - c, xprime = z[1:S_possible], z[S_possible + 1:2S_possible] - n = (c .+ G[sprimei_possible]) ./ Θ[sprimei_possible] + c, xprime = z[1:S_possible], z[(S_possible + 1):(2S_possible)] + n = (c .+ G[sprimei_possible]) ./ Theta[sprimei_possible] u_c = Uc.(c, n) - Eu_c = dot(Π[s_, sprimei_possible], u_c) - out .= x * u_c / Eu_c - u_c .* c - Un(c, n) .* n - β * xprime + Eu_c = dot(Pi[s_, sprimei_possible], u_c) + out .= x * u_c / Eu_c - u_c .* c - Un(c, n) .* n - beta * xprime end if model.transfers == true - lb = vcat(zeros(S_possible), ones(S_possible)*xbar[1], zeros(S_possible)) + lb = vcat(zeros(S_possible), ones(S_possible) * xbar[1], + zeros(S_possible)) if model.n_less_than_one == true ub = vcat(ones(S_possible) - G[sprimei_possible], - ones(S_possible) * xbar[2], ones(S_possible)) + ones(S_possible) * xbar[2], ones(S_possible)) else ub = vcat(100 * ones(S_possible), - ones(S_possible) * xbar[2], - 100 * ones(S_possible)) + ones(S_possible) * xbar[2], + 100 * ones(S_possible)) end init = vcat(T.z0[i_x, s_][sprimei_possible], T.z0[i_x, s_][2S .+ sprimei_possible], @@ -1254,9 +1256,10 @@ function get_policies_time1(T::BellmanEquation_Recursive, opt = Opt(:LN_COBYLA, 3S_possible) equality_constraint!(opt, cons, zeros(S_possible)) else - lb = vcat(zeros(S_possible), ones(S_possible)*xbar[1]) + lb = vcat(zeros(S_possible), ones(S_possible) * xbar[1]) if model.n_less_than_one == true - ub = vcat(ones(S_possible)-G[sprimei_possible], ones(S_possible)*xbar[2]) + ub = vcat(ones(S_possible) - G[sprimei_possible], + ones(S_possible) * xbar[2]) else ub = vcat(ones(S_possible), ones(S_possible) * xbar[2]) end @@ -1279,15 +1282,16 @@ function get_policies_time1(T::BellmanEquation_Recursive, (minf, minx, ret) = NLopt.optimize(opt, init) if ret != :SUCCESS && ret != :ROUNDOFF_LIMITED && ret != :MAXEVAL_REACHED && - ret != :FTOL_REACHED && ret != :MAXTIME_REACHED + ret != :FTOL_REACHED && ret != :MAXTIME_REACHED error("optimization failed: ret = $ret") end T.z0[i_x, s_][sprimei_possible] = minx[1:S_possible] - T.z0[i_x, s_][S .+ sprimei_possible] = minx[1:S_possible] .+ G[sprimei_possible] - T.z0[i_x, s_][2S .+ sprimei_possible] = minx[S_possible .+ 1:2S_possible] + T.z0[i_x, s_][S .+ sprimei_possible] = minx[1:S_possible] .+ + G[sprimei_possible] + T.z0[i_x, s_][2S .+ sprimei_possible] = minx[(S_possible .+ 1):(2S_possible)] if model.transfers == true - T.z0[i_x, s_][3S .+ sprimei_possible] = minx[2S_possible + 1:3S_possible] + T.z0[i_x, s_][3S .+ sprimei_possible] = minx[(2S_possible + 1):(3S_possible)] else T.z0[i_x, s_][3S .+ sprimei_possible] = zeros(S) end @@ -1295,26 +1299,25 @@ function get_policies_time1(T::BellmanEquation_Recursive, return vcat(-minf, T.z0[i_x, s_]) end - function get_policies_time0(T::BellmanEquation_Recursive, B_::Real, s0::Integer, Vf::AbstractArray{Function}, xbar::AbstractVector) model = T.model - β, Θ, G = model.β, model.Θ, model.G + beta, Theta, G = model.beta, model.Theta, model.G U, Uc, Un = model.U, model.Uc, model.Un function objf(z, grad) c, xprime = z[1], z[2] - n = (c + G[s0]) / Θ[s0] - return -(U(c, n) + β * Vf[s0](xprime)) + n = (c + G[s0]) / Theta[s0] + return -(U(c, n) + beta * Vf[s0](xprime)) end - function cons(z,grad) + function cons(z, grad) c, xprime, TT = z[1], z[2], z[3] - n = (c + G[s0]) / Θ[s0] - return -Uc(c, n) * (c - B_ - TT) - Un(c, n) * n - β * xprime + n = (c + G[s0]) / Theta[s0] + return -Uc(c, n) * (c - B_ - TT) - Un(c, n) * n - beta * xprime end cons_no_trans(z, grad) = cons(vcat(z, 0), grad) @@ -1326,13 +1329,13 @@ function get_policies_time0(T::BellmanEquation_Recursive, ub = [100.0, xbar[2], 100.0] end init = vcat(T.zFB[s0][1], T.zFB[s0][3], T.zFB[s0][4]) - init = [0.95124922, -1.15926816, 0.0] + init = [0.95124922, -1.15926816, 0.0] opt = Opt(:LN_COBYLA, 3) equality_constraint!(opt, cons) else lb = [0.0, xbar[1]] if model.n_less_than_one == true - ub = [1-G[s0], xbar[2]] + ub = [1 - G[s0], xbar[2]] else ub = [100, xbar[2]] end @@ -1344,7 +1347,6 @@ function get_policies_time0(T::BellmanEquation_Recursive, init[init .> ub] = ub[init .> ub] init[init .< lb] = lb[init .< lb] - min_objective!(opt, objf) lower_bounds!(opt, lb) upper_bounds!(opt, ub) @@ -1354,14 +1356,14 @@ function get_policies_time0(T::BellmanEquation_Recursive, (minf, minx, ret) = NLopt.optimize(opt, init) if ret != :SUCCESS && ret != :ROUNDOFF_LIMITED && ret != :MAXEVAL_REACHED && - ret != :FTOL_REACHED - error("optimization failed: ret = $ret") + ret != :FTOL_REACHED + error("optimization failed: ret = $ret") end if model.transfers == true - return -minf, minx[1], minx[1]+G[s0], minx[2], minx[3] + return -minf, minx[1], minx[1] + G[s0], minx[2], minx[3] else - return -minf, minx[1], minx[1]+G[s0], minx[2], 0 + return -minf, minx[1], minx[1] + G[s0], minx[2], 0 end end ``` @@ -1429,31 +1431,30 @@ We assume the same utility parameters as in the {doc}`Lucas-Stokey economy <../d This utility function is implemented in the following constructor ```{code-cell} julia -function crra_utility(; - β = 0.9, - σ = 2.0, - γ = 2.0, - Π = 0.5 * ones(2, 2), - G = [0.1, 0.2], - Θ = ones(Float64, 2), - transfers = false - ) +function CRRAModel(; + beta = 0.9, + sigma = 2.0, + gamma = 2.0, + Pi = 0.5 * ones(2, 2), + G = [0.1, 0.2], + Theta = ones(Float64, 2), + transfers = false) function U(c, n) - if σ == 1.0 + if sigma == 1.0 U = log(c) else - U = (c.^(1.0 - σ) - 1.0) / (1.0 - σ) + U = (c .^ (1.0 - sigma) - 1.0) / (1.0 - sigma) end - return U - n.^(1 + γ) / (1 + γ) + return U - n .^ (1 + gamma) / (1 + gamma) end # Derivatives of utility function - Uc(c,n) = c.^(-σ) - Ucc(c,n) = -σ * c.^(-σ - 1.0) - Un(c,n) = -n.^γ - Unn(c,n) = -γ * n.^(γ - 1.0) + Uc(c, n) = c .^ (-sigma) + Ucc(c, n) = -sigma * c .^ (-sigma - 1.0) + Un(c, n) = -n .^ gamma + Unn(c, n) = -gamma * n .^ (gamma - 1.0) n_less_than_one = false - return Model(β, Π, G, Θ, transfers, - U, Uc, Ucc, Un, Unn, n_less_than_one) + return Model(beta, Pi, G, Theta, transfers, + U, Uc, Ucc, Un, Unn, n_less_than_one) end ``` @@ -1468,31 +1469,31 @@ Paths with circles are histories in which there is peace, while those with triangle denote war. ```{code-cell} julia -time_example = crra_utility(G=[0.1, 0.1, 0.1, 0.2, 0.1, 0.1], - Θ = ones(6)) # Θ can in principle be random +time_example = CRRAModel(;G = [0.1, 0.1, 0.1, 0.2, 0.1, 0.1], + Theta = ones(6)) # Theta can in principle be random -time_example.Π = [ 0.0 1.0 0.0 0.0 0.0 0.0; +time_example.Pi = [0.0 1.0 0.0 0.0 0.0 0.0; 0.0 0.0 1.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.5 0.5 0.0; 0.0 0.0 0.0 0.0 0.0 1.0; 0.0 0.0 0.0 0.0 0.0 1.0; 0.0 0.0 0.0 0.0 0.0 1.0] -# Initialize μgrid for value function iteration -μgrid = range(-0.7, 0.01, length = 200) +# Initialize mugrid for value function iteration +mugrid = range(-0.7, 0.01, length = 200) time_example.transfers = true # Government can use transfers time_sequential = SequentialAllocation(time_example) # Solve sequential problem -time_bellman = RecursiveAllocation(time_example, μgrid) +time_bellman = RecursiveAllocation(time_example, mugrid) sHist_h = [1, 2, 3, 4, 6, 6, 6] sHist_l = [1, 2, 3, 5, 6, 6, 6] -sim_seq_h = simulate(time_sequential, 1., 1, 7, sHist_h) -sim_bel_h = simulate(time_bellman, 1., 1, 7, sHist_h) -sim_seq_l = simulate(time_sequential, 1., 1, 7, sHist_l) -sim_bel_l = simulate(time_bellman, 1., 1, 7, sHist_l) +sim_seq_h = simulate(time_sequential, 1.0, 1, 7, sHist_h) +sim_bel_h = simulate(time_bellman, 1.0, 1, 7, sHist_h) +sim_seq_l = simulate(time_sequential, 1.0, 1, 7, sHist_l) +sim_bel_l = simulate(time_bellman, 1.0, 1, 7, sHist_l) using Plots @@ -1500,24 +1501,28 @@ titles = hcat("Consumption", "Labor Supply", "Government Debt", "Tax Rate", "Government Spending", "Output") sim_seq_l_plot = hcat(sim_seq_l[1:3]..., sim_seq_l[4], time_example.G[sHist_l], - time_example.Θ[sHist_l] .* sim_seq_l[2]) + time_example.Theta[sHist_l] .* sim_seq_l[2]) sim_bel_l_plot = hcat(sim_bel_l[1:3]..., sim_bel_l[5], time_example.G[sHist_l], - time_example.Θ[sHist_l] .* sim_bel_l[2]) + time_example.Theta[sHist_l] .* sim_bel_l[2]) sim_seq_h_plot = hcat(sim_seq_h[1:3]..., sim_seq_h[4], time_example.G[sHist_h], - time_example.Θ[sHist_h] .* sim_seq_h[2]) + time_example.Theta[sHist_h] .* sim_seq_h[2]) sim_bel_h_plot = hcat(sim_bel_h[1:3]..., sim_bel_h[5], time_example.G[sHist_h], - time_example.Θ[sHist_h] .* sim_bel_h[2]) -p = plot(size = (920, 750), layout =(3, 2), - xaxis=(0:6), grid=false, titlefont=Plots.font("sans-serif", 10)) + time_example.Theta[sHist_h] .* sim_bel_h[2]) +p = plot(size = (920, 750), layout = (3, 2), + xaxis = (0:6), grid = false, titlefont = Plots.font("sans-serif", 10)) plot!(p, title = titles) -for i=1:6 - plot!(p[i], 0:6, sim_seq_l_plot[:, i], marker=:circle, color=:black, lab="") - plot!(p[i], 0:6, sim_bel_l_plot[:, i], marker=:circle, color=:red, lab="") - plot!(p[i], 0:6, sim_seq_h_plot[:, i], marker=:utriangle, color=:black, lab="") - plot!(p[i], 0:6, sim_bel_h_plot[:, i], marker=:utriangle, color=:red, lab="") +for i in 1:6 + plot!(p[i], 0:6, sim_seq_l_plot[:, i], marker = :circle, color = :black, + lab = "") + plot!(p[i], 0:6, sim_bel_l_plot[:, i], marker = :circle, color = :red, + lab = "") + plot!(p[i], 0:6, sim_seq_h_plot[:, i], marker = :utriangle, color = :black, + lab = "") + plot!(p[i], 0:6, sim_bel_h_plot[:, i], marker = :utriangle, color = :red, + lab = "") end p ``` @@ -1574,21 +1579,21 @@ $$ In accordance, we will re-define our utility function ```{code-cell} julia -function log_utility(;β = 0.9, - ψ = 0.69, - Π = 0.5 * ones(2, 2), - G = [0.1, 0.2], - Θ = ones(2), - transfers = false) +function log_utility(; beta = 0.9, + psi = 0.69, + Pi = 0.5 * ones(2, 2), + G = [0.1, 0.2], + Theta = ones(2), + transfers = false) # Derivatives of utility function - U(c,n) = log(c) + ψ * log(1 - n) - Uc(c,n) = 1 ./ c - Ucc(c,n) = -c.^(-2.0) - Un(c,n) = -ψ ./ (1.0 .- n) - Unn(c,n) = -ψ ./ (1.0 .- n).^2.0 + U(c, n) = log(c) + psi * log(1 - n) + Uc(c, n) = 1 ./ c + Ucc(c, n) = -c .^ (-2.0) + Un(c, n) = -psi ./ (1.0 .- n) + Unn(c, n) = -psi ./ (1.0 .- n) .^ 2.0 n_less_than_one = true - return Model(β, Π, G, Θ, transfers, - U, Uc, Ucc, Un, Unn, n_less_than_one) + return Model(beta, Pi, G, Theta, transfers, + U, Uc, Ucc, Un, Unn, n_less_than_one) end ``` @@ -1604,7 +1609,7 @@ log_example = log_utility() log_example.transfers = true # Government can use transfers log_sequential = SequentialAllocation(log_example) # Solve sequential problem -log_bellman = RecursiveAllocation(log_example, μgrid) # Solve recursive problem +log_bellman = RecursiveAllocation(log_example, mugrid) # Solve recursive problem T = 20 sHist = [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1] @@ -1614,22 +1619,26 @@ sim_seq = simulate(log_sequential, 0.5, 1, T, sHist) sim_bel = simulate(log_bellman, 0.5, 1, T, sHist) sim_seq_plot = hcat(sim_seq[1:3]..., - sim_seq[4], log_example.G[sHist], log_example.Θ[sHist] .* sim_seq[2]) + sim_seq[4], log_example.G[sHist], + log_example.Theta[sHist] .* sim_seq[2]) sim_bel_plot = hcat(sim_bel[1:3]..., - sim_bel[5], log_example.G[sHist], log_example.Θ[sHist] .* sim_bel[2]) + sim_bel[5], log_example.G[sHist], + log_example.Theta[sHist] .* sim_bel[2]) #plot policies p = plot(size = (920, 750), layout = grid(3, 2), - xaxis=(0:T), grid=false, titlefont=Plots.font("sans-serif", 10)) + xaxis = (0:T), grid = false, titlefont = Plots.font("sans-serif", 10)) labels = fill(("", ""), 6) labels[3] = ("Complete Market", "Incomplete Market") plot!(p, title = titles) -for i = vcat(collect(1:4), 6) - plot!(p[i], sim_seq_plot[:, i], marker=:circle, color=:black, lab=labels[i][1]) - plot!(p[i], sim_bel_plot[:, i], marker=:utriangle, color=:blue, lab=labels[i][2], - legend=:bottomright) +for i in vcat(collect(1:4), 6) + plot!(p[i], sim_seq_plot[:, i], marker = :circle, color = :black, + lab = labels[i][1]) + plot!(p[i], sim_bel_plot[:, i], marker = :utriangle, color = :blue, + lab = labels[i][2], + legend = :bottomright) end -plot!(p[5], sim_seq_plot[:, 5], marker=:circle, color=:blue, lab="") +plot!(p[5], sim_seq_plot[:, 5], marker = :circle, color = :blue, lab = "") ``` When the government experiences a prolonged period of peace, it is able to reduce @@ -1653,38 +1662,29 @@ Random.seed!(42) ```{code-cell} julia T_long = 200 sim_seq_long = simulate(log_sequential, 0.5, 1, T_long) -sHist_long = sim_seq_long[end-2] +sHist_long = sim_seq_long[end - 2] sim_bel_long = simulate(log_bellman, 0.5, 1, T_long, sHist_long) sim_seq_long_plot = hcat(sim_seq_long[1:4]..., - log_example.G[sHist_long], log_example.Θ[sHist_long] .* sim_seq_long[2]) + log_example.G[sHist_long], + log_example.Theta[sHist_long] .* sim_seq_long[2]) sim_bel_long_plot = hcat(sim_bel_long[1:3]..., sim_bel_long[5], - log_example.G[sHist_long], log_example.Θ[sHist_long] .* sim_bel_long[2]) + log_example.G[sHist_long], + log_example.Theta[sHist_long] .* sim_bel_long[2]) -p = plot(size = (920, 750), layout = (3, 2), xaxis=(0:50:T_long), grid=false, - titlefont=Plots.font("sans-serif", 10)) +p = plot(size = (920, 750), layout = (3, 2), xaxis = (0:50:T_long), + grid = false, + titlefont = Plots.font("sans-serif", 10)) plot!(p, title = titles) -for i = 1:6 - plot!(p[i], sim_seq_long_plot[:, i], color=:black, linestyle=:solid, lab=labels[i][1]) - plot!(p[i], sim_bel_long_plot[:, i], color=:blue, linestyle=:dot, lab=labels[i][2], - legend=:bottomright) +for i in 1:6 + plot!(p[i], sim_seq_long_plot[:, i], color = :black, linestyle = :solid, + lab = labels[i][1]) + plot!(p[i], sim_bel_long_plot[:, i], color = :blue, linestyle = :dot, + lab = labels[i][2], + legend = :bottomright) end p ``` -```{code-cell} julia ---- -tags: [remove-cell] ---- -@testset begin - # @test sim_seq_long_plot[50, 3] ≈ 0.3951985593686047 - # @test sim_bel_long_plot[50, 3] ≈ 0.05684753244006188 atol = 1e-2 - # @test sim_seq_long_plot[100, 4] ≈ 0.340233842670859 - # @test sim_bel_long_plot[100, 4] ≈ 0.2093423366870517 atol = 1e-3 - # @test sim_seq_long_plot[200, 2] ≈ 0.5839693539786998 - # @test sim_bel_long_plot[200, 2] ≈ 0.6324036099550768 atol = 1e-3 -end -``` - [^fn_a]: In an allocation that solves the Ramsey problem and that levies distorting taxes on labor, why would the government ever want to hand revenues back to the private sector? It would not in an economy with state-contingent debt, since diff --git a/lectures/dynamic_programming_squared/dyn_stack.md b/lectures/dynamic_programming_squared/dyn_stack.md index e8c1d5d7..4527a9d8 100644 --- a/lectures/dynamic_programming_squared/dyn_stack.md +++ b/lectures/dynamic_programming_squared/dyn_stack.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (dyn_stack)= @@ -914,7 +914,8 @@ dynamic program as outlined above ```{code-cell} julia -using LaTeXStrings, QuantEcon, Plots, LinearAlgebra, Statistics, Parameters, Random +using LaTeXStrings, QuantEcon, Plots, LinearAlgebra, Statistics, + Random ``` @@ -929,16 +930,12 @@ We define named tuples and default values for the model and solver settings, and instantiate one copy of each ```{code-cell} julia -model = @with_kw (a0 = 10, - a1 = 2, - β = 0.96, - γ = 120., - n = 300) +function model(; a0 = 10, a1 = 2, beta = 0.96, gamma = 120.0, n = 300) + return (; a0, a1, beta, gamma, n) +end # things like tolerances, etc. -settings = @with_kw (tol0 = 1e-8, - tol1 = 1e-16, - tol2 = 1e-2) +settings(; tol0 = 1e-8, tol1 = 1e-16, tol2 = 1e-2) = (; tol0, tol1, tol2) defaultModel = model(); defaultSettings = settings(); @@ -947,21 +944,26 @@ defaultSettings = settings(); Now we can compute the actual policy using the LQ routine from QuantEcon.jl ```{code-cell} julia -@unpack a0, a1, β, γ, n = defaultModel -@unpack tol0, tol1, tol2 = defaultSettings +(; a0, a1, beta, gamma, n) = defaultModel +(; tol0, tol1, tol2) = defaultSettings -βs = [β^x for x = 0:n-1] +betas = [beta^x for x in 0:(n - 1)] Alhs = I + zeros(4, 4); -Alhs[4, :] = [β * a0 / (2 * γ), -β * a1 / (2 * γ), -β * a1 / γ, β] # Euler equation coefficients +Alhs[4, :] = [ + beta * a0 / (2 * gamma), + -beta * a1 / (2 * gamma), + -beta * a1 / gamma, + beta, +] # Euler equation coefficients Arhs = I + zeros(4, 4); -Arhs[3, 4] = 1.; +Arhs[3, 4] = 1.0; Alhsinv = inv(Alhs); A = Alhsinv * Arhs; -B = Alhsinv * [0, 1, 0, 0,]; +B = Alhsinv * [0, 1, 0, 0]; R = [0 -a0/2 0 0; -a0/2 a1 a1/2 0; 0 a1/2 0 0; 0 0 0 0]; -Q = γ; -lq = QuantEcon.LQ(Q, R, A, B, bet=β); +Q = gamma; +lq = QuantEcon.LQ(Q, R, A, B, bet = beta); P, F, d = stationary_values(lq) P22 = P[4:end, 4:end]; @@ -970,17 +972,17 @@ P22inv = inv(P22); H_0_0 = -P22inv * P21; # simulate forward -π_leader = zeros(n); +pi_leader = zeros(n); z0 = [1, 1, 1]; x0 = H_0_0 * z0; y0 = vcat(z0, x0); Random.seed!(1) # for reproducibility yt, ut = compute_sequence(lq, y0, n); -π_matrix = R + F' * Q * F; +pi_matrix = R + F' * Q * F; for t in 1:n - π_leader[t] = -(yt[:, t]' * π_matrix * yt[:, t]); + pi_leader[t] = -(yt[:, t]' * pi_matrix * yt[:, t]) end println("Computed policy for Stackelberg leader: $F") @@ -990,7 +992,7 @@ println("Computed policy for Stackelberg leader: $F") --- tags: [remove-cell] --- -#test F ≈ [-1.580044538772657, 0.29461312747031404, 0.6748093760774972, 6.539705936147515]' +@test F ≈ [-1.580044538772657, 0.29461312747031404, 0.6748093760774972, 6.539705936147515]' ``` ### Implied Time Series for Price and Quantities @@ -1001,12 +1003,12 @@ The following code plots the price and quantities q_leader = yt[2, 1:end]; q_follower = yt[3, 1:end]; q = q_leader + q_follower; -p = a0 .- a1*q; +p = a0 .- a1 * q; -plot(1:n+1, [q_leader, q_follower, p], - title = "Output and Prices, Stackelberg Duopoly", - labels = ["leader output" "follower output" "price"], - xlabel = L"t") +plot(1:(n + 1), [q_leader, q_follower, p], + title = "Output and Prices, Stackelberg Duopoly", + labels = ["leader output" "follower output" "price"], + xlabel = L"t") ``` ### Value of Stackelberg Leader @@ -1017,7 +1019,7 @@ We'll compute it two ways (they give identical answers -- just a check on coding and thinking) ```{code-cell} julia -v_leader_forward = sum(βs .* π_leader); +v_leader_forward = sum(betas .* pi_leader); v_leader_direct = -yt[:, 1]' * P * yt[:, 1]; println("v_leader_forward (forward sim) is $v_leader_forward") @@ -1028,13 +1030,13 @@ println("v_leader_direct is $v_leader_direct") --- tags: [remove-cell] --- -#test v_leader_forward ≈ 150.0316212532547 -#test v_leader_direct ≈ 150.03237147548967 +@test v_leader_forward ≈ 150.0316212532547 +@test v_leader_direct ≈ 150.03237147548967 ``` ```{code-cell} julia # manually check whether P is an approximate fixed point -P_next = (R + F' * Q * F + β * (A - B * F)' * P * (A - B * F)); +P_next = (R + F' * Q * F + beta * (A - B * F)' * P * (A - B * F)); all(P - P_next .< tol0) ``` @@ -1042,14 +1044,14 @@ all(P - P_next .< tol0) --- tags: [remove-cell] --- -#test all(P - P_next .< tol0) +@test all(P - P_next .< tol0) ``` ```{code-cell} julia # manually checks whether two different ways of computing the # value function give approximately the same answer v_expanded = -((y0' * R * y0 + ut[:, 1]' * Q * ut[:, 1] + - β * (y0' * (A - B * F)' * P * (A - B * F) * y0))); + beta * (y0' * (A - B * F)' * P * (A - B * F) * y0))); (v_leader_direct - v_expanded < tol0)[1, 1] ``` @@ -1057,7 +1059,7 @@ v_expanded = -((y0' * R * y0 + ut[:, 1]' * Q * ut[:, 1] + --- tags: [remove-cell] --- -#test (v_leader_direct - v_expanded < tol0)[1, 1] +@test (v_leader_direct - v_expanded < tol0)[1, 1] ``` ## Exhibiting Time Inconsistency of Stackelberg Plan @@ -1085,11 +1087,13 @@ for t in 1:n vt_reset_leader[t] = -yt_reset[:, t]' * P * yt_reset[:, t] end -p1 = plot(1:n+1, [(-F * yt)', (-F * yt_reset)'], labels = ["Stackelberg Leader" L"Continuation Leader at $t$"], - title = "Leader Control Variable", xlabel = L"t"); -p2 = plot(1:n+1, [yt[4, :], yt_reset[4, :]], title = "Follower Control Variable", xlabel = L"t", legend = false); +p1 = plot(1:(n + 1), [(-F * yt)', (-F * yt_reset)'], + labels = ["Stackelberg Leader" L"Continuation Leader at $t$"], + title = "Leader Control Variable", xlabel = L"t"); +p2 = plot(1:(n + 1), [yt[4, :], yt_reset[4, :]], + title = "Follower Control Variable", xlabel = L"t", legend = false); p3 = plot(1:n, [vt_leader, vt_reset_leader], legend = false, - xlabel = L"t", title = "Leader Value Function"); + xlabel = L"t", title = "Leader Value Function"); plot(p1, p2, p3, layout = (3, 1), size = (800, 600)) ``` @@ -1102,14 +1106,14 @@ We check that the recursive **Big** $K$ **, little** $k$ formulation of the foll $\vec q_1$ that we computed when we solved the Stackelberg problem ```{code-cell} julia -Ã = I + zeros(5, 5); -Ã[1:4, 1:4] .= A - B * F; -R̃ = [0 0 0 0 -a0/2; 0 0 0 0 a1/2; 0 0 0 0 0; 0 0 0 0 0; -a0/2 a1/2 0 0 a1]; -Q̃ = Q; -B̃ = [0, 0, 0, 0, 1]; - -lq_tilde = QuantEcon.LQ(Q̃, R̃, Ã, B̃, bet=β); -P̃, F̃, d̃ = stationary_values(lq_tilde); +A_tilde = I + zeros(5, 5); +A_tilde[1:4, 1:4] .= A - B * F; +R_tilde = [0 0 0 0 -a0/2; 0 0 0 0 a1/2; 0 0 0 0 0; 0 0 0 0 0; -a0/2 a1/2 0 0 a1]; +Q_tilde = Q; +B_tilde = [0, 0, 0, 0, 1]; + +lq_tilde = QuantEcon.LQ(Q_tilde, R_tilde, A_tilde, B_tilde, bet = beta); +P_tilde, F_tilde, d_tilde = stationary_values(lq_tilde); y0_tilde = vcat(y0, y0[3]); yt_tilde = compute_sequence(lq_tilde, y0_tilde, n)[1]; ``` @@ -1117,7 +1121,7 @@ yt_tilde = compute_sequence(lq_tilde, y0_tilde, n)[1]; ```{code-cell} julia # checks that the recursive formulation of the follower's problem gives # the same solution as the original Stackelberg problem -plot(1:n+1, [yt_tilde[5, :], yt_tilde[3, :]], labels = [L"\tilde{q}" L"q"]) +plot(1:(n + 1), [yt_tilde[5, :], yt_tilde[3, :]], labels = [L"\tilde{q}" L"q"]) ``` Note: Variables with `_tilde` are obtained from solving the follower's @@ -1132,7 +1136,7 @@ max(abs(yt_tilde[5] - yt_tilde[3])) --- tags: [remove-cell] --- -#test max(abs(yt_tilde[5] - yt_tilde[3])) ≈ 0. atol = 1e-15 +@test max(abs(yt_tilde[5] - yt_tilde[3])) ≈ 0. atol = 1e-15 ``` ```{code-cell} julia @@ -1144,7 +1148,7 @@ yt[:, 1][end] - (yt_tilde[:, 2] - yt_tilde[:, 1])[end] < tol0 --- tags: [remove-cell] --- -#test yt[:, 1][end] - (yt_tilde[:, 2] - yt_tilde[:, 1])[end] < tol0 +@test yt[:, 1][end] - (yt_tilde[:, 2] - yt_tilde[:, 1])[end] < tol0 ``` ### Explanation of Alignment @@ -1159,7 +1163,7 @@ Can you spot what features of $\tilde F$ imply this? Hint: remember the components of $X_t$ ```{code-cell} julia -F̃ # policy function in the follower's problem +F_tilde # policy function in the follower's problem ``` ```{code-cell} julia @@ -1167,43 +1171,43 @@ P # value function in the Stackelberg problem ``` ```{code-cell} julia -P̃ # value function in the follower's problem +P_tilde # value function in the follower's problem ``` ```{code-cell} julia # manually check that P is an approximate fixed point -all((P - ((R + F' * Q * F) + β * (A - B * F)' * P * (A - B * F)) .< tol0)) +all((P - ((R + F' * Q * F) + beta * (A - B * F)' * P * (A - B * F)) .< tol0)) ``` ```{code-cell} julia --- tags: [remove-cell] --- -#test all((P - ((R + F' * Q * F) + β * (A - B * F)' * P * (A - B * F)) .< tol0)) +@test all((P - ((R + F' * Q * F) + beta * (A - B * F)' * P * (A - B * F)) .< tol0)) ``` ```{code-cell} julia # compute `P_guess` using `F_tilde_star` -F̃_star = -[0, 0, 0, 1, 0]'; +F_tilde_star = -[0, 0, 0, 1, 0]'; P_guess = zeros(5, 5); for i in 1:1000 - P_guess = ((R̃ + F̃_star' * Q̃ * F̃_star) + - β * (Ã - B̃ * F̃_star)' * P_guess - * (Ã - B̃ * F̃_star)); + P_guess = ((R_tilde + F_tilde_star' * Q_tilde * F_tilde_star) + + beta * (A_tilde - B_tilde * F_tilde_star)' * P_guess + * (A_tilde - B_tilde * F_tilde_star)) end ``` ```{code-cell} julia # value function in the follower's problem --(y0_tilde' * P̃ * y0_tilde)[1, 1] +-(y0_tilde' * P_tilde * y0_tilde)[1, 1] ``` ```{code-cell} julia --- tags: [remove-cell] --- -@test -(y0_tilde' * P̃ * y0_tilde)[1, 1] ≈ 112.65590740578173 +@test -(y0_tilde' * P_tilde * y0_tilde)[1, 1] ≈ 112.65590740578173 ``` ```{code-cell} julia @@ -1220,8 +1224,8 @@ tags: [remove-cell] ```{code-cell} julia # c policy using policy iteration algorithm -F_iter = (β * inv(Q + β * B̃' * P_guess * B̃) - * B̃' * P_guess * Ã); +F_iter = (beta * inv(Q + beta * B_tilde' * P_guess * B_tilde) + * B_tilde' * P_guess * A_tilde); P_iter = zeros(5, 5); dist_vec = zeros(5, 5); @@ -1229,27 +1233,30 @@ for i in 1:100 # compute P_iter dist_vec = similar(P_iter) for j in 1:1000 - P_iter = (R̃ + F_iter' * Q * F_iter) + β * - (Ã - B̃ * F_iter)' * P_iter * - (Ã - B̃ * F_iter); + P_iter = (R_tilde + F_iter' * Q * F_iter) + + beta * + (A_tilde - B_tilde * F_iter)' * P_iter * + (A_tilde - B_tilde * F_iter) # update F_iter - F_iter = β * inv(Q + β * B̃' * P_iter * B̃) * - B̃' * P_iter * Ã; + F_iter = beta * inv(Q + beta * B_tilde' * P_iter * B_tilde) * + B_tilde' * P_iter * A_tilde - dist_vec = P_iter - ((R̃ + F_iter' * Q * F_iter) + - β * (Ã - B̃ * F_iter)' * P_iter * - (Ã - B̃ * F_iter)); + dist_vec = P_iter - ((R_tilde + F_iter' * Q * F_iter) + + beta * (A_tilde - B_tilde * F_iter)' * P_iter * + (A_tilde - B_tilde * F_iter)) end end if maximum(abs.(dist_vec)) < 1e-8 - dist_vec2 = F_iter - (β * inv(Q + β * B̃' * P_iter * B̃) * B̃' * P_iter * Ã) - if maximum(abs.(dist_vec2)) < 1e-8 - @show F_iter - else - println("The policy didn't converge: try increasing the number of outer loop iterations") - end + dist_vec2 = F_iter - + (beta * inv(Q + beta * B_tilde' * P_iter * B_tilde) * B_tilde' * + P_iter * A_tilde) + if maximum(abs.(dist_vec2)) < 1e-8 + @show F_iter + else + println("The policy didn't converge: try increasing the number of outer loop iterations") + end else println("The policy didn't converge: try increasing the number of inner loop iterations") end @@ -1259,22 +1266,23 @@ end yt_tilde_star = zeros(n, 5); yt_tilde_star[1, :] = y0_tilde; -for t in 1:n-1 - yt_tilde_star[t+1, :] = (Ã - B̃ * F̃_star) * yt_tilde_star[t, :]; +for t in 1:(n - 1) + yt_tilde_star[t + 1, :] = (A_tilde - B_tilde * F_tilde_star) * + yt_tilde_star[t, :] end plot([yt_tilde_star[:, 5], yt_tilde[3, :]], labels = [L"\tilde{q}" L"q"]) ``` ```{code-cell} julia -maximum(abs.(yt_tilde_star[:, 5] - yt_tilde[3, 1:end-1])) +maximum(abs.(yt_tilde_star[:, 5] - yt_tilde[3, 1:(end - 1)])) ``` ```{code-cell} julia --- tags: [remove-cell] --- -#test maximum(abs.(yt_tilde_star[:, 5] - yt_tilde[3, 1:end-1])) < 1e-15 +@test maximum(abs.(yt_tilde_star[:, 5] - yt_tilde[3, 1:end-1])) < 1e-15 ``` ## Markov Perfect Equilibrium @@ -1317,21 +1325,21 @@ B1 = [0, 0, 1]; B2 = [0, 1, 0]; R1 = [0 0 -a0/2; 0 0 a1/2; -a0/2 a1/2 a1]; R2 = [0 -a0/2 0; -a0/2 a1 a1/2; 0 a1/2 0]; -Q1 = Q2 = γ; -S1 = S2 = W1 = W2 = M1 = M2 = 0.; +Q1 = Q2 = gamma; +S1 = S2 = W1 = W2 = M1 = M2 = 0.0; # solve using nnash from QE F1, F2, P1, P2 = nnash(A, B1, B2, R1, R2, Q1, Q2, - S1, S2, W1, W2, M1, M2, - beta = β, - tol = tol1); + S1, S2, W1, W2, M1, M2, + beta = beta, + tol = tol1); # simulate forward AF = A - B1 * F1 - B2 * F2; z = zeros(3, n); z[:, 1] .= 1; -for t in 1:n-1 - z[:, t+1] = AF * z[:, t] +for t in 1:(n - 1) + z[:, t + 1] = AF * z[:, t] end println("Policy for F1 is $F1") @@ -1342,8 +1350,8 @@ println("Policy for F2 is $F2") --- tags: [remove-cell] --- -#test round(F1[1], digits = 4) == -0.227 -#test round(F2[2], digits = 4) == 0.0945 +@test round(F1[1], digits = 4) == -0.227 +@test round(F2[2], digits = 4) == 0.0945 ``` ```{code-cell} julia @@ -1351,7 +1359,8 @@ q1 = z[2, :]; q2 = z[3, :]; q = q1 + q2; # total output, MPE p = a0 .- a1 * q; # total price, MPE -plot([q, p], labels = ["total ouput" "total price"], title = "Output and prices, duopoly MPE", xlabel = L"t") +plot([q, p], labels = ["total ouput" "total price"], + title = "Output and prices, duopoly MPE", xlabel = L"t") ``` ```{code-cell} julia @@ -1370,11 +1379,11 @@ tags: [remove-cell] # compute values u1 = -F1 * z; u2 = -F2 * z; -π_1 = (p .* q1)' - γ * u1.^2; -π_2 = (p .* q2)' - γ * u2.^2; +pi_1 = (p .* q1)' - gamma * u1 .^ 2; +pi_2 = (p .* q2)' - gamma * u2 .^ 2; -v1_forward = π_1 * βs; -v2_forward = π_2 * βs; +v1_forward = pi_1 * betas; +v2_forward = pi_2 * betas; v1_direct = -z[:, 1]' * P1 * z[:, 1]; v2_direct = -z[:, 1]' * P2 * z[:, 1]; @@ -1387,16 +1396,16 @@ println("Firm 2: Direct is $v2_direct, Forward is $(v2_forward[1])"); --- tags: [remove-cell] --- -#test round(v1_direct, digits = 4) == 133.3296 -#test round(v2_direct, digits = 4) == 133.3296 -#test round(v1_forward[1], digits = 4) == 133.3303 -#test round(v2_forward[1], digits = 4) == 133.3303 +@test round(v1_direct, digits = 3) == 133.329 +@test round(v2_direct, digits = 3) == 133.329 +@test round(v1_forward[1], digits = 3) == 133.330 +@test round(v2_forward[1], digits = 3) == 133.330 ``` ```{code-cell} julia # sanity check -Λ_1 = A - B2 * F2; -lq1 = QuantEcon.LQ(Q1, R1, Λ_1, B1, bet = β); +Lambda_1 = A - B2 * F2; +lq1 = QuantEcon.LQ(Q1, R1, Lambda_1, B1, bet = beta); P1_ih, F1_ih, d = stationary_values(lq1); v2_direct_alt = -z[:, 1]' * P1_ih * z[:, 1] + d; @@ -1410,13 +1419,15 @@ vt_MPE = zeros(n); vt_follower = zeros(n); for t in 1:n - vt_MPE[t] = -z[:, t]' * P1 * z[:, t]; - vt_follower[t] = -yt_tilde[:, t]' * P̃ * yt_tilde[:, t]; + vt_MPE[t] = -z[:, t]' * P1 * z[:, t] + vt_follower[t] = -yt_tilde[:, t]' * P_tilde * yt_tilde[:, t] end -plot([vt_MPE, vt_leader, vt_follower], labels = ["MPE" "Stackelberg leader" "Stackelberg follower"], - title = "MPE vs Stackelberg Values", - xlabel = L"t") +plot([vt_MPE, vt_leader, vt_follower], + labels = ["MPE" "Stackelberg leader" "Stackelberg follower"], + title = "MPE vs Stackelberg Values", + xlabel = L"t", + legend = :outertopright) ``` ```{code-cell} julia @@ -1428,7 +1439,7 @@ println("vt_MPE(y0) = $(vt_MPE[1])"); ```{code-cell} julia # total difference in value b/t Stackelberg and MPE -vt_leader[1] + vt_follower[1] - 2*vt_MPE[1] +vt_leader[1] + vt_follower[1] - 2 * vt_MPE[1] ``` ```{code-cell} julia diff --git a/lectures/dynamic_programming_squared/lqramsey.md b/lectures/dynamic_programming_squared/lqramsey.md index d42e659e..84a22866 100644 --- a/lectures/dynamic_programming_squared/lqramsey.md +++ b/lectures/dynamic_programming_squared/lqramsey.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (lqramsey)= @@ -582,8 +582,7 @@ using Test ``` ```{code-cell} julia -using LaTeXStrings, QuantEcon, Plots, LinearAlgebra, Parameters - +using LaTeXStrings, QuantEcon, Plots, LinearAlgebra abstract type AbstractStochProcess end @@ -592,14 +591,13 @@ struct ContStochProcess{TF <: AbstractFloat} <: AbstractStochProcess C::Matrix{TF} end - struct DiscreteStochProcess{TF <: AbstractFloat} <: AbstractStochProcess P::Matrix{TF} x_vals::Matrix{TF} end struct Economy{TF <: AbstractFloat, SP <: AbstractStochProcess} - β::TF + beta::TF Sg::Matrix{TF} Sd::Matrix{TF} Sb::Matrix{TF} @@ -613,65 +611,62 @@ function compute_exog_sequences(econ, x) g, d, b, s = [dropdims(S * x, dims = 1) for S in (Sg, Sd, Sb, Ss)] #= solve for Lagrange multiplier in the govt budget constraint - In fact we solve for ν = λ / (1 + 2*λ). Here ν is the - solution to a quadratic equation a(ν^2 - ν) + b = 0 where + In fact we solve for nu = lambda / (1 + 2*lambda). Here nu is the + solution to a quadratic equation a(nu^2 - nu) + b = 0 where a and b are expected discounted sums of quadratic forms of the state. =# Sm = Sb - Sd - Ss return g, d, b, s, Sm end - -function compute_allocation(econ, Sm, ν, x, b) - Sg, Sd, Sb, Ss = econ.Sg, econ.Sd, econ.Sb, econ.Ss - - # solve for the allocation given ν and x - Sc = 0.5 .* (Sb + Sd - Sg - ν .* Sm) - Sl = 0.5 .* (Sb - Sd + Sg - ν .* Sm) +function compute_allocation(econ, Sm, nu, x, b) + (; Sg, Sd, Sb, Ss) = econ + # solve for the allocation given nu and x + Sc = 0.5 .* (Sb + Sd - Sg - nu .* Sm) + Sl = 0.5 .* (Sb - Sd + Sg - nu .* Sm) c = dropdims(Sc * x, dims = 1) l = dropdims(Sl * x, dims = 1) p = dropdims((Sb - Sc) * x, dims = 1) # Price without normalization - τ = 1 .- l ./ (b .- c) - rvn = l .* τ + tau = 1 .- l ./ (b .- c) + rvn = l .* tau - return Sc, Sl, c, l, p, τ, rvn + return Sc, Sl, c, l, p, tau, rvn end - -function compute_ν(a0, b0) +function compute_nu(a0, b0) disc = a0^2 - 4a0 * b0 - if disc ≥ 0 - ν = 0.5 *(a0 - sqrt(disc)) / a0 + if disc >= 0 + nu = 0.5 * (a0 - sqrt(disc)) / a0 else println("There is no Ramsey equilibrium for these parameters.") error("Government spending (economy.g) too low") end # Test that the Lagrange multiplier has the right sign - if ν * (0.5 - ν) < 0 + if nu * (0.5 - nu) < 0 print("Negative multiplier on the government budget constraint.") error("Government spending (economy.g) too low") end - return ν + return nu end - -function compute_Π(B, R, rvn, g, ξ) - π = B[2:end] - R[1:end-1] .* B[1:end-1] - rvn[1:end-1] + g[1:end-1] - Π = cumsum(π .* ξ) - return π, Π +function compute_Pi(B, R, rvn, g, xi) + pi = B[2:end] - R[1:(end - 1)] .* B[1:(end - 1)] - rvn[1:(end - 1)] + + g[1:(end - 1)] + Pi = cumsum(pi .* xi) + return pi, Pi end - -function compute_paths(econ::Economy{<:AbstractFloat, <:DiscreteStochProcess}, T) +function compute_paths(econ::Economy{<:AbstractFloat, <:DiscreteStochProcess}, + T) # simplify notation - @unpack β, Sg, Sd, Sb, Ss = econ - @unpack P, x_vals = econ.proc + (; beta, Sg, Sd, Sb, Ss) = econ + (; P, x_vals) = econ.proc mc = MarkovChain(P) - state = simulate(mc, T, init=1) + state = simulate(mc, T, init = 1) x = x_vals[:, state] # Compute exogenous sequence @@ -679,38 +674,36 @@ function compute_paths(econ::Economy{<:AbstractFloat, <:DiscreteStochProcess}, T # compute a0, b0 ns = size(P, 1) - F = I - β.*P - a0 = (F \ ((Sm * x_vals)'.^2))[1] ./ 2 - H = ((Sb - Sd + Sg) * x_vals) .* ((Sg - Ss)*x_vals) + F = I - beta .* P + a0 = (F \ ((Sm * x_vals)' .^ 2))[1] ./ 2 + H = ((Sb - Sd + Sg) * x_vals) .* ((Sg - Ss) * x_vals) b0 = (F \ H')[1] ./ 2 # compute lagrange multiplier - ν = compute_ν(a0, b0) + nu = compute_nu(a0, b0) - # Solve for the allocation given ν and x - Sc, Sl, c, l, p, τ, rvn = compute_allocation(econ, Sm, ν, x, b) + # Solve for the allocation given nu and x + Sc, Sl, c, l, p, tau, rvn = compute_allocation(econ, Sm, nu, x, b) # compute remaining variables - H = ((Sb - Sc) * x_vals) .* ((Sl - Sg) * x_vals) - (Sl * x_vals).^2 + H = ((Sb - Sc) * x_vals) .* ((Sl - Sg) * x_vals) - (Sl * x_vals) .^ 2 temp = dropdims(F * H', dims = 2) B = temp[state] ./ p H = dropdims(P[state, :] * ((Sb - Sc) * x_vals)', dims = 2) - R = p ./ (β .* H) - temp = dropdims(P[state, :] *((Sb - Sc) * x_vals)', dims = 2) - ξ = p[2:end] ./ temp[1:end-1] + R = p ./ (beta .* H) + temp = dropdims(P[state, :] * ((Sb - Sc) * x_vals)', dims = 2) + xi = p[2:end] ./ temp[1:(end - 1)] - # compute π - π, Π = compute_Π(B, R, rvn, g, ξ) + # compute pi + pi, Pi = compute_Pi(B, R, rvn, g, xi) - return (g = g, d = d, b = b, s = s, c = c, - l = l, p = p, τ = τ, rvn = rvn, B = B, - R = R, π = π, Π = Π, ξ = ξ) + return (; g, d, b, s, c, l, p, tau, rvn, B, R, pi, Pi, xi) end function compute_paths(econ::Economy{<:AbstractFloat, <:ContStochProcess}, T) # simplify notation - @unpack β, Sg, Sd, Sb, Ss = econ - @unpack A, C = econ.proc + (; beta, Sg, Sd, Sb, Ss) = econ + (; A, C) = econ.proc # generate an initial condition x0 satisfying x0 = A x0 nx, nx = size(A) @@ -725,7 +718,7 @@ function compute_paths(econ::Economy{<:AbstractFloat, <:ContStochProcess}, T) w = randn(nw, T) x[:, 1] = x0 for t in 2:T - x[:, t] = A *x[:, t-1] + C * w[:, t] + x[:, t] = A * x[:, t - 1] + C * w[:, t] end # compute exogenous sequence @@ -733,77 +726,74 @@ function compute_paths(econ::Economy{<:AbstractFloat, <:ContStochProcess}, T) # compute a0 and b0 H = Sm'Sm - a0 = 0.5 * var_quadratic_sum(A, C, H, β, x0) - H = (Sb - Sd + Sg)'*(Sg + Ss) - b0 = 0.5 * var_quadratic_sum(A, C, H, β, x0) + a0 = 0.5 * var_quadratic_sum(A, C, H, beta, x0) + H = (Sb - Sd + Sg)' * (Sg + Ss) + b0 = 0.5 * var_quadratic_sum(A, C, H, beta, x0) # compute lagrange multiplier - ν = compute_ν(a0, b0) + nu = compute_nu(a0, b0) - # solve for the allocation given ν and x - Sc, Sl, c, l, p, τ, rvn = compute_allocation(econ, Sm, ν, x, b) + # solve for the allocation given nu and x + Sc, Sl, c, l, p, tau, rvn = compute_allocation(econ, Sm, nu, x, b) # compute remaining variables - H = Sl'Sl - (Sb - Sc)' *(Sl - Sg) + H = Sl'Sl - (Sb - Sc)' * (Sl - Sg) L = zeros(T) for t in eachindex(L) - L[t] = var_quadratic_sum(A, C, H, β, x[:, t]) + L[t] = var_quadratic_sum(A, C, H, beta, x[:, t]) end B = L ./ p - Rinv = dropdims(β .* (Sb- Sc)*A*x, dims = 1) ./ p + Rinv = dropdims(beta .* (Sb - Sc) * A * x, dims = 1) ./ p R = 1 ./ Rinv AF1 = (Sb - Sc) * x[:, 2:end] - AF2 = (Sb - Sc) * A * x[:, 1:end-1] - ξ = AF1 ./ AF2 - ξ = dropdims(ξ, dims = 1) + AF2 = (Sb - Sc) * A * x[:, 1:(end - 1)] + xi = AF1 ./ AF2 + xi = dropdims(xi, dims = 1) - # compute π - π, Π = compute_Π(B, R, rvn, g, ξ) + # compute pi + pi, Pi = compute_Pi(B, R, rvn, g, xi) - return (g = g, d = d, b = b, s = s, - c = c, l = l, p = p, τ = τ, - rvn = rvn, B = B, R = R, - π = π, Π = Π, ξ = ξ) + return (; g, d, b, s, c, l, p, tau, rvn, B, R, pi, Pi, xi) end function gen_fig_1(path) T = length(path.c) - plt_1 = plot(path.rvn, lw=2, label = L"\tau_t l_t") - plot!(plt_1, path.g, lw=2, label= L"g_t") - plot!(plt_1, path.c, lw=2, label= L"c_t") - plot!(xlabel="Time", grid=true) + plt_1 = plot(path.rvn, lw = 2, label = L"\tau_t l_t") + plot!(plt_1, path.g, lw = 2, label = L"g_t") + plot!(plt_1, path.c, lw = 2, label = L"c_t") + plot!(xlabel = "Time", grid = true) - plt_2 = plot(path.rvn, lw=2, label=L"\tau_t l_t") - plot!(plt_2, path.g, lw=2, label=L"g_t") - plot!(plt_2, path.B[2:end], lw=2, label=L"B_{t+1}") - plot!(xlabel="Time", grid=true) + plt_2 = plot(path.rvn, lw = 2, label = L"\tau_t l_t") + plot!(plt_2, path.g, lw = 2, label = L"g_t") + plot!(plt_2, path.B[2:end], lw = 2, label = L"B_{t+1}") + plot!(xlabel = "Time", grid = true) - plt_3 = plot(path.R, lw=2, label=L"R_{t-1}") - plot!(plt_3, xlabel="Time", grid=true) + plt_3 = plot(path.R, lw = 2, label = L"R_{t-1}") + plot!(plt_3, xlabel = "Time", grid = true) - plt_4 = plot(path.rvn, lw=2, label=L"\tau_t l_t") - plot!(plt_4, path.g, lw=2, label=L"g_t") - plot!(plt_4, path.π, lw=2, label=L"\pi_t") - plot!(plt_4, xlabel="Time", grid=true) + plt_4 = plot(path.rvn, lw = 2, label = L"\tau_t l_t") + plot!(plt_4, path.g, lw = 2, label = L"g_t") + plot!(plt_4, path.pi, lw = 2, label = L"\pi_t") + plot!(plt_4, xlabel = "Time", grid = true) - plot(plt_1, plt_2, plt_3, plt_4, layout=(2,2), size = (800,600)) + plot(plt_1, plt_2, plt_3, plt_4, layout = (2, 2), size = (800, 600)) end function gen_fig_2(path) - T = length(path.c) - paths = [path.ξ, path.Π] + paths = [path.xi, path.Pi] labels = [L"\xi_t", L"\Pi_t"] plt_1 = plot() plt_2 = plot() plots = [plt_1, plt_2] for (plot, path, label) in zip(plots, paths, labels) - plot!(plot, 2:T, path, lw=2, label=label, xlabel="Time", grid=true) + plot!(plot, 2:T, path, lw = 2, label = label, xlabel = "Time", + grid = true) end - plot(plt_1, plt_2, layout=(2,1), size = (600,500)) + plot(plt_1, plt_2, layout = (2, 1), size = (600, 500)) end ``` @@ -847,39 +837,23 @@ using Random Random.seed!(42) # parameters -β = 1 / 1.05 -ρ, mg = .7, .35 -A = [ρ mg*(1 - ρ); 0.0 1.0] -C = [sqrt(1 - ρ^2) * mg / 10 0.0; 0 0] +beta = 1 / 1.05 +rho, mg = 0.7, 0.35 +A = [rho mg*(1 - rho); 0.0 1.0] +C = [sqrt(1 - rho^2) * mg/10 0.0; 0 0] Sg = [1.0 0.0] Sd = [0.0 0.0] Sb = [0 2.135] Ss = [0.0 0.0] proc = ContStochProcess(A, C) -econ = Economy(β, Sg, Sd, Sb, Ss, proc) +econ = Economy(beta, Sg, Sd, Sb, Ss, proc) T = 50 path = compute_paths(econ, T) gen_fig_1(path) ``` -```{code-cell} julia ---- -tags: [remove-cell] ---- -@testset begin - #test path.p[3] ≈ 1.5395294981420302 atol = 1e-3 # randomness check. - #test path.g[31] ≈ 0.366487070014081 atol = 1e-3 # stuff we plot - #test path.c[36] ≈ 0.6291101011610297 atol = 1e-3 - #test path.B[9] ≈ 0.07442403655989423 atol = 1e-3 - #test path.rvn[27] ≈ 0.35013269833342753 atol = 1e-3 - #test path.π[31] ≈ -0.05846215388377568 atol = 1e-3 - #test path.R[43] ≈ 1.0437715852385672 atol = 1e-3 - #test path.ξ[43] ≈ 1.001895202392805 atol = 1e-3 - #test path.Π[43] ≈ -0.4185282208457552 atol = 1e-3 # plot tests -end -``` The legends on the figures indicate the variables being tracked. @@ -911,48 +885,31 @@ Random.seed!(42); ```{code-cell} julia # Parameters -β = 1 / 1.05 +beta = 1 / 1.05 P = [0.8 0.2 0.0 - 0.0 0.5 0.5 - 0.0 0.0 1.0] + 0.0 0.5 0.5 + 0.0 0.0 1.0] # Possible states of the world # Each column is a state of the world. The rows are [g d b s 1] x_vals = [0.5 0.5 0.25; - 0.0 0.0 0.0; - 2.2 2.2 2.2; - 0.0 0.0 0.0; - 1.0 1.0 1.0] + 0.0 0.0 0.0; + 2.2 2.2 2.2; + 0.0 0.0 0.0; + 1.0 1.0 1.0] Sg = [1.0 0.0 0.0 0.0 0.0] Sd = [0.0 1.0 0.0 0.0 0.0] Sb = [0.0 0.0 1.0 0.0 0.0] Ss = [0.0 0.0 0.0 1.0 0.0] proc = DiscreteStochProcess(P, x_vals) -econ = Economy(β, Sg, Sd, Sb, Ss, proc) +econ = Economy(beta, Sg, Sd, Sb, Ss, proc) T = 15 path = compute_paths(econ, T) gen_fig_1(path) ``` -```{code-cell} julia ---- -tags: [remove-cell] ---- -@testset begin - #test path.p[3] ≈ 1.5852129146694405 - #test path.B[13] ≈ 0.003279632025474284 - #@test path.g ≈ [0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, 0.25, - # 0.25, 0.25] - #test path.rvn[7] ≈ 0.3188722725349599 - #test path.c[2] ≈ 0.6147870853305598 - #@test path.R ≈ [1.05, 1.05, 1.05, 1.05, 1.05, 1.0930974212983846, 1.05, 1.05, 1.05, 1.05, - # 1.05, 1.05, 1.05, 1.05, 1.05] - #@test path.ξ ≈ [1.0, 1.0, 1.0, 1.0, 1.0, 0.9589548368586813, 1.0, 1.0, 1.0, 1.0, 1.0, - # 1.0, 1.0, 1.0] -end -``` The call `gen_fig_2(path)` generates @@ -997,41 +954,26 @@ Random.seed!(42); tags: [hide-output] --- # parameters -β = 1 / 1.05 -ρ, mg = .95, .35 -A = [0. 0. 0. ρ mg*(1-ρ); +beta = 1 / 1.05 +rho, mg = .95, .35 +A = [0. 0. 0. rho mg*(1-rho); 1. 0. 0. 0. 0.; 0. 1. 0. 0. 0.; 0. 0. 1. 0. 0.; 0. 0. 0. 0. 1.] C = zeros(5, 5) -C[1, 1] = sqrt(1 - ρ^2) * mg / 8 +C[1, 1] = sqrt(1 - rho^2) * mg / 8 Sg = [1. 0. 0. 0. 0.] Sd = [0. 0. 0. 0. 0.] Sb = [0. 0. 0. 0. 2.135] Ss = [0. 0. 0. 0. 0.] proc = ContStochProcess(A, C) -econ = Economy(β, Sg, Sd, Sb, Ss, proc) +econ = Economy(beta, Sg, Sd, Sb, Ss, proc) T = 50 path = compute_paths(econ, T) ``` -```{code-cell} julia ---- -tags: [remove-cell] ---- -@testset begin - #test path.p[3] ≈ 1.524261187305079 - #test path.B[13] ≈ -0.053219518947408805 - #test path.g[7] ≈ 0.36908804521710115 - #test path.rvn[7] ≈ 0.35146870025913474 - #test path.c[2] ≈ 0.6259521929536346 - #test path.R[5][1] ≈ 1.0501742289013196 - #test path.ξ[10] ≈ 1.002202281639002 -end -``` - ```{code-cell} julia gen_fig_1(path) ``` diff --git a/lectures/dynamic_programming_squared/opt_tax_recur.md b/lectures/dynamic_programming_squared/opt_tax_recur.md index 2a6aea2e..b58ab291 100644 --- a/lectures/dynamic_programming_squared/opt_tax_recur.md +++ b/lectures/dynamic_programming_squared/opt_tax_recur.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (opt_tax_recur)= @@ -726,10 +726,10 @@ import QuantEcon: simulate mutable struct Model{TF <: AbstractFloat, TM <: AbstractMatrix{TF}, TV <: AbstractVector{TF}} - β::TF - Π::TM + beta::TF + Pi::TM G::TV - Θ::TV + Theta::TV transfers::Bool U::Function Uc::Function @@ -747,31 +747,31 @@ import QuantEcon: simulate S::TI cFB::TV nFB::TV - ΞFB::TV + XiFB::TV zFB::TV end function SequentialAllocation(model) - β, Π, G, Θ = model.β, model.Π, model.G, model.Θ - mc = MarkovChain(Π) - S = size(Π, 1) # Number of states + beta, Pi, G, Theta = model.beta, model.Pi, model.G, model.Theta + mc = MarkovChain(Pi) + S = size(Pi, 1) # Number of states # now find the first best allocation - cFB, nFB, ΞFB, zFB = find_first_best(model, S, 1) + cFB, nFB, XiFB, zFB = find_first_best(model, S, 1) - return SequentialAllocation(model, mc, S, cFB, nFB, ΞFB, zFB) + return SequentialAllocation(model, mc, S, cFB, nFB, XiFB, zFB) end function find_first_best(model, S, version) if version != 1 && version != 2 throw(ArgumentError("version must be 1 or 2")) end - β, Θ, Uc, Un, G, Π = - model.β, model.Θ, model.Uc, model.Un, model.G, model.Π + beta, Theta, Uc, Un, G, Pi = + model.beta, model.Theta, model.Uc, model.Un, model.G, model.Pi function res!(out, z) c = z[1:S] n = z[S+1:end] - out[1:S] = Θ .* Uc(c, n) + Un(c, n) - out[S+1:end] = Θ .* n - c - G + out[1:S] = Theta .* Uc(c, n) + Un(c, n) + out[S+1:end] = Theta .* n - c - G end res = nlsolve(res!, 0.5 * ones(2 * S)) @@ -782,31 +782,31 @@ function find_first_best(model, S, version) if version == 1 cFB = res.zero[1:S] nFB = res.zero[S+1:end] - ΞFB = Uc(cFB, nFB) # Multiplier on the resource constraint - zFB = vcat(cFB, nFB, ΞFB) - return cFB, nFB, ΞFB, zFB + XiFB = Uc(cFB, nFB) # Multiplier on the resource constraint + zFB = vcat(cFB, nFB, XiFB) + return cFB, nFB, XiFB, zFB elseif version == 2 cFB = res.zero[1:S] nFB = res.zero[S+1:end] IFB = Uc(cFB, nFB) .* cFB + Un(cFB, nFB) .* nFB - xFB = \(I - β * Π, IFB) + xFB = \(I - beta * Pi, IFB) zFB = [vcat(cFB[s], xFB[s], xFB) for s in 1:S] return cFB, nFB, IFB, xFB, zFB end end -function time1_allocation(pas::SequentialAllocation, μ) +function time1_allocation(pas::SequentialAllocation, mu) model, S = pas.model, pas.S - Θ, β, Π, G, Uc, Ucc, Un, Unn = - model.Θ, model.β, model.Π, model.G, + Theta, beta, Pi, G, Uc, Ucc, Un, Unn = + model.Theta, model.beta, model.Pi, model.G, model.Uc, model.Ucc, model.Un, model.Unn function FOC!(out, z) c = z[1:S] n = z[S+1:2S] - Ξ = z[2S+1:end] - out[1:S] = Uc(c, n) .- μ * (Ucc(c, n) .* c .+ Uc(c, n)) .- Ξ # FOC c - out[S+1:2S] = Un(c, n) .- μ * (Unn(c, n) .* n .+ Un(c, n)) + Θ .* Ξ # FOC n - out[2S+1:end] = Θ .* n - c - G # Resource constraint + Xi = z[2S+1:end] + out[1:S] = Uc(c, n) .- mu * (Ucc(c, n) .* c .+ Uc(c, n)) .- Xi # FOC c + out[S+1:2S] = Un(c, n) .- mu * (Unn(c, n) .* n .+ Un(c, n)) + Theta .* Xi # FOC n + out[2S+1:end] = Theta .* n - c - G # Resource constraint return out end # Find the root of the FOC @@ -815,56 +815,56 @@ function time1_allocation(pas::SequentialAllocation, μ) error("Could not find LS allocation.") end z = res.zero - c, n, Ξ = z[1:S], z[S+1:2S], z[2S+1:end] + c, n, Xi = z[1:S], z[S+1:2S], z[2S+1:end] # Now compute x Inv = Uc(c, n) .* c + Un(c, n) .* n - x = \(I - β * model.Π, Inv) - return c, n, x, Ξ + x = \(I - beta * model.Pi, Inv) + return c, n, x, Xi end function time0_allocation(pas::SequentialAllocation, B_, s_0) model = pas.model - Π, Θ, G, β = model.Π, model.Θ, model.G, model.β + Pi, Theta, G, beta = model.Pi, model.Theta, model.G, model.beta Uc, Ucc, Un, Unn = model.Uc, model.Ucc, model.Un, model.Unn # First order conditions of planner's problem function FOC!(out, z) - μ, c, n, Ξ = z[1], z[2], z[3], z[4] - xprime = time1_allocation(pas, μ)[3] + mu, c, n, Xi = z[1], z[2], z[3], z[4] + xprime = time1_allocation(pas, mu)[3] out .= vcat( - Uc(c, n) .* (c - B_) .+ Un(c, n) .* n + β * dot(Π[s_0, :], xprime), - Uc(c, n) .- μ * (Ucc(c, n) .* (c - B_) + Uc(c, n)) - Ξ, - Un(c, n) .- μ * (Unn(c, n) .* n .+ Un(c, n)) + Θ[s_0] .* Ξ, - (Θ .* n .- c - G)[s_0] + Uc(c, n) .* (c - B_) .+ Un(c, n) .* n + beta * dot(Pi[s_0, :], xprime), + Uc(c, n) .- mu * (Ucc(c, n) .* (c - B_) + Uc(c, n)) - Xi, + Un(c, n) .- mu * (Unn(c, n) .* n .+ Un(c, n)) + Theta[s_0] .* Xi, + (Theta .* n .- c - G)[s_0] ) end # Find root - res = nlsolve(FOC!, [0.0, pas.cFB[s_0], pas.nFB[s_0], pas.ΞFB[s_0]]) + res = nlsolve(FOC!, [0.0, pas.cFB[s_0], pas.nFB[s_0], pas.XiFB[s_0]]) if res.f_converged == false error("Could not find time 0 LS allocation.") end return (res.zero...,) end -function time1_value(pas::SequentialAllocation, μ) +function time1_value(pas::SequentialAllocation, mu) model = pas.model - c, n, x, Ξ = time1_allocation(pas, μ) + c, n, x, Xi = time1_allocation(pas, mu) U_val = model.U.(c, n) - V = \(I - model.β*model.Π, U_val) + V = \(I - model.beta*model.Pi, U_val) return c, n, x, V end function Τ(model, c, n) Uc, Un = model.Uc.(c, n), model.Un.(c, n) - return 1 .+ Un ./ (model.Θ .* Uc) + return 1 .+ Un ./ (model.Theta .* Uc) end function simulate(pas::SequentialAllocation, B_, s_0, T, sHist = nothing) model = pas.model - Π, β, Uc = model.Π, model.β, model.Uc + Pi, beta, Uc = model.Pi, model.beta, model.Uc if isnothing(sHist) sHist = QuantEcon.simulate(pas.mc, T, init=s_0) @@ -873,25 +873,25 @@ function simulate(pas::SequentialAllocation, B_, s_0, T, sHist = nothing) nHist = similar(cHist) Bhist = similar(cHist) ΤHist = similar(cHist) - μHist = similar(cHist) + muHist = similar(cHist) RHist = zeros(T-1) # time 0 - μ, cHist[1], nHist[1], _ = time0_allocation(pas, B_, s_0) + mu, cHist[1], nHist[1], _ = time0_allocation(pas, B_, s_0) ΤHist[1] = Τ(pas.model, cHist[1], nHist[1])[s_0] Bhist[1] = B_ - μHist[1] = μ + muHist[1] = mu # time 1 onward for t in 2:T - c, n, x, Ξ = time1_allocation(pas,μ) + c, n, x, Xi = time1_allocation(pas,mu) u_c = Uc(c,n) s = sHist[t] ΤHist[t] = Τ(pas.model, c, n)[s] - Eu_c = dot(Π[sHist[t-1],:], u_c) + Eu_c = dot(Pi[sHist[t-1],:], u_c) cHist[t], nHist[t], Bhist[t] = c[s], n[s], x[s] / u_c[s] - RHist[t-1] = Uc(cHist[t-1], nHist[t-1]) / (β * Eu_c) - μHist[t] = μ + RHist[t-1] = Uc(cHist[t-1], nHist[t-1]) / (beta * Eu_c) + muHist[t] = mu end - return cHist, nHist, Bhist, ΤHist, sHist, μHist, RHist + return cHist, nHist, Bhist, ΤHist, sHist, muHist, RHist end mutable struct BellmanEquation{TP <: Model, @@ -911,7 +911,7 @@ end end function BellmanEquation(model, xgrid, policies0) - S = size(model.Π, 1) # Number of states + S = size(model.Pi, 1) # Number of states xbar = collect(extrema(xgrid)) time_0 = false cf, nf, xprimef = policies0 @@ -924,19 +924,19 @@ end function get_policies_time1(T, i_x, x, s, Vf) model, S = T.model, T.S - β, Θ, G, Π = model.β, model.Θ, model.G, model.Π + beta, Theta, G, Pi = model.beta, model.Theta, model.G, model.Pi U, Uc, Un = model.U, model.Uc, model.Un function objf(z, grad) c, xprime = z[1], z[2:end] n = c + G[s] Vprime = [Vf[sprime](xprime[sprime]) for sprime in 1:S] - return -(U(c, n) + β * dot(Π[s, :], Vprime)) + return -(U(c, n) + beta * dot(Pi[s, :], Vprime)) end function cons(z, grad) c, xprime = z[1], z[2:end] n = c+G[s] - return x - Uc(c, n) * c - Un(c, n) * n - β * dot(Π[s, :], xprime) + return x - Uc(c, n) * c - Un(c, n) * n - beta * dot(Pi[s, :], xprime) end lb = vcat(0, T.xbar[1] * ones(S)) ub = vcat(1 - G[s], T.xbar[2] * ones(S)) @@ -962,18 +962,18 @@ end function get_policies_time0(T, B_, s0, Vf) model, S = T.model, T.S - β, Θ, G, Π = model.β, model.Θ, model.G, model.Π + beta, Theta, G, Pi = model.beta, model.Theta, model.G, model.Pi U, Uc, Un = model.U, model.Uc, model.Un function objf(z, grad) c, xprime = z[1], z[2:end] n = c + G[s0] Vprime = [Vf[sprime](xprime[sprime]) for sprime in 1:S] - return -(U(c, n) + β * dot(Π[s0, :], Vprime)) + return -(U(c, n) + beta * dot(Pi[s0, :], Vprime)) end function cons(z, grad) c, xprime = z[1], z[2:end] n = c + G[s0] - return -Uc(c, n) * (c - B_) - Un(c, n) * n - β * dot(Π[s0, :], xprime) + return -Uc(c, n) * (c - B_) - Un(c, n) * n - beta * dot(Pi[s0, :], xprime) end lb = vcat(0, T.xbar[1] * ones(S)) ub = vcat(1-G[s0], T.xbar[2] * ones(S)) @@ -1295,41 +1295,41 @@ The above steps are implemented in a type called RecursiveAllocation --- tags: [output_scroll] --- - struct RecursiveAllocation{TP <: Model, TI <: Integer, +struct RecursiveAllocation{TP <: Model, TI <: Integer, TVg <: AbstractVector, TVv <: AbstractVector, TVp <: AbstractArray} model::TP mc::MarkovChain S::TI T::BellmanEquation - μgrid::TVg + mugrid::TVg xgrid::TVg Vf::TVv policies::TVp end -function RecursiveAllocation(model, μgrid) - mc = MarkovChain(model.Π) +function RecursiveAllocation(model, mugrid) + mc = MarkovChain(model.Pi) G = model.G - S = size(model.Π, 1) # Number of states + S = size(model.Pi, 1) # Number of states # Now find the first best allocation - Vf, policies, T, xgrid = solve_time1_bellman(model, μgrid) + Vf, policies, T, xgrid = solve_time1_bellman(model, mugrid) T.time_0 = true # Bellman equation now solves time 0 problem - return RecursiveAllocation(model, mc, S, T, μgrid, xgrid, Vf, policies) + return RecursiveAllocation(model, mc, S, T, mugrid, xgrid, Vf, policies) end -function solve_time1_bellman(model, μgrid) - μgrid0 = μgrid - S = size(model.Π, 1) +function solve_time1_bellman(model, mugrid) + mugrid0 = mugrid + S = size(model.Pi, 1) # First get initial fit PP = SequentialAllocation(model) - c = zeros(length(μgrid), 2) + c = zeros(length(mugrid), 2) n = similar(c) x = similar(c) V = similar(c) - for (i, μ) in enumerate(μgrid0) - c[i, :], n[i, :], x[i, :], V[i, :] = time1_value(PP, μ) + for (i, mu) in enumerate(mugrid0) + c[i, :], n[i, :], x[i, :], V[i, :] = time1_value(PP, mu) end Vf = Vector{AbstractInterpolation}(undef, 2) cf = similar(Vf) @@ -1346,7 +1346,7 @@ function solve_time1_bellman(model, μgrid) policies = [cf, nf, xprimef] # Create xgrid xbar = [maximum(minimum(x, dims = 1)), minimum(maximum(x, dims = 1))] - xgrid = range(xbar[1], xbar[2], length = length(μgrid0)) + xgrid = range(xbar[1], xbar[2], length = length(mugrid0)) # Now iterate on bellman equation T = BellmanEquation(model, xgrid, policies) diff = 1.0 @@ -1410,19 +1410,19 @@ end function simulate(pab::RecursiveAllocation, B_, s_0, T, sHist = QuantEcon.simulate(mc, s_0, T)) model, S, policies = pab.model, pab.S, pab.policies - β, Π, Uc = model.β, model.Π, model.Uc + beta, Pi, Uc = model.beta, model.Pi, model.Uc cf, nf, xprimef = policies[1], policies[2], policies[3] cHist = zeros(T) nHist = similar(cHist) Bhist = similar(cHist) ΤHist = similar(cHist) - μHist = similar(cHist) + muHist = similar(cHist) RHist = zeros(T - 1) # time 0 cHist[1], nHist[1], xprime = time0_allocation(pab, B_, s_0) ΤHist[1] = Τ(pab.model, cHist[1], nHist[1])[s_0] Bhist[1] = B_ - μHist[1] = 0.0 + muHist[1] = 0.0 # time 1 onward for t in 2:T s, x = sHist[t], xprime[sHist[t]] @@ -1431,12 +1431,12 @@ function simulate(pab::RecursiveAllocation, B_, s_0, T, xprime = [xprimef[s, sprime](x) for sprime in 1:S] ΤHist[t] = Τ(pab.model, c, n)[s] u_c = Uc(c, n) - Eu_c = dot(Π[sHist[t-1], :], u_c) - μHist[t] = pab.Vf[s](x) - RHist[t-1] = Uc(cHist[t-1], nHist[t-1]) / (β * Eu_c) + Eu_c = dot(Pi[sHist[t-1], :], u_c) + muHist[t] = pab.Vf[s](x) + RHist[t-1] = Uc(cHist[t-1], nHist[t-1]) / (beta * Eu_c) cHist[t], nHist[t], Bhist[t] = c[s], n, x / u_c[s] end - return cHist, nHist, Bhist, ΤHist, sHist, μHist, RHist + return cHist, nHist, Bhist, ΤHist, sHist, muHist, RHist end ``` @@ -1490,30 +1490,29 @@ This utility function is implemented in the type CRRAutility ```{code-cell} julia function crra_utility(; - β = 0.9, - σ = 2.0, - γ = 2.0, - Π = 0.5 * ones(2, 2), - G = [0.1, 0.2], - Θ = ones(2), - transfers = false - ) + beta = 0.9, + sigma = 2.0, + gamma = 2.0, + Pi = 0.5 * ones(2, 2), + G = [0.1, 0.2], + Theta = ones(2), + transfers = false) function U(c, n) - if σ == 1.0 + if sigma == 1.0 U = log(c) else - U = (c.^(1.0 .- σ) .- 1.0) / (1.0 - σ) + U = (c .^ (1.0 .- sigma) .- 1.0) / (1.0 - sigma) end - return U .- n.^(1 + γ) / (1 + γ) + return U .- n .^ (1 + gamma) / (1 + gamma) end # Derivatives of utility function - Uc(c,n) = c.^(-σ) - Ucc(c,n) = -σ * c.^(-σ - 1.0) - Un(c,n) = -n.^γ - Unn(c,n) = -γ * n.^(γ - 1.0) + Uc(c, n) = c .^ (-sigma) + Ucc(c, n) = -sigma * c .^ (-sigma - 1.0) + Un(c, n) = -n .^ gamma + Unn(c, n) = -gamma * n .^ (gamma - 1.0) n_less_than_one = false - return Model(β, Π, G, Θ, transfers, - U, Uc, Ucc, Un, Unn, n_less_than_one) + return Model(beta, Pi, G, Theta, transfers, + U, Uc, Ucc, Un, Unn, n_less_than_one) end ``` @@ -1528,15 +1527,15 @@ We can now plot the Ramsey tax under both realizations of time $t = 3$ governme using Random Random.seed!(42) # For reproducible results. -M_time_example = crra_utility(G=[0.1, 0.1, 0.1, 0.2, 0.1, 0.1], - Θ=ones(6)) # Θ can in principle be random +M_time_example = crra_utility(G = [0.1, 0.1, 0.1, 0.2, 0.1, 0.1], + Theta = ones(6)) # Theta can in principle be random -M_time_example.Π = [0.0 1.0 0.0 0.0 0.0 0.0; - 0.0 0.0 1.0 0.0 0.0 0.0; - 0.0 0.0 0.0 0.5 0.5 0.0; - 0.0 0.0 0.0 0.0 0.0 1.0; - 0.0 0.0 0.0 0.0 0.0 1.0; - 0.0 0.0 0.0 0.0 0.0 1.0] +M_time_example.Pi = [0.0 1.0 0.0 0.0 0.0 0.0; + 0.0 0.0 1.0 0.0 0.0 0.0; + 0.0 0.0 0.0 0.5 0.5 0.0; + 0.0 0.0 0.0 0.0 0.0 1.0; + 0.0 0.0 0.0 0.0 0.0 1.0; + 0.0 0.0 0.0 0.0 0.0 1.0] PP_seq_time = SequentialAllocation(M_time_example) # Solve sequential problem @@ -1556,38 +1555,23 @@ titles = hcat("Consumption", "Output") sim_seq_l_plot = [sim_seq_l[1:4]..., M_time_example.G[sHist_l], - M_time_example.Θ[sHist_l].*sim_seq_l[2]] + M_time_example.Theta[sHist_l] .* sim_seq_l[2]] sim_seq_h_plot = [sim_seq_h[1:4]..., M_time_example.G[sHist_h], - M_time_example.Θ[sHist_h].*sim_seq_h[2]] - + M_time_example.Theta[sHist_h] .* sim_seq_h[2]] #plots = plot(layout=(3,2), size=(800,600)) plots = [plot(), plot(), plot(), plot(), plot(), plot()] -for i = 1:6 - plot!(plots[i], sim_seq_l_plot[i], color=:black, lw=2, - marker=:circle, markersize=2, label="") - plot!(plots[i], sim_seq_h_plot[i], color=:red, lw=2, - marker=:circle, markersize=2, label="") - plot!(plots[i], title=titles[i], grid=true) +for i in 1:6 + plot!(plots[i], sim_seq_l_plot[i], color = :black, lw = 2, + marker = :circle, markersize = 2, label = "") + plot!(plots[i], sim_seq_h_plot[i], color = :red, lw = 2, + marker = :circle, markersize = 2, label = "") + plot!(plots[i], title = titles[i], grid = true) end -plot(plots[1], plots[2], plots[3], plots[4], plots[5], plots[6], layout=(3,2), size=(800,600)) +plot(plots[1], plots[2], plots[3], plots[4], plots[5], plots[6], + layout = (3, 2), size = (800, 600)) ``` -```{code-cell} julia ---- -tags: [remove-cell] ---- -@testset begin - @test M_time_example.G[sHist_l] ≈ [0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1] - #test M_time_example.Θ[sHist_l] .* sim_seq_l[2] ≈ [1.026385289423105, 0.9945696863679917, - # 0.9945696863679917, 0.9945696863679917, - # 0.9945696863679917, 0.9945696863679917, - # 0.9945696863679917] - @test M_time_example.G[sHist_h] ≈ [0.1, 0.1, 0.1, 0.2, 0.1, 0.1, 0.1] - #test sim_seq_l[end] ≈ [1.0361020796451619, 1.111111111111111, 1.052459380877434, - # 1.111111111111111, 1.111111111111111, 1.111111111111111] -end -``` **Tax smoothing** @@ -1628,11 +1612,11 @@ The following plot illustrates how the government lowers the interest rate at time 0 by raising consumption ```{code-cell} julia -plot(sim_seq_l[end], color=:black, lw=2, - marker=:circle, markersize=2, label="") -plot!(sim_seq_h[end], color=:red, lw=2, - marker=:circle, markersize=2, label="") -plot!(title="Gross Interest Rate", grid=true) +plot(sim_seq_l[end], color = :black, lw = 2, + marker = :circle, markersize = 2, label = "") +plot!(sim_seq_h[end], color = :red, lw = 2, + marker = :circle, markersize = 2, label = "") +plot!(title = "Gross Interest Rate", grid = true) ``` ### Government Saving @@ -1701,35 +1685,25 @@ Random.seed!(42); # For reproducible results. ``` ```{code-cell} julia -M2 = crra_utility(G=[0.15], Π=ones(1, 1), Θ=[1.0]) +M2 = crra_utility(G = [0.15], Pi = ones(1, 1), Theta = [1.0]) PP_seq_time0 = SequentialAllocation(M2) # solve sequential problem B_vec = range(-1.5, 1.0, length = 100) taxpolicy = Matrix(hcat([simulate(PP_seq_time0, B_, 1, 2)[4] for B_ in B_vec]...)') -interest_rate = Matrix(hcat([simulate(PP_seq_time0, B_, 1, 3)[end] for B_ in B_vec]...)') +interest_rate = Matrix(hcat([simulate(PP_seq_time0, B_, 1, 3)[end] + for B_ in B_vec]...)') titles = ["Tax Rate" "Gross Interest Rate"] labels = [[L"Time , $t = 0$" L"Time , $t \geq 0$"], ""] -plots = plot(layout=(2,1), size =(700,600)) +plots = plot(layout = (2, 1), size = (700, 600)) for (i, series) in enumerate((taxpolicy, interest_rate)) - plot!(plots[i], B_vec, series, linewidth=2, label=labels[i]) - plot!(plots[i], title=titles[i], grid=true, legend=:topleft) + plot!(plots[i], B_vec, series, linewidth = 2, label = labels[i]) + plot!(plots[i], title = titles[i], grid = true, legend = :topleft) end plot(plots) ``` -```{code-cell} julia ---- -tags: [remove-cell] ---- -@testset begin - #test B_vec[3] ≈ -1.4494949494949494 - #test taxpolicy[2, 2] ≈ 0.0020700125847712414 - #test interest_rate[3, 1] ≈ 1.113064964490116 -end -``` - The figure indicates that if the government enters with positive debt, it sets a tax rate at $t=0$ that is less than all later tax rates. @@ -1781,9 +1755,10 @@ B1_vec = hcat([simulate(PP_seq_time0, B_, 1, 2)[3][2] for B_ in B_vec]...)' # Compute the optimal policy if the government could reset tau1_reset = Matrix(hcat([simulate(PP_seq_time0, B1, 1, 1)[4] for B1 in B1_vec]...)') -plot(B_vec, taxpolicy[:, 2], linewidth=2, label=L"\tau_1") -plot!(B_vec, tau1_reset, linewidth=2, label=L"\tau_1^R") -plot!(title="Tax Rate", xlabel="Initial Government Debt", legend=:topleft, grid=true) +plot(B_vec, taxpolicy[:, 2], linewidth = 2, label = L"\tau_1") +plot!(B_vec, tau1_reset, linewidth = 2, label = L"\tau_1^R") +plot!(title = "Tax Rate", xlabel = "Initial Government Debt", legend = :topleft, + grid = true) ``` The tax rates in the figure are equal for only two values of initial government debt. @@ -1819,21 +1794,21 @@ $$ We will write a new constructor LogUtility to represent this utility function ```{code-cell} julia -function log_utility(;β = 0.9, - ψ = 0.69, - Π = 0.5 * ones(2, 2), - G = [0.1, 0.2], - Θ = ones(2), - transfers = false) +function log_utility(; beta = 0.9, + psi = 0.69, + Pi = 0.5 * ones(2, 2), + G = [0.1, 0.2], + Theta = ones(2), + transfers = false) # Derivatives of utility function - U(c,n) = log(c) + ψ * log(1 - n) - Uc(c,n) = 1 ./ c - Ucc(c,n) = -c.^(-2.0) - Un(c,n) = -ψ ./ (1.0 .- n) - Unn(c,n) = -ψ ./ (1.0 .- n).^2.0 + U(c, n) = log(c) + psi * log(1 - n) + Uc(c, n) = 1 ./ c + Ucc(c, n) = -c .^ (-2.0) + Un(c, n) = -psi ./ (1.0 .- n) + Unn(c, n) = -psi ./ (1.0 .- n) .^ 2.0 n_less_than_one = true - return Model(β, Π, G, Θ, transfers, - U, Uc, Ucc, Un, Unn, n_less_than_one) + return Model(beta, Pi, G, Theta, transfers, + U, Uc, Ucc, Un, Unn, n_less_than_one) end ``` @@ -1853,9 +1828,9 @@ Random.seed!(42); # For reproducible results. ```{code-cell} julia M1 = log_utility() -μ_grid = range(-0.6, 0.0, length = 200) +mu_grid = range(-0.6, 0.0, length = 200) PP_seq = SequentialAllocation(M1) # Solve sequential problem -PP_bel = RecursiveAllocation(M1, μ_grid) # Solve recursive problem +PP_bel = RecursiveAllocation(M1, mu_grid) # Solve recursive problem T = 20 sHist = [1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1] @@ -1865,8 +1840,8 @@ sim_seq = simulate(PP_seq, 0.5, 1, T, sHist) sim_bel = simulate(PP_bel, 0.5, 1, T, sHist) # Plot policies -sim_seq_plot = [sim_seq[1:4]..., M1.G[sHist], M1.Θ[sHist].*sim_seq[2]] -sim_bel_plot = [sim_bel[1:4]..., M1.G[sHist], M1.Θ[sHist].*sim_bel[2]] +sim_seq_plot = [sim_seq[1:4]..., M1.G[sHist], M1.Theta[sHist] .* sim_seq[2]] +sim_bel_plot = [sim_bel[1:4]..., M1.G[sHist], M1.Theta[sHist] .* sim_bel[2]] titles = hcat("Consumption", "Labor Supply", @@ -1874,36 +1849,26 @@ titles = hcat("Consumption", "Tax Rate", "Government Spending", "Output") -labels = [["Sequential", "Recursive"], ["",""], ["",""], ["",""], ["",""], ["",""]] -plots=plot(layout=(3,2), size=(850,780)) - -for i = 1:6 - plot!(plots[i], sim_seq_plot[i], color=:black, lw=2, marker=:circle, - markersize=2, label=labels[i][1]) - plot!(plots[i], sim_bel_plot[i], color=:blue, lw=2, marker=:xcross, - markersize=2, label=labels[i][2]) - plot!(plots[i], title=titles[i], grid=true, legend=:topright) +labels = [ + ["Sequential", "Recursive"], + ["", ""], + ["", ""], + ["", ""], + ["", ""], + ["", ""], +] +plots = plot(layout = (3, 2), size = (850, 780)) + +for i in 1:6 + plot!(plots[i], sim_seq_plot[i], color = :black, lw = 2, marker = :circle, + markersize = 2, label = labels[i][1]) + plot!(plots[i], sim_bel_plot[i], color = :blue, lw = 2, marker = :xcross, + markersize = 2, label = labels[i][2]) + plot!(plots[i], title = titles[i], grid = true, legend = :topright) end plot(plots) ``` -```{code-cell} julia ---- -tags: [remove-cell] ---- -@testset begin - #test sim_seq_plot[1][14] ≈ 0.38396935397869975 - #test sim_seq_plot[2][14] ≈ 0.5839693539786998 - #test sim_seq_plot[3][14] ≈ 0.3951985593686047 - #test sim_seq_plot[4][14] ≈ 0.3631746680706347 - #test sim_seq_plot[5][14] ≈ 0.2 - #test sim_seq_plot[6][14] ≈ 0.5839693539786998 - #test sim_bel_plot[3][5] ≈ 0.5230509296608254 atol = 1e-3 - #test sim_bel_plot[5][7] ≈ 0.1 - #test sim_bel_plot[2][3] ≈ 0.5402933557593538 atol = 1e-3 -end -``` - As should be expected, the recursive and sequential solutions produce almost identical allocations. diff --git a/lectures/getting_started_julia/fundamental_types.md b/lectures/getting_started_julia/fundamental_types.md index 27134997..57e5848a 100644 --- a/lectures/getting_started_julia/fundamental_types.md +++ b/lectures/getting_started_julia/fundamental_types.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (fundamental_types)= diff --git a/lectures/getting_started_julia/getting_started.md b/lectures/getting_started_julia/getting_started.md index 01b518f8..88a6ef11 100644 --- a/lectures/getting_started_julia/getting_started.md +++ b/lectures/getting_started_julia/getting_started.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (getting_started)= diff --git a/lectures/getting_started_julia/introduction_to_types.md b/lectures/getting_started_julia/introduction_to_types.md index f756c3b2..63298324 100644 --- a/lectures/getting_started_julia/introduction_to_types.md +++ b/lectures/getting_started_julia/introduction_to_types.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (introduction_to_types)= diff --git a/lectures/getting_started_julia/julia_by_example.md b/lectures/getting_started_julia/julia_by_example.md index 18f8383a..6ba241f7 100644 --- a/lectures/getting_started_julia/julia_by_example.md +++ b/lectures/getting_started_julia/julia_by_example.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (julia_by_example)= diff --git a/lectures/getting_started_julia/julia_essentials.md b/lectures/getting_started_julia/julia_essentials.md index 29f54f4f..1a06f3ed 100644 --- a/lectures/getting_started_julia/julia_essentials.md +++ b/lectures/getting_started_julia/julia_essentials.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (julia_essentials)= diff --git a/lectures/intro.md b/lectures/intro.md index e8957b8d..7ca20f2e 100644 --- a/lectures/intro.md +++ b/lectures/intro.md @@ -11,7 +11,7 @@ kernelspec: # Quantitative Economics with Julia -This website presents a set of lectures on quantitative economic modeling, designed and written by [Jesse Perla](https://www.jesseperla.com), [Thomas J. Sargent](http://www.tomsargent.com/) and [John Stachurski](http://johnstachurski.net/). The language instruction is Julia. +This website presents a set of lectures on quantitative economic modeling. ```{tableofcontents} ``` \ No newline at end of file diff --git a/lectures/introduction_dynamics/ar1_processes.md b/lectures/introduction_dynamics/ar1_processes.md index 72994099..dd010ab2 100644 --- a/lectures/introduction_dynamics/ar1_processes.md +++ b/lectures/introduction_dynamics/ar1_processes.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (ar1)= diff --git a/lectures/introduction_dynamics/finite_markov.md b/lectures/introduction_dynamics/finite_markov.md index b42d5ebe..66995304 100644 --- a/lectures/introduction_dynamics/finite_markov.md +++ b/lectures/introduction_dynamics/finite_markov.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (mc)= diff --git a/lectures/introduction_dynamics/kalman.md b/lectures/introduction_dynamics/kalman.md index 545aa472..522f9670 100644 --- a/lectures/introduction_dynamics/kalman.md +++ b/lectures/introduction_dynamics/kalman.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (kalman)= diff --git a/lectures/introduction_dynamics/linear_models.md b/lectures/introduction_dynamics/linear_models.md index 4cb70fd5..06199f4d 100644 --- a/lectures/introduction_dynamics/linear_models.md +++ b/lectures/introduction_dynamics/linear_models.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (lssm)= diff --git a/lectures/introduction_dynamics/scalar_dynam.md b/lectures/introduction_dynamics/scalar_dynam.md index 54a39f94..145f1532 100644 --- a/lectures/introduction_dynamics/scalar_dynam.md +++ b/lectures/introduction_dynamics/scalar_dynam.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (scalar_dynam)= diff --git a/lectures/introduction_dynamics/short_path.md b/lectures/introduction_dynamics/short_path.md index 1f77d93f..b6b60456 100644 --- a/lectures/introduction_dynamics/short_path.md +++ b/lectures/introduction_dynamics/short_path.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (short_path)= diff --git a/lectures/introduction_dynamics/wealth_dynamics.md b/lectures/introduction_dynamics/wealth_dynamics.md index d94f8043..88a8da89 100644 --- a/lectures/introduction_dynamics/wealth_dynamics.md +++ b/lectures/introduction_dynamics/wealth_dynamics.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (wd)= diff --git a/lectures/more_julia/data_statistical_packages.md b/lectures/more_julia/data_statistical_packages.md index c557eb7a..47c78737 100644 --- a/lectures/more_julia/data_statistical_packages.md +++ b/lectures/more_julia/data_statistical_packages.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (data_statistical_packages)= diff --git a/lectures/more_julia/general_packages.md b/lectures/more_julia/general_packages.md index e126c136..df61cc13 100644 --- a/lectures/more_julia/general_packages.md +++ b/lectures/more_julia/general_packages.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (general_packages)= diff --git a/lectures/more_julia/generic_programming.md b/lectures/more_julia/generic_programming.md index bdeec031..f7d4fdc4 100644 --- a/lectures/more_julia/generic_programming.md +++ b/lectures/more_julia/generic_programming.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (generic_programming)= diff --git a/lectures/more_julia/optimization_solver_packages.md b/lectures/more_julia/optimization_solver_packages.md index 5d272770..af179d55 100644 --- a/lectures/more_julia/optimization_solver_packages.md +++ b/lectures/more_julia/optimization_solver_packages.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (optimization_solver_packages)= @@ -35,7 +35,7 @@ In this lecture we introduce a few of the Julia libraries that we've found parti tags: [hide-output] --- using LinearAlgebra, Statistics -using ForwardDiff, Zygote, Optim, JuMP, Ipopt, BlackBoxOptim, Roots, NLsolve, LeastSquaresOptim +using ForwardDiff, Optim, JuMP, Ipopt, Roots, NLsolve using Optim: converged, maximum, maximizer, minimizer, iterations #some extra functions ``` @@ -222,80 +222,17 @@ dsqrt(x) = ForwardDiff.derivative(squareroot, x) dsqrt(2.0) ``` -### Zygote.jl +### Reverse-Mode AD Unlike forward-mode auto-differentiation, reverse-mode is very difficult to implement efficiently, and there are many variations on the best approach. Many reverse-mode packages are connected to machine-learning packages, since the efficient gradients of $R^N \to R$ loss functions are necessary for the gradient descent optimization algorithms used in machine learning. -One recent package is [Zygote.jl](https://github.com/FluxML/Zygote.jl), which is used in the Flux.jl framework. +At this point, Julia does not have a single consistently usable reverse-mode AD package without rough edges, but a few key ones to consider are: -```{code-cell} julia -using Zygote - -h(x, y) = 3x^2 + 2x + 1 + y * x - y -gradient(h, 3.0, 5.0) -``` - -Here we see that Zygote has a gradient function as the interface, which returns a tuple. - -You could create this as an operator if you wanted to., - -```{code-cell} julia -D(f) = x -> gradient(f, x)[1] # returns first in tuple - -D_sin = D(sin) -D_sin(4.0) -``` - -For functions of one (Julia) variable, we can find the by simply using the `'` after a function name - -```{code-cell} julia -using Statistics -p(x) = mean(abs, x) -p'([1.0, 3.0, -2.0]) -``` - -Or, using the complicated iterative function we defined for the squareroot, - -```{code-cell} julia -squareroot'(2.0) -``` - -Zygote supports combinations of vectors and scalars as the function parameters. - -```{code-cell} julia -h(x, n) = (sum(x .^ n))^(1 / n) -gradient(h, [1.0, 4.0, 6.0], 2.0) -``` - -The gradients can be very high dimensional. For example, to do a simple nonlinear optimization problem -with 1 million dimensions, solved in a few seconds. - -```{code-cell} julia -using Optim, LinearAlgebra -N = 1000000 -y = rand(N) -lambda = 0.01 -obj(x) = sum((x .- y) .^ 2) + lambda * norm(x) - -x_iv = rand(N) -function g!(G, x) - G .= obj'(x) -end - -results = optimize(obj, g!, x_iv, LBFGS()) # or ConjugateGradient() -println("minimum = $(results.minimum) with in " * - "$(results.iterations) iterations") -``` - -Caution: while Zygote is the most exciting reverse-mode AD implementation in Julia, it has many rough edges. - -- If you write a function, take its gradient, and then modify the function, you need to call `Zygote.refresh()` or else the gradient will be out of sync. This may not apply for Julia 1.3+. -- It provides no features for getting Jacobians, so you would have to ask for each row of the Jacobian separately. That said, you - probably want to use `ForwardDiff.jl` for Jacobians if the dimension of the output is similar to the dimension of the input. -- You cannot, in the current release, use mutating functions (e.g. modify a value in an array/etc.) although that feature is in progress. -- Compiling can be very slow for complicated functions. +- [ReverseDiff.jl](https://github.com/JuliaDiff/ReverseDiff.jl), a relatively dependable but limited package. Not really intended for standard ML-pipline usage +- [Zygote.jl](https://github.com/FluxML/Zygote.jl), which is flexible but buggy and less reliable. In a slow process of deprecation, but often the primary alternative. +- [Enzyme.jl](https://enzyme.mit.edu/julia/stable/), which is the most promising (and supports both forward and reverse mode). However, the usage is more tailored for scientific machine learning and scalar functions rather than fast GPU kernels, and it relies on a innovative (but not fully stable) approach to compilation. ## Optimization @@ -482,17 +419,6 @@ println("x = ", value(x), " y = ", value(y)) Another package for doing global optimization without derivatives is [BlackBoxOptim.jl](https://github.com/robertfeldt/BlackBoxOptim.jl). -To see an example from the documentation - -```{code-cell} julia -using BlackBoxOptim - -function rosenbrock2d(x) - return (1.0 - x[1])^2 + 100.0 * (x[2] - x[1]^2)^2 -end - -results = bboptimize(rosenbrock2d; SearchRange = (-5.0, 5.0), NumDimensions = 2); -``` An example for [parallel execution](https://github.com/robertfeldt/BlackBoxOptim.jl/blob/master/examples/rosenbrock_parallel.jl) of the objective is provided. @@ -586,46 +512,6 @@ If $M = N$ and we know a root $F(x^*) = 0$ to the system of equations exists, th An implementation of NLS is given in [LeastSquaresOptim.jl](https://github.com/matthieugomez/LeastSquaresOptim.jl). -From the documentation - -```{code-cell} julia -using LeastSquaresOptim -function rosenbrock(x) - [1 - x[1], 100 * (x[2] - x[1]^2)] -end -LeastSquaresOptim.optimize(rosenbrock, zeros(2), Dogleg()) -``` - -**Note:** Because there is a name clash between `Optim.jl` and this package, to use both we need to qualify the use of the `optimize` function (i.e. `LeastSquaresOptim.optimize`). - -Here, by default it will use AD with `ForwardDiff.jl` to calculate the Jacobian, -but you could also provide your own calculation of the Jacobian (analytical or using finite differences) and/or calculate the function inplace. - -```{code-cell} julia -function rosenbrock_f!(out, x) - out[1] = 1 - x[1] - out[2] = 100 * (x[2] - x[1]^2) -end -LeastSquaresOptim.optimize!(LeastSquaresProblem(x = zeros(2), - f! = rosenbrock_f!, - output_length = 2)) - -# if you want to use gradient -function rosenbrock_g!(J, x) - J[1, 1] = -1 - J[1, 2] = 0 - J[2, 1] = -200 * x[1] - J[2, 2] = 100 -end -LeastSquaresOptim.optimize!(LeastSquaresProblem(x = zeros(2), - f! = rosenbrock_f!, - g! = rosenbrock_g!, - output_length = 2)) -``` - -## Additional Notes - -Watch [this video](https://www.youtube.com/watch?v=vAp6nUMrKYg&feature=youtu.be) from one of Julia's creators on automatic differentiation. ## Exercises diff --git a/lectures/multi_agent_models/aiyagari.md b/lectures/multi_agent_models/aiyagari.md index 11ae13bb..0253cfaa 100644 --- a/lectures/multi_agent_models/aiyagari.md +++ b/lectures/multi_agent_models/aiyagari.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (aiyagari)= @@ -195,6 +195,7 @@ The object also includes a default set of parameters that we'll adopt unless oth ```{code-cell} julia using LinearAlgebra, Statistics +using LaTeXStrings, Plots, QuantEcon ``` ```{code-cell} julia @@ -205,30 +206,27 @@ using Test, Random ``` ```{code-cell} julia -using LaTeXStrings, Parameters, Plots, QuantEcon - -``` - -```{code-cell} julia -Household = @with_kw (r = 0.01, - w = 1.0, - σ = 1.0, - β = 0.96, - z_chain = MarkovChain([0.9 0.1; 0.1 0.9], [0.1; 1.0]), - a_min = 1e-10, - a_max = 18.0, - a_size = 200, - a_vals = range(a_min, a_max, length = a_size), - z_size = length(z_chain.state_values), - n = a_size * z_size, - s_vals = gridmake(a_vals, z_chain.state_values), - s_i_vals = gridmake(1:a_size, 1:z_size), - u = σ == 1 ? x -> log(x) : x -> (x^(1 - σ) - 1) / (1 - σ), - R = setup_R!(fill(-Inf, n, a_size), a_vals, s_vals, r, w, u), - # -Inf is the utility of dying (0 consumption) - Q = setup_Q!(zeros(n, a_size, n), s_i_vals, z_chain)) - -function setup_Q!(Q, s_i_vals, z_chain) +function Household(; r = 0.01, + w = 1.0, + sigma = 1.0, + beta = 0.96, + z_chain = MarkovChain([0.9 0.1; 0.1 0.9], [0.1; 1.0]), + a_min = 1e-10, + a_max = 18.0, + a_size = 200, + a_vals = range(a_min, a_max, length = a_size), + # -Inf is the utility of dying (0 consumption) + u = sigma == 1 ? x -> log(x) : + x -> (x^(1 - sigma) - 1) / (1 - sigma)) + + # Create grids + z_size = length(z_chain.state_values) + n = a_size * z_size + s_vals = gridmake(a_vals, z_chain.state_values) + s_i_vals = gridmake(1:a_size, 1:z_size) + + # Fill in the Q and R + Q = zeros(n, a_size, n) for next_s_i in 1:size(Q, 3) for a_i in 1:size(Q, 2) for s_i in 1:size(Q, 1) @@ -241,10 +239,8 @@ function setup_Q!(Q, s_i_vals, z_chain) end end end - return Q -end -function setup_R!(R, a_vals, s_vals, r, w, u) + R = fill(-Inf, n, a_size) for new_a_i in 1:size(R, 2) a_new = a_vals[new_a_i] for s_i in 1:size(R, 1) @@ -256,7 +252,8 @@ function setup_R!(R, a_vals, s_vals, r, w, u) end end end - return R + return (; r, w, sigma, beta, z_chain, a_min, a_max, a_size, a_vals, z_size, + n, s_vals, s_i_vals, u, R, Q) end ``` @@ -271,16 +268,16 @@ Random.seed!(42); ```{code-cell} julia # Create an instance of Household -am = Household(a_max = 20.0, r = 0.03, w = 0.956) +am = Household(; a_max = 20.0, r = 0.03, w = 0.956) # Use the instance to build a discrete dynamic program -am_ddp = DiscreteDP(am.R, am.Q, am.β) +am_ddp = DiscreteDP(am.R, am.Q, am.beta) # Solve using policy function iteration results = solve(am_ddp, PFI) # Simplify names -(;z_size, a_size, n, a_vals) = am +(; z_size, a_size, n, a_vals) = am z_vals = am.z_chain.state_values # Get all optimal actions across the set of @@ -298,10 +295,10 @@ plot!(xlabel = "current assets", ylabel = "next period assets", grid = false) tags: [remove-cell] --- @testset begin - #test a_vals[4] ≈ 0.3015075377869347 - #test a_star[4] ≈ 0.2010050252246231 - #test results.v[4] ≈ -27.48291672016239 - #test z_vals ≈ [0.1, 1.0] + @test a_vals[4] ≈ 0.3015075377869347 + @test a_star[4] ≈ 0.2010050252246231 + @test results.v[4] ≈ -27.48291672016239 + @test z_vals ≈ [0.1, 1.0] end ``` @@ -323,29 +320,16 @@ Random.seed!(42); ``` ```{code-cell} julia -# Firms' parameters -const A = 1 -const N = 1 -const α = 0.33 -const β = 0.96 -const δ = 0.05 - -function r_to_w(r) - return A * (1 - α) * (A * α / (r + δ)) ^ (α / (1 - α)) -end -function rd(K) - return A * α * (N / K) ^ (1 - α) - δ -end - -function prices_to_capital_stock(am, r) +# Calculate supply of capital for a given r +function prices_to_capital_stock(r; beta, A, N, alpha, delta, a_max) + # Create an instance of Household given the parameters - # Set up problem - w = r_to_w(r) - (;a_vals, s_vals, u) = am - setup_R!(am.R, a_vals, s_vals, r, w, u) + # Calculate the equilibrium wages + w = A * (1 - alpha) * (A * alpha / (r + delta))^(alpha / (1 - alpha)) + am = Household(; beta, a_max, w, r) - aiyagari_ddp = DiscreteDP(am.R, am.Q, am.β) + aiyagari_ddp = DiscreteDP(am.R, am.Q, am.beta) # Compute the optimal policy results = solve(aiyagari_ddp, PFI) @@ -354,33 +338,39 @@ function prices_to_capital_stock(am, r) stationary_probs = stationary_distributions(results.mc)[:, 1][1] # Return K - return dot(am.s_vals[:, 1], stationary_probs) + K = dot(am.s_vals[:, 1], stationary_probs) + + # Return capital + return K end -# Create an instance of Household -am = Household(β = β, a_max = 20.0) +# Inverse Demand for capital +function r_inverse_demand(K; A, N, alpha, delta) + return A * alpha * (N / K)^(1 - alpha) - delta +end # Create a grid of r values at which to compute demand and supply of capital r_vals = range(0.005, 0.04, length = 20) -# Compute supply of capital -k_vals = prices_to_capital_stock.(Ref(am), r_vals) +# Firms' parameters +A = 1 +N = 1 +alpha = 0.33 +beta = 0.96 +delta = 0.05 +a_max = 20.0 -# Plot against demand for capital by firms -demand = rd.(k_vals) -labels = ["demand for capital" "supply of capital"] -plot(k_vals, [demand r_vals], label = labels, lw = 2, alpha = 0.6) -plot!(xlabel = "capital", ylabel = "interest rate", xlim = (2, 14), ylim = (0.0, 0.1)) -``` +prices_to_capital_stock(r_vals[1]; A, N, alpha, beta, delta, a_max) -```{code-cell} julia ---- -tags: [remove-cell] ---- -@testset begin - #test k_vals[4] ≈ 3.920775511050653 - #test demand[4] ≈ 0.08211578674946372 - #test r_vals[4] ≈ 0.010526315789473684 -end -``` +# Compute supply of capital +k_vals = prices_to_capital_stock.(r_vals; A, N, alpha, beta, delta, a_max) + +r_inverse_demand_vals = r_inverse_demand.(k_vals; A, N, alpha, delta) +# Plot against demand for capital by firms +labels = ["demand for capital" "supply of capital"] +plot(k_vals, [r_inverse_demand_vals r_vals], label = labels, lw = 2, + alpha = 0.6) +plot!(xlabel = "capital", ylabel = "interest rate", xlim = (2, 14), + ylim = (0.0, 0.1)) +``` \ No newline at end of file diff --git a/lectures/multi_agent_models/arellano.md b/lectures/multi_agent_models/arellano.md index 8b0fb7cb..41805bcc 100644 --- a/lectures/multi_agent_models/arellano.md +++ b/lectures/multi_agent_models/arellano.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (arellano)= @@ -301,7 +301,7 @@ The code can be found below: tags: [hide-output] --- using LinearAlgebra, Statistics -using LaTeXStrings, Parameters, QuantEcon, DataFrames, Plots, Random +using LaTeXStrings, QuantEcon, DataFrames, Plots, Random ``` ```{code-cell} julia @@ -312,25 +312,25 @@ using Test ``` ```{code-cell} julia -function ArellanoEconomy(;β = .953, - γ = 2., - r = 0.017, - ρ = 0.945, - η = 0.025, - θ = 0.282, - ny = 21, - nB = 251) +function ArellanoEconomy(; beta = 0.953, + gamma = 2.0, + r = 0.017, + rho = 0.945, + eta = 0.025, + theta = 0.282, + ny = 21, + nB = 251) # create grids - Bgrid = collect(range(-.4, .4, length = nB)) - mc = tauchen(ny, ρ, η) - Π = mc.p + Bgrid = collect(range(-0.4, 0.4, length = nB)) + mc = tauchen(ny, rho, eta) + Pi = mc.p ygrid = exp.(mc.state_values) - ydefgrid = min.(.969 * mean(ygrid), ygrid) + ydefgrid = min.(0.969 * mean(ygrid), ygrid) # define value functions # notice ordered different than Python to take - # advantage of column major layout of Julia) + # advantage of column major layout of Julia vf = zeros(nB, ny) vd = zeros(1, ny) vc = zeros(nB, ny) @@ -338,13 +338,12 @@ function ArellanoEconomy(;β = .953, q = ones(nB, ny) .* (1 / (1 + r)) defprob = zeros(nB, ny) - return (β = β, γ = γ, r = r, ρ = ρ, η = η, θ = θ, ny = ny, - nB = nB, ygrid = ygrid, ydefgrid = ydefgrid, - Bgrid = Bgrid, Π = Π, vf = vf, vd = vd, vc = vc, - policy = policy, q = q, defprob = defprob) + return (; beta, gamma, r, rho, eta, theta, ny, + nB, ygrid, ydefgrid, Bgrid, Pi, vf, vd, vc, + policy, q, defprob) end -u(ae, c) = c^(1 - ae.γ) / (1 - ae.γ) +u(ae, c) = c^(1 - ae.gamma) / (1 - ae.gamma) function one_step_update!(ae, EV, @@ -352,16 +351,17 @@ function one_step_update!(ae, EVc) # unpack stuff - @unpack β, γ, r, ρ, η, θ, ny, nB = ae - @unpack ygrid, ydefgrid, Bgrid, Π, vf, vd, vc, policy, q, defprob = ae - zero_ind = searchsortedfirst(Bgrid, 0.) + (; beta, gamma, r, rho, eta, theta, ny, nB) = ae + (; ygrid, ydefgrid, Bgrid, Pi, vf, vd, vc, policy, q, defprob) = ae + zero_ind = searchsortedfirst(Bgrid, 0.0) for iy in 1:ny y = ae.ygrid[iy] ydef = ae.ydefgrid[iy] # value of being in default with income y - defval = u(ae, ydef) + β * (θ * EVc[zero_ind, iy] + (1-θ) * EVd[1, iy]) + defval = u(ae, ydef) + + beta * (theta * EVc[zero_ind, iy] + (1 - theta) * EVd[1, iy]) ae.vd[1, iy] = defval for ib in 1:nB @@ -369,15 +369,14 @@ function one_step_update!(ae, current_max = -1e14 pol_ind = 0 - for ib_next=1:nB - c = max(y - ae.q[ib_next, iy]*Bgrid[ib_next] + B, 1e-14) - m = u(ae, c) + β * EV[ib_next, iy] + for ib_next in 1:nB + c = max(y - ae.q[ib_next, iy] * Bgrid[ib_next] + B, 1e-14) + m = u(ae, c) + beta * EV[ib_next, iy] if m > current_max current_max = m pol_ind = ib_next end - end # update value and policy functions @@ -390,14 +389,14 @@ end function compute_prices!(ae) # unpack parameters - @unpack β, γ, r, ρ, η, θ, ny, nB = ae + (; beta, gamma, r, rho, eta, theta, ny, nB) = ae # create default values with a matching size vd_compat = repeat(ae.vd, nB) default_states = vd_compat .> ae.vc # update default probabilities and prices - copyto!(ae.defprob, default_states * ae.Π') + copyto!(ae.defprob, default_states * ae.Pi') copyto!(ae.q, (1 .- ae.defprob) / (1 + r)) return end @@ -405,13 +404,13 @@ end function vfi!(ae; tol = 1e-8, maxit = 10000) # unpack stuff - @unpack β, γ, r, ρ, η, θ, ny, nB = ae - @unpack ygrid, ydefgrid, Bgrid, Π, vf, vd, vc, policy, q, defprob = ae - Πt = Π' + (; beta, gamma, r, rho, eta, theta, ny, nB) = ae + (; ygrid, ydefgrid, Bgrid, Pi, vf, vd, vc, policy, q, defprob) = ae + Pit = Pi' # Iteration stuff it = 0 - dist = 10. + dist = 10.0 # allocate memory for update V_upd = similar(ae.vf) @@ -420,11 +419,11 @@ function vfi!(ae; tol = 1e-8, maxit = 10000) it += 1 # compute expectations for this iterations - # (we need Π' because of order value function dimensions) + # (we need Pi' because of order value function dimensions) copyto!(V_upd, ae.vf) - EV = ae.vf * Πt - EVd = ae.vd * Πt - EVc = ae.vc * Πt + EV = ae.vf * Pit + EVd = ae.vd * Pit + EVc = ae.vc * Pit # update value function one_step_update!(ae, EV, EVd, EVc) @@ -443,20 +442,19 @@ end function QuantEcon.simulate(ae, capT = 5000; y_init = mean(ae.ygrid), - B_init = mean(ae.Bgrid), - ) + B_init = mean(ae.Bgrid),) # get initial indices - zero_index = searchsortedfirst(ae.Bgrid, 0.) + zero_index = searchsortedfirst(ae.Bgrid, 0.0) y_init_ind = searchsortedfirst(ae.ygrid, y_init) B_init_ind = searchsortedfirst(ae.Bgrid, B_init) # create a QE MarkovChain - mc = MarkovChain(ae.Π) + mc = MarkovChain(ae.Pi) y_sim_indices = simulate(mc, capT + 1; init = y_init_ind) # allocate and fill output - y_sim_val = zeros(capT+1) + y_sim_val = zeros(capT + 1) B_sim_val, q_sim_val = similar(y_sim_val), similar(y_sim_val) B_sim_indices = fill(0, capT + 1) default_status = fill(false, capT + 1) @@ -478,7 +476,7 @@ function QuantEcon.simulate(ae, default_status[t + 1] = true y_sim_val[t] = ae.ydefgrid[y_sim_indices[t]] B_sim_indices[t + 1] = zero_index - B_sim_val[t+1] = 0. + B_sim_val[t + 1] = 0.0 q_sim_val[t] = ae.q[zero_index, y_sim_indices[t]] else default_status[t] = false @@ -488,15 +486,15 @@ function QuantEcon.simulate(ae, q_sim_val[t] = ae.q[B_sim_indices[t + 1], y_sim_indices[t]] end - # if you are in default + # if you are in default else B_sim_indices[t + 1] = zero_index - B_sim_val[t+1] = 0. + B_sim_val[t + 1] = 0.0 y_sim_val[t] = ae.ydefgrid[y_sim_indices[t]] q_sim_val[t] = ae.q[zero_index, y_sim_indices[t]] - # with probability θ exit default status - default_status[t + 1] = rand() ≥ ae.θ + # with probability theta exit default status + default_status[t + 1] = rand() >= ae.theta end end @@ -591,14 +589,14 @@ using DataFrames, Plots Compute the value function, policy and equilibrium prices ```{code-cell} julia -ae = ArellanoEconomy(β = .953, # time discount rate - γ = 2., # risk aversion - r = 0.017, # international interest rate - ρ = .945, # persistence in output - η = 0.025, # st dev of output shock - θ = 0.282, # prob of regaining access - ny = 21, # number of points in y grid - nB = 251) # number of points in B grid +ae = ArellanoEconomy(beta = 0.953, # time discount rate + gamma = 2.0, # risk aversion + r = 0.017, # international interest rate + rho = 0.945, # persistence in output + eta = 0.025, # st dev of output shock + theta = 0.282, # prob of regaining access + ny = 21, # number of points in y grid + nB = 251) # number of points in B grid # now solve the model on the grid. vfi!(ae) @@ -625,9 +623,9 @@ iy_high, iy_low = map(x -> searchsortedfirst(ae.ygrid, x), (high, low)) x = zeros(0) q_low = zeros(0) q_high = zeros(0) -for i in 1:ae.nB +for i in 1:(ae.nB) b = ae.Bgrid[i] - if -0.35 ≤ b ≤ 0 # to match fig 3 of Arellano + if -0.35 <= b <= 0 # to match fig 3 of Arellano push!(x, b) push!(q_low, ae.q[i, iy_low]) push!(q_high, ae.q[i, iy_high]) @@ -638,7 +636,8 @@ end plot(x, q_low, label = "Low") plot!(x, q_high, label = "High") plot!(title = L"Bond price schedule $q(y, B^\prime)$", - xlabel = L"B^\prime", ylabel = L"q", legend_title = L"y", legend = :topleft) + xlabel = L"B^\prime", ylabel = L"q", legend_title = L"y", + legend = :topleft) ``` ```{code-cell} julia @@ -658,17 +657,18 @@ Draw a plot of the value functions plot(ae.Bgrid, ae.vf[:, iy_low], label = "Low") plot!(ae.Bgrid, ae.vf[:, iy_high], label = "High") plot!(xlabel = L"B", ylabel = L"V(y,B)", title = "Value functions", - legend_title=L"y", legend = :topleft) + legend_title = L"y", legend = :topleft) ``` Draw a heat map for default probability ```{code-cell} julia -heatmap(ae.Bgrid[1:end-1], - ae.ygrid[2:end], - reshape(clamp.(vec(ae.defprob[1:end - 1, 1:end - 1]), 0, 1), 250, 20)') +heatmap(ae.Bgrid[1:(end - 1)], + ae.ygrid[2:end], + reshape(clamp.(vec(ae.defprob[1:(end - 1), 1:(end - 1)]), 0, 1), 250, + 20)') plot!(xlabel = L"B^\prime", ylabel = L"y", title = "Probability of default", - legend = :topleft) + legend = :topleft) ``` Plot a time series of major variables simulated from the model @@ -696,10 +696,12 @@ plots = plot(layout = (3, 1), size = (700, 800)) # Plot the three variables, and for each each variable shading the period(s) of default # in grey for i in 1:3 - plot!(plots[i], 1:T, y_vals[i], title = titles[i], xlabel = "time", label = "", lw = 2) + plot!(plots[i], 1:T, y_vals[i], title = titles[i], xlabel = "time", + label = "", lw = 2) for j in 1:length(def_start) plot!(plots[i], [def_start[j], def_end[j]], fill(maximum(y_vals[i]), 2), - fillrange = [extrema(y_vals[i])...], fcolor = :grey, falpha = 0.3, label = "") + fillrange = [extrema(y_vals[i])...], fcolor = :grey, falpha = 0.3, + label = "") end end diff --git a/lectures/multi_agent_models/harrison_kreps.md b/lectures/multi_agent_models/harrison_kreps.md index 156ac748..2517dfdf 100644 --- a/lectures/multi_agent_models/harrison_kreps.md +++ b/lectures/multi_agent_models/harrison_kreps.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (harrison_kreps)= @@ -290,12 +290,12 @@ Here's a function that can be used to compute these values using LinearAlgebra function price_single_beliefs(transition, dividend_payoff; - β=.75) + beta = 0.75) # First compute inverse piece - imbq_inv = inv(I - β * transition) + imbq_inv = inv(I - beta * transition) # Next compute prices - prices = β * ((imbq_inv * transition) * dividend_payoff) + prices = beta * ((imbq_inv * transition) * dividend_payoff) return prices end @@ -416,28 +416,28 @@ Here's code to solve for $\bar p$, $\hat p_a$ and $\hat p_b$ using the iterative ```{code-cell} julia function price_optimistic_beliefs(transitions, dividend_payoff; - β=.75, max_iter=50000, - tol=1e-16) + beta = 0.75, max_iter = 50000, + tol = 1e-16) # We will guess an initial price vector of [0, 0] - p_new = [0,0] - p_old = [10.0,10.0] + p_new = [0, 0] + p_old = [10.0, 10.0] # We know this is a contraction mapping, so we can iterate to conv - for i ∈ 1:max_iter + for i in 1:max_iter p_old = p_new temp = [maximum((q * p_old) + (q * dividend_payoff)) - for q in transitions] - p_new = β * temp + for q in transitions] + p_new = beta * temp # If we succed in converging, break out of for loop - if maximum(sqrt, ((p_new - p_old).^2)) < 1e-12 + if maximum(sqrt, ((p_new - p_old) .^ 2)) < 1e-12 break end end - temp=[minimum((q * p_old) + (q * dividend_payoff)) for q in transitions] - ptwiddle = β * temp + temp = [minimum((q * p_old) + (q * dividend_payoff)) for q in transitions] + ptwiddle = beta * temp phat_a = [p_new[1], ptwiddle[2]] phat_b = [ptwiddle[1], p_new[2]] @@ -484,22 +484,21 @@ Constraints on short sales prevent that. Here's code to solve for $\check p$ using iteration ```{code-cell} julia -function price_pessimistic_beliefs(transitions, - dividend_payoff; - β=.75, max_iter=50000, - tol=1e-16) +function price_pessimistic_beliefs(transitions, dividend_payoff; beta = 0.75, + max_iter = 50000, tol = 1e-16) # We will guess an initial price vector of [0, 0] p_new = [0, 0] p_old = [10.0, 10.0] # We know this is a contraction mapping, so we can iterate to conv - for i ∈ 1:max_iter + for i in 1:max_iter p_old = p_new - temp=[minimum((q * p_old) + (q* dividend_payoff)) for q in transitions] - p_new = β * temp + temp = [minimum((q * p_old) + (q * dividend_payoff)) + for q in transitions] + p_new = beta * temp # If we succed in converging, break out of for loop - if maximum(sqrt, ((p_new - p_old).^2)) < 1e-12 + if maximum(sqrt, ((p_new - p_old) .^ 2)) < 1e-12 break end end @@ -567,7 +566,8 @@ labels = ["p_a", "p_b", "p_optimistic", "p_pessimistic"] for (transition, label) in zip(transitions, labels) println(label) println(repeat("=", 20)) - s0, s1 = round.(price_single_beliefs(transition, dividendreturn), digits=2) + s0, s1 = round.(price_single_beliefs(transition, dividendreturn), + digits = 2) println("State 0: $s0") println("State 1: $s1") println(repeat("-", 20)) @@ -594,7 +594,7 @@ heterogeneous beliefs. opt_beliefs = price_optimistic_beliefs([qa, qb], dividendreturn) labels = ["p_optimistic", "p_hat_a", "p_hat_b"] -for (p, label) ∈ zip(opt_beliefs, labels) +for (p, label) in zip(opt_beliefs, labels) println(label) println(repeat("=", 20)) s0, s1 = round.(p, digits = 2) diff --git a/lectures/multi_agent_models/lake_model.md b/lectures/multi_agent_models/lake_model.md index 1e87f825..c8aee14f 100644 --- a/lectures/multi_agent_models/lake_model.md +++ b/lectures/multi_agent_models/lake_model.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (lake_model)= @@ -196,9 +196,8 @@ Here's the code: --- tags: [hide-output] --- -using LinearAlgebra, Statistics -using Distributions, Expectations, NLsolve, Parameters, Plots -using QuantEcon, Roots, Random +using LinearAlgebra, Statistics, Distributions +using NLsolve, Plots, QuantEcon, Roots, Random ``` ```{code-cell} julia @@ -208,49 +207,36 @@ tags: [remove-cell] using Test ``` -```{code-cell} julia - -``` +Reusable functions for simulating linear maps and finding their fixed points ```{code-cell} julia -LakeModel = @with_kw (λ = 0.283, α = 0.013, b = 0.0124, d = 0.00822) - -function transition_matrices(lm) - (;λ, α, b, d) = lm - g = b - d - A = [(1 - λ) * (1 - d) + b (1 - d) * α + b - (1 - d) * λ (1 - d) * (1 - α)] - Â = A ./ (1 + g) - return (A = A, Â = Â) +function simulate_linear(A, x_0, T) + X = zeros(length(x_0), T + 1) + X[:, 1] = x_0 + for t in 2:(T + 1) + X[:, t] = A * X[:, t - 1] + end + return X end -function rate_steady_state(lm) - (;Â) = transition_matrices(lm) - sol = fixedpoint(x -> Â * x, fill(0.5, 2)) - converged(sol) || error("Failed to converge in $(result.iterations) iterations") +function linear_steady_state(A, x_0 = ones(size(A, 1)) / size(A, 1)) + sol = fixedpoint(x -> A * x, x_0) + converged(sol) || error("Failed to converge in $(sol.iterations) iter") return sol.zero end +``` -function simulate_stock_path(lm, X0, T) - (;A) = transition_matrices(lm) - X_path = zeros(eltype(X0), 2, T) - X = copy(X0) - for t in 1:T - X_path[:, t] = X - X = A * X - end - return X_path -end +```{code-cell} julia +function LakeModel(; lambda = 0.283, alpha = 0.013, b = 0.0124, d = 0.00822) + # calculate transition matrices + g = b - d + A = [(1 - lambda) * (1 - d)+b (1 - d) * alpha+b + (1 - d)*lambda (1 - d)*(1 - alpha)] + A_hat = A ./ (1 + g) -function simulate_rate_path(lm, x0, T) - (;Â) = transition_matrices(lm) - x_path = zeros(eltype(x0), 2, T) - x = copy(x0) - for t in 1:T - x_path[:, t] = x - x = Â * x - end - return x_path + # Solve for fixed point to find the steady-state u and e + x_bar = linear_steady_state(A_hat) + return (; lambda, alpha, b, d, A, A_hat, x_bar) end ``` @@ -258,24 +244,22 @@ Let's observe these matrices for the baseline model ```{code-cell} julia lm = LakeModel() -A, Â = transition_matrices(lm) -A +lm.A ``` ```{code-cell} julia -Â +lm.A_hat ``` And a revised model ```{code-cell} julia -lm = LakeModel(α = 2.0) -A, Â = transition_matrices(lm) -A +lm = LakeModel(; alpha = 0.2) +lm.A ``` ```{code-cell} julia -Â +lm.A_hat ``` ```{code-cell} julia @@ -283,8 +267,8 @@ Â tags: [remove-cell] --- @testset begin - @test lm.α ≈ 2.0 - @test A[1][1] ≈ 0.7235062600000001 + @test lm.alpha ≈ 0.2 + @test lm.A[1][1] ≈ 0.7235062600000001 end ``` @@ -303,15 +287,18 @@ U_0 = u_0 * N_0 E_0 = e_0 * N_0 X_0 = [U_0; E_0] -X_path = simulate_stock_path(lm, X_0, T) +X_path = simulate_linear(lm.A, X_0, T - 1) x1 = X_path[1, :] x2 = X_path[2, :] -x3 = dropdims(sum(X_path, dims = 1), dims = 1) +x3 = sum(X_path, dims = 1)' -plt_unemp = plot(title = "Unemployment", 1:T, x1, color = :blue, lw = 2, grid = true, label = "") -plt_emp = plot(title = "Employment", 1:T, x2, color = :blue, lw = 2, grid = true, label = "") -plt_labor = plot(title = "Labor force", 1:T, x3, color = :blue, lw = 2, grid = true, label = "") +plt_unemp = plot(title = "Unemployment", 1:T, x1, color = :blue, lw = 2, + grid = true, label = "") +plt_emp = plot(title = "Employment", 1:T, x2, color = :blue, lw = 2, + grid = true, label = "") +plt_labor = plot(title = "Labor force", 1:T, x3, color = :blue, lw = 2, + grid = true, label = "") plot(plt_unemp, plt_emp, plt_labor, layout = (3, 1), size = (800, 600)) ``` @@ -343,8 +330,7 @@ This is the case for our default parameters: ```{code-cell} julia lm = LakeModel() -A, Â = transition_matrices(lm) -e, f = eigvals(Â) +e, f = eigvals(lm.A_hat) abs(e), abs(f) ``` @@ -362,21 +348,23 @@ Let's look at the convergence of the unemployment and employment rate to steady ```{code-cell} julia lm = LakeModel() -e_0 = 0.92 # initial employment rate -u_0 = 1 - e_0 # initial unemployment rate -T = 50 # simulation length +e_0 = 0.92 # initial employment rate +u_0 = 1 - e_0 # initial unemployment rate +T = 50 # simulation length -xbar = rate_steady_state(lm) +u_bar, e_bar = lm.x_bar x_0 = [u_0; e_0] -x_path = simulate_rate_path(lm, x_0, T) - -plt_unemp = plot(title ="Unemployment rate", 1:T, x_path[1, :],color = :blue, lw = 2, - alpha = 0.5, grid = true, label = "") -plot!(plt_unemp, [xbar[1]], color=:red, linetype = :hline, linestyle = :dash, lw = 2, label = "") -plt_emp = plot(title = "Employment rate", 1:T, x_path[2, :],color = :blue, lw = 2, alpha = 0.5, - grid = true, label = "") -plot!(plt_emp, [xbar[2]], color=:red, linetype = :hline, linestyle = :dash, lw = 2, label = "") -plot(plt_unemp, plt_emp, layout = (2, 1), size=(700,500)) +x_path = simulate_linear(lm.A_hat, x_0, T - 1) + +plt_unemp = plot(title = "Unemployment rate", 1:T, x_path[1, :], color = :blue, + lw = 2, alpha = 0.5, grid = true, label = "") +plot!(plt_unemp, [u_bar], color = :red, linetype = :hline, linestyle = :dash, + lw = 2, label = "") +plt_emp = plot(title = "Employment rate", 1:T, x_path[2, :], color = :blue, + lw = 2, alpha = 0.5, grid = true, label = "") +plot!(plt_emp, [e_bar], color = :red, linetype = :hline, linestyle = :dash, + lw = 2, label = "") +plot(plt_unemp, plt_emp, layout = (2, 1), size = (700, 500)) ``` ```{code-cell} julia @@ -480,35 +468,33 @@ MarkovChain type to investigate this. Let's plot the path of the sample averages over 5,000 periods ```{code-cell} julia -using QuantEcon, Roots, Random -``` - -```{code-cell} julia -lm = LakeModel(d = 0, b = 0) +lm = LakeModel(; d = 0, b = 0) T = 5000 # Simulation length -(;α, λ) = lm -P = [(1 - λ) λ - α (1 - α)] +(; alpha, lambda) = lm +P = [(1-lambda) lambda + alpha (1-alpha)] ``` ```{code-cell} julia Random.seed!(42) +u_bar, e_bar = lm.x_bar mc = MarkovChain(P, [0; 1]) # 0=unemployed, 1=employed -xbar = rate_steady_state(lm) - -s_path = simulate(mc, T; init=2) -s̄_e = cumsum(s_path) ./ (1:T) -s̄_u = 1 .- s̄_e -s_bars = [s̄_u s̄_e] -plt_unemp = plot(title = "Percent of time unemployed", 1:T, s_bars[:,1],color = :blue, lw = 2, - alpha = 0.5, label = "", grid = true) -plot!(plt_unemp, [xbar[1]], linetype = :hline, linestyle = :dash, color=:red, lw = 2, label = "") -plt_emp = plot(title = "Percent of time employed", 1:T, s_bars[:,2],color = :blue, lw = 2, - alpha = 0.5, label = "", grid = true) -plot!(plt_emp, [xbar[2]], linetype = :hline, linestyle = :dash, color=:red, lw = 2, label = "") -plot(plt_unemp, plt_emp, layout = (2, 1), size=(700,500)) +s_path = simulate(mc, T; init = 2) +s_bar_e = cumsum(s_path) ./ (1:T) +s_bar_u = 1 .- s_bar_e +s_bars = [s_bar_u s_bar_e] + +plt_unemp = plot(title = "Percent of time unemployed", 1:T, s_bars[:, 1], + color = :blue, lw = 2, alpha = 0.5, label = "", grid = true) +plot!(plt_unemp, [u_bar], linetype = :hline, linestyle = :dash, color = :red, + lw = 2, label = "") +plt_emp = plot(title = "Percent of time employed", 1:T, s_bars[:, 2], + color = :blue, lw = 2, alpha = 0.5, label = "", grid = true) +plot!(plt_emp, [e_bar], linetype = :hline, linestyle = :dash, color = :red, + lw = 2, label = "") +plot(plt_unemp, plt_emp, layout = (2, 1), size = (700, 500)) ``` ```{code-cell} julia @@ -516,8 +502,8 @@ plot(plt_unemp, plt_emp, layout = (2, 1), size=(700,500)) tags: [remove-cell] --- @testset begin - #test xbar[1] ≈ 0.04391891891891919 - #test s_bars[end,end] ≈ 0.957 + @test u_bar ≈ 0.04391891891891919 + @test s_bars[end,end] ≈ 0.9488 end ``` @@ -630,160 +616,190 @@ Following {cite}`davis2006flow`, we set $\alpha$, the hazard rate of leaving emp We will make use of (with some tweaks) the code we wrote in the {doc}`McCall model lecture <../dynamic_programming/mccall_model>`, embedded below for convenience. ```{code-cell} julia -function solve_mccall_model(mcm; U_iv = 1.0, V_iv = ones(length(mcm.w)), tol = 1e-5, +function solve_mccall_model(mcm; U_iv = 1.0, V_iv = ones(length(mcm.w)), + tol = 1e-5, iter = 2_000) - (;α, β, σ, c, γ, w, E, u) = mcm + (; alpha, beta, sigma, c, gamma, w, w_probs, u) = mcm - # necessary objects - u_w = u.(w, σ) - u_c = u(c, σ) + # pre-calculate utilities + u_w = u.(w, sigma) + u_c = u(c, sigma) # Bellman operator T. Fixed point is x* s.t. T(x*) = x* function T(x) - V = x[1:end-1] + V = x[1:(end - 1)] U = x[end] - [u_w + β * ((1 - α) * V .+ α * U); u_c + β * (1 - γ) * U + β * γ * E * max.(U, V)] + return [u_w + beta * ((1 - alpha) * V .+ alpha * U); + u_c + beta * (1 - gamma) * U + + beta * gamma * dot(w_probs, max.(U, V))] end # value function iteration x_iv = [V_iv; U_iv] # initial x val xstar = fixedpoint(T, x_iv, iterations = iter, xtol = tol, m = 0).zero - V = xstar[1:end-1] + V = xstar[1:(end - 1)] U = xstar[end] # compute the reservation wage w_barindex = searchsortedfirst(V .- U, 0.0) if w_barindex >= length(w) # if this is true, you never want to accept - w̄ = Inf + w_bar = Inf else - w̄ = w[w_barindex] # otherwise, return the number + w_bar = w[w_barindex] # otherwise, return the number end # return a NamedTuple, so we can select values by name - return (V = V, U = U, w̄ = w̄) + return (; V, U, w_bar) end ``` And the McCall object ```{code-cell} julia -# a default utility function -u(c, σ) = c > 0 ? (c^(1 - σ) - 1) / (1 - σ) : -10e-6 - -# model constructor -McCallModel = @with_kw (α = 0.2, - β = 0.98, # discount rate - γ = 0.7, - c = 6.0, # unemployment compensation - σ = 2.0, - u = u, # utility function - w = range(10, 20, length = 60), # wage values - E = Expectation(BetaBinomial(59, 600, 400))) # distribution over wage values +function McCallModel(; alpha, beta, gamma, c, sigma, w, w_probs, + u = (c, sigma) -> c > 0 ? + (c^(1 - sigma) - 1) / (1 - sigma) : + -10e-6) + return (; alpha, beta, gamma, c, sigma, u, w, w_probs) +end ``` Now let's compute and plot welfare, employment, unemployment, and tax revenue as a function of the unemployment compensation rate ```{code-cell} julia -# some global variables that will stay constant -α = 0.013 -α_q = (1 - (1 - α)^3) -b_param = 0.0124 -d_param = 0.00822 -β = 0.98 -γ = 1.0 -σ = 2.0 - -# the default wage distribution: a discretized log normal -log_wage_mean, wage_grid_size, max_wage = 20, 200, 170 -w_vec = range(1e-3, max_wage, length = wage_grid_size + 1) - -logw_dist = Normal(log(log_wage_mean), 1) -cdf_logw = cdf.(logw_dist, log.(w_vec)) -pdf_logw = cdf_logw[2:end] - cdf_logw[1:end-1] - -p_vec = pdf_logw ./ sum(pdf_logw) -w_vec = (w_vec[1:end-1] + w_vec[2:end]) / 2 - -E = expectation(Categorical(p_vec)) # expectation object - -function compute_optimal_quantities(c, τ) - mcm = McCallModel(α = α_q, - β = β, - γ = γ, - c = c - τ, # post-tax compensation - σ = σ, - w = w_vec .- τ, # post-tax wages - E = E) # expectation operator - - (;V, U, w̄) = solve_mccall_model(mcm) - indicator = wage -> wage > w̄ - λ = γ * E * indicator.(w_vec .- τ) - - return w̄, λ, V, U +function compute_optimal_quantities(c_pretax, tau; w_probs, sigma, gamma, beta, + alpha, w_pretax) + mcm = McCallModel(; alpha, beta, gamma, sigma, w_probs, + c = c_pretax - tau, # post-tax compensation + w = w_pretax .- tau) + + (; V, U, w_bar) = solve_mccall_model(mcm) + accept_wage = w_pretax .- tau .> w_bar + + # sum up proportion accepting the wages + lambda = gamma * dot(w_probs, accept_wage) + return w_bar, lambda, V, U end -function compute_steady_state_quantities(c, τ) - w̄, λ_param, V, U = compute_optimal_quantities(c, τ) +function compute_steady_state_quantities(c_pretax, tau; w_probs, sigma, gamma, + beta, alpha, w_pretax, b, d) + w_bar, lambda, V, U = compute_optimal_quantities(c_pretax, tau; w_probs, + sigma, + gamma, beta, alpha, + w_pretax) # compute steady state employment and unemployment rates - lm = LakeModel(λ = λ_param, α = α_q, b = b_param, d = d_param) - x = rate_steady_state(lm) - u_rate, e_rate = x + lm = LakeModel(; lambda, alpha, b, d) + u_rate, e_rate = lm.x_bar # compute steady state welfare - indicator(wage) = wage > w̄ - decisions = indicator.(w_vec .- τ) - w = (E * (V .* decisions)) / (E * decisions) + accept_wage = w_pretax .- tau .> w_bar + w = (dot(w_probs, V .* accept_wage)) / dot(w_probs, accept_wage) welfare = e_rate .* w + u_rate .* U return u_rate, e_rate, welfare end -function find_balanced_budget_tax(c) +function find_balanced_budget_tax(c_pretax; w_probs, sigma, gamma, beta, alpha, + w_pretax, b, d) function steady_state_budget(t) - u_rate, e_rate, w = compute_steady_state_quantities(c, t) - return t - u_rate * c + u_rate, e_rate, w = compute_steady_state_quantities(c_pretax, t; + w_probs, sigma, + gamma, beta, alpha, + w_pretax, b, d) + return t - u_rate * c_pretax end - τ = find_zero(steady_state_budget, (0.0, 0.9c)) - return τ + tau = find_zero(steady_state_budget, (0.0, 0.9 * c_pretax)) + return tau end +``` -# levels of unemployment insurance we wish to study -Nc = 60 -c_vec = range(5, 140, length = Nc) - -tax_vec = zeros(Nc) -unempl_vec = similar(tax_vec) -empl_vec = similar(tax_vec) -welfare_vec = similar(tax_vec) - -for i in 1:Nc - t = find_balanced_budget_tax(c_vec[i]) - u_rate, e_rate, welfare = compute_steady_state_quantities(c_vec[i], t) - tax_vec[i] = t - unempl_vec[i] = u_rate - empl_vec[i] = e_rate - welfare_vec[i] = welfare +Helper function to calculate for various unemployment insurance levels + +```{code-cell} julia +function calculate_equilibriums(c_pretax; w_probs, sigma, gamma, beta, alpha, + w_pretax, b, d) + tau_vec = similar(c_pretax) + u_vec = similar(c_pretax) + e_vec = similar(c_pretax) + welfare_vec = similar(c_pretax) + + for (i, c_pre) in enumerate(c_pretax) + tau = find_balanced_budget_tax(c_pre; w_probs, sigma, gamma, beta, + alpha, w_pretax, b, d) + u_rate, e_rate, welfare = compute_steady_state_quantities(c_pre, tau; + w_probs, + sigma, + gamma, beta, + alpha, + w_pretax, + b, d) + tau_vec[i] = tau + u_vec[i] = u_rate + e_vec[i] = e_rate + welfare_vec[i] = welfare + end + return tau_vec, u_vec, e_vec, welfare_vec end +``` -plt_unemp = plot(title = "Unemployment", c_vec, unempl_vec, color = :blue, lw = 2, alpha=0.7, - label = "",grid = true) -plt_tax = plot(title = "Tax", c_vec, tax_vec, color = :blue, lw = 2, alpha=0.7, label = "", - grid = true) -plt_emp = plot(title = "Employment", c_vec, empl_vec, color = :blue, lw = 2, alpha=0.7, label = "", - grid = true) -plt_welf = plot(title = "Welfare", c_vec, welfare_vec, color = :blue, lw = 2, alpha=0.7, label = "", - grid = true) +Parameters for our experiment + +```{code-cell} julia +alpha_base = 0.013 +alpha = (1 - (1 - alpha_base)^3) +b = 0.0124 +d = 0.00822 +beta = 0.98 +gamma = 1.0 +sigma = 2.0 + +# the default wage distribution: a discretized log normal +log_wage_mean, wage_grid_size, max_wage = 20, 200, 170 +w_pretax = range(1e-3, max_wage, length = wage_grid_size + 1) +logw_dist = Normal(log(log_wage_mean), 1) +cdf_logw = cdf.(logw_dist, log.(w_pretax)) +pdf_logw = cdf_logw[2:end] - cdf_logw[1:(end - 1)] +w_probs = pdf_logw ./ sum(pdf_logw) # probabilities +w_pretax = (w_pretax[1:(end - 1)] + w_pretax[2:end]) / 2 -plot(plt_unemp, plt_emp, plt_tax, plt_welf, layout = (2,2), size = (800, 700)) +# levels of unemployment insurance we wish to study +c_pretax = range(5, 140, length = 60) +tau_vec, u_vec, e_vec, welfare_vec = calculate_equilibriums(c_pretax; w_probs, + sigma, gamma, beta, + alpha, w_pretax, b, + d) + +# plots +plt_unemp = plot(title = "Unemployment", c_pretax, u_vec, color = :blue, + lw = 2, alpha = 0.7, label = "", grid = true) +plt_tax = plot(title = "Tax", c_pretax, tau_vec, color = :blue, lw = 2, + alpha = 0.7, label = "", grid = true) +plt_emp = plot(title = "Employment", c_pretax, e_vec, color = :blue, lw = 2, + alpha = 0.7, label = "", grid = true) +plt_welf = plot(title = "Welfare", c_pretax, welfare_vec, color = :blue, lw = 2, + alpha = 0.7, label = "", grid = true) + +plot(plt_unemp, plt_emp, plt_tax, plt_welf, layout = (2, 2), size = (800, 700)) ``` Welfare first increases and then decreases as unemployment benefits rise. The level that maximizes steady state welfare is approximately 62. +```{code-cell} julia +--- +tags: [remove-cell] +--- +@testset begin + @test tau_vec[2] ≈ 0.859664806251665 + @test u_vec[10] ≈ 0.22587607040020583 + @test e_vec[4] ≈ 0.8527180941230578 +end +``` + ## Exercises ### Exercise 1 @@ -830,7 +846,7 @@ steady state values to x0 ```{code-cell} julia lm = LakeModel() -x0 = rate_steady_state(lm) +x0 = lm.x_bar println("Initial Steady State: $x0") ``` @@ -844,14 +860,10 @@ T = 50 New legislation changes $\lambda$ to $0.2$ ```{code-cell} julia -lm = LakeModel(λ = 0.2) -``` - -```{code-cell} julia -xbar = rate_steady_state(lm) # new steady state -X_path = simulate_stock_path(lm, x0 * N0, T) -x_path = simulate_rate_path(lm, x0, T) -println("New Steady State: $xbar") +lm = LakeModel(; lambda = 0.2) +X_path = simulate_linear(lm.A, x0 * N0, T - 1) +x_path = simulate_linear(lm.A_hat, x0, T - 1) +println("New Steady State: $(lm.x_bar)") ``` Now plot stocks @@ -859,14 +871,14 @@ Now plot stocks ```{code-cell} julia x1 = X_path[1, :] x2 = X_path[2, :] -x3 = dropdims(sum(X_path, dims = 1), dims = 1) +x3 = sum(X_path, dims = 1)' -plt_unemp = plot(title = "Unemployment", 1:T, x1, color = :blue, grid = true, label = "", - bg_inside = :lightgrey) -plt_emp = plot(title = "Employment", 1:T, x2, color = :blue, grid = true, label = "", - bg_inside = :lightgrey) -plt_labor = plot(title = "Labor force", 1:T, x3, color = :blue, grid = true, label = "", - bg_inside = :lightgrey) +plt_unemp = plot(title = "Unemployment", 1:T, x1, color = :blue, grid = true, + label = "", bg_inside = :lightgrey) +plt_emp = plot(title = "Employment", 1:T, x2, color = :blue, grid = true, + label = "", bg_inside = :lightgrey) +plt_labor = plot(title = "Labor force", 1:T, x3, color = :blue, grid = true, + label = "", bg_inside = :lightgrey) plot(plt_unemp, plt_emp, plt_labor, layout = (3, 1), size = (800, 600)) ``` @@ -876,23 +888,23 @@ plot(plt_unemp, plt_emp, plt_labor, layout = (3, 1), size = (800, 600)) tags: [remove-cell] --- @testset begin - #test x1[1] ≈ 8.266626766923284 - #test x2[2] ≈ 91.43632870031433 - #test x3[3] ≈ 100.83774723999996 + @test x3[21] ≈ 108.70045145781441 + @test x2[12] ≈ 93.05432951806618 end ``` And how the rates evolve ```{code-cell} julia -plt_unemp = plot(title = "Unemployment rate", 1:T, x_path[1,:], color = :blue, grid = true, - label = "", bg_inside = :lightgrey) -plot!(plt_unemp, [xbar[1]], linetype = :hline, linestyle = :dash, color =:red, label = "") - -plt_emp = plot(title = "Employment rate", 1:T, x_path[2,:], color = :blue, grid = true, - label = "", bg_inside = :lightgrey) -plot!(plt_emp, [xbar[2]], linetype = :hline, linestyle = :dash, color =:red, label = "") +plt_unemp = plot(title = "Unemployment rate", 1:T, x_path[1, :], color = :blue, + grid = true, label = "", bg_inside = :lightgrey) +plot!(plt_unemp, [u_bar], linetype = :hline, linestyle = :dash, color = :red, + label = "") +plt_emp = plot(title = "Employment rate", 1:T, x_path[2, :], color = :blue, + grid = true, label = "", bg_inside = :lightgrey) +plot!(plt_emp, [e_bar], linetype = :hline, linestyle = :dash, color = :red, + label = "") plot(plt_unemp, plt_emp, layout = (2, 1), size = (800, 600)) ``` @@ -901,8 +913,8 @@ plot(plt_unemp, plt_emp, layout = (2, 1), size = (800, 600)) tags: [remove-cell] --- @testset begin - #test x_path[1,3] ≈ 0.09471014989625384 - #test x_path[2,7] ≈ 0.8936171021324064 + @test x_path[1,3] ≈ 0.09471014989625384 + @test x_path[2,7] ≈ 0.8936171021324064 end ``` @@ -921,7 +933,7 @@ state ```{code-cell} julia lm = LakeModel() -x0 = rate_steady_state(lm) +x0 = lm.x_bar ``` ```{code-cell} julia @@ -929,23 +941,23 @@ x0 = rate_steady_state(lm) tags: [remove-cell] --- @testset begin - #test x0[1] ≈ 0.08266626766923285 + @test x0[1] ≈ 0.08266626766923285 end ``` Here are the other parameters: ```{code-cell} julia -b̂ = 0.003 -T̂ = 20 +b_hat = 0.003 +T_hat = 20 ``` Let's increase $b$ to the new value and simulate for 20 periods ```{code-cell} julia -lm = LakeModel(b=b̂) -X_path1 = simulate_stock_path(lm, x0 * N0, T̂) # simulate stocks -x_path1 = simulate_rate_path(lm, x0, T̂) # simulate rates +lm = LakeModel(; b = b_hat) +X_path1 = simulate_linear(lm.A, x0 * N0, T_hat - 1) +x_path1 = simulate_linear(lm.A_hat, x0, T_hat - 1) ``` Now we reset $b$ to the original value and then, using the state @@ -953,9 +965,9 @@ after 20 periods for the new initial conditions, we simulate for the additional 30 periods ```{code-cell} julia -lm = LakeModel(b = 0.0124) -X_path2 = simulate_stock_path(lm, X_path1[:, end-1], T-T̂+1) # simulate stocks -x_path2 = simulate_rate_path(lm, x_path1[:, end-1], T-T̂+1) # simulate rates +lm = LakeModel(; b = 0.0124) +X_path2 = simulate_linear(lm.A, X_path1[:, end - 1], T - T_hat) +x_path2 = simulate_linear(lm.A_hat, x_path1[:, end - 1], T - T_hat) ``` Finally we combine these two paths and plot @@ -966,20 +978,20 @@ X_path = hcat(X_path1, X_path2[:, 2:end]) ``` ```{code-cell} julia -x1 = X_path[1,:] -x2 = X_path[2,:] -x3 = dropdims(sum(X_path, dims = 1), dims = 1) +x1 = X_path[1, :] +x2 = X_path[2, :] +x3 = sum(X_path, dims = 1)' -plt_unemp = plot(title = "Unemployment", 1:T, x1, color = :blue, lw = 2, alpha = 0.7, - grid = true, label = "", bg_inside = :lightgrey) +plt_unemp = plot(title = "Unemployment", 1:T, x1, color = :blue, lw = 2, + alpha = 0.7, grid = true, label = "", bg_inside = :lightgrey) plot!(plt_unemp, ylims = extrema(x1) .+ (-1, 1)) -plt_emp = plot(title = "Employment", 1:T, x2, color = :blue, lw = 2, alpha = 0.7, grid = true, - label = "", bg_inside = :lightgrey) +plt_emp = plot(title = "Employment", 1:T, x2, color = :blue, lw = 2, + alpha = 0.7, grid = true, label = "", bg_inside = :lightgrey) plot!(plt_emp, ylims = extrema(x2) .+ (-1, 1)) -plt_labor = plot(title = "Labor force", 1:T, x3, color = :blue, alpha = 0.7, grid = true, - label = "", bg_inside = :lightgrey) +plt_labor = plot(title = "Labor force", 1:T, x3, color = :blue, alpha = 0.7, + grid = true, label = "", bg_inside = :lightgrey) plot!(plt_labor, ylims = extrema(x3) .+ (-1, 1)) plot(plt_unemp, plt_emp, plt_labor, layout = (3, 1), size = (800, 600)) ``` @@ -989,23 +1001,24 @@ plot(plt_unemp, plt_emp, plt_labor, layout = (3, 1), size = (800, 600)) tags: [remove-cell] --- @testset begin - #test x1[1] ≈ 8.266626766923284 - #test x2[2] ≈ 92.11681873319097 - #test x3[3] ≈ 98.95872483999996 + @test x1[1] ≈ 8.266626766923284 + @test x2[2] ≈ 92.11681873319097 + @test x3[3] ≈ 98.95872483999996 end ``` And the rates ```{code-cell} julia -plt_unemp = plot(title = "Unemployment Rate", 1:T, x_path[1,:], color = :blue, grid = true, - label = "", bg_inside = :lightgrey, lw = 2) -plot!(plt_unemp, [x0[1]], linetype = :hline, linestyle = :dash, color =:red, label = "", lw = 2) - -plt_emp = plot(title = "Employment Rate", 1:T, x_path[2,:], color = :blue, grid = true, - label = "", bg_inside = :lightgrey, lw = 2) -plot!(plt_emp, [x0[2]], linetype = :hline, linestyle = :dash, color =:red, label = "", lw = 2) - +plt_unemp = plot(title = "Unemployment Rate", 1:T, x_path[1, :], color = :blue, + grid = true, label = "", bg_inside = :lightgrey, lw = 2) +plot!(plt_unemp, [x0[1]], linetype = :hline, linestyle = :dash, color = :red, + label = "", lw = 2) + +plt_emp = plot(title = "Employment Rate", 1:T, x_path[2, :], color = :blue, + grid = true, label = "", bg_inside = :lightgrey, lw = 2) +plot!(plt_emp, [x0[2]], linetype = :hline, linestyle = :dash, color = :red, + label = "", lw = 2) plot(plt_unemp, plt_emp, layout = (2, 1), size = (800, 600)) ``` @@ -1014,8 +1027,8 @@ plot(plt_unemp, plt_emp, layout = (2, 1), size = (800, 600)) tags: [remove-cell] --- @testset begin - #test x_path[1,3] ≈ 0.06791408368459205 - #test x_path[2,7] ≈ 0.9429334437639298 + @test x_path[1,3] ≈ 0.06791408368459205 + @test x_path[2,7] ≈ 0.9429334437639298 end ``` diff --git a/lectures/multi_agent_models/lucas_model.md b/lectures/multi_agent_models/lucas_model.md index b5239a57..50082321 100644 --- a/lectures/multi_agent_models/lucas_model.md +++ b/lectures/multi_agent_models/lucas_model.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (lucas_asset)= @@ -386,69 +386,54 @@ using Test ``` ```{code-cell} julia -using LinearAlgebra, Statistics -using Distributions, Interpolations, LaTeXStrings, Parameters, Plots, Random +using LinearAlgebra, Statistics, Random +using Distributions, Interpolations, LaTeXStrings, Plots, NLsolve ``` ```{code-cell} julia -# model -function LucasTree(;γ = 2.0, - β = 0.95, - α = 0.9, - σ = 0.1, - grid_size = 100) - - ϕ = LogNormal(0.0, σ) - shocks = rand(ϕ, 500) +function LucasTree(; gamma = 2.0, + beta = 0.95, + alpha = 0.9, + sigma = 0.1, + grid_size = 100, + num_z = 500) + phi = LogNormal(0.0, sigma) + z = rand(phi, num_z) # build a grid with mass around stationary distribution - ssd = σ / sqrt(1 - α^2) - grid_min, grid_max = exp(-4ssd), exp(4ssd) + ssd = sigma / sqrt(1 - alpha^2) + grid_min = exp(-4 * ssd) + grid_max = exp(4 * ssd) grid = range(grid_min, grid_max, length = grid_size) - # set h(y) = β * int u'(G(y,z)) G(y,z) ϕ(dz) + # set h(y) = beta * int u'(G(y,z)) G(y,z) phi(dz) h = similar(grid) for (i, y) in enumerate(grid) - h[i] = β * mean((y^α .* shocks).^(1 - γ)) + h[i] = beta * mean((y^alpha .* z) .^ (1 - gamma)) end - return (γ = γ, β = β, α = α, σ = σ, ϕ = ϕ, grid = grid, shocks = shocks, h = h) -end - -# approximate Lucas operator, which returns the updated function Tf on the grid -function lucas_operator(lt, f) - - # unpack input - (;grid, α, β, h) = lt - z = lt.shocks - - Af = LinearInterpolation(grid, f, extrapolation_bc=Line()) - - Tf = [ h[i] + β * mean(Af.(grid[i]^α .* z)) for i in 1:length(grid) ] - return Tf + return (; gamma, beta, alpha, sigma, phi, grid, z, h) end # get equilibrium price for Lucas tree -function solve_lucas_model(lt; - tol = 1e-6, - max_iter = 500) - - (;grid, γ) = lt - - i = 0 - f = zero(grid) # Initial guess of f - error = tol + 1 - - while (error > tol) && (i < max_iter) - f_new = lucas_operator(lt, f) - error = maximum(abs, f_new - f) - f = f_new - i += 1 +function solve_lucas_model(lt; ftol = 1e-8, iterations = 500) + (; grid, gamma, alpha, beta, h, z) = lt + + # approximate Lucas operator, which returns the updated function Tf on the grid + function T(f) + Af = linear_interpolation(grid, f, extrapolation_bc = Line()) + # Using z for monte-carlo integration + Tf = [h[i] + beta * mean(Af.(grid[i]^alpha .* z)) + for i in 1:length(grid)] + return Tf end - # p(y) = f(y) * y ^ γ - price = f .* grid.^γ + sol = fixedpoint(T, zero(grid); ftol, iterations) + converged(sol) || error("Failed to converge in $(sol.iterations) iter") + f = sol.zero + + price = f .* grid .^ gamma # f(y)*y^gamma return price end @@ -459,7 +444,7 @@ An example of usage is given in the docstring and repeated here ```{code-cell} julia Random.seed!(42) # For reproducible results. -tree = LucasTree(γ = 2.0, β = 0.95, α = 0.90, σ = 0.1) +tree = LucasTree(; gamma = 2.0, beta = 0.95, alpha = 0.90, sigma = 0.1) price_vals = solve_lucas_model(tree); ``` @@ -468,9 +453,9 @@ price_vals = solve_lucas_model(tree); tags: [remove-cell] --- @testset begin - #test price_vals[57] ≈ 44.5077566916004 - #test price_vals[78] ≈ 68.42956586308563 - #test price_vals[13] ≈ 9.880376662058682 + @test price_vals[57] ≈ 41.35601991726328 + @test price_vals[78] ≈ 63.474988006734925 + @test price_vals[13] ≈ 9.24450665849126 end ``` @@ -519,11 +504,11 @@ Random.seed!(42); ```{code-cell} julia plot() -for β in (.95, 0.98) - tree = LucasTree(;β = β) +for beta in (0.95, 0.98) + tree = LucasTree(; beta) grid = tree.grid price_vals = solve_lucas_model(tree) - plot!(grid, price_vals, lw = 2, label = L"\beta = %$β") + plot!(grid, price_vals, lw = 2, label = L"\beta = %$beta") end plot!(xlabel = L"y", ylabel = "price", legend = :topleft) @@ -535,9 +520,9 @@ tags: [remove-cell] --- @testset begin # For the 0.98, since the other one is overwritten. Random.seed!(42) - price_vals = solve_lucas_model(LucasTree(β = 0.98)) - #test price_vals[20] ≈ 35.00073581199659 - #test price_vals[57] ≈ 124.32987344509688 + price_vals = solve_lucas_model(LucasTree(beta = 0.98)) + @test price_vals[20] ≈ 32.17514173843709 + @test price_vals[57] ≈ 113.89100588660085 end ``` diff --git a/lectures/multi_agent_models/markov_asset.md b/lectures/multi_agent_models/markov_asset.md index 27bc9878..ccf296ba 100644 --- a/lectures/multi_agent_models/markov_asset.md +++ b/lectures/multi_agent_models/markov_asset.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (mass)= @@ -290,13 +290,12 @@ The next figure shows a simulation, where --- tags: [remove-cell] --- -using Test, Random +using Test ``` ```{code-cell} julia -using LinearAlgebra, Statistics -using LaTeXStrings, Parameters, Plots, QuantEcon - +using LinearAlgebra, Statistics, Random +using LaTeXStrings, Plots, QuantEcon, NLsolve ``` ```{code-cell} julia @@ -317,7 +316,7 @@ d_series = cumprod(g_series) # assumes d_0 = 1 series = [x_series g_series d_series log.(d_series)] labels = [L"X_t" L"g_t" L"d_t" L"ln(d_t)"] -plot(series, layout = 4, labels = labels) +plot(series; layout = 4, labels) ``` ```{code-cell} julia @@ -325,10 +324,9 @@ plot(series, layout = 4, labels = labels) tags: [remove-cell] --- @testset begin - #test x_series[4] ≈ -0.669642857142857 - #test g_series[5] ≈ 0.4094841251523643 - #test d_series[9] ≈ 0.03514706070454392 # Near the inflection point. - #test log.(d_series)[72] ≈ -29.24107142857142 # Something near the end. + @test x_series[4] ≈ -0.22321428571428567 + @test g_series[6] ≈ 1.2500884211272658 + @test d_series[9] ≈ 0.5118913634883987 end ``` @@ -404,20 +402,15 @@ Here's the code, including a test of the spectral radius condition ```{code-cell} julia n = 25 # size of state space -β = 0.9 +beta = 0.9 mc = tauchen(n, 0.96, 0.02) K = mc.p .* exp.(mc.state_values)' -v = (I - β * K) \ (β * K * ones(n, 1)) +v = (I - beta * K) \ (beta * K * ones(n, 1)) -plot(mc.state_values, - v, - lw = 2, - ylabel = "price-dividend ratio", - xlabel = "state", - alpha = 0.7, - label = L"v") +plot(mc.state_values, v; lw = 2, ylabel = "price-dividend ratio", + xlabel = L"X_t", alpha = 0.7, label = L"v") ``` ```{code-cell} julia @@ -425,10 +418,8 @@ plot(mc.state_values, tags: [remove-cell] --- @testset begin - #test v[2] ≈ 3.4594684257743284 atol = 1e-7 - #test v[1] ≈ 3.2560393349907755 - #test v[5] ≈ 4.526909446326235 - #test K[8] ≈ 8.887213530262768e-10 + @test v[2] ≈ 3.4594684257743284 + @test K[8] ≈ 8.887213530262768e-10 end ``` @@ -536,45 +527,27 @@ Assuming that the spectral radius of $J$ is strictly less than $\beta^{-1}$, thi v = (I - \beta J)^{-1} \beta J {\mathbb 1} ``` -We will define a function tree_price to solve for $v$ given parameters stored in +We will define a function `tree_price` to solve for $v$ given parameters stored in the AssetPriceModel objects +The default Markov Chain for will be a discretized AR(1) with $\rho = 0.9, \sigma = 0.02$ and discretized into 25 states using Tauchen's method. + ```{code-cell} julia -# A default Markov chain for the state process -ρ = 0.9 -σ = 0.02 -n = 25 -default_mc = tauchen(n, ρ, σ) - -AssetPriceModel = @with_kw (β = 0.96, - γ = 2.0, - mc = default_mc, - n = size(mc.p)[1], - g = exp) - -# test stability of matrix Q -function test_stability(ap, Q) - sr = maximum(abs, eigvals(Q)) - if sr ≥ 1 / ap.β - msg = "Spectral radius condition failed with radius = $sr" - throw(ArgumentError(msg)) - end +function AssetPriceModel(; beta = 0.96, gamma = 2.0, g = exp, + mc = tauchen(25, 0.9, 0.02)) + return (; beta, gamma, mc, g) end # price/dividend ratio of the Lucas tree -function tree_price(ap; γ = ap.γ) - # Simplify names, set up matrices - (;β, mc) = ap - P, y = mc.p, mc.state_values - y = reshape(y, 1, ap.n) - J = P .* ap.g.(y).^(1 - γ) - - # Make sure that a unique solution exists - test_stability(ap, J) +function tree_price(ap) + (; beta, mc, gamma, g) = ap + P = mc.p + y = mc.state_values' + J = P .* g.(y) .^ (1 - gamma) + @assert maximum(abs, eigvals(J)) < 1 / beta # check stability # Compute v - v = (I - β * J) \ sum(β * J, dims = 2) - + v = (I - beta * J) \ sum(beta * J, dims = 2) return v end ``` @@ -583,25 +556,16 @@ Here's a plot of $v$ as a function of the state for several values of $\gamma$, with a positively correlated Markov process and $g(x) = \exp(x)$ ```{code-cell} julia -γs = [1.2, 1.4, 1.6, 1.8, 2.0] -ap = AssetPriceModel() -states = ap.mc.state_values - -lines = [] -labels = [] - -for γ in γs - v = tree_price(ap, γ = γ) - label = L"\gamma = %$γ" - push!(labels, label) - push!(lines, v) +gammas = [1.2, 1.4, 1.6, 1.8, 2.0] +p = plot(title = "Price-dividend ratio as a function of the state", + xlabel = L"X_t", ylabel = "price-dividend ratio") + +for gamma in gammas + ap = AssetPriceModel(; gamma) + states = ap.mc.state_values + plot!(states, tree_price(ap); label = L"\gamma = %$gamma") end - -plot(lines, - labels = reshape(labels, 1, length(labels)), - title = "Price-dividend ratio as a function of the state", - ylabel = "price-dividend ratio", - xlabel = "state") +p ``` ```{code-cell} julia @@ -609,10 +573,10 @@ plot(lines, tags: [remove-cell] --- @testset begin - #test lines[2][4] ≈ 33.36574362637905 - #test lines[3][12] ≈ 28.52560591264372 - #test lines[4][18] ≈ 22.38597470787489 - #test lines[5][24] ≈ 15.81947255704859 + ap = AssetPriceModel() + v = tree_price(ap) + @test v[5] ≈ 74.54830456854316 + @test v[16] ≈ 29.426651157109678 end ``` @@ -687,24 +651,23 @@ yields the solution p = (I - \beta M)^{-1} \beta M \zeta {\mathbb 1} ``` -The above is implemented in the function consol_price +The above is implemented in the function `consol_price` ```{code-cell} julia -function consol_price(ap, ζ) - # Simplify names, set up matrices - (;β, γ, mc, g, n) = ap - P, y = mc.p, mc.state_values - y = reshape(y, 1, n) - M = P .* g.(y).^(-γ) - - # Make sure that a unique solution exists - test_stability(ap, M) +function consol_price(ap, zeta) + (; beta, gamma, mc, g) = ap + P = mc.p + y = mc.state_values' + M = P .* g.(y) .^ (-gamma) + @assert maximum(abs, eigvals(M)) < 1 / beta # Compute price - return (I - β * M) \ sum(β * ζ * M, dims = 2) + return (I - beta * M) \ sum(beta * zeta * M, dims = 2) end ``` +Note that the `sum(Q, dims=2)` is equivalent to `Q * ones(size(Q)[1], 1)`. + ### Pricing an Option to Purchase the Consol Let's now price options of varying maturity that give the right to purchase a consol at a price $p_S$. @@ -771,52 +734,46 @@ T w = \max \{ \beta M w,\; p - p_S {\mathbb 1} \} $$ -Start at some initial $w$ and iterate to convergence with $T$. +Start at some initial $w$ and iterate to convergence with $T$, or use a fixed point algorithm. We can find the solution with the following function call_option ```{code-cell} julia # price of perpetual call on consol bond -function call_option(ap, ζ, p_s, ϵ = 1e-7) - - # Simplify names, set up matrices - (;β, γ, mc, g, n) = ap - P, y = mc.p, mc.state_values - y = reshape(y, 1, n) - M = P .* g.(y).^(-γ) - - # Make sure that a unique console price exists - test_stability(ap, M) - - # Compute option price - p = consol_price(ap, ζ) - w = zeros(ap.n, 1) - error = ϵ + 1 - while (error > ϵ) - # Maximize across columns - w_new = max.(β * M * w, p .- p_s) - # Find maximal difference of each component and update - error = maximum(abs, w - w_new) - w = w_new - end - - return w +function call_option(ap, zeta, p_s) + (; beta, gamma, mc, g) = ap + P = mc.p + y = mc.state_values' + M = P .* g.(y) .^ (-gamma) + @assert maximum(abs, eigvals(M)) < 1 / beta + + # Find consol prices + p = consol_price(ap, zeta) + + # Operator for fixed point, using consol prices + T(w) = max.(beta * M * w, p .- p_s) + + # Compute option price as fixed point + sol = fixedpoint(T, zeros(length(y), 1)) + converged(sol) || error("Failed to converge in $(sol.iterations) iter") + return sol.zero end ``` Here's a plot of $w$ compared to the consol price when $P_S = 40$ ```{code-cell} julia -ap = AssetPriceModel(β=0.9) -ζ = 1.0 +ap = AssetPriceModel(; beta = 0.9) +zeta = 1.0 strike_price = 40.0 x = ap.mc.state_values -p = consol_price(ap, ζ) -w = call_option(ap, ζ, strike_price) +p = consol_price(ap, zeta) +w = call_option(ap, zeta, strike_price) -plot(x, p, color = "blue", lw = 2, xlabel = "state", label = "consol price") -plot!(x, w, color = "green", lw = 2, label = "value of call option") +plot(x, p, color = "blue", lw = 2, xlabel = L"X_t", label = "consol price") +plot!(x, w, color = "green", lw = 2, + label = "value of call option with strike at $strike_price") ``` ```{code-cell} julia @@ -824,8 +781,8 @@ plot!(x, w, color = "green", lw = 2, label = "value of call option") tags: [remove-cell] --- @testset begin - #test p[17] ≈ 9.302197030956606 - #test w[20] ≈ 0.46101660813737866 + @test p[17] ≈ 9.302197030956606 + @test w[20] ≈ 0.4610168409491948 end ``` @@ -836,15 +793,6 @@ where the consol prices is high --- will eventually be visited. The reason is that $\beta=0.9$, so the future is discounted relatively rapidly -```{code-cell} julia ---- -tags: [remove-cell] ---- -@testset begin - #test x[2] ≈ -0.126178653628809 - #test p[5] ≈ 52.85568616593254 -end -``` ### Risk Free Rates @@ -899,9 +847,9 @@ Consider the following primitives n = 5 P = fill(0.0125, n, n) + (0.95 - 0.0125)I s = [1.05, 1.025, 1.0, 0.975, 0.95] -γ = 2.0 -β = 0.94 -ζ = 1.0 +gamma = 2.0 +beta = 0.94 +zeta = 1.0 ``` Let $g$ be defined by $g(x) = x$ (that is, $g$ is the identity map). @@ -961,25 +909,25 @@ Is one higher than the other? Can you give intuition? ```{code-cell} julia n = 5 -P = fill(0.0125, n, n) + (0.95 - 0.0125)I +P = fill(0.0125, n, n) + (0.95 - 0.0125) * I s = [0.95, 0.975, 1.0, 1.025, 1.05] # state values mc = MarkovChain(P, s) - -γ = 2.0 -β = 0.94 -ζ = 1.0 +g = x -> x # identity +gamma = 2.0 +beta = 0.94 +zeta = 1.0 p_s = 150.0 ``` Next we'll create an instance of AssetPriceModel to feed into the functions. ```{code-cell} julia -ap = AssetPriceModel(β = β, mc = mc, γ = γ, g = x -> x) +ap = AssetPriceModel(; beta, mc, gamma, g) ``` +Lucas tree prices are ```{code-cell} julia -v = tree_price(ap) -println("Lucas Tree Prices: $v\n") +tree_price(ap) ``` ```{code-cell} julia @@ -987,17 +935,18 @@ println("Lucas Tree Prices: $v\n") tags: [remove-cell] --- @testset begin - #test v[2] ≈ 21.935706611219704 + v = tree_price(ap) + @test v[2] ≈ 21.935706611219704 end ``` +Consol Bond Prices ```{code-cell} julia -v_consol = consol_price(ap, 1.0) -println("Consol Bond Prices: $(v_consol)\n") +consol_price(ap, 1.0) ``` ```{code-cell} julia -w = call_option(ap, ζ, p_s) +w = call_option(ap, zeta, p_s) ``` ```{code-cell} julia @@ -1005,8 +954,8 @@ w = call_option(ap, ζ, p_s) tags: [remove-cell] --- @testset begin - #test v_consol[1] ≈ 753.8710047641985 - #test w[2][1] ≈ 176.83933430191294 + @test consol_price(ap, 1.0)[1] ≈ 753.8710047641985 + @test w[2] ≈ 176.83933430191294 end ``` @@ -1015,23 +964,20 @@ end Here's a suitable function: ```{code-cell} julia -function finite_horizon_call_option(ap, ζ, p_s, k) - - # Simplify names, set up matrices - (;β, γ, mc) = ap - P, y = mc.p, mc.state_values - y = y' - M = P .* ap.g.(y).^(- γ) - - # Make sure that a unique console price exists - test_stability(ap, M) +function finite_horizon_call_option(ap, zeta, p_s, k) + (; beta, gamma, mc) = ap + P = mc.p + y = mc.state_values' + M = P .* ap.g.(y) .^ (-gamma) + @assert maximum(abs, eigvals(M)) < 1 / beta # Compute option price - p = consol_price(ap, ζ) - w = zeros(ap.n, 1) + p = consol_price(ap, zeta) + + w = zeros(length(y), 1) for i in 1:k # Maximize across columns - w = max.(β * M * w, p .- p_s) + w = max.(beta * M * w, p .- p_s) end return w @@ -1043,30 +989,18 @@ end tags: [remove-cell] --- @testset begin - #test p[3] ≈ 70.00064625026326 - #test w[2] ≈ 176.83933430191294 + @test finite_horizon_call_option(ap, zeta, p_s, 5)[3] ≈ 31.798938780647198 end ``` ```{code-cell} julia -lines = [] -labels = [] +p = plot(title = "Value Finite Horizon Call Option", xlabel = L"t", + ylabel = "value") for k in [5, 25] - w = finite_horizon_call_option(ap, ζ, p_s, k) - push!(lines, w) - push!(labels, L"k = %$k") -end -plot(lines, labels = reshape(labels, 1, length(labels))) -``` - -```{code-cell} julia ---- -tags: [remove-cell] ---- -@testset begin - #test lines[1][4] ≈ 29.859285398252347 - #test lines[2][2] ≈ 147.00074548801277 + w = finite_horizon_call_option(ap, zeta, p_s, k) + plot!(w; label = L"k = %$k") end +p ``` Not surprisingly, the option has greater value with larger $k$. diff --git a/lectures/multi_agent_models/markov_perf.md b/lectures/multi_agent_models/markov_perf.md index a7b61d10..3f062158 100644 --- a/lectures/multi_agent_models/markov_perf.md +++ b/lectures/multi_agent_models/markov_perf.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (markov_perf)= @@ -432,28 +432,28 @@ using QuantEcon, LinearAlgebra # parameters a0 = 10.0 a1 = 2.0 -β = 0.96 -γ = 12.0 +beta = 0.96 +gamma = 12.0 # in LQ form -A = I + zeros(3, 3) +A = I + zeros(3, 3) B1 = [0.0, 1.0, 0.0] B2 = [0.0, 0.0, 1.0] -R1 = [ 0.0 -a0 / 2.0 0.0; - -a0 / 2.0 a1 a1 / 2.0; - 0.0 a1 / 2.0 0.0] +R1 = [0.0 -a0/2.0 0.0; + -a0/2.0 a1 a1/2.0; + 0.0 a1/2.0 0.0] -R2 = [ 0.0 0.0 -a0 / 2.0; - 0.0 0.0 a1 / 2.0; - -a0 / 2.0 a1 / 2.0 a1] +R2 = [0.0 0.0 -a0/2.0; + 0.0 0.0 a1/2.0; + -a0/2.0 a1/2.0 a1] -Q1 = Q2 = γ +Q1 = Q2 = gamma S1 = S2 = W1 = W2 = M1 = M2 = 0.0 # solve using QE's nnash function F1, F2, P1, P2 = nnash(A, B1, B2, R1, R2, Q1, Q2, S1, S2, W1, W2, M1, M2, - beta=β) + beta = beta) # display policies println("Computed policies for firm 1 and firm 2:") @@ -480,8 +480,8 @@ In particular, let's take F2 as computed above, plug it into {eq}`eq_mpe_p1p` an We hope that the resulting policy will agree with F1 as computed above ```{code-cell} julia -Λ1 = A - (B2 * F2) -lq1 = QuantEcon.LQ(Q1, R1, Λ1, B1, bet=β) +Lambda1 = A - (B2 * F2) +lq1 = QuantEcon.LQ(Q1, R1, Lambda1, B1, bet = beta) P1_ih, F1_ih, d = stationary_values(lq1) F1_ih ``` @@ -493,7 +493,7 @@ tags: [remove-cell] @testset begin @test P1_ih[2, 2] ≈ 5.441368459897164 @test d ≈ 0.0 - @test Λ1[1, 1] ≈ 1.0 && Λ1[3, 2] ≈ -0.07584666305807419 + @test Lambda1[1, 1] ≈ 1.0 && Lambda1[3, 2] ≈ -0.07584666305807419 @test F1_ih ≈ [-0.6684661291052371 0.29512481789806305 0.07584666292394007] @test isapprox(F1, F1_ih, atol=1e-7) # Make sure the test below comes up true. end @@ -504,7 +504,7 @@ This is close enough for rock and roll, as they say in the trade. Indeed, isapprox agrees with our assessment ```{code-cell} julia -isapprox(F1, F1_ih, atol=1e-7) +isapprox(F1, F1_ih, atol = 1e-7) ``` ### Dynamics @@ -522,22 +522,21 @@ The following program ```{code-cell} julia using LaTeXStrings, Plots - AF = A - B1 * F1 - B2 * F2 n = 20 x = zeros(3, n) x[:, 1] = [1 1 1] -for t in 1:n-1 - x[:, t+1] = AF * x[:, t] +for t in 1:(n - 1) + x[:, t + 1] = AF * x[:, t] end q1 = x[2, :] q2 = x[3, :] q = q1 + q2 # total output, MPE p = a0 .- a1 * q # price, MPE -plt = plot(q, color=:blue, lw=2, alpha=0.75, label="total output") -plot!(plt, p, color=:green, lw=2, alpha=0.75, label="price") -plot!(plt, title="Output and prices, duopoly MPE") +plt = plot(q, color = :blue, lw = 2, alpha = 0.75, label = "total output") +plot!(plt, p, color = :green, lw = 2, alpha = 0.75, label = "price") +plot!(plt, title = "Output and prices, duopoly MPE") ``` ```{code-cell} julia @@ -651,9 +650,9 @@ The exercise is to calculate these matrices and compute the following figures. The first figure shows the dynamics of inventories for each firm when the parameters are ```{code-cell} julia -δ = 0.02 -D = [ -1 0.5; - 0.5 -1] +delta = 0.02 +D = [-1 0.5; + 0.5 -1] b = [25, 25] c1 = c2 = [1, -2, 1] e1 = e2 = [10, 10, 3] @@ -683,28 +682,28 @@ First let's compute the duopoly MPE under the stated parameters # parameters a0 = 10.0 a1 = 2.0 -β = 0.96 -γ = 12.0 +beta = 0.96 +gamma = 12.0 # in LQ form A = I + zeros(3, 3) B1 = [0.0, 1.0, 0.0] B2 = [0.0, 0.0, 1.0] -R1 = [ 0.0 -a0 / 2.0 0.0; - -a0 / 2.0 a1 a1 / 2.0; - 0.0 a1 / 2.0 0.0] +R1 = [0.0 -a0/2.0 0.0; + -a0/2.0 a1 a1/2.0; + 0.0 a1/2.0 0.0] -R2 = [ 0.0 0.0 -a0 / 2.0; - 0.0 0.0 a1 / 2.0; - -a0 / 2.0 a1 / 2.0 a1] +R2 = [0.0 0.0 -a0/2.0; + 0.0 0.0 a1/2.0; + -a0/2.0 a1/2.0 a1] -Q1 = Q2 = γ +Q1 = Q2 = gamma S1 = S2 = W1 = W2 = M1 = M2 = 0.0 # solve using QE's nnash function F1, F2, P1, P2 = nnash(A, B1, B2, R1, R2, Q1, Q2, S1, S2, W1, W2, M1, M2, - beta=β) + beta = beta) ``` ```{code-cell} julia @@ -783,9 +782,9 @@ resulting dynamics of $\{q_t\}$, starting at $q_0 = 2.0$. tags: [hide-output] --- R = a1 -Q = γ +Q = gamma A = B = 1 -lq_alt = QuantEcon.LQ(Q, R, A, B, bet=β) +lq_alt = QuantEcon.LQ(Q, R, A, B, bet=beta) P, F, d = stationary_values(lq_alt) q̄ = a0 / (2.0 * a1) qm = zeros(n) @@ -814,15 +813,19 @@ end Let's have a look at the different time paths ```{code-cell} julia -plt_q = plot(qm, color=:blue, lw=2, alpha=0.75, label="monopolist output") -plot!(plt_q, q, color=:green, lw=2, alpha=0.75, label="MPE total output") -plot!(plt_q, xlabel="time", ylabel="output", ylim=(2,4),legend=:topright) +plt_q = plot(qm, color = :blue, lw = 2, alpha = 0.75, + label = "monopolist output") +plot!(plt_q, q, color = :green, lw = 2, alpha = 0.75, + label = "MPE total output") +plot!(plt_q, xlabel = "time", ylabel = "output", ylim = (2, 4), + legend = :topright) -plt_p = plot(pm, color=:blue, lw=2, alpha=0.75, label="monopolist price") -plot!(plt_p, p, color=:green, lw=2, alpha=0.75, label="MPE price") -plot!(plt_p, xlabel="time", ylabel="price",legend=:topright) +plt_p = plot(pm, color = :blue, lw = 2, alpha = 0.75, + label = "monopolist price") +plot!(plt_p, p, color = :green, lw = 2, alpha = 0.75, label = "MPE price") +plot!(plt_p, xlabel = "time", ylabel = "price", legend = :topright) -plot(plt_q, plt_p, layout=(2,1), size=(700,600)) +plot(plt_q, plt_p, layout = (2, 1), size = (700, 600)) ``` ### Exercise 2 @@ -830,13 +833,13 @@ plot(plt_q, plt_p, layout=(2,1), size=(700,600)) We treat the case $\delta = 0.02$ ```{code-cell} julia -δ = 0.02 -D = [-1 0.5; +delta = 0.02 +D = [-1 0.5; 0.5 -1] b = [25, 25] c1 = c2 = [1, -2, 1] e1 = e2 = [10, 10, 3] -δ_1 = 1-δ +delta_1 = 1 - delta ``` Recalling that the control and state are @@ -860,42 +863,42 @@ we set up the matrices as follows: ```{code-cell} julia # create matrices needed to compute the Nash feedback equilibrium -A = [δ_1 0 -δ_1 * b[1]; - 0 δ_1 -δ_1 * b[2]; - 0 0 1] - -B1 = δ_1 * [1 -D[1, 1]; - 0 -D[2, 1]; - 0 0] -B2 = δ_1 * [0 -D[1, 2]; - 1 -D[2, 2]; - 0 0] - -R1 = -[0.5 * c1[3] 0 0.5 * c1[2]; - 0 0 0; - 0.5 * c1[2] 0 c1[1]] - -R2 = -[0 0 0; - 0 0.5 * c2[3] 0.5*c2[2]; - 0 0.5 * c2[2] c2[1]] - -Q1 = [-0.5*e1[3] 0; - 0 D[1, 1]] -Q2 = [-0.5*e2[3] 0; - 0 D[2, 2]] +A = [delta_1 0 -delta_1*b[1]; + 0 delta_1 -delta_1*b[2]; + 0 0 1] + +B1 = delta_1 * [1 -D[1, 1]; + 0 -D[2, 1]; + 0 0] +B2 = delta_1 * [0 -D[1, 2]; + 1 -D[2, 2]; + 0 0] + +R1 = -[0.5*c1[3] 0 0.5*c1[2]; + 0 0 0; + 0.5*c1[2] 0 c1[1]] + +R2 = -[0 0 0; + 0 0.5*c2[3] 0.5*c2[2]; + 0 0.5*c2[2] c2[1]] + +Q1 = [-0.5*e1[3] 0; + 0 D[1, 1]] +Q2 = [-0.5*e2[3] 0; + 0 D[2, 2]] S1 = zeros(2, 2) S2 = copy(S1) -W1 = [ 0.0 0.0; - 0.0 0.0; - -0.5 * e1[2] b[1] / 2.0] -W2 = [ 0.0 0.0; - 0.0 0.0; - -0.5 * e2[2] b[2] / 2.0] +W1 = [0.0 0.0; + 0.0 0.0; + -0.5*e1[2] b[1]/2.0] +W2 = [0.0 0.0; + 0.0 0.0; + -0.5*e2[2] b[2]/2.0] -M1 = [0.0 0.0; - 0.0 D[1, 2] / 2.0] +M1 = [0.0 0.0; + 0.0 D[1, 2]/2.0] M2 = copy(M1) ``` @@ -943,16 +946,16 @@ corresponding to $\delta = 0.02$ AF = A - B1 * F1 - B2 * F2 n = 25 x = zeros(3, n) -x[:, 1] = [2 0 1] -for t in 1:(n-1) - x[:, t+1] = AF * x[:, t] +x[:, 1] = [2 0 1] +for t in 1:(n - 1) + x[:, t + 1] = AF * x[:, t] end I1 = x[1, :] I2 = x[2, :] -plot(I1, color=:blue, lw=2, alpha=0.75, label="inventories, firm 1") -plot!(I2, color=:green, lw=2, alpha=0.75, label="inventories, firm 2") -plot!(title=L"\delta = 0.02") +plot(I1, color = :blue, lw = 2, alpha = 0.75, label = "inventories, firm 1") +plot!(I2, color = :green, lw = 2, alpha = 0.75, label = "inventories, firm 2") +plot!(title = L"\delta = 0.02") ``` ```{code-cell} julia diff --git a/lectures/multi_agent_models/matsuyama.md b/lectures/multi_agent_models/matsuyama.md index 3153335a..ab0a1611 100644 --- a/lectures/multi_agent_models/matsuyama.md +++ b/lectures/multi_agent_models/matsuyama.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (matsuyama)= @@ -336,13 +336,12 @@ using Test ``` ```{code-cell} julia -using LinearAlgebra, Statistics -using Plots, Parameters +using LinearAlgebra, Statistics, Plots ``` ```{code-cell} julia -function h_j(j, nk, s1, s2, θ, δ, ρ) +function h_j(j, nk, s1, s2, theta, delta, rho) # Find out who's h we are evaluating if j == 1 sj = s1 @@ -354,8 +353,8 @@ function h_j(j, nk, s1, s2, θ, δ, ρ) # Coefficients on the quadratic a x^2 + b x + c = 0 a = 1.0 - b = ((ρ + 1 / ρ) * nk - sj - sk) - c = (nk * nk - (sj * nk) / ρ - sk * ρ * nk) + b = ((rho + 1 / rho) * nk - sj - sk) + c = (nk * nk - (sj * nk) / rho - sk * rho * nk) # Positive solution of quadratic form root = (-b + sqrt(b * b - 4 * a * c)) / (2 * a) @@ -363,41 +362,49 @@ function h_j(j, nk, s1, s2, θ, δ, ρ) return root end -DLL(n1, n2, s1_ρ, s2_ρ, s1, s2, θ, δ, ρ) = - (n1 ≤ s1_ρ) && (n2 ≤ s2_ρ) +function DLL(n1, n2, s1_rho, s2_rho, s1, s2, theta, delta, rho) + (n1 <= s1_rho) && (n2 <= s2_rho) +end -DHH(n1, n2, s1_ρ, s2_ρ, s1, s2, θ, δ, ρ) = - (n1 ≥ h_j(1, n2, s1, s2, θ, δ, ρ)) && (n2 ≥ h_j(2, n1, s1, s2, θ, δ, ρ)) +function DHH(n1, n2, s1_rho, s2_rho, s1, s2, theta, delta, rho) + (n1 >= h_j(1, n2, s1, s2, theta, delta, rho)) && + (n2 >= h_j(2, n1, s1, s2, theta, delta, rho)) +end -DHL(n1, n2, s1_ρ, s2_ρ, s1, s2, θ, δ, ρ) = - (n1 ≥ s1_ρ) && (n2 ≤ h_j(2, n1, s1, s2, θ, δ, ρ)) +function DHL(n1, n2, s1_rho, s2_rho, s1, s2, theta, delta, rho) + (n1 >= s1_rho) && (n2 <= h_j(2, n1, s1, s2, theta, delta, rho)) +end -DLH(n1, n2, s1_ρ, s2_ρ, s1, s2, θ, δ, ρ) = - (n1 ≤ h_j(1, n2, s1, s2, θ, δ, ρ)) && (n2 ≥ s2_ρ) +function DLH(n1, n2, s1_rho, s2_rho, s1, s2, theta, delta, rho) + (n1 <= h_j(1, n2, s1, s2, theta, delta, rho)) && (n2 >= s2_rho) +end -function one_step(n1, n2, s1_ρ, s2_ρ, s1, s2, θ, δ, ρ) +function one_step(n1, n2, s1_rho, s2_rho, s1, s2, theta, delta, rho) # Depending on where we are, evaluate the right branch - if DLL(n1, n2, s1_ρ, s2_ρ, s1, s2, θ, δ, ρ) - n1_tp1 = δ * (θ * s1_ρ + (1 - θ) * n1) - n2_tp1 = δ * (θ * s2_ρ + (1 - θ) * n2) - elseif DHH(n1, n2, s1_ρ, s2_ρ, s1, s2, θ, δ, ρ) - n1_tp1 = δ * n1 - n2_tp1 = δ * n2 - elseif DHL(n1, n2, s1_ρ, s2_ρ, s1, s2, θ, δ, ρ) - n1_tp1 = δ * n1 - n2_tp1 = δ * (θ * h_j(2, n1, s1, s2, θ, δ, ρ) + (1 - θ) * n2) - elseif DLH(n1, n2, s1_ρ, s2_ρ, s1, s2, θ, δ, ρ) - n1_tp1 = δ * (θ * h_j(1, n2, s1, s2, θ, δ, ρ) + (1 - θ) * n1) - n2_tp1 = δ * n2 + if DLL(n1, n2, s1_rho, s2_rho, s1, s2, theta, delta, rho) + n1_tp1 = delta * (theta * s1_rho + (1 - theta) * n1) + n2_tp1 = delta * (theta * s2_rho + (1 - theta) * n2) + elseif DHH(n1, n2, s1_rho, s2_rho, s1, s2, theta, delta, rho) + n1_tp1 = delta * n1 + n2_tp1 = delta * n2 + elseif DHL(n1, n2, s1_rho, s2_rho, s1, s2, theta, delta, rho) + n1_tp1 = delta * n1 + n2_tp1 = delta * (theta * h_j(2, n1, s1, s2, theta, delta, rho) + + (1 - theta) * n2) + elseif DLH(n1, n2, s1_rho, s2_rho, s1, s2, theta, delta, rho) + n1_tp1 = delta * (theta * h_j(1, n2, s1, s2, theta, delta, rho) + + (1 - theta) * n1) + n2_tp1 = delta * n2 end return n1_tp1, n2_tp1 end -new_n1n2(n1_0, n2_0, s1_ρ, s2_ρ, s1, s2, θ, δ, ρ) = - one_step(n1_0, n2_0, s1_ρ, s2_ρ, s1, s2, θ, δ, ρ) +function new_n1n2(n1_0, n2_0, s1_rho, s2_rho, s1, s2, theta, delta, rho) + one_step(n1_0, n2_0, s1_rho, s2_rho, s1, s2, theta, delta, rho) +end -function pers_till_sync(n1_0, n2_0, s1_ρ, s2_ρ, s1, s2, θ, δ, ρ, +function pers_till_sync(n1_0, n2_0, s1_rho, s2_rho, s1, s2, theta, delta, rho, maxiter, npers) # Initialize the status of synchronization @@ -407,16 +414,17 @@ function pers_till_sync(n1_0, n2_0, s1_ρ, s2_ρ, s1, s2, θ, δ, ρ, nsync = 0 - while (~synchronized) && (iters < maxiter) + while (!synchronized) && (iters < maxiter) # Increment the number of iterations and get next values iters += 1 - n1_t, n2_t = new_n1n2(n1_0, n2_0, s1_ρ, s2_ρ, s1, s2, θ, δ, ρ) + n1_t, n2_t = new_n1n2(n1_0, n2_0, s1_rho, s2_rho, s1, s2, theta, delta, + rho) # Check whether same in this period if abs(n1_t - n2_t) < 1e-8 nsync += 1 - # If not, then reset the nsync counter + # If not, then reset the nsync counter else nsync = 0 end @@ -432,20 +440,21 @@ function pers_till_sync(n1_0, n2_0, s1_ρ, s2_ρ, s1, s2, θ, δ, ρ, return synchronized, pers_2_sync end -function create_attraction_basis(s1_ρ, s2_ρ, s1, s2, θ, δ, ρ, +function create_attraction_basis(s1_rho, s2_rho, s1, s2, theta, delta, rho, maxiter, npers, npts) # Create unit range with npts synchronized, pers_2_sync = false, 0 - unit_range = range(0.0, 1.0, length = npts) + unit_range = range(0.0, 1.0, length = npts) # Allocate space to store time to sync time_2_sync = zeros(npts, npts) # Iterate over initial conditions for (i, n1_0) in enumerate(unit_range) for (j, n2_0) in enumerate(unit_range) - synchronized, pers_2_sync = pers_till_sync(n1_0, n2_0, s1_ρ, s2_ρ, - s1, s2, θ, δ, ρ, - maxiter, npers) + synchronized, pers_2_sync = pers_till_sync(n1_0, n2_0, s1_rho, + s2_rho, s1, s2, theta, + delta, rho, maxiter, + npers) time_2_sync[i, j] = pers_2_sync end end @@ -453,18 +462,17 @@ function create_attraction_basis(s1_ρ, s2_ρ, s1, s2, θ, δ, ρ, end # model -function MSGSync(s1 = 0.5, θ = 2.5, δ = 0.7, ρ = 0.2) +function MSGSync(s1 = 0.5, theta = 2.5, delta = 0.7, rho = 0.2) # Store other cutoffs and parameters we use s2 = 1 - s1 - s1_ρ = min((s1 - ρ * s2) / (1 - ρ), 1) - s2_ρ = 1 - s1_ρ + s1_rho = min((s1 - rho * s2) / (1 - rho), 1) + s2_rho = 1 - s1_rho - return (s1 = s1, s2 = s2, s1_ρ = s1_ρ, s2_ρ = s2_ρ, θ = θ, δ = δ, ρ = ρ) + return (; s1, s2, s1_rho, s2_rho, theta, delta, rho) end function simulate_n(model, n1_0, n2_0, T) - # Unpack parameters - @unpack s1, s2, θ, δ, ρ, s1_ρ, s2_ρ = model + (; s1, s2, theta, delta, rho, s1_rho, s2_rho) = model # Allocate space n1 = zeros(T) @@ -474,30 +482,28 @@ function simulate_n(model, n1_0, n2_0, T) for t in 1:T # Get next values n1[t], n2[t] = n1_0, n2_0 - n1_0, n2_0 = new_n1n2(n1_0, n2_0, s1_ρ, s2_ρ, s1, s2, θ, δ, ρ) + n1_0, n2_0 = new_n1n2(n1_0, n2_0, s1_rho, s2_rho, s1, s2, theta, delta, + rho) end return n1, n2 end -function pers_till_sync(model, n1_0, n2_0, - maxiter = 500, npers = 3) - # Unpack parameters - @unpack s1, s2, θ, δ, ρ, s1_ρ, s2_ρ = model +function pers_till_sync(model, n1_0, n2_0, maxiter = 500, npers = 3) + (; s1, s2, theta, delta, rho, s1_rho, s2_rho) = model - return pers_till_sync(n1_0, n2_0, s1_ρ, s2_ρ, s1, s2, - θ, δ, ρ, maxiter, npers) + return pers_till_sync(n1_0, n2_0, s1_rho, s2_rho, s1, s2, + theta, delta, rho, maxiter, npers) end function create_attraction_basis(model; maxiter = 250, npers = 3, npts = 50) - # Unpack parameters - @unpack s1, s2, θ, δ, ρ, s1_ρ, s2_ρ = model + (; s1, s2, theta, delta, rho, s1_rho, s2_rho) = model - ab = create_attraction_basis(s1_ρ, s2_ρ, s1, s2, θ, δ, - ρ, maxiter, npers, npts) + ab = create_attraction_basis(s1_rho, s2_rho, s1, s2, theta, delta, + rho, maxiter, npers, npts) return ab end ``` @@ -513,8 +519,9 @@ The time series share parameters but differ in their initial condition. Here's the function ```{code-cell} julia -function plot_timeseries(n1_0, n2_0, s1 = 0.5, θ = 2.5, δ = 0.7, ρ = 0.2) - model = MSGSync(s1, θ, δ, ρ) +function plot_timeseries(n1_0, n2_0, s1 = 0.5, theta = 2.5, delta = 0.7, + rho = 0.2) + model = MSGSync(s1, theta, delta, rho) n1, n2 = simulate_n(model, n1_0, n2_0, 25) return [n1 n2] end @@ -569,20 +576,21 @@ Replicate the figure {ref}`shown above ` by coloring initial conditions ### Exercise 1 ```{code-cell} julia -function plot_attraction_basis(s1 = 0.5, θ = 2.5, δ = 0.7, ρ = 0.2; npts = 250) +function plot_attraction_basis(s1 = 0.5, theta = 2.5, delta = 0.7, rho = 0.2; + npts = 250) # Create attraction basis - unitrange = range(0, 1, length = npts) - model = MSGSync(s1, θ, δ, ρ) - ab = create_attraction_basis(model,npts=npts) + unitrange = range(0, 1, length = npts) + model = MSGSync(s1, theta, delta, rho) + ab = create_attraction_basis(model, npts = npts) plt = Plots.heatmap(ab, legend = false) end ``` ```{code-cell} julia params = [[0.5, 2.5, 0.7, 0.2], - [0.5, 2.5, 0.7, 0.4], - [0.5, 2.5, 0.7, 0.6], - [0.5, 2.5, 0.7, 0.8]] + [0.5, 2.5, 0.7, 0.4], + [0.5, 2.5, 0.7, 0.6], + [0.5, 2.5, 0.7, 0.8]] plots = (plot_attraction_basis(p...) for p in params) plot(plots..., size = (1000, 1000)) @@ -593,13 +601,13 @@ plot(plots..., size = (1000, 1000)) tags: [remove-cell] --- function plot_attraction_basis(s1 = 0.5, - θ = 2.5, - δ = 0.7, - ρ = 0.2; + theta = 2.5, + delta = 0.7, + rho = 0.2; npts = 250) # Create attraction basis unitrange = range(0, 1, length = npts) - model = MSGSync(s1, θ, δ, ρ) + model = MSGSync(s1, theta, delta, rho) ab = create_attraction_basis(model, npts = npts) end diff --git a/lectures/multi_agent_models/rational_expectations.md b/lectures/multi_agent_models/rational_expectations.md index 4c3d9fe1..19654114 100644 --- a/lectures/multi_agent_models/rational_expectations.md +++ b/lectures/multi_agent_models/rational_expectations.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (ree)= @@ -595,7 +595,7 @@ using Test ``` ```{code-cell} julia -using QuantEcon, Printf, LinearAlgebra +using QuantEcon, LinearAlgebra ``` To map a problem into a {doc}`discounted optimal linear control problem <../dynamic_programming/lqcontrol>`, we need to define. @@ -662,34 +662,36 @@ Here's our solution # model parameters a0 = 100 a1 = 0.05 -β = 0.95 -γ = 10.0 +beta = 0.95 +gamma = 10.0 # beliefs -κ0 = 95.5 -κ1 = 0.95 +kappa0 = 95.5 +kappa1 = 0.95 # formulate the LQ problem -A = [1 0 0 - 0 κ1 κ0 - 0 0 1] +A = [1 0 0 + 0 kappa1 kappa0 + 0 0 1] B = [1.0, 0.0, 0.0] -R = [ 0 a1/2 -a0/2 - a1/2 0 0 - -a0/2 0 0] +R = [0 a1/2 -a0/2 + a1/2 0 0 + -a0/2 0 0] -Q = 0.5 * γ +Q = 0.5 * gamma # solve for the optimal policy -lq = QuantEcon.LQ(Q, R, A, B; bet = β) +lq = QuantEcon.LQ(Q, R, A, B; bet = beta) P, F, d = stationary_values(lq) -hh = h0, h1, h2 = -F[3], 1 - F[1], -F[2] - -@printf("F = [%.3f, %.3f, %.3f]\n", F[1], F[2], F[3]) -@printf("(h0, h1, h2) = [%.3f, %.3f, %.3f]\n", h0, h1, h2) +# unpack results +h0 = -F[3] +h1 = 1 - F[1] +h2 = -F[2] +@show F +@show h0, h1, h2; ``` ```{code-cell} julia @@ -748,16 +750,18 @@ candidates = ([94.0886298678, 0.923409232937], [95.0818452486, 0.952459076301]) for (k0, k1) in candidates - A = [1 0 0 + A = [1 0 0 0 k1 k0 - 0 0 1] - lq = QuantEcon.LQ(Q, R, A, B; bet=β) + 0 0 1] + lq = QuantEcon.LQ(Q, R, A, B; bet = beta) P, F, d = stationary_values(lq) - hh = h0, h1, h2 = -F[3], 1 - F[1], -F[2] + h0 = -F[3] + h1 = 1 - F[1] + h2 = -F[2] if isapprox(k0, h0; atol = 1e-4) && isapprox(k1, h1 + h2; atol = 1e-4) - @printf("Equilibrium pair = (%.6f, %.6f)\n", k0, k1) - @printf("(h0, h1, h2) = [%.6f, %.6f, %.6f]\n", h0, h1, h2) + println("Equilibrium pair = ($k0, $k1)") + @show h0, h1, h2 end end ``` @@ -830,18 +834,19 @@ $\kappa_0 = -F_1$ and $\kappa_1 = 1-F_0$ A = I + zeros(2, 2) B = [1.0, 0.0] -R = [ a1 / 2.0 -a0 / 2.0 - -a0 / 2.0 0.0] +R = [a1/2.0 -a0/2.0 + -a0/2.0 0.0] -Q = γ / 2.0 +Q = gamma / 2.0 # solve for the optimal policy -lq = QuantEcon.LQ(Q, R, A, B; bet=β) +lq = QuantEcon.LQ(Q, R, A, B; bet = beta) P, F, d = stationary_values(lq) # print the results -κ0, κ1 = -F[2], 1 - F[1] -println("κ0=$κ0\tκ1=$κ1") +kappa0 = -F[2] +kappa1 = 1 - F[1] +@show kappa0, kappa1; ``` ```{code-cell} julia @@ -849,8 +854,8 @@ println("κ0=$κ0\tκ1=$κ1") tags: [remove-cell] --- @testset begin - @test κ0 ≈ 95.081845248600 rtol = 4 - @test κ1 ≈ 0.952459076301 rtol = 4 + @test kappa0 ≈ 95.081845248600 rtol = 4 + @test kappa1 ≈ 0.952459076301 rtol = 4 end ``` @@ -876,18 +881,18 @@ The problem can be solved as follows A = I + zeros(2, 2) B = [1.0, 0.0] -R = [ a1 -a0 / 2.0 - -a0 / 2.0 0.0] +R = [a1 -a0/2.0 + -a0/2.0 0.0] -Q = γ / 2.0 +Q = gamma / 2.0 # solve for the optimal policy -lq = QuantEcon.LQ(Q, R, A, B; bet=β) +lq = QuantEcon.LQ(Q, R, A, B; bet = beta) P, F, d = stationary_values(lq) # print the results m0, m1 = -F[2], 1 - F[1] -println("m0=$m0\tm1=$m1") +@show m0, m1; ``` ```{code-cell} julia diff --git a/lectures/multi_agent_models/schelling.md b/lectures/multi_agent_models/schelling.md index 868aed51..3bfc53b9 100644 --- a/lectures/multi_agent_models/schelling.md +++ b/lectures/multi_agent_models/schelling.md @@ -6,9 +6,8 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- - (schelling)= ```{raw} html
@@ -148,7 +147,7 @@ using Test, Random ``` ```{code-cell} julia -using Parameters, Plots, LinearAlgebra, Statistics +using Plots, LinearAlgebra, Statistics ``` @@ -160,7 +159,7 @@ Random.seed!(42); ``` ```{code-cell} julia -Agent = @with_kw (kind, location = rand(2)) +Agent(; kind, location = rand(2)) = (; kind, location) draw_location!(a) = a.location .= rand(2) @@ -179,7 +178,7 @@ function is_happy(a) # partialsortperm(get_distance.(Ref(a), agents), # 1:neighborhood_size)) - return share ≥ preference + return share >= preference end function update!(a) @@ -205,7 +204,8 @@ function plot_distribution(agents) end end - p = scatter(x_vals_0, y_vals_0, color = :orange, markersize = 8, alpha = 0.6) + p = scatter(x_vals_0, y_vals_0, color = :orange, markersize = 8, + alpha = 0.6) scatter!(x_vals_1, y_vals_1, color = :green, markersize = 8, alpha = 0.6) return plot!(legend = :none) end diff --git a/lectures/multi_agent_models/uncertainty_traps.md b/lectures/multi_agent_models/uncertainty_traps.md index a637b118..b2a8d799 100644 --- a/lectures/multi_agent_models/uncertainty_traps.md +++ b/lectures/multi_agent_models/uncertainty_traps.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (uncertainty_traps)= @@ -231,22 +231,26 @@ using Test, Random ```{code-cell} julia using LinearAlgebra, Statistics -using DataFrames, LaTeXStrings, Parameters, Plots +using DataFrames, LaTeXStrings, Plots ``` ```{code-cell} julia -UncertaintyTrapEcon = @with_kw (a = 1.5, # risk aversion - γ_x = 0.5, # production shock precision - ρ = 0.99, # correlation coefficient for θ - σ_θ = 0.5, # standard dev. of θ shock - num_firms = 100, # number of firms - σ_F = 1.5, # standard dev. of fixed costs - c = -420.0, # external opportunity cost - μ_init = 0.0, # initial value for μ - γ_init = 4.0, # initial value for γ - θ_init = 0.0, # initial value for θ - σ_x = sqrt(a / γ_x)) # standard dev. of shock +function # standard dev. of shock +UncertaintyTrapEcon(; a = 1.5, # risk aversion + gamma_x = 0.5, # production shock precision + rho = 0.99, # correlation coefficient for theta + sigma_theta = 0.5, # standard dev. of theta shock + num_firms = 100, # number of firms + sigma_F = 1.5, # standard dev. of fixed costs + c = -420.0, # external opportunity cost + mu_init = 0.0, # initial value for mu + gamma_init = 4.0, # initial value for gamma + theta_init = 0.0, # initial value for theta + sigma_x = sqrt(a / gamma_x)) # standard dev. of shock + (; a, gamma_x, rho, sigma_theta, num_firms, sigma_F, c, mu_init, gamma_init, + theta_init, sigma_x) +end ``` In the results below we use this code to simulate time series for the major variables. @@ -360,18 +364,19 @@ different values of $M$ ```{code-cell} julia econ = UncertaintyTrapEcon() -@unpack ρ, σ_θ, γ_x = econ # simplify names +(; rho, sigma_theta, gamma_x) = econ # simplify names -# grid for γ and γ_{t+1} -γ = range(1e-10, 3, length = 200) +# grid for gamma and gamma_{t+1} +gamma = range(1e-10, 3, length = 200) M_range = 0:6 -γp = 1 ./ (ρ^2 ./ (γ .+ γ_x .* M_range') .+ σ_θ^2) +gammap = 1 ./ (rho^2 ./ (gamma .+ gamma_x .* M_range') .+ sigma_theta^2) labels = ["0" "1" "2" "3" "4" "5" "6"] -plot(γ, γ, lw = 2, label = "45 Degree") -plot!(γ, γp, lw = 2, label = labels) -plot!(xlabel = L"\gamma", ylabel = L"\gamma^\prime", legend_title = L"M", legend = :bottomright) +plot(gamma, gamma, lw = 2, label = "45 Degree") +plot!(gamma, gammap, lw = 2, label = labels) +plot!(xlabel = L"\gamma", ylabel = L"\gamma^\prime", legend_title = L"M", + legend = :bottomright) ``` ```{code-cell} julia @@ -379,9 +384,9 @@ plot!(xlabel = L"\gamma", ylabel = L"\gamma^\prime", legend_title = L"M", legend tags: [remove-cell] --- @testset begin - @test γp[2,2] ≈ 0.46450522950184053 - @test γp[3,3] ≈ 0.8323524432613787 - @test γp[5,5] ≈ 1.3779664509290432 + @test gammap[2,2] ≈ 0.46450522950184053 + @test gammap[3,3] ≈ 0.8323524432613787 + @test gammap[5,5] ≈ 1.3779664509290432 end ``` @@ -396,49 +401,53 @@ is, the number of active firms and average output ```{code-cell} julia function simulate(uc, capT = 2_000) # unpack parameters - @unpack a, γ_x, ρ, σ_θ, num_firms, σ_F, c, μ_init, γ_init, θ_init, σ_x = uc + (; a, gamma_x, rho, sigma_theta, num_firms, sigma_F, c, mu_init, gamma_init, theta_init, sigma_x) = uc # draw standard normal shocks w_shocks = randn(capT) # aggregate functions - # auxiliary function ψ - function ψ(γ, μ, F) - temp1 = -a * (μ - F) - temp2 = 0.5 * a^2 / (γ + γ_x) + # auxiliary function psi + function psi(gamma, mu, F) + temp1 = -a * (mu - F) + temp2 = 0.5 * a^2 / (gamma + gamma_x) return (1 - exp(temp1 + temp2)) / a - c end # compute X, M - function gen_aggregates(γ, μ, θ) - F_vals = σ_F * randn(num_firms) - M = sum(ψ.(Ref(γ), Ref(μ), F_vals) .> 0) # counts number of active firms - if any(ψ(γ, μ, f) > 0 for f in F_vals) # ∃ an active firm - x_vals = θ .+ σ_x * randn(M) + function gen_aggregates(gamma, mu, theta) + F_vals = sigma_F * randn(num_firms) + M = sum(psi.(Ref(gamma), Ref(mu), F_vals) .> 0) # counts number of active firms + if any(psi(gamma, mu, f) > 0 for f in F_vals) # there is an active firm + x_vals = theta .+ sigma_x * randn(M) X = mean(x_vals) else X = 0.0 end - return (X = X, M = M) + return (; X, M) end # initialize dataframe - X_init, M_init = gen_aggregates(γ_init, μ_init, θ_init) - df = DataFrame(γ = γ_init, μ = μ_init, θ = θ_init, X = X_init, M = M_init) + X_init, M_init = gen_aggregates(gamma_init, mu_init, theta_init) + df = DataFrame(gamma = gamma_init, mu = mu_init, theta = theta_init, + X = X_init, M = M_init) # update dataframe for t in 2:capT # unpack old variables - θ_old, γ_old, μ_old, X_old, M_old = (df.θ[end], df.γ[end], df.μ[end], df.X[end], df.M[end]) + theta_old, gamma_old, mu_old, X_old, M_old = (df.theta[end], + df.gamma[end], df.mu[end], + df.X[end], df.M[end]) # define new beliefs - θ = ρ * θ_old + σ_θ * w_shocks[t-1] - μ = (ρ * (γ_old * μ_old + M_old * γ_x * X_old))/(γ_old + M_old * γ_x) - γ = 1 / (ρ^2 / (γ_old + M_old * γ_x) + σ_θ^2) + theta = rho * theta_old + sigma_theta * w_shocks[t - 1] + mu = (rho * (gamma_old * mu_old + M_old * gamma_x * X_old)) / + (gamma_old + M_old * gamma_x) + gamma = 1 / (rho^2 / (gamma_old + M_old * gamma_x) + sigma_theta^2) # compute new aggregates - X, M = gen_aggregates(γ, μ, θ) - push!(df, (γ = γ, μ = μ, θ = θ, X = X, M = M)) + X, M = gen_aggregates(gamma, mu, theta) + push!(df, (; gamma, mu, theta, X, M)) end # return @@ -459,19 +468,20 @@ Random.seed!(42); # set random seed for reproducible results ```{code-cell} julia df = simulate(econ) -plot(eachindex(df.μ), df.μ, lw = 2, label = L"\mu") -plot!(eachindex(df.θ), df.θ, lw = 2, label = L"\theta") -plot!(xlabel = L"x", ylabel = L"y", legend_title = "Variable", legend = :bottomright) +plot(eachindex(df.mu), df.mu, lw = 2, label = L"\mu") +plot!(eachindex(df.theta), df.theta, lw = 2, label = L"\theta") +plot!(xlabel = L"x", ylabel = L"y", legend_title = "Variable", + legend = :bottomright) ``` Now let's plot the whole thing together ```{code-cell} julia -len = eachindex(df.θ) -yvals = [df.θ, df.μ, df.γ, df.M] +len = eachindex(df.theta) +yvals = [df.theta, df.mu, df.gamma, df.M] vars = [L"\theta", L"\mu", L"\gamma", L"M"] -plt = plot(layout = (4,1), size = (600, 600)) +plt = plot(layout = (4, 1), size = (600, 600)) for i in 1:4 plot!(plt[i], len, yvals[i], xlabel = L"t", ylabel = vars[i], label = "") @@ -484,7 +494,7 @@ plot(plt) --- tags: [remove-cell] --- -mdf = DataFrame(t = eachindex(df.θ), θ = df.θ, μ = df.μ, γ = df.γ, M = df.M) +mdf = DataFrame(t = eachindex(df.theta), theta = df.theta, mu = df.mu, gamma = df.gamma, M = df.M) @testset begin @test stack(mdf, collect(2:5))[:value][3] ≈ -0.49742498224730913 atol = 1e-3 diff --git a/lectures/software_engineering/need_for_speed.md b/lectures/software_engineering/need_for_speed.md index 22ff0864..b54b0112 100644 --- a/lectures/software_engineering/need_for_speed.md +++ b/lectures/software_engineering/need_for_speed.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (types_methods)= diff --git a/lectures/software_engineering/testing.md b/lectures/software_engineering/testing.md index 955cf081..3d3824b4 100644 --- a/lectures/software_engineering/testing.md +++ b/lectures/software_engineering/testing.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (testing)= diff --git a/lectures/software_engineering/tools_editors.md b/lectures/software_engineering/tools_editors.md index 7291bb65..07e62c1c 100644 --- a/lectures/software_engineering/tools_editors.md +++ b/lectures/software_engineering/tools_editors.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (tools_editors)= diff --git a/lectures/software_engineering/version_control.md b/lectures/software_engineering/version_control.md index 270ee489..2dfc8788 100644 --- a/lectures/software_engineering/version_control.md +++ b/lectures/software_engineering/version_control.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (version_control)= diff --git a/lectures/status.md b/lectures/status.md index f1780a67..d87f405c 100644 --- a/lectures/status.md +++ b/lectures/status.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- # Execution Statistics diff --git a/lectures/time_series_models/additive_functionals.md b/lectures/time_series_models/additive_functionals.md index 5d4bde7c..9c54ed87 100644 --- a/lectures/time_series_models/additive_functionals.md +++ b/lectures/time_series_models/additive_functionals.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (additive_functionals)= @@ -206,11 +206,6 @@ All of these objects are computed using the code below. -```{code-cell} julia -using LinearAlgebra, Statistics -``` - - ```{code-cell} julia --- tags: [remove-cell] @@ -219,13 +214,12 @@ using Test, Random ``` ```{code-cell} julia -using Distributions, LaTeXStrings, Parameters, Plots, QuantEcon - +using Distributions, LaTeXStrings, Plots, QuantEcon +using LinearAlgebra, Statistics ``` ```{code-cell} julia -function AMF_LSS_VAR(A, B, D, F = nothing; ν = nothing) - +function AMF_LSS_VAR(A, B, D, F = nothing; upsilon = nothing) if B isa AbstractVector B = reshape(B, length(B), 1) end @@ -250,33 +244,31 @@ function AMF_LSS_VAR(A, B, D, F = nothing; ν = nothing) F = reshape(F, length(F), 1) end - # set ν - if isnothing(ν) - ν = zeros(nm, 1) - elseif ndims(ν) == 1 - ν = reshape(ν, length(ν), 1) + # set upsilon + if isnothing(upsilon) + upsilon = zeros(nm, 1) + elseif ndims(upsilon) == 1 + upsilon = reshape(upsilon, length(upsilon), 1) else - throw(ArgumentError("ν must be column vector!")) + throw(ArgumentError("upsilon must be column vector!")) end - if size(ν, 1) != size(D, 1) - error("The size of ν is inconsistent with D!") + if size(upsilon, 1) != size(D, 1) + error("The size of upsilon is inconsistent with D!") end # construct BIG state space representation - lss = construct_ss(A, B, D, F, ν, nx, nk, nm) + lss = construct_ss(A, B, D, F, upsilon, nx, nk, nm) - return (A = A, B = B, D = D, F = F, ν = ν, nx = nx, nk = nk, nm = nm, lss = lss) + return (; A, B, D, F, upsilon, nx, nk, nm, lss) end -AMF_LSS_VAR(A, B, D) = - AMF_LSS_VAR(A, B, D, nothing, ν=nothing) -AMF_LSS_VAR(A, B, D, F, ν) = - AMF_LSS_VAR(A, B, D, [F], ν=[ν]) - -function construct_ss(A, B, D, F, - ν, nx, nk, nm) +AMF_LSS_VAR(A, B, D) = AMF_LSS_VAR(A, B, D, nothing, upsilon = nothing) +function AMF_LSS_VAR(A, B, D, F, upsilon) + AMF_LSS_VAR(A, B, D, [F], upsilon = [upsilon]) +end +function construct_ss(A, B, D, F, upsilon, nx, nk, nm) H, g = additive_decomp(A, B, D, F, nx) # auxiliary blocks with 0's and 1's to fill out the lss matrices @@ -295,7 +287,7 @@ function construct_ss(A, B, D, F, A1 = hcat(1, 0, nx0r, ny0r, ny0r) # transition for 1 A2 = hcat(1, 1, nx0r, ny0r, ny0r) # transition for t A3 = hcat(nx0c, nx0c, A, nyx0m', nyx0m') # transition for x_{t+1} - A4 = hcat(ν, ny0c, D, ny1m, ny0m) # transition for y_{t+1} + A4 = hcat(upsilon, ny0c, D, ny1m, ny0m) # transition for y_{t+1} A5 = hcat(ny0c, ny0c, nyx0m, ny0m, ny1m) # transition for m_{t+1} Abar = vcat(A1, A2, A3, A4, A5) @@ -308,13 +300,13 @@ function construct_ss(A, B, D, F, G2 = hcat(ny0c, ny0c, nyx0m, ny1m, ny0m) # selector for y_{t} G3 = hcat(ny0c, ny0c, nyx0m, ny0m, ny1m) # selector for martingale G4 = hcat(ny0c, ny0c, -g, ny0m, ny0m) # selector for stationary - G5 = hcat(ny0c, ν, nyx0m, ny0m, ny0m) # selector for trend + G5 = hcat(ny0c, upsilon, nyx0m, ny0m, ny0m) # selector for trend Gbar = vcat(G1, G2, G3, G4, G5) # build LSS type x0 = hcat(1, 0, nx0r, ny0r, ny0r) S0 = zeros(length(x0), length(x0)) - lss = LSS(Abar, Bbar, Gbar, zeros(nx+4nm, 1), x0, S0) + lss = LSS(Abar, Bbar, Gbar, zeros(nx + 4nm, 1), x0, S0) return lss end @@ -327,22 +319,22 @@ function additive_decomp(A, B, D, F, nx) return H, g end -function multiplicative_decomp(A, B, D, F, ν, nx) +function multiplicative_decomp(A, B, D, F, upsilon, nx) H, g = additive_decomp(A, B, D, F, nx) - ν_tilde = ν .+ 0.5 * diag(H * H') + upsilon_tilde = upsilon .+ 0.5 * diag(H * H') - return H, g, ν_tilde + return H, g, upsilon_tilde end function loglikelihood_path(amf, x, y) - @unpack A, B, D, F = amf + (; A, B, D, F) = amf k, T = size(y) FF = F * F' FFinv = inv(FF) - temp = y[:, 2:end]-y[:, 1:end-1] - D*x[:, 1:end-1] - obs = temp .* FFinv .* temp + temp = y[:, 2:end] - y[:, 1:(end - 1)] - D * x[:, 1:(end - 1)] + obs = temp .* FFinv .* temp obssum = cumsum(obs) - scalar = (logdet(FF) + k * log(2π)) * (1:T) + scalar = (logdet(FF) + k * log(2pi)) * (1:T) return -(obssum + scalar) / 2 end @@ -354,17 +346,16 @@ function loglikelihood(amf, x, y) end function plot_additive(amf, T; npaths = 25, show_trend = true) - # pull out right sizes so we know how to increment - @unpack nx, nk, nm = amf + (; nx, nk, nm) = amf # allocate space (nm is the number of additive functionals - we want npaths for each) - mpath = zeros(nm*npaths, T) + mpath = zeros(nm * npaths, T) mbounds = zeros(2nm, T) - spath = zeros(nm*npaths, T) + spath = zeros(nm * npaths, T) sbounds = zeros(2nm, T) - tpath = zeros(nm*npaths, T) - ypath = zeros(nm*npaths, T) + tpath = zeros(nm * npaths, T) + ypath = zeros(nm * npaths, T) # simulate for as long as we wanted moment_generator = moment_sequence(amf.lss) @@ -378,7 +369,8 @@ function plot_additive(amf, T; npaths = 25, show_trend = true) for ii in 1:nm li, ui = 2(ii - 1) + 1, 2ii if sqrt(yvar[nx + nm + ii, nx + nm + ii]) != 0.0 - madd_dist = Normal(ymeans[nx + nm + ii], sqrt(yvar[nx + nm + ii, nx + nm + ii])) + madd_dist = Normal(ymeans[nx + nm + ii], + sqrt(yvar[nx + nm + ii, nx + nm + ii])) mbounds[li, t] = quantile(madd_dist, 0.01) mbounds[ui, t] = quantile(madd_dist, 0.99) elseif sqrt(yvar[nx + nm + ii, nx + nm + ii]) == 0.0 @@ -389,7 +381,8 @@ function plot_additive(amf, T; npaths = 25, show_trend = true) end if sqrt(yvar[nx + 2nm + ii, nx + 2nm + ii]) != 0.0 - sadd_dist = Normal(ymeans[nx + 2nm + ii], sqrt(yvar[nx + 2nm + ii, nx + 2nm + ii])) + sadd_dist = Normal(ymeans[nx + 2nm + ii], + sqrt(yvar[nx + 2nm + ii, nx + 2nm + ii])) sbounds[li, t] = quantile(sadd_dist, 0.01) sbounds[ui, t] = quantile(sadd_dist, 0.99) elseif sqrt(yvar[nx + 2nm + ii, nx + 2nm + ii]) == 0.0 @@ -404,8 +397,8 @@ function plot_additive(amf, T; npaths = 25, show_trend = true) # pull out paths for n in 1:npaths - x, y = simulate(amf.lss,T) - for ii in 0:nm - 1 + x, y = simulate(amf.lss, T) + for ii in 0:(nm - 1) ypath[npaths * ii + n, :] = y[nx + ii + 1, :] mpath[npaths * ii + n, :] = y[nx + nm + ii + 1, :] spath[npaths * ii + n, :] = y[nx + 2nm + ii + 1, :] @@ -415,22 +408,24 @@ function plot_additive(amf, T; npaths = 25, show_trend = true) add_figs = [] - for ii in 0:nm-1 - li, ui = npaths*(ii), npaths*(ii + 1) + for ii in 0:(nm - 1) + li, ui = npaths * (ii), npaths * (ii + 1) LI, UI = 2ii, 2(ii + 1) push!(add_figs, - plot_given_paths(T, ypath[li + 1:ui, :], mpath[li + 1:ui, :], spath[li + 1:ui, :], - tpath[li + 1:ui, :], mbounds[LI + 1:UI, :], sbounds[LI + 1:UI, :], - show_trend = show_trend)) + plot_given_paths(T, ypath[(li + 1):ui, :], mpath[(li + 1):ui, :], + spath[(li + 1):ui, :], + tpath[(li + 1):ui, :], mbounds[(LI + 1):UI, :], + sbounds[(LI + 1):UI, :], + show_trend = show_trend)) end return add_figs end function plot_multiplicative(amf, T, npaths = 25, show_trend = true) # pull out right sizes so we know how to increment - @unpack nx, nk, nm = amf + (; nx, nk, nm) = amf # matrices for the multiplicative decomposition - H, g, ν_tilde = multiplicative_decomp(A, B, D, F, ν, nx) + H, g, upsilon_tilde = multiplicative_decomp(A, B, D, F, upsilon, nx) # allocate space (nm is the number of functionals - we want npaths for each) mpath_mult = zeros(nm * npaths, T) @@ -450,21 +445,24 @@ function plot_multiplicative(amf, T, npaths = 25, show_trend = true) # lower and upper bounds - for each multiplicative functional for ii in 1:nm - li, ui = 2(ii - 1)+1, 2ii + li, ui = 2(ii - 1) + 1, 2ii if yvar[nx + nm + ii, nx + nm + ii] != 0.0 - Mdist = LogNormal(ymeans[nx + nm + ii]- 0.5t * diag(H * H')[ii], - sqrt(yvar[nx + nm + ii, nx + nm + ii])) + Mdist = LogNormal(ymeans[nx + nm + ii] - + 0.5t * diag(H * H')[ii], + sqrt(yvar[nx + nm + ii, nx + nm + ii])) mbounds_mult[li, t] = quantile(Mdist, 0.01) mbounds_mult[ui, t] = quantile(Mdist, 0.99) elseif yvar[nx + nm + ii, nx + nm + ii] == 0.0 - mbounds_mult[li, t] = exp.(ymeans[nx + nm + ii] - 0.5t * diag(H * H')[ii]) - mbounds_mult[ui, t] = exp.(ymeans[nx + nm + ii] - 0.5t * diag(H * H')[ii]) + mbounds_mult[li, t] = exp.(ymeans[nx + nm + ii] - + 0.5t * diag(H * H')[ii]) + mbounds_mult[ui, t] = exp.(ymeans[nx + nm + ii] - + 0.5t * diag(H * H')[ii]) else error("standard error is negative") end if yvar[nx + 2nm + ii, nx + 2nm + ii] != 0.0 Sdist = LogNormal(-ymeans[nx + 2nm + ii], - sqrt(yvar[nx + 2nm + ii, nx + 2nm + ii])) + sqrt(yvar[nx + 2nm + ii, nx + 2nm + ii])) sbounds_mult[li, t] = quantile(Sdist, 0.01) sbounds_mult[ui, t] = quantile(Sdist, 0.99) elseif yvar[nx + 2nm + ii, nx + 2nm + ii] == 0.0 @@ -479,38 +477,43 @@ function plot_multiplicative(amf, T, npaths = 25, show_trend = true) # pull out paths for n in 1:npaths - x, y = simulate(amf.lss,T) - for ii in 0:nm-1 - ypath_mult[npaths * ii + n, :] = exp.(y[nx+ii+1, :]) - mpath_mult[npaths * ii + n, :] = - exp.(y[nx+nm + ii+1, :] - collect(1:T)*0.5*diag(H * H')[ii+1]) - spath_mult[npaths * ii + n, :] = 1 ./exp.(-y[nx+2*nm + ii+1, :]) - tpath_mult[npaths * ii + n, :] = - exp.(y[nx + 3nm + ii+1, :] + (1:T) * 0.5 * diag(H * H')[ii + 1]) + x, y = simulate(amf.lss, T) + for ii in 0:(nm - 1) + ypath_mult[npaths * ii + n, :] = exp.(y[nx + ii + 1, :]) + mpath_mult[npaths * ii + n, :] = exp.(y[nx + nm + ii + 1, :] - + collect(1:T) * 0.5 * + diag(H * H')[ii + 1]) + spath_mult[npaths * ii + n, :] = 1 ./ + exp.(-y[nx + 2 * nm + ii + 1, :]) + tpath_mult[npaths * ii + n, :] = exp.(y[nx + 3nm + ii + 1, :] + + (1:T) * 0.5 * + diag(H * H')[ii + 1]) end end mult_figs = [] - for ii in 0:nm-1 + for ii in 0:(nm - 1) li, ui = npaths * ii, npaths * (ii + 1) LI, UI = 2ii, 2(ii + 1) push!(mult_figs, - plot_given_paths(T, ypath_mult[li+1:ui, :], mpath_mult[li+1:ui, :], - spath_mult[li+1:ui, :], tpath_mult[li+1:ui, :], - mbounds_mult[LI+1:UI, :], sbounds_mult[LI+1:UI, :], - horline = 1.0, show_trend=show_trend)) + plot_given_paths(T, ypath_mult[(li + 1):ui, :], + mpath_mult[(li + 1):ui, :], + spath_mult[(li + 1):ui, :], + tpath_mult[(li + 1):ui, :], + mbounds_mult[(LI + 1):UI, :], + sbounds_mult[(LI + 1):UI, :], + horline = 1.0, show_trend = show_trend)) end return mult_figs end function plot_martingales(amf, T, npaths = 25) - # pull out right sizes so we know how to increment - @unpack A, B, D, F, ν, nx, nk, nm = amf + (; A, B, D, F, upsilon, nx, nk, nm) = amf # matrices for the multiplicative decomposition - H, g, ν_tilde = multiplicative_decomp(A, B, D, F, ν, nx) + H, g, upsilon_tilde = multiplicative_decomp(A, B, D, F, upsilon, nx) # allocate space (nm is the number of functionals - we want npaths for each) mpath_mult = zeros(nm * npaths, T) @@ -527,13 +530,16 @@ function plot_martingales(amf, T, npaths = 25) for ii in 1:nm li, ui = 2(ii - 1) + 1, 2ii if yvar[nx + nm + ii, nx + nm + ii] != 0.0 - Mdist = LogNormal(ymeans[nx + nm + ii] - 0.5^2 * t * diag(H * H')[ii], - sqrt(yvar[nx + nm + ii, nx + nm + ii])) + Mdist = LogNormal(ymeans[nx + nm + ii] - + 0.5^2 * t * diag(H * H')[ii], + sqrt(yvar[nx + nm + ii, nx + nm + ii])) mbounds_mult[li, t] = quantile(Mdist, 0.01) mbounds_mult[ui, t] = quantile(Mdist, 0.99) elseif yvar[nx + nm + ii, nx + nm + ii] == 0.0 - mbounds_mult[li, t] = ymeans[nx + nm + ii] - 0.5^2 * t * diag(H * H')[ii] - mbounds_mult[ui, t] = ymeans[nx + nm + ii]- 0.5t * diag(H * H')[ii] + mbounds_mult[li, t] = ymeans[nx + nm + ii] - + 0.5^2 * t * diag(H * H')[ii] + mbounds_mult[ui, t] = ymeans[nx + nm + ii] - + 0.5t * diag(H * H')[ii] else error("standard error is negative") end @@ -544,21 +550,23 @@ function plot_martingales(amf, T, npaths = 25) # pull out paths for n in 1:npaths x, y = simulate(amf.lss, T) - for ii in 0:nm-1 - mpath_mult[npaths * ii + n, :] = - exp.(y[nx+nm + ii+1, :] - (1:T) * 0.5 * diag(H * H')[ii+1]) + for ii in 0:(nm - 1) + mpath_mult[npaths * ii + n, :] = exp.(y[nx + nm + ii + 1, :] - + (1:T) * 0.5 * + diag(H * H')[ii + 1]) end end mart_figs = [] - for ii in 0:nm-1 - li, ui = npaths*(ii), npaths*(ii + 1) + for ii in 0:(nm - 1) + li, ui = npaths * (ii), npaths * (ii + 1) LI, UI = 2ii, 2(ii + 1) push!(mart_figs, - plot_martingale_paths(T, mpath_mult[li + 1:ui, :], - mbounds_mult[LI + 1:UI, :], horline = 1)) - plot!(mart_figs[ii + 1], title = L"Martingale components for many paths of $y_{ii + 1}$") + plot_martingale_paths(T, mpath_mult[(li + 1):ui, :], + mbounds_mult[(LI + 1):UI, :], horline = 1)) + plot!(mart_figs[ii + 1], + title = L"Martingale components for many paths of $y_{ii + 1}$") end return mart_figs @@ -571,10 +579,10 @@ function plot_given_paths(T, ypath, mpath, spath, tpath, mbounds, sbounds; trange = 1:T # allocate transpose - mpathᵀ = Matrix(mpath') + mpath_T = Matrix(mpath') # create figure - plots=plot(layout = (2, 2), size = (800, 800)) + plots = plot(layout = (2, 2), size = (800, 800)) # plot all paths together @@ -584,16 +592,19 @@ function plot_given_paths(T, ypath, mpath, spath, tpath, mbounds, sbounds; if show_trend plot!(plots[1], trange, tpath[1, :], label = L"t_t", color = :red) end - plot!(plots[1], seriestype = :hline, [horline], color = :black, linestyle=:dash, label = "") - plot!(plots[1], title = "One Path of All Variables", legend=:topleft) + plot!(plots[1], seriestype = :hline, [horline], color = :black, + linestyle = :dash, label = "") + plot!(plots[1], title = "One Path of All Variables", legend = :topleft) # plot martingale component plot!(plots[2], trange, mpath[1, :], color = :magenta, label = "") - plot!(plots[2], trange, mpathᵀ, alpha = 0.45, color = :magenta, label = "") + plot!(plots[2], trange, mpath_T, alpha = 0.45, color = :magenta, label = "") ub = mbounds[2, :] lb = mbounds[1, :] - plot!(plots[2], ub, fillrange = lb, alpha = 0.25, color = :magenta, label = "") - plot!(plots[2], seriestype = :hline, [horline], color = :black, linestyle =:dash, label = "") + plot!(plots[2], ub, fillrange = lb, alpha = 0.25, color = :magenta, + label = "") + plot!(plots[2], seriestype = :hline, [horline], color = :black, + linestyle = :dash, label = "") plot!(plots[2], title = "Martingale Components for Many Paths") # plot stationary component @@ -601,15 +612,18 @@ function plot_given_paths(T, ypath, mpath, spath, tpath, mbounds, sbounds; plot!(plots[3], Matrix(spath'), alpha = 0.25, color = :green, label = "") ub = sbounds[2, :] lb = sbounds[1, :] - plot!(plots[3], ub, fillrange = lb, alpha = 0.25, color = :green, label = "") - plot!(plots[3], seriestype = :hline, [horline], color = :black, linestyle=:dash, label = "") + plot!(plots[3], ub, fillrange = lb, alpha = 0.25, color = :green, + label = "") + plot!(plots[3], seriestype = :hline, [horline], color = :black, + linestyle = :dash, label = "") plot!(plots[3], title = "Stationary Components for Many Paths") # plot trend component if show_trend == true plot!(plots[4], Matrix(tpath'), color = :red, label = "") end - plot!(plots[4], seriestype = :hline, [horline], color = :black, linestyle =:dash, label = "") + plot!(plots[4], seriestype = :hline, [horline], color = :black, + linestyle = :dash, label = "") plot!(plots[4], title = "Trend Components for Many Paths") return plots @@ -627,8 +641,10 @@ function plot_martingale_paths(T, mpath, mbounds; ub = mbounds[2, :] lb = mbounds[1, :] #plot!(plt, lb, fillrange = ub, alpha = 0.25, color = :magenta, label = "") - plot!(plt, seriestype = :hline, [horline], color = :black, linestyle =:dash, label = "") - plot!(plt, trange, Matrix(mpath'), linewidth=0.25, color = :black, label = "") + plot!(plt, seriestype = :hline, [horline], color = :black, + linestyle = :dash, label = "") + plot!(plt, trange, Matrix(mpath'), linewidth = 0.25, color = :black, + label = "") return plt end @@ -645,40 +661,40 @@ Random.seed!(42); ``` ```{code-cell} julia -ϕ_1, ϕ_2, ϕ_3, ϕ_4 = 0.5, -0.2, 0, 0.5 -σ = 0.01 -ν = 0.01 # growth rate +phi_1, phi_2, phi_3, phi_4 = 0.5, -0.2, 0, 0.5 +sigma = 0.01 +upsilon = 0.01 # growth rate ## A matrix should be n x n -A = [ϕ_1 ϕ_2 ϕ_3 ϕ_4; - 1 0 0 0; - 0 1 0 0; - 0 0 1 0] +A = [phi_1 phi_2 phi_3 phi_4; + 1 0 0 0; + 0 1 0 0; + 0 0 1 0] # B matrix should be n x k -B = [σ, 0, 0, 0] +B = [sigma, 0, 0, 0] D = [1 0 0 0] * A F = [1, 0, 0, 0] ⋅ vec(B) -amf = AMF_LSS_VAR(A, B, D, F, ν) +amf = AMF_LSS_VAR(A, B, D, F, upsilon) T = 150 x, y = simulate(amf.lss, T) -plt_1=plot() -plt_2=plot() +plt_1 = plot() +plt_2 = plot() plots = [plt_1, plt_2] # plots = plot(layout = (2, 1)) plot!(plots[1], 1:T, y[amf.nx + 1, :], color = :black, lw = 2, label = "") -plot!(plots[1], title = L"A particular path of $y_t$") +plot!(plots[1], title = L"A particular path of $y_t$") plot!(plots[2], 1:T, y[1, :], color = :green, lw = 2, label = "") -plot!(plots[2], seriestype = :hline, [0], color = :black, lw = 2, linestyle=:dashdot, - label = "") +plot!(plots[2], seriestype = :hline, [0], color = :black, lw = 2, + linestyle = :dashdot, label = "") plot!(plots[2], title = L"Associated path of $x_t$") # plot(plots) -plot(plots[1], plots[2], layout=(2,1), size=(700,500)) +plot(plots[1], plots[2], layout = (2, 1), size = (700, 500)) ``` ```{code-cell} julia diff --git a/lectures/time_series_models/arma.md b/lectures/time_series_models/arma.md index 2edcefb7..8f2bde8f 100644 --- a/lectures/time_series_models/arma.md +++ b/lectures/time_series_models/arma.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (arma)= @@ -80,12 +80,6 @@ For supplementary reading, see. * {cite}`CryerChan2008`, all ``` - - -```{code-cell} julia -using LinearAlgebra, Statistics -``` - ## Introduction Consider a sequence of random variables $\{ X_t \}$ indexed by $t \in \mathbb Z$ and taking values in $\mathbb R$. @@ -231,22 +225,24 @@ using Test ```{code-cell} julia using LaTeXStrings, Plots +using LinearAlgebra, Statistics - -plt_1=plot() -plt_2=plot() +plt_1 = plot() +plt_2 = plot() plots = [plt_1, plt_2] -for (i, ϕ) in enumerate((0.8, -0.8)) +for (i, phi) in enumerate((0.8, -0.8)) times = 0:16 - acov = [ϕ.^k ./ (1 - ϕ.^2) for k in times] - label = L"autocovariance, $\phi = %$ϕ$" - plot!(plots[i], times, acov, color=:blue, lw=2, marker=:circle, markersize=3, - alpha=0.6, label=label) - plot!(plots[i], legend=:topright, xlabel="time", xlim=(0,15)) - plot!(plots[i], seriestype=:hline, [0], linestyle=:dash, alpha=0.5, lw=2, label="") + acov = [phi .^ k ./ (1 - phi .^ 2) for k in times] + label = L"autocovariance, $\phi = %$phi$" + plot!(plots[i], times, acov, color = :blue, lw = 2, marker = :circle, + markersize = 3, + alpha = 0.6, label = label) + plot!(plots[i], legend = :topright, xlabel = "time", xlim = (0, 15)) + plot!(plots[i], seriestype = :hline, [0], linestyle = :dash, alpha = 0.5, + lw = 2, label = "") end -plot(plots[1], plots[2], layout=(2,1), size=(700,500)) +plot(plots[1], plots[2], layout = (2, 1), size = (700, 500)) ``` ```{code-cell} julia @@ -254,9 +250,9 @@ plot(plots[1], plots[2], layout=(2,1), size=(700,500)) tags: [remove-cell] --- @testset begin - ϕ = 0.8 + phi = 0.8 times = 0:16 - acov = [ϕ.^k ./ (1 - ϕ.^2) for k in times] + acov = [phi.^k ./ (1 - phi.^2) for k in times] @test acov[4] ≈ 1.422222222222223 # Can't access acov directly because of scoping. @test acov[1] ≈ 2.7777777777777786 end @@ -480,21 +476,22 @@ It is a nice exercise to verify that {eq}`ma1_sd_ed` and {eq}`ar1_sd_ed` are ind Plotting {eq}`ar1_sd_ed` reveals the shape of the spectral density for the AR(1) model when $\phi$ takes the values 0.8 and -0.8 respectively ```{code-cell} julia -ar1_sd(ϕ, ω) = 1 ./ (1 .- 2 * ϕ * cos.(ω) .+ ϕ.^2) +ar1_sd(phi, omega) = 1 ./ (1 .- 2 * phi * cos.(omega) .+ phi .^ 2) -ω_s = range(0, π, length = 180) +omega_s = range(0, pi, length = 180) -plt_1=plot() -plt_2=plot() -plots=[plt_1, plt_2] +plt_1 = plot() +plt_2 = plot() +plots = [plt_1, plt_2] -for (i, ϕ) in enumerate((0.8, -0.8)) - sd = ar1_sd(ϕ, ω_s) - label = L"spectral density, $\phi = %$ϕ$" - plot!(plots[i], ω_s, sd, color=:blue, alpha=0.6, lw=2, label=label) - plot!(plots[i], legend=:top, xlabel="frequency", xlim=(0,π)) +for (i, phi) in enumerate((0.8, -0.8)) + sd = ar1_sd(phi, omega_s) + label = L"spectral density, $\phi = %$phi$" + plot!(plots[i], omega_s, sd, color = :blue, alpha = 0.6, lw = 2, + label = label) + plot!(plots[i], legend = :top, xlabel = "frequency", xlim = (0, pi)) end -plot(plots[1], plots[2], layout=(2,1), size=(700,500)) +plot(plots[1], plots[2], layout = (2, 1), size = (700, 500)) ``` ```{code-cell} julia @@ -502,9 +499,9 @@ plot(plots[1], plots[2], layout=(2,1), size=(700,500)) tags: [remove-cell] --- @testset begin - @test ar1_sd(0.8, ω_s)[18] ≈ 9.034248169239635 - @test ar1_sd(-0.8, ω_s)[18] ≈ 0.3155260821833043 - @test ω_s[1] == 0.0 && ω_s[end] ≈ π && length(ω_s) == 180 # Grid invariant. + @test ar1_sd(0.8, omega_s)[18] ≈ 9.034248169239635 + @test ar1_sd(-0.8, omega_s)[18] ≈ 0.3155260821833043 + @test omega_s[1] == 0.0 && omega_s[end] ≈ pi && length(omega_s) == 180 # Grid invariant. end ``` @@ -536,34 +533,35 @@ products on the right-hand side of {eq}`sumpr` is large. These ideas are illustrated in the next figure, which has $k$ on the horizontal axis ```{code-cell} julia -ϕ = -0.8 +phi = -0.8 times = 0:16 -y1 = [ϕ.^k ./ (1 - ϕ.^2) for k in times] -y2 = [cos.(π * k) for k in times] +y1 = [phi .^ k ./ (1 - phi .^ 2) for k in times] +y2 = [cos.(pi * k) for k in times] y3 = [a * b for (a, b) in zip(y1, y2)] -# Autocovariance when ϕ = -0.8 -plt_1 = plot(times, y1, color=:blue, lw=2, marker=:circle, markersize=3, - alpha=0.6, label=L"\gamma(k)") -plot!(plt_1, seriestype=:hline, [0], linestyle=:dash, alpha=0.5, - lw=2, label="") -plot!(plt_1, legend=:topright, xlim=(0,15), yticks=[-2, 0, 2]) +# Autocovariance when phi = -0.8 +plt_1 = plot(times, y1, color = :blue, lw = 2, marker = :circle, markersize = 3, + alpha = 0.6, label = L"\gamma(k)") +plot!(plt_1, seriestype = :hline, [0], linestyle = :dash, alpha = 0.5, + lw = 2, label = "") +plot!(plt_1, legend = :topright, xlim = (0, 15), yticks = [-2, 0, 2]) -# Cycles at frequence π -plt_2 = plot(times, y2, color=:blue, lw=2, marker=:circle, markersize=3, - alpha=0.6, label=L"cos(\pi k)") -plot!(plt_2, seriestype=:hline, [0], linestyle=:dash, alpha=0.5, - lw=2, label="") -plot!(plt_2, legend=:topright, xlim=(0,15), yticks=[-1, 0, 1]) +# Cycles at frequence pi +plt_2 = plot(times, y2, color = :blue, lw = 2, marker = :circle, markersize = 3, + alpha = 0.6, label = L"cos(\pi k)") +plot!(plt_2, seriestype = :hline, [0], linestyle = :dash, alpha = 0.5, + lw = 2, label = "") +plot!(plt_2, legend = :topright, xlim = (0, 15), yticks = [-1, 0, 1]) # Product -plt_3 = plot(times, y3, seriestype=:sticks, marker=:circle, markersize=3, - lw=2, label=L"\gamma(k) cos(\pi k)") -plot!(plt_3, seriestype=:hline, [0], linestyle=:dash, alpha=0.5, - lw=2, label="") -plot!(plt_3, legend=:topright, xlim=(0,15), ylim=(-3,3), yticks=[-1, 0, 1, 2, 3]) +plt_3 = plot(times, y3, seriestype = :sticks, marker = :circle, markersize = 3, + lw = 2, label = L"\gamma(k) cos(\pi k)") +plot!(plt_3, seriestype = :hline, [0], linestyle = :dash, alpha = 0.5, + lw = 2, label = "") +plot!(plt_3, legend = :topright, xlim = (0, 15), ylim = (-3, 3), + yticks = [-1, 0, 1, 2, 3]) -plot(plt_1, plt_2, plt_3, layout=(3,1), size=(800,600)) +plot(plt_1, plt_2, plt_3, layout = (3, 1), size = (800, 600)) ``` ```{code-cell} julia @@ -583,34 +581,35 @@ not matched, the sequence $\gamma(k) \cos(\omega k)$ contains both positive and negative terms, and hence the sum of these terms is much smaller ```{code-cell} julia -ϕ = -0.8 +phi = -0.8 times = 0:16 -y1 = [ϕ.^k ./ (1 - ϕ.^2) for k in times] -y2 = [cos.(π * k/3) for k in times] +y1 = [phi .^ k ./ (1 - phi .^ 2) for k in times] +y2 = [cos.(pi * k / 3) for k in times] y3 = [a * b for (a, b) in zip(y1, y2)] -# Autocovariance when ϕ = -0.8 -plt_1 = plot(times, y1, color=:blue, lw=2, marker=:circle, markersize=3, - alpha=0.6, label=L"\gamma(k)") -plot!(plt_1, seriestype=:hline, [0], linestyle=:dash, alpha=0.5, - lw=2, label="") -plot!(plt_1, legend=:topright, xlim=(0,15), yticks=[-2, 0, 2]) +# Autocovariance when phi = -0.8 +plt_1 = plot(times, y1, color = :blue, lw = 2, marker = :circle, markersize = 3, + alpha = 0.6, label = L"\gamma(k)") +plot!(plt_1, seriestype = :hline, [0], linestyle = :dash, alpha = 0.5, + lw = 2, label = "") +plot!(plt_1, legend = :topright, xlim = (0, 15), yticks = [-2, 0, 2]) -# Cycles at frequence π -plt_2 = plot(times, y2, color=:blue, lw=2, marker=:circle, markersize=3, - alpha=0.6, label=L"cos(\pi k/3)") -plot!(plt_2, seriestype=:hline, [0], linestyle=:dash, alpha=0.5, - lw=2, label="") -plot!(plt_2, legend=:topright, xlim=(0,15), yticks=[-1, 0, 1]) +# Cycles at frequence pi +plt_2 = plot(times, y2, color = :blue, lw = 2, marker = :circle, markersize = 3, + alpha = 0.6, label = L"cos(\pi k/3)") +plot!(plt_2, seriestype = :hline, [0], linestyle = :dash, alpha = 0.5, + lw = 2, label = "") +plot!(plt_2, legend = :topright, xlim = (0, 15), yticks = [-1, 0, 1]) # Product -plt_3 = plot(times, y3, seriestype=:sticks, marker=:circle, markersize=3, - lw=2, label=L"\gamma(k) cos(\pi k/3)") -plot!(plt_3, seriestype=:hline, [0], linestyle=:dash, alpha=0.5, - lw=2, label="") -plot!(plt_3, legend=:topright, xlim=(0,15), ylim=(-3,3), yticks=[-1, 0, 1, 2, 3]) +plt_3 = plot(times, y3, seriestype = :sticks, marker = :circle, markersize = 3, + lw = 2, label = L"\gamma(k) cos(\pi k/3)") +plot!(plt_3, seriestype = :hline, [0], linestyle = :dash, alpha = 0.5, + lw = 2, label = "") +plot!(plt_3, legend = :topright, xlim = (0, 15), ylim = (-3, 3), + yticks = [-1, 0, 1, 2, 3]) -plot(plt_1, plt_2, plt_3, layout=(3,1), size=(600,600)) +plot(plt_1, plt_2, plt_3, layout = (3, 1), size = (600, 600)) ``` ```{code-cell} julia @@ -753,64 +752,65 @@ using QuantEcon, Random # plot functions function plot_spectral_density(arma, plt) - (w, spect) = spectral_density(arma, two_pi=false) - plot!(plt, w, spect, lw=2, alpha=0.7,label="") - plot!(plt, title="Spectral density", xlim=(0,π), - xlabel="frequency", ylabel="spectrum", yscale=:log) + (w, spect) = spectral_density(arma, two_pi = false) + plot!(plt, w, spect, lw = 2, alpha = 0.7, label = "") + plot!(plt, title = "Spectral density", xlim = (0, pi), + xlabel = "frequency", ylabel = "spectrum", yscale = :log) return plt end function plot_spectral_density(arma) plt = plot() - plot_spectral_density(arma, plt=plt) + plot_spectral_density(arma, plt = plt) return plt end function plot_autocovariance(arma, plt) acov = autocovariance(arma) n = length(acov) - plot!(plt, 0:(n-1), acov, seriestype=:sticks, marker=:circle, - markersize=2,label="") - plot!(plt, seriestype=:hline, [0], color=:red, label="") - plot!(plt, title="Autocovariance", xlim=(-0.5, n-0.5), - xlabel="time", ylabel="autocovariance") + plot!(plt, 0:(n - 1), acov, seriestype = :sticks, marker = :circle, + markersize = 2, label = "") + plot!(plt, seriestype = :hline, [0], color = :red, label = "") + plot!(plt, title = "Autocovariance", xlim = (-0.5, n - 0.5), + xlabel = "time", ylabel = "autocovariance") return plt end function plot_autocovariance(arma) plt = plot() - plot_spectral_density(arma, plt=plt) + plot_spectral_density(arma, plt = plt) return plt end function plot_impulse_response(arma, plt) psi = impulse_response(arma) n = length(psi) - plot!(plt, 0:(n-1), psi, seriestype=:sticks, marker=:circle, - markersize=2, label="") - plot!(plt, seriestype=:hline, [0], color=:red, label="") - plot!(plt, title="Impluse response", xlim=(-0.5,n-0.5), - xlabel="time", ylabel="response") + plot!(plt, 0:(n - 1), psi, seriestype = :sticks, marker = :circle, + markersize = 2, label = "") + plot!(plt, seriestype = :hline, [0], color = :red, label = "") + plot!(plt, title = "Impluse response", xlim = (-0.5, n - 0.5), + xlabel = "time", ylabel = "response") return plt end function plot_impulse_response(arma) plt = plot() - plot_spectral_density(arma, plt=plt) + plot_spectral_density(arma, plt = plt) return plt end function plot_simulation(arma, plt) X = simulation(arma) n = length(X) - plot!(plt, 0:(n-1), X, lw=2, alpha=0.7, label="") - plot!(plt, title="Sample path", xlim=(0,0,n), xlabel="time", ylabel="state space") + plot!(plt, 0:(n - 1), X, lw = 2, alpha = 0.7, label = "") + plot!(plt, title = "Sample path", xlim = (0, 0, n), xlabel = "time", + ylabel = "state space") return plt end function plot_simulation(arma) plt = plot() - plot_spectral_density(arma, plt=plt) + plot_spectral_density(arma, plt = plt) return plt end @@ -822,14 +822,14 @@ function quad_plot(arma) plots = [plt_1, plt_2, plt_3, plt_4] plot_functions = [plot_spectral_density, - plot_impulse_response, - plot_autocovariance, - plot_simulation] + plot_impulse_response, + plot_autocovariance, + plot_simulation] for (i, plt, plot_func) in zip(1:1:4, plots, plot_functions) plots[i] = plot_func(arma, plt) end - return plot(plots[1], plots[2], plots[3], plots[4], layout=(2,2), size=(800,800)) - + return plot(plots[1], plots[2], plots[3], plots[4], layout = (2, 2), + size = (800, 800)) end ``` @@ -839,9 +839,9 @@ We'll use the model $X_t = 0.5 X_{t-1} + \epsilon_t - 0.8 \epsilon_{t-2}$ ```{code-cell} julia Random.seed!(42) # For reproducible results. -ϕ = 0.5; -θ = [0, -0.8]; -arma = ARMA(ϕ, θ, 1.0) +phi = 0.5; +theta = [0, -0.8]; +arma = ARMA(phi, theta, 1.0) quad_plot(arma) ``` @@ -864,7 +864,7 @@ end The call ```{code-block} julia -arma = ARMA(ϕ, θ, σ) +arma = ARMA(phi, theta, sigma) ``` creates an instance `arma` that represents the ARMA($p, q$) model @@ -874,15 +874,15 @@ X_t = \phi_1 X_{t-1} + ... + \phi_p X_{t-p} + \epsilon_t + \theta_1 \epsilon_{t-1} + ... + \theta_q \epsilon_{t-q} $$ -If `ϕ` and `θ` are arrays or sequences, then the interpretation will +If `phi` and `theta` are arrays or sequences, then the interpretation will be -* `ϕ` holds the vector of parameters $(\phi_1, \phi_2,..., \phi_p)$ -* `θ` holds the vector of parameters $(\theta_1, \theta_2,..., \theta_q)$ +* `phi` holds the vector of parameters $(\phi_1, \phi_2,..., \phi_p)$ +* `theta` holds the vector of parameters $(\theta_1, \theta_2,..., \theta_q)$ -The parameter `σ` is always a scalar, the standard deviation of the white noise. +The parameter `sigma` is always a scalar, the standard deviation of the white noise. -We also permit `ϕ` and `θ` to be scalars, in which case the model will be interpreted as +We also permit `phi` and `theta` to be scalars, in which case the model will be interpreted as $$ X_t = \phi X_{t-1} + \epsilon_t + \theta \epsilon_{t-1} diff --git a/lectures/time_series_models/classical_filtering.md b/lectures/time_series_models/classical_filtering.md index 1666ab21..970ddfb2 100644 --- a/lectures/time_series_models/classical_filtering.md +++ b/lectures/time_series_models/classical_filtering.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (classical_filtering)= @@ -61,11 +61,6 @@ In this lecture we investigate these ideas using mostly elementary linear algebr Useful references include {cite}`Whittle1963`, {cite}`HanSar1980`, {cite}`Orfanidisoptimum1988`, {cite}`Athanasios1991`, and {cite}`Muth1960`. - -```{code-cell} julia -using LinearAlgebra, Statistics -``` - ## Infinite Horizon Prediction and Filtering Problems We pose two related prediction and filtering problems. @@ -587,57 +582,55 @@ using Test ``` ```{code-cell} julia +using LinearAlgebra, Statistics using Polynomials.PolyCompat, LinearAlgebra import Polynomials.PolyCompat: roots, coeffs function LQFilter(d, h, y_m; r = nothing, - β = nothing, + beta = nothing, h_eps = nothing) - m = length(d) - 1 m == length(y_m) || throw(ArgumentError("y_m and d must be of same length = $m")) - # define the coefficients of ϕ up front - ϕ = zeros(2m + 1) - for i in -m:m - ϕ[m-i+1] = sum(diag(d*d', -i)) + # define the coefficients of phi up front + phi = zeros(2m + 1) + for i in (-m):m + phi[m - i + 1] = sum(diag(d * d', -i)) end - ϕ[m+1] = ϕ[m+1] + h + phi[m + 1] = phi[m + 1] + h - # if r is given calculate the vector ϕ_r + # if r is given calculate the vector phi_r if isnothing(r) k = nothing - ϕ_r = nothing + phi_r = nothing else k = size(r, 1) - 1 - ϕ_r = zeros(2k + 1) + phi_r = zeros(2k + 1) - for i = -k:k - ϕ_r[k-i+1] = sum(diag(r*r', -i)) + for i in (-k):k + phi_r[k - i + 1] = sum(diag(r * r', -i)) end if isnothing(h_eps) == false - ϕ_r[k+1] = ϕ_r[k+1] + h_eps + phi_r[k + 1] = phi_r[k + 1] + h_eps end end - # if β is given, define the transformed variables - if isnothing(β) - β = 1.0 + # if beta is given, define the transformed variables + if isnothing(beta) + beta = 1.0 else - d = β.^(collect(0:m)/2) * d - y_m = y_m * β.^(- collect(1:m)/2) + d = beta .^ (collect(0:m) / 2) * d + y_m = y_m * beta .^ (-collect(1:m) / 2) end - return (d = d, h = h, y_m = y_m, m = m, ϕ = ϕ, β = β, - ϕ_r = ϕ_r, k = k) + return (; d, h, y_m, m, phi, beta, phi_r, k) end function construct_W_and_Wm(lqf, N) - - d, m = lqf.d, lqf.m + (; d, m) = lqf W = zeros(N + 1, N + 1) W_m = zeros(N + 1, m) @@ -648,9 +641,9 @@ function construct_W_and_Wm(lqf, N) # (1) constuct the D_{m+1} matrix using the formula - for j in 1:(m+1) - for k in j:(m+1) - D_m1[j, k] = dot(d[1:j, 1], d[k-j+1:k, 1]) + for j in 1:(m + 1) + for k in j:(m + 1) + D_m1[j, k] = dot(d[1:j, 1], d[(k - j + 1):k, 1]) end end @@ -661,63 +654,63 @@ function construct_W_and_Wm(lqf, N) for j in 1:m for i in (j + 1):(m + 1) - M[i, j] = D_m1[i-j, m+1] + M[i, j] = D_m1[i - j, m + 1] end end M # Euler equations for t = 0, 1, ..., N-(m+1) - ϕ, h = lqf.ϕ, lqf.h + phi, h = lqf.phi, lqf.h W[1:(m + 1), 1:(m + 1)] = D_m1 + h * I W[1:(m + 1), (m + 2):(2m + 1)] = M for (i, row) in enumerate((m + 2):(N + 1 - m)) - W[row, (i + 1):(2m + 1 + i)] = ϕ' + W[row, (i + 1):(2m + 1 + i)] = phi' end for i in 1:m - W[N - m + i + 1 , end-(2m + 1 - i)+1:end] = ϕ[1:end-i] + W[N - m + i + 1, (end - (2m + 1 - i) + 1):end] = phi[1:(end - i)] end for i in 1:m - W_m[N - i + 2, 1:(m - i)+1] = ϕ[(m + 1 + i):end] + W_m[N - i + 2, 1:((m - i) + 1)] = phi[(m + 1 + i):end] end return W, W_m end function roots_of_characteristic(lqf) - m, ϕ = lqf.m, lqf.ϕ + (; m, phi) = lqf # Calculate the roots of the 2m-polynomial - ϕ_poly = Poly(ϕ[end:-1:1]) - proots = roots(ϕ_poly) + phi_poly = Poly(phi[end:-1:1]) + proots = roots(phi_poly) # sort the roots according to their length (in descending order) - roots_sorted = sort(proots, by=abs)[end:-1:1] - z_0 = sum(ϕ) / polyval(poly(proots), 1.0) + roots_sorted = sort(proots, by = abs)[end:-1:1] + z_0 = sum(phi) / polyval(poly(proots), 1.0) z_1_to_m = roots_sorted[1:m] # we need only those outside the unit circle - λ = 1 ./ z_1_to_m - return z_1_to_m, z_0, λ + lambda = 1 ./ z_1_to_m + return z_1_to_m, z_0, lambda end function coeffs_of_c(lqf) - m = lqf.m - z_1_to_m, z_0, λ = roots_of_characteristic(lqf) + (; m) = lqf + z_1_to_m, z_0, lambda = roots_of_characteristic(lqf) c_0 = (z_0 * prod(z_1_to_m) * (-1.0)^m)^(0.5) c_coeffs = coeffs(poly(z_1_to_m)) * z_0 / c_0 return c_coeffs end function solution(lqf) - z_1_to_m, z_0, λ = roots_of_characteristic(lqf) + z_1_to_m, z_0, lambda = roots_of_characteristic(lqf) c_0 = coeffs_of_c(lqf)[end] - A = zeros(lqf.m) + A = zeros(m) for j in 1:m - denom = 1 - λ/λ[j] + denom = 1 - lambda / lambda[j] A[j] = c_0^(-2) / prod(denom[1:m .!= j]) end - return λ, A + return lambda, A end function construct_V(lqf; N = nothing) @@ -728,12 +721,12 @@ function construct_V(lqf; N = nothing) throw(ArgumentError("N must be Integer!")) end - ϕ_r, k = lqf.ϕ_r, lqf.k + (; phi_r, k) = lqf V = zeros(N, N) for i in 1:N for j in 1:N - if abs(i-j) ≤ k - V[i, j] = ϕ_r[k + abs(i-j)+1] + if abs(i - j) <= k + V[i, j] = phi_r[k + abs(i - j) + 1] end end end @@ -751,7 +744,7 @@ function predict(lqf, a_hist, t) V = construct_V(N + 1) aux_matrix = zeros(N + 1, N + 1) - aux_matrix[1:t+1 , 1:t+1 ] = Matrix(I, t + 1, t + 1) + aux_matrix[1:(t + 1), 1:(t + 1)] = Matrix(I, t + 1, t + 1) L = cholesky(V).U' Ea_hist = inv(L) * aux_matrix * L * a_hist @@ -759,7 +752,7 @@ function predict(lqf, a_hist, t) end function optimal_y(lqf, a_hist, t = nothing) - β, y_m, m = lqf.β, lqf.y_m, lqf.m + (; beta, y_m, m) = lqf N = length(a_hist) - 1 W, W_m = construct_W_and_Wm(lqf, N) @@ -776,35 +769,35 @@ function optimal_y(lqf, a_hist, t = nothing) if isnothing(t) # if the problem is deterministic a_hist = J * a_hist - # transform the a sequence if β is given - if β != 1 - a_hist = reshape(a_hist * (β^(collect(N:0)/ 2)), N + 1, 1) + # transform the a sequence if beta is given + if beta != 1 + a_hist = reshape(a_hist * (beta^(collect(N:0) / 2)), N + 1, 1) end - ā = a_hist - W_m * y_m # ā from the lecutre - Uy = \(L, ā) # U @ ȳ = L^{-1}ā from the lecture - ȳ = \(U, Uy) # ȳ = U^{-1}L^{-1}ā - # Reverse the order of ȳ with the matrix J + a_bar = a_hist - W_m * y_m # a_bar from the lecutre + Uy = \(L, a_bar) # U @ y_bar = L^{-1}a_bar from the lecture + y_bar = \(U, Uy) # y_bar = U^{-1}L^{-1}a_bar + # Reverse the order of y_bar with the matrix J J = reverse(Matrix(I, N + m + 1, N + m + 1), dims = 2) - y_hist = J * vcat(ȳ, y_m) # y_hist : concatenated y_m and ȳ - # transform the optimal sequence back if β is given - if β != 1 - y_hist = y_hist .* β.^(- collect(-m:N)/2) + y_hist = J * vcat(y_bar, y_m) # y_hist : concatenated y_m and y_bar + # transform the optimal sequence back if beta is given + if beta != 1 + y_hist = y_hist .* beta .^ (-collect((-m):N) / 2) end else # if the problem is stochastic and we look at it Ea_hist = reshape(predict(a_hist, t), N + 1, 1) Ea_hist = J * Ea_hist - ā = Ea_hist - W_m * y_m # ā from the lecutre - Uy = \(L, ā) # U @ ȳ = L^{-1}ā from the lecture - ȳ = \(U, Uy) # ȳ = U^{-1}L^{-1}ā + a_bar = Ea_hist - W_m * y_m # a_bar from the lecutre + Uy = \(L, a_bar) # U @ y_bar = L^{-1}a_bar from the lecture + y_bar = \(U, Uy) # y_bar = U^{-1}L^{-1}a_bar - # Reverse the order of ȳ with the matrix J + # Reverse the order of y_bar with the matrix J J = reverse(Matrix(I, N + m + 1, N + m + 1), dims = 2) - y_hist = J * vcat(ȳ, y_m) # y_hist : concatenated y_m and ȳ + y_hist = J * vcat(y_bar, y_m) # y_hist : concatenated y_m and y_bar end - return y_hist, L, U, ȳ + return y_hist, L, U, y_bar end ``` @@ -830,7 +823,7 @@ y_m = zeros(m) d = [1.0, -2.0] r = [1.0, -2.0] h = 0.0 -example = LQFilter(d, h, y_m, r=d) +example = LQFilter(d, h, y_m, r = d) ``` The Wold representation is computed by example.coefficients_of_c(). @@ -861,7 +854,7 @@ and put it in $V$. Then we'll take a Cholesky decomposition of $V = L^{-1} L^{-1} = Li Li'$ and use it to form the vector of "moving average representations" $x = Li \varepsilon$ and the vector of "autoregressive representations" $L x = \varepsilon$ ```{code-cell} julia -V = construct_V(example,N=5) +V = construct_V(example, N = 5) ``` Notice how the lower rows of the "moving average representations" are converging to the appropriate infinite history Wold representation @@ -951,7 +944,7 @@ V = construct_V(example, N = 8) ```{code-cell} julia F = cholesky(V) Li = F.L -Li[end-2:end, :] +Li[(end - 2):end, :] ``` ```{code-cell} julia diff --git a/lectures/time_series_models/estspec.md b/lectures/time_series_models/estspec.md index 83d5cd78..a616292b 100644 --- a/lectures/time_series_models/estspec.md +++ b/lectures/time_series_models/estspec.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (estspec)= @@ -45,12 +45,6 @@ Once the basic technique has been explained, we will apply it to the analysis of For supplementary reading, see {cite}`Sargent1987` or {cite}`CryerChan2008`. - - -```{code-cell} julia -using LinearAlgebra, Statistics -``` - (periodograms)= ## {index}`Periodograms ` @@ -223,21 +217,24 @@ using Test ```{code-cell} julia using QuantEcon, Plots, Random +using LinearAlgebra, Statistics Random.seed!(42) # For reproducible results. n = 40 # Data size -ϕ = 0.5 # AR parameter -θ = [0, -0.8] # MA parameter -σ = 1.0 -lp = ARMA(ϕ, θ, σ) +phi = 0.5 # AR parameter +theta = [0, -0.8] # MA parameter +sigma = 1.0 +lp = ARMA(phi, theta, sigma) X = simulation(lp, ts_length = n) x, y = periodogram(X) -x_sd, y_sd = spectral_density(lp, two_pi=false, res=120) +x_sd, y_sd = spectral_density(lp, two_pi = false, res = 120) -plot(x, y,linecolor="blue", linewidth=2, linealpha=0.5, lab="periodogram") -plot!(x_sd, y_sd, linecolor="red", linewidth=2, linealpha=0.8, lab="spectral density") +plot(x, y, linecolor = "blue", linewidth = 2, linealpha = 0.5, + lab = "periodogram") +plot!(x_sd, y_sd, linecolor = "red", linewidth = 2, linealpha = 0.8, + lab = "spectral density") ``` ```{code-cell} julia @@ -314,14 +311,15 @@ Note the smaller weights towards the edges and larger weights in the center, so ```{code-cell} julia function hanning_window(M) - w = [0.5 - 0.5 * cos(2 * pi * n / (M - 1)) for n = 0:(M-1)] + w = [0.5 - 0.5 * cos(2 * pi * n / (M - 1)) for n in 0:(M - 1)] return w end window = hanning_window(25) / sum(hanning_window(25)) x = range(-12, 12, length = 25) -plot(x, window, color="darkblue", title="Hanning window", ylabel="Weights", - xlabel="Position in sequence of weights", legend=false, grid=false) +plot(x, window, color = "darkblue", title = "Hanning window", + ylabel = "Weights", + xlabel = "Position in sequence of weights", legend = false, grid = false) ``` ```{code-cell} julia @@ -522,10 +520,10 @@ Random.seed!(42); # reproducible results ```{code-cell} julia n = 400 -ϕ = 0.5 -θ = [0, -0.8] -σ = 1.0 -lp = ARMA(ϕ, θ, 1.0) +phi = 0.5 +theta = [0, -0.8] +sigma = 1.0 +lp = ARMA(phi, theta, 1.0) X = simulation(lp, ts_length = n) xs = [] @@ -541,7 +539,7 @@ for (i, wl) in enumerate([15, 55, 175]) # window lengths push!(xs, x) push!(ys, y) - x_sd, y_sd = spectral_density(lp, two_pi=false, res=120) + x_sd, y_sd = spectral_density(lp, two_pi = false, res = 120) push!(x_sds, x_sd) push!(y_sds, y_sd) @@ -566,13 +564,13 @@ end ``` ```{code-cell} julia -plot(xs, ys, layout=(3,1), color=:blue, alpha=0.5, - linewidth=2, label=["periodogram" "" ""]) -plot!(x_sds, y_sds, layout=(3,1), color=:red, alpha=0.8, - linewidth=2, label=["spectral density" "" ""]) -plot!(x_sms, y_sms, layout=(3,1), color=:black, - linewidth=2, label=["smoothed periodogram" "" ""]) -plot!(title=reshape(titles,1,length(titles))) +plot(xs, ys, layout = (3, 1), color = :blue, alpha = 0.5, + linewidth = 2, label = ["periodogram" "" ""]) +plot!(x_sds, y_sds, layout = (3, 1), color = :red, alpha = 0.8, + linewidth = 2, label = ["spectral density" "" ""]) +plot!(x_sms, y_sms, layout = (3, 1), color = :black, + linewidth = 2, label = ["smoothed periodogram" "" ""]) +plot!(title = reshape(titles, 1, length(titles))) ``` ### Exercise 2 @@ -587,26 +585,26 @@ Random.seed!(42); # reproducible results ```{code-cell} julia lp2 = ARMA(-0.9, 0.0, 1.0) wl = 65 -p = plot(layout=(3,1)) +p = plot(layout = (3, 1)) for i in 1:3 - X = simulation(lp2,ts_length=150) - plot!(p[i],xlims = (0,pi)) + X = simulation(lp2, ts_length = 150) + plot!(p[i], xlims = (0, pi)) - x_sd, y_sd = spectral_density(lp2,two_pi=false, res=180) - plot!(p[i],x_sd, y_sd, linecolor=:red, linestyle=:solid, - yscale=:log10, linewidth=2, linealpha=0.75, - label="spectral density",legend=:topleft) + x_sd, y_sd = spectral_density(lp2, two_pi = false, res = 180) + plot!(p[i], x_sd, y_sd, linecolor = :red, linestyle = :solid, + yscale = :log10, linewidth = 2, linealpha = 0.75, + label = "spectral density", legend = :topleft) x, y_smoothed = periodogram(X, "hamming", wl) - plot!(p[i],x, y_smoothed, linecolor=:black, linestyle=:solid, - yscale=:log10, linewidth=2, linealpha=0.75, - label="standard smoothed periodogram",legend=:topleft) + plot!(p[i], x, y_smoothed, linecolor = :black, linestyle = :solid, + yscale = :log10, linewidth = 2, linealpha = 0.75, + label = "standard smoothed periodogram", legend = :topleft) x, y_ar = ar_periodogram(X, "hamming", wl) - plot!(p[i],x, y_ar, linecolor=:blue, linestyle=:solid, - yscale=:log10, linewidth=2, linealpha=0.75, - label="AR smoothed periodogram",legend=:topleft) + plot!(p[i], x, y_ar, linecolor = :blue, linestyle = :solid, + yscale = :log10, linewidth = 2, linealpha = 0.75, + label = "AR smoothed periodogram", legend = :topleft) end p ``` diff --git a/lectures/time_series_models/lu_tricks.md b/lectures/time_series_models/lu_tricks.md index 24856a5b..06b34847 100644 --- a/lectures/time_series_models/lu_tricks.md +++ b/lectures/time_series_models/lu_tricks.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (lu_tricks)= @@ -64,7 +64,7 @@ Useful references include {cite}`Whittle1963`, {cite}`HanSar1980`, {cite}`Orfani ```{code-cell} julia -using LaTeXStrings, Polynomials, Plots, Random, Parameters +using LaTeXStrings, Polynomials, Plots, Random using LinearAlgebra, Statistics ``` @@ -902,50 +902,50 @@ tags: [output_scroll] --- function LQFilter(d, h, y_m; r = nothing, - β = nothing, + beta = nothing, h_eps = nothing) m = length(d) - 1 m == length(y_m) || throw(ArgumentError("y_m and d must be of same length = $m")) - # define the coefficients of ϕ up front - ϕ = zeros(2m + 1) + # define the coefficients of phi up front + phi = zeros(2m + 1) for i in -m:m - ϕ[m-i+1] = sum(diag(d*d', -i)) + phi[m-i+1] = sum(diag(d*d', -i)) end - ϕ[m+1] = ϕ[m+1] + h + phi[m+1] = phi[m+1] + h - # if r is given calculate the vector ϕ_r + # if r is given calculate the vector phi_r if isnothing(r) k = nothing - ϕ_r = nothing + phi_r = nothing else k = size(r, 1) - 1 - ϕ_r = zeros(2k + 1) + phi_r = zeros(2k + 1) for i = -k:k - ϕ_r[k-i+1] = sum(diag(r*r', -i)) + phi_r[k-i+1] = sum(diag(r*r', -i)) end if h_eps != nothing - ϕ_r[k+1] = ϕ_r[k+1] + h_eps + phi_r[k+1] = phi_r[k+1] + h_eps end end - # if β is given, define the transformed variables - if isnothing(β) - β = 1.0 + # if beta is given, define the transformed variables + if isnothing(beta) + beta = 1.0 else - d = β.^(collect(0:m)/2) * d - y_m = y_m * β.^(- collect(1:m)/2) + d = beta.^(collect(0:m)/2) * d + y_m = y_m * beta.^(- collect(1:m)/2) end - return (d = d, h = h, y_m = y_m, m = m, ϕ = ϕ, β = β, ϕ_r = ϕ_r, k = k) + return (;d, h, y_m, m, phi, beta, phi_r, k) end function construct_W_and_Wm(lqf, N) - @unpack d, m = lqf + (;d, m) = lqf W = zeros(N + 1, N + 1) W_m = zeros(N + 1, m) @@ -974,67 +974,67 @@ function construct_W_and_Wm(lqf, N) M # Euler equations for t = 0, 1, ..., N-(m+1) - @unpack ϕ, h = lqf + (;phi, h) = lqf W[1:(m + 1), 1:(m + 1)] = D_m1 + h * I W[1:(m + 1), (m + 2):(2m + 1)] = M for (i, row) in enumerate((m + 2):(N + 1 - m)) - W[row, (i + 1):(2m + 1 + i)] = ϕ' + W[row, (i + 1):(2m + 1 + i)] = phi' end for i in 1:m - W[N - m + i + 1 , end-(2m + 1 - i)+1:end] = ϕ[1:end-i] + W[N - m + i + 1 , end-(2m + 1 - i)+1:end] = phi[1:end-i] end for i in 1:m - W_m[N - i + 2, 1:(m - i)+1] = ϕ[(m + 1 + i):end] + W_m[N - i + 2, 1:(m - i)+1] = phi[(m + 1 + i):end] end return W, W_m end function roots_of_characteristic(lqf) - @unpack m, ϕ = lqf + (;m, phi) = lqf # Calculate the roots of the 2m-polynomial - ϕ_poly=Polynomial(ϕ[end:-1:1]) - proots = roots(ϕ_poly) + phi_poly=Polynomial(phi[end:-1:1]) + proots = roots(phi_poly) # sort the roots according to their length (in descending order) roots_sorted = sort(proots, by=abs)[end:-1:1] - z_0 = sum(ϕ) / (fromroots(proots))(1.0) + z_0 = sum(phi) / (fromroots(proots))(1.0) z_1_to_m = roots_sorted[1:m] # we need only those outside the unit circle - λ = 1 ./ z_1_to_m - return z_1_to_m, z_0, λ + lambda = 1 ./ z_1_to_m + return z_1_to_m, z_0, lambda end function coeffs_of_c(lqf) - m = lqf.m - z_1_to_m, z_0, λ = roots_of_characteristic(lqf) + (;m) = lqf + z_1_to_m, z_0, lambda = roots_of_characteristic(lqf) c_0 = (z_0 * prod(z_1_to_m) * (-1.0)^m)^(0.5) c_coeffs = coeffs(Polynomial(z_1_to_m)) * z_0 / c_0 return c_coeffs end function solution(lqf) - z_1_to_m, z_0, λ = roots_of_characteristic(lqf) + z_1_to_m, z_0, lambda = roots_of_characteristic(lqf) c_0 = coeffs_of_c(lqf)[end] - A = zeros(lqf.m) + A = zeros(m) for j in 1:m - denom = 1 - λ/λ[j] + denom = 1 - lambda/lambda[j] A[j] = c_0^(-2) / prod(denom[1:m .!= j]) end - return λ, A + return lambda, A end function construct_V(lqf; N=nothing) - @unpack ϕ_r, k = lqf + (;phi_r, k) = lqf V = zeros(N, N) for i in 1:N for j in 1:N if abs(i-j) <= k - V[i, j] = ϕ_r[k + abs(i-j)+1] + V[i, j] = phi_r[k + abs(i-j)+1] end end end @@ -1060,7 +1060,7 @@ function predict(lqf, a_hist, t) end function optimal_y(lqf, a_hist, t = nothing) - @unpack β, y_m, m = lqf + (;beta, y_m, m) = lqf N = length(a_hist) - 1 W, W_m = construct_W_and_Wm(lqf, N) @@ -1077,35 +1077,35 @@ function optimal_y(lqf, a_hist, t = nothing) if isnothing(t) # if the problem is deterministic a_hist = J * a_hist - # transform the a sequence if β is given - if β != 1 - a_hist = reshape(a_hist * (β^(collect(N:0)/ 2)), N + 1, 1) + # transform the a sequence if beta is given + if beta != 1 + a_hist = reshape(a_hist * (beta^(collect(N:0)/ 2)), N + 1, 1) end - ā = a_hist - W_m * y_m # ā from the lecutre - Uy = \(L, ā) # U @ ȳ = L^{-1}ā from the lecture - ȳ = \(U, Uy) # ȳ = U^{-1}L^{-1}ā - # Reverse the order of ȳ with the matrix J + a_bar = a_hist - W_m * y_m # a_bar from the lecutre + Uy = \(L, a_bar) # U @ y_bar = L^{-1}a_bar from the lecture + y_bar = \(U, Uy) # y_bar = U^{-1}L^{-1}a_bar + # Reverse the order of y_bar with the matrix J J = reverse(I + zeros(N+m+1, N + m + 1), dims = 2) - y_hist = J * vcat(ȳ, y_m) # y_hist : concatenated y_m and ȳ - # transform the optimal sequence back if β is given - if β != 1 - y_hist = y_hist .* β.^(- collect(-m:N)/2) + y_hist = J * vcat(y_bar, y_m) # y_hist : concatenated y_m and y_bar + # transform the optimal sequence back if beta is given + if beta != 1 + y_hist = y_hist .* beta.^(- collect(-m:N)/2) end else # if the problem is stochastic and we look at it Ea_hist = reshape(predict(lqf, a_hist, t), N + 1, 1) Ea_hist = J * Ea_hist - ā = Ea_hist - W_m * y_m # ā from the lecutre - Uy = \(L, ā) # U @ ȳ = L^{-1}ā from the lecture - ȳ = \(U, Uy) # ȳ = U^{-1}L^{-1}ā + a_bar = Ea_hist - W_m * y_m # a_bar from the lecutre + Uy = \(L, a_bar) # U @ y_bar = L^{-1}a_bar from the lecture + y_bar = \(U, Uy) # y_bar = U^{-1}L^{-1}a_bar - # Reverse the order of ȳ with the matrix J + # Reverse the order of y_bar with the matrix J J = reverse(I + zeros(N + m + 1, N + m + 1), dims = 2) - y_hist = J * vcat(ȳ, y_m) # y_hist : concatenated y_m and ȳ + y_hist = J * vcat(y_bar, y_m) # y_hist : concatenated y_m and y_bar end - return y_hist, L, U, ȳ + return y_hist, L, U, y_bar end ``` @@ -1144,27 +1144,29 @@ using Test ```{code-cell} julia - # set seed and generate a_t sequence Random.seed!(123) n = 100 -a_seq = sin.(range(0, 5 * pi, length = n)) .+ 2 + 0.1 * randn(n) - -function plot_simulation(;γ=0.8, m=1, h=1., y_m=2.) - d = γ * [1, -1] - y_m = [y_m] - - testlq = LQFilter(d, h, y_m) - y_hist, L, U, y = optimal_y(testlq, a_seq) - y = y[end:-1:1] # reverse y - - # plot simulation results - time = 1:length(y) - plt = plot(time, a_seq / h, lw=2, color=:black, alpha=0.8, marker = :circle, - markersize = 2, label=L"a_t") - plot!(plt, time, y, lw=2, color=:blue, marker = :circle, markersize = 2, alpha=0.8, - label=L"y_t") - plot!(plt, xlabel="Time", grid=true, xlim=(0,maximum(time)), legend=:bottomleft) +a_seq = sin.(range(0, 5 * pi, length = n)) .+ 2 + 0.1 * randn(n) + +function plot_simulation(; gamma = 0.8, m = 1, h = 1.0, y_m = 2.0) + d = gamma * [1, -1] + y_m = [y_m] + + testlq = LQFilter(d, h, y_m) + y_hist, L, U, y = optimal_y(testlq, a_seq) + y = y[end:-1:1] # reverse y + + # plot simulation results + time = 1:length(y) + plt = plot(time, a_seq / h, lw = 2, color = :black, alpha = 0.8, + marker = :circle, + markersize = 2, label = L"a_t") + plot!(plt, time, y, lw = 2, color = :blue, marker = :circle, markersize = 2, + alpha = 0.8, + label = L"y_t") + plot!(plt, xlabel = "Time", grid = true, xlim = (0, maximum(time)), + legend = :bottomleft) end plot_simulation() @@ -1173,21 +1175,21 @@ plot_simulation() Here's what happens when we change $\gamma$ to 5.0 ```{code-cell} julia -plot_simulation(γ=5.0) +plot_simulation(gamma = 5.0) ``` And here's $\gamma = 10$ ```{code-cell} julia -plot_simulation(γ=10.0) +plot_simulation(gamma = 10.0) ``` ```{code-cell} julia --- tags: [remove-cell] --- -γ = 10.0 -d = γ*[-1, 1] +gamma = 10.0 +d = gamma*[-1, 1] y_hist, L, U, y = optimal_y(LQFilter(d , 1., [2.]), a_seq) @testset begin diff --git a/lectures/time_series_models/multiplicative_functionals.md b/lectures/time_series_models/multiplicative_functionals.md index 575c421e..c867628e 100644 --- a/lectures/time_series_models/multiplicative_functionals.md +++ b/lectures/time_series_models/multiplicative_functionals.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (multiplicative_functionals)= @@ -113,15 +113,18 @@ using Test, Random ```{code-cell} julia using LinearAlgebra, Statistics -using Distributions, LaTeXStrings, Parameters, Plots, QuantEcon +using Distributions, LaTeXStrings, Plots, QuantEcon import Distributions: loglikelihood ``` ```{code-cell} julia -AMF_LSS_VAR = @with_kw (A, B, D, F = 0.0, ν = 0.0, lss = construct_ss(A, B, D, F, ν)) +function AMF_LSS_VAR(; A, B, D, F = 0.0, nu = 0.0, + lss = construct_ss(A, B, D, F, nu)) + return (; A, B, D, F, nu, lss) +end -function construct_ss(A, B, D, F, ν) +function construct_ss(A, B, D, F, nu) H, g = additive_decomp(A, B, D, F) # Build A matrix for LSS @@ -129,7 +132,7 @@ function construct_ss(A, B, D, F, ν) A1 = [1 0 0 0 0] # Transition for 1 A2 = [1 1 0 0 0] # Transition for t A3 = [0 0 A 0 0] # Transition for x_{t+1} - A4 = [ν 0 D 1 0] # Transition for y_{t+1} + A4 = [nu 0 D 1 0] # Transition for y_{t+1} A5 = [0 0 0 0 1] # Transition for m_{t+1} Abar = vcat(A1, A2, A3, A4, A5) @@ -142,7 +145,7 @@ function construct_ss(A, B, D, F, ν) G2 = [0 0 0 1 0] # Selector for y_{t} G3 = [0 0 0 0 1] # Selector for martingale G4 = [0 0 -g 0 0] # Selector for stationary - G5 = [0 ν 0 0 0] # Selector for trend + G5 = [0 nu 0 0 0] # Selector for trend Gbar = vcat(G1, G2, G3, G4, G5) # Build LSS struct @@ -159,22 +162,22 @@ function additive_decomp(A, B, D, F) return H, g end -function multiplicative_decomp(A, B, D, F, ν) +function multiplicative_decomp(A, B, D, F, nu) H, g = additive_decomp(A, B, D, F) - ν_tilde = ν + 0.5 * H^2 + nu_tilde = nu + 0.5 * H^2 - return ν_tilde, H, g + return nu_tilde, H, g end function loglikelihood_path(amf, x, y) - @unpack A, B, D, F = amf + (; A, B, D, F) = amf T = length(y) FF = F^2 FFinv = inv(FF) - temp = y[2:end] - y[1:end-1] - D*x[1:end-1] - obs = temp .* FFinv .* temp + temp = y[2:end] - y[1:(end - 1)] - D * x[1:(end - 1)] + obs = temp .* FFinv .* temp obssum = cumsum(obs) - scalar = (log(FF) + log(2pi)) * (1:T-1) + scalar = (log(FF) + log(2pi)) * (1:(T - 1)) return -0.5 * (obssum + scalar) end @@ -220,7 +223,7 @@ function population_means(amf, T = 150) # Pull out moment generator moment_generator = moment_sequence(amf.lss) - for (tt, x) = enumerate(moment_generator) + for (tt, x) in enumerate(moment_generator) ymeans = x[2] xmean[tt] = ymeans[1] ymean[tt] = ymeans[2] @@ -266,13 +269,13 @@ Xmean_pop, Ymean_pop = population_means(amf, T) # Plot sample means vs population means plt_1 = plot(Xmean_t', color = :blue, label = L"(1/I) \sum_i x_t^i") plot!(plt_1, Xmean_pop, color = :black, label = L"E x_t") -plot!(plt_1, title = L"x_t", xlim = (0, T), legend = :bottomleft) +plot!(plt_1, title = L"x_t", xlim = (0, T), legend = :outertopright) plt_2 = plot(Ymean_t', color = :blue, label = L"(1/I) \sum_i x_t^i") plot!(plt_2, Ymean_pop, color = :black, label = L"E y_t") -plot!(plt_2, title = L"y_t", xlim = (0, T), legend = :bottomleft) +plot!(plt_2, title = L"y_t", xlim = (0, T), legend = :outertopright) -plot(plt_1, plt_2, layout = (2, 1), size = (800,500)) +plot(plt_1, plt_2, layout = (2, 1), size = (800, 500)) ``` ### Simulating log-likelihoods @@ -303,7 +306,7 @@ function simulate_likelihood(amf, Xit, Yit) I, T = size(Xit) # Allocate space - LLit = zeros(I, T-1) + LLit = zeros(I, T - 1) for i in 1:I LLit[i, :] = loglikelihood_path(amf, Xit[i, :], Yit[i, :]) @@ -320,7 +323,8 @@ LLmean_t = mean(LLT) plot(seriestype = :histogram, LLT, label = "") plot!(title = L"Distribution of $(I/T)log(L_T)|\theta_0$") -vline!([LLmean_t], linestyle = :dash, color = :black, lw = 2, alpha = 0.6, label = "") +vline!([LLmean_t], linestyle = :dash, color = :black, lw = 2, alpha = 0.6, + label = "") ``` ```{code-cell} julia @@ -347,13 +351,13 @@ Let's see this in a simulation normdist = Normal(0, F) mult = 1.175 println("The pdf at +/- $mult sigma takes the value: $(pdf(normdist,mult*F))") -println("Probability of dL being larger than 1 is approx: "* +println("Probability of dL being larger than 1 is approx: " * "$(cdf(normdist,mult*F)-cdf(normdist,-mult*F))") # Compare this to the sample analogue: -L_increment = LLit[:,2:end] - LLit[:,1:end-1] -r,c = size(L_increment) -frac_nonegative = sum(L_increment.>=0)/(c*r) +L_increment = LLit[:, 2:end] - LLit[:, 1:(end - 1)] +r, c = size(L_increment) +frac_nonegative = sum(L_increment .>= 0) / (c * r) print("Fraction of dlogL being nonnegative in the sample is: $(frac_nonegative)") ``` @@ -370,7 +374,7 @@ end Let's also plot the conditional pdf of $\Delta y_{t+1}$ ```{code-cell} julia -xgrid = range(-1, 1, length = 100) +xgrid = range(-1, 1, length = 100) println("The pdf at +/- one sigma takes the value: $(pdf(normdist, F)) ") plot(xgrid, pdf.(normdist, xgrid), label = "") plot!(title = L"Conditional pdf $f(\Delta y_{t+1} | x_t)$") @@ -418,16 +422,17 @@ Random.seed!(42); ```{code-cell} julia # Create the second (wrong) alternative model -amf2 = AMF_LSS_VAR(A = 0.9, B = 1.0, D = 0.55, F = 0.25) # parameters for θ_1 closer to θ_0 +amf2 = AMF_LSS_VAR(A = 0.9, B = 1.0, D = 0.55, F = 0.25) # parameters for theta_1 closer to theta_0 # Get likelihood from each path x^{i}, y^{i} LLit2 = simulate_likelihood(amf2, Xit, Yit) -LLT2 = 1/(T-1) * LLit2[:, end] +LLT2 = 1 / (T - 1) * LLit2[:, end] LLmean_t2 = mean(LLT2) plot(seriestype = :histogram, LLT2, label = "") -vline!([LLmean_t2], color = :black, lw = 2, linestyle = :dash, alpha = 0.6, label = "") +vline!([LLmean_t2], color = :black, lw = 2, linestyle = :dash, alpha = 0.6, + label = "") plot!(title = L"Distribution of $(1/T)log(L_T) | \theta_1)$") ``` @@ -444,9 +449,10 @@ end Let's see a histogram of the log-likelihoods under the true and the alternative model (same sample paths) ```{code-cell} julia -plot(seriestype = :histogram, LLT, bin = 50, alpha = 0.5, label = "True", normed = true) -plot!(seriestype = :histogram, LLT2, bin = 50, alpha = 0.5, label = "Alternative", - normed = true) +plot(seriestype = :histogram, LLT, bin = 50, alpha = 0.5, label = "True", + normed = true) +plot!(seriestype = :histogram, LLT2, bin = 50, alpha = 0.5, + label = "Alternative", normed = true) vline!([mean(LLT)], color = :black, lw = 2, linestyle = :dash, label = "") vline!([mean(LLT2)], color = :black, lw = 2, linestyle = :dash, label = "") ``` @@ -572,8 +578,8 @@ Random.seed!(42); ```{code-cell} julia function simulate_martingale_components(amf, T = 1_000, I = 5_000) # Get the multiplicative decomposition - @unpack A, B, D, F, ν, lss = amf - ν, H, g = multiplicative_decomp(A, B, D, F, ν) + (; A, B, D, F, nu, lss) = amf + nu, H, g = multiplicative_decomp(A, B, D, F, nu) # Allocate space add_mart_comp = zeros(I, T) @@ -585,13 +591,13 @@ function simulate_martingale_components(amf, T = 1_000, I = 5_000) add_mart_comp[i, :] = bar[3, :] end - mul_mart_comp = exp.(add_mart_comp' .- (0:T-1) * H^2 / 2)' + mul_mart_comp = exp.(add_mart_comp' .- (0:(T - 1)) * H^2 / 2)' return add_mart_comp, mul_mart_comp end # Build model -amf_2 = AMF_LSS_VAR(A = 0.8, B = 0.001, D = 1.0, F = 0.01, ν = 0.005) +amf_2 = AMF_LSS_VAR(A = 0.8, B = 0.001, D = 1.0, F = 0.01, nu = 0.005) amc, mmc = simulate_martingale_components(amf_2, 1_000, 5_000) @@ -666,16 +672,16 @@ We will plot the densities of $\log {\widetilde M}_t$ for different values of $t Here is some code that tackles these tasks ```{code-cell} julia -function Mtilde_t_density(amf, t; xmin = 1e-8, xmax = 5.0, npts = 5000) +function Mtilde_t_density(amf, t; xmin = 1e-8, xmax = 5.0, npts = 50) + (; A, B, D, F, nu) = amf # Pull out the multiplicative decomposition - νtilde, H, g = - multiplicative_decomp(amf.A, amf.B, amf.D, amf.F, amf.ν) - H2 = H*H + nutilde, H, g = multiplicative_decomp(A, B, D, F, nu) + H2 = H * H # The distribution mdist = LogNormal(-t * H2 / 2, sqrt(t * H2)) - x = range(xmin, xmax, length = npts) + x = range(xmin, xmax, length = npts) p = pdf.(mdist, x) return x, p @@ -684,29 +690,32 @@ end function logMtilde_t_density(amf, t; xmin = -15.0, xmax = 15.0, npts = 5000) # Pull out the multiplicative decomposition - @unpack A, B, D, F, ν = amf - νtilde, H, g = multiplicative_decomp(A, B, D, F, ν) + (; A, B, D, F, nu) = amf + nutilde, H, g = multiplicative_decomp(A, B, D, F, nu) H2 = H * H # The distribution lmdist = Normal(-t * H2 / 2, sqrt(t * H2)) - x = range(xmin, xmax, length = npts) + x = range(xmin, xmax, length = npts) p = pdf.(lmdist, x) return x, p end times_to_plot = [10, 100, 500, 1000, 2500, 5000] -dens_to_plot = [Mtilde_t_density(amf_2, t, xmin=1e-8, xmax=6.0) for t in times_to_plot] -ldens_to_plot = [logMtilde_t_density(amf_2, t, xmin=-10.0, xmax=10.0) for t in times_to_plot] +dens_to_plot = [Mtilde_t_density(amf_2, t, xmin = 1e-8, xmax = 6.0) + for t in times_to_plot] +ldens_to_plot = [logMtilde_t_density(amf_2, t, xmin = -10.0, xmax = 10.0) + for t in times_to_plot] # plot_title = "Densities of M_t^tilda" is required, however, plot_title is not yet # supported in Plots -plots = plot(layout = (3,2), size = (600,800)) +plots = plot(layout = (3, 2), size = (600, 800)) for (it, dens_t) in enumerate(dens_to_plot) x, pdf = dens_t - plot!(plots[it], title = "Density for time (time_to_plot[it])") + plot!(plots[it], title = "Density for time (time_to_plot[it])", + titlefontsize = 10) plot!(plots[it], pdf, fillrange = 0, label = "") end plot(plots) @@ -739,28 +748,29 @@ $\nu = \tilde{\nu}$. Here's our code ```{code-cell} julia -function Uu(amf, δ, γ) - @unpack A, B, D, F, ν = amf - ν_tilde, H, g = multiplicative_decomp(A, B, D, F, ν) +function Uu(amf, delta, gamma) + (; A, B, D, F, nu) = amf + nu_tilde, H, g = multiplicative_decomp(A, B, D, F, nu) - resolv = 1 / (1 - exp(-δ) * A) + resolv = 1 / (1 - exp(-delta) * A) vect = F + D * resolv * B - U_risky = exp(-δ) * resolv * D - u_risky = exp(-δ) / (1 - exp(-δ)) * (ν + 0.5 * (1 - γ) * (vect^2)) + U_risky = exp(-delta) * resolv * D + u_risky = exp(-delta) / (1 - exp(-delta)) * + (nu + 0.5 * (1 - gamma) * (vect^2)) U_det = 0 - u_det = exp(-δ) / (1 - exp(-δ)) * ν_tilde + u_det = exp(-delta) / (1 - exp(-delta)) * nu_tilde return U_risky, u_risky, U_det, u_det end # Set remaining parameters -δ = 0.02 -γ = 2.0 +delta = 0.02 +gamma = 2.0 # Get coeffs -U_r, u_r, U_d, u_d = Uu(amf_2, δ, γ) +U_r, u_r, U_d, u_d = Uu(amf_2, delta, gamma) ``` The values of the two processes are diff --git a/lectures/tools_and_techniques/geom_series.md b/lectures/tools_and_techniques/geom_series.md index 0ad2dc00..814be925 100644 --- a/lectures/tools_and_techniques/geom_series.md +++ b/lectures/tools_and_techniques/geom_series.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (mc)= @@ -499,7 +499,7 @@ in a project with gross one period nominal rate of return accumulates project - thus, $1$ dollar invested at time $0$ pays interest $r$ dollars after one period, so we have $r+1 = R$ - dollars at time$1$ + dollars at time $1$ - at time $1$ we reinvest $1+r =R$ dollars and receive interest of $r R$ dollars at time $2$ plus the *principal* $R$ dollars, so we receive $r R + R = (1+r)R = R^2$ @@ -551,7 +551,7 @@ The **present value** of the lease is $$ \begin{aligned} -p_0 & = x_0 + x_1/R + x_2/(R^2) + \ddots \\ +p_0 & = x_0 + x_1/R + x_2/(R^2) + \cdots \\ & = x_0 (1 + G R^{-1} + G^2 R^{-2} + \cdots ) \\ & = x_0 \frac{1}{1 - G R^{-1}} \end{aligned} @@ -704,7 +704,7 @@ plot!(plt, T, y_3, label = L"$T$-period Lease First-order Approx. adj.") Evidently our approximations perform well for small values of $T$. -However, holding $g$ and r fixed, our approximations deteriorate as $T$ increases. +However, holding $g$ and $r$ fixed, our approximations deteriorate as $T$ increases. Next we compare the infinite and finite duration lease present values over different lease lengths $T$. diff --git a/lectures/tools_and_techniques/iterative_methods_sparsity.md b/lectures/tools_and_techniques/iterative_methods_sparsity.md index 42896d18..58d5dcd8 100644 --- a/lectures/tools_and_techniques/iterative_methods_sparsity.md +++ b/lectures/tools_and_techniques/iterative_methods_sparsity.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (iterative_methods_sparsity)= @@ -457,7 +457,7 @@ equation through methods such as value-function iteration. The condition we will examine here is called [**diagonal dominance**](https://en.wikipedia.org/wiki/Diagonally_dominant_matrix). $$ -|A_{ii}| \geq \sum_{j\neq i} |A_{ij}| \quad\text{for all } i = 1\ldots N +|A_{ii}| \geq \sum_{j\neq i} |A_{ij}| \quad\text{for all } i = 1, \ldots N $$ That is, in every row, the diagonal element is weakly greater in absolute value than the sum of all of the other elements in the row. In cases @@ -466,7 +466,7 @@ where it is strictly greater, we say that the matrix is strictly diagonally domi With our example, given that $Q$ is the infinitesimal generator of a Markov chain, we know that each row sums to 0, and hence it is weakly diagonally dominant. -However, notice that when $\rho > 0$, and since the diagonal of $Q$ is negative, $A = rho I - Q$ makes the matrix strictly diagonally dominant. +However, notice that when $\rho > 0$, and since the diagonal of $Q$ is negative, $A = \rho I - Q$ makes the matrix strictly diagonally dominant. ### Jacobi Iteration @@ -1187,7 +1187,7 @@ $$ If $Q$ is a matrix, we could just take its transpose to find the adoint. However, with matrix-free methods, we need to implement the adjoint-vector product directly. -The logic for the adjoint is that for a given $n = (n_1,\ldots, n_m, \ldots n_M)$, the $Q^T$ product for that row has terms enter when +The logic for the adjoint is that for a given $n = (n_1,\ldots, n_m, \ldots, n_M)$, the $Q^T$ product for that row has terms enter when 1. $1 < n_m \leq N$, entering into the identical $n$ except with one less customer in the $m$ position 1. $1 \leq n_m < N$, entering into the identical $n$ except with one more customer in the $m$ position @@ -1299,35 +1299,4 @@ function stationary_psi(p) end p = default_params(; N = 10, M = 5) @btime stationary_psi($p); -``` - -As a final demonstration, consider calculating the full evolution of the $psi(t)$ Markov chain. For the constant -$Q'$ matrix, the solution to this system of equations is $\psi(t) = \exp(Q') \psi(0)$ - -Matrix-free Krylov methods using a technique called [exponential integration](https://en.wikipedia.org/wiki/Exponential_integrator) can solve this for high-dimensional problems. - -For this, we can set up a `MatrixFreeOperator` for our `Q_T_mul!` function (equivalent to the `LinearMap`, but with some additional requirements for the ODE solver) and use the [LinearExponential](http://docs.juliadiffeq.org/latest/solvers/ode_solve.html#Exponential-Methods-for-Linear-and-Affine-Problems-1) time-stepping method. - -```{code-cell} julia -using OrdinaryDiffEq, DiffEqOperators - -function solve_transition_dynamics(p, t) - (; N, M) = p - - psi_0 = [1.0; fill(0.0, N^M - 1)] - O! = MatrixFreeOperator((dpsi, psi, p, t) -> Q_T_mul!(dpsi, psi, p), (p, 0.0), - size = (N^M, N^M), opnorm = (p) -> 1.25) - - # define the corresponding ODE problem - prob = ODEProblem(O!, psi_0, (0.0, t[end]), p) - return solve(prob, LinearExponential(krylov = :simple), tstops = t) -end -t = 0.0:5.0:100.0 -p = default_params(; N = 10, M = 6) -sol = solve_transition_dynamics(p, t) -v = solve_bellman(p) -plot(t, [dot(sol(tval), v) for tval in t], xlabel = L"t", label = L"E_t(v)") -``` - -The above plot (1) calculates the full dynamics of the Markov chain from the $n_m = 1$ for all $m$ initial condition; (2) solves the dynamics of a system of a million ODEs; and (3) uses the calculation of the Bellman equation to find the expected valuation during that transition. The entire process takes less than 30 seconds. - +``` \ No newline at end of file diff --git a/lectures/tools_and_techniques/linear_algebra.md b/lectures/tools_and_techniques/linear_algebra.md index 397090ad..ddc3eb14 100644 --- a/lectures/tools_and_techniques/linear_algebra.md +++ b/lectures/tools_and_techniques/linear_algebra.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (linear_algebra)= @@ -402,7 +402,7 @@ $m > n$ vectors in $\mathbb R ^n$ must be linearly dependent. The following statements are equivalent to linear independence of $A := \{a_1, \ldots, a_k\} \subset \mathbb R ^n$. 1. No vector in $A$ can be formed as a linear combination of the other elements. -1. If $\beta_1 a_1 + \cdots \beta_k a_k = 0$ for scalars $\beta_1, \ldots, \beta_k$, then $\beta_1 = \cdots = \beta_k = 0$. +1. If $\beta_1 a_1 + \cdots + \beta_k a_k = 0$ for scalars $\beta_1, \ldots, \beta_k$, then $\beta_1 = \cdots = \beta_k = 0$. (The zero in the first expression is the origin of $\mathbb R ^n$) @@ -415,13 +415,13 @@ In other words, if $A := \{a_1, \ldots, a_k\} \subset \mathbb R ^n$ is linearly independent and $$ -y = \beta_1 a_1 + \cdots \beta_k a_k +y = \beta_1 a_1 + \cdots + \beta_k a_k $$ then no other coefficient sequence $\gamma_1, \ldots, \gamma_k$ will produce the same vector $y$. -Indeed, if we also have $y = \gamma_1 a_1 + \cdots \gamma_k a_k$, +Indeed, if we also have $y = \gamma_1 a_1 + \cdots + \gamma_k a_k$, then $$ diff --git a/lectures/tools_and_techniques/lln_clt.md b/lectures/tools_and_techniques/lln_clt.md index 63a17b22..22c09344 100644 --- a/lectures/tools_and_techniques/lln_clt.md +++ b/lectures/tools_and_techniques/lln_clt.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (lln_clt)= diff --git a/lectures/tools_and_techniques/numerical_linear_algebra.md b/lectures/tools_and_techniques/numerical_linear_algebra.md index 749eec56..b4f81c25 100644 --- a/lectures/tools_and_techniques/numerical_linear_algebra.md +++ b/lectures/tools_and_techniques/numerical_linear_algebra.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (numerical_linear_algebra)= @@ -54,7 +54,7 @@ The theme of this lecture, and numerical linear algebra in general, comes down t --- tags: [hide-output] --- -using LinearAlgebra, Statistics, BenchmarkTools, SparseArrays, Random, Parameters +using LinearAlgebra, Statistics, BenchmarkTools, SparseArrays, Random Random.seed!(42); # seed random numbers for reproducibility ``` @@ -491,14 +491,11 @@ To manually use the QR decomposition in solving linear least squares: ```{code-cell} julia Af = qr(A) -Q = Af.Q -R = [Af.R; zeros(N - M, M)] # Stack with zeros -@show Q * R ≈ A -x = R \ Q' * b # simplified QR solution for least squares +@show Af.Q * Af.R ≈ A +x = Af.R \ (Matrix(Af.Q)' * b) # simplified QR solution for least squares ``` -This stacks the `R` with zeros, but the more specialized algorithm would not multiply directly -in that way. +See [here](https://discourse.julialang.org/t/qr-decomposition-with-julia-how-to/92508/8) for more, thought keep in mind that more specialized algorithm would be more efficient. In some cases, if an LU is not available for a particular matrix structure, the QR factorization can also be used to solve systems of equations (i.e., not just LLS). This tends to be about 2 times slower than the LU @@ -626,7 +623,7 @@ Q = Tridiagonal(fill(alpha, N - 1), [-alpha; fill(-2alpha, N - 2); -alpha], Here we can use `Tridiagonal` to exploit the structure of the problem. -Consider a simple payoff vector $r$ associated with each state, and a discount rate $rho$. Then we can solve for +Consider a simple payoff vector $r$ associated with each state, and a discount rate $\rho$. Then we can solve for the expected present discounted value in a way similar to the discrete-time case. $$ @@ -655,23 +652,23 @@ linear problem. v = A \ r ``` -The $Q$ is also used to calculate the evolution of the Markov chain, in direct analogy to the $psi_{t+k} = psi_t P^k$ evolution with the transition matrix $P$ of the discrete case. +The $Q$ is also used to calculate the evolution of the Markov chain, in direct analogy to the $\psi_{t+k} = \psi_t P^k$ evolution with the transition matrix $P$ of the discrete case. In the continuous case, this becomes the system of linear differential equations $$ -\dot{psi}(t) = Q(t)^T psi(t) +\dot{\psi}(t) = Q(t)^T \psi(t) $$ given the initial condition $\psi(0)$ and where the $Q(t)$ intensity matrix is allowed to vary with time. In the simplest case of a constant $Q$ matrix, this is a simple constant-coefficient system of linear ODEs with coefficients $Q^T$. -If a stationary equilibrium exists, note that $\dot{psi}(t) = 0$, and the stationary solution $psi^{*}$ needs to satisfy +If a stationary equilibrium exists, note that $\dot{\psi}(t) = 0$, and the stationary solution $\psi^{*}$ needs to satisfy $$ -0 = Q^T psi^{*} +0 = Q^T \psi^{*} $$ -Notice that this is of the form $0 psi^{*} = Q^T psi^{*}$ and hence is equivalent to finding the eigenvector associated with the $\lambda = 0$ eigenvalue of $Q^T$. +Notice that this is of the form $0 \psi^{*} = Q^T \psi^{*}$ and hence is equivalent to finding the eigenvector associated with the $\lambda = 0$ eigenvalue of $Q^T$. With our example, we can calculate all of the eigenvalues and eigenvectors diff --git a/lectures/tools_and_techniques/orth_proj.md b/lectures/tools_and_techniques/orth_proj.md index 92d5e7b5..fb730798 100644 --- a/lectures/tools_and_techniques/orth_proj.md +++ b/lectures/tools_and_techniques/orth_proj.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (orth_proj)= diff --git a/lectures/tools_and_techniques/stationary_densities.md b/lectures/tools_and_techniques/stationary_densities.md index ffc3292e..4d903c2b 100644 --- a/lectures/tools_and_techniques/stationary_densities.md +++ b/lectures/tools_and_techniques/stationary_densities.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (statd)= diff --git a/lectures/troubleshooting.md b/lectures/troubleshooting.md index 94277480..febb508b 100644 --- a/lectures/troubleshooting.md +++ b/lectures/troubleshooting.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (troubleshooting)= diff --git a/lectures/zreferences.md b/lectures/zreferences.md index 54a244a3..3b982ed8 100644 --- a/lectures/zreferences.md +++ b/lectures/zreferences.md @@ -6,7 +6,7 @@ jupytext: kernelspec: display_name: Julia language: julia - name: julia-1.9 + name: julia-1.10 --- (references)= diff --git a/requirements.txt b/requirements.txt index e2869105..b4a8b16c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ jupyter-book==0.15.1 -quantecon-book-theme==0.5.3 +quantecon-book-theme==0.7.1 sphinx-tojupyter==0.3.0 sphinxext.rediraffe==0.2.7 \ No newline at end of file