From b14c2e7a4e29e3665e72656c05f80861baaa8a6f Mon Sep 17 00:00:00 2001 From: Curro Campuzano Date: Mon, 29 Sep 2025 09:18:53 +0200 Subject: [PATCH 1/4] Add example custom simulator --- docs/examples/gallery/sbc.md | 61 +++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/docs/examples/gallery/sbc.md b/docs/examples/gallery/sbc.md index f7b66f4..23bab13 100644 --- a/docs/examples/gallery/sbc.md +++ b/docs/examples/gallery/sbc.md @@ -11,7 +11,7 @@ kernelspec: # Simulation based calibration -This example demonstrates how to use the `SBC` class for simulation-based calibration, supporting both PyMC and Bambi models. +This example demonstrates how to use the `SBC` class for simulation-based calibration, supporting PyMC, Bambi and Numpyro models. ```{jupyter-execute} @@ -66,6 +66,25 @@ plot_ecdf_pit(sbc.simulations, ); ``` +In certain scenarios, you might want to pass a custom function to the `SBC` class to generate the data. For instance, if you aim to evaluate the effect of model misspecification by generating data from a different model than the one used for model fitting. + +Next, we determine the impact of occasional large deviations (outliers) by drawing from a Laplace distribution instead of a normal distribution (which we use to fit the model). + +```{jupyter-execute} +def simulator(theta, seed, **kwargs): + rng = np.random.default_rng(seed) + # Here we use a Laplace distribution, but it could also be some mechanistic simulator + scale = sigma / np.sqrt(2) + return {"y": rng.laplace(theta, scale)} + +sbc = simuk.SBC(centered_eight, + num_simulations=100, + simulator=simulator, + sample_kwargs={'draws': 25, 'tune': 50}) + +sbc.run_simulations(); +``` + ::::: :::::{tab-item} Bambi @@ -103,6 +122,25 @@ We expect a uniform distribution, the gray envelope corresponds to the 94% credi plot_ecdf_pit(sbc.simulations) ``` +In certain scenarios, you might want to pass a custom function to the `SBC` class to generate the data. For instance, if you aim to evaluate the effect of model misspecification by generating data from a different model than the one used for model fitting. + +Next, we determine the impact of occasional large deviations (outliers) by drawing from a Laplace distribution instead of a normal distribution (which we use to fit the model). + +```{jupyter-execute} +def simulator(mu, seed, sigma, **kwargs): + rng = np.random.default_rng(seed) + # Here we use a Laplace distribution, but it could also be some mechanistic simulator + scale = sigma / np.sqrt(2) + return {"y": rng.laplace(mu, scale)} + +sbc = simuk.SBC(bmb_model, + num_simulations=100, + simulator=simulator, + sample_kwargs={'draws': 25, 'tune': 50}) + +sbc.run_simulations(); +``` + ::::: :::::{tab-item} Numpyro @@ -150,3 +188,24 @@ plot_ecdf_pit(sbc.simulations, visuals={"xlabel":False}, ); ``` + +In certain scenarios, you might want to pass a custom function to the `SBC` class to generate the data. For instance, if you aim to evaluate the effect of model misspecification by generating data from a different model than the one used for model fitting. + +Next, we determine the impact of occasional large deviations (outliers) by drawing from a Laplace distribution instead of a normal distribution (which we use to fit the model). + +```{jupyter-execute} +def simulator(theta, seed, **kwargs): + rng = np.random.default_rng(seed) + # Here we use a Laplace distribution, but it could also be some mechanistic simulator + scale = sigma / np.sqrt(2) + return {"y": rng.laplace(theta, scale)} + +sbc = simuk.SBC(nuts_kernel, + sample_kwargs={"num_warmup": 50, "num_samples": 75}, + num_simulations=100, + simulator=simulator, + data_dir={"J": 8, "sigma": sigma, "y": y} +) + +sbc.run_simulations(); +``` From 81bbae1c4083d9284071c46109f56d40db594153 Mon Sep 17 00:00:00 2001 From: Curro Campuzano Date: Sun, 5 Oct 2025 12:19:54 +0200 Subject: [PATCH 2/4] Add sections to SBC example --- docs/examples/gallery/sbc.md | 115 ++++++++++++++++++++++------------- 1 file changed, 72 insertions(+), 43 deletions(-) diff --git a/docs/examples/gallery/sbc.md b/docs/examples/gallery/sbc.md index 23bab13..12bd166 100644 --- a/docs/examples/gallery/sbc.md +++ b/docs/examples/gallery/sbc.md @@ -11,8 +11,6 @@ kernelspec: # Simulation based calibration -This example demonstrates how to use the `SBC` class for simulation-based calibration, supporting PyMC, Bambi and Numpyro models. - ```{jupyter-execute} from arviz_plots import plot_ecdf_pit, style @@ -21,11 +19,15 @@ import simuk style.use("arviz-variat") ``` +## Out-of-the-box SBC +This example demonstrates how to use the `SBC` class for simulation-based calibration, supporting PyMC, Bambi and Numpyro models. By default, the generative model implied by the probabilistic model is used. + + ::::::{tab-set} :class: full-width :::::{tab-item} PyMC -:sync: pymc +:sync: pymc_default First, define a PyMC model. In this example, we will use the centered eight schools model. @@ -66,29 +68,10 @@ plot_ecdf_pit(sbc.simulations, ); ``` -In certain scenarios, you might want to pass a custom function to the `SBC` class to generate the data. For instance, if you aim to evaluate the effect of model misspecification by generating data from a different model than the one used for model fitting. - -Next, we determine the impact of occasional large deviations (outliers) by drawing from a Laplace distribution instead of a normal distribution (which we use to fit the model). - -```{jupyter-execute} -def simulator(theta, seed, **kwargs): - rng = np.random.default_rng(seed) - # Here we use a Laplace distribution, but it could also be some mechanistic simulator - scale = sigma / np.sqrt(2) - return {"y": rng.laplace(theta, scale)} - -sbc = simuk.SBC(centered_eight, - num_simulations=100, - simulator=simulator, - sample_kwargs={'draws': 25, 'tune': 50}) - -sbc.run_simulations(); -``` - ::::: :::::{tab-item} Bambi -:sync: bambi +:sync: bambi_default Now, we define a Bambi Model. @@ -122,29 +105,10 @@ We expect a uniform distribution, the gray envelope corresponds to the 94% credi plot_ecdf_pit(sbc.simulations) ``` -In certain scenarios, you might want to pass a custom function to the `SBC` class to generate the data. For instance, if you aim to evaluate the effect of model misspecification by generating data from a different model than the one used for model fitting. - -Next, we determine the impact of occasional large deviations (outliers) by drawing from a Laplace distribution instead of a normal distribution (which we use to fit the model). - -```{jupyter-execute} -def simulator(mu, seed, sigma, **kwargs): - rng = np.random.default_rng(seed) - # Here we use a Laplace distribution, but it could also be some mechanistic simulator - scale = sigma / np.sqrt(2) - return {"y": rng.laplace(mu, scale)} - -sbc = simuk.SBC(bmb_model, - num_simulations=100, - simulator=simulator, - sample_kwargs={'draws': 25, 'tune': 50}) - -sbc.run_simulations(); -``` - ::::: :::::{tab-item} Numpyro -:sync: numpyro +:sync: numpyro_default We define a Numpyro Model, we use the centered eight schools model. @@ -189,6 +153,67 @@ plot_ecdf_pit(sbc.simulations, ); ``` +::::: + +:::::: + +## Custom simulator SBC + +::::::{tab-set} +:class: full-width + +:::::{tab-item} PyMC +:sync: pymc_custom + +In certain scenarios, you might want to pass a custom function to the `SBC` class to generate the data. For instance, if you aim to evaluate the effect of model misspecification by generating data from a different model than the one used for model fitting. + +Next, we determine the impact of occasional large deviations (outliers) by drawing from a Laplace distribution instead of a normal distribution (which we use to fit the model). + +```{jupyter-execute} +def simulator(theta, seed, **kwargs): + rng = np.random.default_rng(seed) + # Here we use a Laplace distribution, but it could also be some mechanistic simulator + scale = sigma / np.sqrt(2) + return {"y": rng.laplace(theta, scale)} + +sbc = simuk.SBC(centered_eight, + num_simulations=100, + simulator=simulator, + sample_kwargs={'draws': 25, 'tune': 50}) + +sbc.run_simulations(); +``` + +::::: + +:::::{tab-item} Bambi +:sync: bambi_custom + +In certain scenarios, you might want to pass a custom function to the `SBC` class to generate the data. For instance, if you aim to evaluate the effect of model misspecification by generating data from a different model than the one used for model fitting. + +Next, we determine the impact of occasional large deviations (outliers) by drawing from a Laplace distribution instead of a normal distribution (which we use to fit the model). + +```{jupyter-execute} +def simulator(mu, seed, sigma, **kwargs): + rng = np.random.default_rng(seed) + # Here we use a Laplace distribution, but it could also be some mechanistic simulator + scale = sigma / np.sqrt(2) + return {"y": rng.laplace(mu, scale)} + +sbc = simuk.SBC(bmb_model, + num_simulations=100, + simulator=simulator, + sample_kwargs={'draws': 25, 'tune': 50}) + +sbc.run_simulations(); +``` + +::::: + + +:::::{tab-item} Numpyro +:sync: numpyro_custom + In certain scenarios, you might want to pass a custom function to the `SBC` class to generate the data. For instance, if you aim to evaluate the effect of model misspecification by generating data from a different model than the one used for model fitting. Next, we determine the impact of occasional large deviations (outliers) by drawing from a Laplace distribution instead of a normal distribution (which we use to fit the model). @@ -209,3 +234,7 @@ sbc = simuk.SBC(nuts_kernel, sbc.run_simulations(); ``` + +::::: + +:::::: From de54bc3712b7e645e65fbb8cf704f00acc5444b3 Mon Sep 17 00:00:00 2001 From: Curro Campuzano Date: Sun, 5 Oct 2025 17:22:49 +0200 Subject: [PATCH 3/4] Add posterior SBC --- docs/examples.rst | 12 ++ docs/examples/gallery/posterior_sbc.md | 157 +++++++++++++++++++++++++ docs/examples/img/posterior_sbc.png | Bin 0 -> 110752 bytes simuk/sbc.py | 152 +++++++++++++++++------- simuk/tests/test_sbc.py | 123 ++++++++++++++++++- 5 files changed, 402 insertions(+), 42 deletions(-) create mode 100644 docs/examples/gallery/posterior_sbc.md create mode 100644 docs/examples/img/posterior_sbc.png diff --git a/docs/examples.rst b/docs/examples.rst index b813285..ad98a55 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -17,3 +17,15 @@ The gallery below presents examples that demonstrate the use of Simuk. +++ SBC + + .. grid-item-card:: + :link: ./examples/gallery/posterior_sbc.html + :text-align: center + :shadow: none + :class-card: example-gallery + + .. image:: examples/img/posterior_sbc.png + :alt: Posterior SBC + + +++ + Posterior SBC diff --git a/docs/examples/gallery/posterior_sbc.md b/docs/examples/gallery/posterior_sbc.md new file mode 100644 index 0000000..fa61ca4 --- /dev/null +++ b/docs/examples/gallery/posterior_sbc.md @@ -0,0 +1,157 @@ +--- +jupytext: + text_representation: + extension: .md + format_name: myst +kernelspec: + display_name: Python 3 + language: python + name: python3 +--- + +# Posterior simulation based calibration + +```{jupyter-execute} + +from arviz_plots import plot_ecdf_pit, style +import numpy as np +import simuk +style.use("arviz-variat") +``` + +This example demonstrates how to use the `SBC` class for posterior simulation-based calibration (SBC), supporting PyMC, Bambi and Numpyro models. In this version of SBC, we aim to validate the inference conditioned on the observed data and we restrict the analysis to space of parameters supported by the posterior distribution. + +::::::{tab-set} +:class: full-width + +:::::{tab-item} PyMC +:sync: pymc_default + +First, define a PyMC model and sample from the posterior distribution. In this example, we will use the centered eight schools model. + +```{jupyter-execute} + +import pymc as pm + +data = np.array([28.0, 8.0, -3.0, 7.0, -1.0, 1.0, 18.0, 12.0]) +sigma = np.array([15.0, 10.0, 16.0, 11.0, 9.0, 11.0, 10.0, 18.0]) + +with pm.Model() as centered_eight: + mu = pm.Normal('mu', mu=0, sigma=5) + tau = pm.HalfCauchy('tau', beta=5) + theta = pm.Normal('theta', mu=mu, sigma=tau, shape=8) + y_obs = pm.Normal('y', mu=theta, sigma=sigma, observed=data) + trace = pm.sample(1000) +``` + +Pass the model and the trace to the `SBC` class, set the number of simulations to 100, and run the simulations. Parameters will be drawn from the provided trace (which are from the posterior distribution). If the trace is not provided, the model will be sampled from the prior distribution (prior SBC). This process may take some time since the model runs multiple times (100 in this example). + +```{jupyter-execute} + +sbc = simuk.SBC(centered_eight, + num_simulations=100, + trace=trace, + sample_kwargs={'draws': 25, 'tune': 50}) + +sbc.run_simulations(); +``` + +We compare the posterior distribution (conditional on our observed data) and the posterior distribution conditional on the data and the simulated data using the ArviZ function `plot_ecdf_pit`. We expect a uniform distribution; the gray envelope corresponds to the 94% credible interval. + +```{jupyter-execute} + +plot_ecdf_pit(sbc.simulations, + visuals={"xlabel":False}, +); +``` + +::::: + +:::::{tab-item} Bambi +:sync: bambi_default + +Now, we define a Bambi Model and sample from the posterior distribution. + +```{jupyter-execute} + +import bambi as bmb +import pandas as pd + +x = np.random.normal(0, 1, 200) +y = 2 + np.random.normal(x, 1) +df = pd.DataFrame({"x": x, "y": y}) +bmb_model = bmb.Model("y ~ x", df) +trace = bmb_model.fit(num_samples=25, tune=50) +``` + +Pass the model and the trace to the `SBC` class, set the number of simulations to 100, and run the simulations. +Parameters will be drawn from the provided trace (which are from the posterior distribution). If the trace is not provided, the model will be sampled from the prior distribution (prior SBC). This process may take some time, as the model runs multiple times. + +```{jupyter-execute} + +sbc = simuk.SBC(bmb_model, + num_simulations=100, + trace=trace, + sample_kwargs={'draws': 25, 'tune': 50}) + +sbc.run_simulations(); +``` + +We compare the posterior distribution (conditional on our observed data) and the posterior distribution conditional on the data and the simulated data using the ArviZ function `plot_ecdf_pit`. We expect a uniform distribution; the gray envelope corresponds to the 94% credible interval. + + +```{jupyter-execute} +plot_ecdf_pit(sbc.simulations) +``` + +::::: + +:::::{tab-item} Numpyro +:sync: numpyro_default + +We define a Numpyro Model, we use the centered eight schools model. + +```{jupyter-execute} +import numpyro +import numpyro.distributions as dist +from jax import random +from numpyro.infer import MCMC, NUTS + +y = np.array([28.0, 8.0, -3.0, 7.0, -1.0, 1.0, 18.0, 12.0]) +sigma = np.array([15.0, 10.0, 16.0, 11.0, 9.0, 11.0, 10.0, 18.0]) + +def eight_schools_cauchy_prior(J, sigma, y=None): + mu = numpyro.sample("mu", dist.Normal(0, 5)) + tau = numpyro.sample("tau", dist.HalfCauchy(5)) + with numpyro.plate("J", J): + theta = numpyro.sample("theta", dist.Normal(mu, tau)) + numpyro.sample("y", dist.Normal(theta, sigma), obs=y) +``` + +We obtain samples from the posterior by running MCMC. +```{jupyter-execute} +# We use the NUTS sampler +nuts_kernel = NUTS(eight_schools_cauchy_prior) +mcmc = MCMC(nuts_kernel, num_warmup=500, num_samples=1000) +mcmc.run(random.PRNGKey(0), J=8, sigma=sigma, y=y) +``` + +Pass the model and the `mcmc` to the `SBC` class, set the number of simulations to 100, and run the simulations. For numpyro model, we pass in the ``data_dir`` parameter. + +```{jupyter-execute} +sbc = simuk.SBC(nuts_kernel, + sample_kwargs={"num_warmup": 50, "num_samples": 75}, + trace=mcmc, + num_simulations=100, + data_dir={"J": 8, "sigma": sigma, "y": y}, +) +sbc.run_simulations() +``` + +We compare the posterior distribution (conditional on our observed data) and the posterior distribution conditional on the data and the simulated data using the ArviZ function `plot_ecdf_pit`. We expect a uniform distribution; the gray envelope corresponds to the 94% credible interval. + +```{jupyter-execute} +plot_ecdf_pit(sbc.simulations, + visuals={"xlabel":False}, +); +``` diff --git a/docs/examples/img/posterior_sbc.png b/docs/examples/img/posterior_sbc.png new file mode 100644 index 0000000000000000000000000000000000000000..94fffae3140c5fbe024c0855a980700c369dddaf GIT binary patch literal 110752 zcmdq}XIN9)_6LkEI*N)20)q6dV53NrjwoQG+2}=(UIG#VgcbosihyFHBS@3pdsT|k zdkFyrDWQcDS|D)eV()#<`9Jr|{dnJ(=h^$55O&sDbB-~7WsI3%ZB6y#M>&o{5OnDk~!5_@BQJMm)0?$;y854SdQG=Ue)&5X9XG|3l%_?WPD(K+x@* z*B^SsE#i)RGPczhA&E$Sx%mE$-7OVq1zVeFYFp*B0Ey)8qw~|f_xyz}_Hw%@hx_ZU zUi;O+R87Z8Om<%3Phdbt3twgIy@zH$(cN)b!OTTtubi)>!p*8W^1(Qwk3=G&DZ#D%^TY1SoT3Qs>E9m=|H)i<8UFeCKQFG` zE$8_64G2>H-xt3w|F-+@ThRZ$z!U{${m%vd&x_7e|NnR~-c$+6dFH<#2jk+pRW(tA zcVt9&2lU#TtjBy#V1yu+Xwn(XlirH|U60v+R=|dk!b7$p4Yw!`5;wE*YGsX|{Wy0+ zA^j?;k*zjze0O|Hs)no+fqqyyt3Z(Hccp}q4*I*upM7cBkN>-HHUj>9B3>hH22QHN zXWxpP?VX?XSZ!is2!f!87*d5&e;1S@CYC()KRd}1;w<^!Ex`Qmi+cUWf&ab*{ht@s z8st2szxM}2x!Z277*)Gjl9y_TsFBpTckj#e^fZ#-H6iCSRH@usYwL6Oopn$9@#BY1;#CNuO7iVgCm(ZGj~yHu8sglO`}?ND za-?flU*pSs7s^PR9)4TyejmB_e$gfF%2Tp-$j@D8yp!kIVP9C6mz$fWTQmO%-+}OT zCCy0JjjZgmnR>gBnoReah}$hniVUxjQ-%|y$EffjV|QcHyl&m-S}oJ5inX7Y`nt$t zU8!DUQ`}bwyFC%U5(;FzmKJ%f#c!`=WUE4l+DdWnH)Fb%?^+aoJ@LSs^;j_PE$*VC zB0L47hjJxpKCADMuJL;-D=QKz7lNj4lE>mmXOg^;|3o;35{`%u3A?M7l`ko*_IEIm~JD>HFjM~SL< z2-nN`_d=SPjqh)krCZBSopB7{Yd`=D$i~+8#ilJE4aQ~ zHNKHc3>1{-Tkz0D^%M}SeP^tD!Rig_B!be(bzg}wk#r{G>c1f?6e;4j(}wr#@-i_n zG+fxW7noaB+HX0q@v6)7p1!1ilAn^PCZy9(X}3rz)~OPo_7KJ75xlf0aE%I5mdQv| z2Rr}p{l8($a?62pTtl!rW~h2b@(M!9W5uj;CdR(^=g&JsEjGkYUFgB0-U5r3`y=u4 zo>z^%mP%3-k3-P2`$`cXz+EM0>LmUX@hlzFA59YyHjC5aclTa$I^9a#X}69UKRC?5 zU;Yd+%;kiArVLSoves6+;S8tHg-f!Yp-I}lXf&=ozfdWI? z-X7Rw&xx((#3|i6(f~22=6B1zqRrS~-^2iiYC5g^#cO;$0sr={@NM_n z_4q!JD@BPnytP)vN6HYUq%yzVGGgskjY!P_nSj_4uU>8D>|4fF#g5ZK7;I+ZK-au= z(jBQBb%gKVkDrwJv6h&Mw-oWx@53G}6ZVA_wi_5b$sSCbHnZt|r1U-z%zJWsyKHsa zO~mhliUrf9vw1#C_I+f6-vRi&V;SxPjlO2wwVsuQQiqYZCi`n2tv|n0t0gZX(i69X z6Kyzz^^J_${n^&n*EPzFBOJfQ?o27|PaP(l+az=1_Dxom3J{)hq)IrpZ`JKq)nSR7 z6JTYuw0!0t$f55+Q0IN6#8h8eq4ePYY@Bng7jD4>FYUK3%{h*W@EQ~Fnb`6%ZOe-d3!3UkMIDg5hF6+*wY((Z_a z0~7U5Xx(-wF=4A(FkaT}E8;o;q7W_en9PQ_vi-l6Tbs8)b!%+QsBO2sv$M3iMklDE zFI~$T8_qad>$BS{3JM1KLFoWG(2$g=Ur!5R%ypF9)yT)X6aJH5t&@}H*xh>?Zu?TE z)Hh^D2CEErw+LF_)}AwZ^C}QLyEt37B*PL`~#q01>|4`!s2KuwmLKUANQmVQXif z0C1!~T~X2pRC9L&6BEt8zP?$UFTh%#dg~*QvOXNk_1pjQ1B{rcj7&7m%@b#@b+2s3 z%ekjTc>fW|ygVAe5S2juLIlW~k6#L6{PsM6^rI!5k$ zmd?}fbxW(sa83#hP&3X3ZRoJH|5La2>Q(^+&4rOF6u|bm z9MPpZyc=asY#9RKxoZf@JaVQz`XN%+*zM71wWn(zb^>5%x)Lcx>5iaQLOWNt$1Zjv zAz>ri`fmh)Q`3ti(`+%VfU0UigV-BhnV8xl27%PV!@MJR3WB<2He4;{tufC&acms< z`}vi706k@1@-t$Y^upCEjfWdkLmJ3) zLMN6lf&akt5Z<;l0^#Pyw^MM0C!YKi`Gi9iu-@sZ$9md~Z(K_$X1a42Lote4aNhz`govy^(L#v&wOJ z%7sIL6@mg%eU}+G#OrOwY9G@4ywSo%7&x}i?g~aXef}7Lw5L7O(;d+pfNbyqZ->iS;(dn8H{lf2Rybr4eF3DKM7}VVb*tOOiI6)9dzz-56cDEQp9oa^7hhX{Plk$U z=Aj3&dfmNS+`n8b->MDzLU$8}^E7MzIVq)$v`fY#fL+mvpifag^j@Ux8 zJ7?>3nVdYQFPTQe+dF2uo*$%ec{gTcWF#Si5mI)Yp9P5vHA(%K^%lNT{)QdjEd3AG zXaSU%?SsJ}{H)B|!NI}%BM!Jq$pw?GOLc3P@I3p!d3wDjcE^dSB0d-56@6rN^=7U! zqP5YjH@M%@-1zYEquf!q>ivy8EuQ_ApuQ>)=ERCFA7R|Hwkx(EZKe_}_B6+dY0{~6 z`wMlN2ip+`pTfBnMpt|%cH$?Z698sgVWSbF#hED8X&M*5Ms_X7#S7Lft?CV*jI^pLR1R}}NUEb&6I(_S-sjufm7l8ke$@h8QmLx!W-q3vATEa@t_feSDpQrWt zy8=K-di>fjlJ*(XW!cy6bRg0accK&VJ1!8E)C%*U^sTxBvi|^Nq4J*K3e%*HxZT_MjP_N`308Q>-9|2LY(oU38G}%iWUY@>KkQ@~8V&G%ySMD8O)%*J%>*?dKx$xJ_sfyTnCc=!Wt8qY* z&BWtLWtY!#)G{FBX>iSPBDwi(TKj$QC93;LIF46WMnbmHNgLm|H}i?*EegU4K$&Vic<{g{^T2QCqn}LH55wRgYS=$` z<_Ba@H=^LAm>vFcvZmAY&r5j@p1bORB`;p<=>bXbbyD4rsIKmF6gt-PU6hel)QSHV z+4Nw+PeW*;I?^=2Mqk4;yLg@kM<>efTd~N76GhrRo|iffhisM3qIMk8i3Ai zjeJa(0e*emg)@g}4dM-E(<0@1tFdaTbFqO5CV}e_Btzph&dEV%_s4~;G$4;AR!lgwQxPVvBDu^(=3M>Nw zh1d1l&@Ea~=l0rMyxrx|EZ)0M-t|&MKoC0}3|vK5x-1F=ASf&Vq=oAh#6*pkdv1%Z zdtF8eT=9P1Dd#X#&aGOmJQQtHdAk8h+X2~a8;JcG1gihJ$Rf5(WMPsHg8neeec$U9 zA>Su$mencDKL8KaM&BLZi z5#WGC__l1ZrH=TbM6v@3mLo*qbrj);;uL*IV-v8llG`Q0vPu6JiHqQ&j>g|LMUVSP zh3r-Xwx9vK7j$cY#VgCfRS@1!)bcvaxqJX$vqc}ME6nTQ{TYO9&|WE6Sl}uwyF?Hb zCe{^35@9Q)a;1@>h~$MrNmX?L^$m;N!dy>+_pDrBi{fTMT8jsH!8Fl#X~_3VM^~5o zN<1Z`Tya*>yL@^Hq;Lgy`eRpjud`rrF#Leiu_t{p^92wbzwDa08^?AmIOjBQTl}h* zhLnC$Fx~=M*DqEIG48!Q!EfWUx4lYS`&d_vA5wKz1@#uAQ!yEGsW2i&@9gkJBQh~v zN#Sp4yFFy&s)6naHF<|x8XefI{b-ERCyf)x@^@qOtu@@ zq~gB#?oIJbtl1-g78mXWWb)_l-CDx#Gn%Xg<3sfs0c);@`Vz}F(jxIK{SO!RHPj=x zm*%R$$3r1EXYDW)b_4O~t!13;!9H07;ny9&{SKG@hOiw@XstAtj-@x%*T+vffRORt zT*k%1ahff@IRtz*I>_Q5i`VAh$cF?U7m>_A>OE7I4 zS=+?p@o8lnmyE!ls1jj8RI}YAvh0Pcs;nFxYN3KKg)g$!m-l;@|Fhme<5KnJimPWi zBNOsK$#)@+4%JG*5XaGKVfY1T>w%@QilXTyaKmjI*8mzJJiV&oIpJpuaWL-}gtQ;U zN+Y=OL+(@U(c+GTs4`a|f{2FH*OD#Vm@-o-AfW)5fBGEJEvuS<13bJFhUcVP00Mu- zJxJFqsp)D6pbL5?3>K0QPw=)jFgAAdOoSsGKcAJ?sUpC@z+h`PznK{U(-Z|@Ih<{+ z`1_Ly`^y9;&)wJ3U@NtxnryOFsjEH<3k&VPz~fmwHBa7nNdtnwahDyKfCqyu z;*=0(54J9ftI0B5o|?ejN&xVHYFK>S-wUGWoRI1d`3f*4RT?qgd3JB@i#cSXZAj@;07OMeeF?e-& z4d{4+KBh7njz-|}S}I%9LCTLhU{`_+9Ac31#R!zkBD2zm*xELgY&(*qLtJ)lQ(cyL2tPc=bt4*QM@gY&o#8v%Sc;KC0{R4@7M zcO687F#ULJWf6ihzM>lblvPh(!Gm2_Q0jznKkf4ZQ2Z76W=_OCTqPizV^{y$KNRfX z|2ueK4=qlZ-Wu}&i?|2Fi9KXWhd~D`KiFXM=R4GY@H!^c z24!Yu9#VJUp(Wa(6A#G!a?sy*_X&mwa8nDK9FKU68?j@@TQlPE9{T>?FiyspJ zCQ8?I@$5D5e1Y#9e?-ee1(wQ%GE*6jrdyRmCEkk}!P1Cvc}x-94r1p9*)7K0@D4^> z4Marv^8#bEh+!HPRIdj9x~34*^dm|zc3jZEb+zZ#6(jO1b$NaUq=YMph`+qpBfQd+ zL$6VGR98J{5jI{%0F<)m2c}KH>NUb=(c(BFqUkwsB@QBe{%j=CDG1q*g1vvlawf#; z_2Q`H7BDCjBM;4=(x#>+BJdijL}uxg59oEN!lLQFz}0M|bQnYFc@4{gqk(r5*sx7v<6>cW>V6N&6mQBioU{XbfTj_ql=3f$8kkg zo)7RE-vJ-WH#r>ynX-~GvPV^at7f}ssAZ?_fN)SX3+gW@v`68sApW9Lx<(#JBB$ckSIHWz~_g9OT@A>GTje;W3b9^1gOTt~MpT1qRDrm`bKCVasOsV_HDr z!vjL;qRViMQ(+MHqi21yGk_~GHk-y)yYj+E1`e4%*gPL!c`5xgl&Olzl+BbU;t&>3 zKY-hYYEuOfJ`R;w-13M01wV2gK7eP>44CKbT+7VY=P%_|UnK+I+q)9T1-ZBD)KHS_ zG7t{wWi?BVc-U7$AM8#fDjw`~rNdH*OXk^MIXOAgzHu2kaAa8XEx`G#Q3raLyH$N6 z`;#JRS-F*8BPLXT&QAdY*cX3J#Pc>R;CfaRLDjO3*Wkhgd1#vnxj>@SlCAE zyQko_`LrcMNdR-I;oa~FvKQ#L^erwf)&t`OBD03FS@8XVu>uBmV6wk~I|#5Y2cCYB zY8dJoHDosSeXVF+`__xYTASeF&_WyYi2P*e}-vT1% zzb~9W{Ob(Ezx)5ad-$)VdH6~Hue#V_U$hkl6a32WZ*WW`wL}B==)nVFK-b?H_IF&m zbcrf2u?#VhaQ=KYA03o51^_z#v94~163E}@Yn*_o-vxP3r9cZc725iAcL_tM3rkBs zY!W6CHJlj@sBe7u@S(T8y}dpHkb{7e4^HSPC0=te|J4GLT2sz_`5v&&Iktg?Y<3dv zKf&QhbCdSU{LG6NFC?U;rB^H{pnBe$xN5{i?d29Rn*vc6027phkj2e%j--I#B`UfT z$Gn@S)XtX!)>D*`7{MhcRXo+y_?g*m1g2M;CvATAN(dE3Pg_7>QJd>Rp zZ007heKMbxoe{*E%=a&-drlEQ;a1cUCs2SwVQ&qv&ST_q(Err02Tkywyr|n@s=>gr zK06}wU0Adr)Eo(l7$%uhHNR4=p2N%=#76PSkFE4C&MKgh{poLC+%)$$q+BhNTW?HZnnM^92k@f~T9hUe0mn5A17! z26T$z>w;5C1Rd0|Ot$zN{6dX$s?r~aQQQz_9Xw|M9b-62q8Ii-LBjnUcuILq?%=H4 z8a-ePESL0*1-Qc{8inNa`ack=F5da|CL-YwuQaBbLv z|D-lkz2A9NQ2Q)1Gqb+*>hQoRNGKsA@rvfz{XN$=CS^DCM>|ED@;%qB+{C-x!3R^S zhoAjX`4Vbkj{h!D%#5|7gqltSkGalN!ckkY9Tvj$cqI;u3HAA*>K)FEodNb?mp4-%r z(92{uZQA>#3wHxmAWTna*-P_f{d5JPuCvHM)yv#8m>%Zrmy@URX-T)sIgVc3w^w8T z^F0^{oYTBPpZdoOEYyL2%mG%qept?P?dfP4B5~PETbU_0JW>)03#B(=aS3;KbCU!` z`ZY-cbK<6J1n3}~&i$d@9;|ifA3|nA$uGkztQ+ivgemNkOarsdc%53 za$n+pzV^!T3>z!!QJIP>#N+klq7}!R%0OWS8duGS0}^#+`l{&s3p2`+u~+SJIeDzo zZ6QO82BQ5rCjKr+#wLjee55^-N%(TNO1tuaV3~#63@E3Ee=<+R_l=;!!0tEzrZ)co zx_BkV`a4~H`74s5%4Jo1MM{Xwt9N`F>^bpHc}zj7J-w)td0Xo?P&^@(iv9zvnkt^G z(DHDB0Px5>`_m~QpS-&k<1#ae6wMuf{yZ&>e1=A&!S9uCt4@Uh97#>qH#UBM<@qTf zibTdH>pn3{i=3F|HR{llefH;;EOM?pLyO964(^-gbccyDK*%hc_|H?8j?{X|Ui8}B zVwqeGq4Z`fOV#~t5OV6zk0^a(gJSdzxlCd?rV+-ZAQ3Wp!@d9 z@8{eC<90nc9KZHF=X3`8nI1AN(+aUQ*qMz{4uYVvMWImO(TaJEG@cwo?=G{?gZc*Q z#{SS|SWg4`p)uuDc_jtqJFWh{0y1CyHR|j9W;s?gLUnrV?8l|6Pg9DT@MoNI{l%(5 z$&zR$DH=|l{dqeu>jE|3am?yfNy+yw9)*iu~r zV+wXtv4gXcK8u=E%3?R<0Z7=5m#kl-dq( zs?4J>F5auh`J#p=y*jtm|7jks4fbaSV^C;&MdF9I;Y`@pUPD3C1nI!@({E1FO@D z;N&Y_bbtnl5X;wfX7~W^~EB6 zXsB;Kb7soQ*N$HUU7H@LHX`%X%1UkaWYSyMd~?eZ*FC0uMm3(>brcjako=fhrfgbv zEy_V>^~QnX(_A-_4ROFaPy_20d6&94rRvw%*ciw#Gu{(ivhQegl5BFZMKLBWQ~O9F zay|29#Saa946Y5&R5jCAZh!hFn@YN`xz}uGJmsLW<#+5UrqNe40g$$pPKtWHZ0UVE zA-M)S%<6fw^dwzL6lmNael z!SeHu;cgz~#wU&G%!N$`Zz&7u1Q~)gBSQ81;>-i7FM{* zntXD{D%`Sf%*FAjh0&~t737rCgz(P1wm4A{wKHWi$&@$HAw#7t3GxFE$|p#iQbgz_ zw{NsB&#@|vKBC1q1JzTEm{6p!Kbf00K&^c58I|$~my)mi60S-buu`lVmk@d5GOH5h z6!T4eyo{7Z&6;IWq&%=djkh%W-OFq)^Y=454QqXDES*)pe zyto=-R+8Jc6EJt3KEB#GH92>n=>&UPhPp+qOzw54-uY&^EJx6HBO;(Z8CrDgVhwiC z&v}>vBvKB(3wCx>g=IkO94*x8CvdGaA0OlqcZf|vxqQms(DLJZ^FztEqo$92!*6U9 zqrVmvNGVCaIbUUD!-C7E^9d`Y>G|9zj4GgUt}C?+OG4GL@>32l55*4OKG%2_s<+_? zn%ktC(#Yq)T%^txDEe$mZ^>t5d>zzMQ94L;Tl%AbSxt3y9IzebK|AOuzwD0w+^rF# zGHc12$!0Qs4&N#JrAx!<&d{QXX2h`M#H!dj%4T_*{gF103PE?c`q3v}Bg&;m&Y)b? z4we=;cXwVEtu@!&87{EU2sn$nPl4$P(wVHN>{ETiWFqEweEK}t)%P(ksVVG#DwkKP zBu9oX^Yx6JfY_aeA^{;Pwru;LlXyZK6Nv?$l)4W`w@YhjteM-Zyx_c=XS0LP;|$4S z&0;Ht;PUFj)yAKE$EcRbb3~J740^HrrB)k|s&_A(-Cmg7B23iPWwG@`%7|nyT}Q8{B9NK)fQqfQ6w}G2^Lob2 zrr3*54H#n7%*wD+{ow_o3enBRc~92mpO9P_i?>qxy!5H&OH@_hi!!dtO3l0nuKuA< zPHO{Z0As5{4C?wihm;SHF|)5^6=vdSvM4gl>t&y@8kTLQdusKU&l{06$}4Z0$EFXP zSC9Nv?#}_K9Z>S3BImx?L^uu!L@G$8UJkezc;DguiPx&i(*9{UR4X@|=Z(3Vz>f8o zc$!hK1)|9e2Hmcps$k#4`*7lofO=uldk$8p`Nrk6F`(;#!*d6A2siNcdbL3;8`6;T z?$|?b;x_>CqZO{!n}Wnp7OmUBw!XFt_$g2R;zQ)I;3G@X(b3Q2m__w^6#fESLGJ#! zArlv!QAM0bLHEzmXyW1m0>3Sm5`duAz`9j{kgyaCG|AB@D=2J2eh{A50cqB|xajb0*M^#sEU0%J3dnN>cJL)L4O36cht55cf0bHD z_8f->P9sn)ft!tu{t&}E;z6Ece`XB*V@Cdy9KU~GrPT<^)S>t3ezH#A7vyrRxNq$9 zjiAC4ga43c<5$M-9e7Sa5?%)~DhVC_2|WX{G0*8!mHp@+Q`I}u>-8ZT2hPo5hBWBz zK}m5GAAk>P$!Bl2oxB`Qs)};#nW`<-2`c(MarLYPKo$lM1QJblaQ|Jsg-9EiLXz~p zo%k%ha9`6pemrZ~MZrH>CuQ@-V(%%6<7O+1{`3%$A7ua*KLW@4nUOk+!mOM+8!z~K z-k(kmSx<#oefFpI&1Ew#=AoVoC)vZd{n)rN+%^N2j|pgxMp(4}oo}6$H-Z*6v(t3P z%9XejY7!RqJBq#HG`a1;Gi%o73OxsY>4s*wahfJUwI^@3dHDU6c|(RHPx22;Ep%=o zb7-Nt7AHs0uY_k-Qxv&`&Vky)?pXgfz}}JnuzW^A0H#lA#+g%6Tq}^7d=uwyoki(| zqo)juS_Z?E{U$D-%6>T?y5bs`ls8r(xm#__i=HCKzCa3WW0zexxTSQoxFkV_Q{_`S`DSsSnF+k9ZJF-{(2kZ=>q>10%b5FTCl#%-Za(0jXS{6*Jet_yk zHMqJ@SX+D6;+B2hqn};H0O1La|>*#~j zY)XuWC6}4Exc-P$GDYYw_{Ytz+HWBSqpvx&c_na0C^9=j7E$@- z)j!!W{V8s|vP6mDIHu?zk6IeSTn~2M0FH9Z;0i!jm=4a((xjjOrCcO)KuMn_$rBkC za;F&>EXC-}HwETH;7BE&qJ16ybX-1Y{6J(0)DFDURb>mN`>&mC0&m7<(%h;#UOXey zd@b`u2i<2@f1W>LcAwX(uM;&1iL(VE$*kMq;j>fY$X}p3g89vicB7)9mr%XveE6t; zE-B)ZX=r4oar7C%RqodS(jRVlj_*lcpPlCmS&mwrEYxSa17S43e|PIY-P45bV@HTE z)>MmzFZDg|R2{<2(T-g%=D3bCk)tV-Q!@boxZJH!9t{KHt~h~gsL;8I4-OBH7jziE z%Qh>|w|)JrMckjI^6^|wQu(VDRb+lbbTp8i%C>U1)D-OLSfM0({-+$rk0rNF^uMF0 z960Yx15K@Z^C0uN5hf$YZU;(DDj8?b(?D|{Kh=jy_gVC!pFOLllGPTeoR(mS%?8uS zQ!NpUT|74)n1jlc*h9k>hgdZq4!aiDG|R^YBovFG~C=R`J^&jM+|PR%`TUXNeM z?Vc6NtMe0yuc$g+ME88NfqG~+Q%Bk7-E%^6XfPgVW4ArGf_!bg02h|ma>>mlw@yMr z&tCKJz57%I)Jhc>TP6#fQA%QLY}DB;QO+BfLxl=1&VutayfS0(kCL93X%K2Upku~` z*|*p=%x}sbuN<84b6Rru_LvbSDc?3sg{kI1Pm~p4exB1U{ji+FHjFMf5~jaGgA=6hxk?XQ5ZiZN+`8x zIr041Maf)79>utULSRUD+da`+G-Hm>k)-}?BX>!4$PL1%Q7jm=R+=n|a+h2g5HM0m z>U^W)p^iBMB?<96aBSRmNEy$tpnuo^56_@TRHIpLPjl~o5^v00^(kS9M;v<(Qge*^ z$)+z)>}sU+3hwSlqRSCI!dQj4hDP+{m%a5LJx8=6sUY@rv?7Q9&6L8XCe`(Uu!ol^ zUk!bncY%^PORSDi4h~Gk2Pua7%N<2vK{rX2C29bmyao`$DnbvRF>F{}dif;I*sDp^ zc9-~l81>^dL9j8i$F@?xwL$JnHnZi`@x=feBl~%>D|?`asXgr-yp@8+%=@5$JQk9?iM)X2u$)B#mh^EF>Lk z=BUpYuW{gLA#E0&qVItlVC?@}IPWUreBlL)*W9>$j9iG>MkCQ9=tRl_BJe@1TTCwF zd+EvpfTv@)mtHd9p7^^HqyrOXhskfZ;?T#vhbq5B>>f;^4ywPF z)uF3?(sE%i2i#@zD^M=FfuaHXfqPD`q0aUOsP)%yB%l){98TYiPfXM$K4^v9ih`Hv zQ}zDP7oVaS)@;m-ANSLXkkov>`FM*keR#>2XSTU#Mb#GnDg#99Wm!udgUN%Nz|%Ri zaRJytD(wsK6lCmyp^?$O*o&p~(UU++LA0my!$+k!a5}z?16(XatLHVUlfVWBB`c|1 zEZ|BBb_n5}U-`7innWA&SEYVmoU)hubAnUVmx!v2(=i=bc(`(DxZnottQ{4OiBlbx zoJn2EZA}7D4Slo8;59P_A1rfIhpSe-N{9E~zerx9H&(B)XIq_Q z&UJbM8%qC_Gc|6f*BH0#gt0=)whXNxvAD(3fMeR!Oy^&VF7))}u$i{_OxB9ph_RZ& z;&Zw)$LF}LDWK+FV~;I-A{&;kOY6MCsP&fst8f)wLnb z$?DcumRDnkz(@&HKcdOkgC~F(0y?4FPkQO!momhC$Vm}tI<_{; zL^1c6E3FEzhZEK_mU9{tSvGBUei;Mz`vqp`wiZXC2G+VA^JO_&;fGXxHu*hxk-Xwz z8fRWu%?x42_+Ooh8tGZ;I(mneD?2<_LYtOJ*n!n4Eb>c|qub4o<8!ALw>m`q_dHcP z$*dM~1Tp)DWuQqPHpigM&G{X1m2N=)g8`H{kuYN$^IGR8Pa4J~xahJZSHX6k%^z&2 z`~**z&9%Z~8Th{RB1$Ed3*CrSwcFK^fmh3&y6oDZr#VqBfzL8ES4zU3-2ck-$5dY~ zD#3?*ML;g^q6|=XeP|0{6s*8eCj>gyTff0Hi-hF4d1ZSLAj)Ux_1He@g5eG1W!b>* zkHd6+9eRGqjL7%z-(Rk0v;=FDTjVgtx)mJxCA?YrOu*jX1X)4nhuPNZR7>o>*FE#D zj*jExIM8Akhu(Sb)OnwC1wN6n-1nz81ETg z7Vh760&Ws`z&rQusSO1Q{js*TR`-#8SU*2+w@G2i#ARtnlVv}t=rX|{_}BCK;O=!^ zo=g4%Qy%0H=~;_HgLu&5Z(_ba3ao;s8p@@JiQI1!>~vXE3P&mIprngCq1!fp*(HF< z@}qi;U~mV56g13RSS7`tD;)a4pZ^%5)rP=dil;1|H|A+hNQ}vN_;H`!e(^tUp-QlO zg`SM(*XgB!9Udx3)EjnwDF=I?r*?OUPsU_F5wK-i`5X{?mZ~M?;J4}1ps}hDs_no+ z1k(hSf!zgw9a!V|J|E4knM{5Y#6|Hkb>Bc*y5fRyk(Z2u`H*)i>nXK*P;h|*dE-Yl zVa5lqnpi8wb**5KsAwoC*emWX@@VGZ7*wC3QVLvvf^U=Ta4~9@G2>bvh>Dsj!~PL^ zRX_!Gmvw$SFM)rE{1BWQ*_}1F=V7yi{1#E}s8_0`^^^xRBH}*_)XQIX$-ZV~qOO&f z4hXkj#t`m$=%|$4m=#t`Mcj}0Bd_?_;~;_bu7}I;C5713xIrP@l^Zw*GA+!je$;zo zWe#MRvS~nJ&$+)I-yMDVMxOciYFd!A{M-Pb8%1XK14$egR0Id!mx#ZYJt4{w729dj zWnjEcN<}S&SvVa-m4Q5~MbF_=sR6qJ5^q9)&gDx<}^%K@~GV`E`f!n)y3#{p{ zO-#v&!2rQk(DyTKy7+@$uZ4Q^&|wJjN2WQkB!&Ai1L4qvFEDP+AH2QsGv2W41$EHU z$k4>qw^P6%U{IYzvp#9R9wNHYY(FC!fK!dnuLaXIeQC5^0!-ynZ!~IVCl1z#$yyV` zrCuOB$c(?5_lSUw$Hd2TZQ#4rdopf-8&R%D>m7z^6@9y!SRF7GOPz3F!176;$oxGI zaT_M#cILId)2A}t(#u9nq6dYBxwzI_EGcdmy?7#P*w-o`GV+GoW%ZeXjOTo{pOT09 z6@_Vqp|Ua0WM3E1){DRLT?uJ^g{$06OG>&1nD4G-juY~!ofpMk%K|p&C*n&OuNkQ> z#%!3u%{Wm}Fk|*Jgha0|?#tEg*wb1bqTCN^wh9vUdi~Wp1-n(goR+o(C1Xb=;-i?J zf#E~ecohz}GAsF}YbG(#PF{5+nxm_GT=A0@*TL0yjLWP`rk&(;VigFrRYfnH!9dH4 ztv@u`bk^D523F5&`pia>ur;SCq3&4FAA0&EDmC?7{9g0T950LNPXRjRn<1fvO6mi* zCH)^Vy|UY|8W-*N*SBO4qMRNQ78(^^(H=CzgE@jC%*NVUAx2Um_<(cO?=RUVFK#-h zRd5`OkY;oJ_1%D!qUC!y0`~J{K6hNfaoxIqlfjE(pndR1FtHtXH`Pl3wB&5yrs`=T zlSFh32lf=wq0}l&TZel7$-`2u2wy(+>hLh-hef&B-?W=M^OQFNl0O^&`rO{oo8iR> zdTm!O2db57Xr=Dpe-u{^qWR4ClwQdu8>f4Kr4AX*q_27f+Hd(s^cb6m&l{Sn+EpD{ z1PSqO^YvNK`3lZ=WPz^>iwL|ZFF?}PN+}he*`(_)!gL2akvqrOjtbGwe@A_vaN z_374n-reNLEVaq1ef*h;gNT5c(*D`AL`UzBv3ueN~YioA_&; z;OB|%Nk`nH)671kVa-VvMxtMUeU%E)zp=5b<`F^lHzB%{c zwSRIBB_kh!+-45kqXjcZ9lj1(J@p$A;?`0d#qgzP`1OqKlS`|8OhEEs3h4FJzsXT7 zjK5yeBE0#ycq^jZLnbFq-fg^&N50@g!dk*Y*RC{|3Yhf~Yz$?pmO(n7TarWZFPPWh z{RSRmrL{7Pl2j%SNcjOjnPfwT9KcS&58iGfhCo2u*9iKq(8cWS)Uu>jd|`Sl*2gI^fD)E0a3L3u>juyj)jlb`T0o&D=6Sq;s1 zjv6e#c!DyZ2FIAd2>l3Y`H+WKvmoG zQ(g+cO@G_!OP^ZkVG;g1@_ab71V+~S{(PA|?Zh_4*W3gSa-whEsbGCMV#@^a*3IcD zzyc2*gndJk4a~3Dj_XJD+^s~H8t*vRnLj`;`?y=f9qX6&wpOwV2m2qvX$3Hm^f~p0 zeLA6=<`iaGRS-w-UCO)_ygO5K(40nRxpeB(b^8p)y~~#`e>r3_E~qEEO9EXdI7(FM z3Jd`cc3(8$+5i+TEbCKLIA-JTrbjA&$auYlF!p_JA*jRtGFVsl5*WgEb}p360UxZ#x>Le0>f0uG zy9RXQmpTq!EP?S;2s(Yr^{MXi*l2MZ(kI2=Y75a%Ols$sr~*eSimR(Hn{{w~=j2?a zZ2{{G_aJj$fU~+1tQ&uWA*kU;Pv^sp-oZc52LrQqGfK(k)kpqfr-r)EM2*#p{#n{* z2i*`qsFKa~X*{xbiMVg+2B<6&xIo3l#S-%mJ}2=df$0O-K5&SWFz|@9PH%d=*hmkB zwZ#?DyoMlW-+Eb;E=#_XR(a(MAlw~9X|N)c(6Lgv*c@xjlU6Lbpj7-#HJFkirI z0259P&CQ~FSp^4dUeKP^mPHe7Cb)-$!+?Msb|||EK{mJQD;0jvvz`|eEDBy2MvKY* z_=EFh0`X0+%Qms=H2!gaF3R-B{{G&sX#%(Bk8qvDQv&^8nQh7p`xp%aUoBpv*5=}b zfg~W1pXM&?9MEK!IVpH8Ym1Z?n!++s8qujTxUjHL;cnp2ba?509ZuIk)pd=}Z{L z4OtN0$y?)a_b61qWaZGI=W$6;E0s!cu+xXzFT&3-W_8l;>_qpeUleA;{Gwtf_<8|@ z244$cxgmC?>Fh?XaaEz`y!zrD_hH+D_i9z5b}W?8JGbX`Tfe|GX&uGFr^G>a0t(3B z;X=#1gV)c?27Jf-%({gQql8#qFN5=ROk?+5d-{1W>7;E+l8rbl9X74U zcOz6Jkgq&j05P9GsgjFh6?nyC+{KnwmFPMs1STF9;75v>_;jrpRhbf}mhvJXr}DG= z8W>cy?5jN?8-D^wkF#8>a0Io^%g>Hx@jG25xVuj7do3Wc$5<>hkdKKEs$ zG;Ds{F4U~#*KtTyM~P<$Pv#uRCuexc`NYAejVTtukq3IcDEnMA`2Gj1o7hZN3Kd#F zCu-J_#ax&ZV()nTr-MzSnew1}QDIvkKBwsEy?)jcgZtwPQ=jN)ps$sej=BG3gi8Sf ziPnZlSUz02hnU}iZ|Cbjw_|06vHrmeQ{dU!yvnjI=?^3vldE^h{9Wn<)e>Hz!qJ^$wKg0`mE}>2)}BO^A5T zqRwClI@Z`1S60AA3K9`@w5Thr0Q3C!Sd_#(}SYPBn4@9oYiTkdFc!l?C5l z03TiYwtG`!+_ptQQUMbEn$yZx`q}S$QyYE)QJd<>ozm0TV3o{?F6#Cb1XGsUQaSTU zG2pu~kULH8+zS=TwjUIO!+FJQxv*{tvThf*V&zIBK$6WJQdD}j9LZ(hk3p4XWzrwO zO^PGY4v^4W56v(dWlvVtfdnNiuI?2-FX#0U&{YIO59h?h#NN=XMQ|&`bUYd|G&SvV z3RMcIZ~z}@_y!RlbBj&bL1}AC;0o$VR`5>yr=c$#b_~>Aad`PL=IeMhe(nC-j)n)< zP4|FFO@nw?(U9WO-C$VFw;OFE^kx`SS=Ca&vHT`=TVPe(I|H$q|Z+*Iw21<<=$>& zEie6X;iubXW4e%i=a2#Bw`8EydbJQ}NDSe7d zmwx$Wz5T(U-|=HA2{>8`D5Ti%nIPyt$H8}p0p#T=b3ap|)0UM+N_X(1a4=pU;!J^^ ze$EHdh)spnG$c)9H)49Y9xxn>qONWNhmJATNaNf%ZCLzyp zANO>1lfo2{7AtvJN`ND&)`y$R<&)#-0Qw5?)Y5hheVX%cK?ED|88ml+GlDQ_ZCh0B z{~|U!W=EmyXj1uz95d?zY`ODVTr9{O#k=L`dN5U6xO6(DRmpAs;qvM5hKuT;GShen zmUQkBpOz{JOxch5vwN1_<$A1K6SW*&<9!?w)%!1x#_LNQ3HDt4^etCkwkTmHz4rZM zt$3%Ml9>VujPFv0*kQZnb3OkbX5$VlO}0g@#7tZ)&F=bg#_-%>#Jy8>Y?*YLPin2^ zH&W;i#?S4!OnyId=`022>Kr3@g>Rv)~XbPO-(+omFH675RjuD&0cNHrAC;CRelFC!ID>G6H zYO^f00Szp|-he@6Z*4nmKbbNZ4R5B$ZXc^Tq*2%RGIO7bJC-93OC3s-|a5> zLojYomW++;fW@`jR-;N&Hh?ABr{T4kZtXL}riiGh0jIDJADuT&Hib5NxUf?>11UK4 z6XWZ+3wG%qXO&DpYqUP@ny*9bC-hN+jY~-h(qC{I`Cd~)kaBbhR;p4*Poit+*qTdn z=YH;8;ZtUozs#R3_TI~h`h$$AcGkUv-*YYj@s;!doJ`TWdzS%pBJX^)p;&k)h4^;DKAR^+i~RsUlgnZ%^s z#oW7me%Sax5)ut}YZEPt$(0rtpYr_Fcr^lar!Elu$vc@pkPVHSpX1pEBtkH5<6^Zg zE!Wqlzzu(|7Pmg48_^2p0V@0Am*0UeO{$7F*Sq$=aR=|sE#ND~3`li6mK^PUgPJcp ziAb|E3@sZKE}8h8gW?ifr>(;JfCZA5eInlyGjssfu-gyIlULo0QPK%T5-_|O&u<<5)cuuV5Jt~N$0rYTK zb6=YLS!y&&%V`4i{rFoX2QT4qLJNgK*nXUn(OS9 zUMkEp{L_R>9F9glWq13c>SlBCE2B#q>$_M;pOpWKZ9 z*b?vT)*%1?A?>Z>nr{EM;UR(;hzODb)&&@pN~a=Nq;%H>NQ=PcXbX|F=@2BOyGE## zf`Uj4gn2gO}g$^?N<{^SYnse&!!I80_2`?>dk7aZHq0OyyifC;Jsw zL%XlLY|+gJM{4mmLUzKcaq8-biHMk#zt?$g@3H{+fW38I4=?+Hxp>#h?!+&D@K558 z8|e&O8M#t-eLt$jLTJgH^+u%Z7}MYPAT&Ficz8%@0}cKPaQO0Nd;75Q*LsL@JU`A( zbBd22o~J{Nx#>jKk1KZwnOmq7U#t9O>*eHdTvM~9aOy>Uh>(UgJ&F*PByIboMC$Th z-d1(oLsIN=q-ojUH_xt0j%d!3ihJ8pA*=^O3xai?VP{T=#%~Yy#D7r0LqrLX6O+ic zOU-^9jeCrVx+$dWPABidY}H|UR15wPZ-CRJr;=jrRcknbBLbyTxB0}v=umR3gQT5? z-R}V_Fz9yYhyv@=dWlstHP-bGa!B`h=Bew$k)|pEk05{v`*ciNtqjT5iRRnmdOwzW zAswV{%C2g=P|eB2_>_1J&iQ?LnZ|Uaw7y5YUOaVYryo&J!3$?6)ve@=QnXKGUU>Q? z*CmU(R;4z-2JTZ&SLmcnZL5vXVv+B-g)%w)BgUUc>0GUFoGxLob(sR{EQ%qZm0 z@gTpe#@j*R9pX-1c@t$yJ+3=kIl!)@j$XgO3EM^O}Zx;u-SP(0aM5Luq6K08l%f{gFXdvz;a)em z$?jwN8|F_zQv&D{@&^UYYYayo-|+b$ltDtSp^)n>O}sMLN{g#|DW3=KE$pS95)sJ& zcsa}X0! z*~ElT6_;Jh5BLcU%053_v<($e@3PbNth{^z(k~BD0Cl53Qt%PONocpUd6JM5w$JC@ z>+}zou2(*_tIdqWR{&JagBg|NabWnhG1GyhoR=Evy>Dv`ysE{qY*w8R01ZHNE%JR>8cPTJt>r}=mLW|{I(Dy!tL6T-5Cr%l%xsKG+hKOE{eO^90oYY`CT4LsodAr!y90qqHkIow_j8qGdxScyD zhf=u$vEi5M_%FU6?QvfWVrCTZadQ8)U{>p9r8>s%y*9PzttDdk3478_K0u*ou8=-B zZBEcg>`rgp%reSgU-)zwdlCP=TIQw2nVUJQ{HO?)@6#>!a$DaY!rg`A*nM5TvX_y~ z9*cW1sdZiqHUZ>J(n;Ua&ZujA>x(A#FBVzxLHk$Rp*y{-MIj|&_-C_sEXd!d;vEXj zcnJ*^GBVo;NwI*Bu4%l;Ny=e#M`agev)S#PTe-)CVn1%3gu%2_X%AK6TR(J*i_ME> z#n02JkfAMfmyz`M=e@B`J$!$=xry*8+$#DW{y_cq^OefABg0qJP{J?JgVk=YTy{44 zdO5;%c0yUyTB)9{NBkR@Hj8^ow|}KoUpmYEu==MK=g!v6QiLu5+EK_NH`oeq_u*%o z=-+&s#(j-y0S_{D>#4<|;I8d?OEVo@FQ=-sbBFF*@Y4mK+nyWq;>FqJ>*uR{_Yhvn zzyIj{wb)(|;7iIzpEHzPElw_{ryoLz`(i7+?&^ke+86htHB3|Fe5ke!fjL%8{TdA% zOnsQpPCtKCusf5Ho@BA=HSak0%5K{sp*b_EUvd)nm{Ql@uM(P@Sarf7XZ>q}V7Fl* z?TVUCaalx%%KJFbY9~x04@Rwi>vow+y&=giYE5v(v}h4?c@?!9(6?&0Zc1i3cA~~? z+FytSByHv#`R?4|w@_44a&tKR!5G`Dsu=4~7|Mu!LC%=|&1BOB|9eI($qLWqjq4Ve zow@pWFO~lF~&Ehwk<#Npy~Rm-4Ox zgsL70ls=oO7CNl;PF^jN6S&ON@ld?)-Me?#%?jE_-}sab(?L!WtMJ3kZxzlvg1ZzR zKxUCbx><7E(ecTebhb_G(>@q#+?n*L(z+_ssSd&|DDcr~GaP*?4eW(QQ z+dHvkb5i>I_)gm%sT|~tuRFCbqOjd-NTxwX8x?FhWvcnS*`+(92A@Z(3JU12sdz85 z?Q43852-KjDH*DlAtelosOEj)u856=aPFcNXZS;3X2Zd{eJy9K6|)KNXI=NAXlG_Z zEbsItEu09e;PKh!)Wh(%bKqe?Z^{h3@`bHX;rLpmQ!OfQ+MH<#?`cXmHF zdD}SCf}~%%3)g7>f*fS!c1PuR1gFj9^|>3pNpmW@YI6oHc5i)@_QK(Ix~U`S2xA^~ z;NGiAW=((-MAjcM<`Y=HSZ#Uy+6i6PhQ${8sU4!`lgIV<=c*>;?_&r)q1{*ROMkZJ zwTeMgY?QBuy?sV*VYF!}6W?jLMY^{HWGF)CW9@g--V~|bI3?$$?l_I6BlX7>Tl}2q zi6bwey<9Pyr#mh-X#u|ZsAYI$&RwZD+0Ux6_bqnWtc;qn!i(=OfTwtUok#NURK>t0 zWr5wO$-0+DXULKD+jFU%5eoFP+is38$DPGh4R!BcXZqR{{_IG>Hilr&nTTz7_w8m( zn=`Yp;G6ceyLKzqY6t2wvqkRVlt1-{rSn~^uL9fr3Y6yq$?#pw_R=v@qrCgq?$fU< zf;LYN*7&%fBOl7HbZ41$Qt0*nI>h~QT6c~g^^CH{IzPoOX`Pg{^Rk;IjeI8I z_#GXVCd!K34rlDNaDV9lVA_F%)yAP0rj^X7)IFJ5K7#kOCJN-;ezAHDN#Ob3&U|(s z_8X(M55KKJMS zrVdEYb)vOB{(jWTXsuA@S8#mIZw9R-u;;ro<1oXk!0=}G3e5=4)@=tky&HeRucI-*5J_MXp}(qF=h2vI%}}cjcr| zV~0DvG+<6-ND`ML^? zk~5?+b^NOFL5Wb#mW8T?6{H<_$z}_e?xfj5FOM_T}lkU+3bIwd^rHhM#W%9huK4iMa0}8l9w1&Mn z^7s|LJFBO~92x*ign-;D_MfeY+z}i&jX$O-#Bi&(#^PLqU?yC=4SL_K;VtGmQqw{4 z`{9|NP#498Qfc@EbAOJys)wSxJr@AoxRS}XqcC>mB+_PTST?rhVL(OID|8Ad;9XPr=L(v!DNh-4A6%@8 zuRlTJ2={y&2Zg;F%e+D}r=2>IS@=$LT*pztJHAsoz0(!95^t$WX=C!VOjSJnhUJfI_}2eZ*}27lgRy%=iQQOTl;4vP+SFTE`FuN z_#^cx2g{qc+TD2URIB1&x)yV-@g3v6Af1ZPWkRY!DVINjO7|fo_a;{!C%sZNz_psR ztr}zHE$R>tZ`QLtDU{&`07jjlQ;y>;9me?y(Jbm> zmbn6Q-r4(XD6y)c&6gLRe^Udl0mPPq@;p zpWohds9)??>S**5w$Fr-;j0+(+D{B?M^FwF4q>ILq(UiN()_9g+pVkG5(QZE_dRo31y4@%Ti!-j&Us)OQ33S}1~NGO}Q>R`=3uC3MoElJTt z?&Bf!$|Ts%oZ1zP+geO&CBC%3=+|Qw)U(9&9&nN%dZ`ZYHAqs@Ds64+ zp31Sfn7cNwz2j7inj3YbKLF4Yq0YDrXnvx(vTsvk^Vro&TAKV@ags07cCKg;t15gn z@@(o?Th5SM{33$~F*B0^05>JpD6(AhW+iZ;Nv*{I;(6t06?C3G7C{jCBlx|QMZLoQ8 zpaA|eBJgYga%6;k+SJ5ktL6P{;;}-j_bd_kg2=nbK*u6&CX>{8#FM>-Ub?OZGrbhi z&^DatXAN;b_6|dnGc2_mmz?=2pkhE?`Z|34?eyrGgwD@Dc0TFFOu1srG(_*A2}(O8 z7Q`p*T6bqpUiXI1+Eb^ti|++MWHM0yK!4f&`Rfcry5{o0W#C3(L8a>0K2fM~+1A@r zXu(To4YOjc@LbZ`;;+WZ(*%;lA7@R#(FqH@oxTYTkB{VL|E}}w1$tU1{6eW-qYT>o z5^@!UupVe7)zpzNx`}`luI`O8c&Z}AFb+k0z|d)q343JanqEAax;iINEDZ2x=m0ZKRI!K^{C1(#p3(!^*DlAM17wWI0#uohVdLw*VJ8iVJ zC^u*NrKGm?fuq$>TbxUvWX1UZn(!X?Ub<0k@Ki?uY2U|8u9RLHHI?od{F~&>Kr02) z!H}n&C?kRJy0sYB&VAj2A=3+gE{Ocp^B|u}IJO-XeDn3}4L*5EG$4|iqx$(m)jc0O zh8EpC>6ubBe<-@^^{v|LcPhmd2k@;7sX=jx>X}(tr7U3{{@quf6ZvrxXkRo+0v zCYrW(2D)YRexQ7AFCKem_R75=t0OO~Va1~tiDr=6aPLk&R< z9et=bZ{#8*NgCT8RhnFENVtd6$&+=#v7_$l46^!xPvOJV@f#J>W6p+!E2x%sbk|8e zcELm_82)pPw25?Ytaln3g^wJ$Kl>%_A}wsrA-X$z%rQVXziaxZmR#yDYCr1kEw3P? za>8q&*V54zYLLciq{gL+vhns~I_WBREH4rD9hXCWu$ z5&s0fC3GzVfRODz={}Sam24@{wy-@n_k#ypeBNFGhaEkUt#cUsWB2o;(DBIWm{}UU z+SGL6%2a~LZfd?B+mz89R<~yQh=<(XFMy@&2H>@x?uB#3keBMFv>3+$vj`xqoQ8S} zTjTQZ%ek^It&^@b(I?$vC(kVV?$7h9^MR6MAU1FnI^;?1c3pA( z+zN7fmAiMh%;siwyt?l+|ABt&c)@M#onBAPNEecNS5;B>#C_<9e0(=Y_`7q<`D7i_ zti_OiM$ef*4_T?uqH5`FVfNrAO^R0G2LI^pNHvM#s;ca}oT_@HS5`k}@3b$s(6L)6 zX!pt8Vlt*jC55W^^sowkzHJ$KQigv z^RCTAI!lzIEhZQS?B~>X@3BlKm`cyJO~=!T%K+FMX|-;ogjy_3!D0gXRq{`F_$wlV zj`wfSet=)hG*Up(ln0yoT;XMz!)>CaeCmWOdU)r8I@^ax!DL=V%YaL@8ymDe2^gw+ z@WaKo=pT6uc}I^)UDx%#P&qwm%8arP+G}BH*^#WukVj`-JE_6^%!wZtkz}6xIg*2` zwiZ{;5zyLGE8pNgB*Kvzx;^ir(7WK>-T6e}BRA@F144@;v-oPG|AFR{{4LZ0X{K3NP0*}3k4{<{Jh*oX{}=qYTr(mWKUnf3LRbveDKL9@a6RG18Wi{dmlj_ zbxP|uT?hk;>rSk3<#jIMb_KMFe6?W)uZXyRal3Q6pi+`I#p8!8Wi@JfvWBARJ77`K z+fg_hMW>^W6udUri$p7!{<w6RrhIyA8T$&ocxE4nQqIE?}+fgDon%s=xRM zTwn<|DoDMN39~TVG4+?Uzan)KKUb18x4ug!Gnfq3a!@NMnA7whB!UBaZM zAyNN>m4(T2PdPG$^x~Ri{~1w4X}^e#yL-Vbtxs!sVO6-^ois66>JDBRxtyXYshv;< zf)?qV-tUdc`#Rb73#j+|n~yNP9}KYHXXBM*mHosL03XYKB{G5-K(NRm9-DF5JjF4M zKUH|CpPXjr96;<_6V1Wm3M*=YaD^ZI3b44YUv`w!d^Rsl*SZJ|Yz8A19H}vx$7uTt zTY>#q2%Mz1Wj$mpBRF|_b`fKQ1^|EqUxz6gcdPHl&RaZskf!>sSNvV?_au!_V%(k) znFaF(Q|0-43*zr4BBQ!y|5g^aTomP)%xF|n5h9!#yYDYVkO3*1Zm`2Ud@WHbN(lBZ zxt*6rU0+|n)Unh05sY=IFbQpy-w>2sIE9h^x;FokH?p23wN|~W$8jI7ecKHj(ya-1 zDrJ~?OFB{_f3b^_MYWep-@|H$KdI}9n&0~O z?@!6kik2?)W23t?df(0IJHEX0Om z5sX|Y(b!M5@)17Hb{M?Eh^n+ypnytHL=82dfoF#zxqvf6$Rdzffh&~qQ_hGX*we|R z1p91~)4i7dG_9GTdjt6m)`nA0yqyLp+u!oc?}WW8E^ZTF{O~i!{p1S@bx>xYbN2Sq zbgt5Eh|FS1S{egaB_caq&n~tYe4d`MXKp){#{H z$)7GYQ*&QGP*4$u$rPdK5k29X6soBX?pIfyjb`$yvsWLAw$oT!BUJi8b5}PBsdQ;) z;d5iyvKJ|g_D791S)YmB-f5R3^*GV7H;5amTK+*}$2=V4+-usGOP9j;ilIIuq*-}` zEs(q+d@bS}wxsvBHW;`#yZEHgbTb)L=k!6d*+6`@or};k4kxw7U(+>7?cm*u_vHB6 zKKP+Ng)skMz*TtOPs-jcc)QMvU^4K?Ttx2$mwMIy3{Y$M*ham%(a>yHfE?m0W&2Lg zccw>-@a{3&o-8CJw4vM80J_^}8ZfU-*EL#g9N zec>)=@XHOi{7t?QP^v+oJ)O9P_1)rH&IBV|m*%CKzT$G>5!I9V=SL$a^zAlyCM{+a zlPzmTSa1V6y}XC$p8aKA2MFYnvCfW;tsCRhaYJQWy-}nlh0tK1ffcMu5Wx4Gtl#$U zD+qbQ-E-k)Tz$jZ<@rEO_f`&Xg13qj`&>a#p1a`A1lV&^CD%rdXW~1=#(2;>g3oz4 z9iSuWW%-ht7*S_~=%tc9ps-X!s*lG|a5-q#$a%$W&n2RrhuIc+;Q;8?vgnc-FQLjR z0M|X!S;CMf@ZV#}`HwsO>$ydG%0+{EX|9k-!MdU%@#*g1m#>FUaf+kYB&umq3BSAv zZ>yDt2<>)0yqO+S+;LfY8iluM=k61@3((=aHTKZ&>44CVV+DaJTk(t4SPLiz)`|gH zoEn?ixsHz?y@xdaO7@_eETB3k6XwH)izPj>YvWdGV&!vhj4!87f5(&d}hvJ*)9>`B_b@eU~cMsc_*D-ju zG{)kl_0jLnsh=0Md?}}^`Lyfn?!A-_!KpUf>9x;zdUbW&WS{ut=h`D&To`B&MvQlW zUv2Erfg;A#u(!^9*>oWz0g|0_7&WWd6e0b+5ojBzJB`rmhyZh(6YL3+bzOaZa*IhJ zA^A`EOL*1zui#f~h+-J@dq8uJ=~v&kpVUwN93nBr=do*ft-t&RW_JE=;;|VAQpagz z+G@jhGjhipZKq!zfxMEVNC|*eK)irjvvqbp;kR_Hh{yUY!6^50zNGdg|FLbGYkX85 zku@>j?1OEK{MubGG!>YtiEj*fer$)Qne?o{(*DBg-szp~FxcVJqR9$ZtWuxuxdZQE zM&h#j*=h@pI<5WaQXj{L$)DF0lTL|pUAS(^x<{OgRUsVp6`|_=8eg!9dKUEH0rWTk z<`P_0>bURDhtl!U{LAhhIt&Jrfh?#`+xh@t@cKGJ*-L3ngmtNrrpT`!jIQ*Z{#e~W zWQBicX6EzJ1z=hOItofJ8;x&oO{ZoBO=}b8Mrh-P)m(U|z)R&!k1GAAH?Bmb=3Gnk@fKFs>Ew(Fv6}X;`&WrLLo|K6WL`RFZQCe;d zLZPd|`tC;Q)xC9()VG~Tf2!3tD;IWwtET&5y+iB#L~)oBcO0>wtjuCz9(Gtx4ZmY7 zL4--z7n!R^%8xks@;Vb`2WfPuwhA^?Z#TFC43jO4^=s>9x88@VqeH1wB6ug-z@NsPN9-l>N7&q>1v6hfy5$$@f?^>B_y2B=h%MM^uo_Xs{ch_@0gdXhTrGV>~B%47Y^lf6j@r~ zedvN0!9M@y143EvX-?ETHQjk8rtd>R*hDGxZ5YDI%7-TBqQYq2w-fiLHs(Y*4o|2< zs5);)UaRX(A*H?>-qQzcMNynPmq{3lpqa_Q277lUKAGYPvh4%L-pTz^;15rX$iA|; z`1l;ZGJq`eYig01QXedqn@>2GGv~x z*=o`^0zO;Taz7?wN{)7QkcKxlWhe`X_$mY-$ z9Y>jQWJBSoWDiQ6?;X$#`N3=)V{q^9qo@3!h$Cklqv9PoCumHF9`Q-G^Q&WOK5EXa zU*L7=Or%`cIH908VJzA#D?(j4T3y*IEI07n8{zXyV_#i6>UM$TC%2VIHbE^*N**KruH70F#;b%v}uU9ccKgm7XV?8kB zD|}a=Kro>}`k;o&ap}&~9JrIj7>EpNSF#I2ZWM|XXguK|pDNGFaTwZ|YJm4J?1 zt;Bt#mbT%19Jc2!v2R44U(&84sZCvu8Ii>hR}{9-(zOZQ@h%Vc>5>yci62Dx03oqN zH1&jM3c|2x{j*|>s5e!@-Fv^^?XScAs=or2{xSAE_ssgk1ogYauN9;CW*AwTfnhcx zvUX6i1se7DJecKK^1#Fq9edmR;*!2p^974T3zW|(xV>%&mV6Tnx^Wud2atE+dT2S( zayFIAy#L${K2+*T+p?0EG!7%3t13OGq$ts#$R~Fr6{vb3snB$v4pNlg`*vCZ7eI8o zgrAm(ccPfS>Lmdc&~aJ}9aG zCFclk+yC#@9l~LN=0`&L8EusHGJIN*w>~J8y2XPK_cLt&G+HYovAva?akOfYZ!9hV zbDD8&LB_KC%?kc-$@NDUk?qa>(Sz3M>mv5F+#&;!mR&DKTX(yGH_CnXj9*5fBk0H8P7=X3b5|zgZ z^$!+s61pi zs?l9ow?&W>dxu1OM4`HKYI$T_dP_d%9|Wx-T`tVdl&SC2KZuGEc-}@|O?q$8P6~cm zTK?hNok;+50SJkRl(a~|NfLZ}i~a_ovW0eC`gjU2TJ_ zQJNrK+V1+yD+k*+WzSqdq-`7-;A6CwXZvyqlE7A(W|XlVB{Hj0$5s@ z)kY0OP)DCSx;!qmapm6V)@o=&-a_$QO0 zECBh4oS?;jqWQ=Zmm-J2i*q+=EYU$P8fgK)F)B!ZWhG!0Ko3?j9bd5K` zUe*ebdB@wdgwYDzDI-2&cBvbF;_kvc@ZnE*u&dcO7Iq8CNF-ZB5y~DoI-5xjGeKjXh`qFyulPV`J})RRxOWTXJ#<5^&^X}trnZK z=f|1$!Z3Ars1f=KI@~JTFAldJU(^z&^><}hg;eLZ6}76c2IA|YZbxpdLA>p({jN90 zxd%eAJz*KOR(dDjhrD%`L!~A`Q&SeWS=dCMTY7r*Ir4_fE(4o4S90Jd>|XiLI=lT_ z*C%B@B~?)CkKU^78BI6%DK{^{c=-HJ<@LVktcwj~Hlh-by<<_a>DkqUeo7)YUrR3J&a@mUdtcgCV099(Ze55r zr<^fjfPg>bETWXKdtUQ^3e_bRl=RCl}p{I=0pfI z@P!;k^E@Qj$M=R{F{{@pGPCIO$J5aAHGAF(qYb#np++@d)62z_ht-WzxS`BnNcPsPxaXiH^8IXAg~r zrA$SnxK#H;)_ZU~t=p^3Yv#lbLO6S7VKJXHuo99jlsTHni!zbZbLS?G+Im{jTw)yL zlOyihMBT0}EUxML5c>hP=xYLIsFk^StXCBET=?vgzb1{BrF`ewt@JcbY*cjg+E)YDU}XbR|)*eJbcC{PN(^kfUp8!4p?11v```~ICVhet_y zOHpx_ttxRiPd&HczqVPss@ZTdSZbJJ8Ca+vb_+UwdC5RrVZ z6n0kW_nn-bJvd`vIa29m&iSC0)%N+J>%Mc8bNuN_+qItOT#5qLk?IMBrBLgc)CuA6TUvJw zcW*D7W+IS=ZY107xhw0A3LbSae99s(z>36Z0|i0`+0^jtLA(`~Z1=H@mmXWcV=M$w zLQnmY*6&=Ip~?P$aDCawQW&II8j*~=Xc%}T5upQ}=sG0&f)1b_I}rKEm+iDUIV#I+ zic?Who(PfOsdaYOxw8q>f|OSG=7X?-WykYB;67a(56H_t(>hyzuGcE4oaYQ7>b9pp z^W|0G>=6I8R(-8|Hv=koIyN!!WR$2d53bw6mQh`$>%z5c_FUR1>M{__jf z6hhJgZyI|vXEZNJ8K{sow6q+)6VC<0JMFpodvLe7^_9|C%N-<_Pdh}=RJpRWMN6idY`G7TVK%0Go+dvfR3&Pd{vA4^Boi6>aUaTE4^Zq~Yi9#^|w?910E1zTEu_Zr3q#Te|l3`HI zh!{VZtuz*4Bi_Mv)-J-6+cACEP!NA<9n+whuaB_y{%^kJ>e)nI z(&s5&nYh?nLj_p^Cjd}WOD6~Cbu3%B8?6&1uD5W(mmleYnbQ$xLf*>QeU6ZTFYOm; z8ok_(d+vI+q;kXd_k0n(7MF9TgNt!2;@p`Qu8=b=Ch=TV+nPhnA zrfmQ3oWJ>PbpHE|FqJy!&^VTbX+rX z`VAs8n6lQB^##$q^B#1o%z(>1@9*~kb~j9^hk6$F7_kiMS?*QeLl9XYMS?FW-wDp( zfb4H^QIPbeq7yv=NM>6SZs;u%c|-^?fQSin+>#S213AcgKF6U0P7#Q*tMyUNZbUa|M(zxB`$f_arTc(@;Zxn^d7*fEvR65~Q^f0(+}ulJuKjJxiFyuW z3N0$IF-f=As!hYrf*ftH!7EQGS9{-%S4q#Ieu1Dky0C->x2b~FByssdM_yBJdy006Zu?XQA3$XG3sc$>NG8deh; z;tdmP8MnB>sv9dD|&O zDC|p2!}^bqN-NLi15@!X1(y*SXndZBwQys)(BUBk zopx#SzSYY8nT@1SfrTwyI7E}3IegI<zWXgm z!=}7?pg3bwJvYD8t+sVQIBaQiV`S4$O5LokKd*XyvAugs_tC>!bNw#2Sg$MDGVhDWW#Wc@ zhz`t3+!z}=&)!$O>o3uJy1{Mu2T3z4(x&Z8d|l|h9w){^=a z?_f5lQ!l|`#?~7ya(7f2UDg!c8;NwCx8Q+Cx`W^dy0ZiGN@4i|E4KwENwT_iaAI{| z(cXg67j~0l#K`sG0XsQEY9I(M%45v(vVB4JG0t*x4KFRy#uW{J`5PB~^Mdjwar0x1 zIQu7rNAP*=!g=>}5UoB%n03dr%Nh7@ETwdAM7x?F=H6%zS`~X<`{KZYZz{~$kw};` zp94;b%w}=PUTt|{cHr7hO%oT*+rw@t!b)6yjI2aW*x8Pde2q?7d&6d!cu@|r7ZxVI zmOncsH{%lWI~Hm@j*W(y#KhCNqi_H?!`D_d@7KRz{>z;2)qrSecVO>h*)@YUh(XC9BfBG!T8WVCnRQ$kt?L_? zH zy2M7LLgqLpc| zfJ?V@l{rbKhGnF4k!#g*VRFbpxz^)Z0mo)2ObVWjsnN{yTuizOc1VKd7oJ8;)K%Tq z0XTR!Pkx1G(VXO^iu2~}A^Qu!#E%3F_c6qn-@J@I_t1M)9f2zBnpk0|oscY)txP*A zszPv2_^gq~gB=_kMh_Q{?cgU?bOB0z4QzC?YmvGO`D^nMqExn}cE89~PVEg_+n2w| zYjJ~rIdzA9Ys1=fZs`Hf?;;-9tG+E~l0AnR;%-J13;WuJ-(875n0r0p;ZoIfPHstf zn_lwbGek1=43%xFHm7%7Lmo|ADowrlBJ#O+&OhN@`i&07(PypivLo^@d< zmt9qLc{{hXi4ixST*1uEsm5yuNa=x#LWm6g(ypaX3DQ{tv@U_!NeT0IMzQGxKhW8m zf>&cIM#YrS^TSDzDd()Rcph?YF9gZc&H(Pd_k-G|CI6b$98$eopUT%KdyGa-c^HtX%#D;GU5f>Dj zr-vMnCdB81ywxuvJGuOp5=Q)oiMsDE6l;1akW4z;DqdhAf{NK#3fkzL3fcsH?3vY^ zikchjpwPP^=y$uicrHimqjcEA{MhZe5Az*Hsjt8MC$e!vtoQ5dW3I++zaX+P;DU%{ zR8Ki(%+#>ycYO0_0;Nvb`$2qj0x|vzuT$DRMNW?Xj&gY6cbrdrmEnC+0#T010mP84 z^mI0ZRf5!^d8#GfOtfKrahV2oNTk65iTO?xMQ%)`Y`pd$f)LQl<(FV*hKQcu{UAyB zyy#;4rmxW06{Cd&gPl}``g+2f=ogc`VzvSh_H^Xmd!=AE0|KqnD=xN!agk#Cq7TZR zUKBD3Q|v%^K{-bB^5UKU3Y01i%Mol@Yyj0kmYIXOsk`h>2|k|=Uo!5}E^f+sYkba_ z-LWI_vPTegurokOR(9a#=~BUpNm7RB$;JQ7k0&xeS)s`MAd%nJ{M^)0=G^?x{Kz01 zOs~lk<_C%Yw&q7RJ0(2mKl5`Ci2{$0!u%jn;P3f4_-B6VBy9N8eqi{?6e_A$xfmI3@bz zY&od=;Gi;j;nET;;YkigVy)j;EF(BRz ztX#W@ks=)cGwWuS9{TK^3Jv7Ta7KI(=#Wq1+S2Py?rZB3efh?-#k#dJ>0CKyJLFjJ z_aOqTUMa29L%YRl#qs!>7m*`eexU#9{U9xKqlR&Ix&#!E=ReWPdFOdgdXNNi^Zr*K zI?WaF%Ky(F`v2R{;X_MT3@5`S1VqPmUO}@5jLbcUiAb13y{ScxE-n5xhnMZ$q=G1S zNBLUViAw;Jbh+6*medPo_!CuPU=8w>{^^Va+bFukpJVKcS=8Jgk!8qEZ;c- z%$(T4k}|f}%aOK{t&Na$BzKz6>tq>Xl~&b)opkzGt2;h+wvN6MH0;VOep_r3M$ z3p$w+eIF5DxDLZBA#ai`2BzyE>_lfXPrJ0-C^Ekp` zInmAKqE6F*g;3pN)cRC4fJD{msiYPJ)w(w|i&flxZ339kI>J>UqJG025f9Sh*I$wg z<5*}$m|41YC$a&vcu!6=Os1uVjEM7^TwRaMUj&`S;VwIWIN}YB4b8vQD~E1gMGsoh zdaW`ZC@sI7sthDm)&zbzcoBwB7(@f2&vg(W9=Pb5^%LN+XAs?KEp3nj?cPdj@bT#B z&T`mQRbUS~6kpy)euXc8l9v<$#HLDTLa_%6R3vT z<(YvSIngZxoZ;n#c0g954{H>$wMRRpA2VLJV>Lf{PhQt5LcPtuho~R4=|I%qoUh~0+NeD~$3;@l z(+?l@Pfr2Y!vDS);=zr-6jwiJYau3n$Kr~C{&P>mlQ%Y?yT@bdxHk5R;bd9&yvu-a z1Lep`Di@*<-VO5S4aro0C=}BAqiOvr(Nm^|%vstg9R*hGMyFoq`?kdImytWNm*`ZAI)b5nv!~bK7Kg!@0|-lZW?>qrgaIjL zNyJoif_W)@{+z|Hzj19t(Lj^C#l$uLC%y7d`T;{;C`)t%RzkV`(v}c5XvscCQhIv^ zea(pQl+D!??Lt2S=?iF+b+^t^%3awvTia6i*yTM3MPBOWmpBl13)n!MJ|Cy@+j7_S zXXT>294;*nz6riKHE1;p#y9*^%YV=GLh(h z58}HN?;p>NGOgA!tghfK{oH(;Pg;7;Rfq+xwhtInyOn9(nbGs6QU}%e?Fg>N+3>Hl zpf)1rV*>jkPPT5@XhrL7mQJ@)EY*;yb8Y;I#92g| z8N0Uf;!)+(MRt~ft3Rf&oqogE&0itXwddaIfA=&Lt9Vj9LYu?PE%omjhk9i|Hx>7S z`C?qFF)gQ6fLbhY70^cXikU7ZKH2SUo{B&Ha$X#XDz1f%t2^Oos7*81u;;g%cJzHI zda{-LX8yG)80|&a_3$T56v}&lAB)a09 zE`dOSq+Qz`{^?NQK5|1MRPXkVC;HZX?i*3A;CXq_?o>3Ql0LQC8MJ}bK882<(nJau zvOn#VHx{C`p`(GQ6rIlv!s24g>s9uKeV%h&RmH2PNv_~OA@ zwRxLd2bgqDZ4)HCu>5y;!4EGzPLcr!Xs%$-hs;h!ApgxOxWU<|?PNJ9^SKKTK+MhB zPU(tA^M*7#Z(l7k#RIK{Sa`p}O_OUw5`7(8`tu-jE}sOKTSE*$@d$* z0OV5G^SQ$^E|ns!>PR@1FkCr;FVPK}S2O67KoflM89)n~OkH=!;LJdteNOV39qxre zV^2>H_Wlyo(&SB_$6{t;!0!K(0Lip`)m4ts=594P2~O=e2{Ga)|7FBoF4D}E><>ET zg9FIQLmWWiza0P{*=zNgXJR>|m&qkiQaDq0O_@d3JYc{+CW*3&)G(szHwH&GeqmFr zK&xFbrF(I45zG13_;}alw)%}Nn?K@5qkOrN*x7Qf2(HwCZTK0L)Os1>wUa53i+3Y; zGl`h**pGJnPc47m;e2INvoad)S92*cp(L^tJ$m`Cf|HU9=RJYdVIE(iPALphXj5!K zY&nczjGt0W)3>qP)NUmHr^(&O-jmf7V+7{@3uwy&Zswc1p8n_4 z(f(WgK4=G1(*D|YEDz>j;h7Jz-*=Fg_BHkbA%Tg6c_|W*0hPs&RnXEW=@iPU#oW!9 z`b0bke0S0mE6CZ(TFMkt!o1KTX`2{mv3}%eO1s z@|mC@BA;<_HLx9AR zMD>TBc*S4E(VC6p;PC6r9T%f$ry+9oMIz&ix~;}gUs!~I205dr>>;CbT!T_i6p|t% zbs!$tArR1*Sc02BK8EZNu|KB*i5;Q#P>T!({Ml7*|{gq!UmQ{0`m zTCgWg1)zZU3aQf%^f5IWHpmI@qHj~~SPZ-TFw*RH84o>pzYpazXHr%*ewF5Uisbfj z`H{><;(=`&Jao|m#Z$9D<-`mjpX73>gR|7HcJ#lJS1?CEz|FpZx=L&tQVrNt_QPxw zG&304?ML>Wc-{F%Av84fQ0lpJ>F3g8!}Xf7&uQu>rb+OyNqAmLj9mD?*n97wsIo2& z@F4>zs2GTnj37Z!kQ^FyFe0Ex&LSWgB&P-gFoFaHL?jvjB}&eqAUR9Ul9Qw+Lj!v* z&V1i|Tf1Aee{R)wO%*de{ocFp-V=Z4ckUJImA^=8GU9X9?~WDaoz_H=?|*$izxS`2 z7bhc}ST}4}SChmh^&KKv?UiN{idOpPHYK(q6c-bw+7j_u(UV$X z*N==7xUb-9Z{p(>VskvF_*jV zuzz07Q0}#Dxvh9vY5zqaCWKq}_eUn&>sA zxdOQWk=&i7(NLWzW6li}@#{f+xG9gDx)bnr;lQ~l+uaV+7TZs&}eT|fl$nT;#hTs z_3m|zn$x5B_5?u7&1xo5SdpP!l2;Ew2mQ^>UPa|Nsg;)K?Tec3Tg#jBd^*Jv60_C; zR7EgF{s<6J%vRa}j3SUzM8|EpZO~tQw$pv%V~`vr1)HnYnTm9p%D*M#=*alg^}OgT zBq3o)LZbd9A?#I+Z7(0;Op%1}BMFfJkzt^QX}kfd9~hl@3WmsqCTt2#*ef()Zp4L3 z@6CaoZN=?3DY-*FYL*$WbI|;xyt{LalRTafWMitx{OA2IQE;;P*nD22n?-{;gA|yO ztkyUV$;lgva+N)mn_=}xzpuuG6EEGL{1KbcA2$o)d^BL;M`*EaO?c(uYs`mv^C#YO zK2_i=-(H<{C~>)ody!!~Jn+ZpFQa6i3^xF$QU9IyUu!irHjN2+Eq)mw=cin!l-na;r;B!?oqb%$q_9=S9BF?Cj^)9z3&ZvlJF8GnQ!_HiJh@V-{JNiwiHQnMfpH*>9nRBWDz)ewO#P6`D6auoirdkcv(DRJ9Ct zA{49fvHy`)&`KM@*!D&c*&E3Lx3A$1c?mXlza{zq_5a)Flc;~)@0OQ*?qY*@8G=im zg?&U?ySy6lD;Z^A8STCb@$Jl0?;P4* zvD~r0`A}+yxX85Az^=XhwxiInW*Jo*y#PL&_b@lZua&WRjZ2J+`gQ0&BHJ;0$}_o= zhA_546vb?}P|@-1MHx4f+X?*M+6@6GIyilFW;*U?cELG1s*#>|< z^5AV6T~9x;f^l;RGLtw>zJ?{g)EmD_j>?J8WJXzv-c|m*oHpq?=Q2PA>e}bN@kZa@ zxK7LrmWn}bz(L5OS7c_Hef6=#cTyFIofqSoM|^tH1ud&{AS$_vGoGDx--vhbc1%tF z@sBw+ag&9lrFA2Ws40nV4q9^@7mxc#fz;W+;Ν*>NiJCT?b8u(nl=lK}>t{=5FE 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

