diff --git a/Project.toml b/Project.toml index 1dec3bc15..fa5969b5e 100644 --- a/Project.toml +++ b/Project.toml @@ -19,6 +19,8 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" LinearMaps = "7a12625a-238d-50fd-b39a-03d52299707e" LowRankApprox = "898213cb-b102-5a47-900c-97e73b919f73" MCMCChains = "c7f686f2-ff18-58e9-bc7b-31028e88f75d" +Manifolds = "1cead3c2-87b3-11e9-0ccd-23c62b72b94e" +Manopt = "0fc0a36d-df90-57f3-8f93-d78a9fc72bb5" Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" ProgressBars = "49802e3a-d2f1-5c88-81d8-b72133a6f568" @@ -47,6 +49,8 @@ KernelFunctions = "0.10.64, 0.11" LinearMaps = "3.11.4" LowRankApprox = "0.5.5" MCMCChains = "7" +Manifolds = "0.11.19" +Manopt = "0.5.34" Plots = "1.41.1" Printf = "1" ProgressBars = "1" diff --git a/docs/Manifest.toml b/docs/Manifest.toml index 188bad891..101b149f2 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -1,13 +1,13 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.11.5" +julia_version = "1.11.9" manifest_format = "2.0" project_hash = "e4d965798d55f5903483b71f545533e62ea32fdf" [[deps.ADTypes]] -git-tree-sha1 = "8be2ae325471fc20b11c27bb34b518541d07dd3a" +git-tree-sha1 = "bbc22a9a08a0ef6460041086d8a7b27940ed4ffd" uuid = "47edcb42-4c32-4615-8424-f2b9edc5f35b" -version = "1.19.0" +version = "1.22.0" [deps.ADTypes.extensions] ADTypesChainRulesCoreExt = "ChainRulesCore" @@ -48,21 +48,53 @@ uuid = "99985d1d-32ba-4be9-9821-2ec096f28918" version = "0.5.24" [[deps.AbstractMCMC]] -deps = ["BangBang", "ConsoleProgressMonitor", "Distributed", "LogDensityProblems", "Logging", "LoggingExtras", "ProgressLogging", "Random", "StatsBase", "TerminalLoggers", "Transducers"] -git-tree-sha1 = "87e63dcb990029346b091b170252f3c416568afc" +deps = ["BangBang", "ConsoleProgressMonitor", "Dates", "Distributed", "LogDensityProblems", "Logging", "LoggingExtras", "ProgressLogging", "Random", "StatsBase", "TerminalLoggers", "UUIDs"] +git-tree-sha1 = "8ac6182431567907e0d5170bcac6dd48fa541f78" uuid = "80f14c24-f653-4e6a-9b94-39d6b0f70001" -version = "4.4.2" +version = "5.15.1" + + [deps.AbstractMCMC.extensions] + AbstractMCMCOnlineStatsExt = "OnlineStats" + AbstractMCMCTensorBoardLoggerExt = "TensorBoardLogger" + + [deps.AbstractMCMC.weakdeps] + OnlineStats = "a15396b6-48d5-5d58-9928-6d29437db91e" + TensorBoardLogger = "899adc3e-224a-11e9-021f-63837185c80f" [[deps.AbstractTrees]] git-tree-sha1 = "2d9c9a55f9c93e8887ad391fbae72f8ef55e1177" uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" version = "0.4.5" +[[deps.Accessors]] +deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "MacroTools"] +git-tree-sha1 = "2eeb2c9bef11013efc6f8f97f32ee59b146b09fb" +uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" +version = "0.1.44" + + [deps.Accessors.extensions] + AxisKeysExt = "AxisKeys" + IntervalSetsExt = "IntervalSets" + LinearAlgebraExt = "LinearAlgebra" + StaticArraysExt = "StaticArrays" + StructArraysExt = "StructArrays" + TestExt = "Test" + UnitfulExt = "Unitful" + + [deps.Accessors.weakdeps] + AxisKeys = "94b1ba4f-4ee9-5380-92f1-94cde586c3c5" + IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" + LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" + StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" + StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" + [[deps.Adapt]] deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "7e35fca2bdfba44d797c53dfe63a51fabf39bfc0" +git-tree-sha1 = "0761717147821d696c9470a7a86364b2fbd22fd8" uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "4.4.0" +version = "4.5.2" weakdeps = ["SparseArrays", "StaticArrays"] [deps.Adapt.extensions] @@ -70,10 +102,10 @@ weakdeps = ["SparseArrays", "StaticArrays"] AdaptStaticArraysExt = "StaticArrays" [[deps.AdvancedMH]] -deps = ["AbstractMCMC", "Distributions", "FillArrays", "LinearAlgebra", "LogDensityProblems", "Random", "Requires"] -git-tree-sha1 = "b2a1602952739e589cf5e2daff1274a49f22c9a4" +deps = ["AbstractMCMC", "Distributions", "DocStringExtensions", "FillArrays", "LinearAlgebra", "LogDensityProblems", "Random", "Requires"] +git-tree-sha1 = "62ddbccf0ce5c26f8ef3cebe4bedef6b1599d616" uuid = "5b7e9947-ddc0-4b3f-9b55-0d8042f74170" -version = "0.7.5" +version = "0.8.10" [deps.AdvancedMH.extensions] AdvancedMHForwardDiffExt = ["DiffResults", "ForwardDiff"] @@ -101,6 +133,12 @@ version = "2.5.0" uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" version = "1.1.2" +[[deps.ArnoldiMethod]] +deps = ["LinearAlgebra", "Random", "StaticArrays"] +git-tree-sha1 = "d57bd3762d308bded22c3b82d033bff85f6195c6" +uuid = "ec485272-7323-5ecc-a04f-4719b315124d" +version = "0.4.0" + [[deps.Arpack]] deps = ["Arpack_jll", "Libdl", "LinearAlgebra", "Logging"] git-tree-sha1 = "9b9b347613394885fd1c8c7729bfc60528faa436" @@ -108,18 +146,19 @@ uuid = "7d9fca2a-8960-54d3-9f78-7d1dccf2cb97" version = "0.5.4" [[deps.Arpack_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "OpenBLAS_jll", "Pkg"] -git-tree-sha1 = "5ba6c757e8feccf03a1554dfaf3e26b3cfc7fd5e" +deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "libblastrampoline_jll"] +git-tree-sha1 = "7f54761502ff149a9d492e4acefe9805898e29b3" uuid = "68821587-b530-5797-8361-c406ea357684" -version = "3.5.1+1" +version = "3.5.2+0" [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra"] -git-tree-sha1 = "d81ae5489e13bc03567d4fbbb06c546a5e53c857" +git-tree-sha1 = "54f895554d05c83e3dd59f6a396671dae8999573" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.22.0" +version = "7.24.0" [deps.ArrayInterface.extensions] + ArrayInterfaceAMDGPUExt = "AMDGPU" ArrayInterfaceBandedMatricesExt = "BandedMatrices" ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" ArrayInterfaceCUDAExt = "CUDA" @@ -134,6 +173,7 @@ version = "7.22.0" ArrayInterfaceTrackerExt = "Tracker" [deps.ArrayInterface.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" BandedMatrices = "aae01518-5342-5314-be14-df237901396f" BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" @@ -164,16 +204,17 @@ uuid = "39de3d68-74b9-583c-8d2d-e117c070f3a9" version = "0.4.8" [[deps.BangBang]] -deps = ["Compat", "ConstructionBase", "InitialValues", "LinearAlgebra", "Requires", "Setfield", "Tables"] -git-tree-sha1 = "7aa7ad1682f3d5754e3491bb59b8103cae28e3a3" +deps = ["Accessors", "ConstructionBase", "InitialValues", "LinearAlgebra"] +git-tree-sha1 = "cceb62468025be98d42a5dc581b163c20896b040" uuid = "198e06fe-97b7-11e9-32a5-e1d131e6ad66" -version = "0.3.40" +version = "0.4.9" [deps.BangBang.extensions] BangBangChainRulesCoreExt = "ChainRulesCore" BangBangDataFramesExt = "DataFrames" BangBangStaticArraysExt = "StaticArrays" BangBangStructArraysExt = "StructArrays" + BangBangTablesExt = "Tables" BangBangTypedTablesExt = "TypedTables" [deps.BangBang.weakdeps] @@ -181,22 +222,18 @@ version = "0.3.40" DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" + Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" TypedTables = "9d95f2ec-7b3d-5a63-8d20-e2491e220bb9" [[deps.Base64]] uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" version = "1.11.0" -[[deps.Baselet]] -git-tree-sha1 = "aebf55e6d7795e02ca500a689d326ac979aaf89e" -uuid = "9718e550-a3fa-408a-8086-8db961cd8217" -version = "0.1.1" - [[deps.BenchmarkTools]] -deps = ["Compat", "JSON", "Logging", "Printf", "Profile", "Statistics", "UUIDs"] -git-tree-sha1 = "7fecfb1123b8d0232218e2da0c213004ff15358d" +deps = ["Compat", "JSON", "Logging", "PrecompileTools", "Printf", "Profile", "Statistics", "UUIDs"] +git-tree-sha1 = "9670d3febc2b6da60a0ae57846ba74670290653f" uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" -version = "1.6.3" +version = "1.8.0" [[deps.BitTwiddlingConvenienceFunctions]] deps = ["Static"] @@ -217,31 +254,31 @@ uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" version = "0.2.7" [[deps.Cairo_jll]] -deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] -git-tree-sha1 = "fde3bf89aead2e723284a8ff9cdf5b551ed700e8" +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "d0efe2c6fdcdaa1c161d206aa8b933788397ec71" uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" -version = "1.18.5+0" +version = "1.18.6+0" [[deps.CalibrateEmulateSample]] -deps = ["AbstractGPs", "AbstractMCMC", "AdvancedMH", "ChunkSplitters", "Conda", "Distributions", "DocStringExtensions", "EnsembleKalmanProcesses", "ForwardDiff", "GaussianProcesses", "KernelFunctions", "LinearAlgebra", "LinearMaps", "LowRankApprox", "MCMCChains", "Pkg", "Printf", "ProgressBars", "PyCall", "Random", "RandomFeatures", "ReverseDiff", "ScikitLearn", "StableRNGs", "Statistics", "StatsBase", "TSVD"] +deps = ["AbstractGPs", "AbstractMCMC", "AdvancedMH", "ChunkSplitters", "Conda", "Distributions", "DocStringExtensions", "EnsembleKalmanProcesses", "ForwardDiff", "GaussianProcesses", "KernelFunctions", "LinearAlgebra", "LinearMaps", "LowRankApprox", "MCMCChains", "Manifolds", "Manopt", "Pkg", "Printf", "ProgressBars", "PyCall", "Random", "RandomFeatures", "ReverseDiff", "ScikitLearn", "StableRNGs", "Statistics", "StatsBase", "TSVD"] path = ".." uuid = "95e48a1f-0bec-4818-9538-3db4340308e3" -version = "0.7.0" +version = "1.0.0" [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "e4c6a16e77171a5f5e25e9646617ab1c276c5607" +git-tree-sha1 = "12177ad6b3cad7fd50c8b3825ce24a99ad61c18f" uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.26.0" +version = "1.26.1" weakdeps = ["SparseArrays"] [deps.ChainRulesCore.extensions] ChainRulesCoreSparseArraysExt = "SparseArrays" [[deps.ChunkSplitters]] -git-tree-sha1 = "63a3903063d035260f0f6eab00f517471c5dc784" +git-tree-sha1 = "1c52c8e2673edc030191177ff1aee42d25149acb" uuid = "ae650224-84b6-46f8-82ea-d812ca08434e" -version = "3.1.2" +version = "3.2.0" [[deps.CloseOpenIntervals]] deps = ["Static", "StaticArrayInterface"] @@ -261,6 +298,38 @@ git-tree-sha1 = "962834c22b66e32aa10f7611c08c8ca4e20749a9" uuid = "944b1d66-785c-5afd-91f1-9de20f533193" version = "0.7.8" +[[deps.ColorSchemes]] +deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] +git-tree-sha1 = "b0fd3f56fa442f81e0a47815c92245acfaaa4e34" +uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" +version = "3.31.0" + +[[deps.ColorTypes]] +deps = ["FixedPointNumbers", "Random"] +git-tree-sha1 = "67e11ee83a43eb71ddc950302c53bf33f0690dfe" +uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" +version = "0.12.1" +weakdeps = ["StyledStrings"] + + [deps.ColorTypes.extensions] + StyledStringsExt = "StyledStrings" + +[[deps.ColorVectorSpace]] +deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] +git-tree-sha1 = "8b3b6f87ce8f65a2b4f857528fd8d70086cd72b1" +uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" +version = "0.11.0" +weakdeps = ["SpecialFunctions"] + + [deps.ColorVectorSpace.extensions] + SpecialFunctionsExt = "SpecialFunctions" + +[[deps.Colors]] +deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] +git-tree-sha1 = "37ea44092930b1811e666c3bc38065d7d87fcc74" +uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" +version = "0.13.1" + [[deps.CommonSubexpressions]] deps = ["MacroTools"] git-tree-sha1 = "cda2cfaebb4be89c9084adaca7dd7333369715c5" @@ -321,9 +390,9 @@ weakdeps = ["IntervalSets", "LinearAlgebra", "StaticArrays"] [[deps.Convex]] deps = ["AbstractTrees", "BenchmarkTools", "LDLFactorizations", "LinearAlgebra", "MathOptInterface", "OrderedCollections", "SparseArrays", "Test"] -git-tree-sha1 = "dec769959be3af9ba94970b1f14b31c196b0fb9e" +git-tree-sha1 = "b42f0670988b3ee7bfcf0d9ff0f9243a2736963f" uuid = "f65535da-76fb-5f13-bab9-19810c17039a" -version = "0.16.4" +version = "0.16.5" [[deps.CpuId]] deps = ["Markdown"] @@ -343,9 +412,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 = "d8928e9169ff76c6281f39a659f9bca3a573f24c" +git-tree-sha1 = "5fab31e2e01e70ad66e3e24c968c264d1cf166d6" uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "1.8.1" +version = "1.8.2" [[deps.DataStructures]] deps = ["Compat", "InteractiveUtils", "OrderedCollections"] @@ -363,11 +432,6 @@ deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" version = "1.11.0" -[[deps.DefineSingletons]] -git-tree-sha1 = "0fba8b706d0178b4dc7fd44a96a92382c9065c2c" -uuid = "244e2a9f-e319-4986-a169-4d1fe445cd52" -version = "0.1.2" - [[deps.DiffResults]] deps = ["StaticArraysCore"] git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" @@ -382,9 +446,9 @@ version = "1.15.1" [[deps.DifferentiationInterface]] deps = ["ADTypes", "LinearAlgebra"] -git-tree-sha1 = "80bd15222b3e8d0bc70d921d2201aa0084810ce5" +git-tree-sha1 = "d0250552e42bf7cc36479fd38a6e30004c9e8c2b" uuid = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63" -version = "0.7.12" +version = "0.7.17" [deps.DifferentiationInterface.extensions] DifferentiationInterfaceChainRulesCoreExt = "ChainRulesCore" @@ -394,7 +458,7 @@ version = "0.7.12" DifferentiationInterfaceFiniteDiffExt = "FiniteDiff" DifferentiationInterfaceFiniteDifferencesExt = "FiniteDifferences" DifferentiationInterfaceForwardDiffExt = ["ForwardDiff", "DiffResults"] - DifferentiationInterfaceGPUArraysCoreExt = "GPUArraysCore" + DifferentiationInterfaceGPUArraysCoreExt = ["GPUArraysCore", "Adapt"] DifferentiationInterfaceGTPSAExt = "GTPSA" DifferentiationInterfaceMooncakeExt = "Mooncake" DifferentiationInterfacePolyesterForwardDiffExt = ["PolyesterForwardDiff", "ForwardDiff", "DiffResults"] @@ -408,6 +472,7 @@ version = "0.7.12" DifferentiationInterfaceZygoteExt = ["Zygote", "ForwardDiff"] [deps.DifferentiationInterface.weakdeps] + Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" DiffResults = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" Diffractor = "9f5e2b26-1114-432f-b630-d3fe2085c51c" @@ -448,9 +513,9 @@ version = "1.11.0" [[deps.Distributions]] deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] -git-tree-sha1 = "3bc002af51045ca3b47d2e1787d6ce02e68b943a" +git-tree-sha1 = "e421c1938fafab0165b04dc1a9dbe2a26272952c" uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.25.122" +version = "0.25.125" [deps.Distributions.extensions] DistributionsChainRulesCoreExt = "ChainRulesCore" @@ -469,9 +534,9 @@ version = "0.9.5" [[deps.Documenter]] deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "CodecZlib", "Dates", "DocStringExtensions", "Downloads", "Git", "IOCapture", "InteractiveUtils", "JSON", "Logging", "Markdown", "MarkdownAST", "Pkg", "PrecompileTools", "REPL", "RegistryInstances", "SHA", "TOML", "Test", "Unicode"] -git-tree-sha1 = "70c521ca3a23c576e12655d15963977c9766c26b" +git-tree-sha1 = "56e9c37b5e7c3b4f080ab1da18d72d5c290e184a" uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "1.16.0" +version = "1.17.0" [[deps.Downloads]] deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] @@ -491,10 +556,10 @@ uuid = "2904ab23-551e-5aed-883f-487f97af5226" version = "0.2.4" [[deps.EnsembleKalmanProcesses]] -deps = ["Convex", "Distributions", "DocStringExtensions", "FFMPEG", "GaussianRandomFields", "Interpolations", "LinearAlgebra", "MathOptInterface", "Optim", "QuadGK", "Random", "RecipesBase", "SCS", "SparseArrays", "Statistics", "StatsBase", "TOML", "TSVD"] -git-tree-sha1 = "52faab1c57dac15c161f60f0c1d94ebb110ea3c8" +deps = ["Convex", "Distributions", "DocStringExtensions", "FFMPEG", "GaussianRandomFields", "Interpolations", "LinearAlgebra", "MathOptInterface", "Optim", "QuadGK", "Random", "RecipesBase", "SCS", "SparseArrays", "Statistics", "StatsBase", "TOML"] +git-tree-sha1 = "bb39ccc7bd5f7e8f078a987820044d85d61df72b" uuid = "aa8a2aa5-91d8-4396-bcef-d4f2ec43552d" -version = "2.6.0" +version = "2.7.0" [deps.EnsembleKalmanProcesses.extensions] EnsembleKalmanProcessesMakieExt = "Makie" @@ -503,15 +568,15 @@ version = "2.6.0" Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" [[deps.EnumX]] -git-tree-sha1 = "bddad79635af6aec424f53ed8aad5d7555dc6f00" +git-tree-sha1 = "c49898e8438c828577f04b92fc9368c388ac783c" uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" -version = "1.0.5" +version = "1.0.7" [[deps.Expat_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "27af30de8b5445644e8ffe3bcb0d72049c089cf1" +git-tree-sha1 = "8f05e9a2e7c2e3eb524102bb2926c5743c07fbe1" uuid = "2e619515-83b5-522b-bb60-26c02a35a201" -version = "2.7.3+0" +version = "2.8.0+0" [[deps.FFMPEG]] deps = ["FFMPEG_jll"] @@ -520,10 +585,16 @@ uuid = "c87230d0-a227-11e9-1b43-d7ebe4e7570a" version = "0.4.5" [[deps.FFMPEG_jll]] -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 = "ccc81ba5e42497f4e76553a5545665eed577a663" +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", "libva_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "cac41ca6b2d399adfc95e51240566f8a60a80806" uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" -version = "8.0.0+0" +version = "8.1.0+0" + +[[deps.FFTA]] +deps = ["AbstractFFTs", "DocStringExtensions", "LinearAlgebra", "MuladdMacro", "Primes", "Random", "Reexport"] +git-tree-sha1 = "65e55303b72f4a567a51b174dd2c47496efeb95a" +uuid = "b86e33f2-c0db-4aa1-a6e0-ab43e668529e" +version = "0.3.1" [[deps.FFTW]] deps = ["AbstractFFTs", "FFTW_jll", "Libdl", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] @@ -533,15 +604,15 @@ version = "1.10.0" [[deps.FFTW_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "6d6219a004b8cf1e0b4dbe27a2860b8e04eba0be" +git-tree-sha1 = "6866aec60ef98e3164cd8d6855225684207e9dff" uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" -version = "3.3.11+0" +version = "3.3.12+0" [[deps.FastGaussQuadrature]] deps = ["LinearAlgebra", "SpecialFunctions", "StaticArrays"] -git-tree-sha1 = "58d83dd5a78a36205bdfddb82b1bb67682e64487" +git-tree-sha1 = "0044e9f5e49a57e88205e8f30ab73928b05fe5b6" uuid = "442a2c76-b920-505d-bb47-c5924d526838" -version = "0.4.9" +version = "1.1.0" [[deps.FileWatching]] uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" @@ -549,21 +620,22 @@ version = "1.11.0" [[deps.FillArrays]] deps = ["LinearAlgebra"] -git-tree-sha1 = "5bfcd42851cf2f1b303f51525a54dc5e98d408a3" +git-tree-sha1 = "2f979084d1e13948a3352cf64a25df6bd3b4dca3" uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "1.15.0" -weakdeps = ["PDMats", "SparseArrays", "Statistics"] +version = "1.16.0" +weakdeps = ["PDMats", "SparseArrays", "StaticArrays", "Statistics"] [deps.FillArrays.extensions] FillArraysPDMatsExt = "PDMats" FillArraysSparseArraysExt = "SparseArrays" + FillArraysStaticArraysExt = "StaticArrays" FillArraysStatisticsExt = "Statistics" [[deps.FiniteDiff]] deps = ["ArrayInterface", "LinearAlgebra", "Setfield"] -git-tree-sha1 = "9340ca07ca27093ff68418b7558ca37b05f8aeb1" +git-tree-sha1 = "f7017a4f337f8df189fcce98e32b67a1298a2115" uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" -version = "2.29.0" +version = "2.31.0" [deps.FiniteDiff.extensions] FiniteDiffBandedMatricesExt = "BandedMatrices" @@ -577,23 +649,23 @@ version = "2.29.0" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" +[[deps.FixedPointNumbers]] +deps = ["Statistics"] +git-tree-sha1 = "05882d6995ae5c12bb5f36dd2ed3f61c98cbb172" +uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +version = "0.8.5" + [[deps.Fontconfig_jll]] deps = ["Artifacts", "Bzip2_jll", "Expat_jll", "FreeType2_jll", "JLLWrappers", "Libdl", "Libuuid_jll", "Zlib_jll"] git-tree-sha1 = "f85dac9a96a01087df6e3a749840015a0ca3817d" uuid = "a3f928ae-7b40-5064-980b-68af3947d34b" version = "2.17.1+0" -[[deps.Formatting]] -deps = ["Logging", "Printf"] -git-tree-sha1 = "fb409abab2caf118986fc597ba84b50cbaf00b87" -uuid = "59287772-0a20-5a39-b81b-1366585eb4c0" -version = "0.4.3" - [[deps.ForwardDiff]] deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] -git-tree-sha1 = "afb7c51ac63e40708a3071f80f5e84a752299d4f" +git-tree-sha1 = "cddeab6487248a39dae1a960fff0ac17b2a28888" uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "0.10.39" +version = "1.3.3" weakdeps = ["StaticArrays"] [deps.ForwardDiff.extensions] @@ -601,9 +673,9 @@ weakdeps = ["StaticArrays"] [[deps.FreeType2_jll]] deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "2c5512e11c791d1baed2049c5652441b28fc6a31" +git-tree-sha1 = "70329abc09b886fd2c5d94ad2d9527639c421e3e" uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" -version = "2.13.4+0" +version = "2.14.3+1" [[deps.FriBidi_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -629,9 +701,9 @@ version = "1.11.0" [[deps.GaussianProcesses]] deps = ["Distances", "Distributions", "ElasticArrays", "ElasticPDMats", "FastGaussQuadrature", "ForwardDiff", "LinearAlgebra", "Optim", "PDMats", "Printf", "ProgressMeter", "Random", "RecipesBase", "ScikitLearnBase", "SpecialFunctions", "StaticArrays", "Statistics", "StatsFuns"] -git-tree-sha1 = "31749ff6868caf6dd50902eec652a724071dbed3" +git-tree-sha1 = "d983b4e1ff0257ed7c51686e6a63926551884373" uuid = "891a1506-143c-57d2-908e-e1f8e92e6de9" -version = "0.12.5" +version = "0.12.6" [[deps.GaussianRandomFields]] deps = ["Arpack", "FFTW", "FastGaussQuadrature", "LinearAlgebra", "Random", "RecipesBase", "SpecialFunctions", "Statistics", "StatsBase"] @@ -659,15 +731,20 @@ version = "3.7.0+0" [[deps.Git_jll]] deps = ["Artifacts", "Expat_jll", "JLLWrappers", "LibCURL_jll", "Libdl", "Libiconv_jll", "OpenSSL_jll", "PCRE2_jll", "Zlib_jll"] -git-tree-sha1 = "b6a684587ebe896d9f68ae777f648205940f0f70" +git-tree-sha1 = "0dd4cfb426924210c8f42742751cbde74b27bfa3" uuid = "f8c6e375-362e-5223-8a59-34ff63f689eb" -version = "2.51.3+0" +version = "2.54.0+0" [[deps.Glib_jll]] deps = ["Artifacts", "GettextRuntime_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] -git-tree-sha1 = "50c11ffab2a3d50192a228c313f05b5b5dc5acb2" +git-tree-sha1 = "24f6def62397474a297bfcec22384101609142ed" uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" -version = "2.86.0+0" +version = "2.86.3+0" + +[[deps.Glossaries]] +git-tree-sha1 = "60a11a815b6113e7024157c31a77a75619d97a23" +uuid = "8f48dd54-e453-4cdc-9500-53b96149560b" +version = "0.1.1" [[deps.Graphite2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -675,6 +752,12 @@ git-tree-sha1 = "8a6dbda1fd736d60cc477d99f2e7a042acfa46e8" uuid = "3b182d85-2403-5c21-9c21-1e1f0cc25472" version = "1.3.15+0" +[[deps.Graphs]] +deps = ["ArnoldiMethod", "DataStructures", "Distributed", "Inflate", "LinearAlgebra", "Random", "SharedArrays", "SimpleTraits", "SparseArrays", "Statistics"] +git-tree-sha1 = "7a98c6502f4632dbe9fb1973a4244eaa3324e84d" +uuid = "86223c79-3864-5bf0-83f7-82e725a168b6" +version = "1.13.1" + [[deps.HarfBuzz_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll"] git-tree-sha1 = "f923f9a774fcf3f5cb761bfa43aeadd689714813" @@ -682,10 +765,16 @@ uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" version = "8.5.1+0" [[deps.HostCPUFeatures]] -deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Static"] -git-tree-sha1 = "8e070b599339d622e9a081d17230d74a5c473293" +deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Preferences", "Static"] +git-tree-sha1 = "af9ab7d1f70739a47f03be78771ebda38c3c71bf" uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" -version = "0.1.17" +version = "0.1.18" + +[[deps.HypergeometricFunctions]] +deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] +git-tree-sha1 = "68c173f4f449de5b438ee67ed0c9c748dc31a2ec" +uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" +version = "0.3.28" [[deps.IOCapture]] deps = ["Logging", "Random"] @@ -698,6 +787,11 @@ git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" version = "0.1.1" +[[deps.Inflate]] +git-tree-sha1 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" +uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" +version = "0.1.5" + [[deps.InitialValues]] git-tree-sha1 = "4da0f88e9a39111c2fa3add390ab15f3a44f3ca3" uuid = "22cec73e-a1b8-11e9-2c92-598750a2cf9c" @@ -716,6 +810,11 @@ version = "1.4.5" ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" Parsers = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" +[[deps.IntegerMathUtils]] +git-tree-sha1 = "4c1acff2dc6b6967e7e750633c50bc3b8d83e617" +uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" +version = "0.1.3" + [[deps.IntelOpenMP_jll]] deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] git-tree-sha1 = "ec1debd61c300961f98064cfb21287613ad7f303" @@ -728,25 +827,26 @@ uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" version = "1.11.0" [[deps.Interpolations]] -deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "Requires", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] -git-tree-sha1 = "88a101217d7cb38a7b481ccd50d21876e1d1b0e0" +deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArrays", "Random", "Ratios", "SharedArrays", "SparseArrays", "StaticArrays", "WoodburyMatrices"] +git-tree-sha1 = "65d505fa4c0d7072990d659ef3fc086eb6da8208" uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" -version = "0.15.1" +version = "0.16.2" [deps.Interpolations.extensions] + InterpolationsForwardDiffExt = "ForwardDiff" InterpolationsUnitfulExt = "Unitful" [deps.Interpolations.weakdeps] + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" [[deps.IntervalSets]] -git-tree-sha1 = "03b4f40b4987baa6a653a21f6f33f902af6255f3" +git-tree-sha1 = "79d6bd28c8d9bccc2229784f1bd637689b256377" uuid = "8197267c-284f-5f27-9208-e0e47529a953" -version = "0.7.12" -weakdeps = ["Printf", "Random", "RecipesBase", "Statistics"] +version = "0.7.14" +weakdeps = ["Random", "RecipesBase", "Statistics"] [deps.IntervalSets.extensions] - IntervalSetsPrintfExt = "Printf" IntervalSetsRandomExt = "Random" IntervalSetsRecipesBaseExt = "RecipesBase" IntervalSetsStatisticsExt = "Statistics" @@ -767,9 +867,9 @@ uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" version = "1.3.1" [[deps.IrrationalConstants]] -git-tree-sha1 = "7fd44fd4ff43fc60815f8e764c0f352b83c49151" +git-tree-sha1 = "b2d91fe939cae05960e760110b328288867b5758" uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" -version = "0.1.1" +version = "0.2.6" [[deps.IterTools]] git-tree-sha1 = "42d5f897009e7ff2cf88db414a389e5ed1bdd023" @@ -789,9 +889,9 @@ version = "1.7.1" [[deps.JSON]] deps = ["Dates", "Logging", "Parsers", "PrecompileTools", "StructUtils", "UUIDs", "Unicode"] -git-tree-sha1 = "5b6bb73f555bc753a6153deec3717b8904f5551c" +git-tree-sha1 = "fe23330af47b8ab4e135b2ff65f7398c3a2bfc65" uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" -version = "1.3.0" +version = "1.5.2" [deps.JSON.extensions] JSONArrowExt = ["ArrowTypes"] @@ -799,29 +899,23 @@ version = "1.3.0" [deps.JSON.weakdeps] ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" -[[deps.JSON3]] -deps = ["Dates", "Mmap", "Parsers", "PrecompileTools", "StructTypes", "UUIDs"] -git-tree-sha1 = "411eccfe8aba0814ffa0fdf4860913ed09c34975" -uuid = "0f8b85d8-7281-11e9-16c2-39a750bddbf1" -version = "1.14.3" - - [deps.JSON3.extensions] - JSON3ArrowExt = ["ArrowTypes"] - - [deps.JSON3.weakdeps] - ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" - [[deps.KernelDensity]] -deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] -git-tree-sha1 = "ba51324b894edaf1df3ab16e2cc6bc3280a2f1a7" +deps = ["Distributions", "DocStringExtensions", "FFTA", "Interpolations", "StatsBase"] +git-tree-sha1 = "4260cfc991b8885bf747801fb60dd4503250e478" uuid = "5ab0869b-81aa-558d-bb23-cbf5423bbe9b" -version = "0.6.10" +version = "0.6.11" [[deps.KernelFunctions]] deps = ["ChainRulesCore", "Compat", "CompositionsBase", "Distances", "FillArrays", "Functors", "IrrationalConstants", "LinearAlgebra", "LogExpFunctions", "Random", "Requires", "SpecialFunctions", "Statistics", "StatsBase", "TensorCore", "Test", "ZygoteRules"] -git-tree-sha1 = "0b75b447ee242254ff037402461e5593a84f9ac7" +git-tree-sha1 = "9db545feadff48ec2da8216f589857e7a619df84" uuid = "ec8451be-7e33-11e9-00cf-bbf324bd1392" -version = "0.10.66" +version = "0.10.67" + +[[deps.Kronecker]] +deps = ["LinearAlgebra", "NamedDims", "SparseArrays", "StatsBase"] +git-tree-sha1 = "9253429e28cceae6e823bec9ffde12460d79bb38" +uuid = "2c470bb0-bcc8-11e8-3dad-c9649493f05e" +version = "0.5.5" [[deps.LAME_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -831,9 +925,9 @@ version = "3.100.3+0" [[deps.LDLFactorizations]] deps = ["AMD", "LinearAlgebra", "SparseArrays", "Test"] -git-tree-sha1 = "70f582b446a1c3ad82cf87e62b878668beef9d13" +git-tree-sha1 = "d75c5cb8d6ac9c359ae9eb8e87e446ba9f221dd4" uuid = "40e66cde-538c-5869-a4ad-c39174c6795b" -version = "0.10.1" +version = "0.10.2" [[deps.LLVMOpenMP_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -841,12 +935,6 @@ git-tree-sha1 = "eb62a3deb62fc6d8822c0c4bef73e4412419c5d8" uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" version = "18.1.8+0" -[[deps.LZO_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1c602b1127f4751facb671441ca72715cc95938a" -uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" -version = "2.10.3+0" - [[deps.LaTeXStrings]] git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" @@ -917,21 +1005,21 @@ version = "1.18.0+0" [[deps.Libmount_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "3acf07f130a76f87c041cfb2ff7d7284ca67b072" +git-tree-sha1 = "cc3ad4faf30015a3e8094c9b5b7f19e85bdf2386" uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" -version = "2.41.2+0" +version = "2.42.0+0" [[deps.Libuuid_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "2a7a12fc0a4e7fb773450d17975322aa77142106" +git-tree-sha1 = "d620582b1f0cbe2c72dd1d5bd195a9ce73370ab1" uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" -version = "2.41.2+0" +version = "2.42.0+0" [[deps.LineSearches]] -deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] -git-tree-sha1 = "4adee99b7262ad2a1a4bbbc59d993d24e55ea96f" +deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Printf"] +git-tree-sha1 = "9ea3422d03222c6de679934d1c08f0a99405aa03" uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" -version = "7.4.0" +version = "7.5.1" [[deps.LinearAlgebra]] deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] @@ -1016,16 +1104,16 @@ weakdeps = ["FillArrays"] LowRankMatricesFillArraysExt = "FillArrays" [[deps.MCMCChains]] -deps = ["AbstractMCMC", "AxisArrays", "Dates", "Distributions", "Formatting", "IteratorInterfaceExtensions", "KernelDensity", "LinearAlgebra", "MCMCDiagnosticTools", "MLJModelInterface", "NaturalSort", "OrderedCollections", "PrettyTables", "Random", "RecipesBase", "Serialization", "Statistics", "StatsBase", "StatsFuns", "TableTraits", "Tables"] -git-tree-sha1 = "c659f7508035a7bdd5102aef2de028ab035f289a" +deps = ["AbstractMCMC", "AxisArrays", "DataAPI", "Dates", "Distributions", "IteratorInterfaceExtensions", "KernelDensity", "LinearAlgebra", "MCMCDiagnosticTools", "MLJModelInterface", "NaturalSort", "OrderedCollections", "PrettyTables", "Random", "RecipesBase", "Statistics", "StatsBase", "StatsFuns", "TableTraits", "Tables"] +git-tree-sha1 = "060d6bc7cf60e621dfd056ed2c1a2db1e68db0fe" uuid = "c7f686f2-ff18-58e9-bc7b-31028e88f75d" -version = "5.7.1" +version = "7.7.0" [[deps.MCMCDiagnosticTools]] -deps = ["AbstractFFTs", "DataAPI", "DataStructures", "Distributions", "LinearAlgebra", "MLJModelInterface", "Random", "SpecialFunctions", "Statistics", "StatsBase", "Tables"] -git-tree-sha1 = "d1737c39191aa26f42a64e320de313f1d1fd74b1" +deps = ["AbstractFFTs", "DataAPI", "DataStructures", "Distributions", "LinearAlgebra", "MLJModelInterface", "Random", "SpecialFunctions", "Statistics", "StatsBase", "StatsFuns", "Tables"] +git-tree-sha1 = "526c98cd41028da22c01cb8a203246799ad853a8" uuid = "be115224-59cd-429b-ad48-344e309966f0" -version = "0.2.1" +version = "0.3.15" [[deps.MKL_jll]] deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] @@ -1035,15 +1123,99 @@ version = "2025.2.0+0" [[deps.MLJModelInterface]] deps = ["InteractiveUtils", "REPL", "Random", "ScientificTypesBase", "StatisticalTraits"] -git-tree-sha1 = "ccaa3f7938890ee8042cc970ba275115428bd592" +git-tree-sha1 = "c275fae2e693206b4527dd9d2382aa15359ef3ed" uuid = "e80e1ace-859a-464e-9ed9-23947d8ae3ea" -version = "1.12.0" +version = "1.12.1" [[deps.MacroTools]] git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" version = "0.5.16" +[[deps.ManifoldDiff]] +deps = ["ADTypes", "DifferentiationInterface", "LinearAlgebra", "ManifoldsBase", "Markdown", "Random", "Requires"] +git-tree-sha1 = "28c69b401c75dd3f3b34a39bb7cb7948a2aeb61d" +uuid = "af67fdf4-a580-4b9f-bbec-742ef357defd" +version = "0.4.5" + + [deps.ManifoldDiff.weakdeps] + FiniteDiff = "6a86dc24-6348-571c-b903-95158fe2bd41" + FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000" + ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" + Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" + +[[deps.Manifolds]] +deps = ["ADTypes", "DifferentiationInterface", "Graphs", "Kronecker", "LinearAlgebra", "ManifoldDiff", "ManifoldsBase", "Markdown", "MatrixEquations", "Quaternions", "Random", "SimpleWeightedGraphs", "SpecialFunctions", "StaticArrays", "Statistics", "StatsBase", "Tullio"] +git-tree-sha1 = "709b90386258b79674859d61fc5dd397bd9c941d" +uuid = "1cead3c2-87b3-11e9-0ccd-23c62b72b94e" +version = "0.11.22" + + [deps.Manifolds.extensions] + ManifoldsBoundaryValueDiffEqExt = "BoundaryValueDiffEq" + ManifoldsDistributionsExt = ["Distributions", "RecursiveArrayTools"] + ManifoldsHybridArraysExt = "HybridArrays" + ManifoldsNLsolveExt = "NLsolve" + ManifoldsOrdinaryDiffEqDiffEqCallbacksExt = ["DiffEqCallbacks", "OrdinaryDiffEq", "RecursiveArrayTools"] + ManifoldsOrdinaryDiffEqExt = "OrdinaryDiffEq" + ManifoldsRecipesBaseExt = ["Colors", "RecipesBase"] + ManifoldsRecursiveArrayToolsExt = "RecursiveArrayTools" + ManifoldsTestExt = "Test" + + [deps.Manifolds.weakdeps] + BoundaryValueDiffEq = "764a87c0-6b3e-53db-9096-fe964310641d" + Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" + DiffEqCallbacks = "459566f4-90b8-5000-8ac3-15dfb0a30def" + Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" + HybridArrays = "1baab800-613f-4b0a-84e4-9cd3431bfbb9" + NLsolve = "2774e3e8-f4cf-5e23-947b-6d7e65073b56" + OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" + RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" + RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[[deps.ManifoldsBase]] +deps = ["LinearAlgebra", "Markdown", "Printf", "Random"] +git-tree-sha1 = "9329a9b772e3e50409b5b5cbbace1351139c6cf3" +uuid = "3362f125-f0bb-47a3-aa74-596ffd7ef2fb" +version = "2.3.5" + + [deps.ManifoldsBase.extensions] + ManifoldsBasePlotsExt = "Plots" + ManifoldsBaseQuaternionsExt = "Quaternions" + ManifoldsBaseRecursiveArrayToolsExt = "RecursiveArrayTools" + ManifoldsBaseStatisticsExt = "Statistics" + + [deps.ManifoldsBase.weakdeps] + Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" + Quaternions = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" + RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" + Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" + +[[deps.Manopt]] +deps = ["ColorSchemes", "ColorTypes", "Colors", "DataStructures", "Dates", "Glossaries", "LinearAlgebra", "ManifoldDiff", "ManifoldsBase", "Markdown", "Preferences", "Printf", "Random", "SparseArrays", "Statistics"] +git-tree-sha1 = "656cfa06ad863c778799c6b116e6f8310844a470" +uuid = "0fc0a36d-df90-57f3-8f93-d78a9fc72bb5" +version = "0.5.36" + + [deps.Manopt.extensions] + ManoptJuMPExt = "JuMP" + ManoptLRUCacheExt = "LRUCache" + ManoptLineSearchesExt = "LineSearches" + ManoptManifoldsExt = "Manifolds" + ManoptRecursiveArrayToolsExt = "RecursiveArrayTools" + ManoptRipQPQuadraticModelsExt = ["RipQP", "QuadraticModels"] + + [deps.Manopt.weakdeps] + JuMP = "4076af6c-e467-56ae-b986-b466b2749572" + LRUCache = "8ac3fa9e-de4c-5943-b1dc-09c6b5f20637" + LineSearches = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" + Manifolds = "1cead3c2-87b3-11e9-0ccd-23c62b72b94e" + Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" + QuadraticModels = "f468eda6-eac5-11e8-05a5-ff9e497bcd19" + RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" + RipQP = "1e40b3f8-35eb-4cd8-8edd-3e515bb9de08" + [[deps.ManualMemory]] git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667" @@ -1056,27 +1228,35 @@ version = "1.11.0" [[deps.MarkdownAST]] deps = ["AbstractTrees", "Markdown"] -git-tree-sha1 = "465a70f0fc7d443a00dcdc3267a497397b8a3899" +git-tree-sha1 = "93c718d892e73931841089cdc0e982d6dd9cc87b" uuid = "d0879d2d-cac2-40c8-9cee-1863dc0c7391" -version = "0.1.2" +version = "0.1.3" [[deps.MathOptInterface]] -deps = ["BenchmarkTools", "CodecBzip2", "CodecZlib", "DataStructures", "ForwardDiff", "JSON3", "LinearAlgebra", "MutableArithmetics", "NaNMath", "OrderedCollections", "PrecompileTools", "Printf", "SparseArrays", "SpecialFunctions", "Test"] -git-tree-sha1 = "a2cbab4256690aee457d136752c404e001f27768" +deps = ["CodecBzip2", "CodecZlib", "ForwardDiff", "JSON", "LinearAlgebra", "MutableArithmetics", "NaNMath", "OrderedCollections", "PrecompileTools", "Printf", "SparseArrays", "SpecialFunctions", "Test"] +git-tree-sha1 = "73939c06e863f8d68322106fdc2464f3443b5e1a" uuid = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" -version = "1.46.0" +version = "1.51.0" + + [deps.MathOptInterface.extensions] + MathOptInterfaceBenchmarkToolsExt = "BenchmarkTools" + MathOptInterfaceCliqueTreesExt = "CliqueTrees" + + [deps.MathOptInterface.weakdeps] + BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" + CliqueTrees = "60701a23-6482-424a-84db-faee86b9b1f8" + +[[deps.MatrixEquations]] +deps = ["LinearAlgebra", "LinearMaps"] +git-tree-sha1 = "51f3fade0b4ff2cf90b36b3312425460631abb56" +uuid = "99c1a7ee-ab34-5fd5-8076-27c950a045f4" +version = "2.5.6" [[deps.MbedTLS_jll]] deps = ["Artifacts", "Libdl"] uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" version = "2.28.6+0" -[[deps.MicroCollections]] -deps = ["BangBang", "InitialValues", "Setfield"] -git-tree-sha1 = "629afd7d10dbc6935ec59b32daeb33bc4460a42e" -uuid = "128add7d-3638-4c79-886c-908ea0c25c34" -version = "0.1.4" - [[deps.Missings]] deps = ["DataAPI"] git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" @@ -1091,11 +1271,16 @@ version = "1.11.0" uuid = "14a3606d-f60d-562e-9121-12d972cd8159" version = "2023.12.12" +[[deps.MuladdMacro]] +git-tree-sha1 = "cac9cc5499c25554cba55cd3c30543cff5ca4fab" +uuid = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" +version = "0.2.4" + [[deps.MutableArithmetics]] deps = ["LinearAlgebra", "SparseArrays", "Test"] -git-tree-sha1 = "22df8573f8e7c593ac205455ca088989d0a2c7a0" +git-tree-sha1 = "7c25249fc13a070f5ba433c50e21e22bb33c6fb0" uuid = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" -version = "1.6.7" +version = "1.7.1" [[deps.NLSolversBase]] deps = ["ADTypes", "DifferentiationInterface", "Distributed", "FiniteDiff", "ForwardDiff"] @@ -1109,6 +1294,25 @@ git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" version = "1.1.3" +[[deps.NamedDims]] +deps = ["LinearAlgebra", "Statistics"] +git-tree-sha1 = "f9e4a49ecd1ea2eccfb749a506fa882c094152b4" +uuid = "356022a1-0364-5f58-8944-0da4b18d706f" +version = "1.2.3" + + [deps.NamedDims.extensions] + AbstractFFTsExt = "AbstractFFTs" + ChainRulesCoreExt = "ChainRulesCore" + CovarianceEstimationExt = "CovarianceEstimation" + TrackerExt = "Tracker" + + [deps.NamedDims.weakdeps] + AbstractFFTs = "621f4979-c628-5d54-868e-fcf4e3e8185c" + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" + CovarianceEstimation = "587fd27a-f159-11e8-2dae-1979310e6154" + Requires = "ae029012-a4dd-5104-9daa-d747884805df" + Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" + [[deps.NaturalSort]] git-tree-sha1 = "eda490d06b9f7c00752ee81cfa451efe55521e21" uuid = "c020b1a1-e9b0-503a-9c33-f039bfc54a85" @@ -1140,9 +1344,9 @@ version = "1.3.6+0" [[deps.OpenBLAS32_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] -git-tree-sha1 = "ece4587683695fe4c5f20e990da0ed7e83c351e7" +git-tree-sha1 = "dd0d9979377e43918a80486a562ddedcc6d9bdf3" uuid = "656ef2d0-ae68-5445-9ca0-591084a874a2" -version = "0.3.29+0" +version = "0.3.33+0" [[deps.OpenBLAS_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] @@ -1156,15 +1360,15 @@ version = "0.8.5+0" [[deps.OpenSSH_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "OpenSSL_jll", "Zlib_jll"] -git-tree-sha1 = "301412a644646fdc0ad67d0a87487466b491e53d" +git-tree-sha1 = "57baa4b81a24c2910afbb6d853aa0685e4312bf7" uuid = "9bd350c2-7e96-507f-8002-3f2e150b4e1b" -version = "10.2.1+0" +version = "10.3.1+0" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "f19301ae653233bc88b1810ae908194f07f8db9d" +git-tree-sha1 = "2ac022577e5eac7da040de17776d51bb770cd895" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.5.4+0" +version = "3.5.6+0" [[deps.OpenSpecFun_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] @@ -1174,9 +1378,9 @@ version = "0.5.6+0" [[deps.Optim]] deps = ["Compat", "EnumX", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] -git-tree-sha1 = "61942645c38dd2b5b78e2082c9b51ab315315d10" +git-tree-sha1 = "48968edaf014f67e58fe4c8a4ce72d392aed3294" uuid = "429524aa-4258-5aef-a3af-852621145aeb" -version = "1.13.2" +version = "1.13.3" weakdeps = ["MathOptInterface"] [deps.Optim.extensions] @@ -1184,9 +1388,9 @@ weakdeps = ["MathOptInterface"] [[deps.Opus_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "c392fc5dd032381919e3b22dd32d6443760ce7ea" +git-tree-sha1 = "e2bb57a313a74b8104064b7efd01406c0a50d2ff" uuid = "91d4177d-7536-5919-b921-800302f37372" -version = "1.5.2+0" +version = "1.6.1+0" [[deps.OrderedCollections]] git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" @@ -1212,9 +1416,9 @@ version = "0.12.3" [[deps.Parsers]] deps = ["Dates", "PrecompileTools", "UUIDs"] -git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" +git-tree-sha1 = "5d5e0a78e971354b1c7bff0655d11fdc1b0e12c8" uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "2.8.3" +version = "2.8.4" [[deps.Pixman_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] @@ -1257,15 +1461,27 @@ version = "1.2.1" [[deps.Preferences]] deps = ["TOML"] -git-tree-sha1 = "0f27480397253da18fe2c12a4ba4eb9eb208bf3d" +git-tree-sha1 = "8b770b60760d4451834fe79dd483e318eee709c4" uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.5.0" +version = "1.5.2" [[deps.PrettyTables]] -deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "Reexport", "StringManipulation", "Tables"] -git-tree-sha1 = "1101cd475833706e4d0e7b122218257178f48f34" +deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "REPL", "Reexport", "StringManipulation", "Tables"] +git-tree-sha1 = "624de6279ab7d94fc9f672f0068107eb6619732c" uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "2.4.0" +version = "3.3.2" + + [deps.PrettyTables.extensions] + PrettyTablesTypstryExt = "Typstry" + + [deps.PrettyTables.weakdeps] + Typstry = "f0ed7684-a786-439e-b1e3-3b82803b501e" + +[[deps.Primes]] +deps = ["IntegerMathUtils"] +git-tree-sha1 = "25cdd1d20cd005b52fc12cb6be3f75faaf59bb9b" +uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" +version = "0.5.7" [[deps.Printf]] deps = ["Unicode"] @@ -1284,9 +1500,9 @@ version = "1.5.1" [[deps.ProgressLogging]] deps = ["Logging", "SHA", "UUIDs"] -git-tree-sha1 = "d95ed0324b0799843ac6f7a6a85e65fe4e5173f0" +git-tree-sha1 = "f0803bc1171e455a04124affa9c21bba5ac4db32" uuid = "33c8b6b6-d38a-422a-b730-caa89a2f386c" -version = "0.1.5" +version = "0.1.6" [[deps.ProgressMeter]] deps = ["Distributed", "Printf"] @@ -1295,9 +1511,9 @@ uuid = "92933f4c-e287-5a05-a399-4b506db050ca" version = "1.11.0" [[deps.PtrArrays]] -git-tree-sha1 = "1d36ef11a9aaf1e8b74dacc6a731dd1de8fd493d" +git-tree-sha1 = "4fbbafbc6251b883f4d2705356f3641f3652a7fe" uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" -version = "1.3.0" +version = "1.4.0" [[deps.PyCall]] deps = ["Conda", "Dates", "Libdl", "LinearAlgebra", "MacroTools", "Serialization", "VersionParsing"] @@ -1307,9 +1523,9 @@ version = "1.96.4" [[deps.QuadGK]] deps = ["DataStructures", "LinearAlgebra"] -git-tree-sha1 = "9da16da70037ba9d701192e27befedefb91ec284" +git-tree-sha1 = "5e8e8b0ab68215d7a2b14b9921a946fee794749e" uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.11.2" +version = "2.11.3" [deps.QuadGK.extensions] QuadGKEnzymeExt = "Enzyme" @@ -1317,6 +1533,12 @@ version = "2.11.2" [deps.QuadGK.weakdeps] Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" +[[deps.Quaternions]] +deps = ["LinearAlgebra", "Random", "RealDot"] +git-tree-sha1 = "4d8c1b7c3329c1885b857abb50d08fa3f4d9e3c8" +uuid = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0" +version = "0.7.7" + [[deps.REPL]] deps = ["InteractiveUtils", "Markdown", "Sockets", "StyledStrings", "Unicode"] uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" @@ -1343,12 +1565,16 @@ deps = ["Requires"] git-tree-sha1 = "1342a47bf3260ee108163042310d26f2be5ec90b" uuid = "c84ed2f1-dad5-54f0-aa8e-dbefe2724439" version = "0.4.5" +weakdeps = ["FixedPointNumbers"] [deps.Ratios.extensions] RatiosFixedPointNumbersExt = "FixedPointNumbers" - [deps.Ratios.weakdeps] - FixedPointNumbers = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" +[[deps.RealDot]] +deps = ["LinearAlgebra"] +git-tree-sha1 = "9f0a1b71baaf7650f4fa8a1d168c7fb6ee41f0c9" +uuid = "c1ae055f-0cd5-4b69-90a6-9a35b1a98df9" +version = "0.1.0" [[deps.RecipesBase]] deps = ["PrecompileTools"] @@ -1375,27 +1601,27 @@ version = "1.3.1" [[deps.ReverseDiff]] deps = ["ChainRulesCore", "DiffResults", "DiffRules", "ForwardDiff", "FunctionWrappers", "LinearAlgebra", "LogExpFunctions", "MacroTools", "NaNMath", "Random", "SpecialFunctions", "StaticArrays", "Statistics"] -git-tree-sha1 = "3ab8eee3620451b09f0272c271875b4bc02146d9" +git-tree-sha1 = "f1b07322a8cdc0d46812473b37fb72f69ec07b22" uuid = "37e2e3b7-166d-5795-8a7a-e32c996b4267" -version = "1.16.1" +version = "1.16.2" [[deps.Rmath]] deps = ["Random", "Rmath_jll"] -git-tree-sha1 = "f65dcb5fa46aee0cf9ed6274ccbd597adc49aa7b" +git-tree-sha1 = "5b3d50eb374cea306873b371d3f8d3915a018f0b" uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" -version = "0.7.1" +version = "0.9.0" [[deps.Rmath_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "e60724fd3beea548353984dc61c943ecddb0e29a" +git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8" uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" -version = "0.4.3+0" +version = "0.5.1+0" [[deps.SCS]] deps = ["LinearAlgebra", "MathOptInterface", "OpenBLAS32_jll", "PrecompileTools", "SCS_jll", "SparseArrays"] -git-tree-sha1 = "48ec3c39787bc7b278789b9af17c157ea8774dae" +git-tree-sha1 = "cd27f0cfefd06c7b2bd0343e08edbd9a3d2e1869" uuid = "c946c3f1-0d1f-5ce8-9dea-7daa1f7e2d13" -version = "2.4.0" +version = "2.6.3" [deps.SCS.extensions] SCSSCS_GPU_jllExt = ["SCS_GPU_jll"] @@ -1407,9 +1633,9 @@ version = "2.4.0" [[deps.SCS_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl", "libblastrampoline_jll"] -git-tree-sha1 = "05d6e31efa3debae6618dabee35dbd53cf4539d8" +git-tree-sha1 = "f7864fb125fc5eb61fa2f2c5738623be0b986edd" uuid = "f4f2fc5b-1d94-523c-97ea-2ab488bedf4b" -version = "300.200.900+0" +version = "300.200.1100+0" [[deps.SHA]] uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" @@ -1427,14 +1653,15 @@ uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" version = "0.6.43" [[deps.SciMLPublic]] -git-tree-sha1 = "ed647f161e8b3f2973f24979ec074e8d084f1bee" +git-tree-sha1 = "0ba076dbdce87ba230fff48ca9bca62e1f345c9b" uuid = "431bcebd-1456-4ced-9d72-93c2757fff0b" -version = "1.0.0" +version = "1.0.1" [[deps.ScientificTypesBase]] -git-tree-sha1 = "a8e18eb383b5ecf1b5e6fc237eb39255044fd92b" +deps = ["InteractiveUtils"] +git-tree-sha1 = "e785eaa35a0f5518a388f9010e66fda64ea95ede" uuid = "30f210dd-8aff-4c5f-94ba-8e64358c1161" -version = "3.0.0" +version = "3.1.0" [[deps.ScikitLearn]] deps = ["Compat", "Conda", "DataFrames", "Distributed", "IterTools", "LinearAlgebra", "MacroTools", "Parameters", "Printf", "PyCall", "Random", "ScikitLearnBase", "SparseArrays", "StatsBase", "VersionParsing"] @@ -1450,9 +1677,9 @@ version = "0.5.0" [[deps.SentinelArrays]] deps = ["Dates", "Random"] -git-tree-sha1 = "712fb0231ee6f9120e005ccd56297abbc053e7e0" +git-tree-sha1 = "ebe7e59b37c400f694f52b58c93d26201387da70" uuid = "91c51154-3ec4-41a3-a24f-3f23e20d615c" -version = "1.4.8" +version = "1.4.9" [[deps.Serialization]] uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" @@ -1469,6 +1696,18 @@ deps = ["Distributed", "Mmap", "Random", "Serialization"] uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" version = "1.11.0" +[[deps.SimpleTraits]] +deps = ["InteractiveUtils", "MacroTools"] +git-tree-sha1 = "be8eeac05ec97d379347584fa9fe2f5f76795bcb" +uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" +version = "0.9.5" + +[[deps.SimpleWeightedGraphs]] +deps = ["Graphs", "LinearAlgebra", "Markdown", "SparseArrays"] +git-tree-sha1 = "749a2b719ec7f34f280c0d97ac3dab5c89818631" +uuid = "47aef6b3-ad0c-573a-a1e2-d07658019622" +version = "1.5.1" + [[deps.Sockets]] uuid = "6462fe0b-24de-5631-8697-dd941f90decc" version = "1.11.0" @@ -1486,20 +1725,14 @@ version = "1.11.0" [[deps.SpecialFunctions]] deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "f2685b435df2613e25fc10ad8c26dddb8640f547" +git-tree-sha1 = "2700b235561b0335d5bef7097a111dc513b8655e" uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.6.1" +version = "2.7.2" weakdeps = ["ChainRulesCore"] [deps.SpecialFunctions.extensions] SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" -[[deps.SplittablesBase]] -deps = ["Setfield", "Test"] -git-tree-sha1 = "e08a62abc517eb79667d0a29dc08a3b589516bb5" -uuid = "171d559e-b47b-412a-8079-5efa626c420e" -version = "0.1.15" - [[deps.StableRNGs]] deps = ["Random"] git-tree-sha1 = "4f96c596b8c8258cc7d3b19797854d368f243ddc" @@ -1508,15 +1741,15 @@ version = "1.0.4" [[deps.Static]] deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools", "SciMLPublic"] -git-tree-sha1 = "49440414711eddc7227724ae6e570c7d5559a086" +git-tree-sha1 = "bb072715f158b59ad8819ff80da5ffa90cce6ceb" uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" -version = "1.3.1" +version = "1.4.0" [[deps.StaticArrayInterface]] -deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Static"] -git-tree-sha1 = "96381d50f1ce85f2663584c8e886a6ca97e60554" +deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "SciMLPublic", "Static"] +git-tree-sha1 = "2a635e15d5035c53b345077c947f31ff91744078" uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" -version = "1.8.0" +version = "1.10.0" weakdeps = ["OffsetArrays", "StaticArrays"] [deps.StaticArrayInterface.extensions] @@ -1525,9 +1758,9 @@ weakdeps = ["OffsetArrays", "StaticArrays"] [[deps.StaticArrays]] deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "b8693004b385c842357406e3af647701fe783f98" +git-tree-sha1 = "246a8bb2e6667f832eea063c3a56aef96429a3db" uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.15" +version = "1.9.18" weakdeps = ["ChainRulesCore", "Statistics"] [deps.StaticArrays.extensions] @@ -1557,9 +1790,9 @@ weakdeps = ["SparseArrays"] [[deps.StatsAPI]] deps = ["LinearAlgebra"] -git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" +git-tree-sha1 = "178ed29fd5b2a2cfc3bd31c13375ae925623ff36" uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" -version = "1.7.1" +version = "1.8.0" [[deps.StatsBase]] deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] @@ -1568,35 +1801,36 @@ uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" version = "0.33.21" [[deps.StatsFuns]] -deps = ["ChainRulesCore", "InverseFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] -git-tree-sha1 = "5950925ff997ed6fb3e985dcce8eb1ba42a0bbe7" +deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] +git-tree-sha1 = "91f091a8716a6bb38417a6e6f274602a19aaa685" uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" -version = "0.9.18" +version = "1.5.2" +weakdeps = ["ChainRulesCore", "InverseFunctions"] + + [deps.StatsFuns.extensions] + StatsFunsChainRulesCoreExt = "ChainRulesCore" + StatsFunsInverseFunctionsExt = "InverseFunctions" [[deps.StringManipulation]] deps = ["PrecompileTools"] -git-tree-sha1 = "725421ae8e530ec29bcbdddbe91ff8053421d023" +git-tree-sha1 = "d05693d339e37d6ab134c5ab53c29fce5ee5d7d5" uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" -version = "0.4.1" - -[[deps.StructTypes]] -deps = ["Dates", "UUIDs"] -git-tree-sha1 = "159331b30e94d7b11379037feeb9b690950cace8" -uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4" -version = "1.11.0" +version = "0.4.4" [[deps.StructUtils]] deps = ["Dates", "UUIDs"] -git-tree-sha1 = "79529b493a44927dd5b13dde1c7ce957c2d049e4" +git-tree-sha1 = "dd974aefe288ef2898733aecf40858dc86742d74" uuid = "ec057cc2-7a8d-4b58-b3b3-92acb9f63b42" -version = "2.6.0" +version = "2.8.1" [deps.StructUtils.extensions] StructUtilsMeasurementsExt = ["Measurements"] + StructUtilsStaticArraysCoreExt = ["StaticArraysCore"] StructUtilsTablesExt = ["Tables"] [deps.StructUtils.weakdeps] Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" [[deps.StyledStrings]] @@ -1668,31 +1902,11 @@ git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" version = "0.11.3" -[[deps.Transducers]] -deps = ["Adapt", "ArgCheck", "BangBang", "Baselet", "CompositionsBase", "ConstructionBase", "DefineSingletons", "Distributed", "InitialValues", "Logging", "Markdown", "MicroCollections", "Requires", "Setfield", "SplittablesBase", "Tables"] -git-tree-sha1 = "3064e780dbb8a9296ebb3af8f440f787bb5332af" -uuid = "28d57a85-8fef-5791-bfe6-a80928e7c999" -version = "0.4.80" - - [deps.Transducers.extensions] - TransducersBlockArraysExt = "BlockArrays" - TransducersDataFramesExt = "DataFrames" - TransducersLazyArraysExt = "LazyArrays" - TransducersOnlineStatsBaseExt = "OnlineStatsBase" - TransducersReferenceablesExt = "Referenceables" - - [deps.Transducers.weakdeps] - BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" - DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" - LazyArrays = "5078a376-72f3-5289-bfd5-ec5146d43c02" - OnlineStatsBase = "925886fa-5bf2-5e8e-b522-a9147a512338" - Referenceables = "42d2dcc6-99eb-4e98-b66c-637b7d73030e" - [[deps.Tullio]] deps = ["DiffRules", "LinearAlgebra", "Requires"] -git-tree-sha1 = "972698b132b9df8791ae74aa547268e977b55f68" +git-tree-sha1 = "de0febfe1243e89f352abd4ca0e9de6c8e6190c5" uuid = "bc48ee85-29a4-5162-ae0b-a64e1601d4bc" -version = "0.3.8" +version = "0.3.9" [deps.Tullio.extensions] TullioCUDAExt = "CUDA" @@ -1733,15 +1947,15 @@ version = "1.3.0" [[deps.WoodburyMatrices]] deps = ["LinearAlgebra", "SparseArrays"] -git-tree-sha1 = "c1a7aa6219628fcd757dede0ca95e245c5cd9511" +git-tree-sha1 = "248a7031b3da79a127f14e5dc5f417e26f9f6db7" uuid = "efce3f68-66dc-5838-9240-27a6d6f5f9b6" -version = "1.0.0" +version = "1.1.0" [[deps.Xorg_libX11_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] -git-tree-sha1 = "b5899b25d17bf1889d25906fb9deed5da0c15b3b" +git-tree-sha1 = "808090ede1d41644447dd5cbafced4731c56bd2f" uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" -version = "1.8.12+0" +version = "1.8.13+0" [[deps.Xorg_libXau_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -1757,9 +1971,15 @@ version = "1.1.6+0" [[deps.Xorg_libXext_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] -git-tree-sha1 = "a4c0ee07ad36bf8bbce1c3bb52d21fb1e0b987fb" +git-tree-sha1 = "1a4a26870bf1e5d26cd585e38038d399d7e65706" uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" -version = "1.3.7+0" +version = "1.3.8+0" + +[[deps.Xorg_libXfixes_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] +git-tree-sha1 = "75e00946e43621e09d431d9b95818ee751e6b2ef" +uuid = "d091e8ba-531a-589c-9de9-94069b037ed8" +version = "6.0.2+0" [[deps.Xorg_libXrender_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] @@ -1767,6 +1987,12 @@ git-tree-sha1 = "7ed9347888fac59a618302ee38216dd0379c480d" uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" version = "0.9.12+0" +[[deps.Xorg_libpciaccess_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "58972370b81423fc546c56a60ed1a009450177c3" +uuid = "a65dc6b1-eb27-53a1-bb3e-dea574b5389e" +version = "0.19.0+0" + [[deps.Xorg_libxcb_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXau_jll", "Xorg_libXdmcp_jll"] git-tree-sha1 = "bfcaf7ec088eaba362093393fe11aa141fa15422" @@ -1792,9 +2018,9 @@ version = "0.2.7" [[deps.libaom_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "371cc681c00a3ccc3fbc5c0fb91f58ba9bec1ecf" +git-tree-sha1 = "850b06095ee71f0135d644ffd8a52850699581ed" uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" -version = "3.13.1+0" +version = "3.13.3+0" [[deps.libass_jll]] deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Zlib_jll"] @@ -1807,6 +2033,12 @@ deps = ["Artifacts", "Libdl"] uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" version = "5.11.0+0" +[[deps.libdrm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libpciaccess_jll"] +git-tree-sha1 = "63aac0bcb0b582e11bad965cef4a689905456c03" +uuid = "8e53e030-5e6c-5a89-a30b-be5b7263a166" +version = "2.4.125+1" + [[deps.libfdk_aac_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "646634dd19587a56ee2f1199563ec056c5f228df" @@ -1815,9 +2047,15 @@ version = "2.0.4+0" [[deps.libpng_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "07b6a107d926093898e82b3b1db657ebe33134ec" +git-tree-sha1 = "e51150d5ab85cee6fc36726850f0e627ad2e4aba" uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" -version = "1.6.50+0" +version = "1.6.58+0" + +[[deps.libva_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll", "Xorg_libXext_jll", "Xorg_libXfixes_jll", "libdrm_jll"] +git-tree-sha1 = "7dbf96baae3310fe2fa0df0ccbb3c6288d5816c9" +uuid = "9a156e7d-b971-5f62-b2c9-67348b8fb97c" +version = "2.23.0+0" [[deps.libvorbis_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll"] diff --git a/docs/src/data_processing.md b/docs/src/data_processing.md index 662bcad95..c4b48efef 100644 --- a/docs/src/data_processing.md +++ b/docs/src/data_processing.md @@ -12,37 +12,72 @@ The framework works as follows An external API is also available using the `encode_data`, and `encode_structure_matrix` methods if needed to encode new data, or new covariance-type matrices. ## Defaults and recommendations -### Default schedule (no explicit dimension reduction) -When no schedule is provided, i.e. + +### Recommended schedule: ("latest and greatest") + +Given `ekp` and `prior` from an ensemble kalman process run (e.g., the "Calibrate" stage). Assume we have chosen our machine learning tool and obtained training data. Our recommendeded family to balance efficiency and reduce dimension is to use the `retain_var` and `retain_info`. + ```julia -emulator = Emulator(machine_learning_tool, input_output_pairs) +retain_var = 0.999 # reduce dimension retaining 99.9% of variance (for PCA) +retain_info = 0.999 # reduce dimension retaining 99.9% of information (for likelihood-informed) +ekp_it = 5 # number of eki iteration (for likelihood-informed) + +encoder_schedule = [ + (decorrelate_sample_cov(retain_var = retain_var), "in"), + (decorrelate_structure_mat(retain_var = retain_var), "out"), + (likelihood_informed(retain_info=retain_info, iters = 1:ekp_it), "in"), + (likelihood_informed(retain_info=retain_info, iters = 1:1), "out"), +] ``` -The default schedule under-the-hood, is given by +The motivation is that PCA is an efficient, but blunt, tool for reducing dimension from ((>100s) -> (100s)) dimension, then use likelihood-informed tools to hone down ((100s) -> (10s)) dimensions. `iters=1:X` is more performant in input than output dimension for `X>1` so we only do this here. This schedule is added to the emulator as follows +``` +emulator = Emulator( + machine_learning_tool, + input_output_pairs; + encoder_schedule = encoder_schedule, + encoder_kwargs = encoder_kwargs_from(ekp, prior), # kwargs from "Calibrate" objects +) +``` + +## Recommended `encoder_kwargs` + +The `EnsembleKalmanProcesses` infrastructure naturally provides information to build the data processors. We provide some utilities to extract these into `kwargs` of the correct format, the recommended (but not only) option is: + ```julia -schedule = (decorrelate_sample_cov(), "in_and_out") +# `prior::ParameterDistribution` +# `ekp::EnsembleKalmanProcess` +encoder_kwargs = encoder_kwargs_from(ekp, prior) ``` -If the user only provides the observational noise covariance, + +### Default schedule (to whiten with no dimension reduction) +When the user provides no `encoder_schedule`, the following is created ```julia emulator = Emulator( machine_learning_tool, input_output_pairs; - encoder_kwargs = (; obs_noise_cov = obs_noise_cov), + encoder_kwargs = encoder_kwargs, ) ``` The default schedule under-the-hood, is given by ```julia schedule = [ (decorrelate_sample_cov(), "in"), - (decorrelate_structure_mat(), "out"), # uses obs_noise_cov + (decorrelate_structure_mat(), "out"), # uses obs_noise_cov kwarg +] +``` +With no kwargs also provided, the following schedule under-the-hood, is given by +```julia +schedule = [ + (decorrelate_sample_cov(), "in_and_out"), ] ``` !!! note "Switch encoding off" To ensure that no encoding is happening, the user must pass in an empty schedule `encoder_schedule = []` -### Recommended: schedule for PCA dimension reduction +## Other typical schedule: PCA dimension reduction -Our recommendeded family to balance efficiency and reduce dimension is to use the `retain_var` kwargs. +Robust and blunt dimension reduction can be done with only PCA ```julia retain_var_in = 0.99 # reduce dimension retaining 99% of input variance retain_var_out = 0.95 # reduce dimension retaining 95% of output variance @@ -59,22 +94,21 @@ emulator = Emulator( encoder_kwargs = encoder_kwargs, ) ``` -## Recommended: Get `encoder_kwargs` from `ObservationSeries` etc. +## kwargs from other objects: -To transition more smoothly from the `EnsembleKalmanProcesses` infrastructure, one can also get the kwargs in the desired format from any [`Observation` and `ObservationSeries`](https://clima.github.io/EnsembleKalmanProcesses.jl/dev/observations/) objects, as well as [`ParameterDistribution`](https://clima.github.io/EnsembleKalmanProcesses.jl/dev/parameter_distributions/) objects used in the `EnsembleKalmanProcesses.jl` package. +One can also obtain individual kwarg sets from other objects, and can merge these as follows ```julia # `prior::ParameterDistribution` -input_kwargs = get_kwargs_from(prior) - # `observation_series::ObservationSeries` +input_kwargs = get_kwargs_from(prior) output_kwargs = get_kwargs_from(observation_series) - encoder_kwargs = merge(input_kwargs, output_kwargs) ``` + +Though not recommended, you can also build your own keyword arguments. !!! note "Observational noise notes" 1. The `obs_noise_cov` object does not need to be a constructed `AbstractMatrix`, rather it can be any type of compactly stored matrix compatible with `EnsembleKalmanProcesses` (e.g., [here](https://clima.github.io/EnsembleKalmanProcesses.jl/dev/observations/)). - 2. When `ObservationSeries` contains multiple observations, it is assumed that the covariance of the noise of all observations are the same. (If they are not, only the first will be taken by default in `get_kwargs_from(...)` - + 2. When `ObservationSeries` contains multiple observations, it is assumed that the covariance of the noise of all observations are the same. (If they are not, only the first will be taken by default in `get_kwargs_from(...)` ## Building and interpreting encoder schedules @@ -145,7 +179,7 @@ The `DataContainerProcessor` encodes "input" data agnostic of the "output" data, The `PairedDataContainerProcessor` encodes inputs (or outputs) using information of the both inputs and outputs in pairs - `CanonicalCorrelation` - constructed with `canonical_correlation()`, which performs [canonical correlation analysis](https://en.wikipedia.org/wiki/Canonical_correlation) to process the pairs. In effect this performs PCA on the cross-correlation from input and output samples. -- [Coming soon] `LikelihoodInformed` - this will use the data or likelihood from the inverse problem at hand to build diagnostic matrices that are used to find informative directions for dimension reduction. In particular we build generalizations of current frameworks (e.g., [Cui, Zahm 2021](http://doi.org/10.1088/1361-6420/abeafb), [Baptista, Marzouk, Zahm 2022](https://arxiv.org/abs/2207.08670)) to use the latest EKP iterations. +- `LikelihoodInformed`- constructed with `likelihood_informed()`- we use the data or likelihood from the inverse problem at hand to build diagnostic matrices that are used to find informative directions for dimension reduction. In particular we build generalizations of current frameworks (e.g., [Cui, Zahm 2021](http://doi.org/10.1088/1361-6420/abeafb), [Baptista, Marzouk, Zahm 2022](https://arxiv.org/abs/2207.08670)) to use the latest EKP iterations. We in fact generalize this framework here [Preprint Coming soon] for use in partially-informed distributions (e.g. EKI iterations) This is an extensible framework, and so new data processors can be added to this library. diff --git a/examples/DimensionReduction/Project.toml b/examples/DimensionReduction/Project.toml new file mode 100644 index 000000000..04a347cf2 --- /dev/null +++ b/examples/DimensionReduction/Project.toml @@ -0,0 +1,18 @@ +[deps] +AdvancedMH = "5b7e9947-ddc0-4b3f-9b55-0d8042f74170" +CalibrateEmulateSample = "95e48a1f-0bec-4818-9538-3db4340308e3" +ChunkSplitters = "ae650224-84b6-46f8-82ea-d812ca08434e" +DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" +Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" +DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" +EnsembleKalmanProcesses = "aa8a2aa5-91d8-4396-bcef-d4f2ec43552d" +FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341" +ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" +JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" +LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" +MCMCChains = "c7f686f2-ff18-58e9-bc7b-31028e88f75d" +Manifolds = "1cead3c2-87b3-11e9-0ccd-23c62b72b94e" +Manopt = "0fc0a36d-df90-57f3-8f93-d78a9fc72bb5" +Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" +Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" +StatsPlots = "f3b207a7-027a-5e70-b257-86293d7955fd" diff --git a/examples/DimensionReduction/calibrate.jl b/examples/DimensionReduction/calibrate.jl new file mode 100644 index 000000000..a12218d7b --- /dev/null +++ b/examples/DimensionReduction/calibrate.jl @@ -0,0 +1,65 @@ +using Distributions +using EnsembleKalmanProcesses +using JLD2 +using LinearAlgebra +using Random + + +include("./models.jl") # defines dims, files, mod_type +# select the forward map +@info "Executing model type $(mod_type)" + +function main() + if mod_type == "linear" + prior_cov, y, obs_noise_cov, model, true_parameter = lin(input_dim, output_dim, rng) + else + bad_model(mod_type, mod_types) + end + + prior_obj = ParameterDistribution( + Parameterized(MvNormal(zeros(size(prior_cov, 1)), prior_cov)), + fill(no_constraint(), size(prior_cov, 1)), + "$(mod_type)_prior", + ) + + n_ensemble = 80 + initial_ensemble = construct_initial_ensemble(rng, prior_obj, n_ensemble) + ekp = EnsembleKalmanProcess(initial_ensemble, y, obs_noise_cov, TransformInversion(); rng) + + max_iter = 20 + n_iters = 0 + for i in 1:max_iter + n_iters += 1 + G_ens = hcat([forward_map(param, model) for param in eachcol(get_ϕ_final(prior_obj, ekp))]...) + terminate = update_ensemble!(ekp, G_ens) + if !isnothing(terminate) + break + end + end + @info "EKP iterations: $n_iters" + @info "Loss over iterations: $(get_error(ekp))" + @info "Timesteps: $(ekp.Δt)" + @info "Checkpoints: $(get_algorithm_time(ekp))" + αs = vec([0 get_algorithm_time(ekp)[1:end]...]) + ekp_samples = Dict(α => (get_u(ekp, i), get_g(ekp, i)) for (i, α) in enumerate(αs[1:(end - 1)])) + + # evaluate at final time + G_ens = hcat([forward_map(param, model) for param in eachcol(get_ϕ_final(prior_obj, ekp))]...) + ekp_samples[αs[end]] = (get_u(ekp, length(αs)), G_ens) + + #! format: off + save( + joinpath(datadir,"ekp_$(mod_type).jld2"), + "ekpobj", ekp, + "ekp_samples", ekp_samples, + "prior_obj", prior_obj, + "y", y, + "obs_noise_cov", obs_noise_cov, + "model", model, + "true_parameter", true_parameter, + "alphas", αs, + ) + #! format: on + +end +main() diff --git a/examples/DimensionReduction/emulate_sample.jl b/examples/DimensionReduction/emulate_sample.jl new file mode 100644 index 000000000..10efcb5ea --- /dev/null +++ b/examples/DimensionReduction/emulate_sample.jl @@ -0,0 +1,165 @@ +using Distributions +using EnsembleKalmanProcesses +using JLD2 +using LinearAlgebra +using Random +using MCMCChains +using AdvancedMH +using DataFrames # table print at end +# CES +using CalibrateEmulateSample.Emulators +using CalibrateEmulateSample.MarkovChainMonteCarlo +using CalibrateEmulateSample.Utilities + + +include("./models.jl") +# select the forward map +mod_types = ["linear"] +mod_type = mod_types[1] +@info "Executing model type $(mod_type)" + +function main() + loaded = load("datafiles/ekp_$(mod_type).jld2") + ekpobj = loaded["ekpobj"] + ekp_samples = loaded["ekp_samples"] + prior = loaded["prior_obj"] + obs_noise_cov = loaded["obs_noise_cov"] + y = loaded["y"] + model = loaded["model"] + true_parameter = loaded["true_parameter"] + αs = loaded["alphas"] + mask = [1, length(αs)] # don't do all cases + αs = αs[mask] + + min_iter = 1 + max_iter = min(10, length(αs)) # number of EKP iterations to use data from is at most this + training_points = [ekp_samples[α] for α in αs[min_iter:max_iter]] + + encoder_schedule_ref = [(decorrelate_structure_mat(), "in_and_out")] + + # chosen some truncations with similar dimension + rvs_rinfos = [(0.995, 0.99995), (0.99, 0.9995), (0.98, 0.995), (0.95, 0.97), (0.9, 0.9)] + + # as we have more input samples than out stored in ekp. we provide the extended set of outputs to be used in the likelihood informed processor + final_samples_out = ekp_samples[αs[end]][2] + encoder_kwargs = encoder_kwargs_from(ekpobj, prior; final_samples_out = final_samples_out) + + flat_io_pairs = get_training_points(ekpobj, min_iter:max_iter, g_final = final_samples_out) + + names = ["reference", "PCA-in-out", "PCA(mat)-in-out", ["LI-in(1:$(i))-out(1:1)" for i in mask]...] + + + if mod_type == "linear" + ni_scaling = 0.0 # noise injection when eval forward map (def. 1) + else + bad_model(mod_type, mod_types) + end + + all_errs = zeros(length(rvs_rinfos), length(names)) + reduced_dims = zeros(Int, length(rvs_rinfos), length(names)) # store reduced dims for final table + + for (idx, rv_rinfo) in enumerate(rvs_rinfos) + rv, rinfo = rv_rinfo + encoder_schedule_decorrelate_samp = [(decorrelate_sample_cov(retain_var = rv), "in_and_out")] + encoder_schedule_decorrelate = [(decorrelate_structure_mat(retain_var = rv), "in_and_out")] + encoder_schedules_li = [ + [ + (decorrelate_structure_mat(), "in_and_out"), + (likelihood_informed(retain_info = rinfo, iters = 1:i), "in"), + (likelihood_informed(retain_info = rinfo, iters = 1:1), "out"), + ] for i in mask + ] + + em_ref = forward_map_wrapper( + param -> forward_map(param, model), + prior, + flat_io_pairs; + encoder_schedule = deepcopy(encoder_schedule_ref), + encoder_kwargs = deepcopy(encoder_kwargs), + noise_injector_scaling = ni_scaling, # shouldnt be needed + ) + + em_decorrelate_samp = forward_map_wrapper( + param -> forward_map(param, model), + prior, + flat_io_pairs; + encoder_schedule = deepcopy(encoder_schedule_decorrelate_samp), + encoder_kwargs = deepcopy(encoder_kwargs), + noise_injector_scaling = ni_scaling, + ) + + em_decorrelate = forward_map_wrapper( + param -> forward_map(param, model), + prior, + flat_io_pairs; + encoder_schedule = deepcopy(encoder_schedule_decorrelate), + encoder_kwargs = deepcopy(encoder_kwargs), + noise_injector_scaling = ni_scaling, + ) + + + ems_li = [ + forward_map_wrapper( + param -> forward_map(param, model), + prior, + flat_io_pairs; + encoder_schedule = deepcopy(encoder_schedule), + encoder_kwargs = deepcopy(encoder_kwargs), + noise_injector_scaling = ni_scaling, + ) for encoder_schedule in encoder_schedules_li + ] + post_means = reshape(true_parameter, input_dim, 1) + post_covs = [] + for (iidx, nn, em) in zip(1:length(names), names, vcat(em_ref, em_decorrelate_samp, em_decorrelate, ems_li...)) + + reduced_dims[idx, iidx] = get_encoded_dim(get_encoder_schedule(em), "in") + println(" ") + @info "Encoding name: $(nn)" + E, _ = get_encoder_from_schedule(get_encoder_schedule(em), "in") + + if isnothing(E) + @info "No truncation" + else + ed = get_encoded_dim(get_encoder_schedule(em), "in") + @info "Truncation criteria (var>$(rv), or information > $(rinfo))" + @info "input dim reduced to: $(ed)" + + end + println(" ") + u0 = rand(MvNormal(mean(prior), cov(prior))) + mcmc = MCMCWrapper(RWMHSampling(), y, prior, em; init_params = u0) + new_step = optimize_stepsize(mcmc; init_stepsize = 0.05, N = 2000, discard_initial = 0) + + println("Begin MCMC - with step size ", new_step) + mcmc = MCMCWrapper(RWMHSampling(), y, prior, em; init_params = u0) + chain = MarkovChainMonteCarlo.sample(mcmc, 40_000; stepsize = new_step, discard_initial = 5_000) + posterior = MarkovChainMonteCarlo.get_posterior(mcmc, chain) + + post_mean = mean(posterior) + post_cov = cov(posterior) + + post_means = hcat(post_means, reshape(post_mean, input_dim, 1)) + push!(post_covs, post_cov) + end + + # post_means[:,1] = true parameter + # post_means[:,2] = ref + # post_means[:,3] = decor, LI etc. + # so err cols are normalized diff to ref of (decor, LI etc.) (lower is better) + all_errs[idx, :] = [norm(post_means[:, 1] - v) / norm(post_means[:, 1]) for v in eachcol(post_means[:, 2:end])]' + end + + df = DataFrame(all_errs, [Symbol(n) for n in names[1:end]]) + + # build dataframe + pairs = [(reduced_dims[i, j], all_errs[i, j]) for i in axes(all_errs, 1), j in axes(all_errs, 2)] + + df = DataFrame(pairs, Symbol.(names[1:end])) # columns = names + df.truncation = rvs_rinfos # add row labels + return df, all_errs, reduced_dims[:, 1:end] +end + +df, all_errs, red_dims = main() + +@info "(reduced_dim, error) of posterior mean to whitened \"reference\" solution,\n when using the truncation ({for PCA}, {for LI})" +select!(df, :reference, :) diff --git a/examples/DimensionReduction/models.jl b/examples/DimensionReduction/models.jl new file mode 100644 index 000000000..34e5fd9a7 --- /dev/null +++ b/examples/DimensionReduction/models.jl @@ -0,0 +1,70 @@ +using Distributions +using LinearAlgebra +using Statistics + +using EnsembleKalmanProcesses +using EnsembleKalmanProcesses.ParameterDistributions + +abstract type ForwardMapType end + +function bad_model_type(mod_type, mod_types) + throw(ArgumentError("Unknown model type provided: $(mod_type), please choose from $(mod_types)")) +end + +# setup parameters +input_dim = 100 +output_dim = 100 + +datadir = joinpath(@__DIR__, "datafiles") +if !isdir(datadir) + mkpath(datadir) +end + +rng = Random.MersenneTwister(41) + +mod_types = ["linear"] +mod_type = mod_types[1] + + + +## Linear +struct Lin{AM <: AbstractMatrix} <: ForwardMapType + input_dim::Int + output_dim::Int + G::AM +end + +function lin(input_dim, output_dim, rng) + # prior + γ0 = 4.0 + β_γ = -2 + prior_cov = Diagonal([γ0 * (1.0 * j)^β_γ for j in 1:input_dim]) + + U = qr(randn(rng, (output_dim, output_dim))).Q + V = qr(randn(rng, (input_dim, input_dim))).Q + λ0 = 100.0 + β_λ = -1 + Λ = Diagonal([λ0 * (1.0 * j)^β_λ for j in 1:output_dim]) + A = U * Λ * V[1:output_dim, :] # output x input + model = Lin(input_dim, output_dim, A) + + # generate data sample + obs_noise_cov = Diagonal([Float64(j)^(-1 / 2) for j in 1:output_dim]) + noise = rand(rng, MvNormal(zeros(output_dim), obs_noise_cov)) + # true_parameter = reshape(ones(input_dim), :, 1) + true_parameter = rand(rng, MvNormal(zeros(input_dim), prior_cov)) + y = vec(forward_map(true_parameter, model) + noise) + return prior_cov, y, obs_noise_cov, model, true_parameter +end + +function forward_map(X::AVorM, model::Lin) where {AVorM <: AbstractVecOrMat} + return model.G * X +end + +function jac_forward_map(X::AbstractVector, model::Lin) + return model.G +end + +function jac_forward_map(X::AbstractMatrix, model::Lin) + return [jac_forward_map(x, model) for x in eachcol(X)] +end diff --git a/src/Emulator.jl b/src/Emulator.jl index a4507f078..d03d6827a 100644 --- a/src/Emulator.jl +++ b/src/Emulator.jl @@ -2,14 +2,12 @@ module Emulators using ..DataContainers using ..Utilities -import ..Utilities.encode_with_schedule -import ..Utilities.decode_with_schedule +# to API for encoding import ..Utilities.encode_data -import ..Utilities.decode_data import ..Utilities.encode_structure_matrix +import ..Utilities.decode_data import ..Utilities.decode_structure_matrix - using DocStringExtensions using Statistics using Distributions @@ -41,17 +39,21 @@ include(joinpath("MachineLearningTools", "RandomFeature.jl")) # Random Freatures # etc. # defaults in error, all MachineLearningTools require these functions. -function throw_define_mlt() - throw(ErrorException("Unknown MachineLearningTool defined, please use a known implementation")) +function throw_define_mlt(mlt) + throw( + ErrorException( + "Unknown MachineLearningTool defined, please use a known implementation. Please check all methods are defined for the MLT received: \n $mlt", + ), + ) end function build_models!(mlt, iopairs, input_structure_mats, output_structure_mats, mlt_kwargs...) - throw_define_mlt() + throw_define_mlt(mlt) end function optimize_hyperparameters!(mlt) - throw_define_mlt() + throw_define_mlt(mlt) end function predict(mlt, new_inputs; mlt_kwargs...) - throw_define_mlt() + throw_define_mlt(mlt) end # We will define the different emulator types after the general statements @@ -247,49 +249,14 @@ function optimize_hyperparameters!(emulator::Emulator{FT}, args...; kwargs...) w optimize_hyperparameters!(emulator.machine_learning_tool, args...; kwargs...) end -""" -$(TYPEDSIGNATURES) - -Encode the new data (a `DataContainer`, or matrix where data are columns) representing inputs (`"in"`) or outputs (`"out"`). with the stored and initialized encoder schedule. -""" -function encode_data( - encoder_schedule::VV, - data::MorDC, - in_or_out::AS, -) where {AS <: AbstractString, MorDC <: Union{AbstractMatrix, DataContainer}, VV <: AbstractVector} - if isa(data, AbstractMatrix) - return get_data(encode_with_schedule(encoder_schedule, DataContainer(data), in_or_out)) - else - return encode_with_schedule(encoder_schedule, data, in_or_out) - end -end - function encode_data( em_or_fmw::EorFMW, - data::MorDC, + data, in_or_out::AS, -) where { - AS <: AbstractString, - MorDC <: Union{AbstractMatrix, DataContainer}, - EorFMW <: Union{Emulator, ForwardMapWrapper}, -} +) where {AS <: AbstractString, EorFMW <: Union{Emulator, ForwardMapWrapper}} return encode_data(get_encoder_schedule(em_or_fmw), data, in_or_out) end - -""" -$(TYPEDSIGNATURES) - -Encode a new structure matrix in the input space (`"in"`) or output space (`"out"`). with the stored and initialized encoder schedule. -""" -function encode_structure_matrix( - encoder_schedule::VV, - structure_mat, - in_or_out::AS, -) where {AS <: AbstractString, VV <: AbstractVector} - return encode_with_schedule(encoder_schedule, structure_mat, in_or_out) -end - function encode_structure_matrix( em_or_fmw::EorFMW, structure_mat, @@ -298,49 +265,14 @@ function encode_structure_matrix( return encode_structure_matrix(get_encoder_schedule(em_or_fmw), structure_mat, in_or_out) end - -""" -$(TYPEDSIGNATURES) - -Decode the new data (a `DataContainer`, or matrix where data are columns) representing inputs (`"in"`) or outputs (`"out"`). with the stored and initialized encoder schedule. -""" -function decode_data( - encoder_schedule::VV, - data::MorDC, - in_or_out::AS, -) where {AS <: AbstractString, MorDC <: Union{AbstractMatrix, DataContainer}, VV <: AbstractVector} - if isa(data, AbstractMatrix) - return get_data(decode_with_schedule(encoder_schedule, DataContainer(data), in_or_out)) - else - return decode_with_schedule(encoder_schedule, data, in_or_out) - end -end - function decode_data( em_or_fmw::EorFMW, - data::MorDC, + data, in_or_out::AS, -) where { - AS <: AbstractString, - MorDC <: Union{AbstractMatrix, DataContainer}, - EorFMW <: Union{Emulator, ForwardMapWrapper}, -} +) where {AS <: AbstractString, EorFMW <: Union{Emulator, ForwardMapWrapper}} return decode_data(get_encoder_schedule(em_or_fmw), data, in_or_out) end -""" -$(TYPEDSIGNATURES) - -Decode a new structure matrix in the input space (`"in"`) or output space (`"out"`). with the stored and initialized encoder schedule. -""" -function decode_structure_matrix( - encoder_schedule::VV, - structure_mat, - in_or_out::AS, -) where {AS <: AbstractString, VV <: AbstractVector} - return decode_with_schedule(encoder_schedule, structure_mat, in_or_out) -end - function decode_structure_matrix( em_or_fmw::EorFMW, structure_mat, @@ -502,8 +434,6 @@ function forward_map_wrapper( else push!(encoder_schedule, (decorrelate_sample_cov(), "out")) end - else - @warn "Please note that only the output encoder is used in this implementation. \nThe input encoder will be initialized if provided, but not used during sampling, which is completed in the full parameter space." end encoder_schedule = create_encoder_schedule(encoder_schedule) diff --git a/src/Utilities.jl b/src/Utilities.jl index 86fb34a0f..01b8d02bf 100644 --- a/src/Utilities.jl +++ b/src/Utilities.jl @@ -22,9 +22,9 @@ export PairedDataContainerProcessor, DataContainerProcessor export create_encoder_schedule, initialize_and_encode_with_schedule!, encode_with_schedule, - decode_with_schedule, encode_data, encode_structure_matrix, + decode_with_schedule, decode_data, decode_structure_matrix, norm, @@ -35,7 +35,8 @@ export create_encoder_schedule, get_decoder_from_schedule, NoiseInjector, decode_and_add_noise, - create_noise_injector + create_noise_injector, + get_encoded_dim const StructureMatrix = Union{UniformScaling, AbstractMatrix, AbstractVector, LinearMap} # The vector appears due to possible block-structured matrices (build=false) @@ -44,33 +45,62 @@ const StructureVector = Union{AbstractVector, AbstractMatrix} # In case of a mat """ $(DocStringExtensions.TYPEDSIGNATURES) -Extract the training points needed to train the Gaussian process regression. +Extract and flatten the training points needed to train an Emulator. returned as a `PairedDataContainer` - `ekp` - EnsembleKalmanProcess holding the parameters and the data that were produced during the Ensemble Kalman (EK) process. -- `train_iterations` - Number (or indices) EK layers/iterations to train on. - +- `train_iterations` - Number (e.g. 1:train_iterations), or indices train_iterations=`3:2:9`, for EKP iterations to extract. +- `g_final[=nothing]` - EKP will typically store one extra input data iteration. If desired, the user can add output data for this final iteration directly with `g_final`. It should be of type `<: AbstractMatrix`, sized consistently as with return values from `get_g(ekp,1)`. """ function get_training_points( ekp::EKP.EnsembleKalmanProcess{FT, IT, P}, - train_iterations::Union{IT, AbstractVector{IT}}, + train_iterations::Union{IT, AbstractVector{IT}}; + g_final = nothing, ) where {FT, IT, P} if !isa(train_iterations, AbstractVector) - # Note u[end] does not have an equivalent g - iter_range = (get_N_iterations(ekp) - train_iterations + 1):get_N_iterations(ekp) + iter_range = 1:min(train_iterations, length(get_u(ekp))) else - iter_range = train_iterations + min_it = max(1, minimum(train_iterations)) + max_it = min(length(get_u(ekp)), maximum(train_iterations)) + iter_range = [i for i in train_iterations if (min_it <= i <= max_it)] + end + + @info "extracting iterations $(iter_range) from EnsembleKalmanProcess" + if (maximum(iter_range) > length(get_g(ekp))) && isnothing(g_final) + throw( + ArgumentError( + "Require outputs associated to parameters `get_u(ekp,$(maximum(iter_range)))`. \n the user can provide this with the `g_final` keyword. Received `g_final=$(g_final)`", + ), + ) end u_tp = [] g_tp = [] - for i in iter_range - push!(u_tp, get_u(ekp, i)) #N_parameters x N_ens - push!(g_tp, get_g(ekp, i)) #N_data x N_ens + + g_len = length(get_g(ekp)) + g_full = [get_g(ekp, i) for i in iter_range[iter_range .<= g_len]] + if !isnothing(g_final) + if (isa(g_final, AbstractMatrix)) # add the matrix + if !(size(g_full[1]) == size(g_final)) + throw(ArgumentError("Expected `g_final` size: $(size(g_full[1])), received $(size(g_final)).")) + end + push!(g_full, g_final) + else + throw( + ArgumentError( + "Expected `g_final` to be type `<:AbstractMatrix`, of size: $(size(g_full[1])), received $(typeof(g_final)).", + ), + ) + end + end + + for (idx, ir) in enumerate(iter_range) + push!(u_tp, get_u(ekp, ir)) #N_parameters x N_ens + push!(g_tp, g_full[idx]) #N_data x N_ens end - u_tp = hcat(u_tp...) # N_parameters x (N_ek_it x N_ensemble)] - g_tp = hcat(g_tp...) # N_data x (N_ek_it x N_ensemble) + u_tp = reduce(hcat, u_tp) # N_parameters x (N_ek_it x N_ensemble)] + g_tp = reduce(hcat, g_tp) # N_data x (N_ek_it x N_ensemble) training_points = PairedDataContainer(u_tp, g_tp, data_are_columns = true) @@ -85,6 +115,8 @@ $(TYPEDSIGNATURES) Extracts the relevant encoder kwargs from the observation as a NamedTuple. Contains, - `:obs_noise_cov` as (unbuilt) noise covariance - `:observation` as obs vector + +Commonly called from `encoder_kwargs_from(ekp, prior)` """ function encoder_kwargs_from(obs::OB) where {OB <: Observation} return (; obs_noise_cov = get_obs_noise_cov(obs, build = false), observation = get_obs(obs)) @@ -96,6 +128,8 @@ $(TYPEDSIGNATURES) Extracts the relevant encoder kwargs from the ObservationSeries as a NamedTuple. Assumes the same noise covariance for all observation vectors. Contains, - `:obs_noise_cov` as (unbuilt) noise covariance of FIRST observation - `:observation` as obs vector from all observations + +Commonly called from `encoder_kwargs_from(ekp, prior)` """ function encoder_kwargs_from(os::OS) where {OS <: ObservationSeries} observations = get_observations(os) @@ -115,11 +149,96 @@ $(TYPEDSIGNATURES) Extracts the relevant encoder kwargs from the ParameterDistribution prior. Contains, - `:prior_cov` as prior covariance + +Commonly called from `encoder_kwargs_from(ekp, prior)` """ function encoder_kwargs_from(prior::PD) where {PD <: ParameterDistribution} return (; prior_cov = cov(prior)) end +""" +$(TYPEDSIGNATURES) + +Extracts the relevant encoder kwargs from a vector triple (samples_in, samples_out, dt). Samples describe an ordered sequence of distributions in input and output space, each indexed with a temperature, or algorithm time, `dt`. + +Contains +- `:input_structure_vecs`: Dict with fields `:dt` (Vec{Float}), `:samples_in` (Vec{Matrix}) +- `:output_structure_vecs`: Dict with fields `:dt` (Vec{Float}), `:samples_out` (Vec{Matrix}) + +Commonly called from `encoder_kwargs_from(ekp, prior)` +""" +function encoder_kwargs_from( + samples_in::VV2, + samples_out::VV1, + dt::VV3, +) where {VV1 <: AbstractVector, VV2 <: AbstractVector, VV3 <: AbstractVector} + if !(minimum(abs.(dt[1])) < eps()) # if 0 is not the first element of the algorithm time. + dt = [0, dt...] + end + if length(samples_out) < min(length(samples_in), length(dt)) + @info """Detected fewer `samples_out` ($(length(samples_out))) than `samples_in` ($(length(samples_in))) and `dt` ($(length(dt))). Input-output structure vectors will be created from $(length(samples_out)) samples. +This commonly occurs when samples are built from `get_u(ekp), get_g(ekp)`. +The final interation of output samples, (e.g., from evaluating `g=forward_map_ensemble(get_ϕ_final(ekp)`) can be provided by `encoder_kwargs_from(ekp, prior; final_samples_out=g)` + +""" + end + len = minimum([length(samples_out), length(samples_in), length(dt)]) + # usually u is stored to one later value than g + samples_in = samples_in[1:len] + dt = dt[1:len] + samples_out = samples_out[1:len] + return (; + input_structure_vecs = Dict(:dt => dt, :samples_in => samples_in), + output_structure_vecs = Dict(:dt => dt, :samples_out => samples_out), + ) +end + +""" +$(TYPEDSIGNATURES) + +Extracts the relevant encoder kwargs from the `ekp` object, `prior` distribution. returned as a tuple that is passed to an `Emulator` or `ForwardMapWrapper` in the keyword argument `encoder_kwargs`. One can overload constructed kwargs by providing kwargs. + +kwargs: +- Common overloaded kwarg: `final_samples_out`. As `ekp` stores one more input than output, by default we truncate to the penultimate `ekp` iteration (where input output pairs exist). However, one can provide an additional final output paired with `g=forward_map_ensemble(get_ϕ_final(ekp))` with `final_samples_out=g` + +- Other overloading kwargs: `observation_series`,`samples_in`,`samples_out`,`dt` +""" +function encoder_kwargs_from( + ekp::EKP, + prior::PD; + observation_series = nothing, + samples_in = nothing, + samples_out = nothing, + dt = nothing, + final_samples_out = nothing, +) where {PD <: ParameterDistribution, EKP <: EnsembleKalmanProcess} + observation_series = isnothing(observation_series) ? get_observation_series(ekp) : observation_series + samples_in = isnothing(samples_in) ? get_u(ekp) : samples_in + samples_out = isnothing(samples_out) ? get_g(ekp) : samples_out + dt = isnothing(dt) ? get_algorithm_time(ekp) : dt + # a common setting is you have one-less samples_out than (samples_in, dt) so we extend g + if !isnothing(final_samples_out) + if (isa(final_samples_out, AbstractMatrix)) # add one matrix + if length(samples_out) > 0 + @assert(size(samples_out[1]) == size(final_samples_out)) + end + push!(samples_out, final_samples_out) + else # add a vector of matrices + if length(samples_out) > 0 + @assert all(size(samples_out[1]) == size(so) for so in final_samples_out) + end + samples_out = reduce(vcat, [samples_out, final_samples_out]) + end + end + + prior_kwargs = encoder_kwargs_from(prior) + obs_kwargs = encoder_kwargs_from(observation_series) + io_kwargs = encoder_kwargs_from(samples_in, samples_out, dt) + return merge(prior_kwargs, obs_kwargs, io_kwargs) + +end + + ## multiplication with observation covariance objects without building """ $(TYPEDSIGNATURES) @@ -379,24 +498,53 @@ function get_structure_mat(structure_mats, name = nothing) end end -function _encode_data(proc::P, data, apply_to::AS) where {P <: DataProcessor, AS <: AbstractString} +# just for reshaping into matrix +function _encode_data(proc::P, data::VV) where {P <: DataProcessor, VV <: AbstractVector} + data_vec = isa(data, DataContainer) ? get_data(data) : data + if eltype(data) <: Real # one vec + return _encode_data(proc, reshape(data, :, 1)) # reshape to column + else # vec of vec + return [_encode_data(proc, vec_or_mat) for vec_or_mat in data] + end +end + + +function _encode_data( + proc::P, + data::PDC, + apply_to::AS, +) where {P <: DataProcessor, AS <: AbstractString, PDC <: PairedDataContainer} input_data, output_data = get_data(data) if apply_to == "in" - return encode_data(proc, input_data) + return _encode_data(proc, input_data) elseif apply_to == "out" - return encode_data(proc, output_data) + return _encode_data(proc, output_data) else bad_apply_to(apply_to) end end -function _decode_data(proc::P, data, apply_to::AS) where {P <: DataProcessor, AS <: AbstractString} +# just for reshaping +function _decode_data(proc::P, data::VV) where {P <: DataProcessor, VV <: AbstractVector} + if eltype(data) <: Real # one vec + return _decode_data(proc, reshape(data, :, 1)) # reshape to column + else # vec of vec + return [_decode_data(proc, data[vec]) for vec in data] + end +end + + +function _decode_data( + proc::P, + data::PDC, + apply_to::AS, +) where {P <: DataProcessor, AS <: AbstractString, PDC <: PairedDataContainer} input_data, output_data = get_data(data) if apply_to == "in" - return decode_data(proc, input_data) + return _decode_data(proc, input_data) elseif apply_to == "out" - return decode_data(proc, output_data) + return _decode_data(proc, output_data) else bad_apply_to(apply_to) end @@ -410,7 +558,11 @@ function _initialize_and_encode_data!( apply_to::AS, ) where {AS <: AbstractString} initialize_processor!(proc, get_data(data)..., structure_mats..., structure_vecs..., apply_to) - return _encode_data(proc, data, apply_to) + if apply_to ∈ ["in", "out"] + return _encode_data(proc, data, apply_to) + else + bad_apply_to(apply_to) + end end function _initialize_and_encode_data!( @@ -500,8 +652,8 @@ function initialize_and_encode_with_schedule!( prior_cov::Union{Nothing, StructureMatrix} = nothing, obs_noise_cov::Union{Nothing, StructureMatrix} = nothing, observation::Union{Nothing, StructureVector} = nothing, - prior_samples_in::Union{Nothing, StructureVector} = nothing, - prior_samples_out::Union{Nothing, StructureVector} = nothing, + samples_in::Union{Nothing, StructureVector} = nothing, + samples_out::Union{Nothing, StructureVector} = nothing, ) where {VV <: AbstractVector, PDC <: PairedDataContainer} processed_io_pairs = deepcopy(io_pairs) @@ -533,16 +685,16 @@ function initialize_and_encode_with_schedule!( end input_structure_vecs = deepcopy(input_structure_vecs) - if !isnothing(prior_samples_in) - (input_structure_vecs[:prior_samples_in] = prior_samples_in) + if !isnothing(samples_in) + (input_structure_vecs[:samples_in] = samples_in) end output_structure_vecs = deepcopy(output_structure_vecs) if !isnothing(observation) (output_structure_vecs[:observation] = observation) end - if !isnothing(prior_samples_out) - (output_structure_vecs[:prior_samples_out] = prior_samples_out) + if !isnothing(samples_out) + (output_structure_vecs[:samples_out] = samples_out) end # apply_to is the string "in", "out" etc. @@ -557,20 +709,25 @@ function initialize_and_encode_with_schedule!( apply_to, ) + non_encode_list = [:dt] # non-data fields if apply_to == "in" input_structure_mats = Dict{Symbol, StructureMatrix}( - name => encode_structure_matrix(processor, mat) for (name, mat) in input_structure_mats + name => (name ∉ non_encode_list ? _encode_structure_matrix(processor, mat) : mat) for + (name, mat) in input_structure_mats ) input_structure_vecs = Dict{Symbol, StructureVector}( - name => encode_data(processor, vec) for (name, vec) in input_structure_vecs + name => (name ∉ non_encode_list ? _encode_data(processor, vec) : vec) for + (name, vec) in input_structure_vecs ) processed_io_pairs = PairedDataContainer(processed, get_outputs(processed_io_pairs)) elseif apply_to == "out" output_structure_mats = Dict{Symbol, StructureMatrix}( - name => encode_structure_matrix(processor, mat) for (name, mat) in output_structure_mats + name => (name ∉ non_encode_list ? _encode_structure_matrix(processor, mat) : mat) for + (name, mat) in output_structure_mats ) output_structure_vecs = Dict{Symbol, StructureVector}( - name => encode_data(processor, vec) for (name, vec) in output_structure_vecs + name => (name ∉ non_encode_list ? _encode_data(processor, vec) : vec) for + (name, vec) in output_structure_vecs ) processed_io_pairs = PairedDataContainer(get_inputs(processed_io_pairs), processed) end @@ -599,7 +756,7 @@ function encode_with_schedule( # apply_to is the string "in", "out" etc. for (processor, apply_to) in encoder_schedule if apply_to == in_or_out - processed = encode_data(processor, get_data(processed_container)) + processed = _encode_data(processor, get_data(processed_container)) processed_container = DataContainer(processed) end end @@ -625,13 +782,48 @@ function encode_with_schedule( # apply_to is the string "in", "out" etc. for (processor, apply_to) in encoder_schedule if apply_to == in_or_out - processed_structure_matrix = encode_structure_matrix(processor, processed_structure_matrix) + processed_structure_matrix = _encode_structure_matrix(processor, processed_structure_matrix) end end return processed_structure_matrix end +""" +$(TYPEDSIGNATURES) + +Encode the new data (a `DataContainer`, or matrix where data are columns, or vector viewed as one column) representing inputs (`"in"`) or outputs (`"out"`), with the stored and initialized encoder schedule. +Always internally calls `CES.Utilities.encode_with_schedule` +""" +function encode_data( + encoder_schedule::VV, + data::VorMorDC, + in_or_out::AS, +) where {AS <: AbstractString, VorMorDC <: Union{AbstractVector, AbstractMatrix, DataContainer}, VV <: AbstractVector} + if isa(data, AbstractVector) + return vec(get_data(encode_with_schedule(encoder_schedule, DataContainer(reshape(data, :, 1)), in_or_out))) + elseif isa(data, AbstractMatrix) + return get_data(encode_with_schedule(encoder_schedule, DataContainer(data), in_or_out)) + else + return encode_with_schedule(encoder_schedule, data, in_or_out) + end +end + +""" +$(TYPEDSIGNATURES) + +Encode a new structure matrix in the input space (`"in"`) or output space (`"out"`). with the stored and initialized encoder schedule. +Always internally calls `CES.Utilities.encode_with_schedule`. If the structure matrix is a `LinearMap`, then the encoded structure matrix remains a `LinearMap` +""" +function encode_structure_matrix( + encoder_schedule::VV, + structure_mat, + in_or_out::AS, +) where {AS <: AbstractString, VV <: AbstractVector} + return encode_with_schedule(encoder_schedule, structure_mat, in_or_out) +end + + """ $TYPEDSIGNATURES @@ -653,10 +845,10 @@ function decode_with_schedule( processed = _decode_data(processor, processed_io_pairs, apply_to) if apply_to == "in" - processed_input_structure_mat = decode_structure_matrix(processor, processed_input_structure_mat) + processed_input_structure_mat = _decode_structure_matrix(processor, processed_input_structure_mat) processed_io_pairs = PairedDataContainer(processed, get_outputs(processed_io_pairs)) elseif apply_to == "out" - processed_output_structure_mat = decode_structure_matrix(processor, processed_output_structure_mat) + processed_output_structure_mat = _decode_structure_matrix(processor, processed_output_structure_mat) processed_io_pairs = PairedDataContainer(get_inputs(processed_io_pairs), processed) else bad_apply_to(apply_to) @@ -685,7 +877,7 @@ function decode_with_schedule( for idx in reverse(eachindex(encoder_schedule)) (processor, apply_to) = encoder_schedule[idx] if apply_to == in_or_out - processed = decode_data(processor, get_data(processed_container)) + processed = _decode_data(processor, get_data(processed_container)) processed_container = DataContainer(processed) end end @@ -712,7 +904,7 @@ function decode_with_schedule( for idx in reverse(eachindex(encoder_schedule)) (processor, apply_to) = encoder_schedule[idx] if apply_to == in_or_out - processed_structure_matrix = decode_structure_matrix(processor, processed_structure_matrix) + processed_structure_matrix = _decode_structure_matrix(processor, processed_structure_matrix) end end @@ -720,6 +912,40 @@ function decode_with_schedule( end +""" +$(TYPEDSIGNATURES) + +Decode the new data (a `DataContainer`, or matrix where data are columns, or vector viewed as one column) representing inputs (`"in"`) or outputs (`"out"`), with the stored and initialized encoder schedule. +Always internally calls `CES.Utilities.decode_with_schedule` +""" +function decode_data( + encoder_schedule::VV, + data::VorMorDC, + in_or_out::AS, +) where {AS <: AbstractString, VorMorDC <: Union{AbstractVector, AbstractMatrix, DataContainer}, VV <: AbstractVector} + if isa(data, AbstractVector) + return vec(get_data(decode_with_schedule(encoder_schedule, DataContainer(reshape(data, :, 1)), in_or_out))) + elseif isa(data, AbstractMatrix) + return get_data(decode_with_schedule(encoder_schedule, DataContainer(data), in_or_out)) + else + return decode_with_schedule(encoder_schedule, data, in_or_out) + end +end + +""" +$(TYPEDSIGNATURES) + +Decode a new structure matrix in the input space (`"in"`) or output space (`"out"`). with the stored and initialized encoder schedule. +Always internally calls `CES.Utilities.decode_with_schedule`. If the structure matrix is a `LinearMap`, then the decoded structure matrix remains a `LinearMap` +""" +function decode_structure_matrix( + encoder_schedule::VV, + structure_mat, + in_or_out::AS, +) where {AS <: AbstractString, VV <: AbstractVector} + return decode_with_schedule(encoder_schedule, structure_mat, in_or_out) +end + # Errors function bad_apply_to(apply_to::AS) where {AS <: AbstractString} @@ -765,8 +991,9 @@ function get_encoder_from_schedule( if length(encoder_mats) == 0 return nothing, nothing else - # Note, the action of encoders (E_1,E_2,E_3) is the product x -> (E_3*E_2*E_1)*x so must be reversed. `prod` unsafe here + # Note, the action of encoders (E_1,E_2,E_3) is the product x -> (E_3*E_2*E_1)*x so must be reversed linear_part = reduce(*, reverse(encoder_mats)) + # rather than extracting the shifts etc. we can get this by just applying it to zero constant_part = encode_data(encoder_schedule, zeros(size(linear_part, 2), 1), in_or_out) @@ -785,7 +1012,40 @@ function get_encoder_from_schedule(encoder_schedule::VV) where {VV <: AbstractVe "in" => get_encoder_from_schedule(encoder_schedule, "in"), "out" => get_encoder_from_schedule(encoder_schedule, "out"), ) +end +""" +$(TYPEDSIGNATURES) + +gets the dimension of the encoded space, for input (providing "in"), or output (providing "out"), provides nothing if encoder schedule is empty or uninitialized +""" +function get_encoded_dim(encoder_schedule::VV, in_or_out::AS) where {VV <: AbstractVector, AS <: AbstractString} + if length(encoder_schedule) == 0 + return nothing + else + if in_or_out ∉ ["in", "out"] + bad_in_or_out(in_or_out) + end + + encoder_mat_sizes = + [size(get_encoder_mat(processor)[1]) for (processor, apply_to) in encoder_schedule if apply_to == in_or_out] + + if length(encoder_mat_sizes) == 0 + return nothing + else + # (E_1, E_2, E_3) applied as E_3(E_2(E_1(x))) size(E_3,1) matters + return encoder_mat_sizes[end][1] + end + end +end + +""" +$(TYPEDSIGNATURES) + +gets the dimension of the encoded space, returned as a Dict with keys "in","out". Provides nothing values if encoder schedule is empty or uninitialized +""" +function get_encoded_dim(encoder_schedule::VV) where {VV <: AbstractVector} + return Dict("in" => get_encoded_dim(encoder_schedule, "in"), "out" => get_encoded_dim(encoder_schedule, "out")) end """ @@ -841,6 +1101,14 @@ function get_decoder_from_schedule(encoder_schedule::VV) where {VV <: AbstractVe ) end + +get_encoder_from_schedule(single_encoder::T, args...; kwargs...) where {T <: Tuple} = + get_encoder_from_schedule([single_encoder], args...; kwargs...) +get_decoder_from_schedule(single_encoder::T, args...; kwargs...) where {T <: Tuple} = + get_decoder_from_schedule([single_encoder], args...; kwargs...) +get_encoded_dim(single_encoder::T, args...; kwargs...) where {T <: Tuple} = + get_encoded_dim([single_encoder], args...; kwargs...) + ## Decoding and add noise: """ $(TYPEDEF) @@ -977,5 +1245,6 @@ end include("Utilities/canonical_correlation.jl") include("Utilities/decorrelator.jl") include("Utilities/elementwise_scaler.jl") +include("Utilities/likelihood_informed.jl") end # module diff --git a/src/Utilities/canonical_correlation.jl b/src/Utilities/canonical_correlation.jl index 9e52cc1fd..0020ad79b 100644 --- a/src/Utilities/canonical_correlation.jl +++ b/src/Utilities/canonical_correlation.jl @@ -178,12 +178,7 @@ initialize_processor!( ) where {MM <: AbstractMatrix, AS <: AbstractString} = initialize_processor!(cc, in_data, out_data, apply_to) -""" -$(TYPEDSIGNATURES) - -Apply the `CanonicalCorrelation` encoder, on a columns-are-data matrix -""" -function encode_data(cc::CanonicalCorrelation, data::MM) where {MM <: AbstractMatrix} +function _encode_data(cc::CanonicalCorrelation, data::MM) where {MM <: AbstractMatrix} data_mean = get_data_mean(cc)[1] encoder_mat = get_encoder_mat(cc)[1] out = zeros(size(encoder_mat, 1), size(data, 2)) @@ -191,12 +186,7 @@ function encode_data(cc::CanonicalCorrelation, data::MM) where {MM <: AbstractMa return out end -""" -$(TYPEDSIGNATURES) - -Apply the `CanonicalCorrelation` decoder, on a columns-are-data matrix -""" -function decode_data(cc::CanonicalCorrelation, data::MM) where {MM <: AbstractMatrix} +function _decode_data(cc::CanonicalCorrelation, data::MM) where {MM <: AbstractMatrix} data_mean = get_data_mean(cc)[1] decoder_mat = get_decoder_mat(cc)[1] out = zeros(size(decoder_mat, 1), size(data, 2)) @@ -204,22 +194,12 @@ function decode_data(cc::CanonicalCorrelation, data::MM) where {MM <: AbstractMa return out .+ data_mean end -""" -$(TYPEDSIGNATURES) - -Apply the `CanonicalCorrelation` encoder to a provided structure matrix -""" -function encode_structure_matrix(cc::CanonicalCorrelation, structure_matrix::SM) where {SM <: StructureMatrix} +function _encode_structure_matrix(cc::CanonicalCorrelation, structure_matrix::SM) where {SM <: StructureMatrix} encoder_mat = get_encoder_mat(cc)[1] return encoder_mat * structure_matrix * encoder_mat' end -""" -$(TYPEDSIGNATURES) - -Apply the `CanonicalCorrelation` decoder to a provided structure matrix -""" -function decode_structure_matrix(cc::CanonicalCorrelation, enc_structure_matrix::SM) where {SM <: StructureMatrix} +function _decode_structure_matrix(cc::CanonicalCorrelation, enc_structure_matrix::SM) where {SM <: StructureMatrix} decoder_mat = get_decoder_mat(cc)[1] return decoder_mat * enc_structure_matrix * decoder_mat' end diff --git a/src/Utilities/decorrelator.jl b/src/Utilities/decorrelator.jl index 6c5ec24c6..c6a37cdae 100644 --- a/src/Utilities/decorrelator.jl +++ b/src/Utilities/decorrelator.jl @@ -359,12 +359,7 @@ function initialize_processor!( end -""" -$(TYPEDSIGNATURES) - -Apply the `Decorrelator` encoder, on a columns-are-data matrix -""" -function encode_data(dd::Decorrelator, data::MM) where {MM <: AbstractMatrix} +function _encode_data(dd::Decorrelator, data::MM) where {MM <: AbstractMatrix} data_mean = get_data_mean(dd)[1] encoder_mat = get_encoder_mat(dd)[1] out = zeros(size(encoder_mat, 1), size(data, 2)) @@ -372,12 +367,7 @@ function encode_data(dd::Decorrelator, data::MM) where {MM <: AbstractMatrix} return out end -""" -$(TYPEDSIGNATURES) - -Apply the `Decorrelator` decoder, on a columns-are-data matrix -""" -function decode_data(dd::Decorrelator, data::MM) where {MM <: AbstractMatrix} +function _decode_data(dd::Decorrelator, data::MM) where {MM <: AbstractMatrix} data_mean = get_data_mean(dd)[1] decoder_mat = get_decoder_mat(dd)[1] out = zeros(size(decoder_mat, 1), size(data, 2)) @@ -385,22 +375,12 @@ function decode_data(dd::Decorrelator, data::MM) where {MM <: AbstractMatrix} return out .+ data_mean end -""" -$(TYPEDSIGNATURES) - -Apply the `Decorrelator` encoder to a provided structure matrix. If the structure matrix is a LinearMap, then the encoded structure matrix remains a LinearMap. -""" -function encode_structure_matrix(dd::Decorrelator, structure_matrix::SM) where {SM <: StructureMatrix} +function _encode_structure_matrix(dd::Decorrelator, structure_matrix::SM) where {SM <: StructureMatrix} encoder_mat = get_encoder_mat(dd)[1] return encoder_mat * structure_matrix * encoder_mat' end -""" -$(TYPEDSIGNATURES) - -Apply the `Decorrelator` decoder to a provided structure matrix. If the structure matrix is a LinearMap, then the encoded structure matrix remains a LinearMap. -""" -function decode_structure_matrix(dd::Decorrelator, enc_structure_matrix::SM) where {SM <: StructureMatrix} +function _decode_structure_matrix(dd::Decorrelator, enc_structure_matrix::SM) where {SM <: StructureMatrix} decoder_mat = get_decoder_mat(dd)[1] return decoder_mat * enc_structure_matrix * decoder_mat' end diff --git a/src/Utilities/elementwise_scaler.jl b/src/Utilities/elementwise_scaler.jl index be3987ad2..ec6449f1b 100644 --- a/src/Utilities/elementwise_scaler.jl +++ b/src/Utilities/elementwise_scaler.jl @@ -218,24 +218,14 @@ function initialize_processor!(es::ElementwiseScaler, data::MM) where {MM <: Abs end end -""" -$(TYPEDSIGNATURES) - -Apply the `ElementwiseScaler` encoder, on a columns-are-data matrix -""" -function encode_data(es::ElementwiseScaler, data::MM) where {MM <: AbstractMatrix} +function _encode_data(es::ElementwiseScaler, data::MM) where {MM <: AbstractMatrix} out = zeros(size(data)) enc = get_data_encoder_mat(es)[1] mul!(out, enc, data) # must use this form to get matrix output of enc*out return out end -""" -$(TYPEDSIGNATURES) - -Apply the `ElementwiseScaler` decoder, on a columns-are-data matrix -""" -function decode_data(es::ElementwiseScaler, data::MM) where {MM <: AbstractMatrix} +function _decode_data(es::ElementwiseScaler, data::MM) where {MM <: AbstractMatrix} out = zeros(size(data)) dec = get_data_decoder_mat(es)[1] mul!(out, dec, data) # must use this form to get matrix output of dec*out @@ -255,22 +245,12 @@ initialize_processor!( ) where {MM <: AbstractMatrix} = initialize_processor!(es, data) -""" -$(TYPEDSIGNATURES) - -Apply the `ElementwiseScaler` encoder to a provided structure matrix. If the structure matrix is a LinearMap, then the encoded structure matrix remains a LinearMap. -""" -function encode_structure_matrix(es::ElementwiseScaler, structure_matrix::SM) where {SM <: StructureMatrix} +function _encode_structure_matrix(es::ElementwiseScaler, structure_matrix::SM) where {SM <: StructureMatrix} encoder_mat = get_struct_encoder_mat(es)[1] return encoder_mat * structure_matrix * encoder_mat' end -""" -$(TYPEDSIGNATURES) - -Apply the `ElementwiseScaler` decoder to a provided structure matrix. If the structure matrix is a LinearMap, then the encoded structure matrix remains a LinearMap. -""" -function decode_structure_matrix(es::ElementwiseScaler, enc_structure_matrix::SM) where {SM <: StructureMatrix} +function _decode_structure_matrix(es::ElementwiseScaler, enc_structure_matrix::SM) where {SM <: StructureMatrix} decoder_mat = get_struct_decoder_mat(es)[1] return decoder_mat * enc_structure_matrix * decoder_mat' end diff --git a/src/Utilities/likelihood_informed.jl b/src/Utilities/likelihood_informed.jl new file mode 100644 index 000000000..75156c701 --- /dev/null +++ b/src/Utilities/likelihood_informed.jl @@ -0,0 +1,371 @@ +# included in Utilities.jl + +using Manifolds, Manopt + +export LikelihoodInformed, likelihood_informed, get_retain_info, get_iters, get_grad_type + +""" +$(TYPEDEF) + +Uses both input and output data to learn a subspace that allows for a reduced posterior which is close to the full posterior. + +Preferred construction is with the [`likelihood_informed`](@ref) method. + +# Fields +$(TYPEDFIELDS) +""" +mutable struct LikelihoodInformed{ + VV1 <: AbstractVector, + VV2 <: AbstractVector, + VV3 <: AbstractVector, + VV4 <: AbstractVector, + FT <: Real, +} <: PairedDataContainerProcessor + encoder_mat::VV1 + decoder_mat::VV2 + data_mean::VV3 + retain_info::FT + apply_to::Union{Nothing, AbstractString} + iters::VV4 + grad_type::Symbol +end + +""" +$(TYPEDSIGNATURES) + +Constructs the `LikelihoodInformed` struct. Keywords: +- `retain_info`: the method will attempt to limit the KL divergence of the true posterior from the reduced posterior to a value proportional to (1 - `retain_info`). Choose `retain_info` close to 1 to get a good approximation in a large subspace, and reduce it to get a worse approximation in a smaller subspace. +- `iters`[`= [1]`]: the likelihood-informed data processor requires samples from the distribution `∝ π_prior(x) π_likelihood(y | x)^α` with `α ∈ [0, 1]`. Here, `iter` indicates the structure vector iterations to use, as sampled from these distributions. For how to pass in these samples, see the `use_data_as_samples` parameter. +- `grad_type`[`= :linreg`]: how the gradient of the forward model at the samples will be approximated. Choose from `:linreg` (global linear regression) and `:localsl` (localized statistical linearization; see [Wacker, 2025]). +""" +function likelihood_informed(; retain_info = 1, iters = 1, grad_type = :linreg) + grad_types = [:linreg, :localsl] + if grad_type ∉ grad_types + throw(ArgumentError("Unknown grad_type=$grad_type, please select from $(grad_types)")) + end + if !isa(iters, AbstractVector) + iters = [iters] + end + if !(eltype(iters) <: Integer) + throw( + ArgumentError, + "Iterations must be passed as an Int or Vec{Int}. This corresponds to which of the structure-vectors are used to construct the subspace", + ) + end + + LikelihoodInformed([], [], [], retain_info, nothing, iters, grad_type) +end + +get_encoder_mat(li::LikelihoodInformed) = li.encoder_mat +get_decoder_mat(li::LikelihoodInformed) = li.decoder_mat +get_data_mean(li::LikelihoodInformed) = li.data_mean +get_retain_info(li::LikelihoodInformed) = li.retain_info +get_iters(li::LikelihoodInformed) = li.iters +get_grad_type(li::LikelihoodInformed) = li.grad_type + +function Base.show(io::IO, li::LikelihoodInformed) + out = "LikelihoodInformed" + out *= ": iters=$(get_iters(li)), grad_type=$(get_grad_type(li))" + if get_retain_info(li) < 1.0 + out *= ", retain_info=$(get_retain_info(li))" + end + print(io, out) +end + +function initialize_processor!( + li::LikelihoodInformed, + in_data::MM, + out_data::MM, + ::Dict{Symbol, SM1}, + output_structure_matrices::Dict{Symbol, SM2}, + input_structure_vectors::Dict{Symbol, SV1}, + output_structure_vectors::Dict{Symbol, SV2}, + apply_to::AS, +) where { + MM <: AbstractMatrix, + SM1 <: StructureMatrix, + SM2 <: StructureMatrix, + SV1 <: StructureVector, + SV2 <: StructureVector, + AS <: AbstractString, +} + input_dim = size(in_data, 1) + output_dim = size(out_data, 1) + + + if length(get_encoder_mat(li)) == 0 + iters = get_iters(li) + + if :dt in keys(input_structure_vectors) + alphas = get_structure_vec(input_structure_vectors, :dt) + else + @warn "Structure vectors do not contain key `:dt`. \n Continuing, assuming all vectors come from the prior `:dt=>0`." + iters = [1] + alphas = [0] + end + @info "Constructing a likelihood-informed subspace using, \n iterations:$(get_iters(li)), \n α: $(alphas[iters]) " + diagnostic_mats = Dict{Int64, AbstractMatrix}() + samples_means = Dict{Int64, AbstractMatrix}() + diagnostic_fs = [] + diagnostic_egrads = [] + + obs_noise_cov = Matrix(get_structure_mat(output_structure_matrices, :obs_noise_cov)) + # We convert this to a matrix here to avoid dealing with LinearMaps.jl + obs_whitened = if obs_noise_cov ≈ I + obs_noise_cov = I(output_dim) + true + else + @warn "Consider using decorrelate_structure_mat to gain obs_noise_cov = I before calling likelihood_informed" + false + end + noise_cov_inv = inv(obs_noise_cov) + + li.apply_to = apply_to + + for (it, α) in zip(iters, alphas[iters]) # take the iterations from alpha + #(NB! "iters" may not be 1:end) + + # construct the diagnostic matrix, for which we take the eigendecomposition to find encoder/decoder matrices + y = if α ≈ 0.0 + # For α=0, it doesn't matter what this value is, so we avoid requiring its presence + zeros(size(out_data, 1)) + else + vec(get_structure_vec(output_structure_vectors, :observation)[1]) + end + + # take samples from the appropriate distribution as prescribed by alpha + samples_in, samples_out = + if (:samples_in ∈ keys(input_structure_vectors)) && (:samples_out ∈ keys(output_structure_vectors)) + ( + get_structure_vec(input_structure_vectors, :samples_in)[it], + get_structure_vec(output_structure_vectors, :samples_out)[it], + ) + else + @info "Structure vectors either not provided, else do not contain keys `:samples_in, :samples_out`. \n Continuing using input-output pairs as structure vectors" + (in_data, out_data) + end + samples_in_mean = mean(samples_in, dims = 2) + samples_out_mean = mean(samples_out, dims = 2) + + grads = if get_grad_type(li) == :linreg + grad = (samples_out .- samples_out_mean) / (samples_in .- samples_in_mean) + fill(grad, size(samples_in, 2)) + else + @assert get_grad_type(li) == :localsl + + map(eachcol(samples_in)) do u + # TODO: It might be interesting to introduce a parameter to weight this distance with. + # This can be a scalar or a matrix; in the latter case, we can even use the covariance + # of the samples (or the prior covariance). + weights = exp.(-1 / 2 * norm.(eachcol(u .- samples_in)) .^ 2) + weights ./= sum(weights) + D = Diagonal(sqrt.(weights)) + uw = (samples_in .- sum(samples_in * Diagonal(weights); dims = 2)) * D + gw = (samples_out .- sum(samples_out * Diagonal(weights); dims = 2)) * D + gw / uw + end + end + + # get the mean shift + samples_means[it] = if apply_to == "in" + samples_in_mean + else + samples_out_mean + end + + + # get the diagnostics: + # either we get the mats to be truncated, + # or we find the functions & gradients when matrix-free + # if apply_to == "in" || (α ≈ 0 && obs_whitened) #if we keep this branch then we have to possibly combine diagnostic mats and f's + if apply_to == "in" + diagnostic_mats[it] = hermitianpart( + mean( + grad' * + noise_cov_inv * + ((1 - α) * obs_noise_cov + α^2 * (y - g) * (y - g)') * + noise_cov_inv * + grad for (g, grad) in zip(eachcol(samples_out), grads) + ), + ) + elseif apply_to == "out" && (α ≈ 0 && obs_whitened) && (length(alphas[iters]) == 1) # special case for output space (whitened and prior-only distribution) + diagnostic_mats[it] = hermitianpart(mean(grad * grad' for grad in grads)) + else + # @assert apply_to == "out" && ( !(α ≈ 0 && obs_whitened) || length(alphas[iters]) > 1 ) + @assert apply_to == "out" + # Need to represent the "f" and "egrad" functions for this α + f = + (_, Vs) -> begin + prec = noise_cov_inv - Vs * inv(Vs' * obs_noise_cov * Vs) * Vs' + tr( + mean( + grad' * prec * ((1 - α)obs_noise_cov + α^2 * (y - g) * (y - g)') * prec * grad for + (g, grad) in zip(eachcol(out_data), grads) + ), + ) + end + egrad = + (_, Vs) -> begin + B = Vs * inv(Vs' * obs_noise_cov * Vs) * Vs' + prec = noise_cov_inv - B + + -2obs_noise_cov * + prec * + mean( + begin + A = ((1 - α)obs_noise_cov + α^2 * (y - g) * (y - g)') + S = grad * grad' + (S * prec * A + A * prec * S) + end for (g, grad) in zip(eachcol(out_data), grads) + ) * + B * + Vs + end + + push!(diagnostic_fs, f) + push!(diagnostic_egrads, egrad) + + end + + end + + # summarize path of diagnostic matrices, if we have more than one + encoder_mat = nothing + if length(keys(diagnostic_mats)) > 0 # using diagnostic_mats + if length(iters) > 1 + # trap rule + alpha_weight = zeros(length(iters)) + Δa = diff(alphas[iters]) + alpha_weight[1:(end - 1)] .+= Δa ./ 2 + alpha_weight[2:end] .+= Δa ./ 2 + alpha_weight ./= sum(alpha_weight) + diagnostic_mat = sum(alpha_weight[i] * diagnostic_mats[iter] for (i, iter) in enumerate(iters[2:end])) + samples_mean = sum(alpha_weight[i] * samples_means[iter] for (i, iter) in enumerate(iters[2:end])) + else + diagnostic_mat = diagnostic_mats[iters[1]] + samples_mean = samples_means[iters[1]] + end + + # then get the eigen-decomposition + decomp = eigen(diagnostic_mat, sortby = (-)) + sv_cumsum = cumsum(log.(decomp.values .+ 1) .^ 2) / sum(log.(decomp.values .+ 1) .^ 2) # frac Forstner distance-based cutoff + trunc_val = nothing + retain_info = get_retain_info(li) + if retain_info >= 1.0 + trunc_val = apply_to == "in" ? input_dim : output_dim + else + trunc_val = findfirst(x -> (x ≥ retain_info), sv_cumsum) + trunc_val = isnothing(trunc_val) ? (apply_to == "in" ? input_dim : output_dim) : trunc_val + @info " truncating at $trunc_val/$(length(sv_cumsum)) retaining $(100.0*sv_cumsum[trunc_val])% of the information" + end + encoder_mat = decomp.vectors[:, 1:trunc_val]' + else # using diagnostic_f's and diagnostic_egrads + @assert length(diagnostic_fs) > 0 && length(diagnostic_egrads) > 0 + @assert apply_to == "out" + + diagnostic_f, diagnostic_egrad, samples_mean = if length(iters) > 1 + alpha_weight = zeros(length(iters)) + Δa = diff(alphas[iters]) + alpha_weight[1:(end - 1)] .+= Δa ./ 2 + alpha_weight[2:end] .+= Δa ./ 2 + alpha_weight ./= sum(alpha_weight) + diagnostic_f = (x, Vs) -> sum(w * f(x, Vs) for (f, w) in zip(diagnostic_fs, alpha_weight)) + diagnostic_egrad = + (x, Vs) -> sum(w * egrad(x, Vs) for (egrad, w) in zip(diagnostic_egrads, alpha_weight)) + samples_mean = sum(alpha_weight[i] * samples_means[iter] for (i, iter) in enumerate(iters[2:end])) + + # return: + diagnostic_f, diagnostic_egrad, samples_mean + else + diagnostic_f = diagnostic_fs[1] + diagnostic_egrad = diagnostic_egrads[1] + samples_mean = samples_means[iters[1]] + + # return: + diagnostic_f, diagnostic_egrad, samples_mean + end + + @warn "Using LikelihoodInformed on output data with α≠0 or with obs_noise_cov≠I triggers a manifold optimization process that may take some time. If α=0, consider using decorrelate_structure_mat to gain obs_noise_cov = I before calling likelihood_informed" + + k = 1 + Vs = nothing + retain_info = get_retain_info(li) + while true + M = Grassmann(output_dim, k) + + diagnostic_rgrad = (M, Vs) -> begin + (I - Vs * Vs') * diagnostic_egrad(M, Vs) + end + + Vs = Matrix(qr(randn(output_dim, k)).Q) + quasi_Newton!(M, diagnostic_f, diagnostic_rgrad, Vs; stopping_criterion = StopWhenCostChangeLess(0.1)) + + + ref = diagnostic_f(M, zeros(output_dim, 0)) + val = diagnostic_f(M, Vs) + if val / ref ≤ 1 - retain_info + @info " truncating at $k/$output_dim retaining $(100.0*(1-val/ref))% of the KL divergence reduction" + break # TODO: Start bisecting? + else + newk = min(2k, output_dim) + @info " increasing k from $k to $newk" + k = newk + end + + end + + encoder_mat = Vs' # setting encoder mat + + end + decoder_mat = encoder_mat' + + # creat the linear maps: + # we explicitly make the encoder/decoder maps + encoder_map = LinearMap( + x -> encoder_mat * x, # Ax + x -> encoder_mat' * x, # A'x + size(encoder_mat, 1), # size(A,1) + size(encoder_mat, 2), # size(A,2) + ) + + decoder_map = LinearMap( + x -> decoder_mat * x, # Ax + x -> decoder_mat' * x, # A'x + size(decoder_mat, 1), # size(A,1) + size(decoder_mat, 2), # size(A,2) + ) + + push!(get_encoder_mat(li), encoder_map) + push!(get_decoder_mat(li), decoder_map) + + push!(get_data_mean(li), vec(samples_mean)) + + end + +end + +function _encode_data(li::LikelihoodInformed, data::MM) where {MM <: AbstractMatrix} + data_mean = get_data_mean(li)[1] + encoder_mat = get_encoder_mat(li)[1] + out = zeros(size(encoder_mat, 1), size(data, 2)) + mul!(out, encoder_mat, data .- data_mean) + return out +end + +function _decode_data(li::LikelihoodInformed, data::MM) where {MM <: AbstractMatrix} + data_mean = get_data_mean(li)[1] + decoder_mat = get_decoder_mat(li)[1] + out = zeros(size(decoder_mat, 1), size(data, 2)) + mul!(out, decoder_mat, data) # must use this form to get matrix output of dec*out + return out .+ data_mean +end + +function _encode_structure_matrix(li::LikelihoodInformed, structure_matrix::SM) where {SM <: StructureMatrix} + encoder_mat = get_encoder_mat(li)[1] + return encoder_mat * structure_matrix * encoder_mat' +end + +function _decode_structure_matrix(li::LikelihoodInformed, structure_matrix::SM) where {SM <: StructureMatrix} + decoder_mat = get_decoder_mat(li)[1] + return decoder_mat * structure_matrix * decoder_mat' +end diff --git a/test/GaussianProcess/runtests.jl b/test/GaussianProcess/runtests.jl index 3d7a6080c..1b566221e 100644 --- a/test/GaussianProcess/runtests.jl +++ b/test/GaussianProcess/runtests.jl @@ -74,6 +74,8 @@ using CalibrateEmulateSample.Utilities Emulators.optimize_hyperparameters!(em1) + @test_throws ErrorException Emulators.optimize_hyperparameters!(10) # not an mlt + μ1, σ1² = Emulators.predict(em1, new_inputs) @test vec(μ1) ≈ [0.0, 1.0, 0.0, -1.0, 0.0] atol = 0.3 diff --git a/test/Utilities/runtests.jl b/test/Utilities/runtests.jl index 7acda147c..8703e6cd3 100644 --- a/test/Utilities/runtests.jl +++ b/test/Utilities/runtests.jl @@ -19,16 +19,32 @@ using CalibrateEmulateSample.ParameterDistributions n_ens = 10 dim_obs = 3 dim_par = 2 - initial_ensemble = randn(rng, dim_par, n_ens)#params are cols + prior = constrained_gaussian("test", 1.0, 2.0, 0.0, Inf, repeats = dim_par) + initial_ensemble = construct_initial_ensemble(rng, prior, n_ens) # params are cols y_obs = randn(rng, dim_obs) Γy = Matrix{Float64}(I, dim_obs, dim_obs) ekp = EnsembleKalmanProcesses.EnsembleKalmanProcess(initial_ensemble, y_obs, Γy, Inversion(), rng = rng) - g_ens = randn(rng, dim_obs, n_ens) # data are cols + function G(rng, x::MM, Γy) where {MM <: AbstractMatrix} + d_in, d_ens = size(x) + d_out = size(Γy, 1) + A = randn(rng, d_out, d_in) + b = abs.(randn(rng, d_out, 1)) + return A * x .+ b .+ rand(MvNormal(zeros(d_out), Γy), d_ens) + end + g_ens = G(rng, initial_ensemble, Γy) # data are cols EnsembleKalmanProcesses.update_ensemble!(ekp, g_ens) training_points = get_training_points(ekp, 1) @test get_inputs(training_points) ≈ initial_ensemble @test get_outputs(training_points) ≈ g_ens + g_ens_final = G(rng, get_ϕ_final(prior, ekp), Γy) + training_points = get_training_points(ekp, 1:2, g_final = g_ens_final) + @test get_inputs(training_points) ≈ reduce(hcat, get_u(ekp)) + @test get_outputs(training_points) ≈ reduce(hcat, [g_ens, g_ens_final]) + @test_throws ArgumentError get_training_points(ekp, 1:2) + @test_throws ArgumentError get_training_points(ekp, 1:2, g_final = [1]) + @test_throws ArgumentError get_training_points(ekp, 1:2, g_final = g_ens_final') + #positive definiteness mat = reshape(collect(-3:(-3 + 10^2 - 1)), 10, 10) tol = 1e12 * eps() @@ -42,6 +58,51 @@ using CalibrateEmulateSample.ParameterDistributions @test isposdef(pdmat2) @test minimum(eigvals(pdmat2)) >= (1 - 1e-4) * tol + # get encoder kwargs from ekp and prior + encoder_kwargs = encoder_kwargs_from(ekp, prior, final_samples_out = g_ens_final) + + prior_kwargs = (; prior_cov = cov(prior)) + obs_kwargs = (; obs_noise_cov = [Γy], observation = [y_obs]) + io_kwargs = (; + input_structure_vecs = Dict(:dt => [0, get_algorithm_time(ekp)...], :samples_in => get_u(ekp)), + output_structure_vecs = Dict( + :dt => [0, get_algorithm_time(ekp)...], + :samples_out => [get_g(ekp)..., g_ens_final], + ), + ) + test_kwargs = merge(prior_kwargs, obs_kwargs, io_kwargs) + + @test all(encoder_kwargs[key] == test_kwargs[key] for key in keys(encoder_kwargs)) + + + # remove final g + encoder_reduced_kwargs = encoder_kwargs_from(ekp, prior) + io_reduced_kwargs = (; + input_structure_vecs = Dict( + :dt => [0, get_algorithm_time(ekp)...][1:(end - 1)], + :samples_in => get_u(ekp)[1:(end - 1)], + ), + output_structure_vecs = Dict(:dt => [0, get_algorithm_time(ekp)...][1:(end - 1)], :samples_out => get_g(ekp)), + ) + test_reduced_kwargs = merge(prior_kwargs, obs_kwargs, io_reduced_kwargs) + @test all(encoder_reduced_kwargs[key] == test_reduced_kwargs[key] for key in keys(encoder_kwargs)) + + # replace samples: + encoder_reduced_kwargs_2 = encoder_kwargs_from( + ekp, + prior; + dt = [0, 0, get_algorithm_time(ekp)...], + samples_in = [get_u(ekp)[1], get_u(ekp)[1], get_u(ekp)[1]], + samples_out = [get_g(ekp)[1]], # 2-short + final_samples_out = [get_g(ekp)[1], g_ens_final], # extend by 2 + ) + + @test encoder_reduced_kwargs_2[:output_structure_vecs] == + Dict(:dt => [0, 0, get_algorithm_time(ekp)...], :samples_out => [get_g(ekp)[1], get_g(ekp)[1], g_ens_final]) + + + # for the following experiments + encoder_kwargs_for_exps = encoder_kwargs_from(ekp, prior, final_samples_out = g_ens_final) end @@ -158,6 +219,8 @@ end @test Utilities.get_structure_mat(structure_mats, "c") == [1 2; 3 4] # quick build tests and test getters + + # elementwise zs = zscore_scale() mm = minmax_scale() qq = quartile_scale() @@ -174,6 +237,7 @@ end @test get_data_decoder_mat(QQ) == [4] @test get_struct_encoder_mat(QQ) == [5] @test get_struct_decoder_mat(QQ) == [6] + # decorrelator dd = decorrelate() @test get_retain_var(dd) == 1.0 @test get_decorrelate_with(dd) == "combined" @@ -191,7 +255,7 @@ end @test get_max_rank(DD) == 5 @test get_psvd_kwargs(DD) == (; test = 6) - + # canonical correlation cc = canonical_correlation() @test get_retain_var(cc) == 1.0 cc2 = canonical_correlation(retain_var = 0.7) @@ -202,14 +266,36 @@ end @test get_decoder_mat(cc3) == [3] @test get_apply_to(cc3) == "test" + # likelihood informed + ll = likelihood_informed() + @test get_retain_info(ll) == 1.0 + @test get_iters(ll) == [1] + @test get_grad_type(ll) == :linreg + ll2 = likelihood_informed(retain_info = 0.99, iters = 3:5, grad_type = :localsl) + @test get_retain_info(ll2) == 0.99 + @test get_iters(ll2) == 3:5 + @test get_grad_type(ll2) == :localsl + ll3 = LikelihoodInformed([2], [3], [4], 0.99, nothing, [3:5], :localsl) + @test get_encoder_mat(ll3) == [2] + @test get_decoder_mat(ll3) == [3] + @test get_data_mean(ll3) == [4] + @test_throws ArgumentError likelihood_informed(grad_type = :bad_type) + @test_throws ArgumentError likelihood_informed(iters = 1.3) # test equalities cc = canonical_correlation() cc_copy = canonical_correlation() dd = decorrelate() dd_copy = decorrelate() + zs = zscore_scale() + zs_copy = zscore_scale() + ll = likelihood_informed() + ll_copy = likelihood_informed() + @test cc == cc_copy @test dd == dd_copy + @test zs == zs_copy + @test ll == ll_copy # get some data as IO pairs for functional tests @@ -234,6 +320,8 @@ end "canonical-correlation", "decorrelate-structure-mat-retain-0.95-var", "canonical-correlation-0.95-var", + "likelihood_informed-0.99-info", + "likelihood_informed-0.99-info-acc", ] # Test encodings-decodings individually @@ -247,9 +335,25 @@ end (canonical_correlation(), "in_and_out"), (decorrelate_structure_mat(retain_var = 0.95), "in_and_out"), (canonical_correlation(retain_var = 0.95), "in_and_out"), + (likelihood_informed(retain_info = 0.99), "in_and_out"), + (likelihood_informed(retain_info = 0.99, iters = 1:2, grad_type = :localsl), "in_and_out"), ] - lossless = [fill(true, 6); fill(false, 4)] # are these lossless approximations? + lossless = [fill(true, 6); fill(false, length(schedules) - 6)] # are these lossless approximations? + + # kwargs - can usually get from EKP + prior_kwargs = (; prior_cov = prior_cov) + obs_kwargs = (; obs_noise_cov = [obs_noise_cov], observation = [vec(out_data[:, 1])]) + io_kwargs = (; + input_structure_vecs = Dict(:dt => [0, 0.5], :samples_in => [in_data, in_data .+ 1]), + output_structure_vecs = Dict(:dt => [0, 0.5], :samples_out => [out_data, out_data .+ 1]), + ) + test_kwargs = merge(prior_kwargs, obs_kwargs, io_kwargs) + + # quick test without struct. vec, + test_kwargs_no_svs = merge(prior_kwargs, obs_kwargs) + sch_test = create_encoder_schedule((likelihood_informed(retain_info = 0.85), "in_and_out")) + initialize_and_encode_with_schedule!(sch_test, io_pairs; test_kwargs_no_svs...) # functional test pipeline tol = 1e-12 @@ -257,7 +361,7 @@ end for (name, sch, ll_flag) in zip(test_names, schedules, lossless) encoder_schedule = create_encoder_schedule(sch) (encoded_io_pairs, encoded_input_structure_mats, encoded_output_structure_mats, _, _) = - initialize_and_encode_with_schedule!(encoder_schedule, io_pairs; prior_cov, obs_noise_cov) + initialize_and_encode_with_schedule!(encoder_schedule, io_pairs; test_kwargs...) (decoded_io_pairs, decoded_input_structure_mat, decoded_output_structure_mat) = decode_with_schedule( encoder_schedule, @@ -265,6 +369,18 @@ end encoded_input_structure_mats[:prior_cov], encoded_output_structure_mats[:obs_noise_cov], ) + enc_in_dim = get_encoded_dim(encoder_schedule, "in") + enc_out_dim = get_encoded_dim(encoder_schedule, "out") + enc_dims = get_encoded_dim(encoder_schedule) + @test enc_in_dim == enc_dims["in"] + @test enc_out_dim == enc_dims["out"] + @test enc_in_dim == size(get_inputs(encoded_io_pairs), 1) + @test enc_out_dim == size(get_outputs(encoded_io_pairs), 1) + @test isnothing(get_encoded_dim([], "in")) + @test_throws ArgumentError get_encoded_dim(encoder_schedule, "bad_in") + + + for (enc_dat, dec_dat, test_dat, enc_covv, dec_covv, test_covv, dim) in zip( (get_inputs(encoded_io_pairs), get_outputs(encoded_io_pairs)), (get_inputs(decoded_io_pairs), get_outputs(decoded_io_pairs)), @@ -274,6 +390,7 @@ end (prior_cov, obs_noise_cov), (in_dim, out_dim), ) + # univariate "rescaling" tests if name == "zscore" stat_vec = [[mean(dd), std(dd)] for dd in eachrow(enc_dat)] @@ -428,6 +545,7 @@ end in_mat = in_dat * in_dat' out_mat = out_dat * out_dat' for (i_o, dat, mat) in (("in", in_dat, in_mat), ("out", out_dat, out_mat)) + enc_dat = encode_data(encoder_schedule, dat, i_o) dec_dat = decode_data(encoder_schedule, enc_dat, i_o) enc_mat = Matrix(encode_structure_matrix(encoder_schedule, mat, i_o)) @@ -442,6 +560,13 @@ end @test isapprox(norm((D * enc_dat + b) - dec_dat), 0; atol = tol * size(D, 1)) @test isapprox(norm(E * mat * E' - enc_mat), 0; atol = tol * size(E, 1)^2) @test isapprox(norm(D * enc_mat * D' - dec_mat), 0; atol = tol * size(D, 1)^2) + + # test vec input + enc_dat_vec = encode_data(encoder_schedule, vec(dat), i_o) + dec_dat_vec = decode_data(encoder_schedule, enc_dat_vec, i_o) + @test isapprox(norm(enc_dat_vec - vec(enc_dat)), 0; atol = tol) + @test isapprox(norm(dec_dat_vec - vec(dec_dat)), 0; atol = tol) + end end