diff --git a/FORMULATION_AUDIT.md b/FORMULATION_AUDIT.md new file mode 100644 index 0000000..6e78357 --- /dev/null +++ b/FORMULATION_AUDIT.md @@ -0,0 +1,59 @@ +# RKHS Formulation Audit + +This repository uses ridgeless RKHS collocation: each independent kernel +function is identified by including its squared RKHS norm, `alpha' K alpha`, +in the objective. The active implementation uses direct JAX callbacks into UNO. + +## Asset Pricing + +- RKHS functions: asset price/costate `p`. +- Algebraic helpers: none. +- Objective: `||p||_H^2`. +- Constraints: collocated asset-pricing ODE `dp/dt = r p - x(t)`. +- Solver implementation: direct JAX/UNO quadratic model. + +## Basic Neoclassical Growth + +- RKHS functions: capital `k`, consumption `c`, costate `mu`. +- Algebraic helpers: none. +- Objective: `||k||_H^2 + ||c||_H^2 + ||mu||_H^2`. +- Constraints: resource equation, Euler equation, `mu*c = 1`, and positive + domain guards for `k`, `c`, and `mu`. +- Solver implementation: direct JAX/UNO nonlinear model; adding the `c` norm + removes the former under-identification of consumption coefficients. + +## Concave-Convex Growth + +- RKHS functions: capital `k`, consumption `c`, costate `mu`. +- Algebraic helpers: diagnostic production power `z`, output `Y`, and marginal + product `P` returned after the solve. +- Objective: `||k||_H^2 + ||c||_H^2 + ||mu||_H^2`. +- Constraints: same economic equations as basic growth with production replaced + by `A max(k^a, b_1 k^a - b_2)`. JAX traces the max production function and its + marginal product directly; the solver does not use steady states, basin + thresholds, or branch enumeration. Residuals are checked on the collocation + grid and a denser validation grid; ambiguous crossing/local-solve failures + are rejected quickly rather than silently plotted. +- Solver implementation: thin public wrapper around `neoclassical_growth_matern` + with kinked production parameters. + +## Human Capital + +- RKHS functions: physical capital `k`, human capital `h`, physical investment + `i_k`, human investment `i_h`, consumption `c`, and costates `mu_k`, `mu_h`. +- Algebraic helpers: none. +- Objective: sum of all seven squared RKHS norms. +- Constraints: two accumulation equations, two Euler equations, resource + feasibility, `mu_k*c = 1`, and `mu_k = mu_h`. +- Solver implementation: direct JAX/UNO nonlinear model with the small + initial-condition system solved in JAX through `nlls_gram`. + +## Optimal Advertising + +- RKHS functions: market share `x`, costate `mu`, advertising control `u`. +- Algebraic helpers: none. +- Objective: `||x||_H^2 + ||mu||_H^2 + ||u||_H^2`. +- Constraints: market-share dynamics, costate equation, advertising marginal + condition, and positive control guard `u >= 1e-8`. +- Solver implementation: direct JAX/UNO nonlinear model including the RKHS norm + for the kernel-represented control. diff --git a/Manifest.toml b/Manifest.toml deleted file mode 100644 index 666d359..0000000 --- a/Manifest.toml +++ /dev/null @@ -1,2769 +0,0 @@ -# This file is machine-generated - editing it directly is not advised - -julia_version = "1.12.1" -manifest_format = "2.0" -project_hash = "342b4a51e11fa212424a5b9e47b15ecd5e04a3fb" - -[[deps.ADTypes]] -git-tree-sha1 = "27cecae79e5cc9935255f90c53bb831cc3c870d7" -uuid = "47edcb42-4c32-4615-8424-f2b9edc5f35b" -version = "1.18.0" -weakdeps = ["ChainRulesCore", "ConstructionBase", "EnzymeCore"] - - [deps.ADTypes.extensions] - ADTypesChainRulesCoreExt = "ChainRulesCore" - ADTypesConstructionBaseExt = "ConstructionBase" - ADTypesEnzymeCoreExt = "EnzymeCore" - -[[deps.ASL_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "6252039f98492252f9e47c312c8ffda0e3b9e78d" -uuid = "ae81ac8f-d209-56e5-92de-9978fef736f9" -version = "0.1.3+0" - -[[deps.Accessors]] -deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "MacroTools"] -git-tree-sha1 = "3b86719127f50670efe356bc11073d84b4ed7a5d" -uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" -version = "0.1.42" - - [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" -uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "4.4.0" -weakdeps = ["SparseArrays", "StaticArrays"] - - [deps.Adapt.extensions] - AdaptSparseArraysExt = "SparseArrays" - AdaptStaticArraysExt = "StaticArrays" - -[[deps.AliasTables]] -deps = ["PtrArrays", "Random"] -git-tree-sha1 = "9876e1e164b144ca45e9e3198d0b689cadfed9ff" -uuid = "66dad0bd-aa9a-41b7-9441-69ab47430ed8" -version = "1.1.3" - -[[deps.AlmostBlockDiagonals]] -deps = ["ConcreteStructs"] -git-tree-sha1 = "743abe5e5fe8cff96dad4123f263c0d8eee281c0" -uuid = "a95523ee-d6da-40b5-98cc-27bc505739d5" -version = "0.1.10" - -[[deps.ArgTools]] -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.ArrayInterface]] -deps = ["Adapt", "LinearAlgebra"] -git-tree-sha1 = "d2cd034553ee6ca084edaaf8ed6c9d50fd01555d" -uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.21.0" - - [deps.ArrayInterface.extensions] - ArrayInterfaceBandedMatricesExt = "BandedMatrices" - ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" - ArrayInterfaceCUDAExt = "CUDA" - ArrayInterfaceCUDSSExt = ["CUDSS", "CUDA"] - ArrayInterfaceChainRulesCoreExt = "ChainRulesCore" - ArrayInterfaceChainRulesExt = "ChainRules" - ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" - ArrayInterfaceMetalExt = "Metal" - ArrayInterfaceReverseDiffExt = "ReverseDiff" - ArrayInterfaceSparseArraysExt = "SparseArrays" - ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" - ArrayInterfaceTrackerExt = "Tracker" - - [deps.ArrayInterface.weakdeps] - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" - ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" - Metal = "dde4c033-4e86-420c-a63e-0dd931031962" - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" - -[[deps.ArrayLayouts]] -deps = ["FillArrays", "LinearAlgebra", "StaticArrays"] -git-tree-sha1 = "355ab2d61069927d4247cd69ad0e1f140b31e30d" -uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" -version = "1.12.0" -weakdeps = ["SparseArrays"] - - [deps.ArrayLayouts.extensions] - ArrayLayoutsSparseArraysExt = "SparseArrays" - -[[deps.Artifacts]] -uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" -version = "1.11.0" - -[[deps.BandedMatrices]] -deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra", "PrecompileTools"] -git-tree-sha1 = "4826c9fe6023a87029e54870ad1a9800c7ea6623" -uuid = "aae01518-5342-5314-be14-df237901396f" -version = "1.10.1" - - [deps.BandedMatrices.extensions] - BandedMatricesSparseArraysExt = "SparseArrays" - CliqueTreesExt = "CliqueTrees" - - [deps.BandedMatrices.weakdeps] - CliqueTrees = "60701a23-6482-424a-84db-faee86b9b1f8" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - -[[deps.Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" -version = "1.11.0" - -[[deps.BenchmarkTools]] -deps = ["Compat", "JSON", "Logging", "Printf", "Profile", "Statistics", "UUIDs"] -git-tree-sha1 = "7fecfb1123b8d0232218e2da0c213004ff15358d" -uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" -version = "1.6.3" - -[[deps.BitFlags]] -git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" -uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35" -version = "0.1.9" - -[[deps.BitTwiddlingConvenienceFunctions]] -deps = ["Static"] -git-tree-sha1 = "f21cfd4950cb9f0587d5067e69405ad2acd27b87" -uuid = "62783981-4cbd-42fc-bca8-16325de8dc4b" -version = "0.1.6" - -[[deps.BoundaryValueDiffEq]] -deps = ["ADTypes", "BoundaryValueDiffEqAscher", "BoundaryValueDiffEqCore", "BoundaryValueDiffEqFIRK", "BoundaryValueDiffEqMIRK", "BoundaryValueDiffEqMIRKN", "BoundaryValueDiffEqShooting", "DiffEqBase", "FastClosures", "ForwardDiff", "LinearAlgebra", "Reexport", "SciMLBase"] -git-tree-sha1 = "d6ec33e4516b2e790a64128afdb54f3b536667a7" -uuid = "764a87c0-6b3e-53db-9096-fe964310641d" -version = "5.18.0" - - [deps.BoundaryValueDiffEq.extensions] - BoundaryValueDiffEqODEInterfaceExt = "ODEInterface" - - [deps.BoundaryValueDiffEq.weakdeps] - ODEInterface = "54ca160b-1b9f-5127-a996-1867f4bc2a2c" - -[[deps.BoundaryValueDiffEqAscher]] -deps = ["ADTypes", "AlmostBlockDiagonals", "BoundaryValueDiffEqCore", "ConcreteStructs", "DiffEqBase", "DifferentiationInterface", "FastClosures", "ForwardDiff", "LinearAlgebra", "PreallocationTools", "RecursiveArrayTools", "Reexport", "SciMLBase", "Setfield"] -git-tree-sha1 = "47c833c459738a3f27c5b458ecf7832a4731ef4d" -uuid = "7227322d-7511-4e07-9247-ad6ff830280e" -version = "1.8.0" - -[[deps.BoundaryValueDiffEqCore]] -deps = ["ADTypes", "Adapt", "ArrayInterface", "ConcreteStructs", "DiffEqBase", "ForwardDiff", "LineSearch", "LinearAlgebra", "Logging", "NonlinearSolveFirstOrder", "PreallocationTools", "RecursiveArrayTools", "Reexport", "SciMLBase", "Setfield", "SparseArrays", "SparseConnectivityTracer", "SparseMatrixColorings"] -git-tree-sha1 = "b7b4d8cc80f116eab2eb6124dba58ea7aef31b85" -uuid = "56b672f2-a5fe-4263-ab2d-da677488eb3a" -version = "1.11.1" - -[[deps.BoundaryValueDiffEqFIRK]] -deps = ["ADTypes", "ArrayInterface", "BandedMatrices", "BoundaryValueDiffEqCore", "ConcreteStructs", "DiffEqBase", "DifferentiationInterface", "FastAlmostBandedMatrices", "FastClosures", "ForwardDiff", "LinearAlgebra", "PreallocationTools", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "Setfield", "SparseArrays"] -git-tree-sha1 = "325e6981a414cfa5181218936c23f0e16dee8f08" -uuid = "85d9eb09-370e-4000-bb32-543851f73618" -version = "1.9.0" - -[[deps.BoundaryValueDiffEqMIRK]] -deps = ["ADTypes", "ArrayInterface", "BandedMatrices", "BoundaryValueDiffEqCore", "ConcreteStructs", "DiffEqBase", "DifferentiationInterface", "FastAlmostBandedMatrices", "FastClosures", "ForwardDiff", "LinearAlgebra", "PreallocationTools", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "Setfield", "SparseArrays"] -git-tree-sha1 = "da6ae5e564ad06ced4d7504929c58130558007dd" -uuid = "1a22d4ce-7765-49ea-b6f2-13c8438986a6" -version = "1.9.0" - -[[deps.BoundaryValueDiffEqMIRKN]] -deps = ["ADTypes", "ArrayInterface", "BandedMatrices", "BoundaryValueDiffEqCore", "ConcreteStructs", "DiffEqBase", "DifferentiationInterface", "FastAlmostBandedMatrices", "FastClosures", "ForwardDiff", "LinearAlgebra", "PreallocationTools", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "Setfield", "SparseArrays"] -git-tree-sha1 = "609c2d03ea024df0d475fee483b93cf0e87c29d6" -uuid = "9255f1d6-53bf-473e-b6bd-23f1ff009da4" -version = "1.8.0" - -[[deps.BoundaryValueDiffEqShooting]] -deps = ["ADTypes", "ArrayInterface", "BandedMatrices", "BoundaryValueDiffEqCore", "ConcreteStructs", "DiffEqBase", "DifferentiationInterface", "FastAlmostBandedMatrices", "FastClosures", "ForwardDiff", "LinearAlgebra", "PreallocationTools", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "Setfield", "SparseArrays"] -git-tree-sha1 = "ba9bd1f31b58bfd5e48a56da0a426bcbd3462546" -uuid = "ed55bfe0-3725-4db6-871e-a1dc9f42a757" -version = "1.9.0" - -[[deps.BracketingNonlinearSolve]] -deps = ["CommonSolve", "ConcreteStructs", "NonlinearSolveBase", "PrecompileTools", "Reexport", "SciMLBase"] -git-tree-sha1 = "57f9f59bec88ce80cd3e46efc39f126395789bb0" -uuid = "70df07ce-3d50-431d-a3e7-ca6ddb60ac1e" -version = "1.5.0" -weakdeps = ["ChainRulesCore", "ForwardDiff"] - - [deps.BracketingNonlinearSolve.extensions] - BracketingNonlinearSolveChainRulesCoreExt = ["ChainRulesCore", "ForwardDiff"] - BracketingNonlinearSolveForwardDiffExt = "ForwardDiff" - -[[deps.Bzip2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1b96ea4a01afe0ea4090c5c8039690672dd13f2e" -uuid = "6e34b625-4abd-537c-b88f-471c36dfa7a0" -version = "1.0.9+0" - -[[deps.CEnum]] -git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc" -uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82" -version = "0.5.0" - -[[deps.CPUSummary]] -deps = ["CpuId", "IfElse", "PrecompileTools", "Preferences", "Static"] -git-tree-sha1 = "f3a21d7fc84ba618a779d1ed2fcca2e682865bab" -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" -uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" -version = "1.18.5+0" - -[[deps.ChainRulesCore]] -deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "e4c6a16e77171a5f5e25e9646617ab1c276c5607" -uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.26.0" -weakdeps = ["SparseArrays"] - - [deps.ChainRulesCore.extensions] - ChainRulesCoreSparseArraysExt = "SparseArrays" - -[[deps.CloseOpenIntervals]] -deps = ["Static", "StaticArrayInterface"] -git-tree-sha1 = "05ba0d07cd4fd8b7a39541e31a7b0254704ea581" -uuid = "fb6a15b2-703c-40df-9091-08a04967cfa9" -version = "0.1.13" - -[[deps.CodecBzip2]] -deps = ["Bzip2_jll", "TranscodingStreams"] -git-tree-sha1 = "84990fa864b7f2b4901901ca12736e45ee79068c" -uuid = "523fee87-0ab8-5b00-afb7-3ecf72e48cfd" -version = "0.8.5" - -[[deps.CodecZlib]] -deps = ["TranscodingStreams", "Zlib_jll"] -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.CommonSolve]] -git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" -uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" -version = "0.2.4" - -[[deps.CommonSubexpressions]] -deps = ["MacroTools"] -git-tree-sha1 = "cda2cfaebb4be89c9084adaca7dd7333369715c5" -uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" -version = "0.3.1" - -[[deps.CommonWorldInvalidations]] -git-tree-sha1 = "ae52d1c52048455e85a387fbee9be553ec2b68d0" -uuid = "f70d9fcc-98c5-4d4a-abd7-e4cdeebd8ca8" -version = "1.0.0" - -[[deps.Compat]] -deps = ["TOML", "UUIDs"] -git-tree-sha1 = "9d8a54ce4b17aa5bdce0ea5c34bc5e7c340d16ad" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.18.1" -weakdeps = ["Dates", "LinearAlgebra"] - - [deps.Compat.extensions] - CompatLinearAlgebraExt = "LinearAlgebra" - -[[deps.CompilerSupportLibraries_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.3.0+1" - -[[deps.CompositionsBase]] -git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" -uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b" -version = "0.1.2" -weakdeps = ["InverseFunctions"] - - [deps.CompositionsBase.extensions] - CompositionsBaseInverseFunctionsExt = "InverseFunctions" - -[[deps.ConcreteStructs]] -git-tree-sha1 = "f749037478283d372048690eb3b5f92a79432b34" -uuid = "2569d6c7-a4a2-43d3-a901-331e8e4be471" -version = "0.2.3" - -[[deps.ConcurrentUtilities]] -deps = ["Serialization", "Sockets"] -git-tree-sha1 = "d9d26935a0bcffc87d2613ce14c527c99fc543fd" -uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" -version = "2.5.0" - -[[deps.ConstructionBase]] -git-tree-sha1 = "b4b092499347b18a015186eae3042f72267106cb" -uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.6.0" - - [deps.ConstructionBase.extensions] - ConstructionBaseIntervalSetsExt = "IntervalSets" - ConstructionBaseLinearAlgebraExt = "LinearAlgebra" - ConstructionBaseStaticArraysExt = "StaticArrays" - - [deps.ConstructionBase.weakdeps] - IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" - LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - -[[deps.Contour]] -git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" -uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" -version = "0.6.3" - -[[deps.CpuId]] -deps = ["Markdown"] -git-tree-sha1 = "fcbb72b032692610bfbdb15018ac16a36cf2e406" -uuid = "adafc99b-e345-5852-983c-f28acb93d879" -version = "0.3.1" - -[[deps.DataAPI]] -git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" -uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" -version = "1.16.0" - -[[deps.DataStructures]] -deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "4e1fe97fdaed23e9dc21d4d664bea76b65fc50a0" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.22" - -[[deps.Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" -version = "1.11.0" - -[[deps.Dbus_jll]] -deps = ["Artifacts", "Expat_jll", "JLLWrappers", "Libdl"] -git-tree-sha1 = "473e9afc9cf30814eb67ffa5f2db7df82c3ad9fd" -uuid = "ee1fde0b-3d02-5ea6-8484-8dfef6360eab" -version = "1.16.2+0" - -[[deps.DelayDiffEq]] -deps = ["ArrayInterface", "DataStructures", "DiffEqBase", "FastBroadcast", "ForwardDiff", "LinearAlgebra", "Logging", "OrdinaryDiffEq", "OrdinaryDiffEqCore", "OrdinaryDiffEqDefault", "OrdinaryDiffEqDifferentiation", "OrdinaryDiffEqFunctionMap", "OrdinaryDiffEqNonlinearSolve", "OrdinaryDiffEqRosenbrock", "Printf", "RecursiveArrayTools", "Reexport", "SciMLBase", "SimpleNonlinearSolve", "SimpleUnPack", "SymbolicIndexingInterface"] -git-tree-sha1 = "bb84c7ab3de56ada66430b5671db3b3cdaadcd61" -uuid = "bcd4f6db-9728-5f36-b5f7-82caef46ccdb" -version = "5.61.0" - -[[deps.DelimitedFiles]] -deps = ["Mmap"] -git-tree-sha1 = "9e2f36d3c96a820c678f2f1f1782582fcf685bae" -uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" -version = "1.9.1" - -[[deps.DiffEqBase]] -deps = ["ArrayInterface", "ConcreteStructs", "DocStringExtensions", "EnzymeCore", "FastBroadcast", "FastClosures", "FastPower", "FunctionWrappers", "FunctionWrappersWrappers", "LinearAlgebra", "Logging", "Markdown", "MuladdMacro", "PrecompileTools", "Printf", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "SciMLStructures", "Setfield", "Static", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "TruncatedStacktraces"] -git-tree-sha1 = "087632db966c90079a5534e4147afea9136ca39a" -uuid = "2b5f629d-d688-5b77-993f-72d75c75574e" -version = "6.190.2" - - [deps.DiffEqBase.extensions] - DiffEqBaseCUDAExt = "CUDA" - DiffEqBaseChainRulesCoreExt = "ChainRulesCore" - DiffEqBaseEnzymeExt = ["ChainRulesCore", "Enzyme"] - DiffEqBaseForwardDiffExt = ["ForwardDiff"] - DiffEqBaseGTPSAExt = "GTPSA" - DiffEqBaseGeneralizedGeneratedExt = "GeneralizedGenerated" - DiffEqBaseMPIExt = "MPI" - DiffEqBaseMeasurementsExt = "Measurements" - DiffEqBaseMonteCarloMeasurementsExt = "MonteCarloMeasurements" - DiffEqBaseMooncakeExt = "Mooncake" - DiffEqBaseReverseDiffExt = "ReverseDiff" - DiffEqBaseSparseArraysExt = "SparseArrays" - DiffEqBaseTrackerExt = "Tracker" - DiffEqBaseUnitfulExt = "Unitful" - - [deps.DiffEqBase.weakdeps] - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" - GTPSA = "b27dd330-f138-47c5-815b-40db9dd9b6e8" - GeneralizedGenerated = "6b9d7cbe-bcb9-11e9-073f-15a7a543e2eb" - MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" - Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" - MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca" - Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" - Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" - -[[deps.DiffEqCallbacks]] -deps = ["ConcreteStructs", "DataStructures", "DiffEqBase", "DifferentiationInterface", "LinearAlgebra", "Markdown", "RecipesBase", "RecursiveArrayTools", "SciMLBase", "StaticArraysCore"] -git-tree-sha1 = "448d118c4a7763b041fc41cf91c85d23773f1dc2" -uuid = "459566f4-90b8-5000-8ac3-15dfb0a30def" -version = "4.10.1" - - [deps.DiffEqCallbacks.extensions] - DiffEqCallbacksFunctorsExt = "Functors" - - [deps.DiffEqCallbacks.weakdeps] - Functors = "d9f16b24-f501-4c13-a1f2-28368ffc5196" - -[[deps.DiffEqNoiseProcess]] -deps = ["DiffEqBase", "Distributions", "GPUArraysCore", "LinearAlgebra", "Markdown", "Optim", "PoissonRandom", "QuadGK", "Random", "Random123", "RandomNumbers", "RecipesBase", "RecursiveArrayTools", "ResettableStacks", "SciMLBase", "StaticArraysCore", "Statistics"] -git-tree-sha1 = "516d553f5deee7c55b2945b5edf05b6542837887" -uuid = "77a26b50-5914-5dd7-bc55-306e6241c503" -version = "5.24.1" - - [deps.DiffEqNoiseProcess.extensions] - DiffEqNoiseProcessReverseDiffExt = "ReverseDiff" - - [deps.DiffEqNoiseProcess.weakdeps] - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - -[[deps.DiffResults]] -deps = ["StaticArraysCore"] -git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" -uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" -version = "1.1.0" - -[[deps.DiffRules]] -deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] -git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" -uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" -version = "1.15.1" - -[[deps.DifferentialEquations]] -deps = ["BoundaryValueDiffEq", "DelayDiffEq", "DiffEqBase", "DiffEqCallbacks", "DiffEqNoiseProcess", "JumpProcesses", "LinearAlgebra", "LinearSolve", "NonlinearSolve", "OrdinaryDiffEq", "Random", "RecursiveArrayTools", "Reexport", "SciMLBase", "SteadyStateDiffEq", "StochasticDiffEq", "Sundials"] -git-tree-sha1 = "afdc7dfee475828b4f0286d63ffe66b97d7a3fa7" -uuid = "0c46a032-eb83-5123-abaf-570d42b7fbaa" -version = "7.16.1" - -[[deps.DifferentiationInterface]] -deps = ["ADTypes", "LinearAlgebra"] -git-tree-sha1 = "529bebbc74b36a4cfea09dd2aecb1288cd713a6d" -uuid = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63" -version = "0.7.9" - - [deps.DifferentiationInterface.extensions] - DifferentiationInterfaceChainRulesCoreExt = "ChainRulesCore" - DifferentiationInterfaceDiffractorExt = "Diffractor" - DifferentiationInterfaceEnzymeExt = ["EnzymeCore", "Enzyme"] - DifferentiationInterfaceFastDifferentiationExt = "FastDifferentiation" - DifferentiationInterfaceFiniteDiffExt = "FiniteDiff" - DifferentiationInterfaceFiniteDifferencesExt = "FiniteDifferences" - DifferentiationInterfaceForwardDiffExt = ["ForwardDiff", "DiffResults"] - DifferentiationInterfaceGPUArraysCoreExt = "GPUArraysCore" - DifferentiationInterfaceGTPSAExt = "GTPSA" - DifferentiationInterfaceMooncakeExt = "Mooncake" - DifferentiationInterfacePolyesterForwardDiffExt = ["PolyesterForwardDiff", "ForwardDiff", "DiffResults"] - DifferentiationInterfaceReverseDiffExt = ["ReverseDiff", "DiffResults"] - DifferentiationInterfaceSparseArraysExt = "SparseArrays" - DifferentiationInterfaceSparseConnectivityTracerExt = "SparseConnectivityTracer" - DifferentiationInterfaceSparseMatrixColoringsExt = "SparseMatrixColorings" - DifferentiationInterfaceStaticArraysExt = "StaticArrays" - DifferentiationInterfaceSymbolicsExt = "Symbolics" - DifferentiationInterfaceTrackerExt = "Tracker" - DifferentiationInterfaceZygoteExt = ["Zygote", "ForwardDiff"] - - [deps.DifferentiationInterface.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - DiffResults = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" - Diffractor = "9f5e2b26-1114-432f-b630-d3fe2085c51c" - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" - FastDifferentiation = "eb9bf01b-bf85-4b60-bf87-ee5de06c00be" - FiniteDiff = "6a86dc24-6348-571c-b903-95158fe2bd41" - FiniteDifferences = "26cc04aa-876d-5657-8c51-4c34ba976000" - ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" - GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" - GTPSA = "b27dd330-f138-47c5-815b-40db9dd9b6e8" - Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" - PolyesterForwardDiff = "98d1487c-24ca-40b6-b7ab-df2af84e126b" - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - SparseConnectivityTracer = "9f842d2f-2579-4b1d-911e-f412cf18a3f5" - SparseMatrixColorings = "0a514795-09f3-496d-8182-132a7b665d35" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" - Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" - -[[deps.Distances]] -deps = ["LinearAlgebra", "Statistics", "StatsAPI"] -git-tree-sha1 = "c7e3a542b999843086e2f29dac96a618c105be1d" -uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.10.12" -weakdeps = ["ChainRulesCore", "SparseArrays"] - - [deps.Distances.extensions] - DistancesChainRulesCoreExt = "ChainRulesCore" - DistancesSparseArraysExt = "SparseArrays" - -[[deps.Distributed]] -deps = ["Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" -version = "1.11.0" - -[[deps.Distributions]] -deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] -git-tree-sha1 = "3bc002af51045ca3b47d2e1787d6ce02e68b943a" -uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.25.122" - - [deps.Distributions.extensions] - DistributionsChainRulesCoreExt = "ChainRulesCore" - DistributionsDensityInterfaceExt = "DensityInterface" - DistributionsTestExt = "Test" - - [deps.Distributions.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" - Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[deps.DocStringExtensions]] -git-tree-sha1 = "7442a5dfe1ebb773c29cc2962a8980f47221d76c" -uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.9.5" - -[[deps.Downloads]] -deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] -uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" -version = "1.6.0" - -[[deps.EnumX]] -git-tree-sha1 = "bddad79635af6aec424f53ed8aad5d7555dc6f00" -uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" -version = "1.0.5" - -[[deps.EnzymeCore]] -git-tree-sha1 = "e059db5d02720ae826445f5ce2fdfb3d53236b87" -uuid = "f151be2c-9106-41f4-ab19-57ee4f262869" -version = "0.8.14" -weakdeps = ["Adapt"] - - [deps.EnzymeCore.extensions] - AdaptExt = "Adapt" - -[[deps.EpollShim_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "8a4be429317c42cfae6a7fc03c31bad1970c310d" -uuid = "2702e6a9-849d-5ed8-8c21-79e8b8f9ee43" -version = "0.0.20230411+1" - -[[deps.ExceptionUnwrapping]] -deps = ["Test"] -git-tree-sha1 = "d36f682e590a83d63d1c7dbd287573764682d12a" -uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4" -version = "0.1.11" - -[[deps.Expat_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "27af30de8b5445644e8ffe3bcb0d72049c089cf1" -uuid = "2e619515-83b5-522b-bb60-26c02a35a201" -version = "2.7.3+0" - -[[deps.ExponentialUtilities]] -deps = ["Adapt", "ArrayInterface", "GPUArraysCore", "GenericSchur", "LinearAlgebra", "PrecompileTools", "Printf", "SparseArrays", "libblastrampoline_jll"] -git-tree-sha1 = "cae251c76f353e32d32d76fae2fea655eab652af" -uuid = "d4d017d3-3776-5f7e-afef-a10c40355c18" -version = "1.27.0" -weakdeps = ["StaticArrays"] - - [deps.ExponentialUtilities.extensions] - ExponentialUtilitiesStaticArraysExt = "StaticArrays" - -[[deps.ExprTools]] -git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" -uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" -version = "0.1.10" - -[[deps.ExproniconLite]] -git-tree-sha1 = "c13f0b150373771b0fdc1713c97860f8df12e6c2" -uuid = "55351af7-c7e9-48d6-89ff-24e801d99491" -version = "0.10.14" - -[[deps.FFMPEG]] -deps = ["FFMPEG_jll"] -git-tree-sha1 = "95ecf07c2eea562b5adbd0696af6db62c0f52560" -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" -uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" -version = "8.0.0+0" - -[[deps.FastAlmostBandedMatrices]] -deps = ["ArrayInterface", "ArrayLayouts", "BandedMatrices", "ConcreteStructs", "LazyArrays", "LinearAlgebra", "MatrixFactorizations", "PrecompileTools", "Reexport"] -git-tree-sha1 = "9482a2b4face8ade73792c23a54796c79ed1bcbf" -uuid = "9d29842c-ecb8-4973-b1e9-a27b1157504e" -version = "0.1.5" - -[[deps.FastBroadcast]] -deps = ["ArrayInterface", "LinearAlgebra", "Polyester", "Static", "StaticArrayInterface", "StrideArraysCore"] -git-tree-sha1 = "ab1b34570bcdf272899062e1a56285a53ecaae08" -uuid = "7034ab61-46d4-4ed7-9d0f-46aef9175898" -version = "0.3.5" - -[[deps.FastClosures]] -git-tree-sha1 = "acebe244d53ee1b461970f8910c235b259e772ef" -uuid = "9aa1b823-49e4-5ca5-8b0f-3971ec8bab6a" -version = "0.3.2" - -[[deps.FastGaussQuadrature]] -deps = ["LinearAlgebra", "SpecialFunctions", "StaticArrays"] -git-tree-sha1 = "0044e9f5e49a57e88205e8f30ab73928b05fe5b6" -uuid = "442a2c76-b920-505d-bb47-c5924d526838" -version = "1.1.0" - -[[deps.FastPower]] -git-tree-sha1 = "5f7afd4b1a3969dc34d692da2ed856047325b06e" -uuid = "a4df4552-cc26-4903-aec0-212e50a0e84b" -version = "1.1.3" - - [deps.FastPower.extensions] - FastPowerEnzymeExt = "Enzyme" - FastPowerForwardDiffExt = "ForwardDiff" - FastPowerMeasurementsExt = "Measurements" - FastPowerMonteCarloMeasurementsExt = "MonteCarloMeasurements" - FastPowerMooncakeExt = "Mooncake" - FastPowerReverseDiffExt = "ReverseDiff" - FastPowerTrackerExt = "Tracker" - - [deps.FastPower.weakdeps] - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" - Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" - MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca" - Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" - -[[deps.FileWatching]] -uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" -version = "1.11.0" - -[[deps.FillArrays]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "173e4d8f14230a7523ae11b9a3fa9edb3e0efd78" -uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "1.14.0" -weakdeps = ["PDMats", "SparseArrays", "Statistics"] - - [deps.FillArrays.extensions] - FillArraysPDMatsExt = "PDMats" - FillArraysSparseArraysExt = "SparseArrays" - FillArraysStatisticsExt = "Statistics" - -[[deps.FiniteDiff]] -deps = ["ArrayInterface", "LinearAlgebra", "Setfield"] -git-tree-sha1 = "9340ca07ca27093ff68418b7558ca37b05f8aeb1" -uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" -version = "2.29.0" - - [deps.FiniteDiff.extensions] - FiniteDiffBandedMatricesExt = "BandedMatrices" - FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" - FiniteDiffSparseArraysExt = "SparseArrays" - FiniteDiffStaticArraysExt = "StaticArrays" - - [deps.FiniteDiff.weakdeps] - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" - 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.Format]] -git-tree-sha1 = "9c68794ef81b08086aeb32eeaf33531668d5f5fc" -uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" -version = "1.3.7" - -[[deps.ForwardDiff]] -deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] -git-tree-sha1 = "ba6ce081425d0afb2bedd00d9884464f764a9225" -uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "1.2.2" -weakdeps = ["StaticArrays"] - - [deps.ForwardDiff.extensions] - ForwardDiffStaticArraysExt = "StaticArrays" - -[[deps.FreeType2_jll]] -deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "2c5512e11c791d1baed2049c5652441b28fc6a31" -uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" -version = "2.13.4+0" - -[[deps.FriBidi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "7a214fdac5ed5f59a22c2d9a885a16da1c74bbc7" -uuid = "559328eb-81f9-559d-9380-de523a88c83c" -version = "1.0.17+0" - -[[deps.FunctionWrappers]] -git-tree-sha1 = "d62485945ce5ae9c0c48f124a84998d755bae00e" -uuid = "069b7b12-0de2-55c6-9aab-29f3d0a68a2e" -version = "1.1.3" - -[[deps.FunctionWrappersWrappers]] -deps = ["FunctionWrappers"] -git-tree-sha1 = "b104d487b34566608f8b4e1c39fb0b10aa279ff8" -uuid = "77dc65aa-8811-40c2-897b-53d922fa7daf" -version = "0.1.3" - -[[deps.Future]] -deps = ["Random"] -uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" -version = "1.11.0" - -[[deps.GLFW_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libglvnd_jll", "Xorg_libXcursor_jll", "Xorg_libXi_jll", "Xorg_libXinerama_jll", "Xorg_libXrandr_jll", "libdecor_jll", "xkbcommon_jll"] -git-tree-sha1 = "fcb0584ff34e25155876418979d4c8971243bb89" -uuid = "0656b61e-2033-5cc2-a64a-77c0f6c09b89" -version = "3.4.0+2" - -[[deps.GPUArraysCore]] -deps = ["Adapt"] -git-tree-sha1 = "83cf05ab16a73219e5f6bd1bdfa9848fa24ac627" -uuid = "46192b85-c4d5-4398-a991-12ede77f4527" -version = "0.2.0" - -[[deps.GR]] -deps = ["Artifacts", "Base64", "DelimitedFiles", "Downloads", "GR_jll", "HTTP", "JSON", "Libdl", "LinearAlgebra", "Preferences", "Printf", "Qt6Wayland_jll", "Random", "Serialization", "Sockets", "TOML", "Tar", "Test", "p7zip_jll"] -git-tree-sha1 = "f52c27dd921390146624f3aab95f4e8614ad6531" -uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" -version = "0.73.18" - -[[deps.GR_jll]] -deps = ["Artifacts", "Bzip2_jll", "Cairo_jll", "FFMPEG_jll", "Fontconfig_jll", "FreeType2_jll", "GLFW_jll", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Libtiff_jll", "Pixman_jll", "Qt6Base_jll", "Zlib_jll", "libpng_jll"] -git-tree-sha1 = "4b0406b866ea9fdbaf1148bc9c0b887e59f9af68" -uuid = "d2c73de3-f751-5644-a686-071e5b155ba9" -version = "0.73.18+0" - -[[deps.GenericSchur]] -deps = ["LinearAlgebra", "Printf"] -git-tree-sha1 = "a694e2a57394e409f7a11ee0977362a9fafcb8c7" -uuid = "c145ed77-6b09-5dd9-b285-bf645a82121e" -version = "0.5.6" - -[[deps.GettextRuntime_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Libiconv_jll"] -git-tree-sha1 = "45288942190db7c5f760f59c04495064eedf9340" -uuid = "b0724c58-0f36-5564-988d-3bb0596ebc4a" -version = "0.22.4+0" - -[[deps.Ghostscript_jll]] -deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Zlib_jll"] -git-tree-sha1 = "38044a04637976140074d0b0621c1edf0eb531fd" -uuid = "61579ee1-b43e-5ca0-a5da-69d92c66a64b" -version = "9.55.1+0" - -[[deps.Glib_jll]] -deps = ["Artifacts", "GettextRuntime_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] -git-tree-sha1 = "50c11ffab2a3d50192a228c313f05b5b5dc5acb2" -uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" -version = "2.86.0+0" - -[[deps.Graphite2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -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.Grisu]] -git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" -uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" -version = "1.0.2" - -[[deps.HTTP]] -deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"] -git-tree-sha1 = "5e6fe50ae7f23d171f44e311c2960294aaa0beb5" -uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.19" - -[[deps.HarfBuzz_jll]] -deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll"] -git-tree-sha1 = "f923f9a774fcf3f5cb761bfa43aeadd689714813" -uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" -version = "8.5.1+0" - -[[deps.Hwloc_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "XML2_jll", "Xorg_libpciaccess_jll"] -git-tree-sha1 = "3d468106a05408f9f7b6f161d9e7715159af247b" -uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" -version = "2.12.2+0" - -[[deps.HypergeometricFunctions]] -deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] -git-tree-sha1 = "68c173f4f449de5b438ee67ed0c9c748dc31a2ec" -uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" -version = "0.3.28" - -[[deps.IfElse]] -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.IntelOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] -git-tree-sha1 = "ec1debd61c300961f98064cfb21287613ad7f303" -uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2025.2.0+0" - -[[deps.InteractiveUtils]] -deps = ["Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" -version = "1.11.0" - -[[deps.InverseFunctions]] -git-tree-sha1 = "a779299d77cd080bf77b97535acecd73e1c5e5cb" -uuid = "3587e190-3f89-42d0-90ee-14403ec27112" -version = "0.1.17" -weakdeps = ["Dates", "Test"] - - [deps.InverseFunctions.extensions] - InverseFunctionsDatesExt = "Dates" - InverseFunctionsTestExt = "Test" - -[[deps.Ipopt]] -deps = ["Ipopt_jll", "LinearAlgebra", "OpenBLAS32_jll", "PrecompileTools"] -git-tree-sha1 = "e9ba6935a217a75c1f486307681e29288e0388b1" -uuid = "b6b21f68-93f8-5de0-b562-5493be1d77c9" -version = "1.12.0" -weakdeps = ["MathOptInterface"] - - [deps.Ipopt.extensions] - IpoptMathOptInterfaceExt = "MathOptInterface" - -[[deps.Ipopt_jll]] -deps = ["ASL_jll", "Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "MUMPS_seq_jll", "SPRAL_jll", "libblastrampoline_jll"] -git-tree-sha1 = "b33cbc78b8d4de87d18fcd705054a82e2999dbac" -uuid = "9cc047cb-c261-5740-88fc-0cf96f7bdcc7" -version = "300.1400.1900+0" - -[[deps.IrrationalConstants]] -git-tree-sha1 = "b2d91fe939cae05960e760110b328288867b5758" -uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" -version = "0.2.6" - -[[deps.IteratorInterfaceExtensions]] -git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" -uuid = "82899510-4779-5014-852e-03e436cf321d" -version = "1.0.0" - -[[deps.JLFzf]] -deps = ["REPL", "Random", "fzf_jll"] -git-tree-sha1 = "82f7acdc599b65e0f8ccd270ffa1467c21cb647b" -uuid = "1019f520-868f-41f5-a6de-eb00f4b6a39c" -version = "0.1.11" - -[[deps.JLLWrappers]] -deps = ["Artifacts", "Preferences"] -git-tree-sha1 = "0533e564aae234aff59ab625543145446d8b6ec2" -uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" -version = "1.7.1" - -[[deps.JSON]] -deps = ["Dates", "Logging", "Parsers", "PrecompileTools", "StructUtils", "UUIDs", "Unicode"] -git-tree-sha1 = "06ea418d0c95878c8f3031023951edcf25b9e0ef" -uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" -version = "1.2.0" - - [deps.JSON.extensions] - JSONArrowExt = ["ArrowTypes"] - - [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.Jieko]] -deps = ["ExproniconLite"] -git-tree-sha1 = "2f05ed29618da60c06a87e9c033982d4f71d0b6c" -uuid = "ae98c720-c025-4a4a-838c-29b094483192" -version = "0.2.1" - -[[deps.JpegTurbo_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "4255f0032eafd6451d707a51d5f0248b8a165e4d" -uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" -version = "3.1.3+0" - -[[deps.JuMP]] -deps = ["LinearAlgebra", "MacroTools", "MathOptInterface", "MutableArithmetics", "OrderedCollections", "PrecompileTools", "Printf", "SparseArrays"] -git-tree-sha1 = "d6ece925e8798b6f078731ab04ce82c5433b0d64" -uuid = "4076af6c-e467-56ae-b986-b466b2749572" -version = "1.29.2" - - [deps.JuMP.extensions] - JuMPDimensionalDataExt = "DimensionalData" - - [deps.JuMP.weakdeps] - DimensionalData = "0703355e-b756-11e9-17c0-8b28908087d0" - -[[deps.JuliaSyntaxHighlighting]] -deps = ["StyledStrings"] -uuid = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011" -version = "1.12.0" - -[[deps.JumpProcesses]] -deps = ["ArrayInterface", "DataStructures", "DiffEqBase", "DiffEqCallbacks", "DocStringExtensions", "FunctionWrappers", "Graphs", "LinearAlgebra", "PoissonRandom", "Random", "RecursiveArrayTools", "Reexport", "SciMLBase", "Setfield", "StaticArrays", "SymbolicIndexingInterface", "UnPack"] -git-tree-sha1 = "905a2a28770e23f3ed750306ef48eb8c46c3a002" -uuid = "ccbc3e58-028d-4f4c-8cd5-9ae44345cda5" -version = "9.19.1" - - [deps.JumpProcesses.extensions] - JumpProcessesKernelAbstractionsExt = ["Adapt", "KernelAbstractions"] - - [deps.JumpProcesses.weakdeps] - Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" - FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" - KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" - -[[deps.KernelEconExamples]] -deps = ["BoundaryValueDiffEq", "DifferentialEquations", "Distributions", "Ipopt", "JuMP", "LinearAlgebra", "OSQP", "QuadGK", "Statistics"] -path = "." -uuid = "9d687d3a-22d1-4cc8-8dc9-bb15139a4de0" -version = "1.0.0-DEV" - -[[deps.Krylov]] -deps = ["LinearAlgebra", "Printf", "SparseArrays"] -git-tree-sha1 = "d1fc961038207e43982851e57ee257adc37be5e8" -uuid = "ba0b0d4f-ebba-5204-a429-3ac8c609bfb7" -version = "0.10.2" - -[[deps.LAME_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "059aabebaa7c82ccb853dd4a0ee9d17796f7e1bc" -uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" -version = "3.100.3+0" - -[[deps.LERC_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "aaafe88dccbd957a8d82f7d05be9b69172e0cee3" -uuid = "88015f11-f218-50d7-93a8-a6af411a945d" -version = "4.0.1+0" - -[[deps.LLVMOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -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" -version = "1.4.0" - -[[deps.Latexify]] -deps = ["Format", "Ghostscript_jll", "InteractiveUtils", "LaTeXStrings", "MacroTools", "Markdown", "OrderedCollections", "Requires"] -git-tree-sha1 = "44f93c47f9cd6c7e431f2f2091fcba8f01cd7e8f" -uuid = "23fbe1c1-3f47-55db-b15f-69d7ec21a316" -version = "0.16.10" - - [deps.Latexify.extensions] - DataFramesExt = "DataFrames" - SparseArraysExt = "SparseArrays" - SymEngineExt = "SymEngine" - TectonicExt = "tectonic_jll" - - [deps.Latexify.weakdeps] - DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - SymEngine = "123dc426-2d89-5057-bbad-38513e3affd8" - tectonic_jll = "d7dd28d6-a5e6-559c-9131-7eb760cdacc5" - -[[deps.LayoutPointers]] -deps = ["ArrayInterface", "LinearAlgebra", "ManualMemory", "SIMDTypes", "Static", "StaticArrayInterface"] -git-tree-sha1 = "a9eaadb366f5493a5654e843864c13d8b107548c" -uuid = "10f19ff3-798f-405d-979b-55457f8fc047" -version = "0.1.17" - -[[deps.LazyArrays]] -deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra", "MacroTools", "SparseArrays"] -git-tree-sha1 = "79ee64f6ba0a5a49930f51c86f60d7526b5e12c8" -uuid = "5078a376-72f3-5289-bfd5-ec5146d43c02" -version = "2.8.0" - - [deps.LazyArrays.extensions] - LazyArraysBandedMatricesExt = "BandedMatrices" - LazyArraysBlockArraysExt = "BlockArrays" - LazyArraysBlockBandedMatricesExt = "BlockBandedMatrices" - LazyArraysStaticArraysExt = "StaticArrays" - - [deps.LazyArrays.weakdeps] - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" - BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - -[[deps.LazyArtifacts]] -deps = ["Artifacts", "Pkg"] -uuid = "4af54fe1-eca0-43a8-85a7-787d91b784e3" -version = "1.11.0" - -[[deps.LevyArea]] -deps = ["LinearAlgebra", "Random", "SpecialFunctions"] -git-tree-sha1 = "56513a09b8e0ae6485f34401ea9e2f31357958ec" -uuid = "2d8b4e74-eb68-11e8-0fb9-d5eb67b50637" -version = "1.0.0" - -[[deps.LibCURL]] -deps = ["LibCURL_jll", "MozillaCACerts_jll"] -uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" -version = "0.6.4" - -[[deps.LibCURL_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll", "Zlib_jll", "nghttp2_jll"] -uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "8.11.1+1" - -[[deps.LibGit2]] -deps = ["LibGit2_jll", "NetworkOptions", "Printf", "SHA"] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" -version = "1.11.0" - -[[deps.LibGit2_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"] -uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5" -version = "1.9.0+0" - -[[deps.LibSSH2_jll]] -deps = ["Artifacts", "Libdl", "OpenSSL_jll"] -uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.11.3+1" - -[[deps.Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" -version = "1.11.0" - -[[deps.Libffi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "c8da7e6a91781c41a863611c7e966098d783c57a" -uuid = "e9f186c6-92d2-5b65-8a66-fee21dc1b490" -version = "3.4.7+0" - -[[deps.Libglvnd_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll", "Xorg_libXext_jll"] -git-tree-sha1 = "d36c21b9e7c172a44a10484125024495e2625ac0" -uuid = "7e76a0d4-f3c7-5321-8279-8d96eeed0f29" -version = "1.7.1+1" - -[[deps.Libiconv_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809" -uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531" -version = "1.18.0+0" - -[[deps.Libmount_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "3acf07f130a76f87c041cfb2ff7d7284ca67b072" -uuid = "4b2f31a3-9ecc-558c-b454-b3730dcb73e9" -version = "2.41.2+0" - -[[deps.Libtiff_jll]] -deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "LERC_jll", "Libdl", "XZ_jll", "Zlib_jll", "Zstd_jll"] -git-tree-sha1 = "f04133fe05eff1667d2054c53d59f9122383fe05" -uuid = "89763e89-9b03-5906-acba-b20f662cd828" -version = "4.7.2+0" - -[[deps.Libuuid_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "2a7a12fc0a4e7fb773450d17975322aa77142106" -uuid = "38a345b3-de98-5d2b-a5d3-14cd9215e700" -version = "2.41.2+0" - -[[deps.LineSearch]] -deps = ["ADTypes", "CommonSolve", "ConcreteStructs", "FastClosures", "LinearAlgebra", "MaybeInplace", "SciMLBase", "SciMLJacobianOperators", "StaticArraysCore"] -git-tree-sha1 = "97d502765cc5cf3a722120f50da03c2474efce04" -uuid = "87fe0de2-c867-4266-b59a-2f0a94fc965b" -version = "0.1.4" -weakdeps = ["LineSearches"] - - [deps.LineSearch.extensions] - LineSearchLineSearchesExt = "LineSearches" - -[[deps.LineSearches]] -deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] -git-tree-sha1 = "4adee99b7262ad2a1a4bbbc59d993d24e55ea96f" -uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" -version = "7.4.0" - -[[deps.LinearAlgebra]] -deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -version = "1.12.0" - -[[deps.LinearSolve]] -deps = ["ArrayInterface", "ChainRulesCore", "ConcreteStructs", "DocStringExtensions", "EnumX", "GPUArraysCore", "InteractiveUtils", "Krylov", "LazyArrays", "Libdl", "LinearAlgebra", "MKL_jll", "Markdown", "OpenBLAS_jll", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "Setfield", "StaticArraysCore", "UnPack"] -git-tree-sha1 = "13d7e269fcdf9ce431bcd6d501eb8c35c950d9cf" -uuid = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" -version = "3.44.0" - - [deps.LinearSolve.extensions] - LinearSolveAMDGPUExt = "AMDGPU" - LinearSolveBLISExt = ["blis_jll", "LAPACK_jll"] - LinearSolveBandedMatricesExt = "BandedMatrices" - LinearSolveBlockDiagonalsExt = "BlockDiagonals" - LinearSolveCUDAExt = "CUDA" - LinearSolveCUDSSExt = "CUDSS" - LinearSolveCUSOLVERRFExt = ["CUSOLVERRF", "SparseArrays"] - LinearSolveCliqueTreesExt = ["CliqueTrees", "SparseArrays"] - LinearSolveEnzymeExt = "EnzymeCore" - LinearSolveFastAlmostBandedMatricesExt = "FastAlmostBandedMatrices" - LinearSolveFastLapackInterfaceExt = "FastLapackInterface" - LinearSolveForwardDiffExt = "ForwardDiff" - LinearSolveHYPREExt = "HYPRE" - LinearSolveIterativeSolversExt = "IterativeSolvers" - LinearSolveKernelAbstractionsExt = "KernelAbstractions" - LinearSolveKrylovKitExt = "KrylovKit" - LinearSolveMetalExt = "Metal" - LinearSolveMooncakeExt = "Mooncake" - LinearSolvePardisoExt = ["Pardiso", "SparseArrays"] - LinearSolveRecursiveFactorizationExt = "RecursiveFactorization" - LinearSolveSparseArraysExt = "SparseArrays" - LinearSolveSparspakExt = ["SparseArrays", "Sparspak"] - - [deps.LinearSolve.weakdeps] - AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - BlockDiagonals = "0a1fb500-61f7-11e9-3c65-f5ef3456f9f0" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - CUDSS = "45b445bb-4962-46a0-9369-b4df9d0f772e" - CUSOLVERRF = "a8cc9031-bad2-4722-94f5-40deabb4245c" - CliqueTrees = "60701a23-6482-424a-84db-faee86b9b1f8" - EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" - FastAlmostBandedMatrices = "9d29842c-ecb8-4973-b1e9-a27b1157504e" - FastLapackInterface = "29a986be-02c6-4525-aec4-84b980013641" - ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" - HYPRE = "b5ffcf37-a2bd-41ab-a3da-4bd9bc8ad771" - IterativeSolvers = "42fd0dbc-a981-5370-80f2-aaf504508153" - KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" - KrylovKit = "0b1a1467-8014-51b9-945f-bf0ae24f4b77" - LAPACK_jll = "51474c39-65e3-53ba-86ba-03b1b862ec14" - Metal = "dde4c033-4e86-420c-a63e-0dd931031962" - Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" - Pardiso = "46dd5b70-b6fb-5a00-ae2d-e8fea33afaf2" - RecursiveFactorization = "f2c3362d-daeb-58d1-803e-2bc74f2840b4" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - Sparspak = "e56a9233-b9d6-4f03-8d0f-1825330902ac" - blis_jll = "6136c539-28a5-5bf0-87cc-b183200dce32" - -[[deps.LogExpFunctions]] -deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f" -uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.29" - - [deps.LogExpFunctions.extensions] - LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" - LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" - LogExpFunctionsInverseFunctionsExt = "InverseFunctions" - - [deps.LogExpFunctions.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" - InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" - -[[deps.Logging]] -uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" -version = "1.11.0" - -[[deps.LoggingExtras]] -deps = ["Dates", "Logging"] -git-tree-sha1 = "f00544d95982ea270145636c181ceda21c4e2575" -uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" -version = "1.2.0" - -[[deps.METIS_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "2eefa8baa858871ae7770c98c3c2a7e46daba5b4" -uuid = "d00139f3-1899-568f-a2f0-47f597d42d70" -version = "5.1.3+0" - -[[deps.MKL_jll]] -deps = ["Artifacts", "IntelOpenMP_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "oneTBB_jll"] -git-tree-sha1 = "282cadc186e7b2ae0eeadbd7a4dffed4196ae2aa" -uuid = "856f044c-d86e-5d09-b602-aeab76dc8ba7" -version = "2025.2.0+0" - -[[deps.MUMPS_seq_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "METIS_jll", "libblastrampoline_jll"] -git-tree-sha1 = "fc0c8442887b48c15aec2b1787a5fc812a99b2fd" -uuid = "d7ed1dd3-d0ae-5e8e-bfb4-87a502085b8d" -version = "500.800.100+0" - -[[deps.MacroTools]] -git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.16" - -[[deps.ManualMemory]] -git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" -uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667" -version = "0.1.8" - -[[deps.Markdown]] -deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" -version = "1.11.0" - -[[deps.MathOptInterface]] -deps = ["BenchmarkTools", "CodecBzip2", "CodecZlib", "DataStructures", "ForwardDiff", "JSON3", "LinearAlgebra", "MutableArithmetics", "NaNMath", "OrderedCollections", "PrecompileTools", "Printf", "SparseArrays", "SpecialFunctions", "Test"] -git-tree-sha1 = "a2cbab4256690aee457d136752c404e001f27768" -uuid = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" -version = "1.46.0" - -[[deps.MatrixFactorizations]] -deps = ["ArrayLayouts", "LinearAlgebra", "Printf", "Random"] -git-tree-sha1 = "3bb3cf4685f1c90f22883f4c4bb6d203fa882b79" -uuid = "a3b82374-2e81-5b9e-98ce-41277c0e4c87" -version = "3.1.3" -weakdeps = ["BandedMatrices"] - - [deps.MatrixFactorizations.extensions] - MatrixFactorizationsBandedMatricesExt = "BandedMatrices" - -[[deps.MaybeInplace]] -deps = ["ArrayInterface", "LinearAlgebra", "MacroTools"] -git-tree-sha1 = "54e2fdc38130c05b42be423e90da3bade29b74bd" -uuid = "bb5d69b7-63fc-4a16-80bd-7e42200c7bdb" -version = "0.1.4" -weakdeps = ["SparseArrays"] - - [deps.MaybeInplace.extensions] - MaybeInplaceSparseArraysExt = "SparseArrays" - -[[deps.MbedTLS]] -deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] -git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" -uuid = "739be429-bea8-5141-9913-cc70e7f3736d" -version = "1.1.9" - -[[deps.MbedTLS_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "3cce3511ca2c6f87b19c34ffc623417ed2798cbd" -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.10+0" - -[[deps.Measures]] -git-tree-sha1 = "b513cedd20d9c914783d8ad83d08120702bf2c77" -uuid = "442fdcdd-2543-5da2-b0f3-8c86c306513e" -version = "0.3.3" - -[[deps.Missings]] -deps = ["DataAPI"] -git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d" -uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" -version = "1.2.0" - -[[deps.Mmap]] -uuid = "a63ad114-7e13-5084-954f-fe012c677804" -version = "1.11.0" - -[[deps.Moshi]] -deps = ["ExproniconLite", "Jieko"] -git-tree-sha1 = "53f817d3e84537d84545e0ad749e483412dd6b2a" -uuid = "2e0e35c7-a2e4-4343-998d-7ef72827ed2d" -version = "0.3.7" - -[[deps.MozillaCACerts_jll]] -uuid = "14a3606d-f60d-562e-9121-12d972cd8159" -version = "2025.5.20" - -[[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" -uuid = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" -version = "1.6.7" - -[[deps.NLSolversBase]] -deps = ["ADTypes", "DifferentiationInterface", "Distributed", "FiniteDiff", "ForwardDiff"] -git-tree-sha1 = "25a6638571a902ecfb1ae2a18fc1575f86b1d4df" -uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" -version = "7.10.0" - -[[deps.NLsolve]] -deps = ["Distances", "LineSearches", "LinearAlgebra", "NLSolversBase", "Printf", "Reexport"] -git-tree-sha1 = "019f12e9a1a7880459d0173c182e6a99365d7ac1" -uuid = "2774e3e8-f4cf-5e23-947b-6d7e65073b56" -version = "4.5.1" - -[[deps.NaNMath]] -deps = ["OpenLibm_jll"] -git-tree-sha1 = "9b8215b1ee9e78a293f99797cd31375471b2bcae" -uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" -version = "1.1.3" - -[[deps.NetworkOptions]] -uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" -version = "1.3.0" - -[[deps.NonlinearSolve]] -deps = ["ADTypes", "ArrayInterface", "BracketingNonlinearSolve", "CommonSolve", "ConcreteStructs", "DifferentiationInterface", "FastClosures", "FiniteDiff", "ForwardDiff", "LineSearch", "LinearAlgebra", "LinearSolve", "NonlinearSolveBase", "NonlinearSolveFirstOrder", "NonlinearSolveQuasiNewton", "NonlinearSolveSpectralMethods", "PrecompileTools", "Preferences", "Reexport", "SciMLBase", "SimpleNonlinearSolve", "StaticArraysCore", "SymbolicIndexingInterface"] -git-tree-sha1 = "1d091cfece012662b06d25c792b3a43a0804c47b" -uuid = "8913a72c-1f9b-4ce2-8d82-65094dcecaec" -version = "4.12.0" - - [deps.NonlinearSolve.extensions] - NonlinearSolveFastLevenbergMarquardtExt = "FastLevenbergMarquardt" - NonlinearSolveFixedPointAccelerationExt = "FixedPointAcceleration" - NonlinearSolveLeastSquaresOptimExt = "LeastSquaresOptim" - NonlinearSolveMINPACKExt = "MINPACK" - NonlinearSolveNLSolversExt = "NLSolvers" - NonlinearSolveNLsolveExt = ["NLsolve", "LineSearches"] - NonlinearSolvePETScExt = ["PETSc", "MPI", "SparseArrays"] - NonlinearSolveSIAMFANLEquationsExt = "SIAMFANLEquations" - NonlinearSolveSpeedMappingExt = "SpeedMapping" - NonlinearSolveSundialsExt = "Sundials" - - [deps.NonlinearSolve.weakdeps] - FastLevenbergMarquardt = "7a0df574-e128-4d35-8cbd-3d84502bf7ce" - FixedPointAcceleration = "817d07cb-a79a-5c30-9a31-890123675176" - LeastSquaresOptim = "0fc2ff8b-aaa3-5acd-a817-1944a5e08891" - LineSearches = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" - MINPACK = "4854310b-de5a-5eb6-a2a5-c1dee2bd17f9" - MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" - NLSolvers = "337daf1e-9722-11e9-073e-8b9effe078ba" - NLsolve = "2774e3e8-f4cf-5e23-947b-6d7e65073b56" - PETSc = "ace2c81b-2b5f-4b1e-a30d-d662738edfe0" - SIAMFANLEquations = "084e46ad-d928-497d-ad5e-07fa361a48c4" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - SpeedMapping = "f1835b91-879b-4a3f-a438-e4baacf14412" - Sundials = "c3572dad-4567-51f8-b174-8c6c989267f4" - -[[deps.NonlinearSolveBase]] -deps = ["ADTypes", "Adapt", "ArrayInterface", "CommonSolve", "Compat", "ConcreteStructs", "DifferentiationInterface", "EnzymeCore", "FastClosures", "LinearAlgebra", "Markdown", "MaybeInplace", "Preferences", "Printf", "RecursiveArrayTools", "SciMLBase", "SciMLJacobianOperators", "SciMLOperators", "SciMLStructures", "Setfield", "StaticArraysCore", "SymbolicIndexingInterface", "TimerOutputs"] -git-tree-sha1 = "9dba8e7ccfaf4c10b3a3b4cc52abf639f8558efd" -uuid = "be0214bd-f91f-a760-ac4e-3421ce2b2da0" -version = "2.0.0" - - [deps.NonlinearSolveBase.extensions] - NonlinearSolveBaseBandedMatricesExt = "BandedMatrices" - NonlinearSolveBaseChainRulesCoreExt = "ChainRulesCore" - NonlinearSolveBaseEnzymeExt = ["ChainRulesCore", "Enzyme"] - NonlinearSolveBaseForwardDiffExt = "ForwardDiff" - NonlinearSolveBaseLineSearchExt = "LineSearch" - NonlinearSolveBaseLinearSolveExt = "LinearSolve" - NonlinearSolveBaseMooncakeExt = "Mooncake" - NonlinearSolveBaseReverseDiffExt = "ReverseDiff" - NonlinearSolveBaseSparseArraysExt = "SparseArrays" - NonlinearSolveBaseSparseMatrixColoringsExt = "SparseMatrixColorings" - NonlinearSolveBaseTrackerExt = "Tracker" - - [deps.NonlinearSolveBase.weakdeps] - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" - LineSearch = "87fe0de2-c867-4266-b59a-2f0a94fc965b" - LinearSolve = "7ed4a6bd-45f5-4d41-b270-4a48e9bafcae" - Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - SparseMatrixColorings = "0a514795-09f3-496d-8182-132a7b665d35" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" - -[[deps.NonlinearSolveFirstOrder]] -deps = ["ADTypes", "ArrayInterface", "CommonSolve", "ConcreteStructs", "FiniteDiff", "ForwardDiff", "LineSearch", "LinearAlgebra", "LinearSolve", "MaybeInplace", "NonlinearSolveBase", "PrecompileTools", "Reexport", "SciMLBase", "SciMLJacobianOperators", "Setfield", "StaticArraysCore"] -git-tree-sha1 = "01c48c37ba47721ec6489a1668ab3bb1f5b603c0" -uuid = "5959db7a-ea39-4486-b5fe-2dd0bf03d60d" -version = "1.9.0" - -[[deps.NonlinearSolveQuasiNewton]] -deps = ["ArrayInterface", "CommonSolve", "ConcreteStructs", "LinearAlgebra", "LinearSolve", "MaybeInplace", "NonlinearSolveBase", "PrecompileTools", "Reexport", "SciMLBase", "SciMLOperators", "StaticArraysCore"] -git-tree-sha1 = "a233b7bbb32426170b238e2e2b82b0f9f1c5caba" -uuid = "9a2c21bd-3a47-402d-9113-8faf9a0ee114" -version = "1.10.0" -weakdeps = ["ForwardDiff"] - - [deps.NonlinearSolveQuasiNewton.extensions] - NonlinearSolveQuasiNewtonForwardDiffExt = "ForwardDiff" - -[[deps.NonlinearSolveSpectralMethods]] -deps = ["CommonSolve", "ConcreteStructs", "LineSearch", "MaybeInplace", "NonlinearSolveBase", "PrecompileTools", "Reexport", "SciMLBase"] -git-tree-sha1 = "139bf9211930a829703481b3ffd86b1ab309cd07" -uuid = "26075421-4e9a-44e1-8bd1-420ed7ad02b2" -version = "1.5.0" -weakdeps = ["ForwardDiff"] - - [deps.NonlinearSolveSpectralMethods.extensions] - NonlinearSolveSpectralMethodsForwardDiffExt = "ForwardDiff" - -[[deps.OSQP]] -deps = ["Libdl", "LinearAlgebra", "MathOptInterface", "OSQP_jll", "SparseArrays"] -git-tree-sha1 = "50faf456a64ac1ca097b78bcdf288d94708adcdd" -uuid = "ab2f91bb-94b4-55e3-9ba0-7f65df51de79" -version = "0.8.1" - -[[deps.OSQP_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "d0f73698c33e04e557980a06d75c2d82e3f0eb49" -uuid = "9c4f68bf-6205-5545-a508-2878b064d984" -version = "0.600.200+0" - -[[deps.Ogg_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "b6aa4566bb7ae78498a5e68943863fa8b5231b59" -uuid = "e7412a2a-1a6e-54c0-be00-318e2571c051" -version = "1.3.6+0" - -[[deps.OpenBLAS32_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] -git-tree-sha1 = "ece4587683695fe4c5f20e990da0ed7e83c351e7" -uuid = "656ef2d0-ae68-5445-9ca0-591084a874a2" -version = "0.3.29+0" - -[[deps.OpenBLAS_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] -uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.29+0" - -[[deps.OpenLibm_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.7+0" - -[[deps.OpenSSL]] -deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "NetworkOptions", "OpenSSL_jll", "Sockets"] -git-tree-sha1 = "386b47442468acfb1add94bf2d85365dea10cbab" -uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c" -version = "1.6.0" - -[[deps.OpenSSL_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.5.1+0" - -[[deps.OpenSpecFun_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1346c9208249809840c91b26703912dff463d335" -uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" -version = "0.5.6+0" - -[[deps.Optim]] -deps = ["Compat", "EnumX", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] -git-tree-sha1 = "61942645c38dd2b5b78e2082c9b51ab315315d10" -uuid = "429524aa-4258-5aef-a3af-852621145aeb" -version = "1.13.2" -weakdeps = ["MathOptInterface"] - - [deps.Optim.extensions] - OptimMOIExt = "MathOptInterface" - -[[deps.Opus_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "c392fc5dd032381919e3b22dd32d6443760ce7ea" -uuid = "91d4177d-7536-5919-b921-800302f37372" -version = "1.5.2+0" - -[[deps.OrderedCollections]] -git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee" -uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.8.1" - -[[deps.OrdinaryDiffEq]] -deps = ["ADTypes", "Adapt", "ArrayInterface", "CommonSolve", "DataStructures", "DiffEqBase", "DocStringExtensions", "EnumX", "ExponentialUtilities", "FastBroadcast", "FastClosures", "FillArrays", "FiniteDiff", "ForwardDiff", "FunctionWrappersWrappers", "InteractiveUtils", "LineSearches", "LinearAlgebra", "LinearSolve", "Logging", "MacroTools", "MuladdMacro", "NonlinearSolve", "OrdinaryDiffEqAdamsBashforthMoulton", "OrdinaryDiffEqBDF", "OrdinaryDiffEqCore", "OrdinaryDiffEqDefault", "OrdinaryDiffEqDifferentiation", "OrdinaryDiffEqExplicitRK", "OrdinaryDiffEqExponentialRK", "OrdinaryDiffEqExtrapolation", "OrdinaryDiffEqFIRK", "OrdinaryDiffEqFeagin", "OrdinaryDiffEqFunctionMap", "OrdinaryDiffEqHighOrderRK", "OrdinaryDiffEqIMEXMultistep", "OrdinaryDiffEqLinear", "OrdinaryDiffEqLowOrderRK", "OrdinaryDiffEqLowStorageRK", "OrdinaryDiffEqNonlinearSolve", "OrdinaryDiffEqNordsieck", "OrdinaryDiffEqPDIRK", "OrdinaryDiffEqPRK", "OrdinaryDiffEqQPRK", "OrdinaryDiffEqRKN", "OrdinaryDiffEqRosenbrock", "OrdinaryDiffEqSDIRK", "OrdinaryDiffEqSSPRK", "OrdinaryDiffEqStabilizedIRK", "OrdinaryDiffEqStabilizedRK", "OrdinaryDiffEqSymplecticRK", "OrdinaryDiffEqTsit5", "OrdinaryDiffEqVerner", "Polyester", "PreallocationTools", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "SciMLStructures", "SimpleNonlinearSolve", "SimpleUnPack", "SparseArrays", "Static", "StaticArrayInterface", "StaticArrays", "TruncatedStacktraces"] -git-tree-sha1 = "89cd4e81d7a668f8858fba6779212f41a0360260" -uuid = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" -version = "6.102.1" - -[[deps.OrdinaryDiffEqAdamsBashforthMoulton]] -deps = ["DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqLowOrderRK", "Polyester", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static"] -git-tree-sha1 = "09aae1486c767caa6bce9de892455cbdf5a6fbc8" -uuid = "89bda076-bce5-4f1c-845f-551c83cdda9a" -version = "1.5.0" - -[[deps.OrdinaryDiffEqBDF]] -deps = ["ADTypes", "ArrayInterface", "DiffEqBase", "FastBroadcast", "LinearAlgebra", "MacroTools", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "OrdinaryDiffEqNonlinearSolve", "OrdinaryDiffEqSDIRK", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "StaticArrays", "TruncatedStacktraces"] -git-tree-sha1 = "ce8db53fd1e4e41c020fd53961e7314f75e4c21c" -uuid = "6ad6398a-0878-4a85-9266-38940aa047c8" -version = "1.10.1" - -[[deps.OrdinaryDiffEqCore]] -deps = ["ADTypes", "Accessors", "Adapt", "ArrayInterface", "DataStructures", "DiffEqBase", "DocStringExtensions", "EnumX", "FastBroadcast", "FastClosures", "FastPower", "FillArrays", "FunctionWrappersWrappers", "InteractiveUtils", "LinearAlgebra", "Logging", "MacroTools", "MuladdMacro", "Polyester", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "SciMLStructures", "SimpleUnPack", "Static", "StaticArrayInterface", "StaticArraysCore", "SymbolicIndexingInterface", "TruncatedStacktraces"] -git-tree-sha1 = "4b68f9ca0cfa68cb9ee544df96391d47ca0e62a9" -uuid = "bbf590c4-e513-4bbe-9b18-05decba2e5d8" -version = "1.36.0" - - [deps.OrdinaryDiffEqCore.extensions] - OrdinaryDiffEqCoreEnzymeCoreExt = "EnzymeCore" - OrdinaryDiffEqCoreMooncakeExt = "Mooncake" - - [deps.OrdinaryDiffEqCore.weakdeps] - EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" - Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" - -[[deps.OrdinaryDiffEqDefault]] -deps = ["ADTypes", "DiffEqBase", "EnumX", "LinearAlgebra", "LinearSolve", "OrdinaryDiffEqBDF", "OrdinaryDiffEqCore", "OrdinaryDiffEqRosenbrock", "OrdinaryDiffEqTsit5", "OrdinaryDiffEqVerner", "PrecompileTools", "Preferences", "Reexport", "SciMLBase"] -git-tree-sha1 = "7d5ddeee97e1bdcc848f1397cbc3d03bd57f33e7" -uuid = "50262376-6c5a-4cf5-baba-aaf4f84d72d7" -version = "1.8.0" - -[[deps.OrdinaryDiffEqDifferentiation]] -deps = ["ADTypes", "ArrayInterface", "ConcreteStructs", "ConstructionBase", "DiffEqBase", "DifferentiationInterface", "FastBroadcast", "FiniteDiff", "ForwardDiff", "FunctionWrappersWrappers", "LinearAlgebra", "LinearSolve", "OrdinaryDiffEqCore", "SciMLBase", "SciMLOperators", "SparseMatrixColorings", "StaticArrayInterface", "StaticArrays"] -git-tree-sha1 = "320b5f3e4e61ca0ad863c63c803f69973ba6efce" -uuid = "4302a76b-040a-498a-8c04-15b101fed76b" -version = "1.16.1" -weakdeps = ["SparseArrays"] - - [deps.OrdinaryDiffEqDifferentiation.extensions] - OrdinaryDiffEqDifferentiationSparseArraysExt = "SparseArrays" - -[[deps.OrdinaryDiffEqExplicitRK]] -deps = ["DiffEqBase", "FastBroadcast", "LinearAlgebra", "MuladdMacro", "OrdinaryDiffEqCore", "RecursiveArrayTools", "Reexport", "SciMLBase", "TruncatedStacktraces"] -git-tree-sha1 = "4c0633f587395d7aaec0679dc649eb03fcc74e73" -uuid = "9286f039-9fbf-40e8-bf65-aa933bdc4db0" -version = "1.4.0" - -[[deps.OrdinaryDiffEqExponentialRK]] -deps = ["ADTypes", "DiffEqBase", "ExponentialUtilities", "FastBroadcast", "LinearAlgebra", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "RecursiveArrayTools", "Reexport", "SciMLBase"] -git-tree-sha1 = "3b81416ff11e55ea0ae7b449efc818256d9d450b" -uuid = "e0540318-69ee-4070-8777-9e2de6de23de" -version = "1.8.0" - -[[deps.OrdinaryDiffEqExtrapolation]] -deps = ["ADTypes", "DiffEqBase", "FastBroadcast", "FastPower", "LinearSolve", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "Polyester", "RecursiveArrayTools", "Reexport", "SciMLBase"] -git-tree-sha1 = "9e1b11cf448a2c1bca640103c1c848a20aa2f967" -uuid = "becaefa8-8ca2-5cf9-886d-c06f3d2bd2c4" -version = "1.9.0" - -[[deps.OrdinaryDiffEqFIRK]] -deps = ["ADTypes", "DiffEqBase", "FastBroadcast", "FastGaussQuadrature", "FastPower", "LinearAlgebra", "LinearSolve", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "OrdinaryDiffEqNonlinearSolve", "Polyester", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators"] -git-tree-sha1 = "b968d66de3de5ffcf18544bc202ca792bad20710" -uuid = "5960d6e9-dd7a-4743-88e7-cf307b64f125" -version = "1.16.0" - -[[deps.OrdinaryDiffEqFeagin]] -deps = ["DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "Polyester", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static"] -git-tree-sha1 = "815b54211201ec42b8829e0275ab3c9632d16cbe" -uuid = "101fe9f7-ebb6-4678-b671-3a81e7194747" -version = "1.4.0" - -[[deps.OrdinaryDiffEqFunctionMap]] -deps = ["DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static"] -git-tree-sha1 = "fe750e4b8c1b1b9e1c1319ff2e052e83ad57b3ac" -uuid = "d3585ca7-f5d3-4ba6-8057-292ed1abd90f" -version = "1.5.0" - -[[deps.OrdinaryDiffEqHighOrderRK]] -deps = ["DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static"] -git-tree-sha1 = "42096f72136078fa02804515f1748ddeb1f0d47d" -uuid = "d28bc4f8-55e1-4f49-af69-84c1a99f0f58" -version = "1.5.0" - -[[deps.OrdinaryDiffEqIMEXMultistep]] -deps = ["ADTypes", "DiffEqBase", "FastBroadcast", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "OrdinaryDiffEqNonlinearSolve", "Reexport", "SciMLBase"] -git-tree-sha1 = "a5dcd75959dada0005b1707a5ca9359faa1734ba" -uuid = "9f002381-b378-40b7-97a6-27a27c83f129" -version = "1.7.0" - -[[deps.OrdinaryDiffEqLinear]] -deps = ["DiffEqBase", "ExponentialUtilities", "LinearAlgebra", "OrdinaryDiffEqCore", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators"] -git-tree-sha1 = "925fc0136e8128fd19abf126e9358ec1f997390f" -uuid = "521117fe-8c41-49f8-b3b6-30780b3f0fb5" -version = "1.6.0" - -[[deps.OrdinaryDiffEqLowOrderRK]] -deps = ["DiffEqBase", "FastBroadcast", "LinearAlgebra", "MuladdMacro", "OrdinaryDiffEqCore", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static"] -git-tree-sha1 = "3cc4987c8e4725276b55a52e08b56ded4862917e" -uuid = "1344f307-1e59-4825-a18e-ace9aa3fa4c6" -version = "1.6.0" - -[[deps.OrdinaryDiffEqLowStorageRK]] -deps = ["Adapt", "DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "Polyester", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static", "StaticArrays"] -git-tree-sha1 = "e6bd0a7fb6643a57b06a90415608a81aaf7bd772" -uuid = "b0944070-b475-4768-8dec-fb6eb410534d" -version = "1.7.0" - -[[deps.OrdinaryDiffEqNonlinearSolve]] -deps = ["ADTypes", "ArrayInterface", "DiffEqBase", "FastBroadcast", "FastClosures", "ForwardDiff", "LinearAlgebra", "LinearSolve", "MuladdMacro", "NonlinearSolve", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "PreallocationTools", "RecursiveArrayTools", "SciMLBase", "SciMLOperators", "SciMLStructures", "SimpleNonlinearSolve", "StaticArrays"] -git-tree-sha1 = "f59c1c07cfa674c1d3f5dd386c4274d9bc2be221" -uuid = "127b3ac7-2247-4354-8eb6-78cf4e7c58e8" -version = "1.15.0" - -[[deps.OrdinaryDiffEqNordsieck]] -deps = ["DiffEqBase", "FastBroadcast", "LinearAlgebra", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqTsit5", "Polyester", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static"] -git-tree-sha1 = "c90aa7fa0d725472c4098096adf6a08266c2f682" -uuid = "c9986a66-5c92-4813-8696-a7ec84c806c8" -version = "1.4.0" - -[[deps.OrdinaryDiffEqPDIRK]] -deps = ["ADTypes", "DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "OrdinaryDiffEqNonlinearSolve", "Polyester", "Reexport", "SciMLBase", "StaticArrays"] -git-tree-sha1 = "9d599d2eafdf74ab26ea6bf3feb28183a2ade143" -uuid = "5dd0a6cf-3d4b-4314-aa06-06d4e299bc89" -version = "1.6.0" - -[[deps.OrdinaryDiffEqPRK]] -deps = ["DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "Polyester", "Reexport", "SciMLBase"] -git-tree-sha1 = "8e35132689133255be6d63df4190b5fc97b6cf2b" -uuid = "5b33eab2-c0f1-4480-b2c3-94bc1e80bda1" -version = "1.4.0" - -[[deps.OrdinaryDiffEqQPRK]] -deps = ["DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static"] -git-tree-sha1 = "63fb643a956b27cd0e33a3c6d910c3c118082e0f" -uuid = "04162be5-8125-4266-98ed-640baecc6514" -version = "1.4.0" - -[[deps.OrdinaryDiffEqRKN]] -deps = ["DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "Polyester", "RecursiveArrayTools", "Reexport", "SciMLBase"] -git-tree-sha1 = "a31c41f9dbea7c7179c6e544c25c7e144d63868c" -uuid = "af6ede74-add8-4cfd-b1df-9a4dbb109d7a" -version = "1.5.0" - -[[deps.OrdinaryDiffEqRosenbrock]] -deps = ["ADTypes", "DiffEqBase", "DifferentiationInterface", "FastBroadcast", "FiniteDiff", "ForwardDiff", "LinearAlgebra", "LinearSolve", "MacroTools", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "Polyester", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static"] -git-tree-sha1 = "f34bc2f58656843596d09a4c4de8c20724ebc2f1" -uuid = "43230ef6-c299-4910-a778-202eb28ce4ce" -version = "1.18.1" - -[[deps.OrdinaryDiffEqSDIRK]] -deps = ["ADTypes", "DiffEqBase", "FastBroadcast", "LinearAlgebra", "MacroTools", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "OrdinaryDiffEqNonlinearSolve", "RecursiveArrayTools", "Reexport", "SciMLBase", "TruncatedStacktraces"] -git-tree-sha1 = "20caa72c004414435fb5769fadb711e96ed5bcd4" -uuid = "2d112036-d095-4a1e-ab9a-08536f3ecdbf" -version = "1.7.0" - -[[deps.OrdinaryDiffEqSSPRK]] -deps = ["DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "Polyester", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static", "StaticArrays"] -git-tree-sha1 = "3bce87977264916bd92455754ab336faec68bf8a" -uuid = "669c94d9-1f4b-4b64-b377-1aa079aa2388" -version = "1.7.0" - -[[deps.OrdinaryDiffEqStabilizedIRK]] -deps = ["ADTypes", "DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "OrdinaryDiffEqNonlinearSolve", "OrdinaryDiffEqStabilizedRK", "RecursiveArrayTools", "Reexport", "SciMLBase", "StaticArrays"] -git-tree-sha1 = "75abe7462f4b0b2a2463bb512c8a5458bbd39185" -uuid = "e3e12d00-db14-5390-b879-ac3dd2ef6296" -version = "1.6.0" - -[[deps.OrdinaryDiffEqStabilizedRK]] -deps = ["DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "RecursiveArrayTools", "Reexport", "SciMLBase", "StaticArrays"] -git-tree-sha1 = "7e94d3d1b3528b4bcf9e0248198ee0a2fd65a697" -uuid = "358294b1-0aab-51c3-aafe-ad5ab194a2ad" -version = "1.4.0" - -[[deps.OrdinaryDiffEqSymplecticRK]] -deps = ["DiffEqBase", "FastBroadcast", "MuladdMacro", "OrdinaryDiffEqCore", "Polyester", "RecursiveArrayTools", "Reexport", "SciMLBase"] -git-tree-sha1 = "e8dd5ab225287947016dc144a5ded1fb83885638" -uuid = "fa646aed-7ef9-47eb-84c4-9443fc8cbfa8" -version = "1.7.0" - -[[deps.OrdinaryDiffEqTsit5]] -deps = ["DiffEqBase", "FastBroadcast", "LinearAlgebra", "MuladdMacro", "OrdinaryDiffEqCore", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static", "TruncatedStacktraces"] -git-tree-sha1 = "778c7d379265f17f40dbe9aaa6f6a2a08bc7fa3e" -uuid = "b1df2697-797e-41e3-8120-5422d3b24e4a" -version = "1.5.0" - -[[deps.OrdinaryDiffEqVerner]] -deps = ["DiffEqBase", "FastBroadcast", "LinearAlgebra", "MuladdMacro", "OrdinaryDiffEqCore", "Polyester", "PrecompileTools", "Preferences", "RecursiveArrayTools", "Reexport", "SciMLBase", "Static", "TruncatedStacktraces"] -git-tree-sha1 = "185578fa7c38119d4318326f9375f1cba0f0ce53" -uuid = "79d7bb75-1356-48c1-b8c0-6832512096c2" -version = "1.6.0" - -[[deps.PCRE2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "efcefdf7-47ab-520b-bdef-62a2eaa19f15" -version = "10.44.0+1" - -[[deps.PDMats]] -deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "f07c06228a1c670ae4c87d1276b92c7c597fdda0" -uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" -version = "0.11.35" - -[[deps.Pango_jll]] -deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] -git-tree-sha1 = "0662b083e11420952f2e62e17eddae7fc07d5997" -uuid = "36c8627f-9965-5494-a995-c6b170f724f3" -version = "1.57.0+0" - -[[deps.Parameters]] -deps = ["OrderedCollections", "UnPack"] -git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" -uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" -version = "0.12.3" - -[[deps.Parsers]] -deps = ["Dates", "PrecompileTools", "UUIDs"] -git-tree-sha1 = "7d2f8f21da5db6a806faf7b9b292296da42b2810" -uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "2.8.3" - -[[deps.Pixman_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "LLVMOpenMP_jll", "Libdl"] -git-tree-sha1 = "db76b1ecd5e9715f3d043cec13b2ec93ce015d53" -uuid = "30392449-352a-5448-841d-b1acce4e97dc" -version = "0.44.2+0" - -[[deps.Pkg]] -deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "Random", "SHA", "TOML", "Tar", "UUIDs", "p7zip_jll"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.12.0" -weakdeps = ["REPL"] - - [deps.Pkg.extensions] - REPLExt = "REPL" - -[[deps.PlotThemes]] -deps = ["PlotUtils", "Statistics"] -git-tree-sha1 = "41031ef3a1be6f5bbbf3e8073f210556daeae5ca" -uuid = "ccf2f8ad-2431-5c83-bf29-c5338b663b6a" -version = "3.3.0" - -[[deps.PlotUtils]] -deps = ["ColorSchemes", "Colors", "Dates", "PrecompileTools", "Printf", "Random", "Reexport", "StableRNGs", "Statistics"] -git-tree-sha1 = "26ca162858917496748aad52bb5d3be4d26a228a" -uuid = "995b91a9-d308-5afd-9ec6-746e21dbc043" -version = "1.4.4" - -[[deps.Plots]] -deps = ["Base64", "Contour", "Dates", "Downloads", "FFMPEG", "FixedPointNumbers", "GR", "JLFzf", "JSON", "LaTeXStrings", "Latexify", "LinearAlgebra", "Measures", "NaNMath", "Pkg", "PlotThemes", "PlotUtils", "PrecompileTools", "Printf", "REPL", "Random", "RecipesBase", "RecipesPipeline", "Reexport", "RelocatableFolders", "Requires", "Scratch", "Showoff", "SparseArrays", "Statistics", "StatsBase", "TOML", "UUIDs", "UnicodeFun", "Unzip"] -git-tree-sha1 = "12ce661880f8e309569074a61d3767e5756a199f" -uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" -version = "1.41.1" - - [deps.Plots.extensions] - FileIOExt = "FileIO" - GeometryBasicsExt = "GeometryBasics" - IJuliaExt = "IJulia" - ImageInTerminalExt = "ImageInTerminal" - UnitfulExt = "Unitful" - - [deps.Plots.weakdeps] - FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" - GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326" - IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" - ImageInTerminal = "d8c32880-2388-543b-8c61-d9f865259254" - Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" - -[[deps.PoissonRandom]] -deps = ["LogExpFunctions", "Random"] -git-tree-sha1 = "67afbcbe9e184d6729a92a022147ed4cf972ca7b" -uuid = "e409e4f3-bfea-5376-8464-e040bb5c01ab" -version = "0.4.7" - -[[deps.Polyester]] -deps = ["ArrayInterface", "BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "ManualMemory", "PolyesterWeave", "Static", "StaticArrayInterface", "StrideArraysCore", "ThreadingUtilities"] -git-tree-sha1 = "6f7cd22a802094d239824c57d94c8e2d0f7cfc7d" -uuid = "f517fe37-dbe3-4b94-8317-1923a5111588" -version = "0.7.18" - -[[deps.PolyesterWeave]] -deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] -git-tree-sha1 = "645bed98cd47f72f67316fd42fc47dee771aefcd" -uuid = "1d0040c9-8b98-4ee7-8388-3f51789ca0ad" -version = "0.2.2" - -[[deps.PositiveFactorizations]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" -uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" -version = "0.2.4" - -[[deps.PreallocationTools]] -deps = ["Adapt", "ArrayInterface", "PrecompileTools"] -git-tree-sha1 = "c05b4c6325262152483a1ecb6c69846d2e01727b" -uuid = "d236fae5-4411-538c-8e31-a6e3d9e00b46" -version = "0.4.34" - - [deps.PreallocationTools.extensions] - PreallocationToolsForwardDiffExt = "ForwardDiff" - PreallocationToolsReverseDiffExt = "ReverseDiff" - PreallocationToolsSparseConnectivityTracerExt = "SparseConnectivityTracer" - - [deps.PreallocationTools.weakdeps] - ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - SparseConnectivityTracer = "9f842d2f-2579-4b1d-911e-f412cf18a3f5" - -[[deps.PrecompileTools]] -deps = ["Preferences"] -git-tree-sha1 = "07a921781cab75691315adc645096ed5e370cb77" -uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" -version = "1.3.3" - -[[deps.Preferences]] -deps = ["TOML"] -git-tree-sha1 = "0f27480397253da18fe2c12a4ba4eb9eb208bf3d" -uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.5.0" - -[[deps.Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" -version = "1.11.0" - -[[deps.Profile]] -deps = ["StyledStrings"] -uuid = "9abbd945-dff8-562f-b5e8-e1ebf5ef1b79" -version = "1.11.0" - -[[deps.PtrArrays]] -git-tree-sha1 = "1d36ef11a9aaf1e8b74dacc6a731dd1de8fd493d" -uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" -version = "1.3.0" - -[[deps.Qt6Base_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Vulkan_Loader_jll", "Xorg_libSM_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_cursor_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "libinput_jll", "xkbcommon_jll"] -git-tree-sha1 = "34f7e5d2861083ec7596af8b8c092531facf2192" -uuid = "c0090381-4147-56d7-9ebc-da0b1113ec56" -version = "6.8.2+2" - -[[deps.Qt6Declarative_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6ShaderTools_jll"] -git-tree-sha1 = "da7adf145cce0d44e892626e647f9dcbe9cb3e10" -uuid = "629bc702-f1f5-5709-abd5-49b8460ea067" -version = "6.8.2+1" - -[[deps.Qt6ShaderTools_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll"] -git-tree-sha1 = "9eca9fc3fe515d619ce004c83c31ffd3f85c7ccf" -uuid = "ce943373-25bb-56aa-8eca-768745ed7b5a" -version = "6.8.2+1" - -[[deps.Qt6Wayland_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6Declarative_jll"] -git-tree-sha1 = "8f528b0851b5b7025032818eb5abbeb8a736f853" -uuid = "e99dba38-086e-5de3-a5b1-6e4c66e897c3" -version = "6.8.2+2" - -[[deps.QuadGK]] -deps = ["DataStructures", "LinearAlgebra"] -git-tree-sha1 = "9da16da70037ba9d701192e27befedefb91ec284" -uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.11.2" - - [deps.QuadGK.extensions] - QuadGKEnzymeExt = "Enzyme" - - [deps.QuadGK.weakdeps] - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - -[[deps.REPL]] -deps = ["InteractiveUtils", "JuliaSyntaxHighlighting", "Markdown", "Sockets", "StyledStrings", "Unicode"] -uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" -version = "1.11.0" - -[[deps.Random]] -deps = ["SHA"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" -version = "1.11.0" - -[[deps.Random123]] -deps = ["Random", "RandomNumbers"] -git-tree-sha1 = "dbe5fd0b334694e905cb9fda73cd8554333c46e2" -uuid = "74087812-796a-5b5d-8853-05524746bad3" -version = "1.7.1" - -[[deps.RandomNumbers]] -deps = ["Random"] -git-tree-sha1 = "c6ec94d2aaba1ab2ff983052cf6a606ca5985902" -uuid = "e6cf234a-135c-5ec9-84dd-332b85af5143" -version = "1.6.0" - -[[deps.RecipesBase]] -deps = ["PrecompileTools"] -git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" -uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" -version = "1.3.4" - -[[deps.RecipesPipeline]] -deps = ["Dates", "NaNMath", "PlotUtils", "PrecompileTools", "RecipesBase"] -git-tree-sha1 = "45cf9fd0ca5839d06ef333c8201714e888486342" -uuid = "01d81517-befc-4cb6-b9ec-a95719d0359c" -version = "0.6.12" - -[[deps.RecursiveArrayTools]] -deps = ["Adapt", "ArrayInterface", "DocStringExtensions", "GPUArraysCore", "LinearAlgebra", "RecipesBase", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface"] -git-tree-sha1 = "51bdb23afaaa551f923a0e990f7c44a4451a26f1" -uuid = "731186ca-8d62-57ce-b412-fbd966d074cd" -version = "3.39.0" - - [deps.RecursiveArrayTools.extensions] - RecursiveArrayToolsFastBroadcastExt = "FastBroadcast" - RecursiveArrayToolsForwardDiffExt = "ForwardDiff" - RecursiveArrayToolsKernelAbstractionsExt = "KernelAbstractions" - RecursiveArrayToolsMeasurementsExt = "Measurements" - RecursiveArrayToolsMonteCarloMeasurementsExt = "MonteCarloMeasurements" - RecursiveArrayToolsReverseDiffExt = ["ReverseDiff", "Zygote"] - RecursiveArrayToolsSparseArraysExt = ["SparseArrays"] - RecursiveArrayToolsStructArraysExt = "StructArrays" - RecursiveArrayToolsTablesExt = ["Tables"] - RecursiveArrayToolsTrackerExt = "Tracker" - RecursiveArrayToolsZygoteExt = "Zygote" - - [deps.RecursiveArrayTools.weakdeps] - FastBroadcast = "7034ab61-46d4-4ed7-9d0f-46aef9175898" - ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" - KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" - Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" - MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca" - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" - Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" - Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" - -[[deps.Reexport]] -git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" -uuid = "189a3867-3050-52da-a836-e630ba90ab69" -version = "1.2.2" - -[[deps.RelocatableFolders]] -deps = ["SHA", "Scratch"] -git-tree-sha1 = "ffdaf70d81cf6ff22c2b6e733c900c3321cab864" -uuid = "05181044-ff0b-4ac5-8273-598c1e38db00" -version = "1.0.1" - -[[deps.Requires]] -deps = ["UUIDs"] -git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64" -uuid = "ae029012-a4dd-5104-9daa-d747884805df" -version = "1.3.1" - -[[deps.ResettableStacks]] -deps = ["StaticArrays"] -git-tree-sha1 = "256eeeec186fa7f26f2801732774ccf277f05db9" -uuid = "ae5879a3-cd67-5da8-be7f-38c6eb64a37b" -version = "1.1.1" - -[[deps.Rmath]] -deps = ["Random", "Rmath_jll"] -git-tree-sha1 = "52b99504e2c174d9a8592a89647f5187063d1eb1" -uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" -version = "0.8.2" - -[[deps.Rmath_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8" -uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" -version = "0.5.1+0" - -[[deps.RuntimeGeneratedFunctions]] -deps = ["ExprTools", "SHA", "Serialization"] -git-tree-sha1 = "86a8a8b783481e1ea6b9c91dd949cb32191f8ab4" -uuid = "7e49a35a-f44a-4d26-94aa-eba1b4ca6b47" -version = "0.5.15" - -[[deps.SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" -version = "0.7.0" - -[[deps.SIMDTypes]] -git-tree-sha1 = "330289636fb8107c5f32088d2741e9fd7a061a5c" -uuid = "94e857df-77ce-4151-89e5-788b33177be4" -version = "0.1.0" - -[[deps.SPRAL_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "Libdl", "METIS_jll", "libblastrampoline_jll"] -git-tree-sha1 = "4f9833187a65ead66ed1907b44d5f20606282e3f" -uuid = "319450e9-13b8-58e8-aa9f-8fd1420848ab" -version = "2025.5.20+0" - -[[deps.SciMLBase]] -deps = ["ADTypes", "Accessors", "Adapt", "ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "Moshi", "PreallocationTools", "PrecompileTools", "Preferences", "Printf", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "SciMLStructures", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface"] -git-tree-sha1 = "737abcec59e3b999dda21018a6f3e442c0a58a65" -uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" -version = "2.121.1" - - [deps.SciMLBase.extensions] - SciMLBaseChainRulesCoreExt = "ChainRulesCore" - SciMLBaseDistributionsExt = "Distributions" - SciMLBaseEnzymeExt = "Enzyme" - SciMLBaseForwardDiffExt = "ForwardDiff" - SciMLBaseMLStyleExt = "MLStyle" - SciMLBaseMakieExt = "Makie" - SciMLBaseMeasurementsExt = "Measurements" - SciMLBaseMonteCarloMeasurementsExt = "MonteCarloMeasurements" - SciMLBaseMooncakeExt = "Mooncake" - SciMLBasePartialFunctionsExt = "PartialFunctions" - SciMLBasePyCallExt = "PyCall" - SciMLBasePythonCallExt = "PythonCall" - SciMLBaseRCallExt = "RCall" - SciMLBaseReverseDiffExt = "ReverseDiff" - SciMLBaseTrackerExt = "Tracker" - SciMLBaseZygoteExt = ["Zygote", "ChainRulesCore"] - - [deps.SciMLBase.weakdeps] - ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" - MLStyle = "d8e11817-5142-5d16-987a-aa16d5891078" - Makie = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" - Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" - MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca" - Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" - PartialFunctions = "570af359-4316-4cb7-8c74-252c00c2016b" - PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" - PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d" - RCall = "6f49c342-dc21-5d91-9882-a32aef131414" - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" - Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" - -[[deps.SciMLJacobianOperators]] -deps = ["ADTypes", "ArrayInterface", "ConcreteStructs", "ConstructionBase", "DifferentiationInterface", "FastClosures", "LinearAlgebra", "SciMLBase", "SciMLOperators"] -git-tree-sha1 = "a273b291c90909ba6fe08402dd68e09aae423008" -uuid = "19f34311-ddf3-4b8b-af20-060888a46c0e" -version = "0.1.11" - -[[deps.SciMLOperators]] -deps = ["Accessors", "ArrayInterface", "DocStringExtensions", "LinearAlgebra", "MacroTools"] -git-tree-sha1 = "c1053ba68ede9e4005fc925dd4e8723fcd96eef8" -uuid = "c0aeaf25-5076-4817-a8d5-81caf7dfa961" -version = "1.9.0" -weakdeps = ["SparseArrays", "StaticArraysCore"] - - [deps.SciMLOperators.extensions] - SciMLOperatorsSparseArraysExt = "SparseArrays" - SciMLOperatorsStaticArraysCoreExt = "StaticArraysCore" - -[[deps.SciMLPublic]] -git-tree-sha1 = "ed647f161e8b3f2973f24979ec074e8d084f1bee" -uuid = "431bcebd-1456-4ced-9d72-93c2757fff0b" -version = "1.0.0" - -[[deps.SciMLStructures]] -deps = ["ArrayInterface"] -git-tree-sha1 = "566c4ed301ccb2a44cbd5a27da5f885e0ed1d5df" -uuid = "53ae85a6-f571-4167-b2af-e1d143709226" -version = "1.7.0" - -[[deps.Scratch]] -deps = ["Dates"] -git-tree-sha1 = "9b81b8393e50b7d4e6d0a9f14e192294d3b7c109" -uuid = "6c6a2e73-6563-6170-7368-637461726353" -version = "1.3.0" - -[[deps.Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" -version = "1.11.0" - -[[deps.Setfield]] -deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] -git-tree-sha1 = "c5391c6ace3bc430ca630251d02ea9687169ca68" -uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" -version = "1.1.2" - -[[deps.SharedArrays]] -deps = ["Distributed", "Mmap", "Random", "Serialization"] -uuid = "1a1011a3-84de-559e-8e89-a11a2f7dc383" -version = "1.11.0" - -[[deps.Showoff]] -deps = ["Dates", "Grisu"] -git-tree-sha1 = "91eddf657aca81df9ae6ceb20b959ae5653ad1de" -uuid = "992d4aef-0814-514b-bc4d-f2e9a6c4116f" -version = "1.0.3" - -[[deps.SimpleBufferStream]] -git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1" -uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7" -version = "1.2.0" - -[[deps.SimpleNonlinearSolve]] -deps = ["ADTypes", "ArrayInterface", "BracketingNonlinearSolve", "CommonSolve", "ConcreteStructs", "DifferentiationInterface", "FastClosures", "FiniteDiff", "ForwardDiff", "LineSearch", "LinearAlgebra", "MaybeInplace", "NonlinearSolveBase", "PrecompileTools", "Reexport", "SciMLBase", "Setfield", "StaticArraysCore"] -git-tree-sha1 = "8825064775bf4ae0f22d04ea63979d8c868fd510" -uuid = "727e6d20-b764-4bd8-a329-72de5adea6c7" -version = "2.9.0" - - [deps.SimpleNonlinearSolve.extensions] - SimpleNonlinearSolveChainRulesCoreExt = "ChainRulesCore" - SimpleNonlinearSolveReverseDiffExt = "ReverseDiff" - SimpleNonlinearSolveTrackerExt = "Tracker" - - [deps.SimpleNonlinearSolve.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" - -[[deps.SimpleTraits]] -deps = ["InteractiveUtils", "MacroTools"] -git-tree-sha1 = "be8eeac05ec97d379347584fa9fe2f5f76795bcb" -uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d" -version = "0.9.5" - -[[deps.SimpleUnPack]] -git-tree-sha1 = "58e6353e72cde29b90a69527e56df1b5c3d8c437" -uuid = "ce78b400-467f-4804-87d8-8f486da07d0a" -version = "1.1.0" - -[[deps.Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" -version = "1.11.0" - -[[deps.SortingAlgorithms]] -deps = ["DataStructures"] -git-tree-sha1 = "64d974c2e6fdf07f8155b5b2ca2ffa9069b608d9" -uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "1.2.2" - -[[deps.SparseArrays]] -deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] -uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" -version = "1.12.0" - -[[deps.SparseConnectivityTracer]] -deps = ["ADTypes", "DocStringExtensions", "FillArrays", "LinearAlgebra", "Random", "SparseArrays"] -git-tree-sha1 = "62f3dbfa8e0bb01ce41076ee31686f0514a9e339" -uuid = "9f842d2f-2579-4b1d-911e-f412cf18a3f5" -version = "1.1.1" - - [deps.SparseConnectivityTracer.extensions] - SparseConnectivityTracerChainRulesCoreExt = "ChainRulesCore" - SparseConnectivityTracerLogExpFunctionsExt = "LogExpFunctions" - SparseConnectivityTracerNNlibExt = "NNlib" - SparseConnectivityTracerNaNMathExt = "NaNMath" - SparseConnectivityTracerSpecialFunctionsExt = "SpecialFunctions" - - [deps.SparseConnectivityTracer.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - LogExpFunctions = "2ab3a3ac-af41-5b50-aa03-7779005ae688" - NNlib = "872c559c-99b0-510c-b3b7-b6c96a88d5cd" - NaNMath = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" - SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" - -[[deps.SparseMatrixColorings]] -deps = ["ADTypes", "DocStringExtensions", "LinearAlgebra", "PrecompileTools", "Random", "SparseArrays"] -git-tree-sha1 = "d3f3b7bb8a561b5ff20ee7cf9574841ee4e4e137" -uuid = "0a514795-09f3-496d-8182-132a7b665d35" -version = "0.4.22" - - [deps.SparseMatrixColorings.extensions] - SparseMatrixColoringsCUDAExt = "CUDA" - SparseMatrixColoringsCliqueTreesExt = "CliqueTrees" - SparseMatrixColoringsColorsExt = "Colors" - - [deps.SparseMatrixColorings.weakdeps] - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - CliqueTrees = "60701a23-6482-424a-84db-faee86b9b1f8" - Colors = "5ae59095-9a9b-59fe-a467-6f913c188581" - -[[deps.SpecialFunctions]] -deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "f2685b435df2613e25fc10ad8c26dddb8640f547" -uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.6.1" -weakdeps = ["ChainRulesCore"] - - [deps.SpecialFunctions.extensions] - SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" - -[[deps.StableRNGs]] -deps = ["Random"] -git-tree-sha1 = "4f96c596b8c8258cc7d3b19797854d368f243ddc" -uuid = "860ef19b-820b-49d6-a774-d7a799459cd3" -version = "1.0.4" - -[[deps.Static]] -deps = ["CommonWorldInvalidations", "IfElse", "PrecompileTools", "SciMLPublic"] -git-tree-sha1 = "1e44e7b1dbb5249876d84c32466f8988a6b41bbb" -uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" -version = "1.3.0" - -[[deps.StaticArrayInterface]] -deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Static"] -git-tree-sha1 = "96381d50f1ce85f2663584c8e886a6ca97e60554" -uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" -version = "1.8.0" - - [deps.StaticArrayInterface.extensions] - StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" - StaticArrayInterfaceStaticArraysExt = "StaticArrays" - - [deps.StaticArrayInterface.weakdeps] - OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - -[[deps.StaticArrays]] -deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "b8693004b385c842357406e3af647701fe783f98" -uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.15" -weakdeps = ["ChainRulesCore", "Statistics"] - - [deps.StaticArrays.extensions] - StaticArraysChainRulesCoreExt = "ChainRulesCore" - StaticArraysStatisticsExt = "Statistics" - -[[deps.StaticArraysCore]] -git-tree-sha1 = "192954ef1208c7019899fbf8049e717f92959682" -uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.3" - -[[deps.Statistics]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0" -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -version = "1.11.1" -weakdeps = ["SparseArrays"] - - [deps.Statistics.extensions] - SparseArraysExt = ["SparseArrays"] - -[[deps.StatsAPI]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "9d72a13a3f4dd3795a195ac5a44d7d6ff5f552ff" -uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" -version = "1.7.1" - -[[deps.StatsBase]] -deps = ["AliasTables", "DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] -git-tree-sha1 = "a136f98cefaf3e2924a66bd75173d1c891ab7453" -uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -version = "0.34.7" - -[[deps.StatsFuns]] -deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] -git-tree-sha1 = "1ec049c79e13fb2638ddbf8793ab2cbbeb266f45" -uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" -version = "1.5.1" -weakdeps = ["ChainRulesCore", "InverseFunctions"] - - [deps.StatsFuns.extensions] - StatsFunsChainRulesCoreExt = "ChainRulesCore" - StatsFunsInverseFunctionsExt = "InverseFunctions" - -[[deps.SteadyStateDiffEq]] -deps = ["ConcreteStructs", "DiffEqBase", "DiffEqCallbacks", "LinearAlgebra", "NonlinearSolveBase", "Reexport", "SciMLBase"] -git-tree-sha1 = "0a297695b71f24b4158c9c4c1eaaec976a86e87d" -uuid = "9672c7b4-1e72-59bd-8a11-6ac3964bc41f" -version = "2.7.0" - -[[deps.StochasticDiffEq]] -deps = ["ADTypes", "Adapt", "ArrayInterface", "DataStructures", "DiffEqBase", "DiffEqNoiseProcess", "DocStringExtensions", "FastPower", "FiniteDiff", "ForwardDiff", "JumpProcesses", "LevyArea", "LinearAlgebra", "Logging", "MuladdMacro", "NLsolve", "OrdinaryDiffEqCore", "OrdinaryDiffEqDifferentiation", "OrdinaryDiffEqNonlinearSolve", "Random", "RandomNumbers", "RecursiveArrayTools", "Reexport", "SciMLBase", "SciMLOperators", "SparseArrays", "StaticArrays", "UnPack"] -git-tree-sha1 = "63c85dd929eaf9910fd30ba1b5aa2892d3bb0368" -uuid = "789caeaf-c7a9-5a7d-9973-96adeb23e2a0" -version = "6.83.0" - -[[deps.StrideArraysCore]] -deps = ["ArrayInterface", "CloseOpenIntervals", "IfElse", "LayoutPointers", "LinearAlgebra", "ManualMemory", "SIMDTypes", "Static", "StaticArrayInterface", "ThreadingUtilities"] -git-tree-sha1 = "83151ba8065a73f53ca2ae98bc7274d817aa30f2" -uuid = "7792a7ef-975c-4747-a70f-980b88e8d1da" -version = "0.5.8" - -[[deps.StructTypes]] -deps = ["Dates", "UUIDs"] -git-tree-sha1 = "159331b30e94d7b11379037feeb9b690950cace8" -uuid = "856f2bd8-1eba-4b0a-8007-ebc267875bd4" -version = "1.11.0" - -[[deps.StructUtils]] -deps = ["Dates", "UUIDs"] -git-tree-sha1 = "cd47aa083c9c7bdeb7b92de26deb46d6a33163c9" -uuid = "ec057cc2-7a8d-4b58-b3b3-92acb9f63b42" -version = "2.5.1" - - [deps.StructUtils.extensions] - StructUtilsMeasurementsExt = ["Measurements"] - StructUtilsTablesExt = ["Tables"] - - [deps.StructUtils.weakdeps] - Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" - Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" - -[[deps.StyledStrings]] -uuid = "f489334b-da3d-4c2e-b8f0-e476e12c162b" -version = "1.11.0" - -[[deps.SuiteSparse]] -deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] -uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" - -[[deps.SuiteSparse_jll]] -deps = ["Artifacts", "Libdl", "libblastrampoline_jll"] -uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "7.8.3+2" - -[[deps.Sundials]] -deps = ["CEnum", "DataStructures", "DiffEqBase", "Libdl", "LinearAlgebra", "Logging", "PrecompileTools", "Reexport", "SciMLBase", "SparseArrays", "Sundials_jll"] -git-tree-sha1 = "7c7a7ee705724b3c80d5451ac49779db36c6f758" -uuid = "c3572dad-4567-51f8-b174-8c6c989267f4" -version = "4.28.0" - -[[deps.Sundials_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "SuiteSparse_jll", "libblastrampoline_jll"] -git-tree-sha1 = "91db7ed92c66f81435fe880947171f1212936b14" -uuid = "fb77eaff-e24c-56d4-86b1-d163f2edb164" -version = "5.2.3+0" - -[[deps.SymbolicIndexingInterface]] -deps = ["Accessors", "ArrayInterface", "RuntimeGeneratedFunctions", "StaticArraysCore"] -git-tree-sha1 = "94c58884e013efff548002e8dc2fdd1cb74dfce5" -uuid = "2efcf032-c050-4f8e-a9bb-153293bab1f5" -version = "0.3.46" - - [deps.SymbolicIndexingInterface.extensions] - SymbolicIndexingInterfacePrettyTablesExt = "PrettyTables" - - [deps.SymbolicIndexingInterface.weakdeps] - PrettyTables = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" - -[[deps.TOML]] -deps = ["Dates"] -uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" -version = "1.0.3" - -[[deps.Tar]] -deps = ["ArgTools", "SHA"] -uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" -version = "1.10.0" - -[[deps.TensorCore]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" -uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" -version = "0.1.1" - -[[deps.Test]] -deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" -version = "1.11.0" - -[[deps.ThreadingUtilities]] -deps = ["ManualMemory"] -git-tree-sha1 = "d969183d3d244b6c33796b5ed01ab97328f2db85" -uuid = "8290d209-cae3-49c0-8002-c8c24d57dab5" -version = "0.5.5" - -[[deps.TimerOutputs]] -deps = ["ExprTools", "Printf"] -git-tree-sha1 = "3748bd928e68c7c346b52125cf41fff0de6937d0" -uuid = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f" -version = "0.5.29" - - [deps.TimerOutputs.extensions] - FlameGraphsExt = "FlameGraphs" - - [deps.TimerOutputs.weakdeps] - FlameGraphs = "08572546-2f56-4bcf-ba4e-bab62c3a3f89" - -[[deps.TranscodingStreams]] -git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742" -uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.11.3" - -[[deps.TruncatedStacktraces]] -deps = ["InteractiveUtils", "MacroTools", "Preferences"] -git-tree-sha1 = "ea3e54c2bdde39062abf5a9758a23735558705e1" -uuid = "781d530d-4396-4725-bb49-402e4bee1e77" -version = "1.4.0" - -[[deps.URIs]] -git-tree-sha1 = "bef26fb046d031353ef97a82e3fdb6afe7f21b1a" -uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" -version = "1.6.1" - -[[deps.UUIDs]] -deps = ["Random", "SHA"] -uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" -version = "1.11.0" - -[[deps.UnPack]] -git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" -uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" -version = "1.0.2" - -[[deps.Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" -version = "1.11.0" - -[[deps.UnicodeFun]] -deps = ["REPL"] -git-tree-sha1 = "53915e50200959667e78a92a418594b428dffddf" -uuid = "1cfade01-22cf-5700-b092-accc4b62d6e1" -version = "0.4.1" - -[[deps.Unzip]] -git-tree-sha1 = "ca0969166a028236229f63514992fc073799bb78" -uuid = "41fe7b60-77ed-43a1-b4f0-825fd5a5650d" -version = "0.2.0" - -[[deps.Vulkan_Loader_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Wayland_jll", "Xorg_libX11_jll", "Xorg_libXrandr_jll", "xkbcommon_jll"] -git-tree-sha1 = "2f0486047a07670caad3a81a075d2e518acc5c59" -uuid = "a44049a8-05dd-5a78-86c9-5fde0876e88c" -version = "1.3.243+0" - -[[deps.Wayland_jll]] -deps = ["Artifacts", "EpollShim_jll", "Expat_jll", "JLLWrappers", "Libdl", "Libffi_jll"] -git-tree-sha1 = "96478df35bbc2f3e1e791bc7a3d0eeee559e60e9" -uuid = "a2964d1f-97da-50d4-b82a-358c7fce9d89" -version = "1.24.0+0" - -[[deps.XML2_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "80d3930c6347cfce7ccf96bd3bafdf079d9c0390" -uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.13.9+0" - -[[deps.XZ_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "fee71455b0aaa3440dfdd54a9a36ccef829be7d4" -uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" -version = "5.8.1+0" - -[[deps.Xorg_libICE_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "a3ea76ee3f4facd7a64684f9af25310825ee3668" -uuid = "f67eecfb-183a-506d-b269-f58e52b52d7c" -version = "1.1.2+0" - -[[deps.Xorg_libSM_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libICE_jll"] -git-tree-sha1 = "9c7ad99c629a44f81e7799eb05ec2746abb5d588" -uuid = "c834827a-8449-5923-a945-d239c165b7dd" -version = "1.2.6+0" - -[[deps.Xorg_libX11_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xtrans_jll"] -git-tree-sha1 = "b5899b25d17bf1889d25906fb9deed5da0c15b3b" -uuid = "4f6342f7-b3d2-589e-9d20-edeb45f2b2bc" -version = "1.8.12+0" - -[[deps.Xorg_libXau_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "aa1261ebbac3ccc8d16558ae6799524c450ed16b" -uuid = "0c0b7dd1-d40b-584c-a123-a41640f87eec" -version = "1.0.13+0" - -[[deps.Xorg_libXcursor_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXfixes_jll", "Xorg_libXrender_jll"] -git-tree-sha1 = "6c74ca84bbabc18c4547014765d194ff0b4dc9da" -uuid = "935fb764-8cf2-53bf-bb30-45bb1f8bf724" -version = "1.2.4+0" - -[[deps.Xorg_libXdmcp_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "52858d64353db33a56e13c341d7bf44cd0d7b309" -uuid = "a3789734-cfe1-5b06-b2d0-1dd0d9d62d05" -version = "1.1.6+0" - -[[deps.Xorg_libXext_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] -git-tree-sha1 = "a4c0ee07ad36bf8bbce1c3bb52d21fb1e0b987fb" -uuid = "1082639a-0dae-5f34-9b06-72781eeb8cb3" -version = "1.3.7+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_libXi_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll", "Xorg_libXfixes_jll"] -git-tree-sha1 = "a376af5c7ae60d29825164db40787f15c80c7c54" -uuid = "a51aa0fd-4e3c-5386-b890-e753decda492" -version = "1.8.3+0" - -[[deps.Xorg_libXinerama_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll"] -git-tree-sha1 = "a5bc75478d323358a90dc36766f3c99ba7feb024" -uuid = "d1454406-59df-5ea1-beac-c340f2130bc3" -version = "1.1.6+0" - -[[deps.Xorg_libXrandr_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXext_jll", "Xorg_libXrender_jll"] -git-tree-sha1 = "aff463c82a773cb86061bce8d53a0d976854923e" -uuid = "ec84b674-ba8e-5d96-8ba1-2a689ba10484" -version = "1.5.5+0" - -[[deps.Xorg_libXrender_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] -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 = "4909eb8f1cbf6bd4b1c30dd18b2ead9019ef2fad" -uuid = "a65dc6b1-eb27-53a1-bb3e-dea574b5389e" -version = "0.18.1+0" - -[[deps.Xorg_libxcb_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libXau_jll", "Xorg_libXdmcp_jll"] -git-tree-sha1 = "bfcaf7ec088eaba362093393fe11aa141fa15422" -uuid = "c7cfdc94-dc32-55de-ac96-5a1b8d977c5b" -version = "1.17.1+0" - -[[deps.Xorg_libxkbfile_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll"] -git-tree-sha1 = "e3150c7400c41e207012b41659591f083f3ef795" -uuid = "cc61e674-0454-545c-8b26-ed2c68acab7a" -version = "1.1.3+0" - -[[deps.Xorg_xcb_util_cursor_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_jll", "Xorg_xcb_util_renderutil_jll"] -git-tree-sha1 = "9750dc53819eba4e9a20be42349a6d3b86c7cdf8" -uuid = "e920d4aa-a673-5f3a-b3d7-f755a4d47c43" -version = "0.1.6+0" - -[[deps.Xorg_xcb_util_image_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] -git-tree-sha1 = "f4fc02e384b74418679983a97385644b67e1263b" -uuid = "12413925-8142-5f55-bb0e-6d7ca50bb09b" -version = "0.4.1+0" - -[[deps.Xorg_xcb_util_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll"] -git-tree-sha1 = "68da27247e7d8d8dafd1fcf0c3654ad6506f5f97" -uuid = "2def613f-5ad1-5310-b15b-b15d46f528f5" -version = "0.4.1+0" - -[[deps.Xorg_xcb_util_keysyms_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] -git-tree-sha1 = "44ec54b0e2acd408b0fb361e1e9244c60c9c3dd4" -uuid = "975044d2-76e6-5fbe-bf08-97ce7c6574c7" -version = "0.4.1+0" - -[[deps.Xorg_xcb_util_renderutil_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] -git-tree-sha1 = "5b0263b6d080716a02544c55fdff2c8d7f9a16a0" -uuid = "0d47668e-0667-5a69-a72c-f761630bfb7e" -version = "0.3.10+0" - -[[deps.Xorg_xcb_util_wm_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xcb_util_jll"] -git-tree-sha1 = "f233c83cad1fa0e70b7771e0e21b061a116f2763" -uuid = "c22f9ab0-d5fe-5066-847c-f4bb1cd4e361" -version = "0.4.2+0" - -[[deps.Xorg_xkbcomp_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxkbfile_jll"] -git-tree-sha1 = "801a858fc9fb90c11ffddee1801bb06a738bda9b" -uuid = "35661453-b289-5fab-8a00-3d9160c6a3a4" -version = "1.4.7+0" - -[[deps.Xorg_xkeyboard_config_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_xkbcomp_jll"] -git-tree-sha1 = "00af7ebdc563c9217ecc67776d1bbf037dbcebf4" -uuid = "33bec58e-1273-512f-9401-5d533626f822" -version = "2.44.0+0" - -[[deps.Xorg_xtrans_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "a63799ff68005991f9d9491b6e95bd3478d783cb" -uuid = "c5fb5394-a638-5e4d-96e5-b29de1b5cf10" -version = "1.6.0+0" - -[[deps.Zlib_jll]] -deps = ["Libdl"] -uuid = "83775a58-1f1d-513f-b197-d71354ab007a" -version = "1.3.1+2" - -[[deps.Zstd_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "446b23e73536f84e8037f5dce465e92275f6a308" -uuid = "3161d3a3-bdf6-5164-811a-617609db77b4" -version = "1.5.7+1" - -[[deps.eudev_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "c3b0e6196d50eab0c5ed34021aaa0bb463489510" -uuid = "35ca27e7-8b34-5b7f-bca9-bdc33f59eb06" -version = "3.2.14+0" - -[[deps.fzf_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "b6a34e0e0960190ac2a4363a1bd003504772d631" -uuid = "214eeab7-80f7-51ab-84ad-2988db7cef09" -version = "0.61.1+0" - -[[deps.libaom_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "371cc681c00a3ccc3fbc5c0fb91f58ba9bec1ecf" -uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" -version = "3.13.1+0" - -[[deps.libass_jll]] -deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "125eedcb0a4a0bba65b657251ce1d27c8714e9d6" -uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" -version = "0.17.4+0" - -[[deps.libblastrampoline_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.15.0+0" - -[[deps.libdecor_jll]] -deps = ["Artifacts", "Dbus_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "Pango_jll", "Wayland_jll", "xkbcommon_jll"] -git-tree-sha1 = "9bf7903af251d2050b467f76bdbe57ce541f7f4f" -uuid = "1183f4f0-6f2a-5f1a-908b-139f9cdfea6f" -version = "0.2.2+0" - -[[deps.libevdev_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "56d643b57b188d30cccc25e331d416d3d358e557" -uuid = "2db6ffa8-e38f-5e21-84af-90c45d0032cc" -version = "1.13.4+0" - -[[deps.libfdk_aac_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "646634dd19587a56ee2f1199563ec056c5f228df" -uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" -version = "2.0.4+0" - -[[deps.libinput_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "eudev_jll", "libevdev_jll", "mtdev_jll"] -git-tree-sha1 = "91d05d7f4a9f67205bd6cf395e488009fe85b499" -uuid = "36db933b-70db-51c0-b978-0f229ee0e533" -version = "1.28.1+0" - -[[deps.libpng_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "07b6a107d926093898e82b3b1db657ebe33134ec" -uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" -version = "1.6.50+0" - -[[deps.libvorbis_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll"] -git-tree-sha1 = "11e1772e7f3cc987e9d3de991dd4f6b2602663a5" -uuid = "f27f6e37-5d2b-51aa-960f-b287f2bc3b7a" -version = "1.3.8+0" - -[[deps.mtdev_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "b4d631fd51f2e9cdd93724ae25b2efc198b059b1" -uuid = "009596ad-96f7-51b1-9f1b-5ce2d5e8a71e" -version = "1.1.7+0" - -[[deps.nghttp2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.64.0+1" - -[[deps.oneTBB_jll]] -deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] -git-tree-sha1 = "1350188a69a6e46f799d3945beef36435ed7262f" -uuid = "1317d2d5-d96f-522e-a858-c73665f53c3e" -version = "2022.0.0+1" - -[[deps.p7zip_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.5.0+2" - -[[deps.x264_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "14cc7083fc6dff3cc44f2bc435ee96d06ed79aa7" -uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" -version = "10164.0.1+0" - -[[deps.x265_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "e7b67590c14d487e734dcb925924c5dc43ec85f3" -uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" -version = "4.1.0+0" - -[[deps.xkbcommon_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libxcb_jll", "Xorg_xkeyboard_config_jll"] -git-tree-sha1 = "fbf139bce07a534df0e699dbb5f5cc9346f95cc1" -uuid = "d8fb68d0-12a3-5cfd-a85a-d49703b185fd" -version = "1.9.2+0" diff --git a/Project.toml b/Project.toml deleted file mode 100644 index 00cada6..0000000 --- a/Project.toml +++ /dev/null @@ -1,35 +0,0 @@ -name = "KernelEconExamples" -uuid = "9d687d3a-22d1-4cc8-8dc9-bb15139a4de0" -version = "1.0.0-DEV" -authors = ["Jesse Perla and contributors"] - -[deps] -BoundaryValueDiffEq = "764a87c0-6b3e-53db-9096-fe964310641d" -DifferentialEquations = "0c46a032-eb83-5123-abaf-570d42b7fbaa" -Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" -Ipopt = "b6b21f68-93f8-5de0-b562-5493be1d77c9" -JuMP = "4076af6c-e467-56ae-b986-b466b2749572" -LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" -OSQP = "ab2f91bb-94b4-55e3-9ba0-7f65df51de79" -Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" -QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" - -[compat] -BoundaryValueDiffEq = "5.18.0" -DifferentialEquations = "7.16.1" -Distributions = "0.25.120" -Ipopt = "1.12.0" -JuMP = "1.29.2" -LinearAlgebra = "1.12.0" -OSQP = "0.8.1" -Plots = "1.41.1" -QuadGK = "2.11.2" -Statistics = "1.11.1" -julia = "1.11" - -[extras] -Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[targets] -test = ["Test"] diff --git a/README.md b/README.md index ce44044..3c30fbf 100644 --- a/README.md +++ b/README.md @@ -1,90 +1,73 @@ -# Solving Models of Economic Dynamics with Ridgeless Kernel Regressions -This repository contains the replication code and extra examples for [Solving Models of Economic Dynamics with Ridgeless Kernel Regressions](https://arxiv.org/pdf/2406.01898) by Mahdi Ebrahimi Kahou, Jesse Perla, and Geoff Pleiss - -Full replication code is provided for Python, and additional Julia code is in progress. - -# Python Setup -We recommend installation with `uv` (on all platforms, but especially on MacOS and Linux). If you wish to use `conda` see notes at the end of these instructions. - -## Windows Ipopt Installation -Ipopt binary installation is tricky, and we find the most reliable method is to use Anaconda (even if you will otherwise use `uv`). To do so, install ipopt in your base Anaconda with - -```bash -conda install -n base -c conda-forge ipopt=3.11.1 pkg-config -``` - - For Windows, version `3.11.1` seems to be essential. - - If you have clutter in your base Anaconda which prevents this from correctly installing, then you may need to reinstall Anaconda. - - If you run into issues the binary dependencies in Julia are bullet-proof and seamless. - -## Setup with uv -`uv` is a much faster alternative to Conda, even if it has incomplete support for challenging binary dependencies. - -1. Install [uv](https://github.com/astral-sh/uv#installation). This is a usually a one-line installation: - - On Linux/MacOS: `curl -LsSf https://astral.sh/uv/install.sh | sh` - - On Windows: `powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"` or with winget `winget install --id=astral-sh.uv -e` - - If you have any installation issues, [see the docs](https://docs.astral.sh/uv/getting-started/installation/) for troubleshooting -2. Install optimizer dependencies. - - On MacOS: `brew install ipopt pkg-config` - - Linux: `sudo apt-get install coinor-libipopt-dev pkg-config` - - Windows: See note above if you have not previously installed Ipopt or JAX -3. Synchronize the environment -```bash - uv sync -``` -4. Finally, you will want to make sure you activate the python environment each time you use it. - - In VS Code you can activate the default environment with `>Python: Select Interpreter` to be the `.venv` local to the directory - - If the debugger isn't working in that case, sometimes setting the vscode `terminal.integrated.shellIntegration.enabled: true` in the settings can help - - Outside of vscode, a simple, platform specific CLI line will [activate .venv](https://docs.python.org/3/tutorial/venv.html#creating-virtual-environments) in your terminal. - -**Troubleshooting**: -- If you receive JAX errors about DLL load failures, you may need to update [https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#visual-studio-2015-2017-2019-and-2022](https://learn.microsoft.com/en-us/cpp/windows/latest-supported-vc-redist?view=msvc-170#visual-studio-2015-2017-2019-and-2022) -- See notes above on Windows Ipopt installation challenges - -## Figure Replication -After installation, to generate all of the figures in the paper and the appendices, - -```bash -python all_figures.py -``` - -The output will be in the `./figures` folder - -## Example Usage -The individual files support CLI arguments. To pick specific points rather than the linspace grid, pass in `--train_points_list` as below - -```bash -python neoclassical_growth_matern.py -python neoclassical_growth_matern.py --train_points=5 -python neoclassical_growth_matern.py --rho=5.0 -python neoclassical_growth_matern.py --train_points_list="[0.0,2.0,5.0,10.0,20.0]" -python neoclassical_growth_matern.py --train_points=20 --train_T=10.0 --test_T=10.0 --k_0=0.5 -``` - -These functions can also be imported and called directly, for example, - -```python -from neoclassical_growth_matern import neoclassical_growth_matern -sol = neoclassical_growth_matern(rho=10.0) -print(sol["c_rel_error"].mean())~~~~ -``` - -## Python Conda Installation -If you prefer to use `conda` for your entire environment management, install `uv` as above, then generate a requirements file and a conda environment - -```bash -uv pip freeze > requirements.txt -conda create -n kernels python=3.11 -conda activate kernels -pip install -r requirements.txt -conda install -c conda-forge ipopt=3.11.1 -``` - - -# Julia Setup -Julia is more straightforward and cross-platform -1. If required, install Julia from [juliaup](https://github.com/JuliaLang/juliaup). This can be done in a one-line terminal command: - - MacOS/Linux: `curl -fsSL https://install.julialang.org | sh` - - Windows: `winget install --name Julia --id 9NJNWW8PVKMN -e -s msstore` -2. Install the [VS Code Julia extension](https://marketplace.visualstudio.com/items?itemName=julialang.language-julia). See [here](https://julia.quantecon.org/getting_started_julia/getting_started.html#setting-up-git-and-vs-code) for more details. -3. Then activate and instantiate the environment to get the required packages. See [here](https://julia.quantecon.org/getting_started_julia/getting_started.html#installing-packages) for more. - - If you start a Julia REPL is VS Code, then you just need: `] instantiate` \ No newline at end of file +# Solving Models of Economic Dynamics with Ridgeless Kernel Regressions + +This repository contains replication code and extra Python examples for +[Solving Models of Economic Dynamics with Ridgeless Kernel Regressions](https://arxiv.org/pdf/2406.01898) +by Mahdi Ebrahimi Kahou, Jesse Perla, and Geoff Pleiss. + +## Setup + +Use `uv` for all Python environment management. + +1. Install [uv](https://docs.astral.sh/uv/getting-started/installation/). + - Linux/macOS: `curl -LsSf https://astral.sh/uv/install.sh | sh` + - Windows PowerShell: `powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"` + - Windows winget: `winget install --id=astral-sh.uv -e` +2. Synchronize the environment: + +```bash +uv sync +``` + +The project solves the RKHS collocation problems through direct JAX callbacks +to UNO via the `unopy` wheel. No optimization DSL, external optimizer +executable, or conda environment is needed. + +The human-capital example uses `nlls_gram` for its small JAX float64 +initial-condition solve. + +## Figure Replication + +Generate the paper and appendix figures with: + +```bash +uv run python all_figures.py +``` + +Outputs are written to `./figures`. + +## Example Usage + +Individual scripts support CLI arguments through `jsonargparse`: + +```bash +uv run python neoclassical_growth_matern.py +uv run python neoclassical_growth_matern.py --train_points=5 +uv run python neoclassical_growth_matern.py --rho=5.0 +uv run python neoclassical_growth_matern.py --train_points_list="[0.0,2.0,5.0,10.0,20.0]" +uv run python neoclassical_growth_matern.py --train_points=20 --train_T=10.0 --test_T=10.0 --k_0=0.5 +``` + +The functions can also be imported directly: + +```python +from neoclassical_growth_matern import neoclassical_growth_matern + +sol = neoclassical_growth_matern(rho=10.0) +print(sol["c_rel_error"].mean()) +``` + +## Models + +- `asset_pricing_matern.py`: asset-pricing QP. +- `neoclassical_growth_matern.py`: baseline and optional kinked-production neoclassical growth DNLP. +- `neoclassical_growth_concave_convex_matern.py`: concave-convex growth wrapper. +- `neoclassical_human_capital_matern.py`: two-capital human-capital DNLP. +- `optimal_advertising_matern.py`: optimal-advertising DNLP. + +## Tests + +Run the Python smoke and initialization checks with: + +```bash +uv run python -m unittest discover -s tests +``` diff --git a/all_figures.py b/all_figures.py index 0de3e4c..cc361ed 100644 --- a/all_figures.py +++ b/all_figures.py @@ -1,28 +1,23 @@ -import os - -output_folder = os.path.abspath( - os.path.join(os.path.dirname(os.path.abspath(__file__)), "figures") -) -os.makedirs(output_folder, exist_ok=True) - -# run all the figures scripts -print("Executing figures_asset_pricing.py") -os.system("python figures_asset_pricing.py") - -print("Executing figures_neoclassical_growth_concave_convex.py") -os.system("python figures_neoclassical_growth_concave_convex.py") - -print("Executing figures_neoclassical_growth_baseline.py") -os.system("python figures_neoclassical_growth_baseline.py") - -print("Executing figures_neoclassical_growth_robustness.py") -os.system("python figures_neoclassical_growth_robustness.py") - -print("Executing figures_optimal_advertising.py") -os.system("python figures_optimal_advertising.py") - -print("Executing tables_neoclassical_growth.py") -os.system("python tables_neoclassical_growth.py") - -print("Executing figures_neoclassical_human_capital.py") -os.system("python figures_neoclassical_human_capital.py") +import os +import subprocess +import sys + +output_folder = os.path.abspath( + os.path.join(os.path.dirname(os.path.abspath(__file__)), "figures") +) +os.makedirs(output_folder, exist_ok=True) + +SCRIPTS = [ + "figures_asset_pricing.py", + "figures_neoclassical_growth_concave_convex.py", + "figures_neoclassical_growth_baseline.py", + "figures_neoclassical_growth_robustness.py", + "figures_optimal_advertising.py", + "tables_neoclassical_growth.py", + "figures_neoclassical_human_capital.py", +] + + +for script in SCRIPTS: + print(f"Executing {script}") + subprocess.run([sys.executable, script], check=True) diff --git a/asset_pricing_benchmark.py b/asset_pricing_benchmark.py index 7a4d8a3..c964a0a 100644 --- a/asset_pricing_benchmark.py +++ b/asset_pricing_benchmark.py @@ -1,17 +1,12 @@ -import jax.numpy as jnp -from scipy.integrate import quad - - -def mu_f_array(t, c, g, r, x_0): - - def x(s, c, g, x_0): - return (x_0 + (c / g)) * jnp.exp(g * s) - (c / g) - - def discount_x(s): - return jnp.exp(-r * s) * x(s, c, g, x_0) - - result = jnp.zeros_like(t) - for i, t_value in enumerate(t): - integral, err = quad(discount_x, t_value, 2000) - result = result.at[i].set(jnp.exp(r * t_value) * integral) - return result +import jax.numpy as jnp + + +def mu_f_array(t, c, g, r, x_0): + a = x_0 + c / g + horizon = 2000.0 + exp_gt = jnp.exp(g * t) + finite_horizon = jnp.exp(r * t) * ( + a * jnp.exp((g - r) * horizon) / (g - r) + + (c / (g * r)) * jnp.exp(-r * horizon) + ) + return finite_horizon - a * exp_gt / (g - r) - c / (g * r) diff --git a/asset_pricing_matern.py b/asset_pricing_matern.py index 9702588..609584c 100644 --- a/asset_pricing_matern.py +++ b/asset_pricing_matern.py @@ -1,16 +1,21 @@ +import time +from typing import List, Optional + import jax import jax.numpy as jnp -import numpy as np -import pyomo.environ as pyo -from pyomo.opt import TerminationCondition import jsonargparse +import numpy as np +import unopy from jax import config -from kernels import integrated_matern_kernel_matrices + from asset_pricing_benchmark import mu_f_array -from typing import List, Optional +from kernels import integrated_matern_kernel_matrices +from rkhs import rkhs_norm_squared config.update("jax_enable_x64", True) +NLP_OPTIONS = dict(preset="ipopt") + def asset_pricing_matern( r: float = 0.1, @@ -20,7 +25,6 @@ def asset_pricing_matern( nu: float = 0.5, sigma: float = 1.0, rho: float = 10, - solver_type: str = "ipopt", train_T: float = 40.0, train_points: int = 41, test_T: float = 50.0, @@ -28,90 +32,190 @@ def asset_pricing_matern( train_points_list: Optional[List[float]] = None, verbose: bool = False, ): - # if passing in `train_points` then doesn't us a grid. Otherwise, uses linspace if train_points_list is None: train_data = jnp.linspace(0, train_T, train_points) else: train_data = jnp.array(train_points_list) test_data = jnp.linspace(0, test_T, test_points) - # Construct kernel matrices - N = len(train_data) + n_train = len(train_data) K, K_tilde = integrated_matern_kernel_matrices( train_data, train_data, nu, sigma, rho ) - K = np.array(K) # pyomo doesn't support jax arrays - K_tilde = np.array(K_tilde) - - # Create pyomo model and variables - m = pyo.ConcreteModel() - m.I = range(N) - m.alpha_mu = pyo.Var(m.I, within=pyo.Reals, initialize=0.0) - m.mu_0 = pyo.Var(within=pyo.NonNegativeReals, initialize=0.0) - - - # Map kernels to variables. Pyomo doesn't support p_0 + K_tilde @ m.alpha - def mu(m, i): - return m.mu_0 + sum(K_tilde[i, j] * m.alpha_mu[j] for j in m.I) - - def dmu_dt(m, i): - return sum(K[i, j] * m.alpha_mu[j] for j in m.I) - - def x(i): - return (x_0 + (c / g)) * np.exp(g * i) - (c / g) - - # Define constraints and objective for model and solve - @m.Constraint(m.I) # for each index in m.I - def dp_dt_constraint(m, i): - return dmu_dt(m, i) == r * mu(m, i) - x(i) - - - @m.Objective(sense=pyo.minimize) - def min_norm(m): # alpha @ K @ alpha not supported by pyomo - return sum(K[i, j] * m.alpha_mu[i] * m.alpha_mu[j] for i in m.I for j in m.I) - - solver = pyo.SolverFactory(solver_type) - options = { - "tol": 1e-14, # Tighten the tolerance for optimality - "dual_inf_tol": 1e-14, # Tighten the dual infeasibility tolerance - "constr_viol_tol": 1e-14, # Tighten the constraint violation tolerance - "max_iter": 5000, # Adjust the maximum number of iterations if needed - } - results = solver.solve(m, tee=verbose, options=options) - if not results.solver.termination_condition == TerminationCondition.optimal: - print(str(results.solver)) # raise exception? - - alpha_mu = jnp.array([pyo.value(m.alpha_mu[i]) for i in m.I]) - mu_0 = pyo.value(m.mu_0) - - # Interpolator using training data + K = np.asarray((K + K.T) / 2) + K_tilde = np.asarray(K_tilde) + K_jax = jnp.asarray(K) + K_tilde_jax = jnp.asarray(K_tilde) + x_train = (x_0 + c / g) * jnp.exp(g * train_data) - c / g + + n_variables = n_train + 1 + n_constraints = n_train + p_0_guess = float(mu_f_array(jnp.array([0.0]), c, g, r, x_0)[0]) + x_initial = np.zeros(n_variables, dtype=np.float64) + x_initial[n_train] = max(p_0_guess, 0.0) + + def unpack(z): + alpha = z[:n_train] + p_0 = z[n_train] + return alpha, p_0 + + def path_values(z, K_eval, K_tilde_eval): + alpha, p_0 = unpack(z) + p = p_0 + K_tilde_eval @ alpha + dp_dt = K_eval @ alpha + return p, dp_dt + + def objective(z): + alpha, _ = unpack(z) + return alpha @ K_jax @ alpha + + def constraints(z): + p, dp_dt = path_values(z, K_jax, K_tilde_jax) + return dp_dt - (r * p - x_train) + + def lagrangian(z, objective_multiplier, multipliers): + return objective_multiplier * objective(z) + jnp.dot(multipliers, constraints(z)) + + objective_value = jax.jit(objective) + objective_gradient = jax.jit(jax.grad(objective)) + constraint_values = jax.jit(constraints) + constraint_jacobian = jax.jit(jax.jacfwd(constraints)) + lagrangian_hessian = jax.jit(jax.hessian(lagrangian, argnums=0)) + + x_initial_jax = jnp.asarray(x_initial) + zero_multipliers = jnp.zeros(n_constraints, dtype=jnp.float64) + jax.block_until_ready(objective_value(x_initial_jax)) + jax.block_until_ready(objective_gradient(x_initial_jax)) + jax.block_until_ready(constraint_values(x_initial_jax)) + jax.block_until_ready(constraint_jacobian(x_initial_jax)) + jax.block_until_ready(lagrangian_hessian(x_initial_jax, 1.0, zero_multipliers)) + + variable_lower_bounds = np.full(n_variables, -np.inf, dtype=np.float64) + variable_upper_bounds = np.full(n_variables, np.inf, dtype=np.float64) + variable_lower_bounds[n_train] = 0.0 + constraint_lower_bounds = np.zeros(n_constraints, dtype=np.float64) + constraint_upper_bounds = np.zeros(n_constraints, dtype=np.float64) + + model = unopy.Model( + unopy.PROBLEM_QUADRATIC, + n_variables, + variable_lower_bounds, + variable_upper_bounds, + unopy.ZERO_BASED_INDEXING, + ) + + def objective_callback(z): + return float(objective_value(jnp.asarray(z))) + + def objective_gradient_callback(z, gradient): + gradient[:] = np.asarray(objective_gradient(jnp.asarray(z))) + + model.set_objective( + unopy.MINIMIZE, objective_callback, objective_gradient_callback + ) + + jacobian_rows = np.repeat(np.arange(n_constraints, dtype=np.int32), n_variables) + jacobian_columns = np.tile(np.arange(n_variables, dtype=np.int32), n_constraints) + + def constraints_callback(z, constraint_output): + constraint_output[:] = np.asarray(constraint_values(jnp.asarray(z))) + + def jacobian_callback(z, jacobian_output): + jacobian_output[:] = np.asarray( + constraint_jacobian(jnp.asarray(z)) + ).reshape(-1) + + model.set_constraints( + n_constraints, + constraints_callback, + constraint_lower_bounds, + constraint_upper_bounds, + len(jacobian_rows), + jacobian_rows, + jacobian_columns, + jacobian_callback, + ) + + hessian_rows, hessian_columns = np.tril_indices(n_variables) + hessian_rows = hessian_rows.astype(np.int32) + hessian_columns = hessian_columns.astype(np.int32) + + def hessian_callback(z, objective_multiplier, multipliers, hessian_output): + hessian = np.asarray( + lagrangian_hessian( + jnp.asarray(z), + float(objective_multiplier), + jnp.asarray(multipliers), + ) + ) + hessian_output[:] = hessian[hessian_rows, hessian_columns] + + model.set_lagrangian_hessian( + len(hessian_rows), + unopy.LOWER_TRIANGLE, + hessian_rows, + hessian_columns, + hessian_callback, + ) + model.set_lagrangian_sign_convention(unopy.MULTIPLIER_POSITIVE) + model.set_initial_primal_iterate(x_initial) + + solver = unopy.UnoSolver() + options = dict(NLP_OPTIONS) + solver.set_preset(options.pop("preset")) + if not verbose: + solver.set_option("logger", "SILENT") + solver.set_option("print_solution", False) + for option_name, option_value in options.items(): + solver.set_option(option_name, option_value) + + start = time.perf_counter() + result = solver.optimize(model) + elapsed = time.perf_counter() - start + + z = jnp.asarray(np.array(result.primal_solution, dtype=np.float64)) + alpha, p_0 = unpack(z) + rkhs_norms = {"p": rkhs_norm_squared(alpha, K)} + train_residual = constraints(z) + max_train_residual = float(jnp.max(jnp.abs(train_residual))) + @jax.jit - def kernel_solution(test_data): - # pointwise comparison test_data to train_data - K_test, K_tilde_test = integrated_matern_kernel_matrices( - test_data, train_data, nu, sigma, rho + def kernel_solution(test_points_data): + _, K_tilde_test = integrated_matern_kernel_matrices( + test_points_data, train_data, nu, sigma, rho ) - mu_test = mu_0 + K_tilde_test @ alpha_mu - return mu_test + return p_0 + K_tilde_test @ alpha - # Generate test_data and compare to the benchmark - mu_benchmark = mu_f_array(test_data, c, g, r, x_0) - mu_test = kernel_solution(test_data) + p_benchmark = mu_f_array(test_data, c, g, r, x_0) + p_test = kernel_solution(test_data) + p_rel_error = jnp.abs(p_benchmark - p_test) / p_benchmark - mu_rel_error = jnp.abs(mu_benchmark - mu_test) / mu_benchmark + solve_time = result.cpu_time + if solve_time is None: + solve_time = elapsed + solver_status = str(result.optimization_status).split(".")[-1] + solution_status = str(result.solution_status).split(".")[-1] print( - f"solve_time(s) = {results.solver.Time}, E(|rel_error(p)|) = {mu_rel_error.mean()}" + f"solve_time(s) = {solve_time}, E(|rel_error(p)|) = {p_rel_error.mean()}" ) return { "t_train": train_data, "t_test": test_data, - "p_test": mu_test, - "p_benchmark": mu_benchmark, - "p_rel_error": mu_rel_error, - "alpha": alpha_mu, - "p_0": mu_0, - "solve_time": results.solver.Time, - "kernel_solution": kernel_solution, # interpolator + "p_test": p_test, + "p_benchmark": p_benchmark, + "p_rel_error": p_rel_error, + "alpha": alpha, + "p_0": float(p_0), + "rkhs_norms": rkhs_norms, + "train_residuals": {"asset_pricing": train_residual}, + "max_train_residual": max_train_residual, + "solve_time": solve_time, + "wall_time": elapsed, + "solver_status": solver_status, + "solution_status": solution_status, + "stationarity": result.solution_stationarity, + "primal_feasibility": result.solution_primal_feasibility, + "kernel_solution": kernel_solution, } diff --git a/figures_asset_pricing.py b/figures_asset_pricing.py index 845982e..4c1b690 100644 --- a/figures_asset_pricing.py +++ b/figures_asset_pricing.py @@ -1,133 +1,133 @@ -import jax.numpy as jnp -import matplotlib.pyplot as plt -import os -from asset_pricing_matern import asset_pricing_matern - -from mpl_toolkits.axes_grid1.inset_locator import ( - zoomed_inset_axes, - mark_inset, - inset_axes, -) - -fontsize = 17 -ticksize = 16 -figsize = (15, 7) -params = { - "font.family": "serif", - "figure.figsize": figsize, - "figure.dpi": 80, - "figure.edgecolor": "k", - "figure.constrained_layout.use": True, # Adjust layout to prevent overlap - "font.size": fontsize, - "axes.labelsize": fontsize, - "axes.titlesize": fontsize, - "xtick.labelsize": ticksize, - "ytick.labelsize": ticksize, -} -plt.rcParams.update(params) - - -## Plot given solution -def plot_asset_pricing( - sol_matern, - output_path, - p_rel_error_ylim=(1e-5, 2 * 1e-2), - zoom=True, - zoom_loc=[85, 95], -): - t = sol_matern["t_test"] - T = sol_matern["t_train"].max() - p_hat_matern = sol_matern["p_test"] - p_benchmark = sol_matern["p_benchmark"] - p_rel_error_matern = sol_matern["p_rel_error"] - - - # Plotting - plt.figure(figsize=(15, 7)) - - ax_prices = plt.subplot(1, 2, 1) - - plt.plot( - t, p_hat_matern, color="k", label=r"$\hat{\mu}(t)$: Kernel Approximation"#Mtérn - ) - plt.plot( - t, - p_benchmark, - linestyle="--", - color="k", - label=r"$\mu_f(t)$: Closed-Form Solution", - ) - plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") - - plt.ylabel(r"Price: $\mu(t)$") - plt.xlabel("Time") - plt.legend() # Show legend with labels - - ax_rel = plt.subplot(1, 2, 2) - - plt.plot( - t, - p_rel_error_matern, - color="k", - label=r"$\varepsilon_{\mu}(t)$: Relative Errors", - )#, Matérn Kernel Approx. - - plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") - plt.yscale("log") # Set y-scale to logarithmic - plt.ylim(p_rel_error_ylim[0], p_rel_error_ylim[1]) - plt.xlabel("Time") - plt.legend() # Show legend with labels - - # Zoom in part of the plot - if zoom == True: - time_window = ( - zoom_loc # Indices: The window on the x-axis that want to be zoomed in - ) - ave_value = 0.5 * ( - p_benchmark[time_window[0]] + p_benchmark[time_window[1]] - ) # The average on the y-axis that want to be zoomed in - window_width = 0.01 * ave_value - axins = zoomed_inset_axes( - ax_prices, - 3, - loc="center", - bbox_to_anchor=(0.5, 0.7, -0.3, -0.3), - bbox_transform=ax_prices.transAxes, - ) - - axins.plot( - t[time_window[0] - 1 : time_window[1] + 1], - p_hat_matern[time_window[0] - 1 : time_window[1] + 1], - color="k", - ) - - axins.plot( - t[time_window[0] - 1 : time_window[1] + 1], - p_benchmark[time_window[0] - 1 : time_window[1] + 1], - linestyle="--", - color="k", - ) - - x1, x2, y1, y2 = ( - t[time_window[0]], - t[time_window[1]], - ave_value - window_width, - ave_value + window_width, - ) - axins.set_xlim(x1, x2) - axins.set_ylim(y1, y2) - plt.xticks(fontsize=8, visible=False) - plt.tick_params( - axis="x", which="both", bottom=False, top=False, labelbottom=False - ) - plt.yticks(fontsize=8) - mark_inset(ax_prices, axins, loc1=1, loc2=3, linewidth="0.7", ls="--", ec="0.5") - - plt.savefig(output_path, format="pdf") - - -# Plots with various parameters -sol_matern = asset_pricing_matern() -plot_asset_pricing( - sol_matern, "figures/asset_pricing_contiguous.pdf" -) +import matplotlib.pyplot as plt +import jsonargparse +from asset_pricing_matern import asset_pricing_matern + +from mpl_toolkits.axes_grid1.inset_locator import ( + zoomed_inset_axes, + mark_inset, +) + +fontsize = 17 +ticksize = 16 +figsize = (15, 7) +params = { + "font.family": "serif", + "figure.figsize": figsize, + "figure.dpi": 80, + "figure.edgecolor": "k", + "figure.constrained_layout.use": True, # Adjust layout to prevent overlap + "font.size": fontsize, + "axes.labelsize": fontsize, + "axes.titlesize": fontsize, + "xtick.labelsize": ticksize, + "ytick.labelsize": ticksize, +} +plt.rcParams.update(params) + + +## Plot given solution +def plot_asset_pricing( + sol_matern, + output_path, + p_rel_error_ylim=(1e-5, 2 * 1e-2), + zoom=True, + zoom_loc=[85, 95], +): + t = sol_matern["t_test"] + T = sol_matern["t_train"].max() + p_hat_matern = sol_matern["p_test"] + p_benchmark = sol_matern["p_benchmark"] + p_rel_error_matern = sol_matern["p_rel_error"] + + + # Plotting + plt.figure(figsize=(15, 7)) + + ax_prices = plt.subplot(1, 2, 1) + + plt.plot( + t, p_hat_matern, color="k", label=r"$\hat{\mu}(t)$: Kernel Approximation"#Mtérn + ) + plt.plot( + t, + p_benchmark, + linestyle="--", + color="k", + label=r"$\mu_f(t)$: Closed-Form Solution", + ) + plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") + + plt.ylabel(r"Price: $\mu(t)$") + plt.xlabel("Time") + plt.legend() # Show legend with labels + + plt.subplot(1, 2, 2) + + plt.plot( + t, + p_rel_error_matern, + color="k", + label=r"$\varepsilon_{\mu}(t)$: Relative Errors", + )#, Matérn Kernel Approx. + + plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") + plt.yscale("log") # Set y-scale to logarithmic + plt.ylim(p_rel_error_ylim[0], p_rel_error_ylim[1]) + plt.xlabel("Time") + plt.legend() # Show legend with labels + + # Zoom in part of the plot + if zoom is True: + time_window = ( + zoom_loc # Indices: The window on the x-axis that want to be zoomed in + ) + ave_value = 0.5 * ( + p_benchmark[time_window[0]] + p_benchmark[time_window[1]] + ) # The average on the y-axis that want to be zoomed in + window_width = 0.01 * ave_value + axins = zoomed_inset_axes( + ax_prices, + 3, + loc="center", + bbox_to_anchor=(0.5, 0.7, -0.3, -0.3), + bbox_transform=ax_prices.transAxes, + ) + + axins.plot( + t[time_window[0] - 1 : time_window[1] + 1], + p_hat_matern[time_window[0] - 1 : time_window[1] + 1], + color="k", + ) + + axins.plot( + t[time_window[0] - 1 : time_window[1] + 1], + p_benchmark[time_window[0] - 1 : time_window[1] + 1], + linestyle="--", + color="k", + ) + + x1, x2, y1, y2 = ( + t[time_window[0]], + t[time_window[1]], + ave_value - window_width, + ave_value + window_width, + ) + axins.set_xlim(x1, x2) + axins.set_ylim(y1, y2) + plt.xticks(fontsize=8, visible=False) + plt.tick_params( + axis="x", which="both", bottom=False, top=False, labelbottom=False + ) + plt.yticks(fontsize=8) + mark_inset(ax_prices, axins, loc1=1, loc2=3, linewidth="0.7", ls="--", ec="0.5") + + plt.savefig(output_path, format="pdf") + + +def main(): + sol_matern = asset_pricing_matern() + plot_asset_pricing(sol_matern, "figures/asset_pricing_contiguous.pdf") + + +if __name__ == "__main__": + jsonargparse.CLI(main) diff --git a/figures_neoclassical_growth_baseline.py b/figures_neoclassical_growth_baseline.py index 9436213..8508255 100644 --- a/figures_neoclassical_growth_baseline.py +++ b/figures_neoclassical_growth_baseline.py @@ -1,189 +1,197 @@ -import jax.numpy as jnp -import matplotlib.pyplot as plt -import os -from neoclassical_growth_matern import neoclassical_growth_matern - -from mpl_toolkits.axes_grid1.inset_locator import ( - zoomed_inset_axes, - mark_inset, - inset_axes, -) - -fontsize = 17 -ticksize = 16 -figsize = (15, 10) -params = { - "font.family": "serif", - "figure.figsize": figsize, - "figure.dpi": 80, - "figure.edgecolor": "k", - "figure.constrained_layout.use": True, # Adjust layout to prevent overlap - "font.size": fontsize, - "axes.labelsize": fontsize, - "axes.titlesize": fontsize, - "xtick.labelsize": ticksize, - "ytick.labelsize": ticksize, -} -plt.rcParams.update(params) - - -## Plot given solution - -sol_matern = neoclassical_growth_matern() -output_path = "figures/neoclassical_growth_model_baseline.pdf" - -zoom = True -zoom_loc = [90, 99] - -t = sol_matern["t_test"] -T = sol_matern["t_train"].max() -c_hat_matern = sol_matern["c_test"] -k_hat_matern = sol_matern["k_test"] -c_benchmark = sol_matern["c_benchmark"] -k_benchmark = sol_matern["k_benchmark"] -k_rel_error_matern = sol_matern["k_rel_error"] -c_rel_error_matern = sol_matern["c_rel_error"] - -# Plotting -plt.figure(figsize=(15, 10)) - -ax_capital = plt.subplot(2, 2, 1) - -plt.plot(t, k_hat_matern, color="k", label=r"$\hat{x}(t)$: Kernel Approximation")# Matérn -plt.plot(t, k_benchmark, linestyle="--", color="k", label=r"$x(t)$: Benchmark Solution") -plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") - -plt.ylabel("Capital: $x(t)$") -plt.xlabel("Time") -plt.legend() # Show legend with labels - - -ax_rel_k = plt.subplot(2, 2, 2) -k_rel_error_ylim = (1e-6, 2 * 1e-2) - -plt.plot( - t, - k_rel_error_matern, - color="k", - label=r"$\varepsilon_x(t)$: Relative Errors for $x(t)$", -) -plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") -plt.yscale("log") # Set y-scale to logarithmic -plt.ylim(k_rel_error_ylim[0], k_rel_error_ylim[1]) -plt.xlabel("Time") -plt.legend() - -ax_consumption = plt.subplot(2, 2, 3) -c_rel_error_ylim = (1e-7, 2 * 1e-2) - -plt.plot(t, c_hat_matern, color="b", label=r"$\hat{y}(t)$: Kernel Approximation") #Matérn -plt.plot(t, c_benchmark, linestyle="--", color="b", label=r"$y(t)$: Benchmark Solution") -plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") - -plt.ylabel("Consumption: $y(t)$") -plt.xlabel("Time") -plt.legend() # Show legend with labels - -ax_rel_c = plt.subplot(2, 2, 4) - -plt.plot( - t, - c_rel_error_matern, - color="b", - label=r"$\varepsilon_y(t)$: Reletaive Errors for $y(t)$", -) - -plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") -plt.yscale("log") # Set y-scale to logarithmic -plt.ylim(c_rel_error_ylim[0], c_rel_error_ylim[1]) -plt.xlabel("Time") -plt.legend() # Show legend with labels - - - -# Zoom in part of the plot -if zoom == True: - time_window = ( - zoom_loc # Indices: The window on the x-axis that want to be zoomed in - ) - ave_value = 0.5 * ( - k_benchmark[time_window[0]] + k_benchmark[time_window[1]] - ) # The average on the y-axis that want to be zoomed in - window_width = 0.01 * ave_value - axins = zoomed_inset_axes( - ax_capital, - 3, - loc="center", - bbox_to_anchor=(0.5, 0.7, -0.3, -0.3), - bbox_transform=ax_capital.transAxes, - ) - - axins.plot( - t[time_window[0] - 1 : time_window[1] + 1], - k_hat_matern[time_window[0] - 1 : time_window[1] + 1], - color="k", - ) - - axins.plot( - t[time_window[0] - 1 : time_window[1] + 1], - k_benchmark[time_window[0] - 1 : time_window[1] + 1], - linestyle="--", - color="k", - ) - - x1, x2, y1, y2 = ( - t[time_window[0]], - t[time_window[1]], - ave_value - window_width, - ave_value + window_width, - ) - axins.set_xlim(x1, x2) - axins.set_ylim(y1, y2) - plt.xticks(fontsize=8, visible=False) - plt.tick_params(axis="x", which="both", bottom=False, top=False, labelbottom=False) - plt.yticks(fontsize=8) - mark_inset(ax_capital, axins, loc1=1, loc2=3, linewidth="0.7", ls="--", ec="0.5") - - time_window = ( - zoom_loc # Indices: The window on the x-axis that want to be zoomed in - ) - ave_value = 0.5 * ( - c_benchmark[time_window[0]] + c_benchmark[time_window[1]] - ) # The average on the y-axis that want to be zoomed in - window_width = 0.01 * ave_value - axins = zoomed_inset_axes( - ax_consumption, - 3, - loc="center", - bbox_to_anchor=(0.5, 0.7, -0.3, -0.3), - bbox_transform=ax_consumption.transAxes, - ) - - axins.plot( - t[time_window[0] - 1 : time_window[1] + 1], - c_hat_matern[time_window[0] - 1 : time_window[1] + 1], - color="b", - ) - - axins.plot( - t[time_window[0] - 1 : time_window[1] + 1], - c_benchmark[time_window[0] - 1 : time_window[1] + 1], - linestyle="--", - color="b", - ) - - x1, x2, y1, y2 = ( - t[time_window[0]], - t[time_window[1]], - ave_value - window_width, - ave_value + window_width, - ) - axins.set_xlim(x1, x2) - axins.set_ylim(y1, y2) - plt.xticks(fontsize=8, visible=False) - plt.tick_params(axis="x", which="both", bottom=False, top=False, labelbottom=False) - plt.yticks(fontsize=8) - mark_inset( - ax_consumption, axins, loc1=1, loc2=3, linewidth="0.7", ls="--", ec="0.5" - ) -plt.savefig(output_path, format="pdf") +import matplotlib.pyplot as plt +import jsonargparse +from neoclassical_growth_matern import neoclassical_growth_matern + +from mpl_toolkits.axes_grid1.inset_locator import ( + zoomed_inset_axes, + mark_inset, +) + +fontsize = 17 +ticksize = 16 +figsize = (15, 10) +params = { + "font.family": "serif", + "figure.figsize": figsize, + "figure.dpi": 80, + "figure.edgecolor": "k", + "figure.constrained_layout.use": True, # Adjust layout to prevent overlap + "font.size": fontsize, + "axes.labelsize": fontsize, + "axes.titlesize": fontsize, + "xtick.labelsize": ticksize, + "ytick.labelsize": ticksize, +} +plt.rcParams.update(params) + + +## Plot given solution +def plot_neoclassical_growth_baseline( + sol_matern, + output_path, + zoom=True, + zoom_loc=[90, 99], +): + t = sol_matern["t_test"] + T = sol_matern["t_train"].max() + c_hat_matern = sol_matern["c_test"] + k_hat_matern = sol_matern["k_test"] + c_benchmark = sol_matern["c_benchmark"] + k_benchmark = sol_matern["k_benchmark"] + k_rel_error_matern = sol_matern["k_rel_error"] + c_rel_error_matern = sol_matern["c_rel_error"] + + # Plotting + plt.figure(figsize=(15, 10)) + + ax_capital = plt.subplot(2, 2, 1) + + plt.plot(t, k_hat_matern, color="k", label=r"$\hat{x}(t)$: Kernel Approximation")# Matérn + plt.plot(t, k_benchmark, linestyle="--", color="k", label=r"$x(t)$: Benchmark Solution") + plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") + + plt.ylabel("Capital: $x(t)$") + plt.xlabel("Time") + plt.legend() # Show legend with labels + + + plt.subplot(2, 2, 2) + k_rel_error_ylim = (1e-6, 2 * 1e-2) + + plt.plot( + t, + k_rel_error_matern, + color="k", + label=r"$\varepsilon_x(t)$: Relative Errors for $x(t)$", + ) + plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") + plt.yscale("log") # Set y-scale to logarithmic + plt.ylim(k_rel_error_ylim[0], k_rel_error_ylim[1]) + plt.xlabel("Time") + plt.legend() + + ax_consumption = plt.subplot(2, 2, 3) + c_rel_error_ylim = (1e-7, 2 * 1e-2) + + plt.plot(t, c_hat_matern, color="b", label=r"$\hat{y}(t)$: Kernel Approximation") #Matérn + plt.plot(t, c_benchmark, linestyle="--", color="b", label=r"$y(t)$: Benchmark Solution") + plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") + + plt.ylabel("Consumption: $y(t)$") + plt.xlabel("Time") + plt.legend() # Show legend with labels + + plt.subplot(2, 2, 4) + + plt.plot( + t, + c_rel_error_matern, + color="b", + label=r"$\varepsilon_y(t)$: Reletaive Errors for $y(t)$", + ) + + plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") + plt.yscale("log") # Set y-scale to logarithmic + plt.ylim(c_rel_error_ylim[0], c_rel_error_ylim[1]) + plt.xlabel("Time") + plt.legend() # Show legend with labels + + + + # Zoom in part of the plot + if zoom is True: + time_window = ( + zoom_loc # Indices: The window on the x-axis that want to be zoomed in + ) + ave_value = 0.5 * ( + k_benchmark[time_window[0]] + k_benchmark[time_window[1]] + ) # The average on the y-axis that want to be zoomed in + window_width = 0.01 * ave_value + axins = zoomed_inset_axes( + ax_capital, + 3, + loc="center", + bbox_to_anchor=(0.5, 0.7, -0.3, -0.3), + bbox_transform=ax_capital.transAxes, + ) + + axins.plot( + t[time_window[0] - 1 : time_window[1] + 1], + k_hat_matern[time_window[0] - 1 : time_window[1] + 1], + color="k", + ) + + axins.plot( + t[time_window[0] - 1 : time_window[1] + 1], + k_benchmark[time_window[0] - 1 : time_window[1] + 1], + linestyle="--", + color="k", + ) + + x1, x2, y1, y2 = ( + t[time_window[0]], + t[time_window[1]], + ave_value - window_width, + ave_value + window_width, + ) + axins.set_xlim(x1, x2) + axins.set_ylim(y1, y2) + plt.xticks(fontsize=8, visible=False) + plt.tick_params(axis="x", which="both", bottom=False, top=False, labelbottom=False) + plt.yticks(fontsize=8) + mark_inset(ax_capital, axins, loc1=1, loc2=3, linewidth="0.7", ls="--", ec="0.5") + + time_window = ( + zoom_loc # Indices: The window on the x-axis that want to be zoomed in + ) + ave_value = 0.5 * ( + c_benchmark[time_window[0]] + c_benchmark[time_window[1]] + ) # The average on the y-axis that want to be zoomed in + window_width = 0.01 * ave_value + axins = zoomed_inset_axes( + ax_consumption, + 3, + loc="center", + bbox_to_anchor=(0.5, 0.7, -0.3, -0.3), + bbox_transform=ax_consumption.transAxes, + ) + + axins.plot( + t[time_window[0] - 1 : time_window[1] + 1], + c_hat_matern[time_window[0] - 1 : time_window[1] + 1], + color="b", + ) + + axins.plot( + t[time_window[0] - 1 : time_window[1] + 1], + c_benchmark[time_window[0] - 1 : time_window[1] + 1], + linestyle="--", + color="b", + ) + + x1, x2, y1, y2 = ( + t[time_window[0]], + t[time_window[1]], + ave_value - window_width, + ave_value + window_width, + ) + axins.set_xlim(x1, x2) + axins.set_ylim(y1, y2) + plt.xticks(fontsize=8, visible=False) + plt.tick_params(axis="x", which="both", bottom=False, top=False, labelbottom=False) + plt.yticks(fontsize=8) + mark_inset( + ax_consumption, axins, loc1=1, loc2=3, linewidth="0.7", ls="--", ec="0.5" + ) + plt.savefig(output_path, format="pdf") + + +def main(): + sol_matern = neoclassical_growth_matern() + plot_neoclassical_growth_baseline( + sol_matern, "figures/neoclassical_growth_model_baseline.pdf" + ) + + +if __name__ == "__main__": + jsonargparse.CLI(main) diff --git a/figures_neoclassical_growth_concave_convex.py b/figures_neoclassical_growth_concave_convex.py index c26eaaa..72eb0c1 100644 --- a/figures_neoclassical_growth_concave_convex.py +++ b/figures_neoclassical_growth_concave_convex.py @@ -1,128 +1,232 @@ -import jax.numpy as jnp -import matplotlib.pyplot as plt -import numpy as np -import os -from neoclassical_growth_concave_convex_matern import neoclassical_growth_concave_convex_matern - -from mpl_toolkits.axes_grid1.inset_locator import ( - zoomed_inset_axes, - mark_inset, - inset_axes, -) - -fontsize = 17 -ticksize = 16 -figsize = (15, 7) -params = { - "font.family": "serif", - "figure.figsize": figsize, - "figure.dpi": 80, - "figure.edgecolor": "k", - "figure.constrained_layout.use": True, # Adjust layout to prevent overlap - "font.size": fontsize, - "axes.labelsize": fontsize, - "axes.titlesize": fontsize, - "xtick.labelsize": ticksize, - "ytick.labelsize": ticksize, -} -plt.rcParams.update(params) - - -## Plots for concave-convex production function -sol_1 = neoclassical_growth_concave_convex_matern(k_0=0.5, train_points=20) -sol_2 = neoclassical_growth_concave_convex_matern(k_0=1.0, train_points=20) -sol_3 = neoclassical_growth_concave_convex_matern(k_0=3.0, train_points=20) -sol_4 = neoclassical_growth_concave_convex_matern(k_0=4.0, train_points=20) -output_path = "figures/neoclassical_growth_model_concave_convex.pdf" - -plt.figure(figsize=(15, 8)) - -k_hat_1 = sol_1["k_test"] -k_hat_2 = sol_2["k_test"] -k_hat_3 = sol_3["k_test"] -k_hat_4 = sol_4["k_test"] - -c_hat_1 = sol_1["c_test"] -c_hat_2 = sol_2["c_test"] -c_hat_3 = sol_3["c_test"] -c_hat_4 = sol_4["c_test"] - -T = sol_1["t_train"].max() -t = sol_1["t_test"] - -ax_capital = plt.subplot(1, 2, 1) -plt.plot(t, k_hat_1, color="b", label=r"$\hat{x}(t): x_0 = 0.5$") -plt.plot(t, k_hat_2, color="gray", label=r"$\hat{x}(t): x_0 = 1$") -plt.plot(t, k_hat_3, color="r", label=r"$\hat{x}(t): x_0 = 3$") -plt.plot(t, k_hat_4, color="c", label=r"$\hat{x}(t): x_0 = 4$") -# plt.axhline(y=sol_1["k_ss_low"], linestyle="-.", color="k", label=r"$x_1^*$: Steady-State") -# plt.axhline(y=sol_1["k_ss_high"], linestyle="dashed", color="k", label=r"$x_2^*$: Steady-State") -plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") -plt.ylabel("Capital: $x(t)$") -plt.xlabel("Time") -plt.legend() # Show legend with labels - -ax_consumption = plt.subplot(1, 2, 2) -plt.plot(t, c_hat_1, color="b", label=r"$\hat{y}(t): x_0 = 0.5$") -plt.plot(t, c_hat_2, color="gray", label=r"$\hat{y}(t): x_0 = 1$") -plt.plot(t, c_hat_3, color="r", label=r"$\hat{y}(t): x_0 = 3$") -plt.plot(t, c_hat_4, color="c", label=r"$\hat{y}(t): x_0 = 4$") -# plt.axhline(y=sol_1["c_ss_low"], linestyle="-.", color="k", label=r"$y_1^*$: Steady-State") -# plt.axhline(y=sol_1["c_ss_high"], linestyle="dashed", color="k", label=r"$y_2^*$: Steady-State") -plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") -plt.ylabel("Consumption: $y(t)$") -plt.xlabel("Time") -plt.legend() # Show legend with labels - -#plt.savefig(output_path, format="pdf") - - -sols = [ - neoclassical_growth_concave_convex_matern(k_0=k_0, train_points=20) - for k_0 in np.linspace(0.5, 4.0, 70) -] - -output_path = "figures/neoclassical_growth_model_concave_convex_threshold.pdf" - -plt.figure(figsize=(15,8)) - -T = sols[0]["t_train"].max() -t = sols[0]["t_test"] - -ax_capital = plt.subplot(1, 2, 1) -for sol in sols: - plt.plot(t, sol["k_test"], color="gray") - -# plt.axhline( -# y=sols[0]["k_ss_low"], linestyle="-.", color="k", label=r"$k_1^*$: Steady-State" -# ) -# plt.axhline( -# y=sols[0]["k_ss_high"], -# linestyle="dashed", -# color="k", -# label=r"$k_2^*$: Steady-State", -# ) -plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") -plt.ylabel("Capital: $x(t)$") -plt.xlabel("Time") -plt.legend() # Show legend with labels - -ax_consumption = plt.subplot(1, 2, 2) -for sol in sols: - plt.plot(t, sol["c_test"], color="b") - -# plt.axhline( -# y=sols[0]["c_ss_low"], linestyle="-.", color="k", label=r"$c_1^*$: Steady-State" -# ) -# plt.axhline( -# y=sols[0]["c_ss_high"], -# linestyle="dashed", -# color="k", -# label=r"$c_2^*$: Steady-State", -# ) -plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") -plt.ylabel("Consumption: $y(t)$") -plt.xlabel("Time") -plt.legend() # Show legend with labels - -plt.savefig(output_path, format="pdf") +import jax.numpy as jnp +import matplotlib.pyplot as plt +import numpy as np +import json +import jsonargparse +import subprocess +import sys +from neoclassical_growth_concave_convex_matern import neoclassical_growth_concave_convex_matern + +fontsize = 17 +ticksize = 16 +figsize = (15, 7) +params = { + "font.family": "serif", + "figure.figsize": figsize, + "figure.dpi": 80, + "figure.edgecolor": "k", + "figure.constrained_layout.use": True, # Adjust layout to prevent overlap + "font.size": fontsize, + "axes.labelsize": fontsize, + "axes.titlesize": fontsize, + "xtick.labelsize": ticksize, + "ytick.labelsize": ticksize, +} +plt.rcParams.update(params) + +ARRAY_PAYLOAD_KEYS = {"t_train", "t_test", "k_test", "c_test"} + + +def parse_threshold_payload(stdout: str): + for line in reversed(stdout.splitlines()): + try: + payload = json.loads(line) + except json.JSONDecodeError: + continue + parsed = [] + for item in payload: + parsed.append( + { + key: jnp.asarray(value) if key in ARRAY_PAYLOAD_KEYS else value + for key, value in item.items() + } + ) + return parsed + return [] + + +def solve_threshold_points(k_0_values, timeout_seconds: float): + code = """ +import json +import sys + +import numpy as np + +from neoclassical_growth_concave_convex_matern import neoclassical_growth_concave_convex_matern + +payload = [] +for raw_k_0 in sys.argv[1:]: + k_0 = float(raw_k_0) + try: + sol = neoclassical_growth_concave_convex_matern(k_0=k_0, train_points=41) + except Exception as exc: + payload.append({ + "k_0": k_0, + "valid_solution": False, + "rejection_reason": f"exception:{type(exc).__name__}", + "candidate_branch": "none", + }) + continue + payload.append({ + "k_0": k_0, + "valid_solution": bool(sol["valid_solution"]), + "rejection_reason": sol["rejection_reason"], + "candidate_branch": sol["candidate_branch"], + "max_helper_residual": float(sol["max_helper_residual"]), + "max_train_residual": float(sol["max_train_residual"]), + "max_validation_residual": float(sol["max_validation_residual"]), + "p_lower_violation": float(sol["p_lower_violation"]), + "p_upper_violation": float(sol["p_upper_violation"]), + "t_train": np.asarray(sol["t_train"]).tolist(), + "t_test": np.asarray(sol["t_test"]).tolist(), + "k_test": np.asarray(sol["k_test"]).tolist(), + "c_test": np.asarray(sol["c_test"]).tolist(), + }) +print(json.dumps(payload)) +""" + try: + result = subprocess.run( + [sys.executable, "-c", code, *[str(float(k_0)) for k_0 in k_0_values]], + check=False, + capture_output=True, + text=True, + timeout=timeout_seconds, + ) + except subprocess.TimeoutExpired: + return [] + if result.returncode != 0: + return [] + + return parse_threshold_payload(result.stdout) + + +def solve_threshold_group(k_0_values): + sols = solve_threshold_points(k_0_values, timeout_seconds=8.0) + if len(sols) == len(k_0_values): + return sols + + fallback = [] + for k_0 in k_0_values: + fallback.extend(solve_threshold_points([k_0], timeout_seconds=5.0)) + return fallback + + +def main(): + sol_1 = neoclassical_growth_concave_convex_matern(k_0=0.5, train_points=41) + sol_2 = neoclassical_growth_concave_convex_matern(k_0=1.0, train_points=41) + sol_3 = neoclassical_growth_concave_convex_matern(k_0=3.0, train_points=41) + sol_4 = neoclassical_growth_concave_convex_matern(k_0=4.0, train_points=41) + for sol in (sol_1, sol_2, sol_3, sol_4): + if not sol["valid_solution"]: + raise RuntimeError( + f"Invalid core concave-convex solve: {sol['rejection_reason']}" + ) + output_path = "figures/neoclassical_growth_model_concave_convex.pdf" + + plt.figure(figsize=(15, 8)) + + k_hat_1 = sol_1["k_test"] + k_hat_2 = sol_2["k_test"] + k_hat_3 = sol_3["k_test"] + k_hat_4 = sol_4["k_test"] + + c_hat_1 = sol_1["c_test"] + c_hat_2 = sol_2["c_test"] + c_hat_3 = sol_3["c_test"] + c_hat_4 = sol_4["c_test"] + + T = sol_1["t_train"].max() + t = sol_1["t_test"] + + plt.subplot(1, 2, 1) + plt.plot(t, k_hat_1, color="b", label=r"$\hat{x}(t): x_0 = 0.5$") + plt.plot(t, k_hat_2, color="gray", label=r"$\hat{x}(t): x_0 = 1$") + plt.plot(t, k_hat_3, color="r", label=r"$\hat{x}(t): x_0 = 3$") + plt.plot(t, k_hat_4, color="c", label=r"$\hat{x}(t): x_0 = 4$") + plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") + plt.ylabel("Capital: $x(t)$") + plt.xlabel("Time") + plt.legend() # Show legend with labels + + plt.subplot(1, 2, 2) + plt.plot(t, c_hat_1, color="b", label=r"$\hat{y}(t): x_0 = 0.5$") + plt.plot(t, c_hat_2, color="gray", label=r"$\hat{y}(t): x_0 = 1$") + plt.plot(t, c_hat_3, color="r", label=r"$\hat{y}(t): x_0 = 3$") + plt.plot(t, c_hat_4, color="c", label=r"$\hat{y}(t): x_0 = 4$") + plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") + plt.ylabel("Consumption: $y(t)$") + plt.xlabel("Time") + plt.legend() # Show legend with labels + + plt.savefig(output_path, format="pdf") + + # Sweep x_0 across the initial-condition range, skipping failed solves. + sols = [] + rejected = [] + threshold_grid = np.linspace(0.5, 4.0, 40) + for i in range(0, len(threshold_grid), 8): + group = threshold_grid[i : i + 8] + group_sols = solve_threshold_group(group) + seen = set() + for sol in group_sols: + seen.add(round(float(sol["k_0"]), 12)) + if not sol.get("valid_solution", False): + rejected.append(sol) + continue + k = np.asarray(sol["k_test"]) + c = np.asarray(sol["c_test"]) + if ( + np.all(np.isfinite(k)) + and np.all(np.isfinite(c)) + and k.min() > 0 + and c.min() > 0 + and k.max() < 10 + ): + sols.append(sol) + else: + rejected.append(sol) + for k_0 in group: + if round(float(k_0), 12) not in seen: + rejected.append({ + "k_0": float(k_0), + "valid_solution": False, + "rejection_reason": "timeout_or_missing_payload", + "candidate_branch": "none", + }) + + if not sols: + raise RuntimeError("No finite concave-convex threshold trajectories solved.") + print( + f"concave-convex threshold accepted={len(sols)} rejected={len(rejected)}" + ) + + output_path = "figures/neoclassical_growth_model_concave_convex_threshold.pdf" + + plt.figure(figsize=(15,8)) + + T = sols[0]["t_train"].max() + t = sols[0]["t_test"] + + plt.subplot(1, 2, 1) + for sol in sols: + plt.plot(t, sol["k_test"], color="gray") + + plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") + plt.ylabel("Capital: $x(t)$") + plt.xlabel("Time") + plt.legend() # Show legend with labels + + plt.subplot(1, 2, 2) + for sol in sols: + plt.plot(t, sol["c_test"], color="b") + + plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") + plt.ylabel("Consumption: $y(t)$") + plt.xlabel("Time") + plt.legend() # Show legend with labels + + plt.savefig(output_path, format="pdf") + + +if __name__ == "__main__": + jsonargparse.CLI(main) diff --git a/figures_neoclassical_growth_robustness.py b/figures_neoclassical_growth_robustness.py index b6f8974..a07376e 100644 --- a/figures_neoclassical_growth_robustness.py +++ b/figures_neoclassical_growth_robustness.py @@ -1,258 +1,273 @@ -import jax.numpy as jnp -import matplotlib.pyplot as plt -import os -from neoclassical_growth_matern import neoclassical_growth_matern - -from mpl_toolkits.axes_grid1.inset_locator import ( - zoomed_inset_axes, - mark_inset, - inset_axes, -) - -fontsize = 14 -ticksize = 14 -figsize = (15, 10) -params = { - "font.family": "serif", - "figure.figsize": figsize, - "figure.dpi": 80, - "figure.edgecolor": "k", - "font.size": fontsize, - "axes.labelsize": fontsize, - "axes.titlesize": fontsize, - "xtick.labelsize": ticksize, - "ytick.labelsize": ticksize, -} -plt.rcParams.update(params) - - -## Plot given solution -def plot_neoclassical_growth( - sol, - output_path, - k_rel_error_ylim=(1e-6, 2 * 1e-2), - c_rel_error_ylim=(1e-6, 2 * 1e-2), - zoom=True, - zoom_loc=[50, 60], -): - t = sol["t_test"] - T = sol["t_train"].max() - c_hat = sol["c_test"] - k_hat = sol["k_test"] - c_benchmark = sol["c_benchmark"] - k_benchmark = sol["k_benchmark"] - k_rel_error = sol["k_rel_error"] - c_rel_error = sol["c_rel_error"] - # Plotting - plt.figure(figsize=(15, 10)) - - ax_capital = plt.subplot(2, 2, 1) - - plt.plot(t, k_hat, color="k", label=r"$\hat{x}(t)$: Kernel Approximation") #Matérn - plt.plot( - t, k_benchmark, linestyle="--", color="k", label=r"$x(t)$: Benchmark Solution" - ) - plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") - - plt.ylabel("Capital: $x(t)$") - plt.xlabel("Time") - plt.legend() # Show legend with labels - - ax_rel_k = plt.subplot(2, 2, 2) - - plt.plot( - t, - k_rel_error, - color="k", - label=r"$\varepsilon_x(t)$: Relative Errors for $x(t)$", - ) - plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") - plt.yscale("log") # Set y-scale to logarithmic - plt.ylim(k_rel_error_ylim[0], k_rel_error_ylim[1]) - plt.xlabel("Time") - plt.legend() # Show legend with labels - - ax_consumption = plt.subplot(2, 2, 3) - - plt.plot(t, c_hat, color="b", label=r"$\hat{y}(t)$: Kernel Approximation") #Matérn - plt.plot( - t, c_benchmark, linestyle="--", color="b", label=r"$y(t)$: Benchmark Solution" - ) - plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") - - plt.ylabel("Consumption: $y(t)$") - plt.xlabel("Time") - plt.legend() # Show legend with labels - - ax_rel_c = plt.subplot(2, 2, 4) - - plt.plot( - t, - c_rel_error, - color="b", - label=r"$\varepsilon_y(t)$: Reletaive Errors for $y(t)$", - ) - plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") - plt.yscale("log") # Set y-scale to logarithmic - plt.ylim(c_rel_error_ylim[0], c_rel_error_ylim[1]) - plt.xlabel("Time") - plt.legend() # Show legend with labels - - plt.tight_layout() # Adjust layout to prevent overlap - - # Zoom in part of the plot - if zoom == True: - time_window = ( - zoom_loc # Indices: The window on the x-axis that want to be zoomed in - ) - ave_value = 0.5 * ( - k_benchmark[time_window[0]] + k_benchmark[time_window[1]] - ) # The average on the y-axis that want to be zoomed in - window_width = 0.01 * ave_value - axins = zoomed_inset_axes( - ax_capital, - 3, - loc="center", - bbox_to_anchor=(0.5, 0.7, -0.3, -0.3), - bbox_transform=ax_capital.transAxes, - ) - - axins.plot( - t[time_window[0] - 1 : time_window[1] + 1], - k_hat[time_window[0] - 1 : time_window[1] + 1], - color="k", - ) - axins.plot( - t[time_window[0] - 1 : time_window[1] + 1], - k_benchmark[time_window[0] - 1 : time_window[1] + 1], - linestyle="--", - color="k", - ) - - x1, x2, y1, y2 = ( - t[time_window[0]], - t[time_window[1]], - ave_value - window_width, - ave_value + window_width, - ) - axins.set_xlim(x1, x2) - axins.set_ylim(y1, y2) - plt.xticks(fontsize=8, visible=False) - plt.tick_params( - axis="x", which="both", bottom=False, top=False, labelbottom=False - ) - plt.yticks(fontsize=8) - mark_inset( - ax_capital, axins, loc1=1, loc2=3, linewidth="0.7", ls="--", ec="0.5" - ) - - time_window = ( - zoom_loc # Indices: The window on the x-axis that want to be zoomed in - ) - ave_value = 0.5 * ( - c_benchmark[time_window[0]] + c_benchmark[time_window[1]] - ) # The average on the y-axis that want to be zoomed in - window_width = 0.01 * ave_value - axins = zoomed_inset_axes( - ax_consumption, - 3, - loc="center", - bbox_to_anchor=(0.5, 0.7, -0.3, -0.3), - bbox_transform=ax_consumption.transAxes, - ) - - axins.plot( - t[time_window[0] - 1 : time_window[1] + 1], - c_hat[time_window[0] - 1 : time_window[1] + 1], - color="b", - ) - axins.plot( - t[time_window[0] - 1 : time_window[1] + 1], - c_benchmark[time_window[0] - 1 : time_window[1] + 1], - linestyle="--", - color="b", - ) - - x1, x2, y1, y2 = ( - t[time_window[0]], - t[time_window[1]], - ave_value - window_width, - ave_value + window_width, - ) - axins.set_xlim(x1, x2) - axins.set_ylim(y1, y2) - plt.xticks(fontsize=8, visible=False) - plt.tick_params( - axis="x", which="both", bottom=False, top=False, labelbottom=False - ) - plt.yticks(fontsize=8) - mark_inset( - ax_consumption, axins, loc1=1, loc2=3, linewidth="0.7", ls="--", ec="0.5" - ) - plt.savefig(output_path, format="pdf") - - -# Plots with various parameters -sol = neoclassical_growth_matern( - train_points_list=[0.0, 1.0, 3.0, 5.0, 10.0, 15.0, 20.0, 25.0, 30.0, 35.0, 38.0, 40.0], lambda_p = 1e-6 -) -plot_neoclassical_growth( - sol, - "figures/neoclassical_growth_model_sparse.pdf", - c_rel_error_ylim=(1e-7, 2 * 1e-2), - zoom=True, - zoom_loc=[10, 20], -) - -sol = neoclassical_growth_matern(train_T=10.0, train_points=11, test_T=15.0) -plot_neoclassical_growth( - sol, - "figures/neoclassical_growth_model_far_steady_state.pdf", - k_rel_error_ylim=(1e-4, 1e-1), - c_rel_error_ylim=(1e-4, 1e-1), - zoom=False, -) -''' -sol = neoclassical_growth_matern(nu=1.5) -plot_neoclassical_growth( - sol, - "figures/neoclassical_growth_model_nu_1_5.pdf", - k_rel_error_ylim=(1e-7, 1e-2), - c_rel_error_ylim=(1e-7, 1e-2), - zoom=True, - zoom_loc=[75, 85], -) - - -sol = neoclassical_growth_matern(nu=2.5) -plot_neoclassical_growth( - sol, - "figures/neoclassical_growth_model_nu_2_5.pdf", - k_rel_error_ylim=(1e-7, 1e-2), - c_rel_error_ylim=(1e-8, 1e-2), - zoom=True, - zoom_loc=[75, 85], -) - - -sol = neoclassical_growth_matern(rho=2) -plot_neoclassical_growth( - sol, - "figures/neoclassical_growth_model_rho_2.pdf", - k_rel_error_ylim=(1e-7, 1e-2), - c_rel_error_ylim=(1e-7, 1e-2), - zoom=True, - zoom_loc=[75, 85], -) - - -sol = neoclassical_growth_matern(rho=20) -plot_neoclassical_growth( - sol, - "figures/neoclassical_growth_model_rho_20.pdf", - k_rel_error_ylim=(1e-7, 1e-2), - c_rel_error_ylim=(1e-7, 1e-2), - zoom=True, - zoom_loc=[75, 85], -) -''' +import matplotlib.pyplot as plt +import jsonargparse +from neoclassical_growth_matern import neoclassical_growth_matern + +from mpl_toolkits.axes_grid1.inset_locator import ( + zoomed_inset_axes, + mark_inset, +) + +fontsize = 14 +ticksize = 14 +figsize = (15, 10) +params = { + "font.family": "serif", + "figure.figsize": figsize, + "figure.dpi": 80, + "figure.edgecolor": "k", + "font.size": fontsize, + "axes.labelsize": fontsize, + "axes.titlesize": fontsize, + "xtick.labelsize": ticksize, + "ytick.labelsize": ticksize, +} +plt.rcParams.update(params) + + +## Plot given solution +def plot_neoclassical_growth( + sol, + output_path, + k_rel_error_ylim=(1e-6, 2 * 1e-2), + c_rel_error_ylim=(1e-6, 2 * 1e-2), + zoom=True, + zoom_loc=[50, 60], +): + t = sol["t_test"] + T = sol["t_train"].max() + c_hat = sol["c_test"] + k_hat = sol["k_test"] + c_benchmark = sol["c_benchmark"] + k_benchmark = sol["k_benchmark"] + k_rel_error = sol["k_rel_error"] + c_rel_error = sol["c_rel_error"] + # Plotting + plt.figure(figsize=(15, 10)) + + ax_capital = plt.subplot(2, 2, 1) + + plt.plot(t, k_hat, color="k", label=r"$\hat{x}(t)$: Kernel Approximation") #Matérn + plt.plot( + t, k_benchmark, linestyle="--", color="k", label=r"$x(t)$: Benchmark Solution" + ) + plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") + + plt.ylabel("Capital: $x(t)$") + plt.xlabel("Time") + plt.legend() # Show legend with labels + + plt.subplot(2, 2, 2) + + plt.plot( + t, + k_rel_error, + color="k", + label=r"$\varepsilon_x(t)$: Relative Errors for $x(t)$", + ) + plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") + plt.yscale("log") # Set y-scale to logarithmic + plt.ylim(k_rel_error_ylim[0], k_rel_error_ylim[1]) + plt.xlabel("Time") + plt.legend() # Show legend with labels + + ax_consumption = plt.subplot(2, 2, 3) + + plt.plot(t, c_hat, color="b", label=r"$\hat{y}(t)$: Kernel Approximation") #Matérn + plt.plot( + t, c_benchmark, linestyle="--", color="b", label=r"$y(t)$: Benchmark Solution" + ) + plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") + + plt.ylabel("Consumption: $y(t)$") + plt.xlabel("Time") + plt.legend() # Show legend with labels + + plt.subplot(2, 2, 4) + + plt.plot( + t, + c_rel_error, + color="b", + label=r"$\varepsilon_y(t)$: Reletaive Errors for $y(t)$", + ) + plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") + plt.yscale("log") # Set y-scale to logarithmic + plt.ylim(c_rel_error_ylim[0], c_rel_error_ylim[1]) + plt.xlabel("Time") + plt.legend() # Show legend with labels + + plt.tight_layout() # Adjust layout to prevent overlap + + # Zoom in part of the plot + if zoom is True: + time_window = ( + zoom_loc # Indices: The window on the x-axis that want to be zoomed in + ) + ave_value = 0.5 * ( + k_benchmark[time_window[0]] + k_benchmark[time_window[1]] + ) # The average on the y-axis that want to be zoomed in + window_width = 0.01 * ave_value + axins = zoomed_inset_axes( + ax_capital, + 3, + loc="center", + bbox_to_anchor=(0.5, 0.7, -0.3, -0.3), + bbox_transform=ax_capital.transAxes, + ) + + axins.plot( + t[time_window[0] - 1 : time_window[1] + 1], + k_hat[time_window[0] - 1 : time_window[1] + 1], + color="k", + ) + axins.plot( + t[time_window[0] - 1 : time_window[1] + 1], + k_benchmark[time_window[0] - 1 : time_window[1] + 1], + linestyle="--", + color="k", + ) + + x1, x2, y1, y2 = ( + t[time_window[0]], + t[time_window[1]], + ave_value - window_width, + ave_value + window_width, + ) + axins.set_xlim(x1, x2) + axins.set_ylim(y1, y2) + plt.xticks(fontsize=8, visible=False) + plt.tick_params( + axis="x", which="both", bottom=False, top=False, labelbottom=False + ) + plt.yticks(fontsize=8) + mark_inset( + ax_capital, axins, loc1=1, loc2=3, linewidth="0.7", ls="--", ec="0.5" + ) + + time_window = ( + zoom_loc # Indices: The window on the x-axis that want to be zoomed in + ) + ave_value = 0.5 * ( + c_benchmark[time_window[0]] + c_benchmark[time_window[1]] + ) # The average on the y-axis that want to be zoomed in + window_width = 0.01 * ave_value + axins = zoomed_inset_axes( + ax_consumption, + 3, + loc="center", + bbox_to_anchor=(0.5, 0.7, -0.3, -0.3), + bbox_transform=ax_consumption.transAxes, + ) + + axins.plot( + t[time_window[0] - 1 : time_window[1] + 1], + c_hat[time_window[0] - 1 : time_window[1] + 1], + color="b", + ) + axins.plot( + t[time_window[0] - 1 : time_window[1] + 1], + c_benchmark[time_window[0] - 1 : time_window[1] + 1], + linestyle="--", + color="b", + ) + + x1, x2, y1, y2 = ( + t[time_window[0]], + t[time_window[1]], + ave_value - window_width, + ave_value + window_width, + ) + axins.set_xlim(x1, x2) + axins.set_ylim(y1, y2) + plt.xticks(fontsize=8, visible=False) + plt.tick_params( + axis="x", which="both", bottom=False, top=False, labelbottom=False + ) + plt.yticks(fontsize=8) + mark_inset( + ax_consumption, axins, loc1=1, loc2=3, linewidth="0.7", ls="--", ec="0.5" + ) + plt.savefig(output_path, format="pdf") + + +def main(): + sol = neoclassical_growth_matern( + train_points_list=[ + 0.0, + 1.0, + 3.0, + 5.0, + 10.0, + 15.0, + 20.0, + 25.0, + 30.0, + 35.0, + 38.0, + 40.0, + ] + ) + plot_neoclassical_growth( + sol, + "figures/neoclassical_growth_model_sparse.pdf", + c_rel_error_ylim=(1e-7, 2 * 1e-2), + zoom=True, + zoom_loc=[10, 20], + ) + + sol = neoclassical_growth_matern(train_T=10.0, train_points=11, test_T=15.0) + plot_neoclassical_growth( + sol, + "figures/neoclassical_growth_model_far_steady_state.pdf", + k_rel_error_ylim=(1e-4, 1e-1), + c_rel_error_ylim=(1e-4, 1e-1), + zoom=False, + ) + + +if __name__ == "__main__": + jsonargparse.CLI(main) +''' +sol = neoclassical_growth_matern(nu=1.5) +plot_neoclassical_growth( + sol, + "figures/neoclassical_growth_model_nu_1_5.pdf", + k_rel_error_ylim=(1e-7, 1e-2), + c_rel_error_ylim=(1e-7, 1e-2), + zoom=True, + zoom_loc=[75, 85], +) + + +sol = neoclassical_growth_matern(nu=2.5) +plot_neoclassical_growth( + sol, + "figures/neoclassical_growth_model_nu_2_5.pdf", + k_rel_error_ylim=(1e-7, 1e-2), + c_rel_error_ylim=(1e-8, 1e-2), + zoom=True, + zoom_loc=[75, 85], +) + + +sol = neoclassical_growth_matern(rho=2) +plot_neoclassical_growth( + sol, + "figures/neoclassical_growth_model_rho_2.pdf", + k_rel_error_ylim=(1e-7, 1e-2), + c_rel_error_ylim=(1e-7, 1e-2), + zoom=True, + zoom_loc=[75, 85], +) + + +sol = neoclassical_growth_matern(rho=20) +plot_neoclassical_growth( + sol, + "figures/neoclassical_growth_model_rho_20.pdf", + k_rel_error_ylim=(1e-7, 1e-2), + c_rel_error_ylim=(1e-7, 1e-2), + zoom=True, + zoom_loc=[75, 85], +) +''' diff --git a/figures_neoclassical_human_capital.py b/figures_neoclassical_human_capital.py index 98e6608..37d5b33 100644 --- a/figures_neoclassical_human_capital.py +++ b/figures_neoclassical_human_capital.py @@ -1,13 +1,7 @@ -import jax.numpy as jnp import matplotlib.pyplot as plt -import os +import jsonargparse from neoclassical_human_capital_matern import human_capital_matern -from mpl_toolkits.axes_grid1.inset_locator import ( - zoomed_inset_axes, - mark_inset, - inset_axes, -) fontsize = 17 ticksize = 16 @@ -26,86 +20,90 @@ plt.rcParams.update(params) -## Plot given solution -sol = human_capital_matern() -output_path = "figures/neoclassical_human_capital.pdf" +def main(): + sol = human_capital_matern() + output_path = "figures/neoclassical_human_capital.pdf" -t = sol["t_test"] -T = sol["t_train"].max() -c_hat = sol["c_test"] -k_hat = sol["k_test"] -h_hat = sol["h_test"] -i_k_hat = sol["i_k_test"] -i_h_hat = sol["i_h_test"] -mu_k_hat = sol["mu_k_test"] -mu_h_hat = sol["mu_h_test"] + t = sol["t_test"] + T = sol["t_train"].max() + c_hat = sol["c_test"] + k_hat = sol["k_test"] + h_hat = sol["h_test"] + i_k_hat = sol["i_k_test"] + i_h_hat = sol["i_h_test"] + mu_k_hat = sol["mu_k_test"] + mu_h_hat = sol["mu_h_test"] -# Plotting + # Plotting -ax_physical_capital = plt.subplot(4, 2, 1) + plt.subplot(4, 2, 1) -plt.plot(t, k_hat, color="k", label=r"$\hat{x}_k(t)$: Kernel Approximation") -#plt.axhline(y=sol["k_ss"], linestyle="-.", color="k", label=r"$k^*$:Steady-State") -plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") -plt.ylabel("Physical Capital: $x_k(t)$") -plt.xlabel("Time") -plt.legend() # Show legend with labels + plt.plot(t, k_hat, color="k", label=r"$\hat{x}_k(t)$: Kernel Approximation") + #plt.axhline(y=sol["k_ss"], linestyle="-.", color="k", label=r"$k^*$:Steady-State") + plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") + plt.ylabel("Physical Capital: $x_k(t)$") + plt.xlabel("Time") + plt.legend() # Show legend with labels -ax_human_capital = plt.subplot(4, 2, 2) + plt.subplot(4, 2, 2) -plt.plot(t, h_hat, color="k", label=r"$\hat{x}_h(t)$: Kernel Approximation") -#plt.axhline(y=sol["h_ss"], linestyle="-.", color="grey", label=r"$h^*$: Steady-State") -plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") -plt.ylabel("Human Capital: $x_h(t)$") -plt.xlabel("Time") -plt.legend() # Show legend with labels + plt.plot(t, h_hat, color="k", label=r"$\hat{x}_h(t)$: Kernel Approximation") + #plt.axhline(y=sol["h_ss"], linestyle="-.", color="grey", label=r"$h^*$: Steady-State") + plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") + plt.ylabel("Human Capital: $x_h(t)$") + plt.xlabel("Time") + plt.legend() # Show legend with labels -ax_consumption = plt.subplot(4, 2, 3) + plt.subplot(4, 2, 3) -plt.plot(t, c_hat, color="b", label=r"$\hat{y}_c(t)$: Kernel Approximation") -#plt.axhline(y=sol["c_ss"], linestyle="-.", color="b", label=r"$c^*$: Steady-State") -plt.axvline(x=T, color="b", linestyle=":", label="Extrapolation/Interpolation") -plt.ylabel("Consumption: $y_c(t)$") -plt.xlabel("Time") -plt.legend() # Show legend with labels + plt.plot(t, c_hat, color="b", label=r"$\hat{y}_c(t)$: Kernel Approximation") + #plt.axhline(y=sol["c_ss"], linestyle="-.", color="b", label=r"$c^*$: Steady-State") + plt.axvline(x=T, color="b", linestyle=":", label="Extrapolation/Interpolation") + plt.ylabel("Consumption: $y_c(t)$") + plt.xlabel("Time") + plt.legend() # Show legend with labels -ax_investment_k = plt.subplot(4, 2, 4) + plt.subplot(4, 2, 4) -plt.plot(t, i_k_hat, color="b", label=r"$\hat{y}_k(t)$: Kernel Approximation") -#plt.axhline(y=sol["i_k_ss"], linestyle="-.", color="k", label=r"$i_k^*$: Steady-State") -plt.axvline(x=T, color="b", linestyle=":", label="Extrapolation/Interpolation") -plt.ylabel("Physical Capital Investment: $y_k(t)$") -plt.xlabel("Time") -plt.legend() # Show legend with labels + plt.plot(t, i_k_hat, color="b", label=r"$\hat{y}_k(t)$: Kernel Approximation") + #plt.axhline(y=sol["i_k_ss"], linestyle="-.", color="k", label=r"$i_k^*$: Steady-State") + plt.axvline(x=T, color="b", linestyle=":", label="Extrapolation/Interpolation") + plt.ylabel("Physical Capital Investment: $y_k(t)$") + plt.xlabel("Time") + plt.legend() # Show legend with labels -ax_investment_h = plt.subplot(4, 2, 5) + plt.subplot(4, 2, 5) -plt.plot(t, i_h_hat, color="b", label=r"$\hat{y}_h(t)$: Kernel Approximation") -#plt.axhline(y=sol["i_h_ss"], linestyle="-.", color="grey", label=r"$i_h^*$: Steady-State") -plt.axvline(x=T, color="b", linestyle=":", label="Extrapolation/Interpolation") -plt.ylabel("Human Capital Investment: $y_h(t)$") -plt.xlabel("Time") -plt.legend() # Show legend with labels + plt.plot(t, i_h_hat, color="b", label=r"$\hat{y}_h(t)$: Kernel Approximation") + #plt.axhline(y=sol["i_h_ss"], linestyle="-.", color="grey", label=r"$i_h^*$: Steady-State") + plt.axvline(x=T, color="b", linestyle=":", label="Extrapolation/Interpolation") + plt.ylabel("Human Capital Investment: $y_h(t)$") + plt.xlabel("Time") + plt.legend() # Show legend with labels -ax_investment_mu_k = plt.subplot(4, 2, 6) + plt.subplot(4, 2, 6) -plt.plot(t, mu_k_hat, color="grey", label=r"$\hat{\mu}_k(t)$: Kernel Approximation") -#plt.axhline(y=sol["i_h_ss"], linestyle="-.", color="grey", label=r"$i_h^*$: Steady-State") -plt.axvline(x=T, color="grey", linestyle=":", label="Extrapolation/Interpolation") -plt.ylabel(r"Co-state Variable: $\mu_k(t)$") -plt.xlabel("Time") -plt.legend() # Show legend with labels + plt.plot(t, mu_k_hat, color="grey", label=r"$\hat{\mu}_k(t)$: Kernel Approximation") + #plt.axhline(y=sol["i_h_ss"], linestyle="-.", color="grey", label=r"$i_h^*$: Steady-State") + plt.axvline(x=T, color="grey", linestyle=":", label="Extrapolation/Interpolation") + plt.ylabel(r"Co-state Variable: $\mu_k(t)$") + plt.xlabel("Time") + plt.legend() # Show legend with labels -ax_investment_mu_h = plt.subplot(4, 2, 7) + plt.subplot(4, 2, 7) -plt.plot(t, mu_h_hat, color="grey", label=r"$\hat{\mu}_h(t)$: Kernel Approximation") -#plt.axhline(y=sol["i_h_ss"], linestyle="-.", color="grey", label=r"$i_h^*$: Steady-State") -plt.axvline(x=T, color="grey", linestyle=":", label="Extrapolation/Interpolation") -plt.ylabel(r"Co-state Variable: $\mu_h(t)$") -plt.xlabel("Time") -plt.legend() # Show legend with labels + plt.plot(t, mu_h_hat, color="grey", label=r"$\hat{\mu}_h(t)$: Kernel Approximation") + #plt.axhline(y=sol["i_h_ss"], linestyle="-.", color="grey", label=r"$i_h^*$: Steady-State") + plt.axvline(x=T, color="grey", linestyle=":", label="Extrapolation/Interpolation") + plt.ylabel(r"Co-state Variable: $\mu_h(t)$") + plt.xlabel("Time") + plt.legend() # Show legend with labels -plt.tight_layout() # Adjust layout to prevent overlap + plt.tight_layout() # Adjust layout to prevent overlap -plt.savefig(output_path, format="pdf") + plt.savefig(output_path, format="pdf") + + +if __name__ == "__main__": + jsonargparse.CLI(main) diff --git a/figures_optimal_advertising.py b/figures_optimal_advertising.py index f0c0292..e3caec0 100644 --- a/figures_optimal_advertising.py +++ b/figures_optimal_advertising.py @@ -1,62 +1,57 @@ -import jax.numpy as jnp -import matplotlib.pyplot as plt -import numpy as np -import os -from optimal_advertising_matern import ( - optimal_advertising_matern, -) - -from mpl_toolkits.axes_grid1.inset_locator import ( - zoomed_inset_axes, - mark_inset, - inset_axes, -) - -fontsize = 17 -ticksize = 16 -figsize = (15, 7) -params = { - "font.family": "serif", - "figure.figsize": figsize, - "figure.dpi": 80, - "figure.edgecolor": "k", - "font.size": fontsize, - "axes.labelsize": fontsize, - "axes.titlesize": fontsize, - "xtick.labelsize": ticksize, - "ytick.labelsize": ticksize, -} -plt.rcParams.update(params) - - -## Plot for optimal advertising -sol = optimal_advertising_matern() -output_path = "figures/optimal_advertising.pdf" - -plt.figure(figsize=(15, 7)) - -x_hat = sol["x_test"] -mu_hat = sol["mu_test"] -u_hat = sol["u_test"] - -T = sol["t_train"].max() -t = sol["t_test"] - -ax_market_share = plt.subplot(1, 2, 1) -plt.plot(t, x_hat, color="k", label=r"$\hat{x}(t)$: Kernel Approximation") -#plt.axhline(y=sol["x_ss"], linestyle="-.", color="k", label=r"$x^*$: Steady-State") -plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") -plt.ylabel(r"Market Share: $x(t)$") -plt.xlabel("Time") -plt.legend() # Show legend with labels - -ax_mu = plt.subplot(1, 2, 2) -plt.plot(t, mu_hat, color="blue", label=r"$\hat{\mu}(t)$: Kernel Approximation") -#plt.axhline(y=sol["mu_ss"], linestyle="-.", color="b", label=r"$\mu^*$: Steady-State") -plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") -plt.ylabel(r"Co-state Variable: $\mu(t)$") -plt.xlabel("Time") -plt.legend() # Show legend with labels -plt.tight_layout() - -plt.savefig(output_path, format="pdf") +import matplotlib.pyplot as plt +import jsonargparse +from optimal_advertising_matern import optimal_advertising_matern + + +fontsize = 17 +ticksize = 16 +figsize = (15, 7) +params = { + "font.family": "serif", + "figure.figsize": figsize, + "figure.dpi": 80, + "figure.edgecolor": "k", + "font.size": fontsize, + "axes.labelsize": fontsize, + "axes.titlesize": fontsize, + "xtick.labelsize": ticksize, + "ytick.labelsize": ticksize, +} +plt.rcParams.update(params) + + +def main(): + sol = optimal_advertising_matern() + output_path = "figures/optimal_advertising.pdf" + + plt.figure(figsize=(15, 7)) + + x_hat = sol["x_test"] + mu_hat = sol["mu_test"] + sol["u_test"] + + T = sol["t_train"].max() + t = sol["t_test"] + + plt.subplot(1, 2, 1) + plt.plot(t, x_hat, color="k", label=r"$\hat{x}(t)$: Kernel Approximation") + #plt.axhline(y=sol["x_ss"], linestyle="-.", color="k", label=r"$x^*$: Steady-State") + plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") + plt.ylabel(r"Market Share: $x(t)$") + plt.xlabel("Time") + plt.legend() # Show legend with labels + + plt.subplot(1, 2, 2) + plt.plot(t, mu_hat, color="blue", label=r"$\hat{\mu}(t)$: Kernel Approximation") + #plt.axhline(y=sol["mu_ss"], linestyle="-.", color="b", label=r"$\mu^*$: Steady-State") + plt.axvline(x=T, color="k", linestyle=":", label="Extrapolation/Interpolation") + plt.ylabel(r"Co-state Variable: $\mu(t)$") + plt.xlabel("Time") + plt.legend() # Show legend with labels + plt.tight_layout() + + plt.savefig(output_path, format="pdf") + + +if __name__ == "__main__": + jsonargparse.CLI(main) diff --git a/neoclassical_growth_benchmark.py b/neoclassical_growth_benchmark.py index 5e637f3..a0dbd48 100644 --- a/neoclassical_growth_benchmark.py +++ b/neoclassical_growth_benchmark.py @@ -1,46 +1,45 @@ -import jax.numpy as jnp -import numpy as np -from scipy.integrate import solve_bvp - - -# Neoclassical Growth Benchmark solution -def neoclassical_growth_benchmark(a, delta, r, sigma_crra, k_0, t_grid, perturb_k=1e-4): - #a: capital share - #delta: depreciation - #r: discount rate - #sigma_crra: the constant relative risk aversion coefficient - #k_0: initial condition for capital - #t_grid: The grid for time where we want to solve the problem over (0,t_1,...,T) - #perturb_k : how far away from the steady-state capital you want the trajectory be at the terminal time, T - - k_ss = ((delta + r) / a) ** (1 / (a - 1)) - c_ss = a * k_ss**a - -delta * k_ss - # perturb the final value of the capital at T to help convergence - k_T = k_ss - perturb_k - - def ODE(t, y): - k = y[0] - c = y[1] - return jnp.vstack( - ( - k**a - c - delta * k, - (c / sigma_crra) * (a * k ** (a - 1) - r - delta), - ) - ) - - def bc(ya, yb): - return jnp.array([ya[0] - k_0, yb[0] - k_T]) #boundary condition, k(0) = k_0, k(T) = k_T - - iv = 1 * jnp.ones((2, t_grid.size)) - solution = solve_bvp(ODE, bc, t_grid, iv) - - # the "solution" is an interpolator already, can just unpack - T_max = t_grid[-1] - - def interpolate_solution(t_grid): - if t_grid[-1] > T_max: - raise ValueError("Extrapolation not supported") - val = solution.sol(t_grid) - return val[0], val[1] - - return interpolate_solution +import jax.numpy as jnp +from scipy.integrate import solve_bvp + + +# Neoclassical Growth Benchmark solution +def neoclassical_growth_benchmark(a, delta, r, sigma_crra, k_0, t_grid, perturb_k=1e-4): + #a: capital share + #delta: depreciation + #r: discount rate + #sigma_crra: the constant relative risk aversion coefficient + #k_0: initial condition for capital + #t_grid: The grid for time where we want to solve the problem over (0,t_1,...,T) + #perturb_k : how far away from the steady-state capital you want the trajectory be at the terminal time, T + + k_ss = ((delta + r) / a) ** (1 / (a - 1)) + a * k_ss**a - -delta * k_ss + # perturb the final value of the capital at T to help convergence + k_T = k_ss - perturb_k + + def ODE(t, y): + k = y[0] + c = y[1] + return jnp.vstack( + ( + k**a - c - delta * k, + (c / sigma_crra) * (a * k ** (a - 1) - r - delta), + ) + ) + + def bc(ya, yb): + return jnp.array([ya[0] - k_0, yb[0] - k_T]) #boundary condition, k(0) = k_0, k(T) = k_T + + iv = 1 * jnp.ones((2, t_grid.size)) + solution = solve_bvp(ODE, bc, t_grid, iv) + + # the "solution" is an interpolator already, can just unpack + T_max = t_grid[-1] + + def interpolate_solution(t_grid): + if t_grid[-1] > T_max: + raise ValueError("Extrapolation not supported") + val = solution.sol(t_grid) + return val[0], val[1] + + return interpolate_solution diff --git a/neoclassical_growth_concave_convex_matern.py b/neoclassical_growth_concave_convex_matern.py index 1d1ccbe..396292a 100644 --- a/neoclassical_growth_concave_convex_matern.py +++ b/neoclassical_growth_concave_convex_matern.py @@ -1,14 +1,8 @@ -import jax -import jax.numpy as jnp -import numpy as np -import pyomo.environ as pyo -from pyomo.opt import TerminationCondition -import jsonargparse -from jax import config -from kernels import integrated_matern_kernel_matrices from typing import List, Optional -config.update("jax_enable_x64", True) +import jsonargparse + +from neoclassical_growth_matern import neoclassical_growth_matern def neoclassical_growth_concave_convex_matern( @@ -22,130 +16,35 @@ def neoclassical_growth_concave_convex_matern( nu: float = 0.5, sigma: float = 1.0, rho: float = 10, - solver_type: str = "ipopt", train_T: float = 40.0, train_points: int = 41, - test_T: float = 50, + test_T: float = 50.0, test_points: int = 41, benchmark_T: float = 60.0, benchmark_points: int = 300, train_points_list: Optional[List[float]] = None, verbose: bool = False, ): - # if passing in `train_points` then doesn't us a grid. Otherwise, uses linspace - if train_points_list is None: - train_data = jnp.linspace(0, train_T, train_points) - else: - train_data = jnp.array(train_points_list) - test_data = jnp.linspace(0, test_T, test_points) - benchmark_grid = jnp.linspace(0, benchmark_T, benchmark_points) - - # Construct kernel matrices - N = len(train_data) - K, K_tilde = integrated_matern_kernel_matrices( - train_data, train_data, nu, sigma, rho + return neoclassical_growth_matern( + a=a, + delta=delta, + rho_hat=rho_hat, + k_0=k_0, + A=A, + b_1=b_1, + b_2=b_2, + nu=nu, + sigma=sigma, + rho=rho, + train_T=train_T, + train_points=train_points, + test_T=test_T, + test_points=test_points, + benchmark_T=benchmark_T, + benchmark_points=benchmark_points, + train_points_list=train_points_list, + verbose=verbose, ) - K = np.array(K) # pyomo doesn't support jax arrays - K_tilde = np.array(K_tilde) - - # Create pyomo model and variables - m = pyo.ConcreteModel() - m.I = range(N) - m.alpha_mu = pyo.Var(m.I, within=pyo.Reals, initialize=0.0) - #m.alpha_c = pyo.Var(m.I, within=pyo.Reals, initialize=0.0) - m.alpha_k = pyo.Var(m.I, within=pyo.Reals, initialize=0.0) - #m.c_0 = pyo.Var(within=pyo.NonNegativeReals, initialize=1.0) - m.mu_0 = pyo.Var(within=pyo.NonNegativeReals, initialize=1.0) # mu*c =1 - - # Map kernels to variables. Pyomo doesn't support c_0 + K_tilde @ m.alpha_c - def mu(m, i): - return m.mu_0 + sum(K_tilde[i, j] * m.alpha_mu[j] for j in m.I) - - #def c(m, i): - #return m.c_0 + sum(K_tilde[i, j] * m.alpha_c[j] for j in m.I) - - def k(m, i): - return k_0 + sum(K_tilde[i, j] * m.alpha_k[j] for j in m.I) - - def dmu_dt(m, i): - return sum(K[i, j] * m.alpha_mu[j] for j in m.I) - - def dk_dt(m, i): - return sum(K[i, j] * m.alpha_k[j] for j in m.I) - - # Production function - base = b_2 / (b_1 - 1) - exponent = 1 / a - k_bar = base**exponent - - def f(k): - return A * pyo.Expr_if(k < k_bar, k**a, b_1 * k**a - b_2) - - def f_prime(k): - return pyo.Expr_if( - k < k_bar, A * a * (k ** (a - 1)), A * a * b_1 * (k ** (a - 1)) - ) - - # Define constraints and objective for model and solve - @m.Constraint(m.I) # for each index in m.I - def resource_constraint(m, i): - return dk_dt(m, i) == f(k(m, i)) - delta * k(m, i) - (1/mu(m, i)) - - @m.Constraint(m.I) # for each index in m.I - def euler(m, i): - return dmu_dt(m, i) == -mu(m, i) * (f_prime(k(m, i)) - delta - rho_hat) - - #@m.Constraint(m.I) # for each index in m.I - #def shadow_price(m, i): - #return c(m, i) * mu(m, i) - 1.0 == 0.0 - - - @m.Objective(sense=pyo.minimize) - def min_norm(m): # alpha @ K @ alpha not supported by pyomo - return sum(K[i, j] * m.alpha_mu[i] * m.alpha_mu[j] for i in m.I for j in m.I) + sum(K[i, j] * m.alpha_k[i] * m.alpha_k[j] for i in m.I for j in m.I) - - solver = pyo.SolverFactory(solver_type) - options = { - "tol": 1e-8, # Tighten the tolerance for optimality - "dual_inf_tol": 1e-8, # Tighten the dual infeasibility tolerance - "constr_viol_tol": 1e-8, # Tighten the constraint violation tolerance - "max_iter": 5000, # Adjust the maximum number of iterations if needed - } # See https://coin-or.github.io/Ipopt/OPTIONS.html for more details # can add options here. See https://coin-or.github.io/Ipopt/OPTIONS.html#OPTIONS_AMPL - results = solver.solve(m, tee=verbose, options=options) - if not results.solver.termination_condition == TerminationCondition.optimal: - print(str(results.solver)) # raise exception? - - alpha_mu = jnp.array([pyo.value(m.alpha_mu[i]) for i in m.I]) - alpha_k = jnp.array([pyo.value(m.alpha_k[i]) for i in m.I]) - mu_0 = pyo.value(m.mu_0) - - # Interpolator using training data - @jax.jit - def kernel_solution(test_data): - # pointwise comparison test_data to train_data - K_test, K_tilde_test = integrated_matern_kernel_matrices( - test_data, train_data, nu, sigma, rho - ) - mu_test = mu_0 + K_tilde_test @ alpha_mu - k_test = k_0 + K_tilde_test @ alpha_k - c_test = 1.0 / mu_test - return k_test, c_test - - # Generate test_data and compare to the benchmark - k_test, c_test = kernel_solution(test_data) - - print(f"solve_time(s) = {results.solver.Time}") - return { - "t_train": train_data, - "t_test": test_data, - "k_test": k_test, - "c_test": c_test, - "alpha_m": alpha_mu, - "alpha_k": alpha_k, - "mu_0": mu_0, - "solve_time": results.solver.Time, - "kernel_solution": kernel_solution, # interpolator - } if __name__ == "__main__": diff --git a/neoclassical_growth_matern.py b/neoclassical_growth_matern.py index ddd7d9a..c391e9f 100644 --- a/neoclassical_growth_matern.py +++ b/neoclassical_growth_matern.py @@ -1,151 +1,469 @@ +import time +from typing import List, Optional + import jax import jax.numpy as jnp -import numpy as np -import pyomo.environ as pyo -from pyomo.opt import TerminationCondition import jsonargparse +import numpy as np +import unopy from jax import config + from kernels import integrated_matern_kernel_matrices from neoclassical_growth_benchmark import neoclassical_growth_benchmark -from typing import List, Optional +from rkhs import rkhs_norm_squared config.update("jax_enable_x64", True) +NLP_OPTIONS = dict(preset="ipopt") +KINKED_NLP_OPTIONS = dict(preset="ipopt", max_iterations=25, time_limit=0.15) +ACCEPTED_SOLUTION_STATUSES = {"FEASIBLE_KKT_POINT", "FEASIBLE_SMALL_STEP"} +TRAIN_RESIDUAL_TOL = 1e-5 +VALIDATION_RESIDUAL_TOL = 5e-3 +MPK_BOUND_TOL = 1e-3 +DOMAIN_EPS = 1e-6 + def neoclassical_growth_matern( a: float = 1 / 3, delta: float = 0.1, rho_hat: float = 0.11, - k_0: float = 1.0,#k_0 is the state variable initial conditions here, i.e., x_0 + k_0: float = 1.0, # k_0 is the state variable initial condition. + A: Optional[float] = None, + b_1: Optional[float] = None, + b_2: Optional[float] = None, nu: float = 0.5, sigma: float = 1.0, rho: float = 10, - solver_type: str = "ipopt", train_T: float = 40.0, train_points: int = 41, - test_T: float = 50, + test_T: float = 50.0, test_points: int = 100, benchmark_T: float = 60.0, benchmark_points: int = 300, train_points_list: Optional[List[float]] = None, - lambda_p: float = 0.0, #Smooting penalty for the optimizer, This is purely because of the DAE term mu*c = 1 verbose: bool = False, ): - # if passing in `train_points` then doesn't us a grid. Otherwise, uses linspace + kinked_parameter_count = sum(parameter is not None for parameter in (A, b_1, b_2)) + if kinked_parameter_count not in {0, 3}: + raise ValueError("Set all of A, b_1, and b_2, or set none of them.") + use_kinked_production = kinked_parameter_count == 3 + A_value = 1.0 if A is None else float(A) + b_1_value = 1.0 if b_1 is None else float(b_1) + b_2_value = 0.0 if b_2 is None else float(b_2) + if train_points_list is None: train_data = jnp.linspace(0, train_T, train_points) else: train_data = jnp.array(train_points_list) test_data = jnp.linspace(0, test_T, test_points) + validation_points = max(test_points, benchmark_points) + validation_data = jnp.linspace(0, train_T, validation_points) benchmark_grid = jnp.linspace(0, benchmark_T, benchmark_points) - # Construct kernel matrices - N = len(train_data) + n_train = len(train_data) K, K_tilde = integrated_matern_kernel_matrices( train_data, train_data, nu, sigma, rho ) - K = np.array(K) # pyomo doesn't support jax arrays - K_tilde = np.array(K_tilde) + K = np.asarray((K + K.T) / 2) + K_tilde = np.asarray(K_tilde) + K_jax = jnp.asarray(K) + K_tilde_jax = jnp.asarray(K_tilde) + + n_variables = 3 * n_train + 2 + n_constraints = 6 * n_train + + def initial_production(k_value): + if use_kinked_production: + return A_value * max(k_value**a, b_1_value * k_value**a - b_2_value) + return k_value**a + + c_flow_guess = max(initial_production(k_0) - delta * k_0, DOMAIN_EPS) + x_initial = np.zeros(n_variables, dtype=np.float64) + x_initial[3 * n_train] = c_flow_guess + x_initial[3 * n_train + 1] = 1.0 / c_flow_guess + + def unpack(x): + alpha_mu = x[:n_train] + alpha_c = x[n_train : 2 * n_train] + alpha_k = x[2 * n_train : 3 * n_train] + c_0 = x[3 * n_train] + mu_0 = x[3 * n_train + 1] + return alpha_mu, alpha_c, alpha_k, c_0, mu_0 + + def path_values(x, K_eval, K_tilde_eval): + alpha_mu, alpha_c, alpha_k, c_0, mu_0 = unpack(x) + mu = mu_0 + K_tilde_eval @ alpha_mu + c = c_0 + K_tilde_eval @ alpha_c + k = k_0 + K_tilde_eval @ alpha_k + dmu_dt = K_eval @ alpha_mu + dk_dt = K_eval @ alpha_k + return k, c, mu, dk_dt, dmu_dt + + def production_scalar(k_scalar): + k_positive = jnp.maximum(k_scalar, DOMAIN_EPS) + z = k_positive**a + if use_kinked_production: + return A_value * jnp.maximum(z, b_1_value * z - b_2_value) + return z + + production = jax.vmap(production_scalar) + marginal_product = jax.vmap(jax.grad(production_scalar)) + + def objective(x): + alpha_mu, alpha_c, alpha_k, _, _ = unpack(x) + return ( + alpha_mu @ K_jax @ alpha_mu + + alpha_c @ K_jax @ alpha_c + + alpha_k @ K_jax @ alpha_k + ) + + def constraints(x): + k, c, mu, dk_dt, dmu_dt = path_values(x, K_jax, K_tilde_jax) + output = production(k) + mpk = marginal_product(k) + resource = dk_dt - (output - delta * k - c) + euler = dmu_dt + mu * (mpk - delta - rho_hat) + shadow_price = mu * c - 1.0 + return jnp.concatenate([resource, euler, shadow_price, k, c, mu]) + + def lagrangian(x, objective_multiplier, multipliers): + return objective_multiplier * objective(x) + jnp.dot(multipliers, constraints(x)) + + objective_value = jax.jit(objective) + objective_gradient = jax.jit(jax.grad(objective)) + constraint_values = jax.jit(constraints) + constraint_jacobian = jax.jit(jax.jacfwd(constraints)) + lagrangian_hessian = jax.jit(jax.hessian(lagrangian, argnums=0)) + + x_initial_jax = jnp.asarray(x_initial) + zero_multipliers = jnp.zeros(n_constraints, dtype=jnp.float64) + jax.block_until_ready(objective_value(x_initial_jax)) + jax.block_until_ready(objective_gradient(x_initial_jax)) + jax.block_until_ready(constraint_values(x_initial_jax)) + jax.block_until_ready(constraint_jacobian(x_initial_jax)) + jax.block_until_ready(lagrangian_hessian(x_initial_jax, 1.0, zero_multipliers)) + + variable_lower_bounds = np.full(n_variables, -np.inf, dtype=np.float64) + variable_upper_bounds = np.full(n_variables, np.inf, dtype=np.float64) + variable_lower_bounds[3 * n_train :] = DOMAIN_EPS + constraint_lower_bounds = np.concatenate( + [ + np.zeros(3 * n_train, dtype=np.float64), + np.full(3 * n_train, DOMAIN_EPS, dtype=np.float64), + ] + ) + constraint_upper_bounds = np.concatenate( + [ + np.zeros(3 * n_train, dtype=np.float64), + np.full(3 * n_train, np.inf, dtype=np.float64), + ] + ) + + model = unopy.Model( + unopy.PROBLEM_NONLINEAR, + n_variables, + variable_lower_bounds, + variable_upper_bounds, + unopy.ZERO_BASED_INDEXING, + ) + + def objective_callback(x): + return float(objective_value(jnp.asarray(x))) - # Create pyomo model and variables - m = pyo.ConcreteModel() - m.I = range(N) - m.alpha_mu = pyo.Var(m.I, within=pyo.Reals, initialize=0.0) - m.alpha_c = pyo.Var(m.I, within=pyo.Reals, initialize=0.0) - m.alpha_k = pyo.Var(m.I, within=pyo.Reals, initialize=0.0) #k is the state variable here, i.e., x - m.c_0 = pyo.Var(within=pyo.NonNegativeReals, initialize=k_0**a - delta * k_0) - m.mu_0 = pyo.Var(within=pyo.NonNegativeReals, initialize=k_0**a - delta * k_0) + def objective_gradient_callback(x, gradient): + gradient[:] = np.asarray(objective_gradient(jnp.asarray(x))) - # Map kernels to variables. Pyomo doesn't support c_0 + K_tilde @ m.alpha_c - def mu(m, i): - return m.mu_0 + sum(K_tilde[i, j] * m.alpha_mu[j] for j in m.I) + model.set_objective( + unopy.MINIMIZE, objective_callback, objective_gradient_callback + ) - def c(m, i): - return m.c_0 + sum(K_tilde[i, j] * m.alpha_c[j] for j in m.I) + jacobian_rows = np.repeat(np.arange(n_constraints, dtype=np.int32), n_variables) + jacobian_columns = np.tile(np.arange(n_variables, dtype=np.int32), n_constraints) - def k(m, i): #k is the state variable here, i.e., x - return k_0 + sum(K_tilde[i, j] * m.alpha_k[j] for j in m.I) + def constraints_callback(x, constraint_output): + constraint_output[:] = np.asarray(constraint_values(jnp.asarray(x))) - def dmu_dt(m, i): - return sum(K[i, j] * m.alpha_mu[j] for j in m.I) + def jacobian_callback(x, jacobian_output): + jacobian_output[:] = np.asarray( + constraint_jacobian(jnp.asarray(x)) + ).reshape(-1) - def dk_dt(m, i): #dk_dt is the state variable's derivative here, i.e., dx_dt - return sum(K[i, j] * m.alpha_k[j] for j in m.I) + model.set_constraints( + n_constraints, + constraints_callback, + constraint_lower_bounds, + constraint_upper_bounds, + len(jacobian_rows), + jacobian_rows, + jacobian_columns, + jacobian_callback, + ) - # Define constraints and objective for model and solve - @m.Constraint(m.I) # for each index in m.I - def resource_constraint(m, i): - return dk_dt(m, i) == k(m, i) ** a - delta * k(m, i) - c(m, i) + hessian_rows, hessian_columns = np.tril_indices(n_variables) + hessian_rows = hessian_rows.astype(np.int32) + hessian_columns = hessian_columns.astype(np.int32) - @m.Constraint(m.I) # for each index in m.I - def euler(m, i): - return dmu_dt(m, i) == -mu(m, i) * (a * k(m, i) ** (a - 1) - delta - rho_hat) + def hessian_callback(x, objective_multiplier, multipliers, hessian_output): + hessian = np.asarray( + lagrangian_hessian( + jnp.asarray(x), + float(objective_multiplier), + jnp.asarray(multipliers), + ) + ) + hessian_output[:] = hessian[hessian_rows, hessian_columns] + + model.set_lagrangian_hessian( + len(hessian_rows), + unopy.LOWER_TRIANGLE, + hessian_rows, + hessian_columns, + hessian_callback, + ) + model.set_lagrangian_sign_convention(unopy.MULTIPLIER_POSITIVE) + model.set_initial_primal_iterate(x_initial) - @m.Constraint(m.I) # for each index in m.I - def shadow_price(m, i): - return mu(m, i) * c(m, i) == 1.0 + solver = unopy.UnoSolver() + options = dict(KINKED_NLP_OPTIONS if use_kinked_production else NLP_OPTIONS) + solver.set_preset(options.pop("preset")) + if not verbose: + solver.set_option("logger", "SILENT") + solver.set_option("print_solution", False) + for option_name, option_value in options.items(): + solver.set_option(option_name, option_value) + start = time.perf_counter() + result = solver.optimize(model) + elapsed = time.perf_counter() - start - @m.Objective(sense=pyo.minimize) - def min_norm(m): # alpha @ K @ alpha not supported by pyomo - return sum(K[i, j] * m.alpha_mu[i] * m.alpha_mu[j] for i in m.I for j in m.I)+sum(K[i, j] * m.alpha_k[i] * m.alpha_k[j] for i in m.I for j in m.I) + lambda_p*(sum(K[i, j] * m.alpha_c[i] * m.alpha_c[j] for i in m.I for j in m.I) - + sum(K[i, j] * m.alpha_k[i] * m.alpha_k[j] for i in m.I for j in m.I)+ sum(K[i, j] * m.alpha_mu[i] * m.alpha_mu[j] for i in m.I for j in m.I) + x = jnp.asarray(np.array(result.primal_solution, dtype=np.float64)) + alpha_mu, alpha_c, alpha_k, c_0, mu_0 = unpack(x) + rkhs_norms = { + "k": rkhs_norm_squared(alpha_k, K), + "c": rkhs_norm_squared(alpha_c, K), + "mu": rkhs_norm_squared(alpha_mu, K), + } + + def evaluate_grid(points_data): + K_eval, K_tilde_eval = integrated_matern_kernel_matrices( + points_data, train_data, nu, sigma, rho + ) + k_values, c_values, mu_values, dk_values, dmu_values = path_values( + x, K_eval, K_tilde_eval ) - #lambda_p makes sure the optimizer returns smooth (non-wiggly solutions in the extrapolation), we set it to zero - solver = pyo.SolverFactory(solver_type) - options = { - "tol": 1e-8, # Tighten the tolerance for optimality - "dual_inf_tol": 1e-8, # Tighten the dual infeasibility tolerance - "constr_viol_tol": 1e-8, # Tighten the constraint violation tolerance - "max_iter": 2000, # Adjust the maximum number of iterations if needed - } # See https://coin-or.github.io/Ipopt/OPTIONS.html for more details # can add options here. See https://coin-or.github.io/Ipopt/OPTIONS.html#OPTIONS_AMPL - results = solver.solve(m, tee=verbose, options=options) - if not results.solver.termination_condition == TerminationCondition.optimal: - print(str(results.solver)) # raise exception? - - alpha_c = jnp.array([pyo.value(m.alpha_c[i]) for i in m.I]) - alpha_k = jnp.array([pyo.value(m.alpha_k[i]) for i in m.I]) - c_0 = pyo.value(m.c_0) - - # Interpolator using training data + output_values = production(k_values) + mpk_values = marginal_product(k_values) + k_positive = jnp.maximum(k_values, DOMAIN_EPS) + z_values = k_positive**a + if use_kinked_production: + branch_low_values = A_value * z_values + branch_high_values = A_value * (b_1_value * z_values - b_2_value) + branch_gap = branch_low_values - branch_high_values + m1_values = A_value * a * k_positive ** (a - 1.0) + m2_values = b_1_value * m1_values + else: + branch_low_values = z_values + branch_high_values = z_values + branch_gap = jnp.full_like(k_values, jnp.inf) + m1_values = mpk_values + m2_values = mpk_values + implied_mpk = delta + rho_hat - dmu_values / mu_values + mpk_lower_bound = jnp.minimum(m1_values, m2_values) + mpk_upper_bound = jnp.maximum(m1_values, m2_values) + return { + "k": k_values, + "c": c_values, + "mu": mu_values, + "z": z_values, + "Y": output_values, + "P": implied_mpk, + "branch_low": branch_low_values, + "branch_high": branch_high_values, + "resource": dk_values - (output_values - delta * k_values - c_values), + "euler": dmu_values + mu_values * (mpk_values - delta - rho_hat), + "shadow_price": mu_values * c_values - 1.0, + "branch_gap": branch_gap, + "mpk_lower_violation": jnp.maximum(mpk_lower_bound - implied_mpk, 0.0), + "mpk_upper_violation": jnp.maximum(implied_mpk - mpk_upper_bound, 0.0), + } + + train_eval = evaluate_grid(train_data) + validation_eval = evaluate_grid(validation_data) + test_eval = evaluate_grid(test_data) + + train_residuals = { + "resource": train_eval["resource"], + "euler": train_eval["euler"], + "shadow_price": train_eval["shadow_price"], + } + validation_residuals = { + "resource_validation": validation_eval["resource"], + "euler_validation": validation_eval["euler"], + "shadow_price_validation": validation_eval["shadow_price"], + } + helper_residuals = {**train_residuals, **validation_residuals} + max_train_residual = max( + float(jnp.max(jnp.abs(residual))) for residual in train_residuals.values() + ) + max_validation_residual = max( + float(jnp.max(jnp.abs(residual))) for residual in validation_residuals.values() + ) + max_helper_residual = max(max_train_residual, max_validation_residual) + p_lower_violation = max( + float(jnp.max(train_eval["mpk_lower_violation"])), + float(jnp.max(validation_eval["mpk_lower_violation"])), + ) + p_upper_violation = max( + float(jnp.max(train_eval["mpk_upper_violation"])), + float(jnp.max(validation_eval["mpk_upper_violation"])), + ) + active_branch_switch_train = bool( + use_kinked_production + and jnp.min(train_eval["branch_gap"]) < 0.0 + and jnp.max(train_eval["branch_gap"]) > 0.0 + ) + min_branch_gap_train = float(jnp.min(jnp.abs(train_eval["branch_gap"]))) + @jax.jit - def kernel_solution(test_data): - # pointwise comparison test_data to train_data + def kernel_solution(test_points_data): K_test, K_tilde_test = integrated_matern_kernel_matrices( - test_data, train_data, nu, sigma, rho + test_points_data, train_data, nu, sigma, rho ) - c_test = c_0 + K_tilde_test @ alpha_c - k_test = k_0 + K_tilde_test @ alpha_k + k_test, c_test, _, _, _ = path_values(x, K_test, K_tilde_test) return k_test, c_test - sol_benchmark = neoclassical_growth_benchmark( - a, delta, rho_hat, 1.0, k_0, benchmark_grid + finite_positive = bool( + jnp.all(jnp.isfinite(train_eval["k"])) + and jnp.all(jnp.isfinite(train_eval["c"])) + and jnp.all(jnp.isfinite(train_eval["mu"])) + and jnp.all(jnp.isfinite(validation_eval["k"])) + and jnp.all(jnp.isfinite(validation_eval["c"])) + and jnp.all(jnp.isfinite(validation_eval["mu"])) + and jnp.all(jnp.isfinite(test_eval["k"])) + and jnp.all(jnp.isfinite(test_eval["c"])) + and jnp.min(train_eval["k"]) > 0.0 + and jnp.min(train_eval["c"]) > 0.0 + and jnp.min(train_eval["mu"]) > 0.0 + and jnp.min(validation_eval["k"]) > 0.0 + and jnp.min(validation_eval["c"]) > 0.0 + and jnp.min(validation_eval["mu"]) > 0.0 + and jnp.min(test_eval["k"]) > 0.0 + and jnp.min(test_eval["c"]) > 0.0 ) - # Generate test_data and compare to the benchmark - k_benchmark, c_benchmark = sol_benchmark(test_data) - k_test, c_test = kernel_solution(test_data) + solve_time = result.cpu_time + if solve_time is None: + solve_time = elapsed + solver_status = str(result.optimization_status).split(".")[-1] + solution_status = str(result.solution_status).split(".")[-1] + rejection_reasons = [] + if solver_status != "SUCCESS": + rejection_reasons.append("solver_status") + if solution_status not in ACCEPTED_SOLUTION_STATUSES: + rejection_reasons.append("solution_status") + if not finite_positive: + rejection_reasons.append("nonfinite_or_nonpositive") + if max_train_residual > TRAIN_RESIDUAL_TOL: + rejection_reasons.append("train_residual") + if use_kinked_production and max_validation_residual > VALIDATION_RESIDUAL_TOL: + rejection_reasons.append("validation_residual") + if use_kinked_production and ( + p_lower_violation > MPK_BOUND_TOL or p_upper_violation > MPK_BOUND_TOL + ): + rejection_reasons.append("p_bound") + valid_solution = not rejection_reasons - k_rel_error = jnp.abs(k_benchmark - k_test) / k_benchmark - c_rel_error = jnp.abs(c_benchmark - c_test) / c_benchmark - print( - f"solve_time(s) = {results.solver.Time}, E(|rel_error(k)|) = {k_rel_error.mean()}, E(|rel_error(c)|) = {c_rel_error.mean()}" - ) + benchmark_solution = None + k_benchmark = jnp.full_like(test_data, jnp.nan) + c_benchmark = jnp.full_like(test_data, jnp.nan) + k_rel_error = jnp.full_like(test_data, jnp.nan) + c_rel_error = jnp.full_like(test_data, jnp.nan) + if not use_kinked_production: + benchmark_solution = neoclassical_growth_benchmark( + a, delta, rho_hat, 1.0, k_0, benchmark_grid + ) + k_benchmark, c_benchmark = benchmark_solution(test_data) + k_rel_error = jnp.abs(k_benchmark - test_eval["k"]) / k_benchmark + c_rel_error = jnp.abs(c_benchmark - test_eval["c"]) / c_benchmark + + if use_kinked_production: + print(f"solve_time(s) = {solve_time}") + else: + print( + f"solve_time(s) = {solve_time}, E(|rel_error(k)|) = {k_rel_error.mean()}, E(|rel_error(c)|) = {c_rel_error.mean()}" + ) return { "t_train": train_data, "t_test": test_data, - "k_test": k_test, - "c_test": c_test, + "k_test": test_eval["k"], + "c_test": test_eval["c"], "k_benchmark": k_benchmark, "c_benchmark": c_benchmark, "k_rel_error": k_rel_error, "c_rel_error": c_rel_error, + "alpha_m": alpha_mu, + "alpha_mu": alpha_mu, "alpha_c": alpha_c, "alpha_k": alpha_k, - "c_0": c_0, - "solve_time": results.solver.Time, - "kernel_solution": kernel_solution, # interpolator - "benchmark_solution": sol_benchmark, # interpolator + "c_0": float(c_0), + "mu_0": float(mu_0), + "rkhs_norms": rkhs_norms, + "helper_residuals": helper_residuals, + "train_residuals": train_residuals, + "validation_residuals": validation_residuals, + "k_train": train_eval["k"], + "mu_train": train_eval["mu"], + "c_train": train_eval["c"], + "z_train": train_eval["z"], + "Y_train": train_eval["Y"], + "P_train": train_eval["P"], + "branch_low_train": train_eval["branch_low"], + "branch_high_train": train_eval["branch_high"], + "solve_time": solve_time, + "wall_time": elapsed, + "solver_status": solver_status, + "solution_status": solution_status, + "stationarity": result.solution_stationarity, + "primal_feasibility": result.solution_primal_feasibility, + "valid_solution": valid_solution, + "rejection_reason": "accepted" if valid_solution else ",".join(rejection_reasons), + "candidate_branch": "jax_max" if use_kinked_production else "smooth", + "candidate_diagnostics": [ + { + "branch": "jax_max" if use_kinked_production else "smooth", + "valid_solution": valid_solution, + "rejection_reason": "accepted" + if valid_solution + else ",".join(rejection_reasons), + "solver_status": solver_status, + "solution_status": solution_status, + "solve_time": solve_time, + "wall_time": elapsed, + "max_helper_residual": max_helper_residual, + "max_train_residual": max_train_residual, + "max_validation_residual": max_validation_residual, + "p_lower_violation": p_lower_violation, + "p_upper_violation": p_upper_violation, + "objective": float( + rkhs_norms["k"] + rkhs_norms["c"] + rkhs_norms["mu"] + ), + } + ], + "max_helper_residual": max_helper_residual, + "max_train_residual": max_train_residual, + "max_validation_residual": max_validation_residual, + "p_lower_violation": p_lower_violation, + "p_upper_violation": p_upper_violation, + "active_branch_switch_train": active_branch_switch_train, + "min_branch_gap_train": min_branch_gap_train, + "use_kinked_production": use_kinked_production, + "production_parameters": { + "A": A_value, + "b_1": b_1_value, + "b_2": b_2_value, + }, + "kernel_solution": kernel_solution, + "benchmark_solution": benchmark_solution, } diff --git a/neoclassical_human_capital_matern.py b/neoclassical_human_capital_matern.py index 6ba3a9d..1ad9bde 100644 --- a/neoclassical_human_capital_matern.py +++ b/neoclassical_human_capital_matern.py @@ -1,17 +1,80 @@ +import time from typing import List, Optional +import jax import jax.numpy as jnp import jsonargparse import numpy as np -import pyomo.environ as pyo +import unopy from jax import config -from pyomo.opt import TerminationCondition +from nlls_gram import UnderdeterminedLevenbergMarquardt from kernels import integrated_matern_kernel_matrices +from rkhs import rkhs_norm_squared config.update("jax_enable_x64", True) -from scipy.optimize import fsolve +NLP_OPTIONS = dict(preset="filtersqp", time_limit=5.0) +ACCEPTED_SOLUTION_STATUSES = {"FEASIBLE_KKT_POINT", "FEASIBLE_SMALL_STEP"} +DOMAIN_EPS = 1e-8 + + +def _human_capital_initial_residual(params, batch): + a_k, a_h, delta_k, delta_h, k_0 = batch + h_0 = jnp.exp(params["log_h"]) + c_0 = jnp.exp(params["log_c"]) + f = (k_0**a_k) * (h_0**a_h) + f_k = a_k * (k_0 ** (a_k - 1.0)) * (h_0**a_h) + f_h = a_h * (k_0**a_k) * (h_0 ** (a_h - 1.0)) + return jnp.array( + [ + f_h - delta_h - (f_k - delta_k), + c_0 + delta_h * h_0 + delta_k * k_0 - f, + ], + dtype=h_0.dtype, + ) + + +def human_capital_initial_conditions( + a_k: float = 1 / 3, + a_h: float = 1 / 4, + delta_k: float = 0.1, + delta_h: float = 0.05, + k_0: float = 1.5, + iterations: int = 20, +): + dtype = jnp.float64 + batch = tuple( + jnp.asarray(value, dtype=dtype) for value in (a_k, a_h, delta_k, delta_h, k_0) + ) + k_0_jax = batch[-1] + c_guess = ( + (k_0_jax**batch[0]) * (k_0_jax**batch[1]) + - batch[3] * k_0_jax + - batch[2] * k_0_jax + ) + c_guess = jnp.maximum(c_guess, jnp.asarray(1e-12, dtype=dtype)) + params = { + "log_h": jnp.log(k_0_jax), + "log_c": jnp.log(c_guess), + } + solver = UnderdeterminedLevenbergMarquardt( + _human_capital_initial_residual, init_damping=1e-4 + ) + state = solver.init(dtype=dtype) + + @jax.jit + def step(params, state): + return solver.update(params, state, batch) + + info = None + for _ in range(iterations): + params, state, info = step(params, state) + + h_0 = jnp.exp(params["log_h"]) + c_0 = jnp.exp(params["log_c"]) + residual = _human_capital_initial_residual(params, batch) + return h_0, c_0, residual, info def human_capital_matern( @@ -19,12 +82,11 @@ def human_capital_matern( a_h: float = 1 / 4, delta_k: float = 0.1, delta_h: float = 0.05, - rho_hat: float = 0.11, # discount rate - k_0: float = 1.5, # 3.0024724187979452, #1.5, + rho_hat: float = 0.11, + k_0: float = 1.5, nu: float = 0.5, sigma: float = 1.0, rho: float = 10, - solver_type: str = "ipopt", train_T: float = 80.0, train_points: int = 61, test_T: float = 100.0, @@ -32,228 +94,384 @@ def human_capital_matern( benchmark_T: float = 60.0, benchmark_points: int = 300, train_points_list: Optional[List[float]] = None, - lambda_p: float = 5e-3, # small smoothing penalty to stabilize IPOPT verbose: bool = False, ): - # if passing in `train_points` then doesn't us a grid. Otherwise, uses linspace + _ = benchmark_T if train_points_list is None: train_data = jnp.linspace(0, train_T, train_points) else: train_data = jnp.array(train_points_list) test_data = jnp.linspace(0, test_T, test_points) - benchmark_grid = jnp.linspace(0, benchmark_T, benchmark_points) + validation_points = max(test_points, benchmark_points) + validation_data = jnp.linspace(0, train_T, validation_points) - # Construct kernel matrices - N = len(train_data) + n_train = len(train_data) K, K_tilde = integrated_matern_kernel_matrices( train_data, train_data, nu, sigma, rho ) - K = np.array(K) # pyomo doesn't support jax arrays - K_tilde = np.array(K_tilde) - - # Production function - def f(k, h): - return (k**a_k) * (h**a_h) - - def f_k(k, h): - return (a_k * k ** (a_k - 1)) * (h**a_h) - - def f_h(k, h): - return (k**a_k) * (a_h * h ** (a_h - 1)) - - def no_arbitrage_constraint(h): - return f_h(k_0, h) - f_k(k_0, h) - delta_h + delta_k - - initial_guess = [k_0] - result = fsolve(no_arbitrage_constraint, initial_guess) - h_0 = result[0] - - # Create pyomo model and variables - m = pyo.ConcreteModel() - m.I = range(N) - # 8 variables - m.alpha_k = pyo.Var( - m.I, within=pyo.Reals, initialize=0.0 - ) # coeffs for x_k(t): we call it in the code k(t) - m.alpha_h = pyo.Var( - m.I, within=pyo.Reals, initialize=0.0 - ) # coeffs for x_h(t): we call it in the code h(t) - m.alpha_mu_k = pyo.Var(m.I, within=pyo.Reals, initialize=0.0) # coeffs for \mu_k(t) - m.alpha_mu_h = pyo.Var(m.I, within=pyo.Reals, initialize=0.0) # coeffs for \mu_h(t) - m.alpha_i_k = pyo.Var( - m.I, within=pyo.Reals, initialize=0.0 - ) # coeff for y_k(t): we call it i_k(t) in the code - m.alpha_i_h = pyo.Var( - m.I, within=pyo.Reals, initialize=0.0 - ) # coeff for y_h(t): we call it i_h(t) in the code - m.alpha_c = pyo.Var( - m.I, within=pyo.Reals, initialize=0.0 - ) # coeff for for y_c(t): we call it c(t) in the code - - # initializations of variables at 0 for 6 variables: h_0 and k_0 are given to us from the economic setup - m.i_k_0 = pyo.Var(within=pyo.NonNegativeReals, initialize=delta_k * k_0) # y_k(0) - m.i_h_0 = pyo.Var(within=pyo.NonNegativeReals, initialize=delta_h * h_0) # y_h(0) - m.c_0 = pyo.Var( - within=pyo.NonNegativeReals, - initialize=f(k_0, h_0) - delta_h * h_0 - delta_k * k_0, - ) # y_c(0) - m.mu_k_0 = pyo.Var( - within=pyo.NonNegativeReals, - initialize=1 / (f(k_0, h_0) - delta_h * h_0 - delta_k * k_0), - ) # \mu(0) = 1/c(0) - m.mu_h_0 = pyo.Var( - within=pyo.NonNegativeReals, - initialize=1 / (f(k_0, h_0) - delta_h * h_0 - delta_k * k_0), - ) # \mu(0) = 1/c(0) - - # defining the integrated kernel functional approximation - def k(m, i): # x_k(t): physical capital k(t) - return k_0 + sum(K_tilde[i, j] * m.alpha_k[j] for j in m.I) - - def h(m, i): # x_h(t): human capital h(t) - return h_0 + sum(K_tilde[i, j] * m.alpha_h[j] for j in m.I) - - def i_k(m, i): # y_k(t): investment in physical capital i_k(t) - return m.i_k_0 + sum(K_tilde[i, j] * m.alpha_i_k[j] for j in m.I) - - def i_h(m, i): # y_h(t): investment in human capital i_h(t) - return m.i_h_0 + sum(K_tilde[i, j] * m.alpha_i_h[j] for j in m.I) - - def c(m, i): # y_c(t): consumption, c(t) - return m.c_0 + sum(K_tilde[i, j] * m.alpha_c[j] for j in m.I) - - def mu_k(m, i): # \mu(t): co-state variable - return m.mu_k_0 + sum(K_tilde[i, j] * m.alpha_mu_k[j] for j in m.I) - - def mu_h(m, i): # the transversality variable for physical capital - return m.mu_h_0 + sum(K_tilde[i, j] * m.alpha_mu_h[j] for j in m.I) - - # defining the derivatives of the variables - def dk_dt(m, i): # \dot{x}_k(t) : derivative of the physical capital - return sum(K[i, j] * m.alpha_k[j] for j in m.I) - - def dh_dt(m, i): # \dot{x}_h(t) : derivative of the human capital - return sum(K[i, j] * m.alpha_h[j] for j in m.I) - - def dmu_k_dt(m, i): - return sum(K[i, j] * m.alpha_mu_k[j] for j in m.I) - - def dmu_h_dt(m, i): - return sum(K[i, j] * m.alpha_mu_h[j] for j in m.I) - - # defining constraints and objective for model and solve - @m.Constraint(m.I) # for each index in m.I - def dk_dt_constraint(m, i): - return dk_dt(m, i) == i_k(m, i) - delta_k * k(m, i) - - @m.Constraint(m.I) # for each index in m.I - def dh_dt_constraint(m, i): - return dh_dt(m, i) == i_h(m, i) - delta_h * h(m, i) - - @m.Constraint(m.I) # for each index in m.I - def dmu_k_dt_constraint(m, i): - return dmu_k_dt(m, i) == -mu_k(m, i) * ( - f_k(k(m, i), h(m, i)) - delta_k - rho_hat + K = np.asarray((K + K.T) / 2) + K_tilde = np.asarray(K_tilde) + K_jax = jnp.asarray(K) + K_tilde_jax = jnp.asarray(K_tilde) + + h_0_jax, c_0_init_jax, initial_residual, _ = human_capital_initial_conditions( + a_k, a_h, delta_k, delta_h, k_0 + ) + h_0 = float(h_0_jax) + c_0_init = float(c_0_init_jax) + + n_functions = 7 + n_scalars = 5 + n_variables = n_functions * n_train + n_scalars + n_equalities = 7 * n_train + n_constraints = 14 * n_train + x_initial = np.zeros(n_variables, dtype=np.float64) + scalar_start = n_functions * n_train + x_initial[scalar_start] = delta_k * k_0 + x_initial[scalar_start + 1] = delta_h * h_0 + x_initial[scalar_start + 2] = c_0_init + x_initial[scalar_start + 3] = 1.0 / c_0_init + x_initial[scalar_start + 4] = 1.0 / c_0_init + + def unpack(x): + alpha_k = x[:n_train] + alpha_h = x[n_train : 2 * n_train] + alpha_i_k = x[2 * n_train : 3 * n_train] + alpha_i_h = x[3 * n_train : 4 * n_train] + alpha_c = x[4 * n_train : 5 * n_train] + alpha_mu_k = x[5 * n_train : 6 * n_train] + alpha_mu_h = x[6 * n_train : 7 * n_train] + i_k_0 = x[7 * n_train] + i_h_0 = x[7 * n_train + 1] + c_0 = x[7 * n_train + 2] + mu_k_0 = x[7 * n_train + 3] + mu_h_0 = x[7 * n_train + 4] + return ( + alpha_k, + alpha_h, + alpha_i_k, + alpha_i_h, + alpha_c, + alpha_mu_k, + alpha_mu_h, + i_k_0, + i_h_0, + c_0, + mu_k_0, + mu_h_0, + ) + + def path_values(x, K_eval, K_tilde_eval): + ( + alpha_k, + alpha_h, + alpha_i_k, + alpha_i_h, + alpha_c, + alpha_mu_k, + alpha_mu_h, + i_k_0, + i_h_0, + c_0, + mu_k_0, + mu_h_0, + ) = unpack(x) + k = k_0 + K_tilde_eval @ alpha_k + h = h_0 + K_tilde_eval @ alpha_h + i_k = i_k_0 + K_tilde_eval @ alpha_i_k + i_h = i_h_0 + K_tilde_eval @ alpha_i_h + c = c_0 + K_tilde_eval @ alpha_c + mu_k = mu_k_0 + K_tilde_eval @ alpha_mu_k + mu_h = mu_h_0 + K_tilde_eval @ alpha_mu_h + dk_dt = K_eval @ alpha_k + dh_dt = K_eval @ alpha_h + dmu_k_dt = K_eval @ alpha_mu_k + dmu_h_dt = K_eval @ alpha_mu_h + return k, h, i_k, i_h, c, mu_k, mu_h, dk_dt, dh_dt, dmu_k_dt, dmu_h_dt + + def production_terms(k, h): + k_positive = jnp.maximum(k, DOMAIN_EPS) + h_positive = jnp.maximum(h, DOMAIN_EPS) + f = (k_positive**a_k) * (h_positive**a_h) + f_k = a_k * (k_positive ** (a_k - 1.0)) * (h_positive**a_h) + f_h = a_h * (k_positive**a_k) * (h_positive ** (a_h - 1.0)) + return f, f_k, f_h + + def objective(x): + ( + alpha_k, + alpha_h, + alpha_i_k, + alpha_i_h, + alpha_c, + alpha_mu_k, + alpha_mu_h, + *_, + ) = unpack(x) + return ( + alpha_k @ K_jax @ alpha_k + + alpha_h @ K_jax @ alpha_h + + alpha_i_k @ K_jax @ alpha_i_k + + alpha_i_h @ K_jax @ alpha_i_h + + alpha_c @ K_jax @ alpha_c + + alpha_mu_k @ K_jax @ alpha_mu_k + + alpha_mu_h @ K_jax @ alpha_mu_h ) - @m.Constraint(m.I) # for each index in m.I - def dmu_h_dt_constraint(m, i): - return dmu_h_dt(m, i) == -mu_h(m, i) * ( - f_h(k(m, i), h(m, i)) - delta_h - rho_hat + def constraints(x): + ( + k, + h, + i_k, + i_h, + c, + mu_k, + mu_h, + dk_dt, + dh_dt, + dmu_k_dt, + dmu_h_dt, + ) = path_values(x, K_jax, K_tilde_jax) + f, f_k, f_h = production_terms(k, h) + equalities = jnp.concatenate( + [ + dk_dt - (i_k - delta_k * k), + dh_dt - (i_h - delta_h * h), + dmu_k_dt + mu_k * (f_k - delta_k - rho_hat), + dmu_h_dt + mu_h * (f_h - delta_h - rho_hat), + c + i_h + i_k - f, + mu_k * c - 1.0, + mu_k - mu_h, + ] ) + positive_domains = jnp.concatenate([k, h, i_k, i_h, c, mu_k, mu_h]) + return jnp.concatenate([equalities, positive_domains]) + + def lagrangian(x, objective_multiplier, multipliers): + return objective_multiplier * objective(x) + jnp.dot(multipliers, constraints(x)) + + objective_value = jax.jit(objective) + objective_gradient = jax.jit(jax.grad(objective)) + constraint_values = jax.jit(constraints) + constraint_jacobian = jax.jit(jax.jacfwd(constraints)) + lagrangian_hessian = jax.jit(jax.hessian(lagrangian, argnums=0)) + + x_initial_jax = jnp.asarray(x_initial) + zero_multipliers = jnp.zeros(n_constraints, dtype=jnp.float64) + jax.block_until_ready(objective_value(x_initial_jax)) + jax.block_until_ready(objective_gradient(x_initial_jax)) + jax.block_until_ready(constraint_values(x_initial_jax)) + jax.block_until_ready(constraint_jacobian(x_initial_jax)) + jax.block_until_ready(lagrangian_hessian(x_initial_jax, 1.0, zero_multipliers)) + + variable_lower_bounds = np.full(n_variables, -np.inf, dtype=np.float64) + variable_upper_bounds = np.full(n_variables, np.inf, dtype=np.float64) + variable_lower_bounds[scalar_start:] = DOMAIN_EPS + constraint_lower_bounds = np.concatenate( + [ + np.zeros(n_equalities, dtype=np.float64), + np.full(7 * n_train, DOMAIN_EPS, dtype=np.float64), + ] + ) + constraint_upper_bounds = np.concatenate( + [ + np.zeros(n_equalities, dtype=np.float64), + np.full(7 * n_train, np.inf, dtype=np.float64), + ] + ) + + model = unopy.Model( + unopy.PROBLEM_NONLINEAR, + n_variables, + variable_lower_bounds, + variable_upper_bounds, + unopy.ZERO_BASED_INDEXING, + ) - @m.Constraint(m.I) # for each index in m.I - def feasibility(m, i): - return 0.0 == c(m, i) + i_h(m, i) + i_k(m, i) - f(k(m, i), h(m, i)) - - @m.Constraint(m.I) # for each index in m.I - def shadow_price(m, i): - return mu_k(m, i) * c(m, i) - 1.0 == 0.0 - - @m.Constraint(m.I) # for each index in m.I - def b_h_constraint(m, i): - return mu_k(m, i) - mu_h(m, i) == 0.0 - - @m.Objective(sense=pyo.minimize) - def min_norm(m): # alpha @ K @ alpha not supported by pyomo - # Core RKHS norms - core = ( - sum(K[i, j] * m.alpha_mu_k[i] * m.alpha_mu_k[j] for i in m.I for j in m.I) - + sum(K[i, j] * m.alpha_k[i] * m.alpha_k[j] for i in m.I for j in m.I) - + sum(K[i, j] * m.alpha_mu_h[i] * m.alpha_mu_h[j] for i in m.I for j in m.I) - + sum(K[i, j] * m.alpha_h[i] * m.alpha_h[j] for i in m.I for j in m.I) + def objective_callback(x): + return float(objective_value(jnp.asarray(x))) + + def objective_gradient_callback(x, gradient): + gradient[:] = np.asarray(objective_gradient(jnp.asarray(x))) + + model.set_objective( + unopy.MINIMIZE, objective_callback, objective_gradient_callback + ) + + jacobian_rows = np.repeat(np.arange(n_constraints, dtype=np.int32), n_variables) + jacobian_columns = np.tile(np.arange(n_variables, dtype=np.int32), n_constraints) + + def constraints_callback(x, constraint_output): + constraint_output[:] = np.asarray(constraint_values(jnp.asarray(x))) + + def jacobian_callback(x, jacobian_output): + jacobian_output[:] = np.asarray( + constraint_jacobian(jnp.asarray(x)) + ).reshape(-1) + + model.set_constraints( + n_constraints, + constraints_callback, + constraint_lower_bounds, + constraint_upper_bounds, + len(jacobian_rows), + jacobian_rows, + jacobian_columns, + jacobian_callback, + ) + + hessian_rows, hessian_columns = np.tril_indices(n_variables) + hessian_rows = hessian_rows.astype(np.int32) + hessian_columns = hessian_columns.astype(np.int32) + + def hessian_callback(x, objective_multiplier, multipliers, hessian_output): + hessian = np.asarray( + lagrangian_hessian( + jnp.asarray(x), + float(objective_multiplier), + jnp.asarray(multipliers), + ) ) - # Small smoothing/regularization on variables that only appear via constraints - reg = ( - sum(K[i, j] * m.alpha_i_k[i] * m.alpha_i_k[j] for i in m.I for j in m.I) - + sum(K[i, j] * m.alpha_i_h[i] * m.alpha_i_h[j] for i in m.I for j in m.I) - + sum(K[i, j] * m.alpha_c[i] * m.alpha_c[j] for i in m.I for j in m.I) + hessian_output[:] = hessian[hessian_rows, hessian_columns] + + model.set_lagrangian_hessian( + len(hessian_rows), + unopy.LOWER_TRIANGLE, + hessian_rows, + hessian_columns, + hessian_callback, + ) + model.set_lagrangian_sign_convention(unopy.MULTIPLIER_POSITIVE) + model.set_initial_primal_iterate(x_initial) + + solver = unopy.UnoSolver() + options = dict(NLP_OPTIONS) + solver.set_preset(options.pop("preset")) + if not verbose: + solver.set_option("logger", "SILENT") + solver.set_option("print_solution", False) + for option_name, option_value in options.items(): + solver.set_option(option_name, option_value) + + start = time.perf_counter() + result = solver.optimize(model) + elapsed = time.perf_counter() - start + + x = jnp.asarray(np.array(result.primal_solution, dtype=np.float64)) + ( + alpha_k, + alpha_h, + alpha_i_k, + alpha_i_h, + alpha_c, + alpha_mu_k, + alpha_mu_h, + i_k_0, + i_h_0, + c_0, + mu_k_0, + mu_h_0, + ) = unpack(x) + rkhs_norms = { + "k": rkhs_norm_squared(alpha_k, K), + "h": rkhs_norm_squared(alpha_h, K), + "i_k": rkhs_norm_squared(alpha_i_k, K), + "i_h": rkhs_norm_squared(alpha_i_h, K), + "c": rkhs_norm_squared(alpha_c, K), + "mu_k": rkhs_norm_squared(alpha_mu_k, K), + "mu_h": rkhs_norm_squared(alpha_mu_h, K), + } + + def evaluate_grid(points_data): + K_eval, K_tilde_eval = integrated_matern_kernel_matrices( + points_data, train_data, nu, sigma, rho ) - return core + lambda_p * reg - - solver = pyo.SolverFactory(solver_type) - # IPOPT tends to be more robust with adaptive barrier, reasonable tolerances, and without hard bound relaxation = 0 - options = { - "tol": 1e-8, - "dual_inf_tol": 1e-8, - "constr_viol_tol": 1e-8, - "acceptable_tol": 1e-6, - "mu_strategy": "adaptive", - "print_level": 5 if verbose else 3, - "max_iter": 4000, - # "bound_relax_factor": 1e-8, # keep tiny but nonzero; disabling can sometimes trigger restoration failures + ( + k_values, + h_values, + i_k_values, + i_h_values, + c_values, + mu_k_values, + mu_h_values, + dk_values, + dh_values, + dmu_k_values, + dmu_h_values, + ) = path_values(x, K_eval, K_tilde_eval) + f_values, f_k_values, f_h_values = production_terms(k_values, h_values) + return { + "k": k_values, + "h": h_values, + "i_k": i_k_values, + "i_h": i_h_values, + "c": c_values, + "mu_k": mu_k_values, + "mu_h": mu_h_values, + "physical_accumulation": dk_values + - (i_k_values - delta_k * k_values), + "human_accumulation": dh_values - (i_h_values - delta_h * h_values), + "physical_euler": dmu_k_values + + mu_k_values * (f_k_values - delta_k - rho_hat), + "human_euler": dmu_h_values + + mu_h_values * (f_h_values - delta_h - rho_hat), + "feasibility": c_values + i_h_values + i_k_values - f_values, + "shadow_price": mu_k_values * c_values - 1.0, + "costate_gap": mu_k_values - mu_h_values, + "hidden_dae_residual": (f_k_values - delta_k) + - (f_h_values - delta_h), + } + + train_eval = evaluate_grid(train_data) + validation_eval = evaluate_grid(validation_data) + test_eval = evaluate_grid(test_data) + + residual_names = [ + "physical_accumulation", + "human_accumulation", + "physical_euler", + "human_euler", + "feasibility", + "shadow_price", + "costate_gap", + ] + train_residuals = {name: train_eval[name] for name in residual_names} + validation_residuals = { + f"{name}_validation": validation_eval[name] for name in residual_names } - try: - results = solver.solve(m, tee=verbose, options=options) - except Exception as e: - # Retry once with slightly relaxed settings if the first attempt failed before loading solutions - if verbose: - print( - f"First solve attempt failed: {e}. Retrying with relaxed tolerances..." - ) - options_retry = dict(options) - options_retry.update( - { - "tol": 1e-6, - "dual_inf_tol": 1e-6, - "constr_viol_tol": 1e-6, - "acceptable_tol": 1e-4, - } + max_train_residual = max( + float(jnp.max(jnp.abs(residual))) for residual in train_residuals.values() + ) + max_validation_residual = max( + float(jnp.max(jnp.abs(residual))) for residual in validation_residuals.values() + ) + finite_positive = bool( + all( + jnp.all(jnp.isfinite(test_eval[name])) + and jnp.all(jnp.isfinite(validation_eval[name])) + and jnp.min(test_eval[name]) > 0.0 + and jnp.min(validation_eval[name]) > 0.0 + for name in ["k", "h", "i_k", "i_h", "c", "mu_k", "mu_h"] ) - results = solver.solve(m, tee=verbose, options=options_retry) - if not results.solver.termination_condition == TerminationCondition.optimal: - print(str(results.solver)) # raise exception? - - alpha_c = jnp.array([pyo.value(m.alpha_c[i]) for i in m.I]) - alpha_k = jnp.array([pyo.value(m.alpha_k[i]) for i in m.I]) - alpha_h = jnp.array([pyo.value(m.alpha_h[i]) for i in m.I]) - alpha_i_k = jnp.array([pyo.value(m.alpha_i_k[i]) for i in m.I]) - alpha_i_h = jnp.array([pyo.value(m.alpha_i_h[i]) for i in m.I]) - alpha_mu_k = jnp.array([pyo.value(m.alpha_mu_k[i]) for i in m.I]) - alpha_mu_h = jnp.array([pyo.value(m.alpha_mu_h[i]) for i in m.I]) - - c_0 = pyo.value(m.c_0) - i_k_0 = pyo.value(m.i_k_0) - i_h_0 = pyo.value(m.i_h_0) - mu_k_0 = pyo.value(m.mu_k_0) - mu_h_0 = pyo.value(m.mu_h_0) - - # Interpolator using training data - # @jax.jit - def kernel_solution(test_data): - # pointwise comparison test_data to train_data + ) + + @jax.jit + def kernel_solution(test_points_data): K_test, K_tilde_test = integrated_matern_kernel_matrices( - test_data, train_data, nu, sigma, rho + test_points_data, train_data, nu, sigma, rho ) - c_test = c_0 + K_tilde_test @ alpha_c - k_test = k_0 + K_tilde_test @ alpha_k - h_test = h_0 + K_tilde_test @ alpha_h - i_k_test = i_k_0 + K_tilde_test @ alpha_i_k - i_h_test = i_h_0 + K_tilde_test @ alpha_i_h - mu_k_test = mu_k_0 + K_tilde_test @ alpha_mu_k - mu_h_test = mu_h_0 + K_tilde_test @ alpha_mu_h - - feasibility_test = c_test + i_h_test + i_k_test - f(k_test, h_test) + ( + k_test, + h_test, + i_k_test, + i_h_test, + c_test, + mu_k_test, + mu_h_test, + *_, + ) = path_values(x, K_test, K_tilde_test) + f_test, _, _ = production_terms(k_test, h_test) + feasibility_test = c_test + i_h_test + i_k_test - f_test return ( k_test, h_test, @@ -265,40 +483,63 @@ def kernel_solution(test_data): feasibility_test, ) - # Generate test_data - ( - k_test, - h_test, - c_test, - i_k_test, - i_h_test, - mu_k_test, - mu_h_test, - feasibility_test, - ) = kernel_solution(test_data) - - print(f"solve_time(s) = {results.solver.Time}") + solve_time = result.cpu_time + if solve_time is None: + solve_time = elapsed + solver_status = str(result.optimization_status).split(".")[-1] + solution_status = str(result.solution_status).split(".")[-1] + rejection_reasons = [] + if solver_status != "SUCCESS": + rejection_reasons.append("solver_status") + if solution_status not in ACCEPTED_SOLUTION_STATUSES: + rejection_reasons.append("solution_status") + if not finite_positive: + rejection_reasons.append("nonfinite_or_nonpositive") + if max_train_residual > 1e-5: + rejection_reasons.append("train_residual") + valid_solution = not rejection_reasons + + print(f"solve_time(s) = {solve_time}") return { "t_train": train_data, "t_test": test_data, - "k_test": k_test, - "h_test": h_test, - "c_test": c_test, - "i_k_test": i_k_test, - "i_h_test": i_h_test, - "mu_k_test": mu_k_test, - "mu_h_test": mu_h_test, - "feasibility_test": feasibility_test, + "k_test": test_eval["k"], + "h_test": test_eval["h"], + "c_test": test_eval["c"], + "i_k_test": test_eval["i_k"], + "i_h_test": test_eval["i_h"], + "mu_k_test": test_eval["mu_k"], + "mu_h_test": test_eval["mu_h"], + "feasibility_test": test_eval["feasibility"], + "hidden_dae_residual_test": test_eval["hidden_dae_residual"], "alpha_c": alpha_c, "alpha_k": alpha_k, "alpha_h": alpha_h, "alpha_i_k": alpha_i_k, "alpha_i_h": alpha_i_h, - "c_0": c_0, - "i_k_0": i_k_0, - "i_h_0": i_h_0, - "solve_time": results.solver.Time, - "kernel_solution": kernel_solution, # interpolator + "alpha_mu_k": alpha_mu_k, + "alpha_mu_h": alpha_mu_h, + "c_0": float(c_0), + "h_0": h_0, + "i_k_0": float(i_k_0), + "i_h_0": float(i_h_0), + "mu_k_0": float(mu_k_0), + "mu_h_0": float(mu_h_0), + "initial_condition_residual": initial_residual, + "rkhs_norms": rkhs_norms, + "train_residuals": train_residuals, + "validation_residuals": validation_residuals, + "max_train_residual": max_train_residual, + "max_validation_residual": max_validation_residual, + "solve_time": solve_time, + "wall_time": elapsed, + "solver_status": solver_status, + "solution_status": solution_status, + "stationarity": result.solution_stationarity, + "primal_feasibility": result.solution_primal_feasibility, + "valid_solution": valid_solution, + "rejection_reason": "accepted" if valid_solution else ",".join(rejection_reasons), + "kernel_solution": kernel_solution, } diff --git a/notebooks/asset_pricing_julia.ipynb b/notebooks/asset_pricing_julia.ipynb deleted file mode 100644 index 75a6436..0000000 --- a/notebooks/asset_pricing_julia.ipynb +++ /dev/null @@ -1,418 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "3a55a9f6", - "metadata": {}, - "outputs": [], - "source": [ - "using Distributions, QuadGK\n", - "using JuMP, OSQP\n", - "using LinearAlgebra\n", - "using Plots" - ] - }, - { - "cell_type": "markdown", - "id": "c36ebd46", - "metadata": {}, - "source": [ - "[FORMULA PLACEHOLDER]" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "fb582b52", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "asset_pricing_baseline (generic function with 1 method)" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "function matern_kernel_0p5(t_i, t_j; sigma, rho)\n", - " d = abs(t_i - t_j)\n", - " return sigma^2 * exp(-d / rho)\n", - "end\n", - "\n", - "function integrated_matern_kernel_0p5(t_i, t_j; sigma, rho)\n", - " s = t_i - t_j\n", - " d = abs(s)\n", - " base = rho * (sigma^2) \n", - " if s < 0\n", - " return base * (exp(-d / rho) - exp(-t_j / rho))\n", - " else\n", - " return base * (2 - exp(-d / rho) - exp(-t_j / rho))\n", - " end\n", - "end\n", - "\n", - "function matrices_matern_kernel_0p5(t, s; sigma, rho)\n", - " K = [matern_kernel_0p5(t[i], s[j]; sigma, rho) for i in 1:length(t), j in 1:length(s)]\n", - " K_tilde = [integrated_matern_kernel_0p5(t[i], s[j]; sigma, rho) for i in 1:length(t), j in 1:length(s)]\n", - " return K, K_tilde\n", - "end\n", - "\n", - "#The function is defined in \"src/asset_pricing_baseline.jl\"\n", - "function asset_pricing_baseline(t, c, g, r, x_0; T_max=2000.0)\n", - " x(s) = (x_0 + c / g) * exp(g * s) - c / g\n", - " discount_x(s) = exp(-r * s) * x(s)\n", - " return [quadgk(discount_x, t_val, T_max)[1] for t_val in t] .* exp.(r .* t)\n", - "end" - ] - }, - { - "cell_type": "markdown", - "id": "44648be2", - "metadata": {}, - "source": [ - "Setting up the parameters" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "1dbccf64", - "metadata": {}, - "outputs": [], - "source": [ - "r = 0.1\n", - "c = 0.02\n", - "g = -0.2\n", - "x_0 = 0.01\n", - "sigma = 1.0\n", - "rho = 10.0\n", - "\n", - "train_T = 40.0\n", - "train_points = 41\n", - "test_T = 50.0\n", - "test_points = 100\n", - "\n", - "verbose = false\n", - "eps_abs = 1e-12\n", - "eps_rel = 1e-12\n", - "max_iter = 5000;" - ] - }, - { - "cell_type": "markdown", - "id": "4d9d9dbf", - "metadata": {}, - "source": [ - "Training and testing grids" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "1505e684", - "metadata": {}, - "outputs": [], - "source": [ - "train_data = range(0, train_T, length=train_points)\n", - "test_data = range(0, test_T, length=test_points);" - ] - }, - { - "cell_type": "markdown", - "id": "4af9e658", - "metadata": {}, - "source": [ - "Kernel matrices and closed-form $x(t)$ solution" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "54743e25", - "metadata": {}, - "outputs": [], - "source": [ - "# Construct kernel matrices using nu=0.5\n", - "K, K_tilde = matrices_matern_kernel_0p5(train_data, train_data; sigma, rho)\n", - "K = Symmetric((K + K')/2) \n", - "N = length(train_data)\n", - "\n", - "x = (x_0 + c / g) .* exp.(g .* train_data) .- c / g;" - ] - }, - { - "cell_type": "markdown", - "id": "49da9439", - "metadata": {}, - "source": [ - "Setting up the QP" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "b82e7c0c", - "metadata": {}, - "outputs": [], - "source": [ - "model = Model(OSQP.Optimizer)\n", - "\n", - "if !verbose\n", - " set_silent(model)\n", - "end\n", - "\n", - "set_attribute(model, \"eps_abs\", eps_abs)\n", - "set_attribute(model, \"eps_rel\", eps_rel)\n", - "set_attribute(model, \"max_iter\", max_iter)\n", - "\n", - "@variable(model, alpha_mu[1:N])\n", - "@variable(model, mu_0 >= 0)\n", - "\n", - "# Objective: minimize alpha' * K * alpha (using dot for symmetric K)\n", - "@objective(model, Min, dot(alpha_mu, K * alpha_mu))\n", - "\n", - "# Constraints: dp/dt = r*p - x(t)\n", - "# where p(t) = mu_0 + K_tilde * alpha and dp/dt = K * alpha\n", - "@constraint(model, K * alpha_mu .== r * (mu_0 .+ K_tilde * alpha_mu) .- x)\n", - "\n", - "optimize!(model)" - ] - }, - { - "cell_type": "markdown", - "id": "dcdfa036", - "metadata": {}, - "source": [ - "Extracting solutions and building the interpolator" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "7488b1d8", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "kernel_solution (generic function with 1 method)" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "alpha = value.(alpha_mu)\n", - "p_0 = value(mu_0)\n", - "solve_time_sec = solve_time(model)\n", - "\n", - "# Kernel solution interpolator\n", - "function kernel_solution(t_test)\n", - " _, K_tilde_test = matrices_matern_kernel_0p5(t_test, train_data; sigma, rho)\n", - " return p_0 .+ K_tilde_test * alpha\n", - "end\n" - ] - }, - { - "cell_type": "markdown", - "id": "5d44ace6", - "metadata": {}, - "source": [ - "Evaluating on the test grid" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "6a3d7fcc", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "solve_time(s) = 0.000927832, E(|rel_error(p)|) = 0.00015457791795277267\n" - ] - } - ], - "source": [ - "p_baseline = asset_pricing_baseline(test_data, c, g, r, x_0)\n", - "p_test = kernel_solution(test_data)\n", - "p_rel_error = abs.(p_baseline .- p_test) ./ p_baseline\n", - "\n", - "println(\"solve_time(s) = $solve_time_sec, E(|rel_error(p)|) = $(mean(p_rel_error))\")" - ] - }, - { - "cell_type": "markdown", - "id": "dc9f0627", - "metadata": {}, - "source": [ - "Plotting the result" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "cb3548fa", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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", - "image/svg+xml": [ - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "p1 = plot(\n", - " test_data,\n", - " p_test,\n", - " label = \"Kernel Approximation\",\n", - " xlabel = \"Time\",\n", - " ylabel = \"Price\",\n", - " legend = :bottomright,\n", - ")\n", - "\n", - "plot!(\n", - " test_data,\n", - " p_baseline,\n", - " linestyle = :dash,\n", - " label = \"Closed-Form Solution\",\n", - ")\n", - "\n", - "vline!(\n", - " p1,\n", - " [40],\n", - " linestyle = :dot,\n", - " color = :black,\n", - " label = \"Extrapolation/Interpolation\",\n", - ")\n", - "\n", - "p2 = plot(\n", - " test_data,\n", - " p_rel_error,\n", - " label = \"Relative error\",\n", - " xlabel = \"Time\",\n", - " yscale = :log10,\n", - " legend = :topleft,\n", - ")\n", - "\n", - "vline!(\n", - " p2,\n", - " [40],\n", - " linestyle = :dot,\n", - " color = :black,\n", - " label = \"Extrapolation/Interpolation\",\n", - ")\n", - "\n", - "plot(p1, p2, layout = (1, 2), size = (800, 350))\n" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Julia 1.12.1", - "language": "julia", - "name": "julia-1.12" - }, - "language_info": { - "file_extension": ".jl", - "mimetype": "application/julia", - "name": "julia", - "version": "1.12.1" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/notebooks/neoclassical_growth_julia.ipynb b/notebooks/neoclassical_growth_julia.ipynb deleted file mode 100644 index e7d7d82..0000000 --- a/notebooks/neoclassical_growth_julia.ipynb +++ /dev/null @@ -1,570 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "03fd1cae", - "metadata": {}, - "outputs": [], - "source": [ - "using QuadGK\n", - "using JuMP, OSQP\n", - "using Ipopt\n", - "using Statistics\n", - "using DifferentialEquations\n", - "using BoundaryValueDiffEq\n", - "using LinearAlgebra\n", - "using Plots" - ] - }, - { - "cell_type": "markdown", - "id": "b2759286", - "metadata": {}, - "source": [ - "[FORMULA PLACEHOLDER]" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "e1dd5722", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "neoclassical_growth_baseline (generic function with 1 method)" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "function matern_kernel_0p5(t_i, t_j; sigma, rho)\n", - " d = abs(t_i - t_j)\n", - " return sigma^2 * exp(-d / rho)\n", - "end\n", - "\n", - "function integrated_matern_kernel_0p5(t_i, t_j; sigma, rho)\n", - " s = t_i - t_j\n", - " d = abs(s)\n", - " base = rho * (sigma^2) \n", - " if s < 0\n", - " return base * (exp(-d / rho) - exp(-t_j / rho))\n", - " else\n", - " return base * (2 - exp(-d / rho) - exp(-t_j / rho))\n", - " end\n", - "end\n", - "\n", - "function matrices_matern_kernel_0p5(t, s; sigma, rho)\n", - " K = [matern_kernel_0p5(t[i], s[j]; sigma, rho) for i in 1:length(t), j in 1:length(s)]\n", - " K_tilde = [integrated_matern_kernel_0p5(t[i], s[j]; sigma, rho) for i in 1:length(t), j in 1:length(s)]\n", - " return K, K_tilde\n", - "end\n", - "\n", - "# The function is defined in \"src/neoclassical_growth_baseline.jl\"\n", - "function neoclassical_growth_baseline(a, delta, r, sigma_crra, k_0, T_max;dt=0.001)\n", - " k_ss = ((delta + r) / a)^(1 / (a - 1))\n", - " c_ss = a * k_ss^a - delta * k_ss\n", - "\n", - " \n", - " function ode!(dy, y, p, t)\n", - " k, c = y\n", - " dy[1] = k^a - c - delta * k\n", - " dy[2] = (c / sigma_crra) * (a * k^(a - 1) - r - delta)\n", - " end\n", - " \n", - " function bc!(residual, y, p, t)\n", - " residual[1] = y[1][1] - k_0\n", - " residual[2] = y[end][1] - k_ss\n", - " end\n", - " \n", - " tspan = (0.0, T_max)\n", - " initial_guess = [k_ss, c_ss]\n", - " bvp = BVProblem(ode!, bc!, initial_guess, tspan)\n", - " \n", - " return solve(bvp, MIRK4(); dt)\n", - "end" - ] - }, - { - "cell_type": "markdown", - "id": "53b10d35", - "metadata": {}, - "source": [ - "Defining the parameters" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "52174187", - "metadata": {}, - "outputs": [], - "source": [ - "a = 1/3\n", - "delta = 0.1\n", - "rho_hat = 0.11\n", - "k_0 = 1.0\n", - "nu = 0.5\n", - "sigma = 1.0\n", - "rho = 10.0\n", - "train_T = 40.0\n", - "train_points = 41\n", - "test_T = 50.0\n", - "test_points = 100\n", - "baseline_T = 60.0\n", - "lambda_p = 0.0\n", - "verbose = false\n", - "tol = 1e-8\n", - "dual_inf_tol = 1e-8\n", - "constr_viol_tol = 1e-8\n", - "max_iter = 2000;" - ] - }, - { - "cell_type": "markdown", - "id": "47d08cd4", - "metadata": {}, - "source": [ - "Traning and testing grids" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "690aded4", - "metadata": {}, - "outputs": [], - "source": [ - "train_data = range(0, train_T, length=train_points)\n", - "test_data = range(0, test_T, length=test_points);" - ] - }, - { - "cell_type": "markdown", - "id": "07f094f5", - "metadata": {}, - "source": [ - "Constructing kernel matrices " - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "de6e1c85", - "metadata": {}, - "outputs": [], - "source": [ - "K, K_tilde = matrices_matern_kernel_0p5(train_data, train_data; sigma, rho)\n", - "K = Symmetric((K + K')/2) # symmetric since train_data both arguments. K_tilde not symmetric\n", - "N = length(train_data);" - ] - }, - { - "cell_type": "markdown", - "id": "7a9d6860", - "metadata": {}, - "source": [ - "Speicfying the JuMP model, variables, and objective" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "ea143e9f", - "metadata": {}, - "outputs": [], - "source": [ - "# Create JuMP model with Ipopt (non-convex problem)\n", - "model = Model(Ipopt.Optimizer)\n", - "if !verbose\n", - " set_silent(model)\n", - "end\n", - "set_attribute(model, \"tol\", tol)\n", - "set_attribute(model, \"dual_inf_tol\", dual_inf_tol)\n", - "set_attribute(model, \"constr_viol_tol\", constr_viol_tol)\n", - "set_attribute(model, \"max_iter\", max_iter)\n", - "\n", - "@variable(model, alpha_mu[1:N])\n", - "@variable(model, alpha_c[1:N])\n", - "@variable(model, alpha_k[1:N])\n", - "@variable(model, c_0 >= 0, start = k_0^a - delta * k_0)\n", - "@variable(model, mu_0 >= 0, start = k_0^a - delta * k_0)\n", - "\n", - "@objective(model, Min,\n", - " dot(alpha_mu, K * alpha_mu) +\n", - " dot(alpha_k, K * alpha_k)\n", - "); " - ] - }, - { - "cell_type": "markdown", - "id": "0f140a46", - "metadata": {}, - "source": [ - "Defining auxiliary variables, nonlinear expressions, and system constraints; solving the model" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "52d93183", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Solving Neoclassical Growth Matern with N=41\n", - "\n", - "******************************************************************************\n", - "This program contains Ipopt, a library for large-scale nonlinear optimization.\n", - " Ipopt is released as open source code under the Eclipse Public License (EPL).\n", - " For more information visit https://github.com/coin-or/Ipopt\n", - "******************************************************************************\n", - "\n" - ] - } - ], - "source": [ - "# Building blocks to preserve sparsity in JuMP's nonlinear model\n", - "# Create auxiliary variables for linear transformations of alpha coefficients\n", - "@variable(model, dk_dt[1:N]) # dk_dt = K * alpha_k (derivative via kernel)\n", - "@variable(model, dmu_dt[1:N]) # dmu_dt = K * alpha_mu (derivative via kernel)\n", - "@variable(model, k_tilde[1:N]) # k_tilde = K_tilde * alpha_k (integrated kernel)\n", - "@variable(model, mu_tilde[1:N]) # mu_tilde = K_tilde * alpha_mu (integrated kernel)\n", - "@variable(model, c_tilde[1:N]) # c_tilde = K_tilde * alpha_c (integrated kernel)\n", - "\n", - "# Linear equality constraints define these auxiliary variables\n", - "@constraint(model, dk_dt .== K * alpha_k)\n", - "@constraint(model, dmu_dt .== K * alpha_mu)\n", - "@constraint(model, k_tilde .== K_tilde * alpha_k)\n", - "@constraint(model, mu_tilde .== K_tilde * alpha_mu)\n", - "@constraint(model, c_tilde .== K_tilde * alpha_c)\n", - "\n", - "# Nonlinear expressions for state and control variables\n", - "@NLexpression(model, mu[i=1:N], mu_0 + mu_tilde[i])\n", - "@NLexpression(model, c[i=1:N], c_0 + c_tilde[i])\n", - "@NLexpression(model, k[i=1:N], k_0 + k_tilde[i])\n", - "\n", - "# System constraints (resource, Euler, shadow price)\n", - "@NLconstraint(model, [i=1:N], dk_dt[i] == k[i]^a - delta * k[i] - c[i])\n", - "@NLconstraint(model, [i=1:N], dmu_dt[i] == -mu[i] * (a * k[i]^(a-1) - delta - rho_hat))\n", - "@NLconstraint(model, [i=1:N], mu[i] * c[i] == 1.0)\n", - "\n", - "println(\"Solving Neoclassical Growth Matern with N=$N\")\n", - "optimize!(model)" - ] - }, - { - "cell_type": "markdown", - "id": "41fb52f4", - "metadata": {}, - "source": [ - "Extracting solutions and evaluating on the test grid" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "596fee91", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "solve_time(s) = 2.217989206314087, E(|rel_error(k)|) = 0.0004391826666156981, E(|rel_error(c)|) = 0.000304995693303921\n" - ] - } - ], - "source": [ - "alpha_c_val = value.(alpha_c)\n", - "alpha_k_val = value.(alpha_k)\n", - "c_0_val = value(c_0)\n", - "solve_time_sec = solve_time(model)\n", - "\n", - "# Kernel solution interpolator\n", - "function kernel_solution(t_test)\n", - " _, K_tilde_test = matrices_matern_kernel_0p5(t_test, train_data; sigma, rho)\n", - " c_test = c_0_val .+ K_tilde_test * alpha_c_val\n", - " k_test = k_0 .+ K_tilde_test * alpha_k_val\n", - " return k_test, c_test\n", - "end\n", - "\n", - "# Baseline solution\n", - "sol_baseline = neoclassical_growth_baseline(a, delta, rho_hat, 1.0, k_0, baseline_T)\n", - "\n", - "function baseline_solution(t_test)\n", - " sol = sol_baseline.(t_test)\n", - " k_baseline = [s[1] for s in sol]\n", - " c_baseline = [s[2] for s in sol]\n", - " return k_baseline, c_baseline\n", - "end;\n", - "\n", - "# Evaluate on test data\n", - "k_baseline, c_baseline = baseline_solution(test_data)\n", - "k_test, c_test = kernel_solution(test_data)\n", - "\n", - "k_rel_error = abs.(k_baseline .- k_test) ./ k_baseline\n", - "c_rel_error = abs.(c_baseline .- c_test) ./ c_baseline\n", - "\n", - "println(\"solve_time(s) = $solve_time_sec, E(|rel_error(k)|) = $(mean(k_rel_error)), E(|rel_error(c)|) = $(mean(c_rel_error))\")" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4a8c7886", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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Xl5eZ4SGEEItImUcZDtbZdDliPQNmM410owYorTPrlDkaWpquvXWWw0Gw4YNG6KiogCgrKxsw4YNNpvtxhtvHDBgAABcuHChoKAgPT3966+/HjcFQkYbAAAgAElEQVRuHKU0KSnp7Nmzv/zyy4gRIyZOnMifilL6/fffHz9+PCsr67bbblOppD4B3bZtG8MwCxYsWLFixahRo/gbd+3alZaWdvjw4bNnz44dO3bkyJEAUFdXt3379uHDh69cuTIuLm7mzJmxsbEAsHfv3oSEhIKCgoMHDz788MMmk2ndunX5+fl9+/a9+eabGYY5duxYbW3t2LFjAcBms23YsGHq1KlqtTojI4O/3MaNG4cOHfrjjz+Wlpbeeuut/fr1++GHH44cOTJu3Lhrr70WANxu9/bt2w8fPswwzI033jhw4EAA2LJlCwCsXbvWYDCMGzcuOjo6+dJaF5Zlv/nmm7Nnzw4aNGjatGmEEAD44YcfcnJyfvzxxwsXLkyePHno0KGd/TtECCmNSUusTo7/WplTZS61yrSrfd/hcHz88cfz5s3rsriULNLfIp1rgMwYuYNA6PJYrdYbbrghNTV1zZo1fNa+d+/e0aNHnzt3zm63T506ddOmTQDw888/z5kz5/7773c6nU1NTX/729/uuOOO1atXcxx31113ffnllwBAKb3jjjv+/ve/a7XaL7744qabbqKUSlx6xYoV995777333rt69WqbzcbfuGTJkmnTpm3cuBEAbrvttpUrVwLA+fPn77nnnlmzZgHAf//73+uuu44v4b/99tu33nrrRx99xHGc0+mcPXv2a6+9plarly5devvttwNAfHz87Nmzd+7cCQCPP/74V199FRMTY7Va7733Xv5yCxYsuOmmm3799dfy8vJRo0Y988wza9ascTgcU6dO5T+LOHXq1HvvvUcIaWhomDx58o8//ggApaWlAFBcXFxYWGi323fv3v3qq6/yz0BeXt6yZcvUavVLL73k6Z9ZsGDBrFmzDh06VF9fP27cuGPHjnX2r1E5KKWfffbZ/Pnz33jjDenXD0LK1mZxqhIr7joVcbC0vQ+toqLitdde67KgFA4r7jQzBgvuqEtsKaPvnuQ6/bTRGvjXWJX3q/bVV18dOnToJ598Qi59evTkk0++8sord911FwBcddVVf/rTn2688UYAqK2tPXLkCF/qfu+994YOHfrhhx8CQGxs7KpVq2bOnLlhw4aioqKDBw8yDPP4448PHTp0x44dfLXbX319/ddff3306NHs7OyrrrpqzZo1v/vd7/gfDRky5N133+WvPm/evDvvvJM/ftmyZUOGDAGA66+//tNPP+XbXfr37//FF18AwJ49e7Zu3VpcXBwdHf3II49kZWVt27Zt/Pjxy5cvv/vuu5988snt27cfPHjQP5I777xz4cKFAHDo0KGysrJ///vf/IP9+uuvR4wYMWjQoFWrVvFHZmdnv/POO5MnT/7d7353//33z58/n18jtWvXLv6AjRs3njx58uzZsxqN5oEHHsjMzPzll1+uueYaAJg+fTp/lcrKyv/85z+DBw/u6O9Q4R555BGNRjNr1qzCwkJKKemCDzVff/31AwcOdPppw5Pb7VarI+g/a47jAIBhZEhyTSbT+++/34knjNdBrWccpBIr7lEqqHW0+8MEjUaj0Wi6LCiFi6C/BYIwcUddZ1A8mZnd+a+uHjrfPOiRRx5Zv379okWLlixZAgAcxx08ePDTTz9du3YtADQ1NZ04caIlpEGD+Kydl5OTw3+RkZFRWVkJAPv376+vr+fzbACora09efKkWOK+cuXKwYMHx8fH19bW3nbbbf/61788ifuYMWP4L66//vrCwsKGhgYAMBqNfNbO33706FH+a76hBQCOHj2am5sbHR0NAFFRUddee+2RI0fGjx+fl5c3derU+fPnHzhwwGg0+kcyfPhw/ouePXt6f338+HH+GViwYMG2bdv0er3dbhc8g8fRo0dHjx7N/6cSFxc3bNiwI0eO8Im799NVVlYmcZJIVlRUtGfPnkOHDtntds/LoNN98803U6dOvcwFygh54zju7rvv7tzE3aQlVselDZg40Cmw4s63yrRvjrvZbPbMVEDthYk75PWSOwikUCl6mJkVir/TGRkZW7dunTBhAgAsWbKEEKLRaBYuXJidnc0f4Cl58o00Hp4yHiGEb2nQaDTDhg3jm0Z4CQkJYtddsWLF8ePHr7jiCv7bhoaGwsJC/qJOZ0uVyeFwMAzD58Eul8tTf3U6nTqdzicqnU7ncrk85/ccY7VaN23alJmZuWXLlmHDhvlH4v1A/Jvy33jjjfr6+mPHjul0um+++ebFF18Ue0R8DJ7g+fg9cUZU1bPDjh49qlKpJk+ezHFcQkLCypUru+h5mzhx4ujRo7vizCgysSx79913d+45TVqocwEFIArtcY9SgYPtyEPDcZAdprh3f+2UWLw3AyvuqPvLzMzcunXrV199tWjRIkLIpEmTNm/enH2JRPLtY9KkSTt27IiOjubv2LNnT0/a6uPUqVOHDx8uKSmpueT222//6KOP+J+uXbuWn7S4Zs2anJwcPjW32+0bNmwAAIfDsX79ev9y7KhRo37++ecLFy4AQFlZ2Y4dO6677joAeOSRR/Ly8n766ac33nijA+NrSktLBw4cqNPpKKWenhmVSsX3yvscfN11123durWqqgoACgoKDh8+7PlAAHmrqqoa3ha/vtnpdJaXl3/33Xdbt24lhHTFcFKEugs1A1EqaHQBQLvL0t1C6xz39qSTbrebXwSFOiCyC0gcu+DYX8jtawEU9y4YRZ7MzEy+IxwA/v73v99xxx3XXnttnz59ioqKevfu/emnnwZzklGjRj311FPDhg0bM2aM0+k8dOjQpk2bBBsSli9fPn36dJPJ5Lnl7rvvfvTRRxcvXgwA0dHR1113Xa9evXbs2MF37ABAQkLCm2+++emnn/76669XX331zTff7HPOfv36/fGPf7z22mvHjBmzc+fOp556avDgwcuWLfv111/37t2r1+uXLVt25513/vLLL+16Zu65557bbrstPz+/uLjYbG7dbe3BBx+8/vrr+/Tp4735dk5OzsMPPzxs2LDRo0dv37795ZdfzsrKatflFIBSevbs2XPnzo0ePdpgMHhur66u3rRpU1RU1JQpUxITEwXXG/Tu3TsjI4N/v9enT5/y8vLQxY1Q+DFpidVJjRqi0MWp4Gh/4l5WVrZgwYIZM2Z0WVyKRpUlPj6+pqZG+pj6+nr+C2dN5f6n7rK7uz4suXkecoRwuVzNzc2hv+6OHTvGjBkT4otaLBar1er5tra2tqCgwO12syx74sSJzZs35+fn8z9qbGwsKyvzHFleXl5XV8d/3dTUVFpa6vlRdXX19u3bd+3a1dDQwN9y4cIFn6e0tLS0trbW+xaXy1VQUOByuW655ZZ//etfxcXFW7du9Rxz7Ngxs9nscrl27tx55MgRjuP42ysqKjxheM68bdu2Cxcu8N+eP3/e+4Di4uKGhga3211UVMTfUlJS4onN+2xWq7WystLzLP33v/8tLCy02Wznz5/3nK2+vr6goMBmszU2NpaXl3tuLykp2bZtm8Vi8b7Fc5Xa2tqLFy/SUHnllVeee+45lmUbGxtDcLmqqqq4uLjExEQAOH36tOf206dPJycn//a3v73xxhsHDRrk81vz4DguNzf3u++++/XXXwcMGHD8+PEgr9vc3BwVFRXwMP6v2ejRo3ft2hXkmREKhtvtVqlUnX7aq75yHa3mKKVj17l+snCCx3Tf/6O/PcfetNH9/kn2oR3tyKUuXLiQkZHRdVGFoU5MSyK64l5dWXVRl9iu4aMIhZvU1FTvb00mk6cKPmDAAH6COy86Oppf98lLSUnxfG0wGLwLqz169Lj++uu9T5uenu5z3bS0NJ9b1Gq1p6seADIzMzMzM/2P4btfPDzT073P7H3ynj17ev/Uc87evXvzX/Tq1bpOxfts3j2UqampnifK+4RGo9GzVtX7yenVq5f3aX2u4v05g/LExsYePXo0PT3dpzf9tddemzVr1t///ndK6Q033PCvf/1r/vz5/ncnhKxbt+6vf/1rTU3NO++8w0/ND15tba13JNLbCCAU/jx7MCm04k4cLOfkSLseWnp6Ot82iTogwhP3i/X6JLmjQEhpbrzxRv/umh49etxzzz2yxIPaRaPRZGRk8EsUvK1bt45fIUAIueOOO77++mvBxB0AUlJSXn/99fZel1LqcDi83/v97ne/e/nll30O4ze75ScGItTp+BFYnSiG0VjqHA3RXLNL67Y7GhoEXrqeLZy7Hc7BNDnVDc0ucENDgzv4OyYkJHT6Ux3O3G632+32nr4gKCoqKuCgzIhO3BurLjqiE+WOAiGleeSRR/xvTEtL60Ayh8KEy+WqqqryfPCSnp7O72DViQghOp3Ou+Iuxmg0yjLkG0UC6XGxHZBoYB0qrdHIuMFtMmqNRuH1qZ1+3dCIb6YuYIlaE6OnRqM+yHtxHLd//37Pdt2RgE/cfQa7dUxE/+1zWKtpbA+5o0CoE2zatGnu3LkzZsxYsGDBjh07+BvNZnNNTU3nXmj27NlfffWVz401NTVPeuHHyXc6juNWrlx5//33z5w586mnnuL3UhUzbdq0LVu2SBxw8OBBt7ulPrR+/fqZM2d2ZqyKw7Isx3GexhWVSuV59iJEQUHBs88+++yzz/7xj398//33pYuFGzduvOWWWyQOOHXqlGeiUUVFhafvK2y9++67/fr169GjB+2krXA3bNjw8MMPA4DL5Tp06JDn9i+++OKZZ57plEuECc/mqYpslYlSd2Rxamlp6Zw5c7oqJqVT3IuoPai1Sm3CVhnU7S1atOjuu+/u06fPnDlzsrKyHn74YT53r6ys7PSOgsbGRu8x5zyr1bp06VKz2ZyRkZGRkeE9uaUTvfzyyy+++OINN9zw+9//3mw2b968WeLgmpoah8MhcUBubq4nc+rfvz+/yywSExUVFR8fz+/SBQAVFRX+ixyUraSk5J///Gd2dnZqaurq1atzcnJsNpvYwQ6HQ/qjgwcffNCzAU1MTMyiRYs6OdxO5XA4nnjiiS1bttTU1HTKPriU0meeeeaxxx4DgOrqau+JqzNmzPjqq69KSkou/yphwnRp81QnC8pbU6djwM6Ci6MaxU26DFsR3SqjbqiKTsBWGdS97dix48033zx27JinrfwPf/iDf0qxa9eurVu3mkymmTNn8stSnU7nqlWrTp06FRMTM3nyZH7D0ebm5lWrVhUXFw8ZMuTWW2/1bJb06aefFhcX33rrrRKRPPLII94rXAFg8+bNu3fvTk5OvvPOO/kFnbt27YqKiqqqqtq+ffvDDz+8devWSZMm/ec//7l48eJdd93Vp0+fVatWnThxYtq0af7T01etWvWnP/1p9uzZADB16lTP7W63e9WqVWfOnBkwYMCMGTN8ljPu2LEjNjaW37G1vLx8586dM2bM4IeLf/LJJzExMXl5eWq12vMJptvtXrly5dmzZwcMGDBz5ky+JeOrr74aOXLk5s2bi4uLp0yZMmrUqGB+NQozfvz4TZs28b+XTZs28YNHI4per587dy4APPTQQ/Hx8fv27eOfhMLCwnXr1tlstv/f3n0HNHH+jwN/MiAJBEjYYYiAYhFZRkDAUa1VHIiKiOIArUrVOqp1VrTu+umwrVWUOnFbrbjqwIUDQQTZSBQU2SOskD3u98fz632vAVEsEAnP66/c8eTu/ZB7Lk+ee8aYMWPwtYFxjx8/fvDggVAoHDBgQGBgIAAgKSmpoqLixo0bFRUVXC7X2dkZFpzU1FSBQID/YzMyMqqrq0eMGAEASElJuX37No1GCwkJURuujSe+ceMGmUwODg6GE5impaWJRCIMw27evDl9+vTs7Gxvb+/bt2+/evVq8+bNTU1Np0+fLikp8fb2HjNmDDzIoUOHxowZc+7cOYVCgQ9gaGpq2rt3L4ZhV69etbW1HT16tEQiOXXqVFFRkYeHR1BQELxLnDhxYtiwYZcvX66trV27di0xNplM9ueffz5//tzS0jI4ONjS0hIuYwwHLsfFxalUKrhe6eTJk42NjSdPnnzgwIHNmze3x4emeSxdUpkIA9o7j7tUBWQqoN+W6qS1tfXhw4c7LCgt161b3PXFNSwz1OKOdG1//vmn2trvNBqNzWYT0+zfvz8sLMzQ0PDly5ceHh7FxcUAgIULF/75559OTk40Gi0+Ph4A0NTU5OPj8/jxYysrq+joaLyr+sSJE8+dO2dra7tmzZrs7Oy3RQJH3sjlctjMv2XLlq+++srExCQ1NdXT0xM2b585c2batGlHjx41MzNTKBQrV64MDg4WCARNTU3+/v4LFy589uyZnp5eQEBA8xNZWlqeO3cOBo/DMGz06NHHjx+3sLDYt29f84mBT5w4cf36dfj65cuXmzZtAgA0NjYCAOrr6+vq6uRy+dOnT3/66Sd4tICAgJMnT6odbdOmTRMnTnz16hWdTh89evTTp0/f56PpulasWAG7MURFRUVGRkokEgDAqlWrfvrpp61bt3799dd3796NjIzUdJgaI5VKlUolnHUnISFh+PDhIpFIX19/woQJ+MWG+/XXX2k0mpWV1ZYtW9atWwcAEIvFCoVCKBTW1dVJJJL6+npY1oRCYUREBP6UbOXKlYWFhQCA6Ojo8PBwJpPZ2Njo6+v76tUrtVMcP348JCREV1dXLpcPHjwYlp2rV6/Onj37xx9/NDU1VSqVW7ZsGTt2bG5urpGRkVgs9vHxuXfvnoWFxdq1a1esWAGPs2TJkvHjx/P5fOIMSyqVqqGhAQBQV1cHZ2IdMmTIlStXLCwsduzYMXfuXJhs9erV48aNKy4uVuurLZFI/Pz8/vzzTxsbm6qqqoSEBBgb3r8Zdjqqq6urq6uDeR82bJg2TTnyf11ltHLlVCpJosDamjUymezt7d1hQWm5btzijmFG0jpdi/ddURJB2kqS91Rw9/z7pCRRqSYR35J01YetyN7wGq6oN0uQ6QyT2VHgnwfWRUVFxIk4mlOpVOvWrbtw4cKQIUMAAA0NDT/99NMvv/ySnJy8a9cu2J4H/f77766urvv37wcAzJw5s0ePHhs2bHj9+vWzZ89ev36tq6s7bdo0tUkSifD5Jbdt2zZ37tzt27c/e/bsk08+AQCMHTt27969sNZiZ2d38uRJ/F2LFi2Cs83cvn2bwWDs3LkTAMDj8a5cudKvXz/i8ffs2TNv3jw4y+SYMWOioqIsLS3j4+Pz8/MLCgp0dHTCw8Pt7OwSExP9/Pxa+YfA3IWHhy9ZsgTOVo5XxG/cuPHixYuXL1/iR3v8+DFsXw8LC1u+fDkAoLy8PC4ubsCAAa2foktzd3eXSCR4HuFjh4EDBz548OD8+fNmZmapqakfVVeZybeVDbL26XtNtKwfZazt/zWRNjU1rVmzRi6Xx8fHT5w4EV5mK1as2LVr18SJEwEAjo6O27ZtCwgIIB7k9OnT8EVgYKCLi8v27duHDRtmY2MzadIkuAZZWVkZTDB48GAqlZqQkDBs2LDS0tLExMSzZ8/Ck2ZkZMB+8CQS6ddff/3ll1/w48PW8bt377q6ugIA9PT0fvrpJ9icqaenFxcXh3duCQ0NXb9+PQAgOjqazWbDRdnGjRvn5OS0YsUK+IEuW7ZMrduYoaHhwoULd+3aBbuenzp1SiwWnzt3jkQiTZkyxc7ObuXKlbCYz507t/nA9D/++AOGQdyZlZWFjyqZOXPmt99+S+zX7uTklJWVhWFYu3TL0TiWrlZPB0n+/y3ubc3amzdvXFxcOiYoLdd9K+5KQV0Dhelg+I5pdxDkg+n2cDIcMeW9klKoJB1a8906FrbNj0DSpQPC9xmDwWh9nBxcoQnv3TF48GBYb16yZElQUJCvr+/o0aPnzp1rZGSUlpaWnp7++eefw5RSqZTH47148YLL5erq6gIAmEymm5sb/Ovs2bNh8xhsqwYA8Pl8vKtMWlqagYEB/DqHJ83MzISvvby8iOHhXQs4HA7+2srKqrq6Wi0jffr0uX//fmVl5aNHj37++efhw4dnZWXBDgBw/iw9PT0ul5udnf3Oivvb5OTk+Pj44Efr379/dnY2/Nd5enrCNNbW1rAdVIvNmjWrxf1ubm74BfBR+caV3PSOadY+hIfJvyqOZDKZzWbLZDKpVDp06FAymaxQKDIzM3/++ee9e/cCAMRicX5+vtpBNm/efPz4cTKZzGQy6+vrm5qamExmi6cjkUizZs06evTosGHDYmNjg4KCWCxWWlqaWCyeN28eTNN8dEFRUVFtbS38VQkA4PP5cNlaAICXlxex7osXvZycHHw5BVtbWxsbm7y8PHjYd7aD5uTk+Pn5wcOamJjANbZgSW/xvc+ePSO2DkACgYDYqK+GyWTC1WrUut51USwaqV6mAlpacadTgOSDBqeOHTv29evXHRWWVuu+FXdBTU2ljqkHqrcjHYasb0hz8vwvRyDRGO88gpeX16FDh1Qq1dsmyGMwGCqVSiaTwfoo/nU4b9680NDQ+Pj4AwcOnDx5MjU1lU6nBwUFwT4SEIfDKSkpgT0lIPz1+PHj4fwSenp6sOeJ2kklEgneZkb8DsZrFRDeJZ1EIhFfvy2/FhYWkyZNGjhwoLW19atXr/T09IjhNf+yp1Ao+JTkrYwmhFo5GloJ6GM20Lwzmmb19PRgw3BYWJinp+enn376ySef6Orqbtq0CZ8WRq0YxsfHnz59+unTp4aGhrW1tSYmJs0nyCcKDw93dXXdvXt3bGzsr7/+CgCg0+l0On3fvn14oWAw/jXpHp1Op1Aou3fvhr+uAaGIqZU1fBMWT3y/WCzGj6n2luba+l49Pb3m5c7MzKyVCa9gXx3tqLUDQou7XKWFXWVoFCBVAmkbu8oolcrWCwLSCq379ffeqiurGxhoZCrS5UVERPD5/I0bN+JdYy9fvow3bwMAjI2NXV1dT5w4AQCQy+WnTp0aOnQoAIDP5xsaGgYHB//+++95eXkqlWrUqFHXrl0zMzNzcHBwcHBgsVg0Gs3X1zc5ORn2LM/Pz8cnbps4ceKkSZMmTZrU4vero6OjoaEhHAMKH6zDk/4Xt27dwlevyMjI0NHRsbS0HDRo0P3790tKSgAAL168SE1NVWtu79Gjx7Nnz+Dr8+f/r+cSi8VqXnUYNGhQQkICnKGcx+OlpaV9cOM9osUcHR0jIiI2bNhAJpNHjhx59epVh3+o9fCurKy0sLAwNDQEAMTGxuL7W7z8AAB2dnZeXl6rV68WCASfffYZAKB3797m5ubJycnw+Pb29ngFHbK2tnZ2dr579y4ewzvnih4yZMilS5fgk7o7d+6IxWLYzeZ9DB069Nq1a3w+HwCQmpr65s0btWdoakaOHHn69Gl8jh04J9WAAQOysrLgHiMjI4VCQfzxn5mZ6ePj857xfPxgH3e5ClBIQBu6/vwbmQQoJCBUtK3F3crK6ueff+6woLRc921xr28UCpgW706HIB83ExOTmzdvzpw58+DBg05OTq9fv7awsIArXOL++OOPkJCQ8+fPFxcX29vbw36oAwcO5HA4lpaWaWlp3377LZlMDgsLg73Svby8GhoaCgoKCgoKHBwcoqKivL29vb29y8rKmk+a0SJdXd1Dhw5FRETExMTk5+f7+vr+9/kWd+3aNW3atH79+slksry8vOjoaCaT2a9fv2+//dbb25vL5aakpHz//fdqPf7Dw8Ojo6MHDx4slUrxrjsAgEWLFg0ePNjW1nbPnj34TldX17Vr13p5ecGj7dy5E07QgSBq1q5d26tXr4yMjN9//z00NNTd3b1Xr16FhYVcLvfAgQN4srFjx27evPnTTz+lUqn48lUAgDlz5kRGRv72228LFiwYO3Ys8cgRERGzZs1au3YtfMijo6Nz6tSp6dOn79u3j81m5+XlLV26dNGiRcS3nDx5MjQ09NixY+bm5vn5+fDtrQQfGBh47do1V1dXFxeX1NTUAwcOvP/qP4MGDfriiy/c3d09PT2fPHmyZ88es1bneBg/fvyjR49cXFx8fHzKysoiIiIWLFgQEhISEBAAnxMyGIy5c+c6OztzOJwzZ844Ojpeu3at+SjzrotFI9XLMK3sJwPRKaBR1rYJc6hUqtpQEKQNMO3CZrNra2tbT9PY2Ihh2JHnitl3JJ0SlObBLHcfsH9k55/3wYMHgwYN6vzzQjwe7+HDh2/evMH3VFZWqlQq+FosFqemphYWFuJ/VSgU2dnZDx8+rKysJB6Hz+c/fvw4JydHoVDgO0tLSx8/fiyRSAQCgVQqVTu1QqGoqKhoHpJQKExJSSGGJBQKiR9NfX09fhbikUUiEZzJTk1VVVViYmJ6erpAICDur6mpSUpKIpZ9OI87ftLk5OSSkhK5XN7Q0ICnkUqltbW1MplMIpHU1dW1crSGhga5XA5fi8VioVDYPLaOs3379rVr1yqVyqamps48bycTi8V0Ov2dyeDdzM/P79GjRx0f1P+Ry+XEiwTDsIaGBngxq1SqV69ePXr0qLi4GP5JIpHg149YLE5KSuLxeBiG1dbW4kVSqVTW1taKxWKlUkksgwqFgnj14mfPy8tLTEzk8/kthqdQKHg83qNHj6qqqvDzEi9U4jUMlZaWPnnyhPjtUFdXp1Qqmx9cqVSq5b2ioiI5Obm+vh7fQyzLzVVXVycmJhLvP2PGjLl+/Tq+Cf9jCoWCz+c7ODho5DtLoVBQKJT2P6wKox6U1UgwdqzsbWm69He06THZwIvyS0UtXDmtwAtLN9GO1ZLu2+JeIiZxDLpv9hHt07t37969exP3mJub46/pdHr//v2Jf6VQKC0O6jc2Nm4+h7qVlRUcu9ZiN1YKhYJPKUOkp6enNvuKWr8aIyMj/DVxxJ5aL16cmZlZi817JiYmJib/miGKOCGmnp4ePmwOdlqAdHV1m3cLbvFoxHe1y5rVSJdDpVLhWgQ4/KogkUg9e/Ykrn5Ko9HwK4pOp+MdP4iXJRzqCl8TiyqFQlGbzhWenfi8qOwumQkAACAASURBVDkKhaJ2B1C7UInXMIQXapxaBomhqv3JwsJCrcgTy3JzpqamcAYn3A8//HDlypVRo0bBTfw/lpSUtH379vd/AvDxo5AAgwL4EoymtS3upEYZaFOLe3l5+dChQwsKCjouKi3WfWuupUKsH1v7+pshCIIgyMeub9++cAEmNfhqUNqETSNVioEuRTurHHQKEMjbNjhVLpc3X4EbeU9a+gPwPZSKgPVbZ6NCEARBEARpByxdUCXGtLWPO40CGuVty52FhcWqVas6LCItp6XX0XsoEWI2+tr58xfpVvbs2bOAYNeuXW9Lyefznzx50nGRhISE4GvNNCcUCu/fv49vbt++/YNv3IcOHUpJSXnw4AE+hXyLioqK8vLyPuwU78Pd3R2fY6e5qqqq1NRUfDMiIoI4ZhHpcng83oJ/KyoqelvipKQkfB6Vdvfo0aPWJ11JT08vLy+Hr8ViMZPJ/LDWzdLS0m3btgEAli9f3vraBcQZn9rd4cOH37awAJSYmIhPSpORkaG2cNvHwEgXVEuAjpZWuOgU0CRv29BbGo0WERHRUQFpOy29jt5DqRCzRhV3pOu7cuVKTU1N/384OTm9LeXTp0+/+uqrjotELBa38uVdVFQUGhqKbwYEBMDFJtsKw7BNmzZZWVnl5ORcuHChlZRnzpzp0BnHhEJhK1MRP3z48JtvvsE3Z82ahS95g3RFpaWlJ06c6E/QykTjX375ZXp6egdFolQqW1+RICoqKj4+Hr7W1dXdtWsXlfoh3WLPnz8P56w8cOBARUVFKyk///zz1peB+y/gqL5WEoSHhz9//hy+trGxiYqK6qBIPhjsKkPTukncIRoFKDEtnKL+o9VN+7jLVaBeBszRGDNEK/j4+OALK0K3bt2i0+mDBg0CALx+/TohIWHq1KnXrl2rrq6OiYkhkUjz5s27ffu2hYVFRkZGSkpKVFRUdXX1lStXysvL7ezsZs+eDQeHpaSkKBSKysrKBw8eeHh4zJgxA64Co1Qqjx8/npOT4+joGB4erjYMrr6+/sKFC9nZ2SwWa9KkSXAIbFxcnEgkiomJAQDMmDFDLpfjtfza2tqjR49WVlb6+PjgtfmYmJjAwMCjR482NDRMmzYNX7AzLS2Nw+EQZ9ZrMXF5eXlycnJVVVVMTIypqemkSZMAAA8ePLh58yaDwZg6dSqcNTIpKYlCoZSXl9+5c2fp0qUvX760srJKSkrKz88fOnQoPk+fUCg8cuRIUVGRu7v7tGnT1BbZKSsru3DhQmFhoZmZ2cyZM62trUUiUXx8fFlZWUxMjK6ubkREhEwmUygUMP2rV6/OnDkjEAhGjRo1ZMgQ+B+7dOnS0KFDDx48SCaTv/jiC1tb2/92USDtj06nqxW0mpqauLi4mTNnwoGVZ86ccXV15fP5fD7/ypUrL168GDhwoJWV1c2bN728vGJjY/v16zd+/PiLFy+mp6fr6OiMGTMGrssrk8mOHDkyevToQ4cOkUikmTNn4vOQZmZmxsXFYRg2fvx4fPle3MOHD+/evdvQ0ODu7h4WFkahUJ49e1ZUVHTv3j2JROLq6url5QXnsoDp//777wcPHpiYmMyYMcPS0hIAkJycDADg8/m3b992dnaePXs2vtbYxYsXN27cSDxdi4nj4uIAAEePHtXX1x87dqy1tXVdXd3x48dLSkq8vLyCg4NJJJJYLD5x4gTMoJmZ2aRJk+7cuePq6nrs2DETE5M5c+bgw8Hv379/48YNAwOD0NBQtclYMQz7+++/k5OTpVLpoEGDAgMDAQB3795tbGyMi4tLT08fPHiwqakpvj6USqU6depURkaGnZ1dREQEXKv1xo0bdnZ2T548yczM9PX1DQ4O/g9XxPti6YJqidZ2laFTAABta3GvqqoaPnx4dnZ2B4Wk3bT0OnqXsoqazxV5bRkDjSAfL5lM1vQP+Ezc0tJy0qRJeXl5Uqk0ODi4qamp+VqkBw8eDAoKSk5O7tOnDwDgr7/+IpPJXl5e2dnZgwcPhm3Jly5dCg0NvXz5soeHR3R09NKlS+F7g4ODjx8/3q9fv1u3bg0dOlSt4fnp06c8Hq9///4MBmPYsGHE1aBw165dg8sh1dfX9+/fv6CgoE+fPps3b165ciVM8OWXX4aFhRkYGMBfIHiD38WLF4OCgtSO9rbERLt27frqq6/g+jWDBw9+8eIFAOD8+fMhISF//fWXs7MziUSKiYkZN25cQUGBs7Pz0qVL4Tr2MpnM19c3KSnJxcVl//79zZ/ax8fH19XVeXl5CYXCAQMG1NTUND/7kSNHHj58CAB4/vy5t7e3RCKxs7ObMWMG7D9TWVm5cOHCL7/80tbWtrq6esiQIWjk1kcIw7AmAgCAqanptWvX4EV76tSpqKio5r+4iouLFy5cOG/ePEtLSzabXVhYCOc153A4U6dOvXLlCgBAIpFERkZOnz7dxsZGoVAMHDgQril29+7dzz77jMlkGhkZjRo16vr162oHP3HihLm5uYeHx/Hjx9V+VEAymWzp0qXwR+O2bdtWrFjRu3fv8vJyT09P2J3mwoULYWFhly5dcnFx2bNnz3fffQffWF9fn5ubq7YA2dsSE1VWVnK53LKyMldX13379q1YsQIAIBAIIiMjZ8yYYWhoaGFh8fr164ULFy5evLhv374vX7709/eHte2DBw/OmDHDzs5OIpF4e3urdXWTSqVnzpzp2bPnJ598smHDhv/973/Nz15cXIxHFR4evn//fhcXl6SkJF9fX1imoqOjJ06c+Pz5cycnp2XLlsGV6ToaSxdUirW2TZrW9oq7RCJpaGjooHi0X7tMKvnxeM953DOuXTn8v12dE9LHoEvPEfsBPpJ53K9evcrlcn19fUtKSjAMS0pK8vLy8vb2zsrKwjCMx+N5e3sPGDDg3r17GIZVV1f7+flxudzz589jGCaTyYYOHcrlcvft2wePFhQUxOVyt27dqnbSgIAAOp1u9I/Vq1fD/TExMa6urvPmzZs0aRLcc/36dS8vL/yN06ZNmz59utrRZDJZbW1t3759k5KSMAxbv359//794Z/KysoYDEZVVdWTJ09MTEzgFNFKpbJ3795//fUXhmFjx46NjY0lHq2urm7NmjXffPMNhmE5OTmWlpb4nzZu3LhkyRIMw3bu3Dl69Gi489WrVzQarbq6GsMwEol069YtuH/EiBEnTpyAr93c3HJycjAMi46O9vf3hztbTLxz5865c+fCnQ0NDUwmE34QGIZt3br1q6++wjDsm2++GTZsGB7V5MmTw8LC8E/TwsICw7DY2FhPT088R0wmMzc3F8MwR0fHJ0+e4O+F03IHBwcfOHAAw7Dz589/+umn+F9DQ0P37t2LYdicOXO+/vpruPPGjRvwf/L8+XMSiQQnNlapVLa2tqmpqfh70TzuRC3O4z5q1Cgul/vjjz/CzenTp3O5XLwsLF26lMvlfvHFF3Bz69atXC43KCgIbu7bt4/L5Q4dOlQmk2EYdv78eS6X6+fnB69D3J07d0gkkhGBRCLBMKyurs7e3n7Hjh2mpqaZmZkwsbu7+507d+DrtLQ0MpncfNbqhoaGffv2weIJKzH4NTx79uw1a9ZgGDZs2LDffvsNj9PX1xfDsISEhH79+qn964qLi2k0GszCuHHjjh49Cv8kFAoBABKJRCQSMRgMePPBMGzq1KnwFKtXrx45ciTceePGDXd3d/j6+PHj4eHh8LWBgQH8b78tMQAAn2B+xYoVy5Ytwz8sJpPZ2NhYWVkJAMDLS3JyMplMLioqgpt+fn5HjhzBMIzD4dy8eRPu/PrrryMiIjAM279//+TJk4n5bWpqSkhI6NOnD9zs1atXcnIyfJ2amtqzZ08Mw/Ly8phMJj79vIeHB/yfBAUFwTsPhmG//vpraGgoftgOmscdw7ANTxVDLsuHX5W/LUGX/o6eGK8Af8jeNKne/y1CoXDjxo0dFtHHCM3j/l+J+NVypum70yHIfzBo0KD9+/eTSCQOhwMAcHNzi46OBgDAbuj29vawQRdOz2xiYvL777+rVCpHR0cAgI6Ozu7du2UyGd6A9/333wuFQvh0W82WLVuI3amhefPmnTlz5vz5863MlcvlcvHXf/75Z1RUFIVCYTAYJSUlJSUlcAAcPgM6h8PhcDj5+fmFhYVubm6wgy+ZTPbx8cnNzSV2WC8oKPjiiy9KSkpYLFZ1dXXrfbvz8vLwaeN79uxpZmbG4/HglM/4MuwcDgc2Y79+/VokErU4i1zzxEQ8Hk8mk8HhUE1NTVVVVb169YJ/UpveHs+vl5dXVVVVTU1NXl4ePhaQxWJ98sknubm5zs7O+FseP368aNEisVisr69fXFyM9+ppUW5u7tdffw1f+/r6VlRUwG7EbDbbxsYGAEAikSwtLeGS8sh7+vnnn8ViMT4r+caNGxsbG/Ep/5ctWzZz5kx8JvKIiIiAgADYcQIAMHHixAEDBujq6uro6AAAhg8fbmdnRyaT1ebyBwCYmppWVVWp7WSxWPv27Rs1atQPP/yAX4RqLCws4IcLAKitrZ09e3ZGRoaJiYlAIDA2NsaTeXl5wRfe3t7Xrl0DAOTl5e3cuRPu9PPzaz6ee+vWrQcPHjQwMNDV1YXroL2tk9Xr168pFAo+cNPX1/f27dvwNX7FWllZ4WXn4sWL06ZNa36cFhMTPXv2rLKy8vPPP1coFAKBQCaTFRYWcjgcMplM7OpjaWnZo0cPPL+5ubl1dXXl5eX43WDgwIFqo8/lcvnixYuvXbvGZrMxDIMPJd4mLy/vk08+wT90X1/f3Nzc98xCuzPSJVVJMHvtmZv+X/5pcW9DHwY9PT34KAb5AN204q6oryGxP7qB54iWMTQ0JNaMGQwGcZNKpRI3SSSSWgdWtUpA68uvNJeRkZGZmclisa5fvz516tQW0+DLD4nF4vDw8MzMTFid5XK5KpUK/gm22OGvmUymvr5+853Ew65atWrMmDGwkrFjx46MjIxW4mQymfjRMAwjHg3va0sikTAMAwDExcVNmDChxeM0T0zsHaSvr0+n08+cOYPvxIfrqS0phQcDx//p6+vr6+uXlpa2kt+5c+fu2LFj/PjxAIDw8HD8X/fO/AqFQjKZDH8C4fETs4C8J7XfcmorkamtjmRtbU0cI2Fubk5c/4jFYhEL5jthGLZ37143N7c///xzyZIleJkiIu7csWOHlZVVXFwciUQ6c+YMsW4qEongMkkikQj+riCWtaamJrULLzk5+dChQ5mZmQYGBlKpVF9fv5Vrj8lkSqVShUIBr/wWCxpOKpUmJCQcPny4+XGaJ1ajr68/Z86c2bNn43sMDAxqa2vJZDJxjCxxfK1QKGSz2Xp6emQyWSgUwgE2zQvaiRMn8vPzCwoKqFRqdnY2/hv7bWGo3abw33VqY1Q6AYsGqsRYHyPt7Jz8AX3ckf9CA//pwsLCwMBAR0fHoKCg169fN08watSozwn279/f7jGQG2toxi2sv4gg2kEoFE6dOvXnn3++cOHCkiVL8vPzAQBsNrumpqbFGmFTU5NSqYQtlCkpKcSq9rVr12Cj1I0bN8hk8ieffALbrmCaN2/e3Lp1a9iwYcSj8fl8+JBBKBSeOnUK7mSz2Y2NjVKpVO3Uw4cPP3fuHJzN7a+//tLT04N97lvUYgf3t2Gz2Xj7aO/evTkczoULF9hsNpvNNjIyIn6pE509exZ2t42NjR04cCDspn/16lX4rP/Ro0dlZWVqy8Hy+Xz4JKS8vPzq1av42WFfi+b5PXbsGOxzfPDgQT8/P7QUa5f266+/lpaWPnnyhMPhrFu3Du6En36L6eHVQiKRFAqFWs04NjYWACCTyU6fPj18+HAAwPDhww8fPgyvooMHD3722Wdqh2IymbB2e/jwYXyoSYtnt7a2tre3P3bsGABAJBKdOnVK7WhEd+7c8fHxwR9KvBPxjGPHjj1x4oSOjg4sa2KxuMU5beCAbABAXV3d5cuXhw8fTqPR/P39Dx06BACQy+WxsbHN82tqagqPdvDgwRbPjhswYEBZWVliYiIAoLKy8sqVK/BfqhFsXVAn1ebpIAFoWw9+Pp8/bty4DopH62mgxX3y5MkjR47cv3//r7/+Onny5KdPn6olWLVqFbxPyWSy4ODgjnieQhfxDU3VH4MiSBe1YcMGON0yAKBXr14pKSkLFizw9/efMWMGAGD9+vVTpkxJTk6Gk0Xa2trq6enxeDziEeB0KB4eHk5OTiKRiNj2z+VyP/vsM3Nz8/T09CNHjtDpdCsrqz179owcObJfv37Z2dkbNmxQ6xyydOnSuXPnnjp1qri4GHbGBQBwOJzJkyfb29szGIzHjx/jiSdMmHDr1q2+ffv27t2bx+PFxsaqNYHjamtr8/Ly4Cwc7yMwMPC3337r2bOnu7v7xYsXz5w5ExYWtm/fPjab/eLFi3Xr1rU4mK93797e3t4mJiYvXryAAwf9/PwWL17s7u7u4uKSnZ39xx9/qHWiWLlyZWBgIJfLLS8vxzvV+Pn5mZqa9ujRw8TEhDgz4NKlSxMTE/v27WtmZlZdXd36jJbIR6WmpobNZuObJ06csLCw2Lp1a2JiIo1GO3z4sKen5+DBg4OCghYtWrR06dK1a9euW7dOrS9WZGTkuHHjEhMT4S9A2FEKys3N/fTTT0tLS11cXMLDwwEAW7ZsmTBhgqenJ5lMxudvwQ0bNozBYHh6erJYLBsbG9hQDQD44osvZs6cuXfv3tmzZy9fvhzuJJPJR44cCQ0NPXLkyOvXr4cOHQpP0aI2/UIGAKxYseLTTz/V09M7duzYvHnz4NBPV1fX2tpaiUSSlZXV/C09evSIjo7evXt3bm5uWFgYnAILjhy9evVqdXV1nz598NHw0LRp03bv3j148GCJREK8Ry1evHjevHkMBmPLli34k0ljY+MDBw7AWa1ycnKWLFmiNtC2M7FoJAxo83SQoI0t7kKhsPWVAZDWtEtP+feXlJTEYrHgABqpVGpkZJSSkvK2xOfOnYND7N//+O85OJW3fMLDIuH7H7ar69IDXz7ARzI4tXOIRKJGgqamJpVKVVtbK5f//4FQaptyuRyWkaamJji6DldQUJCTk6NSqQQCgVQqxTBs/fr1y5cvF4lEGRkZaiMjRSJRVlYW8dISiUT4WWpra9PS0uApiG9UKBS1tbVKpVIqlRLPzufzs7Oz4Z0BP4JK9f9HO8HjxMbGzp49G08gk8lEItHbEuPJxGJxQ0MDvvn69eusrCyBQIDHjB8Ew7DJkyfv37+/vr4+IyODGAyGYQ0NDVlZWcQjw8cU8HVZWVlGRoZUKhUKhcQDymQyODxOLBYTD1hWVpafn4+/XaFQ4KPoMAxrbGwkJkaDU4laHJzaCRQKReO/yeVyoVCIX0sYhqltNjQ0iMVihUJRX19PPFRjY+OzZ8/q6upkMhnMDhycKpfLCwoKXr16pXbqV69eFRYWEiOBQ8Ph65ycHPiWuro6/IrCMEwgEMBkxEIql8tzc3OrqqrwPcQiAENVqVQ9evQoLy8nHgoeuXliYpzE+4xAIEhPT3/z5g3chHchPGVycnKvXr1UKlVubi7xRBiGKZVKHo9XWlqK75HJZPj9XCKRZGZmlpWVKZVKYpGB/0OJRKJWTODPBuIdAL+5YRgmlUqJ/5yOG5yaVqMCf8hmJ7y1MtOlv6NXP1GQ/pC9Ox1BY2NjZGRkB8XzcerCg1NzcnJcXV3hGCBdXV1XV9fs7Gy15864Q4cOzZkz55096toKkwhVgGzFZrTvYRFEIxiMFq5kYrsgiUQiblKpVLjZ/Dk4nNocAKDWtZTBYDQfcMlgMNRWKCRGAp+Sw9fEFnQKhQL3q3UFNjY2Jo7SU8sCDHXs2LGwHzmko6MD7yQtJsbR6XRiXxQ7O7u3xYwzMjJqnl9DQ0O1/BJPBEfuNs+Xjo4OHB6n1h8GTw9RKBR8FB0AAG86RT4eFAql+eei1glEbUkm2GEdAGBkZETcb2Bg4OHhAV/j1zCEl0EiYgd9GAl+IgqFgvfvJ15CgFCKiWFTqVTiuGrw7yJAoVCMjIyUSuX9+/eJ4+DxQzVPTDwUsRgymUx3d3d8U+0uhO9UCwYAQCaT1YYoEEs6jUbDB/+o5Rf/bxMLJo1GUyu2xJubrq5ui2MS2h1LFwDt7QVOI7d5pksDA4MffvihY8LRfp1dca+pqcFLFwAATjrRYsrS0tL4+PjffvutTccXCAT29vb4+LPAwEA4cQdRU0VJmY6Jq0rY1NSmY3dhQqGw+TTeWkzxj04+L3GhE+0wePDgjlvJvK3UavYdYcKECWqVho8EnKoftve3npJGo6nVBZGPH41GW716decPmmwRhUJR+33b7jgczvz58zv0FB8Vli4JtLEXeBdCo5C09TfJx6mzK+4sFos4JqyxsfFtX8ZHjhwZMmQInBrv/TGZzLS0NPyHOIPBaD7wq0YortE1NTViNnu31sIwTK0NVbvBWnvnj/ljMBha9gNp5MiRmg6hU02fPl3TIbRMV1eXyWRSKJT3Hy+IdCE0Gu3777/XdBSdx9bWFl9qrTsw0gVkkta2uNMpbc5afX39/Pnzz5492zERabnOrrg7ODjk5+djGEYikVQqFY/Ha/HJIIZhR44c2bRpU1uPTyKRWCxW80dyRA21tU36aGQqgiAIgiAdjkwCBjraPDi1rQ8TGhsbiVMUIG3S2T8Ahw0bpqOjAye9io2NpdPpQ4YMAQDcvn2b2Cvm3r171dXVb5uw+T8S19VKmWguSARBEARBOgNLl6TF00G2afUlAIChoeH7zw+GqOns64hCoZw8eXLTpk0mJiZbtmw5efIkHHuan59/9+5dPNm5c+fmzJmjNtCnvcjr+SRD1OKOIAiCIEhnYOm2uXbbVXxAizuLxSLOxI+0iQbmcff39y8sLBQKhcTOmgsXLly4cCG+uWfPno4LgNzE17VDLe4IgiAIgnQGFk1rB6d+QB935L/QQMUd0uAQK0wq1TO3fHc6BGkjKpWanp7+tulNOxQcN9L559UgkUjUQQ/lPjYVFRXEBeQRAACVSp0zZ043GXPfDUu3RmAY1uIir+2Cpau1U6/Q2z6rjEAgWLVqVXR0dMdEpOU0VnHXoE0em1dao5kZkPbn4+Nz//59lUrV+acWiUTaN6dNK+Ry+ZAhQ7rP8KaPc5JKDTp58mRFRYWmo+gk3ec3KiSTyUgkkkZmNe24JRTYNK0dnEpve1eZurq6K1euoIr7h+mOFXcFSccRLW+CdAASiURciLszNTU16evrd5+Ku1KpdHZ25nK5mg6k82jkB+FHy9ra2traWtNRdBKBQNCt1uSSSqUkEqlzlkbqNGvcyWxd7bw/mzGABaNtWdPX17e3t++geLRed6y4X/pUZmBAe3c6BEE+VhQK5eHDh5qOAkEQ5L30MdLOWjsAwN2YdPHztjW5m5iYXL16tYPi0Xpa2uUKQRAEQRAEQbQLqrgjCNL1YBi2fft2TUeBIAiCtJlIJPr55581HUVXhSruCIJ0PXK5HN33EQRBuqKampoDBw5oOoquqjtW3GNjYwUCgaaj6DxisfjQoUOajqJTZWVl3bt3T9NRdKq//vqrrKxM01F0HhKJRKfTNR1FpyoqKrp8+bKmo9C8mJgYhUKh6Sg6D5/PP336tKaj6FSPHz9++vSppqPoVMeOHWtsbNR0FJ2HRCIplUpNR9GpsrOzicuM/hfdseK+d+/eoqIiTUfReSoqKnbt2qXpKDrV/fv3u1sV59ixY1lZWZqOovNgGCaRSDQdRadKS0s7deqUpqPQvO3btzc0NGg6is7D4/G6W9vkjRs3bt26pekoOlV0dPTr1681HUXnwTCMQtHS2THf4sGDB5cuXWqXQ3XHijuCIAiCIAiCdDmo4o4gSNeDYRia1xxBEKQrkslkQqFQ01F0VajijiBI1yOXy7tVR2cEQRCtUVNT06369LcvEoZhmo6hPdFoNCsrKzK5tR8kJSUlFhYWGllOWSMUCkV5ebmtra2mA+k8jY2NcrncxMRE04F0noqKCiMjIwaDoelAOolKpSoqKupWa++JRCKBQGBhYdF6sjFjxuzevbtzQmpfUqlUX1/fzs6u9WRFRUW2trat3+S1iVQq5fP5VlZWmg6k89TV1ZFIJBaLpelAOk9paam5uXn3qZbI5fLS0tKePXtqOpDOIxAIpFKpqalp68kiIiKioqJaT6NtK6dmZWVRqe/IVGNjo6GhYefE85HoblmWy+VyuVxPT0/TgXQegUDAZDJJJK1dnK+57nZVq1QqkUjEZDJbT9Z1qzs0Gi07O/udC913t88ddL8sSyQSEolEo3WjBc6720cMul+WFQqFTCZ7Z7XkfRocta3FHUEQBEEQBEG0Und52oggCIIgCIIgXRqquCMIgiAIgiBIF4Aq7giCIAiCIAjSBaCKO4IgCIIgCIJ0AajijiAIgiAIgiBdAKq4IwiCIAiCIEgXgCruCIIgCIIgCNIFUL777jtNx9CpSktLb9++LRKJtHshuvLych6PZ2pqSqFQ8J2NjY3x8fGlpaXat+5gcXHxgwcPSkpKzM3NiQu41NbW3rx5s6amxsbGRpsWJ5JIJE+fPn3y5Amfz+dwOMRP+fnz5/fv36dSqdq6cGxOTo5AIDA2Nsb3pKWlJSUlGRgYaNNyHlKpNCMjo/wfFAoFX3pJiwvyOxUWFt69e1elUpmbm2s6lg705s2bly9fcjgc4l2Lz+fHx8fz+Xwtu5sBAAoKCh4+fFhZWal2NysvL799+3ZjY6O1tbUGw2t3QqEwJSUlJSWlsbHRysqK+GlmZGQkJibq6el13ZXUWpeeni6TyYyMjOAmhmFJSUlpaWkmJib6+vqaja0dNTU1ZWVl4TdwOp2Or2sOC/J/qpZg3cnVq1eNjY1DQ0MdHR0jIyM1HU6HKC0ttba2hqtzvXnzBt//4sULDocTGBjo7e3t16iG+QAAEeBJREFU5+cnFos1GGT72rhxo7m5+ZgxY/z8/DgcTmZmJtyfmppqamo6adIkNze30aNHKxQKzcbZjmbMmOHr6xsSEuLm5ubk5FRWVgb3//jjj5aWltOmTbOwsNizZ49mg+wICQkJVCp14sSJ+J5FixbZ29uHhoaamJhcunRJg7G1Lx6PR6VSuf84fvw43K/FBfmdjh49ampqOm3aNGtr6++++07T4XSIzMxMc3NzeAOXy+X4/pSUFFNT0+DgYFdX13HjximVSg0G2b4iIyOtra0DAwP79+/v6OhYVFQE99+6dcvExGTKlClOTk6zZs3SbJDtKyAgYMiQISEhIU5OTgMGDGhoaID7V65c2aNHj6lTp5qamp49e1azQXaEs2fPksnkBQsWwE2VShUcHOzs7Dx58mRTU9NHjx5pNrx2lJCQwGAw8Bv49evX4f52Kcjdq+Lu4uISGxuLYVh1dbWRkVF2dramI2p/IpEoOzu7vr5ereIeERHx1VdfYRgml8sHDBhw6NAhzcXYznJyciQSCXw9f/784OBg+Hrs2LGbNm3CMEwkEvXq1UubanV4aVepVEOGDNm6dSuGYXV1dfr6+hkZGRiGPXnyxMjIqKmpSZNRtjehUOjm5jZnzhy84p6bm2tgYFBRUYFh2OnTp/v06aNSqTQaY7vh8XgmJibN96sV5IMHD3Z6aJohlUotLCzi4+MxDCsoKGAwGOXl5ZoOqv3V19fn5+fzeDy1ivuoUaO2bduGYZhQKHRwcPj77781F2M7y8zMxFtVxo8fv2jRIviay+XGxMRgGFZbW2tqapqSkqKxENsbfgOXy+XOzs6wFL969UpPT6+4uBjDsEuXLtnZ2WlTYxOGYTU1NX379g0NDcUr7nfv3rW2tm5sbMQwbNeuXUOHDtVkfO0qISGhX79+zfcHBATAgiwSiT64IHejx6wvXrzg8XiTJ08GAJiamo4YMSIuLk7TQbU/BoPh4uJCfNoIxcXFTZs2DQBApVJDQkK0Ke99+/al0WjwtaOjY1NTEwBAKpVev34dZpnBYEyYMEGbsox3kCCRSBQKxcDAAAAQHx/fs2dPNzc3AICXl5epqendu3c1GWV7i4qKmjVrloODA77n4sWLw4YNs7CwAABMmDChqKgoLy9PcwG2M5VKlZKSkpmZKZfL8Z0XL17U1oLcuqSkJJVK9dlnnwEAHBwcPD09r169qumg2p+RkZGTk5PaA3SRSBQfHz916lQAgJ6eXlBQkDZ97q6urvgXFn4DLy4uTktLCw0NBQCw2eyAgABtyjLxBk4mk2EvuMuXL/v5+dnY2AAAxowZU19fn56ersko29vixYvXrVtH7OQWFxc3btw4+P01derU+/fv19XVaS7AdiaXy5OSkvLy8pRKJdwjEolu3rwJCzKDwfjggtyNKu4lJSWmpqZ4NyNbW9vS0lLNhtRphEJhfX19jx494Ka25r2xsXH//v0zZ84EAJSXlyuVSltbW/gn7cvy9evXp0yZ4unpaW9vP3/+fABASUkJnl8AgK2tbUlJieYCbGfJycn37t1bunQpcScxyzQazdzcXJs+ZSqV+s033wQHBzs5OaWmpgIARCJRXV2d1hfkFpWUlBC7hGrZ5d26srIylUqlxXczqKys7Pjx4zNmzAAAlJSUGBkZ4aNWtC/Lp06dmjJlSr9+/caMGRMcHAz+fTejUCgcDkebrvArV67U1dVNnz6duJOYZUtLSx0dHW36lAUCwZo1awICAtzd3V+8eAHaryB3o4q7TCajUqn4po6OjkQi0WA8nUkmkwEA8FYNHR0dqVSq0Yjan1QqDQ0N9ff3h7cG2EiJf+Lal+VevXqFhIRMnDjx2rVrsFYnl8vVrnCtybJUKo2MjPzjjz+IGQRaneWePXuWlZUlJCTweLypU6fOmTMHdI+C/DZa/Fm/k1wuJ5PJ2v25NzY2Tpw4MSIiYsSIEaAbfNyurq6TJ0+eMGHCiRMnnj9/DlqqomhNlhsaGlasWLFnzx61/VqcZR8fn+Li4nv37hUWFnp7e3/11Veg/QpyN6q4czgcPp+vUqngZnV1tXZPLEPEYrHodHpNTQ3crKqq4nA4mg2pfcnl8tDQUD09vUOHDsE9lpaWAAAtzjKsuG/YsGH+/Pk//PADAMDS0hLPL9CuK/z8+fNNTU1nz55ds2bNzZs3c3JytmzZAgDgcDjV1dUwDYZhNTU1WpNlHR0d+JVGIpG++OKLrKwssVis9QW5FVp8eb+TpaWlSqXi8/lws7q6Wss+d6FQOHbs2P79++/cuRPusbS0rK+vVygUcFP7styvX78pU6bs2LEjMDBw9+7d4N93M6BdV/iBAwcYDEZMTMyaNWsSExOTkpJ++eUX8O8sC4VCoVCoNZ8yjUaDHaIoFMqcOXNSUlJA+xXkblRx79Onj76+flJSEgBAqVTeu3dv0KBBmg6qk5BIpEGDBt2+fRtu3rlzR5vyrlQqZ82aJZVKT548if98NzAwcHd319YsE4lEIjqdDgDw9/dPT0+HfQSrqqry8vJ8fX01HV374HK5q1atcnBwcHBwYLPZenp6dnZ2AAB/f//79+/DHoSpqakUCqVv376aDrb95ebmstls2M1Piwty6wYMGFBeXl5YWAgAEIvFjx8/7j55Z7PZLi4ud+7cgZu3b9/WpryLxeLx48f36tVrz549eFcoBwcHc3Pz+/fvAwAwDLt79642ZZlIJBLhRfvhw4fwqVpubq5QKHR3d9d0dO1j+PDhCxcuhDdwQ0NDQ0ND2JV/0KBBd+7cwTAMAHDnzp1evXppTcWdKDc3F7YktldBpr47ibag0WjLli2bM2fOqlWr4uPjjY2NR44cqemgOsSGDRvg+J7vv//ewMBg27ZtFApl5cqVoaGhVCoVPn+HP/G1w/r16y9cuLBgwYKNGzcCAMzMzFasWAEAWL169ddffy0UCrOysgoLC2HXSe0wYcIEX19fNpudmZl55MiRGzduAAAcHR3Hjx8fHBw8a9asgwcPTp06Fd4ctUCfPn369OkDX1dXV5PJ5FmzZgEARowYweFwpk2bFhAQ8NNPPy1btgz+htECv//++6tXr3r37l1RUbF79+7169fD/cSCfO/ePW0qyK0zMTGZN29eaGjookWLzp496+fn5+Hhoemg2p9UKt24cSP8+b1u3Tomk7lhwwbwz92soaEhIyOjuLg4LCxM05G2mwULFjx9+pTL5a5btw4A4ODgMH/+fDjAY/78+WvXrk1ISKBQKIGBgZqOtH0oFIoxY8aMGjVKX1//6dOnFy9ehO2Jfn5+ffv2DQkJmTBhwm+//bZw4UI4alMLeHp6enp6wtfZ2dkKhQJOExISErJp06Z58+YNHDhwy5Yt69ev15oFCrZs2SISiezt7QsKCqKjo/ft2wf3r1mz5r8X5O61ANOgQYPMzMweP37s5OS0e/dufKCqlnn27BmDwRgxYoSRkRGDwfD39yeRSI6Ojv7+/g8fPtTR0dm7dy8+vk0LSCQSFxcXJpPJYDAYDAaLxeJyuQAAV1dXV1fXBw8eGBsb79u3z8zMTNORthtDQ0Mej1dUVGRlZRUdHQ1nkgEAjB8/XiwWp6WljRw5cuPGjc0nF9ICOjo6jo6Ozs7OAAASiTRlypTS0tK8vLwZM2YsWrRIa+77hoaGRUVFPB6PTqdHRUXB6TUAAMSCHB0drU0F+Z1GjhxJpVJTUlK8vb1/+OEHHR0dTUfU/lQqVXp6OpvNHjFihJ6enoGBgY+PDwDA3d29b9++Dx8+NDU13bdvnzYtryaVSl1dXfX09OAN3Nzc3NXVFQDg6+trZWX1+PHjnj177tmzB1+ArKsjkUh6eno8Hq+kpMTR0fGPP/6wt7eHfwoJCamqqsrOzp48efLy5cu15m5GpKOj06dPH0dHRwAAlUoNDQ198eJFYWHh4sWLtennqIGBwatXr/Lz81ks1s6dO/FmYjc3N7wgR0dHf1hBJsGHFAiCIAiCIAiCfMy6UR93BEEQBEEQBOm6UMUdQRAEQRAEQboAVHFHEARBEARBkC4AVdwRBEEQBEEQpAtAFXcEQRAEQRAE6QJQxR1BEARBEARBugBUcUcQBEEQBEGQLgBV3BEEQRAEQRCkC0AVdwRBEARBEATpAlDFHUFaoHw7lUolFoujoqJSU1M1HSaCIAiirvUbeHV1dVRUVH5+vqbDRJAPgSruCKKutLSU+nYsFkssFm/dujUtLU3TkSIIgiD/8vTp01Zu4M7OztXV1Vu3buXxeJqOFEE+BFXTASDIR8fY2Pj06dP45qJFi6ytrdetWwc3dXR0mEzm6dOnvby8NBQggiAI0jJHR0fiDTwsLGzQoEELFy6Em4aGhjY2NqdPn+ZyuRoKEEH+ExKGYZqOAUE+ara2ts7Ozjdv3iTuFAqFNBqNSqUCAEQikVwuNzIyqq+vz83N5XA49vb2MFlZWdmbN2/69OnDZrPVDisSibKzs5VKpZubm76+fufkBUEQpFuhUqlhYWGxsbH4HgzDRCIRnU6nUCgAgKamJgzDDAwMqqurX7x40aNHDxsbG5iyqKiooqLC2dnZ0NBQ7bCNjY05OTkUCsXNzY1Op3dadhAEdZVBkDarra1lMpmHDx+Gm8uXL/fw8Dhw4ICVlZW/v7+Dg8PcuXMVCsWXX35pa2vr6+traWl55MgR/O0Yhm3bts3c3NzHx8fPz8/c3PyXX37RTE4QBEG6mby8PCaT+ffff8PNGTNmjBo1aseOHdbW1v7+/nZ2duvWrROLxaGhofb29gMHDrSysrp06RL+doVCsWLFCjMzMz8/Px8fHw6Hc+zYMQ1lBemOUMUdQdpBRUVFTEzMo0eP+Hz+hg0bDh48OHr0aIFA8PLly4qKilGjRi1evJjP58PE//vf/zZs2LB582Y+n19XV7dmzZqvv/764sWLms0CgiBI95SZmRkfH5+enl5TUxMZGbljx47x48dbWFi8efOmqKjIw8MjMjJSIpHAxN98883evXujo6Pr6+urq6tnzpwZERHx+PFjzWYB6UYwBEFaZWNj8/nnnxP3wCp4TEwM3IyMjAQAPH/+HG7KZDJDQ0Nra2uJRAL3wPlnrly5gmGYWCw2MjKaP38+8YBDhw4NCAjo8JwgCIJ0MxQKZebMmcQ9OTk5AIBLly7BzaCgIDqdXlFRATfr6upIJJKbm5tKpYJ7rl69CgBITU3FMKyyslJHR2fjxo340ZRKpbOz8+zZszshLwiCYRganIog7cDExKRPnz7wtY6OjpWVlZOTE41Gg3vs7OwAAKWlpQCA9PT0hoYGpVIZExODv51KpT5//rzTo0YQBEFAr169LCws4GsWi2VoaOjr60sikeCeHj16AABKS0v79++fmJgol8sFAgHxBq6vr49u4EinQRV3BGkHBgYGxE0qlUrcA8ewKhQKAEBdXR0AID09vaioCE9AIpH69evXSbEiCIIgBG29gSclJWVmZuIJWCyWlZVVJ8WKdHuo4o4gncrU1BQAsHjx4vDwcE3HgiAIgrQBvIFHRUUFBARoOhakm0KDUxGkU3l4eFhaWh46dEilUmk6FgRBEKQNBg8erK+vf/DgQU0HgnRfqMUdQTqVjo7Orl27wsLCxo0bt3jxYhsbm9LS0oSEBAqFsnXrVk1HhyAIgrwVi8Xavn370qVLw8LCZs+ebWFhUVxcfPPmzR49eqxYsULT0SHdAqq4I8g72NnZcTgc4h4KhWJvb48vyWFqagpHL+FsbGzMzc3xTTKZ7ODggKefOnWqoaHhd999N27cOJVKRaPRvLy80E0fQRCk3Tk4OBDvxgAAXV1de3t7fNk7CwsL2IsdZ2dnZ2xsjG/q6Og4ODjg6ZcsWWJubr59+/aRI0cCABgMhr+/f1BQUMdmA0H+gVZORRCNkUgkEomExWJpOhAEQRCkbUQikUKhaL6oKoJ0KFRxRxAEQRAEQZAuAA1ORRAEQRAEQZAuAFXcEQRBEARBEKQLQBV3BEEQBEEQBOkCUMUdQRAEQRAEQboAVHFHEARBEARBkC4AVdwRBEEQBEEQpAtAFXcEQRAEQRAE6QJQxR1BEARBEARBugBUcUcQBEEQBEGQLgBV3BEEQRAEQRCkC/h/DHPdu7NcC14AAAAASUVORK5CYII=", - "image/svg+xml": [ - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ], - "text/html": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "p1 = plot(\n", - " test_data,\n", - " k_test,\n", - " label = \"Kernel Approximation\",\n", - " xlabel = \"Time\",\n", - " ylabel = \"Capital\",\n", - " legend = :bottomright,\n", - ")\n", - "plot!(\n", - " test_data,\n", - " k_baseline,\n", - " linestyle = :dash,\n", - " label = \"Closed-Form Solution\",\n", - ")\n", - "\n", - "# Since the relative error of k is 0 at t = 1, it breaks the log y scale, and so is omitted\n", - "p2 = plot(\n", - " test_data[2:end],\n", - " k_rel_error[2:end],\n", - " label = \"Relative error for k(t)\",\n", - " xlabel = \"Time\",\n", - " yscale = :log10,\n", - " legend = :bottomleft,\n", - ")\n", - "\n", - "p3 = plot(\n", - " test_data,\n", - " c_test,\n", - " label = \"Kernel Approximation\",\n", - " xlabel = \"Time\",\n", - " ylabel = \"Consumption\",\n", - " legend = :bottomright,\n", - ")\n", - "plot!(\n", - " test_data,\n", - " c_baseline,\n", - " linestyle = :dash,\n", - " label = \"Closed-Form Solution\",\n", - ")\n", - "\n", - "p4 = plot(\n", - " test_data,\n", - " c_rel_error,\n", - " label = \"Relative error for c(t)\",\n", - " xlabel = \"Time\",\n", - " yscale = :log10,\n", - " legend = :bottomleft,\n", - ")\n", - "\n", - "for ax in (p1, p2, p3, p4)\n", - " vline!(\n", - " ax,\n", - " [40],\n", - " linestyle = :dot,\n", - " color = :black,\n", - " label = \"Extrapolation/Interpolation\",\n", - " )\n", - "end\n", - "\n", - "plot(p1, p2, p3, p4, layout = (2, 2), size = (1000, 850))" - ] - }, - { - "cell_type": "markdown", - "id": "713b4bfb", - "metadata": {}, - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Julia 1.12.1", - "language": "julia", - "name": "julia-1.12" - }, - "language_info": { - "file_extension": ".jl", - "mimetype": "application/julia", - "name": "julia", - "version": "1.12.1" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/optimal_advertising_matern.py b/optimal_advertising_matern.py index 620b4d1..3f8a074 100644 --- a/optimal_advertising_matern.py +++ b/optimal_advertising_matern.py @@ -1,15 +1,21 @@ +import time +from typing import List, Optional + import jax import jax.numpy as jnp -import numpy as np -import pyomo.environ as pyo -from pyomo.opt import TerminationCondition import jsonargparse +import numpy as np +import unopy from jax import config + from kernels import integrated_matern_kernel_matrices -from typing import List, Optional +from rkhs import rkhs_norm_squared config.update("jax_enable_x64", True) +NLP_OPTIONS = dict(preset="ipopt") +DOMAIN_EPS = 1e-8 + def optimal_advertising_matern( rho_hat: float = 0.11, @@ -20,7 +26,6 @@ def optimal_advertising_matern( nu: float = 0.5, sigma: float = 1.0, rho: float = 15, - solver_type: str = "ipopt", train_T: float = 40.0, train_points: int = 41, test_T: float = 50.0, @@ -30,98 +35,208 @@ def optimal_advertising_matern( train_points_list: Optional[List[float]] = None, verbose: bool = False, ): - # if passing in `train_points` then doesn't us a grid. Otherwise, uses linspace + _ = (benchmark_T, benchmark_points) if train_points_list is None: train_data = jnp.linspace(0, train_T, train_points) else: train_data = jnp.array(train_points_list) test_data = jnp.linspace(0, test_T, test_points) - benchmark_grid = jnp.linspace(0, benchmark_T, benchmark_points) - # Construct kernel matrices - N = len(train_data) + n_train = len(train_data) K, K_tilde = integrated_matern_kernel_matrices( train_data, train_data, nu, sigma, rho ) - K = np.array(K) # pyomo doesn't support jax arrays - K_tilde = np.array(K_tilde) - - # Create pyomo model and variables - m = pyo.ConcreteModel() - m.I = range(N) - m.alpha_x = pyo.Var(m.I, within=pyo.Reals, initialize=0.0) - m.alpha_mu = pyo.Var(m.I, within=pyo.Reals, initialize=0.0) - m.alpha_u = pyo.Var(m.I, within=pyo.Reals, initialize=0.0) - m.mu_0 = pyo.Var(within=pyo.NonNegativeReals, initialize=0.0) - m.u_0 = pyo.Var(within=pyo.NonNegativeReals, initialize=0.0) - - # Map kernels to variables. Pyomo doesn't support mu_0 + K_tilde @ m.alpha_mu - def mu(m, i): - return m.mu_0 + sum(K_tilde[i, j] * m.alpha_mu[j] for j in m.I) - - def x(m, i): - return x_0 + sum(K_tilde[i, j] * m.alpha_x[j] for j in m.I) - - def dmu_dt(m, i): - return sum(K[i, j] * m.alpha_mu[j] for j in m.I) - - def dx_dt(m, i): - return sum(K[i, j] * m.alpha_x[j] for j in m.I) - - def u(m, i): - return m.u_0 + sum(K_tilde[i, j] * m.alpha_u[j] for j in m.I) - - # Define constraints and objective for model and solve - @m.Constraint(m.I) # for each index in m.I - def dx_dt_constraint(m, i): - return dx_dt(m, i) == (1 - x(m, i))*u(m, i)- beta*x(m,i) + K = np.asarray((K + K.T) / 2) + K_tilde = np.asarray(K_tilde) + K_jax = jnp.asarray(K) + K_tilde_jax = jnp.asarray(K_tilde) + n_variables = 3 * n_train + 2 + n_constraints = 4 * n_train gamma = (beta + rho_hat) / c - @m.Constraint(m.I) # for each index in m.I - def dmu_dt_constraint(m, i): - return dmu_dt(m, i) == -gamma + (rho_hat + beta)*mu(m, i) + mu(m, i)*u(m, i) - - @m.Constraint(m.I) # for each index in m.I - def shadow_price(m, i): - return u(m, i)**((1.0-kappa)/kappa) - kappa*mu(m, i)*(1 - x(m, i)) == 0.0 - - @m.Objective(sense=pyo.minimize) - def min_norm(m): # alpha @ K @ alpha not supported by pyomo - return sum(K[i, j] * m.alpha_mu[i] * m.alpha_mu[j] for i in m.I for j in m.I)+sum(K[i, j] * m.alpha_x[i] * m.alpha_x[j] for i in m.I for j in m.I) - - solver = pyo.SolverFactory(solver_type) - options = { - "tol": 1e-6, # Tighten the tolerance for optimality - "dual_inf_tol": 1e-6, # Tighten the dual infeasibility tolerance - "constr_viol_tol": 1e-6, # Tighten the constraint violation tolerance - "max_iter": 1000, # Adjust the maximum number of iterations if needed - } - results = solver.solve(m, tee=verbose, options=options) - if not results.solver.termination_condition == TerminationCondition.optimal: - print(str(results.solver)) # raise exception? - - alpha_mu = jnp.array([pyo.value(m.alpha_mu[i]) for i in m.I]) - alpha_x = jnp.array([pyo.value(m.alpha_x[i]) for i in m.I]) - alpha_u = jnp.array([pyo.value(m.alpha_u[i]) for i in m.I]) - u_0 = pyo.value(m.u_0) - mu_0 = pyo.value(m.mu_0) - - # Interpolator using training data + control_power = (1.0 - kappa) / kappa + u_0_guess = max(beta * x_0 / max(1.0 - x_0, DOMAIN_EPS), DOMAIN_EPS) + mu_0_guess = max(gamma / (rho_hat + beta + u_0_guess), DOMAIN_EPS) + x_initial = np.zeros(n_variables, dtype=np.float64) + x_initial[3 * n_train] = mu_0_guess + x_initial[3 * n_train + 1] = u_0_guess + + def unpack(z): + alpha_x = z[:n_train] + alpha_mu = z[n_train : 2 * n_train] + alpha_u = z[2 * n_train : 3 * n_train] + mu_0 = z[3 * n_train] + u_0 = z[3 * n_train + 1] + return alpha_x, alpha_mu, alpha_u, mu_0, u_0 + + def path_values(z, K_eval, K_tilde_eval): + alpha_x, alpha_mu, alpha_u, mu_0, u_0 = unpack(z) + x = x_0 + K_tilde_eval @ alpha_x + mu = mu_0 + K_tilde_eval @ alpha_mu + u = u_0 + K_tilde_eval @ alpha_u + dx_dt = K_eval @ alpha_x + dmu_dt = K_eval @ alpha_mu + return x, mu, u, dx_dt, dmu_dt + + def objective(z): + alpha_x, alpha_mu, alpha_u, _, _ = unpack(z) + return ( + alpha_x @ K_jax @ alpha_x + + alpha_mu @ K_jax @ alpha_mu + + alpha_u @ K_jax @ alpha_u + ) + + def constraints(z): + x, mu, u, dx_dt, dmu_dt = path_values(z, K_jax, K_tilde_jax) + state = dx_dt - ((1.0 - x) * u - beta * x) + costate = dmu_dt - (-gamma + (rho_hat + beta) * mu + mu * u) + shadow_price = u**control_power - kappa * mu * (1.0 - x) + return jnp.concatenate([state, costate, shadow_price, u]) + + def lagrangian(z, objective_multiplier, multipliers): + return objective_multiplier * objective(z) + jnp.dot(multipliers, constraints(z)) + + objective_value = jax.jit(objective) + objective_gradient = jax.jit(jax.grad(objective)) + constraint_values = jax.jit(constraints) + constraint_jacobian = jax.jit(jax.jacfwd(constraints)) + lagrangian_hessian = jax.jit(jax.hessian(lagrangian, argnums=0)) + + x_initial_jax = jnp.asarray(x_initial) + zero_multipliers = jnp.zeros(n_constraints, dtype=jnp.float64) + jax.block_until_ready(objective_value(x_initial_jax)) + jax.block_until_ready(objective_gradient(x_initial_jax)) + jax.block_until_ready(constraint_values(x_initial_jax)) + jax.block_until_ready(constraint_jacobian(x_initial_jax)) + jax.block_until_ready(lagrangian_hessian(x_initial_jax, 1.0, zero_multipliers)) + + variable_lower_bounds = np.full(n_variables, -np.inf, dtype=np.float64) + variable_upper_bounds = np.full(n_variables, np.inf, dtype=np.float64) + variable_lower_bounds[3 * n_train] = 0.0 + variable_lower_bounds[3 * n_train + 1] = DOMAIN_EPS + constraint_lower_bounds = np.concatenate( + [ + np.zeros(3 * n_train, dtype=np.float64), + np.full(n_train, DOMAIN_EPS, dtype=np.float64), + ] + ) + constraint_upper_bounds = np.concatenate( + [ + np.zeros(3 * n_train, dtype=np.float64), + np.full(n_train, np.inf, dtype=np.float64), + ] + ) + + model = unopy.Model( + unopy.PROBLEM_NONLINEAR, + n_variables, + variable_lower_bounds, + variable_upper_bounds, + unopy.ZERO_BASED_INDEXING, + ) + + def objective_callback(z): + return float(objective_value(jnp.asarray(z))) + + def objective_gradient_callback(z, gradient): + gradient[:] = np.asarray(objective_gradient(jnp.asarray(z))) + + model.set_objective( + unopy.MINIMIZE, objective_callback, objective_gradient_callback + ) + + jacobian_rows = np.repeat(np.arange(n_constraints, dtype=np.int32), n_variables) + jacobian_columns = np.tile(np.arange(n_variables, dtype=np.int32), n_constraints) + + def constraints_callback(z, constraint_output): + constraint_output[:] = np.asarray(constraint_values(jnp.asarray(z))) + + def jacobian_callback(z, jacobian_output): + jacobian_output[:] = np.asarray( + constraint_jacobian(jnp.asarray(z)) + ).reshape(-1) + + model.set_constraints( + n_constraints, + constraints_callback, + constraint_lower_bounds, + constraint_upper_bounds, + len(jacobian_rows), + jacobian_rows, + jacobian_columns, + jacobian_callback, + ) + + hessian_rows, hessian_columns = np.tril_indices(n_variables) + hessian_rows = hessian_rows.astype(np.int32) + hessian_columns = hessian_columns.astype(np.int32) + + def hessian_callback(z, objective_multiplier, multipliers, hessian_output): + hessian = np.asarray( + lagrangian_hessian( + jnp.asarray(z), + float(objective_multiplier), + jnp.asarray(multipliers), + ) + ) + hessian_output[:] = hessian[hessian_rows, hessian_columns] + + model.set_lagrangian_hessian( + len(hessian_rows), + unopy.LOWER_TRIANGLE, + hessian_rows, + hessian_columns, + hessian_callback, + ) + model.set_lagrangian_sign_convention(unopy.MULTIPLIER_POSITIVE) + model.set_initial_primal_iterate(x_initial) + + solver = unopy.UnoSolver() + options = dict(NLP_OPTIONS) + solver.set_preset(options.pop("preset")) + if not verbose: + solver.set_option("logger", "SILENT") + solver.set_option("print_solution", False) + for option_name, option_value in options.items(): + solver.set_option(option_name, option_value) + + start = time.perf_counter() + result = solver.optimize(model) + elapsed = time.perf_counter() - start + + z = jnp.asarray(np.array(result.primal_solution, dtype=np.float64)) + alpha_x, alpha_mu, alpha_u, mu_0, u_0 = unpack(z) + rkhs_norms = { + "x": rkhs_norm_squared(alpha_x, K), + "mu": rkhs_norm_squared(alpha_mu, K), + "u": rkhs_norm_squared(alpha_u, K), + } + + train_constraints = constraints(z) + train_residuals = { + "state": train_constraints[:n_train], + "costate": train_constraints[n_train : 2 * n_train], + "shadow_price": train_constraints[2 * n_train : 3 * n_train], + } + max_train_residual = max( + float(jnp.max(jnp.abs(residual))) for residual in train_residuals.values() + ) + @jax.jit - def kernel_solution(test_data): - # pointwise comparison test_data to train_data + def kernel_solution(test_points_data): K_test, K_tilde_test = integrated_matern_kernel_matrices( - test_data, train_data, nu, sigma, rho + test_points_data, train_data, nu, sigma, rho ) - mu_test = mu_0 + K_tilde_test @ alpha_mu - x_test = x_0 + K_tilde_test @ alpha_x - u_test = u_0 + K_tilde_test @ alpha_u + x_test, mu_test, u_test, _, _ = path_values(z, K_test, K_tilde_test) return x_test, mu_test, u_test - # Generate test_data and compare to the benchmark x_test, mu_test, u_test = kernel_solution(test_data) - - print(f"solve_time(s) = {results.solver.Time}") + solve_time = result.cpu_time + if solve_time is None: + solve_time = elapsed + solver_status = str(result.optimization_status).split(".")[-1] + solution_status = str(result.solution_status).split(".")[-1] + print(f"solve_time(s) = {solve_time}") return { "t_train": train_data, "t_test": test_data, @@ -130,10 +245,19 @@ def kernel_solution(test_data): "u_test": u_test, "alpha_mu": alpha_mu, "alpha_x": alpha_x, - "mu_0": mu_0, - "u_0": u_0, - "solve_time": results.solver.Time, - "kernel_solution": kernel_solution, # interpolator + "alpha_u": alpha_u, + "mu_0": float(mu_0), + "u_0": float(u_0), + "rkhs_norms": rkhs_norms, + "train_residuals": train_residuals, + "max_train_residual": max_train_residual, + "solve_time": solve_time, + "wall_time": elapsed, + "solver_status": solver_status, + "solution_status": solution_status, + "stationarity": result.solution_stationarity, + "primal_feasibility": result.solution_primal_feasibility, + "kernel_solution": kernel_solution, } diff --git a/pyproject.toml b/pyproject.toml index 6e32d13..39b5f12 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,12 +5,17 @@ description = "Replication Code for Solving Models of Economic Dynamics with Rid readme = "README.md" requires-python = ">=3.13" dependencies = [ - "cyipopt>=1.6.1", "jax>=0.7.2", "jinja2>=3.1.6", "jsonargparse>=4.41.0", "matplotlib>=3.10.6", + "nlls-gram>=0.5.1", "pandas>=2.3.2", - "pyomo>=6.9.4", "quadax>=0.2.9", + "unopy>=0.4.10", +] + +[project.optional-dependencies] +gurobi = [ + "gurobipy>=13.0.2", ] diff --git a/rkhs.py b/rkhs.py new file mode 100644 index 0000000..0c41395 --- /dev/null +++ b/rkhs.py @@ -0,0 +1,8 @@ +import numpy as np + + +def rkhs_norm_squared(alpha, gram_matrix) -> float: + """Return alpha' K alpha for a kernel coefficient vector.""" + alpha_np = np.asarray(alpha, dtype=float).ravel() + gram_np = np.asarray(gram_matrix, dtype=float) + return float(alpha_np @ gram_np @ alpha_np) diff --git a/scripts/probe_concave_convex.py b/scripts/probe_concave_convex.py new file mode 100644 index 0000000..94695a9 --- /dev/null +++ b/scripts/probe_concave_convex.py @@ -0,0 +1,174 @@ +import argparse +import csv +import json +import subprocess +import sys +import time +from pathlib import Path + + +DEFAULT_K0_VALUES = [ + 0.5, + 1.0, + 1.5, + 1.75, + 1.846, + 1.9, + 1.95, + 2.0, + 2.1, + 3.0, + 4.0, +] + +CHILD_CODE = """ +import json + +from neoclassical_growth_concave_convex_matern import neoclassical_growth_concave_convex_matern + +sol = neoclassical_growth_concave_convex_matern( + k_0=float(__import__("sys").argv[1]), + train_points=int(__import__("sys").argv[2]), + test_points=int(__import__("sys").argv[3]), +) +print(json.dumps({ + "valid_solution": bool(sol["valid_solution"]), + "rejection_reason": sol["rejection_reason"], + "candidate_branch": sol["candidate_branch"], + "solver_status": sol["solver_status"], + "solve_time": float(sol["solve_time"]), + "max_helper_residual": float(sol["max_helper_residual"]), + "max_train_residual": float(sol["max_train_residual"]), + "max_validation_residual": float(sol["max_validation_residual"]), + "p_lower_violation": float(sol["p_lower_violation"]), + "p_upper_violation": float(sol["p_upper_violation"]), + "active_branch_switch_train": bool(sol["active_branch_switch_train"]), + "min_branch_gap_train": float(sol["min_branch_gap_train"]), + "candidate_diagnostics": sol["candidate_diagnostics"], +})) +""" + + +def default_threshold_grid(): + return [0.5 + i * (4.0 - 0.5) / 39 for i in range(40)] + + +def parse_args(): + parser = argparse.ArgumentParser( + description="Probe concave-convex direct JAX/UNO solves under hard timeouts." + ) + parser.add_argument("--timeout", type=float, default=5.0) + parser.add_argument("--train-points", type=int, default=41) + parser.add_argument("--test-points", type=int, default=41) + parser.add_argument("--threshold-grid", action="store_true") + parser.add_argument("--output-dir", default="tmp") + parser.add_argument("k0", nargs="*", type=float) + return parser.parse_args() + + +def probe_one(k_0, timeout, train_points, test_points): + start = time.perf_counter() + try: + result = subprocess.run( + [ + sys.executable, + "-c", + CHILD_CODE, + str(float(k_0)), + str(int(train_points)), + str(int(test_points)), + ], + check=False, + capture_output=True, + text=True, + timeout=timeout, + ) + except subprocess.TimeoutExpired: + return { + "k_0": float(k_0), + "run_status": "timeout", + "wall_time": time.perf_counter() - start, + "valid_solution": False, + "rejection_reason": "subprocess_timeout", + } + + row = { + "k_0": float(k_0), + "run_status": "ok" if result.returncode == 0 else "error", + "wall_time": time.perf_counter() - start, + } + if result.returncode != 0: + row["valid_solution"] = False + row["rejection_reason"] = "subprocess_error" + row["stderr_tail"] = result.stderr.splitlines()[-8:] + return row + + payload = None + for line in reversed(result.stdout.splitlines()): + if line.startswith("{"): + payload = json.loads(line) + break + if payload is None: + row["run_status"] = "no_json" + row["valid_solution"] = False + row["rejection_reason"] = "missing_payload" + row["stdout_tail"] = result.stdout.splitlines()[-8:] + return row + + row.update(payload) + return row + + +def main(): + args = parse_args() + if args.k0: + k0_values = args.k0 + elif args.threshold_grid: + k0_values = default_threshold_grid() + else: + k0_values = DEFAULT_K0_VALUES + + output_dir = Path(args.output_dir) + output_dir.mkdir(parents=True, exist_ok=True) + rows = [ + probe_one(k_0, args.timeout, args.train_points, args.test_points) + for k_0 in k0_values + ] + + jsonl_path = output_dir / "concave_convex_probe.jsonl" + with jsonl_path.open("w", encoding="utf-8") as handle: + for row in rows: + handle.write(json.dumps(row) + "\n") + + csv_path = output_dir / "concave_convex_probe.csv" + fieldnames = [ + "k_0", + "run_status", + "valid_solution", + "rejection_reason", + "candidate_branch", + "solver_status", + "solve_time", + "wall_time", + "max_helper_residual", + "max_train_residual", + "max_validation_residual", + "p_lower_violation", + "p_upper_violation", + "active_branch_switch_train", + "min_branch_gap_train", + ] + with csv_path.open("w", newline="", encoding="utf-8") as handle: + writer = csv.DictWriter(handle, fieldnames=fieldnames, extrasaction="ignore") + writer.writeheader() + writer.writerows(rows) + + accepted = sum(1 for row in rows if row.get("valid_solution")) + rejected = len(rows) - accepted + print( + f"wrote {jsonl_path} and {csv_path}; accepted={accepted} rejected={rejected}" + ) + + +if __name__ == "__main__": + main() diff --git a/src/KernelEconExamples.jl b/src/KernelEconExamples.jl deleted file mode 100644 index 4088499..0000000 --- a/src/KernelEconExamples.jl +++ /dev/null @@ -1,26 +0,0 @@ -module KernelEconExamples -using Distributions, QuadGK -using DifferentialEquations, BoundaryValueDiffEq -using JuMP, OSQP, Ipopt -using LinearAlgebra - -include("kernels.jl") -include("neoclassical_growth_baseline.jl") -include("asset_pricing_baseline.jl") -include("asset_pricing_matern.jl") -include("neoclassical_growth_matern.jl") - -export matern_kernel_0p5, - matern_kernel_1p5, - matern_kernel_2p5, - matern_kernel_inf, - integrated_matern_kernel_0p5, - integrated_matern_kernel_1p5, - integrated_matern_kernel_2p5, - integrated_matern_kernel_inf, - matrices_matern_kernel_0p5, - neoclassical_growth_baseline, - asset_pricing_baseline, - asset_pricing_matern, - neoclassical_growth_matern -end diff --git a/src/asset_pricing_baseline.jl b/src/asset_pricing_baseline.jl deleted file mode 100644 index 0d6a0ad..0000000 --- a/src/asset_pricing_baseline.jl +++ /dev/null @@ -1,7 +0,0 @@ -using QuadGK - -function asset_pricing_baseline(t, c, g, r, x_0; T_max=2000.0) - x(s) = (x_0 + c / g) * exp(g * s) - c / g - discount_x(s) = exp(-r * s) * x(s) - return [quadgk(discount_x, t_val, T_max)[1] for t_val in t] .* exp.(r .* t) -end diff --git a/src/asset_pricing_matern.jl b/src/asset_pricing_matern.jl deleted file mode 100644 index 1668a4f..0000000 --- a/src/asset_pricing_matern.jl +++ /dev/null @@ -1,75 +0,0 @@ -using JuMP -using OSQP -using Statistics - -function asset_pricing_matern(; - r=0.1, - c=0.02, - g=-0.2, - x_0=0.01, - sigma=1.0, - rho=10.0, - train_T=40.0, - train_points=41, - test_T=50.0, - test_points=100, - verbose=false, - eps_abs = 1e-12, - eps_rel = 1e-12, - max_iter = 5000 -) - # Setup training and test data - train_data = range(0, train_T, length=train_points) - test_data = range(0, test_T, length=test_points) - - # Construct kernel matrices using nu=0.5 - K, K_tilde = matrices_matern_kernel_0p5(train_data, train_data; sigma, rho) - K = Symmetric((K + K')/2) - N = length(train_data) - - # x(t) solution - x = (x_0 + c/g) * exp.(g * train_data) .- c/g - - # OSQP is ~35x faster than Ipopt for this convex QP - # To use Ipopt instead: Model(Ipopt.Optimizer) with attributes: - # "tol", "dual_inf_tol", "constr_viol_tol", "max_iter" - model = Model(OSQP.Optimizer) - if !verbose - set_silent(model) - end - set_attribute(model, "eps_abs", eps_abs) - set_attribute(model, "eps_rel", eps_rel) - set_attribute(model, "max_iter", max_iter) - - @variable(model, alpha_mu[1:N]) - @variable(model, mu_0 >= 0) - - # Objective: minimize alpha' * K * alpha (using dot for symmetric K) - @objective(model, Min, dot(alpha_mu, K * alpha_mu)) - - # Constraints: dp/dt = r*p - x(t) - # where p(t) = mu_0 + K_tilde * alpha and dp/dt = K * alpha - @constraint(model, K * alpha_mu .== r * (mu_0 .+ K_tilde * alpha_mu) .- x) - - optimize!(model) - - alpha = value.(alpha_mu) - p_0 = value(mu_0) - solve_time_sec = solve_time(model) - - # Kernel solution interpolator - function kernel_solution(t_test) - _, K_tilde_test = matrices_matern_kernel_0p5(t_test, train_data; sigma, rho) - return p_0 .+ K_tilde_test * alpha - end - - # Evaluate on test data - p_baseline = asset_pricing_baseline(test_data, c, g, r, x_0) - p_test = kernel_solution(test_data) - p_rel_error = abs.(p_baseline .- p_test) ./ p_baseline - - println("solve_time(s) = $solve_time_sec, E(|rel_error(p)|) = $(mean(p_rel_error))") - - return (; t_train=train_data, t_test=test_data, p_test, p_baseline, p_rel_error, - alpha, p_0, solve_time=solve_time_sec, kernel_solution) -end diff --git a/src/kernels.jl b/src/kernels.jl deleted file mode 100644 index d516507..0000000 --- a/src/kernels.jl +++ /dev/null @@ -1,65 +0,0 @@ -function matern_kernel_0p5(t_i, t_j; sigma, rho) - d = abs(t_i - t_j) - return sigma^2 * exp(-d / rho) -end - -function matern_kernel_1p5(t_i, t_j; sigma, rho) - d = abs(t_i - t_j) - exponent = sqrt(3) * d / rho - return sigma^2 * (1 + exponent) * exp(-exponent) -end - -function matern_kernel_2p5(t_i, t_j; sigma, rho) - d = abs(t_i - t_j) - exponent = sqrt(5) * d / rho - term = (5 * d^2) / (3 * rho^2) - return sigma^2 * (1 + exponent + term) * exp(-exponent) -end - -function matern_kernel_inf(t_i, t_j; sigma, rho) - d = abs(t_i - t_j) - exponent = -0.5 * (d^2 / rho^2) - return sigma^2 * exp(exponent) -end - -#Integrated matern kernels -function integrated_matern_kernel_0p5(t_i, t_j; sigma, rho) - s = t_i - t_j - d = abs(s) - base = rho * (sigma^2) - if s < 0 - return base * (exp(-d / rho) - exp(-t_j / rho)) - else - return base * (2 - exp(-d / rho) - exp(-t_j / rho)) - end -end - -function integrated_matern_kernel_1p5(t_i, t_j; sigma, rho) - function matern_integrand(t) - return matern_kernel_1p5(t, t_j; sigma=sigma, rho=rho) - end - integral, info = QuadGK.quadgk(matern_integrand, 0.0, t_i) - return ifelse(iszero(t_i), zero(integral), integral) -end - -function integrated_matern_kernel_2p5(t_i, t_j; sigma, rho) - function matern_integrand(t) - return matern_kernel_2p5(t, t_j; sigma=sigma, rho=rho) - end - integral, info = QuadGK.quadgk(matern_integrand, 0.0, t_i) - return ifelse(iszero(t_i), zero(integral), integral) -end - -function integrated_matern_kernel_inf(t_i, t_j; sigma, rho) - function matern_integrand(t) - return matern_kernel_inf(t, t_j; sigma=sigma, rho=rho) - end - integral, info = QuadGK.quadgk(matern_integrand, 0.0, t_i) - return ifelse(iszero(t_i), zero(integral), integral) -end - -function matrices_matern_kernel_0p5(t, s; sigma, rho) - K = [matern_kernel_0p5(t[i], s[j]; sigma, rho) for i in 1:length(t), j in 1:length(s)] - K_tilde = [integrated_matern_kernel_0p5(t[i], s[j]; sigma, rho) for i in 1:length(t), j in 1:length(s)] - return K, K_tilde -end \ No newline at end of file diff --git a/src/neoclassical_growth_baseline.jl b/src/neoclassical_growth_baseline.jl deleted file mode 100644 index 74c438a..0000000 --- a/src/neoclassical_growth_baseline.jl +++ /dev/null @@ -1,25 +0,0 @@ -using DifferentialEquations -using BoundaryValueDiffEq - -function neoclassical_growth_baseline(a, delta, r, sigma_crra, k_0, T_max;dt=0.001) - k_ss = ((delta + r) / a)^(1 / (a - 1)) - c_ss = a * k_ss^a - delta * k_ss - - - function ode!(dy, y, p, t) - k, c = y - dy[1] = k^a - c - delta * k - dy[2] = (c / sigma_crra) * (a * k^(a - 1) - r - delta) - end - - function bc!(residual, y, p, t) - residual[1] = y[1][1] - k_0 - residual[2] = y[end][1] - k_ss - end - - tspan = (0.0, T_max) - initial_guess = [k_ss, c_ss] - bvp = BVProblem(ode!, bc!, initial_guess, tspan) - - return solve(bvp, MIRK4(); dt) -end diff --git a/src/neoclassical_growth_matern.jl b/src/neoclassical_growth_matern.jl deleted file mode 100644 index 2923814..0000000 --- a/src/neoclassical_growth_matern.jl +++ /dev/null @@ -1,141 +0,0 @@ -using JuMP -using Ipopt -using Statistics -# JuMP nonlinear optimization is incomplete - -# Broadcasted code for nonlinear constraints doesn't work well with JuMPs nonlinear auto-diff implementation -# Objective: minimize alpha' * K * alpha -# @objective(model, Min, -# alpha_mu' * K * alpha_mu + -# alpha_k' * K * alpha_k + - -# mu = mu_0 .+ K_tilde * alpha_mu -# c = c_0 .+ K_tilde * alpha_c -# k = k_0 .+ K_tilde * alpha_k -# dmu_dt = K * alpha_mu -# dk_dt = K * alpha_k - -# # Resource constraint: dk/dt = k^a - delta*k - c -# @constraint(model, dk_dt .== k.^a .- delta .* k .- c) - -# # Euler equation: dmu/dt = -mu * (a*k^(a-1) - delta - rho_hat) -# @constraint(model, dmu_dt .== -mu .* (a .* k.^(a-1) .- delta .- rho_hat)) - -# # Shadow price: mu * c = 1 -# @constraint(model, mu .* c .== 1.0) - -function neoclassical_growth_matern(; - a=1/3, - delta=0.1, - rho_hat=0.11, - k_0=1.0, - nu=0.5, - sigma=1.0, - rho=10.0, - train_T=40.0, - train_points=41, - test_T=50.0, - test_points=100, - baseline_T=60.0, - lambda_p=0.0, - verbose=false, - tol=1e-8, - dual_inf_tol=1e-8, - constr_viol_tol=1e-8, - max_iter=2000 -) - # Setup training and test data - train_data = range(0, train_T, length=train_points) - test_data = range(0, test_T, length=test_points) - - # Construct kernel matrices using nu=0.5 - K, K_tilde = matrices_matern_kernel_0p5(train_data, train_data; sigma, rho) - K = Symmetric((K + K')/2) # symmetric since train_data both arguments. K_tilde not symmetric - N = length(train_data) - - # Create JuMP model with Ipopt (non-convex problem) - model = Model(Ipopt.Optimizer) - if !verbose - set_silent(model) - end - set_attribute(model, "tol", tol) - set_attribute(model, "dual_inf_tol", dual_inf_tol) - set_attribute(model, "constr_viol_tol", constr_viol_tol) - set_attribute(model, "max_iter", max_iter) - - @variable(model, alpha_mu[1:N]) - @variable(model, alpha_c[1:N]) - @variable(model, alpha_k[1:N]) - @variable(model, c_0 >= 0, start = k_0^a - delta * k_0) - @variable(model, mu_0 >= 0, start = k_0^a - delta * k_0) - - @objective(model, Min, - dot(alpha_mu, K * alpha_mu) + - dot(alpha_k, K * alpha_k) - ) - - # Building blocks to preserve sparsity in JuMP's nonlinear model - # Create auxiliary variables for linear transformations of alpha coefficients - @variable(model, dk_dt[1:N]) # dk_dt = K * alpha_k (derivative via kernel) - @variable(model, dmu_dt[1:N]) # dmu_dt = K * alpha_mu (derivative via kernel) - @variable(model, k_tilde[1:N]) # k_tilde = K_tilde * alpha_k (integrated kernel) - @variable(model, mu_tilde[1:N]) # mu_tilde = K_tilde * alpha_mu (integrated kernel) - @variable(model, c_tilde[1:N]) # c_tilde = K_tilde * alpha_c (integrated kernel) - - # Linear equality constraints define these auxiliary variables - @constraint(model, dk_dt .== K * alpha_k) - @constraint(model, dmu_dt .== K * alpha_mu) - @constraint(model, k_tilde .== K_tilde * alpha_k) - @constraint(model, mu_tilde .== K_tilde * alpha_mu) - @constraint(model, c_tilde .== K_tilde * alpha_c) - - # Nonlinear expressions for state and control variables - @NLexpression(model, mu[i=1:N], mu_0 + mu_tilde[i]) - @NLexpression(model, c[i=1:N], c_0 + c_tilde[i]) - @NLexpression(model, k[i=1:N], k_0 + k_tilde[i]) - - # System constraints (resource, Euler, shadow price) - @NLconstraint(model, [i=1:N], dk_dt[i] == k[i]^a - delta * k[i] - c[i]) - @NLconstraint(model, [i=1:N], dmu_dt[i] == -mu[i] * (a * k[i]^(a-1) - delta - rho_hat)) - @NLconstraint(model, [i=1:N], mu[i] * c[i] == 1.0) - - println("Solving Neoclassical Growth Matern with N=$N") - optimize!(model) - - alpha_c_val = value.(alpha_c) - alpha_k_val = value.(alpha_k) - c_0_val = value(c_0) - solve_time_sec = solve_time(model) - - # Kernel solution interpolator - function kernel_solution(t_test) - _, K_tilde_test = matrices_matern_kernel_0p5(t_test, train_data; sigma, rho) - c_test = c_0_val .+ K_tilde_test * alpha_c_val - k_test = k_0 .+ K_tilde_test * alpha_k_val - return k_test, c_test - end - - # Baseline solution - sol_baseline = neoclassical_growth_baseline(a, delta, rho_hat, 1.0, k_0, baseline_T) - - function baseline_solution(t_test) - sol = sol_baseline.(t_test) - k_baseline = [s[1] for s in sol] - c_baseline = [s[2] for s in sol] - return k_baseline, c_baseline - end - - # Evaluate on test data - k_baseline, c_baseline = baseline_solution(test_data) - k_test, c_test = kernel_solution(test_data) - - k_rel_error = abs.(k_baseline .- k_test) ./ k_baseline - c_rel_error = abs.(c_baseline .- c_test) ./ c_baseline - - println("solve_time(s) = $solve_time_sec, E(|rel_error(k)|) = $(mean(k_rel_error)), E(|rel_error(c)|) = $(mean(c_rel_error))") - - return (; t_train=train_data, t_test=test_data, k_test, c_test, - k_baseline, c_baseline, k_rel_error, c_rel_error, - alpha_c=alpha_c_val, alpha_k=alpha_k_val, c_0=c_0_val, - solve_time=solve_time_sec, kernel_solution, baseline_solution) -end diff --git a/tables_neoclassical_growth.py b/tables_neoclassical_growth.py index 0754bd9..5a6ea65 100644 --- a/tables_neoclassical_growth.py +++ b/tables_neoclassical_growth.py @@ -1,44 +1,51 @@ -import pandas as pd - -from neoclassical_growth_matern import neoclassical_growth_matern - -sol_default = neoclassical_growth_matern() -sol_nu_1_5 = neoclassical_growth_matern(nu=1.5) -sol_nu_2_5 = neoclassical_growth_matern(nu=2.5,lambda_p = 1e-4) -sol_rho_2 = neoclassical_growth_matern(rho=2) -sol_rho_20 = neoclassical_growth_matern(rho=20) - -k_rel_error = sol_default["k_rel_error"] -c_rel_error = sol_default["c_rel_error"] - -sols = [sol_default, sol_nu_1_5, sol_nu_2_5, sol_rho_2, sol_rho_20] - -df = pd.DataFrame( - { - r"$\nu$": [r"$1/2$", r"$3/2$", r"$5/2$", r"$1/2$", r"$1/2$"], - r"$\ell$": [10, 10, 10, 2, 20], - r"Max of Rel. Error: $\hat{x}(t)$": [ - sol["k_rel_error"].max().item() for sol in sols - ], - r"Max of Rel. Error: $\hat{y}(t)$": [ - sol["c_rel_error"].max().item() for sol in sols - ], - r"Min of Rel. Error: $\hat{x}(t)$": [ - sol["k_rel_error"][1:].min().item() for sol in sols - ], - r"Min of Rel. Error: $\hat{y}(t)$": [ - sol["c_rel_error"].min().item() for sol in sols - ], - } -) - -with open("figures/neoclassical_growth_model_nu_rho.tex", "w") as f: - f.write(df.to_latex(index=False, float_format="%.1e")) - - -# r"Avg. of Rel. Error: $\hat{k}(t)$": [ -# sol["k_rel_error"].mean().item() for sol in sols -# ], -# r"Avg. of Rel. Error: $\hat{c}(t)$": [ -# sol["c_rel_error"].mean().item() for sol in sols -# ], +import pandas as pd +import jsonargparse + +from neoclassical_growth_matern import neoclassical_growth_matern + + +def main(): + sol_default = neoclassical_growth_matern() + sol_nu_1_5 = neoclassical_growth_matern(nu=1.5) + sol_nu_2_5 = neoclassical_growth_matern(nu=2.5) + sol_rho_2 = neoclassical_growth_matern(rho=2) + sol_rho_20 = neoclassical_growth_matern(rho=20) + + sol_default["k_rel_error"] + sol_default["c_rel_error"] + + sols = [sol_default, sol_nu_1_5, sol_nu_2_5, sol_rho_2, sol_rho_20] + + df = pd.DataFrame( + { + r"$\nu$": [r"$1/2$", r"$3/2$", r"$5/2$", r"$1/2$", r"$1/2$"], + r"$\ell$": [10, 10, 10, 2, 20], + r"Max of Rel. Error: $\hat{x}(t)$": [ + sol["k_rel_error"].max().item() for sol in sols + ], + r"Max of Rel. Error: $\hat{y}(t)$": [ + sol["c_rel_error"].max().item() for sol in sols + ], + r"Min of Rel. Error: $\hat{x}(t)$": [ + sol["k_rel_error"][1:].min().item() for sol in sols + ], + r"Min of Rel. Error: $\hat{y}(t)$": [ + sol["c_rel_error"].min().item() for sol in sols + ], + } + ) + + with open("figures/neoclassical_growth_model_nu_rho.tex", "w") as f: + f.write(df.to_latex(index=False, float_format="%.1e")) + + +if __name__ == "__main__": + jsonargparse.CLI(main) + + +# r"Avg. of Rel. Error: $\hat{k}(t)$": [ +# sol["k_rel_error"].mean().item() for sol in sols +# ], +# r"Avg. of Rel. Error: $\hat{c}(t)$": [ +# sol["c_rel_error"].mean().item() for sol in sols +# ], diff --git a/test/runtests.jl b/test/runtests.jl deleted file mode 100644 index 3501d97..0000000 --- a/test/runtests.jl +++ /dev/null @@ -1,10 +0,0 @@ -using KernelEconExamples -using Test - -# Include test files -include("test_neoclassical_growth_baseline.jl") - -include("test_asset_pricing_matern.jl") -include("test_neoclassical_growth_matern.jl") -include("test_kernels.jl") - diff --git a/test/test_asset_pricing_matern.jl b/test/test_asset_pricing_matern.jl deleted file mode 100644 index f97b1ef..0000000 --- a/test/test_asset_pricing_matern.jl +++ /dev/null @@ -1,70 +0,0 @@ -using KernelEconExamples -using Test -using Statistics - -@testset "Asset Pricing Baseline" begin - c = 1.0 - g = 0.02 - r = 0.05 - x_0 = 1.0 - - # Test vector input with values from Python - t_values = [0.0, 10.0, 20.0, 30.0, 40.0, 50.0] - expected = [700.0, 1076.384765625, 1536.1019287109375, 2097.60205078125, - 2783.419677734375, 3621.0791015625] - - result = asset_pricing_baseline(t_values, c, g, r, x_0) - - @test all(isapprox.(result, expected; rtol=1e-5)) -end - -@testset "Asset Pricing Matern" begin - @testset "Exact Python Defaults" begin - # Use EXACT defaults from Python asset_pricing_matern.py: - # r=0.1, c=0.02, g=-0.2, x_0=0.01, sigma=1.0, rho=10.0, - # train_T=40.0, train_points=41, test_T=50.0, test_points=100 - result = asset_pricing_matern( - r=0.1, - c=0.02, - g=-0.2, - x_0=0.01, - sigma=1.0, - rho=10.0, - train_T=40.0, - train_points=41, - test_T=50.0, - test_points=100, - verbose=false - ) - - # Verify p_0 matches Python: 0.699497563627038 - @test result.p_0 ≈ 0.699497563627038 atol=1e-10 - - # Verify mean relative error matches Python: ~0.00015457791718911825 - @test mean(result.p_rel_error) < 0.0002 - - # Check p_test values match Python output - # Python: [0.69949756 0.72836592 0.75446368 0.7780531 0.79937546] - @test result.p_test[1] ≈ 0.699497563627038 atol=1e-10 - @test result.p_test[2] ≈ 0.7283659243149404 atol=1e-9 - @test result.p_test[3] ≈ 0.7544636771840599 atol=1e-9 - @test result.p_test[4] ≈ 0.7780530968662679 atol=1e-9 - @test result.p_test[5] ≈ 0.7993754633594473 atol=1e-9 - - # Check alpha values match Python output - # Python: [ 0.08571768 -0.00738086 -0.00604294 -0.00494754 -0.0040507 ] - @test result.alpha[1] ≈ 0.08571768381161791 atol=1e-10 - @test result.alpha[2] ≈ -0.007380863880940638 atol=1e-10 - @test result.alpha[3] ≈ -0.006042940243608704 atol=1e-10 - @test result.alpha[4] ≈ -0.004947541016455121 atol=1e-10 - @test result.alpha[5] ≈ -0.004050703982286589 atol=1e-10 - - - # Sanity checks - @test result.p_0 >= 0 - @test all(isfinite.(result.alpha)) - @test all(isfinite.(result.p_test)) - @test all(isfinite.(result.p_baseline)) - end - -end diff --git a/test/test_kernels.jl b/test/test_kernels.jl deleted file mode 100644 index ce9b979..0000000 --- a/test/test_kernels.jl +++ /dev/null @@ -1,63 +0,0 @@ -using KernelEconExamples -using Test - -@testset "matern_kernel_0p5" begin - @test matern_kernel_0p5(25.0, 25.0; sigma = 1.5, rho = 11.0) ≈ 2.25 rtol=1e-6 - @test matern_kernel_0p5(0.0, 50.0; sigma = 1.0, rho = 10.0) ≈ 0.00673795 rtol=1e-6 - @test matern_kernel_0p5(1.0, 40.0; sigma = 1.5, rho = 11.0) ≈ 0.06492489 rtol=1e-6 -end - -@testset "matern_kernel_1p5" begin - @test matern_kernel_1p5(25.0, 25.0; sigma = 1.5, rho = 11.0) ≈ 2.25 rtol=1e-6 - @test matern_kernel_1p5(0.0, 50.0; sigma = 1.0, rho = 10.0) ≈ 0.00167451 rtol=1e-6 - @test matern_kernel_1p5(1.0, 40.0; sigma = 1.5, rho = 11.0) ≈ 0.034591846 rtol=1e-6 -end - -@testset "matern_kernel_2p5" begin - @test matern_kernel_2p5(25.0, 25.0; sigma = 1.0, rho = 15.0) ≈ 1.0 rtol=1e-6 - @test matern_kernel_2p5(0.0, 50.0; sigma = 1.0, rho = 15.0) ≈ 0.01562696 rtol=1e-6 - @test matern_kernel_2p5(1.0, 40.0; sigma = 1.5, rho = 11.0) ≈ 0.024238449 rtol=1e-6 -end - -@testset "matern_kernel_inf" begin - @test matern_kernel_inf(25.0, 25.0; sigma = 1.0, rho = 15.0) ≈ 1.0 rtol=1e-6 - @test matern_kernel_inf(0.0, 50.0; sigma = 1.0, rho = 15.0) ≈ 0.00386592 rtol=1e-6 - @test matern_kernel_inf(1.0, 40.0; sigma = 1.5, rho = 11.0) ≈ 0.004193609 rtol=1e-6 -end - -@testset "integrated_matern_kernel_0p5" begin - @test integrated_matern_kernel_0p5(25.0, 25.0; sigma = 1.0, rho = 15.0) ≈ 12.166864 rtol=1e-5 - @test integrated_matern_kernel_0p5(0.0, 50.0; sigma = 1.0, rho = 15.0) ≈ 0.0 - @test integrated_matern_kernel_0p5(1.0, 40.0; sigma = 1.5, rho = 11.0) ≈ 0.06206109 rtol=1e-5 -end - -@testset "integrated_matern_kernel_1p5" begin - @test integrated_matern_kernel_1p5(25.0, 25.0; sigma = 1.0, rho = 15.0) ≈ 14.96084 rtol=1e-5 - @test integrated_matern_kernel_1p5(0.0, 50.0; sigma = 1.0, rho = 15.0) ≈ 0.0 - @test integrated_matern_kernel_1p5(1.0, 40.0; sigma = 1.5, rho = 11.0) ≈ 0.03234953 rtol=1e-6 -end - -@testset "integrated_matern_kernel_2p5" begin - @test integrated_matern_kernel_2p5(25.0, 25.0; sigma = 1.0, rho = 15.0) ≈ 15.7074995 rtol=1e-5 - @test integrated_matern_kernel_2p5(0.0, 50.0; sigma = 1.0, rho = 15.0) ≈ 0.0 - @test integrated_matern_kernel_2p5(1.0, 40.0; sigma = 1.5, rho = 11.0) ≈ 0.02238993 rtol=1e-6 -end - -@testset "integrated_matern_kernel_inf" begin - @test integrated_matern_kernel_inf(25.0, 25.0; sigma = 1.0, rho = 15.0) ≈ 17.002823 rtol=1e-5 - @test integrated_matern_kernel_inf(0.0, 50.0; sigma = 1.0, rho = 15.0) ≈ 0.0 - @test integrated_matern_kernel_inf(1.0, 40.0; sigma = 1.5, rho = 11.0) ≈ 0.00358036 rtol=1e-5 -end - -#matrices_matern_kernel tests -@testset "matrices_matern_kernel_0p5" begin - t = [1.0, 5.0, 10.0] - s = [10.0, 20.0, 30.0] - K, K_tilde = matrices_matern_kernel_0p5(t, s; sigma=1.5, rho=11.0) - @test K[1, 1] ≈ 0.9927746 rtol=1e-6 - @test K[2, 2] ≈ 0.57539064 rtol=1e-6 - - @test K_tilde[1, 1] ≈ 0.9489851 rtol=1e-6 - @test K_tilde[2, 2] ≈ 2.311862 rtol=1e-6 -end - diff --git a/test/test_neoclassical_growth_matern.jl b/test/test_neoclassical_growth_matern.jl deleted file mode 100644 index 7ae4ebd..0000000 --- a/test/test_neoclassical_growth_matern.jl +++ /dev/null @@ -1,83 +0,0 @@ -using Test -using KernelEconExamples -using Statistics - -@testset "Neoclassical Growth Baseline" begin - # Default parameters from neoclassical_growth_matern.py - a = 1/3 - delta = 0.1 - rho_hat = 0.11 - sigma_crra = 1.0 - k_0 = 1.0 - T_max = 60.0 - - @testset "Steady State Calculation" begin - k_ss = ((delta + rho_hat) / a)^(1 / (a - 1)) - c_ss = a * k_ss^a - delta * k_ss - - @test k_ss ≈ 1.999812026503847 rtol=1e-10 - @test c_ss ≈ 0.21997932291542321 rtol=1e-10 - end - - @testset "Baseline Solution" begin - sol = neoclassical_growth_baseline(a, delta, rho_hat, sigma_crra, k_0, T_max;dt=0.01) - - # Test values generated from Python implementation - test_cases = [ - (0.0, 1.000000000000000, 0.6933843919901543), - (5.0, 1.657592269184338, 0.9428171663266427), - (10.0, 1.8861852823518497, 1.0217645195263247), - (20.0, 1.9874366901147922, 1.055808609459406), - ] - - for (t, k_expected, c_expected) in test_cases - val = sol(t) - @test val[1] ≈ k_expected rtol=1e-3 - @test val[2] ≈ c_expected rtol=1e-3 - end - end - - -end - -@testset "Neoclassical Growth Matern" begin - @testset "Exact Python Defaults" begin - # Test with exact Python default parameters - result = neoclassical_growth_matern( - a=1/3, - delta=0.1, - rho_hat=0.11, - k_0=1.0, - nu=0.5, - sigma=1.0, - rho=10.0, - train_T=80.0, - train_points=81, - test_T=50.0, - test_points=100, - baseline_T=60.0, - lambda_p=0.0, - verbose=true - ) - - # Comparing mean relative errors to Python errors - Julia error strictly smaller - @test mean(result.k_rel_error) < 1e-3 # 0.00040656029171102316 in Python - @test mean(result.c_rel_error) < 1e-3 # 0.0019231719188908187 in Python - - # Testing relative errors at specific T's - k_error_list = result.k_rel_error - c_error_list = result.c_rel_error - - @test k_error_list[1] == 0.0 - @test k_error_list[40] < 1e-3 - @test k_error_list[80] < 1e-5 - @test k_error_list[100] < 1e-5 - - @test c_error_list[1] < 1e-2 - @test c_error_list[40] < 1e-4 - @test c_error_list[80] < 1e-5 - @test c_error_list[100] < 1e-6 - - - end -end diff --git a/tests/test_python_models.py b/tests/test_python_models.py new file mode 100644 index 0000000..10dbcdb --- /dev/null +++ b/tests/test_python_models.py @@ -0,0 +1,186 @@ +import importlib +import unittest + +import jax.numpy as jnp + +from asset_pricing_matern import asset_pricing_matern +from neoclassical_growth_concave_convex_matern import ( + neoclassical_growth_concave_convex_matern, +) +from neoclassical_growth_matern import neoclassical_growth_matern +from neoclassical_human_capital_matern import ( + human_capital_initial_conditions, + human_capital_matern, +) +from optimal_advertising_matern import optimal_advertising_matern + + +def assert_all_finite(testcase, array): + testcase.assertTrue(bool(jnp.all(jnp.isfinite(array)))) + + +def assert_rkhs_norms(testcase, sol, expected_keys): + testcase.assertEqual(set(sol["rkhs_norms"]), set(expected_keys)) + for value in sol["rkhs_norms"].values(): + testcase.assertTrue(bool(jnp.isfinite(jnp.asarray(value)))) + testcase.assertGreaterEqual(value, -1e-10) + + +class ModelSmokeTests(unittest.TestCase): + def test_figure_modules_import(self): + for module_name in [ + "figures_asset_pricing", + "figures_neoclassical_growth_baseline", + "figures_neoclassical_growth_robustness", + "figures_neoclassical_growth_concave_convex", + "figures_optimal_advertising", + "figures_neoclassical_human_capital", + "tables_neoclassical_growth", + ]: + with self.subTest(module_name=module_name): + importlib.import_module(module_name) + + def test_human_capital_initial_conditions(self): + h_0, c_0, residual, _ = human_capital_initial_conditions() + + self.assertEqual(h_0.dtype, jnp.float64) + self.assertEqual(c_0.dtype, jnp.float64) + self.assertAlmostEqual(float(h_0), 1.3745155888757778, places=12) + self.assertLess(float(jnp.linalg.norm(residual, ord=jnp.inf)), 1e-12) + + def test_asset_pricing_smoke(self): + sol = asset_pricing_matern() + + assert_all_finite(self, sol["p_test"]) + assert_rkhs_norms(self, sol, {"p"}) + self.assertEqual(sol["solver_status"], "SUCCESS") + self.assertLess(sol["max_train_residual"], 1e-10) + self.assertLess(float(sol["p_rel_error"].mean()), 5e-3) + + def test_neoclassical_growth_smoke(self): + sol = neoclassical_growth_matern() + + assert_all_finite(self, sol["k_test"]) + assert_all_finite(self, sol["c_test"]) + assert_rkhs_norms(self, sol, {"k", "c", "mu"}) + self.assertEqual(sol["solver_status"], "SUCCESS") + self.assertTrue(sol["valid_solution"], sol["rejection_reason"]) + self.assertTrue(bool(jnp.all(sol["k_test"] > 0.0))) + self.assertTrue(bool(jnp.all(sol["c_test"] > 0.0))) + self.assertLess(float(sol["k_rel_error"].mean()), 2e-2) + self.assertLess(float(sol["c_rel_error"].mean()), 2e-2) + self.assertLess(sol["max_train_residual"], 1e-8) + + def test_neoclassical_growth_robustness_cases(self): + cases = [ + {}, + {"nu": 1.5}, + {"nu": 2.5}, + {"rho": 2}, + {"rho": 20}, + ] + for kwargs in cases: + with self.subTest(kwargs=kwargs): + sol = neoclassical_growth_matern(**kwargs) + + self.assertEqual(sol["solver_status"], "SUCCESS") + self.assertTrue(sol["valid_solution"], sol["rejection_reason"]) + self.assertLess(sol["max_train_residual"], 1e-8) + self.assertLess(float(jnp.mean(sol["k_rel_error"])), 2e-2) + self.assertLess(float(jnp.mean(sol["c_rel_error"])), 2e-2) + + def test_concave_convex_smoke(self): + sol = neoclassical_growth_concave_convex_matern() + + assert_all_finite(self, sol["k_test"]) + assert_all_finite(self, sol["c_test"]) + assert_rkhs_norms(self, sol, {"k", "c", "mu"}) + self.assertTrue(sol["valid_solution"], sol["rejection_reason"]) + self.assertEqual(sol["solver_status"], "SUCCESS") + self.assertTrue(bool(jnp.all(sol["k_test"] > 0.0))) + self.assertTrue(bool(jnp.all(sol["c_test"] > 0.0))) + self.assertLess(sol["max_train_residual"], 1e-5) + self.assertLess(sol["max_validation_residual"], 5e-3) + self.assertLess(sol["p_lower_violation"], 1e-3) + self.assertLess(sol["p_upper_violation"], 1e-3) + self.assertLess(sol["solve_time"], 0.5) + + def test_concave_convex_interior_cases(self): + for k_0 in [0.5, 1.0, 1.5, 2.0, 3.0, 4.0]: + with self.subTest(k_0=k_0): + sol = neoclassical_growth_concave_convex_matern(k_0=k_0) + + self.assertTrue(sol["valid_solution"], sol["rejection_reason"]) + assert_all_finite(self, sol["k_test"]) + assert_all_finite(self, sol["c_test"]) + self.assertTrue(bool(jnp.all(sol["k_test"] > 0.0))) + self.assertTrue(bool(jnp.all(sol["c_test"] > 0.0))) + self.assertLess(sol["max_train_residual"], 1e-5) + self.assertLess(sol["max_validation_residual"], 5e-3) + self.assertLess(sol["p_lower_violation"], 1e-3) + self.assertLess(sol["p_upper_violation"], 1e-3) + self.assertLess(sol["solve_time"], 0.5) + + def test_concave_convex_boundary_cases_fail_fast_or_validate(self): + for k_0 in [1.0384615384615383, 1.04, 1.05]: + with self.subTest(k_0=k_0): + sol = neoclassical_growth_concave_convex_matern(k_0=k_0) + + if sol["valid_solution"]: + self.assertLess(sol["max_train_residual"], 1e-5) + self.assertLess(sol["max_validation_residual"], 5e-3) + self.assertLess(sol["p_lower_violation"], 1e-3) + self.assertLess(sol["p_upper_violation"], 1e-3) + else: + self.assertNotEqual(sol["rejection_reason"], "accepted") + self.assertLess(sol["solve_time"], 0.5) + + def test_optimal_advertising_smoke(self): + sol = optimal_advertising_matern() + + assert_all_finite(self, sol["x_test"]) + assert_all_finite(self, sol["mu_test"]) + assert_all_finite(self, sol["u_test"]) + assert_rkhs_norms(self, sol, {"x", "mu", "u"}) + self.assertEqual(sol["solver_status"], "SUCCESS") + self.assertTrue(bool(jnp.all(sol["u_test"] > 0.0))) + self.assertLess(sol["max_train_residual"], 1e-8) + + def test_human_capital_smoke(self): + sol = human_capital_matern() + + for key in [ + "k_test", + "h_test", + "c_test", + "i_k_test", + "i_h_test", + "mu_k_test", + "mu_h_test", + "feasibility_test", + "hidden_dae_residual_test", + ]: + assert_all_finite(self, sol[key]) + assert_rkhs_norms( + self, sol, {"k", "h", "i_k", "i_h", "c", "mu_k", "mu_h"} + ) + self.assertTrue(sol["valid_solution"], sol["rejection_reason"]) + self.assertEqual(sol["solver_status"], "SUCCESS") + self.assertAlmostEqual(float(sol["h_0"]), 1.3745155888757778, places=12) + self.assertLess( + float(jnp.linalg.norm(sol["initial_condition_residual"], ord=jnp.inf)), + 1e-12, + ) + self.assertLess(sol["max_train_residual"], 1e-8) + self.assertLess(sol["max_validation_residual"], 1e-3) + self.assertLess(float(jnp.max(jnp.abs(sol["feasibility_test"]))), 1e-3) + self.assertLess( + float(jnp.max(jnp.abs(sol["hidden_dae_residual_test"]))), 1e-5 + ) + self.assertLess( + float(jnp.max(jnp.abs(sol["mu_k_test"] - sol["mu_h_test"]))), 1e-4 + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/uv.lock b/uv.lock index 4988d85..91e5aec 100644 --- a/uv.lock +++ b/uv.lock @@ -1,6 +1,14 @@ version = 1 revision = 3 requires-python = ">=3.13" +resolution-markers = [ + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] [[package]] name = "contourpy" @@ -66,18 +74,9 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" }, ] -[[package]] -name = "cyipopt" -version = "1.6.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "numpy" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/8f/41/56b471f90635ca2fb8baad5a8933d88a6f7346a8ddb7038000fcf787ebfc/cyipopt-1.6.1.tar.gz", hash = "sha256:ae7e2d0a430687d8e89cd4e61cab9920c8941a167ed8bb442dde902570035c3f", size = 67956, upload-time = "2025-08-14T10:25:09.113Z" } - [[package]] name = "equinox" -version = "0.13.0" +version = "0.13.8" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jax" }, @@ -85,47 +84,66 @@ dependencies = [ { name = "typing-extensions" }, { name = "wadler-lindig" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/bb/ad/c538b895e3f1290738b7a5eccd9c91b132e6f7ee13958a82ee8e4465f137/equinox-0.13.0.tar.gz", hash = "sha256:d59615be722373e9d66e0ba78462964e6357fb76a8b1b98c2c6027961b778a69", size = 137892, upload-time = "2025-07-07T20:44:24.13Z" } +sdist = { url = "https://files.pythonhosted.org/packages/19/ff/522336d2f8264f2ad97119710b76e2cddf66145d03a1e89899175d26b192/equinox-0.13.8.tar.gz", hash = "sha256:dd075050018e2dd02e252e9d29d3060f7e67f085622d8d27a8e89e24bb8523db", size = 145257, upload-time = "2026-05-05T10:03:43.258Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/9a/3d0699b268d9c2794f12e1c202626293170662cd9f7d4f9ad5817d9496f6/equinox-0.13.0-py3-none-any.whl", hash = "sha256:66720e6f39b4907812e2c5912ca523d698293f6f1d25736362b174f426b02c49", size = 177703, upload-time = "2025-07-07T20:44:22.666Z" }, + { url = "https://files.pythonhosted.org/packages/ae/d6/69a76c8ccdef14af687c497040292a46e59fc7a0ab24724b60e50ca61030/equinox-0.13.8-py3-none-any.whl", hash = "sha256:ca004348533cc30a63ebe8823d7dd4bb626dce17743d40bbddb89b402ef2a240", size = 185813, upload-time = "2026-05-05T10:03:41.673Z" }, ] [[package]] name = "fonttools" -version = "4.60.0" +version = "4.63.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/84/69/c97f2c18e0db87d2c7b15da1974dace76ae938f1cfa22e2727a648b7ed43/fonttools-4.63.0.tar.gz", hash = "sha256:caeb583deeb5168e694b65cda8b4ee62abedfa66cf88488734466f2366b9c4e0", size = 3597189, upload-time = "2026-05-14T12:04:30.958Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/8d/d8fec3dcde2963f8c908fb315e5ff2cd0ac34f82394bbbf73a2aa5145ce3/fonttools-4.63.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:cd7e9857e5e63738b9d9fd707bc1f59c8b09e5177726d23664db393c59bb08bd", size = 2876062, upload-time = "2026-05-14T12:03:32.554Z" }, + { url = "https://files.pythonhosted.org/packages/ef/71/d935dc54e4ff121bfdd11e08702db63a7e6f25af21d8a3d7b7212df53641/fonttools-4.63.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c2a2a42198b696a6f48fad91709afb55176e66a5e566131219dba372fb7f8c59", size = 2424594, upload-time = "2026-05-14T12:03:34.86Z" }, + { url = "https://files.pythonhosted.org/packages/8e/40/e76320afa1df918e146155ef239b1719ee266092e96f5423bfd075affba1/fonttools-4.63.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e874792a8212b44583ea02189d9e693906b2f78b261f372f95d6c563210ac1d", size = 5024840, upload-time = "2026-05-14T12:03:36.745Z" }, + { url = "https://files.pythonhosted.org/packages/ce/36/0b805d8c485f872f65a509cbe3b58a5d0d17bee855333b54a150c79d3061/fonttools-4.63.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:22135da48a348785c5e2d5d2d9d6bec5ed44adacbaeb9db12d9493bf6c6bfa68", size = 4975801, upload-time = "2026-05-14T12:03:38.833Z" }, + { url = "https://files.pythonhosted.org/packages/c8/26/2cee03d0aa083ab022da5c07aff9ed3f689da1defb81ad6917c9627896da/fonttools-4.63.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ccf41f2efdf56994d22d73bef4ced1052161958169428d06ba9724ea9e9a64be", size = 4965009, upload-time = "2026-05-14T12:03:41.494Z" }, + { url = "https://files.pythonhosted.org/packages/7e/48/cc4b66d9058c0d0982c833fad10127c4b0e9324606aafa41382295ca4102/fonttools-4.63.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9ced0bd02ac751dd6319b0da88aaef24414e3b0dbc32bb4f24944821a3741a27", size = 5105892, upload-time = "2026-05-14T12:03:43.525Z" }, + { url = "https://files.pythonhosted.org/packages/d8/1f/a98a30a814b9ddef3a2e706025f90b9e0bc94890e6cb15254bc86547d11a/fonttools-4.63.0-cp313-cp313-win32.whl", hash = "sha256:85be818f5506e8a7753153def2c9550178f0ecae6a47b5e0e8dbb23f7cc90380", size = 2291313, upload-time = "2026-05-14T12:03:45.594Z" }, + { url = "https://files.pythonhosted.org/packages/92/46/5177b01f3b4abfdd4409f31cca4ab279c9343a26efbe9ec78c97fc612e02/fonttools-4.63.0-cp313-cp313-win_amd64.whl", hash = "sha256:ba04cb5891d4c0c21b6da95eda8d7b090021508a294fff33464fc7d241e0856b", size = 2342299, upload-time = "2026-05-14T12:03:47.414Z" }, + { url = "https://files.pythonhosted.org/packages/27/d2/23d25e3f247b328be58d04a4c9f894178a0d1eda7d42867cfb388adaf416/fonttools-4.63.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:fd1e3094f42d806d3d7c79162fc59e5910fcbe3a7360c385b8da969bc4493745", size = 2875338, upload-time = "2026-05-14T12:03:50.052Z" }, + { url = "https://files.pythonhosted.org/packages/cd/58/7dfa0c761cb3b2964e2a84c4dc986c926a87de0cb9fb60d5b28ded3f2914/fonttools-4.63.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:6e528da43bc3791085f8cb6141b1d13e459226790240340fcbb4625649238b03", size = 2422661, upload-time = "2026-05-14T12:03:52.154Z" }, + { url = "https://files.pythonhosted.org/packages/dd/87/64cfa18a7a1621d17b7f4502b2b0ed8a135a90c3db51ea590ee99043e76b/fonttools-4.63.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b2248c5decb223562f7902ff6325077a073f608ee8e33e88ad88db734eb9f49", size = 5010526, upload-time = "2026-05-14T12:03:54.647Z" }, + { url = "https://files.pythonhosted.org/packages/36/e1/a8933a72c45a87177fbde2696e0d0755c8c9062f8c077a961c6215fa27b1/fonttools-4.63.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:308f957cdeaf8abe4e5f2f124902ef405448af92c90f80e302a3b771c2e6116b", size = 4923946, upload-time = "2026-05-14T12:03:56.984Z" }, + { url = "https://files.pythonhosted.org/packages/27/60/872e6e233b8c5e8b41413796ff18b7fe479661bd40147e071b450dfad7a1/fonttools-4.63.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:bf00f21eb5fb721dbaf73d1e9da6d02a1af7768f2ebcf9798be98beab8ba90f6", size = 4962489, upload-time = "2026-05-14T12:03:59.443Z" }, + { url = "https://files.pythonhosted.org/packages/30/c4/83c24f2ec38b90cfda84bf4b1a1f49df80e84a1db4e7ac6e0d41bf23bc39/fonttools-4.63.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c1aaa4b9c75798400ac043ce04d74e7830376c85095a5a6ed7cba2f17a266bf4", size = 5071870, upload-time = "2026-05-14T12:04:02.122Z" }, + { url = "https://files.pythonhosted.org/packages/de/40/3ae22b60ff1d41ce0bd044b31238cdc72cef99f28b976f1e128ebd618c9b/fonttools-4.63.0-cp314-cp314-win32.whl", hash = "sha256:22693918177bd9ceabec4736d338045f357769416fc6b0b2508eefef75b08616", size = 2295026, upload-time = "2026-05-14T12:04:04.47Z" }, + { url = "https://files.pythonhosted.org/packages/c3/d4/98078064ccc76b45cb0f6c002452011e93c4bd26f6850344f0951cc1fe89/fonttools-4.63.0-cp314-cp314-win_amd64.whl", hash = "sha256:7d782fac32985914c351556f68ac0855391572bcd87de50e05970d3cd4c96fc5", size = 2347454, upload-time = "2026-05-14T12:04:06.752Z" }, + { url = "https://files.pythonhosted.org/packages/49/4e/652d1580c5f4e39f7d103b0c793e4773129ad633dce4addd0cf4dfebde02/fonttools-4.63.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:6db5140a60a5d731d21ec076745b40a310607731b0a565b50776393188649001", size = 2958152, upload-time = "2026-05-14T12:04:08.706Z" }, + { url = "https://files.pythonhosted.org/packages/0e/55/ad864c9a9b219f552eb46b32cd7906c466e5a578ba0c3abfcc0fe7413eb6/fonttools-4.63.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7d76edbff9014094dbf03bd2d074709dfa6ec7aba13d838c937a2b33d2d6a86e", size = 2460809, upload-time = "2026-05-14T12:04:10.783Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2b/0aa8db70f18cf52e49b4ed5ecec68547f981160bf5ded3b5aed6faa0a6f9/fonttools-4.63.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0eac00b9118c3c2f87d272e45341871c5b3066baa3c86897fa634a7c3fb59096", size = 5148649, upload-time = "2026-05-14T12:04:12.747Z" }, + { url = "https://files.pythonhosted.org/packages/7f/63/18e4369c25043096f1048e0c9915951adc4f842bd81c6b18155824d6fa99/fonttools-4.63.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:51394295f1a51de8b5f30bdb1e1b9a4231536c7064ef5c6e211eec19fa36036f", size = 4932147, upload-time = "2026-05-14T12:04:14.806Z" }, + { url = "https://files.pythonhosted.org/packages/a1/3f/67f3eac2ffd8a98446c5022f8ed3864eac878a5ff7af8df4c8286dba16cc/fonttools-4.63.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9e12f105d2b6342c559c298afb674006bb2893afc7102dcf8a1b55b0486b4e40", size = 5027237, upload-time = "2026-05-14T12:04:17.675Z" }, + { url = "https://files.pythonhosted.org/packages/1a/ba/4e6214cb38a7b04779e97bb7636de9a5c7f20af7018d03dee0b64c08510a/fonttools-4.63.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:796f27556dbe094c4824f75ca85267e4df776c79036c8441469a4df37038c196", size = 5053933, upload-time = "2026-05-14T12:04:20.818Z" }, + { url = "https://files.pythonhosted.org/packages/34/3b/214dcc19ee31d3d38fb5ad2755c11ef0514e5dc300bbaf41c0b69f393799/fonttools-4.63.0-cp314-cp314t-win32.whl", hash = "sha256:948428a275741f0b64b113c955425a953314f4b9ab9997f73a72c83e68e569c8", size = 2359326, upload-time = "2026-05-14T12:04:24.22Z" }, + { url = "https://files.pythonhosted.org/packages/dd/1e/3ff1a9b523058c2eeb6a9d50f5574e2a738200d0d94107d5bc4105e8da3f/fonttools-4.63.0-cp314-cp314t-win_amd64.whl", hash = "sha256:6d4741eb179121cab9eea4cb2393d24492373a260d7945006358c08cfbf45419", size = 2425829, upload-time = "2026-05-14T12:04:26.829Z" }, + { url = "https://files.pythonhosted.org/packages/2c/47/c99d5268f354002ce80f8d029cd9d7d872969da1de8b93d32de4dc56d6f4/fonttools-4.63.0-py3-none-any.whl", hash = "sha256:445af2eab030a16b9171ea8bdda7ebf7d96bda2df88ee182a464252f6e05e20d", size = 1164562, upload-time = "2026-05-14T12:04:29.092Z" }, +] + +[[package]] +name = "gurobipy" +version = "13.0.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/27/d9/4eabd956fe123651a1f0efe29d9758b3837b5ae9a98934bdb571117033bb/fonttools-4.60.0.tar.gz", hash = "sha256:8f5927f049091a0ca74d35cce7f78e8f7775c83a6901a8fbe899babcc297146a", size = 3553671, upload-time = "2025-09-17T11:34:01.504Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b4/6b/d090cd54abe88192fe3010f573508b2592cf1d1f98b14bcb799a8ad20525/fonttools-4.60.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:97100ba820936cdb5148b634e0884f0088699c7e2f1302ae7bba3747c7a19fb3", size = 2824791, upload-time = "2025-09-17T11:32:47.002Z" }, - { url = "https://files.pythonhosted.org/packages/97/8c/7ccb5a27aac9a535623fe04935fb9f469a4f8a1253991af9fbac2fe88c17/fonttools-4.60.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:03fccf84f377f83e99a5328a9ebe6b41e16fcf64a1450c352b6aa7e0deedbc01", size = 2347081, upload-time = "2025-09-17T11:32:49.204Z" }, - { url = "https://files.pythonhosted.org/packages/f8/1a/c14f0bb20b4cb7849dc0519f0ab0da74318d52236dc23168530569958599/fonttools-4.60.0-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a3ef06671f862cd7da78ab105fbf8dce9da3634a8f91b3a64ed5c29c0ac6a9a8", size = 4902095, upload-time = "2025-09-17T11:32:51.848Z" }, - { url = "https://files.pythonhosted.org/packages/c9/a0/c7c91f07c40de5399cbaec7d25e04c9afac6c8f80036a98c125efdb5fe1a/fonttools-4.60.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3f2195faf96594c238462c420c7eff97d1aa51de595434f806ec3952df428616", size = 4959137, upload-time = "2025-09-17T11:32:54.185Z" }, - { url = "https://files.pythonhosted.org/packages/38/d2/169e49498df9f2c721763aa39b0bf3d08cb762864ebc8a8ddb99f5ba7ec8/fonttools-4.60.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:3887008865fa4f56cff58a1878f1300ba81a4e34f76daf9b47234698493072ee", size = 4900467, upload-time = "2025-09-17T11:32:56.664Z" }, - { url = "https://files.pythonhosted.org/packages/cc/9c/bfb56b89c3eab8bcb739c7fd1e8a43285c8dd833e1e1d18d4f54f2f641af/fonttools-4.60.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5567bd130378f21231d3856d8f0571dcdfcd77e47832978c26dabe572d456daa", size = 5043508, upload-time = "2025-09-17T11:32:58.944Z" }, - { url = "https://files.pythonhosted.org/packages/77/30/2b511c7eb99faee1fd9a0b42e984fb91275da3d681da650af4edf409d0fd/fonttools-4.60.0-cp313-cp313-win32.whl", hash = "sha256:699d0b521ec0b188ac11f2c14ccf6a926367795818ddf2bd00a273e9a052dd20", size = 2216037, upload-time = "2025-09-17T11:33:01.192Z" }, - { url = "https://files.pythonhosted.org/packages/3d/73/a2cc5ee4faeb0302cc81942c27f3b516801bf489fdc422a1b20090fff695/fonttools-4.60.0-cp313-cp313-win_amd64.whl", hash = "sha256:24296163268e7c800009711ce5c0e9997be8882c0bd546696c82ef45966163a6", size = 2265190, upload-time = "2025-09-17T11:33:03.935Z" }, - { url = "https://files.pythonhosted.org/packages/86/dd/a126706e45e0ce097cef6de4108b5597795acaa945fdbdd922dbc090d335/fonttools-4.60.0-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:b6fe3efdc956bdad95145cea906ad9ff345c17b706356dfc1098ce3230591343", size = 2821835, upload-time = "2025-09-17T11:33:06.094Z" }, - { url = "https://files.pythonhosted.org/packages/ac/90/5c17f311bbd983fd614b82a7a06da967b5d3c87e3e61cf34de6029a92ff4/fonttools-4.60.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:764b2aaab839762a3aa3207e5b3f0e0dfa41799e0b091edec5fcbccc584fdab5", size = 2344536, upload-time = "2025-09-17T11:33:08.574Z" }, - { url = "https://files.pythonhosted.org/packages/60/67/48c1a6229b2a5668c4111fbd1694ca417adedc1254c5cd2f9a11834c429d/fonttools-4.60.0-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b81c7c47d9e78106a4d70f1dbeb49150513171715e45e0d2661809f2b0e3f710", size = 4842494, upload-time = "2025-09-17T11:33:11.338Z" }, - { url = "https://files.pythonhosted.org/packages/13/3e/83b0b37d02b7e321cbe2b8fcec0aa18571f0a47d3dc222196404371d83b6/fonttools-4.60.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:799ff60ee66b300ebe1fe6632b1cc55a66400fe815cef7b034d076bce6b1d8fc", size = 4943203, upload-time = "2025-09-17T11:33:13.285Z" }, - { url = "https://files.pythonhosted.org/packages/c9/07/11163e49497c53392eaca210a474104e4987c17ca7731f8754ba0d416a67/fonttools-4.60.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f9878abe155ddd1b433bab95d027a686898a6afba961f3c5ca14b27488f2d772", size = 4889233, upload-time = "2025-09-17T11:33:15.175Z" }, - { url = "https://files.pythonhosted.org/packages/60/90/e85005d955cb26e7de015d5678778b8cc3293c0f3d717865675bd641fbfc/fonttools-4.60.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ded432b7133ea4602fdb4731a4a7443a8e9548edad28987b99590cf6da626254", size = 4998335, upload-time = "2025-09-17T11:33:17.217Z" }, - { url = "https://files.pythonhosted.org/packages/2a/82/0374ad53729de6e3788ecdb8a3731ce6592c5ffa9bff823cef2ffe0164af/fonttools-4.60.0-cp314-cp314-win32.whl", hash = "sha256:5d97cf3a9245316d5978628c05642b939809c4f55ca632ca40744cb9de6e8d4a", size = 2219840, upload-time = "2025-09-17T11:33:19.494Z" }, - { url = "https://files.pythonhosted.org/packages/11/c3/804cd47453dcafb7976f9825b43cc0e61a2fe30eddb971b681cd72c4ca65/fonttools-4.60.0-cp314-cp314-win_amd64.whl", hash = "sha256:61b9ef46dd5e9dcb6f437eb0cc5ed83d5049e1bf9348e31974ffee1235db0f8f", size = 2269891, upload-time = "2025-09-17T11:33:21.743Z" }, - { url = "https://files.pythonhosted.org/packages/75/bf/1bd760aca04098e7028b4e0e5f73b41ff74b322275698071454652476a44/fonttools-4.60.0-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:bba7e3470cf353e1484a36dfb4108f431c2859e3f6097fe10118eeae92166773", size = 2893361, upload-time = "2025-09-17T11:33:23.68Z" }, - { url = "https://files.pythonhosted.org/packages/25/35/7a2c09aa990ed77f34924def383f44fc576a5596cc3df8438071e1baa1ac/fonttools-4.60.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:c5ac6439a38c27b3287063176b3303b34982024b01e2e95bba8ac1e45f6d41c1", size = 2374086, upload-time = "2025-09-17T11:33:25.988Z" }, - { url = "https://files.pythonhosted.org/packages/77/a9/f85ed2493e82837ff73421f3f7a1c3ae8f0b14051307418c916d9563da1f/fonttools-4.60.0-cp314-cp314t-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:4acd21e9f125a1257da59edf7a6e9bd4abd76282770715c613f1fe482409e9f9", size = 4848766, upload-time = "2025-09-17T11:33:28.018Z" }, - { url = "https://files.pythonhosted.org/packages/d1/91/29830eda31ae9231a06d5246e5d0c686422d03456ed666e13576c24c3f97/fonttools-4.60.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b4a6fc53039ea047e35dc62b958af9cd397eedbc3fa42406d2910ae091b9ae37", size = 5084613, upload-time = "2025-09-17T11:33:30.562Z" }, - { url = "https://files.pythonhosted.org/packages/48/01/615905e7db2568fe1843145077e680443494b7caab2089527b7e112c7606/fonttools-4.60.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ef34f44eadf133e94e82c775a33ee3091dd37ee0161c5f5ea224b46e3ce0fb8e", size = 4956620, upload-time = "2025-09-17T11:33:32.497Z" }, - { url = "https://files.pythonhosted.org/packages/97/8e/64e65255871ec2f13b6c00b5b12d08b928b504867cfb7e7ed73e5e941832/fonttools-4.60.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:d112cae3e7ad1bb5d7f7a60365fcf6c181374648e064a8c07617b240e7c828ee", size = 4973202, upload-time = "2025-09-17T11:33:34.561Z" }, - { url = "https://files.pythonhosted.org/packages/e0/6d/04d16243eb441e8de61074c7809e92d2e35df4cd11af5632e486bc630dab/fonttools-4.60.0-cp314-cp314t-win32.whl", hash = "sha256:0f7b2c251dc338973e892a1e153016114e7a75f6aac7a49b84d5d1a4c0608d08", size = 2281217, upload-time = "2025-09-17T11:33:36.965Z" }, - { url = "https://files.pythonhosted.org/packages/ab/5f/09bd2f9f28ef0d6f3620fa19699d11c4bc83ff8a2786d8ccdd97c209b19a/fonttools-4.60.0-cp314-cp314t-win_amd64.whl", hash = "sha256:c8a72771106bc7434098db35abecd84d608857f6e116d3ef00366b213c502ce9", size = 2344738, upload-time = "2025-09-17T11:33:39.372Z" }, - { url = "https://files.pythonhosted.org/packages/f9/a4/247d3e54eb5ed59e94e09866cfc4f9567e274fbf310ba390711851f63b3b/fonttools-4.60.0-py3-none-any.whl", hash = "sha256:496d26e4d14dcccdd6ada2e937e4d174d3138e3d73f5c9b6ec6eb2fd1dab4f66", size = 1142186, upload-time = "2025-09-17T11:33:59.287Z" }, + { url = "https://files.pythonhosted.org/packages/3e/de/d32f793c5c208f34b289049c05fbc003ed5c6818e7e84c113651992cc923/gurobipy-13.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6cc4be757540f48b3f206427cacbcd78f5e8c07dddd8654e3b1c6e3b87327082", size = 15978090, upload-time = "2026-05-05T10:43:18.396Z" }, + { url = "https://files.pythonhosted.org/packages/a5/11/77458930745fb661a0b5aea39211101a22c5413161bb10f954f015af3f70/gurobipy-13.0.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1d7840fdf7928a6faf9fff795dde727940164e87d0bced98075df1ead38b12f9", size = 14866672, upload-time = "2026-05-05T10:43:21.508Z" }, + { url = "https://files.pythonhosted.org/packages/79/08/70c909650ae684a4d8468fec8b2e5d2f3be5b7f602e48b3cffd1e67ee6cc/gurobipy-13.0.2-cp313-cp313-manylinux_2_26_aarch64.whl", hash = "sha256:407f87b87b556b2d73f738ca4b9a41c3aed0ee412958a68b127d2108a8c300e2", size = 87208386, upload-time = "2026-05-05T10:43:26.333Z" }, + { url = "https://files.pythonhosted.org/packages/fd/7f/e68bd10b04c87f60d82f0d81340cf23e6e8d5e012dbac474dffbdf990657/gurobipy-13.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:5b26c7ab11fd406f6ecf10958728b9f9344b818fee86db5b516a46aefe8400f2", size = 11244495, upload-time = "2026-05-05T10:43:29.624Z" }, + { url = "https://files.pythonhosted.org/packages/83/ae/0481b8f6d883b1907713bb9f92313257d3f1b7608f02d73f27d6c39516ae/gurobipy-13.0.2-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:a827eff3ae926b67625026b80365007ab7be398e60e188753268dc1f0e876b3e", size = 15848186, upload-time = "2026-05-05T10:43:32.11Z" }, + { url = "https://files.pythonhosted.org/packages/30/ce/b62840162e24e03bd55fc265882fb9eb602d47a4dc27a9b7775c4741993e/gurobipy-13.0.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f82340708955c24ab20f5d41b4d7fbd0e94cf4e7740841360e2024c9d222961f", size = 14766019, upload-time = "2026-05-05T10:43:34.359Z" }, + { url = "https://files.pythonhosted.org/packages/27/b9/467bce6c7b03883b8dc1646756b5c870c7a156c89cf13ca32dfcee0cc7b3/gurobipy-13.0.2-cp314-cp314-manylinux_2_26_aarch64.whl", hash = "sha256:f7714d69d778af882d756e222340920e8dbfc004a509998604cb9b4cb1d43242", size = 87137188, upload-time = "2026-05-05T10:43:38.447Z" }, + { url = "https://files.pythonhosted.org/packages/1a/50/22546477a0277d1eaf7f67da5629c27782b63b85daeeabf394ce52627cac/gurobipy-13.0.2-cp314-cp314-win_amd64.whl", hash = "sha256:443d79ab626c383f01f0ea56c37533c9023e4d65abf8356563d2cf8da513001d", size = 11465255, upload-time = "2026-05-05T10:43:53.498Z" }, + { url = "https://files.pythonhosted.org/packages/39/5c/06e98babc2b0df16f2e42e52a222b4f880bd0a59e7e025ced25c47b7aeae/gurobipy-13.0.2-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:57c7c129f9c305296c12130bb0d8f0157785e4aaf5cee501174b8320a3a9195d", size = 16161861, upload-time = "2026-05-05T10:43:41.663Z" }, + { url = "https://files.pythonhosted.org/packages/42/21/6b0ceecfc45ebed38c5f9f3d87441baad8832743eaa85a31ac09ba4543e7/gurobipy-13.0.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:29a7449544e9b17def147b8c77d0eb30c8f343e2900bc0b004877b903ed41595", size = 14761111, upload-time = "2026-05-05T10:43:44.075Z" }, + { url = "https://files.pythonhosted.org/packages/1e/d4/b3b915fdce536d1331d45305cc55e8952694109377cbfe4e82c1fa38c986/gurobipy-13.0.2-cp314-cp314t-manylinux_2_26_aarch64.whl", hash = "sha256:8207e3503a74c43a19c120c6c117a5c6892d060e5f803fe072209be127a984e0", size = 87131303, upload-time = "2026-05-05T10:43:47.705Z" }, + { url = "https://files.pythonhosted.org/packages/b3/6b/2532e54305cf3a905f4df5a050d51f066391829f18f3c167a6ccd15da28d/gurobipy-13.0.2-cp314-cp314t-win_amd64.whl", hash = "sha256:9e2f956649fa46304a5aa2d18dbccfdb6d742092db2f0f798d37a4c3ccca5e99", size = 11906319, upload-time = "2026-05-05T10:43:50.882Z" }, ] [[package]] name = "jax" -version = "0.7.2" +version = "0.10.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jaxlib" }, @@ -134,14 +152,14 @@ dependencies = [ { name = "opt-einsum" }, { name = "scipy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8f/e7/1e8e8af59b7659c83dc07dfa1dc23bc13551e5ef89bdef19ced044a497fc/jax-0.7.2.tar.gz", hash = "sha256:71a42b964bc6d52e819311429e6c0f5742e2a4650226dab1a1dd26fd986ca70d", size = 2434085, upload-time = "2025-09-16T16:48:53.108Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d2/73/eb91d98fcadfa2cbcfdd4e417ab116e47eb20882acc5ee678e47c35d6b57/jax-0.10.2.tar.gz", hash = "sha256:bf77428a8c2e6904c4f46d5ab12aa5cfc6cad2179f07f7e4c0fc75ac86ef0639", size = 2775110, upload-time = "2026-06-17T23:44:57.818Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/e6/5fd0f6fff79eb47469ff9c4fa27125b661517a2fbf8884689b02e9fdfaa8/jax-0.7.2-py3-none-any.whl", hash = "sha256:e7e32f9be51ae5cc6854225958c57de8cca2187d279844338465b15e8a1fe7f2", size = 2835570, upload-time = "2025-09-16T16:48:51.33Z" }, + { url = "https://files.pythonhosted.org/packages/89/82/5ab5211079a151b6f661529369c0c8e98ec64cabf5c0cf22a0a05af124d8/jax-0.10.2-py3-none-any.whl", hash = "sha256:724d73c4678d8b06f6a6ab4db1b8a2fea8cd4f1e2c2564f99601634ec7b8d1c6", size = 3219515, upload-time = "2026-06-17T23:42:41.259Z" }, ] [[package]] name = "jaxlib" -version = "0.7.2" +version = "0.10.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "ml-dtypes" }, @@ -149,32 +167,32 @@ dependencies = [ { name = "scipy" }, ] wheels = [ - { url = "https://files.pythonhosted.org/packages/57/48/4eafdde441b6e37a20b969033b0c73680eb4bf59003518d9099459a115d0/jaxlib-0.7.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e1b3dfe9915825fce006ea095b853f57681845c5bfa80975dcc3788936371fb0", size = 53562665, upload-time = "2025-09-16T16:49:31.05Z" }, - { url = "https://files.pythonhosted.org/packages/14/a2/3ed83db683a8f0cd7c60266f1d8e34137c6d13cb0f6e8b66717ea3f38665/jaxlib-0.7.2-cp313-cp313-manylinux_2_27_aarch64.whl", hash = "sha256:97c793e97be5ddc73b3e85e6ce8ad3709e8054f75ea219cc0cb4f0805a65af06", size = 71556806, upload-time = "2025-09-16T16:49:34.45Z" }, - { url = "https://files.pythonhosted.org/packages/3e/0b/a33add48e904dd88a52d4653cc8290da0f2d3dc132c60c5dbda6783f4e4a/jaxlib-0.7.2-cp313-cp313-manylinux_2_27_x86_64.whl", hash = "sha256:49d99620486effda87400024723a452306566996e3de719ee633f05220d1ee77", size = 78167866, upload-time = "2025-09-16T16:49:37.838Z" }, - { url = "https://files.pythonhosted.org/packages/90/9b/2049f4e5e5527cee1cf26a9f037b91abac85503074b5420678bc199b1af7/jaxlib-0.7.2-cp313-cp313-win_amd64.whl", hash = "sha256:59081f79245a40a6a2590e660fb2981ac541112893a6617121822a6afdbb5ead", size = 58041016, upload-time = "2025-09-16T16:49:40.962Z" }, - { url = "https://files.pythonhosted.org/packages/5e/da/79ab9f3d34b3ea6b30dacdb3415afd6a9d8160a8bdb48ed581192e80fb5c/jaxlib-0.7.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3ba65706622ba6b8cd33be51d2b8a3619ac4023faa18de67158ae6c67dc7097f", size = 53649187, upload-time = "2025-09-16T16:49:43.817Z" }, - { url = "https://files.pythonhosted.org/packages/87/0f/b39c008ef8015dcfafee04a5f575546a8111d0b9baee027fee2c89f40549/jaxlib-0.7.2-cp313-cp313t-manylinux_2_27_aarch64.whl", hash = "sha256:a1427c5f61c52d792fc55678cdc005ad9889ecd61e12dd312494e3daa71ce58d", size = 71654672, upload-time = "2025-09-16T16:49:46.82Z" }, - { url = "https://files.pythonhosted.org/packages/f2/7e/883e9bc1198f64a45505c0d83d013a1a068265c0f8c53ba7b28c874562f9/jaxlib-0.7.2-cp313-cp313t-manylinux_2_27_x86_64.whl", hash = "sha256:4803d42c9019f7650da15db32dde6f17cd49279da72000878b045e31524e2cda", size = 78265965, upload-time = "2025-09-16T16:49:50.484Z" }, - { url = "https://files.pythonhosted.org/packages/de/9c/44efc0f1636e96292339d9fbef34261ba57d7197d527c302d52fac584016/jaxlib-0.7.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b24ff1c564033bbe8dc4a14690e3fdb89b7e15230474afda6b2c1c90ef94bf32", size = 53565475, upload-time = "2025-09-16T16:49:53.708Z" }, - { url = "https://files.pythonhosted.org/packages/68/99/4b1ff7240b62e4d812f7fef28422d3927dd288a2ed9d54471f1eeb0b93e8/jaxlib-0.7.2-cp314-cp314-manylinux_2_27_aarch64.whl", hash = "sha256:7c70385cf7a0ea5feebd47d5a45816b3b1abfd0487060da58173f175cfd318a8", size = 71563416, upload-time = "2025-09-16T16:49:57.172Z" }, - { url = "https://files.pythonhosted.org/packages/8a/00/d8f5dc1113b55eae3d2f74e424b13de152478cd73f3d40d96b359307106c/jaxlib-0.7.2-cp314-cp314-manylinux_2_27_x86_64.whl", hash = "sha256:c76fb5fbb3ca2417f881ecbadd0516ea5ab9cc49daeab079752dc7f7a4951f0d", size = 78182392, upload-time = "2025-09-16T16:50:00.749Z" }, - { url = "https://files.pythonhosted.org/packages/be/0b/f0e2f6c391c2691b4ec7d32045832270148182d6e3fbb15d6d04027c7bec/jaxlib-0.7.2-cp314-cp314-win_amd64.whl", hash = "sha256:2554fcb4835efafdf2cc92754733aec2a566d26716ad95ea5a77da1053e6269a", size = 60230144, upload-time = "2025-09-16T16:50:03.993Z" }, - { url = "https://files.pythonhosted.org/packages/68/01/e1c44924d3a2a84a6dbc97d9fa515712decc92199a16a519c44e98dcfe33/jaxlib-0.7.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:84e158bbc79eab93b1493cdd031f93e1483b7a26a98edfdd2868f3d0752b0228", size = 53648014, upload-time = "2025-09-16T16:50:07.348Z" }, - { url = "https://files.pythonhosted.org/packages/ee/8e/b16f6f1957aba6736f1c90c0161060deb1c1f4c91ea68cbced3ba7b6e163/jaxlib-0.7.2-cp314-cp314t-manylinux_2_27_aarch64.whl", hash = "sha256:4716dc886bda1372a2c78dc6d3c23e50049044d7c552d22a95a14aac6e040731", size = 71659925, upload-time = "2025-09-16T16:50:11.135Z" }, - { url = "https://files.pythonhosted.org/packages/0c/e2/47c52aa806e98f00754b1c303f85d0594d623a7ff5c8592923f7bae45fce/jaxlib-0.7.2-cp314-cp314t-manylinux_2_27_x86_64.whl", hash = "sha256:3ecc0b2e76c089cef350f7916275431b299a17615e32ced1ece18cdd47df6bd2", size = 78264963, upload-time = "2025-09-16T16:50:14.613Z" }, + { url = "https://files.pythonhosted.org/packages/c2/68/eaa4cebe253359196a8e80a33b242959e27d8d2a6ae3d09339f21da2acb8/jaxlib-0.10.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4df530afa354a22dc1747a5d560640450cbb895d49889338a3f58c76a4c76c8e", size = 61434805, upload-time = "2026-06-17T23:44:10.511Z" }, + { url = "https://files.pythonhosted.org/packages/25/c1/4b884ea5962b6beb3c0f93742db54246bbf8b3274e48b0aca47908e454be/jaxlib-0.10.2-cp313-cp313-manylinux_2_27_aarch64.whl", hash = "sha256:45b28b0238697ab74bbcf20411aafb6db42acc31836cc2fd711e5cf056bf9556", size = 81084260, upload-time = "2026-06-17T23:44:14.065Z" }, + { url = "https://files.pythonhosted.org/packages/36/ac/4ee28c65861605945223145fbcd3c9362ec2255ddf7d917574e205548c82/jaxlib-0.10.2-cp313-cp313-manylinux_2_27_x86_64.whl", hash = "sha256:9e4818b4a8756fd3918766ca2aa5342125809f4f08a6fe46026d4386e7c23644", size = 85467706, upload-time = "2026-06-17T23:44:17.471Z" }, + { url = "https://files.pythonhosted.org/packages/79/54/9918b0f77a25a1299818c0610305ca2bea38ed90584f4489b60357e2dd39/jaxlib-0.10.2-cp313-cp313-win_amd64.whl", hash = "sha256:c75d6f1df1c9cff08e110b4a21c79560fdc502f4288972d6b117d25dafd44352", size = 65897894, upload-time = "2026-06-17T23:44:21.153Z" }, + { url = "https://files.pythonhosted.org/packages/56/5b/70df11da52a8b1a826184cccc05a3fec8aed76058a980021873fba3069cb/jaxlib-0.10.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4c202d8ff7c1f3b5049dbd8f1e30e52759cd4e0a5835f0b3c7ae076a05818e28", size = 61564746, upload-time = "2026-06-17T23:44:24.421Z" }, + { url = "https://files.pythonhosted.org/packages/23/5c/184a648ea5db6c8b1a08fc5784c157b4c557255e009fb56091393df3c6de/jaxlib-0.10.2-cp313-cp313t-manylinux_2_27_aarch64.whl", hash = "sha256:b7b029bb95d981566750475b9719a9d6b66ed5dd2748851667899b6cfe075299", size = 81204888, upload-time = "2026-06-17T23:44:27.57Z" }, + { url = "https://files.pythonhosted.org/packages/6c/5c/539596a55265711d74147913278bcdc38412980be7d74d9c9d860297c486/jaxlib-0.10.2-cp313-cp313t-manylinux_2_27_x86_64.whl", hash = "sha256:e8b126097d609b0c6e6786e89f6dd6978adc02ebd5f63a1c61293fbac7821305", size = 85583810, upload-time = "2026-06-17T23:44:30.962Z" }, + { url = "https://files.pythonhosted.org/packages/f2/0d/27471ec9f1d04674f6e62de809412371e097aed3eca7d9483e677c54c214/jaxlib-0.10.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:72eba28b12fee02616fa42aa4b881b4ab62d7757c7843c462401d3fb34a27be4", size = 61446097, upload-time = "2026-06-17T23:44:34.196Z" }, + { url = "https://files.pythonhosted.org/packages/af/c8/941a7f7f37510f51290a5bd1a413aeef977fb8ba8adc0cfe8391233a764c/jaxlib-0.10.2-cp314-cp314-manylinux_2_27_aarch64.whl", hash = "sha256:f18f56fee90699cfba9b6627045a7a299702cb0e2af82ce180d9a6a7c8048093", size = 81096546, upload-time = "2026-06-17T23:44:37.486Z" }, + { url = "https://files.pythonhosted.org/packages/69/77/ac054882c220872512df28d16aeb648fe0e651efbb5be4fd7c4817fd88b0/jaxlib-0.10.2-cp314-cp314-manylinux_2_27_x86_64.whl", hash = "sha256:ca34f363197fb0ac4082582ca755007910369e33f8a8ba3d35ed94b71070107d", size = 85472993, upload-time = "2026-06-17T23:44:40.904Z" }, + { url = "https://files.pythonhosted.org/packages/0d/7d/c592d1fa69c210be0d2743fffc598dfc2f54efa9671c5f6f5d1e151c6f4a/jaxlib-0.10.2-cp314-cp314-win_amd64.whl", hash = "sha256:99818b0a18adc0b899abf4873795e8d65169441d87ab2e5cbb228e73d0f25808", size = 68376553, upload-time = "2026-06-17T23:44:44.968Z" }, + { url = "https://files.pythonhosted.org/packages/54/9b/91b00ec74985d29708b50420b4103c1f651c8f1c253d4fcb49d1bbb532cd/jaxlib-0.10.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:fc62997fce8831819551a2a5469a818169b09582b5b648c102d11ac7205bb812", size = 61564620, upload-time = "2026-06-17T23:44:48.217Z" }, + { url = "https://files.pythonhosted.org/packages/a1/c7/49d2b19c3b3105c30e1d3af2062e82e1977fb239d3dc3cbb583ef676dda7/jaxlib-0.10.2-cp314-cp314t-manylinux_2_27_aarch64.whl", hash = "sha256:a24d6e3cba263978293eae8b41330d5ccf24d6cdd1a6bcd4e82aff34e767620d", size = 81206365, upload-time = "2026-06-17T23:44:51.419Z" }, + { url = "https://files.pythonhosted.org/packages/bf/99/006cedf443f4a01f2088651facce79b2105bfb4905bfe9162eb0920a6dfb/jaxlib-0.10.2-cp314-cp314t-manylinux_2_27_x86_64.whl", hash = "sha256:5a2ac7aed7c4e661f67600bbcdec9e589151c1efec91f4cdb8d484af1a45c895", size = 85584458, upload-time = "2026-06-17T23:44:55.377Z" }, ] [[package]] name = "jaxtyping" -version = "0.3.2" +version = "0.3.11" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "wadler-lindig" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/88/a8/416bd7ea110ec6b68e8868b0f99c985c735adcf7badc491d3c343937260a/jaxtyping-0.3.2.tar.gz", hash = "sha256:f30483fac4b42e915db8ad2414a85c3b63284aa7d3c100b96b59f755cf4a86ad", size = 44989, upload-time = "2025-04-23T09:48:16.907Z" } +sdist = { url = "https://files.pythonhosted.org/packages/91/c1/091b8852bd7cbf50bd655543c8506033cf4029300c67f8c176c1286879a9/jaxtyping-0.3.11.tar.gz", hash = "sha256:b09c14acf6686feb9e0df5b0d8c6e7c5b6f8d36bf059ee54cd522a186c2ef050", size = 46489, upload-time = "2026-06-13T18:35:23.167Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c9/b9/281e10e2d967ea5e481683eaec99f55ac5a61085ee60551c36942ef32bef/jaxtyping-0.3.2-py3-none-any.whl", hash = "sha256:6a020fd276226ddb5ac4f5725323843dd65e3c7e85c64fd62431e5f738c74e04", size = 55409, upload-time = "2025-04-23T09:48:15.924Z" }, + { url = "https://files.pythonhosted.org/packages/8b/38/c66bbdc5047f4776c2bd3e47e5295a350e3fa44d5b8942105e71c2a876a0/jaxtyping-0.3.11-py3-none-any.whl", hash = "sha256:8a4bedc4e3f963fa82df41bd13c7ebc2bad925601eb48614c65798f21329d4e3", size = 56593, upload-time = "2026-06-13T18:35:22.01Z" }, ] [[package]] @@ -191,14 +209,14 @@ wheels = [ [[package]] name = "jsonargparse" -version = "4.41.0" +version = "4.49.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pyyaml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/44/86/60032fb5623df8d938d31f733e4b3385c40791d85d0fae3dfb4e3be10c42/jsonargparse-4.41.0.tar.gz", hash = "sha256:ba1806bf0ed0ad1975e403dffb18b3a755fee3bfe4e7b36d8cce2f297b552b5f", size = 206634, upload-time = "2025-09-04T03:46:34.715Z" } +sdist = { url = "https://files.pythonhosted.org/packages/87/0b/f012466077d803b546955bf827ab30a320ad1550e3167195432cc2d6bfad/jsonargparse-4.49.0.tar.gz", hash = "sha256:9e691a09d937fb4c6bc1f6d3bf6c3546efa03381ea1e64ee10759095f1b14da7", size = 125237, upload-time = "2026-05-15T06:48:44.807Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/62/fc/6ac1943f22f3d2e14703335d64a7d68496f0480c82a3077cde44b2c55ef5/jsonargparse-4.41.0-py3-none-any.whl", hash = "sha256:cd49b6a2fea723ee4d80f9df034f51af226128a7f166be8755d6acdeb3e077a7", size = 228528, upload-time = "2025-09-04T03:46:32.668Z" }, + { url = "https://files.pythonhosted.org/packages/61/64/51cbc9044f5b1ee4fb9894fe791f50dfdb52dc080acfafb5818ba19e8c27/jsonargparse-4.49.0-py3-none-any.whl", hash = "sha256:2025880765fd792f6fb9861aa93f26da5f6c350be5d7656321369b22b0d2538e", size = 134834, upload-time = "2026-05-15T06:48:40.76Z" }, ] [[package]] @@ -206,118 +224,172 @@ name = "kernel-econ-alignment" version = "0.1.0" source = { virtual = "." } dependencies = [ - { name = "cyipopt" }, { name = "jax" }, { name = "jinja2" }, { name = "jsonargparse" }, { name = "matplotlib" }, + { name = "nlls-gram" }, { name = "pandas" }, - { name = "pyomo" }, { name = "quadax" }, + { name = "unopy" }, +] + +[package.optional-dependencies] +gurobi = [ + { name = "gurobipy" }, ] [package.metadata] requires-dist = [ - { name = "cyipopt", specifier = ">=1.6.1" }, + { name = "gurobipy", marker = "extra == 'gurobi'", specifier = ">=13.0.2" }, { name = "jax", specifier = ">=0.7.2" }, { name = "jinja2", specifier = ">=3.1.6" }, { name = "jsonargparse", specifier = ">=4.41.0" }, { name = "matplotlib", specifier = ">=3.10.6" }, + { name = "nlls-gram", specifier = ">=0.5.1" }, { name = "pandas", specifier = ">=2.3.2" }, - { name = "pyomo", specifier = ">=6.9.4" }, { name = "quadax", specifier = ">=0.2.9" }, + { name = "unopy", specifier = ">=0.4.10" }, ] +provides-extras = ["gurobi"] [[package]] name = "kiwisolver" -version = "1.4.9" +version = "1.5.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5c/3c/85844f1b0feb11ee581ac23fe5fce65cd049a200c1446708cc1b7f922875/kiwisolver-1.4.9.tar.gz", hash = "sha256:c3b22c26c6fd6811b0ae8363b95ca8ce4ea3c202d3d0975b2914310ceb1bcc4d", size = 97564, upload-time = "2025-08-10T21:27:49.279Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/67/9c61eccb13f0bdca9307614e782fec49ffdde0f7a2314935d489fa93cd9c/kiwisolver-1.5.0.tar.gz", hash = "sha256:d4193f3d9dc3f6f79aaed0e5637f45d98850ebf01f7ca20e69457f3e8946b66a", size = 103482, upload-time = "2026-03-09T13:15:53.382Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/31/c1/c2686cda909742ab66c7388e9a1a8521a59eb89f8bcfbee28fc980d07e24/kiwisolver-1.4.9-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a5d0432ccf1c7ab14f9949eec60c5d1f924f17c037e9f8b33352fa05799359b8", size = 123681, upload-time = "2025-08-10T21:26:26.725Z" }, - { url = "https://files.pythonhosted.org/packages/ca/f0/f44f50c9f5b1a1860261092e3bc91ecdc9acda848a8b8c6abfda4a24dd5c/kiwisolver-1.4.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efb3a45b35622bb6c16dbfab491a8f5a391fe0e9d45ef32f4df85658232ca0e2", size = 66464, upload-time = "2025-08-10T21:26:27.733Z" }, - { url = "https://files.pythonhosted.org/packages/2d/7a/9d90a151f558e29c3936b8a47ac770235f436f2120aca41a6d5f3d62ae8d/kiwisolver-1.4.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1a12cf6398e8a0a001a059747a1cbf24705e18fe413bc22de7b3d15c67cffe3f", size = 64961, upload-time = "2025-08-10T21:26:28.729Z" }, - { url = "https://files.pythonhosted.org/packages/e9/e9/f218a2cb3a9ffbe324ca29a9e399fa2d2866d7f348ec3a88df87fc248fc5/kiwisolver-1.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b67e6efbf68e077dd71d1a6b37e43e1a99d0bff1a3d51867d45ee8908b931098", size = 1474607, upload-time = "2025-08-10T21:26:29.798Z" }, - { url = "https://files.pythonhosted.org/packages/d9/28/aac26d4c882f14de59041636292bc838db8961373825df23b8eeb807e198/kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5656aa670507437af0207645273ccdfee4f14bacd7f7c67a4306d0dcaeaf6eed", size = 1276546, upload-time = "2025-08-10T21:26:31.401Z" }, - { url = "https://files.pythonhosted.org/packages/8b/ad/8bfc1c93d4cc565e5069162f610ba2f48ff39b7de4b5b8d93f69f30c4bed/kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bfc08add558155345129c7803b3671cf195e6a56e7a12f3dde7c57d9b417f525", size = 1294482, upload-time = "2025-08-10T21:26:32.721Z" }, - { url = "https://files.pythonhosted.org/packages/da/f1/6aca55ff798901d8ce403206d00e033191f63d82dd708a186e0ed2067e9c/kiwisolver-1.4.9-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:40092754720b174e6ccf9e845d0d8c7d8e12c3d71e7fc35f55f3813e96376f78", size = 1343720, upload-time = "2025-08-10T21:26:34.032Z" }, - { url = "https://files.pythonhosted.org/packages/d1/91/eed031876c595c81d90d0f6fc681ece250e14bf6998c3d7c419466b523b7/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:497d05f29a1300d14e02e6441cf0f5ee81c1ff5a304b0d9fb77423974684e08b", size = 2224907, upload-time = "2025-08-10T21:26:35.824Z" }, - { url = "https://files.pythonhosted.org/packages/e9/ec/4d1925f2e49617b9cca9c34bfa11adefad49d00db038e692a559454dfb2e/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:bdd1a81a1860476eb41ac4bc1e07b3f07259e6d55bbf739b79c8aaedcf512799", size = 2321334, upload-time = "2025-08-10T21:26:37.534Z" }, - { url = "https://files.pythonhosted.org/packages/43/cb/450cd4499356f68802750c6ddc18647b8ea01ffa28f50d20598e0befe6e9/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:e6b93f13371d341afee3be9f7c5964e3fe61d5fa30f6a30eb49856935dfe4fc3", size = 2488313, upload-time = "2025-08-10T21:26:39.191Z" }, - { url = "https://files.pythonhosted.org/packages/71/67/fc76242bd99f885651128a5d4fa6083e5524694b7c88b489b1b55fdc491d/kiwisolver-1.4.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d75aa530ccfaa593da12834b86a0724f58bff12706659baa9227c2ccaa06264c", size = 2291970, upload-time = "2025-08-10T21:26:40.828Z" }, - { url = "https://files.pythonhosted.org/packages/75/bd/f1a5d894000941739f2ae1b65a32892349423ad49c2e6d0771d0bad3fae4/kiwisolver-1.4.9-cp313-cp313-win_amd64.whl", hash = "sha256:dd0a578400839256df88c16abddf9ba14813ec5f21362e1fe65022e00c883d4d", size = 73894, upload-time = "2025-08-10T21:26:42.33Z" }, - { url = "https://files.pythonhosted.org/packages/95/38/dce480814d25b99a391abbddadc78f7c117c6da34be68ca8b02d5848b424/kiwisolver-1.4.9-cp313-cp313-win_arm64.whl", hash = "sha256:d4188e73af84ca82468f09cadc5ac4db578109e52acb4518d8154698d3a87ca2", size = 64995, upload-time = "2025-08-10T21:26:43.889Z" }, - { url = "https://files.pythonhosted.org/packages/e2/37/7d218ce5d92dadc5ebdd9070d903e0c7cf7edfe03f179433ac4d13ce659c/kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:5a0f2724dfd4e3b3ac5a82436a8e6fd16baa7d507117e4279b660fe8ca38a3a1", size = 126510, upload-time = "2025-08-10T21:26:44.915Z" }, - { url = "https://files.pythonhosted.org/packages/23/b0/e85a2b48233daef4b648fb657ebbb6f8367696a2d9548a00b4ee0eb67803/kiwisolver-1.4.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:1b11d6a633e4ed84fc0ddafd4ebfd8ea49b3f25082c04ad12b8315c11d504dc1", size = 67903, upload-time = "2025-08-10T21:26:45.934Z" }, - { url = "https://files.pythonhosted.org/packages/44/98/f2425bc0113ad7de24da6bb4dae1343476e95e1d738be7c04d31a5d037fd/kiwisolver-1.4.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:61874cdb0a36016354853593cffc38e56fc9ca5aa97d2c05d3dcf6922cd55a11", size = 66402, upload-time = "2025-08-10T21:26:47.101Z" }, - { url = "https://files.pythonhosted.org/packages/98/d8/594657886df9f34c4177cc353cc28ca7e6e5eb562d37ccc233bff43bbe2a/kiwisolver-1.4.9-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:60c439763a969a6af93b4881db0eed8fadf93ee98e18cbc35bc8da868d0c4f0c", size = 1582135, upload-time = "2025-08-10T21:26:48.665Z" }, - { url = "https://files.pythonhosted.org/packages/5c/c6/38a115b7170f8b306fc929e166340c24958347308ea3012c2b44e7e295db/kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92a2f997387a1b79a75e7803aa7ded2cfbe2823852ccf1ba3bcf613b62ae3197", size = 1389409, upload-time = "2025-08-10T21:26:50.335Z" }, - { url = "https://files.pythonhosted.org/packages/bf/3b/e04883dace81f24a568bcee6eb3001da4ba05114afa622ec9b6fafdc1f5e/kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a31d512c812daea6d8b3be3b2bfcbeb091dbb09177706569bcfc6240dcf8b41c", size = 1401763, upload-time = "2025-08-10T21:26:51.867Z" }, - { url = "https://files.pythonhosted.org/packages/9f/80/20ace48e33408947af49d7d15c341eaee69e4e0304aab4b7660e234d6288/kiwisolver-1.4.9-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:52a15b0f35dad39862d376df10c5230155243a2c1a436e39eb55623ccbd68185", size = 1453643, upload-time = "2025-08-10T21:26:53.592Z" }, - { url = "https://files.pythonhosted.org/packages/64/31/6ce4380a4cd1f515bdda976a1e90e547ccd47b67a1546d63884463c92ca9/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a30fd6fdef1430fd9e1ba7b3398b5ee4e2887783917a687d86ba69985fb08748", size = 2330818, upload-time = "2025-08-10T21:26:55.051Z" }, - { url = "https://files.pythonhosted.org/packages/fa/e9/3f3fcba3bcc7432c795b82646306e822f3fd74df0ee81f0fa067a1f95668/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:cc9617b46837c6468197b5945e196ee9ca43057bb7d9d1ae688101e4e1dddf64", size = 2419963, upload-time = "2025-08-10T21:26:56.421Z" }, - { url = "https://files.pythonhosted.org/packages/99/43/7320c50e4133575c66e9f7dadead35ab22d7c012a3b09bb35647792b2a6d/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:0ab74e19f6a2b027ea4f845a78827969af45ce790e6cb3e1ebab71bdf9f215ff", size = 2594639, upload-time = "2025-08-10T21:26:57.882Z" }, - { url = "https://files.pythonhosted.org/packages/65/d6/17ae4a270d4a987ef8a385b906d2bdfc9fce502d6dc0d3aea865b47f548c/kiwisolver-1.4.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dba5ee5d3981160c28d5490f0d1b7ed730c22470ff7f6cc26cfcfaacb9896a07", size = 2391741, upload-time = "2025-08-10T21:26:59.237Z" }, - { url = "https://files.pythonhosted.org/packages/2a/8f/8f6f491d595a9e5912971f3f863d81baddccc8a4d0c3749d6a0dd9ffc9df/kiwisolver-1.4.9-cp313-cp313t-win_arm64.whl", hash = "sha256:0749fd8f4218ad2e851e11cc4dc05c7cbc0cbc4267bdfdb31782e65aace4ee9c", size = 68646, upload-time = "2025-08-10T21:27:00.52Z" }, - { url = "https://files.pythonhosted.org/packages/6b/32/6cc0fbc9c54d06c2969faa9c1d29f5751a2e51809dd55c69055e62d9b426/kiwisolver-1.4.9-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:9928fe1eb816d11ae170885a74d074f57af3a0d65777ca47e9aeb854a1fba386", size = 123806, upload-time = "2025-08-10T21:27:01.537Z" }, - { url = "https://files.pythonhosted.org/packages/b2/dd/2bfb1d4a4823d92e8cbb420fe024b8d2167f72079b3bb941207c42570bdf/kiwisolver-1.4.9-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d0005b053977e7b43388ddec89fa567f43d4f6d5c2c0affe57de5ebf290dc552", size = 66605, upload-time = "2025-08-10T21:27:03.335Z" }, - { url = "https://files.pythonhosted.org/packages/f7/69/00aafdb4e4509c2ca6064646cba9cd4b37933898f426756adb2cb92ebbed/kiwisolver-1.4.9-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:2635d352d67458b66fd0667c14cb1d4145e9560d503219034a18a87e971ce4f3", size = 64925, upload-time = "2025-08-10T21:27:04.339Z" }, - { url = "https://files.pythonhosted.org/packages/43/dc/51acc6791aa14e5cb6d8a2e28cefb0dc2886d8862795449d021334c0df20/kiwisolver-1.4.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:767c23ad1c58c9e827b649a9ab7809fd5fd9db266a9cf02b0e926ddc2c680d58", size = 1472414, upload-time = "2025-08-10T21:27:05.437Z" }, - { url = "https://files.pythonhosted.org/packages/3d/bb/93fa64a81db304ac8a246f834d5094fae4b13baf53c839d6bb6e81177129/kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72d0eb9fba308b8311685c2268cf7d0a0639a6cd027d8128659f72bdd8a024b4", size = 1281272, upload-time = "2025-08-10T21:27:07.063Z" }, - { url = "https://files.pythonhosted.org/packages/70/e6/6df102916960fb8d05069d4bd92d6d9a8202d5a3e2444494e7cd50f65b7a/kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f68e4f3eeca8fb22cc3d731f9715a13b652795ef657a13df1ad0c7dc0e9731df", size = 1298578, upload-time = "2025-08-10T21:27:08.452Z" }, - { url = "https://files.pythonhosted.org/packages/7c/47/e142aaa612f5343736b087864dbaebc53ea8831453fb47e7521fa8658f30/kiwisolver-1.4.9-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d84cd4061ae292d8ac367b2c3fa3aad11cb8625a95d135fe93f286f914f3f5a6", size = 1345607, upload-time = "2025-08-10T21:27:10.125Z" }, - { url = "https://files.pythonhosted.org/packages/54/89/d641a746194a0f4d1a3670fb900d0dbaa786fb98341056814bc3f058fa52/kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a60ea74330b91bd22a29638940d115df9dc00af5035a9a2a6ad9399ffb4ceca5", size = 2230150, upload-time = "2025-08-10T21:27:11.484Z" }, - { url = "https://files.pythonhosted.org/packages/aa/6b/5ee1207198febdf16ac11f78c5ae40861b809cbe0e6d2a8d5b0b3044b199/kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:ce6a3a4e106cf35c2d9c4fa17c05ce0b180db622736845d4315519397a77beaf", size = 2325979, upload-time = "2025-08-10T21:27:12.917Z" }, - { url = "https://files.pythonhosted.org/packages/fc/ff/b269eefd90f4ae14dcc74973d5a0f6d28d3b9bb1afd8c0340513afe6b39a/kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:77937e5e2a38a7b48eef0585114fe7930346993a88060d0bf886086d2aa49ef5", size = 2491456, upload-time = "2025-08-10T21:27:14.353Z" }, - { url = "https://files.pythonhosted.org/packages/fc/d4/10303190bd4d30de547534601e259a4fbf014eed94aae3e5521129215086/kiwisolver-1.4.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:24c175051354f4a28c5d6a31c93906dc653e2bf234e8a4bbfb964892078898ce", size = 2294621, upload-time = "2025-08-10T21:27:15.808Z" }, - { url = "https://files.pythonhosted.org/packages/28/e0/a9a90416fce5c0be25742729c2ea52105d62eda6c4be4d803c2a7be1fa50/kiwisolver-1.4.9-cp314-cp314-win_amd64.whl", hash = "sha256:0763515d4df10edf6d06a3c19734e2566368980d21ebec439f33f9eb936c07b7", size = 75417, upload-time = "2025-08-10T21:27:17.436Z" }, - { url = "https://files.pythonhosted.org/packages/1f/10/6949958215b7a9a264299a7db195564e87900f709db9245e4ebdd3c70779/kiwisolver-1.4.9-cp314-cp314-win_arm64.whl", hash = "sha256:0e4e2bf29574a6a7b7f6cb5fa69293b9f96c928949ac4a53ba3f525dffb87f9c", size = 66582, upload-time = "2025-08-10T21:27:18.436Z" }, - { url = "https://files.pythonhosted.org/packages/ec/79/60e53067903d3bc5469b369fe0dfc6b3482e2133e85dae9daa9527535991/kiwisolver-1.4.9-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:d976bbb382b202f71c67f77b0ac11244021cfa3f7dfd9e562eefcea2df711548", size = 126514, upload-time = "2025-08-10T21:27:19.465Z" }, - { url = "https://files.pythonhosted.org/packages/25/d1/4843d3e8d46b072c12a38c97c57fab4608d36e13fe47d47ee96b4d61ba6f/kiwisolver-1.4.9-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2489e4e5d7ef9a1c300a5e0196e43d9c739f066ef23270607d45aba368b91f2d", size = 67905, upload-time = "2025-08-10T21:27:20.51Z" }, - { url = "https://files.pythonhosted.org/packages/8c/ae/29ffcbd239aea8b93108de1278271ae764dfc0d803a5693914975f200596/kiwisolver-1.4.9-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e2ea9f7ab7fbf18fffb1b5434ce7c69a07582f7acc7717720f1d69f3e806f90c", size = 66399, upload-time = "2025-08-10T21:27:21.496Z" }, - { url = "https://files.pythonhosted.org/packages/a1/ae/d7ba902aa604152c2ceba5d352d7b62106bedbccc8e95c3934d94472bfa3/kiwisolver-1.4.9-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b34e51affded8faee0dfdb705416153819d8ea9250bbbf7ea1b249bdeb5f1122", size = 1582197, upload-time = "2025-08-10T21:27:22.604Z" }, - { url = "https://files.pythonhosted.org/packages/f2/41/27c70d427eddb8bc7e4f16420a20fefc6f480312122a59a959fdfe0445ad/kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8aacd3d4b33b772542b2e01beb50187536967b514b00003bdda7589722d2a64", size = 1390125, upload-time = "2025-08-10T21:27:24.036Z" }, - { url = "https://files.pythonhosted.org/packages/41/42/b3799a12bafc76d962ad69083f8b43b12bf4fe78b097b12e105d75c9b8f1/kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7cf974dd4e35fa315563ac99d6287a1024e4dc2077b8a7d7cd3d2fb65d283134", size = 1402612, upload-time = "2025-08-10T21:27:25.773Z" }, - { url = "https://files.pythonhosted.org/packages/d2/b5/a210ea073ea1cfaca1bb5c55a62307d8252f531beb364e18aa1e0888b5a0/kiwisolver-1.4.9-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:85bd218b5ecfbee8c8a82e121802dcb519a86044c9c3b2e4aef02fa05c6da370", size = 1453990, upload-time = "2025-08-10T21:27:27.089Z" }, - { url = "https://files.pythonhosted.org/packages/5f/ce/a829eb8c033e977d7ea03ed32fb3c1781b4fa0433fbadfff29e39c676f32/kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0856e241c2d3df4efef7c04a1e46b1936b6120c9bcf36dd216e3acd84bc4fb21", size = 2331601, upload-time = "2025-08-10T21:27:29.343Z" }, - { url = "https://files.pythonhosted.org/packages/e0/4b/b5e97eb142eb9cd0072dacfcdcd31b1c66dc7352b0f7c7255d339c0edf00/kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:9af39d6551f97d31a4deebeac6f45b156f9755ddc59c07b402c148f5dbb6482a", size = 2422041, upload-time = "2025-08-10T21:27:30.754Z" }, - { url = "https://files.pythonhosted.org/packages/40/be/8eb4cd53e1b85ba4edc3a9321666f12b83113a178845593307a3e7891f44/kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:bb4ae2b57fc1d8cbd1cf7b1d9913803681ffa903e7488012be5b76dedf49297f", size = 2594897, upload-time = "2025-08-10T21:27:32.803Z" }, - { url = "https://files.pythonhosted.org/packages/99/dd/841e9a66c4715477ea0abc78da039832fbb09dac5c35c58dc4c41a407b8a/kiwisolver-1.4.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:aedff62918805fb62d43a4aa2ecd4482c380dc76cd31bd7c8878588a61bd0369", size = 2391835, upload-time = "2025-08-10T21:27:34.23Z" }, - { url = "https://files.pythonhosted.org/packages/0c/28/4b2e5c47a0da96896fdfdb006340ade064afa1e63675d01ea5ac222b6d52/kiwisolver-1.4.9-cp314-cp314t-win_amd64.whl", hash = "sha256:1fa333e8b2ce4d9660f2cda9c0e1b6bafcfb2457a9d259faa82289e73ec24891", size = 79988, upload-time = "2025-08-10T21:27:35.587Z" }, - { url = "https://files.pythonhosted.org/packages/80/be/3578e8afd18c88cdf9cb4cffde75a96d2be38c5a903f1ed0ceec061bd09e/kiwisolver-1.4.9-cp314-cp314t-win_arm64.whl", hash = "sha256:4a48a2ce79d65d363597ef7b567ce3d14d68783d2b2263d98db3d9477805ba32", size = 70260, upload-time = "2025-08-10T21:27:36.606Z" }, + { url = "https://files.pythonhosted.org/packages/9d/69/024d6711d5ba575aa65d5538042e99964104e97fa153a9f10bc369182bc2/kiwisolver-1.5.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:fd40bb9cd0891c4c3cb1ddf83f8bbfa15731a248fdc8162669405451e2724b09", size = 123166, upload-time = "2026-03-09T13:13:48.032Z" }, + { url = "https://files.pythonhosted.org/packages/ce/48/adbb40df306f587054a348831220812b9b1d787aff714cfbc8556e38fccd/kiwisolver-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c0e1403fd7c26d77c1f03e096dc58a5c726503fa0db0456678b8668f76f521e3", size = 66395, upload-time = "2026-03-09T13:13:49.365Z" }, + { url = "https://files.pythonhosted.org/packages/a8/3a/d0a972b34e1c63e2409413104216cd1caa02c5a37cb668d1687d466c1c45/kiwisolver-1.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dda366d548e89a90d88a86c692377d18d8bd64b39c1fb2b92cb31370e2896bbd", size = 64065, upload-time = "2026-03-09T13:13:50.562Z" }, + { url = "https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3", size = 1477903, upload-time = "2026-03-09T13:13:52.084Z" }, + { url = "https://files.pythonhosted.org/packages/18/d8/55638d89ffd27799d5cc3d8aa28e12f4ce7a64d67b285114dbedc8ea4136/kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c50b89ffd3e1a911c69a1dd3de7173c0cd10b130f56222e57898683841e4f96", size = 1278751, upload-time = "2026-03-09T13:13:54.673Z" }, + { url = "https://files.pythonhosted.org/packages/b8/97/b4c8d0d18421ecceba20ad8701358453b88e32414e6f6950b5a4bad54e65/kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4db576bb8c3ef9365f8b40fe0f671644de6736ae2c27a2c62d7d8a1b4329f099", size = 1296793, upload-time = "2026-03-09T13:13:56.287Z" }, + { url = "https://files.pythonhosted.org/packages/c4/10/f862f94b6389d8957448ec9df59450b81bec4abb318805375c401a1e6892/kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0b85aad90cea8ac6797a53b5d5f2e967334fa4d1149f031c4537569972596cb8", size = 1346041, upload-time = "2026-03-09T13:13:58.269Z" }, + { url = "https://files.pythonhosted.org/packages/a3/6a/f1650af35821eaf09de398ec0bc2aefc8f211f0cda50204c9f1673741ba9/kiwisolver-1.5.0-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:d36ca54cb4c6c4686f7cbb7b817f66f5911c12ddb519450bbe86707155028f87", size = 987292, upload-time = "2026-03-09T13:13:59.871Z" }, + { url = "https://files.pythonhosted.org/packages/de/19/d7fb82984b9238115fe629c915007be608ebd23dc8629703d917dbfaffd4/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:38f4a703656f493b0ad185211ccfca7f0386120f022066b018eb5296d8613e23", size = 2227865, upload-time = "2026-03-09T13:14:01.401Z" }, + { url = "https://files.pythonhosted.org/packages/7f/b9/46b7f386589fd222dac9e9de9c956ce5bcefe2ee73b4e79891381dda8654/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3ac2360e93cb41be81121755c6462cff3beaa9967188c866e5fce5cf13170859", size = 2324369, upload-time = "2026-03-09T13:14:02.972Z" }, + { url = "https://files.pythonhosted.org/packages/92/8b/95e237cf3d9c642960153c769ddcbe278f182c8affb20cecc1cc983e7cc5/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c95cab08d1965db3d84a121f1c7ce7479bdd4072c9b3dafd8fecce48a2e6b902", size = 1977989, upload-time = "2026-03-09T13:14:04.503Z" }, + { url = "https://files.pythonhosted.org/packages/1b/95/980c9df53501892784997820136c01f62bc1865e31b82b9560f980c0e649/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fc20894c3d21194d8041a28b65622d5b86db786da6e3cfe73f0c762951a61167", size = 2491645, upload-time = "2026-03-09T13:14:06.106Z" }, + { url = "https://files.pythonhosted.org/packages/cb/32/900647fd0840abebe1561792c6b31e6a7c0e278fc3973d30572a965ca14c/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7a32f72973f0f950c1920475d5c5ea3d971b81b6f0ec53b8d0a956cc965f22e0", size = 2295237, upload-time = "2026-03-09T13:14:08.891Z" }, + { url = "https://files.pythonhosted.org/packages/be/8a/be60e3bbcf513cc5a50f4a3e88e1dcecebb79c1ad607a7222877becaa101/kiwisolver-1.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bf3acf1419fa93064a4c2189ac0b58e3be7872bf6ee6177b0d4c63dc4cea276", size = 73573, upload-time = "2026-03-09T13:14:12.327Z" }, + { url = "https://files.pythonhosted.org/packages/4d/d2/64be2e429eb4fca7f7e1c52a91b12663aeaf25de3895e5cca0f47ef2a8d0/kiwisolver-1.5.0-cp313-cp313-win_arm64.whl", hash = "sha256:fa8eb9ecdb7efb0b226acec134e0d709e87a909fa4971a54c0c4f6e88635484c", size = 64998, upload-time = "2026-03-09T13:14:13.469Z" }, + { url = "https://files.pythonhosted.org/packages/b0/69/ce68dd0c85755ae2de490bf015b62f2cea5f6b14ff00a463f9d0774449ff/kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:db485b3847d182b908b483b2ed133c66d88d49cacf98fd278fadafe11b4478d1", size = 125700, upload-time = "2026-03-09T13:14:14.636Z" }, + { url = "https://files.pythonhosted.org/packages/74/aa/937aac021cf9d4349990d47eb319309a51355ed1dbdc9c077cdc9224cb11/kiwisolver-1.5.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:be12f931839a3bdfe28b584db0e640a65a8bcbc24560ae3fdb025a449b3d754e", size = 67537, upload-time = "2026-03-09T13:14:15.808Z" }, + { url = "https://files.pythonhosted.org/packages/ee/20/3a87fbece2c40ad0f6f0aefa93542559159c5f99831d596050e8afae7a9f/kiwisolver-1.5.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:16b85d37c2cbb3253226d26e64663f755d88a03439a9c47df6246b35defbdfb7", size = 65514, upload-time = "2026-03-09T13:14:18.035Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7f/f943879cda9007c45e1f7dba216d705c3a18d6b35830e488b6c6a4e7cdf0/kiwisolver-1.5.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4432b835675f0ea7414aab3d37d119f7226d24869b7a829caeab49ebda407b0c", size = 1584848, upload-time = "2026-03-09T13:14:19.745Z" }, + { url = "https://files.pythonhosted.org/packages/37/f8/4d4f85cc1870c127c88d950913370dd76138482161cd07eabbc450deff01/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b0feb50971481a2cc44d94e88bdb02cdd497618252ae226b8eb1201b957e368", size = 1391542, upload-time = "2026-03-09T13:14:21.54Z" }, + { url = "https://files.pythonhosted.org/packages/04/0b/65dd2916c84d252b244bd405303220f729e7c17c9d7d33dca6feeff9ffc4/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56fa888f10d0f367155e76ce849fa1166fc9730d13bd2d65a2aa13b6f5424489", size = 1404447, upload-time = "2026-03-09T13:14:23.205Z" }, + { url = "https://files.pythonhosted.org/packages/39/5c/2606a373247babce9b1d056c03a04b65f3cf5290a8eac5d7bdead0a17e21/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:940dda65d5e764406b9fb92761cbf462e4e63f712ab60ed98f70552e496f3bf1", size = 1455918, upload-time = "2026-03-09T13:14:24.74Z" }, + { url = "https://files.pythonhosted.org/packages/d5/d1/c6078b5756670658e9192a2ef11e939c92918833d2745f85cd14a6004bdf/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_39_riscv64.whl", hash = "sha256:89fc958c702ee9a745e4700378f5d23fddbc46ff89e8fdbf5395c24d5c1452a3", size = 1072856, upload-time = "2026-03-09T13:14:26.597Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c8/7def6ddf16eb2b3741d8b172bdaa9af882b03c78e9b0772975408801fa63/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9027d773c4ff81487181a925945743413f6069634d0b122d0b37684ccf4f1e18", size = 2333580, upload-time = "2026-03-09T13:14:28.237Z" }, + { url = "https://files.pythonhosted.org/packages/9e/87/2ac1fce0eb1e616fcd3c35caa23e665e9b1948bb984f4764790924594128/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:5b233ea3e165e43e35dba1d2b8ecc21cf070b45b65ae17dd2747d2713d942021", size = 2423018, upload-time = "2026-03-09T13:14:30.018Z" }, + { url = "https://files.pythonhosted.org/packages/67/13/c6700ccc6cc218716bfcda4935e4b2997039869b4ad8a94f364c5a3b8e63/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:ce9bf03dad3b46408c08649c6fbd6ca28a9fce0eb32fdfffa6775a13103b5310", size = 2062804, upload-time = "2026-03-09T13:14:32.888Z" }, + { url = "https://files.pythonhosted.org/packages/1b/bd/877056304626943ff0f1f44c08f584300c199b887cb3176cd7e34f1515f1/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:fc4d3f1fb9ca0ae9f97b095963bc6326f1dbfd3779d6679a1e016b9baaa153d3", size = 2597482, upload-time = "2026-03-09T13:14:34.971Z" }, + { url = "https://files.pythonhosted.org/packages/75/19/c60626c47bf0f8ac5dcf72c6c98e266d714f2fbbfd50cf6dab5ede3aaa50/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f443b4825c50a51ee68585522ab4a1d1257fac65896f282b4c6763337ac9f5d2", size = 2394328, upload-time = "2026-03-09T13:14:36.816Z" }, + { url = "https://files.pythonhosted.org/packages/47/84/6a6d5e5bb8273756c27b7d810d47f7ef2f1f9b9fd23c9ee9a3f8c75c9cef/kiwisolver-1.5.0-cp313-cp313t-win_arm64.whl", hash = "sha256:893ff3a711d1b515ba9da14ee090519bad4610ed1962fbe298a434e8c5f8db53", size = 68410, upload-time = "2026-03-09T13:14:38.695Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/060f45052f2a01ad5762c8fdecd6d7a752b43400dc29ff75cd47225a40fd/kiwisolver-1.5.0-cp314-cp314-macosx_10_15_universal2.whl", hash = "sha256:8df31fe574b8b3993cc61764f40941111b25c2d9fea13d3ce24a49907cd2d615", size = 123231, upload-time = "2026-03-09T13:14:41.323Z" }, + { url = "https://files.pythonhosted.org/packages/c2/a7/78da680eadd06ff35edef6ef68a1ad273bad3e2a0936c9a885103230aece/kiwisolver-1.5.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:1d49a49ac4cbfb7c1375301cd1ec90169dfeae55ff84710d782260ce77a75a02", size = 66489, upload-time = "2026-03-09T13:14:42.534Z" }, + { url = "https://files.pythonhosted.org/packages/49/b2/97980f3ad4fae37dd7fe31626e2bf75fbf8bdf5d303950ec1fab39a12da8/kiwisolver-1.5.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0cbe94b69b819209a62cb27bdfa5dc2a8977d8de2f89dfd97ba4f53ed3af754e", size = 64063, upload-time = "2026-03-09T13:14:44.759Z" }, + { url = "https://files.pythonhosted.org/packages/e7/f9/b06c934a6aa8bc91f566bd2a214fd04c30506c2d9e2b6b171953216a65b6/kiwisolver-1.5.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:80aa065ffd378ff784822a6d7c3212f2d5f5e9c3589614b5c228b311fd3063ac", size = 1475913, upload-time = "2026-03-09T13:14:46.247Z" }, + { url = "https://files.pythonhosted.org/packages/6b/f0/f768ae564a710135630672981231320bc403cf9152b5596ec5289de0f106/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e7f886f47ab881692f278ae901039a234e4025a68e6dfab514263a0b1c4ae05", size = 1282782, upload-time = "2026-03-09T13:14:48.458Z" }, + { url = "https://files.pythonhosted.org/packages/e2/9f/1de7aad00697325f05238a5f2eafbd487fb637cc27a558b5367a5f37fb7f/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5060731cc3ed12ca3a8b57acd4aeca5bbc2f49216dd0bec1650a1acd89486bcd", size = 1300815, upload-time = "2026-03-09T13:14:50.721Z" }, + { url = "https://files.pythonhosted.org/packages/5a/c2/297f25141d2e468e0ce7f7a7b92e0cf8918143a0cbd3422c1ad627e85a06/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a4aa69609f40fce3cbc3f87b2061f042eee32f94b8f11db707b66a26461591a", size = 1347925, upload-time = "2026-03-09T13:14:52.304Z" }, + { url = "https://files.pythonhosted.org/packages/b9/d3/f4c73a02eb41520c47610207b21afa8cdd18fdbf64ffd94674ae21c4812d/kiwisolver-1.5.0-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:d168fda2dbff7b9b5f38e693182d792a938c31db4dac3a80a4888de603c99554", size = 991322, upload-time = "2026-03-09T13:14:54.637Z" }, + { url = "https://files.pythonhosted.org/packages/7b/46/d3f2efef7732fcda98d22bf4ad5d3d71d545167a852ca710a494f4c15343/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:413b820229730d358efd838ecbab79902fe97094565fdc80ddb6b0a18c18a581", size = 2232857, upload-time = "2026-03-09T13:14:56.471Z" }, + { url = "https://files.pythonhosted.org/packages/3f/ec/2d9756bf2b6d26ae4349b8d3662fb3993f16d80c1f971c179ce862b9dbae/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:5124d1ea754509b09e53738ec185584cc609aae4a3b510aaf4ed6aa047ef9303", size = 2329376, upload-time = "2026-03-09T13:14:58.072Z" }, + { url = "https://files.pythonhosted.org/packages/8f/9f/876a0a0f2260f1bde92e002b3019a5fabc35e0939c7d945e0fa66185eb20/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e4415a8db000bf49a6dd1c478bf70062eaacff0f462b92b0ba68791a905861f9", size = 1982549, upload-time = "2026-03-09T13:14:59.668Z" }, + { url = "https://files.pythonhosted.org/packages/6c/4f/ba3624dfac23a64d54ac4179832860cb537c1b0af06024936e82ca4154a0/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d618fd27420381a4f6044faa71f46d8bfd911bd077c555f7138ed88729bfbe79", size = 2494680, upload-time = "2026-03-09T13:15:01.364Z" }, + { url = "https://files.pythonhosted.org/packages/39/b7/97716b190ab98911b20d10bf92eca469121ec483b8ce0edd314f51bc85af/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5092eb5b1172947f57d6ea7d89b2f29650414e4293c47707eb499ec07a0ac796", size = 2297905, upload-time = "2026-03-09T13:15:03.925Z" }, + { url = "https://files.pythonhosted.org/packages/a3/36/4e551e8aa55c9188bca9abb5096805edbf7431072b76e2298e34fd3a3008/kiwisolver-1.5.0-cp314-cp314-win_amd64.whl", hash = "sha256:d76e2d8c75051d58177e762164d2e9ab92886534e3a12e795f103524f221dd8e", size = 75086, upload-time = "2026-03-09T13:15:07.775Z" }, + { url = "https://files.pythonhosted.org/packages/70/15/9b90f7df0e31a003c71649cf66ef61c3c1b862f48c81007fa2383c8bd8d7/kiwisolver-1.5.0-cp314-cp314-win_arm64.whl", hash = "sha256:fa6248cd194edff41d7ea9425ced8ca3a6f838bfb295f6f1d6e6bb694a8518df", size = 66577, upload-time = "2026-03-09T13:15:09.139Z" }, + { url = "https://files.pythonhosted.org/packages/17/01/7dc8c5443ff42b38e72731643ed7cf1ed9bf01691ae5cdca98501999ed83/kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_universal2.whl", hash = "sha256:d1ffeb80b5676463d7a7d56acbe8e37a20ce725570e09549fe738e02ca6b7e1e", size = 125794, upload-time = "2026-03-09T13:15:10.525Z" }, + { url = "https://files.pythonhosted.org/packages/46/8a/b4ebe46ebaac6a303417fab10c2e165c557ddaff558f9699d302b256bc53/kiwisolver-1.5.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:bc4d8e252f532ab46a1de9349e2d27b91fce46736a9eedaa37beaca66f574ed4", size = 67646, upload-time = "2026-03-09T13:15:12.016Z" }, + { url = "https://files.pythonhosted.org/packages/60/35/10a844afc5f19d6f567359bf4789e26661755a2f36200d5d1ed8ad0126e5/kiwisolver-1.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6783e069732715ad0c3ce96dbf21dbc2235ab0593f2baf6338101f70371f4028", size = 65511, upload-time = "2026-03-09T13:15:13.311Z" }, + { url = "https://files.pythonhosted.org/packages/f8/8a/685b297052dd041dcebce8e8787b58923b6e78acc6115a0dc9189011c44b/kiwisolver-1.5.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e7c4c09a490dc4d4a7f8cbee56c606a320f9dc28cf92a7157a39d1ce7676a657", size = 1584858, upload-time = "2026-03-09T13:15:15.103Z" }, + { url = "https://files.pythonhosted.org/packages/9e/80/04865e3d4638ac5bddec28908916df4a3075b8c6cc101786a96803188b96/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a075bd7bd19c70cf67c8badfa36cf7c5d8de3c9ddb8420c51e10d9c50e94920", size = 1392539, upload-time = "2026-03-09T13:15:16.661Z" }, + { url = "https://files.pythonhosted.org/packages/ba/01/77a19cacc0893fa13fafa46d1bba06fb4dc2360b3292baf4b56d8e067b24/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bdd3e53429ff02aa319ba59dfe4ceeec345bf46cf180ec2cf6fd5b942e7975e9", size = 1405310, upload-time = "2026-03-09T13:15:18.229Z" }, + { url = "https://files.pythonhosted.org/packages/53/39/bcaf5d0cca50e604cfa9b4e3ae1d64b50ca1ae5b754122396084599ef903/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cdcb35dc9d807259c981a85531048ede628eabcffb3239adf3d17463518992d", size = 1456244, upload-time = "2026-03-09T13:15:20.444Z" }, + { url = "https://files.pythonhosted.org/packages/d0/7a/72c187abc6975f6978c3e39b7cf67aeb8b3c0a8f9790aa7fd412855e9e1f/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:70d593af6a6ca332d1df73d519fddb5148edb15cd90d5f0155e3746a6d4fcc65", size = 1073154, upload-time = "2026-03-09T13:15:22.039Z" }, + { url = "https://files.pythonhosted.org/packages/c7/ca/cf5b25783ebbd59143b4371ed0c8428a278abe68d6d0104b01865b1bbd0f/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:377815a8616074cabbf3f53354e1d040c35815a134e01d7614b7692e4bf8acfa", size = 2334377, upload-time = "2026-03-09T13:15:23.741Z" }, + { url = "https://files.pythonhosted.org/packages/4a/e5/b1f492adc516796e88751282276745340e2a72dcd0d36cf7173e0daf3210/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0255a027391d52944eae1dbb5d4cc5903f57092f3674e8e544cdd2622826b3f0", size = 2425288, upload-time = "2026-03-09T13:15:25.789Z" }, + { url = "https://files.pythonhosted.org/packages/e6/e5/9b21fbe91a61b8f409d74a26498706e97a48008bfcd1864373d32a6ba31c/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:012b1eb16e28718fa782b5e61dc6f2da1f0792ca73bd05d54de6cb9561665fc9", size = 2063158, upload-time = "2026-03-09T13:15:27.63Z" }, + { url = "https://files.pythonhosted.org/packages/b1/02/83f47986138310f95ea95531f851b2a62227c11cbc3e690ae1374fe49f0f/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0e3aafb33aed7479377e5e9a82e9d4bf87063741fc99fc7ae48b0f16e32bdd6f", size = 2597260, upload-time = "2026-03-09T13:15:29.421Z" }, + { url = "https://files.pythonhosted.org/packages/07/18/43a5f24608d8c313dd189cf838c8e68d75b115567c6279de7796197cfb6a/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e7a116ae737f0000343218c4edf5bd45893bfeaff0993c0b215d7124c9f77646", size = 2394403, upload-time = "2026-03-09T13:15:31.517Z" }, + { url = "https://files.pythonhosted.org/packages/3b/b5/98222136d839b8afabcaa943b09bd05888c2d36355b7e448550211d1fca4/kiwisolver-1.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:1dd9b0b119a350976a6d781e7278ec7aca0b201e1a9e2d23d9804afecb6ca681", size = 79687, upload-time = "2026-03-09T13:15:33.204Z" }, + { url = "https://files.pythonhosted.org/packages/99/a2/ca7dc962848040befed12732dff6acae7fb3c4f6fc4272b3f6c9a30b8713/kiwisolver-1.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:58f812017cd2985c21fbffb4864d59174d4903dd66fa23815e74bbc7a0e2dd57", size = 70032, upload-time = "2026-03-09T13:15:34.411Z" }, +] + +[[package]] +name = "lineax" +version = "0.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "equinox" }, + { name = "jax" }, + { name = "jaxtyping" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/77/e0/b7e501899cebd6dc609a01645350afa7976d40a8f3c0bfdf4560e448b2b7/lineax-0.1.1.tar.gz", hash = "sha256:187b8ea93b8e1099fb792e81c6e71a9c269f4fcadbb5313fe312d5847f581f9d", size = 53195, upload-time = "2026-05-01T15:59:06.793Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/f8/0d32243c6b8e5dbee9097cf0c95bbdf8681ba4463c927c2e3445f3775814/lineax-0.1.1-py3-none-any.whl", hash = "sha256:2e399f1674773ab2ba54d76175a618977a554f47abd0a345198d53d92c07beb2", size = 77567, upload-time = "2026-05-01T15:59:05.517Z" }, ] [[package]] name = "markupsafe" -version = "3.0.2" +version = "3.0.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274, upload-time = "2024-10-18T15:21:24.577Z" }, - { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352, upload-time = "2024-10-18T15:21:25.382Z" }, - { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122, upload-time = "2024-10-18T15:21:26.199Z" }, - { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085, upload-time = "2024-10-18T15:21:27.029Z" }, - { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978, upload-time = "2024-10-18T15:21:27.846Z" }, - { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208, upload-time = "2024-10-18T15:21:28.744Z" }, - { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357, upload-time = "2024-10-18T15:21:29.545Z" }, - { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344, upload-time = "2024-10-18T15:21:30.366Z" }, - { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101, upload-time = "2024-10-18T15:21:31.207Z" }, - { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603, upload-time = "2024-10-18T15:21:32.032Z" }, - { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510, upload-time = "2024-10-18T15:21:33.625Z" }, - { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486, upload-time = "2024-10-18T15:21:34.611Z" }, - { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480, upload-time = "2024-10-18T15:21:35.398Z" }, - { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914, upload-time = "2024-10-18T15:21:36.231Z" }, - { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796, upload-time = "2024-10-18T15:21:37.073Z" }, - { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473, upload-time = "2024-10-18T15:21:37.932Z" }, - { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114, upload-time = "2024-10-18T15:21:39.799Z" }, - { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload-time = "2024-10-18T15:21:40.813Z" }, - { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload-time = "2024-10-18T15:21:41.814Z" }, - { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload-time = "2024-10-18T15:21:42.784Z" }, + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, ] [[package]] name = "matplotlib" -version = "3.10.6" +version = "3.11.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "contourpy" }, @@ -330,115 +402,130 @@ dependencies = [ { name = "pyparsing" }, { name = "python-dateutil" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a0/59/c3e6453a9676ffba145309a73c462bb407f4400de7de3f2b41af70720a3c/matplotlib-3.10.6.tar.gz", hash = "sha256:ec01b645840dd1996df21ee37f208cd8ba57644779fa20464010638013d3203c", size = 34804264, upload-time = "2025-08-30T00:14:25.137Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1f/24/080c99d223d158d3a8902769269ab6da5b50f7a0e6e072513907e02b7a6c/matplotlib-3.11.0.tar.gz", hash = "sha256:68c0c7be01b30dcca3638934f7f591df73401235cbdbf0d1ab1c71e7db7f8b57", size = 33251176, upload-time = "2026-06-12T02:29:15.508Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/db/18380e788bb837e724358287b08e223b32bc8dccb3b0c12fa8ca20bc7f3b/matplotlib-3.10.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:819e409653c1106c8deaf62e6de6b8611449c2cd9939acb0d7d4e57a3d95cc7a", size = 8273231, upload-time = "2025-08-30T00:13:13.881Z" }, - { url = "https://files.pythonhosted.org/packages/d3/0f/38dd49445b297e0d4f12a322c30779df0d43cb5873c7847df8a82e82ec67/matplotlib-3.10.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:59c8ac8382fefb9cb71308dde16a7c487432f5255d8f1fd32473523abecfecdf", size = 8128730, upload-time = "2025-08-30T00:13:15.556Z" }, - { url = "https://files.pythonhosted.org/packages/e5/b8/9eea6630198cb303d131d95d285a024b3b8645b1763a2916fddb44ca8760/matplotlib-3.10.6-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:84e82d9e0fd70c70bc55739defbd8055c54300750cbacf4740c9673a24d6933a", size = 8698539, upload-time = "2025-08-30T00:13:17.297Z" }, - { url = "https://files.pythonhosted.org/packages/71/34/44c7b1f075e1ea398f88aeabcc2907c01b9cc99e2afd560c1d49845a1227/matplotlib-3.10.6-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25f7a3eb42d6c1c56e89eacd495661fc815ffc08d9da750bca766771c0fd9110", size = 9529702, upload-time = "2025-08-30T00:13:19.248Z" }, - { url = "https://files.pythonhosted.org/packages/b5/7f/e5c2dc9950c7facaf8b461858d1b92c09dd0cf174fe14e21953b3dda06f7/matplotlib-3.10.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f9c862d91ec0b7842920a4cfdaaec29662195301914ea54c33e01f1a28d014b2", size = 9593742, upload-time = "2025-08-30T00:13:21.181Z" }, - { url = "https://files.pythonhosted.org/packages/ff/1d/70c28528794f6410ee2856cd729fa1f1756498b8d3126443b0a94e1a8695/matplotlib-3.10.6-cp313-cp313-win_amd64.whl", hash = "sha256:1b53bd6337eba483e2e7d29c5ab10eee644bc3a2491ec67cc55f7b44583ffb18", size = 8122753, upload-time = "2025-08-30T00:13:23.44Z" }, - { url = "https://files.pythonhosted.org/packages/e8/74/0e1670501fc7d02d981564caf7c4df42974464625935424ca9654040077c/matplotlib-3.10.6-cp313-cp313-win_arm64.whl", hash = "sha256:cbd5eb50b7058b2892ce45c2f4e92557f395c9991f5c886d1bb74a1582e70fd6", size = 7992973, upload-time = "2025-08-30T00:13:26.632Z" }, - { url = "https://files.pythonhosted.org/packages/b1/4e/60780e631d73b6b02bd7239f89c451a72970e5e7ec34f621eda55cd9a445/matplotlib-3.10.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:acc86dd6e0e695c095001a7fccff158c49e45e0758fdf5dcdbb0103318b59c9f", size = 8316869, upload-time = "2025-08-30T00:13:28.262Z" }, - { url = "https://files.pythonhosted.org/packages/f8/15/baa662374a579413210fc2115d40c503b7360a08e9cc254aa0d97d34b0c1/matplotlib-3.10.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e228cd2ffb8f88b7d0b29e37f68ca9aaf83e33821f24a5ccc4f082dd8396bc27", size = 8178240, upload-time = "2025-08-30T00:13:30.007Z" }, - { url = "https://files.pythonhosted.org/packages/c6/3f/3c38e78d2aafdb8829fcd0857d25aaf9e7dd2dfcf7ec742765b585774931/matplotlib-3.10.6-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:658bc91894adeab669cf4bb4a186d049948262987e80f0857216387d7435d833", size = 8711719, upload-time = "2025-08-30T00:13:31.72Z" }, - { url = "https://files.pythonhosted.org/packages/96/4b/2ec2bbf8cefaa53207cc56118d1fa8a0f9b80642713ea9390235d331ede4/matplotlib-3.10.6-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8913b7474f6dd83ac444c9459c91f7f0f2859e839f41d642691b104e0af056aa", size = 9541422, upload-time = "2025-08-30T00:13:33.611Z" }, - { url = "https://files.pythonhosted.org/packages/83/7d/40255e89b3ef11c7871020563b2dd85f6cb1b4eff17c0f62b6eb14c8fa80/matplotlib-3.10.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:091cea22e059b89f6d7d1a18e2c33a7376c26eee60e401d92a4d6726c4e12706", size = 9594068, upload-time = "2025-08-30T00:13:35.833Z" }, - { url = "https://files.pythonhosted.org/packages/f0/a9/0213748d69dc842537a113493e1c27daf9f96bd7cc316f933dc8ec4de985/matplotlib-3.10.6-cp313-cp313t-win_amd64.whl", hash = "sha256:491e25e02a23d7207629d942c666924a6b61e007a48177fdd231a0097b7f507e", size = 8200100, upload-time = "2025-08-30T00:13:37.668Z" }, - { url = "https://files.pythonhosted.org/packages/be/15/79f9988066ce40b8a6f1759a934ea0cde8dc4adc2262255ee1bc98de6ad0/matplotlib-3.10.6-cp313-cp313t-win_arm64.whl", hash = "sha256:3d80d60d4e54cda462e2cd9a086d85cd9f20943ead92f575ce86885a43a565d5", size = 8042142, upload-time = "2025-08-30T00:13:39.426Z" }, - { url = "https://files.pythonhosted.org/packages/7c/58/e7b6d292beae6fb4283ca6fb7fa47d7c944a68062d6238c07b497dd35493/matplotlib-3.10.6-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:70aaf890ce1d0efd482df969b28a5b30ea0b891224bb315810a3940f67182899", size = 8273802, upload-time = "2025-08-30T00:13:41.006Z" }, - { url = "https://files.pythonhosted.org/packages/9f/f6/7882d05aba16a8cdd594fb9a03a9d3cca751dbb6816adf7b102945522ee9/matplotlib-3.10.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:1565aae810ab79cb72e402b22facfa6501365e73ebab70a0fdfb98488d2c3c0c", size = 8131365, upload-time = "2025-08-30T00:13:42.664Z" }, - { url = "https://files.pythonhosted.org/packages/94/bf/ff32f6ed76e78514e98775a53715eca4804b12bdcf35902cdd1cf759d324/matplotlib-3.10.6-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f3b23315a01981689aa4e1a179dbf6ef9fbd17143c3eea77548c2ecfb0499438", size = 9533961, upload-time = "2025-08-30T00:13:44.372Z" }, - { url = "https://files.pythonhosted.org/packages/fe/c3/6bf88c2fc2da7708a2ff8d2eeb5d68943130f50e636d5d3dcf9d4252e971/matplotlib-3.10.6-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:30fdd37edf41a4e6785f9b37969de57aea770696cb637d9946eb37470c94a453", size = 9804262, upload-time = "2025-08-30T00:13:46.614Z" }, - { url = "https://files.pythonhosted.org/packages/0f/7a/e05e6d9446d2d577b459427ad060cd2de5742d0e435db3191fea4fcc7e8b/matplotlib-3.10.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:bc31e693da1c08012c764b053e702c1855378e04102238e6a5ee6a7117c53a47", size = 9595508, upload-time = "2025-08-30T00:13:48.731Z" }, - { url = "https://files.pythonhosted.org/packages/39/fb/af09c463ced80b801629fd73b96f726c9f6124c3603aa2e480a061d6705b/matplotlib-3.10.6-cp314-cp314-win_amd64.whl", hash = "sha256:05be9bdaa8b242bc6ff96330d18c52f1fc59c6fb3a4dd411d953d67e7e1baf98", size = 8252742, upload-time = "2025-08-30T00:13:50.539Z" }, - { url = "https://files.pythonhosted.org/packages/b1/f9/b682f6db9396d9ab8f050c0a3bfbb5f14fb0f6518f08507c04cc02f8f229/matplotlib-3.10.6-cp314-cp314-win_arm64.whl", hash = "sha256:f56a0d1ab05d34c628592435781d185cd99630bdfd76822cd686fb5a0aecd43a", size = 8124237, upload-time = "2025-08-30T00:13:54.3Z" }, - { url = "https://files.pythonhosted.org/packages/b5/d2/b69b4a0923a3c05ab90527c60fdec899ee21ca23ede7f0fb818e6620d6f2/matplotlib-3.10.6-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:94f0b4cacb23763b64b5dace50d5b7bfe98710fed5f0cef5c08135a03399d98b", size = 8316956, upload-time = "2025-08-30T00:13:55.932Z" }, - { url = "https://files.pythonhosted.org/packages/28/e9/dc427b6f16457ffaeecb2fc4abf91e5adb8827861b869c7a7a6d1836fa73/matplotlib-3.10.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:cc332891306b9fb39462673d8225d1b824c89783fee82840a709f96714f17a5c", size = 8178260, upload-time = "2025-08-30T00:14:00.942Z" }, - { url = "https://files.pythonhosted.org/packages/c4/89/1fbd5ad611802c34d1c7ad04607e64a1350b7fb9c567c4ec2c19e066ed35/matplotlib-3.10.6-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee1d607b3fb1590deb04b69f02ea1d53ed0b0bf75b2b1a5745f269afcbd3cdd3", size = 9541422, upload-time = "2025-08-30T00:14:02.664Z" }, - { url = "https://files.pythonhosted.org/packages/b0/3b/65fec8716025b22c1d72d5a82ea079934c76a547696eaa55be6866bc89b1/matplotlib-3.10.6-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:376a624a218116461696b27b2bbf7a8945053e6d799f6502fc03226d077807bf", size = 9803678, upload-time = "2025-08-30T00:14:04.741Z" }, - { url = "https://files.pythonhosted.org/packages/c7/b0/40fb2b3a1ab9381bb39a952e8390357c8be3bdadcf6d5055d9c31e1b35ae/matplotlib-3.10.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:83847b47f6524c34b4f2d3ce726bb0541c48c8e7692729865c3df75bfa0f495a", size = 9594077, upload-time = "2025-08-30T00:14:07.012Z" }, - { url = "https://files.pythonhosted.org/packages/76/34/c4b71b69edf5b06e635eee1ed10bfc73cf8df058b66e63e30e6a55e231d5/matplotlib-3.10.6-cp314-cp314t-win_amd64.whl", hash = "sha256:c7e0518e0d223683532a07f4b512e2e0729b62674f1b3a1a69869f98e6b1c7e3", size = 8342822, upload-time = "2025-08-30T00:14:09.041Z" }, - { url = "https://files.pythonhosted.org/packages/e8/62/aeabeef1a842b6226a30d49dd13e8a7a1e81e9ec98212c0b5169f0a12d83/matplotlib-3.10.6-cp314-cp314t-win_arm64.whl", hash = "sha256:4dd83e029f5b4801eeb87c64efd80e732452781c16a9cf7415b7b63ec8f374d7", size = 8172588, upload-time = "2025-08-30T00:14:11.166Z" }, + { url = "https://files.pythonhosted.org/packages/55/41/aa47f156b061d14c98b906f76c428507397708ec63ff94f410ae1752b426/matplotlib-3.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6ce3b839b34ae1f430b4616893a2945a2999debaa7e94e7e29a2a8bbf286f7b5", size = 9450532, upload-time = "2026-06-12T02:28:06.769Z" }, + { url = "https://files.pythonhosted.org/packages/8c/4f/5a9eb0375e81413953febf8af7b012a6b6357f53438a15c4f5ad86c6bbb5/matplotlib-3.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:373db8f91214e8ccaf35ac833cc1dd59dd961e148bbd55dd027141591dde1313", size = 9279760, upload-time = "2026-06-12T02:28:09.152Z" }, + { url = "https://files.pythonhosted.org/packages/a4/c0/1117d53077e3ac3152503a84e9cf7a5c239576805ee71276e80c2aaa7471/matplotlib-3.11.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:be152b7570324dc8d01574cc9474dd2d803237acf528bcbb5b211fa347461a09", size = 10031623, upload-time = "2026-06-12T02:28:11.26Z" }, + { url = "https://files.pythonhosted.org/packages/92/7e/e937138daffad65b71bf831a377809dcbc830fb4f31a31e067dc1faa2575/matplotlib-3.11.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:126f256df600652d7e4b394cf3164ff75210a00038f287c95a012a6f58d0e83f", size = 10839372, upload-time = "2026-06-12T02:28:14.102Z" }, + { url = "https://files.pythonhosted.org/packages/1d/c2/438ecc197ffb8023b6b9922915542f2172f5fd45b76703b0b4fc47322243/matplotlib-3.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:03acfeddf87b0dddb11b081ef7740ad445a3ca8bcb6b8e3011b08f2cf802b75c", size = 10924099, upload-time = "2026-06-12T02:28:16.383Z" }, + { url = "https://files.pythonhosted.org/packages/40/2e/395883da416f378b3ed2c9f3e843ac477eae1ce731b671b79adaa6f0bacd/matplotlib-3.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:ab3722f04f3ff34c23b5012c5873d2894174e06c3822fcdac3610965a5ac7d06", size = 9329727, upload-time = "2026-06-12T02:28:18.581Z" }, + { url = "https://files.pythonhosted.org/packages/61/82/2c388956abf8bf392dfb5b8917c502f1082df6a941b781ab8c8e5ba2474b/matplotlib-3.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:c945824670fb8915b4ac879e5e61f3c58e0913022f70a0de4c082b17372f8771", size = 9003506, upload-time = "2026-06-12T02:28:20.474Z" }, + { url = "https://files.pythonhosted.org/packages/c8/c1/34454baa44da7975ada82e9aea37105ec47059514dc967d3be14426ba8dc/matplotlib-3.11.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3489c3dc487669b4a980bc3068f87856de7a1564248d3f6c629efb2a58b03f24", size = 9499838, upload-time = "2026-06-12T02:28:22.713Z" }, + { url = "https://files.pythonhosted.org/packages/b1/c3/98fe79a398cf232219f090163a7fa7e6766e9f2e0ad26df54d6f8934d8ee/matplotlib-3.11.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:6a98f5476ce784a50ce09998f4ae1e6a9f25043cef8a480c98949902eda74620", size = 9332298, upload-time = "2026-06-12T02:28:24.796Z" }, + { url = "https://files.pythonhosted.org/packages/95/e4/b4b7c33151e74e5c802f3cde1ba807ebfc38401e329b44e215a5888dd76d/matplotlib-3.11.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:565af866fd63e4bd3f987d580afe27c44c2552a3b3305f4ecbb85133601ea6f3", size = 10045491, upload-time = "2026-06-12T02:28:27.141Z" }, + { url = "https://files.pythonhosted.org/packages/71/28/394548efd68354110c1a1be11fe6b6e559e06d1a23da35908a0e316c55a9/matplotlib-3.11.0-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e6b3e64dea5062c570f04358e2711859f3531b459f29516274fbad889079e4f3", size = 10857059, upload-time = "2026-06-12T02:28:29.222Z" }, + { url = "https://files.pythonhosted.org/packages/c8/44/e7922e6e2a4d63bdfbc9dc4a53e3850ab438d46cf42e6779bb15ec92c948/matplotlib-3.11.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:942b37c5db1899610bd1543ce8e13e4ecff9a4633e7f63bb6aa9205d2644ebd1", size = 10939576, upload-time = "2026-06-12T02:28:31.66Z" }, + { url = "https://files.pythonhosted.org/packages/3d/be/b1ca96003a441d619b727fee21d671fdff7a5ce2f1bb797b2521aa2f679a/matplotlib-3.11.0-cp313-cp313t-win_amd64.whl", hash = "sha256:c08e649a6313e1291e713623b97a38e5bb4aa580b2a100a94a3309bc6b9c8eb3", size = 9379519, upload-time = "2026-06-12T02:28:33.888Z" }, + { url = "https://files.pythonhosted.org/packages/e3/72/4bf3b91821c34596dd6a7bdac5836d94f744144c8208939ef49d8ec43f7e/matplotlib-3.11.0-cp313-cp313t-win_arm64.whl", hash = "sha256:2746cd2c113742ff6ce37a864c5ac5fd7aa644568f445e66166e457ac78e40e0", size = 9055456, upload-time = "2026-06-12T02:28:35.878Z" }, + { url = "https://files.pythonhosted.org/packages/57/52/a94102ac99eb78e2fe9b826674f9ef9ee23327110ea6ab4776c1b4eb6209/matplotlib-3.11.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3338e3e3de128cf50d0d2fb92a122815daf9c755bd882a474343c05f8fd7ec79", size = 9452137, upload-time = "2026-06-12T02:28:37.93Z" }, + { url = "https://files.pythonhosted.org/packages/7c/03/b8cdb625a21f710dfa11bbca1f48fb4057d2c0286975f8b415bf80942c99/matplotlib-3.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:25c2e5455efd8d99f41fb79871a31feb7d301569642e332ec58d72cfe9282bc3", size = 9281514, upload-time = "2026-06-12T02:28:40.028Z" }, + { url = "https://files.pythonhosted.org/packages/b7/2d/4e1240ea82ee197dfb3851e71f71c87eeeb975f1753b56a0588e4e80739a/matplotlib-3.11.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9695457a467ff86d23f35037a43deb6f1134dd6d3e2ac8ce1e2087cff09ffb9", size = 10843005, upload-time = "2026-06-12T02:28:42.39Z" }, + { url = "https://files.pythonhosted.org/packages/29/dc/6377ecfaa5fef79430f74a1a16638b4e2aa30d4692bae2c19f9d76fe3b01/matplotlib-3.11.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:19c16c61dea63b3582918503e6b294193961261d9daa806d4ae2151f1ad05430", size = 11127459, upload-time = "2026-06-12T02:28:44.483Z" }, + { url = "https://files.pythonhosted.org/packages/6f/41/795c405aa7560443a3b01309424cde4a1113b85c90b8a63417444a749617/matplotlib-3.11.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2d72ea8b7924f3cb955e61518d21e43b3df1e6c8a793b480a0c1214f185d30ba", size = 10925160, upload-time = "2026-06-12T02:28:46.564Z" }, + { url = "https://files.pythonhosted.org/packages/1a/f7/3a9e6389a7cfaeff76c56e40c2dabcb13110e21e82f837228c834ebe748c/matplotlib-3.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:1c02da0a629dfa9debf52725ea06866b74c1fb70a895bae05e4493d34074f9f2", size = 9485186, upload-time = "2026-06-12T02:28:49.344Z" }, + { url = "https://files.pythonhosted.org/packages/8b/c0/396478ee7cf2091d182db8b4a8695f6a37f1ddb978989cf9dbb84cd5c123/matplotlib-3.11.0-cp314-cp314-win_arm64.whl", hash = "sha256:aa55d73b3117d4b07f959cd9eb6f69b375d8df3414139c479388e551aa5d999d", size = 9160349, upload-time = "2026-06-12T02:28:51.382Z" }, + { url = "https://files.pythonhosted.org/packages/c5/6f/1c3bd51bb2b34eaacdcf3c3d859dbb357f952fc8020c617dc118ad7c9e38/matplotlib-3.11.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:a9d8c6e7cd2f0ddf11d8d92e520dd1d9d2abb0cf6ac8831e338666c81e905847", size = 9500921, upload-time = "2026-06-12T02:28:53.443Z" }, + { url = "https://files.pythonhosted.org/packages/e0/0d/4d861d0121840cb1a3fd4a10deb211efd6fccd481ed23e553f31f4f4da4a/matplotlib-3.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:be050fcf32f729eda99f7f75a80bf67612ce16ab9ac1c23a387dcaede95cb70e", size = 9332190, upload-time = "2026-06-12T02:28:55.623Z" }, + { url = "https://files.pythonhosted.org/packages/4b/cb/22f6bc35711a0b5639a784e74e653e77c86210bd4304449dd399a482f74e/matplotlib-3.11.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dfabef0230d0697aa0d717385194dd41162e00207a68bf4abf94c2bf4c27dca0", size = 10854181, upload-time = "2026-06-12T02:28:57.856Z" }, + { url = "https://files.pythonhosted.org/packages/3f/7e/9a9eaca731a2939589da520f0ebe8fd8753d0f51fca98c7d20af6dbe261a/matplotlib-3.11.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1644db30e759199443493ac5e5caec24fdb775a8f6123021f85ba47c4133c3cb", size = 11137715, upload-time = "2026-06-12T02:29:00.555Z" }, + { url = "https://files.pythonhosted.org/packages/ef/f9/9b030b6088354acb0296871bb624b25befc1c42509d3c6cd17420c83a5b8/matplotlib-3.11.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:15b0d160079cb10699a0e98b5989c70677b2df7cacdc62af67c30f2facec46d9", size = 10939427, upload-time = "2026-06-12T02:29:02.527Z" }, + { url = "https://files.pythonhosted.org/packages/59/94/6b273eaee4ee250863567d100865da61a5c1527fa67f527b7ed22e0dd29c/matplotlib-3.11.0-cp314-cp314t-win_amd64.whl", hash = "sha256:446307e6b04b57b1f1239e228a1ec2af0d589a1008cebc3dfa3f5441d095cfb6", size = 9535809, upload-time = "2026-06-12T02:29:04.994Z" }, + { url = "https://files.pythonhosted.org/packages/60/95/1d36bddf2b7e2692c1540e78a6e5bc88bc1496b137e3e35a611f91b65ac3/matplotlib-3.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:652fb5696271d4c50f196d22a5ff4f8e4444c74f847423570d7dc0aa2bbd0159", size = 9209226, upload-time = "2026-06-12T02:29:07.033Z" }, ] [[package]] name = "ml-dtypes" -version = "0.5.3" +version = "0.5.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/78/a7/aad060393123cfb383956dca68402aff3db1e1caffd5764887ed5153f41b/ml_dtypes-0.5.3.tar.gz", hash = "sha256:95ce33057ba4d05df50b1f3cfefab22e351868a843b3b15a46c65836283670c9", size = 692316, upload-time = "2025-07-29T18:39:19.454Z" } +sdist = { url = "https://files.pythonhosted.org/packages/0e/4a/c27b42ed9b1c7d13d9ba8b6905dece787d6259152f2309338aed29b2447b/ml_dtypes-0.5.4.tar.gz", hash = "sha256:8ab06a50fb9bf9666dd0fe5dfb4676fa2b0ac0f31ecff72a6c3af8e22c063453", size = 692314, upload-time = "2025-11-17T22:32:31.031Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/a1/4008f14bbc616cfb1ac5b39ea485f9c63031c4634ab3f4cf72e7541f816a/ml_dtypes-0.5.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c760d85a2f82e2bed75867079188c9d18dae2ee77c25a54d60e9cc79be1bc48", size = 676888, upload-time = "2025-11-17T22:31:56.907Z" }, + { url = "https://files.pythonhosted.org/packages/d3/b7/dff378afc2b0d5a7d6cd9d3209b60474d9819d1189d347521e1688a60a53/ml_dtypes-0.5.4-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce756d3a10d0c4067172804c9cc276ba9cc0ff47af9078ad439b075d1abdc29b", size = 5036993, upload-time = "2025-11-17T22:31:58.497Z" }, + { url = "https://files.pythonhosted.org/packages/eb/33/40cd74219417e78b97c47802037cf2d87b91973e18bb968a7da48a96ea44/ml_dtypes-0.5.4-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:533ce891ba774eabf607172254f2e7260ba5f57bdd64030c9a4fcfbd99815d0d", size = 5010956, upload-time = "2025-11-17T22:31:59.931Z" }, + { url = "https://files.pythonhosted.org/packages/e1/8b/200088c6859d8221454825959df35b5244fa9bdf263fd0249ac5fb75e281/ml_dtypes-0.5.4-cp313-cp313-win_amd64.whl", hash = "sha256:f21c9219ef48ca5ee78402d5cc831bd58ea27ce89beda894428bc67a52da5328", size = 212224, upload-time = "2025-11-17T22:32:01.349Z" }, + { url = "https://files.pythonhosted.org/packages/8f/75/dfc3775cb36367816e678f69a7843f6f03bd4e2bcd79941e01ea960a068e/ml_dtypes-0.5.4-cp313-cp313-win_arm64.whl", hash = "sha256:35f29491a3e478407f7047b8a4834e4640a77d2737e0b294d049746507af5175", size = 160798, upload-time = "2025-11-17T22:32:02.864Z" }, + { url = "https://files.pythonhosted.org/packages/4f/74/e9ddb35fd1dd43b1106c20ced3f53c2e8e7fc7598c15638e9f80677f81d4/ml_dtypes-0.5.4-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:304ad47faa395415b9ccbcc06a0350800bc50eda70f0e45326796e27c62f18b6", size = 702083, upload-time = "2025-11-17T22:32:04.08Z" }, + { url = "https://files.pythonhosted.org/packages/74/f5/667060b0aed1aa63166b22897fdf16dca9eb704e6b4bbf86848d5a181aa7/ml_dtypes-0.5.4-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6a0df4223b514d799b8a1629c65ddc351b3efa833ccf7f8ea0cf654a61d1e35d", size = 5354111, upload-time = "2025-11-17T22:32:05.546Z" }, + { url = "https://files.pythonhosted.org/packages/40/49/0f8c498a28c0efa5f5c95a9e374c83ec1385ca41d0e85e7cf40e5d519a21/ml_dtypes-0.5.4-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:531eff30e4d368cb6255bc2328d070e35836aa4f282a0fb5f3a0cd7260257298", size = 5366453, upload-time = "2025-11-17T22:32:07.115Z" }, + { url = "https://files.pythonhosted.org/packages/8c/27/12607423d0a9c6bbbcc780ad19f1f6baa2b68b18ce4bddcdc122c4c68dc9/ml_dtypes-0.5.4-cp313-cp313t-win_amd64.whl", hash = "sha256:cb73dccfc991691c444acc8c0012bee8f2470da826a92e3a20bb333b1a7894e6", size = 225612, upload-time = "2025-11-17T22:32:08.615Z" }, + { url = "https://files.pythonhosted.org/packages/e5/80/5a5929e92c72936d5b19872c5fb8fc09327c1da67b3b68c6a13139e77e20/ml_dtypes-0.5.4-cp313-cp313t-win_arm64.whl", hash = "sha256:3bbbe120b915090d9dd1375e4684dd17a20a2491ef25d640a908281da85e73f1", size = 164145, upload-time = "2025-11-17T22:32:09.782Z" }, + { url = "https://files.pythonhosted.org/packages/72/4e/1339dc6e2557a344f5ba5590872e80346f76f6cb2ac3dd16e4666e88818c/ml_dtypes-0.5.4-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:2b857d3af6ac0d39db1de7c706e69c7f9791627209c3d6dedbfca8c7e5faec22", size = 673781, upload-time = "2025-11-17T22:32:11.364Z" }, + { url = "https://files.pythonhosted.org/packages/04/f9/067b84365c7e83bda15bba2b06c6ca250ce27b20630b1128c435fb7a09aa/ml_dtypes-0.5.4-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:805cef3a38f4eafae3a5bf9ebdcdb741d0bcfd9e1bd90eb54abd24f928cd2465", size = 5036145, upload-time = "2025-11-17T22:32:12.783Z" }, + { url = "https://files.pythonhosted.org/packages/c6/bb/82c7dcf38070b46172a517e2334e665c5bf374a262f99a283ea454bece7c/ml_dtypes-0.5.4-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14a4fd3228af936461db66faccef6e4f41c1d82fcc30e9f8d58a08916b1d811f", size = 5010230, upload-time = "2025-11-17T22:32:14.38Z" }, + { url = "https://files.pythonhosted.org/packages/e9/93/2bfed22d2498c468f6bcd0d9f56b033eaa19f33320389314c19ef6766413/ml_dtypes-0.5.4-cp314-cp314-win_amd64.whl", hash = "sha256:8c6a2dcebd6f3903e05d51960a8058d6e131fe69f952a5397e5dbabc841b6d56", size = 221032, upload-time = "2025-11-17T22:32:15.763Z" }, + { url = "https://files.pythonhosted.org/packages/76/a3/9c912fe6ea747bb10fe2f8f54d027eb265db05dfb0c6335e3e063e74e6e8/ml_dtypes-0.5.4-cp314-cp314-win_arm64.whl", hash = "sha256:5a0f68ca8fd8d16583dfa7793973feb86f2fbb56ce3966daf9c9f748f52a2049", size = 163353, upload-time = "2025-11-17T22:32:16.932Z" }, + { url = "https://files.pythonhosted.org/packages/cd/02/48aa7d84cc30ab4ee37624a2fd98c56c02326785750cd212bc0826c2f15b/ml_dtypes-0.5.4-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:bfc534409c5d4b0bf945af29e5d0ab075eae9eecbb549ff8a29280db822f34f9", size = 702085, upload-time = "2025-11-17T22:32:18.175Z" }, + { url = "https://files.pythonhosted.org/packages/5a/e7/85cb99fe80a7a5513253ec7faa88a65306be071163485e9a626fce1b6e84/ml_dtypes-0.5.4-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2314892cdc3fcf05e373d76d72aaa15fda9fb98625effa73c1d646f331fcecb7", size = 5355358, upload-time = "2025-11-17T22:32:19.7Z" }, + { url = "https://files.pythonhosted.org/packages/79/2b/a826ba18d2179a56e144aef69e57fb2ab7c464ef0b2111940ee8a3a223a2/ml_dtypes-0.5.4-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0d2ffd05a2575b1519dc928c0b93c06339eb67173ff53acb00724502cda231cf", size = 5366332, upload-time = "2025-11-17T22:32:21.193Z" }, + { url = "https://files.pythonhosted.org/packages/84/44/f4d18446eacb20ea11e82f133ea8f86e2bf2891785b67d9da8d0ab0ef525/ml_dtypes-0.5.4-cp314-cp314t-win_amd64.whl", hash = "sha256:4381fe2f2452a2d7589689693d3162e876b3ddb0a832cde7a414f8e1adf7eab1", size = 236612, upload-time = "2025-11-17T22:32:22.579Z" }, + { url = "https://files.pythonhosted.org/packages/ad/3f/3d42e9a78fe5edf792a83c074b13b9b770092a4fbf3462872f4303135f09/ml_dtypes-0.5.4-cp314-cp314t-win_arm64.whl", hash = "sha256:11942cbf2cf92157db91e5022633c0d9474d4dfd813a909383bd23ce828a4b7d", size = 168825, upload-time = "2025-11-17T22:32:23.766Z" }, +] + +[[package]] +name = "nlls-gram" +version = "0.5.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jax" }, + { name = "lineax" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3b/d6/4c97a9567aa06d10ffd0c5c59cf7a8bd579a76b29fe1a96f96aa41fd3c4f/nlls_gram-0.5.1.tar.gz", hash = "sha256:52317dc4587d69c39cbd0ea630e0e909cae4aaba5fba403a5d10406ef88ee9fd", size = 103311, upload-time = "2026-06-20T18:29:59.683Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2d/87/1bcc98a66de7b2455dfb292f271452cac9edc4e870796e0d87033524d790/ml_dtypes-0.5.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5103856a225465371fe119f2fef737402b705b810bd95ad5f348e6e1a6ae21af", size = 663781, upload-time = "2025-07-29T18:38:42.984Z" }, - { url = "https://files.pythonhosted.org/packages/fd/2c/bd2a79ba7c759ee192b5601b675b180a3fd6ccf48ffa27fe1782d280f1a7/ml_dtypes-0.5.3-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4cae435a68861660af81fa3c5af16b70ca11a17275c5b662d9c6f58294e0f113", size = 4956217, upload-time = "2025-07-29T18:38:44.65Z" }, - { url = "https://files.pythonhosted.org/packages/14/f3/091ba84e5395d7fe5b30c081a44dec881cd84b408db1763ee50768b2ab63/ml_dtypes-0.5.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6936283b56d74fbec431ca57ce58a90a908fdbd14d4e2d22eea6d72bb208a7b7", size = 4933109, upload-time = "2025-07-29T18:38:46.405Z" }, - { url = "https://files.pythonhosted.org/packages/bc/24/054036dbe32c43295382c90a1363241684c4d6aaa1ecc3df26bd0c8d5053/ml_dtypes-0.5.3-cp313-cp313-win_amd64.whl", hash = "sha256:d0f730a17cf4f343b2c7ad50cee3bd19e969e793d2be6ed911f43086460096e4", size = 208187, upload-time = "2025-07-29T18:38:48.24Z" }, - { url = "https://files.pythonhosted.org/packages/a6/3d/7dc3ec6794a4a9004c765e0c341e32355840b698f73fd2daff46f128afc1/ml_dtypes-0.5.3-cp313-cp313-win_arm64.whl", hash = "sha256:2db74788fc01914a3c7f7da0763427280adfc9cd377e9604b6b64eb8097284bd", size = 161559, upload-time = "2025-07-29T18:38:50.493Z" }, - { url = "https://files.pythonhosted.org/packages/12/91/e6c7a0d67a152b9330445f9f0cf8ae6eee9b83f990b8c57fe74631e42a90/ml_dtypes-0.5.3-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:93c36a08a6d158db44f2eb9ce3258e53f24a9a4a695325a689494f0fdbc71770", size = 689321, upload-time = "2025-07-29T18:38:52.03Z" }, - { url = "https://files.pythonhosted.org/packages/9e/6c/b7b94b84a104a5be1883305b87d4c6bd6ae781504474b4cca067cb2340ec/ml_dtypes-0.5.3-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0e44a3761f64bc009d71ddb6d6c71008ba21b53ab6ee588dadab65e2fa79eafc", size = 5274495, upload-time = "2025-07-29T18:38:53.797Z" }, - { url = "https://files.pythonhosted.org/packages/5b/38/6266604dffb43378055394ea110570cf261a49876fc48f548dfe876f34cc/ml_dtypes-0.5.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bdf40d2aaabd3913dec11840f0d0ebb1b93134f99af6a0a4fd88ffe924928ab4", size = 5285422, upload-time = "2025-07-29T18:38:56.603Z" }, - { url = "https://files.pythonhosted.org/packages/7c/88/8612ff177d043a474b9408f0382605d881eeb4125ba89d4d4b3286573a83/ml_dtypes-0.5.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:aec640bd94c4c85c0d11e2733bd13cbb10438fb004852996ec0efbc6cacdaf70", size = 661182, upload-time = "2025-07-29T18:38:58.414Z" }, - { url = "https://files.pythonhosted.org/packages/6f/2b/0569a5e88b29240d373e835107c94ae9256fb2191d3156b43b2601859eff/ml_dtypes-0.5.3-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bda32ce212baa724e03c68771e5c69f39e584ea426bfe1a701cb01508ffc7035", size = 4956187, upload-time = "2025-07-29T18:39:00.611Z" }, - { url = "https://files.pythonhosted.org/packages/51/66/273c2a06ae44562b104b61e6b14444da00061fd87652506579d7eb2c40b1/ml_dtypes-0.5.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c205cac07d24a29840c163d6469f61069ce4b065518519216297fc2f261f8db9", size = 4930911, upload-time = "2025-07-29T18:39:02.405Z" }, - { url = "https://files.pythonhosted.org/packages/93/ab/606be3e87dc0821bd360c8c1ee46108025c31a4f96942b63907bb441b87d/ml_dtypes-0.5.3-cp314-cp314-win_amd64.whl", hash = "sha256:cd7c0bb22d4ff86d65ad61b5dd246812e8993fbc95b558553624c33e8b6903ea", size = 216664, upload-time = "2025-07-29T18:39:03.927Z" }, - { url = "https://files.pythonhosted.org/packages/30/a2/e900690ca47d01dffffd66375c5de8c4f8ced0f1ef809ccd3b25b3e6b8fa/ml_dtypes-0.5.3-cp314-cp314-win_arm64.whl", hash = "sha256:9d55ea7f7baf2aed61bf1872116cefc9d0c3693b45cae3916897ee27ef4b835e", size = 160203, upload-time = "2025-07-29T18:39:05.671Z" }, - { url = "https://files.pythonhosted.org/packages/53/21/783dfb51f40d2660afeb9bccf3612b99f6a803d980d2a09132b0f9d216ab/ml_dtypes-0.5.3-cp314-cp314t-macosx_10_13_universal2.whl", hash = "sha256:e12e29764a0e66a7a31e9b8bf1de5cc0423ea72979f45909acd4292de834ccd3", size = 689324, upload-time = "2025-07-29T18:39:07.567Z" }, - { url = "https://files.pythonhosted.org/packages/09/f7/a82d249c711abf411ac027b7163f285487f5e615c3e0716c61033ce996ab/ml_dtypes-0.5.3-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:19f6c3a4f635c2fc9e2aa7d91416bd7a3d649b48350c51f7f715a09370a90d93", size = 5275917, upload-time = "2025-07-29T18:39:09.339Z" }, - { url = "https://files.pythonhosted.org/packages/7f/3c/541c4b30815ab90ebfbb51df15d0b4254f2f9f1e2b4907ab229300d5e6f2/ml_dtypes-0.5.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ab039ffb40f3dc0aeeeba84fd6c3452781b5e15bef72e2d10bcb33e4bbffc39", size = 5285284, upload-time = "2025-07-29T18:39:11.532Z" }, + { url = "https://files.pythonhosted.org/packages/7a/e8/943f0b4d9ca6e63a750eb7fc70694c8174413a4afff6c04a68ea49b51eab/nlls_gram-0.5.1-py3-none-any.whl", hash = "sha256:23686f23830f9adf5798fa241054315ed31882673fea7d4369c1b8f468fcf0ff", size = 10513, upload-time = "2026-06-20T18:29:58.434Z" }, ] [[package]] name = "numpy" -version = "2.3.3" +version = "2.4.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d0/19/95b3d357407220ed24c139018d2518fab0a61a948e68286a25f1a4d049ff/numpy-2.3.3.tar.gz", hash = "sha256:ddc7c39727ba62b80dfdbedf400d1c10ddfa8eefbd7ec8dcb118be8b56d31029", size = 20576648, upload-time = "2025-09-09T16:54:12.543Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/ad/fed0499ce6a338d2a03ebae59cd15093910c8875328855781952abf6c2fe/numpy-2.4.6.tar.gz", hash = "sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda", size = 20735807, upload-time = "2026-05-18T23:37:14.07Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7d/b9/984c2b1ee61a8b803bf63582b4ac4242cf76e2dbd663efeafcb620cc0ccb/numpy-2.3.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f5415fb78995644253370985342cd03572ef8620b934da27d77377a2285955bf", size = 20949588, upload-time = "2025-09-09T15:56:59.087Z" }, - { url = "https://files.pythonhosted.org/packages/a6/e4/07970e3bed0b1384d22af1e9912527ecbeb47d3b26e9b6a3bced068b3bea/numpy-2.3.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d00de139a3324e26ed5b95870ce63be7ec7352171bc69a4cf1f157a48e3eb6b7", size = 14177802, upload-time = "2025-09-09T15:57:01.73Z" }, - { url = "https://files.pythonhosted.org/packages/35/c7/477a83887f9de61f1203bad89cf208b7c19cc9fef0cebef65d5a1a0619f2/numpy-2.3.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:9dc13c6a5829610cc07422bc74d3ac083bd8323f14e2827d992f9e52e22cd6a6", size = 5106537, upload-time = "2025-09-09T15:57:03.765Z" }, - { url = "https://files.pythonhosted.org/packages/52/47/93b953bd5866a6f6986344d045a207d3f1cfbad99db29f534ea9cee5108c/numpy-2.3.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:d79715d95f1894771eb4e60fb23f065663b2298f7d22945d66877aadf33d00c7", size = 6640743, upload-time = "2025-09-09T15:57:07.921Z" }, - { url = "https://files.pythonhosted.org/packages/23/83/377f84aaeb800b64c0ef4de58b08769e782edcefa4fea712910b6f0afd3c/numpy-2.3.3-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:952cfd0748514ea7c3afc729a0fc639e61655ce4c55ab9acfab14bda4f402b4c", size = 14278881, upload-time = "2025-09-09T15:57:11.349Z" }, - { url = "https://files.pythonhosted.org/packages/9a/a5/bf3db6e66c4b160d6ea10b534c381a1955dfab34cb1017ea93aa33c70ed3/numpy-2.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5b83648633d46f77039c29078751f80da65aa64d5622a3cd62aaef9d835b6c93", size = 16636301, upload-time = "2025-09-09T15:57:14.245Z" }, - { url = "https://files.pythonhosted.org/packages/a2/59/1287924242eb4fa3f9b3a2c30400f2e17eb2707020d1c5e3086fe7330717/numpy-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b001bae8cea1c7dfdb2ae2b017ed0a6f2102d7a70059df1e338e307a4c78a8ae", size = 16053645, upload-time = "2025-09-09T15:57:16.534Z" }, - { url = "https://files.pythonhosted.org/packages/e6/93/b3d47ed882027c35e94ac2320c37e452a549f582a5e801f2d34b56973c97/numpy-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8e9aced64054739037d42fb84c54dd38b81ee238816c948c8f3ed134665dcd86", size = 18578179, upload-time = "2025-09-09T15:57:18.883Z" }, - { url = "https://files.pythonhosted.org/packages/20/d9/487a2bccbf7cc9d4bfc5f0f197761a5ef27ba870f1e3bbb9afc4bbe3fcc2/numpy-2.3.3-cp313-cp313-win32.whl", hash = "sha256:9591e1221db3f37751e6442850429b3aabf7026d3b05542d102944ca7f00c8a8", size = 6312250, upload-time = "2025-09-09T15:57:21.296Z" }, - { url = "https://files.pythonhosted.org/packages/1b/b5/263ebbbbcede85028f30047eab3d58028d7ebe389d6493fc95ae66c636ab/numpy-2.3.3-cp313-cp313-win_amd64.whl", hash = "sha256:f0dadeb302887f07431910f67a14d57209ed91130be0adea2f9793f1a4f817cf", size = 12783269, upload-time = "2025-09-09T15:57:23.034Z" }, - { url = "https://files.pythonhosted.org/packages/fa/75/67b8ca554bbeaaeb3fac2e8bce46967a5a06544c9108ec0cf5cece559b6c/numpy-2.3.3-cp313-cp313-win_arm64.whl", hash = "sha256:3c7cf302ac6e0b76a64c4aecf1a09e51abd9b01fc7feee80f6c43e3ab1b1dbc5", size = 10195314, upload-time = "2025-09-09T15:57:25.045Z" }, - { url = "https://files.pythonhosted.org/packages/11/d0/0d1ddec56b162042ddfafeeb293bac672de9b0cfd688383590090963720a/numpy-2.3.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:eda59e44957d272846bb407aad19f89dc6f58fecf3504bd144f4c5cf81a7eacc", size = 21048025, upload-time = "2025-09-09T15:57:27.257Z" }, - { url = "https://files.pythonhosted.org/packages/36/9e/1996ca6b6d00415b6acbdd3c42f7f03ea256e2c3f158f80bd7436a8a19f3/numpy-2.3.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:823d04112bc85ef5c4fda73ba24e6096c8f869931405a80aa8b0e604510a26bc", size = 14301053, upload-time = "2025-09-09T15:57:30.077Z" }, - { url = "https://files.pythonhosted.org/packages/05/24/43da09aa764c68694b76e84b3d3f0c44cb7c18cdc1ba80e48b0ac1d2cd39/numpy-2.3.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:40051003e03db4041aa325da2a0971ba41cf65714e65d296397cc0e32de6018b", size = 5229444, upload-time = "2025-09-09T15:57:32.733Z" }, - { url = "https://files.pythonhosted.org/packages/bc/14/50ffb0f22f7218ef8af28dd089f79f68289a7a05a208db9a2c5dcbe123c1/numpy-2.3.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:6ee9086235dd6ab7ae75aba5662f582a81ced49f0f1c6de4260a78d8f2d91a19", size = 6738039, upload-time = "2025-09-09T15:57:34.328Z" }, - { url = "https://files.pythonhosted.org/packages/55/52/af46ac0795e09657d45a7f4db961917314377edecf66db0e39fa7ab5c3d3/numpy-2.3.3-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:94fcaa68757c3e2e668ddadeaa86ab05499a70725811e582b6a9858dd472fb30", size = 14352314, upload-time = "2025-09-09T15:57:36.255Z" }, - { url = "https://files.pythonhosted.org/packages/a7/b1/dc226b4c90eb9f07a3fff95c2f0db3268e2e54e5cce97c4ac91518aee71b/numpy-2.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da1a74b90e7483d6ce5244053399a614b1d6b7bc30a60d2f570e5071f8959d3e", size = 16701722, upload-time = "2025-09-09T15:57:38.622Z" }, - { url = "https://files.pythonhosted.org/packages/9d/9d/9d8d358f2eb5eced14dba99f110d83b5cd9a4460895230f3b396ad19a323/numpy-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2990adf06d1ecee3b3dcbb4977dfab6e9f09807598d647f04d385d29e7a3c3d3", size = 16132755, upload-time = "2025-09-09T15:57:41.16Z" }, - { url = "https://files.pythonhosted.org/packages/b6/27/b3922660c45513f9377b3fb42240bec63f203c71416093476ec9aa0719dc/numpy-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ed635ff692483b8e3f0fcaa8e7eb8a75ee71aa6d975388224f70821421800cea", size = 18651560, upload-time = "2025-09-09T15:57:43.459Z" }, - { url = "https://files.pythonhosted.org/packages/5b/8e/3ab61a730bdbbc201bb245a71102aa609f0008b9ed15255500a99cd7f780/numpy-2.3.3-cp313-cp313t-win32.whl", hash = "sha256:a333b4ed33d8dc2b373cc955ca57babc00cd6f9009991d9edc5ddbc1bac36bcd", size = 6442776, upload-time = "2025-09-09T15:57:45.793Z" }, - { url = "https://files.pythonhosted.org/packages/1c/3a/e22b766b11f6030dc2decdeff5c2fb1610768055603f9f3be88b6d192fb2/numpy-2.3.3-cp313-cp313t-win_amd64.whl", hash = "sha256:4384a169c4d8f97195980815d6fcad04933a7e1ab3b530921c3fef7a1c63426d", size = 12927281, upload-time = "2025-09-09T15:57:47.492Z" }, - { url = "https://files.pythonhosted.org/packages/7b/42/c2e2bc48c5e9b2a83423f99733950fbefd86f165b468a3d85d52b30bf782/numpy-2.3.3-cp313-cp313t-win_arm64.whl", hash = "sha256:75370986cc0bc66f4ce5110ad35aae6d182cc4ce6433c40ad151f53690130bf1", size = 10265275, upload-time = "2025-09-09T15:57:49.647Z" }, - { url = "https://files.pythonhosted.org/packages/6b/01/342ad585ad82419b99bcf7cebe99e61da6bedb89e213c5fd71acc467faee/numpy-2.3.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:cd052f1fa6a78dee696b58a914b7229ecfa41f0a6d96dc663c1220a55e137593", size = 20951527, upload-time = "2025-09-09T15:57:52.006Z" }, - { url = "https://files.pythonhosted.org/packages/ef/d8/204e0d73fc1b7a9ee80ab1fe1983dd33a4d64a4e30a05364b0208e9a241a/numpy-2.3.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:414a97499480067d305fcac9716c29cf4d0d76db6ebf0bf3cbce666677f12652", size = 14186159, upload-time = "2025-09-09T15:57:54.407Z" }, - { url = "https://files.pythonhosted.org/packages/22/af/f11c916d08f3a18fb8ba81ab72b5b74a6e42ead4c2846d270eb19845bf74/numpy-2.3.3-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:50a5fe69f135f88a2be9b6ca0481a68a136f6febe1916e4920e12f1a34e708a7", size = 5114624, upload-time = "2025-09-09T15:57:56.5Z" }, - { url = "https://files.pythonhosted.org/packages/fb/11/0ed919c8381ac9d2ffacd63fd1f0c34d27e99cab650f0eb6f110e6ae4858/numpy-2.3.3-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:b912f2ed2b67a129e6a601e9d93d4fa37bef67e54cac442a2f588a54afe5c67a", size = 6642627, upload-time = "2025-09-09T15:57:58.206Z" }, - { url = "https://files.pythonhosted.org/packages/ee/83/deb5f77cb0f7ba6cb52b91ed388b47f8f3c2e9930d4665c600408d9b90b9/numpy-2.3.3-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9e318ee0596d76d4cb3d78535dc005fa60e5ea348cd131a51e99d0bdbe0b54fe", size = 14296926, upload-time = "2025-09-09T15:58:00.035Z" }, - { url = "https://files.pythonhosted.org/packages/77/cc/70e59dcb84f2b005d4f306310ff0a892518cc0c8000a33d0e6faf7ca8d80/numpy-2.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ce020080e4a52426202bdb6f7691c65bb55e49f261f31a8f506c9f6bc7450421", size = 16638958, upload-time = "2025-09-09T15:58:02.738Z" }, - { url = "https://files.pythonhosted.org/packages/b6/5a/b2ab6c18b4257e099587d5b7f903317bd7115333ad8d4ec4874278eafa61/numpy-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e6687dc183aa55dae4a705b35f9c0f8cb178bcaa2f029b241ac5356221d5c021", size = 16071920, upload-time = "2025-09-09T15:58:05.029Z" }, - { url = "https://files.pythonhosted.org/packages/b8/f1/8b3fdc44324a259298520dd82147ff648979bed085feeacc1250ef1656c0/numpy-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d8f3b1080782469fdc1718c4ed1d22549b5fb12af0d57d35e992158a772a37cf", size = 18577076, upload-time = "2025-09-09T15:58:07.745Z" }, - { url = "https://files.pythonhosted.org/packages/f0/a1/b87a284fb15a42e9274e7fcea0dad259d12ddbf07c1595b26883151ca3b4/numpy-2.3.3-cp314-cp314-win32.whl", hash = "sha256:cb248499b0bc3be66ebd6578b83e5acacf1d6cb2a77f2248ce0e40fbec5a76d0", size = 6366952, upload-time = "2025-09-09T15:58:10.096Z" }, - { url = "https://files.pythonhosted.org/packages/70/5f/1816f4d08f3b8f66576d8433a66f8fa35a5acfb3bbd0bf6c31183b003f3d/numpy-2.3.3-cp314-cp314-win_amd64.whl", hash = "sha256:691808c2b26b0f002a032c73255d0bd89751425f379f7bcd22d140db593a96e8", size = 12919322, upload-time = "2025-09-09T15:58:12.138Z" }, - { url = "https://files.pythonhosted.org/packages/8c/de/072420342e46a8ea41c324a555fa90fcc11637583fb8df722936aed1736d/numpy-2.3.3-cp314-cp314-win_arm64.whl", hash = "sha256:9ad12e976ca7b10f1774b03615a2a4bab8addce37ecc77394d8e986927dc0dfe", size = 10478630, upload-time = "2025-09-09T15:58:14.64Z" }, - { url = "https://files.pythonhosted.org/packages/d5/df/ee2f1c0a9de7347f14da5dd3cd3c3b034d1b8607ccb6883d7dd5c035d631/numpy-2.3.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:9cc48e09feb11e1db00b320e9d30a4151f7369afb96bd0e48d942d09da3a0d00", size = 21047987, upload-time = "2025-09-09T15:58:16.889Z" }, - { url = "https://files.pythonhosted.org/packages/d6/92/9453bdc5a4e9e69cf4358463f25e8260e2ffc126d52e10038b9077815989/numpy-2.3.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:901bf6123879b7f251d3631967fd574690734236075082078e0571977c6a8e6a", size = 14301076, upload-time = "2025-09-09T15:58:20.343Z" }, - { url = "https://files.pythonhosted.org/packages/13/77/1447b9eb500f028bb44253105bd67534af60499588a5149a94f18f2ca917/numpy-2.3.3-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:7f025652034199c301049296b59fa7d52c7e625017cae4c75d8662e377bf487d", size = 5229491, upload-time = "2025-09-09T15:58:22.481Z" }, - { url = "https://files.pythonhosted.org/packages/3d/f9/d72221b6ca205f9736cb4b2ce3b002f6e45cd67cd6a6d1c8af11a2f0b649/numpy-2.3.3-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:533ca5f6d325c80b6007d4d7fb1984c303553534191024ec6a524a4c92a5935a", size = 6737913, upload-time = "2025-09-09T15:58:24.569Z" }, - { url = "https://files.pythonhosted.org/packages/3c/5f/d12834711962ad9c46af72f79bb31e73e416ee49d17f4c797f72c96b6ca5/numpy-2.3.3-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0edd58682a399824633b66885d699d7de982800053acf20be1eaa46d92009c54", size = 14352811, upload-time = "2025-09-09T15:58:26.416Z" }, - { url = "https://files.pythonhosted.org/packages/a1/0d/fdbec6629d97fd1bebed56cd742884e4eead593611bbe1abc3eb40d304b2/numpy-2.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:367ad5d8fbec5d9296d18478804a530f1191e24ab4d75ab408346ae88045d25e", size = 16702689, upload-time = "2025-09-09T15:58:28.831Z" }, - { url = "https://files.pythonhosted.org/packages/9b/09/0a35196dc5575adde1eb97ddfbc3e1687a814f905377621d18ca9bc2b7dd/numpy-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8f6ac61a217437946a1fa48d24c47c91a0c4f725237871117dea264982128097", size = 16133855, upload-time = "2025-09-09T15:58:31.349Z" }, - { url = "https://files.pythonhosted.org/packages/7a/ca/c9de3ea397d576f1b6753eaa906d4cdef1bf97589a6d9825a349b4729cc2/numpy-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:179a42101b845a816d464b6fe9a845dfaf308fdfc7925387195570789bb2c970", size = 18652520, upload-time = "2025-09-09T15:58:33.762Z" }, - { url = "https://files.pythonhosted.org/packages/fd/c2/e5ed830e08cd0196351db55db82f65bc0ab05da6ef2b72a836dcf1936d2f/numpy-2.3.3-cp314-cp314t-win32.whl", hash = "sha256:1250c5d3d2562ec4174bce2e3a1523041595f9b651065e4a4473f5f48a6bc8a5", size = 6515371, upload-time = "2025-09-09T15:58:36.04Z" }, - { url = "https://files.pythonhosted.org/packages/47/c7/b0f6b5b67f6788a0725f744496badbb604d226bf233ba716683ebb47b570/numpy-2.3.3-cp314-cp314t-win_amd64.whl", hash = "sha256:b37a0b2e5935409daebe82c1e42274d30d9dd355852529eab91dab8dcca7419f", size = 13112576, upload-time = "2025-09-09T15:58:37.927Z" }, - { url = "https://files.pythonhosted.org/packages/06/b9/33bba5ff6fb679aa0b1f8a07e853f002a6b04b9394db3069a1270a7784ca/numpy-2.3.3-cp314-cp314t-win_arm64.whl", hash = "sha256:78c9f6560dc7e6b3990e32df7ea1a50bbd0e2a111e05209963f5ddcab7073b0b", size = 10545953, upload-time = "2025-09-09T15:58:40.576Z" }, + { url = "https://files.pythonhosted.org/packages/fb/82/bdab26d7438c6791ca31b7c024ca37c1eab8b726ba236129005cd4a06e45/numpy-2.4.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:511dbaf848decaaaf4b4ca48032619fb3138710c4bf7da7617765edad1ef96b0", size = 16684648, upload-time = "2026-05-18T23:34:29.41Z" }, + { url = "https://files.pythonhosted.org/packages/1b/30/a80189bcc7f5e4258b3fbc3968d909d1756f54d023299ecc39ad6fdb9ef8/numpy-2.4.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bf162abab1c1a736333192707cef898e735a5ca00f38f27eeedf44b39d9e85eb", size = 14693902, upload-time = "2026-05-18T23:34:33.013Z" }, + { url = "https://files.pythonhosted.org/packages/97/12/70b5d0d7c15e1ebb8a6a84a8caa1d19e181d84fb58bb6d70aca29099dec1/numpy-2.4.6-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:043191bfa8eab18c776647b62723ac9dddece59743b13f49b2016094129c2b3f", size = 5198992, upload-time = "2026-05-18T23:34:36.132Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8c/ebd2a8f8a83541f8d38cc5667e8c2b69cecfd30da6e45693e8158857d44b/numpy-2.4.6-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:6180d8b35af935aed8ece3a85e0a43f87393ae0ac87c8d2c8bd2c993f7270ef3", size = 6546944, upload-time = "2026-05-18T23:34:38.484Z" }, + { url = "https://files.pythonhosted.org/packages/bb/c5/7b863a97a91671a0338f4253bd3b5a3d3852f0692dae91711c9f4a10e787/numpy-2.4.6-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b", size = 15669392, upload-time = "2026-05-18T23:34:41.257Z" }, + { url = "https://files.pythonhosted.org/packages/a5/9d/3584b9984ca4c047aea75214ce1a4c4c73d849bd71b604264b7f5653f8a8/numpy-2.4.6-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089", size = 16633220, upload-time = "2026-05-18T23:34:45.075Z" }, + { url = "https://files.pythonhosted.org/packages/05/ae/7c67fba23bd98caec7c99261f3a16072ade14813486b0282cb29846de832/numpy-2.4.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a", size = 17020800, upload-time = "2026-05-18T23:34:49.065Z" }, + { url = "https://files.pythonhosted.org/packages/d9/5d/3b6725cb31d983c5e66916f5d36f6d7e5521129e4c4404d64f918292a5b6/numpy-2.4.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605", size = 18357600, upload-time = "2026-05-18T23:34:52.709Z" }, + { url = "https://files.pythonhosted.org/packages/f7/da/2ccc6c2fe8898dee01d90c75c5f5f914a23daf99e3e0f59516a08760c8b5/numpy-2.4.6-cp313-cp313-win32.whl", hash = "sha256:56b39e5e0622a09a25bf5baf62f4bcf0cb8a41ae6e2819cf49bbc5a74c083f91", size = 5961134, upload-time = "2026-05-18T23:34:55.618Z" }, + { url = "https://files.pythonhosted.org/packages/b5/cd/9cc4dc876fb065d5c220aae4d5e14826b2715331bb7618ce1fb07a679d99/numpy-2.4.6-cp313-cp313-win_amd64.whl", hash = "sha256:c4fc99836233ea196540b17ab0983aff60ed07941751930f5f4d05bc3b3b7359", size = 12318598, upload-time = "2026-05-18T23:34:58.928Z" }, + { url = "https://files.pythonhosted.org/packages/39/1e/c0bcba1f8694116485fe28fd1be698c278fcda4141c5b0e53a2aed8b12a8/numpy-2.4.6-cp313-cp313-win_arm64.whl", hash = "sha256:a7c711e21628b52034bb5ab8d1bce291f752fcc5e92accc615778acee1ff4778", size = 10222272, upload-time = "2026-05-18T23:35:02.167Z" }, + { url = "https://files.pythonhosted.org/packages/63/6d/cc5619247c8f4204e507f5883528372e4ac4bb189e579fb859a12e480b1f/numpy-2.4.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:112b06a867b235ef466ed3508ddf0238050df9c727cafb5301ac385b899189a1", size = 14821197, upload-time = "2026-05-18T23:35:05.468Z" }, + { url = "https://files.pythonhosted.org/packages/00/58/f1c39161c87d9e9bed660f1ed4bafc0e403d5ec9650b6dd77aead07d489b/numpy-2.4.6-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:eaf7fa2de5c0be8ae6ff8e9bea2ccd725e980541244521d8d4b5f3354a27babe", size = 5326287, upload-time = "2026-05-18T23:35:08.693Z" }, + { url = "https://files.pythonhosted.org/packages/af/57/3917ab0fd97f271a8694513581b8a36c655f111c446852c302f04ccdb6fc/numpy-2.4.6-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:7265a2f3d436e54ef9f2b52b5c937e6be778781bd97a590319d7348f1c1ca997", size = 6646763, upload-time = "2026-05-18T23:35:11.459Z" }, + { url = "https://files.pythonhosted.org/packages/eb/0f/037e64c494b67581ae18193d770adef354c41f3f2c8ebf865602d949bf8f/numpy-2.4.6-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20", size = 15728070, upload-time = "2026-05-18T23:35:14.79Z" }, + { url = "https://files.pythonhosted.org/packages/21/a6/5d2bae9c9542eb4df16dc9c46dc79c186e9bad53805dfa5399a6023c6db0/numpy-2.4.6-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d", size = 16681752, upload-time = "2026-05-18T23:35:18.836Z" }, + { url = "https://files.pythonhosted.org/packages/92/14/23d1dfb410ae362cd59ce53e936b1513d545eb40db3949ced632e19a459e/numpy-2.4.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67", size = 17086024, upload-time = "2026-05-18T23:35:22.52Z" }, + { url = "https://files.pythonhosted.org/packages/4b/6e/23595a2c642cdf3bc567877064bdd7f91c8b0038a4453cf2daf7248eafe9/numpy-2.4.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd", size = 18403398, upload-time = "2026-05-18T23:35:26.398Z" }, + { url = "https://files.pythonhosted.org/packages/8a/90/0ac3bc947217e66dec77e7cbc6a1979d1af70b6461b82f620d3bccd5e4c8/numpy-2.4.6-cp313-cp313t-win32.whl", hash = "sha256:29a287e0cf63ff528da061de6b9f64a4618da591ca1046aafc54062e40ca7eab", size = 6084971, upload-time = "2026-05-18T23:35:29.387Z" }, + { url = "https://files.pythonhosted.org/packages/77/71/5673e351671a1d2bd6063b91b44f70c0affea7d1516fa7a6572941ba4aa1/numpy-2.4.6-cp313-cp313t-win_amd64.whl", hash = "sha256:25c692919ac5a01f170a3bfcd62d745b24fd095c353d50812637d6fcab442e75", size = 12458532, upload-time = "2026-05-18T23:35:32.175Z" }, + { url = "https://files.pythonhosted.org/packages/3f/88/19d3503c5046e688f049274b27a3ef3d771152fa80d3ba3d01a3dff61abe/numpy-2.4.6-cp313-cp313t-win_arm64.whl", hash = "sha256:1e978ec1e8bd0e0e4de6bb75de9d30cbb74db6b6a2bb727618613703ca0167dd", size = 10291881, upload-time = "2026-05-18T23:35:35.465Z" }, + { url = "https://files.pythonhosted.org/packages/f8/91/3ab2044d05fd16d343c5ac2e69b127f1b2854040dd20b193257c78028bd3/numpy-2.4.6-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:06ca2f61ec4385a07a6977c55ba998a4466c123642b4a32694d3128fce18c079", size = 16683458, upload-time = "2026-05-18T23:35:38.353Z" }, + { url = "https://files.pythonhosted.org/packages/8e/62/764ce66fa4147ae6d73071a3abf804ffe606f174618697c571acdf26a7c9/numpy-2.4.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:38efbc8de75c7a0fc1ac190162d892787f3f47b57cc291231aafee36b80982b7", size = 14704559, upload-time = "2026-05-18T23:35:42.14Z" }, + { url = "https://files.pythonhosted.org/packages/60/61/23f27c172f022e04025b7dc2367f4d63c1a398120607ec896228649a6f48/numpy-2.4.6-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:d581b735e177fdcdce6fed8e7e8880a3fb6ee4e3653a3ac6af01c6f4c03effc5", size = 5209716, upload-time = "2026-05-18T23:35:45.377Z" }, + { url = "https://files.pythonhosted.org/packages/03/71/21cf70dc6ea3e3acb95fc53a265b2fc248b981f0194ceb5b475271b8809d/numpy-2.4.6-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:0a041d3d761dc3c35cc56ce0351506a02bcbc25f7b169f652435141a17db9096", size = 6543947, upload-time = "2026-05-18T23:35:47.926Z" }, + { url = "https://files.pythonhosted.org/packages/d5/91/64288395ee1799bd2e0b04a305dce9666da90c961e1f3fe982a05ee1c036/numpy-2.4.6-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b", size = 15685197, upload-time = "2026-05-18T23:35:50.863Z" }, + { url = "https://files.pythonhosted.org/packages/f3/eb/ebffaa97dc55502df69584a8f0dcf07f69a3e0b3e2323670a2722db9aa39/numpy-2.4.6-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8", size = 16638245, upload-time = "2026-05-18T23:35:54.752Z" }, + { url = "https://files.pythonhosted.org/packages/b8/0b/54f9da33128d7e350fab89c7455902eeae70349ee52bddb448dc4a576f45/numpy-2.4.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402", size = 17036587, upload-time = "2026-05-18T23:35:58.355Z" }, + { url = "https://files.pythonhosted.org/packages/b6/f0/fdebc1052db1cc37c64beb22072d67cd6d1c71adca1299f53dec2b5e20d3/numpy-2.4.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb", size = 18363226, upload-time = "2026-05-18T23:36:02.845Z" }, + { url = "https://files.pythonhosted.org/packages/aa/b4/298628d98c72b57e57f7165ae6a481a1deaf6f3c28262a6e4c739c275930/numpy-2.4.6-cp314-cp314-win32.whl", hash = "sha256:aaf159caa35993cb1f56fb9b8e4610d35758e7ca005412eb1daa856a78c9c4b1", size = 6010196, upload-time = "2026-05-18T23:36:05.92Z" }, + { url = "https://files.pythonhosted.org/packages/df/ac/46de6dda46478f7942f839e094970be2d4a861e005c4b3bf07c92e291a09/numpy-2.4.6-cp314-cp314-win_amd64.whl", hash = "sha256:b507f5c4c1d508876d1819b6bf9a49d365b96320b5d4993426b33a23ca4b8261", size = 12450334, upload-time = "2026-05-18T23:36:09.107Z" }, + { url = "https://files.pythonhosted.org/packages/78/92/b8b798ac784102c0da830d2257d59358e3d3d90d1e2b3f2575dad976c5cf/numpy-2.4.6-cp314-cp314-win_arm64.whl", hash = "sha256:6f41ae150c4e32db4f3310cdaf64b1593a03dbabe29eec77fc9b50fe64061df6", size = 10495678, upload-time = "2026-05-18T23:36:12.766Z" }, + { url = "https://files.pythonhosted.org/packages/30/34/ec28d1aa8115971537c01469ab2011ee96827930f0a124de1000cc2a7ed7/numpy-2.4.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ece3d2cfe132e7d51f44a832b303895e6f2d499c5e74dfbdb06ee246147a304a", size = 14823672, upload-time = "2026-05-18T23:36:16.473Z" }, + { url = "https://files.pythonhosted.org/packages/16/bd/f6d1fede4e54e8042a7ff97bb495510f3c220f94bcd9e8b228e87c92cc0d/numpy-2.4.6-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:e3e5193ef5a3dc73bceee50f7fdc2c90dbb76c42df8d8fae3d1067a583df579e", size = 5328731, upload-time = "2026-05-18T23:36:19.767Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f0/e105b9e2fd728a9910103884decd6951d9dd73896b914a98d9a231de02ee/numpy-2.4.6-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:17f9ade344e7d9b464a084d69bcf18fc691cb1db67c62ed80820bf4926d78f0e", size = 6649805, upload-time = "2026-05-18T23:36:22.266Z" }, + { url = "https://files.pythonhosted.org/packages/82/dd/1206a7ca6ab15e3f02069707ca96222e202af681bb73756da7527f3cb837/numpy-2.4.6-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43", size = 15730496, upload-time = "2026-05-18T23:36:25.713Z" }, + { url = "https://files.pythonhosted.org/packages/51/e7/38d3ea825dcab85a591734decb2f6c67caa7c8367d374df1a1c3842f9b07/numpy-2.4.6-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e", size = 16679616, upload-time = "2026-05-18T23:36:29.652Z" }, + { url = "https://files.pythonhosted.org/packages/93/b7/caabfdf53edf663e0b4eb74d7d405d83baef09eb5e83bcd32d601d72b93e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895", size = 17085145, upload-time = "2026-05-18T23:36:33.449Z" }, + { url = "https://files.pythonhosted.org/packages/f9/45/68d7c33a6bcf3e5aa3bdbd57a367e6f615286dfd6482f97e8ffeb734306e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4", size = 18403813, upload-time = "2026-05-18T23:36:37.369Z" }, + { url = "https://files.pythonhosted.org/packages/9c/50/0753655aa844c99cd9e018aacf76f130f1bd81d881bb74bc0aef5d73a8ba/numpy-2.4.6-cp314-cp314t-win32.whl", hash = "sha256:260a5d70215b61ab4fadf5c7baacd64821842975eea312125ed3c39a6391b063", size = 6156982, upload-time = "2026-05-18T23:36:40.817Z" }, + { url = "https://files.pythonhosted.org/packages/b2/d4/7c67becf668f973cb490cec3e98dfd799d866f9c989a54d355672cfa0db6/numpy-2.4.6-cp314-cp314t-win_amd64.whl", hash = "sha256:81a1cca95ed5bb92aa8b10dd2cdc9a0d3853a50fad926c28b5d7e8ea54389627", size = 12638908, upload-time = "2026-05-18T23:36:43.996Z" }, + { url = "https://files.pythonhosted.org/packages/43/bb/e1c71a4295b1b1d1393d50dbb4f2a36283c6859d9d3892e84f00ec5a91d5/numpy-2.4.6-cp314-cp314t-win_arm64.whl", hash = "sha256:0c9136e14ed34a9e343a31c533d78a9813a69a3148332bce5e9821cb2f996e66", size = 10565867, upload-time = "2026-05-18T23:36:47.114Z" }, ] [[package]] @@ -452,127 +539,122 @@ wheels = [ [[package]] name = "packaging" -version = "25.0" +version = "26.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134, upload-time = "2026-04-24T20:15:23.917Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, + { url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195, upload-time = "2026-04-24T20:15:22.081Z" }, ] [[package]] name = "pandas" -version = "2.3.2" +version = "3.0.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, { name = "python-dateutil" }, - { name = "pytz" }, - { name = "tzdata" }, + { name = "tzdata", marker = "sys_platform == 'emscripten' or sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/79/8e/0e90233ac205ad182bd6b422532695d2b9414944a280488105d598c70023/pandas-2.3.2.tar.gz", hash = "sha256:ab7b58f8f82706890924ccdfb5f48002b83d2b5a3845976a9fb705d36c34dcdb", size = 4488684, upload-time = "2025-08-21T10:28:29.257Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/87/4341c6252d1c47b08768c3d25ac487362bf403f0313ddae4a2a26c9b1b4c/pandas-3.0.3.tar.gz", hash = "sha256:696a4a00a2a2a35d4e5deb3fc946641b96c944f02230e4f76137fe35d806c4fc", size = 4651414, upload-time = "2026-05-11T18:54:29.21Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/27/64/a2f7bf678af502e16b472527735d168b22b7824e45a4d7e96a4fbb634b59/pandas-2.3.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0c6ecbac99a354a051ef21c5307601093cb9e0f4b1855984a084bfec9302699e", size = 11531061, upload-time = "2025-08-21T10:27:34.647Z" }, - { url = "https://files.pythonhosted.org/packages/54/4c/c3d21b2b7769ef2f4c2b9299fcadd601efa6729f1357a8dbce8dd949ed70/pandas-2.3.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c6f048aa0fd080d6a06cc7e7537c09b53be6642d330ac6f54a600c3ace857ee9", size = 10668666, upload-time = "2025-08-21T10:27:37.203Z" }, - { url = "https://files.pythonhosted.org/packages/50/e2/f775ba76ecfb3424d7f5862620841cf0edb592e9abd2d2a5387d305fe7a8/pandas-2.3.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0064187b80a5be6f2f9c9d6bdde29372468751dfa89f4211a3c5871854cfbf7a", size = 11332835, upload-time = "2025-08-21T10:27:40.188Z" }, - { url = "https://files.pythonhosted.org/packages/8f/52/0634adaace9be2d8cac9ef78f05c47f3a675882e068438b9d7ec7ef0c13f/pandas-2.3.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ac8c320bded4718b298281339c1a50fb00a6ba78cb2a63521c39bec95b0209b", size = 12057211, upload-time = "2025-08-21T10:27:43.117Z" }, - { url = "https://files.pythonhosted.org/packages/0b/9d/2df913f14b2deb9c748975fdb2491da1a78773debb25abbc7cbc67c6b549/pandas-2.3.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:114c2fe4f4328cf98ce5716d1532f3ab79c5919f95a9cfee81d9140064a2e4d6", size = 12749277, upload-time = "2025-08-21T10:27:45.474Z" }, - { url = "https://files.pythonhosted.org/packages/87/af/da1a2417026bd14d98c236dba88e39837182459d29dcfcea510b2ac9e8a1/pandas-2.3.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:48fa91c4dfb3b2b9bfdb5c24cd3567575f4e13f9636810462ffed8925352be5a", size = 13415256, upload-time = "2025-08-21T10:27:49.885Z" }, - { url = "https://files.pythonhosted.org/packages/22/3c/f2af1ce8840ef648584a6156489636b5692c162771918aa95707c165ad2b/pandas-2.3.2-cp313-cp313-win_amd64.whl", hash = "sha256:12d039facec710f7ba305786837d0225a3444af7bbd9c15c32ca2d40d157ed8b", size = 10982579, upload-time = "2025-08-21T10:28:08.435Z" }, - { url = "https://files.pythonhosted.org/packages/f3/98/8df69c4097a6719e357dc249bf437b8efbde808038268e584421696cbddf/pandas-2.3.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:c624b615ce97864eb588779ed4046186f967374185c047070545253a52ab2d57", size = 12028163, upload-time = "2025-08-21T10:27:52.232Z" }, - { url = "https://files.pythonhosted.org/packages/0e/23/f95cbcbea319f349e10ff90db488b905c6883f03cbabd34f6b03cbc3c044/pandas-2.3.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0cee69d583b9b128823d9514171cabb6861e09409af805b54459bd0c821a35c2", size = 11391860, upload-time = "2025-08-21T10:27:54.673Z" }, - { url = "https://files.pythonhosted.org/packages/ad/1b/6a984e98c4abee22058aa75bfb8eb90dce58cf8d7296f8bc56c14bc330b0/pandas-2.3.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2319656ed81124982900b4c37f0e0c58c015af9a7bbc62342ba5ad07ace82ba9", size = 11309830, upload-time = "2025-08-21T10:27:56.957Z" }, - { url = "https://files.pythonhosted.org/packages/15/d5/f0486090eb18dd8710bf60afeaf638ba6817047c0c8ae5c6a25598665609/pandas-2.3.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b37205ad6f00d52f16b6d09f406434ba928c1a1966e2771006a9033c736d30d2", size = 11883216, upload-time = "2025-08-21T10:27:59.302Z" }, - { url = "https://files.pythonhosted.org/packages/10/86/692050c119696da19e20245bbd650d8dfca6ceb577da027c3a73c62a047e/pandas-2.3.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:837248b4fc3a9b83b9c6214699a13f069dc13510a6a6d7f9ba33145d2841a012", size = 12699743, upload-time = "2025-08-21T10:28:02.447Z" }, - { url = "https://files.pythonhosted.org/packages/cd/d7/612123674d7b17cf345aad0a10289b2a384bff404e0463a83c4a3a59d205/pandas-2.3.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d2c3554bd31b731cd6490d94a28f3abb8dd770634a9e06eb6d2911b9827db370", size = 13186141, upload-time = "2025-08-21T10:28:05.377Z" }, + { url = "https://files.pythonhosted.org/packages/c5/90/62d8302883c44308c477e222c3daf7c813a34c8e96985882fbd53d964352/pandas-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:67b3b64c11910cfa29f4e94a14d3bff9ee693b6fc76055e7cad549cee0aec5fa", size = 10331071, upload-time = "2026-05-11T18:52:58.838Z" }, + { url = "https://files.pythonhosted.org/packages/7f/ae/6a6493c783a101f165e4356953ba3c74d6f77f0042fa7d753da9dfbb640c/pandas-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:39436b377d56d2a2e52d0395bdbee171f01068e99af5250509aceeb929f765c7", size = 9875690, upload-time = "2026-05-11T18:53:01.431Z" }, + { url = "https://files.pythonhosted.org/packages/62/7c/5df8e9f56c69a2769fbe9382a5ef8f2658c007e376434e1e2cbb57ad895f/pandas-3.0.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d4be06d68f9ddcfc645b87534911da79a8fbffc7573c80e0edcf42a5020624d8", size = 10381634, upload-time = "2026-05-11T18:53:04.393Z" }, + { url = "https://files.pythonhosted.org/packages/99/68/1237369725aa617bb358263d535803e3053fdbc593513ec5ed9c9896b5b6/pandas-3.0.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a4eeb6830daf35a71cc09649bd823e2b542dac246cdee9614c6e4bd65028cd6a", size = 10891243, upload-time = "2026-05-11T18:53:07.643Z" }, + { url = "https://files.pythonhosted.org/packages/25/93/77d108e8af7222b4a503ebde0e30215b1c2e4f8e53a526431890f22d5586/pandas-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1928e07221f82db493cd4af1e23c1bfca524a19a4699887975bff68f49a72bfb", size = 11388659, upload-time = "2026-05-11T18:53:10.634Z" }, + { url = "https://files.pythonhosted.org/packages/d0/bd/eff5b4399f332ac386c853f6cd2bd3fa2ca0061b9f36ecd9c4d7c4265649/pandas-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51b1fe551acb77dac643c6fda86084d8d446c10fe64b06a9cc29c4cc8540e7f2", size = 11942880, upload-time = "2026-05-11T18:53:13.536Z" }, + { url = "https://files.pythonhosted.org/packages/2c/20/559ace4200982c3887d0b86bfd0d856a2143ef8ddab63cc07934951a964c/pandas-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:a82d532a3351d435432cd913edbccaf8b8e01d4dd0e5ced5a8d2e8ecd94c7e44", size = 9757091, upload-time = "2026-05-11T18:53:16.306Z" }, + { url = "https://files.pythonhosted.org/packages/3a/66/69055a09fe200f29f922a3eeec4804611900b95f52d932ece3393c3c0c19/pandas-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:275c14e0fce14a2ec20eee474aecd305478ea3c1e6f6a9d8fe219a165542717e", size = 9057282, upload-time = "2026-05-11T18:53:18.768Z" }, + { url = "https://files.pythonhosted.org/packages/57/0e/efe801b0e6811e8e650cd21b7f2608e30f08a7067e2bf6e8752b0d56ee3c/pandas-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:46997386d528eb40376ecd6b033cf4a8a1e5282580f68f43de875b78cba2199d", size = 10767016, upload-time = "2026-05-11T18:53:21.227Z" }, + { url = "https://files.pythonhosted.org/packages/ea/dc/eb55135a1d5f0f0519f28da1f609a206d2cad1f9c35c32d51e38dd7261ae/pandas-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:261e308dfb22448384b7580cf719d2f998fe2966c92893c3e77d14008af1f066", size = 10420210, upload-time = "2026-05-11T18:53:23.982Z" }, + { url = "https://files.pythonhosted.org/packages/c6/3e/b1d5d955ce33ffecb407465a60bc32769d74fcf68224b7ae67ae11d4dea4/pandas-3.0.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dd1a5d1def6a46002e964510bdc67c368aa0951df5d1d9f8365336f5a1f490cd", size = 10336126, upload-time = "2026-05-11T18:53:26.731Z" }, + { url = "https://files.pythonhosted.org/packages/f5/76/a01261711ab60a22d71b862f0de20e4c504bf80457270ad8cb42110f6abc/pandas-3.0.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d72828c20c6d6e83e1e22a6a3b47b326b71664112fa9705dcbccfd7a39b62085", size = 10728051, upload-time = "2026-05-11T18:53:29.125Z" }, + { url = "https://files.pythonhosted.org/packages/e9/21/ea191195e587b18cf682e97f433f81b2d0fbe341380e80a3e0d6e4403c8e/pandas-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d26cbe1fcfc12e8fd900e2454163e466b2d3af84f7c75481df7683ffc073d870", size = 11350796, upload-time = "2026-05-11T18:53:32.056Z" }, + { url = "https://files.pythonhosted.org/packages/64/69/f0eaaf54939f0e8c6768fd06be9af2cef9b36048b96dfb9e1b2c685a807e/pandas-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:3e91cec1879ada0624fc3dc9953c5cbd60208e59c0db28f540c5d6d47502422f", size = 11799741, upload-time = "2026-05-11T18:53:34.985Z" }, + { url = "https://files.pythonhosted.org/packages/45/a4/865e0e510cae5fc2194de4db28be638952de942571ba9125934fd9c01d47/pandas-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:08d789b41f87e0905880e293cedf6197ce71fe67cc081358b1e148a491b9bd13", size = 10499958, upload-time = "2026-05-11T18:53:37.857Z" }, + { url = "https://files.pythonhosted.org/packages/86/54/effdcc3c0ff7a08037889200e148ebe94c16c4f653be078c7b3675955df1/pandas-3.0.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3650109c0f22879df8bd6179ab9ee3d7f1d1d4e7e0094a3f0032d9f51e2e64ac", size = 10336065, upload-time = "2026-05-11T18:53:41.099Z" }, + { url = "https://files.pythonhosted.org/packages/68/10/bf2d6738d72748b961a3751ab89522d58c54efc36a8e1a12161216cd45cf/pandas-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:bab900348131a7db1f69a7309ef141fd5680f1487094193bcbbb61791573bf8f", size = 9926101, upload-time = "2026-05-11T18:53:43.515Z" }, + { url = "https://files.pythonhosted.org/packages/ae/e9/e35cf11c8a136e757b956f5f0efdcaa50aecde85ea055f1898dfc68262f3/pandas-3.0.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba7e08b9ac1d54569cd1e256e3668975ed624d6826f7b68df0342b012007bddb", size = 10457553, upload-time = "2026-05-11T18:53:46.394Z" }, + { url = "https://files.pythonhosted.org/packages/58/3b/1cdec6772bdbaf7b25dab360c59f03cadf05492dd724c6540af905389b07/pandas-3.0.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d71c63ae4ebdbf70209742096f1fc46a83a0613c99d4b23766cced9ff8cd62a", size = 10914065, upload-time = "2026-05-11T18:53:49.134Z" }, + { url = "https://files.pythonhosted.org/packages/c4/c2/1ef644445fcd72e3627bceec77e3560636f87ddce4ed841afe76b83b5bf9/pandas-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e3a2ec42c98ffa2565a67e08e218d06d72576d758d90facb7c00805194d8f360", size = 11459188, upload-time = "2026-05-11T18:53:52.527Z" }, + { url = "https://files.pythonhosted.org/packages/7e/49/4d8d4f42cbc9c4adc7a1870f269c02cbd6cd40d059622c06fb298addcbad/pandas-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:335f62418ed562cfc3c49e9e196375c28b729dcef8543abf4f9438e381bf3c76", size = 11982966, upload-time = "2026-05-11T18:53:55.043Z" }, + { url = "https://files.pythonhosted.org/packages/38/55/792619469bab9882d8bbd5865d45a72f6478762d04a9af4bf0d08c503e95/pandas-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:3c20a521bbb85902f79f7270c80a59e1b5452d96d170c034f207181870f97ac5", size = 9876755, upload-time = "2026-05-11T18:53:58.067Z" }, + { url = "https://files.pythonhosted.org/packages/2a/af/33c469653b0ba03b50c3a98192d4c07f0c75c66b263ceb097fce0ee97d31/pandas-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:a2d2dff8a04f3917b55ab3910c32990f8ddf7eceba114947838cefa976a68977", size = 9198658, upload-time = "2026-05-11T18:54:00.733Z" }, + { url = "https://files.pythonhosted.org/packages/a2/fa/b8c257bd76b8bd060c3a9151c1fca05e9b9c5e3af5d0f549c0356f6d143d/pandas-3.0.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:0d589105b3c14645af1738ff279b2995102d8f7a03b0a66dc8d95550eb513e04", size = 10787242, upload-time = "2026-05-11T18:54:03.564Z" }, + { url = "https://files.pythonhosted.org/packages/54/eb/f19206ffb0bf1919002969aa448b4702c6594845156a6f8050674855aac3/pandas-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:13fc1e853d9e04743d11ba75a985ccbc2a317fe07d8af61e445a6fd24dacd6a6", size = 10436369, upload-time = "2026-05-11T18:54:06.311Z" }, + { url = "https://files.pythonhosted.org/packages/fd/24/c7c39fb4fe22b71a0c2d78bf0c585c600092d85f94f086d2b3b2f6ca27e2/pandas-3.0.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:819959dab7bbd0049c15623fbac4e29a191b9528160a61fb1032242d8ced2d9c", size = 10358306, upload-time = "2026-05-11T18:54:09.085Z" }, + { url = "https://files.pythonhosted.org/packages/16/ec/dd2a9eb7fa1204df88c0864164e35b228ac581062ac612ba0a67fd812e4c/pandas-3.0.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:60ae316d3fd75d1858d450d0db0103ea2be3e7d4a95ec2f064f7e2ae63f7b028", size = 10758394, upload-time = "2026-05-11T18:54:11.956Z" }, + { url = "https://files.pythonhosted.org/packages/95/6e/00c61ea8e85b4f6d8d35e11852a1a4998fc7fafc91c6a602d1cc9c972d64/pandas-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bd3a518890b400d32f9023722dc9a9a5c969f00b415419a3c06c043f09bb5d7d", size = 11375717, upload-time = "2026-05-11T18:54:14.539Z" }, + { url = "https://files.pythonhosted.org/packages/31/89/8fc1c268969fac43688d65fd92e67df24bd128d53cb4d2eee534cd307399/pandas-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9c39be2d709d01fa972a0cabc522389fceca4f3969332ba25a7d6c5802cf976a", size = 11828897, upload-time = "2026-05-11T18:54:17.146Z" }, + { url = "https://files.pythonhosted.org/packages/56/3b/e7d20dea247a3e6dc0bd8a6953854afbedc03951def4e7371e05e7263e25/pandas-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4db8c527972a821cf5286b40ccc57642a39bc62e62022b42f99f8a67fca8c3a1", size = 10900855, upload-time = "2026-05-11T18:54:19.72Z" }, + { url = "https://files.pythonhosted.org/packages/0f/54/68a0978d1ef8502b8492099beaa6e7a0c1b32e3b5d4f677f5810cb08711c/pandas-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:b2c95f8bfc1ee412bf482605d7bfd30c12d1d26bd59fdd91efeef1d4718decb1", size = 9466464, upload-time = "2026-05-11T18:54:22.754Z" }, ] [[package]] name = "pillow" -version = "11.3.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/d0d6dea55cd152ce3d6767bb38a8fc10e33796ba4ba210cbab9354b6d238/pillow-11.3.0.tar.gz", hash = "sha256:3828ee7586cd0b2091b6209e5ad53e20d0649bbe87164a459d0676e035e8f523", size = 47113069, upload-time = "2025-07-01T09:16:30.666Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/93/0952f2ed8db3a5a4c7a11f91965d6184ebc8cd7cbb7941a260d5f018cd2d/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:1c627742b539bba4309df89171356fcb3cc5a9178355b2727d1b74a6cf155fbd", size = 2128328, upload-time = "2025-07-01T09:14:35.276Z" }, - { url = "https://files.pythonhosted.org/packages/4b/e8/100c3d114b1a0bf4042f27e0f87d2f25e857e838034e98ca98fe7b8c0a9c/pillow-11.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:30b7c02f3899d10f13d7a48163c8969e4e653f8b43416d23d13d1bbfdc93b9f8", size = 2170652, upload-time = "2025-07-01T09:14:37.203Z" }, - { url = "https://files.pythonhosted.org/packages/aa/86/3f758a28a6e381758545f7cdb4942e1cb79abd271bea932998fc0db93cb6/pillow-11.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:7859a4cc7c9295f5838015d8cc0a9c215b77e43d07a25e460f35cf516df8626f", size = 2227443, upload-time = "2025-07-01T09:14:39.344Z" }, - { url = "https://files.pythonhosted.org/packages/01/f4/91d5b3ffa718df2f53b0dc109877993e511f4fd055d7e9508682e8aba092/pillow-11.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ec1ee50470b0d050984394423d96325b744d55c701a439d2bd66089bff963d3c", size = 5278474, upload-time = "2025-07-01T09:14:41.843Z" }, - { url = "https://files.pythonhosted.org/packages/f9/0e/37d7d3eca6c879fbd9dba21268427dffda1ab00d4eb05b32923d4fbe3b12/pillow-11.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7db51d222548ccfd274e4572fdbf3e810a5e66b00608862f947b163e613b67dd", size = 4686038, upload-time = "2025-07-01T09:14:44.008Z" }, - { url = "https://files.pythonhosted.org/packages/ff/b0/3426e5c7f6565e752d81221af9d3676fdbb4f352317ceafd42899aaf5d8a/pillow-11.3.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2d6fcc902a24ac74495df63faad1884282239265c6839a0a6416d33faedfae7e", size = 5864407, upload-time = "2025-07-03T13:10:15.628Z" }, - { url = "https://files.pythonhosted.org/packages/fc/c1/c6c423134229f2a221ee53f838d4be9d82bab86f7e2f8e75e47b6bf6cd77/pillow-11.3.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f0f5d8f4a08090c6d6d578351a2b91acf519a54986c055af27e7a93feae6d3f1", size = 7639094, upload-time = "2025-07-03T13:10:21.857Z" }, - { url = "https://files.pythonhosted.org/packages/ba/c9/09e6746630fe6372c67c648ff9deae52a2bc20897d51fa293571977ceb5d/pillow-11.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c37d8ba9411d6003bba9e518db0db0c58a680ab9fe5179f040b0463644bc9805", size = 5973503, upload-time = "2025-07-01T09:14:45.698Z" }, - { url = "https://files.pythonhosted.org/packages/d5/1c/a2a29649c0b1983d3ef57ee87a66487fdeb45132df66ab30dd37f7dbe162/pillow-11.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:13f87d581e71d9189ab21fe0efb5a23e9f28552d5be6979e84001d3b8505abe8", size = 6642574, upload-time = "2025-07-01T09:14:47.415Z" }, - { url = "https://files.pythonhosted.org/packages/36/de/d5cc31cc4b055b6c6fd990e3e7f0f8aaf36229a2698501bcb0cdf67c7146/pillow-11.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:023f6d2d11784a465f09fd09a34b150ea4672e85fb3d05931d89f373ab14abb2", size = 6084060, upload-time = "2025-07-01T09:14:49.636Z" }, - { url = "https://files.pythonhosted.org/packages/d5/ea/502d938cbaeec836ac28a9b730193716f0114c41325db428e6b280513f09/pillow-11.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:45dfc51ac5975b938e9809451c51734124e73b04d0f0ac621649821a63852e7b", size = 6721407, upload-time = "2025-07-01T09:14:51.962Z" }, - { url = "https://files.pythonhosted.org/packages/45/9c/9c5e2a73f125f6cbc59cc7087c8f2d649a7ae453f83bd0362ff7c9e2aee2/pillow-11.3.0-cp313-cp313-win32.whl", hash = "sha256:a4d336baed65d50d37b88ca5b60c0fa9d81e3a87d4a7930d3880d1624d5b31f3", size = 6273841, upload-time = "2025-07-01T09:14:54.142Z" }, - { url = "https://files.pythonhosted.org/packages/23/85/397c73524e0cd212067e0c969aa245b01d50183439550d24d9f55781b776/pillow-11.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:0bce5c4fd0921f99d2e858dc4d4d64193407e1b99478bc5cacecba2311abde51", size = 6978450, upload-time = "2025-07-01T09:14:56.436Z" }, - { url = "https://files.pythonhosted.org/packages/17/d2/622f4547f69cd173955194b78e4d19ca4935a1b0f03a302d655c9f6aae65/pillow-11.3.0-cp313-cp313-win_arm64.whl", hash = "sha256:1904e1264881f682f02b7f8167935cce37bc97db457f8e7849dc3a6a52b99580", size = 2423055, upload-time = "2025-07-01T09:14:58.072Z" }, - { url = "https://files.pythonhosted.org/packages/dd/80/a8a2ac21dda2e82480852978416cfacd439a4b490a501a288ecf4fe2532d/pillow-11.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:4c834a3921375c48ee6b9624061076bc0a32a60b5532b322cc0ea64e639dd50e", size = 5281110, upload-time = "2025-07-01T09:14:59.79Z" }, - { url = "https://files.pythonhosted.org/packages/44/d6/b79754ca790f315918732e18f82a8146d33bcd7f4494380457ea89eb883d/pillow-11.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5e05688ccef30ea69b9317a9ead994b93975104a677a36a8ed8106be9260aa6d", size = 4689547, upload-time = "2025-07-01T09:15:01.648Z" }, - { url = "https://files.pythonhosted.org/packages/49/20/716b8717d331150cb00f7fdd78169c01e8e0c219732a78b0e59b6bdb2fd6/pillow-11.3.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1019b04af07fc0163e2810167918cb5add8d74674b6267616021ab558dc98ced", size = 5901554, upload-time = "2025-07-03T13:10:27.018Z" }, - { url = "https://files.pythonhosted.org/packages/74/cf/a9f3a2514a65bb071075063a96f0a5cf949c2f2fce683c15ccc83b1c1cab/pillow-11.3.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f944255db153ebb2b19c51fe85dd99ef0ce494123f21b9db4877ffdfc5590c7c", size = 7669132, upload-time = "2025-07-03T13:10:33.01Z" }, - { url = "https://files.pythonhosted.org/packages/98/3c/da78805cbdbee9cb43efe8261dd7cc0b4b93f2ac79b676c03159e9db2187/pillow-11.3.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f85acb69adf2aaee8b7da124efebbdb959a104db34d3a2cb0f3793dbae422a8", size = 6005001, upload-time = "2025-07-01T09:15:03.365Z" }, - { url = "https://files.pythonhosted.org/packages/6c/fa/ce044b91faecf30e635321351bba32bab5a7e034c60187fe9698191aef4f/pillow-11.3.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f6ecbeff5005399bb48d198f098a9b4b6bdf27b8487c7f38ca16eeb070cd59", size = 6668814, upload-time = "2025-07-01T09:15:05.655Z" }, - { url = "https://files.pythonhosted.org/packages/7b/51/90f9291406d09bf93686434f9183aba27b831c10c87746ff49f127ee80cb/pillow-11.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bc6e6fd0395bc052f16b1a8670859964dbd7003bd0af2ff08342eb6e442cfe", size = 6113124, upload-time = "2025-07-01T09:15:07.358Z" }, - { url = "https://files.pythonhosted.org/packages/cd/5a/6fec59b1dfb619234f7636d4157d11fb4e196caeee220232a8d2ec48488d/pillow-11.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:83e1b0161c9d148125083a35c1c5a89db5b7054834fd4387499e06552035236c", size = 6747186, upload-time = "2025-07-01T09:15:09.317Z" }, - { url = "https://files.pythonhosted.org/packages/49/6b/00187a044f98255225f172de653941e61da37104a9ea60e4f6887717e2b5/pillow-11.3.0-cp313-cp313t-win32.whl", hash = "sha256:2a3117c06b8fb646639dce83694f2f9eac405472713fcb1ae887469c0d4f6788", size = 6277546, upload-time = "2025-07-01T09:15:11.311Z" }, - { url = "https://files.pythonhosted.org/packages/e8/5c/6caaba7e261c0d75bab23be79f1d06b5ad2a2ae49f028ccec801b0e853d6/pillow-11.3.0-cp313-cp313t-win_amd64.whl", hash = "sha256:857844335c95bea93fb39e0fa2726b4d9d758850b34075a7e3ff4f4fa3aa3b31", size = 6985102, upload-time = "2025-07-01T09:15:13.164Z" }, - { url = "https://files.pythonhosted.org/packages/f3/7e/b623008460c09a0cb38263c93b828c666493caee2eb34ff67f778b87e58c/pillow-11.3.0-cp313-cp313t-win_arm64.whl", hash = "sha256:8797edc41f3e8536ae4b10897ee2f637235c94f27404cac7297f7b607dd0716e", size = 2424803, upload-time = "2025-07-01T09:15:15.695Z" }, - { url = "https://files.pythonhosted.org/packages/73/f4/04905af42837292ed86cb1b1dabe03dce1edc008ef14c473c5c7e1443c5d/pillow-11.3.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:d9da3df5f9ea2a89b81bb6087177fb1f4d1c7146d583a3fe5c672c0d94e55e12", size = 5278520, upload-time = "2025-07-01T09:15:17.429Z" }, - { url = "https://files.pythonhosted.org/packages/41/b0/33d79e377a336247df6348a54e6d2a2b85d644ca202555e3faa0cf811ecc/pillow-11.3.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:0b275ff9b04df7b640c59ec5a3cb113eefd3795a8df80bac69646ef699c6981a", size = 4686116, upload-time = "2025-07-01T09:15:19.423Z" }, - { url = "https://files.pythonhosted.org/packages/49/2d/ed8bc0ab219ae8768f529597d9509d184fe8a6c4741a6864fea334d25f3f/pillow-11.3.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0743841cabd3dba6a83f38a92672cccbd69af56e3e91777b0ee7f4dba4385632", size = 5864597, upload-time = "2025-07-03T13:10:38.404Z" }, - { url = "https://files.pythonhosted.org/packages/b5/3d/b932bb4225c80b58dfadaca9d42d08d0b7064d2d1791b6a237f87f661834/pillow-11.3.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2465a69cf967b8b49ee1b96d76718cd98c4e925414ead59fdf75cf0fd07df673", size = 7638246, upload-time = "2025-07-03T13:10:44.987Z" }, - { url = "https://files.pythonhosted.org/packages/09/b5/0487044b7c096f1b48f0d7ad416472c02e0e4bf6919541b111efd3cae690/pillow-11.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41742638139424703b4d01665b807c6468e23e699e8e90cffefe291c5832b027", size = 5973336, upload-time = "2025-07-01T09:15:21.237Z" }, - { url = "https://files.pythonhosted.org/packages/a8/2d/524f9318f6cbfcc79fbc004801ea6b607ec3f843977652fdee4857a7568b/pillow-11.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:93efb0b4de7e340d99057415c749175e24c8864302369e05914682ba642e5d77", size = 6642699, upload-time = "2025-07-01T09:15:23.186Z" }, - { url = "https://files.pythonhosted.org/packages/6f/d2/a9a4f280c6aefedce1e8f615baaa5474e0701d86dd6f1dede66726462bbd/pillow-11.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7966e38dcd0fa11ca390aed7c6f20454443581d758242023cf36fcb319b1a874", size = 6083789, upload-time = "2025-07-01T09:15:25.1Z" }, - { url = "https://files.pythonhosted.org/packages/fe/54/86b0cd9dbb683a9d5e960b66c7379e821a19be4ac5810e2e5a715c09a0c0/pillow-11.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:98a9afa7b9007c67ed84c57c9e0ad86a6000da96eaa638e4f8abe5b65ff83f0a", size = 6720386, upload-time = "2025-07-01T09:15:27.378Z" }, - { url = "https://files.pythonhosted.org/packages/e7/95/88efcaf384c3588e24259c4203b909cbe3e3c2d887af9e938c2022c9dd48/pillow-11.3.0-cp314-cp314-win32.whl", hash = "sha256:02a723e6bf909e7cea0dac1b0e0310be9d7650cd66222a5f1c571455c0a45214", size = 6370911, upload-time = "2025-07-01T09:15:29.294Z" }, - { url = "https://files.pythonhosted.org/packages/2e/cc/934e5820850ec5eb107e7b1a72dd278140731c669f396110ebc326f2a503/pillow-11.3.0-cp314-cp314-win_amd64.whl", hash = "sha256:a418486160228f64dd9e9efcd132679b7a02a5f22c982c78b6fc7dab3fefb635", size = 7117383, upload-time = "2025-07-01T09:15:31.128Z" }, - { url = "https://files.pythonhosted.org/packages/d6/e9/9c0a616a71da2a5d163aa37405e8aced9a906d574b4a214bede134e731bc/pillow-11.3.0-cp314-cp314-win_arm64.whl", hash = "sha256:155658efb5e044669c08896c0c44231c5e9abcaadbc5cd3648df2f7c0b96b9a6", size = 2511385, upload-time = "2025-07-01T09:15:33.328Z" }, - { url = "https://files.pythonhosted.org/packages/1a/33/c88376898aff369658b225262cd4f2659b13e8178e7534df9e6e1fa289f6/pillow-11.3.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:59a03cdf019efbfeeed910bf79c7c93255c3d54bc45898ac2a4140071b02b4ae", size = 5281129, upload-time = "2025-07-01T09:15:35.194Z" }, - { url = "https://files.pythonhosted.org/packages/1f/70/d376247fb36f1844b42910911c83a02d5544ebd2a8bad9efcc0f707ea774/pillow-11.3.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f8a5827f84d973d8636e9dc5764af4f0cf2318d26744b3d902931701b0d46653", size = 4689580, upload-time = "2025-07-01T09:15:37.114Z" }, - { url = "https://files.pythonhosted.org/packages/eb/1c/537e930496149fbac69efd2fc4329035bbe2e5475b4165439e3be9cb183b/pillow-11.3.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ee92f2fd10f4adc4b43d07ec5e779932b4eb3dbfbc34790ada5a6669bc095aa6", size = 5902860, upload-time = "2025-07-03T13:10:50.248Z" }, - { url = "https://files.pythonhosted.org/packages/bd/57/80f53264954dcefeebcf9dae6e3eb1daea1b488f0be8b8fef12f79a3eb10/pillow-11.3.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c96d333dcf42d01f47b37e0979b6bd73ec91eae18614864622d9b87bbd5bbf36", size = 7670694, upload-time = "2025-07-03T13:10:56.432Z" }, - { url = "https://files.pythonhosted.org/packages/70/ff/4727d3b71a8578b4587d9c276e90efad2d6fe0335fd76742a6da08132e8c/pillow-11.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4c96f993ab8c98460cd0c001447bff6194403e8b1d7e149ade5f00594918128b", size = 6005888, upload-time = "2025-07-01T09:15:39.436Z" }, - { url = "https://files.pythonhosted.org/packages/05/ae/716592277934f85d3be51d7256f3636672d7b1abfafdc42cf3f8cbd4b4c8/pillow-11.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:41342b64afeba938edb034d122b2dda5db2139b9a4af999729ba8818e0056477", size = 6670330, upload-time = "2025-07-01T09:15:41.269Z" }, - { url = "https://files.pythonhosted.org/packages/e7/bb/7fe6cddcc8827b01b1a9766f5fdeb7418680744f9082035bdbabecf1d57f/pillow-11.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:068d9c39a2d1b358eb9f245ce7ab1b5c3246c7c8c7d9ba58cfa5b43146c06e50", size = 6114089, upload-time = "2025-07-01T09:15:43.13Z" }, - { url = "https://files.pythonhosted.org/packages/8b/f5/06bfaa444c8e80f1a8e4bff98da9c83b37b5be3b1deaa43d27a0db37ef84/pillow-11.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a1bc6ba083b145187f648b667e05a2534ecc4b9f2784c2cbe3089e44868f2b9b", size = 6748206, upload-time = "2025-07-01T09:15:44.937Z" }, - { url = "https://files.pythonhosted.org/packages/f0/77/bc6f92a3e8e6e46c0ca78abfffec0037845800ea38c73483760362804c41/pillow-11.3.0-cp314-cp314t-win32.whl", hash = "sha256:118ca10c0d60b06d006be10a501fd6bbdfef559251ed31b794668ed569c87e12", size = 6377370, upload-time = "2025-07-01T09:15:46.673Z" }, - { url = "https://files.pythonhosted.org/packages/4a/82/3a721f7d69dca802befb8af08b7c79ebcab461007ce1c18bd91a5d5896f9/pillow-11.3.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8924748b688aa210d79883357d102cd64690e56b923a186f35a82cbc10f997db", size = 7121500, upload-time = "2025-07-01T09:15:48.512Z" }, - { url = "https://files.pythonhosted.org/packages/89/c7/5572fa4a3f45740eaab6ae86fcdf7195b55beac1371ac8c619d880cfe948/pillow-11.3.0-cp314-cp314t-win_arm64.whl", hash = "sha256:79ea0d14d3ebad43ec77ad5272e6ff9bba5b679ef73375ea760261207fa8e0aa", size = 2512835, upload-time = "2025-07-01T09:15:50.399Z" }, -] - -[[package]] -name = "ply" -version = "3.11" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e5/69/882ee5c9d017149285cab114ebeab373308ef0f874fcdac9beb90e0ac4da/ply-3.11.tar.gz", hash = "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3", size = 159130, upload-time = "2018-02-15T19:01:31.097Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a3/58/35da89ee790598a0700ea49b2a66594140f44dec458c07e8e3d4979137fc/ply-3.11-py2.py3-none-any.whl", hash = "sha256:096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce", size = 49567, upload-time = "2018-02-15T19:01:27.172Z" }, -] - -[[package]] -name = "pyomo" -version = "6.9.4" +version = "12.2.0" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "ply" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/91/d4/bbb4ab79bb3015e3bdd488435ef71f7806144cc6ae4146ee6c5f64ac53f2/pyomo-6.9.4.tar.gz", hash = "sha256:34ad22cd6bf9956de9c0d3842d01c1f92dee0515b25aa3e8f113b326549b1231", size = 3033231, upload-time = "2025-08-28T02:11:24.976Z" } +sdist = { url = "https://files.pythonhosted.org/packages/8c/21/c2bcdd5906101a30244eaffc1b6e6ce71a31bd0742a01eb89e660ebfac2d/pillow-12.2.0.tar.gz", hash = "sha256:a830b1a40919539d07806aa58e1b114df53ddd43213d9c8b75847eee6c0182b5", size = 46987819, upload-time = "2026-04-01T14:46:17.687Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/65/04/dc4d3d9369c4cb1b6e68ce18bbba066ea83284942322836e791dbf693bb2/pyomo-6.9.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1a768a178ae3f0391c66e2334da3d1618c9c85c9d879bc86de441efd143f491", size = 4267029, upload-time = "2025-08-28T02:10:02.066Z" }, - { url = "https://files.pythonhosted.org/packages/6b/52/824e9cea51ed0a25636b66e8c122dce5fcd22a197bf4646dd6c5f138fe36/pyomo-6.9.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:09cde10e5fe8414f453d1ed3bccef1b42fc048fc2da0a9c936e40b2f877201bf", size = 4255606, upload-time = "2025-08-28T02:10:06.383Z" }, - { url = "https://files.pythonhosted.org/packages/a2/dc/97005d683ca57e231a8f613921adaf480d3a82f40d280c6d0185855a92c6/pyomo-6.9.4-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df3e173d330666f881258deefa79f37373b941d4a5b00edc6aa5b10680720dc1", size = 4312670, upload-time = "2025-08-28T02:10:11.563Z" }, - { url = "https://files.pythonhosted.org/packages/64/73/47525078660eced084abb9a79e1e4c74098c992316c93ab6ead2dc7f8bda/pyomo-6.9.4-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8a13baebcdb05deadeb0ec4b04ecedffa65f1e86179418fa67e603a4f8f1bf17", size = 4344540, upload-time = "2025-08-28T02:10:15.731Z" }, - { url = "https://files.pythonhosted.org/packages/d8/e3/56c20c3358e58206e7270a42ff666a267a6c01492213c8c47aad8676b487/pyomo-6.9.4-py3-none-any.whl", hash = "sha256:a274d74616c0b793279931f3b2175a31f9c63213f2d7b86c14d168c6c264f782", size = 3892640, upload-time = "2025-08-28T02:11:13.845Z" }, + { url = "https://files.pythonhosted.org/packages/4a/01/53d10cf0dbad820a8db274d259a37ba50b88b24768ddccec07355382d5ad/pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:8297651f5b5679c19968abefd6bb84d95fe30ef712eb1b2d9b2d31ca61267f4c", size = 4100837, upload-time = "2026-04-01T14:43:41.506Z" }, + { url = "https://files.pythonhosted.org/packages/0f/98/f3a6657ecb698c937f6c76ee564882945f29b79bad496abcba0e84659ec5/pillow-12.2.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:50d8520da2a6ce0af445fa6d648c4273c3eeefbc32d7ce049f22e8b5c3daecc2", size = 4176528, upload-time = "2026-04-01T14:43:43.773Z" }, + { url = "https://files.pythonhosted.org/packages/69/bc/8986948f05e3ea490b8442ea1c1d4d990b24a7e43d8a51b2c7d8b1dced36/pillow-12.2.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:766cef22385fa1091258ad7e6216792b156dc16d8d3fa607e7545b2b72061f1c", size = 3640401, upload-time = "2026-04-01T14:43:45.87Z" }, + { url = "https://files.pythonhosted.org/packages/34/46/6c717baadcd62bc8ed51d238d521ab651eaa74838291bda1f86fe1f864c9/pillow-12.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5d2fd0fa6b5d9d1de415060363433f28da8b1526c1c129020435e186794b3795", size = 5308094, upload-time = "2026-04-01T14:43:48.438Z" }, + { url = "https://files.pythonhosted.org/packages/71/43/905a14a8b17fdb1ccb58d282454490662d2cb89a6bfec26af6d3520da5ec/pillow-12.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56b25336f502b6ed02e889f4ece894a72612fe885889a6e8c4c80239ff6e5f5f", size = 4695402, upload-time = "2026-04-01T14:43:51.292Z" }, + { url = "https://files.pythonhosted.org/packages/73/dd/42107efcb777b16fa0393317eac58f5b5cf30e8392e266e76e51cff28c3d/pillow-12.2.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f1c943e96e85df3d3478f7b691f229887e143f81fedab9b20205349ab04d73ed", size = 6280005, upload-time = "2026-04-01T14:43:54.242Z" }, + { url = "https://files.pythonhosted.org/packages/a8/68/b93e09e5e8549019e61acf49f65b1a8530765a7f812c77a7461bca7e4494/pillow-12.2.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:03f6fab9219220f041c74aeaa2939ff0062bd5c364ba9ce037197f4c6d498cd9", size = 8090669, upload-time = "2026-04-01T14:43:57.335Z" }, + { url = "https://files.pythonhosted.org/packages/4b/6e/3ccb54ce8ec4ddd1accd2d89004308b7b0b21c4ac3d20fa70af4760a4330/pillow-12.2.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5cdfebd752ec52bf5bb4e35d9c64b40826bc5b40a13df7c3cda20a2c03a0f5ed", size = 6395194, upload-time = "2026-04-01T14:43:59.864Z" }, + { url = "https://files.pythonhosted.org/packages/67/ee/21d4e8536afd1a328f01b359b4d3997b291ffd35a237c877b331c1c3b71c/pillow-12.2.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eedf4b74eda2b5a4b2b2fb4c006d6295df3bf29e459e198c90ea48e130dc75c3", size = 7082423, upload-time = "2026-04-01T14:44:02.74Z" }, + { url = "https://files.pythonhosted.org/packages/78/5f/e9f86ab0146464e8c133fe85df987ed9e77e08b29d8d35f9f9f4d6f917ba/pillow-12.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:00a2865911330191c0b818c59103b58a5e697cae67042366970a6b6f1b20b7f9", size = 6505667, upload-time = "2026-04-01T14:44:05.381Z" }, + { url = "https://files.pythonhosted.org/packages/ed/1e/409007f56a2fdce61584fd3acbc2bbc259857d555196cedcadc68c015c82/pillow-12.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1e1757442ed87f4912397c6d35a0db6a7b52592156014706f17658ff58bbf795", size = 7208580, upload-time = "2026-04-01T14:44:08.39Z" }, + { url = "https://files.pythonhosted.org/packages/23/c4/7349421080b12fb35414607b8871e9534546c128a11965fd4a7002ccfbee/pillow-12.2.0-cp313-cp313-win32.whl", hash = "sha256:144748b3af2d1b358d41286056d0003f47cb339b8c43a9ea42f5fea4d8c66b6e", size = 6375896, upload-time = "2026-04-01T14:44:11.197Z" }, + { url = "https://files.pythonhosted.org/packages/3f/82/8a3739a5e470b3c6cbb1d21d315800d8e16bff503d1f16b03a4ec3212786/pillow-12.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:390ede346628ccc626e5730107cde16c42d3836b89662a115a921f28440e6a3b", size = 7081266, upload-time = "2026-04-01T14:44:13.947Z" }, + { url = "https://files.pythonhosted.org/packages/c3/25/f968f618a062574294592f668218f8af564830ccebdd1fa6200f598e65c5/pillow-12.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:8023abc91fba39036dbce14a7d6535632f99c0b857807cbbbf21ecc9f4717f06", size = 2463508, upload-time = "2026-04-01T14:44:16.312Z" }, + { url = "https://files.pythonhosted.org/packages/4d/a4/b342930964e3cb4dce5038ae34b0eab4653334995336cd486c5a8c25a00c/pillow-12.2.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:042db20a421b9bafecc4b84a8b6e444686bd9d836c7fd24542db3e7df7baad9b", size = 5309927, upload-time = "2026-04-01T14:44:18.89Z" }, + { url = "https://files.pythonhosted.org/packages/9f/de/23198e0a65a9cf06123f5435a5d95cea62a635697f8f03d134d3f3a96151/pillow-12.2.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:dd025009355c926a84a612fecf58bb315a3f6814b17ead51a8e48d3823d9087f", size = 4698624, upload-time = "2026-04-01T14:44:21.115Z" }, + { url = "https://files.pythonhosted.org/packages/01/a6/1265e977f17d93ea37aa28aa81bad4fa597933879fac2520d24e021c8da3/pillow-12.2.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:88ddbc66737e277852913bd1e07c150cc7bb124539f94c4e2df5344494e0a612", size = 6321252, upload-time = "2026-04-01T14:44:23.663Z" }, + { url = "https://files.pythonhosted.org/packages/3c/83/5982eb4a285967baa70340320be9f88e57665a387e3a53a7f0db8231a0cd/pillow-12.2.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d362d1878f00c142b7e1a16e6e5e780f02be8195123f164edf7eddd911eefe7c", size = 8126550, upload-time = "2026-04-01T14:44:26.772Z" }, + { url = "https://files.pythonhosted.org/packages/4e/48/6ffc514adce69f6050d0753b1a18fd920fce8cac87620d5a31231b04bfc5/pillow-12.2.0-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2c727a6d53cb0018aadd8018c2b938376af27914a68a492f59dfcaca650d5eea", size = 6433114, upload-time = "2026-04-01T14:44:29.615Z" }, + { url = "https://files.pythonhosted.org/packages/36/a3/f9a77144231fb8d40ee27107b4463e205fa4677e2ca2548e14da5cf18dce/pillow-12.2.0-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:efd8c21c98c5cc60653bcb311bef2ce0401642b7ce9d09e03a7da87c878289d4", size = 7115667, upload-time = "2026-04-01T14:44:32.773Z" }, + { url = "https://files.pythonhosted.org/packages/c1/fc/ac4ee3041e7d5a565e1c4fd72a113f03b6394cc72ab7089d27608f8aaccb/pillow-12.2.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9f08483a632889536b8139663db60f6724bfcb443c96f1b18855860d7d5c0fd4", size = 6538966, upload-time = "2026-04-01T14:44:35.252Z" }, + { url = "https://files.pythonhosted.org/packages/c0/a8/27fb307055087f3668f6d0a8ccb636e7431d56ed0750e07a60547b1e083e/pillow-12.2.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:dac8d77255a37e81a2efcbd1fc05f1c15ee82200e6c240d7e127e25e365c39ea", size = 7238241, upload-time = "2026-04-01T14:44:37.875Z" }, + { url = "https://files.pythonhosted.org/packages/ad/4b/926ab182c07fccae9fcb120043464e1ff1564775ec8864f21a0ebce6ac25/pillow-12.2.0-cp313-cp313t-win32.whl", hash = "sha256:ee3120ae9dff32f121610bb08e4313be87e03efeadfc6c0d18f89127e24d0c24", size = 6379592, upload-time = "2026-04-01T14:44:40.336Z" }, + { url = "https://files.pythonhosted.org/packages/c2/c4/f9e476451a098181b30050cc4c9a3556b64c02cf6497ea421ac047e89e4b/pillow-12.2.0-cp313-cp313t-win_amd64.whl", hash = "sha256:325ca0528c6788d2a6c3d40e3568639398137346c3d6e66bb61db96b96511c98", size = 7085542, upload-time = "2026-04-01T14:44:43.251Z" }, + { url = "https://files.pythonhosted.org/packages/00/a4/285f12aeacbe2d6dc36c407dfbbe9e96d4a80b0fb710a337f6d2ad978c75/pillow-12.2.0-cp313-cp313t-win_arm64.whl", hash = "sha256:2e5a76d03a6c6dcef67edabda7a52494afa4035021a79c8558e14af25313d453", size = 2465765, upload-time = "2026-04-01T14:44:45.996Z" }, + { url = "https://files.pythonhosted.org/packages/bf/98/4595daa2365416a86cb0d495248a393dfc84e96d62ad080c8546256cb9c0/pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:3adc9215e8be0448ed6e814966ecf3d9952f0ea40eb14e89a102b87f450660d8", size = 4100848, upload-time = "2026-04-01T14:44:48.48Z" }, + { url = "https://files.pythonhosted.org/packages/0b/79/40184d464cf89f6663e18dfcf7ca21aae2491fff1a16127681bf1fa9b8cf/pillow-12.2.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:6a9adfc6d24b10f89588096364cc726174118c62130c817c2837c60cf08a392b", size = 4176515, upload-time = "2026-04-01T14:44:51.353Z" }, + { url = "https://files.pythonhosted.org/packages/b0/63/703f86fd4c422a9cf722833670f4f71418fb116b2853ff7da722ea43f184/pillow-12.2.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:6a6e67ea2e6feda684ed370f9a1c52e7a243631c025ba42149a2cc5934dec295", size = 3640159, upload-time = "2026-04-01T14:44:53.588Z" }, + { url = "https://files.pythonhosted.org/packages/71/e0/fb22f797187d0be2270f83500aab851536101b254bfa1eae10795709d283/pillow-12.2.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:2bb4a8d594eacdfc59d9e5ad972aa8afdd48d584ffd5f13a937a664c3e7db0ed", size = 5312185, upload-time = "2026-04-01T14:44:56.039Z" }, + { url = "https://files.pythonhosted.org/packages/ba/8c/1a9e46228571de18f8e28f16fabdfc20212a5d019f3e3303452b3f0a580d/pillow-12.2.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:80b2da48193b2f33ed0c32c38140f9d3186583ce7d516526d462645fd98660ae", size = 4695386, upload-time = "2026-04-01T14:44:58.663Z" }, + { url = "https://files.pythonhosted.org/packages/70/62/98f6b7f0c88b9addd0e87c217ded307b36be024d4ff8869a812b241d1345/pillow-12.2.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22db17c68434de69d8ecfc2fe821569195c0c373b25cccb9cbdacf2c6e53c601", size = 6280384, upload-time = "2026-04-01T14:45:01.5Z" }, + { url = "https://files.pythonhosted.org/packages/5e/03/688747d2e91cfbe0e64f316cd2e8005698f76ada3130d0194664174fa5de/pillow-12.2.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7b14cc0106cd9aecda615dd6903840a058b4700fcb817687d0ee4fc8b6e389be", size = 8091599, upload-time = "2026-04-01T14:45:04.5Z" }, + { url = "https://files.pythonhosted.org/packages/f6/35/577e22b936fcdd66537329b33af0b4ccfefaeabd8aec04b266528cddb33c/pillow-12.2.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cbeb542b2ebc6fcdacabf8aca8c1a97c9b3ad3927d46b8723f9d4f033288a0f", size = 6396021, upload-time = "2026-04-01T14:45:07.117Z" }, + { url = "https://files.pythonhosted.org/packages/11/8d/d2532ad2a603ca2b93ad9f5135732124e57811d0168155852f37fbce2458/pillow-12.2.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4bfd07bc812fbd20395212969e41931001fd59eb55a60658b0e5710872e95286", size = 7083360, upload-time = "2026-04-01T14:45:09.763Z" }, + { url = "https://files.pythonhosted.org/packages/5e/26/d325f9f56c7e039034897e7380e9cc202b1e368bfd04d4cbe6a441f02885/pillow-12.2.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9aba9a17b623ef750a4d11b742cbafffeb48a869821252b30ee21b5e91392c50", size = 6507628, upload-time = "2026-04-01T14:45:12.378Z" }, + { url = "https://files.pythonhosted.org/packages/5f/f7/769d5632ffb0988f1c5e7660b3e731e30f7f8ec4318e94d0a5d674eb65a4/pillow-12.2.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:deede7c263feb25dba4e82ea23058a235dcc2fe1f6021025dc71f2b618e26104", size = 7209321, upload-time = "2026-04-01T14:45:15.122Z" }, + { url = "https://files.pythonhosted.org/packages/6a/7a/c253e3c645cd47f1aceea6a8bacdba9991bf45bb7dfe927f7c893e89c93c/pillow-12.2.0-cp314-cp314-win32.whl", hash = "sha256:632ff19b2778e43162304d50da0181ce24ac5bb8180122cbe1bf4673428328c7", size = 6479723, upload-time = "2026-04-01T14:45:17.797Z" }, + { url = "https://files.pythonhosted.org/packages/cd/8b/601e6566b957ca50e28725cb6c355c59c2c8609751efbecd980db44e0349/pillow-12.2.0-cp314-cp314-win_amd64.whl", hash = "sha256:4e6c62e9d237e9b65fac06857d511e90d8461a32adcc1b9065ea0c0fa3a28150", size = 7217400, upload-time = "2026-04-01T14:45:20.529Z" }, + { url = "https://files.pythonhosted.org/packages/d6/94/220e46c73065c3e2951bb91c11a1fb636c8c9ad427ac3ce7d7f3359b9b2f/pillow-12.2.0-cp314-cp314-win_arm64.whl", hash = "sha256:b1c1fbd8a5a1af3412a0810d060a78b5136ec0836c8a4ef9aa11807f2a22f4e1", size = 2554835, upload-time = "2026-04-01T14:45:23.162Z" }, + { url = "https://files.pythonhosted.org/packages/b6/ab/1b426a3974cb0e7da5c29ccff4807871d48110933a57207b5a676cccc155/pillow-12.2.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:57850958fe9c751670e49b2cecf6294acc99e562531f4bd317fa5ddee2068463", size = 5314225, upload-time = "2026-04-01T14:45:25.637Z" }, + { url = "https://files.pythonhosted.org/packages/19/1e/dce46f371be2438eecfee2a1960ee2a243bbe5e961890146d2dee1ff0f12/pillow-12.2.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d5d38f1411c0ed9f97bcb49b7bd59b6b7c314e0e27420e34d99d844b9ce3b6f3", size = 4698541, upload-time = "2026-04-01T14:45:28.355Z" }, + { url = "https://files.pythonhosted.org/packages/55/c3/7fbecf70adb3a0c33b77a300dc52e424dc22ad8cdc06557a2e49523b703d/pillow-12.2.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5c0a9f29ca8e79f09de89293f82fc9b0270bb4af1d58bc98f540cc4aedf03166", size = 6322251, upload-time = "2026-04-01T14:45:30.924Z" }, + { url = "https://files.pythonhosted.org/packages/1c/3c/7fbc17cfb7e4fe0ef1642e0abc17fc6c94c9f7a16be41498e12e2ba60408/pillow-12.2.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1610dd6c61621ae1cf811bef44d77e149ce3f7b95afe66a4512f8c59f25d9ebe", size = 8127807, upload-time = "2026-04-01T14:45:33.908Z" }, + { url = "https://files.pythonhosted.org/packages/ff/c3/a8ae14d6defd2e448493ff512fae903b1e9bd40b72efb6ec55ce0048c8ce/pillow-12.2.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0a34329707af4f73cf1782a36cd2289c0368880654a2c11f027bcee9052d35dd", size = 6433935, upload-time = "2026-04-01T14:45:36.623Z" }, + { url = "https://files.pythonhosted.org/packages/6e/32/2880fb3a074847ac159d8f902cb43278a61e85f681661e7419e6596803ed/pillow-12.2.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e9c4f5b3c546fa3458a29ab22646c1c6c787ea8f5ef51300e5a60300736905e", size = 7116720, upload-time = "2026-04-01T14:45:39.258Z" }, + { url = "https://files.pythonhosted.org/packages/46/87/495cc9c30e0129501643f24d320076f4cc54f718341df18cc70ec94c44e1/pillow-12.2.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:fb043ee2f06b41473269765c2feae53fc2e2fbf96e5e22ca94fb5ad677856f06", size = 6540498, upload-time = "2026-04-01T14:45:41.879Z" }, + { url = "https://files.pythonhosted.org/packages/18/53/773f5edca692009d883a72211b60fdaf8871cbef075eaa9d577f0a2f989e/pillow-12.2.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f278f034eb75b4e8a13a54a876cc4a5ab39173d2cdd93a638e1b467fc545ac43", size = 7239413, upload-time = "2026-04-01T14:45:44.705Z" }, + { url = "https://files.pythonhosted.org/packages/c9/e4/4b64a97d71b2a83158134abbb2f5bd3f8a2ea691361282f010998f339ec7/pillow-12.2.0-cp314-cp314t-win32.whl", hash = "sha256:6bb77b2dcb06b20f9f4b4a8454caa581cd4dd0643a08bacf821216a16d9c8354", size = 6482084, upload-time = "2026-04-01T14:45:47.568Z" }, + { url = "https://files.pythonhosted.org/packages/ba/13/306d275efd3a3453f72114b7431c877d10b1154014c1ebbedd067770d629/pillow-12.2.0-cp314-cp314t-win_amd64.whl", hash = "sha256:6562ace0d3fb5f20ed7290f1f929cae41b25ae29528f2af1722966a0a02e2aa1", size = 7225152, upload-time = "2026-04-01T14:45:50.032Z" }, + { url = "https://files.pythonhosted.org/packages/ff/6e/cf826fae916b8658848d7b9f38d88da6396895c676e8086fc0988073aaf8/pillow-12.2.0-cp314-cp314t-win_arm64.whl", hash = "sha256:aa88ccfe4e32d362816319ed727a004423aab09c5cea43c01a4b435643fa34eb", size = 2556579, upload-time = "2026-04-01T14:45:52.529Z" }, ] [[package]] name = "pyparsing" -version = "3.2.4" +version = "3.3.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/98/c9/b4594e6a81371dfa9eb7a2c110ad682acf985d96115ae8b25a1d63b4bf3b/pyparsing-3.2.4.tar.gz", hash = "sha256:fff89494f45559d0f2ce46613b419f632bbb6afbdaed49696d322bcf98a58e99", size = 1098809, upload-time = "2025-09-13T05:47:19.732Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/53/b8/fbab973592e23ae313042d450fc26fa24282ebffba21ba373786e1ce63b4/pyparsing-3.2.4-py3-none-any.whl", hash = "sha256:91d0fcde680d42cd031daf3a6ba20da3107e08a75de50da58360e7d94ab24d36", size = 113869, upload-time = "2025-09-13T05:47:17.863Z" }, + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, ] [[package]] @@ -587,95 +669,95 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] -[[package]] -name = "pytz" -version = "2025.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f8/bf/abbd3cdfb8fbc7fb3d4d38d320f2441b1e7cbe29be4f23797b4a2b5d8aac/pytz-2025.2.tar.gz", hash = "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3", size = 320884, upload-time = "2025-03-25T02:25:00.538Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/81/c4/34e93fe5f5429d7570ec1fa436f1986fb1f00c3e0f43a589fe2bbcd22c3f/pytz-2025.2-py2.py3-none-any.whl", hash = "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00", size = 509225, upload-time = "2025-03-25T02:24:58.468Z" }, -] - [[package]] name = "pyyaml" -version = "6.0.2" +version = "6.0.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, - { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, - { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, - { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, - { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, - { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, - { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, - { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, - { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] [[package]] name = "quadax" -version = "0.2.9" +version = "0.2.13" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "equinox" }, { name = "jax" }, { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f6/a0/df4a3f61e90039e8e70100199d4b80a2529e876cebba8818c86218e6ea83/quadax-0.2.9.tar.gz", hash = "sha256:594ffddc0af894d9d89fd145dc3907168d6ead29e05e266548b2365b850eda51", size = 35445, upload-time = "2025-07-31T00:31:46.377Z" } +sdist = { url = "https://files.pythonhosted.org/packages/11/59/d45759a97e8acb0266444a3452c98139d4a75ada6ccf4020d62a09f4ac03/quadax-0.2.13.tar.gz", hash = "sha256:136359729026d42f8566dbdbfa361dab78ac906ffb8363705434fc5d4957354b", size = 36353, upload-time = "2026-04-18T00:36:04.701Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/24/e9/07b545bda225fb8ccff5e5d20361bd90f352d8df8380adcd5f59e149ca65/quadax-0.2.9-py3-none-any.whl", hash = "sha256:41c72d919294a2db3afa797d1ea1183f960d04f4aaec383267d16df68c76e267", size = 30730, upload-time = "2025-07-31T00:31:45.09Z" }, + { url = "https://files.pythonhosted.org/packages/22/cc/4fa4d2ac1c1a4c3d300f0f49f6052f34c13a0dcb8a5d9134a725c8410626/quadax-0.2.13-py3-none-any.whl", hash = "sha256:4ab69b77cc3ecdf64fcb1c5091bcadd280386406eab3609002808084860a3eb0", size = 31607, upload-time = "2026-04-18T00:36:03.201Z" }, ] [[package]] name = "scipy" -version = "1.16.2" +version = "1.18.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4c/3b/546a6f0bfe791bbb7f8d591613454d15097e53f906308ec6f7c1ce588e8e/scipy-1.16.2.tar.gz", hash = "sha256:af029b153d243a80afb6eabe40b0a07f8e35c9adc269c019f364ad747f826a6b", size = 30580599, upload-time = "2025-09-11T17:48:08.271Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/25/c2700dfaf6442b4effaa91af24ebce5dc9d31bb4a69706313aae70d72cd0/scipy-1.18.0.tar.gz", hash = "sha256:67b2ad2ad54c72ca6d04975a9b2df8c3638c34ddd5b28738e94fc2b57929d378", size = 30774447, upload-time = "2026-06-19T15:01:43.456Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/27/c5b52f1ee81727a9fc457f5ac1e9bf3d6eab311805ea615c83c27ba06400/scipy-1.16.2-cp313-cp313-macosx_10_14_x86_64.whl", hash = "sha256:84f7bf944b43e20b8a894f5fe593976926744f6c185bacfcbdfbb62736b5cc70", size = 36604856, upload-time = "2025-09-11T17:41:47.695Z" }, - { url = "https://files.pythonhosted.org/packages/32/a9/15c20d08e950b540184caa8ced675ba1128accb0e09c653780ba023a4110/scipy-1.16.2-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:5c39026d12edc826a1ef2ad35ad1e6d7f087f934bb868fc43fa3049c8b8508f9", size = 28864626, upload-time = "2025-09-11T17:41:52.642Z" }, - { url = "https://files.pythonhosted.org/packages/4c/fc/ea36098df653cca26062a627c1a94b0de659e97127c8491e18713ca0e3b9/scipy-1.16.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e52729ffd45b68777c5319560014d6fd251294200625d9d70fd8626516fc49f5", size = 20855689, upload-time = "2025-09-11T17:41:57.886Z" }, - { url = "https://files.pythonhosted.org/packages/dc/6f/d0b53be55727f3e6d7c72687ec18ea6d0047cf95f1f77488b99a2bafaee1/scipy-1.16.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:024dd4a118cccec09ca3209b7e8e614931a6ffb804b2a601839499cb88bdf925", size = 23512151, upload-time = "2025-09-11T17:42:02.303Z" }, - { url = "https://files.pythonhosted.org/packages/11/85/bf7dab56e5c4b1d3d8eef92ca8ede788418ad38a7dc3ff50262f00808760/scipy-1.16.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7a5dc7ee9c33019973a470556081b0fd3c9f4c44019191039f9769183141a4d9", size = 33329824, upload-time = "2025-09-11T17:42:07.549Z" }, - { url = "https://files.pythonhosted.org/packages/da/6a/1a927b14ddc7714111ea51f4e568203b2bb6ed59bdd036d62127c1a360c8/scipy-1.16.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c2275ff105e508942f99d4e3bc56b6ef5e4b3c0af970386ca56b777608ce95b7", size = 35681881, upload-time = "2025-09-11T17:42:13.255Z" }, - { url = "https://files.pythonhosted.org/packages/c1/5f/331148ea5780b4fcc7007a4a6a6ee0a0c1507a796365cc642d4d226e1c3a/scipy-1.16.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:af80196eaa84f033e48444d2e0786ec47d328ba00c71e4299b602235ffef9acb", size = 36006219, upload-time = "2025-09-11T17:42:18.765Z" }, - { url = "https://files.pythonhosted.org/packages/46/3a/e991aa9d2aec723b4a8dcfbfc8365edec5d5e5f9f133888067f1cbb7dfc1/scipy-1.16.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9fb1eb735fe3d6ed1f89918224e3385fbf6f9e23757cacc35f9c78d3b712dd6e", size = 38682147, upload-time = "2025-09-11T17:42:25.177Z" }, - { url = "https://files.pythonhosted.org/packages/a1/57/0f38e396ad19e41b4c5db66130167eef8ee620a49bc7d0512e3bb67e0cab/scipy-1.16.2-cp313-cp313-win_amd64.whl", hash = "sha256:fda714cf45ba43c9d3bae8f2585c777f64e3f89a2e073b668b32ede412d8f52c", size = 38520766, upload-time = "2025-09-11T17:43:25.342Z" }, - { url = "https://files.pythonhosted.org/packages/1b/a5/85d3e867b6822d331e26c862a91375bb7746a0b458db5effa093d34cdb89/scipy-1.16.2-cp313-cp313-win_arm64.whl", hash = "sha256:2f5350da923ccfd0b00e07c3e5cfb316c1c0d6c1d864c07a72d092e9f20db104", size = 25451169, upload-time = "2025-09-11T17:43:30.198Z" }, - { url = "https://files.pythonhosted.org/packages/09/d9/60679189bcebda55992d1a45498de6d080dcaf21ce0c8f24f888117e0c2d/scipy-1.16.2-cp313-cp313t-macosx_10_14_x86_64.whl", hash = "sha256:53d8d2ee29b925344c13bda64ab51785f016b1b9617849dac10897f0701b20c1", size = 37012682, upload-time = "2025-09-11T17:42:30.677Z" }, - { url = "https://files.pythonhosted.org/packages/83/be/a99d13ee4d3b7887a96f8c71361b9659ba4ef34da0338f14891e102a127f/scipy-1.16.2-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:9e05e33657efb4c6a9d23bd8300101536abd99c85cca82da0bffff8d8764d08a", size = 29389926, upload-time = "2025-09-11T17:42:35.845Z" }, - { url = "https://files.pythonhosted.org/packages/bf/0a/130164a4881cec6ca8c00faf3b57926f28ed429cd6001a673f83c7c2a579/scipy-1.16.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:7fe65b36036357003b3ef9d37547abeefaa353b237e989c21027b8ed62b12d4f", size = 21381152, upload-time = "2025-09-11T17:42:40.07Z" }, - { url = "https://files.pythonhosted.org/packages/47/a6/503ffb0310ae77fba874e10cddfc4a1280bdcca1d13c3751b8c3c2996cf8/scipy-1.16.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:6406d2ac6d40b861cccf57f49592f9779071655e9f75cd4f977fa0bdd09cb2e4", size = 23914410, upload-time = "2025-09-11T17:42:44.313Z" }, - { url = "https://files.pythonhosted.org/packages/fa/c7/1147774bcea50d00c02600aadaa919facbd8537997a62496270133536ed6/scipy-1.16.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ff4dc42bd321991fbf611c23fc35912d690f731c9914bf3af8f417e64aca0f21", size = 33481880, upload-time = "2025-09-11T17:42:49.325Z" }, - { url = "https://files.pythonhosted.org/packages/6a/74/99d5415e4c3e46b2586f30cdbecb95e101c7192628a484a40dd0d163811a/scipy-1.16.2-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:654324826654d4d9133e10675325708fb954bc84dae6e9ad0a52e75c6b1a01d7", size = 35791425, upload-time = "2025-09-11T17:42:54.711Z" }, - { url = "https://files.pythonhosted.org/packages/1b/ee/a6559de7c1cc710e938c0355d9d4fbcd732dac4d0d131959d1f3b63eb29c/scipy-1.16.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:63870a84cd15c44e65220eaed2dac0e8f8b26bbb991456a033c1d9abfe8a94f8", size = 36178622, upload-time = "2025-09-11T17:43:00.375Z" }, - { url = "https://files.pythonhosted.org/packages/4e/7b/f127a5795d5ba8ece4e0dce7d4a9fb7cb9e4f4757137757d7a69ab7d4f1a/scipy-1.16.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:fa01f0f6a3050fa6a9771a95d5faccc8e2f5a92b4a2e5440a0fa7264a2398472", size = 38783985, upload-time = "2025-09-11T17:43:06.661Z" }, - { url = "https://files.pythonhosted.org/packages/3e/9f/bc81c1d1e033951eb5912cd3750cc005943afa3e65a725d2443a3b3c4347/scipy-1.16.2-cp313-cp313t-win_amd64.whl", hash = "sha256:116296e89fba96f76353a8579820c2512f6e55835d3fad7780fece04367de351", size = 38631367, upload-time = "2025-09-11T17:43:14.44Z" }, - { url = "https://files.pythonhosted.org/packages/d6/5e/2cc7555fd81d01814271412a1d59a289d25f8b63208a0a16c21069d55d3e/scipy-1.16.2-cp313-cp313t-win_arm64.whl", hash = "sha256:98e22834650be81d42982360382b43b17f7ba95e0e6993e2a4f5b9ad9283a94d", size = 25787992, upload-time = "2025-09-11T17:43:19.745Z" }, - { url = "https://files.pythonhosted.org/packages/8b/ac/ad8951250516db71619f0bd3b2eb2448db04b720a003dd98619b78b692c0/scipy-1.16.2-cp314-cp314-macosx_10_14_x86_64.whl", hash = "sha256:567e77755019bb7461513c87f02bb73fb65b11f049aaaa8ca17cfaa5a5c45d77", size = 36595109, upload-time = "2025-09-11T17:43:35.713Z" }, - { url = "https://files.pythonhosted.org/packages/ff/f6/5779049ed119c5b503b0f3dc6d6f3f68eefc3a9190d4ad4c276f854f051b/scipy-1.16.2-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:17d9bb346194e8967296621208fcdfd39b55498ef7d2f376884d5ac47cec1a70", size = 28859110, upload-time = "2025-09-11T17:43:40.814Z" }, - { url = "https://files.pythonhosted.org/packages/82/09/9986e410ae38bf0a0c737ff8189ac81a93b8e42349aac009891c054403d7/scipy-1.16.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:0a17541827a9b78b777d33b623a6dcfe2ef4a25806204d08ead0768f4e529a88", size = 20850110, upload-time = "2025-09-11T17:43:44.981Z" }, - { url = "https://files.pythonhosted.org/packages/0d/ad/485cdef2d9215e2a7df6d61b81d2ac073dfacf6ae24b9ae87274c4e936ae/scipy-1.16.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:d7d4c6ba016ffc0f9568d012f5f1eb77ddd99412aea121e6fa8b4c3b7cbad91f", size = 23497014, upload-time = "2025-09-11T17:43:49.074Z" }, - { url = "https://files.pythonhosted.org/packages/a7/74/f6a852e5d581122b8f0f831f1d1e32fb8987776ed3658e95c377d308ed86/scipy-1.16.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9702c4c023227785c779cba2e1d6f7635dbb5b2e0936cdd3a4ecb98d78fd41eb", size = 33401155, upload-time = "2025-09-11T17:43:54.661Z" }, - { url = "https://files.pythonhosted.org/packages/d9/f5/61d243bbc7c6e5e4e13dde9887e84a5cbe9e0f75fd09843044af1590844e/scipy-1.16.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d1cdf0ac28948d225decdefcc45ad7dd91716c29ab56ef32f8e0d50657dffcc7", size = 35691174, upload-time = "2025-09-11T17:44:00.101Z" }, - { url = "https://files.pythonhosted.org/packages/03/99/59933956331f8cc57e406cdb7a483906c74706b156998f322913e789c7e1/scipy-1.16.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:70327d6aa572a17c2941cdfb20673f82e536e91850a2e4cb0c5b858b690e1548", size = 36070752, upload-time = "2025-09-11T17:44:05.619Z" }, - { url = "https://files.pythonhosted.org/packages/c6/7d/00f825cfb47ee19ef74ecf01244b43e95eae74e7e0ff796026ea7cd98456/scipy-1.16.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5221c0b2a4b58aa7c4ed0387d360fd90ee9086d383bb34d9f2789fafddc8a936", size = 38701010, upload-time = "2025-09-11T17:44:11.322Z" }, - { url = "https://files.pythonhosted.org/packages/e4/9f/b62587029980378304ba5a8563d376c96f40b1e133daacee76efdcae32de/scipy-1.16.2-cp314-cp314-win_amd64.whl", hash = "sha256:f5a85d7b2b708025af08f060a496dd261055b617d776fc05a1a1cc69e09fe9ff", size = 39360061, upload-time = "2025-09-11T17:45:09.814Z" }, - { url = "https://files.pythonhosted.org/packages/82/04/7a2f1609921352c7fbee0815811b5050582f67f19983096c4769867ca45f/scipy-1.16.2-cp314-cp314-win_arm64.whl", hash = "sha256:2cc73a33305b4b24556957d5857d6253ce1e2dcd67fa0ff46d87d1670b3e1e1d", size = 26126914, upload-time = "2025-09-11T17:45:14.73Z" }, - { url = "https://files.pythonhosted.org/packages/51/b9/60929ce350c16b221928725d2d1d7f86cf96b8bc07415547057d1196dc92/scipy-1.16.2-cp314-cp314t-macosx_10_14_x86_64.whl", hash = "sha256:9ea2a3fed83065d77367775d689401a703d0f697420719ee10c0780bcab594d8", size = 37013193, upload-time = "2025-09-11T17:44:16.757Z" }, - { url = "https://files.pythonhosted.org/packages/2a/41/ed80e67782d4bc5fc85a966bc356c601afddd175856ba7c7bb6d9490607e/scipy-1.16.2-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:7280d926f11ca945c3ef92ba960fa924e1465f8d07ce3a9923080363390624c4", size = 29390172, upload-time = "2025-09-11T17:44:21.783Z" }, - { url = "https://files.pythonhosted.org/packages/c4/a3/2f673ace4090452696ccded5f5f8efffb353b8f3628f823a110e0170b605/scipy-1.16.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:8afae1756f6a1fe04636407ef7dbece33d826a5d462b74f3d0eb82deabefd831", size = 21381326, upload-time = "2025-09-11T17:44:25.982Z" }, - { url = "https://files.pythonhosted.org/packages/42/bf/59df61c5d51395066c35836b78136accf506197617c8662e60ea209881e1/scipy-1.16.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:5c66511f29aa8d233388e7416a3f20d5cae7a2744d5cee2ecd38c081f4e861b3", size = 23915036, upload-time = "2025-09-11T17:44:30.527Z" }, - { url = "https://files.pythonhosted.org/packages/91/c3/edc7b300dc16847ad3672f1a6f3f7c5d13522b21b84b81c265f4f2760d4a/scipy-1.16.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:efe6305aeaa0e96b0ccca5ff647a43737d9a092064a3894e46c414db84bc54ac", size = 33484341, upload-time = "2025-09-11T17:44:35.981Z" }, - { url = "https://files.pythonhosted.org/packages/26/c7/24d1524e72f06ff141e8d04b833c20db3021020563272ccb1b83860082a9/scipy-1.16.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7f3a337d9ae06a1e8d655ee9d8ecb835ea5ddcdcbd8d23012afa055ab014f374", size = 35790840, upload-time = "2025-09-11T17:44:41.76Z" }, - { url = "https://files.pythonhosted.org/packages/aa/b7/5aaad984eeedd56858dc33d75efa59e8ce798d918e1033ef62d2708f2c3d/scipy-1.16.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bab3605795d269067d8ce78a910220262711b753de8913d3deeaedb5dded3bb6", size = 36174716, upload-time = "2025-09-11T17:44:47.316Z" }, - { url = "https://files.pythonhosted.org/packages/fd/c2/e276a237acb09824822b0ada11b028ed4067fdc367a946730979feacb870/scipy-1.16.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b0348d8ddb55be2a844c518cd8cc8deeeb8aeba707cf834db5758fc89b476a2c", size = 38790088, upload-time = "2025-09-11T17:44:53.011Z" }, - { url = "https://files.pythonhosted.org/packages/c6/b4/5c18a766e8353015439f3780f5fc473f36f9762edc1a2e45da3ff5a31b21/scipy-1.16.2-cp314-cp314t-win_amd64.whl", hash = "sha256:26284797e38b8a75e14ea6631d29bda11e76ceaa6ddb6fdebbfe4c4d90faf2f9", size = 39457455, upload-time = "2025-09-11T17:44:58.899Z" }, - { url = "https://files.pythonhosted.org/packages/97/30/2f9a5243008f76dfc5dee9a53dfb939d9b31e16ce4bd4f2e628bfc5d89d2/scipy-1.16.2-cp314-cp314t-win_arm64.whl", hash = "sha256:d2a4472c231328d4de38d5f1f68fdd6d28a615138f842580a8a321b5845cf779", size = 26448374, upload-time = "2025-09-11T17:45:03.45Z" }, + { url = "https://files.pythonhosted.org/packages/05/52/9c0136c2de7ae0779b7b366447766cec6d9f0702c56bb8ffeb04c8fd3af4/scipy-1.18.0-cp313-cp313-macosx_10_15_x86_64.whl", hash = "sha256:09143f676d157d9f546d663504ef9c1becb819824f1afc018814176411942446", size = 31036107, upload-time = "2026-06-19T15:00:14.03Z" }, + { url = "https://files.pythonhosted.org/packages/02/73/0291a64843270f4efb86cdcf2ee0f2048631b65ec6b405398b2b4dbf11bf/scipy-1.18.0-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:5efe260f69417b97ddae455bfb5a95e8359f7f66ad7fa9522a60feb66f169520", size = 28663303, upload-time = "2026-06-19T15:00:16.819Z" }, + { url = "https://files.pythonhosted.org/packages/d3/0f/10ffa0b697a572f4e0d48b92a88895d366422f019f723e7e14a84c050dac/scipy-1.18.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:68363b7eaacd8b5dd426df56d782cc156468ac79a127a1b87ca597d6e2e82197", size = 20404960, upload-time = "2026-06-19T15:00:19.635Z" }, + { url = "https://files.pythonhosted.org/packages/7e/d2/e896cea21ba8edd6c81d4c55b1ffcc717e79698dcbebf9641b4cfb4c6622/scipy-1.18.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:c5557d8be5da8e41353fcd4d21491fdbab83b062fc579e94dc09a7c8ab4f669b", size = 23034074, upload-time = "2026-06-19T15:00:22.107Z" }, + { url = "https://files.pythonhosted.org/packages/ea/b2/e83ea34279a52c03374477c74006256ec78df65fc877baa4617d6de1d202/scipy-1.18.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0d13bca67c096d89fb95ced0d8921807300fce0275643aef9533cc63a0773468", size = 33942038, upload-time = "2026-06-19T15:00:24.964Z" }, + { url = "https://files.pythonhosted.org/packages/f6/af/e8fe5fb136f51e2b01678b92cb4106d10d8cd68ec147ead2e7cb0ac75398/scipy-1.18.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a46f9273dbd0eb1cefba61c9b8648b4dfe3cbc14a080176f9a73e44b8336dc7f", size = 35266390, upload-time = "2026-06-19T15:00:28.059Z" }, + { url = "https://files.pythonhosted.org/packages/3a/49/2c5cbb907b56695fc67517811d1db234dfd83381a84814ec220aded2794d/scipy-1.18.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5aba46108853ddfc77906b6557aac839d2b52e900c1d72a1180adaaab58d265f", size = 35551324, upload-time = "2026-06-19T15:00:31.014Z" }, + { url = "https://files.pythonhosted.org/packages/bb/73/eda39f7a2d306ff0ffc574afd13c0bbb6d10a603d9a413998ee269487a80/scipy-1.18.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b6f758e35f12757b5d95c00bc6de2438e229c2664b7a92e96f205959d9f2dfa4", size = 37404785, upload-time = "2026-06-19T15:00:34.072Z" }, + { url = "https://files.pythonhosted.org/packages/b7/d2/ae881ee28d014f38e0ccbfd974a06a919ba9af34f1f74bf42b5301891d63/scipy-1.18.0-cp313-cp313-win_amd64.whl", hash = "sha256:1afac4a847207c7ff8efd321734a50b06d0280b3b2a2c0fc2f413101747ad7c7", size = 36554943, upload-time = "2026-06-19T15:00:36.903Z" }, + { url = "https://files.pythonhosted.org/packages/70/3a/21154e2d54eb3639c6bf4dbae2e531c68356bfe95990daa30df33b30d556/scipy-1.18.0-cp313-cp313-win_arm64.whl", hash = "sha256:c5dbddf60e58c2312316d097271a8e73d40eaf2eabfa4d95ed7d3695bbf2ce7b", size = 24350911, upload-time = "2026-06-19T15:00:40.062Z" }, + { url = "https://files.pythonhosted.org/packages/78/b5/915a19b3de2f7430062b509653563db1633ddbb6f021b06731521115d4e2/scipy-1.18.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:4c256ee70c0d1a8a2ace807e199ccd4e3f57037433842abb3fb36bc17eaa9578", size = 31036253, upload-time = "2026-06-19T15:00:43.216Z" }, + { url = "https://files.pythonhosted.org/packages/d7/88/b72def7262e150d16be13fca37a96481138d624e700340bc3362a7588929/scipy-1.18.0-cp314-cp314-macosx_12_0_arm64.whl", hash = "sha256:2ef3abc54a4ffc53765374b0d5728532dfdd2585ed23f6b11c206a1f0b1b9af8", size = 28673758, upload-time = "2026-06-19T15:00:46.663Z" }, + { url = "https://files.pythonhosted.org/packages/91/02/2e636a61a525632c373cf6a9c24442a3ffb79e364d38e98b32042964ac32/scipy-1.18.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:f2a6af57bd9e4a75d70e4117e78a1bbee84f79ae3fbb6d0111005d6ebcc4cb8d", size = 20415514, upload-time = "2026-06-19T15:00:49.399Z" }, + { url = "https://files.pythonhosted.org/packages/c9/b6/2135974442f6aba159d9d39d774a1c8cb19947016725d69fecc685df45bf/scipy-1.18.0-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:3f1ac564d3bf6c03d861d2cd87a1bea0da2887136f7fb1bf519c05a8971452d6", size = 23034398, upload-time = "2026-06-19T15:00:51.941Z" }, + { url = "https://files.pythonhosted.org/packages/f6/e6/ba89ec5abf6ee9257c0d1ec985573f3ae32742c24bc03e016388a40b1b15/scipy-1.18.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40395a5fcd1abee49a5c7aaa98c29db393eedc835138560a588c47ec16156690", size = 33998032, upload-time = "2026-06-19T15:00:54.838Z" }, + { url = "https://files.pythonhosted.org/packages/7f/c4/bc41eb19b0fd0db868f4132920879019318d80cc522ad8f2bca4611af808/scipy-1.18.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8ca01e8ae69f1b18e9a58d91afead31be3cef0dd905a10249dac559ee15460a0", size = 35283333, upload-time = "2026-06-19T15:00:58.152Z" }, + { url = "https://files.pythonhosted.org/packages/53/a4/cbdeef6eb3830a8462a9d4ada814de5fc984345cc9ecf17cbec51a036f1e/scipy-1.18.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7a7f3b01647384dbc3a711e8c6778e0aabbe93959249fef5c7393396bcac0867", size = 35610216, upload-time = "2026-06-19T15:01:01.155Z" }, + { url = "https://files.pythonhosted.org/packages/80/4d/b2b82502b65f661d1b789c1665dcdf315d5f12194e06fc0b37946294ebae/scipy-1.18.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6aa94e78ec192a30063a5e72e561c28af769dc311190b24fe91774eff1969709", size = 37418960, upload-time = "2026-06-19T15:01:04.155Z" }, + { url = "https://files.pythonhosted.org/packages/93/3e/902d836831474b0ab5a37d16404f7bc5fafd9efba632890e271ba952635f/scipy-1.18.0-cp314-cp314-win_amd64.whl", hash = "sha256:2d8bbdc6c817f5b4006a54d799d4f5bab6f910193cbb9a1ff310833d4d270f61", size = 37288845, upload-time = "2026-06-19T15:01:07.822Z" }, + { url = "https://files.pythonhosted.org/packages/b6/43/8d73b337a3bdb14daa0314f0434210747c02d79d729ce1777574a817dcf6/scipy-1.18.0-cp314-cp314-win_arm64.whl", hash = "sha256:18e9575f1569b2c54174e6159d32942e03731177f63dce7975f0a0c88d102f5b", size = 24988971, upload-time = "2026-06-19T15:01:11.076Z" }, + { url = "https://files.pythonhosted.org/packages/b4/b4/f11918b0508a2787031a0499a03fbe3546f3bb5ca05d01038c45b278c09a/scipy-1.18.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:f351e0dd702687d12a402b867a1b4146a256923e1c38317cbc472f6372b94707", size = 31399325, upload-time = "2026-06-19T15:01:13.723Z" }, + { url = "https://files.pythonhosted.org/packages/7b/d1/1f287b57c0ff0ee5185dff3946d92c8017d39b0e431f0ae79a3ff1859512/scipy-1.18.0-cp314-cp314t-macosx_12_0_arm64.whl", hash = "sha256:7c7a51b33ce387193c97f228320cf8e87361daa1bba750638677729598b3e677", size = 29092110, upload-time = "2026-06-19T15:01:16.908Z" }, + { url = "https://files.pythonhosted.org/packages/ff/1a/7b74eb6c392fdcb27d414c0e7558a6d0231eb3b6d73571f479bb81ea8794/scipy-1.18.0-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:84031d7b052a54fae2f8632e0ec802073d385476eb9a63079bce6e23ef9283d4", size = 20833811, upload-time = "2026-06-19T15:01:20.488Z" }, + { url = "https://files.pythonhosted.org/packages/7c/ad/f3941716320a7b9cb4d68734a903b45fe16eff5fb7da7e16f2e619304979/scipy-1.18.0-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:56abf29a7c067dde59be8b9a22d606a4ea1b2f2a4b756d9d903c62818f5dacce", size = 23396644, upload-time = "2026-06-19T15:01:23.364Z" }, + { url = "https://files.pythonhosted.org/packages/22/22/1446b62ffe07f9719b7d9b1b6a4e05a772833ae8f441fe4c22c34c9b250f/scipy-1.18.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1ad44305cfa24b1ba5803cbbebf033590ccbac1aa5d612d727b785325ab408b0", size = 34079318, upload-time = "2026-06-19T15:01:26.002Z" }, + { url = "https://files.pythonhosted.org/packages/56/3b/b87da667098bb470fa30c7011b0ba351ee976dd395c78798c66e941665a3/scipy-1.18.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:945c1761b93f38d7f99ae81ae80c63e621471608c7eeead563f6df025585cd58", size = 35324320, upload-time = "2026-06-19T15:01:28.881Z" }, + { url = "https://files.pythonhosted.org/packages/f8/a1/c7932f91909759b0267f75fdea34e91309f96b895757534b76a90b6b4344/scipy-1.18.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1a4441f15d620578772a49e5ab48c0ee1f7a0220e387110283062729136b2553", size = 35699541, upload-time = "2026-06-19T15:01:31.968Z" }, + { url = "https://files.pythonhosted.org/packages/f7/86/5185061a1fcc41d18c5dc2463969b3a3964b31d9ac67b2fb05d4c7ff7670/scipy-1.18.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9aac6192fac56bf2ca534389d24623f07b39ff83317d58287285e7fbd622ff76", size = 37472480, upload-time = "2026-06-19T15:01:35.136Z" }, + { url = "https://files.pythonhosted.org/packages/31/8e/f04c68e39919a010d34f2ee1367fd705b0a25a02f609d755f0bfbc0a15fc/scipy-1.18.0-cp314-cp314t-win_amd64.whl", hash = "sha256:e40baea28ae7f5475c779741e2d90b1247c78531207b49c7030e698ff81cee3f", size = 37365390, upload-time = "2026-06-19T15:01:38.091Z" }, + { url = "https://files.pythonhosted.org/packages/d5/19/969dc072906c84dd0a3b05dcf57ea750936087d7873549e408b35cfc3f97/scipy-1.18.0-cp314-cp314t-win_arm64.whl", hash = "sha256:368e0a705903c466aa5f08eefb39e6b1b6b2d659e7352a31fd9e2438365be0f8", size = 25279661, upload-time = "2026-06-19T15:01:40.817Z" }, ] [[package]] @@ -698,11 +780,36 @@ wheels = [ [[package]] name = "tzdata" -version = "2025.2" +version = "2026.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/95/32/1a225d6164441be760d75c2c42e2780dc0873fe382da3e98a2e1e48361e5/tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9", size = 196380, upload-time = "2025-03-23T13:54:43.652Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/19/1b9b0e29f30c6d35cb345486df41110984ea67ae69dddbc0e8a100999493/tzdata-2026.2.tar.gz", hash = "sha256:9173fde7d80d9018e02a662e168e5a2d04f87c41ea174b139fbef642eda62d10", size = 198254, upload-time = "2026-04-24T15:22:08.651Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/e4/dccd7f47c4b64213ac01ef921a1337ee6e30e8c6466046018326977efd95/tzdata-2026.2-py2.py3-none-any.whl", hash = "sha256:bbe9af844f658da81a5f95019480da3a89415801f6cc966806612cc7169bffe7", size = 349321, upload-time = "2026-04-24T15:22:05.876Z" }, +] + +[[package]] +name = "unopy" +version = "0.4.11" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f4/2c/e7a1afe7462d6116043ec8f254bb2c4d664a741f339032805c5089509130/unopy-0.4.11.tar.gz", hash = "sha256:af324c7b5d8121acd830aa4b88d1412ab3875dcb2feff2536baa7a1c1abb9037", size = 2224914, upload-time = "2026-06-24T13:29:50.807Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/23/c7abc0ca0a1526a0774eca151daeb8de62ec457e77262b66b359c3c7679e/tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8", size = 347839, upload-time = "2025-03-23T13:54:41.845Z" }, + { url = "https://files.pythonhosted.org/packages/bb/c0/0158abed9033e4cab69a2ec2efb326f7b7907df70c4247005924dda6b8e8/unopy-0.4.11-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:912cc5cbc791ec2b2171fc204b51bf9c27d35c1dc18f58a7e72847dd698a093d", size = 5188812, upload-time = "2026-06-24T13:29:15.311Z" }, + { url = "https://files.pythonhosted.org/packages/ed/75/2694c01a44ce597cdea5dddfd9486b1b282b9a85cdea7b84f6e74ebd134f/unopy-0.4.11-cp313-cp313-macosx_15_0_x86_64.whl", hash = "sha256:b196f88e6055e851448280ceb5ea3586f17e28b44dec53456046eea254b24075", size = 6161773, upload-time = "2026-06-24T13:29:17.141Z" }, + { url = "https://files.pythonhosted.org/packages/d6/3d/fd49c4fd3e7bf098f1e9beb941261ce9451e6eb6ec3df04d36e9b6e7dc03/unopy-0.4.11-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:70b20609e124f5f71aa6e1d97e1ee1d89049fe91be6b317a1c75e12fc036747c", size = 5186191, upload-time = "2026-06-24T13:29:19.102Z" }, + { url = "https://files.pythonhosted.org/packages/f5/34/0d345816053c2aa77ad00a6442e88ca847c14fc7f8d9de552c4da48e64e8/unopy-0.4.11-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b4236aa673f029e27d4ea2dac2661265bc342b99453fe506887848470d349075", size = 6076399, upload-time = "2026-06-24T13:29:20.915Z" }, + { url = "https://files.pythonhosted.org/packages/8e/ac/4648acfed49c875bbb16523db04065aafdc3331fe1ab026578c4604d3c00/unopy-0.4.11-cp313-cp313-win_amd64.whl", hash = "sha256:767fb813a4d2aced04b51576f2d9192951884de5c44c79b1e281fbe4f17daea8", size = 7429295, upload-time = "2026-06-24T13:29:22.723Z" }, + { url = "https://files.pythonhosted.org/packages/4b/81/bdb324bfc339b1b4b10ca9d807c1e5e4409c79131887e491f5a2562b3c2f/unopy-0.4.11-cp314-cp314-macosx_15_0_arm64.whl", hash = "sha256:4081c578891ffdf8bccbc91377d191183cbf22b3a5c6ea3f529d70406890166b", size = 5189394, upload-time = "2026-06-24T13:29:24.744Z" }, + { url = "https://files.pythonhosted.org/packages/ba/10/4d786d2d5dfb40faa23b8c490f78e70876d7b13cbd79a21ddf8d65b795f0/unopy-0.4.11-cp314-cp314-macosx_15_0_x86_64.whl", hash = "sha256:5a77dbba22d92bded26a4d85332fc9a3772aba1f1ba9c8fde89fc663804f9509", size = 6162324, upload-time = "2026-06-24T13:29:26.555Z" }, + { url = "https://files.pythonhosted.org/packages/49/f0/1f33b67d0c17da3d1b3c1739afe3a0894226a2765a42fd8df32b311cb10d/unopy-0.4.11-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:09c38481453723369cbe6fa80b4f0a04a4b1e98ac76e1ef630ac166e18f103c4", size = 5186394, upload-time = "2026-06-24T13:29:28.41Z" }, + { url = "https://files.pythonhosted.org/packages/31/f3/539c82a0d97e556b6892e918b2d23d5cdd6759575e19b96f534e493c67e6/unopy-0.4.11-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5ddff2ccf9a14833865ffbd38dc2885c81219a242aadeac9daf1b7ef8424f9d1", size = 6076601, upload-time = "2026-06-24T13:29:30.139Z" }, + { url = "https://files.pythonhosted.org/packages/71/d7/b2ab0ffb136e486e7c916f5561693100a23f48869f946224615309141a4e/unopy-0.4.11-cp314-cp314-win_amd64.whl", hash = "sha256:f58a768835de2359014efc98ae682ec0c17eaa9aafc8cff99e6397f4d467d538", size = 7645181, upload-time = "2026-06-24T13:29:32.18Z" }, + { url = "https://files.pythonhosted.org/packages/01/06/2e014de4a154d6f1af29ab9ed1dc13fadd6923d2044fb0ef5fa045db120e/unopy-0.4.11-cp314-cp314t-macosx_15_0_arm64.whl", hash = "sha256:8f6fe7ab1d46cddb6455f807fad214fe7c78ef3f190b31ca3ef1c78d1765906d", size = 5198121, upload-time = "2026-06-24T13:29:33.99Z" }, + { url = "https://files.pythonhosted.org/packages/78/b3/8feb06260654bd96038243efac21f2294d41bb0c576dcd0d41d14fb0044f/unopy-0.4.11-cp314-cp314t-macosx_15_0_x86_64.whl", hash = "sha256:886d3133f8bc29d52b67e195f76629de1699011753daab220f12684b6ae33878", size = 6175435, upload-time = "2026-06-24T13:29:35.929Z" }, + { url = "https://files.pythonhosted.org/packages/be/6c/115c5c24031e5b6926fd3008fba3c9d6dca018dbd982039ea2d88e36b6fa/unopy-0.4.11-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bfab0099207578eae27617136dfdbc8e4c5decbbcc2c806bd5622e7eb72fb257", size = 5189122, upload-time = "2026-06-24T13:29:37.893Z" }, + { url = "https://files.pythonhosted.org/packages/4e/41/beb6fa1ec2c571ddf1e15a6ecf5b655af554587f1c09529ae145531c3531/unopy-0.4.11-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee7f3792936d274191363bc5266364a4a20cab6e01089865b9fa3e9fad060a3e", size = 6080599, upload-time = "2026-06-24T13:29:40.119Z" }, ] [[package]]