From 608c6cc156471175dba6df3711da028dd5f0903d Mon Sep 17 00:00:00 2001 From: Thomas Wutzler Date: Wed, 25 Mar 2026 11:06:36 +0000 Subject: [PATCH 01/31] let PBM return a tuple of observations and additional quantities. --- docs/src/tutorials/basic_cpu.md | 14 ++++-- docs/src/tutorials/basic_cpu.qmd | 14 ++++-- docs/src/tutorials/blocks_corr.md | 8 ++-- docs/src/tutorials/blocks_corr.qmd | 8 ++-- docs/src/tutorials/corr_site_global.md | 8 ++-- docs/src/tutorials/corr_site_global.qmd | 8 ++-- .../intermediate/basic_cpu_results.jld2 | Bin 193191 -> 193191 bytes docs/src/tutorials/logden_user.md | 8 ++-- docs/src/tutorials/logden_user.qmd | 8 ++-- docs/src/tutorials/lux_gpu.md | 6 +-- docs/src/tutorials/lux_gpu.qmd | 4 +- src/DoubleMM/f_doubleMM.jl | 14 ++++-- src/PBMApplicator.jl | 45 +++++++++++------- src/elbo.jl | 8 ++-- src/gf.jl | 10 ++-- test/test_HybridProblem.jl | 8 ++-- test/test_doubleMM.jl | 14 +++--- test/test_elbo.jl | 2 +- 18 files changed, 108 insertions(+), 79 deletions(-) diff --git a/docs/src/tutorials/basic_cpu.md b/docs/src/tutorials/basic_cpu.md index 18d8b38..32b37ee 100644 --- a/docs/src/tutorials/basic_cpu.md +++ b/docs/src/tutorials/basic_cpu.md @@ -35,7 +35,8 @@ $$ function f_doubleMM(θc::CA.ComponentVector{ET}, x) where ET # extract parameters not depending on order, i.e whether they are in θP or θM @unpack r0, r1, K1, K2 = θc - r0 .+ r1 .* x.S1 ./ (K1 .+ x.S1) .* x.S2 ./ (K2 .+ x.S2) + y = r0 .+ r1 .* x.S1 ./ (K1 .+ x.S1) .* x.S2 ./ (K2 .+ x.S2) + (y, y[1:0]) end ``` @@ -44,6 +45,10 @@ or fixed during the model inversion. However, it cannot assume an ordering in the parameters, but needs to access the components by its symbolic names in the provided `ComponentArray`. +In addtion to the predictions, the PBM returns additional quantities that may +be used in penalizing unrealistic conditions independent of observations. +In this simple example, just an empty vector is returned. + ## Likelihood function HVI requires the evaluation of the likelihood of the predictions. @@ -311,7 +316,8 @@ function f_doubleMM_sites(θc_tr::CA.ComponentMatrix, xPc::CA.ComponentMatrix) K1 = is_valid .* CA.getdata(θc_tr[:, Val(:K1)])' K2 = is_valid .* CA.getdata(θc_tr[:, Val(:K2)])' # each variable is a matrix (n_obs x n_site) - r0 .+ r1 .* S1 ./ (K1 .+ S1) .* S2 ./ (K2 .+ S2) + y = r0 .+ r1 .* S1 ./ (K1 .+ S1) .* S2 ./ (K2 .+ S2) + (y, y[1:0,:]) end ``` @@ -347,8 +353,8 @@ in the following [Inspect results of fitted problem](@ref) tutorial. In order to use the results from this tutorial in other tutorials, the updated `probo` `HybridProblem` and the interpreters are saved to a JLD2 file. -Before the problem is updated, so that it uses the redefinition [`DoubleMM.f_doubleMM_sites`](@ref) -of the PBM in module `DoubleMM` rather than +Before the problem is updated, it uses the redefinition [`DoubleMM.f_doubleMM_sites`](@ref) +of the PBM in module `DoubleMM` rather than what we defined in module `Main` to allow for easier reloading with JLD2. ``` julia diff --git a/docs/src/tutorials/basic_cpu.qmd b/docs/src/tutorials/basic_cpu.qmd index 86def5c..b9ad1e0 100644 --- a/docs/src/tutorials/basic_cpu.qmd +++ b/docs/src/tutorials/basic_cpu.qmd @@ -46,7 +46,8 @@ $$ function f_doubleMM(θc::CA.ComponentVector{ET}, x) where ET # extract parameters not depending on order, i.e whether they are in θP or θM @unpack r0, r1, K1, K2 = θc - r0 .+ r1 .* x.S1 ./ (K1 .+ x.S1) .* x.S2 ./ (K2 .+ x.S2) + y = r0 .+ r1 .* x.S1 ./ (K1 .+ x.S1) .* x.S2 ./ (K2 .+ x.S2) + (y, y[1:0]) end ``` @@ -55,6 +56,10 @@ or fixed during the model inversion. However, it cannot assume an ordering in the parameters, but needs to access the components by its symbolic names in the provided `ComponentArray`. +In addtion to the predictions, the PBM returns additional quantities that may +be used in penalizing unrealistic conditions independent of observations. +In this simple example, just an empty vector is returned. + ## Likelihood function HVI requires the evaluation of the likelihood of the predictions. @@ -349,7 +354,8 @@ function f_doubleMM_sites(θc_tr::CA.ComponentMatrix, xPc::CA.ComponentMatrix) K1 = is_valid .* CA.getdata(θc_tr[:, Val(:K1)])' K2 = is_valid .* CA.getdata(θc_tr[:, Val(:K2)])' # each variable is a matrix (n_obs x n_site) - r0 .+ r1 .* S1 ./ (K1 .+ S1) .* S2 ./ (K2 .+ S2) + y = r0 .+ r1 .* S1 ./ (K1 .+ S1) .* S2 ./ (K2 .+ S2) + (y, y[1:0,:]) end ``` @@ -384,8 +390,8 @@ in the following [Inspect results of fitted problem](@ref) tutorial. In order to use the results from this tutorial in other tutorials, the updated `probo` `HybridProblem` and the interpreters are saved to a JLD2 file. -Before the problem is updated, so that it uses the redefinition [`DoubleMM.f_doubleMM_sites`](@ref) -of the PBM in module `DoubleMM` rather than +Before the problem is updated, it uses the redefinition [`DoubleMM.f_doubleMM_sites`](@ref) +of the PBM in module `DoubleMM` rather than what we defined in module `Main` to allow for easier reloading with JLD2. ```{julia} diff --git a/docs/src/tutorials/blocks_corr.md b/docs/src/tutorials/blocks_corr.md index 75459aa..6d54ad6 100644 --- a/docs/src/tutorials/blocks_corr.md +++ b/docs/src/tutorials/blocks_corr.md @@ -106,10 +106,10 @@ First, draw a sample. ``` julia n_sample_pred = 400 -(y_cor, θsP_cor, θsMs_tr_cor) = (; y, θsP, θsMs_tr) = predict_hvi( - Random.default_rng(), probo_cor; n_sample_pred) -(y_ind, θsP_ind, θsMs_tr_ind) = (; y, θsP, θsMs_tr) = predict_hvi( - Random.default_rng(), probo_ind; n_sample_pred) +(; y, θsP, θsMs_tr) = predict_hvi(Random.default_rng(), probo_cor; n_sample_pred) +(y_cor, θsP_cor, θsMs_tr_cor) = (y, θsP, θsMs_tr) +(; y, θsP, θsMs_tr) = predict_hvi(Random.default_rng(), probo_ind; n_sample_pred) +(y_ind, θsP_ind, θsMs_tr_ind) = (y, θsP, θsMs_tr) ``` ``` julia diff --git a/docs/src/tutorials/blocks_corr.qmd b/docs/src/tutorials/blocks_corr.qmd index e5f2c71..e18a200 100644 --- a/docs/src/tutorials/blocks_corr.qmd +++ b/docs/src/tutorials/blocks_corr.qmd @@ -109,10 +109,10 @@ solver = HybridPosteriorSolver(; alg=Adam(0.02), n_MC=3) First, draw a sample. ```{julia} n_sample_pred = 400 -(y_cor, θsP_cor, θsMs_tr_cor) = (; y, θsP, θsMs_tr) = predict_hvi( - Random.default_rng(), probo_cor; n_sample_pred) -(y_ind, θsP_ind, θsMs_tr_ind) = (; y, θsP, θsMs_tr) = predict_hvi( - Random.default_rng(), probo_ind; n_sample_pred) +(; y, θsP, θsMs_tr) = predict_hvi(Random.default_rng(), probo_cor; n_sample_pred) +(y_cor, θsP_cor, θsMs_tr_cor) = (y, θsP, θsMs_tr) +(; y, θsP, θsMs_tr) = predict_hvi(Random.default_rng(), probo_ind; n_sample_pred) +(y_ind, θsP_ind, θsMs_tr_ind) = (y, θsP, θsMs_tr) ``` ```{julia} diff --git a/docs/src/tutorials/corr_site_global.md b/docs/src/tutorials/corr_site_global.md index 2bc5aed..223f1d7 100644 --- a/docs/src/tutorials/corr_site_global.md +++ b/docs/src/tutorials/corr_site_global.md @@ -114,10 +114,10 @@ First, draw a sample. ``` julia n_sample_pred = 400 -(y_cond, θsP_cond, θsMs_cond) = (; y, θsP, θsMs_tr) = predict_hvi( - Random.default_rng(), probo_cond; n_sample_pred) -(y_uncond, θsP_uncond, θsMs_uncond) = (; y, θsP, θsMs_tr) = predict_hvi( - Random.default_rng(), probo_uncond; n_sample_pred) +(; y, θsP, θsMs_tr) = predict_hvi(Random.default_rng(), probo_cond; n_sample_pred) +(y_cond, θsP_cond, θsMs_cond) = (y, θsP, θsMs_tr) +(; y, θsP, θsMs_tr) = predict_hvi(Random.default_rng(), probo_uncond; n_sample_pred) +(y_uncond, θsP_uncond, θsMs_uncond) = (y, θsP, θsMs_tr) ``` ``` julia diff --git a/docs/src/tutorials/corr_site_global.qmd b/docs/src/tutorials/corr_site_global.qmd index 774bbd0..19246cf 100644 --- a/docs/src/tutorials/corr_site_global.qmd +++ b/docs/src/tutorials/corr_site_global.qmd @@ -123,10 +123,10 @@ solver = HybridPosteriorSolver(; alg=Adam(0.02), n_MC=3) First, draw a sample. ```{julia} n_sample_pred = 400 -(y_cond, θsP_cond, θsMs_cond) = (; y, θsP, θsMs_tr) = predict_hvi( - Random.default_rng(), probo_cond; n_sample_pred) -(y_uncond, θsP_uncond, θsMs_uncond) = (; y, θsP, θsMs_tr) = predict_hvi( - Random.default_rng(), probo_uncond; n_sample_pred) +(; y, θsP, θsMs_tr) = predict_hvi(Random.default_rng(), probo_cond; n_sample_pred) +(y_cond, θsP_cond, θsMs_cond) = (y, θsP, θsMs_tr) +(; y, θsP, θsMs_tr) = predict_hvi(Random.default_rng(), probo_uncond; n_sample_pred) +(y_uncond, θsP_uncond, θsMs_uncond) = (y, θsP, θsMs_tr) ``` ```{julia} diff --git a/docs/src/tutorials/intermediate/basic_cpu_results.jld2 b/docs/src/tutorials/intermediate/basic_cpu_results.jld2 index 3a838189f676ac06bfd94e578b19845d33083e1b..a7e804c1b023f9292a4c19fcf49803c33c384a99 100644 GIT binary patch delta 16369 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 cat(a,b; dims=3), + mapreduce((a,b) -> (cat(a[1],b[1]; dims=3), cat(a[2],b[2]; dims=3)), eachcol(CA.getdata(θsP)[:,2:end]), eachslice(CA.getdata(θsMs_tr)[:,:,2:end], dims=3); - init=y1a) do θP, θMs + init=(y1a, add1a)) do θP, θMs app(θP, θMs, xP) end end - return(y_pred) + return(y_pred_and_add) end @@ -96,7 +102,7 @@ Process-Base-Model applicator that returns its θMs inputs. Used for testing. struct NullPBMApplicator <: AbstractPBMApplicator end function apply_model(app::NullPBMApplicator, θP::AbstractVector, θMs_tr::AbstractMatrix, xP) - return CA.getdata(θMs_tr) + return CA.getdata(θMs_tr), CA.getdata(θMs_tr) end create_nsite_applicator(app::NullPBMApplicator, n_site) = app @@ -130,7 +136,7 @@ end PBMSiteApplicator(fθ; θP, θM, θFix, xPvec) Construct AbstractPBMApplicator from process-based model `fθ` that computes predictions -for a single site. +and addtional quantities for a single site. The Applicator combines enclosed `θFix`, with provided `θMs` and `θP` and constructs a `ComponentVector` that can be indexed by symbolic parameter names, corresponding to the templates provided during @@ -170,8 +176,8 @@ function apply_model(app::PBMSiteApplicator, θP::AbstractVector, θMs_tr::Abstr θ = vcat(CA.getdata(θP), CA.getdata(θM_tr), CA.getdata(app.θFix)) θc = app.intθ1(θ); # show errors without ";" xPc = app.int_xPsite(xP1); - ans = CA.getdata(app.fθ(θc, xPc)) - ans + ans = app.fθ(θc, xPc) + CA.getdata(ans[1]), CA.getdata(ans[2]) end # mapreduce-hcat is only typestable with init, which needs number of rows # https://discourse.julialang.org/t/type-instability-of-mapreduce-vs-map-reduce/121136 @@ -189,8 +195,11 @@ function apply_model(app::PBMSiteApplicator, θP::AbstractVector, θMs_tr::Abstr end xP1, it_xP = Iterators.peel(eachcol(CA.getdata(xP))) obs1 = apply_PBMsite(θMs1_tr, xP1) + init = (reshape(obs1[1], :,1),reshape(obs1[2], :, 1)) + hcat_2tuple = (a,b) -> (hcat(a[1], b[1]), hcat(a[2],b[2])) + #hcat_2tuple(init, init) local pred_sites = mapreduce( - apply_PBMsite, hcat, it_θMs_tr, it_xP; init=reshape(obs1, :, 1)) + apply_PBMsite, hcat_2tuple, it_θMs_tr, it_xP; init) return pred_sites end @@ -370,8 +379,8 @@ function apply_model(app::PBMPopulationGlobalApplicator, θP::AbstractVector, θ local θsc_tr = app.intθs(CA.getdata(θs_tr)) local θgc = app.intθg(CA.getdata(θg)) local xPc = app.int_xP(CA.getdata(xP)) - local pred_sites = app.fθpop(θsc_tr, θgc, xPc) - return pred_sites + local y_pred_and_add = app.fθpop(θsc_tr, θgc, xPc) + return y_pred_and_add end diff --git a/src/elbo.jl b/src/elbo.jl index 76d262c..72ab7d2 100644 --- a/src/elbo.jl +++ b/src/elbo.jl @@ -142,7 +142,7 @@ function neg_elbo_ζtf(ζsP, ζsMs_tr, σ, f, py, xP, y_ob, y_unc; f_sample = (ζP, ζMs_tr) -> begin θP, θMs_tr, logjac_i = transform_and_logjac_ζ(ζP, ζMs_tr; transP, transMs) # currently logpdf only works on CPU - y_pred_i = f(θP, θMs_tr, xP) + (y_pred_i, addq_pred_i) = f(θP, θMs_tr, xP) #nLy1 = neg_logden_indep_normal(y_ob, y_pred_i, y_unc) # Main.@infiltrate_main # Test.@inferred( f(θP, θMs, xP) ) @@ -304,6 +304,8 @@ Prediction function for hybrid variational inference parameter model. Returns an NamedTuple `(; y, θsP, θsMs_tr, entropy_ζ)` with entries - `y`: Array `(n_obs, n_site, n_sample_pred)` of model predictions. +- `addq`: Array `(n_addq, n_site, n_sample_pred)` of additional quantities computed + by the PBM. - `θsP`: ComponentArray `(n_θP, n_sample_pred)` of PBM model parameters that are kept constant across sites. - `θsMs_tr`: ComponentArray `(n_site, n_θM, n_sample_pred)` of PBM model parameters @@ -347,8 +349,8 @@ function predict_hvi(rng, prob::AbstractHybridProblem; scenario=Val(()), f_dev = f end #y = apply_process_model(θsP, θsMs_tr, f_dev, xP) - y = f_dev(θsP, θsMs_tr, xP) - (; y, θsP, θsMs_tr, entropy_ζ) + (y, addq) = f_dev(θsP, θsMs_tr, xP) + (; y, addq, θsP, θsMs_tr, entropy_ζ) end """ diff --git a/src/gf.jl b/src/gf.jl index a7f0b28..b9b0bba 100644 --- a/src/gf.jl +++ b/src/gf.jl @@ -85,11 +85,11 @@ function predict_point_hvi(rng, prob::AbstractHybridProblem; scenario=Val(()), xM = isnothing(xM) ? xM_dl : xM xP = isnothing(xP) ? xP_dl : xP end - y_pred, θMs_tr, θP = gf(prob, xM, xP; scenario, gdevs, is_testmode, kwargs...) + y_pred, addq_pred, θMs_tr, θP = gf(prob, xM, xP; scenario, gdevs, is_testmode, kwargs...) pt = get_hybridproblem_par_templates(prob) θPc = ComponentArrayInterpreter(pt.θP)(θP) θMsc = ComponentArrayInterpreter((size(θMs_tr,1),), pt.θM)(θMs_tr) - (;y_pred, θMs_tr=θMsc, θP=θPc) + (;y_pred, addq_pred, θMs_tr=θMsc, θP=θPc) end @@ -167,12 +167,12 @@ function gf(g::AbstractModelApplicator, transMs, transP, f, xM, xP, ϕg, ζP, # θP = transPM(CA.getdata(ζP)) θP = transP(CA.getdata(ζP)) θP_cpu = cdev(θP) - y_pred = f(θP_cpu, θMs_tr, xP) + y_pred, addq_pred = f(θP_cpu, θMs_tr, xP) # fM = RRuleMonitor("f in gf", (θP_cpu) -> f(θP_cpu, θMs_tr, xP), DI.AutoForwardDiff()) # y_pred = fM(θP_cpu) # fM = RRuleMonitor("f in gf", (θP_cpu, θMs_tr) -> f(θP_cpu, θMs_tr, xP)) # y_pred = fM(θP_cpu, θMs_tr) # very slow large JvP with θMs_tr - return y_pred, θMs_tr, θP_cpu + return y_pred, addq_pred, θMs_tr, θP_cpu end """ @@ -265,7 +265,7 @@ function get_loss_gf(g, transM, transP, f, py, @show ϕc.ϕP #Main.@infiltrate_main end - y_pred, θMs_tr_pred, θP_pred = gf( + y_pred, addq_pred, θMs_tr_pred, θP_pred = gf( g, transMs, transP, f, xM, xP, CA.getdata(ϕc.ϕg), CA.getdata(ϕc.ϕP), pbm_covar_indices; cdev, is_testmode, kwargs...) #σ = exp.(y_unc ./ 2) diff --git a/test/test_HybridProblem.jl b/test/test_HybridProblem.jl index 7e55e63..20843d2 100644 --- a/test/test_HybridProblem.jl +++ b/test/test_HybridProblem.jl @@ -44,7 +44,7 @@ function construct_problem(; scenario::Val{scen}) where scen CA.getdata(θc[par])::ET end local y = r0 .+ r1 .* x.S1 ./ (K1 .+ x.S1) .* x.S2 ./ (K2 .+ x.S2) - return (y) + return (y, y[1:0]) end n_out = length(θM) rng = StableRNG(111) @@ -263,7 +263,7 @@ test_with_flux = (scenario) -> begin @test θP.r0 < 1.5 * θPt.r0 @test exp(ϕ.ϕq.μP.K2) == θP.K2 < 1.5 * θP.K2 n_sample_pred = 12 - (; y, θsP, θsMs_tr, entropy_ζ) = predict_hvi(rng, probo; scenario, n_sample_pred); + (; y, addq, θsP, θsMs_tr, entropy_ζ) = predict_hvi(rng, probo; scenario, n_sample_pred); _,_,y_obs,_ = get_hybridproblem_train_dataloader(prob; scenario).data @test size(y) == (size(y_obs)..., n_sample_pred) yc = cdev(y) @@ -329,7 +329,7 @@ test_with_flux_gpu = (scenario) -> begin @test probo.ϕq == cdev(ϕ.ϕq) # predict using problem and its associated dataloader n_sample_pred = 201 - (; y, θsP, θsMs_tr) = predict_hvi(rng, probo; scenario = scenf, n_sample_pred); + (; y, addq, θsP, θsMs_tr) = predict_hvi(rng, probo; scenario = scenf, n_sample_pred); # to inspect correlations among θP and θMs_tr construct ComponentVector # TODO redo get_int_PMst_site # get_ca_int_PMs = let @@ -383,7 +383,7 @@ test_with_flux_gpu = (scenario) -> begin ); @test resopt.u isa GPUArraysCore.AbstractGPUVector n_sample_pred = 11 - (; y, θsP, θsMs_tr) = predict_hvi( + (; y, addq, θsP, θsMs_tr) = predict_hvi( rng, probo; scenario = scenf, n_sample_pred,is_inferred = Val(true)); # @test cdev(ϕ.ϕq.ρsM)[1] > 0 # too few iterations end; diff --git a/test/test_doubleMM.jl b/test/test_doubleMM.jl index 2684f05..3fbb079 100644 --- a/test/test_doubleMM.jl +++ b/test/test_doubleMM.jl @@ -78,25 +78,25 @@ end #y = CP.DoubleMM.f_doubleMM(θ, xPM, θpos) end end - y = @inferred fy(θvec, xPM) + (y, _addq) = @inferred fy(θvec, xPM) f_batch = PBMSiteApplicator(CP.DoubleMM.f_doubleMM; θP = θP_true, θM = θMs_true[:,1], θFix=CA.ComponentVector(), xPvec=xP[:,1]) - y_exp = f_batch(θP_true, θMs_true', xP) + (y_exp, _addq_exp) = f_batch(θP_true, θMs_true', xP) @test y == y_exp - ygrad = Zygote.gradient(θv -> sum(fy(θv, xPM)), θvec)[1] + ygrad = Zygote.gradient(θv -> sum(fy(θv, xPM)[1]), θvec)[1] if gdev isa MLDataDevices.AbstractGPUDevice # θg = gdev(θ) # xPMg = gdev(xPM) # yg = CP.DoubleMM.f_doubleMM(θg, xPMg, intθ); θvecg = gdev(θvec); # errors without ";" xPMg = CP.apply_preserve_axes(gdev, xPM); - yg = fy(θvecg, xPMg) - yg = @inferred fy(θvecg, xPMg); + #yg, _addg = fy(θvecg, xPMg) + yg, -addg = @inferred fy(θvecg, xPMg); #@usingany Cthulhu #@descend_code_warntype fy(θvecg, xPMg) @test cdev(yg) == y_exp - ygradg = Zygote.gradient(θv -> sum(fy(θv, xPMg)), θvecg)[1]; + ygradg = Zygote.gradient(θv -> sum(fy(θv, xPMg)[1]), θvecg)[1]; @test ygradg isa CA.ComponentArray @test CA.getdata(ygradg) isa GPUArraysCore.AbstractGPUArray ygradgc = CP.apply_preserve_axes(cdev, ygradg) # can print the cpu version @@ -117,7 +117,7 @@ end (θvec, xPM, y_o, y_unc) -> begin θ = hcat(CA.getdata(θvec.P[is]), CA.getdata(θvec.Ms')) θc = intθ(θ) - y = CP.DoubleMM.f_doubleMM_sites(θc, xPM) + y = CP.DoubleMM.f_doubleMM_sites(θc, xPM)[1] #y = CP.DoubleMM.f_doubleMM(θ, xPM, θpos) res = fneglogden(y_o, y, y_unc) res diff --git a/test/test_elbo.jl b/test/test_elbo.jl index c92ea3d..27e18a5 100644 --- a/test/test_elbo.jl +++ b/test/test_elbo.jl @@ -434,7 +434,7 @@ test_scenario = (scenario, approx) -> begin θsPc = int_mP(θsP) @test all(θsPc[:r0, :] .> 0) # - y = @inferred f_pred(θsP, θsMs_tr, xP) + (y, addq) = @inferred f_pred(θsP, θsMs_tr, xP) @test y isa Array @test size(y) == (size(y_o)..., n_sample_pred) end From 6e0ee397b1949006fe0f9f35bcc0113ad03c4fdd Mon Sep 17 00:00:00 2001 From: Thomas Wutzler Date: Thu, 26 Mar 2026 15:32:23 +0000 Subject: [PATCH 02/31] replace penalty_loss_function by callable AbstractPenaltyComputer --- docs/make.jl | 1 + docs/src/tutorials/basic_cpu.md | 2 +- docs/src/tutorials/basic_cpu.qmd | 2 +- .../intermediate/basic_cpu_results.jld2 | Bin 193191 -> 193465 bytes docs/src/tutorials/penalty.md | 139 ++++++++++++++++ docs/src/tutorials/penalty.qmd | 149 ++++++++++++++++++ src/AbstractHybridProblem.jl | 56 +++++++ src/DoubleMM/f_doubleMM.jl | 7 +- src/HybridProblem.jl | 16 +- src/HybridSolver.jl | 30 +++- src/HybridVariationalInference.jl | 7 +- src/PBMApplicator.jl | 2 +- src/elbo.jl | 43 ++--- src/gf.jl | 10 +- test/test_HybridProblem.jl | 4 + test/test_doubleMM.jl | 10 +- test/test_elbo.jl | 5 +- 17 files changed, 431 insertions(+), 52 deletions(-) create mode 100644 docs/src/tutorials/penalty.md create mode 100644 docs/src/tutorials/penalty.qmd diff --git a/docs/make.jl b/docs/make.jl index 9ff370c..02020f7 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -25,6 +25,7 @@ makedocs(; "How to" => [ ".. use GPU" => "tutorials/lux_gpu.md", ".. specify log-Likelihood" => "tutorials/logden_user.md", + ".. specify penalties" => "tutorials/penalties.md", ".. model independent parameters" => "tutorials/blocks_corr.md", ".. model site-global corr" => "tutorials/corr_site_global.md", ], diff --git a/docs/src/tutorials/basic_cpu.md b/docs/src/tutorials/basic_cpu.md index 32b37ee..d03e874 100644 --- a/docs/src/tutorials/basic_cpu.md +++ b/docs/src/tutorials/basic_cpu.md @@ -45,7 +45,7 @@ or fixed during the model inversion. However, it cannot assume an ordering in the parameters, but needs to access the components by its symbolic names in the provided `ComponentArray`. -In addtion to the predictions, the PBM returns additional quantities that may +In addition to the predictions, the PBM returns additional quantities that may be used in penalizing unrealistic conditions independent of observations. In this simple example, just an empty vector is returned. diff --git a/docs/src/tutorials/basic_cpu.qmd b/docs/src/tutorials/basic_cpu.qmd index b9ad1e0..5d385f3 100644 --- a/docs/src/tutorials/basic_cpu.qmd +++ b/docs/src/tutorials/basic_cpu.qmd @@ -56,7 +56,7 @@ or fixed during the model inversion. However, it cannot assume an ordering in the parameters, but needs to access the components by its symbolic names in the provided `ComponentArray`. -In addtion to the predictions, the PBM returns additional quantities that may +In addition to the predictions, the PBM returns additional quantities that may be used in penalizing unrealistic conditions independent of observations. In this simple example, just an empty vector is returned. diff --git a/docs/src/tutorials/intermediate/basic_cpu_results.jld2 b/docs/src/tutorials/intermediate/basic_cpu_results.jld2 index a7e804c1b023f9292a4c19fcf49803c33c384a99..820dd4ec65d2e3b3dbba1e6c69e79af4c331c79a 100644 GIT binary patch delta 17295 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 UrjM^$dQ+=>pd_glX|v^j05XPpaR2}S delta 17048 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 maximum(x -> isfinite(x) ? x : zero(x), col), + eachcol(y_obs)) + # add a penalty if r1 is larger than 0.95 times the maximum + sum(max.(zero(eltype(θMs_tr)), θMs_tr[:,:r1] .- 0.95 .* y_obs_max)) +end +``` + +## Update the problem and redo the inversion + +HybridProblem has keyword argument `penalty_computer` to specify the Callable +that computes the penalty. It defaults to `ZeroPenaltyComputer`, which +returns zero penalty cost. + +Here we construct a [`CustomPenaltyComputer`](@ref) with the function specified +above and update the problem. + +``` julia +penalty_computer = CustomPenaltyComputer(compute_penalty_r1) +prob_pen = HybridProblem(prob; penalty_computer) + +using OptimizationOptimisers +import Zygote +# silence warning of no GPU backend found (because we did not import CUDA here) +ENV["MLDATADEVICES_SILENCE_WARN_NO_GPU"] = 1 + +# first run a few iterators with updating only optimizing the mean +solver_point = HybridPointSolver(; alg=Adam(0.02)) +(; probo) = solve(prob_pen, solver_point; + callback = callback_loss(100), # output during fitting + epochs = 5, +); probo_pen_point = probo; + +# starting from this, also estimate the posterior uncertainty parameters +solver = HybridPosteriorSolver(; alg=Adam(0.02), n_MC=3) +(; probo) = solve(probo_pen_point, solver; + callback = callback_loss(100), # output during fitting + epochs = 5, +); +``` + +## Writing a customized PenaltyComputer + +In the above example, the maximum of the observations in the batch +are recomputed each time, the PenaltyComputer is called. + +This can be avoided, because the function receives argument, `i_sites`, +which can be used to index precomputed observation maxima, stored +in a struct implementing type `AbstractPenaltyComputer` +and function `apply_penalty_computer`. + +``` julia +struct R1PenaltyComputer{T} <: AbstractPenaltyComputer where T + ys_max::Vector{T} +end +function R1PenaltyComputer(ys::AbstractMatrix) + ys_max = vec(maximum(ys; dims = 1)) + R1PenaltyComputer(ys_max) +end +function HybridVariationalInference.apply_penalty_computer( + pc::R1PenaltyComputer, + y_pred::AbstractMatrix, addq_pred::AbstractMatrix, θMs_tr::AbstractMatrix, θP::AbstractVector, + y_obs::AbstractMatrix, i_sites, + ϕg, ϕq::AbstractVector + ) + y_obs_max = pc.ys_max[i_sites] + #@assert y_obs_max == map(col -> maximum(x -> isfinite(x) ? x : zero(x), col), eachcol(y_obs)) + # add a penalty if r1 is larger than 0.95 times the maximum + sum(max.(zero(eltype(θMs_tr)), θMs_tr[:,:r1] .- 0.95 .* y_obs_max)) +end + +ys = get_hybridproblem_train_dataloader(probo).data[3] +penalty_computer = R1PenaltyComputer(ys) +``` + +Rerunning the inversion using with the update PenaltyComputer: + +``` julia +prob_pen = HybridProblem(probo; penalty_computer) +(; probo) = solve(prob_pen, solver; + callback = callback_loss(100), # output during fitting + epochs = 5, +); +``` diff --git a/docs/src/tutorials/penalty.qmd b/docs/src/tutorials/penalty.qmd new file mode 100644 index 0000000..3533b06 --- /dev/null +++ b/docs/src/tutorials/penalty.qmd @@ -0,0 +1,149 @@ +--- +title: "How to specify custom Penalties" +engine: julia +execute: + echo: true + output: false + daemon: 3600 +format: + commonmark: + variant: -raw_html+tex_math_dollars + wrap: preserve +bibliography: twutz_txt.bib +--- + +``` @meta +CurrentModule = HybridVariationalInference +``` + +This guide shows how the user can specify a customized penalties to help +the solver to converge to global minimum. + +## Motivation +The basic cost in HVI is the negative log of the joint probability, i.e. +the likelihood of the observations given the parameters * prior probability +of the parameters. + +Sometimes there is additional knowledge not encoded in the prior, such as +one parameter must be larger than another, or entropy-weights of the +ML-parameters, and the solver accept a function to add additional loss terms. +The loglikelihood function assigns a cost to the mismatch between predictions and +observations. This often needs to be customized to the specific inversion. + +This guide walks through the specification of such additional penalties. + +First load necessary packages. +```{julia} +using HybridVariationalInference +using SimpleChains +using ComponentArrays: ComponentArrays as CA +using JLD2 +``` + +This tutorial reuses and modifies the fitted object saved at the end of the +[Basic workflow without GPU](@ref) tutorial, that used a log-Likelihood +function assuming observation error to be distributed independently normal. + +```{julia} +fname = "intermediate/basic_cpu_results.jld2" +print(abspath(fname)) +prob = probo_normal = load(fname, "probo"); +``` + +## Write function to compute the penalty loss + +The function signature corresponds to the one described in [`apply_penalty_computer`](@ref). + +In this example we want to avoid local minima when parameter, `r1`, is larger than +70% of the maximum observation. + +```{julia} +function compute_penalty_r1(y_pred::AbstractMatrix, addq_pred::AbstractMatrix, + θMs_tr::AbstractMatrix, θP::AbstractVector, + y_obs::AbstractMatrix, i_sites, + ϕg, ϕq::AbstractVector) + # compute the maximum of observed rates at each site + y_obs_max = map(col -> maximum(x -> isfinite(x) ? x : zero(x), col), + eachcol(y_obs)) + # add a penalty if r1 is larger than 0.95 times the maximum + sum(max.(zero(eltype(θMs_tr)), θMs_tr[:,:r1] .- 0.95 .* y_obs_max)) +end +``` + +## Update the problem and redo the inversion + +HybridProblem has keyword argument `penalty_computer` to specify the Callable +that computes the penalty. It defaults to `ZeroPenaltyComputer`, which +returns zero penalty cost. + +Here we construct a [`CustomPenaltyComputer`](@ref) with the function specified +above and update the problem. + +```{julia} +penalty_computer = CustomPenaltyComputer(compute_penalty_r1) +prob_pen = HybridProblem(prob; penalty_computer) + +using OptimizationOptimisers +import Zygote +# silence warning of no GPU backend found (because we did not import CUDA here) +ENV["MLDATADEVICES_SILENCE_WARN_NO_GPU"] = 1 + +# first run a few iterators with updating only optimizing the mean +solver_point = HybridPointSolver(; alg=Adam(0.02)) +(; probo) = solve(prob_pen, solver_point; + callback = callback_loss(100), # output during fitting + epochs = 5, +); probo_pen_point = probo; + +# starting from this, also estimate the posterior uncertainty parameters +solver = HybridPosteriorSolver(; alg=Adam(0.02), n_MC=3) +(; probo) = solve(probo_pen_point, solver; + callback = callback_loss(100), # output during fitting + epochs = 5, +); +``` + +## Writing a customized PenaltyComputer + +In the above example, the maximum of the observations in the batch +are recomputed each time, the PenaltyComputer is called. + +This can be avoided, because the function receives argument, `i_sites`, +which can be used to index precomputed observation maxima, stored +in a struct implementing type `AbstractPenaltyComputer` +and function `apply_penalty_computer`. + +```{julia} +struct R1PenaltyComputer{T} <: AbstractPenaltyComputer where T + ys_max::Vector{T} +end +function R1PenaltyComputer(ys::AbstractMatrix) + ys_max = vec(maximum(ys; dims = 1)) + R1PenaltyComputer(ys_max) +end +function HybridVariationalInference.apply_penalty_computer( + pc::R1PenaltyComputer, + y_pred::AbstractMatrix, addq_pred::AbstractMatrix, θMs_tr::AbstractMatrix, θP::AbstractVector, + y_obs::AbstractMatrix, i_sites, + ϕg, ϕq::AbstractVector + ) + y_obs_max = pc.ys_max[i_sites] + #@assert y_obs_max == map(col -> maximum(x -> isfinite(x) ? x : zero(x), col), eachcol(y_obs)) + # add a penalty if r1 is larger than 0.95 times the maximum + sum(max.(zero(eltype(θMs_tr)), θMs_tr[:,:r1] .- 0.95 .* y_obs_max)) +end + +ys = get_hybridproblem_train_dataloader(probo).data[3] +penalty_computer = R1PenaltyComputer(ys) +``` + +Rerunning the inversion using with the update PenaltyComputer: +```{julia} +prob_pen = HybridProblem(probo; penalty_computer) +(; probo) = solve(prob_pen, solver; + callback = callback_loss(100), # output during fitting + epochs = 5, +); +``` + + diff --git a/src/AbstractHybridProblem.jl b/src/AbstractHybridProblem.jl index d7835a6..b1b5b0e 100644 --- a/src/AbstractHybridProblem.jl +++ b/src/AbstractHybridProblem.jl @@ -29,6 +29,62 @@ The initial value of parameters to estimate is spread """ abstract type AbstractHybridProblem end; +abstract type AbstractPenaltyComputer end; + +""" + CustomPenaltyComputer(f::Function) + +A wrapper to use a custom function to compute additional loss penalty terms +during the HVI fit. +""" +struct CustomPenaltyComputer <: AbstractPenaltyComputer + f::Function +end + +""" + apply_penalty_computer(::AbstractPenaltyComputer, + y_pred::AbstractMatrix, addq_pred::AbstractMatrix, + θMs::AbstractMatrix, θP::AbstractVector, + y_obs::AbstractMatrix, + ϕg, ϕq::AbstractVector) +Add zero i.e. no additional loss terms during the HVI fit. + +The basic cost in HVI is the negative log of the joint probability, i.e. +the likelihood of the observations given the parameters * prior probability +of the parameters. + +Sometimes there is additional knowledge not encoded in the prior, such as +one parameter must be larger than another, or entropy-weights of the +ML-parameters, and the solver accept a function to add additional loss terms. + +Arguments +- y_pred::AbstractMatrix: Observations +- addq_pred::AbstractMatrix: Additional quantities computed by the PBM +- θMs_tr::AbstractMatrix: site parameters (with sites in rows and parameters in columns) +- θP::AbstractVector: global parameters +- y_obs::AbstractMatrix, observations +- i_sites: indices of sites in the minibatch, useful for using precoputed quantities +- ϕg: ML-model parameters, +- ϕq::AbstractVector, additional parameters of the posterior +""" +function apply_penalty_computer end; +function apply_penalty_computer(pc::CustomPenaltyComputer, args...; kwargs...) + pc.f(args...; kwargs...) +end + +function (pc::AbstractPenaltyComputer)(args...; kwargs...) + apply_penalty_computer(pc, args...; kwargs...) +end + + +""" + get_hybridproblem_penalty_computer(::AbstractHybridProblem; scenario) + +Return a func +""" +function get_hybridproblem_penalty_computer end; + + """ get_hybridproblem_MLapplicator([rng::AbstractRNG,] ::AbstractHybridProblem; scenario=()) diff --git a/src/DoubleMM/f_doubleMM.jl b/src/DoubleMM/f_doubleMM.jl index 10f64dd..41684d0 100644 --- a/src/DoubleMM/f_doubleMM.jl +++ b/src/DoubleMM/f_doubleMM.jl @@ -62,7 +62,7 @@ function f_doubleMM(θc::CA.ComponentVector{ET}, x) where ET lim1 = x.S1 ./ (K1 .+ x.S1) lim2 = x.S2 ./ (K2 .+ x.S2) y = r0 .+ r1 .* lim1 .* lim2 - return (y, vcat(lim1, lim2)) # in addtion to y returm the limitations as a vector + return (y, vcat(lim1, lim2)) # in addition to y return the limitations as a vector end end @@ -140,7 +140,7 @@ function f_doubleMM_sites(θc_tr::CA.ComponentMatrix, xPc::CA.ComponentMatrix) lim1 = S1 ./ (K1 .+ S1) lim2 = S2 ./ (K2 .+ S2) y = r0 .+ r1 .* lim1 .* lim2 - return (y, vcat(lim1, lim2)) # in addtion to y returm the limitations as a vector + return (y, vcat(lim1, lim2)) # in addition to y return the limitations as a vector #(rep_fac .* r0') .+ (rep_fac .* r1') .* S1 ./ ((rep_fac .* K1') .+ S1) .* S2 ./ ((rep_fac .* K2') .+ S2) end @@ -423,4 +423,7 @@ function HVI.get_hybridproblem_ϕq(prob::DoubleMMCase; scenario::Val{scen}) wher end +function HVI.get_hybridproblem_penalty_computer(prob::DoubleMMCase; scenario = ()) + ZeroPenaltyComputer() +end diff --git a/src/HybridProblem.jl b/src/HybridProblem.jl index c454c7a..ca7e9ce 100644 --- a/src/HybridProblem.jl +++ b/src/HybridProblem.jl @@ -45,6 +45,8 @@ struct HybridProblem <: AbstractHybridProblem n_batch::Int pbm_covars::NTuple{_N, Symbol} where _N approx::AbstractHVIApproximation + penalty_computer::AbstractPenaltyComputer + #penalty_computer:: #inner constructor to constrain the types function HybridProblem( θM::CA.ComponentVector, @@ -63,11 +65,13 @@ struct HybridProblem <: AbstractHybridProblem n_batch::Int; cor_ends::NamedTuple = (P = [length(ϕq[Val(:μP)])], M = [length(θM)]), pbm_covars::NTuple{N,Symbol} = (), - approx::AbstractHVIApproximation = MeanHVIApproximationMat() + approx::AbstractHVIApproximation = MeanHVIApproximationMat(), + penalty_computer::AbstractPenaltyComputer = ZeroPenaltyComputer(), ) where N new( θM, f_batch, g, ϕg, ϕq, priors, py, transM, transP, cor_ends, - train_dataloader, test_data, n_covar, n_site, n_batch, pbm_covars, approx) + train_dataloader, test_data, n_covar, n_site, n_batch, pbm_covars, + approx, penalty_computer) end end @@ -132,6 +136,7 @@ function update_hybridProblem(prob::AbstractHybridProblem; scenario, θP = nothing, ϕunc = nothing, approx::AbstractHVIApproximation = MeanHVIApproximationMat(), + penalty_computer::AbstractPenaltyComputer = get_hybridproblem_penalty_computer(prob; scenario), ) cor_ends_new = if !isnothing(cor_ends) # if new cor_ends was specified then re-initialize the ρsP and ρsM in ϕq @@ -148,7 +153,8 @@ function update_hybridProblem(prob::AbstractHybridProblem; scenario, ϕq = CA.ComponentVector(ϕq; ϕunc...) end HybridProblem(θM, ϕq, g, ϕg, f_batch, priors, py, transM, transP, train_dataloader, - test_data, n_covar, n_site, n_batch; cor_ends = cor_ends_new, pbm_covars, approx) + test_data, n_covar, n_site, n_batch; cor_ends = cor_ends_new, pbm_covars, + approx, penalty_computer) end function HybridProblem(prob::HybridProblem; kwargs... ) @@ -252,6 +258,10 @@ function get_hybridproblem_MLapplicator(prob::HybridProblem; scenario = ()) prob.g, prob.ϕg end +function get_hybridproblem_penalty_computer(prob::HybridProblem; scenario = ()) + prob.penalty_computer +end + function get_hybridproblem_train_dataloader(prob::HybridProblem; scenario = ()) prob.train_dataloader end diff --git a/src/HybridSolver.jl b/src/HybridSolver.jl index 441d64f..7e61015 100644 --- a/src/HybridSolver.jl +++ b/src/HybridSolver.jl @@ -66,14 +66,21 @@ function CommonSolve.solve(prob::AbstractHybridProblem, solver::HybridPointSolve zero_prior_logdensity = omit_priors ? 0f0 : get_zero_prior_logdensity( priorsP, priorsM, pt.θP, pt.θM) #intP = ComponentArrayInterpreter(pt.θP) + intθP = ComponentArrayInterpreter(pt.θP) + intθMs = ComponentArrayInterpreter((n_batch,), pt.θM) + penalty_computer = get_hybridproblem_penalty_computer(prob; scenario) loss_gf = get_loss_gf(g_dev, transM, transP, f_dev, py, intϕ; n_site_batch=n_batch, cdev=infer_cdev(gdevs), pbm_covars, - priorsP, priorsM, is_omit_priors, zero_prior_logdensity,) + priorsP, priorsM, is_omit_priors, zero_prior_logdensity, penalty_computer, + intθMs, intθP, + ) loss_gf_test = get_loss_gf(g_dev, transM, transP, ftest_dev, py, intϕ; n_site_batch=n_site_test, cdev=infer_cdev(gdevs), pbm_covars, - priorsP, priorsM, is_omit_priors, zero_prior_logdensity,) + priorsP, priorsM, is_omit_priors, zero_prior_logdensity, penalty_computer, + intθMs, intθP, + ) # call loss function once l1 = is_infer ? Test.@inferred(loss_gf(ϕ0_dev, first(train_loader_dev)...; is_testmode=true))[1] : @@ -233,6 +240,12 @@ function CommonSolve.solve(prob::AbstractHybridProblem, solver::HybridPosteriorS py = get_hybridproblem_neg_logden_obs(prob; scenario) + penalty_computer = get_hybridproblem_penalty_computer(prob; scenario) + # intθP = ComponentArrayInterpreter(pt.θP, (solver.n_MC,)) + # intθMs = ComponentArrayInterpreter((n_batch,), pt.θM, (solver.n_MC,)) + intθP = ComponentArrayInterpreter(pt.θP) + intθMs = ComponentArrayInterpreter((n_batch,), pt.θM) + priors_θP_mean, priors_θMs_mean = construct_priors_θ_mean( prob, ϕ0_dev.ϕg, keys(pt.θM), pt.θP, θmean_quant, g_dev, transM, transP; scenario, gdevs, pbm_covars) @@ -241,7 +254,7 @@ function CommonSolve.solve(prob::AbstractHybridProblem, solver::HybridPosteriorS g_dev, transP, transMs, f_dev, py; solver.n_MC, solver.n_MC_cap, cor_ends, priors_θP_mean, priors_θMs_mean, cdev=infer_cdev(gdevs), pbm_covars, pt.θP, int_ϕq, int_ϕg_ϕq, priorsP, priorsM, - is_omit_priors, zero_prior_logdensity, approx, + is_omit_priors, zero_prior_logdensity, approx, penalty_computer, intθMs, intθP, ) # test loss function once # tmp = first(train_loader_dev) @@ -294,8 +307,9 @@ function get_loss_elbo(g, transP, transMs, f, py; n_MC, n_MC_mean = max(n_MC,20), n_MC_cap=n_MC, cor_ends, priors_θP_mean, priors_θMs_mean, cdev, pbm_covars, θP, int_ϕq, int_ϕg_ϕq, - priorsP, priorsM, floss_penalty = zero_penalty_loss, + priorsP, priorsM, penalty_computer = ZeroPenaltyComputer(), is_omit_priors, zero_prior_logdensity, approx, + intθMs, intθP ) let g = g, transP = transP, transMs = transMs, f = f, py = py, n_MC = n_MC, n_MC_cap = n_MC_cap, n_MC_mean = n_MC_mean, @@ -305,9 +319,10 @@ function get_loss_elbo(g, transP, transMs, f, py; pbm_covar_indices = get_pbm_covar_indices(θP, pbm_covars), trans_mP=StackedArray(transP, n_MC_mean), trans_mMs=StackedArray(transMs.stacked, n_MC_mean), - priorsP=priorsP, priorsM=priorsM, floss_penalty=floss_penalty, + priorsP=priorsP, priorsM=priorsM, penalty_computer=penalty_computer, is_omit_priors = is_omit_priors, zero_prior_logdensity = zero_prior_logdensity, - approx = approx + approx = approx, + intθMs = get_concrete(intθMs), intθP = get_concrete(intθP) function loss_elbo(ϕ, rng, xM, xP, y_o, y_unc, i_sites; is_testmode) #ϕc = int_ϕg_ϕq(ϕ) @@ -316,8 +331,9 @@ function get_loss_elbo(g, transP, transMs, f, py; int_ϕq, int_ϕg_ϕq, n_MC, n_MC_cap, n_MC_mean, cor_ends, priors_θP_mean, priors_θMs_mean, cdev, pbm_covar_indices, transP, transMs, trans_mP, trans_mMs, - priorsP, priorsM, floss_penalty, #ϕg = ϕc.ϕg, ϕq = ϕc.ϕq, + priorsP, priorsM, penalty_computer, #ϕg = ϕc.ϕg, ϕq = ϕc.ϕq, is_testmode, is_omit_priors, zero_prior_logdensity, approx, + intθMs, intθP, ) end end diff --git a/src/HybridVariationalInference.jl b/src/HybridVariationalInference.jl index 2602191..523afe7 100644 --- a/src/HybridVariationalInference.jl +++ b/src/HybridVariationalInference.jl @@ -65,7 +65,10 @@ include("PBMApplicator.jl") # export AbstractGPUDataHandler, NullGPUDataHandler, get_default_GPUHandler # include("GPUDataHandler.jl") -export AbstractHybridProblem, get_hybridproblem_MLapplicator, get_hybridproblem_PBmodel, +export AbstractHybridProblem, AbstractPenaltyComputer, CustomPenaltyComputer, + apply_penalty_computer, + get_hybridproblem_MLapplicator, get_hybridproblem_PBmodel, + get_hybridproblem_penalty_computer, get_hybridproblem_ϕq, get_hybridproblem_θP, get_hybridproblem_float_type, gen_hybridproblem_synthetic, get_hybridproblem_par_templates, get_hybridproblem_transforms, @@ -111,7 +114,7 @@ include("logden_normal.jl") export get_ca_starts, get_ca_ends, get_cor_count include("cholesky.jl") -export neg_elbo_gtf, sample_posterior, predict_hvi, zero_penalty_loss +export neg_elbo_gtf, sample_posterior, predict_hvi, ZeroPenaltyComputer export get_hybridproblem_correlation_Ms include("elbo_dev.jl") include("elbo_sepvec.jl") diff --git a/src/PBMApplicator.jl b/src/PBMApplicator.jl index 556ed31..221c9e7 100644 --- a/src/PBMApplicator.jl +++ b/src/PBMApplicator.jl @@ -136,7 +136,7 @@ end PBMSiteApplicator(fθ; θP, θM, θFix, xPvec) Construct AbstractPBMApplicator from process-based model `fθ` that computes predictions -and addtional quantities for a single site. +and additional quantities for a single site. The Applicator combines enclosed `θFix`, with provided `θMs` and `θP` and constructs a `ComponentVector` that can be indexed by symbolic parameter names, corresponding to the templates provided during diff --git a/src/elbo.jl b/src/elbo.jl index 72ab7d2..3b0f76d 100644 --- a/src/elbo.jl +++ b/src/elbo.jl @@ -58,11 +58,12 @@ function neg_elbo_gtf_components(rng, ϕ::AbstractVector{FT}, g, f, py, trans_mP =StackedArray(transP, n_MC), # provide with creating cost function trans_mMs =StackedArray(transMs.stacked, n_MC), priorsP, priorsM, - floss_penalty = zero_penalty_loss, + penalty_computer = ZeroPenaltyComputer(), is_testmode, is_omit_priors, zero_prior_logdensity, approx::AbstractHVIApproximation, + intθP, intθMs, ) where {FT} n_MCr = isempty(priors_θP_mean) ? n_MC : max(n_MC, n_MC_mean) ζsP, ζsMs_tr, σ = generate_ζ(approx, rng, g, ϕ, xM; n_MC=n_MCr, cor_ends, pbm_covar_indices, @@ -78,7 +79,8 @@ function neg_elbo_gtf_components(rng, ϕ::AbstractVector{FT}, g, f, py, loss_comps = neg_elbo_ζtf( ζsP_cpu[:,1:n_MC], ζsMs_tr_cpu[:,:,1:n_MC], σ, f, py, xP, y_ob, y_unc; n_MC_cap, transP, transMs, priorsP, priorsM, - floss_penalty, ϕg, ϕq, is_omit_priors, zero_prior_logdensity,) + penalty_computer, ϕg, ϕq, is_omit_priors, zero_prior_logdensity, + i_sites, intθMs, intθP) # # maybe: provide trans_mP and trans_mMs with creating cost function # not used any more and merging named tuples takes long @@ -126,7 +128,7 @@ Compute the neg_elbo for each sampled parameter vector (last dimension of ζs). - `neg_log_prior`: the prior of parameters at constrained scale - `logjac`, negative logarithm of the absolute value of the determinant of the Jacobian of the transformation `θ=T(ζ)`. -- `loss_penalty`: additional loss terms from floss_penalty +- `loss_penalty`: additional loss terms from penalty_computer - compute entropy of transformation """ function neg_elbo_ζtf(ζsP, ζsMs_tr, σ, f, py, xP, y_ob, y_unc; @@ -134,9 +136,10 @@ function neg_elbo_ζtf(ζsP, ζsMs_tr, σ, f, py, xP, y_ob, y_unc; transP, transMs=StackedArray(transM, size(ζsMs_tr, 2)), priorsP, priorsM, - floss_penalty, ϕg, ϕq, + penalty_computer, ϕg, ϕq, is_omit_priors::Val, zero_prior_logdensity, + i_sites, intθP, intθMs, ) n_MC = size(ζsP,2) f_sample = (ζP, ζMs_tr) -> begin @@ -150,7 +153,8 @@ function neg_elbo_ζtf(ζsP, ζsMs_tr, σ, f, py, xP, y_ob, y_unc; # @usingany Cthulhu # @descend_code_warntype f(θP, θMs, xP) nLy_i = py(y_ob, y_pred_i, y_unc) - loss_penalty_i = convert(eltype(nLy_i),floss_penalty(y_pred_i, θMs_tr, θP, ϕg, ϕq)) + loss_penalty_i = convert(eltype(nLy_i),penalty_computer( + y_pred_i, addq_pred_i, intθMs(θMs_tr), intθP(θP), y_ob, i_sites, ϕg, ϕq)) neg_log_prior_i = compute_priors_logdensity(priorsP, priorsM, θP, θMs_tr, is_omit_priors, zero_prior_logdensity) # make sure names to not match outer, otherwise Box type instability @@ -259,30 +263,13 @@ function compute_priors_logdensity(priorsP, priorsM, θP, θMs_tr, zero_prior_lo neg_log_prior_i end -""" - zero_penalty_loss(y_pred, θMs, θP, ϕg, ϕq) - -Add zero i.e. no additional loss terms during the HVI fit. - -The basic cost in HVI is the negative log of the joint probability, i.e. -the likelihood of the observations given the parameters * prior probability -of the parameters. - -Sometimes there is additional knowledge not encoded in the prior, such as -one parameter must be larger than another, or entropy-weights of the -ML-parameters, and the solver accept a function to add additional loss terms. - -Arguments -- y_pred::AbstractMatrix: Observations -- θMs::AbstractMatrix: site parameters -- θP::AbstractVector: global parameters -- ϕg: ML-model parameters, -- ϕq::AbstractVector, additional parameters of the posterior -""" -function zero_penalty_loss( - y_pred::AbstractMatrix, θMs::AbstractMatrix, θP::AbstractVector, +struct ZeroPenaltyComputer <: AbstractPenaltyComputer end +function apply_penalty_computer( + ::ZeroPenaltyComputer, + y_pred::AbstractMatrix, addq_pred::AbstractMatrix, θMs_tr::AbstractMatrix, θP::AbstractVector, + y_obs::AbstractMatrix, i_sites::AbstractVector, ϕg, ϕq::AbstractVector) - return zero(eltype(θMs)) + return zero(eltype(θMs_tr)) end diff --git a/src/gf.jl b/src/gf.jl index b9b0bba..16c89a8 100644 --- a/src/gf.jl +++ b/src/gf.jl @@ -230,10 +230,11 @@ function get_loss_gf(g, transM, transP, f, py, intϕ(1:length(intϕ)).ϕP); cdev=cpu_device(), pbm_covars, n_site_batch, - floss_penalty = zero_penalty_loss, + penalty_computer = ZeroPenaltyComputer(), priorsP, priorsM, is_omit_priors::Val = Val(false), zero_prior_logdensity, + intθP, intθMs, kwargs...) let g = g, transM = transM, transP = transP, f = f, @@ -243,7 +244,8 @@ function get_loss_gf(g, transM, transP, f, py, pbm_covar_indices = CA.getdata(intP(1:length(intP))[pbm_covars]), zero_prior_logdensity = zero_prior_logdensity, is_omit_priors = is_omit_priors, priorsP = priorsP, priorsM = priorsM, - floss_penalty = floss_penalty, + penalty_computer = penalty_computer, + intθMs = get_concrete(intθMs), intθP = get_concrete(intθP), cpu_dev = cpu_device() # real cpu, different form infer_cdev(gdevs) that maybe idenetity #, intP = get_concrete(intP) #inv_transP = inverse(transP), kwargs = kwargs @@ -286,7 +288,9 @@ function get_loss_gf(g, transM, transP, f, py, error("debug get_loss_gf") end ϕq = eltype(θP_pred)[] # no uncertainty parameters optimized - loss_penalty = floss_penalty(y_pred, θMs_tr_pred, θP_pred, ϕc.ϕg, ϕq) + loss_penalty = penalty_computer( + y_pred, addq_pred, intθMs(θMs_tr_pred), intθP(θP_pred), + y_o, i_sites, ϕc.ϕg, ϕq) #@show nLy, neg_log_prior, loss_penalty nLjoint_pen = nLy + neg_log_prior + loss_penalty return (;nLjoint_pen, y_pred, θMs_tr_pred, θP_pred, nLy, neg_log_prior, loss_penalty) diff --git a/test/test_HybridProblem.jl b/test/test_HybridProblem.jl index 20843d2..a31a667 100644 --- a/test/test_HybridProblem.jl +++ b/test/test_HybridProblem.jl @@ -151,6 +151,7 @@ test_without_flux = (scenario) -> begin #----------- fit g and θP to y_o rng = StableRNG(111) g, ϕg0 = get_hybridproblem_MLapplicator(prob; scenario) + pt = get_hybridproblem_par_templates(prob; scenario) n_site, n_batch = get_hybridproblem_n_site_and_batch(prob; scenario) train_loader = get_hybridproblem_train_dataloader(prob; scenario) (xM, xP, y_o, y_unc, i_sites) = first(train_loader) @@ -167,12 +168,15 @@ test_without_flux = (scenario) -> begin priorsM = Tuple(priors[k] for k in keys(par_templates.θM)) # slightly disturb θP_true p = p0 = vcat(ϕg0, par_templates.θP .* convert(eltype(ϕg0), 0.8)) + intθP = ComponentArrayInterpreter(pt.θP) + intθMs = ComponentArrayInterpreter((n_batch,), pt.θM) # Pass the site-data for the batches as separate vectors wrapped in a tuple zero_prior_logdensity = CP.get_zero_prior_logdensity( priorsP, priorsM, par_templates.θP, par_templates.θM) loss_gf = get_loss_gf(g, transM, transP, f, py, intϕ; pbm_covars, n_site_batch = n_batch, priorsP, priorsM, zero_prior_logdensity, + intθMs, intθP, ) (_xM, _xP, _y_o, _y_unc, _i_sites) = first(train_loader) #l1 = loss_gf(p0, _xM, _xP, _y_o, _y_unc, _i_sites; is_testmode = false) diff --git a/test/test_doubleMM.jl b/test/test_doubleMM.jl index 3fbb079..d9672e8 100644 --- a/test/test_doubleMM.jl +++ b/test/test_doubleMM.jl @@ -198,6 +198,7 @@ end @testset "loss_gf" begin #----------- fit g and θP to y_o (without uncertainty, without transforming θP) g, ϕg0 = get_hybridproblem_MLapplicator(prob; scenario) + pt = get_hybridproblem_par_templates(prob; scenario) (; transP, transM) = get_hybridproblem_transforms(prob; scenario) n_site, n_site_batch = get_hybridproblem_n_site_and_batch(prob; scenario) f = get_hybridproblem_PBmodel(prob; scenario) @@ -220,14 +221,19 @@ end train_loader = get_hybridproblem_train_dataloader(prob; scenario) @assert train_loader.data == (xM, xP, y_o, y_unc, i_sites) pbm_covars = get_hybridproblem_pbmpar_covars(prob; scenario) + intθP = ComponentArrayInterpreter(pt.θP) + intθMs_batch = ComponentArrayInterpreter((n_batch,), pt.θM) + intθMs_site = ComponentArrayInterpreter((n_site,), pt.θM) #loss_gf = get_loss_gf(g, transM, f, intϕ; gdev = identity) zero_prior_logdensity = CP.get_zero_prior_logdensity( priorsP, priorsM, par_templates.θP, par_templates.θM) loss_gf = get_loss_gf(g, transM, transP, f, py, intϕ; - pbm_covars, n_site_batch = n_batch, priorsP, priorsM, zero_prior_logdensity) + pbm_covars, n_site_batch = n_batch, priorsP, priorsM, zero_prior_logdensity, + intθMs = intθMs_batch, intθP,) loss_gf_site = get_loss_gf(g, transM, transP, f2, py, intϕ; - pbm_covars, n_site_batch = n_site, priorsP, priorsM, zero_prior_logdensity) + pbm_covars, n_site_batch = n_site, priorsP, priorsM, zero_prior_logdensity, + intθMs = intθMs_site, intθP,) nLjoint = @inferred first(loss_gf(p0, first(train_loader)...; is_testmode=true)) (xM_batch, xP_batch, y_o_batch, y_unc_batch, i_sites_batch) = first(train_loader) # @usingany Cthulhu diff --git a/test/test_elbo.jl b/test/test_elbo.jl index 27e18a5..37fa170 100644 --- a/test/test_elbo.jl +++ b/test/test_elbo.jl @@ -350,6 +350,7 @@ test_scenario = (scenario, approx) -> begin @testset "neg_elbo_gtf cpu $(last(CP._val_value(scenario)))" begin i_sites = 1:n_batch transMs = StackedArray(transM, size(ζsMs_tr, 1)) + intθMs = ComponentArrayInterpreter((n_batch,), int_M) cost = @inferred ( #@descend_code_warntype ( neg_elbo_gtf(rng, ϕ_ini, g, f, py, @@ -358,7 +359,7 @@ test_scenario = (scenario, approx) -> begin cor_ends, pbm_covar_indices, transP, transMs, priorsP, priorsM, is_testmode = true, is_omit_priors = Val(false), zero_prior_logdensity=zero(eltype(ϕ_ini)), - approx, + approx, intθMs, intθP = int_P ) ) @test cost isa Float64 @@ -369,7 +370,7 @@ test_scenario = (scenario, approx) -> begin cor_ends, pbm_covar_indices, transP, transMs, priorsP, priorsM, is_testmode = false, is_omit_priors = Val(false), zero_prior_logdensity=zero(eltype(ϕ_ini)), - approx, + approx, intθMs, intθP = int_P ), CA.getdata(ϕ_ini)) @test gr[1] isa Vector From ffaac178f9561c3dd89da51500a48f6568b88ece Mon Sep 17 00:00:00 2001 From: Thomas Wutzler Date: Fri, 27 Mar 2026 08:04:45 +0000 Subject: [PATCH 03/31] let PenaltyComputer return several components --- Project.toml | 3 +- docs/src/tutorials/penalty.md | 31 +++++++++---------- docs/src/tutorials/penalty.qmd | 31 +++++++++---------- src/AbstractHybridProblem.jl | 15 ++++++---- src/HybridProblem.jl | 6 ++-- src/HybridSolver.jl | 7 +++-- src/HybridVariationalInference.jl | 2 +- src/elbo.jl | 49 ++++++++++++++++++++++++------- src/gf.jl | 4 +-- 9 files changed, 92 insertions(+), 56 deletions(-) diff --git a/Project.toml b/Project.toml index 7a5a80d..ca5cd0d 100644 --- a/Project.toml +++ b/Project.toml @@ -46,6 +46,7 @@ HybridVariationalInferenceFluxExt = "Flux" HybridVariationalInferenceLuxExt = "Lux" HybridVariationalInferenceSimpleChainsExt = "SimpleChains" +# require Optimization 5.3 do deal with NaN gradients [compat] Bijectors = "0.14, 0.15" BlockDiagonals = "0.1.42, 0.2" @@ -70,7 +71,7 @@ MLUtils = "0.4.5" Missings = "1.2.0" NaNMath = "1.1.3" Optimisers = "0.4.6" -Optimization = "3.11, 4" +Optimization = "5.3" Random = "1.10.0" SimpleChains = "0.4.8" StableRNGs = "1.0.2" diff --git a/docs/src/tutorials/penalty.md b/docs/src/tutorials/penalty.md index cfaa2c2..110e0e6 100644 --- a/docs/src/tutorials/penalty.md +++ b/docs/src/tutorials/penalty.md @@ -43,7 +43,7 @@ prob = probo_normal = load(fname, "probo"); ## Write function to compute the penalty loss -The function signature corresponds to the one described in [`apply_penalty_computer`](@ref). +The function signature corresponds to the one described in [`compute_penalty`](@ref). In this example we want to avoid local minima when parameter, `r1`, is larger than 70% of the maximum observation. @@ -57,7 +57,8 @@ function compute_penalty_r1(y_pred::AbstractMatrix, addq_pred::AbstractMatrix, y_obs_max = map(col -> maximum(x -> isfinite(x) ? x : zero(x), col), eachcol(y_obs)) # add a penalty if r1 is larger than 0.95 times the maximum - sum(max.(zero(eltype(θMs_tr)), θMs_tr[:,:r1] .- 0.95 .* y_obs_max)) + penalty = sum(max.(zero(eltype(θMs_tr)), θMs_tr[:,:r1] .- 0.95 .* y_obs_max)) + (; penalty) end ``` @@ -67,12 +68,12 @@ HybridProblem has keyword argument `penalty_computer` to specify the Callable that computes the penalty. It defaults to `ZeroPenaltyComputer`, which returns zero penalty cost. -Here we construct a [`CustomPenaltyComputer`](@ref) with the function specified -above and update the problem. +We can pass the function directly or alternatively construct a [`CustomPenaltyComputer`](@ref) and update the problem. ``` julia -penalty_computer = CustomPenaltyComputer(compute_penalty_r1) -prob_pen = HybridProblem(prob; penalty_computer) +#penalty_computer = CustomPenaltyComputer(compute_penalty_r1) +#prob_pen = HybridProblem(prob; penalty_computer) +prob_pen = HybridProblem(prob; penalty_computer = compute_penalty_r1) using OptimizationOptimisers import Zygote @@ -102,26 +103,26 @@ are recomputed each time, the PenaltyComputer is called. This can be avoided, because the function receives argument, `i_sites`, which can be used to index precomputed observation maxima, stored in a struct implementing type `AbstractPenaltyComputer` -and function `apply_penalty_computer`. +and function `compute_penalty`. ``` julia struct R1PenaltyComputer{T} <: AbstractPenaltyComputer where T - ys_max::Vector{T} + r_max::Vector{T} end function R1PenaltyComputer(ys::AbstractMatrix) - ys_max = vec(maximum(ys; dims = 1)) - R1PenaltyComputer(ys_max) + r_max = 0.95 .* vec(maximum(ys; dims = 1)) + R1PenaltyComputer(r_max) end -function HybridVariationalInference.apply_penalty_computer( +function HybridVariationalInference.compute_penalty( pc::R1PenaltyComputer, y_pred::AbstractMatrix, addq_pred::AbstractMatrix, θMs_tr::AbstractMatrix, θP::AbstractVector, y_obs::AbstractMatrix, i_sites, ϕg, ϕq::AbstractVector ) - y_obs_max = pc.ys_max[i_sites] - #@assert y_obs_max == map(col -> maximum(x -> isfinite(x) ? x : zero(x), col), eachcol(y_obs)) - # add a penalty if r1 is larger than 0.95 times the maximum - sum(max.(zero(eltype(θMs_tr)), θMs_tr[:,:r1] .- 0.95 .* y_obs_max)) + @assert pc.r_max[i_sites] == 0.95 .* map(col -> maximum(x -> isfinite(x) ? x : zero(x), col), eachcol(y_obs)) + # add a penalty if r1 is larger r_max + penalty = sum(max.(zero(eltype(θMs_tr)), θMs_tr[:,:r1] .- pc.r_max[i_sites])) + (;penalty) end ys = get_hybridproblem_train_dataloader(probo).data[3] diff --git a/docs/src/tutorials/penalty.qmd b/docs/src/tutorials/penalty.qmd index 3533b06..f714152 100644 --- a/docs/src/tutorials/penalty.qmd +++ b/docs/src/tutorials/penalty.qmd @@ -52,7 +52,7 @@ prob = probo_normal = load(fname, "probo"); ## Write function to compute the penalty loss -The function signature corresponds to the one described in [`apply_penalty_computer`](@ref). +The function signature corresponds to the one described in [`compute_penalty`](@ref). In this example we want to avoid local minima when parameter, `r1`, is larger than 70% of the maximum observation. @@ -66,7 +66,8 @@ function compute_penalty_r1(y_pred::AbstractMatrix, addq_pred::AbstractMatrix, y_obs_max = map(col -> maximum(x -> isfinite(x) ? x : zero(x), col), eachcol(y_obs)) # add a penalty if r1 is larger than 0.95 times the maximum - sum(max.(zero(eltype(θMs_tr)), θMs_tr[:,:r1] .- 0.95 .* y_obs_max)) + penalty = sum(max.(zero(eltype(θMs_tr)), θMs_tr[:,:r1] .- 0.95 .* y_obs_max)) + (; penalty) end ``` @@ -76,10 +77,10 @@ HybridProblem has keyword argument `penalty_computer` to specify the Callable that computes the penalty. It defaults to `ZeroPenaltyComputer`, which returns zero penalty cost. -Here we construct a [`CustomPenaltyComputer`](@ref) with the function specified -above and update the problem. +We can pass the function directly or alternatively construct a [`CustomPenaltyComputer`](@ref) and update the problem. ```{julia} +#prob_pen = HybridProblem(prob; penalty_computer = compute_penalty_r1) penalty_computer = CustomPenaltyComputer(compute_penalty_r1) prob_pen = HybridProblem(prob; penalty_computer) @@ -106,31 +107,31 @@ solver = HybridPosteriorSolver(; alg=Adam(0.02), n_MC=3) ## Writing a customized PenaltyComputer In the above example, the maximum of the observations in the batch -are recomputed each time, the PenaltyComputer is called. +are recomputed each time when the PenaltyComputer is called. -This can be avoided, because the function receives argument, `i_sites`, +This can be avoided. The PenaltyComputer receives argument, `i_sites`, which can be used to index precomputed observation maxima, stored in a struct implementing type `AbstractPenaltyComputer` -and function `apply_penalty_computer`. +and function `compute_penalty`. ```{julia} struct R1PenaltyComputer{T} <: AbstractPenaltyComputer where T - ys_max::Vector{T} + r_max::Vector{T} end function R1PenaltyComputer(ys::AbstractMatrix) - ys_max = vec(maximum(ys; dims = 1)) - R1PenaltyComputer(ys_max) + r_max = 0.95 .* vec(maximum(ys; dims = 1)) + R1PenaltyComputer(r_max) end -function HybridVariationalInference.apply_penalty_computer( +function HybridVariationalInference.compute_penalty( pc::R1PenaltyComputer, y_pred::AbstractMatrix, addq_pred::AbstractMatrix, θMs_tr::AbstractMatrix, θP::AbstractVector, y_obs::AbstractMatrix, i_sites, ϕg, ϕq::AbstractVector ) - y_obs_max = pc.ys_max[i_sites] - #@assert y_obs_max == map(col -> maximum(x -> isfinite(x) ? x : zero(x), col), eachcol(y_obs)) - # add a penalty if r1 is larger than 0.95 times the maximum - sum(max.(zero(eltype(θMs_tr)), θMs_tr[:,:r1] .- 0.95 .* y_obs_max)) + # @assert pc.r_max[i_sites] == 0.95 .* map(col -> maximum(x -> isfinite(x) ? x : zero(x), col), eachcol(y_obs)) + # add a penalty if r1 is larger r_max + penalty = sum(max.(zero(eltype(θMs_tr)), θMs_tr[:,:r1] .- pc.r_max[i_sites])) + (;penalty) end ys = get_hybridproblem_train_dataloader(probo).data[3] diff --git a/src/AbstractHybridProblem.jl b/src/AbstractHybridProblem.jl index b1b5b0e..062d6ae 100644 --- a/src/AbstractHybridProblem.jl +++ b/src/AbstractHybridProblem.jl @@ -30,6 +30,7 @@ The initial value of parameters to estimate is spread abstract type AbstractHybridProblem end; abstract type AbstractPenaltyComputer end; +const PenaltyComputerOrFunction = Union{AbstractPenaltyComputer, Function} """ CustomPenaltyComputer(f::Function) @@ -42,10 +43,10 @@ struct CustomPenaltyComputer <: AbstractPenaltyComputer end """ - apply_penalty_computer(::AbstractPenaltyComputer, + compute_penalty(::PenaltyComputerOrFunction, y_pred::AbstractMatrix, addq_pred::AbstractMatrix, θMs::AbstractMatrix, θP::AbstractVector, - y_obs::AbstractMatrix, + y_obs::AbstractMatrix, i_sites::AbstractVector{<:Int}, ϕg, ϕq::AbstractVector) Add zero i.e. no additional loss terms during the HVI fit. @@ -66,14 +67,18 @@ Arguments - i_sites: indices of sites in the minibatch, useful for using precoputed quantities - ϕg: ML-model parameters, - ϕq::AbstractVector, additional parameters of the posterior + +Returns a NamedTuple +- with first element (Real): the total penalty +- other component (Real): optional information on parts of the penalty """ -function apply_penalty_computer end; -function apply_penalty_computer(pc::CustomPenaltyComputer, args...; kwargs...) +function compute_penalty end; +function compute_penalty(pc::CustomPenaltyComputer, args...; kwargs...) pc.f(args...; kwargs...) end function (pc::AbstractPenaltyComputer)(args...; kwargs...) - apply_penalty_computer(pc, args...; kwargs...) + compute_penalty(pc, args...; kwargs...) end diff --git a/src/HybridProblem.jl b/src/HybridProblem.jl index ca7e9ce..1b8c9e3 100644 --- a/src/HybridProblem.jl +++ b/src/HybridProblem.jl @@ -45,7 +45,7 @@ struct HybridProblem <: AbstractHybridProblem n_batch::Int pbm_covars::NTuple{_N, Symbol} where _N approx::AbstractHVIApproximation - penalty_computer::AbstractPenaltyComputer + penalty_computer::PenaltyComputerOrFunction #penalty_computer:: #inner constructor to constrain the types function HybridProblem( @@ -66,7 +66,7 @@ struct HybridProblem <: AbstractHybridProblem cor_ends::NamedTuple = (P = [length(ϕq[Val(:μP)])], M = [length(θM)]), pbm_covars::NTuple{N,Symbol} = (), approx::AbstractHVIApproximation = MeanHVIApproximationMat(), - penalty_computer::AbstractPenaltyComputer = ZeroPenaltyComputer(), + penalty_computer::PenaltyComputerOrFunction = ZeroPenaltyComputer(), ) where N new( θM, f_batch, g, ϕg, ϕq, priors, py, transM, transP, cor_ends, @@ -136,7 +136,7 @@ function update_hybridProblem(prob::AbstractHybridProblem; scenario, θP = nothing, ϕunc = nothing, approx::AbstractHVIApproximation = MeanHVIApproximationMat(), - penalty_computer::AbstractPenaltyComputer = get_hybridproblem_penalty_computer(prob; scenario), + penalty_computer::PenaltyComputerOrFunction = get_hybridproblem_penalty_computer(prob; scenario), ) cor_ends_new = if !isnothing(cor_ends) # if new cor_ends was specified then re-initialize the ρsP and ρsM in ϕq diff --git a/src/HybridSolver.jl b/src/HybridSolver.jl index 7e61015..4ddf4f7 100644 --- a/src/HybridSolver.jl +++ b/src/HybridSolver.jl @@ -387,9 +387,10 @@ function compute_elbo_components( f_batch = get_hybridproblem_PBmodel(prob; scenario) f = (n_site_pred == n_batch) ? f : create_nsite_applicator(f_batch, n_site_pred) py = get_hybridproblem_neg_logden_obs(prob; scenario) - priors_θ_mean = construct_priors_θ_mean( - prob, ϕ0_dev.ϕg, keys(θM), θP, θmean_quant, g_dev, transM; - scenario, gdev, cdev, pbm_covars) + priors_θ_mean = nothing + # priors_θ_mean = construct_priors_θ_mean( + # prob, ϕ0_dev.ϕg, keys(θM), θP, θmean_quant, g_dev, transM; + # scenario, gdev, cdev, pbm_covars) neg_elbo_gtf_components( rng, ϕ0_dev, g_dev, transPMs_batch, f, py, xM, xP, y_o, y_unc, i_sites, interpreters; solver.n_MC, solver.n_MC_cap, cor_ends, priors_θ_mean) diff --git a/src/HybridVariationalInference.jl b/src/HybridVariationalInference.jl index 523afe7..7eabb16 100644 --- a/src/HybridVariationalInference.jl +++ b/src/HybridVariationalInference.jl @@ -66,7 +66,7 @@ include("PBMApplicator.jl") # include("GPUDataHandler.jl") export AbstractHybridProblem, AbstractPenaltyComputer, CustomPenaltyComputer, - apply_penalty_computer, + compute_penalty, get_hybridproblem_MLapplicator, get_hybridproblem_PBmodel, get_hybridproblem_penalty_computer, get_hybridproblem_ϕq, get_hybridproblem_θP, diff --git a/src/elbo.jl b/src/elbo.jl index 3b0f76d..b753e23 100644 --- a/src/elbo.jl +++ b/src/elbo.jl @@ -65,6 +65,15 @@ function neg_elbo_gtf_components(rng, ϕ::AbstractVector{FT}, g, f, py, approx::AbstractHVIApproximation, intθP, intθMs, ) where {FT} + ϕc = int_ϕg_ϕq(ϕ) + VT= typeof(@view(ϕ[1:1])) + ϕg = CA.getdata(ϕc.ϕg)::VT + ϕq = CA.getdata(ϕc.ϕq)::VT + if(!all(isfinite.(ϕ))) + @show ϕq + @show ϕg + error("encountered non-finite optimized parameters") + end n_MCr = isempty(priors_θP_mean) ? n_MC : max(n_MC, n_MC_mean) ζsP, ζsMs_tr, σ = generate_ζ(approx, rng, g, ϕ, xM; n_MC=n_MCr, cor_ends, pbm_covar_indices, int_ϕq, int_ϕg_ϕq, is_testmode, i_sites) @@ -72,10 +81,6 @@ function neg_elbo_gtf_components(rng, ϕ::AbstractVector{FT}, g, f, py, ζsMs_tr_cpu = cdev(ζsMs_tr) # fetch to CPU, because for <1000 sites (n_batch) this is faster # # maybe: translate ζ once and supply to both neg_elbo and negloglik_meanθ - ϕc = int_ϕg_ϕq(ϕ) - VT= typeof(@view(ϕ[1:1])) - ϕg = CA.getdata(ϕc.ϕg)::VT - ϕq = CA.getdata(ϕc.ϕq)::VT loss_comps = neg_elbo_ζtf( ζsP_cpu[:,1:n_MC], ζsMs_tr_cpu[:,:,1:n_MC], σ, f, py, xP, y_ob, y_unc; n_MC_cap, transP, transMs, priorsP, priorsM, @@ -131,7 +136,7 @@ Compute the neg_elbo for each sampled parameter vector (last dimension of ζs). - `loss_penalty`: additional loss terms from penalty_computer - compute entropy of transformation """ -function neg_elbo_ζtf(ζsP, ζsMs_tr, σ, f, py, xP, y_ob, y_unc; +function neg_elbo_ζtf(ζsP::AbstractArray{T}, ζsMs_tr, σ, f, py, xP, y_ob, y_unc; n_MC_cap=size(ζsP,2), transP, transMs=StackedArray(transM, size(ζsMs_tr, 2)), @@ -140,10 +145,22 @@ function neg_elbo_ζtf(ζsP, ζsMs_tr, σ, f, py, xP, y_ob, y_unc; is_omit_priors::Val, zero_prior_logdensity, i_sites, intθP, intθMs, -) +) where T n_MC = size(ζsP,2) - f_sample = (ζP, ζMs_tr) -> begin + #@show ζsMs_tr[1,4,:] # fourth component goes to NaN at some time + if !all(isfinite.(ζsMs_tr)) + return (; + nLjoint=T(1e9), entropy_ζ=zero(T), loss_penalty=zero(T), nLy=zero(T), + neg_log_prior=T(1e9), neg_log_jac=zero(T)) + end + f_sample = (ζP, ζMs_tr) -> begin θP, θMs_tr, logjac_i = transform_and_logjac_ζ(ζP, ζMs_tr; transP, transMs) + if !all(isfinite.(θMs_tr)) + i_row = findfirst(θM -> !all(isfinite.(θM)), eachrow(θMs_tr)) + @show i_row #info "encountered non-finite θMs_tr at $(i_row)th site" + @show θMs_tr[i_row,:] + @show ζMs_tr[i_row,:] + end # currently logpdf only works on CPU (y_pred_i, addq_pred_i) = f(θP, θMs_tr, xP) #nLy1 = neg_logden_indep_normal(y_ob, y_pred_i, y_unc) @@ -153,8 +170,8 @@ function neg_elbo_ζtf(ζsP, ζsMs_tr, σ, f, py, xP, y_ob, y_unc; # @usingany Cthulhu # @descend_code_warntype f(θP, θMs, xP) nLy_i = py(y_ob, y_pred_i, y_unc) - loss_penalty_i = convert(eltype(nLy_i),penalty_computer( - y_pred_i, addq_pred_i, intθMs(θMs_tr), intθP(θP), y_ob, i_sites, ϕg, ϕq)) + loss_penalty_i = convert(eltype(nLy_i),first(penalty_computer( + y_pred_i, addq_pred_i, intθMs(θMs_tr), intθP(θP), y_ob, i_sites, ϕg, ϕq))) neg_log_prior_i = compute_priors_logdensity(priorsP, priorsM, θP, θMs_tr, is_omit_priors, zero_prior_logdensity) # make sure names to not match outer, otherwise Box type instability @@ -264,12 +281,12 @@ function compute_priors_logdensity(priorsP, priorsM, θP, θMs_tr, zero_prior_lo end struct ZeroPenaltyComputer <: AbstractPenaltyComputer end -function apply_penalty_computer( +function compute_penalty( ::ZeroPenaltyComputer, y_pred::AbstractMatrix, addq_pred::AbstractMatrix, θMs_tr::AbstractMatrix, θP::AbstractVector, y_obs::AbstractMatrix, i_sites::AbstractVector, ϕg, ϕq::AbstractVector) - return zero(eltype(θMs_tr)) + return (; penalty = zero(eltype(θMs_tr))) end @@ -480,6 +497,12 @@ function generate_ζ( xMP0 = _append_each_covars(xM, CA.getdata(μ_ζP), pbm_covar_indices) ϕm0 = g(xMP0, ϕg; is_testmode) μ_ζMs0 = ϕm0 + # if !all(isfinite.(μ_ζMs0)) + # @show μ_ζMs0 + # is_infinte_ϕg = !all(isfinite.(ϕg)) + # @show is_infinte_ϕg + # error("encountered non-finite μ_ζMs0") + # end ζP_resids, ζMs_parfirst_resids, σ = sample_ζresid_norm(approx, rng, i_sites, ϕm0, ϕq; n_MC, cor_ends, int_ϕq) ζsP = isempty(μ_ζP) ? ζP_resids : (μ_ζP .+ ζP_resids) # n_par x n_MC @@ -652,6 +675,10 @@ function sample_ζresid_norm(approx::MeanHVIApproximationMat, # is this multiplication efficient if Uσ is not concrete but only sumtype BlockDiagonal? urandn = hcat(zP, zMs) ζ_resids_parfirst = (Uσ' * urandn') #::typeof(urandn) # n_par x n_MC + # if !all(isfinite.(ζ_resids_parfirst)) + # @show ζ_resids_parfirst + # @show Uσ + # end #ζ_resids_parfirst = (urandn * Uσ)' #::typeof(urandn) # n_par x n_MC #ζ_resids_parfirst = urandn' * Uσ # n_MC x n_par # need to handle empty(ζP) explicitly, otherwise Zygote tries to take gradient diff --git a/src/gf.jl b/src/gf.jl index 16c89a8..17d94b8 100644 --- a/src/gf.jl +++ b/src/gf.jl @@ -288,9 +288,9 @@ function get_loss_gf(g, transM, transP, f, py, error("debug get_loss_gf") end ϕq = eltype(θP_pred)[] # no uncertainty parameters optimized - loss_penalty = penalty_computer( + loss_penalty = first(penalty_computer( y_pred, addq_pred, intθMs(θMs_tr_pred), intθP(θP_pred), - y_o, i_sites, ϕc.ϕg, ϕq) + y_o, i_sites, ϕc.ϕg, ϕq)) #@show nLy, neg_log_prior, loss_penalty nLjoint_pen = nLy + neg_log_prior + loss_penalty return (;nLjoint_pen, y_pred, θMs_tr_pred, θP_pred, nLy, neg_log_prior, loss_penalty) From ca49e27c18e7d6a6afe86ac7777c3321d889a99c Mon Sep 17 00:00:00 2001 From: Thomas Wutzler Date: Mon, 30 Mar 2026 12:09:52 +0000 Subject: [PATCH 04/31] fix type inference with penalties --- src/HVIApproximation.jl | 4 ++++ src/HybridVariationalInference.jl | 1 + src/elbo.jl | 5 ++++- src/logden_normal.jl | 2 +- test/Project.toml | 1 + test/test_cholesky_structure.jl | 1 + test/test_doubleMM.jl | 1 + test/test_elbo.jl | 3 ++- 8 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/HVIApproximation.jl b/src/HVIApproximation.jl index ceb29b0..fbf43fc 100644 --- a/src/HVIApproximation.jl +++ b/src/HVIApproximation.jl @@ -22,3 +22,7 @@ abstract type AbstractMeanVarSepHVIApproximation <: AbstractHVIApproximation end struct MeanVarSepHVIApproximation <: AbstractMeanVarSepHVIApproximation end + +abstract type AbstractMeanScalingHVIApproximation <: AbstractHVIApproximation end + +struct MeanScalingHVIApproximation <: AbstractMeanScalingHVIApproximation end diff --git a/src/HybridVariationalInference.jl b/src/HybridVariationalInference.jl index 7eabb16..e339e25 100644 --- a/src/HybridVariationalInference.jl +++ b/src/HybridVariationalInference.jl @@ -43,6 +43,7 @@ include("bijectors_utils.jl") export AbstractHVIApproximation, AbstractMeanHVIApproximation export MeanHVIApproximation, MeanHVIApproximationMat export AbstractMeanVarSepHVIApproximation, MeanVarSepHVIApproximation +export AbstractMeanScalingHVIApproximation, MeanScalingHVIApproximation include("HVIApproximation.jl") export AbstractComponentArrayInterpreter, ComponentArrayInterpreter, diff --git a/src/elbo.jl b/src/elbo.jl index b753e23..5d1ee4b 100644 --- a/src/elbo.jl +++ b/src/elbo.jl @@ -210,6 +210,7 @@ function neg_elbo_ζtf(ζsP::AbstractArray{T}, ζsMs_tr, σ, f, py, xP, y_ob, y_ #Main.@infiltrate_main end #@assert length(σ) == n_θ + #entropy_ζ = convert(T, entropy_MvNormal(n_θ, logdetΣ)) # defined in logden_normal entropy_ζ = entropy_MvNormal(n_θ, logdetΣ) # defined in logden_normal # if i_sites[1] == 1 # #Main.@infiltrate_main @@ -599,7 +600,9 @@ ML-model predcitions of size `(n_θM, n_site)`. * `int_ϕq`: Interpret vector as ComponentVector with components ρsP, ρsM, logσ2_ζP, coef_logσ2_ζMs(intercept + slope), """ -function sample_ζresid_norm(approx::AbstractHVIApproximation, rng::Random.AbstractRNG, +function sample_ζresid_norm( + approx::Union{AbstractMeanHVIApproximation,AbstractMeanVarSepHVIApproximation}, + rng::Random.AbstractRNG, i_sites, ϕm::AbstractMatrix, ϕq::AbstractVector, args...; diff --git a/src/logden_normal.jl b/src/logden_normal.jl index 1655383..1d2c0b3 100644 --- a/src/logden_normal.jl +++ b/src/logden_normal.jl @@ -71,7 +71,7 @@ end # end -entropy_MvNormal(K, logdetΣ) = (K * log(2 * π * ℯ) + logdetΣ) / 2 +entropy_MvNormal(K::Integer, logdetΣ::T) where T = (T(K) * log(T(2) * T(π) * T(ℯ)) + logdetΣ) / T(2) # compiler figures out log(2 * π * ℯ) already, no need to tinker #entropy_MvNormal(K, logdetΣ) = (K * (1 + log(2π)) + logdetΣ) / 2 entropy_MvNormal(Σ) = entropy_MvNormal(size(Σ, 1), logdet(Σ)) diff --git a/test/Project.toml b/test/Project.toml index c78503d..6abadd9 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -17,6 +17,7 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" Lux = "b2108857-7c20-44ae-9111-449ecde12c47" MLDataDevices = "7e8f7934-dd98-4c1a-8fe8-92b47a384d40" MLUtils = "f1d291b0-491e-4a28-83b9-f70985020b54" +Optimization = "7f7a1694-90dd-40f0-9382-eb1efda571ba" OptimizationOptimisers = "42dfb2eb-d2b4-4451-abcd-913932933ac1" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" diff --git a/test/test_cholesky_structure.jl b/test/test_cholesky_structure.jl index 1d98b49..c2767cf 100644 --- a/test/test_cholesky_structure.jl +++ b/test/test_cholesky_structure.jl @@ -2,6 +2,7 @@ using LinearAlgebra, Test using HybridVariationalInference using HybridVariationalInference: HybridVariationalInference as CP using Zygote +import Optimization using OptimizationOptimisers using ComponentArrays: ComponentArrays as CA #using SymmetricFormats diff --git a/test/test_doubleMM.jl b/test/test_doubleMM.jl index d9672e8..658e4aa 100644 --- a/test/test_doubleMM.jl +++ b/test/test_doubleMM.jl @@ -11,6 +11,7 @@ using SimpleChains using MLUtils import Zygote +import Optimization using OptimizationOptimisers using MLDataDevices diff --git a/test/test_elbo.jl b/test/test_elbo.jl index 37fa170..adb903a 100644 --- a/test/test_elbo.jl +++ b/test/test_elbo.jl @@ -362,7 +362,8 @@ test_scenario = (scenario, approx) -> begin approx, intθMs, intθP = int_P ) ) - @test cost isa Float64 + #@test cost isa Float64 + @test cost isa promote_type(eltype(xM), eltype(y_o), eltype(ϕ_ini)) gr = Zygote.gradient( ϕ -> neg_elbo_gtf(rng, ϕ, g, f, py, xM[:, i_sites], xP[:, i_sites], y_o[:, i_sites], y_unc[:, i_sites], i_sites; From d42e8ea5f6fcfbed94d8793b489775beb7318252 Mon Sep 17 00:00:00 2001 From: Thomas Wutzler Date: Mon, 30 Mar 2026 14:09:16 +0000 Subject: [PATCH 05/31] remove n_covar from HybridProblem replace by fallback on train_dataloader but keep it in AbstractHybridProblem to allow returning an automatic train_dataloader and add get_hybridproblem_HVIApproximation --- ext/HybridVariationalInferenceFluxExt.jl | 9 +-- ext/HybridVariationalInferenceLuxExt.jl | 11 +-- ...bridVariationalInferenceSimpleChainsExt.jl | 14 ++-- src/AbstractHybridProblem.jl | 27 ++++--- src/DoubleMM/f_doubleMM.jl | 14 +++- src/HVIApproximation.jl | 18 ++++- src/HybridProblem.jl | 17 ++--- src/HybridVariationalInference.jl | 7 +- src/ModelApplicator.jl | 16 ++++ src/elbo_scaling.jl | 75 +++++++++++++++++++ test/test_HybridProblem.jl | 18 +++-- 11 files changed, 168 insertions(+), 58 deletions(-) create mode 100644 src/elbo_scaling.jl diff --git a/ext/HybridVariationalInferenceFluxExt.jl b/ext/HybridVariationalInferenceFluxExt.jl index 315bc51..cf0cb6b 100644 --- a/ext/HybridVariationalInferenceFluxExt.jl +++ b/ext/HybridVariationalInferenceFluxExt.jl @@ -55,12 +55,7 @@ end function HVI.construct_3layer_MLApplicator( rng::AbstractRNG, prob::HVI.AbstractHybridProblem, ::Val{:Flux}; scenario::Val{scen}) where scen - (;θM) = get_hybridproblem_par_templates(prob; scenario) - n_out = length(θM) - n_covar = get_hybridproblem_n_covar(prob; scenario) - n_pbm_covars = length(get_hybridproblem_pbmpar_covars(prob; scenario)) - n_input = n_covar + n_pbm_covars - #(; n_covar, n_θM) = get_hybridproblem_sizes(prob; scenario) + (; n_input, n_output) = get_numberof_inputs_outputs(prob; scenario) float_type = get_hybridproblem_float_type(prob; scenario) is_using_dropout = :use_dropout ∈ scen is_using_dropout && error("dropout scenario not supported with Flux yet.") @@ -69,7 +64,7 @@ function HVI.construct_3layer_MLApplicator( Flux.Dense(n_input => n_input * 4, tanh), Flux.Dense(n_input * 4 => n_input * 4, tanh), # dense layer without bias that maps to n outputs and `logistic` activation - Flux.Dense(n_input * 4 => n_out, logistic, bias = false) + Flux.Dense(n_input * 4 => n_output, logistic, bias = false) ) construct_ChainsApplicator(rng, g_chain, float_type) end diff --git a/ext/HybridVariationalInferenceLuxExt.jl b/ext/HybridVariationalInferenceLuxExt.jl index c8995c9..d457c82 100644 --- a/ext/HybridVariationalInferenceLuxExt.jl +++ b/ext/HybridVariationalInferenceLuxExt.jl @@ -53,12 +53,7 @@ function HVI.construct_3layer_MLApplicator( rng::AbstractRNG, prob::HVI.AbstractHybridProblem, ::Val{:Lux}; scenario::Val{scen}, p_dropout = 0.2) where scen - (;θM) = get_hybridproblem_par_templates(prob; scenario) - n_out = length(θM) - n_covar = get_hybridproblem_n_covar(prob; scenario) - n_pbm_covars = length(get_hybridproblem_pbmpar_covars(prob; scenario)) - n_input = n_covar + n_pbm_covars - #(; n_covar, n_θM) = get_hybridproblem_sizes(prob; scenario) + (; n_input, n_output) = get_numberof_inputs_outputs(prob; scenario) float_type = get_hybridproblem_float_type(prob; scenario) is_using_dropout = :use_dropout ∈ scen g_chain = if is_using_dropout @@ -69,7 +64,7 @@ function HVI.construct_3layer_MLApplicator( Lux.Dense(n_input * 4 => n_input * 4, tanh), Lux.Dropout(p_dropout), # dense layer without bias that maps to n outputs and `logistic` activation - Lux.Dense(n_input * 4 => n_out, logistic, use_bias = false) + Lux.Dense(n_input * 4 => n_output, logistic, use_bias = false) ) else Lux.Chain( @@ -77,7 +72,7 @@ function HVI.construct_3layer_MLApplicator( Lux.Dense(n_input => n_input * 4, tanh), Lux.Dense(n_input * 4 => n_input * 4, tanh), # dense layer without bias that maps to n outputs and `logistic` activation - Lux.Dense(n_input * 4 => n_out, logistic, use_bias = false) + Lux.Dense(n_input * 4 => n_output, logistic, use_bias = false) ) end construct_ChainsApplicator(rng, g_chain, float_type) diff --git a/ext/HybridVariationalInferenceSimpleChainsExt.jl b/ext/HybridVariationalInferenceSimpleChainsExt.jl index 8c36453..39a3ed3 100644 --- a/ext/HybridVariationalInferenceSimpleChainsExt.jl +++ b/ext/HybridVariationalInferenceSimpleChainsExt.jl @@ -22,12 +22,8 @@ end function HVI.construct_3layer_MLApplicator( rng::AbstractRNG, prob::HVI.AbstractHybridProblem, ::Val{:SimpleChains}; scenario::Val{scen}) where scen - n_covar = get_hybridproblem_n_covar(prob; scenario) - n_pbm_covars = length(get_hybridproblem_pbmpar_covars(prob; scenario)) - n_input = n_covar + n_pbm_covars - FloatType = get_hybridproblem_float_type(prob; scenario) - (;θM) = get_hybridproblem_par_templates(prob; scenario) - n_out = length(θM) + (; n_input, n_output) = get_numberof_inputs_outputs(prob; scenario) + float_type = get_hybridproblem_float_type(prob; scenario) is_using_dropout = :use_dropout ∈ scen g_chain = if is_using_dropout SimpleChain( @@ -38,7 +34,7 @@ function HVI.construct_3layer_MLApplicator( TurboDense{true}(tanh, n_input * 4), SimpleChains.Dropout(0.2), # dense layer without bias that maps to n outputs and `logistic` activation - TurboDense{false}(logistic, n_out) + TurboDense{false}(logistic, n_output) ) else SimpleChain( @@ -47,10 +43,10 @@ function HVI.construct_3layer_MLApplicator( TurboDense{true}(tanh, n_input * 4), TurboDense{true}(tanh, n_input * 4), # dense layer without bias that maps to n outputs and `logistic` activation - TurboDense{false}(logistic, n_out) + TurboDense{false}(logistic, n_output) ) end - construct_ChainsApplicator(rng, g_chain, FloatType) + construct_ChainsApplicator(rng, g_chain, float_type) end end # module diff --git a/src/AbstractHybridProblem.jl b/src/AbstractHybridProblem.jl index 062d6ae..c0cb5ef 100644 --- a/src/AbstractHybridProblem.jl +++ b/src/AbstractHybridProblem.jl @@ -12,7 +12,6 @@ For a specific prob, provide functions that specify details - `get_hybridproblem_train_dataloader` (may use `construct_dataloader_from_synthetic`) - `get_hybridproblem_test_data` - `get_hybridproblem_priors` -- `get_hybridproblem_n_covar` - `get_hybridproblem_n_site_and_batch` optionally - `gen_hybridproblem_synthetic` @@ -188,16 +187,15 @@ function get_hybridproblem_transforms end """ get_hybridproblem_n_covar(::AbstractHybridProblem; scenario) -Provide the number of covariates. +Provide the number of covariates. Default implementation falls back to train_dataloader """ -function get_hybridproblem_n_covar(::AbstractHybridProblem; scenario) end -# function get_hybridproblem_n_covar(prob::AbstractHybridProblem; scenario) -# train_loader = get_hybridproblem_train_dataloader(Random.default_rng(), prob; scenario) -# (xM, xP, y_o, y_unc) = first(train_loader) -# n_covar = size(xM, 1) -# return (n_covar) -# end - +function get_hybridproblem_n_covar(prob::AbstractHybridProblem; scenario) + train_dataloader = get_hybridproblem_train_dataloader( + Random.default_rng(), prob; scenario) + (xM, xP, y_o, y_unc) = first(train_dataloader) + n_covar = size(xM, 1) + return (n_covar) +end function get_hybridproblem_pbmpar_covars(::AbstractHybridProblem; scenario) () @@ -379,5 +377,14 @@ function setup_PBMpar_interpreter(θP, θM, θall = vcat(θP, θM)) intθ, θFix end +""" + get_hybridproblem_HVIApproximation(::AbstractHybridProblem; scenario) + +Return a AbstractHVIApproximation that should be used with this problem +""" +function get_hybridproblem_HVIApproximation end + + + diff --git a/src/DoubleMM/f_doubleMM.jl b/src/DoubleMM/f_doubleMM.jl index 41684d0..f7f8123 100644 --- a/src/DoubleMM/f_doubleMM.jl +++ b/src/DoubleMM/f_doubleMM.jl @@ -334,6 +334,8 @@ function HVI.get_hybridproblem_train_dataloader(prob::DoubleMMCase; scenario::Va rng::AbstractRNG = StableRNG(111), kwargs... ) where {scen} n_site, n_batch = get_hybridproblem_n_site_and_batch(prob; scenario) + # In order to avoid cirular dependcies, need to implement specific version of + # HVI.get_hybridproblem_n_covar, which be default relies on the train_dataloader dl = construct_dataloader_from_synthetic(rng, prob; scenario, n_batch, kwargs...) if (:driverNAN ∈ scen) (xM, xP, y_o, y_unc, i_sites) = dl.data @@ -411,7 +413,7 @@ function HVI.get_hybridproblem_cor_ends(prob::DoubleMMCase; scenario::Val{scen}) end function HVI.get_hybridproblem_ϕq(prob::DoubleMMCase; scenario::Val{scen}) where {scen} - approx = (:sepvar ∈ scen) ? MeanVarSepHVIApproximation() : MeanHVIApproximationMat() + approx = get_hybridproblem_HVIApproximation(prob; scenario) FT = get_hybridproblem_float_type(prob; scenario) cor_ends = get_hybridproblem_cor_ends(prob; scenario) (;θP, θM) = get_hybridproblem_par_templates(prob; scenario) @@ -427,3 +429,13 @@ function HVI.get_hybridproblem_penalty_computer(prob::DoubleMMCase; scenario = ( ZeroPenaltyComputer() end +function HVI.get_hybridproblem_HVIApproximation(prob::DoubleMMCase; scenario::Val{scen}) where {scen} + approx = if (:scalingall ∈ scen) + (;θP, θM) = get_hybridproblem_par_templates(prob; scenario) + MeanHVIApproximationMat([length(θM)]) + elseif (:sepvar ∈ scen) + MeanVarSepHVIApproximation() + else + MeanHVIApproximationMat() + end +end \ No newline at end of file diff --git a/src/HVIApproximation.jl b/src/HVIApproximation.jl index fbf43fc..04598ca 100644 --- a/src/HVIApproximation.jl +++ b/src/HVIApproximation.jl @@ -2,11 +2,17 @@ AbstractHVIApproximation Provides a type hierarchy to distinguish different forms and -parameterizations of posterior approximations. +parameterizations of posterior approximations. + +Subtypes must implement method `get_numberof_MLinputs(approx, θM)` that +returns the numberof required outputs of the machine learning model +per site for a parameter vector `θM`. """ -abstract type AbstractHVIApproximation end +abstract type AbstractHVIApproximation end, +function get_numberof_MLinputs end abstract type AbstractMeanHVIApproximation <: AbstractHVIApproximation end +get_numberof_MLinputs(::AbstractMeanHVIApproximation, θM) = length(θM) # First implementation with one big sparse covariance matrix struct MeanHVIApproximationMat <: AbstractMeanHVIApproximation end @@ -19,10 +25,16 @@ struct MeanHVIApproximationDev <: AbstractMeanHVIApproximation end abstract type AbstractMeanVarSepHVIApproximation <: AbstractHVIApproximation end +get_numberof_MLinputs(::AbstractMeanVarSepHVIApproximation, θM) = length(θM) struct MeanVarSepHVIApproximation <: AbstractMeanVarSepHVIApproximation end abstract type AbstractMeanScalingHVIApproximation <: AbstractHVIApproximation end -struct MeanScalingHVIApproximation <: AbstractMeanScalingHVIApproximation end +struct MeanScalingHVIApproximation <: AbstractMeanScalingHVIApproximation + scalingblocks_ends::Vector{Int} +end +function get_numberof_MLinputs(approx::MeanScalingHVIApproximation, θM) + length(θM) + length(approx.scalingblocks_ends) +end diff --git a/src/HybridProblem.jl b/src/HybridProblem.jl index 1b8c9e3..ab254d1 100644 --- a/src/HybridProblem.jl +++ b/src/HybridProblem.jl @@ -40,7 +40,6 @@ struct HybridProblem <: AbstractHybridProblem cor_ends::@NamedTuple{P::Vector{Int}, M::Vector{Int}} # = (P=(1,),M=(1,)) train_dataloader::MLUtils.DataLoader test_data::NamedTuple - n_covar::Int n_site::Int n_batch::Int pbm_covars::NTuple{_N, Symbol} where _N @@ -60,7 +59,6 @@ struct HybridProblem <: AbstractHybridProblem transP::Stacked, train_dataloader::MLUtils.DataLoader, test_data::NamedTuple, - n_covar::Int, n_site::Int, n_batch::Int; cor_ends::NamedTuple = (P = [length(ϕq[Val(:μP)])], M = [length(θM)]), @@ -70,7 +68,7 @@ struct HybridProblem <: AbstractHybridProblem ) where N new( θM, f_batch, g, ϕg, ϕq, priors, py, transM, transP, cor_ends, - train_dataloader, test_data, n_covar, n_site, n_batch, pbm_covars, + train_dataloader, test_data, n_site, n_batch, pbm_covars, approx, penalty_computer) end end @@ -127,7 +125,6 @@ function update_hybridProblem(prob::AbstractHybridProblem; scenario, transM = get_hybridproblem_transforms(prob; scenario).transM, train_dataloader = get_hybridproblem_train_dataloader(prob; scenario), test_data = get_hybridproblem_test_data(prob; scenario), - n_covar = get_hybridproblem_n_covar(prob; scenario), n_site = get_hybridproblem_n_site_and_batch(prob; scenario)[1], n_batch = get_hybridproblem_n_site_and_batch(prob; scenario)[2], cor_ends = nothing, @@ -135,7 +132,7 @@ function update_hybridProblem(prob::AbstractHybridProblem; scenario, ϕq = get_hybridproblem_ϕq(prob; scenario), θP = nothing, ϕunc = nothing, - approx::AbstractHVIApproximation = MeanHVIApproximationMat(), + approx::AbstractHVIApproximation = get_hybridproblem_HVIApproximation(prob; scenario), penalty_computer::PenaltyComputerOrFunction = get_hybridproblem_penalty_computer(prob; scenario), ) cor_ends_new = if !isnothing(cor_ends) @@ -153,12 +150,12 @@ function update_hybridProblem(prob::AbstractHybridProblem; scenario, ϕq = CA.ComponentVector(ϕq; ϕunc...) end HybridProblem(θM, ϕq, g, ϕg, f_batch, priors, py, transM, transP, train_dataloader, - test_data, n_covar, n_site, n_batch; cor_ends = cor_ends_new, pbm_covars, + test_data, n_site, n_batch; cor_ends = cor_ends_new, pbm_covars, approx, penalty_computer) end function HybridProblem(prob::HybridProblem; kwargs... ) - update_hybridProblem(prob; scenario = Val(()), approx = prob.approx, kwargs...) + update_hybridProblem(prob; scenario = Val(()), kwargs...) end @@ -276,9 +273,6 @@ end function get_hybridproblem_pbmpar_covars(prob::HybridProblem; scenario = ()) prob.pbm_covars end -function get_hybridproblem_n_covar(prob::HybridProblem; scenario = ()) - prob.n_covar -end function get_hybridproblem_n_site_and_batch(prob::HybridProblem; scenario = ()) prob.n_site, prob.n_batch end @@ -305,3 +299,6 @@ function get_quantile_transformed(priors::Tuple, trans; end +function get_hybridproblem_HVIApproximation(prob::HybridProblem; scenario = ()) + prob.approx +end \ No newline at end of file diff --git a/src/HybridVariationalInference.jl b/src/HybridVariationalInference.jl index e339e25..24fd209 100644 --- a/src/HybridVariationalInference.jl +++ b/src/HybridVariationalInference.jl @@ -41,6 +41,7 @@ VERSION >= v"1.11.0-DEV.469" && eval(Meta.parse("public Logistic")) include("bijectors_utils.jl") export AbstractHVIApproximation, AbstractMeanHVIApproximation +export get_numberof_MLinputs export MeanHVIApproximation, MeanHVIApproximationMat export AbstractMeanVarSepHVIApproximation, MeanVarSepHVIApproximation export AbstractMeanScalingHVIApproximation, MeanScalingHVIApproximation @@ -49,7 +50,7 @@ include("HVIApproximation.jl") export AbstractComponentArrayInterpreter, ComponentArrayInterpreter, StaticComponentArrayInterpreter export flatten1, get_concrete, get_positions, stack_ca_int, compose_interpreters -export construct_partric +export construct_partric, get_numberof_inputs_outputs include("ComponentArrayInterpreter.jl") export AbstractModelApplicator, construct_ChainsApplicator @@ -76,7 +77,7 @@ export AbstractHybridProblem, AbstractPenaltyComputer, CustomPenaltyComputer, get_hybridproblem_train_dataloader, get_hybridproblem_test_data, get_hybridproblem_neg_logden_obs, - get_hybridproblem_n_covar, + get_hybridproblem_n_covar, # default get_hybridproblem_n_site_and_batch, get_hybridproblem_cor_ends, get_hybridproblem_priors, @@ -84,6 +85,7 @@ export AbstractHybridProblem, AbstractPenaltyComputer, CustomPenaltyComputer, gen_cov_pred, construct_dataloader_from_synthetic, gdev_hybridproblem_dataloader, gdev_hybridproblem_data, + get_hybridproblem_HVIApproximation, setup_PBMpar_interpreter, get_gdev_MP, init_hybrid_ϕq @@ -119,6 +121,7 @@ export neg_elbo_gtf, sample_posterior, predict_hvi, ZeroPenaltyComputer export get_hybridproblem_correlation_Ms include("elbo_dev.jl") include("elbo_sepvec.jl") +include("elbo_scaling.jl") include("elbo.jl") include("elbo2.jl") diff --git a/src/ModelApplicator.jl b/src/ModelApplicator.jl index 1ccabfd..65642ff 100644 --- a/src/ModelApplicator.jl +++ b/src/ModelApplicator.jl @@ -69,9 +69,25 @@ Implemented for machine learning extensions, such as Flux or SimpleChains. `ml_engine` usually is of type `Val{Symbol}`, e.g. Val(:Flux). See `select_ml_engine`. Scenario is a value-type of `NTuple{_,Symbol}`. + +Implementations may call +`get_numberof_inputs_outputs(prob; scenario) -> (n_input, n_output)`. """ function construct_3layer_MLApplicator end +function get_numberof_inputs_outputs(prob; scenario) + n_covar = get_hybridproblem_n_covar(prob; scenario) + n_pbm_covars = length(get_hybridproblem_pbmpar_covars(prob; scenario)) + n_input = n_covar + n_pbm_covars + (;θM) = get_hybridproblem_par_templates(prob; scenario) + #n_out = length(θM) + approx = get_hybridproblem_HVIApproximation(prob; scenario) + n_output = get_numberof_MLinputs(approx, θM) + (;n_input, n_output) +end + + + """ select_ml_engine(;scenario) diff --git a/src/elbo_scaling.jl b/src/elbo_scaling.jl new file mode 100644 index 0000000..3fe4e04 --- /dev/null +++ b/src/elbo_scaling.jl @@ -0,0 +1,75 @@ +# Similar to MeanHVIApproximationMat +# but ML model predicts a scaling factor for a group of variance parameters +# ϕq element logσ2_ζM_offsets contains a vector of log-offsets, i.e. multipliers, +# for each block of ML scaled parameters +# the log-offset for the first entry in each block is 0 + +function sample_ζresid_norm(approx::AbstractMeanScalingHVIApproximation, + i_sites, + zP::AbstractMatrix, zMs::AbstractMatrix, + ϕm::TM, ϕq::AbstractVector{T}; + int_ϕq=get_concrete(ComponentArrayInterpreter(ϕq)), + cor_ends +) where {T,TM<:AbstractMatrix{T}} + ϕuncc = ϕqc = int_ϕq(CA.getdata(ϕq)) + logσ2_par_offsets2 = ϕqc[Val(:logσ2_ζM_offsets)] + n_scale_blocks = length(logσ2_par_offsets2) + length_scale_blocks = length.(logσ2_par_offsets2) .+ 1 + n_par = size(ϕm,1) - n_scale_blocks + ζMs = ϕm[1:n_par,:] + logσ2_sites = ϕm[n_par+1,:] + ζP = ϕqc[Val(:μP)] + n_θP, n_θMs, (n_θM, n_batch) = length(ζP), length(ζMs), size(ζMs) + # do not create a UpperTriangular Matrix of an AbgeneraGÜUArray in transformU_cholesky1 + ρsP = isempty(ϕuncc[Val(:ρsP)]) ? similar(ϕuncc[Val(:ρsP)]) : ϕuncc[Val(:ρsP)] # required by zygote + UP = transformU_block_cholesky1(ρsP, cor_ends.P) + ρsM = isempty(ϕuncc[Val(:ρsM)]) ? similar(ϕuncc[Val(:ρsM)]) : ϕuncc[Val(:ρsM)] # required by zygote + # cholesky factor of the correlation: diag(UM' * UM) .== 1 + # coefficients ρsM can be larger than 1, still yielding correlations <1 in UM' * UM + UM = transformU_block_cholesky1(ρsM, cor_ends.M) + # + # Expand site-level offsets to each M-parameter (row) in repeated block structure + logσ2_site_offsets = repeat_rows_by_counts(logσ2_sites, length_scale_blocks) + # Expand parameter offsets to the same block structure, first scale-row is 0 + logσ2_par_offsets = vcat([repeat(vcat(zero(T), o), 1, n_batch) for o in logσ2_par_offsets2]...) + + logσ2_logMs = logσ2_par_offsets .+ logσ2_site_offsets + # + logσ2_ζP = vec(CA.getdata(ϕuncc[Val(:logσ2_ζP)])) + # CUDA cannot multiply BlockDiagonal * Diagonal, construct already those blocks + σMs = reshape(exp.(logσ2_logMs ./ 2), n_θM, :) + σP = exp.(logσ2_ζP ./ 2) + # BlockDiagonal does work with CUDA, but not with combination of Zygote and CUDA + # need to construct full matrix for CUDA + Uσ, diagUσ = _compute_choleskyfactor(UP, UM, σP, σMs, n_batch) # inferred only BlockDiagonal + #diagUσ = diag(Uσ)::typeof(σP) # elements of the diagonal: standard deviations + n_MC = size(zP, 1) + # is this multiplication efficient if Uσ is not concrete but only sumtype BlockDiagonal? + urandn = hcat(zP, zMs) + ζ_resids_parfirst = (Uσ' * urandn') #::typeof(urandn) # n_par x n_MC + #ζ_resids_parfirst = (urandn * Uσ)' #::typeof(urandn) # n_par x n_MC + #ζ_resids_parfirst = urandn' * Uσ # n_MC x n_par + # need to handle empty(ζP) explicitly, otherwise Zygote tries to take gradient + ζP_resids = isempty(ζP) ? ζ_resids_parfirst[1:0, :] : ζ_resids_parfirst[1:n_θP, :] + ζMs_parfirst_resids = reshape(ζ_resids_parfirst[(n_θP+1):end, :], n_θM, n_batch, n_MC) + ζP_resids, ζMs_parfirst_resids, diagUσ + # #map(std, eachcol(ζ_resids_parfirst[:, 3:8])) + # ζ_resid = transpose_mPMs_sitefirst(ζ_resids_parfirst; intm_PMs_parfirst) + # #map(std, eachcol(ζ_resid[:, 3:8])) # all ~ 0.1 in sample_ζresid_norm cpu + # #map(std, eachcol(ζ_resid[:, 2 + n_batch .+ (-1:5)])) # all ~ 100, except first two + # # returns AbstractGPUuArrays to either continue on GPU or need to transfer to CPU + # ζ_resid, diagUσ +end + +# repeat rows of a matrix by per-row counts, non-mutating (Zygote-friendly) +function repeat_rows_by_counts(A::AbstractMatrix, counts::AbstractVector{<:Integer}) + @assert length(counts) == size(A,1) "Need to provide a count for each row." + if isempty(A) + return similar(A, 0, size(A,2)) + end + idx = vcat((fill(i, counts[i]) for i in axes(counts,1))...) + return A[idx, :] +end + + + diff --git a/test/test_HybridProblem.jl b/test/test_HybridProblem.jl index a31a667..0a3d700 100644 --- a/test/test_HybridProblem.jl +++ b/test/test_HybridProblem.jl @@ -46,7 +46,6 @@ function construct_problem(; scenario::Val{scen}) where scen local y = r0 .+ r1 .* x.S1 ./ (K1 .+ x.S1) .* x.S2 ./ (K2 .+ x.S2) return (y, y[1:0]) end - n_out = length(θM) rng = StableRNG(111) # n_batch = 10 n_site, n_batch = get_hybridproblem_n_site_and_batch(CP.DoubleMM.DoubleMMCase(); scenario) @@ -57,8 +56,16 @@ function construct_problem(; scenario::Val{scen}) where scen i_test = n_site .+ (1:n_site_test) test_data = (; xM = xM[:, i_test], xP = xP[:, i_test], y_true = y_true[:, i_test], y_o = y_o[:, i_test], y_unc = y_unc[:, i_test]) - n_covar = size(xM,1) + approx = if (:scalingall ∈ scen) + MeanHVIApproximationMat([length(θM)]) + elseif (:MeanHVIApproxBlocks ∈ scen) + MeanHVIApproximationMat() + else + MeanHVIApproximationMat() + end + n_covar = size(xM,1) n_input = (:covarK2 ∈ scen) ? n_covar +1 : n_covar + n_out = get_numberof_MLinputs(approx, θM) g_chain = SimpleChain( static(n_input), # input dimension (optional) # dense layer with bias that maps to 8 outputs and applies `tanh` activation @@ -97,14 +104,9 @@ function construct_problem(; scenario::Val{scen}) where scen xPvec=xP[:,1]) ϕunc0 = init_hybrid_ϕunc(MeanHVIApproximation(), cor_ends, zero(FT); θM, transM, n_site) ϕq = CP.update_μP_by_θP(ϕunc0, θP, transP) - approx = if (:MeanHVIApproxBlocks ∈ scen) - MeanHVIApproximation() - else - MeanHVIApproximationMat() - end HybridProblem(θM, ϕq, g_chain_scaled, ϕg0, f_batch, priors_dict, py, - transM, transP, train_dataloader, test_data, n_covar, n_site, n_batch; + transM, transP, train_dataloader, test_data, n_site, n_batch; cor_ends, pbm_covars, approx, #ϕunc0, ) From c00f3cc2e6c1e919dcc27958468b78da6124dc44 Mon Sep 17 00:00:00 2001 From: Thomas Wutzler Date: Tue, 31 Mar 2026 15:01:36 +0000 Subject: [PATCH 06/31] make RangeScalingModelApplicator apply only to range of parameters to allow separating parameter and scale outputs of ML model --- docs/src/tutorials/basic_cpu.qmd | 4 +- src/DoubleMM/f_doubleMM.jl | 9 ++-- src/HVIApproximation.jl | 9 +++- src/HybridProblem.jl | 9 ++-- src/ModelApplicator.jl | 74 +++++++++++++++++++++++++++----- src/elbo_scaling.jl | 3 +- src/init_hybrid_params.jl | 47 ++++++++++++++++++-- test/test_HybridProblem.jl | 4 +- test/test_ModelApplicator.jl | 60 +++++++++++++++++++++++++- test/test_elbo.jl | 50 ++++++++++++--------- 10 files changed, 221 insertions(+), 48 deletions(-) diff --git a/docs/src/tutorials/basic_cpu.qmd b/docs/src/tutorials/basic_cpu.qmd index 5d385f3..2b27347 100644 --- a/docs/src/tutorials/basic_cpu.qmd +++ b/docs/src/tutorials/basic_cpu.qmd @@ -255,9 +255,9 @@ invocation of the process based model (PBM), defined at the beginning. ```{julia} approx = MeanHVIApproximation() f_batch = PBMSiteApplicator(f_doubleMM; θP, θM, θFix, xPvec=xP[:,1]) -ϕq0 = init_hybrid_ϕq(approx, θP, θM, transP; n_site, transM) +(;ϕqc, approx) = init_hybrid_ϕq(approx, θP, θM, transP; n_site, transM) -prob = HybridProblem(θM, ϕq0, g_chain_scaled, ϕg0, +prob = HybridProblem(θM, ϕqc, g_chain_scaled, ϕg0, f_batch, priors_dict, py, transM, transP, train_dataloader, test_data,n_covar, n_site, n_batch; approx) ``` diff --git a/src/DoubleMM/f_doubleMM.jl b/src/DoubleMM/f_doubleMM.jl index f7f8123..9eff58d 100644 --- a/src/DoubleMM/f_doubleMM.jl +++ b/src/DoubleMM/f_doubleMM.jl @@ -215,7 +215,7 @@ function HVI.get_hybridproblem_MLapplicator( g = if (:use_rangescaling ∈ scen) RangeScalingModelApplicator(g_nomag, lowers, uppers, eltype(ϕ_g0)) else - NormalScalingModelApplicator(g_nomag, lowers, uppers, eltype(ϕ_g0)) + NormalScalingModelApplicator(g_nomag, lowers, uppers, eltype(ϕ_g0)) end return g, ϕ_g0 end @@ -419,9 +419,9 @@ function HVI.get_hybridproblem_ϕq(prob::DoubleMMCase; scenario::Val{scen}) wher (;θP, θM) = get_hybridproblem_par_templates(prob; scenario) n_site, _ = get_hybridproblem_n_site_and_batch(prob; scenario) (;transP, transM) = get_hybridproblem_transforms(prob; scenario) - ϕunc = init_hybrid_ϕunc(approx, cor_ends, zero(FT); θM, transM, n_site) + (;ϕqc, approx) = tmp = init_hybrid_ϕunc(approx, cor_ends, zero(FT); θM, transM, n_site) # for DoubleMMCase templates gives the correct values - ϕq = HVI.update_μP_by_θP(ϕunc, θP, transP) + ϕqP = HVI.update_μP_by_θP(ϕqc, θP, transP) end @@ -432,7 +432,8 @@ end function HVI.get_hybridproblem_HVIApproximation(prob::DoubleMMCase; scenario::Val{scen}) where {scen} approx = if (:scalingall ∈ scen) (;θP, θM) = get_hybridproblem_par_templates(prob; scenario) - MeanHVIApproximationMat([length(θM)]) + FT = eltype(θM) + MeanScalingHVIApproximation([length(θM)],FT(2) .* log.([FT(0.1) * θM[end]])) elseif (:sepvar ∈ scen) MeanVarSepHVIApproximation() else diff --git a/src/HVIApproximation.jl b/src/HVIApproximation.jl index 04598ca..77748ed 100644 --- a/src/HVIApproximation.jl +++ b/src/HVIApproximation.jl @@ -32,8 +32,15 @@ struct MeanVarSepHVIApproximation <: AbstractMeanVarSepHVIApproximation end abstract type AbstractMeanScalingHVIApproximation <: AbstractHVIApproximation end -struct MeanScalingHVIApproximation <: AbstractMeanScalingHVIApproximation +struct MeanScalingHVIApproximation{T} <: AbstractMeanScalingHVIApproximation scalingblocks_ends::Vector{Int} + logσ2_ζM_base::Vector{T} +end +function MeanScalingHVIApproximation{T}(approx::AbstractMeanScalingHVIApproximation; + scalingblocks_ends = approx.scalingblocks_ends, + logσ2_ζM_base = approx.logσ2_ζM_base, +) where T + MeanScalingHVIApproximation{T}(scalingblocks_ends, logσ2_ζM_base) end function get_numberof_MLinputs(approx::MeanScalingHVIApproximation, θM) length(θM) + length(approx.scalingblocks_ends) diff --git a/src/HybridProblem.jl b/src/HybridProblem.jl index ab254d1..d7a6cc6 100644 --- a/src/HybridProblem.jl +++ b/src/HybridProblem.jl @@ -88,8 +88,9 @@ function init_hybrid_ϕq( kwargs..., ) FT = promote_type(eltype(θP), eltype(θM)) - ϕunc0 = init_hybrid_ϕunc(approx, cor_ends, zero(FT); θM, n_site, kwargs...) - ϕq = update_μP_by_θP(ϕunc0, θP, transP) + (;ϕqc, approx) = init_hybrid_ϕunc(approx, cor_ends, zero(FT); θM, n_site, kwargs...) + ϕqP = update_μP_by_θP(ϕqc, θP, transP) + (;ϕqc = ϕqP, approx) end @@ -137,8 +138,8 @@ function update_hybridProblem(prob::AbstractHybridProblem; scenario, ) cor_ends_new = if !isnothing(cor_ends) # if new cor_ends was specified then re-initialize the ρsP and ρsM in ϕq - ϕunc0 = init_hybrid_ϕunc(approx, cor_ends, zero(eltype(ϕq)); θM, transM) - ϕq = CA.ComponentVector(;ϕq..., ρsP = ϕunc0.ρsP, ρsM = ϕunc0.ρsM) + (;ϕqc) = init_hybrid_ϕunc(approx, cor_ends, zero(eltype(ϕq)); θM, transM) + ϕq = CA.ComponentVector(;ϕq..., ρsP = ϕqc.ρsP, ρsM = ϕqc.ρsM) cor_ends else get_hybridproblem_cor_ends(prob; scenario) diff --git a/src/ModelApplicator.jl b/src/ModelApplicator.jl index 65642ff..e360ea4 100644 --- a/src/ModelApplicator.jl +++ b/src/ModelApplicator.jl @@ -116,17 +116,26 @@ of the wrapped `app` by scalar `y0`. struct MagnitudeModelApplicator{M,A} <: AbstractModelApplicator app::A multiplier::M + range_scaled::UnitRange{Int} end +@functor MagnitudeModelApplicator (app, multiplier) +function MagnitudeModelApplicator(app::AbstractModelApplicator, multiplier; range_scaled = 1:0) + MagnitudeModelApplicator(app, multiplier, range_scaled) +end function apply_model(app::MagnitudeModelApplicator, x, ϕ; kwargs...) #@show size(x), size(ϕ), app.multiplier @assert eltype(app.multiplier) == eltype(ϕ) - apply_model(app.app, x, ϕ; kwargs...) .* app.multiplier + if !isempty(app.range_scaled) + res = apply_model(app.app, x, ϕ; kwargs...) + res_scaled = res[app.range_scaled] .* app.multiplier + combine_range(res, res_scaled, app.range_scaled) + else + apply_model(app.app, x, ϕ; kwargs...) .* app.multiplier + end end - - """ NormalScalingModelApplicator(app, μ, σ) NormalScalingModelApplicator(app, priors, transM) @@ -149,8 +158,9 @@ struct NormalScalingModelApplicator{VF,A} <: AbstractModelApplicator app::A μ::VF σ::VF + range_scaled::UnitRange{Int} end -@functor NormalScalingModelApplicator +@functor NormalScalingModelApplicator (app, μ, σ) """ NormalScalingModelApplicator(app, lowers, uppers, FT::Type; repeat_inner::Integer = 1) @@ -165,6 +175,7 @@ It usually corresponds to the type used in other ML-parts of the model, e.g. `Fl """ function NormalScalingModelApplicator( app::AbstractModelApplicator, lowers, uppers, FT::Type; + range_scaled = 1:0, repeat_inner::Integer = 1) pars = map(lowers, uppers) do lower, upper dζ = fit(Normal, @qp_l(lower), @qp_u(upper)) @@ -173,7 +184,29 @@ function NormalScalingModelApplicator( # use collect to make it an array that works with gpu μ = repeat(collect(FT, first.(pars)); inner=(repeat_inner,)) σ = repeat(collect(FT, last.(pars)); inner=(repeat_inner,)) - NormalScalingModelApplicator(app, μ, σ) + app = if isempty(range_scaled) || (repeat_inner == 1) + NormalScalingModelApplicator(app, μ, σ, range_scaled) + else + error("debug and implement NormalScalingModelApplicator with repeated blocks, e.g. for multivariate normal distribution with independent components") + range_scaled_rep = repeat(range_scaled, inner=repeat_inner) + app_sub = NormalScalingModelApplicator(app, μ, σ, range_scaled_rep[2:end]) + NormalScalingModelApplicator(app_sub, μ, σ, range_scaled_rep[2:end]) + end +end + +function NormalScalingModelApplicator( + app::AbstractModelApplicator, μ, σ; + range_scaled = 1:0, # empty range indicates rescaling all outputs + repeat_inner::Integer = 1) + pars = map(lowers, uppers) do lower, upper + dζ = fit(Normal, @qp_l(lower), @qp_u(upper)) + params(dζ) + end + # use collect to make it an array that works with gpu + μ = repeat(collect(FT, first.(pars)); inner=(repeat_inner,)) + σ = repeat(collect(FT, last.(pars)); inner=(repeat_inner,)) + range_scaled_rep = repeat(range_scaled, inner=repeat_inner) + NormalScalingModelApplicator(app, μ, σ, range_scaled_rep) end function apply_model(app::NormalScalingModelApplicator, x, ϕ; kwargs...) @@ -181,14 +214,18 @@ function apply_model(app::NormalScalingModelApplicator, x, ϕ; kwargs...) # @show typeof(app.μ) # @show typeof(ϕ) @assert eltype(app.μ) == eltype(ϕ) - ans = norminvcdf.(app.μ, app.σ, y_perc) # from StatsFuns + ans = if !isempty(app.range_scaled) + ans_scaled = norminvcdf.(app.μ, app.σ, y_perc[app.range_scaled]) # from StatsFuns + combine_range(y_perc, ans_scaled, app.range_scaled) + else + ans_scaled = norminvcdf.(app.μ, app.σ, y_perc) + end # if !all(isfinite.(ans)) # @info "NormalScalingModelApplicator.apply_model: encountered non-finite results" # #@show ans, y_perc, app.μ, app.σ # #@show app.app, x, ϕ # #error("error to print stacktrace") # end - ans end """ @@ -201,26 +238,43 @@ struct RangeScalingModelApplicator{VF,A} <: AbstractModelApplicator offset::VF width::VF app::A + range_scaled::UnitRange{Int} end function apply_model(app::RangeScalingModelApplicator, x, ϕ; kwargs...) res0 = apply_model(app.app, x, ϕ; kwargs...) - res0 .* app.width .+ app.offset + if !isempty(app.range_scaled) + res_scaled = res0[app.range_scaled] .* app.width .+ app.offset + combine_range(res0, res_scaled, app.range_scaled) + else + res0 .* app.width .+ app.offset + end +end + +function combine_range(res0, res_scaled, range_scaled) + range_before = 1:(range_scaled[1]-1) + range_after = (range_scaled[end]+1):length(res0) + vcat(res0[range_before], res_scaled, res0[range_after]) end + + """ RangeScalingModelApplicator(app, lowers, uppers, FT::Type; repeat_inner::Integer = 1) Provide the target ragen by vectors `lower` and `upper`. The size of both outputs must correspond to the size of the output of `app`. + """ function RangeScalingModelApplicator( app::AbstractModelApplicator, lowers::VT, uppers::VT, - FT::Type) where VT<:AbstractVector + FT::Type; + range_scaled = 1:0 + ) where VT<:AbstractVector width = collect(FT, uppers .- lowers) lowersFT = collect(FT, lowers) # convert eltype - RangeScalingModelApplicator(lowersFT, width, app) + RangeScalingModelApplicator(lowersFT, width, app, range_scaled) end diff --git a/src/elbo_scaling.jl b/src/elbo_scaling.jl index 3fe4e04..285ed8b 100644 --- a/src/elbo_scaling.jl +++ b/src/elbo_scaling.jl @@ -2,7 +2,7 @@ # but ML model predicts a scaling factor for a group of variance parameters # ϕq element logσ2_ζM_offsets contains a vector of log-offsets, i.e. multipliers, # for each block of ML scaled parameters -# the log-offset for the first entry in each block is 0 +# the log-offset for the last entry in each block is stored in approx.logσ2_ζM_base function sample_ζresid_norm(approx::AbstractMeanScalingHVIApproximation, i_sites, @@ -12,6 +12,7 @@ function sample_ζresid_norm(approx::AbstractMeanScalingHVIApproximation, cor_ends ) where {T,TM<:AbstractMatrix{T}} ϕuncc = ϕqc = int_ϕq(CA.getdata(ϕq)) + logσ2_ζM_base = approx.logσ2_ζM_base logσ2_par_offsets2 = ϕqc[Val(:logσ2_ζM_offsets)] n_scale_blocks = length(logσ2_par_offsets2) length_scale_blocks = length.(logσ2_par_offsets2) .+ 1 diff --git a/src/init_hybrid_params.jl b/src/init_hybrid_params.jl index c429e5a..6f004bb 100644 --- a/src/init_hybrid_params.jl +++ b/src/init_hybrid_params.jl @@ -94,7 +94,11 @@ Arguments: - `ρ0`: default entry for ρsP and ρsM, defaults = 0f0. - `coef_logσ2_logM`: default column for `coef_logσ2_ζMs`, defaults to `[-10.0, 0.0]` -Returns a `ComponentVector` of +Returns a Tuple of +- `ϕqc::ComponentVector`: parameters of the posterior approximation +- `approx`: possibly updated Approximation + +For MeanHVIApproximation, `ϕqc` contains components - `logσ2_ζP`: vector of log-variances of ζP (on log scale). defaults to -10 - `coef_logσ2_ζMs`: offset and slope for the log-variances of ζM scaling with @@ -121,7 +125,7 @@ function init_hybrid_ϕunc( coef_logσ2_ζMs, ρsP, ρsM) - ca = CA.ComponentVector(;nt...)::CA.ComponentVector + (; ϕqc = CA.ComponentVector(;nt...)::CA.ComponentVector, approx) end function init_hybrid_ϕunc( @@ -149,7 +153,7 @@ function init_hybrid_ϕunc( logσ2_ζMs, ρsP, ρsM) - ca = CA.ComponentVector(;nt...)::CA.ComponentVector + (; ϕqc = CA.ComponentVector(;nt...)::CA.ComponentVector, approx) end function compute_σ_unconstrained(transM::Stacked, θM, rel_err) @@ -175,3 +179,40 @@ end # end # end + +function init_hybrid_ϕunc( + approx::SApp, + cor_ends::NamedTuple, + ρ0::FT = 0.0f0, + logσ2_ζMs::AbstractMatrix{FT} = Array{FT}(undef, 0, 0), + logσ2_ζP::AbstractVector{FT} = fill(FT(-10.0), cor_ends.P[end]), + ρsP = fill(ρ0, get_cor_count(cor_ends.P)), + ρsM = fill(ρ0, get_cor_count(cor_ends.M)); + transM, + θM::CA.ComponentVector, + n_site::Integer, + relerr = 0.01, +) where {FT, SApp <: MeanScalingHVIApproximation} + logσ2 = if isempty(logσ2_ζMs) + # relative error of the template of θM + σ = compute_σ_unconstrained(transM, CA.getdata(θM), relerr) + logσ2 = FT(2) * log.(convert.(FT,σ)) + else + error("check and implement inferring median logσ2 from logσ2_ζMs") + median(logσ2_ζMs; dims=1) + end + is_end = approx.scalingblocks_ends # abbreviations + # update logσ2_ζM_base of last parameter in approx - its not calibrated + approx = SApp(approx; logσ2_ζM_base = logσ2[is_end]) + is_offset = range.(vcat(1,is_end[1:(end-1)]),(is_end .- 1)) # excluding last parameter + logσ2_ζM_offsets = map(is_end, is_offset) do i_end, is_offset + logσ2[is_offset] .- logσ2[i_end] + end + nt = (; + logσ2_ζP, + logσ2_ζM_offsets, + ρsP, + ρsM) + (; ϕqc = CA.ComponentVector(;nt...)::CA.ComponentVector, approx) +end + diff --git a/test/test_HybridProblem.jl b/test/test_HybridProblem.jl index 0a3d700..9bca70a 100644 --- a/test/test_HybridProblem.jl +++ b/test/test_HybridProblem.jl @@ -102,8 +102,8 @@ function construct_problem(; scenario::Val{scen}) where scen f_batch = PBMSiteApplicator( f_doubleMM; θP, θM, θFix=CA.ComponentVector{FT}(), xPvec=xP[:,1]) - ϕunc0 = init_hybrid_ϕunc(MeanHVIApproximation(), cor_ends, zero(FT); θM, transM, n_site) - ϕq = CP.update_μP_by_θP(ϕunc0, θP, transP) + (; ϕqc, approx) = init_hybrid_ϕunc(approx, cor_ends, zero(FT); θM, transM, n_site) + ϕq = CP.update_μP_by_θP(ϕqc, θP, transP) HybridProblem(θM, ϕq, g_chain_scaled, ϕg0, f_batch, priors_dict, py, transM, transP, train_dataloader, test_data, n_site, n_batch; diff --git a/test/test_ModelApplicator.jl b/test/test_ModelApplicator.jl index 70521e6..f5ed231 100644 --- a/test/test_ModelApplicator.jl +++ b/test/test_ModelApplicator.jl @@ -25,12 +25,23 @@ end; @test y == c1 .* m end; +@testset "MagnitudeModelApplicator subset" begin + app = NullModelApplicator() + c1 = CA.ComponentVector(a = (a1 = 1, a2 = 2:3), b = 3:4) + range_scaled = 2:3 + m = 2 + g = MagnitudeModelApplicator(app, m; range_scaled) + y = g(c1, eltype(m)[]) + @test y[range_scaled] == c1[range_scaled] .* m + @test y[1:end .∉ Ref(range_scaled)] == c1[1:end .∉ Ref(range_scaled)] +end; + @testset "NormalScalingModelApplicator" begin app = NullModelApplicator() r = logistic.(randn(5)) # 0..1 σ = fill(2.0, 5) μ = collect(exp.(1.0:5.0)) # different magnitudes - g = NormalScalingModelApplicator(app, μ, σ) + g = NormalScalingModelApplicator(app, μ, σ, 1:0) y = g(r, eltype(μ)[]) p = normcdf.(μ, σ, y) #hcat(r, p) @@ -45,6 +56,28 @@ end; end end; +@testset "NormalScalingModelApplicator subset" begin + app = NullModelApplicator() + r = logistic.(randn(10)) # 0..1 + σ = fill(2.0, 5) + μ = collect(exp.(1.0:5.0)) # different magnitudes + range_scaled = 2 .+ (1:length(σ)) + g = NormalScalingModelApplicator(app, μ, σ, range_scaled) + y = g(r, eltype(μ)[]) + p = normcdf.(μ, σ, y[range_scaled]) + #hcat(r, p) + @test p ≈ r[range_scaled] + @test y[1:end .∉ Ref(range_scaled)] == r[1:end .∉ Ref(range_scaled)] + #cdev = cpu_device() + if gdev isa MLDataDevices.AbstractGPUDevice + g_gpu = g |> gdev + @test g_gpu.μ isa GPUArraysCore.AbstractGPUArray + r_gpu = r |> gdev + y = g_gpu(r_gpu, eltype(g_gpu.μ)[]) + @test y isa GPUArraysCore.AbstractGPUArray + end +end; + @testset "RangeScalingModelApplicator" begin app = NullModelApplicator() r = logistic.(randn(Float32, 5)) # 0..1 @@ -66,3 +99,28 @@ end; @test cdev(y_dev) ≈ y end end; + +@testset "RangeScalingModelApplicator subset" begin + app = NullModelApplicator() + r = logistic.(randn(Float32, 10)) # 0..1 + lowers = collect(exp.(1.0:5.0)) # different magnitudes + uppers = lowers .* 2 + range_scaled = 2 .+ (1:length(lowers)) + g = RangeScalingModelApplicator(app, lowers, uppers, eltype(r); range_scaled) + y = @inferred g(r, []) + width = uppers .- lowers + @test y[range_scaled] ≈ (r[range_scaled] .* width .+ lowers) + @test eltype(y) == eltype(r) + @test y[1:end .∉ Ref(range_scaled)] == r[1:end .∉ Ref(range_scaled)] + #cdev = cpu_device() + if gdev isa MLDataDevices.AbstractGPUDevice + g_gpu = g |> gdev + @test g_gpu.offset isa GPUArraysCore.AbstractGPUArray + @test g_gpu.width isa GPUArraysCore.AbstractGPUArray + r_gpu = r |> gdev + y_dev = g_gpu(r_gpu, []) + @test y_dev isa GPUArraysCore.AbstractGPUArray + @test cdev(y_dev) ≈ y + end +end; + diff --git a/test/test_elbo.jl b/test/test_elbo.jl index adb903a..668fd57 100644 --- a/test/test_elbo.jl +++ b/test/test_elbo.jl @@ -25,14 +25,21 @@ ggdev = gpu_device() rng = StableRNG(111) const prob = DoubleMM.DoubleMMCase() +scenario = Val((:covarK2,)) +scenario = Val((:scalingall,)) +scenario = Val((:sepvar,)) scenario = Val((:default,)) -#scenario = Val((:covarK2,)) +pt = get_hybridproblem_par_templates(prob; scenario) +FT = eltype(pt.θM) #approx = MeanHVIApproximationMat() #approx = MeanVarSepHVIApproximation() +#approx = MeanScalingHVIApproximation([length(pt.θM)], FT(2) .* log.([FT(0.1) * pt.θM[end]])) -test_scenario = (scenario, approx) -> begin - probc = HybridProblem(prob; scenario, approx); +test_scenario = (scenario) -> begin + #probc = HybridProblem(prob; scenario, approx); + probc = HybridProblem(prob; scenario); + #@assert typeof(probc.approx) == typeof(approx) FT = get_hybridproblem_float_type(probc; scenario) par_templates = get_hybridproblem_par_templates(probc; scenario) int_P, int_M = map(ComponentArrayInterpreter, par_templates) @@ -74,10 +81,11 @@ test_scenario = (scenario, approx) -> begin # transP = elementwise(exp) # transM = Stacked(elementwise(identity), elementwise(exp)) #transM = Stacked(elementwise(identity), elementwise(exp), elementwise(exp)) # test mismatch - ϕq0 = init_hybrid_ϕq(approx, par_templates.θP, par_templates.θM, transP, cor_ends; transM, n_site) - # ϕunc0 = init_hybrid_ϕunc(cor_ends, zero(FT)) + (;ϕqc, approx) = tmp = init_hybrid_ϕq(probc.approx, par_templates.θP, par_templates.θM, transP, cor_ends; transM, n_site) + probc = HybridProblem(probc; approx) # update approx in probc + # (ϕunc0, approx) = init_hybrid_ϕunc(cor_ends, zero(FT)) # ϕq0 = CP.update_μP_by_θP(ϕunc0, θP_true, transP) - (; ϕ, interpreters) = init_hybrid_params(ϕg0, ϕq0) + (; ϕ, interpreters) = init_hybrid_params(ϕg0, ϕqc) int_ϕq = interpreters.ϕq int_ϕg_ϕq = interpreters.ϕg_ϕq ϕ_ini = ϕ @@ -98,7 +106,7 @@ test_scenario = (scenario, approx) -> begin ζsP, ζsMs_tr, σ = @inferred ( # @descend_code_warntype ( CP.generate_ζ( - approx, rng, g, ϕ_ini, xM[:, i_sites]; + probc.approx, rng, g, ϕ_ini, xM[:, i_sites]; n_MC, cor_ends, pbm_covar_indices, i_sites, int_ϕq=interpreters.ϕq, int_ϕg_ϕq=interpreters.ϕg_ϕq, is_testmode = false) @@ -116,7 +124,7 @@ test_scenario = (scenario, approx) -> begin gr = Zygote.gradient( ϕ -> begin _ζsP, _ζsMs_tr, _σ = CP.generate_ζ( - approx, rng, g, ϕ, xM[:, i_sites]; + probc.approx, rng, g, ϕ, xM[:, i_sites]; i_sites, n_MC=8, cor_ends, pbm_covar_indices, int_ϕq=interpreters.ϕq, int_ϕg_ϕq=interpreters.ϕg_ϕq, @@ -163,7 +171,7 @@ test_scenario = (scenario, approx) -> begin _ζsP, _ζsMs_tr, _σ = @inferred ( # @descend_code_warntype ( CP.generate_ζ( - approx, rng, g, _ϕ, xM_batch; + probc.approx, rng, g, _ϕ, xM_batch; i_sites, n_MC = n_predict, cor_ends, pbm_covar_indices, int_ϕq=interpreters.ϕq, int_ϕg_ϕq=interpreters.ϕg_ϕq, @@ -250,7 +258,7 @@ test_scenario = (scenario, approx) -> begin ζsP_d, ζsMs_tr_d, σ_d = @inferred ( # @descend_code_warntype ( CP.generate_ζ( - approx, rng, g_gpu, ϕ, xMg_batch; + probc.approx, rng, g_gpu, ϕ, xMg_batch; i_sites, n_MC, cor_ends, pbm_covar_indices, int_ϕq=interpreters.ϕq, int_ϕg_ϕq=interpreters.ϕg_ϕq, @@ -265,7 +273,7 @@ test_scenario = (scenario, approx) -> begin gr = Zygote.gradient( ϕ -> begin _ζsP, _ζsMs_tr, _σ = CP.generate_ζ( - approx, rng, g_gpu, ϕ, xMg_batch; + probc.approx, rng, g_gpu, ϕ, xMg_batch; i_sites, n_MC, cor_ends, pbm_covar_indices, int_ϕq=interpreters.ϕq, int_ϕg_ϕq=interpreters.ϕg_ϕq, @@ -359,7 +367,7 @@ test_scenario = (scenario, approx) -> begin cor_ends, pbm_covar_indices, transP, transMs, priorsP, priorsM, is_testmode = true, is_omit_priors = Val(false), zero_prior_logdensity=zero(eltype(ϕ_ini)), - approx, intθMs, intθP = int_P + probc.approx, intθMs, intθP = int_P ) ) #@test cost isa Float64 @@ -371,7 +379,7 @@ test_scenario = (scenario, approx) -> begin cor_ends, pbm_covar_indices, transP, transMs, priorsP, priorsM, is_testmode = false, is_omit_priors = Val(false), zero_prior_logdensity=zero(eltype(ϕ_ini)), - approx, intθMs, intθP = int_P + probc.approx, intθMs, intθP = int_P ), CA.getdata(ϕ_ini)) @test gr[1] isa Vector @@ -392,7 +400,7 @@ test_scenario = (scenario, approx) -> begin n_MC=3, cor_ends, pbm_covar_indices, transP, transMs, priorsP, priorsM, is_testmode = true, is_omit_priors = Val(false), zero_prior_logdensity=zero(eltype(ϕ_ini)), - approx, + probc.approx, ) ) @test cost isa Float64 @@ -403,7 +411,7 @@ test_scenario = (scenario, approx) -> begin n_MC=3, cor_ends, pbm_covar_indices, transP, transMs, priorsP, priorsM, is_testmode = false, is_omit_priors = Val(false), zero_prior_logdensity=zero(eltype(ϕ_ini)), - approx, + probc.approx, ), ϕ) @test gr[1] isa GPUArraysCore.AbstractGPUVector @@ -427,7 +435,7 @@ test_scenario = (scenario, approx) -> begin cdev = identity, n_sample_pred, cor_ends, pbm_covar_indices, is_testmode = true, - approx, + probc.approx, ) ) @test θsP isa AbstractMatrix @@ -456,7 +464,7 @@ test_scenario = (scenario, approx) -> begin cdev = identity, # do not transfer to CPU n_sample_pred, cor_ends, pbm_covar_indices, is_testmode = true, - approx, + probc.approx, ) ) # this variant without the problem, does not attach axes @@ -500,8 +508,10 @@ test_scenario = (scenario, approx) -> begin end # test_scenario -test_scenario(Val((:default,)), MeanHVIApproximationMat()) -test_scenario(Val((:default,)), MeanVarSepHVIApproximation()) +test_scenario(Val((:default,))) +test_scenario(Val((:default, :sepvar,))) +#test_scenario(Val((:default, :scalingall,)), MeanScalingHVIApproximation([length(pt.θM)])) # with providing process parameter as additional covariate -test_scenario(Val((:covarK2,)), MeanHVIApproximationMat()) +test_scenario(Val((:covarK2,))) + From 81ae48fdc060f27d822d85d40a25e3f310e8b6cd Mon Sep 17 00:00:00 2001 From: Thomas Wutzler Date: Wed, 1 Apr 2026 20:57:28 +0000 Subject: [PATCH 07/31] working on AbstractMeanScalingHVIApproximation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit need to change ϕqc.logσ2_ζM_offsets from nested vector plain vector and reconstruction of inserting zeros Interesting session with chatbot to implement performant insert_zeros. --- Project.toml | 3 +- src/DoubleMM/f_doubleMM.jl | 9 ++- src/HVIApproximation.jl | 27 +++++++- src/HybridProblem.jl | 4 +- src/HybridVariationalInference.jl | 1 + src/ModelApplicator.jl | 16 +++-- src/elbo.jl | 18 ++++-- src/elbo_scaling.jl | 26 ++++---- src/init_hybrid_params.jl | 10 ++- src/util.jl | 102 ++++++++++++++++++++++++++++++ test/test_ModelApplicator.jl | 26 ++++++++ test/test_elbo.jl | 6 +- test/test_util.jl | 15 ++++- 13 files changed, 225 insertions(+), 38 deletions(-) diff --git a/Project.toml b/Project.toml index ca5cd0d..2667643 100644 --- a/Project.toml +++ b/Project.toml @@ -16,6 +16,7 @@ Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b" Functors = "d9f16b24-f501-4c13-a1f2-28368ffc5196" GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" +IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e" KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" LogExpFunctions = "2ab3a3ac-af41-5b50-aa03-7779005ae688" @@ -46,7 +47,6 @@ HybridVariationalInferenceFluxExt = "Flux" HybridVariationalInferenceLuxExt = "Lux" HybridVariationalInferenceSimpleChainsExt = "SimpleChains" -# require Optimization 5.3 do deal with NaN gradients [compat] Bijectors = "0.14, 0.15" BlockDiagonals = "0.1.42, 0.2" @@ -62,6 +62,7 @@ FillArrays = "1.13.0" Flux = "0.14, 0.15, 0.16" Functors = "0.4, 0.5" GPUArraysCore = "0.1, 0.2" +IterTools = "1.10.0" KernelAbstractions = "0.9.34" LinearAlgebra = "1.10" LogExpFunctions = "0.3.29" diff --git a/src/DoubleMM/f_doubleMM.jl b/src/DoubleMM/f_doubleMM.jl index 9eff58d..5341a17 100644 --- a/src/DoubleMM/f_doubleMM.jl +++ b/src/DoubleMM/f_doubleMM.jl @@ -212,10 +212,15 @@ function HVI.get_hybridproblem_MLapplicator( (; transM) = get_hybridproblem_transforms(prob; scenario) lowers, uppers = HVI.get_quantile_transformed(priors, transM) #n_site, n_batch = get_hybridproblem_n_site_and_batch(prob; scenario) + range_scaled = if (:scalingall ∈ scen) + 1:length(θM) + else + 1:0 + end g = if (:use_rangescaling ∈ scen) - RangeScalingModelApplicator(g_nomag, lowers, uppers, eltype(ϕ_g0)) + RangeScalingModelApplicator(g_nomag, lowers, uppers, eltype(ϕ_g0); range_scaled) else - NormalScalingModelApplicator(g_nomag, lowers, uppers, eltype(ϕ_g0)) + NormalScalingModelApplicator(g_nomag, lowers, uppers, eltype(ϕ_g0); range_scaled) end return g, ϕ_g0 end diff --git a/src/HVIApproximation.jl b/src/HVIApproximation.jl index 77748ed..2eabd16 100644 --- a/src/HVIApproximation.jl +++ b/src/HVIApproximation.jl @@ -5,11 +5,20 @@ Provides a type hierarchy to distinguish different forms and parameterizations of posterior approximations. Subtypes must implement method `get_numberof_MLinputs(approx, θM)` that -returns the numberof required outputs of the machine learning model +returns the number of required outputs of the machine learning model per site for a parameter vector `θM`. + +Subtypes must implement method +`get_numberof_θM(::AbstractHVIApproximation, ml_pred::AbstractArray)` that +returns the number compponents mean parameters `θM` given the machine learning +model predictions, if it differs from the default implementation of +returning their number of rows. +For example, [`MeanScalingHVIApproximation`](@ref) there are more outputs than +the mean parameters with the ML model. """ abstract type AbstractHVIApproximation end, function get_numberof_MLinputs end +get_numberof_θM(::AbstractHVIApproximation, ml_pred::AbstractArray) = size(ml_pred,1) abstract type AbstractMeanHVIApproximation <: AbstractHVIApproximation end get_numberof_MLinputs(::AbstractMeanHVIApproximation, θM) = length(θM) @@ -32,6 +41,17 @@ struct MeanVarSepHVIApproximation <: AbstractMeanVarSepHVIApproximation end abstract type AbstractMeanScalingHVIApproximation <: AbstractHVIApproximation end +""" + MeanScalingHVIApproximation(scalingblocks_ends, logσ2_ζM_base) + +An approximation that requires the ML model to predict a scaling factor, +(i.e. an additive of the log) for +the mean diagonal of the covariance matrix per site in addition to +the mean values of parameters in unconstrained space. + +TODO: describe multiplication of site-factor, parameter-factor and base_variance +for each parameter. +""" struct MeanScalingHVIApproximation{T} <: AbstractMeanScalingHVIApproximation scalingblocks_ends::Vector{Int} logσ2_ζM_base::Vector{T} @@ -45,3 +65,8 @@ end function get_numberof_MLinputs(approx::MeanScalingHVIApproximation, θM) length(θM) + length(approx.scalingblocks_ends) end +function get_numberof_θM(approx::MeanScalingHVIApproximation, ml_pred::AbstractArray) + # scalingblocks_ends reports the end position of the parameters, hence, the last + # corresponds to the number of overall parameters. + approx.scalingblocks_ends[end] +end diff --git a/src/HybridProblem.jl b/src/HybridProblem.jl index d7a6cc6..78b975f 100644 --- a/src/HybridProblem.jl +++ b/src/HybridProblem.jl @@ -79,7 +79,7 @@ end Initialize the non-ML parameter vector. """ function init_hybrid_ϕq( - approx::Union{AbstractMeanHVIApproximation, AbstractMeanVarSepHVIApproximation}, + approx::AbstractHVIApproximation, θP::CA.ComponentVector, θM::CA.ComponentVector, transP::Stacked, @@ -94,8 +94,6 @@ function init_hybrid_ϕq( end - - """ create_ϕq(θP, ϕunc, transP::Stacked) diff --git a/src/HybridVariationalInference.jl b/src/HybridVariationalInference.jl index 24fd209..7405c0c 100644 --- a/src/HybridVariationalInference.jl +++ b/src/HybridVariationalInference.jl @@ -28,6 +28,7 @@ using KernelAbstractions import NaNMath # ignore missing observations in logDensity using DifferentiationInterface: DifferentiationInterface as DI import Zygote +using IterTools: IterTools export DoubleMM diff --git a/src/ModelApplicator.jl b/src/ModelApplicator.jl index e360ea4..6304662 100644 --- a/src/ModelApplicator.jl +++ b/src/ModelApplicator.jl @@ -128,7 +128,7 @@ function apply_model(app::MagnitudeModelApplicator, x, ϕ; kwargs...) @assert eltype(app.multiplier) == eltype(ϕ) if !isempty(app.range_scaled) res = apply_model(app.app, x, ϕ; kwargs...) - res_scaled = res[app.range_scaled] .* app.multiplier + res_scaled = index_firstdim(res,app.range_scaled) .* app.multiplier combine_range(res, res_scaled, app.range_scaled) else apply_model(app.app, x, ϕ; kwargs...) .* app.multiplier @@ -137,7 +137,7 @@ end """ - NormalScalingModelApplicator(app, μ, σ) + NormalScalingModelApplicator(app, μ, σ; range_scaled=1:0) NormalScalingModelApplicator(app, priors, transM) Wrapper around AbstractModelApplicator that transforms each output @@ -209,13 +209,14 @@ function NormalScalingModelApplicator( NormalScalingModelApplicator(app, μ, σ, range_scaled_rep) end + function apply_model(app::NormalScalingModelApplicator, x, ϕ; kwargs...) y_perc = apply_model(app.app, x, ϕ; kwargs...) # @show typeof(app.μ) # @show typeof(ϕ) @assert eltype(app.μ) == eltype(ϕ) ans = if !isempty(app.range_scaled) - ans_scaled = norminvcdf.(app.μ, app.σ, y_perc[app.range_scaled]) # from StatsFuns + ans_scaled = norminvcdf.(app.μ, app.σ, index_firstdim(y_perc,app.range_scaled)) # from StatsFuns combine_range(y_perc, ans_scaled, app.range_scaled) else ans_scaled = norminvcdf.(app.μ, app.σ, y_perc) @@ -228,6 +229,9 @@ function apply_model(app::NormalScalingModelApplicator, x, ϕ; kwargs...) # end end +index_firstdim(v::AbstractVector, i) = v[i] +index_firstdim(v::AbstractMatrix, i) = v[i,:] + """ RangeScalingModelApplicator(app, y0) @@ -244,7 +248,7 @@ end function apply_model(app::RangeScalingModelApplicator, x, ϕ; kwargs...) res0 = apply_model(app.app, x, ϕ; kwargs...) if !isempty(app.range_scaled) - res_scaled = res0[app.range_scaled] .* app.width .+ app.offset + res_scaled = index_firstdim(res0,app.range_scaled) .* app.width .+ app.offset combine_range(res0, res_scaled, app.range_scaled) else res0 .* app.width .+ app.offset @@ -253,8 +257,8 @@ end function combine_range(res0, res_scaled, range_scaled) range_before = 1:(range_scaled[1]-1) - range_after = (range_scaled[end]+1):length(res0) - vcat(res0[range_before], res_scaled, res0[range_after]) + range_after = (range_scaled[end]+1):size(res0,1) + vcat(index_firstdim(res0,range_before), res_scaled, index_firstdim(res0,range_after)) end diff --git a/src/elbo.jl b/src/elbo.jl index 5d1ee4b..4ed7926 100644 --- a/src/elbo.jl +++ b/src/elbo.jl @@ -477,7 +477,8 @@ The output shape of size `(n_site x n_par x n_MC)` is tailored to iterating each MC sample and then transforming each parameter on block across sites. """ function generate_ζ( - approx::Union{AbstractMeanHVIApproximation, AbstractMeanVarSepHVIApproximation}, + #approx::Union{AbstractMeanHVIApproximation, AbstractMeanVarSepHVIApproximation}, + approx::AbstractHVIApproximation, rng::AbstractRNG, g, ϕ::AbstractVector{FT}, xM::MT; int_ϕg_ϕq::AbstractComponentArrayInterpreter, @@ -497,15 +498,16 @@ function generate_ζ( # TODO replace pbm_covar_indices by ComponentArray? dimensions to be type-inferred? xMP0 = _append_each_covars(xM, CA.getdata(μ_ζP), pbm_covar_indices) ϕm0 = g(xMP0, ϕg; is_testmode) - μ_ζMs0 = ϕm0 + ζP_resids, ζMs_parfirst_resids, σ = sample_ζresid_norm(approx, rng, + i_sites, ϕm0, ϕq; n_MC, cor_ends, int_ϕq) + n_θm = size(ζMs_parfirst_resids, 1) + μ_ζMs0 = ϕm0[1:n_θm, :] # if !all(isfinite.(μ_ζMs0)) # @show μ_ζMs0 # is_infinte_ϕg = !all(isfinite.(ϕg)) # @show is_infinte_ϕg # error("encountered non-finite μ_ζMs0") # end - ζP_resids, ζMs_parfirst_resids, σ = sample_ζresid_norm(approx, rng, - i_sites, ϕm0, ϕq; n_MC, cor_ends, int_ϕq) ζsP = isempty(μ_ζP) ? ζP_resids : (μ_ζP .+ ζP_resids) # n_par x n_MC if pbm_covar_indices isa SA.SVector{0} # do not need to predict again but just add the residuals to μ_ζP and μ_ζMs @@ -601,7 +603,8 @@ ML-model predcitions of size `(n_θM, n_site)`. ρsP, ρsM, logσ2_ζP, coef_logσ2_ζMs(intercept + slope), """ function sample_ζresid_norm( - approx::Union{AbstractMeanHVIApproximation,AbstractMeanVarSepHVIApproximation}, + #approx::Union{AbstractMeanHVIApproximation,AbstractMeanVarSepHVIApproximation}, + approx::AbstractHVIApproximation, rng::Random.AbstractRNG, i_sites, ϕm::AbstractMatrix, ϕq::AbstractVector, @@ -609,7 +612,8 @@ function sample_ζresid_norm( n_MC, cor_ends, int_ϕq) ζP = int_ϕq(CA.getdata(ϕq))[Val(:μP)] ζMs = ϕm - n_θP, n_θMs = length(ζP), length(ζMs) + n_θP, n_θM = length(ζP), get_numberof_θM(approx,ζMs) + n_θMs = n_θM * size(ζMs,2) # intm_PMs_parfirst = !isnothing(intm_PMs_parfirst) ? intm_PMs_parfirst : begin # n_θM, n_site_batch = size(ζMs) # get_concrete(ComponentArrayInterpreter( @@ -618,7 +622,7 @@ function sample_ζresid_norm( #urandn = _create_randn(rng, CA.getdata(ζP), n_MC, n_θP + n_θMs) #z = _create_randn(rng, CA.getdata(ζP), n_MC, n_θP) zP = _create_randn(rng, CA.getdata(ζP), n_MC, n_θP) - zMs = _create_randn(rng, CA.getdata(ζP), n_MC, n_θMs) + zMs = _create_randn(rng, CA.getdata(ζP), n_MC, n_θMs) # ζP only for type inference sample_ζresid_norm(approx, i_sites, zP, zMs, CA.getdata(ϕm), ϕq, args...; cor_ends, int_ϕq=get_concrete(int_ϕq) diff --git a/src/elbo_scaling.jl b/src/elbo_scaling.jl index 285ed8b..f0663c3 100644 --- a/src/elbo_scaling.jl +++ b/src/elbo_scaling.jl @@ -12,13 +12,16 @@ function sample_ζresid_norm(approx::AbstractMeanScalingHVIApproximation, cor_ends ) where {T,TM<:AbstractMatrix{T}} ϕuncc = ϕqc = int_ϕq(CA.getdata(ϕq)) - logσ2_ζM_base = approx.logσ2_ζM_base - logσ2_par_offsets2 = ϕqc[Val(:logσ2_ζM_offsets)] - n_scale_blocks = length(logσ2_par_offsets2) - length_scale_blocks = length.(logσ2_par_offsets2) .+ 1 + # add 0 as last logσ2_par_offset-par in block + logσ2_par_offsets_before_end = ϕqc[Val(:logσ2_ζM_offsets)] + # insert zeros at the end of each block of parameters + logσ2_par_offsets = insert_zeros(logσ2_par_offsets_before_end, approx.scalingblocks_ends)::typeof(logσ2_par_offsets_before_end) + b_ends = ChainRulesCore.ignore_derivatives(approx.scalingblocks_ends) + length_scale_blocks = vcat(first(b_ends), diff(b_ends)) + n_scale_blocks = length(b_ends) n_par = size(ϕm,1) - n_scale_blocks ζMs = ϕm[1:n_par,:] - logσ2_sites = ϕm[n_par+1,:] + logσ2_sites = ϕm[(n_par+1):end,:] ζP = ϕqc[Val(:μP)] n_θP, n_θMs, (n_θM, n_batch) = length(ζP), length(ζMs), size(ζMs) # do not create a UpperTriangular Matrix of an AbgeneraGÜUArray in transformU_cholesky1 @@ -29,17 +32,14 @@ function sample_ζresid_norm(approx::AbstractMeanScalingHVIApproximation, # coefficients ρsM can be larger than 1, still yielding correlations <1 in UM' * UM UM = transformU_block_cholesky1(ρsM, cor_ends.M) # - # Expand site-level offsets to each M-parameter (row) in repeated block structure logσ2_site_offsets = repeat_rows_by_counts(logσ2_sites, length_scale_blocks) - # Expand parameter offsets to the same block structure, first scale-row is 0 - logσ2_par_offsets = vcat([repeat(vcat(zero(T), o), 1, n_batch) for o in logσ2_par_offsets2]...) - - logσ2_logMs = logσ2_par_offsets .+ logσ2_site_offsets + logσ2_ζM_bases = reduce(vcat, fill.(approx.logσ2_ζM_base, length_scale_blocks)) + logσ2_ζMs = logσ2_ζM_bases .+ logσ2_par_offsets .+ logσ2_site_offsets # logσ2_ζP = vec(CA.getdata(ϕuncc[Val(:logσ2_ζP)])) # CUDA cannot multiply BlockDiagonal * Diagonal, construct already those blocks - σMs = reshape(exp.(logσ2_logMs ./ 2), n_θM, :) - σP = exp.(logσ2_ζP ./ 2) + σMs = exp.(logσ2_ζMs ./ T(2)) + σP = exp.(logσ2_ζP ./ T(2)) # BlockDiagonal does work with CUDA, but not with combination of Zygote and CUDA # need to construct full matrix for CUDA Uσ, diagUσ = _compute_choleskyfactor(UP, UM, σP, σMs, n_batch) # inferred only BlockDiagonal @@ -64,7 +64,7 @@ end # repeat rows of a matrix by per-row counts, non-mutating (Zygote-friendly) function repeat_rows_by_counts(A::AbstractMatrix, counts::AbstractVector{<:Integer}) - @assert length(counts) == size(A,1) "Need to provide a count for each row." + @assert length(counts) == size(A,1) "Need to provide a count for each row ($counts, $(size(A,1)))." if isempty(A) return similar(A, 0, size(A,2)) end diff --git a/src/init_hybrid_params.jl b/src/init_hybrid_params.jl index 6f004bb..06c56f8 100644 --- a/src/init_hybrid_params.jl +++ b/src/init_hybrid_params.jl @@ -205,9 +205,13 @@ function init_hybrid_ϕunc( # update logσ2_ζM_base of last parameter in approx - its not calibrated approx = SApp(approx; logσ2_ζM_base = logσ2[is_end]) is_offset = range.(vcat(1,is_end[1:(end-1)]),(is_end .- 1)) # excluding last parameter - logσ2_ζM_offsets = map(is_end, is_offset) do i_end, is_offset - logσ2[is_offset] .- logσ2[i_end] - end + # need to provide plain vector and sort out positions in apply to satisfy Zygote + # logσ2_ζM_offsets = map(is_end, is_offset) do i_end, is_offset + # logσ2[is_offset] .- logσ2[i_end] + # end + logσ2_ζM_offsets_gen = (logσ2[is_offset] .- logσ2[i_end] for (i_end, is_offset) in zip(is_end, is_offset)) + logσ2_ζM_offsets = vcat(logσ2_ζM_offsets_gen...) + #tmp = CA.ComponentVector(;zip(Symbol.(axes(is_offset,1)), logσ2_ζM_offsets_gen)...) nt = (; logσ2_ζP, logσ2_ζM_offsets, diff --git a/src/util.jl b/src/util.jl index ff898d5..55413f2 100644 --- a/src/util.jl +++ b/src/util.jl @@ -34,3 +34,105 @@ function vectuptotupvec_allowmissing( allowmissing(passmissing(getindex).(vectup, i))::Vector{Tim[i]} end, npar) end + +""" + insert_zeros(v, positions) + +Return a new vector with `zero(eltype(v))` inserted at each position in `positions`. +Positions are applied in order against the growing vector (as if sequential inserts), +so later indices are interpreted on the updated result. +Only one output vector is allocated. +""" +function insert_zeros(v::AbstractVector, positions::AbstractVector{<:Integer}) + n = length(v) + m = length(positions) # number of insert positions + + # If there are no insertions, just copy and return the original vector. + if m == 0 + return collect(v) + end + + # Convert positions to an array; we can index into p in the same order. + # (This also allows `positions` to be any AbstractVector.) + p = positions + + # Validate each insertion position using the growing-vector semantics: + # after k-1 insertions, the vector length is n + k - 1, so pk must be in [1, length+1]. + for (k, pk) in enumerate(positions) + curr_len = n + k - 1 + if pk < 1 || pk > curr_len + 1 + throw(ArgumentError("insert_zeros position $pk out of bounds for length $curr_len")) + end + end + + # Map each sequential insert position to a bucket index in the final sequence, + # where 0 <= x[k] <= n (0 means before first element, n means after last element). + # Formula: p[k]-1 (zero-based insert target in original coords) minus the number of + # previously inserted positions that fall before p[k], because they shift later indexes. + x = [p[k] - 1 - count(j -> p[j] < p[k], 1:k-1) for k in 1:m] + + # zero_chain(i) yields one `zero(eltype(v))` per insertion that should occur in bucket i. + zero_chain = i -> (zero(eltype(v)) for k in 1:m if x[k] == i) + + # Build output lazily by iterating i from 0..n: + # for each i, first emit zeros for that bucket, then emit original v[i+1] when i no contribution to grad_v + # * if it's from original v[k] => add ȳ to grad_v[k] + function pullback(ȳ) + n = length(v) + m = length(positions) + + # Compute insertion buckets x[k] as in insert_zeros. + p = positions + x = [p[k] - 1 - count(j -> p[j] < p[k], 1:k-1) for k in 1:m] + + # Determine how many zeros are produced in each bucket i in 0:n. + zeros_per_bucket = zeros(Int, n + 1) + for xi in x + zeros_per_bucket[xi + 1] += 1 + end + + grad_v = zeros(eltype(v), n) + src = 1 # index in original input vector v from which gradient flows + out_idx = 1 # current index in output vector y/ȳ + + for i in 0:n + # Step past inserted zeros for this bucket (all zero insertions from insert_zeros) + # out_idx becomes the position of the next original value (if any) after zero insertions. + out_idx += zeros_per_bucket[i + 1] + + if i < n + # Map output gradient back to exactly one input element v[src]. + # ȳ[out_idx] refers to the gradient at output position corresponding to v[src] + grad_v[src] += ȳ[out_idx] + src += 1 + + # Advance to next output index (past this original value) + out_idx += 1 + end + end + + return NoTangent(), grad_v, NoTangent() + end + + return y, pullback +end diff --git a/test/test_ModelApplicator.jl b/test/test_ModelApplicator.jl index f5ed231..55d86ac 100644 --- a/test/test_ModelApplicator.jl +++ b/test/test_ModelApplicator.jl @@ -34,6 +34,9 @@ end; y = g(c1, eltype(m)[]) @test y[range_scaled] == c1[range_scaled] .* m @test y[1:end .∉ Ref(range_scaled)] == c1[1:end .∉ Ref(range_scaled)] + ym = g(hcat(c1,c1 .* 2),eltype(m)[]) # transforming matrix + @test ym[:,1] == y + @test ym[:,2] == y .* 2 end; @testset "NormalScalingModelApplicator" begin @@ -59,6 +62,7 @@ end; @testset "NormalScalingModelApplicator subset" begin app = NullModelApplicator() r = logistic.(randn(10)) # 0..1 + r2 = logistic.(randn(10)) # 0..1 σ = fill(2.0, 5) μ = collect(exp.(1.0:5.0)) # different magnitudes range_scaled = 2 .+ (1:length(σ)) @@ -68,13 +72,22 @@ end; #hcat(r, p) @test p ≈ r[range_scaled] @test y[1:end .∉ Ref(range_scaled)] == r[1:end .∉ Ref(range_scaled)] + rm = hcat(r, r2) + ym = g(rm, eltype(μ)[]) + @test ym[:,1] == y + p2 = normcdf.(μ, σ, ym[range_scaled,2]) + @test p2 ≈ r2[range_scaled] + @test ym[1:end .∉ Ref(range_scaled),2] == r2[1:end .∉ Ref(range_scaled)] #cdev = cpu_device() if gdev isa MLDataDevices.AbstractGPUDevice g_gpu = g |> gdev @test g_gpu.μ isa GPUArraysCore.AbstractGPUArray r_gpu = r |> gdev + rm_gpu = rm |> gdev y = g_gpu(r_gpu, eltype(g_gpu.μ)[]) @test y isa GPUArraysCore.AbstractGPUArray + ym = g_gpu(rm_gpu, eltype(g_gpu.μ)[]) + @test ym isa GPUArraysCore.AbstractGPUArray end end; @@ -89,6 +102,10 @@ end; @test y ≈(r .* width .+ lowers) @test eltype(y) == eltype(r) #cdev = cpu_device() + rm = hcat(r, r .* 2) + ym = g(rm, []) + @test ym[:,1] == y + @test ym[:,2] ≈(rm[:,2] .* width .+ lowers) if gdev isa MLDataDevices.AbstractGPUDevice g_gpu = g |> gdev @test g_gpu.offset isa GPUArraysCore.AbstractGPUArray @@ -113,6 +130,11 @@ end; @test eltype(y) == eltype(r) @test y[1:end .∉ Ref(range_scaled)] == r[1:end .∉ Ref(range_scaled)] #cdev = cpu_device() + rm = hcat(r, r .* 2) + ym = g(rm, []) + @test ym[:,1] == y + @test ym[range_scaled,2] ≈(rm[range_scaled,2] .* width .+ lowers) + @test ym[1:end .∉ Ref(range_scaled),2] == rm[1:end .∉ Ref(range_scaled),2] if gdev isa MLDataDevices.AbstractGPUDevice g_gpu = g |> gdev @test g_gpu.offset isa GPUArraysCore.AbstractGPUArray @@ -121,6 +143,10 @@ end; y_dev = g_gpu(r_gpu, []) @test y_dev isa GPUArraysCore.AbstractGPUArray @test cdev(y_dev) ≈ y + rm_gpu = rm |> gdev + ym_dev = g_gpu(rm_gpu, []) + @test y_dev isa GPUArraysCore.AbstractGPUArray + @test cdev(ym_dev) ≈ ym end end; diff --git a/test/test_elbo.jl b/test/test_elbo.jl index 668fd57..88f630c 100644 --- a/test/test_elbo.jl +++ b/test/test_elbo.jl @@ -39,6 +39,8 @@ FT = eltype(pt.θM) test_scenario = (scenario) -> begin #probc = HybridProblem(prob; scenario, approx); probc = HybridProblem(prob; scenario); + # tmp = first(get_hybridproblem_train_dataloader(prob; scenario))[1] + # probc.g(tmp, probc.ϕg) #@assert typeof(probc.approx) == typeof(approx) FT = get_hybridproblem_float_type(probc; scenario) par_templates = get_hybridproblem_par_templates(probc; scenario) @@ -81,7 +83,8 @@ test_scenario = (scenario) -> begin # transP = elementwise(exp) # transM = Stacked(elementwise(identity), elementwise(exp)) #transM = Stacked(elementwise(identity), elementwise(exp), elementwise(exp)) # test mismatch - (;ϕqc, approx) = tmp = init_hybrid_ϕq(probc.approx, par_templates.θP, par_templates.θM, transP, cor_ends; transM, n_site) + (;ϕqc, approx) = tmp = init_hybrid_ϕq( + probc.approx, par_templates.θP, par_templates.θM, transP, cor_ends; transM, n_site) probc = HybridProblem(probc; approx) # update approx in probc # (ϕunc0, approx) = init_hybrid_ϕunc(cor_ends, zero(FT)) # ϕq0 = CP.update_μP_by_θP(ϕunc0, θP_true, transP) @@ -104,6 +107,7 @@ test_scenario = (scenario) -> begin i_sites = 1:n_batch ζsP, ζsMs_tr, σ = @inferred ( + # @usingany Cthulhu # @descend_code_warntype ( CP.generate_ζ( probc.approx, rng, g, ϕ_ini, xM[:, i_sites]; diff --git a/test/test_util.jl b/test/test_util.jl index e273924..c61d0b3 100644 --- a/test/test_util.jl +++ b/test/test_util.jl @@ -1,7 +1,20 @@ using Test -using HybridVariationalInference: vectuptotupvec_allowmissing, vectuptotupvec +using HybridVariationalInference: vectuptotupvec_allowmissing, vectuptotupvec, insert_zeros +using HybridVariationalInference: HybridVariationalInference as HVI using Zygote +@testset "insert_zeros" begin + @test HVI.insert_zeros([1,2,3], [2,4]) == [1,0,2,0,3] + @test HVI.insert_zeros([1,2,3], [1,1]) == [0,0,1,2,3] + @test_throws ArgumentError HVI.insert_zeros([1,2], [4]) + @test HVI.insert_zeros([1,2,3], 2) == [1,0,2,3] + @test @inferred HVI.insert_zeros([1,2,3,4], [1,3,4,7,9]) == [0,1,0,0,2,3,0,4,0] + # position 9 is not available at the beginning, but after inserting 4 zeros, the vector has length 9, so it is valid + @test_throws ArgumentError HVI.insert_zeros([1,2,3,4], reverse([1,3,4,7,9])) + @test Zygote.gradient(x -> sum(HVI.insert_zeros(x, [1,3,4,7,9])), [1,2,3,4]) == ([1.0, 1.0, 1.0, 1.0],) + +end; + @testset "vectuptotupvec" begin vectup = [(1,1.01, "string 1"), (2,2.02, "string 2")] tupvec = @inferred vectuptotupvec(vectup) From 8130d1cc83efa699f9de6df8cc0f016d4fb4e0e4 Mon Sep 17 00:00:00 2001 From: Thomas Wutzler Date: Thu, 2 Apr 2026 07:57:26 +0000 Subject: [PATCH 08/31] Implement OneBasedVectorWithZero to allow efficient indexing with a vector to insert zeros. --- src/HybridVariationalInference.jl | 1 + src/OneBasedVectorWithZero.jl | 108 ++++++++++++++++++++++++++ src/elbo_scaling.jl | 22 ++---- src/util.jl | 122 +++++++++++------------------- test/runtests.jl | 4 +- test/test_elbo.jl | 6 +- test/test_util.jl | 93 +++++++++++++++++++++-- 7 files changed, 251 insertions(+), 105 deletions(-) create mode 100644 src/OneBasedVectorWithZero.jl diff --git a/src/HybridVariationalInference.jl b/src/HybridVariationalInference.jl index 7405c0c..85168cb 100644 --- a/src/HybridVariationalInference.jl +++ b/src/HybridVariationalInference.jl @@ -32,6 +32,7 @@ using IterTools: IterTools export DoubleMM +include("OneBasedVectorWithZero.jl") include("util.jl") export extend_stacked_nrow, StackedArray diff --git a/src/OneBasedVectorWithZero.jl b/src/OneBasedVectorWithZero.jl new file mode 100644 index 0000000..35463ac --- /dev/null +++ b/src/OneBasedVectorWithZero.jl @@ -0,0 +1,108 @@ +""" + OneBasedVectorWithZero(data) + +A thin wrapper over an `AbstractVector` that exposes a linear 1-based indexing API +mapping `v[i]` to `data[axes(data, 1)[i]]` on the underlying storage +and provides a value at index 0 (defaulting to zero) that is not stored in the underlying vector. + +Example usage: +```jldoctest; output=false +v = HVI.OneBasedVectorWithZero([10,20,30]) +v[1] == 10 +v[2] == 20 +v[3] == 30 +v[0] == 0 # default value at index 0 is zero +v[[1,0,0,3]] == [10,0,0,30] +``` +""" +struct OneBasedVectorWithZero{E,V<:AbstractVector{E}} <: AbstractVector{E} + data::V + val_at_zero::E # optional field to store the value at index 0 if needed +end + +OneBasedVectorWithZero(v::AbstractVector; val_at_zero=zero(eltype(v))) = OneBasedVectorWithZero(v, val_at_zero) +Base.size(v::OneBasedVectorWithZero) = size(v.data) +Base.length(v::OneBasedVectorWithZero) = length(v.data) +Base.eltype(v::OneBasedVectorWithZero) = eltype(v.data) +Base.axes(v::OneBasedVectorWithZero) = (Base.OneTo(length(v)),) +Base.IndexStyle(::Type{<:OneBasedVectorWithZero}) = IndexLinear() +Base.empty(v::OneBasedVectorWithZero) = OneBasedVectorWithZero(empty(v.data), v.val_at_zero) + +function Base.getindex(v::OneBasedVectorWithZero, i::Integer) + tmp = i isa Integer + if i == 0 + return v.val_at_zero + elseif 1 <= i <= length(v) + return v.data[axes(v.data,1)[i]] + else + throw(BoundsError(v, i)) + end +end + +# Bools is a subtype of Integer, need to handle this case separately +function Base.getindex(v::OneBasedVectorWithZero, inds::AbstractVector{<:Bool}) + v.data[inds] +end + +function Base.getindex(v::OneBasedVectorWithZero, inds::AbstractVector{<:Integer}) + return map(i -> getindex(v, i), inds) +end + +function Base.setindex!(v::OneBasedVectorWithZero, value, i::Integer) + # setting index 0 is not allowed + if 1 <= i <= length(v) + v.data[axes(v.data, 1)[i]] = value + return v + else + throw(BoundsError(v, i)) + end +end + +function Base.iterate(v::OneBasedVectorWithZero, state=1) + state > length(v) ? nothing : (v[state], state + 1) +end + +function ChainRulesCore.rrule(::typeof(getindex), v::OneBasedVectorWithZero, i::Integer) + if i == 0 + y = v.val_at_zero + function pullback0(ȳ) + # no gradient to base vector or val_at_zero + return NoTangent(), NoTangent(), NoTangent() + end + return y, pullback0 + elseif 1 <= i <= length(v) + y = v.data[axes(v.data,1)[i]] + function pullback(ȳ) + dv = zero(v.data) + dv[axes(v.data,1)[i]] += ȳ + return NoTangent(), OneBasedVectorWithZero(dv, zero(eltype(v))), NoTangent() + end + return y, pullback + else + throw(BoundsError(v, i)) + end +end + +function ChainRulesCore.rrule(::typeof(getindex), v::OneBasedVectorWithZero, inds::AbstractVector{<:Integer}) + y = getindex(v, inds) + function pullback(ȳ) + dv = zero(v.data) + for (k, idx) in enumerate(inds) + if 1 <= idx <= length(v) + dv[axes(v.data,1)[idx]] += ȳ[k] + end + end + return NoTangent(), OneBasedVectorWithZero(dv, zero(eltype(v))), NoTangent() + end + return y, pullback +end + +if isdefined(Main, :Zygote) || isdefined(HybridVariationalInference, :Zygote) + Zygote.@adjoint function OneBasedVectorWithZero(v::AbstractVector; val_at_zero=zero(eltype(v))) + h = OneBasedVectorWithZero(v, val_at_zero) + return h, Δ -> ( + Δ isa OneBasedVectorWithZero ? Δ.data : Δ, + NoTangent() + ) + end +end diff --git a/src/elbo_scaling.jl b/src/elbo_scaling.jl index f0663c3..310333a 100644 --- a/src/elbo_scaling.jl +++ b/src/elbo_scaling.jl @@ -13,10 +13,12 @@ function sample_ζresid_norm(approx::AbstractMeanScalingHVIApproximation, ) where {T,TM<:AbstractMatrix{T}} ϕuncc = ϕqc = int_ϕq(CA.getdata(ϕq)) # add 0 as last logσ2_par_offset-par in block - logσ2_par_offsets_before_end = ϕqc[Val(:logσ2_ζM_offsets)] - # insert zeros at the end of each block of parameters - logσ2_par_offsets = insert_zeros(logσ2_par_offsets_before_end, approx.scalingblocks_ends)::typeof(logσ2_par_offsets_before_end) b_ends = ChainRulesCore.ignore_derivatives(approx.scalingblocks_ends) + logσ2_par_offsets_before_end = OneBasedVectorWithZero(ϕqc[Val(:logσ2_ζM_offsets)]) + # TODO move idxs_par0 and idxs_repblocks to approx and create during initialization + idxs_par0 = insert_zeros(1:length(logσ2_par_offsets_before_end), b_ends) + # insert zeros at the end of each block of parameters + logσ2_par_offsets = logσ2_par_offsets_before_end[idxs_par0] length_scale_blocks = vcat(first(b_ends), diff(b_ends)) n_scale_blocks = length(b_ends) n_par = size(ϕm,1) - n_scale_blocks @@ -32,7 +34,9 @@ function sample_ζresid_norm(approx::AbstractMeanScalingHVIApproximation, # coefficients ρsM can be larger than 1, still yielding correlations <1 in UM' * UM UM = transformU_block_cholesky1(ρsM, cor_ends.M) # - logσ2_site_offsets = repeat_rows_by_counts(logσ2_sites, length_scale_blocks) + idxs_repblocks = vcat((fill(i, length_scale_blocks[i]) for i in axes(length_scale_blocks,1))...) + logσ2_site_offsets = logσ2_sites[idxs_repblocks,:] + # TODO fill.(approx.logσ2_ζM_base already during initialization of approx logσ2_ζM_bases = reduce(vcat, fill.(approx.logσ2_ζM_base, length_scale_blocks)) logσ2_ζMs = logσ2_ζM_bases .+ logσ2_par_offsets .+ logσ2_site_offsets # @@ -62,15 +66,5 @@ function sample_ζresid_norm(approx::AbstractMeanScalingHVIApproximation, # ζ_resid, diagUσ end -# repeat rows of a matrix by per-row counts, non-mutating (Zygote-friendly) -function repeat_rows_by_counts(A::AbstractMatrix, counts::AbstractVector{<:Integer}) - @assert length(counts) == size(A,1) "Need to provide a count for each row ($counts, $(size(A,1)))." - if isempty(A) - return similar(A, 0, size(A,2)) - end - idx = vcat((fill(i, counts[i]) for i in axes(counts,1))...) - return A[idx, :] -end - diff --git a/src/util.jl b/src/util.jl index 55413f2..649c925 100644 --- a/src/util.jl +++ b/src/util.jl @@ -35,6 +35,33 @@ function vectuptotupvec_allowmissing( end, npar) end +""" + take_n!(itr, n) + +Peel off the first `n` elements of an drop-iterator `itr` and +return them as a vector, while mutating `itr` to now start after those `n` elements. + +# Examples +```jldoctest; output=false +it = drop_iterate(1:5) # initialize the iterator + +a1 = take_n!(it,3) +collect(a1) == [1,2,3] + +a2 = take_n!(it,3) +collect(a2) == [4,5] # only two element left, so return those + +a3 = take_n!(it,3) +collect(a3) == [] # no elements left, so return empty vector +``` +""" +function take_n!(itr::Base.RefValue{<:Base.Iterators.Drop},n) + ans = Iterators.take(itr[], n) + itr[] = Iterators.drop(itr[], n) + ans +end +drop_iterate(x) = Ref(Iterators.drop(x,0)) + """ insert_zeros(v, positions) @@ -44,95 +71,34 @@ so later indices are interpreted on the updated result. Only one output vector is allocated. """ function insert_zeros(v::AbstractVector, positions::AbstractVector{<:Integer}) - n = length(v) - m = length(positions) # number of insert positions - - # If there are no insertions, just copy and return the original vector. - if m == 0 - return collect(v) - end - - # Convert positions to an array; we can index into p in the same order. - # (This also allows `positions` to be any AbstractVector.) - p = positions - - # Validate each insertion position using the growing-vector semantics: - # after k-1 insertions, the vector length is n + k - 1, so pk must be in [1, length+1]. - for (k, pk) in enumerate(positions) - curr_len = n + k - 1 - if pk < 1 || pk > curr_len + 1 - throw(ArgumentError("insert_zeros position $pk out of bounds for length $curr_len")) - end - end - - # Map each sequential insert position to a bucket index in the final sequence, - # where 0 <= x[k] <= n (0 means before first element, n means after last element). - # Formula: p[k]-1 (zero-based insert target in original coords) minus the number of - # previously inserted positions that fall before p[k], because they shift later indexes. - x = [p[k] - 1 - count(j -> p[j] < p[k], 1:k-1) for k in 1:m] - - # zero_chain(i) yields one `zero(eltype(v))` per insertion that should occur in bucket i. - zero_chain = i -> (zero(eltype(v)) for k in 1:m if x[k] == i) - - # Build output lazily by iterating i from 0..n: - # for each i, first emit zeros for that bucket, then emit original v[i+1] when i= 0) "Positions must be in strictly ascending order." + # length of blocks before insert is diff(postions) -1 + length_blocks_beforeinsert = Iterators.flatten((first(positions) .- 1, dpos1)) + #collect(length_blocks_beforeinsert) == [1,2] + it = drop_iterate(v) # to allow take_n! + #collect(HVI.take_n!(it, 4)) == v + gen = (Iterators.flatten( + (take_n!(it, l), zero(eltype(v)))) for l in length_blocks_beforeinsert) + # collect(Iterators.flatten(gen)) == [10, 0, 20, 30, 0] + return collect(Iterators.flatten(gen)) end -insert_zeros(v::AbstractVector, position::Integer) = insert_zeros(v, [position]) - function ChainRulesCore.rrule(::typeof(insert_zeros), v::AbstractVector, positions::AbstractVector{<:Integer}) - # Forward pass: compute output normally. y = insert_zeros(v, positions) - # Reverse pass (pullback) for gradient of `insert_zeros`: # - We only propagate gradients into `v`. # - `positions` is treated as non-differentiable (NoTangent()). - # - For each output value: - # * if it's one of the inserted zeros => no contribution to grad_v - # * if it's from original v[k] => add ȳ to grad_v[k] + # We ignore the gradients for the postions, where zero was inserted + # Otherwise, we just need to extract the corresponding positions in ȳ function pullback(ȳ) n = length(v) m = length(positions) - - # Compute insertion buckets x[k] as in insert_zeros. - p = positions - x = [p[k] - 1 - count(j -> p[j] < p[k], 1:k-1) for k in 1:m] - - # Determine how many zeros are produced in each bucket i in 0:n. - zeros_per_bucket = zeros(Int, n + 1) - for xi in x - zeros_per_bucket[xi + 1] += 1 - end - - grad_v = zeros(eltype(v), n) - src = 1 # index in original input vector v from which gradient flows - out_idx = 1 # current index in output vector y/ȳ - - for i in 0:n - # Step past inserted zeros for this bucket (all zero insertions from insert_zeros) - # out_idx becomes the position of the next original value (if any) after zero insertions. - out_idx += zeros_per_bucket[i + 1] - - if i < n - # Map output gradient back to exactly one input element v[src]. - # ȳ[out_idx] refers to the gradient at output position corresponding to v[src] - grad_v[src] += ȳ[out_idx] - src += 1 - - # Advance to next output index (past this original value) - out_idx += 1 - end - end - + grad_v = OneBasedVectorWithZero(ȳ[:])[1:(n+m) .∉ Ref(positions)] return NoTangent(), grad_v, NoTangent() end - return y, pullback end diff --git a/test/runtests.jl b/test/runtests.jl index 41e0902..2495c47 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,12 +3,12 @@ const GROUP = get(ENV, "GROUP", "All") # defined in in CI.yml @time begin if GROUP == "All" || GROUP == "Basic" + #@safetestset "test" include("test/test_util.jl") + @time @safetestset "test_util" include("test_util.jl") #@safetestset "test" include("test/test_RRuleMonitor.jl") @time @safetestset "test_RRuleMonitor" include("test_RRuleMonitor.jl") #@safetestset "test" include("test/test_bijectors_utils.jl") @time @safetestset "test_bijectors_utils" include("test_bijectors_utils.jl") - #@safetestset "test" include("test/test_util.jl") - @time @safetestset "test_util" include("test_util.jl") #@safetestset "test" include("test/test_util_ca.jl") @time @safetestset "test_util_ca" include("test_util_ca.jl") #@safetestset "test" include("test/test_util_gpu.jl") diff --git a/test/test_elbo.jl b/test/test_elbo.jl index 88f630c..20ed886 100644 --- a/test/test_elbo.jl +++ b/test/test_elbo.jl @@ -138,7 +138,7 @@ test_scenario = (scenario) -> begin @test gr[1] isa Vector end - if !(:covarK2 ∈ CP._val_value(scenario)) && (approx isa MeanHVIApproximation) + if !(:covarK2 ∈ CP._val_value(scenario)) && (probc.approx isa MeanHVIApproximation) # can only test distribution if g is not repeated @testset "generate_ζ check sd residuals $(last(CP._val_value(scenario)))" begin # prescribe very different uncertainties @@ -512,9 +512,9 @@ test_scenario = (scenario) -> begin end # test_scenario +test_scenario(Val((:scalingall,))) test_scenario(Val((:default,))) -test_scenario(Val((:default, :sepvar,))) -#test_scenario(Val((:default, :scalingall,)), MeanScalingHVIApproximation([length(pt.θM)])) +test_scenario(Val((:sepvar,))) # with providing process parameter as additional covariate test_scenario(Val((:covarK2,))) diff --git a/test/test_util.jl b/test/test_util.jl index c61d0b3..913bec6 100644 --- a/test/test_util.jl +++ b/test/test_util.jl @@ -3,15 +3,92 @@ using HybridVariationalInference: vectuptotupvec_allowmissing, vectuptotupvec, i using HybridVariationalInference: HybridVariationalInference as HVI using Zygote + +@testset "OneBasedVectorWithZero" begin + # Standard Julia 1-based vector (no underlying shift) + v1 = HVI.OneBasedVectorWithZero([10,20,30]) + @test @inferred v1[1] == 10 + @test v1[2] == 20 + @test v1[3] == 30 + @test v1[[true,true,true]] == [10,20,30] + + v1[1] = 100 + @test v1[1] == 100 + @test v1.data[1] == 100 + + # Underlying 0-based vector should still present 1-based API. + struct ZeroBasedVector{T} <: AbstractVector{T} + data::Vector{T} + end + Base.size(v::ZeroBasedVector) = size(v.data) + Base.length(v::ZeroBasedVector) = length(v.data) + Base.axes(v::ZeroBasedVector) = (0:length(v)-1,) + Base.getindex(v::ZeroBasedVector, i::Integer) = v.data[i+1] + Base.setindex!(v::ZeroBasedVector, x, i::Integer) = (v.data[i+1] = x) + + data0 = ZeroBasedVector([10,20,30]) + v0 = HVI.OneBasedVectorWithZero(data0) + @test eltype(v0) == Int + @test @inferred v0[1] == 10 + @test v0[2] == 20 + @test v0[3] == 30 + + v0[1] = 100 + @test v0[1] == 100 + @test v0.data[0] == 100 + + # bounds for non-zero indices should be 1..length for wrapper independent of underlying axis + @test v0[0] == 0 + @test_throws BoundsError v0[-1] + @test_throws BoundsError v0[4] + @test_throws BoundsError v0[0] = 50 + + @test collect(v0) == [100,20,30] + @test length(v0) == 3 + @test axes(v0) == (Base.OneTo(3),) + + # gradient pass through values works + g = Zygote.gradient(x -> sum(HVI.OneBasedVectorWithZero(x)), [1.0, 2.0, 3.0]) + @test g == ([1.0,1.0,1.0],) + + v1 = HVI.OneBasedVectorWithZero([10,20,30]) + # @usingany Cthulhu + # @descend_code_warntype v1[0] + @inferred v1[0] + @test v1[0] == 0 # default value at index 0 is zero + v1 = HVI.OneBasedVectorWithZero([10,20,30]; val_at_zero=-5) + @test @inferred(v1[0]) == -5 # default value at index 0 is zero + @test v1[[1,1,2,3]] == [10,10,20,30] + @test v1[[1,0,0,3]] == [10,-5,-5,30] + g1 = Zygote.gradient(y -> sum(HVI.OneBasedVectorWithZero(y)[[1,1,0,0,2]]), [1.0,2.0,3.0]) + @test g1 == ([2.0,1.0,0.0],) +end; + +@testset "take_n!" begin + it = HVI.drop_iterate(1:5) # initialize the iterator + a1 = HVI.take_n!(it,3) + @test collect(a1) == [1,2,3] + a2 = HVI.take_n!(it,3) + @test collect(a2) == [4,5] # only two element left, so return those + a3 = HVI.take_n!(it,3) + @test collect(a3) == [] # no elements left, so return empty vector +end + @testset "insert_zeros" begin - @test HVI.insert_zeros([1,2,3], [2,4]) == [1,0,2,0,3] - @test HVI.insert_zeros([1,2,3], [1,1]) == [0,0,1,2,3] - @test_throws ArgumentError HVI.insert_zeros([1,2], [4]) - @test HVI.insert_zeros([1,2,3], 2) == [1,0,2,3] - @test @inferred HVI.insert_zeros([1,2,3,4], [1,3,4,7,9]) == [0,1,0,0,2,3,0,4,0] - # position 9 is not available at the beginning, but after inserting 4 zeros, the vector has length 9, so it is valid - @test_throws ArgumentError HVI.insert_zeros([1,2,3,4], reverse([1,3,4,7,9])) - @test Zygote.gradient(x -> sum(HVI.insert_zeros(x, [1,3,4,7,9])), [1,2,3,4]) == ([1.0, 1.0, 1.0, 1.0],) + @test @inferred HVI.insert_zeros([1,2,3], [2,5]) == [1,0,2,3,0] + @test @inferred HVI.insert_zeros([1,2,3], [1,5]) == [0,1,2,3,0] + @test_throws AssertionError HVI.insert_zeros([1,2,3], [2,4]) + @test_throws AssertionError HVI.insert_zeros([1,2,3], [1,1,6]) + Zygote.gradient(x -> sum(HVI.insert_zeros(x, [2,5])), [1,2,3]) + + # + v = HVI.OneBasedVectorWithZero([10,20,30]) + idxs = HVI.insert_zeros(1:length(v), [2,5]) + res = @inferred v[idxs] + # @usingany Cthulhu + #@descend_code_warntype v[idxs] + @test res == [10, 0, 20, 30, 0] + @test Zygote.gradient(x -> sum(x[idxs]), v) == ([1.0, 1.0, 1.0],) end; From 36d1452ead014e52a30fbd9528470acdb326876c Mon Sep 17 00:00:00 2001 From: Thomas Wutzler Date: Thu, 2 Apr 2026 13:29:10 +0000 Subject: [PATCH 09/31] Implement OneBasedVectorWithZero to allow efficient indexing with a vector to insert zeros. --- src/HybridVariationalInference.jl | 1 + src/OneBasedVectorWithZero.jl | 107 ++++++++++++++++++++++++++ src/elbo_scaling.jl | 22 ++---- src/util.jl | 122 +++++++++++------------------- test/runtests.jl | 4 +- test/test_elbo.jl | 6 +- test/test_util.jl | 93 +++++++++++++++++++++-- 7 files changed, 250 insertions(+), 105 deletions(-) create mode 100644 src/OneBasedVectorWithZero.jl diff --git a/src/HybridVariationalInference.jl b/src/HybridVariationalInference.jl index 7405c0c..85168cb 100644 --- a/src/HybridVariationalInference.jl +++ b/src/HybridVariationalInference.jl @@ -32,6 +32,7 @@ using IterTools: IterTools export DoubleMM +include("OneBasedVectorWithZero.jl") include("util.jl") export extend_stacked_nrow, StackedArray diff --git a/src/OneBasedVectorWithZero.jl b/src/OneBasedVectorWithZero.jl new file mode 100644 index 0000000..5530534 --- /dev/null +++ b/src/OneBasedVectorWithZero.jl @@ -0,0 +1,107 @@ +""" + OneBasedVectorWithZero(data) + +A thin wrapper over an `AbstractVector` that exposes a linear 1-based indexing API +mapping `v[i]` to `data[axes(data, 1)[i]]` on the underlying storage +and provides a value at index 0 (defaulting to zero) that is not stored in the underlying vector. + +Example usage: +```jldoctest; output=false +v = HVI.OneBasedVectorWithZero([10,20,30]) +v[1] == 10 +v[2] == 20 +v[3] == 30 +v[0] == 0 # default value at index 0 is zero +v[[1,0,0,3]] == [10,0,0,30] +``` +""" +struct OneBasedVectorWithZero{E,V<:AbstractVector{E}} <: AbstractVector{E} + data::V + val_at_zero::E # optional field to store the value at index 0 if needed +end + +OneBasedVectorWithZero(v::AbstractVector; val_at_zero=zero(eltype(v))) = OneBasedVectorWithZero(v, val_at_zero) +Base.size(v::OneBasedVectorWithZero) = size(v.data) +Base.length(v::OneBasedVectorWithZero) = length(v.data) +Base.eltype(v::OneBasedVectorWithZero) = eltype(v.data) +Base.axes(v::OneBasedVectorWithZero) = (Base.OneTo(length(v)),) +Base.IndexStyle(::Type{<:OneBasedVectorWithZero}) = IndexLinear() +Base.empty(v::OneBasedVectorWithZero) = OneBasedVectorWithZero(empty(v.data), v.val_at_zero) + +function Base.getindex(v::OneBasedVectorWithZero, i::Integer) + if i == 0 + return v.val_at_zero + elseif 1 <= i <= length(v) + return v.data[axes(v.data,1)[i]] + else + throw(BoundsError(v, i)) + end +end + +# Bools is a subtype of Integer, need to handle this case separately +function Base.getindex(v::OneBasedVectorWithZero, inds::AbstractVector{<:Bool}) + v.data[inds] +end + +function Base.getindex(v::OneBasedVectorWithZero, inds::AbstractVector{<:Integer}) + return map(i -> getindex(v, i), inds) +end + +function Base.setindex!(v::OneBasedVectorWithZero, value, i::Integer) + # setting index 0 is not allowed + if 1 <= i <= length(v) + v.data[axes(v.data, 1)[i]] = value + return v + else + throw(BoundsError(v, i)) + end +end + +function Base.iterate(v::OneBasedVectorWithZero, state=1) + state > length(v) ? nothing : (v[state], state + 1) +end + +function ChainRulesCore.rrule(::typeof(getindex), v::OneBasedVectorWithZero, i::Integer) + if i == 0 + y = v.val_at_zero + function pullback0(ȳ) + # no gradient to base vector or val_at_zero + return NoTangent(), NoTangent(), NoTangent() + end + return y, pullback0 + elseif 1 <= i <= length(v) + y = v.data[axes(v.data,1)[i]] + function pullback(ȳ) + dv = zero(v.data) + dv[axes(v.data,1)[i]] += ȳ + return NoTangent(), OneBasedVectorWithZero(dv, zero(eltype(v))), NoTangent() + end + return y, pullback + else + throw(BoundsError(v, i)) + end +end + +function ChainRulesCore.rrule(::typeof(getindex), v::OneBasedVectorWithZero, inds::AbstractVector{<:Integer}) + y = getindex(v, inds) + function pullback(ȳ) + dv = zero(v.data) + for (k, idx) in enumerate(inds) + if 1 <= idx <= length(v) + dv[axes(v.data,1)[idx]] += ȳ[k] + end + end + return NoTangent(), OneBasedVectorWithZero(dv, zero(eltype(v))), NoTangent() + end + return y, pullback +end + +if isdefined(Main, :Zygote) || isdefined(HybridVariationalInference, :Zygote) + Zygote.@adjoint function OneBasedVectorWithZero(v::AbstractVector; val_at_zero=zero(eltype(v))) + h = OneBasedVectorWithZero(v, val_at_zero) + return h, Δ -> ( + Δ isa OneBasedVectorWithZero ? Δ.data : Δ, + NoTangent() + ) + end +end diff --git a/src/elbo_scaling.jl b/src/elbo_scaling.jl index f0663c3..310333a 100644 --- a/src/elbo_scaling.jl +++ b/src/elbo_scaling.jl @@ -13,10 +13,12 @@ function sample_ζresid_norm(approx::AbstractMeanScalingHVIApproximation, ) where {T,TM<:AbstractMatrix{T}} ϕuncc = ϕqc = int_ϕq(CA.getdata(ϕq)) # add 0 as last logσ2_par_offset-par in block - logσ2_par_offsets_before_end = ϕqc[Val(:logσ2_ζM_offsets)] - # insert zeros at the end of each block of parameters - logσ2_par_offsets = insert_zeros(logσ2_par_offsets_before_end, approx.scalingblocks_ends)::typeof(logσ2_par_offsets_before_end) b_ends = ChainRulesCore.ignore_derivatives(approx.scalingblocks_ends) + logσ2_par_offsets_before_end = OneBasedVectorWithZero(ϕqc[Val(:logσ2_ζM_offsets)]) + # TODO move idxs_par0 and idxs_repblocks to approx and create during initialization + idxs_par0 = insert_zeros(1:length(logσ2_par_offsets_before_end), b_ends) + # insert zeros at the end of each block of parameters + logσ2_par_offsets = logσ2_par_offsets_before_end[idxs_par0] length_scale_blocks = vcat(first(b_ends), diff(b_ends)) n_scale_blocks = length(b_ends) n_par = size(ϕm,1) - n_scale_blocks @@ -32,7 +34,9 @@ function sample_ζresid_norm(approx::AbstractMeanScalingHVIApproximation, # coefficients ρsM can be larger than 1, still yielding correlations <1 in UM' * UM UM = transformU_block_cholesky1(ρsM, cor_ends.M) # - logσ2_site_offsets = repeat_rows_by_counts(logσ2_sites, length_scale_blocks) + idxs_repblocks = vcat((fill(i, length_scale_blocks[i]) for i in axes(length_scale_blocks,1))...) + logσ2_site_offsets = logσ2_sites[idxs_repblocks,:] + # TODO fill.(approx.logσ2_ζM_base already during initialization of approx logσ2_ζM_bases = reduce(vcat, fill.(approx.logσ2_ζM_base, length_scale_blocks)) logσ2_ζMs = logσ2_ζM_bases .+ logσ2_par_offsets .+ logσ2_site_offsets # @@ -62,15 +66,5 @@ function sample_ζresid_norm(approx::AbstractMeanScalingHVIApproximation, # ζ_resid, diagUσ end -# repeat rows of a matrix by per-row counts, non-mutating (Zygote-friendly) -function repeat_rows_by_counts(A::AbstractMatrix, counts::AbstractVector{<:Integer}) - @assert length(counts) == size(A,1) "Need to provide a count for each row ($counts, $(size(A,1)))." - if isempty(A) - return similar(A, 0, size(A,2)) - end - idx = vcat((fill(i, counts[i]) for i in axes(counts,1))...) - return A[idx, :] -end - diff --git a/src/util.jl b/src/util.jl index 55413f2..649c925 100644 --- a/src/util.jl +++ b/src/util.jl @@ -35,6 +35,33 @@ function vectuptotupvec_allowmissing( end, npar) end +""" + take_n!(itr, n) + +Peel off the first `n` elements of an drop-iterator `itr` and +return them as a vector, while mutating `itr` to now start after those `n` elements. + +# Examples +```jldoctest; output=false +it = drop_iterate(1:5) # initialize the iterator + +a1 = take_n!(it,3) +collect(a1) == [1,2,3] + +a2 = take_n!(it,3) +collect(a2) == [4,5] # only two element left, so return those + +a3 = take_n!(it,3) +collect(a3) == [] # no elements left, so return empty vector +``` +""" +function take_n!(itr::Base.RefValue{<:Base.Iterators.Drop},n) + ans = Iterators.take(itr[], n) + itr[] = Iterators.drop(itr[], n) + ans +end +drop_iterate(x) = Ref(Iterators.drop(x,0)) + """ insert_zeros(v, positions) @@ -44,95 +71,34 @@ so later indices are interpreted on the updated result. Only one output vector is allocated. """ function insert_zeros(v::AbstractVector, positions::AbstractVector{<:Integer}) - n = length(v) - m = length(positions) # number of insert positions - - # If there are no insertions, just copy and return the original vector. - if m == 0 - return collect(v) - end - - # Convert positions to an array; we can index into p in the same order. - # (This also allows `positions` to be any AbstractVector.) - p = positions - - # Validate each insertion position using the growing-vector semantics: - # after k-1 insertions, the vector length is n + k - 1, so pk must be in [1, length+1]. - for (k, pk) in enumerate(positions) - curr_len = n + k - 1 - if pk < 1 || pk > curr_len + 1 - throw(ArgumentError("insert_zeros position $pk out of bounds for length $curr_len")) - end - end - - # Map each sequential insert position to a bucket index in the final sequence, - # where 0 <= x[k] <= n (0 means before first element, n means after last element). - # Formula: p[k]-1 (zero-based insert target in original coords) minus the number of - # previously inserted positions that fall before p[k], because they shift later indexes. - x = [p[k] - 1 - count(j -> p[j] < p[k], 1:k-1) for k in 1:m] - - # zero_chain(i) yields one `zero(eltype(v))` per insertion that should occur in bucket i. - zero_chain = i -> (zero(eltype(v)) for k in 1:m if x[k] == i) - - # Build output lazily by iterating i from 0..n: - # for each i, first emit zeros for that bucket, then emit original v[i+1] when i= 0) "Positions must be in strictly ascending order." + # length of blocks before insert is diff(postions) -1 + length_blocks_beforeinsert = Iterators.flatten((first(positions) .- 1, dpos1)) + #collect(length_blocks_beforeinsert) == [1,2] + it = drop_iterate(v) # to allow take_n! + #collect(HVI.take_n!(it, 4)) == v + gen = (Iterators.flatten( + (take_n!(it, l), zero(eltype(v)))) for l in length_blocks_beforeinsert) + # collect(Iterators.flatten(gen)) == [10, 0, 20, 30, 0] + return collect(Iterators.flatten(gen)) end -insert_zeros(v::AbstractVector, position::Integer) = insert_zeros(v, [position]) - function ChainRulesCore.rrule(::typeof(insert_zeros), v::AbstractVector, positions::AbstractVector{<:Integer}) - # Forward pass: compute output normally. y = insert_zeros(v, positions) - # Reverse pass (pullback) for gradient of `insert_zeros`: # - We only propagate gradients into `v`. # - `positions` is treated as non-differentiable (NoTangent()). - # - For each output value: - # * if it's one of the inserted zeros => no contribution to grad_v - # * if it's from original v[k] => add ȳ to grad_v[k] + # We ignore the gradients for the postions, where zero was inserted + # Otherwise, we just need to extract the corresponding positions in ȳ function pullback(ȳ) n = length(v) m = length(positions) - - # Compute insertion buckets x[k] as in insert_zeros. - p = positions - x = [p[k] - 1 - count(j -> p[j] < p[k], 1:k-1) for k in 1:m] - - # Determine how many zeros are produced in each bucket i in 0:n. - zeros_per_bucket = zeros(Int, n + 1) - for xi in x - zeros_per_bucket[xi + 1] += 1 - end - - grad_v = zeros(eltype(v), n) - src = 1 # index in original input vector v from which gradient flows - out_idx = 1 # current index in output vector y/ȳ - - for i in 0:n - # Step past inserted zeros for this bucket (all zero insertions from insert_zeros) - # out_idx becomes the position of the next original value (if any) after zero insertions. - out_idx += zeros_per_bucket[i + 1] - - if i < n - # Map output gradient back to exactly one input element v[src]. - # ȳ[out_idx] refers to the gradient at output position corresponding to v[src] - grad_v[src] += ȳ[out_idx] - src += 1 - - # Advance to next output index (past this original value) - out_idx += 1 - end - end - + grad_v = OneBasedVectorWithZero(ȳ[:])[1:(n+m) .∉ Ref(positions)] return NoTangent(), grad_v, NoTangent() end - return y, pullback end diff --git a/test/runtests.jl b/test/runtests.jl index 41e0902..2495c47 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,12 +3,12 @@ const GROUP = get(ENV, "GROUP", "All") # defined in in CI.yml @time begin if GROUP == "All" || GROUP == "Basic" + #@safetestset "test" include("test/test_util.jl") + @time @safetestset "test_util" include("test_util.jl") #@safetestset "test" include("test/test_RRuleMonitor.jl") @time @safetestset "test_RRuleMonitor" include("test_RRuleMonitor.jl") #@safetestset "test" include("test/test_bijectors_utils.jl") @time @safetestset "test_bijectors_utils" include("test_bijectors_utils.jl") - #@safetestset "test" include("test/test_util.jl") - @time @safetestset "test_util" include("test_util.jl") #@safetestset "test" include("test/test_util_ca.jl") @time @safetestset "test_util_ca" include("test_util_ca.jl") #@safetestset "test" include("test/test_util_gpu.jl") diff --git a/test/test_elbo.jl b/test/test_elbo.jl index 88f630c..20ed886 100644 --- a/test/test_elbo.jl +++ b/test/test_elbo.jl @@ -138,7 +138,7 @@ test_scenario = (scenario) -> begin @test gr[1] isa Vector end - if !(:covarK2 ∈ CP._val_value(scenario)) && (approx isa MeanHVIApproximation) + if !(:covarK2 ∈ CP._val_value(scenario)) && (probc.approx isa MeanHVIApproximation) # can only test distribution if g is not repeated @testset "generate_ζ check sd residuals $(last(CP._val_value(scenario)))" begin # prescribe very different uncertainties @@ -512,9 +512,9 @@ test_scenario = (scenario) -> begin end # test_scenario +test_scenario(Val((:scalingall,))) test_scenario(Val((:default,))) -test_scenario(Val((:default, :sepvar,))) -#test_scenario(Val((:default, :scalingall,)), MeanScalingHVIApproximation([length(pt.θM)])) +test_scenario(Val((:sepvar,))) # with providing process parameter as additional covariate test_scenario(Val((:covarK2,))) diff --git a/test/test_util.jl b/test/test_util.jl index c61d0b3..913bec6 100644 --- a/test/test_util.jl +++ b/test/test_util.jl @@ -3,15 +3,92 @@ using HybridVariationalInference: vectuptotupvec_allowmissing, vectuptotupvec, i using HybridVariationalInference: HybridVariationalInference as HVI using Zygote + +@testset "OneBasedVectorWithZero" begin + # Standard Julia 1-based vector (no underlying shift) + v1 = HVI.OneBasedVectorWithZero([10,20,30]) + @test @inferred v1[1] == 10 + @test v1[2] == 20 + @test v1[3] == 30 + @test v1[[true,true,true]] == [10,20,30] + + v1[1] = 100 + @test v1[1] == 100 + @test v1.data[1] == 100 + + # Underlying 0-based vector should still present 1-based API. + struct ZeroBasedVector{T} <: AbstractVector{T} + data::Vector{T} + end + Base.size(v::ZeroBasedVector) = size(v.data) + Base.length(v::ZeroBasedVector) = length(v.data) + Base.axes(v::ZeroBasedVector) = (0:length(v)-1,) + Base.getindex(v::ZeroBasedVector, i::Integer) = v.data[i+1] + Base.setindex!(v::ZeroBasedVector, x, i::Integer) = (v.data[i+1] = x) + + data0 = ZeroBasedVector([10,20,30]) + v0 = HVI.OneBasedVectorWithZero(data0) + @test eltype(v0) == Int + @test @inferred v0[1] == 10 + @test v0[2] == 20 + @test v0[3] == 30 + + v0[1] = 100 + @test v0[1] == 100 + @test v0.data[0] == 100 + + # bounds for non-zero indices should be 1..length for wrapper independent of underlying axis + @test v0[0] == 0 + @test_throws BoundsError v0[-1] + @test_throws BoundsError v0[4] + @test_throws BoundsError v0[0] = 50 + + @test collect(v0) == [100,20,30] + @test length(v0) == 3 + @test axes(v0) == (Base.OneTo(3),) + + # gradient pass through values works + g = Zygote.gradient(x -> sum(HVI.OneBasedVectorWithZero(x)), [1.0, 2.0, 3.0]) + @test g == ([1.0,1.0,1.0],) + + v1 = HVI.OneBasedVectorWithZero([10,20,30]) + # @usingany Cthulhu + # @descend_code_warntype v1[0] + @inferred v1[0] + @test v1[0] == 0 # default value at index 0 is zero + v1 = HVI.OneBasedVectorWithZero([10,20,30]; val_at_zero=-5) + @test @inferred(v1[0]) == -5 # default value at index 0 is zero + @test v1[[1,1,2,3]] == [10,10,20,30] + @test v1[[1,0,0,3]] == [10,-5,-5,30] + g1 = Zygote.gradient(y -> sum(HVI.OneBasedVectorWithZero(y)[[1,1,0,0,2]]), [1.0,2.0,3.0]) + @test g1 == ([2.0,1.0,0.0],) +end; + +@testset "take_n!" begin + it = HVI.drop_iterate(1:5) # initialize the iterator + a1 = HVI.take_n!(it,3) + @test collect(a1) == [1,2,3] + a2 = HVI.take_n!(it,3) + @test collect(a2) == [4,5] # only two element left, so return those + a3 = HVI.take_n!(it,3) + @test collect(a3) == [] # no elements left, so return empty vector +end + @testset "insert_zeros" begin - @test HVI.insert_zeros([1,2,3], [2,4]) == [1,0,2,0,3] - @test HVI.insert_zeros([1,2,3], [1,1]) == [0,0,1,2,3] - @test_throws ArgumentError HVI.insert_zeros([1,2], [4]) - @test HVI.insert_zeros([1,2,3], 2) == [1,0,2,3] - @test @inferred HVI.insert_zeros([1,2,3,4], [1,3,4,7,9]) == [0,1,0,0,2,3,0,4,0] - # position 9 is not available at the beginning, but after inserting 4 zeros, the vector has length 9, so it is valid - @test_throws ArgumentError HVI.insert_zeros([1,2,3,4], reverse([1,3,4,7,9])) - @test Zygote.gradient(x -> sum(HVI.insert_zeros(x, [1,3,4,7,9])), [1,2,3,4]) == ([1.0, 1.0, 1.0, 1.0],) + @test @inferred HVI.insert_zeros([1,2,3], [2,5]) == [1,0,2,3,0] + @test @inferred HVI.insert_zeros([1,2,3], [1,5]) == [0,1,2,3,0] + @test_throws AssertionError HVI.insert_zeros([1,2,3], [2,4]) + @test_throws AssertionError HVI.insert_zeros([1,2,3], [1,1,6]) + Zygote.gradient(x -> sum(HVI.insert_zeros(x, [2,5])), [1,2,3]) + + # + v = HVI.OneBasedVectorWithZero([10,20,30]) + idxs = HVI.insert_zeros(1:length(v), [2,5]) + res = @inferred v[idxs] + # @usingany Cthulhu + #@descend_code_warntype v[idxs] + @test res == [10, 0, 20, 30, 0] + @test Zygote.gradient(x -> sum(x[idxs]), v) == ([1.0, 1.0, 1.0],) end; From 91798bd6276d4dad9c01bf08e466682108bf5b38 Mon Sep 17 00:00:00 2001 From: Thomas Wutzler Date: Tue, 7 Apr 2026 17:37:13 +0000 Subject: [PATCH 10/31] move indices up into Approximation class to avoid repeated computation --- src/HVIApproximation.jl | 25 +++++++++++++++++++++---- src/elbo_scaling.jl | 16 ++++------------ src/util.jl | 2 +- 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/HVIApproximation.jl b/src/HVIApproximation.jl index 2eabd16..700b85d 100644 --- a/src/HVIApproximation.jl +++ b/src/HVIApproximation.jl @@ -53,14 +53,30 @@ TODO: describe multiplication of site-factor, parameter-factor and base_variance for each parameter. """ struct MeanScalingHVIApproximation{T} <: AbstractMeanScalingHVIApproximation - scalingblocks_ends::Vector{Int} - logσ2_ζM_base::Vector{T} + scalingblocks_ends::Vector{Int} # indices of end of blocks with the same scaling factor + # log_var of last parameters in block (to be mulitplied by par_factor and site_factor) + logσ2_ζM_bases::Vector{T} # already repeated for blocks in parameters + # indexing into logσ2_par_offsets_before_end, including repeats and zeros + idxs_par0::Vector{Int} + # indexing into logσ2_sites including repeats + idxs_repblocks::Vector{Int} end +function MeanScalingHVIApproximation(scalingblocks_ends, logσ2_ζM_base::AbstractVector{T} + ) where T + idxs_par0 = insert_zeros( + 1:(scalingblocks_ends[end] - length(scalingblocks_ends)), scalingblocks_ends) + length_scale_blocks = vcat(first(scalingblocks_ends), diff(scalingblocks_ends)) + idxs_repblocks = vcat((fill(i, length_scale_blocks[i]) for i in axes(length_scale_blocks,1))...) + logσ2_ζM_bases = reduce(vcat, fill.(logσ2_ζM_base, length_scale_blocks)) + MeanScalingHVIApproximation{T}( + scalingblocks_ends, logσ2_ζM_bases, idxs_par0, idxs_repblocks) +end + function MeanScalingHVIApproximation{T}(approx::AbstractMeanScalingHVIApproximation; scalingblocks_ends = approx.scalingblocks_ends, - logσ2_ζM_base = approx.logσ2_ζM_base, + logσ2_ζM_base::AbstractVector{T} = approx.logσ2_ζM_bases[scalingblocks_ends], ) where T - MeanScalingHVIApproximation{T}(scalingblocks_ends, logσ2_ζM_base) + MeanScalingHVIApproximation(scalingblocks_ends, logσ2_ζM_base) end function get_numberof_MLinputs(approx::MeanScalingHVIApproximation, θM) length(θM) + length(approx.scalingblocks_ends) @@ -70,3 +86,4 @@ function get_numberof_θM(approx::MeanScalingHVIApproximation, ml_pred::Abstract # corresponds to the number of overall parameters. approx.scalingblocks_ends[end] end + diff --git a/src/elbo_scaling.jl b/src/elbo_scaling.jl index 310333a..e73b5a7 100644 --- a/src/elbo_scaling.jl +++ b/src/elbo_scaling.jl @@ -13,14 +13,9 @@ function sample_ζresid_norm(approx::AbstractMeanScalingHVIApproximation, ) where {T,TM<:AbstractMatrix{T}} ϕuncc = ϕqc = int_ϕq(CA.getdata(ϕq)) # add 0 as last logσ2_par_offset-par in block - b_ends = ChainRulesCore.ignore_derivatives(approx.scalingblocks_ends) logσ2_par_offsets_before_end = OneBasedVectorWithZero(ϕqc[Val(:logσ2_ζM_offsets)]) - # TODO move idxs_par0 and idxs_repblocks to approx and create during initialization - idxs_par0 = insert_zeros(1:length(logσ2_par_offsets_before_end), b_ends) - # insert zeros at the end of each block of parameters - logσ2_par_offsets = logσ2_par_offsets_before_end[idxs_par0] - length_scale_blocks = vcat(first(b_ends), diff(b_ends)) - n_scale_blocks = length(b_ends) + logσ2_par_offsets = logσ2_par_offsets_before_end[approx.idxs_par0] + n_scale_blocks = length(approx.scalingblocks_ends) n_par = size(ϕm,1) - n_scale_blocks ζMs = ϕm[1:n_par,:] logσ2_sites = ϕm[(n_par+1):end,:] @@ -34,11 +29,8 @@ function sample_ζresid_norm(approx::AbstractMeanScalingHVIApproximation, # coefficients ρsM can be larger than 1, still yielding correlations <1 in UM' * UM UM = transformU_block_cholesky1(ρsM, cor_ends.M) # - idxs_repblocks = vcat((fill(i, length_scale_blocks[i]) for i in axes(length_scale_blocks,1))...) - logσ2_site_offsets = logσ2_sites[idxs_repblocks,:] - # TODO fill.(approx.logσ2_ζM_base already during initialization of approx - logσ2_ζM_bases = reduce(vcat, fill.(approx.logσ2_ζM_base, length_scale_blocks)) - logσ2_ζMs = logσ2_ζM_bases .+ logσ2_par_offsets .+ logσ2_site_offsets + logσ2_site_offsets = logσ2_sites[approx.idxs_repblocks,:] + logσ2_ζMs = approx.logσ2_ζM_bases .+ logσ2_par_offsets .+ logσ2_site_offsets # logσ2_ζP = vec(CA.getdata(ϕuncc[Val(:logσ2_ζP)])) # CUDA cannot multiply BlockDiagonal * Diagonal, construct already those blocks diff --git a/src/util.jl b/src/util.jl index 649c925..a9b04f2 100644 --- a/src/util.jl +++ b/src/util.jl @@ -73,7 +73,7 @@ Only one output vector is allocated. function insert_zeros(v::AbstractVector, positions::AbstractVector{<:Integer}) # does not work with Zygote, but its only used to create the indexing vector # v = [10,20,30];positions = [2, 5] # means insert zeros before original v[2] and v[4], so final output has zeros at those positions. - @assert length(v)+ length(positions) == positions[end] "The last position in `positions` must be equal to the final length of the output vector after all insertions." + @assert length(v) + length(positions) == positions[end] "The last position in `positions` must be equal to the final length of the output vector after all insertions." dpos1 = diff(positions) .- 1 @assert all(dpos1 .>= 0) "Positions must be in strictly ascending order." # length of blocks before insert is diff(postions) -1 From 80e82e13922201907a12e574be43354ca20684b8 Mon Sep 17 00:00:00 2001 From: Thomas Wutzler Date: Tue, 7 Apr 2026 17:57:49 +0000 Subject: [PATCH 11/31] test M3 scenario with 2 scaling blocks --- src/DoubleMM/f_doubleMM.jl | 28 +++++++++++++++++++++++----- src/ModelApplicator.jl | 1 + src/elbo_scaling.jl | 9 +++++---- src/init_hybrid_params.jl | 10 +++++++--- test/test_elbo.jl | 6 ++++-- 5 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/DoubleMM/f_doubleMM.jl b/src/DoubleMM/f_doubleMM.jl index 5341a17..9003859 100644 --- a/src/DoubleMM/f_doubleMM.jl +++ b/src/DoubleMM/f_doubleMM.jl @@ -8,6 +8,9 @@ const θP_nor0 = θP[(:K2,)] θP_nor0_K1 = θM[(:K1,)] θM_nor0_K1 = vcat(θM[(:r1,)], θP[(:K2,)]) +# scenrio with three components in θM to test scaling blocks +θP_M3 = θP[(:r0,)] +θM_M3 = vcat(θP[(:K2,)], θM) const xP_S1 = Float32[0.5, 0.5, 0.5, 0.5, 0.4, 0.3, 0.2, 0.1] const xP_S2 = Float32[1.0, 3.0, 4.0, 5.0, 5.0, 5.0, 5.0, 5.0] @@ -177,6 +180,11 @@ function HVI.get_hybridproblem_par_templates( end return ((; θP = θP_nor0, θM)) end + if (:M3 ∈ scen) + # three components in θM + return ((; θP = θP_M3, θM = θM_M3)) + end + #(; θP, θM, θf = eltype(θP)[]) (; θP, θM) end @@ -212,7 +220,7 @@ function HVI.get_hybridproblem_MLapplicator( (; transM) = get_hybridproblem_transforms(prob; scenario) lowers, uppers = HVI.get_quantile_transformed(priors, transM) #n_site, n_batch = get_hybridproblem_n_site_and_batch(prob; scenario) - range_scaled = if (:scalingall ∈ scen) + range_scaled = if any((:scalingall, :M3) .∈ Ref(scen)) 1:length(θM) else 1:0 @@ -372,15 +380,16 @@ function HVI.gen_hybridproblem_synthetic(rng::AbstractRNG, prob::DoubleMMCase; scenario::Val{scen}, n_site_test = 0) where {scen} n_covar_pc = 2 n_site, n_batch = get_hybridproblem_n_site_and_batch(prob; scenario) + pt = get_hybridproblem_par_templates(prob; scenario) n_siteall = n_site + n_site_test n_covar = get_hybridproblem_n_covar(prob; scenario) - n_θM = length(θM) + n_θM = length(pt.θM) FloatType = get_hybridproblem_float_type(prob; scenario) xM, θMs_true0 = gen_cov_pred(rng, FloatType, n_covar_pc, n_covar, n_siteall, n_θM; rhodec = 8, is_using_dropout = false) - int_θMs_sites = ComponentArrayInterpreter(θM, (n_siteall,)) + int_θMs_sites = ComponentArrayInterpreter(pt.θM, (n_siteall,)) # normalize to be distributed around the prescribed true values - θMs_true = int_θMs_sites(scale_centered_at(θMs_true0, θM, FloatType(0.1))) + θMs_true = int_θMs_sites(scale_centered_at(θMs_true0, pt.θM, FloatType(0.1))) f_batch = get_hybridproblem_PBmodel(prob; scenario) f = create_nsite_applicator(f_batch, n_siteall) #xP = fill((; S1 = xP_S1, S2 = xP_S2), n_siteall) @@ -411,6 +420,8 @@ function HVI.get_hybridproblem_cor_ends(prob::DoubleMMCase; scenario::Val{scen}) if (:neglect_cor ∈ scen) # one block for each parameter, i.e. neglect all correlations (P = 1:length(pt.θP), M = 1:length(pt.θM)) + elseif (:M3 ∈ scen) + (P = 1:length(pt.θP), M = [1,length(pt.θM)]) # last two parameters else # single big blocks (P = [length(pt.θP)], M = [length(pt.θM)]) @@ -438,7 +449,14 @@ function HVI.get_hybridproblem_HVIApproximation(prob::DoubleMMCase; scenario::Va approx = if (:scalingall ∈ scen) (;θP, θM) = get_hybridproblem_par_templates(prob; scenario) FT = eltype(θM) - MeanScalingHVIApproximation([length(θM)],FT(2) .* log.([FT(0.1) * θM[end]])) + block_ends = [length(θM)] + MeanScalingHVIApproximation(block_ends,FT(2) .* log.(FT(0.1) .* θM[block_ends])) + elseif (:M3 ∈ scen) + # last two parameters own scaling + (;θP, θM) = get_hybridproblem_par_templates(prob; scenario) + FT = eltype(θM) + block_ends = [1,length(θM)] + MeanScalingHVIApproximation(block_ends,FT(2) .* log.(FT(0.1) .* θM[block_ends])) elseif (:sepvar ∈ scen) MeanVarSepHVIApproximation() else diff --git a/src/ModelApplicator.jl b/src/ModelApplicator.jl index 6304662..64b0d91 100644 --- a/src/ModelApplicator.jl +++ b/src/ModelApplicator.jl @@ -167,6 +167,7 @@ end Fit a Normal distribution to number iterators `lower` and `upper` and transform results of the wrapped `app` `AbstractModelApplicator`. +The results of the inner applicator are assumed to be (0,1). If `repeat_inner` is given, each fitted distribution is repeated as many times to support independent multivariate normal distribution. diff --git a/src/elbo_scaling.jl b/src/elbo_scaling.jl index e73b5a7..dd3f730 100644 --- a/src/elbo_scaling.jl +++ b/src/elbo_scaling.jl @@ -18,18 +18,19 @@ function sample_ζresid_norm(approx::AbstractMeanScalingHVIApproximation, n_scale_blocks = length(approx.scalingblocks_ends) n_par = size(ϕm,1) - n_scale_blocks ζMs = ϕm[1:n_par,:] - logσ2_sites = ϕm[(n_par+1):end,:] + logσ2_sites_offset_blocks = logit.(ϕm[(n_par+1):end,:]) # (0..1)->(-Inf, +Inf), 0.5->0 ζP = ϕqc[Val(:μP)] n_θP, n_θMs, (n_θM, n_batch) = length(ζP), length(ζMs), size(ζMs) # do not create a UpperTriangular Matrix of an AbgeneraGÜUArray in transformU_cholesky1 - ρsP = isempty(ϕuncc[Val(:ρsP)]) ? similar(ϕuncc[Val(:ρsP)]) : ϕuncc[Val(:ρsP)] # required by zygote + # isempty conditional required by zygote + ρsP = isempty(ϕuncc[Val(:ρsP)]) ? similar(ϕuncc[Val(:ρsP)]) : ϕuncc[Val(:ρsP)] UP = transformU_block_cholesky1(ρsP, cor_ends.P) - ρsM = isempty(ϕuncc[Val(:ρsM)]) ? similar(ϕuncc[Val(:ρsM)]) : ϕuncc[Val(:ρsM)] # required by zygote + ρsM = isempty(ϕuncc[Val(:ρsM)]) ? similar(ϕuncc[Val(:ρsM)]) : ϕuncc[Val(:ρsM)] # cholesky factor of the correlation: diag(UM' * UM) .== 1 # coefficients ρsM can be larger than 1, still yielding correlations <1 in UM' * UM UM = transformU_block_cholesky1(ρsM, cor_ends.M) # - logσ2_site_offsets = logσ2_sites[approx.idxs_repblocks,:] + logσ2_site_offsets = logσ2_sites_offset_blocks[approx.idxs_repblocks,:] logσ2_ζMs = approx.logσ2_ζM_bases .+ logσ2_par_offsets .+ logσ2_site_offsets # logσ2_ζP = vec(CA.getdata(ϕuncc[Val(:logσ2_ζP)])) diff --git a/src/init_hybrid_params.jl b/src/init_hybrid_params.jl index 06c56f8..d5108a1 100644 --- a/src/init_hybrid_params.jl +++ b/src/init_hybrid_params.jl @@ -201,15 +201,19 @@ function init_hybrid_ϕunc( error("check and implement inferring median logσ2 from logσ2_ζMs") median(logσ2_ζMs; dims=1) end - is_end = approx.scalingblocks_ends # abbreviations + is_end = approx.scalingblocks_ends # abbreviation # update logσ2_ζM_base of last parameter in approx - its not calibrated approx = SApp(approx; logσ2_ζM_base = logσ2[is_end]) - is_offset = range.(vcat(1,is_end[1:(end-1)]),(is_end .- 1)) # excluding last parameter + is_par_offset = range.(vcat(1,is_end[1:(end-1)]),(is_end .- 1)) # excluding last parameter + length_scale_blocks = vcat(first(is_end), diff(is_end)) + is_par_offset = range.((is_end .- length_scale_blocks .+ 1),(is_end .- 1)) # excluding last parameter # need to provide plain vector and sort out positions in apply to satisfy Zygote # logσ2_ζM_offsets = map(is_end, is_offset) do i_end, is_offset # logσ2[is_offset] .- logσ2[i_end] # end - logσ2_ζM_offsets_gen = (logσ2[is_offset] .- logσ2[i_end] for (i_end, is_offset) in zip(is_end, is_offset)) + logσ2_ζM_offsets_gen = (logσ2[is_offset] .- logσ2[i_end] for + (i_end, is_offset) in zip(is_end, is_par_offset)) + #collect(logσ2_ζM_offsets_gen) logσ2_ζM_offsets = vcat(logσ2_ζM_offsets_gen...) #tmp = CA.ComponentVector(;zip(Symbol.(axes(is_offset,1)), logσ2_ζM_offsets_gen)...) nt = (; diff --git a/test/test_elbo.jl b/test/test_elbo.jl index 20ed886..887e8f6 100644 --- a/test/test_elbo.jl +++ b/test/test_elbo.jl @@ -27,6 +27,7 @@ rng = StableRNG(111) const prob = DoubleMM.DoubleMMCase() scenario = Val((:covarK2,)) scenario = Val((:scalingall,)) +scenario = Val((:M3,)) scenario = Val((:sepvar,)) scenario = Val((:default,)) @@ -69,7 +70,7 @@ test_scenario = (scenario) -> begin f = get_hybridproblem_PBmodel(probc; scenario) f_pred = create_nsite_applicator(f, n_site) - n_θM, n_θP = values(map(length, par_templates)) + n_θP, n_θM = values(map(length, par_templates)) py = neg_logden_indep_normal @@ -512,7 +513,8 @@ test_scenario = (scenario) -> begin end # test_scenario -test_scenario(Val((:scalingall,))) +#test_scenario(Val((:scalingall,))) +test_scenario(Val((:M3,))) test_scenario(Val((:default,))) test_scenario(Val((:sepvar,))) From 9fde8952f54bc7bd2bdaddae74fd2b0f361175b3 Mon Sep 17 00:00:00 2001 From: Thomas Wutzler Date: Wed, 8 Apr 2026 15:57:03 +0000 Subject: [PATCH 12/31] update the tutorial to use the ScalingHVIApproximation --- docs/src/tutorials/Manifest-v1.11.toml | 471 ++++++++++-------- docs/src/tutorials/basic_cpu.md | 47 +- docs/src/tutorials/basic_cpu.qmd | 44 +- docs/src/tutorials/basic_cpu_mean.md | 372 ++++++++++++++ docs/src/tutorials/basic_cpu_mean.qmd | 415 +++++++++++++++ docs/src/tutorials/blocks_corr.md | 2 +- .../figure-commonmark/cell-10-output-1.png | Bin 97959 -> 104652 bytes .../figure-commonmark/cell-11-output-1.png | Bin 105495 -> 110964 bytes .../figure-commonmark/cell-12-output-1.png | Bin 68473 -> 73443 bytes docs/src/tutorials/inspect_results.qmd | 22 +- .../intermediate/basic_cpu_mean_results.jld2 | Bin 0 -> 193513 bytes .../intermediate/basic_cpu_results.jld2 | Bin 193465 -> 194044 bytes intermediate/basic_cpu_results.jld2 | Bin 0 -> 194044 bytes src/HybridProblem.jl | 2 +- 14 files changed, 1133 insertions(+), 242 deletions(-) create mode 100644 docs/src/tutorials/basic_cpu_mean.md create mode 100644 docs/src/tutorials/basic_cpu_mean.qmd create mode 100644 docs/src/tutorials/intermediate/basic_cpu_mean_results.jld2 create mode 100644 intermediate/basic_cpu_results.jld2 diff --git a/docs/src/tutorials/Manifest-v1.11.toml b/docs/src/tutorials/Manifest-v1.11.toml index 4f4e554..4a282b3 100644 --- a/docs/src/tutorials/Manifest-v1.11.toml +++ b/docs/src/tutorials/Manifest-v1.11.toml @@ -26,6 +26,30 @@ weakdeps = ["ChainRulesCore", "Test"] AbstractFFTsChainRulesCoreExt = "ChainRulesCore" AbstractFFTsTestExt = "Test" +[[deps.AbstractMCMC]] +deps = ["BangBang", "ConsoleProgressMonitor", "Dates", "Distributed", "LogDensityProblems", "Logging", "LoggingExtras", "ProgressLogging", "Random", "StatsBase", "TerminalLoggers", "UUIDs"] +git-tree-sha1 = "8ac6182431567907e0d5170bcac6dd48fa541f78" +uuid = "80f14c24-f653-4e6a-9b94-39d6b0f70001" +version = "5.15.1" + + [deps.AbstractMCMC.extensions] + AbstractMCMCOnlineStatsExt = "OnlineStats" + AbstractMCMCTensorBoardLoggerExt = "TensorBoardLogger" + + [deps.AbstractMCMC.weakdeps] + OnlineStats = "a15396b6-48d5-5d58-9928-6d29437db91e" + TensorBoardLogger = "899adc3e-224a-11e9-021f-63837185c80f" + +[[deps.AbstractPPL]] +deps = ["AbstractMCMC", "Accessors", "BangBang", "DensityInterface", "JSON", "LinearAlgebra", "MacroTools", "OrderedCollections", "Random", "StatsBase"] +git-tree-sha1 = "e7be2de9646c1f61332de9f1e32c7dedf1e00831" +uuid = "7a57a42e-76ec-4ea3-a279-07e840d6d9cf" +version = "0.14.2" +weakdeps = ["Distributions"] + + [deps.AbstractPPL.extensions] + AbstractPPLDistributionsExt = ["Distributions", "LinearAlgebra"] + [[deps.AbstractTrees]] git-tree-sha1 = "2d9c9a55f9c93e8887ad391fbae72f8ef55e1177" uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" @@ -33,9 +57,9 @@ version = "0.4.5" [[deps.Accessors]] deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "MacroTools"] -git-tree-sha1 = "856ecd7cebb68e5fc87abecd2326ad59f0f911f3" +git-tree-sha1 = "2eeb2c9bef11013efc6f8f97f32ee59b146b09fb" uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" -version = "0.1.43" +version = "0.1.44" [deps.Accessors.extensions] AxisKeysExt = "AxisKeys" @@ -57,9 +81,9 @@ version = "0.1.43" [[deps.Adapt]] deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "7e35fca2bdfba44d797c53dfe63a51fabf39bfc0" +git-tree-sha1 = "35ea197a51ce46fcd01c4a44befce0578a1aaeca" uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "4.4.0" +version = "4.5.0" weakdeps = ["SparseArrays", "StaticArrays"] [deps.Adapt.extensions] @@ -94,11 +118,12 @@ version = "1.1.2" [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra"] -git-tree-sha1 = "d81ae5489e13bc03567d4fbbb06c546a5e53c857" +git-tree-sha1 = "78b3a7a536b4b0a747a0f296ea77091ca0a9f9a3" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.22.0" +version = "7.23.0" [deps.ArrayInterface.extensions] + ArrayInterfaceAMDGPUExt = "AMDGPU" ArrayInterfaceBandedMatricesExt = "BandedMatrices" ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" ArrayInterfaceCUDAExt = "CUDA" @@ -113,6 +138,7 @@ version = "7.22.0" ArrayInterfaceTrackerExt = "Tracker" [deps.ArrayInterface.weakdeps] + AMDGPU = "21141c5a-9bdb-4563-92ae-f87d6854732e" BandedMatrices = "aae01518-5342-5314-be14-df237901396f" BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" @@ -132,9 +158,9 @@ version = "1.11.0" [[deps.Atomix]] deps = ["UnsafeAtomics"] -git-tree-sha1 = "29bb0eb6f578a587a49da16564705968667f5fa8" +git-tree-sha1 = "b8651b2eb5796a386b0398a20b519a6a6150f75c" uuid = "a9b6321e-bd34-4604-b9c9-b65b8de01458" -version = "1.1.2" +version = "1.1.3" [deps.Atomix.extensions] AtomixCUDAExt = "CUDA" @@ -174,9 +200,9 @@ version = "0.6.1" [[deps.BangBang]] deps = ["Accessors", "ConstructionBase", "InitialValues", "LinearAlgebra"] -git-tree-sha1 = "308d82aa3d83140909590aa5a7824540944f110f" +git-tree-sha1 = "cceb62468025be98d42a5dc581b163c20896b040" uuid = "198e06fe-97b7-11e9-32a5-e1d131e6ad66" -version = "0.4.8" +version = "0.4.9" [deps.BangBang.extensions] BangBangChainRulesCoreExt = "ChainRulesCore" @@ -209,14 +235,13 @@ uuid = "9718e550-a3fa-408a-8086-8db961cd8217" version = "0.1.1" [[deps.Bijectors]] -deps = ["ArgCheck", "ChainRulesCore", "ChangesOfVariables", "Distributions", "DocStringExtensions", "Functors", "InverseFunctions", "IrrationalConstants", "LinearAlgebra", "LogExpFunctions", "MappedArrays", "Random", "Reexport", "Roots", "SparseArrays", "Statistics"] -git-tree-sha1 = "52f3f101c0c541145da25fba9805f3ef076f2d96" +deps = ["AbstractPPL", "ArgCheck", "ChainRulesCore", "ChangesOfVariables", "DifferentiationInterface", "Distributions", "DocStringExtensions", "EnzymeCore", "FillArrays", "Functors", "InverseFunctions", "IrrationalConstants", "LinearAlgebra", "LogExpFunctions", "MappedArrays", "Random", "Reexport", "Roots", "SparseArrays", "Statistics", "Test"] +git-tree-sha1 = "d6ee8f89dd20f933fbdad578a798e32babb617ee" uuid = "76274a88-744f-5084-9051-94815aaf08c4" -version = "0.15.16" +version = "0.15.20" [deps.Bijectors.extensions] BijectorsDistributionsADExt = "DistributionsAD" - BijectorsEnzymeCoreExt = "EnzymeCore" BijectorsForwardDiffExt = "ForwardDiff" BijectorsLazyArraysExt = "LazyArrays" BijectorsMooncakeExt = "Mooncake" @@ -226,7 +251,6 @@ version = "0.15.16" [deps.Bijectors.weakdeps] ChainRules = "082447d4-558c-5d27-93f4-14fc19e9eca2" DistributionsAD = "ced4e74d-a319-5a8a-b0ac-84af2272839c" - EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" LazyArrays = "5078a376-72f3-5289-bfd5-ec5146d43c02" Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" @@ -287,10 +311,10 @@ uuid = "4e9b3aee-d8a1-5a3d-ad8b-7d824db253f0" version = "1.0.1+0" [[deps.CUDA]] -deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Compiler_jll", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "DataFrames", "ExprTools", "GPUArrays", "GPUCompiler", "GPUToolbox", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "SparseArrays", "StaticArrays", "Statistics", "demumble_jll"] -git-tree-sha1 = "3fe1fb600b6ec029697416d5851ef0661c538f20" +deps = ["AbstractFFTs", "Adapt", "BFloat16s", "CEnum", "CUDA_Compiler_jll", "CUDA_Driver_jll", "CUDA_Runtime_Discovery", "CUDA_Runtime_jll", "Crayons", "ExprTools", "GPUArrays", "GPUCompiler", "GPUToolbox", "KernelAbstractions", "LLVM", "LLVMLoopInfo", "LazyArtifacts", "Libdl", "LinearAlgebra", "Logging", "NVTX", "Preferences", "PrettyTables", "Printf", "Random", "Random123", "RandomNumbers", "Reexport", "SparseArrays", "StaticArrays", "Statistics", "demumble_jll"] +git-tree-sha1 = "ea6a2ab8307059b6c9ea186ff7dfcd032a13b731" uuid = "052768ef-5323-5732-b1bb-66c8b64840ba" -version = "5.9.6" +version = "5.11.0" [deps.CUDA.extensions] ChainRulesCoreExt = "ChainRulesCore" @@ -306,15 +330,15 @@ version = "5.9.6" [[deps.CUDA_Compiler_jll]] deps = ["Artifacts", "CUDA_Driver_jll", "CUDA_Runtime_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "e547b2202721853ec06c6d9a71c87426419ba765" +git-tree-sha1 = "8c19e97de5b7574672e4a7a3abd55714ad66d59a" uuid = "d1e2174e-dfdc-576e-b43e-73b79eb1aca8" -version = "0.4.1+1" +version = "0.4.2+0" [[deps.CUDA_Driver_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "23bf4e60006b78544f753880fbcf1aa158a7669c" +deps = ["Artifacts", "JLLWrappers", "Libdl", "TOML"] +git-tree-sha1 = "061f39cc84e99928830aa1005d79f7e99097ba28" uuid = "4ee394cb-3365-5eb0-8335-949819d2adfc" -version = "13.1.0+2" +version = "13.2.0+0" [[deps.CUDA_Runtime_Discovery]] deps = ["Libdl"] @@ -324,15 +348,15 @@ version = "1.0.0" [[deps.CUDA_Runtime_jll]] deps = ["Artifacts", "CUDA_Driver_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "92cd84e2b760e471d647153ea5efc5789fc5e8b2" +git-tree-sha1 = "af17d37b5b8b4d7525f8902eba1ef6141a9a7d3b" uuid = "76a88914-d11a-5bdc-97e0-2f5a05c973a2" -version = "0.19.2+0" +version = "0.21.0+0" [[deps.CUDNN_jll]] deps = ["Artifacts", "CUDA_Runtime_jll", "JLLWrappers", "LazyArtifacts", "Libdl", "TOML"] -git-tree-sha1 = "dff9a69017686c95f1fd601c63c088244b3db75b" +git-tree-sha1 = "70dea6a7133d2100a143b515a00d6d887e208500" uuid = "62b44479-cb7b-5706-934f-f13b2eb2e645" -version = "9.17.1+0" +version = "9.20.0+0" [[deps.Cairo]] deps = ["Cairo_jll", "Colors", "Glib_jll", "Graphics", "Libdl", "Pango_jll"] @@ -342,15 +366,15 @@ version = "1.1.1" [[deps.CairoMakie]] deps = ["CRC32c", "Cairo", "Cairo_jll", "Colors", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "PrecompileTools"] -git-tree-sha1 = "5017d6849aff775febd36049f7d926a5fb6677ec" +git-tree-sha1 = "fa072933899aae6dc61dde934febed8254e66c6a" uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" -version = "0.15.8" +version = "0.15.9" [[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 = "a21c5464519504e41e0cbc91f0188e8ca23d7440" +deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] +git-tree-sha1 = "d0efe2c6fdcdaa1c161d206aa8b933788397ec71" uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" -version = "1.18.5+1" +version = "1.18.6+0" [[deps.ChainRules]] deps = ["Adapt", "ChainRulesCore", "Compat", "Distributed", "GPUArraysCore", "IrrationalConstants", "LinearAlgebra", "Random", "RealDot", "SparseArrays", "SparseInverseSubset", "Statistics", "StructArrays", "SuiteSparse"] @@ -360,9 +384,9 @@ version = "1.73.0" [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "e4c6a16e77171a5f5e25e9646617ab1c276c5607" +git-tree-sha1 = "12177ad6b3cad7fd50c8b3825ce24a99ad61c18f" uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.26.0" +version = "1.26.1" weakdeps = ["SparseArrays"] [deps.ChainRulesCore.extensions] @@ -484,13 +508,14 @@ version = "1.1.1+0" [[deps.ComponentArrays]] deps = ["Adapt", "ArrayInterface", "ChainRulesCore", "ConstructionBase", "Functors", "LinearAlgebra", "StaticArrayInterface", "StaticArraysCore"] -git-tree-sha1 = "0d1b8b3d556d70a29ad515325cd2f5f4ed703e09" +git-tree-sha1 = "f9873e13c3f89808e518118951eb6b244f7af735" uuid = "b0b7db55-cfe3-40fc-9ded-d10e2dbeff66" -version = "0.15.32" +version = "0.15.33" [deps.ComponentArrays.extensions] ComponentArraysGPUArraysExt = "GPUArrays" ComponentArraysKernelAbstractionsExt = "KernelAbstractions" + ComponentArraysMooncakeExt = "Mooncake" ComponentArraysOptimisersExt = "Optimisers" ComponentArraysReactantExt = "Reactant" ComponentArraysRecursiveArrayToolsExt = "RecursiveArrayTools" @@ -502,6 +527,7 @@ version = "0.15.32" [deps.ComponentArrays.weakdeps] GPUArrays = "0c68f7d7-f131-5f86-a1c3-88cf8149b2d7" KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" + Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" Optimisers = "3bd65402-5787-11e9-1adc-39752487f4e2" Reactant = "3c362404-f566-11ee-1572-e11a4b42c853" RecursiveArrayTools = "731186ca-8d62-57ce-b412-fbd966d074cd" @@ -521,9 +547,9 @@ weakdeps = ["InverseFunctions"] [[deps.ComputePipeline]] deps = ["Observables", "Preferences"] -git-tree-sha1 = "76dab592fa553e378f9dd8adea16fe2591aa3daa" +git-tree-sha1 = "3b4be73db165146d8a88e47924f464e55ab053cd" uuid = "95dc2771-c249-4cd0-9c9f-1f3b4330693c" -version = "0.1.6" +version = "0.1.7" [[deps.ConcreteStructs]] git-tree-sha1 = "f749037478283d372048690eb3b5f92a79432b34" @@ -532,9 +558,9 @@ version = "0.2.3" [[deps.ConcurrentUtilities]] deps = ["Serialization", "Sockets"] -git-tree-sha1 = "d9d26935a0bcffc87d2613ce14c527c99fc543fd" +git-tree-sha1 = "21d088c496ea22914fe80906eb5bce65755e5ec8" uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb" -version = "2.5.0" +version = "2.5.1" [[deps.ConsoleProgressMonitor]] deps = ["Logging", "ProgressMeter"] @@ -564,6 +590,18 @@ git-tree-sha1 = "439e35b0b36e2e5881738abc8857bd92ad6ff9a8" uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" version = "0.6.3" +[[deps.CoreMath]] +deps = ["CoreMath_jll"] +git-tree-sha1 = "8c0480f92b1b1796239156a1b9b1bfb1b39499b4" +uuid = "b7a15901-be09-4a0e-87d2-2e66b0e09b5a" +version = "0.1.0" + +[[deps.CoreMath_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "a692a4c1dc59a4b8bc0b6403876eb3250fde2bc3" +uuid = "a38c48d9-6df1-5ac9-9223-b6ada3b5572b" +version = "0.1.0+0" + [[deps.CpuId]] deps = ["Markdown"] git-tree-sha1 = "fcbb72b032692610bfbdb15018ac16a36cf2e406" @@ -580,17 +618,11 @@ git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe" uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" version = "1.16.0" -[[deps.DataFrames]] -deps = ["Compat", "DataAPI", "DataStructures", "Future", "InlineStrings", "InvertedIndices", "IteratorInterfaceExtensions", "LinearAlgebra", "Markdown", "Missings", "PooledArrays", "PrecompileTools", "PrettyTables", "Printf", "Random", "Reexport", "SentinelArrays", "SortingAlgorithms", "Statistics", "TableTraits", "Tables", "Unicode"] -git-tree-sha1 = "d8928e9169ff76c6281f39a659f9bca3a573f24c" -uuid = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" -version = "1.8.1" - [[deps.DataStructures]] deps = ["OrderedCollections"] -git-tree-sha1 = "e357641bb3e0638d353c4b29ea0e40ea644066a6" +git-tree-sha1 = "e86f4a2805f7f19bec5129bc9150c38208e5dc23" uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.19.3" +version = "0.19.4" [[deps.DataValueInterfaces]] git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" @@ -625,6 +657,12 @@ git-tree-sha1 = "9e2f36d3c96a820c678f2f1f1782582fcf685bae" uuid = "8bb1440f-4735-579b-a4ab-409b98df4dab" version = "1.9.1" +[[deps.DensityInterface]] +deps = ["InverseFunctions", "Test"] +git-tree-sha1 = "80c3e8639e3353e5d2912fb3a1916b8455e2494b" +uuid = "b429d917-457f-4dbc-8f4c-0cc954292b1d" +version = "0.4.0" + [[deps.DiffResults]] deps = ["StaticArraysCore"] git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" @@ -720,17 +758,13 @@ deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadG git-tree-sha1 = "fbcc7610f6d8348428f722ecbe0e6cfe22e672c6" uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" version = "0.25.123" +weakdeps = ["ChainRulesCore", "DensityInterface", "Test"] [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" @@ -748,14 +782,14 @@ uuid = "5ae413db-bbd1-5e63-b57d-d24a61df00f5" version = "2.2.4+0" [[deps.EnumX]] -git-tree-sha1 = "7bebc8aad6ee6217c78c5ddcf7ed289d65d0263e" +git-tree-sha1 = "c49898e8438c828577f04b92fc9368c388ac783c" uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" -version = "1.0.6" +version = "1.0.7" [[deps.EnzymeCore]] -git-tree-sha1 = "990991b8aa76d17693a98e3a915ac7aa49f08d1a" +git-tree-sha1 = "24bbb6fc8fb87eb71c1f8d00184a60fc22c63903" uuid = "f151be2c-9106-41f4-ab19-57ee4f262869" -version = "0.8.18" +version = "0.8.19" weakdeps = ["Adapt", "ChainRulesCore"] [deps.EnzymeCore.extensions] @@ -813,10 +847,10 @@ 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 = "01ba9d15e9eae375dc1eb9589df76b3572acd3f2" +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libva_jll", "libvorbis_jll", "x264_jll", "x265_jll"] +git-tree-sha1 = "66381d7059b5f3f6162f28831854008040a4e905" uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" -version = "8.0.1+0" +version = "8.0.1+1" [[deps.FFTA]] deps = ["AbstractFFTs", "DocStringExtensions", "LinearAlgebra", "MuladdMacro", "Primes", "Random", "Reexport"] @@ -914,9 +948,9 @@ version = "1.3.7" [[deps.ForwardDiff]] deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] -git-tree-sha1 = "eef4c86803f47dcb61e9b8790ecaa96956fdd8ae" +git-tree-sha1 = "cddeab6487248a39dae1a960fff0ac17b2a28888" uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "1.3.2" +version = "1.3.3" weakdeps = ["StaticArrays"] [deps.ForwardDiff.extensions] @@ -930,9 +964,9 @@ version = "4.1.1" [[deps.FreeType2_jll]] deps = ["Artifacts", "Bzip2_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "2c5512e11c791d1baed2049c5652441b28fc6a31" +git-tree-sha1 = "70329abc09b886fd2c5d94ad2d9527639c421e3e" uuid = "d7e528f0-a631-5988-bf34-fe36492bcfd7" -version = "2.13.4+0" +version = "2.14.3+1" [[deps.FreeTypeAbstraction]] deps = ["BaseDirs", "ColorVectorSpace", "Colors", "FreeType", "GeometryBasics", "Mmap"] @@ -952,10 +986,17 @@ uuid = "069b7b12-0de2-55c6-9aab-29f3d0a68a2e" version = "1.1.3" [[deps.FunctionWrappersWrappers]] -deps = ["FunctionWrappers"] -git-tree-sha1 = "b104d487b34566608f8b4e1c39fb0b10aa279ff8" +deps = ["FunctionWrappers", "PrecompileTools", "TruncatedStacktraces"] +git-tree-sha1 = "5201523536a43bf8aef3914b7f60b552b098ef8e" uuid = "77dc65aa-8811-40c2-897b-53d922fa7daf" -version = "0.1.3" +version = "1.1.0" + + [deps.FunctionWrappersWrappers.extensions] + FunctionWrappersWrappersEnzymeExt = ["Enzyme", "EnzymeCore"] + + [deps.FunctionWrappersWrappers.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" + EnzymeCore = "f151be2c-9106-41f4-ab19-57ee4f262869" [[deps.Functors]] deps = ["Compat", "ConstructionBase", "LinearAlgebra", "Random"] @@ -992,21 +1033,21 @@ version = "0.2.0" [[deps.GPUCompiler]] deps = ["ExprTools", "InteractiveUtils", "LLVM", "Libdl", "Logging", "PrecompileTools", "Preferences", "Scratch", "Serialization", "TOML", "Tracy", "UUIDs"] -git-tree-sha1 = "966946d226e8b676ca6409454718accb18c34c54" +git-tree-sha1 = "fedfe5e7db7035271c3f58359007f971da1dde87" uuid = "61eb1bfa-7361-4325-ad38-22787b887f55" -version = "1.8.2" +version = "1.9.1" [[deps.GPUToolbox]] deps = ["LLVM"] -git-tree-sha1 = "9e9186b09a13b7f094f87d1a9bb266d8780e1b1c" +git-tree-sha1 = "a589b6c1a0eff953571f5d8b0474f5020831114d" uuid = "096a3bc2-3ced-46d0-87f4-dd12716f4bfc" -version = "1.0.0" +version = "1.1.1" [[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 = "ee0585b62671ce88e48d3409733230b401c9775c" +git-tree-sha1 = "44716a1a667cb867ee0e9ec8edc31c3e4aa5afdc" uuid = "28b8d3ca-fb5f-59d9-8090-bfdbd6d07a71" -version = "0.73.22" +version = "0.73.24" [deps.GR.extensions] IJuliaExt = "IJulia" @@ -1016,9 +1057,9 @@ version = "0.73.22" [[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 = "7dd7173f7129a1b6f84e0f03e0890cd1189b0659" +git-tree-sha1 = "be8a1b8065959e24fdc1b51402f39f3b6f0f6653" uuid = "d2c73de3-f751-5644-a686-071e5b155ba9" -version = "0.73.22+0" +version = "0.73.24+0" [[deps.GeometryBasics]] deps = ["EarCut_jll", "Extents", "IterTools", "LinearAlgebra", "PrecompileTools", "Random", "StaticArrays"] @@ -1081,9 +1122,9 @@ 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" +git-tree-sha1 = "51059d23c8bb67911a2e6fd5130229113735fc7e" uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" -version = "1.10.19" +version = "1.11.0" [[deps.HarfBuzz_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll"] @@ -1103,7 +1144,7 @@ uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" version = "0.1.18" [[deps.HybridVariationalInference]] -deps = ["Bijectors", "BlockDiagonals", "ChainRulesCore", "Combinatorics", "CommonSolve", "ComponentArrays", "DifferentiationInterface", "DistributionFits", "Distributions", "FillArrays", "Functors", "GPUArraysCore", "KernelAbstractions", "LinearAlgebra", "LogExpFunctions", "MLDataDevices", "MLUtils", "Missings", "NaNMath", "Optimisers", "Optimization", "Random", "StableRNGs", "StaticArrays", "StatsBase", "StatsFuns", "Test", "UnPack", "Zygote"] +deps = ["Bijectors", "BlockDiagonals", "ChainRulesCore", "Combinatorics", "CommonSolve", "ComponentArrays", "DifferentiationInterface", "DistributionFits", "Distributions", "FillArrays", "Functors", "GPUArraysCore", "IterTools", "KernelAbstractions", "LinearAlgebra", "LogExpFunctions", "MLDataDevices", "MLUtils", "Missings", "NaNMath", "Optimisers", "Optimization", "Random", "StableRNGs", "StaticArrays", "StatsBase", "StatsFuns", "Test", "UnPack", "Zygote"] path = "../../.." uuid = "a108c475-a4e2-4021-9a84-cfa7df242f64" version = "0.2.0" @@ -1188,19 +1229,6 @@ git-tree-sha1 = "4da0f88e9a39111c2fa3add390ab15f3a44f3ca3" uuid = "22cec73e-a1b8-11e9-2c92-598750a2cf9c" version = "0.3.1" -[[deps.InlineStrings]] -git-tree-sha1 = "8f3d257792a522b4601c24a577954b0a8cd7334d" -uuid = "842dd82b-1e85-43dc-bf29-5d0ee9dffc48" -version = "1.4.5" - - [deps.InlineStrings.extensions] - ArrowTypesExt = "ArrowTypes" - ParsersExt = "Parsers" - - [deps.InlineStrings.weakdeps] - ArrowTypes = "31f734f8-188a-4ce0-8406-c8a06bd891cd" - Parsers = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" - [[deps.IntegerMathUtils]] git-tree-sha1 = "4c1acff2dc6b6967e7e750633c50bc3b8d83e617" uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" @@ -1223,16 +1251,17 @@ weakdeps = ["ForwardDiff", "Unitful"] InterpolationsUnitfulExt = "Unitful" [[deps.IntervalArithmetic]] -deps = ["CRlibm", "MacroTools", "OpenBLASConsistentFPCSR_jll", "Printf", "Random", "RoundingEmulator"] -git-tree-sha1 = "02b61501dbe6da3b927cc25dacd7ce32390ee970" +deps = ["CRlibm", "CoreMath", "MacroTools", "OpenBLASConsistentFPCSR_jll", "Printf", "Random", "RoundingEmulator"] +git-tree-sha1 = "f1c42fcaca2d8034fe392f3e86c2e0809f75b2a1" uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" -version = "1.0.2" +version = "1.0.6" [deps.IntervalArithmetic.extensions] IntervalArithmeticArblibExt = "Arblib" IntervalArithmeticDiffRulesExt = "DiffRules" IntervalArithmeticForwardDiffExt = "ForwardDiff" IntervalArithmeticIntervalSetsExt = "IntervalSets" + IntervalArithmeticIrrationalConstantsExt = "IrrationalConstants" IntervalArithmeticLinearAlgebraExt = "LinearAlgebra" IntervalArithmeticRecipesBaseExt = "RecipesBase" IntervalArithmeticSparseArraysExt = "SparseArrays" @@ -1242,14 +1271,15 @@ version = "1.0.2" DiffRules = "b552c78f-8df3-52c6-915a-8e097449b14b" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" + IrrationalConstants = "92d709cd-6900-40b7-9082-c6be49f344b6" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" [[deps.IntervalSets]] -git-tree-sha1 = "d966f85b3b7a8e49d034d27a189e9a4874b4391a" +git-tree-sha1 = "79d6bd28c8d9bccc2229784f1bd637689b256377" uuid = "8197267c-284f-5f27-9208-e0e47529a953" -version = "0.7.13" +version = "0.7.14" weakdeps = ["Random", "RecipesBase", "Statistics"] [deps.IntervalSets.extensions] @@ -1267,11 +1297,6 @@ weakdeps = ["Dates", "Test"] InverseFunctionsDatesExt = "Dates" InverseFunctionsTestExt = "Test" -[[deps.InvertedIndices]] -git-tree-sha1 = "6da3c4316095de0f5ee2ebd875df8721e7e0bdbe" -uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f" -version = "1.3.1" - [[deps.IrrationalConstants]] git-tree-sha1 = "b2d91fe939cae05960e760110b328288867b5758" uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" @@ -1295,9 +1320,9 @@ version = "1.0.0" [[deps.JLD2]] deps = ["ChunkCodecLibZlib", "ChunkCodecLibZstd", "FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "ScopedValues"] -git-tree-sha1 = "8f8ff711442d1f4cfc0d86133e7ee03d62ec9b98" +git-tree-sha1 = "941f87a0ae1b14d1ac2fa57245425b23a9d7a516" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.6.3" +version = "0.6.4" weakdeps = ["UnPack"] [deps.JLD2.extensions] @@ -1317,9 +1342,9 @@ version = "1.7.1" [[deps.JSON]] deps = ["Dates", "Logging", "Parsers", "PrecompileTools", "StructUtils", "UUIDs", "Unicode"] -git-tree-sha1 = "b3ad4a0255688dcb895a52fafbaae3023b588a90" +git-tree-sha1 = "67c6f1f085cb2671c93fe34244c9cccde30f7a26" uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" -version = "1.4.0" +version = "1.5.0" [deps.JSON.extensions] JSONArrowExt = ["ArrowTypes"] @@ -1359,9 +1384,9 @@ version = "0.2.4" [[deps.KernelAbstractions]] deps = ["Adapt", "Atomix", "InteractiveUtils", "MacroTools", "PrecompileTools", "Requires", "StaticArrays", "UUIDs"] -git-tree-sha1 = "fb14a863240d62fbf5922bf9f8803d7df6c62dc8" +git-tree-sha1 = "f2e76d3ced51a2a9e185abc0b97494c7273f649f" uuid = "63c18a36-062a-441e-b654-da1e3ab1ce7c" -version = "0.9.40" +version = "0.9.41" weakdeps = ["EnzymeCore", "LinearAlgebra", "SparseArrays"] [deps.KernelAbstractions.extensions] @@ -1381,12 +1406,6 @@ git-tree-sha1 = "059aabebaa7c82ccb853dd4a0ee9d17796f7e1bc" uuid = "c1c5ebd0-6772-5130-a774-d5fcae4a789d" version = "3.100.3+0" -[[deps.LBFGSB]] -deps = ["L_BFGS_B_jll"] -git-tree-sha1 = "e2e6f53ee20605d0ea2be473480b7480bd5091b5" -uuid = "5be7bae1-8223-5378-bac3-9e7378a2f6e6" -version = "0.4.1" - [[deps.LERC_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "aaafe88dccbd957a8d82f7d05be9b69172e0cee3" @@ -1420,18 +1439,6 @@ git-tree-sha1 = "eb62a3deb62fc6d8822c0c4bef73e4412419c5d8" uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" version = "18.1.8+0" -[[deps.LZO_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1c602b1127f4751facb671441ca72715cc95938a" -uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" -version = "2.10.3+0" - -[[deps.L_BFGS_B_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "77feda930ed3f04b2b0fbb5bea89e69d3677c6b0" -uuid = "81d17ec3-03a1-5e46-b53e-bddc35a13473" -version = "3.0.1+0" - [[deps.LaTeXStrings]] git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c" uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" @@ -1553,6 +1560,12 @@ deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" version = "1.11.0" +[[deps.LogDensityProblems]] +deps = ["ArgCheck", "DocStringExtensions", "Random"] +git-tree-sha1 = "d9625f27ded4ad726ceca7819394a4cc77ed25b3" +uuid = "6fdf6af0-433a-55f7-b3ed-c6c6e0b8df7c" +version = "2.2.0" + [[deps.LogExpFunctions]] deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f" @@ -1659,9 +1672,9 @@ version = "1.5.3" [[deps.LuxLib]] deps = ["ArrayInterface", "CPUSummary", "ChainRulesCore", "DispatchDoctor", "EnzymeCore", "FastClosures", "Functors", "KernelAbstractions", "LinearAlgebra", "LuxCore", "MLDataDevices", "Markdown", "NNlib", "Preferences", "Random", "Reexport", "SciMLPublic", "Static", "StaticArraysCore", "Statistics", "UUIDs"] -git-tree-sha1 = "d93ed9031e8609a63dcd7f158f8565f93a0ab61e" +git-tree-sha1 = "77f3257b18e9fedd39b7b7990f0d3a0800a834ae" uuid = "82251201-b29d-42c6-8e01-566dec8acb11" -version = "1.15.4" +version = "1.15.6" [deps.LuxLib.extensions] AppleAccelerateExt = "AppleAccelerate" @@ -1702,9 +1715,9 @@ version = "1.15.4" [[deps.MCMCDiagnosticTools]] deps = ["AbstractFFTs", "DataAPI", "DataStructures", "Distributions", "LinearAlgebra", "MLJModelInterface", "Random", "SpecialFunctions", "Statistics", "StatsBase", "StatsFuns", "Tables"] -git-tree-sha1 = "f90494689e927268dec7bbd1ece64f134ad251f4" +git-tree-sha1 = "2f464b68e84673727b4e4216a6254fba7da5cf4e" uuid = "be115224-59cd-429b-ad48-344e309966f0" -version = "0.3.16" +version = "0.3.17" [[deps.MLCore]] deps = ["DataAPI", "SimpleTraits", "Tables"] @@ -1714,9 +1727,9 @@ version = "1.0.0" [[deps.MLDataDevices]] deps = ["Adapt", "Functors", "Preferences", "Random", "SciMLPublic"] -git-tree-sha1 = "d8ab79840174b85db64214d4140d4be0a9270210" +git-tree-sha1 = "39a69ca451c3e78b9a6a2e42ef894fdf7505e629" uuid = "7e8f7934-dd98-4c1a-8fe8-92b47a384d40" -version = "1.17.4" +version = "1.17.5" [deps.MLDataDevices.extensions] AMDGPUExt = "AMDGPU" @@ -1784,9 +1797,9 @@ version = "0.5.16" [[deps.Makie]] deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "ComputePipeline", "Contour", "Dates", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Format", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageBase", "ImageIO", "InteractiveUtils", "Interpolations", "IntervalSets", "InverseFunctions", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "PNGFiles", "Packing", "Pkg", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun", "Unitful"] -git-tree-sha1 = "d1b974f376c24dad02c873e951c5cd4e351cd7c2" +git-tree-sha1 = "68af66ec16af8b152309310251ecb4fbfe39869f" uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.24.8" +version = "0.24.9" [deps.Makie.extensions] MakieDynamicQuantitiesExt = "DynamicQuantities" @@ -1817,9 +1830,9 @@ version = "0.6.7" [[deps.MbedTLS]] deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] -git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf" +git-tree-sha1 = "8785729fa736197687541f7053f6d8ab7fc44f92" uuid = "739be429-bea8-5141-9913-cc70e7f3736d" -version = "1.1.9" +version = "1.1.10" [[deps.MbedTLS_jll]] deps = ["Artifacts", "Libdl"] @@ -1971,9 +1984,9 @@ version = "0.3.3" [[deps.OpenEXR_jll]] deps = ["Artifacts", "Imath_jll", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "df9b7c88c2e7a2e77146223c526bf9e236d5f450" +git-tree-sha1 = "135492b7e97fc86d9b132b96a54d2d3dd3e0c6a8" uuid = "18a262bb-aa17-5467-a713-aee519bc75cb" -version = "3.4.4+0" +version = "3.4.8+0" [[deps.OpenLibm_jll]] deps = ["Artifacts", "Libdl"] @@ -1988,9 +2001,9 @@ version = "1.6.1" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "c9cbeda6aceffc52d8a0017e71db27c7a7c0beaf" +git-tree-sha1 = "2ac022577e5eac7da040de17776d51bb770cd895" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.5.5+0" +version = "3.5.6+0" [[deps.OpenSpecFun_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"] @@ -2015,44 +2028,46 @@ version = "0.4.7" Reactant = "3c362404-f566-11ee-1572-e11a4b42c853" [[deps.Optimization]] -deps = ["ADTypes", "ArrayInterface", "ConsoleProgressMonitor", "DocStringExtensions", "LBFGSB", "LinearAlgebra", "Logging", "LoggingExtras", "OptimizationBase", "Printf", "ProgressLogging", "Random", "Reexport", "SciMLBase", "SparseArrays", "TerminalLoggers"] -git-tree-sha1 = "fa2449ce34cc1d7b2191bad4d3356a5376412288" +deps = ["ADTypes", "ArrayInterface", "ConsoleProgressMonitor", "DocStringExtensions", "LinearAlgebra", "Logging", "LoggingExtras", "OptimizationBase", "Printf", "Reexport", "SciMLBase", "SparseArrays", "TerminalLoggers"] +git-tree-sha1 = "2c409c814c2d745620fdd55391a66ee514561146" uuid = "7f7a1694-90dd-40f0-9382-eb1efda571ba" -version = "4.8.0" +version = "5.5.0" [[deps.OptimizationBase]] -deps = ["ADTypes", "ArrayInterface", "DifferentiationInterface", "DocStringExtensions", "FastClosures", "LinearAlgebra", "PDMats", "Reexport", "SciMLBase", "SparseArrays", "SparseConnectivityTracer", "SparseMatrixColorings"] -git-tree-sha1 = "a4d72b85ec4b0ef7aca1a1e067406fcc673addae" +deps = ["ADTypes", "ArrayInterface", "DifferentiationInterface", "DocStringExtensions", "FastClosures", "LinearAlgebra", "PDMats", "PrecompileTools", "Reexport", "SciMLBase", "SciMLLogging", "SparseArrays", "SparseConnectivityTracer", "SparseMatrixColorings", "SymbolicIndexingInterface"] +git-tree-sha1 = "a3d7837832e515111c95a02df7dc55edbdf17d8a" uuid = "bca83a33-5cc9-4baa-983d-23429ab6bcbb" -version = "2.14.0" +version = "5.1.0" [deps.OptimizationBase.extensions] - OptimizationEnzymeExt = "Enzyme" + OptimizationChainRulesCoreExt = "ChainRulesCore" + OptimizationEnzymeExt = ["ChainRulesCore", "Enzyme"] OptimizationFiniteDiffExt = "FiniteDiff" OptimizationForwardDiffExt = "ForwardDiff" OptimizationMLDataDevicesExt = "MLDataDevices" OptimizationMLUtilsExt = "MLUtils" - OptimizationMTKExt = "ModelingToolkit" + OptimizationMooncakeExt = "Mooncake" OptimizationReverseDiffExt = "ReverseDiff" OptimizationSymbolicAnalysisExt = "SymbolicAnalysis" OptimizationZygoteExt = "Zygote" [deps.OptimizationBase.weakdeps] + ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" FiniteDiff = "6a86dc24-6348-571c-b903-95158fe2bd41" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" MLDataDevices = "7e8f7934-dd98-4c1a-8fe8-92b47a384d40" MLUtils = "f1d291b0-491e-4a28-83b9-f70985020b54" - ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78" + Mooncake = "da2b9cff-9c12-43a0-ae48-6db2b0edb7d6" ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" SymbolicAnalysis = "4297ee4d-0239-47d8-ba5d-195ecdf594fe" Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" [[deps.OptimizationOptimisers]] -deps = ["Optimisers", "Optimization", "Printf", "ProgressLogging", "Reexport"] -git-tree-sha1 = "ea6169605fe93e02df87874f388279ae766175d9" +deps = ["Logging", "Optimisers", "OptimizationBase", "Reexport", "SciMLBase"] +git-tree-sha1 = "7caf4c41e3ee6d348381228b6517decea28867e3" uuid = "42dfb2eb-d2b4-4451-abcd-913932933ac1" -version = "0.3.11" +version = "0.3.16" [[deps.Opus_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -2161,9 +2176,9 @@ 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 = "1cc8ad0762e59e713ee3ef28f9b78b2c9f4ca078" +git-tree-sha1 = "cb20a4eacda080e517e4deb9cfb6c7c518131265" uuid = "91a5bcdd-55d7-5caf-9e0b-520d859cae80" -version = "1.41.5" +version = "1.41.6" [deps.Plots.extensions] FileIOExt = "FileIO" @@ -2196,17 +2211,11 @@ git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" uuid = "647866c9-e3ac-4575-94e7-e3d426903924" version = "0.1.2" -[[deps.PooledArrays]] -deps = ["DataAPI", "Future"] -git-tree-sha1 = "36d8b4b899628fb92c2749eb488d884a926614d3" -uuid = "2dfb63ee-cc39-5dd5-95bd-886bf059d720" -version = "1.4.3" - [[deps.PreallocationTools]] deps = ["Adapt", "ArrayInterface", "PrecompileTools"] -git-tree-sha1 = "dc8d6bde5005a0eac05ae8faf1eceaaca166cfa4" +git-tree-sha1 = "e16b73bf892c55d16d53c9c0dbd0fb31cb7e25da" uuid = "d236fae5-4411-538c-8e31-a6e3d9e00b46" -version = "1.1.2" +version = "1.2.0" [deps.PreallocationTools.extensions] PreallocationToolsForwardDiffExt = "ForwardDiff" @@ -2226,9 +2235,9 @@ version = "1.2.1" [[deps.Preferences]] deps = ["TOML"] -git-tree-sha1 = "522f093a29b31a93e34eaea17ba055d850edea28" +git-tree-sha1 = "8b770b60760d4451834fe79dd483e318eee709c4" uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.5.1" +version = "1.5.2" [[deps.PrettyPrint]] git-tree-sha1 = "632eb4abab3449ab30c5e1afaa874f0b98b586e4" @@ -2237,9 +2246,9 @@ version = "0.2.0" [[deps.PrettyTables]] deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "REPL", "Reexport", "StringManipulation", "Tables"] -git-tree-sha1 = "211530a7dc76ab59087f4d4d1fc3f086fbe87594" +git-tree-sha1 = "624de6279ab7d94fc9f672f0068107eb6619732c" uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d" -version = "3.2.3" +version = "3.3.2" [deps.PrettyTables.extensions] PrettyTablesTypstryExt = "Typstry" @@ -2271,9 +2280,9 @@ uuid = "92933f4c-e287-5a05-a399-4b506db050ca" version = "1.11.0" [[deps.PtrArrays]] -git-tree-sha1 = "1d36ef11a9aaf1e8b74dacc6a731dd1de8fd493d" +git-tree-sha1 = "4fbbafbc6251b883f4d2705356f3641f3652a7fe" uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" -version = "1.3.0" +version = "1.4.0" [[deps.QOI]] deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] @@ -2283,33 +2292,39 @@ version = "1.0.2" [[deps.Qt6Base_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Fontconfig_jll", "Glib_jll", "JLLWrappers", "Libdl", "Libglvnd_jll", "OpenSSL_jll", "Vulkan_Loader_jll", "Xorg_libSM_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Xorg_libxcb_jll", "Xorg_xcb_util_cursor_jll", "Xorg_xcb_util_image_jll", "Xorg_xcb_util_keysyms_jll", "Xorg_xcb_util_renderutil_jll", "Xorg_xcb_util_wm_jll", "Zlib_jll", "libinput_jll", "xkbcommon_jll"] -git-tree-sha1 = "34f7e5d2861083ec7596af8b8c092531facf2192" +git-tree-sha1 = "d7a4bff94f42208ce3cf6bc8e4e7d1d663e7ee8b" uuid = "c0090381-4147-56d7-9ebc-da0b1113ec56" -version = "6.8.2+2" +version = "6.10.2+1" [[deps.Qt6Declarative_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6ShaderTools_jll"] -git-tree-sha1 = "da7adf145cce0d44e892626e647f9dcbe9cb3e10" +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6ShaderTools_jll", "Qt6Svg_jll"] +git-tree-sha1 = "d5b7dd0e226774cbd87e2790e34def09245c7eab" uuid = "629bc702-f1f5-5709-abd5-49b8460ea067" -version = "6.8.2+1" +version = "6.10.2+1" [[deps.Qt6ShaderTools_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll"] -git-tree-sha1 = "9eca9fc3fe515d619ce004c83c31ffd3f85c7ccf" +git-tree-sha1 = "4d85eedf69d875982c46643f6b4f66919d7e157b" uuid = "ce943373-25bb-56aa-8eca-768745ed7b5a" -version = "6.8.2+1" +version = "6.10.2+1" + +[[deps.Qt6Svg_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll"] +git-tree-sha1 = "81587ff5ff25a4e1115ce191e36285ede0334c9d" +uuid = "6de9746b-f93d-5813-b365-ba18ad4a9cf3" +version = "6.10.2+0" [[deps.Qt6Wayland_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Qt6Base_jll", "Qt6Declarative_jll"] -git-tree-sha1 = "8f528b0851b5b7025032818eb5abbeb8a736f853" +git-tree-sha1 = "672c938b4b4e3e0169a07a5f227029d4905456f2" uuid = "e99dba38-086e-5de3-a5b1-6e4c66e897c3" -version = "6.8.2+2" +version = "6.10.2+1" [[deps.QuadGK]] deps = ["DataStructures", "LinearAlgebra"] -git-tree-sha1 = "9da16da70037ba9d701192e27befedefb91ec284" +git-tree-sha1 = "5e8e8b0ab68215d7a2b14b9921a946fee794749e" uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.11.2" +version = "2.11.3" [deps.QuadGK.extensions] QuadGKEnzymeExt = "Enzyme" @@ -2356,9 +2371,9 @@ weakdeps = ["FixedPointNumbers"] [[deps.ReactantCore]] deps = ["ExpressionExplorer", "MacroTools"] -git-tree-sha1 = "f3e31b90afcd152578a6c389eae46dd38b9a4f38" +git-tree-sha1 = "5b9e0fe7fb2cf3794fd96ac32bf2732aa4bb9776" uuid = "a3311ec8-5e00-46d5-b541-4f83e724a433" -version = "0.1.16" +version = "0.1.19" [[deps.RealDot]] deps = ["LinearAlgebra"] @@ -2380,12 +2395,13 @@ version = "0.6.12" [[deps.RecursiveArrayTools]] deps = ["Adapt", "ArrayInterface", "DocStringExtensions", "GPUArraysCore", "LinearAlgebra", "PrecompileTools", "RecipesBase", "StaticArraysCore", "SymbolicIndexingInterface"] -git-tree-sha1 = "18d2a6fd1ea9a8205cadb3a5704f8e51abdd748b" +git-tree-sha1 = "d0282d612f22dcad7b81cf487b746e63aa2a6709" uuid = "731186ca-8d62-57ce-b412-fbd966d074cd" -version = "3.48.0" +version = "3.54.0" [deps.RecursiveArrayTools.extensions] RecursiveArrayToolsFastBroadcastExt = "FastBroadcast" + RecursiveArrayToolsFastBroadcastPolyesterExt = ["FastBroadcast", "Polyester"] RecursiveArrayToolsForwardDiffExt = "ForwardDiff" RecursiveArrayToolsKernelAbstractionsExt = "KernelAbstractions" RecursiveArrayToolsMeasurementsExt = "Measurements" @@ -2404,6 +2420,7 @@ version = "3.48.0" KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c" Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca" + Polyester = "f517fe37-dbe3-4b94-8317-1923a5111588" ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" @@ -2443,9 +2460,9 @@ version = "0.5.1+0" [[deps.Roots]] deps = ["Accessors", "CommonSolve", "Printf"] -git-tree-sha1 = "8a433b1ede5e9be9a7ba5b1cc6698daa8d718f1d" +git-tree-sha1 = "b2f70f34eb9973572d55c332933c6a04c911f549" uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -version = "2.2.10" +version = "2.2.14" [deps.Roots.extensions] RootsChainRulesCoreExt = "ChainRulesCore" @@ -2497,9 +2514,9 @@ version = "0.6.43" [[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", "SciMLLogging", "SciMLOperators", "SciMLPublic", "SciMLStructures", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface"] -git-tree-sha1 = "f2c5ddf74a49c1fd74e511d31168f0354c6c1e19" +git-tree-sha1 = "908c0bf271604d09393a21c142116ab26f66f67c" uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" -version = "2.138.1" +version = "2.154.0" [deps.SciMLBase.extensions] SciMLBaseChainRulesCoreExt = "ChainRulesCore" @@ -2542,9 +2559,9 @@ version = "2.138.1" [[deps.SciMLLogging]] deps = ["Logging", "LoggingExtras", "Preferences"] -git-tree-sha1 = "a51104fa06a784c5ddf4a9937c5e0c03de0c6878" +git-tree-sha1 = "0161be062570af4042cf6f69e3d5d0b0555b6927" uuid = "a6db7da4-7206-11f0-1eab-35f2a5dbe1d1" -version = "1.9.0" +version = "1.9.1" weakdeps = ["Tracy"] [deps.SciMLLogging.extensions] @@ -2552,9 +2569,9 @@ weakdeps = ["Tracy"] [[deps.SciMLOperators]] deps = ["Accessors", "ArrayInterface", "DocStringExtensions", "LinearAlgebra"] -git-tree-sha1 = "794c760e6aafe9f40dcd7dd30526ea33f0adc8b7" +git-tree-sha1 = "234869cf9fee9258a95464b7a7065cc7be84db00" uuid = "c0aeaf25-5076-4817-a8d5-81caf7dfa961" -version = "1.15.1" +version = "1.16.0" weakdeps = ["SparseArrays", "StaticArraysCore"] [deps.SciMLOperators.extensions] @@ -2580,9 +2597,9 @@ version = "3.1.0" [[deps.ScopedValues]] deps = ["HashArrayMappedTries", "Logging"] -git-tree-sha1 = "c3b2323466378a2ba15bea4b2f73b081e022f473" +git-tree-sha1 = "ac4b837d89a58c848e85e698e2a2514e9d59d8f6" uuid = "7e506255-f358-4e82-b7e4-beb19740aa63" -version = "1.5.0" +version = "1.6.0" [[deps.Scratch]] deps = ["Dates"] @@ -2694,9 +2711,9 @@ version = "0.1.2" [[deps.SparseMatrixColorings]] deps = ["ADTypes", "DocStringExtensions", "LinearAlgebra", "PrecompileTools", "Random", "SparseArrays"] -git-tree-sha1 = "6ed48d9a3b22417c765dc273ae3e1e4de035e7c8" +git-tree-sha1 = "1c1be8c6fdfaf9b6c9e156c509e672953b8e6af7" uuid = "0a514795-09f3-496d-8182-132a7b665d35" -version = "0.4.23" +version = "0.4.26" [deps.SparseMatrixColorings.extensions] SparseMatrixColoringsCUDAExt = "CUDA" @@ -2713,9 +2730,9 @@ version = "0.4.23" [[deps.SpecialFunctions]] deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "5acc6a41b3082920f79ca3c759acbcecf18a8d78" +git-tree-sha1 = "2700b235561b0335d5bef7097a111dc513b8655e" uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.7.1" +version = "2.7.2" weakdeps = ["ChainRulesCore"] [deps.SpecialFunctions.extensions] @@ -2758,9 +2775,9 @@ weakdeps = ["OffsetArrays", "StaticArrays"] [[deps.StaticArrays]] deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"] -git-tree-sha1 = "eee1b9ad8b29ef0d936e3ec9838c7ec089620308" +git-tree-sha1 = "246a8bb2e6667f832eea063c3a56aef96429a3db" uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.9.16" +version = "1.9.18" weakdeps = ["ChainRulesCore", "Statistics"] [deps.StaticArrays.extensions] @@ -2819,15 +2836,15 @@ version = "0.5.8" [[deps.StringManipulation]] deps = ["PrecompileTools"] -git-tree-sha1 = "a3c1536470bf8c5e02096ad4853606d7c8f62721" +git-tree-sha1 = "d05693d339e37d6ab134c5ab53c29fce5ee5d7d5" uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e" -version = "0.4.2" +version = "0.4.4" [[deps.StructArrays]] deps = ["ConstructionBase", "DataAPI", "Tables"] -git-tree-sha1 = "a2c37d815bf00575332b7bd0389f771cb7987214" +git-tree-sha1 = "ad8002667372439f2e3611cfd14097e03fa4bccd" uuid = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" -version = "0.7.2" +version = "0.7.3" weakdeps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LinearAlgebra", "SparseArrays", "StaticArrays"] [deps.StructArrays.extensions] @@ -2839,16 +2856,18 @@ weakdeps = ["Adapt", "GPUArraysCore", "KernelAbstractions", "LinearAlgebra", "Sp [[deps.StructUtils]] deps = ["Dates", "UUIDs"] -git-tree-sha1 = "28145feabf717c5d65c1d5e09747ee7b1ff3ed13" +git-tree-sha1 = "fa95b3b097bcef5845c142ea2e085f1b2591e92c" uuid = "ec057cc2-7a8d-4b58-b3b3-92acb9f63b42" -version = "2.6.3" +version = "2.7.1" [deps.StructUtils.extensions] StructUtilsMeasurementsExt = ["Measurements"] + StructUtilsStaticArraysCoreExt = ["StaticArraysCore"] StructUtilsTablesExt = ["Tables"] [deps.StructUtils.weakdeps] Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" + StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" [[deps.StyledStrings]] @@ -2927,9 +2946,9 @@ version = "0.5.5" [[deps.TiffImages]] deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "PrecompileTools", "ProgressMeter", "SIMD", "UUIDs"] -git-tree-sha1 = "98b9352a24cb6a2066f9ababcc6802de9aed8ad8" +git-tree-sha1 = "08c10bc34f4e7743f530793d0985bf3c254e193d" uuid = "731e570b-9d59-4bfa-96dc-6df516fadf69" -version = "0.11.6" +version = "0.11.8" [[deps.Tracy]] deps = ["ExprTools", "LibTracyClient_jll", "Libdl"] @@ -2975,6 +2994,12 @@ git-tree-sha1 = "4d4ed7f294cda19382ff7de4c137d24d16adc89b" uuid = "981d1d27-644d-49a2-9326-4793e63143c3" version = "0.1.0" +[[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" @@ -3016,9 +3041,9 @@ weakdeps = ["ConstructionBase", "ForwardDiff", "InverseFunctions", "LaTeXStrings PrintfExt = "Printf" [[deps.UnsafeAtomics]] -git-tree-sha1 = "b13c4edda90890e5b04ba24e20a310fbe6f249ff" +git-tree-sha1 = "0f30765c32d66d58e41f4cb5624d4fc8a82ec13b" uuid = "013be700-e6cd-48c3-b4a1-df204f14c38f" -version = "0.3.0" +version = "0.3.1" weakdeps = ["LLVM"] [deps.UnsafeAtomics.extensions] @@ -3091,9 +3116,9 @@ version = "1.1.0" [[deps.XZ_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "9cce64c0fdd1960b597ba7ecda2950b5ed957438" +git-tree-sha1 = "b29c22e245d092b8b4e8d3c09ad7baa586d9f573" uuid = "ffd25f8a-64ca-5728-b0f7-c24cf3aae800" -version = "5.8.2+0" +version = "5.8.3+0" [[deps.Xorg_libICE_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -3167,6 +3192,12 @@ git-tree-sha1 = "7ed9347888fac59a618302ee38216dd0379c480d" uuid = "ea2f1a96-1ddc-540d-b46f-429655e07cfa" version = "0.9.12+0" +[[deps.Xorg_libpciaccess_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "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" @@ -3270,9 +3301,9 @@ version = "0.2.7" [[deps.cuDNN]] deps = ["CEnum", "CUDA", "CUDA_Runtime_Discovery", "CUDNN_jll"] -git-tree-sha1 = "c1e756c5b075d06f19595ac0bc6388ab2973237a" +git-tree-sha1 = "5494b0ae3ddc5ca0f64159d5ed3a396f36e0fcfe" uuid = "02a925ec-e4fe-4b08-9a7e-0d78e3d38ccd" -version = "1.4.6" +version = "1.4.7" [[deps.demumble_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -3321,6 +3352,12 @@ git-tree-sha1 = "9bf7903af251d2050b467f76bdbe57ce541f7f4f" uuid = "1183f4f0-6f2a-5f1a-908b-139f9cdfea6f" version = "0.2.2+0" +[[deps.libdrm_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libpciaccess_jll"] +git-tree-sha1 = "63aac0bcb0b582e11bad965cef4a689905456c03" +uuid = "8e53e030-5e6c-5a89-a30b-be5b7263a166" +version = "2.4.125+1" + [[deps.libevdev_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] git-tree-sha1 = "56d643b57b188d30cccc25e331d416d3d358e557" @@ -3341,9 +3378,9 @@ version = "1.28.1+0" [[deps.libpng_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "e015f211ebb898c8180887012b938f3851e719ac" +git-tree-sha1 = "e2a7072fc0cdd7949528c1455a3e5da4122e1153" uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" -version = "1.6.55+0" +version = "1.6.56+0" [[deps.libsixel_jll]] deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "libpng_jll"] @@ -3351,6 +3388,12 @@ git-tree-sha1 = "c1733e347283df07689d71d61e14be986e49e47a" uuid = "075b6546-f08a-558a-be8f-8157d0f608a5" version = "1.10.5+0" +[[deps.libva_jll]] +deps = ["Artifacts", "JLLWrappers", "Libdl", "Xorg_libX11_jll", "Xorg_libXext_jll", "Xorg_libXfixes_jll", "libdrm_jll"] +git-tree-sha1 = "7dbf96baae3310fe2fa0df0ccbb3c6288d5816c9" +uuid = "9a156e7d-b971-5f62-b2c9-67348b8fb97c" +version = "2.23.0+0" + [[deps.libvorbis_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll"] git-tree-sha1 = "11e1772e7f3cc987e9d3de991dd4f6b2602663a5" diff --git a/docs/src/tutorials/basic_cpu.md b/docs/src/tutorials/basic_cpu.md index d03e874..82b2f85 100644 --- a/docs/src/tutorials/basic_cpu.md +++ b/docs/src/tutorials/basic_cpu.md @@ -186,8 +186,11 @@ PBM parameters, given the covariates. Here, we specify a 3-layer feed-forward neural network using the `SimpleChains` framework which works efficiently on CPU. +The ML model predicts the components of θM and an additional uncertainty +factor per site. + ``` julia -n_out = length(θM) # number of individuals to predict +n_out = length(θM) + 1 # number of individuals to predict, and uncertainty factor n_input = n_covar = size(xM,1) g_chain = SimpleChain( @@ -221,10 +224,16 @@ specific prior distribution forms. However, for simplicity, a [`NormalScalingModelApplicator`](@ref) is fitted to the transformed 5% and 95% quantiles of the original prior. +All raw ML output are in the range (0,1). We want to scale the predictions +of the mean parameters to the likeli range on unconstrained scale, but do +not scale the output for the uncertainty factor. This is taken care of +by the, `range_scaled`, keyword argument. + ``` julia priorsM = Tuple(priors_dict[k] for k in keys(θM)) lowers, uppers = get_quantile_transformed(priorsM, transM) -g_chain_scaled = NormalScalingModelApplicator(g_chain_app, lowers, uppers, FT) +range_scaled = 1:length(lowers) # do only scale means, but not the uncertainty factor +g_chain_scaled = NormalScalingModelApplicator(g_chain_app, lowers, uppers, FT; range_scaled) ``` The `g_chain_scaled` `ModelApplicator` now predicts in unconstrained scale, @@ -232,22 +241,44 @@ transforms logistic predctions around 0.5 to the range of high prior probability of the parameters, and transforms ML predictions near 0 or 1 towards the outer lower probability ranges. +## Setting up the Approximation strategy and the initial parmeters + +Here, we are using the `MeanScalingHVIApproximation` approximation of the posterior +density, where the ML model predicts the means of the model at unconstrained scale +and a multiplier, i.e offset at log scale, of the main diagonal of the +covariance matrix for each site. + +We need to specify the stucture of scaling blocks (here we use on block for +all parameters), the magnitude of the variance (that will be multiplied by the +site factor) at log-scale. + +Given this information, the initial values to be optimized and some information +in the approximator can be initialized. + +``` julia +block_ends = [length(θM)] # one scaling factor of all parameters +σ = FT(0.1) .* θM[block_ends] # standard deviation of 10% of values of template +logσ2 = FT(2) .* log.(σ) # transform to log_var scale +approx = MeanScalingHVIApproximation(block_ends, logσ2) + +(;ϕqc, approx) = init_hybrid_ϕq(approx, θP, θM, transP; n_site, transM) +``` + ## Assembling the information All the specifications above are stored in a [`HybridProblem`](@ref) structure. -Before, a [`PBMSiteApplicator`](@ref) is constructed that translates an invocation -given a vector of global parameters, and a matrix of site parameters to +Before, a [`PBMSiteApplicator`](@ref) is constructed that efficiently +translates an invocation given +a vector of global parameters, and a matrix of site parameters to invocation of the process based model (PBM), defined at the beginning. ``` julia -approx = MeanHVIApproximation() f_batch = PBMSiteApplicator(f_doubleMM; θP, θM, θFix, xPvec=xP[:,1]) -ϕq0 = init_hybrid_ϕq(approx, θP, θM, transP; n_site, transM) -prob = HybridProblem(θM, ϕq0, g_chain_scaled, ϕg0, +prob = HybridProblem(θM, ϕqc, g_chain_scaled, ϕg0, f_batch, priors_dict, py, - transM, transP, train_dataloader, test_data,n_covar, n_site, n_batch; approx) + transM, transP, train_dataloader, test_data, n_site, n_batch; approx) ``` ## Perform the inversion diff --git a/docs/src/tutorials/basic_cpu.qmd b/docs/src/tutorials/basic_cpu.qmd index 2b27347..3f315e6 100644 --- a/docs/src/tutorials/basic_cpu.qmd +++ b/docs/src/tutorials/basic_cpu.qmd @@ -197,8 +197,11 @@ PBM parameters, given the covariates. Here, we specify a 3-layer feed-forward neural network using the `SimpleChains` framework which works efficiently on CPU. +The ML model predicts the components of θM and an additional uncertainty +factor per site. + ```{julia} -n_out = length(θM) # number of individuals to predict +n_out = length(θM) + 1 # number of individuals to predict, and uncertainty factor n_input = n_covar = size(xM,1) g_chain = SimpleChain( @@ -232,10 +235,16 @@ specific prior distribution forms. However, for simplicity, a [`NormalScalingModelApplicator`](@ref) is fitted to the transformed 5% and 95% quantiles of the original prior. +All raw ML output are in the range (0,1). We want to scale the predictions +of the mean parameters to the likeli range on unconstrained scale, but do +not scale the output for the uncertainty factor. This is taken care of +by the, `range_scaled`, keyword argument. + ```{julia} priorsM = Tuple(priors_dict[k] for k in keys(θM)) lowers, uppers = get_quantile_transformed(priorsM, transM) -g_chain_scaled = NormalScalingModelApplicator(g_chain_app, lowers, uppers, FT) +range_scaled = 1:length(lowers) # do only scale means, but not the uncertainty factor +g_chain_scaled = NormalScalingModelApplicator(g_chain_app, lowers, uppers, FT; range_scaled) ``` The `g_chain_scaled` `ModelApplicator` now predicts in unconstrained scale, @@ -243,23 +252,44 @@ transforms logistic predctions around 0.5 to the range of high prior probability of the parameters, and transforms ML predictions near 0 or 1 towards the outer lower probability ranges. +## Setting up the Approximation strategy and the initial parmeters + +Here, we are using the `MeanScalingHVIApproximation` approximation of the posterior +density, where the ML model predicts the means of the model at unconstrained scale +and a multiplier, i.e offset at log scale, of the main diagonal of the +covariance matrix for each site. + +We need to specify the stucture of scaling blocks (here we use on block for +all parameters), the magnitude of the variance (that will be multiplied by the +site factor) at log-scale. + +Given this information, the initial values to be optimized and some information +in the approximator can be initialized. + +```{julia} +block_ends = [length(θM)] # one scaling factor of all parameters +σ = FT(0.1) .* θM[block_ends] # standard deviation of 10% of values of template +logσ2 = FT(2) .* log.(σ) # transform to log_var scale +approx = MeanScalingHVIApproximation(block_ends, logσ2) + +(;ϕqc, approx) = init_hybrid_ϕq(approx, θP, θM, transP; n_site, transM) +``` ## Assembling the information All the specifications above are stored in a [`HybridProblem`](@ref) structure. -Before, a [`PBMSiteApplicator`](@ref) is constructed that translates an invocation -given a vector of global parameters, and a matrix of site parameters to +Before, a [`PBMSiteApplicator`](@ref) is constructed that efficiently +translates an invocation given +a vector of global parameters, and a matrix of site parameters to invocation of the process based model (PBM), defined at the beginning. ```{julia} -approx = MeanHVIApproximation() f_batch = PBMSiteApplicator(f_doubleMM; θP, θM, θFix, xPvec=xP[:,1]) -(;ϕqc, approx) = init_hybrid_ϕq(approx, θP, θM, transP; n_site, transM) prob = HybridProblem(θM, ϕqc, g_chain_scaled, ϕg0, f_batch, priors_dict, py, - transM, transP, train_dataloader, test_data,n_covar, n_site, n_batch; approx) + transM, transP, train_dataloader, test_data, n_site, n_batch; approx) ``` ```{julia} diff --git a/docs/src/tutorials/basic_cpu_mean.md b/docs/src/tutorials/basic_cpu_mean.md new file mode 100644 index 0000000..c6c6aa9 --- /dev/null +++ b/docs/src/tutorials/basic_cpu_mean.md @@ -0,0 +1,372 @@ +# Basic workflow without GPU + + +``` @meta +CurrentModule = HybridVariationalInference +``` + +First load necessary packages. + +``` julia +using HybridVariationalInference +using HybridVariationalInference: HybridVariationalInference as HVI +using ComponentArrays: ComponentArrays as CA +using Bijectors +using StableRNGs +using SimpleChains +using StatsFuns +using MLUtils +using DistributionFits +using UnPack +``` + +Next, specify many moving parts of the Hybrid variational inference (HVI) + +## The process-based model + +The example process based model (PBM) predicts a double-monod constrained rate +for different substrate concentrations, `S1`, and `S2`. + +$$ +y = r_0+ r_1 \frac{S_1}{K_1 + S_1} \frac{S_2}{K_2 + S_2} +$$ + +``` julia +function f_doubleMM(θc::CA.ComponentVector{ET}, x) where ET + # extract parameters not depending on order, i.e whether they are in θP or θM + @unpack r0, r1, K1, K2 = θc + y = r0 .+ r1 .* x.S1 ./ (K1 .+ x.S1) .* x.S2 ./ (K2 .+ x.S2) + (y, y[1:0]) +end +``` + +Its formulation is independent of which parameters are global, site-specific, +or fixed during the model inversion. +However, it cannot assume an ordering in the parameters, but needs to +access the components by its symbolic names in the provided `ComponentArray`. + +In addition to the predictions, the PBM returns additional quantities that may +be used in penalizing unrealistic conditions independent of observations. +In this simple example, just an empty vector is returned. + +## Likelihood function + +HVI requires the evaluation of the likelihood of the predictions. +It corresponds to the cost of predictions given some observations. + +The user specifies a function of the negative log-Likelihood +`neg_logden(obs, pred, uncertainty_parameters)`, +where all of the parameters are arrays with columns for sites. + +Here, we use the [`neg_logden_indep_normal`](@ref) function +that assumed observations to be distributed independently +normal around a true value. +The provided `y_unc` uncertainty parameters, here, corresponds to +`logσ2`, denoting the log of the variance parameter of the normal distribution. + +``` julia +py = neg_logden_indep_normal +``` + +## Global-Site, transformations, and priors + +### Global and site-specific parameters + +In this example, we will assign a fixed value to r0 parameter, treat +the K2 parameter as unknown but the same across sites, and predict +r1 and K1 for each site separately, based on covariates known at the sites. + +Here we provide initial values for them by using `ComponentVector`. + +``` julia +FT = Float32 +θM0 = θM = CA.ComponentVector{FT}(r1=0.5, K1=0.2) # separately for each individual +θP0 = θP = CA.ComponentVector{FT}(K2=2.0) # population: same across individuals, +θFix = CA.ComponentVector{FT}(r0=0.3) # r0, i.e. not estimated +``` + +### Parameter Transformations + +HVI allows for transformations of parameters in an unconstrained space, +where the probability density is not strictly zero anywhere to the original +constrained space. + +Here, our model parameters are strictly positive, and we use the exponential function +to transform unconstrained estimates to the original constrained domain. + +``` julia +transP = Stacked(HVI.Exp()) +transM = Stacked(HVI.Exp(), HVI.Exp()) +``` + +Parameter transformations are specified using the `Bijectors` package. +Because, `Bijectors.elementwise(exp)`, has problems with automatic differentiation (AD) +on GPU, we use the public but non-exported [`Exp`](@ref) wrapper inside `Bijectors.Stacked`. + +### Prior information on parameters at constrained scale + +HVI is an approximate bayesian analysis and combines prior information on +the parameters with the model and observed data. + +Here, we provide a wide prior by fitting a Lognormal distributions to +- the mode corresponding to the initial value provided above +- the 0.95-quantile 3 times the mode +using the `DistributionFits.jl` package. + +``` julia +θall = vcat(θP, θM) +priors_dict = Dict{Symbol, Distribution}( + keys(θall) .=> fit.(LogNormal, θall, QuantilePoint.(θall .* 3, 0.95), Val(:mode))) +``` + +## Observations, model drivers and covariates + +The model parameters are inverted using information on the +- observed data, `y_o` +- its uncertainty, `y_unc` +- known covariates across sites, `xM` +- model drivers, `xP` +Here, we use synthetic data generated by the package. + +``` julia +rng = StableRNG(111) +n_site_test = 60 +(; xM, xP, y_o, y_unc) = gen_hybridproblem_synthetic( + rng, DoubleMM.DoubleMMCase(); n_site_test, scenario=Val((:omit_r0,))) +n_site = size(y_o,2) - n_site_test +i_test = n_site .+ (1:n_site_test) +i_train = 1:n_site +test_data = (; xM = xM[:, i_test], xP = xP[:, i_test], + y_o = y_o[:, i_test], y_unc = y_unc[:, i_test], i_site = i_test) +train_data = (; xM = xM[:, i_train], xP = xP[:, i_train], + y_o = y_o[:, i_train], y_unc = y_unc[:, i_train], i_site = i_train) +``` + +Lets look at them. + +``` julia +map(size,train_data) +``` + + (xM = (5, 800), xP = (16, 800), y_o = (8, 800), y_unc = (8, 800), i_site = (800,)) + +All of them have 800 columns, corresponding to 800 sites. +There are 5 site-covaritas, 16 values of model drivers, and 8 observations per site. + +``` julia +xP[:,1] +``` + + ComponentVector{Float32}(S1 = Float32[0.5, 0.5, 0.5, 0.5, 0.4, 0.3, 0.2, 0.1], S2 = Float32[1.0, 3.0, 4.0, 5.0, 5.0, 5.0, 5.0, 5.0]) + +In each column of the model drivers there is a ComponentVector with +components S1 and S2 corresponding to the concentrations, for which outputs +were observed. +This allows notation `x.S1` in the PBM above. + +The `y_unc` becomes its meaning by the Likelihood-function to be specified with +the problem below. + +### Providing data in batches + +HVI uses `MLUtils.DataLoader` to provide batches of the data during each +iteration of the solver. In addition to the data, it provides an +index to the sites inside a tuple. + +``` julia +n_batch = 20 +train_dataloader = MLUtils.DataLoader( + CA.getdata.(values(train_data)), batchsize=n_batch, partial=false) +``` + +## The Machine-Learning model + +The machine-learning (ML) part predicts parameters of the posterior of site-specific +PBM parameters, given the covariates. +Here, we specify a 3-layer feed-forward neural network using the `SimpleChains` +framework which works efficiently on CPU. + +``` julia +n_out = length(θM) # number of individuals to predict +n_input = n_covar = size(xM,1) + +g_chain = SimpleChain( + static(n_input), # input dimension (optional) + TurboDense{true}(tanh, n_input * 4), + TurboDense{true}(tanh, n_input * 4), + # dense layer without bias that maps to n outputs to (0..1) + TurboDense{false}(logistic, n_out) +) +# get a template of the parameter vector, ϕg0 +g_chain_app, ϕg0 = construct_ChainsApplicator(rng, g_chain) +``` + +The `g_chain_app` `ChainsApplicator` predicts the parameters of the posterior, +approximation given a vector of ML weights,`ϕg`. +During construction, an initial template of this vector is created. +This abstraction layer allows to use different ML frameworks and replace the +`SimpleChains` model by `Flux` or `Lux`. + +### Using priors to scale ML-parameter estimates + +In order to balance gradients, the `g_chain_app` ModelApplicator defined above +predicts on a scale (0..1). +Now the priors are used to translate this to the parameter range by using the +cumulative density distribution. + +Priors were specified at constrained scale, but the ML model predicts +parameters on unconstrained scale. +This transformation of the distribution can be mathematically worked out for +specific prior distribution forms. +However, for simplicity, a [`NormalScalingModelApplicator`](@ref) +is fitted to the transformed 5% and 95% quantiles of the original prior. + +``` julia +priorsM = Tuple(priors_dict[k] for k in keys(θM)) +lowers, uppers = get_quantile_transformed(priorsM, transM) +g_chain_scaled = NormalScalingModelApplicator(g_chain_app, lowers, uppers, FT) +``` + +The `g_chain_scaled` `ModelApplicator` now predicts in unconstrained scale, +transforms logistic predctions around 0.5 to the range of +high prior probability of the parameters, +and transforms ML predictions near 0 or 1 towards the outer lower probability ranges. + +## Assembling the information + +All the specifications above are stored in a [`HybridProblem`](@ref) structure. + +Before, a [`PBMSiteApplicator`](@ref) is constructed that translates an invocation +given a vector of global parameters, and a matrix of site parameters to +invocation of the process based model (PBM), defined at the beginning. + +``` julia +approx = MeanHVIApproximation() +f_batch = PBMSiteApplicator(f_doubleMM; θP, θM, θFix, xPvec=xP[:,1]) +(;ϕqc, approx) = init_hybrid_ϕq(approx, θP, θM, transP; n_site, transM) + +prob = HybridProblem(θM, ϕqc, g_chain_scaled, ϕg0, + f_batch, priors_dict, py, + transM, transP, train_dataloader, test_data, n_site, n_batch; approx) +``` + +## Perform the inversion + +Eventually, having assembled all the moving parts of the HVI, we can perform +the inversion. + +``` julia +# silence warning of no GPU backend found (because we did not import CUDA here) +ENV["MLDATADEVICES_SILENCE_WARN_NO_GPU"] = 1 +``` + +``` julia +using OptimizationOptimisers +import Zygote + +solver = HybridPosteriorSolver(; alg=Adam(0.02), n_MC=3) + +(; probo, interpreters) = solve(prob, solver; rng, + callback = callback_loss(100), # output during fitting + epochs = 2, +); +``` + +The solver object is constructed given the specific stochastic optimization algorithm +and the number of Monte-Carlo samples that are drawn in each iteration +from the predicted parameter posterior. + +Then the solver is applied to the problem using [`solve`](@ref) +for a given number of iterations or epochs. +For this tutorial, we additionally specify that the function to transfer structures to +the GPU is the identity function, so that all stays on the CPU, and this tutorial +hence does not require ad GPU or GPU libraries. + +Among the return values are +- `probo`: A copy of the HybridProblem, with updated optimized parameters +- `interpreters`: A `NamedTuple` with several `ComponentArrayInterpreter`s that +will help analyzing the results. + +## Using a population-level process-based model + +So far, the process-based model ran for each single site. +For this simple model, some performance grains result from matrix-computations +when running the model for all sites within one batch simultaneously. + +In the following, the PBM specification accepts matrices as arguments +for parameters and drivers +and returns a matrix of precitions. +Generally, the sites are the last dimension. So for the drivers and predictions, one column corresponds to one site. +However, for the parameters one row corresponds to one site. + +``` julia +using StaticArrays +function f_doubleMM_sites(θc_tr::CA.ComponentMatrix, xPc::CA.ComponentMatrix) + # extract several covariates from xP + S1 = view(xPc, Val(:S1), :) + S2 = view(xPc, Val(:S2), :) + # + # extract the parameters as row-repeated vectors + # θc_tr[:,:r0] is parameter r0 for each site in batch + # dot-multiplication of full matrix times row-vector repeats for each observation row + # also introduces zero for missing observations, leading to zero gradient there + is_valid = isfinite.(S1) .&& isfinite.(S2) + r0 = is_valid .* CA.getdata(θc_tr[:, Val(:r0)])' + r1 = is_valid .* CA.getdata(θc_tr[:, Val(:r1)])' + K1 = is_valid .* CA.getdata(θc_tr[:, Val(:K1)])' + K2 = is_valid .* CA.getdata(θc_tr[:, Val(:K2)])' + # each variable is a matrix (n_obs x n_site) + y = r0 .+ r1 .* S1 ./ (K1 .+ S1) .* S2 ./ (K2 .+ S2) + (y, y[1:0,:]) +end +``` + +Again, the function should not rely on the order of parameters but use symbolic indexing +to extract the parameter vectors. + +A corresponding [`PBMPopulationApplicator`](@ref) transforms calls with +partitioned global and site parameters to calls of this matrix version of the PBM. +The HVI Problem needs to be updated with this new applicatior. + +``` julia +f_batch = PBMPopulationApplicator(f_doubleMM_sites, n_batch; θP, θM, θFix, xPvec=xP[:,1]) +probo_sites = HybridProblem(probo; f_batch) +``` + +For numerical efficiency, the number of sites within one batch is part of the +`PBMPopulationApplicator`. The problem stores an applicator for `n_batch` sites, +however, an applicator for `n_site_pred` sites can be obtained by +`create_nsite_applicator(f_batch, n_site_pred)`. + +``` julia +(; probo) = solve(probo_sites, solver; rng, + callback = callback_loss(100), # output during fitting + epochs = 20, + #is_inferred = Val(true), # activate type-checks +); +``` + +## Saving the results + +Extracting useful information from the optimized HybridProblem is covered +in the following [Inspect results of fitted problem](@ref) tutorial. +In order to use the results from this tutorial in other tutorials, +the updated `probo` `HybridProblem` and the interpreters are saved to a JLD2 file. + +Before the problem is updated, it uses the redefinition [`DoubleMM.f_doubleMM_sites`](@ref) +of the PBM in module `DoubleMM` rather than what we defined in +module `Main` to allow for easier reloading with JLD2. + +``` julia +f_batch = PBMPopulationApplicator(DoubleMM.f_doubleMM_sites, n_batch; θP, θM, θFix, xPvec=xP[:,1]) +probo2 = HybridProblem(probo; f_batch) +``` + +``` julia +using JLD2 +fname = "intermediate/basic_cpu_mean_results.jld2" +mkpath("intermediate") +if probo2 isa AbstractHybridProblem # do not save on failure above + jldsave(fname, false, IOStream; probo=probo2, interpreters) +end +``` diff --git a/docs/src/tutorials/basic_cpu_mean.qmd b/docs/src/tutorials/basic_cpu_mean.qmd new file mode 100644 index 0000000..adfd3ee --- /dev/null +++ b/docs/src/tutorials/basic_cpu_mean.qmd @@ -0,0 +1,415 @@ +--- +title: "Basic workflow without GPU" +engine: julia +julia: + exeflags: ["+1.11"] +execute: + echo: true + output: false + daemon: 3600 +format: + commonmark: + variant: -raw_html+tex_math_dollars + wrap: preserve +bibliography: twutz_txt.bib +--- + +``` @meta +CurrentModule = HybridVariationalInference +``` + +First load necessary packages. +```{julia} +using HybridVariationalInference +using HybridVariationalInference: HybridVariationalInference as HVI +using ComponentArrays: ComponentArrays as CA +using Bijectors +using StableRNGs +using SimpleChains +using StatsFuns +using MLUtils +using DistributionFits +using UnPack +``` + +Next, specify many moving parts of the Hybrid variational inference (HVI) + +## The process-based model +The example process based model (PBM) predicts a double-monod constrained rate +for different substrate concentrations, `S1`, and `S2`. + +$$ +y = r_0+ r_1 \frac{S_1}{K_1 + S_1} \frac{S_2}{K_2 + S_2} +$$ + +```{julia} +function f_doubleMM(θc::CA.ComponentVector{ET}, x) where ET + # extract parameters not depending on order, i.e whether they are in θP or θM + @unpack r0, r1, K1, K2 = θc + y = r0 .+ r1 .* x.S1 ./ (K1 .+ x.S1) .* x.S2 ./ (K2 .+ x.S2) + (y, y[1:0]) +end +``` + +Its formulation is independent of which parameters are global, site-specific, +or fixed during the model inversion. +However, it cannot assume an ordering in the parameters, but needs to +access the components by its symbolic names in the provided `ComponentArray`. + +In addition to the predictions, the PBM returns additional quantities that may +be used in penalizing unrealistic conditions independent of observations. +In this simple example, just an empty vector is returned. + +## Likelihood function + +HVI requires the evaluation of the likelihood of the predictions. +It corresponds to the cost of predictions given some observations. + +The user specifies a function of the negative log-Likelihood +`neg_logden(obs, pred, uncertainty_parameters)`, +where all of the parameters are arrays with columns for sites. + +Here, we use the [`neg_logden_indep_normal`](@ref) function +that assumed observations to be distributed independently +normal around a true value. +The provided `y_unc` uncertainty parameters, here, corresponds to +`logσ2`, denoting the log of the variance parameter of the normal distribution. + +```{julia} +py = neg_logden_indep_normal +``` + +## Global-Site, transformations, and priors +### Global and site-specific parameters +In this example, we will assign a fixed value to r0 parameter, treat +the K2 parameter as unknown but the same across sites, and predict +r1 and K1 for each site separately, based on covariates known at the sites. + +Here we provide initial values for them by using `ComponentVector`. + +```{julia} +FT = Float32 +θM0 = θM = CA.ComponentVector{FT}(r1=0.5, K1=0.2) # separately for each individual +θP0 = θP = CA.ComponentVector{FT}(K2=2.0) # population: same across individuals, +θFix = CA.ComponentVector{FT}(r0=0.3) # r0, i.e. not estimated +``` +### Parameter Transformations +HVI allows for transformations of parameters in an unconstrained space, +where the probability density is not strictly zero anywhere to the original +constrained space. + +Here, our model parameters are strictly positive, and we use the exponential function +to transform unconstrained estimates to the original constrained domain. + +```{julia} +transP = Stacked(HVI.Exp()) +transM = Stacked(HVI.Exp(), HVI.Exp()) +``` + +Parameter transformations are specified using the `Bijectors` package. +Because, `Bijectors.elementwise(exp)`, has problems with automatic differentiation (AD) +on GPU, we use the public but non-exported [`Exp`](@ref) wrapper inside `Bijectors.Stacked`. + +### Prior information on parameters at constrained scale + +HVI is an approximate bayesian analysis and combines prior information on +the parameters with the model and observed data. + +Here, we provide a wide prior by fitting a Lognormal distributions to +- the mode corresponding to the initial value provided above +- the 0.95-quantile 3 times the mode +using the `DistributionFits.jl` package. + +```{julia} +θall = vcat(θP, θM) +priors_dict = Dict{Symbol, Distribution}( + keys(θall) .=> fit.(LogNormal, θall, QuantilePoint.(θall .* 3, 0.95), Val(:mode))) +``` + +## Observations, model drivers and covariates + +The model parameters are inverted using information on the +- observed data, `y_o` +- its uncertainty, `y_unc` +- known covariates across sites, `xM` +- model drivers, `xP` +Here, we use synthetic data generated by the package. + +```{julia} +rng = StableRNG(111) +n_site_test = 60 +(; xM, xP, y_o, y_unc) = gen_hybridproblem_synthetic( + rng, DoubleMM.DoubleMMCase(); n_site_test, scenario=Val((:omit_r0,))) +n_site = size(y_o,2) - n_site_test +i_test = n_site .+ (1:n_site_test) +i_train = 1:n_site +test_data = (; xM = xM[:, i_test], xP = xP[:, i_test], + y_o = y_o[:, i_test], y_unc = y_unc[:, i_test], i_site = i_test) +train_data = (; xM = xM[:, i_train], xP = xP[:, i_train], + y_o = y_o[:, i_train], y_unc = y_unc[:, i_train], i_site = i_train) +``` + +```{julia} +#| echo: false +#| eval: false +() -> begin + (; xM, θP_true, θMs_true, xP, y_true, y_o, y_unc) = + gen_hybridproblem_synthetic(rng, DoubleMM.DoubleMMCase(); scenario=Val((:omit_r0,))) +end +``` + +Lets look at them. +```{julia} +#| output: true +map(size,train_data) +``` +All of them have 800 columns, corresponding to 800 sites. +There are 5 site-covaritas, 16 values of model drivers, and 8 observations per site. + +```{julia} +#| output: true +xP[:,1] +``` +In each column of the model drivers there is a ComponentVector with +components S1 and S2 corresponding to the concentrations, for which outputs +were observed. +This allows notation `x.S1` in the PBM above. + +The `y_unc` becomes its meaning by the Likelihood-function to be specified with +the problem below. + +### Providing data in batches + +HVI uses `MLUtils.DataLoader` to provide batches of the data during each +iteration of the solver. In addition to the data, it provides an +index to the sites inside a tuple. + +```{julia} +n_batch = 20 +train_dataloader = MLUtils.DataLoader( + CA.getdata.(values(train_data)), batchsize=n_batch, partial=false) +``` + +## The Machine-Learning model + +The machine-learning (ML) part predicts parameters of the posterior of site-specific +PBM parameters, given the covariates. +Here, we specify a 3-layer feed-forward neural network using the `SimpleChains` +framework which works efficiently on CPU. + +```{julia} +n_out = length(θM) # number of individuals to predict +n_input = n_covar = size(xM,1) + +g_chain = SimpleChain( + static(n_input), # input dimension (optional) + TurboDense{true}(tanh, n_input * 4), + TurboDense{true}(tanh, n_input * 4), + # dense layer without bias that maps to n outputs to (0..1) + TurboDense{false}(logistic, n_out) +) +# get a template of the parameter vector, ϕg0 +g_chain_app, ϕg0 = construct_ChainsApplicator(rng, g_chain) +``` + +The `g_chain_app` `ChainsApplicator` predicts the parameters of the posterior, +approximation given a vector of ML weights,`ϕg`. +During construction, an initial template of this vector is created. +This abstraction layer allows to use different ML frameworks and replace the +`SimpleChains` model by `Flux` or `Lux`. + +### Using priors to scale ML-parameter estimates + +In order to balance gradients, the `g_chain_app` ModelApplicator defined above +predicts on a scale (0..1). +Now the priors are used to translate this to the parameter range by using the +cumulative density distribution. + +Priors were specified at constrained scale, but the ML model predicts +parameters on unconstrained scale. +This transformation of the distribution can be mathematically worked out for +specific prior distribution forms. +However, for simplicity, a [`NormalScalingModelApplicator`](@ref) +is fitted to the transformed 5% and 95% quantiles of the original prior. + +```{julia} +priorsM = Tuple(priors_dict[k] for k in keys(θM)) +lowers, uppers = get_quantile_transformed(priorsM, transM) +g_chain_scaled = NormalScalingModelApplicator(g_chain_app, lowers, uppers, FT) +``` + +The `g_chain_scaled` `ModelApplicator` now predicts in unconstrained scale, +transforms logistic predctions around 0.5 to the range of +high prior probability of the parameters, +and transforms ML predictions near 0 or 1 towards the outer lower probability ranges. + + +## Assembling the information + +All the specifications above are stored in a [`HybridProblem`](@ref) structure. + +Before, a [`PBMSiteApplicator`](@ref) is constructed that translates an invocation +given a vector of global parameters, and a matrix of site parameters to +invocation of the process based model (PBM), defined at the beginning. + +```{julia} +approx = MeanHVIApproximation() +f_batch = PBMSiteApplicator(f_doubleMM; θP, θM, θFix, xPvec=xP[:,1]) +(;ϕqc, approx) = init_hybrid_ϕq(approx, θP, θM, transP; n_site, transM) + +prob = HybridProblem(θM, ϕqc, g_chain_scaled, ϕg0, + f_batch, priors_dict, py, + transM, transP, train_dataloader, test_data, n_site, n_batch; approx) +``` + +```{julia} +#| eval: false +#| echo: false + +# test invoking +#θMs = stack(Iterators.repeated(θM, n_batch); dims=1) +θMs = θM' .+ (randn(n_batch, size(θM,1)) .* 0.05) +x_batch = xP[:,1:n_batch] +y1 = f_batch(CA.getdata(θP), CA.getdata(θMs), CA.getdata(x_batch))[2] + + +() -> begin + y1 - y_o[:,1:n_batch] # check size and roughly equal + #using Test + #@inferred f_batch(CA.getdata(θP), CA.getdata(θMs), CA.getdata(x_batch))[2] + @inferred Vector{Float64} f_batch(CA.getdata(θP), CA.getdata(θMs), CA.getdata(x_batch))[2] + #using Cthulhu + #@descend_code_warntype f_batch(CA.getdata(θP), CA.getdata(θMs), CA.getdata(x_batch)) + prob0 = HVI.DoubleMM.DoubleMMCase() + f_batch0 = get_hybridproblem_PBmodel(prob0) + y1f = f_batch0(θP, θMs, x_batch)[2] + y1 .- y1f # equal +end +``` + +## Perform the inversion + +Eventually, having assembled all the moving parts of the HVI, we can perform +the inversion. + +```{julia} +# silence warning of no GPU backend found (because we did not import CUDA here) +ENV["MLDATADEVICES_SILENCE_WARN_NO_GPU"] = 1 +``` + +```{julia} +using OptimizationOptimisers +import Zygote + +solver = HybridPosteriorSolver(; alg=Adam(0.02), n_MC=3) + +(; probo, interpreters) = solve(prob, solver; rng, + callback = callback_loss(100), # output during fitting + epochs = 2, +); +``` + +The solver object is constructed given the specific stochastic optimization algorithm +and the number of Monte-Carlo samples that are drawn in each iteration +from the predicted parameter posterior. + +Then the solver is applied to the problem using [`solve`](@ref) +for a given number of iterations or epochs. +For this tutorial, we additionally specify that the function to transfer structures to +the GPU is the identity function, so that all stays on the CPU, and this tutorial +hence does not require ad GPU or GPU libraries. + +Among the return values are +- `probo`: A copy of the HybridProblem, with updated optimized parameters +- `interpreters`: A `NamedTuple` with several `ComponentArrayInterpreter`s that + will help analyzing the results. + +## Using a population-level process-based model + +So far, the process-based model ran for each single site. +For this simple model, some performance grains result from matrix-computations +when running the model for all sites within one batch simultaneously. + +In the following, the PBM specification accepts matrices as arguments +for parameters and drivers +and returns a matrix of precitions. +Generally, the sites are the last dimension. So for the drivers and predictions, one column corresponds to one site. +However, for the parameters one row corresponds to one site. + + +```{julia} +using StaticArrays +function f_doubleMM_sites(θc_tr::CA.ComponentMatrix, xPc::CA.ComponentMatrix) + # extract several covariates from xP + S1 = view(xPc, Val(:S1), :) + S2 = view(xPc, Val(:S2), :) + # + # extract the parameters as row-repeated vectors + # θc_tr[:,:r0] is parameter r0 for each site in batch + # dot-multiplication of full matrix times row-vector repeats for each observation row + # also introduces zero for missing observations, leading to zero gradient there + is_valid = isfinite.(S1) .&& isfinite.(S2) + r0 = is_valid .* CA.getdata(θc_tr[:, Val(:r0)])' + r1 = is_valid .* CA.getdata(θc_tr[:, Val(:r1)])' + K1 = is_valid .* CA.getdata(θc_tr[:, Val(:K1)])' + K2 = is_valid .* CA.getdata(θc_tr[:, Val(:K2)])' + # each variable is a matrix (n_obs x n_site) + y = r0 .+ r1 .* S1 ./ (K1 .+ S1) .* S2 ./ (K2 .+ S2) + (y, y[1:0,:]) +end +``` + +Again, the function should not rely on the order of parameters but use symbolic indexing +to extract the parameter vectors. + +A corresponding [`PBMPopulationApplicator`](@ref) transforms calls with +partitioned global and site parameters to calls of this matrix version of the PBM. +The HVI Problem needs to be updated with this new applicatior. + +```{julia} +f_batch = PBMPopulationApplicator(f_doubleMM_sites, n_batch; θP, θM, θFix, xPvec=xP[:,1]) +probo_sites = HybridProblem(probo; f_batch) +``` + +For numerical efficiency, the number of sites within one batch is part of the +`PBMPopulationApplicator`. The problem stores an applicator for `n_batch` sites, +however, an applicator for `n_site_pred` sites can be obtained by +`create_nsite_applicator(f_batch, n_site_pred)`. + +```{julia} +(; probo) = solve(probo_sites, solver; rng, + callback = callback_loss(100), # output during fitting + epochs = 20, + #is_inferred = Val(true), # activate type-checks +); +``` + +## Saving the results +Extracting useful information from the optimized HybridProblem is covered +in the following [Inspect results of fitted problem](@ref) tutorial. +In order to use the results from this tutorial in other tutorials, +the updated `probo` `HybridProblem` and the interpreters are saved to a JLD2 file. + +Before the problem is updated, it uses the redefinition [`DoubleMM.f_doubleMM_sites`](@ref) +of the PBM in module `DoubleMM` rather than what we defined in +module `Main` to allow for easier reloading with JLD2. + +```{julia} +f_batch = PBMPopulationApplicator(DoubleMM.f_doubleMM_sites, n_batch; θP, θM, θFix, xPvec=xP[:,1]) +probo2 = HybridProblem(probo; f_batch) +``` + +```{julia} +using JLD2 +fname = "intermediate/basic_cpu_mean_results.jld2" +mkpath("intermediate") +if probo2 isa AbstractHybridProblem # do not save on failure above + jldsave(fname, false, IOStream; probo=probo2, interpreters) +end +``` + +```{julia} +#| eval: false +#| echo: false +probo = load(fname, "probo"; iotype = IOStream); +``` diff --git a/docs/src/tutorials/blocks_corr.md b/docs/src/tutorials/blocks_corr.md index 6d54ad6..203076a 100644 --- a/docs/src/tutorials/blocks_corr.md +++ b/docs/src/tutorials/blocks_corr.md @@ -86,7 +86,7 @@ Check that the new specification uses fewer parameters. length(get_hybridproblem_ϕq(prob)), length(get_hybridproblem_ϕq(prob_ind)) ``` - (7, 6) + (4, 3) ``` julia using OptimizationOptimisers diff --git a/docs/src/tutorials/blocks_corr_files/figure-commonmark/cell-10-output-1.png b/docs/src/tutorials/blocks_corr_files/figure-commonmark/cell-10-output-1.png index d620c2b46b265dd0de3784a88907452ad5c4e990..9f662c9c89df49664a6f40b6d13b20856f23bceb 100644 GIT binary patch literal 104652 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

*S9E{-Dt>rH@U0`S)3G>KA%v@e8IP<8kO; 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

p_rLsfwkV(&#{sYW_*rY;h*MphQ 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

wPfasRDDXFui6aMziz+<4C2wua84@D)8Wfe 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%0Ar#0u<&3R6s%*n@)SNwq=~-_9?p58@ zMgr=GPTK@n)P5UBG+CX>K#^@1@0;BN>9&QLNOe+2M?-{{?~n=rePz;2fU7(<*)9E3 zfyenz%TSW))ds%n~@t5aEo^@{(AVRVhSwjk8Mnfn@DXu z7)rfB9mTQ=w)4q5Tp0fL`Uu$3Ve-i$F%*a*3PcFSR~f{F7dy|QlaeLC2-Ij4GCa4X zJnvkfapSm*#UmVa-JA+%vVdo^`-t&^YsZ5ksgPz|39-%>dU1W)mS$w-LK6k$J`4{8 z8hJQ7)B95(N34GWv4&J>a=a(087Uz3JD!38%?MV89kRbJK_csS0|nKvq^8_SkF_#g z0?q0e*rdN*yX7Nwd|ae4w}oboOyFI#t1Ada5GQZd1v(^>C~b()KmVK0%ipO@HpNFK za``xnfaLqLI^(3``YWX9uV1OWaU^p8p4I~rnU>N@$k;ZiN>d|Ku!z#K-F96RJH+es z{__&IDau@=l<|I>`pU9)=$KgWzzgz~NB~H+lar&yLxS`(4u)|KBgkq05hFC&mYx9s z0QYNKJdBMI{f{5bklVSb6HqckUI8MSvjjYkE8#mZ{TC)i4dOJMU@<`TCFzvaKMFE? z8F)#RNhN{PalMNeuEwK0?RruNb8&{=g`G~&^TTSd9#yuoORjK441ieTgR(E4Cx0Gc}CXY zWHrYfE7&*sw^8x#94tu+JrY20Vg~pG$Zy1Ycg|3XMmE+CuIuA4@j8PdE$&$8s3QSB zG%f%25IQ)3Goi~w2hW%+VLD5T_eXg#Jb8X&%b)z-p;?XKduk|A1{DTmUE=g~lI8f; z4B0IiHj2*iyjzwaD=~%)M0Q7_!J=)b*6XF(B1lZhM!ts0_jU&^WQOIw&#QlX)~|?U z(B@(Ye^2cqip6u4fY}~g^xBsRQ}2>_k0=tqmrT~dx{LhcJb|{C5LRl|5YPn(1^Fhs zp#v^E^Y?+fbQKa7Dxrqv=o94ncdy>njg)X^mUmKfKFZ`kMxVg1Ev-L zvi1*hZ=IX2r=BAvPbX9EuK2D-GjJ*j5k6rBK|=3rvpiN3+uBu;>`-*>-1?4! z!EtY2ZV6vYL43|Phn*6ZAhdBGAY~?t;?bw zL|bEK)Rhq9{I;?eW>~K{V`u76 z77jR0=ms#)i5FS~sO>K|PFQ16X-FvPQufcv{A5avB*2)=J)|Kq!~MqKqLZT}f8_o6 z+RnHbGn8wjXmXsI)P;Pn4F$k^fgY(>pei1@61V4XfG84KZ{Fq%cd+j5s5+fIr$4y) zZRFIEP-z@$kO9kUAueHOgal6~G42<2Vo0KZ2;h{CEp(SQ{C;_wYMPTbgf9PfE?TlQrdx_bO|mA`dz--hEyb8^g_9R~N@Jp8OooKPqO zi4>+%Pq|-&^{nx5nhq!dCgPzec8WI^-uxW^6>$2f4$q6AjrXI$Iz9a)i_}iVVYDTR z6_1Z4hZnlZS3wCPWuu{wZ(zXdILb;=p0gz75gqz9<-|oPhzcfD4$!s9Ub{|2?KgdC zO#5sY`JzATD$xB<-_SqvReovr`4tLKNDveMbw-?=ZDEuK=k(g}Qy37vF8-!TKP3-> zbY`co+NqNq1$-Y!6g`xT#NS4M8%|Bz?lxroT>}QhKqD)jM0Ur@&KsR^qxka0CzGhu z7AF6HWP}|+F4Wack!_ig`j5``RoGwEIsnjUc~HN}4uYAOvjp@YLl~f-@6Gaf`i5S? z8oL-y$K#?5gsBld>lC7e9oAQ+cfoWg2n1Z9WbruYT6nZsnyB6DJy1k-t0uf8vW37+*0tfx-+t8eP_#`xjXpa6zJHe z%vRt=I5{&8KM6A8B)%#2;iX$!?A2~6^8-2vBJ&Gu`vHV2LcuR0mxCczPiL0|K0svE zz38Q=UlvFOQrOw=_|F%8S%hpxclIA8C?y(PteoFpHF>$Ke1Mob1)K)dUy8w+8Iyg<*>o5}3{IBfkSj|rT$0eyoEJxMYRtsKRB?x%BZ zKj$Pje!Fl)uix02YjtxoqiT(85!BfCsg6CdX*kfWY6=4uz<&L!(~-JqmHk?7wr54| zr7Hri76kALlpzH>E~HH-@sUJ5yTsVEagIBLwH^v&rM7v^3`2R@t*f_Hbh6-59p&6i zdWZ0E=3^Rj6`nri%k||i=4O;T@-S;#U6ML^T7D@H~2?lkaA$ug2Lx4o5I6}#qI*MB~uu=RvJ z(-Rd6GX!xDLe%$=0!g^@uBl>iKfZFB5#I*0-a@Tc680`7;NbYTt{a^$*ST4G@!rTy zVW&11oP;01t9t|4g(=+!XJH{s%V!$8S@;-A}poE#F+;5a*6v6KACd zI)%yhdyBQh&X*+}(B9;Ncwk-&9(B$#f7BgFQwGxC)rnGslhZ$en29j(zV?z)w@D)L z0^p&m88c%xOQ<`KIb6ybKllM_+LX-mT2PuP{%YFn!p0CHF0AjDZp39)|cl*o}F^ybjH_i!$rN};~_0` z3C>Y}<&BKl(!Gk3DspLB$L4oWyj`EtBe(7*IMI;Tgw)-g42rGh0QXrbM3C5F2qu2`hH;QPuCtr$Qe( zy^4wDV1M#RjpSiNT^IzI0^y>1-KjPc?(%qHZ#*xD8qx1OcQ7)GDr1}2$7KO6k*dmU zi13CCTE3z91j!bY<#%HV4NUI9w#?B_m@NZxkodx-`uw551%k%)+W~J%p|pF#vSO7*R5BV#;Bv;5dn&+UmvTQ& z9};4AEM$Z2o->rp(+%$I_U zZu^r9P!MCw&-oh39gyP@NoJ2rrrqVD$BDgtS6`Cx^v0$I&1+yh)~5TObehf$ui10& zW?$2YV{>yJ*AuBNr%0yRhM;v3l5|wUvmXZ)bs{2Fp5mnjYWFxdZHrBe94?%KO0^A9 zSA>Ta_wGS0Ba&&h7Q&*=itRA z|JdR6^!H^La=zzOWq|&nk>g|+4Mq~@_{Xn5#qM_4f3r$_Cott^Q?mY~&4lHv%kL+E z2*XDRS-SIibTO|N4BG=)b84-G+x#_&>Uh+7B9BLxgu*<7k)h}{V2yGSV{ZOrc!U~M4H+oD2xti%OeSjR$ z;ql7SnrNShv+X(a#dgPckd(N=<6lHS%0P?(Q`Qg|{fesuf&}S8{+NC-N{LZYbaIA6 zmIALM1E_rCMK~{)!u7WQ60(L+DbABgBJZA17htL0(%CrnWGLuvn%ezI)!!YGTazBr z2&zCRuv5U%p8_7CCK@BmD;|^M1ZR!sedRiMyo+e_oHulk8TQ$P$O~#L<0{fXWrzgO z^?1FzPzki!P^^(q?4}WYDpFS!NmWO#xi|ypArU1c=&ZsjzYnJx+vh*J(wsFsJCIr6 z^yu+LS~=h(62Wf9UjZW$EAiK}o�u_1=BjO`GD@rJdKr)E$H@J&4WRzn>*bx>7DY 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 z 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 literal 105495 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

QHO>rwr)8@F&NJ3x;#E0bDgn2F!y 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 diff --git a/docs/src/tutorials/blocks_corr_files/figure-commonmark/cell-12-output-1.png b/docs/src/tutorials/blocks_corr_files/figure-commonmark/cell-12-output-1.png index 23e29ce24dcd490e1968460a461b8a0c4bdb0d1f..3cbb9f55812d546986f32c458fd2951e7f5f8469 100644 GIT binary patch literal 73443 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 HF!B2zT>!qy literal 68473 zcmce-Rajh6vn?7S!Cit&aCf)h8rxCFOgA-DzC-~p4#(cUe85d#F`Pajw?w*z|&s|i% ze?s_0@l^%;1tNyHIF{^bx&_B^`+_>zF61;fv0^_G`gIV3;+0Bjgox_i% zOH(s5p}Dza49Q5)rY;MPZ}W#!HeAbeuCA_Z>54*sucjY0u)3+Ksi@-P<9{A4)?xm% z;4tOML_|XapJ`)fSJ2Usb9Uw&y7oG}r|bT5HzFcJ?CzM)^Mn`^6Vrx^Fm&y6WF%6w zG^IdxEKwi$fcs{u|GIKGC}AS(4!}>SoviqO|5-(W_+L+z+x)pXwqNTYf&NmY!S-n< zjgjuTwpsXLibBK_UH<;Rj)yY*?(i2}YI3p$FCe_xJvU`fEx`Vq#)7>P@Per&8tMvOvB z?H4T8BOWP6LdfU}6g)9;O422rK$_kyD;2QIR{Q1Ls`ka7=5B;$uBXtuZBQfHz zYZCt;!T2u;$W?H?3zH*Q1450p?A8v1R$8pOkjy1 z^dAvF<}u0a>y=lFDf}$AlA( zPG)tvGe*}RN2aW%hLy8$?9uV(M6kB5ZtC!Q*<;D!YJVEOe0Dg4+fJoIzbV%Dq&fV{ z7X+Nc`Rd*Eu8`2MFm{&>Nw9z}40LoR$G;m&H5mG%33_5cu7wh%F!e-cad^C$!`e9P z>uKu6c(WHnE1du69U$wwbIi~?q)^ar=D9AfRt_mq-~)?0pUBh`Dg{3zvi3z?+LReR z&_6AE0%b#9_}}9tlYV2g?`eCgQ|I3l&o%$liVCLSkdSnKHyUHV^H;ZPfug=QN2YTX zx_> zGqbbjbNWs-Zo5j3&D(g(!WV;-uqAFiX^Hy&o#AOy^eIHMT#MbT7lFrq;gi{P@q4f~ zu*LW_JWovdX*NImgmP!YaAAX z7&zE8itFKI0qd*2r`uo)Y#RT2c$4dQfd~@2!l*qXIvT~*%?%L+MKZ;*KZa-^inU`f z_!V-Rh`#{3$Q^m$-$P^7qvhtL`g$%$F34O+d+rhxqrW#9Ppd)*K3ghM za}i^})wWn_bO84d9~ugWlSow)_%C3_mfLQw;u{EBVR7*Wm-~Un&RC|5zCIC>lamu^ zz@4c-gE9pkrCIYblJ-wcSjoxBp`oGc3`|TYQts~DU0q!e zBt*n6sI!W?ddOQkIs{Mf6rZMshDn27x@e$C)k*8A$TB}M+N#eXGi(vW#b0C#deU%k zBqEoUmgYeqX`uCNGB7j8JUsYV=+ba;;b>D(P%PWPO4i9BhoYX}m($qf&3dLkLdax$ zeP3traa^RGgd)(dcBH9CoWBo;3hI7NN*<#Me|QUWHc9@~NO9rCdScHJYn2Q;7e!iM zlCMjVnYsC5n>S~bR+T}7bO8kmOKfoP3kzN8BDHUP?gy~q1@>Glsqk=7@4!I8^uA7` zJpt&fQtIm1&CSh{Qc_Ucfmo8Z+f`p;(SWSpUP&Bfk$WnSRubin%}v$vSti34oDvZ4 zsf7huFE2jud2MY%W@ct8p!OjlAwggp^epN_!*BWu2MU^>M1k#+{^iNdf)mb=`XKy* zoLzX@N&aPY&v5y}`x71hlhp<1VEQt4I!6UGQ^|0Q#x3p5Lanm9>Q+Iw0<|)7mdVWg z-+0S?@ZSH~r)pnV(*yCvrPPTC8zM1`SpyOP~9$a{P9 zfB5i0F`XlfchxHd5u4_0K=diWsNDw>w3gP>4h1QxSGkfXe3`MDvig1a6K*JbW412B@Uga>Q#r2;S?o{T94b zSXlVObz6RU#ce|PG7kvy83wfOYpuoXwIRU>b z703+Bt-%Da)xVdQr?Z*9sP1@Rhy?ZN6Ikn9ka_^!?N67WC(*p$kfsEPL9^*n5p|+k zlp@IG~Ir~4Lmq_)y!7g0BNSxi{NC!ZYsP2i0 zIDlFca&zOFns{q!YUoG3|gd;&&J~%jFBaETT@j0L;^*v(0xV%I}My3RnqXfWC zkK^A`A3o66GGT+b{HL*(JC2zL^%;g^7+b~2Ze)+$8w>{j?Ni(%=yOul zGh+jl2nM%^^(s?X3|rR0ZvJLI5c^1M+mL}qBH&EVkQ}+SWnpmt@UX$a#)hE{w&K^X zI4o44SrVm#Vc?B>adB8>N%@qVt+WRU<;+Bsf@(R$-mn|h>mt|FedA_JWp%+TG5Zxa z#IEKyCLC?lO4qJ$LS9^ojJo-kTL40#EnsrsO&{Ljxxtx*9u}E8{~>Q{AY|Dp zmnaf?de4K``Z8=vf23vL4@ap##+#&7%E)HHaTB*ehHi^_Ldrkz?bmCw7gs{Rd1J}RnBQnRHfR2YTq2$X{wu*S9e`tu3`eM~p9gvloMyz%@Lsa-I2pZ(W-ZteU zf)`prQRYgkgxhN{7?o)1Ju^AQAI=;FU1YLUla927`g6Er1k{z^B7G&S0ivI*J{~b_ zB@lK`vAi64sDEBqKLwlQt^wq8#0sC_o?N!-SvlzzxXG?GfAAdO*HKgcQT=8D)p6qQ zO2Jw0fI>)|RtRI=Sl9UlO7XqN~Qq@%*=R# zPL4uDO^drOd?p&HY^x-*>F=DFyRXa5OIdS1BFq6q?<|}MN=Im?Q8zYO<>x8n8}(Ux zG1aM={zK6$@^`H4G}OVczH|^qfoQ{Ro8^&HW_qC=&OdJ=Jtau0u<@;u6YFs z*HYG!?~0ILa<(m>i69xI4-W|CuEWj`ORIHRWe(7Rwd(;xIe*4AtLy=b8aF#N1Td*W z)X;Qy3XZMs{&dvMH0co}V)TaJdQej=z(X&J`U%tLSYz+g`}p>$xt)ro{`b{N+D0b? zxCB|?%|mT%%rFiw8C;r70ucps2?hl-FBhF_u~=g=hT03ftyFxo^q4$om;@w2(@+Xm zAo6-#vgZ+A%q`!JLKMd54ip`8;K2digukE_>tHvG7WchF+fxss2hPlTb*fi|6R|R? zeYkwztJzG4iedVmmEt5#oVmtHkwN$p5YOfFTmO2UBf8aPuSDJx*_}#3L09UXBfg$d z_h!DzVftM!Z){!8UuSc+7%XdVuzlFREAR;-*&|+Muf$M{aAaImi|W6CwdhgNOt;sy0ePqvtp3kSb$_@ZE=;t<%vpdY_I z*Nw2vzFvlSPR3^+~H;aJd;f~wg_#`2Y}Hp4L3 z^-5LmJ!_GANK&8sQV#DFA+1*Kd_7df*;Y^UCR0Kh)9%XZQ2nJW()o6Ym!l?H5vtV_ zS$b5NLya?gvnI0_mfaP=p3b=2)g^@;xSmtbR}CWSdrh>6nR}8`rN@4H1pUv|ke^BZ z^Xm7EqAF>NXu(7NC!{iL?HhSk_}ijOPOV($uMJs1=Of*cl6Jvtsdt_>7g^kKWO*Lz&ZddNRNLqhVk`eO?C2=7fbKGj9o+Ti%ejkUSZ*P~wm`T{zyrlloqXU7PJ8w01|;b9vG2Wkq6AXw{I zwixAsZ(zpDf4qhu-CVz=?@c8oBh72<8xFgQL+{lT|A8(lvPcFBuym1lffn?{MD8U| zcyw#Kl)IN%jo^Z@LEMm8iE>2(D7GiT{_Ukax)9<3fr$MNhz6s74J8)Te}yuVv7)N0 zoAYbVj)FRqSK1h+Wcs?eg!*j7++W8l?`z}^&s!9MlLH(jOE)6uYm!vPVPoaFXf6&U zyE3PSU!d~D&@y=69a6&WQIj4L$(*J=gKeeWp(I)Yb~8BSH!K#tUoZ{I0v|WYz>rnr zckf!o`|oZ*6gH*ZUu-`bfI*|nu_-AdW4HmZFuY&zqOxzBvaP^=(~HT75H9fYQ4yqS zh#WDk5%lt~L_@wwHSrvT^`WOw(&#;m;OYDj>X}BJ=J;L{vK+Esq@Gd@%rM3zQ(|X4 z))b)h4TeFPDB7+LBZ#2-boa_7C%^7u^xJpU+aq$q1oO-PJx`oKbaBmE4oqS81Jb!AO=4x1!MY-8#-BcfBsgT^j z+?q=y=@TbQs+%E|Io1_fV0m{)Jts7m3UV)N#~Sa_IP;R;fo)p&*H4*(*2EP2=%hj| zb|!XwsfX?mCQ-f5)4RUowNDWNVAFlIJO0=Z;ctD2a5d$sAFlE-kq|5>s*D{$DOc&W z=_Ahb=g*e||NWJemVRrn&>e;hcmXi=xmL;9~?RGh=oouw2WXXXMSC;h6i?GO9~v+h$0%dXUT0 zKMU7KiOOuz6l4LaP2m`sH$&xvX}g1pIA)EoAT8x z^XP<76e9pWBX(|b2shiHTAz!pj<#_}=$pN8_W65*_ITci1_E$4ub{!L|Ha=I8z9l- z6^hFeGUb{>MP>&ccqLG7;{22P_H`*$%1kts_?7)KW2OP(IJqAPsI@Lkz&Hvi2U`QS z+>GH&m%}XvCr4@h4P4d(1V*~4QDYPZAiS1K(=Wep`?wW={_W*phe(7JyBTk)IFBF# zX+jng(Sw8fSlS6m{T+v|(IS(C;)>vJ##c|?^|?`lIR#(Hi|zdUoR1g{jD16C?B)v) z7s_xnl6-|!mSw=Kl+N1XprWF}xVDQ6SLtZ{AlmJ&D-4F#PdwF^Jg%)?lsi~>L zl9J8M%@B1tImE-c%7X9TBTaigvwz%E!9fcTNoLgMuo}hZaaJ^B!?YXD*3NEf|D)gI`GC;V-KN3d z09oKD*}prP3N1z`6k4Iz5DDXBhM$_0Kkzc;#m6jqv`&BfSx_NbXU2dmtUKn)> z6Tn)_g~Ocp@@$jdqE~IC%tLSf9vRtS5g4Pbr@GXNucLZS;?r*&cq+97m9$zzN>a!y z?d9PBe*nwE(~|2=QJyT5Kl_9)+8Ts@@us||E%yqTWyb*r?8NR5-vkpbb7wdZ)0ORx z$9{ukBog+3QQjct0IUDclG3IeAm#u?r2?Q!&5jO#IxEUI^LR9=hN14Yo17w01|1Wg zdSCfWTe+>viMb=cci>shF8lE9w*>_N@b~G~F7wM)<{#$xjfke6YfHH^dnKyR^-?O- zd2QZUUW+J8#wqtx0}m0cg4FBlR#KX~s%!(qs6KHYAA$S( z``+H(_?(<^FlXC1I`%IuWy0pW0-3mrnZ2Y}l+bt`}={BqR|9T1Hs+yWodU}MfLxS`jo5Qq?{gXjr)_&Yq z!>O|x%LkJy4leFgyRWCn-z)Wwrw2PQx%HiI4gls6#iKRbu+@Xz@6Nf3I^s|T@CD#@ zcN*r6Hv8TfTL6j@w#%+g*K(^2TQ?kUPgdF<4$3QxJ98)`KEqfC4sa8ZQBet05lOVl zzrZYeu<#HTm&q$-~t_80M42)Pb&DBZe8S=i?4;E~cn&6G5` z3+S9|3o53fTZ?&!?loxuUA2khIC*}1Mann!AQA^d=oYmL-ab-jt9qya(k|b7e}EW} zNc=tP1*pNYkw2|&6D5#nKK;T9*)yOc8_=9tiQ<0E7*3V1l|iWwF%qA$XoNVW2J7a%{RAZHd!ONFAHPk*#i6C^6>YIzq{kC7$ zW$=L7RK7bV8K1x;BpiNY>=*P_Kp-QAh!>Vhmw*U`?(WK1S2==sM)!xw^T?wk`&bge&s`>YWn~d3E3KFJySbOY6j;xX z>LxBOMp*yD+rucW5P0;RSiuu=0RciOkXtYoJaTW(23F9PoI1w_yBZfAfn7{GxZ(Bg4C45M2(ERiAs*Whuo9HCcfb+tDIY+X11zwvmyfBho^y!WgMv%XH^$K)c4*LbRP@-wj>0Y!qczu}BIYKii)4*^%+b|2@ zQ;iVJlqd#>&7q{+B^hHYr0?YCN&Hl)ronK#VNY|pI=*OD>Hi20Rc%wz8=LKx8e9#~ z0{|IhMM*5j93UeCYw!Nuy#sS=&#YU>Qr(^jV&I~ttdS+>iN?=kKsnFT&JBW6h)2TI zmvk9pg-6D)9rg|JF)?}-D+li0=APP~wG`UedD3?huL_!F|7|m_{eyoXV1GozhRh^V z&P&V2`p1s^3evB=lOcZqdzd`t0LE;L0A>aj*`keILeO25z&^DEN(vnZ2S=KKJA*(r znv}CM+vY%ANpbP(z7%GCSvffhpfHpa7E%GZBV@Wa0-GHlg%0I4(2>rbwR#+HOv#W@ z3kqfeo~q8Y=XDm~y+9g7lZle{-JNf`9Q z&Aq7tuf)vE5&zqj@Fb(^65rdCt(_fLP%x7K>ojF!vC$g=NK7`9pU;eZ_NieqsUwPS zq-`?>2pyOnj9FdS0nrli%ZF2;Zk%ESMhHY9u0$YCQjR$P>khFOG#uOJ(@~4-9#H5( zmcaH3T>4-TbBZSiNW;E8D(;-<_Yrx@otL@_Nq1`wh8 zN;MhgL{?L)HU4#>!1pKH_r{{?W48ib(BXw;hRAyg;VSZIy4`v_{J=DOq%9o%P z0Jf9nCc1kSr+a#0ky_0+S0YuX=z76uN&hGTKG<@k&A(YbGFer9f|7%OR} zJLB42(eTg2Wu_0A?TUlJx4T;ALRp+>2HVa7ud40sFO|cdyJis3oSFG~Y(m1wa-c+j z-L0abp`l`6F#33Z>5`n1@>yL+2fs>OLZa;Z_x$|)7kz-;1e!A+D$vCyCskk>@&E7v z@#*P9fIoD(xV>#*QaAb^FF*+ZVSEHJ(qPP={|2COaB#3QE-|qpAdYjuX)$ncLd)0J zO@>ECRDmc;*t#+vO~4sX718Xrd$AcOT5C7Y0#c+3k6EvGqc6&38&pJ41c5$*F!}43 zIM7-^b2845NV&h!;ih(HHjs^P3LXC?YiY@udT~y|K1xa`_dY7ws{l=|GQYMqF$)PB z43}=rXsI)*y1Ee?VKd|}iaeOc$~Gk3ksWx_ab-sK&bzemqTkc3mi8o_lf(dEG@$v( z=qORojgHdlR`_fraaPA4@&*cipMSrW(+DnEWPk-%mc`v!J$ea}eV`g)XrnYv0 z7A&j=6F|KOV8eg_x8HQ6bnTve?%*$7TX(n_ac!EhnxCJLx3@P$!25zq34m;Xr2!us zISs;NV{hNP4`fV;fXfD)i;GKdU*9(`uwVB zL_|UoXLsF_#lpf`Xs~+&1PBNrm;r!b4bf}$U)HIx zF*9@bLTD#S?x)|{rKP&0eC8oqd5a<>%9c~o!D zx{8n$e3omOVkZ30QOlR8D2a)^f;;)xFi z?u+%7ufL%7udU_gZUC`=ty)l`pf6}Tq&*+fuE6!e@A{oG4fD{3fjLp6PC-r|`V|%V z&!5*-z+D1P%teSg&zY?>piFU3i|MLN6FY~b@*=VVXTmD}V{q0w3wNx3>$6ir6iOaaO%HQE?Pfm`s1ye*k^D*7w%2aUGqxLXRd;D*+J%86F&b z2mCddKOLJ2CJ(P46Kf}UYqw+xa_+q4WC?LqpL~Yj^R#^w06jVNkd+{;t$iOya|{o# zZt4Ek9DuY0^cu^+Oot25&$41uc~sP#`d3c!eSS}3Wl!+1WeNeIXI){{+nKh zRV;1p+HXJ#S`f7OL$W!!ndtz;R93`;@9E@|Efkv|``l;^IL*|Hxww+F_H(L#$}f+D z{k_l{^$&uI!P! zoe*%mhq*m5=IET5^EfZ<{G;%>l&$?U0I_*rWGjUmRm%X%LpX^lB3A-{*ai+DfTI!f zy*piP2a^pD!Hm4OaW5_|RA8tLOgz%D#1R0QwzOoxbi#x3>J6@dM=u~whAi3_S5?Il za9XiBF7x5QwET2Fm$yJ-hHc=@&7O89*>*9^xV63g z&FiFjmk$&o5J&tNX;4jo)q@9A27_1tB{{(W4V&z1%;9rn6GM%v2a>7e9t}W83i$hQ zK17=fWNcs)f}ti@o}LvNcLo4L02zQL8enI+zuSz1srBal(Wbx(^YLH?F>J^J)=q#z z9D1k#xOFh8{)WF-(OK#aei(`)aRcXs{jQ$@E$1GMT#@vFXlTWlbcN;*nWzNuv@kACJ95fOz>G4kl705FG) z7^<=G0+EzqRI*s$;(Jv?~W=j$1D zn1K?q5Y6>|38Ywa!6S=5pZfPkUsH!fJv9UCilp(4j=%%O1v(LMDq>Qd%vgq-L^j`tpHfW1KWjsQTNcu2ylwr1*3~T#&2wx{cduK19OcM zuwnIRN=m}jGHreYim#f!{z$dhh5#36Du7UenMydV$1Sc8W{CwoqG1CIA28`SwO`}q z`ri~CXVj(JEnm-$)jAQe?u?N5yCN=NPRT71~ zMiqyM0K(MUdB~I}t5kAIWH5Y@Qt$;w-bSDr^k6eP4EVc(Mr!s<=ud#0F-KBuvPSk9 z&>NqO%Aq$~7{&fcV;2RMkaD{Q*S5BZj@+aCKC@l39K&P@NG=eO)?kjH2Km07M_Y!B zC1*YhmR|jGil6%VZ8fOc;Pn;edlWz&ihqBP2R?oo=y6~O5&zrftX8%j;wyMLnMi36 z`>Z{*JV*68)0jY9>;8v`Hb1+!sRi|2qfZ+GFRt`}0}ooHS^)eBzCNBO#$NF}nJ;NU z+X``bMd$b)2|7Ughq6qQ&Vrz0Ol0Dr4GAFFTlcuFDkW2cxQ!R>-kY%&RVmJ*B%ow2 zOW}V+2wqR0vgx(qa;5lh@fI+slV$3(EL02(ks$5?NCi`0rfjyvfm0H;hN59WeC~W5 zaTqUMU^jfZL@@H+E|K2RY>??q{gFc)seQ$>Ox0X4O)0}7Wjy5jQrid1zO3;So^qyL(2jZqZ!s+`ztuPkwSkg;OF>@PZ7Ucd2j zt!Rtj<;hwH%&$w3NSlCA1SW|%1hd^kAD$-A9bfzJ#tVWeiqK3|x6Bw;j;Nt>8<-qI z`!ImLSGjFl_nRcE)V?3&84xUiB212uBWF;uv9WRY^yl>4;^(L5Fng#rrF66jP$Rss zNJ+;NsTDA)jDardq75|GU_{~jxENYKgWo^k#w%%yFL}NBH46s(rc$ucBoSu;-NjM2^4J$UWYC9o0c17lCWI?NXfXV2i2V__7>3;My{E{-D z_=U1Kq7Lt>$L<#_(*tSiT1(NiE#Kn-v(t+(`B$FqC<95Ps;_yTszmQ+X=s>5fUX-0 zKyGu|MvK-m?p)*9*}Tkxq0UIy5nXAQ;nz-5WwYp2I{AY!U_9^yoz_;b0?4e8hut77 zU{Ejs#+geFB!Wp64CMeJ-M+ub=)Y#HB%qr`P-FCKtB>;t0SrLH1U^y1{*S07%6Zvo zY50y-xhE_el9rrR@(23ffD2gdEJ4CukIA76d$56}`$O-rAksbPkcdM0WKkO2oehIW>TOaUjN{kEhcp+tM@$EiIDpw-r{<94%K1u4oj5k!>( z8W5EMrY~Z3` z`%`o|knj!YVZu`rO>OIs6hMGvNxP$28#E!X$h4A^xmu%{|JslMoJ~(M;WTqr!vG^6 z5D|+8YonFa3LwJ#Uzd_3T&!yZfvoTPfq^AlB4r=TF|Tl3Q8$SoyKpC6?AVK)`FWT` zO0xkdv>{9IW^RMPGZ0zlUI}v9g?<9fHoTPu`r1QC_{$peNHL@%S;d$Y<|zYW6Aln9 zA3s>gSo!CM1D~PWKp}aVCghOl%@^928!v%nrEBzFn)3ui5WqROdoRq5!>~dv7kZGH zKxR`09uFA&J9QF_Y0?@y5)^#Rgj2Yz`SVAo6n5{*%B$~ z%`B;uyM!t;X-v_7cAvw9R^T8m@N)OUDr0}{*H#ywq&WuXqX4$gv~9y?NGX<-E+UQh?b55G7R_43O(OVGSPrv-4kUmvdCBZItOzi+?#=9rcfY_5&BO~93y}lhyZ-9RnI;D!b10bF__l!y;b9z8L$k6{e)8rwk%uK zzELnXFzb6Jv!DMRakvq&ynN{M60j(7jk%`477V;4@IF$oO{Br_6u$RNIOk&w8`}>< za!*gR-6HO0oS8IdpL!=IPY)F8Ljy`8B@GvP26Fm^RE2wAAM}%lw@I(-aKnI~u3Xi$ zh9838Uf6H%=1h@$OmF6+_adUJgU=o9*8C)`3iy&AlAciCRPc8b6T#;STf7x%ov z9AyvOi-R+&->>eS6%?NV=Zo_!@3`y^+2?h+g2jGNbnAA!Udc@GZpf!Vl|^$la#)}M zhoz7(Z~kdR%0m0f_2WxsdZ_i-|Re*CbV6fi_kJ;^1D_gth#xeb+sEp zn(W}J0MyIbBO5Tj&FV`=!c88-!vWkmXoFPadt(Lu=KO0mJIC)!_%wdK1K&Xaxv|^0 zrE;Lp>}A#{;OqmYoTo(9FY5B4K_n9>Z-EEE8Tfda!;OiDjXiK(>njpkv>3rNTH9YQ zbvpS#C(c!X89#K$UhX{=12Aer=}fL2v?^c)8oK zTm;)X*Y+Xhe{}z1bxjSfrgN~Q%k2QngeLyW^Ve>-SGN> zo%nqc?4Lh+O#r|c_*xye9&gFgr=WIu(PA*efS-yr^vNU0izCmFd|&u&TCQ%ec#0(x zPddQ4xML1pV3*=2VU4eL>k%?}5b8NVk}MaDe|;Jo;M)q<;%k~ zEITT4!hu6{F!1xAZ>hjCSE>{8ZYM^;^ss=H(mX+L<-`h-J+^WNNbVquIwr1P-X5hR3jO&1b~{0R2TZT26{4OX%8f+ntKgg zaDlzEpsX1EgTm#m%%f`ageyk%#daEPNNcFA$y?Ti#eVC!+o!5Z0cN{SB8&-UHxF0P zA~wL>2o`7*xS$JCXC4hm#Qhe}N8bVZp`H*|F9!H6SpE}l;EUtCxnS!M(2xho{iD!C z+B0Td{Fkp}4M#~d%uqp9rdh9d%*UPXuq-T!4Vp~7NOhv9(~$Kk*=qo#VCtO`Eo0_? z#JIqRbE>}^(O~uwE86%6dUhSK8v8-oKTXdve?+@1s9o&V4wrZN?VO(o$__9rd{Zs| z@tZ`blL0=Q$&DYNd6C~npEi1qUtL9_kpu8M@X+sSJ;0VVN6cy+V1;-BrY%VP%)+yd zA%;yg(#HdgS`@$p8FezJd-CLV+c&rsfok*P(S|??@JF>)g`iu&#`Qw~79tRJGaWNF zJJQoAG1?m7dxJ$ZtqSus4loJsf}P8nWD03F>pQA3xwn&)(myhYS3*IB^&H77`g9qowe}|XN*(0l&RG}EM2)@c< zl6_$i>&iL3+X_90S-l1iNRzu0@Ct93oDv`qyz>}b-8^yqbNTdd;&ih^cmf%&YijK_ zXCgbirWHq;I_&bo`@XR3zS_i%-r&KJVk9#29AUoP+hdBZDlL9E;$rXsDdWNZ?)TEd zh@BvsThA4W(pQYi$h?0w0e^i+{m#UKpL{EUpbWUcGjkPeoGZ@ZSniAUU?|FGs;=n^d+ZMl~adk-|y{%r6R zTT5SFH>e{_eLo{4G~ep$d*ube2|CYVJ=6Yewh`QPdv?l5J89)HIeSWl(ZB>%gL{ej z0*T0n-hOX;)BpXl=LOr7s~!uf9isq&Y?@Kn&`$q+*0-99>H`zD(Di?`d!CSHr`hMB z>uLM593*(~9pL`jYU*;zX-ixVOQ^xQ<{!Q*ofx~vmrM+ml+E`ilv+k)T3cqUddoz1s2MKXy*WWy0EQ;sz85)M|uN^M}lF}V2fqFw=VQNCy+)e3z1 z2Yh)aoGc_GFYg}*t>u8Lng`Qt_TS}>w&H*pGG zd8(%FE$7qQ7oa+C^sWdnl5mLz!8-TCQ#|{y$xcd zDXi`I9@3R`h7oL@pGf^#l3);|$@Mpn$K<9=UG2pP1Us&Y_b@L>7o1N~*K zxm@g|8&l{fYu;IM%5UUnycEnY;?Qq+F5Y_!b{zOt7<5*o6=^H2_w^M(%%uouT9K2P zT>jRh1n@c_fbb(ozJObM^I>w`)CDr6j6_MHAyd8>D@w5*fvP$4@p`j**23D{fy`Ut zzE9sf4>b_2sXNjC{p0yp;>J0T^JV z5U!;?4=+5Pymw?Bb&VqRG2vcq8%@%Tz@==HTYLWh&cc`nIw9}vyXVZ!NBpTrT1yz&e zO4m>p3!&@w@qWgj7%d`yen*mdgzM&a+W8S)Kj=3qV}O8RGoZmFkAZO>~JJJE)%r z|4YWH+WcK6!M14lwIKu1V)4m}C7>z(mW5=*a#OwR;E0x6T)9vzWMGKjC5z{6jwbx? zGwQpJdw!R#{_u-ma{?z1Z76jseF-0L1YKHQ1wmf@!)>Wldg1LV!M#``&EnsQL2)-% zLe1>wR+^nWuPB{}U+=qXdFi5xEv!Xr)MFO&XeBQoCMG5-%q=F?`A(}OGs*b3^oJe=n%$3Me}pxkuZUAwE}|J#!Gsbq--NxJb+)R!eH5Rp`CPEf4w23_*S2tL&@Tpbs7 zt6TK_!*ud@gPd_hk6;j-_wk{?zs>c@2CXsOg%Qc{uToWZM%R-Sw&7p2M}7k&Qjqyp zI#~(SQezO@u5@oi10I&-5*|&rikwxQ7*<5Ypq~=r8$qx56-ltdWI~NX2F7x6rX6c8 zB}y$KkO!zPk9G(j3EUYv+C1=-9V>Q@SFZ1{5KstlwMvMp=|VpH?pPIQmw!PQmd#v@ zt+t~n*}T5u_tvP-ygyJ8d|9)w5_&KrNz?#KCeG)(cvM(q-wS$<)-P+dcG@ARmGV}r zKXhJSKv$*lP~tYVv8M->QF@H^LWAC2VE62Kwtyus+3vqw=*B$aTOLCliBt_;w<$)6 zkfc^i%OwMSil0&1Khv3$xxqz*y`K1eBrWL@VP|sn7#hdUX`isIkTyS^I}nFrLX^h z#b{Y?1UX8EonJUIF-7DB|FVN6xKAVg&QHOC_IcAACge^h71r;i;KN%h?;^Qv5x3rz zBUXdYb~!1f^2_Gp!b@fX)m!xIyR*@JzkC!z(0P&wNP;`N`;7uhTa|~4$@#OadFR(z zDHI3NzB_-+AWH^1}y2LG)XUH{ZACbaf2` zEfI_+9IK$^62~Z#B?$=@pznZsf+eeDfUtf17e(>xg9~y&VmH0*LC*+OOUM03%$76B zdw-7?iyE_iX$z19>Yf>9l#sBdF$h$&FyMDG*qQO?NPXPgP)h;fwu=HjAYSgCV{ul?OqS1$h*G~aEvcM(~ z5CE%mL3;0bUeKSix%I*OdV4CrGzv7<9%?x(aoO(WVi0)HRi7H4dVH#TiSN#k%xzu{K9X_r^g0E*@pGrd&yxfbMg|! zB_Nu@nYlnfHS$U)VPOdmFHegR`tpjUm=&qj$umZFpZ z-)QWBq0zX?vR1y>QJhOD8U+&2NTFE*Aun~H6w4TrrWM*z`eR^b!I>!{U*R| z6^;xi`YAM3nz}%Jgm`F-le5`Gkt43EYO9%f78VN-lB~-IN1tP*d{n|GkA7JtB249v zUtWV9a!u`}8T4pi3Ff-;$s zmzQ^{1`sqd7dvy}JF0hQ{_uKZUIrXI$=Z!1(wM=NQ{|TSEMb%%cm>Za8(U>jW~a;= z-Gnr-z%Jt;6?LQXX^3W(LU?NK$VhFPomxE2o7fRYh)o}1-rH;1oU(0n+Ya|VXS2~* z77>gJR~{>>=ADhJH7WFiac*fJyN?Dt4|A8j(*OUQEuq!Ek}CgvqP~Z;|16vHCYborSxcr{gv1I4T z+klrjq}Yf^4k`eEKCIn%{i}6ZzW9I`)6O%)K#(m@LoGhgp#Ir;>4+(ImX@0N4*P`& zy`yP>5^<1y_2Ev3CVbgpKoe z{?=4BY{CtZ?u#C^smjgi()C6hOq5(a-90}*^inQY~yLpf<=SruujtQq;qA*trdm- z^L{CF$e&9N0QTNq5z-V()wbl57~hT)^;7;QwPK~B7RL|Y#F$#@GJ?YA_PPIJ>oY@3 zh0^Ph9W^g2H`G%+p0j~_ew}PbwYMl)+VQaFb9$l9BD}y_DonEP zyS3+K%PnnRm7+p|2C?XZ&8eOTcYz_x+tr*qFpW3*iteRM9fUlh@0DDA`Y{+uREMwz zBvKG$QxNusP-mBG@^QMRG(YN;+BC5ViQpJB%IouINEKjtpM8Z2)tm6O^Uy*CP!oGS zEhNL8|2>+bY<-veAk+h7LUKh@3oDpmeS8b2Iq0x3>mWk1XMTkx%iu zsy8?h`aqZ1+XV9HwFJV#^rS@j;y7skzuux&bea+dK3rgc(a=IV{46{v9ENpr)iM{w z$eH~;0$MFZosPZ_>}w4wplr@w%5ZX1MuOR|9EPXFslyI+AIcHII15*5ff%P;mGN^r z(-v}A$MKllkU?k1&CWod<=jqK9Y%=-MzrU~+KRH&-FZ7%ydFU&lN~|}pA|3x%!#ur zF1%b_eLbh`;VJ~?mwWVxAjDYhrrG~R(|gBL{r>;suOv~Dz4zWTd&|hq&L*4eEfGTY z3Rwx+D=V{Plf6O+=NK8u2#2KK1rb;$1C z?7{q3D-tQ}|A-s9dB^v5AL?dqKD+HJRx>yGc%9*vSJ=c1$t*F^r0Wwd-bXOxFt&I6 z-|v1kHaqXK$k=z^9H_7S6#ZVdiczC`Jy`@2=OjSUpet54Y|lRMkko7(g@bpbKnTbG@*Iea0_ut#^{ywL*Pw;x#M0 zlJC*mT1VFp{3Yn3T@oCU84NmD9RP~v_?D9j`RSV(=ND(9xmBrer!Dt&hyJwE^ChD- zNguJft>W=#k6Y%WGox&&CkFxUdiqb_fbHBREi3yEwhwI`d3Vo*t-agCVHT(l6f>$~+In+T@w%4|?ASUh6W_Oqchnc0)6m+g z8UI3F1!K!phGz}xni&TO&$)-@|c{~P08bQw|)NMY|PwT^tbJX_7;0D3EF2OWPfu0fOa&bje9?X zxueF^WaQ@4#e<+AJ>jh+t&%@{r689aZ*&>foCnBSEE}>Jg*GMuhFyxa;-9JS?M^xD zXleNmRsd$bS?uSx2Ef|Ivtf7)?0n+Gt1oZ6%@=LD22V?jLo%w4gWxh(i-LAwHf=i4 zb-=o#{;|T3dWnNM`wz#yfmCD(s%xdc$4?BFns?~^GQ$VZ1Ule6z{fd@?u)HIdiDkf zzNbl0LtIV{EeS~8PEccIcce$RB!$|aVk5$IWNRlD)=ZLkX9s(Q!I$tfgwFb0(V_uB zx=Z9p%94~&+JlIwG;ah@#>85HobejiJ(ZsZ)Se}!%hpKre*1#g@%{Ukbq#!62EDcK4o7kmjcF4>2Ej&A01#+X1_jhY$ zalcXPPKe-I-pYxFgk= ziQ`{?c~IUQ;Vep;xgt_;I%}$XtFf^Jd4KMU4$J?4SX8JJ^X_k;aG2SV8-qVLAM!5S zU1ZcY#pOIeDDSx~pq&3M8sA02yFCECF<{>O7U&t!aBWo|^Yey=@(rt-9B@AQQQU)A zrE^GR{{PpPF&2O6=bE+rEm;zM8+3Z^x}sF`i)sB zEI3VS{rg@>7gN`}5h>I)r9FtxYlh@iy&g2j(R~7e4~WsbKIYEs7-7p>9>`I1Z7?+x$iv&x*U|CQD&I1u!h)ri`}(5DQEtmB!^= z>v&Y(8f$WQltqWgoZnjIz>Y$#4)jEd!3lDvp*4xZU;k3wD$~S@GTOB$ztDI`F{%?@ z$C<6bc{gi2(6i%X1LReFl$Nq*uRtIG2Qv)&n&vYRH#5T#Xc0$*_r-Zc!yqkkNp5J= z$b`9aJX_#*<)en@U&D@E7!__ImJcpV+#*Xtbc8b}zN?t-2IhAu-P{_bqBX2kngLm5 zMa_p3+Pw&mX(!KBZS1n$eTN6Hu34J8v>$BgVoL4=y%gGMu{IVkb#6a+kR*68vv3~& z0J{$fqG<=ra3+wQQ+tMDaSAGW6zGK-3dHllSZ!vef#KBa7{oD~8a?R*jOA=n( z_0ao__sQSje}Rs9FjZ-Xo++S_9%QGJpz%;M?7D>6yeC!r>rFJ#f!miDw6Zpsyh>|O zCMaF>00%L-IF;oS@2}O?(OLFz_of`0K|))l=!eU*Ndp|>o}f4-n9A}LcPuODzD~T+ zdMM@VC*xnsjf9Z}+!RVI@L*=m>`03NT^aR%GbnHq1Q3(X_1;J7iva+pWqW%pjoxC1 zbzabNNdlhtx1;z&`R9Ot;amy0Qf&4`G7F9pc5s4vj1|ZT_U*SrEoqAkXnzyfRm4hY$n(&jQX_M7T6Pa!g~`=`@&Oy*@T}Q4J-DMbCc7pC zkdoV*tf7e8UH~fcO`*X~b{Ne+ANX5|clhP}hMBZ@9+75IDh{(^5d!K!sc5NvI2(%5 zX1z*mq`Zf%P1BU-_ zEHPS~jBzp()%$kzv2ArtnA@p>Jlja5^aXPT@1;737$CI?_(g=nc|^xobB^!;-*zLK z{nmCz%})kXdtJy9H$gTKpSLgku&5lppat-lEK${d`^p~c=(qTJqv>96^iGS98RsMe zWrw|NXF5!akg_8@q3h>I54m8?#VmpnVpW||8jV4l7WQTw{G6{%Ge*}b^%6grOG2?{ zgGe{fN0TM&g`<7|=$FmVCtKb33x{{Qnc%0Anej?I>H%ib9C;v6z_{z*HpE`H%84|! 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