diff --git a/Manifest.toml b/Manifest.toml
index a66e8e175..366ab594e 100644
--- a/Manifest.toml
+++ b/Manifest.toml
@@ -2,7 +2,7 @@
julia_version = "1.11.7"
manifest_format = "2.0"
-project_hash = "6ed163b5c6c108dfaae31b757b21ff71e297872f"
+project_hash = "2b3993e6e60ba9c1c456523b8f2caaae65279013"
[[deps.ADTypes]]
git-tree-sha1 = "27cecae79e5cc9935255f90c53bb831cc3c870d7"
@@ -40,9 +40,9 @@ version = "5.8.2"
[[deps.AbstractPPL]]
deps = ["AbstractMCMC", "Accessors", "DensityInterface", "JSON", "LinearAlgebra", "Random", "StatsBase"]
-git-tree-sha1 = "01107828b7367278491629b294a018e718697c3e"
+git-tree-sha1 = "43944cbd64e035e7228eb3e0f024d611058cbc78"
uuid = "7a57a42e-76ec-4ea3-a279-07e840d6d9cf"
-version = "0.13.2"
+version = "0.13.5"
weakdeps = ["Distributions"]
[deps.AbstractPPL.extensions]
@@ -181,15 +181,15 @@ version = "3.5.1+1"
[[deps.ArrayInterface]]
deps = ["Adapt", "LinearAlgebra"]
-git-tree-sha1 = "dbd8c3bbbdbb5c2778f85f4422c39960eac65a42"
+git-tree-sha1 = "d81ae5489e13bc03567d4fbbb06c546a5e53c857"
uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9"
-version = "7.20.0"
+version = "7.22.0"
[deps.ArrayInterface.extensions]
ArrayInterfaceBandedMatricesExt = "BandedMatrices"
ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices"
ArrayInterfaceCUDAExt = "CUDA"
- ArrayInterfaceCUDSSExt = "CUDSS"
+ ArrayInterfaceCUDSSExt = ["CUDSS", "CUDA"]
ArrayInterfaceChainRulesCoreExt = "ChainRulesCore"
ArrayInterfaceChainRulesExt = "ChainRules"
ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore"
@@ -259,9 +259,9 @@ version = "0.4.8"
[[deps.BandedMatrices]]
deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra", "PrecompileTools"]
-git-tree-sha1 = "d5133c6b1326fe10042e41ddf1d46b0a1a4011f4"
+git-tree-sha1 = "4826c9fe6023a87029e54870ad1a9800c7ea6623"
uuid = "aae01518-5342-5314-be14-df237901396f"
-version = "1.9.5"
+version = "1.10.1"
[deps.BandedMatrices.extensions]
BandedMatricesSparseArraysExt = "SparseArrays"
@@ -273,9 +273,9 @@ version = "1.9.5"
[[deps.BangBang]]
deps = ["Accessors", "ConstructionBase", "InitialValues", "LinearAlgebra"]
-git-tree-sha1 = "26f41e1df02c330c4fa1e98d4aa2168fdafc9b1f"
+git-tree-sha1 = "a49f9342fc60c2a2aaa4e0934f06755464fcf438"
uuid = "198e06fe-97b7-11e9-32a5-e1d131e6ad66"
-version = "0.4.4"
+version = "0.4.6"
[deps.BangBang.extensions]
BangBangChainRulesCoreExt = "ChainRulesCore"
@@ -304,9 +304,9 @@ version = "0.1.1"
[[deps.Bijectors]]
deps = ["ArgCheck", "ChainRulesCore", "ChangesOfVariables", "Distributions", "DocStringExtensions", "Functors", "InverseFunctions", "IrrationalConstants", "LinearAlgebra", "LogExpFunctions", "MappedArrays", "Random", "Reexport", "Roots", "SparseArrays", "Statistics"]
-git-tree-sha1 = "1f8e2022a4f6dbbe3c7b60f728647973e7b514ef"
+git-tree-sha1 = "e717d07fec10a086054ca960857bac637db4dd1f"
uuid = "76274a88-744f-5084-9051-94815aaf08c4"
-version = "0.15.10"
+version = "0.15.11"
weakdeps = ["ChainRules", "DistributionsAD", "EnzymeCore", "ForwardDiff", "LazyArrays", "Mooncake", "ReverseDiff"]
[deps.Bijectors.extensions]
@@ -424,21 +424,9 @@ version = "0.3.14"
[[deps.CategoricalArrays]]
deps = ["DataAPI", "Future", "Missings", "Printf", "Requires", "Statistics", "Unicode"]
-git-tree-sha1 = "1568b28f91293458345dabba6a5ea3f183250a61"
+git-tree-sha1 = "5084cc1a28976dd1642c9f337b28a3cb03e0f7d2"
uuid = "324d7699-5711-5eae-9e2f-1d82baa6b597"
-version = "0.10.8"
-
- [deps.CategoricalArrays.extensions]
- CategoricalArraysJSONExt = "JSON"
- CategoricalArraysRecipesBaseExt = "RecipesBase"
- CategoricalArraysSentinelArraysExt = "SentinelArrays"
- CategoricalArraysStructTypesExt = "StructTypes"
-
- [deps.CategoricalArrays.weakdeps]
- JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
- RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
- SentinelArrays = "91c51154-3ec4-41a3-a24f-3f23e20d615c"
- StructTypes = "856f2bd8-1eba-4b0a-8007-ebc267875bd4"
+version = "0.10.7"
[[deps.ChainRules]]
deps = ["Adapt", "ChainRulesCore", "Compat", "Distributed", "GPUArraysCore", "IrrationalConstants", "LinearAlgebra", "Random", "RealDot", "SparseArrays", "SparseInverseSubset", "Statistics", "StructArrays", "SuiteSparse"]
@@ -563,34 +551,6 @@ deps = ["Artifacts", "Libdl"]
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"
version = "1.1.1+0"
-[[deps.ComponentArrays]]
-deps = ["Adapt", "ArrayInterface", "ChainRulesCore", "ConstructionBase", "Functors", "LinearAlgebra", "StaticArrayInterface", "StaticArraysCore"]
-git-tree-sha1 = "d8b02e2226568644b6758b2d113fe5b08884eec0"
-uuid = "b0b7db55-cfe3-40fc-9ded-d10e2dbeff66"
-version = "0.15.29"
-
- [deps.ComponentArrays.extensions]
- ComponentArraysGPUArraysExt = "GPUArrays"
- ComponentArraysKernelAbstractionsExt = "KernelAbstractions"
- ComponentArraysOptimisersExt = "Optimisers"
- ComponentArraysReactantExt = "Reactant"
- ComponentArraysRecursiveArrayToolsExt = "RecursiveArrayTools"
- ComponentArraysReverseDiffExt = "ReverseDiff"
- ComponentArraysSciMLBaseExt = "SciMLBase"
- ComponentArraysTrackerExt = "Tracker"
- ComponentArraysZygoteExt = "Zygote"
-
- [deps.ComponentArrays.weakdeps]
- GPUArrays = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7"
- KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c"
- Optimisers = "3bd65402-5787-11e9-1adc-39752487f4e2"
- Reactant = "3c362404-f566-11ee-1572-e11a4b42c853"
- RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd"
- ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267"
- SciMLBase = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
- Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c"
- Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"
-
[[deps.CompositionsBase]]
git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad"
uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b"
@@ -657,9 +617,9 @@ version = "1.16.0"
[[deps.DataFrames]]
deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"]
-git-tree-sha1 = "c967271c27a95160e30432e011b58f42cd7501b5"
+git-tree-sha1 = "d8928e9169ff76c6281f39a659f9bca3a573f24c"
uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
-version = "1.8.0"
+version = "1.8.1"
[[deps.DataStructures]]
deps = ["Compat", "InteractiveUtils", "OrderedCollections"]
@@ -903,9 +863,9 @@ version = "3.5.1"
[[deps.DynamicPPL]]
deps = ["ADTypes", "AbstractMCMC", "AbstractPPL", "Accessors", "BangBang", "Bijectors", "Chairmarks", "Compat", "ConstructionBase", "DifferentiationInterface", "Distributions", "DocStringExtensions", "InteractiveUtils", "LinearAlgebra", "LogDensityProblems", "MacroTools", "OrderedCollections", "Printf", "Random", "Statistics", "Test"]
-git-tree-sha1 = "27884b501e0f31c68f75181151617b77e6ac0263"
+git-tree-sha1 = "8caa9710b7a1b7c89a063ce8e578a25725d5c8eb"
uuid = "366bfd00-2699-11ea-058f-f148b4cae6d8"
-version = "0.37.5"
+version = "0.38.1"
[deps.DynamicPPL.extensions]
DynamicPPLChainRulesCoreExt = ["ChainRulesCore"]
@@ -939,9 +899,9 @@ version = "1.0.5"
[[deps.Enzyme]]
deps = ["CEnum", "EnzymeCore", "Enzyme_jll", "GPUCompiler", "InteractiveUtils", "LLVM", "Libdl", "LinearAlgebra", "ObjectFile", "PrecompileTools", "Preferences", "Printf", "Random", "SparseArrays"]
-git-tree-sha1 = "9895c1784cfabb101ee51f3461b132083729a1de"
+git-tree-sha1 = "bd778fdcba83fdf6c97e1bc2b55600557fa519a7"
uuid = "7da242da-08ed-463a-9acd-ee780be4f1d9"
-version = "0.13.86"
+version = "0.13.87"
[deps.Enzyme.extensions]
EnzymeBFloat16sExt = "BFloat16s"
@@ -991,9 +951,9 @@ version = "0.1.11"
[[deps.Expat_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"]
-git-tree-sha1 = "7bb1361afdb33c7f2b085aa49ea8fe1b0fb14e58"
+git-tree-sha1 = "27af30de8b5445644e8ffe3bcb0d72049c089cf1"
uuid = "2e619515-83b5-522b-bb60-26c02a35a201"
-version = "2.7.1+0"
+version = "2.7.3+0"
[[deps.ExponentialUtilities]]
deps = ["Adapt", "ArrayInterface", "GPUArraysCore", "GenericSchur", "LinearAlgebra", "PrecompileTools", "Printf", "SparseArrays", "libblastrampoline_jll"]
@@ -1158,28 +1118,6 @@ git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172"
uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93"
version = "0.8.5"
-[[deps.Flux]]
-deps = ["Adapt", "ChainRulesCore", "Compat", "EnzymeCore", "Functors", "LinearAlgebra", "MLCore", "MLDataDevices", "MLUtils", "MacroTools", "NNlib", "OneHotArrays", "Optimisers", "Preferences", "ProgressLogging", "Random", "Reexport", "Setfield", "SparseArrays", "SpecialFunctions", "Statistics", "Zygote"]
-git-tree-sha1 = "d0751ca4c9762d9033534057274235dfef86aaf9"
-uuid = "587475ba-b771-5e3f-ad9e-33799f191a9c"
-version = "0.16.5"
-
- [deps.Flux.extensions]
- FluxAMDGPUExt = "AMDGPU"
- FluxCUDAExt = "CUDA"
- FluxCUDAcuDNNExt = ["CUDA", "cuDNN"]
- FluxEnzymeExt = "Enzyme"
- FluxMPIExt = "MPI"
- FluxMPINCCLExt = ["CUDA", "MPI", "NCCL"]
-
- [deps.Flux.weakdeps]
- AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e"
- CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba"
- Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9"
- MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195"
- NCCL = "3fe64909-d7a1-4096-9b7d-7a0f12cf0f6b"
- cuDNN = "02a925ec-e4fe-4b08-9a7e-0d78e3d38ccd"
-
[[deps.Fontconfig_jll]]
deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"]
git-tree-sha1 = "f85dac9a96a01087df6e3a749840015a0ca3817d"
@@ -1193,9 +1131,9 @@ version = "1.3.7"
[[deps.ForwardDiff]]
deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"]
-git-tree-sha1 = "dc41303865a16274ecb8450c220021ce1e0cf05f"
+git-tree-sha1 = "ba6ce081425d0afb2bedd00d9884464f764a9225"
uuid = "f6369f11-7733-5829-9624-2563aa707210"
-version = "1.2.1"
+version = "1.2.2"
weakdeps = ["StaticArrays"]
[deps.ForwardDiff.extensions]
@@ -1464,10 +1402,16 @@ uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
version = "1.7.1"
[[deps.JSON]]
-deps = ["Dates", "Mmap", "Parsers", "Unicode"]
-git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a"
+deps = ["Dates", "Logging", "Parsers", "PrecompileTools", "StructUtils", "UUIDs", "Unicode"]
+git-tree-sha1 = "06ea418d0c95878c8f3031023951edcf25b9e0ef"
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
-version = "0.21.4"
+version = "1.2.0"
+
+ [deps.JSON.extensions]
+ JSONArrowExt = ["ArrowTypes"]
+
+ [deps.JSON.weakdeps]
+ ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd"
[[deps.Jieko]]
deps = ["ExproniconLite"]
@@ -1533,12 +1477,6 @@ git-tree-sha1 = "059aabebaa7c82ccb853dd4a0ee9d17796f7e1bc"
uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d"
version = "3.100.3+0"
-[[deps.LBFGSB]]
-deps = ["L_BFGS_B_jll"]
-git-tree-sha1 = "e2e6f53ee20605d0ea2be473480b7480bd5091b5"
-uuid = "5be7bae1-8223-5378-bac3-9e7378a2f6e6"
-version = "0.4.1"
-
[[deps.LERC_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"]
git-tree-sha1 = "aaafe88dccbd957a8d82f7d05be9b69172e0cee3"
@@ -1575,12 +1513,6 @@ git-tree-sha1 = "1c602b1127f4751facb671441ca72715cc95938a"
uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac"
version = "2.10.3+0"
-[[deps.L_BFGS_B_jll]]
-deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"]
-git-tree-sha1 = "77feda930ed3f04b2b0fbb5bea89e69d3677c6b0"
-uuid = "81d17ec3-03a1-5e46-b53e-bddc35a13473"
-version = "3.0.1+0"
-
[[deps.LaTeXStrings]]
git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c"
uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
@@ -1994,9 +1926,9 @@ version = "1.0.0"
[[deps.MLDataDevices]]
deps = ["Adapt", "Functors", "Preferences", "Random", "SciMLPublic"]
-git-tree-sha1 = "f5c0536d7bcd78610c5195398e37ce2ab8fd8789"
+git-tree-sha1 = "df4fb509c1a328d7a616ec6fe2cffc96128ead80"
uuid = "7e8f7934-dd98-4c1a-8fe8-92b47a384d40"
-version = "1.13.0"
+version = "1.14.0"
[deps.MLDataDevices.extensions]
MLDataDevicesAMDGPUExt = "AMDGPU"
@@ -2095,9 +2027,9 @@ version = "1.11.0"
[[deps.MatrixFactorizations]]
deps = ["ArrayLayouts", "LinearAlgebra", "Printf", "Random"]
-git-tree-sha1 = "5d094d4d7887b1d75abccf960ae104a4428e948e"
+git-tree-sha1 = "3bb3cf4685f1c90f22883f4c4bb6d203fa882b79"
uuid = "a3b82374-2e81-5b9e-98ce-41277c0e4c87"
-version = "3.1.0"
+version = "3.1.3"
weakdeps = ["BandedMatrices"]
[deps.MatrixFactorizations.extensions]
@@ -2129,12 +2061,6 @@ git-tree-sha1 = "c13304c81eec1ed3af7fc20e75fb6b26092a1102"
uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e"
version = "0.3.2"
-[[deps.Memoization]]
-deps = ["MacroTools"]
-git-tree-sha1 = "7dbf904fa6c4447bd1f1d316886bfbe29feacf45"
-uuid = "6fafb56a-5788-4b4e-91ca-c0cea6611c73"
-version = "0.2.2"
-
[[deps.MicroCollections]]
deps = ["Accessors", "BangBang", "InitialValues"]
git-tree-sha1 = "44d32db644e84c75dab479f1bc15ee76a1a3618f"
@@ -2408,12 +2334,6 @@ git-tree-sha1 = "b6aa4566bb7ae78498a5e68943863fa8b5231b59"
uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051"
version = "1.3.6+0"
-[[deps.OneHotArrays]]
-deps = ["Adapt", "ChainRulesCore", "Compat", "GPUArraysCore", "LinearAlgebra", "NNlib"]
-git-tree-sha1 = "bfe8e84c71972f77e775f75e6d8048ad3fdbe8bc"
-uuid = "0b1bfda6-eb8a-41d2-88d8-f5af5cad476f"
-version = "0.2.10"
-
[[deps.OpenBLAS_jll]]
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"]
uuid = "4536629a-c528-5b80-bd46-f80d51c5b363"
@@ -2471,16 +2391,16 @@ version = "0.4.6"
Reactant = "3c362404-f566-11ee-1572-e11a4b42c853"
[[deps.Optimization]]
-deps = ["ADTypes", "ArrayInterface", "ConsoleProgressMonitor", "DocStringExtensions", "LBFGSB", "LinearAlgebra", "Logging", "LoggingExtras", "OptimizationBase", "Printf", "ProgressLogging", "Random", "Reexport", "SciMLBase", "SparseArrays", "TerminalLoggers"]
-git-tree-sha1 = "fa2449ce34cc1d7b2191bad4d3356a5376412288"
+deps = ["ADTypes", "ArrayInterface", "ConsoleProgressMonitor", "DocStringExtensions", "LinearAlgebra", "Logging", "LoggingExtras", "OptimizationBase", "Printf", "ProgressLogging", "Reexport", "SciMLBase", "SparseArrays", "TerminalLoggers"]
+git-tree-sha1 = "6b74af28fe70d6c828746376549c357cf88d3c3a"
uuid = "7f7a1694-90dd-40f0-9382-eb1efda571ba"
-version = "4.8.0"
+version = "5.0.0"
[[deps.OptimizationBase]]
deps = ["ADTypes", "ArrayInterface", "DifferentiationInterface", "DocStringExtensions", "FastClosures", "LinearAlgebra", "PDMats", "Reexport", "SciMLBase", "SparseArrays", "SparseConnectivityTracer", "SparseMatrixColorings"]
-git-tree-sha1 = "2c0d0c5c531f790fe5f8f5e6e858909b11a847ea"
+git-tree-sha1 = "9656e816095035cb993863fea4209f0cd8b1bc45"
uuid = "bca83a33-5cc9-4baa-983d-23429ab6bcbb"
-version = "2.13.2"
+version = "3.3.1"
[deps.OptimizationBase.extensions]
OptimizationEnzymeExt = "Enzyme"
@@ -2505,16 +2425,16 @@ version = "2.13.2"
Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f"
[[deps.OptimizationNLopt]]
-deps = ["NLopt", "Optimization", "Random", "Reexport"]
-git-tree-sha1 = "49d76b9da5210991366ff9b685287a412f6ea69b"
+deps = ["NLopt", "OptimizationBase", "Random", "Reexport", "SciMLBase"]
+git-tree-sha1 = "067cbeb17f03494d40affa13c750411f737417ca"
uuid = "4e6fcdb7-1186-4e1f-a706-475e75c168bb"
-version = "0.3.4"
+version = "0.3.6"
[[deps.OptimizationOptimJL]]
-deps = ["Optim", "Optimization", "PrecompileTools", "Reexport", "SparseArrays"]
-git-tree-sha1 = "d9e2cca329ce969a3dc26c9278d77bfeff7012ef"
+deps = ["Optim", "OptimizationBase", "PrecompileTools", "Reexport", "SciMLBase", "SparseArrays"]
+git-tree-sha1 = "f46a4ac6619a232ef35f9f8728d76fd7baeb962e"
uuid = "36348300-93cb-4f02-beb5-3c3902f8871e"
-version = "0.4.5"
+version = "0.4.6"
[[deps.Opus_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"]
@@ -2994,9 +2914,9 @@ version = "0.6.12"
[[deps.RecursiveArrayTools]]
deps = ["Adapt", "ArrayInterface", "DocStringExtensions", "GPUArraysCore", "LinearAlgebra", "RecipesBase", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface"]
-git-tree-sha1 = "96bef5b9ac123fff1b379acf0303cf914aaabdfd"
+git-tree-sha1 = "51bdb23afaaa551f923a0e990f7c44a4451a26f1"
uuid = "731186ca-8d62-57ce-b412-fbd966d074cd"
-version = "3.37.1"
+version = "3.39.0"
[deps.RecursiveArrayTools.extensions]
RecursiveArrayToolsFastBroadcastExt = "FastBroadcast"
@@ -3055,9 +2975,9 @@ version = "1.16.1"
[[deps.Rmath]]
deps = ["Random", "Rmath_jll"]
-git-tree-sha1 = "852bd0f55565a9e973fcfee83a84413270224dc4"
+git-tree-sha1 = "52b99504e2c174d9a8592a89647f5187063d1eb1"
uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa"
-version = "0.8.0"
+version = "0.8.2"
[[deps.Rmath_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"]
@@ -3109,10 +3029,10 @@ uuid = "26aad666-b158-4e64-9d35-0e672562fa48"
version = "0.5.2"
[[deps.SciMLBase]]
-deps = ["ADTypes", "Accessors", "Adapt", "ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "Moshi", "PreallocationTools", "PrecompileTools", "Preferences", "Printf", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "SciMLStructures", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface"]
-git-tree-sha1 = "737abcec59e3b999dda21018a6f3e442c0a58a65"
+deps = ["ADTypes", "Accessors", "Adapt", "ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "Moshi", "PreallocationTools", "PrecompileTools", "Preferences", "Printf", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "SciMLPublic", "SciMLStructures", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface"]
+git-tree-sha1 = "7680fbbc8a4fdf9837b4cae5e3fbebe53ec8e4ff"
uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462"
-version = "2.121.1"
+version = "2.122.0"
[deps.SciMLBase.extensions]
SciMLBaseChainRulesCoreExt = "ChainRulesCore"
@@ -3373,9 +3293,9 @@ weakdeps = ["ChainRulesCore", "Statistics"]
StaticArraysStatisticsExt = "Statistics"
[[deps.StaticArraysCore]]
-git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682"
+git-tree-sha1 = "6ab403037779dae8c514bad259f32a447262455a"
uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c"
-version = "1.4.3"
+version = "1.4.4"
[[deps.StatisticalTraits]]
deps = ["ScientificTypesBase"]
@@ -3407,9 +3327,9 @@ version = "0.33.21"
[[deps.StatsFuns]]
deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"]
-git-tree-sha1 = "8e45cecc66f3b42633b8ce14d431e8e57a3e242e"
+git-tree-sha1 = "1ec049c79e13fb2638ddbf8793ab2cbbeb266f45"
uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
-version = "1.5.0"
+version = "1.5.1"
weakdeps = ["ChainRulesCore", "InverseFunctions"]
[deps.StatsFuns.extensions]
@@ -3474,9 +3394,9 @@ version = "0.4.1"
[[deps.StructArrays]]
deps = ["ConstructionBase", "DataAPI", "Tables"]
-git-tree-sha1 = "8ad2e38cbb812e29348719cc63580ec1dfeb9de4"
+git-tree-sha1 = "a2c37d815bf00575332b7bd0389f771cb7987214"
uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
-version = "0.7.1"
+version = "0.7.2"
weakdeps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LinearAlgebra", "SparseArrays", "StaticArrays"]
[deps.StructArrays.extensions]
@@ -3491,6 +3411,20 @@ git-tree-sha1 = "c581be48ae1cbf83e899b14c07a807e1787512cc"
uuid = "53d494c1-5632-5724-8f4c-31dff12d585f"
version = "0.3.1"
+[[deps.StructUtils]]
+deps = ["Dates", "UUIDs"]
+git-tree-sha1 = "cd47aa083c9c7bdeb7b92de26deb46d6a33163c9"
+uuid = "ec057cc2-7a8d-4b58-b3b3-92acb9f63b42"
+version = "2.5.1"
+
+ [deps.StructUtils.extensions]
+ StructUtilsMeasurementsExt = ["Measurements"]
+ StructUtilsTablesExt = ["Tables"]
+
+ [deps.StructUtils.weakdeps]
+ Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7"
+ Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
+
[[deps.StyledStrings]]
uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b"
version = "1.11.0"
@@ -3679,14 +3613,14 @@ version = "1.6.0"
[[deps.Turing]]
deps = ["ADTypes", "AbstractMCMC", "AbstractPPL", "Accessors", "AdvancedHMC", "AdvancedMH", "AdvancedPS", "AdvancedVI", "BangBang", "Bijectors", "Compat", "DataStructures", "Distributions", "DistributionsAD", "DocStringExtensions", "DynamicPPL", "EllipticalSliceSampling", "ForwardDiff", "Libtask", "LinearAlgebra", "LogDensityProblems", "MCMCChains", "NamedArrays", "Optimization", "OptimizationOptimJL", "OrderedCollections", "Printf", "Random", "Reexport", "SciMLBase", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"]
-git-tree-sha1 = "1eb4c81c19e9f245c46c38e0c16e8efa4e484cba"
+git-tree-sha1 = "3062ce6a48bd5faf5a82a416b55e8d58da44794a"
uuid = "fce5fe82-541a-59a6-adf8-730c64b5f9a0"
-version = "0.40.4"
+version = "0.41.0"
weakdeps = ["DynamicHMC", "Optim"]
[deps.Turing.extensions]
TuringDynamicHMCExt = "DynamicHMC"
- TuringOptimExt = "Optim"
+ TuringOptimExt = ["Optim", "AbstractPPL"]
[[deps.URIs]]
git-tree-sha1 = "bef26fb046d031353ef97a82e3fdb6afe7f21b1a"
@@ -4038,10 +3972,10 @@ uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d"
version = "1.59.0+0"
[[deps.oneTBB_jll]]
-deps = ["Artifacts", "JLLWrappers", "Libdl"]
-git-tree-sha1 = "d5a767a3bb77135a99e433afe0eb14cd7f6914c3"
+deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"]
+git-tree-sha1 = "1350188a69a6e46f799d3945beef36435ed7262f"
uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e"
-version = "2022.0.0+0"
+version = "2022.0.0+1"
[[deps.p7zip_jll]]
deps = ["Artifacts", "Libdl"]
diff --git a/Project.toml b/Project.toml
index 3498eed33..137e2fa1b 100644
--- a/Project.toml
+++ b/Project.toml
@@ -3,23 +3,17 @@ ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b"
AbstractGPs = "99985d1d-32ba-4be9-9821-2ec096f28918"
AbstractMCMC = "80f14c24-f653-4e6a-9b94-39d6b0f70001"
AbstractPPL = "7a57a42e-76ec-4ea3-a279-07e840d6d9cf"
-AdvancedHMC = "0bf59076-c3b1-5ca4-86bd-e02cd72cde3d"
AdvancedMH = "5b7e9947-ddc0-4b3f-9b55-0d8042f74170"
AdvancedVI = "b5ca4192-6429-45e5-a2d9-87aec30a685c"
Bijectors = "76274a88-744f-5084-9051-94815aaf08c4"
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
-ComponentArrays = "b0b7db55-cfe3-40fc-9ded-d10e2dbeff66"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
-DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
-DelayDiffEq = "bcd4f6db-9728-5f36-b5f7-82caef46ccdb"
DifferentialEquations = "0c46a032-eb83-5123-abaf-570d42b7fbaa"
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
-DistributionsAD = "ced4e74d-a319-5a8a-b0ac-84af2272839c"
DynamicHMC = "bbc10e6e-7c05-544b-b16e-64fede858acb"
DynamicPPL = "366bfd00-2699-11ea-058f-f148b4cae6d8"
FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b"
-Flux = "587475ba-b771-5e3f-ad9e-33799f191a9c"
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
Functors = "d9f16b24-f501-4c13-a1f2-28368ffc5196"
GLM = "38e38edf-8417-5370-95a0-9cbb8c7f171a"
@@ -35,25 +29,24 @@ MLDataUtils = "cc2ba9b6-d476-5e6d-8eaf-a92d5412d41d"
MLUtils = "f1d291b0-491e-4a28-83b9-f70985020b54"
MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
Measures = "442fdcdd-2543-5da2-b0f3-8c86c306513e"
-Memoization = "6fafb56a-5788-4b4e-91ca-c0cea6611c73"
Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6"
NNlib = "872c559c-99b0-510c-b3b7-b6c96a88d5cd"
Optimisers = "3bd65402-5787-11e9-1adc-39752487f4e2"
-Optimization = "7f7a1694-90dd-40f0-9382-eb1efda571ba"
OptimizationNLopt = "4e6fcdb7-1186-4e1f-a706-475e75c168bb"
OptimizationOptimJL = "36348300-93cb-4f02-beb5-3c3902f8871e"
PDMats = "90014a1f-27ba-587c-ab20-58faa44d9150"
+Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
RDatasets = "ce6b1742-4840-55fa-b093-852dadbb1d8b"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267"
SciMLSensitivity = "1ed8b502-d754-442c-8d5d-10ac956f44a1"
+StableRNGs = "860ef19b-820b-49d6-a774-d7a799459cd3"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
StatsFuns = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd"
Turing = "fce5fe82-541a-59a6-adf8-730c64b5f9a0"
-UnPack = "3a884ed6-31ef-47d7-9d2a-63182c4928ed"
[compat]
-Turing = "0.40"
+Turing = "0.41"
diff --git a/_quarto.yml b/_quarto.yml
index 38c47bfd6..b44b5f713 100644
--- a/_quarto.yml
+++ b/_quarto.yml
@@ -43,7 +43,7 @@ website:
href: https://turinglang.org/team/
right:
# Current version
- - text: "v0.40"
+ - text: "v0.41"
menu:
- text: Changelog
href: https://turinglang.org/docs/changelog.html
diff --git a/developers/compiler/design-overview/index.qmd b/developers/compiler/design-overview/index.qmd
index 6b27454dc..8a4ad28b9 100755
--- a/developers/compiler/design-overview/index.qmd
+++ b/developers/compiler/design-overview/index.qmd
@@ -36,6 +36,7 @@ The following are the main jobs of the `@model` macro:
## The model
+
The `Model` struct contains the four internal fields `f`, `args`, `defaults`, and `context`.
When `model::Model` is called, then the internal function `model.f` is called as `model.f(rng, varinfo, sampler, context, model.args...)`
diff --git a/developers/contexts/submodel-condition/index.qmd b/developers/contexts/submodel-condition/index.qmd
index 3519116bf..75bf34031 100755
--- a/developers/contexts/submodel-condition/index.qmd
+++ b/developers/contexts/submodel-condition/index.qmd
@@ -102,19 +102,14 @@ We begin by mentioning some high-level desiderata for their joint behaviour.
Take these models, for example:
```{julia}
-# We define a helper function to unwrap a layer of SamplingContext, to
-# avoid cluttering the print statements.
-unwrap_sampling_context(ctx::DynamicPPL.SamplingContext) = ctx.context
-unwrap_sampling_context(ctx::DynamicPPL.AbstractContext) = ctx
-
@model function inner()
- println("inner context: $(unwrap_sampling_context(__model__.context))")
+ println("inner context: $(__model__.context)")
x ~ Normal()
return y ~ Normal()
end
@model function outer()
- println("outer context: $(unwrap_sampling_context(__model__.context))")
+ println("outer context: $(__model__.context)")
return a ~ to_submodel(inner())
end
@@ -124,7 +119,7 @@ with_outer_cond = outer() | (@varname(a.x) => 1.0)
# 'Inner conditioning'
inner_cond = inner() | (@varname(x) => 1.0)
@model function outer2()
- println("outer context: $(unwrap_sampling_context(__model__.context))")
+ println("outer context: $(__model__.context)")
return a ~ to_submodel(inner_cond)
end
with_inner_cond = outer2()
diff --git a/developers/transforms/dynamicppl/index.qmd b/developers/transforms/dynamicppl/index.qmd
index a02dde7af..ed27513c4 100644
--- a/developers/transforms/dynamicppl/index.qmd
+++ b/developers/transforms/dynamicppl/index.qmd
@@ -67,7 +67,7 @@ Note that this acts on _all_ variables in the model, including unconstrained one
vi_linked = DynamicPPL.link(vi, model)
println("Transformed value: $(DynamicPPL.getindex_internal(vi_linked, vn_x))")
println("Transformed logp: $(DynamicPPL.getlogp(vi_linked))")
-println("Transformed flag: $(DynamicPPL.istrans(vi_linked, vn_x))")
+println("Transformed flag: $(DynamicPPL.is_transformed(vi_linked, vn_x))")
```
Indeed, we can see that the new logp value matches with
@@ -82,7 +82,7 @@ The reverse transformation, `invlink`, reverts all of the above steps:
vi = DynamicPPL.invlink(vi_linked, model) # Same as the previous vi
println("Un-transformed value: $(DynamicPPL.getindex_internal(vi, vn_x))")
println("Un-transformed logp: $(DynamicPPL.getlogp(vi))")
-println("Un-transformed flag: $(DynamicPPL.istrans(vi, vn_x))")
+println("Un-transformed flag: $(DynamicPPL.is_transformed(vi, vn_x))")
```
### Model and internal representations
@@ -104,7 +104,7 @@ Note that `vi_linked[vn_x]` can also be used as shorthand for `getindex(vi_linke
We can see (for this linked varinfo) that there are _two_ differences between these outputs:
1. _The internal representation has been transformed using the bijector (in this case, the log function)._
- This means that the `istrans()` flag which we used above doesn't modify the model representation: it only tells us whether the internal representation has been transformed or not.
+ This means that the `is_transformed()` flag which we used above doesn't modify the model representation: it only tells us whether the internal representation has been transformed or not.
2. _The internal representation is a vector, whereas the model representation is a scalar._
This is because in DynamicPPL, _all_ internal values are vectorised (i.e. converted into some vector), regardless of distribution. On the other hand, since the model specifies a univariate distribution, the model representation is a scalar.
@@ -131,7 +131,7 @@ Before that, though, we'll take a quick high-level look at how the HMC sampler i
While DynamicPPL provides the _functionality_ for transforming variables, the transformation itself happens at an even higher level, i.e. in the sampler itself.
The HMC sampler in Turing.jl is in [this file](https://github.com/TuringLang/Turing.jl/blob/5b24cebe773922e0f3d5c4cb7f53162eb758b04d/src/mcmc/hmc.jl).
In the first step of sampling, it calls `link` on the sampler.
-This transformation is preserved throughout the sampling process, meaning that `istrans()` always returns true.
+This transformation is preserved throughout the sampling process, meaning that `is_transformed()` always returns true.
We can observe this by inserting print statements into the model.
Here, `__varinfo__` is the internal symbol for the `VarInfo` object used in model evaluation:
@@ -145,7 +145,7 @@ setprogress!(false)
println("-----------")
println("model repn: $(DynamicPPL.getindex(__varinfo__, @varname(x)))")
println("internal repn: $(DynamicPPL.getindex_internal(__varinfo__, @varname(x)))")
- println("istrans: $(istrans(__varinfo__, @varname(x)))")
+ println("is_transformed: $(is_transformed(__varinfo__, @varname(x)))")
end
end
@@ -154,10 +154,10 @@ sample(demo2(), HMC(0.1, 3), 3);
(Here, the check on `if x isa AbstractFloat` prevents the printing from occurring during computation of the derivative.)
-You can see that during the three sampling steps, `istrans` is always kept as `true`.
+You can see that during the three sampling steps, `is_transformed` is always kept as `true`.
::: {.callout-note}
-The first two model evaluations where `istrans` is `false` occur prior to the actual sampling.
+The first two model evaluations where `is_transformed` is `false` occur prior to the actual sampling.
One occurs when the model is checked for correctness (using [`DynamicPPL.check_model_and_trace`](https://github.com/TuringLang/DynamicPPL.jl/blob/ba490bf362653e1aaefe298364fe3379b60660d3/src/debug_utils.jl#L582-L612)).
The second occurs because the model is evaluated once to generate a set of initial parameters inside [DynamicPPL's implementation of `AbstractMCMC.step`](https://github.com/TuringLang/DynamicPPL.jl/blob/ba490bf362653e1aaefe298364fe3379b60660d3/src/sampler.jl#L98-L117).
Both of these steps occur with all samplers in Turing.jl, so are not specific to the HMC example shown here.
@@ -169,7 +169,7 @@ The biggest prerequisite for this to work correctly is that the potential energy
This is exactly the same as how we had to make sure to define `logq(y)` correctly in the toy HMC example above.
Within Turing.jl, this is correctly handled because a statement like `x ~ LogNormal()` in the model definition above is translated into `assume(LogNormal(), @varname(x), __varinfo__)`, defined [here](https://github.com/TuringLang/DynamicPPL.jl/blob/ba490bf362653e1aaefe298364fe3379b60660d3/src/context_implementations.jl#L225-L229).
-If you follow the trail of function calls, you can verify that the `assume` function does indeed check for the presence of the `istrans` flag and adds the Jacobian term accordingly.
+If you follow the trail of function calls, you can verify that the `assume` function does indeed check for the presence of the `is_transformed` flag and adds the Jacobian term accordingly.
## A deeper dive into DynamicPPL's internal machinery
@@ -234,7 +234,7 @@ DynamicPPL.getindex_internal(vi_linked, vn_x)
```
The purpose of having all of these machinery is to allow other parts of DynamicPPL, such as the tilde pipeline, to handle transformed variables correctly.
-The following diagram shows how `assume` first checks whether the variable is transformed (using `istrans`), and then applies the appropriate transformation function.
+The following diagram shows how `assume` first checks whether the variable is transformed (using `is_transformed`), and then applies the appropriate transformation function.
```{mermaid}
@@ -246,7 +246,7 @@ graph TD
A["x ~ LogNormal()"]:::boxStyle
B["vn = @varname(x)
dist = LogNormal()
x, vi = ..."]:::boxStyle
C["assume(vn, dist, vi)"]:::boxStyle
- D(["if istrans(vi, vn)"]):::boxStyle
+ D(["if is_transformed(vi, vn)"]):::boxStyle
E["f = from_internal_transform(vi, vn, dist)"]:::boxStyle
F["f = from_linked_internal_transform(vi, vn, dist)"]:::boxStyle
G["x, logjac = with_logabsdet_jacobian(f, getindex_internal(vi, vn, dist))"]:::boxStyle
@@ -267,7 +267,7 @@ graph TD
Here, `with_logabsdet_jacobian` is defined [in the ChangesOfVariables.jl package](https://juliamath.github.io/ChangesOfVariables.jl/stable/api/#ChangesOfVariables.with_logabsdet_jacobian), and returns both the effect of the transformation `f` as well as the log Jacobian term.
-Because we chose `f` appropriately, we find here that `x` is always the model representation; furthermore, if the variable was _not_ linked (i.e. `istrans` was false), the log Jacobian term will be zero.
+Because we chose `f` appropriately, we find here that `x` is always the model representation; furthermore, if the variable was _not_ linked (i.e. `is_transformed` was false), the log Jacobian term will be zero.
However, if it was linked, then the Jacobian term would be appropriately included, making sure that sampling proceeds correctly.
## Why do we need to do this at runtime?
diff --git a/tutorials/bayesian-linear-regression/index.qmd b/tutorials/bayesian-linear-regression/index.qmd
index c28148371..8eeff5faa 100755
--- a/tutorials/bayesian-linear-regression/index.qmd
+++ b/tutorials/bayesian-linear-regression/index.qmd
@@ -41,9 +41,8 @@ using StatsBase
# Functionality for working with scaled identity matrices.
using LinearAlgebra
-# Set a seed for reproducibility.
-using Random
-Random.seed!(0);
+# For ensuring reproducibility.
+using StableRNGs: StableRNG
```
```{julia}
@@ -76,7 +75,7 @@ The next step is to get our data ready for testing. We'll split the `mtcars` dat
select!(data, Not(:Model))
# Split our dataset 70%/30% into training/test sets.
-trainset, testset = map(DataFrame, splitobs(data; at=0.7, shuffle=true))
+trainset, testset = map(DataFrame, splitobs(StableRNG(468), data; at=0.7, shuffle=true))
# Turing requires data in matrix form.
target = :MPG
@@ -143,7 +142,7 @@ With our model specified, we can call the sampler. We will use the No U-Turn Sam
```{julia}
model = linear_regression(train, train_target)
-chain = sample(model, NUTS(), 5_000)
+chain = sample(StableRNG(468), model, NUTS(), 20_000)
```
We can also check the densities and traces of the parameters visually using the `plot` functionality.
@@ -158,7 +157,7 @@ It looks like all parameters have converged.
#| echo: false
let
ess_df = ess(chain)
- @assert minimum(ess_df[:, :ess]) > 500 "Minimum ESS: $(minimum(ess_df[:, :ess])) - not > 700"
+ @assert minimum(ess_df[:, :ess]) > 500 "Minimum ESS: $(minimum(ess_df[:, :ess])) - not > 500"
@assert mean(ess_df[:, :ess]) > 2_000 "Mean ESS: $(mean(ess_df[:, :ess])) - not > 2000"
@assert maximum(ess_df[:, :ess]) > 3_500 "Maximum ESS: $(maximum(ess_df[:, :ess])) - not > 3500"
end
@@ -243,9 +242,11 @@ let
ols_test_loss = msd(test_prediction_ols, testset[!, target])
@assert bayes_train_loss < bayes_test_loss "Bayesian training loss ($bayes_train_loss) >= Bayesian test loss ($bayes_test_loss)"
@assert ols_train_loss < ols_test_loss "OLS training loss ($ols_train_loss) >= OLS test loss ($ols_test_loss)"
- @assert isapprox(bayes_train_loss, ols_train_loss; rtol=0.01) "Difference between Bayesian training loss ($bayes_train_loss) and OLS training loss ($ols_train_loss) unexpectedly large!"
- @assert isapprox(bayes_test_loss, ols_test_loss; rtol=0.05) "Difference between Bayesian test loss ($bayes_test_loss) and OLS test loss ($ols_test_loss) unexpectedly large!"
+ @assert bayes_train_loss > ols_train_loss "Bayesian training loss ($bayes_train_loss) <= OLS training loss ($bayes_train_loss)"
+ @assert bayes_test_loss < ols_test_loss "Bayesian test loss ($bayes_test_loss) >= OLS test loss ($ols_test_loss)"
end
```
-As we can see above, OLS and our Bayesian model fit our training and test data set about the same.
+We can see from this that both linear regression techniques perform fairly similarly.
+The Bayesian linear regression approach performs worse on the training set, but better on the test set.
+This indicates that the Bayesian approach is more able to generalise to unseen data, i.e., it is not overfitting the training data as much.
diff --git a/tutorials/bayesian-poisson-regression/index.qmd b/tutorials/bayesian-poisson-regression/index.qmd
index dbbd5fb87..f82c866bb 100755
--- a/tutorials/bayesian-poisson-regression/index.qmd
+++ b/tutorials/bayesian-poisson-regression/index.qmd
@@ -182,7 +182,10 @@ We use the Gelman, Rubin, and Brooks Diagnostic to check whether our chains have
We expect the chains to have converged. This is because we have taken sufficient number of iterations (1500) for the NUTS sampler. However, in case the test fails, then we will have to take a larger number of iterations, resulting in longer computation time.
```{julia}
-gelmandiag(chain)
+# Because some of the sampler statistics are `missing`, we need to extract only
+# the parameters and then concretize the array so that `gelmandiag` can be computed.
+parameter_chain = MCMCChains.concretize(MCMCChains.get_sections(chain, :parameters))
+gelmandiag(parameter_chain)
```
From the above diagnostic, we can conclude that the chains have converged because the PSRF values of the coefficients are close to 1.
diff --git a/tutorials/gaussian-mixture-models/index.qmd b/tutorials/gaussian-mixture-models/index.qmd
index 99db86bc2..bd7595a2c 100755
--- a/tutorials/gaussian-mixture-models/index.qmd
+++ b/tutorials/gaussian-mixture-models/index.qmd
@@ -38,11 +38,11 @@ Random.seed!(3)
# Define Gaussian mixture model.
w = [0.5, 0.5]
-μ = [-3.5, 0.5]
-mixturemodel = MixtureModel([MvNormal(Fill(μₖ, 2), I) for μₖ in μ], w)
+μ = [-2.0, 2.0]
+mixturemodel = MixtureModel([MvNormal(Fill(μₖ, 2), 0.2 * I) for μₖ in μ], w)
# We draw the data points.
-N = 60
+N = 30
x = rand(mixturemodel, N);
```
@@ -145,7 +145,7 @@ let
# μ[1] and μ[2] can switch places, so we sort the values first.
chain = Array(chains[:, ["μ[1]", "μ[2]"], i])
μ_mean = vec(mean(chain; dims=1))
- @assert isapprox(sort(μ_mean), μ; rtol=0.1) "Difference between estimated mean of μ ($(sort(μ_mean))) and data-generating μ ($μ) unexpectedly large!"
+ @assert isapprox(sort(μ_mean), μ; atol=0.5) "Difference between estimated mean of μ ($(sort(μ_mean))) and data-generating μ ($μ) unexpectedly large!"
end
end
```
@@ -212,7 +212,7 @@ let
# μ[1] and μ[2] can no longer switch places. Check that they've found the mean
chain = Array(chains[:, ["μ[1]", "μ[2]"], i])
μ_mean = vec(mean(chain; dims=1))
- @assert isapprox(sort(μ_mean), μ; rtol=0.4) "Difference between estimated mean of μ ($(sort(μ_mean))) and data-generating μ ($μ) unexpectedly large!"
+ @assert isapprox(sort(μ_mean), μ; atol=0.5) "Difference between estimated mean of μ ($(sort(μ_mean))) and data-generating μ ($μ) unexpectedly large!"
end
end
```
@@ -350,7 +350,7 @@ let
# μ[1] and μ[2] can no longer switch places. Check that they've found the mean
chain = Array(chains[:, ["μ[1]", "μ[2]"], i])
μ_mean = vec(mean(chain; dims=1))
- @assert isapprox(sort(μ_mean), μ; rtol=0.4) "Difference between estimated mean of μ ($(sort(μ_mean))) and data-generating μ ($μ) unexpectedly large!"
+ @assert isapprox(sort(μ_mean), μ; atol=0.5) "Difference between estimated mean of μ ($(sort(μ_mean))) and data-generating μ ($μ) unexpectedly large!"
end
end
```
diff --git a/usage/mode-estimation/index.qmd b/usage/mode-estimation/index.qmd
index a592a83dd..cf49e84c7 100755
--- a/usage/mode-estimation/index.qmd
+++ b/usage/mode-estimation/index.qmd
@@ -37,7 +37,7 @@ data = [1.5, 2.0]
model = gdemo(data)
```
-Finding the maximum aposteriori or maximum likelihood parameters is as simple as
+Finding the maximum a posteriori or maximum likelihood parameters is as simple as
```{julia}
# Generate a MLE estimate.
@@ -80,6 +80,14 @@ maximum_likelihood(
When providing values to arguments like `initial_params` the parameters are typically specified in the order in which they appear in the code of the model, so in this case first `s²` then `m`. More precisely it's the order returned by `Turing.Inference.getparams(model, DynamicPPL.VarInfo(model))`.
+::: {.callout-note}
+## Initialisation strategies and consistency with MCMC sampling
+
+Since Turing v0.41, for MCMC sampling, the `initial_params` argument must be a `DynamicPPL.AbstractInitStrategy` as described in [the sampling options page]({{< meta usage-sampling-options >}}#specifying-initial-parameters)).
+The optimisation interface has not yet been updated to use this; thus, initial parameters are still specified as Vectors.
+We expect that this will be changed in the near future.
+:::
+
We can also do constrained optimisation, by providing either intervals within which the parameters must stay, or costraint functions that they need to respect. For instance, here's how one can find the MLE with the constraint that the variance must be less than 0.01 and the mean must be between -1 and 1.:
```{julia}
diff --git a/usage/sampling-options/index.qmd b/usage/sampling-options/index.qmd
index a9ec93f2c..986fefcb4 100644
--- a/usage/sampling-options/index.qmd
+++ b/usage/sampling-options/index.qmd
@@ -108,36 +108,32 @@ typeof(transitions)
In Turing.jl, initial parameters for MCMC sampling can be specified using the `initial_params` keyword argument.
-For **single-chain sampling**, the AbstractMCMC interface generally expects that you provide a completely flattened vector of parameters.
-
-```{julia}
-chn = sample(demo_model(), MH(), 5; initial_params=[1.0, -5.0])
-chn[:x][1], chn[:y][1]
-```
+::: {.callout-important}
+## New `initial_params` in Turing v0.41
-::: {.callout-note}
-Note that a number of samplers use warm-up steps by default (see the [Thinning and Warmup section below](#thinning-and-warmup)), so `chn[:param][1]` may not correspond to the exact initial parameters you provided.
-`MH()` does not do this, which is why we use it here.
+In Turing v0.41, the permitted values for `initial_params` are different. In particular, `Vector`s are no longer permitted, because they are semantically ambiguous (the way in which indices correspond to parameters relies on DynamicPPL internals). This page describes the new behaviour.
:::
-Note that for Turing models, the use of `Vector` can be extremely error-prone as the order of parameters in the flattened vector is not always obvious (especially if there are parameters with non-trivial types).
-In general, parameters should be provided in the order they are defined in the model.
-A relatively 'safe' way of obtaining parameters in the correct order is to first generate a `VarInfo`, and then linearise that:
+For **single-chain sampling** with Turing, the `initial_params` keyword argument should be a `DynamicPPL.AbstractInitStrategy`.
+There are three main options, all of which are re-exported by Turing.
-```{julia}
-using DynamicPPL
-vi = VarInfo(demo_model())
-initial_params = vi[:]
-```
+- `InitFromPrior()`: generate initial parameters by sampling from the prior
+- `InitFromUniform(lower, upper)`: generate initial parameters by sampling uniformly from the given bounds in linked space
+- `InitFromParams(namedtuple_or_dict)`: use the provided initial parameters, supplied either as a `NamedTuple` or a `Dict{<:VarName}`
-To avoid this situation, you can also use `NamedTuple` to specify initial parameters.
+If `initial_params` is unspecified, each sampler will use its own default initialisation strategy: for most samplers this is `InitFromPrior` but for Hamiltonian samplers it is `InitFromUniform(-2, 2)` (which mimics the behaviour of Stan).
```{julia}
-chn = sample(demo_model(), MH(), 5; initial_params=(y=2.0, x=-6.0))
+chn = sample(demo_model(), MH(), 5; initial_params=InitFromParams((x = 1.0, y = -5.0)))
chn[:x][1], chn[:y][1]
```
-This works even for parameters with more complex types.
+::: {.callout-note}
+Note that a number of samplers use warm-up steps by default (see the [Thinning and Warmup section below](#thinning-and-warmup)), so `chn[:param][1]` may not correspond to the exact initial parameters you provided.
+`MH()` does not do this, which is why we use it here.
+:::
+
+This approach scales for parameters with more complex types.
```{julia}
@model function demo_complex()
@@ -145,35 +141,21 @@ This works even for parameters with more complex types.
y ~ MvNormal(zeros(3), I)
end
init_x, init_y = rand(LKJCholesky(3, 0.5)), rand(MvNormal(zeros(3), I))
-chn = sample(demo_complex(), MH(), 5; initial_params=(x=init_x, y=init_y));
+chn = sample(demo_complex(), MH(), 5; initial_params=InitFromParams((x=init_x, y=init_y)));
```
For **multiple-chain sampling**, the `initial_params` keyword argument should be a vector with length equal to the number of chains being sampled.
Each element of this vector should be the initial parameters for the corresponding chain, as described above.
-Thus, for example, a vector of vectors, or a vector of `NamedTuple`s, can be used.
+Thus, for example, you can supply a vector of `AbstractInitStrategy` objects.
If you want to use the same initial parameters for all chains, you can use `fill`:
```{julia}
-initial_params = fill((x=1.0, y=-5.0), 3)
+initial_params = fill(InitFromParams((x=1.0, y=-5.0)), 3)
chn = sample(demo_model(), MH(), MCMCThreads(), 5, 3; initial_params=initial_params)
chn[:x][1,:], chn[:y][1,:]
```
-::: {.callout-important}
-## Upcoming changes in Turing v0.41
-
-In Turing v0.41, instead of providing _initial parameters_, users will have to provide what is conceptually an _initialisation strategy_.
-The keyword argument is still `initial_params`, but the permitted values (for single-chain sampling) will either be:
-
-- `InitFromPrior()`: generate initial parameters by sampling from the prior
-- `InitFromUniform(lower, upper)`: generate initial parameters by sampling uniformly from the given bounds in linked space
-- `InitFromParams(namedtuple_or_dict)`: use the provided initial parameters, supplied either as a `NamedTuple` or a `Dict{<:VarName}`
-
-Initialisation with `Vector` will be fully removed due to its inherent ambiguity.
-Initialisation with a raw `NamedTuple` will still be supported (it will simply be wrapped in `InitFromParams()`); but we expect to remove this eventually, so it will be more future-proof to use `InitFromParams()` directly.
-
-For multiple chains, the same as above applies: the `initial_params` keyword argument should be a vector of initialisation strategies, one per chain.
-:::
+In Turing v0.41, initialisation with a raw `NamedTuple` is still supported (it will simply be wrapped in `InitFromParams()`); but we expect to remove this eventually, so it will likely be more future-proof to wrap this in `InitFromParams()` yourself.
## Saving and resuming sampling
@@ -190,10 +172,10 @@ chn1 = sample(rng, demo_model(), MH(), 5; save_state=true);
```
For `MCMCChains.Chains`, this results in the final sampler state being stored inside the chain metadata.
-You can access it using `DynamicPPL.loadstate`:
+You can access it using `Turing.loadstate`:
```{julia}
-saved_state = DynamicPPL.loadstate(chn1)
+saved_state = Turing.loadstate(chn1)
typeof(saved_state)
```
@@ -211,6 +193,13 @@ Note that the exact format saved in `chn.info.samplerstate`, and that expected b
For single-chain sampling, the saved state, and the required initial state, is just a single sampler state.
For multiple-chain sampling, it is a vector of states, one per chain.
+::: {.callout-warning}
+## `resume_from`
+
+The `resume_from` argument has been removed in Turing v0.41; please use `initial_state=loadstate(chn)` instead, as described here.
+In v0.41, `loadstate` is also exported from Turing rather than DynamicPPL.
+:::
+
This means that, for example, after sampling a single chain, you could sample three chains that branch off from that final state:
```{julia}
@@ -226,7 +215,7 @@ If both are provided, `initial_params` will be silently ignored.
```{julia}
chn2 = sample(rng, demo_model(), MH(), 5;
- initial_state=saved_state, initial_params=(x=0.0, y=0.0)
+ initial_state=saved_state, initial_params=InitFromParams((x=0.0, y=0.0))
)
chn2[:x][1], chn2[:y][1]
```
diff --git a/usage/troubleshooting/index.qmd b/usage/troubleshooting/index.qmd
index 380378cd5..cba2c6744 100755
--- a/usage/troubleshooting/index.qmd
+++ b/usage/troubleshooting/index.qmd
@@ -79,7 +79,7 @@ end
model = initial_bad2() | (y = 50.0,)
```
-The problem here is that HMC attempts to find initial values for parameters inside the region of `[-2, 2]`, _after_ the parameters have been transformed to unconstrained space.
+The problem here is that HMC's default initialisation strategy is `InitFromUniform(-2, 2)`: in other words, it attempts to find initial values for transformed parameters inside the region of `[-2, 2]`.
For a distribution of `Exponential(100)`, the appropriate transformation is `log(x)` (see the [variable transformation docs]({{< meta dev-transforms-distributions >}}) for more info).
Thus, HMC attempts to find initial values of `log(x)` in the region of `[-2, 2]`, which corresponds to `x` in the region of `[exp(-2), exp(2)]` = `[0.135, 7.39]`.
@@ -94,11 +94,16 @@ logjoint(model, (x = exp(-2),))
logjoint(model, (x = exp(2),))
```
-The most direct way of fixing this is to manually provide a set of initial parameters that are valid.
-For example, you can obtain a set of initial parameters with `rand(Vector, model)`, and then pass this as the `initial_params` keyword argument to `sample`:
+You can fix this by overriding the default initialisation strategy (discussed in more detail in [the sampling options page]({{< meta usage-sampling-options >}}#specifying-initial-parameters)).
```{julia}
-sample(model, NUTS(), 1000; initial_params=rand(Vector, model))
+# Use initial parameters drawn from the model's prior.
+sample(model, NUTS(), 1000; initial_params=InitFromPrior())
+```
+
+```{julia}
+# Use manually specified initial parameters (always in untransformed space).
+sample(model, NUTS(), 1000; initial_params=InitFromParams((x = 60.0,)))
```
More generally, you may also consider reparameterising the model to avoid such issues.
@@ -159,3 +164,5 @@ A better solution is to pass a type as a parameter to the model:
end
sample(forwarddiff_working2(), NUTS(; adtype=AutoForwardDiff()), 10)
```
+
+Alternatively, you can use a different AD backend such as Mooncake which does not rely on dual numbers.