n( 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 Date: Mon, 27 Oct 2025 10:12:29 +0100 Subject: [PATCH 4/4] Augmented posterior predictive (WP) --- simuk/sbc.py | 91 ++++++++++++++++++++++---------- simuk/tests/test_sbc.py | 114 +++------------------------------------- 2 files changed, 71 insertions(+), 134 deletions(-) diff --git a/simuk/sbc.py b/simuk/sbc.py index 05af04f..3458ecb 100644 --- a/simuk/sbc.py +++ b/simuk/sbc.py @@ -19,6 +19,7 @@ from collections.abc import Mapping import arviz +import xarray import numpy as np from arviz_base import dict_to_dataset, extract, from_dict, from_numpyro from tqdm import tqdm @@ -65,7 +66,7 @@ class SBC: simulator : callable A custom simulator function that takes as input the model parameters and a int parameter named `seed`, and must return a dictionary of named observations. - trace : arviz.InferenceData | numpyro.infer.mcmc.MCMC + trace : arviz.InferenceData | numpyro.infer.mcmc.MCMC Trace generated from fitting the model to the data. If provided, posterior SBC (rather than prior SBC) will be performed. In this version, we aim to validate the inference conditionally on observed data by drawing parameters from the @@ -149,6 +150,8 @@ def __init__( # Check provided trace self._trace_posterior = None if trace is not None: + if simulator is not None: + raise NotImplementedError if self.engine == "numpyro" and isinstance(trace, MCMC): # Recall that we are not calling `arviz_base.from_dict` but `arviz.from_dict` # TODO: check if this is intended or some transitions between API versions @@ -173,6 +176,8 @@ def __init__( posterior = posterior.reset_index("sample", drop=True) posterior = posterior.expand_dims({"chain": [0]}).rename({"sample": "draw"}) self._trace_posterior = posterior + # Get observed data from `trace.observed_data`. This will fail if no observed data present + self._observed_data = trace.observed_data def _extract_variable_names(self): """Extract observed and free variables from the model.""" @@ -199,28 +204,59 @@ def _get_seeds(self): rng = np.random.default_rng(self.seed) return rng.integers(0, 2**30, size=self.num_simulations) - def _get_prior_predictive_samples(self): - """Generate samples to use for the simulations.""" + def _get_augmented_predictive_samples(self): + """Generate samples to use for the simulations in posterior SBC.""" + # Draw parameters from posterior for posterior SBC with self.model: - # Draw parameters from prior for prior SBC - if self._trace_posterior is None: - idata = pm.sample_prior_predictive( - samples=self.num_simulations, random_seed=self._seeds[0] + # We treat the posterior as the new prior and generate synthetic data + prior = extract(self._trace_posterior, group="posterior", keep_dataset=True) + if self.simulator is None: + idata = pm.sample_posterior_predictive( + trace=self._trace_posterior, random_seed=self._seeds[0] ) - prior = extract(idata, group="prior", keep_dataset=True) - if self.simulator is None: - prior_pred = extract(idata, group="prior_predictive", keep_dataset=True) - return prior, prior_pred - # Draw parameters from posterior for posterior SBC + prior_pred = extract(idata, group="posterior_predictive", keep_dataset=True) + # Augment `prior_pred` with observed data + observed = self._observed_data + y_dim = [d for d in observed.dims if d.startswith("y")][0] + sample_dim = "sample" + observed_b = observed.expand_dims( + {sample_dim: prior_pred[sample_dim]} + ).assign_coords({sample_dim: prior_pred[sample_dim]}) + augmented = xarray.concat([prior_pred, observed_b], dim=y_dim) + return prior, augmented else: - # We treat the posterior as the new prior - prior = extract(self._trace_posterior, group="posterior", keep_dataset=True) - if self.simulator is None: - idata = pm.sample_posterior_predictive( - trace=self._trace_posterior, random_seed=self._seeds[0] - ) - prior_pred = extract(idata, group="posterior_predictive", keep_dataset=True) - return prior, prior_pred + # Deal with custom simulator + prior_pred = [] + for i in range(prior.sizes["sample"]): + params = {var: prior[var].isel(sample=i).values for var in prior.data_vars} + params["seed"] = self._seeds[i] + try: + res = self.simulator(**params) + assert isinstance(res, Mapping), ( + f"Simulator must return a dictionary, got {type(res)}" + ) + prior_pred.append(res) + except Exception as e: + raise ValueError( + f"Error generating prior predictive sample with parameters {params}: {e}." + ) + prior_pred = dict_to_dataset( + {key: np.stack([pp[key] for pp in prior_pred]) for key in prior_pred[0]}, + sample_dims=["sample"], + coords={**prior.coords}, + ) + + def _get_prior_predictive_samples(self): + """Generate samples to use for the simulations in prior SBC.""" + # Draw parameters from prior for prior SBC + with self.model: + idata = pm.sample_prior_predictive( + samples=self.num_simulations, random_seed=self._seeds[0] + ) + prior = extract(idata, group="prior", keep_dataset=True) + if self.simulator is None: + prior_pred = extract(idata, group="prior_predictive", keep_dataset=True) + return prior, prior_pred # Deal with custom simulator prior_pred = [] for i in range(prior.sizes["sample"]): @@ -228,9 +264,9 @@ def _get_prior_predictive_samples(self): params["seed"] = self._seeds[i] try: res = self.simulator(**params) - assert isinstance( - res, Mapping - ), f"Simulator must return a dictionary, got {type(res)}" + assert isinstance(res, Mapping), ( + f"Simulator must return a dictionary, got {type(res)}" + ) prior_pred.append(res) except Exception as e: raise ValueError( @@ -285,13 +321,12 @@ def _get_prior_predictive_samples_numpyro(self): return prior, prior_pred def _get_posterior_samples(self, prior_predictive_draw): - """Generate posterior samples conditioned to a prior predictive sample.""" + """Generate posterior samples conditioned to a prior predictive sample or an augmented posterior predictive sample.""" new_model = pm.observe(self.model, prior_predictive_draw) with new_model: check = pm.sample( **self.sample_kwargs, random_seed=self._seeds[self._simulations_complete] ) - posterior = extract(check, group="posterior", keep_dataset=True) return posterior @@ -330,8 +365,10 @@ def run_simulations(self): seed was passed initially, it will still be respected (that is, the resulting simulations will be identical to running without pausing in the middle). """ - prior, prior_pred = self._get_prior_predictive_samples() - + if self._trace_posterior is None: + prior, prior_pred = self._get_prior_predictive_samples() + else: + prior, prior_pred = self._get_augmented_predictive_samples() progress = tqdm( initial=self._simulations_complete, total=self.num_simulations, diff --git a/simuk/tests/test_sbc.py b/simuk/tests/test_sbc.py index f851070..3a74b2b 100644 --- a/simuk/tests/test_sbc.py +++ b/simuk/tests/test_sbc.py @@ -183,120 +183,20 @@ def test_sbc_numpyro_fail_no_observed_variable(): # Test posterior SBC -def test_posterior_sbc_pymc_with_observed_variables(): - with centered_eight: - trace = pm.sample(draws=100, tune=100, chains=4) - sbc = simuk.SBC( - centered_eight, - trace=trace, - num_simulations=10, - sample_kwargs={"draws": 5, "tune": 5}, - ) - sbc.run_simulations() - assert "prior_sbc" in sbc.simulations - - -def test_posterior_sbc_pymc_with_custom_simulator(): - with centered_eight: - trace = pm.sample(draws=100, tune=100, chains=4) - sbc = simuk.SBC( - centered_eight, - trace=trace, - num_simulations=10, - simulator=centered_eight_simulator, - sample_kwargs={"draws": 5, "tune": 5}, - ) - sbc.run_simulations() - assert "prior_sbc" in sbc.simulations - -def test_posterior_sbc_bambi_with_observed_variables(): - trace = bmb_model.fit(num_samples=25, tune=50) - sbc = simuk.SBC( - bmb_model, - trace=trace, - num_simulations=10, - sample_kwargs={"draws": 5, "tune": 5}, - ) - sbc.run_simulations() - assert "prior_sbc" in sbc.simulations +with pm.Model() as posterior_model: + mu = pm.Normal("mu", mu=0, sigma=5) + y_obs = pm.Normal("y", mu=mu, sigma=1.0, observed=data) -@pytest.mark.skipif( - hasattr(bmb, "__version__") and tuple(map(int, bmb.__version__.split("."))) <= (0, 14), - reason="requires bambi version > 0.14", -) -def test_posterior_sbc_bambi_with_custom_simulator(): - # TODO: The names of the parameters drawn using `bmb_model.prior_predictive` - # or `bmb_model.fit` are different from the ones you get if you access the - # `pymc` backend model. Eventually, we should decide how to handle this. - bmb_model.build() - model = bmb_model.backend.model - with model: +def test_posterior_sbc_pymc_with_observed_variables(): + with posterior_model: trace = pm.sample(draws=100, tune=100, chains=4) sbc = simuk.SBC( - model, + posterior_model, trace=trace, num_simulations=10, sample_kwargs={"draws": 5, "tune": 5}, - simulator=bmb_simulator, ) sbc.run_simulations() - assert "prior_sbc" in sbc.simulations - - -def test_posterior_sbc_numpyro_with_observed_variables(): - nuts_kernel = NUTS(eight_schools_cauchy_prior) - mcmc = MCMC(nuts_kernel, num_warmup=25, num_samples=50) - data_dir = {"J": 8, "sigma": sigma, "y": data} - mcmc.run(random.PRNGKey(0), **data_dir) - sbc = simuk.SBC( - nuts_kernel, - trace=mcmc, - num_simulations=10, - sample_kwargs={"num_warmup": 50, "num_samples": 25}, - data_dir=data_dir, - ) - sbc.run_simulations() - assert "prior_sbc" in sbc.simulations - - -def test_posterior_sbc_numpyro_with_custom_simulator(): - nuts_kernel = NUTS(eight_schools_cauchy_prior) - mcmc = MCMC(nuts_kernel, num_warmup=25, num_samples=50) - data_dir = {"J": 8, "sigma": sigma, "y": data} - mcmc.run(random.PRNGKey(0), **data_dir) - sbc = simuk.SBC( - nuts_kernel, - trace=mcmc, - num_simulations=10, - sample_kwargs={"num_warmup": 50, "num_samples": 25}, - data_dir=data_dir, - simulator=centered_eight_simulator, - ) - sbc.run_simulations() - assert "prior_sbc" in sbc.simulations - - -# --- Error handling tests posterior SBC --- -def test_posterior_sbc_fail_if_not_enough_samples(): - with pytest.raises(ValueError, match="does not contain enough samples"): - with centered_eight: - # Trace is too short - trace = pm.sample(draws=10, tune=10, chains=4) - _ = simuk.SBC( - centered_eight, - trace=trace, - num_simulations=1000, - sample_kwargs={"draws": 5, "tune": 5}, - ) - - -def test_posterior_sbc_fail_if_wrong_trace(): - with pytest.raises(ValueError, match="does not contain a `posterior`"): - with centered_eight: - _ = simuk.SBC( - centered_eight, - trace={}, - num_simulations=100, - ) + assert "posterior_sbc" in sbc.simulations