loo/0000755000176200001440000000000014411522703011042 5ustar liggesusersloo/NAMESPACE0000644000176200001440000001007514411130104012252 0ustar liggesusers# Generated by roxygen2: do not edit by hand S3method("$",loo) S3method("[",loo) S3method("[[",loo) S3method(E_loo,default) S3method(E_loo,matrix) S3method(ap_psis,array) S3method(ap_psis,default) S3method(ap_psis,matrix) S3method(crps,matrix) S3method(crps,numeric) S3method(dim,importance_sampling) S3method(dim,kfold) S3method(dim,loo) S3method(dim,psis_loo) S3method(dim,waic) S3method(elpd,array) S3method(elpd,matrix) S3method(importance_sampling,array) S3method(importance_sampling,default) S3method(importance_sampling,matrix) S3method(loo,"function") S3method(loo,array) S3method(loo,matrix) S3method(loo_approximate_posterior,"function") S3method(loo_approximate_posterior,array) S3method(loo_approximate_posterior,matrix) S3method(loo_compare,default) S3method(loo_crps,matrix) S3method(loo_model_weights,default) S3method(loo_moment_match,default) S3method(loo_predictive_metric,matrix) S3method(loo_scrps,matrix) S3method(loo_subsample,"function") S3method(nobs,psis_loo_ss) S3method(plot,loo) S3method(plot,psis) S3method(plot,psis_loo) S3method(print,compare.loo) S3method(print,compare.loo_ss) S3method(print,importance_sampling) S3method(print,importance_sampling_loo) S3method(print,loo) S3method(print,pareto_k_table) S3method(print,pseudobma_bb_weights) S3method(print,pseudobma_weights) S3method(print,psis) S3method(print,psis_loo) S3method(print,psis_loo_ap) S3method(print,stacking_weights) S3method(print,waic) S3method(print_dims,importance_sampling) S3method(print_dims,importance_sampling_loo) S3method(print_dims,kfold) S3method(print_dims,psis_loo) S3method(print_dims,psis_loo_ss) S3method(print_dims,waic) S3method(psis,array) S3method(psis,default) S3method(psis,matrix) S3method(relative_eff,"function") S3method(relative_eff,array) S3method(relative_eff,default) S3method(relative_eff,importance_sampling) S3method(relative_eff,matrix) S3method(scrps,matrix) S3method(scrps,numeric) S3method(sis,array) S3method(sis,default) S3method(sis,matrix) S3method(tis,array) S3method(tis,default) S3method(tis,matrix) S3method(update,psis_loo_ss) S3method(waic,"function") S3method(waic,array) S3method(waic,matrix) S3method(weights,importance_sampling) export(.compute_point_estimate) export(.ndraws) export(.thin_draws) export(E_loo) export(compare) export(crps) export(elpd) export(example_loglik_array) export(example_loglik_matrix) export(extract_log_lik) export(find_model_names) export(gpdfit) export(is.kfold) export(is.loo) export(is.psis) export(is.psis_loo) export(is.sis) export(is.tis) export(is.waic) export(kfold) export(kfold_split_grouped) export(kfold_split_random) export(kfold_split_stratified) export(loo) export(loo.array) export(loo.function) export(loo.matrix) export(loo_approximate_posterior) export(loo_approximate_posterior.array) export(loo_approximate_posterior.function) export(loo_approximate_posterior.matrix) export(loo_compare) export(loo_crps) export(loo_i) export(loo_model_weights) export(loo_model_weights.default) export(loo_moment_match) export(loo_moment_match.default) export(loo_predictive_metric) export(loo_scrps) export(loo_subsample) export(loo_subsample.function) export(mcse_loo) export(nlist) export(obs_idx) export(pareto_k_ids) export(pareto_k_influence_values) export(pareto_k_table) export(pareto_k_values) export(print_dims) export(pseudobma_weights) export(psis) export(psis_n_eff_values) export(psislw) export(relative_eff) export(scrps) export(sis) export(stacking_weights) export(tis) export(waic) export(waic.array) export(waic.function) export(waic.matrix) export(weights.importance_sampling) importFrom(matrixStats,colLogSumExps) importFrom(matrixStats,colMaxs) importFrom(matrixStats,colSums2) importFrom(matrixStats,colVars) importFrom(matrixStats,logSumExp) importFrom(parallel,makePSOCKcluster) importFrom(parallel,mclapply) importFrom(parallel,parLapply) importFrom(parallel,stopCluster) importFrom(stats,constrOptim) importFrom(stats,nobs) importFrom(stats,qnorm) importFrom(stats,quantile) importFrom(stats,rgamma) importFrom(stats,rnorm) importFrom(stats,sd) importFrom(stats,setNames) importFrom(stats,update) importFrom(stats,var) importFrom(stats,weights) loo/data/0000755000176200001440000000000014411130104011741 5ustar liggesusersloo/data/milk.rda0000644000176200001440000000260213267637066013420 0ustar liggesusersBZh91AY&SYB)?E$C:Vq^he$I MM шdd24y#5 @4 2 "I@2LFM2h42bi0 b #hi!M4(FTlj=Cڧz# h=G4iQzbSLFhM e5AfUhOt8MMKn6)c?V2ډy UQn{ ,AkO4#-Xlcm7 Ryxukae E|CꠓKŸ@;jQ$ %mm&: T=8$3^W G$ߌ-(W4M/|Fp \ k\8=BrnLxj6ğ51 ^B9xCQY[i$UPs0AA-sU l5PÑgLásU+܁J2V nQ/JK"(Hv!Floo/data/Kline.rda0000644000176200001440000000066513267637066013535 0ustar liggesusersBZh91AY&SYA^0_TIMdߐ@0F@AZ mLSLMFL4GCRi2ibF44ESzjd @@J*Ij#xIB9J 'aMTuC19F HoX&PH]ojn{sּU=y;oOun^6F*^[jfhms1r]{{]^^lvl+{+SoYْnZwL07]vێugٺwj냮m՚wny{cZl;7w$=w^vz;'{==d]ws]7]]U^UR빝M7}s磱5ݾ뭷wo}W.}v]۾V93ﻳyGλ=zw]v۹iN/ZWUj=n{ۑvΎ.z۳ۺo9 "jzk[iw.Ƕ6Х7cGZlE{{Nyso-6[Q5=gwsץݽ:uc{ȗFݽշmn8ifONum;mq{W\ӷm{{]=gz]ܽM+{&J˶Sζ޻g=׵[&kowsM^kkkF^7Wwni[rzn\w_ywfwڽUkw]3Jys{txxeo/tzαw׻{*7R׳z秷Lw4wvusgszLwYW#w^}t}ofލ;&˶:UveT^nyRnwwGOzh:soYU=M뗛λ\6MLGOzy{*c-a(ݷ;u$is]i֬VzݻUU]̻9nhk^4=n==L]즫{qt{wr;=^Ն^T{k]ɛ;osnkWd׻=mu۱j{ou۞{ݷkY{zknYJwp$neǝ#w-ɾKnwGo9ݭs-6M{^bh[n{w= {=Ӝ}'޲o}{}Ͻ{}/zٽ;WzmZC}+}}xx|îz㮒yV7ݕ޻׷_yuG[]bs٥sW]]e{n݋j7w-Y{ez)sݽW[[l/nC^t{h(y[wrr뭷SRb}ڒGZ6*jM}w h @}@P@@h͏9>==@}0ӶF$>@}:}4>69@@ݸt{t=A=Nvu7 @h;`z@}}t}@(:2op@;`@UT]v> $^@{l :T 7]C}zp vb}N{bw}L tL`& #F2@LLLL0$ I&SjSF@ !h ` cLF4&&?ɈPz#`iL` 04ha0#AF&LFb4b4(DA i& i 4 hBH Pw d@ yy|yl- t>eɍOzf c5&,4d`M7%wT;f*Kc~]ZߏK#KID5]T$R"R/Ά[R~L)ΥȖ= R~r^/zSj[f%l{Ԁ!0 AB)Ba ,!oEA\/Ђ%Oϩզv,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, 3@ &(<[/Es1[eYABl%^H{@!_s>}钸 :V9^ttNzplj>;SoO 4v:k;bv%sp)ǸlI;DwpmtĠ-e'ZW|4FP*oΘ1PTvVЮQ?YpHMʀ*G&پwH(ogeSIAx2G,fDtc59+e屓q(맳 =dv,P|&scN?>hBnGP$0$ PܛE'B*r"ĨdP/ҿ|`RѬ8 BDp`30%0'4g!86x34tglQ'?(K~¼{NN~h-*lOx _N%Wo3bbvn(ѐ_Use,l{I j!@k켎VΣ'f\5KfWs.s+W؎ e=h/fdBۧm)Эvg_j?`z*emwfKr 8DӶj-CF)0HGo^xAcjUڱav{g`a@Wa]ҔjO˒@h1sMCPq(=g =3 U`S1[o0BQR`bł=>^%>Et+x(^hۈ.Ř-kuN԰}؟Pѳ<n~ї@C#R $v"€j+0 9z2=P=m@fݩSvo1'&3>XN8ѴYLE`hk/bx 0!r"Lmϲ,,q`RF8\u2H_˺\d҅^Z}u#E{GՂk%ZXUC#q !5B:;OH,0@ "O3 ? =P.gg#)~*2BnLFr2U;0WLMoj+n4bgjuVgHh^.CJkjɟ/*V8\Sӟ\@3j$ !^ܗX憸aT{PSVsfQΑ3sTf1h| 6ڡߜXT7<{6T>B˛-OVJ&H@=y7_XwLW!+@3jOמSH gkRHy;!gЃ:P(Boqp8VGeͪLPDEJP5=!#`uiĨXp D|ӞMZu@  Zo+y'x?G61D;1 6GOϧI5wxv0>ّz`B;Oَ$uH9V xyj,>t+A`1;wdkg^_paSp%D@fL/(n JFvw:OlH(R GA]aiq=Rŏw2 $HSpPX&B]n 6 }[_4||ǃ@@@Hv𬻨7{J2 QxF঩LW'; 0UlLJvY;EiA>i#yd)T*#P"L&4(_ga`V- OSHڄ^٣!sA:8Xm%%~ eZNĖn"7 eiUJ_v5X/P!N26B|@b d$éY}nOXp9mU8 7MQ `ntT0@M掲Qq"gt p] =f1CFwrh+v<@5mQΈ0;s"x1$]8[,aBNc&4]rʇŨ^&G↝0sc,k bRI ƕF[F[`ұ}BΣp M/ݜgQ4< AXC7i8wQ"M}f994"j aIYc/۰<xipy03''W$aie_%V#GU =][-N /e5u͛rt:NK@.{sY3F߮⬇ųg ȕ`h,8฾9'q\wZ*i}%i+G̃BB,̲rA0pܺa~mgp|6B b ~F_]|9;[<8+ i?i"2 ~M=)E@Ty.6d>E%g&SUuEY_xoa4 @PtD;8yӑ92?=US\R)}HD!j2 3MO$gɄ ZkɨY_FFu& +u`G@M$k .k=g:!0`X1mPz tʄJ`H 3Wb>8G~@~nzwF)xFuH E2>T~)PKV`-7E&IٙPWo翛d4`@ >Z?:Ei@">}qtRfҠ>]k?{þp^XUiڦL*\P9ΦrɊcʊi+[Hܐ@>z13G5yJJw׭ YU*EyBD[!f9shD6(4F1=86I/8xP~!F -u +ն}$"Gc]RL5ǝ 4+/BiNcldu4.]u ^!q4{:3b¡ XE_+fDA5ק3- Xc~a/\0"$ĻsV#&mMIʷv _72B;uDPzh_; g"NYfDѿCA$$c`ЪN^WFqU+VT8] ݨ.#aq UrğE(\P"2w6q3@ɥt?&w̤BhKi-Ǜ1ATn" < üwԀPFjXT FƜhMQ!t1nb+>u}wt>%}韓 ]^SzKm]C!3cU%;r { 2G ҊrMkhvx7T\jLQf![G пUۡHIVT6-9?% 4#~+1P2IFYx U:2%LgFX]rqt*`q3ѻk]>HӌӺ s&VJȹ-竁-3qH1 Di1mܗ!1>n[V j }GDiUXDr@]*DI,;b*+@H8cP-9w bcWLgrTD5;rL{gʈlM'Bt{iK}C,##|xGX.;4 6%ny>l]m*Z5«rӎ3ΞKcp! Z%?@LpP B=?W$3_ޔ#~ i\Z "7x)נ 7)wpƖȡ %[捠Ac%F(ͺoMIn|69D~ JM#Q2 {/$lɜ@p=JpϾ`cc"U49|J:ak} I֞߰iZC(I[|9̀3"WL~uT⮀g~xo}FA H<7t/|'#i5dV%G&qܣAX %ٰ,=aHH?lT7憆R2Æ-B+{鬦m`m0klmq waُ%Wg<ېG6prՊ*d.ʜ0dK~W0sכZktUIӪK&dQ!ŷm3ȥby9\][ސA nM}W@=_)bՀ$D᪍=a '7 ,Ul&bA#^S 4.:b&=9L C n"rt4C>:AY2MqWq&Mxܶ 4YCڃr=pN﹀JWGX %xZs8s wX9KK ~66EV[V\v<cw|GbG:ss޼V[Gɑy1 :ϤLwJRTNAVP< |=ETTAfNt]9oXJ|_lgډTLh^(ڂ|U6 [eI`d*P' (5Zl#rYWc>6dHJ@aY/$4| ^1eus62 8"҂ =-"^#U.ь(\o1!/V>: j6z̯F)ѐnL$kkcFSys%b=Za;V{ᛦ/!s[̞s9*l"$*x$ *hY0ycIQ2ހ.z9 @o_b?:bwH8@2=)[bWѷ)LUh*tINzQY9+H CW% | Ϩ?%xO&i漏! ~D`WHʓd,8#Ckk7{˰܎KǜP4 /KM6w"@XF=2t"u107d#ʿo#ThT๴[(-xb+j7ŮGs*ߙ&9'K_Wlu~g2z+Jz{SV2~0UoĤ$>__h}k׹ϭJ`m02dkh sxżINNo(l]qUDJK%P[|M#o<7WM!Yǂm <ώ*ely>P!ֵ@!YIO4@{4JWh_Ys`@f:,NϦUhh)`Ϗ/w|jC{IsmW'[3k"9o ȼO˘ tͪ(6M?qD*H/CP/ vt`Bn?bRJ2ߟ6Z[p01y߂ %f}ϝQc aM OB;1{ebȒo`#z uVz-RO|rѨu0&-j XR H"cuo^Lrߣ"] ~p]Uę\  .1[Gq5Hr:hx ܠ|R9_D3#jqrͺY}oxMĺV[C: yu8No>.&H^rnm`9Ƿ 0dZM^5hX`XgBAB&K^b("A=tTw#+Ե%OBn-mkM*Égo@>ҏ<9DSLC1]R ~$ET-Moڸaqiw!PHH 27D>묾HNރ{/(д$G5zj vڵ>WEbh?+[@V>~*@VL/שּׁTn=|#k5NOl zwb}j86E"wl@GX!h ]\cS{,PEz2{R/Кr@mna+ FlSqR[-6p,IyXBvQ[9\5(͸] ?GJeK|ݻGmQ;MWBjQU8\P8 Ĭ7q10cMXtcFŔa T|Wwvmh5T!=JHio چւS|٤mfFc_&-ϕS\ALHs)'vn'e j8h/7ڽ~U>ɶq*F$|Pɛimǻt͙Y`l͸ ݝ}-)|l7vOc %w]!'cXž뭟X ~q[QdnFp8h3z"p4tmVN >nǁmיf;=:FRl<,*o.Jq8>lrN|5 QZ' 8D4o0JS&&Bw*m Cn'EՀP}U"G #0@/o2aZ /O9I=#$WUX*a  )4n5'~<66'_ ͑ ;f]K%նCN>KRzMӆҹ-4s[og^zRDꂢ 6etEg@_G (`,gؓ6 [8|@X;-rff, 31(Q/~4s8Hz\u={R.g 7m-Ga: P?_zpҧhk+ SXNmPjp7lb6Q Cx þgu,=&PCM43 !A6qHh5Cb*^xԦ3;# Yn829[ѥg4f.0Pj4%_ZC s{vt?ۻtźY/NJp4,LwE\@%F߅ψ*F-K<$fxj٭Ƨ)O;Tm[6l׏;> _vے9+~&֒'%<3\R(3hl6; hF'YV-BLGl( {? /M94 p3Abfj\q@ݲ}r^.G5"}r ">B*eߐ5;pMXK;#p'%F+AW*UMλއ_{ 9"Y i*5l<6)YTn{3/\f#;33sJ{5_㒼X lOZ,Eϸ^TTX ][ygO[oLnJ ;_48C_&QWd>%6Y&X?h<} t/U$>W9pIqȊR bj'W4U&eLCkoj.izo~ 3D'@\(Ah[?4'_\V~Ɋu[O=|nid]0 Ba4)O*>4`T<3`X^^O S!}KEd]?<Z(:%A^u(DְcSj5~YZXK%52)z:W;{ßd$+Wa^pDne.9_#3q" '":t@E,x?k/\3RO(oJ+~J)a)0T{{ \r5N? :"^1eBc%/ w[ OmUjaj\ˣ0}Yٺ?.45d׍;"NCKзVNQ^eo.[x3M<̞ÇM|ac%Pk,PO#X+üwTI$=ӮΊaˬ")8zG2Fjid/z홈Sv%gߟ39f'CQ%xRx`;1dAZA>\|JDan9/$r{&ގ1=Cu93c/8_wg9kNJ >0'_f57.ThsX`XV`7: %Wv7,|&.*PlkSupm0m;. 'vs 8fQ0Ux+{lIlք!ӚRJâݬ'%/uEhP.orANIXs'\ ḭZsAHchHސdP_1zS̸v&z!0t?ʜLuJT) Xs ͪTv~]{x#zAEŒE2:0X-L2>9 ВrK1s73A{f#<7ʈb# vz7mx|0JuY<:24!sC HvZA]W^WњHSLIL୳X>i/$z&.;epa;ұAXR6<caZ;DY4㭧CS&VFkv!V9sOS:\\0]sstN>[f%Th<3..=}#yf aLOoGӇZJ}gi7I\ߤsKzHSeAirD[mT]3dhNGeTE<۵ Y:/'em8?,u }e|@E's9SS>'~p4vnϓ/)uo} ̍/܀@!! >[*ȷs9Y?ޥqPVd:g;yRzFF%+3LlN &843ʋ h^1o3d;i*f׎|KWD F*D2'\8ܯ4]KM(ل#ff MM3n@8"K`O֮j/A[)? 6ԸoWX-bqom<;Z<A8۪ڮE">l2̓d`S|X-&%-h_HNmQ@o 5N%{,{0;M|z&C4B^b8&v| `_4>2UTұ^ ac[ 60;]:$._Lj( Nyu45/O">E%AXPo|ĺve H74R]|Fte~i&0brܟx択}#&8"F&T!ܚg/S~1boQDR[q% h?t|P`uxLIl ,w#6ڛeza7G' M%Y+ Z]ޠmlXQ጗ב-e7mO$?-exV!*(G*F6/Q֊=bY|>R BC29ȶ@v+_6-F6˼S+(oT(lE b:q^.OcmxB"˛B{rDJ rOHm D5N}wyˌ8DneWd\ q3$BGW uJ:9a?莴a+#˔ޅ-ŔYkPGח]WS`ηʎt3[_"Eߚ|[@HLomaٳt9>UA3j۲[} } {,quVd;ΔQqwo<}s%O_kpY8pJ!~j6cʺH(زD$Y_yg||Ԍ(DV!w8. K_S!<}΋j?زC F|a_:Ã[|";\LOfYE &=\~)_jw^}dXk)ZR;";Ytlpኼ:V*k> mW%>"ne;AĴӇ*euzC<󻬵4%_3W SuV\Aex4L#DQ*lNbu6됣 'Ja|1Ayg铴һ2${TZ:]]bKИZɚگ{/YGb-?}a{ 5&K&mJ"! m"%W<̭\r6H%m_ZHx e{?p+izDgݮo|@8ѭ$8bR#,[險*A PZU7M׹.dyL!!L:Xs$$lvuiMK?nFy\x\0繹xlPڰ6?}4J9 ^x UӫO \p81PWQWѳGRqc{ 2V1~z+ۉ=gAOm4]o'+o4,w{e]xi.%T| er!! [}eTPZ9ŀCVp^iq~El$bjUu55Q(?U(ಸ KAR/4mt*MTIOu p1h9\9N#`#R/=Džt İVel)eԃ9T3f}G%F7˼0{5 ,*1X~Ձ`DEy=YMKr5CmYO5 ݀D̼9`ϱF1/dKw\ju`a(` -K-}ќ6XCtk_LBލs>Ǭ㕤 ɁߢG?z%ØlT`y'q3!}q&!(v@D0î;Rb)]y;I`#C|Li<~&LfN՘{0ђSg>{ь]K}-u !C|jGPxlLtB4!˿3{1L ,6ԵcC'E~L5Nx!I7XA \?.+0Mx2ADT^C@FQ4_t[uxPz].qy܌^A9`uB+uRͬe/~n1xl 7IaFqEJfB޾p لDv:S}LʉIu@Ec4Ѽ؏tY] GRvDgf-ds^<^3jy'DyY B0Ӕ\B7-+[V߰Q]A7hV[w1hpZ}mMlH94oԀMM=bv&(qbt>Ls6S{G>I~8vU5E]s:{}XDF2|1҃gm!<|tÄ^8%e߳Q|K|#q:ΪUExqbv'e0ue^$∜Qx9?^}0AД:^Ԕ@XSQ/7}c,^՛9> aIo{NDt$pE2U/erd,JKfp;;pǖ _Xg:?}MHSnv8,Hj@[?s{NRmxeWZ-XPR~/b/; !fF q;^F%˳dN J$g-"+ -.&R\`SNknp/k(3lNuDew]DcYvcO=@є4a Oui(fW2F0Ɍ(VjN)NC$y^oJ nqQR;`\c\' th晿&5E]d`Ynӑ6x,kF$JP[9>{vsM/wwiQeиd=< Й~>soDHΏXj`A{7F \k",tbGEa%ʠ`qQIAJ@ҋR(U;9l:d$jJ\"&3Ag "UEۂwa-xWq7BXԓ+@7ًio@dSKY2x1_RȝR2+7XyN|tg2)8[oINDZ,8vjȯ͞}{s6Ċ3Y KZ_N؆G DMP$a-ĥ3@0ւ!LQ]:,(aiDΗ${*0Vxv߈v]+6JDJM_ćh@(1y&[_yv˪ bԠ1xBTo!#{X^Eȹ.FqcvJ]Y׾ x\$rшaO޲~Blzce{Rko&:6‚*~iݢ$&.-`+ 46v4O!O?i 8?Txf&ET /q j,B\Oq[)`brҎ2̂N/ˑ[c8Gn1 *s2QCZNZZ6*7V KqcP#/rrCW)'kQ'pA[gdȣP #'2v\`I'I7ab8S"|"m#|yY uEҴ~/c}CNbEIve턵k^HKy fXWfZnǂw{pXF9BBRC`{e#Gf_O ܩ3tjR'iDb<.7 6/̉ֆ"s ʪ#ˏ#05U1f҂Ԇ}8?M@@hfX\ZhbuޛTTmO;UnH3{:Ogt5LS5#?w !nӏvp iWR7.WzSӹkiG0qŔvx Z`nX-ýc@Ш`'+f|jkſ*tb5I!؀(F>jLfI.8; d~œ^gײ"֬6\y2:,hk1IRtˏ ~@J<đ8яk(WԦ Ӆ/ok ]_B]GΥ73ֈD ɭ97O?(@!KÚT8>\_~,7躣=Y胱xr8&D"k#

EQtv:QҜ޳cf>;k/o!f Ǔz(Z3۶EeH /?&f ?3FJfbܜ}ԪYm7>dTcbsmNgiPAƈC~6mTtϑr'B*PfDI3Z' 0UH'5)d^8 &%7%GQC@!/Dfڙ\ i6,dm鲞Δwc?.Yr.Ȓ9c>4#J8̣ l ^FfRDmeu>1s39o- !ƜP}TB>CKFtqV{;Ky\ިtYՍn(woc8,ZӨ4[3կ"y.vM(艋Z69I>R> 5Mk7\=5p_BmtA~,'bɇJf#3t/0O"n| o\Fs.k#3~n9OPs(8z[Pn("|;g/K\4AxOXk@pPJ rߖ$8lo;r]ҙM1A?◴ͫoA/).ʑ))"F[9P=,E 8*JܜAp_u>|!RΎ?yiԹD;m$C9l-ݶZDϸ[LN3.loaЫR{ [g>k`m4p],1Znk 7+М'NJ߃p.D2'LlcgRL!DzYri]¤# +qAco[$FS$CnެYY8hsWYk; 1 -DQ2$B;ěl|Q0u4zK&<>90D8#t+"b-nj’bT'ԣ#m_]2dVjj h'1CЬw{,*1kHyɔh\ .8 \Y(OYDJSUgMcM9XDo-&*Ũy6$+>+sMxRU){;@.?hAɬjN{Y@VVM8"8 | 'be}$XNԜ՜mkgƏƍﬦP^- ~dA D]êW׵Q\2F+._fϱuO<$\nʲd6a3W%e3З@7I>L["T^͇[i3L—}!af{K[ g`P*{e)D.?O[.e燕£L+&z* Wg0 Q˓]BSeI{:G'mpO.86g+y@E n5܇SY>݈/&~:l]^_`ʕD>S'c\ O;"66=Q^D'|4:V X)!1̋Q(Z/q1docD-SA*zFrXYHW"6<3i$5jA!LΛw׹ak"{@cڈDp20#͂Y(-iʼn$ss$0>Pjuy7QH(=K nqtmA([A[ b9bm[k_ w>D l1R5WK5he#OD׀*@QE5;s= /ŹD_҆=^yUtZܒ/ ~,dй+!NN4+foY9X,wBq o@o\Ls%q=oǒ* g 6?rs4RxS%Xxx0e{ЌF#]`ڸ/?ˏ$9xF{ (_0t\DSG]0qӭĻt.XΊR4&K@y#H@i'V/T`8P:Aƃ <*"{kbEn׎5:oZ)UYPM;|DY}VyRq#.59+@Hp-oM$((Gt_ܔTnocЮf^.wYgy_!4#.XyaM .{% 쓶l3ð[B|w~h D#\I(.:ޏ? ]Giy<,+3wN'T%BOvF %К0%Mչ۷lLuP\PM5ƗlGUf7.1{GCP-r!!KivӡE ( ʁBfr5AyǓllA(, y3NUʹ{U=?@!ͦбᓟɎ3 .w^;]j,x_3K.A.'z?gƍ 2 sB~"o-pZ?,;Ë-^}=߳.gk^ٲIRF/n-Z;|pL(P-Ϙd+n><!#j+7d ZW7箺ib[]dd P}C`_'Bz"tЎY:900ׂޠ_02γ$١tg=M۫26i)b6$/ɉ+OO?I,/_9Ysa* i8 ;Wt8]R6<#?}Qrcߌ(s^Ck[YnHκj)'u\iru 6! YYqSM)2Ȼ@GQ\PxC]9謖84աI GK7A:M*j`} d$ᶚ6ڢCYZ~EWqJ6-ӮI/8vi_R/(-5.ǞI JY@ukFdRXSH6KMҋQzQوިC\ieF.F4`99vw+r u§yf>hJȞsZK~ĮDVfh+: ,\܊H֞48 >x@k3>'⯣0>hS(N{kH٤w{9pT}N^Vim]k}Z h~N hxϳ)ԣO!&ɦ Y.q@'OSQ#t,UԿōiTTt\dİޟ '8_ tu3 k[_=GRș, Xd8%g֫uޕ9v-BA{DA\bnvIw-fz '[ &_$sȠh=3/-W+:& DX l$ R=12ۦO!j2DinѼ/1[6"9[tG7 t/=L::LF.cAV5 `j%DŹW^Z~@ѕ!cvEo-G`qI7(N8|i] 'âuQ?=c=C]Bv8z c&0]aP&qZB:ΦS FJ&0?oO$}K?3LIDBX Gi/ 8Ș;?[:!3؍*!O> ؿXbN @48';s {:%jM;64~䝫b;tRa«t =3šy5r'U[sg@z(E #gFv+NTWډ[E5cl_v,50Њ{u +tӟOu&gȵTt4#,MbU06K6{㿥mmզcjD򏄛Ȁk. hW-O;DѸZ@e7??b,ϻpGtu)Dߕgwzo9Fx1(>(qqa2yjKj֠=W3jGaYʒE{FeQe|O?JvCk ㌬R ?e) ;s\CMjs)s {n%jֈֵ]}j4!P!3v%,/, gg+ R K?%п'Wmj!~_fj LSBŖHZKEy(wxFgLj6ݮ$W 6#}h/7~XgM9CKʹhBG[pTGಿO{|f,qnfN$ 4%G%&4h;1 N)"|Z3RDc/ܭJnPb%0 d);KpʶB(ܺxSV;d z E/A稼•#e2gR6 (tY $Hg CkqR F/]M<=u7wL' ,)WYiO鉾53* xyg'`tm]?8zT9)>2ƃ5?嗛7G{2>~.zj|L:J]fsywsj;5/{ՄD4+$v[@Ϣƽ_G*Zzj85 eԒ(mw>hk 7޷aR˛*0H٘MD4|fs?>:Rf$<LR:mz] {C*7Wg#2-+AQ}N$k=$Gv'D#iw3$1 Xˢdzx >)ś%ewvg. 1Vg39N 8S(Mܔ\앹 bXۦN2RJhJSL30f'1OɇV,վ@Nf[ G~-١s#h $>)n"C?{O*OfAƛ& .ʝC2WcP5ʜph=&!/DMd8˵9CʸbLfPz6âYxS3LԿ_7jVEySo~W~`PU2YEC='>Pυv]ze&W5 MHZC6ijѢ;cG9\M[76eǨDKs#&P'2z*}#X$)8uLaDю`\MgIյs H]'Mh{qIԭu7{Ӓ5>FjtIk,4SO_~m&g*v 0"9~>%xB_aFʩmZ-Wkӄƙܿ*wGd]cD5܁gRqFB$7`+*gL6NAZ6C;҂S˷OQgBIwQ6M/gI\iDEF'98 n^C9P)xde a餂Y^4f1OZPt! uj@{V"c R#*uĕ.19m#vM'Nxhk:J壣Me-p>Cb{<ƕ_1%>p `4Y *hwe8jp*{c;}3Yҝke0 ?xM,ԗ銵u4A<5/Vy ۳)*JŀcJE6(_0 Q kPB<*ղQy{JR[;{bx.B7ύs+tq[>IA, aK,#^z r5bǵ4׎t%D8Tx~7lKH%#ן5&0XM.4[ :Ȅ:rl١}T?3G;{&?c %&6nXp#mqO8tEDզ)o,̄U< zPY-0ɵM rN"$ñWĹ孞R]M&P;No݈/$ZɾeMXNڭ,(AQ5k78tt{\S3$KKDxG*E:?rej@3nQdHpY9G3B!BTba=|! w ƾ|v?[D7nk~)beAr{ ґ+H.dUapu9ts 0\)N/K|v#Ѳ >r!\"wvOK5_rRuf e[iOR QWXDKL0 =Hce7۽6cB%+%v&GI+i´2Cr19/5>^fH,QSNeb߲pޛ~L#ht)f/mmvSGcMt1# MmLg}~k'cXfLȗ )T݀6C#Lrԩf M qv/+,9imLj?%.!I -h 4jUpՋsRQ $ [[-UFxq9t`g`|p,"r#:rMS2Vg7m)@^w֒{kW,xU?ã 0>2DRҶ~ox$q=UMew㟵K_4O'dj.el~XH½~xw!_J5'V3F>+pdMd扼F=67 qa;6R?X>(wX8;Y@:v>75$u훨1:zEѾ8|h4Ӆ*jDnX溅˫5|+gki ~:pjw` K@ުBIi)ƈ.Ioӫϥnx mLX?hӕY/tIQ<p-W.I 4@::"{kC^V(Zh-5ch?:q@ۍľEg4,^qIBL/!4P1ՊTǍ3ce ;47~5\zxA&ؘbYV\uάqEM34 w_cgLbj"gL jUaޫ{re`Kb^ptk'qN(Cߢ+ND4Z~#h?\PuWi-Äo3*Ϧ3r" p*-2yfSօ.1 rN?ey^B [{y{kdYW \Xmeڸѹ] Ioq"cBiOE|;!%EM:/&k%F6ڧ[vuSd{xw1iDeذkDn?j┫8 (]DJ.U^Y8%vAsU#qpؼ%HKU8yRmI6q6VɳkbL=?QD5{YG`D굪(atɰ ܯy,4^!D9L]۰ӡmѩxxde)RlzvK!-pKbF NOx^k݊ W_,>/fgk j G ;I5YUk9qt8NU7. 9 ~UjYN)aPw`,p8h78F0HVn=^zLQM%)luip8*W҃; u1s0H'iJʒܻ|}rCTvH&̏q'a<6&q:Unz}d\E;|{LwpCbq){նI/蕒Drt{:I_0uobeCM"O/4:($l r]DD3]4EUDPHyE,簝눝(/s>6Ϯ۝Vdi< R;l ć uHP Ϩ-غM$p 1TG3Zóʣ 'I>n! lPɨ 3AB(KυQ݊X$%RđhV%(A1jPywkLIܔ@/czk|׍sW7╉ .sxey%jO12RDY{Z󹍦dDCl/EdR;"$(惛 ܬMS駒 piJzөw4Ӭʱ%.RN%^!Ik2Wz,N2i` .OD|%6 Y"]n"\DR8cXVrCN᪙m3}|13ܺ#;p`qe/qdbص+:t27:T^ƽ7#)Fr~#MjqM @ ~;5hsYD2) / L "ĊPE_0 Thb52 ko1l`n{Q9(pi$6b4|Ť*%59h67;e=K Yz~_u2ODziQo'\h9#}Mr@(ŅhկJʁ^tی)&έ--Ʒ~c3g1xsXGePiQ%YfOURZ]D:k{(N7(-KїJWprrȫ_6+3I[2(@qbScn'un=&b* ӋqGkůV7>4CHthzC) ȯ uXZ[B>/Cec9f/onX5Z%&5BkJddlwX /r|h7^.h튐?@wuæ 8 U,=pb8F?uI6d;1l<_΅6f%~#6rUdGOVJ oruSAEN 4F!ndh2j-t2wI Q' tRrOMmK~OK1 ߀N9MU]4R.~N H(AZpC[uP-tN|vT|[cib-Y mY1jc8Xl)6d'@p:,2 UY\= 1Xafl1A9[_chHTe˽?m.q r b AxPPE>94]fOc ^> CJDDMIu4Lc1P.PR:8 z*Bd,E:-viӷET0њ1HgfQ»„T2 QAn.ω6yZ!X"gW笠V=Q9CbI"׋ صm âܩyJH! [-j GiҎgW(y?5u?/PKt/"&T1ħgXo@nO9د[1t ? axwYE I(x6зZ[QAپ y ]ZKI_Hvةހ1ӞJrM% s@9WEFhy3C 6n@p9h=D.Kj+%Sg>Eͮv@IhQMQ`e: 9+!a, `]J3eJ)j*,Հ_N=%eB67p2//$ W_iٜL^&򧝭P-\`Dj_C.$\Q΁b6e%lOqHPl QČLD&ͥVŹ2 K?J mV0u0IӶCD45ɚ *,n~*zc$ 'ġ=J…{*$1e.w״ 1 7NG0ygWw{t[u5(&7a9H_8 }H.-"KǝwfYF rj*L$SXOxJ$5t "ߝFeK!$Ux"v .ғhmZ }< `FzNlx ?3"w~ް_y{M$Ȭ9وc\*U& U%'9hA֤= &_BV̛FhB:ϩn@:71L/{Mjh9Fd%L,Qɐ8W5NjYi\FUm?ذ욝wd6/ەDzRз^]VůBg˴;\xfH yi;u N(B>c]lP_u\- %a[0[+}Z;YUZ􍔬\H=alC4"OK S_B?QM|)Vp(2ɁLs6ЕZMMO*ҫ—QT,ѠvAiNIodfȗ6Ҟ$.RoY$޷!s>^h E0,nKVFXKs b=fh%A˂Q#DVuzAb?bM*6H}`{MͱP5Fn}]ębn-HTr:Px3zF@ې'b)V0ϢWe'~|b[r&GωNH_*Q L46#":өFڎҊqVREkVΝ?s][y*1 )l|> oIOaBsfİMVح"fxϜwQ EA,&@ex/X7D[q{dAsd8dL*/ߥB\eZ< >lvވK|rGՆZIlz)$kQ/߂~=on՗ϐ)sH{Y5}xlh>>Sp+çɰ hyQJr};FHg:GRP)|KN6q [naCǬ&Oƕb/;T$%/?bJR16EJV_ `:]-ԻȜ=Þ3П3F]R:#(2:04p,CZم[w nmœe+AmS^bgA?MzÆrHs#ޔ/ZB˫Ds\/ k)Q§sWj~;ZcaӖ`SZC߄g1c@gr~ !otu AS*OtXA%9&krlE,هZiv>io=)?UZB"?oxR:[В,-YӜ|/pN۶X,U ]>(*w0x0>_2XH  gA2g+2~{dJh@ )iQyQa*zIRC#9S-UgL͢b*.(^ Ԅk`a xiK:: -ߥ&>1¹K(" {pP6$\"VqA:9>V=J8tn0')VH WnVG|0F..g:A6ur u"~MVS %,_q5@jVc1㎬PDE OЍ2VpܤSbN6 Qup8' $F,LjL*KawusS_S$ӣ+Z H?E F>+:yn>W տz5cs'1XwJ~?(<.&͞DC E^?*'YE}'0M _&L%'K+KA1e@sȷͫ&CxdI?;[Yd{m=K* H#HbNX~JkQ0g'Bӂ}nc!&V;Ha&6MuOb.k9-+?-6Z| |C_7) K54G) AuNM6o^!L!wozƧG bѐ qs!}aּN7b"0yu|,}>A7%B|󼧌4fjQ;(!4W!ο*m9J76OG.pcm6G*pm{'S7UncLg<#ļ̫2u<ƱvQ174091SoV_#)^|}0eiS~k Tz|D xFgo;1chJwXΩ)\9Z‡JJ{9̧&G4վLt*zJ/gڑyd-s; bLb\9v2Fە& bmQ>?nM}Me@:y1,u֋z((Ux?i.גz*Ʃ?rc4/eu,iϜY/̬3 K^ 3omh#ID קQr/3.BPRExj֗l&r:]WfCHtl7@."8JDF MlJETRΤ9. EzkS.r =E>l^)\;}g9Z~LO156N-G; "pvHm0 mC8phB39<&uQnKAVB!.qQ 1h:hԡGU*\{&lfW?!8jUs%݆ZbO t2k4O>v_),zPz(%/[af8yo9 jzvvhTkZg{ קJJ@1̍2_MwFէaj{7HF TƓ*jC|\ۍOm ( 0 Ycqz$7JkX#ǨH_E!ycr.Y%7b#g9ѷB 5LJq+Nե oIc"rEڡ#' nז"g"uug%:QYkL5dcDTOT[ޅ鉨: )?¯o!cChi0w/Pp[JPJ豨Q_E{j7»DbMc}Г,/XzɅVeUqZ9a2 9FVxO'=hİ$x埻' .dHv۬Чêvږhғ4V1m蘾H_)DOLĂW]㱋Xү`tU+9Usqz뮷}6`Cy`?bd ,&EZ.sV43w?|Efx}D5lH\w!*MNzprlYid٪4 Y_*4P=҅ *rhj`:ָK;s_"R/<ϖf=u!:e6]A1 [?n65VaUo{}aXs%g?&!W,{|`mkIA;2G9]ѕY7Qw &HOH?"c!1/.DTZh71=`?YڞoY2":'Q"^9cXSnT#Ӥ\O@`D U( 3ZCH[\Kx\#MܓV|r!!5tl{b vGqFq/pi|$8!S^J*b]KAkؕk@&ِpr;z«vw 8Ce8Ϭb?;:O`cE`QWr<9t4PctF;zuω^]eag & zOavI3u{Dō¾RWzBkD3K*a[x&zN1ιpR:.Fo))D3A/yMfoLNzWCifDQbz@7ĞRgi%kZr-]:,q^fϜz7̴wFEMI/pݻ1H#к*|b,$H<Yg_frKv>rBpg/QJǒ+jSrRt+0"~Qĉ>)~8}:;Rd9$cHkϽː2^HİP h0pb: {'yG+B!.8?6/#ռeէfQ_h֏?xs[vl.SqT÷z>y)eI~`~>i'b*^\Sޏ\HCg$CR5)dSb`1seA<÷rmUTٲAkѢtDRUg&L!um.e#vG_FԳ8aUsVxjjًi[E!cpriF/Ɲ8S/ӛa|[ki k([3O0Ϭ ^'- \KYahan!Ѷe1odьfqc nx?pŸ jpkȼׁAi=v[OLDh,Bb$w9mV{vUAB{'B~iČ}h!tP)#00f+>~RÊhM2VLNG>=)ۉKQ}>(ZJ5!3csc+> =~yX^ 7Q9H/sOؗ$e z*ΙLfUg/- @H) ~&аUAP'CU4j4Sڱ&5y[;ƽ5:ǚ~l=Yc )cwmh=*Hy]1.W*WktLʔ8R:!ǽX09EQE>RpgcD.l54rsRKJuIT@ؑ߹rjq;٣8zbV{JIt.iF,8 -gq-"!Y19 '`\̤^QSjo$á(/#tKNP_Y5[|yyݏMnhd Lȹ.rLK*Ay@}]FX87qS_hNh)M͉Ӹo9I$Eo;xu0Q*Λk?k8Dq8]G55(Cq;\Va-Zvn<jtm]Va+~V+#.մW9ޗ|T׼u(D'$ʻw^jn$9S<2T:ƃXeCVt5DX}&„ E/K*\!Bd2!z4/* + ee6qt]j* wIDӖ_%oM(2\Mzy~d$WdӃaKOvTZɟ't%_nfZ."jA8}i*WMR; Ys~?It1fYl~~j{&X %TQab5 b7S.li]ׄ5yb .M͜=*'sp(eѰ&gPu|̉# 8|w83Ra{pFYK,|ZO;"ɻIpqg:ZQ%(Yb_66 [tr*O: ߈:Xc~8HŸb"9A<=kRYUk`p!yON5~Kq:FNt)S=Nwǣ1BSI5gN&mȜN~L ;&ަIywd^ oP 3]edMft 켚Z&q1%eb$Qx$_hyIZk:qҪ7@Z9visG|0J..ǡk?  l ߓ2)wZ!}HěD'γK,)hQ㡡K|']HPt$Dί`]Д>#y_4,҂FopKd'6FO ־l-AV}Y!mp.IJa:1PҤ k7qP]?Y'J Gg?YuukLzeryzqVn 4a&F] ZS}3tyjGGc!1Iҷe%s|[R& TEcPA<-C6wVMSs2~]@STzP=. #!1`~FQ5}MxrOUM2 Z2YzF(f]$F F^NrU=,!;|SӋ ϣE9)3ܨ-zfsa? ^PP0w"p S+[w shu=׌KDXteHa4X#ZRv7 ۋr59g`tڔ! D=m@c|X~F@%v̥-̰el t2d/}L{c aC}!'eJoKpv SZ*SA6)#ԈpnWW\ry)b9СfNFIL"8YVS^́1VB:.M/91U423Q~צM4^JN/^u*E*qn߹"zʧgF 1uҟ!D72F \F2d9+h p$ۈ:ҹQZ£,ᝒkM6 f1)zdd5.hyOK9ϊBSwٍ8Ri"C0mgfl!## lN~nARta D+^" =@ /ʉg+]/wXgdCR(R{#;vmr~=´8G8Bvb}0a X3toݜf>?uI=yEܪ*Of_fry7~a)3%n&$ [WWX/@P/Qֳx S4'$VU"2q\~ynWjz"?Wz)đF41o9Cz3ш'W]EX6йҫJ"WuEUTb?N\c ES׽{Y%~m}uy:65Vé;#ǺR2)h~ftkVGqpRtҢǩ:XMlj:RC~ܼ{$_4[  At8DձTѽbKC S)"lŰX` cU^zAgukwY2w-=5xo֮ ,,,,,wRWɷ1!&yԱ:'1ZOi{>CR|]!ixUݦEH<5Y["z!0ѿSڱ覆DS hj20;ZwZqdCqLLh]-R{-34ʥ)JS jYk暪+R)JꔥV;m?ʓΉ=O;5{]4O/ϛ[y\㶅ؒFZ^⁈,::Z;ʘk8YnMK% eh+|FhיE+WPbQU g"|qv? ]kh྘sYzLxڕGyiL±1t޸-ZÃB2Wc\ЦYkAQ=|ttcx?6^B%,"/:c pSѸ_0K|I9lkJYRsa3Y}@Yv!w ~}*#PNLxŃ0"x9w5 MF+8H=bAj"~m})`AfOD"^>D4bQ I'xFL)Oi]uTo\R2[z}ފ/T+Sz,pyE-’5~?18oM_(ݢ=QNO$ R>|:wkD5Kݳ֣ڒBݼ`coH.@y԰p4_"%r 3Tˀ ( V9;LTXL݌;I`H C0U=dx̊ĴJ')Dhං Ta8_7 Hg4;2hX;Ç+!)Cx+4~ެ[S+볬ɉg3Cc`hԫZDe7s!w^`:BEdmlsb҉^Fi\v t@oϒm 0/V?5β'`~BMɛY!5c ߨJ&Ӄlj6(?p>(u/US;2|EBa;Ռra;'}Msm豉Ox5wZ>''{x+CO"".OuL*RG%v8WDq+; ̓ A(k{e7xTs?BZ0=Q-^i 8- 䘨a(4Oϧ6*NP2sRԢdII&qf 7mL0@\I) @R&) @~)|M\ےSt0@ٝ"W __X>QѮZ3.P矯~m ̒)?C3>QI06@ ۤ.t2 |K֟R }[Ͳ+ot큿l}z li-uy;Z 68kn90h_68Qx3 &Vb1C!G}{ɣڠp^hy6OG>i8\o&7qc0&T/aN _BGv<}o%qV,<4qS}L+2cNc[T=5[gtpCM_|)6+'raLj]ʮ*PGpO]od G&')"h%vkR5d {5>Ϛ󁥌NS뼶4Hp]:Ʉzj9;~5=f*(!\e.,ޚ ^[ĢVlɤ;0J?SEXSr(\#z]æ<=%[zP*E)I3ԉ򡾴wߩ66cb>V%{;SFF.*L8cLCI<5e7uHW.J t0(O NXo^,Q \n=i̲,,,,8O-ZꞢʙ/cww\؆.֚j}twYO6cGw]ٜfL% 2 &x(|2C.֌,rCpEP {"L40:Ioe:;GyLQX&B@k^ }#l=SJc"RDLg1IJSpD8?咔~e,~'NBlZG8Vz_2eA!1t9J4v,n\IEvGӃi\!}rj}0h< OgWB2}ZWW'+jOKc2]?%~1^&i\>ey"\v/[f=mS^x5D'tpѴ͚'M8>#@DޔEZ޽9EDh|r87]]O\Nars<}FO:ypnu/'B22*w uj ]9=ζòՂi73+q_BHplWec*''^5Hï\iK$yB٣Abxzt:`N~hzT9H e;Yi7Bh8rȀmG?lJKNsQ+$j&PRY]B-<ҒLn6IݩvyS49i:zBA,R֖WImnPC1GĭnKZ`TBeH[x0&hXr+ .)C9["Ȳ湒;Y89n/˶D<.1c}$J}'0Ŵ) (PB (PB (Pupi`_tt*c5>Φ|/?#s|HQNTꨴs`+zf)a* ,wm#s@g d1^|pp>][P|>OqG,Uii{SIeZ)XgMJW}d2_ Jite"IYlI86ck$S%S<+@\xÌqNϝ&3|1,ܤL$Piqm!qR81b6;iȷ=݉LȔ_Y8`l;Htyeya sCO sf|v 3L%DW4 :ʼn8ڽ+؈:R* zp#$eBx֬5ԿPMh {l+;S4L:]`$EHةU_˸֩JRR)U[*RH0` DNDc7UN=?^1kj^AChD&-%oT#gL=!|a15u&Nd4>z0UTZkh2yg 7W ,O#aN wV1k$~ՆC`v8)EгM]UP{*{/2}[sQ' c\WZ~ w+@neL<=Kp-o>m a7i詽1x>h)/jǑqFO*F-Y߿_vNvm/V+}ÙΡ)pL(YVnP!9-!bkĤ\  y4>E @'@3Xyo Q +: ?3pį:!q[x$Iуo'+L~ m"L/uPAY~JEeV5(p2\0IJ!.eO/飞'{x 7"U\-Axj&ͫMcI| &H!NB gJ|%#) lo <ތh[4}t9BhyZ;*L %{0ڳTjp0+W.7IQJSTiT4Υ)"+)M^]Lv-ߴ~D8y`U'37y?N!ՠAL!7AP[3mdR7mHJw+i6 ".J7cnFqkhlY8U ^jž.VW}Ǒ07ߏa4QqV~T2OuYAnMKpX}Ru_[qHfkk Z;lӇǙFhY-A%4sqsy)'nYX|^V}lM[t%x:}EJh V5f[Z6s«*3?vfplܙb*k쏸7Y<DANljl!4M$M^:l|rcj+ohOUcz/Z`]&ZͰl\rC  hB$G֞4NahtzbXD'nQLeVlI5UVS(%D^ޖL;xds۪<){]͊=7UvK֒͘2~-B@rN%AP2'Zj|āB_DGq̌M6:OlCQ+)ʩ TߝV}CxTR hYY$.d9L̀}RDXRCRM"ի^i}ZͲ)J{I[ Ѻ <}9,*@lwVw04ߐKp:P7Vq/7eՁB;~%5!P W(Ús-'!'nBE%'+ chPD_6IIǵ>||Z_@x%UL^ fiu:T?q'O9iw;pʼn" (SE@pZ'ZQgZ@еrBtJ6"D 0`)~a֪Ug(VG D֠QJUS`)]"1!Ne% ] Vdu>lkëE |DrgĢg˿̋Q40:,W_hHLqTX<7x۝o1vޫ&4בт\FF[:ijP`D1dK[`ȸ7b )So^Lꎣ&`|[0=vJɧc"pen !WE(44Y JO#MEEa]&Ѝ27R ^? >D?z/_0G.%#FkH|<,>{}#,f e/rEˏjr^U>i&Af!,M!t3$"|$0Kg;jHgG^? (> *v%y?1EWP}|Mpu#:̆l1mSKAK4 1~3}-Jnu l#80=Z쫚WY^g4)qB jy yVwcYmn׼ds*4k+g%TJ`z[$46f~D\r oecs+LwrsPļzj/x9jt1(Ñ :'|Dz.:?kEQrXJ\mm H%򅉹?}Ljmc2Ċy1L7ɒ%[|QN9FH0ޅ{(Wݫ+dF?tbsSTN0d(]6Wv gMf{ב"6.EC#;R7U~\d{Q{#`LAmW[ NSmNbc3~^Nz,,,,,1}OdNh]q>_#\#W`W"owFCYX}/ XQ ]"S%.ӯN|vYՌ/Xn~K__O`@>V]1s<j2Nлn?g])R JS-0Ye?JSAJA=DE;*qצ"OjTLsS^Y?2tw?HbCnS;Ј,C΋ JJ%r0ߤeվrT< K F[E1Bc R N)n7Շ!'竰ݻEU(p+ZmX0j0׹8Ce[ y䩒PCUOPe- /_wYp;e};I5wFyɏzh^*KcK_k6Po ɖ} t8ko,;d9 d Ut8P D?77cb͏m^I+(ET1]^zbY7&i6EVtK wUQPB扞A ov=?%m}ưk-WCֳFIp3"'Y26Y=ڴ]U_&G/>q78rsOE\KZ3|MPP2e y _g;^aIX#z19^=LULp_*=CjFJ T}kŷ\o? 龈h@ܭmr]CdTY\򻆹kG 9@ tPqDmUJ2 b"}IIH9c2VH>M)QXm򂽁x8fҖm5y5P0=$y<71ڰ6, ȱKu1,9i5QF2Lc(Moh⤰ QLɏ@)2rʳȔ@F;?"(z? W.ypװG4/x?}Y{ m#8Ʀ8!8]_۶of} ?Cäa5ť ‹- 1uH?Q2Z }r=F5ih\uW܈Z#H,UV}Ԍz1nЭsbDt!vƁ:tK#|T,⨴[Q/s1 Nd ǰ< }fj!58XiB &.Xv7b"CMHyJ,B7hb\Ib8f5)/E//ҳ@R0>{2\a,-6"Td 6$nvQCgtlB6lӧ$>ri};I8.YD~ǒJC\I#gȬX!bɛ61x+&EgiµhE0N&{䱣JY'4 ^OYޓ,cod}[H8Q$،Ru BJ(U𘘶HZRWD6>JB|)!@;>@ N4k|7[h ~˞<oVkg٪7ok -ʁZD-Gx]:D앉@|ةV\N^ςX)G f=tp*d.)iԁ?ܘw64ﱈ|*YR9Ǧj8',`;2!,@͒%IQڿRnto)ixv2n DZe_7} 2fewG7RFxΉ܌9x ꊹv"`ʂ 㜤%XOy֣M_ H_lvyuB3gr.e\ TWnq\+3'_*n<g_ݿXB".ގ+&uVMsx/ӗy6iɿW'ODjOj V괇b+P5fDVak5Ow€/yҠqO<jAԀF; C1u.=+8dIJAъ5"T5ohN_f쾊!pjbH(VHs ڹ#z>IN\жv~T8̧@M9cg34:od-LpdKk)[*JďVm,P1!JYͿDG(-ŜYKv{oY"p.c{ ܕZ~\7;{? N1v6FWt޹<.KuC(;b PJ?cIq1ۢrp?9dHg *HjUKJ.m7DpgL>k`-+HDʴVF[%%' =~E@ܚG !(*_T`yD5#Z;M u`)KH0#ױ}:eyDVi|[s| ~ タT+rSћ̕=<9֥$FQ:-^D@ YK u>쬠n5䡴 yj:}?TWLā\/8ӵ ~ ivUlGdIvixf6֑YuVkb@i7b`Ƣ{_gѷx0NgT(^ '>aRwm@ns-rU.<K\6ıK(MLS,o8}MvKr"ߡeT^Iؚ*/+/dz:ʹ$~$RLqU/S'2t!edn˟ا0@Ɵ~K@}mTSDՋل47c$$|'XK6ϭGt lPQs}!%>(`PUJצ8ZnFk:Ǎ\pbRBv_NDo28KW:zmjV1f5mޝ_t]yRU7|֨-PlĹ}}+͓߼g~4%@ݛ {+]RކrtJ %:HůZE-y1asS׊V.y7 . "J_vbrSz(N^b5?=VHrb(6>{C2'*rHJ :[=re)K%-| dӈY(({rH]ӔdOG!]7S-glE.~WD䀄x^p >e/6y(v>M ѭIx?;Ynh؄GmƐS\:`eq8jso< cF.Cb&+/STzve)ϋ;f x(<%+!}l q,2((rr^goD[2:P:zKiv|dY F Ӟ_ T^w. #˧eA#n0Lt:PG?3fU{4RzjDs:@ii[`>zh;,r#q+U}2e6&X'}rHׇW6[:4c\ k@#x7J0So6+mc5F-,ݒH2p00[8:*Sjz@&1VN絅>)d|x?w=CT>Vj*A-=Q+/Lq)o4*总eЇ137B%iE1 )^(.+3aM"S2L$GNvP2ӄi[߲>jHp0"e;ua{a!LD 6Xbn-Mi%^u3`TBTr#G%h J.p9D8i}BH"-zzrsBCɸ-#p`}F#ӯ>[NB siwfɑl"Q|h`^-O j{ݥyfJ)ʫᇕ!e1%93myX_T.2AN-%LRVwpկvҵop4<\T"{&v7 ]xepx=U*"-<+&j>I zy?}(|zuuÀR[-Eҡ,LzqmxCraH25J;'H|kT#@}vԆ2ÊCxeМey[`Ad%X 5[Ei7\\'ݖG?h) iWdg]N4QV@V>V'kדzG=+5+"[D:Kd.FupҒJ顣juIJ$I<}_CvbŦu7I A.L&dTcepTi7R>mEFJA[1c/9pވ5z6 jkiD),]ڞ~$"Yp4imF=8ykU*a? CAphpI!+xzF]@ 1'xIс0Ks;=vm{%@2лF0֑Oԫ<[;+E"y0ވD35(fH\]\^$UyOHd"@WX0lh sauzѧC?c9ajvj|,+``XTbz|BCK-k:yX!jFs^-ٮF_uQ+fo!KfX@kx}|%\&f+CJmƱ5ocgl,ƭX+zβ'3$wCX4s)TuJ|X(} { {{.@ ao˘B)P.[x˜P[Y8ű̲nme~7?oC Osۊ] i7Qg,RXN9ntFQd#poxxl'x{UhZ7ܥc`f+= >y 0WZQu]Zh%•񠞊 ЉPG@R %r%c+`Y0% { aKpЫR;+@LdʤdWy(!=a [xpZ8Pݝ;sb˪{9NDڀ;R\+ Um;RѩcvɁ*^Ī0ϹakYyY[Zf:0^j k 5ԑ;K@6/މ_ _ AG;E#灅\жpcj@&T7y1uOΙe_eWUޑ3p(3##užn\sjh]}[vRm>}#mˉB[79M{fFN,ZVKH\{㑮aRy !Fߟyr w13 lbKYnSΆRjC$ O IXX:^e]g+Q+ތlqnJ``@VxKɌ`Z[ʥ>k-s!YOW g.-k΋]ij zMXbr J?̊4Bie{'}ޣ6 #YX+A#ӒqYQuIh61LYf[9͂Gs6h+x.m'xܜ2:mlPl+áb U3R;@UM.,卍oi6\SRs:>l"j4/ lz1Y+̡!eV/*M x;5r3Z?[#RQi9M 7< #Cas½ -³zRyqu-Z!=L<ɞ 7c+sF>%  ω Yg$uLcLT.DJ ?%9Y'Yq آe N5c|$UFOhw]+3SF=ٜZMV1s &+*]X]B#Nc`PZϨeą3BIvwV71ɊTn=$ib>!m /j{{·6`ߴGQmBQ_ 5D n}jxyIAz<]OeiȬse~FIC׉8y׹/;.kB:n4/µp #խ0 ##/fo Bіu'< Xݤץ+BR7︍8uF+O&:/?H$b/L=M{fwμE4}D"WC~?|%9*\)sK/ƈI;98=|o#WO{4™.;Fr?bN]w/bf5IWn"3H8mx l/(l.\GY(ʾ㊐UE_ Q)蓙#g?hƣ`E A.Zi.?xm:TdpJokf&!sR D9\/»o%~`K''trhsKu>>I5ycq :!*oVm)v>nN֤KbL6*ˌF;.FSli]yiJ.\\]w#'}2#U")xS*l\PTuͽf{CԹɖ{$3F@:֛N=~{ɯAGyATP;U? (59rDS $K1EUp]a^Jhe|%=Lɝ-az:!W >Imv,s\R;JeR"_ O.omq,g?LD=p:͛Bw2dLcgT v`D| 'P5j=Mr`;=փ6+4oP.;jߡܝO~X[- f.[q{ ]0X $S׆=?ʹg+e,.MrU7%q.ijN  keWSo{f) iǏa1- gb F)&gܬ=^=!8o?-z-q'9+6+6뼜ȖwGu'hm%O.G/NS;.nN\IZ2Fپ%E{Vd&BJj|doPz2=IѐöDLYCGSkib5aEu/Ї~f0?R¦DUfY42Nrd8@q7E`_χ ex+j ǯwKE K@RώYxj^&՟}f'4!0 ep}$v['g8h=Ưyl3m;]Ҟ?VBtΔ_L >tz]^}g:ГRB 8 A 9O'a<*/m)68ڴEk!pu 4Gp㛾`j|BOWcH|aڢh ,~sԟFΒ]粂 $볔ԟ !!A9O *`Жa6}JHX<%ܜ| Cj/OV)r` `_YTLN)$m(Ž(%-٣+F7(4y pMS> 6o:G'V]̌z mQr?n5C4Y\H-gޟqLO r|5ewkZ$^-%,䯫 F=GM0@[Vwqm> 7ry6"NYᎦSZ⺤BěE\*SLDHZ,n/Nġ8AHQ{99uc,0ήӢI>`Ҋ24QpC;y%ƲMoIñAv/!X*,Aҥ$UM$ K.#4<B6j!W%req}E᥽8D3|h0&=67u"䠴k5h-R b=>ê9Jpׅ) sh?(߭ W{ 8`<@4ѮMdK]9E8¹!#K#JUx yd ~Md,/ O)z8*^>(UA) VL"g0sPQUTJzҦԭw=h?D[9 "-XMO"7WV}`6ɕ1JjsYQgx^_ۧ{yVuKu}z;{8_烃?p0lecti=ӛZdg0 M8IQ<1!Iz [ZS|*E%#x@L[-zfPty9O?Mv+XlZ.PUl%,MS'^1T]Ut!d.< onvɧRCB0y/BZpר_I )AH^~Y)v"UNq5s2HG !؎ҳG~:F`-gK2Tpno6~,MiY W4kXPkWCLQ~S&!64̑V^Qgitz(^ a^瓨ȁjK1ѸX3wcڵY#mX,~%:ĴLbYj"39[gp}ħ'HnJ h$-Pk~⋭1O j٘ql(kQ(^/9{*|k=>)/c`Oo2:S ۛme^ 8D[qF8pZL'zBh>jL®񉻗$; wRA!/ o * aѵ5GԷ*#I嫵< lt=kVo;; I_FgNsM K+PZf6礴Gj$]ؤY uQhk3GHIݒ &]Oe®3b=,uj{ӛ-QlEhe,k>{D]zK{: uhd*4{O*x%= *'Ѷa͹LW'2l9!j'NmY\AxwQ%\};ѕ"0/sM91AHo3<*5هXɗB;hQ 'p"9r ,Ӥ*-8V r28yjnCptV3.yo/*lc3P-* 02d&װ<:W+/ˢhۃ[kл|d"9)T]B8պ^|(|qsΨqiД >Ȕ WcN"IjWܣ52[`~w`lp֧}spQ'uJ!՗zEu"XTPGX:Xy~bGںN8w#7rmPlc ind[ [ cZԟIe☸fD:94L,EU:.H@PwxKu3B8}0t(UaG|;C츫N~#ۃ#ÏceiwҐ4N%x<86 DA¡oen*n1Чt\zל'-l&F%) gCeEXo-uv3>:PBx#el?sඎD>7nVX~Y80aq8/ҧjl#%z`v^?f>#'bV•+g&7AvE';q7X>n]sg9$VL&ĤlL=h_{j2elLW*IO16 S{R((P !Bs5Hg)>l2yfҕLk=0<]*fp9tc\:nɆQMNنq?ün6:|FZcoY,ُXaUU \(')x/G#_Zϔ6#O-,JQWpCn)JvsbqMX'_y?`ȟȬ nؤM`؇FUk N6- 8B(NviQsMJSR^gXㆣ9fD9,yFTs.yp<*9f=@>c3]W ]o@I h 롄]NiGy0x x%`~;sb{rɦSnt֑:<]P\{^XvXi&)^[⥺?*Aze gpjГp+mC=fVɽk,&iԨ_qFQm “A6)%?"[C%!⣐SlXI6{ߠޘhI& 6 } @YB?_֜re fwc#]tS˳*:Q3pqNXcdpIs崊 SI/und1F8W'C=;0.^|gX]I=sv*\ !7 ̐69aƙh@n{n~і'sSZ9Xfj V5ϐw:S1 . 9.!lv<}ĕ[_7\J[5j8E}Ĥ6۫jU >a}$f,Ų(< 8@mc|V~i(WhW]#sا42(3+}%$2O&/ Ť⥘U5ݛz:*Qg -I+ \l0 >uf2h][0?.~=ksM:{*iL%y-yyD/t` PP̛e&tw:9!A,}Zz03{\3rDȞĕy9} EpҾ%]Ւ]wìBWjH糘?,S-մlCFC˥Ov]CC@ p qǫ?:Gƒd2QH궍<`9<%3Xts.jhumK]N󓊹W"=-ڡ4>tT/V1bφ.z~^!Z΋[gL|6%n}$bӡ:^Tdq]M푖Id(Yq &>5`Up2w$E.Y$yzxCׅt.+P X&dCkܰƶH@XX=Ę*%oҹY<Þ뷱տ6mኖP P @P":sA /}.x(_Lg5I+ t_)Sj&w! SFc6¡>,r} z{zzЀ|Y# 8+O;v[>yglU W#ﶩ=Rox髝C6m(v:W "OəSB2al?I:"iq%^46>ӖاSWƁ6:hBq(wuyK˙G.kV<4"bk, vGH#LD5U=12 :P\E.vWCF ڜF>{ ]hu$f }nVOI&Bk҃WKL.E쮥06OkmG+\VكU&2<:g#lbvM)*%4ktץ(ܑyd3C;XθqhآF:TӸZfs%ѷa`׭dHXV{Pى1.oEmG$W'BBcȪ7ZR2|$t}70#%Av`ZШ'%Lԃbـ;+ПmJߚ*! v-ٮ9,tTbbɛx1'__,6M7IR|zȳLנ%OX7 Sq_E3~f_ԥBwcy' 7I5uK~ᶮ[%3pY&Intߖ#{݅Jm$[u@4@$d\#>s}Y oYlk2-"!!+6l|@Bcl%Q`O W#尭 ~E 2;/}n\9CʋM#cpJ~t4t,)l%@ƞ`7|?\*TPGA-nɪ9_R瞪$2/@i Мq~;Owl8X̪Ϡ'([c,ވ/k߳xNbq-8LڧŎlz tn^x=iWܙێ{vcK-=4RpeYO'>5BEY3wF+'A_9d<$}DhXJ!˵hf' e|s*(dT<)H:AU=z[z#^dW$ 4I0fY!IXؒ)B ({ 3x_*>LR>jR=nq/xddy +EФK_B((.b-/P"w1%޹|G0%|u,>uUL܏up3m2cE$fp[r?`t 3^al˼Z혳0XuJ6EfK^܀0 G^M)-'O4$ I<^d-3QP?y(IAvʏJdN6c!L }J ʙL2ZK\FIn' CPajlbe!흸b{o5s%tAj ~~@~5Ď#?xߡѧ=[Voؓf*C}/`1}m( Ob4k,Nc6d=e6Ԅŗn6֊\ ѝcw(8,^ģ(^ȳ,;. 7@C^vv{.&q u'mGח|nB3ɌGo:fAH.gF5Ѩ^,t'?ڋ{`Uz" H7 5Y\X]ЪA:<h~f$>~`;һ!v:%!LhK+U$R6/x;v i(WX4u#WKOp]XLCY<ׯj?UW:%*z ȓ\p#E1yu OT C sP!7Aח~=%>$ 16@y6e(3H:aP쭡-Xs;"s,K|: 4tW()~,%-W}IY{ރ+[|3* f_ɍ*3}(-&ZJk`((&"j`r'Xt3(ߟi6yJ0Kudʑr'2f!Ba^DoLը#j !V ReAb]sM7ܬ/h*Lcv4<6kf/6|QaNZqg|8lYס߾}nа:ld=`\tŴp0zja}XNJ+ YH,O3ؤM#ױV4ہ=(vS{]ڲ}^Kϔ0{ern#T K ud鉅\R/a0p8|3> "odS=o!)]E1gH5E%81?T*5.3wL', 6H|r2P\?Kx瞑,ɀ]<`zӕ:ȦdDSc in>bxmF \QTN?H1Mnw`ՃZwˁ v0Hu xNnPCgbk=">-pIP28x-Oޔ (+yP3lYkaK)UM,뉮 tWN9ƒU46䅯)젞,)+vB$µİy-B9 F5ř"&{#xQm9Hv>rì^/:R`F<^3 ZҘo_^UE?$E1mGk61SB)K28Ϥɽm.t'e}IF u/D{pQV@c $C$%ɕO#d_֮/{md`L|Smd=bU#M`w'u v yJ}%2dݓ7q$OIǜR8 *E\ڌ/'&][d\=XIǬ([IDTteWy!cղ 2#v'zH.?(W6-6xD^1vaD}1y >{ sY.V6vKS5SxYQz_>/Op .$D~q~X9d?{d+1"(L|<~nؿ!z x\SZȿ£@"fNUpHP@w% q7l㦗UzSNiP[Fv8BBϭeSf_qAVQ )$_dxs5'W?@)΀UdoDȬDˉt.4יT"{q1OzLɌ2M0D$XJn d=9$~ f tL C-]MIkq*}$~B5;{eLLz[qAv^ PaOV0^<V9Sx,SM5|o| \6dḫ9j:kH9M*oFN02߸4*HlAe&^$"dtd^Dlҫקuv1JqT轎G\-"<oh0=&i6 :Ig 3ru[vuU1B1CsW$# x!fS~@|FC]y['7 <r~Ò$]pB*wNJ0 RPD֯؈T?0y3L`mE}Bò\@}qJ&ȾZ<] qz;+!6ߥ݇3UrBeFPI&) Cb~g_P~&y;p/0tc"@ju Fcw?ۧxx,2)?| CoJ! ,5VAߍT-3C~/ Ǥ` 4{5vZ ]ԿRx)=>4ߧCK";ur=)LQzPvE:w*y) z#)?_iD/y~$}9xx>v;uoM+##H7\B RnGx+&z6nCu eo/iGMԬstr $k(gԀU4ttR'7JFv-gl*HvVdWc=nzVm SnW[Rj =BV}ҥEYB7],)T\bs4LWeB[*RDGqeUrRe" Ӎ9E>֩ :@(+ `|"@wf0L£SϲVoroΔ4dG >>/RU3o*#{mZʥ?zlE)?Y&bEi)[m4?rwqOh,#=Ƃ޻ l޽ &i@D-4:9fGY r)yv)ĭ!* vir5=Qq|OwPm<hF$'+O)tɘI7#P>1QؗJBL̩D6V+8L<k!SH`svlEpDd.~EMaEPXMtmaPM)._D T:|왃]JSi㛠K.T 꿙w[Ke<癉ǯGpH'n%Fy澐{ܛx]ٷXUԞ!렲n3{AMkpV\14JLjVK"00{EQv:iVمˁ?ި{sт;\T9?#U PqnKW'<< rsi9$x\7Ex}v/J1/ZzDkp+X!g.m2_ (5HD(b~|!>^-Pe:Ֆ#)`l  OX_\^_ wxҥC vcu)ue 5?{b8쉣*"p4!iY1,KhJKRhDӪ&ԕȳK(5n7вN"14,v)ڇ#C  mO>RݎN4/Ao ~@ex^݃^-O|A5Y::񀭦蛼-Nc(EqromekdfviISFk1 bDC<PFrO׷;'zͽ"/2_uj"IQ^wǹmi̱vQIL+64&TFBow2xQor8辽fiI+[ L\,7O|j e"egE=ۍ爆,D:BSL!-CZ&fVƩS)N?wLJs&,5$Ӝ}6 b[:2ǐSyxhآT5F*qJQ Ìr>T>`gsɦ4[j;GTVA% 41X+k\e$T>#MD/2k%D1a}He!3ɝYfۗN UdhV9*Ys n:G9l{[¢Bom_AZ \-&Z/)=g:T:rޠڝT kUI FkS3$%jׄs_ӳWbwGۅY5 d=wbYލ@; 3Y&nD۪pm?8I*DTx1-H5!tٳuV8C/&%^G6_ 鹬ltlzYp13w*϶&:WNb\U~uo9Ce$z|!Ӈ!Ooqu,TK[p'i"))] T&L 6 n+ z FUW8XBCŵ+ :\̑5R5-~Y'M2960CzOڹt;WM'nF7#mn{ H{:*r_WRNB_xACDeB0{k3!(3:MXjfQփHX$;})$j+4vڝ큓5JILp2.9}V%orgwzK؃?/kbgy∮Lͅ)Rvݤ;fVHZ\yArN~P -^!!ଷ]<6g5U8Cf4klAy6 !by:SE9VDiM9B7pBmT.H'QK m @;M=/a>hCoe.W5߽_Pc|Ek(HpH.s:OAo/0>.PaO"|:)slȯ܍ƪl9߸jzVF19fP' )C#OY#puuLarhC3 ~ pʇ,Z\Bq-fw[|Aõ!־?Й)P_ tY>v"{(w+@Ō'db^R1ך_n ɟHkXv .Li'}3Ū̓ 5OX3y`+E' `Gb1MMr- <sȉ߅upՀ8W{;vLYu!^pq;5YO)+cq-7UW-5[3hok/5ćW b$igR޿r(H* v5γy{hO:4%A.`Ϳ?@Ɂl'L8%.+;M"DT#>MtCfjPf+-ҐX$Ս +њ;qJUk{og7tZ9g]mt(] a T gaB(P/ޥʯȸa$Z$ L@*7I!xq*>xpVSJ Kex:Im ZBJ dLmG^bdR[1'Mqm pG?sxݴkȓs ?st5 e#-f)5~bT[qH_p%En9Y\3 Z ģ77x/З 1<j"`PEͲ#k(>)&e36:Ü/I>C}xl?]WI2xճ|psu$.euQŽOJhҢIrE^b·vY5a<h]lrՆ °9T)ujs [M+> 8QqrTZ faw\URr ԑ(#0coq!2h8yysSY}`(:?_cu ȩ*O6Ed QV7R^\ ` dhl s c7g*'ywnpIh }hUUV"<Ǖ"ĉςuUU׺=m賂,\XXe +s(!ہB_YJ]0 /c9䡏ȃ${5ݢ!2 |E ̈́)X>w5qovxJDWce~`b!ccwO7HQkP8 tH9|IwY-72 o^<!3 οi?RRZ: ݃T(X*z*S.s0'KHܱV*31|0#G+mצ%Uͤ~ABГ}Kcg1?4nWYόVsUN aA4)xåS6zFT7V+yQ<ƊjF 9,Z^x:4O!k^ck{n?~x_7 $dHmPP("BՋc?;,R4zMk|˴2f[~൨ ĈqT{Doa,/DZw_ߒfݳ{liC<"J̗& ٓ/[딘d8 Q~< b abf0X=/=爁P͇W}(K$y5 ԃӱ Vl,IӰ `fCǪthD9P $:1mܰWD_wFy-<--Nu2#2]Z2zҥéz(PW wVx>VPޚ[z߇!cK=O"vމtڎ)ݖJwq8?4PYG]{@-]FMX? #OϚW%D\hH5FH)}?tx̢0P҆fU/< n@aq1Lw*U_@ה±PiA%*+:kiOtD[Q@ƴ"l4vK,%5@7hK a`4ss6v0Fؚh#:stR&N,:pbNuҎm+ {Sr\2/qck8 N0ةPh ^;ZqlNqcES .a>)]ONQU,AyGE@gu__sԭCw.Q]`K2wS>o áJy MZg^WGq&C Zƅ! w_)rb"l][-l  ˸ȦHt5J y¥B iڱ(JDb7+n)&ׅZ#і=_9ZgP!,I3RXyq%T$S5o]v1jʬɘa)ӖҘJ\z}ߟץł}0\D n.ɓlVdUuepΙ{ZJ~؍ Sq7Џ}Q(63e@J0Ll>܈۫MʕbH@j{拿k |v~X>1HʏWUH˧Q#QHN;\`F=,aaSiB[æ 6mSv>ҔzS 9.ޮ/2\d׬X㛰k9M uvaN6e#.` %׍Ϡ>7P.sq7ϊQ԰@޿Y5se)hZ${,MCU`Coj-x懥r~0}@,"W:,DťכMN<SyHͼVӴMKҤ-:C' V !C[ [RTQCPҡfǣLsr*iz/ڔ>K' YJ5𕰎O=)5FZak ~Fr"qV?FfSL<<PږHYh0?9i8֤(,J`W='W>M9!l*ǩ72l.aVn'w-x0jO/ռ7 ^Ӌ)a܏ g&Pe3fn.Wdbۆ+LJYBCr8q`/~CŻFe/=\.UXX|Q"'d#ݐطyV&aZ!t^n~_؎V]=̀2\}7U|󈈬@HKIx|6TDT(L*W-Ix']JvY3Y"5$ڵkv >NY$\$ n!q(sOPIz+>2?)B~1OECI #ruKz~ Pi3f};|̘}eMq\ClXd1Izsne~ʔcbKtuoy܂o-+VIb_d2ÁuV;o^De 4h$skE3wXv8AZqbv8i`UNCg+Ko5DNR`@ձװ x`P"f ;j,d%ڔ~3$LJpkh-ԾO]Me["iU Hx?Y_^E`HwPn_@ct,_6;| >q \.d) ~ؿ>yd33f_ fł8^?q,LF2䂣M-86oZO>_җ ss!?lWRO%UWe3,t-3,_Nk,1$jӨ-i:G;5nkXCݓ^+>Q+ufp9`hkDN :>ָ\{rg˪"rڧ@R]F r &jŌ}W@t)ERiǔֲv2Mj"&: (r|P1?|C]ԯ=f;N}Ma#o3K"FEe!;V@vwu4l>ek' (lPq?&=#Qv(f$vBrdQf-EAaţaFo5g`{O.UcKMOH еNTX׾X0^bdZ¿o8m8uxL9}'.U-9֝ZJ3.9tA2cxmX;CLúq?5< {wl?P1`]| 43`ܧ%<0rF)MEFP,SxTNIC";%Ɛe1#հݗ $ܨ.~T@e)U, 1ymAS`SizɠvheJlxnԇ5 OC;U<ڐ4T>jB2z4bb>)1]D (txp =7<}/FNNJ6gXl`º/1t~X-tZb Rg zM6( ; Ѿ޽SE?qXz[b?$c `;ާ dj8deW}9~ +ϓ |$FV{VZLp½+$fRߧ W0ͯOX+^VWYkٞ@KѶBOv'{m},ZG#WZ}wiܪ W <QMp6tJCp\LHHA)UΏgeYvekCPj1k-1z;>ݦ)w*Y|*gB)a{~.vY֩YX@W1Z{UnkiV2?.lYu%in٨!vhHcƻ7af㝕[a#`& rxМj$LܾM(i Ž&@_7,"5E }e q o{bbFֈK[@l(P~3WQ4n=(~&ٗXaS._q&099$kڔ S߿X}v.rg|c{$bVQ4W$~x V lyt9LOWg` u{K pi<|nQ7hyKfSQ5Jt &k 6τŷ؁3Y F-hIȁ)2D:Z]ŀ}gH~Y76ƍ\"Lƕ4v~TuDBHT\8g9;6aF[S2*܎-#6'nM4*H1ɕal U)$FgߥR=&t~7q?k!IfJA3``K2hn~}W=K7LbWhnqaGח{ظ5bAL{xq& g"L&b+TR[/14' _qlM7yj4~i!0Q*ylYAB{gB>3Ig 9clښfhEZR?["S$,@ˣٓwiR$h^Nĉ< 5_ fV"txrwE5.%Kcxj a_TSǝaaTu*DMN`7P 5i{6l'mp:U6⣔!9 o_55:;R| ӓfrT{~G4'kAY϶iwX0e 7Ju3ߊqwt o#OV ,: > =^i[Z@f0h}PƵy̷x<|#Z9#e^(K26}ol]y k6+0ZH/'MTb8ޥnfEy=g%&(~yD%_]sr%g5G:HKkLغI|D(ʞ${򅊚s-c!WA,3FbKX@p5L ʔhtP^$Caz]j8ߊn_ٱ 'DK>;{PaMd(C*[k wa>D([D}ZVep824 4o!%yty\i|4NߛM|ׅ9y+fS&Hn=ː\Vz'JQ lw#̐88888Z&aπ#ʹj~CzNP\)[)]ٮ0pͫJgf֐^?a ֈ1JGav? 0M[I7Z[^"))ˍk G~:~&P|~ٗ4~}c 0rbU8ŕ O[¼lO 3m2(7>lipz Y t&HC y*AZdž,^c!Df)`~\W/ ֕Y.Gio$nOckQc΄XVq(.1S~֧agU>㪛wO\c E -dIZIvG֑UKC6>IFmCR+r=Y4a"} ;XcNY >ZhE7S%X0vtes񁠄C^JhP?)\O.z\&/ =).mνp`傪?Y2<gRLaX3t0AX0o~ëauriU.踆 D<{\UoO#tANt^En XɕI[ RuC˥gS{h,~wgɂyF8iwuDHP %|*`iH!MoЙfaۆ*󇵈/F#^grl[4%6Q?|\hspq@])IZ#$CX(D1GuAÔ=L?=,'H&dg[b||,fY f"⃝A _#߷2ͣ5e0g{煂b/;ft[TS}?F' NW`+b9iX]ToSIodZDeºLK(W.ΟRbWcL͢1pSY)٥U1sSa)ݰaq/[o-)una-,X5hL0K>qF~4 c': l )b9B4)rzV1~=چƙg bt,Pw\H/Ik+Fe@ncLp7{l^@Wpbs%j#"aoX'!QI]$.*YdbBdb7eEZ- d?S:PڝJi]%~zy*噀S/R(jܟ} ~9-y>3+,bIɖKz @dɟ-iYΐfuL.+ Mi`߬v@33םT)^L4;@)/%7: 'ljN(X'n;> gi) #~-1F;pd[z̢(7!X{6%l@i+ޫd[ϙfݽ&]n'XSMJ~$'Eއ|₫TtaCM`@0]&F# QPopu(5 u28l =M'W|A̭ͭWAlyd X!;U:LigLO#J_*W[ #+ӕ*(g{++' CC 1QXmڷW{ *̃!  Z9i_X;OGPF GW\h.g~BSt@e!?v!rmY@T޴ijXPǻI^HMؑh̩5g3sK,0#tG(c)ht8(*E7_mҡղ?T:^ ,^#A4o }m2Rq2|j-,: 4ٱXIYHfOyw;zF ǻ[ {xÂSٖ;[3~j΂4'YFmf,_ttP_A.{maRD;jW66Ka>~)'פ4ʜ2d-V>CYVݓ6 ˧%'kDTPJ<3섲&o_8RCC Khr23¿cXhXmIݚ&v5QMF@!>B%wZ%UCBܨ?*0a 3]X#0>\Wt΋7TexHoRk9u &֩lx52K>l٨i\sG*N*幆}:Cv~gm̟o`nxC ç9(t{wp3DЕD%CyhZCHi9uN9/oR)`LqDE25QZ]ܦ؏aLy}lOGuwyN{rLr;z,?aNS9odPBV ]JgAa C7jy $^ig%*@5ib=/!Ukh)4Z,q3 B|O3~mIZo 48u4y1Q^h[8ݛZcm EG.xLCYId^դtV:$/&+Nז0;YFW b%6>C$S=&cV:]0;Ą_ў@VXѭ.Zh$7D'[I3Nͽ sY21" i|3*ǻÑX-H'^ڧ&ɱ-DnMq-.q#8j5&9=)$R\8/ .I5ҘCMg ~'6~HTCJ~{*|gy8z]92fcр1MINNBNTԧӫa,m+E C+zuiȇU`l$_xۚ4L@vvL0=u* U;b7륇#ͤRY1,o&C7IB~:E?U=偽X28Y'C ^:۷*T7_4&|gav'3=Jr6H(u=QdNܦ'Q6ӞIGatWh؄MZM.|kh%4+$*AeN;u# Ws3dX)F-| z|Zhcm&S0cX#1))yDJ!2Z}K<4| v*6/gFytK8t >@ɯq.ngnHϡGtO1H4)rcYdt\DZEsh(!lfe3ўLdwEGaoy:֢ս 1N z6U ٝiMܸL3VPS ]-1^H/^:RZew.Z q-eQnJɒ iJ<nvO!?)rjGlbBIO2*)!FmbaFkp]NHWr c 9u̻-?*×)ߟM ˟ej؊!7`Wx/7"7zkV˒n;{!v9 $1Wtظ&x^ arN3HKeuPzhD WC+;}&=_:)"%B9Gl)ԩ :􅶞v!^ {iǝhG)1)N~n"X u|M7ZrP;iKQ59 > # jl8O4&;ųDu[Il%0Ri^']:96p _*#]?[Q[7G%JnO_R9 t gXtP rٲ{|tͳY5ChF֏1Jb_u&4}AXCs3*bi̭fĄ:^1ls~72! [`'R~ ̂3 s:bVB:3#k+Z<*dx{瑶bl)b0up^jد뙻e/*xBCG 62XK* 71M,dF9P')6`o}{WQS(ɱ mht*2ĝO`iX>< #=ЗYІg&{ jSas2n6a^9 婇p$vI`Wˣ5'R.0;2p3WsmIj6>;7=œ5Kgˈ tώhIۋO4AeP ;`T5B&Y!Ó/{Xb]qWqYBvq5ە}@a-uGl2;_E)|L޻[e?9ǜ#٫SCp4ǎ|g*rm?]D|0mL[hSg "_HSA;YazzܒjVaz_o˾aQ_aтI4:1,]  ^5&{TEBBAP0tOnw}[Q'F3$>`̹ey6Y+O|w76=V[љ$*B dih缁vqJǟ?8׾l]pz>v3/l]c_'t&- KwYvRg'FuM;MўX]HWRz(4:#_ߴ*_-֏2ƔYxUk5+h1q}d4ć$=(R2HĒ ^Y>6lYJea=VGGIJ_f/È0HddV73`8-J*iAOJmU#u^pǫ) (p;`7o4l ҴϜ|6(-?FE>Ͻn}_nbzz/2OQy2r{JgmʾL~ kRf-76qa~NWfAL@)Y6ZCWBɓ59N± 2`xNSVIR) ҳ3fohdi^,$x#0G(FgH5é^aj*ކ&Z^~~ TwK8-:/)e+3>Q3A=9aBÞ H9 %BfA?W]hhq$&8hi2+^<,*c4Z;Gi ڣǕVO7Cp0Ƿ:e@?8\hC3!IgrJ=Lt,~dU%RsM?1CA,D1r#]90쉩Cw2)Y몴-73gmhd0*Ծ=ޑ5P3^d_Vqlʍ+'6"ѼPa`;5RKur<~#^gfZH5CGmteC<7`puQ¹t=kZg&ED1 wꐿKRni+Q &.(m6?T.=keuaz^ wK_K]z70$ݘlMao~b+N>RO c^ s q<)Xa4^^8LYX{W_dh;}GKs{_>&0qwXc0gx%895:2<0_heX? RAHCө9RoR;Ak>?Y~)ϼª,g[%l27LA74xmZ! -#J2o+JiʋXs'Ĝr_woOA;ZkG[~|RynTfͻo\jnfr)2rhgaͷy Lwl RauAzW<- N}, O:?*@չo0!xaމqβI財iB!09GҼ T6^F2WO$/uuVIR)_Yy1Ƚyb{ÒLx40J 5\9"#ΞAnCAOSX@Jz1MnU@ErVSfmhDW- O ?R0F>N}Fw$tQJxV`=,.{ @߾$ՃsM/Bv*G?%U}оbQe+jUѸѢg# !c4kf! {g*qT{`\t;ap/^yMiҽ8gEt.`Z[@[5^N ԯ$P\*)%|~tmp_Go}"5fXZbb1 {J_=uhm؝$XUAA|ʝ4;$mb7W9/#(ނ9]!-.zb%[()S%6#{&f*Qca=4ʳ&V:0~i*2EȨ2\!yd#M h\0,>_+E< 0Z(QCCPU7uYd5(5\XV]4eSD[!򸂸Gǣ3g24&/6hֶq%@i[Ye (e҄-\ȏ(KϨا-z7#nC Zw8B$NMN2a㻖V/@F#̿]f!TuJ/T#%$3K{H= ^wyDv-Xo ɍGJ?ywYj[pLR5EPQ A"@D [dY`@D  A"@D>doy0@/e&N )ue d%ŀ2@,@EEmgz71]Uv':nU5Ť˭?t+TcW@ܓVl(j-cx-TC:6iioŠ7a3![Gwܛȝ*%hܣ$c:Cs|iֹL\2.{x{35۵q_C TtR6ӹzKU85e ƫ/p3Ñ2eZ~&c̡ %ЄEku XH18šohx[ XvMʅ܊QɞV,5`_'_lޔu]w@,!jw035A[;XR\`F *,q= {/s8|X,z]&T䦅y2t_d!u?*Si?/ARir*q;YtĚFS9^ǧ6Vb`Ë:]X5{]3<,͛XSB>$gpyώ-) C׆զI2{4,4NNV62/h tR ;Ttᛎ+=_v`f6{i5pG-, }F%S,xQ.R6v/P.ffVbZJrJ:>*o օE+ZgܱTɒI:߄}{ ժB,偝~ } _h+x(̓ !r DZ`U<6kÝHo0G$+PgݩA6ԣ՞yT? &~?nP UkݟUyhrvSe-Ke~)O!5`wf+Xoഽ$+褌Ϛ"i9B!n0nsݫWaN8qi @rII` I2 mF,ڦpPf6KrhKU6bD-oE>;h_;=+M/3sn2;^F4O,{0 a*qڌ!Aš z2 yf=d .GUb9Kqp ߚ9I}F J[*!6_"L!/ HrPCoQtS7=EtǏ{7+6߮^*&sE2%A.,&71 ҿ6hj-hWOdnq2BRkh.K-;ԳTM#;>9Pm$$ L@-V"Qm?4b4=wt Ɋg~aă) vW,D@bRJ&5^fM +mbƒG lft{[u'A7Ȭ|2&uI.x8}mdMpX/Kc+_T^ VJ6@!xQM9ai;ze| F>3j?NmļK׵^.qOWf[   b~s|fWe7\($YExyg XTs~}sf̕I19ٓ*<|h*1Ro-ґvռ. L6TLvF͌YC+*öB*Ht:[D GG(xFMB9H") M9fhqv;a.r%:K1މ:%~߬Vqy( e| MbȄ7ieksa2O:rV?)e/yۼ[E(/f[1x973W`KLvRC7piz o ;y@4k4qHNmU.Lf-%)xKT  6% iĐF+'kfh=Q">͒ZHQm7¼f4vYF+>J5-AG^C0~:XεbYE,ch#Ct"T󞁑ᐋ. 4_L!<=!ZvI{[nl Y'NѦbZ wD Ŋkz*R %EET KT ?+$pRs:Re&#H3GmL4? 5R82M$\Сa/Kݨhb _ڣ.g?I߯9M-o`e @cIU1JY ٖZSz !?88El+nؓcʩѐkaK;gSϊ =N$$ IK x'\8g(YDŽLj@eʲshK>#ɂR]CzlpA84G_Ƀmek ~Gio1q(l^]1:pJn?Fs/1B|_-ToӪK)*4'3^%f,*KliMb\P3:e 1K9y,݀X5 6hQ,">pDG?߽@gq Rw8=\v2Z.ڌH5.~5āƺ1[pw[_ &%Q@5^B9:vYdFF&Ql@50P};#^ەh^fvfBRq~Zm4[DQ21|bdz>i'u@Ak NŠlOP :ݐLxOt[ ݛx&_Wjף`ݷ㾛yt%/9φ\V=B+c;*Seaϝ_9nQAXDt,iED gS~3#0°IBvPB>L%y,P]Xw ,Ľ =az4%ݒֲOhɂG^Si/]mDEqmÍ./ab+Ã8JQ$TLsT{-fI>%D\|c*eQ_Tmx_F GRkiHa~֩vb0ԡ"~)IP\AZsIPW:IB>gs^@m{e ?cR݂"z۰RC$k)筦 l_}k@H럓Eu3քC: vcx8U+VD&/44uf4z36_21@p'ΩÑ 3i0FrubY3FtQ]Pa ' 2q~kYƐl/17,!(esf`XD?'62.\IE2pie&uyL79Afn׼/F" <*,8>̈́ u;A0P¨x#KQ%;Lw @>v+IH:]-O=͈Oti*%6w},z/ݾn_َ-LG)NG!4R3S8lOMLbᦗtc:*֋t)>IYbP ͝&cZp<-`E0}pu_>ۈM,o;e߲;Ѕ[G(  4%0RG H"/(*2axBXL(&ES *#Z&aA_ESPF,_5_ Xy8d wϟ`5v?ΜbBy=G\]I[gs/Zij/~><2]76Y{ئ~(eS+C:|w$I=,m{oKN6ݝ_W{`bm󚿨5gh;a=ra8 jb Q)R=}{PIL P0XKW-|G]nƱrg 10,ȹy6]08 oRnkvd/mRPɯ'̡[h^ٟ?t/&@LA=j~&l]PN_KJWb4 .qOTT,_l!j^U_9[V\t}wBe CkG?Na$[zjJ'j ¼2<(Ṕ{@YldP?\m3p1-6:EbFO~̻ܤi Oʾ?10V;蹶Q.Ug*~EZATGJQ bfxgnZެ_>IdP$qC)^O&vܡP!6sՎiOr79d9wNmA=BZNW8ygZJ,r$4DKp?6^':'[A|2Ѱ\Kvqw惻-7M-6nC\|'I?6ExܡSB\"Yמ3U,JA?0%hu%䃲\T+e"CX(P ?^UUT~C2wc~8 HE!xlX%1ш")mYۏ(hώ{gӜ^+%PLZDZF.}&rNjykr+b$aC㻛?5Y*Pl/wTR׭){E_ ?j:1<՟$yutglcR~$?apTQARp@UU3G)PEߙ0C]e0mNDU*ʲPŚMw˗(fކ&gP7Λ_(ezKz',[ $i:$IRBXzB ?g$?P{%t|mLۘɁmyp4#|BpR $7N NH i  ,UzjO4pyuX$B+9@kW9qVKrCFtSjna=l짌Ñ<#qVI.U /!qO _<ȶ֜qL.>^'b́2  T"54vd)Qw:*޺.ȯK;>` + h:xi 4oi;pB@4=4)Ǫ|-ۛ2ZJ{Vi_N`"KgGW׸UmJ7 `|MA]?.g8,)rqn^ xD ĹdZTZf\b-)"%:jffMG*cnz`̅q1FV5S]k0#Y˧](HIz]F^+FXƋbfͅN> P +n籢H肩*G9 P=AОleơ9G#dT1uP!?y~ܯgC!b'nW-+#?}ݦw;΃ۤ%pH4m"̭}]ZuTDL[߿ N_"N{ւ_yEzMV1SU&YmR9C0J҉ل&3 Bz꥿:?qh)!ֈޞ_Ylh5E"[)qc䪹=4Y*~^=s{eApsQs'C: q~v}[iR][GXQsapg> 2xR{`jgb$$wX^BTNŌ)yZTs55bHbM&F*`}!;#!cε8SW5{; ۱Ztj(.Iu֓;{("K,O|:0T)ݢdw`]Fx::i>ŁfeZ̖?؝`TLٙ⡙N:i@v I-]x\2Xdo8~9JꍎMy l2Lž\7)dߧoA4Xx}o-X0=$) n>ؙ=#Uͣ 4S> \zu*/8pivDrICrjXl!Ƴap'0h i.O$Yu^ 7Ĵ0CI#*abHݮi1S*n>/"DpbG}ȵ8W.*J&s4B?ъ(lyBXe;%S2M;vUtRDM{"<S̥blX+}䡩9Uaʓ|x1(q*"`%x%1>A'p'L1*>52a'zDhUl |"_ kzyGwɩ> OӴgHSuƒ}b!M }m'$HLZJ'1q)r)6Z(3O$?Z,UZf<`2\}Qi룈lkC,-Rl]54|tk_rT {VۃTÇWvyנD>2}8눐-\X)sě?sF_|;^pSP{;H~Dw 3(=YĭqВøK40w:ԑF%9AP~ՀX֐Ѯ(x*&&uwRQ}D!0qk<+@bTܿ,JKBsGj OObÝswm8)$\ؖж"ӈB0辵{)=뮺poٝ["iDݱ_C? -fF s*~qFJd#(.,*L¯n"~sK᯴4׬{0-k]z {HP֔Ⰿʹ'gUxک8h 2 -wJD;7CK~Yzء?N2Q'cnPn}D] Ao:J^2^q:5ۄ71q;X!?+kIH:CC\A2 I8ݝ7y4$0{T ^mcRdGTO\jT%aȑ^bg,ZȃFdC7:k'kb27d%VF_ke~Sju߀ 7u;ۄGp Q~yܵ.?ϻ<@s+dtsZr.oMlcy <e.X!g'Q VײC~z) "Exp' ]p6!IGV!l)ht"ZnQf ؘzp+YC Q*OS{5f'n81OL -2oz6X(hK `ՓCk_~xj:|*&gduOۋJ_ 2v)dHrރO=gNݾ1Qz9׼尨H 4^ij(wD`&*nr*Dqˉ,\8ueL5rxHmi+"$F)+tӁ,@I`~t-}$=jZGᇠa)xyܭR٤ tlM-g2adh cHrjp3{1) wv&z-kd_߉U1\0+2&7 $}qRL9"H!v'wkKk̀X'zdNkJ>[jY=6c>Ӕ%C 5L^8#QcMaœ1ɹN2ևhW!prKĜ9M_G'ǾD i&ϯl%k@u3S&[ژ'rDBYEJDhB,cqnT{ƍNl.F*'كIWXSǥl435*[r|O]GҷF~.eo38gpKAE]m,y`} kq(R({m>pdR2j fKNph:?=yf'ފqNR#uLb4<r­12n!Fx9ꍭ ee}'JvRsk4'0l$J }`KI >׵h)-t,/NGⴵNG=ĬjWaZR-$qB![Kx)cR-Dj$u;(;spԾ:u &$%Pd,&:K@%'~YԓXw•eɺtzxSCuQDUhb=ʃj(KىqY2vsZkFs?UʵVOɿ0Dd`_;琀Hԭ~:/6bZ=n?b5Y_2VuTehHx&n[$ՠzc.tfT1isy#Y٬-:\jTBX3nÿT_q:zar ^!:QPb]t5J t%EZbM|Q׻UܶOMvt[LuЏ`ږ(CN#::G>$IUpSI1@伇b>c5PxzO o5_Ac4W 8E{fl}(1p83)@݄٘`AuQuE!"gWAYQipIE5r\̥h-xzj_shz4Ej(%GEL EWX ]7M_`-3t$0Cq;DǭvoWz*wIղP  x5e.T]lC"kTIe1ݒV1i~kzez.6övٌvXͯbx3h {P$X ?Ch#Nx-ߡzbS?1򿿑]$т\LbD%Ku; LPͳ F?¡H(_ 1jx3ٙ69(~Gɚ 6|h"^^^ِD[F3.v}"wҖT>FmQ_AgPH{l %VAR&K@g`̀a8;|ǝ9&?<Ǥ岊VZ_zH{K0Zkx+Jd&5'e-qSAiLjtjgB&rm/"\H@s0T}+J7KS ;чpSD;3a_'wK}Pʞцδ oY/Df@dwH`ͪPcc7%f v]0'?ry皒%8[fL.@e~#%4k=PwD]N-G7Hu2}&E]ݰKff(;z`J y2AvJIC$.h DZu%S,UZӢ~}@+D\ļl4l8m1ѾtT7x\×9`jly®2ɯ a sX:oUVb^)#9C S"3O`~)f\!׼ ޾a5,K8]w`-a;WJ~jwx|vhjGY׭<|Ҥ"rvc?kX:A%ߗz)SXvW+Z缩| >a'f4I?dBC 55G|&)e쳙bV>c32{W /3O8/Y{ݤ 40+n9r>-@N>_xQ}C|>u*@hc7Xc>KB)Wh \nA19upzhhuDOlrCh"YM$0QpEP1k%t9WF䛍9aKH ;474Zi W dy` &I"R%)'ywy2i]٬[ t?ſ*^}QT[xt=*=fDR ޗ^+C^#WoͲL0-MrZyZ(XJG_v*s DcQ鰀Vs)-8ċ w98ߌ6ۖ<0@AcG1γ^mʶ@eudZQ~q:aw_4E8a$BOBҮ(sC=QG7_!23S5;rx9>F~.sGr@~16~Yhp_%϶$̽қƤ|H}ēgM\`nThFz CHG"WZOHb?۳:g 4(\K 5@hQk?=9L5ree0MYJ_DZ['51%f_6wr\;'KoSPmIrtjdf(ATUׄZ"C῍ x8<ĵ4^N2B~{XI/ _M5Qs MS"x3 Hr2GqkW𛐑2?(@ "@XyzE9͍ປ[ʣRwcXH\CaG,3JGVf|N.Tfr:\o]X%<pOR:%HtzhuHWdDUTb>&7-ݓ_@O ăB 4ĭE2[\/T7Ԋ9ݽm|%uV`ʕZq]8'Qƴ݃zVBN ۓ6v 1M"f+i*LBYƋ1}lW#3W~ݯ64(W ]U|$ȩŷΎk"UOѓ2< <_Q+b w1o,A^)< *gf\ew*3sU2Sew5@Rc(:ben.DK䇻Pd׹D8$V8}8YraP{:o^j*sUd76Q[`N$|D1^ y'ns^#aYK(`FԑȀ>T)=r WJ.8.èEROlv[ݝVw;m}0NRHzdUP+_VZR^Qv dg 9)ΒVgs1]N;PSl)EH\GA2{GIkT2=G, NT {(KcRW;oَNz1{:9-Fzazo+1{W >$%i~8$1N3:ܩ́"\z{,b}J4ɉ=@?sU yV4\'ATK+Ep.%&F# ?H 3Jլ_lxO,U36$βyvܐY%)q9bA mxXj4*Z,EoɷXK\)l2)NcEGO# D?{gb rС-5i^xRvī+]S4`g%R@uB<;5 vngQc urgIM{wҡSkPJlڣh<҈H3,zR$ǘάryAF2 2e3_DdT;ҜhsfU5>;v NIfт{K6j:s>E&#8ѐ7NBP p%>q(͆G!C{!s54Z"xY| ukj&vn8Q#w8V? A#8&KOz8G+[Ct4Wˎ+!5Aaʣ8P]cf>5/K:fL O\cHcOw% =3J,J]z>aW^g`iqynŸ&dM7bs6aȯ2Ne-BGg##v2sErA{Zr& Yzѫ^4]9-3n"3屝mV<352ɶءhm&p_rL{gM瀄vJBœ[2&:I4UcPjnoa->YJ׌W)`TP!d H?Q,y sQ:F׽q$`@XՅM":*gS Fv:Q<d'd.h&dzZMpBÄфjaW0 9Od,Ԕu(_ćzS^SS-evs5KL&w5_@/pȣŚX59/"\OJ\2IY.r; ^Oa]AGefy`X *MEro) }-B"rB]s j+L|B @JrSӪmE~K6%jhꏪܫ 4uAnү;٦ߤ*?'F&WLJ<躆ۏ6*@}Q{x)4?j5{~*1νTOf N8 Uj,0Cg1B绑DN[O&:_pUơԮ+D/E@"(삣T􏐾A>cBg0EB!9Y9,B JfL=i[kFywڿC [M9k2I#Jsۊ:kQX019e\Dypi@ځ!(-:qzCo-])}#Mcp# R2cisoj),/aMY.%#Ys^ 哑Z.S+7?R`h 5$ŋ?]2))$: KD7+1j[yѶ/Q)](i8=yuK3d#*Kd'={ zA2>`䕲ywM3P+\LFa 79MxS3fk!xl{ebmƏfteTה' $QG#[&ua-`9Ru Eb'&X6La qZ69099 )[yŪk͔ 'B⫫)8WT ERSʈՇ؎= GޘKqՐ0yF ײO5l|ADmݩꂐtp\OڜqRVG;[iNz~8D ~:%.]%cKA2hNSn6hqvql3qqQ]anq)G;:H:!L Vrn 1`;: 5+ 0$Y60H,4Xv[F~JbTGq> ۦdJqGZF1&bIPv1 UCOL^_EO:'ݦg|ӓp 4( N \ECbe.\d> V4U9t$?m%%1|ԉpHNoFMB!.hāVTd,~_}(yٟdll9.?a]*hOٸC w5Xڿsz<dʂ>(oJ-9X:0-!TW;J(#ֆ}TbuT`>Dmu=:Gf xڈ7:)w[;5A մn^͍z? nb{z*$jl+HV3: l0ƕ#u TwOxUU 1GzTOTz}Үʘ7.eބ[VӺ]4f^Sش~XHk/I8lMy!nėЈ9,xҩoD&AOZ:iet9į4Ӌw x5/KRqca4L-Bվfoл)1]\T 3þmhD'go$FV+\lv4XsL 4zɉL20i8ia.S&M} 7JLO(HD]M 餄ggk~/[h9qnƢ3 ɂp(,C.alC.)KuPUg"t9rnjU6ڰ^Pb@dxs>PXRM:dxRV`9S[ >p$RfH?܌t Д bNՏXrYiìKN1'kzrߤ &ŧĹBTQl[kWU@Ib>6:?e zIgWcUzr߾;uAz⎩edC)"5a %{hFXS eO޳u?C&Y8ܪՠ֖/~ %ISPM gâ-]/.|l?_P^qt}r!9Erj OIQWz)<WE'1\2sfߐy#ۂ"[@>/sji^Je Niv֔DžW4쉜'>vp-,bUMx|#XےXt5C*>ՈNEZJ %zgN!ƀZG00o(/+LD!AjZ u]iΪ!ڃ%Ak3(_#\ Ρ#Ϡ6KFȒa]ld@)\=S:k @}0hkTB~EDJPq9sJIe`),B7΅L+ЋYɤo׊gBG.!}[lavgC 9ph+un7oĬc)͂+"*vLYa7?2kL|'Τ.%2D~b~Sa=Sv:I\֮xx4 Hw"m>ܻ܇3g ՄE{α {h7܂wkL&e*dM `^K [p q.q$g3&5;A (~r;<͌@́R`hwEY@I&޾fnQB:w;mFA {T[*>vaWl .N,?n|Bu{[F&|S,'$,97a Ks]2Y԰)dDQqU"$l)}=G mM=(uPtܠI*Y S Xe|!LNmzeꞼкN%]'vfSN!- :k[g'yKMdubVƂ耰+mN i5x 3_'E95RMu a$'g ULo({zE^%l[+Gt[pJ"P~>(FgqW 5 нq#A&Bb㖘}otzc[<{"~ 0~@WAƴyZvFҀ8Dej xҤEbYYoKhi # Hnn~Vxr]{~R>7+I;Cq:;f.쾁_Vt>ԝ\@x4#P !_s4G1[Mt$h;cy}s -Ω,] $9p('9#A\f2vvS5Tf\J!o&W 5QÑMǐxVF:~, J@Ƥ}hޟ.ۣL)" w[;l<,Ć@FbXb եgCG#l#Tu%V!Ov>Cd דߚٌB@:};RFɰ5Gۓ/rp{s=1Ȥ`H1c- ydObO(]~IPL7@X3?ͧOB$K^cQNX y^MapO\QmrُI0 !s Nv\]LDӯ Ԣˏ ""} `U~Ok`@zQM (ZͲn,Oqܳv&u:ŊGg!r̛%~ui~4?T|`(( 1Eu> 񄧱;:E 〨R O3vr |PqVꜝ^ϩ  ],M&ݹX㞵hITUVczDݹF!=yc|}ll=.]-8G|koF!m8֘wM{ZѹY*WԍUұt >&vҽQx3>+ FtCN}g^& fh ^臣53!=IFߩQo9iŮ]+C)p2)\c1@&>uT6~џGGxK"K%&5ŴUQx- *Ċb -VX;}-nL[)xY왷#I(.hHr@Epw4}q$WMޒ,ŕZDެؗ]Na DYE b ϝEIvj{ jNKyVGJeO"X#b )HtI|jTwfD`eZW?-E2~]îQ˜IpU0S/G3u_NԪ RoFŁVrMwfvr"e* +1,lxUI {3&Ŵ|s"؊)Q%3-1JGČ(.nlgkybfZ56QЅUdẗHg;ӂ&5ù" *// Hal%e}ޗ7+!$J.EƀoGw?jn3aRֻ }P|0 i^i>O ֹS7 K@ (~0 G|_Cbk"?sj%>BA/|4G]\m fQק. O:rC~#gO5)]T_"K15]5eu(ZpN(>_lT䶜8& & .4~)NSuDb]{ [TT8ܥŔnnp[^ނݖ.x[6@5 *j& Y]~SIcUPp'ZIyuQC{Z] Sz1˺ܰπPV9lnwa3R#~49/oYjY%a:Szf8Q'Y d:`},fQ"Ӻ阌b9Xj[b4;H$ro0ȑ ΁x(J)R c>j? džJŃSpɼTN1jA=tedtv:⛼WZ9Y](Y(U;Z58x駌8uhb,XϿ$5jB7%ªfe.?3P=]2WqmٯG 9KF/oj^=0l>S 8Tgs7?1/Ջ1|,s 6NwK /Ir>':Xf>.da\Ƕblx3u ۟?jr!D0`3y#>l㓱);(vSX te =2d G ns;@lS7D"%͉MPiܟ}԰j36SH:/EI AN$Xxi- [0 JE ,G89#dn¿ =)R2r/oZmfr;>AF:nfF^}^ CZ?z찒Çvg/7y jQ9vA8q4NrPm52VZض0M5mi dգq 8/oyL0?Y4 -^*ʽu(Pyc`!_Lτa#0 u0;g^M ! K逖3~_E_ @@ Zݏ^& tӑwٞ)kr]#L O[_{0:xs1Y\'+goJǚw'`shҦ1H€9DQ3/[M7HQqsY;.v%W[PZh"fF-FɷqZbQ)2=ey-, MkF1l"&}d N,>'6~oxi+ZMj{;>~pd]< ]{/4*Nt{2;=w̉92~`c2yԧֳ:ԥ1%WɃt|E6d0F2C/c9{3}ۤ_yl- uwۗ lYZ>eC%}y^Ri5;0H? kȓ{WܓFd N%p.nKz#\L4ȺogTϔj 9J166RJÚvٗvVhEGwxht H>;(Ƒ?unޱ4R)Zkӆ h[Ǟ !e`Bɜ۶H(@|MTPu<HSrT4PA :${ _ o>Qwt lN|歅dsw]V*#/oPTVǭD1D=/CNo\,]UzLQfLv -r#3,"|Yxty"淚K]\"OTȯPaQzX!{~J$,ߚqi{ kɗֵ*d;ĢCd.aEVIoPdv F,^GNqb)PtV^P/k-=Ϗ^[Old'"A<ȟR1k GJpc^A}>Q]bL~#*ӊ– nX F̤h(u<<FF#bbs(ԋ '=B%p~.phW<biިٖFMd.NpK/~(ۂΣarH+۬gQgD(Ykm>l+)ENWoCn"sǨEa@^|ʦ' w$rO1V9hoѠ[N,W՛pKΔ=2o GB;ش@Mj,Ӹd评Rz^ӬgWY #"auUZFcypmR*Ϝ -C8K"@ IZmFi_U>6پFPD'mwzH{_mi*$# ɷN,_>IX$%/w6߶e, C%C^EEq) ^\AOµƤQ^C>!YvvVJ<ЂTQ=f%-5YA5YaS&p/YEa= kȃ`h*ѪĒJGtrz 5 !HsU?2u\n ') zN8I<Ѽs'uRٷ(fn2]'I{bk-+$ ,2M;KG^N;kZ3)+:"ϖM#GK jՠ6 f)1$͸ o Rqr'dLRƉZ\yhV}D듷q|8 FX(=F6+S ,ӮdsB2Ŵ/kO͕)~+1~RvF!Tl˞hv0'NY'?O2&/)>Tn n ?L6^Wރox c0=2 ubT_-w8-- aI|~Y:j,T BZl{3s޷g$n/ؤkCVӸ[|DZ7vWiI)VW3+IM(l[\Srɉ0}^lڗ>:2 Fډ(-1;k +B~vIvdD0y]&Zu UQ$:ЅۅLNTʝp3u7q 21F_ (SRldHxƗ# .@20t? )6rY-=_C3|3p &o𮿋 #xr)t,_&*QsJdYŜե߳K') 숗uYqGY!6G]T(m#f !2vuToųIKҽ&r|Eu~%d_#k/%Y/BQ>֑(f1+bu5b~If{mx<iP# &_Sʓbv%K.KʆF+ph2pGyL[lY*[$M7U/V\ClRyiq9P))ʵ-n$6]/p]GBߡBh`s Zٺ5 =Fz(d6C?pme9$AR4H:/$]@UΑ5hշN0{gS2̓ÇzIYg=}ǡK}zߡ7]K>sJzO_b-dTFi/|LCH0֦CC;<2>Tq=ltTQvSx>ف}ޔ=^+=@ܖuo^5H՞+. آswG=džCq2#>OU'.CVFl UTS,<}FV'ɗKInYBwp4XאhT:OEj#ǰUaMBG Ʌa503umI<@87 p]5*AtN8%#+Q'K3j4h/,%it%POSq2/cYL/)X%D轱i3~Ue%͚>OÖ)pj6#{įB63 +M 0V침(m$&OO^QQV6Ejsv?ГALjR L% [JN6δ8 Oq>%"i΍,5DgE(S<¼{lXCpyd̑Fr_On׸4BZzAoQV١v`6svƨevq,<8f.u]ap$M[":gz8F\R3 V-,&~3QeUCBNJiuFΆp_-`IMw,s-&OOR5!*WNY ji$j;yD߄{Èca% XSxU}l"3Yk 1Ȕ%ꉙgW!INNd#,ąߪd^0ץ/9%Ȭ*w+g12;/?mJ-I6"%9*h:J;՚yI-JRy 8}<__'[?=GLhx^h!5Yڼ mQ[7|u |6 /eJ}ɜ@B4=S҃H}g~⥥]cA,(~tɯaQxM^1oI\tӠF 0lUv/4RŲR.*i3IHIVeR3+Yٻ Øq^7Tv$Zz!v/ܯ4R®j숇ömqw|On됲i\v La5l[FVQ=Z @*'*F.$RFnFz5pnpR{hҦ5e1ܱB-OYaֳ3+{ q<0 L|,hp>@,nOS` E GGHcGB#X=u*kP$ش=()SLq ?9ȡEp@`"(y>"M#8q Ԁ2~  k`oGH\z$hcQ,Q!}uvb&KvHtre3ՏsIs󢮾2ջ=5,a vn(?Aa)l~X2†/!PvO~WPjEinH4NvEh"aǁ7D>˂>_LRVDlrQ (~/0[ĚB¸պOUAce(!zTl(r^5 %_P5 Y`ZFK04ccőr\9~XBKZN Z &@#FWF4y1?e瘬#&9zsb9:.i)>+ U>8jpts>>bE|€\矤@ bg˔(r(EC fE@> L 6"(n y{hwP݈ ABmE!+A-YoEW;6 |LMb`< C«Hςj5t߶I o1y)8JUVRkS}@*_ga .;'`M:'Z?[H.un-RX",SEe=4ٯEa M᠟S*LKH|;mm[:c29#S o3>QQ`nqqQ*饉1*,o [Mɲp^9f%̘E%P>xfІZEh)}k$EI/7 v[7?{SP?e"ȝE9zi,)]3yXJKgJ]DQ!:anwcfE2&lJ\p M&xe m_a\y5@]՘Ǖ#cv cg/*Qu-g/_÷)f1߄|wQi92LCgEI &~*o*-{ܮ8w^ SNpudU0/Ki3g_M8DtwoRKwPCs͋~Ȭ34bs̃zXʾ*6˫ HFs@àdw*G#%5@( fE)P@:Gޑ4zb&l_$s fmPJ_٪e4g'Pɔo{{iO=uye@vRIAٛ5T. 3v-p}sNnsqӐ[XNsr5 EkZAN55ArUC1qk&m$ 7鿷嚤c 8 8ʍ XJ~>TxێWu&g˅^ %mIؤlI2gᙑ:k(ƚd/C*fk~aK+*zixԼ%/G@xvH6+_-).n( )"t>qxyөf<7وr73Lх12UkDP=Z>m`Էl)68UJ`Oy`錡E uu|:M_TpnfGZ'ՖuPvpd\T&Sin1heߴh=([ JhV~a{Rg&s8 ym) 6eL +PrZtJ<.vY\7R\#M|zF+GY:7K@X)%4IC?:YCAϽ%tBFBo-" Kx7r-# ){Q:H p>Aa$T8 *mZHQsPSAф>A`uX:T\Wʈ ^{e]F t7m&hsBCLld i:97JPm߶EXN q"YE0@ 4kХdc<=oVنu3BNH}>֟4H8n h"ݨ_Ǘ=bQN&஠ۨL"( u G_ jQ?`ݜj] gȨس oPbc51wz9U~&;}Sε-*o,U ` !~j/;y^+l!DUE vEb|- rIKe?F4,~*Há Gg: A ?Lyq .NېV f(mz 0 (c;Ԣ<&g˛׌킓wvNAnG$Aɖ+ը'pEּav`TZ4-h'c}`ɡQ$ƪ479v`ì{9dfv)Q%Ǐ]WT cj狂^g36!UB ) _ܢ_>lDq5#20o_!KWQN.zjɀ4@|*n e't1{CSyh. J 37%Ɲ?,Z/j+b(?v#Tm726xԒBe'O5(.H2ޡNq.?Պzewrw}@q,D9eiSE)XAEL\0nleɍ֍(Xx(S_dه \k |~'ꃉT(L4K]_,W{HtaۺDi>ğyc8A;Y՜rZdvX$rl'|}?Up]2Oʏdz8+d4?w3t5g4T$m&.HUBSb~΃Dz"xWEfKZxdcDk3 4JQU+GlƼJ JʋFOLUP^ȃ[YNS!Ak7)eOUhljFE[Bm.7uȚ@B,3\9ZlC 9 GENا3u$ĞG]M]=uBGd)ԼU|מIxG.SS- cu{? 6ԙ_f\zԹ[*#Zudi)Y2N^݄Xdχ}@vvEm596TХh+M\*(^˟ ro2ҸJ8dWΔP%ٷQ$y>ӏ!¸H&rߟ>Ɲyֳ\) ^IU&d[C`)l$I!N+OՑ L,IC&yQ6dWCלl%NR4LUw.hӶӘi˜5KIBʩs[u5^j$LF!% Uui}6Մ)yGV-^1d e@hZ%#6e'xmy5A4 O^fڡAK>3t:Jbm[<$! $ Sp!sѷ#KYe)m,']<5Q6ܛ)*2]( `976着waDSŁQԙx T9tXRtWk.#6p=-4Y*x0OOΒm ׈1!:Av|/z&$T"x3&>$}"FpK]‘mHkmG$6EّkKb(OoSkhiѯ QG/w{`/Zjh[Jc/ͺ{T[AY,H\GCW||̤_=IȖլH51[rsĠgx ;XbB>y'F55,, xpWX÷m6bS)aRvQ Q7+A 6H9shэ]iʋw4w[l7޶hx Zd5&4"&BItG+luTіj,oW復h;]1 ,>ɢPsAW68t%Se8Rqajo%q}xe TJ=J[{XHa [H="|Gra _f+0^cqK }Qѕ º: %gds>k%iqd>d쫹~ڏ W0cx@ނ]1Y-Kxes% dO Lݖ%Os]' >p}X_q7F%-,uDy* i3yK&3$}EG{7@Ӭ_›Bo+E #We85޺N^ckFZwZ6 sϨ!3;M[ug0@%sƆ@*wt܆ [F(sqG{ٺ.W ז(yp[{\ss`tisdSzNZVoa}5}>3u` Aᔜ'=-G=)'-$?"q/% lJ|w̬mqt& V ywGønkܴl|_o0@Ǭz{gPɷGߍu~xu.v]$HzQ'>$O4o7wH{d#5B(a/|(Mh)Jn`mR2 UdWhѽL5'}dfAR>%;2Q a@ FNeI%.Ӻ*_H+[)4)o 96UA _xt"G*^5ۤ=(4n㺰"fQUACEo]T2wFJx.g6`PbQ&qRSf!bpi Z/xzs.`++ 1OL47+M &Ky"/DBi0@ۼֻ /~R,ZxuEuN2u! fO揶BWZYچebG)va!"3WJn;~7■kg GTME(u1AB/풊nqhrK22fyi߰uJttpky:S~'|G<]&?( A5-2tL ƸTz آR2Ϯ/D˭CZΊƛ1=&#B|F]XPk<ԍɶ*'78#Ky0m.$<8E]yO:ٌKůc$Bטطll N~|,r>۔'Q],}|D}OfP, n6il)PO"h[]5< ]F([Fpz=ѢUbe 0>9LTɊ>>. \xR+n ruY1*E)z%@r.8y2WeU SI3BBR_0G8d:*dFG a0Xoxܴ/]G(tnuD#:z:[[7_[YlpE"|:Օt(n\&tT~ZlT?D;EGO-gN(ڸȼD5:Bq[+>_v€TYt1 {'?8[_߻1}a le/?}"0MfblL ) { $ JȞ;B"#\idEV ^ur÷7a@p-)Pͤ]wW--*X! 5>% L1uC4@`zlF8<^Y5QS]Jt~Ęv>#+gЬϩHxՂb1!4K:9 o{MIךx9Նc:v:+sGzUL ]} OmշQQ4Կkv 0)t{acKIj.%v$SbHX)?[DPlYMnDF:cl` XFMjNF8e|Vߩ(MuzUޔZv+gǀAF @g>|L5[v9H7'KQ|o&TBYYVbى?M%VY‡fn;*jDgjsn1Mi-R¶Qhh7CԿm >]Դ3S ,o9n6O`ˍ~K#_] ГVS/7dS&~Gx$58F P:09;o!]m~3 E|Gj䛃.+KLvm 0S rf\#s*i@ˊ-ɞlKMoEv[=wnq7W0xX+v ^qI#FE.Q`nys&ZV@1KFdBIi6bk}W˻^HxDG$- h|k$`ESa\t%q[fETס "7}{א3WO谰Fp$X@پIw#)cj1YA!;|5>bY1GD4leDEYbqu7,4RpG'evJ Ү)CHv N %È3+Yrܽ\؞Cа3.5SwlJʼY]ocu[~mzcLAJ2=)t)*uMr,gm;G#c8aF߉UjC#p avȭ vFbS*GFz!vD+LWfKҝØ V>d<*Xx@PpTsr#%Oay9vb$:ú~po\{|}(a9Ѻseb3<?j(*~2/qU*>%%u!\`&jM(@*wOn7oAӰN.W)-u9IsIĄ63=!b]|0VcRRȝ6m, f&G GM )!ީ'!?>WH9ՠ5/3FJ_lߠ;M]e+)9˝h_qP\Sb4K`ʣ@~m>&/0/~^'h.IwA$`dØy)q|gt8Bҍ̠#[% ͭzX?># @?R&ƦVq%/Q)EJIUIH'2K>nɽ:23B }/RIn;yˬ^sOLuIIR~pϒد;?IJ0{d׃*{HEY6t A1?WB!eIt8 Qm!T?7o| bqc,jK 1Uz{bHQa4ТXΡ⩾yOc68ErYV8y/+KgZSvU ZFGgjI"jLjqZB L0P=<)j%\B2C)X9yˆK/c5xƙ9!m#!{g`б\Wk4Usy%ʚ-Lh/yƶ tkO sQ&RJ'yL@*b1ReV@'_mJM pJW`$d5^P`AR WVf:Ć/|j`I^Hך%l#K8F_as~p,RP:>OH̝@ӿQפ+h~jTu6.Kw>gie$ˡvT޹Dn]UX'Y*õ|c6o;ɾ 8mሉ^MbccWI$t sյΥR3@0~eC ~&5&rK3P]-,u1cyg 9"&mJd;$8~̳ Y}YWx,r&$|&RqLF2 I-qd xSd9KV:iENu叓V.^ !Pb( l`{;^bC5p?$S[ʎh,o}TB5f84 dτwgq l^*6gmKY d!/("xI@YDwOag&ڝljϐef -#T4=!x8sALa#|zFa 13I V ! c@| :8\2FJ_FLʻɩĄ?/Ȍ~L(o3?8T T=WyF oZ P Uao-XέUힷ 3K^cBZZoٿJgO^$&H(e24lt) l T.@}^ eޠ ޫ*ȥ`* 3>b+ W hmd/Y F Ss6LQja< TPה2oq0Ԯ[Ђ. eـ,?RYP3gur*\Z[ tSkrU)nә%WlsĮJ!Z}/SYk[?5A2aӺYiӓ67^ɠb ( +nSNDYD+D-M&0bK ۳P>X[1t7 SER C_E B|]ܼS a_jd |2bI=RvkTmVYS%i]k) rKNӁt>-fWQn艹W'-~q{2h^\DYeeH4HZ-Jg9LU2M4b qXb HogB)쉾IόUyUjRj@HqR+˞g1#* LBޑIY"׾"1w){Ss;He[1՜uh+dǕŌIF e)2Ԁ%!R}2JT\<tEK$o[1k TtxrTdJgbNv<'htTFp\c !7@~Z&poUl1-cRmjiUJ o %8"K6T̙>Zr¼cʞ%֔?ҩj6IIGx FB^{B`]:9ZP4nNd8ay^v, XZ[k*QA},pI9POpBʆGULA;);c5emsܬ5A%mL˲hAHu1|u vS"&MJ!wksYoERz5y'Ebd=t50jl;(J;t<7xp[e | 3r/ez[ Yji%n ,+.U8ڊIa KOCoT–ye6cG{'rAc̾ yex/IlbBpj_ŸCCO,4o3n#0 äZ;~F9ZNg Irσ6D?Tr9}IkGBY4޸myw@ӯ73G Z#N 2?NHpxoO:5㿜z`CAFp-9^D2ZFs DH/@ YM B%=xEXqE*Cz&;VF ѫ͈TO ᙿ\;6,.X^z=雁֏s§ 6wvU :]R}*{I M.sQnUoX"ߨt0o@pD @fr 3dtԜ4TÒskK!`@>:H&NG151kM,_Ƅ.u'}RZJ$9s xiR:,Աa@8㟜F L9a?OmYFC@#0u%oXrΞ*.7qrʋ^&*2;!D^ƋpH{ĊV)h3  Z׉Ι-dzQ Ox΄G."Z`i~_]dfMX޿$ӋOBrY/50m̗LktZbhTKeI)>!S= 1WP:lU1mM z=7gp%ф|+=xhTn"hcl6]%A! PMX V$!-4mxX JEe1*Bv^*E'Uqp {Ԉ>e`܃dw!Pc7t$mаZÅ/3ވqhLН& E0bYapK^)"C mäg-QĩxSZLrll{2s6!]v_>`vV:1&K K.\ɯm5ҤA( YHwe8D1"t-ʢmDQXoc*΢npryl]z DzL/ؖM'LWPޱFa勯eA oaPV2$؆ף(|֮xfxn*kYȦ 3 CFXn7Ldd(l-&OJu Y[k)-9 t0ƧXhwD[XD"Ba\Q 9;͐SBkqB2K?QRbnֳA-xt&E x㫘p:.x f&P*i1qr++B?ʺo{1Gێ̜g_ ͒oP[ӥ nC>pOR>z8}p Fco5P}ik^}c$I7{߷쑭TjIFAn`tpԯ@$o%]\(()|cNt DHOh ˍ+A,(G3BK#Ϟ\0dǾ[\B"PI 4G)#z㷟kp>cAOA/ b; ~X.u$짓= ݾDDa\ *h"{ݝeHNFme`n镒?cR<gB3 yX?:B36bk$8Q$]*<{>8uޡ lG9C h3"^Si*eS*cD h!tuҭ {Uftx猭j"G~`gv"BxbqqW#$' t1z? nJȩdRtz{HL*^JUlJ0y9(er2~DV,E{ؒ\>@"b(L HC /aM’UxẻtY42+6z­zB/|s&/{]_+O_d&褊x#)ELLT#Tdg<\^s; y-a#Ĺϥ^oTVz3[yp)ϲU$ 50HRZqdJpGa) _MS(}XՂsE#5:s/T:gUVePK$Bto?}sByg֦.0v8,ꎔU#fхvq^8"QFf΢!tY??!:m;@;=}pzt{W@^I #Pjb^t 1)۝hn,KDJNq]+9%7Wf~2=.@`|E1n|@6<I(b9BeIi'{i̓=yq3?0j\=Q}au>Ba%iP)ۯ?Z`Yj5LdDH£s#ہ; XDb͎vnD׻,849n8&ȼlP]_IvOo]cO5T)y1#!q<*фDCC:xrI(PB'tcI~(_pK b`8 \iTCgW]]B 0#-yvY0:^$fV^Ӗ- tڑZ5,)F.%+-)2[N^7B6 _$,n?HNT 6y>EU[1km J95EOC&k^?T;( =j0\bVB(ܵˈ¥i}1\5c2{dQ)ǧHy62<|nȏoj兔‚UowbUb:cR;0!З1xcZ JpW)jBr6vz*z荧^⺦y쬺5ShX1'p^ XSnh}8F3Rq<@N7f c1K4RA {7O,0F1!~#T}fN(5 DEi;:eZzUaXi3T3\+} lWy_!eFo~*Yүn tJSC(ѕ[G S/U(!_dO:0nr14Ė*3!M I꭬ N`Ͳ-"jSPSLIyڗ3W)8,17h#'-9IQ:T QmhR2ֽ['aƽT}*gnJ OVɀ,ߖk";@WW.!E=*D~telR7+7#Z94Rsnng}R#`gPщ~ؖVxfvUդP)Ұb:1~{.a=Z8 N'{C/S2E[*y>HsE N w=l=d}Uی%ޏh3D#b #{JEOpuVD@3q=U3Xv xэN~0\z4mWs dB2gS"30,uEN>'bln2`ڡzgƫYA03e  EA!2  #o[.W;hlN =.1J&0qb!]oFS ȅ<jVȡoq| 8-vbͻQ"irg$Sh(JFnަrG/{G32j 8)<6"I{J8 ç;ѮHĪhH" _Km6{Ӓc#RBH`vK1nslL9ME`KC?QAOA\aB;$S8K_\_p4(ע|kM QI{V> k7R=wEx1ξ59uYyx]Q%jSEFZʂ cXTp{t@A+rH$B[VWeN]%5OLZF%??KL#YtjwnR%?G'mFgwMh:MJ&{̭·f?ZϮ)ބT&!ݟ5>jШS 67ܑGs{D}$rE%ݚw<ʁ,ѡp vƞeۚW|E@ j1r4eE.eܳE;o=s&%Ouq7`ՒvFXciY֖en^kyn.OQNvgzwi;pəf4ѫ1Xm XC?_3eY#yŴ9٢q[}$3s~!a|唜%~zC6Eݨopȕ %HY]p+hf)/?I0lq1 &hBPm"zk"(}˴m&tx8hWUZ"Fn޽#C`oFu(3&OsH k$KxVB;ʨc/!V3NԂ6"@yi_IԎt-r|/[w[$Ìo~dWTz<5KKjHF+ς#_aGGJO` |_Lq{{A ݫ.f;55r64*,Dplq935.Zh:{\nr,f&4=X&#U[;5` UtY{r{7EyQaZ>qHdU:G>VJ4[R:(luwеd`d SQE ipWt562CEͳRմAY*5J$W v)i*7o* YT(ϊȺkXQi15YcqubG/tOP}9ÄT"|3kD%ǁep8Cl ۼ^0mٽ53MT.YƼȰ͐Q[;yEl qɥR~ FZ?-tj+i(˽Ef[ٿS*F(H&ϤtqJ|9ʫf |G_[˔]{+0߱$h@ML ꕛ`7DxyUl{mɯQi+RL}Skት(7{YnQ6eRBfCW @e,\`UQhJf=UKvЍOŝR~)¼O?\ O n0(I꧗_'-FwOo#Jy7,#ElJ*fΒ?"9%za 4LGv!U Įx~U&J3G-,R/Q]K!LCҤP_6QWN$]ElpӆQh?fiDQwJQદЍ}WamXF<pn)^NG_3?R/#m`H#3>Un|3]Q \8 A*Ue [Y@[.C1U@4R%1:в+-|Սbƀݱo cd&\'t5:FxQc *Zk9*c<(P 1{$=%'1 ZƇzfpLpm$PN(eqjО:" 6RqHW U{X6P}6Y!G¿"W -6Hwx@4& ?v.HyPRi$nǏ21I2W[3 nNX IhVs3_ > OAcHcX?ed0E:أp pض䪰R_U*i)L[5&CċkQPcaC$WCj*@1j4T|zv7apw* _b✞a xݩ/4g F i"Ʌ+U0gkPH ?5^@ZC2 qV"3ڮ \B)՘k^0T#hj}_$wG$;q2NgD3ߜʐZjI ocA-\"@#4_ X2~{)}O*"/GSSzCKނXr+ؾ-WU`=Z-+{ 5b툆e3%NwyVW]d) ʹXo}G8 2 Y Mi$Ps Ë"ӣh!1V FBh{`Ҷ|;t$*KkIűAfN]!rVM+cu9l!,-4͑; O>'3 4WQaN,G([Ii=V~B(\"8MZj}߮eZ@:>1SǸ)qMȐ Å"(,MbƠBxqR. U6P5y4 Cu'Qa)җRaG}#4 sdnO=xv)љO!ђiUmb[^>v\R^Ke;9xgWߘl0QV'3cLhtaR:̦ fZ)z8M- l^Zè gҞJ1|>(4 4XXŅBqzZP?$eǞ|Qߚz,xC7*7{F4&.;y AJB&M<ϋD*nEE[CRl[-hcaZ\ͻ0`[_& ʗ~`yd< r"4>/n(DҏSU i8x`#Hs j~q#WaqS2gCyE#COo;_Ux6Źѣx0.J`r|59txel!ǪiW<T4\ #ZШ8qo G<8$Rwx^h[i=RX(P1ڻ }aE絞0QQ_/-~UY}BO"PFxQ3p"G u.D֚;u oHc7aM'*\ ړXHj]FD? =n,eOusG3^`AawғS "ZČǛp$Yz{CRx[N/v/ɈČ;UўOSE\U7Ȅsw^k厛oH*ʶ n&9?mQNyZ? pvkYHk'a6U]Ȧ{7= ^ơ8lqLS6FпK^K,?ǝ5 /| wYu\QFXC.WC}TD{+A:Wɩ0R-vfu 299t4`h"f]a>vR}+\bd0ifHu +uP_7 tDt'AΎz!b rq O˳aI+Df2unq7_ Yq>Pv5S0?y"-N'M=o^cxaYydM( 7AJѺ g p+,Wb*LzjG+uGۢa>KnED$EYmj8J.WHɢe$75l8F7*7:o.8 us+իlVz? CV,7,!~Zk nVr-]u6)*ša%7rg})_-l'֌W:/s1c)~Cq oYPP틴Gw&zʢ-:A\8lzoHȋ%C1vL fiFoz/ň!'{_לE~_[ZR/ =y:r`n( 6̓M1 .FU?Uˏyy U;­<F ssj4aRi/ t"ŝn]c!)l[Sz޺O5ewðң.`[К6Uia@ @KUkTZ_qb SepG0ˡyH=WFCe הB6Cm[Ch֫o"Qg`TQ.BdFiEm: Xs<1 }P%=AvW_t>`׼&"+_ O[-IZ2 BfWd? L=:Nw44?9lC$ \CQQi*4H|Hg: '|MQ7He't spxJhQMpI*͛TJ Pߤl)VlPB{lia|XC-/"E /}bG>*IQzGRqM-gWxanճ%6]1 -rM{3F5dJpWٍupT$<& G{k*d$[8\-h;Dwq2fF nE$ڐ̾aI67oG&/Wa I}#|yzaA9*Zh  ,^k{XJ#ivΆ[tEH+}2'G[7H Eإ`^!D^;0d; 7u|30ޗy׻5>`7O L1A?~ا0fM[ςxdHDZM@i${Or뾊X6K[ BO:?DJ.G߉ C ӻB]uTPHOP_*SJrW>>Z_m{*HIʘBv/2v4:NjԦt?.3\.,uM]u X&@dCއgR/IP?WOR LQlKcN p gLNZ`rl Ys?9=#{h:ۛ>feK-8loGIp1UBD̗ӋFդ{HYG't-eć\al5Wn$hգˈ}iR;q*^<j}v9G1j$M*,iRILjוpߌvWUwf c՝ o :G =&+ɽ/,#<颎Z|A?ɫ%=oag˄&,O퀜h#3łPܘo{?^2{gqȇ6n %1D2Pk[\ UgSC@KV)̀J0FA2B}g x `(ufJ5N/x dESC;M^ |C36 h4[= *~$"m7ßb$RŤw9wwJS9fzR R 1=W]^=r\e[f8bYJۤsɨ#u =m\1 @!,?C赥_SW?ie !ɞǺCAmB:kVۧ/L ;6RcGM&ca6z[s\Hy q UiI[4i5޼(Kҍ:4ty. * G@a4̗=JT'=33jL1:C**'ry"j\iن*9 T3"8**Jí7}'C`1Ƙ|}*i`)$CuvޓG6ldrUw-xd,۳Ȑ mm(4- FeQA?dBHyqPn\{i |AԨOSʶ_K)=z/uD.މM?o`Um3ԗGZ Ad"d]v/{/= TDt% @jD9R nOQEUDԂUKOC~`?VA'j.0Qkg4@OQN%,)W%*ENra_[rDTsC avTqBf p>V1R-a (-yŸ5G8eȭ~9Ny!iLv-4Qc?"\Q 6.R݌Hr˱+'jEBr"Ź k͆* {6ʣDqMB߶ȗ& @K7P{&AUTqBJԗߨǎ z7oc5=C^[p?gH9U|gI\&`pyMȴ" _{aףf~W#&=ƙTe/_Љ挠IYV-z4 ! \ ]cq s"US egUhh6FA $[=ݥUe+2bZM%oLJ@FԇS/0gD@uQ#A$Y Qn ԛK &S0gČ1X 8<9i ctTӋjhu\ w&4GMkq!=}H=,Ptf7֤@c.WGMёŎh g`:<t=;m!$l'^fHe5س\:ZO!I^O3u;H*r&̩G-uLuָ0uLfY*Ƕ:6I*^l./ )N5=eqDlH"Uw@8 ."}C}el !ƾ*QȬ"@ReCy,l~<{[Q!]<2L`Ds$En&UU)bMSlIekC)f|Gٷjkv=5L%ItlUI봹1l˟;pHGMQ@ae"pߪB\@)yNdqOpX@<%nΰ!xQ"ˁk%ٰuXrܿd/iHpBjB^]tKѯVN3IoC WS¢T.*j eD?Xa QgJ9FC}D)O'wjg$mUIsN&G*i* #@?"_ALLwn_Λ!Ŧ\'c2eMfb܉2ieEGhvFDټDفe`]T8vȚ˛ at`5swOK8'A1+;F%K[ӭVMpNHG'X>j- ?[E/ЛrP]F!}[#XnQς99{"bS)1s92\'\< v..xKS$ 5&^| Eܰ!&5J!ToJ H)NgŁ%L)taH)eہ3%Aߢ, @rҳQ;dDTI3PA|FO`Q ~Mz8)(ImnHIxcM@ m]}c8e|v!6S-1%Ǖb=5|KŧVӤ $ '_rp,?0-š=[ϭHxIܳV-]MRb1ƿ *}un]'m]z)zer:+Vhl:#lrݛ(csDch%lYr '(%@&WLx+'IOr` ՛Ţ%3T%f~V]mr׊yX*N4lNemm;)1dRWgT4(=Qr-GK_H.APe'FD߱-J<ʰp m/V'rϾDX74TcYxoW39- \?# S /n&G~wwU8:cbL3T;xlWibs& \[):OrZꈋ 10vրǪx8w(k*f0_8EjDO (!G{_ȌrU$"jkqw)ztZ'ue{8|ds-d߷\Qu"/1eL7ť};{X՘W;(d)3jnj,@PR5$Z.Sj\^?rXLLtƃ ]d4O|;!ATUdP0Tzyo2<*yRقOnp=M;DNN˘Dd^ME=ʮ^}b1vb/!QabE+0T&#Ic=YvS4if )ElAgm6d=H{ܓD0.hkug>-T? gJ(M/a B{dB\ AhO"X J!˃؅NQnWsWo"RY󍲐 +ۛդE8e;MWv] 2N|x$%o'3ԃ'W7._fgsou'=p۹>Hp?_B |$iooSQmWªjt%yvE3tN\O߹ŏzHHi5_ƎZݱKƔ$y{̼ YF֙W/Cݸ|ެ2Ɣj1&_(1(==Cgt3y0sc@t>) g *#Be gʂ!W*/jͫ_i P:8/;C$X["CLc{ɟ8AJy*70}ztrP qIjϗ{.ִ!:ߡ-/|P<8m5pdS[; U<2հ ?;'/!S\괯d9СeԎdxDR"#-Ca8쟮іv$Bvꬉ^RVZ)y퐔}twJm݅"Zf-+<Lѕz%N G0or@A isI\nǸz {jp9p|4vWE{Ɗv{D5U_(C$j X5#Ap~PP䈗eٍB:X;V's\줮T y3fW)U'MѼ!H@K,f| ɦG(=B,y|>617 ~LnsY=?=ϻw:OW Q*бo݇D4 }PiXuz-L `ׯCr%<=@ +R);1ˣGt jnI(z'_QNgN;0-a[I1|xiؾ/.D00fUs75 S?%䧖$;EP2{x>PpjV4B3tKsRV.XWj{ Pe6poWx Mێm;)1| A;&3쏠\{+}JRa/T=MNqy?-$}X=)baδSZåYrlT-YN=\}0 GS [7[4A'n^E[~ٵ֙*ubx*4YUЍȻp ?U󪾢Z5@$qQ ^gNh;ykRH:OʧI^<ٗ8*'C7%-U ns?ΆJLdYC CCbC99sR7vsAtpj~QeKL>fεޤ-3tU1|Ok #y(@߃ G 7r7c`5>M$q[Iv|n=zIw7~˴Jq։ ShPUb,bQ%GqompkC\U{&DwkF'&iлo$Y@e!(90(|$mbM/珙 Տ]FiQrEYc=R 8_(़HtV C}J9z g~%ηDG~V_˓^Kԕm>ƶ7Fc"7vE6!tGKiiȔT*` 4]LRin2uSňX80dVZRkzDi6}]ϑة 3\H?kϮ5 T*Ж}o%iJ7(i>rÓW; }@0_m#+pڏG{4 Vˮ5;Ǫ@"sٴh$ߔ2pP1d8/g8B~VTftk\C)_kM j<ˏx? Cv1 ĜT2B6_$˴87}ẝ͚>REV)zma«€!`-გeq2W5)JɎ0f,fF@sA(b4W̭)k$`^_̞<{D*j8r3>Ym(8L|=@ aC3K,2s8 +ꅧ|- Y5e댡8i`?>E5QQEw%VCU!WSIvF^| _Tjm ;#{B95~)cxϊ?,Ge_hY?|KFMxiG\d>8/$Ldف9$~pT8Y]߽IJz>gѤ&od7P);74̨fuKEDHeml>3 eA_xJPYkgn.c E0*tMjog52A6*L'{AcW3Sc!N;=˻¸H4DŽ0q2(LR'z5C}Kd‚Mi2Re,7jFD  ^e#Q:4qbNr L@K.8SO, "ؑ`c՜;g^(6%%kFr? (b@&MmXMAk]@Y\wh)?r-$nβ3+}BjIMYF؁ϨżNfY˕rdb䩑;hcDe| 8Ռ\a9:{/E?Ώ:5ߋ9 zFjVL[k*[Н`hQ +u)7Uѣ*eEE7(Y3FܙF "c vu9Cu:*FezBNb>1%Ùp!AX|Oa/ilRo iY\þNT_>te:ab(W:lߒR䦔8 դQ'HTV[T`>AytSf4AFI/ S K%]Yrs1rR> ,%~p`lb)84wM4˲gcRے@K&G/gjiEJrVCBB?:VE =~~g@ !u45SBv!B>$ z%kM_TC^}qB2m(.܍@$֮<;wxq9ٳU3"\g d*-rlZ6D00Y$X8mp u, FrVtBלש颦mc09@U$) KØwtzjAyU7}o"|Z#P$H"i$~塽jCH#:-6Qa|tRɫ k~j D ?܂N4=f( 8$42HDzOjljw90h~@≇s*ex0Σ{wmM=NEU EVuz״G܂.uSFAiO45n؇Sr@} \m3 .kZWwnW~; t8.ܥ'x3Rj:+5YOU~VpsBnX +t>B(iˮΪ$ hSq fq3tN^r4 ۇsӥ3e!ʹJi0&<[8^n]yHyaA9J6 jBn5|IT^$Ro/W`zUY(VS &EL%]ޱkQy /tq>%8ZsZet>I4wo~.nC+łW7^?B$0"j9HOȗ~%%ٞTH|KleIL #a͍]>eFTf>hN<|34˅KB_@Zi% JkX&RXƩ:&HW~ثo1i'髃FY+hrb/eHC>O4,K QTH/1ʯIgKnLK6퀨AXbtSۃwzą1`XalOzN'1VSł=[`u[! r V b Ž۵y֐W0ά1uDžmEJ4 ־4a5VcS3[ɮa#{YQ˛9SÇz6("K1Gr{S4 "t.}Uy''ߔ''dEaA⮾R 2cZ1Fڢ&\߆59q9ݛ@/Npb +nYro饲sȠֲHacCS hDFpHfHjx[hE =+ nm1 c}xݻ(lBN:(&9*o: ىY dn~ Tc1$0,a΃B<+zj17-pJ/ $U3 #.GucǰD1> 2~![) 8H<Şb&Gr&w@ڤYCQAn)"#}/àο.oLD= ȗxGvA ò{A(,$VHBh 7;sx }?J+=~՛i yhQ 4>HÕv`FzsB k`v?Gx|/*sYE0RbrZ_UV79lA@fS1߯ՑF$y]H%JT|ʢ>Ko(۝?C/Nc0ޙ8qJ*3Djf$5KKM3=`'pnaĥ@'[)B>TGT17OҒyKRZ^ Yf(ďSz3sM) vT"W[$zV̷VSu62roZ ?vbrql׺uBWl{EBuPYXܽ KIcH= |iLS$ ۿo,r[=<`tfIA\I @)>%Oy&߼e9YDDhOkZ#םZG8nor4w9F c\s|O5>-Ve}M'H,'(ZYS-vn(~&vs pN]HP"vu q~r@HmAS~FBFwA㑶m[n(!Tx|NP%ezV1OSTH"eGVW% +>O#$rqYAaj!8u@"%1{dn! kOyhSѫG0СNx Jߥ`e)(2ئm^ezwa4xF_TAP:E< ˼sA>,Ka fpQih =C`%սԶjY/D{*}]I+nc U ﶤM&0CbWdUND5Mw"!n68 w. /$KxiNqZ(|H[R<$i$ўNH.^?uT. +^47\6-5ǔNL\;\BF.902i!-=P> k!1 ߲)r_4arN-tyP aWo2v3?*LPvq1g:,^ɒPkXFBfB 0Vqzz}[!XXWG LxKa\blzjZy뿉h{88 Bȍ*߻I5uF`l+X!|<芧={{K;-Aac70PJddѶ+ QNѼ cX&d⿤8f}շU+,,Msk .nr->(9rz/ouE Q'CV PG>jV1gz c̃ԯ_=@9y\}TΣ@MŶ.)n͸Hg|?n#Tu2Lѯjp+~8KCPR4m!2I8Zu*q6I+.CZA9cY@B}sS;¸QHw a$+L]#s0My~^o۱@nl*H85Q! c4j$"NI ;9ۛB\;w:X>jn}M=*uC`IS\Day?NݼE\ csse#ُG:W|n廿OM1rW&YϺBת'Ɗq|~ @t!y. y":zl%yKq;b<QT| ;?.Hcf4@blc`džiY0QoumEXdb B^Qq"Tnqe-etH"6BSh ᗗ*E)W%4vvnœ<{v\56|""Aߏv}ŸHXpfb4\ExHJt!G,JfE<͢uvLbhW蹓%Y^jL&+on9^SAIN,'eɻGX/#tبte(gPU?+EOSb;D{zqG-G(,$M}~\|H1DTyu!uU\ mib΋O!FMke@>Gl$  "ZRW0T63y*6@J5]7 pD.' ;P$R4MIMb$RSnU]06KrИM<`Aa"AK–T~Eap( (j(X+˖K [1Kgc7<ߟ:ӛd-1BJ$/Fq]=9I` rDM?fo [ yi2q֊N}U:N X THĩ{5b~{N0(y䦋 &uۯAK\ GIW#4}? )x؂k_d*MԩT gZ+T:"V} f8~;-Ҭ5_I-7}ة6/E:b3Kox0)6C=`qqYl>3srsàMaMeMNrZx5%08/GFdIaν& ǟ<9H"jňV(8/,²yاp\gGUꥉ`}F@yK<;Rځ! 6z1r,lUTw|ٯC*`0ȩlq|7+!?[(q2oVJ&{.A$ f(%ndA5yB:@g+xG+IU_ucYrZZl.,7!do{k bSW< 1;DT&u?Q& "lB3+d[M]@*Bܒ?5Y,SwىIgjOuVL|wG)k&Ϯr['ٺ}E`m.<ڑ]'wmJ\m );!<*pl^7q|#b|ez'L/WtG_O<q\I@L3Ba ("҂c #gͫr)/RϪ2*ɅwC´TXSٷwlYy:П,:+ mH1wwbVInXeUVw\zpf}z)Պlç%úyҎ+շGdu"K(+ T26p$ai(ls=yW6̫-+t" .P25ӦXɖEݟ pT}Ŝ'e's̎S,g*> on^#qa@M&ه;z7;7Qzjz.芸UC%׿ٔ~@ghE@N6;h|tpHm;rqxd5>>4@[Ӟ$j!wޮ($ p?X:p(vD/&0{ 靤p G=C 4WJ}+H<ֱN}Nj=Z/ k9;c dFg{Z؂H4 kmKȏ:em}l *o{Β.O!n"БViТOTE22XuT2 *OD8# ~) nϼ) [K u|N]ÔÈp2L@=0m 8JHV1ם1ߞ~J]5CղX[ ;sýe!xAB~ҶzwIV~I$Rw6w*~w )dg N/B]LO*23q[YPqeuMqẅ́^6c+u39&\œ@tYVJ.X 2`?hn-U Gv@H%)H7(~G@O  nG$b̸|%x+s)"Zgxl\9{q1NcioA1;/ev g0ߝ),+g`uOƙ&ӠR !-3u)Jd6! OL1#e_y >YA~2/ ds uXtܛ0cBDB֠=.ec 4>A یx'^EKѷnj*Idۿ܁j`jbAi eJ@V2! x:/]t29M/w) A]8A}@ZLtePpW'hc\r#"-{LCr-@@ 'Oase)ˀD1%1 ;B&'v4OG=V h{e=ڴtm;ؒi A<%X#){OD^eIyTt]8 `EfZc8Ϣ{2$v-/ y* ^ ٿ [Y 볹x@b (c-oQhv7!GhvߙжNY 6K)0aL_Nsغh >yܜN!{}b&%pXQC1Zŧ~}&N wVuڡajbe+6YU^ +qj_Kjc lVvRV U,&N|jF [P.%jBE9A+-A{i cfؓ9~"7i'7J/ !D˕98PMd?SBqFt ]5dyѰ,ܣbAV|K4] k[jK2F lho/c\]ynYeYC>iKѰW1ш<Ǣ6RekDY$SM0m3 PHf?}kB8!`)9I27GUpƙt lQG ԯ*r`!q_')Dܠ[! b$11J DÑ>`chEW;˔4ǻgSF֔u(__}o( ^~Xf?FEw @Nz݈vAJO" ?},=oY|nl[pwjJװEim)gah2cJ@oe'g1Q|J3hǾt꾋ꀡ/_9ˆMo,8, ܆S„Ƨfv{W_I gjLq!+}3Jld I]['qO!$`Zi:)>(Q舛}PH*wH7(߆ ;႞44' (D '5Т;h.RLSO8PH(z=QG }2os=qCn?x,a?~n}OK tmVJ8A*㊼e)r?ޡ㔨0( 3 `ͪz6uAV9yKxNa3]j/6-^DVӫťxὈ xt2}^n !(WÚD σ/Y\cV,@j0 czr}e _f7xLZséyʳw1/\9BWgF1/ϱ N=ی1vvF0YT/d~%dc׹^@O!7 :>]C>Ţ;XFJ5{ޏH1Kx9G*beގ2΍ڍĭct:fB|~Q06ˌG+Cκ0_1!z$kL6{DieҰH;4xpmg(4C0q3cU?`kLܔa26mw}tFpUD^B1Z5:p35EgKHfCH!55P{%  D"# |Z@7P9;W?mj:+LM\.ߑrer}!pӺ?;H'L{bL ci49[M16Fv"i4r׫yl>uDoTa'z14W6ʟM˗aˏ>nk’Z;1kc (`BiXs3F]Ls|hTFZ ;VGtRf]~CKxa& lXXtxP ِhV5;2d90q!f'TogZd$isp1 3ޏcF+MS6X?㏲߂7SHdbfA0igqU,~'ɷz.WҞ/v(C)z&0mFA&?cUMQ.w}zr‹nρvU~­skiߣ[T7'h ‹J_:0Ҭ&XfZ ~#띜0Ņ~tc%RK)Pwf< q2h+`ke UOիAp!5]6689QksJDX]\Rso5&-8 P0nd.,?r qѡƮDp䒈]ۘ4NNz caE(7 q 쇵}Mvifu9F|nD+&e *TtO;ڣF{`kz@2Ȗ(՗ UF@yJNzP.#oW dz%k"p Ä?T̘$ xmF$xE@MlZpK%[s&jŰFocXm2LUi5 \roҁf=ބˈQ\]2ȫ'4㨺C r|qN̅2U{`'biNP; < Mߙ@UַxױQBF-%`opj ;,"΁Q.ey:*O8b`ŤߑE K@(-Y_bOjs?fx9ETBGJݏ{tG(iAӑ2xԮmxa{Fh&ԥF5}m<Ҟ%t}"nPgG9q!'-n=Lg#k,'l5"t+{o@L &i5M~tl2co60P}ֺ H P-L͠| _tD7MA_yRS *9d3KaqL`bQ]!H)!ěV3؄'` fێt,acpl^xaҔl{Ay}#elY0̇!EH`Ē^Ct-kỏ44p!h:je B%)Krto$QG3i|v\ lwѻ_풁ac'> -^DPjgDżršczFX롎 "Ih`7vm/d∽"Vo1ms"HՐEi ZH+p::.Č* sdi-J˯|ϗl3LH^b4v(%m/,|Ԟ``leE!Þ͉1Ò.^J?FF}~Grn!]2WzK١ӏxUT C~̔ի9pv&x&CS/`7?kZ?{\"^x|"RttJBP/SR ppIEB"{i$jDb xH+wh< Hk)iz<]3[^8ܨ@5C|@p,sǏH0g1#\uaqmjĚ7Qs/+D} AGSiZht =ғo H" @,0@M`QIh(ƅ/] *24g=83{i̼f١BŤIB +h4m덝/ MRcUC. ֣YS '?/Z~.Y<A g1CkE&0EŅ#& @P^ "{č&2!?F1x0@jHINh1xX',ƯIyq4*[Ą ˳>l 0"{S(2FMꐶh˧Z)<]e<K.F/$Pp"\2vр `Fn\NZZqWU2!jHo/7|@2& c@cY]X]=qiX}EW{Fi k|g]M3Si #AS2cX:.bdνV#N=)}wqbsP."/bpFyϤA uk|H 0AD)t^( }uHa~!GXrH{3uo vQ{C,47Ly8 ` ?tnpm@> zGeob[Os)|͐ ŤUF"j 8@\/$H;m DØxحg| Qht| z+YbX h!{N'k7\tY0 X1~T'.tC?(V*S\@  d"w51x?5 =zN HE2!syqrzAe+w..*uz'jS$m)WBgFxb~g}/8 - \ dq`푌>-HY/"B1>rbQTt@jp Nf \8iԑe!PK ,B4S{*K[|je;D_c6˹t#߻ y\kTWIβ= 9@ ҾOt#gXJfnK p`!-]?lhi Ne/,O.z; s* a_R\#*Ҁf]r!2eVt:FmkP d?MP>f?̕r.\CևT/ͥ'Z3=$ȁg= V0hI >PcdALJgtʞWB?A]27KLǖ8Pcvy)' 12DE/@鏺c I+H6S@NeMy1k+YlN7K`uDKӊ\@"cʞJa]]8AQ5Wa Jqk+шOȾonT0]=[kS6%m$~FQvJ !Y?R !~ȃ΄wş$%xonG:=%#W҅npwI "M6$ 2M̼D.1̭o[{ϼY7@i3/]fsWIt~Q3u+)LAR#O;sZc LcWwEpBep}ˇ(ƹLr~$k8GI=XH%Oϣ}9cYn:tf( LmTaarNcz쑲<:29!KeBx.̊B)bj+pϲOe5HκZfV -]Oz%*~>D:} GƱ8n7TQ[z#E0Ey! TFaXy:EрJGŎfS*!έ'i0X,X5@կbBM2 dآD$rxξB5H+ʠ-Ә4bƕuw.Hn?|A9Y}MUAJOOhtV"pm\͐ru&­ $5r=m՟@%N~"287L΄9P=.PxP Hkd {f$x#ٞݶ%qLf0|cGRًc/+F 1>-тTlP.mĽDj,/J& 3ik<[uҀSpf8E 0yЏJ EjϭߓЯaX{%P]8m@$WW Gcy>9XLw&.tg]p_Ė,`0 !uEL.tzˁC;#jEtfK牦70@už{JJ[? ^9lBU[D){6 %zZYTP* A?}ͮܨlւq^ Κ};Jh F-K]i͍2~3? TUkTPx#fB4-O#bEFIžMDWr2&yٻ<Ǚ*TE+UB; z./{ۀcco] b)քK9ߞ_"jSB3jύ-ݐ G^#8; Sc gIH;)$67貔KZ,C06fd?3}C_]剢@]շqNx픦 9JVNal7}y>c\4xx`{5// &4*(0 xᐂ*$0Xi>DN Ȅkdllx*IwH7Hf<YHR7>s myhCZO<,g}D^^Ih$,U|̺ _2~SGA> Tcilq͢U)\|6~Ԫ<2;oMq6Ơ<+`B9Eq(5[aDa4Y="5t2K H/IFM ! 6x G_ Kq\ϣ>_hu-rB3l\ACa!a"Tͫ[xf /\k)A l-LvK\-DsGPQ.MͼxtЀ25(,Ry)ں7}]˻KbӼO|r9"MGO}z x#^D=NptA6?r,ZaGt$%#g̺i dX r ՜D>ʧ׻.=WG]= 9ת<7G)MX{ݬ.Ex}еIUN?nq+h%=d6Uh`,B8ur '3a13T ;2{Ov){oo (C, ,Icmʨ|^hWܩoܕ!v߃sj.Mz_[Rƪ*u=Ad&m_Kᤵ6tA?Wy1Qz\_"Mh |NP Gx.B<CZ `ZI#:fVz81\G㸗:]) U!$# 6._Pbefvre)s&/ݯ<膿LkmΎ^UᝬzI[[5U] xae>8+ew8ۍ Csޭ_ޤ:s˄!io%4tA'AprՒ Dë]ưnK{V yȰ~[8[9ۿ!w^=Fs16@!/O+oUUyNJe̽-%G*9P?oZ/S_*aEH-^%#8pUt{yE)9=LDHfQA }w$r(=6ق+ܼϹhK7ӑj8]ehwm4&vm }Ш\a4Un_tjO[AȌ4QiU*#O+qED x㱷lrPTdwQYU[;V-X5{7Tt4mzY}w˷Ps&wibþ?$EHS5BC9){r <#;aCs8GC0nqZmG)֍}8^2X$KGY" LLZ_2-~gQVSMƖVHgM4465J\c/}t: E ON] rҩ|J?WfB^y{Dߧ?Y>Ny; 9`#ɮ{h*G]+C} nA8m's=۶Eμ:v٠#;>1"f^_3+a-@/J +P2% i1_DtZ?#bQ c-(3T(WaBw8ڦlG~"РheMR8&1J=^d-d+"h$ne r֗dB/~ NbMq*o߃ y)ՠb'^V.%KQDO-.ۄA\5ْ[~=0Wc^gt1s|oᅿm3ՒݪN)VS`v#|}+|Q $p^q<|('6agIoNmԐܐ-VaW=C "=^A==,7#2nƿhs0#5+bDŔ93d?wl![`6 5KcdPŵ>izb b"IJ=42  )8V?T! +$w fH09W5qaԧ`̄:ڨT!j:O6ZAFH qjO.Ο)4tweD⋞wn]y#CHҷ4 tش͉fvMZAI81'BU( 8:ه#[{'vykc_s9Q&FxxG}Z}(Jc̽DpG2LgJ%pF _wC'^o  i/e:~TT:ءBB앂T{sLS`0`]1x<ҢkTs\[L3O$Wj]he<2aD-X2]~kdmQ0 :/ ((=:HE~'-e9K3dp!$TrƩ P,`HwEF݄P i,ws H>9⻖>ɊNz?=RxuQH)=ﴒ$U§"eCܺN%_)ePw=ޯinBPa:u>@' 1 69׉Yؒj*Mnz_=%ܖƞDlz c rSkSq'k.(E_t0M+hP 7 , %\j]Hˣv (fQHg8arHGjd(xZc;!ZYvX&ˆkp& 0rmu ![5rd_w3cEn@nʨv:-{AOf&0i ENǴS{Uu U&']j7:C>VwYOnհL} K@ѹ8Zf1Z UOknM?@x;'#sSO,ZYӇUW_>jkH SvU5B$,!C(1P^aAun qmWM?B+u5C&414,(hCA;([8}VI_ZۍF9 jM91X3ۇtWec\1_5jm#>g(yQf>dL>y$qs"I/ ;R96#>l#MZ,'}-$MCk]?׿P:Іz\_5' 218);$u i?}x+@^Fcٯ'@7_Hg+ d5{|rӐzֿ.G*+h 2!p^l:sh{9Hμ]lU> Hr( Lb 3pHW+fݩ 6PPEk,Y8$|}Hv.M9->ɭПO>+{ Ni8͠鐒-}=۫QVcg"EK:>{V4q"~ha&f rȴxݯ EFˁ}xojBˈl- 4ZKnpn;F 3́#է Ѥ[b.~ ;EB@xͫL=Jf=,g!&n 6PPWo/HŠZVŶm2w|Ƥ.[B0\. ^"jj✙i #(}aܿ'F0i ak&Чos$KX{ qUj+ӛBeKQdv]c~7wIUv$pG**YEߦͨ6V]EX7XgsgP(?97XQmu a9cJOPDgv*@i#b',w "ʝs"HX \?˜% vp axO@C),7킓p^ѥO<ûL4Cˢ>ziZAzڏa4KVY ˩.7AF@l=fxm J:$Un#@Gq&LӟJ) @  p t4%.>=;j$ieߙEZi;IoX\P?!W("UsZ^gTj?ذ/߮|3e`iv/ad6%vFk2 !묽FHahӧgu-E%bέAs]4Z)EA>ϔan5V?Ԕ@y |-ρvX1co(ZqE8bzÖKtG?EV8 kS&Jw*kqK(8]Z3*"'l+ p4]h.'*^ `#YX{%])^Q릜Q$AKIs\T !j3+}PZ^CD;@m6gGzҬg;bV!2&0s j&S>v5fr,PVqfe/RVli(aMԍWil`_l4` Dj!ƔА}R=RipNj,XO4 c3gv;zb):H7i<(ǛX7bm<\)"^:"RR%@lSG UOX7䊡gˬp6;UKlT4f/[7NT61KX7+Wr[p$4m FlA =27[&i3,eϋص.֘6)fb7 {$n*.g]=wf8/3`n!=W]ydwK}%9q^|z=t '.{U9PQmnr{id3+ьq jodǒ16@b+'Yܪ"/FG `q'3{>JLKHW@~"!v_ؙͬ^oNޡD-4}.tdiV, z)he1Î}y` aL,9!ynbk66˹;h*7!^\f^cӻs`bb8c83FDy Vsrlw -m1~5h<LD MVC% wVP*p-AOjUlx W$(26ҁl =P;m5"ߡmP0.n7ei&n`[q4~[@&-un&/LYAJGIlmra F\‚xiM'7_*DtGjPӕN(C)G/BTœ;ӟ2IJm_B7ά˦<> +;&(no|T^95O"J㟯X0ZM[NϪ?--!`P%-Wɡ #(q]`W,\^cNq10K< tXAg>X|T[{K*(psUXI 9}$RK(>D2caM~x> }ļy7O]л:ozr8#4࿬'m;}R&k+-]RLzkPOD j$h̟_?"ݮ+mX0zPre Z:k "&e)944LAUc^{_k1uPf2@6h>2g˘K!1v}HJG-jtA$= $(;wLPLg1R%tѩ86W)M#gSR6.a~?m,*a&P-_5J! M#9ՀxI1d1W4$W(T)-[] _K^3"5 g I cm]}P02~RlPQ7YZ!%; Ml@(Y[RkT&h7=}KE;!r)wGErsDamfƦIjPy758ޠ4dMt)'Lʊ!H ]YL xȓ> .NԗrwD(H M 16 ySsğ${=K K f&pLEr$q1s]LSu: Έh͐OI@ڎƚ\0Q63УV_z=Z3eKGͨpv}igpyytVfwҀλxIX cI?Zm})w9or*S"JhdAƳػ:pF]9"2 jmq[޻ӡab5hjvo1&GZ:^u镥[p﷫~^H^ "b#Q7A\ygD}W:lFMe6V=Z%BR;o0 %ިʬ Ir;$o7Xc!IU<_SU}=줖 N22fT @~CY}O!lϳC܈ޱ]gF@qp7Rp e CЁmqWG'\=WK"vc*?׳R;*O%WfH2ݸfW1:ӨΐٶjN5'2,vo EONFvu)j)4ὊcoMлU9'#cq)b if, 'F"sh?n;%H @" P\fi`򸘵P-`%٩~IҹL8|H􊒨؅voP˶.@(&x;>;! W2՝ M\wKva[wL:8w0thPn!tW,LΌNu>ȏ 3e9f#zKL=8+|$t6JΌ=$\*YPv&OzWR]2p~bMbdmc&2d%*d } $U44o»LRUm7ckU2Z9D+,w:5Sar#i"+Xc>[z;r02'OJ\nA7+>,4,, ŝt٩*}Kg]c--<.1LH(s ^`_f:iU3+sISѧNO?[*oJE@ŦދyJ1Qb6d\m[5K.[Py>XYI XȂ0]Sh+x|[?CQ |-!Bz\w3RG^ F<ūŹ佖i6,q7"#ռH4q?,Qˆinq,p=0ϗx3E%J4gxN[ϼopT!|i@M~CkXHvC-e,H%9Bɪ.okV BQ^q82ҩ^w%a+A͍t$uZ.KchyoeSGMYĶt}RI Sey /CZxh'͗/@CL)#V=w3ز~(B?Jd~sP" F+Kjo[ov}eL t`/p~jyzu pID+~xErqo\([}Togȱs^zzp{d];&&V\'ZQ2*)X}*^B؜鿨p 6FTuK^y6!~ ?ef{9}>'gp'|[+;~#$5|N'#'+郢y"D9+dfz+?ki? 8OgTxkZ9uCsYYu>oX G)0I_"W J-U/R!HbpӶt!)Hs?7M6:.N tƾNzPglGWAUC¨q HL& [Tť p{鍛_\B 5gb7 . wSOi v8L[)ڣ5NK?x umE"]y\' 1Ou<Ugٞ뱑e3Z ]:iY|sa:``V,5ۺX$gO72E2*1&e}C姄9T|PTfoA;} S);b~3giOjc:F'/=x]ی!R$rs`8!%x"kꊒ͋ ٞg$fr~b4c"%pu*ِKt=yI*;}+B5,k_#8iԏ5f`.93I"wZF8 s6iHxJgt 'iO+o*d"#)#\hEg$ XAѻjGM ,N=3Y Q]tK%XY/AuTKZԠD2/v YgJ-Cf+h5 'U}Q\V'~ Hⶸ[{PI;(U_1覠ɧ8(!kqA墧f1# 7Sh4į}|~ sBG6ru^hz7"R%w, xY FӒ3S(6!rOd*Gm' OE-wݐ̨"E$w-b=NA| H~Epc_@fDڒˉlt)cFyTY% =6Q$Vȣđr)ޣh$` rPX䢻fJ3K CsnxrL:XxBES`{=t4 ﳐ%Kz | ;Gδz65|]##gctEbg3͚E5x'hY%ճ7uI"fDCMZņ(=(T>`5R q`%SX' .L˖ QфQ&]F\Nx(_qf:h}шZWON=X,wg*nͅv$M^e;_aW%Vӭ1Fe"Y u8CPw09bFVFϝN-~\C7 xNނ9y;H,N5Eƍσ$لm5V:NJ3]h=78E/na)nY+c 4tv!#/xF**]/yQk4_8}׈S2?$!nI29By 0U%zN,R@ڦ<5#ϔ\7Yjx0Lm~fOǷ9|Ju뫗%nTN=㻪թ2Є3 f$\ QNB#zS+ v&h]UBZ>e(X&u[uxJ W[h!=zkzBTݒ0<YFi@J}9BklnW{JyjB@[:D..^`GfSs˹Ⱦ #8T(m&扸D!MZΎ ԻѭTb^"/k!ehD'AX?WQ>Lk;-Izȓ*A3.xOnThTq ŇIcIjBjl:'!$+Iꠥ[UÒ~|SឃL|"Jy=՜eK( һ`T"ꎐF#&%@÷6r`淁%{ s+ {M>~Ғ,#o|ZPj^i/[1Z =lWJ$~8BFv5uWF(?4 7Rȶ~+/vF\f p%A.3MFh ۅwP?+`eD.sXȎߔ zP xZl%WX#w6kw7X~/ $G\Gd ՐehZBP|&AJ&J?%QҘLqq~gB U7m2DL%uHn{uJrkE,fY%S pÛ ҽ<‡BQCl/m_ҏqEN S͐F6Gڏ=G2dJшXޡ8Ҷ13౐`U -RFgT!ꏘ2sc$R>]\(WLqJ@R#>u+ck@NULcS $/\WFO%7 Ye T&"YHjrʎ>3ڝSvglA/)pPo-8=oU`k8n'5?_v3 iXDG֮ةClx-9^|"p] :+"ˍ#&///BE9?2 NiF<-1åM)h݃ jt; (X e&}݊&X$1OPPe$hvϦXp-s>ΡYhNpr;ޓN: -E wvQKݦ[uijC)..aZĖ mv#@'TejH@4*Y#|(y݁tjp" %lni&-Է-T@ލ]7KP3{UR8Bm'5K셝ǟs.{kkTB U?Wv,z +|PMPQr +:V7&p<*>+-0vה2.qî{Z7Rǡm`76gC7;HrTowN5VvWbmk9gv.vMzU&:,<ht=ԑX[\~H=1U0,Y9_ʻ U7m`8L`[?b #^G FC^.ӈܕ-3ԝuLΕ2ki,&\,JQp1pxaǰI꼪+fw~`p?aTCA 3Be~Outb:şӣa v}J2~ }C o=]okhxϓ߻ 1Vmwʓ ߔ'BLzae}Fǁ2!I ycmdlyrE9AnN*0+*vU)8Q/w'JKa#eBg$ժ "C/EH75EM8qƃ)=OX'פI~N8i@.V ? <]@7ͱ˷mm!a#1V]]w ZcilVfA:hy;\?Fe3bA`}'8""JH6jWXJ{mqQe mơP:"bgnaQYaX^2+~G0 Yn'-XgGa!VG]F]쫂 UkPxI t  aa:طm$#Gن_ɖ5+6Yy >}˃.Ӏ9J۴wGeG nC!wL$џB lTOBZ90hGWZ0^?_#9fAEְqP?Orlvm$!E`eO[K:@9-HoSߜt)F; ="qYw.@\[H P:°pِ4ƛϴzm;}c0"c|P0UmJi0G/i&B `cnq( `V|ic\5 O+)` K)o͕!< o( FfO[㝜U[$rN/3m!4LP]^td|P~=h.eq{D-g n@q A}";vVM_pǸ}7&)ES9|8(>pföKzd< j <@=? eKpHwRDHN{2$t^KVI݇1@͛) iJ$gմ]3w_,NM!Z<.>ߴ" oB"nx/suIg3 8zX<8yNR}zv!:2?4#:`!\J zoB2>gCL>&uLGiP1E0.t" L(kgƽ?oL;VEK8zW3.ǛiV/z. Q@p.#-t#&SwҘR\țɟӡQymn1̶Tg{a]wG &,qۍ@%bJMF]'M߉}mKX1_LϥQݩt'P݁^E /|Iƪb6yoe%,(U˯ohkp".P5V'Y4a7 ">h/+v z[kyj=G2ߦk5W9vg3I=g:~C@j!L!< /z:9w@(@ m;XQ+D!.]Gm ѕܓWD+GrL2ϥ~ g:{R L?g9/4f3/k"Y-V43K٠ʪ 7aYH;ʔr71~1YCkѥpJS{P%|-2CIÝwH02 Oɖp,J$!yֱQ^nedê̞ieJ*\Qɪ EGa }/62$$pA 67e5>s̛v É C3C<%N\bm20"l$䦕祛jQۏMD>Oֆxam&R\~Ӊ9 64濁[l it~C!b]DRA+2.$"ј6=l%a18n ) I"ޏdL莶ۗe :?Z 2lڐ*Δ*> Ht{y16Nuږq;,j@.M̾(xnfRJTi L~qa%L vi#9Gfh${ahjKPzf~?W_v([[rP۹yA[F]XjsLk2\i~qgW^0qUn!qXgRd }{䣫7+ HMex%(lCYZ)dbƩj^D~Zx~Q$2yM滂`FoƕBX:FxjghSXOyl"X0vZXh?m@NW1yacVJ TjÊH C;PDXP㯘z-V\)y^wZ"E\!ЀSEGX2#oBYkQ3,Nfd@ ^OU`2 1(GJzeQ.;qJ,#_dEȹuwLo0Vjl'J̺Y#bUI\]eUaSs_G~߂okl4E|^ 5]*s4duI}Ɯ\CnZŒQ*C[i.bE& q>26AŌB^8<ʋ1kh>D/Й؏zA}`9\ Z[iqec_$تCXd,ŁI=P7w!fV^#Yy7`)y+6Hx5`(e(/K&gHDhg&:i?!KCo9{c)oA^p{,0!$ W-p:VK~NEϤN"PR]KF2Hl{u͑ʀ/t߷?E`(euVX<(~DW"%ݮ՜YEn cskQc wF1x--Aw cl' 3XU Q-Qn.QOsc)ew:b@B@=2,qb P6, ҕ]G04vw }Z C>6> a1_ f<@obLǰʥ_A᳭SGzz3K "͏)n!kڰZP/*;ixsAZh\6] 䛨I/K]-o;<q& &1޿?nQTOalCBџiQP.*ƻ<y>'⁉Cg9|4xJ& _Mx*1ls  ! k ydך8AWӪojq]Wm2O'"|j`nX4zTς<~W,m|g` `mEaleu?{׳oT ޡnSٟqaVXI9 $_Ly]:=^ D0|M8e /!Sg:mT4X > %\?QWQP@MTrCnaAJU,-$]}Nd+8LP/8/xY^R&k藉W:o"2NdW:Ѷ <;4 V4M͟ Q n\7`L>ARъ?!}:gxiּ些X )Eblܕ'xe7D];njmmTE-sٟ S9|W;lF^#*d>(9{^(-x!p5ft7uӾx#&7?۹ѳ;B*pVMȇr@w"e?Ńa @y ;<iu>&K0 jeE?_B"7y:?rI$t3RQP4'3-}4 +қekjB uU0fԔB0 p~_,t l%3A]>h@?< 2_Ac|SHQ7i1S ZWcƇKϲ̱+Tw&hH[raPmԹIη9Ǿ*d|Oy*hRCB^r>|Vi\ lC4kX=v=Ծ#w4f Tn& ? :ʐ=pP kV"`ӇvC# 0Xu$׆0Q"  uEJV@6M&5x[,@ɜ 7T}|-WFb2Sz?Ϗ~״LWHغLv]U? ,Xܲl +(,+0̯tT屆Qqk߹=;6vqbF5j!3Bv^[m#ԷKӤy@T2%IQi yZա  c{a ~ C͚j U.)oR;2ԩH鋤+?S5T˵c}ǝ\Rbck5<ugx w|2=z8zpi't:#v4UoQ^U'hݡ 31wc[e/Ο[M MJULηta00m~(h2L]-^n1 Cǣr)є+5<=[`1%c^ߍGBܽԜ:R |{ X19 FЧ(]^'STN1,R>_%u"3~Kh[ PF$9`caG G 2,̦2skΝI!sYj!MBYtp"׍L&x)S݅'t3dJO]úcGhoM `tn Fbk2u^FV{1dx[GΤu51s47c(6V# ̯$`(f]0p?zLFelz>LBH#ѣe1w”&Bn}Ǿ4tc`!<4 ؆ cV,'fa0K&\@b>vTju^2$!-\ol:߶i&[$grKœ0[^&Tz2tv>mm 2mwJ'^˩E_24in`cBJ,J_!Xsb$>VzW.8 | cm|G{d(tJ[`$NaLO;М :VNME,UxIOD;j'Ob(2HLɣ!dZdl6\fKA_$ߣׅ>"{7Յ9͈?d[b+y_QgqĶS>Sv68XZ z#셎2W#ɺdF>D\="Tٛ=&pumX;>&f]۴0ɘZR HobNH+5H|_3<9:{f, n^vX}8!RRqbNeq}Q&%h5M<,Ez54I`*i@pVA{PEwunm8Wk}L_/w ?mqNYJ DRi@ɘ*E&ҹuPW^sɀ,T.5۔iW!Waq>K|Z?LQ0gt|N}Ȗ熨ν'\sHႸ 6j &ө yG#냼68n[V X~)CA[ %~n~+HwGdV@7"NMڰfK?H .I(,}\GZϐ,* Wm^8p/brTggcG6FE `.es 6B<ۤ5&"Av 1Q'2-3d0W-M4âp:g^b|௞#10~QvE|Q Á˷zN@~vqÝjf7'nnc_ۗ"MQ4ÜokAPzJ,ض`!z{Bi",JM+ۯ[.Ȥ#s_b [?"g7GFCN%C!+aHZLMir&J&z-D&,0&̾!8BEu_?zк\'eW j<?GV!cὮlVק|y6\ }) =KRLe6D0j# 4mBxWeu!u6`0aq|[ {}e,N‡f˴O*.؎K,;`6 @r B!KN5=خD8^"MTp@SG]x@ | گ# n4KwQ+šu>;4~Gü]C+{:ӟ! S&}O & aީmr(_R!EmN!VCE<݅m~8Ε0=i`¹"Bn3~X$lE+s^@MDK&1xc0ődWCM.?'^4.lq q nʫ.&VFKWzWdtN^gmc|{O6/R"ے3'i7F/u~'Gy^@9!?Zw)NEFj狐ڷCo\.Ճk?/($_LqC>0qsdmyV#YۂciŔ(tM BEAZc Pl, }a)5ц-?}->jϦ]^ :+߃_WX(} 2R"|=#bWZВJ/ [Ce Q#t9#3,oq~L`t~V < x1gŽ1i/V=Hu)D˻a4`s(Ld.,{X Z /T ؊͗Sh]8Cw-Bzǎs h]/ \EQWcC>j:Ax\.OEkIm/`F•|ė]>>BurA .1 m6#m+@=xOvW ZԂwS=_ᙰkmJFdګtpF츂׬WW@TkJi(t @N=S&%%ֹp-I wǟho1[9vLz77'< \{[x=T}f2DnRHq67m}l# :.+j6}zv}$h 2Yx8̪yn5x=#v&|=rLĚyHdo6f O^V]`U)NED3%gZVcy}`W c69V x;.q'ɩ&3ܚN)f*$W[h,C,/6S 0g pT @wn> kHUTGd&rJt&іl=x/u- PvZ\KfcīDWθ`t :M;bI4;W%gstŘ#|tLz2i*uoQ5[3ے(hdz3R)x&"£>K]`-Hqk$ϚԮQ UL98`aL,+vn-8.nGtbx`cy$T1-H0Ө"Y͘{\F_ݓ5cl}Rx1N<f6A2_dRa_*%Q༧)}X`l|u$Ewą$1|bԃ6bH-%1jJuov򚝆TftXAUÊ|oPP|83{jQ]D] Qtu!g18aRBNic+}m?\Q4<{5AimWb@`l<0uaV. JZ~,RCZ8(hu6/u?%.<4` :aHU U0Z[W6 M uLT*8m#0H)k&y!cX3 J8u<ܖm Eùքft{v\>JanLk7>oD}j%9!ͨb8B/pNw0Gon,Kp5+RpML&LB\9#@^eCV}{5WI}Rw 1BPv*iphӕeח|9^Q:"U?pE] 󌴒s&'B:n \A`r}J& t5l^m1 z#pTHޓ9|T>CM&2@&1 ?r冘޽3##v[?ǚr3NOb8W9AeڎIh!\cfm[׈iw4 Vk\J14H%L8BO|O$< 6 ^irRsYŢhwU1X(t Ky6(:o=,_^?X_$D@W;LUW]Q0l}S爑IN8?o;ig3{ޏ4s`%n7M 9Pf(st#P}#$ QHD` ȞcI["Vq"Hv&?|Z:F)rjnm{J}佘0Br|qZ-xknZkGbMaCO6xFݕk3+);;{/"#bwΥz!DLe}|gf y*VrدO]<ʁ-0y#TvGnh*:{+5kCB߾':Gv#V4-y\GOr"! G0߬"J/=$?j?ZY ߟАa]@#IQ}='u74VKͤ$ZOŏv f":\KO{I̗gs\UMcҧLN ^]O Xe)-M2d >\jnW{I;ls. 4XXj}l ^NLFLҢzt]L眎Qur.qu{ *.d4s,AՕHqכZ?U0d4|D&1u%,Fo6]hACwNWWvdס=l e9aRZMwQe@īPa ʬ.D%*|sǪNզ18%U5M)l䅬&,JG >{L-e`kA($޸ D}5rӏiМ_˗,ZdG]6f[cjC X50EDZ᣼G.%%rlgJ4|cmH 5`h_O o 2}aЖX.2wWO3i(W4SrJG9;*˥ЗFKVtr`(Ф7y׼NF*cMT6*/4RǩeH?z(} a8.疎)_XK;<Χ9(L#_Npٱ➈L擁-~>MhQz-\ǂC0 hL;lxep$u(7oxUHR}nʱ:hƖz3vl^%egE _zV@ .A3.;t(*E9D ܯʜ,Z ue)si=5'/0qakJ^Zuɯq BfG SLɾYӯ[1imuݼlmg s61IY/ uxdu{߳)}"6>ء=FUd;jIy,]4#$ז :DXGQ}5mTkfD!l2Ul޴ej4@9[=3{SniHK ~o [9+,?uuPNgF<7BDٻemy`oFM1aJ/h+2nqjR RR wp\Ù.XK ?j}leoßRiS $[Zw+"78c8*$owfBoczqN{'Lxl|4io=nMW"`0͗yʼ ِ[U6>_Eҹm5/Vc9Fh̗^.a|7kRA&~Չ)Ԣk P _vqQMP[rPvϦSJMƔOfJ7GjiiK=A8~cYC@?=P>Jg YB#G ~TKV]E =]^p)  5#my^X-Rm½*1& 499 ~hBD8^>~KձH3a],V5ʂl&*lc,>c3-|Bpy;tĎJou-+HNU3.sNFqxa{޹Җq8a"hBUb62qpڂ]PjK%Wsx6W WȰ†h~.S :^}|, DUB_XTΧEƖYSHJ܇NHɧdG#sζ!ΊȨ0t o(p贍ߐG-P~C[ʕ& a4j_Dx; 7CV3+ZbN-} h*W/H^>ir2$:NV*3h7n)0GP/3A6ŀxQaT)6v7cK}vƳh*9>5 f}  &n}~$@ΊN1\xh}쨸}m`ͅy@?^遇uKL?ғ^!'7#gy$5ص(ylae;^8Ꝑ)< mzPI\qF-:aw~Z0 Cp&tDK;w>qk:OK'~RX-r_ l\(O p"MT m x"aƪDr$Ww#kH$ϵ#M{XoGnu.I]):yLc@^W0D,WYY47fI-˻TjQ!k5\J@7y]6:'!;\ZJWsi-uDwV,L:_TsYE;.4ֶL[n 󿕷$PQz6.\L4Lw{iDQi Gぬs?syZ1ѤՖ3mۛcdLAZIM%Hʍ$OPt}KNZ@rnf4 NM2w8&I;/22c2"5 BEwU{ʧAc S\@+ 1 ‡Y'xY>NwN|0?]QT:k04ckb-c6aَ~u H &c]ʳf~+ =ɮgqX>Y59鍇FG1ލ'v6U`@0r,9u7Bv:n+Dsϟ>y=~,)9q!͒' MrܞIBzClr}SCx~5qKvBU$U ~d/"R"@zعr$tseWF IoHuv̯Fo٧|!W~l2wҖ!fSץw mԺn5ϭLSjXK\(|iiE-pwLFe}Fcp%OͽċP\60I_tQJܞmx`pr 1QN}P*Z1p0쇘 "L@p!g԰ި@,o˰ =F!%{ j.6(b FZ{7aZi-=MZQ8"[8 ,C&DW#!dY=!k}"OPx؂7I7=|Ѫ,JDBP.3qA]QRy_"n+1b`Ζwn)[Uk1l,0aǗ,ŽRNoIM^W! /d L~Օϙ[HX4 G8-,@<'c,fqjhl:PtjJƉpP3u#Qx7 M1\~%Q!k^;> ~@/LdF30l !h_a]a%fw~Nԥ,yBAōWBqJ"+dS{FvU؆*L@1ʊ1sKOJgdz!JdkÕa>d}m^SA@Q T1/ԭuJuBl UFDdmi ǩq 0 P(z}SNȃ mEN< hⓗ_Ar(ءY/H r%rT(|7Qh`]d+vm)\|"" `:"5ufOa8#Syq !jˌ9mRHHBg+=@߅f|,ga % ܄t#oH]:m*0)@^ 8߮afW|r\W&PЋxqz(l(ĎPŊG aG ;B"wӮQԶgڐ=WQG7LtLtV=HhJr~;$1 kZ(NB!ےi#X @G:C nVm߫dFɖέ<_NeL- o`WѰrӫIAQ;BFz!F c; B:opf3Tb0f]5CzӑSG'Ε$bRIUF@49h +:>f sb#iZ \Q5̮6 tZ `)]گZEXCσ Jr&, DE&!c`$nd sMHl.kOTrG g7/¸=9Ek<|3VXv:%Ă:z25-X~`1ӊ<ےњNHqnU۷MGA\'B!< 3"߰Q tmj˓԰j-.oxb [rW/i7siՠ1iaiCPoIA&PG :z&c@Tn6E* |H>_IԂ@bD2vЪX0 DD6L {[9Ȁ@QF4|Bc"ۀU0DH@H>yK_r5) u]ے@#k^k1TMlÔ%oKVW}u_h&5MoWPenŧkfH3wO!7-e@̼=Tc|>[" 0Cv3ʣq5 Ν$e!FSOq>(jkIbp^:)yt(Lpx \qJW3XAsGX Eqa4\{jQ1}ppHҊ~瞱.Y"[` j 鯸/m3ђ0 HDxwP-CqH_}Bo ||tl&k_팫2a]A1.<,f[+ߪ!ɷL=Lt~nvlL"7#HdG.CRtwqܬE8|"F?\D"Vn1 ` և_=JGrwrE( "<DD/t4uƟ-RYIkQvOXw{!@"?%/spj38FtZh7e(?p !M G[BG" Yl/9$H7Ag"$[! h l4Bا&( Ds"& Qե dAbG"Az|mR| ŁN_?Rl$GD;u.u8|0 \͕!9,%p>X$ A0x̬h QH<^UX0u\u8bCl}%,!ĸqЖ­=)`*A J+^{o:mi\]}ʹY"nu2Nؖ mAE_$P^.$GgO|R# !&arfJ^S肑@Ec,t"Р"NFZ<o 3&ph/0a/jr 5>С ~6xݹkotrWo;KisT{֟^xlly̖*X]%7HcW.*!G{fDK¬uT^ATq?1yi;z03~{(QQ)`@w{,ğ2[W3@;wV9ܖRD}vN D6l+sr:A ]F|LHqegpo׻MzO NQ.9Z%< S9vlQVfmғ\4h@@ޜx ƌA%6%Q 0 ]ECLhZՒOtm-{QPujS%ASֿ>)pŽ,ATzDD(.J5OX%LjoD/wStsW2h8z'!aȗ׽󛟡Wys=(‘ >&hy t&Hxщv)HFytDzՖVDpo};75@6s?yP8wɨnSxZW #ãYDs$uȃ%< W=l1Q8n\?8er̓ eSl iEߪ .;$v $ou*ޔ[5US0ko[pB:Eqnqb+_}GpEKzl8u$Fޡ %Hr;LmCNcYĴ_K82ӿ(gdhc6~=^jݝt MT]5e GfDV| O(!ׇKrd`:&")tў3mqwC< +NesͽH%q # aH[#яW5*i.V_5n#異K_t iIN#1B 9>B+~:G;C:V_|ڎcMhLoYhl) =MUm)fDA.Ǭ@ӏ, =qň|Q_4$ek)rbw׵p 'Ro~VYj6ĊnY*9 r",v;! 1tFiPc<Is~ FgLl}4E~;ƼWAv!C?)?+UЫ?aqGIhnqYeV! @:q sB xZH<POZ7vL(܂_{IAZ׬@ 42Zb{@<^xWb JH}!mQ (!Ү*T֐D|?'SғZ|8,P "-B8\ *yеI*H@tb (Y *H(o!( vACjdeT=^LT!gv4]`D^ pΤ )x|ӥH(@ՅBC9SZh4+RY݉a3 qDؐ B~Tk[b"LBK^F"q pr͑c$OF ,MZJv޾n J7b=y@׻1"y- "u(P 5CHN4zK[ (u0ue2@51$y vCiƟ=J W4Z-sEY+ROz<Ї AQ# H7[c @Ȼ VP#MO$XG2˘mN @Q.'0@T!#~ՉSU!o16dXq I= ͞B`~RW ]FHG&" IRa4~,%} 4ג8 Y HW|+ːg`÷緜09AiIѧEWk 'f_Ap7"E*wyF"A!=Hȋ率֫L4b ~wWo\Y o;VTPzM@@O*Cm)RV :aO(85`L*$xKJVGnyY E@MU 0 }L9"#eC$ (D > ٧`IΖa~?4>ڧKpd:s@n:# rX%%F|ֆhWГ \/r恥=r۪3r~:=e`ч_)e]^q7mOಐ"*AB6b%0TL3c3X-$l7"aZz@cB!8pXʆ(XC CNfjqn tC(BE ~l ,"ξ ˥Ho~]u;Oe<[i0,yQev[UA']ERz=Noo6Uֵ1sϥYW'( V0[ 0rZYpQj0zvDD,BHL1GZ9RSGY PpPP@(*HC!IQB@9bGfzH >A4C턑˞eq y-5eP7;yIJmhB SS^BQ Qx>?^Tk2]vtB3\2aaR׎ArIjb۪rtb Eh `lNĊrz(}Frܒ)=مhN r@^$Y)"vO #~+D];:?ZAǪ2s#A?UӘLC sb!RE .nҎa/T/l &/Ҧ`ƒXMbEhwxU\k lkC qy3 xaD2μ%OYVD;=p( vȊr}`зHtR Vc{|v@jC}H= ;@P#(GAކܝ gwIX *ܿtb`w$Q&$T`a}U& "!g2v (, B uPH$!3OƬhi$OY=\x!H"x9K'YqݕV2̝Y c\MdƉW~$B7Y sdlGh&(k*"( ݌)Eě/[y1p:+x:Kd&XN'GΟCRbĈ5ʵkoZj$5Q  :Bv82@+?_."A &`f_4s⽘"HlƑ8{aXDüm#cKgE] @]_TMLs# b*e(-^Ƚwm{.obY!|,P_.&@VSƘ[IQ(BnGi)דlj{_d.͋6-1$nb-'!x# 6ÚPRĬ$W 2za\@T`,."q ,bȧۖ>eEk8 $8Xbit^4@_Àf Cgj{R`$`L$X,`ه>P*|hD@K_q|< u:> |J=>dy"UgYXbivqLB;U B[jH,%̂5ALDBVG8fxhzx !5rԗS aW4hGBLHkПANjfH. a̅Ő=t>E!nN&<~=܁ポN}wT0Ǣ+CE5T5Joo?K融6RL^G= w̚{iE 5Nk\ ]bnq[z۴`kA鍶XCw6eFKlޠZh7(iK7>S#[VmOu`,7|6( 2_iWy19ܗ( xc !Ů~= Dg9-RutFtdT-,F۪.c p+ݗX0 . O8HPh|__;N!L! PiR`" OjD z4!Hن(\MҶV!ѻ-jR2O`oA ɸ '90nA\sDy7]7]/S/h @ZO" }x9Ox ɩa(AxV}b?e ?T Ӊ>p/l`^%r^,j1 ` [C0r'Qf3 s EF)w qkd 0@87^A|oi&~Y1xN^]ȇC\(@mE@P0͊Q#Sp9DVA%ۤyč\5I߼xOjۉ6h3v"լ\X;E=> 2T:Ws7B QmZz4qz׏Q@0\H{EГl8)Xmq 0PEy۲Kcsw'sOlok8GD=G]6ۃFvu#=ׅ\xǑ$=XKl%+V%&a x y"hF\L>,7K-F &t!rX &HÊi`DCD$Yk \CE`;>% yE *L@12V[|~*4!#!ҏbor2@bR> jưѴqE7JŒHy?"(G@83DG1Bz@Q++PD7Dgh_GtPWPj#:bgIk9 CF5B@$rq ! TD/E#`%.(ԍj' F H1 @/,\!݉WD!/ЀV y9S Hq4Ɖ1 .p 6Di츺 z"@ #0"(|#85:s5FPbżL>|U#`BDy a ipG:@mëu&=Qm/3S`Ո87ɘT.C< a-QjJQwrw+# γR(giӣ?f=N~CX <Q?$+ qZ*2SnSa {^JRKPb[޻ a*-a prXb@qs"@݃Ȣ!CItCؙL.%b G !q$!>'کsq&WB[H}*`Zs 6sdSg~oth ? ooPgu7Sk{5 i)<)v>h!Ji0=mڑ d@Xpy%,\d rIߗ 2FMBxԷy֨FIys~ _Z*fb#skBQ_R39|b莝=Dnh(,iZj ȅV2!ʈ 7srzA RR C҇~! k?~f=Y"p}ez."_9GIm!)*ab 3e Hބ'r[ci\TJ:^=zM ad0a]A &pM=$M|@ΐ^t'O\EbPln $ڞrG5'It'WN皌MжW:O; E>(FG"^/ ߑ>gP!Ia`5XFy$mm8ZRyjǪ| kǸ!odXeUuC@kMYN0uymZV e ;3 "ېs^S^;ACQ mceKqywrrЭm;E_8[xDy _ 3=amIC:>apE o xXrWts|EI6,2Q]n_9"2EN 'iv^>X 9.o>ezh $ۈ]ig>`QK,[],Xj@`ٻLDZ8^t _hJD|]Al!uJOlf,n|>ei /-_tež/Y7N9Bq&,"6C Ea{MA%>0eKԪۤ9OSߚɿ/6wO_=ڰa -Y#cO6E\+YB #p'c`:nMw+Xcd{i \|_hYիm`3@4^[$(O#qEZ5u%k1H9=>)_}ևC:~znLO.L,< "һkcQCዌ>ZLtJ[3  j{>Bž[ {I.ӎlEo\ +Y·?KQ,$1[S>#wU~oE7Oxdo֫|KԿ>b4,9\I0QPdzBӖ[T.Foؤ4ݐ]Pi2Ź%} $Ȃa tiq= .2| 9jnǬH,b-ɩŨQ j(oT]ivƐ(qw-;zִ=& d8_n#g ǛY$קx=嚭07/=-Vmsp:HڲZGO.׾"ͦPOnRf. >7Щu! ƃaD\=;Ox/2FOv" tso5.B?v\1dm۴[TZ"{+7_yH1"3cM-ڃn4,m(|;5xiL7}@M Af򜅜.ܒ*\'7@ 'R|4_X̏p0CKիf/l}alu{u "PXApMJox;GZ-7eTEo"ݓ}x,-ou?1a˴<<( r,LֵPd5ːvՎ9a"N͋?dy{]W {;͈Uy&bfM9ҽ<Os"vX1/nBny;%>.7"R.G@Z=fa> `Fd xh[;D?曕8(-3{:du$u khI-g~L `i|Y3!s1 aDg[-_V765*firQ/cO/IH_Q-΋\7fhRPljNI;c05$E 谝gs|?A]%L#]AٴklݭZpP2,hnPBoᓏe*L8XEu# hҽ]yt&06 ]~8ϿE<3ڨE `.#MaTҲ)B*UuBMl1T w]x׳Q(*Uy0Qna˕C%zjHr1OR=r\ur ( -[Nlq?}n APrU⯺y :. ?Yu7e w>l{{+xbu(!G&ŏ1RUPE:z|ciQf3s?O|}EV8fTFKgۼqߏTa![~N9g֩½aTSijÍ36QޞlQ{sj! ׬@ =tٙP(:Nqjcԩ)p. vQSLna[o=_+5aTw1|Q{~Z&x'E;l@Zs-UW޲&B$I^yRyKⷊq kKSyJBl1Teᩩٵ\{v^Y}wTVo +/o@;cTFpP7$/rz?fiϦ<5וMU\dӉVF/(vij_YK$HAhSLB8"5(),(6޸RF4o-a Z:sۅ +VeJq,sp!ٺ@@}50c(M:槗d(ty5$!ǩO9Bdfd:ɬPRʑת!-VB#-T#Q@U_érf_]K?yW/'lǷ51E(jB B `jȭ7ӱDH_,v{a/O`C\eJ|ee8!P#Ɵ2Zt h5{|[]+2Haazimeܶ%v8U_a]ɀOĭ`'<0 ğd?<4|^Q&%ҋ!ۗQ\-|Y5#){٩Z"oCg8ʈGR7fwA@.LJs ~IQD0DຕwXNYm 7ԷJTաN:|hSRtQ`qA n<( :A„nG>.Q}FӃPV!sQz-HƜdI6H#i ;JvE@ tjm2/Aꪄ 渻€mbQ/SJ†uqt8sn7Ɩb&WHWF>۴?̷ujܫ{tV-mrU;`O2[l3B`]I[5PDϝ8E*^;:^Ӄxe}T!F;׹UKp M"}K5;ޓ%7m+ջ%+mt "BLU}ol cs&BLM +Jucj]6=x̫ Dwƫ3N vޡS1 H֫^'lYK8^JN o$:#?𜰄(xAko| p﯁HCjPeO<3"z" ljadӜeo4Z\Xl٪c4q.//ڑ?0;=Fhۈw+9Rܟ#{t 0.Xs-'u#I`QVT*f,;9.ۜZTY;1'ڂDiʁ֡!K νɡ7iıP6iW!PKƾvذ[t0Yř`FV[hM'9mA:<ʡn0n kzih}h+Gay*j(Q ?$NKپ35{:5 hmo[O*wΪ{ŝd]N$nߋ?i;g~@-{gAnp\V&atN^4߄dSNe>Rr{n9W6iω / rg=iAʖ`Ukݮ="5??."%q`m/&G˹Akƺ^Au!t.γ5ӫJ?At0b^ ՝*[4ѡWs׹%N3UoѰ~JSW`'y]u|:ezЪ{a'!=*ƖH4#pʅKsQ,tH~Ik˭|qjKʱO-U!̨*ssx:X: Tc-]Mc~k|7ȋLJo"ړҔκTa% ,t/a#6щuĕB\֜?@xy)$a=·CֵV&$|bc-?})ԚapTi=ߏKO(STDOØlڥ[[$3>y[FCn[(1bLUA? Tf=ͽ&| C^QC^gTw??%u.ѧ7θal7F{qgt?O?-bK/Sn] \J?4xm[7l+k@UaSvr#/%|YI8rر|nyu/D:n" XXe9}TkI!ohg-*;`ʥ<J/5pp]'Z?wXyDC+Ȏ40Dl/*~@A#|vl{EֵGl.g?[078Z@=|b =;r>e X-*RkVXx(lkrA&18R(Hvϖ4t(-mߑzXv"ƶsd('ՙQ^٥׭9-զZFpM̦kRb#qEf|Yn0f qiLj(%ߜno&b^^%Fo(.ޏ9갑#H{b 9iľK\ 7@A h E; WQbݢ̊If*p8,N)#\(gUYZTO#]"ގaPWƱW5Zə|uϼ!̘<qE{VE5 Ssh/ -Oc]یpz+X 9#򺪧6sdC֤!2Zj$Ykuλd d۹y;%Zg븽oQYB\]_X[tfN%tLk!Gؗk㢞u*% /dZh:gk?ZhĪ!TE[hVJ0Kk;2*YBf"%(a`b{L#^pL`cd*:]}y'#Žp,ïC+9zO" =xcht'0u.&m[6H>v*jr9?ʎw{mמ)\9uzi|r݀z=(6p%Ūra &I8MWeYij7\bAX:G/kii-eQ0` {@(µqfƒh>b2" . & md]7LI͕dBD3$AQ˝4KzeP~-mO4xc7zS3 =ir"".`"'5z;@gpv^8&U0D8q)?@$Cf8am] e >h@X@?QbIҿTK_ ֙܆6#ކYCa8{&+ yó$ -}"_cל2ۉ&0ڒcz;g0mk;Udr=ԺrtSqwkַU'L%pL+p}0$!NLlBfq(ޒvƘXSH>l1}%* 0HvJH&qZ2DžPK\E88JA/+9 ^Wh_,SS/IvqJtQlW(\hΫ}܅oJ5H )H6{4z xUD}hɥeOb{#M\Ua>6k&)BZ1Q-j~:찏nBst|ma D"H[j+Pm(-o/uy6Q3T2]˰t(2U rrop_\-Ŧr,ۘ?D> e2p/x6fa^YAyg4v5~!"4Hh!uzz;fD<PBUu8|K ȥRu4\a5[`r:T aG6= ,22.6hw2$^޹q*iTq&O)\. ?RN˷mfZvdeor22I$O8v۬+Z; _{>kk-.s["Kr;u]9w].Ë́0f;#L\Hc9$D;={q735^[Ph^́ 8"\4i!fT (ŭή-6!(ݭ;z_3a4ퟦ/rԼ9rB!_1$$-?hDjeg;!q cQjI4P%kϑv.4PEvUwгw('<[>4|D=V,Eahd{X,n.u <ШAXJ~ϋ3?S_祁 PEF` oۑZ{:vv) SYBsElZp. x\L~<.,p5e;[aQqee6)1_ʐt! ?Vzwřhו!YUk+ƣ=Cyš#p#,>jZCu҃;k9-ps߈\|9Tr8p@<5AԣE+\F<^(u @yofJᎦ[9Bj~5VֱQ9::| CUύ6KjЂ@!lV\R&))M8#BZ! \f97`X[%DHL0B~!R/J}"ʒI$1tXހcf +Λh0ۣ{^:[[y-@y5)?]mi|Y䦼&5HI` }Y\QI 34M3jzef"0_]uˇHlUe~~eX ڦa$!50c@twJV`;0W=C̕yOv|=ۚ÷4]P]If7L5eRK'%KaQ$܀1t;!I8 5xK*؛ v""n:B>=(A;X|cLdѮ^'{˄o{F\`y1~Ie;$V+^om!]ƿY!\ VsN5o~rVJ[΋Y񘋟n܆mC6nǫk蟥y4废G[䳃+Tq伥t|q- $l-.DW=VAmvQ贞N~Gud-Sx q STy#0S$1+^t X@㯼Ba앭ҹ~mqAq6Hsî߲Z˯HtwqHx_<'(Z(4-t ~ݍچ_\ީɘxrT:aI_+wG47#u60Sy) nJ!0i?}s2Rjp`ݢ:ReeMC:haИ̹}y y@WZS`D. 5 ɐ|lÜX/m)؈xUhBlMaΉvpIW\C !a hTӡ w { 7f͇UKOL\n .a+'а,\^`9Q1::ì\U_N`s} 6xFl`4)zWsП`'z 1_C3gKԅW~$W(Dz81Uͽ1kg ; N+Wf!_a1W4cڵ$m/~si|D㿗eSvV*┯ZʜBdi7n7(|2F 6R2E&oV/6 e6ϋY2b vT -͹g?A^n1`p~tn׶+cn{Gɋ)V ϟ!qt8Tm e|WȵTsGOQܺX9Z&<]7<4<]姚-DB'˰q)/86'|Ԙ /{5nVAOR5 K{JMaW] /T+=rK|Vr<[_y<}ko|tkdx*a/>SV<|R ]H3J+2a)s)k89lG@S!X-P U%{V,~ È$wON'Vꇊ2ؾ!DK$8ld5gASMNw?f\+ѨIRb~O S-m[eay YHn 8bojHC9x7Tz7 ~9Y zr| [ 3Fm1ӎ2y6yC\lZ8)c~` +8Q owl'or8W1HE1L=n.t=x x2T$Frf?{ȦVw1%8{ V}#w=e! w5ϲjQg{D`B]b/:ˢAzJyF&f"4 t&M{=ӶXE P<2 iP'Vg.]'8-2%8q7˹Rc˸9bq/Lb9%QoMG㜄}4mX.5!}'zqi3*q6+T)Sx}Ma,3Hԛz5K(sN:2Rc=:<6w3`qٯҟ+MY4~χUT`ûsl8Ƹ^{ߘ}+Tvr;^-'\JO*/@t11>?ш Z1(;nug!!urP &d駞7 u?[jW{){85y;g?p,#!tK)xeW/E }:z>,D 1TmOO.zW"4@V)IKR.Q`\! PHqd EY?.o>ޞ?b8x@6'1̎;{".7 a]k6%AEOIpi"KulʕJ`}nDC!(n/ު_vlM `hzz&vaض;,;n .e/֡fXAĚ|A^(B1R!K))li / 1o=ʯxj\IP5}(?:a$O5.ќFjZ:R " ˍHco`jPh4*EOPt lIt!%H; =& ޸>{wѲuSj2ίjiq,eWsL%! $.osk40cxb"oY>}xu92DWed8wߡn-||*݉ڿEdTBY]o X*QV>PT6@X?aOzQ\ us,sB7xd[)df}zxW檧[H!힮tοNK(ݱu"@8Xl~pjyvƞ~aF,C qZdܖ ໑F`I@7T*7,1K>nΘozpJM|=j 1Iyym~,J= ̥sL7ՠ;+]/CЇLnܞz+_S޿rf %bۥR ƚ8?є$g2Ϝn9G|u0!~D0+&@ l+*+9ɫ'~.S} ]u=|j]tQ|?Z 9oRA0 @ B ^Wl4Ar1Oْ0\t6{G}kr[:c5}ZBL n`G$A;9GO0dA6l,iDti}3`>6Ekza["(wl2z` n:Ai3Ty&3vBxY2ABMp\!Bc]wh8fWi+}#[khe4s,UmFI8tAJ>I*ػb]~CN c@`D@Qՙ$JZҊ? ,ϻSBYD8߲@ o"P _SrL}U?@A{rW_DwGuMby3Kp8#delDP7 Wfjn ӈ~#v8 ш;L3 mu4| f}/ܬ^Rrp?== L~O oҋdaJIhgxvɹB`wZi|3Zx C-ܗki0m?9x9-dĈ1K%xN;~Em.Z/T%1;d,at TYJ*;J>B&=EX)1{)Iы)ǵYM6s8cc0MVkջ126B4Vk:YbkEǎĕ΀=XFvf ts=a %fKdԱS:9yq[P|\o\%fm]yH\]|̯ a>qsK /u-tTr]$z 4 کl0=cUpy {F@~Bqx͐5H\Z B$b@|@fܧo'|ݵH%aW~ִ8ǿ/ #; ._rtv˧$̺<>lT# /Nآ4GVh9{שiʹ JdyrOj5:Z+ =,>|i0J wSӆOZRjEr]s߰A>\ñ$xH+$w}xpz.e`9U=.-pi%7cT[XCH~n4?YVvk:# W޺h/^էko6]yf=3E]vMXfPVB JGPzZJ5vpGlǬ{ dHHr"ueliMr -a|@~R<}9(էv Ϣ9_:!tx_Ķ/l1HGoUtvԨ%%tu0.C LӶ"eB2Hw9@!X @혾Ne}6wXtl UR+y:O+^˙e|}HZߓ! ;Dk4-AP> OzQ}iO^H:UP(<]rۓS5]'gֹ\-!!hw խӳZɊSqH 3X>Jͤ0Jif+0l<7 dFlB+C$Ac.)]Ix 'b:mR Q:%V2R0Ǘ?s ]ȵf3Fȱ[[}s+mN*S;)0?^SHcJ'!ͧ/[G3',)25CydsknZWp/c; 'Jz\qy^'dY+SF 8T^ܝv{U KK;%IOf,Ymp3m eqMO M "װǺDX7Zf.z݂|jH{Ϳ?2.oȥ*.˗{ë<%fϽ[LLj5\:lm#.tyi;pwf{9~?m\mn*Ejv 8bRV^n9[yj9D?F@+\MfVjZ/)od$~N7G xCѺLURC ҅{޲63stsE8ś=/ 5fh;Ɯ)rÞ?',u'Y_S/CKpz( JG.@:  3HA*gV{oҀz iq9Aty8ե7|U@h9Hؾ]@ H9"8WI4 (6RU%1._'c>==54{YQ: L[bθv ~0B ?u(^@<}k4/Cl)*-:ޘu 8a(ِA1q\BJW@55qA&ļSSChO# ONMRTu._K7k3 =(!v/6ZkVô=~z=u}fǡ*%p7EqS,"iOwM^ C,vv:p{?JՊD!]rFUXt-}eWذ!`n%V̐ Mx 8.=3l-# U3*׵R6kAWi\Z/wn8CUI f*@}ª'L @$G F~$9Fklc15-c5Gih6#L{<2C%5hat?BԖHYMrFΧW@_z8nQںlG 90b/u&*Pqw b$U|@,}pA|gM|X -MMeE{{Ow>SkWJ5q`\"YQ!p%%h/ `OC ^-e_̛ axk$Fw;F0*vC.Ƅ^snѽQJNbgP{~l=Ex{1F4\oUM=ll4V"R԰xApXAQsǴSVWjMp}h;7¤ݷoqQr|z!Hα 4rq-asC%$Eأ $2wִIpN$[Œ?;ix[Z9rb83SF{N. q cǮ]Al#/ͱfXlrί\.}f $&>z F; A$8B81u3 1^ZV~Ɵw|.! ?`bi/GnylkBiVE=Vs1жЏ}4:Ea]pkr^-@{h[\ ӨNn/w #_q$RzΟٽ䶞Dr:/#w)=vWw"9|L&sVDdT&eQSȰ ӻ>=..KVFdix"J3 wHGwCԒcVN:4PpEIY:}Up0b^;Fyl.OKT~\5 jc=>9z4{ar^݇ϕ,ppw|Aq-bK)m76z cQ,90B@62W4=|_},w3jĹؾR_+GjliT+vO.ɀPuurpcV^CYUw:wm}ˌX=}T4kB R~uW)yLpl}JFwu*<0{շ|=-Uq9G L8P+S*]ْ”h{ԫ~=e|xLI!b͙Fzmrޚ+ث|ˆ XO='u^k~_ )fY`jۼϩܳY6!vFxr:2izni2a3/V172LַC#Ow53iX8z}/*pһңwj s:(E-usuFTB!*@[/׶ш7qB~UкO-xwb•s^UJDo?~` ӊo.)xݮOށQKw?j֓}H%wB6*R^WڬxOJoxDe$vHNZqo;j( kQt>p0<URXRAݗ̥eMջZo\6Zy\taǨLۥV1׬HPA.Cr/~Na\'sW~z11/k[D`|G4)f]sb]]*̰x$Q7J c?ӱC0DNȞ 4NJhM b79 P ztE2Te}_)l;?D\t>I]yZz0mi?ȑ>6 vc:6^.*~BV${ŐoB422#96$:>&6;ґ ùQL //o._6' gd9Ʀ$Ne>E$)!F\ 7PBqݨa4Vvq^wds,{L(ywKǣ4vns4=gAPaV::׺toLyd&Xfq>v~ާ](u 9aV*7 yyW$a+ԲX K>C&SoTTe,uhvܮۖ+ KvPjH|pyX .g]n[5>]Ó]^6ʃOѳE$uV|7twpr Ỏj"vzW'}:B%[QJ队mbէ}ߏ-~:tO @CzwD$Jh }Rذ/R .%Ծ4$X1ו$gN!nXFh\U${5;;g-Y;jTHO`%wS.˂1 0qo!RP`*y9i$nt* jq睑uahڏikF6ZV^ mcm=['v wGlq =@:5^fQ8AuPEZAţit J'uN[+o$'qX U.5_!GWeo|lo_cq`(؍;3=77 om&` 46 h8`F$~m^ WsW^y0GNl>jAݞx+IyB/70*2emCWqvg0Xڿ;7 7򹻁o@L{&\V5B6sЖY TRqԄJz ' n\J"J&`.TOs@KЗHx<n"9 jUi@(X4v=N3{P\.Wf.i^o{{?H1Uźcu@n, m6X(Ae& prNG:)\}\pL cg-d(p:uj2S9rCse:7&!M*;(`cs,| 9j̊/ҬfBttz2 s|b683km;;Tr]׍CzjWs􇻔?j2g[kΈdeD\nφ¶vD GS̈́W3K*=z@n/?obt(c*i\對O7ZYy6_:rvQɟWypcVEtST:n&=]>5<Tuv{CN]?LH7+5|$ڔM]R>!S0AҍLq׶n:Q͖P}G<^uY/#n(3`4(s;6mu}y:_㶢xۅ!{mMh(s,*nlSLJ.nyQЖj*783!GSʲjخ_Yj|-Wi"zq* Oɽ#h3RoJkKVٹv>Kޏ,~@xWVؕ>4'^7REulob xWBTI|Rm@? UwKi/>?+4wk1iwp 0!ÍqF pcv*1n*^Ac[>ضBpɓ4M׊V_j(%M~9g;z.?y+ۑԚcˆ1@|z(Gm#2Q ٠3)#yn՗%̗cxO>e˄?JWT$Zbt(.Z}U7dk>i fFTATI6_{]̆!5P5C[WsV/DZZz)r%pvzBC [UP.c㑈鮻 kQUm݆!}QGΨXbؐVqME@s]U{D1>,~,v<>#&dti ȄRl=wjCqo?HpIIRAQ+Sm- sRCV>ğnaU?]?C=2A" 9$If0Q` Ւޝk1Ҡ'R׈}YςCaZMSBS #. ~Jt Wgq*FwM Vmj3AdCVqjct\~R=8 5 { PEa. 2iLqY^ 1Zr~;ƻDOzk^kFvV9CMI b9`CqVƵ~y.C1j5.;V)o`m,/ ϑpuQ_8;,M+׾3Dw_x,Xi0+=MeLa@/p8Wi(SqmT\]P,|Sˆy/α^^ @D9j"+ѥB2>}e?{tJA#Hڻ&CP-hi=^IjG>ɕp1)ycyb&O_4 M=.CZCm()^luT='dBҹVڋQ-)`3{0{yfE1;dVϡ/XB>wS#)[U6=Vㅡ=` LnBI:Q-JTD3 4ةP"g?/nY$~HZ?Fv0غVK į;t ը[8v;溻N1S7qzb ^2+[QˍJ=e$7kƪa}Jy< Q^۫_͆xG^ZLrW,@L}(ůsyQ<{p0ڙd8'lxMV|qEo6-Z!`GmxR)[~!0/hzFO;2{ye[5F [1YkeJ%֖IOWJrM3]C\fE\S!;vl֔ʋ'u\/bANчPh_ e>얚fi)\@?iuB`+gGDwxV/.@ݒjȦ8|>)2C|M}okm-Fu?-fH0 xԻ{l.{STvx'o68BAQ,"&10QB}x)dWvz[]Lށ%6NTeR^?hu%EKY1QU f] 21'*1qg0)Մ֗$;SľDE!pcLqq8u iunoI;AmUxεx:[P1 ܝGhn`] <ҐͽHH߼+? >a?c]b~z=-M}hsij*:@B{ .kCR., 0`r p$M TBX(-H,"k"֎>" }~@`4&-פ/QR Mva[<`Bp0Z#-lJ&G9==;ِwH,äF AD >5Slo„TārL5ásNXT m,J\NV?rB8w [8Lk)7@2#8KSBrP@ZgkWcP8J|o l_+}6[HB8[DMCT"IqHk+kICM wXz.Ș;ƒEf\> W| o?W)Bg6\;:ӡ5 \ʷ5H*bn񥭂 "f仭R=V}r4ݾ8?5AQjC.]&U AQ9qՙTp4slx(֗nY6~9(-؁aH: :iCȮ+lGDjBN/#Sqgd$\0iJCUIP)2ȴۉr)qor]ȡ)O@A$h D@ # Q`(oHKv_Wl^rȇrJ@cKqLG$tyVldsH&{,VnHc&l[G345lPeGw/{@et!M'Ԡ= H(Œ?;@=A-ؽ2Cp$Fյ'>RkXp>0,آd & m˨ӡY d͓^1EP@tGRhlUj Dk(kCsp+6 } 4쉏J@++ 0w,]i_H:0)4sU:E&EY-])#֌vסwb/ YTNa>2X~WĐwEhHן"aM5^@@C6I(:<_]/[Zdb:kLq]#cXiꭲԧ&<֔pA<$q_`@%n]H]L#6&0\K+`0;) 'NI{\ʐov3DA@8L8=͊„kaUAa4.N`(։42(#F|=lQNໜKt dirɛL,x #A db4n'5#^-GlJ@|2 5{|儖! ) G;9]? )7 z1m !Ey*z⸠E' C*RBj${]`4{  }JW A^>5Fy^=_GbJ""Z=TJ쯞P.8Ma532E tIxHW}ԅ"K\ajIWȐ1c ѻ.6A@IH!q4v_ 5gO{nqR4BBxn%X'i_ȄuY͡JۢoɀpT,^;(2A4RA9EЦyHU2'x5m"EAL %ޮUM`Di|O8gz[Q'ª>*ܧ;}εNɄՒA# ~ȨDkcF`XhS]R @Cu滫ma(zAebsgԮ@nqF|HqM0XB6ɽ55r@ ʲHvF@BY*U7檷zsURo>$hgH֒3BM>7`P&P;Jkֲ DTD5k})T$HTiA@@y:,°شk?WWYl=T#.+g+]mY1ýH/Af. ^k#rXЫYT&|X;$x՘q|v;-Wn(9&-

X4*'uFDBNqsx|FԖ:F^";Ƹ\vDI794^KdD̑x0{2rҌT9:n\F[`isX*T!a FZUanݴ Puѯh,oCz l}j5/&^D:d AmHT>K~G7t>kMo_0*9_z;/`# }-;[vG{Ob)v cLĤA732xj.YuYf](`9B7#'A2QX'8uhv51g).2km[`;Ɣ^WFC{ @E;1EXUYYhS1 o ~\(C+cg~Qu9(WM3e‹hX Tv/crNPjw!bMEqVQ&-IC( smԀ0|62D*|!QZ%A)4 (o$}|ӳ]"*5>\$u[O[ ,a Fo0OۧA(i{!_BX B(d'KS1} O[c[P軕)8c?lOa `Haĩ[e l0 &(e(yOM, ' >#WXG96=,o͓T\]WZ h7X8O7,I r2talACژ&( ֠\Bt@OgmO,AƤXEµ>n''|(RKD0?" x.FiXn"`.F^(Gf0ne/Ϊ rQ豈O0V`w:jq4K}2UAb`&x Ebz|U}IY܀ So*HQAԮaI(F?U De[PǏdh !gHwx ||` i eoWČ+,ll,])IO :='7WR B\M1cGI"Feϛ%9u0IQ|c먯'C./Qh_6gyc}na~B&+{/:K.2u2FfO>^I@@RAU)Aܺ叻4wZg,s<sr1ܦy_2kr;~LZ^ tx).͂y}n_eǝ9P,[$ㅳ flӳVFT>'*}jA  ( /J[X!ùj_yGVitMx?L:}JwO 4ccӵs^*#I/vNpQU|uðh}2 VxD1þQT !g+w e7q}ϿXas/ժ.|zݐ`hPY`nS=b } ߍv'rX)S:lX+^].8B/WeZFQ=GCHf++"|lIg #J@<I2ai@ >1J Cr(H:OkDP?̴hk ާ6.dRJn"'V:xrlx>Vҋ5˜;X5d'E)~Ee('|VxyAGW3Ж w;y-1'[@Us$J)C@';,Rub=aOhp*Jx(H*ҬǃjOKEGW;@OCB~5K|Ӎd|, %A<N츪Yr] \Xk6gtT|l\v?6 پΆ3Q?w DAeA"[pGֲ%4NXzRxNĴj S^ҰJ[s? 5x4]Mk(/, vʇLZD[yJD@BO'u'h(!K5A[ 7EUwz:] =c\(;wsgeKIҠbYUԟؽm-G򛝢ϖ`ALdg[1]7!{ ˅mqFI삻&_zea"<"jU:נi=3\cS_?'d":"O絺S{߽uqĴQ|W])KhRN:O6b; 4 i-c_1*)ZU kT^9%Xw! 0J1ZՒox0ΖWZcfH &Q/o v9VoZ2[ `v9s_;m9n\BP6Ik.U]obH[༗yh_j3 B 1_MCCi x"*[y_˃o.Ae?W5_U5-7wD'3hvCQl ?O?= zZn7@X)ƼE*w-y>'-Nsk>BWaZymX>^'L],+%dil dp" r$|uB\ p#* /V˰8S4BJg}}ٴeQ@ pOq^̨8n6]uϝPrk0sXJwm.?]tun%?r zJsAY_oxKN-BGI՝\yj)&Wa xَ" >dՁ,Ht(#[;Ӧ@jhLJN܃|/XMJ++z!ތ]\TRux~HOTC pUO®v֯z[{~`0-۶;qf%ŘN]$20ME:NM_|!*1Y 6YmWI\+& c1V-e;a Т}W5Au>jZ?&^/[뎸izYȝ*w$@OUv됤mBSoYeT1j |TcWhЯc<,` 7rlpSp'FҙFx yx\JY6NQ(VG0`[9 ͊ ÜM@ԅ`BtI \M;;)̗֕ XrPzUI PzkJUʂs,Ayv].~G2&|\ K =1ì!858(~nhkWHd>2Z&>JA<2=]l˓Gbt&Bi$2>ӫ;" Om&6ղ9Ljb˛enf71ENM0?U8&20oG r;L?3lg;ڔke$'gd7y_AR= ΓPk< |I}̩U=@(q(>)c_WG]lQ+,y`Dޤ6P^W+T\!RO!YSޚ(n Q9zoBYoUbgluWl: 58PkyNF(تUfk* h Li%ojŇ7ɼoԩ카!({HRjWRYW(_tasHcgEᴥ0SBY \E=WP:u˝g~\OOk K|""yKʼnZX*9'[\m $#ss "LQfdv$pgPX =ykk{[MVi;%9Ŧ&5á Q:_bTMLm9qQYՈ]&0l ;mM/K`ܨI5!5?Ln9S6Q}+Uhb ,sRWL}CĬR@.ꔈ6(P_Gc-kHnP,Ҍ-$ 3xS޽g֍)U_z05_4 n0]'mJM;X2rʃL@P ^1ۊ| {ӗ9`Ԑ JpiDŽi}& PTn?LC Xٶg9sUm-=0XB@b9QPx&Gz   Wbi5#h$T>.7b|@b!,煉җѓqblc&w. g۵*;3"Af/AfsUώ5+KC\DDx* aHkXkG)"i()kUbӛ@}IH єhc|(dU#wK!R:KOh q3TMҎø,K!=@6V|%Os`f[P.d\, @[D܈ ^ =ƜQ-+5;CUj5/( 44a4APrb ޹RJ\Y !dA{HbT)65ҜU_;TM.xZE ݱ`²^ )hUp=?2vhx%}P@Qg HMprW8:f0:>WV- ,삭-kag_jͯA?YB3?'_\$qks]\>)*ؿp 爜H mnP@~O9MtSka10"/V\ @QC *:Ou,g-Z'vY)b}@pMR"x  d0 0sYsG+ c&)YK 0gp8' iUhwUמHz0Rv2}L.E;j3`ZV(3«LJmݦrʛN#u^-d q>=N;DpozJ<'ޠ|IoVch;=^ɬVڦV_mH4r5tqN#!M,ۛH1\&_&8\H{~GJ؏Jھ) =u/"Ȧ/TGKch O?u."Ո A//wk;~^`•SM;B̍ 8o.X2`:=bcN+l`*(k զ,ԧCF$q-_en!o !MR42eW4|o9都ػ~v*m1v4z'F/l_$ =\-'W!ZGzI2=&Y5"9 n/AyXWH=fZT/3? K,1ŕEJn!g_YsZ+|M~!}Mӂ79۴..=5o8`f6 xNm hiU}Q7Ugw>qd]I 'jyCg^5'F]N@u+n}nv5r?/_6k$s)OEg m)C]_(jidqCq sV?٭ʥڒ^9(Mk퀗iZT) lF ™Ua5fӛހ5Ķ88Egh xQpKn8Z-kj[( ""IE~NT4H_H́RƋW 4`+Č7V˾]]$:@_\Wa-ڳP` N=-z7PF=q_/+Nk+ 4eEN[d6u4777<`yO6o`AE.,xA~B  Гx !|,'VL4t43f6ir\(n1^ *_/qʥnC h yr'on _&՟Y yz%\{GT1;A1ִgHڼCR9ʨ=fvH:B:b{S@KyN_ϑ݅w8p{ex1ruqPI=M_}i7ܚ/rwDd)BJZV.zw5^5ŖY0 , zRst8!]]I<{Ih&וO_d^B185G]}VQR.6tvMEYݯT M k|؊]^)H;5Ŵ2zc/Z7N/ݶy=vBPCLUpL?⛈3؉\gǾ<{ A+d._Dn2b]Q+[/@Di |e<P[cj 1LoO;7l x>8 2^2c{/EOtZQK-8dbcj娋=/ҲhǜMNk+וWUV(RwW1q+FUA0- ꨜ j.û.wRj(@nN[^l 9ʜ`jWnӮ]pصv \dk  *'foa;Ь){Qխke0{W8&Ţ˨-Æz۬YH,sc+sCh@;RNm QԱv dos*a_ﲗxZzGCҰZ#ɯwXj0hd uF 2%>FVV1ۑJY%"(c9:RQuEXR1bA~zA#"Z ] ]aK8t6Iͥ^X]r|=*Sr81$iӎP He|J@&>C}{C}jo6CrȰW=Z ?*O)͞5I%ܛ@ҳA{Gl_&hXWWUނN~922d[G)/M > I8DhQ‰kr_Mc8>/kuޝ"Gn7x;uRH.OxFnOIKHw$n |ϷQ=B:̀<)_O*c#$dN|p݋+G ?ˢ(c۳5!$AdT-7z»0|v|k( 0-OV3C憛wY`e jXB/ڋ?-=O1?Qvbsqǔ]4z!c5_C*F'U-H!{Lh蛐Ŋ8y'$'IG_1 %ٱ6)ą5.T[G8wlcgIN!nKV#ᢹڸy߅zПm;'ZSxMIy Su\b&ʊDܨj @3U(HaJ=A|'iCC2:" :m95,!L 37Z78{M&pn%^KbS"lAQ^l+=6<]!\ьaH#0Xo}̱C:C(b;O R}4x,n{}:,Ht9~E5kY7B^ƫƿ@׵g>|^Is,8EX|*:\^ЫR:8H0 -8N>Ow"Fиl6?[z.n<9˻0#]FQØY%QPD(DoFp osh1oVZLv|Yb7 )Mq_'*)\|} ".v о)Uejf(IULLJ@c6s㜃A⅞J`/Xs uDB2zz Q78(ϵYVm[վ} WDzv"d(kh)hMQKd+F~q2%{P`rO? ,+siGkU8יد#dD؊&X CQ~Ee^5j C?w<0l,k~ !tْ%k/5VOABV)M0:lujw1]c3ҩ.va#s4i>ԫ,ky-Zr6V(:Vߧv ]+$m)g r %0[R豎'J.~f] I WYlAEK%찐r B@fjjt.e@Ŗ%v*R@DGi*.RL#a5k,ƭ%L 0v*CsƱq r@C8Sߴ#Ge~qstzVN6B=A I^S/^&yqD`@Y2Ue_ sM4UFXzm9j f3aEPIXq=5,ts7'8)S߅QVAj98wU!2'  i[_ULpWGMZ wPY+C7mi1'<\-GA9bl[ZIuRD_k/4==@\\K⦯ `%׌Í,MDZ+`o2[ńQtRa`#!ך-vc8ѢH@kd|1q5 $׿eB\)T͓Y4*!0Ю]r -i~ ^[ș^B0Q1{trɄĨ8;az9T0ڋغSsFf Ų\ hBp4ߩQV?y)]`?ιlU|bd:~cVt4eV$W&!\k\ +qHTRY+h5OD㸦BwR##i?FUBG!&vA?毿li- I.zY)4zjRԆIS* AZѿcxaw_vf_l*A~(~JV+:>")ˡ!θ4POMIxbߠkz(s\i.9o7@ZFԳC֋8+p+x$V }`'?u6ᲴNq.WmY?´.3Co\^c3M\156B~~X;c=r8֤#mJ9lIXLB$BCy}$9 }Kl<Uh>'2(?eZR:x˕/T*!a |UŌ22-1,wƽ䆄BZn J0^l)mqfeWj>;W=ǻe7mz l!5=5?&6zJ 3UK?l>o4'uH[^Mkx(x\%lI=ذ{h 0y^[GRؗRסC%( ؈Wؑw"P?{V`yAE$8< u=OSx/ׄsi;PpՃf ]7DFdZR(=jGWA**6Y9I>x WRi$>kzQCt}ϳ>pCۺdԍ>cU Gux?`ӆ/n~Q,w9eFeT{rF?A`aCRybx6cNHO }ksSGcD=s2>IUpPˎ>i2My5E!$۠"f8 ̖Y [iN~e(MJTM\ѣ0&8FϠBP.(bA<)@z}$ǞHE{*}R+>!'OBN۞'mDo-;2 LEzbKMQ^?aWSz'Q|m@y4)v$swEo.szhMGrzޛikIc1yxkXV.AsJD6KՆx 9!e>m?~5Mu?JCԞ#%&0i׌a ;Y#M Z?-7zzRko { BIoT{ nAI~AXkM!x/խQ|4_؏W3M7[=2g0v<*&k ;Cydlg5] *b 5ffUxj{[}G5H\#ISm Tƽ\'8W}TTV;deoڕxȇwv^> 4!XDn0.p;aִo yHp 7+Z៊ \Ќѳt@?Mh^ohnN&Cj~W*س[BǪ4f̿xÝN]9bXS \-&zdoE%p_0f`}t?"S|IEO:TqE(7B|܇exro8|- &jqenmzl<9~֞=΁z"VVg(ӹRe[Q]tawmUUL|4AV(%bC]_Ah=;klJO=H>ZӘ3 5Sk+v__XWD^0c810)2n2Yң-|M]/V[ShysUxY̭) jp8mj q0k΄~wWQGG;l$Nd}C*8:`D=]G*[G`W&NUc-Q9=/YY UNe|VD0)rz$IGa -S|)^"ij`h[Agh}rHuS_c/o4YPbZ. a^B([ 7muLsΠ48uBᗘa X zqڦY(6kIHΒ-m:yj~.vO3Ą P&}IBv^:#^6sJntnPeyپx>E]87l[VΝ9,qW2 H >r;gWIuҕ^ݍZ-iZ_ϙUutLU͟ʟ9e23v2lSmG0,~ѢC-R0׍[s2=g”Z{V?Cw41; V U(9Îq >P \R1~_cjpG:˅MOB+]r:sMm,o7_9-0L+2EȈ x}uH^xټ^ zaH>Q\6Xg5?|u)hd#,W2  Ο]Ђ7F5JeQFn\D5ĒJ8V8 yqx 0*HM.8h0X6.Ρpx'@hԍ !1ty'e4L: w6Yi!Fqf~֎e]:ںgEOZ\.QӬ*AZrw< 1?lpnm&œOߥ>+L-K ]MU>)σzً0L[A[3 ($P9l!s;9iy0~fgzΥG 5Crt{G1߮4xdV@i~C~vS3 MzlQS.Re*,{غ_1QAĎͳ|H4cRDΙ}egN $b\׳Ski?]ݽnƼL:gY|{j!X=xqaW#Z !o\e#*AqjbRN:֕Y:D{i=UCX, O/"1*"NIpңuV^8$^ڊS?I 2[a!|KOa`4=m.iъ+J1wJ 0\3#Dљpԋ 7MPjjߎEy/Q0U޸sk;l?@}:,sl&PjiS{AdS{_bT2h9z'B?_;F~_2d)m}p 1TKpܙIa z12]u{l s߶9ՃĴ-`|*Ѐuvtc.OVv XXn7jCu|:ǟǣⶠ=YFTW?v#"cݴC䚥3l|[2N[wX&Z5d4ig| U.Ȝ8ڜ6=;Q w0fOS5$ߨGG42jd x :;U,?EƪVlTH9jWy5JB7Ǩ9Cfa'՛}R :Q4,PVvxxc[u֚EGd!{6jI8N*M"^ˏ86;?XTVUԷE|8ZMkN3諂T6.X0c3ł= ZR$~8 +;O^Do9 SuCPe=sqUqlfIs ؏t\Fo\ŠMş}hypM5 syQw 5m'7MJTTN6;x!n0 Q@[wt8Aqg@橢Z`)m;6pCއ2$f\RēQ#HvG<*½oCHmcbj \÷Z(ٲ Fa= 5 U cOfVxCq,O``ר;wX:Q̩q{4D1" d[D};Yó9NVظFCmn_ݝVO:{Y+|[Zyuާq_^"Hm', Fk@#[jȒ$IJ;5/YW0oc0(4r0$AoǤ?/x^V7*m_ſ{sP:kƅKHBA!NϡY&g5GlF?gsY"?c?[-{{]rT* ȉr7-\ 5Ӟ?[JrBFl]Drk?>A}h ڲ4SaWc{ٰU ӑ'?n iaܰcos{VA .kTfu1"-eqB n*?n5?2S˚|irfRPz;l_Ӡ[y9eӔuΰ%o2elttbCjۮΘM(3Kυ8f'=$@͍@Ymfah[?˗A&n%t0Voŕ9ê/`}1->y!7,IHnU&!Btxj! !`4Nr}; \7cq-8az19]ۡd8HhiHe{eWJ e-_Y$wg÷_:xD$B)ȥ-)z l2q VG够GqiI>iVPt exH חlrY#GꬢĊ 캐ey>'*tqt%RP 50˻VWvKyb}0|j.& !صt M?@fr=-E{uod8@nGٰxg/)PwոAR"۬G'>QQ>v7k~/#GI lLeTU?&#~d$YYZ5mE'8:К ss-u%yt%27 mpP ߯nd KFXC%'nP0=t t~ Zm3&w,hA Zq-Mbxs*ØHk2ᑅWDժ6;]sz*vxh8j#oZ"Xo)|5#@M!*dZxB:CEEzyM/OQ6v4PVp!svhW` b8Af/ "6耿 :ùFM..G:ɫtDx >ŭQ%zZ-67q6/7j}İu#OL.,%:xfPO 4ӡ;ɤ$:pxbT Eѻްp=%bM ƅ N!M.) jA1P xqcj7=eoғAvJ $%m.:LqR[E+(97ݑV̘;/E2Ci׊ue-򤞘["Mpo!qPXdi֧.LVHz*&Q+EN2z4ޒ=!iֲYx8P$uU W︷{dAHqR>&5Bum^-SX9zF-Q]_A(.yx'9Sw[oXEx =<:Wp8D 9##y#P^T'X6bJ "}7԰Z<'jRGcH56yBFfu@m j=@tDa\*‘rS %o.вWD v!Oi'Eq/V~xz{yCn_O+{K81u5$RGX-Lg5N`k0㧋"|dI7~ĿgPOQM$>46^_d2N;|G~통 ZtpEUc:(9V'ۤnx+f oMX9ivl~; Ķ3)icB|-awtbʞ)~r8CQlSyc.Zd }lrr{'y^O5 mYD:,uj~ԀtEU^6MF"0liq<_p SA2V2gp{˻Qjč;n1oڳ?|f̲\:~M~x!ϖkۋV/\C+ζJ˝>\EP}?%ijC?_J`9yI()Z! k$$ \[q mKd<&q.L<;{NH|$'_q?;_w:]7Y K]#!,{,3ni6u'0ىǯj_X*l`'4/c(1Hny0s K}a񫅍O>'#""Q /o¿a3# ?) ޜa"VXU biZEXx:6m )4x-ר9SnLc6LE@WV dJ?;jrG:ȭw}ߘLn.:X܂}tCL_iOK(2^ꏱ3GE1ɏFC(yH a{k5/g|?P$UH~i R%JD&~)H-eOO$l=!mF`!u,VEQuxY&7I*G`pu _w2}3I\hj␡ڴ [+8%ݻH , T*]œeͭQyx#5AJ_ë?;AKͨYozJ]gB@4W^s7"OKX!|9DWf܃;#ٲǙ.a9|VN ALm߻;cZxONHԐB:Jc^`$pEIq^AE[U\T 1R4G_CH\2v4 "uGc0k(ᢡ' ߛC*XC7z~3Átk\Gq;ZJCL׉p³-U%W}ug K-EG5#.ԝr=g3WE-hje1`J)ȯs&%Kj%QT E-O'9^)RAUjNbѪ%Zdc-v/7Cuɠ|*.1O/u؂@:is-.[qPE1mѿ/lqslVapWԅ~ث!}ݸ]Fyӫ5g.W+*aig +M js~Gm0lAvBS)j2zBf~YATsI @UDQԜ3rcQ_kR+˜4 .{ڈnݔ߀#,Fxg<^ <$R. r5`C+'o#맞enV/u&g9FWbِ_/ڎrsȜF!K.d{g !;=u8.'dkᅿ~r+f~ V;8=Vn߽gp54č(nj5{y͖K:~:Jl]V篶z@ZIʕimKڪ29#^3- Z &O %s̪u ,|B X-IiK/f{WB3F5/2WS /vVvGp  K* {NțC!lOS<xZ]95  ,xyihz'>Ucý\uvǓs`k$Ԍr~0?>70~RytK14P9P9"6ꅙVZU( B/&:Cc X OKغVu,֐|3f]?8t$NnkeAbW-wcտOw𧺰yzNy΃[ 2>0웛5N %?nK1Uq"tjExŇ;PAF/6䔩8 Uǧ 8C8Wqk0ofY\+J#xjm›D;|5ӴZg6o(KElSu, > |"a`鱾:,*+\2lwOæg~g+ {KxirW&G3y 7Ϋ_@d$ы˴JWu#2up"}%ՃWrg>{9+>{R;]bJ8%b%X!x1GKT+ /k}չnyv~\C*3-~kNњ@Yt~٧{|ZfUQ?Jd=[ӣЦqy6H3_= 9pI~5 {l~cnwk dlTT&f ARik1 L!vVlAAS>JbSDC>_|c]^e/̷=/SN ɼB:^r9}8g0xfՅ署:Ǡ,6vD7"0t`VyX 2_k9qWQK:/d8ꓠӏisܗ/ 2Os͒h'9Ot`6C D)(Ԥ,g|>*>QV4]Gݦ-4󸃅 WXBjyع9LW[TwOpݹl5=5 x9E}t"{o=Sʶl bi9KIEx׻c2UykbG+S}%$~(5H!BqgZ-x5XePT7:^_lȋ@=<{ ۄWֵƀc7RgsU/SQ~Wמ2WF>x,)$]7mSztn%HD4' Nk/iV+!0Gږ]w^AP|.m#-y&gCylz!B( hS/5HSO[akQfn'ӧ*+Y],Ppa,j"UU^}ҹЛ*L^8m/%My笰 7\CԆ>bȅvs>2,zԣLhp^OU-E⧅m}R+'؝Gr)򅛌JkŽ6p WePӰbxZT_O hnQ_BK9qܒ馧.ⵃLFY<ݟ f<=X=qw;~5H0aR[E+k>PR[S)>ȮX* c+;Mҝ1w* X۞[#(s2|*|ik^=DnVM=Y"NH.ӆ4p15< 2ruE6;\.K<ҸU5@[!;/tk{y-3ۤ o+6\ٱM [rS{dnHc9zSφ٦=2|r}[t Eu(Tr8V L8C3 xG%DF;u.B812fb>1L$\i&[<Mc(A&/).{⥜Z+DbMIiI]%U)%Syz@!ւ*nC^rGR%j~(jDER4uMy{.1}C:yڱ߿ !#F;YʵYmȴ1Q1 +$}oưǎۋ]Wr^( uz}ɼҘym3L2xN^X7yHE-xX ωѠ?'8.aRla JxVwqsQgH1S k Sq 8Mh-AP}ܚ`Vg5 Oݮ_avLEX(t/m.]3b\ v61XUpI.\F=yFױ0{O/aۍpQհ-/1qL J7]be"aQ'pۅ;UǵQJ B`5N@ XiAB3*) y.?TO~l벥|T];y;vػ%ۍR\^zcgmo?\"&vu18†ul[~4Đ_2vVv ߔB ʃ7)eW\^gt8\X+wa0Fj`(jy 9JBr#`q QnK^6#w+<|=|ĬSG9er+/_A?U55mr=u:\31uvLu5!2G:&ސIH{H,aOTN kEzґ0tEa<Aah\t>WIf,q5.B09mtv$!ߞ (ZV\UtW?dq)ͥw;x3ZH`DԊ+0~9CO?G`1C:s \j䖥Pze%>6ZmcX TwVхѠLCϚx߯+i9Z^ SH{E׉݇z)$GwmU0]#p=.=eJn0.+8O{fhNE9,3EBDxRA] GA͉sjcqd4_\nL0dPB>o2?簙+&UO觡d}ֽ-g7"ZdS(-M]D@p\ƽdh6m 1p]r) z48~7O%'KO`Jxb_+ff'INXnFrb%o#p:v%$" mݤX;= A?o`Tox!mY:=x={v:kNq% ӿ4d.ol1 s{NhlZ]̗[Y=HWVv"rbeZ2,@y+y; xԦ"T`NDWWE5Y?K>)zzB ]gJ-Ta֮.d08<$6 TT>:P72: yI'bbe#\`n;*UԲv>P !7X"Jpe/@[΢J+`PQژGy#|k{WMv~tLxyW\Lo-3M^fl+ $5İ4Q1 Jzߑ G}EnxCM}{Y]\į4Ӑ ,Kƺ8 f+x>dw KpP$WBFsϠ`wF$n "hk+?e l<}wR`9Yxќo]Z3r ^]eqrW[l$Y"vja.{80X^~~bKM5nFvh`G|a BCK{qL;qy7&l}fOo>ͩCqU-n춧\ z,}sh#,Q. Ԗsh8<H8%OIOO-nbA{W?c NpXX9G6Z pQ@'uze#*?%( O2pQg Bڔ䝼MtѴi.=d7c7;ܫQRS-ss%>JVPbZ?C׎snSWTD yͱkk5$ë* foZM L*%6%Ӌ=鱬7 J|ŖݎumX"k+Ges +; Xӑ A*lS'-QC0I~hИU6>?ҙ_z?cl GNIp(%Lyg:JU8u9Z޼bg4Yqby^5Pi4W}4BwNQdxpXCT'́2jE $əA geKtpHkM\6RxH%.<(R] :޶?txpAXF gT@j_{0ANꈷp!] ea31 [+ pצCqØs V6cJ lz +8FE5r>LoSԟ~'Bpˊ5kqzZxc.7:e8|N'0t &]|M0|ruΊ˪W\ZPBׂȈq~tQAHzdG-l0ʎ q$ڿ#zV!J] к*y]|AS?eN61-'}4< Re Fe>8x:9Sp_IQ ' v*[\{vkyv,,E7ʸkd݈tc@=Ieۄ չOEA%QotRgSű߹kogTfY)Zc+ήf"T*GYx)MBndbwx- %P]hfD >-ASCtdw|ʏHӽv)w8ĖT*ubiT\^(tM7OcLrם\0hƳ[%U5$_I"pYTsj| 2mӴ6nq u1 F,j  N9t,$O{9&>w{u?d1kdj8lW/Dݓ/ ,wWBg_}/ޯ@26zzĸB+-{Z^`MtDbutF 1{hAB gH:e/m.fد?3lX, `!Au8fBB1WAw3\e* "[ 3ߺBYӱ\5d S"HvD}s 2Uo8UU&!CNX`산2z['f_!E&l##Ez+ $,A#Zdsܪ͒L@(xȖuL5G,Xyau!R\C=]ɒ "ǜO{|^3 XObS 7e"+$M@KiS? 'AR̄ A珢  ']qv#V;si=AQ eZ|1$HHUፘSmKO~Wp۳LUSkV I"-D IweS>`d#|KOVq|'CLu 4 5! ዖČI yL%/'=9NáZn&VlFD=B9 ;kO|BGu+:W;/_hmن޽p]Mc'AB'Z 2Rlq}O  w9NrZ,ki >է]2.~w&`)CG )yj}N>U `^.f'xiqOɿ4nѼnb m?]']!q ؤl~5@71!Jܧ z R lf8L s%Y 56(>فj!d2kv?>9;h= {E-7 J>2 Nh2׆T'z7st4 P}(`uCt_)t>X` %ȏ%h ^(f֐|=;4\RӥЅMYOm`.ƪ[8J.RO$00(@w4u<po-Bԁpî7MuL{%( iZ-h_): PϾ84G%|'bֺDŽ d!R(SУ!$ TYWOf'YpILKmg]L?#NsKS[\~_a~-8TjG"y ՝?<͡㯸PF}, v0eЯKH *rؚ|0GuSy<|F?5VVШjY y:Se<3z %AlkH+prw}[iEPq[FV.nV ezi֜=q:nb2 Ri]S)^i1v@R(@ p{$D0>4_q *Z#t7Ȫ F  k`m7"ƯiA.YC%?<s#"9X/+<"T^SS"4z操y֌-ţu;9@Ndӿ7qV`^Y =SMy2-gr& 5wIN§v5`k.W&rMUJ!;:OM_ pzi'M!t6E^Nw]` ppt4e9WYJ c y/i.˽ꝶ)C|*}*pAWk*^xHi+$j "=pE7d0|m~Juva G=`PNBkRz58\gPmdl ^E4d ذqvIH + ٌ-@6Y}!cpN,%ecΆfO{ݮkÄʾAhn dF^m̟Ok.8MvCJ&Ʀʝɵ;~3h "*4H0qa ܥ>L~N;4&A[h^ANk /АZq" P~ӠP-p/D!e ϳ (ͺu(I\ϱY&X®8'r7| $WZٓ1㠻({aDw$S aloo/data/voice_loo.rda0000644000176200001440000000332614411130104014413 0ustar liggesusersBZh91AY&SYLzm]2wwtmI2dm#hAMC GCF iѣACFi ̠ 0M3S4Cj0i2ih&FЙ4ɂh2zHh&4zSBi4=M#a04MM'h jI4I&&44=54zFCi C@d2j4 4ɠ4hCFC Fdhz j= h4h4h 4h ͂afIʨԀp,LA, 0̓‘u+bWJ;_B|GXX b  c !e,ŜA) C[Im"qF#Hr.eВeԻܕ/ё.3/h` `0jaA2bLP̚1f0lMNQV PpAd%&F01nHƮ3y*؁Kv 2#68L%fgc>oF5Z#BAdWRhUܡ $ jN :}\Y@ŘD3 S5H%rڊ0gӌON!| ~.?=>lpB(v :Ġ!XP'x|95u%J%ja":qH|8Qʤ']wP!38 5 h,m߯D $^ߔb۸,9 f8r# P| Q휾qS1OsSeD SwG ܜDbq); Ay&vc/UYftBU_auuAjOʿ4J!1ҜPE c+㵩D/'T(IG_FQ~rrBT2Ì87B=wiRb൘RQJ Bg֥mYF- Ҽ°l{|D`H"U*gN=zYS*AWXB<(/庢NK;\ƉY8PMԔx*~`indv `oOonax '(2yB!2ؖo5-I8U]d;/tCGF.wƩ2ȭS@4[]OgQ;9襒 N} or \code{p_loo > p} indicates that the model has very weak predictive capability and may indicate a severe model misspecification. See below for more on interpreting \code{p_loo} when there are warnings about high Pareto k diagnostic values. } \section{Pareto k estimates}{ The Pareto \code{k} estimate is a diagnostic for Pareto smoothed importance sampling (PSIS), which is used to compute components of \code{elpd_loo}. In importance-sampling LOO (the full posterior distribution is used as the proposal distribution). The Pareto k diagnostic estimates how far an individual leave-one-out distribution is from the full distribution. If leaving out an observation changes the posterior too much then importance sampling is not able to give reliable estimate. If \code{k<0.5}, then the corresponding component of \code{elpd_loo} is estimated with high accuracy. If \verb{0.50.7}, then importance sampling is not able to provide useful estimate for that component/observation. Pareto k is also useful as a measure of influence of an observation. Highly influential observations have high k values. Very high k values often indicate model misspecification, outliers or mistakes in data processing. See Section 6 of Gabry et al. (2019) for an example. \subsection{Interpreting \code{p_loo} when Pareto \code{k} is large}{ If \code{k > 0.7} then we can also look at the \code{p_loo} estimate for some additional information about the problem: \itemize{ \item If \verb{p_loo << p} (the total number of parameters in the model), then the model is likely to be misspecified. Posterior predictive checks (PPCs) are then likely to also detect the problem. Try using an overdispersed model, or add more structural information (nonlinearity, mixture model, etc.). \item If \code{p_loo < p} and the number of parameters \code{p} is relatively large compared to the number of observations (e.g., \code{p>N/5}), it is likely that the model is so flexible or the population prior so weak that it’s difficult to predict the left out observation (even for the true model). This happens, for example, in the simulated 8 schools (in VGG2017), random effect models with a few observations per random effect, and Gaussian processes and spatial models with short correlation lengths. \item If \code{p_loo > p}, then the model is likely to be badly misspecified. If the number of parameters \verb{p<N/5} (more accurately we should count number of observations influencing each parameter as in hierarchical models some groups may have few observations and other groups many), it is possible that PPCs won't detect the problem. } } } \section{elpd_diff}{ \code{elpd_diff} is the difference in \code{elpd_loo} for two models. If more than two models are compared, the difference is computed relative to the model with highest \code{elpd_loo}. } \section{se_diff}{ The standard error of component-wise differences of elpd_loo (Eq 24 in VGG2017) between two models. This SE is \emph{smaller} than the SE for individual models due to correlation (i.e., if some observations are easier and some more difficult to predict for all models). } \references{ Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. \emph{Statistics and Computing}. 27(5), 1413--1432. doi:10.1007/s11222-016-9696-4 (\href{https://link.springer.com/article/10.1007/s11222-016-9696-4}{journal version}, \href{https://arxiv.org/abs/1507.04544}{preprint arXiv:1507.04544}). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. \href{https://arxiv.org/abs/1507.02646}{preprint arXiv:1507.02646} Gabry, J. , Simpson, D. , Vehtari, A. , Betancourt, M. and Gelman, A. (2019), Visualization in Bayesian workflow. \emph{J. R. Stat. Soc. A}, 182: 389-402. doi:10.1111/rssa.12378 (\href{https://rss.onlinelibrary.wiley.com/doi/full/10.1111/rssa.12378}{journal version}, \href{https://arxiv.org/abs/1709.01449}{preprint arXiv:1709.01449}, \href{https://github.com/jgabry/bayes-vis-paper}{code on GitHub}) } loo/man/loo_moment_match_split.Rd0000644000176200001440000000720214214417101016640 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/split_moment_matching.R \name{loo_moment_match_split} \alias{loo_moment_match_split} \title{Split moment matching for efficient approximate leave-one-out cross-validation (LOO)} \usage{ loo_moment_match_split( x, upars, cov, total_shift, total_scaling, total_mapping, i, log_prob_upars, log_lik_i_upars, r_eff_i, cores, is_method, ... ) } \arguments{ \item{x}{A fitted model object.} \item{upars}{A matrix containing the model parameters in unconstrained space where they can have any real value.} \item{cov}{Logical; Indicate whether to match the covariance matrix of the samples or not. If \code{FALSE}, only the mean and marginal variances are matched.} \item{total_shift}{A vector representing the total shift made by the moment matching algorithm.} \item{total_scaling}{A vector representing the total scaling of marginal variance made by the moment matching algorithm.} \item{total_mapping}{A vector representing the total covariance transformation made by the moment matching algorithm.} \item{i}{Observation index.} \item{log_prob_upars}{A function that takes arguments \code{x} and \code{upars} and returns a matrix of log-posterior density values of the unconstrained posterior draws passed via \code{upars}.} \item{log_lik_i_upars}{A function that takes arguments \code{x}, \code{upars}, and \code{i} and returns a vector of log-likeliood draws of the \code{i}th observation based on the unconstrained posterior draws passed via \code{upars}.} \item{r_eff_i}{MCMC relative effective sample size of the \code{i}'th log likelihood draws.} \item{cores}{The number of cores to use for parallelization. This defaults to the option \code{mc.cores} which can be set for an entire R session by \code{options(mc.cores = NUMBER)}. The old option \code{loo.cores} is now deprecated but will be given precedence over \code{mc.cores} until \code{loo.cores} is removed in a future release. \strong{As of version 2.0.0 the default is now 1 core if \code{mc.cores} is not set}, but we recommend using as many (or close to as many) cores as possible. \itemize{ \item Note for Windows 10 users: it is \strong{strongly} \href{https://github.com/stan-dev/loo/issues/94}{recommended} to avoid using the \code{.Rprofile} file to set \code{mc.cores} (using the \code{cores} argument or setting \code{mc.cores} interactively or in a script is fine). }} \item{is_method}{The importance sampling method to use. The following methods are implemented: \itemize{ \item \code{\link[=psis]{"psis"}}: Pareto-Smoothed Importance Sampling (PSIS). Default method. \item \code{\link[=tis]{"tis"}}: Truncated Importance Sampling (TIS) with truncation at \code{sqrt(S)}, where \code{S} is the number of posterior draws. \item \code{\link[=sis]{"sis"}}: Standard Importance Sampling (SIS). }} \item{...}{Further arguments passed to the custom functions documented above.} } \value{ A list containing the updated log-importance weights and log-likelihood values. Also returns the updated MCMC effective sample size and the integrand-specific log-importance weights. } \description{ A function that computes the split moment matching importance sampling loo. Takes in the moment matching total transformation, transforms only half of the draws, and computes a single elpd using multiple importance sampling. } \references{ Paananen, T., Piironen, J., Buerkner, P.-C., Vehtari, A. (2021). Implicitly adaptive importance sampling. \emph{Statistics and Computing}, 31, 16. doi:10.1007/s11222-020-09982-2. arXiv preprint arXiv:1906.08850. } \seealso{ \code{\link[=loo]{loo()}}, \code{\link[=loo_moment_match]{loo_moment_match()}} } loo/man/nobs.psis_loo_ss.Rd0000644000176200001440000000065013575772017015420 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/loo_subsample.R \name{nobs.psis_loo_ss} \alias{nobs.psis_loo_ss} \title{The number of observations in a \code{psis_loo_ss} object.} \usage{ \method{nobs}{psis_loo_ss}(object, ...) } \arguments{ \item{object}{a \code{psis_loo_ss} object.} \item{...}{Currently unused.} } \description{ The number of observations in a \code{psis_loo_ss} object. } loo/man/pareto-k-diagnostic.Rd0000644000176200001440000001730414407123455015763 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/diagnostics.R \name{pareto-k-diagnostic} \alias{pareto-k-diagnostic} \alias{pareto_k_table} \alias{pareto_k_ids} \alias{pareto_k_values} \alias{pareto_k_influence_values} \alias{psis_n_eff_values} \alias{mcse_loo} \alias{plot.psis_loo} \alias{plot.loo} \alias{plot.psis} \title{Diagnostics for Pareto smoothed importance sampling (PSIS)} \usage{ pareto_k_table(x) pareto_k_ids(x, threshold = 0.5) pareto_k_values(x) pareto_k_influence_values(x) psis_n_eff_values(x) mcse_loo(x, threshold = 0.7) \method{plot}{psis_loo}( x, diagnostic = c("k", "n_eff"), ..., label_points = FALSE, main = "PSIS diagnostic plot" ) \method{plot}{psis}( x, diagnostic = c("k", "n_eff"), ..., label_points = FALSE, main = "PSIS diagnostic plot" ) } \arguments{ \item{x}{An object created by \code{\link[=loo]{loo()}} or \code{\link[=psis]{psis()}}.} \item{threshold}{For \code{pareto_k_ids()}, \code{threshold} is the minimum \eqn{k} value to flag (default is \code{0.5}). For \code{mcse_loo()}, if any \eqn{k} estimates are greater than \code{threshold} the MCSE estimate is returned as \code{NA} (default is \code{0.7}). See \strong{Details} for the motivation behind these defaults.} \item{diagnostic}{For the \code{plot} method, which diagnostic should be plotted? The options are \code{"k"} for Pareto \eqn{k} estimates (the default) or \code{"n_eff"} for PSIS effective sample size estimates.} \item{label_points, ...}{For the \code{plot()} method, if \code{label_points} is \code{TRUE} the observation numbers corresponding to any values of \eqn{k} greater than 0.5 will be displayed in the plot. Any arguments specified in \code{...} will be passed to \code{\link[graphics:text]{graphics::text()}} and can be used to control the appearance of the labels.} \item{main}{For the \code{plot()} method, a title for the plot.} } \value{ \code{pareto_k_table()} returns an object of class \code{"pareto_k_table"}, which is a matrix with columns \code{"Count"}, \code{"Proportion"}, and \code{"Min. n_eff"}, and has its own print method. \code{pareto_k_ids()} returns an integer vector indicating which observations have Pareto \eqn{k} estimates above \code{threshold}. \code{pareto_k_values()} returns a vector of the estimated Pareto \eqn{k} parameters. These represent the reliability of sampling. \code{pareto_k_influence_values()} returns a vector of the estimated Pareto \eqn{k} parameters. These represent influence of the observations on the model posterior distribution. \code{psis_n_eff_values()} returns a vector of the estimated PSIS effective sample sizes. \code{mcse_loo()} returns the Monte Carlo standard error (MCSE) estimate for PSIS-LOO. MCSE will be NA if any Pareto \eqn{k} values are above \code{threshold}. The \code{plot()} method is called for its side effect and does not return anything. If \code{x} is the result of a call to \code{\link[=loo]{loo()}} or \code{\link[=psis]{psis()}} then \code{plot(x, diagnostic)} produces a plot of the estimates of the Pareto shape parameters (\code{diagnostic = "k"}) or estimates of the PSIS effective sample sizes (\code{diagnostic = "n_eff"}). } \description{ Print a diagnostic table summarizing the estimated Pareto shape parameters and PSIS effective sample sizes, find the indexes of observations for which the estimated Pareto shape parameter \eqn{k} is larger than some \code{threshold} value, or plot observation indexes vs. diagnostic estimates. The \strong{Details} section below provides a brief overview of the diagnostics, but we recommend consulting Vehtari, Gelman, and Gabry (2017) and Vehtari, Simpson, Gelman, Yao, and Gabry (2019) for full details. } \details{ The reliability and approximate convergence rate of the PSIS-based estimates can be assessed using the estimates for the shape parameter \eqn{k} of the generalized Pareto distribution: \itemize{ \item If \eqn{k < 0.5} then the distribution of raw importance ratios has finite variance and the central limit theorem holds. However, as \eqn{k} approaches \eqn{0.5} the RMSE of plain importance sampling (IS) increases significantly while PSIS has lower RMSE. \item If \eqn{0.5 \leq k < 1}{0.5 <= k < 1} then the variance of the raw importance ratios is infinite, but the mean exists. TIS and PSIS estimates have finite variance by accepting some bias. The convergence of the estimate is slower with increasing \eqn{k}. If \eqn{k} is between 0.5 and approximately 0.7 then we observe practically useful convergence rates and Monte Carlo error estimates with PSIS (the bias of TIS increases faster than the bias of PSIS). If \eqn{k > 0.7} we observe impractical convergence rates and unreliable Monte Carlo error estimates. \item If \eqn{k \geq 1}{k >= 1} then neither the variance nor the mean of the raw importance ratios exists. The convergence rate is close to zero and bias can be large with practical sample sizes. } \subsection{What if the estimated tail shape parameter \eqn{k} exceeds \eqn{0.5}}{ Importance sampling is likely to work less well if the marginal posterior \eqn{p(\theta^s | y)} and LOO posterior \eqn{p(\theta^s | y_{-i})} are very different, which is more likely to happen with a non-robust model and highly influential observations. If the estimated tail shape parameter \eqn{k} exceeds \eqn{0.5}, the user should be warned. (Note: If \eqn{k} is greater than \eqn{0.5} then WAIC is also likely to fail, but WAIC lacks its own diagnostic.) In practice, we have observed good performance for values of \eqn{k} up to 0.7. When using PSIS in the context of approximate LOO-CV, we recommend one of the following actions when \eqn{k > 0.7}: \itemize{ \item With some additional computations, it is possible to transform the MCMC draws from the posterior distribution to obtain more reliable importance sampling estimates. This results in a smaller shape parameter \eqn{k}. See \code{\link[=loo_moment_match]{loo_moment_match()}} for an example of this. \item Sampling directly from \eqn{p(\theta^s | y_{-i})} for the problematic observations \eqn{i}, or using \eqn{k}-fold cross-validation will generally be more stable. \item Using a model that is more robust to anomalous observations will generally make approximate LOO-CV more stable. } } \subsection{Observation influence statistics}{ The estimated shape parameter \eqn{k} for each observation can be used as a measure of the observation's influence on posterior distribution of the model. These can be obtained with \code{pareto_k_influence_values()}. } \subsection{Effective sample size and error estimates}{ In the case that we obtain the samples from the proposal distribution via MCMC the \strong{loo} package also computes estimates for the Monte Carlo error and the effective sample size for importance sampling, which are more accurate for PSIS than for IS and TIS (see Vehtari et al (2019) for details). However, the PSIS effective sample size estimate will be \strong{over-optimistic when the estimate of \eqn{k} is greater than 0.7}. } } \references{ Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. \emph{Statistics and Computing}. 27(5), 1413--1432. doi:10.1007/s11222-016-9696-4 (\href{https://link.springer.com/article/10.1007/s11222-016-9696-4}{journal version}, \href{https://arxiv.org/abs/1507.04544}{preprint arXiv:1507.04544}). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. \href{https://arxiv.org/abs/1507.02646}{preprint arXiv:1507.02646} } \seealso{ \itemize{ \item \code{\link[=psis]{psis()}} for the implementation of the PSIS algorithm. \item The \href{https://mc-stan.org/loo/articles/online-only/faq.html}{FAQ page} on the \strong{loo} website for answers to frequently asked questions. } } loo/man/loo_subsample.Rd0000644000176200001440000002166614407123455014771 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/loo_subsample.R \name{loo_subsample} \alias{loo_subsample} \alias{loo_subsample.function} \title{Efficient approximate leave-one-out cross-validation (LOO) using subsampling} \usage{ loo_subsample(x, ...) \method{loo_subsample}{`function`}( x, ..., data = NULL, draws = NULL, observations = 400, log_p = NULL, log_g = NULL, r_eff = NULL, save_psis = FALSE, cores = getOption("mc.cores", 1), loo_approximation = "plpd", loo_approximation_draws = NULL, estimator = "diff_srs", llgrad = NULL, llhess = NULL ) } \arguments{ \item{x}{A function. The \strong{Methods (by class)} section, below, has detailed descriptions of how to specify the inputs.} \item{data, draws, ...}{For \code{loo_subsample.function()}, these are the data, posterior draws, and other arguments to pass to the log-likelihood function. Note that for some \code{loo_approximation}s, the draws will be replaced by the posteriors summary statistics to compute loo approximations. See argument \code{loo_approximation} for details.} \item{observations}{The subsample observations to use. The argument can take four (4) types of arguments: \itemize{ \item \code{NULL} to use all observations. The algorithm then just uses standard \code{loo()} or \code{loo_approximate_posterior()}. \item A single integer to specify the number of observations to be subsampled. \item A vector of integers to provide the indices used to subset the data. \emph{These observations need to be subsampled with the same scheme as given by the \code{estimator} argument}. \item A \code{psis_loo_ss} object to use the same observations that were used in a previous call to \code{loo_subsample()}. }} \item{log_p, log_g}{Should be supplied only if approximate posterior draws are used. The default (\code{NULL}) indicates draws are from "true" posterior (i.e. using MCMC). If not \code{NULL} then they should be specified as described in \code{\link[=loo_approximate_posterior]{loo_approximate_posterior()}}.} \item{r_eff}{Vector of relative effective sample size estimates for the likelihood (\code{exp(log_lik)}) of each observation. This is related to the relative efficiency of estimating the normalizing term in self-normalizing importance sampling when using posterior draws obtained with MCMC. If MCMC draws are used and \code{r_eff} is not provided then the reported PSIS effective sample sizes and Monte Carlo error estimates will be over-optimistic. If the posterior draws are independent then \code{r_eff=1} and can be omitted. The warning message thrown when \code{r_eff} is not specified can be disabled by setting \code{r_eff} to \code{NA}. See the \code{\link[=relative_eff]{relative_eff()}} helper functions for computing \code{r_eff}.} \item{save_psis}{Should the \code{"psis"} object created internally by \code{loo_subsample()} be saved in the returned object? See \code{\link[=loo]{loo()}} for details.} \item{cores}{The number of cores to use for parallelization. This defaults to the option \code{mc.cores} which can be set for an entire R session by \code{options(mc.cores = NUMBER)}. The old option \code{loo.cores} is now deprecated but will be given precedence over \code{mc.cores} until \code{loo.cores} is removed in a future release. \strong{As of version 2.0.0 the default is now 1 core if \code{mc.cores} is not set}, but we recommend using as many (or close to as many) cores as possible. \itemize{ \item Note for Windows 10 users: it is \strong{strongly} \href{https://github.com/stan-dev/loo/issues/94}{recommended} to avoid using the \code{.Rprofile} file to set \code{mc.cores} (using the \code{cores} argument or setting \code{mc.cores} interactively or in a script is fine). }} \item{loo_approximation}{What type of approximation of the loo_i's should be used? The default is \code{"plpd"} (the log predictive density using the posterior expectation). There are six different methods implemented to approximate loo_i's (see the references for more details): \itemize{ \item \code{"plpd"}: uses the lpd based on point estimates (i.e., \eqn{p(y_i|\hat{\theta})}). \item \code{"lpd"}: uses the lpds (i,e., \eqn{p(y_i|y)}). \item \code{"tis"}: uses truncated importance sampling to approximate PSIS-LOO. \item \code{"waic"}: uses waic (i.e., \eqn{p(y_i|y) - p_{waic}}). \item \code{"waic_grad_marginal"}: uses waic approximation using first order delta method and posterior marginal variances to approximate \eqn{p_{waic}} (ie. \eqn{p(y_i|\hat{\theta})}-p_waic_grad_marginal). Requires gradient of likelihood function. \item \code{"waic_grad"}: uses waic approximation using first order delta method and posterior covariance to approximate \eqn{p_{waic}} (ie. \eqn{p(y_i|\hat{\theta})}-p_waic_grad). Requires gradient of likelihood function. \item \code{"waic_hess"}: uses waic approximation using second order delta method and posterior covariance to approximate \eqn{p_{waic}} (ie. \eqn{p(y_i|\hat{\theta})}-p_waic_grad). Requires gradient and Hessian of likelihood function. } As point estimates of \eqn{\hat{\theta}}, the posterior expectations of the parameters are used.} \item{loo_approximation_draws}{The number of posterior draws used when integrating over the posterior. This is used if \code{loo_approximation} is set to \code{"lpd"}, \code{"waic"}, or \code{"tis"}.} \item{estimator}{How should \code{elpd_loo}, \code{p_loo} and \code{looic} be estimated? The default is \code{"diff_srs"}. \itemize{ \item \code{"diff_srs"}: uses the difference estimator with simple random sampling (srs). \code{p_loo} is estimated using standard srs. \item \code{"hh"}: uses the Hansen-Hurwitz estimator with sampling proportional to size, where \code{abs} of loo_approximation is used as size. \item \code{"srs"}: uses simple random sampling and ordinary estimation. }} \item{llgrad}{The gradient of the log-likelihood. This is only used when \code{loo_approximation} is \code{"waic_grad"}, \code{"waic_grad_marginal"}, or \code{"waic_hess"}. The default is \code{NULL}.} \item{llhess}{The hessian of the log-likelihood. This is only used with \code{loo_approximation = "waic_hess"}. The default is \code{NULL}.} } \value{ \code{loo_subsample()} returns a named list with class \code{c("psis_loo_ss", "psis_loo", "loo")}. This has the same structure as objects returned by \code{\link[=loo]{loo()}} but with the additional slot: \itemize{ \item \code{loo_subsampling}: A list with two vectors, \code{log_p} and \code{log_g}, of the same length containing the posterior density and the approximation density for the individual draws. } } \description{ Efficient approximate leave-one-out cross-validation (LOO) using subsampling } \details{ The \code{loo_subsample()} function is an S3 generic and a methods is currently provided for log-likelihood functions. The implementation works for both MCMC and for posterior approximations where it is possible to compute the log density for the approximation. } \section{Methods (by class)}{ \itemize{ \item \code{loo_subsample(`function`)}: A function \code{f()} that takes arguments \code{data_i} and \code{draws} and returns a vector containing the log-likelihood for a single observation \code{i} evaluated at each posterior draw. The function should be written such that, for each observation \code{i} in \code{1:N}, evaluating \if{html}{\out{

}}\preformatted{f(data_i = data[i,, drop=FALSE], draws = draws) }\if{html}{\out{
}} results in a vector of length \code{S} (size of posterior sample). The log-likelihood function can also have additional arguments but \code{data_i} and \code{draws} are required. If using the function method then the arguments \code{data} and \code{draws} must also be specified in the call to \code{loo()}: \itemize{ \item \code{data}: A data frame or matrix containing the data (e.g. observed outcome and predictors) needed to compute the pointwise log-likelihood. For each observation \code{i}, the \code{i}th row of \code{data} will be passed to the \code{data_i} argument of the log-likelihood function. \item \code{draws}: An object containing the posterior draws for any parameters needed to compute the pointwise log-likelihood. Unlike \code{data}, which is indexed by observation, for each observation the entire object \code{draws} will be passed to the \code{draws} argument of the log-likelihood function. \item The \code{...} can be used if your log-likelihood function takes additional arguments. These arguments are used like the \code{draws} argument in that they are recycled for each observation. } }} \references{ Magnusson, M., Riis Andersen, M., Jonasson, J. and Vehtari, A. (2019). Leave-One-Out Cross-Validation for Large Data. In \emph{International Conference on Machine Learning} Magnusson, M., Riis Andersen, M., Jonasson, J. and Vehtari, A. (2020). Leave-One-Out Cross-Validation for Model Comparison in Large Data. In \emph{International Conference on Artificial Intelligence and Statistics (AISTATS)} } \seealso{ \code{\link[=loo]{loo()}}, \code{\link[=psis]{psis()}}, \code{\link[=loo_compare]{loo_compare()}} } loo/man/print_dims.Rd0000644000176200001440000000162013575772017014272 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/print.R \name{print_dims} \alias{print_dims} \alias{print_dims.importance_sampling} \alias{print_dims.psis_loo} \alias{print_dims.importance_sampling_loo} \alias{print_dims.waic} \alias{print_dims.kfold} \alias{print_dims.psis_loo_ss} \title{Print dimensions of log-likelihood or log-weights matrix} \usage{ print_dims(x, ...) \method{print_dims}{importance_sampling}(x, ...) \method{print_dims}{psis_loo}(x, ...) \method{print_dims}{importance_sampling_loo}(x, ...) \method{print_dims}{waic}(x, ...) \method{print_dims}{kfold}(x, ...) \method{print_dims}{psis_loo_ss}(x, ...) } \arguments{ \item{x}{The object returned by \code{\link[=psis]{psis()}}, \code{\link[=loo]{loo()}}, or \code{\link[=waic]{waic()}}.} \item{...}{Ignored.} } \description{ Print dimensions of log-likelihood or log-weights matrix } \keyword{internal} loo/man/E_loo.Rd0000644000176200001440000000763714407123455013164 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/E_loo.R \name{E_loo} \alias{E_loo} \alias{E_loo.default} \alias{E_loo.matrix} \title{Compute weighted expectations} \usage{ E_loo(x, psis_object, ...) \method{E_loo}{default}( x, psis_object, ..., type = c("mean", "variance", "quantile"), probs = NULL, log_ratios = NULL ) \method{E_loo}{matrix}( x, psis_object, ..., type = c("mean", "variance", "quantile"), probs = NULL, log_ratios = NULL ) } \arguments{ \item{x}{A numeric vector or matrix.} \item{psis_object}{An object returned by \code{\link[=psis]{psis()}}.} \item{...}{Arguments passed to individual methods.} \item{type}{The type of expectation to compute. The options are \code{"mean"}, \code{"variance"}, and \code{"quantile"}.} \item{probs}{For computing quantiles, a vector of probabilities.} \item{log_ratios}{Optionally, a vector or matrix (the same dimensions as \code{x}) of raw (not smoothed) log ratios. If working with log-likelihood values, the log ratios are the \strong{negative} of those values. If \code{log_ratios} is specified we are able to compute \link[=pareto-k-diagnostic]{Pareto k} diagnostics specific to \code{E_loo()}.} } \value{ A named list with the following components: \describe{ \item{\code{value}}{ The result of the computation. For the matrix method, \code{value} is a vector with \code{ncol(x)} elements, with one exception: when \code{type="quantile"} and multiple values are specified in \code{probs} the \code{value} component of the returned object is a \code{length(probs)} by \code{ncol(x)} matrix. For the default/vector method the \code{value} component is scalar, with one exception: when \code{type} is \code{"quantile"} and multiple values are specified in \code{probs} the \code{value} component is a vector with \code{length(probs)} elements. } \item{\code{pareto_k}}{ Function-specific diagnostic. If \code{log_ratios} is not specified when calling \code{E_loo()}, \code{pareto_k} will be \code{NULL}. Otherwise, for the matrix method it will be a vector of length \code{ncol(x)} containing estimates of the shape parameter \eqn{k} of the generalized Pareto distribution. For the default/vector method, the estimate is a scalar. } } } \description{ The \code{E_loo()} function computes weighted expectations (means, variances, quantiles) using the importance weights obtained from the \link[=psis]{PSIS} smoothing procedure. The expectations estimated by the \code{E_loo()} function assume that the PSIS approximation is working well. \strong{A small \link[=pareto-k-diagnostic]{Pareto k} estimate is necessary, but not sufficient, for \code{E_loo()} to give reliable estimates.} Additional diagnostic checks for gauging the reliability of the estimates are in development and will be added in a future release. } \examples{ \donttest{ if (requireNamespace("rstanarm", quietly = TRUE)) { # Use rstanarm package to quickly fit a model and get both a log-likelihood # matrix and draws from the posterior predictive distribution library("rstanarm") # data from help("lm") ctl <- c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14) trt <- c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69) d <- data.frame( weight = c(ctl, trt), group = gl(2, 10, 20, labels = c("Ctl","Trt")) ) fit <- stan_glm(weight ~ group, data = d, refresh = 0) yrep <- posterior_predict(fit) dim(yrep) log_ratios <- -1 * log_lik(fit) dim(log_ratios) r_eff <- relative_eff(exp(-log_ratios), chain_id = rep(1:4, each = 1000)) psis_object <- psis(log_ratios, r_eff = r_eff, cores = 2) E_loo(yrep, psis_object, type = "mean") E_loo(yrep, psis_object, type = "var") E_loo(yrep, psis_object, type = "quantile", probs = 0.5) # median E_loo(yrep, psis_object, type = "quantile", probs = c(0.1, 0.9)) # To get Pareto k diagnostic with E_loo we also need to provide the negative # log-likelihood values using the log_ratios argument. E_loo(yrep, psis_object, type = "mean", log_ratios = log_ratios) } } } loo/man/example_loglik_array.Rd0000644000176200001440000000203013575772017016310 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/example_log_lik_array.R \name{example_loglik_array} \alias{example_loglik_array} \alias{example_loglik_matrix} \title{Objects to use in examples and tests} \usage{ example_loglik_array() example_loglik_matrix() } \value{ \code{example_loglik_array()} returns a 500 (draws) x 2 (chains) x 32 (observations) pointwise log-likelihood array. \code{example_loglik_matrix()} returns the same pointwise log-likelihood values as \code{example_loglik_array()} but reshaped into a 1000 (draws*chains) x 32 (observations) matrix. } \description{ Example pointwise log-likelihood objects to use in demonstrations and tests. See the \strong{Value} and \strong{Examples} sections below. } \examples{ LLarr <- example_loglik_array() (dim_arr <- dim(LLarr)) LLmat <- example_loglik_matrix() (dim_mat <- dim(LLmat)) all.equal(dim_mat[1], dim_arr[1] * dim_arr[2]) all.equal(dim_mat[2], dim_arr[3]) all.equal(LLarr[, 1, ], LLmat[1:500, ]) all.equal(LLarr[, 2, ], LLmat[501:1000, ]) } loo/man/loo-package.Rd0000644000176200001440000001217714407123455014304 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/loo-package.R \docType{package} \name{loo-package} \alias{loo-package} \title{Efficient LOO-CV and WAIC for Bayesian models} \description{ \if{html}{ \figure{stanlogo.png}{options: width="50" alt="mc-stan.org"} } \emph{Stan Development Team} This package implements the methods described in Vehtari, Gelman, and Gabry (2017), Vehtari, Simpson, Gelman, Yao, and Gabry (2019), and Yao et al. (2018). To get started see the \strong{loo} package \href{https://mc-stan.org/loo/articles/index.html}{vignettes}, the \code{\link[=loo]{loo()}} function for efficient approximate leave-one-out cross-validation (LOO-CV), the \code{\link[=psis]{psis()}} function for the Pareto smoothed importance sampling (PSIS) algorithm, or \code{\link[=loo_model_weights]{loo_model_weights()}} for an implementation of Bayesian stacking of predictive distributions from multiple models. } \details{ Leave-one-out cross-validation (LOO-CV) and the widely applicable information criterion (WAIC) are methods for estimating pointwise out-of-sample prediction accuracy from a fitted Bayesian model using the log-likelihood evaluated at the posterior simulations of the parameter values. LOO-CV and WAIC have various advantages over simpler estimates of predictive error such as AIC and DIC but are less used in practice because they involve additional computational steps. This package implements the fast and stable computations for approximate LOO-CV laid out in Vehtari, Gelman, and Gabry (2017). From existing posterior simulation draws, we compute LOO-CV using Pareto smoothed importance sampling (PSIS; Vehtari, Simpson, Gelman, Yao, and Gabry, 2019), a new procedure for stabilizing and diagnosing importance weights. As a byproduct of our calculations, we also obtain approximate standard errors for estimated predictive errors and for comparing of predictive errors between two models. We recommend PSIS-LOO-CV instead of WAIC, because PSIS provides useful diagnostics and effective sample size and Monte Carlo standard error estimates. } \references{ Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. \emph{Statistics and Computing}. 27(5), 1413--1432. doi:10.1007/s11222-016-9696-4 (\href{https://link.springer.com/article/10.1007/s11222-016-9696-4}{journal version}, \href{https://arxiv.org/abs/1507.04544}{preprint arXiv:1507.04544}). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. \href{https://arxiv.org/abs/1507.02646}{preprint arXiv:1507.02646} Yao, Y., Vehtari, A., Simpson, D., and Gelman, A. (2018) Using stacking to average Bayesian predictive distributions. \emph{Bayesian Analysis}, advance publication, doi:10.1214/17-BA1091. (\href{https://projecteuclid.org/euclid.ba/1516093227}{online}). Magnusson, M., Riis Andersen, M., Jonasson, J. and Vehtari, A. (2019). Leave-One-Out Cross-Validation for Large Data. In \emph{International Conference on Machine Learning} Magnusson, M., Riis Andersen, M., Jonasson, J. and Vehtari, A. (2020). Leave-One-Out Cross-Validation for Model Comparison in Large Data. In \emph{International Conference on Artificial Intelligence and Statistics (AISTATS)} Epifani, I., MacEachern, S. N., and Peruggia, M. (2008). Case-deletion importance sampling estimators: Central limit theorems and related results. \emph{Electronic Journal of Statistics} \strong{2}, 774-806. Gelfand, A. E. (1996). Model determination using sampling-based methods. In \emph{Markov Chain Monte Carlo in Practice}, ed. W. R. Gilks, S. Richardson, D. J. Spiegelhalter, 145-162. London: Chapman and Hall. Gelfand, A. E., Dey, D. K., and Chang, H. (1992). Model determination using predictive distributions with implementation via sampling-based methods. In \emph{Bayesian Statistics 4}, ed. J. M. Bernardo, J. O. Berger, A. P. Dawid, and A. F. M. Smith, 147-167. Oxford University Press. Gelman, A., Hwang, J., and Vehtari, A. (2014). Understanding predictive information criteria for Bayesian models. \emph{Statistics and Computing} \strong{24}, 997-1016. Ionides, E. L. (2008). Truncated importance sampling. \emph{Journal of Computational and Graphical Statistics} \strong{17}, 295-311. Koopman, S. J., Shephard, N., and Creal, D. (2009). Testing the assumptions behind importance sampling. \emph{Journal of Econometrics} \strong{149}, 2-11. Peruggia, M. (1997). On the variability of case-deletion importance sampling weights in the Bayesian linear model. \emph{Journal of the American Statistical Association} \strong{92}, 199-207. Stan Development Team (2017). The Stan C++ Library, Version 2.17.0. \url{https://mc-stan.org}. Stan Development Team (2018). RStan: the R interface to Stan, Version 2.17.3. \url{https://mc-stan.org}. Watanabe, S. (2010). Asymptotic equivalence of Bayes cross validation and widely application information criterion in singular learning theory. \emph{Journal of Machine Learning Research} \strong{11}, 3571-3594. Zhang, J., and Stephens, M. A. (2009). A new and efficient estimation method for the generalized Pareto distribution. \emph{Technometrics} \strong{51}, 316-325. } loo/man/weights.importance_sampling.Rd0000644000176200001440000000177013701164066017622 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/importance_sampling.R \name{weights.importance_sampling} \alias{weights.importance_sampling} \title{Extract importance sampling weights} \usage{ \method{weights}{importance_sampling}(object, ..., log = TRUE, normalize = TRUE) } \arguments{ \item{object}{An object returned by \code{\link[=psis]{psis()}}, \code{\link[=tis]{tis()}}, or \code{\link[=sis]{sis()}}.} \item{...}{Ignored.} \item{log}{Should the weights be returned on the log scale? Defaults to \code{TRUE}.} \item{normalize}{Should the weights be normalized? Defaults to \code{TRUE}.} } \value{ The \code{weights()} method returns an object with the same dimensions as the \code{log_weights} component of \code{object}. The \code{normalize} and \code{log} arguments control whether the returned weights are normalized and whether or not to return them on the log scale. } \description{ Extract importance sampling weights } \examples{ # See the examples at help("psis") } loo/man/waic.Rd0000644000176200001440000001227014407123455013037 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/waic.R \name{waic} \alias{waic} \alias{waic.array} \alias{waic.matrix} \alias{waic.function} \alias{is.waic} \title{Widely applicable information criterion (WAIC)} \usage{ waic(x, ...) \method{waic}{array}(x, ...) \method{waic}{matrix}(x, ...) \method{waic}{`function`}(x, ..., data = NULL, draws = NULL) is.waic(x) } \arguments{ \item{x}{A log-likelihood array, matrix, or function. The \strong{Methods (by class)} section, below, has detailed descriptions of how to specify the inputs for each method.} \item{draws, data, ...}{For the function method only. See the \strong{Methods (by class)} section below for details on these arguments.} } \value{ A named list (of class \code{c("waic", "loo")}) with components: \describe{ \item{\code{estimates}}{ A matrix with two columns (\code{"Estimate"}, \code{"SE"}) and three rows (\code{"elpd_waic"}, \code{"p_waic"}, \code{"waic"}). This contains point estimates and standard errors of the expected log pointwise predictive density (\code{elpd_waic}), the effective number of parameters (\code{p_waic}) and the information criterion \code{waic} (which is just \code{-2 * elpd_waic}, i.e., converted to deviance scale). } \item{\code{pointwise}}{ A matrix with three columns (and number of rows equal to the number of observations) containing the pointwise contributions of each of the above measures (\code{elpd_waic}, \code{p_waic}, \code{waic}). } } } \description{ The \code{waic()} methods can be used to compute WAIC from the pointwise log-likelihood. However, we recommend LOO-CV using PSIS (as implemented by the \code{\link[=loo]{loo()}} function) because PSIS provides useful diagnostics as well as effective sample size and Monte Carlo estimates. } \section{Methods (by class)}{ \itemize{ \item \code{waic(array)}: An \eqn{I} by \eqn{C} by \eqn{N} array, where \eqn{I} is the number of MCMC iterations per chain, \eqn{C} is the number of chains, and \eqn{N} is the number of data points. \item \code{waic(matrix)}: An \eqn{S} by \eqn{N} matrix, where \eqn{S} is the size of the posterior sample (with all chains merged) and \eqn{N} is the number of data points. \item \code{waic(`function`)}: A function \code{f()} that takes arguments \code{data_i} and \code{draws} and returns a vector containing the log-likelihood for a single observation \code{i} evaluated at each posterior draw. The function should be written such that, for each observation \code{i} in \code{1:N}, evaluating \if{html}{\out{
}}\preformatted{f(data_i = data[i,, drop=FALSE], draws = draws) }\if{html}{\out{
}} results in a vector of length \code{S} (size of posterior sample). The log-likelihood function can also have additional arguments but \code{data_i} and \code{draws} are required. If using the function method then the arguments \code{data} and \code{draws} must also be specified in the call to \code{loo()}: \itemize{ \item \code{data}: A data frame or matrix containing the data (e.g. observed outcome and predictors) needed to compute the pointwise log-likelihood. For each observation \code{i}, the \code{i}th row of \code{data} will be passed to the \code{data_i} argument of the log-likelihood function. \item \code{draws}: An object containing the posterior draws for any parameters needed to compute the pointwise log-likelihood. Unlike \code{data}, which is indexed by observation, for each observation the entire object \code{draws} will be passed to the \code{draws} argument of the log-likelihood function. \item The \code{...} can be used if your log-likelihood function takes additional arguments. These arguments are used like the \code{draws} argument in that they are recycled for each observation. } }} \examples{ ### Array and matrix methods LLarr <- example_loglik_array() dim(LLarr) LLmat <- example_loglik_matrix() dim(LLmat) waic_arr <- waic(LLarr) waic_mat <- waic(LLmat) identical(waic_arr, waic_mat) \dontrun{ log_lik1 <- extract_log_lik(stanfit1) log_lik2 <- extract_log_lik(stanfit2) (waic1 <- waic(log_lik1)) (waic2 <- waic(log_lik2)) print(compare(waic1, waic2), digits = 2) } } \references{ Watanabe, S. (2010). Asymptotic equivalence of Bayes cross validation and widely application information criterion in singular learning theory. \emph{Journal of Machine Learning Research} \strong{11}, 3571-3594. Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. \emph{Statistics and Computing}. 27(5), 1413--1432. doi:10.1007/s11222-016-9696-4 (\href{https://link.springer.com/article/10.1007/s11222-016-9696-4}{journal version}, \href{https://arxiv.org/abs/1507.04544}{preprint arXiv:1507.04544}). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. \href{https://arxiv.org/abs/1507.02646}{preprint arXiv:1507.02646} } \seealso{ \itemize{ \item The \strong{loo} package \href{https://mc-stan.org/loo/articles/}{vignettes} and Vehtari, Gelman, and Gabry (2017) and Vehtari, Simpson, Gelman, Yao, and Gabry (2019) for more details on why we prefer \code{loo()} to \code{waic()}. \item \code{\link[=loo_compare]{loo_compare()}} for comparing models on approximate LOO-CV or WAIC. } } loo/man/tis.Rd0000644000176200001440000001151614407123455012715 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/tis.R \name{tis} \alias{tis} \alias{tis.array} \alias{tis.matrix} \alias{tis.default} \title{Truncated importance sampling (TIS)} \usage{ tis(log_ratios, ...) \method{tis}{array}(log_ratios, ..., r_eff = NULL, cores = getOption("mc.cores", 1)) \method{tis}{matrix}(log_ratios, ..., r_eff = NULL, cores = getOption("mc.cores", 1)) \method{tis}{default}(log_ratios, ..., r_eff = NULL) } \arguments{ \item{log_ratios}{An array, matrix, or vector of importance ratios on the log scale (for Importance sampling LOO, these are \emph{negative} log-likelihood values). See the \strong{Methods (by class)} section below for a detailed description of how to specify the inputs for each method.} \item{...}{Arguments passed on to the various methods.} \item{r_eff}{Vector of relative effective sample size estimates containing one element per observation. The values provided should be the relative effective sample sizes of \code{1/exp(log_ratios)} (i.e., \code{1/ratios}). This is related to the relative efficiency of estimating the normalizing term in self-normalizing importance sampling. See the \code{\link[=relative_eff]{relative_eff()}} helper function for computing \code{r_eff}. If using \code{psis} with draws of the \code{log_ratios} not obtained from MCMC then the warning message thrown when not specifying \code{r_eff} can be disabled by setting \code{r_eff} to \code{NA}.} \item{cores}{The number of cores to use for parallelization. This defaults to the option \code{mc.cores} which can be set for an entire R session by \code{options(mc.cores = NUMBER)}. The old option \code{loo.cores} is now deprecated but will be given precedence over \code{mc.cores} until \code{loo.cores} is removed in a future release. \strong{As of version 2.0.0 the default is now 1 core if \code{mc.cores} is not set}, but we recommend using as many (or close to as many) cores as possible. \itemize{ \item Note for Windows 10 users: it is \strong{strongly} \href{https://github.com/stan-dev/loo/issues/94}{recommended} to avoid using the \code{.Rprofile} file to set \code{mc.cores} (using the \code{cores} argument or setting \code{mc.cores} interactively or in a script is fine). }} } \value{ The \code{tis()} methods return an object of class \code{"tis"}, which is a named list with the following components: \describe{ \item{\code{log_weights}}{ Vector or matrix of smoothed (and truncated) but \emph{unnormalized} log weights. To get normalized weights use the \code{\link[=weights.importance_sampling]{weights()}} method provided for objects of class \code{tis}. } \item{\code{diagnostics}}{ A named list containing one vector: \itemize{ \item \code{pareto_k}: Not used in \code{tis}, all set to 0. \item \code{n_eff}: Effective sample size estimates. } } } Objects of class \code{"tis"} also have the following \link[=attributes]{attributes}: \describe{ \item{\code{norm_const_log}}{ Vector of precomputed values of \code{colLogSumExps(log_weights)} that are used internally by the \code{\link[=weights]{weights()}}method to normalize the log weights. } \item{\code{r_eff}}{ If specified, the user's \code{r_eff} argument. } \item{\code{tail_len}}{ Not used for \code{tis}. } \item{\code{dims}}{ Integer vector of length 2 containing \code{S} (posterior sample size) and \code{N} (number of observations). } \item{\code{method}}{ Method used for importance sampling, here \code{tis}. } } } \description{ Implementation of truncated (self-normalized) importance sampling (TIS), truncated at S^(1/2) as recommended by Ionides (2008). } \section{Methods (by class)}{ \itemize{ \item \code{tis(array)}: An \eqn{I} by \eqn{C} by \eqn{N} array, where \eqn{I} is the number of MCMC iterations per chain, \eqn{C} is the number of chains, and \eqn{N} is the number of data points. \item \code{tis(matrix)}: An \eqn{S} by \eqn{N} matrix, where \eqn{S} is the size of the posterior sample (with all chains merged) and \eqn{N} is the number of data points. \item \code{tis(default)}: A vector of length \eqn{S} (posterior sample size). }} \examples{ log_ratios <- -1 * example_loglik_array() r_eff <- relative_eff(exp(-log_ratios)) tis_result <- tis(log_ratios, r_eff = r_eff) str(tis_result) # extract smoothed weights lw <- weights(tis_result) # default args are log=TRUE, normalize=TRUE ulw <- weights(tis_result, normalize=FALSE) # unnormalized log-weights w <- weights(tis_result, log=FALSE) # normalized weights (not log-weights) uw <- weights(tis_result, log=FALSE, normalize = FALSE) # unnormalized weights } \references{ Ionides, Edward L. (2008). Truncated importance sampling. \emph{Journal of Computational and Graphical Statistics} 17(2): 295--311. } \seealso{ \itemize{ \item \code{\link[=psis]{psis()}} for approximate LOO-CV using PSIS. \item \code{\link[=loo]{loo()}} for approximate LOO-CV. \item \link{pareto-k-diagnostic} for PSIS diagnostics. } } loo/man/obs_idx.Rd0000644000176200001440000000123013575772017013546 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/loo_subsample.R \name{obs_idx} \alias{obs_idx} \title{Get observation indices used in subsampling} \usage{ obs_idx(x, rep = TRUE) } \arguments{ \item{x}{A \code{psis_loo_ss} object.} \item{rep}{If sampling with replacement is used, an observation can have multiple samples and these are then repeated in the returned object if \code{rep=TRUE} (e.g., a vector \code{c(1,1,2)} indicates that observation 1 has been subampled two times). If \code{rep=FALSE} only the unique indices are returned.} } \value{ An integer vector. } \description{ Get observation indices used in subsampling } loo/man/dot-compute_point_estimate.Rd0000644000176200001440000000130013575772017017461 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/loo_subsample.R \name{.compute_point_estimate} \alias{.compute_point_estimate} \title{Compute a point estimate from a draws object} \usage{ .compute_point_estimate(draws) } \arguments{ \item{draws}{A draws object with draws from the posterior.} } \value{ A 1 by P matrix with point estimates from a draws object. } \description{ Compute a point estimate from a draws object } \details{ This is a generic function to thin draws from arbitrary draws objects. The function is internal and should only be used by developers to enable \code{\link[=loo_subsample]{loo_subsample()}} for arbitrary draws objects. } \keyword{internal} loo/man/importance_sampling.matrix.Rd0000644000176200001440000000527013575772017017465 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/importance_sampling.R \name{importance_sampling.matrix} \alias{importance_sampling.matrix} \title{Importance sampling of matrices} \usage{ \method{importance_sampling}{matrix}( log_ratios, method, ..., r_eff = NULL, cores = getOption("mc.cores", 1) ) } \arguments{ \item{log_ratios}{An array, matrix, or vector of importance ratios on the log scale (for PSIS-LOO these are \emph{negative} log-likelihood values). See the \strong{Methods (by class)} section below for a detailed description of how to specify the inputs for each method.} \item{...}{Arguments passed on to the various methods.} \item{r_eff}{Vector of relative effective sample size estimates containing one element per observation. The values provided should be the relative effective sample sizes of \code{1/exp(log_ratios)} (i.e., \code{1/ratios}). This is related to the relative efficiency of estimating the normalizing term in self-normalizing importance sampling. If \code{r_eff} is not provided then the reported PSIS effective sample sizes and Monte Carlo error estimates will be over-optimistic. See the \code{\link[=relative_eff]{relative_eff()}} helper function for computing \code{r_eff}. If using \code{psis} with draws of the \code{log_ratios} not obtained from MCMC then the warning message thrown when not specifying \code{r_eff} can be disabled by setting \code{r_eff} to \code{NA}.} \item{cores}{The number of cores to use for parallelization. This defaults to the option \code{mc.cores} which can be set for an entire R session by \code{options(mc.cores = NUMBER)}. The old option \code{loo.cores} is now deprecated but will be given precedence over \code{mc.cores} until \code{loo.cores} is removed in a future release. \strong{As of version 2.0.0 the default is now 1 core if \code{mc.cores} is not set}, but we recommend using as many (or close to as many) cores as possible. \itemize{ \item Note for Windows 10 users: it is \strong{strongly} \href{https://github.com/stan-dev/loo/issues/94}{recommended} to avoid using the \code{.Rprofile} file to set \code{mc.cores} (using the \code{cores} argument or setting \code{mc.cores} interactively or in a script is fine). }} \item{is_method}{The importance sampling method to use. The following methods are implemented: \itemize{ \item \code{\link[=psis]{"psis"}}: Pareto-Smoothed Importance Sampling (PSIS). Default method. \item \code{\link[=tis]{"tis"}}: Truncated Importance Sampling (TIS) with truncation at \code{sqrt(S)}, where \code{S} is the number of posterior draws. \item \code{\link[=sis]{"sis"}}: Standard Importance Sampling (SIS). }} } \description{ Importance sampling of matrices } \keyword{internal} loo/man/loo_compare.Rd0000644000176200001440000001072314407123455014414 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/loo_compare.R, R/loo_compare.psis_loo_ss_list.R \name{loo_compare} \alias{loo_compare} \alias{loo_compare.default} \alias{print.compare.loo} \alias{print.compare.loo_ss} \title{Model comparison} \usage{ loo_compare(x, ...) \method{loo_compare}{default}(x, ...) \method{print}{compare.loo}(x, ..., digits = 1, simplify = TRUE) \method{print}{compare.loo_ss}(x, ..., digits = 1, simplify = TRUE) } \arguments{ \item{x}{An object of class \code{"loo"} or a list of such objects. If a list is used then the list names will be used as the model names in the output. See \strong{Examples}.} \item{...}{Additional objects of class \code{"loo"}, if not passed in as a single list.} \item{digits}{For the print method only, the number of digits to use when printing.} \item{simplify}{For the print method only, should only the essential columns of the summary matrix be printed? The entire matrix is always returned, but by default only the most important columns are printed.} } \value{ A matrix with class \code{"compare.loo"} that has its own print method. See the \strong{Details} section. } \description{ Compare fitted models based on \link[=loo-glossary]{ELPD}. By default the print method shows only the most important information. Use \code{print(..., simplify=FALSE)} to print a more detailed summary. } \details{ When comparing two fitted models, we can estimate the difference in their expected predictive accuracy by the difference in \code{\link[=loo-glossary]{elpd_loo}} or \code{elpd_waic} (or multiplied by \eqn{-2}, if desired, to be on the deviance scale). When using \code{loo_compare()}, the returned matrix will have one row per model and several columns of estimates. The values in the \code{\link[=loo-glossary]{elpd_diff}} and \code{\link[=loo-glossary]{se_diff}} columns of the returned matrix are computed by making pairwise comparisons between each model and the model with the largest ELPD (the model in the first row). For this reason the \code{elpd_diff} column will always have the value \code{0} in the first row (i.e., the difference between the preferred model and itself) and negative values in subsequent rows for the remaining models. To compute the standard error of the difference in \link[=loo-glossary]{ELPD} --- which should not be expected to equal the difference of the standard errors --- we use a paired estimate to take advantage of the fact that the same set of \eqn{N} data points was used to fit both models. These calculations should be most useful when \eqn{N} is large, because then non-normality of the distribution is not such an issue when estimating the uncertainty in these sums. These standard errors, for all their flaws, should give a better sense of uncertainty than what is obtained using the current standard approach of comparing differences of deviances to a Chi-squared distribution, a practice derived for Gaussian linear models or asymptotically, and which only applies to nested models in any case. } \examples{ # very artificial example, just for demonstration! LL <- example_loglik_array() loo1 <- loo(LL, r_eff = NA) # should be worst model when compared loo2 <- loo(LL + 1, r_eff = NA) # should be second best model when compared loo3 <- loo(LL + 2, r_eff = NA) # should be best model when compared comp <- loo_compare(loo1, loo2, loo3) print(comp, digits = 2) # show more details with simplify=FALSE # (will be the same for all models in this artificial example) print(comp, simplify = FALSE, digits = 3) # can use a list of objects with custom names # will use apple, banana, and cherry, as the names in the output loo_compare(list("apple" = loo1, "banana" = loo2, "cherry" = loo3)) \dontrun{ # works for waic (and kfold) too loo_compare(waic(LL), waic(LL - 10)) } } \references{ Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. \emph{Statistics and Computing}. 27(5), 1413--1432. doi:10.1007/s11222-016-9696-4 (\href{https://link.springer.com/article/10.1007/s11222-016-9696-4}{journal version}, \href{https://arxiv.org/abs/1507.04544}{preprint arXiv:1507.04544}). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. \href{https://arxiv.org/abs/1507.02646}{preprint arXiv:1507.02646} } \seealso{ \itemize{ \item The \href{https://mc-stan.org/loo/articles/online-only/faq.html}{FAQ page} on the \strong{loo} website for answers to frequently asked questions. } } loo/man/print.loo.Rd0000644000176200001440000000263013701164066014036 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/print.R \name{print.loo} \alias{print.loo} \alias{print.waic} \alias{print.psis_loo} \alias{print.importance_sampling_loo} \alias{print.psis_loo_ap} \alias{print.psis} \alias{print.importance_sampling} \title{Print methods} \usage{ \method{print}{loo}(x, digits = 1, ...) \method{print}{waic}(x, digits = 1, ...) \method{print}{psis_loo}(x, digits = 1, plot_k = FALSE, ...) \method{print}{importance_sampling_loo}(x, digits = 1, plot_k = FALSE, ...) \method{print}{psis_loo_ap}(x, digits = 1, plot_k = FALSE, ...) \method{print}{psis}(x, digits = 1, plot_k = FALSE, ...) \method{print}{importance_sampling}(x, digits = 1, plot_k = FALSE, ...) } \arguments{ \item{x}{An object returned by \code{\link[=loo]{loo()}}, \code{\link[=psis]{psis()}}, or \code{\link[=waic]{waic()}}.} \item{digits}{An integer passed to \code{\link[base:Round]{base::round()}}.} \item{...}{Arguments passed to \code{\link[=plot.psis_loo]{plot.psis_loo()}} if \code{plot_k} is \code{TRUE}.} \item{plot_k}{Logical. If \code{TRUE} the estimates of the Pareto shape parameter \eqn{k} are plotted. Ignored if \code{x} was generated by \code{\link[=waic]{waic()}}. To just plot \eqn{k} without printing use the \link[=pareto-k-diagnostic]{plot()} method for 'loo' objects.} } \value{ \code{x}, invisibly. } \description{ Print methods } \seealso{ \link{pareto-k-diagnostic} } loo/man/loo.Rd0000644000176200001440000003321214407123455012704 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/loo.R \name{loo} \alias{loo} \alias{loo.array} \alias{loo.matrix} \alias{loo.function} \alias{loo_i} \alias{is.loo} \alias{is.psis_loo} \title{Efficient approximate leave-one-out cross-validation (LOO)} \usage{ loo(x, ...) \method{loo}{array}( x, ..., r_eff = NULL, save_psis = FALSE, cores = getOption("mc.cores", 1), is_method = c("psis", "tis", "sis") ) \method{loo}{matrix}( x, ..., r_eff = NULL, save_psis = FALSE, cores = getOption("mc.cores", 1), is_method = c("psis", "tis", "sis") ) \method{loo}{`function`}( x, ..., data = NULL, draws = NULL, r_eff = NULL, save_psis = FALSE, cores = getOption("mc.cores", 1), is_method = c("psis", "tis", "sis") ) loo_i( i, llfun, ..., data = NULL, draws = NULL, r_eff = NULL, is_method = "psis" ) is.loo(x) is.psis_loo(x) } \arguments{ \item{x}{A log-likelihood array, matrix, or function. The \strong{Methods (by class)} section, below, has detailed descriptions of how to specify the inputs for each method.} \item{r_eff}{Vector of relative effective sample size estimates for the likelihood (\code{exp(log_lik)}) of each observation. This is related to the relative efficiency of estimating the normalizing term in self-normalizing importance sampling when using posterior draws obtained with MCMC. If MCMC draws are used and \code{r_eff} is not provided then the reported PSIS effective sample sizes and Monte Carlo error estimates will be over-optimistic. If the posterior draws are independent then \code{r_eff=1} and can be omitted. The warning message thrown when \code{r_eff} is not specified can be disabled by setting \code{r_eff} to \code{NA}. See the \code{\link[=relative_eff]{relative_eff()}} helper functions for computing \code{r_eff}.} \item{save_psis}{Should the \code{"psis"} object created internally by \code{loo()} be saved in the returned object? The \code{loo()} function calls \code{\link[=psis]{psis()}} internally but by default discards the (potentially large) \code{"psis"} object after using it to compute the LOO-CV summaries. Setting \code{save_psis=TRUE} will add a \code{psis_object} component to the list returned by \code{loo}. Currently this is only needed if you plan to use the \code{\link[=E_loo]{E_loo()}} function to compute weighted expectations after running \code{loo}.} \item{cores}{The number of cores to use for parallelization. This defaults to the option \code{mc.cores} which can be set for an entire R session by \code{options(mc.cores = NUMBER)}. The old option \code{loo.cores} is now deprecated but will be given precedence over \code{mc.cores} until \code{loo.cores} is removed in a future release. \strong{As of version 2.0.0 the default is now 1 core if \code{mc.cores} is not set}, but we recommend using as many (or close to as many) cores as possible. \itemize{ \item Note for Windows 10 users: it is \strong{strongly} \href{https://github.com/stan-dev/loo/issues/94}{recommended} to avoid using the \code{.Rprofile} file to set \code{mc.cores} (using the \code{cores} argument or setting \code{mc.cores} interactively or in a script is fine). }} \item{is_method}{The importance sampling method to use. The following methods are implemented: \itemize{ \item \code{\link[=psis]{"psis"}}: Pareto-Smoothed Importance Sampling (PSIS). Default method. \item \code{\link[=tis]{"tis"}}: Truncated Importance Sampling (TIS) with truncation at \code{sqrt(S)}, where \code{S} is the number of posterior draws. \item \code{\link[=sis]{"sis"}}: Standard Importance Sampling (SIS). }} \item{data, draws, ...}{For the \code{loo.function()} method and the \code{loo_i()} function, these are the data, posterior draws, and other arguments to pass to the log-likelihood function. See the \strong{Methods (by class)} section below for details on how to specify these arguments.} \item{i}{For \code{loo_i()}, an integer in \code{1:N}.} \item{llfun}{For \code{loo_i()}, the same as \code{x} for the \code{loo.function()} method. A log-likelihood function as described in the \strong{Methods (by class)} section.} } \value{ The \code{loo()} methods return a named list with class \code{c("psis_loo", "loo")} and components: \describe{ \item{\code{estimates}}{ A matrix with two columns (\code{Estimate}, \code{SE}) and three rows (\code{elpd_loo}, \code{p_loo}, \code{looic}). This contains point estimates and standard errors of the expected log pointwise predictive density (\code{\link[=loo-glossary]{elpd_loo}}), the effective number of parameters (\code{\link[=loo-glossary]{p_loo}}) and the LOO information criterion \code{looic} (which is just \code{-2 * elpd_loo}, i.e., converted to deviance scale). } \item{\code{pointwise}}{ A matrix with five columns (and number of rows equal to the number of observations) containing the pointwise contributions of the measures (\code{elpd_loo}, \code{mcse_elpd_loo}, \code{p_loo}, \code{looic}, \code{influence_pareto_k}). in addition to the three measures in \code{estimates}, we also report pointwise values of the Monte Carlo standard error of \code{\link[=loo-glossary]{elpd_loo}} (\code{\link[=loo-glossary]{mcse_elpd_loo}}), and statistics describing the influence of each observation on the posterior distribution (\code{influence_pareto_k}). These are the estimates of the shape parameter \eqn{k} of the generalized Pareto fit to the importance ratios for each leave-one-out distribution (see the \link{pareto-k-diagnostic} page for details). } \item{\code{diagnostics}}{ A named list containing two vectors: \itemize{ \item \code{pareto_k}: Importance sampling reliability diagnostics. By default, these are equal to the \code{influence_pareto_k} in \code{pointwise}. Some algorithms can improve importance sampling reliability and modify these diagnostics. See the \link{pareto-k-diagnostic} page for details. \item \code{n_eff}: PSIS effective sample size estimates. } } \item{\code{psis_object}}{ This component will be \code{NULL} unless the \code{save_psis} argument is set to \code{TRUE} when calling \code{loo()}. In that case \code{psis_object} will be the object of class \code{"psis"} that is created when the \code{loo()} function calls \code{\link[=psis]{psis()}} internally to do the PSIS procedure. } } The \code{loo_i()} function returns a named list with components \code{pointwise} and \code{diagnostics}. These components have the same structure as the \code{pointwise} and \code{diagnostics} components of the object returned by \code{loo()} except they contain results for only a single observation. } \description{ The \code{loo()} methods for arrays, matrices, and functions compute PSIS-LOO CV, efficient approximate leave-one-out (LOO) cross-validation for Bayesian models using Pareto smoothed importance sampling (\link[=psis]{PSIS}). This is an implementation of the methods described in Vehtari, Gelman, and Gabry (2017) and Vehtari, Simpson, Gelman, Yao, and Gabry (2019). The \code{loo_i()} function enables testing log-likelihood functions for use with the \code{loo.function()} method. } \details{ The \code{loo()} function is an S3 generic and methods are provided for 3-D pointwise log-likelihood arrays, pointwise log-likelihood matrices, and log-likelihood functions. The array and matrix methods are the most convenient, but for models fit to very large datasets the \code{loo.function()} method is more memory efficient and may be preferable. } \section{Methods (by class)}{ \itemize{ \item \code{loo(array)}: An \eqn{I} by \eqn{C} by \eqn{N} array, where \eqn{I} is the number of MCMC iterations per chain, \eqn{C} is the number of chains, and \eqn{N} is the number of data points. \item \code{loo(matrix)}: An \eqn{S} by \eqn{N} matrix, where \eqn{S} is the size of the posterior sample (with all chains merged) and \eqn{N} is the number of data points. \item \code{loo(`function`)}: A function \code{f()} that takes arguments \code{data_i} and \code{draws} and returns a vector containing the log-likelihood for a single observation \code{i} evaluated at each posterior draw. The function should be written such that, for each observation \code{i} in \code{1:N}, evaluating \if{html}{\out{
}}\preformatted{f(data_i = data[i,, drop=FALSE], draws = draws) }\if{html}{\out{
}} results in a vector of length \code{S} (size of posterior sample). The log-likelihood function can also have additional arguments but \code{data_i} and \code{draws} are required. If using the function method then the arguments \code{data} and \code{draws} must also be specified in the call to \code{loo()}: \itemize{ \item \code{data}: A data frame or matrix containing the data (e.g. observed outcome and predictors) needed to compute the pointwise log-likelihood. For each observation \code{i}, the \code{i}th row of \code{data} will be passed to the \code{data_i} argument of the log-likelihood function. \item \code{draws}: An object containing the posterior draws for any parameters needed to compute the pointwise log-likelihood. Unlike \code{data}, which is indexed by observation, for each observation the entire object \code{draws} will be passed to the \code{draws} argument of the log-likelihood function. \item The \code{...} can be used if your log-likelihood function takes additional arguments. These arguments are used like the \code{draws} argument in that they are recycled for each observation. } }} \section{Defining \code{loo()} methods in a package}{ Package developers can define \code{loo()} methods for fitted models objects. See the example \code{loo.stanfit()} method in the \strong{Examples} section below for an example of defining a method that calls \code{loo.array()}. The \code{loo.stanreg()} method in the \strong{rstanarm} package is an example of defining a method that calls \code{loo.function()}. } \examples{ ### Array and matrix methods (using example objects included with loo package) # Array method LLarr <- example_loglik_array() rel_n_eff <- relative_eff(exp(LLarr)) loo(LLarr, r_eff = rel_n_eff, cores = 2) # Matrix method LLmat <- example_loglik_matrix() rel_n_eff <- relative_eff(exp(LLmat), chain_id = rep(1:2, each = 500)) loo(LLmat, r_eff = rel_n_eff, cores = 2) ### Using log-likelihood function instead of array or matrix set.seed(124) # Simulate data and draw from posterior N <- 50; K <- 10; S <- 100; a0 <- 3; b0 <- 2 p <- rbeta(1, a0, b0) y <- rbinom(N, size = K, prob = p) a <- a0 + sum(y); b <- b0 + N * K - sum(y) fake_posterior <- as.matrix(rbeta(S, a, b)) dim(fake_posterior) # S x 1 fake_data <- data.frame(y,K) dim(fake_data) # N x 2 llfun <- function(data_i, draws) { # each time called internally within loo the arguments will be equal to: # data_i: ith row of fake_data (fake_data[i,, drop=FALSE]) # draws: entire fake_posterior matrix dbinom(data_i$y, size = data_i$K, prob = draws, log = TRUE) } # Use the loo_i function to check that llfun works on a single observation # before running on all obs. For example, using the 3rd obs in the data: loo_3 <- loo_i(i = 3, llfun = llfun, data = fake_data, draws = fake_posterior, r_eff = NA) print(loo_3$pointwise[, "elpd_loo"]) # Use loo.function method (setting r_eff=NA since this posterior not obtained via MCMC) loo_with_fn <- loo(llfun, draws = fake_posterior, data = fake_data, r_eff = NA) # If we look at the elpd_loo contribution from the 3rd obs it should be the # same as what we got above with the loo_i function and i=3: print(loo_with_fn$pointwise[3, "elpd_loo"]) print(loo_3$pointwise[, "elpd_loo"]) # Check that the loo.matrix method gives same answer as loo.function method log_lik_matrix <- sapply(1:N, function(i) { llfun(data_i = fake_data[i,, drop=FALSE], draws = fake_posterior) }) loo_with_mat <- loo(log_lik_matrix, r_eff = NA) all.equal(loo_with_mat$estimates, loo_with_fn$estimates) # should be TRUE! \dontrun{ ### For package developers: defining loo methods # An example of a possible loo method for 'stanfit' objects (rstan package). # A similar method is included in the rstan package. # In order for users to be able to call loo(stanfit) instead of # loo.stanfit(stanfit) the NAMESPACE needs to be handled appropriately # (roxygen2 and devtools packages are good for that). # loo.stanfit <- function(x, pars = "log_lik", ..., save_psis = FALSE, cores = getOption("mc.cores", 1)) { stopifnot(length(pars) == 1L) LLarray <- loo::extract_log_lik(stanfit = x, parameter_name = pars, merge_chains = FALSE) r_eff <- loo::relative_eff(x = exp(LLarray), cores = cores) loo::loo.array(LLarray, r_eff = r_eff, cores = cores, save_psis = save_psis) } } } \references{ Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. \emph{Statistics and Computing}. 27(5), 1413--1432. doi:10.1007/s11222-016-9696-4 (\href{https://link.springer.com/article/10.1007/s11222-016-9696-4}{journal version}, \href{https://arxiv.org/abs/1507.04544}{preprint arXiv:1507.04544}). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. \href{https://arxiv.org/abs/1507.02646}{preprint arXiv:1507.02646} } \seealso{ \itemize{ \item The \strong{loo} package \href{https://mc-stan.org/loo/articles/index.html}{vignettes} for demonstrations. \item The \href{https://mc-stan.org/loo/articles/online-only/faq.html}{FAQ page} on the \strong{loo} website for answers to frequently asked questions. \item \code{\link[=psis]{psis()}} for the underlying Pareto Smoothed Importance Sampling (PSIS) procedure used in the LOO-CV approximation. \item \link{pareto-k-diagnostic} for convenience functions for looking at diagnostics. \item \code{\link[=loo_compare]{loo_compare()}} for model comparison. } } loo/man/importance_sampling.Rd0000644000176200001440000000215713575772017016163 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/importance_sampling.R \name{importance_sampling} \alias{importance_sampling} \title{A parent class for different importance sampling methods.} \usage{ importance_sampling(log_ratios, method, ...) } \arguments{ \item{log_ratios}{An array, matrix, or vector of importance ratios on the log scale (for PSIS-LOO these are \emph{negative} log-likelihood values). See the \strong{Methods (by class)} section below for a detailed description of how to specify the inputs for each method.} \item{method}{The importance sampling method to use. The following methods are implemented: \itemize{ \item \code{\link[=psis]{"psis"}}: Pareto-Smoothed Importance Sampling (PSIS). Default method. \item \code{\link[=tis]{"tis"}}: Truncated Importance Sampling (TIS) with truncation at \code{sqrt(S)}, where \code{S} is the number of posterior draws. \item \code{\link[=sis]{"sis"}}: Standard Importance Sampling (SIS). }} \item{...}{Arguments passed on to the various methods.} } \description{ A parent class for different importance sampling methods. } \keyword{internal} loo/man/figures/0000755000176200001440000000000014407123455013267 5ustar liggesusersloo/man/figures/stanlogo.png0000644000176200001440000003745413267637066015653 0ustar liggesusersPNG  IHDRwx+sBIT|d pHYs&:4tEXtSoftwarewww.inkscape.org< IDATxw|ՙsf$w+$` ؘbQCB ے'7B6R6uq6e7M ل$ ؒm Л$W43+WY{nyޯ/lIw >̙31 B2J #7¡# #a@H P U] ]tuW~V-nUt+ˊ@l sy#/f TILxC&f~I&`= PX]&b.{gʘɋE 邞0t hrh=OuO\Κ;gnnՓ zt2L¾xYIqAsb?l_3bw끳1s+WAŮmZ􇕻OA_LӀsxH`9pO_Can5 j.͠gڪ' UX;i\}2Ə A|g2xEnE٬Z;),V%sNLbALpCfX3j8w5O+~WϪg}1~X%L]PSyL1|/cʽ atC=؟{9ROLl;-!/aKH> `<` 4u-7%ʽNiܻ ;)x+֑|1c^"Qs.ȇ} hLOSq#cʽ-p+5o P;)7Ŵ0o܋|F dS |1J7(`-Nczʽ,a؈#~ܔgw3VE`ܗyBwS o0{V,sQ?|}1K"{/Y.+q5Jy9NZx "j9UX\oӶwa^2[xmoG!F@ǘ,٤׆2O2X{Lã)A¿6ҲwrdgK?%F#c]JF>;H9rϓJ?#ti;/evyʁ{4Qs%AFb_ .YB*2wc K ^;Kri*oC}1@J;-ߙ 0=Q=S8NRJܳZRGӠ_.[|s~5wS JBja킾 ˘ʎ7՞6rfjߣOASdb1E 8y)PF҄we߁ʑ{-aї1hnY@ʽG1a8wc Jл,Exq@f_VsaLy%p",CþYTFnwc r =U[(H_,N?+LpleK鲑;ɕt\/;}g1&V.NpTi/}2W徘 z+YɒdFɒzd˽ ^ r,C<{hyt$CʶR}&{)R{)-`ʲQ} VĘUnw*{9+EԾW¦mDe_鑲*&j&` J5Kgw Sʦܛ -=;r\Ȕ(&j?s^KY;)M%_¿aʚMޕ )|wSvv 9A;[Y;)?%9r^#ࣾ@,]NߙLy+ro?@;)i1"ДܴLfnrdP%Xs(%5roS5sJE2^n1Ţdʽ+\O 7oV.܂9/E)*%Q~ <5}" 9~wc˽F)&̞*"ܔ.%AQd mĉ_1( $W69I1ٗ۩{AP!Ug[S2r_ȸG,003.;1&rA5 Z[hL}15O89}4 5U|'1GNK}؍)/9-SypZ.a0B"Fq xN\t뮐z˘ÑY{sO;hnLƏ Vӕ|bYモc= [܊"&p 4a/71 b؍)5xSLSXHwyܛȋ@U6kЖ&u-y4,er$S''L&o+Hl;#wV7؍g9;U0i S#'!> |*[6rof\<?dϫevA)TiB2k$~*?+/z1ٷqnT 2 =϶vO][V-e쨈j`@6gzF3 9zk|g1X)d"]8&B8ɄY=&(Vy ؍f L z2ȉ'v]qx pe9Xhg7f?ׁ͋la\v(o#y/Vy'r{)w9$`*N2S+'r4/2zYҟ+H35O`F5&sSZjXOG+i2_#b3e­L<"E<]$EO9`-x]Eh]L^o ˜@j'(LKΡSA|BKĻ1sKЇzg;}12ۀ'+:ݡ')LVuG`j=ˋɻ$-T pCNQS]T[?^}'(7&(-3K"_ie&?1G"'55'_{DVA+)\Z]U]yBJ ~ړq rES>lV|*=NHftɚ*7.zX=ZD8Vlk> Cꩂ:8;) NՇ U4p{a۽~\n68Ȕ%Nu]#1\;y͵ԥb*SaG~ȅq{&kuϋLo88d3ɂW}M\Vy߳bYc# z:l8͘Cp!ɥa]!kLOll}(UK86">8]f88"3zOMqpn˽R&IoRHe5h!JR&W=[3߹ɂeF6m;t;rBA$sh 9pTzZÖωHW 6hJKcC}ae%V55ss 3dގw)u̦.%YOd?P-vxΑmph66*7H߬ Z|qȟ&jM4y"i;wBڣ8`&pv1HN͚nF\2Jpe|TQ{<{X87A'eLq.Kn޴ V!e9(3Ag>ksw$g*6Le2|#m#W.5g8$ru9c~;D?WթzUvB$:̍?}ș 5Cs@,!zKqtu;ZE.>v#azblbɳCh=<#?QB + \1>}`;U]oorF&VˠԞ -L˸JTo9vO >ҮɻSW\8G!` \'.慃س}ޠQc;Bڈ.$S#!=g&`TOjuW>fX|a_uLz7:.ΊǎQ#ԖBm)}LxE< zZ>s~c撷"8o8* 83d1Y9z6}0SP"~c_N.ʘqQ`+yc"!5sorדRږ_]~q+UAѱcZ2Jޘ~C'*3 88jB{*zx`.ΑmR2HLX'u{~ V<+EGhn%(/c␩Q@13ݞLF>zn7=η3zsnv\]ld+$!p|r|ƌ) `o7E\½ 4(dBߚ81.wE&o)cB-scae~*m[Dy0ˆcc 6ecʀ1j2Vd]wRuOJݛ\2WrK'Ȉq(({p)aw 2&ϡe{j{ڵo5 q k*:88ҾMQdr,%Ikw?t^n+a vQ ##jqH͛1]a(5M+ { >w s8`R؍v;Miџ*;9m]<FK<-ܘ;YȸG'dҗ]bJcj0(և<~d^ҒyKAĈD8&maSƅ [=/Vw]Edt8P+wpVg :*Xś%_R, eN r/E\Qh?5%V0Q|RÉMQゎ .`x,XVfˎ"i)PF694/\|YivT8W]sA !S P Δ=ӵ<qVgtӣЖ^[nHžw sU*483p^N{8HIKvb'^q / !τ123  A6;W|1sd831]Ɍ(dXsx;*:Xk-EB`&;*T8. &R67ފNBlRxw]Bf)qzgA Agĺx$"R P`j”b^ bۍ-f?/u}_#e{9%dsed 'D!6Ɓ-4X'>;͡WrJ=mSGM.aetM" wWtp~Gm%MQ, Ч|1:y]5U8!VE'ɲ jS3f(mABKK솗25@:*f_TbD`<@Eiq Ͷ /;hnQLAT8Mԧ+9% 9v,§"kX ]7)V\QACΐV%o(:mGҢ E 6r76H)qȔ^vѝ0IDAT .Rgv|G1r+Y0~RLҢuYԊb&{jTbRccbeKX^%0fdaqJne2WgD&Hhu1ĊH)ʃN.IWlrU>ØBLNx9Hhski+1Q cN陂tM,Ua^S(뜲&iu VE!+` zZ=K!Qg2JJu,]ɬt%ӣБV޼:{K$gO7Q 0<ɒK,c=|$OБb\bw5zHUgy]3!P;jbv&$]2g9.x޿٧yr7%Axqe%%촢Ϫ];dL 0:qNu+Niu-Ab ^kSiyv4N0"IqJ]f+M _ ҜzD^3S v42nEct>Bb}P˘0L9J.(d-{wn*\PצnBNBwc|쒁*^nh6Ӣ.aUb6gJQc)/Joc{ bd#&2,,FnØči¿Jճvd2x^GFgeLQ;岢 O.TOeŖ?xL61#j‚8Si Zu..7$2T;v8 A61+E湱oHѐ(Ű[q3Dݦ;*~ R=htܝ"ywci 'D'D] fK(7!$M+_QJ.B7D9cLu.fe&(i)xaz-)TN8g[zWS`|03EcΐE2ms4$Ċ!]lݘz%J.8,إ'U~^y>;C.9Id9]*U\@J=Az[N"`D9C}>ہrsHU 'DJ蘒&?͵ w}KNyc{cU>{97d71$1cgBbuM Wo|mlcYy `rE c鋁*{.cyCƷw}c7L~h7ЃuM> z\"cay*;wHJwmof@%h M_h]7ݘ4> :*CdItŞ+P[ \ϒhNA_AM85Q&jZKk]a+g olߴP_LjGi0onɴ 4e-1&%uTpNg\x Ck+vE?O;LCoN[~2q800"sT"EaCǺ!ȦdAOG從Q< `S)*!prrtH*]RqM?=@9џ]\Ý@0!*Q1:ݛb,2 Y =|u/'&E>Nk]#-}Cw;w!Yzp=MAy8O1S4'Oy8)L߭urG]flnLaFZ>| =-v` 1&T`A@2bM[0Y 7/CAz:cLN$@Sۥ=6S}"bh7/c1~%W+ <+I "z~cX k1/z^ neq+3^(6Tŋ޼3_cCPޓbpDƊ`}|zy0ч17t~-ٖC E_^rn}}1[OhW='3ۚyBo19w_ 4rPGZ=?>Rws֭Դ>z_ OY+D3V8t`}}u:kzc \=`bm_YQ{AgJ_D2vTDq)#i&%[RWǸ )Y ;#YM X<Ê|2"_OB*v +B"ءs{"G3ۂڲHc*l<;̡dls=AۋYK{cJD$$pˌ@Յ\ U؞C[/#0_cSYp pͪuMԾ'KlHS6*̇y_¦T Ɓ2rv4oBЛҶ<|3ɍ}g1;V5S}"1)iл/f߁jW`,WO뙽yRw6rHo ,1$ p.Re߁Vj @;9l;dyǰ.ެ7r@5QȧJy!@yEy\cr(^'pk#k}ʆLJrC?pnVG%dqLYwlzԷZqs@coLYwl[L }حԋm Łs2r̕_\Ø hSi!Sx;Dq_s:mL!ɃaZ)yw ڜ.߁r)˄K}?h=P;ɪ6\ >nstqk^Ϩ?^ÝO!$ﳟ$R@Yyrk?>?Քd K}?S4_ne[@;-FZs~g.4QspIg*;,ͮq@0p* odA@8SΖB>NpwֳY߁e)+#җ]^A६DDNfjyN㝂> !s=XHC\;CFZ)_kgvzmGeB5^S.s@13tu;9M959.p @ܗd` \͡\\Oy>gپ3%)NEt$ֳv@LxE%3L(H{}޼]P[@>od2S-LqoF \Z:@-M):?.7Qn|Vpp#>3=AV*:T%(:[tY@l_g2-GĖy!w[PM30Uq 0))&d[@Q |+w2g"] ^;!H) \( b7י,R}gDR;sdLѻqnK4!""A.dJZ;i":R80w".Kp*S9 Id&91QXƔ0J|,AR@O(,sݻH[.oo#zp>0^2@}o; y{H];Or)d΂|AO@މr@[<~20SLY v(ٴ\;Au[9@c:oȧhSD/{.p"h=ɩn8Aꀩsiw(=яU) /)Kۮ|?0iBBtVW}yNeܱBw{6v5f AuJR'TcKam+QlȻOf98vM|g+~ZNƟ )rt{j1EqWLӺcKymS^Νͪud{7v/?k9rcJIK@xlV$ܻ۬dZq)r}VN{e]pϡe$PN}m+Ӏscf% Xw\)r_DI7KɌk}g2xd@Rc_Qs N#B|lZ7kw|hdwŸ|g1xs_;Y[e2-R&WFo.W^_9ޭvoP63ƔE!o+]av&Y-3crGJG[VʲwkKW)ƔLė/E^!诀c]};Oe_ >! )vil~A|rLxyQY;H!(u=QOۚv4b-Czk2imT+czJ{1\B+9&jjLڮiY;H!rBj:t0wc>^ppZPٴL7.ieY|Y1{4gXwF=DA Ř2+GiyL7{g+fwcʉB$idrYMB=kS.Jd+ޱ{d6 `<Ɣ]|Ra1G'}ifbLy( yl<;Hi~Cˊ!wcJXܳd5 ;1E5z FYHCh?i'[gs 3Z4Y)pwXrR1ǘ +|g.ľÔ"+~Y) H>lLs=O~ A?_Oo})VyC;IY=jLإ*:b\X{̸Z} ]؟)iꕾ+R}f(:Y.}TOF=S&)7&M['>L/^YTB>%9aK$?gNa{Y!~8wc' I;1[|1r/PVm}s-cd^S;9gv+m89{[1[BywO<۫^~y4vq>>̮reoh3q{6s +2邼O@<&o^+zs#m 4z >]]r們w@TUsKo D7~1ʝ{jv8wu nZִˡjWtSw.$qoX

Vf>?+}piܱ++G0YS 4^~әnD r{gC8F05M`U~k'yZ&>00<)Ky#bڴkKup\!S9 Hq;<,VfV14wC8y +Vp{.fzUU ޠ*X|X5j9W/ׯyAEy qK鱽oA )9 3"2p_}x}qOq$sCuO+o}LJNDÖ+w'F CdFg98ɶ)fAy6K|Yk++G 7*=`GPy7/z\lerj5*0MHLf|gˣx^yOͦe 9pQEeˍ#N ԝae4`F,\|Y[jd (0O1.`+dUׯW%z<{5wzΗs6lS]os$7^%LI4!@&&1F(:BHō t3f 3c}f]yJX9Q4Gn@~NERCI;D8'WݴsByK)j0~D%P! d޹EQpm,Fi*RڂX U`$j2G1l?Πɡ"^@p_zNƙa$FF:u5ȏ2IENDB`loo/man/figures/logo.svg0000644000176200001440000002316214407123455014754 0ustar liggesusers loo/man/dot-thin_draws.Rd0000644000176200001440000000126613575772017015056 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/loo_subsample.R \name{.thin_draws} \alias{.thin_draws} \title{Thin a draws object} \usage{ .thin_draws(draws, loo_approximation_draws) } \arguments{ \item{draws}{A draws object with posterior draws.} \item{loo_approximation_draws}{The number of posterior draws to return (ie after thinning).} } \value{ A thinned draws object. } \description{ Thin a draws object } \details{ This is a generic function to thin draws from arbitrary draws objects. The function is internal and should only be used by developers to enable \code{\link[=loo_subsample]{loo_subsample()}} for arbitrary draws objects. } \keyword{internal} loo/man/update.psis_loo_ss.Rd0000644000176200001440000001207414407123455015733 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/loo_subsample.R \name{update.psis_loo_ss} \alias{update.psis_loo_ss} \title{Update \code{psis_loo_ss} objects} \usage{ \method{update}{psis_loo_ss}( object, ..., data = NULL, draws = NULL, observations = NULL, r_eff = NULL, cores = getOption("mc.cores", 1), loo_approximation = NULL, loo_approximation_draws = NULL, llgrad = NULL, llhess = NULL ) } \arguments{ \item{object}{A \code{psis_loo_ss} object to update.} \item{...}{Currently not used.} \item{data, draws}{See \code{\link[=loo_subsample.function]{loo_subsample.function()}}.} \item{observations}{The subsample observations to use. The argument can take four (4) types of arguments: \itemize{ \item \code{NULL} to use all observations. The algorithm then just uses standard \code{loo()} or \code{loo_approximate_posterior()}. \item A single integer to specify the number of observations to be subsampled. \item A vector of integers to provide the indices used to subset the data. \emph{These observations need to be subsampled with the same scheme as given by the \code{estimator} argument}. \item A \code{psis_loo_ss} object to use the same observations that were used in a previous call to \code{loo_subsample()}. }} \item{r_eff}{Vector of relative effective sample size estimates for the likelihood (\code{exp(log_lik)}) of each observation. This is related to the relative efficiency of estimating the normalizing term in self-normalizing importance sampling when using posterior draws obtained with MCMC. If MCMC draws are used and \code{r_eff} is not provided then the reported PSIS effective sample sizes and Monte Carlo error estimates will be over-optimistic. If the posterior draws are independent then \code{r_eff=1} and can be omitted. The warning message thrown when \code{r_eff} is not specified can be disabled by setting \code{r_eff} to \code{NA}. See the \code{\link[=relative_eff]{relative_eff()}} helper functions for computing \code{r_eff}.} \item{cores}{The number of cores to use for parallelization. This defaults to the option \code{mc.cores} which can be set for an entire R session by \code{options(mc.cores = NUMBER)}. The old option \code{loo.cores} is now deprecated but will be given precedence over \code{mc.cores} until \code{loo.cores} is removed in a future release. \strong{As of version 2.0.0 the default is now 1 core if \code{mc.cores} is not set}, but we recommend using as many (or close to as many) cores as possible. \itemize{ \item Note for Windows 10 users: it is \strong{strongly} \href{https://github.com/stan-dev/loo/issues/94}{recommended} to avoid using the \code{.Rprofile} file to set \code{mc.cores} (using the \code{cores} argument or setting \code{mc.cores} interactively or in a script is fine). }} \item{loo_approximation}{What type of approximation of the loo_i's should be used? The default is \code{"plpd"} (the log predictive density using the posterior expectation). There are six different methods implemented to approximate loo_i's (see the references for more details): \itemize{ \item \code{"plpd"}: uses the lpd based on point estimates (i.e., \eqn{p(y_i|\hat{\theta})}). \item \code{"lpd"}: uses the lpds (i,e., \eqn{p(y_i|y)}). \item \code{"tis"}: uses truncated importance sampling to approximate PSIS-LOO. \item \code{"waic"}: uses waic (i.e., \eqn{p(y_i|y) - p_{waic}}). \item \code{"waic_grad_marginal"}: uses waic approximation using first order delta method and posterior marginal variances to approximate \eqn{p_{waic}} (ie. \eqn{p(y_i|\hat{\theta})}-p_waic_grad_marginal). Requires gradient of likelihood function. \item \code{"waic_grad"}: uses waic approximation using first order delta method and posterior covariance to approximate \eqn{p_{waic}} (ie. \eqn{p(y_i|\hat{\theta})}-p_waic_grad). Requires gradient of likelihood function. \item \code{"waic_hess"}: uses waic approximation using second order delta method and posterior covariance to approximate \eqn{p_{waic}} (ie. \eqn{p(y_i|\hat{\theta})}-p_waic_grad). Requires gradient and Hessian of likelihood function. } As point estimates of \eqn{\hat{\theta}}, the posterior expectations of the parameters are used.} \item{loo_approximation_draws}{The number of posterior draws used when integrating over the posterior. This is used if \code{loo_approximation} is set to \code{"lpd"}, \code{"waic"}, or \code{"tis"}.} \item{llgrad}{The gradient of the log-likelihood. This is only used when \code{loo_approximation} is \code{"waic_grad"}, \code{"waic_grad_marginal"}, or \code{"waic_hess"}. The default is \code{NULL}.} \item{llhess}{The hessian of the log-likelihood. This is only used with \code{loo_approximation = "waic_hess"}. The default is \code{NULL}.} } \value{ A \code{psis_loo_ss} object. } \description{ Update \code{psis_loo_ss} objects } \details{ If \code{observations} is updated then if a vector of indices or a \code{psis_loo_ss} object is supplied the updated object will have exactly the observations indicated by the vector or \code{psis_loo_ss} object. If a single integer is supplied, new observations will be sampled to reach the supplied sample size. } loo/man/psislw.Rd0000644000176200001440000000470514407123455013441 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/psislw.R \name{psislw} \alias{psislw} \title{Pareto smoothed importance sampling (deprecated, old version)} \usage{ psislw( lw, wcp = 0.2, wtrunc = 3/4, cores = getOption("mc.cores", 1), llfun = NULL, llargs = NULL, ... ) } \arguments{ \item{lw}{A matrix or vector of log weights. For computing LOO, \code{lw = -log_lik}, the \emph{negative} of an \eqn{S} (simulations) by \eqn{N} (data points) pointwise log-likelihood matrix.} \item{wcp}{The proportion of importance weights to use for the generalized Pareto fit. The \code{100*wcp}\\% largest weights are used as the sample from which to estimate the parameters of the generalized Pareto distribution.} \item{wtrunc}{For truncating very large weights to \eqn{S}^\code{wtrunc}. Set to zero for no truncation.} \item{cores}{The number of cores to use for parallelization. This defaults to the option \code{mc.cores} which can be set for an entire R session by \code{options(mc.cores = NUMBER)}, the old option \code{loo.cores} is now deprecated but will be given precedence over \code{mc.cores} until it is removed. \strong{As of version 2.0.0, the default is now 1 core if \code{mc.cores} is not set, but we recommend using as many (or close to as many) cores as possible.}} \item{llfun, llargs}{See \code{\link[=loo.function]{loo.function()}}.} \item{...}{Ignored when \code{psislw()} is called directly. The \code{...} is only used internally when \code{psislw()} is called by the \code{\link[=loo]{loo()}} function.} } \value{ A named list with components \code{lw_smooth} (modified log weights) and \code{pareto_k} (estimated generalized Pareto shape parameter(s) k). } \description{ As of version \verb{2.0.0} this function is \strong{deprecated}. Please use the \code{\link[=psis]{psis()}} function for the new PSIS algorithm. } \references{ Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. \emph{Statistics and Computing}. 27(5), 1413--1432. doi:10.1007/s11222-016-9696-4 (\href{https://link.springer.com/article/10.1007/s11222-016-9696-4}{journal version}, \href{https://arxiv.org/abs/1507.04544}{preprint arXiv:1507.04544}). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. \href{https://arxiv.org/abs/1507.02646}{preprint arXiv:1507.02646} } \seealso{ \link{pareto-k-diagnostic} for PSIS diagnostics. } loo/man/kfold-helpers.Rd0000644000176200001440000000365613575772017014674 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/kfold-helpers.R \name{kfold-helpers} \alias{kfold-helpers} \alias{kfold_split_random} \alias{kfold_split_stratified} \alias{kfold_split_grouped} \title{Helper functions for K-fold cross-validation} \usage{ kfold_split_random(K = 10, N = NULL) kfold_split_stratified(K = 10, x = NULL) kfold_split_grouped(K = 10, x = NULL) } \arguments{ \item{K}{The number of folds to use.} \item{N}{The number of observations in the data.} \item{x}{A discrete variable of length \code{N} with at least \code{K} levels (unique values). Will be coerced to a \link[=factor]{factor}.} } \value{ An integer vector of length \code{N} where each element is an index in \code{1:K}. } \description{ These functions can be used to generate indexes for use with K-fold cross-validation. See the \strong{Details} section for explanations. } \details{ \code{kfold_split_random()} splits the data into \code{K} groups of equal size (or roughly equal size). For a categorical variable \code{x} \code{kfold_split_stratified()} splits the observations into \code{K} groups ensuring that relative category frequencies are approximately preserved. For a grouping variable \code{x}, \code{kfold_split_grouped()} places all observations in \code{x} from the same group/level together in the same fold. The selection of which groups/levels go into which fold (relevant when when there are more groups than folds) is randomized. } \examples{ ids <- kfold_split_random(K = 5, N = 20) print(ids) table(ids) x <- sample(c(0, 1), size = 200, replace = TRUE, prob = c(0.05, 0.95)) table(x) ids <- kfold_split_stratified(K = 5, x = x) print(ids) table(ids, x) grp <- gl(n = 50, k = 15, labels = state.name) length(grp) head(table(grp)) ids_10 <- kfold_split_grouped(K = 10, x = grp) (tab_10 <- table(grp, ids_10)) colSums(tab_10) ids_9 <- kfold_split_grouped(K = 9, x = grp) (tab_9 <- table(grp, ids_9)) colSums(tab_9) } loo/man/crps.Rd0000644000176200001440000000745114411130104013050 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/crps.R \name{crps} \alias{crps} \alias{scrps} \alias{loo_crps} \alias{loo_scrps} \alias{crps.matrix} \alias{crps.numeric} \alias{loo_crps.matrix} \alias{scrps.matrix} \alias{scrps.numeric} \alias{loo_scrps.matrix} \title{Continuously ranked probability score} \usage{ crps(x, ...) scrps(x, ...) loo_crps(x, ...) loo_scrps(x, ...) \method{crps}{matrix}(x, x2, y, ..., permutations = 1) \method{crps}{numeric}(x, x2, y, ..., permutations = 1) \method{loo_crps}{matrix}( x, x2, y, log_lik, ..., permutations = 1, r_eff = NULL, cores = getOption("mc.cores", 1) ) \method{scrps}{matrix}(x, x2, y, ..., permutations = 1) \method{scrps}{numeric}(x, x2, y, ..., permutations = 1) \method{loo_scrps}{matrix}( x, x2, y, log_lik, ..., permutations = 1, r_eff = NULL, cores = getOption("mc.cores", 1) ) } \arguments{ \item{x}{A \code{S} by \code{N} matrix (draws by observations), or a vector of length \code{S} when only single observation is provided in \code{y}.} \item{...}{Passed on to \code{\link[=E_loo]{E_loo()}} in the \verb{loo_*()} version of these functions.} \item{x2}{Independent draws from the same distribution as draws in \code{x}. Should be of the identical dimension.} \item{y}{A vector of observations or a single value.} \item{permutations}{An integer, with default value of 1, specifying how many times the expected value of |X - X'| (\verb{|x - x2|}) is computed. The row order of \code{x2} is shuffled as elements \code{x} and \code{x2} are typically drawn given the same values of parameters. This happens, e.g., when one calls \code{posterior_predict()} twice for a fitted \pkg{rstanarm} or \pkg{brms} model. Generating more permutations is expected to decrease the variance of the computed expected value.} \item{log_lik}{A log-likelihood matrix the same size as \code{x}.} \item{r_eff}{An optional vector of relative effective sample size estimates containing one element per observation. See \code{\link[=psis]{psis()}} for details.} \item{cores}{The number of cores to use for parallelization of \verb{[psis()]}. See \code{\link[=psis]{psis()}} for details.} } \value{ A list containing two elements: \code{estimates} and \code{pointwise}. The former reports estimator and standard error and latter the pointwise values. } \description{ The \code{crps()} and \code{scrps()} functions and their \verb{loo_*()} counterparts can be used to compute the continuously ranked probability score (CRPS) and scaled CRPS (SCRPS) (see Bolin and Wallin, 2022). CRPS is a proper scoring rule, and strictly proper when the first moment of the predictive distribution is finite. Both can be expressed in terms of samples form the predictive distribution. See e.g. Gneiting and Raftery (2007) for a comprehensive discussion on CRPS. } \details{ To compute (S)CRPS, the user needs to provide two sets of draws, \code{x} and \code{x2}, from the predictive distribution. This is due to the fact that formulas used to compute CRPS involve an expectation of the absolute difference of \code{x} and \code{x2}, both having the same distribution. See the \code{permutations} argument, as well as Gneiting and Raftery (2007) for details. } \examples{ \dontrun{ # An example using rstanarm library(rstanarm) data("kidiq") fit <- stan_glm(kid_score ~ mom_hs + mom_iq, data = kidiq) ypred1 <- posterior_predict(fit) ypred2 <- posterior_predict(fit) crps(ypred1, ypred2, y = fit$y) loo_crps(ypred1, ypred2, y = fit$y, log_lik = log_lik(fit)) } } \references{ Bolin, D., & Wallin, J. (2022). Local scale invariance and robustness of proper scoring rules. arXiv. \doi{10.48550/arXiv.1912.05642} Gneiting, T., & Raftery, A. E. (2007). Strictly Proper Scoring Rules, Prediction, and Estimation. Journal of the American Statistical Association, 102(477), 359–378. } loo/man/importance_sampling.default.Rd0000644000176200001440000000356013575772017017605 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/importance_sampling.R \name{importance_sampling.default} \alias{importance_sampling.default} \title{Importance sampling (default)} \usage{ \method{importance_sampling}{default}(log_ratios, method, ..., r_eff = NULL) } \arguments{ \item{log_ratios}{An array, matrix, or vector of importance ratios on the log scale (for PSIS-LOO these are \emph{negative} log-likelihood values). See the \strong{Methods (by class)} section below for a detailed description of how to specify the inputs for each method.} \item{...}{Arguments passed on to the various methods.} \item{r_eff}{Vector of relative effective sample size estimates containing one element per observation. The values provided should be the relative effective sample sizes of \code{1/exp(log_ratios)} (i.e., \code{1/ratios}). This is related to the relative efficiency of estimating the normalizing term in self-normalizing importance sampling. If \code{r_eff} is not provided then the reported PSIS effective sample sizes and Monte Carlo error estimates will be over-optimistic. See the \code{\link[=relative_eff]{relative_eff()}} helper function for computing \code{r_eff}. If using \code{psis} with draws of the \code{log_ratios} not obtained from MCMC then the warning message thrown when not specifying \code{r_eff} can be disabled by setting \code{r_eff} to \code{NA}.} \item{is_method}{The importance sampling method to use. The following methods are implemented: \itemize{ \item \code{\link[=psis]{"psis"}}: Pareto-Smoothed Importance Sampling (PSIS). Default method. \item \code{\link[=tis]{"tis"}}: Truncated Importance Sampling (TIS) with truncation at \code{sqrt(S)}, where \code{S} is the number of posterior draws. \item \code{\link[=sis]{"sis"}}: Standard Importance Sampling (SIS). }} } \description{ Importance sampling (default) } \keyword{internal} loo/man/find_model_names.Rd0000644000176200001440000000070713575772017015412 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/loo_compare.R \name{find_model_names} \alias{find_model_names} \title{Find the model names associated with \code{"loo"} objects} \usage{ find_model_names(x) } \arguments{ \item{x}{List of \code{"loo"} objects.} } \value{ Character vector of model names the same length as \code{x.} } \description{ Find the model names associated with \code{"loo"} objects } \keyword{internal} loo/man/loo-datasets.Rd0000644000176200001440000000346614407123455014522 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/datasets.R \name{loo-datasets} \alias{loo-datasets} \alias{Kline} \alias{milk} \alias{voice} \alias{voice_loo} \title{Datasets for loo examples and vignettes} \description{ Small datasets for use in \strong{loo} examples and vignettes. The \code{Kline} and \code{milk} datasets are also included in the \strong{rethinking} package (McElreath, 2016a), but we include them here as \strong{rethinking} is not on CRAN. } \details{ Currently the data sets included are: \itemize{ \item \code{Kline}: Small dataset from Kline and Boyd (2010) on tool complexity and demography in Oceanic islands societies. This data is discussed in detail in McElreath (2016a,2016b). \href{https://www.rdocumentation.org/packages/rethinking/versions/1.59/topics/Kline}{(Link to variable descriptions)} \item \code{milk}: Small dataset from Hinde and Milligan (2011) on primate milk composition.This data is discussed in detail in McElreath (2016a,2016b). \href{https://www.rdocumentation.org/packages/rethinking/versions/1.59/topics/milk}{(Link to variable descriptions)} \item \code{voice}: Voice rehabilitation data from Tsanas et al. (2014). } } \examples{ str(Kline) str(milk) } \references{ Hinde and Milligan. 2011. \emph{Evolutionary Anthropology} 20:9-23. Kline, M.A. and R. Boyd. 2010. \emph{Proc R Soc B} 277:2559-2564. McElreath, R. (2016a). rethinking: Statistical Rethinking book package. R package version 1.59. McElreath, R. (2016b). \emph{Statistical rethinking: A Bayesian course with examples in R and Stan}. Chapman & Hall/CRC. A. Tsanas, M.A. Little, C. Fox, L.O. Ramig: Objective automatic assessment of rehabilitative speech treatment in Parkinson's disease, IEEE Transactions on Neural Systems and Rehabilitation Engineering, Vol. 22, pp. 181-190, January 2014 } loo/man/kfold-generic.Rd0000644000176200001440000000317513575772017014642 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/kfold-generic.R \name{kfold-generic} \alias{kfold-generic} \alias{kfold} \alias{is.kfold} \title{Generic function for K-fold cross-validation for developers} \usage{ kfold(x, ...) is.kfold(x) } \arguments{ \item{x}{A fitted model object.} \item{...}{Arguments to pass to specific methods.} } \value{ For developers defining a \code{kfold()} method for a class \code{"foo"}, the \code{kfold.foo()} function should return a list with class \code{c("kfold", "loo")} with at least the following named elements: \itemize{ \item \code{"estimates"}: A \verb{1x2} matrix containing the ELPD estimate and its standard error. The matrix must have row name "\code{elpd_kfold}" and column names \code{"Estimate"} and \code{"SE"}. \item \code{"pointwise"}: A \code{Nx1} matrix with column name \code{"elpd_kfold"} containing the pointwise contributions for each data point. } It is important for the object to have at least these classes and components so that it is compatible with other functions like \code{\link[=loo_compare]{loo_compare()}} and \code{print()} methods. } \description{ For developers of Bayesian modeling packages, \strong{loo} includes a generic function \code{kfold()} so that methods may be defined for K-fold CV without name conflicts between packages. See, for example, the \code{kfold()} methods in the \strong{rstanarm} and \strong{brms} packages. The \strong{Value} section below describes the objects that \code{kfold()} methods should return in order to be compatible with \code{\link[=loo_compare]{loo_compare()}} and the \strong{loo} package print methods. } loo/man/relative_eff.Rd0000644000176200001440000001073514407123455014553 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/effective_sample_sizes.R \name{relative_eff} \alias{relative_eff} \alias{relative_eff.default} \alias{relative_eff.matrix} \alias{relative_eff.array} \alias{relative_eff.function} \alias{relative_eff.importance_sampling} \title{Convenience function for computing relative efficiencies} \usage{ relative_eff(x, ...) \method{relative_eff}{default}(x, chain_id, ...) \method{relative_eff}{matrix}(x, chain_id, ..., cores = getOption("mc.cores", 1)) \method{relative_eff}{array}(x, ..., cores = getOption("mc.cores", 1)) \method{relative_eff}{`function`}( x, chain_id, ..., cores = getOption("mc.cores", 1), data = NULL, draws = NULL ) \method{relative_eff}{importance_sampling}(x, ...) } \arguments{ \item{x}{A vector, matrix, 3-D array, or function. See the \strong{Methods (by class)} section below for details on specifying \code{x}, but where "log-likelihood" is mentioned replace it with one of the following depending on the use case: \itemize{ \item For use with the \code{\link[=loo]{loo()}} function, the values in \code{x} (or generated by \code{x}, if a function) should be \strong{likelihood} values (i.e., \code{exp(log_lik)}), not on the log scale. \item For generic use with \code{\link[=psis]{psis()}}, the values in \code{x} should be the reciprocal of the importance ratios (i.e., \code{exp(-log_ratios)}). }} \item{chain_id}{A vector of length \code{NROW(x)} containing MCMC chain indexes for each each row of \code{x} (if a matrix) or each value in \code{x} (if a vector). No \code{chain_id} is needed if \code{x} is a 3-D array. If there are \code{C} chains then valid chain indexes are values in \code{1:C}.} \item{cores}{The number of cores to use for parallelization.} \item{data, draws, ...}{Same as for the \code{\link[=loo]{loo()}} function method.} } \value{ A vector of relative effective sample sizes. } \description{ \code{relative_eff()} computes the the MCMC effective sample size divided by the total sample size. } \section{Methods (by class)}{ \itemize{ \item \code{relative_eff(default)}: A vector of length \eqn{S} (posterior sample size). \item \code{relative_eff(matrix)}: An \eqn{S} by \eqn{N} matrix, where \eqn{S} is the size of the posterior sample (with all chains merged) and \eqn{N} is the number of data points. \item \code{relative_eff(array)}: An \eqn{I} by \eqn{C} by \eqn{N} array, where \eqn{I} is the number of MCMC iterations per chain, \eqn{C} is the number of chains, and \eqn{N} is the number of data points. \item \code{relative_eff(`function`)}: A function \code{f()} that takes arguments \code{data_i} and \code{draws} and returns a vector containing the log-likelihood for a single observation \code{i} evaluated at each posterior draw. The function should be written such that, for each observation \code{i} in \code{1:N}, evaluating \if{html}{\out{

}}\preformatted{f(data_i = data[i,, drop=FALSE], draws = draws) }\if{html}{\out{
}} results in a vector of length \code{S} (size of posterior sample). The log-likelihood function can also have additional arguments but \code{data_i} and \code{draws} are required. If using the function method then the arguments \code{data} and \code{draws} must also be specified in the call to \code{loo()}: \itemize{ \item \code{data}: A data frame or matrix containing the data (e.g. observed outcome and predictors) needed to compute the pointwise log-likelihood. For each observation \code{i}, the \code{i}th row of \code{data} will be passed to the \code{data_i} argument of the log-likelihood function. \item \code{draws}: An object containing the posterior draws for any parameters needed to compute the pointwise log-likelihood. Unlike \code{data}, which is indexed by observation, for each observation the entire object \code{draws} will be passed to the \code{draws} argument of the log-likelihood function. \item The \code{...} can be used if your log-likelihood function takes additional arguments. These arguments are used like the \code{draws} argument in that they are recycled for each observation. } \item \code{relative_eff(importance_sampling)}: If \code{x} is an object of class \code{"psis"}, \code{relative_eff()} simply returns the \code{r_eff} attribute of \code{x}. }} \examples{ LLarr <- example_loglik_array() LLmat <- example_loglik_matrix() dim(LLarr) dim(LLmat) rel_n_eff_1 <- relative_eff(exp(LLarr)) rel_n_eff_2 <- relative_eff(exp(LLmat), chain_id = rep(1:2, each = 500)) all.equal(rel_n_eff_1, rel_n_eff_2) } loo/man/loo_approximate_posterior.Rd0000644000176200001440000001366714407123455017437 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/loo_approximate_posterior.R \name{loo_approximate_posterior} \alias{loo_approximate_posterior} \alias{loo_approximate_posterior.array} \alias{loo_approximate_posterior.matrix} \alias{loo_approximate_posterior.function} \title{Efficient approximate leave-one-out cross-validation (LOO) for posterior approximations} \usage{ loo_approximate_posterior(x, log_p, log_g, ...) \method{loo_approximate_posterior}{array}( x, log_p, log_g, ..., save_psis = FALSE, cores = getOption("mc.cores", 1) ) \method{loo_approximate_posterior}{matrix}( x, log_p, log_g, ..., save_psis = FALSE, cores = getOption("mc.cores", 1) ) \method{loo_approximate_posterior}{`function`}( x, ..., data = NULL, draws = NULL, log_p = NULL, log_g = NULL, save_psis = FALSE, cores = getOption("mc.cores", 1) ) } \arguments{ \item{x}{A log-likelihood array, matrix, or function. The \strong{Methods (by class)} section, below, has detailed descriptions of how to specify the inputs for each method.} \item{log_p}{The log-posterior (target) evaluated at S samples from the proposal distribution (g). A vector of length S.} \item{log_g}{The log-density (proposal) evaluated at S samples from the proposal distribution (g). A vector of length S.} \item{save_psis}{Should the \code{"psis"} object created internally by \code{loo_approximate_posterior()} be saved in the returned object? See \code{\link[=loo]{loo()}} for details.} \item{cores}{The number of cores to use for parallelization. This defaults to the option \code{mc.cores} which can be set for an entire R session by \code{options(mc.cores = NUMBER)}. The old option \code{loo.cores} is now deprecated but will be given precedence over \code{mc.cores} until \code{loo.cores} is removed in a future release. \strong{As of version 2.0.0 the default is now 1 core if \code{mc.cores} is not set}, but we recommend using as many (or close to as many) cores as possible. \itemize{ \item Note for Windows 10 users: it is \strong{strongly} \href{https://github.com/stan-dev/loo/issues/94}{recommended} to avoid using the \code{.Rprofile} file to set \code{mc.cores} (using the \code{cores} argument or setting \code{mc.cores} interactively or in a script is fine). }} \item{data, draws, ...}{For the \code{loo_approximate_posterior.function()} method, these are the data, posterior draws, and other arguments to pass to the log-likelihood function. See the \strong{Methods (by class)} section below for details on how to specify these arguments.} } \value{ The \code{loo_approximate_posterior()} methods return a named list with class \code{c("psis_loo_ap", "psis_loo", "loo")}. It has the same structure as the objects returned by \code{\link[=loo]{loo()}} but with the additional slot: \describe{ \item{\code{posterior_approximation}}{ A list with two vectors, \code{log_p} and \code{log_g} of the same length containing the posterior density and the approximation density for the individual draws. } } } \description{ Efficient approximate leave-one-out cross-validation (LOO) for posterior approximations } \details{ The \code{loo_approximate_posterior()} function is an S3 generic and methods are provided for 3-D pointwise log-likelihood arrays, pointwise log-likelihood matrices, and log-likelihood functions. The implementation works for posterior approximations where it is possible to compute the log density for the posterior approximation. } \section{Methods (by class)}{ \itemize{ \item \code{loo_approximate_posterior(array)}: An \eqn{I} by \eqn{C} by \eqn{N} array, where \eqn{I} is the number of MCMC iterations per chain, \eqn{C} is the number of chains, and \eqn{N} is the number of data points. \item \code{loo_approximate_posterior(matrix)}: An \eqn{S} by \eqn{N} matrix, where \eqn{S} is the size of the posterior sample (with all chains merged) and \eqn{N} is the number of data points. \item \code{loo_approximate_posterior(`function`)}: A function \code{f()} that takes arguments \code{data_i} and \code{draws} and returns a vector containing the log-likelihood for a single observation \code{i} evaluated at each posterior draw. The function should be written such that, for each observation \code{i} in \code{1:N}, evaluating \if{html}{\out{
}}\preformatted{f(data_i = data[i,, drop=FALSE], draws = draws) }\if{html}{\out{
}} results in a vector of length \code{S} (size of posterior sample). The log-likelihood function can also have additional arguments but \code{data_i} and \code{draws} are required. If using the function method then the arguments \code{data} and \code{draws} must also be specified in the call to \code{loo()}: \itemize{ \item \code{data}: A data frame or matrix containing the data (e.g. observed outcome and predictors) needed to compute the pointwise log-likelihood. For each observation \code{i}, the \code{i}th row of \code{data} will be passed to the \code{data_i} argument of the log-likelihood function. \item \code{draws}: An object containing the posterior draws for any parameters needed to compute the pointwise log-likelihood. Unlike \code{data}, which is indexed by observation, for each observation the entire object \code{draws} will be passed to the \code{draws} argument of the log-likelihood function. \item The \code{...} can be used if your log-likelihood function takes additional arguments. These arguments are used like the \code{draws} argument in that they are recycled for each observation. } }} \references{ Magnusson, M., Riis Andersen, M., Jonasson, J. and Vehtari, A. (2019). Leave-One-Out Cross-Validation for Large Data. In \emph{International Conference on Machine Learning} Magnusson, M., Riis Andersen, M., Jonasson, J. and Vehtari, A. (2020). Leave-One-Out Cross-Validation for Model Comparison in Large Data. In \emph{International Conference on Artificial Intelligence and Statistics (AISTATS)} } \seealso{ \code{\link[=loo]{loo()}}, \code{\link[=psis]{psis()}}, \code{\link[=loo_compare]{loo_compare()}} } loo/man/dot-ndraws.Rd0000644000176200001440000000121313575772017014202 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/loo_subsample.R \name{.ndraws} \alias{.ndraws} \title{The number of posterior draws in a draws object.} \usage{ .ndraws(x) } \arguments{ \item{x}{A draws object with posterior draws.} } \value{ An integer with the number of draws. } \description{ The number of posterior draws in a draws object. } \details{ This is a generic function to return the total number of draws from an arbitrary draws objects. The function is internal and should only be used by developers to enable \code{\link[=loo_subsample]{loo_subsample()}} for arbitrary draws objects. } \keyword{internal} loo/man/psis.Rd0000644000176200001440000001405214407123455013072 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/psis.R, R/sis.R, R/tis.R \name{psis} \alias{psis} \alias{psis.array} \alias{psis.matrix} \alias{psis.default} \alias{is.psis} \alias{is.sis} \alias{is.tis} \title{Pareto smoothed importance sampling (PSIS)} \usage{ psis(log_ratios, ...) \method{psis}{array}(log_ratios, ..., r_eff = NULL, cores = getOption("mc.cores", 1)) \method{psis}{matrix}(log_ratios, ..., r_eff = NULL, cores = getOption("mc.cores", 1)) \method{psis}{default}(log_ratios, ..., r_eff = NULL) is.psis(x) is.sis(x) is.tis(x) } \arguments{ \item{log_ratios}{An array, matrix, or vector of importance ratios on the log scale (for PSIS-LOO these are \emph{negative} log-likelihood values). See the \strong{Methods (by class)} section below for a detailed description of how to specify the inputs for each method.} \item{...}{Arguments passed on to the various methods.} \item{r_eff}{Vector of relative effective sample size estimates containing one element per observation. The values provided should be the relative effective sample sizes of \code{1/exp(log_ratios)} (i.e., \code{1/ratios}). This is related to the relative efficiency of estimating the normalizing term in self-normalizing importance sampling. If \code{r_eff} is not provided then the reported PSIS effective sample sizes and Monte Carlo error estimates will be over-optimistic. See the \code{\link[=relative_eff]{relative_eff()}} helper function for computing \code{r_eff}. If using \code{psis} with draws of the \code{log_ratios} not obtained from MCMC then the warning message thrown when not specifying \code{r_eff} can be disabled by setting \code{r_eff} to \code{NA}.} \item{cores}{The number of cores to use for parallelization. This defaults to the option \code{mc.cores} which can be set for an entire R session by \code{options(mc.cores = NUMBER)}. The old option \code{loo.cores} is now deprecated but will be given precedence over \code{mc.cores} until \code{loo.cores} is removed in a future release. \strong{As of version 2.0.0 the default is now 1 core if \code{mc.cores} is not set}, but we recommend using as many (or close to as many) cores as possible. \itemize{ \item Note for Windows 10 users: it is \strong{strongly} \href{https://github.com/stan-dev/loo/issues/94}{recommended} to avoid using the \code{.Rprofile} file to set \code{mc.cores} (using the \code{cores} argument or setting \code{mc.cores} interactively or in a script is fine). }} \item{x}{For \code{is.psis()}, an object to check.} } \value{ The \code{psis()} methods return an object of class \code{"psis"}, which is a named list with the following components: \describe{ \item{\code{log_weights}}{ Vector or matrix of smoothed (and truncated) but \emph{unnormalized} log weights. To get normalized weights use the \code{\link[=weights.importance_sampling]{weights()}} method provided for objects of class \code{"psis"}. } \item{\code{diagnostics}}{ A named list containing two vectors: \itemize{ \item \code{pareto_k}: Estimates of the shape parameter \eqn{k} of the generalized Pareto distribution. See the \link{pareto-k-diagnostic} page for details. \item \code{n_eff}: PSIS effective sample size estimates. } } } Objects of class \code{"psis"} also have the following \link[=attributes]{attributes}: \describe{ \item{\code{norm_const_log}}{ Vector of precomputed values of \code{colLogSumExps(log_weights)} that are used internally by the \code{weights} method to normalize the log weights. } \item{\code{tail_len}}{ Vector of tail lengths used for fitting the generalized Pareto distribution. } \item{\code{r_eff}}{ If specified, the user's \code{r_eff} argument. } \item{\code{dims}}{ Integer vector of length 2 containing \code{S} (posterior sample size) and \code{N} (number of observations). } \item{\code{method}}{ Method used for importance sampling, here \code{psis}. } } } \description{ Implementation of Pareto smoothed importance sampling (PSIS), a method for stabilizing importance ratios. The version of PSIS implemented here corresponds to the algorithm presented in Vehtari, Simpson, Gelman, Yao, and Gabry (2019). For PSIS diagnostics see the \link{pareto-k-diagnostic} page. } \section{Methods (by class)}{ \itemize{ \item \code{psis(array)}: An \eqn{I} by \eqn{C} by \eqn{N} array, where \eqn{I} is the number of MCMC iterations per chain, \eqn{C} is the number of chains, and \eqn{N} is the number of data points. \item \code{psis(matrix)}: An \eqn{S} by \eqn{N} matrix, where \eqn{S} is the size of the posterior sample (with all chains merged) and \eqn{N} is the number of data points. \item \code{psis(default)}: A vector of length \eqn{S} (posterior sample size). }} \examples{ log_ratios <- -1 * example_loglik_array() r_eff <- relative_eff(exp(-log_ratios)) psis_result <- psis(log_ratios, r_eff = r_eff) str(psis_result) plot(psis_result) # extract smoothed weights lw <- weights(psis_result) # default args are log=TRUE, normalize=TRUE ulw <- weights(psis_result, normalize=FALSE) # unnormalized log-weights w <- weights(psis_result, log=FALSE) # normalized weights (not log-weights) uw <- weights(psis_result, log=FALSE, normalize = FALSE) # unnormalized weights } \references{ Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. \emph{Statistics and Computing}. 27(5), 1413--1432. doi:10.1007/s11222-016-9696-4 (\href{https://link.springer.com/article/10.1007/s11222-016-9696-4}{journal version}, \href{https://arxiv.org/abs/1507.04544}{preprint arXiv:1507.04544}). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. \href{https://arxiv.org/abs/1507.02646}{preprint arXiv:1507.02646} } \seealso{ \itemize{ \item \code{\link[=loo]{loo()}} for approximate LOO-CV using PSIS. \item \link{pareto-k-diagnostic} for PSIS diagnostics. \item The \strong{loo} package \href{https://mc-stan.org/loo/articles/index.html}{vignettes} for demonstrations. \item The \href{https://mc-stan.org/loo/articles/online-only/faq.html}{FAQ page} on the \strong{loo} website for answers to frequently asked questions. } } loo/man/extract_log_lik.Rd0000644000176200001440000000461313762013700015262 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/extract_log_lik.R \name{extract_log_lik} \alias{extract_log_lik} \title{Extract pointwise log-likelihood from a Stan model} \usage{ extract_log_lik(stanfit, parameter_name = "log_lik", merge_chains = TRUE) } \arguments{ \item{stanfit}{A \code{stanfit} object (\pkg{rstan} package).} \item{parameter_name}{A character string naming the parameter (or generated quantity) in the Stan model corresponding to the log-likelihood.} \item{merge_chains}{If \code{TRUE} (the default), all Markov chains are merged together (i.e., stacked) and a matrix is returned. If \code{FALSE} they are kept separate and an array is returned.} } \value{ If \code{merge_chains=TRUE}, an \eqn{S} by \eqn{N} matrix of (post-warmup) extracted draws, where \eqn{S} is the size of the posterior sample and \eqn{N} is the number of data points. If \code{merge_chains=FALSE}, an \eqn{I} by \eqn{C} by \eqn{N} array, where \eqn{I \times C = S}{I * C = S}. } \description{ Convenience function for extracting the pointwise log-likelihood matrix or array from a \code{stanfit} object from the \pkg{rstan} package. Note: recent versions of \pkg{rstan} now include a \code{loo()} method for \code{stanfit} objects that handles this internally. } \details{ Stan does not automatically compute and store the log-likelihood. It is up to the user to incorporate it into the Stan program if it is to be extracted after fitting the model. In a Stan model, the pointwise log likelihood can be coded as a vector in the transformed parameters block (and then summed up in the model block) or it can be coded entirely in the generated quantities block. We recommend using the generated quantities block so that the computations are carried out only once per iteration rather than once per HMC leapfrog step. For example, the following is the \verb{generated quantities} block for computing and saving the log-likelihood for a linear regression model with \code{N} data points, outcome \code{y}, predictor matrix \code{X}, coefficients \code{beta}, and standard deviation \code{sigma}: \verb{vector[N] log_lik;} \code{for (n in 1:N) log_lik[n] = normal_lpdf(y[n] | X[n, ] * beta, sigma);} } \references{ Stan Development Team (2017). The Stan C++ Library, Version 2.16.0. \url{https://mc-stan.org/} Stan Development Team (2017). RStan: the R interface to Stan, Version 2.16.1. \url{https://mc-stan.org/} } loo/man/loo_model_weights.Rd0000644000176200001440000002311514410420140015600 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/loo_model_weights.R \name{loo_model_weights} \alias{loo_model_weights} \alias{loo_model_weights.default} \alias{stacking_weights} \alias{pseudobma_weights} \title{Model averaging/weighting via stacking or pseudo-BMA weighting} \usage{ loo_model_weights(x, ...) \method{loo_model_weights}{default}( x, ..., method = c("stacking", "pseudobma"), optim_method = "BFGS", optim_control = list(), BB = TRUE, BB_n = 1000, alpha = 1, r_eff_list = NULL, cores = getOption("mc.cores", 1) ) stacking_weights(lpd_point, optim_method = "BFGS", optim_control = list()) pseudobma_weights(lpd_point, BB = TRUE, BB_n = 1000, alpha = 1) } \arguments{ \item{x}{A list of \code{"psis_loo"} objects (objects returned by \code{\link[=loo]{loo()}}) or pointwise log-likelihood matrices or , one for each model. If the list elements are named the names will be used to label the models in the results. Each matrix/object should have dimensions \eqn{S} by \eqn{N}, where \eqn{S} is the size of the posterior sample (with all chains merged) and \eqn{N} is the number of data points. If \code{x} is a list of log-likelihood matrices then \code{\link[=loo]{loo()}} is called internally on each matrix. Currently the \code{loo_model_weights()} function is not implemented to be used with results from K-fold CV, but you can still obtain weights using K-fold CV results by calling the \code{stacking_weights()} function directly.} \item{...}{Unused, except for the generic to pass arguments to individual methods.} \item{method}{Either \code{"stacking"} (the default) or \code{"pseudobma"}, indicating which method to use for obtaining the weights. \code{"stacking"} refers to stacking of predictive distributions and \code{"pseudobma"} refers to pseudo-BMA+ weighting (or plain pseudo-BMA weighting if argument \code{BB} is \code{FALSE}).} \item{optim_method}{If \code{method="stacking"}, a string passed to the \code{method} argument of \code{\link[stats:constrOptim]{stats::constrOptim()}} to specify the optimization algorithm. The default is \code{optim_method="BFGS"}, but other options are available (see \code{\link[stats:optim]{stats::optim()}}).} \item{optim_control}{If \code{method="stacking"}, a list of control parameters for optimization passed to the \code{control} argument of \code{\link[stats:constrOptim]{stats::constrOptim()}}.} \item{BB}{Logical used when \code{"method"}=\code{"pseudobma"}. If \code{TRUE} (the default), the Bayesian bootstrap will be used to adjust the pseudo-BMA weighting, which is called pseudo-BMA+ weighting. It helps regularize the weight away from 0 and 1, so as to reduce the variance.} \item{BB_n}{For pseudo-BMA+ weighting only, the number of samples to use for the Bayesian bootstrap. The default is \code{BB_n=1000}.} \item{alpha}{Positive scalar shape parameter in the Dirichlet distribution used for the Bayesian bootstrap. The default is \code{alpha=1}, which corresponds to a uniform distribution on the simplex space.} \item{r_eff_list}{Optionally, a list of relative effective sample size estimates for the likelihood \code{(exp(log_lik))} of each observation in each model. See \code{\link[=psis]{psis()}} and \code{\link[=relative_eff]{relative_eff()}} helper function for computing \code{r_eff}. If \code{x} is a list of \code{"psis_loo"} objects then \code{r_eff_list} is ignored.} \item{cores}{The number of cores to use for parallelization. This defaults to the option \code{mc.cores} which can be set for an entire R session by \code{options(mc.cores = NUMBER)}. The old option \code{loo.cores} is now deprecated but will be given precedence over \code{mc.cores} until \code{loo.cores} is removed in a future release. \strong{As of version 2.0.0 the default is now 1 core if \code{mc.cores} is not set}, but we recommend using as many (or close to as many) cores as possible. \itemize{ \item Note for Windows 10 users: it is \strong{strongly} \href{https://github.com/stan-dev/loo/issues/94}{recommended} to avoid using the \code{.Rprofile} file to set \code{mc.cores} (using the \code{cores} argument or setting \code{mc.cores} interactively or in a script is fine). }} \item{lpd_point}{If calling \code{stacking_weights()} or \code{pseudobma_weights()} directly, a matrix of pointwise leave-one-out (or K-fold) log likelihoods evaluated for different models. It should be a \eqn{N} by \eqn{K} matrix where \eqn{N} is sample size and \eqn{K} is the number of models. Each column corresponds to one model. These values can be calculated approximately using \code{\link[=loo]{loo()}} or by running exact leave-one-out or K-fold cross-validation.} } \value{ A numeric vector containing one weight for each model. } \description{ Model averaging via stacking of predictive distributions, pseudo-BMA weighting or pseudo-BMA+ weighting with the Bayesian bootstrap. See Yao et al. (2018), Vehtari, Gelman, and Gabry (2017), and Vehtari, Simpson, Gelman, Yao, and Gabry (2019) for background. } \details{ \code{loo_model_weights()} is a wrapper around the \code{stacking_weights()} and \code{pseudobma_weights()} functions that implements stacking, pseudo-BMA, and pseudo-BMA+ weighting for combining multiple predictive distributions. We can use approximate or exact leave-one-out cross-validation (LOO-CV) or K-fold CV to estimate the expected log predictive density (ELPD). The stacking method (\code{method="stacking"}), which is the default for \code{loo_model_weights()}, combines all models by maximizing the leave-one-out predictive density of the combination distribution. That is, it finds the optimal linear combining weights for maximizing the leave-one-out log score. The pseudo-BMA method (\code{method="pseudobma"}) finds the relative weights proportional to the ELPD of each model. However, when \code{method="pseudobma"}, the default is to also use the Bayesian bootstrap (\code{BB=TRUE}), which corresponds to the pseudo-BMA+ method. The Bayesian bootstrap takes into account the uncertainty of finite data points and regularizes the weights away from the extremes of 0 and 1. In general, we recommend stacking for averaging predictive distributions, while pseudo-BMA+ can serve as a computationally easier alternative. } \examples{ \dontrun{ ### Demonstrating usage after fitting models with RStan library(rstan) # generate fake data from N(0,1). N <- 100 y <- rnorm(N, 0, 1) # Suppose we have three models: N(-1, sigma), N(0.5, sigma) and N(0.6,sigma). stan_code <- " data { int N; vector[N] y; real mu_fixed; } parameters { real sigma; } model { sigma ~ exponential(1); y ~ normal(mu_fixed, sigma); } generated quantities { vector[N] log_lik; for (n in 1:N) log_lik[n] = normal_lpdf(y[n]| mu_fixed, sigma); }" mod <- stan_model(model_code = stan_code) fit1 <- sampling(mod, data=list(N=N, y=y, mu_fixed=-1)) fit2 <- sampling(mod, data=list(N=N, y=y, mu_fixed=0.5)) fit3 <- sampling(mod, data=list(N=N, y=y, mu_fixed=0.6)) model_list <- list(fit1, fit2, fit3) log_lik_list <- lapply(model_list, extract_log_lik) # optional but recommended r_eff_list <- lapply(model_list, function(x) { ll_array <- extract_log_lik(x, merge_chains = FALSE) relative_eff(exp(ll_array)) }) # stacking method: wts1 <- loo_model_weights( log_lik_list, method = "stacking", r_eff_list = r_eff_list, optim_control = list(reltol=1e-10) ) print(wts1) # can also pass a list of psis_loo objects to avoid recomputing loo loo_list <- lapply(1:length(log_lik_list), function(j) { loo(log_lik_list[[j]], r_eff = r_eff_list[[j]]) }) wts2 <- loo_model_weights( loo_list, method = "stacking", optim_control = list(reltol=1e-10) ) all.equal(wts1, wts2) # can provide names to be used in the results loo_model_weights(setNames(loo_list, c("A", "B", "C"))) # pseudo-BMA+ method: set.seed(1414) loo_model_weights(loo_list, method = "pseudobma") # pseudo-BMA method (set BB = FALSE): loo_model_weights(loo_list, method = "pseudobma", BB = FALSE) # calling stacking_weights or pseudobma_weights directly lpd1 <- loo(log_lik_list[[1]], r_eff = r_eff_list[[1]])$pointwise[,1] lpd2 <- loo(log_lik_list[[2]], r_eff = r_eff_list[[2]])$pointwise[,1] lpd3 <- loo(log_lik_list[[3]], r_eff = r_eff_list[[3]])$pointwise[,1] stacking_weights(cbind(lpd1, lpd2, lpd3)) pseudobma_weights(cbind(lpd1, lpd2, lpd3)) pseudobma_weights(cbind(lpd1, lpd2, lpd3), BB = FALSE) } } \references{ Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. \emph{Statistics and Computing}. 27(5), 1413--1432. doi:10.1007/s11222-016-9696-4 (\href{https://link.springer.com/article/10.1007/s11222-016-9696-4}{journal version}, \href{https://arxiv.org/abs/1507.04544}{preprint arXiv:1507.04544}). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. \href{https://arxiv.org/abs/1507.02646}{preprint arXiv:1507.02646} Yao, Y., Vehtari, A., Simpson, D., and Gelman, A. (2018) Using stacking to average Bayesian predictive distributions. \emph{Bayesian Analysis}, advance publication, doi:10.1214/17-BA1091. (\href{https://projecteuclid.org/euclid.ba/1516093227}{online}). } \seealso{ \itemize{ \item The \strong{loo} package \href{https://mc-stan.org/loo/articles/}{vignettes}, particularly \href{https://mc-stan.org/loo/articles/loo2-weights.html}{Bayesian Stacking and Pseudo-BMA weights using the \strong{loo} package}. \item \code{\link[=loo]{loo()}} for details on leave-one-out ELPD estimation. \item \code{\link[=constrOptim]{constrOptim()}} for the choice of optimization methods and control-parameters. \item \code{\link[=relative_eff]{relative_eff()}} for computing \code{r_eff}. } } loo/man/compare.Rd0000644000176200001440000000645014407123455013545 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/compare.R \name{compare} \alias{compare} \title{Model comparison (deprecated, old version)} \usage{ compare(..., x = list()) } \arguments{ \item{...}{At least two objects returned by \code{\link[=loo]{loo()}} (or \code{\link[=waic]{waic()}}).} \item{x}{A list of at least two objects returned by \code{\link[=loo]{loo()}} (or \code{\link[=waic]{waic()}}). This argument can be used as an alternative to specifying the objects in \code{...}.} } \value{ A vector or matrix with class \code{'compare.loo'} that has its own print method. If exactly two objects are provided in \code{...} or \code{x}, then the difference in expected predictive accuracy and the standard error of the difference are returned. If more than two objects are provided then a matrix of summary information is returned (see \strong{Details}). } \description{ \strong{This function is deprecated}. Please use the new \code{\link[=loo_compare]{loo_compare()}} function instead. } \details{ When comparing two fitted models, we can estimate the difference in their expected predictive accuracy by the difference in \code{elpd_loo} or \code{elpd_waic} (or multiplied by -2, if desired, to be on the deviance scale). \emph{When that difference, \code{elpd_diff}, is positive then the expected predictive accuracy for the second model is higher. A negative \code{elpd_diff} favors the first model.} When using \code{compare()} with more than two models, the values in the \code{elpd_diff} and \code{se_diff} columns of the returned matrix are computed by making pairwise comparisons between each model and the model with the best ELPD (i.e., the model in the first row). Although the \code{elpd_diff} column is equal to the difference in \code{elpd_loo}, do not expect the \code{se_diff} column to be equal to the the difference in \code{se_elpd_loo}. To compute the standard error of the difference in ELPD we use a paired estimate to take advantage of the fact that the same set of \emph{N} data points was used to fit both models. These calculations should be most useful when \emph{N} is large, because then non-normality of the distribution is not such an issue when estimating the uncertainty in these sums. These standard errors, for all their flaws, should give a better sense of uncertainty than what is obtained using the current standard approach of comparing differences of deviances to a Chi-squared distribution, a practice derived for Gaussian linear models or asymptotically, and which only applies to nested models in any case. } \examples{ \dontrun{ loo1 <- loo(log_lik1) loo2 <- loo(log_lik2) print(compare(loo1, loo2), digits = 3) print(compare(x = list(loo1, loo2))) waic1 <- waic(log_lik1) waic2 <- waic(log_lik2) compare(waic1, waic2) } } \references{ Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. \emph{Statistics and Computing}. 27(5), 1413--1432. doi:10.1007/s11222-016-9696-4 (\href{https://link.springer.com/article/10.1007/s11222-016-9696-4}{journal version}, \href{https://arxiv.org/abs/1507.04544}{preprint arXiv:1507.04544}). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. \href{https://arxiv.org/abs/1507.02646}{preprint arXiv:1507.02646} } loo/man/loo_predictive_metric.Rd0000644000176200001440000000660114411130104016447 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/loo_predictive_metric.R \name{loo_predictive_metric} \alias{loo_predictive_metric} \alias{loo_predictive_metric.matrix} \title{Estimate leave-one-out predictive performance..} \usage{ loo_predictive_metric(x, ...) \method{loo_predictive_metric}{matrix}( x, y, log_lik, ..., metric = c("mae", "rmse", "mse", "acc", "balanced_acc"), r_eff = NULL, cores = getOption("mc.cores", 1) ) } \arguments{ \item{x}{A numeric matrix of predictions.} \item{...}{Additional arguments passed on to \code{\link[=E_loo]{E_loo()}}} \item{y}{A numeric vector of observations. Length should be equal to the number of rows in \code{x}.} \item{log_lik}{A matrix of pointwise log-likelihoods. Should be of same dimension as \code{x}.} \item{metric}{The type of predictive metric to be used. Currently supported options are \code{"mae"}, \code{"rmse"} and \code{"mse"} for regression and for binary classification \code{"acc"} and \code{"balanced_acc"}. \describe{ \item{\code{"mae"}}{ Mean absolute error. } \item{\code{"mse"}}{ Mean squared error. } \item{\code{"rmse"}}{ Root mean squared error, given by as the square root of \code{MSE}. } \item{\code{"acc"}}{ The proportion of predictions indicating the correct outcome. } \item{\code{"balanced_acc"}}{ Balanced accuracy is given by the average of true positive and true negative rates. } }} \item{r_eff}{A Vector of relative effective sample size estimates containing one element per observation. See \code{\link[=psis]{psis()}} for more details.} \item{cores}{The number of cores to use for parallelization of \verb{[psis()]}. See \code{\link[=psis]{psis()}} for details.} } \value{ A list with the following components: \describe{ \item{\code{estimate}}{ Estimate of the given metric. } \item{\code{se}}{ Standard error of the estimate. } } } \description{ The \code{loo_predictive_metric()} function computes estimates of leave-one-out predictive metrics given a set of predictions and observations. Currently supported metrics are mean absolute error, mean squared error and root mean squared error for continuous predictions and accuracy and balanced accuracy for binary classification. Predictions are passed on to the \code{\link[=E_loo]{E_loo()}} function, so this function assumes that the PSIS approximation is working well. } \examples{ \donttest{ if (requireNamespace("rstanarm", quietly = TRUE)) { # Use rstanarm package to quickly fit a model and get both a log-likelihood # matrix and draws from the posterior predictive distribution library("rstanarm") # data from help("lm") ctl <- c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14) trt <- c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69) d <- data.frame( weight = c(ctl, trt), group = gl(2, 10, 20, labels = c("Ctl","Trt")) ) fit <- stan_glm(weight ~ group, data = d, refresh = 0) ll <- log_lik(fit) r_eff <- relative_eff(exp(-ll), chain_id = rep(1:4, each = 1000)) mu_pred <- posterior_epred(fit) # Leave-one-out mean absolute error of predictions mae <- loo_predictive_metric(x = mu_pred, y = d$weight, log_lik = ll, pred_error = 'mae', r_eff = r_eff) # Leave-one-out 90\%-quantile of mean absolute error mae_90q <- loo_predictive_metric(x = mu_pred, y = d$weight, log_lik = ll, pred_error = 'mae', r_eff = r_eff, type = 'quantile', probs = 0.9) } } } loo/man/psis_approximate_posterior.Rd0000644000176200001440000000624114407123455017612 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/psis_approximate_posterior.R \name{psis_approximate_posterior} \alias{psis_approximate_posterior} \title{Diagnostics for Laplace and ADVI approximations and Laplace-loo and ADVI-loo} \usage{ psis_approximate_posterior( log_p = NULL, log_g = NULL, log_liks = NULL, cores, save_psis, ..., log_q = NULL ) } \arguments{ \item{log_p}{The log-posterior (target) evaluated at S samples from the proposal distribution (g). A vector of length S.} \item{log_g}{The log-density (proposal) evaluated at S samples from the proposal distribution (g). A vector of length S.} \item{log_liks}{A log-likelihood matrix of size S * N, where N is the number of observations and S is the number of samples from q. See \code{\link[=loo.matrix]{loo.matrix()}} for details. Default is \code{NULL}. Then only the posterior is evaluated using the k_hat diagnostic.} \item{cores}{The number of cores to use for parallelization. This defaults to the option \code{mc.cores} which can be set for an entire R session by \code{options(mc.cores = NUMBER)}. The old option \code{loo.cores} is now deprecated but will be given precedence over \code{mc.cores} until \code{loo.cores} is removed in a future release. \strong{As of version 2.0.0 the default is now 1 core if \code{mc.cores} is not set}, but we recommend using as many (or close to as many) cores as possible. \itemize{ \item Note for Windows 10 users: it is \strong{strongly} \href{https://github.com/stan-dev/loo/issues/94}{recommended} to avoid using the \code{.Rprofile} file to set \code{mc.cores} (using the \code{cores} argument or setting \code{mc.cores} interactively or in a script is fine). }} \item{save_psis}{Should the \code{"psis"} object created internally by \code{loo()} be saved in the returned object? The \code{loo()} function calls \code{\link[=psis]{psis()}} internally but by default discards the (potentially large) \code{"psis"} object after using it to compute the LOO-CV summaries. Setting \code{save_psis=TRUE} will add a \code{psis_object} component to the list returned by \code{loo}. Currently this is only needed if you plan to use the \code{\link[=E_loo]{E_loo()}} function to compute weighted expectations after running \code{loo}.} \item{log_q}{Deprecated argument name (the same as log_g).} } \value{ If log likelihoods are supplied, the function returns a \code{"loo"} object, otherwise the function returns a \code{"psis"} object. } \description{ Diagnostics for Laplace and ADVI approximations and Laplace-loo and ADVI-loo } \references{ Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. \emph{Statistics and Computing}. 27(5), 1413--1432. doi:10.1007/s11222-016-9696-4 (\href{https://link.springer.com/article/10.1007/s11222-016-9696-4}{journal version}, \href{https://arxiv.org/abs/1507.04544}{preprint arXiv:1507.04544}). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. \href{https://arxiv.org/abs/1507.02646}{preprint arXiv:1507.02646} } \seealso{ \code{\link[=loo]{loo()}} and \code{\link[=psis]{psis()}} } \keyword{internal} loo/DESCRIPTION0000644000176200001440000000471614411522703012560 0ustar liggesusersPackage: loo Type: Package Title: Efficient Leave-One-Out Cross-Validation and WAIC for Bayesian Models Version: 2.6.0 Date: 2023-03-30 Authors@R: c(person("Aki", "Vehtari", email = "Aki.Vehtari@aalto.fi", role = c("aut")), person("Jonah", "Gabry", email = "jsg2201@columbia.edu", role = c("cre", "aut")), person("Mans", "Magnusson", role = c("aut")), person("Yuling", "Yao", role = c("aut")), person("Paul-Christian", "Bürkner", role = c("aut")), person("Topi", "Paananen", role = c("aut")), person("Andrew", "Gelman", role = c("aut")), person("Ben", "Goodrich", role = c("ctb")), person("Juho", "Piironen", role = c("ctb")), person("Bruno", "Nicenboim", role = c("ctb")), person("Leevi", "Lindgren", role = c("ctb"))) Maintainer: Jonah Gabry URL: https://mc-stan.org/loo/, https://discourse.mc-stan.org BugReports: https://github.com/stan-dev/loo/issues Description: Efficient approximate leave-one-out cross-validation (LOO) for Bayesian models fit using Markov chain Monte Carlo, as described in Vehtari, Gelman, and Gabry (2017) . The approximation uses Pareto smoothed importance sampling (PSIS), a new procedure for regularizing importance weights. As a byproduct of the calculations, we also obtain approximate standard errors for estimated predictive errors and for the comparison of predictive errors between models. The package also provides methods for using stacking and other model weighting techniques to average Bayesian predictive distributions. License: GPL (>= 3) LazyData: TRUE Depends: R (>= 3.1.2) Imports: checkmate, matrixStats (>= 0.52), parallel, stats Suggests: bayesplot (>= 1.7.0), brms (>= 2.10.0), ggplot2, graphics, knitr, posterior, rmarkdown, rstan, rstanarm (>= 2.19.0), rstantools, spdep, testthat (>= 2.1.0) VignetteBuilder: knitr Encoding: UTF-8 SystemRequirements: pandoc (>= 1.12.3), pandoc-citeproc RoxygenNote: 7.2.3 NeedsCompilation: no Packaged: 2023-03-31 05:10:34 UTC; jgabry Author: Aki Vehtari [aut], Jonah Gabry [cre, aut], Mans Magnusson [aut], Yuling Yao [aut], Paul-Christian Bürkner [aut], Topi Paananen [aut], Andrew Gelman [aut], Ben Goodrich [ctb], Juho Piironen [ctb], Bruno Nicenboim [ctb], Leevi Lindgren [ctb] Repository: CRAN Date/Publication: 2023-03-31 09:20:03 UTC loo/build/0000755000176200001440000000000014411465510012143 5ustar liggesusersloo/build/vignette.rds0000644000176200001440000000112314411465510014477 0ustar liggesusersTMs0u@JQn:rqk:LCUccMe#)ĿFXr"աpAvQQ?|ǵqEѐKy/e\вTM ɨra{+قi=lPY0IIMZ01R$9MTt́M ;҆ K|\ۂ9پafѻ:;w[m A"kRwhWQl+r뾢S*j=Truloo/build/partial.rdb0000644000176200001440000000007514411455165014277 0ustar liggesusersb```b`abb`b1 H020piּb C".X7loo/tests/0000755000176200001440000000000014407123455012212 5ustar liggesusersloo/tests/testthat/0000755000176200001440000000000014411522703014044 5ustar liggesusersloo/tests/testthat/test_relative_eff.R0000644000176200001440000000314714411130104017654 0ustar liggesuserslibrary(loo) options(mc.cores = 1) set.seed(123) context("relative_eff methods") LLarr <- example_loglik_array() LLmat <- example_loglik_matrix() test_that("relative_eff results haven't changed", { expect_equal_to_reference(relative_eff(exp(LLarr)), "reference-results/relative_eff.rds") }) test_that("relative_eff is equal to ESS / S", { dims <- dim(LLarr) ess <- r_eff <- rep(NA, dims[3]) for (j in 1:dims[3]) { r_eff[j] <- relative_eff(LLarr[,,1, drop=FALSE]) ess[j] <- ess_rfun(LLarr[,,1]) } S <- prod(dim(LLarr)[1:2]) expect_equal(r_eff, ess / S) }) test_that("relative_eff array and matrix methods return identical output", { r_eff_arr <- relative_eff(exp(LLarr)) r_eff_mat <- relative_eff(exp(LLmat), chain_id = rep(1:2, each = nrow(LLarr))) expect_identical(r_eff_arr, r_eff_mat) }) test_that("relative_eff matrix and function methods return identical output", { source(test_path("data-for-tests/function_method_stuff.R")) chain <- rep(1, nrow(draws)) r_eff_mat <- relative_eff(llmat_from_fn, chain_id = chain) r_eff_fn <- relative_eff(llfun, chain_id = chain, data = data, draws = draws, cores = 1) expect_identical(r_eff_mat, r_eff_fn) }) test_that("relative_eff with multiple cores runs", { skip_on_cran() source(test_path("data-for-tests/function_method_stuff.R")) dim(llmat_from_fn) <- c(nrow(llmat_from_fn), 1, ncol(llmat_from_fn)) r_eff_arr <- relative_eff(llmat_from_fn, cores = 2) r_eff_fn <- relative_eff( llfun, chain_id = rep(1, nrow(draws)), data = data, draws = draws, cores = 2 ) expect_identical(r_eff_arr, r_eff_fn) }) loo/tests/testthat/test_loo_approximate_posterior.R0000644000176200001440000001031113576706411022545 0ustar liggesuserssuppressPackageStartupMessages(library(loo)) context("loo_approximate_posterior") # Create test data # Checked by Mans M and Paul B 24th of June 2019 set.seed(123) N <- 50 K <- 10 S <- 1000 a0 <- 1 b0 <- 1 p <- 0.5 y <- rbinom(N, size = K, prob = p) fake_data <- data.frame(y,K) # The log posterior log_post <- function(p, y, a0, b0, K) { log_lik <- sum(dbinom(x = y, size = K, prob = p, log = TRUE)) # the log likelihood log_post <- log_lik + dbeta(x = p, shape1 = a0, shape2 = b0, log = TRUE) # the log prior log_post } it <- optim(par = 0.5, fn = log_post, control = list(fnscale = -1), hessian = TRUE, y = y, a0 = a0, b0 = b0, K = K, lower = 0.01, upper = 0.99, method = "Brent") lap_params <- c(mu = it$par, sd = sqrt(solve(-it$hessian))) a <- a0 + sum(y) b <- b0 + N * K - sum(y) fake_true_posterior <- as.matrix(rbeta(S, a, b)) fake_laplace_posterior <- as.matrix(rnorm(n = S, mean = lap_params["mu"], sd = lap_params["sd"])) # mean(fake_laplace_posterior); sd(fake_laplace_posterior) p_draws <- as.vector(fake_laplace_posterior) log_p <- numeric(S) for(s in 1:S){ log_p[s] <- log_post(p_draws[s], y = y, a0 = a0, b0 = b0, K = K) } log_g <- as.vector(dnorm(as.vector(fake_laplace_posterior), mean = lap_params["mu"], sd = lap_params["sd"], log = TRUE)) llfun <- function(data_i, draws) { dbinom(data_i$y, size = data_i$K, prob = draws, log = TRUE) } ll <- matrix(0, nrow = S, ncol = N) for(j in 1:N){ ll[, j] <- llfun(data_i = fake_data[j, , drop=FALSE], draws = fake_laplace_posterior) } test_that("loo_approximate_posterior.array works as loo_approximate_posterior.matrix", { # Create array with two "chains" log_p_mat <- matrix(log_p, nrow = (S/2), ncol = 2) log_g_mat <- matrix(log_g, nrow = (S/2), ncol = 2) ll_array <- array(0, dim = c((S/2), 2 , ncol(ll))) ll_array[,1,] <- ll[1:(S/2),] ll_array[,2,] <- ll[(S/2 + 1):S,] # Assert that they are ok expect_equivalent(ll_array[1:2,1,1:2], ll[1:2,1:2]) expect_equivalent(ll_array[1:2,2,1:2], ll[(S/2+1):((S/2)+2),1:2]) # Compute aploo expect_silent(aploo1 <- loo_approximate_posterior.matrix(x = ll, log_p = log_p, log_g = log_g)) expect_silent(aploo2 <- loo_approximate_posterior.array(x = ll_array, log_p = log_p_mat, log_g = log_g_mat)) expect_silent(aploo1b <- loo.matrix(x = ll, r_eff = rep(1, N))) # Check equivalence expect_equal(aploo1$estimates, aploo2$estimates) expect_equal(class(aploo1), class(aploo2)) expect_failure(expect_equal(aploo1b$estimates, aploo2$estimates)) expect_failure(expect_equal(class(aploo1), class(aploo1b))) # Should fail with matrix expect_error(aploo2 <- loo_approximate_posterior.matrix(x = ll, log_p = as.matrix(log_p), log_g = log_g)) expect_error(aploo2 <- loo_approximate_posterior.matrix(x = ll, log_p = as.matrix(log_p), log_g = as.matrix(log_g))) # Expect log_p and log_g be stored in the approximate_posterior in the same way expect_length(aploo1$approximate_posterior$log_p, nrow(ll)) expect_length(aploo1$approximate_posterior$log_g, nrow(ll)) expect_equal(aploo1$approximate_posterior$log_p, aploo2$approximate_posterior$log_p) expect_equal(aploo1$approximate_posterior$log_g, aploo2$approximate_posterior$log_g) }) test_that("loo_approximate_posterior.function works as loo_approximate_posterior.matrix", { # Compute aploo expect_silent(aploo1 <- loo_approximate_posterior.matrix(x = ll, log_p = log_p, log_g = log_g)) expect_silent(aploo1b <- loo.matrix(x = ll, r_eff = rep(1, N))) expect_silent(aploo2 <- loo_approximate_posterior.function(x = llfun, log_p = log_p, log_g = log_g, data = fake_data, draws = fake_laplace_posterior)) # Check equivalence expect_equal(aploo1$estimates, aploo2$estimates) expect_equal(class(aploo1), class(aploo2)) expect_failure(expect_equal(aploo1b$estimates, aploo2$estimates)) # Check equivalence # Expect log_p and log_g be stored in the approximate_posterior in the same way expect_length(aploo2$approximate_posterior$log_p, nrow(fake_laplace_posterior)) expect_length(aploo2$approximate_posterior$log_g, nrow(fake_laplace_posterior)) expect_equal(aploo1$approximate_posterior$log_p, aploo2$approximate_posterior$log_p) expect_equal(aploo1$approximate_posterior$log_g, aploo2$approximate_posterior$log_g) }) loo/tests/testthat/test_kfold_helpers.R0000644000176200001440000000651613575772017020076 0ustar liggesuserslibrary(loo) set.seed(14014) context("kfold helper functions") test_that("kfold_split_random works", { fold_rand <- kfold_split_random(10, 100) expect_length(fold_rand, 100) expect_equal(sort(unique(fold_rand)), 1:10) expect_equal(sum(fold_rand == 2), sum(fold_rand == 9)) }) test_that("kfold_split_stratified works", { y <- rep(c(0, 1), times = c(10, 190)) fold_strat <- kfold_split_stratified(5, y) expect_true(all(table(fold_strat) == 40)) y <- rep(c(1, 2, 3), times = c(15, 33, 42)) fold_strat <- kfold_split_stratified(7, y) expect_equal(range(table(fold_strat)), c(12, 13)) y <- mtcars$cyl fold_strat <- kfold_split_stratified(10, y) expect_equal(range(table(fold_strat)), c(3, 4)) }) test_that("kfold_split_grouped works", { grp <- gl(n = 50, k = 15, labels = state.name) fold_group <- kfold_split_grouped(x = grp) expect_true(all(table(fold_group) == 75)) expect_equal(sum(table(fold_group)), length(grp)) fold_group <- kfold_split_grouped(K = 9, x = grp) expect_false(all(table(fold_group) == 75)) expect_equal(sum(table(fold_group)), length(grp)) grp <- gl(n = 50, k = 4, labels = state.name) grp[grp == "Montana"] <- "Utah" fold_group <- kfold_split_grouped(K = 10, x = grp) expect_equal(sum(table(fold_group)), length(grp) - 4) grp <- rep(c("A","B"), each = 20) fold_group <- kfold_split_grouped(K = 2, x = grp) expect_equal(fold_group, as.integer(as.factor(grp))) }) test_that("kfold helpers throw correct errors", { expect_error(kfold_split_random(10), "!is.null(N) is not TRUE", fixed = TRUE) expect_error(kfold_split_random(10.5, 100), "K == as.integer(K) is not TRUE", fixed = TRUE) expect_error(kfold_split_random(10, 100.5), "N == as.integer(N) is not TRUE", fixed = TRUE) expect_error(kfold_split_random(K = c(1,1), N = 100), "length(K) == 1 is not TRUE", fixed = TRUE) expect_error(kfold_split_random(N = c(100, 100)), "length(N) == 1 is not TRUE", fixed = TRUE) expect_error(kfold_split_random(K = 5, N = 4), "K <= N is not TRUE", fixed = TRUE) expect_error(kfold_split_random(K = 1, N = 4), "K > 1 is not TRUE", fixed = TRUE) y <- sample(c(0, 1), size = 200, replace = TRUE, prob = c(0.05, 0.95)) expect_error(kfold_split_stratified(10), "!is.null(x) is not TRUE", fixed = TRUE) expect_error(kfold_split_stratified(10.5, y), "K == as.integer(K) is not TRUE", fixed = TRUE) expect_error(kfold_split_stratified(K = c(1,1), y), "length(K) == 1 is not TRUE", fixed = TRUE) expect_error(kfold_split_stratified(K = 201, y), "K <= length(x) is not TRUE", fixed = TRUE) expect_error(kfold_split_stratified(K = 1, y), "K > 1 is not TRUE", fixed = TRUE) grp <- gl(n = 50, k = 15) expect_error(kfold_split_grouped(10), "!is.null(x) is not TRUE", fixed = TRUE) expect_error(kfold_split_grouped(3, c(1,1,1)), "'K' must not be bigger than the number of levels/groups in 'x'", fixed = TRUE) expect_error(kfold_split_grouped(10.5, grp), "K == as.integer(K) is not TRUE", fixed = TRUE) expect_error(kfold_split_grouped(K = c(1,1), grp), "length(K) == 1 is not TRUE", fixed = TRUE) expect_error(kfold_split_grouped(K = 1, grp), "K > 1 is not TRUE", fixed = TRUE) }) test_that("print_dims.kfold works", { xx <- structure(list(), K = 17, class = c("kfold", "loo")) expect_output(print_dims(xx), "Based on 17-fold cross-validation") attr(xx, "K") <- NULL expect_silent(print_dims(xx)) }) loo/tests/testthat/test_psislw.R0000644000176200001440000000445513267637066016600 0ustar liggesuserslibrary(loo) SW <- suppressWarnings context("psislw") set.seed(123) x <- matrix(rnorm(5000), 100, 50) expect_deprecated <- function(object) { testthat::expect_warning(object, "deprecated", ignore.case = TRUE) } test_that("psislw throws deprecation warning", { expect_deprecated(psislw(x[, 1])) }) test_that("psislw handles special cases, throws appropriate errors/warnings", { expect_warning( psis <- psislw(x[, 1], wcp = 0.01), regexp = "All tail values are the same. Weights are truncated but not smoothed" ) expect_true(is.infinite(psis$pareto_k)) expect_warning( psislw(x[, 1], wcp = 0.01), regexp = "Some Pareto k diagnostic values are too high. See help('pareto-k-diagnostic') for details", fixed = TRUE ) expect_error( expect_deprecated(psislw(wcp = 0.2)), regexp = "'lw' or 'llfun' and 'llargs' must be specified" ) }) test_that("psislw returns expected results", { psis <- SW(psislw(x[, 1])) lw <- psis$lw_smooth expect_equal(length(psis), 2L) expect_equal(nrow(lw), nrow(x)) expect_equal(lw[1], -5.6655489517740527106) expect_equal(lw[50], -5.188442371693668953) expect_equal(range(lw), c(-7.4142421808626526314, -2.6902215137943321643)) expect_equal(psis$pareto_k, 0.17364505906017813075) }) test_that("psislw function and matrix methods return same result", { set.seed(024) # fake data and posterior draws N <- 50; K <- 10; S <- 100; a0 <- 3; b0 <- 2 p <- rbeta(1, a0, b0) y <- rbinom(N, size = K, prob = p) a <- a0 + sum(y); b <- b0 + N * K - sum(y) draws <- rbeta(S, a, b) data <- data.frame(y,K) llfun <- function(i, data, draws) { dbinom(data$y, size = data$K, prob = draws, log = TRUE) } psislw_with_fn <- SW(psislw(llfun = llfun, llargs = nlist(data, draws, N, S))) # Check that we get same answer if using log-likelihood matrix ll <- sapply(1:N, function(i) llfun(i, data[i,, drop=FALSE], draws)) psislw_with_mat <- SW(psislw(-ll)) expect_equal(psislw_with_fn, psislw_with_mat) }) test_that("psislw_warnings helper works properly", { k <- c(0, 0.1, 0.55, 0.75) expect_silent(psislw_warnings(k[1:2])) expect_warning(psislw_warnings(k[1:3]), "Some Pareto k diagnostic values are slightly high") expect_warning(psislw_warnings(k), "Some Pareto k diagnostic values are too high") }) loo/tests/testthat/test_loo_subsampling.R0000644000176200001440000017305314411130104020422 0ustar liggesuserslibrary(loo) options(mc.cores = 1) context("loo_subsampling") test_that("overall loo_subampling works as expected (compared with loo) for diff_est", { set.seed(123) N <- 1000; K <- 10; S <- 1000; a0 <- 3; b0 <- 2 p <- 0.7 y <- rbinom(N, size = K, prob = p) a <- a0 + sum(y); b <- b0 + N * K - sum(y) fake_posterior <- as.matrix(rbeta(S, a, b)) fake_data <- data.frame(y,K) rm(N, K, S, a0, b0, p, y, a, b) llfun_test <- function(data_i, draws) { # each time called internally within loo the arguments will be equal to: # data_i: ith row of fdata (fake_data[i,, drop=FALSE]) # draws: entire fake_posterior matrix dbinom(data_i$y, size = data_i$K, prob = draws, log = TRUE) } expect_silent(true_loo <- loo(llfun_test, draws = fake_posterior, data = fake_data, r_eff = rep(1, nrow(fake_data)))) expect_s3_class(true_loo, "psis_loo") expect_silent(loo_ss <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 500, loo_approximation = "plpd", r_eff = rep(1, nrow(fake_data)))) expect_s3_class(loo_ss, "psis_loo_ss") # Check consistency expect_equivalent(loo_ss$pointwise[, "elpd_loo_approx"], loo_ss$loo_subsampling$elpd_loo_approx[loo_ss$pointwise[, "idx"]]) # Expect values z <- 2 expect_lte(loo_ss$estimates["elpd_loo", "Estimate"] - z * loo_ss$estimates["elpd_loo", "subsampling SE"], true_loo$estimates["elpd_loo", "Estimate"]) expect_gte(loo_ss$estimates["elpd_loo", "Estimate"] + z * loo_ss$estimates["elpd_loo", "subsampling SE"], true_loo$estimates["elpd_loo", "Estimate"]) expect_lte(loo_ss$estimates["p_loo", "Estimate"] - z * loo_ss$estimates["p_loo", "subsampling SE"], true_loo$estimates["p_loo", "Estimate"]) expect_gte(loo_ss$estimates["p_loo", "Estimate"] + z * loo_ss$estimates["p_loo", "subsampling SE"], true_loo$estimates["p_loo", "Estimate"]) expect_lte(loo_ss$estimates["looic", "Estimate"] - z * loo_ss$estimates["looic", "subsampling SE"], true_loo$estimates["looic", "Estimate"]) expect_gte(loo_ss$estimates["looic", "Estimate"] + z * loo_ss$estimates["looic", "subsampling SE"], true_loo$estimates["looic", "Estimate"]) expect_failure(expect_equal(true_loo$estimates["elpd_loo", "Estimate"], loo_ss$estimates["elpd_loo", "Estimate"], tol = 0.00000001)) expect_failure(expect_equal(true_loo$estimates["p_loo", "Estimate"], loo_ss$estimates["p_loo", "Estimate"], tol = 0.00000001)) expect_failure(expect_equal(true_loo$estimates["looic", "Estimate"], loo_ss$estimates["looic", "Estimate"], tol = 0.00000001)) # Test that observations works as expected expect_message(loo_ss2 <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = obs_idx(loo_ss), loo_approximation = "plpd", r_eff = rep(1, nrow(fake_data)))) expect_equal(loo_ss2$estimates, loo_ss$estimates, tol = 0.00000001) expect_silent(loo_ss2 <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = loo_ss, loo_approximation = "plpd", r_eff = rep(1, nrow(fake_data)))) expect_equal(loo_ss2$estimates, loo_ss$estimates, tol = 0.00000001) # Test lpd expect_silent(loo_ss_lpd <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 500, loo_approximation = "lpd", r_eff = rep(1, nrow(fake_data)))) expect_s3_class(loo_ss_lpd, "psis_loo_ss") z <- 2 expect_lte(loo_ss_lpd$estimates["elpd_loo", "Estimate"] - z * loo_ss_lpd$estimates["elpd_loo", "subsampling SE"], true_loo$estimates["elpd_loo", "Estimate"]) expect_gte(loo_ss_lpd$estimates["elpd_loo", "Estimate"] + z * loo_ss_lpd$estimates["elpd_loo", "subsampling SE"], true_loo$estimates["elpd_loo", "Estimate"]) expect_lte(loo_ss_lpd$estimates["p_loo", "Estimate"] - z * loo_ss_lpd$estimates["p_loo", "subsampling SE"], true_loo$estimates["p_loo", "Estimate"]) expect_gte(loo_ss_lpd$estimates["p_loo", "Estimate"] + z * loo_ss_lpd$estimates["p_loo", "subsampling SE"], true_loo$estimates["p_loo", "Estimate"]) expect_lte(loo_ss_lpd$estimates["looic", "Estimate"] - z * loo_ss_lpd$estimates["looic", "subsampling SE"], true_loo$estimates["looic", "Estimate"]) expect_gte(loo_ss_lpd$estimates["looic", "Estimate"] + z * loo_ss_lpd$estimates["looic", "subsampling SE"], true_loo$estimates["looic", "Estimate"]) expect_failure(expect_equal(true_loo$estimates["elpd_loo", "Estimate"], loo_ss_lpd$estimates["elpd_loo", "Estimate"], tol = 0.00000001)) expect_failure(expect_equal(true_loo$estimates["p_loo", "Estimate"], loo_ss_lpd$estimates["p_loo", "Estimate"], tol = 0.00000001)) expect_failure(expect_equal(true_loo$estimates["looic", "Estimate"], loo_ss_lpd$estimates["looic", "Estimate"], tol = 0.00000001)) expect_silent(loo_ss_lpd10 <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 500, loo_approximation = "lpd", loo_approximation_draws = 10, r_eff = rep(1, nrow(fake_data)))) expect_s3_class(loo_ss_lpd10, "psis_loo_ss") z <- 2 expect_lte(loo_ss_lpd10$estimates["elpd_loo", "Estimate"] - z * loo_ss_lpd10$estimates["elpd_loo", "subsampling SE"], true_loo$estimates["elpd_loo", "Estimate"]) expect_gte(loo_ss_lpd10$estimates["elpd_loo", "Estimate"] + z * loo_ss_lpd10$estimates["elpd_loo", "subsampling SE"], true_loo$estimates["elpd_loo", "Estimate"]) expect_lte(loo_ss_lpd10$estimates["p_loo", "Estimate"] - z * loo_ss_lpd10$estimates["p_loo", "subsampling SE"], true_loo$estimates["p_loo", "Estimate"]) expect_gte(loo_ss_lpd10$estimates["p_loo", "Estimate"] + z * loo_ss_lpd10$estimates["p_loo", "subsampling SE"], true_loo$estimates["p_loo", "Estimate"]) expect_lte(loo_ss_lpd10$estimates["looic", "Estimate"] - z * loo_ss_lpd10$estimates["looic", "subsampling SE"], true_loo$estimates["looic", "Estimate"]) expect_gte(loo_ss_lpd10$estimates["looic", "Estimate"] + z * loo_ss_lpd10$estimates["looic", "subsampling SE"], true_loo$estimates["looic", "Estimate"]) expect_failure(expect_equal(true_loo$estimates["elpd_loo", "Estimate"], loo_ss_lpd10$estimates["elpd_loo", "Estimate"], tol = 0.00000001)) expect_failure(expect_equal(true_loo$estimates["p_loo", "Estimate"], loo_ss_lpd10$estimates["p_loo", "Estimate"], tol = 0.00000001)) expect_failure(expect_equal(true_loo$estimates["looic", "Estimate"], loo_ss_lpd10$estimates["looic", "Estimate"], tol = 0.00000001)) # Test conversion of objects expect_silent(true_loo_2 <- loo:::as.psis_loo.psis_loo(true_loo)) expect_silent(true_loo_ss <- loo:::as.psis_loo_ss.psis_loo(true_loo)) expect_s3_class(true_loo_ss, "psis_loo_ss") expect_silent(true_loo_conv <- loo:::as.psis_loo.psis_loo_ss(true_loo_ss)) expect_failure(expect_s3_class(true_loo_conv, "psis_loo_ss")) expect_equal(true_loo_conv, true_loo) expect_error(loo:::as.psis_loo.psis_loo_ss(loo_ss)) }) test_that("loo with subsampling of all observations works as ordinary loo.", { set.seed(123) N <- 1000; K <- 10; S <- 1000; a0 <- 3; b0 <- 2 p <- 0.7 y <- rbinom(N, size = K, prob = p) a <- a0 + sum(y); b <- b0 + N * K - sum(y) fake_posterior <- as.matrix(rbeta(S, a, b)) fake_data <- data.frame(y,K) rm(N, K, S, a0, b0, p, y, a, b) llfun_test <- function(data_i, draws) { dbinom(data_i$y, size = data_i$K, prob = draws, log = TRUE) } expect_silent(true_loo <- loo(llfun_test, draws = fake_posterior, data = fake_data, r_eff = rep(1, nrow(fake_data)))) expect_s3_class(true_loo, "psis_loo") expect_silent(loo_ss <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 1000, loo_approximation = "plpd", r_eff = rep(1, nrow(fake_data)))) expect_s3_class(loo_ss, "psis_loo_ss") expect_error(loo_ss <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 1001, loo_approximation = "plpd", r_eff = rep(1, nrow(fake_data)))) expect_equal(true_loo$estimates["elpd_loo", "Estimate"], loo_ss$estimates["elpd_loo", "Estimate"], tol = 0.00000001) expect_equal(true_loo$estimates["p_loo", "Estimate"], loo_ss$estimates["p_loo", "Estimate"], tol = 0.00000001) expect_equal(true_loo$estimates["looic", "Estimate"], loo_ss$estimates["looic", "Estimate"], tol = 0.00000001) expect_equal(dim(true_loo),dim(loo_ss)) expect_equal(true_loo$diagnostics, loo_ss$diagnostics) expect_equal(max(loo_ss$pointwise[, "m_i"]), 1) }) test_that("overall loo_subsample works with diff_srs as expected (compared with loo)", { set.seed(123) N <- 1000; K <- 10; S <- 1000; a0 <- 3; b0 <- 2 p <- 0.7 y <- rbinom(N, size = K, prob = p) a <- a0 + sum(y); b <- b0 + N * K - sum(y) fake_posterior <- as.matrix(rbeta(S, a, b)) fake_data <- data.frame(y,K) rm(N, K, S, a0, b0, p, y, a, b) llfun_test <- function(data_i, draws) { dbinom(data_i$y, size = data_i$K, prob = draws, log = TRUE) } expect_silent(true_loo <- loo(x = llfun_test, draws = fake_posterior, data = fake_data, r_eff = rep(1, nrow(fake_data)))) expect_silent(loo_ss <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 200, loo_approximation = "plpd", estimator = "diff_srs", r_eff = rep(1, nrow(fake_data)))) expect_equal(true_loo$estimates[1,1], loo_ss$estimates[1,1], tol = 0.1) }) test_that("Test the srs estimator with 'none' approximation", { set.seed(123) N <- 1000; K <- 10; S <- 1000; a0 <- 3; b0 <- 2 p <- 0.7 y <- rbinom(N, size = K, prob = p) a <- a0 + sum(y); b <- b0 + N * K - sum(y) fake_posterior <- as.matrix(rbeta(S, a, b)) fake_data <- data.frame(y,K) rm(N, K, S, a0, b0, p, y, a, b) llfun_test <- function(data_i, draws) { dbinom(data_i$y, size = data_i$K, prob = draws, log = TRUE) } expect_silent(true_loo <- loo(llfun_test, draws = fake_posterior, data = fake_data, r_eff = rep(1, nrow(fake_data)))) expect_s3_class(true_loo, "psis_loo") expect_silent(loo_ss <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 200, loo_approximation = "none", estimator = "srs", r_eff = rep(1, nrow(fake_data)))) expect_s3_class(loo_ss, "psis_loo_ss") expect_error(loo_ss <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 1100, loo_approximation = "none", estimator = "srs", r_eff = rep(1, nrow(fake_data)))) expect_equal(length(obs_idx(loo_ss)), nobs(loo_ss)) # Check consistency expect_equivalent(loo_ss$pointwise[, "elpd_loo_approx"], loo_ss$loo_subsampling$elpd_loo_approx[loo_ss$pointwise[, "idx"]]) # Expect values z <- 2 expect_lte(loo_ss$estimates["elpd_loo", "Estimate"] - z * loo_ss$estimates["elpd_loo", "subsampling SE"], true_loo$estimates["elpd_loo", "Estimate"]) expect_gte(loo_ss$estimates["elpd_loo", "Estimate"] + z * loo_ss$estimates["elpd_loo", "subsampling SE"], true_loo$estimates["elpd_loo", "Estimate"]) expect_lte(loo_ss$estimates["p_loo", "Estimate"] - z * loo_ss$estimates["p_loo", "subsampling SE"], true_loo$estimates["p_loo", "Estimate"]) expect_gte(loo_ss$estimates["p_loo", "Estimate"] + z * loo_ss$estimates["p_loo", "subsampling SE"], true_loo$estimates["p_loo", "Estimate"]) expect_lte(loo_ss$estimates["looic", "Estimate"] - z * loo_ss$estimates["looic", "subsampling SE"], true_loo$estimates["looic", "Estimate"]) expect_gte(loo_ss$estimates["looic", "Estimate"] + z * loo_ss$estimates["looic", "subsampling SE"], true_loo$estimates["looic", "Estimate"]) expect_failure(expect_equal(true_loo$estimates["elpd_loo", "Estimate"], loo_ss$estimates["elpd_loo", "Estimate"], tol = 0.00000001)) expect_failure(expect_equal(true_loo$estimates["p_loo", "Estimate"], loo_ss$estimates["p_loo", "Estimate"], tol = 0.00000001)) expect_failure(expect_equal(true_loo$estimates["looic", "Estimate"], loo_ss$estimates["looic", "Estimate"], tol = 0.00000001)) }) test_that("Test the Hansen-Hurwitz estimator", { set.seed(123) N <- 1000; K <- 10; S <- 1000; a0 <- 3; b0 <- 2 p <- 0.7 y <- rbinom(N, size = K, prob = p) a <- a0 + sum(y); b <- b0 + N * K - sum(y) fake_posterior <- as.matrix(rbeta(S, a, b)) fake_data <- data.frame(y,K) rm(N, K, S, a0, b0, p, y, a, b) llfun_test <- function(data_i, draws) { dbinom(data_i$y, size = data_i$K, prob = draws, log = TRUE) } expect_silent(true_loo <- loo(llfun_test, draws = fake_posterior, data = fake_data, r_eff = rep(1, nrow(fake_data)))) expect_s3_class(true_loo, "psis_loo") expect_silent(loo_ss <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 300, loo_approximation = "plpd", estimator = "hh_pps", r_eff = rep(1, nrow(fake_data)))) expect_s3_class(loo_ss, "psis_loo_ss") expect_silent(loo_ss_max <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 1100, loo_approximation = "plpd", estimator = "hh_pps", r_eff = rep(1, nrow(fake_data)))) expect_s3_class(loo_ss_max, "psis_loo_ss") expect_silent(loo_ss_max2 <- update(loo_ss, draws = fake_posterior, data = fake_data, observations = 1100, r_eff = rep(1, nrow(fake_data)))) expect_equal(nobs(loo_ss_max2), 1100) expect_gt(max(loo_ss_max2$pointwise[, "m_i"]), 1) expect_error(loo_ss_max2 <- update(loo_ss_max2, draws = fake_posterior, data = fake_data, observations = 300, r_eff = rep(1, nrow(fake_data)))) expect_silent(loo_ss_max3 <- update(loo_ss, draws = fake_posterior, data = fake_data, observations = 1500, r_eff = rep(1, nrow(fake_data)))) expect_silent(loo_ss2 <- update(loo_ss, draws = fake_posterior, data = fake_data, observations = loo_ss, r_eff = rep(1, nrow(fake_data)))) expect_error(loo_ss2 <- update(loo_ss, draws = fake_posterior, data = fake_data, observations = loo_ss, loo_approximation = "lpd", r_eff = rep(1, nrow(fake_data)))) expect_equal(loo_ss$estimates, loo_ss2$estimates) expect_equal(length(obs_idx(loo_ss_max)), length(obs_idx(loo_ss_max2))) expect_equal(length(obs_idx(loo_ss_max)), nobs(loo_ss_max)) # Check consistency expect_equivalent(loo_ss$pointwise[, "elpd_loo_approx"], loo_ss$loo_subsampling$elpd_loo_approx[loo_ss$pointwise[, "idx"]]) # Check consistency expect_equivalent(loo_ss_max$pointwise[, "elpd_loo_approx"], loo_ss_max$loo_subsampling$elpd_loo_approx[loo_ss_max$pointwise[, "idx"]]) # Expect values z <- 2 expect_lte(loo_ss$estimates["elpd_loo", "Estimate"] - z * loo_ss$estimates["elpd_loo", "subsampling SE"], true_loo$estimates["elpd_loo", "Estimate"]) expect_gte(loo_ss$estimates["elpd_loo", "Estimate"] + z * loo_ss$estimates["elpd_loo", "subsampling SE"], true_loo$estimates["elpd_loo", "Estimate"]) expect_lte(loo_ss$estimates["p_loo", "Estimate"] - z * loo_ss$estimates["p_loo", "subsampling SE"], true_loo$estimates["p_loo", "Estimate"]) expect_gte(loo_ss$estimates["p_loo", "Estimate"] + z * loo_ss$estimates["p_loo", "subsampling SE"], true_loo$estimates["p_loo", "Estimate"]) expect_lte(loo_ss$estimates["looic", "Estimate"] - z * loo_ss$estimates["looic", "subsampling SE"], true_loo$estimates["looic", "Estimate"]) expect_gte(loo_ss$estimates["looic", "Estimate"] + z * loo_ss$estimates["looic", "subsampling SE"], true_loo$estimates["looic", "Estimate"]) expect_failure(expect_equal(true_loo$estimates["elpd_loo", "Estimate"], loo_ss$estimates["elpd_loo", "Estimate"], tol = 0.00000001)) expect_failure(expect_equal(true_loo$estimates["p_loo", "Estimate"], loo_ss$estimates["p_loo", "Estimate"], tol = 0.00000001)) expect_failure(expect_equal(true_loo$estimates["looic", "Estimate"], loo_ss$estimates["looic", "Estimate"], tol = 0.00000001)) expect_lte(loo_ss_max$estimates["elpd_loo", "Estimate"] - z * loo_ss_max$estimates["elpd_loo", "subsampling SE"], true_loo$estimates["elpd_loo", "Estimate"]) expect_gte(loo_ss_max$estimates["elpd_loo", "Estimate"] + z * loo_ss_max$estimates["elpd_loo", "subsampling SE"], true_loo$estimates["elpd_loo", "Estimate"]) }) test_that("update.psis_loo_ss works as expected (compared with loo)", { set.seed(123) N <- 1000; K <- 10; S <- 1000; a0 <- 3; b0 <- 2 p <- 0.7 y <- rbinom(N, size = K, prob = p) a <- a0 + sum(y); b <- b0 + N * K - sum(y) fake_posterior <- as.matrix(rbeta(S, a, b)) fake_data <- data.frame(y,K) rm(N, K, S, a0, b0, p, y, a, b) llfun_test <- function(data_i, draws) { dbinom(data_i$y, size = data_i$K, prob = draws, log = TRUE) } expect_silent(true_loo <- loo(llfun_test, draws = fake_posterior, data = fake_data, r_eff = rep(1, nrow(fake_data)))) expect_s3_class(true_loo, "psis_loo") expect_silent(loo_ss <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 500, loo_approximation = "plpd", r_eff = rep(1, nrow(fake_data)))) expect_s3_class(loo_ss, "psis_loo_ss") # Check error when draws and data dimensions differ expect_error(loo_ss2 <- update(object = loo_ss, draws = cbind(fake_posterior, 1), data = fake_data, observations = 600, r_eff = rep(1, nrow(fake_data)))) expect_error(loo_ss2 <- update(object = loo_ss, draws = fake_posterior, data = fake_data[-1,], observations = 600, r_eff = rep(1, nrow(fake_data)))) # Add tests for adding observations expect_silent(loo_ss2 <- update(object = loo_ss, draws = fake_posterior, data = fake_data, observations = 600, r_eff = rep(1, nrow(fake_data)))) expect_equal(dim(loo_ss2)[2] - dim(loo_ss)[2], expected = 100) expect_equal(dim(loo_ss2)[2], expected = dim(loo_ss2$pointwise)[1]) expect_length(loo_ss2$diagnostics$pareto_k, 600) expect_length(loo_ss2$diagnostics$n_eff, 600) for(i in 1:nrow(loo_ss2$estimates)) { expect_lt(loo_ss2$estimates[i, "subsampling SE"], loo_ss$estimates[i, "subsampling SE"]) } expect_silent(loo_ss2b <- update(object = loo_ss, draws = fake_posterior, data = fake_data)) expect_equal(loo_ss2b$estimates, loo_ss$estimates) expect_equal(loo_ss2b$pointwise, loo_ss$pointwise) expect_equal(loo_ss2b$diagnostics$pareto_k, loo_ss$diagnostics$pareto_k) expect_equal(loo_ss2b$diagnostics$n_eff, loo_ss$diagnostics$n_eff) expect_silent(loo_ss3 <- update(object = loo_ss2, draws = fake_posterior, data = fake_data, observations = loo_ss)) expect_equal(loo_ss3$estimates, loo_ss$estimates) expect_equal(loo_ss3$pointwise, loo_ss$pointwise) expect_equal(loo_ss3$diagnostics$pareto_k, loo_ss$diagnostics$pareto_k) expect_equal(loo_ss3$diagnostics$n_eff, loo_ss$diagnostics$n_eff) expect_silent(loo_ss4 <- update(object = loo_ss, draws = fake_posterior, data = fake_data, observations = 1000, r_eff = rep(1, nrow(fake_data)))) expect_equal(loo_ss4$estimates[,1], true_loo$estimates[,1]) expect_equal(loo_ss4$estimates[,2], true_loo$estimates[,2], tol = 0.001) expect_silent(loo_ss5 <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 1000, loo_approximation = "plpd", r_eff = rep(1, nrow(fake_data)))) ss4_order <- order(loo_ss4$pointwise[, "idx"]) expect_equal(loo_ss4$pointwise[ss4_order,c(1,3,4)], loo_ss5$pointwise[,c(1,3,4)]) expect_equal(loo_ss4$diagnostics$pareto_k[ss4_order], loo_ss5$diagnostics$pareto_k) expect_equal(loo_ss4$diagnostics$n_eff[ss4_order], loo_ss5$diagnostics$n_eff) expect_equal(loo_ss4$pointwise[ss4_order,c(1,3,4)], true_loo$pointwise[,c(1,3,4)]) expect_equal(loo_ss4$diagnostics$pareto_k[ss4_order], true_loo$diagnostics$pareto_k) expect_equal(loo_ss4$diagnostics$n_eff[ss4_order], true_loo$diagnostics$n_eff) expect_error(loo_ss_min <- update(object = loo_ss, draws = fake_posterior, data = fake_data, observations = 50, r_eff = rep(1, nrow(fake_data)))) expect_silent(true_loo_ss <- loo:::as.psis_loo_ss.psis_loo(true_loo)) expect_silent(loo_ss_subset0 <- update(true_loo_ss, observations = loo_ss, r_eff = rep(1, nrow(fake_data)))) expect_true(identical(obs_idx(loo_ss_subset0), obs_idx(loo_ss))) expect_silent(loo_ss_subset1 <- update(object = loo_ss, observations = loo_ss, r_eff = rep(1, nrow(fake_data)))) expect_message(loo_ss_subset2 <- update(object = loo_ss, observations = obs_idx(loo_ss)[1:10], r_eff = rep(1, nrow(fake_data)))) expect_equal(nobs(loo_ss_subset2), 10) expect_silent(true_loo_ss <- loo:::as.psis_loo_ss.psis_loo(true_loo)) set.seed(4711) expect_silent(loo_ss2 <- update(object = loo_ss, draws = fake_posterior, data = fake_data, observations = 600, r_eff = rep(1, nrow(fake_data)))) expect_silent(loo_ss2_subset0 <- update(object = true_loo_ss, observations = loo_ss2, r_eff = rep(1, nrow(fake_data)))) expect_true(setequal(obs_idx(loo_ss2), obs_idx(loo_ss2_subset0))) expect_true(identical(obs_idx(loo_ss2), obs_idx(loo_ss2_subset0))) expect_true(identical(loo_ss2$diagnostic, loo_ss2_subset0$diagnostic)) # Add tests for changing approx variable expect_silent(loo_ss_lpd <- update(object = loo_ss, draws = fake_posterior, data = fake_data, loo_approximation = "lpd", r_eff = rep(1, nrow(fake_data)))) expect_failure(expect_equal(loo_ss_lpd$loo_subsampling$elpd_loo_approx, loo_ss$loo_subsampling$elpd_loo_approx)) expect_equal(dim(loo_ss_lpd)[2], dim(loo_ss)[2]) expect_equal(dim(loo_ss_lpd)[2], dim(loo_ss_lpd$pointwise)[1]) expect_length(loo_ss_lpd$diagnostics$pareto_k, 500) expect_length(loo_ss_lpd$diagnostics$n_eff, 500) expect_failure(expect_equal(loo_ss_lpd$estimates[1, "subsampling SE"], loo_ss$estimates[1, "subsampling SE"])) expect_failure(expect_equal(loo_ss_lpd$estimates[3, "subsampling SE"], loo_ss$estimates[3, "subsampling SE"])) }) context("loo_subsampling_approximations") geterate_test_elpd_dataset <- function() { N <- 10; K <- 10; S <- 1000; a0 <- 3; b0 <- 2 p <- 0.7 y <- rbinom(N, size = K, prob = p) a <- a0 + sum(y); b <- b0 + N * K - sum(y) fake_posterior <- draws <- as.matrix(rbeta(S, a, b)) fake_data <- data.frame(y,K) rm(N, K, S, a0, b0, p, y, a, b) list(fake_posterior = fake_posterior, fake_data = fake_data) } test_elpd_loo_approximation <- function(cores) { set.seed(123) test_data <- geterate_test_elpd_dataset() fake_posterior <- test_data$fake_posterior fake_data <- test_data$fake_data llfun_test <- function(data_i, draws) { dbinom(data_i$y, size = data_i$K, prob = draws, log = TRUE) } # Compute plpd approximation expect_silent(pi_vals <- loo:::elpd_loo_approximation(.llfun = llfun_test, data = fake_data, draws = fake_posterior, loo_approximation = "plpd", cores = cores)) # Compute it manually point <- mean(fake_posterior) llik <- dbinom(fake_data$y, size = fake_data$K, prob = point, log = TRUE) abs_lliks <- abs(llik) man_elpd_loo_approximation <- abs_lliks/sum(abs_lliks) expect_equal(abs(pi_vals)/sum(abs(pi_vals)), man_elpd_loo_approximation, tol = 0.00001) # Compute lpd approximation expect_silent(pi_vals <- loo:::elpd_loo_approximation(.llfun = llfun_test, data = fake_data, draws = fake_posterior, loo_approximation = "lpd", cores = cores)) # Compute it manually llik <- numeric(10) for(i in seq_along(fake_data$y)){ llik[i] <- loo:::logMeanExp(dbinom(fake_data$y[i], size = fake_data$K, prob = fake_posterior, log = TRUE)) } abs_lliks <- abs(llik) man_approx_loo_variable <- abs_lliks/sum(abs_lliks) expect_equal(abs(pi_vals)/sum(abs(pi_vals)), man_approx_loo_variable, tol = 0.00001) # Compute waic approximation expect_silent(pi_vals_waic <- loo:::elpd_loo_approximation(.llfun = llfun_test, data = fake_data, draws = fake_posterior, loo_approximation = "waic", cores = cores)) expect_true(all(pi_vals > pi_vals_waic)) expect_true(sum(pi_vals) - sum(pi_vals_waic) < 1) # Compute tis approximation expect_silent(pi_vals_tis <- loo:::elpd_loo_approximation(.llfun = llfun_test, data = fake_data, draws = fake_posterior, loo_approximation = "tis", loo_approximation_draws = 100, cores = cores)) expect_true(all(pi_vals > pi_vals_tis)) expect_true(sum(pi_vals) - sum(pi_vals_tis) < 1) } test_that("elpd_loo_approximation works as expected", { test_elpd_loo_approximation(1) }) test_that("elpd_loo_approximation with multiple cores", { test_elpd_loo_approximation(2) }) test_that("Test loo_approximation_draws", { set.seed(123) N <- 1000; K <- 10; S <- 1000; a0 <- 3; b0 <- 2 p <- 0.7 y <- rbinom(N, size = K, prob = p) a <- a0 + sum(y); b <- b0 + N * K - sum(y) fake_posterior <- draws <- as.matrix(rbeta(S, a, b)) fake_data <- data.frame(y,K) rm(N, K, S, a0, b0, p, y, a, b) llfun_test <- function(data_i, draws) { dbinom(data_i$y, size = data_i$K, prob = draws, log = TRUE) } expect_silent(res1 <- loo:::elpd_loo_approximation(.llfun = llfun_test, data = fake_data, draws = fake_posterior, loo_approximation = "waic", loo_approximation_draws = NULL, cores = 1)) expect_silent(res2 <- loo:::elpd_loo_approximation(.llfun = llfun_test, data = fake_data, draws = fake_posterior, loo_approximation = "waic", loo_approximation_draws = 10, cores = 1)) expect_silent(res3 <- loo:::elpd_loo_approximation(.llfun = llfun_test, data = fake_data, draws = fake_posterior[1:10*100,], loo_approximation = "waic", loo_approximation_draws = NULL, cores = 1)) expect_silent(res4 <- loo:::elpd_loo_approximation(.llfun = llfun_test, data = fake_data, draws = fake_posterior[1:10*100,, drop = FALSE], loo_approximation = "waic", loo_approximation_draws = NULL, cores = 1)) expect_failure(expect_equal(res1, res3)) expect_equal(res2, res3) expect_silent(loo_ss1 <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 100, loo_approximation = "plpd", r_eff = rep(1, nrow(fake_data)))) expect_silent(loo_ss2 <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 100, loo_approximation = "plpd", loo_approximation_draws = 10, r_eff = rep(1, nrow(fake_data)))) expect_silent(loo_ss3 <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 100, loo_approximation = "plpd", loo_approximation_draws = 31, r_eff = rep(1, nrow(fake_data)))) expect_error(loo_ss4 <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 100, loo_approximation = "plpd", loo_approximation_draws = 3100, r_eff = rep(1, nrow(fake_data)))) expect_equal(names(loo_ss1$loo_subsampling), c("elpd_loo_approx", "loo_approximation", "loo_approximation_draws", "estimator", ".llfun", ".llgrad", ".llhess", "data_dim", "ndraws")) expect_null(loo_ss1$loo_subsampling$loo_approximation_draws) expect_equal(loo_ss2$loo_subsampling$loo_approximation_draws, 10L) expect_equal(loo_ss3$loo_subsampling$loo_approximation_draws, 31L) }) test_that("waic using delta method and gradient", { if (FALSE){ # Code to generate testdata - saved and loaded to avoid dependency of mvtnorm set.seed(123) N <- 400; beta <- c(1,2); X_full <- matrix(rep(1,N), ncol = 1); X_full <- cbind(X_full, runif(N)); S <- 1000 y_full <- rnorm(n = N, mean = X_full%*%beta, sd = 1) X <- X_full; y <- y_full Lambda_0 <- diag(length(beta)); mu_0 <- c(0,0) b_hat <- solve(t(X)%*%X)%*%t(X)%*%y mu_n <- solve(t(X)%*%X)%*%(t(X)%*%X%*%b_hat + Lambda_0%*%mu_0) Lambda_n <- t(X)%*%X + Lambda_0 # Uncomment row below when running. Commented out to remove CHECK warnings # fake_posterior <- mvtnorm::rmvnorm(n = S, mean = mu_n, sigma = solve(Lambda_n)) colnames(fake_posterior) <- c("a", "b") fake_data <- data.frame(y, X) save(fake_posterior, fake_data, file = test_path("data-for-tests/normal_reg_waic_test_example.rda")) } else { load(file = test_path("data-for-tests/normal_reg_waic_test_example.rda")) } .llfun <- function(data_i, draws) { # data_i: ith row of fdata (fake_data[i,, drop=FALSE]) # draws: entire fake_posterior matrix dnorm(data_i$y, mean = draws[, c("a", "b")] %*% t(as.matrix(data_i[, c("X1", "X2")])), sd = 1, log = TRUE) } .llgrad <- function(data_i, draws) { x_i <- data_i[, "X2"] gr <- cbind(data_i$y - draws[,"a"] - draws[,"b"]*x_i, (data_i$y - draws[,"a"] - draws[,"b"]*x_i) * x_i) colnames(gr) <- c("a", "b") gr } fake_posterior <- cbind(fake_posterior, runif(nrow(fake_posterior))) expect_silent(approx_loo_waic <- loo:::elpd_loo_approximation(.llfun, data = fake_data, draws = fake_posterior, cores = 1, loo_approximation = "waic")) expect_silent(approx_loo_waic_delta <- loo:::elpd_loo_approximation(.llfun, data = fake_data, draws = fake_posterior, cores = 1, loo_approximation = "waic_grad", .llgrad = .llgrad)) expect_silent(approx_loo_waic_delta_diag <- loo:::elpd_loo_approximation(.llfun, data = fake_data, draws = fake_posterior, cores = 1, loo_approximation = "waic_grad_marginal", .llgrad = .llgrad)) # Test that the approaches should not deviate too much diff_waic_delta <- mean(approx_loo_waic - approx_loo_waic_delta) diff_waic_delta_diag <- mean(approx_loo_waic - approx_loo_waic_delta_diag) expect_equal(approx_loo_waic,approx_loo_waic_delta_diag, tol = 0.1) expect_equal(approx_loo_waic,approx_loo_waic_delta, tol = 0.01) # Test usage in subsampling_loo expect_silent(loo_ss_waic <- loo_subsample(x = .llfun, data = fake_data, draws = fake_posterior, cores = 1, r_eff = rep(1, nrow(fake_data)), loo_approximation = "waic", observations = 50, llgrad = .llgrad)) expect_silent(loo_ss_waic_delta <- loo_subsample(x = .llfun, data = fake_data, draws = fake_posterior, cores = 1, r_eff = rep(1, nrow(fake_data)), loo_approximation = "waic_grad", observations = 50, llgrad = .llgrad)) expect_silent(loo_ss_waic_delta_marginal <- loo_subsample(x = .llfun, data = fake_data, draws = fake_posterior, cores = 1, r_eff = rep(1, nrow(fake_data)), loo_approximation = "waic_grad_marginal", observations = 50, llgrad = .llgrad)) expect_silent(loo_ss_plpd <- loo_subsample(x = .llfun, data = fake_data, draws = fake_posterior, cores = 1, r_eff = rep(1, nrow(fake_data)), loo_approximation = "plpd", observations = 50, llgrad = .llgrad)) expect_error(loo_ss_waic_delta <- loo_subsample(x = .llfun, data = fake_data, draws = fake_posterior, cores = 1, r_eff = rep(1, nrow(fake_data)), loo_approximation = "waic_grad", observations = 50)) }) test_that("waic using delta 2nd order method", { if (FALSE){ # Code to generate testdata - saved and loaded to avoid dependency of MCMCPack set.seed(123) N <- 100; beta <- c(1,2); X_full <- matrix(rep(1,N), ncol = 1); X_full <- cbind(X_full, runif(N)); S <- 1000 y_full <- rnorm(n = N, mean = X_full%*%beta, sd = 0.5) X <- X_full; y <- y_full # Uncomment row below when running. Commented out to remove CHECK warnings # fake_posterior <- MCMCpack::MCMCregress(y~x, data = data.frame(y = y,x=X[,2]), thin = 10, mcmc = 10000) # Because Im lazy fake_posterior <- as.matrix(fake_posterior) fake_posterior[,"sigma2"] <- sqrt(fake_posterior[,"sigma2"]) colnames(fake_posterior) <- c("a", "b", "sigma") fake_data <- data.frame(y, X) save(fake_posterior, fake_data, file = test_path("data-for-tests/normal_reg_waic_test_example2.rda"), compression_level = 9) } else { load(file = test_path("data-for-tests/normal_reg_waic_test_example2.rda")) } .llfun <- function(data_i, draws) { # data_i: ith row of fdata (data_i <- fake_data[i,, drop=FALSE]) # draws: entire fake_posterior matrix dnorm(data_i$y, mean = draws[, c("a", "b")] %*% t(as.matrix(data_i[, c("X1", "X2")])), sd = draws[, c("sigma")], log = TRUE) } .llgrad <- function(data_i, draws) { sigma <- draws[,"sigma"] sigma2 <- sigma^2 b <- draws[,"b"] a <- draws[,"a"] x_i <- unlist(data_i[, c("X1", "X2")]) e <- (data_i$y - draws[,"a"] * x_i[1] - draws[,"b"] * x_i[2]) gr <- cbind(e * x_i[1] / sigma2, e * x_i[2] / sigma2, - 1 / sigma + e^2 / (sigma2 * sigma)) colnames(gr) <- c("a", "b", "sigma") gr } .llhess <- function(data_i, draws) { hess_array <- array(0, dim = c(ncol(draws), ncol(draws), nrow(draws)), dimnames = list(colnames(draws),colnames(draws),NULL)) sigma <- draws[,"sigma"] sigma2 <- sigma^2 sigma3 <- sigma2*sigma b <- draws[,"b"] a <- draws[,"a"] x_i <- unlist(data_i[, c("X1", "X2")]) e <- (data_i$y - draws[,"a"] * x_i[1] - draws[,"b"] * x_i[2]) hess_array[1,1,] <- - x_i[1]^2 / sigma2 hess_array[1,2,] <- hess_array[2,1,] <- - x_i[1] * x_i[2] / sigma2 hess_array[2,2,] <- - x_i[2]^2 / sigma2 hess_array[3,1,] <- hess_array[1,3,] <- -2 * x_i[1] * e / sigma3 hess_array[3,2,] <- hess_array[2,3,] <- -2 * x_i[2] * e / sigma3 hess_array[3,3,] <- 1 / sigma2 - 3 * e^2 / (sigma2^2) hess_array } #data <- fake_data fake_posterior <- cbind(fake_posterior, runif(nrow(fake_posterior))) #draws <- fake_posterior <- cbind(fake_posterior, runif(nrow(fake_posterior))) expect_silent(approx_loo_waic <- loo:::elpd_loo_approximation(.llfun, data = fake_data, draws = fake_posterior, cores = 1, loo_approximation = "waic")) expect_silent(approx_loo_waic_delta <- loo:::elpd_loo_approximation(.llfun, data = fake_data, draws = fake_posterior, cores = 1, loo_approximation = "waic_grad", .llgrad = .llgrad)) expect_silent(approx_loo_waic_delta2 <- loo:::elpd_loo_approximation(.llfun, data = fake_data, draws = fake_posterior, cores = 1, loo_approximation = "waic_hess", .llgrad = .llgrad, .llhess = .llhess)) # Test that the approaches should not deviate too much expect_equal(approx_loo_waic,approx_loo_waic_delta2, tol = 0.01) expect_equal(approx_loo_waic,approx_loo_waic_delta, tol = 0.01) expect_silent(test_loo_ss_waic <- loo_subsample(x = .llfun, data = fake_data, draws = fake_posterior, cores = 1, r_eff = rep(1, nrow(fake_data)), loo_approximation = "waic", observations = 50, llgrad = .llgrad)) expect_error(test_loo_ss_delta2 <- loo_subsample(x = .llfun, data = fake_data, draws = fake_posterior, cores = 1, r_eff = rep(1, nrow(fake_data)), loo_approximation = "waic_hess", observations = 50, llgrad = .llgrad)) expect_silent(test_loo_ss_delta2 <- loo_subsample(x = .llfun, data = fake_data, draws = fake_posterior, cores = 1, r_eff = rep(1, nrow(fake_data)), loo_approximation = "waic_hess", observations = 50, llgrad = .llgrad, llhess = .llhess)) expect_silent(test_loo_ss_delta <- loo_subsample(x = .llfun, data = fake_data, draws = fake_posterior, cores = 1, r_eff = rep(1, nrow(fake_data)), loo_approximation = "waic_grad", observations = 50, llgrad = .llgrad)) expect_silent(test_loo_ss_point <- loo_subsample(x = .llfun, data = fake_data, draws = fake_posterior, cores = 1, r_eff = rep(1, nrow(fake_data)), loo_approximation = "plpd", observations = 50, llgrad = .llgrad)) }) context("loo_subsampling_estimation") test_that("whhest works as expected", { N <- 100 m <- 10 z <- rep(1/N, m) y <- 1:10 m_i <- rep(1,m) expect_silent(whe <- loo:::whhest(z = z, m_i = m_i, y = y, N = N)) expect_equal(whe$y_hat_ppz, 550) man_var <- (sum((whe$y_hat_ppz - y/z)^2)/(m-1))/m expect_equal(whe$v_hat_y_ppz, man_var) z <- 1:10/(sum(1:10)*10) expect_silent(whe <- loo:::whhest(z = z, m_i = m_i, y = y, N = N)) expect_equal(whe$y_hat_ppz, 550) expect_equal(whe$v_hat_y_ppz, 0) # School book example # https://newonlinecourses.science.psu.edu/stat506/node/15/ z <- c(650/15650, 2840/15650, 3200/15650) y <- c(420, 1785, 2198) m_i <- c(1,1,1) N <- 10 expect_silent(whe <- loo:::whhest(z = z, m_i = m_i, y = y, N = N)) expect_equal(round(whe$y_hat_ppz, 2), 10232.75, tol = 0) expect_equal(whe$v_hat_y_ppz, 73125.74, tol = 0.01) # Double check that it is rounding error man_var_round <- (sum((round(y/z,2) - 10232.75)^2)) * (1/2) * (1/3) expect_equal(man_var_round, 73125.74, tol = 0.001) man_var_exact <- (sum((y/z - 10232.75)^2)) * (1/2) * (1/3) expect_equal(whe$v_hat_y_ppz, man_var_exact, tol = 0.001) # Add test for variance estimation N <- 100 m <- 10 y <- rep(1:10, 1) true_var <- var(rep(y, 10)) * (99) z <- rep(1/N, m) m_i <- rep(100000, m) expect_silent(whe <- loo:::whhest(z = z, m_i = m_i, y = y, N = N)) expect_equal(true_var, whe$hat_v_y_ppz, tol = 0.01) # Add tests for m_i N <- 100 y <- rep(1:10, 2) m <- length(y) z <- rep(1/N, m) m_i <- rep(1,m) expect_silent(whe1 <- loo:::whhest(z = z, m_i = m_i, y = y, N = N)) y <- rep(1:10) m <- length(y) z <- rep(1/N, m) m_i <- rep(2,m) expect_silent(whe2 <- loo:::whhest(z = z, m_i = m_i, y = y, N = N)) expect_equal(whe1$y_hat_ppz, whe2$y_hat_ppz) expect_equal(whe1$v_hat_y_ppz, whe2$v_hat_y_ppz) expect_equal(whe1$hat_v_y_ppz, whe1$hat_v_y_ppz) }) test_that("srs_diff_est works as expected", { set.seed(1234) N <- 1000 y_true <- 1:N sigma_hat_true <- sqrt(N * sum((y_true - mean(y_true))^2) / length(y_true)) y_approx <- rnorm(N, y_true, 0.1) m <- 100 sigma_hat <- y_hat <- se_y_hat <- numeric(10000) for(i in 1:10000){ y_idx <- sample(1:N, size = m) y <- y_true[y_idx] res <- loo:::srs_diff_est(y_approx, y, y_idx) y_hat[i] <- res$y_hat se_y_hat[i] <- sqrt(res$v_y_hat) sigma_hat[i] <- sqrt(res$hat_v_y) } expect_equal(mean(y_hat), sum(y_true), tol = 0.1) in_ki <- y_hat + 2 * se_y_hat > sum(y_true) & y_hat - 2*se_y_hat < sum(y_true) expect_equal(mean(in_ki), 0.95, tol = 0.01) # Should be unbiased expect_equal(mean(sigma_hat), sigma_hat_true, tol = 0.1) m <- N y_idx <- sample(1:N, size = m) y <- y_true[y_idx] res <- loo:::srs_diff_est(y_approx, y, y_idx) expect_equal(res$y_hat, 500500, tol = 0.0001) expect_equal(res$v_y_hat, 0, tol = 0.0001) expect_equal(sqrt(res$hat_v_y), sigma_hat_true, tol = 0.1) }) test_that("srs_est works as expected", { set.seed(1234) # Cochran 1976 example Table 2.2 y <- c(rep(42,23),rep(41,4), 36, 32, 29, 27, 27, 23, 19, 16, 16, 15, 15, 14, 11, 10, 9, 7, 6, 6, 6, 5, 5, 4, 3) expect_equal(sum(y), 1471) approx_loo <- rep(0L, 676) expect_equal(sum(y^2), 54497) res <- loo:::srs_est(y = y, approx_loo) expect_equal(res$y_hat, 19888, tol = 0.0001) expect_equal(res$v_y_hat, 676^2*229*(1-0.074)/50, tol = 0.0001) expect_equal(res$hat_v_y, 676 * var(y), tol = 0.0001) # Simulation example set.seed(1234) N <- 1000 y_true <- 1:N sigma_hat_true <- sqrt(N * sum((y_true - mean(y_true))^2) / length(y_true)) m <- 100 y_hat <- se_y_hat <- sigma_hat <- numeric(10000) for(i in 1:10000){ y_idx <- sample(1:N, size = m) y <- y_true[y_idx] res <- loo:::srs_est(y = y, y_approx = y_true) y_hat[i] <- res$y_hat se_y_hat[i] <- sqrt(res$v_y_hat) sigma_hat[i] <- sqrt(res$hat_v_y) } expect_equal(mean(y_hat), sum(y_true), tol = 0.1) in_ki <- y_hat + 2*se_y_hat > sum(y_true) & y_hat - 2*se_y_hat < sum(y_true) expect_equal(mean(in_ki), 0.95, tol = 0.01) # Should be unbiased expect_equal(mean(sigma_hat), sigma_hat_true, tol = 0.1) m <- N y_idx <- sample(1:N, size = m) y <- y_true[y_idx] res <- loo:::srs_est(y, y_true) expect_equal(res$y_hat, 500500, tol = 0.0001) expect_equal(res$v_y_hat, 0, tol = 0.0001) }) context("loo_subsampling cases") test_that("Test loo_subsampling and loo_approx with radon data", { skip_on_cran() # avoid going over time limit for tests load(test_path("data-for-tests/test_radon_laplace_loo.rda")) # Rename to spot variable leaking errors llfun_test <- llfun log_p_test <- log_p log_g_test <- log_q draws_test <- draws data_test <- data rm(llfun, log_p,log_q, draws, data) set.seed(134) expect_silent(full_loo <- loo(llfun_test, draws = draws_test, data = data_test, r_eff = rep(1, nrow(data_test)))) expect_s3_class(full_loo, "psis_loo") set.seed(134) expect_silent(loo_ss <- loo_subsample(x = llfun_test, draws = draws_test, data = data_test, observations = 200, loo_approximation = "plpd", r_eff = rep(1, nrow(data_test)))) expect_s3_class(loo_ss, "psis_loo_ss") set.seed(134) expect_silent(loo_ap_ss <- loo_subsample(x = llfun_test, draws = draws_test, data = data_test, log_p = log_p_test, log_g = log_g_test, observations = 200, loo_approximation = "plpd", r_eff = rep(1, nrow(data_test)))) expect_s3_class(loo_ap_ss, "psis_loo_ss") expect_s3_class(loo_ap_ss, "psis_loo_ap") expect_silent(loo_ap_ss_full <- loo_subsample(x = llfun_test, log_p = log_p_test, log_g = log_g_test, draws = draws_test, data = data_test, observations = NULL, loo_approximation = "plpd", r_eff = rep(1, nrow(data_test)))) expect_failure(expect_s3_class(loo_ap_ss_full, "psis_loo_ss")) expect_s3_class(loo_ap_ss_full, "psis_loo_ap") # Expect similar results z <- 2 expect_lte(loo_ss$estimates["elpd_loo", "Estimate"] - z * loo_ss$estimates["elpd_loo", "subsampling SE"], full_loo$estimates["elpd_loo", "Estimate"]) expect_gte(loo_ss$estimates["elpd_loo", "Estimate"] + z * loo_ss$estimates["elpd_loo", "subsampling SE"], full_loo$estimates["elpd_loo", "Estimate"]) expect_lte(loo_ss$estimates["p_loo", "Estimate"] - z * loo_ss$estimates["p_loo", "subsampling SE"], full_loo$estimates["p_loo", "Estimate"]) expect_gte(loo_ss$estimates["p_loo", "Estimate"] + z * loo_ss$estimates["p_loo", "subsampling SE"], full_loo$estimates["p_loo", "Estimate"]) expect_lte(loo_ss$estimates["looic", "Estimate"] - z * loo_ss$estimates["looic", "subsampling SE"], full_loo$estimates["looic", "Estimate"]) expect_gte(loo_ss$estimates["looic", "Estimate"] + z * loo_ss$estimates["looic", "subsampling SE"], full_loo$estimates["looic", "Estimate"]) expect_failure(expect_equal(full_loo$estimates["elpd_loo", "Estimate"], loo_ss$estimates["elpd_loo", "Estimate"], tol = 0.00000001)) expect_failure(expect_equal(full_loo$estimates["p_loo", "Estimate"], loo_ss$estimates["p_loo", "Estimate"], tol = 0.00000001)) expect_failure(expect_equal(full_loo$estimates["looic", "Estimate"], loo_ss$estimates["looic", "Estimate"], tol = 0.00000001)) z <- 2 expect_lte(loo_ap_ss$estimates["elpd_loo", "Estimate"] - z * loo_ap_ss$estimates["elpd_loo", "subsampling SE"], loo_ap_ss_full$estimates["elpd_loo", "Estimate"]) expect_gte(loo_ap_ss$estimates["elpd_loo", "Estimate"] + z * loo_ap_ss$estimates["elpd_loo", "subsampling SE"], loo_ap_ss_full$estimates["elpd_loo", "Estimate"]) expect_lte(loo_ap_ss$estimates["p_loo", "Estimate"] - z * loo_ap_ss$estimates["p_loo", "subsampling SE"], loo_ap_ss_full$estimates["p_loo", "Estimate"]) expect_gte(loo_ap_ss$estimates["p_loo", "Estimate"] + z * loo_ap_ss$estimates["p_loo", "subsampling SE"], loo_ap_ss_full$estimates["p_loo", "Estimate"]) expect_lte(loo_ap_ss$estimates["looic", "Estimate"] - z * loo_ap_ss$estimates["looic", "subsampling SE"], loo_ap_ss_full$estimates["looic", "Estimate"]) expect_gte(loo_ap_ss$estimates["looic", "Estimate"] + z * loo_ap_ss$estimates["looic", "subsampling SE"], loo_ap_ss_full$estimates["looic", "Estimate"]) expect_failure(expect_equal(loo_ap_ss_full$estimates["elpd_loo", "Estimate"], loo_ap_ss$estimates["elpd_loo", "Estimate"], tol = 0.00000001)) expect_failure(expect_equal(loo_ap_ss_full$estimates["p_loo", "Estimate"], loo_ap_ss$estimates["p_loo", "Estimate"], tol = 0.00000001)) expect_failure(expect_equal(loo_ap_ss_full$estimates["looic", "Estimate"], loo_ap_ss$estimates["looic", "Estimate"], tol = 0.00000001)) # Correct printout expect_failure(expect_output(print(full_loo), "Posterior approximation correction used\\.")) expect_failure(expect_output(print(full_loo), "subsampled log-likelihood\nvalues")) expect_failure(expect_output(print(loo_ss), "Posterior approximation correction used\\.")) expect_output(print(loo_ss), "subsampled log-likelihood\nvalues") expect_output(print(loo_ap_ss), "Posterior approximation correction used\\.") expect_output(print(loo_ap_ss), "subsampled log-likelihood\nvalues") expect_output(print(loo_ap_ss_full), "Posterior approximation correction used\\.") expect_failure(expect_output(print(loo_ap_ss_full), "subsampled log-likelihood\nvalues")) # Test conversion of objects expect_silent(loo_ap_full <- loo:::as.psis_loo.psis_loo(loo_ap_ss_full)) expect_s3_class(loo_ap_full, "psis_loo_ap") expect_silent(loo_ap_full_ss <- loo:::as.psis_loo_ss.psis_loo(loo_ap_full)) expect_s3_class(loo_ap_full_ss, "psis_loo_ss") expect_s3_class(loo_ap_full_ss, "psis_loo_ap") expect_silent(loo_ap_full2 <- loo:::as.psis_loo.psis_loo_ss(loo_ap_full_ss)) expect_s3_class(loo_ap_full2, "psis_loo_ap") expect_failure(expect_s3_class(loo_ap_full2, "psis_loo_ss")) expect_equal(loo_ap_full2,loo_ap_full) # Test update set.seed(4712) expect_silent(loo_ss2 <- update(loo_ss, draws = draws_test, data = data_test, observations = 1000, r_eff = rep(1, nrow(data_test)))) expect_gt(dim(loo_ss2)[2], dim(loo_ss)[2]) expect_gt(dim(loo_ss2$pointwise)[1], dim(loo_ss$pointwise)[1]) expect_equal(nobs(loo_ss), 200) expect_equal(nobs(loo_ss2), 1000) for(i in 1:nrow(loo_ss2$estimates)) { expect_lt(loo_ss2$estimates[i, "subsampling SE"], loo_ss$estimates[i, "subsampling SE"]) } set.seed(4712) expect_silent(loo_ap_ss2 <- update(object = loo_ap_ss, draws = draws_test, data = data_test, observations = 2000)) expect_gt(dim(loo_ap_ss2)[2], dim(loo_ap_ss)[2]) expect_gt(dim(loo_ap_ss2$pointwise)[1], dim(loo_ap_ss$pointwise)[1]) expect_equal(nobs(loo_ap_ss), 200) expect_equal(nobs(loo_ap_ss2), 2000) for(i in 1:nrow(loo_ap_ss2$estimates)) { expect_lt(loo_ap_ss2$estimates[i, "subsampling SE"], loo_ap_ss$estimates[i, "subsampling SE"]) } expect_equal(round(full_loo$estimates), round(loo_ap_ss_full$estimates)) expect_failure(expect_equal(full_loo$estimates, loo_ap_ss_full$estimates)) expect_equal(dim(full_loo), dim(loo_ap_ss_full)) expect_s3_class(loo_ap_ss_full, "psis_loo_ap") }) test_that("Test the vignette", { skip_on_cran() # NOTE # If any of these test fails, the vignette probably needs to be updated if (FALSE) { # Generate vignette test case library("rstan") stan_code <- " data { int N; // number of data points int P; // number of predictors (including intercept) matrix[N,P] X; // predictors (including 1s for intercept) int y[N]; // binary outcome } parameters { vector[P] beta; } model { beta ~ normal(0, 1); y ~ bernoulli_logit(X * beta); } " # logistic <- function(x) {1 / (1 + exp(-x))} # logit <- function(x) {log(x) - log(1-x)} llfun_logistic <- function(data_i, draws) { x_i <- as.matrix(data_i[, which(grepl(colnames(data_i), pattern = "X")), drop=FALSE]) y_pred <- draws %*% t(x_i) dbinom(x = data_i$y, size = 1, prob = 1 / (1 + exp(-y_pred)), log = TRUE) } # Prepare data url <- "http://stat.columbia.edu/~gelman/arm/examples/arsenic/wells.dat" wells <- read.table(url) wells$dist100 <- with(wells, dist / 100) X <- model.matrix(~ dist100 + arsenic, wells) standata <- list(y = wells$switch, X = X, N = nrow(X), P = ncol(X)) # Fit model set.seed(4711) fit_1 <- stan(model_code = stan_code, data = standata, seed = 4711) print(fit_1, pars = "beta") parameter_draws <- extract(fit_1)$beta stan_df <- as.data.frame(standata) loo_i(1, llfun_logistic, data = stan_df, draws = parameter_draws) sm <- stan_model(model_code = stan_code) set.seed(4711) fit_laplace <- optimizing(sm, data = standata, draws = 2000, seed = 42) parameter_draws_laplace <- fit_laplace$theta_tilde log_p <- fit_laplace$log_p # The log density of the posterior log_g <- fit_laplace$log_g # The log density of the approximation # For comparisons standata$X[, "arsenic"] <- log(standata$X[, "arsenic"]) stan_df2 <- as.data.frame(standata) set.seed(4711) fit_2 <- stan(fit = fit_1, data = standata, seed = 4711) parameter_draws_2 <- extract(fit_2)$beta save(llfun_logistic, stan_df, stan_df2, parameter_draws, parameter_draws_laplace, parameter_draws_2, log_p, log_g, file = test_path("data-for-tests/loo_subsample_vignette.rda"), compression_level = 9) } else { load(test_path("data-for-tests/loo_subsample_vignette.rda")) } set.seed(4711) expect_warning(looss_1 <- loo_subsample(llfun_logistic, draws = parameter_draws, data = stan_df, observations = 100)) expect_output(print(looss_1), "Computed from 4000 by 100 subsampled log-likelihood") expect_output(print(looss_1), "values from 3020 total observations.") expect_output(print(looss_1), "elpd_loo -1968.5 15.6 0.3") expect_output(print(looss_1), "p_loo 3.1 0.1 0.4") expect_s3_class(looss_1, c("psis_loo_ss", "psis_loo", "loo")) set.seed(4711) expect_warning(looss_1b <- update(looss_1, draws = parameter_draws, data = stan_df, observations = 200)) expect_output(print(looss_1b), "Computed from 4000 by 200 subsampled log-likelihood") expect_output(print(looss_1b), "values from 3020 total observations.") expect_output(print(looss_1b), "elpd_loo -1968.3 15.6 0.2") expect_output(print(looss_1b), "p_loo 3.2 0.1 0.4") expect_s3_class(looss_1b, c("psis_loo_ss", "psis_loo", "loo")) set.seed(4711) expect_warning(looss_2 <- loo_subsample(x = llfun_logistic, draws = parameter_draws, data = stan_df, observations = 100, estimator = "hh_pps", loo_approximation = "lpd", loo_approximation_draws = 100)) expect_output(print(looss_2), "Computed from 4000 by 100 subsampled log-likelihood") expect_output(print(looss_2), "values from 3020 total observations.") # Currently failing # expect_output(print(looss_2), "elpd_loo -1968.9 15.4 0.5") # expect_output(print(looss_2), "p_loo 3.5 0.2 0.5") expect_s3_class(looss_2, c("psis_loo_ss", "psis_loo", "loo")) set.seed(4711) expect_warning(aploo_1 <- loo_approximate_posterior(llfun_logistic, draws = parameter_draws_laplace, data = stan_df, log_p = log_p, log_g = log_g)) expect_output(print(aploo_1), "Computed from 2000 by 3020 log-likelihood matrix") expect_output(print(aploo_1), "elpd_loo -1968.4 15.6") expect_output(print(aploo_1), "p_loo 3.2 0.2") expect_output(print(aploo_1), "Posterior approximation correction used.") expect_output(print(aploo_1), "\\(-Inf, 0.5\\] \\(good\\) 2989 99.0") expect_output(print(aploo_1), "\\(0.5, 0.7\\] \\(ok\\) 31 1.0") expect_s3_class(aploo_1, c("psis_loo_ap", "psis_loo", "loo")) set.seed(4711) expect_warning(looapss_1 <- loo_subsample(llfun_logistic, draws = parameter_draws_laplace, data = stan_df, log_p = log_p, log_g = log_g, observations = 100)) expect_output(print(looapss_1), "Computed from 2000 by 100 subsampled log-likelihood") expect_output(print(looapss_1), "values from 3020 total observations.") expect_output(print(looapss_1), "elpd_loo -1968.2 15.6 0.4") expect_output(print(looapss_1), "p_loo 2.9 0.1 0.5") expect_output(print(looapss_1), "\\(-Inf, 0.5\\] \\(good\\) 97 97.0") expect_output(print(looapss_1), "\\(0.5, 0.7\\] \\(ok\\) 3 3.0") # Loo compare set.seed(4711) expect_warning(looss_1 <- loo_subsample(llfun_logistic, draws = parameter_draws, data = stan_df, observations = 100)) set.seed(4712) expect_warning(looss_2 <- loo_subsample(x = llfun_logistic, draws = parameter_draws_2, data = stan_df2, observations = 100)) expect_output(print(looss_2), "Computed from 4000 by 100 subsampled log-likelihood") expect_output(print(looss_2), "values from 3020 total observations.") expect_output(print(looss_2), "elpd_loo -1952.0 16.2 0.2") expect_output(print(looss_2), "p_loo 2.6 0.1 0.3") expect_warning(comp <- loo_compare(looss_1, looss_2), "Different subsamples in 'model2' and 'model1'. Naive diff SE is used.") expect_output(print(comp), "model1 16.5 22.5 0.4") set.seed(4712) expect_warning(looss_2_m <- loo_subsample(x = llfun_logistic, draws = parameter_draws_2, data = stan_df2, observations = looss_1)) expect_message(looss_2_m <- suppressWarnings(loo_subsample(x = llfun_logistic, draws = parameter_draws_2, data = stan_df2, observations = obs_idx(looss_1))), "Simple random sampling with replacement assumed.") expect_silent(comp <- loo_compare(looss_1, looss_2_m)) expect_output(print(comp), "model1 16.1 4.4 0.1") set.seed(4712) expect_warning(looss_1 <- update(looss_1, draws = parameter_draws, data = stan_df, observations = 200)) expect_warning(looss_2_m <- update(looss_2_m, draws = parameter_draws_2, data = stan_df2, observations = looss_1)) expect_silent(comp2 <- loo_compare(looss_1, looss_2_m)) expect_output(print(comp2), "model1 16.3 4.4 0.1") expect_warning(looss_2_full <- loo(x = llfun_logistic, draws = parameter_draws_2, data = stan_df2)) expect_message(comp3 <- loo_compare(x = list(looss_1, looss_2_full)), "Estimated elpd_diff using observations included in loo calculations for all models.") expect_output(print(comp3), "model1 16.5 4.4 0.3") }) context("loo_compare_subsample") test_that("loo_compare_subsample", { skip_on_cran() # to get under cran check time limit set.seed(123) N <- 1000 x1 <- rnorm(N) x2 <- rnorm(N) x3 <- rnorm(N) sigma <- 2 y <- rnorm(N, 1 + 2*x1 - 2*x2 - 1*x3, sd = sigma) X <- cbind("x0" = rep(1, N), x1, x2, x3) # Generate samples from posterior samples_blin <- function(X, y, sigma, draws = 1000){ XtX <- t(X)%*%X b_hat <- solve(XtX) %*% (t(X) %*% y) Lambda_n = XtX + diag(ncol(X)) mu_n <- solve(Lambda_n) %*% (XtX %*% b_hat + diag(ncol(X)) %*% rep(0,ncol(X))) L <- t(chol(sigma^2 * solve(Lambda_n))) draws_mat <- matrix(0, ncol=ncol(X), nrow = draws) for(i in 1:draws){ z <- rnorm(length(mu_n)) draws_mat[i,] <- L %*% z + mu_n } draws_mat } fake_posterior1 <- samples_blin(X[,1:2], y, sigma, draws = 1000) fake_posterior2 <- samples_blin(X[,1:3], y, sigma, draws = 1000) fake_posterior3 <- samples_blin(X, y, sigma, draws = 1000) fake_data1 <- data.frame(y, X[,1:2]) fake_data2 <- data.frame(y, X[,1:3]) fake_data3 <- data.frame(y, X) llfun_test <- function(data_i, draws) { dnorm(x = data_i$y, mean = draws %*% t(data_i[,-1, drop=FALSE]), sd = sigma, log = TRUE) } expect_silent(l1 <- loo(llfun_test, data = fake_data1, draws = fake_posterior1, r_eff = rep(1, N))) expect_silent(l2 <- loo(llfun_test, data = fake_data2, draws = fake_posterior2, r_eff = rep(1, N))) expect_silent(l3 <- loo(llfun_test, data = fake_data3, draws = fake_posterior3, r_eff = rep(1, N))) expect_silent(lss1 <- loo_subsample(llfun_test, data = fake_data1, draws = fake_posterior1, observations = 100, r_eff = rep(1, N))) expect_silent(lss2 <- loo_subsample(llfun_test, data = fake_data2, draws = fake_posterior2, observations = 100, r_eff = rep(1, N))) expect_silent(lss3 <- loo_subsample(llfun_test, data = fake_data3, draws = fake_posterior3, observations = 100, r_eff = rep(1, N))) expect_silent(lss2o1 <- loo_subsample(llfun_test, data = fake_data2, draws = fake_posterior2, observations = lss1, r_eff = rep(1, N))) expect_silent(lss3o1 <- loo_subsample(llfun_test, data = fake_data3, draws = fake_posterior3, observations = lss1, r_eff = rep(1, N))) expect_silent(lss2hh <- loo_subsample(llfun_test, data = fake_data2, draws = fake_posterior2, observations = 100, estimator = "hh_pps", r_eff = rep(1, N))) expect_warning(lcss <- loo:::loo_compare.psis_loo_ss_list(x = list(lss1, lss2, lss3))) expect_warning(lcss2 <- loo:::loo_compare.psis_loo_ss_list(x = list(lss1, lss2, lss3o1))) expect_silent(lcsso <- loo:::loo_compare.psis_loo_ss_list(x = list(lss1, lss2o1, lss3o1))) expect_warning(lcssohh <- loo:::loo_compare.psis_loo_ss_list(x = list(lss1, lss2hh, lss3o1))) expect_message(lcssf1 <- loo:::loo_compare.psis_loo_ss_list(x = list(loo:::as.psis_loo_ss.psis_loo(l1), lss2o1, lss3o1))) expect_message(lcssf2 <- loo:::loo_compare.psis_loo_ss_list(x = list(loo:::as.psis_loo_ss.psis_loo(l1), lss2o1, loo:::as.psis_loo_ss.psis_loo(l3)))) expect_equal(lcss[,1], lcsso[,1], tolerance = 1) expect_equal(lcss2[,1], lcsso[,1], tolerance = 1) expect_equal(lcssohh[,1], lcsso[,1], tolerance = 1) expect_equal(lcssf1[,1], lcsso[,1], tolerance = 1) expect_equal(lcssf2[,1], lcsso[,1], tolerance = 1) expect_gt(lcss[,2][2], lcsso[,2][2]) expect_gt(lcss[,2][3], lcsso[,2][3]) expect_gt(lcss2[,2][2], lcsso[,2][2]) expect_equal(lcss2[,2][3], lcsso[,2][3]) expect_gt(lcssohh[,2][2], lcsso[,2][2]) expect_equal(lcssohh[,2][3], lcsso[,2][3]) expect_silent(lcss2m <- loo:::loo_compare.psis_loo_ss_list(x = list(lss2o1, lss3o1))) expect_equal(unname(lcss2m[,]), unname(lcsso[1:2,])) expect_warning(lcssapi <- loo_compare(lss1, lss2, lss3)) expect_equal(lcssapi, lcss) expect_warning(lcssohhapi <- loo_compare(lss1, lss2hh, lss3o1)) expect_equal(lcssohhapi, lcssohh) expect_silent(lcss2mapi <- loo_compare(lss2o1, lss3o1)) expect_equal(lcss2mapi, lcss2m) }) context("subsample with tis, sis") test_that("Test 'tis' and 'sis'", { skip_on_cran() set.seed(123) N <- 1000; K <- 10; S <- 1000; a0 <- 3; b0 <- 2 p <- 0.7 y <- rbinom(N, size = K, prob = p) a <- a0 + sum(y); b <- b0 + N * K - sum(y) fake_posterior <- draws <- as.matrix(rbeta(S, a, b)) fake_data <- data.frame(y,K) rm(N, K, S, a0, b0, p, y, a, b) llfun_test <- function(data_i, draws) { dbinom(data_i$y, size = data_i$K, prob = draws, log = TRUE) } expect_silent(loo_ss_full <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 1000, loo_approximation = "plpd", r_eff = rep(1, nrow(fake_data)))) expect_silent(loo_ss_plpd <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 100, loo_approximation = "plpd", r_eff = rep(1, nrow(fake_data)))) expect_silent(loo_ss_tis_S1000 <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 100, loo_approximation = "tis", r_eff = rep(1, nrow(fake_data)))) expect_silent(loo_ss_tis_S100 <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 100, loo_approximation = "tis", loo_approximation_draws = 100, r_eff = rep(1, nrow(fake_data)))) expect_silent(loo_ss_tis_S10 <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 100, loo_approximation = "tis", loo_approximation_draws = 10, r_eff = rep(1, nrow(fake_data)))) expect_silent(loo_ss_sis_S1000 <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 100, loo_approximation = "sis", r_eff = rep(1, nrow(fake_data)))) expect_silent(loo_ss_sis_S100 <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 100, loo_approximation = "sis", loo_approximation_draws = 100, r_eff = rep(1, nrow(fake_data)))) expect_silent(loo_ss_sis_S10 <- loo_subsample(x = llfun_test, draws = fake_posterior, data = fake_data, observations = 100, loo_approximation = "sis", loo_approximation_draws = 10, r_eff = rep(1, nrow(fake_data)))) SEs <- 4 expect_gt(loo_ss_tis_S1000$estimates["elpd_loo", "Estimate"] + SEs*loo_ss_tis_S1000$estimates["elpd_loo", "subsampling SE"], loo_ss_full$estimates["elpd_loo", "Estimate"]) expect_lt(loo_ss_tis_S1000$estimates["elpd_loo", "Estimate"] - SEs*loo_ss_tis_S1000$estimates["elpd_loo", "subsampling SE"], loo_ss_full$estimates["elpd_loo", "Estimate"]) expect_gt(loo_ss_tis_S100$estimates["elpd_loo", "Estimate"] + SEs*loo_ss_tis_S100$estimates["elpd_loo", "subsampling SE"], loo_ss_full$estimates["elpd_loo", "Estimate"]) expect_lt(loo_ss_tis_S100$estimates["elpd_loo", "Estimate"] - SEs*loo_ss_tis_S100$estimates["elpd_loo", "subsampling SE"], loo_ss_full$estimates["elpd_loo", "Estimate"]) expect_gt(loo_ss_tis_S10$estimates["elpd_loo", "Estimate"] + SEs*loo_ss_tis_S10$estimates["elpd_loo", "subsampling SE"], loo_ss_full$estimates["elpd_loo", "Estimate"]) expect_lt(loo_ss_tis_S10$estimates["elpd_loo", "Estimate"] - SEs*loo_ss_tis_S10$estimates["elpd_loo", "subsampling SE"], loo_ss_full$estimates["elpd_loo", "Estimate"]) expect_gt(loo_ss_sis_S1000$estimates["elpd_loo", "Estimate"] + SEs*loo_ss_sis_S1000$estimates["elpd_loo", "subsampling SE"], loo_ss_full$estimates["elpd_loo", "Estimate"]) expect_lt(loo_ss_sis_S1000$estimates["elpd_loo", "Estimate"] - SEs*loo_ss_sis_S1000$estimates["elpd_loo", "subsampling SE"], loo_ss_full$estimates["elpd_loo", "Estimate"]) expect_gt(loo_ss_sis_S100$estimates["elpd_loo", "Estimate"] + SEs*loo_ss_sis_S100$estimates["elpd_loo", "subsampling SE"], loo_ss_full$estimates["elpd_loo", "Estimate"]) expect_lt(loo_ss_sis_S100$estimates["elpd_loo", "Estimate"] - SEs*loo_ss_sis_S100$estimates["elpd_loo", "subsampling SE"], loo_ss_full$estimates["elpd_loo", "Estimate"]) expect_gt(loo_ss_sis_S10$estimates["elpd_loo", "Estimate"] + SEs*loo_ss_sis_S10$estimates["elpd_loo", "subsampling SE"], loo_ss_full$estimates["elpd_loo", "Estimate"]) expect_lt(loo_ss_sis_S10$estimates["elpd_loo", "Estimate"] - SEs*loo_ss_sis_S10$estimates["elpd_loo", "subsampling SE"], loo_ss_full$estimates["elpd_loo", "Estimate"]) }) loo/tests/testthat/data-for-tests/0000755000176200001440000000000014411130104016667 5ustar liggesusersloo/tests/testthat/data-for-tests/normal_reg_waic_test_example2.rda0000644000176200001440000005716414411130104025360 0ustar liggesusers?o?_]"B!)#J"%YEђʈ2Y)!NDDJ\˞ײ5zn_x?o<81tE_Ex8^#LJBY^ 8}>MD5Wh L2캫 2gRS02~jRs[`HVq茁I7j&Pßm1M 6F[0bW־h 86P K$֓@5&h1FuK0i֩8K$äR<[7Xɛ VwjIкc0QTn&U q^s`zT=&o% 1? b!2FVcjJr{0T_<}'f;{% j- 0f? 螧kaRxq7bH L;+d>ɥS3{nLz;&P9cA'-›]shoׯ`B $枽;GVep1{!aFQtXzj@;):L+ooHw 'h 7h0Rnt2-k+ym=Y ր,̧,`yμEQ3P/u wG}]L)#'L['܀`0y(Kd0S]fͥmI#[֩w> 7o`x@y=+_fK7C=zǀnE$yeyTmN`\vVɵ$nI@9=&~o;t;*[wiӷ]ZL =m&a3ӝ~2=bc{`b0Ё_\C:E"~FH;"ˢ}9Sɝ) Ux_Ftf*?]0(60B1s࿺a ?y+0%t`;\9 Gbc6(#A#8׸mfkS"`XƸXN#w6@]%1>lPcBZnjf Ru(NLfM{V'",c ji> -f=zQTS76d]R]"\;Wǽ¸'u60m=WU]KTs`<)5ޥ ¥'kt=%v 0fI*_IR*H/)OIig9y :`L>l0:o;![+9묹0($s$BS|Aen?>c oaDYkamFoC!0? @b j.MU Z)̄A)('ufEgQ8pXX `FٓC@;.vW`.*c\SuV{gDz3lv h!J.fp<) #śPכ}mz{Fh:УkWn C1Ji|@?ə0C?R0^G:3.d0:ߒ^` !=]8S)P s\tGHUH7_O؍prue|6fa!Vy 0׾s`jm;ޯbW*mkX!f =ҬD00.4& ĶXh*mu0:d|P9ydA!hu*Ns[U ů4SQ["' y9Đŗt4y LߍQrCc t7H/t[}0Ož1܀x=&FRB3&gsON}fZ_b4VXV#@p07t0\|0|ޅb![ZImX87oNF|h~ Cqul tF]@;RFP =af/`UPj[i§cY-0J\E'c {0VKo`TDv/ >鰶s6N?,Xq1usL3@ŅP>cpj5}G`(.yS:g`*_33As{VDb=ܒ ;s7p{f$9_"9\h{'&Oj킿?HgEږ^-0P< S_/B:ӈ7 E#ߍ? k~_nm@~Fso sߐh=3?@vmXlj10ݭ\{P  sOv*L DxJ[?NηEm@t=žsP4pD'SHoᲅi5@ N&f5R/!"ʳ=kO*霚㚁UμͶhgs.[WܒBn};z9?溲!}{ pfy8S6 :i"(]Q_Kbꐯ[ !=(=#/ ^"kz~6Hq~%6E^y OnF} K κh6Z`t&0\Q`Õ՚#`}Z[q~ s7'* ۀAx|<-r?3Tۀj0mg&&с#9K ՕoUM)A}|LÄs%02R]*xh:%jYho sp*^ԏNjL,015K~Fյ"¢Ɣⳋf~~`,hU T2BhjYg0ޭ+YHD>[<9|a(iJMpܮF GtTk/zA1LyAM h]B~hCh5keᤜQ[4nxOGdXEf}0kP] vթ5&37^N'~4XhgWw}q)%ز zo>Nm3  `R0^nz5L=0dxel#ihn1aM>0vo^V{сΛN9ljv~_ 0`hn{ZTBt;Kar[bUS->p&'b~]&5s%O)zG$zJG|Ѻ]qH;iRa֬ywngwdDE yŻb!\ˉ5Gf~<ꥎoDUAt10kp5ThD Pe66uA?-Dzп@yzvoP_<Lz?bb0m-awY`0n.B}1g(]+Tlơ3ٷÄ]IU.~.?E~O0iqlMC⫸~\lW;u!=7uuG>`>^qx'0e M=k Fʦ@u7Po;6D: *F ׈q nx:O-3+5GGmgAZ*Ƒ@)kTפֿFzíLI+|:7GԿE?zWK@6PY/ 'M%6V'-~Lh⧳/Xvҋfek=aRRV 7Ofl_e`|vŲ}ǥMy :NxƤ49`TfGٗK c#mi`lu]cYĢUV$L:8J4dEnf`Fuyƫn𿲫=`( y3Gx #ڜa"?~G `ګ &nsL?+Jſq``M=ѻo!Kv߉O?F뼬Zx:E}- MxQt+Tt;?+&cal_6*4O:!:h=뾊R6DٕpYoNxH =zP>&% 9`~&5OIc3}}\F8OY9QE8}g~!^:|0#WVFZpP7YKlJQ/=8ԧQ1[n=B8Z@oMC+Fx Ȓ0єW{hy@N{Q4Po}Y%-t{};ބtⅿVcmW 0湒9͏DSlDe_,L)k 4 Ε.E8{΢47o5B?H`]E~<犯@'MW%1请l sU'_=O0Oq2Lvp/In/0Mv2 :ZO#Y,2Zk' ~^qI>x]75:^gCbofypw߿>RsMB0gjJ&΅:0+?fsvp'ƌ?Ct 09HEatzK'`|mm0hs- Ư3꒮s^0VVmT T22$@*7Zq'#+Iv}S2wt;q`칁ɣ>sP0ˆI i@wQeFTWWNnV*]M8zY6~< LËjo"8.Qz&s{QW9wݫs-)<鏾tNӍOY9}O7U)50LF4>\:STׂ!{I* \#h}Ll;V ̕x/NZo]^aec+dUَkTGR=]v<>}{/J~̌NW)ȧ- h"0qȯ0Y/V5Cאzݹ ~̿{CpgP|:RTʻ%^`ki4:{5g*Nr` aݜk;n/_BEʞoRkJl+p[ȃ5Ϧ#Gn[bw$:'g{,Em8I?JGU4llF0\H`'= 1ĹUS? ~ vdyn' 1)}7Cs}Ǖ >4}m2Vn` I3pg.L ؃ۀI@6 zK#f+c|I\b]P~syN+ @=)a%X4~k`Wx}`7_Z_:smj`3b##&yS+, ?̼=߭n?6~S߾nxXE[z %7sYak+ҀlG1(6},KI.J3Cz#ɻ0奴K.zii\ O?cx\pm v DfwcxLO` %ԀpP_?Ւ3peSs͏`h25˟En*CHtNFBH"0{ᬜW .]2t /X,k6 }h|:pD-(_8 sTZK]>WaE}Keÿi]$kU>_ KMٜw8,`. 1tKEJ*|IiEH4O0^z pQgHaa]'1 3w6Nt5 KXj+}ow.݃#.p9D}sFTsʂ+85du:a /Ei9vn7D8#u=٫cp.wR1R''^vMN*c#$ǯ+B=[hNz1xbJ})ii%p?$WH`Yzَn/8n;#wgb ٟb(/rҊ]1<6t_(@8g{r>>Fۡ}jp%Π- pN&R0`7y`ap!=2;.z#ܖM(|~K_.m+8gi"epA_Opr/t wϢ|fwvP !H'T?aFGelai iyfGl0Jh?W7"KPQzoqXx =sD}e'AgGFe'nNiOF_[`T 8*gwѭfRDh^D$?v8:sƾy!8<"~ -i4Kt;Tl#]*r\Í (z`uB # wԯ8 1'cǧGπTYC}ޯoQ?STuG\Jpֺe4׶w"R ( t={R(S 05?'ՒON2+"Pk aÒݛf{`)^GNF p{xk+W7Þ'ruox6L~RA4_V l2蚻]dÍ<~ '2=;8A5\TP!,3aÿs][K^pJ\iEV0tZwoןX>4|֥;IF+l*! }58>HGR< ṌgSC f<_ZBq%R"u#kNup:i mnLM}jx¢^Qg g `1*y kPb,v|Q?Ssaq}/dY#L؎J1K:b[1 Qpq}x>ŇcL`QUrP kg;T\ s64{ " 9L2~d#;Q^γlw`:y؃)jZ {JpX<2PPp Rp:/wt2kK<~8~ΚQo=tR0K|ǚė2:]<ދpnS?ai}MJ_7 {_]жH7+o| 繊7x-鲡BVD8%Zo{ Q _˺; ȧ4E8y,.E+"ݮ }5;;붆AX[4r&! ؁G7cc%᷁{\l K8߀!>-R. 'sS aqJ k~AҒ֝a=tn8<")g=y=zV 3p3_AzSUIQ8σb񝷑^2-0-Q-s 9N6G|11$oTȇ[(o3K-I٠/W 8 g\0S^{Rr_lبx}1 YA8Ql'~kӻUF% _ag|ܐ͕*[bx4ӿrHYBh ~; *vn,`Dr0W{n}xk^$}h ܦ¤"=~7u#$4av&/)K! }&K_^g$&FZZ֬Ţ׻W `(U8a<1_>SXi |,kL@}#5yJꔈ/nΊOE0|]Hgudg (VeZ:s +[۫scƵ^/یuչܤ 3AK.ᖔ?.oãz(>mGԊFgs'`*$/Ĭ9~s>s6lIy{ۛ&-{N^2g"rzW[&"=܇z ƨK`y&q-`|Lxi6}z0?".[! `)ptp{XH#8fa+R}'=ꛏ>}Q fi9zPjNn:k^W+"_X$: _z*{A[&p71]9j \f`N|R?ῷ9."2^jYMTO%\P;7b2Lݴn,vnnEWbϮptw dwVl.2pe }TGoly/cOWVb(R," =+_/D ԿFߕ&b<~v!U3da z6V7~700rjQ z2 ]:G谤UI_$`8-C[0|8T!?W8/.KU7].~1}S,wՙ!270 rA"Xqkp:Kf]`ɶ$:˟A&;z{xO<`~,|Usl k]sυլ++C/p%/dVRM[_~*;ެ{5L0 ^f'`q7u"]MX|'1Dq)͉@3J&+9`neeuM GX]{c.$M"ݴD^(oYA1tX? PnKṕǀ=gf O?S>?,L~:;DChڮhKbGS𛛤w)/}q/)Ub:GoE>"]ȧ[. de,[ :m@ S43v"V*;|A }=읏x8[{#;sxV<"*e/! q*;(^zƫGk%pZ3-7+zWQ.2]zY  @T𭽿٨.4V-8{s9pf.`E v-)8y鳨vq%ZX2/_u%2h(c#n ѿ7p!)\Z˰n~ S@ da~G #߿":TWuJ! ;O!ovW=U2,$~eSy7du<ځk2Pv[lwXN&:ߒ*R{;2$XAzn]ޚRX^ܵ_Q_0 |XGHSNnFcS{¨O\<sS>`q.pB |L'Gem %$?1L@8*| J | LЗr}hu,wupĠd,n1P ҷW?ҕGM@$ dr@>w&D0k7yQ% E[1zuP|S@TmM/J:Sס&Ѿ5Jr\D˹S='\TC+,R 4ԝ@=Nł"~ Tl2d6I89o:kӷ}/~6'7&)\$ R }vpȷuCdP]+f{ЀT6|{T+?%TUzsi/́E Hw. X¾w=y#@9R? >msj;.HϞ`~(;2C@o$cb&tj+R[譨/W}W % ~Y> + _>)^6CM;ޥ^@zcw7zp۷M YA289Pyg:9բo]5D s'b/bmŷ*Go =3*'ԜBg8&,I@x F`2PZķki`#(gr[uw.68j>)4Ә@uiQO0f('U1F.(ORN,2o?ݓM@XKJ)  G_kzƘ Iһ)mg/_:H,I'ӎ󣠉&~/ ĬgmbxWP`E ̢ct@ݢ@wWsy: (I/`T?L8+^:X =QwOTQ|f'/Rsǟ\L7Y!™Br0NxWهx vt#*,S0DLL'\~?"1Y 7/2$TЀ9fw[@u H/vdwn= }ô('rP|hL'e(M7wޟ~(A=NBuĞ-&ZKrѨ;ri+@`z: d@O>?}mE]#+v7?U':HAψgzf)UP9n^%]@)t1 ?߽ ̎LY Sb [6τfbG qN4gg{.O)t/mHO,5}"Yg d+@SJtzCoBuK,t>%Ajᎈv1OrƩ&~8G{ %еM}^Kt>ض&+;re!C+ 4n ';_'dϷ@oto_ @63 Ki 7AW񰧧'}3 [Ηe e-DLG+(j/t?S{Y͹Tȋ7CAG,>g$&_~?;R%(+~;Go_ݱk[:_7 zW }qi3GAn@^T) 6Bt~@L%T.bᨏCď޼[AbhQ*P淵;N~AvHf"<佈mc ̥~zg}dq?bQۧr rF=zs,fxeN$ w"uuH?^ I!=t[U7f7oTo@yWqxuG|1 Q=p7z3f}ub?(i"sǁ@h=cM+Ţeŧo\p=~}P}Hcݏ<7wYK'WmS"K:)>m_q=hsmbn/t^pio݇8?(IkNDWEiC٢Z4yz|, Py~'a;'&]@ܜ ᦮·kx3?6_@UgS7N+6P 훋k}=C-kt@0"A_MS,N9.t= =W}r%yuu#F֞/&ρڳ@R  >P{ 4oǴ 8Yu"vHgm}+L\{uǣhƲv8ksib 8XGWWll9J_)@ ߾ Hf)6WYoK4_#-@ uZ1HbA~JhrRk=L/@ɣY@{}/~g p.CE&nf! :PdU]Rb 밡/C"TRLҡGV|AZ/);0m(높S ذ=)U|1G7B(~U?ҟ g?quSo=mFP Dkz&(OܰcSvACG|PGdu(uy/%+cTlʵʧj X\!KdWz!Pob Sܓt͠c퀡L .7e}l' ?xzmL(~-3"֍e+M= YƂ5%mʕ6C:絎/?͚2 [SvKscdW-_ F\AoL%Q%4g?6f=2EV/Fux2*oQT'Jǁ^Gٹ4yӗjEZb\U| R-?%v@)'s SH)؂xho4\u@|jSl^i*H 'ϑhcBo~mt@..;RMH?}>'sO'o~95V+/Ձ_e\swY,꯽+Uc=n#6yϡ7{?{ѹ\:U#8شN7TY룧7Q^O?və³ǥm@2Jv@z F@duL=ToWP@z{x/x!`% HOz{wUcq[A &( #=o5eu0zomL:՗M٠U _x/@/W?63-4!ҭ^lB<۰N,zT] 7x* :w4#8Ll¦'nHKzH |G]2CռՏ[ʊ/3ጫd ٮ|,h+^;|= ;S?)M4鹠tyWMGMo-χuMπWUPQ Q#AV}G}B9b_ wS=FD:JU7 +Gu7O)y."?%XU˻ +xtה#h?˸L6kkp6ﻥнX> NIins@*v5=IHݗy Gתd.ԟCmww%Hmiow!BF ~ku(?O _>oW;7H7@ٮe4V}[!C Z-(+7ogGceZ4dfTл+T g CٹMԂDBԁ S_˞Ԃu*@{g\5@L;ù ρ7mGHAv ɏג\bY<p.W <Ub6s9e\w/?WkR<Ӂp28o:Vo  /]ϳo@j"Q@"PDdxp|u0)y@~dJ)vQBCdE˛{BBPe ȷ7/ 4y'^zx^]AWlsOp+T;~-OAKg ;U_c{˴G› +,LQ)n~Dzp}BK:HĿ@$)'i K6 ])OC~G0D<*pҿ_՝Y }*?IC]8{Qo|\sL]kau ط<ӂ_nZ 2u1 ?UиOgYZSA:_ w ]B>G$} ݛ[gK $Ƚ?_Jajw[tT_< 2^ٕ/ʰwn/e3sCzP0iJxȢvQyГ{a%kf iG956>6%[yO>~xd"! 3Ba|5CuGmM[`mqnYL`gǴxk50,j)&Y^Î0|#_KÓn~:iTLp_הg ?|nqL}cba@0~p,|77 ޝ0?=m;R!0u=۹Wj*#OV.X{a0̪_'O0p7?}dF^,yyHUbה{~7"7%4tx>.;6<yY.%xw/_W.o5Qh=ay,ooX*޲.w'B5(h ]7)KzKǖ?-<[}y~?5t3^~>z)Tz~S#)mXӗu$yy^4:<6X/nqTuÃ2ǿ9dygXv_/]5a/>qhr˟ Z/ݲyfۧr&nZ~ܝ_|Muݙ}7)Dky=}NJW\=[#A}kQ-/*iwkŨv޶[{wXߟ󋾼Οc_cwb-dɬE2lĔG;-n8ySŽ_`ѬcîaKFf>;{^wn<-,cg 6v(aʂQkwugɿ~Gk7\P] .xW1gbٰćE̘G/qhU1K}iNڹ3 fck,Iǒuu.],ҩ}6ߵ;&&޷o];;Z{W_u_9&E-_墽;|T~Cvg[te 3G d¿qu043%;nϓ(C fa_=ǐq mhs"e(+4ūnWgP-*l\Ɗ.>WW׋A9fGsl7?xyfZ?s#e^߫ejg-W ՚2xMvw+ūmђ2xvkI[Z\Ղli-ok%yo-[خ^m(?^mWjAoq^3!^{6񟎟DݼZȿ+-۫ڻhm[fdnZ݂{-ޫA[k֬^-sy?%OZ2&떶?ZbǶֆhImG-?^-?Zcf޷^i oZ[ؑg]Zg_'-sλkW+5hz?Lj|oww+8V5}ݒyٖxCKc m/[~5 ؚ9>iixgna̮5<ȶė&'Y[|#6-mZ:^i߷&n-7] -WZVÖ6U[6zڽZm' .C[qKChiĖ-mmJk}3bvyygf-~*ڹֹ+mm}O&NBkߊ$>Zɻyf'-t=Ւ8OKl?n Z0/ڲO$ZB/,Zcu=ëja=Zwf'k?Y?[;[cϷ?nݚϫyE+ǻN[lԷkW+׉?Z9Zm{(h9_?O#@~^}9d>%}>ϗ1/}0~f2b\܇JHXoO /qw[!򲕼_fp{ Ңy{{^]c(HHc kc x!Oy{̂er;W\7_>C~bBN?q/u!x9BgخqkxBN>/3b0r<frAV|]~=yǀs;r~owЫyq|'CȁxDCc\[e>ܯ@q .K~%?4׼)"oPPOmP#&io8әa8#tvQ DuH )y;.ï3^ȅ]f@s8џ8t.aKoꍼx"^Ps~[z3}G(۷_# Rū?ns' wڼ}^!xB7#}@r3e. 9z0~]<=s4 r+Ke ; }:Tj)AUft 4jW M[|g $vaI~[ v!.9A57`g ֧0hx}f@Q~#=p.'_率<5b2oύ ? = Yl~}T>g.}&l9 żA [}n\}mףx}S ߾O-qX~ VWoFw8 qv=23<+Oz;,'s-. yo"߬L?'Gqo~($C_y}ف;xL&~] d"[%U+gu8~<e_r?rrąqcy>s g-V X$ur;˓> =(j(nށq>?6_&TW?\ӷ"a W|/ *-p@+u.w n3 s_@x>ayh(~ϟT={2{rr%t[ XϿ? op}c"/mۏlyt"ol8oxk!'kr>ل,y 9^3QQq+!~1~3Ũן7@ο u-/غ=^!}ȿsp\`oof y{ 5dݸ{$ @@U;,Ȟ~Ѱy/orhmzʹz,@;26!!o9y07X֣r7ȃK(o\Es}?ʪ7!O_5-\ 1~ߩpΧT~.>O<-ǹ+ >Cv~f[ 9c_rv_U^ Eb:jY#<}]卫|"o*}ÿrvXqwklA8zÞG?^̹]yPv2"cK}c#"/@4颣޹;/cP| )w~ oU']89P7,6]9Rp(5~~2嬅zT?k p5ޅo5㱽sCоL/#zy ԰鼼3փh;(< TH&9`PoMp畸lkv[m~ J^ 9՝\'*F B6E\ш-o?{X|>yk-8o } |$a/gn92 ncMVj7hE٨*xA$RQhdTʎ^I\}C!^_uV寜/%~_PzɝheM=oRGc2d^&A<ѐ6h-s.np|vS hx^#pZːD6 !ѷЮۺg?Y~q^B>x/Ӥ1ǗF.fBFy7k6߽wM^=3~J=? ?)ooDh馎yy~ pӘp d߿;Lc4:M׽Wc;>-󆣸:_By> o`=8џzf6,\63!k4!M}_?˅7/E{ \AĐ{y߂S r.;1u|J`JZĝ@Oz&w DB¹ 6o%Ow@ʗ󯻏wrC?}_*[ ?wxRm7Z)a~ xČs7\_K90K;w>7씅mCkgЄv ; kv8 Sύt:3DM k3y}?R^5{B%UP8:H)BzVgiyhGD~vl0pb~4H<كN{~~]-D=xF_f&~8A^;v '¿E;x>h(ڿS?}߾ ld- 󫄔 syZ9ߕvXH땚zy.logGWjrq?ѻx=zZJCח&s>7@h=_<` }~&-o! [!vJoV9O:8~Rwh7vs|~]5$5xDG'sȣ/y_ <{rFf]+ώc|xN[^ϩQcio<]p*^Ypz͝>7[Δ [ pZ~]<)W/>;q}~+//yj^xlhů_IM!o7'1.vCdoϿqC6!\G|z$펄梟/s8'8A9 39"^\=?]oL¯ G4'2D\"RĉezPH¸ ޝ(U*_nFNG1~n|FW_cj'pc jmuPŕkLwGM_Ԙ'A]=Ԡ90~~R_PW=pO8zxʏʏ܈dz`^ޛ! ga?|ߏۚkQÇYhr}4Myh_kq{u*?7"1rc_~#rDz_~PG O^eO"~'H˗# h~Eh7yW{ߧ@3"S0u;>%:_!QȽs8AJts{z-{ht%ϯ/$zJ >RW W|sO:[00<#2w=D<pKžAXvIw_a|&cw/Hϸ?_p펂occ?|?rY~Sإyρ{^> >?óï8}׉*D_kUO8țï7hr;.\CJ_ c$x+YG|BXG/b~vb%X`9#? }=Gp$F}ӵk9`|%of|Xxu9ڑ%7gWs;DZ^AI7a;D zȻ s+N0 BA$-n{p.SUs/&S ȹ6l߸Op)xrpyPVyY/ bߴxy^s=o~N-gB;`88߿ As=*8Sġ}}#-X70N>[b8TЏwz^଍A{&6;]b?JbϪ ~"i@JJzڏ5m _q KG#>6bݣ.#vm=Sz (~ׯroPw5>򠩋۞5c@q<}㸬^p#oP!V.MKq {b޽5W<ױ7Y H|qơ+Lc&Ad0NЏ!o=+wKH>?C\֭(P^! zf=N/y `\1 $^v+b|s汕&l7?C)8{9}+"Ñk42@G P~N8}J{нF-Pɧ ѯa>~?/`GnwiMD"uP؋h8I;%A*~,>C= -c~Sh[q<ɕ8?~Rm?2q(~V-f /}\[\g5S-1ΓMɝ ֔oPב]ejm>OkYokqop,ӗy?u4s Y|RsB \Ah>N# ^%R?YOov~Χ\܎\ >vm:Bܮu(^M'}x'ϴ!Vwzi+M}Cx=>Bw@S>v@ݘѸo=>h?eEߛq{?1^ r7Ÿ /SQW'ioHD$gT;SQבOWBD쐃7L)XS?fp=izY8/e~&Ec~ lxЁUOgn?M'^g=%vI PΕ=7 bźi#Œ9\7qlM$eyc{_w#/'#CѾI b'yڸmy8ȟpR_=w⺗}%U"~P S*obS8ƵRo,yl?W8㸬2C.U ~J ] {:v(~yY:-Ry__*_PAnyCi_vr{p5;eW7c/u/m!ZH| Ë>-{m\a߁nP7p]BWk69??@C1nQCKi0.m~ck0ϟo\_k!.m$> b#p}zbiz1^Pa;9ϫOVgWcU =Sv}4/b }qoUfN2^>3@-SJlC/all}+7i~T3FߍrV11?|C'Bhf>6Q~H%x]/́mÑWK3/O_p=}-ΛK_ŷ3Lĸ_]PoWwb5 aI:΋c\;ʫN5ohE'oK!\ScpH[DB}KWOuC>ѭCjM?Cv[IXk8Ɗ8>"s5/fvxXgžվ>AkD"E?:W ģ>d.4^+b:vN}^q4>F=G0~~Ж)^?Bpn9G:q|o"Hx ux='t{oC;c#'S]~E -ԁ$8zAaNxu`::]>_qs Hv~gFw=orЏ%u[~ʷ"|/Q: Y9Xݖk cs}nO<X9\cb?>7_A, uEaxbSpق: -)t{hH~?IvIC' α ׫j7GsϳYkEp 3^Cže:߇q_!w"gDߍ2c_^5m _ 5a|[{$go=/vgT=&t ;}8ܹ_8"eaxGz&iaSnm5'p(zݢS4__͟u c "^ :q?~q_eO՘FgɄǐ ~<y~S`kHÅ͊8J{gy5@ЃGs3?!N‚ܺpj(9pp97ϟvhLX?v]!x}ͽ*Q_> !d4j4=Z1D܊Im8[QOWQpX?y ~yz_p=8]yC'.G%߬|T'͂oݎAV`r#u,Det} B3-FF@/C$8d`ӳ>'}!{0<Bz/$㳹BQP t<话~Blګ7]w^Ǯu`?ŹU ~DI=kr08I>_z@XRG x>>QGu4 W|ŵ&_k44ƣwis>Ɖdc|$e m~!Br!w8IّL'?9Sıb IoލqOm;Pw2pnF[D}1[ұsbλlW!Dyq`N\O_{2a?Ž NF0_w'+7FQg=vm'/go: ;]Ẓy~5?vRԭD|5/o5~4=0 fAٓd.q}cx88ԟiæע~! uU(׳{qUŷ¾r hW|Vv˱oľfކz\3C6>J&~g+Lu.]ĭc'~6G!r{|G*8 m?] u ( ݧ} Jj~Uzّ0&gҼnvWN&C{#[ǢVn=_OʪF;$1[^iNø#nŷ5y11܇-:Cz=Śv:8zw U|֍Bj-n_+7<#1̺\rBH>M\ͼ]}{?…N#evW܋oBN%z`!c~VC=Oh΂*vD+]]|^ّ'/.x Q%/?~5Qdֳ;T<(I+\BՈ:myG??I[ܥt gEv/']-L2kzl8Ӝڹh&( ~uEimb7<BN~ uq ǔ|DeھG=n;^+g`H-&.x9sk; +q:֧e}ubƭvߍ3˵y6rw2ui,Mis} By6Mp,qa<Ȧ!"Cw!,l?I?byF\y)+<owpsO~DzϏ}}2ןC0KGҶވzؼʂwq!teoQ?h +ճڡ{ W1w-B&oXjǙkK8O}tiNؗܨ =|ƥ.Ě/.99P7g:y=+ YG} SB;~; ACY!XKMsx#uǤԨLi'?Kyʠ@vP)K~;߆LzL%o i79!_%snk('vtvLMV'D5׫. B}Q?9~orUlCqr9An';q߿X蒪mB}|8Ǖx}u@;<OX"[8t߇>g&ʸd5Bmu)qflߴwh{߷z>tSDAC nK]<-Z+ľCϗWF>F8g~:O=3pLzpv>@WŠp=D;1?ؖ6 (?IJ  \F yX\=ϗpG>aormOދ诗 {B9c8d:OMގP0FE@|/3!iY:!{Pq^O:lRV#~>-4\\wEoa˱}~VqU|['Q'xfXnVSlH Ȓ?9:F_sn+1.PQ7lʯЮmQӅ4 uB;;O˲` cxt$d(neo-QD(q*qoNGb{ݲa_ 1t sq{/d߂|kxiڿB'O=OfnRo ZܹdhǪ#?b?v9[[90%<^rSwOx8ǯh/ "XogY?,2וu'Nk>gۅK}x'ahEHu,xĊZ\%x&݆^v>NDEnr!?r@{<0=OC8RóO\~Ꭳ{w{ׇKn-8|(q쫵}8g@pM#D̯_'g:ßSPG ?n'uXŰ7j\}]'Bzˋ!8 pw\`?;lVQGpޜ=/P\ʺT>X#uK!`|{ jWnh'~X "_m\p}jLPڽ揊KJCq$,]p+tޚ^Z>¹}ies&ށ/50)Ŏ1xąڿ Wyw+Uީ]޿y=q&HhǾ5]p}M}ܫ{O[|B>"+Wb<&)Zۧ8kb`s:|{GxBSӵA'D:HDu>M3yCoPYxNbԿq`8^ϯ3Bްnƭ6lt^ZBJ+ڹ'ktF6йc 52 wxexIkx`cI\X2U̇04E/81xmXC!@Z~lZNKKma}ċs&9 a 0N𬐻!^[}}Xj yPƵD|4~6.E& }ur݈ 8 n&rV!ש^;Wnج?_%]~]BS6q1w!gF)d 9;;-t-q&"~vq GU;b|W6ϠBσP}|$7R`BIhspwh?g n\H2r+giEzXtj@j1a֣='T. E)X[(OV 6z}S]ts2qapL!-A|}s}!ߗ||}yxM>.(qPMS tyX Z}<2ת=>A=j$K,0EgBq탮t)h&NoB0>6VȶxJ 8ګ ]ENx>KҞ?;r_<~v]$WF^jLeuy/¸Y{PY#G'b}_qx`z;@Nx) :?i(M[øj,!ls; ^DxF8B}y7.G \/A-O4pG 8Z|7cK5w9:ߍi? RxOB؇L:*ޝ8s]@'=gA^M)ܲ`ߠ<9\OOǸpy<Irc{e㹾1d񼣃{ݝ(c}5x;1Q}ȽߖE@;Z5ߵO߂ui ~?OXˠ>ˉp/||8R?'aHsOc!+hG5N񼧤{w|S_;,t Ѿp_:@K% ox 4}d7.c^|OV"!՘ >QxS=X+x4ƕNgn.z&iïهB=s+t@}[u>h*>oh\\{力8T_N3>W&ྃs Δ] a;*yB|kG~Υ?sr0Μ*}{e9y(u1#z^9´>7 كu4G,qxtCH݂JpU?: m1W_j ;Os |$ u/RvRhHq 7Z;W<a 1(uu3]ASp+T+sGx']缲0U5~-['JQҲz{7Bw'oK_Q'WB> A8&-#ob?)Hq_*l['>6 v4 |t0b?(A<0w?ˮ I,a$ wq~/!#~Dgw K owK ŠK }5k|@=qs4]xִ~@w9eb2_sD~H=郏!OO㞻\Nમ4sE٧]WqLwG g2AwLzJM t BOq?Bq]{BUd \@am +Bꄆ_B'[:=(?!'$ sq/ܜ,>.q yaDžR&Ѯ~FN?usG>-r}S*.hݙoצ@ʉk|`-5[>/4۾ ab9ԅ^89{"Q$:){ WB}p~a9=Gp~Ax ύ"wJ[9 sBox$9|E8gjze׌1g'z79}DjnAYv%QiGݺ?#D|~ (f /q>'F~Fck:x.syڹa1B9g 4ɰ;s}ۉxޑ.u隸Y{.oWvm=ڷoMooWwrv8ܳTVv-ŷY񾃸_;o{O~J(w[ܷB{z6w-cN(~^DtϷo\;k#$t]r|q>ZDΊuԞO+oWM7_r{]>=DOQN%"ޢEiqSXpA(O=6S,ƃL1~^$yq}]hj:;y%9/uz4u|rq%gX,S/OjP-]g;(W8$]%'(;W^1ڋyK!Oַ7}Z~=8H>b|M}iߋ Mb5ωuqR+~/KKE}EP)-9߯NO]9;pNw1^\_(+S,'9#1ԋkޢ"?9|;y-K+.?;|/rԉ\Q+/Sٮr|wh/buFzϯ⽬Q$EvKSC7^T<b%_:\&|\~2_+Crѹ%%%d~r}|rK]"9+[&A~/ǻV{Y:9Dyz/x8#xQSW@_d; Ah'b~zOkU9_x /_ӜނD Il?'i9x^֯@\'_!緜roq3Y^r|K{\'}%oωru:E9kDzInry"A]r>rꜗS'y}Faޢ| v\[ooQ&iϻ NyXzivNkr4_"|v`!KJzjav(8(I7Ҟ&~M1};KJ{ q)7~>:' ~HX..9#CpD D\,ΏnN"癴%zo'"*~]O|MgQ.I_;KDWgv&auUK1/Ή=E_l^A'=i^%; <rފq[w_Gܿ_䜨n78X.ǯ\Gs ~;d*$q_.JJ;C::9O-S7q_?~&nJJ'~(2r}S\$)_^/y9*/9jDy]m]N::qxȧOr}_7vB#KW y?;Y{JC+Er~nAGў:.r]+!{QC}$Sg'87NƍvS ql/9]*E+&!X_β]~_}8,d@Gmr霕vr2i(O!## ~$\} 끈I~vo<>O|{ J;\St~H;V}|I nth3CsUOsV(a~މr5ypyDHE[䛜W E[#Y a{Qv丬I;Y_r~H"r=3OxOsuS_HPZgrREy-,ڡI[.r~y ^\Ci_vqJWӤ=`GWYO}>Ջ뻋q$Gj$DH$ۥS󸂴t;J;muُTb\Ix,o1eL+>"Cd>dAq)iHѝe@駊z+槴zuҎ2+w8#~[xv{nH;Vr]K"O x)}3d^Or^H{EAN6?2%r5x\eUryjWKDNqIWC.:i}_~zquXޯn5QFd\볘&{2n&~2W來hO!8/iȸ{d}z$GJ;aUr}>KArI[YocJCڧrՊ|=%ǝ@"] (a!cUڟ|?N:x?q{Q^iߟe GK ~ਗ7ht=< ^ݞ\VOrK^WD{ݯ~7"?9|v؟* ~l7ɡ!̢ܵn:/-!"ީoCs8*)/$~#פ,>z9&=%eL\c?'9'Te@?2\c3x~_nr=?k؇P6sz+/&ǿQo{}TOҏiΰO&}Ұ(/y}H;OrN]_#U,?,_YNx\-Ǜo Q?N8<ۿ q!5oχ~rNrK=mX些grT{INI=̷y|\H;rJJ?XPM%eA]9}NZ}Nr^~HBþ7qEQ/#TzK[eNx_x_h)zV`gK~/4aF{F[uG^I9xhnn\s=D =*a Oؗ='H;eЫ6r}`o7Jw\H2.#i6:e9+#y@_o:'˩=%ey\Y[˸EL%{RW-n>K=AK]lo.u=|rH D"}wC*/urKP~g}~LG&9@d<~A.wx!2N"%fiq(l8o뷴d"ǩs9.d\\ơ~Oy_ ,ƕ'dI.?GU帒x/ >XoyNB8_I{QƱ='|~t{R"ƃ5v(u~5n<ܕoD^XTW{YB(#YsI{]lm=Rci=$=iJTs?F/J@sp^@5:i-1ĭu`ȸd;}>}N2-CJ_'/YO9d2*ޠ7ү #I;ؠCq"Cwq oyCe9~{xԹqeq#TqP5ߌ {}?q]?%r"Ĺ0NHj_}I,;y]a z|'RӮU71+xi~2*海<$C?_kѮr?#x1+x;9_y)@?noDr}7"Gm?c;΅%nZ꙼侽~z?q@q '1e\I֥Ӯ+ݎmt{a?S7nZڡ}+pRw#uR,A;E9.2q_jKC/+8 ګl?A"bsp>< ^X2V|<ʟ6/ ,뇜 \sIcҏ_h_hoПT|Qa.\rq"&Ge'nHSvW]!!sϵ5 F/ߒGwztwpX[y C#1D{nH>HegU.yW{]`kw:'QOigȸH=r~t3?e(%獮vl'yIG^Szʸ%rI݌7͙ԝx'!/SjOqv[j0rY>sId.(6ԟ RRQ~YR|UtF}l=*ϻI.I9ڰE Rimq$-I;u{pnY\Wa8aԱmBy@sxH]f*~lCu>`o Z+#Q,#*ˣ |?[hg8"ɝ,' WPސ9r]}la}3xav.1ķd{upè4c\t}[U?o&%C>B> :zAWmx~>r F}Y9Xr 3eys* `9*|6>_F;HtjYA/CT~.XS6Qҏ룮K6r>X_gd[hWy%\C(1b|,R7(ur?yqNcEtsM=IIݒ!~*vdUY|\sL=PԹxosprH;Qk\/# CQsߪ0sggxYIYjސ:9oyy)._H=K?OB_z%'zXkX :5ɇ>=hἉr<M%G H?q\s d_C67!h)o^!.^lkJ<_!b9.թ2($? וvl_<<"ǥCNtWiCj2qf]%LJ?I('熝2#ԉv(j\yO M7_mZ]٠srtBE{Πinϋ(235K.74ak 3+pzϙ~Usʘ1w[2kьY v2fK|nA}0}Yfϐ/xPˮ̶KynP/C =RG&YaX6]AG_/Mˮ<`zLσy0=*7Grc*7rc*7rc*7rc*7rc*7r3L*7ͤr3L*7ͤr3L*7ͬr3*7ͬr3*7ͬr,*7͢r,*7͢r,*7ͪrܬ*7ͪrܬ*7ͪrl*7ͦrl*7ͦrl*7ͮr*7ͮr*7ͮrs*7͡rs*7͡rsKb S,a%L)0XKb S,a%L)0XKb S,a%L)0XKb S,a%L)0XKb S,a%L)0XKb S,a%L)0XKb S,a%L)0XKb S,a%L)0XKb S,a%L)0XKb S,a%L)0XKb S,a%L)0XKb S,a%L)0XKb S,a%LĤXbR,1)KL%&bIĤXbR,1)KL%&bIĤXbR,1)KL%&bIĤXbR,1)KL%&bIĤXbR,1)KL%&bIĤXbR,1)KL%&bIĤXbR,1)KL%&bIĤXbR,1)KL%&bIĤXbR,1)KL%&bIĤXbR,1)KL%&bIĤXbR,1)KL%&bIĤXbR,1)KL%&bIĤXbR,1)K̊%fbYĬXbV,1+K̊%fbYĬXbV,1+K̊%fbYĬXbV,1+K̊%fbYĬXbV,1+K̊%fbYĬXbV,1+K̊%fbYĬXbV,1+K̊%fbYĬXbV,1+K̊%fbYĬXbV,1+K̊%fbYĬXbV,1+K̊%fbYĬXbV,1+K̊%fbYĬXbV,1+K̊%fbYĬXbV,1+K̊%fbYĢXbQ,(XK,%bEĢXbQ,(XK,%bEĢXbQ,(XK,%bEĢXbQ,(XK,%bEĢXbQ,(XK,%bEĢXbQ,(XK,%bEĢXbQ,(XK,%bEĢXbQ,(XK,%bEĢXbQ,(XK,%bEĢXbQ,(XK,%bEĢXbQ,(XK,%bEĢXbQ,(XK,%bEĢXbQ,(XK%VbUĪXbU,*XK%VbUĪXbU,*XK%VbUĪXbU,*XK%VbUĪXbU,*XK%VbUĪXbU,*XK%VbUĪXbU,*XK%VbUĪXbU,*XK%VbUĪXbU,*XK%VbUĪXbU,*XK%VbUĪXbU,*XK%VbUĪXbU,*XK%VbUĪXbU,*XK%VbUĦXbS,)Kl%6bMĦXbS,)Kl%6bMĦXbS,)Kl%6bMĦXbS,)Kl%6bMĦXbS,)Kl%6bMĦXbS,)Kl%6bMĦXbS,)Kl%6bMĦXbS,)Kl%6bMĦXbS,)Kl%6bMĦXbS,)Kl%6bMĦXbS,)Kl%6bMĦXbS,)Kl%6bMĦXbS,)K%vb]ĮXbW,+K%vb]ĮXbW,+K%vb]ĮXbW,+K%vb]ĮXbW,+K%vb]ĮXbW,+K%vb]ĮXbW,+K%vb]ĮXbW,+K%vb]ĮXbW,+K%vb]ĮXbW,+K%vb]ĮXbW,+K%vb]ĮXbW,+K%vb]ĮXbW,+K%vb]ġXP,q(8K%bCġXP,q(8K%bCġXP,q(8K%bCġXP,q(8K%bCġXP,q(8K%bCġXP,q(8K%bCġXP,q(8K%bCġXP,q(8K%bCġXP,q(8K%bCġXP,q(8K%bCġXP,q(8K%bCġXP,q(8K%bCġXP,q(8ttAo7#fm%v7ׇC!|}H>$_ׇCe$_Fe$_Fe$_Fe$_Fe$_F5|M$_D5|M$_D5|M$_3L5|$_3L5|$_3L|-$_ B|-$_ B|-$_+J|$_+J|$_+J|m$_F|m$_F|m$_;N|$_;N|$_;Nu|$_Au|$_Au| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||#bW^1+Fx#bW^1+Fx#bW^1+Fx#bW^1+Fx#bW^1+Fx#bW^1+Fx#bW^1+Fx#bW^1+Fx#bW^1+Fx#bW^1+Fx#bW^1+Fx#bW^1+Fx#bWDxe"2^LW&+ᕉDxe"2^LW&+ᕉDxe"2^LW&+ᕉDxe"2^LW&+ᕉDxe"2^LW&+ᕉDxe"2^LW&+ᕉDxe"2^LW&+ᕉDxe"2^LW&+ᕉDxe"2^LW&+ᕉDxe"2^LW&+ᕉDxe"2^LW&+ᕉDxe"2^LW&+ᕉDxe"2^̄Wf+3ᕙLxe&2^ ̄Wf+3ᕙLxe&2^ ̄Wf+3ᕙLxe&2^ ̄Wf+3ᕙLxe&2^ ̄Wf+3ᕙLxe&2^ ̄Wf+3ᕙLxe&2^ ̄Wf+3ᕙLxe&2^ ̄Wf+3ᕙLxe&2^ ̄Wf+3ᕙLxe&2^ ̄Wf+3ᕙLxe&2^ ̄Wf+3ᕙLxe&2^ ̄Wf+3ᕙLxe&2^ ̄Wf+3ᕙBxe!^Y,W+ ᕅBxe!^Y,W+ ᕅBxe!^Y,W+ ᕅBxe!^Y,W+ ᕅBxe!^Y,W+ ᕅBxe!^Y,W+ ᕅBxe!^Y,W+ ᕅBxe!^Y,W+ ᕅBxe!^Y,W+ ᕅBxe!^Y,W+ ᕅBxe!^Y,W+ ᕅBxe!^Y,W+ ᕅBxe!^YWV++ᕕJxe%^Y WV++ᕕJxe%^Y WV++ᕕJxe%^Y WV++ᕕJxe%^Y WV++ᕕJxe%^Y WV++ᕕJxe%^Y WV++ᕕJxe%^Y WV++ᕕJxe%^Y WV++ᕕJxe%^Y WV++ᕕJxe%^Y WV++ᕕJxe%^Y WV++ᕕJxe%^Y WV++ᕕFxe#^lW6+ᕍFxe#^lW6+ᕍFxe#^lW6+ᕍFxe#^lW6+ᕍFxe#^lW6+ᕍFxe#^lW6+ᕍFxe#^lW6+ᕍFxe#^lW6+ᕍFxe#^lW6+ᕍFxe#^lW6+ᕍFxe#^lW6+ᕍFxe#^lW6+ᕍFxe#^Wv+;ᕝNxe'^ Wv+;ᕝNxe'^ Wv+;ᕝNxe'^ Wv+;ᕝNxe'^ Wv+;ᕝNxe'^ Wv+;ᕝNxe'^ Wv+;ᕝNxe'^ Wv+;ᕝNxe'^ Wv+;ᕝNxe'^ Wv+;ᕝNxe'^ Wv+;ᕝNxe'^ Wv+;ᕝNxe'^ Wv+;ᕝAx r^9W+ᕃAx r^9W+ᕃAx r^9W+ᕃAx r^9W+ᕃAx r^9W+ᕃAx r^9W+ᕃAx r^9W+ᕃAx r^9W+ᕃAx r^9W+ᕃAx r^9W+ᕃAx r^9W+ᕃAx r^9W+ᕃAx r^};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ};#vFѷ3ogDΈ}MDn"vѷD&o7}MDn"vѷD&o7}MDn"vѷv/v<wYdi3c^^WH"_H^-,W ?n=ZP֔__|owk[.^-l_|[KzZeKn}['-mvjCɼjýژW ~7{t'BFXi ^mdGkؒ5%kw+:ݻLn^Xڲ~]fjs4!?/yҒ1^m;6DKlZ5(O៏ׯklJ 9)~Pܱl &BҀ&\wnEl|(rv_kFp[lʄa>k)7 a;u%7AZu4vxe)r~g_6%w 57uu ţ^W˴Ǚ .]Z: ҍ =s3誯xԨݼ jޮ;T0o$hAOC@q(*y<!<-|||} 5p->]VBwx{@܅<`~9oFs< r=T 7dk۳$ػrCFBJfG,' 4f_+\ c/.ع~|r4r{| ϧ'oǯ aq|?B?Kv{I^+!p)I8a(~/Y7CP^ ,$oBs1X›Nb}į_Z j^-~~!=d Yvy( !4/03z">7C(;h߹|{vx+^ϋsUߍ;B|%ݲH-~ϬN9<9?,~=Pui~K|vkހoy9!$W_H?!K ow_2+!}(]^O!ycxj]5Ix;Yμ<b C"/\Ma7vO~vB.4qPt _zSo]r~+;BپfOȗ/^ uܜ; c/ۯ"r0'C0|P |-sg ^ϱ#ȇا!x![^*[_ӡz~7^ήPL r2+oNP}{'4~PWKhw.@>k H{]OEqi~®=_>y D{3JpEv(s1=y}/z/ y{n'&|Pm'P0=`ڿfԧe. *^<1e$.w8Ckx>k!p ^ (~sYwAQC9wXw܌ɼ2^ |-?‡؞]&v_[~UPor=g\ s)?up_? CCC|p,אy<ߓ;E( zޟ@\zYHO/@dU {?;y4mwyP]Ty iQu8]_=3s*X'p~V׭U@.!V[飐7b,o\M5,OX| >@ζ:,圥h߀|)ׅKD-kbGly;B<!jm%4!r7/DD;o9pgw.؄㻶,~-P6j@zb\&B8av=x _ŋ&u?7u124z3Y!ȗk*paX}#5s>az\o8 ^y=Al묬-qh_.y)MO"˫:sq00S[V ?:g b3 /EK Ưν?>y+yWv}ߖB;.WWWǸ{"ֿDHna]|M sG0^+ f|o!z^`ϙ{_ڹ_tf,|nWB^_<&PNpIXY|n{י!jz>\XD/G3/ I\AJa~7׳>KC;"$cö>w˧A'vBSj!B3B7C7__rرC_81xp.u-A{lGz ]a#ky}m|_%\:xBbXsȫUwa{;8R2WÀǐ;u<9T T5cjV,D$7 k_xXw,UG1]/==!{#~u[FO@{ky5_)kPouS_CCh74eyq>ߦBp{h} _a w%/쇬ݏLja l/#] o dMqۇ8 ^~Whǐs#80Aoy{Q: Szy}9{\Gc)h 3!˗'::q;@}RH~X4'?W ~Ð32\~vsu=pr$`N$Mc~SwTẑkނvܝd(~x ds2ѮwNqى\p]q~y)Σ^Wz~fC,~??照Jj~L^?qX sx{=qz`= c&uhw$|4xK܏w ?9n@QƯIȥd͟q ^/?-Z|#d~xH8g5Me1>!"N,gBUPDGT104Gt3r(L=vS7bU;iKPnحh-\{e ;4߀PG< AϡÅؿ%ː*ڥ`\HOC?GBK T~U~F'Ӌ _p= c~ DEt Ǹ_c>B{~ߧi;|Ebߠ݇Xh@?4u.BQWȳhֶ߮>yy'38q.G0v(B5\ñ6 VJCkȍC{+y~}!qǧT:0.X`\J߸ZcS&p=lEق߄q1)yrC?p?b^.9/אps(OFZ_SP^C݇}CmHm>W]0~#౏M8/= 5v90[p?w:[qBFqݨIbK{+ +_{bxVw ȹGs}_4׫Bj~6 0cK8qԷw{.E6}=^?p*ʿܿ\8^sƵVy> 8Dp._lF,Ob!tƏ8c^O K26 ^!$ \vM^q,hst.)8Җ_y@GT3 _= x_5;(sI~ hr۽"N8'JnG9' av?OZ;K6b3MIY\e/~!_<8wZK2 3h'u>{AFz)ǰ|;,hw|;{2.=n8~=cžNTi&?ڇ_Z~:9@ޤ(~=A۹tzrVb*WE$[:?r:w]~>8.ș6-O1&8 1^qxî0-y3[0oūю,9߹&> pM|!rm(CW`t[1nvif@pݏ{'|4\@\a*Ο;>_7 Rf'q~ Ax^ 3G_Br<nD!$DI/4{7wu|[p1Om [4Ӝ34akomymNIqvǠ`\ \5"G=:Խ/}w‰XU~߃}p&6ҭmO>ŸW}E֐~Mq#y=rO; l"}#h^GyH1/ ">Pcx>ioE_Dz^Oy4!88 G/:vRfkS_>v ;FznB?8;q| K_i'~ |1jrƌ}Ӧq9}D)-Zެw]+(e7|=I}@4-&%9æݙꍺM:~$dpܽgOž !.78Ny~. 3)b<3`#U7gw%x?v~װoL?+=CA/As|tgWNjr|T=활Up˟-օNQ/wo! _fk'/{۫}y=q}/M3oH>SmSO!GZ* 甾׽|+ѯR،R1zc!Kg^T>.]eyrbwPuZWCyRiVKR1vMS:3ރϮq_/kuxq<<}c@}AnGDܵU>Bo^,ikw~ƸAfwǿr8HF^O쇼ΙgJq_Jހq-o]y ~Z wi%0>_>{ P7M?R ,98 (]~^}up%??6ޞB+R끞~~˿_sxX_ؿ 2v g 4ݭy"nWf} gcdOuLC|_ID057~ِ5nlv;>:A/rVwD{6aAC/q,~an]~yb-!kqޤ^-1`"rx;'ۭI= Kq^xS^u%tyG;.?y;] B>{}Gb"pK\Bʄx2nP{o*rB\Oz_^(7V~i4?4ú?,=9zX'y-ѹj'!!s!~ ZƠpхku2kN/v_u xԗ'\1_>sx\Lp #ݞv9 בx;A@K 8ݳxq=?2+Nhqؠ< ASW {<.hOwïqԑxjl?}pABk?{6jYl| s~, S|؏zi:t,\OЭ;s5~N^7b~/z;yQ2-gQ_G+ ø^i8MoL\CDyO3H~=/qm^Sۿ9{͂].t`d[oxF@ЗQ*-P> 9so n1C2A~n}?~8w x;4K18߽<.[= ׃4L vKoy}>CO܈jk opMvЉS?{ގ*{j6: _ O&Du=|LC[KF.lV9p9-)fZ\y5{كx ]O}!.:RܗEuEe ^-| {>v)έJ#ڽO^aOҗb8Rǻ?:5խ;oz;-47];1N }7N| # ?,CVMo;=t& )pH͎Dg…?Iߟ">fHznSxj#߁FHO3hp[7E"ꋙ}߂Tԗpe# !K$@;pz+臖 9-U%t2b`] ܀;!_q|0ՍZ<1kF8y9{CmY]pp*_7 וLRn%yyůqnQ3 Ξ&sy[/Wù9t/O6]? i{EA%ޣGEd㿯|-[\^@283^5}3/P$56: Q7;[!g s"n;<!U?+>R)ĉeh <AY>=`uMPU{sฏ>ώ4?vKWcu2LW߂˘8wq xRV}0i'я ߢvvOsv}q-]֯q{ߎ>Dgoa.Xԃ9B? sn4BWkqΨ_IDv1Ϥx`5:vBIom{Au.t)+h4^|r* x~ztE{uTYs%B'\)"\Ͽʎ\>y^wdSv(yX1%󽰞`ܡAM_Q\zp F m[G?B,QmIBҍ.[h0F?+|9Ehτla_f7YcqŸOF;<4GFP0E5Xf/.,5nm7n}؝_Mô0ǽLkgoJDv γic^`+AG6 K?qBsL_a>`{A\O~3Z\&K1^yA~?|͋W %k票C*COɸ7qYLD]fȺ< W\ihur \j?&?Fe|L;_?S2ԟ>XO)^: dٵ6d+pd /yOHyE wgu(q+v\5E<8Οdj:ĴG8!⨡^vi({畫b3X`J˔4, r;x%݉BTo9C=<qG4|q:9>$A?3AW%qfGjwͯK3cCO E^>oyBX._pK#!SGXw+{kB'B4Pg4~oEt: x *eqk+}!s[K M:{/-4st\'hkf>aᗁw;qZ8._" ;@0>W/B*_du; V*S66/q r(u إhyyΐ}MGvl\w݋Qw;1>[ gku |آJ`ߐŹAS#q|wp.\ojHJ՞WK~W3&, q>=QˎIC>\r+o)Cd_ġ>E?kzq&`~}%!<_8+п>gʝE=!QG'l ihY?~J| s)z~:u0nUx >3kmZ{j!A LD6h!L$8Ovȷ~Qbo3}Lyߒ2? n¸|@_q \=_vtT};ylܖq>ϻP`zGq-ȭjf]˄'qm\\+8>v?R&]s.:KOs=4?ƝB,3xW\g9d?Nw+G-MGEljos`ǚw 9y㘰;y-C;WX\(rl+jګ+~b>~jR~ݫPwC(GqٸT}\61zwoU5öikbbwb *Hww% "*b bbb<ߋ1sϚ5짰.7x/룳 yeu^ +r)Z GR;ۨ6i]1o%{A up[gIxdli +`Byu[yW.ܫP׺+Go,ls# Q{놼CqICq2 T$u-WnS8}iUUa3[ץxf$Ndvf6# Fx*͛]lX}!ލ >IMoKo0) Xj ~ >5)3>Ŵ17Wp>5 C\c_CLƍƅ)yl0pQ:[4?]xcاS03 w~i7SbGƫySܮih C:\ϊxexLZ8>hBaݰT0>ւ۵- ڗ%<8Pykx0xЏ{3u < |a?ͅib6+wIUoCw{{Ҥ}fkou EB|_J zO+Z1)̻>M.K]2$2Kߡw+WӸ~þpx=pOZӎøZg 坥a{aܺwSi&۰/\o\ay|\[0iXWU:qhW{$NK q8C},|Udb xC7 :0)\ZoK7:_|!/ˇg{3>0o#7|;Ba;AFC,{2ǝ]+oJ˔> u[ڗ3`'-hleՁ`CIHnXuk~^jf]^ƆpɆx;4cKܻVX}<@Ux&Ӈ )A܇(nK%4?WHE}WG[8}  e= ~C' /+aVDy;? o+4ԏ@0ɺin_ o| yBuܓ ߗ;)G𲾧!F>2].f }vC;ͅ =~)|/GA*u[  3G}þY[8>W* o.)<7p# Kڿ!y ֥(Kݕ|ĥ7^]\G:iJ/ yZ#5/  7x5J}[!9ICƚIu=w1ԕ}?4{c73ϼ0\WVzB_#MמIHQ>+Xp'9mw.ܿS{i0 jx.{([YnIyw{ܓrwKd4ۛv%C6p7G} K2kϞ}b2![11{qEuhR\BR'C]"Ȕ p_ZU#{)~!/2!+iA R|}a1RV3_JY!0.Т b 84ڭm^tᾐxP*hgBzB7jhwr A- 6Gv=GN.~wǰwk9C-;x!|pwjV{0&{yv^C)zC} $#epIah?7J.mgvM?V>H{>&wn@&o%|v 2_5fYߛ2fp7׎ۚ3&u)ǟ g!nu}'Qnhړ#iFk&*jMhR;m [ۗc[Dwxpؐe-7+ m}.>m}Ә'xղR<Y~汰2Źmb=k~TSeTx~ny/ VB1qs''ICdž\ Sڭrp_ї?>-aݔdv~{G.ACoG #kUwuZZtgn_/53gs'~V|U,NucI[?Li ^â$hd [Q}!,X;|u2վ|ëO=f79"߿g^4Vn*jNcӕCF U- uOC}CqjN[7ÕCNub)<0gL~]'x̬~o:1gk׉Hl/*-Yp)y:l!VB>w٧҇!qPFfeM;ak8Fk{,WbҢ[fsOOϵ|o; rsBnC[s[+ٷNji#ڷky[c/Y|pr^v(?ms)og}|[UW_ _ꗸgq}|y~ܾ [io((xWz.o.EIqe +:i-|ײIb |Zt,SVo\n[w_\xd?!dp[:{Goyȵv@B}'ׅGWfv^% [96wW >ޭ%G9wJpwmNօ[ÚSݐ6ϿZ )Iϒsug==Y|xiT=:%DžDn|M)ǯM?_&Ɠݪ|^rʵ;nR7̂+A>l5<>QsSSؾZ)@Ʋ .wms&q-^CNA櫹sݔ3sF6A/^uO?b?s%>7Cy*ӌi{LYs?_֏ we.!#̰e{|Q{;M&ϜG;h+/lܥc~#s7,3[oj(it̉&/W~=I^~>V(hڮ:,tqH;t}LO_}}(^aP<?][p 㶛90牜ۅk<~auJZ%yBF/L'yׁ?/mE߻kۨ'?|"m 3b͑_ᵑ^ك 걗-jFVmӻ}X8+kO)|nױ7 ⑯8C1Xaf/m!Wr~8*o^V"՘%숸0/i]OϺTX_k1ȹ TC:̀Fc >?Fo קei#7|h5B>wk"g<_W3O6;Oڼ+b* l >^i 'MMzv_'+F(9O.pdh[4\q>WӲ߅2'ڿӒ3<󗜩OJ\kcy5k }+f+| Mм5Cڄϋҧ߇5m={5OO7;M8(p[7o]Ky(-O*=1^9qd9?y>񀨛^eH|v/sQ&㘿cE.מkrލ)jF/W#C⤜'8*]tJ>y0ޗnCZ[>/#*ř.59cp|~4~Zy SExGJ9]vjZ-[qJWycyYq38߇?ׁ?(70.K_ xVw?Ygy |Oy1=ek#示>z1o ahhuR/"y\|9`;9b\=i OX|혿ar 9+onqE]^[gu`GKCg8/8/Ũz|wB@pO9y8*gi[y8'Ҹ"l_/^Zr77h2aO8IU~jOv`r~ri)wv/J3\my< ip-s y/x؏^Us?SnwX6Y-MrĄםM͑=:mݤYHC۟5ZU-yaum)Bw,?N~!xp )]q\uC}cw1?5'}ic7<2g雾CU[3ǜr 旟?a>xKi~4bE~Z)-]nujτ+BnR+{zq9z_pxr~I/R6?`ƺ-o?`>&8^}#-]nXsrXB[v} r]8 wu)pcWCruQoKmrX}D,Sl} ߲NTx ~|c mÄY6n)mY΋-U)ky<x\:.}/Ε|k92|ָGrNˬUQ'smts;SdyX/m^y=#'\'qHa/Λ%,lxW^sc1?8/RZc3_b=.[i:ֿ k<_}? Gq/w}y 'p??v?p\,Oϑ81_y4ÿ#/o>cފ'ut?1&qH_Ҹ.?a 7r'=b?uZwbr}JGNxΆ|W8FIu#i=W/K0r)|Nqȼ\ ׿1\u"|X !8$^o=GC0?"[9I=]'C> y>r#=; 9Ix [y ΊT8.}'R ?7n//J㢼97{p} k8NO'!?|-H^wޛ+z.8u0<_?xq}Nq}SX{X:_g$σuueI a_p י1_AxMO8~`y cݡ$`=yzrKc 0Ob짘"O:yŮ>rByMp/KҲߔyox㌗&Uخ1ߒ;:XɆy=@pވXʧ~Xg$1??*3opVu)3p=zEcV^/eK7| 3d/ruSױ&~/>"<ǿ!/2 ۷by>yc}EQ:8_  wc?YxOk.hB?|˷ap\Oz5!c {Ș8ue"7$58X}#w8yx7R{[b<-`.]q//-?|Ɏfex&\/P׍㳜g^ o^)?NXw: p^ynuM!ȷYW?UY^\u\*]s[k| /ߥ6=|>x8S02g5Gߔj-aސ+qFIW,`|q۩kc8֡XR'dۣr~v m_"yv/J0>I}lma~z &!p%/1ίms]sbG 1|X|+ܮV~eK^9:8cyKD'aźο=z4?8a^l7}^hub{@ >O~7`,vA}>zny |{Wu:|NsDe!EqҺ9qp^[>_!ۮ:M*uJ"y=+O)#c%^ :Q('׉Iϭ_Ux 7n8?e*p=땸 5GvӦci:Sa]_Ac_K|/@i;u?yimo)mZ;9(i_|u\oT)(G O?e.`).,_^NlO؏ߊ~8WOx#Ϸ Ay}=_bgI%Oⳟ޸eu߆uKlov:XW|n^uUc,ic藢τy-CoHͫ3"~e .ܟ~uAcp>/''a?q3r"כ$_ ?bMqكC~fPvG}]9(i~%5ivgǣ7܎L_ڰ_[_UnJ;sy'>8yh!uߎ?C# SȞ?ΓsX+o}EGRRΛɱ1{^Qd<: }<'w_q'p~/{'|337R]^~ty<]X\> ֙0 #ӎE`'!XW |8ק^#r]7rJL伮h\su0Sa}h]Jq| ۳ #\C Ǡw[ _\|w|'lߤyMdCpu\Nrޅ8DC?2:̻HrEO8N`~g=8 ϱ!o0$y|~_|?Xȟ5zA;q_/{_ 'kiI|8<8NxYqփʕnlX'z0RJ8zOE짘cPtq4܏x}^죒oXQO~c ~O}ӏ籞ugɓϯ8iy|9 !r(mQr~M~πߥu~r 5"7S:PIw.Ckub^;s*<>/Џu"']ޢ ]/ d~'}ze =mOc;z4fx%/R#1z,O\?yցyKEg$ c$K8}\c&#}X@~<|p>(WrCy|*C8 7lX|7E!XlטG㸁e`ค*\F`?B^ ~}G9S87Ͼ"y):<-خp8WyԿe^O~ti$R]пy ^7wozq;<{}0+=`=%=|>g>>;ϊz%ΥS>"\{Te6֝0 9?6YOG77H'΁\؟/w^Wb~y/{8>X*Nc{C "qd/V}>q^2'1qH [/O|}y<JcXy G}"~Sc=|=+W8~b?|>paVˋ^l~q>e^M}:z Ƀ=Xüi_:P$ I@S }DY/3̯`ߖ[b˜<9!q]n8\<&Ҽ5?a;)yLX|09EMbC~zfy 9^X/2p:.oHJp{1_}E?b7̷qߓX_ngu:;cݟy=Kx8}:??'z.wz >7={]{=~]tQ/e>"1,Z<>q^&z;Hy.Wljzs`^W=g?/?f8a{F<[)X"X&7x֯TaJ=^ 쯘aY0b~ǘǣ ^)?1+ qzS$ "ufyI3A^b^ BZٰjIMJ+ x0?ü5p= ؎q'R>^$?yublGxX<'^(>n`=h8~b^`̯}/6GQ|GQ|GQ|GQ|GQ|GQ|GQ|GQ|GQ|GQ|GQ|(>(>(>(>(>(>(>(>(>(>(>QTm|Qp+QDł?Kn>T֭&-XdlMNJӺ-\Dѣy/Zl00ByPR3myD;'**JjZzC)EBOJJ?iOZN$`r &`r &`r &`r &`r &P1r C)P1r C)P1r C%P1Tr C%P1Tr C%P1r C-P1r C-P1r C#14r C#14r C#1r C+1r C+1r C'1tr C'1tr C'1r C/1r C/1FGGF|Ԋ:QDSh M!)D4"BDSh hLDc"јD4&1hLDShJM))E4є"RDShJM%D4T"JDSh*M%D4"ZDShjM-E44"FDӈhM#iD44"FDӊhZM+iE4Ѵ"VDӊhZM'D4t"NDӉh:M'D4"^DӋhzM/E4&XK` ,a%L 0&XK` ,a%L 0&XK` ,a%L 0&XK` ,a%L 0&XK` ,a%L 0&XK` ,a%L 0&XK` ,a%L 0&XK` ,a%L 0&XK` ,a%L 0&XK` ,a%L 0&XK` ,a%L 0&XK` ,a%L 0&XK` ,a%J`RD)X,Q (K%J`RD)X,Q (K%J`RD)X,Q (K%J`RD)X,Q (K%J`RD)X,Q (K%J`RD)X,Q (K%J`RD)X,Q (K%J`RD)X,Q (K%J`RD)X,Q (K%J`RD)X,Q (K%J`RD)X,Q (K%J`RD)X,Q (K%J`RD)X,Q KT%*`JD%X,Q KT%*`JD%X,Q KT%*`JD%X,Q KT%*`JD%X,Q KT%*`JD%X,Q KT%*`JD%X,Q KT%*`JD%X,Q KT%*`JD%X,Q KT%*`JD%X,Q KT%*`JD%X,Q KT%*`JD%X,Q KT%*`JD%X,Q KT%j`ZD-X,Q KԂ%j`ZD-X,Q KԂ%j`ZD-X,Q KԂ%j`ZD-X,Q KԂ%j`ZD-X,Q KԂ%j`ZD-X,Q KԂ%j`ZD-X,Q KԂ%j`ZD-X,Q KԂ%j`ZD-X,Q KԂ%j`ZD-X,Q KԂ%j`ZD-X,Q KԂ%j`ZD-X,Q KԂ%j`ZD-X,hK4%`FD#X,hK4%`FD#X,hK4%`FD#X,hK4%`FD#X,hK4%`FD#X,hK4%`FD#X,hK4%`FD#X,hK4%`FD#X,hK4%`FD#X,hK4%`FD#X,hK4%`FD#X,hK4%`FD#X,hK4%Z`VD+X, hK%Z`VD+X, hK%Z`VD+X, hK%Z`VD+X, hK%Z`VD+X, hK%Z`VD+X, hK%Z`VD+X, hK%Z`VD+X, hK%Z`VD+X, hK%Z`VD+X, hK%Z`VD+X, hK%Z`VD+X, hK%Z`VD+X, Kt%:`ND'X, Kt%:`ND'X, Kt%:`ND'X, Kt%:`ND'X, Kt%:`ND'X, Kt%:`ND'X, Kt%:`ND'X, Kt%:`ND'X, Kt%:`ND'X, Kt%:`ND'X, Kt%:`ND'X, Kt%:`ND'X, Kt%z`^D/X, K%z`^D/X, K%z`^D/X, K%z`^D/X, K%z`^D/X, K%z`^D/X, K%z`^D/X, K%z`^D/X, K%z`^D/X, K%z`^D/X, K%z`^D/X, K%z`^D/X, K%z`^D/ >+gF>+g&5䳖|֑$U WA*H\ q$Ue$.#qH\F2e$UJWI*I\%$q$U*WEH\"qU$U*WEI\5&q$UjWMI\5!q5$ՐWCjH\ !q5$ՒZWKjI\-%q$Ւ:WGH\#qu$Ց:WGI\='q$ՓzWOI\+ᕂJAx R^)W +ᕂJAx R^)W +ᕂJAx R^)W +ᕂJAx R^)W +ᕂJAx R^)W +ᕂJAx R^)W +ᕂJAx R^)W +ᕂJAx R^)W +ᕂJAx R^)W +ᕂJAx R^)W +ᕂJAx R^)W +ᕂJAx R^)W +ᕂJAx bW^1+Fx#bW^1+Fx#bW^1+Fx#bW^1+Fx#bW^1+Fx#bW^1+Fx#bW^1+Fx#bW^1+Fx#bW^1+Fx#bW^1+Fx#bW^1+Fx#bW^1+Fx#bW^1+%ᕒJIx$R^) WJ+%ᕒJIx$R^) WJ+%ᕒJIx$R^) WJ+%ᕒJIx$R^) WJ+%ᕒJIx$R^) WJ+%ᕒJIx$R^) WJ+%ᕒJIx$R^) WJ+%ᕒJIx$R^) WJ+%ᕒJIx$R^) WJ+%ᕒJIx$R^) WJ+%ᕒJIx$R^) WJ+%ᕒJIx$R^) WJ+%ᕒJIx$R^TW*+ᕊJEx"R^TW*+ᕊJEx"R^TW*+ᕊJEx"R^TW*+ᕊJEx"R^TW*+ᕊJEx"R^TW*+ᕊJEx"R^TW*+ᕊJEx"R^TW*+ᕊJEx"R^TW*+ᕊJEx"R^TW*+ᕊJEx"R^TW*+ᕊJEx"R^TW*+ᕊJEx"R^TW*+5ᕚJMx&R^ ԄWj+5ᕚJMx&R^ ԄWj+5ᕚJMx&R^ ԄWj+5ᕚJMx&R^ ԄWj+5ᕚJMx&R^ ԄWj+5ᕚJMx&R^ ԄWj+5ᕚJMx&R^ ԄWj+5ᕚJMx&R^ ԄWj+5ᕚJMx&R^ ԄWj+5ᕚJMx&R^ ԄWj+5ᕚJMx&R^ ԄWj+5ᕚJMx&R^ ԄWj+5ᕚJMx&^i4W+ ᕆJCx!^i4W+ ᕆJCx!^i4W+ ᕆJCx!^i4W+ ᕆJCx!^i4W+ ᕆJCx!^i4W+ ᕆJCx!^i4W+ ᕆJCx!^i4W+ ᕆJCx!^i4W+ ᕆJCx!^i4W+ ᕆJCx!^i4W+ ᕆJCx!^i4W+ ᕆJCx!^i4W+-ᕖJKx%^i WZ+-ᕖJKx%^i WZ+-ᕖJKx%^i WZ+-ᕖJKx%^i WZ+-ᕖJKx%^i WZ+-ᕖJKx%^i WZ+-ᕖJKx%^i WZ+-ᕖJKx%^i WZ+-ᕖJKx%^i WZ+-ᕖJKx%^i WZ+-ᕖJKx%^i WZ+-ᕖJKx%^i WZ+-ᕖJKx%^tW:+ᕎJGx#^tW:+ᕎJGx#^tW:+ᕎJGx#^tW:+ᕎJGx#^tW:+ᕎJGx#^tW:+ᕎJGx#^tW:+ᕎJGx#^tW:+ᕎJGx#^tW:+ᕎJGx#^tW:+ᕎJGx#^tW:+ᕎJGx#^tW:+ᕎJGx#^tW:+=ᕞJOx'^ Wz+=ᕞJOx'^ Wz+=ᕞJOx'^ Wz+=ᕞJOx'^ Wz+=ᕞJOx'^ Wz+=ᕞJOx'^ Wz+=ᕞJOx'^ Wz+=ᕞJOx'^ Wz+=ᕞJOx'^ Wz+=ᕞJOx'^ Wz+=ᕞJOx'^ Wz+=ᕞJOx'^ Wz+=ᕞJOxEvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFvFv%ەoW]Iv%ەoW]Iv%ەoW]Iv%ەoW]Iv%ەoW]Iv~{ >*Ս筛jɢusi}(-"CO?s"8&߽^ 쫏'=d}ḅh~ݬK^G&<^_6÷cR1soxGexu:_W0i>l(5E079a 8\2s *1ڟܻ3m'&dGJȋ&To5^˿`Ro?˙ދJW'G?ZA{ϯgMs"u<>^/d3 ?dC_'󃁿[ul/׭[8SSqgkWq>v・:cj}1 <h>> mt/9_IC|lم_grxT/,;UX>Jw?q2lk_ѻgJpYǀ;uzw9>Wap7x}ʓ =xyr>a:䍌< xZ;'\EM&leO嵶 >oXsx^3N 5۵9s]C jy[]@՛*^@gno1N.E{oêDf{ο'L>7m•pj.k%B磉.Ż|Ex{7rFe`\h6[x/ߩu?ٵ>;F g{8}#J\25曧ms v!p˪[更fp&zCh퇾=J=ǽHYg!9Q1%?S/&'8uz_Zbfg=jh$p JZg:X3D7wS2gWQ)t*s>GBi~??!mqk 'nW]QsO 9l:ev#a7=5tæ}-cq=;%aǻyZ5ߊ~ܶSF =g0Op[ +j[s_T] m{r<n6R*g@~νEB4tWdDdX'gt m/Jzd9zT-i´CS!NpfKImԪiL2pjл\jQ)kݺl(1F]3^=p x wi*nG: ~޼hGh:/o#~>S~,>ի?zwpaW's^.)}GZ_wΦ[Gbƌˏ'=ŗwȝVT{3l}C oS{LjSٵs ڜl3o3ߛx0JQ3 &t^9H7u̲C_  G|W+SN{w×snzgjmjV~A!kCf6f]!^Y{_ԶG#] ~,aW;4 Ye<ލG̽"os?pE3 r6~upQܣx`1,7[?Ӝ{AIu _ښ7у] rN3[Z{?oʃVu7n}pD]grJ3!mi*~$8st '=ێ) ˷lv΁ݥޤS{֪,|fԮuޗ)qC~ K&__[:K;>G2pY|di[pvSBسe{6v-H*V ïWp~?q۫f.n{W^n>7?#<>2rspqQ9/|]E<`ݤKQ'=,ʉ_('ױ9f~4.#Mm -F%G^zhlZL`S8nL>Ta{qYy6j:VjƔ:ɝ &aDr8ڳwmz̳[ܹ|'?7ys]sNC~5ɯ&s,<==zCdpsJV7?/?eUL&q&ל6qX=}l6j93쾝9x~^Ιy ]_ƶKuZ\T-1F=ԊԄhvN }1]ݤxp3s&cxChVYm!䲺S g) ͘eY%wѕœp垹BlS>twL!xuVu^@T2gqY}~wטI½% BQU6e@{~qopnⱝN+7kakyO;:-1 .ǎvnA}e ;h)f)Fk/{3.{ p7ϟbM;qƘmma]s_gp;k| 8y㙤h>wY1$pKxZqlä|iݷ;r|66{.=uK}"M6^ ?X2.3ߗsС3CC~ci"{qaA3u+z5vc܉L^GLrԩ;uMf[Hm_s<`S7t^9"; &Uݦ{Nc팝-7>= SmK3;:{#7Z?50`T_dҥFncJ5uU~ t-s_>dMhߋk x:Ӫ/ܼ-OC`{uz}C0^o6'3}nHNfb f^zLJ^~9<{̱jyhX7pg.=r]}.f3֫BEO&}8Οg^,]ھߒQǡC˽No1RK{ixN A5 +>Mҍű gu/3+W[GigLN]Kn1m}_-:[<{b;Yӽp{ѳ">x|kb8pq+ᩦ8z+McVp9y76OKmǚ^4˝\uF_l;t;zvIRɃ3/.W'-n6fu08cR*o,;~3-_ A>Sgçr`ύ=G[Vm9׸'^j=|6%lx|C scOn>Jb :?jћ }ӕLsV5t]L[y=ӒM^A ck/6{WhqO] onӓ ulܱsk/ҔGu]oY7T=J_=pܭaE}Z~Z iʕlxgy!~jϭWuu5s/#͞uS9[ k|N=]UW :{qwk36<74p4~_ںX-njd6wy_e99]jxăҝ7F1A68!66+|/{fdʤN- \ Ry.M|'?370ac>l҄-`Wa_ z8?c\~foN`3y5ݐLmez硛GIwZ [=aʁCuu&orO/?_~']yc:پ|ޝ/Xiܺ9vnMZ.Ӟ:(/}}f.vVMZya=SՌ >k<ӧUe&r9>CPSy~NR{ۛim=:,Նw6Sѕ6NW/)*lS z"ߩwZF9=p V<^vj8.UՋ \%nng7&Xx/m՞?/8vFKZ[ ΋{Ui)_1@nop6|涯UO8"4Fs&qf}dO=:paץ:w=}#b~pO_&}gae!C]o\ tU!l~|rW{}|)z鯴reh7X.jwhp;439|5/wrǁ#o&;M͈0_ O#jl;˱t{f(iw4>ww4b;-O˄Cjgݳ[|Ll 7i캼],}{wvv)~YoGuV ^m6[lyjO7n/!9+e-xV-u+qoG Qmb2[\^v:̗km48.LZ/x)j=婦8]}۾>v 85+km 5/Bkeh Sw3[erFQUsk>mKoF[~Ii3w傊̄{Ͱ^>1mRD;/3nA9p鲶):r6D\G'NLǍ<a4گ.3oյMHV qVm[ߛ-{T0fopܧcAJp~sgN@Tļϟ[ \"٤Cofkq{!n>k#0\݃L$^sny1c~G Cz}qFe@e B ~uOTJrKFϟхG!y=s8lKw#ϯXv\PO4Y~j|6\}GkqAZ5"֪GB.1 3UiqCA-x`SSn!יvyPVqǹnٳ*Us;T:?̶ σJ6k0o oEvu*k9*}wb'YKDgl[Xp.6j*nR@[}pcM`ŞU_ KLW/x?qiyz_xlP{%΋1-owe6D;Z< 8݃(/잩iۭ <)n}6쬿b=UvxV/٘sO>aK|vŴfwDŽ5Vv9T.Fik;}VyLutnת۲ő{>~_Ӆ *l)Q^ !a|h⸡xpZ55k]UJ N\7鄂*SÃ&+7h+ot`kh<`^럻OAn}9OyJ'u) i5Ye ,n37z1I DL$/k1]&c`r'+֖Ƴ!(Q6 " 63Z5.z ZKxZv6#UsA:كU%!lMew;wxQU |񲠞ݿ/_mvF-n N%%lYۺsQ;&T{Ӆm%޷[κ@㸛\d''y7pt;'xW?;Nuz2C{#JYU69flk+sӘ~mQm~kYeN|2ޜ!旪m|mBbv?/ãJH3o|BeV'NUzr{MTc,/̛b+նѴYb9/lRd߂wr;[CL^%ZvNσ*ӈ40Ts^[Hqq˹I9/UqsJNkU1!nn|FMvK-}-œa٨5ҹk7gt\N nQG+-vhbWֹo /Zq[F~IxܯeFo^UOd qݒݎ'U,4_3aw68yMAp߄))3pmjR ml;>njm!gmږ1@=$'Vh R}9O>ҵڞ!x5M* ~g\mAc6͹U)V,lCg7}d9a;[y7aVק[Aٹ{c'Ab\Rf}n*L#pS:o>:YZ Ў_K7{J_[\~Y~`t,hWnq©j~"l5it/6uѬH|˄A!ڒoz5KVv_i~-u=e6̚l qs,Y+^:_pʏv2w5U3~.],΀]*fڸC7<._~q_7fuάh峹ڈ}`|,Ƕ\b1uw}ăQ6).*hqUԪӃp }阣͗ƷwN+|3LZqO ?ZF3n뛵xP!.FW U+]ʽeHw6n=hޱ1$[cVnRFbn\)P?}3?Kp Q.oH8?=\CFqZ Wb8cc'Oh9r'YwJהx=­l-܂;Xwsg;HN%\:Fnm٢q_=bCXW~sQa `͵D<װgǺGM=*z.=Ç[-[R\rj,7|mqe_zn}3{1|t~$ik޻Z7XţBSF)ܒ}=Zu} O Z{# z~ZBi7 D]~v{:|aap<^;VT1 8X=7 ~vB/#672'&Kv3`}ԮRT)j{ 5!l?IwG^ ͚;!rC_7nXwtmR77UTrՙնVͩK/7-wy nT?Ԭm+gxPlOb§.6sW=ܛ!`UZg C[+v42z ͆N.CV>Z6YO[Y.^QhM\TpX<{c>iUudpmp^~%G/PnlKYzI_I1-rmZdq,=<]7Dʌʟ߂;|-c+V_QUˎ'_`G|77ά17sȃ<`Ǔi{k [.U5ِmBgZ]Z~}]?e;v;5w9_J'3V8[xtNjk<ؔw*@qsvFp]7LY硋Bq}Û-lUi%Dv0k;Di~ϼq 8YjUnBYlg`^eooǖ;\ };;6ʦ/9~NlgSV]1ƫjiF#]78cO}]pKj5_pwژ:}ZK All&'>CLMQWa Qu՛4ǶVϭz4nwn=* ǍokFj =+* &e6k, n߳rǽ?_!FA~yV--;au۫m }L=ԛq7Z ,`u+M,s;j^ Zs%u׍ Cfăږ}ºjxv,k:w4rQK!]9-wk /!+(}5{A^0G>j!ŇLCԼɝ_\rVsޫMN=p;oT?P ^ 2[Vujq[C@p-mv6QF ,盄y!\6D̶Vhh9q{%U{7<4Хg7]c3pط93Nޱ?*0[1~QKvLN9`08Ǭ8X1qϹZebZ]0s*k͵z+IJxhN;ۻZtGBW8s{~m_cۋ%fDcn1 y>oS+%L%Q~ܿ?Q˧ 'wKc_@r[5Ny^^~ػS2\w41Fy-K3n)18ΪbM?;;;E^m%w=6.ӗyvs{`mϡ57‰W&#| \|n$5Džҳu58_UXz/ݷց'MtlCҏI(=~].<_VK{xJd7K~?.u/Om6Jౚw29Ǎ0ћjN3Xm[rL*kS l'!e+]>յ e¹:4Z̊zxܵ] xR]5 kuo_y\eîavwq)Ǭ^cz1msJFcxk;\k4[~k8j޴><<}MƇź!$zms&<(o ,pyƌGtX><ߝCÁuJoƣִ0rK gXܖ{wl~௟=?hfbؐY&cwy3k'A#ޡ{OCzV[ˠVk\2~`Q1aϩwypCncҍwߦqAFk;֦%^},yl뾪cK_SC/Mq=߀sY2(/̣F[m&52z&誜p ?m}P k} _uU"۷<lj{XӴFϯ%_C ϻU?4~C|Lů|9{E"&.{k"XvP~iqxn"eeܹ1o!\>\s8kYǨ+dlrۭ}!F!.?|n~]<z=[Z/mi3jy>E խ!b~*nW4QÝnF po >ʎ]PrK>c_%+cF~HC/7u iZw=3<ՔЬIm7G[C x6Ű64fD`%?aI7[񝦖=.XW{;N^[*tM~V!>NQ;+]V\49b}d7htԡ\;Q-p?w]Vaƞ)?} GrCa1øyrCeՋSvx H|`~o>v-W2 \ΨQܘ=}ٳ7zע cyA׵~3)N3ǪVLb㥞`2Լͷ0N۳FLcofo5 nMg{Q03;6>{m>A}nO|w'ps`c!tc!vá>Ym2zO7`;&iłv$fw V< T HvHIXbRǏǹhZָlh׬Z~a{ac*o$s]']I WG^:S) gr#nՍ<[3s<Vgt5'Ar𪠽=Y7"mNbqUG>>l%ך]is'6~ ,y Lj|g z%GVEw77Mqgс{mm MyxRFQuZyl5XK]9J/H:c { iw]z{ccK`Z)_xCӵ6Dkx'Ԁ>y^!QY&u b|[Mܤc[׍ .&GIfgXG7ővi;G_wu%?;BT$+hE ("QH%QZ(+[{o++Hµ}?py_qx>/lb@ 0OվWeb?+z- e^KKl؃&]?A5㮶giPb1ccDvǩPL+уNj( I C #g!n ޠ Ba}kP~Jj>%Eyz W}c3VG1Z 51(,/;.U I+ }wFzK2pDV/PEDi7*S%.- 2-.5n~@`K}Vǯ+ i .B`OkGXz>nL6H}*tz=_{ eYŒuPoR%֒e u vy7Ilt!|뜨ڠ>N N-%U(+!;H yfJ7?Tp%iJѡwL#_U7-cz0j<rXMaD)lBF|c-!B1ozxI6T9ȺY蝶*=)I_\_ӆ*$wU;ҥֺ{@%}im͐# N=Eh"}eQuZ+jrk%{Ah'(UKfZ: 4 v܈䟍|^ou*j*6eRbGkNmXxTEKmGJ =rkG̾롔SΪq(/³R1(0oN5mCsPXI;nCMiFK" NY]К|I[)J5*auXp}ݠֆuQUɯ;AW\'PaW3Tȭq:"W6Eנa*PRSuQoM濠VzY94c~Rz՝攗ᵴ1BZ:mXҙ(:juɪg |2QFb's M_zzv+Ϸm پ@=ϫ߭BkPA&BHM]A-62]H)1sH6 =bv *NA1x3̃PlYIr|ACmhT{ _sFQ)zQ#I2T4:܅3;à^Nd$^!FBhoҤ2P/frHN7S!orrz Զ C77kz:KoYPKMb>5, U(5j-q™o #-rD~K{|3b«>Tz6*v .}C+rR-aʗ)稉|JƟ43@WBs!cңRдvr*O;Ub*+^rPVdN:yWyon9<^# ~' ue3-OG '?j \=ituBW "BB&-QMXwgʚc*u}LTFYѵ(\uXX+5@SOosa5ZoD!}$uKs:7'v*~ F*;AՉlrHU%˛y_'imah;nJ? ~tgD7K%9Hu ~6NB uC凓z۵a=AdbQQn;Pglғqr~J)#qy`Ћ5;madCqy;PƷ[.T1]硥вY[,YPjO(24]j$<?{oFyGwAմGd&= ~2V _TբJQq<^,; iWآ@!i廩zjh:b '?n髡&PbTQN|/oQ)]ן 1ѓqnVŇ\@ޜ(}sšktְm1 |;u+ ؙPH41Vb>BuZhz+w8y Թ.oT>M]B)AeI3=}Eit RYgI&R롨_s($qxX7fT;Bơ$>wLB]>b1W ]s_킗noxeKEeGxYn'd)^8!MO){L+*aVRZm+5zVhψ}grh> ~.z<6-B֡(k/{x=^?Irg涹/Zmu rӂP=}[ZYPGW۶Hg༔r6S]Ik]zcy:|8G=~?H{/Y4lrGo* 5B͢^g_zcKeDNKXj[XAabT_Ey#G&r^VTFK= Ժf&+oE蓼POXnuWt0jJPIsҾNWcA!%TEv}~9r5{}nޤdhIHA7.: gM@1HzzYhF6i ռ;qs'Pҋ(mq3G8z4s=& M<S7X ;^HG16_(MP)Źkߢ}>+{֌x(\w* ,ly{ >¯<{^:j?k(EzXb^#d|e*r CWR mlRekSjvAq;G!-ކxg^~}P<#5["~V+8f˽Q~V>ܘȪX2]ΞDeEɁs`Pĺ/c41:nS'K*fyIBՊ2!}n{C[M= UctHZeHX|D5ф2HC䕓=NO QuCogx/L8/B䍝DT%Թ|iz0'LZ~GMA LXh:pP&3iZ/m3/$|]I>lQKphJ=^R~N^ QDEwCIl|43Rm >%ʏ*7h»Ƿ֛x6zv@~1%$ 5;8/CӿFA6!]?jX* GZx@Ƹ : riF(5oftTɫb#{o- gX8 QO^lE-o# #Ƌ@=ގ@@F}W _nȰF:hUA_eM!WS*npD̦R /=/pv+zˆg\[QVv{!=T$#(Pd3ms^26ëBK"1(mcF s!5uU( и, },̕2?Nhȶ(=s78 4Obե6a<O<T?+P=kgz]Ty,x+袁gO]EJ#6vHXsnĽ9 v<y)34TU?$k*yvҶU5;Z+KQïS\Xq;I<5"r~ܦ{ u`v8y4p$ʺpݔ='!R;jڳ8,TD43kBiY e Vg@ eI R#էS EN>Åw)zE69cCer׮rM)210Kj>V#9¥QP^S2d&We*'Wi98cGr4P¸L3M%Ў.1 io6^g]B_̫З$ߟֶy۬57=$)r|BAngB{=TOoe{_߉ҬO>J!l J6{z|jE)2ePGX)@=?jd cV*3a<@6|2k`ÆLVԡfYi7`eU~=:0zPn„(NoiOv{,F<&C-ʋ66dw4|: 9VDsP|K8nDߗ@=P0Q[7ʵl|9XS.\B^c"3m!#ι~6wt*(fEyN(/pU~Lzuݛ>DZ c.P%nѵZ5Pø?8unzw'$%b%!ps C'N4Y @2y(R9lGQ9XL& YcyEhJe;i oj{A۴ЩI3/(RqTؕehA|p4msW2LyvRzncBY<\CsvtEAEie3i,g#sE,{YB%Sq''d.{QbXSy^>̓}+3]`j;U1ʚ<`:5.x͗s^Cm);Bj:zT.(zA UV{o:vYAi64ipȍtg2w==~tii?r&ߜL.-"Ϙӫw&P{5WQv3(EwNSϷp, ~b tؼ2%RӄNOI^s 4[Oţ/StEaOw ~o WX&:a -F@}YPj_-r}(]gb-uST['wY“ 2/$<  P"Qvr#hrt;RॽVG킦2yB%T&=Qa M_oy!O-n#y)4SFS!HQ-7GRM^'&w!2KP(+dp2D`i1}dMh v?aGmT ҷ dSʟl ;eW~ ?BZGrF7/ ̹D}35dQMn(u 'i+ b:zj]/t -Uf*iC-\wZGyP/(淹a9ϯIT(I(`́)#T e2 9Pٍ(˳PtR1;jJef` ]X~vnHU?~+K_ )/x¡CWQkɁo(;-m<ͅcPWXDhyz/$Զ~XdW:>"Q5v8?<}7-@ǃE&>-5{24(\ν24˷0coaMȀg3< 5Aj?T C-i-[pCht% Gd T17A`(׶Jgz9TtZnԊJ|tC_mP_ZA<μJ|>,WO/!mԴ~_IrsWC(5ikJxC} 9\z'.yoOq!xGy@{FVPX&-Ծ-E2ʓ܄s@ձ`x+"hRg4N_(g$oS=э>yWw*灚oKڐy!^3|?%x2E>1- jQs.>(UrU6_}5t߸85K&OdP;Aٶl??|+[S?=[Uorj_Ѝ'bs(Rw̾bc%Xw24n$\{ $U/Dtѯ@a GPP >e@nCpk;j(;j7R mg͉?CM m$AJ)9Yl[*PߙCԮ\಼3;%ܞ:.0D_q:č^271nO-f8gU-[$2%[s? t}ΒA0pۼ0c9?+@I-ylg{n@2^?YNSmb@qvRhtb"p]^?s# %@WA,̝"n)C"L)ۆq/̳WUA7k$)HgU,{%8 2"#@-OKJ}V QoP+{kSXf0EQd}ETE{*ЇEwYq gH~ n'g/@.\bo/ yC@DGf@yاۊPO0sPA~. m[iT ݮI0=OiP4Q zL̙c0۲w(+K?6 5; Ԕ K@Od$Q8 ϒlqlFmjH~&2n@%\f,y8> SF7 Ue7>y;fnS7 .v 4-v(Jѯ1yڻl> K#@i:~n{ܫZo7y^s&0Ep(ƌm@-uCW= S/vߞ!0h}H(|r=_ivj]wNO|au D,g0]~nd'R_2̡=zkc&bzׇ\x~nb] +!Nasׁ#K@.6=.skS4~TY}/cB"Ϥ“/og>C ǁXIw!703L݂?}[u $w=u@mԒI0)6n=JoB\k>hǙ3@>IB XyO?F[6 i׀n{\\@.P= lفid6~fe|=n+ogP%B,o_JE\r 30ҁ^b~ jy ^ WwS]H^:@R;p( 3@ *}c[՚h덄9:`m0{H=^kFW!p5^40œ׀`MW M?U|rTdKߝ-34C 'E_q\ZͽK@d4n3d KXo*S?_:/Rcl@th gǔ7qE#ÍwCCE`wuW%M깼llXa7jd dJYPκ3~E3>lRj뙅.d h.?'v^ h]Tץ-@ =k56р%O &]Y1kہ)HԇԔ@~MmM 4ph225@ {]݄903۬ձN?ٗ-+r/xQ$P/(4mniaT@7g$ xUHnZ_^]0w4Jߣ@j+]gSm0'QB&x7+#DOin 0]1@_JTLߠmH\jP>8[6k^[ >RD#gqB.UYwP,ފCcDFl{㎕iw Lu ȤNWqΊO%q4bM4L[J2LGYNuOkvuLcQ4+w @-Qh?l7}:xo|>Aܭ^@8n$ 5~ߝcK> ~<.F'03p9PH9[7[}LPl ϶/)l>a|@3NiOn蹵F7?\ĹS8T`9(&J{`s׿h9ȴtҤ5rŽeaDe?_~/WJdä@>~0 }|R.@# _3Vρ<,-6sv'0sc^%Ef)Eoڗ͛Y"PXT[}x#y!}7c)?pȿքaV%VW5=nx>DnK07.P.0 uW}F;v;jN+T~ }dkƷkcdAn0MBPi39=s@97LK壱H0yئ8DeCY@qckP/m7`\s2-d_:M[&@Q Kavɹ_q jxV<_ Rm@_4~dDaNJݐ ԫjw^@5 s~3Fپ@2O)s'AU ÃY kMCtvŵu%Ç9n8_7]R;@;pSJ&Ѩv3&}`F̿3@MU)`GrG0x=W'I\@8Dok sO:|FȹMW0dϏ˹@Qr`uG[= $ 7F:;^{}gRk;#i-2p>'-@ UZQ$M'y^<& @vWo5ܑ6}8-ZZӫ8?;^ĸHO`\J=}CGfmB in7,7Thʹյ޸5^ oxV&& T>|h$ 96 jKL/e@Qkل͆Z kr59#NyYid#w$}K YO>X\S DeOGua"P<.alNf`H7rT3\I@.0LB{'`v%c?aO}g<C>M%~Y ()$CL0H# s16, X7}Mgu߁fh2< ,I@ۯ-ugDB)@!N mz3w9#݁>. ssߥq`lI8rD9?,P'o)ΰQ`$( yQr f.ْ@hetȆ#qNiI‚@ڷ9v*Spy驟W$sS@+_1+揟'p|zr\J#5caE$7P{s(v bkچbxN[M̳ke9uֶc~9#2 cg+𥆚x?/{1[!!(rV%o} eS-b@qNVƼ5PH\/b~P2TMb"LުQ3>R#m-޼9<~H 06څ? ޳|_ўoB݉@]Ubv[ZNnϓ` ѓ$Me@v*K\49se$y6Kg=קc<8kiD2/D*NZL?k;@fH<s#e\!$UL MSḟ>0'p< 0d* q9fCvWWɇxL;"ƥݼ/ܑ.h ]3;lb7v}Pq#4n=~]o}-#;8s1@`#s[YƻɌb0w2ԷNά.羻Y{.SW]>P3XcrJo`>#- Z/@d3y+M14Wq^ߛǁV(Fχ;V SEd\Pr4l`}~-+ëO3m߽_=ak-@Ym."Ekn%-_ |@vO.[pp l0z뀠plA>?~=b'#]n<=csE7nyN(Ye{7سh-g`/(q>L5r֮7p6|` lG3@b9}( P6> `.NJ#6sg.oy c ttcxe7?y"z?uj;^yZx-Ŗ;Ig7O];_W燿>>>>}!Uqٝjd Lcy\[~60_.ިJ 0(~,n4C@ :_wm^`*hj;)ͺpִ!bU8wҌbc3{;+,k?׋@콡ʹ52q>56\?}U5)Qfo~ɩ`A[0yqm|9'E;SsҦp wNy=wÀh] e ̇6Bpn~qu3vOJ:-@xu4.np̰0wWחإg8oh| f٧apߔZM-I7E!$W`|/țfub%uQy6OEf}_/05'(ȝ\i?(U')7C7Ef_jnmƇ'z#f> vz8!pnG^OC z\3z1[L34sm )7Dm@`ޱ=̜1@'ȕ}=4Y@Xnn4ʳ_o/Q g= <2w6= J s|@r[Հ^g29 Ȧ'G_"|/%`&1ۈ=iq+d\lu*m]Jz.PLǔ'ы%!{ʯװ_cW̆3ǎU/juO% v^N-0%Bsw,VKsmqQ7UР: )0uߌr 0c_ߩk q{Zg[|%@3n:l AA!̝g"ӭ9C(b4OC΄oGRJp|V罫}1JQ~R7 uxȡ:ػW~\z#G؃w)87UsSrCC3~_[2z>5h2L[p{ٽn(A$|`#+Q]sos̻f{^[E 0M4ω@\d')Easpw? "orD,0nq-co@M,(b@u"Z.ǀM/<qI?31 3_mg8L%fƷt۰+y {RاK9怸~[f%k]/Eu6-}0 =KUOc7%Wxs5'̊r43!mķ h<駨#>髸_ﹽ:SO߇cM8ڙRXĪP7|Z[w̔uq~ĕG;{su垛>րpPF# ;3]xe㕁^)"}D"4`_@!-#xOs .'B/ZvuuUOzafl4P__~n]{t&_8 kb36mހ9*~IQ+. ܽLԹٽ\J70vi|ϼ Xп- ϝ$ dJƱ<ir%ƨܻp]zٶSWYW ͘908>mhg/m}@g(=#(@ G$Op^Ud:m KW[}L>+|{%0V^~"x|*P:X#%[7i/rz蛂):cTOf~ο O7+c6` /j6b€$ٰ~egiJ^'CdV{8W"lTsH%]bi@8vTڎv3":ใ4[sHFoo @ڡCHþr S]ߘ{6dM_!k7>5ٍ+S:~X-l.^qW^n K޵DՇ"R4wm׶8Cu\qPݎT&*ͺ#h$17nQVYڼux ~5N[i0~N zӌ "d己Y5xf*=bn]Hf@TܷV0ްLx~H0TErJjЯ Las?MfTui&Ugqhמ> ;X&>?w<жL9_'*e>M3v@{ 9_ %6kɄJS:3Y )6'JJag?0 xWU@A{ڿ $6 k@_EsrD7y(B 5xoz}7M4at@K..eI6Es6`2*A⾄.0ww[Hgq^6mBiEZ{{gZO_p6,g#cA'?s"P-k@,h4Ԅ=7zd}_WO9P pnm 5*z{xL7kTxmY">|=;T@iw|ږsv<LY6?{,$PgWIF&@]qMb-|#[Mط=bT;g'/V@~Yxf je,$ |Y1>-5O$qQ~>Ӎ?힕8Dpp$w\?4ߋ7q(~ 87~;(D5@:B5Vu_ҵ1*,+j{Y Gp_ wr,Lnz`Ԩ@Pכ9TJ:ksϑ[]Yv?a>4ڡtshELnjlk1 Ws`-WH0ċsjwޗ=}s'Kqo>c} Hϥk=?Ub{0ӴU{G&P %܍G<-@5 ;_ӟ<ټYcFn`z77Žⓞ_"@Qwhћe^ρ[Vqh]+ 2җ* NY-0;*ۉZ ovI@x} R U– ɿgO%9ZWo4_E: w2m=y;a+SN8\IY oyniʌm,oB]W.Pdlrٳ|(uLZ̟X[5%rwh@d |Y:T`JL|({I 6,a d'=M[bi\`xӗ@ouh r5&O ˢ )4ᕒ0wIv6*6vxl56yM{ڱہv{C$,l%r'w?b?y'.#BnQ- }ei/)۲~8ԋhN؏ȯ,e/=@Rͣ/Q+@ި{yONJxp݉sUt]޻Ayj rT;@QHV ߾ ~2oiwgZa%6 [`8v};0YB:`., yjgD5q:9a/'JL:un'znV ^ bSt_9"KÊ#zϊ䀴ڜa 80ھ >%/\837GF>/%w]Я2`xs}"os+_D)71 C:r[=մmP'M!V@ p5`Tunȷ`i&a1(ݘ-bM!`F]J~>@Ցhn?x {?U8-sb ןME&0߹p;,OM;U|}K鄰P( WXUW9`(ՄY$//&M _ß@bێ&`j>05ۄEӽMgboi|zv}JɨB0n[uu_D K2뗴`@W8 m>;i rC{1 <$s;7Xn=[:J{uZ{5VNq`4 m loŊ_տZn {<8[qfd&)QgKzFrã@u,nW\[)+An-=(:EeǁtEWT*{0_Lg5ۜ/@t75 ``.侺'O;"`L}yl->"hAy<@#_xCУ/Ew1[Q%5a@8{J qN۳$L@&ѹ/4=73^\52wao=}Ʒy RyiI8xEm78`0~ {[SNZE/!zp4 4!GB&d l庺Syu1 Kc:2m$ d |'C 2?\Mœ'&cBa @99;/ .W)H홦 mں͞W*P[(HU^;Fpc,+oDQ%9(5(}ӏ^nw_ ȱ1bR;C$6A{XOq=l#s E>ynÜ\؇5=|[PDB_Sǝ`M24P:O LfF@6=z90{rfq^ fo/ORmPwft7<5bp.F s;ZM{P[o7Y p}י#"y VuAW4| O<@3¾jagwǔ@'vì{!٠kgbPT{1~B;`z_1{Sn@S0u`^wESLo\Ӽj^`=ILj%?X02k?A~ݽ3@V ck\"bT-_+Iz03(Jz{bqx4g]@}<ԲCO u/9:+ʥya&u؋tN`PFT@lݤS9Ăb4TߜÜ%3R_- 4,k$[2(oErK˙nvZST)wwi@4}y~f <@n{"~\"@ i~_$u!P);nRW8&~ /_¬Nf)xXn{G) Y沇f?- ėnX7R2Yi.a{WG(sOy(9UreQ `Z|c-u9t o%&lƍ)Ղx/],'*H?;Ķcu{a@^;,[fk;mVpnU;ZN 0n'L9\ ~ݜ-@kxǙ$}^1}D!i$1Q̀ԭ&|?06^`PN\ese@9䠧rnA`<](FYn߸>O4#a ϕC?bݾ뼜7>ŏX}@fIʁP 36j8CJ2@_%s {TU{+|{a?jaWuуh@_-yĭ2#~ߎ mǹ7K.?|A 4sxg&Eّ/ga7e D}9K@ΈC@X;c yjN1q^,sRO (xllR;75M G<ǀ0V(_䗿h܀P@9(uC>1gXD81h@:sp-:,B-Tط^/ tPoj _f6KK,a~涯(0 sWDY ys\,,{7>L1iCca \(f0l;ǥLPڼP-ݜz'=!}*ؾ=n{>"s{y'&b/`63k:3w_Pkn|=,UcS0(zQy;w}A .o /@>T#{5*ށoޠLƮyW_5cdbK@@XZ=Н}z) :Bn_M0uac7 EX~Ĺޣ* bd̷ N^JA&P,>Uwu]x:s]~̋-ZTtyzt)qƸ0 uFq=)ڞ%KC zo! LkgP%sW]LKMc zf Q#-9=#s .8%%YD9ݿ0 $޽RA@#;9ԕwN*]&@稯/bm9Iw|` wѰoH1(sn[QhT732+nm.eאַ@d䈣?⽜Q8yr> Lqwdw* ӕV''vٽkoYKz)j#`6H>So=}7q rosgBTcYPNU%vd~9~n_{s%& 0䧏ܾ`Tߣ V7Q.mPq(=@ߠEs\^vyLiIFam-{‡475pRkΔEw7@2lCM0{awo0>(\ɆG{wGEv~I|1%=)PQ۔3t)Vø.b]Hӽ (Ww},NK" 8y)bjm344(|ǹ,W@!EsC A9-ISV3Fz`fG?U~GU\3/%2,7LtzSg Fv EsGbWlx(l,8{p s ?w #2j1-tϵ.3c]4:,> 9z@av4?_߼S`=-Tyخ؁1I'x+ô{ @;p {Lj%gl[d==eEiQQEfE Q>aQN@om,K^{7$ϻhch#E]iGbnQ6X߀@~xf=>96@ޫa~kt+5ZmP&P{'\\y\>ǽ\r7A{"9pn:~;W9Ч@sxUo)grVݺH ?G9t{D׍﾿r{;4w`(q†Q V0lSځ=SPTgUծM?#Jx4t ȗ[~ޅUKOb.;&,L?07N`ͽ@Nq 5c_ W@1~ZrUO^hʛ]L*FPSy{,l;jehS ˊ8vpf?oBhjwr$*cO]ķOX=bve cA|@c) ϕYݳIWev1[ʁzY>γiF2^Kv/^)[Y@iy*pZE0۰m E6os9b { U\*ͽ=Oך}B/nfFÀ8u@i)aZOȥbG?܌_" ijWso~&Q܍alWZj?o 4A9 ͏ְh99qW ΑJؗ/ߺ D8/3@zi;7889[3J~2qL+Þ B` z#[c'0̓"f$ M\THJ> @u2P& }^-̣ |wq~xqu``2@[. 4dc$̂GY,_Rr oiSNTixV]}ϯ;q- e +\ _Z1PYʾ_@('^ ljN+# ͝@<>7!4iAN m1 stɧ-G%R PMa'0>T's1wD{?.YI˱+@߯"V ߾hzM+9zw@=>xApeE}fq\fcˀ%|jtU4:W?OKiC| >RCTWĚѣY.{$#x^r漙3 Ge@ $o&`$iek@~h\[ԩ 'h)@kp w}ҫ4 :1bM<;sԕwh'< ɕ#x'_f⪭鍊@{z{)jkɥ<=ۑ:Js{P*P-6 r-[r=LDސ4"ڼ@Loj4Pݓͻ&vm?hK3y~6h]fQᤌ? Qn4 &r1/`֝9 B-ƹ2Y{Baj`~89wᾗddw@]JUzɏfaDgl&%zCd 1 q˟(^Ide|hQXE'S|Ğbr{f`YY芆mn^:ѥ+@L)rT^w>y جU?`.:j/n@x$@=elU;:jMql}z]0 @M^K HeQT'fa W׿ @8ӎ0?OEUc`"ȴ;$Ťg1/JI/0;nY7}Կj(+i`hbf@{`ur/ \U=?7OM_yI#ua+[ @&w3/]B,>sEq7P.: q-1y\\T3ԖN%͇|ew*~10OR9y -`^}FvR Gom Tȧ~!kc@uZmA'?AE)`(;PO]urxx yt !a8,:q$SJ\E#\gۋy0/fO{i7Ya& Ж 9&#(_V rI&Ni.!k]@;޷3~`Knhx̽o@n} su,v׀zts=tBs=g`fLjuHwk.Ҁq6M?5ʄGD'17&M &óoNqTOno3eb._ySq@ntebq_d`xiT,L[ y؋  "#c9@|? ^?unZ%Ήqu%`k\fOe~xU hwn/B`9e3.$>Gܐ#)03˯`aE`O MSa*0Wc ̵Ď['v09`>WP? W3!VE"@=$ HxCs)!?4mÆ$S2fJ TD2fh$SJPT- 3[Zfy{o-y8m4j= OD޻\DLsaP"U,V \KE3WiIUw8)B㝳hz诃{4+` ύh4f*b/ke4d]GMV3NT)A|ߎƶ=C}UcegttJu18&Bg}~Wc5>?t_}#ӗ˛ qh쥍\hE#4w%14z 46s2L MdR>=*9I8'晣L4t\qQ; ^QꍦN!i}$'1=mC:1L BS]RŷDy)`<ar2o6Fa+ZKf XrhVWh^h[ziX>4(G{>gR[ބ_l΅o88&>|9VtO.\T %y7Ef/1}%KEw_S؃S'~ ̰wBS2TdȗohҷӶEļuhR2>[挅3rΠ /oYߓߔvUM^i/M :bl<FA,?J{|khl8D<ZƧG>J _Q\4{d@}n?wBk-Ehߓ54jփ&E}UARQ^ј˙rBK_4}(2lNFSGR\?, ybk}:Xzh}{A SVShKl9Y4nz33e3PAO#419c ?J VF(h¤`&Tu\0g*{m(W-~Lg.y fG~}`^'q4ld1 Z$NS1UrN4MAB\mu oMП؋&b4wOa^s?y 7_LנU#IhꫵO4fخ e|sg܆v4\d>'*M =8 sI-6^%2ьCY 6>8=&4FZ3ЄRΥ޾dCsXdѨ͋hB#h׳a1h}4^&ωG;0gl+=#4**aq cm~Fj*D$Ry4#8'm_/f23NG3_DZ+*7z ; 4D(/ݱsʓD|hN{a{4މ4N*)3r8=Jk:1Og6a/#Pve4If<8vefgإh 1n=ˑy4))a5My- B$པ 4qQl4W `<{;bzp;Ds^Z}QC>7NY:F (qL&gxݣ<ЌT%g Z7 pZd [^Dcׅ.&BLvg[GT*s^Ɏ@ÇsoKiOuG(ذϣhj;3",Ѥ@FN7fiߐ>o[[GBӬȫhԁ=d*hooOC*Wsb%K 5V!f:qf9䡳̖hrV%꼄-ljG˪"ʂ*1oјʤB43cUƯ=V&Ρə}gBľoP<ZfnGk؝Ưȩ-hzb4=R0/>XBLM>hRt?4v}j^ 󵛁F->EBI8w\]CbdmvV 4%h/KJ7~tًѽ_4 hW8qhlVfAR[/Rch4~,W<܆Uysо y~4!tG&^s1>Uߘ@#׺$ uT !z3hЃiʎsc"&=uT t VkdtÅ7dmoeVُozu'v΃k4$V*uo__2q,U5G3GO_ZKHÞ[ 8dc2z8$K'8$/,D߁ur9]|z್ه^)*+ yON[ƾ(ިkMH˪mn[Rj7UT~MSY2aքE3nM~yz:7g4cɺc4g}JD(4< >|#m_ފ,X}F#t&mwLhUq`>V:0M(6{⌘7է!PPW]hxsgēFɇkhxD(K )hp>,M~a˲Cwq(W$ZZ#~/g&h,jD,o?On)-r#sAhZ9 Ml>S_hīdTPwF>LNFRC5GSY+}8N%xJ- wr $^ØSSWR$9-MҮF1Yhx1'l  h鎻!ًhjǞQ{ 8CД z|܃i۽g¦9ј~?uBht .Yώ2 f~oG>k!y|>i~P닦J=}?6[1:5S# a}V|vp:i [Sd4޼1OyA,]n{j+MUZh?A/7}?(/9RGcSvʎд{RhRC>M`/<7J'7`Nb FSbͬѬjmW,M~5@@c'T= Дǃb0dFGaB)V0Xㄦ<:Ez0}l 6Ƨ8)ߞ  zI<"8}shh9Y6sHMBO!top42UoMR>i%]߇{Ah4q qgjE i#l ́/]f@)KfmhJva̭ZqO $[[ Yᗏ9Իjs4wF7/eGSb<hV~,Z,b~d-~RRF,Gi>땜XQ 6ocDϽ\C&oSd4BRͰHvB,}߻?`NdFcESՖh$Fk-uTE7*V-7F‰'ͨV 1OH'Q4>8cFxc *mh쾈9 4|Fj^YX` {._M^-α\hlmSbd_^8;!1R5ۍ*3vgVy |d'淧NVg/y+ĜX["Q M-hbbM'Q#_t]8fn=]};kS.9;a~sgszUӇI8kјI~hz-@L@$sQc7uh b)Gsєc|&#fs2ѸFñ 8 f þTƅy;s@;qpD]ɪ:hLЗSӰUN4>Eom64v4cA1GS,{ظT`KBf9PV |ۣ둂acKhfrc:ދ!m4blf58_Ή-`)͸1/ 79^2,! hX {cE5R _F>}h4ƿ{%32= tlVGӊۊ:c~L3D#&1G&kEdsv1NY4U<MJ])5DM#ޮg}N;f/ ՚(4`R~,;NUhGrDt#4?yh߅۶>a4}|%Tc޺t٦'V9~)ǰ];q.;lO}^ht!#[Ogh8&n]y4껴*mKs{R;^4$; 7  M[Neo5ܻeZL[ohKF~1P*f5XД`eW!bv{No,*Ję\>JG5ic 1}E s85ojh26tXL|Es<hHc^4y--<v/dN+t^:p TY{OFco_g}F#O\:3ZtB4uK7ьE w739_ &ba,ӧF%~]םrXyzK@3WԻh4O+bkodٚѷvQqXW4ߠ̖*c_7oⳀ z^.WsŬ+[tݼ_r4忩%<ŇqAcRDtjR:g?7^p;j̃Ot\DSuѸa /7JB3ѱbgqNeT 4~',+74rV,C alܓJW;^oBf4m U4#?DѴYHncqsk[4:^>_ Z1_'.JWEC{*vk@j x׿áhמb"VvK\h&~oK3++"=UNWW Sa74WfUpGR*%2n9#7i1>sw9 }H|G>51okb[~ݐWSD|+_x뇈ieS'%7ɢI>`hķz0nn8&o'Y5BS/H4κ]ث3NGCj6TYȕ=G{HV&x /9,h pl=4|-,N 6.]kDEc\/!fbqn'^Z=R|h0F̊ދU{4n ؔ6bw jFSiq)%hĢFC]Mh,A)ޟ5n4X}8 ccS)hI?SEǶohB4v5h3 &{i(]]*SC hWEw/+p.hJ t^=00M 2^D#_z} 0/4-K9F炝a4`sGW[oGөfJ}~ Qʣ|/4i64/FkUΊ( <r4-+9M>qo>+is'^YQ:inB0Djg\/] B'Ģs488&*ϝF^lfcy c3>Gy8׎{))>4xwMFչ|Ac.be2iH{Ѕ F]BИX78.3}%&k :QW7مƤEeZI6ECѡJh5OV54E*p{AߕH7jZA {I,x4 6~j whBNE ?Dea4vl `o(FV*~BC6/75A#(5ǰyD?v݇&*Ȼ=сb8gJsmIvgH?\w~+ܝ=w.钯OUp<W3"p^ϧHӞChPP;h1M[i>^Ei5޽FozeayODD}c {] X0/ov\ýlG<9q}4s_٩`,FtDŽ^{7m YmfR 4Un}Zɋ= h\g*6|Qݱi>U_#ehrqU'=;;){/F`rx)|F}ѱs]/qCv|4!] ĹI4ޠd$1N,<ֲZ3b^Y,aM\ =vpxxnX7 Nwې&=Ĝ fIsj)-*Km@6p1vQ;4>:p[ཾ?9h`*@.4#G sCѬMg/|(>pM XeuunԢwIQ&9߮4s?ItS_8K!hhfڕK `!yFͣɠ1X4p2xM Mr İҧФַ h{lݟT4~wӍ3h"Kڄ o=Vh=!ČjRF yqIWB*4mn<ƣHhy9ázk4g)8c*'ayMulIߍFs(~*{%g8Χ,ik4}{9{hBBӬsW /;d]5UYn4R~Cehlnh@~̗/JJ4fgeXPumOף1N )Tw#"sohl4>u{/2?&)SI;}Em|u=) k8ӆ .zq?r[M^&ePWHGmReCKL/+ Ī+vJڛ B( nI+O:{!m@.6 ?֒\R me=BImȡg]^t@At jMG'T#~Ԕ4cw|0iPm>䞗ʓB'/"[Kh9E@f|'*PK}ʦ7aWO}҈s n}uԽ0HKQv_@,|◗$M@)r(.6,@$, gm74_(?">9R)=mn @>ctCƼkГGusYEV#@S#y|^dNwy $5(d? t[f/]6߁2s%I.Nnm"P޹+( /ޛ% (',<紐+\bԚM>& ^4. wPdv"3@-QC%|ܼ5v%! D~Φ2<?|Nf @uHϳXG9GZiS# @PKkQ$q>ʫXj( 7G.<*y4P1>?8:!t2WEVuE^_%xjNg&1c%Е|vz9{-;ϳ{ytM$m8D' ƟW#(ygmj @-h txٰe:,@uL, qƞ(yC.+h,l@ -ra'0)ܣ{Vs_3ڲO"΍bY.z|Y (ݥ_@ ,^rd H97uԟ*)}F(/{O5!{kS v@䪑y B@B7zsTS#u(3N}sOKgZèG^r-N¨r!<+ޢ㹖@f |n}W@{ݪ,}w8.zeijST K{)RN*i)?Kz(Ws;@^3?Tt{|@9ε eCq|>Q{ݬ@?zC-P ؟\hPMPFzU>UsܗN{R9>嚎#f#зmv+Oq& Ҵ گ-n1[}͵Dy}8g(׎#Bd 1,'-@˾.= DIdv|kr1N=0|[u riC뜬VfQYpP{H\ǚ3\*3=gX AV*}8Mz]y( KaE~@iy D[D&! @ 낟RY`*F9@_X׻H&w^F]@b6; ?FOY4I жn-]Zpf}q~(N+_;4z o Q`ý)=dQX_q8nsx>6]= s=KbW{M0hhZm@ :C\$SP@W+@JSjHp{-?5禬y{UpO~MW4-|1;e$l߲#PۗL^*vl@[4$ =P^wQ{2WRŋ;qAEbl &xl^Fe -e,],qJ sO#lkU 1yHHEQߪ HӅP#/gh@W-.@Lnny(޸Z| ϖO,M}Nc=xAn̰9܁ʲ F1[~KlSթɱ@jA_5m;0_bG6lYM3P ډ8 >! {=#@ (*[~BwZ.U}P+rf4~塓[w$TK9]~SmՆN16%2怺#x.}gz0Ox5oouٳuya.TEi3h u;=}=5aNu- 3'[%p}ws6@aںsߡI1襓gQ &۪eHeCfU@=Pl(J5.y@8&\؅l/d@ ${oT)t(}ʀtk?6tڻ}Gw&k%Ck @J8F XbKsι4{ҁ*p]s\-Gzÿr!zSo⹉>+ϼb9 @P60s~3Z4ޣ=YCVx-ḑ/3eݸ9J9 rl@th6ޟp7k_WqB|?8_vJTz[s ]֦ϸp `=TެvO@V\_4jř0y J;<)+!G&ͧ*m#(2G51OoWԀKeV@ut%W8UF ⡛uKا]OGv K6L%qCP>USj.y} ۋw\I@yԷľ;^@~8т91.@%)nœ-"zQȑT2Eq,[ վ(>8%}TޭX2N9e D7,q ~r+Kuoo<0sP"{u,:S*Pڿr0ے2i#UU ֥ʁ#B ëOL~u6(P}'M'8Gy z;ǥF$qݟ{qޒ6P&&ĩ_wp>|H \_ŀnQH>}g_1Ľ݈}UcUbU-{@g_>byam|<fw[NOJPt[vE(z@T;og˨ϵs&r@7bxjp[|ʴRY0P%w(^J+>́Rk}U GpNxفu{4P_n -{qHK,P~JhsY/Rُxsk:U@?%!;^Ca КNmwiЊ ~]2ʩ@^> sVMgpNŜxLT;h+ @ҩz\Lg <}}Ax@ߧC&쇀Z/(Nl^%4mbLHmj}>NH \b8\10~9gQIOiJ.&$(SɦN o);kc ґŅ^` W?vkJPڴ{[|Vܜo#:^'VNWV tF<7Qbnk4}s=-(]g Tb9@S ~40}G~-I#I2HJY~3IP'jnF m bo` 1%,؏=yݳnIeh7y4;-΁kW#A ث=s@UHʬ5mSس %6FE5$_ ٴsCW!K g>8rz/yjzc?O=udSO Tp ZWma'd B+); T]3/FG;o\u/)7]oeqJ"*ͧnַ@?CsڅG L0J\Qou1debn~>-{+Ը ~a fvP_"Px&>28O? S>D vY[G ϿI+p dd䥌 ⾌62{|Kf3=ooTb_gq@+Y6<:DZĹ\ ޿@qPd:[Iڛ"d@RX[(},ǣ4u|5h|#ş@^esv+f԰{z2ȸ,P-,瑞s\/90q{SA :<xHrixԈ?;;@u 2Y6y䮝K׀0r?>NY) ?b̀B9i=Ρowur% rܸw[{|\L!΀w838q^GI>G>"0"GU wT @VED9T?0' @OTfX o,H.# %Gb㞑'&tmǼˮ>HQ0oZh%'CO')2P|4=E:5\.ǀW0Ͷ[PbnZ7ϛIXx}Q :-y K7 Φvmn+`x+\N1~hU;+}lt܁Um&iGl Joo@h(]@9Vލ}蛑@7轞 D ZBMp|TH nn _tvH ~+Mw指צ'@zKv{Pelأߴ*baSܳ;1sbQ^ Ĉ;҆W0;mz6P!< XVe˸Qh[#Qܧ/m;;#Xh3`K I?lًӆ+S=@ެ?bN $Es6#w}ʤ赭k\Ao4!&zVh  =/vЍݶ` .,ʘ@J ؋|0?<jDzLog߀s9nEEuHfhJ *4PbR,])GÇ ֛_4r6{UdQQ ;I, 1y! % ?9REٮM`)Bzâx룁jCԤ1M^u@'uq5{@nYϳ;q?)w->"xVk7^Tn] tO_߃^цoq9ڢBļcٛr("]6>tx W'J;mÔ䫛@]V;, TmKg9]!FkL.z_Srduuzvj.pԿ;)'p{O1+3we]󫁺U[)뵱4^2T(S }ٗZ7+P W϶WUԏigɶ8]O~oIǶsa;-߲DzkLٗbi`f% _8w_f/Ͻ%B{/THkySULLJ1z5?\$%YU~Vi 7ĀLp9 m>)2@a@HGvV WDԬ>< zߘeJ`~UEŹ5q2=KPJO}S waǥ.H4=zK9uܣb&am.(B k[S@4Է0 =".%& 7fqP; L8z^ F6}&6_RGVr>;IudYH0׾W6΁8ÓQPTP| UqYwyĺ9[(oVcpL^1݁~l,oO*Rd5{9 6U~^zz궲Oct5V/~5m@<-Y$ОG@k"B Д 9lg/<f\jy7707*x19b/ P(*u{&Ɉrse^e_א|~R^){ҀQda Et55pz/lr{uo=ЏnϷ6ҟ]W0>{h8hgσnߴxVefc8׻W.5 (6:0Ѭ-h@Yyzi<XZPijV @o;:׾g[M?.`(% Vb~WN]'S~b>r sD]k7Gaz=!Ր< %p p2b@Ojrv1` =9S̹έ֛%<xc΃y{\yܧ,J 2 _%$>fy)=waq3o\:W,B%ׁE\}B ݷmJlj\Ywȅ d$|j {yO1 %ߝE@U>Yojr@8Qw sUFlY̳:gqTrj*{iqieL(2Su~˙ts(<"1RRe_a@95Q(#ST ~a /#NmCi[?OO<.uիŽ64s@(yQ:kk큽@KI dR1IQǠ+o$T<Bg묣%ǗcyG^zNF@yL=Ab-5fȡ~ mCRӤY93\ֶ^p=lV>c[w;p5ƣ {z@|g_3PoI7Eܙ Te͘rXW]nnf'szt/kYT 6N vջ6U/[cbh;A@\ {s@=sno2 kV +̭75N85>x R>4/^iˆq蝺Uo9k +vkw2ZX½ZV=L$ܲ, P4dUN \\߷qz,kʁPb^1މ#:OHt ^YJǑܧ%;FF8oJZ.XJZAH 1dcI@W;;Ov+H%4(" A!n`Y\)u9xP?qu~yhn{?A edPP gaWeFc@晵 c2PR;S/ef@QJ]'Ƣθ?[hR^8{KY`\Q} :s9V`EekKwc6k92ϚI}Č% ?ZZuw1}W|YS qmMh ɺ)%9LD(hV]-E^}{Q끪@`^USAO2sp5>~[!`ho& E=1BEZF^>Gǹ@ {hf*M@ }׸YzN=x f@0 'MN>׫ tqۻ"PHM|܆I@X=NdFo8WZ>eFa;@%y{wy% oyW * )@{z[F-|nj*BWKل" C-O.}Y}wM߫]Zɘ~<'<\y6QB`~p4:0' 4?2Yo6}K)_sĜA t7D$@xR&w0X,0bf;9o:ekZ,6'=ȱ~d;Wx>"Wys FWw.F!(-.'~ _UA9t HT̉@oNY6wc$R:q;rZJ7$hƷЎgLڽrzق>tQ /JMM! |*_H7 #_sـ:esr9@9K F Hۖ5luZbN7Gnw3@}v>L$|J92Wx6΍k&B@^ۅyN"d#OP p;j\uV=ƥbCG?ۧBI\! _ڞTg6g8NBB w/ )@#HFktLz3q[U ~gDl䶱==x'뎈lbņ/)O؞(qwSI_9 3ʭv s)uwzPaջјtW|3qaϗ}BWcޖm@7=| ;?W9Ujln?$ 7tnۍZF)z@o\9rI?_NM%@Zd@B@VW>d{eZW k=[|ߕ:l{7+*5ҧV'VϺ>Md V]֦ ϛ.?ž~j1Ƶb ~=>łkF\dg'xa{}O/Jz8ho?jDN!q^Eݷrl{Zn+I{^ϱ @l6"ʿ~>y |=5"˥6rqggKom8$bu S.9F-mo|A QR|/~CZ7ݘLt#Uv 37_t??7gK.Y*E{rt9ۑj,9 Ĕg&K$mH7uRPk@{\ve6C_|H4svRpSyut_~ݢ=Dmtm.~:@x'O򀸙7`7O`w`8u9/Rx(7cH?.i@N/*~l!v-qW :bsc]^hW|gAȥ[N7iWD2E,u^|}!%a ]|=ANrv-=3  V[@}17H2?> 'ͶONv/ż#}!d(acvo[hYEI8ǜ1@W+;C Tm;c&7n4<#c'1g^6C/q=5KGTx`& ȦD1מǹxcai(p>NMĘQ&LӀ~t_"~_L]XKOٕPw9?4cV_xJ^' U#)ӆ|. E{>}}@{$}Eh^STy!+_@j'MEOQB#ɓvm;!'yJaqU!0emK :^? sJ-Um3E-g8,ʝD6 ^X9hᷣ⌀2fi :eQ@zj$%ŀ.wV1myݟ6on ˿܎]RVO~ۀ(eHʎ?uu@z9w]"9 럋JhZ@I :?p^=:wrG}1QYþ/TyȏBd^N/3 +7K7͚tط2^2(TjnNsrs5d~|Gwtɱ#K["+v:Q|nhq' lg[5u:G|rދ~L0ڝH O$˼3jz1'@P<8#Au#*c̻7vwc_ɍ=zGJ9^ɼ8m{849kc^Mh{f~ª.p: {Gv27فQ6$N<3V ߅޴p,>௓趕n}{Dxly~ū>茟 w =_[҉+'2]l3ŷ N>{SSBFC ^"%>+=؈-@B72+ꛭɩ(i d.8c0ݗ>FiE"G=kЬS.B@#w?^%s ?vUIA@9̱;>hAoeg@+ɏy[ig- 8U6U0NϮ3^|EP&Я9{Ja?K[0WWn h<<(>-%1Xo~ GJg4s(-2SYrnkTz̹5%e ]iAT8߻ ls/<^N j/jMtb~^p]HZO @<gkO@\=7ynS@/-lҞO&:LmggУ<71FkH>> 87P7/DD3i@s\[\ao%2qT^Q~[Hv#7bt`~H [@>{sC$X<ǗH@n]xhr .)o^9Wg/\ץY(ar/qo)\j2^!$˳1Y@*6l <}LVO2ƪĀE,2tpLU I-w)KyQ >s, ~i)@~,2oZQ n{| 嵕ʄbQ?~5ЫO^f}տ!Yt|bgΫMi_)pzh]0?}pLۋ@̘T|]d>m쫥̡F`/Kh~ ]8u\^.e1Ywa|:XI5By͖cx5*s32$о>&z{]@}XQG0=Q]p|ie)ޛju|./< r_X&U92ļ:339bM ^6ٰ{ ŜHb@SFb&MJ1%`cMSɄP"|O8T6`ׯ t'g^u|-_P$Lnܝ6~ $ ,"3r_rWv@{+Z;V#3ݰ7 aO|1sϞutUFڅ;~T|x(C_2hpmP 9 HSW-'HPuKUpF=:Q}[nR2-m4y@H^?lJ")D|M $+a:x6%t@ا!J%Zozz|caOtpRD!% q`+؄\c~* dԤ[ jnr5yv`8f"_,{|Ngl#hIP>5>6ÆSѹEŭc@}p;SNwrp=יp$ ݭ} s{E8~8~ /0>> .uzЎGP8U+W0]<2k+w3 Ԟhj`XwrAm = ˁkf!^%? 14lc}ԟ5]b}'Ï0~4Q/eO~QڛwV}>1>)T`~OBCO_M%߾q{c@#]Sn8Bƨ/ r_a>Cs k]W\~8GvߦX*1aSkr1,VNz[bE mv9&k7Q__\7ŹnfF礝zvv4۟e3,1LĻGLL`;zta^u3>@Jracxw-Ȟ@WoҒ'N1޴#׷ #ܛc9\/   =-_t9 }:x Ylϫ6/IbЫH^ߪU@1P7qr؟7fz$]= [mTgdpcPFX֨ܯuAby KUX dm Z0ڔ.bҵwTƎfp=ۼ[z-VmmA_Zぬɵ!o:#R-^%?b9d2`0}Br>_0[\Ì?9n" ʣcַ|@J?ƒϘ'u5觕B+ȇp|r*87;`?Xj8^n0+ ;sqϑTIwq^rV*@ss׹y{AzA#ni@~a[ئԉڧ|>nh|PlT刍|HBcoZIMMD*H foU0(3Os`όζ 9D̹Wx }7˫ x/bsw< w+bib ϔӿx|z#"أ"deTC<(>p ɽ tӉQ"m} U.dAr3P#P̕)HCpgXmoz.%} G}ԏ߯[yx5xgK¹ej]iw094<^%7V2oTbl_E9\_#ŋ@<2q:Zf>_Jɲ9m yԸyקwday»@J )r@@W]]u kgԷ`^vq9An3dpGl\z@ѿflh7m0^sd[ً{9M3%$일  u e';DHڊ:! ָ+oHJLJ")iO}Bs'Ʒ/@_WVb*?Z@>G?Δ2= ʀ6l( /AӾxҴG11_ $ n ;NM'@KY(=d/q ;@8 (u[ ϧl7| he͟Ӂync Rj̨@}mE^^ s-­1H;R‚_dm>O'y(9KI)+bk@>oW3pߪkח@YA#aؙq06 O16OV+O/i$_ńzN[H\K=DŘƂw^ V ?WûrV;н-TVy7qcn.=AhѢ){J1^~u!}ڛ {mw=¼ҥoiW 6q SdhC sij:t"e8tª̺%KqbП5D!Rгc%= 0tGA@[("~OL"(H;|x7Ν@/}=uP>\h5K@ ?b$OV4oVNh eJgb- &jC}"ltm1Hw_Ue p0]z|=&4ma.iv H ,,<`9ZJ~yn7i5 yE,NJǁ~K͉FZI]򏀊l ,|v93wl P]SXaֻk@RW|9ü[M?y#}G>PdL?4='(ktz.JϾ(7yϕltaDoCם1zs(d q9-]oi vbnRYiq~քoog*Y>ۛ|sjᶶsG_Wb~Jyxj&ƝhUa4?i(J"y"/g }ZN/TdӺ dCK_+xsF?+uJ;⿗[IP<< $/ϗ oAh#뗍5/SN5­L sȟäeX-.Z؟vбoz {@IM0·Zw,j;@{;JwvHC;@}ҩMk1@myG,>U̱ɒK7͓&@Pu,J ;fx<l؁zƻ3@.Մwyۻ @k{Ԅ,~o`ۢhg&87hf nǽ& +8g.sRIVxί>T3П+"H&BGOpnWq0}I}ܓ"]w ֻe]Nc4< ; $ +)Fu#= 1Zl<0*UHdG e3ms'Lߕ$1Le;0XEjYo qo$Jrg Sc"<{r5-Mf Px{00?YIsEYޘ? @=Rbċ<Ksc@Q'^ TҢ d&&K.ţ4o1@~'l7^~os;3׋k;i{̿ ~}@^-v ]y. :Mm?Eȉ`3ߋq{e"`xYqLwu|g"騆GsxEzHY ہӄU@<"NXbM@+ h ǯp k@}pм tКW1E.N4cb]>u8C8.|Lq߬8% 9AW}(;M,Mg@:#] uxhI:8M9^)F칹@$0xϿ óG/k`{bYw*{]r RQЎ8HK !G޶$ 'G~U\4gAU [@okМ?Oݐžt9j[S_Mgrks5a72#{0 [Ğ'ТYD{EcW|yD[ awɲz=YN[}pͽo] swwEW?!n=! ]@b{ zneg[N:lH)S WKEG lI^3Q7PS33 jdiQ}q8N9_C+ҏ/j}kG&,hDAXr#?+fZ @0;R (.354 .~Qҭ$@]iZvP㷾WP=="6O?v.AoL()l>z?.}>'7+ H`_Y}> $co.9`5yX.aO>jQ{C򉃉qvo?0k }i۾gsSO^ =>5 G[¡WlF~U@^\q ԤRB@,t0 ^ڐBl u"+pN=dS~a@˥\0b8p yz8N(;ՄC=,E޿+Ol_w9zȴ;/kwz ;2vն4˙˘;zDpNOy zZ­ݣ>2(be{xʹx)z|h.?Iwˀ#ٓĽc/e]P.SV +)@oᗆy؇!O Ѧvƹ\J ylvLjr\P hLndW]tgx$駜1ĆNEY(0-X% qH<{x+ss (5֮9Pm Pns?ɼ Ԯ9٬^9? 4B1Wϒk,F Ha5{^ r˪#ρ>- gC>#-@ ǚ @$:T7أs_^wM)H fn؈9Bu1#Ug&P¹ sK^N[۪0^[~ (%ں=i`7^r &$J| dOx*+eS_@v(6 6Mڮ2xY>es@9i&|Wn@2еT^ޯQG՚`#Ҥ"(3nr'\}Nxdj7gF=>̍Dc'̘$`4;L9uV8l$0}s{Xq(PZs6URL hf'j})>0$l-eFc#$w0U!9Eo|f'݋y}_#'='umBq&t4l!sxCs4H="WB3"$,~L9H= ~p%ۣK } D-Lt<6|AG08 Nj}m@Tk%i̩o Z0Zl;Ud4goTŭR k mLwм5-9 vUg/ :o5d^dJW0<+tBr}+ܣץ KiU/ߦ;@8b {PKWG#c]=_dfW.Y.mh@rqGA#ErTy +Ng ϣ-wrՆ{9!v5DZ(6OJ}=y.*āV3|2r0艹*N|=T'/~յ p'/|γo~N6|G|\>}?x$RȚ7hs %cxM߹pyG+^J֒Nü&X~H#BBЗF{ @߽ٚ~@?"vk; *>^M{gFW h7Zx<'; G8] G2f/eoפL?'[,m:7_FeGPr ;[y'SZH@P@[s+EYJ`gW)Ǿ}U [b*nlåwV |&/0NCHiOiAE %2܁1~r-9/B-4 Z<~ ))ܢ d N-S eKjĹ侃>xKD*o^9-̕f쀬VOh$I@"r~xdϹWM{ȵ:ic@a lT<5gd~g}~@ʰk d_;Zeynzi)==ۧpѨ1J>d[dk)lHO5uߊ%sr{f%e {o(qG!z뎫sa_*в_+ǝ,BxI*uk*@2;v6Xa%T֕z@ӷm*Suo>tۍأwU`i8E ) j|n}6ڏ/`"-v H dk+JXlGdŝ@K|{7 ?Wcp.<Téw|jA0 :/WpoN/*~ߖb \W|#&z};2KNt ȿ7^Yjq!Ϯ> qeJ32>c[W80=E-r̊}/P'INRvn{4R7o(F'I@= xs/&ñ-E;vҔH)UJMC3{QFT^w|rݯu<n׉\Nn Yo{Vm.Vt폆Q 0xWhByk7/D^jR;ð, r I&ڧݜ#<#> 8@qZΗ 0а#ئ$#ۋh0 tk!oI8cL!ãv2hպ!r{X 4/!4zysM$ }fc^^ZbalB< 8(wl;_`|S BSxqVș0~6˟ 'QxUj4rM҈'@u!?I/ܣvC-s 2O5+Ľ96C~No/љy<+#qQgC`4 6^'[kjZ F%lyۤ4$a4f"qtJ{|_^zj n]e,ApƐ_uY0@{dIf~20 F_P/\ɁSt'^e\5U"Gz!:_/,m.-Aϔ y;?DP[`́# lj}|}_Y7 kw N &t*+DJPXB迹ON0rGb N(%̉{ݠ_ڞ\= Nl\+}DND@&ߚY(r:{vJڨ_mv7'rn7 DuD|Lej V!+ _}\o[^o}8mkA" (7$a;BׇY;E QLX^5aMW 4 < 6VX2G~fm:V=/o`r0I5;"W}OxØ@hV6wL+PƳ` &l'Μ!g|0$$iuorߊK&zXDu!͊rETv5zÐN+ND/; |&!^?mrդ );C3?n[#0'5KYc}Sj^C58YV K~p".6 }mooF2;%//zv\3}ϭ%DMO#㡟|Y^ 㾟Xg2|Zo.^ч'O셡G&Z36ul0x([QFttAމaO~+McuXW&zFnw*KVaұ\BO<{Uj .%@0GѡJ!qfEǽ˕"rRw5޷KhMOOk;TeB6wf;?wޮ !sWuۂfH0RTF>~GwYOR iT.4*B7?ˆWpOsDN|7kM0|~$% IlM9`dŭ0PҬoтDޱON^AM0dsؚ= `Ǭ]/ &|)!?XZ17 GNʀӏ7}%|)y/Rs)PL^ C{c;eRY3Wda0^yzbrލnц _I=ׄV)a)92|uOKޟ6wpAɦgZ`Q xbOp;cw7ʿAIϔ1@(gZ41wC;Y㣣nMqDby [2󬇁f0P}AcR匇U:lGbgΈ\'^IDO4+#q0n~mӊ5>,GwG xZ}幌#`eSZ]? cyT_ly5\r|Iτ#)Cς`^0tR#f0 [\Ci'0v$vx7d nbC{%D1̩YV$"'Q7-OPY8 4}/@IQw`x w!X nE%O6t:H'Doъ򂡴g *X-}ZV=F{`nFVMr9 ֵ ЗgG=MMv(/Bߪ 'n`!ҥPo3Tۓ~FƟ1.ЯJ=;CWh7/`Q!1_3U^8>9H[9g~yL]Zbks| r(0Y!Ɇ_} z]` ~w} EM퐧PiV,' ]PˇYA0o|ͪp nȎ?jW020vܞ%vD;I=QEn2/&q!zDJ!z,w#Q}ܙ z]9Y|ٺ>"Fn@߳w07//G_ZRu; R3Ո#0Y|z2/\ I#> Kh~+Y(2ÄOYAY0Y S3jVn[?͔+<Fng6QPFXϘhF'gg.\0Ÿrs> {x7+# k]{ #}f{[Y`h9t*Yu+79/1%W,`ms30L|*.p3v_8=Ι#w9Ugm=u3#opr[;7+MsUf3Ej09-/ym# 섑⍮wK뱧-tRno|EOc{pEv _7J2)n*?#JaQw_9CMnM+nD46Ow:>o{i҇qw\0/a2& 5^y>4"5eZOB 7 n~'pū?-(,g;9: ?˜Cjy_5!VOάk`T9- \+}(gOPs>_ca<ӇcGכjBI`Շ47o ?D7"kV [`X*2$ mf}0,NH云 IR5u?D?R1ѥS!F0o0D+/ >;hTa .^v+ *~웻mc>'1 ҧϧ r |v li&0|r#'F'o "Ҽq |M3n WOCDLn>n}ີNj]}6yv@iп{]4 ~-#t ' hHg !0"ުj~FS>èo] R[8#scx`Բ5+n=I;YK<}|񺿮h,>n;mW}uLzT.:%}/wK&r~ _mf5.V('}0wk,%E0LrكQ=Orx'E> <2;6=:AnjXĦ9DN^~GF ։P0LwK/+[G~7@vӒ*eyBH˵M0RAJ?Cǩo`P;o$̈́8m KKFh}4#s`۲7~^Fur\V:/}t4%tv拾_ 5A蜩9C5|y$/KՋ.M 0\W8q_WtdO"WnT&8t{gKOa(rdK1]U#7S`Ya'Bh3ףY 4p/ճ0KF1\)N{FiKFߌCjaH_0+y=-vP``ڗG:b}惀vC<3SC.mKHpwZh0sV9 +^3lœ9aTK8cY&-?m~IQ̥"9nv#zs oʺ0dkV"[ Z)9ʚ_}Ny @l+ v-sc]rs]c >0%m,㻫g Dh 8zc(woP%w]ka1ՂiZ&&5LXuό?ia!1yjC|sqG7=1j칉 {ݦO͉k?P7zjjTK8ז>.QePkb?Bˡ0J֏mSյ?n3o+/gazH!n](m~+[!<0Z>H: jsWBfLj,;ee35={ дch]QBauB.j{؏HI51gf82yR KU4BфX,ʎPd( [oj~RrQS‡bv2\i!PAG̻ne`JR77@YjkDE4tMD.Hq,f3[-CO3J&ٽO[Wg'_9@m*[@/Tf<9fy'O}$޺CłPz=Ԗo׏‹k7!.89/sٔEf>>\{y02qPd' \&9B== rWk ƨ{L:,aқkv-S]!;C[sKR^-[ *]w1|Z ԒTٱ)&uP9@y$ӗUHަ  Cgi`)Y#@Ig&Hp͹M4'^G+vVd˭J^ІG{>2cn=ׇXcE%yHy^ [հGZ_!bu _Ť5{b#O˱-!X-gp?HzIcƷ j2.IjΕC{^5rXq1_V7ò|\w+~H\ŎfX_Olܭm:0k W]C. [ˇ@SO1+qfd~5: EW:^`m{TP/0f ^&iWY%i/9pdEmzI)lH4QA gil.& d~Ā#7NCcotRLS 5qiƞB$uȥ%iaM( }0ǡT÷ۨ/٤{^noOWΊ?[n/hh6r:Wح!3%LaYsh׋ 3qE˥ԞGw}{0zU^x)D\/4,]NҀ&@m6#G|0Ttbt%3{kgv&w:"=i;LRTdi}nGOB{JYv0j^Aj`hKNOWd[: %'et4a&:lsற(kelڦb靲X'K'WzXmTd>ĶGE*(s퟼`xH)~㯵rdէl>U}V#x/Yt3 wHGDjLCfHjt:Yg..C_WU8`[Kض|qqA:uTZFM2rpJ̚BQB"L/kLNJ {'m++wt:qWSV 8]}?t?$} PCҒ;TL-=̖s 6`-8š0Vvƚן赋A|+*wmCz’Q}'VC[?0+W1{-5r^b;]臏|\ydWH <u-2:Bd,{*7d{Ve w>tmUhvj3i?cֆl,l>Y's #5T(.`3e'VP%OXB+;t&YJޱZ]^% jp%jd@ -"Qt#fl x+O#p(dr\]Bӟц\qm`/=ߋ_o *Cۅf.NKǰ ֢<-+H?:WK_CBǀ^WiWtT,0M.ӱ0mcš@Ai1EX^`oHW_xQ>6jEY(XjJL귶.H0,3J3rpM+TV ahǘtX}EM~HC}qKЈB˄$d:\t.)%Zm(d$k0dRm ʵbT_Jx}y73jہ;P7H၆~IzUvg+oĪ׻^:J6 6 ,;躎|'4B=NKObh: J8tɜzJ Vu:}DsNǣ }SZ+*EY{±0ڲH;FĄJ9 WWA6GA&l nlW'@eZY_Wtx/=9\gU^o ;>8eۂX?bue@^ecjU{w}: rCv:gΚ u?ADNWb]wc^1{ XSm3O @záclGP]d_^ dm[,xk?j#30h&W.tz3|\b=,S:fT%1RD4Z <ӹuxztGsU Jx~{*y-ed=nMY䶣ء}_/cbڕ-ꃠC۵4j tk $VyuBSbF;kO`Y Et6(LUzr=B1L 7VPQW@/7H?F7&Q+/uܒ.CKi9(b hÔu6kLy!c hzc[nG~T3ePkb2CHVp4 jlAgPJц,km|~niY^~H6k`"||uLX5E Ϻ!/|N&vBeU;hf5Z?oNci2X(o'׍X d5{>31i/) rOBn!k:9xgՙ,_9f < 0X1;ȉ n6c}ĕN,bԟ AbQ_p_Zʞij t;jKvJi*06_ٰbG>X.P#|G)kA 񼪒!̕J|~ʶ@Z'k=6dywZH$SYͧ+wK7>Un'ΩHg!Sf@bSK9dwaEsJQhmdk}[OCǶɭ`f#Io_c, (8V@!Z|r|_ش=c?CЇ=Ð#-Q%7>KBUqCG e` *I\=q2NEyS!/;c!Ë`45Ϗ= g-HǍX_Cld1 Xswmga/OuQ0'rw/O~BW]cYN=\3$*g8c\ѯM!,_IU 9c3Ë%*=G6X4'#Nz 9/}Sʛ{+J}$߇՝Uv\ket!Ns}iȸ{Lu'p.]|cs&-`R&9OSvu聂lNY}[oWkrՋ[%>+tC ۓ1K+ĆL ,Vɩ%!EB"BNF=YR5fF):f*\y?avũgvC+9A_h 3Dp/7D=B'BasoF#trߵ5TTaO~`&d6\&\CoՂ󾦽_>c :4m(^Uo< mh-W{ۡ'C4pEE]Lw/D=N9brD ?prrGg $B3'3m1 !?bW^@Fl!{$:E7I=) LxF^e慺&@N?MͰڐGGQ̓&8t?Ӏ+/"ty@B ` !,s)lWLtF=ɒX,im^305;CksˬLV@Xq^@S]sۢR~Q@= qcܛw!Q\}:]-nY"_9z z>uO#u1Lc*ցwW>X ŎByhel3f(| ޜ8Ux_FSljSbi鞑0+u88X ].:VX%ثnuarE =c|7WjrǣX' | P:%k)/wnVFfAHv*_zP'&8~EBnyYD/_jƚLjڵBA}\JB˩tA|Ӳ+>2?<Er1WZƦ}zI~d(o{9џ=OhD2#0wxvm]JZqctK3vlb:U4H$f+\MZ.qg.:85Wn&] /A-?x6]ʄJFR~!=daj\ sSeISP䢹lo {}g.n0_r QH^5$kjx638fTܑ,MoRY:V,x#uEøuD}X:F\04LQ7w\ჺVs(:6]LKYd]E=U3aҽy/f0dx S`ˋ-i3\wy _$V[a|ఎ?5(L2}6Ʌٻ"XdZ12j!  ^JwË D-S/5xJPpE4&]rR/l,jvDil!%Tf?y16/0Zo@aCiۍ혠"Tsq(9Kd ۛ07îT|wLܧP3$%C; WC$ }fĥ&X nQJ15˚Qfkcu;0ar][ 񳣐i:xUuGx] 3^QWbk!Si_Vdalv}\D1D^1zSwRd\'dw`~;mdQ(eb+Aj'-U e١M, LnJ|>5RGBM`rb7} *W̐u1N?Ի 瀪E;{kŝvwi3b`~BJ#z/gkք nƸJkna_ؾˮ\r<ə7<,Ɣ[="uǁ'va\桯nFv]lyf\V~CaQVO$GO<STBґ$&Ovx-+.at٠4L`*EL?0K02ԩ_Sjج:3e!5Jk{=<ʿsxYb.(nXt-Ik*}7X;s9)0ɖ*ϫ~k݃? +`uL-pWX? 1̈́'6 ǾL'ub($H{ : nx]ML_;h0\mpFR-}zW@:9}ta: t269{6j[C?܃01wE3P$< ˽//h@'vB jHM%'8Dm\kڳ砂!\Ut7[**b^VmmL]1TXYOBpz g5]X|pҡd/I? /lP>:a6q~ nSx4 wԡiI۫_>Ug 1%Eof=d5?ʧ{wn{^F¾ot`OG yniTr+ރyMwz969zF6tԖ(t/a\٣?/f h{iP 3WYTAx]] f \g\ ؏fh[tߕKOObԪh ZKeACsV5_/I iGỷc)0 iI{3 ںO9޵%17|>LT.Ƌ&0P fkp MPm?:R!]Piu}6 ٗ׌ve>jur^a˜TW6ނ,ѩ/ >0|3e޸p=yZ"!{r¥VNS4݂5ceȟ&cQ_g,_?&Ox$r[cnڿ {(ywf!Oݕ6|7T(t-@qtP5p &S%{at\sKP+t6(aNr7W)ȑYYwk6mz2(61YzVjM/GSX? B?6B=ґQL=s]fKլ}dnzEZJYbP}b,wvaD|mXc~e['-Wo Fn0ec{0W%½&d3 A+!4k( Y1.=+c'fm._I**mƺ5?_ ,_'CG<5;p1Ok2wJ1 㜣ӎ׏f#[^:Y)vD[ FAxt8;a&eV]%1-N lLߝh% $x}  M;L_! iۯoKuhi~}j;q$yEi|;ӖQKo|nu -{Os%HA﫾-=ffh2|x|o\vR2>Y~|nŋÅbƖbcns8pȼa΢ uv:4xZaܡ]}4Lqsu2iX֮m y6M4?rTV5^iyL-;Q;6;oe!Uʗc<*xu1!8=,|c0I8V:U\-_1EJuPtDf3f5o4 eJCC&w uPS`uo mJ) "* cJPb28sH.;ŒuzZc|W^AG.T}RCsT%{X?Cĺ ;/Cj13ń(/` >n6MS( =:vҺsW/]gvUp6e\M7bfX'\smZ`"I,u5" 5=-e~t[z[-QD% jqAAu{XC6#'o|x:C:D߰ؐi \)̕ulP%|z+36'Eǐf9 l:mYGWG0b2`+"Ǵ<Ae9Sk}  P _U!W^m{~+.Nɭ*RAmBy=Uv9gcmi9hi:i,8Ut.-1鳦$iw-`mѯWJfz[ru%[VC~[CY6}fv_8Cs) zls߰,B󑝼juT7_,>pdѰY5S͟qkz);\ּ#?xk 4oAvPokԼqk׸bbDvssOtBan%2WbC%y,e6]t]v;H/l*$=[^2X쐜{c* W'u&U]h1wB!ORkAg 7s=;DYf_z{ۘJA闵bXι> j+r趸 1/wOp>YJNE ]ݽ )oE0e/!5yOkTxQ%?2eBfXH ';@.<-:_xb{j/&:PF d!+zLTN7A'>_Wzx N*Bt {eBpIzkb_b/axũdԖmV̠auvYsP2(QyRX=~RW_Zͬ~b21bQzJ?~%hclute@ J%|tj+6*I>WB[zI3LaEԦ$ƐfY5C>y\~CY}>~&GEEFֲ  Cg5{4E0PjH1?KNN1P֋vh}Xs|OLbh8Ro$ۃ+&[>lW5ag\WR<ۏΚ3z1iG6G?raމio_Ŵ~$Q,+ZWo\1-5P<% /5gyXǻ$[<@p,SU_WSlJ2$4+(}vC|~ <f' k/1Arwf16kNy`R]iMtzT{v̝Xvc鑝NPH*>9.#zs!Cyϝ{nyl)RW]'Kiy~8(V1׉@!OpK$Ӏr57v퀚4J:1'JmM+wM,eDڳکy7~{sCTZ/om}E#&a7ӟ&9.[)+FM4o']$r45޵bRSfFTrw!p3zH˼s-$3"_@AI:@ iXW 7䄂-[ڟU ,wvCvLg{xr%#0eqYg.ey0^2^ۼwc7bT¢Ώo}NB]KYy讬dZX㟇P[)7!;F,#'P8 l/dBZZe.{Xz{tW/* n A+m>GGS[kLyj,ʪ'.M&_[g1>;wa'(>#k׽fBtgfD.~/앯 =Ƿ ָԲ{jY:YU!eL@>םnWYbȘ?J7ݙ *ukyak9%l;7 -N<_D<ǯϋCnPTlv Ahꥲ ({ÒGXR!k~nRū|o1$v J@ѺN \3>Pi'H@l-]Z%_vYuJy;c]ŭ'Eؼ[Н/$Z{Ӂw0P$Ibо[fOGvC찠y$Z!^tE|9d܇_fc`jY;֘@T,~m˼j15 o?g$}_:'k׻B_*'7#X0>۱G, 5[k801]ov̏.;H: >gO3 !HM~8Ggz>NGF{^F9XX%Rsc^ wzX?vT1;a`>T.%&Ucxiu|~šwjq6-g0=oA4ڴpI^yEJ]sPG0ce&ib@Ɉ?v1qռ {mB*h퉹g*>>UkouEX,B}x@Lᴫ(ˑi[0T(舟 ns[2’ (=8tN*x*]QRX!C`霒:W2cBPNu/pfʐqJ$ǹ_b8'yc8`{wA [=,VZX}ҲJ3~k?U=2r,ǘ@]{kcB-eɑjbvHюC`sjedEWwp !{('~& ^sL]%5~n7j쓸 WbcHP~* H2fnLڗ>c~X'!z%J@Ȭ:bN q*qz^b.ϩv.ǠL^ ›6P8]9o?:*w} lR?I|5)&6ԺڙI>1X<| Ƴxo^ALtO9?c c/wvΦL!6V&La\zL}< S%O6B/dE 23z-T~kƇloۿЬnL`&5E^ ̬|ΊHT=Jd1Y66q|4)Mh?_p4d:+0c8m= U-3\ ɓJ5!DZ`x<gor}/¶8̻__0fy2'f1vu1t'rV5`1VKņ7X>цd-q#^06a·;~Yrq |淬] FH)F;s!Ԥ7I7 ˁ's85_cOƪ#k.Db^Ǝ;e1_z5BմS\`%<>خcgl1;CT+L8 L1twMV,yϟ_)n~y:qGTs ~{a8]֙9a]֟m!am^[ U)uLܣ{Nn^` 0֌d۸J=t)Hb~ i9H?k{-R>qy.mHZof<{9r!6S&)ӌЅ/[gpC?5p,HzM ZKFf!-H[3RɃצHBJbdduCMZ2+.}4ق #ōr#·f#)S@'iFgI!sfu7dp=Xi?yCrاMHY>U'TC>/~_d[+DگAkqtyJ_GWG&XG>[d_FQr@Lr UEeե$$m/$,)BtHmIݯsMb&qalu;*ቴBH=#T\>>H7)yz:{݀O5\$i Ne}Wvp@rQHpMF#lvO!]j9|ڎGOkp=dםL:xnU"D<ۏYK'*!=|8_z}s^xo/pNtpD?4 ÕI_蕍dAȁ61{qF4b;|t<~5x}}UH54٪W-$pz@ȓH~>߻Hy[̬5RznFҩs u㲶2R]v=n@jO3GO}٫2]B.g[7}-CׅZ\AږSj._ۋTN݂X80}eY yQfgE]FѯHkx(N}$ %[/#) >d)n i\tّlw8REtQ2θx"䟷NrYפ#u{)qVh:$7meY'@3i2H<:7R4E LɖDOL" e [$_s9D5V훅)?:+5zFz~fp@RBj $ NE+HoJ/ y ]\$yZٻg1>$^_4Y{RݨOyc\b䏷x#|K+H6g3\uoLB3H xˀR=xǫy>Ċ=:OY7=3_焴͋o!{YU5\kbI 99^Dx# YO~㰥0QqS@*[@A5iFP'RV 7GNrξdCUWV~ΈqmKHN*9hldڏi F}58"`}ҏDL#Ovd(&Q'sdSA V_CH 'tGe&B~){B7G_C0m )?XXGsly^W8{g9sȿSę,HM,|-ԿZr5Lq[k:ҬsmHvOTdR6j$_ tFt .WNo4t`8ٛiV9d>$!IdJ`bl!RMN[߆=Ѹ?F \/XR6-fCʮ{8Kz⏔YL*Wguڷ ,f\R8x#$/]CCE|.` B3C^Cvpg^Z\%2dpzrq6NBn[ *DzG܄_'l818wU  >BGuMHyZy{ɛXSḒÜ]SEH;*UsݶN"58}='s/Eh.pe!|˩E>t;WG*el$5DY~Q|Ԗ]w;ܑߓr}} Ijq|s.[Hz<}R=;q/=Hh=Kwz G"#7UxF3_cqAu"Ce2 E1s!2dگy~zM DclTErh:^X7 i%Ա=~K߃2Kwٴ$IQ Se(y0PdkQVƯJqN΀R$VöD4}'{EcL̳] n E\ Wf.$(S!BAZ8Rw#9|)nW\R?]mBpϬxWGGO57#j+|g{*i%^"8Ng} |- #{\ɤ\Or[.$kJΉHnTK%%pņّejQ8Q3W35^ٲȍ}(!=Agp c%Y~%(Ҋ3{(q>iBnBlש>@s/w!uѾ{ dl?z+A8Sh}l**$E G!I&q];vOJVz8܅ޟN2ksV" ѣxnR3&N4AYD?yr}ȄM&I/Lwr4Fzն!VoȅE!$U~}B~l\8f>U9M?>.6OE9(/[ْ!KU @{58Wz G,q"t4oiGB4>Ϋ#|j78dPoڟ&~>H,y 1] y3"<>XNXLL*rp;wR 09~ekg8, #ʫZ85TJGk3př Ge$=p: uv6NdWgys&jb[4Coz7 SQ{E~9e}&dO*Uxs*.c_q%j |W4>7HڹsI4RrN9YS-H{IXRtkǜf/lڛ`:l[@:C }clX .@ݐebNuѴ$%ߺmְn"rѤd=_2&Kt2BJ*T+}I@d-Q?$/XϑM)19w,TPGIxLrdN!K#zǜ}źv|G6]W 7YG7]6#&ѧtk;Cj_CH &7/Gm')u$ vl w)K4W_3te/\`_Mc 1H5{Sڃ(3ِrpw ɍo":lCRM*26>>oy}F=ξ<ӥv # f;HaoFܟS'iHi^:E+H'mq$8'H?=۠z·\7ۏt! .I8/ '^/ S<4&6ލ. Vo . N+d9k<3jcv~%%Y 5DbM\(#;Lj(}{瑴sPiR6<~FwTCkz$Փ\Ɖ%ֵq8ck ZlѼ)D_̋zJW=F੶f)wɍZ \gf>?5ɱwH4#P[b>Бu .HR r1jƢHnI.$㢨:įw,R]M!l 8[(u;zpv_HyjB 2xv4x) NP",$yKU*n7®_;o:ز,F˲MI{ݲsraI-o0RcfHسGX(gz ъz(wSKV=q4O]8#GۑX{a%%sg 2fK?Rt+{뒋(6U`gݼӎHQtѿ %D)Yg32 )j]jM;$EJ7zn$Ĺ׻wWq`@2=jOfǐ4$%9c^pN8ZJTJ~9aO:A;wP2H|H gFVWκpc~ݱW3l?Dnz8ւVHٜo93/xJ87\}P^8Q _R>mRLiߣ USH ;m8gi:]N[Q;#FvL+GHQ={N" U|btM~Ǧ1dB߻fӯ>#ϯ'#q&n\3qM_wڔlE0D,]]BZ.B"%_S38MH6ۄaՔ$OUBg al*GPI<;1n\ueLGoE.q%D_4zm~ReF3>qnJ!Gp⫘D'|/")׮k٬MiSEK$59IP| s]]dZ^Fڟ"NE59pFoCnk*& '8gqqft^E2(ڽGȰ/+mS.ƹCp.8ɸq[Αp*syQ.ξPχ3_\'Cy%#}?|ƊmY>> ˆGq!RIx/U$f}w:| I{za{ӉO>Y?Z] E3{7RQ?spu3+-Vqno8|n#zƯ{lIq6c IgS ˎ&敩_ie)׵"eKs#Rl!rKcDdpl_pZJI_ ھ˩ibbt<=:myŶ8?T㋤ǜ*[CpH4>zuw< slw=2lvjiYsϰ^>E۞H ~}.9vm]k~ڨ g͏_<3` bWiJːuh=>!G}dމ?m?l>ke/!%"t[O mm~8$T܇!c9W߇3oɥՑ[7 Xo%ґq:tK114N>TGt/T ijg 3n}:|p.G8qgA9$L1"tGl ;IfYɚ~G ?#i\H}z0RR${*_ #;8ߎ= !cTcwH_zf RmoyN };LBc2cfܗ)8!R蘑>ЩkMi|F=SIT)N=dM+X)>b>ZO\ٰz0Ñ58~k$gW"|gl $J&xQ[J,Oo~9\ҏCRHQư;;?e#啇~ tTDTMЇESV翏t9meS+yH};1]߳̐ۻH߰\=&tqQ+vydt(, ͧHF8;,"RWPY;C|{rBC{4rHzaL# Tf7qv(4G{~#Q~_2\S|-fq7$=W_4d"O^iY2E! ]ygQI>'R+hLA=wفyσ)I ob_C[qѠrCMM4Mqtx>^[!mV:lHGovNզ!ߑ6:8^D5#D##xq8:RH8:4>]Gڐx&7/tHFYpx&j1gJ?M 4;;N |*ݒeiV :>d}ƹj4R ]a\+|"+I>ϯs7IOIO R8 &3|h'![Xgo֑HY{pڈȉԕukZ[x}KHq1g8Lb ݲj9A3~Qu $\8s?RNLVUH x?WdOBA*Nug~Bz;>MEҏIN&fʴivo42 E[H\%&1'-шzݶ0ǭH<7~Qd IVpJ_TQN1'ט" XuEhճ"֧!I#ɡ_#j&-ֲ/pѸtgg, qf8m;C?^=)}v5dVCmxJ(~d;߉#8c 5#T Q/Ejpz߯Ase;%2QHfCH9aA𜧁8M,hwO+"c#:)O.>#v+~ FM'W z-Cz:DV}P*8wR缑nUR>#=%8"dž.ݻ?N}Fn#%_Uںk)1SיgA ;M.tt Um|_}Si ]'Dϣ{2٪ዚ_rϩKD۫]Ufzȴ]NkO*C_=l_ MOaڳL#;˔U_$c5Mٍ{DSϱO'R}ƉA>r<$ )LlM]Jc?\"GnJGOЊc=7/ >߬qfwrg&Ӟxw#̝W& R$:}U~LNt\2-b̦qޠs}ѫ? E y w~@^Vhن>m>ESbHvd?2nvwEUbHjryy2|ѽnٓE@;J{ cd7Sg͏_~1_Sf-Cۈ(oHdR3ncp3%b&k>Yς:hZ1yd9y%ۖ0ΝCD7D.n6ZaJt~}e[g״ 1rgEcPiD5DϪK7=bN{E$K_pƇn9b^$5o$z#:.['B2>u<-o,sbCA?lj\A2PyQ.ZOg}?橏ѣo֊ۊ;匎Wڪ>nb[;w{1X> ={=z/1tHUt*ѭ8$Y@İ7#I{֫DO"R~'cd}3o:}$h+uZIRzk8oH>spW/<&{Ǜ/DWwDd` fR%sՉWl9Ab`!^M;(Wlb*DtYEbSM\7DOgl{b@(V&iwgOI"z7 0n]Nx1:莒1(XfAmՍ}}Z |KsWDq{^Qk/gQ3;b1Hgu9֡~f] 1HA僉'sI|ՍDχu=.qOu(~D.?Gtn {B 0tNt+{ s 7X&ᡚz)es3͈:Enѻ*ex1}6s7dibHO 1x;)Ov2w{z\s'絼PJbtϨdv 1{R!"H +}[K7W۔oǛS#׿>zgDb}簇wTV&}+,~DwX֍D׍~IĐ\RIȼ6g&i>bXEĐ/O7=pxc sF̶e^u{Oqbd tg"rb0¶їR|UN YIHjZ"gn( Ӱ$5]^\ .YUuCSyo~!Wp)vLje[Ư҉7a>|0 >~`11`4^O?Gf]'̶DanUNMΪ#l޶습]7Ets'>#@ JT9JoGtݛb %ꌅk/DEX>kCdYq5^}~V|l%V)84}_Ee#ުA Ys-~H )XkM isu'L4T5>A=KC2] <$}^ܿA޳?1[˙'|>Bͣ!9n !R!yfI7 *ҚDsNCDOyύi|/#BX}z筠I@ͷgnuMxQ9WA8w׻Zڝ'8Aj KCίGXħ{wN.&<7&-׌"Rҟ^EE,bj|LAF Ud'bFI\l(٨qa)'Eny=&m]#Hy@82#r zL jHk;u> " D-("ئ+ǎrEbr-b`GmIOoVRܶT1bNAAD/`#}ۨDĀ65bD́D=bxҜkDšD?-#T&14^VtV {sS[@e 1\ㆡ}=ߘiU˚Mt,k z9LjgǗi]!S"oS&zOUWLlbo:F,ybڤ:b`V Ab;?le 1d6 n/?-OmU}?,N$|)bZMt<ф֍k%z"z>?D)]ބD=| ]8fnP']ӂƉ!ʥ߈w06}5,&EF`Xͻ/~F֜/Gn<0Gf1s_oU>[R#ro`OȺ ."*D|F̳BW25$jMڮ_$w+l$z2\@.XgMX-nÞ;0b &J &^ϲѥD-[jĐ䑹?~r67B2)wھxi~L͏ΜN"߈< 1%Z@1Kq&sb1tXJ%}4A?PUn]@1Ep1D#Q{f_[w"?nd["zcyk &^uI&ʟ,$̻6WKcq#]k>&Uw]: >%:֧=#; m|_{m@u!65a;vɚ-,SzN؇fM6!:O5ĝ@^SZ735fh1\jus1P,:4+ȱ)D_A#D/7abxؘx䓫jwEAGdAq -|bN!1d"f'L .gG iDP\~1:l_#]a$OV{\>c&;pDz#ǭ ٸ`s~9\mg|.<@ngrn31L刉2.D8&@,?亣c$υ>1+J#r6_q&ҎO$ kd\20ΙF'lZ\#z9}E~ 1nΥ< F#ɏDOW^#F>_@dX)K'7\rDbf{ߑIu}s[LzyJ?ОwflCa9~m(ȕ2E91+7_z(?]c&ZߨpR޹}_9=O0 Yd< h)g-ٵ+0w_k};11Ir` rݬ NK!8;k>A)c@|$ɯOm(R"K= 170K"4;<(GDZ4sKPuLTUI`TܦlMGfϲ?$Jэq~# K*nGڛsOx3^B-FcL LQ^M:Wr~zg)0]rXfUvݰX4,LoVO6;)Š16ҾӸީ}ltlR1fz^YK˽}C`6c#߯>݈C4SJ74p.7<yKO0WF`H(ڏau"{=w Qu@*Զܜ̅kS뱗w{]E63`&g*9uP П YIʘ@hʊiN}`/~+Mݡ_"=bbMދ.'?NZ]de0[>m0jd%']Aw,h -kw ,3TL5h Hck|Sc3yd^ڿA+16<#L祓% lQXm ve\VlKSh|ybޱd/UԵjh%׺nwmjuܒۘKilWq/f^ Xc `x\ǹxGޛ٠xs"a; ğ= X;դ@V8ɞ_V.ҁw }>_%OkzBSV'@ ԅ@xbWͭ:8qL7{.lOrf M^29gၳw7J" 0Vmg4RܯA#`+vz@\л' Ȁ>XZ:%X̯r늖#V+E:ʯ lj~70Fڋ0ONnfSt~}{tz! Qǹ__#d^`\`zi KT`+ꡏgk3O!F $ݺm~:OsVAkˉ@{B9yc|`4p`´c@oD%#T ,p`b?윛yN8X|dW 9{1+^k{*SZڊ䕐e^v@TSAȗNVV33Ưu@u;1,[ o":u|=P,{m=5ܝ9y(P'y+nWNMWPMxB U] ϼ֤3+KL;`fml4أ>o .x0{vcpل8NwL5$,q뀥vD%pjYSz`:,q_;nu8_ Q$EzK|b%nYskƵrgݔ׮~u]2h{M/FMRQU6wCf L+} 0a)߁.y{c3@^tbG88NzJa/3z Zo_9a<0xM^YL]M_s.iU~%03B؊x_QsR>Gd'x[1>&>K|>Oser2I` ދX| 2ݳ<2]`*A_ }ޭJz5%!JgpyyкrfF}/D͝*h{M` `w)9٫CۣߡI}O8c1l#GStt5U/aVuCF`ϟ, \Kpw8r˿czp9';-}$g=a@̙-@-Z15w/(be* / E81mY5Tp=ԇkt`63 =C[oO; !gdk&Xg[9@YBpANJ̪t I?C{q>+ 9cIA 4}r۳6d]#1eO"ٳ8<ɰ Zl}gk:Q@ 5O`]z`vv0>O!YVMys|z抿 B] jqaY xP0PǏPs5ۉ8قeªIp.6{g`|d)9 ƙkz<^e~DڋV{q.J-?1`;-Zev㗲}+.W U{#嶥^;ʬAaO6~W 6W ̜cmAxL Wҏ_5Fϩ|q7?m|#)Y\Z5x}\ȍ'=o^أ^|9.9ngD`.<&#zR"=fkߙz_2[>z:M 䊖g@*Ue\$E$g!n^Vԧhrb`$ 4yG- 3p cm-w?0G(Gz-;sGZOy%iHFNh=rV˽%z5ڗs-"g!нR5p* 3C[xH6(}a866c<7qc?C ״_ zع+!/27 U_/lw@ s^an1`t x mAz'`(D)t*\r.{Oq@\pdA(0$|%M;}jƙ+4ﲉ #.XRTv?\wk Ȯ;w7Ʌk <TB.,iw[yR)~Up";ۀyP6ǻv]|OZ,yl]`Kސ>qh/3R!ԲK!o>9; Gz~OQP:=ΣqBw%+3Pi/ '2eۀqէK>lRڋܷvPܳm?Kѷ!oK;ޜ/Qw| 3Omפ6[wXy!o~2m, V{Svu]:`|Ydc## ٳsvf,]`]B[Iln?iZjY`==U swoJ31}M^E4PfaҚ$TfKKh4c,%tjH(;`YűpG@l{L/5. m:GuWK)F?JoBe>6o3*$ _ЋC_lmM̡^@Hg`ۙ~ nUU`|_$Wzqg{{Ȫr9Ԑh{r#N|7/! J ]{[ 0ǜsp]R6O-Qe̵p䤠0~jWHl(ߕzx@H W 9aK}ǮW""`y֝=h}p (_e :|bп'Vs]nْ/5C|?;}Z+fy9<&l!T::sX>+Z_ŧGf>6%r:oWr<Rcw?c7x-f6JcrX;dNF_7a$c JBtb=.6JEΒ[U 2?^kP~@^="wCGx")3o1oP2zUm` / O-S( $4t-Vt3P`^9LUVR37r; (|#j\8_v7lt_dq o *aX‚sgJ[]y%PbT'&w]qĀ;G5%dҸ$ #}oRUdkH̿u ,GY?doyfv __V5j׈vq Qw&.+kM󁴸Pyģ"C|+M,L{ws`=2ɎDI+of^Ht;ب56iqJh`d'dVwrͥw NTCIc%0Sg#ytO .zAWk G>W^tH2X3䓣C_&0_\͉ƹq>N}]L[Omϟʡgв黢5{wwLEBZ~5_An:}3ӯ@Oyaj'4ṮB\;68w![Mx'za5; E~0k0Gb<! *bNwP-a³2tJXJz|_z-P/,ef5v@{ɓSi;,s9GGcm]:b@ 9o,q:ڀ5rV]K7qNBI {0omX]|ΑVoq={*BJ /#A2XSHSc7SXi6#7f8վko޼:P4 o9nyBCn{}v>-qhSH. oEM:[xHnu`~*\|94!i/08k}]CpLB~փ`M?z]Vh0C.uL&hKVmfeC[Gc/.yYXۯ. Y ]%P]ffoœpO{xff'cexJEy;KM 6]l>lj@O?/+6o;"&./6G^nG흛 ){ .k|(^qE&`M5殬?Tq)Z/J̉q;c(-`նf֔ھg CS&5˵5A_Cۂ磁=_%=-9^<b/M4e(z_vsp~Bt.-`Ɛ@LQ|^;v,>h{ ptQTFC%6/ZUNYGi]wZ/0Չ>~̹lfGe9P=- (mV?H1h[y[0d'dzUG3 M\xq+`ʈz6lCQws}H^L<:v7)7ӯ.F8(.g5~s4#mo;rAaOG`k6}=R'}£_$ >@\:}o2Ɨ2H+_'c.|71]`ov*أXVcIj\s^QƼ4z(Kwg-Ӻ;ThPKƂc\XT!WueshC>jT=A8;4KRJ6"?/SY?oQ`ȣNY^V9}gҙ@H?,f4M {LQh1k~}>Ɔ9|Va~6ϫT횎G<}+UXzȗ(H3c zEC[Ȼ3TkZ Ikޝm{ 摒~3C%ˁqˀ38ɋͽ4a @UϪx9sRU!Uk#mz ﷩r{շkwc^ЫMG2^;_Iԥ5RBm`SyV=8%XAkhEF0^1Am(@߯ lBjX.a9ռ2&췑!/L5- ([pϽ{o`ߥ?гS2/HˢSvhItڻbS~2<B/-eo9J5ߡX7ڨzæT}HI;Wī=4,\~5ҁTomȷӀyIFA=i@y s >+hdm[ˀ7z8;c Z\%hS?Nf~=`,}9~tso_Xuq|Jt% 7~`_aw`98wY1؍^b_K*¿w{ '=T`pV9j+}_+9 n '_}Vת{@z_;!wCdvɭf1?㙇Tҁmo'͐֌}6Nmz 9~!@v`gron9 t_b2 KQtU/cily{VZu[4Я[~$gCt {N=6e[!_\4@Qcut] Ԭ{x|J7X5"O7 /@zW%11!H(xB1mE_ڧ~y˒kϫL!w1x7ӹذ|1P49gOV9wC5'7gFn>T ㉚<{B3G{hRh"c'Q~B[Àl(_=\m3Gy`/^!оO&;光]٥O,)* ̒5G}D@RV wzw'-/hZŻ]^Gt} ܎@_ƫC0+n94<_U˧_bWv?cqSxwV Ej`u5+h055MV_20q_RMm8(-t7qa`e`(0<}SgoW}}ҪQ1e?˾Gm< X?z#לVC A7wyuT-&2"GiRm~h ϻ%fj6PK5: @Nl7?>, $ Ko^VUkgq Ww@lbg*i#‘4 7z2JXR͍Guۼ3Y^LN b7ֵs9/7XS5{Y[37b|XQӱeq70;oY k$]@+jY*_ =A?k3 /ǣq?LA>]"?sh}`.tӌp{j{'<ÞSu %h 0Sc Ynǽ}TwS`}5C{@Ni |C!]G+\/yDd<-ĀUyRRx/Zl:,p1{>xmJ%BK p4з/O ʦKq*w7m;+CeX~dPWG>F~ݍ3,װ] &/wbqxh.Μ/R~Ohy % qʤȑZ5?(^!zA& E͘8%{䁺sY.)#刓@:V"!4J=ϗ=VpyP`: ƭ|t\Ɨ+7k)C~)wm>6u<&(:OMgL?_f`N>v=H#մXO9Z$ HY͢%@n5mű8~('|wIwmxP`)\=qn@i9OF CE˓.@}:'Y0`28m ,nUk70oyUdž1kjU0=Ӂ2EE 5cbn+ztG"6/.zYi .rϣ/y-zLyzb p5ՙ*@[̫Ƶo8jJ_#R'/{){P00yl/aJ8wr;/jã@:Du?pF}`,kѺ1cf3~׷xk^qC\ i޾̋1/྽\\2r(m+c??hc;CG|: w)KTam2iTܖd}`ͰnOڢё#I1pbl v!8Wm+-@ zovR^/D/)4} ;eWYx`p8WDQJښ@SM8n73CK;wfڊm;~o %-^؋!n|,}g)?Z~Y֫᠃DdVo ޟctUgZ-,ڶT7G˼8NP??ry.Ger_[|S懼'KWG{ WuyUϷ:Q6V9h;K~n k뗆'7zXhժ\Uego^N?~."G`C $<9te6UP&QDQR?8X>:9I Ve$?nm̥ꀹ%"H^IS;T]_$eyLz>=&ɮدf^yv_,p\מDnR{`ZLx ̝:zepdM݆Wv5R;' 3UkG*k~>ڻ@/s̍V3_Os 7`S*ܟ"q[uW+ x|uEjHڄ}BRVX_,/+gPg5W `Ż!VK?5zN~hKanא<_ۯi_NGlᬛl72*g ._t|0 l[9w3c|Zj[ر]a `2W|Fu<: =ݚ\qhDpl{2vh#*ۀLwԍʰ*,a`+5.ysH*YןWxn{$uCQ _jGFKuϏNЖ;tk&n@&_&tM;ޏ; oyEzq}$xfv/yqk$fm|5Ly['0ױ>> l]Y 2~آRӟ:u7;sń@/QV ݸ!aYsf@>xyܺNH]í%22[j7b|UJɁOd|{̀vsǃu9[P0 m~zs!c@'Vz!7vuet`;;c]fGrk@7䅚xCiVOY3@{]EEՆ,Y2X|tV]K4K{v)-/VuTޟ2OՇ @g_mLUr_XBw˂92;l[~

po}1{S:gxcr{KO@R`b"8вړ+ǭanhw\*)lm_ƫ7"Y1)]ks)4>/z3u^CR+3yχM@%xeeCzy|h,W .%Jb1hm~ m4gp\0||v~pfMwh#m&'NpoB^՟vPͰ*pvEnfG(;AY濯20?gmr2v5DȜ2`әGU/|87K#S8./{_+~WhL@+qXda๰-gN0o]mv{QQ;ǁѬ!%}@OK?p|-vDN_9T7[> 12dKN^gWsgx: #J9t{M]f8PXΩ{>oXiAK]]lh9)W9[8+?4_\>@}o\].3 96 4WRrx=y]\v(Ǽ"Ҁlۻ*<-__o3ܻϧ\FE8ܴnܓ{E5] m T 0p-uE#qEhɟ{mp\96MYrKYs?]߰3~d"+cֳJئ%tnl?̕Eљ7l z/%v-.Qywk (kBv}v8y.pGpX070V ݷh7Hoղ7ȾGMx^9xq/`AP _F*>2<[})=/(t͌&(/{-'g#˖t#| ;4p^ZY7o}ϣew.GMWvn~P1}ږhB`Ku+z?˹Lelw8?r5Z_{Y@4y )\Sș+;Q)%h{z lmI< uxۤRQzp-ޏqӄ6`/9col{mC4%|<,ƀ+?|{19.:q򋽧a4hTf6`ft^&K̵9UCj$أ {0}.f@Kxg \*=`{!A DG9sUq:H)`>03p<[߮15 N  15?6'Z%Un)Sp n*=s'Z9Paek=gνboɍ3ShmGEF th'lZLN?qt2`s_8ODJsw ?Wcnzqxg.2 &tOJRֈы9A+<RV|t]ʓg{5tRNGW{.DȹJywⒻu]$6{On z⫱^E%{򌺟H9-tkp-XjYɬۅfF `;@E|?=Ȕ[̷ -Bp2щUFtU7H2*SwesEHËOǷ́rX2$D@DZ5n3.}l5>oaOGWk  .Wor_6NǎYC-ثXKw<ˀ|0N5=;%<lp6=Klvz]Kߔ ξ<जYuV`)gV??N ;6z= ); /;dryI/P &p+ڬ\/f ^UD%ءk;~^OZ[?_̯3~2>%khL 8k?=qqVF!1<6/ X@#)9.iaonU!kgm~Y޲\s[kœ&EEޯ[PHý![{-h7U`e'rG!r@X FQM{G2<}iЙa3*@vK &[(.ɲLIsbW?/u)r0C%tlh ,q}"]:?Zc\-IC~/xr1m+t> jMnv*1"O^(ﰧҔ ZMPp[׀3ӏ!׎_= l >{N200g?\~﫫of `6(MvD92]O/"?y گD3zpY.??m oֻ""{Ez'se׹׳GW*`2\)ha LuF}3u)#"n[!*y3چk5O%L^fPӋf|A +EVl 'hy*5֚e[ \ːU0w/Ys`Ojf<'t_,=?S.qTaz <@UMc_\%}OD=kdv,7 l5쁥ՖiyY }p^4h xoU8y'G i"`VO(xlޅ! =Kyg"hU.EECsG?DjuxyV .XAkSE=P+Kr~&=zїpZy 09ϫJ*XSy x!aF'{wIRڨ"l}>LBż:H6Kvȹ=j.*I}BM%. Bf ^7W/dXS-eV'z`{I|>( $xpo ̻ mFn1uJ4֕|)1KCì@'N],w:|_ow%
X(#3FNL`hE%/yg7vy` Sw_v3nFQc[jtC& -$őjWOT`=򐠑ȡn:*a ,7Ý5EK<梾Л` se琌0cowm7V/^s)ZSve'XJ-&#PJ3O)U[BV(!m-K<$s}mșMrR~]qμ=Ϟ'q =AGT4/ >^d8Q+|Nِ${ڭ!&FWz\FsE./G){QԎwjT8̃WE3곆] (`3!:oe/앫}8s]iU{|8lL? lwX"a&PdہrыjwzmelFs<zTY4?+' g(+EmC@ r\:^^XLR#Iݭ8s +ʶ;g;M,RQ;"{p VRnq+:?1eD&'>s;rˉF?}k@ c}W]^snܳCgtdm)(w˓^wH~yNa˘yǁ*t tZlSL*O}>rNm@7xz1SCv<dz] `Tږ|LC8C30*͕mn/@ NBeֿi$3Roj:JUO-Uc@5߂$[jk"~Vw֒¦_¾_>o8zۣ?5=&gЄWOwrzX4C<]oRE's2ȟ^n~=#(z|~xNunrC>WBmuvV@tz&Z$mm[{_|Jy9qck=~pO~V@b'(i_t YW'Fs9ޗn@߻j,I}D6==<\8il:-Y2/t-re@fvyi}MswLY綳L-Ǜ꜉|S$4G;ZI5kJ5}1_~(F>Յ?ā* }Xf 37-~gzH@JR*f?{ V-m)6ЮjIRf7̧ɦsPnwh7_8,u.O\7cíS{L|?wj{g6*8uC2\#j.GVak^eUi@~ u#zS'Ώo!EC@2>G)\4_x#@6Wvi@H]p߫ս@hcmax.09^6A[|m<}qtn Yi-^uXŸsjū;Gٻ$m<{:OG95fm:&1Lz1oss69WcJ}tߩ'qnsr~ 7vFYFˠ^ Tn6l!7i|awJwqnp~D ,UL,[BF]8'7N_:fU>HqAE@%E9uAo(s]zR_aZї6=8{Y#psvÞ~jhKoݡdψmR>_1 }$g rrC/1ƙbUs=w5BŇͣ+g$ǦNwLc||׻b|Hgdv{`DYVEҒn T+MykW.ЅzT}*?n[E]F>ߡRTeKqh%uE>RK߽4½9+"oMMe,/nP)~~!]?&w.B0 "]67e(%xf/[[5R׭Ԃu:_lS=nnD^3}a>ywmMIݑ{,rv9G <"ϻerl+ &=c2n8]Nxa5)$iw'Ruy9zʳcٸKc|# J׌ɼsS=ƣ2".ΠQrzȉ6w¯=fYPOaKqF)S;Ϥ\|i5KN< ,fme.;Aes7;A`_ \R,몃h +R[\wkHL@ N[^G|Ū i`{U~_T݋sKmsQFrW!Iv^"PH#@{vNx\SCnm>qFW7.p7%Ђo3,NEߟ} %ć:䤸ҤEGZ!MuwzF߷fqt Npјg` PE>`/ڄsm^->{rԆ^[h /ۇG/\̻ 9kl .$P̄K?~!]&z]QLH.ci e牛 (IqNyhzG/;y'({Ბq,0wF}〽|!xO*~i? 1Hut#F:pq% KDac.,Y@oœN,S#N?^V>jFT!_LWw_P悫@v6 2{m+`:j}qw f*O[ݥ>Qo{"rfQ`w^;`i/ OVw^%0 K?|Ɯj[;#џ@bRXԬۏ -+ wdym|ßñyρ:*-+2W;:hvB?N7bZ\4^ﬕ\3w%{&s⩄mjdضv'M x\g@JW1@>|P##*ޯ>oHP.jr%՜<󮌶&gvH,iʝG^ 0F-ɶ}rE{z888Qqλtg9uf w>e#@jywTi2؟&b霁0P7'{'Ij0"xs +/x ! *L >;؟ m} 5/mǩI}(ؾ swXsa%'U{^yp=ۄ^8p`Nʍ9|`8D~ &;iw `D_uQAb>I&h/]xÙ"=nXuu%ٻ{ºqߺZiPsrKM}&gBxR#87칧_knE9pOLv$G_'P9@xAfտ;WjQ*Χg+V^57#G ?۫K]}؛Z|;T+}c⩳o#Kc|Q>]0"{n G3/w,P*qW['69h|Zuoso'>IN.voұ7:)pt(yb=" 8~%17#̫d^l-q?@]~񰆇>kzSY'}iνj ?jeZr!Y Y|yX(.1wZྈQݪ uTdeR5!S]Nئ53+qā+A[>D.ݱ &d tM+S7{~q!fp]utw9P7УWߟC$.B/5{Ejj\›a->~i9F]W1OsޭPv E449>gll0 ܧTtg$2M ݽ;'8Y\shmt4򿿍S}17*;eOYSag~dM.{3,t_s`e_3Lui {)8o40Ky_]b?pJ\4s9}w[}}Ib`} *<~OYn,x 8#7ǖ->IC,;<_[ "G/¾ sb ?z;d6ͫ'n?Rӫz2-=+٣w2S (Ն3qamrG{h|`V*gأ2Z]GjKKw[hWϐ|ڸfZxozÁ|[GknSٷOgMCx~s,po>I_ &|rz"tlRZk U}U/sc9$0O !/O}'CZbzfkzO6@-M{;Y?Qʲ}0^uYQ%&s%j8&q!zӁ-tCOlKo(M S:GHǎE+/juW[7 UUܺTPF^G2u{5yYe;#b%7Կ~Z.׈VTSiU:x[PJꈷ%_ߟixT/6pfi߯[iR)IqynMppi`oQ]Wӥ=^R;wmGh`uS4̨r:5юGѣ~ΉrhǏՀݼKq8%Mr8T>byWN|@ۥlSy*!s$sXG6Xcٞ}NP1;X]ފtS&w5" ǵڷs2zS60^UD'D e܋"Q^;Ꝼq>zVb-J[ 9zlWYdz?W5lm)P"^O7Gx#g3yP\ukW' ?*e|/`v޻ 10ֻq-sURM{{jk |4Foސ ܔ7i wKeowfpd%xwB*zj%d#QV2;<897I^E;3c<`OUP1z\GU8[bg>- Z>{ _ϭl=T?]Ǫ @6o+B@"UZ/as0UZo>ΝOK{%\ǫfDQͫS؅YnfºJ̩ 0<59vjpmJw <]Np_yݯxVa)XW%r]ٕKgcZ'p65*,_%"ѺCE l~:!?pJi rQQ䌱7`4g@M \wM7:7OJ yPsTi,ּ؂zfDAuФ]%/d9΃jL]C؜'>AX*dGB{o"牯W#-9*NIB4ς}m'IL qiC}E&{ȟʚ9bm>s "^.ܜc[Yk.p^ dwHLoX:QLC^9,lUFPNK~`S2L'Vv MQw Yq[+2ENk!s8sq/h])&8#gF6,&=Zn2o/FWZa쳷*e ϳl˳3E7uetȮd`q6~u`_ߑwQO;J."ZG i3uD ;i_om17D$#C>|R`Y7"5d YlS["E=bsUDiRڂ(:1wlACW/ǜ;D-Ձu,?ܻ@sV_U}".[ԙGQFO7.Gͳе/? "7Df z3:potKT[%bO8(ͅ"X>$rJWS]/}@=g#OE$>]{)uUD4Y!a0cGD} _C+Ρ>$7y }[~)"Z sUs~W%~Aw`а7~ n0!Yk+mugl"CM"=huq#|/,ya w_|!3ɇpgDQJ|TEN#rXIDnd?ID>v-40g>ߪSz/_;{4//4%!oî!1A+R)IlBQ+WC<qNA(o%Er7}xiVDo{`y4qԧE(ޓo[T*/4;Ouvڢ! !kKDet">?+fZX/,9_VA$[{ C&>Z?ҠcϴWe̡)w4}zc"=y ,}Ҵqۿ{ ;eW4T78؍t# ]^d^jխ*79QS}z Lll/9e.-V47B_μQ;]zcbL07hOL4"Mm5h[Z@6"| !rj1{Sdؤ`"ʭC3u \1} !*cO=ɋMkͫި;5!3v<<KeHa3IxBZ\<#8{ne,uBĩ'ݰn*@tqk7:=oOnaogPmwFҿ|SvӋQK;Ӿs ,|f]sw`${pMAsDꌆog^;O$vE1^mA4h3{%"=FRCkZlFn)SWbo"ӆH\oc/}z=KJ $x()v=m>ُH*J!Rvoqe ?.p?TV.1`뫚jܓ|*d0gsBN:GuaWkN<瓽:]Y#V9-5<Nyu:pgXu4{>Sh8MѰqXlh4X`,L/cN>j# )EdqZFƽAD)Oh(}ïst{a{95(ϳnd}yiHDd$"ߏ>>L&"սVZ{l]Dῲvt k_^F=O؏(ulm@[c;DsJY3YL6=挩&iE4x8/ǞJJc_N|M~ !uoi˜ee!rbbf4`u+vsuFSRbՏ1dq-V@?>3dkwhsu;k ZJ:wZձK<<=^ڿ,5}HF} AQˆS^{$ݡ&,5zY}XعK?ЀZMB"8<4o@D/F#D>H "SAA.z0_ rD4[tW@F%O*묺Q׫눲B´D1s].]f>{$]dy(~ lB3]=zӬSTr4!V[zI?yKqyynF܍HQ+؛р sfweꯖnTz(#Mif"z${Ihᶵ5^Ȥ0}q,ㅍD.buʬc+x??& YDS]ތ뭢rIs3Dx5$ rM30q{x'^ ,P~nٲ--Pfһ ѐo"ސ87ۈ"N{i}cX \-2۾K(/~@+:Ym̈~ҝtx̺md`U򬲗" yqQv' nDæ<bQU F5_I8)Z<|{po17" U][UǿwQjX\3[$\|'sveh(P#cDbbJk1z4؈p!_Y+;owD3Ζ@ӧhx.*VE=AdΊ; p3Ev.{kM!‘1{t7~MzB!gDL 9 8ySϱϟV;ewWYU=?|llQy$|D o|@p=jIu6*Ymp˞E- ufgҏV)jC$r^]e}.|]zi_CrLS?Ofs͈5m3h!H֑L"J7hrnW/D2y$ڍ"⡡+_#v_%;#Je}_rDBqJG~c\:tԗ/wy6u*읻P{ Θ\g<!4c$?)J?x zJ96_XEDpM᩾' [x>^CYY$ ww^܆&w",^Cī _h)5TODC=ˆ[$"wiӎA,BF{ QxoHz؈I#PVtC'Bfzfh)ӥ o5LIzRK Ѩ}:*UzϹQs̠-6>8cj!Nkg#D;{M+wY4X`4j8 <==A\x/p^(ԙOPT_=tvϟO?@#RB ݑ:ړzH ҽut׽+Q>=#.CƽixFeEDrx Z~{nkTE}GU1D6W ϴD8g6KϡB+1Hǿ /||+Cݞ]_m$~C"mǗȏ\ YTi#Wr{w^aw}RAe+Gn۸^|=Ϻkv#k㼘9lG{4#CՊo.bPFSx9ns?~M ^rSM{B,Y4C <n>CD/w)G0w&sTh@C7~RTv "?TU4D|sLxA!ݝ?v"BKqJ38|)oY%D|:z] s%b@c-OqQ;b`y{{|8 `{WPkgv7}89yO˶%و2jLYJeW9rh#FCM6Yh*Xz3$̜Ԫ@O 9p+kUЀ֏iJQ7#b[ke~s/mBCޱ?{lӱj[Uo=/?,V"NC+8^);di"^U6Sp<ߨ-sָ&b9Vגd\St8C]bζ ;ԃOs@7lLVf~dX<7|?݋(&l/";Ŋk'[߸"b~klۈ\tB;lJ‰J| ־9D, ,\ƜK7mޜ;IY(8EgJBGe:ډ_=FD-طhgG{2&Qtl$Uvu!"Xm߉a".AOįtPoMru<* b8nTFQH.f#/U}k%p?tB 8D+lq878d3E}ٚ"x:MPTz]ι|2`3"X1 "㏣{xR^Bw$O:Y9^ |~ʧH#RrW<?Nd Üqe"|;2=_KA .ޣG:m a}{p TSy戓s-0/ڣw;YDq79aE7h ҄RA@/ZT9[ϬB_|Q~y[B\D~=!x%F h#a0®"?qNwB:]K+q)u%"o.$Gq/i;> Z`?nq"*sGOeE+i*O/ub6G*sFh|VwF(ǡVsQܿGs]aB8ϫv!|\y h];py8:ewwhIJRDwA{Mz\Xu9*"rkqJ]cے$1g_'wSG@ѺL=[KGQOmHޓWgЗh.JHQ {u7mGڷlǯK|}CreKѠADnb C/Nz`q 3{Dxm9n~y0wwu;i4QB7a*Ïlgϋϸ()ӫxZZ8&(Cʛ6c!"K\+%T`T{u/QF&'0n#$[4"0b=QU( ؍IcjY=vJ\?Uz(Ɯ|4r{řxT>{g&hr.6Ӑni0#ĝxz:IҥX"=)$k АXn<2Qr1`e%:^Ol} S ׋]ŵѠe eD,pq!8tpUN|#"¬픊ſ F]<&hE"ki"}_ Yr,1t,A\2QUs BBө`4wvgFn^WK@绻5c_"= _N7~G=v-i Q([}ˈb-j꭛H}]@||c~(e,q^K=!8~q|])TXURC$| x4~h"ۖūL| 4a:δ^Ƥ'"֨_} TA_Gc8v20_NBN^tr1ߛr*NˢS-1PZ2}DV#u9u]H >,Y"<̓Ӟ(1\y-P_Ƭ^4[5h+ cl: qZo2Tyi& 4jCp*G3tcܷks6Q/qVy "M.hkcȵR9iqM+:ǥFTnDCW{ 1\"5C2o;Af2D.08~.ĥ " J9Hb | }|}Yh/DmɈT-$A":~sGٷ_a۽orl0E Is\"|a@+E:وHiw~x6U5vaTDzy MBބ͟9@,D' gE->g0Q + 0xr0"[GCѬ{$ΟZlr=~kD!%aoG}_Rmk0/6߈9`u>@%#_n~nX{Y~c?m:HOWh?F%O+簱'H |a"['R{[h >|ؓAD<,}tlM .?FB}-Ҟ"mQmD[۹7: #F):UGFc_)RfO㹙P scG4𔪺xY왳Y#E;oѻXD> uv1}<t=aDT|=c7ic\7hN";."ŝϞ"}hp~@c{}qO<͸C@mpG.sFI4✉|fc޸{9?"e/ ›9ث DۈcDjmZن^D۞~o5DI ^Dž GfGЩ˃%p^ʸa_'i]DVxmПDDB{lMDl-ϿTHaX烺dMlH<} y]ܙ ώ\LJ@q֘BwM9'ne>G JhpU;x;Wm$z9Yywy'šޱ Zs'N-*^6#Ǚx456B"DLEDn8_y$;>$ց(~?qeC.ԓe>HMRED)مH;]W!_.9/D4"|;9&&/xJ2ԧz4 OD0ŽH;/ HF$3~$fxAȗZAc%b0>fV;w ub|[%ߊ:5;wC./Bt#!c\*" }) <„6b_˪+<"cp_d.O_R<2NBS5"@XP}Z}kUo-痚tD~*KDL+ݎ\܋B A3w%D}4G=Ya؃/usp44h#2,9 Dk3ߎ֪>oA=cR%3Z`k,J`#rӞEqK>琵"fwh%دD RdGD}r/p`{YW#S^ءϞygzt^5qnpk"ZD'/OVNy~FM~>_"w{K^x;ZtawSRԗmbi;^~~gݫ~e#/#ro<.w;''p>+H>qI.٫Aegq8J~:aOLLjHΏ^g/k[Lw?<BE4b])g\>(=zuQ>?}{勓GidR/hu vB JCa DYj:+sM7SǟCh+!Dz-&q>{ a/v- .̍^N?AG"|!ueiCk^CQ?mA<|ק"2^!f.߮;q2xްS"yF6s>rl0hSs;w颾bmwg8Fh(4Tx>!D]³m%vDR :H8sB^J:?CύCBw7Ԡ>-S/N3"/劭ƾy܋C++IXxɇ79і6ЗOsԡ눘#Y9W%}&J]y.[+i:̭K x_+??&ִ] I*Lw|߀}Wړ`?_4۟`l];p]BÙLaNAo8-GM7:A7)wc8"3[ofJJǟh@No*uqFoAGOwtFZqY#T/~-?3+?;_7U }սt]q!kB(UKARiNDtVQ/ ;|ܩ$kEa Q2 ҨX!>®dDH(Yu/t"[*ceD*Fġ]&ϏR[: %h"Ke[KZBhyW|~3"eC䙃Ͻ`nI~m}0.KJ_FL;E.[j T1]e&ZI{KH`iT9/]̹&`Ϳo UzmUE`~V =c VdLmp vwN1m( z)@sbrz8{m + {^Kwojv+곏  w4tJ]XԒ*Fܩ[GW d B?<]<}jI`3yO(^Z01(|"k732@e)/M ~Ιq6NqPonLv>C? NXCfn[Cfʻ bt!+^U.2ldx.OFz;^X-5UꀾmP$" s~%9[Gi`m!e?qL8+)] ߇o<hҁNW0gho#PͲsd\"?0n~}o^lȫ d3KÏl=L~%#2 ߺ%eEظK,<"K($k V2pbb˗`g_jLɫ>ׁ)!wp]Q^jl'58g׈k[Tg׳7h&_sVݶFuɠ'Nl ƃ’Ut_`y)cOhWS&N;3nn@囷޸i;N?nƘO2% ⫟Hp ~沤n>_&l"o.nJJBҁU誶8V^%8wW]7sݝ$z[kSq9$X8pUMoީsՃC޳29/} LO{hTYG7'd(Dz%C=ړn\g~L%`g*>־e:%\ 42:=!Co,#3%ҒÑ]WG9mpl+?|ǀA3?.GY36RNeH7#0MΧxف6f >#Uԍ"}30Cǭ&F0pxp8C]rm;|9: tc)0ո?\^sT4/6o&&xuo_m5<'}/y܁p0z'l,q|R%JJ3p6innq^QW\½~Ó)`0 m9+x%O۵.xoO-q"05ZM'6+]ҢWnawf{ͪ5 *X3"csh>mTLO~}/i#؅?~(8ӓ~ťja/[Zv{dIɽ+^%9^`KS" ܔtL_yPvƺ/O4agk8O sV g6aTD,;fάpg?xheAlϩ/@? $K CߕօL=Y;؁^Cn[ ߆ïv้uoX gqyݿZTH6wT2a.n 0-=YO$X'ycw`L3"cf[`.+QzyA/@|8#i 0^Ū[0o?]/ rHf5uOR-:&ߗGD着t!HLnݮq|LՋD(++:zdy$pQϩ [᥈;e[puF}uuGժL`૑sAF5؞i4/9^x}e~}$<͒DQU'w0vaU(4ۓc2oS[ I/][ LOR`].nP4+*E5A&]H\;[5"-A\OpJoSO}~oDŋ=0y1DC|觭[wPR̙ ` YMg؁ZҸ/3/s3|g`m],ꐤYܻ=8|u@!0/4Kuc$ ~3Ι~#E38N9ص莈kK9[/cTRbP/sCU}k>`XYxFx#`1g-āY<ogrN͵>/CVZ[EqWrHWQWV]L M?ʂB{ 1O\n2v[`~02/\ý.\{Uv<6II-JZ& d[̲ V(&0ѝq=?y=s>coQ1:Cw0}YwOb$\ip44KRK%pvJ3O g-Xt [Ulɥ ,Mǽ~*[](ŜVu9 WNfގb{.W]Moeߍ<5]OVDj:-Nkz@:ٌܘ_svS@kmݪygh{q3ak8ս}9jE^=2\_&(0.Qe|ڊïo%bߙ!o s:Fݓ΋R8\{N LGofl?_~;/y(R 3ԉL)I)]G``7[z̏Z`u'[#=Yi:)>cw3`5vƵ^/Z {o֔:V`^R{^^P;0'ć(pbB_^?)a/lYk 1?3u}-My%c29=Ko;^ms' \[iۀO8 >MZz?'  e5W`nZ>6 @S Fpfu`lɼ7SwM_ų@w}7͞m(v;EʴA4K ҃rj8@szP>ǜCyσ7]DM}Q pfѲﳗpxȩ)}Tܿ+ֺ=Ʉ-ش_0fQ/p  RQڶp.9,dny3zsjN7oC}B^`7j˫wfe{*mke[ r3Բq[r%0\,U"2Dh)[Cz+>Nkޜsx%Fl !] Do1\R۸o?/S)њ7N匑[OuF&ى=|7p^eJa^]8SoSqn'7ez1ؾFkit@&,;gW P `,{ω z2xul_ l3յ~Yƚ} wTI:2pzc|B,jƇ֫ f& P瞊gg#_i-kW{be\|9%< 'H-dІ\Jt{w-{zXAٵRtR#JML,]Տe])y2ח-gw"SdcbvHO}zBu `LkJb/S6r2Bc?My|~\lr8~YL.r64qX4 Tיк~"{gA+OB`>Xs4aWEZ@Zd*l~2"ksq_Kc"Q+/הmrk'xN`Jܜ xbg,|>'dVӒ> 점-n;|?xJ3JiM8&{[-hޥLG}^S4Ky `o&߫Nuĸ`_"9rsۯ0n1\](yyUƃ{hޘ|:5'sFFw`-懗ci?tc %yE~d\OyW78zf+W*W|1M^=[cc814uw5+/b>%&ۯ˜צu`{]W0y$a,o`ŊG T=aKTwP$M敎OsؗgZ6^[JY}@_:ΩJ6RsUF@/]yU< >*Jd+Wcsn&1/J*Hk=ꠂX/hQׁJ&/W^۫ULq}Ns1IVĞNJ?T>9Qfs#x%݉q]-K jL[Y;pz7r1)Hǹ߾b,M`/T:R=91kM._qQ8;Vp`?0JzqoaIĖk;?h;{wO7p>XiŴi?~+>nk<9& d~/:+8k?ێ`X (Z Ef¶DJKu<\u :^mUUzj:I 1= + ~3 M6@힯y-z l9SE78ZX/6} &֬?^`?г6>÷*|ep4Sm EyLΝ>@WKV%w?^sYӝX`]1;g 7v90wrUvsl J>ʅhe.s[W[x>3lۉk˕FOOdVK7Γb~=w.807q=9aR٠kOt3 4:sWAFzʾX+-"Y:{h?i5{W^_,g02zҳ*Mq}j@o*-lw_T{&-l WQ ?~׺SbZi<̳ظ`Xb_1GX]/}_ pKƼT!gwfb~,FUӧsy'7F&|1GQ;ƽ7u~p_f{4ٺ撆 /m㥱Z97KWSܞ(.x)z#lL[8>zIZ_5p7Ixor/`K~ub3|6p˳F6t5p|qKmCdn`\Xotq?Lّo5臺B5KOԎNڍuP=\dk qR:33kWa@/O9] K XT>ƌ߱> l>Hy cF>^{Q"CݠWkȍpO;*X?*{Nss__wsv`B eӤt|SO+}Oa`WZ|X|h `%l`SzN`tJn~\t4 _T_%oo,vdMפ }hsr'u\Yh+>ǒa<1(yW @jہxSʪ.2@?d5^0cIY%Y]|>R/k%?.P}Uby;x$KM9=Q္X2vH0'G:&N=<5X߷/7tFs {u@;pi=W gd&w3K->{Y k{kS|y;ɧ@2s*TLagM2#^xdJL'WJ$*L?}݂~!a 3;/=ߵ)+g \v\;`6'm+6n!PJX=<6kZ0s>^2 L~:'Łs'F5_xS Ynǽ$SwWĝlY+~;߁*J*& ,m7Qk!4c+K8 PdUΧoiY Wm+pIV@yJl |m=E\_Xy^yN!` >c>VgIžp`,})|"[) 22)0 5HbkxV#Z`I{=ŏݷ,&]WH&%~bZP.ܴΒ@WfM 3fCq\p{HM\')*hr@EԝCڅ0n$9͎{V-v4+`?RNdI?a1^{i}@_B80-ujޏ1w9,n4r3<7ad{`5%]vN={5bn>Ϯ7󆉞˓R4(c'tI9W`UZjEv{+n@ x1]`=#>{_-\i|vhxzB'/kv z>Ϸu&e+絣R KS;k_\u` $TmU[ws4e 3S^8*%kyWEJ` V/1ϳb\saQ&ō*֠; 8 JSADL }#smp{~Dԟa 9*6T _9zm}) wtMWez1S*O%Xb*$-yx~e9ʒ?X$ };8o^^le q`Ow9ch)xF/Bń|?\lifGbMQ=MS,],hJś}{xWX޺$`8m^,7[ok< %5?'JkK?,%{i~LK2ٍykTof(No-u[Zn('zQ#;s n;鯀#pw߉8)c]#Vs5)J5a~Q85Иvs }50BsRu>qxh{Mƫ(CBmOʖ¨,޽ {NJEfAs@<hTz`H]jZ,eB<99IЧ:K9ALX h{vØ!Љu ,^x&k]S1~t׎+~&~#9+sA@i NO0.ӭ XNB; &pr߅UeO@~30ɪJWlF&6YKlxEm#Џ#}6=[LVIAK#^aq`?;(yWqU]s,P#r +c?3ᣒ_G LIǟi"7ZIs30Sx%#㗁#< FLw7oY \wX[|wR[`7Ƶ@ Zdx1:tϿ]e~q"#ޫY뗀m/"z؞j0H4 ؛9;zb #dgRaY+ZFCk_lZ g!KS2!O>soΟW{l!ytC 0‚w|L'97';LtF}_vKW5jg) zU6 `K㶱sUdf"ף /{v$|'W}k~F`%kNL^'E^n*5&7K-vwG%,}L#-p΅Ya2S `m?%GS01Q%3@x ߯\M7(Q0^FƧkGT\a֞TD [m^Kqx(ޕAG{%ͭ*c 8G):I؋z] TT#&=:*eESq%(7&1^Gtw쥝+8˱#`=}hg3T`t5{{ͮFWd?_ԎdvGw'qQ5ťU C2ك{~GK왂xL.aD+0ٗ@O-ea_zX 'υM=jg04:o]ݎe q0i2O-_OO`o Y6{_coݻ1 5L|#4}DYAAhC*#nSyoЌ>\{[` YE lq]s$ 7&$P:PbQ}}%uOaq:au& sޱ'\"j*Y/vͶ~iI7ßl2<|$ p֨hǼ_ {E^KqBGaq`K9n4Yu%Qs:BywTbqyX 8R~~{}0ֽ9/ui,!>`gٺ:̅{ΈXne@?x[^0-ΊV\LB`i1pn%rknκ?9%5Q,'_+k9݁Ҟ:6v`S~^n̘*}}埐{0%mvZMYu>)<]9zB.;?@#E<5q8eP:\hN^!0zC'VljjW)%̩)*y]}2lF`,]eŋsӥcow1P.ep٧[#sYP"bلL Kw뮔Ont7pB u1>NT45Nd;Uh2ML=ߋ抾 `3uf\ݑS'St: #]QU]=q] *94J*~?Rq >NLBޭ@7f#1hU߽^߮A7%]C!Y`H~zhWs8o~ jzrX^9^?d8` ʵ<@g%mm9Ra𣏕On[svk`멼3 xyjGD57IXAGq+_+?,9 9`VJ(1gt3#!%q_p}oYkc(& <~l:b󁘣S EZaܓJ_#O:_53ہAp 3i,|&^WSAO}ZKf]Kǜq؛/GGx0Fu+,NNߔ{0nJV!YC"~;7u`䬅a;sE%E FSKRxErjt`EUET \Ƿ"'|Ζ*Î_ٹ K܋ҍk/euGdR?_ε#<2x^=PÏC˲|{ ˱?. 0\aRo2xf- X//|'+`ꞰA`(¾+Hy`%W굋gב7c'mxlߗ}d6^8=ERсY%S;Z{?/Y6;9J^^o܆`^5t4JmWۄ5;K8| њ^Ggmi[!B5 +֐5( 螟TH{ֲbd1Q^;'xZF;I3Nܮ{u^șN$`2=\V=֪̈.NP7i+ؒOf`"dsJxnŢ>ɑk5|"|9s?!F{te\\\_ "wҋ[w[F,+{Q"|YŒ*-%ak=)OWjpg^spͤaR/zq_{Dz`{ȬS[%J.QHB|+`%g7?ZzQUolHڕ9S8$I ~zM;.,MY]bۚX0cS{gL`;? Æ{`3eŃ{N]޺SB'Z+.),KN6׉>IUrqbc`Ω8KF4`q?)FEρ#pɆH?1\x+O0 Z4Ρ/_g(7j:0!^<=jh?ps>ï'J,H *F,ҁU_謯@?[1gDsu5>W{h nRqj!:v'ރ@=+)hZ,`*K.YhТ39b>tjďد&`/zMKEVWۤLm<_-v/Vѭ_ٸF%\QY!,/vp ghx.+ WUws`&VMlK`&9aWZJqدΕ^%&]1˝N5%7cOk-eoѨh|4`y>Wm{4(uCuze`ys(цLS` ųiI{kKgY_Us:HixҌ<rJ/ہ)ƞ$[IH+s2CjW=­߄$8me/j :y?;ye0+g4HmJMݟ:o=WΨ +V)L'.>WzJ Xd4טWi36dlN1O:U_=47{EUpڽNL? otL+KnzV:O+cP5I qg͒9`_v`^ɴ{ы:ژcy5sW|:p؂~-wN)`:ۈ:s>Ay]\|1=Sh1DƘOX?k{N|s:3*eQYN`QV1ë5&^>eƁc*8|Z_bfVvs 8זyRw>|XA`ljobث}"86:`^AoG3WxǼ򺥺[ce'.8X:5me߁# Ӫc5핚%0GR"TD p%#Vgs?ڑnC3uC[>n&|{n>{[lx Is^P>ѶTdtV=_tV\҃&' ϖ L)7)}<?69Fzןkj`8K)u[scD/>f #.xɵ &/@opP|~d\)GP_T{ lZb~ɲ0^#v,2 de#x}W1Η~^߂p'4noA @+ogSr,u-zA;[ctC\()o.o/Ud~SP?q ׍Ta|pdzg-v}9WǶ%gh;?lΎBb1nk">,\r2}!ľJR8}Tr;>O-Vo0Ctdxq>}`_.pZFͶe pOCD\+{=Jb70+^KaY ׬J<}6y3Vs@:Uż 55a_WO]=%$(0gbX}&0XSr>0;f/0Ug]̾ȸ O`/;,{vSno|W1},& 瞫 9t10jeM@pЇd$Zbpj.<C.lA>faf(lMB0q3o?uHflG`^۞Xo@orpŋWЁ܏?O^yW Oniƣ$:{OT~\jF ~r{N ;zK=qMN*oz KWzMkESr?aG:>y+}}n}]Vi`vq__i>]I OQy,5A \Q@Zm+/|Vέ\2cVs|`عߥ]ucG}{뾵^KOjeuϺv孼{MIV}8g3<ͶL7{ϒ[&qn}xvġ&Mk6gG*1(f ēc^N8g0kGu*ը䐽eX(T!ˆ; qج{c-5U^x6.زccn24dC>/w6ˮ-̡>:~KrQ'7mZBWX@n|7=7Klg}7&7xX$`;{]qs;~qٳ]w>)?,$V-v N`׃S9yF=gwY9*>{M@S.}W9<M}@I.UU@MvL6p惏^u=XO8^"Պ@b%ߥLroCL5> }.}_ڈ랷a׊wݹ$o//iı(5K"PT ʥ|&9GR%O cn;ysG6"7|>jwELΥW"fCMgX<ύ{^!^Y1Mٟ` ~i,MDyuO)#K(vVqY<8ωV 7LGݍ@̡Y?U-SY'i܋ۮp0bo[Z[v ǿqI8f6GǏ^yFA=W(~Aܦ'!~ZDN䖟½'$K ?ܖeJ_星gx1MWa+Js/F뗓(b|b⬞#/=2h~31|"(_VMݓC  =z@\@Wı8"t0""g]9MK>nR;6v#ք;.s޽ Ɯi3kE/51gCF~X_wN8i!y'uSX`1c҂Xn "ex"R$~H܅O9.=]3zF qE> blji8NDيGSK^"ά)̙ cbBy&xa+7'c| 矴}Q%5>Q+ )D\~W.ԿinGJO!iVcnlb/ݏdf e3}Rܶ;6(zYL3ο ~Ov":רӲX^=b[}>_gl:lADtMMv:qyР^q?mw7 h?Xz_- @ȱ1z#/X=}' q<~i,G=swnwȡu[v<[+F1g鎶-^vMA!ʲiD f[I~2z-=D<ᮛ_pk׷C|1:])7u{7s`/Ĕ*l|E򟍹Rqܫ>ot7߳)2ޛ@դs2>}8֕!^я]|NT@?:zR@qhWDT߿SEċA s?4==[ȾC|}na4?w! 7͕</bGE׃cP퍈s1_v[8q -^>E t ҔYRY.xk[tp |r8OVx=. y5i렞lD|7[[NdMFܗI \OAxWlA0S nhALjk]'~Kp?%Ӟ# l!WvF W1[ɋU4ʞșcㇷ A-3sUO؍x;g UTc/tw1Կ|ܥ{պ͈]{co4dE^%Ø+\WDzv[\c!V8^uň;ʹ=b29po}Nu m<᮳U6.`^{gXc,մi5X+.k=](7~8wl>-!53gCDٷE}N5. $ǧU gwgys#Ӝ^GkID_xsf'M o==QZ'!dLk<(96=vߧrDV6;U\ b\Zq7հ_~q.NGLviVuUϓG4|Oyo푈=GS|> r# &)E0^w!╼]V&. D"5´ƹ]tŔ" B̝?eʵ^Wsn/yc[_<qύW`?QJ?*ы-k~:b^Ϸ eDʒS-\pwHnꃸb:6szݏZJJYQ}▙ЉFշ&#vPsJ ?9+dQEdK;1 F75\. SliS4x[r {5 [jkSֈ!U]C\~a<#Y~˗V5BWq޸wSu9]:^Ϧd7˟/=_mA}Oh҈޿t3V2 ̖DD>q9ơڢ˴h/oNj<4@}5޲~nWeVZF,b{9M_/=~1Vl8VsmG_ht_ы9}`_4{dP!"v_9$xo7D<̿?>300K0yΘ %_6!Y֟hpp='aRۏb;5#ƾ*]ن9Lb^q'qڥtkuuKm*g\E17sy_tWS\>ݿa+sW٣ nEو.Rqmrbw@#yԖT0codOnWs0*zyŨH sTqR\#XF&BW`x  G"Ѡ*ICqLI#lìnMYKuU!9ߎE}$0i7E}UJ;;^ yv~nMk3"#tCR_Msӹ>oѮzls:$F."g,9ey3sw~"vlH^yd0 EY ŞiÇǍU{: ,AT!|m 櫞!jjC1޸ {~4(5ȏJCh -Luu~FRwO"q{J创^"-5'bp -<,K@rPyc7^шt~ "2λI!.(d&B"ͧ#v#dx~ZoiQ83'%ɢsrԏ9oEӋDyvA_|^uֱKӟyg)^D{Y瓺qSV\GJNIF,nT";bĪqK1zoGC!BŮ$|k&_F͂?T`~u !4n{ҺFWNI)4T)4C5͚;oBNe|ߊD ٱ?~$}5QYCTa$yn)\v lO܏Ř4՝ڧ>qe҅_!m"s(g~J|1G]YZts&b?2WmhI_:E-HMc#C j'n{w.jqU2BT+,nouCDEץb?ϓJ"MGw7Fsl[@}]w=*{N ;2UwڰmB7^wXrZNY1gf7\{E􍽪n! xO5Mj/׿g}p,S ձJ+JS${d74@ZagSܳ- i ֑򈉜<U8L?>9F\)V/m: :Ӱ™D}]Y'sUB>"Dƪ :{̮@$mfo.V6!%u}=D7es>sfqGߣ"\80nR7z¼s8Cp]ϛq.a5bӅdAOs>1D_>mшObxenWD=+zG҈ǝF{ ڙS!e;4!Bc 77qA\4I{z ++kD_b::bW?3T})r DSX̕;/`Nqx3@ܜ l61?+6opF<+hH{_Y'+D.. 3\`^Fפ0.8W97&Em IP0BYsġڞ^A̙ .Doڵ>v@:[vMq~3<>4?gh6E'"^MGe!]BѠ+ Q=3ƾO@t͒y"B) V s-qM/GMsѠE0]UsNB4z\ =? ήi9PfLJC :| %#hsh=čңabgwݥU?B"OOۍu@9!5s DQZ돃Ci5%.]{ZTq ޞAv_i@\SZϟfB ˯w{pݴC2垾~ĠW5u rqJuy/:qLqZy\s338.v`X\" Tӵ'.2!;+]9r_9&5FW F|#aPԟ;G^s&ߦ~sfIoZ!k b=4A'Ig.#$pEw6 DzRd b}tyĉ_ʰ!=Yx_m9n+{cYu{Z/Y4p,e`NQHu}}@e2"Lr.L @a)ۇJ|v7 ./1DW$thN1={m"Wn@`ދz U_r!j:M73}k7ѺE8?C,]A!Γw;us7qOI q_HM7XXO b%'⛈UDm߶Q/܈ uE-coF;{{ "QIJDe|iTΧ+CJBTS&/}z:3/8;̋//tcoĿ.b9RsA _xO>5~{<{|D<2 n{^1S7l~<񽮅NvDZNLT[WKa|&q翿-LW'؞B҈;ou;?q>ƥep5KN/y_ bc}Cs؞]ыsUخ+2KbNEJG̞sb)~~v[Saĺ=|DM^7aBᇱo t~X 7A-j]{]0Y?^QF= 8;Dtfh^Cԡm؛l24Z7YF|{H{-9iЅψ,(Q H,>vAbtiU;qݮEי;.!RN3[:qQ;lfeyxS1_>5@4; b$?zgA2twmg컯^n{=ι!x>%܃5㹿i1ű)D d؊b K]ޅC5φ~3 1?_e#ng_`;Q vXI ě/8BDS0xjjA߯$a"1n[/q+mm?W nU]1eyzAw7ɶ|vhUCn ,y'k5?aug;"LBW Q4%u(~ pC GD̪⭓878>ѣe9xutcNYs¿>[0eq.lO=sx]EhLU 4xZdCA̙ž6_}chHs޳g>Gh}+G~Kx\/ZfDOgw" "v[ZǼ/4&"] w]0_YcN0⭾tu&v u""iq@*oNěsƻx)o HA3qZnŜ E7D$އm)Q/Jz|7QD{sFoH!Α-Gv"{TOػl„Va~<:勵|Ke2u;M=Tk(E1̘u@x&"~5ʟ@ZquE+]O"ÙTEb^PDw4&]Tqxz6 xW' #exDL{U"'#F@| ^])gzuEeb3D/yY q6Wgl=ݻi6;^P?(JEi?UJx>tGC>v}hCa |^2;qt+iFԮW&1O|ᇸK?ЧeNq,fD\ёEΈ|"]wCn>*v{% 8 D7~;":U%Ջ/_!.R|䒓=:dz"'yNC#wN #nMO{ #VZ"SxFc 1y&/Y<=w?#7FY*b23B@u +bwc?nWcϖ(y{#uΡP;i EMHSbn#;DQ^.J]SXVqA zJfal$4tAܰCq `#Fuծkw"2?D1_`solUq @DyeI>qoBF3\qDʏ;YZ&z^@l&cD}_0ohna~\~r_>;Lx}T7>$ N ?:y}&N,D-~=확 #AOBJa.c+o7Bc *Ҏߟ/y7Fq -zv@;9O _^=>16|VA?%ωCN18OL ˇhPmNS o̷Ľ}l_.Vw;>F b'q a70_ȗE}w jⱆZ}<륲rr`S3+yg rkq :n{:_!"gU{&w FV˼8RE܌x.^?A^:_[LCC+ ? ^S~oAdb9kMom}~Ui̻ ϛ=:s3"xk#7PV';:wW bB "K,%qCH(" D4+0oJ.y'xcM矌eȮ"Ɉ%}IOFpMd;dm:=S]!h)1sִD6\<8Reba)i3s9àc#-LޭƭѠ#^0??XϚ.i!ރ=6kDMo͟5)0"Sx4f5"{yKy}RijWٻ[&EѰ[5f?tŜ_cϿS>7Y_sB-eɢѐH[aa¼^}ۛ4㞻nUAu>D>^}5iA`wL?u]akӲoz`ޢ2yΒ H=x {e}HbF04zCgŤ ~6FPVKJS i{iIHwQAhen=0PlS_%^3NA8Y-;JI]wi9 4޺%OQFc 3ʇ&Psf '@V,.ymԆ澂r`W)9]=h+->`6w eOp cNX}`fͲ0:h'|2=%58WύvPν}nWD)0 N1J@LbgsR?*$$ڧ~Fײn@olQ寁U)ur tUw+\'ڢ'δa\>eK|ݼ[Yfweg`70MedYҤKY/L=N7r |^v0P@zUȿ䧁S7wj0fs=I,؄%j=QS-Rn"|'ߜl3ya +H/ٕ@:?`y_7@jQ`fxQ^y;@El0sVKzǒB[?{Hlsj.'t'*w\ 8W ڿtcܜ ӓn+[ݰH+^"OBɶ@(ɦopǞTdç cO}=7XɊ%kp}Qbûkן2jxOP-H]@tcyY];ǁh2n0^[$U[WU&i1$P zx~~ fz{Y1jO|5f|ٺ@G!/om=PYbzLa$\]M WTV8xB<9Kd:۶\ Ȩ9yaxOg4GH`~Z}7f V-]eխ/ogqx#\ om1^{FdvD,V͏q $,cb[E|;meJAqiBKssXYFQ8 pY., Ga#Y]~ ̠/@i_⯲@*">H*;}*3W O o.+<}Xy#-x_6{~d#9 5u{tH,PqY<䓔?z)'$n\ Jֱ%3Zx^pk%D9]vb`ka'SZ^>Vs0'Nv\Y #D&( gx'-1kT g("|R,9tJ _]};=:w|6ϴsҕ>g c]8U'̚ǫfx&5Ⱦ ȹ>'ro-vdWO:leec5zmCz"1 *fW׋Uln㿘=T@}xT9bV@o3_;sZ߽ =o>UF_y@`? jIc+L㫂spS~V܍فe}2%"rA`ǿݽyiv&[dLi=,X _ 6疝|(o1~>3vt,`OSd)%h-oB ä܎DO|}`[]S37n-l+) Q`׾VQ;&_[b΃55p*ʕ w^h4Ip/g1/l3R}ď^N@￴9߄Uj<ޣ[VG4.6(Hc+ՀfV`to=5e{Mlj+ଅ;>7asho@nK+|l`Vj:% 8.(;j:}~=3 mqk[:f{:Ŀ-0wn.\w0{Ǟk[y@]2xuֆU;#^%ޛ- :ˀ5ptbHE>~@ ,R]֪1`Pqkbg R`dk;, kQV1OOٽg^^`-]^3B|3fl9xԩkľ\G-\*xi}YcN7=|'`6e\栧 W]|Pm3=5kX ?rr ?U26?7{ '_Z/fz?N/X ̜p bYaEk=6>qrMfy`t,0W&m=$ P:ˬ+P~RѮ`],OzW}I3#.ήY;JԀMjqdwPk3 <kW<# 5Lٶ}mH~`{8^*pW@ezM1f=f Cuꭺuvw_\~ K&Y,)hg ^,Hq4#yE`l3,3BogcVج_G\y tI>ۼ܉{sou9LeD8y+>sf1bR L~sYsV˞ns-ha`lV[[eU8>^}6ai5&cc&/['w ~I4Z D8sMab8߶i (-h&Gܷ[/ yxhw 3-vKw~ de(PvL]9nJ iB./K"EGHImV y9@N t7u{pvOgwuܵNSk| G7B(yu@< ?9J޺ {R-ZRq38j{χ \,{za<P*׀ݵeؚlV޵1  ]'j{'!`f||)W9 ^ 0jC9 ] Z}⋹vǝh;sMy(bꃿ:8n Dw|U9֓Mlk0XϭJ[ sgB[lp>0gx]31oJ_sZUϯ &\ b} X_mt2s`&ƅځ ᦲ{Q@]5LzO׏k=HeA_3̏nͿW'1:d_l>zOb~=mYPWX2;i]{6cx_j&8bq( %;Q%g\ɪs.vC4g 1LGT[_;.Iu}i˥GvCOɆ fr[Nj=쿛n~|XGՓWl}3|I J[~/Yz` PxNQgfz!z x܉ě@}  )<-#3VzE0$$}8kO>Źy `r0ggX+暱QX)}OcUyf}KR7xoЏG8c9üc +s8jAtW|{ ی+ax{a{ף?S6M6yl<_vLoǹ?p)v:Ոq/(At:\_j'&B RO]=$G9H5wi`R'׍^ϣM)PU>gA@n~gxPb̟x4R_RqVa/`Y(So+9sQg:]@-K8 G<"Щ Rñ׽h P:0GFiL1wAu0brGnu?%?Ɨ=.(pfFFDxJQ5:Դ?XUN3fF ü`c+oozd-)Q_i*]x6z-Iƽ{ؑsٸF~Y]gX$)2MCB@U( 5#88O9ŚG-M˨#ք|wVV4=w" a˸v˪Ǿv.~͝&W,q>{0 V67{eۢ_yr[Gxɭ%Oub[F/49nwk^8ۓ\ӀTaO^A8R*؋}2Xb̋[kN“0mptx]͚K2lQ= ].n+ @} i޾.dք_WFwW`-~a:9Jv/vrprxܻYeÿa&ba#[UJ:?`f#׆J@5|Uy޴զR }A?Fμ"i CatE*RN}:*ɒ؉̋NJga!gv}0zsp"t'U<ьlX\ \{Bea@^N|~"#'8#|6R `l֪ \Z#w5=!=ovd9|kOZ;pto6X K߽XoK9=_;Qg䉥)qkY ~I00pyj^84q ,- Kyn=AlWϳ½"}YoPc>/fgx' 4u9dڧr; zY.`\I%fStՎ>f,MftDy}uk>ӣ*?"d2 :'/3ԜE(n}Gүooanvkb֯žkyF<8o1s}*ߨO1s}Lz[iL{;EG1jݭi% ˲Fq/< qπnH^q ,x?W9X챧;5ess`7r`k MM6X?T lp;;</lsy{& v^{_͌J>#>ToՁzȋO=',MW+`$w*TD,Xѥ7@_7p3&pEQcŊvː/*G%M=wspWGMMk0 W3 fcoXۙ'u@p `砈yZPKz+h ɀ7Aj 1,voOSO[уҁv.JՀJw:^zW0뗖x[@NK=4dka:^// q}V5:bP3d;^^tʪTWw}۶;T]r~$0LJa~mߝk.߃gbw';2}hmp8NZB?2=GS|0q a޿xCT`Eϔi 쨳 ؓW\=⳺Q{+9bh^;/n;a!A|58t-P-yΧuzЅ}՗q] >nbTE) v+y pϼhh[#yKBN^n{ 69[2<N =싟L.c@zŧ3J&6B*/^^ߗiIr0O7"yly֢_5$Vr{h؞Ø'܀V, Tə w(xwJ;,fl}}@)':08bWFc4)TNn $drc%KjGH.$M4j+ߣy.Gj,|z.쵍7' d} ̈d͒$LI`2w0}T%[Ӎf@l݉*բ@cCq5|)s 畿 DF܇͕|}a>q9/۹d4t)RD5-$fOd!"[.} -fq4o ݢn $1748th_iY؃mv !ý0/Xfh>{8 [^ߍ7OH-g׃O*[Usץ3]pKp ~f'[n4vj8k/ C}9q+z|m[N텍+>½,%' Ć+H̳vGw)JaNua![OM0~9:' mv}c[D:` %FfYUk5301y.%siܦ[t:x٘͟pJʳrX@6JQktI/:v̛GN_[BuH[#M@~3m{ sىMkN` }bZpzП|i[) NE+Àr^'%ዲ2[ |޻?ŽfYUq80>.|f$`9yCaS _]5d0-"7H񽬯ңgJ-( sJϫW3Y1KJZWkpPOTZ8^on~ _-\T ϭDoPMu1y.{).?9^+^"Ѝ?,u752叨[ޗV[ρ9H./ѳC\_r~n̼C~qa?q܌AC|y|x^/UX6& {V R/~̆c{zhK`ɽҷEʵ 'ne,Ǣ Qw'@w+>ipWĜLUZmmi3`nnbxw~ms}Y}EQ4v kS2< 3>08ĥ^uڔ` ,>|w.UYn _=> -TH)ЪO޶`vp){|ǏC8!l+ܿڂpKhR Fz׭y8miP'z RV}dEe.N9`Pz-1ڸ,5.)0_̈Y؞39,sdLf27gY5 LjTnIS(~B"~`5ndϓ%;%X]msl}=r gg]{bf5ܑ%-@{%/,޿ϗVDO~WTGsu]*[QjlWte!cBN7|r`%6 z_g="2pv>xwC>Suot=ux~*x ?n^)}ғ'E=_bS2 赮ɷq0mZI '7gFtW~7C@;뻥>bc$0͊Lzbck:>z{CJm߃cWc5jLqn]}9ж8?w7'`K4P Wq`\w]#ī[=4= gp潁gflOh.{o2 1@e3YU8?S QK#g}hQD+iÄ}Ws̐ó|Q\[~u/fb`Hr4X-gt[8j큕سnwI@V{c'g'⊦I䎧E&6}s=}0sŲ녀~oKO_7cmgk=qZɻM1{뀉8Ա|^BRw'wbޯ X#k*CgGɒySĎu, iWVaixOca@\%vbS6ye}@/{{p: C\X7E֬``I~1,J:~ۑSx; ޽Hd_=.Y9k:T qxNw%[/[fL3S@g()ɶA'M՚vKV$QRz%d%KD:k<bђ?q8*,Rf왷9JV׿WvZ{8\?Xor0wVl[{H3竾 mn {+ɔ66W;m?:>\~CZĺ)5}OMN.vyE`up_l"^h4| >qJnT>UO=+7|+0,-Z>[ЪG=ȅzi`T6n*mqf J"bek@]KUܠs١f5+R0AD7.q?xWm$]_LvŏsoDC/G ۾g UQ{sǚ:88|R] 2]@DEH+(ͲLRVowp>C>o8ri_/K36ow 2Ͼv&ZZOk5k[=q /j^8w=.1| ,΅9' e(A]zu萑Oj 7@Gϛ17"3Cۍ?T%tNUJ0iV7X_(-{ak $Y E+\JǼ7ҦuM{,t)9 d`|nWŮ?թ@4[vX6oWrq ܋NzeB=.+?ҋ'~ +z\>X\uoqס[<'GbŸ&FE?2[%XJϥ"L3dG3_F ۧYe%<`R`_LhޙDmT5/6[6pePx2# a5pyrXsXz^k"? %d;ol n.E?c'E}8y-N[Btzs` <>#?SY`p$/ 8֮;I$ u=IS@|T],{Jwz sCR-lhY`}>;>J}"*p"+2o}/0~#f.7=KTꉶz朴S!z Dt2~=}k+>frp 3oEȣT+cWbwf- ұ6ж=zʕ|s^!{1w,|Y0pm>ߏǻl)d?+c{'̀@i SB93993AJa-iLx8]3,2;OzIOS<_Lꑈ7Y5vϳv:ȍ>d8Ot\W@-[u1" 2+p-|nN)7 9ܶ ;Rfe?8h0B}8f+2oq70Φwd? tfX ^0S@Yn<\XV?%0iJɚ@ZO#bq4 Tώ%^\ xv gWNѷl/fydhQҊBUA vk.UTӺ}Y Ps'>gZat @*x/dޖwz?Rr5`γ 8ex^{kRIq9yج]?T$` c-; PO56^(NW):ދ5jrނYo-=3}ۧg :dT+x!*}߶y$x–Z1_y31ȩ+Kk.>xl[oً;]?]9XoZqg+x/-%y*F61f0ug2Ƶ4ʍլ3ˢWc /6^i>߶9^Z}=b xM_p=,zNj4m6{br  8{R˚a?# ׃,|[* wRڪcCL#>ɏ^_bQT!ٜ3j@xNE+=*ԆrnLD;|f;w\wt%#d,LN?ƞ=!̹]V=mW(,V)\km?Wk=kDG{>޷̽{ ZW)hy+.d5gR[]6?zoe=1Eg{_t!ZGr\60K K/uQ*}k ښ3oũꐒ*0w&}vBbk7o0?0 $u]b[^(dN^C̻ML.Gߎہ]ʨ@j[.@H4>yߧl}~0%bYmK>+ܖ2'<`$+"Cgwb>J0[tyM@H-Λ;, 'V[@1,g=j'-_ㆿE)x`~3JnZFK«oXw]ӜZ܁d-K~&>;p2?Դ;R&{O=a t[3"kfs0^ *mNy$3 ȑ¥\6'z6s窙P?$3IjU 0 Zr'K@GߦY5=潪Lщf`)LVaT/ ֵGcD`e {:-8:n u\61Z$zMD;]O,1OGo\pr8OŅ~3'm.͙3uW"G tp?6ĝ?i&h{\]MGY3Oׅ@(./w8IۻU쏬 "QO0Ǿ_r9/İPe5em@ N3`9j'K ?>:$К*$:y, 8=]7n6`ΰz!̍P4(O:?I(;ީ[ܳxܣcdM>l>OQ/uJq`bvW RiXzԸ 6_%NϷ}[< H49S2~O@x8lb>S<s=wu=rGl5M1yHWTX?&9@ =.mp <+ʚ0/ݘ?rwSU>{T6՗9~:58,]=GP+V~HXCr9;%[\%ʫN5x|rST.m ws},{&`Ir=*(* ] %zH S R{M'߀9yphZ`rjXu9Po}|Db &9>'SZҋZN8D͉طwq1G%l=,+8L^sݏWp5,{f `Km!V@X/Vy\{hS6u_q\?&@$lu`^KTQ{@p}oxNG皘405s/i23kt6u_Á2;W[ *S]drJ@>vjy…O ].2ünl}菳ɡ@^t:atS]"H{?o`=A+u"~#]hh;9|IY`U &*7ZtۻwY0T@YS@IIG-lۯ*Ni@m0X?~J7c> ߴC]oQfkzQ`<ج{^|`'þ@hv{uLa|:aAU5o5Q֙ GPFvCվ۾@J&HAR B~,ZWso1X)lf@1 vo[/'t_Fe/} 'y>~sHAs=l- Q=03 h?/w"/VE2J0Y0}ùagltXY _uMֲ)pm:78{X `gUxѡՉ5|ycw}30Wfkم}h#@p-{O `OqMx#2C0=STـ{vtϡm|A^_T OЩJE+ELʄd5k4jU;w{MIVdΉ@_΀< ^'j@sY`DxVXx׶R? Tb}jwru9&z؇TF˵l0O|Y0ox a^M^ц˧N`yFC?g,jBF ck޴S{[ .O4gSoL,*~hU$P{iNˊ@ /sy_n6=́|\ `s?Oka64Gh ĪF׀h6,z'a (nf{E|=f#:Xb6κ2ip1zgyTp4xG劼Grz*퍭00uϓ*+1wVX{fF5w HtZUn&Pbď>4ϙ1rÀWqsI=B+E /^])|94 2r/aS!=h,w1{o{JEތ f7.\yF@'MJR@oft">3 565Wߡ"F^5Z=f?PV q߮RUގN3y1sS^k )2.$+`M;ʾ9}:ãp.Wf>dXYb׈Oɘ9U{J/}w1?1?p(ޢɞ+Q{ M8*>y])}> 1g(NMjՌh]`عBl;C^뮲^%l^2VSQaZnvR+_+RL.e i>K^ ]\$^Y9ǓtؔEI`Fa.<Ϧ}>~<]GGԏ[v7C&auӍf=pjǀzq!{BMw,3X>댦fa@>&wW-s_gὍӏ; ?/zlu87-;yE-=6ܸط ‰t-67Gץl @ YqE{H\"ܰLgO>&g Ή ~w| ΟX?xo43pﳟ$~%wrj4e+N%uzaWŲ[9Kl ; [yQZ쬙!@][1=Jv]qc/ZSҌ{ޔj$(}ȴ+6 hBfu[ `ͷ:=ڛ-@-_1{hK* \ k aUT#l!~t Ek=;bnM  e4nEj Y`?leW! ThTύ@ /fow܋'hL55{F2K2qm]<&[u|blVs O1Z Dnc/X[8s93,ޒ8WwxX MW>*:uT!L߶ӿ8g 拆Fm5ɗ H5mݒ睍Oľ-0{k W^&8`}w>'NL~Ei_Xj|__H-*Ap.ZȴĜ.@|$zazh|Q]z!Y6݁k0'W}G{fGޏaf]ʺq+~XNF5N}Εc'8/OX O(Rf71qR M]@*^;c뱿Ԓf;>wY"Zd]WG. <~Ux݁a`(OS}j".(__cγ{ Xgu,vy`Yx _?fn;5L,zғZh]@'!y߉\߽{ >6lܣK9sq)&xO+>p}0oa? rhӼ  z5z~ٴٓ100$ׁ9T Hs~gǜvJM?Or%%1T]4Mų/żwA&knw}wVDž19sb<-YJqx_<4"ʘ5*v#Im1\mQc<}`r]613}~×|X:#~lӾ )%_׶@ ԅr?>]FP%m+3^Q^;}nh^Ч'^7-9^Y2mp |dxoXX̜EQTު)N1'p(x59S ߿g5h[@GW q˘X79yG@韛Lێ9kFdP_께?~-։72k+hR*S9sIգ_RNljZ 2kK ~d[Ar_eFSC~D?.+c8u]? w}a4`Ǣhc=SHp񻢉*nA+:ox ex^zu UVJ|} `B|7sZ`mX3?hٵVy>?}F@msZܫI' @9ޖP6_yCX8yR?$m.~={hV_9vk/[ k2ӵ@n}úM"ǀan؜~ {C8.5>w1 ǚ3]lT^)O{`z |^V@OĬ 4'I0לG9@:OO; I$_?&u XB /fnZv嚮 `*V>¶ԂO5r>{=l ^~LUbϼ3i`݀=gɻ: jӘo?Rߏ[my:;w⛘fVj՚wlr_xI9\ffPܘojRY0>X♈94cj(>lقb/%}q'2[xSnymd>EK/;8+\xk $Vq_2C@m{8Iwo`Iyq (sͧyP%@l8DG>b('qf4;W5fm_ckk|'0_ݡ9 6Wy!\ݶ@>_=.,xn8>`|ES  Z3R35:zI//o&-ǽA)`S;-pN)FaYoeɋ># ]ˁi<͘ӓ.c@<8c!p6~p<GZ-]ܡ%tުc;Px/_H]N}ž`d08/=쀒h<Ο[CJk\0U;oiTPuポN]k6ϿfE]k{xO"Z}-uwH/0B< k`OE |: }zF7By%'w y^X=-Ϛ}e ?Ul~:?mZ>y S\nXrs (=نh.\pSl&0.];'k't;|m</F*IL)62FpGwȄ-@e,U24G0Y!_ F6Zdn+c@ίYk?㋁im?"ۭvWUtj܂ @Kq=?FIU!aρ̸zBtvӭv ]\_&~{.Ր0vd]([濟*z{ P<}ޘJ>T J`kwy.Oׁ>շK39B$*Q<> *ܻ WՒIX<RD:J=Џ/]R zttݜ'u)>I%Hp{?@/_67--P%MPwdq.oձbRlXfP& H)E`5`Mox)]z1?pz|cu;?b_da82*t֋֩nџJ[H$i;SӗSgu4)VFc@3=))؟_Y^zwŎ!vfk[MfohKQϏ'beT'p-w*`$=i2^{*Ɓx P?mkwIx " Ro{T]F`%Z$|\,C<ٿ %sn|9`Sw{h_V-3XSƖV3tk24a~_rgÑ=!ZV.$ '[rgt2 ~'=z Ÿ 2.>wµ@|Ʃ /șe$-lw<?luoZ $SIfF( DBdUBDü=(!Y<^.8qqקɿ6C^֛Bi#Σ"b8]2ߏ` n)Y~<Q,ff7bU?!~GW&rWWb!a7Ġh[r'F&o$XGӎ=C8PYxe`!.b}[Az⬓1n%_4ɦ"175{m[s[+18oT>x{f۱bb{WSjwv(bPYеON[fZZ=.-&Dn0%X(8bd`oĘfbbM&1K=1xW{Շ̿ quZ4^F@w?WfGKDsiI'J 175A_^߰r%Zˀ؛:y̕3Ў?)P}bFȃH%3(qc?-#7c#'$O^uy1O (!Xo_yN/w ^}Fw՟xW zO@)1#bѾ<_66Āwр{v.Ct7$]֩ ]w ѩw ܊'KqF&Bbw71瞦͑K&Xk|`z*f_pho打[N<w^E Vɦ$}=zAt7Z+$(Cl^lqR<>qϪW@|1İ0OA*ǮO[kaR9?t?m67ًEm X-jC7./-Qz=bJLXBvI7b"*}> ^>.b%1.%)1]:d1d[@x~c7>X[/ĘzqF~Vd0 |yc7ĝpoH[(pNh09LL ͍jß**Ĉ-P\ھyuMb]Ԓ 1pveqq!FFj}.C\ƜYݯUʘ`='Fϯ;qwweWf_WFv[_C[ʉq'OMfa\"?\"NJJ?\~5vHx"X2zO>6î},xD'h^m#3>M$Гx&Ƌ6T躑 51xV{ݏJDxyۣIb($Ŕ*}NJ&XV!+޻I"BdnÉt^ J#X #ۚ%@O>vηY SNB hnA v<#H"1nkɯiL);9İi}cĨXmhLh[FbTݸՆ:! YUOzu, b|YTCOמC ټDuC%+ քFe'*І(M!pbP̈́+1qn_xw'`nQ_F>{_a|s {x;#r[`bUuj ӑsŅ*ow|$F-K 8t%UEddҀ'nKتG7'Fpѹ!&].em'F̽D ]R2{*D P^]ݴqڭ|RW=w_*[ѺQw/1$ϣlĀ 'bԬ&>]@2`\2!Z+}wO~zq)cC F.P/CQe#g-fTdo-SKgx1 vk7GEtyڒF}f< %*i؟AX[Q?~(ZR 1:Tg31|,苅󷇹 VrL r91Fi 1r|smݯW]MՐ#Xvϸ%/6]1bo5%b򷗹;c]ܡĈ=-%2%(tOHɲytŶG1?^-1^P4nq"3+E <Åa? aW}"!;}ĘI?/]bbxfbd#K~m(1v۵[a:'^OjXc/F Dg)_=yo-uiB?'Nr:.Kp!F߭˸F$oy3ߙkw} U[hr%81'HIgJB{ޮ&FeuB67 1F!,;8>ve;^[55-wxB@&\cAǜ@Iwopn!W]vkb|cGBRĈٔUPЮ'ԳE\]lc1;< Q61UOvQ-Cޙ;ȴ%X?΋wDOscw˻@֙~8H_1rHVbD L;ݵJ`+=)R 4|3sgR7: W(ebKܹHuc31W|֬Uk=V33_~nRׅHuzIwɂZ{ZgVOY.M+&zH|buhԹ X)˃U}uJGA҂Ġ-+wCS+{yQb?C{mX"6'Fޛz՛G6WC<5҈{_M M[x>.mμV Xj:޿."?=68wC'F<[W2Dž纈% ^ȷgZm0My'Oύ'K]z an&s vb51";5hL ^1|Lk#wom U\gM_;纥0Dth\ u9klw7%#lKՀ:%d^Ki_Ii5p]/ߵod >?7o}2 ƯXmJ|H8b+,䷡ b\DYF)t%R}R`>5|i(17v?608i[`뤸6"Ƃn%[ӜĨguVĠDn6bbg要gY|'kS怷c'?| V΋ jW/u6~u\n|<1l¾{ĨHJJ1zj9{1G-:4yЁ#*cT[-'F{/^r^X?Z^CXTM ,\9roȋgW |].$/!A:dI=}R}6c\10B_b47=u:$dVhŵ` ("h2#Ss1|&ȟ6B!ith+1)Vcn<R'S}eV_+Gs9Ͽ5Lg8?2;v'F(lzs>#ǭgpKM{Հ7$EO|A: EfKGcjRnĐl8- ױ"^%X.aG/6| x;[::R]\V_s(]'bFGŵ@ЭpjV0!W*2'IgҠ?xB9(1.L Uwj7t$&4*i`GA 7*V %'$7,Ƒkua*guy:3lg]bt ޮOeD֑HaoV ,bz4mbLhHKEbˆq 5a%r׶7o@7/IƟ !FnJ~Hxo0raz W/8ӕ#s}6Ā-g# VHybyaÉzr>S+ra2`]u_{CSd nTAp;yd0˃mB~u@ǥo6W [xfAL^K6&'U*au7[Nplg}.ǍчgNm&V=Hԟ2 -W =x4՛f{yZy6}q ޫ_fmOc-!x7cewSM_op8J~4v}D{u{{mibxD:1!pbdo᧨؉aEƇ VD==oU};\n:ӏN_lな(bCy[18Y1x#/QLoi:"9cLM9N}JYH $mZ}au%&BCzZd'9rsh$1=O^.W%bԄlOݚR1Y1\FExO.eX"%|lFRXa!@ '&&PqBvmw|1ZqB񭫋r϶DܨρKj Ś5x9ݵ℺ }dtpqBQ‹6}_qVq*2W> *~0[έQ~|:~h}whWPoR~qBNf@<G}dܯ?OF{ :!8xK#Op|?uҾIތP95\np>P%@ys0ܿiꇿxX'LeC;_S\rl;pZQBqBŪ0rTgA;6՝- |Z' y]|sڙ-륝|𜼑}Q-oHs^ṣG!Sh[_E|g#S&0O^˚9#/u"Kg~G'W~2'`5C.ïℲ)0L{8=3"ݦpů> 4xݑ$#jw/>B4u: oe7|{+.[⺏wqx: o(܁8+ɺO)[*t%D鲥SU-| dS u=N/U,aJsi&uq^rBxRo8TLc|v.I W%ө1~6\}c*<+V r=lz g Mأ'yxaXTqWrX ʞZ/\+T;t x3՘) bB+]m铀}^<;a@-K_}ތ#ETa]*C9Cvh&oࣼn]N3pC?O\s9WX$6!1!~jf'[$ uY꺽K̉\Fxo+)q?p|m m."=8'x粝 :BShGƓ]ΚAo Yuo CF1/qRWh2W 1^Ls]djL|n|=+¸_"nF/\݅~-uOD){{كot6 3ʮ PiZ:ى| L|vb -&c1h=}9&U;8Sq}\Ʀj0?9El?Uq~f`͹V񟺸]͛z@Վ|Uc Pxbv2J%~;2AOa~ ?-L?XkU#茆]g#K!>HٵW<ަ#c?Q'"7oaM=6~l5Q&܇7.J UL4?w9l:Aθzc,D Nx˧ܬ|r3~4؟Vn\|904%! Vi=Q9kzk0sdɼÔx]Zy 1'EJ!s>N)8f[o5\O(m UZq09[!_ˊmTq.ckY;v3y3Jxa[h?; ?x~;\1 wvי5:cM+.ap12[Ͱ#mn{>\w ƫ҇P gx:"5p]yii 0,Nƀ/bJ7Ղy a|JQό7҆TV\xEtGl03SC\s;7_sfڜrݙ5x]z\g?/հ^o|=Xy`[TYŸ\ -W^kڹD))zP*do%Syr3ek8vI}ݜz8V%СE&;A>䄮m.ow --2YC8xwÙ;p"#=J{¾; #;M事)0w'{1w\oLZK=pD\ 9WUB1^7`>h897v0\m FOO%@= q^&%O5wn]7gk7zi>"Wn<+ˬuƷq\f 09E0u@ϗ y1ʅ^.>n8)-!嗷훽jȃm)o<,nΞ~7_:zS- g8,ح lAƓ)Ęy*54/}_AQ#рe:%o<~PuE1ƵpkALf/̲:L؇k 8l xu2] $Mo&;Ckbݻp+|Ʀ9_W?]ZI2<2x99\Mqs1QW^k}/H/*TCѐٽy AV{CF[RuR!^;"[_/=Z:eذO]VbD[m )81}n|u\/a ]y^]+Xuo]jUXP}sZ>C7i}MaD]"r?Sc}v: ׏k>?63%sF#XW o U'XR H$^>1^aWuuϡ=qb)q/ 8+(T{_hr{>'o3Q0ߏ_c= Ģ Nsk2O%dV ?üs UIWWЮ/:*{r_>ᆸ)2vmbJző*A|9c_#`wHYߚiOƺ7WwX/]>]EO\Ɍ(j{ k}b 1WYVOXcth҆[i\\'~/S*s(X3L.^g_!kd q𱶐 -ӵgާUx_ڝ-3ͬV( "ۓ@T]&w;MơvOXot/Y`Tx}XX\8 Rxԃ<09%78u:3%da+K$h!D!~+??Oc^!>&8m[S|= CC{ TH0Owӗ?E^Odw Lj [.YL}cp(wHJ^:z%̏AoWj؄:?vKa&j_/O?1@ jp@ uC\9ŪEk[ #rxFŗxJyxĮKeu_na߰B{Q\)~x^Ϲupoq] z?4;9 +op&a?rۻ0FGFaݸk`ؕk9*8kEo^Wbcya5^7)^%wti΃O/z`K{U~*K{:In);{&Ou.{ïx=;+SdA k%oV'c6ivXsNf-ۙf?flj5歺' 1l^]W x$CoQ)܇ϭ=Yu691&x/m Dai1s\z/*J9U5E?Mrzc޸k/}!= KnG=@ʦ:ySɵ /$oގb> +9|S/$6o޷v࠽#}x-a#7ޏu&>uȃ8_.k+xH;ɢߥ:agcx_ժ4xӱw$l_'ճ:e·ڠK bip4o( S=B/\c}a"mAk ژU^*vxR6S˄[ĺJ>/h?2ggT]7S^?)1"g9xC|M3u.wN:&(q ç0.&Myc](<|U5\=ϼ`vF8$۷OC#^w¶ |lam?4p}]A? y'TUp=2b;#W8ͫB^6?h~Wr.'<}U\7WXw>bŒOcI0:@S/WIKAw0u9q}j 獨wwEo>wH1\A!C bF!^vB>ؿn\B/I};xz1e66Ŧugsxtn/uyIV:x Y]uo`|~!'x9 '[l>ѝ> cxaDNδpy+c SrއO/VJ-`8INgotr܀8ȉ+N/v}ˏ~g|eV5ԋ JoU˜,>&SJE0,a oZı}zE-Z#1o72?ͥ `j<(q@y`#Ƈ;*:A$Ox.zpU?P'%^:-7;'0@'^λCxA}8V}^N۹̫JpQU%vx4iW/M(|v><&J75~Mg7{op5xYtNn2lw /|SgvQGrsY33ݿz] a=?, [y~9}%*ThJ8|)ƗhDչ'#n^iFU8Z [cI>~kt@@֭G;xpw#v;} ] Le_&< 7}Ozn2e_X}q( >'}9_vɲc_f2 }0wQ'4o_N%_IWUxq 9RmpgT(/ RC3gOW#\6yݰzRk5goʂ-Y>m,̇x?['y{g ϕ؆zh`}[h׿9[ib4}l\UWN|r,Wdᩯ1\Uv)X!tR޽/=;!RpXu槄Yx%Rد4/-Cz-u~F{i/Bz׏Om|܋7^݋%sV~Wfp:]@YC~ya|;5ƕqaYڣ5B8>ީّ%x=*:E/8C+A 8UПeu[ ~󨖩޻ G}GS]Ϻ0ú-r JS5y#U\ ĜN_fb4 ޲r߉;x矗k|:缋Gёx蹅=xIiNvU1ȳ?x+:k,ǹaS}.uZ|g6 o9:5b#U B[B@.P*٨S |[G{ߓ0J*65z=qȿ_~-z[ 8gsLM5{qBx"N_共FWǪ &wV+T~y-:ɞӳW;Jf.5;F1Q+3QEtae`Vv幙]z-6dO2QHBׇx=5yME8}#.y7<F~&N{F_~pޚ}+~x}ON QXE\{ r{eoE@?(9(άz] TXs[}5Џx];ybW䞃no}%dny1ٮsA2a}#IwR]q^$ Nalw E Y:Oﻗ|oR|_ t_cs| >ҕQ|yo:1u=ooӪW//A?g}zz!⺔]bM׍|OG ƹ ַ}'}q}OO9ޗ^;}]^oVu$A|!\.U:e֍ͳxߩ Q6us;cTݼ<N;EJ{+dQ&^жpzesYX&Gtt> ϑ{yStaٷOOqbrk cن2$3nu5D-{xuh<`lAoY\ ,@{o`{[י ^\ݚlwwxu>v`QU^gy?C%E˛=Kj~3=|y:_LGԀT[^=z:lγOqR?"؋I},yqrXס uB޼nW+|@s⾘)-׍_0=wDNcCz S™Ԭ+T8t{8dcs;Z"#*7Vsـ:&B׺:A0\48,<|{9gzNʟ}z$ht}lV$1RSH?D"\{ iRItDbKe0 ~5(S #5F{~o WVfh>~M3M Z=qkJpj:"t92=n+XwYJFbc"- cG4~}X=8HFTO <ϥ=Bvq[?V2;Sk͊+4C+&.|(kcM"j mFRK0G g CdƗd]0w VN]Gb*[_)H6و19?pBa>JDv>}<6yRם:b3n:' Ol_D#,V"Z֏܋UO%w{ (?"O  eC#dP~T5 ]#L|ʣʃ]VBnً0| ~4= zq}ؚľ7s@ f ޵.Co#ƶ#Ԕאws H@ks a|FU'V5!jESo"Un#7E$ o~Gψm$Ve{2[ÉkKDw/!C\z/ĝcg"J'uۉ|?sD1]bqZbnBG_^5W PN{*'4tZz)HѶ->rxK)Q_#Mh3˪qO[ةQN13 s xnqDI '_"ڧ*Gc{"MspB=aʆ֥D!venJ_lGK+ƒU2FZd%8N6Q7y @j/#wW]4-\q=ȅ; K9nTl~_Qic[-y\>Gz'!*[/OQGN"՝ڋ$b7Dy_WHpqvG/qAbHDW٧-Z|BVlk!9_8CvvjRpJ[D {Ҏs"S+o1yvUNirFdݑu4{>-$ؠc0VXbKWp!JDt2Ei":+Xԁ뢪"潰k+Fn~~=Unzp?Ƕx7h,0(i6ݒ.Q(z!Qwo{o1nt;yq 'q!Q mi^cDW)#qe/??RݤG㴭DDԮ'&!z‰:'}s'^4ryX^ߊȑջ[ĉyN>SӅekںW#RK7GGoE m5f-K5 BRz3HK37_.zemQLfCfNV!uM1nx//b8{[b="(*v#(śՒ5H84fE.z|7b8q$!M75#rcWwTofu/Qa(E49q^\B[|A;(!;sڑPщA{t AgN"0ݪ̑@sM3pt2!R&GDMxgxA/C䎽Sn1HhU`YV!"Gͫ# ǚM /(] }-ff.D:\,?x>pj#s˷Sv|1qZ<-#`8LY oMt];bPOR؋~^g$mE7 \ґӀc'G]i"dZx>D{GHG O{-@5-{0n\jXQ;O\ruJq~"!Rlb٣GxBx%8 D[ OĬ>^]5( )^%g_g^[}]xzDQ:,t^L\5"nA W?:~LLOQxZW#z@Կ~$n!tOq-1U E.Sd >=v [ frlh+A%fWy0t[[g[h)'ߖnʒ8}]E|?>D#8~dm'2 U,8L!{Zz3O݃|7IDv%> b?GyWfVQS73-!n)S>]cq>ާ^=Dm;iq4J)DiӶsCt2N3$xab5xoc"ڻ 7 DmtC9H2輷oZ7C{fD_o =E+;gÇjXHK# bY!hozwomGbK]u܎=Bj@_"Z4g~H$V}*Y }⊮UIK:kxp<ϖEgHH՚>$[vc)wiDc)nFBmsE^f'y{9PDԹz9rM J{d!-GDyghe-ﮀ.9Q{ɦZpJC_= Z jĹy?<gNltsjHGW+FBz w "&.s:Q:"ED~,DY"'ݱm4C AH؉Π!z8;t's2"FR@]{s% {v,|K|(;K!z~G$f)aD+tx+tovض MQ/߆:ʁϽy()F_k1hg5&"h27wADIneg‡GÐ`1{[EYQ뿃(GA<)#2"-u툹060/t"A8ghJ',"XU(/֦ՂnođMN,<yE~N_B~{Q߮Fdg(  9~X5aDq_Eq:C 6˫G)-1u 1r ~%^l(G<\4mf7"Dx_E' n6CqGW ?Z#gXпھ}=c\SSCBqyϺvqqblepD#jo pe.'__bzD]$N%ϒ={ bĥ?@Lv%WE' eWD?۾'D_Qֈ: ػː]r戣z0~~e +#29Wɤ]dK6*EI}-K#ðMq όC.>Vzsb)${NOx'aUbAY[~D#im2Xn(}H 5hα=27rEtr_5È5J1wZޑn#["+~#sg(1HE4Έhyr-bX<%>?ctd‘ _l'$|씸^b ܭɹ Q_9(sk}M>:|AY[ ~㹼n췎dG7bćt`K+uH!GIBFk=\"P_LO!~A*k2}*">gxA;v gC;#Jf|!79CG\^Qy 7"5uAЏ±^?rO3D~T]jQ,^O}{:=dKV$-ի}wAРU5_o  r+Do 8=:Y49h̘*@ID6}wb+JU| _:{c=ArΊ{ 1RRDJQ4[y7vO6巐B˴Gii9?_gB7 >܏h>%r7up#q`J4%H5+JUjߌC}TAS>(OtB^[׎\pU'"请{8&6=i/Hҵ/" H;%zȩ~ވ{:oAGt 'g(}(~dDfaHTނb%Թʾ1.-;5HsZU4\_GT~OC:CvmB7#5J^JpjD4c]dDpzq=H%KW헉B݇qv|;!4."T,x&lE'&o ݆򥫑\s y#ԙs3T:rUr}h"* ވֻ? w4(q^mz$VaZĔ~'I'يێ ^m׊ho\/"&()&D.Rf*kD#QGq憎[3/!ZFiWئ`6DY 7YEzlx|{-$5Lh8=@,g!e4 iKe1gӈ5^I !ʧ/; Wg.t2AoXS߀8DdrÈ&=k~[J\G?>GBwEHbdy.Nໞ/|懶($[>W "ڦFgAkx rse"͐'t?Uf yyD r~ſB{uc.D73llbJRC1 _o1O,C}RDv:`4r14ϟD^t۸ >[lBO =r,QѮ|Yv[R)TT0KvZt.Y 2֏F4œowv ʑy9qE"ID!ߏQ?o1+ T@?H̐sL\,Dl;\v:"RNUT$̧ߣ1<5Oz z׾Yk6&my8t3ebMZV3DZ=ՈĊޯyy*kO +1>>?(D̦UAgӿJwGt݋y#Ƙ++c_7"lާ܉ỹYd ]ᦽz/g_xڞwE*bXiz˷ ˃HP/>+Df%g>F"Y lюB7>!!}[-=A ܧ gdx<KHź8O2{_s"1wOHGmȦD\Z*o@n8M3 ϺYI0~*!Zuzj/zFbۉC>!lk,_v!^Dxu+읙o/.~ݱ?EyHl툪AwW;
e\"J[^[M$|޽ T.oB*\| 5^BN3:ˬcN gOnY$~.7tVuAq ,.? Ԏ;!{Swt|CRB,s#a3{sC>"گ̘Fom$uM_;o?hU ?Ln·k˶ R?G^/jv$2m g[Hn#ԕ2j ~?2{/!_!!ZՈ(po j݈20F7^9mьDu!U!i$I[64WEhէs/^ (6DVxJ9SBvG!~?<>$\E>@b#;Ao*QZ"akBINKY ϩmeVc]1D4]A>")"1.!cw&hMʃ_ytǢ,yzU 'v:([܆HW5]J5eE|agxn!!{٘M%FD#tW Qk1wO3vWGHPwIn(BbiO}5RSϞWPvيxG H('iؚg QnȒG#׼i(Uao"6Wteںf=HѶ0,Jq#ѭע~|M7NUGB錬j 8ߍm_}>pbp"RHy]ůBOI[M6Wkt,"zCoڱRV\Dዬ*iIz $hW3 rwt"pŷ//p!ꖱv7Z7@ス~d dġVq"q}_CD}Ρ Q_g^,_'g8/S=HYͯgu1r]'>,w |?)Ep*Bz5/%bDF0G8nq!*ҿH˶Ĩ#p@3F-ADĿ v pPDIq. l-s@_x8_eM5 #ac~ᝠO}w@BB-]ˉzeᶈNGWWUȮ?/3(fٞkpn! Q.N #6"d|TOtlHk[?!4Gl?[ D"+FbOlV hU@25;[U #lȻd}>"zr.!:Ыր}}hEߚxcu*' ʵO|JIc#fD1]8wI*N1Ow!JxMQr@4i U8#ӏ+tFbbtLq}c0N|E|!*Sg^?D>KjE]"ˆ&$VX]#zѠ(+{@_e']cGtRa"g2i8gϮlq//]bʈcCo->x;Foy)uҋD=ěamacGVG7#gfXeź}f;'i1="Nv]B4z3Q'H#nx9Q.,1z~wF,8,}Z|`<*-8*w1E֜tB\>H$3-kDYcб:1 <|3׮ƑyWَ.=Iߏ~ UvUAܲ:[&z'o+};yDRQ94,|=Gjڏ8l|&2b (UDYrҸrk"5 $ȫȋMP}E s2f[2w}T7xCID:OD@z6q E3! %i\EԱWs Ϲuӯ^@ӷb'$ Y&Ml#߻?ۄD>yD1[D+܈*1yدZ}AT`:3\Hlva|s$MHYHp[tI0 L_>J?w#OR`q$vbGyd&Dr&w,J Z̑-a/W1SږvD}2>#&m\]*"I_u5$?K .'~F7ԃrhdm=f4Q:g%A)WsXRG+/< G*HڦZY#ǂy]_9J}/N2"WhdĘ{ߍD&;O3D:F<{[DFTRqe 3 ݿoF;kfD~C\>WiRAl b ^]jE1?;"K"_g w%_QBܑon+!J1D_BYwoZ1G_!MH0-hEH"1!GX1y{Ĩf-x RX%yDC+v9!w{ΙS2B<-|])rGBgȿˉۑ1w9#QNI+ZMYU>`?? |1bW1JwbCg3zbJx_ ҵ5gH~j4l-"з|‡*4!D:c 1K9~hZSbACًlE ec!v7- v;Š7SDB'j6#Jq.TD <,\FoZL`L jy z泥#U+Aolnz}ŗ }HyL]څY4#O_(3yJ//v<1J0Fw_A :YG{:5 oZ_ TB46'WGLe܎l^^ xZ98Xixoq zb@MJB²vcL$FHLJ5P+TRuraCO}) NơEՍYoI،,%b x R*hI|:eП!RorJGĈIS>c7c<k&:;u>r "Eig!S&y$*r5 _ qE9Fd_ܽo_WcYfU-|Rk_fͪd *>=+1;^ټ= RU^Fz!#T$bf!+DFS "U]SsZ#2{(29ed@?<plb qtE'B:oK! %"]®-~yHd)͐ @ 撚7_NѶO7ZxAdymblRxh}(;n#QS߫ CMV坍:hw9cs!$ΜˢB)1w,y1t2wr=rU"V><-hrV]nG$J:yx%ṕH^oCύx#A﬘'!k!>uOA{+Dw!D^m}7QT\.B Re{^SD9bpa)W*m<0tG#ƗHO60!$$EΝ홈b?-IqDUnLc~R7PBucd,KTM_oG_w"Ӟ&Tn4_r6FMyQSaYi?/r@}#/{/ |.Vx6%Z.Y;$# NG7 Rw }GO") 󴞔 ^`s˵}UhC1b4[SDqJd$Kz6}^{& KUw՞"ca'8_90E.²9}Zb! 5d#֙`zDT?, ۏ۞דB}Bj}_)AOI*"/R[o["ρ$D6M@"I"5Huul \D\c!jJS[$q6]s@_&!_B8AX(Ydh;9{_^ }5%k&=}=8܇Hҷ){ 0>XDѱ: L-#͡7׃nYXZ]Ԏmm^hܶgA f`țJ ij,t肎aBCJqv䝸0blqڭjNs kwx |J@<2ZDX ]sq!>HKK4DEtxIs FԋbYb+7t >\!1j6o,n)Yv]H,*׭0Dh}Xzq|Q$\bs΃ľ=p`Z !dJR+9!KG p'(?j?7 oP(},F;ه‹\#[P "}a hF$eJ^z歸?y|% 1>|"E lM.!YbqLjUә -M J!A oU4aJw1Qfv>0hWFJ tEum>м R֟< kl/VZ#zXH?S"srԷ2esTb>z(z}i2QY]Ad[YH݅5VuJJE ~4aם>'Bq>Asm!>5I>Q&_1S7(0GMG@J#3}plv6D}uVfMjX@kde@y_Bf?«p@u @ l@l^@4@&@ J@z?r^@,_, @%#bb@\!'@}&wfh@Tߙ3@ @&9 v@E3 (FMÕloo/tests/testthat/data-for-tests/test_data_psis_approximate_posterior.rda0000644000176200001440000201244414411130104027113 0ustar liggesusers4\w<۷"E!TFFBFqJ$;e4L(#{l2"QInT*_*#șx.yys|}_z- L ̛eaל}wrpy//+~=9so}\lllcKm/qSmI 7soK/*K޵ؖlmoS۞>˅ 6ږ- ۖs}o /ToFzOҫ8ڃ(m}Ż-y]}fl_hK/Owڧ`זg ^~p 7@Ųgv[z-Hq5XU<Ѕc~Җި^$3`QΖwpsD _Am˺ϗzBĶ6pǬ",P_ʃm{^;ztzLE~_Č4SBi{c |oZl>S rO/-l纝NαȟLzאRx󌳂=Z-l]gHxyO>x~9nlr|iė? F6#uS8cҬԕ i_O\.m?9u@{[zV JPV+p݉ЇDڞp!ƉmP/RSң^>rx{,LHn>u'Wv>tOf~(=@9qRt":ȱ>x+rǓb[R ? Iɩύw$W7y K7h#}x78:,=~`+Zo[oHKj8ϿKצ7?ri KuRyAOg:`5A2cw Gk Jd/}odO{o;В}F>" +Pc^xxvd=j#tCЇU'' `a)̱ɾ76S4^m*@?֥/Mz%,9k)P'?R%ڞ 8aeˁ~V5J5s\Ts pp]1}< p蕒uΝ~޹s %cN۳ʢ#;΄}\XvރzB_ > }wH4W\Q~<{Lc͵/Va ƊЗrcp{Gǟ oQٿT}0??'|9tc\QyXo$ң[s罛Ba.G.9/|dZ`oZs9/\5>K]g*eF./sfNf|Ia/9{-㛰Sغ`_' 0>o3⤥ϔcnZ ]yQ2})m&g9臑!K'|~wwz +<}iwU:S<ڵ8]G:6WRSGxl ϽWMLNOu,0 :죡RzWz7P̀t֜~!U`^q` :|j[ڧ"KI`blpKp]_cN@Sl܁G]SbzҀ_ro3'?7޺^je'n̓> ڜ}n&' r^rlK/\^A]qe hpl3=M!C$]/GZN+\G~0&~w8D."Pwz\x#+0RE_7p/^An`_)R]<7i%}kk^zПWx@O:4$Xo"~OyOzNpp~Lb԰xu3 GCC}Ǫ˶! 5zu9 ьe +mФԳ/iIoYRdKR'`mbx}W06P[xeùx$`Qj+gwI^.1(ӖF%֓*=*>9|3)VsO0<ǣÕlؿƘ^ Ji.wsO)35a7r+caEݮ#ښ+ m |@ } H;j6s~f8#kBm++8"!E20t3^ U bW?=/@]Փ92W*0D𝾪4n D:5a&\|^,ܗ[m ;k<7e@p>KV.u-ЭLۓ}{]bп+/'B7jE'nN?Ex\oj2L s^"Rdayd ퟁsY\AodɴopS >E z;fCL! hUJ1s~>g/ cNǵs,30Gj> /k|Op.g# mTСMPx8 /Ek^XӬ4oʀZ[+ڣé5Z^LQ^72&Ba:݁Rпnodj߯_} ubGɰ}&~5%#wLPpp=7LF-J PgՍzO֕l<:H1n$ŹAC9 ?LB zzGfCl :Sa Γ;UL(/OV-f:p`Wf ߧOSd]v5[K棠StF_{緘n9ɤ( ThSS|>[2n:|OBpW lP?z!+Dch iDqw?[p ca %Rs[FqXC1n^5}Krm.R:KNsVΒ^ޓz$v!{zyCtNJ0-N HWЃݳK("}oYBwv7B?Yx Q|>/r%oA߳~\g35qC|^$x7YX{\7/@WӜp:F.i7i?vUx=WwWGD[T'ys7s( -g:M7%٨EHZOп _eX[ (八tw _4=y,K8x%}wo:ľ[Id!o䅎i^0[MቘwkO>e_QcBl68I"MVԼs7c쿡q#KOy*]栻)3^36ϸ`[St6Γ {'_o$Q޻3_x#RC\ע^ffUɬ^?H?&`~;;wٓ ?~ pwU0\UweG$)]S<:XxUx'ظ|~sc-._fD7G_Dm m-? ϏL:UP=sUޤOn|}`jq!waaCxTaEϙCBߏXGxCY9L@:@'fmU{GQ&}pU;ń!y5A7r6W<)[;TW 8PF|pUɿm}~8]T;X3N.#dl/|G7hלDRk߃~q\硁Mՠs$( 9N>u-?aҼ ?Db9˘-t8+YC puk]ؖ ?μipS f%9ex FGaroaNDA,#qb$IC_\&.N $xNBQuC'6 E7fl)I㓝N_ς4(4ΗENoJMT} M;n-'dj7y ]NsC>Χ|%sw*q'*4 4ȕ5yo'6r,Y|C˥~wLJ EB:{5{@=J l̖d7U{yp q[9YC[a\K|26gqrmL[=mD7ZJ=I*Ef]IMZzGӠu~Xo˥uop{W=/`~2.kF2@)ρrzNܰKyHIB7c/=dE,p=N>@0?ɗ@72fN߃j9fg?[ug'Ynċl>y|ЉJ mlcӸZXϛ/ xiit82)]7&%0 .>0XibVF΋p \; #&_ q-yw)b `k﮽PY i=7i 1{érZ0<''H_/ |?T5q}CAV <抁|z&+}RHowO{ݻ={`s,Wf7X3ȏ_BslyOk G2Z_K'7>ތ ^ L{VbuFOm-y>JTuph 3mm6W8w,|%)O> x^m9Om K 3> MJs'80Ѵ/ |6k VȹRI!ʈ~r梴 䞚_y_!G ,ܺUP\j8{O\'XJs*t'|RަH/3T;7͔zO4ҿ@.c76u5ph}:H4'gwZ)_x$h+1ǎ өf'iDZ JK[ܕmk2gOe &! ok-;5^*,Eu!wNIvpAHKЗ s|X-鬶pF$t&K.Kl}?:틴!/wFƂw,l~o0 .h>7@Go ]nށ&EN{m<}+KXuB.I? u|r_/=26mRϯtNIP;fGqvNNf쩺s#?wR93%~iNJshy":W\@wVmD6~5bu!l{2'9+8 c6=b QPLK p);5 \:pԆ% ? x~!XI5c~nytϓw} /X8)Q)'A=|ik>1BDes>W;,Ę ]퍜m<;f\&H6c'ӓF7d{IJl{"]⥺3t-\ȋ;~,<7CkLbXZU8g?k}>鹪,i&!/׿H4ntx/SߙEg$U-!@Ӣ%O:^}wEn{#Hu'@F_:+1y*+|X|vEi]g(QX,>&D8NmS~_H^| R?CJ]xԉVj> X`\ ~v@܁}H5H ioHDJ/α(e!b<׳:D:e2ʭP3"ju~B^eF nSBh<=O"OU#:VCCH啐##Nsȳ_ȧi?A?vZAjNLG$Z7zv!ҴɬFґ!"/tm""T, )EѦQLvBo¤~v!Nn_AeOx,>RZUkCF<5 =eFzH5rNӈXP i DAɡ}}Hp$o_")Ԑ*H!DE{2|ޜB|_G:HYQ'4"Ԛ# ȤЃHǕ0g]m@1Gʗ~؁_?vaH秈PXwBo62l^l(" (#u׈P:qziBT>x݂TD+e #.}{RYM@(mFzc@Մ#aHsڱUGI>,phRzVGL(80CCy4O~ 9#eMH]MK"R>wO<83\ٷvR)5n= i!9sD iQQ\3C_rJfSHSp=!MQM+A*1t*r&g / >NսH]|*"t݃g fHv@j5'Uj 9Q$Dz Ts[뎖EZ!;vʴ͠_q{qgA2"rlAZyn"H;uk? 4D^z"j{TeȻK`wF7յ}M9ZԣSuuSE'6gqQ~4(R yc ;pA,S'z\C]VHmUKHOb&yd҈iBEKiR-ʾzQcʐMEQfB`E||"un6!u23)5?7|j$"rO#"KЗ_F I4ЙHu?s$;5ۧ"xI9X)ݝ%\@Fy'R 54$L" bQ(ZQAFavV [Q[krKNLп~>>zfiR]%"r.G/NG{Ww}#V!ŬR>i*Ӧua_9P<()$wVY`qǺw^t%ˀr~ p;]H%%2=buٷא|yxZ Ҩp kG?(O8I*Gj _W6|} Y#BEHn O0?2Yš*.#A :km1e_}A0bR7 c5В+&?n~QĀT55w5 e?!?yIT Rk5>"U:AOs[ UG; WHC2?q{RvFy^K9#ԒD}+1AHJz@"OE|#"Fz&YAğmU_2?CQrgYA߾e|"ͅ,^EGc )#ׅ|HVN>HO8 s9z- -؆ t{D= jAf.^ T"GH}Wd>h R?qS-3>)Mi{[_x󗁇*^Ej'M!c;W>G;F֮0%Rz/g#O? _.?_<p.'#ʺ<=ɼ#"ܨꛞF[7'HK\Cߜo:Bxu#/idMO6f}{ tpװ&c\Ȑ yn\x rZD* -Cw[Gmqѹg8N.kO_EwZ^DHS+xz}`-8n5RVB s;!ϗt1QkNDۋԃ>!ŽD'SH"x'DAn0d_ުSeIʓ<}H͢c5iؗY!WxkDRGDJrisvXEDd6: Py[R?D#y.!-u^{)6eiFef"y?D'2 f=Ok~D u(:4>s.H:#\HCꯐC~Bnֈtw<٤d^"nнZHy>vF9I,mTs']}=aTh=)i_7~7܌P/RY+'m:IF!8 1X~B"^7|W2YNA5"*̦ N#UGv.kOg9lTl00{ԉT˽ "5SP 4?޻&79;|[DuWT/._pE/ƞ@Nn\:T%#-\v#&3S=9^"ȿq\D-Oye꟞AocFO /_H]\Z <>e9igYCj͜\H2W78ȟ*MUDDw߭)5!ȟa TtCs}MewՅƥwe?\~q,ԟ=÷2v 8iH#Y*z-Rjc e6&:l/8 ?MS0̅"E7BxmUׂ #R}w)QJ_Cj4 ~F{k!ӽ"#8QBScBnsx:E>C !Z7Q.sޜyh sýG@a7G HKsyyh "w 1#aDxbB6xʞ?6Aζ4O74BX>쪼z2V%2 5Ee(f /Ǘ@nޞ܁T"uY@?~t;>=X,krRj=Z#c}MHZ0S*Rg1-TnktD!'g֛FHsq DXb4{ζn/BA F;""";2"< t),! 4z[o@la[a.,e$ UY}'sLr#Bԃ娿H?[+D*<ރ]c_Bj_K7s l>I! 7j)HxoHP$"0]L1CJOY fnyw8"&Ʋ'~oDmYlHyG0VB,(4.ݜdA]U[9Dc(ReHE}y2KD]Dw 5o*3 8;DЭ1 ]}[ zUڶSx]K myC6_K}H#ٖrD\*A-?Rt̂a<i)yԿ+cMlYHYB"7soc|pV<߼4hcw;aQ$Ґ9=ɺŒRYSsA.un.!!bj:q^]BRۋ#FZETƴNZ1n2 t1wBU&p@$#_]D;Y~O 8Iu@ 1;!WɀԯlREZ <&p!s'R]TNzւ9EU͗MiLGߪС|$&_Mg0*ǔZNkq0bi=JL3 TdgbL})ϧk}oY&12h|xSME=19$̮i/&U_<\)6vS,0?Ir|M1S~.In.'0MNBuw=&?Rw >4&ɼZc Bos)s Sg0?zRcr6&L fİ2Lnc(.S4d"6avebW~+&OSF˵\\pDz VyOۅ_> i-dG81pariL;ܘ<]Q).%'O }LʛRx)LctZ &3y&ۉe+0սC0L5(uyQ&ɅX'116V郩nn?1tLͷʦ+^t0E?7YL!9&\׏)B `i-2g\?\K?srN &=5 )]5`U_ʁ/ phbr T$[ܟUL902I[.oʃ 3[F1Evѕ_0*E0GWI!&ݻ)ڛ _aNg0:x̵~aiu6j˶y0NSn_ɗ\$C' v](6S"[aJn?0Oxr]1R7`J>Ôz'ԕ> a~5MSK>+53NWz؁7_O33˜nfӸn _) PX1%n+˃O?0Jg0Y鏭q<&:9)ΐdH_sEox0Sm%?gfL$ݫ0ŴM\1/<*6cjpIG[LpdkK1E"-LJ=lxMGOB^Zeb95~RL83` >ǡg s1f.IՕ8׋{W¤hߏzq;Lz)ރ)k1Uj@ r&8 i_j` &kLn{{=ݚ0Et1 Sβ'wxv0Ex6!(?e}>FIXսIsBՖ"?ޚݝ 0vo4þm<_48etD?{O[s.%n'-R0ȦSz5 *8^_f[ sv6 SJ&&ئ .kO݅I70v._xub"&Μ=,s?C|8)3~[\ qV()!G9H-J,15L \tU?`ފS{,vark&_~w>37y_0Ɣ\'sɖ?s"rQK4@.o7z`o̓sULfLh2:9LDuޖ zkF:)Xl)+k[み~lil/fx03Lv;Xr%1&\݅i al31D&Luc>r< sy$ to{=kAױpv8oR*g7r @OVuKdƽ= j()=5,yF+g0h^A =-<g\O=s_(T? ɰs4.B J3A]Yh޳]V6_ڃ1EMi4>I]g2>K(vnHZTi)*$뼀/)%c_-oDLt6,8̏ e@ Jn?󜔓ɪpy`JMp'h\JwdcrM k8 ~*V_@cf !fiя1y)|䢎es۾6㓌/DaTh+g˛ evٽNA^9u79vCW;c=e$L"Ek3S,I2Bݐ0gŏ_b+&7_β5->$1iѾ |ϕK;(xfWyY{#=uykKEuոc|l2 ~'ĩG-/fJaca\?;ZtiK]n󶖼[/@/Y֡)w̺yOO68 嵇?q)N%al+v{S:<eŁ vUk^g|1Lަjx4pKTifvK4Cj69O䕡_"K51MygSLKQyH)1)[lTAL|&S:p5-PLfԬr)Z70iH|E jz󐻎͟|MRL=W3oR[s.}ccʸz7Ka?ڬ,YT>(슧>z!x>bj͹=.e0[޽Fn71̶b1rXj|2nEF =G; O{a|[FXq+'{'M7p7p;Ͻ*n7 a q:gl)M{(tKl 6g%0x `"礵5akV Knq].cʞ>lpNΪ[=`>$Od'TԱ{8y[큹,W{9SkL61@=w?edG.^M8~d> iG1Ʉb}paPh86c#'x GcP*][Q.m.=B~2_S}AԨu1EU҆y&OF&!Om:̖ >izucNX?q)y^FWA/vfI4di:qϝv2pc)\7и湞bRh#U5͙n8?F!nVP])+S?;`]UE w2iyC(}|;C'0ɦpsYD=&)is=奌ja҂b9/וofOǶ) j!/~~/MP`4SCnv~}QiuoUꧮ -Mbm|CJ\}2>dvSCӼ0iBo2^-t&Ly( _`ɬEinBMg\vbx/YƤ]o횠ja$DIizٸSޞ6n^y'Br`y.Xc/>%5G.L'u.<Ô3:%I%!s>PuCIfMJRc@Ψ;w(u[$90jaFp]󹗲G!7:{^v*HUC6dL06 Yd}.}C=}FHoe,^߬`J1v~-ijMniE O/)6mb;> u8_b:Ts,8薾S)@]~Rwn.x-Ќ:Vf` |AW L =,)1>-8O`JV=3X0b_?U?+F<Lݩo9 ߮Z7s9o,CVG_OM=.Ik|; /Eڰ/GWB[۱:ZtB/)'bL]y=$t!P@ws=s]c`. 0XD91)Mtg\=9T{\4GR&:/Mͧz1h7Bܥ!8&c3L=3-NON:zG|~bR[gjdNI9wIqn<;VJe\!wʏڣ0UJĝu}QZ{򾳼=P&F`˱.G7M0:lRm[/,`rmJח ܚ3+,nId'] 7fD}qÔޘtb&GSDFW1+n8̟Qwj &n|&+%Swi0dݏur9 \ g`ꍦ?ЗG:1e_f J,q- lTC@gxi.tcIs4v{MKcVpF -OFñW8LAn{#D3r{yE3K~c_LHc߬W3^s;vX?=IN!P-d_)Ϝ.`ҀFUaKT8 e12nFSN۠u 0oU`j\b*)z\.`2øgb\ҙDQL9\ skx_;|qeΐwZ/6xoz&gAPZgg_be~`놏؝ '_XG_”?=oSO: ?'g~ ~yLԁ q$T;a^*Ԁ:~|?s= :#~F>7Ԑ$!A KL~;>C*-!g&ϻ>o^SYN}2$u0alȫ=7uX`narwHL|rrˑޠ[,5 o],0UoY5 d%?'|QsrLɖ}Q q=HϐG̵ _]?sZB[?[د|7DGA~W>c*S-S$|^IVq ;YX[?;A~pzEiv- Imx=|mAS*frRl;>Z0䵍4; Ag[LV7\R1evs n#{WfZ?tʈ~"M3P >w~G_X!Lj{rno/t1d./lO D09>ڣ)% ߯j0Z~/?0~CO%n'ii, "pca# V-&:=Czs7 ߉|o鿀GT`n1UG.5{,cx4.#j8Qw'A>\>5gfșx']Ƥ3_j#xj|l웊ɖql@^%E1)S[h{MukzFvb9N"(kPȃ{GM೦JaZb.qס\jk:_\|2f7wo73Dtbڂx̧"0]ݘứ.~pכ\>C1+^p 5>dh\ƴ95ݘ"Z SeoqcZ&|ӻZ}vazkwLELWx</HH>NU̶aZJ׵R Us3yM[4}-AFJ5y$x<iU adfsM-yoڃiay`ГovaWNa)X $pj´+x>7nB9 (^ߤ 7_ľ+X?=\ ~RLI./W1D&oP>ij?wQ ٦ƴk+evр#aQϪe~PLikw@;U7O\F f=Uvl'D~߀y;^4KjEnj7Swam^V*u:ߣUZ@~m-3dra˔y퉂=tôك;or/4ߏ1-䘦t8RۏJgfg/3ujoh>y!QA2gXc \TS|!h U^4-΂0]<0}<|&{Vj,ǽ:';-1u(kSckpyfp=V2>ف^OL yjIl5'\-n'c򷖻J ׳\1uC$xN/]揼0݀☞hFwE~YWfT%} 3|Y>cZS˯ ?9](£0msL:ӮcZvv!L%T4Q77`Z_c:Av6[OMǴBQVHcm]]O';9٘X0- 4CR}Q<1=qSJ~Ex[ } ucϟ^> w'Ϟc4w|sVuxoDLM3 q92hs^ly ʟ!|A rScL4 !RrxG*蚙wP=|sb-iNZǔ5|AGb^Ar= )Fn/iE [t? #_3~ǁlt?i^~KsyoC?M0i41kǞ7@{}6 i5~ ࠱>})|xd棘=wG#.q1;Sz= ^Q{e}xKE{.q 9zUT#i:rv&CuAu"f^<7pC ^ƴʘv<{Tx?"j7}gRx8)GItn+6>p9o_&$O;y_ [1g'O3'E?%:R6`qc_J$L7tG\-Lzfwgs~֬!l$C3L'Vc uT{t'0qqNPK S| }Xu8S SվR$-h`ڛ{8atƹNRz/k6U321:Ϗ|b\?>> sq=@>o?r3at{< }g+`j0'YloCDw7A: =o&90m< w2at9/(JӦC .m qwsXxGjK|R,};Crtxg## ox_:&^Qϫ5xx1rۇ}*gGsw.зEqqLKK y}S&!ӿxA);ܳJ}$vchsS'tן-lv0[>mUo{V߄  ya'e#?\tx^pFg]e׶sm-,zv X}3Crm6|]sZ]{$ }5 yؐ(7^شO\%ԞH2PW >*nj:0akkJpաPljl^%~UK_iȼ tB6)D+g10j||~ۋ ؗ-< lׂcSVwNɒv+\ޅi^yOr;`E{=H{o_q4&OUzz r2RU>Ux~8UVF;w.nڕ0o~l,C d27ơiS 4hgWdȲNG>p5_ ´̧aJgmL{SL39{8gi2L{HO|~m|k(pep |7O;;q$9Hy?Jt@=s$}BW_mPfnƴQb|%]~e ,Wa]<&z7#9;_}Wz/ϐ3c 2ܾE uȀo M\\O,K~΋pޞCf# ~v^u9o]!ǞHW7ϯ[AN|*vMpݗ~>N+lX 'S}bmwy0* ׹?䑅XfLZ hw U{ˆ0'PLi}0tKsWVLKL֬LpIh LQOkR#l`m1HRc4֮ LVLI_ṷ-c1EdApGL~)-H]X[kJLnϨC^ ̨=r?`;EPG<\0u[Uo_b)LbrÔS_1yc?ч8aЌ-&'E߿h)ëR,xƥ Sv*>پEL~>.\_)Liv6yzd'=LSkq { 7N^0ET=LZQܩ%ػ7\]C_|4 x73W}||0y#_üoFa٘OZSNEKcJlwFLa{ &~-*"bYl:#*)¿04R/ClP_݀ gM񜩁 SG͘<u "4qM^Yʨ.o3 J09k!%-z<4ST4a2V|)ΒaIӵ=cwuט7](KO`-jL S|1hy㌼2kqɘJpPS )C :3{aKw| ŘX(+ ٕ\yrYl WwoӀM90=ZG η^ &bxh<&KaJdjx&w7~"9 HéL|P[F`RɝU]~⩠7kl9e2Nm7~ S"tVd_o] l3Iyw7óPO[1̤LNJ]L%\%>|HM4lSg0RSLz>A4<*).ݹ Z}497naʞDG&јnd1KT1flEOUL{Bh.z z5z|v^TrS(v|+Ǻ7aV?_2؋c8_Gds1Ie 9/iS9oo)>id7&&޻) O]1inoS8ª}0h7ð oSƤu_J1SNJ@=*Ɣ ~~߾ |kyx#>Ap[4^L?pڱ@DaL_\+~'VR "z$aGg^;{~~Ҏ)6V=෷6°Oڎw\uy&>sm*%0'M0Wֻuc/]墥]l1w0ŏIƿKäߧ(0;c_-؁Jo2y/O.0aʠ[o~;œ]|;!f:_3cSuAOB @71cR_nL54Z p7a\^huGy ;9h.)'cFԯ+mn?>A'˙+1%=Ś{2LtzjxɽfAww@*&ÊF3~ `ʣW*]0jO,SwL=&܎ɛZ@ 8zS[*mL|eY cmg}A Sb-?O\z/YmB`eLX% *Ac*csLXoRGZ8Sx'6B}KܲPM%a{?)&ĞYU&YycU_ %yLh |p^L8)-fW^nԲ=.I阬_W?!c7Yaw) 8%G^äg|1YG>6a1|70Y#@9fÀáqVXcܬ`{Oޔ0u׭i/#s''njXwo^{Tr=1 l0BKUЁ=nXS}kT*@_pmqqүrI&o,Ơ)ĥ,~|Wb;~n;2͘(5ttx,`K s[aDw6н]VVI"0Ũ*J'Ėfj}>|o=1OOܘ0gczx}mf] uM1LQn?ɗD5A7^(ۃy'‹q,pgV0s2%Ќ7?  ^Lw ^5Aj8B.Q3 X} o'WĂ>%69?5N|䇏b0T=8DLe 9X5䐊ux?3חpcٟ6KGn%q/`0;.Is~1_2k ?m>zmSB~{Z\ DC]3qb wJ3Li0dy L9|Kxu!o|0cIpOT׎GObU&I*~7/A?/Oc[YUB϶=_jpkL `v> x?Rdx{hjfKWOaćI"IE~&bSj_|M4!Wz/y.g!v999dXou~;ڌ/sS3{.S~FtyB:). ļʺϲDZ.uư\V{Z:2.pqܐaf8=@_dioծ]3?w)+ C,YƊn%ѵh}Kf>x>k]aֿ;GHTxUS daې[{!O]{c O165 `ȝu('1ydLq[.C_|_"d9aDY| 9"~& 9;`n~˭ڕ pW?){(K&xf >`7WVMЩӆ='!v:xHhu~J!Nvb2{LI->u?(rVA CE~Gge!Dd^L֚0&OI>-{a yW}5I?)?tҼ$t3_ɢDЩo{b:>.胂 WLn`%Ͽ!x,( SסK5 @ f>?.pt[o~QȥkijOmw{*LR(tZưExIWN>"ս4~ GOϝy;Y" 2Vvyw y'e`qLUydi?౿w` J.o\ƛ8{Lwy}tȶT>$8jz4)S? @=L¤` zPa/&'s*BHl.cטp~>Sk1*^Sk;b"ǫIL+/NIF7_?ڟ<|{ Lyฉ2tS&bBAwkǎ_zÄI7֮ c;d)ǤG!>6ެR)\'A'{d?Ƥ=!fQ~EdHی ~?I&ez dB#M=q:Љ<S7|q OLЙgtQ{ye2Ɏ 70jOKx'1E`;L)?/tBVN,( D ;Ud啘 rn݄9۹3.>ﳾTZ|MLShZ2O,g%`͖}O }q x%L6? HLu?sGS|l؁Sa%<`}\W5^; ddKe|hRFFʦPF)EC(eJR*#dK%[CyywWy>뾮+!w8<灺Tp&]QV_}d1USs_Rskb%Qxioױwhp;"O^3~Wr XX=|u->>~.xJIёBgPE arG7|~%/=B?,e{EY"n7M0}hY\٘Q C7`G( h;/%ͰE)ÄօQ0o~|>|wy͜I-8u]Q6c#`ɊgnN}CHhLhM^wStB0wdpЮ\ob96d⼏mC]b:p8щ3LK$~\]Ms=ZSbp+LS`7B.. S.)u}%(h+ V.D:T-C]2} [#0OuF6oڑ]`y5J1?~-cٻy{u̔{`|JR?~^׫9tD|Gy^F>IoЗWka?cOFNڔM; ץeso4؍\~jh˚n`HHG=9T o ܄9ip+L InrpI.鰲D}Jhʢ~gsjtbߩ8T}I0LzSd7~Cl}If˽Xy}ּY$W?{:<ڙa$rHc >~X/CJ<֫"lC%C"7 ?Qun"0_#G]-G90=MqB v eLurke/L!x#w\`:.п{a9L{.V N.EXysq~Pv佴,]з7L TĂ_@3 }Wqwo1F0x-MrD28GcFۏNqGO+3s_x3Ê/u'uoɂ>&v_ ȅʑcQ+#.:0DjYm(xYv_¼Y ALX>̿&`o@ko}e߁J-V܇H^241z507h$[a2 :. ە^Ael g@Z&_ܷ X:'.+oxO P=ΏY LSu@}<49&S@΋'ޜ^hYGO-?*nJ Wh80}r?QUۗ@<}b7Œ۩@v? '#@9贼_ Tl`*~9| w|75LM9Pq 5jVf0筝:k_xҵ* 'S,T?+,}B5 ramS@=7aVcW+̆eF*2 `~;_k0*S!lo6`7Թō4sc%\&;G-Wegz>Su7jus0̱۟ T3.uL4 }}@N c#s M arvu4P 4?E6N@8u9Ju)dп̐s@/V_(*7/(c&Z{\kxp_V/e|g jk.Gh `|̀^:l-y6=<ţVk`Oj,ǰ:0*o{A˟l`MC7m.{qy"@K״rdѲ ;Xkg;);[>K`hNU:|V8nf9"Xy=eݟ|z{p0z^ fd I|mz!UCyO72ܨB^ TY̿_?-PsaF}Jh]`)n(&yr3o%=5dӮc]@{DskB|0G䅗ÇeUŧ2P/7? _&ٓix]EUֈζ [bmm@16 zLK;_}x.6bZ%?wcf ,pH S@uojj4t=JYы6iQ_t389B.f\/U0*9_ixa6eJN-pϊyZ- G}?_*`:\0?ڠ*i b7|3:jA 3jgՀy*2P/_z $2fȲ?Yrt/OF`VЭdg@g%{5P _~_} 0Yݣ2֮3v֧WQ'}iuu0m+-I.koε\?ԈsR*dx0ޫ-ڿE@XD+jgEoXgOKS"pݨG>M,&l_VÇ @Coj`n}k-6MP?pEcc%.pߺIĹq tc]`dz?gu)@΍NĹN+4#0{ f@6H1+s ˁN$Pnv>ѱzoUq(9}0 q=6X&s~s@Q n:M"YXBL=J,^\1Xr Zic|G[?ehbm P{ىqJ|c,gtGy0uջΦհpd4qΒd1_HsY+rYLpz}A\w&sn`&6]zoLw+pݕBfp?>SDX{vwcySp%Ϫ9|&דm}gʮlfʪ)4Hf N4v+}HqUVw/:cƌsR}٥!b 9ndy{Tl}>џ7`scR)` ,¹TLn1d{Wc>Oj wįzqyrO cٲ{ n  ʟ=Ԍ˒h@=\Gc/v퉯< n프Ψ $瀲rg#{W"o|q(B18'D]iWWbn%d9/ԨL`Gg(o{U*Wǃ,`]h]܄>uiL~o:sӦ9U='@}HR>{T NS~kҐfT̾aV}Ǻr>|b`$Km\Љ-mw(cyv36C E@_QKvݗȣ}7*P) @|({P~fV퐑]|V98 yH D r o,%lP,K"S)D,CXs2d!EDo_um.m nx~aQ `z݉+آ.K帿ez嘯yf3*J_kiAm. sjpvI.JlX׋}*E1W/3#: mR1뙉  cӒSa,w'7KԞAdwo 3BBE.w54:JgfPlQÍ@ܢ `vb4gynuXe0܀r(ݣ|Պy䔤 ,q@v{awRD`J7hs ^/6%Ì*ࡂ9`N9뷙f4B< Ůvb0#0˲szԘ=-F=`+M) geG`.V>GTpW1 )ϧ&C y6i`:jHs%#~ß[_x 垏`\#6^-Dﴂ=8w}Bd/u&>xq/r=CJ^]Z-9f`s< u6o {3, }r_>}5gvO]kSjA%M^%C2oτEs`_gHP*ߣjoch"BvHUxniK9=#Bp!wrAΞJ뀹;q*VrÕq.cё3 ~Hn(H9ocnk@<{Y>I? |@f`|Remˏjr׾峡@U)Ze L- 0^ 딳x @ ZNjPy j{d>B.{i5AI~{9}y%M}W9U], գIrgъx22q%3 A!z/63t!9Ն؛\ I!۞3hZ%8,ˏw {酾~2Cu Gt^*!;k ×恊]>}.00_\x%}ggLVhM1K܏gGB0bB64XVCNmU;[,|~چyQp˥Q̕/*`8}1ܯT{wwf$'S Nz{lGP|[~IƼ ׵G qc<l3rE"j묨Źil8iܭ}@Y_;UfUя}K9-gi:ǰ ;Ejʨ`/WQ#mٗg!S FTsiXB5!;Hi>_ UR-Xd[nwDue0|+aŮ%:-<{02ɖj}*}T-}zMP:z:`#s{?P\ˁ%DŽ uv{^H廊=Lթ|80̙!̀:_BgsaVѓ8vfqiָߥ`t^}FA8+m/ 3J'm Vf,Ic|sP1˧wzYrq-\xX2!@|/Lb<': SbԼh(~x_H`w6vJzE`c{'cCC.{W)N<]Pa63,qm|ձO,DQ܌zV؀seYc x;ۈ>/ڭ>ð_3[n3[pwm=+3y~kEke8r\yK;mָK:v˙ Ƚ b?||U$`9.\\KJvM%x۰ω9;?wʼn`,](G xK3ֳSZ eB.|5v#ï)륏(K9,S:zߘ_*}^'0Ou!:Uzsh[f-gp# 5ԗ~y{_E|XkϾܹ]MxC0 eţ#rV{"c_,݆)'!۞!%@|y>ϧ9oE'1(՘z=*&`O.9g=VcZ@)ZnW:}ݳ3qd#= 9PκV-}|Z⍹7KZ'ztŒw6ٽk/s{>q ̬xeg9uW+_6|Z Xazڞxm <8a%uOJWJ2uNjeCo.r4~9`|MG\ υoRBXp{1Xy~xNVy@*z|X<ͫp}DN'A0*Bczvٵ-@^,=ꡆN{@9;9>-ˏݞ(y4=~rv$hܵ_@+jޚ x?A8!w8ǐ>-x o7.WH &Y!`G?lK+5;\{w(`(eG ź]i[mQz7 "/g.:s7M?Ctt`Ե#_F܋;<=}aĒ$g -ȩ"s<[ nΓ{KiSlmJs큙}eg-gcb[Y2Ï\qug)`/V5K͓qȃt[DK\ʧ+ q;HsŃ}ofя8߮j2_ ZhS _H8]w3VR%/[ ?@_]thK=;{Boq{c{3qκb3d{˹G}U^Ҿ24~ Р>>B:h,9Owjb=03uHUl7HVZՉ}Kyg`R{DWU=Apߕuar(Y?;y`_YS.PP!nSlx^j9c0q )^D`frTi!@H=XRzn^gUmTzQo؊u^tvvFգ 6=/9`^(h tY[Ly{奨㽗/90c^tGxu.Ǻc_8qHF>a Лen\)sJ۩ ͗X@Y7 EM`$^>,ru̳Un@xi+؝30̞CGG00?_ƅi^t`p? 趆'n}1Y6 WFy]@/ nIhsȌ ^ 03v@~zrBDG?d]BJumN #>,|wFwjNhm\\@~dsf1pˡO7(r.hӍN:.Sv8 okDHKݷ]N=nb}ݓHߕ^ ;bUQ {}ZzW [.owAifH~U\4ǹUnz$+ǯf;\]4Lv0ht=ςv>8k}Eݵ1`o<>Oa_ ^P=ǃ {gQ=2kݖv?Od DqnA`J7J$z@Yr`Dm]qV){^Ȼ0OSz~`U_k]OV)m._`3`˻&Ked2{^✝s;x{.ۨaE/m߀yE+V ueŀ=6 uxwҀ>\9?RIQ`,bۅf$9 ϧ-=uv=]ѯI:п{^={hF=O8$pzߩ@duF^g-빟WRyKb==/`8I}GܵlaO`kt FF(2#^~Z%ПdjnL3? u>,}c3Q"(tOƁtvϺ}tw -dna3\#Ǜ>O/Ay^U?zuw}Z@ܩqǯu6ktFiˈ}€S!EH?)3<#GȼD?**c>5ĭ/?t{%dqGq29]플ճE}SN@ 8G/dk>L6C~uY O c͏"{q`9 J}M3]"p?0rycϞ[n'#/l@O }^ϨOkjܿewB?֜_h| ]W=V:гaw-䅥 t;k*r7_f>zE_Ź&@>1s9%r0߶Gcs#1u6s*R1gZ7)]j~ǖC8fsם=t-sdIi>bB6U[0UC&ceM< &Y=bLeA[b_9;f7/Ã/PxǣQy[sCDpn1}8T}Pk"SvasUm-wj}ȟRvCҌ]{HM[1vV.?RDf= ❢#-0E:D">E Zԍ-v\!֫ay~5,hFb~{\%Z9[c- 4@03) O+o7y/Dx\Uke@M\\:yg=r[>4̋gQ:kGfc s$u+S\>%wD\Y=umOm#n&M@\p?'J;r@AZ M͌ݎq]%@gXyo^;"|hC#ȉYiߞ^Yl~|6xlu%*_99ή7 j'U-g lXl_=]?$^z5></76:0xv`_άkSp}!WpLl ߋ3ҁGxs#hz w|e葦zs@9}qw}V_#|ZNׯe}l =oq!B8⒑Jܿv9`4m wWI+Rݝk?.F-}8z{Оs@!|~O 'mA]2lb"/Qg c/^,w֛g?D=nč@*>'[zZBݙǬ<Jo҉61g⦐7_!q |ʞ@,['5/ ]pG>'Ƭ:prCL~̻9g#goP7dl-9֗k%m]e@Zj|=9KQ=%l8?4~tCQ[%E coaUdd9|wV oZbMc:x;we57yTu;:v_-.gJ?8&jۤuq@dˮ~M!s=YS}r7q̭-Ϣ߷q;3W{` /G\}۾]ٚKe̷coÛ9[%^V5T1q9U dJj,'3%Y&0Ȧٺu+IF*O}?oJ>G^J@^:{nPqx37~N}W@+nʀ7&9^"u8?aџ C{x  ˁ{Zմzo70jZ|gXzA\_uޫ@x)טw/:o~ \koOں yjB^ ǶF#{7XӷdNGz۴rSݛ[/"ɬ5?澨^#C56%aձ^zpf_tW ?x罾o,)ZQכ@q^s<Ҩ;=X7 ׭s;Wؿ:P" t'&W#k [3y'x~kE.<ZRo3qzȅ=#4a*1 Zl9"dr]lKGH}2RNԕ}Ws9Cp_8S,} <6z|%"}yVrEt8\X' ;731?*-o6ZmQIPW.:_c{9Me.yEIósO~<[tKq@}|(sYvEj&vUH0uCc|&IW[Aܿ{i 3T4u]n>ղKk%Kb?雑[&\QPߤO&0\BԵ/D}(6ra50_ /}+mCP{,:r !Un5yWS,;giLG:z> ȷq*Kp?ޔ1Xܝiò@ϺyNDN[O>[bbZ|3w|>dp  @o3(:\馇|vס}Vl-:`ݺɴ~Ҹ^&-'תzG.m%. NR㝅~[zFE="w[z\R|)SyC2 ПYF|rY }[@(ine_iUi~5.Wf̋\9 W|UR ⯅E+-Gя^Q>_~Pӻ_ߟg|xá)E~=q^0m4muf?ێ4>+ςVx9V^t`cYrMaif j[=4q\7G򉆛)ȷ= '_c4/k 1cj@*d{Rm\xxsۛxl#ՁvWq IGθsﻱ<(r Pؗ eC~2(wuB/QmoevV>wTƏzWE)@*htD`^vRk:e${n;hoY"{s̨%ya#%X]C̣6?S¼5]?~cކ%+ֿ`u+1$usk$qͤ,`.%^h;_+QSE6}w5B}"?V iVS?gV oB}gIsƁVwo^UX[Tt< uKm1o_?v\3F73_`ύ|iu] JUg9ڐ nFb_"0ao-S2E=r H8JG0.U߀k} |&욍^|`(+i/NuzbssrrB:PQin{<dՖ@T[x6kMu~ozw~P[~Ҩ}v`.ZQACYn+P϶',[07 b f'ƮL46R&sn1ӯ,My/#t<;̅Vb "VŕUnˀPfO@kd0r!{.ǰZ1R&͊@>2n>x`:.>jT]1)eOCX֍4 iUSC՘۷lY"@O&ǀy&MLη꣍i@~dw z9i@&lk{8IB{7?܄J5HՇ^DN׫؟IҼ}=|=y( ?~ul[`q wVܕ[ǁbI\ssa>kQ6]vM `J%O5v21U eQ>,_MLﵸŗF݊.k}ہ|80Ak r1?9I$ z 3n,.D垾\^3/kWi4sgkVIisoV@d.oyUD`fv=bE犼!@p+rjԯxjԝƦ{V (hV&x@~:ެ[Cq}WB ? TUn]?(0^:*;$86{ K(bSsڟH tJF83|ϗ~O.`]qMfĎ>XkD;oJ/@3SȲoB(K=Lv ӂkԦ˂2XDs q@}ܲiRO Ŀsy2JȓG0fޫrGVޑQ?ҫZD%T}㵕NGp7ֆ˳{_7ZQSqv_Y&q>ލ5!~g0GjJ|ˈ E\Tկg/p{&uqUQ} €oE`'޽[ C$>ܮ](/a\kw =.~F)o7%aÃ;fΌ~j3I}0/מ{`'O~ j;D\SD 9;p_;=þ@t޼/4ӛ<}FJ8C30h#+|Q{_+PO۶ O9*TQ2Ћ+;nƢJlpD2^^4u> dY`T)]ܸCʿ25C?~~-VFW2}ێ&kœl{9=b nvW:]w_[%(c%gm3o[*n ":xe3 GtCTOl4-F}Cp0jiU!F'rCx 72ݞF_xXգv' q7Q$߯;=R"}5MFΒQ̝rn`*?Yd:?58}?/gġ={kb_U>;Z)w0] {̥{sh灪,+w S ]Ds/~7&˞:y0zk hb v, !K%@6ҸBu/PT)W$0NGoyB*nlRf5IV`JŧLbF%V)0 {V&lݸ2s܂n%/wk8?,Àʠ/ΑGi+0{O9p;&;ް|n y5!s'ړ/ 0v\*{ f!1I`:c͛M@|Q@> ӳ6ϻ߆nA=Q 07|.j`xds\;37zO{7?M֎ȏ߷P BhW>'c _+z㮯/D}c>r PV&Y䑏65C1PRo)0/tEr:rU $8woj~v2ؘ1_*,Mb΅ۻ^"=5}tt)H<̾J ][<ڼtF70- ||6]vzzuxW^\M 5MZ̋8Muc@p^y0q62ܼ0Oϭ_N 0u>Wb,-YkBωLu&SI0Q.ֵM]Ooe8jѻ4r=i+ ~~_6ۅ89}+eŹ-춀g.>$?r+ ycp={zbOі:PXl<KXQwrzޫwȬƚg1Mrl;ddҌ cw;ٌc<)M^sUKg@ż4h6un`\P|QmŘB_#L,5fnըQopZ T_|WEWG=:я_׹`5r'BQG-u,4ǀ?@= uW;4Vr_@U>NN{\!YΩfM?6ϼYUs7iƕ8w}l0E.z0sxtk_ʷ}c@'E7| NK֞Y{@7\j]0An`^U@)J04Q0ȹE O;%Vr(n ފ@z__;rrxM_ٟԝ׊&{uh_6 FRDR¾z5P>}EJwɰ .( lґ~D_H>#ەݏŰ/9onl.ޯ5fͶ\Ɵ\-kf3DXNh ,Tm?x,W ,̽csHbU_U l טľLA RZȣo=^mc9N{\w=}@lO]Gϧ(+$4r=Vi# W\-A~|'x3y={$oH~K>Kf^E!9umckK}{I%?}`V8}'1\*qa.Ҩm>U\<؋ZaeEC]<1uPtTV>Q…e=;-^ff{>hXw@դE(%SjQTMrр{p?v֐x%'~4>X|S_żH[GB?0#C;-5cxg r⃙, J{mj_@n[+Jo{uOOe|ݛϮot?mD5U&؇Һn㾾/4ޜs%y 1)MR) ʃ O&P2#!QP *Wwb؟N`θd]~v%`/^mpػr^=,=&%%q9%oIaϴt}+uysʿC.Y=s-:! >ڒȃqbj#Pk|_>}TC䮵BFeJ\qNEivU0~D*`θ y.Yi*7xndO|{Hey2gZ}]bA1LyT5u{|EV\b ؏$0G#HWcߋ}U}Q@zwG>Nv>xrs5w8qkM>R9X.!ُ߾Ḻ2<&,˼~׏WiFJ^MGnMsT H_b!@xsV@Ƚ;W.lg"F'G^&y_Ő!/sC@,=8 Z&O\-fk$B.CZk6+8ޞ[8H 5Ehsj7kױ9|?:L33:@9u\ }s}wj$珆8Oaή[tѰq3S>pBvO0/0mKS__v?i 6ҹRؿJ˔Cu}1,yˀ36"u\!$ ;uU\5Y뚙zQB::gmU L4, j>@G_} Xk8쒁Xa9+@5g_]v I諟ēJž|Aqϋ,8NGdw`>OMzJe 7͏hx‚0v%Gz`OWp)6M.7 5g-ϦCՏ?p)˖;iAk0;]&e LF: ~nɸ^by9j~`T*0װTbCtރ'f _쇼%'t}@j<,Z}V% K֪$^ zθ]vby .:1f.21aaƧ@(NFebp]=oiCߘ;g.y* ߃ w/)Aґiy||5q@}9:b}lk Ӫ؋SrtQ|4bI ea̍p7Nj(c rso#_Vܿ;g y@ Xh|D?8ai Du'SfIQ ax6 yк24^?Yҫ.%)C y| 1O^>Dx/O>sp_rùQq#2IQSF2:ޜ^: SʚuoWO0?w`O,jVk)gxӶM8߳A82U<Î^[{e .nuJs J<;@b] &OCsf`ݫ*\7 LujۀgŰ:Wv nD/9ݾ{:_o=N _Mҕ_#V~f~- H6kǽm9N=0ɞ(R7es#Bb(j0\m4{"á_?1Ϟ^X˸a, X{U12oF_?|B;A;5L6绫h-I8P<{JմM[ms@sS@9 _?nNgi$Ob^=uݤ|5}R {?g,љ~Q r'kYO {S@RHƈVHڋ: ibp<- ~jB~Ko|ߺ7c`Rx8!L}eurSNRW{iv]i 39~(r/@r?Ci/89_3سD:-?y|@V_H& 4šoop?p A>e^AebΎ.3X:s5ρh \Ol"Pf3@{CsyxK$Leߌ9yȣ|!?n(ľmppy*YYOs1;y7s_> H+ߓq~7(SD[%or2hzk)dV\4_ӧj,\͂]%'=zn(:s;Usğ+c B8ao==⧇Ν^yqr;{9>JՊ߇ Q!W8_KyGnd=[!3 j8sPcnM}+椷 CܚtSL)ˋ,[cc1ozW8`P]1ɨ5KP_K-V-<>)1$3P5ؗVš4`2fi}Hf^)+0uyNb.h^f'^dFN}1qKڐ=eOxå\6 frjuv>,0M/Fѧ9cDŽaIodoCVP e{G\WJi:qY "@D~m`v^ȓ_vΟ0s>rS&<4rW,~k3+ #'.Qtzg\x{g@ycƠl8nB`06E}Fe@ =d`HSkEA ΣWQ CkM8wRFyyZmrl ץl> N[@מ8ywP!eH{? u]QWZt8ꗳlMs:϶W?-;c_)O94y'skBǑO`owUsK{ i T'aޅ֛y6G)Lن\WԽw_P3/'9}S@vinލ\%_< צ~~(+ W)6+@p9^ >EfmzJ܀=AҾxNj4[<Wo}9n~֯F;6B:@Z'JoG.cU~ ƸCPM̫m=70︫8~9ʯw~fi 'ܚ@<+ /b"џ|7s)vcr '5={]dl:c:> >Co0PlDn̕ϫc(s߂qewa8ofN۾ex=W/0vZ#^IL|sv6 .N%.Ca @/ a*comx~5SW 吿z/sjIgף! Wz3YZqjx ;׼Z}tu 6!t"_J1b{ntG[/O@NҔL8ą9O"8JQ ;v;=YfѺ8mc5=5g)>B9jW{sDI9ٓ3A"g^j*~x]+Pɞ:x|)jCۏFa.*L5]O T~Q̹U1K6ZqXR@OpE]d#75++DʊC"q؏xrA Q(.hNBM t>j_Ƈ'vf=Зx se W$0 [=/ 7X߀b}]yU=;sY,2ﲵ{Wqiv|={`;+Ŷ#gH!܉-~9Дc5lCIƑR:<`9]jO?9aZ8c_{Пݗltw'ScWKO{g/dvZ@Yy|e0/[2V;ޅO1! F@},=:M\j8giwZ|ؐ$0zܫ d`̧;{pUrG3䗮;ꗙaN|dRr S-y|8W;G7Utԅm؏ZZ%.I;#ÂoeO`?ڀJlBfydYgu)!t1L37{] _Ӹ=V|z Chvp.ƎuԽ{paϮxVq| H1~N+Wq䬖`LDZ[P뭿_s h k&E-[qER|[%}iidVy g"u]=:5}@9&n @PydįU2Kczv;0>H}u맞(D}O-k))ѾҺ7J Vר+T˾Wk?~m6~Gbߜˑ0"veqNUr?-Ҿ}R"GQq*KC9D&R$h+U+mVjY{L3H+ )0*ƢƑ E_/XUwҭ 3ۀqĿGPGпJ~"83s[vKV%22/6~yj$b#8\:s3j Ec݁Oj̿o近.?lFJNRgZW\u,c7^s֣!`~Ѝ=/i/^1ti ߷K $qɵ_>S/0bZwy{®W2P*3/wدu$ 8̻̿~`ǵs-:/}أ]{~ JJ95x]`8 Ilm3a0NpˆkϻE붅;E=s(7OP@NLۏHrUsR<p>/)rrUm2/fdyZzud]/+95oUav?$0/fzu!Y?r sqxm}ϒvaO 5>g?OL '9a~[*$=fU/'MU9`TM,+މXT-ζ #P`l`zȩ[7; Lv]n32HE;P'*yJFV@ۤğkhyy')d .?qR zT$?d|Z5ukr%*J9S >eiG7oS:>szTLK<"hzDi{mm_ȇPE~ΞxO#uT"5pN\wAoAV*`0E}W;>iDZiFƝc#9n[@].LmNO(/-¹~r_]؉yq>'mNt nfPk2x]_~c1Zf#(ߝھz.6# $˹Fl~bB_3|ASS{eVz8r $C9A#+пo@ZYq[>/FkƔŀFcBZ ,3`4?9n}4}0 R;/ہX贈/㷡W?al)rBo l7?>[ohwi9rZLPßc]Cyrq~|ϲӪq1y*5.H!o(3ҌzeOı-pM}D{:&w|U%eF%/?T/moeZ:4NW2K[ܿ أToFΰ͉|l 0`Xkg*z`hد߹ a,Wۊy,n2ǻ Y /97s]'oDի,|+Қ,@L(r,R XJ*tnl`4v\ߎ=֚3;|^]zi3rz%/0͵~߮|(| (#Kx=ohd Fn@?T?"~= o>=Y yɘW\fagL}vR#UKF_;yl?a/k~ZxH.eo+v܁#gU@ zkN ] 7셡n{.AO>R %인|_Ҭ9s7#?zVfӫZu3|8i .ϻ3}}%5+~i);hݯ 5L|z` /'U>raI=Uf5@=y(Җ YmMaܕ'xg]9uV~֥{H@)}Ɗi$〒 о F;Y@.,hM+)f`|Oj(oXvXXVkة잁@}po tw~7^K9,iM~k@WQ{5e=@dI}{Uq p ao۬o t_ЧVY+UOM}oaZS"z0N;[ƙڏ5uZjᘄ1mr麂o.-Rg@LZ.+ -Xk4s؁:/5X?hk5[q W22ZLTMzܓ##豈ntw{SQ8krtyiJE}W&]jۇrn;;{z[nweq|W}ۺoN`xF|_~M[]6~Ѳ9n { Z>hsu Vc0֦:|cg.XE+Á&7$ ^/ԆZDQbS>|=zIR Wt@\:/(ᴽM_tdWj{$A]YTNP_*/;ACTu Anoa=wh6A1&KV3ҿh.E~0q5[lXkqٶ u/z*](8"hѻ繲uxPغ2X rxY/kME@){>ӞᇌIO,hUrR@K*XfJ=Ѝ.Ċl_Džz4 j%#0d_' !,`SwW]A=Ǭ; Ӷ%v/(O;)gx[o3Ku#- I3:A-*i@a}Jbb>K?/hiE!:E0#g:1;p h_9q8zBU(yZBjx=~ }!]"cx_8S%GV 'kHzo}@4ߗh[V4QU"A8н#Ɓ~/Ss6Qp{/a_a.}= '3$'^gy{2Д֩ybr7о:7.? QSYl'iZ0mR>Du}G ^'j*r qZޟsrKr9 up2S_ eG'Dx%~Zww@3OhbZQգ+#يƩ.k|,Rx9"—O#`.KsfS00kshϣV6tk݁vʽDXh q[˿X JOvG-,Z\O( 텵0R"x9ͣفQ*~h{r_\FSgz1^5ؒ`"C35(i]fν4f3 >MXb0?Փ| U7, vw=`~p>|cHĘ9ucه{H2(yB0 {u9b+߸>ƼM65}߲~k3`=~W 鰍a]%@|=ruv#/\ӟXS 1y >gBcN UE} \H __ײOS9&9}CF,1wH^QJqޞ|Mo=E)eA ّ,uG$p^CVȌE v$^ LdiG}MK!Lsv=aWW}jlx(T2bEj+'#ls:u#Viߦ0k`县B8U 0Ś5]hit̓PfExOX0AF/zk\J? nt4g?uN)8>[*f.q#Lo*m%@d;0a܏oÛ98(h b~8:f<٨?[.O5n9zRR1LƟ4+D#1ȻF)+8$d"/8vƭ ,qp?ۏ _Lf\Zy |}S\DM-MAS^׻|Z&!OYu{(#v]UQO,toM_,Ӹ!ߴ*_~{*6Sf8!_7E?ښ.~L_[F:[5:08 B?;wo 7r$Imo蟁?{xLϘ@~uXu h[{G&9y }|N~\KwVc[yUio)桻ݙ -qcSe%ôR/pN+|2/Əx[W:oeoF-p>wεC?Wz5 4時°8Ko !k?锿Wrox=?Zk K~0[}}[2` P*-Qg 7j4i`ѷ/dy}hNs[6-7Ї-mوz$"Zx0'#~ۿS#}^<]`Gz#y's>WTyl'5-zJr4Jnuc4%M@١Kuдݎ!G_< ]s4"\'Rswx,{.cyNov2?eQݗ-yKs 9NMW0m~@?r;ɦj~ܢb0m#=6;Wq~i#IaӫpǸ@`zW*M5l߽:S_x"a:[ēJ[ t'ȿu3`3{>b*c ͆dv`m~9Oqtk:yl_t;m^[X/iq;v|40o?y6uDi.#-S˸Ky|^a?(t+q;β!ΪJF{|:h5mn")r}u8T籇ykgo]zҏiK>_9^چ.5Z1cOW߽y.<>:4o_a?$:}k{}[[Ŋ'ݷK֢*yrs`:[S=ډ姀ڽ`CuWW`M7.n?ҨYӤ7Q+FKa^st xuQIg3~<O=]շ*3UU#^|x]osmk_f̜4!X\0䊦&PC,ˀ:_WOlBz| ԉMoijC_8׀{GqSOB7t 9MpC6V<Ǹ|舄ݎLotao* >rιA)<;D~.9DO߄|a̽XO,9bI5H+umxf)e|v ~ U efB#ss8,iaKY|Neˀߗk4%3@,lZl`j ~YBh Mʉ-6<[nϬD}> W6AHU }\d szԦ-Y,>z|nY 1ճHrJcFTOu|Bτp3B*nB=*&o௾43 (ŸWxfɹ=0ɤEW E:H?ngG9#V}c҆3 Muތ7ɶ=F1Ih7($<\.Cz\OohGV|g O:}^k<[rݿmOd8e! /j8T.s;L&r0jGzD8ރ~m8ؐ3>0t#/c }zJtûv8ЊFpvl߹O`1_<-L>#h{pbK Q<]{"<TT~P IR Θd~:Kߡ&>ϷHZ ,KxV̞s,oṣ~< ȃv lp=ɠ ?Ny?->kóF> k,UmUe!;k :&a/GѯSW Mk79R?iiPg $ >CA!Rk2Ux]|3vqYߕ1[W-~ |G"0*|,uߧƃKүli܀njdvリI]0rLX}_q<}`Ct#䙞^\ =!>#Ao=DŽr¼|  (&p6&zVmцI/~^ uc/Q[lnM_(Ǩ*1\KWa&U 7䯶&907: /TbD?%߂EmuP ~ν;3*T/_avb@Rx %|.xI<]C0a _C Ŧ7A_2 fڢ ^Xᙒ7b|.;i |QR {hawNͲUoǻwU<]q~|Y{f|s̥g ae]N; 4*kr'==SnҒgjw/wy֏rV7.yĂg,;_}Ѻf,s3Y))(n}xp]D./&mTu8?8Im<4+g#tFv y$ηKLlP#Yէ}?,;V㰏_'NIyaYI Mxz&m*(Ђ,)t{$ ||;Y6z+i~[h\l>oq :3:XQT|^J;Ee`ڴſQGߛ0=\1$t=-NbC]5x}@UL}&閚؊ZTm*~5 ^N zӣ߫8㥃OK7t1b'mXY&^yp,nn;%q^4?cZ6?xYM)ީ/*ahSLm0mAߧrC{slob[ixi|gKx3Iמ]xwj.yq_Hƴ9q1m@^ړb>s /rd `:b0Ŷ'WJ`ڮ/?ʽ1}0YQ h#O?hAxƶQ Vc/gK ˭p]mM[aRCe+8: ?zj|tK;~p4cl;Cv}/^;VyDm4=C;Ws[ω7Ë<%KcvXsIv"v+c$9pXj'^wK&vS%װv=a;J40p=aϼOǫN\ :ks|!lhݼ/-Od`zиx5k ‹v;1]ңdqŘIo4~k⻘Oi"4ݠΕ헃ZVmi&|BEWˮOT w{?mp9KT!˞ Bq$8r^v/n^;|hLQ[9iW>yo|1Y lVr]SUyj%[`xލwq>%Z_x]U ^'#r}$U`Q/LV5QҎOQV觲 }=d6ûd7կj0O+Šŕׄ']Kxy:0F>8y/DžvnV*Gd5O~/8򀿾fǴo*biB1^N`|<5 ks?L[! C71J=ss6`EpyT^ƣ?SV½,Z%;!'dPKҾ&wϜpѓsd)@7qЎWߙ*ܡ`swp^(W }Jhn/9lϙvYHLܦ+x9_0kⅱ3][9v=~+./Vo4d 8:c2Tr즚 .nm|~0[ #2!)o:4}| t^Ǟap)y.})K ANR~}< H|V65ryLô6VIIvWl%~^SoAWu~}qӗkicË~kO#1m6x]V)E)I۶Gm*sd"][=U 9~ef*V F*n]7 {w ix4.k;Q7^H'J/1] 6Z|t-^zP-LB!%(T3ܷ/>H\^n-sahrtPFTV d㹓'P# 1LSR ^轸x /l!x)c'^&:;{x8<*I/qL'¾~$I:5lޣubG0ݚd klDu9-vз 5L#I0-tnK>9ë_m<~@|DNzȖ cBr)0/KNyJ_PXz:p/5`4%VozioͷUL۪y x9_~\.膗;ۮX?oFgV /F06i/R\|6GN1yM=w;pWŠ/T A.s6Sm & ^`2H܁?K:R/RܑLsf ~H| 93j Nǟ_<[jzzG "{5Nxu襏0‰ÞYvf*j!xwJG_|fsCO-^b^p L&N}? yӒsCtd]XO9 /aNu f! Kd ~bz|oGR5 EzؓxQ2h48>p*s3Գyq}wN6SN"൙-^~ގ)N^_:+n %>Ðcf6xo ᕸ΢5ЍSJTad~V@Sl/ \2 kf!W%m^܂iX9gێWXMY/kK5P7I[߮#lçx- 4 vVcg} 5L?G:_/k68t#cyט1yS=&oNTVSYbh/0.˧gA?DT?(:?ͱ/=)>˃|A2&gut&f*Ô3ar%W-K[/E _bg@L}{SG0dKp \Gch Sl{[RNc2].ø>L!bRK &]칲9nd]_J966ro{ ))VL6!xx?!= "&upO.Ŕo&e'i݃ѩ0n'0E,m._pn(׺:%xƎ=irY"^Js_aSK1.L>[@SRbߋF75[0aO_L4ha TW+EJJܻ0M?r{Srnq{Ĥþ Α1?6Lj{h';$6t6jwJ|Pnu"7K)$SS1Uv k&'=sz~ p=):k% T&:, SMUԶ/n [47Ym]py#&o pP}b6I7`S:t{.LN:^x_3,St7p)Rx0[CZ$X܂IG\0)S8+l}_+M0і&g}&U:a역㮅rBx92~S3hԧo0+n/& #Lbkfw.nIєWaZ> ?|%mƫM1GN>"\<&2):/n(HxSm=I)ǜ̫p0gd-/ujT9nkc0WE`2|ܼ22ɣ&^yſ-i3 )=}`]L3/{{Ek.=?a+zLaev9z }%t+0uØ_e9(?~]i|07ε8uD dߑc#yONozЯAB5>24צZyZx,g}w2yMOd FTɓ9 kQ`xPJ_>;ST,o_yՁ;.jo/ ẂLlEw5Ӈ~"0ekkp8Ɲ# :|u)S^Ƙ$ˈr!T&uL-ux>>ިs]0nh0 }?d)FL^۬^Ս0?Y/i.xr4/ŷfg95s/F;Sϔ VMc?/m>gB&uwbb+0K!aBDZfZyj0T w`l?cJpkLi{W/^hL+N-7~3cU;}wW Cײl0~L):iqC="m P!ʶ y6t<]u~Wͦ׾C^UL<;jryYn hA[ńB2WwŽV^ 5 -{F 3Ր '$Z~mNb;>H|B&;[Nj1ܚ5 <]'?1i.~:3}w7cҠ^̷1Un?TH|Tzw&ř ~8*_cw࿲<忭]U1pF f>: yMϡ O>zIƔoHCnyyR$F!hgG}7 b g"ǤT|?nۓ㇘0鴟.L-ԑ^ivy}6k0读Ӵ@U2֙9X@/l8lYj P/N{r'tPK &vߔrcAg}Xb`iXeX;kc1N *}|>Us ~=\ab= aQ>]pޭ2Js< S1w [4Y4iЧR m0:9J=D,k<^+ Jo rx)Bj' /Z؂)Vލ Z,_>|Pjw Ao/.w޸ p#G?O]w\YEaIA&V뿟. _qrG O7Iu,SN+@^u4?~"w#ԱR]Yء9%Řzubx-=[ []/ɶ͗3iP۳-|Ԣf* y[,R,9ˠ`ʭ-xSmSMV >-$.}\0{xŒvTI똢z=-JZd#oF{1eS<14Iqw-.¤"V?3S3tLҒv9`[ɪ6;Ln-F$0yk؉dC#*}m%Ljmkl-p-[,RU6GaRؕܚx.|'L@#L^e|&C;izx좇*&X_s=*ָf_dԹ穫{zx|3=q&]|(h}{0Y2[y1~9L^,b>iSz7_ lssc%Sl[4~(*Qې_XF_G2\0p?iI Swaҕ_~G};mHk'_xa*L%&uyjpTL o0YY'q'>eאx*93PV:ӐT x$N/iWsB׏Ǥo׶>;/xxmt RB*>izgn>ɭKaLxM[ &uT)._+8q6e{zpC+Ϸ|~6}?[^f̜߳JtYLk Px<>$K+%"-0WA޽s yRJRG=Dr5UcGoe/P?ү!_gbBн\crGSx.;o܇{6stRL&hbr_^|`sS6OTojc2[G),k2R^׮9x5m[-=ő W09t%5jan_م1Utq]؏y˘"̭a3=m܏ԯsat LA^:%·phRf'vfEԭѧ:> zI}MW?U7:A>?oqS')~QZ\@V ltR &55\zf:vTl/ׂm_5-IAv T[ \Y$F3rRAG111iL`CyJ\[iĵAv(be]jP#}lgLzqoR@Nj\cX sfjo~WB;d]^A?f($]91G"Josʕ\)䊼SO~_W1\X,bܳjώOCj7G0y0L-hx}O\>ܢɒLV>`^6S=B %wG~z qٷѱW@<}ɠ6焭;6P$;8iqrt>9["̲!Gʹ 8rxC*|W v@4KuٟbjONe'o܂eS^z?KA*`6V3\)E7U-Q=#޼(w< f(3gكI 4Cj.G~?VpqCQ `qGu\L7.TvQ5;$2goTPA.Нn sbM`KS}:`&ȶp \-jQ 0ÐU*Ӧ ?VS[w= |m`)eYS o蜁y-|p)^J"_lk֣{ 70lNއ);crǏWS4_Zwk I =(k+wl|FZ!w_׃ܖA S®Iٿ[>' ϱSŤ3 +1_: CِV.𙬳* 6\IgﰓX<|bG>g: އIΓOcٛw&lI*փY.؏aJQŕ-|rM?&dw9mQLzl $0ٌsucC- 09Nߟaw|7|A?_P|A?_ |A^7ϵ~}qɕ,vb8+WmϏdz'L6*pm{\Y!:G\zY=(̂sVogZK(b ׉FYK(t>.(ð΃TopN3MjpG~{d݌Ѩsﶺ=zRpެgSV+KȽz\_0;U2 CNҡL?ǎp{v%`=#6/yP?4/[gofzڝj0EZoM?P&>oǦ6%^Ԙz=( 0}Gͷ:/tA= m{2Y8poߧL`PvziԾ,KI <Mu.er8.!X}Is,{"^!HR,ãǝ"7|^߬_Pjn=u eI -u ϏU >DѬ7s+}##{XOe ϺT2iIEMT}mI?8 |ʴ.!ϨYM=&_$}>N<τJ5uO`8od0a&ƹpʿQ;veu O/tA*F`ݨ¾(8_^-~zJPJ^=]|p=nܜ҃z'Ro%?@Uw%< NӇs:O}ERzmW㇡/!S-C]S9 }_p񬈕G5}t,u1,7QPsMAXȭȚ' \=Ux\x!n-},xzَ*oeak*}(! d6swދso(?Fj.3'ٿs+Z'._Z=f_;XZb C;3"p݊_Rd{qQ/~CvxiWr=w6R`4$^<>K}'%P O.p2i`PlV H -yL`N܄8E9EY18ºQ;6~a]0v72mGVXǻwnKY*A о9[HtfY.$G/=aJ,EgcyI6PTpx? U62'f %4GiiNX),Ei9?Uæ }7[ 1fS-.ÎԋT[qT~pK p "q߱ pw &oz9nIvuhrQs8}]~7)l_]K! Fa\$z89;h$0۫WuV|\e擖pN&+\|[gDhU.?zFQryU^φD-W}FH(C?na˾'rOX:/3\5YRb8h /S 'j¼Dc P<?'"NczPuV೴3\AaI|9ἱ7Ye[ y׿g$[2Z 쯔I9sHp?I<=\7pDdxҾt?R{ ׄ}anZZz:i^EsyH5w̗pδS'NFmK@w|`}s4m `C1Yoe'nλy_Y(5HW) z] yT]7ї+dݯWFKϣ?J cx|3[{9?o>& gú>!N Η ~Y%P R/y7B}T$y?>2 ;Y]=\ 3#}Nq&o|!>2.ГHu>/Klvt& p\>kQۘs\f gIIH΁]~Or%2l :).G{%X?[<ݖQx ݈Htt87=x7*Gyn,6S}Wy)V7tBcNi 8zꨝuUܧRhi 9::KUK1w헠ߑACiiŻ2!ǟܵyz:]x 5j%_Eqy>X?y"+`rXx,b\ BJe|YSGb6H ]΀ t#+JY?}}Q'[a.cE坡?n<}NxF'%_uŗGpwbjW8|z-[{0o U0Cݣmn]{Mr]OMtSS)sd 7Y"5L.<9q\1Exe!c3}Z' spi^??G*^/HIdtbyͩLRI< Yn+N੸?!g 9J|w<m*e$WIG= q,ugٗ,~|p"[H-F7w[Ǭƀ;C2n7 /9ZƯuut,~(Hd;굲0Sem;$=օ%Ů+I:jOY 8gef u+z8LCbB"[8} {˩zd&E#16qKy0Щ8?]/v PrQ_VM.9J*?WcjPϨ~ouKW6kQi d}ծ#,RbcZ3#*'g׹pVoc^ S (qx]>su#Y Y.j猞 2WcYCCy>ӫn0g[ /&/)._k)߯ԇl\Yyj 9$saEaPKG wJIUI nJZM%)~Ҏw< 3I7r=uosDHSCpҺN0>吠*;Gs2rm[ߏ%0}f''`^QvF8o=K8mQb]!htbvO4| pti)%t,R)n0 |GW}^mYp o. O':D>+<}z s\m>26{=;Jg=`=;X`#Q;|:nb!f΃= uYr0gbP#ȅB]B] zm+̊x1ܮP^fAu )5_\RܫurJեӠkU?=,R豞>N}!O|R*'ҹ0)b%y7䎈p.7I />fP5.A$ h fGc֬nӍqm&_:a&IffuswQ Tp0prig|T6$r3T.8ӷ! PPB7>ѹ^) taf/z~;Z\Pnń9u[SGW"@?CE./gYck:2WZG\?;jrj3OBN E?Yˌ)aggfTE>eM9R \.:¾S]\ad8wˬm%0[Rx9ּFbo1dU9ef&Ξ} 5<sLυz&;Ѕkw]:DwuYB" e£׿k|jvf_< )Q;̱hZ9N)׏6|&&| )uP\z=z(|i>* ';f9Y 6[~o3St~4{<݅#fDŽg+I;J-0W%Duފy&pt+moqu8j}NA3WO:@_Ҹr48ꤡ㐋_( :Xu=Q^-OۘH! ЫPgGGֿǬеyOx1KBz= tc@fSDXׇjO2{K ?:F2j]"%a*qBZ__w0M*TN}{bꕙz~vM0=>6feԤ~F9Pu qr}O>#~ O!EW*cx_{]gǕn%ET4GP׈gpzwXIڐ2Tiozv؏ }P )/MG??OˤGqs7N5_?nxP͗v܆:x{y'teO6HȋU#a+6N%ԩұ vBe`_)ϸ';Ql|x K:}X3G6яo"|m@oS/B]ȴ܁5X{4>rq)YmQ!GK ȇo|VPDӋ`Fa:!S>v(AhuHn8B|HXSUv8G_AQVc̺.E-wG=y czc䝊Zj1VWr W?USD8;wtDc0<i C%8{?l7!4NrnBQѢR֪j4I#Vy5Rj!'5mk۞ymD݃\=G=bǘHQkW" #ӱZzq5D\?_Ôqo"ͯR__Cݫ?cH (R k=ۊ+U(u u8科V{X~RT%R/p;H EO˕2Hdb1NX@ļ1W uVq5Z"g|eMHH,8/Gn}4T.zC!B^W?Դ<*A㪈p0R=zyQ$J$>ɴH)}к*?ꗀoHm2݌O,X%HHsFV$D並t ]FX4|49Y>zzJCz"`v;"޼y${j.Dh9,pۛQtw"E6a6#=魷CkDPo~@BNly)liHR@iǶaw#Uye8=X͈TnaT)DcޖADbI/`_C_M0Fge8QgCmiV5 ^~>Ş0d|MO)Hsdi]a(|UJҭ B6WmO\,B4IlD*N\IɄψP9_|_ xi׭luADյh ȹ/zQRgM[`nFzHM]hRth4@[y9]m硟o!="KI Mw;m!DH>5,B}6I=][Υ&"G)^NHJNQsqF<fe!b4ۈ2|Ͳ9N!vO+H@jqؑniHS ejAZ> %n(y5l14_Iل4yyyXn{d!SՐjEHu1D}(~ ͑?Hwiz9v h2~AV#:D@"a6DHȋRDDX!hoC-1*GZ3ړֻ#ke4Di7pD"Vp&[!]u[kGuT"՞Ko#(Mc`}/IiY_.]' B<"l5;N/I 'sד#zHEDS?#XT|a@j_4oGY]D`ev!⍉jH=(-ZӓJgu$E{+ƐFgӬ "S^Fsw.Z\ Zmd*cDsʅXF倫k| 1"ʘ/?sU~:=dvցE֞z!U7oe"ucn\$M%R9s%i3y1!¾-"-?a݃}!Yǚfx јƧC^"ZH&6]ƨ,/I'Bg3!ւfHaXA{>:sbZ my >sV]vQBA#S>H%w"< |H8Rgz**&^Fę:U"MO5nü&,ވ H wyD)-^DwIϐޝ G߿4ڕ~=_aUM e#@קFwCĿg>;S*~?Et'$(jX~r[%iDͤg ՐGw[o)ܢnH[/.ҜZ񂺽lڌfA{YGFO";~T& E!?wy;"hܿ_-DL=gzxhPv%Fo̹Py~͗c>5y#C̲<ӤJ;ƖL:Z?a"/'O_k-Ojz DŽ}g%;dwo1h*RirArB"v.vDS|,̥!Of"קw!B-TnoB[}wf?#PʦП 6HMT\8r}Rr5_2s#|~!Wje^ˡ #W1=U|~|6P[ KYU捓v9n!u3HCжjlRyzY1=WFKU][Ԃ:R芝97V;W xO+F7BZu[]keHf.""m$A7>B]7~ G [ܯB_R'<[CjudcJ$Tt?xm[dءZrjˆ#":E}Zk{c痱8i5[HiC>. wM/Kϧ^>3v>1<_zw[#MڦH]),U\tL it7X!fkxaM%s\veHmpY{7E?)Eza/jAZ(<6T!=Fk[3VtW̷\4kIM"5[ y8:ts%Ww["||p26r@_kBV$?~>2󯶧 'A4whϩxFh8 )H3:ܷ,f iԈ-=߉,~y E{U& G"M~4_r߬wX D.!MB0n,"ƟfIzUX P}yCehHX4[ @J jwq7HuS[E|,n!画 v_ mܩqHiR孼@Oz@"l|ܞ7Ddy9N@DB޷ I aJODS4ӻ @XӼU!{e]yw/F=?cT E!sHI@]5"03t@uJR#MUGv" ]'vzݘDZ[)yK` ލ4D#sOy#xI1f!L8q"j@ ~%ARF0ȼ:4LJt "zAGj Wj? eDyMZa@_t㡯ޙ"۷Hc|b΁ϱ$::@ M3u4Rx|mX~]LWtWF=@êd,nd"|d1 l2|hb@OA3 /6x!Mֽ"1iG .*r#Id{"֢k׹vHGY!_X>4Na< xPE@  b fD̻Q2*/ RAw!7Q8 EZ]HBg̀4w^}6 cq4|.ギM bj5zi*z BwF΁7IZA>ϯT`G,\yӛfE;gSCo,T韾^HF}_1RB|A'3[)þNM2ށ4\NI@Փ zSΓ yJ-̿#fF)A(?Y+LGD]G;גƚX|Hib.]GHmO'z#oUPy蚉cIa|>qaq~SL4bLO7_k">Gjn/}#rQmQ`QU]TiCZWhFs;zAW/옩Dj=ހ~?X~m"CFaJaGչSKw 1S c܃xn:4nv5w4hocZFG1HUv]}H́36|P("|?c#=ݨd@"A٪K`_=lO{pf%;6@i,w6iG ye1p;?3rix]ϲC%&!¬l"o#;N!5d&[D(!64I6^B vIkaHMytr4I nIi* [Ło"مW/w|sb[F0yKCHt#kGRz_{̼7kJ/:/1;˯e^MLAyo"ȉO }I ˋ)[5!^AȬ}H.@qlkRᵫVZ xq#Q?˧prDur|.D.߈4ˏ<[9!vUYtu@M?;Ҹ̷>Y4z [֌ ߛ.'" vbq݀Mu*RӝJ"ĨRyg 0z>Ö~q&gvoW郙[}H!!"'Rs^ ZʄZܵ,@Ou|~F2NVeCBsnÏH%2r_@_";_& Qߟ3i~afݼlH7H+=|R -#|n?F3CHCGۜ @/ʎ2#.I0"q*SH3#DxCA OUM}O~ 6F=һg{;7H $Jfp'׷0_M-S:{2"5HUѹELjX=.V^$~y~ο%xgKR}.muu'蠗Β x짧>lM{|\?$itƟBnE쥷XliAV?@(oo]|pi\{& b9ӧ;_vVZ1Ғ}t0ThfEV@Άf1a6<0-TCv\|p)B!H=>m:D f#bDw8i&Y~C5;|/qv*rʍ[0^}oo5'~61Pz&;ǔv;R1OLXT6zX۲CS>57x{Ĵ1mgtԭܵ"-UMݰI3ֵl?`NtmL5v|,6IaSxlGLu>Jم+=]o" ܻ%Ws~sOe1Ou=V0%]t&;-1N1`YLOxWrn߫I}t'1%(YaN-,[ ~|S)쏹OOxQbJ(9bW<ﰦ>SUy)ٝ5d%w,$d&D\z)X2{;05:4&jMRO}u܇1~uA,K} LfdN5suC?Sg1Uk-ʘ* 5Ą) ƘBeV'DĤ<)03#աl]2Ty6B1 >ywZpW0L,v*S"Y) 1u-1szk5hUS֑DWQ7T_O\PHLqL=ɏyD󴞓1B^L]&\㜅9tp+r 7ąW~VRBwL^4 q90VHz* io\}&s I[l3Ș265dS_sf0EqLɿ# Jimay4'FQx+}o+? [R>>xvvvuL4 ~GƳ}:0C\b{kYC6[[0%b~fW&o`R/&EK?~κk/m6x.U,PF 2cҒ ;g$ xkv:1]5oH~Kuܫ91amܨ5$ k|G0yOLc vZ;7Οs[[DWRL!n'?UqX wkܯs\f&|R0ٻN.bHW&&HPΥW8#2ãoFG"n{aJl;'qPSJ6HĽ]Sp>nT-V0B)b M+G)S:k_d tKx,T(ɓFLO;)ND,…,ZF; IJ/!3xK)|SDJz-1Ϯ5ҿVFALI-qo؈)cތ)ܔṰN'r]/ML717yr"pw+BHLQ4{{LڵÑ* daWk<8Z &SNbIr|uFL]nirh}lR:0Ff8&Kz1^f0'wKHKaK?>Jmd Npqⓩ\ ;`ݫp ޟx^z$Vz>' /v9ʐU*Uڙ廘:F:Xǁ3ߘ¤G s2+,w LȺS_~P}}cj⍻|x.msz`#-Gz~6 JR0v{Jn:Kxz+-p2Or w֪?NxG`@ W} {tոLJs:møDPHF* !+H,dJT$ E2BmYD,pi޿/dzVa@(;X7ڛŊaםŸP}d>i3Q@Bƽ[[;(6̧Od8]ʻp7ny }EV9 *$)*W"fʚfv$crQX"]d`U߸f#6r{7@'N}C?;P0҃y[G\Nyى$/h[YOwznE=j QIA1tJI}wO|4u0g &ndYh¼JH|@!ɂm=0o^Fߠ=x:0DOq_ܼS~'PjK5}mg90vs.P%)=~hcB=osʽSK;;kud% sœ @=1MaQgL\fp*N[|Fu(*^Apl1]Yg_6h,Z/m䎤p1kbDn{m@tE P:CzyZ)P+k0C2l%<F)O#ls;-;U#PoF.Dsk7wluaIɕ[b[yv@[8uY#T!9d(-~ R4@~GH .VрaM|%sS %п;Vh|ή%5`"Wкlq'ѹ-t`})mԁ&εlSy@gO\?T .9I7xa>< 5rܧv<+0wkvǒ>/큲 Vx!Д3 2Jʹ#@#2rhŽ'Y0AT~`f3_쫧v k]9Iz?Sw&_dUefGZ'][X[SCKյNU[80y^IJӹrm&'I7_;%R6@Z'Y8WCuBtgPoN a+MX?ԃ%%0v&7gI Ԑ#Kob6q ^ysY= @<ڂ`$0O9Crq *cG-ww;vQqɌ`>stOЧiKWQSPTJ6i`1k={ߝ 9OݫLe`;9a&;}XQ?Յ.@%9޸=rJb.;E7  c^lB!F]κ(ڀ*hd˘5d:s'{_vϢ0Zg1t!E܉g#|>`ދ|i(yĶO N>nKq_C5ۜ`Z}j^]0oݥƯ*S +CH9/O?nu P2>mQ(ެ3@Zyy.# OVɬ8tpxo~'70KNl9w x{x'Y$3w(##xjMlʙ//Uh|w9ߎRK/",^}|_azay*yR?T:g3#wCEhnl{M7W#*z5!r&- ̟gSFM,A8!ubL,P/WKms޼c@4 -XôRziP|;؅#z 6NHN_W*#G8,èy˵rDr}mo0摭W%Fwed|' `Š.[T`r~7)cr:ۋ,!bXK}x~!(A2nkkWԑKM+za6KX,{JkNN<ǘ)߻"qȷbCY׈En{扥|M%΁J͟i-dvӁ.BV<1a*N{>9ExsaГm,Kbusş8T8WA8{ ȳ^)̋ʶ_6'~KQZ)SAO5i3)!;. ²rҺ1>9D?yٹvs[wdmYirMoY}@]VsܻTvCϑWM{sUCaCu0!h6Y >cf:c~o+՜4ùjÜ%3WWJ& ܽlfm V9Ų,>k&7/5lCa"Ŕ0oQC4݂%aT]s2tK/]R韁7z7&SW1.~}Puy_Ȩyj}ٰnI^}4˛N=9 ]jfȭuw#g ЙxϢݳV93y`LtQƾ+~'<3W`~h̯/& s<@`I:TYM7C~Q,>0/Ğ{(9/Ϋ9sZ/{߾V;N)hIK(p~:06bNkF{]+ W##xH3b4IYEzYdX[7xJ1lsrJƽp4(h}` M]Ps cFW^?]Ww[0 lyt^ -ia;4_9syѻ_u=c}P {,!FsyDTNZ낾x^NÆ>޺j93_H2rCyR]ϑW뤂Kj?<Skl1V;[5KWDA<<8Us/P;jpUPҬ3Ǒ-Q.D7Â@W̽,J)ڔ9}r)P85998kYd f&8ܽ/2.ԩ&x73̅JLiڗ<&Gv㡈L%rEۢBgh7gdQ'MI3}7*oG`'K*;O;Vu2ֵ%tR=P~q?+Wcz[X/cAkƁfi+@s/ X"9ڏP?V.-%1YHGN(z)#;0fzy3V~}l>gu'&r(=woלlv?VSva&6*+Bp?6'۫fŬ~ekv䏦vV"&Bʵ+[O>7߷<;`޼JS>0_X3B,nN ;9o9ˁ"{{u޵n!*CD6̟6p|9/ܓ[Oe(ވW eudWٍ]+P5+1Kzo Pַ*3@7`soA9#~3טc$ۨst]k_ft\fpyO`泝^`?I(7I_˦&Gmw&&p><3:M?&j:a^ؑ?f&Go@gNԵߟ&o|ۀ_z) (k}-6aNm9GXWh_%,@ 5${@1w5@|eQ/йT`S0r 6sDL}кb޶]W7*̽z ?RZg}*[MS:s _ _gy[p"+@Zcfq*4Nٶu05 D;%@\e ĤC?R,u a9Ԑ-$_ Eٓ~V}4o%F4/Q _qDNE7%)6&"s\?b놞TwE :_Bya&wG@H'ʨ_Rϣ5x6[c=o;Τa@#F[H/ގl'|ji' .|ǵ?VՑ:@n7<-D1V@2|#WTI|]ԧ)@4"/߁.q7Ց7l 'uIyܧgaEf 'UaMG'm9a@\RRH6x]8 $kda|ig I_'}?߱/;d71r>/'Ou`@ϑH9-'I' S0ᵯϛn< 33 Pv풭+#ꛟ@ b@xͮ bpy:o=sbwD4޴9z H͛N6L%@9$դ nےa_guLhkf̐G' m qRyDތ @xcFEx9w\P,S㞟L)BUʳi@dmQ e}z yޯvZ|ZJcXG b,^͗@q!HOo {ߨϯ QڎX$ tG hUApQ $Sc x_I<%@2*;p+ 9ZBz_!<K)nxh cp.;5' q? m8CG1@J7?I@l)) *g#ޮcن;4(_}|3xBY ڧXon. xC?\_[:?s[ySWx>q3߀'"z uRcP^m%~=TMNgN q9RWa 죡z-e [:88*Z ;>AM_P1qT|S ʾk<5` pH0DKIj9":atX*bWEq1 _bNpn۹A1jYĝ'Ȝ@пdը_q-엓X{a>XjZ')Wpjos9 B=SݩVU2H[F[X̵.N\<g D+6U@ ]s*r?<߿mF{ wjTps:V޻uW}xWn5Rrp.z?7sd[̩ m= ?v2 8{Zy?'?un蠞cl['ܪL6)!KཀscT>b ٵU[̹6xI6r >}% ̔|OrUHic['S8&*^z-3Ƿ{Q my> ʅ7v~Q D]H>;w {˻$e8B~@~2ŧ# Q7H.ΏPw3 upNāz.10nw*WQ !)rQ/m(ÚׇIԢJqIךa?+C~#@"/UEnia],v ]4g{D^x $ |JÉi@8g(7 $U4΅z;Cur}h=z|H`v,נ(fü1@lf#7)lI' |c.ޮ\AN>? ȏ85Җ;'Bm8_3y8 FdEGD1YG*?F:2%zr]/# n Ľnf;̒|@ܪK\ &dg+C3x)\Ԫ8'qq!= w<($El'4P/[l@Qr.njs~w {v_5UdЪ\qkp+Qs 5GĜ3qG4lwz @ý@ W{6V?qMA_^iob]C|^Wݽ~&@Lw k|Bq^ or[꡾5ȿ6'|=5N̫nE ~̍DҨ-ԭo$qn:_wkkZK:>UI۱珟7b^fb>}R9lYR }曼v\2a 1ORf笣'ZzoG>XCW0~~Sr _Gw0 yߪkkYm'0{?x(3k'GYN4<7A EMc{e#@Wf tyP:aW=ق hk<aqΚJ!1ح95'.A^vm"ǩ',\Sm֧N%lhf! !Ofh4Mq"bo:_Étԍ˚zJ}oytXW>9ܚs6PPwS/!IBW7]?0=T5v)ï+\QT=m@|π8N8ys5=9{C;W=v3_}Mj!oR]s@& G~IżFv.QҺ@կuc .)'c.k?*$Ӿ_PIe9[ymSő{>uO rlMuAOx(%ւ:h_;ߊ_~d|@!5NɛS/O =Q-ٺ| ,}uH66',` I[Na&S8ra,%S 橏PS>A+3=}6_q֍s@RMg3z: "f;dxyp)n uj?ySs ǡMZa^يJ)m+ [(Q'@֍h4f?6i{qXz9/lz2 UlW< ,s7AF! kߛRbTq.>=]֦]}U3$ +oxoTgaݿooB܍rUWn }f7 = dߖw_Gݒ19䴚}_6 C$i\pLIne:<ɦ-/ q|9U= 1iN[,R+. sƒaR:]̀F?A_厾lr/UqaslJ Ըns* Z$n"֯=Msc#|B^]n3Ҁq+WDUQn'<}q_,ݕTvE(6"⭬-M~@87z[:G/AEr@ܿW 1_+ +v`SZ*~ɉR]:bҘ+i>n>euMuLaMȳ:\tdH;}@6Q=]wN LIa .w6W]ˉȗ7&]>@ߥpG? oR!2~ۆT;jFԑׁ&ՀPp93`E򒺍\LѮ:䒽3KW5h[̢|ۑsg>rݒ͵0P$b>ykAKuS|s} ti{~@wC㇤ |nK\f{D\= yS=6uBK_i}}ֲUy?aJD+d|ƍsgo䐃\:S8jFޜ})%zG3 s Iy~,,,9-uhI LͩQhkf n= 3cn#}@| -m#zqM[w(TU DN3pƜn]~u. 50ŭCuty"rҁ`6mm`2΍]G&N7/0qKxnW8u#&~G6 DCc11ͥ@V~*8MxZeI tkk/L3^".Ϩ6';DK$Idzo)u1qgd>O@H2\Wmr@%]3ߋ|yglDx4lt;f>My#Dp>[{^gwicGK?9b+xz v?A?_a%yuwoyn 0z|\6cϽc/̯rO7\_9I6%rsx9Gp?ŊhU+? 9Yjg66+ŵȝ^}._ =Fz_$8!E=aT+ٙ@tx {DzKC`v/=Wv50ɷ.={z`U2_ }@MJ6f_" or#-`to+hdʀ~U`Lҿif݇oMY| m ہՙ@)C(<*9s0yX: ݀X7{]Tz\-ܩ>Hjn_k?uh<}QFKk $Gu4sϻ]@H1u:dz$6D :{}q;hSWZ-&Ѓ/>Om``xlhWBB0ڎ5,|6z 3%Ȗ0޸[ϧfއ3ځyx;jC㖀7`8|= yϽf.#<%{ 0.l 1[z۵XpA I&enƏ%Нrn.zD _k#t6О[ !-0k4c88^:$W4=:;]ׁHh /J;w뻗o:KV s{@MTtyGw6X/C`osW90or^p&,P/ _X>ܖW =~^JŬ3~Ry|7lar*F dPO/6O9౅lh}"hS@_Xk!nУly~Y3h"W xϼ7r8J>6͏Z6ӋPe欋A10َ}z0xxߢsut]rӞԍcbyz[,xYd+Mg<}ܸv=VFc.2{+Exj5%eId]ѲA{>U/ 1gݰc_ە_gPdc٥j* &Mg³X:@9EEӼBp/Ae%o`:Uqc^j%`?ő4JZ^6`jI@5O}]c@70f'{ϾB]߿ϸZY:--dUSe؏/sԹ46KqRg;m Y@}n'P{7} $a])T6. ņ=Odssq& Ц.;i8ha{tORD>j/j#t  f3\7J huv",poϞA^z=T֎Cl}BQgfq.:g2$qy{4"щQH`r ^of}C;O!jAwXWvk5'€x 9##CQ]gp}gzuV.r%S:t r!ׁX$h=Mh^^#ey稰{&V"}߁s[u6`>o0d2<,uZb/z!`)7TRSV(a)Pz9M^P[`nxh-:Iԋ`(> czr'pၒ+󊂁:$7a9ca-aZk ϊNS0;]zww"e+V(<ҍopiȻE);mc'үtQ'DKSQ3"* M/=a  R؍(v G-fWrS`~QUymD[Aq:e[Y@K3J^!s*q_zSySd#~n.~TQiO<؞u=UWRyVٔJh Lq`0_v S8GvaCj2NGn(xV d_9wWUv/I9 n.^;٬#p×O`v͛<%ӪsZɗ,|̱U7^kqqa &3ku̫"l|W4/7}2xM|UP6B?k=JI:6x,Qc )@K]+sq0) ao{U1g+N4sț'FKuKW\Lύ ,aμz?􅃉SNjpכ%@F.{W[b>`lVz/<`'|Qg{sի^%`)yvco.=9 Z;r ',&MGnzzB$ꗑ/9x7xcڌ9T/7uz}Jkx)06>wHFzUZ30)Mo8a_s?Vǟ>Ա5Q@-h|9߳+A8ɇx)|+v8399XkeRP_;89њ)Οy]t&0^e*I6H!N8M'Va~RF{:܃|L/E9^c1$7~6g}˗`ak82 #Wu[oi),OwWXt0.r]9fnRs~cuug{z5;MˡH3R XZ`\Mv1ᘳR hy(&j_~^HQ}rwnHx^mdEP$L?z~6S})2?u~u7I|5}w'웟M#Ї;t1oG_^ۣO.֕WB{0dnY8y}ПUDxeccO̝KݵB@:CNځyNQČ,h` ߄gpojufǬ/;"/~yoڶyH9wr8Zaco8o4qnGrb j[ BꅯR:`iv`.Qu~.a6Oн^@ oəSwftnO.߃]uk\KX./FV&pnpz:ǞM8ᷭ?s3**Nn=rmY }f;o2oW|ii@v(t?Bn{!:<ӖN Ӕl%,wBFV`]r ,9Yv`UŹw7N?%OOe@5' . l Tn+a8yJW:ם꽖th-zձLMXtL'Lg-lLmJR8ǺpߗC' З?A*_urK+9fD0$*}k' Wn"Dq>I;ˍyV[Z1}թgmő!9_7uZL~b 'SL]ؽ3V+~mfqv}}cxuk'<""bn@Ptk`In ?GG^zңT܇']ykaφ戹3b^tx}B!n{kO[~:e%j֯qFe@}X{*I h}*tD~`]R^eRMrzI!̏;fR_\Ӄ!αH`rcz{?ʽ9pkE{ܨȣ=#+s7]|_cۢ8^(HnFRC,sgsb1<߇@* 4^ܣdVoU} M^Kɞœ6MVH6ùym PnVы2ؼ1Jֵ327.`3R"#.{UΔ4yW8o 8߿wWdlK6c}coR?< apZ;J 5:7B Ц\@{yg;]Q?[ !mGl6ɂ'0 uϼm Zm`찺跛R6@.r3Y@X䅓 c3֗`OHf%0#6MϢߐG\&ۗ9տaN`^x},a$dJB>U>󁧩&s1wh˚j_a `c]EI|8ο`£ૈDnْj8+~ynp1i i }W-ۣ70ziljZ؟_JOԀ5őɍQQ@>\kVHU2g[ 蒊Y#]oUN&"熩`N-1Q5 J,0|wi#߸ZhY @ݵd -T1v<&uбR^(dჹ/LbG O-Fԫ@Z]'PH'?+Ƅq`uX(iz?wj{ EtxE0 _z;SI?"[ fiߋ$ @ lIޡ]%VH~.[lQ` F.ܦ3YC gɡIT޻@1"8)c?mTWR5aFZep r~Ze㸁~k q_$ DlI 6&^Q@}a5m@{4K*sӹ@{sh7|hqUqaާ@]N\c:r o[ ΑO7yF'yҘ\ 5 xIldRIq[ɒ܇NRÇ5*@X+/FHj_/.Q: qC 4{-/ dQݚA@muͣJO|K9ڹw5X5@z1W4o n ];_\bEyZ4֑ S> ?j IL}aҕcm@J z3 $Z`q?v []}Ձ)u(2oܰ6'X)Ü*U9u;ZFz,:ǜQ|1gb@ĕU@'d{GnaW@a+` ˸$'`Vdc|ŊjU—| Kfxziiξ/=l{).k<5`~K1ҳ(0i-6u;E8LE5@_@ۃOxl8?1 fʀ/;=_T~Һ7;@^[|Q{^c#ᕗR Ym8&B_J4Ń@:&5:3C]Wi@kY1kֵ~MȎsoeS1Ȭdy@Ȍ~6Q6i{nQM@>`*/ u7eˎ~R) д2~鉽=@f6^vbHޛM6q4Z]߀| >^Oz x"v"xtp<l93c @\[:tq7, }SˎF)Z,òl-P&YIר7ۯ{/ SZм95"aP,^vf3*}9v7@Zj/1I̾Ds!@J4:b`H5Gɑ'5 #8:YoyGHg݁0Qk9]TTzQ ZS@Ҿ[o+ꅥnZ34MuSpd%L(B}g}u\m ZG/@26ȠfPR_?N\7B_:H /* /ǟg\m8-$g 8Hv01l.O_{}s&F+?!9A5@Uq5qר\ϵ~(~s]t: I}{׾[wI&bkh=P47^8[UO6U6%tQrpεϩp+@cW껎Xۻ~OZ*LFn7v~zHM Yc?rs:$=wQ} C_R92 DQO55@h^uHvvuQǂս.i֮}ޤ^9SH1wn ze-NK ,(M'bp6?_3nazZݵ=i$UF5t3s0c?@|-}s?"fyYٸ_OHy΍ .0sM}hq@Wė~{);="& U?(n¹(W sޏ*Oìï"@|/uB*|rW8ޑE?ɼ(|#߆s"* |:'ճW![K&k_^'b©d<饉s0'WH ;khyV:^tk˃?EYd~p{ V\~Ⱥ فtK8&{?jow<~wQ6E޿N 窟1K̴͸w4ݮ@mwqSsؼ`Dp~x٭5&G"R]ab{KÃ5ku!Bl{ϭXd%>E #ڷ7OkELYc@p:v%Temo6jى$S Bn IPe:fUoWԗ1}'k ~f$dO#6LK5x7r nު~rM> Q&+,P33s^I!z[ +g9ΖR X8JOQE9}/e@^&q?xoiG }s'@}JQs}aeԿu@>,D f[tuP?wrs~L"C 9hg1Е`ߊv2[ 1 <1A)y 8p}>tỵ'( ЧTۣh>:>YM@ Y$#Pw:F\"aM i}Wr{L4_EVE?ؤ6g_.^ 2Bk9(3 昿f5vlOHāt- +vo¦'X'Eyviʆ1ݾ}O>\,8Jbl#D0KO"?}s֬Fn5 Z ou# ̖>BA[v$Ν֥?\2<^N_8l4Z`_܃W'E=0[Mr=P*/OodAY#LxRqNNtr/c2ƾmr\j=6}?^9N,x9ؾ/-[S9@\]y& _|uv@bk(/jrޯ١!uj5g0f .ہZ27[\A&9f: DV[.8!#𿟗x2&*9XJt"38v&l%N Ü6%o6N*U)y]l6d`_ϗD# F}!1?г]зe'a7itqܒ.gw9y|v{=캉IS 7̱ 7yLlby#_@$"wp~UM9Ѻ< f)/Tfpk^ ZUԛ "ᜟJk(kQsq?o9#|8:vx0G[nr:u|[Its5=+/#嚎 D5!E@Zf|H Q@:Dݯ{*Ľ>^#G1/-.|ـ *Ce دm*a?"tra?L$ˌQ8muM9/=8*v 2dDP,}%( )$PE ?rm{g Og?"Ὄ頮 7ƼqxJr5 uKat#s\פR˳A8m`O 9>ֿu^ϋ5@>%9lᘧ0껻酗دk~ܐꓤ_-c0^y|UeM<UrY]GY G}WOHr"}G%PVDcii ~@v?̡QlÊ}{!m#@Pq@2_Y+?V@$X{Gd0no<ڶ ;AT}2u壎JCRmj}3w )׎s;lbq* "=Zi\a d1Tϭ^M0@яIF!Q^x҂mq1̟"ENC}7[ ^9vÕ6 z̨6<`m|O^ mt 9\t1̧Bjb!'b_K(&ϙ9ȱ)7\w|V3Ejt` ugv4#L: g-~py/-ģ$Ӓ[Q 䵢>E]z~(k[ jJF]B l%Ao| @>.S}/*ȝ7_Jv\ QE1;:l$IhC{Ta: 9 ycG_=]bDg. WF3\_qXFڮ=0ۓ~yS6||m+r wa>wl}@ٴAyG!V*GAwjYƞ?[zīC;=6Y1,d#^k,8mҗR $IG]2;)K3̽,ԉt~V˵+=?ǜTJ?D`J}]@rQۚS9P˼z@")px٩;O`s.Jz7V4 \ÜgXyiBw.qlb랣2g3DnTL}s5y [ے"~xNĕV83S$NxgZk1-Sx?VKa“@xR{9q(;~%x>|NHn瑗ߘ.lLl[]נOQrrmBz̭漖tkmQwUb`7pNgz;1O>f,~/u\U])Ɲ4Arn)>׾Hn~)\+)2@ܺu/nd<Rv4~P9IZe D]݈,x#w_3%xS@fn-ۭqW{W ;J4xF,mD lq\yw23}SSyt弙Fs{w~<Ny:KZbR<08yLp] E ʓ0 GO+i`Zn;t^Yp$(X~s<夽h\aaƕ`4Tu X_l-*M3dX wzGY WXZ7z 0L] }-;2SkZ?W _'Z@b(Zhg )6h-f:`ls9bc >ץ嚓JaY}_E@~( 2̟xEpY` j?ʁŭ}@;6# ^^Ze=EaXJœ4N~UxKӷŜEB;2,gpkrа"Ah~wElzEم|v +owPz5ppC1`ͭߠһ\)X^ h)fNBJH., #0rS4c$$4-`U |ĺ8L,=߰vZ6/[Wiϕ\‚yy ׊qNZ={U'maAjڎ\OeucE2ܨ${-Em$ar6K`e )+^1@/Vڲmg|wC>\`)fqE>3~\ -h,:=^ɯ;@kp 5X[#hWk֋ Ud]D{sXT]wυW"DŽXֲam`i%xLM_Xv:?&6"٦`mr7,nX_#ε꾫B`Ӕ@'_mu2ɞ[`SԘ,ջuNG=APF`^N5GWs9bk*sy+&*٦3l=b:':)*2x@6r?,>^yt˭FօٯLmy[ W%y, > 'y@nWjDV@=}"|Ȇ͕+jU_2ax0?`6$*K @Wl:Ja!H@F=;$|ĸvʬ}ݻmlZЈ UŔOܑW2M\|Ox /ܓǷ-_'ޙj=tb/0J7k68LlG00#4_rQ Z|c:e͏>q^e Vn[B2S6nFsfc eVPC3(ۄb>mypјf} |ys_n,}k/ UٱwO%Gf&'uNEBwlIqk,0w{]!mzz a&uǞ2X F;f0=}J?cLvn_h>hӢs‚“0hpF.PZ+!:^e/kjn,0~ ;tsqo%;̐_Q> [;97oꖁKVw"`rhL+u?0dT-ˆ$0v]`z{o&0Қvq3Xiccp9F.{Ǫb| Ƨ-}jޱpag2yCgK`7=}, 9X3EJk\37q2fX =\ޭ-o4]d#~5, ?hB/*WnOD ط3حRc:Fu 㭎E@3U1[^7Lu@kS y65`g$!,TgJZ}Y ĻCmV4aQýo'6TNX/+1d ac^sޕͅx0+vu#>e{de,\; Ň?WbX&0 sqߚ>V X[v4(aa`&~sKRCGUIXtT!;8nPZdž'nKc覼0O`8 ¿=m*OO[4GX XFXEV5eX81+~h{o>FO0w?ZzZ^.O3שoh1hk 9qwb}[`+CX4<߈ ?]4"d}ݱ>F a`j~7%Q$*%%h"0MןY+T K9=%&դ% [wylC!HXW{s?G.t@H\Fm9ajj%4/o}OF !mvr`sv<܃Vg<~IKBI9iO\z7X3Tܞq%ώBLj8g}Nצ⋍70 0wk>Ahֺ,XstF77GMn?.+1ϤEnޑ ?1#p%7*Rlڵ_'j7AK~hx>KKM8=>ADFqa5t*G#ڂ:!\p;}:*u͏rK7Tcf- 2MOEL3*5Y L`~j;#G.'ru: kA fԫ٭J)b],h>M@I NX_Ў+i(""5|{97(]VoQ5=tV`i6Kk_}A֑N\\_Q@ѵL@l/.B1)+_3vz*6Phm'> 'b =TkĊ0OnO29 =ګ5l[%IP<0+k?;o YG]vh]5R|n`+\q߶"XY_xwm+,<9~L='a 4BJ"-e#_ko>,?irʰ0ey h{ڀQlMh`²5Od ׋y/J_`G z}(,r]1ɠq1崒(45>o}鿟Ӭޗ_ycU{߆\y@ocVW\&y[f䩚7u0zox d¢V%O`il)iyp9$I@]yPJrupLznK}ɮyBSlV?9ܝ>1@Em뗪Saqյ֌ڷb7:9yaV0v&9q,ͿSpXh mS+4z"]G˵sL_rϘ!Os.)N0.Md !PJ=7tpm )|]:pޙ2`IqgiG`^D,}Rgw?״vy3<O|=!r+ OS;r}~O%p3@yʄQ+!Y^g4v0^~:`|+ 0O[c 2/r=Q/&|˰D.}Zuoo<><0**L 5;3or<5_u#D'mPgw46sy!k#k7ޚqI4gWtP/B0'j={ 'kj9_" <K}:#Ÿ^';qW-觾ĭMRMʦO%j:Q+*7{*+/',4RYAC JzeXl,7ؘ .YX>up$$7= STF`Mk w 54Ǘ3<0Nq-g+o7-\}T#(f6 W6uIIFD)b٭ XpLޱ蟪x[ZgaZ`]4({;=zpZ e!^ZGoj~RL}[rG ;p7BLSہ+t,`i>s0Xd* tU W5s/ef.ԍ[\75ފ(;ȄOf1I7` oz$o0\4ARjXKNJ?b]iJ`qOsYo:Ѝ`Y@~yIk[q`辯<[f'aA!Ǚ|耺K^2w\}E~&/9y:#[0l4b={egJ]o[ө KEG;1\1I' :~9K_Ǫt<~oAH.Ctx40HΥ=N' Y`aנ̧lcͅ`]I\:HquC`7ު*yX¹ k,{8{NzKeNW` 5M:m$`_9hJnr z\pa> &uW{<0W]*Ǽ'eYP|MZz@Sw0]6/)_ [/×kub!yx<0+cC_,q %G n h!ڊ^J(_<^X\9^oaK>s :e䲽i[9,H.|iˣ>#o -K?`ycS4  6kXƙs0S,+I'>}? Xn,alw[vg"{j-s>r zӏ,g`*}ި>:"`_!>u '-7M&#W=_AN&lLRFÝ|qX<}Yؿ-T@VW4i,ڋbq_[Ɇ5X\cܹ ?od[",q !uLFc?Km/~Ey `)y BUG]Sޢ*уG'x~0&J3Vۉ@_(xjU|Gq~&^|CXEǂ;ApSg _oS`x]ݙȻ篟;Lm!5aa_m?Q“?4?;6 9&EJ E2 ʈ((*%Q-e"ݿJJ+0W㺾W wj;AM%+@Q՘?zUc3v̮xyrǶʰ}fu7i.fLlL+t{B#O#û̾rډo0}o0;\pk!Lb_A+j{#ˑ^g[竖`#h sBwpVV|kJԓGGw0{;y.༛h*fG]_ 6+s^QhF}J_27̕f{Ea a v NPAHXj,3r2/+RIR/xo˂L=/ŸvUmϣOڃqaNy,`Z5 ҴSuW}`Nh[gnsolt:rqWe0se=OO,r̆/Ή+vx'&Jп>t(AvV_`@PLa`OVLpdr w)sQ 񚬷-fTeҍ幑 ҿ!x'2, aSV9uuښ"['A`/:DP*ֶͣd=1N?X;!1Mӫ5 ғ'+7'x!vrJ@ֳ`VN>0cAV];|e:&]_L KM$ %߭'s"HOGu"_JߧZ;m|RdGݚlZ0b/:'$Y ݥu)7Sp h!ȝާ dl_ߤ_߹Iirs"A*!/w$pu^$iF"o)O\Iś Z!u.wV<ףtUl%_9;.v^+XAs6p*q~)ǐ&͑"x8* 5ϋfG+O̼= ȱC? ?;F3 ޕg>?g䥬~+yo ; JsuCrսKJ)=R+9Y< 6 mk2  W"E[<321-ŕ|ω:"V}= *~ s|3ǝ|^juR >?ߗ8dUCFcyJo/Fw>A9mw()}ox&I~i /AQ*+!>V oF{ȧRR=GZ: OmeKn&>/.A_W @,69\Ǽu-3A"6o[$@=}G[FA+A.Πn!8*U|Aݻڿ* }8B zF"H]IN|ǣ^ŤF|\ ?}:{ έ鼜oi5"|ʓ%#'{ :CxNu2藇zHPo~~><}l47epkq)Kuz'X1AIѴ7v n8B6v<?EWXCg=4Cڰƅ ԇ+r͸'/*lp~hL/Q3l?Ul}AjRPC|Dv7UW&xy~5- j~ek8sأ'kW-%;cc%;*alS42%ɚkA=FJeVW x6jב ~OEpv~]-Z{aB|Gj[] Y^BٜK*AۨAv;GbEt#GJ'寺^~s _ԝ$(irϻ|+ȇʿR)I䆶,Diw'r~O"ȼoC)suEV|^vAm[= A)?lSqN'$kw25/P׵ZBw&:o!\$(ś5qL" [˳z#^GJ}mؑNA . 9y{A%̅t: C7m0"(NMA*sq r"y1?o{e%jM;Y{Prk0Eik7C 7A8+=L o"Hd\3&HJ ^W[dY^BaeaclbNA>vH U(| #HmbRo-{tSޤ1ӷ f^*r93 t8'!+zvM3n0O ow|rm&e߭u!j.{&Zsڻo!VSG˓lw?~tN4A+S#x| gc]R}ң08HIP|t'(ˣ\S ʤvn 3%wK6|}iqEqxrSa߹LEXZ+1 eu~!M=#x} ļp%o$#AkX`|G~?EWǵ G-'>?#&]_4C[vD#vU%n\X쵻Gi&!Vo!Hft 6λ/|G:IF ɪʾȩM%G(u< >߁ݻY='z9\XN"\FTIŨs?Ys"x_մFۛrӢA|u؈uϻoʿ 7}jW_*?_"x1_eO +c5y۬]2K޲gs ŠC݂90jk;Ug௾@s:[y~#(]߭"׵ p!qiAX/,j~A$,xk1tGmÓ˄ k[tO]$˭%r˿tA{HP GjhG}BO!vw uTJ=gÝ*ϓޖ۫ǚ'*.*qTA!g;AYuVuWܝ}X1gǰu.޽@k5OWԟo%(#^<ka omv>j`` g~8'ț{wtЊ%xo:~->9"n )5in$^%up!4rjFDU(}'i/"{#Ը[}_^+]G%>( oLJy AHSF5i^?$r,{؈@AI}9A~(y:`iqwH8}IrsM\a\'s&zҔɻ0gr~~eKY%w~ Q'{ԅYp}KF7c~üQJ/iaEőcÖ喝V̷c6Vx:`AQ3+dU&AI`e<@9fLweFW~j8|{zWqoKD}b'?hs4ļA|ГrZvN :>Zu;CWpN)ݺ-N]]HHA?y lBtg #ԅj0OoL ^=}Kj'H[)p&HS; yC*'~ܹ\w^u[e벮i@A!;ȳ ?:i`?/-'ȷ*7[{=f##"F(A~6UCkr?# gͩf/PV6ڂ%|3yTIZ͢Am;ΎJWg\Rٲ6f{f%5+= 3+ rbS)GzT!=FѤq~u׊"njch+wx.AeQd6sZ v'ي;C rSB^ٲ4 gP2 c=?"H}_gvaް}]rYE"Aֻly W 4@d_ח$El`2R+},.BRiĂӘd̖H/¸Zz}cZA2}>^ywSiWi"zԑ\#gn=E,lCuو9]!xA><7f*Truѻ4ȑg{dʭ=*o C_A=vSN[/yzr3nxb@Q |BgW!?&m~mf)=W9*[>-{u/"QKȁٲ*AB]n|%HPf\]jVߖ|SB@/XUChsHזٱ G'-L-cD GY&a'AkȻnUEĎ]y^a}./jyc.A1D43KP$:icܱo^:Az(fuQ^{,P!4b#`XH(Ŀcn&xE%8C6jy1ׯֶqE ~Gk}*S89s4yF ]t~ 'ܷ+K3K J-߉'xncf~J|mOoۻU&f/)*[pq++*D[ PJ|b|؏kw#*-fqɵXX|*oaN[E#5ipCA>hT`CPs'xu9 -EP=ͳEBe MbN\'+4 Poyqr~fܬo7*0q~bNP HFO[1!i~73o5 R #5L (Ƨ[W sB :A"Fc-ATs+8}_> &ǐ+%q=ňCK"e*z1T1#-|uVՁ9t'bke>A6W84{_!U/;" 38tϕ\#//ġU%xHn΍&EBk&rl;{yԋgP?^ h#ȳ&n~!CTfwgo~=F KM%HKNEƽn'֬s$7_<|\ ZBj\&˩;(d&~ -t[,!u]. x`nxaz08<5y\A^{aRW̍Dȿ&[PQAZ;,!*` NWsfkW6>OCE*F/F ;zG|5n#_T6v[e)EI= JaU#.3vK"Ȯ %~Z^&^9}7gN݂mI 15ӛ}< ל@&~:u@L'(Nj5#/M}~-;>:,{_QSiS'⟛ȁuԇOGgF#_y @UlBB)ioޏNwg{ a]Zv7}prׇO]#xv'pO* o-JE̳s<'Sd~)A,w6B^sՋW-?={uI1'4uSU>i m`8ϭ 8YҒ^S en#|~mkB%- w?:&އ`Ju6 qUڍk[) _cNxFhadto|,KEGq!(7*%Y<Ӕ1X΁eВ{k0Jhz 귛 Tz~."qN:XOfwFE乩F_DNm#ȯZtx>?t}ºvE9r9*}\.Ԡ73?};>k`c7m|0"euYŬ,p{ eF`:{95-P$.\ X~\xXKկ [+8q{fކ?e&õ%CSm Zzt9eXVN:x?-n\6e{tcipX/stDNPS`V*,e¸Xلg 9ׁC(>G|Q~ )K5طun:֪rq2>gh#2Zjctd)0^L _kks>[`NґnS >`]Zd$t ?&wr1b`=@[^?o.V9-W9]/m}2u`)Z{%js- v)3iyoUO=z <7ysx)n7'zlQ]0POu:^ MW[Y~#o 0C/)a'`+H? X#*+ƻ{+bF"Rk=g` O_? Fj8/-Sd`]y/= Xݯm̼ET9BܢU#Zbs0t5IXG~f.>6w{^,vL '~Y}TRSVnV}vSj9?sfx0|8[liRlTvЌF>0зLm?W }LNV :W/Q<㻛Łt}:̅]r=g&X_L-mrgsrq:oAr::쬔*ЛXO׫>:dg[F/q<`gTصBb5i(\.> ,׮Gty. сQn(*_}eRcd&Nb?}svs s`77 vGy#es`YݸNb$C-UN ff Ӂ&D)GV:쟻\ibr_.>2yMtk-w\[Us,k=Kos?S g9 b`Nv@ʪf3`u㧇:1mC3a#s xzǀo5k`_|ג =7 NK=vإ' O7^s~~)0s.)ͩ?sp0ζ;=:rg{ie=إ>w K`2vܕ O !%GMLcOjpu/pN($ei2Xo}x^((N px]Xkpίwgfa]x-q?^6kj@F=`O޲M UGkC6pr֡|I YtYGov?V̸s <طZ [R`ɊosJ[JX꺥o uQx wS+SCi> g,fhq.<1+U}'lË]W0>$V  ;tʚߏ. $ =}VUq8A^{$l0}q m9잗8N=+YfsCeg m|睒s 0}o4DS_c]mQhՅ.KɌ>VE#OϹPğ,~1 G?ww_ZugnY]2簔 `}xQG..\#{Q7z> ȣxz0Sv~Iԅ}r?gƉz`_vB]%u?ruSU)@}m^U2C6( JJ`v Kz]_'^'{}r)`UxUN}OQ?Zn~$9_ CXqmu7rYg6ti`\=~| 0]m:oA')'cܣZJy*VK[U7h4ҍzsI K`tДk_=מ؅Bn Y~r9spըl'r {!37f[N~>pa`||p>NXIBK/i"eұ3WX E[j\z#;1YLU&`ǥ7{6ׄ͋Ϊ)!ׁK`rfX*lmE=߂KC8n..c#R{ +ǚQ;|ӽ7Xl*5.`SO=\csg;H^`ŷ?*}~f#[֭W@jȟM9Q ?bW}h5t J6Ks>k'3ȁNXJ9k#UeclCܗY)^S]`2߂_}K G3k`GS "dj {=~ÔnoFJyu4hA}{]Ƴh?' KLG _!0cԺMM޲j2W bVt`xs:~ڇҟyvtu!Mwgs~\c-LXv7/>!yS=ӺxM38Gg.744B;xa7?P}a[0M0VË#l7Ѹ{XJg[Kv1_A`%ݬ_ X|[6B.4q7??gzFs^ Xү P O*qN҅n{ݏ&*Q,5Iuz-:Ya=yKn_~`[VE^M<(Կ}3sgR#Jrq_rZWs0W|.y &,{iP:]c'MB^EvwUSm0Y4D>{ a p ;F>E-sŊf=ZEsj=q_9ψqy{mY`>oY]3Q0csvKo(n`?5gK?;| m tH_: 4!>5BsY>^c#-ت ԟŏywI!|Nj}yqewHJ;3IxeM8!7LgZ,sƆ1uNL?ҡD`~Wؿ"U^t;>Q2wax6YGIX y\>x+JT~|>z uJv?-Z'(0tU}Ri?1oggPObABTEGQ ˬW^q6f+W >?ʿ/d գo$+7MW?`X r1ټ r TӦ h83~/|g1`{9 ٶ}F0r9G;`IIƠ/P_/lM$lFs* Om>`]WS/޸;Oz^XQyouAJ_m#~/*k5B[鴭gX(bq`?#vuì8Sx30mKCq\ץ;p~z܍y_8 bԯ Rg mi_[-_vn`ɳBqkg<_K9JuP>M}OG#MF/k Hbv}1.&`~SqM}v?8Yz}~_I_Z6( k+;9B6NbVA!akSx_쿸qQ0wM)I, Ok3;M^\Xq 'EZ9,?L`>܂ϹɰLŖs?K oKBbm,yؼI]~6t|&|^h?u)CRYl>u ?_M S1u_`e][!OgosDn8fwJ:Kwc?RGrO L?a'+?qcjU鈘c+ HzuF֋]}[a*^qXؿkf0Wb.T[+՟~$9!U.'Sb_6+ ~q96&+jIQnsjDTrQ%<0;NF]ϸI q3?m~u'hxl4%X1S1vcNpfzpD<>Zs/EÓ.P6gfKaO K<0r >Dž]K1G0Rύm;1ocTZrl͇%G-TFB9Km}j?L͟VL>5r^~#l;ԯEy ]fG"xǢ~1/f9zy5P'~F- SsC߸}m}. ,-?w_T;3Wݏc]NA92~e5~I`>~"8Z_+!깰яwmCQqc|pŏPy7yNi;&G_ }<3qC܆95suU,렣r|0PESpeO`^WH}JܳO=a0n)pn XE;ܑQ̐򶖍Cn~SQu5nlI=Xw8e`>y\@ٗO}m ؍VdQCzWs~U5Õm\ o!֣opXwLی}076 CU\;#o\ywp@`&z}/8_TfoaOob[зx20Vt(J븾s] &`R|(O`K>ڇ sorw`䛟L{H,X8OAʍ;GA}|2PAߠ՗Ln#&2\]W~S6`;/+xm`a׀|}3pP?kEߋM8)OGN"ʸvZޏWs}6ex O$=S~{T, e ܩ8AO~kv^rk&hTùӛ) Pb \l'g\z ݙ\CE8~b`ꎟ~ ])/FH(زGYEQy6sG>&Z"c#0ަXݻ w:IXpS1-s =d~ZG'}3Bi߀z,FaӆJ|gHuzRc~os跙.,8oܗg`?>fvc Ս:p?O.t`NښVpe87L>ڡ<\~,ū-nkL C.=Nż,[U7ÍG16itG^-պ? tW;,\CkyVN=Z:ȿ}~Dii,`z{%`@=]eαj\ᓡa`>|vWuisrՠi\+D/Z1x-1؉}tD\h|=O'ESz24\LwLp$njo#G;󀚃w[;MA~S׬&5QGM$%&~n wTVYyۍOX@gNމr~ G8'!`dsrO/u~yi`]`)Ž%5Äq^/YnVp{W$, ט&YK\#SW: O>t0Gd2kk#h,nhN\_Ioup.No6'+l o ;sp\>/7·.yj_#WF|ANji߷x|$ɜA3I4dmipɩC<}aٸˊq?VW{] 햣lLjq̣;x05o؁%#iV=*ng>K', GLB 0olĬȽʩ{VoF2fwGm wi݂ˎmF?0'@f5ƼA ]dZ|0)w'.Z99Y9% MI?;|Mj|?nzD]0yX5@ikc,vjm=R`O_ ,c3X8v3;,qO n2R[c/UI)ڼ}XkE~[}@yrY+`_5@~zPAȖ@xg 1]ݸOokg(T3"P*ŰNJmdczpbU<]<3Em!W5p y#ZY^#/5G~x( ``<il9k=cU rYqtGEEolʞ:3W;)8W^ x)8ߐ`xS.,}8WSyMIxUU|8hpu&c>?`՗TKl[7i#99*l\=e,!]X7nzwF +Y9.raIUl$8f?g؝ǫۭ}~GE!IlLĹdi.+Wg9mε V]u"0O.?ԙ}iM4H`rM[`.15wgY /a:bMдrʋ0&w&]0,]iaڥw +W0=rppW]<0ٛ"{B:zU)'azmQgӌ"pvk~ifQwM]$)~nhpwj-գsx:p|oܳQ5d.O!=P\#qLWh.e5v=cgXO2ç>C>%UD~)?EϺ&;yY@`10|}Zw^G% 8.xOm@NYpFtP' 3m o3p|g=~iqp]zOD2>@}DW2B}=~K"\#_.{[[77jIv&֭z"nv-٣.]ɋ(} "[QuCguolOͅ8Ⱥr ་9JДُ.T3و{RJϡS0s2 8wXb>nP8>nY|sr/-W-П%`Ƌf/o>2-[+tߝbB'a}l`6rqOjh8ob{sc7Uݺ|2+4I<ؚ|c0} %Enj=^L:?9aJƨcg븉tqԗGﮂl peJp%r#?|͆p7věG+=lOiۮ'u] X;Wiߋ2m}0L3S 0OH\KR <~`WlaG9ERz`3ISX %}xɃ-.W,9vec "6 i7lze⭵A/3,>\ܗ f^=TN4>GO(|M#)%sYwH.~b\X@4z8pLhs/ߌc>L3j4";9Ԑs;d 뽆2B?kpN[t?OGy7օR 8M^0IoT~#57!gρgP\![{s.@>F;1|6GTZs3-sw(LZiFvw9B1C-KTp~_o#Gˌ4P"þ/ҭ|g5W+~)ص:e?lhTwc0mJg,{A, =8nlԳ<j~|L(0SmZܕY߻nNma`!9G]}H'ur[p=~0iE߰ؗ)U_DW!^OȧTYÌMLﺉ\dMd&b@0pK0,ݚ(?7bY\!Y3? ӂj4ם0֠OO1@] Ɯ*myc&v&xD=Tp0vVlvnu`Lʫ,槺+4IQc7& oiE`蠣 p l7L5>+38pN<QOp)i΍p0OW!gn`FGxq0)>lQWw-M `n]s,9~6*]-!#'6;%߾C\uo;uwnt'0tW慁{a63ŽX+㗓E=_v_s,ԧ0|ҩ=rN#'>9h{|m'Yzf+pX9:t=J7^{J.(B|@jȉεȇIg^ l/W~:({+tYKC?"ok, ΏE;p.:97|e|3iQϬ\̒gXGf `eE<9 0+lڀ5Yq7KW0#wƄ~IDicNQ {B6/y~ՙ˾tgkL=쮔[H >2%ܥ`:'c8WnƃC֊FGbI`yRaU0R0Nf挕$fZ͵5j+ru0'0\;q}x߻C?a欺ˣwf#31rQwjG{"Ͻ^VuHc ϿBT-g!ǻ[Ew0=>洀@Rnph925rr{Piؽd8+Cߣf߉:?R'}m6%^ޟ{3ܴ>9F5%^nzxXo]?fؗt؉!͔ <"tq<̬=:sUySN& ٴ8{[߮6ׇҋ]WlZ!Nm7̏WǀUm&{NjߍX<׏b38.8aI7~\hNGy z X-/<7;4jּf%ԄhzE+eNf0sk&<8|x>ިؕSEXB P_DMfC~;[mԏVVi+9NzW Lo1c\>=a,-%\+44#Y.`g$.Nx|qmbRyX%|jY-۵9g/LkЖ3'^g}-#*sL|&?ƅKs9"}SE.\|i"X#O]rZ3K1(\zd0]GU^Ԫm}qm\f- 8ܼlBl|i9m+5x31LOҗ[8=+aZǢϯ8"7i .c7.yIQh1RXf?#h}pN1?`ao&`] J4Nl5/MwT W_[l?Krя=j5l]3o%[`:v>iZƌ]Ν.QF_Gu-pԴLՂi >%\`GKݷu~뽒ϧ`:Ig  Y {sٖ'_su+yzO+G0mrpW䢂e՘3 7?N!OfkBa '_O߀iKAfP* Y/KaQwA=fԅ4tu=K4G3X:8 ֮GD9kzK7oɧtmB^$uQ bs.:Cr8-K0'yB<ӿ(^AUq-U/w:}?rnm]o;=X+w 2iE=;QlcR;ˑ1X7aaLmq) {.?/#/E3-iE⺷Ϫl.E̦/Anl8\{(>2sr_Ƈǟϱ|9[zu1Owkb.]pgs[c9Y S?c#Uy[ m\ 8\i3qVOk~[ aÚQ :tf܉x_0Ǿ VYİC`k1{ WV~ǘ.Yxد/P %KϚ9$|Aqx?XIwDy8o|AoPw2]K[7ĊGUUAe%K>g.HEéfjޯȺpq_[0crj"L{g%4>~w? <5)*xM9G+v.ڃ0=0r1ޅ>=܇ٟcJCYU[#*:FF?M78Pr8kǐ; ;3`ƵG~8/:~)QnJe`zؖqJd6-/ԁ&J" s,xazuDtM\(\ͥ 4G!@q;!o[aūIU ,+]wkh;iʖ\kGESH0ZSa*r }.KQx_jn6t;^lR \6OaÏ_K9l6X_|=ֵ8/~b^3Sy/1/?[^()yg3gm y5@\o;Mf;$<\MZڙK:yg#BEsw`zM(iujx/Cb>䗑 U~U/GW&/:F=;:#ґ d6dR:pW8͠ac.)cYSŇF- Zajq1L}gv8UcҪgE P1OWy=:_1jB_ߎ}Zb rNKs:J3oK<Ĺc5ܓ=6bxS7n7Zw z-,b]}G%aȝ~87,8+ug`٧6.g3L ܮY{B"+WMvE635:xjڥGF3I^tHX QQpa^?|uuO69ω)1`\=Ү^[ ,yZa^ ',?h5֥U^4&'ΑЦ4>A8_לE%Mc/?a>Z[m͌ mwjheze a{`+3 vckߨoStNsĽ>T*,¹ui98SU=`GiTSdr$I8ն`KdWb5Hv;2$~OTcg8mz,rG r8q{o?EO+߄iMI.p~k-=ⲑzVXJ /g\<,K^H}AN ƀ}i 6fbzn6ڲ u<)URr]JaKۗH4Q^p}s;<7 79>OXK M0~}cz#YSKY|N:!sd`ϔkL/)?9 egح\OŖ`F9/ ]Ru@ X~g%{&kBvQqۉuR0]0C$NF&LZ{༉t5SăAϪ@|5N'׏Zݢ3hwf9w˂:&G -k _y,S3߲=!rC/qh^sgl~@;rXK hrOEU]d}ДC+d1rC@w/r ]k 7=/~V.h/ױ֑@?&7"Lj vM`VBkeVc9}2.G_4yB2w㙭i MoQ;IZdCή׍@;ıR0}~s:1S?+ڱ=bgڿN8S*N"̀"2nV-30-O=ȇO_Uq{*hFL# ܻG2vK]@??IVz /<5)-j~9=At(O􉻹@L!/S؇ _@d0J8r\q(j'@?bVP@;z;_; hvAo]Gu=Pی멾: Ѧq;Cfvg $_ (-~ԱL7o oCܮS|t1x{-|mh2uo^ڲkGll?mBI7ܫm#ohȸt%Aoz,U[OwΎzx[@?ob|]ۚ90H3K۝QSHe@7y㺅 vRp 0Z"mt,ЗoT=J`Ӏֶv?+V+'!e`pg7mu{I؍koP嶺r\Rvrn|&n`i9PqDЉUnsuP\*)`+ihg\׍}E'+dȋֺ~sj'B/.;E⾻˔V$.'Tø} _:N۞Ɗ@pϊ?.Z,+PFR`. Wb6xwigRO|ѵmasohoKCj+:Rݝ@}YX!{ֶSd+_KSvsH xNCu2ljrGx0ϥ6\Sг_M;3I$q%X=Q͛q"4]ĈM:KxVu4c\x#9.Ju,aOj8ܿ;c& q?v3pomb!cN0t.@|aS67n\~+K"nԟ}Ax:ٸg{}f"-!UQyQ&P?/<69o(xv ݒ,8nIDX@ KwhlBב0|hb~@?񾱢Q%~_r>@4|~dig 911}cNökaRe? }geUh4bĺߙЫ2ԢAr[[@;N7f&cY"KEծ~jePq69mgm^`kьkzy!ηci A@;P^՗ -F R @QVi|}Rޟzg2J Ƶt\WI_&EJU%[glڳYB07pI@#?GAC}뗠̘,[Yпv=h)k<,y4~P2▃+o%u3. m|M#qXś]Pk4gcKN YA[=3o,%ۣ&,p9]gIq6O 9Zn웩N&o؋!="~8 o- "WbĬ=SZjV2eGOc<abc[ عh|e[ꛇ Xg=Y;?rv Lɦu6nP(%(y߱r*l`@:H{$Pٓy?s;N iGP[xLVn8_j]on2=T N= %a{ns#+ZGK8jI.RC|-rt@-whz$[#Obm}^-p#So.6^ CsQ?ڑ@ɬOS%ئu5VScMYy]Z>Z/U.mֽB!/U /W|B>@zec 0'NRoɌ&7,%䑵 T<@zE6KUO[gcC[24{)8][\ed(@}ne,#>˗snl?MnЄdCR7aoFa|/"ڢԨ9@o]o+^Vuyw̩ Ow~bz_gk/Oorbψ"]QϻuƧȵ)Fg>͵+p>c=콄|л@}$v:n&g>#myr`hDH9@=2MA-@c9ގ~՘9dP 9bK9T dHy"bZ]D?9IoƩ֟W*eG@+ΞJF|)]t?qR.AyNUg=vy@06G_ IBw:Mk BɨKECW굻 rq)Jśs/G>y;芇q用ڀ酋_9@Zk!x1$ ܑZ%%ږY\"0ܵ>`4M'Ӏ&[Q[X7WDX~'?P;BèLVD(vDM1o*Aj5oojW>1K 54eY[*?4stwp!LZW MK@ﺙ&B*_}q%I se]NQ=^:*_a9VW u ЙsRPG/9 ]&t yy7oZ$ }i&Am/{B# kݗDze ~(ka/ȹ/0 PG5[_. "o9w+cm!rp qr3z^/d=P TuHه8wͯ_@7y trg[Ny>&{a:}sQWiB/`O7>~}"XX_ieU Rܛk:tc/GZPoD?|ԼCq cu[pO?HALe#[/ȕC5@7ߍӭYEK~9nC>Ded9+n&S뽁[^ԟܟwc#O89!Y:#͚ u|  ыe@8q2Yz.UXuxcC@;`'H?ñgNys~Cp'Ф.fǀ}N,Ƞ[ *w߈>W;Ҏg(A~{ 9zC3HD=PW_,u]ԯ [KG1Օs=+ruiA7}k<5<6X!(F v ;f!v_[eqoLS&{\Olm^Ɏ_cn]7j {u:k}cZKĞ@vh&o C@. cӕ'B`vF]чEkWW;e@_מYAUySt нn,JKSOjaRcKek8eRO1r%=W'F0e7VB]dWRV]!AʘYZrNTL~>UlZX?/+@[6!!!yդufk)E?c쉓̀^5}D5rږmuv@5$w )ٱ+@kW<Q"0QV3POF]lQ58wBYʘL"^`6\'Rך:{WWLONVJ:";~P@bܬjwKQ_=Omk|v=-KGv/nGF D\?x~Пpw|p,0$_(SA]lN8RPGJU~ W>Ө܊>[—Xn+eaHa 9{S?IÝ=5DžoKM 񽡜 m>6#i+FjFC%hE~XՁ5w:OOݯHF%}YD>|} Nhij'ns\~^;>/+d~ǹ:#L[>`._ 9ۋa}j\G:އ9;]'}QOuv6=%H]犖iGԝu^u;ٸo5Rs2mg:Tۇߤth[P;z@_u7`l]|ajͼ2k^\pwQԷӧza\36rv.Q^y``1oD =<{qs[w^kD`nNO;z^#02oۯ S/g gNjs.~}NCȋS#dMxן*ZiXwE{9@E״Z|{#s] ǃyvu*?M+wZks|pyBj@E%M"g>`N.((bnw; sn wR TW_޼j|%DbzECS`Dyt[Ko=kĺ2uw #cB̅ ;jGl䳁%Rz?s;n''b]TcT*FΏGZ-q2mύ_ ^OARs9F{ MP'(* Z iI}7 c1zL{6>$=g|G7OkϨ?cdFnNon?ŕ?&_c^H9u?ui;ߟ#٠sOw}kV? ܨ)gyD&%+,>E`;M12*r}_;`\^qw_h㯨i݈}{:Ӝyh|Hhrם^gߊ<>kb9s6ڕQV,Cy:vK&̣C#)͞%dz)z0ᗲ@9&p7[ ^~oךQ)ԅ:+_"t? ̹/Z׻ ;r'=OW?f`ց>d]my$3s븎/lLOD0|!7>K5 &F21zq?hx[FV+{]ʱC@Us] QQ9lf!oH9f:Lk0ge^5=؃{q>W~(z*}00/3(Bo~72@gd4{ 5@Mf4KA>>}e[=]F11y Bhdt5{~P{+ֆp6l.5euF;l|xaW> T{A g&QjJf't!i)hùO}s6=q٣; S$$ TvPHFCmYFl;?ny *0kV@;-j@'kd O؍n\{dyKzlj ڪbͼn\g䍙7I@u7j!0E>z)w$nx_ gWm >" e%x>}|Jaʏ{ﱵ>(O>uI ;?=saOC˙+97>iC(<t&.a`ix.=Ư?A<<[6XS"NybԢ-Zb}̑7u㗌YcCQW:I7UӴ0tR0Wk\ϟ֫B_C?-rͿoWz{:plNMeZw1a?yHr_.䅵ca1^ýsն\@(`߀6= P2ƚߑ;ּUQ:S>}074y7t*w~Ya:LvYb>A^P^Tn0u<3wv7ιh0)}_ýۀaЮ=g;$TFIkfrKI7mEA`B%d%եq` i_{7Tw(nJ| KZuym'[`[EtzEAUߙAiVy (;ܬ" _]ƦQ '1}3=|#4P^Bkې#' ,Du=.5ycU Kf\CrƲWjjΐJ`t;G4o(;2L'e_>g6IRП.&mxB)#lw<ud.|| Gзu;7O:XԃqcB"CCx'<tMʔ׸}q]MN wZE, ^*-@nZ}9䳙C:,e}ms8aGye cr('ƻ+^Anz=W1^tZh/Ϛ0Lrnj2ѽv:o>-یssOH$MFt0"a>Y1%tA ??&t |@_&5h⊆5{8ZTbQwi)BsNZμ_@d%qnڼS bEk пZ9z,3u{BE`|k^ ꫜ"bOܣCLs!7[%팣_璧Ts_>IG&o@=ss^zܗ6B<O$j={Ðw僩 tp(_; QRdƾf˚$ɖ-KJHEDٚKhUd)T*K,IR~>6{-9ia!F?3gf3u>J~1byA_Q;q{b u󷽱M1q#7`NB h3=`\^-3}3ʒU"x6[u) >وze bvT`y<{-gHeI̯=;~rf| }{YN&-!xf[r߆5oFVE6ڹx0kE8n$\{5D}}.ЗF3{56}}:qOާ9Q&\35ХhP1;cSpu4j,?ۛ.cWZRL;|[sw-j1G7Gߐ6|ulg6q,}8j{ɁrY/"7ΌHxe+N{?'0:Ǵ83nOp,̮7B?/2p ϭϣo93a<9˦޽n=,ecע' 4E˩J&1GW0F7z>"tYE3խԛe̙Ny^k3Cz'd pf[a< isؐ9޷v"Tm9SJLIgERϾCW\.Ԅܡ-W\rdytаmN7#?BKD(djLώ:>G z2~C1/ܗI~5[*g~Bǿ94<l ͙?u6RuغV܋w/NILO0zMKpڸKA t*a0m!30X`r鏼MGEN4vogJչAꌽn gf~xpi{δq˪O ͜j>D#g0KqB{޼*g7M9cT_ x|!'ƙt\[;g6r?s9e̕1IIL%jJvL`A9^'Q;,VƑ?L{{F3Zmr83/"p L kxKRu/NF7Π?0ae[f{s-9Μ`uv,&onș7-3V'p'gg)0-ΔW6.&-RsiUx<yY3<2/qf]x)1^o˙1Y#ݲi0a^S٫1n cjq`3Erg&k{ZO+iZo}=P[kCp>`gj>G?g&fh-O$1VQgZ yG=D},ZA/#/4b0'/Ľ?7̂BoO(g"򦱝st΍8ߋuL+ږu<=wNsZnq`^ӨuT9[})gVxY,W֪HZy[q9y{i%%QcW`b? 93_&f)lU%m87[.4;3ն櫮u/_L%]ΥʙWS^I9M佄3T[HP+E} n }O\N[1e_u$ܱrÿL_he ~5Osj(Or{qknL?:꣦4%f&#_ #gx#^Ù-ȫ`Lj7M _:߳/P[d3py)^XAx/Girf?Ekl.z3ę~M3AW8wjggFx`-g-gk zަe89%BΌfŠe>U{0ծ=-g6tX n[gmSɳX >..^n..\\\g<=sh{\{GОkZ ~`'t w0{??O?_﫹U\\BXˊV G`=jXoԪ}.ws^, [|l[sPW`ME^~ɬ ӋSCzu |qņ_pZ窪'Pz6 G+c7;˃S-6g^``d}ڜR`?;;_/9_G5v)Y}eݵj?Le=m} ;k/OO>ֹ=oڎCw܀5l 'mvRՓGl4z7nۤuXUشcn`O8/]w6o;ECO ǼJs~0om38`]F: +3'`%{CK4c3CZ~|B;8(Kvw:(ַF8>?i6j9B`+(+Z|N4t^6#~(y3Rt?=:5VueI`ak%۾Pvث"w&-/+:vج f 78>d0JY-[l{=z! ǥoj[1eK_8wtY=M ^ ؅kژXGoӀqrekPG`%gE94eł.DoS&vNg[0} `n6 ֻmZuvyG\HBdL{ W Nb;܈损;ixFY~o,z d9.qi}{^&Wbcz}&S X#6˪Yk{jY]wX f\ֳ9wq_kStz;`Kā|e=v [_cÿXW>|QQwfv9 x`-4[-Ĭ;(Y͎D_#KpO[>< *#Y1:%X&9ܯ&+'DŽw%DgM ]C'¢Nü9 q+Irw7`wT= Ցٜ1sSyء?f;; W .HyTQtOTuDg7ZIuXskY8}C:5l[yۛj8*P} cJ+{^`}ons;!oh3~p>|gA>wͲ -W[Oa8`~~: wA`/K!+4Yml 1sdnyJŹXEX3 ?*qjZR+ӃxojO$Y㜦]iXq/꧰=5+wV1p+U0=Wx 6j )Q4`TZ'j>؊fԵ!{p@vh51pd ]`~[1Ǯ1WX_]YJI@Ӟp`=5=NX_o>[sW<;u*UȣsegB_ZM]xF`S nEYz&luM@'[;0I{=1F.`zИF t:nח_IvZ}N"B o'0 V=D^zBƦg`U~<!Ʀs?FHt#O<>n\hbu"J YtxFWLsQt%oXi/D~aݒL5y[j |GOV68^:z\ѩi Ԋw{ԁx/Ac^tRէޜ$9 L Nn+~ .mُ~#cpMXJ.i<ֻQ,#MJI&`[Sq~k]:cepog5@SٞfD8뫜wVP?0@7FG։LU7]CY!̏>[]j ۧo?pSxzcF~8TƳ{.c[Jw?O"wkr^\9 ZD&D AF}a.Ju94ֺ:;&ݘ [Db}ݐs;6)ϖ;s,- >|>X*-:jq.pG9=>G0& {+oάY7,nՏjDnTЁ~$SnW~FȝK-O_B=V]v|*.~ޏҗ;X'W z vxs7*ꕎs(8.t-UZR-U&XԳ> 9|2_I UMU3U3 QS `;OK$!wqz6%sx2 ʢtX:u$iUIFE{"+_B EɃP?Kl7oΌ]KGZgws*b-[첐7L @8GR}aǻe}`&yts|S?*h$NT;Yl_ܻMrWeg!'=uy: c2oWmֈZJg \IT1᠝V8R/b|aB񼲛6=F:|,Tf~϶Wݖ`nBNQqܱc蛹_w9/goļ~nK{lvWf@/{_̶3?1cÀXtulǾWF^ye4~nHj&;)9g=ƥg3-uwmA^D{֤-M5˲C=NvP,UHU `۝|5 op̅1% 2s^[B_4qXmr ޔ85oR1I9$8`' }v01q>fgWjn-5{y0e/ݖoF?|lۣȣnj!] @*}ʽv"YҢ1(X0n]> ?BnT{d\jW?\mp zls_*5'fn;wob}Z%SԳB] !oܓdD!s}#h-/o֢g8}Yx翄v;( c䏸ˁ;#'?guMAOH<ךo+w&N_S5Nq1x?\{c3!]zVP)ީ^|aн{?s&mz\ܸqIXٗ~@ީ݁S6NV%N[.D}VJ k_juG~encPb[؈QqyQ|:#s׿|?ۧAhݘGj5[S[sK"t7<0c O2yKka,ޜ< `pZ.lSPvoļ5'VlbuLmo3}KncP*¼5$Uqt~slCM*U*!?oݳMw_8X9qCrᖕ%`ep/ԇؾSuXʳ>"bW%΅o8xJMMV1eQ(; |+IJ:]7+,o mynΛ5XM`],BX 2?ty RPgH$1GN^ }ڬF+dbr_"fj-G\@_d l ]7xNYgJҢ@ϝ>(sP q#߷>{"yf俍WZ㜇Dn{悛} ,.݃C]P䷤Dm{:\ba؎dxOO62kHA&#Us~F7ޯ^EV2u+]z1Mt9絼}-s/U|P$zxr]ի1X4k:Eʖ cu wE@7o>GG'Jb^rbbRA6w1YʼM۶o*@78@_I蒏%!^p~=UϾ_^ ^νʯzf5U^oT(iz<Tz%7MjqGỺFǗINӍl'#L|f" : ?Ocn7s@r8/ձAjSsbW0 ůث˶ǹy}rRy?KW:n4xc.%+\\CG*1oW\<}aR9o1o.DL9; ty:E}L>79Sœ*cX˯{:JW^7ތ}ﺺGw2w]<肞XLQoͨ~ Kvtn 0;zB3˶ESVoE}u:=\SJ%^Gw@7*{O.C> O`r)F~)zc-<} /Wvbf ܐu PZ\ѽ}O'υ1qs5 >9QQ:|ceVfȣ9#O3).~ImU9|^e:gE|&>:'y[p_!$:9po[Ʃl6/qn/dd+ s{reu2f+}]k~JM7='F}Y 9)x#?*?Kzt[S$FNF]]z'Zjo뿁A~%A{+>~W{8(خ ˻f#GU܈@#40tk|`uc)!jcB;0gőtqFlwOSV*ļAw ];*(2uy# (W׮ WN@i h7@??c~@+m `T=se-|{ys8. ] O/k?MC_B @im$&{@³:+(F|;=g<>ѷ:? 0'Ӽ'ՌTU /恰ŋ^ =͗ $Pig|]=,/zfUoOa["͹ !!gۇzjJ8P*l^,6F j4؞j - P`EѱZ~(Di1ϖAW$<8W^*=G:t$-TM$UW)#">* dۿ[%oFq)sXΫ&RQ(6t+} #| wK#^C B߰l^z᧏.t? įmy%`ae(Tm qMbPV:.t52`YXyU [S~u8SLDbpPgUY@}mABa>{]ð}\)G@02,aٲGƳ@x{k3o+MgHm&I Mq ̣X[{h8袎A k}4=Q"breu/|Vs!q.hBzt%n|ރY8϶jG+\`ޟԯ[旽j= )@(5CIw bn=. *Fg@˸KO*osZ^{>)mĽrʒHaP#Q}cꑷ6nUA75җ!p",jeb{-ܶh70Úb.8Ю~ ]F怄GȾS@7<}3lpyy:{t]0Ĭed>2b*,bɓ 6߀0_o] T_3%@:w6<7@p:tlj@=[0;YWj{l |@8q9j ^+sҊ'~fPغテ Ԃ@axe"g{phm܀>'R0qρI@țd{7@NY-q30o|~ܫ`yJ2Qwz:Ib9O*y}1D*YV 06_x5)W" t)B4hg% ei:u@Y(q9—h~fcN=MP1 < #c9+j2zA:ay6X~I~v;^u@ &} яC@pwuIj@y2 w_vZ gdALj10_uS)xX-0ӟ~>pDoh3-5E ٤.W՛, 9QU"-9̒n]+_%] Z` :OW+Atj eẼEFJ_[-@QGЎN7>Ђpj3=/ p]GZbv RQa)s;H]bK'P=d.0GPfcZmAh뗌q>slJukτvگ}Ur^*m2{\`|23 IS#K@0AxjPYf >m"A$Jhoȅ>£er7bOfnr<&n1fǔZe`]D;Іg &RU{-ft?J`Sr r֪xAm=}h7 O|<TaM@-AA {c}ݚ@J^]hs|ĹXt}&1mZ!lw72k/mOY suf`2Cd޴`[xuƢ86wQ>wgm9=wAQ $뾝6hkLV#k6;7w'0`3Sxߐ߁rˉ9&~n˳ |j䜞tf:5 coB"u~BQIevȽ@#\,Osqsp^f+0u)rol=Z'*>>@M'ĞX mj@}5wBÍe6y5fSCX/ ԇ1 ߌI<a># a{ݳ@Kij_ #n  ŝx'[wjwDaH8=ZD^ywo0v%8)ϫ"ߌNv=)=31@Юë0 _ڥb]Z7!1*Q]# |` Oʁ#aa,#Em˹Y4{2~cJ\+AJ~CB=}玧/R{ޯ~i/s@hbgX6ȧf쫈*7#6ڇhA  /^8J<dg 1Lį"\tJ6_sؚ1MAZƅX4KA@m8u0Lꏄ+XSˤDw&`>zpsrVu =Ĭ$'r@(D9كVls@e' Hn! (cvB}Uٽש 9ސD1))}&@`\w|sC{V(#Qb~^ģ, ܵFKd%\"l:hB5IZmT9}N] 34'}@Ky-q #_k dTC]JW<\iMH%3A>? =3(6G) \=*Ԓ̎+Q Mz#Ql9ŗCKMń)(V&.P# rg]rhA)ޞ×)Q:~(%]g xtXNͬ0c34Z @Qy&G ь9P{mώz Kʾ!/:Sx$ωN?[E`;5 `SC?u#[@4 9Iz.n_A|K4Y/v~c (6L.C8* ̱ZM@>!O)vǾ-{ToǻjZjKc'(Y !5V ^vf@6>r=8=ܲa 2adQ܀ab y?`Z 7u%m'}_gwon?bұrYk bminXʞKF 61JIBP{7eK[\uxcXEN\ԍ @Hzr:Ыb7.C@6lθ3 M-{F*m;[nŃP OoY||_4P<>_*Ͽ+`t. s:IHjjTsl~ZTz4\ d3׼_ic HH">u9c6 eX CÕ׾Ԧt%'ZmI =,~!"Ht- #Eι5 $bq .]>l14WƼ>OF/'#.*_t; quʱ xkcI7ԃX@699k{#Z*B&_CIK 9*&@:cg|} 3?rDG\vځ@np:׹ʭW3KCJm_ K;:.( 7YY+_jk]u6`$Fo&t=驺#,[1YY |Ans_C@0ʼn+@g;fb价jsqMMu$]ySO1g"y}4&PozFNU"{Ba)zj;1&m֊! +@Xi.&e n\@$~7q (Y#X=\{[1P>N_+Tպ,ضb Pv}:.4]hm`svK~"? '\RnC}/W/y`?? FQ7YA 9j6d6nQ9(05Q%w71[YTh25Hh-<9K(ʼnEUz *rwSŸGy%[7 (:_d<)m%%pSDOx\0st$ow!_ BwDFCD7H5s.h&}?sOד/|A#AwnN MGPWŏ灩` +nrPg]IsP^Wc]gk"(NNV轈 ,ow4Ov!а]7cm My%!A~ݔTW+0}Ψw||(uJiBz˦Ap6o<';nF;zy,KٿO_][e&I9O<~a?)TDvM7 SjUQ~={b. gM@7:46 W&,P3d$G)}#= .. \n}L (z:`?a.ϫ-ZRq櫓 N^_{ϝ= ViAtWš go4z4 I!u:+qsQjkzZd #_) (GWb&P94 sf'B0 b>J כկBZ^_ũ=@ t; WUc];@ΦN\^dN?eodZ@,5m[yg` q=_kO{}m-:(#K W]ŏs_,0*~=wAa@}=Q$P~ovu@P̖h[j*2Q}|x#KU2 OM@b6$[Egf2NZ_G}ͮh &W-<*Hh106aPfβ a 9$^M^7 d'J֖S@D,"`O1UVmsF;cH32qGt$m-شR#5*dnTߜU@w+wdOFVE>Ɗc__-cE~ g ' NkWWQUQ+}Q.n@qUĮ_@u cݢwAt^Pٺa|7N%WW@׷|PS0Ua+[2=Ij\Go"4d9]@ 6 rkBa!^*jQaɯ@52ތs/̬&gNI{4y0=0op~}Շ@Ԏ 75XyC{O@ª%gb@rYq qr6j]ސ =/߯8 ny|1' [h'aGRQguȭ7yHWI]8S[.0O ]{ C1 eA8M^gLҤ z,'@WQѾ?`ԋU֣'@nA3.Co\&5d#E͐(m[w>x6v~?z䜽fnt?wKO#,.7/ /TDgi'9 z7*3?1$"& inOށxʞӛ+폚&,(<$INPy ~=` r/ؓA/;Wn1BFSorj&Dϛ8 F]OybY,g٠XzPx zk͉S|]Jvq"d?`Άoy1bUW0HXr?_{@Aq"b 0mRvfaqj7@1`N;g ~n'ܝk# ft:Dm$+DÌb~eꫜ;U ~t H5Z!Y)ʠ};/|q%꼏z#P(t6h~&cVW*xD `Psi;U'kꥌ @vP/p}|5'7qF M{N #5=# ָ=󯡿S 0=AexH}W+6+Xћ@2s iJz-\sR? #HU^I,B(sm9<~=ZR+=.@+鸳eno# 0zF<ܮb1): "S|:3*" ݡTĤ| - \@]n ,M7Dy?Za guM)(ǭ)ш;zvŅ"\gV2Ѿi@{OHP+he#̯ПrF]ܢ \!؝W PŖOw.ӆtqַ\/oh~?r5e1Wtc % {G)Za釛AsXh=b,y{(&KTr|kA__9deDR@D'>c.]x4r^-ZWjClPt#1_qWC2Q߅B.wPL?=-4e݄g @&疽CQ0~<WhDބV0U:kEICZ Wh ^ egoJ6{\`Fb$%7nZfA[رkDzmx]?xL |cry9m\x+tK هiߍ*@]1b*0IT>eS;@X•@]eԭ 2u|jo{:505Ήo-3+Aj9t_1s@t*3f5}R`;z9 l>)sTAn헵*4@w٠N` Mz܀~!x&K2`GɊ l0dpKW6K35`e*$Z+gAV!$Y 6\wHzr7b{ɒ'GAՅ @17|buat%Ϲ.H-zw})gPnh*rr2/^0e?jQ0黦=d1öcU*A(>ht3Тp#\x4n?+ Y e%s|nm0џ1)R@Whg~0 BGX'"/:+/Q@*+(׵AAox#k̪;@µ/+w)'nz%΂v)yRLݛt+HΤ'Y\K` U . %Iݔ #Y{熙Z .9YR[_ƚgWč >?;r_q[ b%9ݟm֟FWpKZ+WC:H/t׎h`ª@Kꔯ|O蚘|u[̻]?o,sABwz f##85OL.F4 Ar]0XẀ/K Ydm1*,@H`H ] L2 tS\=PDp.I ^ܰy`<ů}H5C70uT糇ڠpSY*0^ "< 0M#@aݫ;+B+Hoy QYA$]8zȻȪn= u!{>oi]߻ DLiP7icC 0\F!|Y3jH~N=#/sAIIԫ:|@?$0. S1<@svQ-kKfn.ߖgń/&C؟J٠)/#gs7[UJt㙒EG] lGąN:EIq2BAl/#(d'owVֽZ@7Zwp lDſc@ߞ*;tkJ G쎫d%8^ s!G/l1 MgOb{1tY 1 $q '"'m{7X5Vvu ϱR"P4} "oԿbRĜ4hSEWAjni`Xw \.}22,7>zDBϞ]\&5Iw_7bq^.50G+| ¼ OsifxIwO؂D^coj om?X9Ŧ4ށe/==.s-_8ʓ;n LkgN?%s;3x%J#P/Vuy_Zu{B0_ײ`"fg뺃+:S }ɲ6+>rw׿ҠtqU[!7:p0(,P]gYs2ǻ>]|x>fVZ{)>;xF h/ntZ~-]f{y8̀w @Yg=P] b*O"+AnWY ܞ~/ROiiY'Y:Aaz,=Vt DiwmOO ,'پ%ʢޠ;R1)K@ Ծ2@xgϋLa2"ҁ2?@!''`-wx DgD[?Ù #7$J[bk_!BW} 4]4ټV0Q8 ? v<ƆȞRNiQuS+,7[Ix>0wh w؆ {#^*8 2Y]/ Se Uұ"ȗD]Gnp\Yl-׉}_ie! t<.0{8\UDϏލsGvE6pJ($p$6hYM۶ThNկ]}e0~9:'1׽J?{G_WǗlb@5q9s@ Ė$ZŎDኛ->})ϗ}/:-`._c"їuP7ZbځQPf}\Rߎ%56ywhz=%ߥ[ ٷ/o '~ ?*nHi ')UZfXVD|u׏J`NLbǡYgs;T ߶Zhe߫|*S em>`lHލs<_ANj= 4bKWloߧ}ը#5@Y6|tMAjgx;ȇ*˾=6jKOF-A2{WB |:D7w)9ESwq+9 ܟl' -2֛ʑ}Ywѷn=l;[j6z|ђH)>'fwJÐw.}48v49w*Sz௕9|(<8Ԅ|%=#&M kAUr :b2B?76fX ]kvkG@?G} kc ADB+&*YS ^|"Kw<DH}nJnMU^)]gfEAs)oQہNp: ΟJ߂NM}u`j)%U tK!`yJP؛ 7ġ3\0vWykn@HYsm%~aOyXj+븾F:swz_lc C9) I50yNڞz P O-Qs=U v T+sSc0($ֺTM_ zNB]D[))%s-7|͓ا'˴b}}:I \XZ܀ZwҁBz[ms9XPя@,)(5-Q?7;4Ie <; {SgpX8"m ߪ-=j F]N8KҀ}OnSxzwq"cя^ kOg>sgHO/IR >"xTugs: vݴP//>>!|W 0zNiVGzw70٧v1^$fO:P GT 3 M.ixO=}=%8x/l%;݋8;R _02 4Uz ("kyOx x*k?rK" 5v2K~m.XR]pQGou8s6 $?dwذlEx6K^:AH">7! Zv@֑⌣@jwoPI xbYmz@_EHm'_N y6uIF+W5Q |2+ܒ8L#M.Q࿷[Fі߁Ƴ{ڟ־?=?7e\D͝QluΣg|= |'6ͽm]@BUHid?]yNNPqNs@*KoAkohqtJ ,᫆q/Z؀v7̎Lm~T.y|! yLI c=9gzK <J).@hݣԂ}<}o96/!\,}BҲ'M w'߇{'Cܳ ;f0 "{ϫˁ:fC2 09uf VW) xD)|?J~mo#1c<0귝ω+@j;z*2 "&<-]@띊[>TI8Z6 lug4صןw1'Ҫstѡ0uZ!MѲ{ḧʝ6[PS9y ϯnOg˽8WNnu3߇ճU8+GW"e]/9A ]j%^[3 Pm yd'3 W`Q nW4ujV5 ĝ#\:{=I[П.ϸnȐCuѮa}橮"ճ 4iN>Y]MF_swt}kA\H n_`7gw#hy|j;4Usk{G1F;c?{ Mnj>%5 y~! $R0L u>9#H+k4O!a?Zn2S7s>ߥ/:^Q ;{zN6',ǀga 8@Bu|GׅLI%@uu$gb_7i9:SeSBMwHY5 nǽ_UB^ (mA؍W @ r@wKX83q~DjTD }cQxm~; īc%C_3=2mX97+M w[%z~J+cݛ:s(O8));f^? 39@.Ԏ4L1W=6^$N,ϼ;۪Q!WW_!VoI7Kcf%kI⫏n_Һ< B:xUX~qv#wrN]_=bvRP2ȄdoQkN[џC͢Ayx~u ?*$ϭY-γ;r꿁pnǣkoPljg"?%= |_{ȡ'WcB??EˡJ@E^(ɺ9{+Jƽxv%~n\*3k^< @n佻ut5:0r,)s44[$g$`?=.XOgFN%Wur9eߏ oOyANoH+6t@|2׻BK@q){1-M&|OGuSAEsyh:dk%ؼCP9_i vHFw> zb{9M?"c3Y̧f|bN+)ȓC 3{ {uj@0Sqk+䢃yUxۏx4KN"8h3\ǀ7ɖ@Hr +Wgq hAP~!K=G9˹@@<̺ݟ'-bIuȗ"[%g? ]\mZe7AS,mM@'ZOXĽ@XE0hF$D /~򿵘x_}j|۷\0|74 ČUܩ.r@]9[YB 0-l]Qud޾7bk_(?~bϲ%ebmY<uŦr8kKUOy{}R4 }uڣ>u9|`X[_=<Ƈ?22wHoAz20@TYn9մ]$xcdLփ@GE.g[@ X&ث8t9J rUQu'g0 r%g/V`JK/\lTf,ǜ/u $v~:TsT[~ ~eJB}Tm^o)4[z)+vH:0R!s^ZC 5B)WHj?V5;0O稅a[׆sF=*9ZI Fԗ|_#uқG@.?a/~0[xy3)0/ LoSu6z;k4c\K?2w#iYߘ҈ -^쎺pbnI}Ϣ1 6/@\_`Z~ePj :YE ,_)sQ[1WAci|4{V3Hrd>Mn ʸcrf'@.tuƈG@~/}/=ꌀ)ǸFm|yH6fe1ɹ@bvDi< Dwi7a3ԿzQHU&B.&+mj&!V=~G |v%Gfp"=҇e݉ȥ_9ǁ th]9{++n[ :ST@Ysڃ:ncD>HubrixNmtAiݿ y_)U!` VHE#>gnfe9[?րL >1 Xך+E~_znsu\G?@ 뭛D_^#)]=?"Yq<|u¯n-L?9 Y¹;=+ 4淏=gPMF-=&f:j6̀ӖJ.=)~w\ Jv|FuN/.{(}R[9ԔGWX-%./ק[T3=Ͳ'>~}r A|L';Hd!5rzh-U;o':@:`˜nhNjcoV[ &sReז{W 2#/˪r |w,vk= +^Na>5ynVg"Qw4E WreŇPg!D+L=gbkqEś<+1? 3SZ*g<[O= }W} s胦8GJ[mzJøgphܛm+ykяBVJULb]bW)nE]vz=U+X9Gsn 0v'Ą*k.G^9[3cwG]q]x_R5@Rsv_lDVv $JPO7"Z>V sgŭSm>}zj0ߘx49c۪ˇX,fVV};7gQ%SVQGTݛv|o*H3'mBZ\(?#0͢V(OpX5;ϦF3xK)gO} ` 姏Oaߎ#x=%'H)*Bvo A6Fq\ 2^X7<6"OGwK jv5Bÿqþ;N=ȿ- 1@Llk3t9 x[+琷zG<`%ro/oqp" 8+:(W^w;4 xFx¾(]7Yw4TiJ&eKJwm+m\!_z7TG{}=zW@x1J:iiԟ7בwqQ@0}uj&>߶[}quw ]A]"s"m)s }lSQc?MWW{uCw5r@6Q|5~/_;s~7}.;˅9b@4zo /syC;#*dZ/b~ Hqw_@uy<0;|Ɗ63pvdA}i!w<ފȩ$w[btF D-pu |_vG`}Pgrsܶ4I'O1@A_vk..V91s Խ>L _//|k6✙^jEZTxCx4ν 1T[n}n-X\{d19e㮆(9(Kٿ@p%#}d qjc^۬Xky,1Jܳ^ {{/zL/oSm 4d șM\:jBj:$TzW#ouB?rD ɌN_⯎@rz2&i>&gZi֍u ih9y* "-3cKó X\^=uS>r{s_`{gGI JJ%@/*cл4z區Hs|Y#H>T: @LM ny_r3fSR*=z1[ͻ$,n> ߬6S`=?N^X-~R }S@w/"8:[kT*oK@Fɉ'oO&Ȅ˷nGP iMȻ}>GFvO۲iP n̹k˧qФ;&?b9 j'p?H/W1\헋 }>k660n6 MԹ;oچA-Uu$ $YڼFry$ \4S_WACt+Dh{eO<H F|oȷF:Z2֭V*\<@k>uIp~U9W#;@rAW-uXw,H|Ƥ?g$ =DQ "^"WY 2IM_j!@^2yjcKtRL>h?EǒAlG iw/nSWlݭ *;ݤ kxo_]W^ P5VԹ *Hwwb!v-vcbb  ؘ3vww{==}ˍݳ7sf؝n5|b!NbCfzU}z.FvS֨?6=tʿ 恮^9{ [_  ̮C*Ѣ wѱW! Gz;V&k/Hg5z5.Ý']E})?AX]OŰxʬp_ofG v9 At[nեAhyLul{tܸBq/{E8buPްbCC[_yEIO^pΛ. hkע^CT`|aI1Z~mfn屷ߎi_Gg}Nߏvu)>-|7\Q|!asa i2%燚}(B%IG}/)E{o赴ϝmעwm#$\rJ:7'cϱ+k'<^mi2V ;˧͠-}_е=W~ZL~pcۖLYFsw4>=N`o9z;&ůC3wsDǎh=ӻi=|yq@vb-:[9jIC{G݉+VWϭprtRtZڿ>4giJ4:#~ 0(,z:X=LGKsB[ ˺ۓ|A,GAc]#Џֹn˞/D{-؏NgrcϦ3W=G)ei :pr6zȡ#S=FCTˑyӸ?{6c qWqrҞѣ27ܢQ:k5usi\W=w%8|xㆶD^k^]vCGG|['Cwi:qʭرI_&މ)n\P“ O=GB~G< ?X\_kk&t:fvetnyzt߸Aw`"+zc2ڵJRVݮ>nz :Y_8Xc~jo6`SZXͰSӮnvķ_ϕkآ-g&@Fwoz]5E趠,k{߂g5+\](.f\״f`}i\+wG9h]:6l^ U/Bz쫡inGCiLԵ≷fNqr/W=z77'WwYcE5*9nCKvAu!ZaQo\(f?F,AU|ݼhcnѥNP9@uk~Z:ܟ\}zO+Y=G1) w9K6U83!>NqP4_{lyK$?\8A5d5&[|Anfu7mBvd{-ttlz@t7nRmtq/U. lL"Z/}~s:TAZ>~vimFy鐷_tޥa֌l3Wv 3 q BרCiIksmfݰԦx)ty76I3cVf-nl;-6EGU|Awfoʁh:Vd)Z M,?Z !g)z 0g]{kEmr?&ߘxэAAǣkƮZѹaާ43WuѠF#*.ofL|^(ξ/B@_쿼YgEnd}FsBVħtC]Av% kTm78m}Fn2wASW^1FwmsDܿ+[NqNqk @]݇+ootljT =!O^̅ݛk1?G)i1,m_;Mmt =_1Uէa8 VK{n:wqeX0~~S;=[N{w7V/v@wk*{CH!nMv9u~pm2]"5բivʞ-fXށQmfeK~ Uk4D>jF{+-"ZUN~иsvvX;r27.FС֠1^Aȫv{a!U6h|~媋q&B]TiK}敄8/QHA?jWne*Nb=fO[nkFݥ.=^1>ݖ#>q}D? yrc,:ϴ{8ƭZm~ʑIU];Av6tl п23mDzuGOm/߸ϓk/h_ypx+NkU[{/MKwOPWǁh:cn6Ÿ́ VѥV őVh?kƑgTGFwD \Ow3F*OO>E=$lV˳t{rp^a~!8#:et/)9]TT]4O|aJvb]탋=ٶs\ѹԚ1W7wEߛW,aO#ZcXOb!_#lFzw믪ޯE:o%^wsQxtl?OZGC/ֳMqf;ߋCUQЩSWwgb`As'OGazΙ!#}н$??}i"bD݄_E@5xA(}v/(jf%q?}mYѫ0)3=`75lhԯt*-VԜ`Q[ K?W OnE+cps([b'[y`eAtsũXt|}qȆ܅cҎ$aNo==/Oِ'k9AcמA~M&ZttpUvN_*A_ W9#웠[1h_ߧk\!CXznU-ZGt9 K=kyJOj.an튟CG$59Α4'Q>}R$Ӥ'.}|mT'Jtt{ʪ/:ڧ>l_\G|&UݩVhwcLBAkAb>9]|7+mŎGS_s@w w2CQsL^B[jW ʜ tS9+ [_Gzv7R7W5DwGBۉs.݀Ο^&\߀n?.8=:\uUct0)2 M9KM&OBî~RFn%kqh5~YTU7Z͵[Bvc"t~:bwtIq7OH|xӗ~O>Rah1/+U]϶`- Y՛^l¢oYMS>W@㾍S3nճ$v ȟ:A=&DįVT+TݩgFśj[g?Z zilz9t7Z >|Gtk=dvg*?nV}]{n%?D=0dwxU{+[=:x5>;[?lpq!b}נyU]߈70# XS`St/⻿}Wk-ZEw[gp)?o>-hRN=ΰmvI[?2۶?3b: 5ƔhtyvZ:h_fr,]wKx3 Wuq+SzBYG ѩam1N]K1.Xb!tB%yfӼռy9]\wJ]P¯WY/G ]>x7y:z G}6xa:zX !ux^ⱻdZ&~Gg7;\l''4OBrF^Q5~!t{I3 yt7 eއhp>=_YLz`іmI>XO1EH]hK<500Y 3$>iB. nqڕw(oq/>eD#t(:f(| j'xeVJV3]sO47r޼дќaă8__]> >%:h3m>(z{h9~oW-z)v>iCz8]_z}ソr3UAzk;krRtܶ_XOx&/V6 ~`ƹ|,2 0Ȯѿ߬L=ג}ạ97P3u-yt228]>qz9jN9ˣu^ȓ=<섣'm|ihl.1rW:F!x@ť識pT=VQhqܴuOc#JkH8^ό d #g?f?̄?N2G#tzz\Nc.Ix[Q`f@E[_&oc-zOWy LqSknF+t=>k|ovݬRb_ze[qX" _snѿۘƑPG1 ӳiRla_g! A>^^6o"4̞7ƛegss8 Cwoafoc}/GL ^s}S:fqfM`Oa+wuw̞6)G [\gIg K[tws{>IuuSeybϒ&ql:mdϵ.GOn{~/W\>vLvt-{:ؼeG0a`t}n:=!Y|$elf.v~YLd}Nc%S/6-o3ׁ]oO"<6D&g;sofƗʞggGYYlzEtvYe=d;zmcOd`g8>49}/.y]ecdM{6-l>7Ɵ'w*O,Myq2]l~v V^^wK9L&yl~7?ɗ<[2Ifߓ투G}-}?MEyOm캛gS^sv3dF)+ǍL?d^e;N~َy8&lG8d=!'ɭleyMe͞3}/S=Ye;Ƶ N2}g2/y!8غ`O)3be͞o+[׭il26oÃe{/X6ﲽ ˟,Xvy]e(+y]dODZgzGiw}8)vOʮ='fvX 2d-_ٯ)q}OLRxe;M#粿M7L{le}ޗ%Wzʾ^+6|~}e~$,{/ {{2({n.r'_G#OB泲,G,Oy.y[ٞȼ2='<-Sc&_q2{?{J,.2n|t//nb8 r܀=n68<߲? ۲C6_2NB9Ǟ7Nodoe=-2dq\2'q%}_Wo9 \ٮyX㲝Ȓ2ʼ,ǛqygY^Toy9dG+8&{o='˿,Gl~Ȟ>{=Ol Y^e&}/[,_l<=l^eMgc} Y?!0v?e&9sٸ};2'Qlw :r([ɖGcl|2Jƽl8C}bm,;Oe9yl_:I2"!WCvd5{ƿAdaϷ}.5rW?vC̔Ju*Es且r|_:uhڨȕU?|W&aNOnݗ_mqfz r[?4:j#1pUS#C;+zm3ݲ;{EwYG{\ލ|2:Vz{66h;=t|o?/wo"0WtSokt# >۪v Q_&:HK~V8l=r1x(вƋw6mp:}2J޲Z7ncv't?{A_X>AuhrҶPw|44yEO=}lϠaCzz? ,_eve hYw}Und\5]~Ȩ:[e.8SW:۝ނUZ牎%C >؀~W>6vA̫v7kDYҦZ@ǖv;G~_OGR#M7@* #Vմm3i\ku3tpa9辵3Rѱjд0%mdߩ:r&eH !.$rem@Fo I]m"9~`I$evo%|Dsct[Я-(@g*ϵq']jMvzrcmn~\y)C{Gƪ#sJ* :Pn=\m?Wt? ?z5\l坎] &7-Z;6蜆.LJd.or<2Pt1"'԰7ޕx NX.ɯ>5Я2ab{L[]'INA1i01W3Iˑ.w}ƈkVsնX=p>huK!f] rҎh8rev͔hp!Z֜Nm<|(j.C7yD]oTNk+v}V򚆾#O?=\}786B-:Zӹ,:363Ұ3hoţz+j\~qݻ+p8f/4-~xGƒ}ۧW*#@RЧh7QzO&)q%ĸ?/Na!anK#|9r,ͧQD{-IN/=6jYI%93Ч ѩI/Jnb1MwE <|k6%ߊ޾K&VMkFHzev]GM+j|O=?~:E ;}dOtb' z 7%xBDžҸe΁OLA{Z ͼ:u0USTqL-S73CcV՘;tkڴ3OW ɣU%zOܤOu -=ǟM?^lKxdj~SX彤/_=}\3;c.U-E)W7G)s@:-Z'鄖'FC*Rs{{X+Z2_~-/XAU7v_|t {,#s,XEƯ[0=K4x$ f78`w"C+13eG+##ً^ ǘ#?f9:"u XY8t1rZ.6;-N$;u3C(Tg'mKFo}s ѷs7iw/*fhгKmB]jp]f7.}iu3ޭDg 'yC#^lVSw.Z05A-|[]Z&$MZ>gTLh3ò,tp-=hUF3fF)J~i iѡMj'xi/,.wzy_'7 $~>uzi&DX6cN_枖XꇕmLQGh_A Bj6:pwVv^v3:\u4-uN[M׾GG_ofς> DEm1]#,eɚT4% &=.si-sen"NM%v/? "K80dt1h$^)خ|ɛt8[iԑԸn|hwI!8"h?R[Ct(Dh:zv\rޑ3>6#@G_C̡)DZcJ?+p=WoAi)VdO14m.]_:JCC'rkڵAaa8Y~ke$W^v СăsgW$}5%}-!ױ/NꆠO2к.* g]DZ]Bh@~%2DJ^Jlu~l< ]ލ7kOE9VHq9>UGksUmm|:n;ڮ)w]~mM ̸u` tcZ 4cj ̪ 4R'}.m>V=} $_Q!{: j4|MO]팞MŃ'D WK5mpaa MajWGkc@Z L/ߊk ]6c$7d 3G@6*@Ŧ' Nd\)1v6#j#t0R㼧|#]'g.K/Vunev 0:lV;] x*k,!_8s",!9Hq O[ -1 ꝿbf7pV],%d(^BBg]:/ִ8ښ^uA3̿'!Pqk׷9ts7Xs9a0e)řhc^#(5#MU C()L{ r86P^砞<JT_ymJ=GI}}*{7AR\ةZ9ėdA=K+Y-iVA78pMFɲ@+Tytmyh ^Zhi+s.6}/5am-#N3j pdk'Lkta9"#ߎp[ju[w֏+謫tOgz`)N*hǴ(t(v;윶!h{Lah^Vrd¶h"V󪓢K6/B˷v %v'+|[sF+x܅nWXݞDh}},qA7'^I)G:ը#)یfUiWjBgqBR|Nv]DN024h/Pt z׻0n9Ӯx{U1]o6nH#0ϓkeO~GGSravBFixz:?eFj]o/3?iˮQ]/=F@дE=""h+NS P}KcsJ{hCFO=Fpn>#TeԷէ]NE^w9 M]Σ%q8-1΋@ЕJv߭`'`a?I41y9k&Lp|MF3w;t%>~Y5ukZ X[t#om놶A]r_ѹ{TeDK!L.mk'BY4cG;-9MK }L64C>FSEdć&ݍ,6 m{^]&!BoGiî@砻yϏ)!s\&Q͘d,x5J z~#~xqEInK=Mxs>f/clX{s.;-; 1n^Π0y+'oZK,BK4zv+.J̠?8Pj~3ok)a-,OzUec3? M*<9$9CD`/M<:8j;~g& N^IMqR;cK7:1ЃL4>nۃg :vHr+`-=굶?=!4$(6JU|DcܠkEP쳨kAE |}-(cNYxZ il żc }JA9rZ46Z^Z/Q=ͦ ,,^(ͷZ7BrP($l.}7/^5 7Wun]A嶝O7Hj"^q3p׳Xɵ]M9nrȓK95#H$#-ѯO<wh-Vi` ST}~znӘOkA7=֖BCz-Qh 'W[21UE~ Ē|GPs}j@ܿn՗ /5yt2(lz;\_,_2B+7lP]?;'#MnI[i6 ޻  0qv׺9Om*?MYg^Aqx~}x^ebU7y 9KgVeӤ_ǃʧiu k_o ^rCJ+_~2w* (SY#>y}>^~v{:i /|Z {OݫwjnLJ?R_LX# ၰ,Ai3 kf M{m.PFu:4p!Y~_UUP}>ʯƒ=5 zߒA_CLVR n: ͻogu)@1ϙ']_ R| [HvykUG?dAyq]M>jȿH7=нCZs'6-'Vydqp;7D| 陋6[5+)'m$BXx4(]oޯFhquD}IxN N*azc Aqj KEWԦ6eC;vMډ-Mu-u"yi{׾53>צ ?=w"(C~:P3nK~ 9 dn?ЦOB {ߊR(~\XiCw}N\vρ5 ~~' b~ݞ>C x_oGz'{Qs:h'U.Ȗs! sƌ4=B_sxAftE׼[MSŴNOA$K:A-(Þ ʯseA!-&~|r{4-<'fQ/f/zbJoxmxlH$E>~oK[b߹ {=յ)S9nA=U{_t63T[@^&~Iy<-+w >4ro{N>H^p7xCVg/= $HN NOhA֡6;xO|ߡZ[ t_G! o8 y3+.v>\V#`3 gېݸeChjpOES]B<炍A 7|1oN#=~yS#[,鰓e !5x!As=[G]5Qַ1t3~j\ Mޟ'L(=3fٻr_v}tdqU'~{P"^t")mK];>%)ƅ%w)Ђ#3A)aQ/>27nAˢk!|%|\ITѣ@2'v> #2of. }I/x:!(ûڰ3e{ۓ]|z#2ֵ݀㏓o1+|p̒sh]a뎑?0O*un@wI??x]}ɯ}vKq b"V?eJ~͹;3z9VȞt}vwzKںWJ-~=2`#i9:^:?R֡s2孃3G^Nu8K~O'Sܔk97 %3Ix(ݨFeirq~M]a KC7ŪȮY0A F= #\ =ʊ('fmhj?PZl`5܎MHz,lS$p} ϛvjaypZiY>`}d'4[lC}>5l:&pG~NS^#J|W[}ʆ?y?OT^&?' x-hD vKLڹC|_T_OG$|4k{ 惡KIpe$nnd?7t|("ͺV\_<+bܓ2SôV%>bYﲎ!KUҾ37`?uUG<|uo|,'(Hz:52"9m9oDPfHQ;!slMPȟl}OO1 []L|z!C;TKy?=M݋my?xD7AwX3O{įz/ݺ>FHsרWi^O&(θħ,߾A{k=K8ZwaF`!ŧ%: I1𚷻g^*G'r=Emi>IT7 E wL|YwzqٟC׌~J~Гht8E!,(%9赳| 1I/<>GvϱʒF!Cb^/%k.<; Sk}ps]pPM.-ν_?eU׫ֻb] YCV# ZTz"|HX1h f,E~.]޳"(MJCly{eq*‘F'e_et(oD1!ffsP%]$^- ʞ>L"={sŜY8i/D=ٗzz 6|X[&t0Pj˺O(`4$\_qnM&^~Jb͟$UGxGZY 7/m+$yK!p6ݵ8Sx7g:9^sD6Fs^vѠ49v4|[j=7sh5R6^zwAy\_'?Jw焺;v_DYNfS~boˠrI.v4ūV3VsB[s#J;2H߻ޭ_oy?VЛYd7N%Vi J; . %kn6S7&{[3PJ-nմ)cw7s1/o-$4O(u}fpCj{-ķ͗Cp|% &ɠ[e#8^4هީBbyPJϕak.tKp'k<޺Sѝ!|ߢ]R8Ѹ?(ܧmJ8^6qUAU>i1}N7WPܜ:4sX ܦj_p![K7%`wYaMs.Á+0gJfHNY>=wmnsɏk.yKh]_|s[I6/ޭN?^!ͮo=]~~ch}oVQg?F@vDd;uqBg/Mr?8&_4?[8ޓi- _ǺJKmܻ^} sXGI vBUoYj'i⯋,e_mwe)iNdKFx|=e#ꓜ}j2C>Wnkl4@ѽ2ٱW<<.lmi/ O41r1ϖ2nٓu$?è7r%b>=>tqԊtzLm'CDGQ;_%;"\$9,ċeNsOG#lɌr<dkmvp4g9W.b~?VFSŭ%G w}TG> >Ӱb=ץۯl$o0e Q@U/&KY]+8txx4:Էէ\F5pռ:?/x H.6z~\2tE XdAvcҚdou }[ #毁7*L!R }ސ_)D]GX_lζ_B&=3@!w׽-MXIvPFo#ߦݮ@Y#rOJ ]G ,u~^-^})L_pͼ.վaB&/% "AstA%F'ÁfB[cPEP4ib^~a^#B(GZ|գ:a9 >wo=p9vo;"ʠv@c򻠶A#?hH!b9%Z0ͧOy jPT@=rM@A('q/i\b}6֠7p:]ԷIuP'@ykw}a8hynNOEE=c@4_(׈%B/ڵb>({g i @C焲NT[ HP\֎~(񂺊9i|A*lWzDo!Pkĺ-T TPדm"k崆mAy,橐QRvY *fvNEu?zrPyO(PV4_CWfLpLrB9RPslMٕ@ џߋРJv߶OH'} _+Pa7P@U* =OA(P 77TBZxWc3Av=oŴWCPP1-XP(t})פzTE1}sB˲ZL-o6z_W B\^>mX ]=q? vfqOY-~-M c#b*`<FP @5H̛f[j ĴPV[TܔI8@s}h|b PR7MKitHP _(D>c }@gzBPNJ 1vAm@mbsǎ#PT_z:PGiz3@t_ǫ@e4?0AFP]l^[mфSʎwԓ<9Z?g,vnxF3IޗDN\W DwPɚ>SJs}Q >5mvn*)?WaPK!d6Ђj_!ApP%LOPaQ*yJ^F) q~5tv g̟qiFO: @-T~ bpF=[΢=4,~De-[|~|p]CU}1~ZFpBThP8ٜ8asM"h5TM]@,\_3PxsԵc"T,$Լp1W|p1;bYف ^PnN8YC(|PY[ bި4j ֐pPOu %Jf1O+BIed2(sL>j ,@5Eo+B#P i%%evVsURԏB>he鎠l'Q!"B)򻔵 ԆCZUFd:1ABH#\,Aȿ-黐F~ԭpP YׄR7CO/1a쇉PXTBYZ+1bP2!l4BfTPMncja]:hΕ 2#}-Hˑ#>|l=qeX_[pZ䦆ޅG(O oi² teYTGsoBBдh-$vKAc&5nSP= '}~K^Y5Pٰ>o$w9 =䗩6h-'~STۙv$K̥IL+=z|-!wȽěDC*{)SQǛBP_Ӈ@{>u_(`KWOkm]~BwVv";KtIC%n:~O 'Q#f?~,ŅW&,!"F:T#TxX *X%OoI8YcxBWQ_~-,hT/CK,w]u>u'g7ݲ)MU?R#hxG8R*z; gPJlSDӣI$@%͛q{H~/J&FvG,4n>M;NF, &G(gNa-/Ɍpw>A?T?deޞ:o=7Y~>P6E$*uz-!Kz+ϖUpy$ndxN_|ӳxޠakvv"*уcwP\2@ xz^&:|X=b>/v{7P<=XIr%&V*o:M ;u' UnĔo e3 +@Nȿh$@V/y ~wCBB7hGCXECGnF'4 y|hEX $SǻJHj)To&o{OHiG翦Ӽ4ҦgYK\A]]w|ɱīUa7=oxا` @%'1?&⛯+V$w^F?R[ `TjyjHKL.K}[@5BʗPIube3P*_>&# Cz{ZPYF (DgPP8ĺ7bqb P@+qPT-CjڡhPu)᜻X>HAN@kHrw.S@&ug9Ҹ(b? P hb9PUn&#/ă @+sXCIER\V-@`mӳaq]r'! ާ?O|jox {F8аx : XTb{L4TӪFV"zد_G%]GHϊ<05AUS+8͌R|'TGC7.ퟩֱy]uCޅpDSjoiYꞮwd!LҷQi+~w_B@M7 mq~{UfZ[P g)t]lKxřqۅ f#{}%oHy(s$d$4 e,UË _4#פS@)I$"{%>-@#K['zXEr"g2I- Թsz ;,Wﲌz#V,7#<Hq( J^tJӨt5!=kQP I@}^TBuIb P6"P&m$$>0IBz OaxR<4GDܺ>z_:?<sJL.u-JLey-4H>x䤇4ɛ*ϫ`M|_O6n3)"%O ;m';(9#?Q/Ac.{wTG=KO8/-tIb(Ԭ%dVg[; h bM~L~dBe>^w}gJ,#^+ S,b90%=γ\oiTB{PZG11G,&D5M8*!R?Rz]ڗ\hO3FZ5~jA[_pAS@h.b2(WGyX@h7q+pR0=U-6ɝ؆̈I$4(]^]Rޫrdľˠ'zG⽢Ӣ/Cb %ATBet]OgRJ@ClM+/t?ȵw>EDŽӲ$HGחDb=-uE"SԿsPgABSjB"ZdŰ׿8M,YNf P=(5݀SlOyo~6y>Cf /rA%˧a=MDvM-6\xpVlG@#Rov( E8,u;LH_<$T pFbTP\4PoI~-nc{j}uZ=T;B'">&n}KK}0dϝZ3U|O f_3L%򞐰~Ӏr77rtud퀿(F2Ł8 ,?[|v2r]qKV9fjw̆?e&1ib@wP?8Q[n?P/T ^QH^JnG&8SHHxrwSX/T~%o;6>aMfp)'!08&W |kAa7!r'ӅHpBW&_b>6M6p&+[(WᇡYkPZ/GB{÷0np{~?«KoodʸqUZsm_{;pcϛM;fb@4P+p\  1pCFMHr8Dp y耻;n{h>vH uU&χ? -Ekl5(Bps\>oJ'U뢙|{F~%Hy)j?[EŸ]}],~lHArֱlz(iC}$bAvX"}Ӣg<.xU$O7z>k *;$p=pr}E{څ؄jvE);f[#sJv=/Qhкq/^!9|6]gsyiShWջA8ok#pgjV\. X'չʕbB9/:| 4'<:v8+Ex l/)*nJrݽ=yX OwNHxUС_U8{#X\) (>\OWJ8wgøJn'sȆ}o\yVZybPH}U`9P o\yjL[ܸ{ڑ޼pJא}Ǣ4 ~c?HCL^hX"YO bµ u9͢n,ω%IB·ֺxx}-J !92繂j#GڋEGwZy<#(G= ױ=5uT*MԩOziS=1?bY᥃ _XVx:]MIpA9_06pRKHKn8M&yJ*z דCj!ЭPx_է{,~q=/[«i{0ַ[,r!ɯ?%}2'{6qs7A=ms/{o}9BAQ"d;}fu~|Xj yLh. ۉ rQ2~Ubّ֝iܩKƝw Ⱦm3[.?:xAr|䭇{hZǒ۠}f(oy遲"ݷ5I\d_8`O8uMfͲ4 :BpDM=s:A ڞ{v̭́geseȾQ7Wh;~xf}4o;#uCc?9n3pRPv)4*"}lY_(oL%hʓoE&jTL1˓MVα3jCAnp{Jq=~d]md}S̹;v9p;Ўpal߈lX.=gwNW"'[ (7mNZX~stCµ%|O-(Jl)#%$?o( B&'(Gi߫sA7[w=icKWz !.ӫ<[X/&UD #3IXpxxBL3Ex)_A0d#bvY)̷X<V4[?l_t/ڟ\+͍AyhדHΥ&܍hNhwXs^]is:Hx/cL(~64P,pb׉kA_1{Ic=gKmR8P,vxcIzˀ x(FhxMP Tk+‡ .5 u]^('#af֜i.`^P~v("^yU?󼀫|dEvyIf~1<;p#!#2(&?W#;nܩdYD)7T4_NN>S$?M[T~ŦSkwF=9F;bqb/q 8DUU7]M9{. b_}Pn*8GRy֏{R1ٜLN‘⓫F<™o~:p?[wN/-:+ֿjQ=}fo I7l~8O!iG1 )mc@PJxS[ ϴ?h}L}@QA@w8r߅zD܉xքH,Ov x_۴ϫy wď'jGw~;.aCҸ -iGP~{вߦH40spT(#@2nk3wESAѣ4oݟLegɯPm¹-A!Wu׷,#Ik78gfy/L.eS䯉٭[a^NϪ{(~'z$efvzۥ?FNOhiMXE'Pȝ;_řφ{ yb:Jq*mv?>$w] !d|ޞxX}B2Ǥ%:wS@N[ėꈇjV|5Vv_-"l!FV{y{󧒟mjfIϳ;|wƻ~&76W%'d4In_ON"T1R_nھIn=L~M_@)HbőL3{:j c&8u@m,fMSY+&ezǝuǦ<\zFz3WӀQԈ]Yڽ 4ە<+lO&WΊJck$~,"R(w]\wԦǶ` biT}KV?>SR*YQVףdⵓBvr_ǀߴnފ[ O_Ә?6ړތ1 xd|xnW_}$%:9wݗKözPt![ N_2##r~oMBԷC!,P΋NW. ܴDI?FMWH~Œkm< ɋRħnjTv%"6J$5b핿8Z\queUfq_ϕKFO@Qn~ٗl#sI~&!}T Q $Ot[}%,SԽlA/qGe0O]a=(ց28rO&{XY]-zाP B<Վ1~@tv/mFOLH~N d7mhy ,m4(bI|"=b}4X)N8BN ^vF{Xlq1F)+M?_6F`}5_ԋ#1u:M"1Y@rK,!^W25M܋M7){:= P^`;)c>I8= ٍIkWfC~(<Y_7%ɏfyz22*9=+fbPz(E-] }Ak'>=S׿Ch6䓻>c{|fG?jοx?&uǃRK"K%{k*cV+/#ˡxr s7&T܎Ko0$P4kbϨw~-Շ:C<4zkx>q6䟰|I'}ɟ-?2Pl,B_/v ~Wtݴ$Ph 95( (M7r_-ta{#|=לC ,Χ׏ A,1wr&#巐 1u-˖KhGj]_kNIu|'G*%pm ~<)Ro>^u#xNhũ9!v}zmFcgzҜ.9 9hu|Bc\%^91ӚG۱1ɄˌX_zNNj4^r6ԉxK![,oOiJ^پk8Yc"ZP=7 N|c_?ՌE q_ #3\(CvLʧپqzܶ;`AMCO1$Vok {ķM"Lhn ˪I ꝴz݉J~ˣᚿf$}${{BU^wM57'#eP>xn}\ӀJK,Ś8~[8x bШn iW=e{ f}M/8Bt4W礁H8W"8\̓8N  GA/|c ! RⱢf-s*|{}1-в~͛FP<}sX%PY<t,OZgxXgз4Pv\<'<6sALiz8]"'?[8ڢB"A27@+Ce{ҹРM X)H'E:![]Ay jk bbh5k @֊n{бZ8_)Mlm9(p;譥}.B%hm&#Y]Gײ9뛠c붽xZ<#h? FqZuT}RABz-бrQR?2Tg:Ve} $_sAAYd@c'fb[%GеV,3 ˕vTzl]׃HhQ.)NHm/O46^x.hY~v4! tsh>BХDyRy* GceQy[+;M78Gh ,߂>OHs-:1m4G緁NBJ<G'R~P x~ hs% s~A+һ$RgGt{!;%lR>N\ ā|RF G͏h~>\,A1#@wN"y2nZ%Ht7}.~T?XZ7.gEzDsEzdW3Y_7<-?*Gl`9zlAw=ADcxZO7s;іHyzeyP:C)϶J7:T/xj}=A/o\*7k;'R~cRvE(B'԰W Z߯HՄk1]JivYLnm?/|g,]l>xQeRB+O ZVPnVD3A{|2Xig~^˫|w6"}E&K׋7 sA'1.r&ebc♩BT?!3R?2 s3*6eTgYՎ:z[@ ;z&;+X2t,H}. jBp|dвZ!8 To)_a}0AKt&^Cۄ r@p#h |mguR}5\']~_:w:ϦVѱ]b e~J A?Эꜵ>1)4qshi%iGL7R8v]@PXZ4BC+>힠gOZx~#x%b"@% l"5R?)ad3&Yg}"~ ӧSRmPPqOѲ)eT?%Սk㥸6dW$*ʲ+ Ju|j $Oi@0 #)9}p(cˆoxgQ&#{(HEs`_h\KX_$=˓~):ѳ:cA3I>vNM+>`dY̿ΟǛ'mPSaRy-w-KXEⅺؽ#>(nkDȉ'1̣X3 *Ai,/ꄑ=#Gz%N Y'V?[6LP-uoZv.^:E }kM&uicARF-6"9:E4δI?W)hzm]W!mI9D~l1hdA~+VJyerR96ڠmG(pAYįtnR- i"?3ԲPz;)\{KYl2W Z{]rPA+)Slв>2w{~L@~؎_xݣxƌ P:BkH 4,WWU鎥%UE I%ADQAP 9"***w̽_3s|~>͍jͷ>&P` {ɫBٴJ} Diao,?ź1EL\ui c|_{?bưIh}@(p7u_ADkP:&Hg4(He dPӴq<[/D3@ u:&ȿkޖLb̿M F|ZvcP# 8 m_Z2O4.0xbځ%ħf㪀?o(~PpQĆLu< ku Q:QvѯjJ?츬#n굺񭶸ψ_#|fK?‘y¢krH1/bg1A`G{? Ѹ͎ 1_N k<>_a rCp5h ɾO_mʌV5oooJhGx6uwUkѿ@ k,D)ox#{N3>%L|=(C e !d?/WnEc5[ !&^sFw13/qj) !?O^P&CNؠȼ)ʳ̧?G|x# ɂTC?ؼIhy=xr3L1 Y5ڜa`{Ve<=垄иW] d~(U agGu:c4ګOoiXYӍ=-|; y;qyC|P:5mȵ (BңpCtL<[|;- |ܑz}&f?f6}x3ُNz3ڠ3o,k_ށfuZ^$;О*]? Ҿ" jK+u+pW@.+vm_Siї{.0,X|;^s]WϼنYǮ~f':XEWIYuK;UN1o#{Ft潯ה7I3큷3^%(<z_GNo }_x])ᷠzMھU6顊&`~&%z].{2xjiOGn=i?>=f)#oB#^=ɼG-=x}E OwgdwonD=^]?A: 4Cxf}~W7@A9k5oqg^NUۨ f/#HaW]2{ϞB[^Fe?ӻ7D\79 }E#NUg>_a=s>_'Xp]G`8/^56xk3z~$k,_R|Wy5|ܨ^O_=`mX m|c5lM}x\_MZ>1QgRuHtc5ջBQ$ח=x\ߞx}u3_@ GqNC489/s/ٓ"o!mL7>+W]oVܩ"f<[Gx*T?9[y7WNԽEiNC'BdߝҞ*VP6O?q}ǯɼn:jƔ_<Lݍcܫio}rMd K={.ݎ 91o}R<ӿׯq,գ+RޗĻYwh.[>UgJ^ߝ*RvQ?B7]ʯ;qF-,M{{מG<cd:!g,9xg~+yYs^ߤП^ yayZ^IywoA$4y|w#HW kX;M>5#\[su7z!L'D;}n?Ѱ4rQQg)[dg]O|!G{ij)Y/Pl g /7ҝ2_Xk<Ե}.:s ~+o'N74C6y+9|Ο{D~{䦙hp|U3@xlzϛ<ߑ>4'c}ɓ3m|{Ii@?<4桯nHiyy=-7CqI,&>C ))s{>ԇ%}stfcoOi|1o|i0KݦT5,xO\tB9ȼt(IW;Vj+Ib\e/mqN04@PLz?Wkk1{Zܢ [$Wi(7y(-27y,:4i 9(/>ޝzoڡSYq'[~;?8BN_q0M| 6 mZ؟K>/:CǼu4(֭0aG ֵ#%ucXHƷ5Xm&K}G=tf+1fsNx:(d)GЧzgi\I\ZBPou#`:ƑTy'1tAr_oB1><է}ڝpUJO=[vRnZHPWa^I'թk>g7Q*^IYy.Q>4qXBvfפW'':]Y]0.=VTy:#U[PH#g??_r|~o:9I˓ďOo7 臲7t2|N7v; Ng~%yU"z*q)ƯjOz]fz,2Ir9o3ȸ)>f6#cΎϹHdUib~`G\ij<[HԻV7ȠBFI׀}~= "_nRwfy} =5F$F?zNy %<,0{wOԧ-?qK,pʒS~|ԗ,&]RabXE}f liǴzy#e]=/N伇xWOO8v(;x\2BB'ޥأnoCucsоf@ _at+_3PD ktTus̐m!njw4H=Vwz߯ޟqϥDb}KߜK>#o;v.V]'9h_ 谧2x<ᗠ>ϭyoˏhyʹ&o6|wG %v_b_FQJoFQ][~:> F_N:\o HOiǹ]I|ݍ~ɨ_9+TH=O;K7dM-x~n9 mh 1.ej?:q9Uis5[5޶ OUy'V=$ׅ#~(y: 릟ntUPQۿ6t;~HV?U .#IW%@h¥;9rb\' x~.ɭ]?B#auzcpy[AyK JOAp}=F5 1)P[<ދLIW [q^GmjUCɐCmǍe.b#d;pH/_x5񂪤.Y&|qxב٣B)ډ4p?2e1lTmCkQBF񊇦ch A(I\wʋ||<ýZfw8DgVМ>֤: by.{=O&$U=0<ļ{ǮdcUZA@94sx]h7(|'-q?5h7I3yǹ7gh>E>;5a6Ϯ jqr3Ƕ<BSO !侗Љ:EK?_DՐD݉v&*u8@ !~5i6!b[=Qº2߼dvrj`<< 'C B݆t%  4Xk.g-ͿGѺ0nܪMZyJяbhlWB O bns< Q Y#h.*t^wCۛ? ֜Yd-W,AvI[^ r\s-!eTiOڠϹLx052X {au0{fcC 'jԷē2ކ:!(ߢPq\Ai+u'c]98} Az>C!XCWjnm~ S;~՝b7|I0TS4V֠[7o}8I;dh_h\ߐ2/)Յd@<‹ :v'܍eT0t ~궖_KrL_7r!dXkk> :̛zYxiA풬'l7ݹ ^GA='&@Hlqr} a =U(y̓Ez!E|PTtNYKs8,LоN.z B[E?M^bmUSqb_źRcDtW6B y.,L{$QrFAqzACvqL-/DKSFq^Lҭ O4>в d6WX+}R=7XoF h\ {ߋL, \ƾ8稶?-`_p__ntQ4Ň@r߃uYtG>ͣ7M(DJ> +|B TyHB4eݔuO(֣` (qPr^}Wx8ڪNN:OqqP@ݬkJUȗ7Uҟ<)?-@ܩ|4A|p5Ʉ5=|<2mѯ&^/oL8PaׂO,948b ΂;@*j64角#w02כގ4Do:_hj:a*#\]Lxl&ؿ~k?+i%4})v^V4oGL%]5x{ulL>iXu7I4\y/BH?;yX:#[X*zS!.Pc [>3+M(u}Äq!)A،'ue7J 5xLC7S~Hz6fj`QT~^u彠t65 QYc{Tey m0Ŭ=\M7Yջv}fК ԖA1*">dw1v8N ^'q2/I'O6 h"L:t׀*iIh?ؠL~ӃCп>PGwB A5K俄3Y걧*#c_140w>%7Xz7?_<OS\~k r;7v2I_i䇤3_kXt[ʴSsn0n gKB꧒ϼCId4JA~l! 9[S<ѱWCҎ:Y&2?ِ3,aY;IF|T'nƒhC\ez)C)ֽ`s(+FŽrR?=`?͆zv@͸)w;׭Ry_N|^gY@vx__f@݁!=!‡`JC׍?OO2ܟ&ӉV%!x=|oԃwӘ/g!#{acKTV#A>_yƆK|Ҍ~9zg+ga"9MT)Zp53 gJ}||ěr >_u_(c(>2S|6$H~hߴ-XS $Ks;>hFՈKj~b)$>R*T/2q~_wA5۔'᳞T~Snnq ky3]~D?ԯonp'*wWp^:~v:>Rz wtOߙ<I*sOIâUx}AR#ut8=50,? QJ]}+b^,i͎ YE oii`_-[~Hy'!Y+zk@qZTv^yd!&5"{SJȮ? ^Qߒ| l<h"wO4BuOnө̛T*7j♐xF*wwZ!{iE7@^$=%wRzGeVe4 AZJC!^@$դ;E>#67x4ߩ6H X~>:BFﳚHD|c9yI'J)qW?ufSz? xC:hKs+M@2.yPG3d M创֏=uB_pc3Ϻ>4%>~W>|L4r[>-Pշ}Ms:{4&]rF3㡿jE7@ݯ q_qOx?xM>3}*Dq4oNFXf .H9;k9imM} ^rd>y ]yVȉz˚!( /| 6]gwyFuJ }Jy&ɼ]TqSonͺ>Py~"= A$ Uvr!K͍)kTaBF ®TWNI3wb~mUB${)ϬXF~ս߽!U"obpn ^ߖݍ 'HO u;nq{1/q|;IaauRMdA1ON|q%/U?Sk HoIg^菱S>L+O7]=B8DLwߒ42[݉FB>u3ͩc! LCD \oLzr+hgRʼngA󜓙Fi` EZQ~ByTUt&:G.KjH@2_bG]/}zʻM(kƯws%N/Sퟗ)$aAqa J#0Q3ORPḿ$/+OR: yKAKe.GͩTTi9lz| s( >{Կn.W;Mx ɟ棇E mnJͱ]( P<OM#>Os}rկ!?!.Ps `~&e=qQ}M]$nss=@YicGk|(1Ә>yA΀5 x!HiQG(ˑnBSNoUH>@y-vG}֥cN]gɉߗ5x<Fbj͠1H7m~t^$qȹcVZJY-4r;ͣ?qJ4Tk-7> 5=gu#:DݦeVBPwVhvZ ^*2JüJ˓ K~RD'~/Kz~@z% (xC.R{jnҍR|&sƽ&X $Y]궴Moq&S g?|7w6hw8ǺAN%iߙڽa|A|#d@K;LҥdAXH |d P|Sy%Ϲ/Q#BJSAX%sdIM{uz 1ZfHC?qiq}|r%-V NY &_nyطxv/NIPg@^&_Փ슭#kW)|2~TG{uσC'_W=/.e?odusаݎ~8UzLjJ9ehFo=ֽ~t͖wG5];4X;z- Fq3)oʻ^?ro$QK3&?TeJ< 7-h&. _,0o|ʯxURo xNZ~Ns U޻qχ&s<"_u0 s'B:lZr$JU5 HC9 >_A:A7iv9zYR6ň3s"0QLt8^/xeo5Fj3 z8} Һo>_p ^W;i|yo {<ȺK{g [lzr9xgy[ےp]HoB^o#x? }EM&{p<<͎79 vtbD kiޕ>wF? P@_OM1x\/4݁9^ fΩ<֫*]e[,ֱc\,D|R!k}| ؛F׉=|K!m3^Ϗ}nO9 ^p'{ݖW:_'[ 3佫-2 t"4/qStV*D4Z>3'k ./hӿb?}p "9x^CG >M rhE}\Y]7{T7 wυ=UX3 7BDB>Yo0~{xi:  M;x8RȷUsx(2I_kH:|>3z]H(GL*8u">訟Co&'_{{UV+ԙr(`!? uqjW)(๭Hx冝6ߌ3"GP c#=WtחπWuد"]ȥdqxWuxbTOx/~HJ q[@sW/1߳%on_ ^ Sȁymyo*sHz_lgYCo#.кgG9(Qq ];YӯtsI ZCd 􃷗hk"\!((l CdX* /xzLG{L'PւM y=oQ0rnezF=O묳k"%vOOYm2O};I{EC|n?M(`<ܗ{(?]sNS: ~SKs,DokfL=D|h;H^| rB ?ǼmiNS%G;0k93yw s}n|z!+e{dȊa-'V}1ϻyxK(.poNH;?{o9bg@i)u, "u|cBNҌ]i9k*]0ʒeo ͱVX`y/߹+~o|ٛC{M}|jdh=)[|x[-חvt}qQ~}e}H4ϐ?)~vY6-l 4F}SW|os]xΈkI}R>Wz ?(K%>SoZnuD>xs(Cq^/ q~,|qA/饑ԾxZQ3r/Ez^[6:3n./Hs"شvh:ŖŨGCAJגϕ i4;lrr2OC+;*{y",x?|y)m wEtuHw>O^T<36W2O:/73>F>W.EsUt@ǷrdP^E"M_8턹?s=M -[>LnJ`42;T#Yg*4>広 hsN}ܑy{u=@sv/]'<34-}I50?mŠ9 "7^%NlxeѯAd٣҇H? >uDX2y/Ps~ѿGX㼌7=-g|`'w &|{F"nY^_8| ~xlTO/?|s>c onGx@nhvmY:D>Qڍ[jiᕡY埞:<$\8Qht[mP?YCz{?-Ceʮ~ߜj=x|IU΂%yo>9n9|ooB\}U#V?Zv iCGR>ʛ Pp竿Ƹ™}<sC32קΫgAy0߹nA^?'/x^3\ a[?x.|)kӪ\q?ohЯ:w\6}<Wf6CX "R|^uҳ~ӗ@dw7mI}k4Gqߋ׵='(xfI۫n ^&s~KC畨I;{]1q=DfTKxn JFkVwx[4: "Nxgr~=5Or"VBA۩ŷ|~|?U{9,#(y\󦙆s(ߣ~G(?u'3yÇ/Nzk>ǥxGVc|x2u#T wo=W ~%YVCdympjws.>yF~rCAߙi-R^+}܎W#;:ƥϦ R AxmHGGuOKa!rm[IOw? R~;W_TgL[,CtV{Do<(/~yې'^POw ڵC'hZ۷ͻ/sƓ0zTA'NA;p??uア4'x?߂%h=3:7޷;Ho`<˼vfbP|9ȏ*OӜv+@'LNh_{__[|/>g00x̏鱎SyZv5xguy"٭CVrKO:O8,5ü^qW!1;+=@ܝ7?]wիG m)gk' ^70"q\9:w=Ǐ<U~?n݄ s?"=շy}Cd׊/9o;+ ?_;~8X>/G"ҙLCGI-qN;h{_#Ֆ )x~ޓM뾀Z/E]*$/?TYocϑz~?X]GIn8DfV2b9|tsCƽD|5fv >28}-N1vGAA<{Z9q/溒[ܺo~y1t27E>lY\t!ҁq,|r&4GJOdQ_m7 GxП~U2$uO#USQ~wt^ꝬS<\MW4A9yWcT >rD?ǑVUǢadzC̻ieUgE˸n=qՍoA2 י M}ݧwZSZiJ% ϿGx#r`W"ǵw5Fmc7#l/0#4!X[oH|{ܷCNAa\~^iu"7;Qs^,Q[tG Au|gZy֫"k((q륛DA2v_B{{*Z7:1=mѿ'$)Ic ,$y1m vқHT!Ӥg=$$ /}ř4~>b/r@FPXR)ԁflmI!1,zǷr$ }I 9/>8g%>9MuM|H4.^ tA.d~$ϡ5!^82Gy :l<ɛI'z_ψ/:}۾kAa`~8f <_}b<} %%'Ǚ_: %oM$PQwUhJ$IyE3BP]>iy s!E̓~̻YR!GqI9e^"?M!nLWC.PfN7Aѓ) }`]ޢ=J|O5*m_ <ߚ4eyJzj:q](t%XۓXr#%8c8ۏĺR?z/4]b#qC7簂.lBM ނAi3Ɖ?, _^JtAHf?Gu/Zg8L@ I3da;- k聆%ßLҔ@h!Ҙ|MLwqߴ=pQq.~I<, g "~AE%I81[7q+8積JU9ϓ$:IAR\?K榓 n~{&/򹽨p#4ACM7h=ByHYQY8_q + q֛Kp~!}Lg%cqCӄ vtӴT/ qMcsoONA2gޘyuzuc +5z!8Klg:x5yBֻOf( sRϝ`դf? $.C ɑ0˵U';?0B|! oK̓8?i'"7檓Gs;spC, é2nڝKB!'&y=~|-$X=i~<'=ME}vZ}K!^v'Cb*^E4 S/!a&c" Jk!1.'B=N:g/,“A"?J5ET]i @y# Gپp"\4cRe SIӾIy,@ L$Y!}q"K~1!p*r_[xIM8. ZfH`_w,b>f'擎lWgNK<^AOBlA;vWzx!1WY򹱹ԇe"N#H3QD)i( 1#k~>yW# 11EߺAk+ˏk_EH 2~jo omygTs#FH,CsQ7{5:|B%:QI҅PC8"'o'!z?B{&X1`KLЏ?DY4$?>ih&A=eo$LbSPs1MH8iiY"@󀅬Q} --ģ[h99q R?~SzH!AMH}iLC'\c`_YOV$ޮ)C[4'MtٮZeA!H0_bv~9@pp Lr34S! Nh7[}Y)d>֢&Z"KMKc$'%׉ !q{C$#Hye"hD`gFlI8dݬiqqⵈ7~:Y2cl_M4=]#gԇ]ȼ 7q&w{d??n!RK~I &΢47Hߓ(Kg X'0YY ,oJKڇ23{I|j5q7χ%Y8Yq_">È.^IJwk'@J04CIMv&>ďI6~o; |E N8YF&E^(S_|u|F8OJ0U$\d"潉s?ŧ-qgB|i.;F<<OZCEpUD!CX4c%!^bc?+աPwEa&y0֐ߓ^Ya=f~ rģ=H_dzL&Xtb 5}QӞ u7!fhaNh gM#(^b @OZOEVqO%'N`(֘t&.[I!N@ iF&˭oQ+uc:?ay-d.n/\j?-vi.PWiqrwn ɚ/Zuz^0t<g^M3ڭ/Nj僟C"(|yܗy㾩ăPtxn71tfbi_wN pPl( "CHcU!qxfc$ZKy֮q':\ɳZw|#[MqT$8?<PhǾ11eԄ} u[ Y"sLqONܯ݁ʐx6MlC: ovK -1:h'C?N AVzc&'qG6W`8OPVD.C&;-я9?).b3:aZbtH EnKx/~x)DI3{Es,]?} ]6ew,4cɊu+Sƈ4E8佤[{ ( RM)<ݒdi( S }+ID9eLkP̟ZC [b ™oQМLy]ԯ,u(֙iK=u{(V<*^ 7 c(ѫWL"OS_du-ߟ!Mp}JDob?G-|Rz%R<S<8' ʲ^3t)*I>Y|Gǻ߲l7%F|<_q\#Y7%_{֠9|_y5Hwh.9hAmyS<2jX#DAx7ޢd KSf [<dkpߜ)~ީw4fCClVxKxnLmFgd>\U-(_$Ag;ҹ=_㡚΁ x?ߩRS:@)y z~2OoΠ~lfB-2v]ց5/6uN%B[^~?Fs?SҟGqI伨G3dpy#,ߴ(-Sm-S 眃UEy">/iw."?{TDeG "N:9$ͤk<xyyzݱ2V7P~Ρ> r}۲BQ\2E{۴RWP(PhPU(ޕ_ҠZeֳ 2I;h?LrZ(ͯ+ӗM<|GN,Mrr(S+wRσ*N K%9+M5=K3:j 4>l߾efƳ&:Oh\r\+~X]7UݗA]$'Y7"CMiK11M?@1󆲤!eIzșԇ-:\`ti+.* J/IM)T}>b"՚t) : i4S\wuw u{ޖ `,Xq!j%}iA~e^4t =o[O?4\<ԁFyVOȿUP-EA8)И8ֿZ9auyCGɮJ滖\7 J>=Ot!v> +20xUҖWPс yXVD11^z9l7'*GR.`>zs31r#AZ@m6{B|+bT` xL1?WB?8P)|\A:;%7KSָzdjF-߭z.ϻI&` $ȋ+q 1V/k:G1*wV֙:Gׁ:8|wE?~HQע%]&HϾek[ ӼKܿ$^vm߭7"?un5x.^"M&P4cO̻&*#Gϳ-sd>dg)+=vuP2LyNGY=`Bw_G*U+#Af]1t7QX9mqK`=:U=m~*Akqߖ:f:!2<'tWԟVk9q()X*48_*Ι\z?.:H}wn|FR/RD64P AV"msK܈d^=(g%h9ߌ0 :R]e^B)%vZ<P0yx1ȿ.*!]x*7Jj7Azq rK3ީ.WB?Ja'v߸fP? `yG1Az6o+;_Ќ7PIЇ#*ɼJW}rkvT?l V9ׂ>nݚ:9FeT3ź(Q<'p:Λt&yF:8k֕{%̗͟(堫S> I]ev.+ l甑c>NAQ/|]JKqUiq{WTڪstCf `(]|恐6?s%W$54:DrdF<B}ȒyG:yiNi;<,Ҏ+_|MCʡ_|v|ꨉ.w~/3PvkH}',֯zA0EV@i7'õae=Y"#^4O֙ 6Չi~Ir*:a={=uWAу6 ?xC-s06(x LxXZEec 3͗Fr]%YO1]=Ҹ'xU24~rfqb$%֏a=&} *3dNO鉶+ hAyᰇ!rB!?G dE T:c@<ǀp?9c)#b:e2#Q9 I㾡߿xUdÁ_9.pegPl|:v-_9$=u-F3KGd:b]h1ݶeHb}ƭ~UF(7jR>@;+y>K xȞ_)$OLmf26}SvMqK|/O>?! Jz%WKߐ<tGM ЏokŊ*QXŊKV߯A/fT///Y//9//yIco驿e[Vo٩[j5SkHOZ#=Fzj52RkdHZ##FFj52RkdLZ#3Ffj52SkdLZ#+FVjY5RkdJZ#+FVj٩5SkdNZ#;Fvj٩5rRkIZ#'FNj95rRkMZ#7Fnj5rSkMZ#/F^jy5RkKZ#/F]dkqVVVVVVVVVVVKwjntZ[-ݭVKw2jn Z[-íVpe2jnLZ[-ӭVte2jnLZ[-˭VreղjYn,Z[-˭VveղjnlZ[-ۭVverj9nZ[-ǭVqrj9n\Z[-׭Vurjn\Z[-ϭVsjynm!G|N |NGe=}|I4#RkyNϕ_s9o 9o~}z_JoCyݑQ쾱I2|Xϱ|x̲w?DZG1o4_X^?QGz3s߷7o_d^(1f~ާ=W9,:?^o*9*~_s=s:H;uv@/x4(/,n}MþW|&m;;z߳v`ڮc0PsӁ|}ϑxi}{ns?`t~;$~u[iq>Ws3$s8(9c-uFyg%mhh^w<({Qvf5 ^g&?3}G{Cs3C^ w_-N}2/azf7F[\5!^>=$1.~&~X C=X|`:ޟ->I|_~}v*=?י7I>xW?ghp}vW[d~sX;a9_{ά=mxt/=g߻}{~Ž=goף_}ʟ7E9g~.#{ [?}_!okqnsl+}Z ko|=oo]v{v=^g<_|>6?w:?|?FZ{s9_Ovs՟>kFZ\kc^7|?/bϾ/~x1ϩű%|v Z;qq^=ߛĿ7^{#=Oq=Znel\m~6.οomiLx_M<|nmSYalW[L̾O ߷d'q?Gky~8׷yo43a;^9e6ϙoqr ۭ5aƭ֎>ycퟵ6ޛj9XS=ε}߲y|}onvߌyBm#:8yTϟc훍_->xƳXws-86g}o=~=¿?/{}ټ-. ;̞3ܡ֏js̳cxoX{o-#@k9o~o?ߏ?\,_lqoWYq:ld< YF<\3m|e6a6;ߏw͓<\;xi6e}o}qKslm͋|`߬_kΞc~_u=G_gl.Z˟7֮ڸ{[`Zk_sGX߻lC<:sy6ko+X~[wya;GEUѴ'`!֝zQ% O@THלuD%7J4E' {|o= ͛U;Qa}%J[S^f#HEdŢ|hiz[Cj)UE[8!vmcܢr~u{Բ{$O5Z˾ PsUsn3$΢CUyI%HF|ÐC(*?$j0bfmĢ+F'}JѲ_#jD2D:C+j C-iԡ߇=G|ː:UʯM7GƸRVl&jNs*jjnm_[?~~|^RT*aßUuiٰ^Nr?U{zm\~ЬD(NŪ?FTmqNuqti [z7Q)$_T_WsQ$5ke#-gHE+?Կu1젢V%#$8WfpD*gDmD ˯hɟ҃[D'?M8Qh7UjtN[~v=+͝~\цHE}o}wEEb; CX ]R& QEb˴|GASFSdDe%* њ)Ekn Qm!g2ctUvr_QhUgkuѼZvG0)=FB!E$\4ޑXxVq,ƚ|(j1n&mQf8F.kXI!?f] dDWD*zw# ==W4lTDͼ}U^+"LZEwjQ% hgh(Q)HKX46֌C~gU7mwV-jN*2}E]c{[T;;MK:mH4-KwuZsgj2~F+@mu/h8,j8ِw=TSrQC.qQQ3bь?7n%ZF~O n*Yɐ(ZDR.0b#ٍ"j5,J3=v*ou_Q]o9~m ?n(Y\&IѨV%J]М׋JEWQhfGȈzQ}!#54Z(3B̈: ٭<݈ȈUhZQ!i *?gDDK/" r]Q?uN߅L$nEC5-vo+j~Rۄϊ9LX]4oU/Em"}5t-;,j~9X"jL]wGGno[4zQM[;Jm>b\KZuN4ZlHEɳ m_hUlb@Z>`0È=jPہ1 DD7 9]Ր拊+ ٹu5ۨ[r̢Υ,)j]ˉ&=o@/j.=&oKh2.m[&E^䗴bDEosQ{`{8WF,@4+/ԚYҬ5K7_N"t+N'4{P.ZFV`iE.4Q]IC:E8t!clzDkVoѠYo!fYV.}k8umCkMB?ߐO]E?} ؘU \nCQ9Xٲ7/=FTlN~F:I =Noq޿EߊЂ=(GDF?oDDWiO!1Qi$]"1"[;L5n7vk(HW9Q#$-e٦3h_v:kDZxtz:5HX4{K3EO輖gDEdj}HQAM@MTaD1~NƭZ0?("eT=Dc?.5AƉgjH-m!vF$+hV5chum. J~x))׊k濎G?l#FU*hAB[BQ"SJk#|Azd-QZѴd7|R[ѤQ?~zXoAJnb]DGOۑ,{"=#%jѪ#(Z.|.c{U61ZQ?hZ_Q+D>F4Oѿ)QcE '5/wb^/J{RkhTuog(I"ܺ-}RDk4໇DWi5A/N~L)-5ѬJs7ufQAj]乇hkD=;cѸ֮#QbKVh׈ZwcQ Dv7"| F N! k>YqIcDFdZYc?2(S##&j<7ZiD;(RGxX%茑hqfn(hZڈىʷLЪ1~6dN_?5eDScѐ-{xV4zk30ĥ*v^T_ʟ2D_YmIQj֐^ʈR6TE?h;w'>(a~\o YjF#)ʴ9m # sMM#1EԿ:lQTV'=Qܻ:e(֌⫊'=_ֈ:k _󲦢ӯ~A*4kE)Z :uFԬ`EZ>:Qy!> }E QhnQx ځhbIMuXʦokE;HX9%.?Q2y7KD;EQf#%ޤϢF_#'hTKDNFTHQo ;z9FgyZ}8a9Q}k#E/'xm3Q^QaQz#ƒ^4楢Zw#.7s]}:$ ?jNւ^T>6g9ŏݳUnɉ'ּ.zA!-Q=KD:|YԽc̛U7{VFOԞ=uI٧GZm3m<|-&n5xBj$$jX(3śzk->1ߢ||3E2cTT[kuŴd1Q\9ßZ]D7K6W8֢2KL24G#"#2bi ƨa"mzk4cOD膬ySЯFST~ߨjUPqQ ʻWlv.ݨiDDݡ2K{¿GeDEe> H \NjӏuE6ʕ՝Zsf(>-)#k*NݽQ4`VN-QA5z}ܼmEqLQStD D9F,VXe@DrFL48eDY_Fֹ; }KkoJj/m6couZ(~fI#)cv;ih[@an 퀈2ѭ_VԺ L=EhDE]zK+2@#_7[ᩢIܚe5+iOOrUec2ԌzGnD:*]7nFZTmֹ/w oRֲ+&j4qZ#{nO4@kv&Vㆾ/qSڐMv Q[ ݉_G#t3^T{皈 `VjP}#vzhx#sjO_͝~(Eb>_ uZhp^|'eQ>μ#qeyuVEWѠ4ck]ޣUD&NTԒ^] yy*h~ڈ^uv'zU3^MҏiyVQ{:DQSzvEϊXa?5M?Ռ+z>oɏ*sE[rx4_拦mtX IQm7ע>i֞F5Rah wcwD=&>eġD*X,4w7 nol:Jz#pZ&n@!W^y DtQGAx_jB:X^!ќGAܻOB[IH7M"Qwx9P MbIV0%Xp4gfUk;!S L"~ƿM& $mDbѺ&O{jsuOne< m× M@ɓA+C`,Dut/NwܽǾ@+޺!ؾϧ ]ϫ]?,uMGA{u^B.O) T10>%:!p&<.A`sAE#DW=akN'׃UEkL bô*X./ţ!@Ao6-lbO!VeIQz/~ _R!z-F"qk!݋@>H(2ݵU;v*xK7/v~7Du\YX7,f6 .1-ŏmab:ߎE_2 1=Їk]cD1@TkJ-kNG6*^e(~6=#A!hY6Ap1;L=lSs+o _5t}Z'vMShu D뙾ڠH98ßE핅7S?' XA5x#˱} 4 qq'\n[A}>LeMY2Z~qO ,2cqߜCKΆ8AxV6u׀VZx$ը3#OCԔ#m(^vQv3SA|y8fEQKh6ہxB}!}6[˷yv#{z@lN^Ʊk!:|L@tC6> ~Dy6D3}@S|'A_fuDۿ +1߃ q b]jd>ysf|1?^{e   L OA9SWlĩM~gI_ceޝO}H7/ܸ-C!hgpkpzE_V|x- );wZ1}ah4^Z{{2ɃXFrv 7.4@0^2Z3] B3x]P]$ l1/Z7ֆۦn"_ d]1xKs ~*_O[Xo823AfN8+[Z5y1^-w 'Wj[Q\Qv\b|`fAj_XSņcMF# 6a }Eo)'n5 J^{Vo+Mo`}k=((>'L\ARC2̓BPgџ6}xNaRףZ~&kv +席!Zװ#CIxg-贃 G|DY9dЫVyכކϳL҆`qeV3uH4Pg}0GL{_[~nC' bT7@E+pպFAŤclCEKXꞹŦДB18Pk kT0kd>9Wt]/b;V;G g_l:]X #S!4?Gz䚵AY^[6xmq񼼽^'\!V 82$)Ѳ& Wj׭a9&85BA^g`=!}vx>tqnF{OĜruwWALw C?n825M+Zz2r0py:n~s @6gÖ+hYu20kM ,R}E_5}s1$6]\YA@4FHFcQ~>  sM7ܷ͵"Oi@@}xѝm֦o[-=qDu'jɫCy 00}._=AbY޴I4>mU6CYA AZ3Am _AqoxcG|0xk$?hESO(­zIx!ޜ n6<fAE;3Qc[݉ G0JxH" 4ƃYşj2cjgmA?Ӵ+"ir;(=7u+^t>6#A{ ?Qk1N ]> ;*F(?y~`bῈAteNG5*D?1XG6![w{C!i t3to~ݶ}3A:a釂[7E4_Y뇙ZZkpz!l"@.v&nn*{ zQ&< :mm ( ~Zǩ5nЙF<@bt2 `|6>M50 Eu5?]tX gntnxU; _5 m1cA~C\7I;' !d\v3ޤhK~禕fs]M?D7~=vwRnx.p5D釙?&߉C﹀q4 yl~}e |!>?6 |O&O :<^PWLs_iM NScy0].{1_L0Ą!/aI COy? q2t5>?'r-4e!6$Bt{6hSGK! B/>7K@3qM<+]N{uBNu Q4|W ևgds6& !6.hJv#obўpĎ4[NX AcB 1 ⿙h)V~ ?҅m|SOe]٧3U}.Խky|O_WA.Dy>n Ǹh^-^-6}9Bj!n&u' /ƯU7ta\obV\荖>q|Z1:e%zzXhV{# ? x)#o:9ϼrW+1~^2umRy=)"$) tM@I}>IӇ~U<7M=TSO4 tp Ӎ?̛!4zC-X6@{nю?G崶\[iliS;o b:t=iJM}?-L:+ъ~ Ӏ UlSK<@yNy  um9+>[_FG .vg?(뇘 XWFz2r'69G<Sׇy1>6r_l \cq'Qz~ 6z':69lzz/;9=63}+\bTPͼ(Ov~2lθwC_ʿ6@wf> 791¡ w+HP8oR|W@[眩}c!Z/y>?fӤ^>+h%<`Q?jU !yB㆕'B0(NG\2,L_?0nWBFBD#l/3jB~ɇ_BW^|ߗk$c2JÅ{l_0U((MU;k r3u tz3Poxwuߡ`Q֗  yH=}^l#Pп՗]i9(ꋬu[A~k{?R OːzG?/CAo}:p*?ٚl ̷Hn~ 8:~>VA5Ke߁|[\Hf&J 3Rc;B7K$ߠ/haҡ`駇 ot8>vkuȿb~.@_*gnH'] W)3s(= ^$o?/Ϭ߮=]Yg0.|hx8TXm}_}H1 L5_9s1DN=BšPЫYb!_W^]['րSW\("x߹PpA?.~xSשB~GBĤGBAG{f_;+޻w>4'G>{33?4 /vN/ h~,~K }}˯? w ᫐ .lkȱ'v< {++^9`BpCE=Rž; ||=gu?'^N_8kT(XR_䂷 rߜX8w; |[UP0A?imV,5?oo:^ 6k h odCAZ,K ߤ[:Cuan^Ifffff;1ffƘ)1333k@nuWiޕfN9'ٯbA]h_A&ca<_K~ _R ߏZ+Uw^/o߀V0NJV&50j]vߢ?8cU_OVHs4bFoo)pӜkyywbiTM}yq_&LkiƁqcr7ȶ>7}k=/)譟-Ȼ?oԾz fz)0]'}eT)o1,{'Kcg7ǝ<>[.O6yc]~sځ{ˬ ܮi2͏Yxz3K]5=nٶ*4m2?mB|rOܧuәx^]2hoiΣ.ޯ{%'ѭ̼@mj{ hs]Q>#ǧVCiPP-栭}pv+ ,PN=vyw(/es؅[ރu(d?eF=ZZs}UׁiF{-^#A- r_~x>_f۝0_K[vF0/]7$cD:n^5' $U X8?hiIUBZ9 Cͮ}FR$<~\$+==MT3Z猉+AoMcAP#\\dcwp TW5y!U[(?Poy`i ޽:I|Dsgc\_:VDϝxf*3̙F+Ҳ'1=P3>+1Oc^yTfOff GòGv-uߡy}jn^1{Y|?iU ߋ8yV$؅uS}Uv[\=2G:k n}*wi=1>>^&@[T1X杁){{J*tRp]X>'vż惇y0~]~3G'Oʓ0Μrsyӫdg G|y9/Dv qA."ޠf\#)*<ۊy.A{@ /9ߕOe\5Cm}!fZޞrh@qY*U[5f,W=xp?9=Ŝ)>z/\X qRYC?`\ ̿V2`fХCw0 K])|z Pǣ̓/S}h}qh&?:vnq %1U'n8MV܏h^m;+ ) S޴RW*eJzIǿv8Hyn.k.!7mAM׿ϋp #l],[b_x_ju Dm@?]XhUQՇFq{;-yx0ߴA>drpokPˀΠNJcP}XJesүnA2aVn{ @3ӽxOӈRqS|ŭ,Un:+B5ЫO(t_$+qW^ *t+|+WKГoOڸsPs#Jg]@Z!g u]db2{U]鲯.b@Ena+X {b[yb_>Ξa_kvޟbLۑ+G C^at]]jӍڻ0U}ͷ`>sPuІPR?!OnG3=vSNbT|]=- t kdgM܏0?8ϱn,zu{ԯEܾ޽ҋkv>Z{}G!c&;x?ϑ3 amoi{׭χ;`m>l\`ng3.S!I-ß8ܫL#Ǩժ {ʖ$M#p>W3 ^ sfǟ/o,OάקrqF\~Yi =\'Z.hعa ZoTS9PlnDGjW1/4 Ub=O8/OUn0V|q$т3cjئX@UCqtMW.}fǼTzvm ߁&an &Gx_Ӑי-(/EZa֡AoOW_:g36JH7^tyڈ ZR6aCE{@]5_] ]E$B2{ 0ϾNٲ)f}wԦo6ϴ)G8&ܸ<5khжv*Vn.B<n⣂F_YXN+*PeWZ׿J_I1ԃ}G;DX<ܿA[ͤ1 Y#GxgG%FMS 8cRIfb>9EupvUwm.-Du˼%TOo[4~^%_bG^mb=~깆I[M)N:nӆ9N?T WE۸/77A[yϳc=$Es; :RD؛Jps~8}nKq#Mypb+{' m<9~"ŷ .A[12PsŸ=fx)BJW괰\#帵, ź}p>{SA1 ٝoXLȷIZpz?l,&_#7F$3r{!7XT﹗c޶R I@,{n޸5ֶ9FGE􎰮 w%]ټCO9 |sM]{b8Pkm s4K[^*x5x>?^k{E81.eh?{*x>ғ:n1 *2cUgAp~7/QKW+կ+W{֣K  apwݿU됤|Z\'-*ƃ _lux9he^6`)/WG|j7>gĸKwO_<[[Rg+?ua!G UIolߧ™Z1s4ռhy}l([1\?ySA-p׈:f pw[tegf{Yo Ƒ ]ܯh /b H|E) WcOWճ_,Pe8l eƄu3q<.qx :o7SrEOw;=o_=뱮]t7Oze U; "j)RdZerPtXKP<(sǚDOR ; ~إFԌmB\ h̏_mk[@e1jiFf8?NJ q}٣@Kڱ# 4!y' !d?01^*Y.oC@ v}y?90oVPf#O2L=B꜀Olz  Qػ`?I}JX;r=ootm%ͿR~#T7<ԸP/=^k\ #]}">[tT4ؼ)hu!}f?iwx傠^ 0dmA{GRgBBaH:Y1)ipҜ/7Rd%߽č!Olǻ=K&A@atJIc7_bdOA@1>f_lB4y/25VRIh< ﹆D{r #k?B7 '] C񏂻i8{?I/%8cp_Ϥ'}r 5$m6~xg^Z5;ϹJ,O`+Ļ V>-@0Uhq $"e!$!}e)b;+nPރ@e7$ꃟKt}OJzq ho0'GVߐ}_ RBWp7ͨ$H\u1-Bg~it-3x^/R 8Vր_eT>J7~)ůC<{]KLV)-/(u!Мe'JqwtP0d7thq̏)GsWb':8Ab`4@xmu5'z|,ߣXcuBy&G|. |7<ߢ(._$u M҇оWЉ@_ X# ǺC\g¼F}I0.v7y7Ё^Eow^)o&.t}1??\ Qb[D:-oXJ!n#U?ǣbW2d=wkViiƿRO ̒i}p4qW6*x!0/:'!I! iP$rJQ^?r1?K]Z2_,zԇCCB2?#Q m݄/!)>D{|@7|M#H!s?ߗy!OO~bqJ' Z'˟>%WJA=t=|)BɅLC?#]PN!к7 Ƴ?-0/[A,P~2O" q 0pfp?}dB_0:l+ hKML!_L BH~K<*C,29XZ+k .#'>)~/V Gl}@GI WQyoM!׊dGP7!j|L|~R[By Bk}y5_m_,_#n("Xo$h9ߑ _ u B tUA @>&u|\¶g ѿ|;!ȼ`' wJ+%yosK@$}?ݿOow`0)bARhh>`/¹~SGzIq7nҬ3!oKҔ`>=D3O_KM/LYHnɺJB~f `<|'E:\| \E*q?O̵snq`4h!J0|/v_^|A痨NzKAfl`"!?>m% ٓrH 9TVB E=܄HBI6[C`x 67D3W3YvB@fk GZ!A ɶG~$?/1%0Vc>x$p`AjR>8 8y|WN9N!.O**".{J۠q3$XmOñ*)uUBtj髂u\4u 2_-CH ?m_!OyԣhY#O|@4l ipy0tԉX/c6Qe  1 (Ԡ^A4)]W y7ۃH'\MƻY2B@'!8q:랥HPJ+sC ]';`hA[ b򒿛HAyx)e!WbIPcm1%U9t:=>%xOlց# }~S.1(GǡC^``px,Hav?n4; 9A\SAF\:' >w S5 zuIr(b (.z#.z/-lFteW\8RA#Vu_*!:j<Ȁ~IWϗs((#gc_BJyܿN`BȈAl!@=b_ ouC$c>LBݸz.HA+p%zu|{1  |_|ϥ0oUrG+ du!gK ߄ la3rF{!ϙW. dӷi,-D⺿ c}$eo0+Bb$0_J_$K1k eEglY:!>8ۄu&̗ ZyBBO "\>~&` geyϣ63Gl:v&f穏%ucS(" n.}!ZԹ?N Ր x WEa}rJX>qEHT{M~;KL0Dn1m?'hcIyt(eoCj=zA^0Υ_UG񽓮OV<&_'|~Es}|;U 0oAM 6eӏ}kT*!'>ˆ} ?' $Ž6XOa"R<7B0ޑJ` G^uARv"qį <&ZB!v,?({I~K  )K^S ( # h4O?%je7? I4qFЍ}V!Ŕ,h%swj;1Rz1NbQK>ѿz:PTl O/cݙ qF,+cx|D6w@K6|,_h@0w  ߂A[۾twI=$}\\IK4VI90Xƥ}Lvo{ר3Rpc6|gn9'9oV 5`/ Pc};"y ܩ ZyY qΕ%irg/+C>c'i%k:wecv&W?k {__ڴ7;m>l'U.VmO>ЗEU|^䭸7iTd݃(1kU6mL|͞8Es}m.Gk{ig4M۞Vy[\Z=he%ݻ'Eַ*B+Mos֧ʠq\?ݧ#90nTs<7JOp\sKpZϸf0޽^z7:Tߟy'0qߗX+ZZ<],YQE5桺Bk>S}臈u?nu/k/|-CI~a>xX_:PcjmжҾOp5_}_N)ǫI. ɦw{ZǸDq#<]:W$~'dXo$3GȀG ǸxZ=H]Cz5ϽsCvq`*AM@mL+~moj 'KڎG_A<8=) uw=[ ֓::n*+?R;k >۵MU-y4h~ϻfKÔ98in%Fq9/KA2>{bVD([66η#fސ>E[jy0x!}_AFzpzEI X"~Doק{9YTCˠze|O򺤯'}>P bm!3˻qA.X =ugMsoWl+0Ey;r]Xw=0ߘ7i@˽u, 1\RöF`YWV6;ŎAxnd6"vRy/zC:/0KY;ضt3^xi0gL|"XoT{tesď7ZN+4݇Ov{ZbJ>t)YB&6X{PYs{׎qC D~%w_ºW_MmzsYX )[g^&&}3Au@mDX/.e3ӌS+j!1`Zq?6!}d_h6>rGtx{m-Y<ү^;%]/әX//٨Ow?ҙD'6^|4r\z3t8G )&]]Hk1xKρ8U:A]_Gc˺XY,Fyar 5E9FymM~'GLKu05kz=eI14I %. @`n<>\=?z{D<~}S<覄/|Hfݩ:*mtk=RKv:B`6#{_*"lC[m{EbJ^{- ~,<%cC6v]>8N}8_Vى#s=zզj!^ҩ㱀ؔQjI xZ̚o-|1B"TE̚^]rybcqO4Yc=|ܟEwN[-E<σ+?z6=)7֒Oa7Tg*2-4">]J߳څvPm<#:Ex7'd^u'ZFo߱~6KWzj+\Tv8Xw1b_#lC{BsjmԹ-ȃ-sN`X&SRҾ,*8^Et#{50Sp|sW:;%fw zm 8o#@;`'9s]]=OAw3ܠrƯ}S0~6i?sߺ.s?@}<}DAc8Q#xr;5.dw_qE|t1,6 .u"@y~z`/O54_|S|0_]"P딈uۓLێ+Lo5ضӈvftEFpOY5QCA5+֥A#ֿ[E uL/Eú4)/UmP/exYkLZɄy"u3Z+4GM˝Ah/X4. n 1$xi*۴xG*V1~7hBnr7+Q_N[ Ե7nb<>8tҡ 9NuiC?b\}2,qG6s-o~Nhlr^(BV:o2 .~O!TT摅ߟtݢ+^U{;aݘY9}f&Y1ݝcq`ވ@[ dZ\K x+v_=cSX\t#^WJ_Iz>gm4wԦ}6>Gi{DϵP4~#Ny~QZk1W`V0_KY>Ն}.⨗{kw-S";k//9+n78?~ӶZ ~{M=nLWC@t>#ͺ|h;SrҖ)N[yZR.8$SAm|RӤ>ϖX&F`\"@»U#{tU|Ó^:2hhͼjR8XiALzdg؟}q|eg S7@c -օ8๮7mBΈGKF} ֪cdn67$ ꮭ=85:4_s۷0#&\ν|\5 ZUFuȻ'?% Q?(nRXoC{ZOcȾq/}ꌓxNFrB9`^fE$sƯXũݷF^, ZTBuUv!U$ݨsf}vyu-O_sGYIk fq=^u&3YW]S>kz,0e]U F?{{5pwHøtʾ{/(<'SSa5ߎwՎޕ~o.>!%i_uX ?WS+McIn퇒N7BNxP8ղ%MvҢls˓X/HŸk`HM$Y75;u?PĻ͜ݒa)8aiAGgJqsɳ!n['Akͷ5a_oI`J޷# o4xN1Y*v i}:݉{V_(tQ*e ~1_Yʽ5[קmbu.ֈ?_:ޗG9f,g"qS ׆|1duDCj46.9틂VFVɵ{>ҏPbt@ť:_u5ۘ] ^k;A"Kb]5WҶҌl fF0i|מ|ψ_;F~c,w~m_'kWZVtHП\оAx̞NK%~$.}7/< \Ubw҇3iۨ#`j>I:QY-F У*<1X?*gr K`snJmm O! ׉:->|>iK3l5¦!pM-VW|Wg>C0$y~;ю+ @=dm㿗|mó`%?M"-d@ӬحOx;ۀۂvadgU|a``IǾ~SPJ;?`g=^ :u`3|;5LzAJcJj>VO4C=U' qY_`x혼C0|b?^?>Qڀ-텳\_ akեeޥ/.y`T3w`>=rRN@/}E$l)5,9|WNy{r s;!L7U~j(u>@}g[Эv͇Sc4#> o! x?i  b5 u g}\aY/yN4ZJtZ<xN/>1n9'0:x_'h4-@H؎/B@딄yV/,4~~iR ̆ħU%CX+W^ur*o XD%!K l1 L-!އE$tߴ5sg9E5 0(ރ/كf8n]Tw`W+G]}Xb;|?.o;=_է^Ɲsn|D@~u['>b-K" o,DlPҀ5z潅}ѴHtD0f`ؿ|W7ݵy/X̣%>`4%؂j/0 (Xo} uS7|Lr cb]n=G{vG yI/i bgXЯ 6[KI{N2{)䧼h >`@*ƽoA/`>tB*d'cXNu,'SϱǒL gQ!d㝄C(DKZ_<[`W[{;m6S|K0S=wV3cX\mZ _{n@6gE<$M/?krIɇ;Џ~nL)Ak~u?-X%62_&Yfx '?y2~ݶNٟ|'`Oܺ  +qg^&|o JlA֫|vι>`3>M-PG{lUJ13 әTGQߚs>@l`oN, 0PVXKOس@q_ev?}3#=Np-a|>&Xo۵R,U`J`cU0jϘ[a!|VI? Rhe *B`~_sEB?8\%pađgl l8cw@f''&1|e'Ӆ*"X1 ü`a A 3q.];@pY\AP@lX(`s@| G _3 kCyps*xoX2G uc-$ὦ((U>'KFxt ޓ|@>N^_6 .;yl? [k9 FOf/;ȗ_Ep`WZѦ! <#/>'`'F9I_'UOƟtlwnoג ii>` | %snW]%zCֹ57<ߙtfE~r~AD u}P4Xmcf^1pX܎=Rչ-/h$q+_%&7B~h(6,֥чnT(o<'ls?:#j߇+ju'P һ p= <% X&c~FtLB` uRyί:>֡wd_ B,،^`0Xe؃7+!iӾ6̣a] %,;XR( 0;vD\7oZ3bτ<X&T[c>&7 o.ۈ1bPV e#n<lޣ!; Xl'=X}~xH7CXOA_% -0K`@8Ԛ(|s9y;KE}W?4F4l=&۝I,c"OO:y6VH!y׃xYv'M6|NsKDѴ?K\ƃu |'Fi=p'!,G.Q(`D2I d@e^c}{8AkVKΦ!|7v2Pe s|8='\P>#h ߵ-`z~K؃޵~n [> ',/JLȾ6fh-םH+Vd2soVbp v"!p||g|g388bl 7Y5s@l"fc/nX/FO3Pk)3#} Ea}lKك`~oC· WB %lOߧ_о{zx&P\Q8H>'|ug8TH9]1>6}/ׅWUZ؛HGzC\.xDvX'1\Y4$%Hw1*>l'ǸVpcS7!S g%ʊ3KϼQA ؜qvhbG;되?[Q;APSghX~ߓbc>@sIFg:o5^:}ƴcy͖ԧ/6Q?a~Ҋ)Fϊ69Nwq:ysK3 ].Z~ *ZZ)U[L'c?\6ZvR =.X;h$2t,nC}r?x}{O1>(3b=ZFT0X'߹E 3om #|FWsi v?ؕ#59!P*hb}*axD۷$&0è^gXgBvjD7_]1j]yH7Fܗw!>wASCMvz_KDWc}͟\`_ҋW"ޭ|XN'WbGY lAs GBglWGofǂhSHދF:<ݴ|H969:wZ\xAy{aZӮѸ6٬j[jwS/^\ 'avwn;+Ke<is`Ik nEL&obvLq;L!#)6%팤k$%uZFB<}ulOlO5Ǧ{4 oYWd] s'}Qޮq`Mq3Yu Oʭ_E!,W, I9N` 6 h`s,rZXo?6Ɇ+X;i^g]R G+/"\0lYX~;?? ë]\}W6ȒLfm?($dϬ5e@ WV/ b?֟I.'g^Kc_x XOHw~NzrE!2+(7?wΪJ@֧$$]py9ݝ=_2 |&X(>6c1Z!0U(JUmp|.yLt, ^8!|uH'PV(ߛy.X@tbV>o?e>%̚gBq@(>9O^Ö[3L(Jdv8~<.J$O+Vo48Ÿ'1X|Vd_Dqn!UYC(K2`+·2( ߺWq-8Mqص|/){EVq,$bN%jTuaUGo*'}DW鿥hsD%'I0UC_Gt}#)~[qe{KʃR"'˽3%2ԝQ"uAȻ>Q\^SmQ"G%j)mWҋבW\4T"zD~e}a<|>SR\y$P"S9*-c9}+g)TR4RH|I,9듙Hq\ K,t1LV,P"*>'(za!D=I\/Ɗ=,&Պ+ ;K~S\`Ź^m L*/ѥ)]c+.){Xo8Aq3Q‾WtwaOȮR@q~VcĿL?)R"ڣ #.IJT>vVeCCĨ3!5 W޴ϠD4DNz)ug7HJByW*#R_:/k*wq.oK+Sn`,"`>{řW+(.()Yq>⻫ݚ;cUV٤cG >sUэ ǝRH+**QDrxKK2qQ+D%0>ʹs/G.9gl\+ZRLqkA:(RGq%'ʽ:+$%%rE/9P"Ίvrk%h_ .H}x%b/8 kQJ c>Rj"4Jd63Ĺ!S\8KɹI`l)80KRīJZXqs*űTȁ&S ߇,Z,"(Q%UV (RN1Q(yOqH{>JT\ϮRW_q,}vUOG#Xc)1c(Vbad*%RʲJ*.iojS\yDső~*NNR&RKjQ<*űP`<Ć,!?I܌P )Ā@& D ch|W"~>'T׬^ͻvf%Jh1VʾZ"sDŵ~z,֝z*rЇqH,QIZ%Yw [G XHq5 LH7GSN)(RhGqJ*Q-LʡJDK+Ϊ"mU?Rq5sv%R~3JW*N )Zs<9@~RWq5I SVS8|ܱJd;G)4 (Dy,nD5>v%*(GˆTSa&dL +T*}*Q#UIT>W_;!BJd*LA|!Nb$<.0/89K}6%P(QeD\|J۫ĉ3zN6;4/8bgC&T#BGw#8rOul-jH}$%2ԱR"RwR^*}7T*_r8K}B5sRQXE~]Eq tSe⠽15[8W+Q^Tu'T"ANRY@+oV"BDq Zة+JTA3DPLqtK0!a`%1.k%i үϭWV"#ID9bWqV %N8J *r8m+ROqў5BP;w*Ξr.8$qW V>g^ _D<.~W^z8dqTw%r\dWx⌏(8/gON⤽į8wq$L).uRl"IID8$=% 2lE7.uf} 1Nq<J’gApQq[̗=̟oBqczkg*crIqy|'u5%<¤1'x;[?h D/ՊP8dۡ{OHSGD3en8D9?N()Qr qBJ}0 f&uΔ |g19R:D;V% 3g{%kW"K[<үXqJ,Ѯ%N*9T\"Y^b>Jfr[+ Q) 󋕞}P }ERJqq(e*5/J_[M. g%2eWS>Fl a1TOq.az54W"2n'땈rB6s+ [^>ŕA+N}P-yhJk#qD u{8_SqΔkeJq^) 鷀ϕd5KGΔtJRBq;Jnau)͓W|9P"hNqssnsF}PE<( WR\qΎYqL\*!Iސ+b$*qתnz%e!뾈I딿ERq ̢w;h#$X;yQ>D-<=5zGvAT%}1%=S\wN!jJ! 1ޏX}rS!lJdT՛8=\1q[{(N PS8h^xsU A2)r8h_Lq *uJd곻H]q͔o^&G?/Go9߁`LߗmNs'ho[q qR[q*=WZ|u Ӣ˽0%KE<2%2-ȷVL/=+Q5w$wGOY`*NQ"HaǫbYqa.vAqorS$[*Β]9"=<5^~1Zcqψ|MoE~tr.ej83%ˑJ6 Sq&3ɓTuD{*5H&Bq=~H*.ioͽ $Aq5Š _DZ!xȼb I/X69]=E~ bȸ7bXO =@2ֻ4q69K=($%ɱ>>CP#Ľ 用%RWq,JR8RQYT*?[q)y/䂱>9W䷉KUSrݒ|jF6Dϕaޖ^SڈD;*NEB;Q ?Iژ|vxH|fř3{?7:_jCVB>5>rMqVÊsAW"bЬm"%1H;[Y/r|3\46bɱ#;V"g7َth2I^$q" #X}+0 ]h 5:#7XVZV_kmif*uvMJ/VX)(Gвҁ%4E'_߾[y /9ćHVnXiO 6[kKZP_}t|,'{֟R0X`XRgXoUs}.f,ď71l:O H`=# D~s脟76EmӁ9I?>Eu.Xl-o/Zn"Ex,1} !oK'x9,ݴ5`/Mjްٜ|b,Awy-1p/rm d s`E}V0yb?:[fk{F`u)fݑY )}=kX=d^;\) Gux\{>C?a.ɾ0W^z`DzP{1IKզtD &Nb<M;i > yvNګXw{_ g~O}[ bc;\ S%A~GvQ4yX3Ř6!#4'w`2<.)kc+2`mg!dK^iZ4)N|4ʺ Yr!?X̫0H &؉J6`ߔ5J|T+9/~kv4"c\$?]}Ԭ9I|Y|Mz6拏ˏjr!aM?mgA0Oʾ{FՁl]_y;+{Q,W`% @`Uo-CUGG| +Z{?8eEs\{)1<]< KbX}A6Eٖraw%@}7r?l_`K bi^!|'#BV{>KbXxY'WE.'_kXZ ?'1_ B-xߟuLt9/Z5kү^^{ m~9/Xk?zX"سkqQ;VOU`3o0w֗dSOYpu b265b_[Mb>zlM؊qmm5*H¼XN}f}s>`綮I Qo?O~d95>P4[K{2/`M%`l>P/X 1xral6 v)Qg޼-&`\ žVS/7|We~Rc&>;Vn> -l"^O'X-s؝Iobqkc6y*Q3*= ~̏ruZ4#9:)o7_?ײw֣2?4j,u>asVbr>yL慅u"LlaWp~h$Z"N!<-g,dT0J}|xVÂɾ&ކ2Ϥ*ƫ gb# t)_'&ψocy{iec ('-bz,x0Yg-ђ o0i>VÉ"~?6s|ɧĒa6>룺Z;`}J, Y$0s Le<0k]qu𽱾N*}Ҹ|֦yXE$LL>-1w `14[bM0hu2Ґ޹u;7.5WIo)`6~yz^A\MW6Lq%ZiIw"Ǽ%錅V6:ߛ*B8f}s'C|=/keZc}u|!yjV֩c]3[lq:I}}9bvtD`zqX4R>3 e_3VSK jE{0X À`ןSؿbU1X盌61eR,E -Oy7oO '#!>r!<݁t-|}e+5XG}b%LSmGz&sy[]bv $̃3Gf0+=ts0,H2r;[A8b('錘Se]V)QD -JqXa]l@/)cO`0>ׁe&#k8o7C _ ? &8˽Bݸ'Q_֢y5[yL\ bC}-ڋB٪@o"ݠ\6IYoe:+geC XVAA{ǺyJ"(>&vZ ҃C!KBx}:l6yXId_01-b\u -`% Sԭ9i=5|G%_ 5*)&}?X݄qPU`2 bٶ}{|zK&'8,/u̧tML%h7&ucx\vbld%jR3ۮ{)ӹXiwgLzi+Nb|m+a$hh5,E}fy-LSo`@.E2i:8|dlˤaŕ%}K7V|< e u |?HA`1XSjqaaӛŀ) Yj3bpKFb`%5tw=8*/u,yq`5|GVM}#\M<`뜰'/ .N[o=OloجaUJ҉4l{~Nc_I'wgg"/=>üIsIK:mB#شuGRq䯖a] N?9{iUwXt%}1KbzlIlHTvү>a+1|Tk/Q`m'o 9gxLj<2+$!ϻT#<1ψO8cǹf?>Nj]3l7ru(gXa=yR'Փ )̍["yX f̟Sf㛜c/x`#snhOryH-Vyh+}Y9smlb"IKڣ`M81ٮ`fE`=<[ y|8pur;&{eCcXߋ<& D.\ŀwSbžFQp0k'~"?=4_X_7qJa&Mquͣl |ZnE:B?{F$_Φž6ͼ\ࠥv?9η~ź آ=1$PLXwۻJ\`ƒB`Δ/lf5 ab0"&璎}@6t{_>S7o#2.Ǭs<,'/g-TwL736;r ̩GĿYLb~U C|>mqjߦg\^ʏ`jLs.`'j _© &uL7e9lY8|)'|wo _-3o-oS:(0% ޳΃&c#>%x'H~c8#-fx`~Vy k0YW{,EYH%?&<ԣB,qr)X3dzN01 f'ZӯB]Wspؖ24^9l#_q?XF{v8} Z<єYBj?Tzeٍxu=;c.>M6.ֶ,)< <1ĺ ͇̓@|Da]k[O8 4GYߋn0n3N|`ۖd}kxU<^' Z!5.>v}ꃚOd+5Y^℃w ,`Khfߓgx.u,J!ד^u='[ ޵ņ7.XP<8 |Z[jc_al&I جGi\-!rOx3 0kkq3ec?Ily^LIGhEh&sG/M]uw1!f d39fbL0rs36o[c^L]YI\yym `%\`X)qto  Ix'nJ{ %?YM%sͱs~L9 ZwQ.%G,YU0Ѽ}u'(S~#hx؟˺SE ?'ҡtA^'uF rLd}Y3'zK{8ex^br LuFm $=+ wN-{Ec}&ӟf2eФsY+4T։M@{^.נz⾗:VşC}!;bIƉ4Fk4TP`[GaT7vY,4:NOibޯ%`[1s,uul"|88fu/d 0+)Xel ؒ&^YG+4Y7ښ37g?IxybJ9tN﨟OruGbzOk%E)/_r xוI!18a:+'3]M[Flw x#IJ%y`:@wє*tW.ל`n9eȿ YBuq q-b>ŋd%ZMh{W l{KTx)M$_bJF|IqޣI;D1; ]l% k!7-q"UA|E~>fṸ.9Ez#\)r<0=8||8v+34Pj,[HIC2~BHٛo4ygck* Xў䍁6:իf{N|ݘ}tMɿA. ⵁ瞐I3׳IWq&׫@8NOIo*=\kvW2Y^ݿwo)0kBXea4Xb銀7,1]i;wY>/Yq4֢w`ߐUY E~{цn^[ CCrƺuTGljw*"05*1zVogޟ$(>Hd޴%a04E1{^k6|"%/5A`¼wJ][۷Xen)1O~ \xsct KKMtF"=D0ILm8W7 ԧSسR3Վ,6ϟ) (Ug gϡ9 }`Ueoyהr5K<,拙[s"\mJzgm09D{ =^~{Vxυ?]ǼR)R8B43ma6 |t^e;~!ر {B5yeWl4xX 86s\osx7[iN1ϴ獪~)x싅x|M 9jcT z}bꄺşތFa{cw3/O},kcypdN`:,'@en;]*``yc7XWsӴv&Za=Wh}Vq)΁-u$ј_aK/|a U#b_R0/Dax/wʝbxewS-`c>}R]p~r{cB6̔4w3%-㲤dw=xQ*҂fx߫(ӢM M)(_sڲ7-^Iga{-'3;(-1pW6@+ʽs+m*bG}Akm x3?1-{-xysN6~OR^ T=J`p_M*u ]0mn #eI.`th`0xXrb{ӟgԟUO?>:/|L@ϳAXQPз~^2!Gpܛ^m}m0xþf SyRuyBԽp^1V,09=CSl4䗥W/'{ Co縊U'!l; yp#az`&pcQg̭wy zq`LClkA!U1T~5x ƅ:EHwj"'/hoB/f Z磦)uU@OTWꑀ+=BtR0ط}=ۉϻA4jxޒ y`$?"1jKk#x2ua!cԣ[itWͳ/\KxD30*R=9YӾ}) o<1QK];HA7HgRG ?cQy%^CXw{J]B0ؗ`\_,x6 }󾓑\|K&_}R| 0`?c_ٟ̏ݞ7P_4r7v: UWٴz}רּpwsw m޾śRG71 vU$>G{Emz.IW$0L*^7.О--4K~Z*k>0\Nߟ(Գ?o6h=N}Ao}W+S<Wke,mIg3tʛmHӿ<:!kYU1%;)u]=w1 %)`$sm=gO?)o+kԉ$O>ӾQK!efrc>lUJkb?c>zga>~KΊa}h0xFmgB}zR 3Q>ҏ<`^uΧh{x|!_woP&ċ3xըZL[G x>Ӟsa 1Q ywK}8ĵI,u9<_z}i0 *iW_$hpz@'7oGH~ĒB ic^~z;e-[xPCu~eb\5&hu3zR|<Wu!op_[{i 尢/GљuSbl xjqKڛ/zQW Pk%~v\ !'eCsz}>C"gMt-qPӓ>;x|B|+x{3*{z>d'{֋SYHϹxmeSwjY( iA;pT7oIœ=d#?Klc=C< M-3Ҽ>40W?zAwV0E_=<EA14$ yF"}ݝ#҂>yqv#>R#$vgeVc?Wgj_ȐіgFI{9Rg>~ s'7EF'iݛ%?@QF?=!N6ʒ/A:XK7?ԟ4\b,t'%Hq/i0 =ҽN6xc ֍R//I88q[X(gb=HwFo1h%aD̿ԏ3X-T#/ȷZ!A0JX)ya&A}s4UoGf~'T0RK-yр/aE0X% UdCsAsel֏+h>zcz)t\=G2x+ǫ 1m 1MV^ \;3"֩Ry x~wúIȗ/wƊ:bx]M0D{o Xp?A ,Y$c=l牞6q ) >= KaoW=_+DҜ[#I7XD,OI.EOuSʫF$1uO=i˘:ֽ`p'|{mكoD]M`X`qT o84W05,X\suZM% NXkVй)/rμemyx&jZǚƸ3 tx !q5~=Ju #]{FJ(??D2<]9&L?pq'󫍥YWKH:e׌g%Z/AEuW IW#Y$_( kx/S9K`|@ *Г+//xSUϬM6<\:0[rAqԾy-5jE['|lxnBӦcc3 ֹ(}g+hZ8q L^?cQ`~,AF*Va^iEںg\F);Cw .z/f??[o~Aon.iG!J[PGCT M-Kqݣj?ޯx/V^wI[5{K~I/lzځu_Os:2:;i%^pj$\X`޷'=I`AEaL(boiW7Ka=4?{5>q4nέy3GXK80S[~/ԌޭN ⟣b7c$50JY8oq iϯI!1~|\?j>y0ګ4' 0)0# =YX𰮙!ۭ>[~g$TqxSD5-xR w]8ol'E}6@kg:t x}PM˂Z.-$BY#a"E}]aʞBFhŒpކ/γӣyN柳Xt؆rn^1RMmʁb]J{Yb~`Oيx,W-8BXDz1Mw~GcTRRczB{xxs4hZ f!{$w갯x|N}ZJc38 o|oa{a}yWeƙ7& )<}Ho`=v AOLQK٦J=vuYI? q,Ĺ+7?'2_f΃Y&A~lXМ ?L0>hD|{M|м㹽 =" U1~I̓{5䷋ X:R$#~^ ; f[{W+$qoir;~t yh11I>ɂqӷU]ԒxK{"a[;k W{ɭEu|y{: r  { /=/c0my|ƓR C`ݰWAcQ^Vl܏ tx_bDHx.=k 'N`r5-W7I`ULw>nȎy}[<0Oܘ,E1Ҿm}܏& {!Xӗ1nEMCJ<75kۤ=~_۫㕆#`J3̧k: /͋Z7{eFSizJ[x6W+~F!V#9w /3/h^u6WmsLߪ$>tpb݌随ۏ|]Ĩwv=@쟢d1q$\ޠ x̵k6}\|M1&?9VI7aUȄX.\#S7 Y}#'wҙUovoI:cop7Xw~^ 1ޯ Cmwc}W ~3x]xuSb,h{M43xTz7^EF8ߒ?YF0[8ue>bouħj o$l$!U\.sy:ceK]Svn~=5ϑ؎k'd~++k즘JAux\9."̯Cbp>p2_x1X~U1KBO 9EW/mnU 8{5a]}.p#D x̞@={ (X[M[}' ȽX7X(vQ@ׯ6i#KU jw!foͅ}}bF:ַ[?y3Q3aWFW\C~Ԉ1M}U Fx߮Fg ^?o{q}瞎ܓO}X >FkHaG u%d_{_{a¾ 5m;Rɭ/[w?-:XZ( eI!<4T=?.8.?`¾_|ë=1o'u7ɾŅ.;eʼEYVNJ̿:`"-mϜuxlxWfG=1٧-zymH *xFKwPNjbH+= w%lEQwx} .牪Q{\7?㙬7 h>Ka@YFy0Of/0Vh$ZE McƩB_d߮.?>._~ Yʾ<ݶXS9O/d$0? Y([F J0?bwdv 1sF4^>GR`?ɗvq!UPͯ6oɟ"Oʗ^7ju|υ5j0?˾+F Ezs7hV/,ԋ)y,d %#ڰӖw'y E[^Q4oդzG ]9gih= /uT G `|\( c,+Lm/P evae.rkKq&ߋ{sF=qPexsjDe}=_V(J{ XwOlLcąpKdBYW/)_w~)tE m*k?׵~–>^)#J=f|14]օagui޷~OaBQ<~ͬWfۡ~;۟rT ˢә[ϟz7ߚ?0tp]H=4#YhBif6ۏ0Zw#Dco4ED)e_͌"=W1z9jWj_9ֻ(bv(h@y}ØߥXqE>Y9,l)xzؑ{lu쇩϶ڇ]="s&71ϣZH+\X[$G BG\u א)|ӵjoG%++C]{R.D e}=//:Fw{HŊ)H" }[k,8_&D7Eo7A㛐MF5ьotMjr߅߅ߩw1111111111111111111111111111111B1B1B1B1B1B1B1B1B1B11111111111jt 5:CFPc1jt -:CEТch1Zt -:CGУc1zt =:CcϩV͡om ҷ!6LߪFh94ZCh94ZCh94Z4Fh~Oi4?4ZF h-@h4ZF hA-Hi т4ZF hA-HhB4ZF h!-Dh4ZF ha-Li04J4J4J4J4J4Fi4Fi4Fi4Fi4Fi4N4N4N4N4NK?O,K?O,K?O,K?O,K?O,K?O,K?O,K?O,K?O,K?O,K?O,K?O,K?O,K?O,K?O,K?O,K?O,K?O,K?O,K?O,K?O,K?O,K?O,K?O,K?O,KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ$@, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KĒ $H, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KBĒ$D, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KĒ0$L, KTbJ,Q%*D%XKTbJ,Q%*D%XKTbJ,Q%*D%XKTbJ,Q%*D%XKTbJ,Q%*D%XKTbJ,Q%*D%XKTbJ,Q%*D%XKTbJ,Q%*D%XKTbJ,Q%*D%XKTbJ,Q%*D%XKTbJ,Q%*D%XKTbJ,Q%*D%XKTbJ,Q%*D#hXK4bF,ш%D#hXK4bF,ш%D#hXK4bF,ш%D#hXK4bF,ш%D#hXK4bF,ш%D#hXK4bF,ш%D#hXK4bF,ш%D#hXK4bF,ш%D#hXK4bF,ш%D#hXK4bF,ш%D#hXK4bF,ш%D#hXK4bF,ш%D#hXKtbN,щ%:D'XKtbN,щ%:D'XKtbN,щ%:D'XKtbN,щ%:D'XKtbN,щ%:D'XKtbN,щ%:D'XKtbN,щ%:D'XKtbN,щ%:D'XKtbN,щ%:D'XKtbN,щ%:D'XKtbN,щ%:D'XKtbN,щ%:D'XKtbN,щ%z%%rEa¿)"RYԦ]/"/ /`O1 WW??Xſ.UH"r rhe~@̿U9U8v)<'ƼZ:h2&Z]5+>1Ddо6J<V_EhGUP{YaZ,^9I]Ӣ\o$ofXC@/TAKb[.ZQ9=:Y4ro !j ! yջ$_Wh5Gݹ2GxXh넘'4Tq@[&UA+?_hZԵ< ES+Pn,<[&EsPPP YЊZ=M6e?Jomॿ=z Q4Z#ѵM}3j ZxMOe qKI@sήS4e3uԴV~+^5䷭(~,n! ڵS3?WMSMxKz QQPw,Nd !j/_ZyXc+Dy{QPw3׬MEtBBs9Ϣ+hwlb_CP&|MAYPt_! z+9NPx!Ze!8O5O *6K4+-^\E} 6oD?[7vuhֱq`͍"XV^΋ۢ`o령EsaPyW3Amž_pDS=PUTwKhKE8P~u>]*&W|;6m2'\A/wgQ<ꧢ)h=o54hEa9ϚkuEDټy(hE=D3[V wxwFn"{u;@B>ϡBy[#SE>bxU a%}D {Ru߇Z%A"T"y!w1+#NCny7mU]AZ4fKD4eeРDNMS@Ŧ͐9&A{wuf$!"xv׽}^sdCIB$r[ژ~#'C6ޏ he@s6;B _gIy}{eK^Wπ6?"E>9"nP'1 ֻ޻a^c<9/3v>ȞE:_r='[B? J"B4i([u[%ؼ"}k'޽jAQO\C3SO4 WmྡྷA;+Y@m(W*6qGs'7dF4fwmhv %LtqPS~HqrqQNtp_U*B\e7m\ƞKu^gaxBTB 41~r m- *)"~ŗO1;igV%K lfZ@)@+P=ƚWNXm.n[<[Z.7K9٧maøYl%Mhy7wWz]Թ cueZ]op[ Эh،OqRYXl~Y˂S?}?L(bm/NTӛ}JϠ Ŗ?#w<M|KKpq~Q(TovOw][yyEsZPP~%}'qC@Uփ: ף:'!_V-@nu|%GcPlfwf'E?2hۍ=ekoUɛj|il_"lA"grwXA3 %fE\5݄"V8'KhZhK.W kͤD^۸rG1O8Ўe4qWb8bզQF^`WفlOy[0hE3xP! ܜe\y }+O]'6\4u55s~۲dgCca~j|9;Dft_<u\n2*ͷ\ %~Alb WB 篁VAX! E̘Ҿ$ɰƬ!PUyWo+Z&wKT}ܗ~hkߡZl+O$>M@K^ 4[oHMj/p?Ѯq7WDS"̮Ӿ _FvKkytSW"yDtfPUܲ'!Z(Bg@>_K^Iñ6bm;#Zyey=';h7'piJ-]_+ŏ'A0^@EUb22; sKhɣ)}ׯP3ifr3|s]/%2 а"3Z0{OX|4 Ηl@?WP~yE]h-"k_56I?;iΒqI9ou-s?TC'Bܔ%G@ؾ ]/:;SWH?} LPw /ѽu6C?w@ϭ f.?vn亖-1?s'cv0>M@r@q7c. G?rmz+31V4gs4 Жz Ut{×Ko};a?+Ѹ&mu\/Dm)@ODF;GyVQS}nqyzV祸m'䞗r^ u\=$q~}hQ?H{n-T`~?u@u|Ne쀼޸Bl}h0.cөHcK}ߔqu~_}^s(kG[!N["H(ho9.qs2NSy~Wmh6Dfs|O`Our?WE^8U_ݤø_2ުC>j0>j̞$6ff]`?&,^"qGEWJd?S/ U#fbVtv)z4)?x8#8Lr q f@fxCƗ{؆ယFyqeOZcvf#dB{*DØ]-D@-h6 ̖}P}Yw/U?aG3q=d<>7wKy>}.y]ͪ@/&y|UC3GƟ?Ԋ qrޖ6~:㕹6T6|I=zswKj`CƏz}MHs@fod\ p9ZL3~}!Ux׏T?U653rBےBl>~ꖠơT/GQ#1Vlp7/rj?BT˞v6i2ZH'T@//֗2*!{^:V[̯CK>u*c+/l}zm|?K[ n%eGfkn˵hW&[-M$2B̚hgh:6rFaovabD>CP`|X}qz&Z;70fߡ}]},2^4/Si1~@A[[χ8-Vɸȯsh_Zj[>_qო-h+h?e}3+Z iϐvxQc uvϥcZ=)9ހB=0qA9OWJU+4|ϴhglȄ#xZ9ә&2{S8FkѸկ*x{i7UMjG`E%n}K.%KHEsq"eW_M z<~@@qܟ6܁|z4}G6˸?h7_m<70~v|=Sㅘ:(~6? J6UgHCp}wX\Ix^f_ٮۈtBB \X&x*f^0k[b܊7z]!rY pu<ˮc-»aaPn, wD! CZW:6=MD!y ׮x[FԾ#R416k{BTRsUf.+y!AIjF1+1p^!shB~~eIߺ@{ٳ@4]g\{24]9<ۿ Q!tM/ox6[k=[) B|\6!ZJpOW&sIvW"dAjAHwΐ1Q4Gfd:m^P \+.Psp2P\o&Π]!u; 0;J۠lDuHnk.k lf뵉 =J\\GF /Źf\y _Ict:yLj6 n.t9x/tg€0PBgh*O=o\ϞxN-+Ēw"W d ܝ80?ǯܾr\mU { !Z {y%Bae)ۅxx3PJ'u׋(x-Wtޭ֢-sWoi 3gps )GܫT#_q!3n (*]blyAPz|;|?d Js;}y{k0d QHye-H5cƐZ8%'_w&]qH' @9&k@iyi*$OM!+fGlMu!e W]\\ cx;mp]!P!E4v'L?r\e{7!RxZƹ_s9MPƵbT%/붼FHͻ~B]w !6 .pgzɑu򂫙3;!cTzާ 2Fai6A0./CN/*Lst b6/ck:1(\xĹ7/Eהl~3Pڋ(. \A,@h<31Obs6\xl!}M}Eay,8RIrܑjvugJo[ ɇsyf7f:WYl̞9(Ķ]x&̓s?|UqϠLcFHlDfwXPFb|Աi&6]go=+5חq5PÆFF;x' iøKK]2nM7\5:纶[qe..=\Uh1(?G\ӧ2r5iyUtۅ+zh>7x[ 1.KX EK/+0w#xǸ>מVB\C'rEo sI/cϯ(a>d(:[.ϢԨe0}e}[k30oxVns /Ejpa鞠,ϻ[V?WS]Zng2h\e7 WWO/oe6LvՁ's} h{b|Rz3غ[̤`ʪBVR1*'Ė!mm]D7p?]ǂ+!/fO<_g=̎iCj:B+Y^<(,!jS]wTmk]fȬ-:,^MѤqB 1=4 1&6^};ٟB2Cg~,-^n4 i +7s[+=_=f/N$5p0(V2JyUǢy>xOZ^XV ^ 3ݯ7_䛻Imehvz,$g{gw[? (an(Aݏy%ZaWWckUWK݃{.oҷ1-H^^!ۧV|!X2K, <_9k^KcT55xZvc|WeCZ#! 'A chyR2sNl) BIuǗ!߄ޭp݊ l]SH*>5@ڃoI,̾{߈>k ډ\cҾl^\(f>sW^g C|<" +*_>}r5#f/">/k{W 5S!3Gʳ瞮ە.3/p '")}x[ZW*{ZCa'u8Q2W06|" $ħ P}h޻B\q%_z}\P(([|sT})ĸRhiy9v= /*9~+oR)m"nf Zow}Վ-E1T|(]!cx<dׯ, .?\fm802sQbABSn[FrQ>~ bbV @;^}#އͽ#B渱\ྔpRPZaV%d>RB2>¼ǩ㽥 )Oip_Y&YƩ6xgPo.L? ypuڠ,'z}!^ 88N[)K.h^7$4s 1h25mvk,nyny eOpUː>|Kc_q](ڢA5Zřۦj>ߞdf<u'.KOAi0ݧ Dy?%9(ɕBTGcjx ov?|󑛭C̗sb3(e=W[⹌7ڜEWOӪ1)+B઀ڽv?Ř{6wHo׵c!5k`窄3@in^ȸ\ڈk1풳^!yԗx ۯ0uB=3`=rٿjdxfX3ÀT\ò-G%F?0f{ W^ |\7_c}PPy|vB1B q8p)[p=bO=GsUAwc/M9>'RXv)e9R )D\ðo⮉ 8ٺۘ]o?׌[ 8=\2`\ϱ~t+k?׹b"<\mۯ*=T:2 Dp_Vf=S/ X1(ĞQE&ʹրKY+nU>_ޡ ϞCwQ^߉[×' 'V8G%NR Q).3ܷ`~^S/7g)N1觾mg.׋?Mixɸ)vw|ׄ"xqq`lE+Yev1w$Du.Sk6|3x\qp~H厃wsl^א)WxOcW7~fg{~7W \!&) 0/{=e&Vo/!#!~ 'LS C֌*G &xb\Ey~>kk߇\>axVM%ԣ& .gi^oKڍ@ܧ\pk9n`|3sH ]pq4㚱- D~쮏,ö{K""Y{W1KF\3R\6sT,fiƳςvi\H"EUOs ÷~GC:a/q9wS($ X'irKB0Pr?{ƳP!xt!r5r27Cz<뙝uwz!㨼~7HXu n6NW8E$w;'h8av 2q#G?IoA~.2 Hh u~Q)bfspy-y/g3 T~hh*0?>_qKu?4ogptB?2l5>!͇q|Ϙu?6sWOס:K9' =) ǻx=O?/?8c~ZB;?j)8c\!7Џ˵d]۩]<+<[v?:̂浧躎Ѓ#o۳>*mczGM{0 YQoo ,W| Lb'خ JY0ھWV_|9?>SOVzkujO>Iߏ GlXg4bj)?fGNa;] W&W>.Hv 5gH+@_SG)u1 J[ϊ|uə9<8k:pZrT.Mʬ4}̾;̐)?XNW+Vj/c<-u'=oleG i&UYPX.sxQ\RBR[o!>6q3OgT,ػcv4:@?~e.~6IҮOj̜9/ |g1ً-3یB~*T̓oڱ .~k˅=8ity8}Fiǵl=vk=rZ<>ĸ݂uiep]dƤsf๟:۱ʻq9,9hcp7fԬ༂uJߖ>y`5pqo&O d:jIoL\gV-v)ۯ?Dµ@- 50|7e!}GÊ@mWawɺLZH̏y cycݞւS'g%3+WpH,7'[L\qAB o1֙M±FOo!?>Cd>M;I/>ђ֍Gԣ( ﺿüW,x~Ges';w `HzmÙe+0^ MyΞ"˽ ђ5n]6i?"7㴎~g wQm/a/TͅsمkBWȥķc*>/=VA~ lkNb=[ߍG@Bin~S?_Nӻu~K2N1?*[[5?3 [Fp}XuSd\wBR+9'ia?BYOjs"_"}zxxI%H;-:œq /JRr@Kba~)ڇIcDg0>υmq}sHzC|~@.,Gn탇Usc|ɫs<q)̒~61x9nȬۄbqb?w2x5?dohǸ<J]:]]\ &'*b7c?*%M}$eqB3^\5p >yu6'|yă xkq髖^bF#l=/-\넸48rt==GHx2Oa\vSV l۶gm&q1Iܜ 0,C\0c1P4b93sAsH0~aPm0֋8=~pJ|'cՁ;xg9m-ۺ\7[{}r\UDa1$Tӡ?}u:q\;86_K)ʏ;/e˵{I5*' 1Ivr"PWlx!vYA6$?+8PR2sܕ|&vPcmOx1Xݞ`?hf &(=}d+j OeqBP,`vLy_)cdw|Ͼ6 \h*c0ޖDZ?i;v/^Z]p,ºr6-nrx~j[ϥ?**A~El9R>V\9{פw{^x|hǼz^pU`f7_w6!1U6=į~;{S$w!O$*8/21I:Obe>0D+ϤR6eB"gJ+|YU;gmw<{ <񔍟~b&qӿ9+Wh{ *>!xdbYλ{Ox1,?^y6ix'7ٶ%~ӝq@GHΐ`Trq;:q9 )Ks?6Ok78zM p-SgG/8ܛYʐ!OT=VfWR1v{psį5C8?\vp\VqORx$|bmػzJW?a'2n׬R̠ .<+ 3ڱv80ot*|!B3rG= ?@y] +d+w;V~ZgwBh'~TD bې8g*7{Swho+0( Jh;Fb=RR{3h;v~?A оqEէ?@oJ*q qJ!SQ Vh:p |qVyz2p z +'}fnJye?Pg}q+捦}uYu@JA2#gb(Ř"ۜ>-36?y;A.x?'W~/NƏfXu-Hs8֕'wC]TǸmf"OO[y4P{{ʏ-S1?H Z>:p3Gg!(p< .GȳGo1? 1C1kFcS.?IzӤ}WpJEqfB?<ܬB:$y"?$oa"ps[ 훰ۓ+ZgꎕȯxT rU9=gc׽Cw;ฉ"^{ ~Qo-eg`]7_Usϕ-{Ms 1h托Gh#fV3F:X}C$ +ކاɬ*55TPʼ1״beG6K:,sG̓YȏۀyOʼCY܌Ӧ|1+QY[}K v'@WZ( ڲL~0 V/汙H*WؼiI!f/,f^Z_ 믘gvB0{k[.ts(K=5+Xb}ko‘2,Cb7ݼ1iI<@<s}f]o x9uc08y{O/ǟ45wu 6žtfq,1?|wY-G5`{:q Ly~#C;`a>5c?l+nE<<6^5%-Os L*'j/,2:`?ɸOYo[ўdL-g}[tLsel/7Z3uU AH8Ebc[cKoz- _V#~djnàs`y%d]9m8̗)g kW̯`}ew`fqwoys5ߖZ%Lh&LmGsQ߷S3v_ڞ}J,Xc3۳s?kg"` IMḇ;^l279t<>sYЏE1l=#?ct`]j `V^~U.*9]go֎I)#޿Mӽ~YX0/*X52c.1֣i;jLKq̇65¼ W \XX֜xnG`iķiv?m37 ֵtxi4eĚ0"}{O۳CJes ̭yL̜`~G`a^vwJ_ 2{L$yCOnBgWMs62 훏;w1o ,?zc)l~ns<~<Ǽ&3f%_$}ۘl=XkAP{,gk`Y]7{yTZfq1"b+acBO_NuҌpAhav6WtO`zϋr.C&6g[oò K)]e?x^dYu"a?bf~n,5φ9MD쟱?uX~qߴ4׻ 7ZjIjSGy0/);ꉘH}b2!!5x5 Ÿ97X88zCqxc ghvF~Ϛ/g[qk`9kZBK0t1?c?isZdUX|VR"_vAo &i/`}i-{[;wG{Krfn]XOkӡ?w1{)]c~nvS\C¼>a2죗}-_|'Ļudٜ鰩/lDd9)?7i?+˾ ~78~yl;Z0GdXaq.ݮ1&(0M|KsdvF!U#0ú}f/󍭲Nv}etNI1W<|Ǝl`=lxczك|>> U87װ\Ҝf7hcݥ7vƽm̬*߬ןfAۊq"hZ.oi8Xn}dGoW̳^{yxnnw{I L5yl0BS#@_չ76ڵJ 0K]5B\O^6= o&uf̫.< o:Ys+27YNZvاy<XW#u>}Vgu$4"Vv̾Vٗ(7"k63_bU_$3dnf˼9 þoQ"L{:y-`=uX0k&"1ϱo/1%aݖ[Ϙ&(e|آX+ sY#JZVv$㌖0s[YiG~u=#>x۾ 088VKQ^~e)ʰE<4 \ gy ϣLrC̍II3~Vg&oL%ۮj]`ySsȍ-ǯ)5 `*~fq,-Lx"a<7}3fגuf[z1eߚM<3)X~@{+ 5~p~X4_kl"SU;L Yíqb؏$%㫯zbwbY:?yZ!&q[[n7O>>幃bc>ATpK 0?+`vŇ0&-7PS-U$n3ikXb(3؟z fERY0^`nqdþ zkZaAƶ o ~طr 󚦲&7r ۗ7r0;Wuao<-" Yc` Va/`'`Zx-31o˺ `Ɂ֯LylSr!QW75_0xw./)4žmD~PcX3aH%Ӌ'\Yc*cxqQ擌[JĺQO|z-n-.PYkm k|x1i-KnuRua~_,qbsgv~2/\Hl?j/sv`Xi[^WwZ طv`އ;\Q.ڛ:\4eQI3;ύErS؇ٍWABh@Kr'Bgz୴7ϛsp®^& GA`22ا +~?WyquqU߁A˱_RB1|wuzX{o:j`!_f^ۏVV_g[幛c8H.[wnzB.v2x̏ۏx8]Ql"W=6PAYFȞ3|aY:geN$a[Eqt8rtF;ж[iYoC=u czAzAWYm;9_G%OT5]ɾI70ڇU:6cG@^A¬ xy+۸w q'㹦wIscp$%V&\װOs4O9t(7<|q2~hSf0ʽK;,]OS"0ZxZLHM l`}{okWc!Y9bųc:txNi :5c97}5)\%b8~6>I?uTn;/NtUo|M9syu-g6]s.O}mk8?q30/,nB@,?[.moqaPr굧e\T"UI$i~@<. *$g&pNy~~QJ엤,/X?̧sx1^WaV\ #8Fv3R0ޔ~nOqfaSu|vԱj= u31?eyUg;CnQH*ulW wTk <^㨈?/4V!k[uS ?<蟸>lVOuyE ď~YɣY̣ƾ%_0IIp/B,U8m#b< ?ͷa]GxPkԵO:ϏଧfqUW78D{zp9`˾xn~MUcY!]inYd;J.ϩ]QfB^%-ۯgk^ <=qd:P(Jl<9F`aydٞ瀫mqF_$웒]׻ N )"z[Gݘ%|,pb}!?_ ,<'c'<tv3"8#s8OQv+~ wv[&w8G3Qɾ%ߕ> o? zx^O10820$}}}Ox[vRʉ7.k}::p}}Pg>rUvsAr{Qʷ=x+!cu (}R'٠T;vs]Jh:O! (\%鼙3l+ CQ}VJNTM% M'qN*:-W PZ~ R`ųWatO`_o/nqnΞ Ӟy&;0eKu|dpzwve܄ԧ`0]R$C6_*`huE)IM9̒y)A&8O?zԖ\ 84=&w-R㰮?, 8&<\@Rqwsse_J_sURys8E {*~Se¾Zv]zNq U^W} >Y뙋 nynI; Q`;)1)l4%LP[7;!%mVlǾx@;[A:l of۝f@Ғ/G<.'z~WGoz&8.} Dn$CC;Ve .=_]Nz̬Wuy>Pv`;2g_R4QVi.6,9:dݎWL= < [ :}N7 u\Uqˣ}( lnƳ^[c0O2[v_:ط5Atw>jr*Iz2WϷmYq:c3X؂܌vC: 8hyfpWR OMz}"6c_l(>v`]"0)SRznx";'tɔ/q)2_ͮ\Pƣd .sbv:I$/\+>p}t/4p|qʹXȏ;Hg๳'k;̈́qBۘYw¾hw)S,O^3 sye?, L8s7VU<ðOIBSu6Y[I|6\58c2{sO!2W:o`o]yľiý#Q ܜ7聴8̓Hn7O@_/Y~v8 ^H[ؿRyunb61/݃!}ܲ.e:O gyc6sU)0>FʘfqBCKA|#vopf~HoaCs$+.-_Sf.(Yx=Rx3ni_Cez #H؋V ,}/aߚؗ@ʾOt8 s1Eez~{EPΖ}] 0huP]_~칲_IWp[ l;џT:q"8:u~xtଋ݋/ZEb8$m6hxd]CKLXK⹵}7d<MG.5=," a o؟;7;racƧ#o0*[8O]1M*%W(qwǫ؇ulU/Dx=1kQջc~9|gs >1嬁"yLS8$H-|ӘoyH΅8b8OxtmPC֭*P?3 uj 19 ǓeA%Ayՙ}lrKڊn^ve:A$Nf(31ne2 1=|> 'xngzñ?e/<ԥwWeGOR)_8קM'¸ԛ}| 37|SoEuh:[xΙnAֹ`<-X ?w*>b/ sgʯ_mYOa|AH IT₹QmR}l9D /ǹK8zB8C;I^"uOŦ.?&s-3E7~.?l9L<1[>|}͕_-ט_#g1ø/>Ηo<:\(Δss}+{.yLs4\!syϓypwE'0X_}4Y&nY,?g>^;Q~|3 y+rY?XK2:ȯNJ~urL;W~%u/77Y&aْo+-g|s|5x0W y?^|NyxN$ 6Owyn>33S~\g=x'nIm3zY,ݘg wc^v,9=W^aG-@>f'ccߒ=/,fL~$3îZ"g11irey|iN0-yo/W0汱ȯk{s.1xc<y)Mg؋68ooy,6y}Y}':|oygg5xes ¸]'ϰ ~̕㯔؟p;+_gwsv#B9 ^kofc쓆}km-m#}1߰Kgo0n6yD:FzثFW8xqc7_b9i_z7=FFߕ>aM_Wv|:,zcٍ68mpT^1? {%_eW#^fWƺ;7 Oho07x%_ְxߘWq!~6y0[i#88}O>]}00+r<#f; _l3{U7~y^Wk'amw,[f'ϰc {ӈ̈Mn2mF|Uz001|#Nc?(,,_c=2o󉕆/?G~2x.L5hp_&݈;:ϓg5lEƺ3xbg6:؏ ~}ٰyfs+n痆_dػ̰_ {aav48lo&qNg+Oik,1`델}.v97\-?F#igOϑxΆ}fFUqgFʘy/7g\nuin}Xg#$>Ӱkmcϵ8V%SVg ͽRQ\Ħx=(j2 `l'ii2lV6=*LE1l/6!jmǦ7uO~UH*If}kWv %lv@f+W=G^#HsHG)K_>kݴoT!:v`?fn)Sy/@jH_򬥛!k](sa~w7"r(ulЉW)%T={c ͏'3Q|~l-mKd W|~ba[ݿ=Cr>]]!9>v$ [_x|,ֶ6䭓@zg;6N{9O}egzR$:(fO⸪ z&/;0(ķ@q,иJbO{$&\ƻE2֣ކ]c&7iS*˛ɐ2kօ@+eۻwD CI)ok#(n/@ \-ly3(WE3B>(*oMp]y巏+r?cWm("ks0wU }a!֗U|a`:Qr>D12|. (*rRٵ*(+P\-ceu\ >eoTHڤ`퀢Y/c7E7zHW& ^`<9*n2lGRMS󮽑y׳ :n]Qj>9_\w1kո˝1_Lz omp^GCZl:yb}ʢUBf}kfًFn  ^|aEܲPb^~XT.q5Bf̜tto!D^lXU3Q\ЛM=Qtqlf IP<~E m{pF8ř͝ @q- '7y# O௼/C|r y=H)iwsgK_.\- >o c)uBNA\9AhoO-LޏG8˰2ɓfcl;^b.83vasp\䚻-9?Dߥ\EpMwmc3*Wy]pyoKnхL26lS)*vұ3ց?woæe(zRj]-o۠r (2{R3P9m&4g+qo"OOy f 7]j,e9P;folvO%gvD{'r_XxRMpEtlU 5j@vw>Տϝzh_bG4cx09%wEOoH/gmlzy;q+BwG2 5m?r0>6Vd3R}۽3HvVz]4EwݕKO4bi u(ـ"- oZ (יkTSUgS=\ܶEc]+>Ͳ b7mHb+.C)qYਏdPl_`/|Xnz_?[Oܸ30HorTv &Ibv$鏟[6?b i8(ПIQ)|->< d;[_Z`3쪿U&ѯ E%:^tlqP|D)3Ҁ_gNYW%7*3bI#v=(kab!=E{{nnYO[0 TWԟ(u2߇d5͢y@8í!q,զ]T+(7ngH?f>j⛖V$'nPƘ턖-ɣ? 2~`[(XnwNX72(SxQo&skN(!.s,ؠXFͥ8 ljՖy@G/|e{7(zBv3;'_f唸(C=+dvQq3'6LY94G&GBe~ 26Mu_e4$:w Uh#9;N7,(;` 1V8􏺓ٸ^Z{c7!=׹W|85m+ج;n5(^Y{jN8nU0pJ{=YPJ27cSpxP3mPb0UeJqm}䠍 *E͙(/3WS?$җm:osJ;((cQ& {L; q]u+O2?`,y?Sڢ-̵@/\#W=M_;%Eюt,UȖq9pݕV?󑙏lĆ֥d]y,9:&Hnj6嗂8/F1*ߡ]=<D*zTvdJvEOP=֝˵w!_8|HV,smcv)Z (rH㓒+\ o}^|p|O4ȲJL)b4GDϵʃwwcows~~Xjc~dFq\;l:T9LJȿ7[̜l5|#?櫐yEҎ~ r0Ki0-# 23LflKQ4"3a_Cz(E}3Q5!M;e68KT 1_8P*!sȧ٫hA1z4ɐ1ØSOEhy4M,OQX՞@%g F!ȵ3Ai׺7.G;S\\ X)#F<: ffO?<721N E\:R7㹒gȝo |;ENuDU9#S"EcQt/F}߾8(h$HG)w)8ΩZ$Ol~qx^Hf7bʲgVKqKk\ Ȝ]_[q̘B%Br+>]mq+ Mq-ւ~|'Gqx`78o&@zͣyҤLbȺ pxe1.i+QkͿl5\5xp/ HohbJ܋K+Q@EQ<0ߞځu 3ER}V\}*?sgku2_;sgn}Sz3few=΢ Nډgk?0{2w[ l6&z+rw Z;mJ.k *_n?{L/d.pN 3K ,[nz? ~.dțѹV(&"nn5qj 7Zۊ|Cd9OlAnE{ҏJ|>6lm[r]`mmy&ȏꁽ_p ٌqq @|IgنJe߿d,r%#ǀ*ڨ{@2s2~[lV DgEr{M:2/vQlȿZ7]xjH N]WRPϗ{0w?AI/۠w @{z1} V,?- .M ~zf}"|pI"‑Nֵ(i*0ո s"qGm Z*+g6jW(<˟ߩ׺?QnŞnUB`o")k "*ToS+#i?HޅEZD|j]~nm8&R 4̑B1_P|},N#7~H#9U-R-h9HGoC魊G}|ŒgtwGHpZE#37Q$J|+7{c3#y3 GӶK04kFa=㑁H^e/NN}w_Һ{פֿO?QjlH g$ȓauǗ"8G$ڝN#=>;n|~~H-#k)aV$D}GTN%#7o0['ގ?wMJ*&:~7#y[*7'wZ7u=0w:"w4~lݭ݌s[xIK{C-9Rh W$b10*_G'qW#yO<=tg#gǼH~8U%tCJ yrcݧVZ!w~ܝz7jΞηF>&D";gX`㿃f?o{R+ D^[l$gzV6MeGim+sf:,xY#ޚ]O$w, "ys5^u +Ÿcd #w\ |<'.!g&{kސ |kj>K;^U]q¾+vHj?F㵁I?}gsq7[$Jn "y N쒽3?:mMo2غY}$3 /JO~rvEjזq㏱W9hv~lHA-G |G<[3Ϗ\^{eA)-yl𴄏#O9ތ=gW;u]t'_on_H1)xoZs 򩤁F5mzU\1-]fW]H~;߱-HH ^4=ϔWOD*{sbG$l EkZzᯎH;SV s"w$fhYKغtZql+䦑"ɏT3푂`{~mOu:~o$Vj'Enu0V 6_dzK7ݯ;ʌ,MCTZш>au"WfɛW<|\ܓ_ePlF"8^>T7?oeHwԦGFg|xs<]D >~M?6U}ogF'gz4R0h~l}NrhRƧ%CӪ"y6/E Ls$jʪcKD?.R;׬㧞O,vel>;®)ZU-{<["Vm.]+畭2FE GTa_#E'4g?ZЕ]}ɋwUUfs͑|3E]_87?LEܜ2-)?1̎lkǶm۹m{b۞ضmXm9j;kﵪgfs^|Y>vg]@FKJ7ܩ[Ut!kA=P/[w`LQxow~26?EOU׫`>pdT[msiKكhBsO9Ռ 2[wzI Iy^Vef QS~r!]U5kѲhҊ3 97Ky ?a}9F/K u#p̲.UZ%VbwҀkb\hɠ;ڳx]4 g2c]KYieQ <hXwN͈ ٱXBվ1t +&?:U%}d`XoO3e7Xyy/}>tЊ-PI \O) KcL^o.&h[$,7+n~ Zhߺ5bʍO'a=hokk7T~ϷdSV} zRӷjAɳCc7UhjXnNbwgS/776x?\*'eL+vMl[yѣ}N=bиܤ cbJ1&2JɆq䷇moWc^ d]rZ ޴ߋ>=zUYǩ%swFū@3b6T2UGwBoOMO-VTG6uN0m2pxLr-V/nwQ0΍a[*PwK n%i :EV Q*b]d7ؿQ[L {mߌl;xuP ?7w_L}s`c[1}֡Eo?z9N>irbZhdibkqntº>c\wd<{ʌ8?:ὕa5܅y7Za?ڤ5o8i h6W=S_FcѸϾ/5yvO-ga)ڬԻSs!/- fjTbL[_VUG^J+>-Q; O~ΤC=?ÒfZn~ll1omWA圠vɕI7ۼ^/8R|}bߐw5|DS~N-;n;Ѓz.QO+/_ ?_6Hxr]IqX"pl(Aqɉ@8{T_??Xa8xx_\7Mi{өvqW\X CAQJ4=uu-^WdXGx^R_%$9Zا 9(F˃1c.?w}:o@3=ߞk3vji0q}i} 7:6{;HvfPw1~LX@ zaf?ցo'v:Sㇱ϶28Qaܨ#/(O8LlcxU16WÁ}gX5|6/M<>3_H 9Ei;cR<ZNxSwk-WT̿.oadH{~682z[7J 9Sް_N[ 6VVۦL7`?5YncɎuCfw)m.-euFm6Kuʈܭusj*^y.kz&_[-q:1XyAx.>?-xǍkzcoI\n+dI_lNX?쑉<% ܊OR"+coPoLznMΒcpE;rg/Uu@ѩT?$A {^gƟ;owxݙv֗[D1Gc|󳅯 ZA[u蓅<v}&c^oYU<1}ZOc][MeZs ){oi~eY+Tlϳp+rEgtuk~9Ы]8jZ\:z{q"?/ +u]|_; 1ŇWW2 ;voykq~:ٱy~uRǴ(މjOuq@[CޘH޷5_5+gTC^wU;9WO>FTʬxw'tiE۳ȟv`=.8fE|^N c./O)Ȃ70`z^\ 7Ej*y+jFK٣c~m/A90.-|/2O% |CNN:z͟%7q?:|Dl:)3h%o%kj*H,ސ;a=Yò2;ƧbILAd#Zƫ<eًZp̳㻧OpWfVӂo.}6ثm[\LOXnxje]w'"56# *u{̿vB{5ӆm{(a7]`2y[̛o&&Mȼ׮ֻ/[xűa$ w\zON~80tC Mw^v5 lR(?t=jo˃_f#s l*b~xN{0ÀJ΂ip_Cicly?A΄_jomq-Cò⽕X>?FnG# gƟFtӃ'~ja< v+3W4_ղ`?er̿'/Q_ߋZ"bT s7]ҮbP 2ƒÓb~&9Fm›6EoV rp?n`}%Fs? b2猑OٮHSBϮ~rt〶ʂuh6ހ }{} L ^r=놶4 NW)ߛ$Bb, žV`4١mm@gܷѾvGoMo8HV&Ŗx?dǔ,R<FALu3 Eې1 $-ܾ"$\!q_xn'H ߋ ((]#AlT0(~ GEv>ŧs\_6H pESF󂑮e+Db%3~3F7o _A'-}(ng0F0,5Q  .FKQ `x+g cX(D:AD`!ZD35@I3,M O B@,[t֧߁00Phx`q ==QVGAHՈ^u@TQi0Z 6x2|Kzo{{.'yxc{hO@R*.pYP‚bѥm`pj-3ɣ[E7qʒ^EK04K8uTaͩ ^UoS@Lʹ;nEkɑsҁX@^<7?K1FBұ~cٱ!YM~R{e0ycz*[o dr |#I"xBɓ 8JJR<806 oU8F|n*a1IGqe<`R;*oeAT"3I8$(_>A/ Z?D=BW`}+oo,X0?)2WDj?1Ӏa+H {L3ƳMoS'"0v^|Y\ wy?^#)Dzy2,h,*APC.fBL @o 3:d}8wZ|Q7{ 5гX,_<ԗlzWqf~, @ϛqM/dϏ8F'ynI'{|)7\ybI 3 ;!תg0 D"뢃tR(_( [xx_ )+&; DO()^S❩55#BMO 3fH9 6{Ɂ"TR.ly|?l{զ (5mt%o 0:[8@W:37^pK%(wTcgʶ`WK`(y=R Ϲ|AWO0&( *luZ3' U@L0[?^HMbga6O"YL\ˆދ2JOW9`T߃yt¼J4y$o:%yreޟ^%RmWO;G>)Uh%|^:`i97ɀuP\ ˮo^U<]|`ϝ9eD@ 9}/fXw)r;,i%Achċx@WiqNYAx U0%5w⻁:Ns@?U%x> !05aݬ*B F*sc}PcGu1b|oS[זQ:$`VZ$w5W+2g#Q]smT?㳤c>][69L\>* {J  o⹂[AGcx.wv{@4m̼N>xc6Vk9x\¯=W:Q`(xA3[ ba>(JTں[3^(ˑd|n9c};@(zM:|}eh ?/ cU|WQ?xoR%zĽ,8_ ] k!˔Ty0%WO5 whW_: ~+Rak0/5]U$1 E//}0H6^[l=(φuၐY{7(@Ko|@Ak ֺÒ&K E#ƾl atxX_BDڿ;OuR+.o8 ,6؟T8zǾTѳl`WO d0 ?GJQzzkOSþRh1$8RRd1 JpBQ1(">oY>zΓA."BTm9Ư-%!OٰدEW:d`(>ɕX]7ºtUl,= 뺏nŧͻ_%2-nG5>Uk'Y6q|0VYgsw% *}jǛ%ˬ\$03>#[f(R0,frS*P ((Dm}c!~22"zY|R"#ߟ){cU9YɁ11 /y~0ӏ5~|zq{? +,wR. /eN`ƿ{̋Mxo1xa^̒c**>J ϽSpD|VkQqo, ΔYr.Tr5u@9!a#FȐ0_@igPRS{egě|j);=o"cPWpHJ^uoDm@I==1pi)4}?Yڤ#}r-+=\ʷ`)6+}v-ϥ&|E ),5뇭N/i`޲2Kg`,xQʏYi𽏇QU\$uwaΉ'>e[m}?&ib@kWK7]0J82{k\%wR0bY٠`:!3jT ĵ M064Bj,χ[2;LgV^ FU8X}]XoS\C`e )`1QRD cU'uq3ʙ.XO/c,Sf|J E+M/#ǿR<ߚE}xCsJcT"iX/RxO *BW'ӱI{=T?& >9;7R̷4r"7[].}zio92ReCx>K7F ҭ|JXWr.-Jy$eOk.F݀@Ip1N0_sSr˛pZxoK}^:b=t)w9YzpgnoGtys: qWffy'dd%`sna#Ϗ(u%ڀYB.$wQ˓?A 1^?}ZMK1H{_ |`*v&͏s.G0| ηLϵ*]J 뇆I_ZF 2?B /< [D;R$kt1Q F`_+{?|/Y }]>㹤YtW50^(KˁmJ ڊz+C9'^O2 L p #;`oσ/,i~*ڽyϿwԆ\P n =L*hfՆZCG%$͞c6@˓#;1uҥB]sy_ , εw<[7^m.h?)0hjL 4o}}%Tж+x.~9/@ ǣ2hR/ +Rlŋ+ڼl^DA d鎞~>k[&i-x{YR;3ꬔOXJBяmǘ^l.Gmve'_θV _&$<8r$ xTs,ϜrV| xxDl,2)c.+hƂA;vf.hH@x0]o=GXV力eyLɳZɸO+>9m̟5vy%x9ѲZt2^7/d}@A[7E@{q?+ٽ)Vy%x`$'{7 ;[nۊmPʍMRjЀDE\7͖QxEރyQWWRj'g3:6G׹+yڭró-9О8xש9 ?`ԵӃM]#~gkhN@h1ڣ\-oY[$~PBA'FcLxZ FOˍ#bE3n;~]k<<{Du:b$?uU3~LK>ﵬ'AS]xkx/hf)s}~DxAg\Ra3\<krBhq>Kd]VJ{(zƂԹ.mlo:Nޟ_Ϲ%{4VbseK1"Ja#i.Z9?jn{>+xwYSſ&h3% <𾥈ZJ' 4)M T+9x.׸9qfj3qn{#qZA ^XK;LKxq}bbƱJΝ^mɋq3|LkIoݪ6z_bJOv畯ޝsMf1.k}| ;‹sXdzE@S2XoCVǁKٰ"=,ǛzrUzԪ5CKx x$+h|cebs4R{ 僲n瞺<2A.xӼ{dɞj뀾y 'xZzL/WUу xniw8ߓ?w2Wn˒Ņc}TzUe 'jcR֯> ?L^K9wY 6a^+V8w@afGuvfRh%^εa<;cؒ٘7eBsSrQ/ރu:^>[W:8q1.ݫ^(ܒ6`%-'xЧc{NϏAW_䋥c~|1f@3aT|Y UoOKbȊ[_2l߻k6S]#ާs 镳LGoz*ި01^L$GSʚ?G Cc\" hO\n\<} J?1cU-BPܚ* Qyd&dʜm]zޣyL@%މA/ߠV"lv-%% Rھ1bhQQO|$MnQ𖖅ֱ _Y$;(3FQr!xֳrw%'i^k2f *`|GJ s~Ĺ|oihb_C`Ma}OG{~īX/㔫SSNH =6KizA1RKF{y?9括פ}șg?>·7Ozo*CH1xTetmF_,f`pŘO֮,sϺvzqWb~}N#Eh>v3sV?ƿ?1&St?hܖԠ &d c4PuoXy"֛Lj5/=ұ2gNL_iw}j uo2u᫏c=?%ƃnD3%~aZi%ZߎُٰZKW?żp㰮0hx->HOD[ٸ;."!hE?Wn?{IE%U'ëoH)YɾO3O6#xjXKO~Lִ6a1A>“uzX'+rj$R]]|~ 4ڳ1`Pm{d>֠xrq, }88_"::x٧ `qyk`|o@^+4=߶J+C6ٻݷ-JGv1 .4kboUxX2bK!v'R+OL|^Kf˂Z5vQʡb?|*N| ݶH@[p¬{xo}fi9}o&La~m m&/)[Ү !x6[< eE,窯80֕;mGi/7,3g?>ÖZ7"jyVnnù%{3RN5vƥބ_k}Epg7S1scdXJT'xN/=mcdx?Fg=z3Nnuaê)OΪ>+CaUo`x'0fo?x.ށqkb2֗nvsxp@'Xou5r0ƹ8Ǐ~=~%#xQo;ĸ[M%PzHƵmϷΔȔ,Uۅ>e(}l `<64@KަWDIs܏ 4)3xp|:}N!kT=)c1M/4 ~xY{cTkqrCק Ĺ(@OXk,,յޜ|ztj~d/R{؃1/wtqO0/N 7mܶx.]U ^!s$+'|ϩYLKkqN]\2c抳0v-ӷhO>xTOW@Á8!oqޯyO]q˭?֭`ҕ=lR =XsH>|~?;Y0+~<ƛyGOkϢi>qң>e :ox_ĒUp]ǯ]oLJ0`pIW#ļ\%؟Ӱ>h{za ?^临hUb< ϥTa\;-/G"3v UtZ*mKmۍ){Os,ޛ2MN'.< lsUʯtghGi WrOU K$|(u~| 2Nk9 lv\`g);[{Kw eũMg*hR[WE|aq)5,κu%Z >g8EiH{[{h $>϶_+~~O`Ϣ͸[bş9c7!j1b4'qmgDG"T;B'e|sPćsXG~MZ~Ʃ:J)?#_<. fG'-m|TD\_D[IKGBc=𪾢*،pI:G&&<}Gcs#/)86I'͜%+9pO|A]b G(T~StHS`.z$p 8 &^U] 6Mk\<|6bM^pzf 7mS(1`KTw`gb#%;=y=Q4Vܖm}pZ^w4[1zy3ɶ3~:A?c]29[Ru!l.ﰘ٥|aƖ4r\/.L|% , ٝ?Xʆƻ^&_J: f'?[W_z)@oZmn|6']QYr>w7G'tW7*2.9-$ $z7Owk/X\w; d'f)$ج_a˩N%SKOeg ὿(mӁY>pZ1~ij)*mɮ̩~&=8"M[iK;|ITF*%}s ^c(_Jy?Ԗv|}Y/I%xZU#1pXG9J<@To^(?X'D|cyʂI>EkNNG?SIY>:iXx̸4ă=u$Nj#Y)r 8ى'^88W>`2/V4Ӓ`}#>P&`D.4{oK,jG6)5tѶϧ&LMI۽-dQ6e,]- ᲝU|ynK`pd0̻GP]Pn?! [v7Εq ޣRuL0iZ8Zハϯ5żJپ{kU ϹynJ7!c iolNElϥz6|c&ܛ}qVzvāCKzDv;eXU&x\SNzq[1޵:,(|o/ԩNzF6[| g5>yqUU|2-? R@"VSJÂxTg mG}nfst؊Gv\;^+JaKJ|&g@Ci0qP`x,XQnK:;'es8}SwlW-7 *pzh!pp+xR\q\O7Fj9NFk*YPv>[K˱[7I:wOaT`(~0J>}85;8` %ė2JuڋN,&M_,)TRV ?8+>5+X',D>sh(ipjDj~w8|| bE?/cKVd `VD0b<[[l>G8q+ )5Q2@I>Uە#+囌;4xRν{ X-w];c,G&b_t/DG; H?܉#e{%]Sll)y}|߇\l'*sgZ\X縵4>Q/,N޿ᄎHa)OvuƼq[e |̕Oqf/*)Ee]|->gұrXo–a]jT`MrO0[`]!7sȱUk Qx_ɟG~`T`XOxG7gڂ_ | 6~#UZ*TWaGU~0NڑU`4XWf}h`y/"(aW ^x,~uOb Fk 6m/rp'k:o#7HazuU#6v8龛9N8Hő2kL M5`7c)ي[Q+`]'~SʖƸN<][<Y;Ї}ہ͢-~/U-]Y/u!fłXgɸ AzִL'u9?T8ܡ{#܄N) |S1TgM/>fVsMOe[4bM>"3X=uL Y±Pt48n?$sIMBq ;'{q"BR15{."7*>֏vؿC0/FdYEʌ|X +U;tLjR EGu/[ȪlqL7XG `\F,-;Yr?99Jϗt諧|a#9 ?W6Jߏt*?ou>XopL|5=_?=q5dOӮ(ڀ/q1,4oWXp0^F:Z&5NR~gyݾwWu9H=L+`ug݃ne9O8/9:;'lx뫄ο|][)H'_Ig:>Z [(|^?*9# b<̷2a?Q*px6[)8^F1.tsWd}uy0V6V/ 4vu[L41%~>H@F|p i`5 ~nΊQc)\NzN,:nUy,և1NF:~g`*\s%d/PG0w']@Zt)jq>:mgrK7k1O'nL,v1ƒ'}hWɊax7GoO"k޼vM"\_V›8Hʑv۶I _z@' (Ҟ`']1no9cI3Qd'qx~Nruoc}R@zF LX)ce|r~R7dۍuhrPr}q~D+kyI ~vƏooH?ױTc6[|Hf>x{l_2b!0m^|of)'o``Ώ{9JƑu/)wWu{}[+ og~t>F`q%{=c༦Ν9/1_vwožpEyg@qhb/?ϑn*4c{7H湝';hﴦ B j_*k|8q,%}N8_%hZ~?_b]xp%6l:.<Mԟ;jWrxsR>"2Vn:.Y*ʍ ;Gc&1XY`%=G_ 橶[w4 MuO!W#1,C@!>[/>7:OVNcYέ[R2><_2]=R@x\:F)M Fg%H<+Fӯ B`~>3|IWgh{΍3| Ln]!H HRr @0tzw;tC0E,Uly79 fV0^c6`_bMGqAMF 8cr;@\Ěw 51Kp̯'e6'[ b+) LӄTy^Ĕ`nS3VTq)O^`_\f}U=Up>7K&qb-t AV0/[hfi!.1U0x>`DXkYQC8 b&ױ"Xu\ W꣄}G6 gpu`*H4~?8qf5=;ټu+իmyG˺kL7v]<\PB_oUU2HN`bU} K٩*ƀ)`5fpuÔVu L$} ﮷rwBe_4È`'l`:!`9NŒԟJޮ׍1fȱ~(+H]`S6Uu߭3O'" ?Sdwka\`J`np^k)2ϣؒ/.GzF75Uw4 ݐ6 k{`|LwDdc\ p(/m0?R)t)ak3;*VJڵ%L`>P49 &㖌3c6/u?=1) %l仪NY",`TWW(`x0JQ eC7 [huVDS+?'E/<S;Er,㧼f~# L9֝ e:ܱLW$Y8E~GVConB\Q1|>RueD()`_K Rvu>EuqJx;v?Is2?¼KF3a e+d Wu?i(u20&8@pۏc?oYAGo`V!0>7 V:F9/@YgP"*([N((a[0NL 6YoKp_iȣBX8tg31>Ψs>beJ 3t| F;]2[#@L[b?sRX,%kʣzוfq}P7x1;}i:o+ gʹmyDx7hJO!+~܇/dRX/?srW^UOQ^FCj:'ͻەP%Xf.6bL?WWNQq@~"Prfl"=1o`z`#ay) ȬΒ@0TۍyuՕb`hR[1O5vWTR/¦exJ`JRϝ|,:621 z3ZTbܠyMzfğ 0`.8jd'0J=0YxB9uuFVmo ֝j W?k"ͷMΧzk}SnU7x-d5 ޫ/5n`Ys5ec }fq fA8O>&Y ƣR8IehO#&~ia,M0ߒFC+>;cWs7$ڪYPk#i Yt8NX=scV$K=݌3?i#O~QO\ %4NHIw0H#y /E,x/LOy|F@L^aG1~'ܚ+KiAȮ髠:1ZBR(CoD&- Rhң6zz}>F9Ǿd1*\odG3>`μ*X$L>} 7\ºI5rbcWRx0X1?&p.q0FbQ'esx?$kR9cI`u02e@=+=quFsE[7{X~[yͷA ]|XLcUU醙1~ҞwKdadÛ4n7%6sz g?-D91ZNt ri5Cx,ucu[M}[jI`6Xċ.a ;W}cܤ=ߵaS:L5L s u-s bWiDєtυZ+v^. Gt6= {bfw3:b6g3?'ҏ& ֛0xzYA+U:.͝]B}\}y0,E&Ik F#[gT}b'\u<%ǣطnHκ_KurN :RyH V_tK_17IgUA\9Qp:op9X"{ŽH_!| ;x0vuO T^\#+Xny<)?z9/~~Lj;8Rnz\dn.S39w&/ܧ 5&:OgXU'ޘx$iL\ `8Է;?37=T:6h@C<`1OL8.oqS 0$|{Όi;$%cG`= MI D)+)sdN,3w1J(9n_I>xljcـu⓼6#^YX/(C?0;/JS0^Lb?<;,eد+a1sQnn>ZjaCwm,|.+sLI}ynvZCn>'}BG~HrH`p-7u@D$0 n%e\O1F 7"+$lO,Mi"8/$ۂqGFM0tAL桊[j13'iǏUb>tLV &3>?ۀ&WSa<_-i@wf4 ymC+A_}40"F{B!9$KRae$UFOrio,Wb_{<)q/A<./珼}l 0[4 p;$ Oo)H25(P`v&P)He wR*[X~?[9 +|+̗1Gb>1U-T0`:4׶ ,i?pI#"G6,]gn1gE;w}Ajs»;,d3_jG{;K?+m h_%~'1޺,#Xkq0f/? 6C`6y~/[Vpӱ`O3gPvز h2|\XGy?Lx n ؗ-i|OO7˶(2Zʅ~JJfXid)YC Q*8Z?Kx,mYq(YC20Ÿk鴚%p+64X7m+[4&]<[ɻ񾑮C Q;#&8]XWؕ n3ҖjrRB[ўb^-]yĸs'|me+Yͥf `}C [Rm3-x%A _ (#i^u4C͘ghOl1e} s%/<12^&sW0R^sh{*0b<ӕ|M$,xYo^͗kM.d)x~^sf:klPbk`3.ږp/ (` $%\I߀\~%˦jK*|,ַT)l籟3'1 Xq$_f-譓W%Kgc$9e1o8 & ae- [?c^" {2H _k/Y:F*Ci+0l5 :G+F ~9AuuO|#o%]+;pu8P:ău^.1Or۪Dv+cFPDcl Nn犮`3ŒO40|ŋ#g1_MvM' IO潸uw-vt0׏r'UJ&o#e7U0yg e ]]_,> yշ&e.)?iḴoلmw⭭h1Pa)8HL$}s_E'Mن??CmؾKzJ8{]|WUa9W,3TŲX9C~6#.Va3̓6rVT#pΤU`+Qmp=:Xj'k`Qd;vOL5L7{ZiuDY0=p4fyX{#0EU"`v]/I::D@ ntuql}>J 3Wc=/MUW_f9͎ jus Ⱦ{G/R`0?8XjE#܏:nz9`OQ`n$$\<[jt,YtH_ fƁrm{Pw+Q9։j &#ݘF%tp|n8ۜRjf5d =x4M3ɖk2K~^#<}9ڳɟb]vhA'C0%-#8}X}?'6PGܗ򢕇"w̛~RhwU *͐fܔ 0 :ye_)N)^H N Ly+!HPs ?ؘcWn_h3PX I:k3a(Kɝ+f]PCzd M8d+ zmuV=097&/>ʝwXct/Qk `w=whO.7{x~H= ɍュbXNb|^mw^|-Un-]ǜMs{k TȩC`&=GږuzVi}x/,>VRLƯ^;wE!a o.8vݾכq>ٷY`I;w.U6x2᢭i?㊬S7)SZ"q%aYb2O^:,V3'Hs\/ٌwD͉5gW!uV1di8[%0&) lpvޡ5֛3ANd:S %s{"u IvO.uup|5رVJ >HyOߖ4ٯǾQFws@;Yp*8_eyP1`d~vg`=Er% ~V.(''a`u{. cΦxe<;xw* kTXGXd~6KZpha9g# J, 3˳2Wk9>5^عya~Z,>_-mփY/NAoNQ_je >Z<'NwuZyJCnwz73Tǿ+ r0o!1>f&?3U[j?UchRH ߦdCz/&,ާYHPt.E:uiL̺̫d}+0\d~>lTdޓ5J].ɂs{uot ճ!j^6ᯭB1zV6ҁ6癉T# VDZ6u2՘˱I<'|aqi3`<`޲QS#yIRWf2OJ`=kT`2Hzfg &$z5KC7 ǸE{o}zLiwMZoqx|/Zču&LMR΀kk4*-YU 8^IؔQ VpI,(oId"hE}LT锋/S/uuݺ,#׌80c -)e=9>~P|^`tj}l`֬$;?TaVFsZ/t9,5ud!c'/6$# jf!>׫+G9OiXCq8[Jn(Gپ|7l7?zRg~Cb\>:yj@7f?i_oT8`IX׊xd0L+-֫r7q̣no {$pSlּm`%~QʏUk7_%ːxn#jǗp,e)N Ͽ9IOAVa+ŕs L)41պyZ%f. ?-V>Ghj6!'nHoaZ1?T$A86 E3Kx#,$pߒMYX%嚾939,[U$L kO1Y`xn[ux|K`K>Af_=i?hrf*:|nͺ&7 @v=2D Xf~%;a~#}Yq&1sk.?}[;ea50xhʶP_9]an2.tJGT`!;"sݘwhN޿Q<5-o gdc<lәgrJ~sF(Ds:3{ν˥8oU  L5^h̭/Sӿ"=CO/d9q ?yźTVaϘ{jQO£_ON~K[j YU5q\ź6oL?t})xnH9d=󌙲,Wt`>ۭO,јśo#$kǟ?~w[x~ʾ&xJu;_d%!|ʬIu?lkfŸM$I +}tO#IO؜2F%1)}fos齚̗qu o}tI=/^.-{.騙.~q"‘[/HyyM vny0V XtCgn֋0XR$e_O"0}J0:)HB:~ʾ2Kwxcyu%|Q?O6Xd\5MEøL\Ub6ʰ_+a.6SN~ƂY}' [5P )'hl͗0+jOӞW;`&<{awVgX`0u&41YH:XL0+2ޏ}xы~!pǾ0鲙Y1͕ܼb(aLZ7N(YW*/`}N라8yO簮[YnV*`̔Sc|};ٔ[6\5YdOvjvq{U:hWS;a>!T3+ J#fXs9ڰ5?y$e3'mֱuPjng0b{ 4՛)JYioe~=n=} wo _V/}SWG%& #uk|a?JXLkX$<=Q^['1.Jź1kn}+ H?%gc>%s\# `5Yˮ&" e[ɷP3i޸_4U!gYȇP4ƁطF<;Xj; -|d"ޔ?,/XONtL%t 0̚'Bf,)qEO`_u̻&<9quҡ9!mOE'[.N˯X'ʔ#==UI[eϑy>7W{k!2\=Nt&"[1-[^A:B)$A9 ,9hh~%G_/W_;9&ϓO Ⰺ+\3@f|Aog`F>/&L38Y74Y޺@F{ [四%k93jDd6Yr/7`#L^ϕlwS`&_Eg[X-1?tXɊԉyՑ]& M1gӼ`\BoS7Oa&]H}k-5NƾB'nϲ9k/9ɾ_y?x"ZmnKWW3:YsnW%Xs69^[`^9pMZs#3#XouzL>9g%-jgI@'Nq|jxi?jsb+Ec h #F\ypxzEnzյ&녛y 2uctw{2NV[wAu&] y^50ֵ1Y?9vTA|$]v]7>)a.0GW|/UritüݍnU=6,9'+(iIا,'<!MG[ܷ/J:P&'Ի+"<brvXi.l:~9e Ϧd`>:@Ej՚Fzo9x:Q)D&rR^$;hmɟ Oׂq@b4#K%>y{B5"u*y%[ [lzCw,h`ޢ>]dDH|ckMg~Uc K_uCLu`_Mo3w7LF5 {1e1h{O e9TVm3_Kxō8UAyКǺ8\&oh/#w NJ~'&_ ~0D~E7K\b&M޻}44O#f~#kUv:Bbq 'ˈE4N^j_soZmЏf Oca}`1#|!eZAwtW@gBP놢S/ Azw]n"/w^'~O9)oW糮~3G(i#SveM1ްN&ϋZQHޙ7c=JF^yը[PVMFh Y1IG_ܫgnF+7"r Ik;^ʠu&m;n`wI%?'Řiƕڽڹ_~ bLM‡ ޯXJ` _DB *F󔨕1IZ;RI(:*4Ѻ: {W/q+AAP뭼 #'ߙA"Q\ƒl`SG]ĴջH4x.}x.;i)/̼|}C;sDOxh;tҋs!tړ .TEQIna^}؃Ja0yD0vBǀ>`gZ е+V}M + W'[gʃPk ؏FsWEȏPWIrU 8=Z3 W#1}˕|=^sg}9[GAZl;@M7L WxKJCڻA"{MƫzgxG/(<$@;f@gA9a};ϋD{7@T,ݽh+aBA@Ԡsϑ#c#ƛk^>~q+,:Ǐh 걮8/k1;̃}Ǟt\Ys Hx*%F/E&&xO/s M_ݫr2@"}*1w_Tc^d!2t e u{%:rڶ}ͻ\o]6 +ҭ6mk&k'?L?kYVX7R?' )=ϝ=b};x602k΀hгxod%" uO|P_W \yj"E13f26}뉁GE%L̓ͶMʂ6j2M] 9<)֓6hԂ85`\%=|OzV>qҿ1n}<'оe-S3eC{:Ɖ 琾`e!XW$T4J!;Ԇ.MM,0ΰ^8H8Bc,!&&{LW=,C0^ }Yqj_ZFo b50YAzJm${3m= $)[p\z}>7ˀ`>TC>0 "VV,ЙG.'mw6 '29vVx::2' N~(N㻅a\9~ޥu+~-OTs>|Up(bsg]}.?~ݑz":ˢ2ǸG*{.^CW>G h)^ьp32[]}RwĻз4~4! + }] U`|y}Lӽñ~A~yX-Fߑ~=1k7b\ͮ1~X_zސbP Aҭ=S-q^An]:e ){~}%CU_E oJ;Wgæde?*e^i0>WۻmQẸI:u~+6 ٣!e[j̿% {ccy`])qz>}k~SbDA^nm3O-Ig_NjZQtClCE'Viő8^\=!ֿg7/OscMHYiN0|V'^p}ܬe뻀d㵣S0^F^% OzNoΆϣ?JbxltPצ{v.Ǒw.^ F\ xl>%^gy?cebvz>Mh>uޣI4xdF5Qx'qo3J Ϧ<ċ[%U ۺqQ?TrŢI@xz\1.Sԑ@u4o]ޫ }UIȢ#hWOYS__NNoS:F_0Cd<,HAy~H3I>>ͿErO!҃Hu}Ko>ڪ/=`>¼p`}VΦXg=C3`WWAsF ,\ 9 ?_6H"b. :@S̠w9~Ϭ3x<';7FJJGKzwy̏{wwr?gdb_Rcേg4Cӻ;W F/)7yb_WLJW-de#W>x +%%1rGٽ#1P 0qIxo*̀|~Qr$ӣq3V nm S9 KI؏Tin&H)Пѫ:L- .`~ٜH]fH1tM3N2ba@ۂ`;*̏ϋx)Ͽcѱd]/"Zi_/rnXAzh? _#?p@dckY2ƭKcW]Xcos#b}=t< y>~F?5o{I~bKw^s ]i,f~# %w;,۷~|s|ȜS79h˒ 1[(6bGhߨK.#'޳B7>pVP'a=dj׏Knx޲+#u;#D}qyxFsv_}kl/@Y>\lPЬ1 Ood9-A\nO1o%S91磤ϥ_7i'h]m&*E'3/Z O CeQ:Jy"XRM<1QY `H {=O_ FYKY?̉y/1fŸu ཨZyL/_ԔϳaZ3IZHxF"=/Ha0~I#yF ŀ&=;ԧ>VC,D5sNx QSNuv}Q'zػ$_n<}z9rhxni'R-;tUud1-9&_5'XQDG'Ga'7P -yOs$Tއ7sOi=U ?e|uѪe&%=6H~c_kz_L_6{G_10.Vo.<+^ԃX:ͫR4ۉ3nKI{ZR ֝G {mid\m%TZ:}emqv-@|t:zcfρ 71KB֜7NѸȽ1(ߜ`$`>}Ug`r'Y kMگm[uxB]Ҿ %7AegBN~2*z M7+ߊr|? T0 ]8~w.Kx^O<R~ ? 3_63 \/(a˞BD i~S Q{ LI{j?݃'lJ /K~Pa^/$TG T 14x%X%Ⱦ>a 4XξjR. ސ>k 2U1/rqVG&QAX7:\ѷ@}T ׾0u"i`!_`YAWcL7W9'!\ɀe>r.B' '6 `{`9sǩ0 !TA_cn6,"B|W%<&qOj@-~'^:7oE.b2 c)%sϿ2d|ҍ+O~aW+mdH|}YϼMCծNW"fh!IK!tf-zn t[0%[. KEz?Pk1C</ \2pB慆/E.(!?8c~}^=uCg ƕ37?lRLƼP.z۴? KGkH EX<6p!tFXG8^5|QpQRۀ+sBs_Ez<wGn!o G>^'koCXru1n}!o 1 kt6tBJ1g9#(鍵@lI3iRtfGRʄ+Pvi! V#뮇3?iG?ß~# )VN{pe f8ń=ckO:PuRn  xOL{P⽇2$:~+k Q8U}ogyy! 4|c !IHp|[ |⺊_a rx*"(ͤdg#h3)i/88B!Ǜ!qC,/u86#\p]%=P£378-zTF|t^C_8,)0 .*Z@औ<__7 |R,?X6ĺ# :hX.>k!UFd |9Ո A."8tC$ oA5^n}?Jfo ~gvpx7 0NAnsyR0R 0F^tA<:fNP֑o2?A}g7uPB0 3O~ꦠ)U K=>֏#&QϺ)a_C:AXg _Oz-.ޕLGO>jS2^ ~k~݈x qg-,ϥ7ww<8Xz8ē P|!IQ$Ǟg_'HBeP6DNC~y$c VWB&^e4k)>r)>M% 7BP[ύxᬓx[ eb~!\-J!AHўa<sɀ? r>ʍk!>:\#k$.BozH:tCb^L䄘O\}#!:[bUcǟayaHɭ``T(@ gUU?O5As0gκSЁE7i~%['LDzH>72N?+ Ta3;76I0V4WZšq܏ϐTHySC3ϔa6֥W$[gDEXO= _KT! A5Ω8imu?=X*,Y=>'bn"Rkx:׌(4ϴ/;g֖tB%av(Wo|aSٯ:IFƓ eth4U.ǵ-gHW/81B O~ao&o gߵrOY';~ȁw7L6ٿ/}`HP_zno`}?Q 7`=`]ֿ[hD2D<W7 th|x ( r=t@@"B|utnC!7?ȝO[gg Tu7RX3#̇Z9؟,l\wN uy! 2 ~eA8?Ɇ{ X2tC\m!gDy!I e-y[~}3c2=sFh3¹/O0$\Pz>',KJ4+k  >uV$[J<#ҹ Sige N^E~%w2"WW9Ȇ:(5O;c~@RBXYһ [$~ϋo}|qP g7bOWB oJΏ4a䠰w I0֭G`zAN%g?AB[! |!}!)I\L#޴oSE1A +>P41Lﳟ0;Nb:AֱHЁ'Jp9>Y?A'tW2ib?>zA BGt/x{}D#uhSX4o%ȸJ^Ҽ=GJJMƾQoc^o&'B߱llcAp3ySAq#L^tW< "} % R 0E'.Σs:cӂ\fП޻wcͅ(ImoHH aLsŰdF?w:&0lLz !֡ ]T pP^c~;|/<MʨyS$êJEcbp.11R_A|`DG$ ׇIXsa/B}kXo]8vE /ci#,xN)>}_Ւks`?J(;c膬S|rM%o,On#ia1qb$Yf=afff vWr]U k|g9"#~ȿ{jr!p1Zicyt ֵ2 ޺ $[QpO\b?5{Wnfnq&s1t]:vaDF\Ҵpip. ܢ/mZݴ==xD[&q>Da/\O!t8c9?[wYЃ঴f$6.Wqx%tT EoZUܢGeJ>5CO{] 5sn[\U؂7@ /crw뭹&.OY#gq=)ُ nV& \lg8t1s541ӎ𼃻ϷY/K|uF\e.ӗ[E?kwy]T[pEؓg <`B>'%.ݕ޹<[$$|k9ԫyjB,~ \My~Em#Ү*/>?g5g_y_Kړ "^&z=wn}}B DU^f'GϻޣҋОfWհݍNnQe`RCg'C7%RBԵݞ,qs91XKpnH]XgBGiЖqW ,}Z^fx \9z`޼?MZq~nb6 ss\{p["jp\daN{0y֐HãhhxAunqn-/5x兮u54Cgwucn 4#p1\w"}n&v\;w(w..L BD?ѿrXE'"DOD}\bWa\pT?.ZE|ns!JgLp19\D=B-x]5t6]q#4S8j2^zx['9oSZtq~tH7| e<y.#} ^:niwӁ<x7._߇M8Z3 vMIG8߬#pU<.ZpA|=Y_ =W3 ݃_?& uV9MeL^lV`ƍgm@?[mDk.ח0U"y_PE_[p>Yʏ~[ԓ2RӯO5.o&pOOtѿSVn)nNTWynZ0ެ{`J܇M& tC#w ~fVO̵+p>\iANy? /΍ܗ# mNH ^\wm3I,>Fů 4Ffa_w,Wcƀ8h=-\MyQ]8G }Gή[OunQ.-fEЧ.EOoat q͆u]9oϤ'N.tDu`͋*nv.>M {՗K`a[=mGwy^ sisQ9I_h{\?Dݔ!O$1tD.Gu׿/h@_ ۫~7Ws:#wv$.4sy~^W3pӮŦ' Qٻu/?e{eiGd+59*cP 1t WtVx q6~?=. \7Q1]"uPL>?:\н r0+\Y [xD_Kaйrp]IoF?}C.QV%x{Ͽ; v}+_'8u y1C-%D@[ԕfiD >][t{u._PUho}.JPq޸_-Ksw0H݂|3_9jOmuLB{o\BMr~_\5ш#]nDWrn#OQIW?Ft!/]0@MeOd^jF^.ѧ|u,A nq1t iry#vm~q>C @eS@"#Jܸzʽzv+%rH\!iX?%m=>M7O7/(Mɭ9^a$|tK(ωzGI -5ݢO}ĹG-9kl8pͧ]鹉T:&SD,E};;9y㥡^:."v#xܝӉ 72%xř8ixyp5Kx]M؂x'>Bs\iSz뙓7>U/nC^-r\t)/W!Hu>k7 N,UdRM,YfN<;y TMf Ef|o| HQTҁĹ,_Y__ a a a a a a a a a a aaaaaaaaaaa a a a a a a a a a #.0F\`q1cƈ #.050505050505050505050-0-0-0-0-0-0-0-0-0-0F|`1cƈ#>0F|` 1c$H#!0FB` 11R.UJ~YZ~i_e*/rrrrrrrrrrr4$G3Lr4$G3Lr4$G3r4,G3r4,G3r4"G,r4"G,r4"Ghqr89Z-N'GѬr4*GѬr4*GѬr4&Glr4&Glr4&Ghrx9Z-^/Ghr9Z-A GK%h r9Ē8%qK$I,X'$NbIĒ8%qK$I,X'$NbIĒ8%qK$I,X'$NbIĒ8%qK$I,X'$NbIĒ8%qK$I,X'$NbIĒ8%qK$I,X'$NbIĒ8%qK$I,X'$NbIĒ8%qK$I,X'$NbIĒ8%qK$I,X'$NbIĒ8%qK$I,X'$NbIĒ8%qK$I,X'$NbIĒ8%qK$I,X'$NbIĒ8%qK$I,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,J,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,X/$^bIĒx%K%K,X/$^bIĒx%K%K,X/$^bIĒx%K%K,X/$^bIĒx%K%K,X/$^bIĒx%K%K,X/$^bIĒx%K%K,X/$^bIĒx%K%K,X/$^bIĒx%K%K,X/$^bIĒx%K%K,X/$^bIĒx%K%K,X/$^bIĒx%K%K,X/$^bIĒx%K%K,X/$^bIĒ% K$$H,IX $AbIĒ% K$$H,IX $AbIĒ% K$$H,IX $AbIĒ% K$$H,IX $AbIĒ% K$$H,IX $AbIĒ% K$$H,IX $AbIĒ% K$$H,IX $AbIĒ% K$$H,IX $AbIĒ% K$$H,IX $AbIĒ% K$$H,IX $AbIĒ% K$$H,IX $AbIĒ% K$$H,IX $AbIĒ% K$$$UR0_NRe?Ko`ώz-Q`A?ƍgX)/MW~JS77";dɲ?_Ɋ;ȊLTȊӧVO㾺륍xbܦuVoGc>aS;4pf=u7Q\oۋ#>7Sz 韛o-bۉh&ߵ4x0Q\>>yi%>C܏a?y1汿&}}`̧zuNXZqv^3}c~,>Ÿx}k8~z F׆ƺ&\;c݉kdܯNb {x/}^O[N8&{ (~xqi?q}ٰ=pO1L_Osc<9ZcƼwL̋(?Oܟ U|}W}%槝5EogÿkÎs:*>^mqc~Lo XH$~C@1un^sx js3އ0q7=hdམN=v7J#.0 l!/ﻓx# ;*n#ma̳~+> |2Ouef-)?@1a ">gPc=6w gb>Pu:}$櫫x~?x~ #~g컖^ylnc3ogW\{jdು{0>'濯8y ?  2Јvÿ-s/5Mgu\췁L46Ƹ}﷍2#k}q}W&3V>{A2F>rq=qF>q7יdԈӌH~F\f %ޛ݌89FZ'#e=?fsFb?y3#4&43Pgc\8Oaagy#_a/ȗyEϰ͍|񉑷iiĹsCO]{s#d؅؇} |i[0aw'2Wq_͍|q!5k+gm5~ްzƹO Nea KIy404⾍s1#B^9Ꮛy#_de2b>p mW1d?~j*#$y18e=o-9`b/FF]nJo3UR5ʬFra$v:Q&i1OV޷ 3HNf,L6 oH+ֆuIEFNMrfݞjB_j1 y=xΌ'I;v\&ә|TIf&G\T=dHX_sOS˶I{ZIQrzC|mykbd$gJ]n&k1rdP.^K^ddk$[FFpq 9C!yD۳ hsg IݩZ 5ݥM:c$U!y b$gO2Ab"du" XhI}+;RD_g"$VQJ M0Յ \ $ęHN #!&32KLRzz#rSͳ##'!FM \E%.$aATĮ>1RUj6S LӸ )rT!d$[&~D3Ϡ$.lz֖٘HlIpY$/%!$ H(9#AI2sKĹ 'S䋩|-֘jE LĆdUx! ITu&jFe$$fKS$Nwvg$I&j@>V$zzJwUIאQ .AS-?$oŒT͒Df$W&{z^i,+\HÉ' y7qBd$O_J11>]IL͗bd${.̣80 E$ܔDIhCDQZuF\dं$y]oITEU^ Q1 ,_ex$})&RDrDWhIt/3%Q6T]+׭:d!9w%y-Q)4E"($>Ĉ bCb$aPbj}bxDDHn*y<*O9cIp&"F32$LcZ GUQh7#&1 HIL2.$mX<`$&?nN2fj$)# *UduYH7yh~_\LZ!R}H3 $o:&vCBS$&"<][SZpkՌu<$G,'%ynQʹ $'e}LRLbd$G;$g$Yw0RuJb|-IV&yRm$/'E&遱#0Us$y3|yG> +S i3 !':GS6v6#!Ϻ=, db$6В: 礬$#)&2QzjT 1C+&ٻ{j_NHxґdq] RZQaCLؖe$tY؛\6׉[H-^&sc.ZIe*I$՜LI\čDv,6UALBpИ3ZEP>vYAL= 4Ykgj0w"qA&qߐ>'x ɹɑJ2YIp4"0uiO5 JR d$Ӌv㞮:B2=D'N}%Ž}INF2Lr B=ԘH(BFfj$d #>i#_\$|Fv"yQRXMc*2#g S!)F ٧Hj!$5%qZW$r3S-#!u0 ~Sm$x?#^u>T u'(.jDR8c_$eGH%"#' 0%ao _ıHTsznE 7)Uϒk\$5j"iweЅGWDZ=D,p{' ha|ȿ=J$t%IոCz\JbJ3EHթ^0HLL~DHO&Lj$4y>0ntN$T= }~[$ziɝ9 lI<̲o쑴K4r"ui#f*$7Ɏs$[&BB3yjP%/纳1-$FLD&D HTF!AH'6IF¿Pwx83#x&oŰf$w, s 9nEb3uNQ}e! h/ NNpICMU0~Dđw!1( aQ!C"og9h%,W{A%I)TBҵb$עeTL cS/;04r_$+Mb0 NI`( nD!If&H?M=HPI&Brd8&;N&>+dohۉ.I&M:3$jU[d_j %If5Z'~zT݄A۩! Dp:P&Ƣ=jNˋ*o#<#Ao''RI$'])EeyIdm U")11S"#*vsҕ27jgHd&DFH_GgTf QmD9H.w?u< ^ֲ$6~DLaR9ixC"(z>b$doaeiM$}#YQÉi1IrG5캓o#Erl|$}fj$U7ن83\D'[zd\؅U2w9#$q~L`"S$,_Z bw${Q&Fd$%eb$$t{kOCGeӷ'9$ft+m#2(ǫ!31 ]%SY\ItW9F"Or8THp,'"2zKUHBǞ87DJ")L_$.ݰb e%!רJ$[S#ч:-y "$vCI*/Ef*>1U"qfo{1?34󏟼BTb"/$d4tД?xA1QcvݎI"^bA5qfV'9o4$][-p;ϟe<&1q1R5GebX$?#qߡ$@~Qŵ>Ts0;ASs~w5>O01>yLĉ82G(DtHz.:Nrf"$$S-#1m$m[&E2q+X %qz$z)|~b2܏N$'[0S=v ʐ`)J$?"As* b^1-H/%i=]u-+riЩiŠyʹ\|䝘!IǴ,$ YDrxXXB¶r8zϚlÙ 4ssCuAX9*ZpZ5VŅΝBK _x(FD$[i!!7Q4_̠wI;fEkI jm4nz$d4s':ҌZo7~e!"`ւT>DBI䞯3yܒ$*&ٿ#l'OfS@#*)[G^x)5 [|ک%IJI(\$fMV#9%uᳲzVD*CHw\ N @>wUY"Wn͞[I(KeGIl @Ә Hyn$UD6LئG>]Me$ՔjJx%P0ޣa;EP:*MXxY۝BxBsqHYpSIiL,\b*g? .Fvӄ=/Aֲ@BslхNb7ZAN66HH"9lv&W_n$D%K%YA= ˴V&uh{AcV) caARgԌm@Co?.&?X^ ͨ eTrY}8WCtY ۯxԇ,*`GG8s]W T*ɝvh?z6޵Zu4uu:@/AYJR-۩l-g*GZ{.iF?+D׶uxl xqk? Abw^%| !uwTqOWNqùAk}{Ӫ>.<}MK%x?a qʈs,*ۆW{De//[~u7AKӑ@'uRMݖ5V4K7u1T $N >ԆA});Á@{8|K/f}!Jթ=VO낿//Ƕ;'A+yBMqʔ>:[e]FUSA= /o,?Vۦl|hCXxax?Qk@jhy4z6\W_!@c.}Ǣv<Rݢ@ }/ +F""[Uj|KSx'}-Faem?J3Ͷ>cWb,^q<:5x/%xkP̈́UXQh=_W>6*8YmfkjD~O^!lħ6{=OVfq}İ{]k૩&㸨e AO Pe hρv D?_G;ӟZ L o5bƸ0O.7^~늯/խ[!Y~ zf)v.#1d@ >TTE{Wrg@>l=%8@%A'wEUsd hH(}J-҂Z/6:84:ܗOmZ6A MCh ug L۬ : +~x~Bx;s5Gy3Ɨt+FO4B&W=k YqUU7/M} z_TKYqEnA{N]8v6ל2h_xa)nT!T04Ÿ==^;>1yj]_ ^ G{ Au (c(T)ׂ~7z*V Z}6ټ.+ %OV' .;x:2M ډ ԑy u@ݑO@>H)?}|'GPڸMp2ٵ 9<E bƠduo ^z]nƑ 4|A|F{2Sz+2pj$?h4kP)s~w5Aka?gҰqMğj؋OK> VO:MwBXY/_c5ǫAGcu"w=f!}=~XZhvՃN2eu,p( F Ots bM@c>uAceqY+NOC^~+oO=63J Au4-#E㼰> xuֲ.Mi:e9xy;xhو2ƌ¸Ղ.&e!NzAk:Agۋj)ЃSV ey6.KO C4 4j^D;j}[Y+ 65u5+9ra5;o Z2>^O brPGM^rIXbᏏY طރ,OKhOfV4~GL-ލ~Q#7 m \/ ww T#oF%+=u=|Ft+} zշJ ᾧe}pp?s䕠q]1@o³ZZW {u&76-x?O,wIL&]Oz@[6ڏc|Оs"_Ӆ!.q8Mh:޺oڝՁ#^e-%>\P:,PSDP&u`oX]i~u=@;Mw׭ |4~ ln=n pP5iY?1 S=vx@q> ^[ח<btV3OcD|xA[pzLB -Ly~SK&9=`/k?@zNRs hCɹ?aD~\5 VQ8s'荒z,Nsў63KcZBo'ܥoɼ>ΨQAing|-igF8Kٟ4Я8{t윐;uZcXɯÿr:Eח~CbGs=ގ̹QAi>14p6$("tX9;WlSPvuI&ϧ3_䱽Jb_=zplΒ{0PisFmp>Zl}oP6]?cp:p6xz`$M7pdތϟX^Ay[~$gP4q Mq*ic|6eun-8D}ԐKq\iDpT38-v2M1m O/T}֦`*ipG4: JZG }hn6k"(k,z>>)+z"/T|]b9'f@i%vu:Gb]:χw8"/H/^Oꖭ@ۋ/jӔF kה/ROT;/(A=0׫{EO5|i604DpS3EϞ`Y~H\ (gH3g C *|PEP$w.(M], qn^mPYfr>p̺a/8LoxP1-^ 2M;19x Gk2r" p[<.92p 9ǫ.~[9oӥ|F\G;_'՝ئ)Y6fq]W1pԪpuɞޠ\}sp 3S^38{.• ?q (y`59^aL˃ ^Jp|{Fp ,,prHP3~pl]38h=w"'\?8ף?GvnW4n2)Y$;=e=%–#]0TC__Q~Nmqybqx"(]zU˚-G-پv ~ 7`JY>|]\ȆiqK~e` p-,?gGW\U˷yq7xZG1v؍&HNӃbov$p<]я={b5x]Pm3B5c D\+rc-s曦 Npswè;eţvOu5֧W[sHe%_CȤ] G/wѧÈ*5yᘷ4 ڥ3COlmfRQ^Ў{/fYV[S弄놟* zzߺr$C{(O*өހں* kjJu ~~N-߀ЙiOhwpנdST Ju0 h|]ĉО/C<(7=.7-3q5Ն`ptއH %~6v{ ֓.3 ʇ],u<ר(8ਟ{0Z㲏xJv Olo~5?Vƕ[Sok@M?Y>nלܻ n"q\I,պ[n|M޵Eо[vApdĨͻ2=̇3P:s~G1rԫhJ[oPGf{8ڷp}Y9v7,WO:Ը_U=O-xa_@)?hߙh|x6X8za5p6TOsZ5qtj+S/ыF |.mG{V02;%χKǸ?˳:|WLdz=yasoݩxJU7U˝6'̻/8'J3۲}WGs\V iJ//k*8LXfuyol[\O_}Qwij G7(5\Y%xpI-hogdjp|i$M]x XjKwcО|)u&0SrptK 1:h>f>ΣjFpL庻 7U =J@+8smj6g" c; ?M=(o# Wdo|w ގ~#:ǀn/-_Mq HXZr|~i8W(D<,7|J`o+s:{϶f֯]N7b4mBj_w c/_Y{؏js?51{UP gz{gW\,͏Avۏ`kζ Q@Xy3.܊U8' C<{qa.|Gr`tHea+w8xoN}zt:CMf]۽7snzK_rP9^|,_|B2Q?:~\I c}Ȗ_/Y`?R:ϣ+\y/gH͕JB|92O|z F;^b[ _6[GKٳefkKT܎f v%9llD8qA4/؟djp%S{vό~PcNy}ɽ 7@S~&?gp2wgE=Tnw Vu|e֧ۊ瓉q}'_UNu" g˂H3(^SË끺 Oo= _ГǸkdŢ/Xy~ FmU ʞۆ8HA؍Գ%E[W#~^6{a`/6Q$[of|M*K;pXƯ},sū157h\/ fw ?W90㱛m) E?ق1S$tX|.qnrvn޿NsҪ.[&xmPAL\7~H M;7yǽOum*>pcPţeYvɓlp}e6g w0.ٷb6ɏA=$U6g-LoKZpsZ%zJXݝc};NuvJ?:W::+8RQ#pGu=kaD-ѯU]plc<#dg{'|ߏS1Wd o7$eEޣ?S|k<9)7@Zlte[m #W {~^I)`w3M9UOUѬ:(^F|i{.h7|WҿIMˢ yڭ?}R5ʃ}3Oz\Bf`}JPqo)Yy#ǯTWO[!ҿ{@yv𥊈 C_8}!'(H{W7ߦ@)kȈ3gЮ,77>նtav?#^ÌzGO|C^jͯ7_?ci3#C?_}W1>^PlgB dDDO\lS@zfD|?~?_s*/qD[]}77g /?l!Jxk]nWćqQS^}Sl߻dVp?˛;3:k8X]:-~D?̓S/H˄G=ڣ o/uo"؅eC5lhZ37`|֧{}m}ĩ Vvl* Y'_l}q8uq+ߍ3}ͱHs>Gj&}$VG0!]:߸(i`8*$hC\BdFj5 fӛ7d qӌ8.gOk; ~m_Ը^jw1 Q!u00nAO^ЮG%a v6_M7_ kRh&p JE-ƛJ.Car~C>m1ۧ3~n8no 2JqSy'Q[9۠#W_QgduJ+ǸcNrcqGvЌqڳse 7thq_Ipeh'R8^8hbćk-[}PRC /< Ȱa0]zfYrܱͽ"&uXN ʎŎU]G e&|{(uʝ^*˷_u_N/_2m]cmXm٣,*,i %kqh5w@;)~#>9qR[3/zJڗЏ kj?w( SZ1^Vg[EO71~ltLhGOqj LVm^G_V-m?iJ ?3bE&#p?Kŝi\ BFK48.P^xtvpPkqyq|"'V􉥺/KV~GTP{[p`?kAq{,Y:󫟈kLuv}ѩAZ|o~/)]_97T_q8WƕUmPD^сb(~W̸6"WN:fA?Q'c|`_n9 m8&Paਂj"_hwU/: 񝫅 ZQ4eS(h7<}l8"q.'KSe=+@nꈇR("M%[;Y|gePt{YfFژsxlHnfG(ͫ'5qbҮ!N]w __}O*?RLGo$͛*gϝG{eC1Nb<ln>D/H'Xi~}M1~{&J_czJH5θ,#س*>w]:Kk{p3d\L,Ʒx1)8Ϣ/[9qRП܌Bޥ 'W:Ɣ}ތh ^P '{/ydnj&=%MwtO+7Cz^X3;g8/Sv=Wǘ#}Mvlo AB-P3lEߎv@8O2@l@;3Q1eu]F=kg=c_q*cŲ(53GDݹq>73zH~:޿k~F|I7tچ^,xE֑5WZ#VH>OK=*\ihO7+2q@f_cFm!;%~͆oQ6Ɵ ~FcVU,a%C;/YV@ ]{<]Jae8~A',Wt5?Z/F$W7cgk_Η+o&} uЖu yo9ډN۲\B;-OtǗ,zA;IA2K-^JS5&iubG-ϗG˓~Ck]Gg2d<>OvVA4&a'}>؈ ҴzDII )s_aޯS:a+-}n4 @;ΈA1-wsԍHuD_y;A<Ӳ^iE J3&FsҶ2c4!~z|ϼ:d_g't&c/cXpp4QG+xpUңT H*k7ʎ|%^ktF :kO|eLɔ`h;xс_zmIy tw볆9P1BP OgE=N-#g{U2&PS"y_u4@ZzwZM^Uy#~p SG3~zcۖxߙgoJWEqse]Ի??s{*-<tנۛATuq>KG۬=K׌(]p'(@ި~Mj>O]DVtVZ0>-Mp7@C_U. =GF]@ZwG⩧r'NACmAkъwHZDW*^ M h3NcP7}3i|oz:L+mL;ҡD+&&770ZS:j?"*_- zSoA|-,17Uޟ=ĈTp^\AJ `Zn<|^_w1b\ hסjO/:z]J[JMǁ^$ ky߬oZ*Z-kdfz};A5~~9{}nM tg zIYNhWR"-~4WSQAee#O+#g]M$b:3` $hwV38P}X2fϫ&K؇/Igux3G^$ta;Vc+\?vD?_kmL3tVo/wgIevR+u- J j?Ju.~;MAb o?.[rhd|GDUN/u{gIn2;|_rf}_:mAD+1~2S2Bn~U_|ϐh&bWyX7yO蓣D+Lz6~@5E}o&/Ln9) Jr3 J{ԺL'|]}7IO6nBOn I F#tJ_//QkX0#4ޗzRr~yPٲjdޯ?!tJ gwfFO8*{2Iq-W8.m>%cm /kGmvH=%9~Qd#mU[OHuR; x߰FTҢf;'q^]So6he|F 1xĽ*9n.tq:}skd ~'yA'$1XC?F đ nhHe20>qDcm8GԅANhX pFĀ^?h{߫`zjJtw8aK7gO_ʂOk ӫg~IFi?_EN;gf @ΏմlȚ8ްsge[>>>&δ; U| zkJ4mi μwvuL#|_9&ՠۮN)uTrh}xwFJY&4@Z5@3}|?GVouQez/xt0ЍxwsEF{}o8c< 9|}T+$}ƛq'5 0渫6h/ 8Uc_pP#,1D?iڪ_6"Og͈[\*OԓHɒx8ߋhq^h7Nj1rOׇ /?GݬaQ/4}Š$AQo tL=]/k"=gzc_?}9?GoP4: oky٨ J7 ~6M I7beuAtD;0.On|{;DJBĩ `D?髁nGdcz~#+}hg֚0HxAceMs$MUhA,OD~Ay&@F N' ~$ui[wb)}5A1^WBq\MP,]q%ugZ Σ21׀>ѯ㼱@d0nɺZ xAeNz okf7{cD)WG L0·nO|@;@-ө$5x0}}y|A ~=M FЯOq/]*!i/2@O?XXyO,/ D\ch׭'W `tk:q]ez|F9e}b ؖ[gZ4UioOWΓ=D#@ͤn^1-X &p?Ff{ǕwZ|v:{0_ %@+J~pUJ 4J_0m o](t=@/Έ@t@ic.  >ez ǥ,K_>Q[Uq/V}LOt"3mgF?ʂ}VpbH gzoxaҴs{\o,!>&?SwA}8}ߝ/P1]hЋp>I)V}E%<\ޘxGzƕz?]ѯyarOm-&&NBd:yˀ.x2_q9=W͆_?A,Gbw}YxL:7{3B4:| h>n38u1Na! ^hcֵYz!$ϡst{8n-v/ z0OcG-}mǍP95[~^Lo/Xtf༬aC3,u>эQ9^ G+s)L Ή~T]+}/Z鞁v% .p{ 力E$k1"Vcg㗬^czG=n5@NO1}-8Onu:dKngqSZ^TzrVJ:>(,L|8錎A T 8Jau&v~<+`?!2U@^b/vEcL|M~%{6[1 ~.h#?8bx'Uïy|~GQ3;J-I%,VN4lsFi+]* 8z6} Wc -3 ->@)ܞ)]~P(\I^_,!P놓}%i~ň%z`?73W1 㺛YGxihWQ > aE>g-? NVU~帥+3#`@gAUw`U(po4Ldrp4~x~QZA5kpt0X V0 2Uˠlus((o[;ۥMX p_l9eVjYY8YS)h ]pۺ` sT]}HC]OE(q=F= R[D;؇|Q"16 ʄNZ{!;%vIfAmnŮq8Pȑqtˇ_Jz=2ĄR)݇幆[38Jup:U-/(78V}pd ZU~O7n6wsp4L^B7dckQ ۶;bmh#yne?ܸ0ӏO+XxR;q8|#JɃř@ޭs)Eõ] Z9a˙7|ūHANeq>1;s#<(}>>gO;"^<x3}n8|Nr?1qѳ'ਟ䏃A9bh4X5>+a[]'~,G7^(F qL ecGb~rG6\ *O#oKB[6x|>Jv+~q䴮{'E) ֖ zy ʅ%t'$V λ :{TUE‹! S`<!%A}J_<ѱ'a\?o 6eZ]c:zp9Ǒ'lnE}Sn*8hu{ynj>"f<(}(9gc L1~ֹ8bԻ(8mBp쵔l|[?2=Kp4 ]/Dk]@ u †? 9G{ w#>mAcƲwFlpk/}w>v:82(1)kxBax-8"x Rdv?e2UуR.R0SZkM+-}H`Gv޽K^E"?3=3͌/^o2(OL(p;kvT#-tl'lOY[bܿ`v<7^sT!nN>6g RIoo"?|wvGڭ qoWaI1}ph_oڔ`\G7yש9RwĄ떟{b9"g}K+q()w% |ȚpčR9FAEۘl{1)ڧDX"ګ?ƵܫXoITV?گo'B?o?GS6ScJލ%_,ߙ)hNG3{3ݫ@)ΗUm`d/Rw~ 8s[l(?5Wc(ǚW'Cuzr2]`>`o#'WzU +{q^ ʔ~9Rgâxdo\(kywPFl+1ݍ_!BImMNʚQ(K _PLC>Cѿ7Ѳt:k3_ (#r.\/>!}'QFENVd!޳\ò;0nLZ>a߷UOwqݝG#$hv*S py@Y-?6}+h;BQ`´>15˚Ut-sm4Q`/F(w7 ߇qD7.,d"v 8 lbۙ T^g[85E'6sT\).~%M`܍Am ڑ>|}+~9(g¡vIC+3sRoӄ~ONX [? Nq{pexμXUy%lk} :ҨťtGdo)._G;fKg9ĩwo]nQОDUQ5#nRji iac0>kT:Ĺ~9wT;L:'WG{Yme"w AOήBݷOq^$ڋMWou1o*HX=Y$A7=]?E#;O/sمa-td;xˎp?BY诐_&~ 58ZiBOg1λtAYqEԩ;LOtH1^,_&/}, '^wz e鏱 7g9{~eְtwgG:j0lRx v7wؓMc P682lJd Sj 㽝-rAȖ F;8s-q}gJSΛ%%LJܷ}$7s2tx咡=u.V츸SVp2z o4a{Ez6unW {1ި\&AskR9o}:kwM˥g A&tqvte45b\M۲C8YjozS#Qa\w&r]JߏCk]aI 썩#ʡC目BQfE}Ѯ,|M>o\WxNqlf{O+51^]ӓa|3#FDV ;8t%۲GYq?dE&=oCy.6*B+̏F/'wq_'-v5Qq_ԠLhCP~dsQ 1[ x.}SGӒ{y`8 *koؿ-dUI_XHn*Ϲd({@~p|j:sg ~;יPZGQhѮ8N7?iҶqWvN Q,qJǛ!qYNN&x~!ʤQZ/f~/|b9-98nm=995P22"1p4 ݶ7\;0aQPϺR 1fM~[q_oCOC=D#'RIPDx:㘨؋?t,f|\h8o4u_x 8Rh$ޘǒŮC;4P4@ağW#cNFc>q} *M@Yw|GuJKu=c,/>.qg|Vb)Μ`ŞbLcM9Oa?qe@;jy0\ &p)s˟8Hd_n]#/NƘJڍJ5q=Ce?}tFlA;ٳaFTC6f[6\IYpVT^e^ FX T?c5g5tsg]/*tWYvovFԍ*@kEٔʨ:ӧP+ƛtGuqP9U]ܰeZ1D L'K ,#ѿI 8>n|NΫ}W<<< bPy'מ:WQ2:f<Ƈ%^ 4]}3@rmzm JQoo_Xp.FڶǦC4ܡ+jTid"Q} rG͜_Y!ߟ3<ݱ#F33 _렖\-칿욷0m"#G,N`=! }fe)y+Iq?OVxW\K韹 &}lz?+}*s~,c8ufzI;>Lَ6mS^|ǸˏJlGxc [;ngʘ,DjyI& ܗ\gشj18s4)P~r_/f Dy3;>WԥWp+ݧ7GAǃ1KVj/w~Ǯ?SM=C;̎ۚףѾoy @F'HOއhy]Κ ݫF<(,P|Zn? ^~"Jѿ+t˧vu^BMCo5UcE}J*'MO0@@۫٣Gr]mNMuF}Mu^c޵tD=q?tV^ H F*tw5chfjSQJкr[_igԶh@TCrE}7yS  x"$k܊}.:~~"u/-NvE F\:foRMjtBy1Ril褐 > M[TSec>OCJ;uѼTݽK\'ڭcQ;Ї6gѿx}#/V} BUv]bD?w3?D~A_[G_dh}k#ܤtUyiI@W=Jz^}mF^ȄA_uμgy_<=@KR yN^=9{3G|)]]8[&4|םLC? Fcy<{i" sr~OkKs>/m871>wG*wGP젚YA 3=[ S=7u˳L0LFpoy3K\?]QObMXX'>uCf@ x \9zOj6u#ׅ޲*Kaz.>xp6)=^R@$Þ{ʁϳxsooQwNAyJey4UO.0d hv?p|o #fs3wz/ zk,U}x Ms A\|BKwwdnB:༝\ۋ%d/՘A/ѸAE>{=.͵4oy^s!HB98q>4Wq)Q h[p}xѝݷ6g%BhKewfbž/rgIBQe'kٲD(K3-/$[$kXX=8G>뢇[WUaN Kw t#Ȭk."bxLOE*FB,/iɦ;XW8Rsd[MkQD㫯 k'Oo?ю88Ok+j~ WKqWY4V[E߁a {4/#[M.U|{dJxwor=x.݄U c^A[VM !}gUQ$U@}+Φa|7g-p3~RU-Әۖ"W)^2[W [˻:=7XpM2'/[E7+;KE)Zm@++R|vaY= )k5;oqXep_C#|tnp-q1ŕUQsJUy(|@졍! wq׉PˈlW!th/spxyc85 bgSȞ78/vxp#iyksOZ3˂KY/轂:`@3+.r&u41p~;EAwyBodbZHA\i}x v+ρC3~srcQv[ǂc]p%VZb53LCjX5I> byN%L7 ws^*O'_ L e=8'xhcfSnh?>"Zp0O@_v?ſPTD W?vωl4'㍡Vyɺ+Bp$~~u^&dB .OO+y9QO:zv恓+ 5"l<88~@w;xN~p| [ ."6?Yх^Cla[;b!8vP8 IJ~%Ą%LC1l i@ш,%s~x6g]I3R g@: \}g/,1_@'ÚH\ 7z|ȋ -s/񑁃ʒ{F.pt'^|Lb5MbpT?aX_q|m[BlAv|ڡ%ޫ>3]EAQJBjy̦+;pz1EeV > 8qsl8c{88KGz-{:!NP]A89gDlx v%",dǗ#)1?3~&08HÈ8 b9~P NgXo-8=8;>E $@Ag.:'ڥ^ߕ?aJݯ!f,὜Hr^q K_<'v9=q4n$STw |I8_@\/!V"҃8/SGm{M:(8 7 $f^Zd0?+8T, 9@|!$'gB1ٸR127 q{p(8SWcC髡fCIb w㮤ljωV%:z:f}YQ}яv)CWՇ g)/12<| bӇhOd\7Hb;h"6Z@,c*'^Rn֛ f?ЃuE#SXg Y /BPJorps9w[8Hu|sOXjSC@:ל {+ї=~x(~X( fcR?[7m(8K7 8NƅE?nѳ$E႘,88nsE:~:A}y p^( 8JxK"p*pwptC"GޘDK.꿂; hw6౸z;qO bΟ1#'\ݩGx豦O9 ut/;Nλ]cM|087P#8}[}۽6qR㈟d &q?![@|!:]yjw' 8vR?!8I`qy-qǾ\ 5d !vSl8 g43zpM:8yF _y|8N E׵0o)8x^ bY S+xSV|D+&9b>wI" (A, k-1H b{0y,bw}2XYccP~\ -x+/!SZY_^f OQO dop}N,80WGԖ$8F Ć_5ҙ؟|4 { ؎R ㌿^[kp?p[Ɯ@aEA8x~.$|=mO\HJoL}]brQGK#3$*?'gk=?Sa\U䦡kyH2D>8WbV>GPٞ&|EB3`sokL~E]d,[52i %z/{ҷ@;M|D<;SEݫ8zkgC/ 9!hFHbʲ>TG]#yZ%9#6λLkE8Cusө.1Խp_`߆~.Uq%` 89klDB Qs10وs=k\ټ_b>.Ǟ|lǜxeч39= )Tφ4q{Фc=S>:qD=۹_yr ΓT\ǡ$c\F?U|d пX-îns,Ր.P,3y .^Ұ>hW % eb1+!3 S@ 1Q>8R\]"\D'IybG5Z '1ϴ;g〲w${~>'>Bzh@<Q;s)@,c [||p9  TD]@jGt;f'Bc/@<[v@aW@QPIJ B Ӊ*_:wPWQaR}*oD} NB9~2 cϫxW4'2PZoB5zuVWZg b6 H ]oi>F^'OrTD$)p]b7!hPyońC߸9 47#6?s<sQhhn̓$#%!)꓀Ev:J\5 |,\FXpͥGM&lp΢M>scوq2׋$41pP{C88앂U 1H*cPk1销3>_ԯO} ~ֿ/c$EK2BEQdGxYHG.vg50ĸ.Utk d9`|M؍S0Np 4'5|s~9īO^98_%#-Ƌ9[u$=V<4/1É\ OciI>|c68ꀋuAEKx. CwwGE#=Q6hAl=C;E8ѩs-BICt+1+589MgZbC6N nojQ'Y*w]a%% ?_ { 7ٲ*QΕ O {/vDr6stPA$l~ݶڗCy֍ y{LK%ND ž!H"y^2z,5k%_1Տ]SGuqGKY&%[$Š.:4ҏ )Mv%5tljxі#D {GkتH _%R)ltm5g/d 8WXXʖg"\rfJ)L&K2Ћϰ//F~wPx703R(l57xc,5wyN( [{K2xY_rs6T[xK<+=ȲP\WXMȆn>:v;@ɼ !_iMɸutS))'^*CyZīd"+Y_'̯H O<笋kKYy`aS8tjؒJ\~}Hf?W] !P߲wN܈R9x%an˩Efr@ SlŠO4Cj^n G'KC~pw_։9"“OAjŎXj<_`QL/=[,5n)c[Tq\dp=QYeU焥t T6_8XQ$x~a5wc]~V[$X(:a-;0o6DUE5GϹ!rٸ~x1QW1J"|qTt6",?rXJoV6ױ5lums%/y[fS٤)վs^-GG%_Y< EXؑ9j5'm͗{ eu><)CѾ/:lCR&{WwS(:?j/[VXǩ&<'iO=ϥJ4,MZt}vG+AKXuzNP?_ ¼M6a-CkSt)?{>*w.>Xj+aX8H O3,"nR2)-ÉekW#$ [:X9hl#Cur[T+5cxdC/zxAhy!e{˷a[~cExQ#j E$vaY#'nЎ2F)s<7%ʌMhG/!.\Nxlw`\x_ ߷a-_հ{e?:C~>zGBE_ca_Q~8K OQ/;hy^:La|SNԗΝ݃홬kcsGS+jGx~s |){?h7&yܲǰNtmlR+e?N0e@[s[2 Y#,nE}ԷxKt qֻ Cj_IXϙx>37\֯?0>\帆vxn Ra x,=KR`ڲ3(RE9L@ExP%BjϞpIsZs)/oFTLBcz@֟4o"Š/ aQBL}F҂Pa]Rd@?WeBWnmʁhoKA).W|6m5OlSz86gnw5*XH͇JW"FeCWMgeʢmJYṣeyHĺP2}4Wϡ_y/˩,śh9c[؅,ZEC e#G[ m!ys?oE?V\ +^[Yȴ*dEg(E鄄՜,jz~ \?!έA^a)X966Ɋf~yC^{#<EJW#q~_؊&F–[6GĉpgEߐwˊ/JϼuYX#g~-^@"<\)b>ϧZ5!9¾,b&z1. zp>ס3ϢUMc.wjD;=[dpgcGFx,WfMb<  +⏝a]g[?aGa9ƢtV{{r$iG(OK/,[iW`fͺ|v_9d-\G[jRXa*cto.zDXᡥkT0 yg^8H>3 k?ײɟ [Š.] 2?A?/拳]g}g"9nYyH1d%Mah-| *~[Ӝfhg?pW 0.F-ǂ}v:YM=Md _I7eK+797":RMNgErsEvo u,oF?P&"iO{Ivo~ a)޿_"yW$ЏeB2 71Ok87"v;v)7ۋU笼 D EՎ#Ճ?[;*+/Ih>,Sƭ4 ~: ;{lXƝ?|:k6ʿ|c\ o9O%zgRBZX]E_Wya){-:1!1?qxʮ:9f[%[瘧D<lG@vik?퓆=KV|V~:q]01ye{Eh'^ixω&1[?-"l='_](Fmq!uK!rp׋ Z-(#G<ƟTv^u\<ׅ@ŅK3KHC ?I$,Q|7;-Ry4-,7 ,ٮ>Cd2a~Ao 0nz{h9+T[<jHvj/ԟ*ByE4Qt!MYPڍy F$A$a(ܟȢu5g a)=H]q$ :V9I;#73VϢZy_>3v&Z"܊KivcMG_m  kZ]s'Kqh$T:6iTǸ曄U⇶JX񋅨 )ByƐ3ׄq9ϭRtT^ƷD1s Y;M)ϼQwE#dGʠ[+؆ECgJXŸ|:[)ߚH"-_P 9] B*}uKJ)r[nA3z)k|N҇ k\ V7s]R!?Dy'WTC>#`a]S"`G˞ƼT5$VkKsX+/V|2i]X ~sPp? &z m#1~Puɒ6j!1/^HE' HK/U~FzšFshGNb)HR|4D$'Kͮtj@;BzžM"ʡ#6-qW&i uH ^zÏsNX{Zj!ZTwkq'0OQ$SZ)D) V}d[=97`(#ii {tSAܧjREg+:L'Ǡ}//ڿ(+v}[AR>D'sϊ""GOXJw|ⳋ䍭E2=Zx*)z\iE㸿q~Hga a|LHYa>xh*I3?-:5Ο"I}g:waA4-Eh&%(9OѺ>q%;D_-1L(axO {19V~H~c= [- ]#fp%9>(n7Eug1opH|GT0k'M~A&xhkV!@يT糅E24'qP~ϳ  )ѿT5Jq_GtzFX񄲕S4= B@רlU/ +x;mr>'Vߠ?#R|Va ;^@.*=JDXԦ!U~'Heh/Y%B0{Vu.kEcWdDx GB$6@0;PaJ-b:ؒЕRE"(f *kPOrLGSixJ<Z ĭq`+=4rWq)zRF))|EPZ&;y[>nM?V)='FDqeO >Bkh^h[X7iP@XIXq4-D;nWF7k2W}XGyDz_֯JGU^`pQK"v <#?c?dnKViߧҕyR:G9?KY&f"DeR񅽒;y&8x ^p5 폸Ϛ&\+5'Gd0[v(~\Or՚롑/+~ KwJZV\C*N"GBڢ0.8 x KAFj+,U+F"DtOm}DhL>J:eEֈc9d3|ZzӅVymxYEeDKRsrЍqK!Na}BCX-Tl5ϑQt"^IaVȬ轷dk!]7!(=׉7Q$bpa+HAEpqt/tB"l;`VxaE*D=;\ ehy2gvՁx0NK͑Y Ȑ`\Nqypg)_]d739_R}!! kEِ7ECDinQ}VlE5f}j3"Я2"4X$;]o..;t}iU\_l?^nP|>e0&`uI6HaK”eCTs GTB7,u'zz\j^T:쁌]yy9\rMa&>aQ1yLT'L"k\? R0AU”eM m*fѠ%/Ԥda*}S馛o`gծGҐx>yyEoL{"t4[͹iubT{>)zTSw*o"vnl S -/7WU'ysm*efax^Z4ki_CFh>OuVqi@$ӊF!>IQ#07q|]#_ ss9 |jv0tO&>ػx^M|]YQUHu3.eg 9P%ۿnBa>׺>M _$Bj.437oY|z0+nꦺp rv;o^#5U=*0qfWXNMc:KF_x5aJKD k7L|ˤ>_K~Oh4]ĭa\UF L-E+R͘ ˅YSS^IMYUK! ?YnyGtj},c6U>.uMU6ܚIm/\ᦚ5Ux9'(Ou'M&*FD(D<t{p pH_]s߃N؋xLjg'J?se2Ajc\Sݽ/;pxمL? > SA?ON߂ycLշo* s4_ʹ|͇\2n#V=Q~j6- zDP!5@t"dVbFx hǤүD`}͑BNV^\zA5~{ Ah}tq'HcUEMk^q]b 4ƟLe]j & 3}EkO1Y'W0cY*ojvx0U^N 9"p_lxt҅W 3A97.aryI 11ou7 ODKr_p dsIK܏uՎҁ7~K1jBa!,`N:WrDh`k|G`SXt[vi)UAh/OlH9a "ea>qN@?UT}YKj[v|/7}l+Wh"pDP)C.x%~> 4r,8Ҁ' J@s%.o2agQC!qH^aRzg!="}A~[oSrss3_.ڿn?V#'Wozox |\qU7w]M.>ܭ,EE Ю#Ԝl.lm_>*^JS͹Dה}/\?-g9B|z@POH(K<~Fk&wWpE) jgće_s-k,8#>Tsu2, s-Tt +M+o19?v:h՜Y![vm⾰c`}>dP{Haq|/j?`ߎSDP_)ߥuGX!L fC+ W^YkShO%M.gTgDތ"//{\be.LiJzw-\5NjD V]#.`z܁=Sh窣el+fu˪O:(iZvMuL5lJk4a?_}%9?ֻ? WN'{KJKҕ1sN8u\>g %뚪Nf x?sXt.'o0/oy豣?|֣HkUR;cُ0:-M0^ցWi33YoDq'q# w/TD~?* փ6k4QxugSO?0z6WV?+]L3(fڬC׹VxL`<)foH"g{X&/_:%"P[ݹO*@gV}$x]4Iީ"MMSǘT"TuzRMCx~g(2|KVW+L`*~`m f=@M#+/Hc׬:Z#hppzgE¼y@~+\2y9Tj@p)`ʷ⾲gVSFL( 0 V`~5y1U3@iЧDY#QkaU4ULi$ׁ. ʨ4ډrOo~L;$:JAtٵfn|b~~L ~q kM :Zk/qS.׉Lŏz["TK9OˢԒZ6ܧa4|-={-*_o(|UпM9g1^fhnq/d鑢/V^ő+b@$n-r;g;~y\&p?EqYw^~ө!/0T-fMW1_wavz)ɣyCI3ux0 w0pg5Ў(>x;?h_6c8:,ĺ&d hp_σuLqGU77T| *~u:炃T|Uօxe"뼒V54_o*:2?pp<1vؗ_x|1?J"YÔP|F[hh㡣+97Htg=[k~|O2\G%ӭ|0ϫIx/ޖ?<م~O}T󮑼{5Ӭ,DxOTP q;l#=|c[4_[ʬn85}a~ssEs7*cS10Xw,5hKG:p-&a|u`Mx5IS"vT 狐TezNZ C"}3ŋ]8Vc|ɷuIo'5_?G:XV|RN)eY. ]YxⷾGwdYdڙ5k{p>IBj@|^1"QJhdNNhx׌ԗ"|BLI+dn8:Ѽ{0(^"S]k~!g^N60~{x [o՘Z^tDq0ebukB#&[`w?&=+3/1^nW?'T߃_lsx.Z1>a7˙l{Y&MBx'p^1ƽ8;?ݥZ>1#!sj71e3۞q™nﮍxTQ-?w0y\vVC A?qgvyho?+4 \=zܠ~"026hVycE Oh _ f1rPNDk+'ϬKuxdg]}?#UsFr? PqSE6ݧTTȮاiWQ<?A*@ˡE1fMn"P$N*/31?KPՁL`VQu7ߛj~0 S9IG*=XD: 0qUR=z@Dw,ƷoҼO({vWmzxKJ!=2Ƌʭ&0^IPbl~Ԡ(_ I"^4{ 3QAŏUxF _P&+!njļ;蟫0;l}H)\0>]v7Ud|yLdEQ '`ܧ$SO|w>@Yk@-CUl=qQːУE;%phMR/ES^ %I'[yNTsAW /җm]d# ޷KjJ3cNj4(i{W-}_4c6ډVgecQ|zU0#O2IS;?9.3 i ͬOTc'bܦ!̫$% O}4)l' h2j̔/J'xݤ_7j~\q՗b6w1.. pѮ8Ju"<^P:EoT<@X&c}A1gzE )Lz="Y| /jD>}Eu tzv?E,h׋Y1.׏d~R=٘c4 j^#l䛽_>._NyiQ{Ҥ[CFd_{$LŇ8wF4>URН?wn8ƣ~A݈Gsҍ;4Ozl)SךJ?”]z5Fy? N< px VtQїwokq߷y<mp&` ^sr7hDО<#xGF7ܻ9]O3_@ڛSy7:+7)UDŇ#֘ѮR?_"*ۥ4*:'TO:8?B_oW^mx2bk5qVz==2xg/PEIrʪ@]^Qu_.<YT'> oG+#y rlbxq)I(n9V`ʽ6O":K.9@*Lq GO0n*FǶG /j.l& $bh_YMp=.GC0۷'"Fr_mƺC `<6|ƅ};ygl' \}dAi}~Q _\jF/)QSD%Jױ7K$ӿ9J$%#_Dȍ|"?¯i0UWѯr_Fʋ~ʈ~~]#;Fvt5kdGȎ]#;Fvt95rkDȉ]#'FNt95rkFȍ]#7Fnt5rkFȋ]#/F^ty5kEȋ]#?F~t5kGȏ]#?F~t #]ÈaD0k5Ft #]]]]]]]]]]]]]]]]]]]]Y#QÆFle2W_KRHHHHHHHHHHW֫eղjzlZ^-[W֫rj9zZ^-GWѫrjz\Z^-WWիrjz\Z^-OWӫjyzOӫj>Oӫj~_׫j~_׫j~ƒl%K5dk,X$[cIƒl%K5dk,X$[cIƒl%K5dk,X$[cIƒl%K5dk,X$[cIƒl%K5dk,X$[cIƒl%K5dk,X$[cIƒl%K5dk,X$[cIƒl%K5dk,X$[cIƒl%K5dk,X$[cIƒl%K5dk,X$[cIƒl%K5dk,X$[cIƒl%K5dk,X$[cIƒl%K5dk,X$GcIƒ%9Kr4h,X$GcIƒ%9Kr4h,X$GcIƒ%9Kr4h,X$GcIƒ%9Kr4h,X$GcIƒ%9Kr4h,X$GcIƒ%9Kr4h,X$GcIƒ%9Kr4h,X$GcIƒ%9Kr4h,X$GcIƒ%9Kr4h,X$GcIƒ%9Kr4h,X$GcIƒ%9Kr4h,X$GcIƒ%9Kr4h,X$GcIƒ\%Kr5j,X$WcIƒ\%Kr5j,X$WcIƒ\%Kr5j,X$WcIƒ\%Kr5j,X$WcIƒ\%Kr5j,X$WcIƒ\%Kr5j,X$WcIƒ\%Kr5j,X$WcIƒ\%Kr5j,X$WcIƒ\%Kr5j,X$WcIƒ\%Kr5j,X$WcIƒ\%Kr5j,X$WcIƒ\%Kr5j,X$WcIƒ\%Kr5j,X$OcIƒ<%yK4i,X$OcIƒ<%yK4i,X$OcIƒ<%yK4i,X$OcIƒ<%yK4i,X$OcIƒ<%yK4i,X$OcIƒ<%yK4i,X$OcIƒ<%yK4i,X$OcIƒ<%yK4i,X$OcIƒ<%yK4i,X$OcIƒ<%yK4i,X$OcIƒ<%yK4i,X$OcIƒ<%yK4i,X$OcIƒ|%K5k,X$_cIƒ|%K5k,X$_cIƒ|%K5k,X$_cIƒ|%K5k,X$_cIƒ|%K5k,X$_cIƒ|%K5k,X$_cIƒ|%K5k,X$_cIƒ|%K5k,X$_cIƒ|%K5k,X$_cIƒ|%K5k,X$_cIƒ|%K5k,X$_cIƒ|%K5k,X$_cIƒ|%K5k,14K %CcXbh,14K %CcXbh,14K %CcXbh,14K %CcXbh,14K %CcXbh,14K %CcXbh,14K %CcXbh,14K %CcXbh,14K %CcXbh,14K %CcXbh,14K %CcXbh,14K %CcXbh,14K %KFD~ݨHT0lE/_߿0__D>xb5?Ǫrz(xccJ(36uu_D7Ed;%9܆qR>4$Ćs^  *n oȩT0~&0.)h|]-|刼|ΞHj`flw&8Sc˟|H 4 R"cTX@` Y41=mܾ?~[UT3Knh,ہ??kow_<>wl5X+[4%g@_!VH0n.c\H)̎XL- _B [H|{t𽐊ywIm|h8D ʼ$J`"@"'9f-\sjX z+#Z~ D -v/LS%%R0-'չSs[r84͂q10l>"?c(ҁq|Kh|v@O,Oc;eṑctȯ@@xI\[T;Q&ԬK` sf\Z}K| v_0so(ՠe>GFt6|H|?˟6cHt bɭQxYw<|L 6|yuxdz#5n "g_* 1Aܓ&#on1_AC< E@x|9H5Nj#+>8UB"aE77*/.wDV=*G4V C={q7YXĸe'4=JCz`|EXh |HN^H|;W y,^6  8t ϕ]XQ>iXk|?7,Sq(Ijn>i4 q=i_|iD2o O/ ~/u$^>Qު |HK7i |eI e|߀i"{\V"rI t$!iT</c(gb#cg1&7HTiMȃxHC`N|0&M&?Z/ ΐ49%DŽ49L}^?e,ύ{<71ID >eH|^ٺ=8Fo໢t ?RNnoxHKlW  {i?A:[+L50>4 9)gR(Zc/B?i%,0%^23+QÂ&〱)cL !ׂqDzn [ /'_?Q0^"RDLE4Wo9\E0**s/"?O$%x`\aßv_u~kl;$ l/3վYc&vw"?ߗ}kNoQ>ȵϯtot#'-_ rչNS/4ּ\4i-9H:폱_!`-Y71T!{/H<$d0N+gU;HdߛRR"A%(<_rt=Jy*|}O+iHh@ʸUMD""@Msm\*_ukI38}K"d`ҏ`\gT{xE4]s?`ڏI1"'_vXh𽑨 4yZ=="?]_elq|psH!_*f³rz  57bMc3_C'$ƀH 1hBW!ÊA~i=Ax 錟"_]wec)kHT}˒Yh1>_)tmiy-gط툯پD >DqǓ>&/qxJ_E -0'|(`"h t ~b8$+<&%| *XKx6 cܠi!39RqcD<%B~_<{O3k>7Gz)c [;ϭH}*^ˍq۬#]:# ?D &8@|!Vh 2́qYe"F_=yTTWMM8.gB98[?Ko틓,8b94'}Ugq0sc>El冁E"_K$z$v~rdurA8"%W11k8<čo߇|_}u. 1҉d6S}=C;4m|*6rLi5?V,5c?|u9o਋D4r|gQ p2 Ωpu=nَ.uj5<%w_7fp`LTܻ Wo8%Y~NRhǁVZ<|~Dne8yIcQ?F6(!^sEjD+s0 ׳t5G[i2v+?o?OaIs{3NTӴb<34C 5Cr;վ`/PqoW=.7jsاʷ1>&ǣ2ƓIJ؀o)E,Ÿ A|s*Z猋,m}ʟnO(~Cd8iCb|UQ](P/qI*كqq8_E? ӌ*|ɠi$GٞWɰU툁oO/|*.W!Ϋtʗq\j&ӎq ʱ}7ԑ !>K.I_qNٵkD*(<>(**r_?%pWL9un9N2s YOY[[U_Y?tV.odey]09q6##yߐ52!}ѸU5_ZKcGU~fibG1t 98P0U2"qy 6>axNL߳*u߉їo̻"W+`;D*|va}5+@"^XT 1c˸]c/#QE>"_Dv1#jL ies~ʋ\R?߈3~zs׷s*/|P~ jGnʿoakⷕMcCWqREr<UW;>8#+Pyȇ|oW/3K68/' =|.׃%'UTh|%=Py]ʯتsʎ(ȱ14~,`/sഊUb6eG)] |?1֑WVv\YnKD.8xW黇6Ok<_K銝V/tIT2H-~IjO^D=A  i|@9zw7"I<~= #@$Rk2ܹ/xF#lb|+qaBH4Yʷo:L ,M$Y3^{عHo? UdN'1dP&W[X.dTom?+JV~IVٛDP Lb5V~EWLΐ1pwLG\m$Bw4^t+TXFc{{-3BnV 29 K\] UKJo!k Yp!o<;LBD D?r;/ ܽH%{w^cqsb_wE|үo;@%ןR2W&dӒOԠ't<ny4Oy%=-db0.!I@>w5 򛈤>R&T:F|.")>xJPOT )$!x:-xgr\F"9Jy[KvL4/T@5zLl*THR3HYb6yŖw:B$V+d&{ċ 3a/z}}D9]`W^cNsgȘ~1!Rm2޳o 7&yx5ꛐq QPਤY8/ӯr۷/:A$bx5<,^ O/ @F=RG~xs>dma;DLbP-wz #Lb>O:IF-ӂ̿;>2e7wP,x>0xgORm2~­R];\@T5!cl* R=`,daֱꔘynwwrϊk%wvA:9Frw Hl ^^7Iv> ^0嶑z"޿.wٱ2c}&$(cAMJW: ?f,y7˷^,YD!Wo2O7Z$w8L{}t<+5_wlLVxO Տ"D};[%{wE;[Nīt΃ے4{8+\|KgHV|S9l+r*ʵ i}/ g񹤳/KaG"BPnerv'!wo/=-xwz\7Ǥg2N1 c#,hW?\ur$:&9RCEIQ~g-*| ?mB$ RY >HPN~ ͽoJ$C8p $> fpwE|8>t<(+)ih/IC8.z߽O=?{X)i}]6ShpLz:/>wޛ kljϱMod jD>H=T:G@֡R>SRfTlc+H4<_iO,)UâQ$x.=C3pj`O#S@{*}'=<{tA#7;HdQ,&$b W;"x|%17HFj[I"aP~ݫTTicl)gZA渾o!$V >ɡ>2iFYeHRwnM?%!x ,g8}5'_m2tQ]!b>$ 伭'FjoxTUfA~t/V]}7$z z7$: sFLȪyop5~\bbP׀7ڟ|d>#F$& T>3o*N·!sWrTo  8)cCb k?a3U@\Wx_Z5|ID7YTm$~v(1^Ok[T| _7wJ]o- kz+v?6R\G ?>Ǹ!} \ պJ ThG*񃄥fxIU<دK/Wщk@#%In{& 7<9r# vaE]b X6It*Do ȸ`?[~L-o~YA<+e::o# g9K2 }۔}p]`\̓5B:ﹿ%h+uOOwRO/eC x^B8sdܚ<5zmp_'~poJJ0hWyH˺rQ=O_t7aQNrJ(גUVx#d~N7]9s7|5nmy*{%~1#dI' 3?'f% H?_ #cqS(w^U'!pȔY$Z ۺ'Z(~nO%#3!ڍ2$~Dj%OOH!*/:w5Ccߙv̷PQ.X d!2~(wsCZ/~VJL}ܟ_Z oOA&B1vׯ:ynZO{ǡT.zz#;u` cˤ6'+gȘ9?q>Llo/ փ̙}$:8qYK*_X >]q#W;s^\q"3Y~=\Tfx2W'T}KXLsH< *&,ezgY\1J_H2{}z ^A*OyvR $wT#+:g[oΊϣC^[>ho7RT/ cYzUbА5?SaPq.V FȈ *$$pyXSH T*U{%DgIzI2<^މAֽ4 Ip=*Oy(TU$r ޣC/T{ru=17^ɣ?M\~? ps.$щ87@k{3bἶg&烽]ߑ (ۘOjuҝ] xr=Q2#+-s ddo;2$_BU˪ F5ަP'.p+𜘐 σo! ^;0d6 qBcj*xh d%8CtdeajT'ݘ8gĪ~k[sD]x0-HG\=P 3ϓl]<2UBv4k*ц㯌)$ nw}wqwP?{]j-cll9~T-뗠pwT6]1ΘDc-Esv6IwyN[i"H`\t2:)G=#c-o{~1AKowAcd>m1NhU܏\[::^_@~,t5_$2 =q:{ j~cB_ /sgp7nb7=;-,Q"l@.=:󐩋8WCF}$& eAُxN< tC2^Pܱ6YjTw}) ~/匮Vyۯ5s$wǮV[|2Φz?>.VP#}6Tyڄ7ig HqdZ A , G:1ouʻPu ^B~U30xBi($UBFiɳH _qq!- 7=gK3x~daRr_{=Ru| +2R˲NQ>xAjS%r4zQm͇30)eG suYl I[79:Yu.fipxݣ6%, fA;;M!˵&9ϣ̘ )1\}dyI*x??i8n)@޸_bȒz'edU{ac9dHEa>&Uxkߒ$)YDO?R>+_ߊ;{>%Txs~UOx~]RJȐ~k=w-!L&1o?7Fs9urڃ2PMMS|e6$9r4w7)@eXBF/Ra3Y>̲2GUkqU/Ks)+kU \+){汳!eٍ:IBZu '6YwcMgۙ*XmG?IDѯ=Z} Ǥ.ӦߕRg$'!qu('ߏ >7cqE,H~Dt!w] H@Yoȶ! |3+}8tB%i?rgjGq ׯtBy*-a'J9 5^T9I8V~ 0nΣH6oI 쀴xN3*Ve8/X맲}{*8_~.dōz]߀>!ʹs@ Y5jOH~N4[?_O#7C/RW^^\8zxIgd=tqPds02q$;`ek2WyK(_ѡ)|_[Cd/I>-Kj>i[Ndv;~ $fuYPs<)d&1?;ݟxy >A/Bz+srӴl<{8<'zr-m<rGu~zO:Ze7]ëqӒ!\ܝip.>}]Y3NH ƥ&/59_r}H46 w߻\/[oi [ޖ!NZ3KzD!Z*j/1ټOdV2SKs^5AWyN7]ݛ<˨RUzU$na>*w)ӹ$ERܮ}V\C|# ܐUذuxa^}eOPyCʋ=cmH@q_}K7I8MkD T=FPfҒA?^~me4OHV71OV> 5{N}H~#rƏIlF`sh9H=zL"?T~HM?_xԿy+N{<"çyP^)sB'|޲[Pypj裡zx])s6?} 5O 7߂\^IxSj[A/ԐJs:R ee:cUp?usNҀLWΦ픿?7ygdbjl^Ғֵdt:_Vi*Aʁ'gĀ i&w9cdUb-5oϐaxϽGg d_|^T~3qR{5a?#'AP&AWxн_+(/u {.xbsJyI?LS}S kg,7Vm3Ti5S%;T?~5wuB"޹yS}^7ׇǸ6Ǹ|GVA9 qs~'!8xgb\o ͺv8:}ӮwFTxS%(B#!Hzm lc7!u6y<*fƂ[͋Sm!,x!k˴@5[noF WO幾"c($>/Z Qf˚AJϔC\J5~Okxa2IptQo\vR[Ҩ5Hk@Oox8Ӈ[n&牽D;ܶN6Brk:oBjt[^*&YP6zF+ѹqPH tPVa+w!%(_oKa$sL#/V?7z7RF3K[BrSʱNď<yi=z$^aox3_ƜL~gT'%LtAFK/UJXy<)Sx=CE^0~e,|jVEçO ݋d /pt*G0O%G$cx_?)qybRy_N+AJS'IO3gWp*87}RZHUҺm9~F!ul}>0,d<^E+y^=u-W.\qW_ ~l-YF~GOߥ!/>WD7a|iT,LAje/.L[2]*[E,[ʿY}})ݾbBoxZpwog5se6WvBI NP_xjHj<ϐL Q{\~qK:F#I{gc bqo܅^RJg q#8/QimW>Ȅ̷ aqi<$v|K 6?Vȁgpvc&O@|Ӗ6?ŕx/k'x^.o+Z8Hbs'ɶ7ԓdm$HlkvCӈ۵HH@3>⺶ Cyur_Q\uLH8+ҵG FvM.*PZ9<W]ʮ%<~b8;?Y(;9yVWzgG!qhWowx6Lnz7rEׄqU9q5(SOo A*BB,02ޜ܄md T8<** @HV'|_{CxNT}.mJ7 675T Q%YBh8%~ Q:A`H8$ʇ [o\7ܲ0 gS"j<Ԗ nqE: 'ec=8y>#y\Kn?;Y:T|kߍs\K̳|a >/O>)HL`wvA(SeO&Uu}|U_X'Jbg-ǩӻmpJpZ4qC8qKHLdNsz0W7\:P2 a$~G׾$ĩ,g[t6c>io[] 񋸮RήwjzUݫP&ed?s> ;l Gra{j0,>_ˉ++@)yG3APi@-{ $LBtoλꛋ8Y>\MPRp2d;top]" dgr=)C__y~"$>ܷ~ ;^P~~RW~sS!~x1L3~&.O@d@j7A{1ǡ+c{M S9AՓ>% 0y^b:q> @κ_[g Eu}g鮪^fa@ 1DB\wƈ +(*Qqw#FK91Fh0ň(4\ϥ{v0U:yw~-KƜ']z_;oT72@] {C yZ%} b4kGJSWkmztB2MƏ=LZd׀C#6"v'\tEŏ_\1{S~=b/uRX=Ja%K1`/Q7tTO-GÙI}r,-*F~̃OCy6?-c/^8xaKGGw,Y(=V-v8pő5~5]'v;7[>^#,˸m&\]B-$ Uz}$]=G0d=gz0HY3𿳾sp_cթmJfKiG?ǧ@ZeCԽ Z6~^P?a>_wx!|=l=izI ?Dȹi7 "?֊~=/7AghZ=~nS ۺp*MlB_ӎ˞b>]"F?+K}RT=Dݿץ`C/*܍s 'zR\ 6sAj-[^yZgZq^Ž pNtQ%>֍}O0|J=zm'q]3rW f^V8Ҷlݮg bF7~q (R=_G9-+*EsY:miRhJ W@c=LrQ̔d\wZ?Ms}8%Vp@o97J 9&Z =uyضR\UOQ~ۉ5Aaw/iC5sȯWyzZR{Hh:~氾涊sP'ކ~p6[sR~ sul5>֛s='O}v}<=X%pQIR)Z2ˡcwޫ34Ov Zuh\apG\_WqO$dGZڹ%\~Ս:l 1jݑu P(Bg=.^B>i$v= $w=eV]=ڠWk= <ې[;9b΁_(jy>yf|l(׍~O֝˱Ac}2y'@NO8QlF(4XC㱯\U5|Sg W-s/N1dAڈL*}V_?sם7+4GFc؇*bts` OaJý|8)u-Sj{ u_'EG},͙zI-k6󛩣>:u2g7.nim b1WҾC9 Sgulmb<釷wPZL/Wɿt@]g`>ă.bOۥ{tLepfOV?Zӊw}ˉkO5@ϴ?ToﱣgW{osm~X=L=ksqL=CsR5{_;*,Ĺ~V>_[Ǜi_Wy}>ٟet -ٺ@|[l')9;k#溽Q#is/Cm N/v}[Uݧ[ q}4-fÚϻA'Ź/\E9}6uJ_-hYܯg$#hw/I?)٦_(z̅܎zsރu]t^7d~s֯Џl+}Ƭ#j=LuzzJr`pZgԁ0Q,Ÿϰ+/y* j!ڇY>jX?@ey`ZGC'bt}:ni+),r`<>3k޶WSGJbc0u[:qagm\w!|`>/>q;?y:B k:PW5/ [՟{ )b6,=˾I]4 yrNs2}kլ >oO'i*O?H9#J//ű39/'F}imf)n I8wuo+uNUҊv~gкV]HS!QG/3 BA~.҆܉}oCSI]{P]p>^ 0cg!OM˳Lfװzi[  YW?{;YOP/&9't3PwźO|=6]uJ+ a8's0c`:lf}|©68[WC봆oT0o?s m|%'_+КƏS0| Gm;t{azaeN> 鵬;D 2z^h -͹Ĺ oOzz17moЮ6 jb[&.$Hх|=|yK>B^sRμ_αku@K|k3Rq'8Α'kςk]B|NӘ/ph{Ğy›+N3uP_-a=`t-9Z{zG*7{K>Q:';VP/t]0 'E+PxR-Esb >9괶/v* 6C߮z=Y+'M_Hyb# n;[ˑS?~#r=Sg4x#6[Yۧ }q>/vP/+s_~ uJe"Er}mKjsݻ&cm~FjV:=91}7F#Ij0^zOOME笚{u;F?C|Wۏ'g'۸R7 ֿ;?p[*w`ިv&^ ;9ւWטFc\ʿ!/CݨSUػX6Й.\{@u:~ ݺ*]RCuG_mB_Z<Kn^ljg+u|zOtܻzcR]VB:6ک7owT6N9 TmQ $) W^ Iy.]@Y; >E[b&H+]?X'Pju2EiZ|ǜVfNnӉt.s3U6/>۩MOWZ P}vҙoJqmw:_Ş{~? >CL!YwvMKDZ6`Tù_m(tGA)ns+C-ckϡCPo>be9# }w@J8G_hRvV [.G< $oݍrh)ߡg/VL#*?m4O= 1BwՉ~Ѹc.Poq-۸{:gԻ~ȇ=W]>%wfnu|.q}_;AWm2c}Ur)]6-:ǼsaoTFb?||q?\;>~M۴cC\?53T;J -Ǹ\JƟ`u_'z,c0jɗ͕au:G&/{q7?Iˊǟ'tu| )CN3/|S;HOe~Wqt9]%Z(ԮL:VxL%n*x]Y {/Qp?)-\1y:w54|s[>#?Ÿ~({?LKPAg@qe {q8SU6{Ӱ:q ݺ=\`ʝKgG]..)2m:"r)0>/_ڴ]/zҍymG^K}uLèGfc{,^<3zJ}-DU:D>8յfn9W0W1>LTW'R1c~rУ*ж^]-O1JmG"szyu'zy[Sw9ͭwC?j9|E{h>FpK/d}ǣJ}x_aHW: U |>VHN虽:C3|uHe[Hm.O­N%Rm[9/]A¢#͠v#(ɡf՚0AquoR tٝ/T~FKxҽ{/:/1s\__=ە0u~_qj :aPyf8lOPwm֧:V:,ـuwH,é +ַk,tV!jcTz 꼢B){'a\n6L;H3WVfXK)VKz-B*)$w1^?yS/oG,FB%C5u򽿔oQy?>@ R]H;}lJcabᏧG13|EW/QǫI} zH裗?ǾAM?!H(a뱘_};Mk~ ݹ7GJ-[^G߹^ 7 BUgJ4|}"\n?q;1_yA8!`>}Rv]G˷FK\8eۼW[阌yږ]۽U==:o_xðe_I+pƬR> `CoktjFfÆEZA nN{gZ"]'|]1`pժux\)1V}1k'jCfck9,yE^,[0WUi1Ыwr!fwtĵtΒC*e"$OQ\ϯQI{k)r4gjfo{3]e76I|{#Q/ ֔/A+wC}_}?¯ G:߅^Խ{{X:7s_ok㾪׿~$8W2u{?6#8OV{G}M4V,{#@g0jå#G ϩ5G\xT&BڽMRx^Ow=+r6Po5@M/6V|z~CA_yo@>$ݰG w0x.tuwqZΕ. d_hsY f9G1>Vwt6! |O2IT>>y̭VqZ]f){7uډ _xX||}չ_G]A:7}w~5FRy v/߰Y8E*WnU? F1ۢ??|pKf_]w$tP=^;L+<^_=[L53qVClݮDݺv7}.|**8bbn,;!oއٳU~ } /C_mШF#E{/O3s5a6TSi[)q4|Q{KwЯ_JE5ؿ_ׯ]ލ9_ʍ [__D_ě_$__d_EW}WAU|5_WIU|5_5cA3FЌ4cA3FЌ4cA3F،6ca3F،6ca3F،6cDQ3FԌ5cDQ3FԌ5cDQ3F܌7cq3F܌7cq3F܌7c$I3FҌ4c$I3FҌ4c$I3Fڌ6ci3Fڌ6ci3Fڌ6cdY3F֌5cdY3F֌5cdY3Fތ7cy3Fތ7cy3Fތo1oXˀ/C2˄/SF -`F -`F -dBF -dBF -d"F-b"F-b"F-fbF-fbF-fFK-aFK-aFK-eRFK-eRFK-e2F-c2F-c2F-grF-grF-g4$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$ K$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$$KB$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$"K"$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$&Kb$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$!K$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$%KR$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$#K2$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'Kr$'K&KmDХ`L~ӎݾ~!T 2ׁӢIl6?O;iG=N4NamO9e#gLdӱ;'N?#VO|Sz{ = :Խψ1u;v {)~C|2_ פA{\SmwH}zx(X_HaF a[_}O?2г\>yT*۽l*KekGyKWw9xԁrl6* ɾ` 7 Dh+t@3nAD72Jdh|zʬ7՜/ {[_Ah2([ߙ(&?%Yɼv|BL2&G{x_~Y3 g 6W埦Oَ0ԧ/lmd?93''|_n?h/F26-b|C f(bb.eC`췷Ieg,9։43t2?–o,%Yd2? #1-`|IL4)*j㫄2$^o1򿄜؁5w653E~ު崬u+:3jQ}ŵ5M~״Ze Ý,vRZA,Q;*̝X3D2w:szb/NH %r"$OT6Qi{//N73g)Y埍pP_HIFF٩5s_UF倥9xK[_8 ןYsuswώkt2?Ib&p =LfKq6ƅGJ#6^S?xb͵=ۭäu.ܐbtb:4scu._nnh[Yʬ7fM H:|29c,>f睼bѱƒn\D8"Κ 6!ɝvI[kOb3ߟ3Ფ;3d⒮fpIYFYKSבt{{~,(>s`)rgR $s|t*=-']MXe;][jLR\%v+hgDmIwHW]+tO,nz5]U ~$ܬ8i/*[{rY>=( T,lFҽ.߲^mwSYzN\oQq[Nw KkԪ.ޕ4|[[xIfa,jbIWbͱGpBA{I%Ԋ\x0d/߂ϏPܒnzM:]{0YoגnHtgy1I.Ykwb%]DҼ<"[<ޣf>xy%ݣαgHbm,ř'Ν_*U3mxz@~OI7+U|x\ƭX,馿.ҳmyI77nNs>R~^XmK*n4>̷I7uJbRsJMtælM8`]-(Z~Qvi_>zn).߼NHq6u֞Ԇzue49^$C ܀N7k/_^IôF潀Ol,On|3\ջ>'Kq'w8~Q]?|L&v:m7}Jχi;~ʻS>5\+̘VkGKc>o)閧l5 ӑuAܰ.fgv0 ǎn8 ~".|S0Q ljbI=꾗7{>/ǗSjzqgi@)mxt/9{g?R\b+=gᛧ㥸* K=Oy/ _o;}`yj @.v|IWm I^dy#s2k(M\{m ߿aX\6YW 8E 3,6뼩])Ɠ5=8Z4yNC_HSb,E-e|}Il OweBP%]m3s? |PI2.yIpݽ>vR\zVFO_Ԯ@3|_oQ<*{%]bxHߎYz$Iwbcniyo ?>`Z}w97]I1j}?yM|9sЯag NG:]HQy)KIJqf*c ]Qg:;jfX_O5p?@<_vܢcF{t ,8E)/_n]$]XW#_$]j I%]re)<ͷp6 &xXFy$ݗ1އŭ n=aO5>zh+i"U@%|;jdۊR\ Omzo%}[>s.-1֪Av>S2mUOm=ٲ^*-źxn~A{tav|rµJq[\8Kf gkL{vtOś$r=>` õ ^alscnߔfa?8+GQvt$ `2~!Á^ hhЫ: z&2aX ݚur=<ɞWA=xѼWh[q@߭ Ȃ^ ^ze=I9R.V_t}r;&ŕcZN4^>Zuh I^9ٴdxVSG+ŵ(W}<}q۞=hI\Vn_sE]Ot긇GA_(Q&|ț붊 tg5 .<~ ӦzYHqr6xqy].wxv{׳Rh07".9ydHpPۖ9E?=0u̫g7J"'Vun>JI7>p_g}\T|@Gi-PU*A)Lnu܆}I: ѽ^&Fqknj;;:.X`k]| ) +Yxɻ @^yKNqc_/IqI[j *xpo2-}f N~?-OsJqo~)޴v)࿃nR5Wk5VNYmo?q"5-3~@Vm3 ty[vG4Zw9 t16fnNW[\URqMui~mS)HͺM4t SygÊr}/uk)ũş=;n0ȓ+cC)tx"vtq.xVƈep?݂ f,%ȫEs~bXcWiGx6{.T\ۺIFqciA]*= -iiet~Y oG|pF+ O  ~N\ Nw=9\'#ǶQ^rеp5獶mr YeJ׍o5ŝ:rj^ස>RR\đoAwGnRٝZjUQfr5|{\e?^tW^XR }Ԯސ+{ݑ A!K7O:vw)QG :qzF`W|>ȕCmkbEu+15ȁt{~vk]+}^7}\ٶJG|S -W1ߠn&_\(5ۺ Om3 [LY,\@ G[;խ[e+tM6j@b y lأoU~Sc$CpMICXbك#0^ ?ǝ@7DՃsO}y!X s_sܪrO }~u^T}M|l3R9W̋@ow}J,6-㠟oƅg0xjTșN?]"p==:[Plt;׬;5?UbǞol_`4kyk|;kG;<(W/). aWgUʹ}xc@8W k_7|g 1bc#=K t<ObDZ=[l}saՎ{ܽ!fcM8 U`}ܮuiOmR,ݾABA9]9wu`g//;窛:z|)[s5)2<צF<}; [:T5hOc뛂>)/[jsSlnW:<.ڸA{5{v(ȗW-LGsG;h?xbݴ4_SuqL_7 ;^cqoh| ߁kBUӷG-ց}޷ث]R^UX7G><_Ŵ+W=7֫z)@OOMWm#ŵh<{4S/sufW|13@/ 9 v>;XvC'}G L͸=$C?'f_,1sWHhaOօ}^~Z9bʷI@l ȣSyW>@E x7iI ]N>)jgUFs_y9eW^b w8Ri:8w3|C[22:ףxB w6j鞯;A B^޺D;Ϯ?Pz=1jywWm:Ěm?ۯ.|'\Ug67im=ۜ`^.s_4RkAns+R\CF|!>!B>:ʗ>Ws0?C 4g`LY2x ӈ *> {3 ꕣR=c 0&5'sp>؍}>b/ȷ>qY|kf쨕`ŇO|àG T8.E?sL O0 GP3ö]tv\p͹b#f?;{|K݀w nlܧooz ?{.siS<@,jWn5-]Y,wAòe''A5=ΫΘny޾mR_D`ЯIPЧ/;XMI'#UqVhwtS+9g8"zR`o͙9L[`QWܴcqw^[M:܍/ù$&]{K헇CA f ]GOKq#[sϸ2*z/gJ@\9x #>Y+ǻ\y!ࣃ.֯sp^ۿ}npc^Ik̷9Ww|7\O=lH_'Nwi/SA9ۍj񩟃I&J8'ur_4ͤo369t:1WoA^^{ρ7;Kl?&/N`;ﱔtl?moO {GRYqway΀}~7TAo-8z;Oҧ]bQnem_+V)κmǛ?9e|[6\x¾.Oq9fecm<.x`y{>,^s} ୶_[~K^tFwviJw.\bxm:s_H;)ܑt5v Qj\cOJvJm4: <ةL:95tݩU`L_6Al۸|oIцӧ>z>};V6c،X kS!_>W-Uu= {/x2bɉ?'QOZ6y6~k@Ϲ |49;rgulx`WToUד*;zU 75f.y:bBofw/[mhOޙ\QyUqo^bUf7-]DLJ nH8۽N`/X[o= mXb-;`-3iAFYg4ó؝YEqGN-~p@/<x<J:3s#+/Tv#*ݼeù bgc\@J- cu+^`-o8+GϾ0x ۄojMjaD!o>_b*8t7gW|`F 'txywG]Ǜ] _!ȃF;vz[]3K.z"s%jbR\,gw"p',hxbOwv|oIqmޞ~fC2eѻ+`i{Kpw#?x⟿Jҩz^[Ҟ{| Y g/I? ;~8PH8Enlpȁ/+V]EQIcJnW{K;+t Kq].>"5K sEBik:اׁ^VЇ%gM3qjzJ";u{KJج:K8!!@W{W|Qmb)VnR\xɒn}a=89^W zE.Rt/7ǽ!3j|~:إG͝+=tK },[s{6胋EtEJK9 Yx?}7w2¹n G7n 郎l^y|)xV9}oES}`>h\z ȳLJ6N2:׮&Ӭ@Lײi@ǃ x;YAj&ٞ)m®.3ٳ؁Z/7AG>9Wd􀊠Ow*wk=%Ms} ԋ}ݧ +J%Lf"k0lɱ۲ɓSoΎ, k a)YzW 6ɚUew5J9-ܜ k~p yX`;.urƲA -qTX ]}tY}]UxFdYeͮWօd}(#k&,nx]-ӓp=m}duƞ!k6o:vQz9򪢲ҧaSK'ʚG6yVEϙ^֭ߪ4 aߩm;# dMN:T5ގX`[dMiM;"kJ:؏<5u|_ޏ.^7x=xOZ{*kϽ)aY=VWԆ܃χ}S/k*/>QiozX"J6 eMwC5=O>IV7&[.yتBzKYvֽާ%Lu>~GYO3򁯬+iįZDY; emïR>je͚kOo)/&=j~]aDTb~:}*YaCzM`Yk^۲WmڲWe̓m7 5[cF&XW^CdIy6FuY+dƒZVvҾʚ& +^;2n.*tzJ)rxugܲfPe{F;/ks>;ӠEYäcrاF!U;Ț#WS8FpхF>}\9xYeM/¾6@'j)g5VC.V̵Wdmgꇓkk(k>Dy[بrx 5sq=<^EYiJkdѽ'.e kƐܯN5^ ͖M;Pa Y=p-K *6oԩ ud͈u?&'{û=qNIв+ڷg^r:lv6I8?zԇZ;o47fmbY87t\yKeu]ẙrc!Yr͛>xv'@wKO^?ຽ,k8W>g#Y[oBߛ.k]f]gFV?^tyYۧ\r=&{Nm5BQS,f'k^ rc`is]e[nz|Qa4/n9 /nkv&YsȻj 7uF|qtw=:Y;*x*fvUsCJɚgc;rP~Nk)߿uPּ("<^i%k9&krZ]3d#>Z~*}{srB ,rZY۲'ˀ? &q k=#KVW|wOV;uYm<ͧvǡ2ֹ;+kt=ڮmYZk腠[Z,H4wii/4z}?ѱۃ@/_vMYSa?{ tM#Z50q wrlZ>4pY3j) G:VvP+yn]&_\{='Gx)ٻ C5:gOtj9庼+%kv<\W: wnuhwymL;T_a')zjtD~`[krqgT"_jYAV| n^{~ 79x>TXO<{אO -~;zHM5(ܿ)~Տn{w_lSw9gl5&*|qm͠ŀK^9Y<馑{kΥ惚. w<[g˰ߩm>j}wA/uw:')k93ywЛz旵B:Z.Yo.^g_uy29sڀz>M׎6i4L9*<gj:}>K;dW+ k9y|qTYv׫y4'πNKJo@l6UbX,ob9ЁC9"dM|8+k}wΩGۡ]mu=G&{e< m+̴Zʚ'L)kw}{6p杧+ޭ^u嫕qlWKGtq7N ܖKm<ÎpN=E;?l0}%h)_GYx_};?L/Pe6'%kTVM;jYCVZ)OYs*Lq*,m7mrYnL ].#9n=\Z|Yb/CGU{p˄USF-Uzrd9)BsYctY:(bDMu{d[qba*~Tl xu묡U;>ܧwwVk9<>YQ7}?Iz| zeWk@+4譪[1{kZT[-kl䓦j[Їɳ7YW73 pǀ-!a5]&-< ک~ycz~so%YGwg/?>oX>mHJO>Pf~L FӖX8DVZYF!89f,W9xcC\oV rX2Ktz)Z.@ohꘅszE:Iuȓ)bւ~W\wpkn̖vDtڱm[Q;YӪe=`]\1솋o~ӳ|#nk9Rnq!h[i+7ϴ}Vr},duÚX9}K1ae9wac6uV;wv"knrXϜQ}18]gYǖp9,qm:[䨸 OŊ(_:2\]KƯ_Nִ\3i} |<uS+pԉ]=[뺡_\`]}srA*%w ߕ_n4)^ep֍Hi..yxM &oLxcS'm{rώn|Ԃ64:[]3. N|rxta 2BkqSVMXY"[ϵ5y+}`Uzz~gᄚ\>6αNYS2킽kgc ǂ޵{SToZ>rYO8}<*Y)eۮ`TV8tS9MJdkR`v>~{[^^Y~=^<1ߊ.~^twţɹ.퇠Y!7&~/*ՎԠ?:oD9|ԽA>m~VaWa{|{~t.VO~z$mdu/ld}eY=Y]ٸXoO9LջYk6*jj5ȳY֬YҪ9|\L5qf}F._ |߄R9W:ƃ}|vX(vҠ~Fgw퓬y=e͂{ ]'Ӟn; NȫdI(?㵾@7+y^e)䰌uO7*k֚t_:TYשe.RK{QWgi> :w%F͙Ϲ{)jT ms\LB>ȷie{{婷y<>/8-۬v(yK6$k˖)=q$w-\R#7Bb͐K8vr%pnKe|#oem 3vX홳 Jʚa}ݪ4o^^vJvcN\ޠ<՝()GeO+}'%kH](kG\<4Y(FsQVW9˶$ Ӑݯ+억_T?],tCdC.^w}֖3dqR]Y9E@7ݪlN"u,!hcleM1O9˚ZUl)^ըЏo/wq{U\|Yɝ.{{lLYzV/UCuJI:!ޱz냘3Ț6ݬO4߯<&kz?? 7|Ń'˚/g&j?vV!VVXfZw()>nJͤ7iݔdkY:j>cR|Qko)>yJԈYR[$[Rʭ_ _|w))>qL^y*Iϋ8^JbѬp)Ԑ.'uU62(4{sKY%B[OJ n e>o/z6{ҹ H_kNU1N)>U  _FM9t?ŚJr@[e{[վ*ſ:oU)܆G {JQ.1qXXWB9J>lQtHkϜw6|)T(ߦ`iy#>i9/k:=G鬺LuRK5li'%װ,WDx=l\?<RVO64ROhs[ǰ_.^U.xV[ȄQpWrAQ}V8Y^'7;2-nybӺRBZ~>5 J &gw X طv⣯'V :%pew)YsNeH7 T\vLRB>)F@/l-2*t~e& )jwt./=1rgWNr>~5 I e m:U{R@?k_OquBvw`.f3;py승׹=\(lkZxM&ӿ.鶾x\er9k>5RJp/1\/rw }I #76+\A1_psmk}|P1O*QW! (p;QzZО@G;V4a+\r@qƫa_Tom:eߌqr(·zߙRBYr4忤pZsg:߳@W7~1[J(|QXkr.οΩZ+k·IE )v pOΏHO˘ <,෈e~KIVxxPK[j1ףǵh9p;͖!ş{eE?ڭ7/̆5_Ɔc$~rf^eOt1)x:8hԪx)>Y cm<鹤R֥[prcW5'/_zX pN]ƦyyOl-dډpMy}9p>n~QJ0%jV/Yq(ϮE@~M܊>8@/6Zwu-7 f݁NlNz9 ){RV|Vt{yfm rfKGO&'`R}{))zm>F6p >8f}Weg/ | zͱf7 KoyXMt~8kh)rRs{aL[WIp\prhќ~:=/j-^O痣b6o-qqmȏ[UQDo?]#;Ix{H=o=oeGmV> 踀G;6RUFi廬x)G/nn}u5ojmz;v6aCSo[>Qp }=RZ)փV ebs>]֊Z@': ttۤ#nph)xagxu>w9br=-tæ6ezf0ݳo_r}Ӯ-W״~0ufyp5h);iΎ}^8p)e/?1~c`\Dn۶'L*_ tx / Ac V=q\tc%φ2?cR89_4˱sLȷ0Skvq)7۽tc)ȱusW |sZ|?؇[}Vz_8Ҿd2Z@Iv}8~_@.}iq=G^iAG=~aۺ<l}Xϣ^ ?8=>'붵ǀ\ңj.U:iV3wWa܍0g˩U LjqXxe 0 gFN^npK۹ߎ3;V<76<ԤzKnAzI^~zz3:Ѱk΁RBqSŻx9U` חy7O/د~Wg4X{Yiڋ ޽+ٿd!~灞.lwa,Xg_ُ2eձ?*z^Nr6ĵwqH*>( [\9;wQ\at߳H}_XoёvOW륍O7_ץRyeOo}Spo8>R}JL-ߟ_]&ŷ`_ߙ 8;. mN6_rzjzG@FY7iº]VX zX[vJ%|f]sD́ahwSK;\AW!}2bXjags::Oɴ ZVm@~aeK; nuߩ@-{)1ߨuO:oWi)*.ρ ܒF~ZèC}b)?-?}61#yŽWjoE/1{+eopD.BTjRw'a>zȝCsI܋\?;fȝÝ~:?p۸*WiGL|˂"rJeJ i zW*)_ze*a?ّp+Ѓ+w}܂+U0Kذk&goOG }[GNs5{/]zKB`?nj~(Kr>>tbpI g'~(g^q;yg~yݻ`&~baԵƸysvH87;y<{һ#Yx2*w<|Q>BFx,a:,:. vӫ sqma.x;ف~q19ܽS?ZVcߺc㰼cty>zxsZ~}{ʝ_{h;s/t9Wf~|V.L[ r%W/RB˺A]X5츌Nl1)@Ҋi/v]2@tc]۵v0^:c>f<)s䑤z%|G%7.K&{< 3g>#~E{w3rP`燐%4՝A/HOWV^/@.%[\V׷y5řk5Anq3w 7`_=|!i =U0L]#qt?^~Ȍ7ETy\Z]'V߮t)!GZJk7rogjb#s ج޷9U@޽D{Y1 c~. 0y9~ S̳pi>AOjhk##ANҸ?~Nըsw*УI ܶX >g&=䄮AYzJyL0*v eL6Aa 3Vlm9u'`M =.^r^_z?Zq`3)X>/g65uf>$=Husobpg-\2cQ&Tu1oǍK*:ϳ,/} xQɺ^^drbB`OND{wz}~<z pRRҪv|^:|׎1kh&i&v;=a7|ME@?u0"@Uy6$&/gfz< >_va()`e1 =S PwporG߮so >=)`_/04~=V'6ﱭ%೷N:m[1qT' N odNJg31yfo ZJSj-߯(~7?Rl޺ң[*wX߼̍Lُ-ú7 yofH< 8\ ow5 o!͆2Oo,W jof o ӧ$Gx)B~%H؜ӤvLsj\7臤+]zTOMmN]p\,/.W~{gSgߺ\:,| #IJ:~Ȥw{Nw& ?W)eqÀF?F*WjQ SDq/et#wĘRB_5eq)/=Ǿ] rιsKvv{{)ЗS_pޞ 6>Eۂjm_ p=P쑋yp(&X:__\ mγ'r%c<}Ԛ@練R$X'ntH uO|>zV۟[Ωnh3`.;F!oA:L\Qgw}W}q|LzHuXljM:V hr*~9OpN?ύ]aA7\>m +\a?mYS([279k2]o<lƤ] }y^ORjs8 vUE~s`̹]vg+;vx`qӿԍ 1;}?m[!)؇cu[R1GrL;m3GD<Hmry}wA;ag̛'Lܿ I:esk-}׷u S[l8ݖ }Ojs]w}6mI8ǴڰsqՉ7_*l0.V&`?vsxGkt!pZp}Lmg@[ ۙW0R m߼tͣKz11 oKoV1JݥF{-m>O.z8zs1ؗy;?1ܐU{:K '= dL7g&Tu _&rKJ-NL?=o ݮP㵃no\ܨЍWK䦝vLyx'j8z @. 7re=iG[xyP3 hy[<<~9& ~F>%`ˡ&\7J~Z=1 ǿ_4p͡ ~t$zA͐UV09wz.|rT ׺t<ösh F=:=cͺuR*ըu;;@?nk r돞W#m-fL}hS ؏jr!&.:6_3?\,$9Pgy`FK_y{7{΅w9p#.,|<؀(lr\A~`Պ媒7D}ط_=/ wAosr* Tذ{o}쀻ڶn;pMا=f )Et<+ul5vABӖ`袺wɔ*|eig@:%\5* "˰﷛jCg尿:8K= `1U; ;:!cTk}RB%Vxjh8MڃO??8Kuټ\n'vzl)臷] k(om&7_.vw& .k|US^}G`זLjNݕ;zq ?)uS&;;\bquf-^7?4k3FśX|TŗA<9Q񦠟kUYit{$ó`OltJs6+oXV?ַ׏dN$$\S6q"t 6/ϟ2 :U* 8[}gFJ89*>*jtڊ<ÿbv?eIW=K?B|]\Ez8O$GenRv~I .q^.[mӞJV#&Uzfŧ Mm]9]= ߗNJ6!%m3Ruy*O 5r܉9oNc󮝔u@Å}ߣ 4%Xʸ{RBy9i|M=W qp{I|bLZZ'>~ݗt5b:^$h~KOk[ިh7׽DF?>! u9z^.8A:yk:0_>tqWN%Լ>&z}DF>eLʷ3RI+W-*}mq^_wx]|SȘg -6w1vlYJz>HO :2=gׇr%#! }"_sDu(W]p{.t>ocp=;T օc#frZO :9:>(|R슛~+_FUj(gop9H~(/p_oz;/+·S5}~ 6f&֬Z291K,ޗ(zGbϹ;+~NNCEzFz*NC:qOtINW1ᎇsssBE,GethGH p= >׏zHHLߨ4ݑ9G!> @Qs:D:G ]|q$:@^sQ_|_쏂Q?9:v8.gu2~?8Pl'9H#ߖ+|)&Y\OZGJ}}+;׉GܗKALO(>?ozu yo{-l8P \ Š:{tN\|ezE'\T?E7.~=.q.Rk|^J=U:i$ǖrMz wa~z8d#3'H+ E= 5#1᤟76x :9C|f2NtB3}AχP_ezҵ~3/\'/';wCy`iq}|ƿ*#SFE9^Q~߅~##]#=o|Qu6!yr + Λ^PRGn +<+;>'c0|N&=fHN1w~@xǠ}DOE^I|.uOIn|tΟb+כ8 !].@܍t&Ƿn32ޅ7A99DSOW[Iro])ׯs9RX<nNvr9.W#g(2|eʼnyEq q 9۱>;sMrYIۙs>r GO:9mb Ž8D;_7p;#<F$np9}zg@*x vXF oi?3 q@f'*:7%;F*AKsr)xOq<|8 ++yDإ=GLoR݄S?yU3y/ΗD?썫߸y~p/3b>x yq/2vx(߹ '\ zT/ :qy=/sta}縗/F~9!aƿ\_xѩ^>g?/w),Gx1MSaq;(.x<:7P+~6˾5hwGz~_i9qXv x)!G>`|S,DC:sgqBʋa'ӹ_ǟb q'xu/vO|c!Dxo+>y"g r\q<U|;WryGU\P^9D/,oQeTp3;Hn_~ZԽԑȿ,;@W/պY!7! i3}A![ _)C49+1b],~Wu(Tf! ZIBy~ =Tc(>ϕ1'[H, m(O&uf)KqDG7ÙD=Jt 2Rr{9%:2lΊ *t1~T/CzsA9#ʲz9(ٕq߸x_<8GyR]qy HHBo*}u|7T[>73"y.ΙEFܣ+ON̎up!FIϏ%LΩl7:S&H[0~\ȟSɭ)wIds?6<' ۑ< ~}@0Qo-.qtvYx#ϗt~Pyȯh7uSLsٶ=X$WDn'r>R|jR'>CK9P.!]LjP&5I=FuD裡@zeVO_^0X)}<4 NV}ʨ֮7&:P1d_\';_󥨾846l{>Aԓx_Hg O>,c2Mh }F9S2~RHLW׺7ĵ<χzX}}aDQ$^+"\>#lNNtr]ч~ _\d~??DZl\sA\C:@? z<LNj$=] 9 ^g=:yHG g(y?".bO%ebu~z?'iy_~yCy/(XOe~l[*W/[B 6Ky!u}'~.ԓǑθb|}W^Oy=b ?Tq^0~Bzy~ A"nC{U_`?@+g'8# z^C`:yq]Q=^N)y^ 9NU9YiOq E|'΍:~>'z窇ilȞC/Ebr{Ӄq4o2cV2y[|^E<+KģD/ײ|VKz'9ux(=-{BnD<}ey"|N!ol^M>2/ ȿ'p3 ?Pooudr{&= nrUĽI_~BbW݃UƏUzUee d<^o2yF9?uu7!=/s"/%F܉<ނ<;2P#x ʗR%.|iz^7yޟU0Pߦqiq6ϟqfa.(w!!^;gτVP١S̻L-Zv3cͻN 휖X>@esrݐxOӖqWA=Uv;e { ]ZkEܞB$ٳZ|ʲZI(CQW^xRA<_y}24϶ZUg~!d.Qﳼ蟶|fUaQwޢ>+ O~> >*+\'5Q5Ci|̼YsUAk,zЮxHHh/^xFjӯL}mb8Nsw\3 R2+փ>އ @q_ao I|C:F:GgwW;q_P ;!z똽rw$F yN̟DxU}_D<gx?VI88뗨C?mzq߷5%OݟۥP=/~S뛄P_~2&|1m'"޾[?F{{ge,CvפX6^I2ܪ_£=d?.Y9oH?c|Tf 9A?$Dv(~x>~z'K :dW&Ŏs1yD s$yq>ȟT :wd4~~Gts*!y2#D9a)n\*g~x;b]H^Ur׼o#Eu>~|\ø ܉Ǘ/";*:- ;Z|?g?ū:H:7_YPaWp7| :7"*+@>~v*?x=x3W8w,6Gux+c| (/"@|"p"&(7}yE8/\.nuzT{k zpo<]e`j.LE~E:2[y:ɞE9'P~wE]q\DQo}PX#Dj4sKrY:^_{`ytT/nq|~M7C TU0nKO< ;ۗd QYtAǬרp]V9CVq^h!x#}gK}E :yqGPx.VF?Gcte~`<+bYͫP_ VCx_u\rWq'~W#Kl;Bz.gaס<+GfQwd|ujz~j(φCodh~)(Yn+꣰.1c?Xby掴OH|Ey'36~!'wCqt!}SW('x^"~07/];yyfMۨy^?;ssx>WDzNo`>6[~.L<\Vj0N&7s/&{֍~ă<psx/=1W"߃k0|x}y^u|Iϟտ]Q׆1ݗ'>׬"^@A,3>{Y=߆82`!'㊾} wa Op[ا1ܿGys\oRzA%F #ߦdyK\@:.ox>)Ds?8GLB" ,Oo8 ռYE_6AAH"Tx??0@_Bv~1uA5(pћo Xx󔓳+:G9bcOo'>ߌE&Fh>b%zsѯ\e/P8>3Byy߅CGWEUfc9g/y^+ :sy_Bp=]Sy@)0@?7fj}=PLw}˨Be7?[ӂ1$>0SdHU#zAKh"nb~Cy<*yק >SܿROReQ5(.~> ~Yv<(.}0<񥢾Y|~P̃.XPro[$X*wWp5+M|!{1Cy~?1f/?k_7>?vst޼,G ;?RA|C\(\}^oL~~.Џ*Ĝ!fP.%ʗ牸*/)nQB:jX_ E<hTcNL?(sf}c=?q?g>-|G~_>E>_iMSo<ޢ|c֟Ǔy맪>ܯ?d{{lgfW>UL[M1?)s3NP2XByd$x|1Q<X ߄ۜk7 ~Ey\5%?>+N .}9] ?鉶$ܨ?*ST9a:IXZ۶| \eI^b$w{NW ǿopaPǹ,CxܯyVx1eSW̟#(\dy+ 孡.<'|'} /t~kqHϩȻfs8W{xn7=9P^ГBߑ~Nz>Z/6s]YEG+%Og .|I}aE^l?%v65n̯G8g0N(Oavt.Ik_"/Ky>A/?bFxk,>"_]{n~יP}70/Ag{\mu|m{QOp(pH$N}3v#ŷx\?O8S뇨7"MG,m95cm< (s;թ9๠|$E?Nux.\~#cPn@Zߒ\V_/>,A"}iNNX#oyoEܯyH?W#>y ,U++OJU5ey$X|9Nu!~#sޏ@}Sy[\N0/A~nq?⾬MzͅS4dﱼk?gqyżgq] >a#k*@lEԯ<O2jy9/8oe^<Hoy܄קA}z|nXN?oQ9<3缊u9'3dhn8 uV9 ?Zџf)Day<.)y-9Oc/0?ZOQ^]Oq/cDD(BN~H߼_2++Gyx>GKp}\ <$9y oH?;1=Et7DFz`ނqX~X; ~'߂}Oyx=g|N!h?a=Յ1>}OK}|3>kJ7 륄'FwY~t&x])kbbs i}yL)>wl.>Syz{Q:<'\7qC+^EO\hq Q\S/`} p^/A~i~$ó֝"]|lf7M !:}(Oϗcy,t̓q9>nj|wO7?<?ByTw(OK~ ^)@""o_䙐o$g<(|n]yus\9,>R_:~"Myh, MsNBE~)u bsߊ󆑮x/['n~^4T]ˋ4o'sHߔ(u|]Q^sa9>Ez. 6T"]<!װ^};"&+brҾqz$>CGMSBs~WR?@ϙk\G|M>Ͻ6 P_i又8*קOJgE5?R=O2xʺUFK>W$(C3I{ŹQ}\`E>ɻ,TA<8}|,DbD )+s@X]1ב׬f.o5/r+2ŋu<O?@_.Oi1׀Qc_W>}9dz_$܅8c0u {'@}ΐy>ؿ"at6 Yj$=G MG#ż@g p8Uԡc^ ͉}Y^%<(;o<7\\y"/@Ksq|n9;7=GsD> dy?ȧ0{`y|.$s3g$_q=< ?p~Px~9$XUCqOw兒/뇠tzd}ќeIJg^Ǜ?Q|Q;<V$R?nky&'Oωc)dQ񾶼?=aynCsTy1Ӡor B~W9JpgCs h֏ذ!}/֍r.wQWywm!bsk&D]%^W{z(o&9}y-͉}C:2?F}L"nuȟGUXb\#}ՈYʪw #9Y9dQ|({<u&7y܉XE_z>oyf|oJAP^x^ng6[Zk`,F'8 鹬ydt}p98 J ʿ8ݫOm:JQ?o4@ U }8<_zgK.C$p]V]χC-gfv(wpNUػ'@}spݨ~nꕬߑy|8gy?;1x>ǂ%O7P_]y˿!Ϳ[6R9~+DYShޗ'/?_OvVC}Y^X_bH:y]5a~V/a H@O&_~30Ν㾠?Yϳ\9<iߛIRW~5<^G>aH(y7@* >P3,ߕϑus6>/8.+Gy_3t}J=@8}19NRǵUG)<ۡy{ߎ^]%W<}/09<|<>|17~t(xoGއ煰y8 %ߖ^6C#3Y﷣3sh.sżd}ވS}r't牠 '݅|&GzD ϓpS}UhFS|^;N>/=@=^I}|M(_9+ONPQ}_q=T?+ꖩ_ȇ~&l>(^qGq#'c}!x^\זdX/?QD-8=SD`-,~WT$M)ha ':OF)ōsԩr[;V:v- ^"'}a (g,ψ<]Ѿ!CAIĭmaA~7hy|7as/9Nb_x6k<~8W,z1V~~\/է]p υv3x޷שR2E} :|~ĻQ!}}\P޳~M'E>~c6oDN eC}tYH̯5bs cwQe4sݸAAm:ykۣ󅸽y\}{Q׼C_z>EIa`%+]+bND/+o}d8/g<ljsZx3᫬R>1w;es|Y,b%y+~u6~ܟЗ_O򾊈O/b|x.G~s<0r!d)Wy~*tG+ b q+Qof~+[+{fGszsuB y8QgyK5x^ gOavz!МV8NSHC5bdv=V7ͬ"ߒ_Ţh/k9NPp+ϗ27bĕ~l.K)‚oC7^ XJߞ+bgsoxqu$r;\7@gzf(ˬO/=+/={^r)}n.4צ9\fs?_ߗYbp/kb~0֯b_mUYO=rOb4}„^rQcya7F7?rmV^|ys+j=`<3=bg[a6Y_Gԡmj+? \ir{No1WD}C19&EE};3}@sʄ?~Y\XO~z$qp΀X :U[Vg/s!ݢgiT9Xl>:Wz-s C :(ωχ\a ToW1>Qa|n_ }q.!c'yҾQ7PݏNZϿ'/! PNϼ2 x63*+`Ż+PS9hW๲x6>r@9s"G~Orx{"o.>KDyp^r厥պ*m;?}+~B}ũ[*#_# 0}WѿFӣ|FOS\77)?Iߋu`Y E ~ytR ')SvLoZUg~w#:sL8^Yny/"/'ω~x[xO.~9uxͺES]> VcSEo2??Xe33-m{Yt ;?c_4Oa ?*Hx>~C!|:)|n[Tط1h} Ï}9c^#yJ]N:o^q '8i_Q%Էh HI~yB8? UKHB&yytYnoo~prЀ4/ ZեKUzْF[q߬xJi#څԇ=Bo>F?k룞B|@"#?G}GMrN_o=::&:_ w|0iY~ԣ*WKC8POꁑ?^zcVBY[Oؿ^3gP' %c?Kgpюyly0Oz͕!2zBo: O- h WB %^G P)K!"}V7ΕBi>sx=x#">۲xk{Xϋ^2cqECVIͼ//G\u ]?Hhw~>r{tGWGBD}YQo>~@\CT~4Bv%˅ϋ|"֯lX~<)$ӜD6 {E:a})%"$ ~$}x8'V|MW9d"B<2>?/i7zAċDcM,G.B^uR_tq(oI쟗PӳyZ|y ~x|O~F[ O[޿}.}#>BL<'9@;%u>ࢮ }DP/c &[(V'LHz ؍\r*ۺjK?n,R@PB1B? ;wZ)>MD]ގ~Wċl. )^+/V;jW _Q-b_oR[$3Vϼo(Sv [Dbx.‹x@by掊>h?\uϊs :G\'fGׇ8q"ˠs"8͇#AuY¿Ac^=OJ#igByyC i7#~>>Pz? +#[?A3K~_OC8 @~,"Ew)Ca,b?Ϫ3[D: GvKq+%Bn(Bd[qaףF̹}n<@L>xإf"N/~,}Eq?>7۩Wίs]'Sql.z׉z*g#*6'搉}`[,p eFzc<Jegޘii'ɟ/,~N${3F0'C@zL|͇'heIQ] N.@BOԑܤJ8`4P+ٜ0??G}X?*W(Ay.gq?>C#[6'dž*j}.<#jAyd|ٜ zX\σqIY|.;]%Kھ~CW8G?Pbyύ  yN+a3[8o38b>1=dSr?-G8iTZ>6k좨`l8WE_͊<s658TMcFE\H~;a/a\7" N4N%(p5>c\͙cu$$?Q/2=CW̗VWˮOv=֗z:CY}Xiw>'㹱z*eLƸ 9p]RT}QO.;lN& /~&u~|o /S?}AN`C}Yǒ}?ZAϏ߄חyּh>璮՛\rgho<g}Y|y[u?Iv3y}; :t[ W(?$D>5kIy/>+\ O\a' ~"ͼ߀bn7sS!YݪʱĖ77[_۬~Յ*(!ͬ>E ρ9&}oY: >HE"_I ;zX/e7^׈=qm>WGWq gQ9\CG6="VGx? Cf*t=/sB\(_?ǝ!OGy"V뉈Q䝐%3qg.SҜT>_K弟 GrþֳN=#ʐBMi/J=3~ԇ 7?G,oHeqKvw,_֍ q$^<|hڞoF/ *'˽x)cm|o&} #O(p:0@hdz;:?VF~a+ET< %Q¸VG%\|KyP;#yX]&Ui1\$?OilW8kQH_, σE(_? ]x6ƚBJ9!>s ?Y .uF;U6VGo(sQPfrzl˭d3sc7u|=ow SL7?_ ;Z< Bt>}0ҷE>&9[+<VN>OCB| |>Yvw">8,Wٸ7 ls,ˣSz#>[Hs80?T#f}l[X~>ö$ b>0W 1qXݾMyf?Obxˏ 1]iN,_\1 Y*;~+ !PD> ; [SO)?އ0Fb]ʦI OG:%+e:gZe{W@YtoךGBm8˛ͫPu,>D]tsɻRb1{<+" y? e7HqT҃?|gf/R=uDwmob$%,_∸Ǩ0h| | 7ߌ͹S!~m!뇁~7K*x:V7@z\!`>b'ƉK |q0Qz)"x~͉88 w$(^*CyרG uK:0ǾU߽W qCǸKu/$: S~]يsbLx-VzمЏPȞyOXԽTz#q}b~ k;3 !{ݢL&OymX߁c!pMnAؼ$D&'~o1_fgs\Lq OE9 v6a=$X7}2A|+y8\oy}6o]loԖE~CqmTsM<_`'QWUEQݞWDE]Q9z$Qj&}@(orv jnE}Q]yzX+^_"T>"}\j}o=3v7_kAtf!ھ$OQ8f樤Sބ =hsx}߼T5zE/@u.=| A`\aQ)# .)Vk;%RUjy9"✅r`fW7池%=L#A}vJG00ׂ)z#x}\/ w{vrD/~cA'G" B^)>¼ߴB_yx;lss(#hGR5C~G#+Ue2iWH,>@zS/1ϔžt=y_^Opb?A<'rgp?#OL>}:4+=y}}1[ `7Bh先W*BkY6ټ}8,){B'#3 NA~(B}\FP^?[?7 &?6Wؼ?E\k#?Ub]S+\3)4ʭ"$/ ԸO?ģ$:~qa^}Db;l%33t޷ OW,{*n)4}I._v;{OQ_,ETXE}VE_<"OLc&KGRȿaԯաKM9_=&!Nu`b4K'L>|YˮaS#Qطz6qENC^cR-օ`8Fz3R|N3K5Q~}q߭sNNO}0v-}E OLz \n# =9,_'}(̩>?%KJ;]gIJ9iM=!|%}6Kq_t&uO=x~Yu╂?N_>Dp#VU:ׯʢiȏ$S(Eu"BܱiLG m]뫜W&Z_~}uXBn#u.[po`I|Bz'__MgW)?A+A* sy[N|Cx.l+[1{S܏}8l=4xg G ~"C"y*ϧD<On|~=tRWlQt7*gÞGӾ!C}@2 ?" w;]L'y!dza| ҽS߸_N1G>P/S]z?[|x" .e$KW> st?<&ψ/ȿ+s?WyT(Kyz0Ts/𝾞杻+Y2uM[&qs6ۅ~}O|>P'8mlr|kCk=(QٔʡCDy[cY@yYr+y|69H~:x,͸_G|>=z_gz={?u,] x6ڍy>=֙xd'|ͳsR%ޤϕC mNqHsSۣ<GoPtr+O0mQo§qЁ6*+ Eݎq>'ϗB) <_aS_Gγݮs/1ʲgT/Q3Ѯ~wm h`^Q+Y q" b=:d*ց~B^F5VQ?qJEOJsrX-)QۮS'\8S,S}y,XޚGho>9|K1wϳg"o/qv\&>dsEs#YR/Yɋ:ܜǧ^naBz\䑻wq|3VOD"~y|n7H8Q};ǾzWŇosf}1ޢC<РWyyU &GJ$GKYv* 5Gx_cz#CTy}Yu~ _vT*΃;zQ>50ߍ@>4)&(o'wJs\nzgŒ?WG~Bnr|瘿xRWּHl[yWԵ)>Kk_Kbgkh('ҹgOG#-@y?%Ϭߑ^F"PV6b ||IP?w)+fdwQ 9Gry^87E'9; `v/͹H^0<_|-HxH>~'*Y^6 +ﳗ=ϑfo)Q-Ni.EX7Ozîu z?7ևIqwcB.xn,E G)Q͙|(ѷ껂qNA3q;K9Dq~q)P΋2J1KV_7}ѡ>+#;枈x-ƩtU&'=cߢB>/@ץ'_K>K>*{Wku|;x~+c~5gsq.%a8#7sX~vdV;5';a}0@|_w*(? >?s)ԏ8|1'@} :7u]x_~g$:{t?W |efihY8A7q\?KCE-8 E I fB]9 E-h>3CyX}~/!ꟕo$Q|Cá_D>x_/D)݂땿\썌*ϘYꟑk꺆w?]OOiwOOO5ggO/?AOS5zOt>wu;tw-xOCaup\p?kOyF^'^pͿ{'zs'gz05Ӻ߽%sagu7ڟ?Ox柞gd3<5u5vwg;F:7|oɚֿۓ9ή~ O>wYy w{+5]_m辆茿kj݆oʾ'뿣!~_]Ooh-G/矬7պ3Lko_1ȯ'oό~wϿį\~w_]W7t_u_Cݺ~kp̯w{zwt'սd/ у!2t?5Y)~/w;z׹O_^7t_}b3;[w'kӿ ݋̯>g2t}Oi/C4tF=wk=,J9.2t￾g>wճ:? >y;d!2C ϟߝ!-O^߿Owk3w3ěov<9C5̟/ ]_]3~zW#QZ!g{>6 Wρ7GZ߭Oiw3?; f>'z̟_hOrz~~u?_d&w~*96;wٟ_W8oN_VCW0~u}Cw5~ޯ~jM?7w2O5\cٿ{ƿ˿[ӯ{hR< w$ $-RI*B`J$BIT4*2T4JH) MֳJ=]Yy9ޟ ^{J/nV;~īoW8?:W^c: ~kLg>q=]wog|_:UVm㽒 -ȹӗߜ7g$x^29׮zGAwdt,]~НJ"Go'EP[ξVuևT~Ov/v%S/ғ5x >ٝ\AcrOx ;n/x^zCwJO7'=]>?s;?.垮E'vX,H O~+0?<)t꣫5W!77pǟ.^ƹוO'{R 1:?ݚy$UGy{}V^['y߸7-nߛSwHg}:#uvWzC?r~Un"\]=w'έtƫ~lo=︮tU[o왟vK~gx<n^AKwc^8~tҕ ׮d 2g8ؕu%L^.~pO<9s+!S~p;Wق` ~[2u'``gX8AJgU൞dWݍw@g]_gq''ߑˏ]bgr{cݳZmWwW9yS9=)kJW2*?c& +~YO~],/;t~Ko0)w&W~ݽ;]w8^s  uwև߳tWw6gW6Q ??zt^mռJg#hׯxOAw]cÏd j8uoǾ?=_u6r:}=/qmOw6" Z:?w[]5믤ۓ9;ήϼ=ձcM~吺q 34]=~u::`\gc;{/H9ŏWu6Aΰҕ ;cvu^}ۛ ʏ/v\GOluw΍|tܱ׼ b'Z;=Ӟ؊WzRzS&㺲Y~ʯߕ ~d{\W~֓w9v6}]ߓ]=~;u:yk}]t#yg|=]=ۿʟBA +{t|w~tlgۥ;rk|OPWۛ:J^wsƂJgΏuۥ7':+܂A墳^:7GW'k¯ tcæf,rig~^ܯqMҙʽ[y@oh>:v[GO8jw3 h/A76 \o"G57~aIg}9O&A𫧘o Ŷb5vF.!\=YgW1_w` x.!ȞOݸпKo؎g'F5:z"\q39D{SzR?j(=YcOMݏKڞ޴9Atߝ7;zsLgcK>YWOM.dɜ8_'?Sݱ譿ұ`ǘͿѼ?mƷeW)Kg]8[+y+D^$~{r^=Go~.̿Uz{~Y8.Ȼpm7pqU:㜼 'nGWvZ ά;k]>3_g՘r{3^vߕ.ߓx˫ g|ǞE ~.kVB8O?Ow ]ow(n?B*~uyJkW0THl:zZpn>ih>>7+nn6w}@|j.#7:gal{qVo.ABϛ} #EqѕX<055(/u >ؖQnye>(߮l8Pm6;4h-/HKv=[%]=o9 ؾkks|Xn52s,>X|HHL2:%z"uy7{Ka``;5O;l5ZW(mM~VwfKR7~ Fc;CEcg|ؗ$]MGEU᭄[-gzvȢX{j2{)) q?G簖zhRV'l|UV>x9/LzXc&c\?gX"|yJ+GYB0;~+za<{D)UEprĪ4%rKVg՘:YIGf}J#8^)7tsR7)`ؾ |8%ؾO]+R?{I__OƸQ+bF/\ҧc Mn͆>)ۉkԻCXhz׾q܀?}Yi-zA?qbl8 M{ؙ03UjvpF?};\?143K\W?Rr#'v'Scձ]Goh"vwg}-;vA8|N_ᎵKzd!ܦt߷ J@ڕ_b ;^oT&ؿ"r)沁k ѿr[lp_ L9oDvW؞|*ynq{ύǒ_)[mu Bya눿NV A=s>4G}9}euH 1ݿYFq'xPeI5~41?b'gsޯٰ$;]s3}ڣ^"=o܂=oo<5,zP}k-xV#*;2 ]6<|I9;cv[E`=l.9sq}d??܆K$]Al#F2%o_3<*=ɹ̹5(RJ폒%i^GGM};}"^+aw+3Yoa`|7jVh3cB}i^jRcS=nǿߌHJjSY>1ZO,0q]>yM*64ؐ$ +)G9]k9 X+6~.'}7ɺXu,-J%ș?U> qx[ad}oLWbRnŖ824x:Smïa!ӹ^YɍOk$]2Of]ϵ_@xGsCݢ_ p\99z#< 7?4] |WѫD-3hlih8c2s ⇅#ww<Ǣn0 ElJxINz 93Gs dY!0 CB~Ro?Sjƺ(q;6d|> vYu>Hn3ϜB_leS#o9^y/)i[įy 4_C>i1ϋ;iU$.i~mf/㴜ٮGXWHYPMD_^f:x@1 We C9&BA$^*MG9lN3 NᄏqX&:hE/W&)fXN 1p-X͍0"quvbgA˄b&e(ߪsQ\#r-ߛ9^g,ǻP2;>OӹJfQKv_*MAωu~JqW G%Z+[)^22 *9.N|Fp4b4V9Wղd?ުr! [e8/[Lm;Rа~VIpuGX y92$gNx KQo7g`dxǂħ;0qnzύU5`| )Ge[Uu\4Jq~NZqbD>}Y8iT~l܂xǕxkK0sVyc`ϲn߼2-#b-?V#;1NA/4i铄7S'=&>}ڈ17텁XSԟ;E; [k 'wr>.6wH.c;=޹߇6H|x3Y_B[&O<9"ݜ}xVR6\3Ҟw y+{ (a+(ڍ/x C;N!QqDnduPu^5R}oF^7T$>AGGxD^i5X'atgiWI^^ O߅5c7U"rC~X)'l='nt?Uqa>pƔE}S/Iܬ elL OfDz0eOKnCod gxֺZMZψ4=KUa?L-:5޽Z ތw &c8w2g+>wk92 /? &V38`oGE|A`a>=إM<B# = CSFIR%S[5Ӌˍ'_u Kn;'9u_b22'8apsZpw}]7+I4'H)ɓ>H3yr.Uʨ?CѨ$~|DkF Y֭V|=p;|7b?zF s뭈]\\\Kx |9WoȽ~!$ٽ=DǴZő8p`OZ 'gϢ Dxj|sL`6!GȏnvD_%?CS5g3J)`g?Ww`'Ve[4|/_/neXGyF?n/|͜1mFJدݧ_!y>$Oi!ߊ*~B%~L3(ߍOjMK8Dq g#mGzPIStݑӾ\87_ )Gk+ sjb_YG*LsR{ P]"lgeDv\O.yO$NȹG\q)ӭ&>!I(RV߸CE!6Gm@~T'AxUnq}-\r ه;s?99_z$Xćif}=x3ݕqK؄\fߜ1;q_m /z&Zةn|V ힻgvqO(,A[#sY3?H1٨cw}EQUaYoIA'.{mlN/䞍r*V m?ݘhri뚤ޝ %vsm{Y~c,./ |P\n‡㞽|;_5ٝ>yr%\^r`xfm,0rr}Wt_$rgh&c\n Iqe`\)Q̡qri!o7X? =oOzuDNyX],Q/ X{w.[H~eN9ףrt6Fs.DT uf ɯLg9eNxL+B$Xo'lCoȼSGz8<ۧjZbKLOc1edU-͞`'' Aؾޗ93${\-K٫[%_:Ϟ) Un5m*J d;#vgٓZ/#nduѳJ%㬘^n"x<ɝ>HQ=_ )H$_Έ[dL#W`-iߘu4z7 a+Iuy N0di3QcMv~b:Y]&D/l鑄OG$A_sɻ=IQ}J(H|7Y, ?8N{VG?>ٺOI\'$|S('dt$^\D8Cz5mq77YRF~^uqΧIؒKZ>6}|`G>>nQɟXJKjJ {Ǘ" 3@X8*gFSEyf?aC]r_wbN-跬{ל@?\A;}~ZT;W@5z?9e$ՊqMYXH~ѶTT:/eVI._rs.^|A?SMQmgfgE lvWN0Cb#Gn8 y;{ XZo/ Ӫ9c8BW\x~: v=;c$OOJ뱢I'v ÜN/B|f9yq,œ~R+% ]}Eš$rܿ0ϞB䅵rm = # yUDpS,l_d.q[,1OIEp%^w 2=KqԘgc9|FILJ!;rD2Ewo~8'{c1nVv"yiDyrAY^i}~Ls>#yA$_dmlm}G+=k$_hh9S1fEU|0zRD_rt˞gtDaMd⡯ĞnI!#?{9>&\1 Κx}ϗ@ IƱ;Avflm0Ug~7svB5n $Vu/H/6x6`ďڱ,f䶀+߬y(iUZ5uAeo^@(5s<ɚ@17:y #6ɏTQPqx`|" F j>#i@*|3[uz)0L; t>飁{FQYy %)^߫tc-'~C#]777 5,=Y^v`}Bݻ@nZ D@z7P S:L5%! S/'[u`z^5hٹ_3Ձ6;) sw;-O끹fS@ @-^Fǁ"@9t48ϋY;m#@c/{ 4-Jg-`Ρ,:vAM-?nE}9Z7*(%Jbi: )«BsͲvS&C^v0F\S1 zo+ǀQYii#@Y{z' tqکfVQL Ŏ;C?iլU@oٖ>$3FʕgOPUGZwSF/?Y!>pJ.Y?2-1ZլX=PYcZ;9&T-j˻@w:nksÚ915S60&6BݖѻQn%fo 9Ͼ[ _ "A6mOiУũ]KgJxgAW;+4ũ_@a t@bC@0K.(Bi+fƊ@U20X\qFu{x=0rV7fJ 8_c@Y9sTp`RDT@Sg/Lecć2(jo/]^&#l.BĢ!Wy&죋!(<~إOPzzs|o@l)ȏ~8we0޸y?m{KPhz E#D!| cC`Y4Џ+FzC[C5Ҝxl%`.Dґ nJUCn/Jpa홇 x/VEG=:Yu@e(=~賃T3O&]fRX7R+,2 Gg|?LK?}_@7PbJ=5 9}Cuow}p<і[YhKsWxnE "Aa_{`ߣEt;悈{kf3xsW0^я: & dꔣU'u_@(Y)?6e׊U"s|&Kڪup]WBK5)Z0Enq60t?X#d$P&t"=X:(TS{=l7Kyqg'ӿVDa)8BR` `_>gf`RCLX>-cOޏK〼Qȫ#)W ˀ6In `H{iE_*hƷfu77R юZMt)}7!I|uֈ2οԿ).k>jDj)\7= ;оR U3q~%`l|2ȴ?P}̽1d7,k6fS/-~kO؜+B`268?m"wk$:nOu= [!άIܙ &?h/7Ap-=.P/ hF[>*twG<ރ:ƣ0f2Ӹw1׌˺P0F%z">)}_n#|$8T{S@xш9@)ѓz~ÆMIKnn&`8r1øawH4j{v9sQ(`))y c{(@| G Z@0!xƏߖ`PMt^kA~<3͛c*ʬzt9p=sMukwvh:JAV2^}`4k<({MoӁzÒ)> )O8j420y+4pPKw)v1}@1չf@RUkzXPPo+ \g}`D -t mĸm/y,䛮Æ5z)ڟFa',lBW]-۞@? Zyŗ>zJw90ߪ0=w(ҸR@Nh9Ik(f_ňs%ra{'FjƁ7_EHj ϼg&|qK_ {`[ȕ!'ޞ}{?u+ Wr'yj$ag+I= vboƪ~yWKU fGnꃏY s[>/@STT@? ⚽0;_7Ny c2Jw% te.iǘ!x=j% Kv_}Qi<5 6sEX@QsXBeWg5uPդZ؁ "~K'D8X|ۀ7k0MU?ԴTxnu8ODIϪ`|(7nIחY N0WCYF3KA3mN_`<{+o)G>mn>ЦA޷h;PX K#^$sɣ劘~}x40 m_)yjy-6;3;WL`|fA0aΐy =lM(^5>zu'"^7s\ }uw9YŷΦԖo FշƑY^1eY 6uJdBȋM~iYm;`alA_G]@+! qDO;`m} mC eWKfZæI<o mw(Ͻѯc˴9BWV15?9bS7&FH\[{ZB}|e@sL^lY~xU? ;FvZAxȼlijԆ5xN!ہAہ2T̯ǾuŜq۱@e+iIF.\OC^놅@$P8>UL?`-S5π:y9 e2Ю0q4Af@{|o!/|n_Gog +sQPUYEP_9?XhU^4c<U>Iȭ\0r"℡]@X aܪ:jx)n^0#(WG[SeʻA@a{DcF*]k׸.gOA3l+po޺~! k- ɂ-Bmi=KVa9`R.ׁ15T~-N-ҷ(q|lڛד= @ [=6{xDp˙]2rn4̧M#>w]qXLؗLZU0&$\[vIയX=0J`' ~K^juMfL{c0Gw-[ž WyPj|(zK17?"T (O<*'籂ph=V5VY>N[~,/h w,Q`x`|]} JTZN=;VG<@^c_X20C#b<v7suZPX5i%q#31VU*e 5oqǥԀ)Eq$_~mf) Gi&J@wHbrPP;‘6 wnM ?f8 y5-@?٪gY@.sX?UQI ɩ]Jy~cadLR W`L]24򜝢rnUځhԫ~7΢n7^S/忐?9\$qG&sz$=@̥`S7"e;IAkyYXPħjx.ƉLԟebV&NE?z`2dT-cJ1+Ӛ*jr'wa:GwƯK }zq\{PV_N" ODJ!r!‚MXw1J^:eM.Wc~=Yt0ds"_.Z+}A Pޮi̜g@]~al) -; вl<9WSK}ޏ&\4gI«(eΠOvMȁK18$ (6ԫc>:xk$и%2د)=y{dŭ+(?-#_;#u yIMF2>%_M8wVysȋbt3G/kwU}+A\Lc K@/KL>9W6ԕ|lx>Nh g~^n\Mž<,D0z]['-(hN74 ='NOv Um=}rZ)n>{mrSzAKq|i@5m A;ۮLR-v@WdM| u=*'-*([ǚ ң{Ўe  NX9k˚u8w!GJ:~*0쮄;h:0hfNӷ>Q@/IFES}?Hp}Ƒ?.+uM,Lk)! zjI䫗@]hm5@*~zSc E?B}̅30i>U tͺUomїeo0~y5JG(9w /u~0 n1ղ'!>'wu}$  o9Gpmޅ|8@{_YjplJu:0ys@[G|㐟0lbl Ufg++W].(5_e7^ P^r{-0m̖Z}u]ڈk0r= ?>?{g`* f"/| 0%c?/eN6N[/YLiN>ԯWq@VזϷj%߀~9#@!@hM 39$iX /wG 0(cM46c~0&Tair@K0Wc!wXŖwe+/< z:[HC#]k*< 7Azг"aPySکEw_fҳwqFMNApZVׅ\zb0r5` E V|yGSiYHy/13|8q[o0څoͧqКw>66E{|čBǁ1 xB  ;M1_ RNI 6 EAA@PR&9}.FGRZ0!7bimĩKr׍/m@j/]@~vR:ؐ +H#fvfB4.p-0/pU¼lçi#o'R9 #>LpyMͼ2WXx*rC鿅b>0yO4y׽bۖWL:%__Ps^GW,aV9[kџw̞}kU)?'9>|ll̓B|LZb/`"jloo/tests/testthat/data-for-tests/function_method_stuff.R0000644000176200001440000000057414411130104023414 0ustar liggesusersN <- 50; K <- 10; S <- 100; a0 <- 3; b0 <- 2 p <- rbeta(1, a0, b0) y <- rbinom(N, size = K, prob = p) a <- a0 + sum(y); b <- b0 + N * K - sum(y) draws <- as.matrix(rbeta(S, a, b)) data <- data.frame(y,K) llfun <- function(data_i, draws) { dbinom(data_i$y, size = data_i$K, prob = draws, log = TRUE) } llmat_from_fn <- sapply(1:N, function(i) llfun(data[i,, drop=FALSE], draws)) loo/tests/testthat/data-for-tests/normal_reg_waic_test_example.rda0000644000176200001440000005046314411130104025271 0ustar liggesusersy8]6|]JJdd,\5JI"e&D(2%DJTRRh"!C"|Mfۿ8>^k@{M8 @)N@%9CTЀ?‹1Ӽ%t'1UX> -Ⱦ qC{^fauOV_A}{|[  j]담'1@z7 4܇qˎx-q]("% c?b7$Qߖn37}@uV?{Uw[^:dL) 2Εez2Vghc95K}qZےq0V%?V݌/f`ѯEHP!1T~, (φ?%@I@P&WXP/JhmO>κC*@߶vyPUQ>;k^.|T7$^sT)d nȗ{v@ e||POfIYtnʫi;{$=c +xc ZgYC1`zݤ *+[o3Dh; \?(]Á-rZ: ;^*4WOÞc06DG+¶8O\X&v~R DsPWmUj/0ej S?Fנ5@ ^!ϻin TY!`o5 c@ywUG\lz OO]J"FZbp/du;t_'lU.u/Ρ-Z_&zb6 8\]RVhJk] ͹p&F)r{3ȜCC['z_v jXWz6fӂy/T, K X(.`4@PH+nchW0Iw^КD;]ZXd(bL`nݣہsg )gJ.ul~<ckWmq;0bIm@K/ iՀy/ʭ W=j>֓@>\#6_Vjr/q&qnu̟&=kxߚ6t6U:O] `|c؆;i1@9V](OIb~vH*E赼0"Cۡ(5oGz=>NƹljvxeҌ*¦&Pf>"N0e|0&-LƱա6@IQ1yr*8\O %ț͹?V~q7= ^?m+Ǘ1>P<&6nuz EO9|@>_c `4$:2ݘ ]珊>-㍅x,;Ĉ}2Kncc9`W:k`e)V;U" Oo7g`}twcEZm@;q5?;r4D'MzŊtJscd9?g`Z'|6Ǚ$p`bK-9|u{g0$S78>PӤUo;SZa삍ȫ[F3op6zKeխzəM@}w^4C ?JAK@-}e? B"\=-ܖRnGv8j3k"MR0Se wyM@ z ն.۲ PSWa=Aj7c>= ƿ:3WF1Uܯr.6R*>S{>? ^($)0|_mŸEE;`\%@;ڧu{v%뭴菔gUq>1X&KUF6X> +_b1 7 a6~ͨ!0Q-0ΖJCXo<6ToYIa>׉~Ϗ`]^5&::# ]. 2|J ºormU"Pۀ:5QA? K SIx퀺 o, 6cg 臟8zT:R8fP]%j~!tq7PõfNx8u w[=` 9 \AXdmJS̯^Hz"QVPg#op|VIc];`(BvN$-x>[I*A|L=;̭p۳NH& 0.\Q:alcgDRg{`4~Eϩ{a6~u1juF"?zaq5M|k_P&fk7'.n߸'<לٕi(5pHb'IIgtpN).N P~y·U@W]O* hJ JX mϟ8EIeX < m} \5(56w0U'Tc:nT]n@Vp!0ɳ|埥/:,'qֈ,,NOec;>ܥqKKf@D0im`=Go^#qœ*/!out c1)`eՉ߰'S g=GcILe}WK!@_s}'v`>Kc?5aUVUqN-by-# ^kg)MgiQϿ"+FTq4Ş92e0/}3X:̏T]gԳX$s/;WIbpwrctd6CBr0Vehh/?8\g/H'ha\t^빬bo..9xoR@i}e1 qPj7]R0]'k/a}:)WuJ֯2zGYކ8>]g&N:x'$/\xwD7Uo-NOytx̓;39*; Mٸn(V=ۚIqX" ұ& `.tƺ3ض>: .0rЯd T Ῡ'$>F:HPu]ztO<06S8ESS)0m TsR-yh~Oyn7^3 ѧ0y~6. gצb4^)뮿3_0_?y|@;֬>_M D#ϱ?,6%} 4C<&w sm3Mqths/6a<;kNveFuKۇTowƖ*y<4F_ԟ<hz@z;~`M;Po^~q^eiȨ:op6FotqwWW=C'^mFx77 wϔ*S!o=;1>|ITxb ҝX83*`vtx`I[cq6 yg͊$`j7f;ֈs`5r`2G!cEiHp;a=Gk/ D.DZee{x`>`J\C9s;My}lQkH_~W^}U z~~9-k;8i< sʥ8{E'"s* #HO %k&k[pE`D2Ihኧ}LDR/ fDg:lI_Y#rf<c=o79/w=+o.}';"W nݨ.nZ鼅LuG̽ezm*DvfKeS`*3:VyID>ע*:(2^q8)g--74t2v~#F`{4q\ 8-~&c"rӘeN?0{-oՒ =1p&k$j`vJ6`o&9Dn>n/ 4yɯwzw%HO:"]sX5|% ieNc 3gھX% ?t/oB`8׸j "?7k& ,9SB$Ֆm![O<VQR"_WՖ,^{xV~'"-)yяE7=c#g:c\X5hֶ:l+Yn90Xt:7O|y'3,<IP9s2Lmv܆d)'(nثkL!`?1tطu~(pͅm%0@Haiybr6o_[ ωl]Emm}dT%u7J jW ŒLc>VY"&t<Cǿ+!>p=j 4@ $Q*HnvJDoJWεf0 } "tVD<Ǧ R\l^&3$I൙,p,n] ,[gR]J0gE6>oVF'(RLޣ-ww-`mhx? =u[ lzL"x:VV\'g}zѻӐ- l35rW*[[8~|{T %zLm]ETf yY-Տܲn.=DZA+{U8j;i0W<"ť'*̬MN՟T^ &|) I6kuzZb/8h|~R x州N_w"7xx8D^aۋyp@Δ_iez>?x|1X@c'5𻼳R!9Je^K`h H{?ܸ˞"rJ?BJ,)D;#gpR;quuc"!R\Y\W4n: LF9߀I;YP?H);7)|N;ql]r6oG60@c3J0.TQB%'TΑXU  !KXMoE*0Ͽ3;{nC ;uml0xc{u34/HGV×)VXm6Gd9[0Q_xTg b]R}' `[ QՈOxiii`oy *`.m0r3"/_[T 8|=Uf6gDu,VT&mɈ{D1շXVjTG6|;:D;Wl5Q{١{k"TQC/b0ޙZYLH憴b=86橨|`Έ$& \;n^= ԛ{M׆{{W0!˱F-~CEF1ߢ޴ ^^{yXA{056]Ql6/xdGmz?j)} D<ˆ9D:u_mMb^}_@'4ҥ تf=HK3tMK8v|80L[m"%: } W[]1M ȊŠۛw۫ہӣPٕ?N"U6>#8n%V8HW2\p}TeqĐ"ɖ:Bd&oIb/Ð?5a'pr#?큏 "թZJ\0dfZzq[׫rC_`.})DmXoԚ3xq~*an't,P\̗ٮD"=0q{: j|5LW 5u`~_X*p҇#]O]܇ۛm)Hukk)yWpz:0 mn^yZl("g^ 5jM: W_C= N.Gd ."RlNO`tm-z8xSAb/l8\Ku`@8sT/`_\|ģK5Q@m ޸ t:{Y#0}{M^~]~=O`alLNo~љeYHZ v a]`Pgzn;D6έ[p\tNPh"'qT])%z hzDl7#cUҘ_J!y"M,+HLq pٗ wEքG +.- 鼎AWq=7Wϝ9O:#|\(` Wc]aE"$i^^-QێNO1&b; )z8'ֲO]Ǽ?)9 j:@$=CB`nWT3 U_PZVDe0΅Y"骷#BQzwsgg<{`/v8~5]?*c~ct-"G #1G*[{p"l;hU< D,=2NdgP]sH>f:ͷYɊ"x3DdF5v+=nãE=, {%ڧOtg+;b.z޶0ult'i+!?5I42NEUq.X6`S 󥋼傢9c iote^M zÁoQ2XNç.˝4 8i/ p15 I}e/8.5 -bi1C=Q2`eu%` FvèIYRKq]Qw{jv<#ost8{.}MX^݅HCp-yp1'5kp]*+|3+ى.Y 0Y[5; l/dv?r׫c67G:pN9f[ zAjBHU]dC la#۔vIŘaBXL_P-C+EoԳ|;[kW+wotY;b_z)omU0h6g;ZLF%ӧ2n#RxkIǿkr8{:%u(_7;U1/as喝w0ȻK23YW֧a{a^` C%A_oZׯU!2l:5׫-/1![p݊:^mk ۠OKP "[#R}60=g1YT`~ Z,f\Yr 4#ŭx ⸜h頊VqQODQ]Qm o fE;nHWV3,Va >(6_?24C$ZrE!~3SUX]Xn͇wa~.3̯yXwI;p +,nţdXZ痀y\.[1W@}5r\WF|CT걂0\,^Ӿ[6z Xg/Y\/vW¼jojQ=W? a~a2" 3y`Etg5uZ K%kť>WK,7 X%jpƁv \U~xZ"xj0 dJHyJcd {rr/|97"p}i("W_A$~ Y8/E3x,qwni%X^>E{gz[$Z SxhğLH!Zka^z&G!{v;)OK`-4dyL%oP8H+r%滶.1Lx3~튺 Y^<@3j9s]{̆:lFRofc9qMxe'Vu 5O885ۗXIºθFxUm; kz]lM ģmZv]ZTL) r#X;[}9ѽTH0p*(G rCGI؟+eX<)quAᥲBwR8oySp.y--K. tW1\~;2$_֍rn?z>}XrM0_cP.Xa9Y,ٲGVXiva ~ybi:XϽPN͗*:k2 =x>XI<‹G_ U5Yx<;8mEV Vk=8#b&G$F"X=pWqD#sfL0ΑM9b{k iSŅGiuw` yBR8/9-"{6ܟ0B_?'KC@6~!qXid~`cA·v{ࠡ}kUxɡ1~;`]f-u^^؈q";w?"vr?/8]?s.? Bܿ  8G*#wAi#P*>o9޾ޞ^ =/se `L1 \ͯ Ea}@ێ,1Q;N*ya-2\9-{j xѢRg#VذXF- 6}0˒Q)⚩*WsHD)doc$RvhN\ ޺KFjb0rJ>L_ qV"!3cp_BZe3:jEIc3i6| V77i%a8݃+`-Q8okؘˏE|[xoEǭ^c+GN?KbhOGb/՗ѧ74>߄WFm1 zof/9\a$Èܱd~w\%L_R'zV-{\:KG=bU8O2؀ܴAǝkSߢuo E!T!dM %`21m\~|gMn].S@!$|K19RL}KP8.x`SUưY; !;cq$ށ~@6^vXN#gu롳Jc9$%5i+I?R~DEy J~]1xo;E XFD_E,|vtŸ ӥۿ!.|]_S<)?{b6UA|uOM#XޮJY_pw7@P/ FJ7.!!@S0l ά/m$޲"OL%靠f I摊H$lP(Sh:^EB{/ӫg_o̬9Wj~\ֺ,.={ᰨy6w@/;q+侳J3ukW܈xFx L;5~8%1a %%?>i2՟;py*q5pP0K_aǤN2bՐH)l<E"> LfM,@֥@bZ?{ 6F E-E1 NSZ*}P!PqB|Ç6 G2UH<1ڥ|HՋ ^}@ n,eA#4? 7;xHurꌔk ثr?ItZe}&%U=9,JiEķo=k  yVAdc3ķ6Y$>wM0]tm8~$"a DO2U9-Ȅ>>wL1ձOqP@Z]bϫbu; 8&;l j6HCA]As#\sGNYȨ]]U`ƧO#W8ukSne#wًu+ZJkiIyVb|`~U_?PUQ-@BJwלYC@>Կ2%8x7] _ôvy+"oWxxx?}yCCs |L?$.sͶىZѩYњ~"iX|x_?l_> ˯ r˞vG0;~hvS߹<$-(LڜF-C >Kgs{ˮ-E ,T[d #/3%ڻӈsۿA֞B[Wߓ#PPGbB;E!"A1m7YTI' .zJ_OUTZxƧ%ke0hcmI!?Nm~Mض59ф5yOXʲ=-ܯuh{E! 8(awZS뵍}YfD~G:#Ea\m(#u)-6,Wm(1jbZ/J;]L0[J:R!(.i&5>O2@/k2A.%SlN~,K*n[DNx24L2'~;Dt6lj# Lw_6x=9=9q ݾMM|Wݐߵ8wD$?e0aA|<ýoYZ64Ȅhܜq+k%m#L"/Vs͗x ĕENtQwEZ{.HsrhDYawXICM di= /u 7o wMߍ{$e19ʍw$5lq'c} Ƌ?b1Vߧ}x!߮$ADGR~"ak6 tAƇ_}bހӟQ!rX!ܝ?gE>68|nDwrenHP}gWOs&'y~/~]gW/[mNs㠞S}O@oQUy>3Kzo\B7Opi#,=S߸t~}W _Mm!=||ļ~Eh!)NcF/q]58Ou11qIR?s'csľmBoo٩ _n1K{%rR=ϖ VL#淖q՘&ͻM|#4 -_>r󠣵j#~vO;n:~WrmkVrq1_ǎFy:6~"7}SV]n|WE5۩%vs߭jaxl%>zu^$k=E ֩z+ō4XjyCw ) |ZWA2gx5a%&_Drg] ^8@S21չmh1{nc'_(iwvGV,}=oW,Z{y1-{cD{t:GM.{}g}[vS51ib[Bb?iWbHg7quDTnu& >M|ͳG2w)xlE)WHop_O.[SX/E-n]y^)sLJZ>]7|4}{nvtM[~+8="9a^W.>o+b|h$b+?HYŹ j$lǷ-ľ9K.i#;/#[(oi7}^ʽ nz[מy.q# yaDWdqX_m΍yE=Bta[C؞nZ/Tr%_nfQw=]g~3wUz#۹8{o#ׯڮ HqԴIؿ/tp%:èwk6#.qO= 7ĹJTy3y?ISO PKsKHiļ/u N!敝HAWwɛ%ܼ`,EoF{Gt1^7/F\^ƹ8EoֱcCbJ}rAi1Ci_ߋ$7rdS9qǸU-"7S7.;~z}5g8+Dc0FĹq\+S:].?7?~qD+^x?_t&~L/^ 1_ne4|9&e3r8qeloo/tests/testthat/test_psis.R0000644000176200001440000001114514216213107016204 0ustar liggesuserslibrary(loo) options(mc.cores=1) options(loo.cores=NULL) set.seed(123) context("psis") LLarr <- example_loglik_array() LLmat <- example_loglik_matrix() LLvec <- LLmat[, 1] chain_id <- rep(1:2, each = dim(LLarr)[1]) r_eff_arr <- relative_eff(exp(LLarr)) r_eff_vec <- relative_eff(exp(LLvec), chain_id = chain_id) psis1 <- psis(log_ratios = -LLarr, r_eff = r_eff_arr) test_that("psis results haven't changed", { expect_equal_to_reference(psis1, "reference-results/psis.rds") }) test_that("psis returns object with correct structure", { expect_true(is.psis(psis1)) expect_false(is.loo(psis1)) expect_false(is.psis_loo(psis1)) expect_named(psis1, c("log_weights", "diagnostics")) expect_named(psis1$diagnostics, c("pareto_k", "n_eff")) expect_equal(dim(psis1), dim(LLmat)) expect_length(psis1$diagnostics$pareto_k, dim(psis1)[2]) expect_length(psis1$diagnostics$n_eff, dim(psis1)[2]) }) test_that("psis methods give same results", { psis2 <- suppressWarnings(psis(-LLmat, r_eff = r_eff_arr)) expect_identical(psis1, psis2) psisvec <- suppressWarnings(psis(-LLvec, r_eff = r_eff_vec)) psismat <- suppressWarnings(psis(-LLmat[, 1], r_eff = r_eff_vec)) expect_identical(psisvec, psismat) }) test_that("psis throws correct errors and warnings", { # r_eff=NULL warnings expect_warning(psis(-LLarr), "Relative effective sample sizes") expect_warning(psis(-LLmat), "Relative effective sample sizes") expect_warning(psis(-LLmat[, 1]), "Relative effective sample sizes") # r_eff=NA disables warnings expect_silent(psis(-LLarr, r_eff = NA)) expect_silent(psis(-LLmat, r_eff = NA)) expect_silent(psis(-LLmat[,1], r_eff = NA)) # r_eff=NULL and r_eff=NA give same answer expect_equal( suppressWarnings(psis(-LLarr)), psis(-LLarr, r_eff = NA) ) # r_eff wrong length is error expect_error(psis(-LLarr, r_eff = r_eff_arr[-1]), "one value per observation") # r_eff has some NA values causes error r_eff_arr[2] <- NA expect_error(psis(-LLarr, r_eff = r_eff_arr), "mix NA and not NA values") # tail length warnings expect_warning( psis(-LLarr[1:5,, ]), "Not enough tail samples to fit the generalized Pareto distribution" ) # no NAs or non-finite values allowed LLmat[1,1] <- NA expect_error(psis(-LLmat), "NAs not allowed in input") LLmat[1,1] <- 1 LLmat[10, 2] <- Inf expect_error(psis(-LLmat), "All input values must be finite") # no lists allowed expect_error(expect_warning(psis(as.list(-LLvec))), "List not allowed as input") # if array, must be 3-D array dim(LLarr) <- c(2, 250, 2, 32) expect_error( psis(-LLarr), "length(dim(log_ratios)) == 3 is not TRUE", fixed = TRUE ) }) test_that("throw_tail_length_warnings gives correct output", { expect_silent(throw_tail_length_warnings(10)) expect_equal(throw_tail_length_warnings(10), 10) expect_warning(throw_tail_length_warnings(1), "Not enough tail samples") expect_warning(throw_tail_length_warnings(c(1, 10, 2)), "Skipping the following columns: 1, 3") expect_warning(throw_tail_length_warnings(rep(1, 21)), "11 more not printed") }) test_that("weights method returns correct output", { # default arguments expect_identical(weights(psis1), weights(psis1, normalize = TRUE, log = TRUE)) # unnormalized log-weights same as in psis object expect_equal(psis1$log_weights, weights(psis1, normalize = FALSE)) # normalized weights sum to 1 expect_equal( colSums(weights(psis1, normalize = TRUE, log = FALSE)), rep(1, ncol(psis1$log_weights)) ) }) test_that("psis_n_eff methods works properly", { w <- weights(psis1, normalize = TRUE, log = FALSE) expect_equal(psis_n_eff.default(w[, 1], r_eff = 1), 1 / sum(w[, 1]^2)) expect_equal(psis_n_eff.default(w[, 1], r_eff = 2), 2 / sum(w[, 1]^2)) expect_equal( psis_n_eff.default(w[, 1], r_eff = 2), psis_n_eff.matrix(w, r_eff = rep(2, ncol(w)))[1] ) expect_warning(psis_n_eff.default(w[, 1]), "not adjusted based on MCMC n_eff") expect_warning(psis_n_eff.matrix(w), "not adjusted based on MCMC n_eff") }) test_that("do_psis_i throws warning if all tail values the same", { xx <- c(1,2,3,4,4,4,4,4,4,4,4) val <- expect_warning(do_psis_i(xx, tail_len_i = 6), "all tail values are the same") expect_equal(val$pareto_k, Inf) }) test_that("psis_smooth_tail returns original tail values if k is infinite", { # skip on M1 Mac until we figure out why this test fails only on M1 Mac skip_if(Sys.info()[["sysname"]] == "Darwin" && R.version$arch == "aarch64") xx <- c(1,2,3,4,4,4,4,4,4,4,4) val <- suppressWarnings(psis_smooth_tail(xx, 3)) expect_equal(val$tail, xx) expect_equal(val$k, Inf) }) loo/tests/testthat/test_deprecated_extractors.R0000644000176200001440000001275713267637066021641 0ustar liggesuserslibrary(loo) options(mc.cores = 1) set.seed(123) context("Depracted extractors") LLarr <- example_loglik_array() r_eff_arr <- relative_eff(exp(LLarr)) loo1 <- suppressWarnings(loo(LLarr, r_eff = r_eff_arr)) waic1 <- suppressWarnings(waic(LLarr)) expect_warning_fixed <- function(object, regexp = NULL) { expect_warning(object, regexp = regexp, fixed = TRUE) } test_that("extracting estimates by name is deprecated for loo objects", { # $ method expect_equal( expect_warning_fixed(loo1$elpd_loo, "elpd_loo using '$' is deprecated"), loo1$estimates["elpd_loo", "Estimate"] ) expect_equal( expect_warning_fixed(loo1$se_elpd_loo, "se_elpd_loo using '$' is deprecated"), loo1$estimates["elpd_loo", "SE"] ) expect_equal( expect_warning_fixed(loo1$p_loo, "p_loo using '$' is deprecated"), loo1$estimates["p_loo", "Estimate"] ) expect_equal( expect_warning_fixed(loo1$se_p_loo, "se_p_loo using '$' is deprecated"), loo1$estimates["p_loo", "SE"] ) expect_equal( expect_warning_fixed(loo1$looic, "looic using '$' is deprecated"), loo1$estimates["looic", "Estimate"] ) expect_equal( expect_warning_fixed(loo1$se_looic, "se_looic using '$' is deprecated"), loo1$estimates["looic", "SE"] ) # [ method expect_equal( expect_warning_fixed(loo1["elpd_loo"], "elpd_loo using '[' is deprecated")[[1]], loo1$estimates["elpd_loo", "Estimate"] ) expect_equal( expect_warning_fixed(loo1["se_elpd_loo"], "se_elpd_loo using '[' is deprecated")[[1]], loo1$estimates["elpd_loo", "SE"] ) expect_equal( expect_warning_fixed(loo1["p_loo"], "p_loo using '[' is deprecated")[[1]], loo1$estimates["p_loo", "Estimate"] ) expect_equal( expect_warning_fixed(loo1["se_p_loo"], "se_p_loo using '[' is deprecated")[[1]], loo1$estimates["p_loo", "SE"] ) expect_equal( expect_warning_fixed(loo1["looic"], "looic using '[' is deprecated")[[1]], loo1$estimates["looic", "Estimate"] ) expect_equal( expect_warning_fixed(loo1["se_looic"], "se_looic using '[' is deprecated")[[1]], loo1$estimates["looic", "SE"] ) # [[ method expect_equal( expect_warning_fixed(loo1[["elpd_loo"]], "elpd_loo using '[[' is deprecated"), loo1$estimates["elpd_loo", "Estimate"] ) expect_equal( expect_warning_fixed(loo1[["se_elpd_loo"]], "se_elpd_loo using '[[' is deprecated"), loo1$estimates["elpd_loo", "SE"] ) expect_equal( expect_warning_fixed(loo1[["p_loo"]], "p_loo using '[[' is deprecated"), loo1$estimates["p_loo", "Estimate"] ) expect_equal( expect_warning_fixed(loo1[["se_p_loo"]], "se_p_loo using '[[' is deprecated"), loo1$estimates["p_loo", "SE"] ) expect_equal( expect_warning_fixed(loo1[["looic"]], "looic using '[[' is deprecated"), loo1$estimates["looic", "Estimate"] ) expect_equal( expect_warning_fixed(loo1[["se_looic"]], "se_looic using '[[' is deprecated"), loo1$estimates["looic", "SE"] ) }) test_that("extracting estimates by name is deprecated for waic objects", { expect_equal( expect_warning_fixed(waic1$elpd_waic, "elpd_waic using '$' is deprecated"), waic1$estimates["elpd_waic", "Estimate"] ) expect_equal( expect_warning_fixed(waic1$se_elpd_waic, "se_elpd_waic using '$' is deprecated"), waic1$estimates["elpd_waic", "SE"] ) expect_equal( expect_warning_fixed(waic1$p_waic, "p_waic using '$' is deprecated"), waic1$estimates["p_waic", "Estimate"] ) expect_equal( expect_warning_fixed(waic1$se_p_waic, "se_p_waic using '$' is deprecated"), waic1$estimates["p_waic", "SE"] ) expect_equal( expect_warning_fixed(waic1$waic, "waic using '$' is deprecated"), waic1$estimates["waic", "Estimate"] ) expect_equal( expect_warning_fixed(waic1$se_waic, "se_waic using '$' is deprecated"), waic1$estimates["waic", "SE"] ) expect_equal( expect_warning_fixed(waic1["elpd_waic"], "elpd_waic using '[' is deprecated")[[1]], waic1$estimates["elpd_waic", "Estimate"] ) expect_equal( expect_warning_fixed(waic1["se_elpd_waic"], "se_elpd_waic using '[' is deprecated")[[1]], waic1$estimates["elpd_waic", "SE"] ) expect_equal( expect_warning_fixed(waic1["p_waic"], "p_waic using '[' is deprecated")[[1]], waic1$estimates["p_waic", "Estimate"] ) expect_equal( expect_warning_fixed(waic1["se_p_waic"], "se_p_waic using '[' is deprecated")[[1]], waic1$estimates["p_waic", "SE"] ) expect_equal( expect_warning_fixed(waic1["waic"], "waic using '[' is deprecated")[[1]], waic1$estimates["waic", "Estimate"] ) expect_equal( expect_warning_fixed(waic1["se_waic"], "se_waic using '[' is deprecated")[[1]], waic1$estimates["waic", "SE"] ) expect_equal( expect_warning_fixed(waic1[["elpd_waic"]], "elpd_waic using '[[' is deprecated"), waic1$estimates["elpd_waic", "Estimate"] ) expect_equal( expect_warning_fixed(waic1[["se_elpd_waic"]], "se_elpd_waic using '[[' is deprecated"), waic1$estimates["elpd_waic", "SE"] ) expect_equal( expect_warning_fixed(waic1[["p_waic"]], "p_waic using '[[' is deprecated"), waic1$estimates["p_waic", "Estimate"] ) expect_equal( expect_warning_fixed(waic1[["se_p_waic"]], "se_p_waic using '[[' is deprecated"), waic1$estimates["p_waic", "SE"] ) expect_equal( expect_warning_fixed(waic1[["waic"]], "waic using '[[' is deprecated"), waic1$estimates["waic", "Estimate"] ) expect_equal( expect_warning_fixed(waic1[["se_waic"]], "se_waic using '[[' is deprecated"), waic1$estimates["waic", "SE"] ) }) loo/tests/testthat/test_extract_log_lik.R0000644000176200001440000000051614407123455020410 0ustar liggesuserslibrary(loo) context("extract_log_lik") test_that("extract_log_lik throws appropriate errors", { x1 <- rnorm(100) expect_error(extract_log_lik(x1), regexp = "Not a stanfit object") x2 <- structure(x1, class = "stanfit") expect_error(extract_log_lik(x2)) # not an S4 object OR no applicable method (depending on R version) }) loo/tests/testthat/test_0_helpers.R0000644000176200001440000000522213575772017017127 0ustar liggesuserslibrary(loo) context("helper functions and example data") LLarr <- example_loglik_array() LLmat <- example_loglik_matrix() test_that("example_loglik_array and example_loglik_matrix dimensions ok", { dim_arr <- dim(LLarr) dim_mat <- dim(LLmat) expect_equal(dim_mat[1], dim_arr[1] * dim_arr[2]) expect_equal(dim_mat[2], dim_arr[3]) }) test_that("example_loglik_array and example_loglik_matrix contain same values", { expect_equal(LLmat[1:500, ], LLarr[, 1, ]) expect_equal(LLmat[501:1000, ], LLarr[, 2, ]) }) test_that("reshaping functions result in correct dimensions", { LLmat2 <- llarray_to_matrix(LLarr) expect_identical(LLmat2, LLmat) LLarr2 <- llmatrix_to_array(LLmat2, chain_id = rep(1:2, each = 500)) expect_identical(LLarr2, LLarr) }) test_that("reshaping functions throw correct errors", { expect_error(llmatrix_to_array(LLmat, chain_id = rep(1:2, times = c(400, 600))), regexp = "Not all chains have same number of iterations", fixed = TRUE) expect_error(llmatrix_to_array(LLmat, chain_id = rep(1:2, each = 400)), regexp = "Number of rows in matrix not equal to length(chain_id)", fixed = TRUE) expect_error(llmatrix_to_array(LLmat, chain_id = rep(2:3, each = 500)), regexp = "max(chain_id) not equal to the number of chains", fixed = TRUE) expect_error(llmatrix_to_array(LLmat, chain_id = rnorm(1000)), regexp = "all(chain_id == as.integer(chain_id)) is not TRUE", fixed = TRUE) }) test_that("colLogMeanExps(x) = log(colMeans(exp(x))) ", { expect_equal(colLogMeanExps(LLmat), log(colMeans(exp(LLmat)))) }) test_that("validating log-lik objects and functions works", { f_ok <- function(data_i, draws) return(NULL) f_bad1 <- function(data_i) return(NULL) f_bad2 <- function(data, draws) return(NULL) expect_equal(validate_llfun(f_ok), f_ok) bad_msg <- "Log-likelihood function must have at least the arguments 'data_i' and 'draws'" expect_error(validate_llfun(f_bad1), bad_msg) expect_error(validate_llfun(f_bad2), bad_msg) }) test_that("nlist works", { a <- 1; b <- 2; c <- 3; nlist_val <- list(nlist(a, b, c), nlist(a, b, c = "tornado")) nlist_ans <- list(list(a = 1, b = 2, c = 3), list(a = 1, b = 2, c = "tornado")) expect_equal(nlist_val, nlist_ans) expect_equal(nlist(a = 1, b = 2, c = 3), list(a = 1, b = 2, c = 3)) }) test_that("loo_cores works", { expect_equal(loo_cores(10), 10) options(mc.cores = 2) expect_equal(loo_cores(getOption("mc.cores", 1)), 2) options(mc.cores = 1) options(loo.cores = 2) expect_warning(expect_equal(loo_cores(10), 2), "deprecated") options(loo.cores=NULL) }) loo/tests/testthat/test_psis_approximate_posterior.R0000644000176200001440000001774114411130104022723 0ustar liggesuserslibrary(loo) context("psis_approximate_posterior") load(test_path("data-for-tests/test_data_psis_approximate_posterior.rda")) test_that("Laplace approximation, independent posterior", { log_p <- test_data_psis_approximate_posterior$laplace_independent$log_p log_g <- test_data_psis_approximate_posterior$laplace_independent$log_q ll <- test_data_psis_approximate_posterior$laplace_independent$log_liks expect_silent( psis_lap <- psis_approximate_posterior(log_p = log_p, log_g = log_g, cores = 1, save_psis = FALSE) ) expect_s3_class(psis_lap, "psis") expect_lt(pareto_k_values(psis_lap), 0.7) expect_silent( psis_lap_ll <- psis_approximate_posterior(log_p = log_p, log_g = log_g, log_liks = ll , cores = 1, save_psis = FALSE) ) expect_s3_class(psis_lap_ll, "loo") expect_true(all(pareto_k_values(psis_lap_ll) < 0.7)) }) test_that("Laplace approximation, correlated posterior", { log_p <- test_data_psis_approximate_posterior$laplace_correlated$log_p log_g <- test_data_psis_approximate_posterior$laplace_correlated$log_q ll <- test_data_psis_approximate_posterior$laplace_correlated$log_liks expect_silent( psis_lap <- psis_approximate_posterior(log_p = log_p, log_g = log_g, cores = 1, save_psis = FALSE) ) expect_s3_class(psis_lap, "psis") expect_lt(pareto_k_values(psis_lap), 0.7) expect_silent( psis_lap_ll <- psis_approximate_posterior(log_p = log_p, log_g = log_g, log_liks = ll , cores = 1, save_psis = FALSE) ) expect_s3_class(psis_lap_ll, "loo") expect_true(all(pareto_k_values(psis_lap_ll) < 0.7)) }) test_that("Laplace approximation, normal model", { log_p <- test_data_psis_approximate_posterior$laplace_normal$log_p log_g <- test_data_psis_approximate_posterior$laplace_normal$log_q ll <- test_data_psis_approximate_posterior$laplace_normal$log_liks expect_warning( psis_lap <- psis_approximate_posterior(log_p = log_p, log_g = log_g, cores = 1, save_psis = FALSE) ) expect_s3_class(psis_lap, "psis") expect_gt(pareto_k_values(psis_lap), 0.5) expect_warning( psis_lap_ll <- psis_approximate_posterior(log_p = log_p, log_g = log_g, log_liks = ll , cores = 1, save_psis = FALSE) ) expect_s3_class(psis_lap_ll, "loo") expect_true(all(pareto_k_values(psis_lap_ll) > 0.5)) }) test_that("ADVI fullrank approximation, independent posterior", { log_p <- test_data_psis_approximate_posterior$fullrank_independent$log_p log_g <- test_data_psis_approximate_posterior$fullrank_independent$log_q ll <- test_data_psis_approximate_posterior$fullrank_independent$log_liks expect_silent( psis_advi <- psis_approximate_posterior(log_p = log_p, log_g = log_g, cores = 1, save_psis = FALSE) ) expect_s3_class(psis_advi, "psis") expect_lt(pareto_k_values(psis_advi), 0.7) expect_silent( psis_advi_ll <- psis_approximate_posterior(log_p = log_p, log_g = log_g, log_liks = ll , cores = 1, save_psis = FALSE) ) expect_s3_class(psis_advi_ll, "loo") expect_true(all(pareto_k_values(psis_advi_ll) < 0.7)) }) test_that("ADVI fullrank approximation, correlated posterior", { log_p <- test_data_psis_approximate_posterior$fullrank_correlated$log_p log_g <- test_data_psis_approximate_posterior$fullrank_correlated$log_q ll <- test_data_psis_approximate_posterior$fullrank_correlated$log_liks expect_silent( psis_advi <- psis_approximate_posterior(log_p = log_p, log_g = log_g, cores = 1, save_psis = FALSE) ) expect_s3_class(psis_advi, "psis") expect_lt(pareto_k_values(psis_advi), 0.7) expect_silent( psis_advi_ll <- psis_approximate_posterior(log_p = log_p, log_g = log_g, log_liks = ll , cores = 1, save_psis = FALSE) ) expect_s3_class(psis_advi_ll, "loo") expect_true(all(pareto_k_values(psis_advi_ll) < 0.7)) }) test_that("ADVI fullrank approximation, correlated posterior", { log_p <- test_data_psis_approximate_posterior$fullrank_normal$log_p log_g <- test_data_psis_approximate_posterior$fullrank_normal$log_q ll <- test_data_psis_approximate_posterior$fullrank_normal$log_liks expect_warning( psis_advi <- psis_approximate_posterior(log_p = log_p, log_g = log_g, cores = 1, save_psis = FALSE) ) expect_s3_class(psis_advi, "psis") expect_gt(pareto_k_values(psis_advi), 0.7) expect_warning( psis_advi_ll <- psis_approximate_posterior(log_p = log_p, log_g = log_g, log_liks = ll , cores = 1, save_psis = FALSE) ) expect_s3_class(psis_advi_ll, "loo") expect_true(all(pareto_k_values(psis_advi_ll) > 0.7)) }) test_that("ADVI meanfield approximation, independent posterior", { log_p <- test_data_psis_approximate_posterior$meanfield_independent$log_p log_g <- test_data_psis_approximate_posterior$meanfield_independent$log_q ll <- test_data_psis_approximate_posterior$meanfield_independent$log_liks expect_silent( psis_advi <- psis_approximate_posterior(log_p = log_p, log_g = log_g, cores = 1, save_psis = FALSE) ) expect_s3_class(psis_advi, "psis") expect_lt(pareto_k_values(psis_advi), 0.7) expect_silent( psis_advi_ll <- psis_approximate_posterior(log_p = log_p, log_g = log_g, log_liks = ll , cores = 1, save_psis = FALSE) ) expect_s3_class(psis_advi_ll, "loo") expect_true(all(pareto_k_values(psis_advi_ll) < 0.7)) }) test_that("ADVI meanfield approximation, correlated posterior", { log_p <- test_data_psis_approximate_posterior$meanfield_correlated$log_p log_g <- test_data_psis_approximate_posterior$meanfield_correlated$log_q ll <- test_data_psis_approximate_posterior$meanfield_correlated$log_liks expect_warning( psis_advi <- psis_approximate_posterior(log_p = log_p, log_g = log_g, cores = 1, save_psis = FALSE) ) expect_s3_class(psis_advi, "psis") expect_gt(pareto_k_values(psis_advi), 0.7) expect_warning( psis_advi_ll <- psis_approximate_posterior(log_p = log_p, log_g = log_g, log_liks = ll , cores = 1, save_psis = FALSE) ) expect_s3_class(psis_advi_ll, "loo") expect_true(all(pareto_k_values(psis_advi_ll) > 0.5)) expect_true(any(pareto_k_values(psis_advi_ll) > 0.7)) }) test_that("ADVI meanfield approximation, normal model", { log_p <- test_data_psis_approximate_posterior$meanfield_normal$log_p log_g <- test_data_psis_approximate_posterior$meanfield_normal$log_q ll <- test_data_psis_approximate_posterior$meanfield_normal$log_liks expect_warning( psis_advi <- psis_approximate_posterior(log_p = log_p, log_g = log_g, cores = 1, save_psis = FALSE) ) expect_s3_class(psis_advi, "psis") expect_gt(pareto_k_values(psis_advi), 0.7) expect_warning( psis_advi_ll <- psis_approximate_posterior(log_p = log_p, log_g = log_g, log_liks = ll , cores = 1, save_psis = FALSE) ) expect_s3_class(psis_advi_ll, "loo") expect_true(all(pareto_k_values(psis_advi_ll) > 0.7)) }) test_that("ADVI meanfield approximation, normal model", { log_p <- test_data_psis_approximate_posterior$meanfield_normal$log_p log_g <- test_data_psis_approximate_posterior$meanfield_normal$log_q ll <- test_data_psis_approximate_posterior$meanfield_normal$log_liks expect_warning( psis_advi <- psis_approximate_posterior(log_p = log_p, log_g = log_g, cores = 1, save_psis = FALSE) ) expect_s3_class(psis_advi, "psis") expect_gt(pareto_k_values(psis_advi), 0.7) expect_warning( psis_advi_ll <- psis_approximate_posterior(log_p = log_p, log_g = log_g, log_liks = ll , cores = 1, save_psis = FALSE) ) expect_s3_class(psis_advi_ll, "loo") expect_true(all(pareto_k_values(psis_advi_ll) > 0.7)) }) test_that("Deprecation of log_q argument", { log_p <- test_data_psis_approximate_posterior$laplace_independent$log_p log_g <- test_data_psis_approximate_posterior$laplace_independent$log_q ll <- test_data_psis_approximate_posterior$laplace_independent$log_liks expect_warning( psis_lap <- loo:::psis_approximate_posterior(log_p = log_p, log_q = log_g, cores = 1, save_psis = FALSE) , regexp = "argument log_q has been changed to log_g" ) expect_s3_class(psis_lap, "psis") expect_lt(pareto_k_values(psis_lap), 0.7) }) loo/tests/testthat/test_E_loo.R0000644000176200001440000001303413575772017016303 0ustar liggesuserslibrary(loo) context("E_loo") LLarr <- example_loglik_array() LLmat <- example_loglik_matrix() LLvec <- LLmat[, 1] chain_id <- rep(1:2, each = dim(LLarr)[1]) r_eff_mat <- relative_eff(exp(LLmat), chain_id) r_eff_vec <- relative_eff(exp(LLvec), chain_id = chain_id) psis_mat <- psis(-LLmat, r_eff = r_eff_mat, cores = 2) psis_vec <- psis(-LLvec, r_eff = r_eff_vec) set.seed(123) x <- matrix(rnorm(length(LLmat)), nrow = nrow(LLmat), ncol = ncol(LLmat)) log_rats <- -LLmat # matrix method E_test_mean <- E_loo(x, psis_mat, type = "mean", log_ratios = log_rats) E_test_var <- E_loo(x, psis_mat, type = "var", log_ratios = log_rats) E_test_quant <- E_loo(x, psis_mat, type = "quantile", probs = 0.5, log_ratios = log_rats) E_test_quant2 <- E_loo(x, psis_mat, type = "quantile", probs = c(0.1, 0.9), log_ratios = log_rats) # vector method E_test_mean_vec <- E_loo(x[, 1], psis_vec, type = "mean", log_ratios = log_rats[,1]) E_test_var_vec <- E_loo(x[, 1], psis_vec, type = "var", log_ratios = log_rats[,1]) E_test_quant_vec <- E_loo(x[, 1], psis_vec, type = "quant", probs = 0.5, log_ratios = log_rats[,1]) E_test_quant_vec2 <- E_loo(x[, 1], psis_vec, type = "quant", probs = c(0.1, 0.5, 0.9), log_ratios = log_rats[,1]) # E_loo_khat khat <- E_loo_khat(x, psis_mat, log_rats) test_that("E_loo return types correct for matrix method", { expect_type(E_test_mean, "list") expect_named(E_test_mean, c("value", "pareto_k")) expect_length(E_test_mean, 2) expect_length(E_test_mean$value, ncol(x)) expect_length(E_test_mean$pareto_k, ncol(x)) expect_type(E_test_var, "list") expect_named(E_test_var, c("value", "pareto_k")) expect_length(E_test_var, 2) expect_length(E_test_var$value, ncol(x)) expect_length(E_test_var$pareto_k, ncol(x)) expect_type(E_test_quant, "list") expect_named(E_test_quant, c("value", "pareto_k")) expect_length(E_test_quant, 2) expect_length(E_test_quant$value, ncol(x)) expect_length(E_test_quant$pareto_k, ncol(x)) expect_type(E_test_quant2, "list") expect_named(E_test_quant2, c("value", "pareto_k")) expect_length(E_test_quant2, 2) expect_equal(dim(E_test_quant2$value), c(2, ncol(x))) expect_length(E_test_quant2$pareto_k, ncol(x)) }) test_that("E_loo return types correct for default/vector method", { expect_type(E_test_mean_vec, "list") expect_named(E_test_mean_vec, c("value", "pareto_k")) expect_length(E_test_mean_vec, 2) expect_length(E_test_mean_vec$value, 1) expect_length(E_test_mean_vec$pareto_k, 1) expect_type(E_test_var_vec, "list") expect_named(E_test_var_vec, c("value", "pareto_k")) expect_length(E_test_var_vec, 2) expect_length(E_test_var_vec$value, 1) expect_length(E_test_var_vec$pareto_k, 1) expect_type(E_test_quant_vec, "list") expect_named(E_test_quant_vec, c("value", "pareto_k")) expect_length(E_test_quant_vec, 2) expect_length(E_test_quant_vec$value, 1) expect_length(E_test_quant_vec$pareto_k, 1) expect_type(E_test_quant_vec2, "list") expect_named(E_test_quant_vec2, c("value", "pareto_k")) expect_length(E_test_quant_vec2, 2) expect_length(E_test_quant_vec2$value, 3) expect_length(E_test_quant_vec2$pareto_k, 1) }) test_that("E_loo.default equal to reference", { expect_equal_to_reference(E_test_mean_vec, "reference-results/E_loo_default_mean.rds") expect_equal_to_reference(E_test_var_vec, "reference-results/E_loo_default_var.rds") expect_equal_to_reference(E_test_quant_vec, "reference-results/E_loo_default_quantile_50.rds") expect_equal_to_reference(E_test_quant_vec2, "reference-results/E_loo_default_quantile_10_50_90.rds") }) test_that("E_loo.matrix equal to reference", { expect_equal_to_reference(E_test_mean, "reference-results/E_loo_matrix_mean.rds") expect_equal_to_reference(E_test_var, "reference-results/E_loo_matrix_var.rds") expect_equal_to_reference(E_test_quant, "reference-results/E_loo_matrix_quantile_50.rds") expect_equal_to_reference(E_test_quant2, "reference-results/E_loo_matrix_quantile_10_90.rds") }) test_that("E_loo throws correct errors and warnings", { # warnings expect_warning(E_loo.matrix(x, psis_mat), "'log_ratios' not specified") expect_warning(E_test <- E_loo.default(x[, 1], psis_vec), "'log_ratios' not specified") expect_null(E_test$pareto_k) # errors expect_error(E_loo(x, 1), "is.psis") expect_error( E_loo(x, psis_mat, type = "quantile", probs = 2), "all(probs > 0 & probs < 1) is not TRUE", fixed = TRUE ) expect_error( E_loo(rep("a", nrow(x)), psis_vec), "is.numeric(x) is not TRUE", fixed = TRUE ) expect_error( E_loo(1:10, psis_vec), "length(x) == dim(psis_object)[1] is not TRUE", fixed = TRUE ) expect_error( E_loo(cbind(1:10, 1:10), psis_mat), "identical(dim(x), dim(psis_object)) is not TRUE", fixed = TRUE ) }) test_that("weighted quantiles work", { .wquant_rapprox <- function(x, w, probs) { stopifnot(all(probs > 0 & probs < 1)) ord <- order(x) d <- x[ord] ww <- w[ord] p <- cumsum(ww) / sum(ww) stats::approx(p, d, probs, rule = 2)$y } .wquant_sim <- function(x, w, probs, n_sims) { xx <- sample(x, size = n_sims, replace = TRUE, prob = w / sum(w)) quantile(xx, probs, names = FALSE) } set.seed(123) pr <- seq(0.025, 0.975, 0.025) x1 <- rnorm(100) w1 <- rlnorm(100) expect_equal( .wquant(x1, w1, pr), .wquant_rapprox(x1, w1, pr) ) x1 <- rnorm(1e4) w1 <- rlnorm(1e4) # expect_equal( # .wquant(x1, w1, pr), # .wquant_sim(x1, w1, pr, n_sim = 5e6), # tol = 0.005 # ) expect_equal( .wquant(x1, rep(1, length(x1)), pr), quantile(x1, probs = pr, names = FALSE) ) }) loo/tests/testthat/test_compare.R0000644000176200001440000001264613575772017016704 0ustar liggesuserslibrary(loo) set.seed(123) SW <- suppressWarnings context("compare models") LLarr <- example_loglik_array() LLarr2 <- array(rnorm(prod(dim(LLarr)), c(LLarr), 0.5), dim = dim(LLarr)) LLarr3 <- array(rnorm(prod(dim(LLarr)), c(LLarr), 1), dim = dim(LLarr)) w1 <- SW(waic(LLarr)) w2 <- SW(waic(LLarr2)) test_that("loo_compare throws appropriate errors", { w3 <- SW(waic(LLarr[,, -1])) w4 <- SW(waic(LLarr[,, -(1:2)])) expect_error(loo_compare(2, 3), "must be a list if not a 'loo' object") expect_error(loo_compare(w1, w2, x = list(w1, w2)), "If 'x' is a list then '...' should not be specified") expect_error(loo_compare(w1, list(1,2,3)), "class 'loo'") expect_error(loo_compare(w1), "requires at least two models") expect_error(loo_compare(x = list(w1)), "requires at least two models") expect_error(loo_compare(w1, w3), "same number of data points") expect_error(loo_compare(w1, w2, w3), "same number of data points") }) test_that("loo_compare throws appropriate warnings", { w3 <- w1; w4 <- w2 class(w3) <- class(w4) <- c("kfold", "loo") attr(w3, "K") <- 2 attr(w4, "K") <- 3 expect_warning(loo_compare(w3, w4), "Not all kfold objects have the same K value") class(w4) <- c("psis_loo", "loo") attr(w4, "K") <- NULL expect_warning(loo_compare(w3, w4), "Comparing LOO-CV to K-fold-CV") w3 <- w1; w4 <- w2 attr(w3, "yhash") <- "a" attr(w4, "yhash") <- "b" expect_warning(loo_compare(w3, w4), "Not all models have the same y variable") }) comp_colnames <- c( "elpd_diff", "se_diff", "elpd_waic", "se_elpd_waic", "p_waic", "se_p_waic", "waic", "se_waic" ) test_that("loo_compare returns expected results (2 models)", { comp1 <- loo_compare(w1, w1) expect_s3_class(comp1, "compare.loo") expect_equal(colnames(comp1), comp_colnames) expect_equal(rownames(comp1), c("model1", "model2")) expect_output(print(comp1), "elpd_diff") expect_equivalent(comp1[1:2,1], c(0, 0)) expect_equivalent(comp1[1:2,2], c(0, 0)) comp2 <- loo_compare(w1, w2) expect_s3_class(comp2, "compare.loo") # expect_equal_to_reference(comp2, "reference-results/loo_compare_two_models.rds") comp2_ref <- readRDS(test_path("reference-results/loo_compare_two_models.rds")) expect_equivalent(comp2, comp2_ref) expect_equal(colnames(comp2), comp_colnames) # specifying objects via ... and via arg x gives equal results expect_equal(comp2, loo_compare(x = list(w1, w2))) }) test_that("loo_compare returns expected result (3 models)", { w3 <- SW(waic(LLarr3)) comp1 <- loo_compare(w1, w2, w3) expect_equal(colnames(comp1), comp_colnames) expect_equal(rownames(comp1), c("model1", "model2", "model3")) expect_equal(comp1[1,1], 0) expect_s3_class(comp1, "compare.loo") expect_s3_class(comp1, "matrix") # expect_equal_to_reference(comp1, "reference-results/loo_compare_three_models.rds") comp1_ref <- readRDS(test_path("reference-results/loo_compare_three_models.rds")) expect_equivalent(comp1, comp1_ref) # specifying objects via '...' gives equivalent results (equal # except rownames) to using 'x' argument expect_equivalent(comp1, loo_compare(x = list(w1, w2, w3))) }) # Tests for deprecated compare() ------------------------------------------ test_that("compare throws deprecation warnings", { expect_warning(loo::compare(w1, w2), "Deprecated") expect_warning(loo::compare(w1, w1, w2), "Deprecated") }) test_that("compare returns expected result (2 models)", { comp1 <- expect_warning(loo::compare(w1, w1), "Deprecated") expect_output(print(comp1), "elpd_diff") expect_equal(comp1[1:2], c(elpd_diff = 0, se = 0)) comp2 <- expect_warning(loo::compare(w1, w2), "Deprecated") # expect_equal_to_reference(comp2, "reference-results/compare_two_models.rds") expect_named(comp2, c("elpd_diff", "se")) expect_s3_class(comp2, "compare.loo") # specifying objects via ... and via arg x gives equal results comp_via_list <- expect_warning(loo::compare(x = list(w1, w2)), "Deprecated") expect_equal(comp2, comp_via_list) }) test_that("compare returns expected result (3 models)", { w3 <- SW(waic(LLarr3)) comp1 <- expect_warning(loo::compare(w1, w2, w3), "Deprecated") expect_equal( colnames(comp1), c( "elpd_diff", "se_diff", "elpd_waic", "se_elpd_waic", "p_waic", "se_p_waic", "waic", "se_waic" )) expect_equal(rownames(comp1), c("w1", "w2", "w3")) expect_equal(comp1[1,1], 0) expect_s3_class(comp1, "compare.loo") expect_s3_class(comp1, "matrix") # expect_equal_to_reference(comp1, "reference-results/compare_three_models.rds") # specifying objects via '...' gives equivalent results (equal # except rownames) to using 'x' argument comp_via_list <- expect_warning(loo::compare(x = list(w1, w2, w3)), "Deprecated") expect_equivalent(comp1, comp_via_list) }) test_that("compare throws appropriate errors", { expect_error(suppressWarnings(loo::compare(w1, w2, x = list(w1, w2))), "should not be specified") expect_error(suppressWarnings(loo::compare(x = 2)), "must be a list") expect_error(suppressWarnings(loo::compare(x = list(2))), "should have class 'loo'") expect_error(suppressWarnings(loo::compare(x = list(w1))), "requires at least two models") w3 <- SW(waic(LLarr2[,,-1])) expect_error(suppressWarnings(loo::compare(x = list(w1, w3))), "same number of data points") expect_error(suppressWarnings(loo::compare(x = list(w1, w2, w3))), "same number of data points") }) loo/tests/testthat/reference-results/0000755000176200001440000000000014411130104017467 5ustar liggesusersloo/tests/testthat/reference-results/gpdfit_old.rds0000644000176200001440000000013213575772017022341 0ustar liggesusersb```b`fad`b1@P ^X , @5/17k2fd3st2]loo/tests/testthat/reference-results/loo_predictive_metric_mae_quant.rds0000644000176200001440000000014414411130104026604 0ustar liggesusersb```b`abb`b1|> fn_0UXj7r͓0cH%%%P>Sq*:bqqloo/tests/testthat/reference-results/loo_predictive_metric_bacc_quant.rds0000644000176200001440000000013014411130104026725 0ustar liggesusersb```b`abb`b1|> f`>0piּb CbX#$37$g*N qloo/tests/testthat/reference-results/loo_predictive_metric_mse_mean.rds0000644000176200001440000000014414411130104026416 0ustar liggesusersb```b`abb`b1|> fv0"j~8&cjX84k^bnj1!1 ,ȑZ\X 3!37'qloo/tests/testthat/reference-results/moment_match_loo_Stan_1.rds0000644000176200001440000000570313701164066024756 0ustar liggesusers{=qƭ7A *7Bп ->z qHh"'n*vJ_JsN^X} .zHzPz<8jc,>JQSGD?D1:`EO Zv'bYI y#njS zYhtĠ2w1)UxBd@6>6Ow[>*!ZnZd 4&1l=KOlnM nT^5=wH?/n4kWٽbޮD_[|D𶰂Ip>Vju1z*)z1h3GmK `G G]C ,5NvR'DO&?rKܡ n~ad'_RmUTuxm%U|ö3 Aw.uKt{a )i\V'䄴r;C: qsAx0LIxa \,#6Y_yFQRz'_Sx gµL̡lj~5n6-j2|YKCvBɫp[u5;fܫ>9°]: o\%;7B no%NoOМP}8vY1dW AZ̎8Nῄ ZEW& l=٪C@=6I b9ÝU@Gsl;ՓK2Ȱ\isI=!{- m>:·,u࡞eRH]|$KpK78f'dpN4' vs:_ < ;b @.!/XH"N` sjA]Kp\«| Tj|C&0ɺ %|Z'Z]hDžOK9W Zz ? K"Skee"A֖7g]60RQJJ7NBgOz3"F`7hF1W݊jKAKM݃cz00׼rs74*pJ5AT<\"nxe6-V(w8DFC-q.B:paH !:A"*a=#HM7ZTҗ˄t<(E~Lhimʂo|)JƦ-C,+ jUmëeSPy^nx5u쐻Lqb >. j9$HvZǵ4"0> yCkYGۄKnꮙN{ր3޸d m)JZ*G432HQeIQeHQϨ@4g%}FUg8_}Feg>3N%}F3*>#(KrH#}Fg%}F:3ʑ>#HQeHq23*>&3RIN*(Ktgd> 3RIARH%}F:3J>"3ʒ> 3IQiH#}FigB gT$}Fyg?w5~n0*^` ?m|dž X fƠmL6x~B&4}XѭCZliV޻ NGA;#,UPzWڨ ^t9_@uwN_=}.42'Gڨ7c\z7T(_S9UCKj@M{6oKKh+oMO~q_)BSXXiB2pJXWFx2;5Muݴ󢊠JHh6g` A-TwqZZ6P6PAum$bLnvx.&}W" Ԅ:-t&zS^ex%h\`+7h8df^hѵf-6wJPՐk>2thJk7XB 6MC_lgi+Ψs좻A^}D_vG1/Rz Ŷos3n=G:dؐ'H'ЅTy:'u2p n~U@ލJEh\mUe&\,22ґuC?S1W5t) ;rs^zY& \⇌ uM̨2n,ro߮K&ŐLΑ) ONX"+n2F9=9.G$Xʉ%d4qKlR˙7ҷS<>.'7R_woloo/tests/testthat/reference-results/loo_predictive_metric_acc_quant.rds0000644000176200001440000000014114411130104026565 0ustar liggesusersb```b`abb`b1|> fvyg`aҬy@0 GjqIfnbI*T $i3qloo/tests/testthat/reference-results/loo_predictive_metric_mse_quant.rds0000644000176200001440000000014514411130104026627 0ustar liggesusersb```b`abb`b1|> ft`sW wg`aҬy@0 GjqIfnbI*T $URqloo/tests/testthat/reference-results/moment_match_loo_3.rds0000644000176200001440000000327313701164066023773 0ustar liggesusers{TTE/ Gh}@2fLI1Ezw.-ݫ0i –@^(3RHfi(rZ ];Sw;3[HQDb{`;*sqGpcֿ\;}Y}8gpe+q6-?R%$v`aYn{ ~n}q6SZAq T+5"DW'2zVТ^)jb}[v7R١t2eсVu'Q}sCɹQftGzmSݩ@;GܗtK52qg\ydq o,~zAm =OyWQn,Ay+3W{#{1C?a߽sZwYrc-x!҆ =?E"淤Ko )}M2w E}yWQOw$g8>Yۏ-^[5 Jl/yutl7װƩ\%^:iRm+SG|5(iV`kD4I QQH5+ !Mx.gH!MxgH::!Mx4҄gDxngH'҄gDxgH :!Mx4sǪ~<'AY{s}q,EYVqC35zpD{[~]ˤnË߸ڂ#J%(<-<GoxoyNGAYm{7'oS>('kŽ0{#)w)\u풯on–}8X {7eiM7_4 QɋS!_Z+Ɏi)8~m/J'`]A(r7CةyGBye.A5>R<ڕ߱!K) us!Z~1y>oIF~1hn12%MUmT3/h́&[7 c k]}s?n;_{ (V'R h 'gc*Z]<ՅP}M9 p`@gj>IRjMa9Z'X?"B߯`=ezH}xFg=' ?]`:Ӯ3W$r jM3&&&(M~ loo/tests/testthat/reference-results/mcse_loo.rds0000644000176200001440000000005713701164066022022 0ustar liggesusersb```b`fcd`b2~Nӆ§}|loo/tests/testthat/reference-results/loo_predictive_metric_acc_mean.rds0000644000176200001440000000014014411130104026354 0ustar liggesusersb```b`abb`b1|> fk/-gjX84k^bnj1!1 ,ȑZ\X 3Hqloo/tests/testthat/reference-results/loo.rds0000644000176200001440000000344213701164066021014 0ustar liggesusers{TGƿ$XE {b,X]NY\ 1@ᖐr @d VDMfnjE\R@W`4XqϞgd 6(ILEwYcΣ[,=Aflծ(ByQDw!':eD|Y4ny-I;Mĉc%J/q_%1QL7ݕW0 +>T&Hc f~H?3>H 1͘U<u(fDW,ט`aaF-bTxN_e:s3\lYyp|8λon?Y}n)f؞ E`ꥪ2g\ 'vYY-a>/K`*@y-YMvaVw5?FWvA6i>o:E` n/X SsT'ѳkW1Qlz`#Sq1 3)}.$[%/!m4v5 ׁbe 'n@{WdlVBM!r C%ϟ"SzW_-MlŪА +!i e6ur S*n!upb)g bOИ^{JށqʶϜ^Mk6Z][=U]4'v,lgN?Tjϟ!%K]%*JTY)`=0f^I/WRT|M*B_}X)Psdt*?MLsc9?T ;z>KD  uhV=)Zip^X6 M< Sk6vמظ HNs hzGTMmSiPyʚm%:Sp*臲Rz_Ω`#za5_v>*+_]ORP`USI!>OGJ:UD⿌o݌q7|XwVĆ+% K"cvH%"X!IlpƠ=Gݷd5xs(VE(YKRz:ͽ}bF9ӑst%SD~hg\q[U'(;.'jrNXTP`"ir=rt`ŝ2}2DeoZO9W=RtGl`lH _d(I"#706:y!mH9gK00 IJC$DHdtY#WJ"YX$<>![Zf]x>W#Vu0{u_6ecqߘftg/j!p loo/tests/testthat/reference-results/E_loo_matrix_var.rds0000644000176200001440000000116113575772017023522 0ustar liggesusersb```b`feb`b1|> V|Q~ M}ix`bA݂O޴p]-E>iB}J%sjCUjtSO>X[W}xwk(unmR}=#}ȦiW_NT>x>fC`ՍaןXV?3&#T>ؾr3+k?w*hԳ|V}۲[~هM|g}mgWG&mgim} :%Ŭo(8;o:<hwi5~4O{[{te~eS0ϵ?nO;5/9{.{ٿrc|nM&pyǓ+g& VnзlI8G=W$_?n+ojc{+uc\Aiiӡ3: jS +pG^-N=R״?eB+Ǯ٭z̯u)NJJ wxϖޚQ~7jRJ , @5/17'`YbNi*QXZ ddloo/tests/testthat/reference-results/moment_match_var_and_cov.rds0000644000176200001440000000355413701164066025243 0ustar liggesusers}TSG h$h A XhuF.JaC +"TGPB|ZPF=ES@ ~ *⡅E7샗Xѳf̽s͝maS0 Rm1F"ڹڈ~} :Ss\R>/ Up=)caK 1v Pq<)ѷ5yI[ esɛsi _IeJ;e%֯mNu14sxBSt 9޺Zk M?a3¢p-ƺ:ف&;{XH&ȏz4iw23whcԷ٫w Z,0wZk[2~8 ݞ̣Hk +ip!ʽ}Ξ{H?>k猎pqG6(NQ&'O]=@6&]qzDǂb~$P ff=iO-$:n}3/ 9F;φ 7>; gH'yV$ϐN $КڐerT.q&܊:8"̗s oQGS o)c&4/!Jy!|Q 'n^˘HM3z-ҮQHS@ЩۏѦlQ{W_ +|dӳWitiKHXG/ewRX{|PoSn6.GjiwͫLAV=J 5FE>;lw΋C.;;JX _F4 )`!U/*}M Jyzٰh)~$ ChjW T.ݹ d~~scTU>U@Ž(uZ-T=s+.FM?OֹhεQM銡B[p;i>r[rI(6X U_c䅡ʊﳏ+HMGPoBxw gJ9B/Jzc:%b*a loo/tests/testthat/reference-results/loo_compare_two_models.rds0000644000176200001440000000042513575772017024766 0ustar liggesusersb```b`fed`b2 ƷߖE_X@wO:E}:M0NA͂ RSxo;piH3A-}k )oqvœc)PP ,L@X8AJR`B0b [FLCrSRs QxFP5PQԜ̴4{q*2"_ ʣ 8*PX \T&$;9? (U/'?Ē wZloo/tests/testthat/reference-results/E_loo_default_var.rds0000644000176200001440000000014713575772017023645 0ustar liggesusersb```b`faa`b1|> f Qqz , 5 , @5/17k %攦B9E%@?0tloo/tests/testthat/reference-results/psis.rds0000644000176200001440000072166113701164066021213 0ustar liggesusers03;:S)k/ ;$ik~5 @28z0yKvZ8"vjcXv0 \[V=I]ٞFS6(37{+OY@mi:}Pņ7Zjqr j y|hK܈0V_դʽY,X|(Ɠgil} Ϛ={Tf25+S'`d沖MEQ@(8sqHڧg?;ްp'0Rdl"€>LI.`M0j6)Pg3r}5e@ݛuÝԄ6ryDR SW.zW@ tH6yO`v0eP"ǁ))ͼ LHӃbf6dОcu +Dƭ*ܼ'G8 wN:VIGeiOnH'.yU+]~A\]G-Bs T15 [_\?#-p 0Օg7ko釭N2/0wr1Wu׫/Cͺp8x?.1\SiPT;pTwmiswXX0uH˱3@۬.tW ?2$> YT!emEb!P\.ā!?gӹA~}ؙk< =261@og=Z {'0N8X7Jd]pv7`nqD92\m ]a~4GO@/8 CS'0nܴPV8_nY 2߽A@镝* uhVॸ@겢u5~e`މYCa2Wϗt7ĝ=o`lxm?Q awfc%@ 3}S{"\Gl*{cM=2(am3 ײf;y`|j-ۆX|}\n\WU` '6< ye /՝@ڭ7}y 6T9z @> V 卛.a eZܼ@gyϫrSQ&`;(/nkWK~ᢚv)0Pˁ蠛BRɮ6j6Gҙ.\'NѓW73QWPK8P xh<rKzu,e`vٜ~%aۨG L J/ƁCf>@^(.A[j>GMrgWt(stD 0=w- DS`C&0|.\D튺vW&ooW.t ǫsLЪ{y #냫Wޜ|I)- }l1QngDȩOUU UVt(cڮ@9WV'1N7 (Uk/.:i]tsu%ؗ%Ϙ@- ܑ΋}AZ:k74Tl7Q&4ҩ:4{ >%QWN#4Y,NٻwV2VӸ:0?dokϻGw3k9n%o_o*) ȰUMZS,XA.!޲[+'ئ#zrWR~Qw:`X)~B߫أ7@Қqu@^& DGf oز#ZhS5u[_іOP/Q䶂b"МyYSm;`n86@du}O;bLj卺k{~sX1K:U^޲nh/pxu>]d'IGy{Rp螽,8.tf{5c@ MJuOEx컬0pq lZw~eۇz'\Evf`Ԛ*ن$[6b_ |eꏠmeVGY%0<_&Vd5􈪠/^!꧃aX2t︩  N=*)fQ_pԁg^y#{vr40v{Ȝ=+^'6EԱNp @xc6}n<(as+cGbw-jAӞ,}{a [{\ @(^ P''cs?Z(jD<^$s Ϸ3Zk֙?׊?_Gkѹ({{?p--%Vrܓ7HZ2K97baY0U8)$o.>\4\ 6q^@TVMLãzR"+3q}:X Pޥe@fw|ށ>g+e3,85zם4wOQ؊[Q?*_xHt<5f&.nyd ͋ ?WW&NKKlz=s߁i'.Y+))ٽLR u.^k T"C*fDde)N5u6-?0'_Z<ē*i}bclץt{q>OשּׁK9,X,Pگ\zE}_=5?W`r{40Zvk8c3;g=0lm E|X&s 'b!?Ju,#2 u n{l!3C6%/Ez/+z'Qvg5_q}_A+`F;dz!i OY{vc.Zub;*}:|$W/\+Pe Zu?U$ulQq'o?w;Qg#P+6/;/<0m/gnfg^&m.u>y$cĽ` h=5's'p$ 9'kJ 搸,P{=hbɡnW>;dϬhF8{5HpX,>m}[Pw㙳,uAwTի c5Ow4c>Y_m0TBJ.*IY'p8&ۃ-S7&[亹qvOYr2q?x3>3}/8C:kpx*S^#7v}aW5`RE9vz )_@Ir|+RMu+ΊZF#/fO:~\ui^Ci GzSfPvWn@d5^V {(aaԗ[?ZtfAoƸ ?"Ǩ7q&`>1\{.}:Wߵ$%wL  lCkps3R3.Jہp`?(=61/Mpd<͊2mrϪ!\{Q?+蠿\ =U;*o;Up]]T5y#ijz,>AQ1:؟WnSzR gDs.WT?Bיx;vc8_!#בF7&!I\_% Gņpg7] u~VG2{W5Kw\t}$yݗْ3X? \_\&5ۛۡ(,P # H C ɯB$~iJpdG{uO0e3[i^#s;U`z.딘"n^?y6 }[ڞE}mji LXy}K@Ne=*|g6G]xSH Cy>t.+VreڹԀ)"w}G-"Eg7p8Or\jCpz }>xVeޓ@zEg?PRo'`%~}$V,K+l_jtKDߨycSx^qn=nE]ٻ|hg"0B/ ?C~,, Z?ob+x0HyVwmԽkq3x>XM_!Zx+j[.1ߓŹWx>yK*٦Gu\dBp>Vm~:"@q@yBw3P{>3O}͸.[g0f=OD.޽ȏS܁ΥVy}?+PǷ~!|`[w&ٽhV/x 'S~crf;'ݰ2s3*1ݸ}^r1yj2FS3FK^qMR+i_ C{t$j1nq.}0-AnS{ P5/Su"ϦsZؔ뽄ȃk3]_|ߵ Z3dggO( B|Cpr!Oə6ZNan Jn @5;roɋ?@廿2 <9޾@J!\ ώ&|6'3tO 4{ _nqTJq#YGA26r3GZPX)߶.R;Z%Uӎy7HQuy)8ab_O|PAOcȳ^Uco/  bm%K%vit΅ł!,Zyjd+%Ƕ%]c:X !gt3_ %Ɓ%@&]LB0">oS+Fz^}P\_}, 8B 5:s-\nDx;'lٙGSm՝Em@Ӿ&X#1$`vS#oԕ%:yR?ĝ7A} |/lL@Ŝh.FN^v&p_9ġ>Cj3'`,^gT /%s7MOHNFsFcrŏ\2WyFOs`^Y|耭<4[ чz\SFsUL - 15{$?0ҒMJ mq o}mruתqb^ɮ_/1O.M:Ĭj9!\Q4iTޝLn6@=-\y+@m߱/sO֕w?5ZX.?27>#onX]KmNcvLhsE 6q|{!s|q=_p E枌"+PܬCü@Ʈz ds9䪟UJO[(g O @~Vmp4Q^sf~O zρq3@i?x;FM>8ꈜ/}?א 1w j{݁ u䒒i[_d<Xy8 wS Sw X6A|b&u)KUq*wTp+2hOUQ~8C6,\]v<_!V8_qFؘt'a`.|pK{+0*ǖ/iW \\$L1E׻¾}5%zS ͖<:B;BGA̫=D!z >M!kT\R3ͮ{s8#<JxI ƞO:#7%^l?ڟY}aU-棘Cn6ȣ~p ΟGh*1ief;xpdOX`Do%7jo#Ͷ<߶U]bd"qNTs(nI"j[@xp( g8 wemBEHZ)9N,xˏ%4t~zoCyHnq' n4+.L6A- Lg5q5f=/YA+3#ilI4{sH'N3P/=^'8e{ X ^đbi|>QzU3 v>jo<`XyLa kwBK&̯̃,f5 |0yk]. biZa?%k5n-8 /N x冏sNqe˸?>dՃCXW_7_ ͚ L}HrɎfԱm翻0% nl$~qn'SM1&_8b{f=`_C^#DwnV>i9Ѯ{@ʯ%}Dbi56^Q?{߃@nXo=ټE+iz[}Xˇہ,\zK[C;b^s=+Ȋf_ovLk:[2L;/Rs4;iŮ@zI/Y.&)(8Xw*Mris򡘟Ey=9MMϲM_P7{Auun5@DQ9f-' haM._ْ4+`J㪸63xJrJ< ξΨd Y'%y"~FqNӔ&>;4TV:/0:b,G.Pֽ3RO}ѽ@Eyu _oyKļe5FLb|9b=aS߉ ;ŠGiUܐ4m0x+~3FfY,*(ūc+ͺYVGy,uJׯ ;(o&g{_Y*BIOi^;]B{7>J#y<_NOz-#h֜Sا9͗`ą'A`n{r;&{q.KlqV8v,INݢ@}]D\H7*/%2wZb@ٮd,fC}^ʤYw |œ4kYV(~5sKZ,¾˸-r~I|m_;g [c]w>9w1Z-MC,ǶRx䥨-eˁw2UNH.@HCS*v ?;psN WIjwЬĐ#4[n /}( =pxN 84mJ=٧ݙ+Av |v`E͆KEy&Y4mcFi@sb}f]yg5re (Ǩ'{M|Fl DxSVC>so '-! O/:FϕqZᨿ  wބ Ow{_2>4`+_O ڕD"k#z)J ./i(ܲK@*/t ^\P7qdv(3Az@ȻVfM\i?ȑ:߇z2׿u?wM>"/  ̿i}E]d~GmÝxt_@|ab "Ep Mg;_\7)\"?SWCn戮vXcvN@\u{$syR?s1n2o8g7. ?;՚@xp~9դ}'. "}M;~ju|s %ϧ(9fо{beL-ޚdU2|~I@(~i髊|'B\>O?fwPk N[F yTpƹYcm_A~2ٟv@ɼsN;K#T|mwT v0AV}ǔy HƒkQ:L8dP-C9f7+JJc6Ϊf=w{ۋzȳINk-W,@5}z<{9ǁ]dԺQcpz-6]74\i_ٿƧk RB,>Ҿ?n+hxyNb>J9Mcn=wcjy/QKZK2q%I=q.RYf&M>;IL_e=4Y@;p}0w [he]}9*1¬ Qy G>T$iV띺8LMCWcN4SG3D9з?o9Abq3!i7|f=uZ}UzhJ䙑O/eܐ6z4;KBCY:@l͌rmRK]GXas@dZ8ԅ< G.N=e;4\=9Vs;hIw=gQo>VmO__yw\Mi'|=^Tgd@q>@V8=]WЎr\ͺ}PsauvۊL޽wn.["?glPfV&s:( +tx%_|oO՝Zg;KN8 Ϥ?Qߖ:zd.B`W Zur'8Fn~̧i*6=MWMzobeƨ dKy9̡&+ܵ#\NcKm{/)~``o7sMEP߮}ana[i7EY3M#/IWT_MNJ1nOrA\|czeF^\|9bUa_mrOߠԉA?Y]K#K ^pS:%v'u(Nu5ϥٚvOy4z=hA9>+'6@տjMTf8;}POC&#!+,zpؼ滏1b %Th~zs!r3Esx+)Ank>wbHf}ȏ+LZ+0ymu)3@:N`V9~wPMdһQ7Ğ㼜=2~ni7A- [oۆ'`G} We_*7`>'=Ϙ_ܟ s=ODFc4%MԬ8Gz0uc?.|f܊|`k^]ݜhvf?H~\oC C3r|". :2-gٚzr0o'e1} Q!ȓ $O^~hz9-SםAZ#qq-& Y^2y+3q#z7Tc|XֹeoSЏz ݂>ds]Pgl;&JiD:D_ЌК%YK6 +15 DjѬbS,ű9E 5xy`k;νh$}{kݹLw oa3P svgc6=OoS^aui4-L-|R>+ B[uOJP'sTzO  Jtfլ|ycbV&n$Pc~FC"/wݢ,K9ov 襐UW*lPG0[sz?:' 󯗅pczx j8륫R6pce]ڀަ.sVX2@Ak&v?V p?[0%5+ѥ!@YÍ>5xDnq^."ߝy|`q\A.rѮ$>y6 E'ke\ˇ9,Tc0P[7ٶ3g G$]PKFN}1RZwiԇ=nC8_:2'VbዺN7%)m^?yw/<%&ٸcǦ3az4Cz~»COaa]Fc4۱vjOhV3UבRE8tpJ#(ߋ< yκ@9Qftfguf\Lj& \"qU]dϯ" 5Wa^5佶9P9Ȼ :b>rRflzsA[{khe] ȂdC*X*6 ^̓"S w]YEḒF B1|XmrwrWn`x> [H?W[B}g~ۿhVj$f]"cC>ZPwx~-!SDU:L=^QYgI*aun9eq]GŹ޻Jqg͢Vn[Tp[y&7}6:|p޼Sn|Ѧfw\WŜ2w{T Rsؙ!l% e%\IE Du>m: ĩ M/U*Z튇$}uXW;>]e:ZYfk/' oys~aAL[ gW}>[Th$#}<ۇ|:vV]Ai/;bF Xe1G/(x-߫i"nf[X/rSRd$Ρ&u2NF=b'[+ Wc+ӵkB[)+υܰL}i{`WmA{+6Q|193`~kQ:~>쟚_8G~u~*ч}ܦK0~ݙލ: L%sk\~PDS'SBԁQU \>;!0JƝǼFiĵ;nx*yٶu|$ԕ`m/F%! iüwzs/r O md~)N.+ye篦@Ym^U ĄÁM]=*}+Ww;_#S5wpރ<Sӣ5-sn ?tF3S[`G#7ۋ~ FQߟCx絊R.Ɍf.b#q0؟N(~;?%J5PnwgV6CfO0[_6y=>'\<0(Y j yLy?9(OleW^*. L"%!'- |\V{@iΔ[L\| mbH&soBo#廇cn`},80%d`&d Nx.k0M]+WbBqN|w%6ja]zF8:3U7{WZOԋ>jsR\d'i-k2G:@D^|\aFwc녮S/sr U{;ZzsXtj[1X{!K֭Phq]suOgL`2w9e| 4Nеzvp+I[,cr(PR?3|`r)^_H|-]7U>yW~~` u'7q,3eQK֨zaW+^ d@U_wx0qk"ťpoW EbmB?;`j5[`?ωUBPY*IF} ٿ'd ?~RQ_;d\{V:UynFxLn܏޿/Q=*B0(I ƘuS?]0yauE0iU`m!.F5ׄ30ڗ,A_e]xO 0+4݉|3>Y@@[5y^spX??ұ8;?Ne(BT"#Pq}O S<P~ 9#ғ@-!c?7n Ytir}E=].MGKkJpU[B?CPpIJRX|:z<]){fb ҥٻ>yC'b8"пY0oEO8~%. "?f?WEV }.o Uˋ]>qWS_r݂w 4x q߷GUp\h=U7c[UFmP8j`D)#Z_9ܧy$`~.j>{Ᵽ!/A\f.XI!j 2P~vU;wդyKnlވg@̺8ZNxC=w%V.ҹ9C}w2nNN`mIۆ|疷vs*+ˀ9hÓ ˨>i-}|j_bh9N?oB,X8t]gb8Eׄ,fRNʓ/ٲ}Lu}6qK>[`Xx?3B+N_)7gi 1-&L/2Csm:}[k{e |bs!W`m$\_^[P!9K.}|\`1s^̑n~+~ܤfyUC"g7>zr~/(\Hu쟄?C1(9H3{q.=9|zK@ OD#~ 2o!P )9zfKf5ꊄ(xmCVcPF1wuD{?C]7߲>{crPdΞچiә@[k,{"3˼_pyt8sp}h|qqWx / ]44%3;) q.ӴrA *ۨ,6Wol4$uܷF!H#̙e~U&@t-UBoiY{tqfק]l0<諕3j 8onrsHB}m˙ױʷQ0r+ %2t=D=:31W1oR? ' G;CL610%86BY@<~?}Tlyh9m*c'bޕk5q+D;n-@6Y?,sP|n:o59bUKή@\}C@\:w!{P8rΥ_M^_dǷToӾ:WPpS`D8,9 /o/9I|n.Ǎ]/jsd>A vg fZ* ~N21?@Q]$F 8%Vs|(O|F6s9U[~`hԿګ{~]W`Y(0S@h$FuS1HKz4݃H \:NF t /MX_гq /4ͳ0Ļ݅ǿxw00Xq!ws{~F k~WT6'hk23b@vVm~q&8Y{XАy<uF(VP#`YnC}ÛVI2b-d΢ /Pt<FQ @H{ tQ }d x$ 4~:npw΋@aKU7;0Dc-QUZ#~wbcF@L)ȿ[q#[X*[4\ *KJq}d1_( @\ϝMBJJ22Y2f$Y8x֤/o`|w̫p\)3U{fTȡie˝/M.I䒴y 0j8u}aÁõ"`]jJY-ZqPTA$Cٚ-ȃʇ/Zd@]} sH`pg]y\ȨO%ύj+ɨ0+)8 ̆8o:ƿFFݍMiդQ\=d0%qt7'󢷚@[2:T vj"_ ?Y]m LL|BrCVt·Nw_mX%&qwWuKq=^VCR!H5$[a~s]bAbB&쓢Jj@u㳈̧<'YOo;{Gr!H &ol7ǀ%03g /ybr`:iLE"uou7W?wxj8kn/s\6% 35 R'w\٭.%M2J@H^?BJaw@dոsCZp EsWNrڶuak8Yyh@yz7p?юBU@un|$(H'8%)_9Y/k*g04knZس/a#op̸̝?@l|].ʏC+%f F nyi떂z,yrH uX'~{0W.˅Ke(VǸ⇻@Zx+ޕ\PgM`j$&ÆFk{w2޼|o(7}oE {-̄//?D?=+f~W.0ܝ8V_Q:(YՋ"}ܛ`s|(j׌F$Svz8rns4-|VƵr79|jnLkWo /;"{Gqᆔs\ Q>CKỈO?RyI. /dn5vD#a{QzH_]cnv Doz@/X:['wHzWG5}+~[C:6P5?#_rbΑ !}U0?ro{G&m4٫7+set߁/xViϫyO*_مZo箵ü}ukE|J~w[PA#ܕ0?=sv 7sBi. 8294ԁ1e8Vmx@20lyL c8qū=ڽXU`ȝ{3uݏ>}k,1w6-Xgi}ܯ>C/{naxvn\ woGcYƃB]o& p!T#}Jẽu5_ېf +݊k uӯ #Wd0>A}\c屾ۀS0h11'ٜ]L63/s!QUHr`wd;/ݓ`U{5,_| 7 |*&& }3_1 'FscaXW]EH}}[jWP @m\c}]񶈐[4чmRILd0HB gj7~\A,E1Lr7S$沎7T1oaީB`KN Q7{Hjӝש:XtoùvIH SEKGrR[Wlcُ{^{ g?=|L?p̫`}=R:S8+sfw{`*qMbg~9fM2eB+ўF?~}smKI?gVL9/k'o8]3X _@_΋9Kjz ܏6w=y (Nj|yu͓wV9Mպ Y]J [zhlba =grʄ-"aؗ-B_<]NXJu}BS, Za,M{W F}ei&_Vin:'MQn>R T^]FԯxۘCʲ76!DŽ|Ǿ}i4Eڻ?^DHۙɝZEhs|ܽfo\gLm8?݄w|_QqMym~F-_Sa^p :y"}oQ\^ Ou71oa^mhĝ󱰸fWXo^gǓZ <:=ESnH!۟FCl8طKmӬ W#VΰH 91 3X?E+_=ȗ@vouD.T\KE󎌟9{eݗLuYdZD$0 v7LGם'jz+[fo!O/:(5],*N(8u> a#.:%'0l|1<3/`.8JyMd1_٧paz]iO՟#`柿n@PHlӪq;sϤ6KiN=ϱ*-\Ubr؉x6pǨ5"HN@ pmu4ˀQ ȯάaz)4`ӬovGz}ԻYܷ-*3">پƵ,T=?(%uC:7_^T}5-.x3b7f"qUZh4s^)L# <(/gz1#_=ZQWO.e!߿|ڹ-!Ԇ]ѭzy>FW ^fYP"Pn_N s^;)s5Nέs=&!zN 7\`+q=+@:3n6ɻ8Lmy8߭WE^Zo DvY ⰀVT\B[x{{ͅ6+mo C'C&\j%P4~J=/Yg4{rx%fs}iA w\BGk Vb66+X~w@-5}= g!t'd+ UeZg>FxZY;ye|7 &Taǯğߪ Bo4{{sQjCR.lq~x<U~F >䬼y] oNo\Yw®_gz=ok{hKqd87pZ2 T)ԡg,8?ƉQ/L֬M dS9z6U:<2le|֦@BG0{*TƯ7cf@IZa9W"wl0hO2 9[ .s_6Zo7wIYk痦g >}Z R M4[+S6L+ Yb^!Wƨn/ۀ'|OBL($0kZ3qZJX}{Z C/73(]w_e[GBu-z4;sn5M;[U}h0jFV@}Qq9 9 xIVv,G.} $Z8@umyϷ<9/QxN>Գz ĿUp~k~@uC'꘍ѫzNUz2W}D܁9W w(]}qӮw=s7қ=}\|o/Mpњ8 2g-Go߬ NiKX`x}PCK]riV-ME?nF/k۔(yw^a>u8] WҨ;_ I8_睕EA[)pɭ+}>ٛey]2:GfR c{`&|dC 9k>s \,4ZrZ7QOkPFdvn⭵y3 F9_F#o c~~8uf]O: UZp,dʲcSPK&󜁩ʊrD/]뢹[?yW;|k 4r$]Y(fW+ u&v@|XGie 8Uo՞c>a=ؗb=m/]1u#j\BKgB0.}9тC˝a䳤c'&[l'KpkLg ؉yO_9t*=!?ⱟK{_nE{hv{rT%'0ۉ:/&Qȟ{͹[۳[Lf?k;Ǔ$%NUi]&CߊZ蟅ʦ8sc+Bua }G~nk.@h6aLOU8ﶄ) X\|jEا3k[KS N]V nC/̨: ՛[B7./٭zVg,zab~&wYss@<;UXpUPY3EgjBG-eJϚ)t /_:-Wpщ?غgS#&c :EoȇSVzW]tՃf:.}'0ńvD?.VXw9w"W9_9&SkH؎*[2fKqZbVP/W۴:xy9 ('_iW|R_z,}7~oghZ|W7nV`Q;rN넵I۰o.{듓i{ B5o@~td ďSr4c3'[wa>Ӓ\:x8H (πq}&ǮfuIP'pI=r}wL|$d2\ 瞍F<pH sM#vK^+Y>]~nzcUݖ*@rH{pnkCmGqreE#^zZmŠ9'; ⭻7}&Yߵ'Hs1>x~;Կ7jn]k[s[jR 9e4{\\Xj!&W)8/zq ii_}~RWvf Eo%]iao_qr>1ɳq?m5(qA ys}6 P@DǺ6:@ϮJ?fչf{4' OՀ%[@Bre/__ 9G%濇)94{fWd?ݼ,g8?bJc|j+Vͬkj5 4+T fE NTi[n&km-oTں(`X,l#ȼuνlΩ0|L9+6.GE!\ Q7q.7$,vܲ4̘Q <;cu&"\IiO%QΧ>C:GfeX/(8ᴯ|斕<P@uZ=N jəɅly]mI Բ}޻e3HGKXJ@O1iob^&=hK>`9y߀x8SzM@6kj>5u㎝^5]K~!OY!U*lY~9bnO1kZ(Ú6QS ٧9ŨEB3k*Îjc⽑7˸ļi΋>os[.c/\x;Zα9POtl7~[du3@z7U󂦭7MWNW̑͏޾}}_mrܺa}%Fp37mV0̮~>[>t J0} WfՔo0u`tR|澬f 2_h~ XuP=&0T`?jCaU8&R0W\>?f?| tr|jnSyB'0To4jSdkԚK,4lho!ɟfsN\][h%CUhvgG\K7Z2lFk~>@];b29)cn?'Lڗ^ʝ.cOH}CaPY$> ʑ$>KY{TSwS9!o}qS|VܳUI!ܢ(t\{rBZЮI'%b<>Pu(/0ٷa}}%*aNR @ެO?ugsigCz)֙je`&4ƹWiVG?!KnQþ,⾟ٺ5\W+~p:V>Vh_$tD/jN|y DbO!]~Uy +vuvF{>ͮ}ï\n\D? Ywu)wz.^nˏx/ n#aN>VL)܍s*6Ϥ1.Zoj]kZr&0Yn;vym]yL tӥ%\2iY6PBLNԉԻN 2m}g"צ݋w󹏡"3ZN'3o}Y￱̜9׏m"Sw J[PNU/ߓBn"s},Q't9,=_D`]_=4Ňy 1U}QRüMi>nM ۶Yԍc?qb{u+?u%e ߴ'~T#_w) ֿwmtEd1?X'8.9P$t8KeԎ-rG"cc}G^wK#h;"[3w ԟ3}:;{;%2 j@vz`6Զ oxgp역^»JU==Wx@(4 GpD<چsd([3~lXȕ}F=͚f`Fzɿ[ϊf%H>K;\}b|`=ȥkjOxh٨9 UW|l˷45Q:~t [z2qFd\,Ah{rU+P>V7?H㆏ !0|q%?hExOT<! PLvRW"7# +/imOW<.4ұnuomWƦ]_.؍}v\5Wݘܴx99m UuY6Y ;/|w7'CNs,+az7A22F5qC@wm*[om|l'z:.wy6c,giX`:3Rݬ=sӏ9}HG],NW~ԳXxWZI?s$ex_ֹiܿkAoSc0՛7mrHB=z|><3=I%97/C]=~.9j&V ~΃E}@ߢ~}D-z%vl@ں0l<8RP^|Q}.׋:}-VV47x(KgǧD"NǺ]y>z-^af$Va.{F=q%Әg")#oP勂KdЯ-@rCNt+UkجF*Ȉpk뻴^@\).bn\\WAϕW-YJlUiָ1 |fy }0j| 02Rvfզ_Ča.Nj.a4뿵[d1mOq"`UΘ'#˚-s߷_|!X3a}siA̬Y><> ]5w3yqz官. L4.0g5̿uig7l56 u" 6QSW-YEu3;YKމ\4R5[wAA%$F\呓+z?zI[[qӸo#=[y!g4rC;qvxjWK8jEp]-8X/R}{޲jwjաKq£}'hw% ȭLm}|i"5˟;Ds9w.{=2zvEcznFrT}[lu8'r0d]Дn37wn5Ys]ŹmȻ 7O/kJOe2;xݯhnӇ@D;@^\9+&mH0uyTUCHc@ZKnYJEV%ߧg]y*/hezd0c uzΓj߰sK ;)=c^O;17\?82]4Ibސb=P g%IBVuú媋\>I.dP@,nZO9HJiou-5JmRͿ r!U=|1WtB_tJ\ҭ=WTd%+8V~9r߁N+vz*?**W[r~hiv'/{C;Cf޲2 zl4+40sٓC+lF@[duJmsniѰg1'V:y-uxT8m-Yu5[R1'ŝ6 W9My 9ԻPиz$7ǎ~Ժr@G;L ߻04zv:[J4+Xi5PCnY̎f+ Tj5_>.68|1iՓV#:֍xE(Z7n)L=oO+P}\h:!ٚXyFm-Ou.N\{[\R]f_j/k{f[,L^>,*0{֗J F8dKңh)=~\[CNkK<"߯/h{3!qz:U<@[2ӓ〜%j=O-/8܀ߵcm J@3[>Oc{y{{>\cs+Y1 kVMG6"Zivmu_yr9 ZBsvچ|$ZM \Fz:H=8+>?a۟U@Tؽ{i~@ Ϸ]a PC{\>[e `%̇^٪jRZKhvZڪ)tI) O\l2?a;}KZ* uWf/<Eêe4'ߦhVWdOY7̭:j~,Ro$I2PyonD}>ͺD}Du5\Q4W#Isk@wԣ50r?;lKVa\ϳ3)OqIrqzN0azv}Cj5f^i8ydLU}ӾAN{?Bm#=6~m؞;}+@{%z.W>giVRIz.q &dxPE\v5J78OoJUli9ӼdINcߟRnrBWuu:Ol>wuqvTZl@ߖ[9s5(Σ\"=ogۀ]vfoZ0 >;>U'qM*PvOL+sM۫^s2kOviB=XpRȁ70o{$9"ZWNs4CRƗKqR"v^cۛXxPd]JO$B1<_\CW~6UV.zSAs;{"7\\#(m[7thVB 9ҳGJ@V?Cۍ75nd$[MK"y!?"7{aCl<OڏIߵ,BWozs`PmYg"WFxrW wF[ZUg.6R\'Q`` slҮs|ӍZ G|]W"T9eYA=[yx ni ~@։ (GNҜ9f@ };;KTn5jwe > jGZ'x`%~CuuG>~GK+#jѬi>Xm1ngKm9.]4b"AYQ ֘S E4lKe%ԍcZ3? j:w}͊f?,1\{s 1O-4Eݮ s'KǏbrBN{>ۂf?ˈ]ER@:I.?*ͫ@Џ1/f[άΦe.]8_E;L;ԟQ[A:C?"1玱6-zmz3̗r=kV#8Rʦ=Y&@-{;A~ { ,Z@8vA)znG/-JYuBS>!lOryfg`#PVO;"KSzO: QcjȻ>]!i4+eqH 7?j|}"O{Yue^$J_FyTn7=2Z %m<54O#mȣփ+2jWڽݨ7 =ه[b]VO5y=aL?]xs"}MdzSHap3 3 ؇VWϻZ#g_[5s"V9axnr?*o܏1S~> 'Y~?ˌfy+:;[wYw2D߅O(~ 䲅ͼp]Hwrœqa@>KFΏpצ+!q7s"RwKR.\tX Y@8k7.?uEi۱9?߭rqQi^*~;U.:"f_4ڵ'8oŘoµ܉kwW˔Wy7Aa^n@֙^y s毗F~P['e!)I/?\ N[ <>":0á䎹EM);2sͶn3'.db >P[\AߺQf')3>Z2G_/U Үo%}@Փ O-f= >*NF]m7PNTĿ_9qȭ3܊Ati=':'Oy1WkW<~Oar̡o};GT_ ?,\n>>JIa<ȑV*ol<m@(vKٛ 'zYLϭohE:ljP[ ]r<ۢ>[ zցI_o)|~~2Cyj.UدPg0G zu34f}]u"9<ג,Y$q u@Y/MmTy봸 2` 3biVCuǑ;{Z|YVD#Zw?,9Hd$ꋤ- z9[O1ԓOV}uFcρWTC> 4kgQ(PBgw'쁋W_@ffyaչ8T̯:Og6 >nxڄ%QW9] x҉Q1uOs⚽Ɨp ^j=!m_ %޳9?ݾNo?MCy٥z&koc)g_fj 1U7o'aV}leх E#I3wasB|X.U538& gD\~L"Cl`; D'ٜNlN[dg3,pi3wM@8d5OoesGb=7yGw{:Y}=S>AH\AI}7y -75X oF01Cq G|sc0~|#m?|!<64gvf 5DN%4Q'QlKܹQWse/&/ɱwbh.5?@=76\a|~?|6 }#, ć$ً/iW ;Fp!gKO롾ܰ:B / )$AWU 6| 2O{eY`xڊ \_D޺#_ ;nѓf:zѳ~;3fi[r<4V6Q^)n?ٿdQwJrOeU+}飐xn[ɫp/s%oh8'~q̅Wi O0>i}l/77as.~SOL&o=mUx)[1@n^}>{"ʐyb]&؛CCoTb lN"6ΑDx-9Giy6M )) a9 s1~wa-1;u> {8_y\̼%ԛ*;F {aD}C+{-F8S=}ވ ̉|/5_ 4{Ԁl}֟:8/ԧev;HM_XǗɉX)[6 |æsr8W_xқECnxGNJ!Ȩ>uGSTd cF<3IU¼k!7 V}nes+j "'?2ZpDZ 彪{؜9,_&Si6G8f\\pf=q5[<030M}sZ><ґ:t"Nl`ي]@H⎬lzNg8=w{^}d/Z%`/sq3Ia_@\?$8}ƢrHg1d/ ub0y?-9s l#;^"j"Zcӏ@dWror̺z8'|ǖ˱͙axv.юNLj'ا:Gāb[sax}&+^^8'gm8N_-KVmnVIN￶{EX >HNw .DNYvoo<ًgn{g `n<ت(8s[XK?PKHG߿xG[ԋ[G<з_g1/*3l쑻KRMa4?3ӊmi:Dl8H3" s_0Td Xr?#>¸>HUGKŗmʜaKiT7/MSsF 2sx_ں o Go@,Ӫc 4ر 6yG"g)lgsV`b>ssO%~_{ʾg,(bVێ@HpwLb#L esZy; uuenܝ7 W:@|m=%U>& ^{_;tB虣}#~> `n{_ٙ"Gb=ljw &ED{&sƯy:.|#Я~Xb?n&"7Zy 6:N>w |+,gOUvlEы&6׮2)XGNax'H\neq8 6,Q7<ϫC;/lA?wJo1r\rVl s ܜ+|b]?ZDaUx֦Lsk #,<[(ܞ;.yFg'+(r Yd4{XdqtcZߧK2 yJ}֩*:s+BI~i۷]w kT2~ \lOkN|=i E NVii 4g/-Oc/ڔl߷\Ƨw-B3s쵩5j]lθB WsVK؋uJ># {+1OlħVf ClƲ  lԳsxj/gp$KlgiqPb^ř?%RA1A uu,<Se<2Fꭸb]Lc/֫[',J^ oƼ' q {ڀ,XesΞz9^鐇T?@*۽\ې^O~_P' [ї稴W߸ND-@z6"Gۿ==@opqČ!Vh,2e/|D7md/)t/L:1W0rzZE\* P( :<-V[󸂭`^?ô0wa{sϧЯ[~B=-$"ZMy ߗW9ѻLٜݿ~myA>& .q8~IORq5مݕ#7$5`s*:xuE9Q:9y-G5_y N]2΁܆q}<>Rn x.ŜX_fq^S/[\`ZJm/V>A4a?{|.1+W'W`]\2NR{myAc^7pʹT@ԎUy}`x WWxblХ&ZN 5ܽi3 [;$Bz5KO?{zQ"~ԳJN:AMk/@X?Inzrp>YrOoP?ژ=sIx2[~yq j}3$s9$-Ȧ7xqL qMLQdV& rI@{]s 0Y诈Ex*nkI{Vz"wd^|R봧_.D~rXoJgp~[i!/?N{Q#C' ^` H+#San٫M&齼ؿB?)ʘ{oTIG=yuQLE>{T-̱/;4[?lu{>7['2ijغ.7ӽ0??gC~~ջ" 4̷};]yw:''A* i/ I漏zgRV5q~iSO1]2-y5\z( j/RޒɱsڠnEKԜŨG@2jImc/Vҋ>5^g%?\La.b4b>MN%69.QS쀨yPh 9}U5w/V~jzJ>*a(^HtKNu_7(X_jjM2o$ fs|sƒ2ϰ~T| &GNfjh7G2W2k_a>-Zqͩɀ?;2{ݥĻO9U>͹w'J(u`E9{Q{ y{aa>qUy1e*I.Gy+H"L9vBf- ٜBCiťwQy]OBU) q>^m+|xk}]K@Z땈XfO{,3 ĨVN96Xx:s'CyԫZ$x\n@8l#2sXc(]4ckXt*{lNNkv8U:WʄxF]?wv[/NAN:aʘ@zIHiA?eapkD3 ' gW͎@xwr0}6"}"ߙB[yW<ʣl{[tV7?D* R/wfзG=i62ɞmzWjntdiy׫c1)6~(hg ^-:t?83!UN-ߩQ=q䱦@Ua}ZRoW؋w]wf/d Fv_9r v.!7׌QϚ+Ü=S;}uz#5ٗ k{ *΍P>.g٥ vډA_OotΤ<\9aĺ@ح`yT0@='xI^ib/X0^eaR8IM P4 ޵DJ" 6AO9&Q}>s캶2pR)A~]=anB<{ %smw9w_F}ݵMshJ| D -bUJK۰s8?f9ROL`_qTB[ځD6SXt.V9{)q.҇JV"@<+u(A댾/ VJ\S |.{Hr^K?E.!^r9^MSBJg.@ x0[{e sp4d {d8*sA!#ȧ^ $gsB@TS"#W/]7@f.❑o1|S|s3kj%^mvM&'~*M;>e`=/2q\ubW/7"s?2n' s}zN{s3G'1pv#@2u4.k[y4F!@ܪwV7}Z#j'+Hݬ;g=:K3_h^ʝb w|&`=z6k69H.d/5sҏOG.c9?%^\٫_dCsߗis\@;ЌH( :Kndl{lUXU,*6ltpbnR?8瓖O(!}y:%1kV~n^A(2erf?~< 4v} ۉ|j9$c)4t[$QaH,JHcY?KɨϷX ܵdsuɜ沬% ?߬ZH-]}ֱI4> RCX?M1GNe6GIɜ-8/r_9Cn-Oy৴¿{nEr^rUȫw c/D-8y-MmML6){Qaq|6˜WsbS5/`3ȬuSq [f/G0sy%l8^_ELRRc@}$#*$L|c)M)˾L!⧠_K@!?y_KC_V[`ݑ9;m_MlO{Yu#k@=N[B?, #c]77\?;-{bjePӾb{w'|̚ θA?ضP $ /̵@ش۬릮{ҟ˵i'Sqd Z  Ůʛ)MRE~9rGŵSVů]v@n?viO >wǼq1b+,q[6)I ?Ȫ>CQ@PsٿJd%O cЖ)żs /¹8Ւ#C|+nSJ='3aW8?qu<| 귬q?QS“opa\HB9 g!i`Oٜ2Bx_9MTOg 2rt-!Fiٿ矛=l rW;ݎFп0,V0?TtOb!zOE5[=?w?!HSo bsJ Ps&EK̡xM F)>3gH:VOx.;L1W>Xv H27z sNc}Зu%uLcѿ6L ab@g9nX^;xxy-Xy$!Kf&Ag3Ƽibkf@ V*N?bR0؇U8΢:$W$ٜwW3⑄ߌ䦇P 4kJv둋)\=WӍd ׵@4R]pyGn]T=(:j2bYS\¤6UYա*e)&!֙*)~T2eO eĽQuaU'E0/B Է{,B ϣZ pn M߼|ĘGnibHB_I {Uؓȋ>޷ڝ< sEǵC&< xŲJ8 ;"=0Wzn1A]]Y좌 悲sy,tcہwzal)&U-}vw@n0//Vois[H;5M^}ԧ{q}ofP˴'<AΒu {Xa.8ԀZF8HGbs%L~Q9u,(l)Ħ |88X[xOq13n4!pԚ>OZE31)nl0"nzz^y|گ=`dtt}r^@;V%&hfۀt`.`< c]Yʻ4Ͱm@ʉ '@h {C]6 i\Oǚʵ@KVI} \w+!Z>0=%fHXe$uuN_ Ӛ6Sdӭ:tֱΜFy@ aPy9}ڀyXa7&Fޣ:6y(:F5M@=xK|E_ҵ@tjOJ4L+"? XFBDaZʥ=Qr,O-csmQz>{Ur>0^n5v+}T?r^K3C@NzfЯ_nqL$ޯ? t=,IT=q$SxfWoӁ"[o4֯ZuI]@\^6jԓ@rue0Imul Z|ƌ8мlvOG^)T 'x|%P" m5j ,%@IZ1 a Ҕ aa5>}qA4PX2%1+y {Z tQxӣ@q+m`+ $ 3{3 @1zQB):!@cgֹ8bB@-PG?_>=4=i``7뀞/|~(Uy}:M˛=cT歪2*0k:m(; xW/Z9"ɬ~? e ~qgOtc4m(^:^ W+q:F|N`>'zA r '-?T6躿YC@3Tx,g<|vLF@xUz[:61~ɄHlb+мF "^S]mt:x޽XOe8J8 NO=p٠9-jr8 +{I"UsN\-K20)LD՘{ϼDOb2ԓޣ@}^ /7 m[$=ؽr>| `)-7q.]Be@<'gPe'^jF:ڨS]Zy_qeTjsѣv@K,uS f_@0p kOٛɤA~b[ khP0^Y]u$y\A. `~Ytͬrm踸LME[u궉GB-9 ^[7pO$  @]Ua 1I^i`Y'-x"Jt NKdηSgڻӄw{ovqoJ{j;hspO=fM MF8s@v BSz7/9@ ίolQzG8Q r/,p>֢S8u*Ngl F&<1pX1-+Q̨=R?3J؆$<`xw'[PG8CՉߕo }_]!Rl] 6TjQ~٩@P9:}nK/+ogKfݯ@ !l7Eeh|gIY[:W ^3jM4ڧK?\P=3B0YN.@=b ieSaI'ȅ7u.KE_wҁ܃FwݶAeZJ*雚yoХLӫ~`3Ҁ20r^` M_uOon+Zyu0roe9^H_ve@o[Uh*EE.cl#<sCjᧀn]#Q"5oC>0 wP_*ꁖ"8 7Q}GQVjeJOYDAry@9n(x\>'2>@t~|k o xh- %_X\Ш8[7P>[/>{uvr8j@;i#fОwGzc.bph@n п{ЀrE^Lj|ym͑&O=׹Y 9`r5>{hMj[h_4SޯY-|It<b Y,w@HM@[`Y r"k=!KIPv9 [ w5@S0En%֯u8CjyF'l*uE|jmc PX4侃\qVnԣU=! k|:y0P-WſH;O)B\˷@nT]>>nvGwYGĢ ^`f֥QJ,t#u6^ҟҀiiJD>p;u4`IYc_[ UezP| !@X/,gcI-m˸@92B}U>WB{Ի9e'К6^Bݙ}G"ڵ}4Λp\t0tŵ@"0w9g5ϻRyYMxg o"Ee t3as\)mȣ@IqżxԪv PVM 9 yHuMrS+l%=z<+B[u X'=~ߏ|q&t=_v-VҝPXj>[嫯_'&l?7tײM3R8@ 9:e5!@?Kp{ԫ/4"s.6] jƘVnTyTۓ]@n~ b?1"Za bk9RFN~"zQ" A/J6B"=nOwo۝y`5*D !:'*S)nyП_zq%{;[12s08p/#Kr~/Oyl-< 嫏>PA˺zɸFy[.0GAsE]nI ߳؟eN*Zۃ 7_.G}}=qr)+[[zsΪ!"~y*x T&!O̜*# +/`L|>$ TbP# ;<هyfxn>)8rE/ȶ|fzZј>P®-[jWTHvt9<˒hY;!m@ɌW.Z ) }ϛzs-0jݓx*c$ix⎡5xn]-FH=r}S!Ib>-9HùhQ L=Rw-0ʤr ZR\mtEX]dP:^Aֿ,\Y?Oh> @8;P]{w$^2+V~齀ۿG,wHO`_K]6+0>*6\䳜܏>55e ןWhrp?5fyBO#qkb_mE(WHl֗v 0*nw(ɗk˪Y0h''􉥃Jmԍ r1w=`&h^5`\*ж)\E;urI9T Է'T];a/Q"Ϳt%szۘ\9%3zRTxs/Up5+3Ha>vr*0蚵Wa!(%G#GI~1fj)i&3mW7@~%9z#'gqݟÅӺw3?{₳;0Z_gbo"0dw7mLc;)}ѽEphr.`%VQa.#ymnvQ ^q˼ބM kH W61X?)5ܸa{Ѩ4˥ w((xxX߀zpUvb7K@u3l۹ub~1n _kJ vnu-Wzn`DZTTm@Ss}x+fo2WKtɁP?ԃkͨS|w B8P_  3"_%-v/%471}՘?=C?NkbOwO"tHCU]qd `{_)LUSP#6PҀ>bէiٓ$j̝:Po< 今Þt(LL/OkI_W ކZqn(.cNvv96>&RٶR>` TpKl8 uf"ޥm5RK?zȟBXn=`4w+XuR|/xw!R os˶Ub>(I$5怌;BI3M*"/Jb<ӾmpЧ:09=L:냨_^fіte4k!'̎b>P ,'Wou˸He>U{qdϧ(/IoOIDᕀzPzr9*]PVn^W L#~{ƳLmg~5@eO7 {r0Hȼ+J`nWkg87_sGM&@܍g}d-_p&༉. lѐպb/밿DQ䬭q@[y}CP(O|d-i[ (Sz+K[Rٳ =(Ym0?TKVVR׍`?dvZ'|ɖgG69[cHQ7O}"OMWʥ՜`۴?`.P|Մ3OX5 U8;Ue#v@YyVxApiua E?h:_u\r!(8kRw]@h8 2Vy=^wnk`8T!qa357EJvFyjX.|:.CŜs-pvdT [}rOHؿ̓wvw|;d~CYg`,JUKaNSāx=мrL%u8ק4]`= *^pMe]/~9K'@_ T-QC*׀|sȍ"3S#ר3Nߢ=+!B̩y ZRqk@S$XL-`FCC6" ܩ #b·@$?8j[c/PS%ps!r?* ;vգk;py} 0UϐVC&vPK4oL'ϼͦ=\q|0 2~|{:V}.ɔht%kё")Ӧ >KGv8uCo~ZYޚ׷9|'_WDOmѢe򻵀 !NNDg@z?uX+,r.} a U`nƻo ܣM:u?Ut0iʶ*x֙8-$p(g>qjm 管wq ?^Vh9&lEˮ?@'U7nGloou-im5hh.+ϲ70ZzL'4)tY7BКM"F}qw茦П%mhf\5r+@`@V[ BF q]~6y>up+_J١ٌ-=#(m& r'N3~LY<0XT6nZٷC`(/ 'WV$@v{s&[_-W}I9Lˆ'@/!$=7f__^j/, UtZ4n~} hfBPݰl+{/ڟq>EWxc$po11s;^[#嗝D^\$?W@mYj8\ Ϥm\ES4?USsBzٵ*ۈP$~E)EI|VIvA$wFoOu?&Ԉ_c Z'BQ О:茌Q˱V6uYDwr6goB?Q؜OGh&x-W>ɘzm;mTߘ;{]1NtZ`rrqKNQ T4/Dj<^kmPwzPL`dռL-)1}`6Lǝoڙꀖ۱ WlybR9rOAܬ0 ˀu=G<=c5b#訸X"WZ&,]2[{ů:U Xm?z^@W.,,1 +:.zL% y.G N>eW' %w^O}c-u6!Gewe&[ݥ>Kc6 /<\Ku~Xk+wE]L>ersdl*wtȟptm;r2@q໓921XΞ=%-Jg1ϔUznvU}x~h8˾j;$p;{8p'ꜧSs:Lg]>ڹFhW<܉ƪK0rgu]OZ҆NܓYκgwd‡V¾o~5Cq=b>0Dz Qۃq1~S^7_L'p}[|jBV7vnLQV#wDLwP ?=Ox{CXYQCʲԧLR6BfV(o8\ҭU`εG_ N~{)"gNWLq ̙]-???`X+9/5X8:_)zMw80%>z?-90+ yׯCL"PSN< CQzT`UbOAPt݈@ f3ӯԥ zEO _ .0K#~q y?c:Lq%uèP~Fc@7 u/ԕ +:14\ƍ$D tI2Ә/t'|YC֒~Hp=0g&kM%S9:P&Pw w}7sD >0TUKՀ+独4{ 9n]>b˻Y3l=p1>ǼB0GCqgqB<\QW{|RA.U=vU=j_\Pֶ]KJ9l7ׇyAcӤ EpJReS|9P־u hvGZ(lI& 1PLH9۳[?ZjyI ep<=[Z)V 3^˟@sa]dн&e|)hZT@;u 9iZ}ePUKuC]M}$[}] D揍ʉH˞%}|j"-?Nxbηሾr94㔫d6sS{ށ0%?lBrQz~rWs`;̝p #[GC@s8E o0z6}1*k0H ,C=2P'I&Y_DF;i1Ƚiޗ0W> uO5 Ǥ5RXggƁ^[RbNuA5$ ̿ϯU.Wjh+Rj$Wz68L,YWp] kأIc]@;iMz24k\ Ҍ$ ~ԝ[f")ЂZ{k ?}u@tf'?HZޚA"K/su`~N78Jǜ%h=O"03egm僥ESBz6_D\LMAkZ=bU"Tt|A*T~Z6ߝr*@sH^s=LO*RZ_>AV9|׻(}:)sWǐ{~ms§c@ݺax}Z#. 3 C "(#G"'ԺqR`^9ȸeϹ@$&w0=o^ ȏBXɥ'3 ]ȑ}MG#,2 %{Yu}GO@?2^`:"z \zc=@m0uF{@ r =rK_  BqDYL@*u8$9_q@`~J(.:F=+'7=h% 6;+6^czPyeB:ݴUZݤ"D.ۆ M c4gw+s&& Hsi`l{T*dM^m77i} ^,/8:{n<@~.𤒲+IMI |]B%;$5;( +Jup2C2<7k6!#_}9!FmeoljT `x0.1ծP=B7-G]@Pon2[^ fͣ-Gz2_ 7p˖g!Gz9lgb`ȧzÍLaw\=6+ =f@ @4bX9~G̎WY$H;krԻtVo`],"gj^=SISJfyD(ד|t >͵q?0 `} Рc|M1s/Vj䟚M^y?X_X%/cz˼M"IkO$\78/r着Ҷz&x(;1L!cg/K@]9}U{P|N8fR?SqjNY&`$PRU 8_Jy큻5{75sEi}ZnGvy;GP׭O4->qdά&E,~|,&z n3;/}Ӣ3,ogGj$yj( \V "E7וOD݂-ˁ^ V{(zv>͵q!=K%uJG3oA@wYL b02x rgˏZVq_8 !=(u+04n[;5G&iWI:p$''˾ȓԎ׏eS3 w]npv xLnH?nnȧR@u;?h=?9oOFj=ss`.m(Kҕއ+ak٧eTfµi쳇& n?z n4 @A o]4}g>$~$C7(/2u TTneԼ}ɪ(r_\}^z!@{/& +u v[ נ|{^9y3 k)MQl*I@a}*(`1OP15Mɶ$G ˫^ T\E%'%"75#0*5 DjIL}Fߎ"ꪂgUcNYb <]gə1~/0Х, %X=uuXwHE:\:}߇!YM ϵNWXyY@zҷ5r@zdzYH m\~jSv 9. H$ٜ$Rc*O(ں3m2u5uC')m]kH}Iu& ]; Y끼?Fcf@~ՙHOݬbH'(>Yg{6fk|݂ ?fy#rJt?m2{KM'lו`{*눽Q5(w;@za1 !} .RNJϮɼsEx (+~ď{4į6p.k4Ź*woF>J ~91Wf"s^'^` $Qk vygLR֥!$& OvR@:;g*HYaW)MR8 } y,45rͱ(j HGP+Zhr'S} 䎁VB6ɄF uuI~}}w[ B{_g @L۱\U"Zumu@Tx y#7Ha_Eycs~;JvrL.Kk¿뛚=Rgƃ" )i;ſO<0;vU\3"$pcm/b0$+uHGNͼtFN H[T2Ӫd-BuS8G&L1D\@! xl+w HzO铫taP2Jy>P) {zB+ȋFM@ߗnd]ؗgLGq}ԿXWsܷ"@ȎvH9^C@>vD/(+PDN E'~sŷȏ?qHz4n-O݃@˥Z㫔32|_(B% @'dقg kQ F|y (|_C:U3P̷KYCý<65Քs6v8 -M@:^]=@23'>.@R48e u9Ơpe"@J_jS%o%6 ,LenWy7xroJqQ @ɑ^.&4f6< nm;'צ%`oe0ʮj[T5V~5Bټ]aj@!μ>H=秭q~gTE}[F⪁D ոEyHn.}@1=S/< G .Oh[ f4qU6׻"qSsr"P8TĹrxv˦P ,IC߈y#~ߦ?'*|ikٵ@p Q_Nڬnm;nt;)>u49@,O{m=E D74b)-7n b̵UQ?qދ2e]y)H(v*M]O> ֦٤c#u+Q0G\7^2R@8~pQ?-qn0Dlvuo۷xS:3ā+ۼPFHTwXH=1@w'A=u0bBԵybg2PT"U))H%1H? 7n= wTƁh5 >Zy|?ܫvYqN{ "_7A,}e 딪t ~nzd+1O ٧%@^y3 >]YMʵOpyvOmUlis#>qkꛆNY:wG\.1\_KōX 7m ~מfp.|8}asߟC,rt}ɳ+7 ])1Dm"N Hj:€pܨBx TkA;k!F`PE8U _$ tz~m6*{<ʶ{Q,ؼ@zcCCue- NlWW2ˁtGD}ikV# ?gtD?sP>{cNQ9q}aAKeZ4"HoW7`~p:tīCDYE@ԛMG9ZG9q׭@>ɗ_G(u`rIck$eXQMf_˟ȫ+>YJC.:]VQm+鄫xsGZ6%q/}) Kp/¹㾊Y* +(I' _hXO7F $Qӌvq5Wh:em@Q+؈yD?7>H9?7vyo'%MA? DQ@6]1'r-4L]T>c9r`FK: P,ц]Wkz%c@@Ϣiq8mVc9Wx})Ig@~Uކ~b4}.iPxO9eT ۍq^ny?hArOaT: |2g[sas& }JځjaG ,Ĝ\|q{݂Aovvy`r"jjP+Zw䢮~_l49&S[O1O@h-1?Rl&PGHs;53@rHkӫR1_|s@{I(Q ! |R:^=;_ș1@<ݲw iFmłgVrS6FW{jszBFApԳ1oOy gNߴk@qϭln1sOBL7@=L|Wꆋ!܎`uuY:|d?\8[C$p[ 9;TZR :OCw_b- jپ:/Dv$yL{Vo< $~v́ Gs?OOL{G5A_miJƜ߯pn,J6E9]<;sƷb C8ѿg,5+ $߻-XWE\t DooQV@1N9@]/a#D'K Vy$FEM'Vcں#z o%w̍u;0'YϦ@I#9To' ٳy5Aݪx$rH?yYNhݕg_ &?r>'x?rNsR#<2.= fՀN =6x k;ṾL[7ko7=tv@KbF~W2} 80tG@~3 ’,jrK'Km60Ez}!g{.$ ;# dUѫG-Xqsɗ {7Ҿȫ.͠.Ḵ eBWп+rEV p?> GOGLNC?߾[ݛ~zIzKRA8jK'.1>mo[I(g/ k? :`.#sA:SVs sc5vY\>a>a[t{ ϡkP [Rku²U;׎cN!9AflIg{Z:q3< "R% &m\}l+ߡTj!/VL U`k'K?4z0~ HGZ=!=v >k>SOK479>?VrTϬw^{HOuwڊ<%k+)JDΜՋ~ l dkSW=DZq=eܯNr @7hnܢ@Qr-] dgtCQ{u믁@ѷ-Cc<"P~L `]|:_'ҎHi+ҥy{w3s;\a5w@\FY\$3{u7žMW=uͿOJ*U*4BπpGޚ/@%Kڀ@fZgD4Q֒vd?ab9 RaԃIӟnXc_$ TOPiOw큒8M7^!;0Ya~RJZ7sZs~?6RgDOPk9xg/XBљu@&Z`KfK"=eU3 9rh_ }{L8o勒h%(~@&:ok$nʅv[恢si=ϙ}h1拍-aY6wernF /QS SVFA}esW}]@rW VRugqWcs~#4 䗼@}]? 1RJ/qb]\ĝ>@9nvfOwt1^}Geя+^>B~ʞ%%U8"5y^[ܧq Nx\?{َC9hGc[uO!k\Tl'<@HIjhgw : ~1zڊ)8#ֳyJ{=Lj[8lD~ /l GMJx㹩{7ֽ@u7" 祵E@ZIEI7ȑHZb[ Sj1'x=4bӣҢR:Q_>JG:O|)j]:A#Xר~ϵppFYY˴zŀIKɊsKJ,~Cz1P6[co>>v< ['r4` X> 򎍙@_gh`|S0뀼Qt! }ПW9,}CǤR Ί~Okyӈ E^a>zk^܏~޿A@z,*Qqۨb5n"b_,sIqc=D>Ѵzף9[z+Q@: @,߱c'PmRRCSWqdz0?uxDqM*@ӟY 猜hl:m Kq>;icEf~nԵG(ΚϬ7? nJo"AU)^͞"@< CW{~^]@JWߵ@k:Y[{c$ok}'2 }k4Ŀ]igpć]۲Ŀ=IO6 /#HnUV{߈@z #L^kʡO[_\j>n($5*8V(佐:oİ*@l4 ] R >mzU א/Nk#n2KG_v9r7cH"?Rm{=~TyJY/cG /PEqc13'WE Fu#>FޱzátdCGV7NR¼RQnOoyO+8Oب3Z92ۀpTG{w]@2ظG PCiԭfB ^6>i]S&Ǔf⸪y:ǂ7E[6 *-Ї37:௹PTp^: mͯؗx,M[2v`I"(:3!ڼ!䝁YRWߝ%[lB 297/ ֿ+_qs\pj]U$mDJ:O]&D% B߸Q>Ŕ|׺@*o^ |ggs?ͬt[l~ ڛ_!< ;:> ,~Ӣ^Lt;d[2C7O Ǩ)H"j9ΆwHd|g5@h*,\ ]o5nJKj|>@d |ú6&8VѤ{ףiG.t b!&nڗq/zPwiYc` 5=^R l8lWtAYg& ,t|qA>N5LxezO9UuNe9湇 րm沎9gE T r•\C~}IiaOc;v}a1ʪ\4gj玜t͹n7ݿE݃9nf"u0}|~|X $SZe;셬irKQ/9gG'ٜ oD6t{WWQlK;ɶzR4{1vICv]UN4[A5oQSםً[vB}*M:YT @0i6Զ<~hN]s7.=0;z+K>66BtRzf5C@ C74XNP#tZQ(^# ^7]+,9lhQMƯF6+@|NH|f:^Rl*tT x |  开}zbWI8ubsjc}ˉŎ@Lj6= Xݻ@~Ouٜ°Ve/ħ0 9@~3BFk 2l{z[ K'c^,s<'9!?1 vt̿ ?t-ދj13ye 4܆+mzrR-i/}'Tٜ`Mp~-|ȍk/ +)'楢[ֽ:hK{tP] o[pLz;ܩQtQyNOma/ռ:.7nWfTQSEu<_dӿӒsռt7a!8>nOݽdJ.vE=(Zk&9\ \ E-0WlεM@Zh6"tXzvf6nl&X*O*"7ٹu~ ̱Ix2ERVh״(b/{zl fNU>=s6[>-Ua\t>#o;B@agxu] sNb vYu̟MUݺkKwLl 3Xv퀅K \1K݅[g2D ! 3\5I;h Q_D_S*5?@xpr)qkX>vyɛP=VUV\vE}]i_7ҫԩ)N}t4 {I["AP >}c ˧3ٜWg0~Uڣ1#}]5șr7m>iM7@ 8m8or,Cfݸ._P7}VkiWDS|L,椬Xrq7%xL "5/H~$DBBÛ;/SCyzĬ[V;k83 lN?wu{K&ݎKmB,κbs7ǧ7}t9+KL#")IKQgƜ@H{v9cΔSmw籬\Wst0GLEr (;>|n(947M\[jiejt{)nsT[S ­O$&2^\tH\%E)_u@o {^ qЛsrxQ6sQR9yƜKRO ngґ^=w*nlNSL[Ũg>gsal^?ݞәS~m|}QҠDL BPIRd&)P MRII QE8׺uiVL3~=Y4)oL#@z?vm4 Us?pވɦڿ]/eAnacysB03\:#QݙAź4˹f5^rm#*C_K0˿rY$ yzl.Ӭ;mQMܘG4DSY+ Ѭ#7cL ya܇þOE6H /jw7kkG_-D"B9q]giVs\Dӵh_տ e:ͅrKg7~|@hK/B0nw}, :uݖDT3鹏7kQ64=wf)oI 4գN5Km؄8~j 9߯,G}yRheΣ7l9{`3֎.GepJ~-tq|O6@)|$@>󴸁B{Yz@t}?`3ǛN~n\5\9qu`\gU'W;ޗ-`ط M"_ckLqB]su,]:};3}Ufݵeڀ^0}qJY}9iVΛ< :l]Gi4m@ҵTĜ,ӎٳG MQOf^yuˍf=&ѯVؘ#'ыyb|r~:].M3=y~e9coٙك>sQHcgd/xrA}z.(lx<hӀoogǻ=Ǿ:,tiyT)4KYc}K0En^L>lJ]:_EJ+O5'a#~QP姙"q}}O@8֮0YYF޿#~9hV9{:fvҌ.dy 7g{\z3 9XVBr]g \W.3ɘ@ER"wc1չ{RQ~o PSZanUݖ倏sXv|_V6{uN⧓N o>yԔ/C:g?:+{5rgk Gnܷ͉Kv$k9a3(e 9>| '}W07?>]8aS9M_K3W~ }dӀh\dE5?M~`=8X-ۅ,zh0ae0ꩬUYq$0nea~Z](U\);|,?Q_v(g#o->ë+h}>:xƅt轈rx3#G>1Lp rb,T?:y:>#jL _=})Ont sQ7q^%T1zjsǍ*Ş[bxk"O~9 5Co"o+dD?;7ּxFV*GaP.E^+~dc+L ܽp5^Y Ȱ_'O&[6#9:캆ըWSQ:}0Loҥخ1.~ye/zEDp^q!giy"rھȱ5l)iXaN=U<5/s=H#Ao8q?E*Z 94s"s\)j꟧ 8y)G p /wFZnr).wocݨ90!us2lȅ%Z\ }’7cN}ƫZ|GU-oK>7ga7+IOZ1jE3Ԋ?bNzufClbեМb]"s\@z>jot{hr{A39]Gf +gtS4 P\F.|ncܩ4ӑvG $tCѻ2bh;z`:rY006lhَ~K,"+Y\qeo$3W~_{V<~Qi1sɥLmۀ|Lfx+N;T.ks?]c6~;ir_2܍lz Et/ cEO˴ KQ'v6rb"}N IU ݅E <=6-ό hf]o4lkU) qx <Jg?;je=@T|ޣS=|s55ͱ/|e@q,Rs[\{Au.CkہL @g&7+sZ[1jlD=@_H8E4؝A,*0pJtkˡ/x^ H/\ ߀LiM.gHSs@T9u<@d m\%iKZx9a=ubέ,GG."?_ۺ[6[)z^iۋ/\|ThKrn N<"tyDn<ȺO'7noj8O?sASaQ xi2؎Ǫ|~oe >/ܯ؉:3+m0V[>`~x%9NҗvѡץuwJV䔼[si֨R6=AHf6v.G]{̑:T 3w Xs zV>LZP@.~xcрZEEZ߬_L_QG}y~BӬ;aԥ:V8P"O~'\:uvB*m0ΓNsI#|SACQ˕ R.$nЫ=t9B I z%ˆ2C'7?PKvmEYkr''>i g>躪#WuS<|㩏:]FW +Js,E3sqzmPR rKg.*1`ޡ3to2kػ=@>!q!b sC1W?!-!)'3̡.b^ޯՏylʚ1g%4s`7W_2u˗`NMҬI0%안Ցxw]Y3 =Ps%i1/2|D3|X)s[W>xyid",{ڊ7@H'DK#hs}2L_ ̱1Ar2t ؏AYx=핛5#|ԣݙfqbh?i4 #Kq~HKhǠYSZb4Oeо4Wx4Vd"$֨s2oŕc>I{쒌=X y>x+DĈOKc 39%&Plbc}@^ņܑ* iID}p|I IuM~r^rSJ@K,Jƾ4=ptbchVbk 9[l@v= ԹDhf^l8ϣPy,pwǶ+uD@K_̡*Z+Vn&g `ӜP^s -P4=?5-fmuaQOCago޵@^g=.f En^ oMɲis4@Ff0odMa䮾Q@q_xq(Շw4˧U&$1L3üJwV!z^lQ949a=/Ѫ%n?|ݞߥny +.F^&"gWĤ]:0lQBC9?*Y&oP\y8o=BNز0NW|?޶3[/lB Z֨Jw`} 4t*6kR?̏ο_Y^9}Ig]j;>\!ӱFZǻ< yInc,ͺwKϿ6flQ/8׋0/N&n#P'#cNѬB{<3[}*oB7C&@ZÊ[ufӹh֗ȕm%{/=*\i^\9OXrqS~De—O}ŠNۅ\{?[<@2=*|xtq{\_)OPmoſkO,P)PF\ܷjnّs OiN9>^16'S}lfPs_dvˡ_|  U LVZFC3g~} U`X3ĥfqX7pȹJT,iQlﯸ $..a;]~'ar! TP35waa$u-Mƥ~$Q. 'ޅ&}w;d̵3P.Jgμ\ ˰#|'m:y$W6BJWtVDݷWMu^k Al e],tbNA= :v&z2UqM#\D2וfn }A>1s@^tZk*2D7Kve/SF'0yLgn)=s@Y~s,yXQNAE;r|M>v ߱nA>w{|k"[ 痱"] f:?|wf~/+fyL-`F [f++yp?\!4fYE4cx0 Q}})Spf/G'˧ǧ37Wy\Œ\eZ,si_'rhm8'5cFع.g W[m3_Z8bwKJvuhE6Z4rL-6gg1O +[ާe]az& 9R+݇~ho*0޹v`V1C_{-9<ӄ }unix{n⃛X9,>Xǿ`<,m$^ 4BusJ1Cq`諙IG_0fh\@Yt%PC{5:"_`mA?]?nJRb%|qw@:#Lcuvvu@V&;?AZ@>|4wz:~}c'O.m3,DfM^[!$-i_/c?㗾A}|}Î-jO ރ@|}GBXBFǁ0W>$?rh&RkPZ/Do<߶az_Ɵܾtsꑑ+@ zJ3gEn $q)8n,TOձO۰jɃ@,͎ƣlCq{ q”RQG5\@"JXGx>_ouEng Ysb,P+ϞP~ig^;O}kᮏ R*UO(5b?[(IEV 7k&;G/$NvTHkH0ӞYGSIxT2g? QA^H6Tn~HQoz.O MվAx)[zs/}مs\-XffDuKkXC3Ƹc^~݄Crtq-蛬sghVg4r}0bL'?^ >HE'{v750S⵲@ )Fn߼>ފP6 .v@.^͐ <;evD9!orޙi |GonE7 CJDMq[?g𧈊wmjWcG8~XM3mJBu>U XKkK|Y3+dY!DEb-08,ۿh?!OhV]_P7TѠ?hSMJ7P~eo) wPy|d/wM9P+{-G]#suGͺ㑖̃,a 3yE NI5 yzRg!G>61Zכ(䕫7G=P{S ͊ΟƎFuo'>㊃ұ6oŹ4*6.* QJu}:V=~̟}9|,VsBNO ە?ap 'ש&,b.?tb S)y\dv ] G}5~ȇ߁?C3~g0ݷœ6rƴ@1(9[y O*yx#F 5azqh 摐([`|Zw0Euqum \hȩ@%S{ɻcG#>v\ wǐ(<64o ,Ô,blk󈬦Ylqn袕M#@(ڽ  ߃>(hLfp'A.i4@Yg#_|4CO\P;Oʹra콳Ų:g䠔QOv?X#+@JokmO٥#d@ ~ WĬ{?fٱ7Q/Õ[WC"Nj* ]9<Wv? Tݻ?@U|J]e2Ovw֡Y[?amqNdE\oZx^}.̽Yu[X$ R~˫p1\f_OXq;=D!fWm4IqNW{k^?_:d}gS,Cy̨8,i\U~?[ 򤀒|5kc$()U_@gqx8FE?=GXuSPUoNJlifJ.q|6[v+QYsLV0~0sy"QXs @LS߆x^tu"{'P~rjhɿOl}rPwv^'a y--ӭdbttZꭉ:LZr4f%x}iw]7N,}.i@=אM=~BZb$~J]:%W?ylcj]~ ddg4\l6Q+"0,{Ejy@ V=sHXU{v9PO45Gun;W$P妳Vk{ΔuB?*gϝ"^lwso^d%3ٕakqiŨw~]`_XM6 N7he!拟B;OǼyܷ[uuOРG@u$YY3Fxq;{Ŭ2U\0dC(yzZ*6bg'FhHf^!ߙ5)˘1 ysImW ԋ:VI}/ /?s%P"{ӊd`ݨhۣ7b~8IHݾ &UpETz|QR zИ P'ΗNbJzfcO# |"f} WgqF]#;/e ERn(0nF4;5أkSɹ8gF8( ȒLb "w/ݵwI+ބ5n\(wPU4^@8)ѷdqFmx8rs3Q_*\߄:)!L1ujHGS>O#j"i6]x~EM9#ZXQ/6WhV@򾠅9P'g4D@C)QBQ/b)i B|ln39YEhU期OيhzS<7dFJG΍ҍ\ğ)1n+I{,G Cd ZR^|MeD} K^n8K\Eiԁ|O9֝:{cP1} ?~txQЬKүf8G٩7`gkz.fybB :N1Ym0OYHhm3#?>TWfmv|끼Ǟo-.gUfߟF=7ZMY눠vvF{j5/& 5@)t?ṀB^JG,KOw6烹k;;w. }eX_T KiVupu;ssh(P.iu., ( >3FhߏyY'kҵ֖&~٪ leNi/ 㾮f,@b(ۣ;PE?cW%0Yr?;,^>g^Fs9@5pf''2] Qh3LZQ^P.U,*Shֶ" ̳bϽ|h [z(f=?U/e7AƛR'{~ QVG9yҲ5?j2G/ywEbs[Ύ>h$͚( Tpwؓubbةp~,'"e(6ѬZw 6tѺ2;Mqv !J' 0KgF }/nssv8?A#6&Ri *sv±os#ΊA{d9۞a ,Ѣ-eYy4i~sľloLQ?z9}Q =qnވ\|B+rG(rڎ6軇U6wU,! VfN d9*ZI)Jۡ\ju='ԟE#=+cP(, EuEȖi1BYđߦM4⃷rNV?&\Y]w)G-<)ّA WΉsԵKb/Vg}[rb>`:ֺk>F̿ߛ-\?m5rYT;@DaE+Wdu7 ~C'r o0?^(z #Ǣ(vas@Γ "1z#GZ~X;fib4~Y L3PWE5|k6%rUpO[n]#0dvf,R~ mNKξFt_%P|1+$<\zfjiv8r꣠x؆%@ڧ'yׅf}i}DK.9}}o*5֒fhDW%ar7ԃo2l,xg8À3,xg,prWc{{V*ImuŝewO Ʒ=Ug9w1PyWTg`>x5S\@_G׈D|%pCSkOqA?Pj34Y/ HM C뜍>ue^4;,֔$UU]cnm_w}Ws:TR9|PdW@,.8?@5S4 }k*Wr F}QU%9O/b}tH뼅U|&0s޽Dwx99]cHSg,2?V(Eի05g>ؾKkDu:^IْWWo+]p^/_.W075nG`xf ;@e'`}erC<|[qι@~-c"Wؐ2sߗf;Yus&Uoy话Z q.9>S[l4r۫{@zCj yB(oi>ԥpn>"ŧ XTWjp ofB1aJl-5Kg[n9%GVd|>ߍi֤CMA9PbWފ|TG,`m ++^YP>-4sϝn [T.ߔGLK㿀pV?漁䕿&S81H@5G.k >1E;~24פ@6=^x=Dh3̻yOt^xQJKwô1fó 牅G}tYA.|."y_G&h ?^ղwN[q_ӆl@T vC=(Muz^)uOy`M :DY6#t[0' +ODL ߗab쎶Z'1}C gK[NmB|3Cr`@,P՝OHls%-܍JH29G:>vONgի1xAG.:ߋ{BеׁgB?&<>?MmwC=HgbNҍRbRͺN M )!= QΧۛ tbgu}i WL&'3=I~ );˶ xD1~(O2%1^ga.ܷEE>8? Ve(zG(q>Y͉ȍ@BՂtT u-?fuk o^^/5%??U[~mPu]D_0>ܡ fqf3 %cj[0u]ľb>4l:w}܇S5SV&htCoV+Vm"xʬO{^Ь0I~ܷh֯yC1F_v6s߲͛|]aXϣhnj|y݀/կa=J+sJOs7o<0\'m93P=7sKy@ ;rqo9@R7Ӏ+(}C7y_x ˛nm_]d[v d sKQiwfUy|~ۛ> ĩ,ίnN35d[U>AϏ7;׶=))V?SIb ~ &oj0Gϙ=,BL+@_v7A7~|+D'tK`} kJ_oᓾ÷sGM *l"Y- JZ##-ϐ;V1@$+abd"Zyl]M)z~IWvK8 B?c5~daw!UɊ)o?55W+CTg8H/-{pYs@.?NrҀ (xꮅzW}*w0o|=_;p9l _Vg9z>UlMWuP~-p%u!PD7}2@Z~P#Qe WnY7<- K;'|]i}I͋?7"ukWܧF(i->w#o.qXxͥK`z޻^ظdnY{9;"~_bOtF;ߥS&KbS^cC@DrO᜝7kg#bQ @F59(i p%qЬ=]@֭߰e&{K~{=u$+E`u6'W|YAM@v\t=&7*ِD3C0i湝NҊGOyPCom0P'̸wVbߜ @&<(hCI+Bfz6+-gS`Rȷo&%\xj`'j;rŜ}W 9cU4ۧ#z0_-pVƜPz=;y?fu#cR0Snlf́_ҕ@>4+`ɰfL>H[kq [! w҂LYn9oT!5۾ڿߟF?/2ovu]/40bu,=_Qr?RT݊Ʒ *6ݡSR{f 7dVU $y#zIoxW[  tȘuQӗqV/whEj9,^#]ldF3.}9 ԗ5Ń/M3ג[nw z6OpӌM˺7\=_:~hHjP>KcifuolSg ׫W*XF['c ]OjE>8hy6.kZAcU]z4V")R^>ktSC|ʨK[fyإ6oBo޻0_7Z}cw)󕦑h&;ܷsI H@r|Jlbf1o~)o?F]y)|fM|_0Rԟ$h̕_O,s3@ Hwu.J@5ۋTDy_C&Tk5J/mZ{㬯-*R9F_l!r܍- #Cu#Oy''ۭOeR;r镲}s:/Յ)m"QWZ?ڃsOȥ/{(G.^UK;'@&mSzXw}PMĢUW*wTQ4E8@ LrϹ偨Ksf ~T2Yw}Pؙo/k&:}1?VVe9su%mz`j K[,-b:QK΢ 'D>jLV,\:H?IG@ pȀyq~4JA.hiV{zϝ=afC9VX nq3-hm4F9 7$ 9"qzVYQQ_hVfo+NKs/HymsNoƵ43zIFcvqC䛫GVl9I3sN !wH nz 8|AvvHS3A?/f`jbz93/E{w^81j=v&WE/Je3b'P;I\.촼1F͒51hŻa~?Gn_xرUV/S~QN;hVY5؇e) oK !ŜfifѬc!w[;!E:|r%4XIកux?PEկjghu7§r5̲I!4)zeʼnϸQw zM]UM2Py~^+t{jh֗f@<i~^ }DWmwU ߞVI'Uϔ?C.^GyH}ى9l y|4`gJ~eIh@CƯ+a&tayDA+]6oOVӁ7P%y\?a: *%͙6 (z3/ldr;;m4Su:T ȏ^+L~>E3,:jC:ŋ~ﯔrvIq{?n:\ߵ}UOt5w*N5`v5K,ǽUp|×SOG}Yu9Ȣvs)4{9C7fᾢ%V1O_޶l0gĥn -+SQ?vEH,cnYùf)7bsBP g`2J5G/dL37rY _c3\iVe uU{I+ΗicI >ߚՁk1{f\LTPA?Eܮr̀sTKn qj@Yug "4mR]7B(ӋV@i^ 'inS,W #)y :_^Aު Wnj7f>8/.W]#ngqz wܓ9C/; 'erپ>zρ^2kVJ,&q7w]+1r˂,PoW+,!V)>'`Vw(ּ71G4f(o@)ɟiɳK1-eM3ͧ$џѬSb5Ohz-A;@i 8aw]'}O* 4K󩔑 {bh @9w|f>& RdYw/jCC N)n;[LhVʻ rowTiw|:lR]17b|PR/JRvbU mu4LUOu몗43;xaT1o["®C?9jy9˳_G?C7if}z}+*J />ݑ'T>?[[fj1l?>Ŝ@~:x}U>[S|喳hrL :n + Ѭ} L<Siˡ[,*v=䚲v-|18 s~œYgkoUr'L]hV3_3Y) ŋ#XgѬG< Ob@꿃_N*0N3뛾2ksqVB[uco|&R`nIDm9>lYKs미jz4c6RhNGm}'˗>5&>".ț?F !(BZC;<ʩ*]֙@-!4}HyŹ!so0Dn'1{9wo}!ȭ)lYer03MxHb? Y]B0RssPWO(lG} 5~1y_2$?O°r{"/߭=ߎP5$ IR7B?O8=srr@|<@:F䣴& @,73$o/J0G~5a%&ehf/(ܸ璋7FEJst,bT kLzvYiVCkNحra?2-U ͦHUlS,H.OY oշ?z;2ؖF3ô3,0>Z"c/f F1f@P,cW6p(og,Rw9ZnfQʳD;MCo6]iy6&G洳8W=K%;~92uuͱ@p>ERa ?ŘՈ+ZEa=VאAdscl?OѬל0Oq9f]_=]G^@DXJXc%% vc$ou:ڮ;BZ$wbܙf8f O 'X3Oa>Qr"|yԳޭ4=ۓJ3;ԩxfXk-$v-/h>#~QϿC~n#˟cӺ4)!wzD́fYw_FS԰;iv.}EM\eUXzw# <M P?HLYV?e=wkk&jbU5%OnE?wJ{Bfr,bτ'޹a YBݍ: \$!q s!5zS^7å`r͕9{UL7E3#׻!8+>oSy%T)f|;U0/q >dNuK#IOpnZNq}#; rsN=:@)KF@Nl3 9ΤzITVYԛ"\ǵtkwF`lkK, }d,|WGf4sӎ}\p|Z`EnE=(:1rA-U\diփ-~+[| o>in`0g}έE}~`(M*g N_I؃(_F|$&>nV8)HvQeX|?}\?&uJXHftӬ7n 6i~[3./HI~H8lj-mX}dqG!DKW!ŏhpy=_|{tt3l/Ψ s=CF^wo5 yزP>ɵ.LV6;;[zWv_ }IwY]t%,6f~2-]_7 ԚgC Kb50'sgR|jm4s[g$JIzn&|%F??C87~<+*;#]@|w~ؾEJM̩&Kq7|^fKMr`%&2+jJsyhk |qlʛ_=)> DͪOk;8VF~rtGz9Ք{SF7*6g.dD Ֆ6_<ؠNyk(jI9@4H`֍~ m9 c;u3YclV P}|f]p8ݣxq(p|{~h PU׶}l@x cGsM}Q}83=eDf~Ծ.fڀ\sfUV ft3`o*n7"־v|TW_W7FrZЬ8c87TRf(C}P=琒f .٧rrruIZ)@zni#v<}%>bU9usvBsuӚ5.jtYz[{܎ŃƜry DsPщ09Qu +Gi比' l~{hfI!_EW$aNGtΙɃki濬T<\_#bRO4B侫;˜|?07MLն5ǛQG=zU =Oe e14 C{ł+759GT!r?]Avv79izz:=pꁚ;y=F,1_\ z;Xwicb5P+g_~5/~+E^ Οֻ"ӨCg)KU{nXjw$}zs_]Eؾ*s5E eOoggưa5#-d,o:^a kY;0Tw.GS ܜU%f2{hb]47MUH9}3Si Rgj*򰉼9rVc$ɋci: 䚝okTJQc.#Lm:z#3ӽ@=Ju;n`ݓB#j|PW68]]<*{inmkc?"4sKiۊH& miz9{KZlW V=%~XOp~CϏ.*Kz8ȆƋs~*ϼ+{\+39!o዗B{,6oNe-uhv/{ԷN@eiL6C;͑bc>9ީߋ:jx8EGΜPYmVx~|nkٵ_I)iYL@tgfh}K |-Oir=VoobԟLBAoMkwUXKǍT#Pr&"+љw1q [F)6dɣp1ud3nn mZк$͒(W2?4y 瓳imp}%fWIc@K "zSUp}>s E>{ԇ:9qX VxKs6Ǒ;mkp~O7œ,?C*>W9O,|q)˰|cǑGevݨ]omLy<. _yY#'JȞ@TȮPފutGŌ%Q@ZYNw}쥤0sߟ٨{.Ьʼ$ ` Dh[_M e3^ȹa8/=墮oz$kk׏J/Z>ެ Y?1f 6?zˀ̈́kռtVR@+n{&0hFW9Jߋ$EMnŹw ϙ P6.k`>=sş7qCk<7FΘ\#2 b<첼 91bCy`<2l3 lb]^*#C`s-tEK]Y{vd3pl^% ,#M>ƾz){\?J;t2}©[P^濳Cڬ!rCb@ ŀW"ϚRMF[/,` @\-g +K` ԭfN"D=4FZ L:ԯj1@mKa]OPe(PS,^zRXr-@8P]{C؀tQ:pu^-#3m]nU7^ojxsGMOƢ />FMPnҙƧ; ,~ΒO*wu.qY s*^$ל4T7ӂ+@^货9Ek!nNʠSG ,rkTMz.C՛(BMu؀뱡P_\*=pvR1(׃JK2/cnf~bm>]IGvV5 Ftk=LQÁ  F2 i g5{VfqU@UZxְe 苏  Fly+y feZ`s&2Ԍt2On hoOE8W^N2O1ć2/6ݟK_F~ԋG!wx tch2~vZ69d Pn TB @ʶщ&ZBjDʴ~]=}RZLtsxJ4ǭk{LfPl1|ېj :\ Lp7(B}!{M)o[Q9ܵK-Bs@Ud^D_iOA=V#fl)n6/NrܗFG]bT|y mǾuvGL`T޾DkUѼ܂% \mC~-'7&Qoz\s9^c}6-\Py#O'ej0_]_^l_6˟pß _>~,0B6 )d@oMLTip:-)ggq|qǬjEk WBGP:z"m6e"e|hDus] aT"_\m*L _$` RU4+~ RI8/cgRS;Q.jw)'S#0\dXuxrOJ0P6݋Kt zfG큒u7X.(%+?}ٲlC;ƶ|L+c%x'eAk3@=sEs[ikȑ.iCNVzAm*& g6+˚]cU#su<.gP)~s IK0_x/B*}lMc,|'/ +~kxυ98"Pӛ">lY [#S7G|zOE8iVʆ+!/M5s]Q˂E?G~a]Z]uvmD=?Ӻ1t02@>-U!`U}.IW[Dܹbl74v304 &p"RI$ .\[|v{5L~^Fwq㚆ixD+*?9< >qzwuD8݁jU`85ll}v|.L-LfL ǚ&C:v]x)xLW8coҒ6-2>Y]mL2"0רI}0R.za)e7Q?\9<ͺu6@=<'z;9'X{Gx/Clokk@rq4 +My RCU+b]sC]ɨKP5f󭷏vOT70Ž49ܨf r^ 95g/+7NxPIL+IJb8q` 5>DkG(:׿Qꥂ'Pot\oTa|]0Lɿ2MyW:u-iqQ;07 zDD# _q>,m]~RGt) 'Sp?'mm0',6ڬF|aTy^Jkg4~qSuGq.oNuj6VSdI.ڂhu@}MF>T:F^|7Āe\t3ަu=:}q+.a~HgE`} {Loq=ϛp9賑OWk_H:Z ;Ob^\oi彮d4\bH+r&54eJ|՜b@$}ԟľz]{#n ڊMvWZzn8ֽ9gtՔWH9bCMˑO<^/<{Lsf.T{+ͺcS-Ss%&yyoHx`?4غy3g5 cGέ9.T ow/ Ql|XBtyo&mYoҺ?zwm>49(՜og1Oݴ܊yNi8ͬy=7Pn6U RS*J-9c]pH/^VIx $[ybg9KfX=K+>cKƆ=!8%äi0W!]X9- }x އ[.|.ӕ&@R9<#>u #]Zw%09I`pzt5z]`Ӝ2qE_5p}d6 =Y IqMbfm, ~ϤH >:bSbnl߷+%5Zʹ{zgƖ9/Fs+'梍woĜՑB;6|9_3ڕfXPsUsmfRXe]s u788/מw8Q]G[r>w_4ȃ?yq晓 "U`^&0IӍZtt$Ͳyu#9J|s2m6<[e--XmQW`߾xs o:3KѳoE]Ͽ^1=͢Y_>ZN V/?z S'GJ>#i!n)qڌ("{-ܧ㉤;Vja>A]0 3Qe}r= PU`tuCB55jA G= ֞$(Wf?Zyp1[8gdP}(3~[؁m:b 扽 '#8p?Qowej―N_us!Ow%<(;u(?!k-U/ۈ}gUCQbx.Ƃ=☯^O9$Dٶ ,d ,RXxsa"Wp9r ӿp'wx|&?N`Ə9i俏:-݊ETܣgSc!PR+xN#37i-z#k\e>bPf O!́]GN\32 P{%ub{RXޓQ`QR؊h2nS ltG;٬@jm20A ky{|Is}[=}ed217"yP/g^e9{/yk+oM;q~C-¾ y 3v@dE~sC,U'S}z6o*M_sֻ^|;:^Tk rM89F揁wv4I. 6[j/fV =u}GB'f2q2iv?`߯!u }oCYs ol{M=1>(r"_0}|?ßsr]WuN@l-.a/T\ڃt|0ES_lEQ'Ss"qqN}~JPjo,݋M*G6wiܧ㪯w{-n%|2@"~%vkl8Vވi0ll%ԱujЯs㰲C=90D%t*D~Z<0.@<:YL}/l6#ɧX$65Zxf6{79pN-O>\xt`[D_]B}]?@Fض|z›PJjcvwPiit>430Pjya\!VVc},\v_CrOR+q.βx\)oּBAC >.ToI H]>lo}KP߄R[2^`p>S Ɓ ׽+8O/7T:lϻ>wGtȃt j%oA}x_2utzwE"{%_"1x2fA}*z/<LR,Rb`H{X.d: _piBNO+O5.OմA,y50|5oy Aи"y=PcxLؽnǹz1q}^ާkiz— 8w{ DPPԠ`_+{saHܷR4r_k$O]` jۖRq/}@d]DwX`QɎ<+'/wKS ci_*blΏy u رf~lxP~H#mye~PTQ9rٳ-"\qo(K id-&*&&" 5y+|B`nhE_9xY̏|U L}|\āѧ'l[} ~|餙ﳄܮC8 .qD}˲ԝʊdw W[gUi}),]ߠZfuc{nY|5-(ICқ<鄍BM18gBke]\蓨 e.aBY/auJwHC+}vu#\ cz=sr +aq|)RHgG%L~D>M7?%\8 oQ5T@?k?wV;]FNo-:C}K! sTt'_< ě# VrT yH#‰` 5>:9/' cڔF]=1!1rW#D9cn%4edf,z s?G`Y,]2sXS'c\J2C}J׉}~]~s!?yj+f$7ӬMB׹^+/^@j0l<%IͲHٰO>Xq }CJ)x~>wX gTU,H& ?rGNب/g{_zfsYקn}ܹ{P)\ O9{ocj|w *fJt;mt͇@+GWQ,N^硾m sY{.s3=[^YVRcݫP6nA@XkI,iaO?6 GQo ](ve{Bqjq}e, /0I<\hg? "}~P6Iy kT:s:[!Ziq6ՅXvjEJ`<ߕoʠc=G`7aK*om@oz+[k-w*muk,8r?0ChiZQ7w)D6-S#4y2t@N s?RckM~q?Ha pU缷cJU5턿QϕٟaG3?MZ&_y9SYGqF_vyWKFx!}̊G:nX`} hs^n { u=+1IrP}LKs:iOE07c@rT9eXw%+˜ ',A.@}h}מDYe_]0$@fL-v9=ߤdM 2 n*,bi->I;.z;&prS s.Vkh%e[닫76AhHƠgg7!w;Y.6v]ϭG~fuJ?M!.K/y><]fs#r%I| DtRW[njpыc y\9jg!lqfyҭ1oHmlƼ)_|q>r;S_՞h-FZ@T:X8z>'-@:LnmDO^=OlLJ`EaC~o1~u4O>UEൖ*x }Ow<Ejkk+ÓM ڹĩ/՟d21}vp曌>ޯ0qskcMb\7(P `B~lH)1H#ض; %|WA|CO_~y5YlZw<8fsҽ/13vKWt[Qjo]ua`"uC##KV0KpG|쬚,kUComHk- nDl S.؟&d`"764d¾7*3Qܝu'76n\t"vpxJq|p&č/>gnxEF%ڿE_|r_ﴐ|XײPkj%Y96%|wHCIɮDst^4b_oBsC{֓rbH5I? N㐿I0/g[>bSXkMcpeFϛO?>ǩ}D`hYw&f輩ksg6m.` 6>sZ߳I}0=E_uI!?C[Kbx=tZDί2QNOhEX+/noX{++f/z}:U7]# u#~R}oD,`ʧh2ʶhXZ1+ؾ6[~>b6|Xo <\ 8׾-)='Wo@emt0w?d%UK1#ߕ]pxDkz~D~ kѲ(B BƫR[bXLsG+Gi "WUK&fhr _KHg+j_8/zN}Dh.L:KVPd{ 󻦌U8)żmr:+mxDSɵlk6 >?CQp`w:'9ۉ]ѥ:IoeMpx#@?WlFo@%A 1ov#z,}dqN櫬¤ ×?W{՛%*o {YZ.\u_$ }Mg:hGȨTc}qpky*Y+~%K@[v6H܏o>Ay M&@Cy+ҵ.a`.uӉSɳXrTX0¸T<t +tNL[?ZVgnK[#ݕ[ logLS&٠zK02%5 +Y=AmoW kcKkҒ[*d4ivtm r]G^ /kf{mk:˖ߘ]^p?yW` X9IHu.N܊rL8 0^6O_fJwPVyypSSI߱Tnׇ~ _W?Ul:Y#q ?Tn]Oe6s 5[qILN;5vEoJ|.or6kCem0n*Dz$D" Ԥ%Z%u<:G PPo]~1x1yE# ;^ܥ GX:sh~t ]wX>!StKBWեȧezCG}R9{޵)saDXkADZsh>??1[GW^A١x0b8np[ϣtG68| 7p1*~dt4$ =ļ-uCe w2G~0_ԶKNdy|`F/FܚU 㢱Ҫz)aZ62gQ{oOak%0L'>m 9euN&$ґI.Gby<ݑ3]GvmtwOosאOf^cZ?Wy !җlWG9E](vYQ 0E8c>X)?bhQc픖cb'qJv6"`d(g\2BGoFX[.jGк|g7/^vq,6/.,idN//'#mϞﴯYpqoMBYh*,~9)U]ZoOXpY#AQ1Jj6q5 Ѿ=j =޷bB=GENp|;Q_C Fқxژ+nYխ<7d`45׮p+@p,)\_|^9zkjʞ㛟TG'[qx/o'aciٙh=v} 'W"[s*"QJ:eZu0Z5nB񃑓g$ 1r:PQHލTSRի UΚ+RdwM9U/$QOG=ߧc?ʗ2E[,]_؞xfR`:O. k6> M@4!Lgnw_ ]["Q\ `Y8ޏzHI|`JGQڨG6\xwaW8~2d_ ` ns609o8#絛Q(`)D5nkM~C'75ʶ#%3z}w}`}Lt͋sD>>5\`Kx&+VadA<\]hX5H{ֺPcql)B οb`\0.j7`n:|@x )Wӷ B`aesj"ZxpT7F<>BC1`F9i'pLY9,c:|cC>gq/;^\xՀ89zSs⣳ʾUn ů-힀9s[Wc+zr&©hФB}kO9֚ECH{#ʿguw'#l=nXQS0WD>NeZ[bBzG~dx~=~z0s_]'+{ҏ嚨MW !޺`[/ftQD3PT!<CVn-Ko6>Me;шaX(Z$.tV qʋV#T7Ϛ<@S*đVF9`զDruMދwU5kȑ[ N7Wݿf{߻Yf;BIn@t$)q1uyātb.xoophwj3q{Ѽ/Y=`, aG i?=ܵ,,7ǀ:2=>B}= czkBp9^v9:f~s)-L+!A(k) U* 2lr"NNyyM)W_7f9j >qN38"BκǦc&> \Qz)OT" 3()BS~i(M~ _eYLrA|`͹.g.M2% `74%R |C=&C/DȩyiQ.LE{|6R nGގ-mj·m^"r|X(rw6Uo?%1la:s:Si?P_Խ'x'9VF'N"P\ƉڥO y9`?SysQ~Kn6㛛ݔ^.*k[K*mч804Ll5ۓV,Բ\@9؊6; Ej tF^UG!$n0BT푌(4ɿp7.s9EC7`TC9/|&SޟlX|.ؙx" ?9#ULKxHΛʇ>(˝+v T@? `$T]AW>kB[vj%.8Ƙh=8]n )Z]V[GQW3AK! -<׶rO\ xHFs+['?EU[`Y:Gx*f |"߹1~_(bա\;t Hc=sLH&/{Ͼb/-eN֠?BKN ~6QwܽM͌*kCZ q6@ٸ ':wN@?e?y?&,b%=u_Vxqa${x,ZO88tVqs/SjΌ?QtU]08]]X/F\* H.pkD 8#ꪨG]k9ya4eph=qPG߻{I_F~frk Mq^.{ m:[Ε<@~<ܣzf;#m€?/Kʀo>ckǀ!2o|z(!1]\%bcn=cxH6O-HΤЁzҲ( _[Qs@<18)HC{?tpWZ9ǝ@اG%w{sG[EShp}\gďgVʶR޵D&k 8Fw:ht{̉8 -]H_{_C=a-;| Qfp?ꉿOVum<˿7.p?&fwZ8\ x;W#N_ 96ȋk=q<o#>3/>9jGڟz ^ ͳ͵-01oXVB%τ׉u`cSV  1Ɯ{rW≈j(Zn*VLmx~2 ߒFw6Y:?DV"߭ݛ! }"v93NI|&#kڿCI+zw\gn$扭+jf@Jz§{ J|6 fT`qYlOXOKP6,Unxwj[O= 14GT 0s@𕹒Up0))e;Q|pw`^J6칶l6RSz_G(>v$<=l4Z [:ʷ,_S{ϲBudM-@"|8򻃖MVx{w80IeT>z@-հ6nf,QԷ=5H𞲸j74W“)t^8 WQy fy_HNbcI_77 uPI=,@sjp]ks#r˞}D>{hrm%Z7?n|vD\7!iȚP~z `9~/u"@-# ]ٌmw` l#/k XC1{#[64i0 1:, =(mU@~vV1c2S^(gf46>au)X-ˑ/kԣZ.AeA.ęޢ\o~p==(~f\@\<ҫIxiӞ:[ F}n3̵I o ÇXu~Q ]z JwIIT5ccN΀y.xatS k㢙E3ej >4'=72^3F~ F y~Wx[C|R9p0EwZA~{?_.-?u/AR%sK14ڵ 7 yژEsSF,v>/Ϝ-pw\n]h4 ;&#KxSwһzd)tpԒP3Ly֋UvBi(Y6 ?tVbjR0_?"/ԏE"6 __U: t~7/4s|Ŭԯ#zhu̧QwGtݱ{QEoreC/58GRkx.G"z{\eb%9 2W%!|B^Y-.ً% 2e~ ֶhtT @zEƝwbLp&rڑ=F5@t-! D$3@V|eāᅇ\?8dhmA~UT{wkwAܷrmӚa!sֆl]f[ (Fp|h]8?+>λx4I;P^`eZ˹eKXbj󬵻hᆨoxgw$B&> UiManԿo+ :IxJ'j#γS9oԃYmb4i3 A%"8x>U9d )(5fq]υ͝OǕ2f_>*GZ{*kxp[\NG'D9tԳC/ 3[r +Zc( Js+$\ݷ7H7Tg|UCg7=`SGE+oRW ya)|kޅx]CO}kmߐ4|g{&uK-n GDh5o?mg9cQSDO#ʀ8ST5ҳ{Qn{|ߩC߀`}c9]YW$oYb;2&b i rDn l,ei*k|G*J^ZZz#pk$Kdj>ֻ[ ZVľyiHqGؤ? qoe>s<6 ҁxP[L14 {GM^?e -IxɣHU/~c ~W#al7˴<W>/?('Z- Axj ߚU2!tωD}ha4k~W =_S<]If ) 6XF Qһ1|VŶ7tʟ>q yz<*wÎKl p#Q,c D8+^2]}Eڈ-z]YO=]EK}: B/@n 9miħvg]uc/`=o;/fJ+cެ=IQu什{(/<xft󛏿F(vIV  ekmE\)Eg XKDYŨHf0ֻ6Je]8ֆO'u_Յv|WKCaBp 6TS |/9W֎amekQ-,-s=a ^-pdwkRrο<#Joc&(eu]dkLS~ w|>m#WWXe{n/ϚEI8ߕ;H[C]3Ni2@tu7 Ӿ8s#/Sq:n_ l?$N62e̤⦺I5llîӓ]6YGRle|(`" g\cW'r7Cٷ9WYgmJyޘ+C 綏J.)D #;ԇ+[CO-ø5}%O C) ̭ A?~n [ X<_C,rtiĚl_C%^ytBϻ YȢ*AF3Qe@8#mnmFj;R`:\gXK*7޲?7`Vn]>SiTc$xˠ3:ϡsh5nC쭈>ӯNi-ՈqRd!ܞ>s]8XUU!̡vv2u&qnE0}U :|87=؝O?yJQ|!?tpԏܑov-;C1#@HzY)FȳD8(qWiLXF0Qf<7Kف~VL hi/wG54)kQb0 dCWz~M_ ֵ9v/'x6S@Pulu %a@#i@0OUD%32/^E8(F6} } { CU8<<Kf [^,Cϋ^QA}7nHP=R}CntEf(E|Mt]t'ɯm%1 pT)%pbUJs X=,ݹDO(Gu|b̈́XNWUx -OMh=n}~;HШ1A В= Nz=oXtcˡ2b~G^pʗ_rr^ 77Ñ\`~#8J{؁P|K,<ŲӿÀ牣m%+(*zy@`ho $++JPcÀbP|M҄(屶d7.(j)[+P,X@ 췌QEme. xU G_ x}?zpT6 RCb"_pggG%ݼp/I];<.1_!?% gݪ}304swau~6jB߾ [bEVR3n.ӿn(g#!]-v( juUeGv%Ʃ&`4e#\!09mف^S0~]T(T.>+b;5 )<65-9 }8p9XPB|-Y\#&ҏIrh6?O%\ @8njW6/\Tr xk TATtӇ?!),"~)77 YCؚ$wkڸ T{jiL S|*<*͙%Y]2#`}u v;>t Yv{4  _ M=.ఞψ28ܷLfMA~&b,׭ʞj"0^G+Wj\16h{oW1B ~k^ ʝp`x+p;Y-.Ne0=[!YW :y]['onwG@{\p,]_#QU XQ(hqOҀF}{ -@&/@:8ep+woU\CsoVWS<ԗas{m:OS^!MXaYnJ/U[Y/! |sv.o%8E"y`™ļ/E;f]\/ )wi>n .JI@S ptWj8בkBhD nڛ÷##$ I/GGrhvB;EޗcpG.ym?7o_!<=/`v[녬| 0znwn-_=w @=UgYJA\^,tI-^5 ʶ3EtVс*1Q㰞{C+곷HA;j.v]C^.v:H>~bȧ+ @0|QhS}$4f-_/ϷPᅔE`P7;n؛ e55esvZ>'φ|guH]&P=[xG|FWJ+8ŇɧNLiR^5_:'+<!ZAs7尘<(.RhZ?l"[_6b3wj PM^br9q ۃ-,~ &<zXC+؇<.m*zv<z-CgKh;p7LuH%R r ܸ%fT6q oڸoT({ EU]@p0FQ̊_z.I!r*p< z!H+nJ΍@::~[iv':P]E;]z_=yΰh8=XN]ذokс%  嵢pa[ 5s[.8ίԴ7շ{P?bj)Tͮ'h![JmqUJ_/Y&mw{2yK9̕ |n]Ss$yFH, ΉP + 6zȗLw`yiuS[7NPW ⏉N9+_9`sķU߀[8 1i) )t͵DH>ΜZUA~`,7Cx ].w+V9H}'_1RnVMA( 0-"/wYP pWl4S;U)h>.l-tzkb\GuW5Ccz&V%'qLJZcG d5b{? H,T:Vז4s|٬]{,cj2 &mfqj0 }= ^c9#KfHG}=9ZzJdzfMr]FU؏ꊪ*ՙ@J(;%gǏcpy!r"n]*'[>0'nT9YhdE^NM= DJ>)" UaP.IN]v{lJR0M|?;P;[Xk6yV4~=FA~pwJegN׀ssߑ|oEwa< ba'K(o09]glZYQrN7s )M4_׬p{*tN~u \aU"{=~H.7'p${ P[zg#9U)x9[pu0dhmГ>"WH0lQ  Rtw_qxCf~-x]RڡI*"+;j*i󏾗@m>r~.x9j=@=frc(/vhؤ(x ]q(uzO<}v hk1z}e9f@XXTO]׸iY=_/GmzSb.Wݭ?4}O=@|hܘޛn{:~yTex9>:hOŗ8wHJ?Badc4\1{mxjSaMyCUfe4ۄj]0=R.|)9cw:*16ՄKmw(ԿD9mxST P?Ga4b5PhFe[}_@k7W|ѓ μOx$?P[e j=\jnԶ^vgVdv<`x_#p=ݢq'.usO`A{6jܧwPE}ܮm1'cG\$|CiMYR+$ӁSE8gP65zd>ʛ3fbѼĸn]u} Y]E1`Q7= xپtTjK%~N=Py nPX%)T5+HJ' h@'vj6Ў4&rۣewu`OoI?3xr2/ }EȁlO_}$=GVϑ-A@& ;rApD'ZJU+'mޛ= r-<9@P4chfSۂ@ =ӵ?k\.K;qݽr4wio22?> tp ݧHޫ6Y4y`,ugjͧ`jX%^OSsȂK7eR-o< #Ͼv-vǫ|2WBWsh6OV>]BkW{ZQ]?wlQZE`l1ߙ-VFy:!r*ж^C}]@?Vgl}{k--i)ʬypE%=myu6;_Ң#9$QQڞ#H)H\vz||XOZͫ L-7<{Ĉ!{V?u4V9qAhˮ<@HKsځ Gב_=-V: +؝7zp1k_q4Sk͏`߀ ʑkƯRq.u`kIiFGy#Y-s@soK 4״dex$cA@u <|*j@2\h~X?p͎LCnM@üfC_atP.{wWHkcNglwp4=l#q6Ӌ7RcO'gY愆pd7v4 8 =`'7k 3@WfdS6F[_^~5> B-yx 6PwRJ $⨣`0>fc DM:}ۻ7ۈu 9j fWfnqgL. .'O.h)+*@L ?s44qǾX pXt,heW\ |%n^X;Q>eC .m bmT)h^&aQ>ug!X /wmdWw uk|̎_e\"B=u l _겼;yBav&Z +g j.sH%iYsO$v[}FM5]y_Ӯ^?)_z}DeGVYYh- K^fd~b>g oe<`gd,~6<61guDt X2D5K>oQ׼`К.y &Oj\oa6gzVR?ͼN_f T ms\F r& Q&T;ޅzSt}}@1 pڮ 5$`_Kط ph~"]!WmLpF^(N;rk>g`KyƇ:@{#hnx=ŋ#zzq/s{E~ nu[v'tPܪrsφH@(юzEP ps͓)m4S/A!SB*Wswt&W*TKBU>g<{gZ?96Ay5Rw@ۿ{M{H㵸 h{c+S?J;%Kv ݳ^`Æ*dTN?*Yf41{y~Plz*'q}{){'ʯ3Gyp.(!6_C1P:hb3*3 s>뙲8NUl;h8voԿT3C"laSWxMtMf>J21`'V`,Py\WFO"j0F<ď|v f&{6ڶ{ce%9 2vGO_ QE*z:{=5+O)*B|cAPxKav>1Y7 Wb!3lԋlyJ-]|g _BpK[IMcVh?:ҿ| d3I4Wh|;@{a>wFS{QxVP l+瀋suxvRP~PVwItO\ Qfv_ǻ=nmo~R㊳7 (>l= LWPޟU4-!|R /y3T0xKE+X>20}v"]$,z큧WnI%(屓 voҡ;>>@Z:Õᆸlx+pϑ*6myr8=!īx~%!Sݵ91;nR) |[%dܷFg [ _Hֽ@XܓFcw#^L;!'@Q'z/W 5 3_?٣&دukxMDQ=}(Q-(e6?a0O Y>oobe~5>1: -QG)aCEC?YߺV ԃȷH2SQed o1T}dntzou_ uAhSѿ: t+/yIkF/$%irJű¥d,Ы;\ G^t%SpC xC)%E㨞48Xi]e{|wSMڻm ٭ņiEz&;o#`9R >V* ҿRrǀGom-̪D`8gY]kʯKx%٬j\+Q<$׀z`Q Ӑ)OQ?4wObDe{:oI&ՈY gZow?&ɇ6-4ƷIA['^@d3Hf4a|,E:[tGi5ah+a^vf$pB 2TZiGW&wk) ݾ[5xc~>Zm@_1|{jUNg;sg(FIK%љ8 Fsۡ0{v<mJ CS;O_V[p=AF0MM;O%{u>*S9+4.w?qqk[*0Fz}BpskoV' >Hx\Uq@)vc'O@fw*E5FyoJ5n; ɖfbݰ~3YqXBsPⰯ `^ϝ:n-dכ퉈Yt7\@6ֿLoYnl Ѐ&:0˥Ls&b;YXPh1W!k ]?swwב7y[n;|Öku@8nz 7)ZP(l2o<@;}оxnG@#Rh O} ax"#{?Ff~e!k\DkrPnIO}FM%7xnT=&×!B =EG7y^."ީ~Cdh=0?߲Cyn&VY{˥nVm@ G>,rp!\Rgq}ݵ5+1nSv|zR]_(cyQIbz9dhi:O ~\ǘu}ѻ+g-ml87o_ |h#U5Bi&pR6eRe_諛qc%O~F~6&v9K)Y@JTɋut+;%nC!#4Pް۟rEEB~#4<[K g`OSmG$.9ޏ~Jܨgf o4*t='/56䓬8xPCϞ&&)=sUs[JNjaEMTNyh*Q]K Vϙh҉6=KMȅv^ \ʉŽOT_ETߎ}NUO;|E?Zqy .VuheWzFwQBgtYe{ <۟4[`={Fxyמ&OYFz|S~@<%X_~v!Pk[kSM7n^l@XיxKzF0tU PH]{H lɠqXn ؚGzEtwSV<=ϛOL=%vM "8Lٛ nG3ׄ{J&A@}MQǹ{t ಲrSxH 䫊 G_ɼs3M;4Wv N8 |ø0 qڔۢ7pLy,-%ڡm@`lMgOZW#aqͺ'2QY{?x(;<9+g)Mf?A+pټ&h9!&ӷ?M~\tNќy*c04؞|VU0oIx- _|ItC_ӧYK 0,!8 2㓶̈́ٴㅨϻS/\^ߑQkYD/3Rn ͫ'e+qU2[_c'ߏ\u3ҕ|]nHJGM >,5Җ@yCS.g p9KUBIy]U?𿯔]7J{P3<:51G/1vOIzPܓYS@].qUZ@[ N/o w?ĝnLD1z@Mč݁5\ ͒Qvq!&Rܞi[Po*v{je_n?HA|#a 8mc 2ǘ(䚟p <]gQ@=ju x?lf_N;7+sJƖ'9Q>B,0*de$J+cÀ}4ǣjp˫ lci@ԲL=')@z≺ŨOk1<oC(ίJLve~0C)}RN(˛KPjZx +<kOIjI%//~L$h.P*80lY+>%07묞#kE_cS;`wW#i:Fu<~Y ߀/f+Wo+l(}|S[0QU%)`K mv/oFcxfFh f1zEc+7j,V߷nz@9kyw=0crV>Zt8?mS5C)^~|] ouD`e& n"9$ Xds>?|92pI?ތѾtREg7ǻ'2B)MYdNܮa5#Do(;ez& p 1]p뇨3I=05fRݐj%i74yB|E9_|MT;瑂s?c#{چW44$?@o8 oxx[.q/OY![hc*eWrj>帺qM@/$w.F2L[/tJDc[3t` ؃f;へx8`O,$_C + 9aQl]RS@M򩄏~9)?'8Ψ":i*wp }cwF#`7fk?ثhڨ'T|Hehڀ\/fJ؜ۀQ<. 0v_5>oℶ' $ϡbp|{O[rWyw5њtB'iOy4bЎ?j!KrW,kp%}jV bp4 l)7|0ˇֽs} ؿ$KqG?.]\5Ï3ߑ p52.\cj'٥AKTx;9R 湛8+2ӀݗxI 0ɛ't;0E~ezt&jTVK $~vlje3kV*W&ܹ ~xp7$ D>a~ pva hnAyGs_gVϪ˩%9Z%;.6>|u2D&顢@P[E ~i_g+ R5`m/GzxQr9pT_)IY8}wGϽsL?/p@"E_z0箽W"~|,;rGK20۳Ty8`β|M r#"-q^p }PD-J#a8bϳVy6qےoKʼnyRGJo(`[F@ 0ʴ}qw[ַwJnukYL:^g*{96[ s2Nο mH]?`Ƿ+@y:<\LOJ4֡3 b#p سS&Khl/{)#7wkIgfp"<&z2dꬪ-`$D{\wNq}ݔ6pS`){wsU^4웻Kջ'0 ߮. _&K> 8kR?_K&fS+%<2nd4?tT! ̓gmy?pH.ȿ#p¯p B-|tp;ϑ=OI./zcϷ9Q L]+\J|^203h޴i7lܷ9m}h}.dR'^9HY1;H[ ǽ.G^O"]ĝd!?Ӄ3>$@~R=>æ~Ho lw+c]; F}E~ZXRuKnJ+=8?<+Cw6d/F"u'Eq:0`/lLSbF?`ͶdޥsHlTy?|p{N{#ׁlĆDI@|`ڥ^%w#sN~S7a-u/պWiͱHJ j\vp žs ?Azb/W i LEӧL]<`޿!OzUjq`t-{Wmkgu 6^ᯧ{-;Ev[?68,Ҧ" ߚє8tA` t\E6}t0mr V/m<3qN3Q]md]xwBg(y7@x|`q]kxq7b9w0-< RLVr'y&nT~ccΑ5 _٪$uڦGzg%j(Z\H(\veW Kߗ;$ڄuF~C2@LtFue+3۲|0QNFcsyqa=1V.Q.8T}lá֗=DJ+0Aɏ(yTܚfh4 DbHo7*Z`Zﶺ/?L{)8о<>#F'rQx"ĭ@? ia~ZkX}^pM9LtB*\ [ aA>ϋnb0. Ys> $nM |h & dPS='kcfqξOdKxA _^ȕKioѿe|?\_N#RnZ*O/Gnt<X cHwVP~x: θ [h3qhf='S q7X(7}cWܳ#.KֿDp(qYYg9viȷwsFq@ػ-9/#>Ɍ|Vrd Ew>]Ou48k@tbp[VMUFXQ[x(ϣSi;}e3`mOD|:p3`nVPnDnY>k-ǜwffS)-p.yak`DJTFt&[%'gVl ?y[ R:!g6w*X *o>h_#K/#~墆QC|oD>VѲqu.XU]p^] Zhvv_ >z'e=`[Bou4gHBo~"r0 o'5#2ٳog6;Z?эK\ >G+`_xV D)V>֯};ߖ~mMn4\0B1Է*S&ZPo)HX QYkf<ғH? ?V3[KpS)/`mp@R&A9a[L!EXC/[*oFoh4>?grVq{tr#d w7&(dc8u^nҮ 7]<l'Gx6,ώNy}bg<`rHobm_]}k`.:#މyL XW`F{ vꉲ,{JQ s6dmH : l_XaD-{ Ľ=(WrH ?GFk]۴{_Hڿٸ#5ǩZoZk+L@L?>jQxrssݻkhtsR.=@y'b8 j}ҫ1ԻRH;toJk#Ŝ XȎ?73ێ/?nSO Fyԏq ?s_ֲO6Pm =\ʱL*{IK!O !/^Fts +Oֵy(MKW@ϣb?#&/#zΓWxq 몽|R?َF)KkamNg 7h }/ZB'6[!8{OfNi({h=,O7+VgWi]s6kߺ-:"㨟=W~)q"E3O zK5_A>sl0_}P BђMA9[tV8"c"8 ^Dpߑ]@v܆|D"Y Vc4⸴?Dp`4Ӻz s5ZG`}ֱ@*I4 D)vF{xwK=-O[f'/8^cG: t& #m(oRD}/jZȣfnU'Dk]l,ѱ&U.~V{F|75o֒@y6tqLN M#ΤJe鐣q*34ֹgͻdݮFvǯ}_S "uV+vQkC*>:wֿ͏V:f I^-o.[m/<Dؿaۍ7SKtqR u^9jŮvO1!ե]_dm(knGMKS;1_8]H.lV k/o66#>Z{w6P5Zx^"3Yyڋ݉C"ŌqŠ`-$gmp;dr۰(_|To_on `Wx́7hUOOq<Ld IH2Ғ QBBHR!TB^my99|{\q .+z}݂eNbXg#'#BSHr~ ҨmT%e 7ZzMm~~>` ɱH" ~iu?Y0j^i"{S!#uƨU@F^`{$C8˵M{.pk[DyY٦ }5\`/A :;́ZWnyu9 3CXjK/JqAܗMߗ^ jsԇcoԃL78syۃ\ 3\<=?dSnTSyBFS?WRx j~0䒁Ю3bgzh!p=VI^ ]j\C,TPMH_!'9daAș [Qyae\sނ{a`j2ߞ:P9nZ`h'rё?qOcT  go\A q1CrW=fl@u;qYjᲚcf] @8ہ @]D])f} *ZY /]$)4/O[@A },n`9wsIɳ,TQM\  h<~': !vU@9{s/9À0-=R4Q-zX6x4k,uȡ9|]B<8djޕ ,㵏*a%Qyg^zQ& hQ-&U6o݁ef$KwioP3uɋfPYz&]4߬ α:ogIU*|9o9ܫo8_ <@ j/tCNpL_+wc̀7үTyL8t=}od$. ]8r2c8fN[ Pԓ\ww>s=炢x#|* qz Tsz}f@o5 cIъ_o*g p6l< [rgK?;4L/>&+2`6TZ왇> -A[8%e<) yG~ざFk;^q yc Wk DGnxƞZ7RC>+csx9o4n4F@d渥4؞翹 D~mSV[Ho` vU'ۓi&p܇R"Df઒)8 ?'|_?ywTv5`ג<]t~]6phz B$܃Ӂ  |8K۶TᏏzۗzRŠv} Bcu~>gQx2ߢ- ~v_3ٖԛ"WORoeGܷ{Azh۩VPY5swTs}ͼ\U˙ 6R8 Hu4lup%I$f:jW @Z^|?'VM/-g5\$}EEwɨdc-H-1{ |[?[^:~OxӷϪ@j+YY࿡ߞm<!YRjMgmmcaJ_v뜊|w ḰD,WvͶn֒]πSVri$p֚Șg>? VYIB?td+BQw _0͹R!LgS~D.lwUB)pu*s{N<xm^0!:3Ro8̷!^ϭřmӱ,}Itqs?/_~Qͬu VڎO{{-ĭW+~'I B=);) r9UqI< G?M'E@PAEYA >h ~5{ܮv $9kku&>Ú!6F GV^%`)8' y-pQr ŁM£]4oX;7rxluwϑ]n˿?P?cn{9#d`V5ޢ l?ADoN[ "KǪӃaȲB<ź*4[|F}|#ϖIMp8~uҳ6zv[`#8mÎq[>'Lo j{!8Ɠ\nVޤuGխp>7n|3t~? k wɫ#tuEf|NQ0>:9ַ6 :Rx{{"*AYHO/e W=Ji|+Sr8^C"9~L.[FcWR=O>)i`P•ukl-Lal-pZkd/RSMFu?R~R:wr3 }৫Xw':{[㴨ki ~)Y l'_6<4W1fN6_=2A0-/ߦVGKƍ'6 '瓯jתFA>ր}+pjh N SZ|}e>\I_{D^*8o!5fC&WxxvtA}n0 V{W}z>g6 &A2g=g.DQx 7J®(Y7eOm hoeNõ8}'6p\y?l?z |z}wMVϭ_| |{ w CVv+$~%uΓ< WψQV)>;nr[^!٨וykZN?gddʦ* K+`,w5OYVoE*xˌWrG2+ '2r*{Iv gw|x_r:rlg~c MO8x<:ϩmQ'xn]=\{IB(ϯ5_jGOϣ ϯ}l;CmE$fc3s܂=".G^^=CB'cJIx]+>6ϵ)oo49N9[wXs:r rk%t/?aƔaykb6i:וQ1a  \Xr&D_WeȉK'sgNw(+H^N"g5/t|_UTոv޳{w|yڟiiLpﭛAp[tz]8$5ɿSE=uk9`_R^juuܻhwh'N_4 w8%<Wp~˻`}lXpoU}_97pk0hvmӕkx䆿Uju:Xvqڹ ~ݼ1 8hfտO}XG]Yz= }P09 j4@QӁs(vYёbvp{>- ʦuǁt q( V2Ct Pe_9z<99Giz]R==xmxZҋ=%1g|vRx*VUK|#=|$dW5\_=^9kPQr&O'LA,:+㞻n!5{{3qu~mrX>v_љrp_>(xNG?yLy/xD rl|tًK7z `rcI`ݒWn#~iA&W/OcӃ͎PQA>\YJ7wiG&k*Fg_F[PJ^y yVd1ՖY.j%F륀tτQn~mLwʄ?^7x#pU\]0}G{4v%E hxsZƃ;wu',zmG:*os'sg@v?A rng0ڀ2cSi!ù&8#sq.8B%Ӄ:f V^? TwwmW>>T.5najwA@D)x'C#Ϳp,}jC ́ZVJKhc | Soٍ1C,".xtY' {9ޯEX;b8\[e|~b>MxIQxƯDUpؿ'eTCc_g?4x||m0<'>YH;kʓ!?A$kKjk}ۭ}Gp\6?fؚ3{@>k>`j$jN$]6#C*pg,$p/h`u-Z'zWG`"~C[. $YjΖwV#>Z o0;6:aoȗ?A(n8wv8+)1ExZ̧s=lJ2 |z;v~ogn]>'xvDvu;c\zy p=R^|sDـѱil- $ õ ?0b1;) ݤY쯸 Bo hreJ}rV8߰.p.:g-d7}@A*Uvw.vMU5a* *thwc^ǥb>**yV:5"A-*p;tY'gNm%:-3>M(6Nu xˈ l}y{{MDܬ(8`7Rېz C>5> eȉk 磼yUeϏ9Rt6-eb}.O\uf/,d̿^^~h$uMJ3Qj*^J)~|ȯq'{o{f=_{/S&pn{5ni6işUV?{JUpp~Zɴܐ0Sp;<*,om^H|{|) PHֈVXJq[s uGR`yґt?x>1bjg>*Ӎs鼵!9wP\Լ0,|q2ȽM9R9 Rw%ູ1໪8ZE%YoE7=6\k p'e_ 9`6aX] l5 ``n^oq?]If>w=p/q9}k^#$ό{Ir^uJ$n~*?+ T}M{)zv \?f1ʗ<{+M>=kA{>\y :8|< nYiE6p:T D!Xe?~q>|xx}eWO/K쁐'{Ǒ39W\P4kB _KڜA87e *D,P;pC\c{K8ǧ_,b}WJ\'|NPU5_p"b/D1rM1g k^l ny%k`4b gws8uz?I?KƦR=ھsȶK_p9Sd>Rz_O@MN{ȏ̭ ##ƁvNay]?^QSsfDk ߄1vd & P7KGC{{R86lco "|cV?Po|0t V}{zymEy.i|ff0yl">w2sWep̥+TAU*+qnf=pN>$6l ui7\bsIk%}bz>7i[Eֈ SUp.oX 4dbtV&C~F6*(yoͤq Nްȴ}Tn9ԧ0mcmݜæiɗΫ9\5VMW)ըK*فz!7)^_%_IXUD!p͸#u}eǾ |oDitb+?9f"a+iĎ>dm~WkE-|ُf]߁ۭz3p;)WmpҳbŜS?{Bft?<= B;$f+^[ӊC_NꃧJ{~C#bfr fkE>ay+!wVϺI kX2AcǙ;P`z=fLO==|ْSSQߜ: Fby z7x|I]4%sv̖=h '~,zߋ ?ϟ_[⇘ &1 %Voә!/ QK9\JQ8WeokSI9RB;>z>7z_AN3"c@hZ=QR7䛇 ގ=;AxgTSsnof_c^WL0'3a/k`41 |%|A_ZX&0%/{AwG58WcV0e_ʒ';{[*S*ㇱObNB0p Fn˸`TH8v*457h_wVf/+_@^xRJaaKT7!y{Ij}{*@n>"ԇ)U_ W`9P_d^'[@1r:ۻh'"$&t`? 9IKmӾ,@q0 Z%@H3;߬vZ.(նO Dw©` "q>mxZH]^@`'z2s@i(s?&ғq#>>*oC&0sWNPn]$8? TPX[{K+u@tg-sYԯ:,7 _uXzdYdihR9Ő>!~dS}C<^ lc@N2UBe@g nKu" l#+̀z Dh松m@\-XsUUj}<묕24rkɂ (i."Cf|2o-ޗ@ 'ذb'=o{(WB=P^L*>4jtL!/֟ry3-O c@e޼jJ}w ΁\wB(z\@DcُOje^&PNj=/o PxC o-n߀TX~H=loA-hEu+Xϱ%|}5<@$z,b]ΏO@Lz9rhl+$Z$m;;a&s|#Ún|*y*PzJ]_N}hZ~}ݳUݽ't-7?Z˗_O3&S @Ix ϋ@|v*J@yvC@i<})rPӈ1U`="m+l:n +)3 4vN% g`vyd8U|.s n d<q=*3x?̀-6yҰl|]Ϛ<[\,˃{B7M@W/6R TEZqo[ /ZWXF= :srD_v<A>unnApiiݘԮSO@IY{(cm"[Imf%QF%fB{=J-V? !y*~l !_$ˀ~sгKӎ .lg2qfWo@?Ě,3j{姚_@rq'g3|蓫ƞ8ˣ_)R@1/G u/O0ͬ FpWFP^ڑ? з NHPR AIޮ<5d2nN2;bn2 ,ZC< ZA]97,%|:%ky ^LV %|nmE+ OX~tr76k\T7øߛ ngHgzKp\o>g떁Z_z _2u8W+= b6u-@,MZ:wU)d{Y˫ '҂q{J|FaI y=TC@=P;Mxɹ@1)duaĚs@^[!^zq>Uqp_1ˍycBϡ $ Brk R\?/t)҅q?pu>%9ڎ+x9795 l~%X;b펾r,_(ҹl N"[*@pe U>f|w=6C ika7 `qO!e P+v?{ ݼ?@u ;3AjGa+WFA~tԔuTNUB-Sug%h6piPK ^%*E Wڗp|d{~@t\tD*7^o_j~ѓ]6@;žĹҘͣ@)=DIH6 ䷖z1j?u^Bs2 DSe} oB~&w(ǭhxz]cn^v_  P_KIeҀzjYP66餡.6kߝBjCl迅_]ʯ_j>G@ڝ7 T+.v{i\,o2˲XO4̻ Ŗj.qh'ga<$u2vfXO1¢*/~p`~8qf b@:O 9pnm`.zZŞ K(juOK@~2d{@]}2XN;lo!r3eb&V }ULzۭG3=@ݴeP-O| AJcg"fE0\п/rh'Pj1}˂eEx>ZВ]Ӏ`{uoh+DL8Wפwan*(<{pR[}+d| @|#z; X\839P=rSpceŵՙ%%ZȡkkWd`N!F~.1oPί'}sܷWz_džQ6es{\?$~i[[ܛnke 7'G{`8<2|Siw0(ݭ9O-;޾3 ZM뀣n| L@rS;LVɳ^@(("d.NXۆstzuTzwԨ8H !ޘ9s@ PoymTq(IUs $t*g*QozKŽ_9}G8d[mtbH&aOϘݙ#S}ۍ@54K}7ՁW̚^}gq H#֘[c">!wpoX*`A(쩮u>byK'rꋓ7-& &{w]5^I<7wq$r] ڢ^|F}FլQG0%9%/&Jvx7ݧu# )q='g(}VYGۮ~}FgId\A}:оћc.~${ cow@|mߕQ?/ok{'{]^R4#/+\ݑ>Hԉ4\K~0:*ޫ :G!@=^ɪb{nG|2"1}Zc#Y3q@N~P̋ԷCޖwQ=u_]T>qr[0uz@5۲,X@J <\|׺TP_uv_ҺZ)G[~lo6PpӺy߫?+"gMsg'qfcaCYvO?a5XH0k^V6dFu.換S}.s=tu_WNz#o+}Ct[OV-$Yy -}\VPWy>KfsPR۪ 0p193W/:|bc3k"dxCuw- RtuЀċ./^*~8\+jzrPڦ%[x[?A ake ϦozϨɍ@GWsʶDh6:6DY`^Б59}c$GSv&ȱo@9吲h$qJ`k1]R^"4u^?{O<wjJqv@1ؔT8P5% ^<8H\Y=86 x+#)2I?EM?bj[<h/RN,➦e;+ !>rN5}9s ^/iwXyD $=}j9P2P4a~Y:4SzΕm$E/֣iL0xE'q3|@cۡP}:=n)sGE@yQ5>x*}Ͽ5̢B9Fsi8'_@]aezh3GW]&wW 9} u]k_|r`YS'\{Vefu4` lM^ qiE Ⱦ,ܷ̽Kq<[4y;dvnXc@)U 4U>g6?%j;s`I>n&xuо*I3yq~p|玷Y~vڧ@[^,.)S[yʠWZOUaZoMyIMM{M]b;#فdg*ŝ.otuMkU횚oC&yk.+1hy'ZIYe9 *N9ۺgQ'F-ehagm9>w|j<Vbh~9\1%UtC3 }ܲ[gvFE zk+E15Xr2ag mayl1Wupʀz2iU\N: MTT81Pӛ-m6+} 8嚄[l@=*"dyؕXOzq@=y 9c]>1 )ZEF~w#b@5t8m/40{- ֊=Ksu!j+F}O@J*2xw߄J jk1?^v P坻(!PT~ukR@y{yu=e-Tn~'0Y4ΘuSZΝ@0f9VY@Y &fO/w=ɉB)_(h_V-I=@My#1kX]gfX uk2+A9žT珿oN rjp݁M'Ҵ.ji}qdbcxԎ?Il0Ex(关c?'mc. yu;xȥoo0uvٚ*d,$Qޔh $<(F ZRh kՀhY3}1JOcow:(wz(0WLZrSuQ?|4qaV@M nq-9N?s@AGϱ@9+TSt|0~奫@ U'? {o.Gv PlTh bDx꼞Au@ ݎÜu;"ķ#QwiFU|oB`${ӣCT]@j;#n;%.?}Zl:PVS0wyжuh7`9@KXӆ,(ACTZp#K'uV)R#iV^8 wՠJ~]S|9?,uF!"PC *]]ú:|>=9^Ϩ혯O<l#o=+BAmC׭35KIfVVUjU\~. 9g)E7NӴUG~ҡ{_zQPsjƍԖk,j @k p|y_M~AE4E?{ʕXOƶ}R+1wy{9[J{Rhnƺ"6􊷻/s#ί+C1GV&S?5O~Y":mj_Q>= I`9Y`hmNt]w( lhȗk9%7#x Gm"ؗKË=a BGnBX|M[Om/@ӴT_`^Zч)78\П'n޵^-X[==?۫ TzŚvw t"puMٙ/2>z82@ ?S`xk%,u%9Cm҂+@Gu3ă5M+)tΥd(j@ puAd+ ' o\dLHx?ro˿<0w%k=#VSv\@(G 5 hF1Oi lFpO*"r/ W rh MQ7üYn[}o[lj)+)*lB~|G+/B>;:>5)q )=3uw^_d3ĹԒFk?(a4 ǎcӣhS+ssԗ=5(yoj@>}? rI?Gqo,w^,mRwF;Pvj)-SZ#0:P؝ {)G|Gn췑GnpuM؏ݖ7+VV-Co@f)@_jcj,>6;ZU@XwRQ{EI1pGWy^$Ȼg? <+Zrkĵ! K/ YG= l@U zum sz#gն5wg#:(պ߼mz>y^n6Dل%b3u}߁zwB7fzi@׾G:Al=1&*") \cI*#Ll O7tI 9a]iB_鋯Oy ^Qbco}u uԇOkBFn1}?^ws0ەw#cLXc.E=fNNqfӤק` t1&J Z=̦zG;qRs9sKQ7^/:bZ:yUj pU O;nyd T۞0/8N|ʡ^gȋ@޾"GobPeM2CM;]e-?Kߞ_Ũw[l{> @ǘ=} _2ىglu)\E]ظϛjtY7!K'3heQ֌?[ 䍍ÆQⴤb-! V9ۆsР EQ3O7M'o2s"ὁV\73D9{nz}/-Hb DŌ]` 9&ł] `9F"Ofh}m78ػ~6YhE cy1 ɇFYg@4.ɨ!wHJtmf@NV%D* yfzy8dse.&|=kbzdߘ>.4dyͩҀĞO%Pr?+b]/6;WY2'\D竺@ &Emý ? 䕰Z7 d!@v(zU.b@zc>DNS+9 ;@]Za@no6y2in@DF'%k"'T=+j(`Sy?G<жo{ԑ0W u'mU mv`Y:p}T1MAh?*/5}_i rjI9➼"mf[Yo6t#4y̡=0e n"н]BE ų>7ú'OoX϶HјGwOGHΌVt* SXWi~`(zBj:% <\u_%4 ^@]A\?Û9Yԯ'c1}"70g$0<_;]x+Zt>-[l8:{@èF96g4)6顎$kܰGxtn} wYm6 }|M~c:U'3Zݿ7}j{$|Hg;^]/k+dң?^^ ""5@Wz*1n< W[34og{ ~ǖBC1xϕϦg;(g&mڜZʱçw4I hg-q|j< T/;֠O[Bq gfFcUqC5I!Fs״a!%~e֥[v=9@l|rN@4޺&c]N(&%:I@ߥKs_JC$nG8}e]k.jb8eZ+ P݂ky/-/{=kʛkNỏ@q!9 nzG_<"'I]>#\cq<ҵZ%3aI]>1'Ț!R[1xќ{}!Z#{W8oIeqƕѿHYq\.[Uh:+"sF5W$)0凄#|JlƧl$s~fHvG%0K6%Յ@ZuA35/Qw/^OCu+PO}pkk8Ggܮ U/%vŜԺ": ey[ [BJ珓EO~AQsˮOt[+$ w"?wadg=  [aO`U)0Jh0,r2(DZmepnN>3W/D /ikƒ-r=I@[ g/;.ԉt:s{fO& oH'=}p/6 Џ]ݒsQ14wB ~gAש 8m#!K[_?255*PeLUب&0Bn&ވc׋/+4ldTp5r̷YN@}0-slP޶{ S~ɉtz]݁|~mO ¿}C5n^=\h4YV*͗ۑK\99f,cNػn~"qm E >qN/ju 5Eu݈|B C14[YoKXWA @?@3~=OZ<@uqdaZ?UN!Hnh YO QUƪ7pqͬ'@શ j%qۏFmko@ʜ|W{{bj` V>mH/jP69'q|9Tjt0B [ Qz1ϕ+NL'Xys_#S*QyGJ PwםWu @%C}C%<Q~y{GKAԁևr Cm,Q{+`KX u{YjrW_Ec{o8fK*qGTb#`?ןCn3%{ xG`+v? 9zw?OꁸXs>;~CSSRžrW T; ȁ>b$-k%W[ F`&!./DLx)kq;h֔Sq%l%I5䩝}'%=WjKIZx8}xB˸fDPwΒ;pc=PI ׆p)ۂ^Ե}F[TCU>߉׷LpFӭȹ.qU>ir|>^ፗ#\:Au"ۧ@ް凎=N;9v濔@_[ዏ #vqCo(|Sy?P-w2@>71kG-wŖ;}߀Hk.xs+zޣP jv#108Z膚@䢡[ ͫ\Ϙ<:VM5@fu_z>ktT.q\Oh97ج?WyoI7 Y|}L uC=By_}33ɛN}o=˳Zm0goIC4oڡG׀x9r8(tZprњS씀~hE} A;[1m ${z|o/_:Klpϛ#lc ν`KL^xzx $e%MS~V5ɋ/ Aiwͺl~"q KoNÈH?COSƪV:@5|$IOz?%8ѭ oZ0Fe^@gn+Sc`nvo\־8GJ-:S3L?Nrx5N@NY$ҭõ|FFKo@Qqj=Mzi`ݺI";cҨyݟu#ZhYa ,e1Y3zIf4[*t5 X<7M%vTn0q#uZdU܉iepݔqg=u\@)w 0Us|y4e ucuީyv1!@w"k8{vlVs'77z l@{'sqj|ȅ^B/&6N,=7PBjB2K;k6 leߩhܡ ;]"ѿw2悀6Vfjne+ 5. Yb(6D͸ p@*&E,֋/'?iy]6Su?*π8^$uPG]=ڸrT~sx%7@`+`ߍu=1<oO'@ PV2v@Dl$ro0~W*gսKR"zʬ72-ܮa/ yR@MyiPEuXt꽍D0jlLb [&iV  (tv혛)Ywtk<}-mJsrVuM9 CkS}ZFPgS2|EA0͍zzTe[9wOx+_CO=X1~Z ;c7k=s@$0~:YdX]Io{{ rVm8*2kl@/-srHXo=W*T _Rc;;4|jwB-_= n*)w"4}2qWy"zX3?- 5 zG/8Tm>-sȻw ("v7@?& Ў۹|,/D]SsXvљ)mO׷'GSϿt#IY[E mwX~8jk},ۦqB p3t-Gf_݌( Ϸon;؃FR"mɲ.=5;Fn]R}F`_Ѩw| vd0>!]f慩U䭘b?;ՙm04mH(L_ClJD]uˤ ˿'ρg5߸(个i1y5`q$Ɐ&K\b{ -[ e"xTܱg͆@h8> 4熳~ۇ^uԻ+ۀɞFFE/T u0wH%آ/応{hٮb5E B1pja00>xNbLYС% :{Pcx|Vȓv{_QǗv]+]u|%06bZLМLD;x"GvWbZǕx"ۇH`TE=Lvz0},d؞թG`IcMC4ߛ:8oާՃ8vyp"Cgar$}5̭0T2 ;٩0$uCygNa^;CEBL[_OZecJ;#`?(⊟:ѯ+V2[ʵ@~s;} }۾@B._W#w@8CId3ů٤/o+=&%Nu"oZ~޶;wz_w5^/ؠ~h8fޯ dG0܋GN ]] ́ݸ/WE:ڑë&W^Z`OA@[+SjiOԼ.f eƆ`aRz7uP{xhgR׏w.Ofx6gL.^'ˍqc1ж.˴9WܓJ-Τ>`\|:wCN }#%D8e w=vuǗ>CSnu^ iM׫I@Uk;I yUHbu)J.jżv8rzUAOQQhl0:nIb>bf 䫭=pOʖ9YE |U7ߎXsWO> LV;T1|J}xuƯz+B擷q nA=ҜsSns-rOs&)8G2؎\X 4q` ۜ<+TmŕTԵ @n1(qi̛"*. fk@0L=;zreJ0 Wy$,T=kwJKHKLrkD*0"0D3OJz/@sW=u(h+r#3UeF#baj3+ݠA6: 09"6֢^4dx Rgg'=1T}o]=*&˫1' |t=SG1~4@/rF25E#ۭ1s|]:LJ/}9K3W|}ɰ[Q7)k=[y EEI~ڸǞeqy˦|ZqbLWJei0067_<%ARך{n>Qj 0so 0Хe?q+_OGqc:w4}syW/֛5/| v Fј,OIq89?1M%wq?)6_%3H_-.o:EFi?CNuh'Q_ N*`Nf\Z!Smd`v4Qh@w4OǙySt~-]ݹޥ#%}aþEի|>rZucX>޿1px{Эe#dۺ]:3X؂\#ch6pHo@wW-j|{^1Brý#0ؼzl .kݝUnȹ:4_~m@d̓ kWYI @mr,PBԃ=MV{h"?͗PķF"U:B[sw?/qv 7"K:.~o*n8̂<&Jtz=Z,39t .e:n(z5|zerfݏhwsOYQ/ZNV7@T|/? g?BO_g-}|nOm;1NFRŶm!on(84">bP^qը;VշWUۀ2w0 XU>6V|}a];0ֽ_} ߩϱ/0A)U:5XM ~mfg̥coHoς@Мr7:nNk<(3UZ{EU+3qz:39:?\Z̯ߊmb:xўmSH<&*^א^t0,ܩ:W~|o;i~nS Q`v ' OχZRte0`( D>8|I'N΋]~8t܁s.) }1> 7-TNkDB1A|E?0&4O+125zl[\\W7 .Y#?Em<h)u& ")OS)Ң 0/񾾙9O'oy@NO'w,G~d # o<\k0)- f\«:7rxW rBخmlPϥTBPiG}G1/l8mPp,x.H8ƻZgfA23+.KɧEU>e t}Xow̮ 692ى>n9óQ{]-4vCw&`Xom)6@(ru88JVJxQT.&t3K[;@gaD\`>b4H<)0. .ګP/RkӀL)iqYdq y Zb9;8Sj|{Z~W-vԎA3w/hu U|!¢Xՙ>yPg0\PO?}~\afԌr;Nbao9T؍ `|FX"~9֚ßp \Ҏǽ޳WZQѷhν\نE iq{Xu`C4;OP7l-U훁=u  'ɌaS)s%w²rZ6`*yOƏWw? AVk :-viiWlVro<9Iq̂|W~`jÚϛ/W/-o's 8Cu^g@?4y>?<{@Vw0b{X5撎-Hy)0"!`r-hceQ|g}iRpN|tua ~.V?\*=G\aSp 9V%f n_ܳPT])s-"[R{ wyxȃNMy1/v[}- sC.)ymј<ǠSп*$Y#QhiiKܣ;疴UV[yȍePNҭ zCzhoTyxUNr00T6C.'r*4`߰*敳GfarT6N[cZob -ID~ ;ݲ UWGϕo,A X/C(7iuY._i?2F\PTJLgCx][9?jdE] pstqTcZ nvDn9%l*_ͤ6AĎl:ɖ\Nl/qԐ{B*v&9yQQg i$=u@Z()5%;y w(|q=ǀEn@ԛ dN9@iLo7@+u=z-X ̉>^~ M4Y~J˜ڞ~6m^']p*Tn͓@~PxҋCcʢkȉ6S!@, 4J@М0Dv[.S"jī$~>D9 /mEJبo5rn&Mi8r9;'y ip .:9.{rR-mߎb.W=@C3O|~{2VFdV;J{#͚Oc2%D*d`@nyx7}>^L8\ٳGWn^rMqZܿ?|z{_{r1W\baJ傧4Z۞!v_WpO؝) wlY\zE삸q!rπ.v`_l~$ϫ S[_ó'e[Kd_= %ק\ښx;H[h]{5,꺲ssЭܲL\\ G6oɌȗs^cu1 'QŹ͖܏FA ue1Sv>2stxw@dG]4OGn>r>[ :}}j/Y|*2_O$?bKvI*Ю ?,٤ hR~V F_=컋}IM@ysJ[݄\RD^Etz#n4_V EߒJmݗq7厣/N̩R k  0>R~x.ܙ<6{#bz`=$1y9fNRF0cy˿SE1+D%;}7: +"K1)X@<_~'r |R7p'mpW4 -t5r@ns=\@֍)t9@*s蚗=B3= $Ee RvSҪg;0<܍$z~-67TNeG-=R޿nJ,C^Xyv! UIŜ&CO2Fl WI噧@fѳ,kmh?reM e~ax"з-LXa_eO~vw*M8"u9]çn 9[p'hYn dN{y5z2yi>h\k>Tޔve@>?A촱z{@Mw k+KEI DYO/ ty`'!(OCWwȾǢTx^}-=.0oBoߗW [bݘ] #Өje%P_~/597ѕ54{mX1n +*\ؽ]G`fOY֋_{Nw7;[Y NCIEv{ k^[-Or@.{Y}kDVYI` sʘp#`O\/{!Qֻ^ BϼmTx,}Xͳb _vhQXǫ[1JD0.[a+sGy>h%9N7p)嗋i28fĴz0y煏k"k-m8d_\V$Q0Go䤘J|0} L]g4/k1 {BI md[?rox F=Xq.Ys?dkj>_|])Ó+7"*%=4Ɖ7d1pi8򴟫P#OJ>u47J¸r"q੯kv->?ܥE_ۍ{|e(qz +($+'`|r0'?&/Q_=xn5Õ<I^|w<骎0?Ut^quriÌRZB*I*015ϡ~y#ICc-81$`L\3i$qC_H.cm1_ 7kc/f%J>\]d6#zSaP#2P {nNUwϽ;Qoq1A_!ϟMϒjzU:x~ inX ٟk⹀鰮$CTg h^Sz]kDd?vta6^9`ZHX) 5CŦ*GW{QVV6],HRvK{8v p GFG*^䔖#e0\}fr RΝEm#ȉ;O^!eb |-fn2ˠb}G ͏,BCd %-@Y/YT{n8rTܓ-sL:68确?w)lO "U4j*ޠh=Eϙ}'.= \9 Oo90\@U,ђp|HR $u ^VŜX﹝ 0wĹ,͟dS; *]!q;"za,ܞqXOFMnq = gu&el <+ęvRw3Һ91ؕ[yl>Z{Ѹu7kηo¦yŽ@3C|Q{$<|5BG٘CsY1"7~fW:RsKX ?:`!i <)^b7 W_lR ^/ǞXHDIhL{3v+fb ?ej" CW;-ީwMLyJ>ϽfcKՇGdsMàSۛsk܇$kbV<{ ,DWwBDџ{ c221%kI9;9h |Ѻs8XleWI?ˇp:aIW^ bKSoCc=uŧo/ 0ЇwmDKKJxowYAVV`}Yw=ppWRf:P(=Ȇ?ȉKiiM%0 96UyXJxsz> |yњgKkż{є**!+^3Wݼܲs^`~^yꍞX~>K)0K#֭jn5tMG`5UOE[fއgqD40l+xLe\{> XB4~`9LcudVE"ߎLh{V3cˉ{<_!åqM;/lTࢶ&n^kQv;*C%^'[/}yKnq=*) E`\QdcwOw_ lG/츬xKuC#y+ ^yzxnz5j!I\/\KկF!/~&}B[52}(EssKѲz1b3*)qۣYmq4rs/j*f?9:JZ~Nxp6ߧw\ dRǞWkuN5g9?sS<{5< /zt ?{w8O޹A3 xR1~ov<%h̓mч+L\VD^ -<{]ısv;XAuSxcȗ܋K~b:y6jvw/:l[ϴA~^g,{0'~_o-7qc)vSC>+>ۅ%_+k;/kM2`/mR*C./AϏCe>c:tx"=`FG[+.mԪ^ d`wS=X 5ʥ|V\/=Qv:UJ4`ݭ#s2&;O}Ik3}%xgMkV\zWsC~:NfWc_z|iOB1۔?AG_cq;xdſK{plsvI'^2Ϧ/>b}4>8@oŻۃԾnֵz="M\׃s<\T{o0y?U QBf{ Nd?,t 򫖀yzY 0 7џJf F}J5i20IYKc~Dpy6W{C[_ ]! յak5́ rUK=Gӫ(X>i}-"k>'v`_8.| xG]Ь,O˯x]q5qGzBFlA:%_&%`(S|f|GCcIN%EYtO׹YTۅde\"\:{u@rр//g) ӎZy,{|sOaoO{LݽrPiDgƥv`ىRfe%Б mXG܁,hĕG7'̽H%`dB5{y#n2~IRqwiwΪoZ,tBO ;7&nFܠwx#海p?r U7;^s5K^ F5m28ևW) P Ȳݞx8s4jzԀ)Djf0E*bm@g#X*N<x?cM8 }+w`_vOT+m[ dY@^11H׏g~&_dIupkY8H<[yF GnB#BpV:0[ u66Puu>_/cL=;x؈FJ U/՘7?"ڋM^j ȕ Io@Z`t%F~`:7ڜ jzʓjPs0>籦>gƭӓFHC.)?@x^4cNˏ-i4 .3@q.eejf<%e|5Z u_X;0\ y[js[x"0X' IU ~{ϬX ZCg+i8]Y?{cUf%QN@[A 08Bx~3 ({!KF36k6 c?VG`O?l<,~n0 9N~mN󅎵~5z̏ עq~5+z_:[Ó+ ,0yS\߿Pj0 s&m>NuNz~c R6.eC-'R1_WXyr}ה nkD9c.|w0[}wkǧCO+58+g-P9O2H#[Uf &:~kk>QB@}/v؛p**0b\fA2|4=r3<~&e2#9:pnCco)ρ,b5[нw - 5=2`)~y} |}*h ḷgVmjGR\PV( Tk#Q3J](V8/&^sz䊾ӺvÝ }0ͤ~+/>'+ saxoޏIį:,r{7L` D&E_9oU!P>j[tft}E y8b稏ٯb?~ _MW}޲Syn߆#jކdžJ<臗/K SGVuj {IBY WCrסא5NThz[>[܏C_6ϮvFKoiYY|6gn/_([u]'OgMN ~rI ɵ~2 rpKN5suj\ꁹ~][xPW7L=4T}Pez59|7$ 0>cjӿ<@I2B)`Hmȯu,`裯dJ ~:y=~->>is29Wt߫ݛtCzq Î{j}}8m2oΫǎb-M< =% q8LW]=ԁ\(tx/sY<rl\}"0GkKfn _\g_fات5RC|@ ۻ|32nZܧu^s9o{fQ-witáY'Z@-\c1 -ηs"-|],Ljmm`S{< 5\Gt7a$N"h.Sjmj6w  ,?Q߮.=u`MZ ߢv<W>Oţ~:.&l ԐZ9>\%X@Uܻ ՘b^]b Wᢑ\ = 8_~dPۀc{00M2>)<1 k3 WkfωqqmC3P6f3 CSN8r}ڀ]x+Γܖ) ;"*n []-ѿ76|偕e)'uϩ N ZN6i0hiPp7E+P)J|hWH֏^y֞7 W͛? nt3m5}\ H>"1q9|ym$$0EIWaZԤc ?f <650Z(IsV? YCRj\]p'r=q6Gs- OqlgP5}ȯe5?yk<hf)DͳY@jx^E«@vD>T<+Źbj` 3|kkT]{'4q =%sݻT@/U/ٴq[q̛g򡿝`+݇|m3|_6^-QY EY4 oGS7V_\\v.fcTyч6Tˀ̽V9}Nz]@~tsB}d㛝8m_έMf$砝ʃ;MZvѧ[JDo9>}'T^ucAV~>9A#XNjfcN5rz _|S&D P ~֥peso݁srʬ ޝ}@VZ^.A'{[/{$dߔk:Yrf?PGv=*,uwNKZ`śjc[ވYcActsWD8pp*0s5W̽OqmB ک"ُcD:%pli}>"0g&{6*!oU+cU)CNXE'lC[Ng/Clޛu |LM΢FȒ ;BUmu= ĸ#W =?`>}p2v2Y}w/Ћ=Fr f?Jt_+PSK酦 ȅUŅ>c̶XGfGʲvig07V qaoU! %|@7/z'E PvZʯˑJoFuEOgo{ ύmzT&Ï2"7bN^?[xn=0l?!(_%qd`/_& ı7^j"@6zxPO^Rw 6o80Vq[rrOX{:M7U/{" 9O@=b]=PZ~EmZ}>w_KeVwÞ6{b\|Y!y>{`i0r(Dԃ$PAvz=WG4sydrQVw]R9m>ށ~w fh O26erGj|fqrCUaK1͟u} wu5p9O/B=lrc55KpDq…ir vț'evC@%_9ʅfk7[W L^~2L<}O7(0n<9Y$S{syg6G`^e&>Vuzykn/'`T-@[jzH)cIh]-ddaDWnˋSFvxKL߄}fq#`|[*vu32*ap Q2rF KcS\qaaMaz+`+?}s0=O-?T|sbkE#Z4GvrCP}L#"3-5{ǽ15]%#ׄ=nE0\q=h zb ooۡ)yx"-Y3>/jo78Ӧy;u[m)0wnۣOiwLkT?Yq/`xy?trϸ a-Y9i@])V9 =8%Wx=-U[̯!i?"x!8N`,K} \n=?#d <WwS24Y^}εl2m00e}erusG4N2xGfu@ZUcO0Dcv~.Q]gw6 ryb,w6v^_'#{Z _ j%w@.R̺:^}@}5\rJ 9MnoEv˧6qC>H؆`]`@if;.ÉCM -*3|un||zb s-{%Ý uUcs:'siWoS|r.%qr=ksרe*0scf_|Vsy'qn? l h-j?B{ ~ny[ `yV?VG>$}]EϟFbϘ+O@U:x+0ѭ矢^f]P|cp2xȇ6+sdțkk-]6-7?\,ywEcy!SҡUsϧ7Ȧ})i$=<2c,egʰ^07@F~G& eZ,Lo䀛6Hk~䁖\B*sSrOP)0֦a8-vi`5%b'59B⎉QaݼG臖~wTqGhJuSVOau@u^ {m3@~v tW saQ#{/G_q=W^H]# bPCPw\*. ^= lhS6| bI?WًQ8/ˎwpvm Wz*I?6,+0[ U#LGhd߼}MTZ=層 n[a{I~B,azc?@'>׹<|݊~`:ct{ip6`ݮ%{wo/Bl-Ƚ"Nބ=aێuK Zw0&ŚW}QS;H]E>uv rڹC_f 1ΉB앝LcHY?y(F'8K#om$-G/xns~2siC {q~//_4$)u#OĀ*(wX9 \_}a͎J+E _$|~SA%釋o5!e?rIy4dx 福[%7qމ'@5lYsYf<(x5d:8@+e1ne q# ߉>^ަy 7]}4 %ZgicS4+Mwq՝1C5/ݪvav^o֯r@,*cQ¸ooO&^+FrwA9cתĺhΏ?KF x6&cXYfoS|"or E8Nn3?Lg|Re:cifm+l~V:smQڈzzZc@X:yptt@sTo| X֟a4u{#gɜڴbnSÜX2DtXjdeEO۩y&J$WyTYSJ Oq >(Bsz6hV=vSk>6h"Dg?(ǡ}Z{/.Jbn4'\_9 ثu| sM#uc3gdFR*|=8[7h(Xm~yOl!tW}>:-$ OY vuh٧Sքf0WVGtOsRǁ|duB-l/-֒V' " gai1l1r 5v_x(&V#JJȅ?+Dxצ1FS D5 gFO3zC-oɥ*_GB+55 q@6;ݫ|Ww)`rD΢pS̯S4'QH{[9khm)5i %/F4$@ЦyuO.ѳ.xEso)|k3f_?e#\g,r9}\@h(Jqů^uҜM骼x>UGKQ;_ip-.Zr 7퐳v~z9]T9p)%d4ioFs-{G~)vY3T9*b=]|l s.ǷxvhI"ucg/ ?d={yUlp> Iqףb N*c*ͷ%fPuZ t.}Eֶ}f,F?gginhwú46'>42樇u_kui?̣o]j@x+y~}ssVy5?U=4|ra!++8yp(`3w.09GW8Uќ#zꢪfгQF't_:>FFD=ad ˎUIؗ흀׸ rƫ'*B3v4gJ"Ω#v߭<;<}Q-c:w> ś+l[+w\ԥ둇gsz`mJ@-.n0 T1oo^ތ=2Ea<6* q4@\* s(u"h>e,y` HB J.oDت90msշ!|4NA$ZZJn)>Vp;™5ٹ_X1 ~פy'a{r&l>'?^tv9?k_u\]y#Z>oqS%\gv_vs¾f[@>ї q Gb1E X›]";_tPy,S'}<7â7D8М딷!><]vU '1/']Bg7>_?=Hs8umUb ;cJl?uYBUIPú98۾ϳ]6Q/@n <ϩOܨZ9qۙ Dj{2{*(Fk-mTHQ6mwg;69ͩ:Y-G l2[v#wz.WL,")8g߱O&%Γ;T SZ2 07\ r^Q',@KX[){?yꬎ] Ȅ |8-ycz5c;\ߐ `L .sx{ V]  Bi䁃;ODx{@ @))8uS (&Ƃ|`"1ϧ%OnAaT^t١tc5P}umq9=עd!L-iD) 漓Ox< <`$LlWmUSGqLga@eotG_+׎g3Ӣ9};D_|#^7CM/RZ 8G4O@ GyEZGq{`Ϲ--mPux0.-3Q87}P^sGm,i@5f߭д0`{Ӓ%ѧ/bn':-"w(eӳ6 [UX;z4۴7V7y&|z>?۵_ǜhvJU_~[w@#{JewP&y;{o ·zhpm`tOI3Ö;ܞ i@u}Ὤ2FsuhN3ף*ע/RއfOFv ЉO݆Ģi5GӳQ4[*hW#.{Hw<}0ǩOm-r⛉۹pJEoڅ ai zf *8ͿJִ͹q5M >LYvE|{i,6ȏB 0FsV%ÞgzOYQ.VVYf)fa_|ܺqf /~:1XM<717yOG",,~_Y,rf2sZ2Wo,(W= aS[rn$ ,8 $#@S4G`Vn7VbsDŽVjf:04[uDU~F]S˫]ǖd@Q> Hsfo5k}PfEfb/ 7RQ_QQo%*hhέ>W ]ҫnsA jd˵Ǟy-}3^9Br/ǞsGQ̓ݚezlr,5%!F-%q=kGskcaS۾o4{+ǑßGm] Flj#_ƍ1u*6Nt̋o] qݏ˸d^lrCջJpØ4׫a.I콧Q>m\qlR }Z國>puw@-uh\_lj`%ԭ~BCd4";7 {BW廵^r<8Z@]/xf-n1S2}2*́:x_CxV#%g'OjLln^ tE)j"r}W$w _q }xy||nS@zZ ˤ=?EJ7ӟ'p8ZDP7 S5a1xz操4囼Eٙykt56s=`}Zq"9ж㏗ PР+e{-!zVYaG  ,KE]o -tgfvx6ÊjsrV=vbSKzviU71 P/ס~ڍ^otP;O1;[o 'n94\H !|uMPk{I$0r]\xab. =ZC?1E`Nˑf {Dn<$KiG[ 42{lrj7uc7GlvEsy7cy@Dl/y>p3niycH2b0.E2WqݽE{sنys{f3AŃb@=Q&c} S]ѵ`uCZ{+a/XbFr_xR|@ 5+GpQ:$l%[bkY%?0ib-.a6@^V6k?+kZj@yF?34 .~I֞^~6/F"pE&z/(2l#0ybN>j6%UܷkjNA@)j9:.3S5}5!Ʋxfw1)\P\вa; oliu {H[fG Lu;hDaw>u2Z-w_2׿{"jԥܤ7/:`n=f~hEW;q܉:7n;ijCKFnՈYe9wRxc)r{k3RȏǸf\hЏ¾s\4gcbbQrTF!i]׃wrF צ]8@sfGLC=ވ~uaeW}/j{q S<x^nkl}:/Wr'_Wzh0ux=^]7%: U78"rx"$Ph%l&>a?B(Ќ]yK`n/ﰷ(pCsJu>vT#$rrivtҲDmȤ;hr =g2&q:In sOts; yJz|.os}‘z\,x,q=G7m?O\@ZYY.>1wÌqvrPU!kzRڶ)pB(PwD)Q䶢oE/UET6 } Lp"[M 1%!a/hƾrx@̄C80Rf@4:>Mci`ne=1X\=2ϕ)Gwg`@K̋wouMU&KMe8ϽT: }CHA_M6uO^RZQVVvms_Bd_'oǷڔﴞeu:_&Ī9%87m' >?-7g??|с@yZT1G_xs5K8L͑ՆߗfFu=A}]ک5 e[[n\ĜݴnC_D?r~rA6~G#z^7g~|Q_S_  xМ[\ӵ4aQͪ=~q*>+ѳ쨟q&!ѓmuh{^3*q}L5V9ԉz}>xʶ QO>bJ*Wx&U?r(g8ҍf;NA"?ꉶsWК|657`FovA !~,.㦣 7ʵ"lȱR\o$qJ Ϫp~xP w'{2iݚ|S N/TZ3U2@27l1 /&S4Js~|jzu!_JA6rwc"=3:L縺v^* 䅒ȁ|U@} p3[KkgEWOGuVH/w 9SМ;Bw_i7s"*zcT<ؒ{<*9_qƮS|7rhkwhƎfZfUX*g {L;!}^&LsMm</AȽipPDpD̟#SktS>{~VlO_xqbٳλlW$)oN &R?v;HJfzcLuY"h..p31grM&1 wφ3wOB翊~`SR# 9,*'jWfg;nFlma>7aLlWu ".JjMU~^ša(i/qbOmWIY@R=7 ?_s)jN\4,ƫs4o \nޥu1!Ԭ8HԍY@Fn_SY}a|4J~-Ѳb^ŦmBMސ Ls 3Zq@PևY71WXZc3۫%58(D.}ޗ d_|羹| ߈|+|2ԊH^` 1FBS*Y~[jq$';KO^+ Я8YL3|'9)w䮝;̸vryY(Hdm+vv7/i=Ik~ \T\~ϭӍ>^{;+8Gn`Ϻ̃=mjۃdϻws\az֙Bgb JL_'x^nwKϢ>jF3Ul 9vH{'c^W.+z?=.q[E@z4UF?։0g9Ub#'F*:Tzu_,)BCcI9\OXXZX] ȦɀQ@r[3y Y>s!}?4;汯#ϲ>m^Af_*l\۠?zvS5wf1Ȉ1#u4[oN6k!xW--O5e3ZPNױn}NJ ${y?nk5Q@3λTJԳeد*8}+Ns8|[E&y6\ ^ <*b,NU]j^jkPLsW`]os'T7$K d_۔c>>E^ǙԮir~{KѿVvzŊ˃3.y_d+"v)G`K{ >{Crmg%9*_ JU8cMK(EH%W+s|*j1_2JkWFb m?x JfpX&Vyl@ư40..~ZħQz-,\n2ȝ|_s>o_0'>SioivUI $H_KqcVIsNDnXyh Cׂ܏@$8Yok$JrwA ;"@:| Ҝ ֨m-(S-zL- i|G_u?jǧB~ X(͝D =\M~r12/|>([|N[]A֨TN3R@ﰭ"Y.4{/q( ID&PJν^w@;9t]#oJ|7f[Gs:%~CNZ|B^^ Ɉ^qL!$4 d9nChs}""|z}@xs1@Vl۲9|h"@{ p7=X o^! _\PR̡;w<=Ҝ !ϗSl8/6l{dS#濒<5qW@]w 3|"70PL{.\o/ʜ@. 'g {iFj*PVSBh?ӡ'"k\ }9OVqUf+Ͷc^hlbu9UfC`uh^?\Zг4֮-g:8_wnL<8[RXyS-`~Kszs_} wu̲efF?4%<'bJݝGpe ;DK:sO@ ~jFXp@t:+ȟ[ w?h'N0 OY=l'rtVID?b;}('?9Ԏ@v_\Ə)\:/)>{}ㆹ~0!g@Kxѳ]Noӳ dҳI/פ{%z~(|޷ΰ9=us}Ẃ/p 6TƜym5IrfԮswAs&?b"# ^O8')YCQқˉ3S|A2}*њ w1~ ~}У5@9 >Ѥk^& \H*$w:_ cwHzBlɋ _8yѲꃕ@O8}oùqػ{y'=zf\v=V>Z3嫱3r򫀼J;潗h[+o[?PҒFCiU2ZtWl*Wa9R ftbv'=_/@s>q9My(qT>\e%Rj+0g_i|o}p. D_ͩ M.KLќ㱧_t̹pjC80Lw&]m9r;|6<C5<-|QV5g&ѷ%.YsPǾĻ+[r%xgߍVžwЏW Q/~<@\]H;=sLZJů9zN2#l/'vQDr٘;=4'y'@&l7ބ}ُ"ϻ N-~ؼC9ʝ9_YC4{xB*ţĞoY h+OҳO>GMM`]\Gs.4Ul@P<5ng~7HEoC ݸs|o6=@<׉_na^0pba͹Wm~~Y{,G.j- Hbry4I@@fӜ[{zTl1MSpH@;]~R;ʙ }pm^=ENj6^=]`,I.an_48EQLϒ핻73K3S. Α]{#oٙNB^OE{"e&Ƶa/ yw_%>*W=(4JQMҬo@M_vO~E|5:qխ=4:ݭ^@ͻ5ҁ4Vڀ,5s" 펧R:1  Y\*|`="zGr=c=nFkҹ9Fsdru?l_z甯h]E0/,z9͕zZna |g'=Җ挺>@VT :~&;=tmQ{K@t= OWtzje 1W9;!̽ߑY.ڍ'QǧKhΟ_/P\QuvZ!a%.`̴fpt>E_žh jqLXv2{1SB_Lݪ6LƎ9]`ؘEwjPS;Pw%!h 3lGyh(ծ }zE?Qj6!9yy<br%q[*%Sj+Wgܻo؀1/_B-2&FO ߑ+s>ߋ(g)*n/l\nv|ծ¯/7-OsC{/ܺguw+Z > {@\;0i3\c!PW[[ښO6-P^M,E.jy(=5!y@:I"0y/S5PDs? G%}L9p=E//p>M򨯐PG7lsmbELVd|z-{#oدץ0Q@5W3<l|#INZeNF\W|OsD\Ne>FyRSq δ!/K~*z@"(f| $e2|^_#4GFcb xۃ{ŕo4'0e@~YGb}h~bVytTo˓9Cq>U8|r9+ uyR1 9:3ҐJ#nWgY<©43MdW={|CI@nvTǟ[C{?YK.啕@*=)1Jk%޸nfk:Yby!te3&QCqC1_̽ޙ)>6+;lE`||<ՁƧ;y9X~H}> B>avJ?_ <ǢIcB{t~ޮ9'];7Pes_ީY$`U6zVɗpsٚx_+fǞ xk'=c~-f=|ÐDќ ߉m5y(uc嶨.rV{_5f-y'y̯KԟH{ )v[qtUu^|X~1 F2Fq>BVmB0i7V/Fݔq+Mb&˓n ,V*Gpֹ'玝?o19PY~})BfKW/->zٍ!zvc#}.􎎷$P~/oQU/O ԑE^@:a[Dm^YӤ3zN+Ҝ#fh}^~2u+N@Hڳf؃lMxk%0wkGTWӞ۳|w3Q(OtCy{hcp޿-"mڛ5uVz? f-Y{Wxg6,|Y}z71п?{0xc3:mOneqkC_sRv h~g޲GƸ>[W{_Ҝlp^dKvPE ϱP  c47#;9=q{v$)n?NԬ9b83?6ez濵\@MDǹs}plU|W3w|YEόrGxwۢ5`<~j7PD(ݼ@XMQ(85&k! U[ԐCE'B9gdVsiTuw%yo<`U 9+a]TNB30:wfGd JqO<Ȇf_E=һfa.<8n/=~0%Z%_FP)[#qN0n8!%U\L= 7OcVAYڥ0 vУgs Cif1GT92?/'h>[Q9|t<USDnPyG}GFI50E;4㺭N$,j'*:D8>|Bm y)#۱'{o `c$ѿ2 >-En^Xqp˓O`{Qzou /B0yLdy`#{0zO-_fB~HovD`|{kFvbj/ϱJGsټ{lU>> 1ؓLnw jncb_vN ü|yA0v4Uk7L-VH]>:}1jC"C 0zm\̓=#ѸO?`^~*AWzO<₳YK>B%+?#/YBkS1#'O^|\#0j%723q/Wɺ[>\߼?yW|/r1Ϗk cS@1dV\Qlr!0xqY㿗uo;}!y_f@F-OrqVlP״^C(w8T "cȅo? 8.&0ږ?phk5݁ԛnsᤰNn= ɲ8ͶYP|Эd z6ԍ0P OV}) FH-{}6^w۹ w~t-~\XS5(P_~87.&{x::$t2ߏ PiSo2}ܨUh0| '0u_2g+p6ƞ|ۥ*[ϸ uO@ͤ]Ǽoʈx ܸ_яvb s/]./F@iL=ndoڬz (9 mypObJ"gW(,Pa6'L,08@=k.WfɎk.=?rh9:C'"nZl TuR]؋7!w/#{AKU)gڨ?KWMVi%ܷPe7r߃GtSxTqmѶiwfqZ}n`ȃ+ ZEk >qߺ@ޚF@.4g{Qg[]8NbB47~v+&g3ܐ7㝍ۀU--{Xt[ֿ\DZ)rŀo4[1J00ЗFr)Ó 8|PƊ\xy?iN [̋sce!0SdF#i؋|0mO;М5oaK8 }̂;[Ӵ<}ia؋\HoTDUqlqlm Eq`,LNsL?žG 䉘X XN_kj,DH/p;$4@9+ u&A.hcӜn4>=z1H9{`!Uޔ Ԫ-od.g}αzz[ghN7 ߡVǚ{2JQ2y/utpn;S4}×U ~6A=Y`Rr_.)ݛ+9P/U5:oeb} Y_w},{Lm<M1NC;wq E~6>} +P?8(ӜYǿ ?%Uٍ_g^l{C{ob?i3zv `ơsvIXi3' (,W L% +*uqgzrP`n5^KU[,iFfԏӠ@[P7q_Qch) X)T \w"來.A8}$Ǿ `εې[kbEN;~CұgKh&HE# kʣK'"Pl?o( BD&idCM@lx;n+\Ӥ(Hp54'*kF=!H/OEt*PW xiөϽe$x.ZyE}?<ڿOlEgqfy`|Db&`<0xVwOEhG1*r&]8L@_0:xV_N>byo8s4jg3.yiϣ9Z}cr"Ww[u0n]wYdq>M/vwky |W rXHFacIPh¼eyqg+.O>VzC/(cƯE14_  ]1kf.=Ls7{Yֶ tO2ԏeͱ'mɻ|aza5魙W?Sػ'X䔲6c, zL(?p\oٕӘOQ{]p -R҇4|k`hrf۩w`\|UN"j85?rUؗ?;Ш{ڎ%3^s9r$P~goOBnW8<ц4`|޽b, 'cx~fk ^<\RV ^L( ()uA!UKa,v.˦ٟn޳vmfŽ#m{P.Mqvt 9?Ny&;0ͽo&!we|+i[Q; 6oN]׽D0ۃ{H#,0xvs=اLN ѺB+7{KM'>[ f@/swOc -yʀ9v,0Ĥum ~Ӳ iI3@Z` tWmޱxۀ/?In/tsD費!1|[N<X--9.K i6g+cyK{#_Zwf@4J0N`.(03i6 Asg&~9~kOޡ`raܷ%YԄ>lF1=~4{ts/e=}Q EqDkE}䄜+B.Zx'c0.+۫Gs$wyLZCУ{oi\uwGv.F=2biv߉V 7U >w[|/ ]U '<ɷW&4;a {L\?8=׻u=utw =<JNYtQ+@q^_%s[33"ځ] Nx䵭_o#7d> =[v-w?.A|u&5Bv+c7Jd>0*WRIw ˂ >uB́JrK_hG\k9T\H>< |_nܵzʰOݙ [~lOoj3_rx/~f+'%nr a/a%LL8On|SGjoԵfm'ߐZ0%>< \;O}= {w"AGOڌ\ufs>vH/QyIw?i29uc+9Lަ6/sQ ꕼ 8r ';Z:p&A-Xy&pu2Qbl fLL.y! 8iyy@v&^[NsN+UN`^ ),JBTrxmovZoV}>×@|7y!~Uu笠P\ZֈLٵGn94aO@l/r#ӭh^!rq?a挜s8ௗo6%Ϝ[#qޒNjWF|]gi%zST಑N-VaZcu!-VF]ϭjl)rt"D9lQyx_Nbm0jBݦ" v0|Yq8W-=u @ݞ_I楌.sܡ@*wltU,퓬gTxk d͹kuvޜJ3n')Iȭ)XFwh)x?[L:ߙƞf_r@*2y^Te>DLw~|vV҇fܓdDn./O7ijaw2jwLn^>wOS|Жl Z3Ϭ S=|(-.Ÿ]>ƠkO/g4o|q'724AiY,ӆQr^=[q.'U?`۰% DUjfF?v<\^>:b2w'7F_oP՛Swm{2%S( !3PTI)2eJ2!S%SII$$dV>w|}q{u]{fl K-IF 3NxЎ`_Sn'0zGgNcZ{(-~: '6< ƶbr{?p(|xkV eǿK1RS#Ӡh|LZ ۼ5f5UwKK<D ]@ 䉯2 h96f/KyOc@(bǻcɱtn ұ"乗+'WKlVt[b hߗK`؊>v˾^fm`l0;nrS/fXk<Ҷ*`81ԧ EG\U)>x='ZƩv[EC>2=ȇg;/}_DP҈se*N_Mƪ=K5@swQY<F>EʪWV`[LVEx_y?u{o)5|8*~ X|m @}1/ucna9u;N\WqX}+_[짗_d=Rqs:i),,z_^ Oy xجRhI|.pꉛBGw9\` i}%R+ץ=nX]t/!\ єBp 0^ŭ~ C1w꣆'lml%<WW'x 18rX,رԝ^woPEncXŧ]π@AJZR:^v ?9#Xng S%EBڵ@~භ}XztUn97?U=o'˫ˇ^6uR`ZÓXͷkkG@K{aHf ')2[7|Go J92Gg!4{_#}.5(@fjSN4#3nԥA=WCK!zOA>w)z3`yq%c&%0zeN~!JaNF7fJnpZʭV`Q&tIڰkۛn"sN82eXwIk!="Q@EE::oaV,bs/ 0ߎr1YX,q{q9?XD8&\')(aՆIcl_jO]`餷-.y}}ɢyMf?uprN/ѝ'u`4#o*Ew2*wk] 7L#Ϝ͚mahz1畚lm OY0qɻNϲ?ݹa3!r|v?wS7iZz`yeo3`z ԛ疒7m'b.ܣA`RƳ8wl{dڵ V>y 4N~-Ki8/]<:뒏׽& ,> -NHIIA9uX+L1?¼1jlB]K] WlMz+nw-%DOtZmyk@z_ =m-PSG@}, s"`e'U@FH%œahzuXǗB[T~>d N?%$_"8S̱@gkݚ-/ {r}6G-{\X_t--zS#&ΦXw[^8Ѥ=d'\uhJ"07msL u ]?ms3XLnh!޽%?w0_I̿&ݛ #vi!6 i֧ÚB?ΊL\3~(c~kRB\ʨQ-&pT|U7~y ԯT)W3yG83O_ةb-p};%6M?X:m`#_9BӇ.'M;z/"}(—m]ȏؿZiSk }&˹ {x%|`uu䧨{/`n`ffO|]4@!InFq[c),vR~pihg'bxf/Ѡ@r*NA\bp;C) >|{7hk9p|؆%끫bt6P;ٯ8jeZo6XE@1 4[ nc.4!4;j]8/]szK&ٷ>7[L]F`<)f&1|A6H$bHKzEGjpX~G%vU`l)hCp3FoI-xh]{4Gf. uC˷` CXmϵqoXKu{,]j6˩QTVVC#Z }U,xX#0/|~T+oM7L{CcvH9MhaiJ'ŁUrhB/G=*{f"ulr* Dl<% G䊺ӳg)Kˀjwͥg/QUḃǥ/b?=~QH^ZNۘKR5`nU<jgȮ<[?[ul]U%"HGOr=*aCfsHy>&!^1,xǁuAa9qKZ#hKU>KG쁞,qO{WA_ sjЀv_Z$߾'[(jf@+9dM7B0}Դ[7/- QSAoImGOU1^x}kt.}3D;ع81,CA?Q@bRP³ ˙*X5tܧVc--mrn"G: }?&Ay)IC}ǗOzQ_`[)?-r"<6O` *pچŗ l`muZחLq#sTK8>AmC~c#&uu]S,0/(7a? {Bv_*?ڀX]vZ6w~QqjG:8rnGrG'Əz\dŽ(`N_sL^St8UzPHT揙ZɨKly6a" u⋽c[!Zc/6&_>H,q?ydOa@Kl>znB:j2`\(jڧ2`lizk؞K5#\ƥ_ l/oVmzܕ5 \W6엃*~]Q&V87\=){ǁ;wWsaj[pkf}7և~6}rT)\Xȅϻ}˙tꏟmZex}D]Ed'J"iWgu(DžYqC7' &x4%VvFVcy+"휑 'J5Nwm ٯ_gK5/$S[=@s$棡hbwE=)k|݂^YM&8w~Gmn̏ +ݦ[·-8~Νp/ t9 &GZ빓~mz\XŬ/O\nVHGyP³}1?< y_4yo{-UuV"c;.3%;Uu.̵o\/:c7˴Nk#1( i׎fbI]j)#ت@Ux _6KݸϙR!8f: dh IY䶝;ӀF+KX4VGcrLu0{`  /72Z&Nm&Udqg#b@%SrsCh.O`n[m41;̍PGN'#fv>FvmQb4h̑NUeѦX"7P/ff5}ʫꠅ`r>:e9^IbXw2{MOT>@fs&p/#G k8h˵.v;4BaޛܩtY!,5k195a.֫&I8* Wwg5rn9KaޜvBi%tPc= Vs@p]6!6^}x?@ auJREKSV7-.sy/ Cm‹#ܳn Ήm/=r 2/(@sz Hrֈ @H~1 Z@Wn |GTh!u6st>aȤѥ##mAB qoH¼u!$6̧)p:(vkJz-{[w2_j_ik\ǀ<   @f+U];݀YQ(RGgB1:ܲ@-#H:DtH]=F 䊞S|Yʫ` eeU|E :W$]{m.% *-S,PormZ䩏!@u0%_ro2հ[Xh8 4w|7jjB8Z t@Nq(zV+|UWԚix^M@5UW6ִO~'Ns^ӯ7d* iDJ}b>^n p,7"qnb }dG(О0Qp}%_~j RE; lG~@ykvD ?n ^{gf"O+$B & h'.0)tJ.zOphy [n'7P'[^W9m/"QGzVr|1M.^F?ַ 滮 [l8>L|sBRcl Jotf3{:Zt)~6kXa-@\7#XFD(?s3r:XPGe_5-RɅo GLzWㆳ Pl>$ϕw7ݮ1'-~- 'p.C7b9,6yP4Y 9L44j@2}G/ 0i|P_\POiMf>5XWcTDX[80Y(H;O'Ѐ&[~Hnl_}jl#'ˁtّ;@Aɳh#ߖTu{|NV8 2I[s*Ki@^d?JBP#'̍:9Ա,sCPeDN+vM/GuoQ,P +6j]_Po7|y0jq:>xt g}widˠ19*_σ>1b]6ag(@{[`0~}Ҁ/~>oymU9췀2c@^ mV@ԏ,ͱ $"\w! }UovŲ0.zpHI?"wxC. ]r^|~ʮy.6 njԭlk,+mdQWЏ CzsgeGߏ_5ҿωW宪 ϏI%2bg#NEh@IِHVs3w #r"X 6|;g8w7 C]ČYЯ'@<,v@4^BN{< re%݆@:0a{,3}1C<<8'/}R;g :ԽmL)>́9ur=FDnqyWO ~AV§.ٸpkM {#Gi_w@{=}gcw^,NJ;g7B?< N3[LڰBr"Х2 ^ W = 44sWor\qwU[kcqy _̣o[ .>ЧYZAFfvO㙂8 ~?ug9pQ?R:T+Ϊ;PTp뎅"_Foaă)RC#Q[f\`" kW!|{@8avR 56"rz(Iaƃ/|:^. @, w)j@]V T=0ǐdt\ӣ;F. 5dn[6m:pE ۢ,Ie [tWv!kkM nר-g-PW"a D xq wO\)6;쪐`zGf# 0NH>:hU:`3뼷xu~h)Ko!DD~8xTُ usvfcq@uH,IPd,f`>{i\1X뢞+wڮi[CLܰŖλW+AUaAU qraG1G?׵}Hz9=BLCްjxLO#>"aQ9O0$?]c&yK%r3C9x;u%.G]=8s wļGHEs ٟCYb%ޟ] iH:g!'ֻ@si,Տya3=0G7\Nzc}14[G|l9j}͟Zʧקl6Z oƙ}j^~@6cmGߑa?Ka᝕@o]%8/Z펷XvgU&^t^k&"~XƤȽYZ$U!~)s.۹FCqZ!3c@2 NY >a)ymA Tssm:mr߉o8t?*i)]$0}+? XK&e{ҁaY2P ߼9E0 ;< S֣x"^Y2﵇ϷJ,j|?Tہ=E@W|"rFPn 񘶒wt":Q]+ )/NVe'cn6 Ջuɞ8OQoVjռ@ W ik#yKk@S9qACQ}ofNoȍg+lJ|DZ-<|)4<:\JTUk^>] _驘6h22y^UJہlN$mOuN o?6Rʥm'f30;~=n(OG~ԔB4 (7WL>q--N?Ümre(iG|ɀ ԓ߀|,8xs]W[d%{_g ~~R`W5b%8?lta0\i>If@ ?[ G2΅uɄ@za>o_[eˁv̨P#U[߇%t;f#0/M4qͯ@)vM-@ ̉|H?}֧\U @4r?k=Հ^V̻W`E{rIsUjےܸTr%xbWrv8"~OhпA eio-ŗ9/QCmA 'J&9ǁ Njj*ŰyB!,j(WOۊ{w]*;sWZ$5'Cᩘ?wya)uHDNԕnɖãqM'9(ⷧ)?6iY_xucOP_f>Xtb?׫E@Iݒ-5ç- h,st#y=6䵓zuS\;_/HIIۙԋ8F28Á888'`Μ,y>j3XFQ>3`HUMP_-JQ7v{4Pr}woۀnhda?>9,?E]f!KPtT8k}/i~ξ}8Ϫԛ%ei~π0Ϥ8}U@5Gwǎ?|cg)=^cy?G^n@Glù\(> ԫ@wU=Ρk@a\slj%SB5o.1R  zī:qneR O,e&e3OQx_vaV;uIBBq}vwʭtH&:,\ M 4b}[m Ԉ)u^WCrTQh,P/{e4E,sR",f,]@)LY*Tޯlu@USbQ󋿁{r/ yk7Џ|0Uu7Zه>J|(Ȋ6g9m} ej7ql$9=R/aR @?iR;{e=NkGZ\ pB²Kq>ߜ\Rɋ?\@z?[qԿZdϮ/?<kUuw ?vhsIYW^OE"NX)]հx{gF$< }) ożyb{Jw0>_(ZHz1O> ^:+>PE= Rs|I ofY -~ZQV1soԯ]ϟ;Vap;hU,o&DRM+ VQ@*z?\cmN{,h{| 2@X#[6x)4\!KbK{lMn医J%u M԰e g@zF?Tܘ+l К^y`1@=f諅D6 [0zx F6Kmr7&l209Th*U$V#Ug@ KM;2Y8W/=.Pn6~|zAqG=wvh:t6z(@ɨفl1B@ߐI=Mۉ,9˙}^kt=׬z ?ݪVg@ңZ@߾ݺĉ}1Ρ:ٮk865.;k0Ce9$~* Y̎1dMNEo9rG ̡.gs.8[!:L,8shk(jm>n{#l"]u|0=Д򄋀ʡybU]y?W!;%eOe79\a104 ;)h\.w9l_Z-aġݒ/4:7a~s #Zs|Xi aZo%Ãx|%?gm:Y WGz|,M(:J0JjCC;.=yTՏW;1GlVC]z!PU{љ&`E^S@/nK0P~E={s2-o_E?dyBra PX}9AR)+@Tu q;Ĭ_ ^~u/z)+*'>!Y=sW_m!&(x'6x]eB,P3ՈB/ώkƜX`K؁LZ}g@$MCnuׯ$wM>eo}))ԝIGuSjbG2}5u@Z)ɾ$oUQ86\z E'4hv[dӚ1gls7p9@ .Z܂⁜:f9,qAP^TN"_kF?ة;_yw~ĠN1K Wq dnP.ȁϕ CSU#wjԪ q4U6'B*`+}t'tWY+$oɼ|oZǗnWP5*~&3~<\zyNauښ]@+/#ӭ.p?*zuS .R-e58j$hõV>Fש@s3!T A[*`n!0Cd&_sSdMBvܔ2qrzȮCa>E@ռW^{ bs556p`z+N nCwSIrTn Z ш'r1o 'mt~sai+zRc߃\irT=(# ~}B rB}M 7_} h-MoI뷀~L/ Hə>t欺GVt8X5s(ql_s?TƙrpYl`ܗ VԻ.HUCm@nW`R Σkcx]'yb? '{-NW̿}߶TE>/K !=q^7 q~TȂƹJ̧8qS=G&s-}IL`2|OJؕ[ @={{ V?r*' ީ4 rhgW:_W=cV{dT}Ud`Pʵ70WDjE9u?5<?j݀XQy'r6t 9[~E,jo@k z:vۜ8K]9W;Ywإ1@^m#>^Z5 G 66<@VVZFj`UPe29Ptk899V{& q|Q'<KEMjܫ_rnkǓ"8Q3ӱ>:{-oZčl oysKy yPڬ]`I*ʊͥǰ_Jjlnq ġn|[O`C=k9,9^>/H|^$gu`G`]k>rmqƣΏ S$ꨟqr΋@sK!@19b1f4n0g[lS6mV*y~kr4Iw_:06:/FAs~!rCAtڀH=z̷:PmbNT:l>pqsoMkgtTZƳjmy]Q=z=stp"PNgЧy]:j8kԮt>;Y>V%~ȯN;y 9^lj,G / 5 5kOZݨtI>\0i7~b'6Hw08^ >@M 3VgX vr6{=y/)q!EX&K)L)BA9 5Cʸ,֭:|Oֶ_^@芵YJQ/ 4=qQ6 "up|ߕx4ӰZ@'ݗ=¸#-k ={(Bw?Sּ+ziu6Kul2a7Pṿ:!@^g߶; }}x~G@=IǼ0#]O~G^fGﻟ*JY`n'-'ø9nXOw+df}\-K5i&7YLHX CwIDH _N怞LxG Slz;m%7F*)ܟeu:[(=ԡlbe=-T|P3VrZZՒ1֫c "_4rE]2 ugMm TW7B@ZesLW/-˱$i-ͯ;s\޵y?52rqҁ9|=i?;rt^fPQs|OY?89isn@ښmW;u63S5}gcN2^])>l{nOvtɔ `QdAMB,C\uNϤiG0Q=d"2UP?_W-ɀ@,Fv#ٜ5LM P ջz_{`*lz0^*_9KvHJST@+I>q:u淊+[ϲq%YH:<5;+^|(iU9-Tx*|!I>E}?N{1ߤ픨}4z%_[HVZ4цsbh;/P6՜1|V/wT`\Pu%nd }LĜ#F(oyv(c_B*Գnf쫈,]Ny =zv֑uܘWNO)v_rnnbJٺtUkhXbcq_as0]1یR#oAt¾e㎰&ƛ'b$G#'/[~z7~8]hyiw;.+ 󫍖o H@mwz\Q{?gzc8Wr4H1' aUGO =܆h wˊzX/K+p? {=-8|  \(.wq$}W>Ps'|W;e/QΐIBJ]Npn7M.kKQL!6?nTu+I 4gks@ibP88Oٵ 7Bm#{ zhwяw]B}/0z{*H%jy'IJۑNvUY?qv~s>@sm' ]qj]dɄ@#7] [q9MݾoW7/~j#iGcCu0FB*Vx<ϕ1wEBb_.z0˃ C@ej/rŷMR{[1X Ի e9d6@\zDCj#Ө몎͆[?Q_hh@rZS;\%'9@^f0r9vxWT'D~'Ql*ZP~: %S(\Mz\Y@zr_(U?Ϲ4U*l N8/>of:T b*UgOyrIW@BXU9Ԣ\1pG% Иۓ)z36dU$/Dݿ7Z6*O@λ'`yaJ1EȮˏ]zD|x sPa|7)y;|~Psޜf-ڈ[aA^1?}$XYHVRx .ˡԞk"R@lKEXX{= u#@mNYtjNº۽? Yfv<&~X!vs.| o/.dG$F/@:1qSh6_SI )F?8#}LVr+Px~x$G_qߨpҵZqׯQ9c &v>| bQ7'о;v}Xw(S"/[k$.{ ,*b="z]ꁶlgԽgHMWDzة@׬&'bא/8쥁^-o\X<*wE7ȍm52fpf8 _qp67Hkm"\Yd5l(H~jy%Kzι}\K Sfj‡mN @ѭFڀs37{B#rg"] uN`pt2Z}?~ 1 h @weM_ {]~v&iq3P|.h<ր|\,P9e+Gin@Y}fN_CObG㗽?ys9 & I|]\X<~Q3PD؜cP]XJmϪ!Fϕf#z@ug͑2ȃbJ7~#MlT,W" 7<"*k[!PRQ;@JAE啳+d p Ziڵ{`\ ܀t9nnP븙)="/r.<^a}Y$l'ב?t!'k\WvDDpYC@ :KKsy[VG*s/@p=+g۝M5b@N0%odT5y:CC̫9u@񨲫?]BKs,_0}ݸ o_ ?yρpMҳTshD< {ֽGx톴y֪i =Jg.gn3<?tR)4{ZR34o1%s8i~ZS ֪^Kvr;pw9Z0 Om6-Ls塪$`Mg.=>u.H>ǹrd?r_;f% {Ű4V 1Dlb@m(P8 N<ڔnotOUgٴ1N'[DϣDW:s1W 4Ƿf*G 4P=Dہ| |9YFG:X6>YҘ˟fO?LNa (>Z],jSXi HV+N8pXOVlj+K ǥ ^bsY(sʰ ǵf#&5CG ȳ8z-2q SC)tޝX0}$iCo\ÁWͽy}ԎK{6ׯe2:D>!6Z\`?f2 :mv l=w t`W[d.ޞP=we;\_BhjYp\̕[8_Y-M/B v9ۆSi->nLn,`Tbֽ96#0WwVj~"&'78+a/)ohmcw\%S . { }r5g&"5RtٍV8?Xm(:@ }v^gqCWshL?+`ȭzzם;̕WG'T|NrA9Q&S̕k}mh9kuth3as# 癥פd7{-vk i.9pή{OR2WԵ^dTq|(DY:^M=s9 gu\9w3sn z Ekk$OA5)* u|'vmU"wė@XAΑBh1]ƺzMrEc e t;{q&*K/ 3K9ݴqC֫'t !Hr T?h:HOWW'*…-wםp1U~+\ _w;KV''o$kycxPO=sSrꖻHNvD ~(y!$\\N)|'3N^\n ~,$(K 2?K@˛p?{\wRw9i J!H=fm֏w97_Be=R>@ۢhEc=7vҰuu{Cc@ܝS:0De7Y\e.{q^/e.//)6eD K\&2:ʌ'w>Ērfמ1[gODWPFh,-@V A·9H]Gb h(T_+_ 'gηyQ% d Z"\Yhr6 ćaR˓F_4vCR}טwV$8m$E\@ 1 w 49! p RȚK<)6?kAOՁ(-#G_y̕sN뱟 2>g?aﳹIv|ؗϳ/⼹|\OEnۣTQjޫ䚙"\ӉkQK%^ I$AD-0wAKT-@Rv0U<~pȺ,y it}6v-qQ3ۀw]+v;>䧾/@"ķicdoQfwsj5DFz5>ƃSeͣŷGq oS3x MN@4rA>%?v Xm_݉ԕ1+NOr? GrXML7ZNyX2ڞm=@23n7SeJ䈸療̕ݷ_Ր_\9>g.6NrwbeV ҏW5X#ts*2'%OwxVZe;@Poz:iŠuz7acDkܺ"yผ}q9i^\pjm=21m rʥ,&a0ws阭\\|!򷏖wu[)WOzm_@}s~8 ĭ/)[?\w}[5V%c{ Ć ^)"\+a$|8Fo+G_ ]yIa9̽O5Bgwԩ}؟=h$I%CI̕B!Φ;chPwa`ɂ*#}ا)U4L\%RzM~Ls>ykEc4E4sTr&yGMo7ݡt1ϕ49Tg.m^q9s%iC@x{&hUCΗ17s#7>0ܔsЊby|%{;Oqnsɏ)rRoFvD믾̗5@X>ae9QK4% Mx{CO`.w{4be6<\mvC#sl NXy4S~8WٴO#6so\5g <0ŖݛuS@r|+rjʆQ zs{}X@m% gu{iԽ:@ssۀ']eo[5c| )s-e`4 UKg4$}/a~0ԡ 6cߨ:_9MVI 鎿+ DȨQ_?ib1tD=5&"I߶gOO~:,nz9tޣ(z[r܀``c_]A#7ƑM<̥ ,< e98zUo@nMۚџ:.ۇGuS2CaqJ4օ{hl3)3]丵菰֜BasŻ4)U׽ HL{?an Ю WFͨ믇J4P'mI|mV{b{:37|PݍI'lD?PpCySnu…Źݎ^@ g^S/wޜdFºV 9>䡵wԀxyPVfsr4 GDJosQbK^_g.-bx#E ߺv#kUy9LuG%m^c^>4,I?.*E`2k si)v~闯 O}tgt ԽؓPυv7b4 E];,SmyRy1KYF,&?ڄz@J:5j$s-^dV9ˣa0^@ۤd<t~cj >sY(Le̿i^oPu LV:ۉ=(.ܟn;u:s-.=@,}OĠ@jJ-{w"Py\d+Hԭv̹5jGF ` al\%/ d~sI9H mMe\qpgIs9{ϜP>6/-kq?c ʩ;ƈ``Ef)9 И LWk}m+.S L 쐷:4Zfs]gS mөb;ڀ-[y>?r%pöuX9Ls 5hDu>W4п5v^f~&_!Dcr>ȻU?TD>6Ą>4nwF{u jT_T^.wsimfwbxTW.>A|Ʊ [Wuޑ {Vn>ZMǰW_Gm8^$)[c8'#d2U 9}8-Λn8Bv- Evc[./sq-7Ko*+LcU :nw/?"9}L\zˋ4<O'+̕EJ!̍s;jFyGx@,0y:u=D]/ fYՁJޮx`e.Ϭ^zgegau02l#=@ |ʝf\IJ9ʒm#Vč\o(2p:]_syt^ Xwftk+}T}H<'w#Y9LWS@T(b|Ѧj:y~\d!8? R8n˝{Y\quC_l; ZOQxf /JjKq)e@_7k̊H*S*#Ai )o.RyW &iwagKn\uwz!G7S*>3V/h.-VnDH-)g52~v{VQ͑SPNрԽZ#>X[0OFc̉;\:~E=sNNb. \IG%X'f /C0b䘞>%} gtup 3dt3WflZQ6ґ?/]4Bk@l6](rT~:Zd:qw>YQCŐc>Jg"+ U}ͪ=>gmdx~ێAvO7ɿdei̥ S񬮺$gN P_oGn165w}9zK Q#*A;39#i9iٻ@S*R"WEQ=ee Hӱ;K&v2AqbA#\ݵ@Z %7bpLtm}xryO0+f Txı m?0WId '"u롎݉3&:-@! nGŧxy9fwig} ]ifkFg\@?z63cMỳg51{ʯ};]9Fͽӌ fʭ$J,NĞg_"~@ O`HXtX' C,R!AU lp6w3ǯ"$NY \S$Ovp%RBp . j g^gp]H@y?9É]Asi| ҴMxftޏ 9H4ab% vX/f Q|B @}pVetS3tU7CC>T/c?V?O2}?p^tCUMZ7y?| ~ya~G\뚜^}p=;#b#@tdG>Ա|(?6,;r:^/Zu8>4S3W~i@LxXDۣ֜5ϯSb9 f,s(~HDxkƧ)}:[@ A"QU ֘}{?MW709 nvcO>V׫}軄7Ю NW9{uWjvv@U|Am?`G῎y=_ﷃ:>\?y=~}ݹ۔#ozd)ܴOx8dr И_%}o{KlQ*sj܍1̯JOsaN57JN}e~ I v:0s|5-TB܅۸(2[Bژڏ'}V-fIv?1u\>1)5[gNcN+ݤgsm5m!YZ~2vfg;r~Ǽ=x f%6n)vVH&a3\TT~ˏƙy30020piּb ClT,14(H,J-ɏjloo/tests/testthat/reference-results/E_loo_default_quantile_50.rds0000644000176200001440000000014713575772017025203 0ustar liggesusersb```b`faa`b1|> fbidGX@jX84k^bnj1! ,K)Mr8 RK㳁/m=tloo/tests/testthat/reference-results/compare_two_models.rds0000644000176200001440000000017713575772017024121 0ustar liggesusersb```b`fed`b2@Vs\orߢ/,gd`aҬy@X3D35 %>%3- *T/9']wr~nAbQ^N~>T??'%YRloo/tests/testthat/reference-results/loo_predictive_metric_mae_mean.rds0000644000176200001440000000014414411130104026374 0ustar liggesusersb```b`abb`b1|> fI1 %t59@|N ͚Z d@  rd&BLũ@PE'qloo/tests/testthat/reference-results/model_weights_stacking.rds0000644000176200001440000000010013575772017024736 0ustar liggesusersb```b`fab`b2lk#-:eW3.loo/tests/testthat/reference-results/relative_eff.rds0000644000176200001440000000045513575772017022671 0ustar liggesusersX  ?פ*? j?fq?80l_?%w@?[?텡3?\Y?k?-?3eZb?Ŀ%O?|{?`{g?դ9A?5?̈?|?B$?u۳$?WIy s?t?F?3VZ?)쌜?7Ml?5X?|Af?͜]?슑E+$v?R~9wD?NvLȌ%vloo/tests/testthat/reference-results/moment_match_loo_1.rds0000644000176200001440000000327113701164066023767 0ustar liggesusers{TTE/ :JY51I]Q 2f|(]Zw;bI*\6D ]\aaf`$i)!lmpo3ܹ_EQz%Mkw}glTG-9\(v "% @|rznˆ3(l(dl/%\b5hq۝syˏ3IBږ}ZJG,!Z*1Dg?JYߏJf΍oFLoS XQ|ܫ,2@!9g|6gAyo@܃^*-gD[ .!wCDdda Qq6t?YMaM2MW\ LtG]BϽ}_Xu[[ZB %/fcA5)5lկ.@+ͷ4z{Cτ!s$Z b@u¤D,rzwJLŷZ:0=80@}ȹF5L▓c|\mC@_Hϳ3tګ',u 5x}];7EbtVq@έ dQ+h+,~;z$>v4I\lwSc i k\4ҙzĉ%֭# ZY%M:J| H^\J̐kn_>қuXKDMӱ u [+#q[ ` 7BK;N:-[ݍ֙Gy =ګb<6^g)o>OZzzH<,M=LAГExB3t&E؂k./]ӂ qOC5MÄG%3\>)7H2?G O~>CtJkHDʤ*F&Բ@B;M^`F烐!v?!ǭ̎ ͊;`]賛k @.er߈wBNYљCwtȕՉECg7$l2[zۃm XY#fi!яr1ztax$eJ~,UE['Z̸5_u<уk3)~ _h-F֭Vi-%P&YJ+?"|߯P>eбzH]}|$Zk9' pU2YNfT U' loo/tests/testthat/reference-results/E_loo_matrix_quantile_10_90.rds0000644000176200001440000000160613575772017025370 0ustar liggesusers]mLwye)Х0`Rp\`C ӉLA[)/"Ȳ1lb1KnP%.")#d> n+OprιnN~{q¹p.Q9#e˳yf+Gfc'TEj]X9cw*GHgs, !Ӓ*B:,}9C2&?ߨF2HSm/(F"=*s_Bj򞒟f E9D3 Җok:0)9}7k8I̐"uRW95: m^Etlj:¸?xvwL>-O@׃O|} 0=þ\G♐fȱ)2\}Xy!'XÇHs7h&ߊ732Rqxƣ6tT >IZdW҆8s<iYRS;KhW. :TL|t.|:Z#S,\s_&C^ц ?T鮁Iwbp7viRֵ탫[Oxެ;՞pz:}VBI4g`X<_=&Sb0_Fu]10PZKC^=<Ư5ZtbFK&f>_%pϗ <}̓&X]"܏+>qX/deQYBY`qxloo/tests/testthat/reference-results/gpdfit.rds0000644000176200001440000000013313575772017021504 0ustar liggesusersb```b`fad`b1@&mn?x}rҮb``a320piּb C"Ș -LM2ܜ]loo/tests/testthat/reference-results/loo_scrps.rds0000644000176200001440000000032714411130104022206 0ustar liggesusersb```b`abb`b1|&>#}w~:q @@qFN ͚Z d@  rd&BL@bzsM_w5=頺GYfo 쌪ɤBDJz]7++MxXlq4WpB]Q (+),NU=loo/tests/testthat/reference-results/elpd.rds0000644000176200001440000000115113762013700021135 0ustar liggesusers[HQ3М5/`,D=$H=օ Z˶ewtVjɰX!z كZ[vA*B Urmou_z8s|gXh^0=י!`_%,1kg79' cUd}!0QLZȿ`gZlD/*5ל. ?dvM!g&  LꐍJcX2^[H(?wg#vj!DGEOlٕXz-Dx?D䇟?U/`OZTI4 _W=Nook M['RX4HnAۉ3/dSϝC$9kC:&J3ÞzG y= N TB~2PE~P2A!?J~@~H~PNPA~$?'?82A&?(jPA~POYVdйA~iEr](BlWnkV ƒΈ hhXnLJͭ>G;vhaтHſWloo/tests/testthat/reference-results/moment_match_loo_2.rds0000644000176200001440000000327313701164066023772 0ustar liggesusers{TTE/ ("h3$(EBm{V`n(HLӲ!aBLPC#= kF"GsWNsfb(P#(5nZ{8c;:*ɠsԸJ屷9Vc<)F(~h22 GK`I0EE'1\L"+$ռeKDFL !9Rvu`Zm'K-nD~K+{EUhyXd6 ̾ȅsP$MU/xD= vdumEds7!uCZjjM}<@~mvlLװ,/d(N{GԷ<{K o"s~Ɉg )7U ӭ|?_WSV[u% i1 7 EYKQWfSπ x]p4xtٺ˗34g2b@ՕyFQCH}νazJ#^zn"wyOz<;,L{LQ2D&@lj ظ|W^y@GY׎-?0jRqc}#S4pä:4QBg^c,}/ <??_ُyFo:Qt9aju謥VVJұ}5cor//7Q +$a`:3hb~\lݮuۅD,/a~#>,:^ʬ,l7vmXok'Ka: ӭn=G:a#t}){ΡK3F)(0g ' f~6﷍p>ԬbjX84k^bnj1!1 ,ȑZ\X 3tHqloo/tests/testthat/reference-results/E_loo_matrix_quantile_50.rds0000644000176200001440000000116513575772017025064 0ustar liggesusersb```b`feb`b1|> VbidE ֜v޿HH Ϸ> [穭Z+.uWۃ'\ҝs07.(cڿ N]:[_=җXo^D_zq-_2?ZkivB}M\Ope_MwƶSkwo>u{Ng_:G w BoL̲Mk;>Y,Byv I'ٗǟx2Sk~)޿d=pqzsY~iѬ?7m9v$҉kN fOz卅cP YsS a`AĒT(8HOqloo/tests/testthat/reference-results/E_loo_default_mean.rds0000644000176200001440000000014713575772017023775 0ustar liggesusersb```b`faa`b1|> f0D8ˏƙy30020piּb C*XS p$gotloo/tests/testthat/reference-results/loo_crps.rds0000644000176200001440000000032714411130104022023 0ustar liggesusersb```b`abb`b1|&>h3W|%2A( YsS !`AĒT()Hb\,3u^Ԏ\S`~\/ߜkc-gG&8/\˹*jd#/w<q4WpB]Q (+),Nloo/tests/testthat/reference-results/scrps.rds0000644000176200001440000000032714411130104021335 0ustar liggesusersb```b`abb`b1|&>#jwwܛTgd`aҬy@ kqIfnbI* $1H/ ,eTybW$w[]ߺZ0n]O ޴ϟJ*½76aio8?+8S( g敔g\"loo/tests/testthat/reference-results/gpdfit_default_grid.rds0000644000176200001440000000013313575772017024215 0ustar liggesusersb```b`fab`b1@& !SԾ3( YsS f c6L83=7m]loo/tests/testthat/reference-results/loo_compare_three_models.rds0000644000176200001440000000052713575772017025267 0ustar liggesusersb```b`fed`b2 爫X۲ܷ ؟^[!?=q 4l;D%3- *^̅ȗ'f&Cxbl f~W9ǃ6`jX84k^bnj1!1 ,ȑZ\X 38Mqloo/tests/testthat/reference-results/crps.rds0000644000176200001440000000033014411130104021144 0ustar liggesusersb```b`abb`b1|&>\Tgd`aҬy@ kqIfnbI* $1Hg/g(s=3<-(x^*ҳН;=v+:Mgņ3^fUŴ/y>+/Zq4WpB]Q (+),N?loo/tests/testthat/reference-results/waic.rds0000644000176200001440000000171313575772017021157 0ustar liggesusersLSWߏX_KAl8%l4re5JZJbPm&B4mc8DmH"M 2̘מ>޽s|r:NT8AQhdWFG~t JmIuJrew'l? a\9c}7(@W!?toYZ(MULqsQh̍KеؙwقuXmm_EDb?GMM2_wC5&.ֱݮ]N9k]tB_ؒ q~/g:{56ļq3>~k:Ɯc 33:Ys=bء@&p|FV;;Ŏɧ+Ob 5Ve +nT`GvJ;D@A"''Oa#=DAO@A"`$0\)b?00yCAOA"@!DiiL Sq c0-8j"#عي<:̨чKykX V0D r_"7yCd&&mި⧟b/Ubdox0[&,V_+i_9e?/J[C֟ۿaKElB&n'y3~҃Ӯ$d]e;Rt^`ûYW /o晶G%g?fr_]{R%qtOP\eSgjv˴/Wh#ܰwGQ!D[xߤp_>m`pqzsY~iѬ?7m9v$҉kN jɜTV8]z iǥƽ`},wp x+N +s )?lvҮS@Xo6? 7pV-F+%Sd_K ttJg[0 alU՘)'?X C$.$o}.O=xϞV0clCf3iw$ϛpӻJ{nsP\Q f"Am3<t?ٵ>/WhZS˚kˁ\w7[n/uc2`~Խ-ެ4@_ )=Q+= XRT=L:vX'Q^t9~Nn7S@ﶝbx\o6klJ śx~(71Lɋܓ_õ@n~!h:;\OK>Sy`߾4WΝŠ_RwRnLrnS-!vZYX>ob־/3Pl^ FS4."n\ ڮM}Š4N-+֍q: J` 2|{o"wۻ?]y+>R(E:{#M &]y X@}I`(=3=;̩>'KN()~ ^' [4n=?&= ։ݣ߂wܒl8{G=Gw#ϣA;c1,8j_^cٟo`r2GWr`'Apf z΀KR4<b0P)K7`[5 Ev>'x|qHf]p -l4s?^>tR}*jC 0k Psm5rRBO-f +0m,Pmжx 7AXmX񫭶2(1/e êV4nCӤ3@Ӛrs̗ɿeAx6P}0?Z8jn}` |,Id#x/o;g&de\Ǘgk=KٹߓJx Lg19 .F:Pf9)6Q>';+ |&pjzK75}rahʑS悯yI@|il N.m6Aٻzٷ{3Ao&2 _Vq0'.5C=;r \.7o}q 3ܜIKAi+x0lZ`{5_TF!o&Bs'ELiù7n~Ja+E^8ᚸs {= Ȟwٶ h6:zy5SZ=~S!X= \uשO&lIwϥ/o{vP/+w)f4'ON[8T(| >uB~-w;AqcYY9N ~bpښ6AӬX.f ĩ=}s!h^zUȹ/R;`x4ܨ`,Ź78JB[awQ[: UC{o2/_[/2{oUNf,o`$dܵ{@¼udO]Ǔ, $.'/6 Ik>TA5w`/}ԥdv]ɿ:hyK:xJn}±9`>o]̟ fYEVe*ExI%3 4+cNб]} jOȞenZ?ɉț6V, 8pρ֜ S[w@i-jl״b^N.1?s^l¯ZƊ- U`ls z=c NC87wlbF#=b~KӒ>>C s\G{r!0cf1;'Ϧ&pܻuhOu p#蝶?U7'0 {6}x`ӕ'=ոL(t0X2*q^qBʽv3PG+hwIyꊜf` rU3|;@{O]G3V&˸;zbC\i Kܹ88K_toQǗН=83VTE\Ё^OG*Bz6^YNWn2 &7 os]x̦W[_=t_^8Mb`kQxOs?]9BBuR/-Iص ]EA˿q{:1qo'{)89 gor}Dz3NݽGK0oHXg 8?׽@k27{N6}}i(enCM) MZ0Ko9nLT#Xr+}% $5 c:|8z$SOeyd^7(t${jצ,Gd:/ @R] ̚g߂=x1AUn+t>,LU}U3IoF8vo ,.{KY}IUuR*@;W}qg8ĆL'uԗO@b 8g͎Ǡ&J @_rޓP#u{93i{/80|ݮ"A1^DE>(mX%Jr]+|@S:WVIW8̗{# U9W9qrF׹ 'R/߶ޒIyoPҕ\vs9E̕)u틏J`砉] nO#+\_4Vn+Cq(#e{~n;Ǟx͎Nz>%y焀ž&%~3ڻ 0m(T'}Wե[]hL~_f>n@w~E畓S>,qᝥȩ9TV Y]~ W nϲ!6I-yU.}&[lĢ̻DLSb>| uiӺ~B?{${M ho_p|eV7xIUd5ifnQ.ˣ]@0%T J]g+Bg.140(3{>I>e?w̛lWCʉcCŀ (]>1g"/.%!L`{ .j]6@c0;A3/ /*q?*Vڈy7EO]A7lɻOӝ@H"\ YsO25QZ2 |xsp2&;sҞ}ayp5LGg*&$CmʮOģ/W()aK𘕏MyC72]'9Y{s8.2FT#,LN zw.{;SPTleC yАu;oڀgCڍ k>WeP%6wٍ'fD|vr"e&Aϳ*ܞmkCɯOv.hd9;g& }<:>P7_Ş5>S3q3|^;mA*\ {qAhد]: =<`ºA5C6J, k$mpԲl% }9Ok8(z 8GmN^ qJ3Yao~їM_}j r-.50j5xi.s/A1ZX \8UBfkDLq]ed7 1:7+dV9X-='vlQU/.VuC66צ.s!S)lci`~0 2whAʹ3A+<{% !K>0.\Fj`jԽ0/5:j̢cKyVUUO>ʫ#wvI6ޜxUM@ ٳA]Jx5?JkX8ݒOJi2)\Ɯ 4e: 공ehݺL9#EAr[%;ޑV!V . ջoc yK3 ZT5dgj: ~|0"'i&skb8hYnW'BP{|oV}L}F4F9!ݖ5;ɽ (]lp߲^[.)`/B8U)$obU-b޺=٦>']Ms7"?>ǡ_ע6ODC3҇ǬkA`t L-#j^Iv{e H z_w{0L/]#oAx }*'iAp5ذ|YsӴvaUЏwl@z)Da kT H=Jeƫ| H~z'7ڌCX˿>e?5mѝKOx"zkQs)yV`7w69wΗ^ޒ?)*s:4ݽ'CJ‰ϸbf| u9E;ա?6XfB˷W`;:( v?@glݜk'\oO1PJAlVhRqL#_н Ѹ?s`Wjj,@23 R@$ԣ"`4|xPuw^MokvV=i`8ؙ3ߗ'Mc{r#2Ņ_np4>mdWϢVh߱q =N0%_!Yejn ~I>*}~ʺC8v_ߟ`&y/{\2rY}$Dz"'4iS~8ϔ9+C/~TTS)Cw4s[L+ჳ_.ὦѽ,ϴSLad*I恩*,%2wA6XUO^~ mģvf0e_H ҪdPy<HV)ڂ&WKPjR,'<5;u0nؖxQ _`y0#LcM,e\|?愁ū@*? [@'E&Ѱ|g|"?耞To'.E(gM?o 3$h߉{ ԍvM)skNj> fգ*|_ #=Y։P?;#SkQG-ԟnC;/0V}t3~$^]d)#`o~iju!^4pۧnj*>z/̴T#@5LdgɆyF/9Sp\W}ӖW%~>|Q [+1ɝRyΤO37kog-ZA8-Y/WlktI[IWbY4?TdKZF귄E7i/ ES`_@yğT2LLn{-8e*`~Vi/ZP M纒\SlQa-(]aVo^52)Y[J| 5+LF1&9'4|Fq"p˸;NB{Cͅ`'˅p§tG/h7Pg]q0Th32z'NRc9WŇ4v3$}E5xտg(PP`ynN|KzN3.f4Z.m&/Fä(9lc8|{y0(ם*Tsʵ|#[rPnh-ٚ18]^`m3k1)GGw\Nr9WpVvuhD'ɂeՐC-`.e&2φrZ+nc$I Ƃe;(yRm4oTXI8a ~^;Td@?rG]r3f.M0.f J_o`fpTϘH-"ƥW`3o\ B+I磌~?-Ƿ9z le+Jӭܟ!_YQ|I^]=FԠѬ3q Q-P;mH>?R%LPVGꂑ=ރrjT: 6x$ރ]5l/Nu7 2 y|蓌ul˷NodZC@ҞZjOD w[P5`ܜqK0nx=Oʀ^0&9xᣄ?,ɟE}`U7.H30%2| ?<<KW̟VI}JeL#+y&Nf?اfqe6?R!yzKQQ x}T0[V{ԖĢK`?5$qf(젴K@0zQ眘j6{i/w݄cC0:Jluq&/xp?^*Z^ F;$vnQIl/R+<T f>(Un\{;/$dVsXb#mc?AYyB1NH}c\99奻-+ {w1TjyӱnTc܋=n`͈MW:vٛT~(,q$i5vAR[[[Zn9*|OVg?d7&ɿ}wşS%sPֹ7fM$*VG9 %(S9izKtGY0YI Fr{`lcu.* @w׫@ J4xr)LЮ}^N|+Zд @>=mEn{bV?$;e  5w^,e2WnrQ[??h,Wǫ({r/~n'n}-zٓsUZ⾰3ƾ rE8v9 (|V&]O: W.uFa81c%8?l"yzīu1j+jު_ +7e|6QFH<+蘿z&ł=="|+/6+m n]r:)DW[wU:PmuBcw0{L88ܦdr&B5ޤvG7s7@skӍeL4[DS1h;/iPOM1_ x@gX\42"1?ݔ( h\k-qĝTlwW>mdGʠ1K$DO;_7*>bl+@/K6$| B=5?`X[;*V\wCx͎/6e;"74g-;73ne|z$g/:e碅8Ӳ'l)ƌt"+p1i!I=Ҿch78ӧ²@v o&m'ԗN~53+C@38730l Lߍu[CЮz1$uWӰس 'B-z ^ JI8#4֩;޾+jJD`kO1 ݍEW*iqJ5`O(-OCHh?m 9D$s\sXTzh:@ Tg_BUgP?Aô#]/ŮhP.?g*? <4hPԦO{Զ7=.״ ,uP+0 ]k~ KD =.]e2S4+/ ףѳ̉'7;T>DYH|ehjv1pnX'ﳫKAUnF`} fu1`p]~2tG>3fY@QP6q0TC<ɾ'$F{/͚1 C'Q{<Nn/4!,x KRW(5$o5-]1Sڥ3 ~ntУ*?%+ʐz1MVUiI >4YA$WQ!Ez IVs hOG ^+5TvO4\yaC/ IJ*۲x>1Y۷,9{M `XS 榮gUd_Rvbd+}7G'gqt2&&`.Ћ}ne\Ɔ']SnlR(ǣ)I [X\} j5Z^=c_nh^s ᕦF_ܑ߲뺹n)|>0?7-0FQԻd%ߧ-K˂IJ%y|P*qgX~K]29ohg gUȯ̗|345 BV 󝡯lh mZ`,5K NAy*Ӡ~B{'/$̈́/t̊]^;L.mLɽC?N>EzqŘSjVG дL_]p˥Ӗ}ⱜ@3@OP#ɶo1haف3_C~8rv&vpXо|ƀs R}J2]S0F%{ӿNJd^C[@ }DŽɚ[ݹto:Gv/2{:ǯ} +1tg ʩ5Lɋ#4.}.)/*+҃|ΒE㉿mOpEaFm|fz-?{xV:&郳`M\Ymo*kô`2K{uHϾl+ ƂIfC-C׀qぞ`2Z4k-8mb5V`*2^5fd\.M~qnPfzls!-q4SZzSd>vU(Go0PE{+m!2*8 :[Y)՟v?!?tq5aԿGv=-$EL!`GԪiv@Z"?0Pj ~É/==4T<S1B>̝% !a[\q; C-!K09a;myTvj k{VI1/!VL{gHDˢg֜? Zħ*/$|JF fxǘ i`檋wm_}O{1۷' r4+ \1rr/ |oT o^! zVT y~ҡ&3eg6ca*afDA 'B}` $r@2l;ٻeGlH:Dnڭ|WJ`ۤT8(c$3Xl2'ub@5r.0$WW-okw +͂٫-_, :v qΜ4p Ae?V,{ yXy|{ϸd<1.̍5$Ps}$\S β22Nn_fzOd ae\=f<;@<|t{85Rx˄fO֚pg殊c[Kv]:-k2ocWW|t`g%DQm/$ŏnLiJWg-&i-SUX׊U4A{[?Oo120ׄpuLo Oݺ 'vս.$G4dujF ?/NЃydz7{EfJ0cBIFјVKC<펲+Ӫ[_ ͇zAÐ(8i-AHa7=A覅N!hg<c=!@twl&Fo$JCWsYs`z@dO)'@8~TT$`\9o,mӆ>pz'Nct$-~ D_tkɬ\ m0nQ}V/#yoN?F9;aFvyP97IFXPY| ™af2i(H:eYՐL+ڛ2 \Q㩶! )|nrB.%:tHԌh]0p&i$7KC  ~bQK^+kVIOOTLe¨4')ɚY kK.ҵ|. ' O:gۦ0q^C(;P A Ҍ[ZjyFa$v73%9/MxKg@`QJf F %B7x 4 jW>fo.xK?ϜuAV g@*v<:v$ށ3 Q%1ngJF@GU#yINʄsIU2ƥ,17Lɛ#0Cھ5QXIRҩ xz<0 _ݗ?|KwC߇ vr˯n`9;Hu$ȓ^Nz4j^0݊]fF}`ox;8n3W.P[QVu=>) >gdɏ6|th~R kH;OI@qУ-dp,[qzSVT?xBkS7}%H~xF$<%hAO)gUsPʢf/A‰s7\/ %?R.TF{Ͳ? GU_ڄ Ȑ\4M#ةu$z 95/Q%d>c}g@|]&Oc瘷r/ L9Mر#k#'UN/DC!1yԖՑܒ\;"'Lr!3vxs2j 7C[ `ZEϾ2XDWK9o~M' ~0 -'x+ yo]09RKhA 7%p0|t8$BHmxx喪yP9>| Y? .m[|veȓ|^˸!8u8b~ .}G<=ƞ[0l|s2Z"!Zsoxm}_:i/jTԿ*w:0H_h E֒-eC(#M<© _?5Ө+8/7%wau0p]A|xߕ|Pw4oūlȩ i{!\? )~D|A;m*q9[{_IKqJ#Ր~L`G-)m3Z ?)iߕGAjSr bkBϓ|0o>F<~Hܗ@tR49{=#`f(sk%gOp~kCܕ%o׹vDҹp. 9F +dM݆TR|t2Wty8;ovwowJ{~CkVspSo&JU_MP۳a g* N|,EW9nyy ߲ҏ!m@좓P߁VF dO2[ 1XDsl3]/5*77 >7^vk 5-׾\&d]}j2EZH9꼽Cd Uh٫EwGR:H!/ iC-_CrHA#Nyc؞2jMg?hwCz[5Z4W@ A'n}lo4+kH~_1in3A`|禎|8 nS~C̘1Ojӈ/9.h'C5i?&yǑ{$w('>o2(&i Ԋ@p0' _ ݔ2rA[V,RϴOEk?镼Q8h%xںMQ? n>¼#wU/TS{mD`_OLIpJWS~E :D-#|̼, 5sJ}Hj n _%jql b&:sm|@{W?e[ .6 F~Dq \_i..?V? `CBciuͼz3XG\|׿JQH!S}g=瘑<⿺(?@۷kv' ] jmcDuq=ԻC#p7&36~C{9s5^7\12@TrbK փWx]"ֽ 5#uOv%;+} x3)d5{ k+ ::# bao+Nh!dɕ(_[6nRc ^bC׎jUw~rYr*q R.Wȩ>`UK}">~)J+ ɔ۱.DnW{'/apҾ%Ժa1}٭sz?cBU`:c:bg d9[SJk`{ւqu.p#64 X[u?)R7͇ zyv=hj弛3/AyGj<O!ړ{4Pm6Ioy֣wM'V㵃Dْs;rՌܖ1)vw.Ml[}6QRaU!ɯy#Fu/|qZvDpZLWXČoz5NZ)ڿx={遮,y GQgy{$8_}qk[1@]ȚMXv+^ 0Lp=?}}0p>rk797+:Lm?w-zksYM>+UL@2_zܲG<s};;!Z.6֟^WjBpxo\]S,8=9 3x. RK 0\Cw[Ïu%0P,5#>5i;@]hLʞ@mi{pp~ %O `aCsGZɯyݏ} qL핐tz< U+>Zq9lC)D7.+Mސ׋0zUU`{}Er>KV@$Y/G΁jEd[-rc!K}Fy31X\0;ݏojoylBc?]qy0{q13 ]k @ɫ 9ikn3^s)'a`Xħ^P9A'ٚxp(`8U*7\z2c]w6A(,*?&yAmuweފ[80?g/[]|LP|MKk-+|̍[jzSeV[ɼu{Lv /1D]ӘZW/9S.m]! a<)d`dBiKyW `VtuONO;#G}/$hX?e8Hm:8Ǿ8pӫZ`]1$y"0MKC@_oy3T68jЄ;+N@aމ$L<ɺm :_(G'CVMy~RUuH&Y$5̏giN,&Q4+nJ? =)5]=7c0Dۍ08$~°ϳ }H>/7B)_\yS%pfWԃaǶ4]:``/GҊ[?,_eꍛXo?MBpS/+}'|Y۔ ۩ί=w 7^_#KߪEGvcn'֎C]noGZ޶_N`\9cOޑ錵U_.|% zGm<\F#lLi9gip}b:ϵwt~cJzx^kWOkÖ[v~(g e9 Y%6\vly-^_.}JsIuÁM!Ve&mUځK̺M lLKnĔCOAMfS: Ä\}GY a`z9|[%admL>D<)qG'3 I_jPx~iV}XCiàO\#NxNW G*e]٦$2W3Jʉ^zYğD<*9.ؠ y؋9֚J%gC50Zy'9DTx ybTcoYy//L2(?ٻ%w< -R`v/ٿcQKHOYKW~ӝ9bH 7{zu%WB$$s3s΃VFHRZ2 <=K@|srwC8cWm0} !gi-ũ'.:n?3_ 𦚋^"} w3I8d)6ebߍfTS6I^୨WJ/hlo} Dx|7r\̈h(hk/ {}}'&+{ ?iCfieU$+p0 U]Tid >| (.?7kzɁAXdO J2ñ9!:yx@^ZA[!8Y7{]H$c4-gG#vDQ?- n ua.8.ΞI!K>OCqd-H "!Mp9`x=)} د8Hmo`d*lٓΆ~o;9\d&%b5hά[2mX|mxZczoϠBPy?ٖ% 9ؕKu鯇zʬ,VŊpMeUJ8e  dgl9OV7M_7xUt==C\$rŀrgEm&|yۓ ɾw*!`,O}9 |JR ɭiq7CԎ{fT?Y<ХTW?νu~=Σ҇LKQ=XɼϘ u.{!n+:8Auwpdd_2ur&c< !{; 6Rns+x\FN{) \ሣ7XGhg~;{}K6+ˡe%ilxr} tϼ J ]\LטӸe ^48Mz1*y YoLj7yl犇)Z^dNGa޷|_-ˉ_𫲩2O̻9RK7Z>V@xWoomOaVNj# ?Fky~n5ߘz{9ƁG2'M!Stn` `=2VO =~F!{s54L@5LJ! &3AɛWiΒs,9gn7S=#t#UXZ*wN jW`ftL8ᇥ%g^Hso=VKΝu?PlԆ;?up zr)-S0B析ipmL0t{[w|Hq"2oT;pvm(q%\2sK!-)iMK;?V K7$)þQl)^haċA"y͐~0Lă[,Dn7ʋ |Im_7껢H?Yl"C) %'oF=h[}8p㍏üM_Հ^y^xI{v݆`Yc~ڪK>;ƼB#O _~>O?wυ$vVkipݧ E W{6ğ}}Wm'p8YH6|<S@TImJC}O'K6|Җ'6VSmq, >^U7-$^dm~KG ?}fPe8-RH͓:.'P Ixhc|`Rۇ7x<$Ul1 sjur >â7 BWܒuܛwhMPD4_g%dA8u<UuL T[}uf`}-^4 ǩO kX+ nT}K'X'G-瞸 [f580h,M?0,VUĞoZHBafOy3)`9 AQЍ`p[֝<W%wBZ`[H}|5%3i԰V <ăXƷKs̞+B:c(Y; 6}a? ތ?uVQT7Qv TN)%4i{E4W8;Ԑp2'#KMvFzTxjA?fD' J%C|Vv 83;3ݴxn>=9A}RP=I·pb^`֑MsM!uRkͲwA<ҝ -:xo *`%_բߟ>ېMcC^ KܶTd׬1'P)~˽"ߜ EKB]x=ׯ{BĢ *=@׿ugem 4,v-#{R^p7Ą7{iߓÁC6;X߽NBY6J$,"6iҪ /B\;_Q wT3Cl]s:^`άe`0kmC&ɗ;fd+MtvkJ]QϚ_RR(JCF$am8ʒ&uNu>p}jw!]/2 wY[}C+Q. f娶ž.ڐ _ސ߿`d޼|s܇H&%3UK7]ҎpHwa'~Q+wq5xfrd~)J}nKL.\]/ذwIƌt26m%[Y#ᰠtb,>Ǣy mqZON ɂpLo)ңo$#թ)%~UD.ys8`骧{!c %ﶣmW s!Pw˜o-{;#\1vy+f_Xzpftzvo/P>N s3:I\d68'h?~;FzUe3M Cޡ o]̈́ԅ;m}-##:7Fr>> Jpk2O]v)OwT}'{MJ&"gC%BSP~w,g Q*8mFO;Q{x\{i;rmW7UGl po4 a &G{(f XI8g|zqZ)\ 2JsAU,{PWڟcsk>t;5~{۶7rQ `בS*!a6p&lSQSNe&Ėc8EϘ4X]~iG[ 52 5 _kI>|L]Ԏ0rEVe8x;$ܝ(K_rת~CT{7[ ^Na*^Cr$9S%˼»l ~2{8?>|A8pZ@5pe>]DEx([:9= `V cܜY_Q[cv%cn[3V*?;1soT^CT%1[w^%ԌD0;r!$j@[ςiA̢9}@$DM׀>M1D+K 1zT6kVF?iܘ@3`@Ȱ*ä cvOhN`֯HwrY7's 湢w}`^᫥_]Uv4_9q<l|_3o'ς3GY[ e)/CRF!̟Atkkov_\p߸ M:{`y{;u$oudᬭ |> ,a3cs q<<ѣUZ`TS4@8NN`M8Ʌ|.? K?^'vu۝SisZbːډ=d#2W*y40;+|AUC]]Squ-/oj=E <i[e6Bj] .)/ 73#M[p v a\`pφ4V j֧/otL=k*F"oڂev :w 3}QH;q|;`u0jcx ֗ Oh"48 ]WD`ŝd_nmԃu ( WO~6& 8a"H[KwմOJ]Hx[sLF5UH/=Z=i gmh7HN ƞ|OESCvG>WWH'AέWS!8.jC&[^===70WG`FD|HySV{}>9: e`;-ϫ[R:ѴMG9D'pJDO_NMaW%G:0]_5ϻ߁!tq{wA3!L:a< QQ gIU悵ڶc?4)^ v߶`PqM6OHf7&`x۹0E i\x+,K&3E0gZnQ竬'τh]lpN|7xO*zDS'& #>]^dH>.xrj%(_Lݡ v.^z))&kG!ygۺۧCŔIU!*/ZQ!G]~> 9^WiLc)|x~ NY&2 jS!g ن`ڝ ҄@T 8ЬM*U4ӸFD ;XCt@ձD~kBW_8e HO< ϖΚx:  !po V^鬳+YGB's*DY ϫ͸+kLgB.O[ ʯCWVGYt@`6Q0w^ @~3xn}ps_=HW3 }RG|5CfH ܆S']\Z3k!~qt3񽼼GɕnO_xU_Atê1+roS*P/R'X0~G<zw.xɢ]> Y\ )T-z6bNQ]f4 a=C,?Nví7iΩY /ׄ@$q>kuO8C˩stUׇYvihݠh Z5>ւRvsu9Y!] #k~g^D+8oM & Jw#jk7/9ig@) js^M0Mv=Dꕠjק yj/.p{j~@SA`<\tNk7-wg%??pQ@+h>۳+7JHQ jƂ9GI^j73zB_wU,zwdK@wahtࡁX_ 3 o~Ս6u@9X ,mSg>)hP.PKA]}%:nI:AQ|('o-dڤ8Щ>y+6|&ʿ$cDs3'@ 2U #eAInHN6nlL(Mۿ8փ18-PMuہij/{"Kݳ@km5z h1ctr,.M+=NĔ#ko2sz<=P/(]L>Q4ϕ2/F>XT jo@?"f j]~ Iug:nJjϠ^eM~X$ zF^ W5@0XsuX .oͻ{niP6Mq]0(]n2 ޜwdB9+$A.Sք.FmptK;h ׹|{GuPhڙ@@cm(/. ԝɾyϘj 5l%䘁ܴLč'JWGàohlU-Qg:)]e^d/ZOfkc_ 瘝Ckv0r) pVS ٧IeZB?7ujgSE*jq矍~K'~#ULy=O@>ms-rArwmFp]dN#/]* j۟V^lä/i-(f:W ?٦u Bi@"Ts9hvl(o>s>^92 f{`bg=u `dޑ<-S9&ǀmr Şǡ>k5OΟo.u})YASxO]规i"{B o_)sӧ $o$߿ݷWU]/׼YÓni@зU;X7RCKjڅWI~zߛ䆻]PO!"X߉$wRn)XܷVi s-r=IkY3Ot܍|Urb߾x*7~-/JnH*7ri7즯5?#EAi^=l;BAYS=O,i^D*=C'& $'nUs= z%5&W?L3O6qʤ#MlfPNͣ;frl߾)70}o8Kݙ 9$;9TK#%0~\{@9#U k~u]_l-KQi_GwwnR%+nCa "L'a)%sSyb'9eCɬ;]`,DЇ@9>!D/v=%p?wz䑼٘>c {Hp/=V@pR#|- e:Co~eʯhKI`3䎠I=ommgt͕Ayq|᠉A!k1$giYSʠWc:m5g|EE$Bwc;? 'Co2@MӦ.Z3M t>91TE#e5-)5q{Lۃg@At|X̜,yOAҕz5fԐMk@c̸Y5 >hP 2ݜ6zߪ%oZ8S ?=y'?X"T יL#h*6[r lq*ޯB"P7[(S+fnjnh"|=e_%fx5}7 `$rV~Joܘ]Edvq&+ϳٞKygcI2nŒ|] g!Ji]_I޳ͮW8r5WG>~'ɵc,T;hq;9 N2#éoPI)Y*I%$)M$Pd &IvW9^x>σ"ozDU 61amߌ&9jf*@YZh2XJ]|߮bX%s;ݨS Aزso-t3^& N5 ȎSqlnʦ^ jkˏ@lO#Ox85un\Iy)$0һm_O3= 5$Oq]\3Ec>2ى% C`'o\DACisαuͧ 'd }0+r_%껀S @, Ab;(9ݣ:=N8|TlRlK_n rg:b ݗ!y]$;@P}2Ciۄt_jC]9zTipXa$EɢLM (6 F5 'N:e95fDE"ǾH"}k_"vGA/\58`:t75eߙԁ<$. P+oLB*傹|/9@ #=u mPh:ù9P-Oy1Ϫ-dھ:g<.G)tU oF@݈>۶B~O8MfVQ\ 4yw%~W2@cuGϲXo`7gYw] 5f=G&r`Ǽw[o%+$o | Rj$=Ψ$qCߢ?9 $MY@ l}t(]8hDr {9?^w|]4,14^l{ loڄp~}[i@~tW}rȭR^Ql=@d́4}IG'/&?EK%mH1ן| ۞ʷ̂$:Nn䞲MO>7eYuj1}vT+m_T/.)+1/-O!lv{ɓi?ķ;(yoˍ,g˳20}~&PuãuȿBa_z8/ ԧi}@m x~y3W<۬˿ 1R ?f8>E/\组zƩy(u/P>y=>ވ̏]@lGMľ+CJ׬cǼe6jo1* 6 t5 I:ۙ>Y:|9bkt1ո#/{KKrq !g|>;9琧JLZJP3nO7VR1VBwC$4Qgw_E>G?s])SS]y *tBkQiD'y / @z5z+brK.q'ڌ@>$#Džۀ4`byf(evU0c{󹏮@XB]H\31<1h'|5r}|*KÍ @Y3 dI,N!?V<Ҟ$|[J,"t0"M 4=qg |yV]n[|AKր¡{uA&VHO~މer**ǩ x΅Mǀ[%*D?gsNz~cUm^};9ۂ g$ ƠM囉ߋG'PEx|tH91rK B}1̂E,>~`-'(e*f" 0&r_}/R{rZFWb6R=4>usl s=,~sYF y !Yh_P=>p xA /ަ@5_;>Q]{{L!#U!Tܡ%O nzx. ې7D |菡m rFﱯOYٶ@8r~G1WPhM $ϢAq/VN!0dlC61C?D>n#'18Jc>aa?̍}A{EmL9̻=d &#cc6@:䶣 +AH5f_r{FWPRsk@ y&H 9A@GZ1 =v}rԒ-PAbgڀ:=+Q<!+;y1^>Pd40rBW=ި^G0jʞru5̜"Ǐ+.ݶ>$a/(3"'Q]DN(*b*u'/!2Oɏv;^ruޯL;Nۘu}([}_^krcr& jYzׂ>Hi'8ֈYQ͉|o8-YܟIU,}6o8G$s✿=t@>4.@Oi>v~EWSԣƧQO%ת*;&* ėeX w/e" nƹW~ dYnR_'|}qXd @d2~sǥ9XU獹K3_U-s_$ƾ=^N{F f @Y$_H䴟W_lۉDSq;)PQ*V^N>XŜ}h =\=6GvH"Zk2K PyIgh! 'AfoX-H|=V@zwҷ#CĖYԵ#QJ ;k&p7."Y'p}vأu,j4>6\)bwe sfOsH)C?Ϣ~gŀe  $뀺c>yk7ʂ"մ};b^k(̱B>|D*C-ގF.?k*PvwwP'U%%0΃_Y!d25*̈́csR]އ8Ey[D߳ ͯPZ>&;8\7yuSuy5^ uO濋oyT_5ۗM׫YPL溢 DA(bκ sךϦ }`@_@\{yG= R#{ Fg ]2]ovo̻Bi/FhXUO= j ЙLonnKL t"^w`h*~s}DT~ +D:~NwQ ĵ 8ZY{OƼOg7á ֡~N)rk{ 7ũoQKpN?~fFNx.v<e@u ~*Wx}m"S#_}+˛N΂@(qZ9 Zp?ETsxمzX|#H'qE%"gHac ̵r keBS @0;(p }̷"DyGC:Cgݯ@:i|>WuTz"9zd^ng#؏VJ@]h2[ N/ݮY]P(+>{n_̋ B܏˓o<>_XuT:I`;KG@=AuճY3Z`*?/e=>O=X aqܳeWLϏ#^o(ǡs|ޡ;ߤFνS::VnZyN_trkRn]. mt( 㨣]<vϵW7O]6Ub%qΓz^(bc_eLs tM&su\@3^ 3mIg>G+}JܧOcbi3UV(Ϩ+ҁU&!_ԋ"r؇͂O?S tK=[x OԧW;Qwn}?k+%u׊9`Sݓ>(v(8Iy~xZ/|oE][H½8`G[R}M|3fk'#vsc}7rM45CJ'W Eg|!4~\k+@rqOlR\cc>'u1 Km:xq}( %jW{p y"q=粊Rr敀 EO>KD@ty!tS]/{w?O@_H{:}c Of( >s:L2Ü!}߸R\YFxiZ7@8/|ۅ Hf}>KN@ItY3;Q@̯' >Zyoj)kWgFϮ}L~-S-gC9N8D'Lְ+ `#!A5,?2|rOm `xlIPNEDlۛ U6= Y}w s3qcߟDvNs5'=&q6 28KJ}G3]?cKjQꎇvY[2O✉nKE? Hkۼ }o'{ /:i޷ٴ ^䷬;Qxdȣ-V(}$!Roh>Ȇ9bUo&JF z{~ꓫ2;Ђ3VVdZ 7p_A.-*zĎ9mEHTG=Ԁ= lYy^E@9 IVR9qKM/2lDݬJy-߿^~&ˮKt~Zr2 (ݑ!oxo:P鶹t/] \Q|>:`MRio m<=G|>.W4LsJ`GAN<oP79!PBcn֢m@jc9ӻM* ͽ),9POiL.V~ Xl]眨z)EI {=ӟ,ܯv` |U@bD kL1\}x֬O02 3͸7SYM5XZ0?W~ 7PBJr0s\_5=/=;q?Z@e@( sҝm!2^zR'7;ՠfقƍZ)n9Rekm3ݧY y\ymBǸn[gǣfh:9CcUU{ߓZ~| a;c/Ϻ Rn߀!Ķi#Wro(;W87g3 Ap]ȟ̜u cTM !|Qqp8kwbТ[1˫֤E`h7i:SPPtSs%q ;veLr⛂otqnfLblv/tdPo?QBqOsgSKl!3hjqBa=q̂Py[٨.^5 նD!:o\1B^ysA;1-Z8v uAA?T[a@k 0'&e$^8]Z4RVz=Y7^1.  -dA()&Uyš |A=+ܹ wk+e/ϊ6x*7 ZcBX)K]jLFM+< &hr'v;)Pv~5n:j˶}=pܗor7Nmq<dfÛQقO <^cYdOt IPm U4o/q>bt=ccaǼ_l.<Qr hG<; pVKUfW%c¶"odfxD'f@rLS,;ĝ5}m/^fIOeŀAH P͔xbpoߪ_ƾi, )+Cf^3d}KD{l4#.=E~ @ V\ ]_B)"FfU@ljOE@LJ}ltkcrl" &I45aRGDgjuAcGr!ű4oQyx }(3{2?X;ͳ/A ~^ [観wIg9-R=uN},2Tj N~)gtk.<(~xZz~Efg3T{bB\l4=\;fsv7GU ϰzr'Y~kLƾ}z~ogz{5nÜ^O{0=n{r+ k1_y9Y>OlDO ^73 {> [DqWR +*;VgƜ>D7ڴ >Od&|d^iLic;OTgoSPp59SWk8|@0 P%rE}yΑiҠ }kqrQ?χgwQ+>a嵇PFtp7wp`m̏/vGB>sDy|=g-$/p4#ۓل/xWx&[wb*RFqodkRa>s9 YnCE2_cUJ>{2au9I@T=ZܑBcL- ba![a)Pg [ˀ*2m{iL諒˽77nҵY< gP pxŰ =>4 ;AП'Ho(Dn4ean= B*.(UmZ1iQ?X^đ?O`.f)u7rBF@^5s9w Z < kg;;\?q BhoIBX @n>c粤et=q]dw4g޸! ^rύ${UCwl1:xgϧ6Jv^E-~T-)̳F{o4_T  =@{ N<_h=^\9$0UQ6 ^37k9PyL yGЈd mBOK* w]Q@Y7/b@'V2找o\pϨ'i}7 TnҸO@0Y8ھ|ի .otA䮭g9dhD.αZt3[?Y0M3@T= _/ς<`Dlbr~W1׽ޢ}%K`T..|tX-}Ui0r u;xPWQ[uWRHyғg;"?V~ [^nޅ\fʭ_ޙ2䪛O|L?Oq\R]o@W'.`_^aaҞ>}x߇/_^ߟ:9uy *V)Ľ >mgv8 }۪n)te㿟P^?q_c'y! }ӹOHWG{ڀ(j Wѝ @xWq` P1z36 <y L;CmA@:#1˨qm@?~uGJu%(-] ei?IKIoDVeo@Z;~uu\Zꃲ-Ϟ"qXZ+ S8&@n8FגUNcrc c4[^'j^@ㄦMlXӷ$0=d9%p@?>Ṃ6LN!Ldj_#u#ȍXY|,_ڵ )a=5mY,d;9{RD&d Z ψ xwhriYuT3_%^g ZUs>|1aH|/]]Pm׋sf%&v,P}I 0qBs|gl@p[ ̞<G!n1ȅ\?AUa9 eD#p\܁J%8\/Yz<)i8ɜN2{Q0PLK_cqu Cg%lno|9sdƝ0JR=&@`<ԝ]|naGXԃώ̹/##}qDN PaM }?s"H: [) j}<.Y'aϬ烮7Ώt6 8e(d555- @1E0 T^b; s}`}8/~}3Kߋ=XWz0 5[EYzyK [] #HrB:ED5;>lp&Gk?!5JHҝ]Fo <m!_ qDt H2݃!ƠJ4.*i 7đ͗L0 Z,Cv[O_Mf "kTG @:/pTs@Wv'lڋ!۳WukXM{ = 6~}9V݊zzHk1|ۣE8$oaW iݬ< })]~HN_OW^|:sҺ7|F1h@UMBHĔqY6/m;5.-f_v }J]@<| _/qt@/IHkce3#ļv1g̗޶6z 1 I=sһ@bk*Dlu 1@]ʉAwNEoq]3fqr/!3'.t8}십XM]lo{%UܞQ/1^$IiRgS"Ǭ>WJx޶!F@xKa .Csd怐hbݼ9 \|Ba.Ë~\K15rǠ" F"ʾO.B?ṋNuv|f1 ZRE'|T#G鑧93dtrFh8'm*T̊lp_2ǯ_|u :?Q^xR ^n^>/{QWΆdϺVqN~K9$vg>ƻ8pb^llPL]\s!k B󘮭*ꐙc/r{J(LDO-G qn&\\Ws!#?Plg#G,_||K~l=䒪)?Z+P*EbR9P.Պ<@% Rd~;mBʍSS*"ʟ]@ ft?\C8ogJSP#rߩRH7}('ScRFu'w!~L_D?{B}s׳@j{rVa~GNg۠> jJǹk9}DS. Oc;[Qu7gQ' /1/y/|$Xcm^ d݆ct@n{ii[?^)~S)o ul-tC^]EK e 95 e{<ߪfC7^`1+}3{݊yxmÁnP?sH[{GkݗѵI|02?lA=VW7b]>-ORC}u=w|O qxnDK׀4R}ej~bwմ/k.ݍs \,ց7&"W7緼"QxSk3@)a;قq1iŽ!< {# 8_W쒹ʼn~ _; ɠR`܋u5ZVD./QIvWx#YNKX'^I%[}d^z &I-> [wu?/5SCjN<ײG!$hs%)_}@ܽ'ι,@HMYsw߅nKO;v.-nʒDYy8.V> wU?q!{$=;|DfjQw?=e%W}?> Q3,8:&._ckct3'6r+|/f{6΅G@q;Sv^W%7m8]M}N9y3ȑo"wrZ+ɘQu?Ӟ do5  1g"?=5VȲB-XE@wP P u׭N4Cڦ;lP'j{s"e>59+ $ =W"aPbtj}Wc$;+R]I]'uw xXg:ZTA]]@<6>욮*FܳSO#~i|;s[7W݀Sx?7ZGmcޝJ뼎sGix聏;{s]ǍFȑP讇5-YW{ߐ>xĐg:36}NA"-|L/iAlt_ᆠ@h5;@}sm~NésJl7pbTvڰ[{}Ƕ2jA b-.fJ`{qV*Ow  d40/];zm+c2vʎӤ}ۚSْسIBI:P>d9=K|j:e-Cwu°35/)~ƣ@Y3MJ!~Q7C}bC{qylj9@~p}˕ >ԁ v/5C}fM *<+j@ob2eafɰAN>WsnpǮ篸0ޗ%;VcW Řp_ 2"o.? ? Z:p?F٬=\71V kG~Uw~ O|~Wg!I%9C߫gQ/[/>a={9t#ouj>+Hݶ4@yh #WAD)#Z=cǼӿ|$W=k؝𛇡SIH|wV}B#6krV)f NO q?<~ 9@BhnN稨RR E=;"?^9s?w.rDɈh(F&"\F6]j}tQL\ϲ%@1xpH{QjLbI+ĒD#$p[s]lj[7ms)ܣ\'wx'<zo*x١H"UO¹RtGiR $GqV%1 Ip;S0YOg-jX⽃}'8ꁏ#^Ucx궛?=Z<~gU $Hqa9T~d.lŀtj3կ0M}Eb$~iz[kλM'1oCB?ޫ! k;gjb޵ObN8 H&;l3D)FCG-)s0^D?wSN롿Xz^( @bؤn @3dR9f-ݘE@û@%~*n<|w3 l以:l^- H ^_7=S+1?u=;TsvJytҼ-wrs+`@2Ț|,c Sq$*X2nj?s7okNN2@ ]5SFz̧}x˟~n}^HZ fv"MY}GRވ r}z@l"$u}SL/nA6@] <'Yr\,QHץc[fΰ| tu|y [zQLZڮ *;kK f[IF`u/dg-PGKm€KBS | ]׵x.Ge VJ9~7ɔa{/rTcޛٗJ(+'b?/<;d 23^A|uyީ:?,d|Zȟo2#ĄoǺ|^~Esf=?9tlAw,ϫ: ekC {K.ql(5n*(ka!ȡ?:^r0/:u Q/lq774ہ(䞟'c_/įk>";<}yb~1/t?N(R?\œN"('-os &;ihcN?bj}5$b;a݌89ADݓ~*i ?@z} Yܤ2]ԋ-;^a'3/Ha;L!Tҗ}9u֡/24fnRᅥY q~\w2v>yd صtuĦ#{%7em }oCviU b@yS4B3@;2.}3R<_wnC"g&K?v;B?/ } __]LM3IIcE1kigO$kxt8!,]꓍Чr6} çQ@]۾٤y7{97"?tPg r 55XѿxD<[k!Gi虁{Qq/ZW>a4 bo̹7.cMID@({4B yMLg JczaR7v%Inb^2JJxё[zga_TK.EKc*j=9v@^]@:reY5 MǼSů{Ln ]v4ƖY/ }2!MsӬ9R׋ pns^YϠ?0zHY/w*cz@qNۖ q½sϟ܆[P'd隣6˸o*|Ȩb9o~XM*-6?/! }(D+Q\e9 ]ꢿT?oa yϭF/?kU@>o-78j`_#Eti%@px3rxTȦq) 2K`tgo[0z&afs̙YJMQJwwZ9dVo y2,}?c>3wo^ojOyiIF`+Uy8?C畚꾿@2crg^-e3739ń w,bKcDH^ 䢢~l+iISNn|G ;GJ7p/PnMDn"M9so66̿ʅ@䐭FҿWfjump;YޏZ?e) dǺv]0M X;]*zҒ~9fyhsMqۗ,+@)Opĉ9Q[i ʀt* _P%~S9V ܮzeO챌da.nm"̀QQ7_ qAͅSX`O''eVQ _w(|<|\8 )Y0cˎ,wfr}dR!kI#(Am9@!{| s׫O2 |oiA#T, ٳ{Qg?KHaoF_j#v!/=UOܛ,I<[aCc1 OOGx|k{}k()'h@k^$1E^{ bl%L8Pf<[]|l(\ G8#㰕:J0-ԙd-_m֣L$/]_oӕ=QcΝaL@J.9I8a+y3$ żvC\5?A??zape-@fw?c$w/*wOM^=<]A18UÕ{ipm _/yϦB\q[^6!@$Ü;Ȩ}%[} Ǎ~zր0P֓TOZX _J&usmLq5W<"JRs\l7y3a*˄D;NRdunx Y  $V/ 经E!OT'=tA]HbJK [a>yL}@O,{0'8KK1>yՠ(ܓoR9Cus@X^ny%/ᇏ,ܪ+0i)NȴҋP 췶)Uf\x*$kӟ"4 R[+e5ѷt@|96@/_o>؅y)wnNBqLl 7,lŽzysMPa:klZ{n~ Dܐ#-v߮gƄ"*1Z&fz<= *yz(|x*cRۖo`/'}9퍊i#Wְ[@uJ-q\{mn>蕖2 U@:u?S'Q oӸ=y0N,WbSC++;̍swNGxάcϸG\ZE>s@axć~c|} CQ:HĤ ;^C>N"8z,z{Su4.eܣWoQG4;s_|A!Eԁ =%g3W@]RsU]ϑ$'6`.gl#nJm@+ j>_71'- A~T5ݻ~v9/S8K^diY@ԩ};u?OJ(H6."-]~;(#7xijr3n@ࣨJ_14u?fh9J8H8:4ky $MMj]zW9s9!4ӗy^η_կ@䭳:eɩ_Ź;-<@-NG '`A%Zx{^E?-Mv g#:l=#Nzt?w cˣML@sSG}D_ M:K5bxhW U+l PxQwiH+9݇tḞzAnҟ9 D;M ^OO#.ճȓ{`jU 怗I:O3}A m@no ʆL޳Z!+39mLr$ sTL~nѡw|E=1-?u|ĻꛞmׄqYvșPҍKgƞoBݓKLrrX35)->ii z^RǜQf0 SQ@:i/&U H%Ź~uZ}Wv~ qNĚ } )K@rGGĮ]@JP>%"oH]8'ϟZ}ȁ3yP/r釶?G=}rQ-s﷘32Sn+& 󎟆dp/~BudjH /,b]7(y$=hb/8f4 7&/ d7؄yǗ]yIQ<_B.W= ;J@6WtE Xj@nY{ׁ:F^ U u,J-A)@1;˝$V +r7U>V0  E%t_9sU__mQJvCc Ɍr6~Gu𞡠O(s`$$wՕp8"H|Fl s8GWyg@Vc)jDx@ŰHsJ{'\g'e:2!Oܣ(A]nc!^k!:>wm!qc!g_)>s@)Vߨ3VBP\wDz?m<׿ԏ/CşoRJY)=I_tz$Pu%j4y }wѦS9t|[q"r~N*.4qc-rܫ|hD-Q<)Jý7بpo;?gN!>zuK˱Rg[PݮySPK]7ڀT_Xl:ya67M'O79by-W,w+ WI#zX#{S: =3*?՛Z;0d1y"!(!=e6G -N=ˤY{8R͘07T k_JM|- TYfir' I}zx6᪽Ϗ@^gbPĜ5](zQt[e][ PkonZ;2ԍҍ@~U|~e#+ooXRч=#SL#o.;Cu*Jɥ; %\b6I}So ry#_l r[veCx$aA|Mc*O'y=̷+bOĊ9jӣ5p.Z7:ySĵya-0(6 v_͖! jL׷Y.>fgЯ^~z]hu b ={a&Oo5Kw`}(acy1/ }؍!l%պPD|/i?$ o.ܳ[ɫxΐog~wŕ|\J(HQj{roJX\n\t@? ܝGgV9iO'WyO;s"Ϯ =PWG[fvH3;w4yԝ;Q m 6Jm 9a>y4Up?-Ϸ5?};X;_za-~#ek턷G|>YyNL6q@(NT r/?bg3_Uf<َz=]&3}@Ú ?“;0DLfʜ7 7'V-mUYqu}gS0TԡGr߶c,ޮ4c[2ZNaNJюM$PwRpn 壾gߎ&y{ O%Kp#;b׿@w ]U>w@Ms/\:wJ;p^[}rsNӄv7 O8Y7s #׾#?A2"|f!<+3|;UQLeufkiqӀz|G fi@>̼% #}VB28XPS,]@ Q(W^b@=vFA>浭&MH,K&e$q;xn;t*r'Hޝ:asd >~T`Mۜ0|*0Æ9Gug(Cڱֿ,`HNj "f|pnz ޣ^Rm9,V%杬8jg-_1d+|\>Ƶ1HZ:R?}c 9 2q$ _>a͈dŗ|?BT\^*(>@=F':rri?CAOA6L ɠgd}/lY*M] w/o(q ')oIm }g*~NdW[xA|lЊy9@Hn;%O; )&x6Hpo X#~>]鿞[|o3}MĔJ-rg6 x,kV a |9l{~dM8ô_=HJ]-pv/BA7ZRm~Y5Oh=ײ)?gh }M<Κ$5k{ 2O^BN7Z0iFA.!|tIg7/HOwc@!Ëa.r&\ ~DSÐȜK`7KRdr>J@fe:khz_oYYK͋|/H}2\ j/ȦHek/-mhh($Ȯ7g&VJM3H?| fVL|d(ӳ 7ۤ<DĆ#Av?He)^N"83M=( 9rWӓpįm3X-C$S uxd=&]Ks[@B Z=?8{@+nsR9Fmxd:>=fLj6q:Z$=/@-nHgJ19yKXw STSH}y [޴d8Օ~z:PVeO42Hݐ-97k hvΜ K@6+p/)C. ثg!PS߶+tD/f߭EՓϺuA>;vHH1xْo@ۢ%H^ ޴ RYGMҁTe=Hn5aXf&4̳KSRk;. =tMWgmSJUHgec>~L -{=uT=Dl >ao׮#H qϽ !1N]Q 7;=57YƬ- ~: cT7dn=u] Xx4D</)~">R'l1/w}$Pq> ,/>u )vb\ 'LjȽ2w ;Aefc]b9ɿ'rAn;﫞w@j]_ &g`! ;灘kt Ѽ K7!bf[J̊PDw$GO}=Oƀ6ә]dlD@o` r/ ~<ٿ@X{deOA?pft!Y"AٶY![LD.;E9lKb;Hgg 2R\AγAw:7{䖊ȵ|tĿvK*fY]żA*J=p[ꬩ+6|2%u$nSd=@V֋R] ۬aF2n?VaB?ۊAQދ}\X0+[#M@"X #mW\C\?^9 \q\]RiR@Gg"HwJ< b.>WtMd\<)R6Az'MdO3(؇|:;ܿg uoj!j&?>6cIs@-PV s.c-3;A%C;5زhMy7ןlyLJAF7_pF jǖӟ u=W>^@ZDhwd*o=@QOX0dœCoʃ8+I ˡ' zkg-$xtbs5 -G(+]?"qX 5N-cB|APYC4 dQ?wI'?HIAKi=D{_0ܯN L!v2;#Hn:0ChoTAao @K})d4wѧLo폫YIݪqee Hp{I%d_ YfigDz:KAK|+ͪ %[@I@ Q+I@2!sU{ nW.egW@V|II9îr0uorR)MGe̋}נpk}'4&w|us oߐ.&k/ U]3@ʯ>8 29؍s#@:N( )H7sCN6z1'Y-@{K7ԉ\oÎ0n* ƍAܹI72 C4HF6a&E>o@vGiNnW t3Xd&atkJb#B ^Ⱥ7ēsX(zA k'Ϗ}&Wiż :^-C.i+g%A&r:]jlA/@Z/?WڻQV ƾt*Q+o;|I=tAU4:}ücea۝;Wu'gd3 wrRD5uyW?Im-zA6uMx>Kzǿ.Ypތ>2Z Tu? =$Eu]g,-Ɠ# -w?8N5^>^#onE}k7{HXǢ yDwMHkDv8_^uODf|h2HT|[S-NL*Ze]0vk~,ĵ'Y)vo>C9ìUNꯋEjg#l>|l[A T9J~7yhi+3bba|eyryn sNҞ~$zDXvyK@9a")_Fn`=t1h&!.b)WX~brfs. ;'792eNYA"5n-8~$Mă.tJiUiTC MӾA{$~f>cH>vo 2u< je$A;2A:KQ?:=,~Kf_I"|#n6O%넵,>YzVn$v̦=I7! ~)H7艥roDT\=3ݻ| d< ?9Q@{As,<ڭ4P r_ej=VAƵ 9 !O$? Oj U79i/6 ])"LT=e_Bes|:߹w"UW=@{T#a=ݍ|AmϹ} %ITlt?@\>P)OBK7A:mV\tn9`䣓YWZ= v"0$YkFt70;qBRlXSɑ{7kP? ;ŋ LhW9φUm *ڕEնg@D;ޮ6eރ,Eto3CA .{a9ў $qC~L|hI {I_ |zA"f巼qj7n ~ )pU m<r t\ ;%o)yHNs䀠3At5yyen.H]^;|hއڞOrc@{Kn =zg@BUD\+H ogpSGGw)۳]ނͳ0/Q|nO6+Hh#H^+.:z4d}zA^i1PP.]ЊF6Ԃ<}Kn;+#2VLA͗g \V $Ol RFJ2Bjs 5jF)l_g?H6撾 6gP6 r.M] ?^OQ זճ2w>J̈́cn7ZdoDo݋o\ OckR]`DB Pr+%C6X4<^ybݣAxyji_g\p^eΠ/H A>_9Z{8fAރT$Ϗ+ bN6놅Ьq-u3bWh<+m yj @rRF-% M 9}@ǹ#u9BogRAJBUE9RZ5H\ڹ܍ORk1S /M2>nd W!F9Ȟ[3u-T3 #rg-y=.}]'D1y! rldCc6 >H rS3/:Pp'sjX{GܿM W:Ӻ:tdHƛK1?=O3V}T3i ;ڦ[o +0eFNܡzS8TD*nuFd{⏂ [m3s6'T Hu޲8򚛸VWހ맙w,[9B=2'.C}kUī7pܫG Q_o W6>bA 9!hgA%/@yXD-:ZCu{ oh?+;~܆ge$JsvEUϛjUm' vn>D#3/+T4W8[t1ntd~UPb-@^Mޤ1HxvDw_ߗ;Az#K ۿy"H89<'&kGBA+@.Lׯ[Ԏ8[ڧ ?W:bnŹ{+t7Ƀ9ڠ514]Z% gASӣVPe:ƾo [ADܯNAzcثk5ore=2&^iF3bS(˭sS ; zw[#Wf(wMA׃~ɗ#_@S៽W@n:;29')*2oB[e 2>>ɯnIG'@t\VV5(}>R"?[@tbzQqcF2SE@2 um&K_R~nn6P? %mmU 3,=軝o0?no?jr._y~璬n\ VnI3 >R/%NҌcj][G|@v ':PPW,<$gʮv`w+xo~} 4F&S7½j:x߰ hJVgm6%-"T(*%Ȯ$4!ՉM )"} ^y4ip=Ho16wk-b!pӀ+9cƥ9x٨܁`7da 6Հ3{A3Ѯ러}+[ʄwݓEm0YjBu+,d{]GYxAdkM*$'s;\}T@WCqI'H.Y < ;t^MO}w)r`CهbVdKL­<3!8ݥ3D)N8ull&g.>Ff< ヨ3!]Q 3Γy'-\Εm pW!H=; Ys6cs: Rٗm#[u#ܖ9hY)0rX}5Y OsO 4#gʼni HwM"zb*G>>/{\;eڍ J(pւ gH7LJ᧿NԂfԽ={;_ 9)ۀjeiSȹ|-Bp}:$oVd.WqcW=_h]*&{ygQt>ٛ_kayk;swg궛O7%BG/`7eArS{T8cЯ94Z \ي7ۦiKi!}3dB/ֶ@q8h/Iv9@rܖ==0>^4 HE6![\q&<t0N^_Re$7ov'dT ٮLw\Ȋ&Az-+K{ރVߥ` n*+! .o[iU>~$y@xcvTgݷvD w~qfϒu'0,׾.|;}G0^J|IJ6ek׶sS > O7A5zcy[M8gJP8g>]j-V~wƐz:j<Ec8A?ekQ>0xn>=^>OXSEVk`I‹ ԧ CL'̅bժO`8>b0'?aq|"| ~w`O J?)]~ϊqz_oGWh^|jn7?{| iLBߜ2H,{&h(p6z>fـN.^'yNU?ܘqV06sv`ѹ!eꐅ7b2LD}%K{O/~\߽Ql8|nzxj! r<ߌ[a %"E9a,ScR(0Ș9#z:!}X4ZRV[yȒ{Ĥ8xܓsQO" )FD~.:V| MQ4 mF]YQG N kdQꆛCT=#ܺTS"7+⼏C#`홄'A|3)-dfM"wB<|Fx3kٜ!0iE d0sՋ{̆d0]o 8I (0zs0hZ1}$<ᗶ/xs[Cs(9Īgi9u|&;nHd0> 'Mt A-{ CCN}?yM εO0m $o r+>R YkHdt/H5引6,K8d4;k (ЍpCuG" DÛ\ !yI!X|~HB"B|SYޕK[y;S!sr\w opo̬]0G߭&> \Q6ޟž@$2%3 \YYoeEq,b^OU;}!xп$$O˦/xš?> .zOHV#heH>#Zy nLl lv?/ }td:<B"P _{ ݜcd YIϣfKN~Uom vCğR/CgX߆{xR6Nwgr_W /KY Vcʨ˄/l z zʴIPTSxS{ch&e,vqpc26 X:LBï|ox i[Vf?w,a1:vAp;m%rOς]O!b!\LhQVGӋ՛ ;7Tn&M vTHv}wxϷ-w`k/{nH*veH5 ɫ~ݹ7J'zK{h$s3Nz9ǥ$C.e8!v~$`h@C]GP̀䒾_(c&Pdgfۣ:{IhBxuBHDu5]Jk, ?AV[x^OSZ_@}xNM42F-Zam}?ы -z\ ]~ծ84Ͻ5 m!z2UIڌ, G߉|[-tW^mZ 98oM>Z:/5t" \5H3!ꦌ 憲Owd+u=2]7?dT.G0ݸo į~=2s.:vQj-38^cɳע$YKUOemBCZ_9x -^@vmUۼ=(Zq !yl9CʇpL0̝Q99 |F] ;6, HzF xEkIﯳ=|ǪC0Ҹ}Ёi"Eux?o&雟O |qUn޸j$W|2%y]e+&/dAL&*pgL jo XX@Ht+sT~2`_1y )E&<-_,\~UaC>jmr;;|UlD,5p5ٻA#K-[ǙoAihݧ ~v&.&΄p̈́>}K58Ч&"E3!=+GNM0흿 ϿȜadzTk)(җ熝]'Y_j!9}N n!,8 |AU q7 !1>S1 +Hxś6扶[WܻQ_ae;o LƊ |Dd0>1S 5~Fo|q0kG G`t/cDӔTŷO *!uz-̄KA!ޛmd, 9oClgy)$8lF<# 5M}| :YMixTI8/(>J>* -H*wa+iJVU+@Ych=.<㘘h4;S-t_K> !I^]k=0aM+P@)ל(Hn0qe Xվ "+ͯky,PXDja cRdO% Bj'«vlQ;G9܀lmV oYCZqׁj>SJk5> =aBU!;> ̞v$|={$vs${ ҦVΆ~?m/q؂k~z}[9S>sd?: U vf82w&3e"o}[p2rZ 8`UY h'h1{d\C8ZOXz+3Wy~@/gFi0s3.-,#x暑~u9lYj+_. eJ ߻rfO z`ݛ3\JW磒|ڶyw K'(:9x;!&X+:Xiu ?πAŐwgUf4H|V~;ˍ`Y{n jrx*ס.E{{@9*M}Pc[>p{ʢw=lU15E_@X z0o~92,7=r*9h"^ҙa`YXڌY]x0N-= C[gQiWFRPv`.c]M_]NG5WOըb YmFbnPG*~D`2&j=ZRXՋ 3!Jt{WvI^ ]U0S/ܡg4Pm n fʸ:6a)]ە*`@蚟Ψx4- ?}6Z> Fyka@wm /`T ouHO%(!{`Ax~y=m>v@ͮ1Egi2t+[jH`;~ l]BrYGm鯛!﮻ro܉yDzLe[Gk6:5-Oۢ^K G #Mc1_jy ?+4ՂQؕdngD'Sr;+9` ,[cX) s5S`rW?}S6/[+a)5GKnS!ձPF7C hs/k_֎׉^*6rn[`9o ㄺc`쯱-XT o?D/E1'w| ]7zK` $i~?2 ;DxKY^ Y%+}зĖ[R>>e1A x患+X뛯?jssT\3~A=BA0!]xmtfO~4`t_y&޲|>m\gxM`V[z'փ6Lڇ$7@{cm=8A4߬ci ƻw%`y;/ixTsjn"(U+>K^ o~b O nZ'0y:\kg3sϽvxh[i>&K0ODKR ǝWFRm직*t>E/]F|IU_ o&'#te?SWmG+0Zچ#Q/MrLwmLE}<^L)#;;zg%o&y<.wW׎3]߆槫59:2@` F5E7^>vg5ul+Fl5Kh&ؼt.Xz`Z²$ к/-U| #bwD5eCc9O7sMdr{a쐨gn>w$u77h`5:^ .w䥠 }}`-܏%j[*#"/ّ1yKtgw1/Wo~V{cQ E^̸\rSpoE&v2s; fG<5A8%0d3;+~ߺlib6Om|qK:qvѽ]麨):sOHt{]Foϑ&hesxUp6ܷFG-Z0DAgZ" n/-mD0&LnNGɷg!<㸙k?en0-Vd^(kyp]v f1h3B}m V!z2n߀~3iv#UG?˚z Vb*UO{<E>29RW4~HXKY:ȃaRW_Vb9@Xs;gBM#?+ZpoHcYA k8]od*`5khl՗}Tןog|Vl&w RcvA8yNxc#)eC(_09u SyP:H8RϮZ`Ŗ:]Wʃ?<.+U[7 qꝃoRRRpb8^(͚Cs`eKe#zj&7]^jxBnCKzii{T6QaE`? hݹ&+\ywFwɪoBd^0mm|g;p9f3k>qCكM]wQB޸oU`f]ݳΞlEЍœL$rvO6$\~ӹe`RtLwwpw`3u"GAؗA M`ԙϔWDH3%Ϣ4%g/ZK0gzFvTAʧNy.҉Q yUSw u=y,\BH\R`K"We:@2yHwX^;Vp᫙϶tc.&x6 zv]WBh5g;V' +Yu8f0cWio%oveeLYp,p4͎o!nʴ St͑o%~\FU czkyly<{/2Tއ.wuP<4 %^M=*pUB,mOz=>@`xe)0o0yW{9t;R?NF ;m_ gٸլzT?78s;I_}qzȬVswYtx  ^@6e:cUWW5S[[;i~?8h Ma>X8 ~r&.|'m]O_(I]%.54vɘ:݅,;^>ϊ'r9fufO ο׏KU7ᖦ7`(?_\V]{<\NvXIwB/p>,[AKAWZ7)gSּ>m)-e05^~;ywXՎy 4ھt͓|*.›~"laW)']tuQ'sr]u7w4lI[{m#{kvZĸ S$1#-oFMR[(^ۇK=.lŸk1{A39L-wEkhyؿ3 2>w!چ 23<*:/V`rӆWBUm罝 g@vR]9 1{6XvV7"?!@UgHDrsGJ Y{8اF2/{֢/ӎBS>) Pv%\Xg$4WZU;flTTP~h^͘{9rR4Msb%pܷk,҇4T8=[ ,~ c@B8g+Nni=u^!.jc1|"& ?rؖ>o0q~na88w4Y iCo}k!^vSNTTy&@@ r\9Ԉm;dgtMSKb 4'gģr wbX0B#sp l5x ikAYpv6(71)0 xC|}4̹q[N Z\G%qdQP4`{qy +kCcr/_񥯑3[pژoxy?,0MSk?fp_ߜ$OLCQ,M&=߻ \!YsGlWR!ٰa=,,u=#A*|/?-ډN}7O&%W3RiY;(w#*3m?@n(g.{#{? p(sdTT֑of/gr=eq&9:cĤ59Q>~`R4 zh R<{M#޵oxo˪n3*h錽407X=ƃq`?TǾ5UlvB1JSX3AWoPZv>r(9g>`VKLKe;!ZZ#T5S KҮj@_?tJ Qсk*Yh(GoSi̚,I 6rW#\ +?i0]> 휙Y98<=mMP:S}T>e{xAݼo9,G-L|f^Y=  ŕs!^Ƹ`Le+:go0)XNS>}03ݲf;9пz$0~l8A^B~ |fzjcuIݟV&Oߦ]y 62CA>X3=F5ā>m6O`0Lq*/y7xDI_5wbve}3v,8j)oE 9c2"ֱ!ݠּ wx7`# |?UU︥t 礥VnR8wjǀQX6A@?!cLZen|K\ )T%pVZLsry'? ^3AU_s >{ פZxcT!;l%9^kpVFTJV]TmYcl0w0K Snǁ\7~ [}ʙxJr_&nz2;w\t0E[Vi@Tf?Lz1ERP6s&: ,.'lo}z|GȉCGh=863듹l8꠹{m?+}⛷>z MpCAwoZིW=xT.1~vXzWЙ"g7 ';?A0Svw{׬&=S\R] =;_|;)Zow07Ɣx鐨[N&]xJ' ;5fSBSj#@۝5߾@$߹jix[;D-o9pYNݞJW5*d^ָ=`ݎzINproYĊϵ`:\650|EVI#Bo%0[ͷXJЗLV~ c6}Gd:Oc>}(WX;q5.]7wo 8 r[︃R־8 Amo18dZ*el*[gGնd%xWWurk0|k0nTj :k@=p^!o0pF|N> }t[uhާ; \*WkA3ӺC@y8= o/3qa#ɹg'ktGM6څMǴFy.-'Gx͇D!\s1-{ S{<}%(oE'!4& $|:=PEdfΜw_wޖFlt+!_xᦢ/ɏT} 怭LoMtل AO_+'O/}=1ӦWvj=`=LӺ[\NC; 5O4zz&hXؽ̲& 41~C!n(7[q$򯠳zv[鱺[sԎBW}?/5ގK}e3zm5d3>%:35$OӢѹ'V/y7G+HQͥZc‡4CA5i$CgP䋯~ G7$_سͪ4Jh80)lI~+:6 /ೃ=_W/0te'U]&F P4f||rᶀi '|lW$;[#JM&R4fk_s@c+{㯼?}p=. IC6Ao? ưl=fMmɉb!Yui[_qAn/xfɸ,qnYГ$auIWgڍI䥁_lH/~<私˓`5;TM}YI)yEgׁ6:XePFw"OװӾ` |Nv%ݵ3'8ݳ2`V6 '&av0l%m)4 4_; +q𯃞nw6eȏ`]Y%T[5E%+pҋ\;g{Ը4{xܥBp lf&s~[ }Wg'fl4s,XH|r'd{[V@8'=K/pJ8f:>}rW_͛2A_D8MFp-Kzc@kja)e;e­_ g͡dNo"; څj`(vxٔiK^ckO`Sg<ǁQi٨d^R6}#aKsF:wVytYrIy9r 5WE5聿3,٣pz蹻ot}ƽ:TgfVLّА2bdOph5pP!Er0Oi.^U5D*X컵4b?jG n8"+Cs5+p+f.gB^8| 7f}ئoyU^ e'`~~o b_;ėēNyk2>MI4sՑW`vst-ⳗ9鰋ֈƀѸi!7I ?Zeic,xrz$؜a@QK>z?h*coxzX*@ y:7w<.鯎]xImWEQw-K(/N %ݶH m昏N+}}zS@J᪘&p^^ڵ]սA^-teA,cL0-fxgK Nt VQm]`P_-sH?є.7#-~ɯyÏ}T m;`OZNjA{1u>S ޖ[ȭ/ Ƃqc+er5qM1s _ ʩrO^x9¯ :.t}tゕIµQ^3@ ~{˥(jwEF`N VCvKۈuڍU^EOH|Ex}7W'T0K#O:w2#w [kHP#w߼7=7QD8g?Y8 UewWnʬ$ʠUT MT8;'VP~;AƼ6M2Ʀ)|v#.;3߫ jߩ`V~\3SB\L‰Ow#ʶ"3f1~'Y[(M3[Bd]挞OIR3_q+'돂q, sruq:ݠ}ry`װYhޡq;,߱jy0oV $6$@5`﫰^Tٜi@9q!u{ރg)+N; Q/KԁaꍾIX#bg^ﺾ5&Qt<.)(" rfj=ƛ(Dʍ6/FٖAe@|yu7=":7S͹6W~{I=ZuJf xߧYIwƲ{hϵ٩t6:$XhٵGb*]{3>"JKloj[x[oV?@]pKNߡb[jo*&lǸwlu(|"b=BP?X3|X f1]K7ݥg}yܙ)=(J&`eժu€@;.j)E^i9?hߨ\A0qs&t`4s_*^ o1 '_%ux-&{q3aaAua)QèU( BUwF-7c=kL)4 `KzipvP.0aeVsH.aTAD2wsmt.>.E׉: *!`ԽAos0 O0O@кh8'>U ) n ؋TRv%8vV?R*}ji%t3,s z$!CoO/!B-92'׋#fI;Ǘ~ zDutOK۴tbM,M#UJa6'*t?v%hm%;NM$0&+\PvNP 񗈈|Sn \ОPS/vU^dJFo0n/#`ZjHU [ⶔW`tn1-h(3`};] | `:5NwKTtB& g6.az&]_w@]i_ݢz0jI1saC&_Axr]_~SHx\*6A_ýNɑ- DP{g5SIu7ֱj2#ġ/NpS>!n?6v;|ЋC.:ԁ텘e`_Ԋ]a0@Az֬鿭>.eb ]|ܡ߯QVmdfLi ^zI qfh9'g/a7C08fϨxx5XBy2wѠw,ZS9#? G^$q7UA(?1]CxW@c^£'_9 \Ck,嶀0_ XObͫI?@2M2fhwYl&𽸯g3@S `V`'Eד˞vu:w2!U1\_GΆxmաg5ZI's{;tP /kp:oC!x&A 7ۚU']td0BG#\p?vVh%t!̥畩n,{_:֭E2)'kC18 _J) w?<XMr2#d_?^t̨Ƽ!;2;$j~Q`[=T_S!.L+Y54+ɄkT3+E]XWhpUv~Wt7 z 6]rVf}l/Ю}lk=[8BC~F3Z?3]4u`ά^zaI,TNНxEE5L$[Mo|x Z͡q:`\Z:xTv oS);PgNhoFg-'[yzē7$?Sе+@&oCF >^dWhgF7K/ӣrO0g(g7';j: A:wU`,k_^U; N[P0 ;~ C\09N}}8/ܨ0uҺvrn ݝ!uT\ݦ槣ǁqJ:U.7$7Ѓk>7G?'ޔ>t+9R/hIG..a5Gb ځ vRl fUoG(Xk;׍PO`탙ˍstZLNNQƑ?A ;7ߛ;[]}7czzyn"oމ6_wloo/tests/testthat/test_loo_moment_matching.R0000644000176200001440000003253114216213107021252 0ustar liggesuserslibrary(loo) options(mc.cores = 1) context("moment matching") set.seed(123) S <- 4000 # helper functions for sampling from the posterior distribution rinvchisq <- function(n, df, scale = 1/df, ...) { if ((length(scale) != 1) & (length(scale) != n)) stop("scale should be a scalar or a vector of the same length as x") if (df <= 0) stop("df must be greater than zero") if (any(scale <= 0)) stop("scale must be greater than zero") return((df*scale)/rchisq(n, df = df)) } dinvchisq <- function(x, df, scale=1/df, log = FALSE, ...) { if (df <= 0) stop("df must be greater than zero") if (scale <= 0) stop("scale must be greater than zero") nu <- df/2 if (log) return(ifelse(x > 0, nu*log(nu) - log(gamma(nu)) + nu*log(scale) - (nu + 1)*log(x) - (nu*scale/x), NA)) else return(ifelse(x > 0, (((nu)^(nu))/gamma(nu)) * (scale^nu) * (x^(-(nu + 1))) * exp(-nu*scale/x), NA)) } # generate toy data # normally distributed data with known variance data_sd <- 1.1 data_mean <- 1.3 n <- as.integer(30) y <- rnorm(n = n, mean = data_mean, sd = data_sd) y_tilde <- 11 y[1] <- y_tilde ymean <- mean(y) s2 <- sum((y - ymean)^2)/(n - 1) # draws from the posterior distribution when including all observations draws_full_posterior_sigma2 <- rinvchisq(S, n - 1, s2) draws_full_posterior_mu <- rnorm(S, ymean, sqrt(draws_full_posterior_sigma2/n)) # create a dummy model object x <- list() x$data <- list() x$data$y <- y x$data$n <- n x$data$ymean <- ymean x$data$s2 <- s2 x$draws <- data.frame( mu = draws_full_posterior_mu, sigma = sqrt(draws_full_posterior_sigma2) ) # implement functions for moment matching loo # extract original posterior draws post_draws_test <- function(x, ...) { as.matrix(x$draws) } # extract original log lik draws log_lik_i_test <- function(x, i, ...) { -0.5*log(2*pi) - log(x$draws$sigma) - 1.0/(2*x$draws$sigma^2)*(x$data$y[i] - x$draws$mu)^2 } loglik <- matrix(0,S,n) for (j in seq(n)) { loglik[,j] <- log_lik_i_test(x, j) } # mu, log(sigma) unconstrain_pars_test <- function(x, pars, ...) { upars <- as.matrix(pars) upars[,2] <- log(upars[,2]) upars } log_prob_upars_test <- function(x, upars, ...) { dinvchisq(exp(upars[,2])^2,x$data$n - 1,x$data$s2, log = TRUE) + dnorm(upars[,1],x$data$ymean,exp(upars[,2])/sqrt(x$data$n), log = TRUE) } # compute log_lik_i values based on the unconstrained parameters log_lik_i_upars_test <- function(x, upars, i, ...) { -0.5*log(2*pi) - upars[,2] - 1.0/(2*exp(upars[,2])^2)*(x$data$y[i] - upars[,1])^2 } upars <- unconstrain_pars_test(x, x$draws) lwi_1 <- -loglik[,1] lwi_1 <- lwi_1 - matrixStats::logSumExp(lwi_1) test_that("log_prob_upars_test works", { upars <- unconstrain_pars_test(x, x$draws) xloo <- list() xloo$data <- list() xloo$data$y <- y[-1] xloo$data$n <- n - 1 xloo$data$ymean <- mean(y[-1]) xloo$data$s2 <- sum((y[-1] - mean(y[-1]))^2)/(n - 2) post1 <- log_prob_upars_test(x,upars) post1 <- post1 - matrixStats::logSumExp(post1) post2 <- log_prob_upars_test(xloo,upars) + loglik[,1] post2 <- post2 - matrixStats::logSumExp(post2) expect_equal(post1,post2) }) test_that("loo_moment_match.default warnings work", { # loo object loo_manual <- suppressWarnings(loo(loglik)) loo_manual_tis <- suppressWarnings(loo(loglik, is_method = "tis")) expect_warning(loo_moment_match(x, loo_manual, post_draws_test, log_lik_i_test, unconstrain_pars_test, log_prob_upars_test, log_lik_i_upars_test, max_iters = 30L, k_thres = 100, split = FALSE, cov = TRUE, cores = 1), "Some Pareto k") expect_warning(loo_moment_match(x, loo_manual, post_draws_test, log_lik_i_test, unconstrain_pars_test, log_prob_upars_test, log_lik_i_upars_test, max_iters = 30L, k_thres = 0.5, split = FALSE, cov = TRUE, cores = 1), "The accuracy of self-normalized importance sampling") expect_warning(loo_moment_match(x, loo_manual, post_draws_test, log_lik_i_test, unconstrain_pars_test, log_prob_upars_test, log_lik_i_upars_test, max_iters = 1, k_thres = 0.5, split = TRUE, cov = TRUE, cores = 1), "The maximum number of moment matching iterations") expect_error(loo_moment_match(x, loo_manual_tis, post_draws_test, log_lik_i_test, unconstrain_pars_test, log_prob_upars_test, log_lik_i_upars_test, max_iters = 30L, k_thres = 0.5, split = TRUE, cov = TRUE, cores = 1), "loo_moment_match currently supports only") }) test_that("loo_moment_match.default works", { # loo object loo_manual <- suppressWarnings(loo(loglik)) loo_moment_match_object <- suppressWarnings(loo_moment_match(x, loo_manual, post_draws_test, log_lik_i_test, unconstrain_pars_test, log_prob_upars_test, log_lik_i_upars_test, max_iters = 30L, k_thres = 0.8, split = FALSE, cov = TRUE, cores = 1)) # diagnostic pareto k decreases but influence pareto k stays the same expect_lt(loo_moment_match_object$diagnostics$pareto_k[1], loo_moment_match_object$pointwise[1,"influence_pareto_k"]) expect_equal(loo_moment_match_object$pointwise[,"influence_pareto_k"],loo_manual$pointwise[,"influence_pareto_k"]) expect_equal(loo_moment_match_object$pointwise[,"influence_pareto_k"],loo_manual$diagnostics$pareto_k) expect_equal_to_reference(loo_moment_match_object, "reference-results/moment_match_loo_1.rds") loo_moment_match_object2 <- suppressWarnings(loo_moment_match(x, loo_manual, post_draws_test, log_lik_i_test, unconstrain_pars_test, log_prob_upars_test, log_lik_i_upars_test, max_iters = 30L, k_thres = 0.5, split = FALSE, cov = TRUE, cores = 1)) expect_equal_to_reference(loo_moment_match_object2, "reference-results/moment_match_loo_2.rds") loo_moment_match_object3 <- suppressWarnings(loo_moment_match(x, loo_manual, post_draws_test, log_lik_i_test, unconstrain_pars_test, log_prob_upars_test, log_lik_i_upars_test, max_iters = 30L, k_thres = 0.5, split = TRUE, cov = TRUE, cores = 1)) expect_equal_to_reference(loo_moment_match_object3, "reference-results/moment_match_loo_3.rds") loo_moment_match_object4 <- suppressWarnings(loo_moment_match(x, loo_manual, post_draws_test, log_lik_i_test, unconstrain_pars_test, log_prob_upars_test, log_lik_i_upars_test, max_iters = 30L, k_thres = 100, split = FALSE, cov = TRUE, cores = 1)) expect_equal(loo_manual,loo_moment_match_object4) loo_manual_with_psis <- suppressWarnings(loo(loglik, save_psis = TRUE)) loo_moment_match_object5 <- suppressWarnings(loo_moment_match(x, loo_manual_with_psis, post_draws_test, log_lik_i_test, unconstrain_pars_test, log_prob_upars_test, log_lik_i_upars_test, max_iters = 30L, k_thres = 0.8, split = FALSE, cov = TRUE, cores = 1)) expect_equal(loo_moment_match_object5$diagnostics,loo_moment_match_object5$psis_object$diagnostics) }) test_that("variance and covariance transformations work", { S <- 2000 set.seed(8493874) draws_full_posterior_sigma2 <- rinvchisq(S, n - 1, s2) draws_full_posterior_mu <- rnorm(S, ymean, sqrt(draws_full_posterior_sigma2/n)) x$draws <- data.frame( mu = draws_full_posterior_mu, sigma = sqrt(draws_full_posterior_sigma2) ) loglik <- matrix(0,S,n) for (j in seq(n)) { loglik[,j] <- log_lik_i_test(x, j) } upars <- unconstrain_pars_test(x, x$draws) lwi_1 <- -loglik[,1] lwi_1 <- lwi_1 - matrixStats::logSumExp(lwi_1) loo_manual <- suppressWarnings(loo(loglik)) loo_moment_match_object <- suppressWarnings(loo_moment_match(x, loo_manual, post_draws_test, log_lik_i_test, unconstrain_pars_test, log_prob_upars_test, log_lik_i_upars_test, max_iters = 30L, k_thres = 0.0, split = FALSE, cov = TRUE, cores = 1)) expect_equal_to_reference(loo_moment_match_object, "reference-results/moment_match_var_and_cov.rds") }) test_that("loo_moment_match.default works with multiple cores", { # loo object loo_manual <- suppressWarnings(loo(loglik)) loo_moment_match_manual3 <- suppressWarnings(loo_moment_match(x, loo_manual, post_draws_test, log_lik_i_test, unconstrain_pars_test, log_prob_upars_test, log_lik_i_upars_test, max_iters = 30L, k_thres = 0.5, split = FALSE, cov = TRUE, cores = 1)) loo_moment_match_manual4 <- suppressWarnings(loo_moment_match(x, loo_manual, post_draws_test, log_lik_i_test, unconstrain_pars_test, log_prob_upars_test, log_lik_i_upars_test, max_iters = 30L, k_thres = 0.5, split = FALSE, cov = TRUE, cores = 2)) expect_equal(loo_moment_match_manual3$diagnostics$pareto_k, loo_moment_match_manual4$diagnostics$pareto_k) expect_equal(loo_moment_match_manual3$diagnostics$n_eff, loo_moment_match_manual4$diagnostics$n_eff) expect_equal(loo_moment_match_manual3$estimates, loo_moment_match_manual4$estimates) expect_equal(loo_moment_match_manual3$pointwise, loo_moment_match_manual4$pointwise, tolerance=5e-4) }) test_that("loo_moment_match_split works", { # skip on M1 Mac until we figure out why this test fails only on M1 Mac skip_if(Sys.info()[["sysname"]] == "Darwin" && R.version$arch == "aarch64") is_obj_1 <- suppressWarnings(importance_sampling.default(lwi_1, method = "psis", r_eff = 1, cores = 1)) lwi_1_ps <- as.vector(weights(is_obj_1)) split <- loo_moment_match_split( x, upars, cov = FALSE, total_shift = c(0,0), total_scaling = c(1,1), total_mapping = diag(c(1,1)), i = 1, log_prob_upars = log_prob_upars_test, log_lik_i_upars = log_lik_i_upars_test, cores = 1, r_eff_i = 1, is_method = "psis") expect_named(split,c("lwi", "lwfi", "log_liki", "r_eff_i")) expect_equal(lwi_1_ps,split$lwi) split2 <- loo_moment_match_split( x, upars, cov = FALSE, total_shift = c(-0.1,-0.2), total_scaling = c(0.7,0.7), total_mapping = matrix(c(1,0.1,0.1,1),2,2), i = 1, log_prob_upars = log_prob_upars_test, log_lik_i_upars = log_lik_i_upars_test, cores = 1, r_eff_i = 1, is_method = "psis") expect_equal_to_reference(split2, "reference-results/moment_match_split.rds") }) test_that("passing arguments works", { log_lik_i_upars_test_additional_argument <- function(x, upars, i, passed_arg = FALSE, ...) { if (!passed_arg) { warning("passed_arg was not passed here") } -0.5*log(2*pi) - upars[,2] - 1.0/(2*exp(upars[,2])^2)*(x$data$y[i] - upars[,1])^2 } unconstrain_pars_test_additional_argument <- function(x, pars, passed_arg = FALSE, ...) { if (!passed_arg) { warning("passed_arg was not passed here") } upars <- as.matrix(pars) upars[,2] <- log(upars[,2]) upars } log_prob_upars_test_additional_argument <- function(x, upars, passed_arg = FALSE, ...) { if (!passed_arg) { warning("passed_arg was not passed here") } dinvchisq(exp(upars[,2])^2,x$data$n - 1,x$data$s2, log = TRUE) + dnorm(upars[,1],x$data$ymean,exp(upars[,2])/sqrt(x$data$n), log = TRUE) } post_draws_test_additional_argument <- function(x, passed_arg = FALSE, ...) { if (!passed_arg) { warning("passed_arg was not passed here") } as.matrix(x$draws) } log_lik_i_test_additional_argument <- function(x, i, passed_arg = FALSE, ...) { if (!passed_arg) { warning("passed_arg was not passed here") } -0.5*log(2*pi) - log(x$draws$sigma) - 1.0/(2*x$draws$sigma^2)*(x$data$y[i] - x$draws$mu)^2 } # loo object loo_manual <- suppressWarnings(loo(loglik)) expect_silent(loo_moment_match(x, loo_manual, post_draws_test_additional_argument, log_lik_i_test_additional_argument, unconstrain_pars_test_additional_argument, log_prob_upars_test_additional_argument, log_lik_i_upars_test_additional_argument, max_iters = 30L, k_thres = 0.5, split = TRUE, cov = TRUE, cores = 1, passed_arg = TRUE)) }) loo/tests/testthat/test_loo_and_waic.R0000644000176200001440000001504114411130104017633 0ustar liggesuserslibrary(loo) options(mc.cores = 1) set.seed(123) context("loo, waic and elpd") LLarr <- example_loglik_array() LLmat <- example_loglik_matrix() LLvec <- LLmat[, 1] chain_id <- rep(1:2, each = nrow(LLarr)) r_eff_arr <- relative_eff(exp(LLarr)) r_eff_mat <- relative_eff(exp(LLmat), chain_id = chain_id) loo1 <- suppressWarnings(loo(LLarr, r_eff = r_eff_arr)) waic1 <- suppressWarnings(waic(LLarr)) elpd1 <- suppressWarnings(elpd(LLarr)) test_that("using loo.cores is deprecated", { options(mc.cores = NULL) options(loo.cores = 1) expect_warning(loo(LLarr, r_eff = r_eff_arr, cores = 2), "loo.cores") options(loo.cores = NULL) options(mc.cores = 1) }) test_that("loo, waic and elpd results haven't changed", { expect_equal_to_reference(loo1, "reference-results/loo.rds") expect_equal_to_reference(waic1, "reference-results/waic.rds") expect_equal_to_reference(elpd1, "reference-results/elpd.rds") }) test_that("loo with cores=1 and cores=2 gives same results", { loo2 <- suppressWarnings(loo(LLarr, r_eff = r_eff_arr, cores = 2)) expect_equal(loo1$estimates, loo2$estimates) }) test_that("waic returns object with correct structure", { expect_true(is.waic(waic1)) expect_true(is.loo(waic1)) expect_false(is.psis_loo(waic1)) expect_named( waic1, c( "estimates", "pointwise", # deprecated but still there "elpd_waic", "p_waic", "waic", "se_elpd_waic", "se_p_waic", "se_waic" ) ) est_names <- dimnames(waic1$estimates) expect_equal(est_names[[1]], c("elpd_waic", "p_waic", "waic")) expect_equal(est_names[[2]], c("Estimate", "SE")) expect_equal(colnames(waic1$pointwise), est_names[[1]]) expect_equal(dim(waic1), dim(LLmat)) }) test_that("loo returns object with correct structure", { expect_false(is.waic(loo1)) expect_true(is.loo(loo1)) expect_true(is.psis_loo(loo1)) expect_named( loo1, c( "estimates", "pointwise", "diagnostics", "psis_object", # deprecated but still there "elpd_loo", "p_loo", "looic", "se_elpd_loo", "se_p_loo", "se_looic" ) ) expect_named(loo1$diagnostics, c("pareto_k", "n_eff")) expect_equal(dimnames(loo1$estimates)[[1]], c("elpd_loo", "p_loo", "looic")) expect_equal(dimnames(loo1$estimates)[[2]], c("Estimate", "SE")) expect_equal(colnames(loo1$pointwise), c("elpd_loo", "mcse_elpd_loo", "p_loo", "looic", "influence_pareto_k")) expect_equal(dim(loo1), dim(LLmat)) }) test_that("elpd returns object with correct structure", { expect_true(is.loo(elpd1)) expect_named( elpd1, c( "estimates", "pointwise" ) ) est_names <- dimnames(elpd1$estimates) expect_equal(est_names[[1]], c("elpd", "ic")) expect_equal(est_names[[2]], c("Estimate", "SE")) expect_equal(colnames(elpd1$pointwise), est_names[[1]]) expect_equal(dim(elpd1), dim(LLmat)) }) test_that("two pareto k values are equal", { expect_identical(loo1$pointwise[,"influence_pareto_k"], loo1$diagnostics$pareto_k) }) test_that("loo.array and loo.matrix give same result", { l2 <- suppressWarnings(loo(LLmat, r_eff = r_eff_mat)) expect_identical(loo1$estimates, l2$estimates) expect_identical(loo1$diagnostics, l2$diagnostics) # the mcse_elpd_loo columns won't be identical because we use sampling expect_identical(loo1$pointwise[, -2], l2$pointwise[, -2]) expect_equal(loo1$pointwise[, 2], l2$pointwise[, 2], tol = 0.005) }) test_that("loo.array runs with multiple cores", { loo_with_arr1 <- loo(LLarr, cores = 1, r_eff = NA) loo_with_arr2 <- loo(LLarr, cores = 2, r_eff = NA) expect_identical(loo_with_arr1$estimates, loo_with_arr2$estimates) }) test_that("waic.array and waic.matrix give same result", { waic2 <- suppressWarnings(waic(LLmat)) expect_identical(waic1, waic2) }) test_that("elpd.array and elpd.matrix give same result", { elpd2 <- suppressWarnings(elpd(LLmat)) expect_identical(elpd1, elpd2) }) test_that("loo, waic, and elpd error with vector input", { expect_error(loo(LLvec), regexp = "no applicable method") expect_error(waic(LLvec), regexp = "no applicable method") expect_error(elpd(LLvec), regexp = "no applicable method") }) # testing function methods ------------------------------------------------ source(test_path("data-for-tests/function_method_stuff.R")) waic_with_fn <- waic(llfun, data = data, draws = draws) waic_with_mat <- waic(llmat_from_fn) loo_with_fn <- loo(llfun, data = data, draws = draws, r_eff = rep(1, nrow(data))) loo_with_mat <- loo(llmat_from_fn, r_eff = rep(1, ncol(llmat_from_fn)), save_psis = TRUE) test_that("loo.cores deprecation warning works with function method", { options(loo.cores = 1) expect_warning(loo(llfun, cores = 2, data = data, draws = draws, r_eff = rep(1, nrow(data))), "loo.cores") options(loo.cores=NULL) }) test_that("loo_i results match loo results for ith data point", { expect_warning( loo_i_val <- loo_i(i = 2, llfun = llfun, data = data, draws = draws), "Relative effective sample sizes" ) expect_equal(loo_i_val$pointwise[, "elpd_loo"], loo_with_fn$pointwise[2, "elpd_loo"]) expect_equal(loo_i_val$pointwise[, "p_loo"], loo_with_fn$pointwise[2, "p_loo"]) expect_equal(loo_i_val$diagnostics$pareto_k, loo_with_fn$diagnostics$pareto_k[2]) expect_equal(loo_i_val$diagnostics$n_eff, loo_with_fn$diagnostics$n_eff[2]) }) test_that("function and matrix methods return same result", { expect_equal(waic_with_mat, waic_with_fn) expect_identical(loo_with_mat$estimates, loo_with_fn$estimates) expect_identical(loo_with_mat$diagnostics, loo_with_fn$diagnostics) expect_identical(dim(loo_with_mat), dim(loo_with_fn)) }) test_that("loo.function runs with multiple cores", { loo_with_fn1 <- loo(llfun, data = data, draws = draws, r_eff = rep(1, nrow(data)), cores = 1) loo_with_fn2 <- loo(llfun, data = data, draws = draws, r_eff = rep(1, nrow(data)), cores = 2) expect_identical(loo_with_fn2$estimates, loo_with_fn1$estimates) }) test_that("save_psis option to loo.function makes correct psis object", { loo_with_fn2 <- loo.function(llfun, data = data, draws = draws, r_eff = rep(1, nrow(data)), save_psis = TRUE) expect_identical(loo_with_fn2$psis_object, loo_with_mat$psis_object) }) test_that("loo throws r_eff warnings", { expect_warning(loo(-LLarr), "MCSE estimates will be over-optimistic") expect_warning(loo(-LLmat), "MCSE estimates will be over-optimistic") expect_warning(loo(llfun, data = data, draws = draws), "MCSE estimates will be over-optimistic") }) loo/tests/testthat/test_tisis.R0000644000176200001440000001253513701164066016374 0ustar liggesuserslibrary(loo) options(mc.cores=1) options(loo.cores=NULL) set.seed(123) context("tis and is") LLarr <- example_loglik_array() LLmat <- example_loglik_matrix() LLvec <- LLmat[, 1] chain_id <- rep(1:2, each = dim(LLarr)[1]) r_eff_arr <- relative_eff(exp(LLarr)) r_eff_vec <- relative_eff(exp(LLvec), chain_id = chain_id) psis1 <- psis(log_ratios = -LLarr, r_eff = r_eff_arr) tis1 <- tis(log_ratios = -LLarr, r_eff = r_eff_arr) is1 <- sis(log_ratios = -LLarr, r_eff = r_eff_arr) test_that("tis and is runs", { LLvec[1] <- -10 expect_silent(tis1 <- tis(log_ratios = -LLvec, r_eff = r_eff_vec)) expect_silent(is1 <- sis(log_ratios = -LLvec, r_eff = r_eff_vec)) expect_failure(expect_equal(tis1$log_weights, is1$log_weights)) expect_failure(expect_equal(tis1$log_weights, psis1$log_weights)) }) test_that("tis() and sis() returns object with correct structure for tis/sis", { expect_false(is.psis(tis1)) expect_false(is.psis(is1)) expect_true(is.tis(tis1)) expect_false(is.tis(is1)) expect_false(is.sis(tis1)) expect_true(is.sis(is1)) expect_false(is.loo(tis1)) expect_false(is.loo(is1)) expect_false(is.psis_loo(tis1)) expect_false(is.psis_loo(is1)) expect_named(tis1, c("log_weights", "diagnostics")) expect_named(is1, c("log_weights", "diagnostics")) expect_named(tis1$diagnostics, c("pareto_k", "n_eff")) expect_named(is1$diagnostics, c("pareto_k", "n_eff")) expect_equal(dim(tis1), dim(LLmat)) expect_equal(dim(is1), dim(LLmat)) expect_length(tis1$diagnostics$pareto_k, dim(psis1)[2]) expect_length(is1$diagnostics$pareto_k, dim(psis1)[2]) expect_length(tis1$diagnostics$n_eff, dim(psis1)[2]) expect_length(is1$diagnostics$n_eff, dim(psis1)[2]) expect_equal(attr(psis1, "method")[1], "psis") expect_equal(attr(tis1, "method")[1], "tis") expect_equal(attr(is1, "method")[1], "sis") }) test_that("psis methods give same results", { tis2 <- suppressWarnings(tis(-LLmat, r_eff = r_eff_arr)) expect_identical(tis1, tis2) tisvec <- suppressWarnings(tis(-LLvec, r_eff = r_eff_vec)) tismat <- suppressWarnings(tis(-LLmat[, 1], r_eff = r_eff_vec)) expect_identical(tisvec, tismat) is2 <- suppressWarnings(sis(-LLmat, r_eff = r_eff_arr)) expect_identical(is1, is2) isvec <- suppressWarnings(sis(-LLvec, r_eff = r_eff_vec)) ismat <- suppressWarnings(sis(-LLmat[, 1], r_eff = r_eff_vec)) expect_identical(isvec, ismat) }) test_that("psis throws correct errors and warnings", { # r_eff=NULL warnings expect_warning(tis(-LLarr), "Relative effective sample sizes") expect_warning(tis(-LLmat), "Relative effective sample sizes") expect_warning(tis(-LLmat[, 1]), "Relative effective sample sizes") # r_eff=NA disables warnings expect_silent(tis(-LLarr, r_eff = NA)) expect_silent(tis(-LLmat, r_eff = NA)) expect_silent(tis(-LLmat[,1], r_eff = NA)) # r_eff=NULL and r_eff=NA give same answer expect_equal( suppressWarnings(tis(-LLarr)), tis(-LLarr, r_eff = NA) ) # r_eff wrong length is error expect_error(tis(-LLarr, r_eff = r_eff_arr[-1]), "one value per observation") # r_eff has some NA values causes error r_eff_arr[2] <- NA expect_error(tis(-LLarr, r_eff = r_eff_arr), "mix NA and not NA values") # no NAs or non-finite values allowed LLmat[1,1] <- NA expect_error(tis(-LLmat), "NAs not allowed in input") LLmat[1,1] <- 1 LLmat[10, 2] <- Inf expect_error(tis(-LLmat), "All input values must be finite") # no lists allowed expect_error(expect_warning(tis(as.list(-LLvec)), "List not allowed as input")) # if array, must be 3-D array dim(LLarr) <- c(2, 250, 2, 32) expect_error( tis(-LLarr), "length(dim(log_ratios)) == 3 is not TRUE", fixed = TRUE ) }) test_that("explict test of values for 'sis' and 'tis'", { lw <- 1:16 expect_silent(tis_true <- tis(log_ratios = lw, r_eff = NA)) expect_equal(as.vector(weights(tis_true, log = TRUE, normalize = FALSE)), c(-14.0723, -13.0723, -12.0723, -11.0723, -10.0723, -9.0723, -8.0723, -7.0723, -6.0723, -5.0723, -4.0723, -3.0723, -2.0723, -1.0723, -0.0723, 0.) + 15.07238, tol = 0.001) expect_silent(is_true <- sis(log_ratios = lw, r_eff = NA)) expect_equal(as.vector(weights(is_true, log = TRUE, normalize = FALSE)), lw, tol = 0.00001) lw <- c(0.7609420, 1.3894140, 0.4158346, 2.5307927, 4.3379119, 2.4159240, 2.2462172, 0.8057697, 0.9333107, 1.5599302) expect_silent(tis_true <- tis(log_ratios = lw, r_eff = NA)) expect_equal(as.vector(weights(tis_true, log = TRUE, normalize = FALSE)), c(-2.931, -2.303, -3.276, -1.161, 0, -1.276, -1.446, -2.886, -2.759, -2.132) + 3.692668, tol = 0.001) expect_silent(is_true <- sis(log_ratios = lw, r_eff = NA)) expect_equal(as.vector(weights(is_true, log = TRUE, normalize = FALSE)), lw, tol = 0.00001) }) test_that("tis_loo and sis_loo are returned", { LLmat <- example_loglik_matrix() loo_psis <- suppressWarnings(loo(LLmat, r_eff = NA, is_method = "psis")) loo_tis <- suppressWarnings(loo(LLmat, r_eff = NA, is_method = "tis")) loo_sis <- suppressWarnings(loo(LLmat, r_eff = NA, is_method = "sis")) expect_s3_class(loo_tis, "tis_loo") expect_s3_class(loo_sis, "sis_loo") expect_s3_class(loo_tis, "importance_sampling_loo") expect_s3_class(loo_sis, "importance_sampling_loo") expect_output(print(loo_tis), regexp = "tis_loo") expect_output(print(loo_sis), regexp = "sis_loo") }) loo/tests/testthat/test_loo_predictive_metric.R0000644000176200001440000001377214411130104021600 0ustar liggesusersLL <- example_loglik_matrix() chain_id <- rep(1:2, each = dim(LL)[1] / 2) r_eff <- relative_eff(exp(LL), chain_id) psis_obj <- psis(-LL, r_eff = r_eff, cores = 2) set.seed(123) x <- matrix(rnorm(length(LL)), nrow = nrow(LL), ncol = ncol(LL)) x_prob <- 1 / (1 + exp(-x)) y <- rnorm(ncol(LL)) y_binary <- rbinom(ncol(LL), 1, 0.5) mae_mean <- loo_predictive_metric(x, y, LL, metric = 'mae', r_eff = r_eff) mae_quant <- loo_predictive_metric(x, y, LL, metric = 'mae', r_eff = r_eff, type = 'quantile', probs = 0.9) rmse_mean <- loo_predictive_metric(x, y, LL, metric = 'rmse', r_eff = r_eff) rmse_quant <- loo_predictive_metric(x, y, LL, metric = 'rmse', r_eff = r_eff, type = 'quantile', probs = 0.9) mse_mean <- loo_predictive_metric(x, y, LL, metric = 'mse', r_eff = r_eff) mse_quant <- loo_predictive_metric(x, y, LL, metric = 'mse', r_eff = r_eff, type = 'quantile', probs = 0.9) acc_mean <- loo_predictive_metric(x_prob, y_binary, LL, metric = 'acc', r_eff = r_eff) acc_quant <- loo_predictive_metric(x_prob, y_binary, LL, metric = 'acc', r_eff = r_eff, type = 'quantile', probs = 0.9) bacc_mean <- loo_predictive_metric(x_prob, y_binary, LL, metric = 'balanced_acc', r_eff = r_eff) bacc_quant <- loo_predictive_metric(x_prob, y_binary, LL, metric = 'balanced_acc', r_eff = r_eff, type = 'quantile', probs = 0.9) test_that('loo_predictive_metric stops with incorrect inputs', { expect_error(loo_predictive_metric(as.character(x), y, LL, r_eff = r_eff), 'no applicable method', fixed = TRUE) expect_error(loo_predictive_metric(x, as.character(y), LL, r_eff = r_eff), 'is.numeric(y) is not TRUE', fixed = TRUE) x_invalid <- matrix(rnorm(9), nrow = 3) expect_error(loo_predictive_metric(x_invalid, y, LL, r_eff = r_eff), 'identical(ncol(x), length(y)) is not TRUE', fixed = TRUE) x_invalid <- matrix(rnorm(64), nrow = 2) expect_error(loo_predictive_metric(x_invalid, y, LL, r_eff = r_eff), 'identical(dim(x), dim(log_lik)) is not TRUE', fixed = TRUE) }) test_that('loo_predictive_metric return types are correct', { # MAE expect_type(mae_mean, 'list') expect_type(mae_quant, 'list') expect_named(mae_mean, c('estimate', 'se')) expect_named(mae_quant, c('estimate', 'se')) # RMSE expect_type(rmse_mean, 'list') expect_type(rmse_quant, 'list') expect_named(rmse_mean, c('estimate', 'se')) expect_named(rmse_quant, c('estimate', 'se')) # MSE expect_type(mse_mean, 'list') expect_type(mse_quant, 'list') expect_named(mse_mean, c('estimate', 'se')) expect_named(mse_quant, c('estimate', 'se')) # Accuracy expect_type(acc_mean, 'list') expect_type(acc_quant, 'list') expect_named(acc_mean, c('estimate', 'se')) expect_named(acc_quant, c('estimate', 'se')) # Balanced accuracy expect_type(bacc_mean, 'list') expect_type(bacc_quant, 'list') expect_named(bacc_mean, c('estimate', 'se')) expect_named(bacc_quant, c('estimate', 'se')) }) test_that('loo_predictive_metric is equal to reference', { expect_equal_to_reference(mae_mean, 'reference-results/loo_predictive_metric_mae_mean.rds') expect_equal_to_reference(mae_quant, 'reference-results/loo_predictive_metric_mae_quant.rds') expect_equal_to_reference(rmse_mean, 'reference-results/loo_predictive_metric_rmse_mean.rds') expect_equal_to_reference(rmse_quant, 'reference-results/loo_predictive_metric_rmse_quant.rds') expect_equal_to_reference(mse_mean, 'reference-results/loo_predictive_metric_mse_mean.rds') expect_equal_to_reference(mse_quant, 'reference-results/loo_predictive_metric_mse_quant.rds') expect_equal_to_reference(acc_mean, 'reference-results/loo_predictive_metric_acc_mean.rds') expect_equal_to_reference(acc_quant, 'reference-results/loo_predictive_metric_acc_quant.rds') expect_equal_to_reference(bacc_mean, 'reference-results/loo_predictive_metric_bacc_mean.rds') expect_equal_to_reference(bacc_quant, 'reference-results/loo_predictive_metric_bacc_quant.rds') }) test_that('MAE computation is correct', { expect_equal( .mae(rep(0.5, 5), rep(1, 5))$estimate, 0.5) expect_equal( .mae(rep(0.5, 5), rep(1, 5))$se, 0.0) expect_error( .mae(rep(0.5, 5), rep(1, 3)), 'length(y) == length(yhat) is not TRUE', fixed = TRUE) }) test_that('MSE computation is correct', { expect_equal( .mse(rep(0.5, 5), rep(1, 5))$estimate, 0.25) expect_equal( .mse(rep(0.5, 5), rep(1, 5))$se, 0.0) expect_error( .mse(rep(0.5, 5), rep(1, 3)), 'length(y) == length(yhat) is not TRUE', fixed = TRUE) }) test_that('RMSE computation is correct', { expect_equal( .rmse(rep(0.5, 5), rep(1, 5))$estimate, sqrt(0.25)) expect_equal( .mse(rep(0.5, 5), rep(1, 5))$se, 0.0) expect_error( .mse(rep(0.5, 5), rep(1, 3)), 'length(y) == length(yhat) is not TRUE', fixed = TRUE) }) test_that('Accuracy computation is correct', { expect_equal( .accuracy(c(0, 0, 0, 1, 1, 1), c(0.2, 0.2, 0.2, 0.7, 0.7, 0.7))$estimate, 1.0 ) expect_error( .accuracy(c(1, 0), c(0.5)), 'length(y) == length(yhat) is not TRUE', fixed = TRUE) expect_error( .accuracy(c(2, 1), c(0.5, 0.5)), 'all(y <= 1 & y >= 0) is not TRUE', fixed = TRUE ) expect_error( .accuracy(c(1, 0), c(1.1, 0.5)), 'all(yhat <= 1 & yhat >= 0) is not TRUE', fixed = TRUE ) }) test_that('Balanced accuracy computation is correct', { expect_equal( .balanced_accuracy(c(0, 0, 1, 1, 1, 1), c(0.9, 0.9, 0.9, 0.9, 0.9, 0.9))$estimate, 0.5 ) expect_error( .balanced_accuracy(c(1, 0), c(0.5)), 'length(y) == length(yhat) is not TRUE', fixed = TRUE) expect_error( .balanced_accuracy(c(2, 1), c(0.5, 0.5)), 'all(y <= 1 & y >= 0) is not TRUE', fixed = TRUE ) expect_error( .balanced_accuracy(c(1, 0), c(1.1, 0.5)), 'all(yhat <= 1 & yhat >= 0) is not TRUE', fixed = TRUE ) }) loo/tests/testthat/test_model_weighting.R0000644000176200001440000001005214410420140020360 0ustar liggesuserslibrary(loo) context("loo_model_weights") # generate fake data set.seed(123) y<-rnorm(50,0,1) sd_sim1<- abs(rnorm(500,1.5, 0.1)) sd_sim2<- abs(rnorm(500,1.2, 0.1)) sd_sim3<- abs(rnorm(500,1, 0.05)) log_lik1 <- log_lik2 <- log_lik3 <- matrix(NA, 500, 50) for(s in 1:500) { log_lik1[s,] <- dnorm(y,-1,sd_sim1[s], log=T) log_lik2[s,] <- dnorm(y,0.7,sd_sim2[s], log=T) log_lik3[s,] <- dnorm(y,1,sd_sim3[s], log=T) } ll_list <- list(log_lik1, log_lik2,log_lik3) r_eff_list <- list(rep(0.9,50), rep(0.9,50), rep(0.9,50)) loo_list <- lapply(1:length(ll_list), function(j) { loo(ll_list[[j]], r_eff = r_eff_list[[j]]) }) tol <- 0.01 # absoulte tolerance of weights test_that("loo_model_weights throws correct errors and warnings", { expect_error(loo_model_weights(log_lik1), "list of matrices or a list of 'psis_loo' objects") expect_error(loo_model_weights(list(log_lik1)), "At least two models") expect_error(loo_model_weights(list(loo_list[[1]])), "At least two models") expect_error(loo_model_weights(list(log_lik1), method = "pseudobma"), "At least two models") expect_error(loo_model_weights(list(log_lik1, log_lik2[-1, ])), "same dimensions") expect_error(loo_model_weights(list(log_lik1, log_lik2, log_lik3[, -1])), "same dimensions") loo_list2 <- loo_list attr(loo_list2[[3]], "dims") <- c(10, 10) expect_error(loo_model_weights(loo_list2), "same dimensions") expect_error(loo_model_weights(ll_list, r_eff_list = r_eff_list[-1]), "one component for each model") r_eff_list[[3]] <- rep(0.9, 51) expect_error(loo_model_weights(ll_list, r_eff_list = r_eff_list), "same length as the number of columns") expect_error(loo_model_weights(list(loo_list[[1]], 2)), "List elements must all be 'psis_loo' objects or log-likelihood matrices", fixed = TRUE) expect_warning(loo_model_weights(ll_list), "Relative effective sample sizes") }) test_that("loo_model_weights (stacking and pseudo-BMA) gives expected result", { w1 <- loo_model_weights(ll_list, method = "stacking", r_eff_list = r_eff_list) expect_type(w1,"double") expect_s3_class(w1, "stacking_weights") expect_length(w1, 3) expect_named(w1, paste0("model" ,c(1:3))) expect_equal_to_reference(as.numeric(w1), "reference-results/model_weights_stacking.rds", tolerance = tol, scale=1) expect_output(print(w1), "Method: stacking") w1_b <- loo_model_weights(loo_list) expect_identical(w1, w1_b) w2 <- loo_model_weights(ll_list, r_eff_list=r_eff_list, method = "pseudobma", BB = TRUE) expect_type(w2, "double") expect_s3_class(w2, "pseudobma_bb_weights") expect_length(w2, 3) expect_named(w2, paste0("model", c(1:3))) expect_equal_to_reference(as.numeric(w2), "reference-results/model_weights_pseudobma.rds", tolerance = tol, scale=1) expect_output(print(w2), "Method: pseudo-BMA+") w3 <- loo_model_weights(ll_list, r_eff_list=r_eff_list, method = "pseudobma", BB = FALSE) expect_type(w3,"double") expect_length(w3, 3) expect_named(w3, paste0("model" ,c(1:3))) expect_equal(as.numeric(w3), c(5.365279e-05, 9.999436e-01, 2.707028e-06), tolerance = tol, scale = 1) expect_output(print(w3), "Method: pseudo-BMA") w3_b <- loo_model_weights(loo_list, method = "pseudobma", BB = FALSE) expect_identical(w3, w3_b) }) test_that("stacking_weights and pseudobma_weights throw correct errors", { xx <- cbind(rnorm(10)) expect_error(stacking_weights(xx), "two models are required") expect_error(pseudobma_weights(xx), "two models are required") }) test_that("loo_model_weights uses correct names for list of loo objects", { loo1 <- loo_list[[1]] loo2 <- loo_list[[2]] loo3 <- loo_list[[3]] expect_named( loo_model_weights(list(loo1, loo2, loo3)), c("model1", "model2", "model3") ) expect_named( loo_model_weights(list("a" = loo1, loo2, "c" = loo3)), c("a", "model2", "c") ) expect_named( loo_model_weights(list(`a` = loo1, `b` = loo2, `c` = loo3)), c("a", "b", "c") ) }) loo/tests/testthat/test_crps.R0000644000176200001440000000436214411130104016170 0ustar liggesusersset.seed(123456789) n <- 10 S <- 100 y <- rnorm(n) x1 <- matrix(rnorm(n * S), nrow = S) x2 <- matrix(rnorm(n * S), nrow = S) ll <- matrix(rnorm(n * S) * 0.1 - 1, nrow = S) with_seed <- function(seed, code) { code <- substitute(code) orig.seed <- .Random.seed on.exit(.Random.seed <<- orig.seed) set.seed(seed) eval.parent(code) } test_that("crps computation is correct", { expect_equal(.crps_fun(2.0, 1.0), 0.0) expect_equal(.crps_fun(1.0, 2.0), -1.5) expect_equal(.crps_fun(pi, pi^2), 0.5 * pi - pi^2) expect_equal(.crps_fun(1.0, 0.0, scale = TRUE), 0.0) expect_equal(.crps_fun(1.0, 2.0, scale = TRUE), -2.0) expect_equal(.crps_fun(pi, pi^2, scale = TRUE), -pi^2/pi - 0.5 * log(pi)) }) test_that("crps matches references", { expect_equal_to_reference(with_seed(1, crps(x1, x2, y)), 'reference-results/crps.rds') expect_equal_to_reference(with_seed(1, scrps(x1, x2, y)), 'reference-results/scrps.rds') # Suppress warnings for the missing r_eff suppressWarnings(expect_equal_to_reference( with_seed(1, loo_crps(x1, x2, y, ll)), 'reference-results/loo_crps.rds')) suppressWarnings(expect_equal_to_reference( with_seed(1, loo_scrps(x1, x2, y, ll)), 'reference-results/loo_scrps.rds')) }) test_that("input validation throws correct errors", { expect_error(validate_crps_input(as.character(x1), x2, y), "is.numeric(x) is not TRUE", fixed = TRUE) expect_error(validate_crps_input(x1, as.character(x2), y), "is.numeric(x2) is not TRUE", fixed = TRUE) expect_error(validate_crps_input(x1, x2, c('a', 'b')), "is.numeric(y) is not TRUE", fixed = TRUE) expect_error(validate_crps_input(x1, t(x2), y), "identical(dim(x), dim(x2)) is not TRUE", fixed = TRUE) expect_error(validate_crps_input(x1, x2, c(1, 2)), "ncol(x) == length(y) is not TRUE", fixed = TRUE) expect_error(validate_crps_input(x1, x2, y, t(ll)), "ifelse(is.null(log_lik), TRUE, identical(dim(log_lik), dim(x))) is not TRUE", fixed = TRUE) }) test_that("methods for single data point don't error", { expect_silent(crps(x1[,1], x2[,1], y[1])) expect_silent(scrps(x1[,1], x2[,1], y[1])) }) loo/tests/testthat/test_print_plot.R0000644000176200001440000001317513701164066017434 0ustar liggesuserslibrary(loo) set.seed(1414) context("print, plot, diagnostics") LLarr <- example_loglik_array() waic1 <- suppressWarnings(waic(LLarr)) loo1 <- suppressWarnings(loo(LLarr)) psis1 <- suppressWarnings(psis(-LLarr)) # plotting ---------------------------------------------------------------- test_that("plot methods don't error", { expect_silent(plot(loo1, label_points = FALSE)) expect_silent(plot(psis1, label_points = TRUE)) expect_silent(plot(psis1, diagnostic = "n_eff", label_points = FALSE)) loo1$diagnostics$pareto_k[1] <- 10 expect_silent(plot(loo1, label_points = TRUE)) expect_output(print(loo1, plot_k = TRUE)) expect_output(print(psis1, plot_k = TRUE)) }) test_that("plot methods throw appropriate errors/warnings", { expect_error(plot(waic1), regexp = "No Pareto k estimates found") loo1$diagnostics$pareto_k[1:5] <- Inf psis1$diagnostics$pareto_k[1:5] <- Inf expect_warning(plot(loo1), regexp = "estimates are Inf/NA/NaN and not plotted.") expect_warning(plot(psis1), regexp = "estimates are Inf/NA/NaN and not plotted.") }) # printing ---------------------------------------------------------------- lldim_msg <- paste0("Computed from ", prod(dim(LLarr)[1:2]) , " by ", dim(LLarr)[3], " log-likelihood matrix") lwdim_msg <- paste0("Computed from ", prod(dim(LLarr)[1:2]) , " by ", dim(LLarr)[3], " log-weights matrix") test_that("print.waic output is ok",{ expect_output(print(waic1), lldim_msg) expect_output(print(waic1), "p_waic estimates greater than 0.4. We recommend trying loo instead." ) }) test_that("print.psis_loo and print.psis output ok",{ expect_output(print(psis1), lwdim_msg) expect_output(print(psis1), "Pareto k estimates are good") expect_output(print(loo1), lldim_msg) expect_output(print(loo1), "Pareto k estimates are good") loo1$diagnostics$pareto_k <- psis1$diagnostics$pareto_k <- runif(32, 0, .49) expect_output(print(loo1), regexp = "Pareto k estimates are good") expect_output(print(psis1), regexp = "Pareto k estimates are good") loo1$diagnostics$pareto_k[1] <- psis1$diagnostics$pareto_k[1] <- 0.71 expect_output(print(loo1), regexp = "Pareto k diagnostic") loo1$diagnostics$pareto_k[1] <- psis1$diagnostics$pareto_k[1] <- 1.1 expect_output(print(loo1), regexp = "Pareto k diagnostic") }) # pareto_k_[ids,values,table] --------------------------------------------- test_that("pareto_k_values works for psis_loo and psis objects, errors for waic", { kpsis <- pareto_k_values(psis1) kloo <- pareto_k_values(loo1) expect_identical(kpsis, kloo) expect_identical(kpsis, psis1$diagnostics$pareto_k) expect_error(pareto_k_values(waic1), "No Pareto k estimates found") }) test_that("pareto_k_influence_values works for psis_loo objects, errors for psis waic", { kloo <- pareto_k_influence_values(loo1) kloo2 <- pareto_k_values(loo1) expect_identical(kloo, kloo2) expect_error(pareto_k_influence_values(psis1), "No Pareto k influence estimates found") expect_error(pareto_k_influence_values(waic1), "No Pareto k influence estimates found") }) test_that("pareto_k_ids identifies correct observations", { for (j in 1:5) { loo1$diagnostics$pareto_k <- psis1$diagnostics$pareto_k <- runif(32, .25, 1.25) expect_identical( pareto_k_ids(loo1, threshold = 0.5), pareto_k_ids(psis1, threshold = 0.5) ) expect_identical( pareto_k_ids(loo1, threshold = 0.5), which(pareto_k_values(loo1) > 0.5) ) expect_identical( pareto_k_ids(psis1, threshold = 0.7), which(pareto_k_values(psis1) > 0.7) ) } }) test_that("pareto_k_table gives correct output", { psis1$diagnostics$pareto_k[1:10] <- runif(10, 0, 0.49) psis1$diagnostics$pareto_k[11:17] <- runif(7, 0.51, 0.69) psis1$diagnostics$pareto_k[18:20] <- runif(3, 0.71, 0.99) psis1$diagnostics$pareto_k[21:32] <- runif(12, 1, 10) k <- pareto_k_values(psis1) tab <- pareto_k_table(psis1) expect_output(print(tab), "Pareto k diagnostic values") expect_identical(colnames(tab), c("Count", "Proportion", "Min. n_eff")) expect_equal(sum(tab[, "Count"]), length(k)) expect_equal(sum(tab[, "Proportion"]), 1) expect_equal(sum(k <= 0.5), tab[1,1]) expect_equal(sum(k > 0.5 & k <= 0.7), tab[2,1]) expect_equal(sum(k > 0.7 & k <= 1), tab[3,1]) expect_equal(sum(k > 1), tab[4,1]) psis1$diagnostics$pareto_k[1:32] <- 0.4 expect_output(print(pareto_k_table(psis1)), "All Pareto k estimates are good (k < 0.5)", fixed = TRUE) psis1$diagnostics$pareto_k[1:32] <- 0.65 expect_output(print(pareto_k_table(psis1)), "All Pareto k estimates are ok (k < 0.7)", fixed = TRUE) # if n_eff is NULL psis1$diagnostics$n_eff <- NULL tab2 <- pareto_k_table(psis1) expect_output(print(tab2), "") expect_equal(unname(tab2[, "Min. n_eff"]), rep(NA_real_, 4)) }) # psis_neff and mcse_loo -------------------------------------------------- test_that("psis_n_eff_values extractor works", { n_eff_psis <- psis1$diagnostics$n_eff expect_type(n_eff_psis, "double") expect_identical(psis_n_eff_values(psis1), n_eff_psis) expect_identical(psis_n_eff_values(psis1), psis_n_eff_values(loo1)) psis1$diagnostics$n_eff <- NULL expect_error(psis_n_eff_values(psis1), "No PSIS n_eff estimates found") }) test_that("mcse_loo extractor gives correct value", { mcse <- mcse_loo(loo1) expect_type(mcse, "double") expect_equal_to_reference(mcse, "reference-results/mcse_loo.rds") }) test_that("mcse_loo returns NA when it should", { loo1$diagnostics$pareto_k[1] <- 1.5 mcse <- mcse_loo(loo1) expect_equal(mcse, NA) }) test_that("mcse_loo errors if not psis_loo object", { expect_error(mcse_loo(psis1), "psis_loo") }) loo/tests/testthat/test_gpdfit.R0000644000176200001440000000147313575772017016527 0ustar liggesuserslibrary(loo) context("generalized pareto") test_that("gpdfit returns correct result", { set.seed(123) x <- rexp(100) gpdfit_val_old <- unlist(gpdfit(x, wip=FALSE, min_grid_pts = 80)) expect_equal_to_reference(gpdfit_val_old, "reference-results/gpdfit_old.rds") gpdfit_val_wip <- unlist(gpdfit(x, wip=TRUE, min_grid_pts = 80)) expect_equal_to_reference(gpdfit_val_wip, "reference-results/gpdfit.rds") gpdfit_val_wip_default_grid <- unlist(gpdfit(x, wip=TRUE)) expect_equal_to_reference(gpdfit_val_wip_default_grid, "reference-results/gpdfit_default_grid.rds") }) test_that("qgpd returns the correct result ", { probs <- seq(from = 0, to = 1, by = 0.25) q1 <- qgpd(probs, k = 1, sigma = 1) expect_equal(q1, c(0, 1/3, 1, 3, Inf)) q2 <- qgpd(probs, k = 1, sigma = 0) expect_true(all(is.nan(q2))) }) loo/tests/testthat.R0000644000176200001440000000011413575010725014171 0ustar liggesuserslibrary(loo) library(testthat) Sys.setenv("R_TESTS" = "") test_check("loo") loo/vignettes/0000755000176200001440000000000014411465512013056 5ustar liggesusersloo/vignettes/loo2-weights.Rmd0000644000176200001440000003777114407123455016066 0ustar liggesusers--- title: "Bayesian Stacking and Pseudo-BMA weights using the loo package" author: "Aki Vehtari and Jonah Gabry" date: "`r Sys.Date()`" output: html_vignette: toc: yes params: EVAL: !r identical(Sys.getenv("NOT_CRAN"), "true") --- ```{r, child="children/SETTINGS-knitr.txt"} ``` ```{r, child="children/SEE-ONLINE.txt", eval = if (isTRUE(exists("params"))) !params$EVAL else TRUE} ``` # Introduction This vignette demonstrates the new functionality in __loo__ v2.0.0 for Bayesian stacking and Pseudo-BMA weighting. In this vignette we can't provide all of the necessary background on this topic, so we encourage readers to refer to the paper * Yao, Y., Vehtari, A., Simpson, D., and Gelman, A. (2018). Using stacking to average Bayesian predictive distributions. In Bayesian Analysis, \doi:10.1214/17-BA1091. [Online](https://projecteuclid.org/euclid.ba/1516093227) which provides important details on the methods demonstrated in this vignette. Here we just quote from the abstract of the paper: > **Abstract**: Bayesian model averaging is flawed in the $\mathcal{M}$-open setting in which the true data-generating process is not one of the candidate models being fit. We take the idea of stacking from the point estimation literature and generalize to the combination of predictive distributions. We extend the utility function to any proper scoring rule and use Pareto smoothed importance sampling to efficiently compute the required leave-one-out posterior distributions. We compare stacking of predictive distributions to several alternatives: stacking of means, Bayesian model averaging (BMA), Pseudo-BMA, and a variant of Pseudo-BMA that is stabilized using the Bayesian bootstrap. Based on simulations and real-data applications, we recommend stacking of predictive distributions, with bootstrapped-Pseudo-BMA as an approximate alternative when computation cost is an issue. Ideally, we would avoid the Bayesian model combination problem by extending the model to include the separate models as special cases, and preferably as a continuous expansion of the model space. For example, instead of model averaging over different covariate combinations, all potentially relevant covariates should be included in a predictive model (for causal analysis more care is needed) and a prior assumption that only some of the covariates are relevant can be presented with regularized horseshoe prior (Piironen and Vehtari, 2017a). For variable selection we recommend projective predictive variable selection (Piironen and Vehtari, 2017a; [__projpred__ package](https://cran.r-project.org/package=projpred)). To demonstrate how to use __loo__ package to compute Bayesian stacking and Pseudo-BMA weights, we repeat two simple model averaging examples from Chapters 6 and 10 of _Statistical Rethinking_ by Richard McElreath. In _Statistical Rethinking_ WAIC is used to form weights which are similar to classical "Akaike weights". Pseudo-BMA weighting using PSIS-LOO for computation is close to these WAIC weights, but named after the Pseudo Bayes Factor by Geisser and Eddy (1979). As discussed below, in general we prefer using stacking rather than WAIC weights or the similar pseudo-BMA weights. # Setup In addition to the __loo__ package we will also load the __rstanarm__ package for fitting the models. ```{r setup, message=FALSE} library(rstanarm) library(loo) ``` # Example: Primate milk In _Statistical Rethinking_, McElreath describes the data for the primate milk example as follows: > A popular hypothesis has it that primates with larger brains produce more energetic milk, so that brains can grow quickly. ... The question here is to what extent energy content of milk, measured here by kilocalories, is related to the percent of the brain mass that is neocortex. ... We'll end up needing female body mass as well, to see the masking that hides the relationships among the variables. ```{r data} data(milk) d <- milk[complete.cases(milk),] d$neocortex <- d$neocortex.perc /100 str(d) ``` We repeat the analysis in Chapter 6 of _Statistical Rethinking_ using the following four models (here we use the default weakly informative priors in __rstanarm__, while flat priors were used in _Statistical Rethinking_). ```{r fits, results="hide"} fit1 <- stan_glm(kcal.per.g ~ 1, data = d, seed = 2030) fit2 <- update(fit1, formula = kcal.per.g ~ neocortex) fit3 <- update(fit1, formula = kcal.per.g ~ log(mass)) fit4 <- update(fit1, formula = kcal.per.g ~ neocortex + log(mass)) ``` McElreath uses WAIC for model comparison and averaging, so we'll start by also computing WAIC for these models so we can compare the results to the other options presented later in the vignette. The __loo__ package provides `waic` methods for log-likelihood arrays, matrices and functions. Since we fit our model with rstanarm we can use the `waic` method provided by the __rstanarm__ package (a wrapper around `waic` from the __loo__ package), which allows us to just pass in our fitted model objects instead of first extracting the log-likelihood values. ```{r waic} waic1 <- waic(fit1) waic2 <- waic(fit2) waic3 <- waic(fit3) waic4 <- waic(fit4) waics <- c( waic1$estimates["elpd_waic", 1], waic2$estimates["elpd_waic", 1], waic3$estimates["elpd_waic", 1], waic4$estimates["elpd_waic", 1] ) ``` We get some warnings when computing WAIC for models 3 and 4, indicating that we shouldn't trust the WAIC weights we will compute later. Following the recommendation in the warning, we next use the `loo` methods to compute PSIS-LOO instead. The __loo__ package provides `loo` methods for log-likelihood arrays, matrices, and functions, but since we fit our model with __rstanarm__ we can just pass the fitted model objects directly and __rstanarm__ will extract the needed values to pass to the __loo__ package. (Like __rstanarm__, some other R packages for fitting Stan models, e.g. __brms__, also provide similar methods for interfacing with the __loo__ package.) ```{r loo} # note: the loo function accepts a 'cores' argument that we recommend specifying # when working with bigger datasets loo1 <- loo(fit1) loo2 <- loo(fit2) loo3 <- loo(fit3) loo4 <- loo(fit4) lpd_point <- cbind( loo1$pointwise[,"elpd_loo"], loo2$pointwise[,"elpd_loo"], loo3$pointwise[,"elpd_loo"], loo4$pointwise[,"elpd_loo"] ) ``` With `loo` we don't get any warnings for models 3 and 4, but for illustration of good results, we display the diagnostic details for these models anyway. ```{r print-loo} print(loo3) print(loo4) ``` One benefit of PSIS-LOO over WAIC is better diagnostics. Here for both models 3 and 4 all $k<0.7$ and the Monte Carlo SE of `elpd_loo` is 0.1 or less, and we can expect the model comparison to be reliable. Next we compute and compare 1) WAIC weights, 2) Pseudo-BMA weights without Bayesian bootstrap, 3) Pseudo-BMA+ weights with Bayesian bootstrap, and 4) Bayesian stacking weights. ```{r weights} waic_wts <- exp(waics) / sum(exp(waics)) pbma_wts <- pseudobma_weights(lpd_point, BB=FALSE) pbma_BB_wts <- pseudobma_weights(lpd_point) # default is BB=TRUE stacking_wts <- stacking_weights(lpd_point) round(cbind(waic_wts, pbma_wts, pbma_BB_wts, stacking_wts), 2) ``` With all approaches Model 4 with `neocortex` and `log(mass)` gets most of the weight. Based on theory, Pseudo-BMA weights without Bayesian bootstrap should be close to WAIC weights, and we can also see that here. Pseudo-BMA+ weights with Bayesian bootstrap provide more cautious weights further away from 0 and 1 (see Yao et al. (2018) for a discussion of why this can be beneficial and results from related experiments). In this particular example, the Bayesian stacking weights are not much different from the other weights. One of the benefits of stacking is that it manages well if there are many similar models. Consider for example that there could be many irrelevant covariates that when included would produce a similar model to one of the existing models. To emulate this situation here we simply copy the first model a bunch of times, but you can imagine that instead we would have ten alternative models with about the same predictive performance. WAIC weights for such a scenario would be close to the following: ```{r waic_wts_demo} waic_wts_demo <- exp(waics[c(1,1,1,1,1,1,1,1,1,1,2,3,4)]) / sum(exp(waics[c(1,1,1,1,1,1,1,1,1,1,2,3,4)])) round(waic_wts_demo, 3) ``` Notice how much the weight for model 4 is lowered now that more models similar to model 1 (or in this case identical) have been added. Both WAIC weights and Pseudo-BMA approaches first estimate the predictive performance separately for each model and then compute weights based on estimated relative predictive performances. Similar models share similar weights so the weights of other models must be reduced for the total sum of the weights to remain the same. On the other hand, stacking optimizes the weights _jointly_, allowing for the very similar models (in this toy example repeated models) to share their weight while more unique models keep their original weights. In our example we can see this difference clearly: ```{r stacking_weights} stacking_weights(lpd_point[,c(1,1,1,1,1,1,1,1,1,1,2,3,4)]) ``` Using stacking, the weight for the best model stays essentially unchanged. # Example: Oceanic tool complexity Another example we consider is the Kline oceanic tool complexity data, which McElreath describes as follows: >Different historical island populations possessed tool kits of different size. These kits include fish hooks, axes, boats, hand plows, and many other types of tools. A number of theories predict that larger populations will both develop and sustain more complex tool kits. ... It's also suggested that contact rates among populations effectively increases population [sic, probably should be tool kit] size, as it's relevant to technological evolution. We build models predicting the total number of tools given the log population size and the contact rate (high vs. low). ```{r Kline} data(Kline) d <- Kline d$log_pop <- log(d$population) d$contact_high <- ifelse(d$contact=="high", 1, 0) str(d) ``` We start with a Poisson regression model with the log population size, the contact rate, and an interaction term between them (priors are informative priors as in _Statistical Rethinking_). ```{r fit10, results="hide"} fit10 <- stan_glm( total_tools ~ log_pop + contact_high + log_pop * contact_high, family = poisson(link = "log"), data = d, prior = normal(0, 1, autoscale = FALSE), prior_intercept = normal(0, 100, autoscale = FALSE), seed = 2030 ) ``` Before running other models, we check whether Poisson is good choice as the conditional observation model. ```{r loo10} loo10 <- loo(fit10) print(loo10) ``` We get at least one observation with $k>0.7$ and the estimated effective number of parameters `p_loo` is larger than the total number of parameters in the model. This indicates that Poisson might be too narrow. A negative binomial model might be better, but with so few observations it is not so clear. We can compute LOO more accurately by running Stan again for the leave-one-out folds with high $k$ estimates. When using __rstanarm__ this can be done by specifying the `k_threshold` argument: ```{r loo10-threshold} loo10 <- loo(fit10, k_threshold=0.7) print(loo10) ``` In this case we see that there is not much difference, and thus it is relatively safe to continue. As a comparison we also compute WAIC: ```{r waic10} waic10 <- waic(fit10) print(waic10) ``` The WAIC computation is giving warnings and the estimated ELPD is slightly more optimistic. We recommend using the PSIS-LOO results instead. To assess whether the contact rate and interaction term are useful, we can make a comparison to models without these terms. ```{r contact_high, results="hide"} fit11 <- update(fit10, formula = total_tools ~ log_pop + contact_high) fit12 <- update(fit10, formula = total_tools ~ log_pop) ``` ```{r loo-contact_high} (loo11 <- loo(fit11)) (loo12 <- loo(fit12)) ``` ```{r relo-contact_high} loo11 <- loo(fit11, k_threshold=0.7) loo12 <- loo(fit12, k_threshold=0.7) lpd_point <- cbind( loo10$pointwise[, "elpd_loo"], loo11$pointwise[, "elpd_loo"], loo12$pointwise[, "elpd_loo"] ) ``` For comparison we'll also compute WAIC values for these additional models: ```{r waic-contact_high} waic11 <- waic(fit11) waic12 <- waic(fit12) waics <- c( waic10$estimates["elpd_waic", 1], waic11$estimates["elpd_waic", 1], waic12$estimates["elpd_waic", 1] ) ``` The WAIC computation again gives warnings, and we recommend using PSIS-LOO instead. Finally, we compute 1) WAIC weights, 2) Pseudo-BMA weights without Bayesian bootstrap, 3) Pseudo-BMA+ weights with Bayesian bootstrap, and 4) Bayesian stacking weights. ```{r weights-contact_high} waic_wts <- exp(waics) / sum(exp(waics)) pbma_wts <- pseudobma_weights(lpd_point, BB=FALSE) pbma_BB_wts <- pseudobma_weights(lpd_point) # default is BB=TRUE stacking_wts <- stacking_weights(lpd_point) round(cbind(waic_wts, pbma_wts, pbma_BB_wts, stacking_wts), 2) ``` All weights favor the second model with the log population and the contact rate. WAIC weights and Pseudo-BMA weights (without Bayesian bootstrap) are similar, while Pseudo-BMA+ is more cautious and closer to stacking weights. It may seem surprising that Bayesian stacking is giving zero weight to the first model, but this is likely due to the fact that the estimated effect for the interaction term is close to zero and thus models 1 and 2 give very similar predictions. In other words, incorporating the model with the interaction (model 1) into the model average doesn't improve the predictions at all and so model 1 is given a weight of 0. On the other hand, models 2 and 3 are giving slightly different predictions and thus their combination may be slightly better than either alone. This behavior is related to the repeated similar model illustration in the milk example above. # Simpler coding using `loo_model_weights` function Although in the examples above we called the `stacking_weights` and `pseudobma_weights` functions directly, we can also use the `loo_model_weights` wrapper, which takes as its input either a list of pointwise log-likelihood matrices or a list of precomputed loo objects. There are also `loo_model_weights` methods for stanreg objects (fitted model objects from __rstanarm__) as well as fitted model objects from other packages (e.g. __brms__) that do the preparation work for the user (see, e.g., the examples at `help("loo_model_weights", package = "rstanarm")`). ```{r loo_model_weights} # using list of loo objects loo_list <- list(loo10, loo11, loo12) loo_model_weights(loo_list) loo_model_weights(loo_list, method = "pseudobma") loo_model_weights(loo_list, method = "pseudobma", BB = FALSE) ``` # References McElreath, R. (2016). _Statistical rethinking: A Bayesian course with examples in R and Stan_. Chapman & Hall/CRC. http://xcelab.net/rm/statistical-rethinking/ Piironen, J. and Vehtari, A. (2017a). Sparsity information and regularization in the horseshoe and other shrinkage priors. In Electronic Journal of Statistics, 11(2):5018-5051. [Online](https://projecteuclid.org/euclid.ejs/1513306866). Piironen, J. and Vehtari, A. (2017b). Comparison of Bayesian predictive methods for model selection. Statistics and Computing, 27(3):711-735. \doi:10.1007/s11222-016-9649-y. [Online](https://link.springer.com/article/10.1007/s11222-016-9649-y). Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. _Statistics and Computing_. 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. [online](https://link.springer.com/article/10.1007/s11222-016-9696-4), [arXiv preprint arXiv:1507.04544](https://arxiv.org/abs/1507.04544). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.02646](https://arxiv.org/abs/1507.02646). Yao, Y., Vehtari, A., Simpson, D., and Gelman, A. (2018). Using stacking to average Bayesian predictive distributions. In Bayesian Analysis, \doi:10.1214/17-BA1091. [Online](https://projecteuclid.org/euclid.ba/1516093227). loo/vignettes/loo2-lfo.Rmd0000644000176200001440000006042614407123455015165 0ustar liggesusers--- title: "Approximate leave-future-out cross-validation for Bayesian time series models" author: "Paul Bürkner, Jonah Gabry, Aki Vehtari" date: "`r Sys.Date()`" output: html_vignette: toc: yes encoding: "UTF-8" params: EVAL: !r identical(Sys.getenv("NOT_CRAN"), "true") --- ```{r settings, child="children/SETTINGS-knitr.txt"} ``` ```{r more-knitr-ops, include=FALSE} knitr::opts_chunk$set( cache = TRUE, message = FALSE, warning = FALSE ) ``` ```{r, child="children/SEE-ONLINE.txt", eval = if (isTRUE(exists("params"))) !params$EVAL else TRUE} ``` ## Introduction One of the most common goals of a time series analysis is to use the observed series to inform predictions for future observations. We will refer to this task of predicting a sequence of $M$ future observations as $M$-step-ahead prediction ($M$-SAP). Fortunately, once we have fit a model and can sample from the posterior predictive distribution, it is straightforward to generate predictions as far into the future as we want. It is also straightforward to evaluate the $M$-SAP performance of a time series model by comparing the predictions to the observed sequence of $M$ future data points once they become available. Unfortunately, we are often in the position of having to use a model to inform decisions _before_ we can collect the future observations required for assessing the predictive performance. If we have many competing models we may also need to first decide which of the models (or which combination of the models) we should rely on for predictions. In these situations the best we can do is to use methods for approximating the expected predictive performance of our models using only the observations of the time series we already have. If there were no time dependence in the data or if the focus is to assess the non-time-dependent part of the model, we could use methods like leave-one-out cross-validation (LOO-CV). For a data set with $N$ observations, we refit the model $N$ times, each time leaving out one of the $N$ observations and assessing how well the model predicts the left-out observation. LOO-CV is very expensive computationally in most realistic settings, but the Pareto smoothed importance sampling (PSIS, Vehtari et al, 2017, 2019) algorithm provided by the *loo* package allows for approximating exact LOO-CV with PSIS-LOO-CV. PSIS-LOO-CV requires only a single fit of the full model and comes with diagnostics for assessing the validity of the approximation. With a time series we can do something similar to LOO-CV but, except in a few cases, it does not make sense to leave out observations one at a time because then we are allowing information from the future to influence predictions of the past (i.e., times $t + 1, t+2, \ldots$ should not be used to predict for time $t$). To apply the idea of cross-validation to the $M$-SAP case, instead of leave-*one*-out cross-validation we need some form of leave-*future*-out cross-validation (LFO-CV). As we will demonstrate in this case study, LFO-CV does not refer to one particular prediction task but rather to various possible cross-validation approaches that all involve some form of prediction for new time series data. Like exact LOO-CV, exact LFO-CV requires refitting the model many times to different subsets of the data, which is computationally very costly for most nontrivial examples, in particular for Bayesian analyses where refitting the model means estimating a new posterior distribution rather than a point estimate. Although PSIS-LOO-CV provides an efficient approximation to exact LOO-CV, until now there has not been an analogous approximation to exact LFO-CV that drastically reduces the computational burden while also providing informative diagnostics about the quality of the approximation. In this case study we present PSIS-LFO-CV, an algorithm that typically only requires refitting the time-series model a small number times and will make LFO-CV tractable for many more realistic applications than previously possible. More details can be found in our paper about approximate LFO-CV (Bürkner, Gabry, & Vehtari, 2020), which is available as a preprint on arXiv (https://arxiv.org/abs/1902.06281). ## $M$-step-ahead predictions Assume we have a time series of observations $y = (y_1, y_2, \ldots, y_N)$ and let $L$ be the _minimum_ number of observations from the series that we will require before making predictions for future data. Depending on the application and how informative the data is, it may not be possible to make reasonable predictions for $y_{i+1}$ based on $(y_1, \dots, y_{i})$ until $i$ is large enough so that we can learn enough about the time series to predict future observations. Setting $L=10$, for example, means that we will only assess predictive performance starting with observation $y_{11}$, so that we always have at least 10 previous observations to condition on. In order to assess $M$-SAP performance we would like to compute the predictive densities $$ p(y_{i+1:M} \,|\, y_{1:i}) = p(y_{i+1}, \ldots, y_{i + M} \,|\, y_{1},...,y_{i}) $$ for each $i \in \{L, \ldots, N - M\}$. The quantities $p(y_{i+1:M} \,|\, y_{1:i})$ can be computed with the help of the posterior distribution $p(\theta \,|\, y_{1:i})$ of the parameters $\theta$ conditional on only the first $i$ observations of the time-series: $$ p(y_{i+1:M} \,| \, y_{1:i}) = \int p(y_{i+1:M} \,| \, y_{1:i}, \theta) \, p(\theta\,|\,y_{1:i}) \,d\theta. $$ Having obtained $S$ draws $(\theta_{1:i}^{(1)}, \ldots, \theta_{1:i}^{(S)})$ from the posterior distribution $p(\theta\,|\,y_{1:i})$, we can estimate $p(y_{i+1:M} | y_{1:i})$ as $$ p(y_{i+1:M} \,|\, y_{1:i}) \approx \frac{1}{S}\sum_{s=1}^S p(y_{i+1:M} \,|\, y_{1:i}, \theta_{1:i}^{(s)}). $$ ## Approximate $M$-SAP using importance-sampling {#approximate_MSAP} Unfortunately, the math above makes use of the posterior distributions from many different fits of the model to different subsets of the data. That is, to obtain the predictive density $p(y_{i+1:M} \,|\, y_{1:i})$ requires fitting a model to only the first $i$ data points, and we will need to do this for every value of $i$ under consideration (all $i \in \{L, \ldots, N - M\}$). To reduce the number of models that need to be fit for the purpose of obtaining each of the densities $p(y_{i+1:M} \,|\, y_{1:i})$, we propose the following algorithm. First, we refit the model using the first $L$ observations of the time series and then perform a single exact $M$-step-ahead prediction step for $p(y_{L+1:M} \,|\, y_{1:L})$. Recall that $L$ is the minimum number of observations we have deemed acceptable for making predictions (setting $L=0$ means the first data point will be predicted only based on the prior). We define $i^\star = L$ as the current point of refit. Next, starting with $i = i^\star + 1$, we approximate each $p(y_{i+1:M} \,|\, y_{1:i})$ via $$ p(y_{i+1:M} \,|\, y_{1:i}) \approx \frac{ \sum_{s=1}^S w_i^{(s)}\, p(y_{i+1:M} \,|\, y_{1:i}, \theta^{(s)})} { \sum_{s=1}^S w_i^{(s)}}, $$ where $\theta^{(s)} = \theta^{(s)}_{1:i^\star}$ are draws from the posterior distribution based on the first $i^\star$ observations and $w_i^{(s)}$ are the PSIS weights obtained in two steps. First, we compute the raw importance ratios $$ r_i^{(s)} = \frac{f_{1:i}(\theta^{(s)})}{f_{1:i^\star}(\theta^{(s)})} \propto \prod_{j \in (i^\star + 1):i} p(y_j \,|\, y_{1:(j-1)}, \theta^{(s)}), $$ and then stabilize them using PSIS. The function $f_{1:i}$ denotes the posterior distribution based on the first $i$ observations, that is, $f_{1:i} = p(\theta \,|\, y_{1:i})$, with $f_{1:i^\star}$ defined analogously. The index set $(i^\star + 1):i$ indicates all observations which are part of the data for the model $f_{1:i}$ whose predictive performance we are trying to approximate but not for the actually fitted model $f_{1:i^\star}$. The proportional statement arises from the fact that we ignore the normalizing constants $p(y_{1:i})$ and $p(y_{1:i^\star})$ of the compared posteriors, which leads to a self-normalized variant of PSIS (see Vehtari et al, 2017). Continuing with the next observation, we gradually increase $i$ by $1$ (we move forward in time) and repeat the process. At some observation $i$, the variability of the importance ratios $r_i^{(s)}$ will become too large and importance sampling will fail. We will refer to this particular value of $i$ as $i^\star_1$. To identify the value of $i^\star_1$, we check for which value of $i$ does the estimated shape parameter $k$ of the generalized Pareto distribution first cross a certain threshold $\tau$ (Vehtari et al, 2019). Only then do we refit the model using the observations up to $i^\star_1$ and restart the process from there by setting $\theta^{(s)} = \theta^{(s)}_{1:i^\star_1}$ and $i^\star = i^\star_1$ until the next refit. In some cases we may only need to refit once and in other cases we will find a value $i^\star_2$ that requires a second refitting, maybe an $i^\star_3$ that requires a third refitting, and so on. We refit as many times as is required (only when $k > \tau$) until we arrive at observation $i = N - M$. For LOO, we recommend to use a threshold of $\tau = 0.7$ (Vehtari et al, 2017, 2019) and it turns out this is a reasonable threshold for LFO as well (Bürkner et al. 2020). ## Autoregressive models Autoregressive (AR) models are some of the most commonly used time-series models. An AR(p) model ---an autoregressive model of order $p$--- can be defined as $$ y_i = \eta_i + \sum_{k = 1}^p \varphi_k y_{i - k} + \varepsilon_i, $$ where $\eta_i$ is the linear predictor for the $i$th observation, $\phi_k$ are the autoregressive parameters and $\varepsilon_i$ are pairwise independent errors, which are usually assumed to be normally distributed with equal variance $\sigma^2$. The model implies a recursive formula that allows for computing the right-hand side of the above equation for observation $i$ based on the values of the equations for previous observations. ## Case Study: Annual measurements of the level of Lake Huron To illustrate the application of PSIS-LFO-CV for estimating expected $M$-SAP performance, we will fit a model for 98 annual measurements of the water level (in feet) of [Lake Huron](https://en.wikipedia.org/wiki/Lake_Huron) from the years 1875--1972. This data set is found in the **datasets** R package, which is installed automatically with **R**. In addition to the **loo** package, for this analysis we will use the **brms** interface to Stan to generate a Stan program and fit the model, and also the **bayesplot** and **ggplot2** packages for plotting. ```{r pkgs, cache=FALSE} library("loo") library("brms") library("bayesplot") library("ggplot2") color_scheme_set("brightblue") theme_set(theme_default()) CHAINS <- 4 SEED <- 5838296 set.seed(SEED) ``` Before fitting a model, we will first put the data into a data frame and then look at the time series. ```{r hurondata} N <- length(LakeHuron) df <- data.frame( y = as.numeric(LakeHuron), year = as.numeric(time(LakeHuron)), time = 1:N ) ggplot(df, aes(x = year, y = y)) + geom_point(size = 1) + labs( y = "Water Level (ft)", x = "Year", title = "Water Level in Lake Huron (1875-1972)" ) ``` The above plot shows rather strong autocorrelation of the time-series as well as some trend towards lower levels for later points in time. We can specify an AR(4) model for these data using the **brms** package as follows: ```{r fit, results = "hide"} fit <- brm( y ~ ar(time, p = 4), data = df, prior = prior(normal(0, 0.5), class = "ar"), control = list(adapt_delta = 0.99), seed = SEED, chains = CHAINS ) ``` The model implied predictions along with the observed values can be plotted, which reveals a rather good fit to the data. ```{r plotpreds, cache = FALSE} preds <- posterior_predict(fit) preds <- cbind( Estimate = colMeans(preds), Q5 = apply(preds, 2, quantile, probs = 0.05), Q95 = apply(preds, 2, quantile, probs = 0.95) ) ggplot(cbind(df, preds), aes(x = year, y = Estimate)) + geom_smooth(aes(ymin = Q5, ymax = Q95), stat = "identity", size = 0.5) + geom_point(aes(y = y)) + labs( y = "Water Level (ft)", x = "Year", title = "Water Level in Lake Huron (1875-1972)", subtitle = "Mean (blue) and 90% predictive intervals (gray) vs. observed data (black)" ) ``` To allow for reasonable predictions of future values, we will require at least $L = 20$ historical observations (20 years) to make predictions. ```{r setL} L <- 20 ``` We first perform approximate leave-one-out cross-validation (LOO-CV) for the purpose of later comparison with exact and approximate LFO-CV for the 1-SAP case. ```{r loo1sap, cache = FALSE} loo_cv <- loo(log_lik(fit)[, (L + 1):N]) print(loo_cv) ``` ## 1-step-ahead predictions leaving out all future values The most basic version of $M$-SAP is 1-SAP, in which we predict only one step ahead. In this case, $y_{i+1:M}$ simplifies to $y_{i}$ and the LFO-CV algorithm becomes considerably simpler than for larger values of $M$. ### Exact 1-step-ahead predictions Before we compute approximate LFO-CV using PSIS we will first compute exact LFO-CV for the 1-SAP case so we can use it as a benchmark later. The initial step for the exact computation is to calculate the log-predictive densities by refitting the model many times: ```{r exact_loglik, results="hide"} loglik_exact <- matrix(nrow = nsamples(fit), ncol = N) for (i in L:(N - 1)) { past <- 1:i oos <- i + 1 df_past <- df[past, , drop = FALSE] df_oos <- df[c(past, oos), , drop = FALSE] fit_i <- update(fit, newdata = df_past, recompile = FALSE) loglik_exact[, i + 1] <- log_lik(fit_i, newdata = df_oos, oos = oos)[, oos] } ``` Then we compute the exact expected log predictive density (ELPD): ```{r helpers} # some helper functions we'll use throughout # more stable than log(sum(exp(x))) log_sum_exp <- function(x) { max_x <- max(x) max_x + log(sum(exp(x - max_x))) } # more stable than log(mean(exp(x))) log_mean_exp <- function(x) { log_sum_exp(x) - log(length(x)) } # compute log of raw importance ratios # sums over observations *not* over posterior samples sum_log_ratios <- function(loglik, ids = NULL) { if (!is.null(ids)) loglik <- loglik[, ids, drop = FALSE] rowSums(loglik) } # for printing comparisons later rbind_print <- function(...) { round(rbind(...), digits = 2) } ``` ```{r exact1sap, cache = FALSE} exact_elpds_1sap <- apply(loglik_exact, 2, log_mean_exp) exact_elpd_1sap <- c(ELPD = sum(exact_elpds_1sap[-(1:L)])) rbind_print( "LOO" = loo_cv$estimates["elpd_loo", "Estimate"], "LFO" = exact_elpd_1sap ) ``` We see that the ELPD from LFO-CV for 1-step-ahead predictions is lower than the ELPD estimate from LOO-CV, which should be expected since LOO-CV is making use of more of the time series. That is, since the LFO-CV approach only uses observations from before the left-out data point but LOO-CV uses _all_ data points other than the left-out observation, we should expect to see the larger ELPD from LOO-CV. ### Approximate 1-step-ahead predictions We compute approximate 1-SAP with refit at observations where the Pareto $k$ estimate exceeds the threshold of $0.7$. ```{r setkthresh} k_thres <- 0.7 ``` The code becomes a little bit more involved as compared to the exact LFO-CV. Note that we can compute exact 1-SAP at the refitting points, which comes with no additional computational costs since we had to refit the model anyway. ```{r refit_loglik, results="hide"} approx_elpds_1sap <- rep(NA, N) # initialize the process for i = L past <- 1:L oos <- L + 1 df_past <- df[past, , drop = FALSE] df_oos <- df[c(past, oos), , drop = FALSE] fit_past <- update(fit, newdata = df_past, recompile = FALSE) loglik <- log_lik(fit_past, newdata = df_oos, oos = oos) approx_elpds_1sap[L + 1] <- log_mean_exp(loglik[, oos]) # iterate over i > L i_refit <- L refits <- L ks <- NULL for (i in (L + 1):(N - 1)) { past <- 1:i oos <- i + 1 df_past <- df[past, , drop = FALSE] df_oos <- df[c(past, oos), , drop = FALSE] loglik <- log_lik(fit_past, newdata = df_oos, oos = oos) logratio <- sum_log_ratios(loglik, (i_refit + 1):i) psis_obj <- suppressWarnings(psis(logratio)) k <- pareto_k_values(psis_obj) ks <- c(ks, k) if (k > k_thres) { # refit the model based on the first i observations i_refit <- i refits <- c(refits, i) fit_past <- update(fit_past, newdata = df_past, recompile = FALSE) loglik <- log_lik(fit_past, newdata = df_oos, oos = oos) approx_elpds_1sap[i + 1] <- log_mean_exp(loglik[, oos]) } else { lw <- weights(psis_obj, normalize = TRUE)[, 1] approx_elpds_1sap[i + 1] <- log_sum_exp(lw + loglik[, oos]) } } ``` We see that the final Pareto-$k$-estimates are mostly well below the threshold and that we only needed to refit the model a few times: ```{r plot_ks} plot_ks <- function(ks, ids, thres = 0.6) { dat_ks <- data.frame(ks = ks, ids = ids) ggplot(dat_ks, aes(x = ids, y = ks)) + geom_point(aes(color = ks > thres), shape = 3, show.legend = FALSE) + geom_hline(yintercept = thres, linetype = 2, color = "red2") + scale_color_manual(values = c("cornflowerblue", "darkblue")) + labs(x = "Data point", y = "Pareto k") + ylim(-0.5, 1.5) } ``` ```{r refitsummary1sap, cache=FALSE} cat("Using threshold ", k_thres, ", model was refit ", length(refits), " times, at observations", refits) plot_ks(ks, (L + 1):(N - 1)) ``` The approximate 1-SAP ELPD is remarkably similar to the exact 1-SAP ELPD computed above, which indicates our algorithm to compute approximate 1-SAP worked well for the present data and model. ```{r lfosummary1sap, cache = FALSE} approx_elpd_1sap <- sum(approx_elpds_1sap, na.rm = TRUE) rbind_print( "approx LFO" = approx_elpd_1sap, "exact LFO" = exact_elpd_1sap ) ``` Plotting exact against approximate predictions, we see that no approximation value deviates far from its exact counterpart, providing further evidence for the good quality of our approximation. ```{r plot1sap, cache = FALSE} dat_elpd <- data.frame( approx_elpd = approx_elpds_1sap, exact_elpd = exact_elpds_1sap ) ggplot(dat_elpd, aes(x = approx_elpd, y = exact_elpd)) + geom_abline(color = "gray30") + geom_point(size = 2) + labs(x = "Approximate ELPDs", y = "Exact ELPDs") ``` We can also look at the maximum difference and average difference between the approximate and exact ELPD calculations, which also indicate a ver close approximation: ```{r diffs1sap, cache=FALSE} max_diff <- with(dat_elpd, max(abs(approx_elpd - exact_elpd), na.rm = TRUE)) mean_diff <- with(dat_elpd, mean(abs(approx_elpd - exact_elpd), na.rm = TRUE)) rbind_print( "Max diff" = round(max_diff, 2), "Mean diff" = round(mean_diff, 3) ) ``` ## $M$-step-ahead predictions leaving out all future values To illustrate the application of $M$-SAP for $M > 1$, we next compute exact and approximate LFO-CV for the 4-SAP case. ### Exact $M$-step-ahead predictions The necessary steps are the same as for 1-SAP with the exception that the log-density values of interest are now the sums of the log predictive densities of four consecutive observations. Further, the stability of the PSIS approximation actually stays the same for all $M$ as it only depends on the number of observations we leave out, not on the number of observations we predict. ```{r exact_loglikm, results="hide"} M <- 4 loglikm <- matrix(nrow = nsamples(fit), ncol = N) for (i in L:(N - M)) { past <- 1:i oos <- (i + 1):(i + M) df_past <- df[past, , drop = FALSE] df_oos <- df[c(past, oos), , drop = FALSE] fit_past <- update(fit, newdata = df_past, recompile = FALSE) loglik <- log_lik(fit_past, newdata = df_oos, oos = oos) loglikm[, i + 1] <- rowSums(loglik[, oos]) } ``` ```{r exact4sap, cache = FALSE} exact_elpds_4sap <- apply(loglikm, 2, log_mean_exp) (exact_elpd_4sap <- c(ELPD = sum(exact_elpds_4sap, na.rm = TRUE))) ``` ### Approximate $M$-step-ahead predictions Computing the approximate PSIS-LFO-CV for the 4-SAP case is a little bit more involved than the approximate version for the 1-SAP case, although the underlying principles remain the same. ```{r refit_loglikm, results="hide"} approx_elpds_4sap <- rep(NA, N) # initialize the process for i = L past <- 1:L oos <- (L + 1):(L + M) df_past <- df[past, , drop = FALSE] df_oos <- df[c(past, oos), , drop = FALSE] fit_past <- update(fit, newdata = df_past, recompile = FALSE) loglik <- log_lik(fit_past, newdata = df_oos, oos = oos) loglikm <- rowSums(loglik[, oos]) approx_elpds_1sap[L + 1] <- log_mean_exp(loglikm) # iterate over i > L i_refit <- L refits <- L ks <- NULL for (i in (L + 1):(N - M)) { past <- 1:i oos <- (i + 1):(i + M) df_past <- df[past, , drop = FALSE] df_oos <- df[c(past, oos), , drop = FALSE] loglik <- log_lik(fit_past, newdata = df_oos, oos = oos) logratio <- sum_log_ratios(loglik, (i_refit + 1):i) psis_obj <- suppressWarnings(psis(logratio)) k <- pareto_k_values(psis_obj) ks <- c(ks, k) if (k > k_thres) { # refit the model based on the first i observations i_refit <- i refits <- c(refits, i) fit_past <- update(fit_past, newdata = df_past, recompile = FALSE) loglik <- log_lik(fit_past, newdata = df_oos, oos = oos) loglikm <- rowSums(loglik[, oos]) approx_elpds_4sap[i + 1] <- log_mean_exp(loglikm) } else { lw <- weights(psis_obj, normalize = TRUE)[, 1] loglikm <- rowSums(loglik[, oos]) approx_elpds_4sap[i + 1] <- log_sum_exp(lw + loglikm) } } ``` Again, we see that the final Pareto-$k$-estimates are mostly well below the threshold and that we only needed to refit the model a few times: ```{r refitsummary4sap, cache = FALSE} cat("Using threshold ", k_thres, ", model was refit ", length(refits), " times, at observations", refits) plot_ks(ks, (L + 1):(N - M)) ``` The approximate ELPD computed for the 4-SAP case is not as close to its exact counterpart as in the 1-SAP case. In general, the larger $M$, the larger the variation of the approximate ELPD around the exact ELPD. It turns out that the ELPD estimates of AR-models with $M>1$ show particular variation due to their predictions' dependency on other predicted values. In Bürkner et al. (2020) we provide further explanation and simulations for these cases. ```{r lfosummary4sap, cache = FALSE} approx_elpd_4sap <- sum(approx_elpds_4sap, na.rm = TRUE) rbind_print( "Approx LFO" = approx_elpd_4sap, "Exact LFO" = exact_elpd_4sap ) ``` Plotting exact against approximate pointwise predictions confirms that, for a few specific data points, the approximate predictions underestimate the exact predictions. ```{r plot4sap, cache = FALSE} dat_elpd_4sap <- data.frame( approx_elpd = approx_elpds_4sap, exact_elpd = exact_elpds_4sap ) ggplot(dat_elpd_4sap, aes(x = approx_elpd, y = exact_elpd)) + geom_abline(color = "gray30") + geom_point(size = 2) + labs(x = "Approximate ELPDs", y = "Exact ELPDs") ``` ## Conclusion In this case study we have shown how to do carry out exact and approximate leave-future-out cross-validation for $M$-step-ahead prediction tasks. For the data and model used in our example, the PSIS-LFO-CV algorithm provides reasonably stable and accurate results despite not requiring us to refit the model nearly as many times. For more details on approximate LFO-CV, we refer to Bürkner et al. (2020).
## References Bürkner P. C., Gabry J., & Vehtari A. (2020). Approximate leave-future-out cross-validation for time series models. *Journal of Statistical Computation and Simulation*, 90(14):2499-2523. \doi:/10.1080/00949655.2020.1783262. [Online](https://www.tandfonline.com/doi/full/10.1080/00949655.2020.1783262). [arXiv preprint](https://arxiv.org/abs/1902.06281). Vehtari A., Gelman A., & Gabry J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. *Statistics and Computing*, 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. [Online](https://link.springer.com/article/10.1007/s11222-016-9696-4). [arXiv preprint arXiv:1507.04544](https://arxiv.org/abs/1507.04544). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.02646](https://arxiv.org/abs/1507.02646).
## Appendix ### Appendix: Session information ```{r sessioninfo} sessionInfo() ``` ### Appendix: Licenses * Code © 2018, Paul Bürkner, Jonah Gabry, Aki Vehtari (licensed under BSD-3). * Text © 2018, Paul Bürkner, Jonah Gabry, Aki Vehtari (licensed under CC-BY-NC 4.0). loo/vignettes/loo2-with-rstan.Rmd0000644000176200001440000002030714407123455016477 0ustar liggesusers--- title: "Writing Stan programs for use with the loo package" author: "Aki Vehtari and Jonah Gabry" date: "`r Sys.Date()`" output: html_vignette: toc: yes params: EVAL: !r identical(Sys.getenv("NOT_CRAN"), "true") --- ```{r settings, child="children/SETTINGS-knitr.txt"} ``` ```{r, child="children/SEE-ONLINE.txt", eval = if (isTRUE(exists("params"))) !params$EVAL else TRUE} ``` # Introduction This vignette demonstrates how to write a Stan program that computes and stores the pointwise log-likelihood required for using the __loo__ package. The other vignettes included with the package demonstrate additional functionality. Some sections from this vignette are excerpted from our papers * Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. _Statistics and Computing_. 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. Links: [published](https://link.springer.com/article/10.1007/s11222-016-9696-4) | [arXiv preprint](https://arxiv.org/abs/1507.04544). * Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.04544](https://arxiv.org/abs/1507.02646). which provide important background for understanding the methods implemented in the package. # Example: Well water in Bangladesh This example comes from a survey of residents from a small area in Bangladesh that was affected by arsenic in drinking water. Respondents with elevated arsenic levels in their wells were asked if they were interested in getting water from a neighbor's well, and a series of logistic regressions were fit to predict this binary response given various information about the households (Gelman and Hill, 2007). Here we fit a model for the well-switching response given two predictors: the arsenic level of the water in the resident's home, and the distance of the house from the nearest safe well. The sample size in this example is $N=3020$, which is not huge but is large enough that it is important to have a computational method for LOO that is fast for each data point. On the plus side, with such a large dataset, the influence of any given observation is small, and so the computations should be stable. ## Coding the Stan model Here is the Stan code for fitting the logistic regression model, which we save in a file called `logistic.stan`: ``` data { int N; // number of data points int P; // number of predictors (including intercept) matrix[N,P] X; // predictors (including 1s for intercept) int y[N]; // binary outcome } parameters { vector[P] beta; } model { beta ~ normal(0, 1); y ~ bernoulli_logit(X * beta); } generated quantities { vector[N] log_lik; for (n in 1:N) { log_lik[n] = bernoulli_logit_lpmf(y[n] | X[n] * beta); } } ``` We have defined the log likelihood as a vector named `log_lik` in the generated quantities block so that the individual terms will be saved by Stan. After running Stan, `log_lik` can be extracted (using the `extract_log_lik` function provided in the **loo** package) as an $S \times N$ matrix, where $S$ is the number of simulations (posterior draws) and $N$ is the number of data points. ## Fitting the model with RStan Next we fit the model in Stan using the **rstan** package: ```{r, eval=FALSE} library("rstan") # Prepare data url <- "http://stat.columbia.edu/~gelman/arm/examples/arsenic/wells.dat" wells <- read.table(url) wells$dist100 <- with(wells, dist / 100) X <- model.matrix(~ dist100 + arsenic, wells) standata <- list(y = wells$switch, X = X, N = nrow(X), P = ncol(X)) # Fit model fit_1 <- stan("logistic.stan", data = standata) print(fit_1, pars = "beta") ``` ``` mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat beta[1] 0.00 0 0.08 -0.16 -0.05 0.00 0.05 0.15 1964 1 beta[2] -0.89 0 0.10 -1.09 -0.96 -0.89 -0.82 -0.68 2048 1 beta[3] 0.46 0 0.04 0.38 0.43 0.46 0.49 0.54 2198 1 ``` ## Computing approximate leave-one-out cross-validation using PSIS-LOO We can then use the **loo** package to compute the efficient PSIS-LOO approximation to exact LOO-CV: ```{r, eval=FALSE} library("loo") # Extract pointwise log-likelihood # using merge_chains=FALSE returns an array, which is easier to # use with relative_eff() log_lik_1 <- extract_log_lik(fit_1, merge_chains = FALSE) # as of loo v2.0.0 we can optionally provide relative effective sample sizes # when calling loo, which allows for better estimates of the PSIS effective # sample sizes and Monte Carlo error r_eff <- relative_eff(exp(log_lik_1), cores = 2) # preferably use more than 2 cores (as many cores as possible) # will use value of 'mc.cores' option if cores is not specified loo_1 <- loo(log_lik_1, r_eff = r_eff, cores = 2) print(loo_1) ``` ``` Computed from 4000 by 3020 log-likelihood matrix Estimate SE elpd_loo -1968.5 15.6 p_loo 3.2 0.1 looic 3937.0 31.2 ------ Monte Carlo SE of elpd_loo is 0.0. All Pareto k estimates are good (k < 0.5). See help('pareto-k-diagnostic') for details. ``` The printed output from the `loo` function shows the estimates $\widehat{\mbox{elpd}}_{\rm loo}$ (expected log predictive density), $\widehat{p}_{\rm loo}$ (effective number of parameters), and ${\rm looic} =-2\, \widehat{\mbox{elpd}}_{\rm loo}$ (the LOO information criterion). The line at the bottom of the printed output provides information about the reliability of the LOO approximation (the interpretation of the $k$ parameter is explained in `help('pareto-k-diagnostic')` and in greater detail in Vehtari, Simpson, Gelman, Yao, and Gabry (2019)). In this case the message tells us that all of the estimates for $k$ are fine. ## Comparing models To compare this model to an alternative model for the same data we can use the `loo_compare` function in the **loo** package. First we'll fit a second model to the well-switching data, using `log(arsenic)` instead of `arsenic` as a predictor: ```{r, eval=FALSE} standata$X[, "arsenic"] <- log(standata$X[, "arsenic"]) fit_2 <- stan(fit = fit_1, data = standata) log_lik_2 <- extract_log_lik(fit_2, merge_chains = FALSE) r_eff_2 <- relative_eff(exp(log_lik_2)) loo_2 <- loo(log_lik_2, r_eff = r_eff_2, cores = 2) print(loo_2) ``` ``` Computed from 4000 by 3020 log-likelihood matrix Estimate SE elpd_loo -1952.3 16.2 p_loo 3.1 0.1 looic 3904.6 32.4 ------ Monte Carlo SE of elpd_loo is 0.0. All Pareto k estimates are good (k < 0.5). See help('pareto-k-diagnostic') for details. ``` We can now compare the models on LOO using the `loo_compare` function: ```{r, eval=FALSE} # Compare comp <- loo_compare(loo_1, loo_2) ``` This new object, `comp`, contains the estimated difference of expected leave-one-out prediction errors between the two models, along with the standard error: ```{r, eval=FALSE} print(comp) # can set simplify=FALSE for more detailed print output ``` ``` elpd_diff se_diff model2 0.0 0.0 model1 -16.3 4.4 ``` The first column shows the difference in ELPD relative to the model with the largest ELPD. In this case, the difference in `elpd` and its scale relative to the approximate standard error of the difference) indicates a preference for the second model (`model2`). # References Gelman, A., and Hill, J. (2007). *Data Analysis Using Regression and Multilevel Hierarchical Models.* Cambridge University Press. Stan Development Team (2017). _The Stan C++ Library, Version 2.17.0._ https://mc-stan.org/ Stan Development Team (2018) _RStan: the R interface to Stan, Version 2.17.3._ https://mc-stan.org/ Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. _Statistics and Computing_. 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. [online](https://link.springer.com/article/10.1007/s11222-016-9696-4), [arXiv preprint arXiv:1507.04544](https://arxiv.org/abs/1507.04544). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.02646](https://arxiv.org/abs/1507.02646). loo/vignettes/loo2-example.Rmd0000644000176200001440000003015314407123455016032 0ustar liggesusers--- title: "Using the loo package (version >= 2.0.0)" author: "Aki Vehtari and Jonah Gabry" date: "`r Sys.Date()`" output: html_vignette: toc: yes params: EVAL: !r identical(Sys.getenv("NOT_CRAN"), "true") --- ```{r, child="children/SETTINGS-knitr.txt"} ``` ```{r, child="children/SEE-ONLINE.txt", eval = if (isTRUE(exists("params"))) !params$EVAL else TRUE} ``` # Introduction This vignette demonstrates how to use the __loo__ package to carry out Pareto smoothed importance-sampling leave-one-out cross-validation (PSIS-LOO) for purposes of model checking and model comparison. In this vignette we can't provide all necessary background information on PSIS-LOO and its diagnostics (Pareto $k$ and effective sample size), so we encourage readers to refer to the following papers for more details: * Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. _Statistics and Computing_. 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. Links: [published](https://link.springer.com/article/10.1007/s11222-016-9696-4) | [arXiv preprint](https://arxiv.org/abs/1507.04544). * Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.02646](https://arxiv.org/abs/1507.02646). # Setup In addition to the __loo__ package, we'll also be using __rstanarm__ and __bayesplot__: ```{r setup, message=FALSE} library("rstanarm") library("bayesplot") library("loo") ``` # Example: Poisson vs negative binomial for the roaches dataset ## Background and model fitting The Poisson and negative binomial regression models used below in our example, as well as the `stan_glm` function used to fit the models, are covered in more depth in the __rstanarm__ vignette [_Estimating Generalized Linear Models for Count Data with rstanarm_](http://mc-stan.org/rstanarm/articles/count.html). In the rest of this vignette we will assume the reader is already familiar with these kinds of models. ### Roaches data The example data we'll use comes from Chapter 8.3 of [Gelman and Hill (2007)](http://www.stat.columbia.edu/~gelman/arm/). We want to make inferences about the efficacy of a certain pest management system at reducing the number of roaches in urban apartments. Here is how Gelman and Hill describe the experiment and data (pg. 161): > the treatment and control were applied to 160 and 104 apartments, respectively, and the outcome measurement $y_i$ in each apartment $i$ was the number of roaches caught in a set of traps. Different apartments had traps for different numbers of days In addition to an intercept, the regression predictors for the model are `roach1`, the pre-treatment number of roaches (rescaled above to be in units of hundreds), the treatment indicator `treatment`, and a variable indicating whether the apartment is in a building restricted to elderly residents `senior`. Because the number of days for which the roach traps were used is not the same for all apartments in the sample, we use the `offset` argument to specify that `log(exposure2)` should be added to the linear predictor. ```{r data} # the 'roaches' data frame is included with the rstanarm package data(roaches) str(roaches) # rescale to units of hundreds of roaches roaches$roach1 <- roaches$roach1 / 100 ``` ### Fit Poisson model We'll fit a simple Poisson regression model using the `stan_glm` function from the __rstanarm__ package. ```{r count-roaches-mcmc, results="hide"} fit1 <- stan_glm( formula = y ~ roach1 + treatment + senior, offset = log(exposure2), data = roaches, family = poisson(link = "log"), prior = normal(0, 2.5, autoscale = TRUE), prior_intercept = normal(0, 5, autoscale = TRUE), seed = 12345 ) ``` Usually we would also run posterior predictive checks as shown in the __rstanarm__ vignette [Estimating Generalized Linear Models for Count Data with rstanarm](http://mc-stan.org/rstanarm/articles/count.html), but here we focus only on methods provided by the __loo__ package.
## Using the __loo__ package for model checking and comparison _Although cross-validation is mostly used for model comparison, it is also useful for model checking._ ### Computing PSIS-LOO and checking diagnostics We start by computing PSIS-LOO with the `loo` function. Since we fit our model using __rstanarm__ we can use the `loo` method for `stanreg` objects (fitted model objects from __rstanarm__), which doesn't require us to first extract the pointwise log-likelihood values. If we had written our own Stan program instead of using __rstanarm__ we would pass an array or matrix of log-likelihood values to the `loo` function (see, e.g. `help("loo.array", package = "loo")`). We'll also use the argument `save_psis = TRUE` to save some intermediate results to be re-used later. ```{r loo1} loo1 <- loo(fit1, save_psis = TRUE) ``` `loo` gives us warnings about the Pareto diagnostics, which indicate that for some observations the leave-one-out posteriors are different enough from the full posterior that importance-sampling is not able to correct the difference. We can see more details by printing the `loo` object. ```{r print-loo1} print(loo1) ``` The table shows us a summary of Pareto $k$ diagnostic, which is used to assess the reliability of the estimates. In addition to the proportion of leave-one-out folds with $k$ values in different intervals, the minimum of the effective sample sizes in that category is shown to give idea why higher $k$ values are bad. Since we have some $k>1$, we are not able to compute an estimate for the Monte Carlo standard error (SE) of the expected log predictive density (`elpd_loo`) and `NA` is displayed. (Full details on the interpretation of the Pareto $k$ diagnostics are available in the Vehtari, Gelman, and Gabry (2017) and Vehtari, Simpson, Gelman, Yao, and Gabry (2019) papers referenced at the top of this vignette.) In this case the `elpd_loo` estimate should not be considered reliable. If we had a well-specified model we would expect the estimated effective number of parameters (`p_loo`) to be smaller than or similar to the total number of parameters in the model. Here `p_loo` is almost 300, which is about 70 times the total number of parameters in the model, indicating severe model misspecification. ### Plotting Pareto $k$ diagnostics Using the `plot` method on our `loo1` object produces a plot of the $k$ values (in the same order as the observations in the dataset used to fit the model) with horizontal lines corresponding to the same categories as in the printed output above. ```{r plot-loo1, out.width = "70%"} plot(loo1) ``` This plot is useful to quickly see the distribution of $k$ values, but it's often also possible to see structure with respect to data ordering. In our case this is mild, but there seems to be a block of data that is somewhat easier to predict (indices around 90--150). Unfortunately even for these data points we see some high $k$ values. ### Marginal posterior predictive checks The `loo` package can be used in combination with the `bayesplot` package for leave-one-out cross-validation marginal posterior predictive checks [Gabry et al (2018)](https://arxiv.org/abs/1709.01449). LOO-PIT values are cumulative probabilities for $y_i$ computed using the LOO marginal predictive distributions $p(y_i|y_{-i})$. For a good model, the distribution of LOO-PIT values should be uniform. In the following plot the distribution (smoothed density estimate) of the LOO-PIT values for our model (thick curve) is compared to many independently generated samples (each the same size as our dataset) from the standard uniform distribution (thin curves). ```{r ppc_loo_pit_overlay} yrep <- posterior_predict(fit1) ppc_loo_pit_overlay( y = roaches$y, yrep = yrep, lw = weights(loo1$psis_object) ) ``` The excessive number of values close to 0 indicates that the model is under-dispersed compared to the data, and we should consider a model that allows for greater dispersion. ## Try alternative model with more flexibility Here we will try [negative binomial](https://en.wikipedia.org/wiki/Negative_binomial_distribution) regression, which is commonly used for overdispersed count data. Unlike the Poisson distribution, the negative binomial distribution allows the conditional mean and variance of $y$ to differ. ```{r count-roaches-negbin, results="hide"} fit2 <- update(fit1, family = neg_binomial_2) ``` ```{r loo2} loo2 <- loo(fit2, save_psis = TRUE, cores = 2) print(loo2) ``` ```{r plot-loo2} plot(loo2, label_points = TRUE) ``` Using the `label_points` argument will label any $k$ values larger than 0.7 with the index of the corresponding data point. These high values are often the result of model misspecification and frequently correspond to data points that would be considered ``outliers'' in the data and surprising according to the model [Gabry et al (2019)](https://arxiv.org/abs/1709.01449). Unfortunately, while large $k$ values are a useful indicator of model misspecification, small $k$ values are not a guarantee that a model is well-specified. If there are a small number of problematic $k$ values then we can use a feature in __rstanarm__ that lets us refit the model once for each of these problematic observations. Each time the model is refit, one of the observations with a high $k$ value is omitted and the LOO calculations are performed exactly for that observation. The results are then recombined with the approximate LOO calculations already carried out for the observations without problematic $k$ values: ```{r reloo} if (any(pareto_k_values(loo2) > 0.7)) { loo2 <- loo(fit2, save_psis = TRUE, k_threshold = 0.7) } print(loo2) ``` In the print output we can see that the Monte Carlo SE is small compared to the other uncertainties. On the other hand, `p_loo` is about 7 and still a bit higher than the total number of parameters in the model. This indicates that there is almost certainly still some degree of model misspecification, but this is much better than the `p_loo` estimate for the Poisson model. For further model checking we again examine the LOO-PIT values. ```{r ppc_loo_pit_overlay-negbin} yrep <- posterior_predict(fit2) ppc_loo_pit_overlay(roaches$y, yrep, lw = weights(loo2$psis_object)) ``` The plot for the negative binomial model looks better than the Poisson plot, but we still see that this model is not capturing all of the essential features in the data. ## Comparing the models on expected log predictive density We can use the `loo_compare` function to compare our two models on expected log predictive density (ELPD) for new data: ```{r loo_compare} loo_compare(loo1, loo2) ``` The difference in ELPD is much larger than several times the estimated standard error of the difference again indicating that the negative-binomial model is expected to have better predictive performance than the Poisson model. However, according to the LOO-PIT checks there is still some misspecification, and a reasonable guess is that a hurdle or zero-inflated model would be an improvement (we leave that for another case study).
# References Gabry, J., Simpson, D., Vehtari, A., Betancourt, M. and Gelman, A. (2019), Visualization in Bayesian workflow. _J. R. Stat. Soc. A_, 182: 389-402. \doi:10.1111/rssa.12378. ([journal version](https://rss.onlinelibrary.wiley.com/doi/full/10.1111/rssa.12378), [arXiv preprint](https://arxiv.org/abs/1709.01449), [code on GitHub](https://github.com/jgabry/bayes-vis-paper))
Gelman, A. and Hill, J. (2007). _Data Analysis Using Regression and Multilevel/Hierarchical Models._ Cambridge University Press, Cambridge, UK. Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. _Statistics and Computing_. 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. [online](https://link.springer.com/article/10.1007/s11222-016-9696-4), [arXiv preprint arXiv:1507.04544](https://arxiv.org/abs/1507.04544). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.02646](https://arxiv.org/abs/1507.02646). loo/vignettes/loo2-moment-matching.Rmd0000644000176200001440000002774214407123455017500 0ustar liggesusers--- title: "Avoiding model refits in leave-one-out cross-validation with moment matching" author: "Topi Paananen, Paul Bürkner, Aki Vehtari and Jonah Gabry" date: "`r Sys.Date()`" output: html_vignette: toc: yes params: EVAL: !r identical(Sys.getenv("NOT_CRAN"), "true") --- ```{r, child="children/SETTINGS-knitr.txt"} ``` ```{r, child="children/SEE-ONLINE.txt", eval = if (isTRUE(exists("params"))) !params$EVAL else TRUE} ``` # Introduction This vignette demonstrates how to improve the Monte Carlo sampling accuracy of leave-one-out cross-validation with the __loo__ package and Stan. The __loo__ package automatically monitors the sampling accuracy using Pareto $k$ diagnostics for each observation. Here, we present a method for quickly improving the accuracy when the Pareto diagnostics indicate problems. This is done by performing some additional computations using the existing posterior sample. If successful, this will decrease the Pareto $k$ values, making the model assessment more reliable. __loo__ also stores the original Pareto $k$ values with the name `influence_pareto_k` which are not changed. They can be used as a diagnostic of how much each observation influences the posterior distribution. The methodology presented is based on the paper * Paananen, T., Piironen, J., Buerkner, P.-C., Vehtari, A. (2020). Implicitly Adaptive Importance Sampling. [arXiv preprint arXiv:1906.08850](https://arxiv.org/abs/1906.08850). More information about the Pareto $k$ diagnostics is given in the following papers * Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. _Statistics and Computing_. 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. Links: [published](https://link.springer.com/article/10.1007/s11222-016-9696-4) | [arXiv preprint](https://arxiv.org/abs/1507.04544). * Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.02646](https://arxiv.org/abs/1507.02646). # Example: Eradication of Roaches We will use the same example as in the vignette [_Using the loo package (version >= 2.0.0)_](https://mc-stan.org/loo/articles/loo2-example.html). See the demo for a description of the problem and data. We will use the same Poisson regression model as in the case study. ## Coding the Stan model Here is the Stan code for fitting the Poisson regression model, which we will use for modeling the number of roaches. ```{r stancode} stancode <- " data { int K; int N; matrix[N,K] x; int y[N]; vector[N] offset; real beta_prior_scale; real alpha_prior_scale; } parameters { vector[K] beta; real intercept; } model { y ~ poisson(exp(x * beta + intercept + offset)); beta ~ normal(0,beta_prior_scale); intercept ~ normal(0,alpha_prior_scale); } generated quantities { vector[N] log_lik; for (n in 1:N) log_lik[n] = poisson_lpmf(y[n] | exp(x[n] * beta + intercept + offset[n])); } " ``` Following the usual approach recommended in [_Writing Stan programs for use with the loo package_](http://mc-stan.org/loo/articles/loo2-with-rstan.html), we compute the log-likelihood for each observation in the `generated quantities` block of the Stan program. ## Setup In addition to __loo__, we load the __rstan__ package for fitting the model, and the __rstanarm__ package for the data. ```{r setup, message=FALSE} library("rstan") library("loo") seed <- 9547 set.seed(seed) ``` ## Fitting the model with RStan Next we fit the model in Stan using the __rstan__ package: ```{r modelfit, message=FALSE} # Prepare data data(roaches, package = "rstanarm") roaches$roach1 <- sqrt(roaches$roach1) y <- roaches$y x <- roaches[,c("roach1", "treatment", "senior")] offset <- log(roaches[,"exposure2"]) n <- dim(x)[1] k <- dim(x)[2] standata <- list(N = n, K = k, x = as.matrix(x), y = y, offset = offset, beta_prior_scale = 2.5, alpha_prior_scale = 5.0) # Compile stanmodel <- stan_model(model_code = stancode) # Fit model fit <- sampling(stanmodel, data = standata, seed = seed, refresh = 0) print(fit, pars = "beta") ``` Let us now evaluate the predictive performance of the model using `loo()`. ```{r loo1} loo1 <- loo(fit) loo1 ``` The `loo()` function output warnings that there are some observations which are highly influential, and thus the accuracy of importance sampling is compromised as indicated by the large Pareto $k$ diagnostic values (> 0.7). As discussed in the vignette [_Using the loo package (version >= 2.0.0)_](https://mc-stan.org/loo/articles/loo2-example.html), this may be an indication of model misspecification. Despite that, it is still beneficial to be able to evaluate the predictive performance of the model accurately. ## Moment matching correction for importance sampling To improve the accuracy of the `loo()` result above, we could perform leave-one-out cross-validation by explicitly leaving out single observations and refitting the model using MCMC repeatedly. However, the Pareto $k$ diagnostics indicate that there are 19 observations which are problematic. This would require 19 model refits which may require a lot of computation time. Instead of refitting with MCMC, we can perform a faster moment matching correction to the importance sampling for the problematic observations. This can be done with the `loo_moment_match()` function in the __loo__ package, which takes our existing `loo` object as input and modifies it. The moment matching requires some evaluations of the model posterior density. For models fitted with __rstan__, this can be conveniently done by using the existing `stanfit` object. First, we show how the moment matching can be used for a model fitted using __rstan__. It only requires setting the argument `moment_match` to `TRUE` in the `loo()` function. Optionally, you can also set the argument `k_threshold` which determines the Pareto $k$ threshold, above which moment matching is used. By default, it operates on all observations whose Pareto $k$ value is larger than 0.7. ```{r loo_moment_match} # available in rstan >= 2.21 loo2 <- loo(fit, moment_match = TRUE) loo2 ``` After the moment matching, all observations have the diagnostic Pareto $k$ less than 0.7, meaning that the estimates are now reliable. The total `elpd_loo` estimate also changed from `-5457.8` to `-5478.5`, showing that before moment matching, `loo()` overestimated the predictive performance of the model. The updated Pareto $k$ values stored in `loo2$diagnostics$pareto_k` are considered algorithmic diagnostic values that indicate the sampling accuracy. The original Pareto $k$ values are stored in `loo2$pointwise[,"influence_pareto_k"]` and these are not modified by the moment matching. These can be considered as diagnostics for how big influence each observation has on the posterior distribution. In addition to the Pareto $k$ diagnostics, moment matching also updates the effective sample size estimates. # Using `loo_moment_match()` directly The moment matching can also be performed by explicitly calling the function `loo_moment_match()`. This enables its use also for models that are not using __rstan__ or another package with built-in support for `loo_moment_match()`. To use `loo_moment_match()`, the user must give the model object `x`, the `loo` object, and 5 helper functions as arguments to `loo_moment_match()`. The helper functions are * `post_draws` + A function the takes `x` as the first argument and returns a matrix of posterior draws of the model parameters, `pars`. * `log_lik_i` + A function that takes `x` and `i` and returns a matrix (one column per chain) or a vector (all chains stacked) of log-likeliood draws of the ith observation based on the model `x`. If the draws are obtained using MCMC, the matrix with MCMC chains separated is preferred. * `unconstrain_pars` + A function that takes arguments `x` and `pars`, and returns posterior draws on the unconstrained space based on the posterior draws on the constrained space passed via `pars`. * `log_prob_upars` + A function that takes arguments `x` and `upars`, and returns a matrix of log-posterior density values of the unconstrained posterior draws passed via `upars`. * `log_lik_i_upars` + A function that takes arguments `x`, `upars`, and `i` and returns a vector of log-likelihood draws of the `i`th observation based on the unconstrained posterior draws passed via `upars`. Next, we show how the helper functions look like for RStan objects, and show an example of using `loo_moment_match()` directly. For stanfit objects from __rstan__ objects, the functions look like this: ```{r stanfitfuns} # create a named list of draws for use with rstan methods .rstan_relist <- function(x, skeleton) { out <- utils::relist(x, skeleton) for (i in seq_along(skeleton)) { dim(out[[i]]) <- dim(skeleton[[i]]) } out } # rstan helper function to get dims of parameters right .create_skeleton <- function(pars, dims) { out <- lapply(seq_along(pars), function(i) { len_dims <- length(dims[[i]]) if (len_dims < 1) return(0) return(array(0, dim = dims[[i]])) }) names(out) <- pars out } # extract original posterior draws post_draws_stanfit <- function(x, ...) { as.matrix(x) } # compute a matrix of log-likelihood values for the ith observation # matrix contains information about the number of MCMC chains log_lik_i_stanfit <- function(x, i, parameter_name = "log_lik", ...) { loo::extract_log_lik(x, parameter_name, merge_chains = FALSE)[, , i] } # transform parameters to the unconstraint space unconstrain_pars_stanfit <- function(x, pars, ...) { skeleton <- .create_skeleton(x@sim$pars_oi, x@par_dims[x@sim$pars_oi]) upars <- apply(pars, 1, FUN = function(theta) { rstan::unconstrain_pars(x, .rstan_relist(theta, skeleton)) }) # for one parameter models if (is.null(dim(upars))) { dim(upars) <- c(1, length(upars)) } t(upars) } # compute log_prob for each posterior draws on the unconstrained space log_prob_upars_stanfit <- function(x, upars, ...) { apply(upars, 1, rstan::log_prob, object = x, adjust_transform = TRUE, gradient = FALSE) } # compute log_lik values based on the unconstrained parameters log_lik_i_upars_stanfit <- function(x, upars, i, parameter_name = "log_lik", ...) { S <- nrow(upars) out <- numeric(S) for (s in seq_len(S)) { out[s] <- rstan::constrain_pars(x, upars = upars[s, ])[[parameter_name]][i] } out } ``` Using these function, we can call `loo_moment_match()` to update the existing `loo` object. ```{r loo_moment_match.default, message=FALSE} loo3 <- loo::loo_moment_match.default( x = fit, loo = loo1, post_draws = post_draws_stanfit, log_lik_i = log_lik_i_stanfit, unconstrain_pars = unconstrain_pars_stanfit, log_prob_upars = log_prob_upars_stanfit, log_lik_i_upars = log_lik_i_upars_stanfit ) loo3 ``` As expected, the result is identical to the previous result of `loo2 <- loo(fit, moment_match = TRUE)`. # References Gelman, A., and Hill, J. (2007). *Data Analysis Using Regression and Multilevel Hierarchical Models.* Cambridge University Press. Stan Development Team (2020) _RStan: the R interface to Stan, Version 2.21.1_ https://mc-stan.org Paananen, T., Piironen, J., Buerkner, P.-C., Vehtari, A. (2021). Implicitly adaptive importance sampling. _Statistics and Computing_, 31, 16. \doi:10.1007/s11222-020-09982-2. arXiv preprint arXiv:1906.08850. Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. _Statistics and Computing_. 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. Links: [published](https://link.springer.com/article/10.1007/s11222-016-9696-4) | [arXiv preprint](https://arxiv.org/abs/1507.04544). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.02646](https://arxiv.org/abs/1507.02646). loo/vignettes/loo2-non-factorized.Rmd0000644000176200001440000006631014407123455017325 0ustar liggesusers--- title: "Leave-one-out cross-validation for non-factorized models" author: "Aki Vehtari, Paul Bürkner and Jonah Gabry" date: "`r Sys.Date()`" output: html_vignette: toc: yes encoding: "UTF-8" params: EVAL: !r identical(Sys.getenv("NOT_CRAN"), "true") --- ```{r settings, child="children/SETTINGS-knitr.txt"} ``` ```{r more-knitr-ops, include=FALSE} knitr::opts_chunk$set( cache=TRUE, message=FALSE, warning=FALSE ) ``` ```{r, child="children/SEE-ONLINE.txt", eval = if (isTRUE(exists("params"))) !params$EVAL else TRUE} ``` # Introduction When computing ELPD-based LOO-CV for a Bayesian model we need to compute the log leave-one-out predictive densities $\log{p(y_i | y_{-i})}$ for every response value $y_i, \: i = 1, \ldots, N$, where $y_{-i}$ denotes all response values except observation $i$. To obtain $p(y_i | y_{-i})$, we need to have access to the pointwise likelihood $p(y_i\,|\, y_{-i}, \theta)$ and integrate over the model parameters $\theta$: $$ p(y_i\,|\,y_{-i}) = \int p(y_i\,|\, y_{-i}, \theta) \, p(\theta\,|\, y_{-i}) \,d \theta $$ Here, $p(\theta\,|\, y_{-i})$ is the leave-one-out posterior distribution for $\theta$, that is, the posterior distribution for $\theta$ obtained by fitting the model while holding out the $i$th observation (we will later show how refitting the model to data $y_{-i}$ can be avoided). If the observation model is formulated directly as the product of the pointwise observation models, we call it a *factorized* model. In this case, the likelihood is also the product of the pointwise likelihood contributions $p(y_i\,|\, y_{-i}, \theta)$. To better illustrate possible structures of the observation models, we formally divide $\theta$ into two parts, observation-specific latent variables $f = (f_1, \ldots, f_N)$ and hyperparameters $\psi$, so that $p(y_i\,|\, y_{-i}, \theta) = p(y_i\,|\, y_{-i}, f_i, \psi)$. Depending on the model, one of the two parts of $\theta$ may also be empty. In very simple models, such as linear regression models, latent variables are not explicitly presented and response values are conditionally independent given $\psi$, so that $p(y_i\,|\, y_{-i}, f_i, \psi) = p(y_i \,|\, \psi)$. The full likelihood can then be written in the familiar form $$ p(y \,|\, \psi) = \prod_{i=1}^N p(y_i \,|\, \psi), $$ where $y = (y_1, \ldots, y_N)$ denotes the vector of all responses. When the likelihood factorizes this way, the conditional pointwise log-likelihood can be obtained easily by computing $p(y_i\,|\, \psi)$ for each $i$ with computational cost $O(n)$. Yet, there are several reasons why a *non-factorized* observation model may be necessary or preferred. In non-factorized models, the joint likelihood of the response values $p(y \,|\, \theta)$ is not factorized into observation-specific components, but rather given directly as one joint expression. For some models, an analytic factorized formulation is simply not available in which case we speak of a *non-factorizable* model. Even in models whose observation model can be factorized in principle, it may still be preferable to use a non-factorized form for reasons of efficiency and numerical stability (Bürkner et al. 2020). Whether a non-factorized model is used by necessity or for efficiency and stability, it comes at the cost of having no direct access to the leave-one-out predictive densities and thus to the overall leave-one-out predictive accuracy. In theory, we can express the observation-specific likelihoods in terms of the joint likelihood via $$ p(y_i \,|\, y_{i-1}, \theta) = \frac{p(y \,|\, \theta)}{p(y_{-i} \,|\, \theta)} = \frac{p(y \,|\, \theta)}{\int p(y \,|\, \theta) \, d y_i}, $$ but the expression on the right-hand side may not always have an analytical solution. Computing $\log p(y_i \,|\, y_{-i}, \theta)$ for non-factorized models is therefore often impossible, or at least inefficient and numerically unstable. However, there is a large class of multivariate normal and Student-$t$ models for which there are efficient analytical solutions available. More details can be found in our paper about LOO-CV for non-factorized models (Bürkner, Gabry, & Vehtari, 2020), which is available as a preprint on arXiv (https://arxiv.org/abs/1810.10559). # LOO-CV for multivariate normal models In this vignette, we will focus on non-factorized multivariate normal models. Based on results of Sundararajan and Keerthi (2001), Bürkner et al. (2020) show that, for multivariate normal models with coriance matrix $C$, the LOO predictive mean and standard deviation can be computed as follows: \begin{align} \mu_{\tilde{y},-i} &= y_i-\bar{c}_{ii}^{-1} g_i \nonumber \\ \sigma_{\tilde{y},-i} &= \sqrt{\bar{c}_{ii}^{-1}}, \end{align} where $g_i$ and $\bar{c}_{ii}$ are \begin{align} g_i &= \left[C^{-1} y\right]_i \nonumber \\ \bar{c}_{ii} &= \left[C^{-1}\right]_{ii}. \end{align} Using these results, the log predictive density of the $i$th observation is then computed as $$ \log p(y_i \,|\, y_{-i},\theta) = - \frac{1}{2}\log(2\pi) - \frac{1}{2}\log \sigma^2_{-i} - \frac{1}{2}\frac{(y_i-\mu_{-i})^2}{\sigma^2_{-i}}. $$ Expressing this same equation in terms of $g_i$ and $\bar{c}_{ii}$, the log predictive density becomes: $$ \log p(y_i \,|\, y_{-i},\theta) = - \frac{1}{2}\log(2\pi) + \frac{1}{2}\log \bar{c}_{ii} - \frac{1}{2}\frac{g_i^2}{\bar{c}_{ii}}. $$ (Note that Vehtari et al. (2016) has a typo in the corresponding Equation 34.) From these equations we can now derive a recipe for obtaining the conditional pointwise log-likelihood for _all_ models that can be expressed conditionally in terms of a multivariate normal with invertible covariance matrix $C$. ## Approximate LOO-CV using integrated importance-sampling The above LOO equations for multivariate normal models are conditional on parameters $\theta$. Therefore, to obtain the leave-one-out predictive density $p(y_i \,|\, y_{-i})$ we need to integrate over $\theta$, $$ p(y_i\,|\,y_{-i}) = \int p(y_i\,|\,y_{-i}, \theta) \, p(\theta\,|\,y_{-i}) \,d\theta. $$ Here, $p(\theta\,|\,y_{-i})$ is the leave-one-out posterior distribution for $\theta$, that is, the posterior distribution for $\theta$ obtained by fitting the model while holding out the $i$th observation. To avoid the cost of sampling from $N$ leave-one-out posteriors, it is possible to take the posterior draws $\theta^{(s)}, \, s=1,\ldots,S$, from the \emph{full} posterior $p(\theta\,|\,y)$, and then approximate the above integral using integrated importance sampling (Vehtari et al., 2016, Section 3.6.1): $$ p(y_i\,|\,y_{-i}) \approx \frac{ \sum_{s=1}^S p(y_i\,|\,y_{-i},\,\theta^{(s)}) \,w_i^{(s)}}{ \sum_{s=1}^S w_i^{(s)}}, $$ where $w_i^{(s)}$ are importance weights. First we compute the raw importance ratios $$ r_i^{(s)} \propto \frac{1}{p(y_i \,|\, y_{-i}, \,\theta^{(s)})}, $$ and then stabilize them using Pareto smoothed importance sampling (PSIS, Vehtari et al, 2019) to obtain the weights $w_i^{(s)}$. The resulting approximation is referred to as PSIS-LOO (Vehtari et al, 2017). ## Exact LOO-CV with re-fitting In order to validate the approximate LOO procedure, and also in order to allow exact computations to be made for a small number of leave-one-out folds for which the Pareto $k$ diagnostic (Vehtari et al, 2019) indicates an unstable approximation, we need to consider how we might to do _exact_ leave-one-out CV for a non-factorized model. In the case of a Gaussian process that has the marginalization property, we could just drop the one row and column of $C$ corresponding to the held out out observation. This does not hold in general for multivariate normal models, however, and to keep the original prior we may need to maintain the full covariance matrix $C$ even when one of the observations is left out. The solution is to model $y_i$ as a missing observation and estimate it along with all of the other model parameters. For a conditional multivariate normal model, $\log p(y_i\,|\,y_{-i})$ can be computed as follows. First, we model $y_i$ as missing and denote the corresponding parameter $y_i^{\mathrm{mis}}$. Then, we define $$ y_{\mathrm{mis}(i)} = (y_1, \ldots, y_{i-1}, y_i^{\mathrm{mis}}, y_{i+1}, \ldots, y_N). $$ to be the same as the full set of observations $y$, except replacing $y_i$ with the parameter $y_i^{\mathrm{mis}}$. Second, we compute the LOO predictive mean and standard deviations as above, but replace $y$ with $y_{\mathrm{mis}(i)}$ in the computation of $\mu_{\tilde{y},-i}$: $$ \mu_{\tilde{y},-i} = y_{{\mathrm{mis}}(i)}-\bar{c}_{ii}^{-1}g_i, $$ where in this case we have $$ g_i = \left[ C^{-1} y_{\mathrm{mis}(i)} \right]_i. $$ The conditional log predictive density is then computed with the above $\mu_{\tilde{y},-i}$ and the left out observation $y_i$: $$ \log p(y_i\,|\,y_{-i},\theta) = - \frac{1}{2}\log(2\pi) - \frac{1}{2}\log \sigma^2_{\tilde{y},-i} - \frac{1}{2}\frac{(y_i-\mu_{\tilde{y},-i})^2}{\sigma^2_{\tilde{y},-i}}. $$ Finally, the leave-one-out predictive distribution can then be estimated as $$ p(y_i\,|\,y_{-i}) \approx \sum_{s=1}^S p(y_i\,|\,y_{-i}, \theta_{-i}^{(s)}), $$ where $\theta_{-i}^{(s)}$ are draws from the posterior distribution $p(\theta\,|\,y_{\mathrm{mis}(i)})$. # Lagged SAR models A common non-factorized multivariate normal model is the simultaneously autoregressive (SAR) model, which is frequently used for spatially correlated data. The lagged SAR model is defined as $$ y = \rho Wy + \eta + \epsilon $$ or equivalently $$ (I - \rho W)y = \eta + \epsilon, $$ where $\rho$ is the spatial correlation parameter and $W$ is a user-defined weight matrix. The matrix $W$ has entries $w_{ii} = 0$ along the diagonal and the off-diagonal entries $w_{ij}$ are larger when areas $i$ and $j$ are closer to each other. In a linear model, the predictor term $\eta$ is given by $\eta = X \beta$ with design matrix $X$ and regression coefficients $\beta$. However, since the above equation holds for arbitrary $\eta$, these results are not restricted to linear models. If we have $\epsilon \sim {\mathrm N}(0, \,\sigma^2 I)$, it follows that $$ (I - \rho W)y \sim {\mathrm N}(\eta, \sigma^2 I), $$ which corresponds to the following log PDF coded in **Stan**: ```{r lpdf, eval=FALSE} /** * Normal log-pdf for spatially lagged responses * * @param y Vector of response values. * @param mu Mean parameter vector. * @param sigma Positive scalar residual standard deviation. * @param rho Positive scalar autoregressive parameter. * @param W Spatial weight matrix. * * @return A scalar to be added to the log posterior. */ real normal_lagsar_lpdf(vector y, vector mu, real sigma, real rho, matrix W) { int N = rows(y); real inv_sigma2 = 1 / square(sigma); matrix[N, N] W_tilde = -rho * W; vector[N] half_pred; for (n in 1:N) W_tilde[n,n] += 1; half_pred = W_tilde * (y - mdivide_left(W_tilde, mu)); return 0.5 * log_determinant(crossprod(W_tilde) * inv_sigma2) - 0.5 * dot_self(half_pred) * inv_sigma2; } ``` For the purpose of computing LOO-CV, it makes sense to rewrite the SAR model in slightly different form. Conditional on $\rho$, $\eta$, and $\sigma$, if we write \begin{align} y-(I-\rho W)^{-1}\eta &\sim {\mathrm N}(0, \sigma^2(I-\rho W)^{-1}(I-\rho W)^{-T}), \end{align} or more compactly, with $\widetilde{W}=(I-\rho W)$, \begin{align} y-\widetilde{W}^{-1}\eta &\sim {\mathrm N}(0, \sigma^2(\widetilde{W}^{T}\widetilde{W})^{-1}), \end{align} then this has the same form as the zero mean Gaussian process from above. Accordingly, we can compute the leave-one-out predictive densities with the equations from Sundararajan and Keerthi (2001), replacing $y$ with $(y-\widetilde{W}^{-1}\eta)$ and taking the covariance matrix $C$ to be $\sigma^2(\widetilde{W}^{T}\widetilde{W})^{-1}$. ## Case Study: Neighborhood Crime in Columbus, Ohio In order to demonstrate how to carry out the computations implied by these equations, we will first fit a lagged SAR model to data on crime in 49 different neighborhoods of Columbus, Ohio during the year 1980. The data was originally described in Aneslin (1988) and ships with the **spdep** R package. In addition to the **loo** package, for this analysis we will use the **brms** interface to Stan to generate a Stan program and fit the model, and also the **bayesplot** and **ggplot2** packages for plotting. ```{r setup, cache=FALSE} library("loo") library("brms") library("bayesplot") library("ggplot2") color_scheme_set("brightblue") theme_set(theme_default()) SEED <- 10001 set.seed(SEED) # only sets seed for R (seed for Stan set later) # loads COL.OLD data frame and COL.nb neighbor list data(oldcol, package = "spdep") ``` The three variables in the data set relevant to this example are: * `CRIME`: the number of residential burglaries and vehicle thefts per thousand households in the neighbood * `HOVAL`: housing value in units of $1000 USD * `INC`: household income in units of $1000 USD ```{r data} str(COL.OLD[, c("CRIME", "HOVAL", "INC")]) ``` We will also use the object `COL.nb`, which is a list containing information about which neighborhoods border each other. From this list we will be able to construct the weight matrix to used to help account for the spatial dependency among the observations. ### Fit lagged SAR model A model predicting `CRIME` from `INC` and `HOVAL`, while accounting for the spatial dependency via an SAR structure, can be specified in **brms** as follows. ```{r fit, results="hide"} fit <- brm( CRIME ~ INC + HOVAL + sar(COL.nb, type = "lag"), data = COL.OLD, data2 = list(COL.nb = COL.nb), chains = 4, seed = SEED ) ``` The code above fits the model in **Stan** using a log PDF equivalent to the `normal_lagsar_lpdf` function we defined above. In the summary output below we see that both higher income and higher housing value predict lower crime rates in the neighborhood. Moreover, there seems to be substantial spatial correlation between adjacent neighborhoods, as indicated by the posterior distribution of the `lagsar` parameter. ```{r plot-lagsar, message=FALSE} lagsar <- as.matrix(fit, pars = "lagsar") estimates <- quantile(lagsar, probs = c(0.25, 0.5, 0.75)) mcmc_hist(lagsar) + vline_at(estimates, linetype = 2, size = 1) + ggtitle("lagsar: posterior median and 50% central interval") ``` ### Approximate LOO-CV After fitting the model, the next step is to compute the pointwise log-likelihood values needed for approximate LOO-CV. To do this we will use the recipe laid out in the previous sections. ```{r approx} posterior <- as.data.frame(fit) y <- fit$data$CRIME N <- length(y) S <- nrow(posterior) loglik <- yloo <- sdloo <- matrix(nrow = S, ncol = N) for (s in 1:S) { p <- posterior[s, ] eta <- p$b_Intercept + p$b_INC * fit$data$INC + p$b_HOVAL * fit$data$HOVAL W_tilde <- diag(N) - p$lagsar * spdep::nb2mat(COL.nb) Cinv <- t(W_tilde) %*% W_tilde / p$sigma^2 g <- Cinv %*% (y - solve(W_tilde, eta)) cbar <- diag(Cinv) yloo[s, ] <- y - g / cbar sdloo[s, ] <- sqrt(1 / cbar) loglik[s, ] <- dnorm(y, yloo[s, ], sdloo[s, ], log = TRUE) } # use loo for psis smoothing log_ratios <- -loglik psis_result <- psis(log_ratios) ``` The quality of the PSIS-LOO approximation can be investigated graphically by plotting the Pareto-k estimate for each observation. Ideally, they should not exceed $0.5$, but in practice the algorithm turns out to be robust up to values of $0.7$ (Vehtari et al, 2017, 2019). In the plot below, we see that the fourth observation is problematic and so may reduce the accuracy of the LOO-CV approximation. ```{r plot, cache = FALSE} plot(psis_result, label_points = TRUE) ``` We can also check that the conditional leave-one-out predictive distribution equations work correctly, for instance, using the last posterior draw: ```{r checklast, cache = FALSE} yloo_sub <- yloo[S, ] sdloo_sub <- sdloo[S, ] df <- data.frame( y = y, yloo = yloo_sub, ymin = yloo_sub - sdloo_sub * 2, ymax = yloo_sub + sdloo_sub * 2 ) ggplot(data=df, aes(x = y, y = yloo, ymin = ymin, ymax = ymax)) + geom_errorbar( width = 1, color = "skyblue3", position = position_jitter(width = 0.25) ) + geom_abline(color = "gray30", size = 1.2) + geom_point() ``` Finally, we use PSIS-LOO to approximate the expected log predictive density (ELPD) for new data, which we will validate using exact LOO-CV in the upcoming section. ```{r psisloo} (psis_loo <- loo(loglik)) ``` ### Exact LOO-CV Exact LOO-CV for the above example is somewhat more involved, as we need to re-fit the model $N$ times and each time model the held-out data point as a parameter. First, we create an empty dummy model that we will update below as we loop over the observations. ```{r fit_dummy, cache = TRUE} # see help("mi", "brms") for details on the mi() usage fit_dummy <- brm( CRIME | mi() ~ INC + HOVAL + sar(COL.nb, type = "lag"), data = COL.OLD, data2 = list(COL.nb = COL.nb), chains = 0 ) ``` Next, we fit the model $N$ times, each time leaving out a single observation and then computing the log predictive density for that observation. For obvious reasons, this takes much longer than the approximation we computed above, but it is necessary in order to validate the approximate LOO-CV method. Thanks to the PSIS-LOO approximation, in general doing these slow exact computations can be avoided. ```{r exact-loo-cv, results="hide", message=FALSE, warning=FALSE, cache = TRUE} S <- 500 res <- vector("list", N) loglik <- matrix(nrow = S, ncol = N) for (i in seq_len(N)) { dat_mi <- COL.OLD dat_mi$CRIME[i] <- NA fit_i <- update(fit_dummy, newdata = dat_mi, # just for vignette chains = 1, iter = S * 2) posterior <- as.data.frame(fit_i) yloo <- sdloo <- rep(NA, S) for (s in seq_len(S)) { p <- posterior[s, ] y_miss_i <- y y_miss_i[i] <- p$Ymi eta <- p$b_Intercept + p$b_INC * fit_i$data$INC + p$b_HOVAL * fit_i$data$HOVAL W_tilde <- diag(N) - p$lagsar * spdep::nb2mat(COL.nb) Cinv <- t(W_tilde) %*% W_tilde / p$sigma^2 g <- Cinv %*% (y_miss_i - solve(W_tilde, eta)) cbar <- diag(Cinv); yloo[s] <- y_miss_i[i] - g[i] / cbar[i] sdloo[s] <- sqrt(1 / cbar[i]) loglik[s, i] <- dnorm(y[i], yloo[s], sdloo[s], log = TRUE) } ypred <- rnorm(S, yloo, sdloo) res[[i]] <- data.frame(y = c(posterior$Ymi, ypred)) res[[i]]$type <- rep(c("pp", "loo"), each = S) res[[i]]$obs <- i } res <- do.call(rbind, res) ``` A first step in the validation of the pointwise predictive density is to compare the distribution of the implied response values for the left-out observation to the distribution of the $y_i^{\mathrm{mis}}$ posterior-predictive values estimated as part of the model. If the pointwise predictive density is correct, the two distributions should match very closely (up to sampling error). In the plot below, we overlay these two distributions for the first four observations and see that they match very closely (as is the case for all $49$ observations of in this example). ```{r yplots, cache = FALSE, fig.width=10, out.width="95%", fig.asp = 0.3} res_sub <- res[res$obs %in% 1:4, ] ggplot(res_sub, aes(y, fill = type)) + geom_density(alpha = 0.6) + facet_wrap("obs", scales = "fixed", ncol = 4) ``` In the final step, we compute the ELPD based on the exact LOO-CV and compare it to the approximate PSIS-LOO result computed earlier. ```{r loo_exact, cache=FALSE} log_mean_exp <- function(x) { # more stable than log(mean(exp(x))) max_x <- max(x) max_x + log(sum(exp(x - max_x))) - log(length(x)) } exact_elpds <- apply(loglik, 2, log_mean_exp) exact_elpd <- sum(exact_elpds) round(exact_elpd, 1) ``` The results of the approximate and exact LOO-CV are similar but not as close as we would expect if there were no problematic observations. We can investigate this issue more closely by plotting the approximate against the exact pointwise ELPD values. ```{r compare, fig.height=5} df <- data.frame( approx_elpd = psis_loo$pointwise[, "elpd_loo"], exact_elpd = exact_elpds ) ggplot(df, aes(x = approx_elpd, y = exact_elpd)) + geom_abline(color = "gray30") + geom_point(size = 2) + geom_point(data = df[4, ], size = 3, color = "red3") + xlab("Approximate elpds") + ylab("Exact elpds") + coord_fixed(xlim = c(-16, -3), ylim = c(-16, -3)) ``` In the plot above the fourth data point ---the observation flagged as problematic by the PSIS-LOO approximation--- is colored in red and is the clear outlier. Otherwise, the correspondence between the exact and approximate values is strong. In fact, summing over the pointwise ELPD values and leaving out the fourth observation yields practically equivalent results for approximate and exact LOO-CV: ````{r pt4} without_pt_4 <- c( approx = sum(psis_loo$pointwise[-4, "elpd_loo"]), exact = sum(exact_elpds[-4]) ) round(without_pt_4, 1) ``` From this we can conclude that the difference we found when including *all* observations does not indicate a bug in our implementation of the approximate LOO-CV but rather a violation of its assumptions. # Working with Stan directly So far, we have specified the models in brms and only used Stan implicitely behind the scenes. This allowed us to focus on the primary purpose of validating approximate LOO-CV for non-factorized models. However, we would also like to show how everything can be set up in Stan directly. The Stan code brms generates is human readable and so we can use it to learn some of the essential aspects of Stan and the particular model we are implementing. The Stan program below is a slightly modified version of the code extracted via `stancode(fit_dummy)`: ```{r brms-stan-code, eval=FALSE} // generated with brms 2.2.0 functions { /** * Normal log-pdf for spatially lagged responses * * @param y Vector of response values. * @param mu Mean parameter vector. * @param sigma Positive scalar residual standard deviation. * @param rho Positive scalar autoregressive parameter. * @param W Spatial weight matrix. * * @return A scalar to be added to the log posterior. */ real normal_lagsar_lpdf(vector y, vector mu, real sigma, real rho, matrix W) { int N = rows(y); real inv_sigma2 = 1 / square(sigma); matrix[N, N] W_tilde = -rho * W; vector[N] half_pred; for (n in 1:N) W_tilde[n, n] += 1; half_pred = W_tilde * (y - mdivide_left(W_tilde, mu)); return 0.5 * log_determinant(crossprod(W_tilde) * inv_sigma2) - 0.5 * dot_self(half_pred) * inv_sigma2; } } data { int N; // total number of observations vector[N] Y; // response variable int Nmi; // number of missings int Jmi[Nmi]; // positions of missings int K; // number of population-level effects matrix[N, K] X; // population-level design matrix matrix[N, N] W; // spatial weight matrix int prior_only; // should the likelihood be ignored? } transformed data { int Kc = K - 1; matrix[N, K - 1] Xc; // centered version of X vector[K - 1] means_X; // column means of X before centering for (i in 2:K) { means_X[i - 1] = mean(X[, i]); Xc[, i - 1] = X[, i] - means_X[i - 1]; } } parameters { vector[Nmi] Ymi; // estimated missings vector[Kc] b; // population-level effects real temp_Intercept; // temporary intercept real sigma; // residual SD real lagsar; // SAR parameter } transformed parameters { } model { vector[N] Yl = Y; vector[N] mu = Xc * b + temp_Intercept; Yl[Jmi] = Ymi; // priors including all constants target += student_t_lpdf(temp_Intercept | 3, 34, 17); target += student_t_lpdf(sigma | 3, 0, 17) - 1 * student_t_lccdf(0 | 3, 0, 17); // likelihood including all constants if (!prior_only) { target += normal_lagsar_lpdf(Yl | mu, sigma, lagsar, W); } } generated quantities { // actual population-level intercept real b_Intercept = temp_Intercept - dot_product(means_X, b); } ``` Here we want to focus on two aspects of the Stan code. First, because there is no built-in function in Stan that calculates the log-likelihood for the lag-SAR model, we define a new `normal_lagsar_lpdf` function in the `functions` block of the Stan program. This is the same function we showed earlier in the vignette and it can be used to compute the log-likelihood in an efficient and numerically stable way. The `_lpdf` suffix used in the function name informs Stan that this is a log probability density function. Second, this Stan program nicely illustrates how to set up missing value imputation. Instead of just computing the log-likelihood for the observed responses `Y`, we define a new variable `Yl` which is equal to `Y` if the reponse is observed and equal to `Ymi` if the response is missing. The latter is in turn defined as a parameter and thus estimated along with all other paramters of the model. More details about missing value imputation in Stan can be found in the *Missing Data & Partially Known Parameters* section of the [Stan manual](https://mc-stan.org/users/documentation/index.html). The Stan code extracted from brms is not only helpful when learning Stan, but can also drastically speed up the specification of models that are not support by brms. If brms can fit a model similar but not identical to the desired model, we can let brms generate the Stan program for the similar model and then mold it into the program that implements the model we actually want to fit. Rather than calling `stancode()`, which requires an existing fitted model object, we recommend using `make_stancode()` and specifying the `save_model` argument to write the Stan program to a file. The corresponding data can be prepared with `make_standata()` and then manually amended if needed. Once the code and data have been edited, they can be passed to RStan's `stan()` function via the `file` and `data` arguments. # Conclusion In summary, we have shown how to set up and validate approximate and exact LOO-CV for non-factorized multivariate normal models using Stan with the **brms** and **loo** packages. Although we focused on the particular example of a spatial SAR model, the presented recipe applies more generally to models that can be expressed in terms of a multivariate normal likelihood.
# References Anselin L. (1988). *Spatial econometrics: methods and models*. Dordrecht: Kluwer Academic. Bürkner P. C., Gabry J., & Vehtari A. (2020). Efficient leave-one-out cross-validation for Bayesian non-factorized normal and Student-t models. *Computational Statistics*, \doi:10.1007/s00180-020-01045-4. [ArXiv preprint](https://arxiv.org/abs/1810.10559). Sundararajan S. & Keerthi S. S. (2001). Predictive approaches for choosing hyperparameters in Gaussian processes. *Neural Computation*, 13(5), 1103--1118. Vehtari A., Mononen T., Tolvanen V., Sivula T., & Winther O. (2016). Bayesian leave-one-out cross-validation approximations for Gaussian latent variable models. *Journal of Machine Learning Research*, 17(103), 1--38. [Online](https://jmlr.org/papers/v17/14-540.html). Vehtari A., Gelman A., & Gabry J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. *Statistics and Computing*, 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. [Online](https://link.springer.com/article/10.1007/s11222-016-9696-4). [arXiv preprint arXiv:1507.04544](https://arxiv.org/abs/1507.04544). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.02646](https://arxiv.org/abs/1507.02646). loo/vignettes/loo2-mixis.Rmd0000644000176200001440000002204314407123455015527 0ustar liggesusers--- title: "Mixture IS leave-one-out cross-validation for high-dimensional Bayesian models" author: "Luca Silva and Giacomo Zanella" date: "`r Sys.Date()`" output: html_vignette: toc: yes params: EVAL: !r identical(Sys.getenv("NOT_CRAN"), "true") --- ```{r, child="children/SETTINGS-knitr.txt"} ``` ```{r, child="children/SEE-ONLINE.txt", eval = if (isTRUE(exists("params"))) !params$EVAL else TRUE} ``` # Introduction This vignette shows how to perform Bayesian leave-one-out cross-validation (LOO-CV) using the mixture estimators proposed in the paper [Silva and Zanella (2022)](https://arxiv.org/abs/2209.09190). These estimators have shown to be useful in presence of outliers but also, and especially, in high-dimensional settings where the model features many parameters. In these contexts it can happen that a large portion of observations lead to high values of Pareto-$k$ diagnostics and potential instability of PSIS-LOO estimators. For this illustration we consider a high-dimensional Bayesian Logistic regression model applied to the _Voice_ dataset. ## Setup: load packages and set seed ```{r, warnings=FALSE, message=FALSE} library("rstan") library("loo") library("matrixStats") options(mc.cores = parallel::detectCores(), parallel=FALSE) set.seed(24877) ``` ## Model This is the Stan code for a logistic regression model with regularized horseshoe prior. The code includes an if statement to include a code line needed later for the MixIS approach. ```{r stancode_horseshoe} stancode_horseshoe <- " data { int n; int p; int y[n]; matrix [n,p] X; real scale_global; int mixis; } transformed data { real nu_global=1; // degrees of freedom for the half-t priors for tau real nu_local=1; // degrees of freedom for the half-t priors for lambdas // (nu_local = 1 corresponds to the horseshoe) real slab_scale=2;// for the regularized horseshoe real slab_df=100; // for the regularized horseshoe } parameters { vector[p] z; // for non-centered parameterization real tau; // global shrinkage parameter vector [p] lambda; // local shrinkage parameter real caux; } transformed parameters { vector[p] beta; { vector[p] lambda_tilde; // 'truncated' local shrinkage parameter real c = slab_scale * sqrt(caux); // slab scale lambda_tilde = sqrt( c^2 * square(lambda) ./ (c^2 + tau^2*square(lambda))); beta = z .* lambda_tilde*tau; } } model { vector[n] means=X*beta; vector[n] log_lik; target += std_normal_lpdf(z); target += student_t_lpdf(lambda | nu_local, 0, 1); target += student_t_lpdf(tau | nu_global, 0, scale_global); target += inv_gamma_lpdf(caux | 0.5*slab_df, 0.5*slab_df); for (index in 1:n) { log_lik[index]= bernoulli_logit_lpmf(y[index] | means[index]); } target += sum(log_lik); if (mixis) { target += log_sum_exp(-log_lik); } } generated quantities { vector[n] means=X*beta; vector[n] log_lik; for (index in 1:n) { log_lik[index] = bernoulli_logit_lpmf(y[index] | means[index]); } } " ``` ## Dataset The _LSVT Voice Rehabilitation Data Set_ (see [link](https://archive.ics.uci.edu/ml/datasets/LSVT+Voice+Rehabilitation) for details) has $p=312$ covariates and $n=126$ observations with binary response. We construct data list for Stan. ```{r, results='hide', warning=FALSE, message=FALSE, error=FALSE} data(voice) y <- voice$y X <- voice[2:length(voice)] n <- dim(X)[1] p <- dim(X)[2] p0 <- 10 scale_global <- 2*p0/(p-p0)/sqrt(n-1) standata <- list(n = n, p = p, X = as.matrix(X), y = c(y), scale_global = scale_global, mixis = 0) ``` Note that in our prior specification we divide the prior variance by the number of covariates $p$. This is often done in high-dimensional contexts to have a prior variance for the linear predictors $X\beta$ that remains bounded as $p$ increases. ## PSIS estimators and Pareto-$k$ diagnostics LOO-CV computations are challenging in this context due to high-dimensionality of the parameter space. To show that, we compute PSIS-LOO estimators, which require sampling from the posterior distribution, and inspect the associated Pareto-$k$ diagnostics. ```{r, results='hide', warning=FALSE} chains <- 4 n_iter <- 2000 warm_iter <- 1000 stanmodel <- stan_model(model_code = stancode_horseshoe) fit_post <- sampling(stanmodel, data = standata, chains = chains, iter = n_iter, warmup = warm_iter, refresh = 0) loo_post <-loo(fit_post) ``` ```{r} print(loo_post) ``` As we can see the diagnostics signal either "bad" or "very bad" Pareto-$k$ values for roughly $15-30\%$ of the observations which is a significant portion of the dataset. ## Mixture estimators We now compute the mixture estimators proposed in Silva and Zanella (2022). These require to sample from the following mixture of leave-one-out posteriors \begin{equation} q_{mix}(\theta) = \frac{\sum_{i=1}^n p(y_{-i}|\theta)p(\theta)}{\sum_{i=1}^np(y_{-i})}\propto p(\theta|y)\cdot \left(\sum_{i=1}^np(y_i|\theta)^{-1}\right). \end{equation} The code to generate a Stan model for the above mixture distribution is the same to the one for the posterior, just enabling one line of code with a _LogSumExp_ contribution to account for the last term in the equation above. ``` if (mixis) { target += log_sum_exp(-log_lik); } ``` We sample from the mixture and collect the log-likelihoods term. ```{r, results='hide', warnings=FALSE} standata$mixis <- 1 fit_mix <- sampling(stanmodel, data = standata, chains = chains, iter = n_iter, warmup = warm_iter, refresh = 0, pars = "log_lik") log_lik_mix <- extract(fit_mix)$log_lik ``` We now compute the mixture estimators, following the numerically stable implementation in Appendix A.2 of [Silva and Zanella (2022)](https://arxiv.org/abs/2209.09190). The code below makes use of the package "matrixStats". ```{r} l_common_mix <- rowLogSumExps(-log_lik_mix) log_weights <- -log_lik_mix - l_common_mix elpd_mixis <- logSumExp(-l_common_mix) - rowLogSumExps(t(log_weights)) ``` ## Comparison with benchmark values obtained with long simulations To evaluate the performance of mixture estimators (MixIS) we also generate _benchmark values_, i.e.\ accurate approximations of the LOO predictives $\{p(y_i|y_{-i})\}_{i=1,\dots,n}$, obtained by brute-force sampling from the leave-one-out posteriors directly, getting $90k$ samples from each and discarding the first $10k$ as warmup. This is computationally heavy, hence we have saved the results and we just load them in the current vignette. ```{r} data(voice_loo) elpd_loo <- voice_loo$elpd_loo ``` We can then compute the root mean squared error (RMSE) of the PSIS and mixture estimators relative to such benchmark values. ```{r} elpd_psis <- loo_post$pointwise[,1] print(paste("RMSE(PSIS) =",round( sqrt(mean((elpd_loo-elpd_psis)^2)) ,2))) print(paste("RMSE(MixIS) =",round( sqrt(mean((elpd_loo-elpd_mixis)^2)) ,2))) ``` Here mixture estimator provides a reduction in RMSE. Note that this value would increase with the number of samples drawn from the posterior and mixture, since in this example the RMSE of MixIS will exhibit a CLT-type decay while the one of PSIS will converge at a slower rate (this can be verified by running the above code with a larger sample size; see also Figure 3 of Silva and Zanella (2022) for analogous results). We then compare the overall ELPD estimates with the brute force one. ```{r} elpd_psis <- loo_post$pointwise[,1] print(paste("ELPD (PSIS)=",round(sum(elpd_psis),2))) print(paste("ELPD (MixIS)=",round(sum(elpd_mixis),2))) print(paste("ELPD (brute force)=",round(sum(elpd_loo),2))) ``` In this example, MixIS provides a more accurate ELPD estimate closer to the brute force estimate, while PSIS severely overestimates the ELPD. Note that low accuracy of the PSIS ELPD estimate is expected in this example given the large number of large Pareto-$k$ values. In this example, the accuracy of MixIS estimate will also improve with bigger MCMC sample size. More generally, mixture estimators can be useful in situations where standard PSIS estimators struggle and return many large Pareto-$k$ values. In these contexts MixIS often provides more accurate LOO-CV and ELPD estimates with a single sampling routine (i.e. with a cost comparable to sampling from the original posterior). ## References Silva L. and Zanella G. (2022). Robust leave-one-out cross-validation for high-dimensional Bayesian models. Preprint at [arXiv:2209.09190](https://arxiv.org/abs/2209.09190) Vehtari A., Gelman A., and Gabry J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. *Statistics and Computing*, 27(5), 1413--1432. Preprint at [arXiv:1507.04544](https://arxiv.org/abs/1507.04544) Vehtari A., Simpson D., Gelman A., Yao Y., and Gabry J. (2022). Pareto smoothed importance sampling. Preprint at [arXiv:1507.02646](https://arxiv.org/abs/1507.02646) loo/vignettes/loo2-large-data.Rmd0000644000176200001440000005036613764522153016413 0ustar liggesusers--- title: "Using Leave-one-out cross-validation for large data" author: "Mans Magnusson, Paul Bürkner, Aki Vehtari and Jonah Gabry" date: "`r Sys.Date()`" output: html_vignette: toc: yes params: EVAL: !r identical(Sys.getenv("NOT_CRAN"), "true") --- ```{r settings, child="children/SETTINGS-knitr.txt"} ``` ```{r, child="children/SEE-ONLINE.txt", eval = if (isTRUE(exists("params"))) !params$EVAL else TRUE} ``` # Introduction This vignette demonstrates how to do leave-one-out cross-validation for large data using the __loo__ package and Stan. There are two approaches covered: LOO with subsampling and LOO using approximations to posterior distributions. Some sections from this vignette are excerpted from the papers * Magnusson, M., Riis Andersen, M., Jonasson, J. and Vehtari, A. (2020). Leave-One-Out Cross-Validation for Model Comparison in Large Data. Proceedings of the 23rd International Conference on Artificial Intelligence and Statistics (AISTATS), in PMLR 108. [arXiv preprint arXiv:2001.00980](https://arxiv.org/abs/2001.00980). * Magnusson, M., Andersen, M., Jonasson, J. & Vehtari, A. (2019). Bayesian leave-one-out cross-validation for large data. Proceedings of the 36th International Conference on Machine Learning, in PMLR 97:4244-4253 [online](http://proceedings.mlr.press/v97/magnusson19a.html), [arXiv preprint arXiv:1904.10679](https://arxiv.org/abs/1904.10679). * Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. _Statistics and Computing_. 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. Links: [published](https://link.springer.com/article/10.1007/s11222-016-9696-4) | [arXiv preprint](https://arxiv.org/abs/1507.04544). * Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.04544](https://arxiv.org/abs/1507.04544). which provide important background for understanding the methods implemented in the package. # Setup In addition to the __loo__ package, we'll also be using __rstan__: ```{r setup, message=FALSE} library("rstan") library("loo") set.seed(4711) ``` # Example: Well water in Bangladesh We will use the same example as in the vignette [_Writing Stan programs for use with the loo package_](http://mc-stan.org/loo/articles/loo2-with-rstan.html). See that vignette for a description of the problem and data. The sample size in this example is only $N=3020$, which is not large enough to _require_ the special methods for large data described in this vignette, but is sufficient for demonstration purposes in this tutorial. ## Coding the Stan model Here is the Stan code for fitting the logistic regression model, which we save in a file called `logistic.stan`: ``` // save in `logistic.stan` data { int N; // number of data points int P; // number of predictors (including intercept) matrix[N,P] X; // predictors (including 1s for intercept) int y[N]; // binary outcome } parameters { vector[P] beta; } model { beta ~ normal(0, 1); y ~ bernoulli_logit(X * beta); } ``` Importantly, unlike the general approach recommended in [_Writing Stan programs for use with the loo package_](http://mc-stan.org/loo/articles/loo2-with-rstan.html), we do _not_ compute the log-likelihood for each observation in the `generated quantities` block of the Stan program. Here we are assuming we have a large data set (larger than the one we're actually using in this demonstration) and so it is preferable to instead define a function in R to compute the log-likelihood for each data point when needed rather than storing all of the log-likelihood values in memory. The log-likelihood in R can be coded as follows: ```{r llfun_logistic} # we'll add an argument log to toggle whether this is a log-likelihood or # likelihood function. this will be useful later in the vignette. llfun_logistic <- function(data_i, draws, log = TRUE) { x_i <- as.matrix(data_i[, which(grepl(colnames(data_i), pattern = "X")), drop=FALSE]) logit_pred <- draws %*% t(x_i) dbinom(x = data_i$y, size = 1, prob = 1/(1 + exp(-logit_pred)), log = log) } ``` The function `llfun_logistic()` needs to have arguments `data_i` and `draws`. Below we will test that the function is working by using the `loo_i()` function. ## Fitting the model with RStan Next we fit the model in Stan using the **rstan** package: ```{r, eval=FALSE} # Prepare data url <- "http://stat.columbia.edu/~gelman/arm/examples/arsenic/wells.dat" wells <- read.table(url) wells$dist100 <- with(wells, dist / 100) X <- model.matrix(~ dist100 + arsenic, wells) standata <- list(y = wells$switch, X = X, N = nrow(X), P = ncol(X)) # Compile stan_mod <- stan_model("logistic.stan") # Fit model fit_1 <- sampling(stan_mod, data = standata, seed = 4711) print(fit_1, pars = "beta") ``` ``` mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat beta[1] 0.00 0 0.08 -0.15 -0.05 0.00 0.06 0.16 1933 1 beta[2] -0.89 0 0.10 -1.09 -0.96 -0.89 -0.82 -0.69 2332 1 beta[3] 0.46 0 0.04 0.38 0.43 0.46 0.49 0.54 2051 1 ``` Before we move on to computing LOO we can now test that the log-likelihood function we wrote is working as it should. The `loo_i()` function is a helper function that can be used to test a log-likelihood function on a single observation. ```{r, eval=FALSE} # used for draws argument to loo_i parameter_draws_1 <- extract(fit_1)$beta # used for data argument to loo_i stan_df_1 <- as.data.frame(standata) # compute relative efficiency (this is slow and optional but is recommended to allow # for adjusting PSIS effective sample size based on MCMC effective sample size) r_eff <- relative_eff(llfun_logistic, log = FALSE, # relative_eff wants likelihood not log-likelihood values chain_id = rep(1:4, each = 1000), data = stan_df_1, draws = parameter_draws_1, cores = 2) loo_i(i = 1, llfun_logistic, r_eff = r_eff, data = stan_df_1, draws = parameter_draws_1) ``` ``` $pointwise elpd_loo mcse_elpd_loo p_loo looic influence_pareto_k 1 -0.3314552 0.0002887608 0.0003361772 0.6629103 -0.05679886 ... ``` # Approximate LOO-CV using PSIS-LOO and subsampling We can then use the `loo_subsample()` function to compute the efficient PSIS-LOO approximation to exact LOO-CV using subsampling: ```{r, eval=FALSE} set.seed(4711) loo_ss_1 <- loo_subsample( llfun_logistic, observations = 100, # take a subsample of size 100 cores = 2, # these next objects were computed above r_eff = r_eff, draws = parameter_draws_1, data = stan_df_1 ) print(loo_ss_1) ``` ``` Computed from 4000 by 100 subsampled log-likelihood values from 3020 total observations. Estimate SE subsampling SE elpd_loo -1968.5 15.6 0.3 p_loo 3.1 0.1 0.4 looic 3936.9 31.2 0.6 ------ Monte Carlo SE of elpd_loo is 0.0. All Pareto k estimates are good (k < 0.5). See help('pareto-k-diagnostic') for details. ``` The `loo_subsample()` function creates an object of class `psis_loo_ss`, that inherits from `psis_loo, loo` (the classes of regular `loo` objects). The printed output above shows the estimates $\widehat{\mbox{elpd}}_{\rm loo}$ (expected log predictive density), $\widehat{p}_{\rm loo}$ (effective number of parameters), and ${\rm looic} =-2\, \widehat{\mbox{elpd}}_{\rm loo}$ (the LOO information criterion). Unlike when using `loo()`, when using `loo_subsample()` there is an additional column giving the "subsampling SE", which reflects the additional uncertainty due to the subsampling used. The line at the bottom of the printed output provides information about the reliability of the LOO approximation (the interpretation of the $k$ parameter is explained in `help('pareto-k-diagnostic')` and in greater detail in Vehtari, Simpson, Gelman, Yao, and Gabry (2019)). In this case, the message tells us that all of the estimates for $k$ are fine _for this given subsample_. ## Adding additional subsamples If we are not satisfied with the subsample size (i.e., the accuracy) we can simply add more samples until we are satisfied using the `update()` method. ```{r, eval=FALSE} set.seed(4711) loo_ss_1b <- update( loo_ss_1, observations = 200, # subsample 200 instead of 100 r_eff = r_eff, draws = parameter_draws_1, data = stan_df_1 ) print(loo_ss_1b) ``` ``` Computed from 4000 by 200 subsampled log-likelihood values from 3020 total observations. Estimate SE subsampling SE elpd_loo -1968.3 15.6 0.2 p_loo 3.2 0.1 0.4 looic 3936.7 31.2 0.5 ------ Monte Carlo SE of elpd_loo is 0.0. All Pareto k estimates are good (k < 0.5). See help('pareto-k-diagnostic') for details. ``` ## Specifying estimator and sampling method The performance relies on two components: the estimation method and the approximation used for the elpd. See the documentation for `loo_subsample()` more information on which estimators and approximations are implemented. The default implementation is using the point log predictive density evaluated at the mean of the posterior (`loo_approximation="plpd"`) and the difference estimator (`estimator="diff_srs"`). This combination has a focus on fast inference. But we can easily use other estimators as well as other elpd approximations, for example: ```{r, eval=FALSE} set.seed(4711) loo_ss_1c <- loo_subsample( x = llfun_logistic, r_eff = r_eff, draws = parameter_draws_1, data = stan_df_1, observations = 100, estimator = "hh_pps", # use Hansen-Hurwitz loo_approximation = "lpd", # use lpd instead of plpd loo_approximation_draws = 100, cores = 2 ) print(loo_ss_1c) ``` ``` Computed from 4000 by 100 subsampled log-likelihood values from 3020 total observations. Estimate SE subsampling SE elpd_loo -1968.9 15.4 0.5 p_loo 3.5 0.2 0.5 looic 3937.9 30.7 1.1 ------ Monte Carlo SE of elpd_loo is 0.0. All Pareto k estimates are good (k < 0.5). See help('pareto-k-diagnostic') for details. ``` See the documentation and references for `loo_subsample()` for details on the implemented approximations. # Approximate LOO-CV using PSIS-LOO with posterior approximations Using posterior approximations, such as variational inference and Laplace approximations, can further speed-up LOO-CV for large data. Here we demonstrate using a Laplace approximation in Stan. ```{r, eval=FALSE} fit_laplace <- optimizing(stan_mod, data = standata, draws = 2000, importance_resampling = TRUE) parameter_draws_laplace <- fit_laplace$theta_tilde # draws from approximate posterior log_p <- fit_laplace$log_p # log density of the posterior log_g <- fit_laplace$log_g # log density of the approximation ``` Using the posterior approximation we can then do LOO-CV by correcting for the posterior approximation when we compute the elpd. To do this we use the `loo_approximate_posterior()` function. ```{r, eval=FALSE} set.seed(4711) loo_ap_1 <- loo_approximate_posterior( x = llfun_logistic, draws = parameter_draws_laplace, data = stan_df_1, log_p = log_p, log_g = log_g, cores = 2 ) print(loo_ap_1) ``` The function creates a class, `psis_loo_ap` that inherits from `psis_loo, loo`. ``` Computed from 2000 by 3020 log-likelihood matrix Estimate SE elpd_loo -1968.4 15.6 p_loo 3.2 0.2 looic 3936.8 31.2 ------ Posterior approximation correction used. Monte Carlo SE of elpd_loo is 0.0. Pareto k diagnostic values: Count Pct. Min. n_eff (-Inf, 0.5] (good) 2989 99.0% 1827 (0.5, 0.7] (ok) 31 1.0% 1996 (0.7, 1] (bad) 0 0.0% (1, Inf) (very bad) 0 0.0% All Pareto k estimates are ok (k < 0.7). See help('pareto-k-diagnostic') for details. ``` ## Combining the posterior approximation method with subsampling The posterior approximation correction can also be used together with subsampling: ```{r, eval=FALSE} set.seed(4711) loo_ap_ss_1 <- loo_subsample( x = llfun_logistic, draws = parameter_draws_laplace, data = stan_df_1, log_p = log_p, log_g = log_g, observations = 100, cores = 2 ) print(loo_ap_ss_1) ``` ``` Computed from 2000 by 100 subsampled log-likelihood values from 3020 total observations. Estimate SE subsampling SE elpd_loo -1968.2 15.6 0.4 p_loo 2.9 0.1 0.5 looic 3936.4 31.1 0.8 ------ Posterior approximation correction used. Monte Carlo SE of elpd_loo is 0.0. Pareto k diagnostic values: Count Pct. Min. n_eff (-Inf, 0.5] (good) 97 97.0% 1971 (0.5, 0.7] (ok) 3 3.0% 1997 (0.7, 1] (bad) 0 0.0% (1, Inf) (very bad) 0 0.0% All Pareto k estimates are ok (k < 0.7). See help('pareto-k-diagnostic') for details. ``` The object created is of class `psis_loo_ss`, which inherits from the `psis_loo_ap` class previously described. ## Comparing models To compare this model to an alternative model for the same data we can use the `loo_compare()` function just as we would if using `loo()` instead of `loo_subsample()` or `loo_approximate_posterior()`. First we'll fit a second model to the well-switching data, using `log(arsenic)` instead of `arsenic` as a predictor: ```{r, eval=FALSE} standata$X[, "arsenic"] <- log(standata$X[, "arsenic"]) fit_2 <- sampling(stan_mod, data = standata) parameter_draws_2 <- extract(fit_2)$beta stan_df_2 <- as.data.frame(standata) # recompute subsampling loo for first model for demonstration purposes # compute relative efficiency (this is slow and optional but is recommended to allow # for adjusting PSIS effective sample size based on MCMC effective sample size) r_eff_1 <- relative_eff( llfun_logistic, log = FALSE, # relative_eff wants likelihood not log-likelihood values chain_id = rep(1:4, each = 1000), data = stan_df_1, draws = parameter_draws_1, cores = 2 ) set.seed(4711) loo_ss_1 <- loo_subsample( x = llfun_logistic, r_eff = r_eff_1, draws = parameter_draws_1, data = stan_df_1, observations = 200, cores = 2 ) # compute subsampling loo for a second model (with log-arsenic) r_eff_2 <- relative_eff( llfun_logistic, log = FALSE, # relative_eff wants likelihood not log-likelihood values chain_id = rep(1:4, each = 1000), data = stan_df_2, draws = parameter_draws_2, cores = 2 ) loo_ss_2 <- loo_subsample( x = llfun_logistic, r_eff = r_eff_2, draws = parameter_draws_2, data = stan_df_2, observations = 200, cores = 2 ) print(loo_ss_2) ``` ``` Computed from 4000 by 100 subsampled log-likelihood values from 3020 total observations. Estimate SE subsampling SE elpd_loo -1952.0 16.2 0.2 p_loo 2.6 0.1 0.3 looic 3903.9 32.4 0.4 ------ Monte Carlo SE of elpd_loo is 0.0. All Pareto k estimates are good (k < 0.5). See help('pareto-k-diagnostic') for details. ``` We can now compare the models on LOO using the `loo_compare` function: ```{r, eval=FALSE} # Compare comp <- loo_compare(loo_ss_1, loo_ss_2) print(comp) ``` ``` Warning: Different subsamples in 'model2' and 'model1'. Naive diff SE is used. elpd_diff se_diff subsampling_se_diff model2 0.0 0.0 0.0 model1 16.5 22.5 0.4 ``` This new object `comp` contains the estimated difference of expected leave-one-out prediction errors between the two models, along with the standard error. As the warning indicates, because different subsamples were used the comparison will not take the correlations between different observations into account. Here we see that the naive SE is 22.5 and we cannot see any difference in performance between the models. To force subsampling to use the same observations for each of the models we can simply extract the observations used in `loo_ss_1` and use them in `loo_ss_2` by supplying the `loo_ss_1` object to the `observations` argument. ```{r, eval=FALSE} loo_ss_2 <- loo_subsample( x = llfun_logistic, r_eff = r_eff_2, draws = parameter_draws_2, data = stan_df_2, observations = loo_ss_1, cores = 2 ) ``` We could also supply the subsampling indices using the `obs_idx()` helper function: ```{r, eval=FALSE} idx <- obs_idx(loo_ss_1) loo_ss_2 <- loo_subsample( x = llfun_logistic, r_eff = r_eff_2, draws = parameter_draws_2, data = stan_df_2, observations = idx, cores = 2 ) ``` ``` Simple random sampling with replacement assumed. ``` This results in a message indicating that we assume these observations to have been sampled with simple random sampling, which is true because we had used the default `"diff_srs"` estimator for `loo_ss_1`. We can now compare the models and estimate the difference based on the same subsampled observations. ```{r, eval=FALSE} comp <- loo_compare(loo_ss_1, loo_ss_2) print(comp) ``` ``` elpd_diff se_diff subsampling_se_diff model2 0.0 0.0 0.0 model1 16.1 4.4 0.1 ``` First, notice that now the `se_diff` is now around 4 (as opposed to 20 when using different subsamples). The first column shows the difference in ELPD relative to the model with the largest ELPD. In this case, the difference in `elpd` and its scale relative to the approximate standard error of the difference) indicates a preference for the second model (`model2`). Since the subsampling uncertainty is so small in this case it can effectively be ignored. If we need larger subsamples we can simply add samples using the `update()` method demonstrated earlier. It is also possible to compare a subsampled loo computation with a full loo object. ```{r, eval=FALSE} # use loo() instead of loo_subsample() to compute full PSIS-LOO for model 2 loo_full_2 <- loo( x = llfun_logistic, r_eff = r_eff_2, draws = parameter_draws_2, data = stan_df_2, cores = 2 ) loo_compare(loo_ss_1, loo_full_2) ``` ``` Estimated elpd_diff using observations included in loo calculations for all models. ``` Because we are comparing a non-subsampled loo calculation to a subsampled calculation we get the message that only the observations that are included in the loo calculations for both `model1` and `model2` are included in the computations for the comparison. ``` elpd_diff se_diff subsampling_se_diff model2 0.0 0.0 0.0 model1 16.3 4.4 0.3 ``` Here we actually see an increase in `subsampling_se_diff`, but this is due to a technical detail not elaborated here. In general, the difference should be better or negligible. # References Gelman, A., and Hill, J. (2007). *Data Analysis Using Regression and Multilevel Hierarchical Models.* Cambridge University Press. Stan Development Team (2017). _The Stan C++ Library, Version 2.17.0._ https://mc-stan.org/ Stan Development Team (2018) _RStan: the R interface to Stan, Version 2.17.3._ https://mc-stan.org/ Magnusson, M., Riis Andersen, M., Jonasson, J. and Vehtari, A. (2020). Leave-One-Out Cross-Validation for Model Comparison in Large Data. Proceedings of the 23rd International Conference on Artificial Intelligence and Statistics (AISTATS), in PMLR 108. [arXiv preprint arXiv:2001.00980](https://arxiv.org/abs/2001.00980). Magnusson, M., Andersen, M., Jonasson, J. & Vehtari, A. (2019). Bayesian leave-one-out cross-validation for large data. Proceedings of the 36th International Conference on Machine Learning, in PMLR 97:4244-4253 [online](http://proceedings.mlr.press/v97/magnusson19a.html), [arXiv preprint arXiv:1904.10679](https://arxiv.org/abs/1904.10679). Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. _Statistics and Computing_. 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. [online](https://link.springer.com/article/10.1007/s11222-016-9696-4), [arXiv preprint arXiv:1507.04544](https://arxiv.org/abs/1507.04544). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.02646](https://arxiv.org/abs/1507.02646). loo/vignettes/children/0000755000176200001440000000000013761524476014662 5ustar liggesusersloo/vignettes/children/SETTINGS-knitr.txt0000644000176200001440000000041613703433563020001 0ustar liggesusers```{r SETTINGS-knitr, include=FALSE} stopifnot(require(knitr)) opts_chunk$set( comment=NA, eval = if (isTRUE(exists("params"))) params$EVAL else FALSE, dev = "png", dpi = 150, fig.asp = 0.618, fig.width = 5, out.width = "60%", fig.align = "center" ) ``` loo/vignettes/children/SEE-ONLINE.txt0000644000176200001440000000016713761524476017025 0ustar liggesusers**NOTE: We recommend viewing the fully rendered version of this vignette online at https://mc-stan.org/loo/articles/** loo/vignettes/loo2-elpd.Rmd0000644000176200001440000001723514407123455015331 0ustar liggesusers--- title: "Holdout validation and K-fold cross-validation of Stan programs with the loo package" author: "Bruno Nicenboim" date: "`r Sys.Date()`" output: html_vignette: toc: yes params: EVAL: !r identical(Sys.getenv("NOT_CRAN"), "true") --- ```{r, child="children/SETTINGS-knitr.txt"} ``` ```{r, child="children/SEE-ONLINE.txt", eval = if (isTRUE(exists("params"))) !params$EVAL else TRUE} ``` # Introduction This vignette demonstrates how to do holdout validation and K-fold cross-validation with __loo__ for a Stan program. # Example: Eradication of Roaches using holdout validation approach This vignette uses the same example as in the vignettes [_Using the loo package (version >= 2.0.0)_](http://mc-stan.org/loo/articles/loo2-example.html) and [_Avoiding model refits in leave-one-out cross-validation with moment matching_](https://mc-stan.org/loo/articles/loo2-moment-matching.html). ## Coding the Stan model Here is the Stan code for fitting a Poisson regression model: ```{r stancode} stancode <- " data { int K; int N; matrix[N,K] x; int y[N]; vector[N] offset; real beta_prior_scale; real alpha_prior_scale; } parameters { vector[K] beta; real intercept; } model { y ~ poisson(exp(x * beta + intercept + offset)); beta ~ normal(0,beta_prior_scale); intercept ~ normal(0,alpha_prior_scale); } generated quantities { vector[N] log_lik; for (n in 1:N) log_lik[n] = poisson_lpmf(y[n] | exp(x[n] * beta + intercept + offset[n])); } " ``` Following the usual approach recommended in [_Writing Stan programs for use with the loo package_](http://mc-stan.org/loo/articles/loo2-with-rstan.html), we compute the log-likelihood for each observation in the `generated quantities` block of the Stan program. ## Setup In addition to __loo__, we load the __rstan__ package for fitting the model. We will also need the __rstanarm__ package for the data. ```{r setup, message=FALSE} library("rstan") library("loo") seed <- 9547 set.seed(seed) ``` # Holdout validation For this approach, the model is first fit to the "train" data and then is evaluated on the held-out "test" data. ## Splitting the data between train and test The data is divided between train (80% of the data) and test (20%): ```{r modelfit-holdout, message=FALSE} # Prepare data data(roaches, package = "rstanarm") roaches$roach1 <- sqrt(roaches$roach1) roaches$offset <- log(roaches[,"exposure2"]) # 20% of the data goes to the test set: roaches$test <- 0 roaches$test[sample(.2 * seq_len(nrow(roaches)))] <- 1 # data to "train" the model data_train <- list(y = roaches$y[roaches$test == 0], x = as.matrix(roaches[roaches$test == 0, c("roach1", "treatment", "senior")]), N = nrow(roaches[roaches$test == 0,]), K = 3, offset = roaches$offset[roaches$test == 0], beta_prior_scale = 2.5, alpha_prior_scale = 5.0 ) # data to "test" the model data_test <- list(y = roaches$y[roaches$test == 1], x = as.matrix(roaches[roaches$test == 1, c("roach1", "treatment", "senior")]), N = nrow(roaches[roaches$test == 1,]), K = 3, offset = roaches$offset[roaches$test == 1], beta_prior_scale = 2.5, alpha_prior_scale = 5.0 ) ``` ## Fitting the model with RStan Next we fit the model to the "test" data in Stan using the __rstan__ package: ```{r fit-train} # Compile stanmodel <- stan_model(model_code = stancode) # Fit model fit <- sampling(stanmodel, data = data_train, seed = seed, refresh = 0) ``` We recompute the generated quantities using the posterior draws conditional on the training data, but we now pass in the held-out data to get the log predictive densities for the test data. Because we are using independent data, the log predictive density coincides with the log likelihood of the test data. ```{r gen-test} gen_test <- gqs(stanmodel, draws = as.matrix(fit), data= data_test) log_pd <- extract_log_lik(gen_test) ``` ## Computing holdout elpd: Now we evaluate the predictive performance of the model on the test data using `elpd()`. ```{r elpd-holdout} (elpd_holdout <- elpd(log_pd)) ``` When one wants to compare different models, the function `loo_compare()` can be used to assess the difference in performance. # K-fold cross validation For this approach the data is divided into folds, and each time one fold is tested while the rest of the data is used to fit the model (see Vehtari et al., 2017). ## Splitting the data in folds We use the data that is already pre-processed and we divide it in 10 random folds using `kfold_split_random` ```{r prepare-folds, message=FALSE} # Prepare data roaches$fold <- kfold_split_random(K = 10, N = nrow(roaches)) ``` ## Fitting and extracting the log pointwise predictive densities for each fold We now loop over the 10 folds. In each fold we do the following. First, we fit the model to all the observations except the ones belonging to the left-out fold. Second, we compute the log pointwise predictive densities for the left-out fold. Last, we store the predictive density for the observations of the left-out fold in a matrix. The output of this loop is a matrix of the log pointwise predictive densities of all the observations. ```{r} # Prepare a matrix with the number of post-warmup iterations by number of observations: log_pd_kfold <- matrix(nrow = 4000, ncol = nrow(roaches)) # Loop over the folds for(k in 1:10){ data_train <- list(y = roaches$y[roaches$fold != k], x = as.matrix(roaches[roaches$fold != k, c("roach1", "treatment", "senior")]), N = nrow(roaches[roaches$fold != k,]), K = 3, offset = roaches$offset[roaches$fold != k], beta_prior_scale = 2.5, alpha_prior_scale = 5.0 ) data_test <- list(y = roaches$y[roaches$fold == k], x = as.matrix(roaches[roaches$fold == k, c("roach1", "treatment", "senior")]), N = nrow(roaches[roaches$fold == k,]), K = 3, offset = roaches$offset[roaches$fold == k], beta_prior_scale = 2.5, alpha_prior_scale = 5.0 ) fit <- sampling(stanmodel, data = data_train, seed = seed, refresh = 0) gen_test <- gqs(stanmodel, draws = as.matrix(fit), data= data_test) log_pd_kfold[, roaches$fold == k] <- extract_log_lik(gen_test) } ``` ## Computing K-fold elpd: Now we evaluate the predictive performance of the model on the 10 folds using `elpd()`. ```{r elpd-kfold} (elpd_kfold <- elpd(log_pd_kfold)) ``` If one wants to compare several models (with `loo_compare`), one should use the same folds for all the different models. # References Gelman, A., and Hill, J. (2007). *Data Analysis Using Regression and Multilevel Hierarchical Models.* Cambridge University Press. Stan Development Team (2020) _RStan: the R interface to Stan, Version 2.21.1_ https://mc-stan.org Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. _Statistics and Computing_. 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. Links: [published](https://link.springer.com/article/10.1007/s11222-016-9696-4) | [arXiv preprint](https://arxiv.org/abs/1507.04544). loo/R/0000755000176200001440000000000014411465511011246 5ustar liggesusersloo/R/sis.R0000644000176200001440000001134113701164066012171 0ustar liggesusers#' Standard importance sampling (SIS) #' #' Implementation of standard importance sampling (SIS). #' #' @param log_ratios An array, matrix, or vector of importance ratios on the log #' scale (for Importance sampling LOO, these are *negative* log-likelihood #' values). See the **Methods (by class)** section below for a detailed #' description of how to specify the inputs for each method. #' @template cores #' @param ... Arguments passed on to the various methods. #' @param r_eff Vector of relative effective sample size estimates containing #' one element per observation. The values provided should be the relative #' effective sample sizes of `1/exp(log_ratios)` (i.e., `1/ratios`). #' This is related to the relative efficiency of estimating the normalizing #' term in self-normalizing importance sampling. See the [relative_eff()] #' helper function for computing `r_eff`. If using `psis` with #' draws of the `log_ratios` not obtained from MCMC then the warning #' message thrown when not specifying `r_eff` can be disabled by #' setting `r_eff` to `NA`. #' #' @return The `sis()` methods return an object of class `"sis"`, #' which is a named list with the following components: #' #' \describe{ #' \item{`log_weights`}{ #' Vector or matrix of smoothed but *unnormalized* log #' weights. To get normalized weights use the #' [`weights()`][weights.importance_sampling] method provided for objects of #' class `sis`. #' } #' \item{`diagnostics`}{ #' A named list containing one vector: #' * `pareto_k`: Not used in `sis`, all set to 0. #' * `n_eff`: effective sample size estimates. #' } #' } #' #' Objects of class `"sis"` also have the following [attributes][attributes()]: #' \describe{ #' \item{`norm_const_log`}{ #' Vector of precomputed values of `colLogSumExps(log_weights)` that are #' used internally by the `weights` method to normalize the log weights. #' } #' \item{`r_eff`}{ #' If specified, the user's `r_eff` argument. #' } #' \item{`tail_len`}{ #' Not used for `sis`. #' } #' \item{`dims`}{ #' Integer vector of length 2 containing `S` (posterior sample size) #' and `N` (number of observations). #' } #' \item{`method`}{ #' Method used for importance sampling, here `sis`. #' } #' } #' #' @seealso #' * [psis()] for approximate LOO-CV using PSIS. #' * [loo()] for approximate LOO-CV. #' * [pareto-k-diagnostic] for PSIS diagnostics. #' #' @template loo-and-psis-references #' #' @examples #' log_ratios <- -1 * example_loglik_array() #' r_eff <- relative_eff(exp(-log_ratios)) #' sis_result <- sis(log_ratios, r_eff = r_eff) #' str(sis_result) #' #' # extract smoothed weights #' lw <- weights(sis_result) # default args are log=TRUE, normalize=TRUE #' ulw <- weights(sis_result, normalize=FALSE) # unnormalized log-weights #' #' w <- weights(sis_result, log=FALSE) # normalized weights (not log-weights) #' uw <- weights(sis_result, log=FALSE, normalize = FALSE) # unnormalized weights #' #' @export sis <- function(log_ratios, ...) UseMethod("sis") #' @export #' @templateVar fn sis #' @template array #' sis.array <- function(log_ratios, ..., r_eff = NULL, cores = getOption("mc.cores", 1)) { importance_sampling.array(log_ratios = log_ratios, ..., r_eff = r_eff, cores = cores, method = "sis") } #' @export #' @templateVar fn sis #' @template matrix #' sis.matrix <- function(log_ratios, ..., r_eff = NULL, cores = getOption("mc.cores", 1)) { importance_sampling.matrix(log_ratios, ..., r_eff = r_eff, cores = cores, method = "sis") } #' @export #' @templateVar fn sis #' @template vector #' sis.default <- function(log_ratios, ..., r_eff = NULL) { importance_sampling.default(log_ratios = log_ratios, ..., r_eff = r_eff, method = "sis") } #' @rdname psis #' @export is.sis <- function(x) { inherits(x, "sis") && is.list(x) } # internal ---------------------------------------------------------------- #' Standard IS on a single vector #' #' @noRd #' @param log_ratios_i A vector of log importance ratios (for `loo()`, negative #' log likelihoods). #' @param ... Not used. Included to conform to PSIS API. #' #' @details Implementation standard importance sampling. #' @return A named list containing: #' * `lw`: vector of unnormalized log weights #' * `pareto_k`: scalar Pareto k estimate. For IS, this defaults to 0. do_sis_i <- function(log_ratios_i, ...) { S <- length(log_ratios_i) list(log_weights = log_ratios_i, pareto_k = 0) } loo/R/loo_moment_matching.R0000644000176200001440000005527114407123455015430 0ustar liggesusers#' Moment matching for efficient approximate leave-one-out cross-validation (LOO) #' #' Moment matching algorithm for updating a loo object when Pareto k estimates #' are large. #' #' @export loo_moment_match loo_moment_match.default #' @param x A fitted model object. #' @param loo A loo object to be modified. #' @param post_draws A function the takes `x` as the first argument and returns #' a matrix of posterior draws of the model parameters. #' @param log_lik_i A function that takes `x` and `i` and returns a matrix (one #' column per chain) or a vector (all chains stacked) of log-likelihood draws #' of the `i`th observation based on the model `x`. If the draws are obtained #' using MCMC, the matrix with MCMC chains separated is preferred. #' @param unconstrain_pars A function that takes arguments `x`, and `pars` and #' returns posterior draws on the unconstrained space based on the posterior #' draws on the constrained space passed via `pars`. #' @param log_prob_upars A function that takes arguments `x` and `upars` and #' returns a matrix of log-posterior density values of the unconstrained #' posterior draws passed via `upars`. #' @param log_lik_i_upars A function that takes arguments `x`, `upars`, and `i` #' and returns a vector of log-likelihood draws of the `i`th observation based #' on the unconstrained posterior draws passed via `upars`. #' @param max_iters Maximum number of moment matching iterations. Usually this #' does not need to be modified. If the maximum number of iterations is #' reached, there will be a warning, and increasing `max_iters` may improve #' accuracy. #' @param k_threshold Threshold value for Pareto k values above which the moment #' matching algorithm is used. The default value is 0.5. #' @param split Logical; Indicate whether to do the split transformation or not #' at the end of moment matching for each LOO fold. #' @param cov Logical; Indicate whether to match the covariance matrix of the #' samples or not. If `FALSE`, only the mean and marginal variances are #' matched. #' @template cores #' @param ... Further arguments passed to the custom functions documented above. #' #' @return The `loo_moment_match()` methods return an updated `loo` object. The #' structure of the updated `loo` object is similar, but the method also #' stores the original Pareto k diagnostic values in the diagnostics field. #' #' @details The `loo_moment_match()` function is an S3 generic and we provide a #' default method that takes as arguments user-specified functions #' `post_draws`, `log_lik_i`, `unconstrain_pars`, `log_prob_upars`, and #' `log_lik_i_upars`. All of these functions should take `...`. as an argument #' in addition to those specified for each function. #' #' @seealso [loo()], [loo_moment_match_split()] #' @template moment-matching-references #' #' @examples #' # See the vignette for loo_moment_match() #' @export loo_moment_match <- function(x, ...) { UseMethod("loo_moment_match") } #' @describeIn loo_moment_match A default method that takes as arguments a #' user-specified model object `x`, a `loo` object and user-specified #' functions `post_draws`, `log_lik_i`, `unconstrain_pars`, `log_prob_upars`, #' and `log_lik_i_upars`. #' @export loo_moment_match.default <- function(x, loo, post_draws, log_lik_i, unconstrain_pars, log_prob_upars, log_lik_i_upars, max_iters = 30L, k_threshold = 0.7, split = TRUE, cov = TRUE, cores = getOption("mc.cores", 1), ...) { # input checks checkmate::assertClass(loo,classes = "loo") checkmate::assertFunction(post_draws) checkmate::assertFunction(log_lik_i) checkmate::assertFunction(unconstrain_pars) checkmate::assertFunction(log_prob_upars) checkmate::assertFunction(log_lik_i_upars) checkmate::assertNumber(max_iters) checkmate::assertNumber(k_threshold) checkmate::assertLogical(split) checkmate::assertLogical(cov) checkmate::assertNumber(cores) if ("psis_loo" %in% class(loo)) { is_method <- "psis" } else { stop("loo_moment_match currently supports only the \"psis\" importance sampling class.") } S <- dim(loo)[1] N <- dim(loo)[2] pars <- post_draws(x, ...) # transform the model parameters to unconstrained space upars <- unconstrain_pars(x, pars = pars, ...) # number of parameters in the **parameters** block only npars <- dim(upars)[2] # if more parameters than samples, do not do Cholesky transformation cov <- cov && S >= 10 * npars # compute log-probabilities of the original parameter values orig_log_prob <- log_prob_upars(x, upars = upars, ...) # loop over all observations whose Pareto k is high ks <- loo$diagnostics$pareto_k kfs <- rep(0,N) I <- which(ks > k_threshold) loo_moment_match_i_fun <- function(i) { loo_moment_match_i(i = i, x = x, log_lik_i = log_lik_i, unconstrain_pars = unconstrain_pars, log_prob_upars = log_prob_upars, log_lik_i_upars = log_lik_i_upars, max_iters = max_iters, k_threshold = k_threshold, split = split, cov = cov, N = N, S = S, upars = upars, orig_log_prob = orig_log_prob, k = ks[i], is_method = is_method, npars = npars, ...) } if (cores == 1) { mm_list <- lapply(X = I, FUN = function(i) loo_moment_match_i_fun(i)) } else { if (!os_is_windows()) { mm_list <- parallel::mclapply(X = I, mc.cores = cores, FUN = function(i) loo_moment_match_i_fun(i)) } else { cl <- parallel::makePSOCKcluster(cores) on.exit(parallel::stopCluster(cl)) mm_list <- parallel::parLapply(cl = cl, X = I, fun = function(i) loo_moment_match_i_fun(i)) } } # update results for (ii in seq_along(I)) { i <- mm_list[[ii]]$i loo$pointwise[i, "elpd_loo"] <- mm_list[[ii]]$elpd_loo_i loo$pointwise[i, "p_loo"] <- mm_list[[ii]]$p_loo loo$pointwise[i, "mcse_elpd_loo"] <- mm_list[[ii]]$mcse_elpd_loo loo$pointwise[i, "looic"] <- mm_list[[ii]]$looic loo$diagnostics$pareto_k[i] <- mm_list[[ii]]$k loo$diagnostics$n_eff[i] <- mm_list[[ii]]$n_eff kfs[i] <- mm_list[[ii]]$kf if (!is.null(loo$psis_object)) { loo$psis_object$log_weights[, i] <- mm_list[[ii]]$lwi } } if (!is.null(loo$psis_object)) { attr(loo$psis_object, "norm_const_log") <- matrixStats::colLogSumExps(loo$psis_object$log_weights) loo$psis_object$diagnostics <- loo$diagnostics } # combined estimates cols_to_summarize <- !(colnames(loo$pointwise) %in% c("mcse_elpd_loo", "influence_pareto_k")) loo$estimates <- table_of_estimates(loo$pointwise[, cols_to_summarize, drop = FALSE]) # these will be deprecated at some point loo$elpd_loo <- loo$estimates["elpd_loo","Estimate"] loo$p_loo <- loo$estimates["p_loo","Estimate"] loo$looic <- loo$estimates["looic","Estimate"] loo$se_elpd_loo <- loo$estimates["elpd_loo","SE"] loo$se_p_loo <- loo$estimates["p_loo","SE"] loo$se_looic <- loo$estimates["looic","SE"] # Warn if some Pareto ks are still high psislw_warnings(loo$diagnostics$pareto_k) # if we don't split, accuracy may be compromised if (!split) { throw_large_kf_warning(kfs) } loo } # Internal functions --------------- #' Do moment matching for a single observation. #' #' @noRd #' @param i observation number. #' @param x A fitted model object. #' @param log_lik_i A function that takes `x` and `i` and returns a matrix (one #' column per chain) or a vector (all chains stacked) of log-likeliood draws #' of the `i`th observation based on the model `x`. If the draws are obtained #' using MCMC, the matrix with MCMC chains separated is preferred. #' @param unconstrain_pars A function that takes arguments `x`, and `pars` and #' returns posterior draws on the unconstrained space based on the posterior #' draws on the constrained space passed via `pars`. #' @param log_prob_upars A function that takes arguments `x` and `upars` and #' returns a matrix of log-posterior density values of the unconstrained #' posterior draws passed via `upars`. #' @param log_lik_i_upars A function that takes arguments `x`, `upars`, and `i` #' and returns a vector of log-likelihood draws of the `i`th observation based #' on the unconstrained posterior draws passed via `upars`. #' @param max_iters Maximum number of moment matching iterations. Usually this #' does not need to be modified. If the maximum number of iterations is #' reached, there will be a warning, and increasing `max_iters` may improve #' accuracy. #' @param k_threshold Threshold value for Pareto k values above which the moment #' matching algorithm is used. The default value is 0.5. #' @param split Logical; Indicate whether to do the split transformation or not #' at the end of moment matching for each LOO fold. #' @param cov Logical; Indicate whether to match the covariance matrix of the #' samples or not. If `FALSE`, only the mean and marginal variances are #' matched. #' @param N Number of observations. #' @param S number of MCMC draws. #' @param upars A matrix representing a sample of vector-valued parameters in #' the unconstrained space. #' @param orig_log_prob log probability densities of the original draws from the #' model `x`. #' @param k Pareto k value before moment matching #' @template is_method #' @param npars Number of parameters in the model #' @param ... Further arguments passed to the custom functions documented above. #' @return List with the updated elpd values and diagnostics #' loo_moment_match_i <- function(i, x, log_lik_i, unconstrain_pars, log_prob_upars, log_lik_i_upars, max_iters, k_threshold, split, cov, N, S, upars, orig_log_prob, k, is_method, npars, ...) { # initialize values for this LOO-fold uparsi <- upars ki <- k kfi <- 0 log_liki <- log_lik_i(x, i, ...) S_per_chain <- NROW(log_liki) N_chains <- NCOL(log_liki) dim(log_liki) <- c(S_per_chain, N_chains, 1) r_eff_i <- loo::relative_eff(exp(log_liki), cores = 1) dim(log_liki) <- NULL is_obj <- suppressWarnings(importance_sampling.default(-log_liki, method = is_method, r_eff = r_eff_i, cores = 1)) lwi <- as.vector(weights(is_obj)) lwfi <- rep(-matrixStats::logSumExp(rep(0, S)),S) # initialize objects that keep track of the total transformation total_shift <- rep(0, npars) total_scaling <- rep(1, npars) total_mapping <- diag(npars) # try several transformations one by one # if one does not work, do not apply it and try another one # to accept the transformation, Pareto k needs to improve # when transformation succeeds, start again from the first one iterind <- 1 while (iterind <= max_iters && ki > k_threshold) { if (iterind == max_iters) { throw_moment_match_max_iters_warning() } # 1. match means trans <- shift(x, uparsi, lwi) # gather updated quantities quantities_i <- update_quantities_i(x, trans$upars, i = i, orig_log_prob = orig_log_prob, log_prob_upars = log_prob_upars, log_lik_i_upars = log_lik_i_upars, r_eff_i = r_eff_i, cores = 1, is_method = is_method, ...) if (quantities_i$ki < ki) { uparsi <- trans$upars total_shift <- total_shift + trans$shift lwi <- quantities_i$lwi lwfi <- quantities_i$lwfi ki <- quantities_i$ki kfi <- quantities_i$kfi log_liki <- quantities_i$log_liki iterind <- iterind + 1 next } # 2. match means and marginal variances trans <- shift_and_scale(x, uparsi, lwi) # gather updated quantities quantities_i <- update_quantities_i(x, trans$upars, i = i, orig_log_prob = orig_log_prob, log_prob_upars = log_prob_upars, log_lik_i_upars = log_lik_i_upars, r_eff_i = r_eff_i, cores = 1, is_method = is_method, ...) if (quantities_i$ki < ki) { uparsi <- trans$upars total_shift <- total_shift + trans$shift total_scaling <- total_scaling * trans$scaling lwi <- quantities_i$lwi lwfi <- quantities_i$lwfi ki <- quantities_i$ki kfi <- quantities_i$kfi log_liki <- quantities_i$log_liki iterind <- iterind + 1 next } # 3. match means and covariances if (cov) { trans <- shift_and_cov(x, uparsi, lwi) # gather updated quantities quantities_i <- update_quantities_i(x, trans$upars, i = i, orig_log_prob = orig_log_prob, log_prob_upars = log_prob_upars, log_lik_i_upars = log_lik_i_upars, r_eff_i = r_eff_i, cores = 1, is_method = is_method, ...) if (quantities_i$ki < ki) { uparsi <- trans$upars total_shift <- total_shift + trans$shift total_mapping <- trans$mapping %*% total_mapping lwi <- quantities_i$lwi lwfi <- quantities_i$lwfi ki <- quantities_i$ki kfi <- quantities_i$kfi log_liki <- quantities_i$log_liki iterind <- iterind + 1 next } } # none of the transformations improved khat # so there is no need to try further break } # transformations are now done # if we don't do split transform, or # if no transformations were successful # stop and collect values if (split && (iterind > 1)) { # compute split transformation split_obj <- loo_moment_match_split( x, upars, cov, total_shift, total_scaling, total_mapping, i, log_prob_upars = log_prob_upars, log_lik_i_upars = log_lik_i_upars, cores = 1, r_eff_i = r_eff_i, is_method = is_method, ... ) log_liki <- split_obj$log_liki lwi <- split_obj$lwi lwfi <- split_obj$lwfi r_eff_i <- split_obj$r_eff_i } else { dim(log_liki) <- c(S_per_chain, N_chains, 1) r_eff_i <- loo::relative_eff(exp(log_liki), cores = 1) dim(log_liki) <- NULL } # pointwise estimates elpd_loo_i <- matrixStats::logSumExp(log_liki + lwi) lpd <- matrixStats::logSumExp(log_liki) - log(length(log_liki)) mcse_elpd_loo <- mcse_elpd( ll = as.matrix(log_liki), lw = as.matrix(lwi), E_elpd = exp(elpd_loo_i), r_eff = r_eff_i ) list(elpd_loo_i = elpd_loo_i, p_loo = lpd - elpd_loo_i, mcse_elpd_loo = mcse_elpd_loo, looic = -2 * elpd_loo_i, k = ki, kf = kfi, n_eff = min(1.0 / sum(exp(2 * lwi)), 1.0 / sum(exp(2 * lwfi))) * r_eff_i, lwi = lwi, i = i) } #' Update the importance weights, Pareto diagnostic and log-likelihood #' for observation `i` based on model `x`. #' #' @noRd #' @param x A fitted model object. #' @param upars A matrix representing a sample of vector-valued parameters in #' the unconstrained space. #' @param i observation number. #' @param orig_log_prob log probability densities of the original draws from #' the model `x`. #' @param log_prob_upars A function that takes arguments `x` and #' `upars` and returns a matrix of log-posterior density values of the #' unconstrained posterior draws passed via `upars`. #' @param log_lik_i_upars A function that takes arguments `x`, `upars`, #' and `i` and returns a vector of log-likeliood draws of the `i`th #' observation based on the unconstrained posterior draws passed via #' `upars`. #' @param r_eff_i MCMC effective sample size divided by the total sample size #' for 1/exp(log_ratios) for observation i. #' @template is_method #' @return List with the updated importance weights, Pareto diagnostics and #' log-likelihood values. #' update_quantities_i <- function(x, upars, i, orig_log_prob, log_prob_upars, log_lik_i_upars, r_eff_i, is_method, ...) { log_prob_new <- log_prob_upars(x, upars = upars, ...) log_liki_new <- log_lik_i_upars(x, upars = upars, i = i, ...) # compute new log importance weights is_obj_new <- suppressWarnings(importance_sampling.default(-log_liki_new + log_prob_new - orig_log_prob, method = is_method, r_eff = r_eff_i, cores = 1)) lwi_new <- as.vector(weights(is_obj_new)) ki_new <- is_obj_new$diagnostics$pareto_k is_obj_f_new <- suppressWarnings(importance_sampling.default(log_prob_new - orig_log_prob, method = is_method, r_eff = r_eff_i, cores = 1)) lwfi_new <- as.vector(weights(is_obj_f_new)) kfi_new <- is_obj_f_new$diagnostics$pareto_k # gather results list( lwi = lwi_new, lwfi = lwfi_new, ki = ki_new, kfi = kfi_new, log_liki = log_liki_new ) } #' Shift a matrix of parameters to their weighted mean. #' Also calls update_quantities_i which updates the importance weights based on #' the supplied model object. #' #' @noRd #' @param x A fitted model object. #' @param upars A matrix representing a sample of vector-valued parameters in #' the unconstrained space #' @param lwi A vector representing the log-weight of each parameter #' @return List with the shift that was performed, and the new parameter matrix. #' shift <- function(x, upars, lwi) { # compute moments using log weights mean_original <- colMeans(upars) mean_weighted <- colSums(exp(lwi) * upars) shift <- mean_weighted - mean_original # transform posterior draws upars_new <- sweep(upars, 2, shift, "+") list( upars = upars_new, shift = shift ) } #' Shift a matrix of parameters to their weighted mean and scale the marginal #' variances to match the weighted marginal variances. Also calls #' update_quantities_i which updates the importance weights based on #' the supplied model object. #' #' @noRd #' @param x A fitted model object. #' @param upars A matrix representing a sample of vector-valued parameters in #' the unconstrained space #' @param lwi A vector representing the log-weight of each parameter #' @return List with the shift and scaling that were performed, and the new #' parameter matrix. #' #' shift_and_scale <- function(x, upars, lwi) { # compute moments using log weights S <- dim(upars)[1] mean_original <- colMeans(upars) mean_weighted <- colSums(exp(lwi) * upars) shift <- mean_weighted - mean_original mii <- exp(lwi)* upars^2 mii <- colSums(mii) - mean_weighted^2 mii <- mii*S/(S-1) scaling <- sqrt(mii / matrixStats::colVars(upars)) # transform posterior draws upars_new <- sweep(upars, 2, mean_original, "-") upars_new <- sweep(upars_new, 2, scaling, "*") upars_new <- sweep(upars_new, 2, mean_weighted, "+") list( upars = upars_new, shift = shift, scaling = scaling ) } #' Shift a matrix of parameters to their weighted mean and scale the covariance #' to match the weighted covariance. #' Also calls update_quantities_i which updates the importance weights based on #' the supplied model object. #' #' @noRd #' @param x A fitted model object. #' @param upars A matrix representing a sample of vector-valued parameters in #' the unconstrained space #' @param lwi A vector representing the log-weight of each parameter #' @return List with the shift and mapping that were performed, and the new #' parameter matrix. #' shift_and_cov <- function(x, upars, lwi, ...) { # compute moments using log weights mean_original <- colMeans(upars) mean_weighted <- colSums(exp(lwi) * upars) shift <- mean_weighted - mean_original covv <- stats::cov(upars) wcovv <- stats::cov.wt(upars, wt = exp(lwi))$cov chol1 <- tryCatch( { chol(wcovv) }, error = function(cond) { return(NULL) } ) if (is.null(chol1)) { mapping <- diag(length(mean_original)) } else { chol2 <- chol(covv) mapping <- t(chol1) %*% solve(t(chol2)) } # transform posterior draws upars_new <- sweep(upars, 2, mean_original, "-") upars_new <- tcrossprod(upars_new, mapping) upars_new <- sweep(upars_new, 2, mean_weighted, "+") colnames(upars_new) <- colnames(upars) list( upars = upars_new, shift = shift, mapping = mapping ) } #' Warning message if max_iters is reached #' @noRd throw_moment_match_max_iters_warning <- function() { warning( "The maximum number of moment matching iterations ('max_iters' argument) was reached.\n", "Increasing the value may improve accuracy.", call. = FALSE ) } #' Warning message if not using split transformation and accuracy is compromised #' @noRd throw_large_kf_warning <- function(kf, k_threshold = 0.5) { if (any(kf > k_threshold)) { warning( "The accuracy of self-normalized importance sampling may be bad.\n", "Setting the argument 'split' to 'TRUE' will likely improve accuracy.", call. = FALSE ) } } #' warnings about pareto k values ------------------------------------------ #' @noRd psislw_warnings <- function(k) { if (any(k > 0.7)) { .warn( "Some Pareto k diagnostic values are too high. ", .k_help() ) } else if (any(k > 0.5)) { .warn( "Some Pareto k diagnostic values are slightly high. ", .k_help() ) } } loo/R/print.R0000644000176200001440000001112513575772017012541 0ustar liggesusers#' Print methods #' #' @export #' @param x An object returned by [loo()], [psis()], or [waic()]. #' @param digits An integer passed to [base::round()]. #' @param plot_k Logical. If `TRUE` the estimates of the Pareto shape #' parameter \eqn{k} are plotted. Ignored if `x` was generated by #' [waic()]. To just plot \eqn{k} without printing use the #' [plot()][pareto-k-diagnostic] method for 'loo' objects. #' @param ... Arguments passed to [plot.psis_loo()] if `plot_k` is #' `TRUE`. #' #' @return `x`, invisibly. #' #' @seealso [pareto-k-diagnostic] #' print.loo <- function(x, digits = 1, ...) { cat("\n") print_dims(x) if (!("estimates" %in% names(x))) { x <- convert_old_object(x) } cat("\n") print(.fr(as.data.frame(x$estimates), digits), quote = FALSE) return(invisible(x)) } #' @export #' @rdname print.loo print.waic <- function(x, digits = 1, ...) { print.loo(x, digits = digits, ...) throw_pwaic_warnings(x$pointwise[, "p_waic"], digits = digits, warn = FALSE) invisible(x) } #' @export #' @rdname print.loo print.psis_loo <- function(x, digits = 1, plot_k = FALSE, ...) { print.loo(x, digits = digits, ...) cat("------\n") print_mcse_summary(x, digits = digits) if (length(pareto_k_ids(x, threshold = 0.5))) { cat("\n") } print(pareto_k_table(x), digits = digits) cat(.k_help()) if (plot_k) { graphics::plot(x, ...) } invisible(x) } #' @export #' @rdname print.loo print.importance_sampling_loo <- function(x, digits = 1, plot_k = FALSE, ...) { print.loo(x, digits = digits, ...) cat("------\n") invisible(x) } #' @export #' @rdname print.loo print.psis_loo_ap <- function(x, digits = 1, plot_k = FALSE, ...) { print.loo(x, digits = digits, ...) cat("------\n") cat("Posterior approximation correction used.\n") print_mcse_summary(x, digits = digits) if (length(pareto_k_ids(x, threshold = 0.5))) { cat("\n") } print(pareto_k_table(x), digits = digits) cat(.k_help()) if (plot_k) { graphics::plot(x, ...) } invisible(x) } #' @export #' @rdname print.loo print.psis <- function(x, digits = 1, plot_k = FALSE, ...) { print_dims(x) print(pareto_k_table(x), digits = digits) cat(.k_help()) if (plot_k) { graphics::plot(x, ...) } invisible(x) } #' @export #' @rdname print.loo print.importance_sampling <- function(x, digits = 1, plot_k = FALSE, ...) { print_dims(x) if (plot_k) { graphics::plot(x, ...) } invisible(x) } # internal ---------------------------------------------------------------- #' Print dimensions of log-likelihood or log-weights matrix #' #' @export #' @keywords internal #' #' @param x The object returned by [psis()], [loo()], or [waic()]. #' @param ... Ignored. print_dims <- function(x, ...) UseMethod("print_dims") #' @rdname print_dims #' @export print_dims.importance_sampling <- function(x, ...) { cat( "Computed from", paste(dim(x), collapse = " by "), "log-weights matrix\n" ) } #' @rdname print_dims #' @export print_dims.psis_loo <- function(x, ...) { cat( "Computed from", paste(dim(x), collapse = " by "), "log-likelihood matrix\n" ) } #' @rdname print_dims #' @export print_dims.importance_sampling_loo <- function(x, ...) { cat( "Computed from", paste(dim(x), collapse = " by "), "log-likelihood matrix using", class(x)[1], "\n" ) } #' @rdname print_dims #' @export print_dims.waic <- function(x, ...) { cat( "Computed from", paste(dim(x), collapse = " by "), "log-likelihood matrix\n" ) } #' @rdname print_dims #' @export print_dims.kfold <- function(x, ...) { K <- attr(x, "K", exact = TRUE) if (!is.null(K)) { cat("Based on", paste0(K, "-fold"), "cross-validation\n") } } #' @rdname print_dims #' @export print_dims.psis_loo_ss <- function(x, ...) { cat( "Computed from", paste(c(dim(x)[1], nobs(x)) , collapse = " by "), "subsampled log-likelihood\nvalues from", length(x$loo_subsampling$elpd_loo_approx), "total observations.\n" ) } print_mcse_summary <- function(x, digits) { mcse_val <- mcse_loo(x) cat( "Monte Carlo SE of elpd_loo is", paste0(.fr(mcse_val, digits), ".\n") ) } # print and warning helpers .fr <- function(x, digits) format(round(x, digits), nsmall = digits) .warn <- function(..., call. = FALSE) warning(..., call. = call.) .k_help <- function() "See help('pareto-k-diagnostic') for details.\n" # compatibility with old loo objects convert_old_object <- function(x, digits = 1, ...) { z <- x[-grep("pointwise|pareto_k|n_eff", names(x))] uz <- unlist(z) nms <- names(uz) ses <- grepl("se", nms) list(estimates = data.frame(Estimate = uz[!ses], SE = uz[ses])) } loo/R/E_loo.R0000644000176200001440000002102514407123455012431 0ustar liggesusers#' Compute weighted expectations #' #' The `E_loo()` function computes weighted expectations (means, variances, #' quantiles) using the importance weights obtained from the #' [PSIS][psis()] smoothing procedure. The expectations estimated by the #' `E_loo()` function assume that the PSIS approximation is working well. #' **A small [Pareto k][pareto-k-diagnostic] estimate is necessary, #' but not sufficient, for `E_loo()` to give reliable estimates.** Additional #' diagnostic checks for gauging the reliability of the estimates are in #' development and will be added in a future release. #' #' @export #' @param x A numeric vector or matrix. #' @param psis_object An object returned by [psis()]. #' @param log_ratios Optionally, a vector or matrix (the same dimensions as `x`) #' of raw (not smoothed) log ratios. If working with log-likelihood values, #' the log ratios are the **negative** of those values. If `log_ratios` is #' specified we are able to compute [Pareto k][pareto-k-diagnostic] #' diagnostics specific to `E_loo()`. #' @param type The type of expectation to compute. The options are #' `"mean"`, `"variance"`, and `"quantile"`. #' @param probs For computing quantiles, a vector of probabilities. #' @param ... Arguments passed to individual methods. #' #' @return A named list with the following components: #' \describe{ #' \item{`value`}{ #' The result of the computation. #' #' For the matrix method, `value` is a vector with `ncol(x)` #' elements, with one exception: when `type="quantile"` and #' multiple values are specified in `probs` the `value` component of #' the returned object is a `length(probs)` by `ncol(x)` matrix. #' #' For the default/vector method the `value` component is scalar, with #' one exception: when `type` is `"quantile"` and multiple values #' are specified in `probs` the `value` component is a vector with #' `length(probs)` elements. #' } #' \item{`pareto_k`}{ #' Function-specific diagnostic. #' #' If `log_ratios` is not specified when calling `E_loo()`, #' `pareto_k` will be `NULL`. Otherwise, for the matrix method it #' will be a vector of length `ncol(x)` containing estimates of the shape #' parameter \eqn{k} of the generalized Pareto distribution. For the #' default/vector method, the estimate is a scalar. #' } #' } #' #' #' @examples #' \donttest{ #' if (requireNamespace("rstanarm", quietly = TRUE)) { #' # Use rstanarm package to quickly fit a model and get both a log-likelihood #' # matrix and draws from the posterior predictive distribution #' library("rstanarm") #' #' # data from help("lm") #' ctl <- c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14) #' trt <- c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69) #' d <- data.frame( #' weight = c(ctl, trt), #' group = gl(2, 10, 20, labels = c("Ctl","Trt")) #' ) #' fit <- stan_glm(weight ~ group, data = d, refresh = 0) #' yrep <- posterior_predict(fit) #' dim(yrep) #' #' log_ratios <- -1 * log_lik(fit) #' dim(log_ratios) #' #' r_eff <- relative_eff(exp(-log_ratios), chain_id = rep(1:4, each = 1000)) #' psis_object <- psis(log_ratios, r_eff = r_eff, cores = 2) #' #' E_loo(yrep, psis_object, type = "mean") #' E_loo(yrep, psis_object, type = "var") #' E_loo(yrep, psis_object, type = "quantile", probs = 0.5) # median #' E_loo(yrep, psis_object, type = "quantile", probs = c(0.1, 0.9)) #' #' # To get Pareto k diagnostic with E_loo we also need to provide the negative #' # log-likelihood values using the log_ratios argument. #' E_loo(yrep, psis_object, type = "mean", log_ratios = log_ratios) #' } #' } #' E_loo <- function(x, psis_object, ...) { UseMethod("E_loo") } #' @rdname E_loo #' @export E_loo.default <- function(x, psis_object, ..., type = c("mean", "variance", "quantile"), probs = NULL, log_ratios = NULL) { stopifnot( is.numeric(x), is.psis(psis_object), length(x) == dim(psis_object)[1], is.null(log_ratios) || (length(x) == length(log_ratios)) ) type <- match.arg(type) E_fun <- .E_fun(type) r_eff <- NULL if (type == "variance") { r_eff <- relative_eff(psis_object) } w <- as.vector(weights(psis_object, log = FALSE)) x <- as.vector(x) out <- E_fun(x, w, probs, r_eff) if (is.null(log_ratios)) { warning("'log_ratios' not specified. Can't compute k-hat diagnostic.", call. = FALSE) khat <- NULL } else { khat <- E_loo_khat.default(x, psis_object, log_ratios) } list(value = out, pareto_k = khat) } #' @rdname E_loo #' @export E_loo.matrix <- function(x, psis_object, ..., type = c("mean", "variance", "quantile"), probs = NULL, log_ratios = NULL) { stopifnot( is.numeric(x), is.psis(psis_object), identical(dim(x), dim(psis_object)), is.null(log_ratios) || identical(dim(x), dim(log_ratios)) ) type <- match.arg(type) E_fun <- .E_fun(type) fun_val <- numeric(1) r_eff <- NULL if (type == "variance") { r_eff <- relative_eff(psis_object) } else if (type == "quantile") { stopifnot( is.numeric(probs), length(probs) >= 1, all(probs > 0 & probs < 1) ) fun_val <- numeric(length(probs)) } w <- weights(psis_object, log = FALSE) out <- vapply(seq_len(ncol(x)), function(i) { E_fun(x[, i], w[, i], probs = probs, r_eff = r_eff[i]) }, FUN.VALUE = fun_val) if (is.null(log_ratios)) { warning("'log_ratios' not specified. Can't compute k-hat diagnostic.", call. = FALSE) khat <- NULL } else { khat <- E_loo_khat.matrix(x, psis_object, log_ratios) } list(value = out, pareto_k = khat) } #' Select the function to use based on user's 'type' argument #' #' @noRd #' @param type User's `type` argument. #' @return The function for computing the weighted expectation specified by #' `type`. #' .E_fun <- function(type = c("mean", "variance", "quantile")) { switch( type, "mean" = .wmean, "variance" = .wvar, "quantile" = .wquant ) } #' loo-weighted mean, variance, and quantiles #' #' @noRd #' @param x,w Vectors of the same length. This should be checked inside #' `E_loo()` before calling these functions. #' @param probs Vector of probabilities. #' @param ... ignored. Having ... allows `probs` to be passed to `.wmean()` and #' `.wvar()` in `E_loo()` without resulting in an error. #' .wmean <- function(x, w, ...) { sum(w * x) } .wvar <- function(x, w, r_eff = NULL, ...) { if (is.null(r_eff)) { r_eff <- 1 } r <- (x - .wmean(x, w))^2 sum(w^2 * r) / r_eff } .wquant <- function(x, w, probs, ...) { if (all(w == w[1])) { return(quantile(x, probs = probs, names = FALSE)) } ord <- order(x) x <- x[ord] w <- w[ord] ww <- cumsum(w) ww <- ww / ww[length(ww)] qq <- numeric(length(probs)) for (j in seq_along(probs)) { ids <- which(ww >= probs[j]) wi <- min(ids) if (wi == 1) { qq[j] <- x[1] } else { w1 <- ww[wi - 1] x1 <- x[wi - 1] qq[j] <- x1 + (x[wi] - x1) * (probs[j] - w1) / (ww[wi] - w1) } } return(qq) } #' Compute function-specific k-hat diagnostics #' #' @noRd #' @param log_ratios Vector or matrix of raw (not smoothed) log ratios with the #' same dimensions as `x`. If working with log-likelihood values, the log #' ratios are the negative of those values. #' @return Vector (of length `NCOL(x)`) of k-hat estimates. #' E_loo_khat <- function(x, psis_object, log_ratios, ...) { UseMethod("E_loo_khat") } E_loo_khat.default <- function(x, psis_object, log_ratios, ...) { .E_loo_khat_i(x, log_ratios, attr(psis_object, "tail_len")) } E_loo_khat.matrix <- function(x, psis_object, log_ratios, ...) { tail_lengths <- attr(psis_object, "tail_len") sapply(seq_len(ncol(x)), function(i) { .E_loo_khat_i(x[, i], log_ratios[, i], tail_lengths[i]) }) } #' Compute function-specific khat estimates #' #' @noRd #' @param x_i Vector of values of function h(theta) #' @param log_ratios_i S-vector of log_ratios, log(r(theta)), for a single #' observation. #' @param tail_len_i Integer tail length used for fitting GPD. #' @return Scalar h-specific k-hat estimate. #' .E_loo_khat_i <- function(x_i, log_ratios_i, tail_len_i) { h_theta <- x_i r_theta <- exp(log_ratios_i - max(log_ratios_i)) a <- sqrt(1 + h_theta^2) * r_theta log_a <- sort(log(a)) S <- length(log_a) tail_ids <- seq(S - tail_len_i + 1, S) tail_sample <- log_a[tail_ids] cutoff <- log_a[min(tail_ids) - 1] smoothed <- psis_smooth_tail(tail_sample, cutoff) smoothed$k } loo/R/sysdata.rda0000644000176200001440000071000713261751552013420 0ustar liggesusersBZh91AY&SYXYYw{;>o@a;w}y_yn{Ν<ݾ{4} mk{ͱ[v׺}w>λ]8ڼn{{nr{sv6fj#֩뵧w ;;ۭʽЦoGʼ]ws;{{T[g<)ǭub.v{jKmi^޶{RqUo/{֫ݽڻ-;H2 mZZ:+D+#Y,H`A\`Jg}G^4'8"k1-yklG˃شr-3tLH8.s3 b^KA`b[fbϥ/M-/թi6- QJblHub/@ ]OR;q%$㱲?NI]L[U_ClGU]/@_h-ۅ-n? Ղ5H"K~b+^E{h]Uh3M r#,M$_Ћ{ňyPXٍBuYISO91dž3)PaK`+ZG 54c؃jb7}m,3ivZ6 ]Er@*6~B_H6lgLBElA @c/]H9v#: $ 4(@_]U~aJk`CU$}q_UF4C^ Ui/!Jf H$Ͻh3lƱծ aAlEuHDZ 1q1l=U*+Gm)W敩9! c`6ZH>X G( Ym}l4 cKvkxR6Z&V:gXхa~`vN劺iʄUG֩P+믲pZ;ƴ1P ڥ3hF5-O1% W؃W.ťg{M^X)1dXJЋ#E"W3.Ђ4*Cy AziX f"F=w1rʼni#vLb);Е%4Li+9"F೦b= ėUI-?i%1/XX |BgaT4#i"ă>O0;ւ4mXf_ɱ)|˷ZXX1.JM%hF]b 2Ih_CM?b=mh.Mzi Ա.XV@f c3Ɓ_Qشr 6{BPjzO1]`#HYkb_#A3h\N,6,* kH>v4&Ɩk`o  cAgi/1U˶its}4 zoѦA8}ZQ !a4oa(Vj96 gXvĩ-!n {>4C!/]ֲ .KDŽ,FijL('`x7- g df$B(Bиlh +\U6y" sFEhExw\Z@Yؗ×b3 ~./̏ }4ʄ9օiv7. 6j(ܥ1m{L@vQsR4~,X#}H щQ^aװ\E1*s-?] 36.W*<ƅArdX 7{ȵLhJČj6ѼklO0 +GΎl.98E]^~y-#:>LHa9;h\PwW3`[]o=m;'k 7/<ցJГke %ej2 ["qhx,< g>L~3GfUq_x-.jЅ@t$ʹA@u&F1k;K b04*B4y'<(HeYgo=r_e~w,^_)1`غNEp- qw}88:jq/ˉcAex$Eg6;O艈& Q[RdIa/r:D/7ǑLV)s:BXF6%4ez%ش^abeixGB9 5m";UVeyi#ЎmKKv |)rh=sI9Żb9V5[2/iR/i "4qW _Kt8Bʴ>V[bY}a ֏V'XZKks̲t{LSe?ײFDľ&׊ó@ a[k Ή3j kBߴUYXY\JB K1-fYtLWf$.”kh]JbH^|f0VF )M{0~()F6 8FQEWZx- 冉ר?AYгL9Vi t_P@veS%a2PHDR][\Wb\~,yX5l4 v 4bGm,*c.-ɣf-T +͢D7dKXšŋaivB^G]`Af9jцjyZ7LDH A#FAh/#ՎM֋{Z18Z:N]mV&ς>֒1,=_z7 Ttl AzpMdK@Ÿ3Mdd%Ѵm9;Ve? h= rtхjע1h#YiqhX+ȵ4kߩ%hY]{ XO5Sbue' &+؎Peb%<^h+,Gii_y` ]N?9T֪lfXpXF-P>BZ +HEхIk Ge03ϡy4͈Tƕ6 JTmUs(BF*EA3|55_f5g +K`:f]_ 25ip0&*Sp!X #D8-,kMX9ݿv l9o!bpR_15ع_ v9oJw}w6!:ljoy:@k z+-4NqhZWݤ$Z5]gM FE5gx¬ױy9Zn8@LtƵ/1 )-g2~2q*(ߖCN"bi)4Yٍi"Fg\lFA'5ԺK{VVֲ>~*Y&hڟb8xƴzN3hUWt+LlbU@Rwx *GE20 3fϼsE=Wz F}RX+)hDZӱyUP03i|^M&,Y<.)L K@ ] E#`\ |IRVZ>OQRgX)ub7x]W)010dX_+P{͜%eBi)~L])G?ԵlkFiYh`X0Ph  ,JNb<݋h^ڣ E4Y[$~MRX%gCTj,#gh'[ToVgi[+bY2{HUWמhop,FE03}xJBfef%v7A6xk/OLRUgKyOn}kCE^wim@ n.fDxWbQ qQä?M,Y= ug֑\1\԰ 8iHY|'ŸBF^d wVV{8 2P".T?57H *R 6֣-FM<>K $Gs]íHA;B;&*k :;Kk`t#g#YHTZ8<|UWJ V䞑K= k)1[K %Եb1kN&"^];I@zz8AQhaIi*&04NmhU.~ FYv־ū^[ B~M"i`(+,䘬fPoc`\kXWRıM._q2vy ց|Uwa^U ~[9Ps-",QB ?sEE3Hݵ?#F-vOzU?6 -DƕAɼ-u O2Tq}6](FXGRh;c_M^,æWYeGWm:혱 д*X`]aeUE<ð~5ط4C5^/i]X[X\]12GͮSw< gu4Opshب-0<&~E:`-mma0]ѫ_X-ռsE$l0"Fg;'Eյ;A+2A֠. f㤵f#X'`+kmQȔ*,>ɘfngYYLԤ8= iXlk+5Ohia+ær?.ͱ^\|h =L,bجڧPNۿ,h2%0?ҥVْR-wH-* ޒ8,<^c>&&8+/ԖܘSXM\z,9PkϺab4)Qg氲4{i y}̠|Bj_Ɖ7ղu!EA#h&2:_4H[fe>ju} <3(ߔKcyv.ݔ֌kY:t,Z&94^T[$;s+Mu Z0#ʇ,X~G* e= ZNb$?G%+Nx؋5z/LnKjvu)M~G'Rz] BpWLD`X&^=ga?z_1qx}6ROú2$Ǽ+^vguaY@V>j=9q%앿ON/: Uў>V|[_\R՛y85TlEM>AS W-6LJ9Ņkf1WfbćF-K\^C05X>RlW\Ea]qbdjZ'ٸʋ֫q)QB`i6g]YMd|mBw֬3,>ɥjq sDu3[-}tĈZ7dƴ ia<:6+Կ4Q@][5{U\t뀹kI fb99S >~Lc |LyVY5w}F,ϊjKO{Kؿ,E틜e֡ |.Åq]?srYdhྍW-S9.E>Ls, ۧȖEZ^2;_8nuvIr_Tdajl4y #JZKbp%|@wP"c=S`sYan#UUUx*tH|YRs,,oKgR/9(A?{d [vzW˻AsUzM9-n? olPKF€iW)n'3LFfK/I@}HI V[Q>D@ ea4g4Yٽu75B}o 7hppvOĖtmO4,q7wfb@ 2))%g= |ܴ{/k+濶YdTa ՆHѴ-6>0?*trzsD?j #{揽 ;M^}MiX6*sl<}-Mgök ,>qӦbZYT%k`5oGA}@Z>O k߇BopV(بXG)+>7W"\5jkNϙ8#\W6 ;FX_!T(Ts ]N0׶Rk%)7GXƌ㓐7U6Chc6l3 b@xlTuGR¦23ۓg\rju4V9:G/֜,=3,L\8 )qqw\~8Uh7.ce =BXGzt.Z =miG/sԃBy-_ܩ{H'ڰ;/)ͬ7IQt,!_"FioZW'>›6M-Sz9:6[_eW2fo%Yq[YO j|Wٮ휮ǞΰZVV=Rd Wj{cFMq V]j-cnV /ũn9e0zh*|]r(:j{9 _i©3`ƿ \"l^n:ɵF0H,+곙 cU܀1gj1w`iݝWHq̯zNUIqd3lW :bXa5|+a;e|EWd]mر3b}ɸK컠'@PLƮnjI%vZfw Բbٯg"1e (UO>MȮp*1HKbb?~MY\CBmcZa$:W_"ٱrV3i_mvޖb{O&dy/[jֿSPd:3zV\F2aC/٣å3kPљ6ىaֹyNVa麯I:[< T4flnkT$띳/v߾g~áb, Voc bNL>>T-#ٙ: $*cې'6ؘ=ԞFupxLC˻ H{1vX6p^ߵB0P*[ Tص0ؽlzofYnI.ǁ!g&0پy|lZ((ḱmLVP>3Pe<|W..'  *L!GugSaf{ֵbrWY9>êd;J|U9͇(L\N "UIPk̃]iޝǯGǽw $zL9Xh`3`+jCv/5*XrUJk.,WoqJea䵉{3Y,4Đ3l.§29fL{&OP=wJfәn3 sKmYxWGr,ٖfɋBY6W'+n{vۈ3E1IN>2xُmGŭgㅇe( W+%[*vR9[ea3gq3~xl <:4L0l 7>fn<;M=rh Pi؏ ~#+m1łH,1^QSy>T [~Գ6E yyziS@V{e wJ /240aNl;B34eO=e:Ǹ}OVi<Ol4~vUJ{8/kv1{oYϣդqn4?OsN򚎿&/UnEz*\?vOegHfAҬ+_aMn_m%.-qMS9 3,ml-eXHmxl_WAy/"n&R\믹{~Sy~&jaZUaS^-'h,GV&Nsa >qcڤ=2u<Ƶ\ױ":'5af< 9]?c\嫱im^W<~z$??l˕3(WWPq;Gz6L<^y<=/1eC88=^'tע$EnMAq$=+mXjħ=C̾>ժ`[Odzeبkv3eQl&_fԹ$NEQ}Juye+` -h;ƫg=n;="QX$14~l0]7Fgۦ|2E'd>?aͧe0F6X>ݟikÛ;nuRUܽ>+6_= K2dGY-;Ty#=R" 1j:`jm[MJiN_b5NBq& D/,F` f h0>YX8.>I{D,7F!}Fdww5},M_d^s.:[YIN3K1t_]M\]fA^}'$h o5V FӉWJ/P˷eӿ_#zjk̜vZ/LV'XN'mszǦ;LK-ҽL6Y囥}fEmf[} $Lί45Kv{VʿK𿡙<S(ܺ=s%U)pZ^?I39e3K_oNfu& l[$=l;uy|ړk=&SNOiP\NGVdXqGUeČn^7h[,9h\fL8FSkMbv2Wcyz9s^x/v^ƺSa|(j9_ S \_K±8`PTQ/+Vq~بu^f)~q_+_U9z|ͯ&T{ʠKy^['[L[Bo5]t&/a>]ǚEK9I<UI#gc9|vW{)uwdGejg-lW^ƚPqxؤbe_ay&;\[SoR"Ni_\뢓OzO_ SgVjv!|X>M.E9Znvyh͖SeW xZm7MOȂ@@D3 A8/@ycbl2=Ke M) voJ~v=ܪ١Mbf,۸oAxz|T7 Wtä߹QI5>z?[̸?n1l}_7M\I #9-TMJuͺKݓ[sBʻz^N޷ԯtcm"-h7MĊHt=_aFZ&+/|{yE_ (0bod2 'X PB1nAlH0PiO\:0R Y.0U] %(>2?U'd;Z:qP+ CX kXI'5R|\x=㵸j_V[qmK9bC}[ޭŧ%%+u[` @>' @?ĤNb;2$}?M4=.8j b/]Q)#!]@T0 9\ > S$$X7ૻu'LtאAg >Y=|3ճp6;-K<"PHPBI3h ~oE!-  ȟ|0˯~$R= %fSA2zcd2|O@nZ)qDM}YW-9Yy=/)|@HUXEMn9{s-݁~ұPtPAv@ҋEׂ]9ըhe8@@QsJrg`ץK>SJNƝG|MoѕZ*o|;O[/7Ko.$]1R!z:ZDwM~aO}ui[-XSi3sE_S h= u<x]8hCQ$-ݐiӀox§ Kȷ##va: w`*@ȟ{ ŃfsCt`!,]J$cw٪&Fahl0)YQS-RVEE&ɢi|lU/ O]55~g$(I5@lfnr|BD1i\6Msਜǀiq vB @ H0޳i#,k\X,Jۭ6,!J ID-h0?OdbKhUѴ4q:Yڧ2hm_ J̿ʵ6#նUZɝR26`,_VY>THұ xPXY *lrߞA|e !qcX QfEa9.]PL!iR-|GRp}oRʽc)ݦNhT3}#7:˃g$uYTdSe=o\$xNIUAW}}H'D%" C.W@2 L&~|20트s*QB1d`(Scˉk Y .nS~ha| ޳:SW%lv` 7I o`lN(NqtPʦsRo$(R)R|יeC.UOX/hA`|7#@{+UuS' @  .OG 0GFR  _Ȝ0Â`%a+GҒ'E1L |40` Z'<ռ33 =n @+W!!} (ª$  հ%{ 3yB-%=񔇮d#& C}\~f=I,&UnH( sUn1@7$V3 ^ 0,UUɢNɚ :%7Z=Ιs]= E`Nb!"D-JXk\eM APR" hK t,%S&!h*0U\Q  @Hm nc~Qg=mLm=Ff0ْ/ qѵ!H p$ -z3UGt(sf>0GwEI& AQTރƅ SyWs+c>%b*Ȼ7;5M_ <-{&~y; FZQQ(MOW%dC# nA,`Z_ @1=/2f-k9E&9I3R/H>Z<hR C^  /v HmTDycJQ.&K턆mB K`9l!:*(& J *F{!ͭaLtu}Si Pwe t8 b-1FSpa>|=CkѵHG 2{iY\7}UT?^@'`6MȃjD:k %/q. ..oJ ig)vj{q<|BXcJY= UU?5$NIk}   =eZqApQĂ;}ﮂ!0jEц-EA _U0 A O$ިtDT 0[b xإm"S]M !ïfQo~c*t:/4"ky&QR<*|"  vpĪ(5P7ƃXސQ:_ qjDcARwYRJA g%7$9nH(5@ ~n810T}ՠڰ*>|C+?nᱚZiB~},ζ )Un$%5FHFV`C V)b5 [tyEL9P_<"&zOdiR:JNi3Gδ+mOW`ZĚf&A+?HXJY΁-( Z4QN@RP%rpt`ypT^@>`>n fS{Lz@4Bqt^n1@ &I BatD񥆕AX9C|ȋ0 6R6rbybĹ@{M n9,&`aubj~;{=NUUϽdz|%Nxv\v j8 BS "_M5dVYmi5_gyL->WlG9ӝ:Pwhdm22_M'54?w%+}3uOv/8ߥېL^e]fl;Hmk㟔[@7HB3t/-T{*mWĜ,Zߢ||-1Z~_ub^G_VoRj߽QnR LquVV8Ttxovx'pqꢮ-~yg}oUs7PO{HhaQDָ!ꂞ!ﳬ,MnApyy-n&Xh<ϞZP3= IW7_ye\ IWɠs2b k!X Ж u1Zx>; Q=1'XiG1n'US?Vt9kw!ȳW1f^Ɍ_7\Ah>|Tύ=>_$0z˃sZ^nam',]]o)qK{VM[2jz9tlLo=0Ľ1\C c%Cx V]n y cE'jc:E1'_-NkHR_Epx=L_hp(tldsSK|~,Y%U C;gBkzs!zsd!`upCP7 K ǪZL?Gi\x3nF.‹ǐ_4rekvkKy}MPke:[>J葉<“ACS`_c+kO#@hY_U+*/O|S~yX(?:{/ ;]a]As8˽Nj[!vT5zW;̲3܏nP#:w΂<h,EL9|}mr%z9D'aBD І H@쵂C$U!Ƿjavn媉6uǖQtW3CfJ St<7S;rxN>j?VIjPp˜rS_ʻ?総ujbO B~'o>^Y֙~+OYovԒ={^sB7`n#+G@XQ@R0a .&8JIZ/|YgEt cM2Md-;UGXS=H#_F9Wya2m*Cvs R/ {y88}HeTJfs^9?KbwS8Z}az)ݿ'e8 XZRm^*۽_Ogɞt[]03ζNyɐmz GzWi}V?YM[#q$PGc|j+v'=vY.Z󕺷tq2s֬[ CCB (HD D00 O@cB`@>hUs!;zipė\C*-.2tי_`,=ύ+|R3/Ud.~</\z-zgдn]cy(O@7Fia5KwS~AB4H m\oGYZ 8zo:}*'~{I-`2@ü 0y&JrlxtYu\xzUl'=]ۦ: &"r4S@:G9 R/CuK}PNQeLfz&vդ\4K=e}mf &FQO͙O%T DɭF{D491n[YSn8M$SqxԪFʅ ъݱ3k'DSsrK֮"lo0rUO6Tp_fF{wȑ_wG,o _,MsLms`ڿ ` ki?,Qkf첝Z:͵x} 6sq\/yÙ-l2 ,D =~Z2y W2;>۔͞5?k߿)VW;dYwX:iu"R  C4iX[4:KWDP^ nbly@$IO%\+e6i!uotbK¥f`@.c -{D*@= dkS?)b绉mpK+M2tC~S!5 xH\('3l>[ kH (B@؁K>!9q!Y\.-МUf!P'lmk5X,D'{˅9nZ4wvNl줰:4nr|?$&3oXA"%F`"JO禠[BteE\uaU}fbiI3$( k)`o -qP<\6@-Mt|A=\ebKTQӁ(d_ZWp,:p_@`+x#9c5`L1@!\evŶeɋ,,Pp-E*;f'V `L4+axM(\Gļ:a6̐`%S[v _!+UAjB9UIsv(*Dg}sBm -z]!Ecoz=vf cy투6jn?ԝ.n!Ęncal)OLF噌(߾6Q$A{6x1Oeݴc }7vp/~l`ofu̜S03H`_%WjJs57)HmEꖼ gG2rB2Rр~N v9fz0=V!Y\B,t-*(qI%0XJ)%cB`svJv7: Es j2AALOWv5g=P3Nw(OJ@rVjj?sF )4piX UR5xa!TP%ɂwxx1rک7ZaSHAw޿QBmeÖ#_Yeab];i/twM]ܖGs@GV~\$즗? 2fD,x ΅񴫐p$0(  MƵ@7UE(nXۀ[] = r=S)|I )4é*~p ]Ϝpn:p^s(A- k!߯$b5PkՇz`R) e3h#Φ]H>5ДG 71lӋ Zo}lp $Hn4 #@33[?!^4 }ljB9_QȐCj_!HI}Db)?)sB$޳s^^TNy92+Nnt Ьn{ .?rzGY+{ Nl5u}*pvjuI*,z<"e_وvAwd`S%L ƹH̞ͫqKKO8UcY/8*cg;מtBvF/UPX̯w[ xkRc^$mtFtlWS.sQ$saU؅Iv:?wVaU[&KlDPxBQԓlLRq8&J0T2@WpÀ#׆7aя .On!FO0OD&~l[>'\FFd1܏arEziqӹ4F4~ЁWL W١ă `k8mi澂eg>:+tTE2Z"m>(M6, bsABo9Г_,m^E 7IդB$\jVk;4߃W 4WPFa܋h1I^VD&4vBW#x-hڱ\c}3׼TR a\' ʦ/W81LKz"k7۵XGuj8I:5w^g/,wV0zѻoaԞQ\Ll?7M$wQX $ fa QߙVQ2.fE Wc>xN=Ex @N.l^Ee[}Q]uĂfS,5䟌qHHcpy}ÂњlJy 0W։*^mEp ha^s >^& 0SD~ ˏ2w9!5+aϒÊIP<.o)&$x~xGshcQJ?]OUAm!98 O9>BPZJ*bk{+/VWp-vEb*"e8<{EeE2@t-1D]l mÈa-tDTwo]':@P@zhɕԔW >]#3>;ڼu4t#r?CFK@uERc㼁Kݚ6~b ,mYdH_”D e[_BX-H3JF"S˛2ޡ uH`QYɚLO8u [`E @${9JP-5̔x 9^@`}R[p} DFV>e;6xݜ)Qe<;\;GgG''%Z&HHØu`K[CS-%tRW _2 GFE0V:> KO4?ZJYXq.ɽkfAus-XxO^#U Og' T& *V_Dw:WuDDme]:+W%Ӌit4 5%owN K!|h4q/-=Itg('7$lL/Hp}j\"Vڲ.wS,DW@(3Lj0Mr"ş': ?Ȏ#X,JyBzhBvu{M6ՔYy,tyZO[n`njM[)ϸ"x8_Oh}OTKi{* PΞjPwta&jͩfW*5!֕ܗg%S!z@Ű6.-9TĀu P [تm6zB:zEfZOaڟ}X.UJPm*# SNiEȄ61zy UQEC 3s4 P.jœxXhG8JotLU_ԈGPI,;}kndc̘w >4?l=;~0n[ls2~#S2(PZ8=$}Y~>j \pT_ȿ m% 8+E뾖3m!粺(g 10vkt3- L#Fgʱ.[󋎴U1&`_~ZG7Ju)N. FIwuTUm>h(,FscQ5˺! m#熔pv^*JvBbb 4qL/Gwt2jLr,8"sl0wዜ`8:}. "O ]ǶYԟ(L ,[~;g݇󜟖\k|TUb"wh a1냽X7~DHbFoZӔ[2m+>a}ȍ)8j땐޴30ҎAb3}dEQz@6jjkTO#X!d9뜊ѬҠg>Sn)e|pp|.{ġM5BHѯ`[K~_v$xb[}e1vy۽phl5^Λ}ћ: ~h˒N|s#Hu++jt~pxlm@ xg]MG@H}(?SUM:\K:]-ЙeO\Oe 0c:" 8MqĞռ B;*Q4Lw" sץyeۆa^p=xpGFtkmȝfΈ/kkɌYV}66G5`Iޕ(i?鿮7?=DbLGgx1F^522K1KSʅ28x^y^o#s,ヒ=%,us7*G6 T"?7I9~fze+ g>A;,a`AH /5<5 )yۇYAߔ>J~A9K85~6o8bB Ӡ GBOLD_*AL\[Dl]Ht]@yJQ~RKۿz_!dIpn oz,3E=XG-] w 7*HyjUap~8ֵF<8ðT~Un opcu@vҙ3#1n|~`"9bK%^c(D8r/Nʉ$W)JHb1 %VfV}B9Ҭ.0h57cNTB'Mh\ \%nz(VVd>`B@_ ҹ,M"s#='􋖓D<%m0ELSkP ʥ@tE G齱vܨ5 ,''=@ W` T^JM'Oob1 ݽp `^*kWif˨(>x.q ՗ӒHln՞+a̴i9e:)8r$. [+Lb[`{ or+SG&n]lFu2yZW02h+_I\mkJߥʄ0F\NNE]PWr[oBK{~9/Sr9Mg0(fRpJj*;hf\tדr[ TWc#讆H%C8e㍈ijZy= qV'moZpEHW(aPux]Բj@K J3# IwpBҕGjE GgGNr8@LeTzb$╢: IJo+ҷ1*xn{%ZOj5C ,4Lr&āT~LrenAjMOܠ| vPS޶#W*L1[>lL8: :!)ƕ@eV̆^:[J?\, a5$wbedmt)t; j سOA[ ^ fU~AjvBpy`d֮lq>2&d>l`r›S>^Jy"w^˺qUQxʑ/PΦeųiM;2ևP 7ji#y<DVJ5:77z43[?=6u\g9)'HC:ƫ7Pũ8@ T/9P$WZqD ,BƖs,ЯjPLJOB%& NCR.ʪU~\d &"YtWmb 5T(j-ZIذQt /LO ]|a@h`Ԧ C@4tߩ:kQH~!ec{`t)0S9o)%)/mf=y"MX2I$kT@|.C~jԲ"*|i1DN.a >;qLa!A{ߩK " ^]k&>0$"-؄|}`[+XIrU?2)̨l>~i#deag;` KͳuƼf0<+P3DW D`6=`UOKL(@Y{Vt/$ÙKnoQ6:wZّiěT(^vʹƝd I1TK;M%~н?"u RĽuX+lGk>/ xY/t[ ;& Wq, rH*"4Y Кx3_xԝ7V9@Wҏg@Nf:Q g k[AnjtR$A.~wZ6VZXzW]x 9PVp/TLHzCcC!Uj8>,u /̶mGj[av&ZtCj,"ʾ7.ti&d̉ʖ?߶颉zZ2Y9#Po]%gwE:|hyאv,!3ѱ@G hd ;MER/aQ=x~4p-$nug*zD{uB&pܠeֹWZIg$PH+*\mMO]aD"{r׌#8L.۝=xEb>x rC:q; Fg).UZܦ"gX8{)h]}r0ݬ?ƚM+⽻Az˲R*p'Wū`\¬GvY[BNg-L?0.kI?&X(.&@xGAv^ܭZҵ6WIqk \>&F2#?{TUӴ4vl6VPP[G% -\s[(߱aՎڔ*"-hVG6f2t ö'j$UQ|iofYI4ZoQDW4d2pǺG{dd_s,6ke O v?sF#ݞɾkkB?ch=xVSڗxx|c,  +J,êvvj#z9ׯ 0P꛱zeFL^-~;/>rټ ("آ!z`4XIN69 T&BS@L`Y Tz _]YrH!ЫeV CȲgB#_P=ӱa9p(+šS To,z;Wid*k57XK@/3Q`U]nk_P෭zCJߨ)z`qxăgX'L GzNo>E/zT/{$^u5kD][SdCV3yfT,'ds>$>/cAwMs|/D.%pt],DH)~ K&CS}y-ezb0@`D-aJ^<՘CvXP2 2gƠFpmaq3$׫clDwvL<5%ȸ'YGM7|M2Qc1ƎnqD=pF-xlҗ4z.noU\B%,tR_uj=^DhK@ jk|(t08,튬V(wuX&kr0]&,r>p-"vg*Hc)4Y%Gf44Cϸiz읇;vL{A1o_܏gu Z 7b0D{)T(zh4bU6h#N|ܫOyTej?;+K@n4n@@U.l- Z!w^O=?k#g`ې^].yJY cX!,)\H ̒\ e|t|^1lU /l9#Lz4ɚL9 |a K!9^zi ڿQt*ТW9"GG$Ȥ0_䄺S%Bns`@wO*ڏ/akƳe%hF%>֑oəqz~.%{,**%qC>_h=rv>-27橙rnr-grR ({PG#d?) t|d!S& Ғy0eӯRD,j@lEL^0 #4p@Hk2SA:?iLw"d3ihx dvԔܑ/~ۜ8n~]@q ZI0CW"9 \PX(,qPb o9j|zh`LI}Ұ_>myYsSpnm+BdLͲы#iqPwDS~7~RoTgc79?x~sS| i9bN`uR ngš4<3暝L&í)0^If.hE[lI,*ɱZ.ZG1E4ɦH~S;ۍ4eLA- t7DmPpxg_ ))u3 oSaps{ "hHDZYY M).9hFwg.x_v_̳ g< oo\".|SqyVе%]ob L(X{ * G(QrW{[@7L 𾐺Y7 z+S|*|cPÏ;cs#& 9(P"aIr..W})j^t[Ws' 9 r^ oW?3~TV 6[>Yy'p]'VEݡxN8*CUW&Xd,awŁR:S6Àr.B ݟ!z |0RЏ]R!@0`5N)wsXO:/u0O+иF RuSl~* 9gSFHDgs=il9&f.6QT5 }(9%˛d'gQXM>n][Wo C$sp2|ƎrAZZiusȗ.縿@F1Ϫ?G?ޅp魡{.]WakV@ɺQ@ /W5]$lN2'( -~yCU$^ ĿmF̒VUcI PR_5gϣZ Ç^jfőI;̄"苍%1ubYoV䁃R4ᔩXpܵA[*Û"WN7B=-@_0=wlLV*IbK>|l0GKّgZ|F8iy݈`OQQ좯/׀&e3*#GyAY甍hK*jw-qX~ E$l OSdKIv!}(< L_^#Ja>Xr͘vjQw)c?0i #-^:Oqwqu QSM VH~#Nj4J,PfX+8WyBRJ ~X;Ot-x\dzV4r0%e/yqb Q& .`k]=r!`sɠER7"u)=5+\ɬ1xҟ<=ו[7夵)DP` '><\ OyFBi,PcA,7G|9?Gwv<ZEC7:^a~2v`]E*vҼf/j4^d=:KYhz( ¾D? ǻN(r1C k"15Ig9ڙc뷎ggS]ɍёbЂu~i\;lE_նxzbn?9몸 g 6u Le.=T~߉6a9 S}ᚄHh$~|UG!~uOh`I/i%|,m_vM۪%Yu:1(} ޶cZFl6OLg;F}1qʦR:7TjG|( Țp !uwQUSkY ,IBo"O>fު[hX7{Ưn9mqY(<ϿEh7\-9{51WbU bq 4DKD(lP* 62B e$ق  Dk⥿։x(wPMlxRc%i/ߗ#ҞLv6ںhyF+VS/q0 Ԣ5 o)hFӌӛ[ \H/ 劄o;n;4ɣP%%+K[ukhdǒ:NO]b8E,xmC3^cj7򧿋$+d'2eH{ z.Z6 #9}OJ銻*Pr%Y`humJ{ل||Pua~,؃6dO6I2PI(bGxlm&{nWxeY-`o% kǖ{RRwc|P?6Cb[oG&]:q+-irV.Pw{6j~klv^m6 jOveqnoJ#q̤(AJZGCϑe BVp F|4X7!-uI{q9C`=e{QؼGjªo!i8\"vy$GGиiadWJ-GHJ?WDk#)  4sQx]OA5 ~ENֳ_tH fqjMVыSŪT% ˸>,5]Q9YVbdY kߴFY@^&L n0{__kcҷ|JɗwXQOQVp^_.H zy6 £G"9 9 %g.>?uB!r-*f#$r7ћpvpn*'U8vK{ƗeNUT'q LWb}_} [b[aP|h4歆%;{~HP 6?!'mTSRn^eP|1h\r^"| 6iӅhٔ;Йu%\跍=T0_F}a$mtƪG R$ON Z)ÔN0l^+F>nORiTzϯH6ѢBf4qQ-ZAU&D !n}Bתj:q!!\c6a)}" 2rDgۙDd@ 'Z ?a8Oԙ$Ӹ*RްD`T]]7I<`q+.}qrp}1w+_"ZP=ِ3%<~ȥUfՇǭmu>]< 2b$Ge@ }lj<.sWOC'cゆ" mY\2yUKMϫd܍C>6L+p2X$XN8bfk0/*D섋o+DT"*(p\ Ů^,' %Wr/-[i,W"҇5YDҀ} 7ˆ[i,@<>x~iyc&|T ,r #_%%6ѠBʉ@01/Sx \9ѣҭi{ E`$H~:n2{D:}2OF%9X6r1:guVD[bϐb7$sd~^!׌R'!RE\y^㣂MaϡJ'?ja@e `\ײl!MxP:jHdWGC?yh+U'v26>lj[W$ lncʬU}aZՌ³Z]՝-yћu2"/rXhz CD\Nbv>n9?|"XcRHߌoM0f=1nmáj@TҺTR#6>i2pQ8{/dLr{ep񵇣8<؀.s ''3Wn@^Sʔj%b,B)H.d*-wW;^W ]Xx(aSԉQ|aioJ57NQ_4<+KS}T~r?n ` MT㫔kZ&V dy?ɭkݷMʬ*t5}nZH^,%Pr `^!k+`J:1&؇vsZ$+yIaWW _8ݧNLt[('K˲ր`?qqtxq&EMa/';#M'DLgN뛯$',]<8`rHͱV H1vnjs W^_UBw+D@ {E0!Iep4Nެ1seZL'/7Z4!+L@<9icn,Qh77:h {HrƝLϿƕfc:͙V #;,_7w͠:/fp|c8H\}1'lW΀(>VlȷSzXӯKSwx1`2/Aо;_Phmt!`;<~IH~|u׿d :^=:C+)}foZG39h>@? 'YHёٔ:[rf3AWBi`HQڽqO`e0&j|@<[۞:rKe-T&3[iJ1.ve@);2'\J9}2N7; O/-x!|nje4$GͲGEF,KD)"y-Ma %c8Q; t-/aN-HL@h9Pڽ9_A DV4a"#!tz)cZhkOIo9lh\C%ӑviuf,윧u2v=u&'@x Mqa4ixޭt,ݓ! &txMw靹wس rA]/2->ԳrXo6xqc}"0$YP̪(EG:e-w'WI]t t!?œd @q/nCݕ%5%#6! ed1@*O<׎ 1xeà rF ߛaP0of _ }ʹӾH}V@$UsC3_#qmRp_'󣜏dD{ENOYu9݋1Х% Q[ RXW.)lj}j71*A@qB'2}T?vVnC<>r);"짮I:epo)āɅ_ y~Ia{=4DTz5O7G!gn BZ%u]u]nϒ֞NGSc. dZ bG&@kwNjjvjaWQzsN$m6'[^g:ju q1kgV1޾xƜLƠ54$^`gT qj.Pn i4'DZOCk%G̓!*"/`jDFq>)\jq" oٷ~Hfۖs|N%c/iiı\au>}/6 Y`y[>K1_z0=<>bU҆7sk d 843&Ә;WHldדLH/;Ω`|IH]%A {vE9hEˆo)*2_">$ ښ0<>}a/ʹOնڒr?bilOuC\WXmҒazz 9}D{~xhƻot)ER\!Ї524MgCkz*pDxQdl3Qp={ܛ,۷?ebh4H4%\$j#z1drTzˣm+x'mVnc}+^L-y-L5\]J2u2O9@P tmEMlS3iLtS7|QFU+S[nUUwٸF`\ϟF-8s c'"΄@o6iK0AEA'w5k}s>kÇuN0/;!;S-CN]OX,kPw, '_sr֥l:vIh _ 0 *K R }_M+j[Z%1/4,*VCQp^=+M+-E-ߜ:0 + (8u;&z!vS'q'\  vQBzd"qYϖmOt(qqwiwELn/ZxFP޿T M"ISɃ힜#,H7ǩGsܽd/*p ꁜBڶ{բ. !O^W~R6x:uwZ IGж3( *\{mkQM=&-P,W2UG_(,TF7=`Խh Ŕ:HNgĜt6q3@Z2#d: '/˴sUW벜b֕oVAwt)?x*n?FB@H3kbl-~]Fu !ʙp H!s"VCGl&WGnlLH]`nQ1wyaL Q* >}gZ qhz uZ=!"j q6ix!x=}ůrF_@~|) L뉢SжïqэUjٞL60IY (.B@6"W %g_MK}L%r~12+p3(P2]eI\/>PYu~/q 'x:ɏŒ3 Fe&|8V70 PN^/#4*e╿NV(yu@os}WΰSK^7Y{H-v0ЍDž&IBl%'HĭU?2iI`er*ukKE&qWz'9sWR9g{$/,-hs` K~Nh[)Ǜժ,jK*3=-G2A#}n6 RVBɇBS*P vl9M $I"gb%B%^ @=)]0qHj5{5w:ch/̻DRB7)c8ϖJ{wy@[ΩKao ctͿO+~_=9:P+ 䗞2[ùi8u%XxX}aANMq٫=brb>nJ(rܣZl`~7y7Z#n_G:>ƇuaƇICI_Osn"qnxH~OB iٺV1-"$#A)1ǁc a]4A;it$#"WS "kٻ1]/{"* >Յ~FC)#6ފFRB#8ΟΙSSfAgqWq|Օ1D$Zowe2`&036E?ZB` ͠q4=N?=t=quHf3xz[c&P >D@x޿߸(r LODtސ?cɜR\E6*  c4M?'k-#0#?;BAP&}M"m/cH]3AX1=OݠQɭj+P&T2o3F`lvrbJMNUϳX)昘?;0Bޙt=5'Ly3"?"ejfo[L㩹1[W$@hG=2UBRV['2 CT|{|7u=ZHcu C[H߿JXzQaň?I694`es*wXO 7 wK]Š 08z sؒD"xcd5pƐFQYׂW() f `/FP-XĴ;kQ㬓MX>bML ЪV@=R[DX^T/21ȳ_j`kPU㻷N$9x#C4P,f"Wx" ҉ש|@6V z( i71+28 pZ~ebÎh(:msA*FIҬ\>. o\?AJԲ;GTuH̚ f4j' 3ntV'w2U}ߩͷ'9]~ZxWxK]&%2;~i07J.2z F^Mؤ'yq|a2 :HQk)xF4|CދU<:!$ 985tx>u@ɋ)Fp "/Y~x3KG$)O&(Pt dA*_hyB&Ӵ]V%wZ ~M.Xn\pSׂe6悤3@F}]?YfBcHJfJzXx,d# ާkwuT8^\$j,5֫_/%TOqj.x[>$veʾ B Vg= w[:$˼#vrL&QN |ؤVMQr9m_i ģeO^{>[Zsd_~pɵ7޷@;hyx>cIEuİxX8jwWbH.sr #olcxHyg"% WYwOf*e8yg(e[ vkjAc/R/ۛYL-IɚFM-8:D8?-7]iWS+)V{tҲ~L-qe1~B]u[.3bZesгz^WZr}D"oq#o<WQ.S#V䭯''m-*(?@V P`FO/tRY266d0{Kٶ5" h' `1 cb^ے>I^3JH'|JMcmM;.~ʩKO*T"d6I|̀Ncy`N@#٘~@d3HF-Us]*(3dQx8ToJ"*QSrj)|#x4[2Ă}Y.SS׮#FѻDBl$,Ug2Zq3.@ lyn9:_Ҽ.ήp)5D"AK:/9q0i4TV ܝ>h}?.yZĉ`k R$x :`rWBOO80&oH0AJb}-B;Iʦfæh 8` 0~ Wp#^, bdEJbsNulZwVKs])9V0kІR *Xs'7fz'v lfQƠ}/§ m̽ǑPH9$G\M ;['ׅ?A_ 8V8ma6O&,@FDX:rtH5DUG!ߩȟb:h<~iIh_r՟9UĪD 励`RORq,AnhVM'}oo/.KM31ls7Pl vV}LC$Q0Цo:犲Z μ_?C4*I♕'RzH·}ens_rh D^_d{Zvt=$̮&唝.TԺ48eە[4>K7{V/SV3Z4j4빹6?4fMb_߭K -Fجŕ1aZAԪ 9"vyh@6GEqQ@4w~`ܽXMi7,K怀+EMg3ԁPLK5墵9-M8xJ։ fCHy:> ջ댛竲yC4'LX(j Y(:+s&J!kq!◯ҋj~,1!%7KVŵiQ 7Ѕw뾺rۺmG}E/D[6Ң#pXv1[4@y]n)i$Xd϶Pd&V*+y{șܪ9 qx`zodFTX$o/ÿCL ? "lsO4Ҥ.WK|PDRq~n\v$6S2r^֛9-=KF1y,O֓?4T\:$8Y9X3вJwځx0afEs71I6ޣss):RCŮ{6flv)YVDUVG}a#f:HY^=$)b-YG#G7JL3幎E_ 4UX|.ɋ/] /cA G˱Ed:#fTvlU\nnj s\ޔ |Qs~rg8&s恾 0eά1_w̅GѪi$"жh-e@  |T:)XꯛVﳧ+꺊Ōl&cAYjh ּ >7*޺WIˎ=Jrf r#2[ϫOOj\EL*I\f <--4x )0f+-n'*O-6^]No$Hq9Ok)ϫ_;\ Fb_M!|P i cL+ƍ`Փ_4vM)-Zְx}}%C*˟U3}a ҅9P(?u{({{G3V3ױrh*הYBOco1:8FZ@>acʣ)JJA{cbD0$u btU- S/%%9FoE+{lI YmЯ) ͖1ytF "'9 CU>0׿b]_`p=g<ӅM u2X>_X''ҺJވd3fDod al?HeGIE\Z_y)$A tu_:zcO K&v7v7Xk&9^&bmEu^y6ەCJPa ڲ;UQ=bPWײ 8  nt L{Fn`zXwac`|]J;q1"&f_dynW_xbQZ#A_ NQ0Q^;vd MGڇDC\Tvyqaeq%h2%6 L\]ByxD+<r=U{[_gP %5!\bӧ'5ѴتETd1W<4ԃ+ET Uh FzA+u/'l @lԠ+6*Mk? -Ot-wN?FIY|_ 9/*6RaiXӗ.Bk6`褵Ki#$>9{WhLW\FJͤCMO g3}wTWQz? h)Mo FT@iYe$v1r3>-8vKv*j=yZYzijYl7Xޚp (ZV4FT˽ҧ$wkwV hT&7})\iSd]cHE -/{}rnAs* 6RCw5akZnv\:?C`6%7F sj܏;I۾]X8NGQ"[sC8%4'rlYCxdZ[ AhPt)ԮFk(] &JDD[ y3қb5{"Է(+˻ǕI-Sq*!Y+:NJtU%Z Ъ|HawG(#ҝҜ !lVKxGHDY`T bE5 8d {BR{Pٌ7x ">R_/gFv,5陝8gowNc|b`K;$1,ηkS턅 xDw#_:}Du ixsBB kϙr U1 9buq4IӋsbS)tb.%ڗ#r妝|Ϡ4 Fl*|Pi2R 0ۉTa :s9%.BޭZv+A(BGR։]-jXa@#g-MNZLsbZ;_.-'csS䠚!!ljI5i߲=Ns *}K|S|!=FRkΈV5ۏ lT|XC7lݨ(oWSdia ߙĜ21+&i<|p0e9 z_ {%dj8.ft!(F*adXw AOuQD{EȜ34_8-N>BdUZV}WaGLUDv(: 7xZhP\e>`N%O607U$zDZ 9YE|Y4Wo׆&`MB g 9lK7ģݡ4myc^-73q"6Vmt jx,͠,Q1iA2GTnUj%o Y=6 ڱps9wie$qg_G웷̓CLf ]B.%3q\~̓y# iQڬ75(dxra\Gknm]0'lfy))`RNPYF}Z ~75)da(]YȞT+-TusnQHv /ϕf|e`',S1\/\g\Zp+!%>-׭soĒtky9t\j>;Krn˪BfwN*[8VA2+'_ 5mY AAu>\{NJB őCQ:ȟdq@nȪALwEnH5KבH*l߸ :XvAӆXDvh6xZ Q\S%\-p7ZƲ*zvpO&\KI\a,"D=bw,v.YЬV} c*f=*ch1de1(RB&bɂk~b.AG\[ hRBZ`zwwyh2]%!Z`,$uip(G'|ЮbMlףYFQi1v²!Gs[im1*R=LվqKnU y(mTS|oą,|>onow>X+P'1eṺq mt @;SBMv6 X nS*P j}}Rg }txŵn1J}. ٯ4~ z*u\{B{Qx6TƸ꽻,ie7́0}>ܤ%'i z_u% u5-z ˭1oXjec(ګi9`!)1ƼB.Hew32Ck?~$Bgl ݈Pj jʓ" DdICϹl!hMOlA% ҸԣqIY>G]3B\8Z[uQ.9/22AC'%m2<كpwe iϨ~_7тED}O -SȖl~l d.I 9bFHٺ>hCm?KT:}1'<*ʏ爄&=-3Э"-ny cL$$Yq>uKiAh=ʂIl Љ*T*Yh(mg¦Y2R4U83os~|-p  Smx , :kG| U yI/uF|QNAf6 /}e~UIOK{ >%ׯs#%a\/BN/~ N"EiG-]G/^(>Ś Q[ fu)8j wnVӈbV,qzd빷ZBmA.BvHrR :1"~0lQ!jÑ@$G;ɬc@doVb,9hjJْR4K*p=ιuvpSRBPa)ER gǺ%ۤshE0-FXt)XʯP Ō7DbM[B 8Udk#59 d2T8U).yF ;1ithbTxa2Ang%\)'?ˠ&NmΑ ϽXSHas>2E1'++~(JQy?moz^Y0)+ 8[~s},S02AB-:vL\SKĞ6raB Q 2Tʝ7ApkjV&TG>%<F0yK8VY Q%VE$]I<6#yeJ3=R3X,;wXULC @av Kwp˳̖] dNG:궩;Pygt8\'Kh`݂qgN!{lk8ɘmEO"3C`NǦչe/ aCd;dsײ9b 1 k{AKg.#ZIWa`::MV_Ȓ>wq>bFux.+Cq& 4DHTKQ֛fd7ZOZB9K [ W/6h, P3MVUsέtd{VQа$t~ʏ]3Ƅ_6CDhs!B$dI4?l]ěg,"b Sz0W BT%ӯ G9XL,[:L%8>8 ujhٸW?e@17K&idġ :/4$ShĜ^Tw6Mw$[Xzj{DeC?Ս H/29td.nH+SJ`bϨ܀ۭ,QDh9z>O7yzmch_12,/Zh>zn1s6L#EWٺ>bC[bA$ɾ{mfQv5K<:誆{rKYٝy`~qb'v5%C϶u]DR|ֺјҬͳAD+E;}|;|fm>QzLõi% pd e rL58-04G g+4s !Y@M۫( og#Ϲ5* oI`G,sꓱtd]{xT3ٶhg^skI@S@2:OB62(uEKZ 8yBs/[ GIei0.9#,jy5߇+-HT* fv0/LT~fhTFxxb3Aؖ}|v41p+]A*l{YfIE.!\#gS[~G^&̓)_C{b]:_!g|J[>F42v .|QoٹTFAt%MRv=_ >EQGf"r'"4U_grK:CFKNyD [0,y:PoF3rͪ~j!ptET&z9*;̱yq\r0]diԟ T "80|l?%oe"jV|tzsV6s sr;`HҼ;""=fdz^G~>g=rZms `p \+w5݌җ -@8f GTõ8O'fѰPzk.PI ̎ݓmg# KObdd3e$Gp ~EFzbyXgjgj,U$Daon[w4/3cJw(xQ2fJb"yQ)I0Oڵ5t/`Fwj:Ӓe3 iECL;LKr (Vv (H nX27ϊM!wB =ÏTb()EkOpE(DBg؅=mAh`~y;*8LZ% >DRv_/m@hp'es~FոHkgk },?[;iqfFj@ΚzmAUX=Qstg8j5V:REܐkLBP ʀ[_笴*X7jOAdsLC}R+DecwV?V6hL2CzАՐUjF<@45Ul0?;`L8x%ˇ]I#dwg}N*S0DzuɞqH䰎Y'  5[fKY^Vpltu yca!@nadUe['w\$#{I5"定D"̤[&Jvk!ܶ.Yxp~`Β!2U x^/voY [0p*h`7Hm ӑesE* 54r5Tb>R No"! FQՄȁ1:}*ss;;h@NWbsF\ӉD~^2t?0yL4?DŽpy|xgYq;mQj7l"KpܸUg ֏tMaA [N1%T0/ S3V<v.1G!"U.J!4LgiQ"-z'dn~N (-m4\  ;G4DPS]28}hY[UX̠?=r}GP0V-84Xnya!^H]5z(OoH˴L{IFeyB{leϺ#Rsep^Q1-fE;Dp/lS[DAop#q4<z; )&'QRxzU[|K!eA1e9\O +IO O #S4+j-יRl aw?y`o+ӛz`{u4>*T="$İ[ob,}Zab6 xU s!ʙggh1'њ2$K+0yv8+&9ō3v$+Ύ4:C06S@wy{\;tdܲY$Ӎ5YZ6iWol4Xku2)RW4Qg2c9 o ,SV7]NX5s1YbțcssAhm4I lveq)+L Ϛ \WvϜ\v^-CM^N.! -Ix5x$B;Zբn_bV2ߺ^IƾA^. g&9ܿO"0\s ~W?p"x-|=wSٝ}Hd^l@KknC1&d,:]@M YgbCc"}2"0NI#SsRyL`!%l!3uN0W"#LnUƔFr)RN q;N xbi~W 7Aw.qthBA&#L<* _}hH 6/~XE8+h∕Jqo\S-Ȼ"SUН )G>/s;xUhٰ` 'x`w* ^OI]T9qԐ(v81D_x!ɺ݌8F/+^E=$v};w$ksѪ9C7bd NMW/u7u#,J\"/RAe1hi}68vEâV!.{kC9`]2HUw.޸TsjJPI@I=*U %}}*"J>_=ܵŴ-־gzp%?\ hYgs#}e!֔m)2-^HÐqSjL8 crۉe/$Zƙ5AIx UsX;JmrRxw .hStCXTA%ۮgtg ^SSBAa xvfHUF囒<< z3JC?<ۅ-7줨"Ó/Ә߸hi>a844n6L3@hW%Ȧhx{>z}_/NRƕ}\1 Sxk/^DswGl֙b_my h~͛9:fa{{ˑ׉; u"̱t-*ّVGrMFk7s fDskL==}GmGEozۏ8MMn{lR1ʹ`Un3/Zfl~Q;EOւt'b MDU%igW,ܴ7Ĵ#穮ɵ'sK{;bـ~ҡ"3Ɩu+j'?qp/&2', @}IG@I.6@_ 4 Q&$aO 6Z(Jy Е0m'y/6,6PȆho$ݤ5Tj.0I4rDk^' .^`Zx,S% [>&lr jG$w"-G>!LOmmIX( 9q{Qcܽ]o6毨H=gScX-rH VgUwU;5Oھ@u?fiQ5 d] #yɳ'/t<r%S8f]oVi$ŻLۿF"M [x{v5_GLq0I[HΕܻ߰kxH,V=uv 7">|`xUwr=~Е`2sjaPګ^';Es;ՈKw$H89kR9ۏ.4haI?]MޚAPm~l;&3A F쵿3/ LϭE37+-ZDXSLKU į(Ѣ&ؐ_CH{pۡ&";ט] . _hpf(A)+1KyW2HWctB{-]%im_y;0 h&"n!";r>:6ڒ~aK>k]U3ȓ#MIW~3$/:%AOuݥ_,Hg$&b{ck{ T5'V ZI}td5BEen-7GB$D\`52,v,O̻3/i>ıy<12QNƼb@I٫{{5WV0_bb 8៘>JS#СEsn)c,tX d0I u`b ҴVnciW)qө KV̹)=pB3 1`"={ )5\J,kp h.)Ҳ>`Kb"2Z_pe`@i]&!*Y}B0-# ѢY\OK>Xg|(0!bDtDiG.ҝӚq879)]Dj9&^T@/02ᅮ,z(XD1` z?+ށ/U3[d>0)k2U' vjL}YX#6e*ޑ2a'J6jR=;W~6PyЫ,\XKGea6W[ ֖ܶ!=(<4!Rj}l^:EBװ,IU}4Ƚ՞CEf3#yJLD8J8qPfܟj/SOQyO&2>|g&*Dqb5P-f**حJ tW)fbD*K\mrECgS\k&fdm4xLtǪx&rm 4U 1s7A/<~$[G;C䒀Џijw^-AxC7Lو+mmkuLw%֍.TvJJ1ߪ0=q=,  썌r9y}ʔgҪ˞+zHaK]u 3`=U`⒏JA4o A|ƱAY .od҃PkG)8 6Ryǎxْ@o[gg4!p, is{2i'Fʈ$v0n5>_q_FD_1Ȕ&2~VIF?4aF)]z 6( Ldž 5YEd*?MZL?:cu@@5%+y`d[_^KK!1;kU-u|XFd`P?Xx;8EW9В>~T ]22 .3#VTR.YyEcJMKBHשJҘ=$_754XLuWfvD͗{e6_J5NӪ( gNAraԧ}2 ޠd 'Kj uBL!Ur@r@OEJq=LE\bf<@ APEgV~=(b^r?pdo[efݽ6+Z Q–+W,rCuDn]h,0\JGk5wq3bޝm%oNRb=a 8sS\R=f"lW+.W ǏffQEJZ]4[2RIķ:  c{q/TID,IX[}LVnE/ 51kE*w_\X3ǍYPV6َƩhFOw\Bh`io[-]ak/랧vy`0nX7ˆmɃa<4J}%TYd۫R"nOzK]fԶ;*RZF}NM

&uJlea (Rr|`qp v;12юf~ߣ?p$lMM林Rb6p;DG6ChQ6 jR hZ㢙,U=T HJ n$TDϻeEZ#(d nvVHwq*=X@֜Ō ZaxPL rOkL|K ">uQ"84gܫdiaEZ{;<؎n SТd^ py6T?hX Ae=?%[` 8Ixeq#i[WG"˪fT)Zޝu^\ox_M^$˱[VDFIΌ3,i7Kp%4k2/Kj4"xhbU{(:VLiV]nNy@W|%cS'%(KJu0䁿F.Bzܰa玴-iN5U7 HWNtI: G" gVI},x|Y:$/ q9U^ T@EG$ռxDRB:MF|v:VT5ʡðbc,8'9lJ U!>Tކmn7 9 ߜSq۬ ]Nžk( "c)&`&MbrVDŽhӢH\Er[F_iI;# DNE od-~ocڕj`e V lWêlb@60pwF+)8#Zzuߦo~w͢HGz=H׉n"P#fJY*LdݰtR;{Ř`K"wV £7 H|OK@ P{D:Ma8{LE(:\-BcH'x:<jQ崩GK`z>Vl ;}iXl)(v[˂ș(b֧g R!ZFD!)\O^OPʱ \-}g*~A,?Ԟf]|]wbk7K& LXVu)DЬwW#Q]wq (,bqMep!}T 2*-^?۶CX-wm7,p8a&_|6u JqljR<~zҫ;K;8-ӷ\q"Jyz6$^Mۜ/5&m:{zK,BG$/vi$\]%\N62}d=쥪W7Vw0N JiJԇ3_S aG-Bp|2TY:Ҷe鱝ˍ&V@O*{,U;^G@pCe "'ҧ=i(F?$(R 8=pUU+P-Z^Dh*wú1 [:A@gqF SASFo/zE&w3sNtu|}0;ENGRLdAi5K>\uZ%"dz^3|f .6+ekJRo6j!_:@8pIM}+_Za혮Q ~g~o5y'S0ݰR ) N24y)[RKZok$? cgiPnV;Cp2*vI\6qa C$R8 *p3I/AP`I2"¬ k bfG_#1g&e$`6Lws&0 !+ȑiלC1Qq-'.hnk5b$) 9FP:D y[66Ʊ*ք6aPYt!d##.%u$H2z8Ki2,y4)!;R;Uq;?' @:9A?1%7AϜ|M*+ g.jՖr3Q BBDa4` +eE o ˖2'M*Hh͂颻 DyDOup!\nNoqq$:YZK< ԔrYI>͒K2q(DO$\bB55 r)mXNJ"tN]P92£R>?XYSۺeu4AeJt\WI%sl nWʑ"*XS3'j tpETt yEQW~ۡC*J5v@諄ׯ3ux("l<8ʇѰ#hoxshX&N^#]YN:[O<O!r?!kt^ k szrg/ M<$[X?|?}E;$>8'Zn~Xjr)<3Bm㳕Nʍ#|+uC+iHPhLrK0ǻv_ސǒW괌=1(8kpW<n=.&;F*`F1~0"]/DJ?t=hiXL`8=)!W֮HAgwt=!B'+qaۦU8"sC#gTuSxl(K8bi$AyI=4y713k~eZIa4 inJ*8kyu* \o n"3[LqUՆ* gaРڶ^cfK!w=(V \r5Z^>ȿ GpXyw O618Нԅ'C=Eml^6 gI6 &wQb)<%5]e/I^N{sl!17;0oPg\z>vɿRW?V.O 0;ߪ-%t3kc,ފ kۥ Au!]yH._|P.C>P=t;wXc=B{(PdU^ڟt>rGyq4M78㥲I;;HЍ1yKYtƝc].@aFCfE2ҫB,JO[KHyML)ky J?/m93vG`%N c6/ZQΆ |gz[u,Bd:Xk)FS)EȌ(F'!jjrA,i?DsL`D#A'W$x]66ٖM4rqxφaYV "Anb9BcN5`v}$_`I"tф‹OCS`ODY 5~K_KGZ˃݋Pe Gz=.K!\6Ҏ^7Z;V>lxiR#=az >[pp"Q em=[*$g6'0g6L$"e>>v oVvށpHI5p&pҠ0 XAlсXpW.[D2SÌ{îsFw,şzwQ0'$;He'V. sNgյIe4覘k78ӑc?O(#8;sWZ4įӴ|6?ȝ; z|KW: Au;f5 e>-.&q }]_wҴ&AӂC-0%YRԿ0bYZҜ&PYk{ FI_l4*>,sP`Uk.m:Ym?hLPM',`<߲U)B)>̪`¨U&݅sŠs9jȠ+ygzdŋHWL 2 yB{4(mO:o$^WC =y{'*eFN-5 `*8=U!ԿܠKk=#!ğv,4=lkiZ0sOW)4Ử!qk֗dڸ!!Oa*3T#>Cd?AӅoc{T>\@(n_C4]iw` swϺ?>h?3iEE0xZk?ilKkiOf#oq1ΡD$ᡢi S!eƌ]A9,M`"6,u㲪͆}hr)W(4&m2%5l_5-{P n.+4* SuvxVV GLDW'+lK*,vNwJ~*hU|5+FZw)t_qIZwpTP-fɶ~߷Sf Q?$'OZ{LS8d=ƈqtf&BTAle|]dQ k*D4-K0r![ :p` bTW $'F+/?E]_0V߭D&К=YM™Ie_{Rg{nSK0^v8hK66Q9ש(>%^5^yGyN\R%f¦]{SgJ{A{aui7)dD!JWTDWRAR#=S >Ն߳%كw'>Ώh{%^:Uwhma~f7Ge+|&MGX@[V͓0'!g곩S*\jW$Nuh|rgaLZOtQ~sQ4?- xMT=v52~n1B+:m~NEփ}QQk) PtjA.p©6g"g2MZݚ,'ʴFeR5\dR'eYJ^Iȧ`G ڶ"O?"3ЃM=ljLsGKX=R墳Lxe{r_])eCKud#9h6Xe۟76M`A m宨(8&zG+y1l0.`x>CLUTeW ,"ٺ~Qږ.Oе@=}C7ӝ6Zhx6`uO2@n95Oj\x֣E`:rSg]CVa7\ Q-ْ"|=5 sf[S#*\u:HD/W9 J18MD3P_XڗP.$WZt&ʪBI j}uGGg}J10h9Еjpdjٕ4a]TY/tGWZ ˢ7ߢ)_^z *p:û;6Sc3u[~axW6:d4l[^h\5>㱖my!ǞB#TNCr?fr#&ečYBVه Bhܰ w V*:;(jÀ1”~/6Řy K|'!%tN1>u=Ma GŒ*L`(`dIH]ʼH '0yU,39vZ|A@ѢCQ1#uLOgd0!~!/~ds=@e#~b5 5w>HNH; 0jQT̼!3$nF ~S$f埯4rc醓8g>\i1cɨW%S*!G꜂HбLP0iFΈXCm>U=.b̷WR!z r 0N>KTcm7}D#N>z( ]la ^ I&bhY3^U>rm pTOZvr8qc$u099Ѵv[A\ H5}y@8[BQ\uZ@*/UsΠcA=.o*s4;f~!M֪/\vk {N/f0DŗGo*pZtR y"bAŽMVevGF085vʹ !|s 7S⾿CBqJbe;!4*-[Ňh8aBmnz% U`Oj71⯥Q @O"06x rtYRz$UjX ‚i>6'q@?9OBWRfQKl(C=ʃn E:F+Y~TC"9K Bsun^!-Gp音(Mr(Yƻց/'O$ (慷ٳ߇>zF{)"/h+ ^y|P鏿CuNȲTj@ :mbr Ev]eзilKumeiG>əf[b9F ~)Ӷ%jtc2"i/Mܓ*7 ҟÿG.R; ~1prpEݿK""`B&Vr<~r1館L% f$ gDUakx:W w^)&Fki)r5UG80 /6#NUNdXxo\z 7A2"&' BaX :ɩLTJ}[V|'[7iK<^.ci]IhR -3FI1%z)W*EgWu`c']7uf:\ʟ"uq]u%]uj#`Hn?!M^ᚻ mzM73&F!gYHY:z#]C!Ygar_U7 P/wqMY%`j&z~BJ 2恛KnQWDٲu+_Ixķ)픈uʉQ^L2æhu=~Ty&[_4_pU{L,1Z1 ;?3D|jp޶ƉF?ݺ6T Z[2Lc_%46A* E9AA8MERؒ*>pW84ĀP km1e9_\]EOHm:2}m<Z_N~0h IY2O}K.E3zL`T(ͽdC܈6O}}-{ZiY*ݛ?h0CMuČLz!+0w$EN+o\sLMSaɕ~{ڹ?+Uc68.aHtGddjwR勲hX ^n'O4tc.Gt h-XR&Ei H(#EI;rm1hs Y_DJE-6wF2mb M":˴88u 5zX!1<9?[8GoB}F~NC4y'cc4^z/lE֋ׂ+К}2|%Q*ǁ8H:P&!W`z$ kfUF(S2dovؠì>N@b Njc3uo$nT}z!<#2UPcٙDs{KOLE(X~N΍ZGռ12G;47w>eQE->k;H6s._Î>|{Y!ϑlX!0%#;U^Q743S5/"uXDSF+#lU'T- hFM__-X6`m*Ҡj-_Frm$SWN 5S;MǗ\LXm=aak轿i(x$;!tn7`(Ұ l*]Yt+Y"u'˜q=aԹK`&rذ4`}mXEj6d::G5RcJ#܌@siHWBW3UMd} ]wfQ-~ZP,fv?8Y iS6* s"N%գ|ÍO֗Ĺ܌'U$Uw60HTL_P#wx߾ĒD Y#Š^MK|'@YQMW^3g`Zbs/7Uc)Wn)檄֯0yR9'=-^Z קF*3 w:E B2EQ1fJ4%|rm{u4_9+#t0,z2y8Hj7%JL#@s'KÂ!ݓcN~~fQzs)O,(t淎IKё);!Q. 0/3zUl5A]- wIxpIȀYnRL8L]3.,7: 'e xu$<6_`1a9^ 9& *rEzA8&']8^"+-j.p/nܑ<5/envT}ann4۞202hKy3A0@T` 9"g8PO,t&G?.` ۙlqYDfuhePzME Ǥ4*{0D+Va~bϲ 9/=TnMI/qlRREd'UH~U3`ZTdgeAwbi )]p۠}PYPJW o_0еIֿ Y7fP)yd~oͪm L<lc(|əp#Yb~u񪙛ؗ:h>̀W|L5"+e8~-…Aȓ "]p])/NI']YB}I2-(>ؖ Nyrd@`ڞNDB!"w,}ݦG"(gcJA]O[dH̉T"# ,.b_ΩEMt\.43V%;ED!N,B)eؼi8_6áA]W|@[}*f7OZ LD_dn`//ĚiLm] e҄]sMsR䳭'͌ Dq(g+gG| U&,L%]sWM2U. -b`J궐 }$Vz_GC׽nRcvC`0"AC&RJM)^&]!;)J")8Č\vR z@H֞m gWyDJHq,RL @G;J``X%J2WEQz:Hj(b]u {Fc^k|$$5 i0Ir{ ʓaf} Zs0N"6J_sZCK;"9w:Ϣy#i6όXG1\XR:wf !|y9'p=]5cR?p~&/NPsRp#kޫ;\0xeK;z-)RG *0[3sJ,V'ݱPhlHa~b0(uTyN=6Cٴ(4d`1i)6Ug\f^ߤbmQEGNhQr=LD_9컢!:#̼bw}!0"?8_}w\z ^<Ӝޮ5 \#ZRb&J`F36>_ ^r,q* ÊX4 q?]isch^2 Sɲ8ʎlٲd`KH{'k/E&A`4L:~)w[Nz+XJ)N$Xn®jJ@H,F:ɔĵ;n&\Ci|!9!8`Z߁gAP/qF?2M?]X3x9~!AoH)# ?홷vuTnekM{ujgrULGm*98Q]|$x> d~Lgn+a$v3GH(a̱Ichx\쥏.X!Λ\BP'2ͥo .:ハK -84[ l1d=lC\B'TM+j,y's>8ڑ'c&M39-yX'jt\eg%0YhMHi7cGNS93-¶c9sV˿3Rre~?K3CJ6TJ-al#`&M(S9jS|p|Vpp~0D1e{BN 3dG3úC'Yڃ-l(41(?d3C`n܌Jg2bFt(=u缂/H^" -߻/(o6oB"l2) ;zaeS{@gOEYxh(2^~ю䑂?Qx+0(S; ^pxrfrmŀBGD zĦ$giu>G .T"ͱhZp@|u26L!v D^,~gW `<*tWG$tR"9 :?ano#I_>F.}4t؞kUAH[YA-л=]|$[R%fh^R2?}ؗ \+|h\1ZQn#3Zb3 0vbw4:̨M0 7a5W|Ug"ލUe(\7|>{Qo pɣ[߹|%:MIVfn=0 /r=P}a>U`R Cw7tǹ3*oip0n=NS [,]c<'ReVӁ/A9Ju+$5%4F.>Big6> yD9p!lOҼ"sVA;f=Q*jyA_ / !:#dž橋dKVP?ɍpͨaOdzw2pć T̎r% *k 7ed||7 E kaE~P[ݤ}ODm4 ṟVO 7 *QaOs8So"ԩs5(c@_] U3G릡4EW͕L!txFyPꈝFj5^f\Yܸg)J#Lw| ~GQÕ|e Mtȍ- NI]jri%T]ih}a VW2DSq?&z'HyKw- }\n,K""k*BR٢Y2i-qT@>Pd*Dcv{,Y pQяjc45üoFrҖ%?͊uLz)PW*E!fy88lu 26/@& KQJk gV|`[C5mMϭ2ӡ?Ю0ڢ/c;bv 9)]R6q865]esh>@BŠK(?Ӄ!׆g1wi[n:cw,D ''-y E3c8K5BлDI8Kc),9fr!G WnM,?R|46a1Z/0q IT~ur !8anIL4*rb.B` vo6D3,ˡ&cl4|h6vhI}~XzDYFg@n4EkOwmdre&\&*]\ *{,aXgP|{ܘc>HN> `֚9K`-)drn৐~oܷ4B@qo2]`20DOrD$8άCW^")Ǎ ^d:3& "xȸObYb͗&|9+p.vód)q(HYÅv{w-M`cQJce^i]S~7gWI*ad^-l}(ii%Nz&3UXކhir,Dk7H+g').S1&L~E eSղ"7^MMϽNj/25 LEI0o RUubML(zȿA?'p9{`!٠mfN_ݳ":ޱZ)â\*94<}@h6 ukh杦VJ'lPHdfQ0 Guډ])UKbC򐶑8;P&cXL,|꽞` qxM98<D_ GNjLՙ9٩Ҧͪ03楗>[BhpYN@SaE 5'w 0 V(y102s_YT#} !I^T􇃗` KIW=qB./UT^#$AQS_\PXK>xMfn)R-@HlA4 31d(vkb, #Хg3ʤQA݄'5哓V ,E}~Z8-qw¶R>=NħrurFxY[>Cn{H#Usxy$Nj:Z{o2v2,.79|U~V!8Qb'U{L.. ɖ^ēnq NƟu;m 7TWHT+S~a e3\bQnh[1ո '߾H[^vdiQڲSqKK[e2(T߼zW^2`aO|xe\T\ڌ4fϠsx7V'L٩ch{OM@ٷ1SiBpGW R ,Ϧ| O%aC f5$ ljAs /Ԯ8 $W1|`#egARU?-NwkYR# MbcGj ź(X"6jxYsPpr#@CaJ}o4?FNk5ao=UqںEFdG@ 7G Ax3RI;2@QLaПUC*n!!iVԵmbtټxhR(Sȯ& ƅw!bI?q,i:h-[ncYYv \)DrSC Fm(wy}|gD49ޢڧO,է|f]Ud>0~Տ%c a:qZהgeـ[„ɿ Pˆ,,Q;A&+{(઴N}ȇ% Aً۝3x}'}~m7qϳ[SdL,F}?nHbtc>fV&Ԕ?J ߺ{}W\}#[(+`H@Ճx_ǘ:/8cI-#k~Kh$ RWH?zbq)_ЌA=;P|v,x""m3 (G25ȃqr~w_V~ k@ {b$]tS1}dS,BaDR`ʒ?̵xӥo ~K~h~tYym-3m9X>r F8Z2}X=}w x*Dc8*(d$q8.K7ZJ-%B5rrd^0B (=-u8I%I$zpM }DŒ\w7PӅfpxVe3"J'g:}}1Nx3W6>Jd|̀ %^q;Jc> \yirJ ݘDߚ@#L9N$V|PyGd΄A#'hKrBZUb%( <{;#kUl@jBi[]yn;!D=ВX)*]/zA;:aNvNfu~:tCi1=J0k&+.[3XsT\_=~ii5*?@ƘSy\j+j 8UɦR'ٓS'\c5zPPNDSD?#B)rr+C"qV|`1(Fd%N:σ1 cj5`xOS<$2)54-.8nc7TgbG2'&WEеר3̯}T*+Ty[ * d8صR'D}#Sj݌!*Y |+}GE,vPI yw|6tqöQn4`ީST&K3K42,CC}[X]- 9dP2#_%s hcfU;/O{?ȍjAdr7N}6#fP;^R/]EǎD!t]`vjԁz2oZe7BMV6]~7b0/).:VgkPz sp$CW! y`!tBepcښr\Tm(`w]!` +.1 C%Cqj#bN\+/˙ZyquJO5oؐ!2DB[部GCFFU2#\WYx0@ Ieu郐GATJui|3sx[o_Zs-b-T\袢VOTߐle.e{o9c.d";;,0W=ddC/}sw);8T!P9ڎMAoo~iu]z4.#y*Ծ4RjhivLa6Ni]}p/X:$P7HQ=@/O]nY"Z9ߎ"˪=xb#(b+Q+mv Bs {+`ߦ*-pn18jǷs[$`Bf]IߎJQ[Si\Î`sW %?\IfL~UBlNX:m~{DUd٘,'` нĞ[:F)DKO*ZP}Z[[W vY= 1bkH`|Ccc>6GUBxT ɲH'P^]+fv;=hꁣ _ &U3AgbDquo;7yQ1PBtm0~O 5'Z'}d^MO+n>,fK~9M{c6:Fb*e喇&HQڝ+iˏ09fHd/BVWPwޱJ{2ӎNvRC'ڥ Ag,1L芫 čf7vtW⒯^stCI^[C6`yG`sfFjd\ػqf|d&\b]mbk8~?-ĢT3x q$XxCx{KI5GC*p)hc_L f16-xsZt݄/QD=UI 8Mt Gp ؗgý#*2^^d F"3]k=F/AL [gkAO2~oM_JMSx恴f)a{R)8t!_'rZP5Ic^ne`1'q(MrFp n/ .@Dt'aXu6$w#2"k-/c&[MqO+3ӨPOuiRlt#+IbٹU,Y@Z/%Va $2E bC:re/ߢBa}iMwVԏ#U Cﱺ)|5Ֆ:"W$8]soMEО~ܡɽ:F>ZQ%C-F$A KBI2yf l4"ES_Մ(!JPOFgq7r>(Ё!cz7u(J *?@+\ ! F *J_.spcs7i?{ d{g:FFO_!v򪰼Mrbn9K$DbdFЫ=˙\Vr~d5$nshE! k\ʀ[Xh@R,92~1t;J 3Gu ^aF W۟Fl{Q. YN~8mIxN@{X[z)X+Ar̛^y?;m%K-e8~A26 8|{ޒ@*<S3Q1&q&Vo\ujӭxLu%%NйU!h]fŸ|^&AHI}P}9,*|8M(`&Bfw5źc_u`9sFS<;؟8_ӈĻ,?1[ B*N?R)e6{N>!{K>- *{yMϧ܁H}t:Kl6^heֲ+ȿ_A!~ aB2an k2șO7(,:~iұ[S'r-3ԄHn e_H> w9 .Qҽڏ]q'ZYqR;3<@̗7dYk~XTƩڈX/nhɥ@>4QE;*lWϕaQF1!(\i[fmIc14r9E~kB1k'(t3%a3,p}vU2r~b/o;zQGQO ipFOKJ0XG1s)Rz "PXզ#CS:jm 9`\FKe%;Cwb( c5| x GaC.ádC;iF FdgY"$%n@[<)ɮ/?F\Lp˞bOwpIkkwXP&܀QB&TNh+ƒluy*PRiXm?B@:|%(Ori]p^{v]7ZWyDe{x#U3~-ak"|YRN_Q*5טc7@ /E^Ikg׮-Qgx!'$Bɱ @Z1 4m!+k6iL JX~|7 ,Kzs >vB>l!*@[:i1XrFt2|Ǟն0H~lgHPA׳JRqa{UW|.ɘBar@Q1j)ֈ1击J{KZB!uhcScg _JwWȸ"Ā+E%Ow˶benVbM 4\m%%6[hY[\mZq1\!B'acN*묹y(39&>]HHZdFK>Bpa@ÐڢM}[ OH1ArJ p6GU8i͙bx6Y)eIAAid34CMjR:~A7}QF Iݽ`[NhyT'ohs常_ 8;,<ψ~HJ$ܟ> '1.'7ç?s6I(R8 ݃wMMH $z1[,^J48+9}νpG֤m0|e=/EmZPC.ug\$n|I+5/mP=I\+LHjp]>,y:, vJDfi2Prb-Cf(@". 굷Hb!  mTb # Iz<"\1$[KU}`Vѭ["K mO,pq4bJj2Y-e^;~Jq[ b'z|2{ `YPT-/LS=D]+΄(AtJEvTa'O!%NjYRm26j4%c| ay;hLG&DV @j.3P/P|aMhȃ͝°3=*L06SE5[]'ZQF6Q~R^\ 95Aȟۨ6lL (خTnBVV@Db.K.6 4]ד`kVP'[L?[ ϊ 分>c83Ra/y^TNᾙD={H)`rU5uDH,0t)]r vIoGN q91e>4E g>WĨ ɨ>4YO#5P،*vO\҈[tى? K]Ж'~q..s\nt *7|(х\lj~9:3,zWYDΞ: ~%4I隺ѻc[!0!LibM ^hedePRhf@ Qfe'a$z{97{վ0{HO\~a _͸%m8d7RD)#,ң&z 4($FeK)u~CWoQdeRE axmLXG4PiFl6ʋfR ?*-+TjBb\T…iyAK4e1ᯱ"Jqb x-$@"z=,$anZ7!n8Jڈ-mҌk{Dh@ mnVQB%'6;G&]ESA.` m2z)4Î"JIS<1Hq<S^Ɣ&: Bԝ]6/(ɼ'wNصKINof͞\|1 ZPp >jTA^fم{ղRɠ}rLYc`CN C0_HKdRpWhg ΖS6Tp;!ܬIT-HwKLϹ ߌ@R9y(?6eq1l M*$!/ϿP6Y]jK 㳛NX}'7X }(12u+o}wyȋ^~/>ۇ_#F]ՋT `5ca8SĹР~ΨqUr+e.Me:l"SX(,  e5OLӃP9=|.S@vK.N gOQe䟖ǽl[&\[pC%F6 蹗u - 2k _T8B"$&%>øtaN_%XXәH ~_Fy(ZQq)wݬ. ̠‘GJJU^t5Z<6ela vhK[7n$^Va馯$~9ً7`V"ٲFRL}PgtڬG2ٱ儥n>qo'}R)-GLI13-{;쨲RQ=G@O q.R6\ZƨQ'6ۭ^CG=CH@R^·nuryy3(OԠezn՗Oj j1e$Tp[~/C0[3>jEvK'(OxBKZKQqܾ1д ^N1Ee4X$ ^)~|Z *e灟°Ӄ͟y)"ׁ-F>9V,DM\iAX&GL N\ ZX9u)4DC NX XEcCe'lcI?DD\gHJ?f~Z7ƧKȝ|Aãa$ #&3%w}Cjqz/~lSl(=ΦW$NnDžAM81V = *QITThPI @'D%v#LkA3 m_˘w7x+B83_eᗵB%kd ]J[i$4j26zF|ƹ !›2Z)v>:aNq{\}$ZHP'w/4[LjIU(/Ҕb,P}hRgzOfƃ*ܭ}:Bgtb~%'\Rqex|OCya.M:db0hu_ʍY%WԎ5 =zgٗHW8vZ;d>rj\ExIf`S73z{#+:ހ:a+43k.\٫5 2NCܭ]=|ktȚ:(AEcvs^{EE!D%Rd]+Eȁ He@U MɤKF\d !tHV$c E䎙7Y^s*-fH9ɟש9#,,dD&/xJ)SXDa(p}VW~AhGJ#9IГ)MLM.[]*弙1ؖt'KADŽʸ ~Ńo1cLm(99 q&Sm7Ti!kޟlRݙϴrnb.!˴O:Ƞ$' ~W<ɳ,g͘6?SF(z̔3EXx9`3wi``n~#=B0SōA@k-h̊ znBe:Qs;T= w+ >4^|v|4/8$̿ȃs2M xϤ%%Y3lK~Z Ї7pW8Zg9TuّLѩ yMvqD%5R`@?DK.{"zkHt{x :v;9ptsa6e>t0nRhw#芰P%8T3e/kTd]m?cJ?[x"H9; ́i:cePw|T'?{ gZ9oy5ߎg< 1'%fХwqcG)1Vk骖;GYցV-j䚇L0L@,gej}ÝXRKBE6 SC dY:(J:R}2ݒf%i@=)O3y^uY}Mt&c;o')pd{,D[_6ur6;0Bl,iTm?QɗY`..,<0[dxxt԰9jp?{].^|}' |P&`oJhaWUm#aҊjEBuD@<˳ц7/R*7%Rv(eB3'U]G =Yΰܟѝ4L`&[" C`7`+Q.;1PWd6!Se'F1 ,6J/s+:J޽3:T;ϻQ lƪsAkL $< DOg&B3dLA-t+Q>"szZux*;[DJkM0vt )]NSH"yO1% TSl+;GSRҭubcmG76!dFT3̅Mػ$S/wa:.AQѡpcG$J5 G8Ɇ'?d:y,33ȈG *" ppl 8]! тB-,2sm,䧡0)[,q}`+IЦEde8fDMj$< AǮyz@yͮ_T"]I8-QqTg8"{+?ϗ5A,/uEз3$[&z3 nHN~?bU|SKdI\6&;rJ }'xj%?O }THp!)[yXRm~u?  Z6R[Ck;CBs<6k^!vh^cqPS~,h,)䗖j:"*D7zV6P|(hkG1}Geo%2$Wl491C%HPPNS!Ր3x'Lm7U]0 6R;t,F۶P2 =2tO(iX\Kbn$F%-%VfBj b;[k SY~Hk!DXSoNEDhāDgqgCoyNd uTin(pEhAܖxֆ`_2:l!@hvm޸hTi3TcL?|<_ HRJ$؟(A@֔FoMۼ$H#m@ ȉS+WdDp?h6Qh7y̝yPm *-=Nyc"g5ʥ5fb"VIfU?,OKش{>G ?rΙ1rf yŹ %@DuY % EO{q녆U ReT*Yg֖]4hq[ 7WCac D7y}On9Y8iw4\/b4󋓂W=W8p u(AB7цu>}Ǯ[.ub6 (xfz)||*trzi#%n /"'\G`ZObFltA e&/I" %SL /XewW[Ȗ7<'3 ~EZ6&xm6xK?^$>șx Sd}Jv7zBNۯ e"G1@RcٶӲi] `rdS*Bx< HK9r8|j10-Ib'ZXj⯢0*;tƳԶ̍h]uVZaߣuCov~Q ˴sCR'W~auj 1P-2x]ڈl7=-z)e}䬎|g7忮66uxr#8}䉤t+!.%S9HOR 6JI;''DgƄphݛ:?3<C5w4<-%4>W1 ,!TF4, {lʦ[.R _{TC2'ˠ]@ 2'$DmBu8$8"~]Q`DHsɓk^Ϭj]FBğ!Xm9\½9ӟЪMٷ -ٽV<צvsWcY'U<ģ5Ы <87fWO{Q@E;?l {QJ:aTUoyrNe|SBu#TqN/)FI&`tSPVY:>kC_:_ù/gm?x}cbP͗[ Ļ*pTW Z/X}d76/1 nm{!,FǠo(JwNo4Kz*kׯߓ ey~ tE7Yk59LI'ʿm U20R4 H'HX>NƝ"gS3d?&e9X|Β^tC<=#L-o2sm5z_ޱ2l3x<,%~B?@aOX(Q[$YИzP=<66W+974^E/ ۲hx'ʱ薾|bBѭ~f$zpW(!} Wd隣q ~A4[^+ +bGjQb/Uzbզ(Z(B`HR2[n-Kj` 2Nҩg5f#T`6Nrڕ }GH0ølL )yײǯ ?HgsV']2A?GPajŒMvP9RF_J"y,@`@#H.]+zqJg/} N*ZXq)֣uX>/!a$R #9ԼPu\ ˳#p蟻}3aʌY7M$ʠ.?!)02Q!%]I R@wD: -Rլe  :|ӵ+ uSe|Sk'xALډ$l zw"ݯ~be;4nי"/`W.EǞ jeSt ex{!b;W.ڿE{xEkBiR86vmCnyԣRzí ak w7|1a wMn]To5HX[ m^T $:l!wdAT*;ᑷ[";j又jT 1^h!p4}!Lȣuul 9. LYB G:R}9#~Ǜ*K` Qnb~LAahRܦwQDK0vVDfؼ0 -!NYX ''иIEXznTuWx9mКf4$/Q@O_W7Y2d&1 kOG!>C)1@}K ?#$H`9;P k'U[.) #vPg&HT_l P5p0x9Wƿʠ8v<<]̕hF"DwR~؉x?]ǡ5ԺZuǼg'o(D ?aSIZc5٦޷=}=̙pa?_LSw4 Ŧkթݤ.t*KonpʝM&*(&o6V(|c*>T ɖ+T+St=>ͨM"erȾ|`ۍ]>UÈ,}3)1utռjU# n8k)&!ΆCPHvvL4HI6-m8l%?&{?ȟaaT8c]IB'@RYCK4+C9zI}RdQ|f {%w!5(P딫E$v^񅜮_ONi$.$aa5HXI@_ rHz{Y2A↑zd0A;e懍 bTREL#iܩ= n Fyb3Q1Z QSR򰒔(\:`vBFlrK{zuozj 7qGy8 j. {#_6^Ygm/_rKx-鐄;m j |MS3`b>3sv0D!Jx+s3Xk j?D j|fo.͙ g`\r|JxA0NvSչJAsl`P]xI0d8i½YM+5ALM'$nW/hEB: IRI`-S&–z+NHr|vR9k㺘 ^6"dԹS]L=1SӐsG]A }cCC,/TX BCYOl#fbQ1% Dl׾L?C)K7i0}sN2{˚3ysuiSѾ0Omml':Z"*M7Bf(J!w~.<,Q9>cT"9XE6E]weta]f-FB8D'yT>*?F,ZI?+&1WP|۠YJLf/ 8c M na%= Ic>'r8NCQ>J>V o %{L W^$]ݫ,i}Kߞrk`.:yV|FWZ^ fC/j,O堲I 8-=q2lI{x(0)$2f$í IVOlƋɠS?SE(k51yrG0&@sK((5,-)yىOnգ![<Ҥfy4TvU^2cC6w6Kk/ew?HFw$z3K^ע@s0Hv40HXkږ(6ۧ0EkGh׌@v0@;¯x: gB[tWJ*NW{ܞVAB5F6  nsތ?I72.ʻ%12ez=(Y=Vonzu|cj?d P](J$~ Pvč #4:Wx\7SɄ̖~W!YV#*@ @\۶.\I4!d`7Y5yMWK A?UO6Em%v~SKW黉lZ dדX~ԣىK$In%NA)Xn7D^E(ͷS6=-fݦȌm(uB+UXY DVq'}Dź8xiAVѾm},C%^F1 PNq )h4g8@}m}ŧ |b[fu$<L֧zư~Weȣ Uaa1\tK.H?Zp͒Q=c0ӑk 𚶃u߻4\]XUn n?1d%\(Cɂ߁*}OMbKwu6ż.읎=iz0gfMKAU'^DJ'ƌ*;Ohg:^[;GUnh~WS0ϣψRI43Yl)x.*DGw1U(N }׹X[Xz0 )tS;hJ&"p 6`eC:DxK I4TlƫnQ9q+"N{aEsoLzw y8OVKIK:]N3lGXGwڛgHS5Ğ]ϧ܆}GZ:ͭ>wXۦR3_8Y`! bG.>O.H1I!ȼ>te }v5/폴1ӹ\}1!Ⱦ2_Xs%+ Aj,(,ׄ: iE;a;:E_zmiibU^YL0?(kqɎ?wi=%bvќmؿ`̂{+<:xm&-z 'v2E?RZjA6H]L 0"eSknΛر93=˼[1}WffQibѸehuɻFT!Ƅ&=) 0bIIUva=/U0m=+^脑UZl{MOg8x5-yr bĻ:H3sEf~HHE\Դ<ӊWXNU0WFM!~xDsL 5_bf<+{9oH*c$)/ 5m6gII^Hř&61fW?Kσ. ˟Aǖt@1wQ`@b_ά8Quh<O:e"{*[\ڌ,9"(QG~b`P弛Oe\(k>9}]w0. c\n<x"SÉfNi.6ڪy1Q67(9g*ibf7噓0L:b8 %>޼ǯfTA,*\2?y+?@к\VT3Z}5Jl 7{`/ܡwu0&I?ehxJWȔ": +%). ;Irq+n}^qR;H|>G~{6nd\VPw\W4W8<@RzSI | lݬ]k)-4:¦anfl|Չ cscҏR*\JY#jwVURoa ~ʣY|`@ii+@9+l$p_bݽltb;oRqcB$P(' 9u >,Uw֎lo5fZ69hޯ{8W]u,u7c`ai"DPr.1 |idրnBzt{dfMz8k5)(>)E/_L Uf98wFE+.D ˚񒂯4{DnǹO- Meo~ w0&1у\3MGMEl ݷ,HnUEF~Q nb| $Ij2$˜>SWy"i8W:co tn:5,bA+8ضW1# ;L؂ Exv\]fis$ jGGcs2^@SC\*2z#rzO+0u^:w0B%n%Xf$-aY3(>Иu~4_q]:ߴz m؏o1dD8U>?֗ pjE w|t>z~0#7e'\էDoٓ/O/!-3 ΣpuʖfrDIC^߽[Sm u"B:"cX+.5Il#9xN-S*-df~.͒E0Oc/uASz4GjW}H 3cP4Go?[w07jWBhq;jrNE3Y>˕9S"9U/֚;QзE duA~.Ӫe ] i˚y)0l{h|psxG_jKY#q )|/Ժ4хM|p )SSf&Z$,$Gi i/i-ض]g+B 35B"OҷhoR&3+9W^W"&.< TlgH_D7r:1Z"@KNEa=vl w=/i~w<җ,g*iR~mTO-e;X7H=S kN^JS5ZGাMyOQa<ߠۼ ?$Җ^IVK~W&2٢S?ae ${p|%r#k7ҋ GJL&(rb>maD,Q1kjj9{F|(n}>LmZUAjB.h\ڣYI|=b!4CsJ{xz6 K :)x)@~ +(w97W-S.U]cCр\$qJG=/\IdQ-aja5~r$ \(eX3sOaX<+CZR2GK&fTqt" l\KULs_RI{ } &oBq(a: c^8s %E$~q ˛.u`x6#e(.gzw/pI^AǡF֏:8Cf!W`#:{۷rOKpGK-pu+!ߨFRPIFqc݅72@I 2{.YUP6WMG06;'Ħkd/=VcVN3S_$値IZ=D7an-K4)K>z[=2eP;FJ,+bW_I_/ C*c6_oCr9)ѱ$ Բu׍d!|-6 S!θ9h6L$# (T(&q4^Z[v1ۋ ہZ1"m0Dz G$,0wb?sI1e~EJEƥ3).a%;-"]C02݋/>!E:W:ڕ^c[N$]EJWC$ND{`?/J.'e_<妨{wMvCҤ_=rc9CZx2n!;x;o&UVs& /{ wc $G$ Y<]OhN3dD&0vS!VϾLS#0W~S~❩ CLM}iԗXȬhpF"4v2qqd:Z}t5rܔ W7]P V9aR63+-. G #,uQK`uH5Sxŭ"f##%n35rf`M"% z$"{As.+c}2ZXW{'<МH `fίj:| 8OT]p!܅V%@M50o4Z=c $"0rHBD,'cz D;m~6yY½|MMyvpKo|z*_i/# gzyDB>y=Cabs[!~]\Hr:Rvy$2DW*lF9mi=/i=Un& (}|3QTڂo+)Oј6!Fyi-fB1vuM&p>t5pob7-ˌ~E}ȼ1cG1Pdv{+],A;/Ej;%mxB߼1,A5Z0ܐ+t2n}i`w \[@x%Qxq Z=&˚I@}Zqpl~{lp }fwv"|V,+O:8ɰw߿ѿdR{Vf;X:.C1,h33ud i W&ϠnK_WuES`:B[|n)G7Qڈ =T{:|b%3(qYaSۓ?ЪSz j+%gΔjX;vw+l tP/hU Nqݬ@h>?70y?/f5ܲmZF"=I8b+wSyeJS%M&?r{J jߘU !d̃cM EY7G Hp4L4K݊¿ꃞ]l%~:t4cc svnG#e^yL+h3^ ^w=AHqQGC"Ok|lHd:@x6+\/ݏROcȲčfҢ6+q+ݏ2$k<<>t̗E&Ani7$5u|S~ ótmFAs`Eko]T}B"#8j{ڑѮ nŹ=C~1C<dcq`|n)9k''?^,_ΌEBQeWRfUFXLEЋa)Fr{4֔imCw29T>"1҅:5kd'OXХM أ((lABho4pЌ9$A*-`M3G\Li+Ec>[_-[@\q߈ [ w}7d2ZpdhZI>9ǎ ֲ[m[eoݜ? OGT]nyv;h%LZߌ{ PJߞY^Cx<ɒ S1[! sqցdIc4@d WFr4#\Y}$.h-CW^Ok6칞W"VOcVsg]OLfCC zT1y+9Fr'#[ycp.?!\SMHz!n|9D)ک7QLeHCjQNBw!VD/m61-rEOC.GrpQ!Oͱ]ow? 9{4D<3a-:ϒ}!H]bg}u$&NFj ȭOt.ȔU=$)8aDiɷšp6 jajF ɯHmd;Xlx8m$p2:'$A*5 TF{(!9qֲ؃˧o8\1)c|˃ۤ5P\8msc8x q=p*F-q\X"}6" >1U o߄;U=IQkRoHD女a /eF3Xƶ.dDo<8#wbNPΧ?-[^]NX^XiRiQSɱ:m_sTlS Һv@?{H44$~Is-g/Ț0[zǯ(ϟk}5šˮg jFnU?U|c1ɾ@ |< ʿ]6%ʵ%S̰9"*`vjꅏ*Vm*(^qK g1 0wxE ;z1悃:"$T O-5輭²+s9ʴo+9)crg;G\)i鞦F>qWWlDO P_l2Z爤y''HY4m/u1c y6V$J,h'޺yf0BD4&yBi ~% H:C?'7(u%j.'Oa):e49sRqgƙ#rh7#>kХR?}f|;Jh1qSkX-6`/z }Π mVd/ WCO] Y@kPAyݦ{;d6 d] uc;뜨QD.>6w(NP4OiL`VCLNor5gI 0k{HZSަFぴ?\Fi)@j&BߺL4 ,*XBES]@YydRS2dVQZdUr'JKa^giظì{haQ3DtG? r, DZ[ P+O?~$Dj#5ҠR@p.[$q34z#&Q!H$]jَ&wtmyM`bvě[CwIlG+mֆuV`o~K:s v P_}z}\ko1;ګ^\Sud])q ɿOԝcycR {|DL{-pYw+@5ʌ4]+xP>1Žf|y5dcD?o8IO<;<bDgղϫ{n(o9!O A4 ԉcb0,}dX~$ŕu7.8D Lnab"s`^mquoUHxRwm4 d K,*F[~]2)/{oebL9""`Z3~oA18]~3'_ .B:uheΖ]qPg=~Vm7PF$j46W@WQ( Tm*! St<׉ La w-ދ x!)$y.iM;t l}Y tmZ3֍gRxjF6*z}<:TsIKDE/fl;:#HW}[3E>q㝳p:fdpGF -%3W3u2TWhǑbTY_q#zK$wQ,E;jGRJ堋î45[jСٽj++j" 4E?sX/݈Kz 8bo)DB!hsBU'9.+W+_m{$'U~aOpe_ m/%f%ϫ>ed_d\tcOKX)EW)IF=bLkgWBC#%]1l!58hB z&0c&f8 S)2P3cɯ8poX V(˷ sho Ch?k2~ ~"gC,ί;#*nwe {D=Q2/luo\L2ǣ{%"Wœq+Ke !dI!{fO',%F Jft*zW˜tB+3&E+f"'˨%bݻ1ֶ1 =)VuNӿ㥸t,ʱOU%&Ή|lm3ܰ@ncusv' lz+oY5V&| '3Pt9ʙ6x!k(l!*1tvh$ѝx`p"'`q@_sZ &.iVޠB [1̦ƙw܆ktm3ho0,K(48vg@f=sHM޹$x;Umt_[y2!1!nB`ڷ5,CEMX*ʱ蹫uz+Yˏo%@gB\&yޭ|A_]Xer`$mb9(0wGݳK@%[xKepS#*T/ǹV 7~e%6}8g.g;/] 鋴1v6K;^56R)fIØ-&S cW5OL%tNK;Gӑ'PjMi`>_Nr|>sVM;ãy<6MJ5RDwP8XT|803ΨJ:eOF<7eNn~11QHQmZ˺pex:Z9Yì w9F$ dy'婜58id$9]՗fgU< Hy \ǁœC_8- [Ȥ> I`.1)~$GFՅnF_E]1cܩvv`y f1B.n % T/?8O~AO~Ws'l@#Q65LCtrVbͪM"liF.L`BZVŚ{.mt{]"|jC_M XN6.*5߭ jZn m~a _kJ| Kqht(wFgwJu>8dm(Oab,Gx87|A$D4tEЮ:@i0+#qz9ec,?b^Ęidbf)78fG!Oj<,ﵨ8!)DΩgMpQ' Zy "n9G QnOMağj8 w6X4x S= icJ,;$}00/ >;2MI}Ƴ!4%LYzvd4u_ćvYuˇjD?燕`tB4$R*K)]xA#qUylJ M{Ï>s8=WU%VcG}}GMaL`q%Z*8_L䥫7mеԃBs>,o?|gRP7jP(-|gډXn'l)p zٟ+#eUhJF"2YkwJll Lifhzlm5gK)^1Z)cƮnˮ&[ 0g$V%3{*o7GS=j0ANVۤ1Ca="-IzO#|TWoF:L]-GON2XO'QX%{Ove%:_ox6R9r9^G*|`ܒF=DsCa.ZgO4nr 9b-={q/hXa/eR 3q6Sj.%?S(L1͔:AOSnɓe(/ٹI*Uhȣ˼R',#;H:@e5Pmn6jEJ(!u{钻F2KtE`ZNuRUS(l}i.Д03"A1tӹ$54sV4P_@y67 @pz졏%iքL;e()Qs ЈܧJ$R蔆9bAdmc{ _#>N٘T棢H8_i|zw}Lo'vC=ёlqbsbFp{v`K7'`v5}E75M@9eWKe:bUO0wKKuNA+ǽNd,3O'!${]yO) :#uoŐ_r.jȗ n{~6HS>qπJIe`שz%Emp12<)b*:Z%U Xۂ 2^U`܏G 2߆~-GQ̉bXĈiٔl3"5q$gœ qlAzz<*u̲~]sQ|RP;DO1N]q8g/_knڦ񦇨 /]e2 (CkY >o=ב3\l )ht#uyeV;0`C-{ %$UF^RMz' z QSh?ҒdR~.`K|DF/rTZ}ܱ?4/~ Mة0,t9 ÷_ x 22 >8t& 7d||5k?aIZ bsèM΀RG'0D]"iUDZi,E{ءz'A\guI߳6ZktN~Lj5DhzJҫKNF! zz) @^< ^meڭd1\bJo5@4 V[MTg;U,jYm WCLrA{@M(xxK'6&_TlEW,ɂTɭC ͽ8z`UcCNOV:j=LSl3W;_`d>Νl^}@ܑg,W^.S.'GZe}w <;Rm=hZ"6x(ߐ dbɴV"=+t ӳGt{,CC [wR]!OĚd7ؒO4%$ HPDMUx'{^A5j#!U*F*f=>~l= @T[f ~-bSf`oEAn[ \%V K~-p +ыή% K">݂`\6ps)(?3o{ 0 L[qWl?:Ekj+QkQ`b6%(II0E̻^|ZD-yQv+d1gFSf_|YqZnZ}R>Lw2 6,ð@]?鱺O Gsڴ^1 *_lI(l;Ȏ%Ϧt^`HՇ$|K7(hIg=%#NKƉY~UrAN6vW6}M HPLʾOoc>B[ vy{HYWqVEG|/y-4BiYŎT ,S:-sf\NsDdFK Y["qW%BvGz{foR;dP|/ūMb [%vxUx W(7o@}.1+Ua`v gW7LtgkQggӜ~N3e/ˆt|td'55/RR{xAj#>AIkӭ{<(M%x1Ff3hM0u>"[iٵa2"٘bVŽ,<ΞL ܕTfSeYf͗U@s(,IdH+!wC-؝ ]j7g6r$,E Ma>s nidM$(G?k@7چ HT;NGӛL+[dKh B_!D4: Vغ:Z42-l>=ϙ,ڴZ?׌㿥jQ٨^$+6{[ Y>vPnnQqLQEC AEdgS^BSyAGbRnni%s Hi*CM:3!(@hzVCUj_ZW>u7ʦ%=J?2kXڕF6D;86nw n/U株ձS85m1pտR j l< h6[Y,Od8o)ĆѠJW6F"`AYOsE5}0 'm[g5"r6AHHu2I *ϗ$e\2P 8[j胶kqZ?W\DJ[1 f<1ݗ~t6\F:g,G֑`Ǐ D17 .+]NV'u{R~^T1xUʤ& MelHD\wR'q,Y#G꣓i1hw}a.|ҝ8ӑM:G')MH%z{Ƴ,3}ǟ0k@+,4`d鳙wF9CӋ_p\I9qw}D{VB }Du'e&)nSMۭ=5a5ryIv7зZTes> KeP}PS[hH n/k@s4Fץx˯շ:?E|qoˊ"_[4/2A`MMwJ}^/,2 5G-gstH FC$E6=jޤW̷mv~{sJ['颙2ĕx?sfCdP4IM+X( K{Id*< Ķ+pscy*v2ڶu5w/x,CZI;vd|RCj DQ*Rn IJ!z ˀqLJ-֜$Fi T HΫ8;"1*`WTXMYj>rAdl&^ʻXI(6pdf (sA|ˀIW%੥F!THӜ~r.`ݴcGK;,p\F_;j~ eJz ܊\:'S1*^ V[88FUvaNpbW``sxY^ȇm@@˹$*wW%͠BÎY%9S!83U$MeS1"x:JPsY_4{Ʊ8c4&@&@LI 4t2pQ8fj e,pvj_ əa3 ԓDo w˹Rx "^|ĞgҖ!}#;$,D{~]1f0; ~Ϛa7ăgG}':'9ju@v1E1'v4RӇv[QoQ Ob2L":mҺ. s5X-ey PifU5@̬ +#R7KEd ŢKoa9B'כQA{f!\9^z?e Dآ9&$P(ߟYx,J&<<λ4skSMoUk!DHbPJѮ:.kq/,+hg9B Շ$˚Ɩd:n4(Xyj l^Њ1[=xTC֛Ojh-$?p=vE3% {rkbҏMH~Nz'ݯ0H!./k,ju{5&Ɐٳ|{18$uyN0I#a;duHXx4e`a̽C\' .}VC"_T9z ѴM%[Ec亮"Wxk!$g;rpL !iHCCu}|n%GrqEpIV 5K`*h27m|n4fwr?F/w&z\\f uȤ,qMy7T%9{O Ԛb 5}KO˽%z7 ;4VW"]XpHomNPswc@0SW֎jN/fѽpzpcmRdt1 :& [ߥI~9cGoO?fɩ+=C>#DšڰjCUgt ě}*oYhcܯ^4@LQр`i,An8C]3sUsKGyлe`~>HNp& }V jt(Ђ ] ]"TԘ5TU|%Yh>ra>'t~65I9_?VR T='p`w' 25^]۾W,I4ETfqphE ҢeHW["n0(fCKOQEy- J7/pJ{6\)ݜT%pZ| O No =hf˔?-~'4n٫XGY9IP+wkhSL޶km&`L!cYD'g仆`RDzA;͊R:Id6{ .DIw۩% jض띲 ̺K#q{U $}ÈoXWLл\R(0.e$~.~d.ͻiXHFMd{Ѧr!<(@9ϵD N^-x{DÓ!#u d-brr~VާI6d@ (3ﮐ _TRpc:&L{vo_i=xA1 9*H>~N)ZC=.g(\5$[IhPXO謑4[b{I ƮZ?u9BlhUnh/NҮ# 4N5 * TGh*$f0?6.m?>wE,FhCD^&3w>M}E2]+NbD}L-!N-&&j9Zod[ê1ܶ{>oFqīrkFtQVMs1%&X'O+kke>gWA<ɕpk^#1\|}i zw[6!7)*]s%0*rXg@HV\mC, L6%?2T#>ǫ{g[NJ6/ r=㳃&KC -%V';$KSJtT{ݣk?*!mw\"-tKDd DqhJ)"LQ7TՅh`Y*DLLdڢNԛ|e/օv_j\UL ZLZ]5l_p8j{ީI=(W,7oPXY,YNaXCU|H2pfjgF,({?dW5L?BUYTNoDi 2l}u6PPqc.T2| /ǔ{z)&ѾKS w\E;BSk3qjj>>,pr1V Hd=N40b|0ʯ #29jl/BtU VK+M RXz2fR,HL+ə18Bap;xx\s,5ݍ# L4ѶG[В:<ٌ 3db\ֽE^QOԄ mU1}?TpV}F\b`Dk(}OPNJ1FJ@‰ՠUNR1*QR8CrIZ8yqnK )1_sU?{#7WڂI.gpڦI?`JJaPA1zfߓ(A6}_<4&hePp{r2~I{mrU!^xTHYL}EXjY(TSxu-( _`M(3qNt~VH*V0b&sV ;\…T^|,Hg߆wUy{ڟKc"qvm:훊:zP-jhӿ>KrBL8Z.Da ,̰&g s_N}IqE=#g;85p 5ZvDpJ%;]%7Cr@ty`L8#nnuU2Q{K4^5:փ1},j<40֗ÚsxV3zGOK/~~AH=,ex(w #sxDlmܲ®ㅸC;!MH qfˮŋnO`f#  tr HYb{HajOM'Xl4j- $YͿX(4 PR49p?Y9 a Q_۷=PƂA~ F? p ZѺ?Y 7'CU !Ze7x&lW߈"-mu 9A6&cgŮIFIA4Zwƿ)`v4>m@ž<0Ň+<̊xg^{c8?Zh'qx ='xf%$n8fȁ ,3Kj:ڵ7*1IT۳+3be(TѴe[8Q^JOٰzG׽N3\UbgRhf4-f]e^( b bm@K~vG *Ob&P|EwMBQN䶑=؞4zwU}p(m3*D]#ϩH4W@լoK EGw#FZuW"1']+oҒp}) V::a  ГbU~g.oYǃZk`\~6Pݝu'PX'I:è@Zq]СdrƬ}WC*0av@mkdÓ@GWAs3THb|eۏgV+&T]Dy>9P@ˊ=%[he} Gk7K}!"2;vC/($$ЦSA).Qg,`W-} ` |Bxxw➗RCa]c!-M~ø훺nE#HќGѼ) L O# <^c dњkWkm<\fPG$=@4OyLUUZRnhQ>6z=g.1B1tLD`u̾ڣ}E~gU8]t%4u5_̘uS4°4;eP |H|P20180c&[`3_h^Bϕڦ'*a!᧐/E61 (p[b5ќ@Š1|G Gs|aa{H(l S (l M7t_ɷ7-l&)J7vR["2f,h % #)sJEtRȕgxf=$Xh D*M}eA5FCY%#@&OݤՂu-B3𨀗RaŃizEF*a[x=n@۳M_}U`ŀy3]U$ vH͸ѻfbn_liJPAݿx~Ulu:m6t Gd}†ltl(|oQŲō[ß%=4^! y[G#n:tu>kkЅVU0n9Rh Y)>މQ*s,H%Ш ߉)nă_cǹ|?AϐMyWjv1Ε ~)W2_*&=Qwi`X* j[glda}~-oY\ʸv2oBI!g?SāhѧQHaF] hO|:]4ah{6S/4?9^s0if(Paj?ݾ~Bu9fӠ5#[jNҊ)ɯC<77cxϪ$E:6кFs{S-\ >@C^b;:n] iiώIJj- /R!U$V&Vv"s'?O}`owu%a:u(TGev,\dNx˄}0)(|P*mBe--_V┪ICF52;LUcl*i‹wz3rEs2"٣ՔeMd_yy,/LhB/. gf]9'&!QQ8Ho0vQ"][+5߳`f5do&- ]Yl{1vk`*g_>l'j'vhNv:"q4d7;%AkR/`TyI@BsbprH, q((%VBtg M}Ǟ=6K\>legb RJ715Ө>CV6>. ' 2M^aq -#Gp#w*7F]/ՖIDZoY1'+^NU_dO$m  Q,YLG(%6UFQ,%V?[PڧD DAUR?a7̫”~3ZJ{##@\ixSјTȪW?6?-9CQ{¿?wH޷۠pC3b')XAJtFn+G0&?<odSgtvW$2קsmZI4=;_fa~d|jm;5lnus(0Z&##+KyE{(]q#GV[TO):PJ9 gsCݬVMm^cRoWqle5|=qqrBq.56ƹͧZ'C +ߒH&e^QV0fd]Q@zrau9 Xbx4/Im`@M0qp~>"al,=u=[\A6a6Pj[p2Ki7<$=#5F88*~5Q˄%Ed@BU4~8yC@<ӵA v3V!B/6 \uO8w":3;[oR*N@],gH߱FOJ7ߖצ:)eUrkLɈHI1.IIiiތ#{:$~u4%pU0W:@Y/{3DxE׆Ts< y>/sxa<|#u7*MN34|oC38JV}F['u=^^O8JjQ*Xh_:EН|CLڵpŕZ,M.k&$ jcPw$֖ o'֗y6^&/t%P׍D/)<\.픈Mzpzu`fXTK3#`e"CLb)Rޏ4)֬yÿܥ1+#_i`2 \sҧ'b@ƐRncBޓ$ >`[k? F0y{YpIXص5gJ5dk`80"r4l] %w+=I)H:?cq vP6$RBs9#ʀHf-"% a7pBdhQx &F{Ȁ{֕ᢡ:``͎8[ #8~()Liiex1\?^@>M%cvm #,y^?͕nHWE\v*54Co'-@ԵNvJPkG@HJê ü<_ӪÉ>"sf*yZ!`ѣugFk&'HM8]NPDZuAV7*A""@ˀS^n;pd5 *ƘģŽ,%ݪ[^g<| ok_;}&8&X9`ߪeT,z!6\y`tmZn92L%>G:AV y@U Q2i&k4c&: 될H]rxӢ}޲h"OKA#^< n N޼ '.;gSrEZ2bV$Vp>\UPm^~q(;eKBv+Y`>*rOĴ#J4gK O1J"ձZ2~vYkLZ [w{\m7AѤH{ 6ظ:A5VL,u H} ] ݯ̎K]?E? <:JUȗG!uK8Q5VDcPHʬ-^8瀇P!*BU Gvæ쌞SB4Ͷ73[FO6(aIkB" f<в{U8g@!k!e~[ :#x C<[n2߁o/C2<_9UCjWo4넓l /VԕlU/_1w㿟itHy='F׹R}z]kJɰ"%r@'~SE+xԵ92b%Md%򗲛 v?ND vn3P[Po=. q"GNbc~yZ4Ȃ[LÀ+L}CT8rOad[ ;-}K-ѐaJWI{e*:r-Jj`\VƎHJ-ahE~I&8y1zNBVᮬi,EYIn b)>[I2Ըm$G/7eX)tZ’׭X@Za\C+%Ykz'(njME87yDq1Xӂ ixe͏~ 1a],kuzf1^-P%Cr^M^:U/2GIMRd8RߴHI%U _Rxc~z+(/Š?lcD2=mh2BVcg0xڣ48ܩ@6¾RbI\ L[w⽆3}`9=PhElzTYc,&NTJ` ?6Y'!Ec/Mg.EzK~ |Fʚ9[S6iYj6%0"#w"\^.?'u-[ G>b-7+ԇ20%= wNv!DO; tĊA/ !b&mw]V柗qHp3/܉7|63NJfEk6LT;3JJoҗ[ѴڑQ" cı]#x}IY-%aLŢb(E+Ƿ*e߸[wyI Dv]dל4n/iϳඟӓ9{%6^4jmt> v,8؈1$fF%pLqBۙYlE)no'Wz̓Xc.؃}ӯ{۪]xH۬dȗɶ1ޥ/~4HPb^j.|? L0cjvihMoٜ7lAE< 3=*U#?^qt6Ve*3= ֏' wN)V,غYI`M2uQJ~+'o Y%oʩzJ2i|;7Ȓoޥr0]?$ma!Ӣ @3N?(pF J`"ί4?*/lP!բd8iz"Z+Q"'њv2$rOCGjzּ l۽ >lWY_@ԛ*VGu<޷Ǩs?({Fv߄kʺr;Atێ>XVΞc3{ շz5pbaF'tތPAFz4) Byc#An!r*Ow:t y?9bcLMަ'AHlJBM+"ʺ311AlT>Ap<};v`G:Ee]\`9JU BA ˸hudLT ϟn&c )ćclu^=Rբc$AF=| -|4p,%JPg'jC$\f,MkQ+luMC7e+M4BHNärkdaQZK{qV`nxJoS"F._Jeך=жj2ܬe^խن4%t9{Oro{n+ܼeu;OU,:VuMٹj=r0!{ǏqG/&]n>Ԑ&">:<ϳz6vAi孓'G E;;ED7'~8l=D52M7! ×ӝ~H1r[CM3U2};$_{Rs]f).8 gv=åH:3y#?lUd${7 ~ Jʋ=+iJ+UƇh}g _/nnWbe!D/,d 15p5$Lc*RL}10 Fp#_%۟MM8x8gEj#'h6D0SD1&mh2 x{8}̄RH|b^5x|,[$r48\ҡz8х9+ 뿊2KfVTWAM(=ռxGߔw_<.х;SĖSp"F/Ԙ#OOC5_,(˄Ꞛ|Ί@zhD9xoHD3/™FGWꍐP4E{"(o4o lY%&[=#Kt7~Kj7Q `ݝMk,H5O-$NØczaeo?΀W(֘\_vDIE ŨAdT4ka|O8lٴn[j[=GƀN+٧[S >wC`+@吒pU"X9#y[궨6vb΀&"S~0IŁl m>.NA"2f[{ZE Bdh=BGA4ҭ.icVP"`]P݆g9QQ*%Ctfqk4!JBZGY!aeߔ=QLG]]n 5T4иuq7Kv6)Y4) gέ֦P{Q8)KU _ ,8DKYx\N}<>҈XpP OMSdD+dbܪ`;>R,xLӪR7͊ PR/R_wM kU#8CM5V.W<+jT<3`sybV.MwQRlLxzys>aL`*87~7* ULtkY!?4yh$Q9@gva 0|cl3Gx+'y cWT92G%힒Jj0ui;޾25/&Bάۑ5}R}`?iEl 6Ne"i?+yKqz{]14@qh"6M\Ko{$\ UiSf+} Є\ӑ}ClLSRSS yApL%_bt*ل߳ŕ?.N qz7duOB/aM>R>_8׿AU[@ϗ/&%8yVu!cPVJ-L }O~W˚jpumO(;q9@w̧=?/zcj~u4,F:yKEl#TqŢ6Sw01L\w@~f4;~X[Y8#ʊ.6"h=cָ`CޣƩmiUcO*E+)> n.=6y-H339}E˷,fҘUY gp캾c"53"k:q aǏc{k,iz9.GzF']zY6t4kQ^R2=l @( %h:GL){i 3LtΰMr^GuRGZdic9U ˇu:X0X!^Lʅkᆣ;7ĢKрқ>èd-7fB(=J hr/ |[pU'K%*zLY> /9ZT?3:^n%E6 * ,0n',QѳDW!!1N6 .go _i"~8-`7~ν1ٕC`_a;pۈOʱ3@)nݝn\ԣvoo=ABHv1v֗)HЖt+hB~wwM̛~x(*i2ΘK5N=#wpcOz>Ź qJ_ם)CdDʘ(93f6j HW[Uџ</MZk a@hFOBMo$KBQ[輄s[<'wP$22 H0i0Wi(n"KO'3^,msţE'*?_]qHTOyҸw' WV`~@ ӵt@ho̯W{Y?(5*2 y J ;3ޤOx< lԩ+ d̢9Xz]1̪NT( ߸ jHb(ƎPk2U5(RqW)V6t*/DmP}ʪo^3,W2N'G^D;o JyT/E nr $' (A^sfBJ8vxeZT2;Rwz%3Jv56=rbM H<\˃CQ#ʋ?Nl#sR`[P{7HX pxo&+\{,o'hcS5Y[̒ KP;Kݦ #H&bU,㱀@} eu1$$rJݚ}Xaa2e6&P;.39sPs4'C3}خK1QHlqLa"\wIߺЌGrh(CR.O] όUP>~]ÐPf…’ XƙmBU;<5I0}u ݋& 7辇Ө(gێ:*ȳ(XH癁Z%=bf?k4&VnGvzp Hm IO*M~y oA794t

B5(IWES֍y7%.kڗ Ƒp2D;)KZTfw.+fh5ޗ|KCF)Gyɬ&[(ʊl`fHk i a34K;92dl2ȿa _x1FX0Z;y:PNpxmNdVE\fbd7V}/ݢNo0t|B@5Ƨ=awIKDKe\N}}P<^1]8Ydcu(=FڥH}{Z4QdO0@06N_o;gזׅF\g*wtg|orJ'VO9V$3L\ eL1ؙ: ϸ,(֒sՀHօv"j.9B{\bkX~ 0GԖ`S@cWYUCF) k{zso15wĝb>T_Pdwed?l;ٜ#qɴT{-NC𦫲֍#9(";?չ4P 1f"#A5l붴J.*XGC9dN'UQ TU:MmRS"JpP#BPkA"q˅KXBOq-U }>H#(,Gh ́wVEғɔǀdR$D҂$4~NU#DfsJV_$5I`e5M\͝=8jIG?K{mH`}@ cطl<6aϺ  4L I`U\^~I!7K6J͂ #(YMesU!< Q]Lxgƛ}K8{ٓp#(O1a掼% @F.":?7˻$# =,9HyN~X2Ěgwޕ'd֜uLgZ<.*%A<b@#D 5ݘKpD]NKh+YF@Ӑsã5`$B{YN_Ps׌SdTʬ-؝-yKɯ@V w\ @L bvf0*bIz#'S˜F )$`uE-$0&JHվ];tCU u[oHq$И9Ƥ=p^v}a(d_ʦ^]mXTn>\X;]zLvi޸#Q4de(UKguVޮr{*0&*N+T+vzExdl9qP$\ulF%%\hR_K0KԱ7޸?{`Q[D]YP."8;y!\i2G(M<{BܞG)u#A\ kn/vб:ui~L a}[q3wpl)\f0^\̂~EX"* tmyhVWi)y FHy񲨂#OX H'm#-K0GK(!y96E`<yU{̕_+dϜ_EMs\>z A 2`xErLƘRIa|U|~"Eǚ£=H" γOLk/Az8ءaą,Ɔ?,cii/"6֋=Rx} c3RN(uj[L]3Χ$qgZܓQ 'b=d9\`%9j~AIL`U5&`'#ז."NNأ0g%ǯvdq= ԉYTF| 7)»qَAv$@yJIED_RoI0ʤ#)oC [#Fl0|-i}:w^@y}A>G}cI\εmf\ru ^9ll2:/'{myfy1'T,$PS>}Oq.@%Ix.Y9#fő %9wymsNFx"|OjJcBK&?UEu oFΈRVSE`ye! oH=YY!he8Gb 2c"6s5@r|ӑHm`i%N%Ђ}RI{44a/@ǯ 梁䢅5qC*:GwHcw;ګ_lJP^^5B^Y}?ڋLeo']|3\]^i#P)n 9q BBlO]id7u&R~E^+>ٺ}JX//DK* E+8Vv{׉3Yv# X/es&?[LsYXζF[wͅF{a25cմ T>`" "7y<+%jN׻EלT ð8ϑfcVyH mO֐RςJS{ m[LS;ԠKTV"G-G}F[M Y qv3IiF`$vPEjkptL,JcL<}DXʇ+BEܱz%;_19I8ګJv/ȜR}1Ј{{ Q"haM_VɎqmTz %J.VѲ =.$â.i(`.6rS+i^i F@ ~C 8Ȣ/~̴mܧ#'HO$|_q`@w=YįyeY,((3Uűq|luo L['H)gR.N"ŃU]rt'2!m0[.P6L(k۸TT1&uysr*Vf{4Bo-Ů~>DkK~Ju[*"v@]`΍ߦ 2Z@gP?nr%-#[m8f]^Om5(~J2TnrI^a(H5ѼoDCH\N$Coc̮#rwSNh{k~O*ڨZT*)jjw9F=!ڒ:w88OG`ɀč(=!ʫI&; ~|&kikgyUN< 7 *4,(gTugt3Fأr LKpXAi;-:d TҋXk4^5] ~vټ U> Ve&9B)sr;1>$s GRh'=cFғ13jAZ綢y-8ǻrT5)E.m<bBls*"tJSUNe[3;Dj*@hFːE4h%ȹ@ +ܦ@e,!b/U5 Ӫ1ngɪR]W_ʱI{ǫw<#;,T7}e>#Se+}3kycp|!~7@ܺmqʏ:.fYhw;OxZFOi _@ "X^FSxK1B/o1}{Z_&CWvL(alҝܢʶB{;^8L2.݄LSX9QRt)W _hd-@d!?[CBn4el^ѧaѵ zSӚ_-̈$$7k s3KqV=\}7;;,֖#sU[ETLmZIsB8.z.'UǩiŪlzLbHY[/oaq7/?-SLQ4X\pܕ5DJCxݾ@Ms4i3c(RQg }Z ,_/ozׯ. BmߐCu12(FT1[>MUXU.s+s;~#UD5>u'& 7Nn{;sM!O-qSV/vnit/J~B*|.@ږzMcdAމ6gb㗲-p,h Zo|Yަa-h;N@oo0ͫ3霍F ݪbyٵ2jzN zt׏tb-8-ڌK7QyIK˙oDwgo~hUøy-XݡۗglGHc4]zYۿKDK|Цs=smP߆`Jw)JWuO:wf 07ue#v$ Ʈ)+)5pKZ 7AKBCl ^{ech_sǨty x͘(IH#Do͞8ڱ7HR7F6pY5FÙO!3O!18l',gԠ3uVKlXJ)7f'1Ȱ*+ \fjؾtEALbl-V5aOV>, b{6=ՍAqҪ4hX>sǀb20 D*J@}lñVR1HX2 D-14vg:[xgxҟt#,5ΚxX{K4qjbfۡBº)~eD7l>*ݩ\{phc ös\ksmZdulE^pVq鹥&S#xh8dE]8yD5:-cf>mbBQeǜsUqO 3,Q1Vl&w?+uvo7ɒםstf2%YuHz< jUaYA1_#ߓEb{ q QZ:*3~+N-EW3c9zr+>YRf$ {`ӊ Q`_Vft?vՇkߣd>|>0-71R?kh:?Y?j 8<ĺXou}71gRP:xVD12#w] 42}?2O15n-9Z;gTґQCzUJ31|ZpHbL T6mq²IMas4Ӭ|5k:#l1 f 83,+%pz=!]ԍ= Z9M(F,L#!l=,0ĘG070w@F:Dߡ~xu}<ĺn ۇѰ6S+u`!dW~#Xb SugM4S ӳ*)HA4Dcj8)MFC\ҵ/@akmQb3jE봁OWz(݃'v`^->mhDoy2~R5"Ϟ [ mpN%Q]hCCK`V= x/hj^1Mc&/ӽ]j֖4ɴy R!U2źVA7}ipU]L遀yWoѩUM*`;ZDO VHYo7\'%FPwױNfѮb "vc{P1{zgQ̼ep?K& Ss㘕r#8DP!L%>QM .zJ,WN%wKF6^/)#Pѡuu>膟wة0bÐdl#Sirv&&X1RpX߭لEN)/K!kso:hMuW><:c! 4tmSdEH_29zy7>tfyҳ&/ /"ÿ}: پSiuIƘU'%4yE]D`CyBKr ۜ(J>MU-Ÿo{M"9Wžd:+6֩-1w^mP!FecT%dnEPҥO5f!K95rs^7Pop!:3 ;^dewa_iL| Ds:iΗ85swa&xhJAZyBM4wh6sۃ,TOUlԧNg@I$LooN6uDa9ERO}4O.U=楯JV[ȧ,pjdq֨$-QpΓ31Ƴ )QJ|GR2ϢWA& t 1X+{/2S81:m|LT; U0F\vQ Ѫߙ2)k_n)ƛTy(/IY^K"`-}E. NԥTq[oʃ=>C:l}}#qI]Di(Wo BIHeC&ƃk~W?<\ [rxJh5.gKaisք.84K\#;N.*X73/0,2(EM쪐Wo=BƩ^JgY?$T\]lo3vJU^#EaQ|?۪SZp> n2?׊yXUH[Y温a/~9eirmm*eewfgAS:|E٩ݓB03FDYV] 7*쓉?R^/}ƒ30-8)E5+N RaWYŝ1Ep ҷE$9~=i3 ]OY;ũzTF8#k"U NhG=ϲx#

U5ٲkiJC3 v2Y5n\#]X& +* c)NK%=;Z+U&ėZ8\\Gy3z=XԺE>)JC#R %$3flonf=-O?ig(g n};De/D  L8=<\ʨ8Ƈ9[ sOxC Q#rCVQ1ߺg.bٕzT5ARm9+FTD0MVK)&'u$ s$6wYB+8-|9vI,0ꯜa'{Q,85:Z:)bBg ʜ"-}zÞm֢*TH)(:U:,dB=n@{N~UExNG[X/S<) 7i6Q?:ު~e2 ax|w]b ܺx54ՓiUR3&`=vHySvMi0%DOqz"j $i[VdI!V@7($s*Mܾa*bFREG!O\kOY{cfّ]> OC&؉PQq}鮈æ E@=<6DʺUy*!*6*+4^q_q^O"&ixkU,1yQ\T> "iXq-M͟Ȣn1^ES)cNzA>5N{v"WC[ OR+1 4B*W?3|UJ?n"dlٕ[HbS`x51ݜK3 %,6.;{I^d*ڎV~8&2u}4S;y~-eOq mٚ_id]yK! g5C)Ļ*ay2^= EX5#F?3}tʨO发;Yf5 ]k:O:ihp5 Qwe=XBA^$?U+LʯC!fO~ w@KyȜ0u?Q>dTU-T n!}S7ŽWTd\ӂі>$R x.Ww}p m]a$`dZ)vaEfWyЦz7ץ$IH3s %{IN'YTYM#mnNVtkF`4#و`9M<ɧ8^8 s@c5K8$^x{Ήz_mai.׺쮽 >C5ٚ.G7z^DvW/nATݱ8u"]LHi\mdn0D_}X3p_4TёLdo䓊CG8N;<ׄZH4Qvj6[2)R؊XqغKv/#yM27&N-\ !8YSȦ3 $m`斣Uz1 2Vk)t8r?*4u+PЖ#2By1 4BBxƠLz VSw鏾3~|K9A<8ܓpL#ʐdXQ~Sg{#ٖ726Q|)I O Q(S ϜF|VYYT)i_ZգIڕC-J55:ILS{n|`aG-F[a╃vsFo1U'궊lc ܲVOM;*緶kgCJv^)+|wO5sb᧐+ OۖqΧ I =9Y%F079}~q#s@5wRReԤg/An)<ś,_[ mɫGtlHxOB6?H@*Ma}8ܐ/V Toh*),xQf!{_ }]ccN!7>/grNDI) Qcr Z=XuN2MLޟqmٌu鬉<O+q/ C${<hopeiN!sMc~sNR#|C9a(>a f a\`šn0Eo!2/ݞܵa4F! i$ct4ԜBἶ3];z)Tim&R-rhگ ־oO6!UZ~:x=4|Y: gBG,QD2;5Zk'&:HϨdӺa;ڎc LjbU ]1xwy9’o+hr+sZ4؍E<[TdҔ0ЅTVkoKxcc "t#si?TAHpfq3>]qd0ɶYߺ1Nr'f_Ecc蒲-9Z}fٵUM7H F,"OZơȘ9]:]m_<;UL ݒlrcC} Y.,[hjQS&7:uZQKyOg{n lR(I8eZGߋû[J|ƣwyl:^-~Fӱuoac}9ZDw( kE.+AXtZ`5̨;;4On VDVD'e/um^GJn&zBO>?1?34Qs`ixqS]}ϒ'HWeQA߃e7$>01KNAi{*oA*ӳyGej4 A2ONwQ&vL-4 =6Ugq?]if;BTsd1rN0pXħp恒ٚ^$`+k4P߆"lȂ5/,&O#~$͔ٺlCXVhH#egṼ{Rնv5ř$p>o~xqVͨInXfc~SZk ܜ*yVULj*٣ZĻWuĥU;q+Yl5dpsRtaʫ)U08N8,-l5T&nuiPH#B?>pg#e΋)!st8.uh {ez;^$}at>bR3Ew*$C?©VzhT=4-P_ouN, ڢ6' Xg5UK[r83h# nX'ڬwlr=WnwيN7rvrIst9Z*r|O" rLR`*F"1rM2EtV,Z\~AnеuA&c'tTS`'IMڸB#6(&5נs  [M 2?,F*=n׮{p&@d wITpuz#TlV@hͷ℟ s MvJmCr 9iJ oS4s~3Ԫ& n8w(n.02 L7В,!Qe { Y&,J$ͲR,3tTi5"+ w);9*,31Lp^c& C,UMe=zg{YZ͐2b~gVQ&w>$.^L =4Fz`HE=. -+cWtKKԌhW) "SeNa]wnj[@qhnU 'Fۑ_Fr%׷Z}[TecHkf7ٰT7 ]?b:ݲ?793[\WwO?Xbv#/!enOp] *&-s qum-Ò.A ͼCWҴݡZ_']~!1~MSi)ZgT: ]ߛD$:ldGiH5o1%c I}] U񌹌Ƭ-; Z>XÌ4\&[mG x FY3[%YS1V]ne+J%A-OQpI0cݸp\_ƙk&56y5ff%^s7Zf{9HŔ($_7Ϊl坚c<+j~cꌿ&%wl?Wpܛc/"Ր6=Z$A?şQƌ|- /Raultd̿ݬܤnlQ.o5LqĶuphOIw9~zGzLY OAR3$-(oHd]B4\NBxbǿEǶm5{JDf:%ƊxN˯ӊzG؝ e;c lĮ !#X)GD:bco\DgiD_(x(œg*ơW}lWF hA`xXi,(kJXLt]1LSW4DV^d]A=DRW(+3;"\,ug0t+h YtB{hi*ўՈ\dEItB| M1~L)[lgBvKS1Ixusq)Qh-iK<UVJ-66s$O􍓦8TJ DW/<گN׋7^P^2ƨc$:D 8YR)kv+i;:eŽ} i;'*Xn_^>,ʿӋ ☹a4V#ITIvo_z'җ0wsa3dD3 {̷]4fy{^@VlGcc对j RVh{w66,B"Hxxm}3ZE,螶}!~59"qy[~qw3-h ȒdM鞻aTewa\0ᢻ9޾i"FSc{vG~K0+_@&D&&~^`;I7$X? rdzM(wd.ꇋ4J֟VzsMywJtsz`͗f'[r,IC7=SgI'Dj B1MpecI씪{܊ao%z݂MGcl}o ܲTJЯ)S,il@y\h=W8RqdgS^/_[{k?YˮR@JAfH,  KrRxYuGʠ>yDg2վf Qzx+ج  CY΢|FVLXu2wGS BGwV> v2A>]ȗ*L1ثyj|\n@䖬QÊ^rylVc( mn/ba=?PFsNJ&id$R׭|{2;Pmq_03=I0Nozgw=8r>CҷFM"Y^,0@LBYRX.dxnzɇٝ:#t۪0u|sQ ̋7j%<caN٣ka|D}$ؘc* qubO6HtGFb, .0>bYPyp!3;fg;кdrv!B\GA;OoKQvYy_YqHJx *kNz_gG+q4Qo< ~#=hQjr;^9FjfCxj2ck?>Ym=fޕq96 %`~]⨜KB>ueX`vt 0fQn6wa%`yMZ5ij|2]6xC,EPE,YFhX1AnǨi:Dq*r ɵd{._"Z[<"Y2b9iH6l]$$/4H P~㄀n:5cC E4>T.yu8(m㮹uVږUlj٘8uJX謣&J un(zjx Qs2̅ 9"ǣZ9|'7v54gND$1l\Q]ϗ #?fV ;"(5:oCzk&B`4sR(2<7V應q!MfrGÀH~^~}W` Recj7~-\+n~ѝEykD>yڝyq+G2~i*[:9- G'Ybq>∋,5$GG)pOg*kiq0A^ČI^I{N*1X@t)Q<@jMePH|Q>N |H&ub%ơsk̔(b'A3v){qPjhLP!* D9Z~lYCYRtz)[roYR$-Y{q:G$`G,ݙ+Dxvrjd=uanC+n:6+.a&`amG !oC݂PNi1 <eF| ld# (PXA_ڎ+nuPz~\)mkG/pv˰v3%˱X#"M>sv֑qfښUn8^fvRڦHB֍paԨl(G3Rl;L" alW9?Cӥs2d &QB)?E& R/S'"'%OzzKCGm)Xi0We*̒i-^ߌ5ϐ( ,Yﭘ"𸧷PUK+{y#]-xER2OY;Ji/2m$ZϾ95ۀ}܆'bz}^pఎ='FV,I~cJogw e$Н^NDW YjwЬ׺$,.cl?@L].U?̱6@jɵ,ܓpD;YP}VkBEvq11yS rrĄU5*XZM; P4bV!GomFYE 5 UoH*إرҌylU+Q&zo!WcZMٞFchLk# 7 T&q'w&ڞK \ d.塸;7 nFM`ԣ lR mGi5-W?msh6 a>keԇ|QƙQpYyl@5s&*bo_7\v'т97kw}qc![Tqg|5R:䱇q, Pmۚ5jSpo3Tɿs;J!\H4 wO IpJ  }ڹc\J+IAFgh)޸doхrOJD+^y%oOCu2[~UO11vCtcfɍם#( H HL{:CԹf2ؚx൉rs;=ZQ+DŜ,@4az<7sd ozEdv5ͩ0C; "3)! F:(e?GT>χ Ta 39.<ٴi^a+A^;<~XUǑ+ WQ3/!=z)a=MV]*yHeZoU MPrLc4zdOP4. mWCJc1[hvXz SG#晹3 ưZR\)PK!c,&`}8Wd)q_^t,109Þ HR 36 wA0S n<$h;NS^KM tDpl_CWv.Esߓ̱[P)+ŕ:dvzģ'i|wRV6[,quBgetq*DR]RƷֹ%,Q*-ȎĥeEhgK*L+IiP$}fMz֘nM ]sLVPW1xHyngwcsђPfV4ݍ%+ay/]-fdσqN{KzʘO!n{5 j9'qLUme5\fK'yWvXțO}7t;)hN+{BUθbx'6b UaIlHe<^R]i.֪zoҤjٙI2 D; i>Ct >\aۥM #U:LSL_s^\ ԥαRѰ2!vxbXb%~<;MeJ-=V!y]۹KX@R.fP.mz:e[Lj{Jg)Ղ`vE7{,_i5Zo !odŤ^TݸY.K vXeS${4]<~~ 1sWݗ$ߘ_1vKm|Zk.WU+0ݤG|MϢFFwbASu4XEIMp3k>e1|oQt>)+ҽ6?RlvTvָ'<؀Q`Ф ӨN#Jh Uձp%{ :Se"uY%]G%۩IG#u.gĻ n^YQt\VPy,nq eEBV E&G&zp11f`(P ] x``|c6%|ħP~v3 Zo?pZwj m&v%f~aJ/F2Տl!4y(n$ն5킄TkG偔PPp팆:Ս Z!cU; 2X->Lp~xUI(\&! ό/Gz"[Z0qʍZNҠq0+-Du;E!#.X}t"oķnM6}>V*w:V?LMd];Qχ(*XS9!GzJqHX 6N<4ϗ8>Hsz=v#j6ovҢrrTdQ "6R1d&mz>?g ˵K=ɣӯ0 ,}*ADI;̦ll[V&Ol-4 z/c7WGIPܩ\Pbx7Eblp Pi?v2Z^M&1呦m*x&mtL".LZMhe۲ɺe gN5 =U5";9Lo xCqZlO:吂]Y + rd~99w<e:USJ˞^8Fi9B[DjbڙyjJ6lP Gqy Fse@TF%~ 6znQ rF6YqҶgZ@A ^i].,C˅_%KelF̯ⶀ(^_@Atg27)ROk&'/)cÿ̸|n$b 7z-<2Ԟ}&u2:)({kY_)w_@M[ 7/i ^>݅LVk~v`,}ڳz'9PCny/m M3COlԺ1Vܮar exZKn(D\5}߈ShC0ʖa1~n#Z5O l1z|3Mzx"/O5PaUF¶yv>$)VZrvFkҸ3\:x ԽN;Ǔ<!|ܱyɹ퐌+@ʌ]jezj;#ƾIK ?ф-Ӭ}ZA"ӔMzf0wnVPLߓw|C+RJgܒv)wN d$gGҨk9\2^hr%!RlA"1A<7;d:׼QGoE4F#wnC}e}IN=hIߕ.ruDܙr4I_dX7懱 9^SFi#1E{'""p5:EGQ e@y\/[ :Ŵ#i.(~WI ?%`oW]8C(n߹UD\1;aXs¶|O*W2[QTo[}T+)Y|\A7QQy:95I,Jϸ+4Tn='/4er ԓV8cҘ/xkݶh5},kQM 4VK6c=>m3l,j`U|t7B7ι=cw޺WؤBzW5Y O;ӰS!vMFwIy+K[Zg#@8݇>xx.[*@E_BHCp,LJ߯tYJ;H2#.eeתWmZ"Q䟈.m :JZxb @:eu5v;?ڽ.iw)fDbjNmq.{z&)hW+J5ٻ]SI6O︮ PvvTzN4@HU|Wm#QDDG48]u|tV@- ˹vjOvҋ vX{Tx ʑuB%V`mǒ@h/FNvD~ӍME#)Y)8ENH ,)ܶ"l ᭇ&2pߚjήª''biF#SlI/aH?J7TOYV}832mA`e9\O֡tY)7vOn= [WNbç*ыP 轏&@,.9Ji[j>?hJچZ_KJ  IN^%z.k4Ca Tx֬N16K$ ~K%Y0㏮IwNgT6f85挼w%4$q?g _"-ޛX@l*QGm4[DG4: 54A08|9hR`*VҺKD=AySLKĦ+֧ 23$ c5l|`q~M s V"aS窚Mg)yT>h+- 4mش+=ag,D-%?Uy[GQ zL'6 b9$Flc>cH߸^H"ʒkN҅͐Pm XHڬD S5\/]2Ki ~wـdvOu* pet[f6p|2/Cd:Ƀ( \Kg%RēqUѮؑ^z}!Ʃ2~d?m&cp Qp'XĽx~o]l7"}͡.ڴ&)MÑjjv 怮9!~C~Txv [EF(<|h5.A͉5:|Pa+:z!#Χ֔7tOvת&U3MŠnΌMG ;bf\5e{YT|Jg؃b1ʅQ1&OBA?xRPK_m/*/V%9g۳E@_aQZBQӆË!tkR^ٙ? [O^5G^$ψc nᷨcYr``;quĈjw2D䱖5,ߡ2$?Ͳt-{!^:g>"3vP3 л3yKcC4jE+4D[8!b@i ]bFTzPx{P/gAi}ꛩ6ϊ#ҹ9mWdfψ{@gIӧȭu)k44 W5xMO#xI fL gZG8lml2r.">pZ9ھyYg"'ʗBW " 屽}fM񗯚Σ  Cʓ1U2гi6L}w66ʁ12?gC~']x_&~ONr-85JU@P q*p ^'Sk]٥["_͘(R }.^׼w\ @z1ѣ* b"3ap,Ify}wuddžksnmq&oBT@(/FJ|RbP, L\wК]5펑2jy/)J=p¿ebD6fd+ƏWhF<]Ži\`%S~uw0!i4sU #G]'ա.qy['3 + ,,ajBvvbLi#b2@I) o2? "?\ȱR"U'b @"s.ChN7 nipN=6wm;]ᒳHIGGC٘&Ũ x+y Ȟ6\s[V#d9B6UA! E hq@p\3ÖUdT6ˑE4a֖H3(F*e}|@0Cau +-ZqkLI?Qs*-mō7d2 “!8vĿ1%h#RXQ(v3#j((;rzūk|-x"VЬfZW #ih )'O\m@A4,.mN2h'!N9P!9&U^W^F-M}b"nfڦ0zGmz#T`Y89QH!/_ NQZԕ TWsVMjHnK|ij|˹IŞO4H)$h.9mDT'|9Nċ>'TZl"T iXA'ٲU}}']T@=bn$xPXe{ZxzS/oR,Cй&T KIʪᷟZXsUo "Aka'3;_6M*:OklJI+uwM4:#h'd2^|B>jۉ ǠnBIY#Fwϣ:!!Rklpzp2K* EIԾh2BX]B3ϧ~씮:hl&VZyykyISoEnۏxINy l[CB+39<#<͌+4H;=aHo^O_*&Kj5|]wظJ]gB61#1JcϨ4xZBQ~19$֡ˤv3Q^bQ,^j̦B>"صmw6ؽz $g2trH…"-4)~ wsxpt[v8nwl}y㉓ulp&{u@Yߧ"aX;ߴWNܡ?6fgǤI/*N^r4FLx}#"ڗMHfnA7Oʠts;vE YJXH2SLhe~{fB.:z5ə*nmN\I1 .*m#*% 401+ ;]0`yNTJDɻǴ&Y6W5/$h [mF+RV8/@#.[aRHpi$Ƚ3>F(=UB9NOFiuvsTHRD#iu}VTl0~32 2b! \mƨ#w2rDE2μ}DςLi2ij zhy Lv;F.fCľ݌5$q֠%zkw~=m>3^QJlG=]U`t5&*6^v- F3Klg\l 0_K_cIJ>ʨi l#=eCALAvOEin{;9O9%G,)nνLz. ۊ >;;ߩ,;8l<=CžUWv?4/?yr>`y4B!+p7k3]i1e%KWJHs홂 S0ٳJ篇{XQ\%7^Z3'P\Iv"y!R[Y"`-D4m&9OґAg[nl~H$aqm׵ pN}E=;V~G%ܬ%caa &_%R^FԦӬLZ4 Lf-58=nSdjW YYD"Y ɕG?"XX:JoFb?*{bĜqXEM^nH*C.ЫĩɲMl@ޟG(:U hF}Xj~V0dVyxt~kDj)EGxenK.ZfoN{#v>o!gVܹʛL_Kl L'p+Z5}c+@6$LpQ79*#pW\njT.ci׻ZEEVvǹ MQ%5~-0G׎2B[J1 G~KY~v,3bLld'lEn|XvXѷaUO{(Op#Hڪ_#.Hh> xZ;z`jz5 {ēSLPBwW5L>4)f`.!GLl`K7/z .BGbϧ>;!zMjrV JG7 =?O2r9W^[8"1JY֡ζwÎןk _}B(rяT4&pxrX@Ii Aijgl"fjY1!Y)IMw(<ߍД ssF~3aO׉dr{YqHDX"D}]R2xPr2&*qQT=~_!S|3ÖJ\'  km:.rjp+bk 1$7R f6h pȿwCilyդ:!C+MD{x(Yw?(L!A/v<%LaJ>Ww*$z |Zad%c>az`OZUX*r-aīBW7 XfjD [nW/k:/PE'W;ã`nȭ3sP[zkz}'D& @X6[n|)3CxlvTR0a:׮ a.IFQ԰̒W'ϸcd_J411!/#&5<2!=ZWl-EVt7j MfxXRZW\(b}n}а/H|zЭ 4]/+D)!xul8=*O⧎v;˨rċR1Q(= kdiipheάǗ֖Urpg?C1) h/"/ѬDXP%DH9ѾTJrHR ⼒J9QpRKp$j̆PJ#&=7v$2J|1 #fWfE*RA Dy|p,`!ۘ|ٳoZv o](){8.'R/JhIj>5r2 uVѰى$Z ?!8[E ƯK? ÛY:;yelI.%^gOcT / Fq$%9%Q3&~X֩w8--VZ}"x? rBj'F %јmf23_Mov6b |3 `롴# p泦% NMXažt;p!h=XǯWLl6} ȼLH8*钭͗#_ )Ch0":7>Fl5YeYib LL^@X@Sp!5n_12чj}J7g 2pD6p5m%Zݧ\qt>h55u^L^*+<$ܲGMv~J*%&.Ţ;a\V[8fŪip]MDn _ք|S^'I#;Lz3'`. Oks-Y ~%; o~,&80j6N|/` 6Dñ0U&xu.e?{Iwqr'z4KQ3si׹?4^1Avo"KMx7!#uj9 ،cM h!ؙ8$}:t{(jޢ&&jnq;cIآHcA3&"'?mfA8a"DL}Zx75 7Od~Z/z緝`-IW1KvdQcha-{/yT:8XPPDΈ-Z)m>rV#3xMCj+#^_[ƨ:D{f9hpv;*Cv葭"5%lNu" -"߱01qFp;>Ve"Wq; &P6qgI'g"R1哴WT!}MwinىxejIV$.ACß}0сr)x" } oŌlUH!VI>D (xrz$ٖ~J:$Rf ITmؔ ~R/ژ/O:y._´.j~D$KrE儞*@O'tD0L碶k?Rby tY~1j5A!Y'9B1ǩV;z1PN\_4&s ½Okj{2ƔTi3h] 47i _(,KٸKOK쟀g`x `z̴ T5h7=, ?69 .JmM>oNU3ˮ FRHPpI G*jF1߬(1_=Aز&3/8.JTtΒ]9y.I&<[OE-pq}Ww^9G_̨hRD>ɿOb9$(. u)HTx E t3:&6ա\6/uKw,[k!fxyMQд;^ɬyZIp>Doòfv@Ơ1ٲ^Zϥ@ʾ%X8R \;1x;D@'/a}P%q|;#ETǶ)A\MbKkouMw=gfF̄7K͘[jw0||Cn4HA ]>rζ1Iؒj:+- hJtEho@ vRwC?xc۝wiǣ=|Dc94Ns'!"z֮2bv%WEuSLݐ>R@w8_me߲|.{zRѥ҅WHa vL픟q'?3JN"xn>

x]΍u%J%RLH{fOEn |lj_+GwR?HTUv$X<]n\*֮ufӗIzWsYӲOq%0{(UtˌPIL.#z>XoS{F(&rjx/_%qgћ?N} O-E/)ձ7fѨL+vJ_nR/S~up 9yU(sLR93uh3o"NUPi&mΖ#-ˉѳi[{P<%aI2\Hݟ|wD\Ez_f+e{j'ᚷ2B?CR/?#Ρ1xA´?4cK.3)}*Hݱۺ\E>պ(L]>SY kmמPYN)AyJ."XCJISYyn3:JFL}$jY'P-aF`}앱rT }g]9trz: ߧSIF%_R]\x$n<0N d`J1gi&Bvy]0%/R5;J$)\sb?K<(Tjf?Sz0D뿭+هFT,Ԏaa~6Q OOEqs?k-BQ2b:?Š:*p g!~q U课sxU?h6 J}y%pf&9ٕaTI$r̤M'bž82T,; N-ы[z[} "wr0F$5w~H>7 TEZ,D'X{9ZU{OSPx A2譖f!*.BvbT'`rS ,z1[>vS$ٛǢ>v Vv\'Z>j- ,rlSp"LG'|fZ5aX/jäY#쏛]V=$PcA4q7Ϩ_-ƎC'J̡ V%sR\wtXBP=7*e{yzMA'EyRG03Aϱ?1i1’+[Vxrml8ۏvyXh!E|2H#SӓcwU8Z;pX >˅VpT45`ݐ1+\}ŀ'[`d_$09'h<:qZԥ wJ#E r|ϠMu&)+2\%۰H҃t +sLP!0Sw'=a"-M @ a%y ф._X^!=QMވ]+m_8 pz܊ʈyT=Oxd1Cm~3Ƣg [tEx ՘Ѹ^TcGVQbhUoEݐrÖni+8jVr/)Jqr.ɵt34$jRsZ(RY*͉cUL&|wMU.F@e~yd`#aH5.,./nmL #Ui"oBpttvj&c| 6g +*%NpV|3kC#4%{>?tOI8&?knv-ӎC7HH`"< O6q_U m1F2dQC޽:,ƒGm[7=tKkő}DS-dTi: >3Roޟ>T{gSwtm/'JH]V_zimBx坸胅d* a|ϨRD}*:)S7-bqP'޴m0a "Wh}±JD ZQy$GZ2ȵ*_ 3N?+(+U7 Ȃmf`pbZ/WuaYo)zV*"LטUgzrS஦~x Vz( AK g Xg8 Пۄy ְ c"子U_׀L οD*ie٠>Z]y 2^>%K!:]kIØ{ `YxcgE9Vp e'c򃛯Oi)Ēca2^Fu gwQ[Dk|;n{ #Yޝu3m_j2b Wjr {3;GZu ѦW=RQ_L5K,IN:!I-u x+e}.4&(\Ji!VC7H&+P ŴnOB8l]1~d|.Cx2`o?&{D}s0C}cz_W  1q`c+\?t6@c/0gsn\h}KIj <&71uӘr5X;sHB \ ?g! dӰ ɗJ*ť4N$?ic%4鈌^NXrXԭ6;*`JD6X"kY{rޤ*iV\{>I}4Y>e-9I C% 7l?+0ʒaB6' Q ;G`O XNmVu O3|[8&M|/2}8"MTX?m˴3DݢŅ@̨s f 0O@l'nJot-ãܵ WH MW6}c8GF% S{g̀5,m>f=_=$-oGPvn3OH2Wfg}䐖YIYe,[D-o$pOO0 /BKo1u(5H%NoiŘ H [\+ -aEUVG<%֤q1~ FIu ^؅kVݏ'7M6dƦ}kf{Q.@P( !sr  L1 -2ClJJU=nt!Wi 43p3cR7OH—i*B( kOT!@{L7 p:ϞثƉЭzreu9ř#~y$t& Fu89'HGĿo&hI^йƖ}xcgHfH[1h *[wy ‚G0HY-tg+>}cq`ğKձD~q.)9 !Q$HrgŘ t3d`R#L'P&I]䷆į>ȟ_-~-s֬z/ qX/!TY5;ӏ{{! W hR붃sx.\Ќ~?XH WI'|ԱGш:D0 0k]a $`v花R_J 9YVpXAUbKu y ])!XsgB}0ގ<"tψӖ@?auHz=hE$Ǫr ^oWSGR?jݲva#d1p3ѩz܁M|* *+@L wXqC濔0Kw1oYN :Ԩ1>. }(2(Y.sK4<:b?1m2M_*gARp0b19^oaCW ofԖL APVAySsꟉh>q&v(;0t)FL5yRo)#<_G0mjV$@g$`o#2pquVO6F;Nz\|I fX7 i5G-ʻGkZQO%dr . tg 'MVN"* /ǀßBiq:'q4u~zDĚ:=@Z.k 膭{ƫdO`]z{鱁:Ù/%<\TDe|}S8TSkJ~;/ ؓ;hB]kBx] qxp4EZ[r[UQM0>n:<",z̼>t뉒էnbjw$G|n/2ujjqY߇R4C&͘\=d?k4n'@;X^C:YZӏ^T)zѥZ ^-MJh`x9v (ՠ$ j{n2lxTY2`$͎1&-:+ROmU#-ArՆ|GQ\i.q<@#9:35F VmF$/GDVFs6=eglcpq^/Ҵz ru@UH"G}Lg7$c:D9\m-TFeC. xSrB>ܒe~$Rt ߆鴞&iO`UZsN%L"vԐb7xQ # 9klf]Iݶ=4}{VCl8~tg&~U UզJJIF҂ lTEPWBB=D( cP|HMOk!]p"zꭄs{Ds.u,/1h<( NfTs)#d/8PkHګ*󟯡:q vI%\0ߗ^}Uyc۱,L%l!ݪ]R)t29RI';miƮq8Nc)?=?^YzˈՠFb8-!GKϳUV1*B)x]t=zdßjfvxf,"߯PڀVyMh0J[uY\)rhi_JE1>,at薘ȑ#E+̶)6+Q5&2PI 6*d^@يTB0vLr.{A]zA,Y^4Ѐ(aH06)RmXtEubg詮eQ\<]'e%>@@O6@Ǟ&yN*ءgBd?McghĂE lBbB}"#<ĐcahD1Kpe#`p?[i1$ v[< ),;hI5X8~DfxgU+{"J%v֩_ϢQ&5V,gLAזr_^5@VtN} -)c_T%NҙCREe; a6𐵧B zhS!gDݴ*ɳ Fh7qº˞|fq?g2M|rb; +lo2PpVa'2w_c@ؓ'zqU MvUB\{z";$V]b.alEG{]̄R*}hrnVX$ ltٽ޲ Q"TĚ !o@ay(af{SGZytN}RPcJo1k)NvӰRxDdr=f| F!uYV"mL"<2sT0]D P1*ekl##3uN8O";/'D8*Ǧ]jf%tb\zҤ[6`Vj:ĔO(,eS6#5%Yl ,[}Jk3n9%;I*nʎR(vZ7P %e_R3![n+ oIryr*&M=d> {_[c66A6Fه ,,DNMNQoM׉q Fa.!.2Y9 ^+D1M7R&ٔJם܏  C@hR#/AkC [7ɷ ?`5c0`H(=1I}'?@fF.3jS//n-Mٗytk Wλ;MAyk4Ժ[/f(K&ݘNѭؼ+{@3s@Fx^t~e'8A^O^,L2q)ֲ5x&\ :XJGY8/em_)tdhn_߄ŭc7 O&]_aOzfvF);r!Z9e(<>@ΰ\2*խy+Hh wIԡ0Wu>n|/~wZ$^ЬAOEA:6(sGJU1D)J6f]Wb#U-y**gwe}Sn`\Xc-7v;_':GV`omfby!F! ({Q//HӶ7V_: ,Yt R_z\Wϔo =s)N/G5YaN|%D UUE*Y ݟu Cl wL 2ڹZpc1~4L[k-QV\ fg _VfA 5g2Mwg"@ca~5q̫NN 7^K'ol})NK[ÂP9ٝM1XlC۞HO$ڬ9p⤂;oRj^8CǎxGsUt!W Qb/irݩPv$bq11 (73N0(2{~t+3o=g1eO-׼:#ۭm<{vsWs^gutZLI]$3ײۚ~@@N%aq*.,LtwR}SB|Pgp8'¬_U, >BUa*(.4h5h_WӠwaLh> f܃|`|%~͔rN:+ؗAڮq%Qut)E"OQ֤m͌~V?(+3S锁nSmL?BO/bt{M{,yЖ)WA_- F'ZgFżZW PG#5Hr[ Vcs^Q&-AFv:{+8mIC@dP[Y$C>.ͷo&}`^>ITayaZl:@(a+,C#A`51h|)+,.d?0ɜuS>m+D+ 1tol.!ܒp4Pjs")4Nu0p?a|ul0-D ̆,KO[R5G=bò{c|([r˒y>j<|?acP& C"K܅~e @g0~N&'Gtlis|vE։K׀?<:0u l%涛6*@ͬH MJ\["W!>_OM.blK+;@mc='6c7Txt R)}uJi3?,Y_c)me$?&#~7lJduN*>" Jq5/4Yt *#GWr-td\R|mS|rVG WCgD"/*G8YR2~u*]al;lg]~|SNhNe/s 1iOC\q탍 `Bg$p>$(XD]RC gF.%יZ>Sİ:}{+vm r!Z+tL̖Sw& uO"{Xi{fI))B dztWtIXqL^jD]3m\nl4 *}xe1iȳ\zo;IA C|K4Ƭ-՘+d_!϶XqZU(:TG}ۣ &jBЭFnUV3 ILL PYy5o_2Pi<"JI7QSB[ĻhQۗc{K4 ?\In:9Gǧ<;,mUKȼ i{lw "B^x0z}@~TC~Ϣ!."IG QEBl`?6pOp&t4yw N:ӋW~6-]"X(.SrJ`\)8#l@y2uZ,pts|W7,R$sL4Aڎ\w;ۧyRxg8#y#fHC2$&eu?!WGO>rVeAVG=6(c`f (yĿ6S_dΰ$/GΏ:q6Cv,p[1˸%_ 7LFPSkaD^6ӷ%X9l۰D>]: M)je։ f7kH*ܠ 8AQJTD/4Z_fG7:m/6b Zߔe幾45܏l[m`2Fdͪץf7NGvZBd:.uޢ+H͡Cꄌ\R ^`C!q=UUL3tde,lD騉vVCqqMi0+wm-M{3ls >ũ$`"b(n!yD;S jx~'.A?G'vnkB`>+X˻Z3dk3 }:8f9֥pmDmka *s)ٖn/f{~HäJ%l_ʣi~LT&!B!KHePE&&IQ7~7w(nA[1]-pT޿aG zإCnvjݼ:yy58=GUL%C,p`5NѲ=MR9S0>u?\'f#Qۗ3RկVgw s$ &#|ZNx@BQJLt JoLvxm>,\m#oM8 Ɂ4p9)ڷ DIxcq) @? 1#K( 13oK`b>Ąaq5ciA,W ]Llf`bv [Ȳ`CO@-V,=R"o23$-Q R%kyac7i@YofM`AAx$ivvDL2@OͥUK̏y<غzb}˯Kw2ϩkAx 8fC‘_|^DXo^qS~Z m[|),ݝ NEg4toҺ#\{!tgH6=D#5╏=9³Hp441 MA$>y-L}šǿ["{ H˄0ddA>j0ڎ&,aU=\ek)'<Ig`LN?2ט4`=}|RVTMx{# SY €+J{ ͺRKeIӥt!\EGw1~16yS @RI8'uVMYS5*n~hޖs}(T@θl:0 KA#qdz j'G,،6X$k 54VL>xɏ8(bH^,;O Д[ ҝ ejrxdr`6'g% ;}NZJĕpt˫߽1LP_v؟TE $ ONٔ9DAm#jԑޛ`-ÖӠ\7_<w&:ޙg)ATVN%K_s>CvF=2@?߻[)VTDP3مO bO,ܩ,X}J5/Ii#N9f#ЗYdtݫ$KI4z>S΍Ʃ`¢ Cn=2e;lJ(n'!ωxUp䌻bR"K>'& &5qaX`Kt"qF֖clu7(?<=嗤<0O똑*8fOXukd+Qu# #9{-m`4߷(Q`fk'5D0R8j߄}~4sD8+0ړ{M͚wm S J3mΌyFӎ.rvBV!{v/8!@Z@p`X)b+ܾzXV uZ#0yrɍ.[qHH13(:i(jG rCQ?~lˉO.ZR_8[U*ݯapsz />cskv%;#P)vx)VCKkZl@ذjmVaQ8ܖ'^ Vc69^vTah =O5rHv25e 0Y%Q60})CD؛Le@@ì* :`uL78]bp[~bZ(]?c;qrrVғd낛4u܎-\U /_ǔ)~X{勀Z䂔LI{(VNbsćўB<8( qYNtP:$n-o{+RZ>M Tܼe{Cq pE&kVHP;B"X~2~Lp]IVNDcx>A]!!~_T|:;@#gm]ӱ*sѼ$sNy$x^-?w<&moqf.G=wg0o8@J\H6aJ?_Fu6gF_pH0bmje^ }?vB=9:?l  ,vgl8 /Żm -;q񣕗bR8SB DO*zkBs.T p-p8 SK f+qECfR/&ͪA:w 㼎J0Ϻ170e.Evq}X3yZ:H/# Yؘv2TԢYh50_LxŇUp%mq-%q5FM> ^3woҦ#^7 '(Un2\!DG/&j#۔X+XW' MIJ6ўUH޵/;c9^ & eO\./F*VjNJ^H Z+l -},VZTȇ2i? WqndP=3pnjzý}z ֍㯊"bunV ZH[ 5ݰ1\8xq*.ddRxʰ pMObaFwEz͞+t4a|U4,!ؼ#ioM  # dFAItQggipo9D`")Ĵ qYh-mn%{xQv@';Vy;&{ rP`)!|(SŶ**g_f#WR_(GZ|PPC)(2I]<i! L > @=Գ,}/نv>?NS/!HSHxK)#kpC?j-*90YZ6Wإ ;iՁ|AEd > i<^shC<OV*/>eZ6-i"):]XcmŬݨ#96XF꾴º\"%ZAzJb{4\RFZzl ]FkhS{{р6"{ޘ^3] &sM%GrtXȈxZ"~0)(NJ}2#K + )#pU<=1)W#dĪ]!#gϿ^-K(!\W:~ne(sQ哥/Iy>JrRiV6*8{.c<8~9r-kጬX)؄pYY~ Cz޵) GHF`,i]) ] >{@]G= rzК{)[ 7NmQH~Ǡy`g!"$˭'KgPvY\/1e&[y"wt2^0WSrz;6'Iz 󗜩Pl@,Cb @p.eRTK̸ X^AD?R0 Gi^a 2 Jo :ςy;%UmUIlv5fXC@E 0I)RZx|[I75}/KFFT+I Jfi5#B!XJ L~|Va"<&O'Kh~Muͣԝ6-7[7\^8Y U}SB'eb͘&0a‡~kEje} 7.z"{RGp2E:MVU8EROÏJFT:+$_ŒJݙ~K`QWFI m)ٶ pE7Xo'WђVaNȨWu\vWA-Kߴ:0 n#jׄ&FU,P&F8A((Ts&s 1;ږi0 YjbXI+`PzXNHʻIpiL1[η,U:ݎlvOkrg.FKXaF讀 7s֩0ouef>y?PR[y}Imh镛_VGOMiho62li-3L@7Ǖ&;<-;)>S7'#Ɵ UޡE{0Ԕ"qEszK2!b֠-޽{Qgx\< t|.5aS?ih4KEfJý1`v ,Al#2/$o | {+˛OfUEr:hZy(Gl01z' [wIlDPTO;܍|UH>愧,@5sPL|եɗ+qM0ItycIϲ~J`9)Ú)>,}\/{bL_?l4`F `e|vîLBSJٿ5'`|KIUZ2ʀ} >:!|R0 :v'hR.xAILc2!mAI,LAwnOt9e@u0^-%i㶬v͆go} 둋!zi\)z( 07u;YDtjwGm5qG _H8Sqp1K!Joq) AVFgss>@_fPLK7;>Gd'kաD'Ϛþ&NśTzF-YMώeIboZqk &[#xy9͖9H.-dC({.TXnݓjY{F+U.)>&yܦRgA`:[}'T; ;IXҭM\nn.Ӿ룟!RB}!#ΌiO8lTczp)2=Eo># 7-[*UK]ΤWJ2c Gw_G|FJWmAshRSB[{OK~wLx,k0{#Hgf\Ĵ1$NU|壶i1Lh]Er_5?rQS" 6V d  g03 TSQ5 Q)KB-Hv'}~&+SpɰlHMOդ%IUHsxoMб&?e`xkT{`sVbgƏ$f w%v$pZ,iZa%Xg s*[qB[TɽgN'}sX4o1_L3t^ 7ЦQy`&c\W%"6tv;۔R@4L6BxS0^HnYd(&sL}EaK-q|!-Hh,PtC |Y{&#aky]>G0I$_LeCN1O/ʩjY؃rxޡlx  y>N)9O ANǙ9}8QD lLl{WҮ*/@'2DJ-PNbp6dKv}EZDLkH<[U>(<ĐJHN^!=#  0$a0+"MK+xBBmjFD9GF/ҎowԡUe$zǪ {;JAdY,>92.M@B4@BPz>bQ :9s&nk G/JgUe)Y8ɥ'yM{mR&Jwי>l2s8%-5cV}DY8pڪd,YNkbh;Tq ·OI Z#8$ rP҆~ F+䲿$o1;`H͏ g"MT`d'µY5]zo$s"/>8E KL|7oEsyB}.Ә<9sVX)k%GrCts>MB۸.%ԥ05o  `ZmM!$?i2-]2ŃV/cf$UWt%t6hB!C>(ǚc#!PfNvQ@+'iz,t֞[6V!!?ś৳N6KMX"1ǓYln(P9wo0t)橒xPx߹i4E64RO u$P^ޅ 3>FN C۽*R-!66p7Mٝ]_m\`9&H(:xjZnji `L25f].q1IHsk2K{^`olEAp;#1R47!Z)=U})Ԛj`)Ga(|L V[;3FhJz_}RAUˮHc$ɓ 3)ߎUtl =!W->mD-|=c(m;t丣D7[KLz\~ "a1i,lLM79?>aTIԎ~~%96 %Xe^7'˒;Q.-9 砅mLY B|F [ntXԁ͆NE78UE"?@q hTB*zck-X OуYAƀAk F=!)U7^t>D=p1gedx[&%YL"G28Ό!#/(+Z#f#ț.H y}Akvu5yJٵ4.2l ävߪ_bfk ixELwzIwEh!*bEk4KS&D.(E Aawc@ $[[;B?3q́ zVd_ФEmyx N|FGKH{No r6J7y9 QI?8瀸ORh27$n$ VDe&*1D=.#6K!^xዂʶDO圮jy'.0>fH~HvZ9X `--e;W!knqhdPf.{>PTQ QEc) gvhO}}w\OVn.l} 5VͅXnzȚ4^Z[bkĭPMوFv}O\)rAj %%3SO'2͕m/8сRW|ٛ6!NZu?bgBܣXF`B'#ް xz9|ެ}BMedIm>N-J[Ώj'>$j_ms{o.`w)mLB[8=AM+ ݚ~K:9^i^Jn`C3 a?YxsưH; Gm- TAKOG>IO*ͧ%p,by3w؍wJ+z;"-יFV xylejzo"kь~I-z TAm _svbu*pI{/U}'jx}]\ $ƊJ>;35"-Izx יl!൲,;ٝ ecG.dQ~p9ꕐ2}##pz`]%\]?=+29u6zYFz OHKLE{oK p5ztZG :TP>[1r@ [|YQP("a?9 s~(Z3FB/$EqaP%;|f9\͕/NGI8jIގ8L}ɩ. B 9 id ZJ{#ts'aIeu+p_Sc fW}9 }gWyiP͜LGyy3_H3T{D%;&1yR}ވ᝿vOSfM#4GfupߥYСsFMhU%"}7]&"'ՠKH|8;}48A~`K*rw1N04ԘH!/-ůYCis"Y{g'Ljet((87Tߌhhܜ>Y՟ޜ01)+2)%I]vQ~/GD@ʝ.R+Wؕ(lkD3e& q5! *x@6 ]X| H'U`A(w r8UʟʹJ$Xh+"x|tA]8iOB"J6t2~;ǥc8,)g.t@Fd]^GG͜JJ|9{pi|>AY,tTX BbZ?*VóX6*P\D`g_z?7cFlָfiޡeU5:B_hFgEZY~ɘL#f*G:0i},Mv&pVO{~<]vS$nR/ȋ-v5gx"hN&|Mn"z xz\<5YY?'Hh?y_[Gu3eT*jcsM-1ѣ8S}W`:KX ;ÅXq !MN~ xK|Ep?Wva8iIK4 ]WFT\< ^G1KaN&{"03 T9nI+NB$T>d/7rG,` z‚>t݋Vk(dҢGĵ&DS0ny$Maas"J64`3ņƹ^>M5y̆f*!~Ahv?Z8?iV2Pdɍ>R)]Ml^VB԰bVXbZ#?1,i-RhV3SɌe?4M#ͪ R>V>Tw$0L;xՔGwNli? B#€ٛǬ!ƆFCb>6z >NћNڥOQFղIܞtl4*R0{SU%{UkL<>_""fMJбogmЌHOIx&!Y\vI =w^-&뙥NBmlzc'}V\IXhGƘ0áF _.^U 媛5g+뭓}}쒐ot({:^;1ةdOS5J54o<9L*2Ocԯ(t*X{ />?_p!X2!q?a͵2j.7)(T}P\*nQt:^ѽ*u+ar_!65el}3"Da,~kh3sW+ 8Mދ|f aly qPS .)~NRK17Q??}QQ%wSN{ L }b=:6~,Q71 4[qc]ԖK[nd|/K'XOՂal=(J_zx`L[ ?~z#q42G=3+-) X ѕa"EJ+d͖ ]1x ]XA=_D A/{g8~ ^ UAߝXS65?W\ {-sZ<F3?a]փ'6LW5+6ޥӉS,4it5; z }Xw!Hd?gr,Xªj/Ȏ_/ W 8TpǾTK/[Ni 9駭p(@+VVaۭ fO?vCU .N,֑w6%d>*02e]>ȉنCY@FUc&ggvDg|l 3ͣQ+aXi0I+ҘKq3RYn;N #qc =`"@4;^:Fۈ٪A2y݊cW;uB()ZFNg\|V&qt_[eiÖYiKf슎eu^?v3>5wҫ/H5SD?0[:P[Ԁ^Z?-i=5{H-g@&Vv?ZΊTč\̂Fg+n%*6)Ȅ$],8xiX#G\ =s9}-CZ[dj.BfYNiM*&JJ y{:SwJ4Q;)`>=%S߫yq:@ ZxY;3!փ}4b u0؂#R>5Q:NqkM#p!X55-UŞOY'ܵZ?laC'LPa!Ɯ/7(_u[c<E/LTpФFvn!,~R H(y!1;ӥmD|jߏ*ˈ4 M?P'WǪ5&7C+oE (4W V-(J(1 rDQ?8nDb3 ~z"klc% s1Ē&je\kmj W#;S4fE{ݓNU ޒ YY>N1U3!m'ZT ^j.@>_}t9e̹5}rT,BG\LLnyyHJ!Qu—-vCt!u+|[lKR"U< _BE 2ѝp`)|朢_mp?FB@W-2؀3s^7DޚxB{",q'q]4YGj8-qĐ0=&R%=n:m^aAQWYSHt7WbW)%NC6nL[-%%Ž+cG;ED꿲D(%@ngIo4*j7f/)5?\?.pܜ[.WNneG=c'^$}V2R kp5OPDŎ-#:qɔ?k [M{ MdG5hrS,ԌVYr٦s+-k9D;t*NY#eb.@oeSGp _SU*DoD%\*kyFc3tR7@j JjҋυӟZjA#d/ۚ ,x(S׽9ߘ.ms~x!:~MSn/:̨`HQwhE92q)|M(Ec̉Ba=+dL)c3:Llx3A]@uΝx՛qKJ:MQ5򉹖 ˑUlV^OJgUu7m[W Gd(XjcĞ` Uȗq֧⮌H<~^VP>KQ@#EʮɊshG Q ~><0)LHӺ?Z1FKidcӝkĉ( )!!gHvoI R{шX}_iT$vLyrJo)5+P6gij費x+Ǡdy]f<n{65~gGcw/zj~~lXWj|7Ho4Nc(>{Jj&c .^4oRQj u4G)buwG'yn[Ŷ#N/zKMfUb z_D"8JS@YyjҳpΔGO%g0]Z X Cl@}\a^[ySe[B4gE"\9Z("˖\ @1R0?N\o*|q⎃sԫL_C_f |f ^*ٖA=[NpY יִ}W)- .0s7c NTPS%J,&|C=wKIcs]<Q!*2}sd(S@IU"q~9.nqQM!BټY!1:QDB{XRhMGp KRxs~k=-'PmWSRׁrMOv/i]Gl/ >iS?1H]}$~ h޷A-dfUs6zո:a˗-ˡl2BK/O̓:'0G #2bjBSjZ^n(!7@{t\\puc"X&ByY=;G6ަ6{cb||̳|%AJ_6*u9 Ba)H; +"Ynb|-( ny}#, ȧ;FG4>noZ]M1ƴx}8><YF7F8oF\7zQqU jk{y Ǭ=q OH%bFΈCɀg]^MB_ `;NŬ NFkeaTz҆ ȂB_ #w(y8kk7M P{))N̹Q@JI+%>֌nq)Xp"ROˍQt)__-k?RP:qomEL͊bÓOO 7cPN nsI? 8i\Rm_J[-Bbut 0 B,,% 6|7>77dɇ3g㺷b!ǝU;ޛMj&M64]_]\tUYߊ*`~M\11c3brV4 g[FH.qF _|vUƣt>IBY"G^kJl \KPlW .|c%aVYQ3ȏ{nhϱ?.󹨴!{29fcWWHI>Qg&rYR%TIy FYClocȊ@PrXnGSo_FI\ M=:cl ʕdK>{9(?+y"Gt"ϐ0u؈ù3ޛ*ytu_q7R#)0t&h6@t1s&S"yh|ʦWLR-~/v /ȯ;F,qHqYV;Rh )L]7y ["Ǡ`R3ltC)A~SGEcR{i(sd<6.oiT:">=R="Y]8w5Hdj;VsR\w72My슮˱O:o*3MǤfe~&3U?"Gos a;s@+*>YQkUO$٭a bY0*F}`z{܀S /֚}99O5mZ,Q旞HguHŪ Śr"LI?Ӄ >N|<x82#,X(S1QG Y*K;8:۔e45NRfb@4M׽qsGJ$BB\ewERQ` ,Uu*QE\/~^[5;8Iiq%D_i?Wzd1qo)J([uoB @հRs8JS c ;[MOY"WYVP87KPE)u'N)A&U1:{Cp\ν*$`0eij\ ;I‰D0sq,'|d5D-P$AMMZ Onjj=c$IJKubORIbNHj+m׮fiC !Y 7taw%[XVқ ex`SͰ0O"zMҸ3EpxA0ovdߕYdSr A&o)/_ܳήJCoiSm*W'q5 >uB|qJO21EuG}-} SG+BkъPӫB5M"ÛVm  h|C eh$X0uFXmFp%@I$;{Pݿ j4y>DB&[]qꗖ[v?PL;‹JAʗސ(?UeQ-~, _]xHV$T10[2F߭gXQoI$_7b3=ASd9v4!SXT0p*}ڐgUdg|88"d\eF7= 9X㬁˄%PH'ExM7jd:<,#f|g, $[J X/7&* G|* *E[9[5DQM--WF (W.C4 #8y[mKن<-A^7HrEZ1m &>ÍQ"BHb DbMJD.mlz<|4rܯN8Z#|aTѱ$ge3kVJ!tIH@1(3eKyF} חxR\x- \sFlyhUǔLpwܴyqIm]ܙ44zYGjI[y0oUl˟˦V{Wӷ.zidQ<ڡqnY&#;8S4-.5,%wV8z7_{ m4\\]0!N혍];hk. HR3̽w9 [Uk Pl(n |)>$2YwyW.(ZJCiফA;(tp9S6HͨɊiD̃"QKGJzeGgWu>BĽhO+ u xzW*jh9 Hd+CkF Q 1cf}^"^7x>Jq^|  U0a@*ԼۜvQB$>A@x[Lq _*X$qII }*h;/;XжY)4Ώ@G'UiT<ݻV7_-Y.A4pc4/[x'pdaQ~ׁʫП _Gkp;mS-v$P0wӁ'{1hM֤ĉ%*sꕊlzsZp|xkL楜:;=PL`2"]aNn$cxnp{\zm7eSnf/%KO$וW萐֖H9/Epkq&8*JRLRRa^1i,(G]=006(w/FtP Pˡϊ&Dff@bוo~΍&R|I>t("9.'^3A *-,VoH]אRnn`xV['|j͢ F!>rRqeQWr_RnWa)Hѝ%'.n |:$ h3^}=~(P"$ɐA*RQvtMܕ@+X `D:?9=6xCÌ$.P,Y0v ݖ%1hχ?|:&dCʓ?/Nj9 :/%493BDհ ! MlUxkV*'UP/ZZVW` 'VJ[٣ K29v 0v.ڻI]l2"sSh> +i."7Y/Yu wlm0WSKB!z:" 6Ko\r)1zhǐr2+hk%Svۉ^P鲩0&qW_ 41+%hz }X[=_LxYO8Z#]yθ` ㎼/y~rZ}Uqۨp @[.8O&.XKu?.^^IQ|cn:ط@NN;H84\S` {{P4/xņ?mY$ C zSBB13T cn_qt (#zj󗨥/z FskJx.:"܎G$BQO0R7mPT,J`tIQz~ k=`0  V|Zi|txߎ7FqgSWv q]ܦKGЫ$5oְ7_[{_`uܟl-T(ԵM&TR V>'xg9ydCjِz i+7DBkP\umaOY~ߵZo *4CA f#7L/V#z}ˣ)Kb`{ Gj L?$&߮2x I5i%~pYN& \9 ݳf"ci4Mv6?K>In",7mEɪwN6N%5 BP9j(y Kr^*.5?5<t'\݌o>cG*l$ A1otD'~] ,`0òc5Urɲ<')30w. !SslTa3.Iy3Nu@9CwsZ$ri[sx8**əi*MI`CG&0+Jgw/-)3Ƥ>uoymq 3y7ip u*p7tMӲlTZ =7 ӨްRJ,ƶLe?QK!DTIE.mSe[YoAlƟ/ YFS G\,-B^;SL$VY9n)"Zs0ȶˊx,l0.i0pǟ''ɛZ^nUѱa=ȔuF 'sØ:;drfb\H1y 66MAs< {Oj_j"t>oͶ[w0<j }x.uvNٵDŰ߫@| 9My@g #9K5,v隝k.HqCzccVTVpB Uw!.7^A*++[LnM/l aUj{V'r[p볞|mQAKW)j4 %2ST+XLcاnPf%Mxjb+qWv 'i"ͯCqVep Շ?"0Joswv*b[q-34+}3/{9iZN/L5|n::j% ==bU0O|,M E!ITp@Tmno#ðc;0@| OYːE()Hj B>C6Ҙ3[>/(C &??CM0o^[f'ٜ[5 :.,HL* +ӘsbTj/oz= +JmixL~JXNLU}\X3O ǧKQl͎|ܤiZUؙŗ- )k}E.ٍڃ>&H-1R .gE!'S]CIy?,ӎ{3tI/}QumVϾDDc \<焐S˿Yh(\:?ڕCo{;{[b?"m `2v?*d`PXu "!RKCXgnz3npmC٭+:'j?[0J sێD|ݾj Vtz^+ǚX-e|'zA،K+#.!~g5ȄUNF;g_ =m[kۼƀ~W;xrP~%`3mc&.N }WDs C8j™5Ƙ-Ôe3̕H#h}PE"qLKh-X XbرP^.=KxTn s 02%j?",I6 8eА}:+݈+r@$DqZYr"I 瀄=S .L0&Tb͒GHy)er_ȅ d=- 66X Šۛ}3x.H} 6iu[؀ 1k@pT,@k]bu}- sOc!EGiC?DuϊG)V&|tG&Nߩ;DaѼ+) d9EQ& rgmB?М#]D営e3-PG <#-Q dewBimXsaP < I6|Ӆ2Fk{ 9EFVe mdBӳ QԴ<8tN""8Wcp\Uΰ$d$ľ๵5;)svtЫ_K}@͢-8)+0zZtj3L,}iԚiF) seHf~B՝6ml)->  'iWT%"D@ŹQ ٸ?JAy07t6 jU#yd{ 'y ؾ0& jruVmy\CZ]KCJiP:[e,&$;J)ΰzg6"P 5Th0)ܹDҶj@ߣpV|6H ᤥ'5$HC@wM1s؏-ںqSb6t~91~݃߃EN#2&vt Z4٦0LIG<*5M*!gL+v& g,*"xCt}Z-D/v9i XOn.$SCjߜ][',KEF[z[?6[a'X@e5#Jd=LuS5zé՘Y;)X n*Gł^[;ļҙV gy@̹ifmEnPeF95rXiѮhI1 %9rOՀ4{?k1+ {wy3fr<lo{$ mN.Gc! G_W)]-Rݰ3=/>,p0vq~/tOH!#e2|D,hLKASp4\..`(}.wlHǝ!Y}GoMϧe:3DsbUկFD`eȞMH'`9Aw5b );VS؇=]nOmy~SrIo;Dl{l;п.O"s;ayV4wEn0QZ'x7P)Ujb3c͡D.hښɆxuY֗|<URpc;C#joos\#߫"wf/kuߎt9hG;Uܒ,Gx6Ձ=͸ɞzHT*A?\Y/=3ncуҭsķ[1B<)vC.[zJwH9_BBP-=8 OX^>y0;A$Ŷ Tk&2@b O0CG8}'uldU _` #]@E0t/OC¤^V:LXșS<\gdh?e*R#-Y0FT~۹E9Icͪ r9e̚Tǭ[YF D0|+]7fl%@m 03K؄J/28z8*w }KQ+M"^IX 5ҟ螔KGסcb*ٯрL7v[^D=qG>V ? =AxnDYt߽~xuϪ/ajO.e#@FV!oַA;mwBV9q^5P{ tî댌S.3Kc֤ Ĩi3jrʂA 3?!WPӢp O=unuma`Y%'7Ath~L0K_ %{[ϻr loKxzet%Bh*Q]vaܺ"n?Χ=8oX%NutRq.Y՗V+2l}nj?#3bč%DJ !iN*Vi jrMa2V?{ }c Qŧmlʠa?.,j+Lk'YXdҥl9xԪR4`.Y;|onYnG=`)$wc|NZ(BNQ9ltC"֗Qb&{{Yn?-fhP򸕛ݜ̕&M ~)g@Nx6nNRwTA Q_Be3\X |a@+P;syLOs3-13LD,-^G4gSr*:&RCr=yHT{*ZWNXG fMNH*'3v9cr5Q F/(+=이$5"`SWx 5/fO7K?aC4Ғ̣TO λr& er+fV6yӄgb+L8,2ӦS5n#w~gJ23`tP= 6fP9ɾ5i#r tKomܧd젰u0ueⲀ{imZ^/OT19sV%:P̤ql)4ov. ʝQ}:zAA԰v)JF(hHR#r8!\}7Q`$q{Wt>{NI"q~z1.S!)' R7y ._$AN@qMfK%_PBP9·8TFm=N0{y;! d{G.tvLz"Tj0I~%N .M2vzȟa Tdц޵]}Zl@uiKCYO['_*HNҷ?xss>y^j5]ZB#ӫ* bS6\Gų|mݘf)0$'G)!~ WEio`}s@uv!7,8N]U?9iq/jeY:^n8q-ˬf| _I<-&R3t4nZ[=F/|Rp]03x1#68.| A?]`a@? i)ak&aiF9~AU i%H`}A'3X`6'e T(`)qkkż`Owy>zϋ뉊㩳heo30٧)zlm/UOM|/;#S|/=CIѵ|;O褤?ז[? ܮ\fp\,b0D&+ 6C;c⿄E8;yO{ F&^l+i^ pf~ΐ 'Uי'6 tP|uvDFC@(@0#mV69ͪ/X[|BvUr0j!ͮ\o8@"~^V>))*՚)ŤY;pX OK;ug~'9d*df5;v]p|J'd ՞EH@1^  t p39ހl6 =)lȑ/{ V'GEIN{ ^hoT-Q癐kLlt> i}KZZPcHMXG^MIZ@tTk(M㝋,\{Em >]ˋ־UNkC2=(ox2k =7ϓ|sc/":KĿ\pgQGg/;>ȏkg&~nzLM.PZ3r~\s\K "?묵]`rߍaPŁоJڌ+K.bj̽C 6)X=>;yz6Ͷg WU_)<߫/#{pJ^!qQ[rTGֽKuG~q ]B.|My۹uYi`^2Rw.+UNˬT,Tz 2h/t:"!^*ۄ0o sؿAεhyeAڟcE=ȺEx2U|VҢfA޼[;ڐ_?[h~ \eJ=Z(5#=Gen+}v& ,.ނY=r7kN3f>FɇbvEfOIWtƸ58XZ aO{ ƾ=;w-cEAL95XgB t/+M[r$dy4&`j`iw7loX' +_Z,y`ޯ)o?\wG%iԞqNũU3vmiY}\Ikk= '겏#*>W!,!=eLse["wHKYkz, g3ƙY9w,I*ЭWY|{W(7Yߏ[Hx"LA`D{_!E՛ejHϖc. 2Wf!e:wNz{wft`p,ۨn98zܳ&.w9"T^E`0-kzZkب|(-m/m"o"#iKr٭TT}ur/;|4lR\7ɴi*-Y,zs/ל'mR$Gۜ~ w,t6y:93f#^[\Aa1-G``(p/+ y||l<3,RP1S;$_kaoasYsaUgWK)QjhS­` ,ƿgU?ydyU셒}-}"0:ڵjR\۠:X3;抋^[V0b Rb[ؑX4Xo>1\نⲽi5RZ|M8²֕h\_sF>s4C_`aViɤb-2/U14-+7i梉_A5yiZl*l!S#kwfR 7h]+8v#ȿ-c9!V(L~N|efea;jR+n2t|$' @q 4,^7H# ݙV%D7h3= v6,R@.[D.U#Ɠay|',^9Ɩ!u#X%3b5]b>\ڷ*u0Щ6|ܜݒ<Pe~ ,q 2f+fFϿFN03 M^WKV;[ , gkxV%xV-KghrۤV`NV@Ԅt ²?S$F-(faaWhc; U)„ĥ loo/R/waic.R0000644000176200001440000001156213761524476012336 0ustar liggesusers#' Widely applicable information criterion (WAIC) #' #' The `waic()` methods can be used to compute WAIC from the pointwise #' log-likelihood. However, we recommend LOO-CV using PSIS (as implemented by #' the [loo()] function) because PSIS provides useful diagnostics as well as #' effective sample size and Monte Carlo estimates. #' #' @export waic waic.array waic.matrix waic.function #' @inheritParams loo #' #' @return A named list (of class `c("waic", "loo")`) with components: #' #' \describe{ #' \item{`estimates`}{ #' A matrix with two columns (`"Estimate"`, `"SE"`) and three #' rows (`"elpd_waic"`, `"p_waic"`, `"waic"`). This contains #' point estimates and standard errors of the expected log pointwise predictive #' density (`elpd_waic`), the effective number of parameters #' (`p_waic`) and the information criterion `waic` (which is just #' `-2 * elpd_waic`, i.e., converted to deviance scale). #' } #' \item{`pointwise`}{ #' A matrix with three columns (and number of rows equal to the number of #' observations) containing the pointwise contributions of each of the above #' measures (`elpd_waic`, `p_waic`, `waic`). #' } #' } #' #' @seealso #' * The __loo__ package [vignettes](https://mc-stan.org/loo/articles/) and #' Vehtari, Gelman, and Gabry (2017) and Vehtari, Simpson, Gelman, Yao, #' and Gabry (2019) for more details on why we prefer `loo()` to `waic()`. #' * [loo_compare()] for comparing models on approximate LOO-CV or WAIC. #' #' @references #' Watanabe, S. (2010). Asymptotic equivalence of Bayes cross validation and #' widely application information criterion in singular learning theory. #' *Journal of Machine Learning Research* **11**, 3571-3594. #' #' @template loo-and-psis-references #' #' @examples #' ### Array and matrix methods #' LLarr <- example_loglik_array() #' dim(LLarr) #' #' LLmat <- example_loglik_matrix() #' dim(LLmat) #' #' waic_arr <- waic(LLarr) #' waic_mat <- waic(LLmat) #' identical(waic_arr, waic_mat) #' #' #' \dontrun{ #' log_lik1 <- extract_log_lik(stanfit1) #' log_lik2 <- extract_log_lik(stanfit2) #' (waic1 <- waic(log_lik1)) #' (waic2 <- waic(log_lik2)) #' print(compare(waic1, waic2), digits = 2) #' } #' waic <- function(x, ...) { UseMethod("waic") } #' @export #' @templateVar fn waic #' @template array #' waic.array <- function(x, ...) { waic.matrix(llarray_to_matrix(x), ...) } #' @export #' @templateVar fn waic #' @template matrix #' waic.matrix <- function(x, ...) { ll <- validate_ll(x) lldim <- dim(ll) lpd <- matrixStats::colLogSumExps(ll) - log(nrow(ll)) # colLogMeanExps p_waic <- matrixStats::colVars(ll) elpd_waic <- lpd - p_waic waic <- -2 * elpd_waic pointwise <- cbind(elpd_waic, p_waic, waic) throw_pwaic_warnings(pointwise[, "p_waic"], digits = 1) return(waic_object(pointwise, dims = lldim)) } #' @export #' @templateVar fn waic #' @template function #' @param draws,data,... For the function method only. See the #' **Methods (by class)** section below for details on these arguments. #' waic.function <- function(x, ..., data = NULL, draws = NULL) { stopifnot(is.data.frame(data) || is.matrix(data), !is.null(draws)) .llfun <- validate_llfun(x) N <- dim(data)[1] S <- length(as.vector(.llfun(data_i = data[1,, drop=FALSE], draws = draws, ...))) waic_list <- lapply(seq_len(N), FUN = function(i) { ll_i <- .llfun(data_i = data[i,, drop=FALSE], draws = draws, ...) ll_i <- as.vector(ll_i) lpd_i <- logMeanExp(ll_i) p_waic_i <- var(ll_i) elpd_waic_i <- lpd_i - p_waic_i c(elpd_waic = elpd_waic_i, p_waic = p_waic_i) }) pointwise <- do.call(rbind, waic_list) pointwise <- cbind(pointwise, waic = -2 * pointwise[, "elpd_waic"]) throw_pwaic_warnings(pointwise[, "p_waic"], digits = 1) waic_object(pointwise, dims = c(S, N)) } #' @export dim.waic <- function(x) { attr(x, "dims") } #' @rdname waic #' @export is.waic <- function(x) { inherits(x, "waic") && is.loo(x) } # internal ---------------------------------------------------------------- # structure the object returned by the waic methods waic_object <- function(pointwise, dims) { estimates <- table_of_estimates(pointwise) out <- nlist(estimates, pointwise) # maintain backwards compatibility old_nms <- c("elpd_waic", "p_waic", "waic", "se_elpd_waic", "se_p_waic", "se_waic") out <- c(out, setNames(as.list(estimates), old_nms)) structure( out, dims = dims, class = c("waic", "loo") ) } # waic warnings # @param p 'p_waic' estimates throw_pwaic_warnings <- function(p, digits = 1, warn = TRUE) { badp <- p > 0.4 if (any(badp)) { count <- sum(badp) prop <- count / length(badp) msg <- paste0("\n", count, " (", .fr(100 * prop, digits), "%) p_waic estimates greater than 0.4. ", "We recommend trying loo instead.") if (warn) .warn(msg) else cat(msg, "\n") } invisible(NULL) } loo/R/loo.R0000644000176200001440000005753614214417101012173 0ustar liggesusers#' Efficient approximate leave-one-out cross-validation (LOO) #' #' The `loo()` methods for arrays, matrices, and functions compute PSIS-LOO #' CV, efficient approximate leave-one-out (LOO) cross-validation for Bayesian #' models using Pareto smoothed importance sampling ([PSIS][psis()]). This is #' an implementation of the methods described in Vehtari, Gelman, and Gabry #' (2017) and Vehtari, Simpson, Gelman, Yao, and Gabry (2019). #' #' @export loo loo.array loo.matrix loo.function #' @param x A log-likelihood array, matrix, or function. The **Methods (by class)** #' section, below, has detailed descriptions of how to specify the inputs for #' each method. #' @param r_eff Vector of relative effective sample size estimates for the #' likelihood (`exp(log_lik)`) of each observation. This is related to #' the relative efficiency of estimating the normalizing term in #' self-normalizing importance sampling when using posterior draws obtained #' with MCMC. If MCMC draws are used and `r_eff` is not provided then #' the reported PSIS effective sample sizes and Monte Carlo error estimates #' will be over-optimistic. If the posterior draws are independent then #' `r_eff=1` and can be omitted. The warning message thrown when `r_eff` is #' not specified can be disabled by setting `r_eff` to `NA`. See the #' [relative_eff()] helper functions for computing `r_eff`. #' @param save_psis Should the `"psis"` object created internally by `loo()` be #' saved in the returned object? The `loo()` function calls [psis()] #' internally but by default discards the (potentially large) `"psis"` object #' after using it to compute the LOO-CV summaries. Setting `save_psis=TRUE` #' will add a `psis_object` component to the list returned by `loo`. #' Currently this is only needed if you plan to use the [E_loo()] function to #' compute weighted expectations after running `loo`. #' @template cores #' @template is_method #' #' @details The `loo()` function is an S3 generic and methods are provided for #' 3-D pointwise log-likelihood arrays, pointwise log-likelihood matrices, and #' log-likelihood functions. The array and matrix methods are the most #' convenient, but for models fit to very large datasets the `loo.function()` #' method is more memory efficient and may be preferable. #' #' @section Defining `loo()` methods in a package: Package developers can define #' `loo()` methods for fitted models objects. See the example `loo.stanfit()` #' method in the **Examples** section below for an example of defining a #' method that calls `loo.array()`. The `loo.stanreg()` method in the #' **rstanarm** package is an example of defining a method that calls #' `loo.function()`. #' #' @return The `loo()` methods return a named list with class #' `c("psis_loo", "loo")` and components: #' \describe{ #' \item{`estimates`}{ #' A matrix with two columns (`Estimate`, `SE`) and three rows (`elpd_loo`, #' `p_loo`, `looic`). This contains point estimates and standard errors of the #' expected log pointwise predictive density ([`elpd_loo`][loo-glossary]), the #' effective number of parameters ([`p_loo`][loo-glossary]) and the LOO #' information criterion `looic` (which is just `-2 * elpd_loo`, i.e., #' converted to deviance scale). #' } #' #' \item{`pointwise`}{ #' A matrix with five columns (and number of rows equal to the number of #' observations) containing the pointwise contributions of the measures #' (`elpd_loo`, `mcse_elpd_loo`, `p_loo`, `looic`, `influence_pareto_k`). #' in addition to the three measures in `estimates`, we also report #' pointwise values of the Monte Carlo standard error of [`elpd_loo`][loo-glossary] #' ([`mcse_elpd_loo`][loo-glossary]), and statistics describing the influence of #' each observation on the posterior distribution (`influence_pareto_k`). #' These are the estimates of the shape parameter \eqn{k} of the #' generalized Pareto fit to the importance ratios for each leave-one-out #' distribution (see the [pareto-k-diagnostic] page for details). #' } #' #' \item{`diagnostics`}{ #' A named list containing two vectors: #' * `pareto_k`: Importance sampling reliability diagnostics. By default, #' these are equal to the `influence_pareto_k` in `pointwise`. #' Some algorithms can improve importance sampling reliability and #' modify these diagnostics. See the [pareto-k-diagnostic] page for details. #' * `n_eff`: PSIS effective sample size estimates. #' } #' #' \item{`psis_object`}{ #' This component will be `NULL` unless the `save_psis` argument is set to #' `TRUE` when calling `loo()`. In that case `psis_object` will be the object #' of class `"psis"` that is created when the `loo()` function calls [psis()] #' internally to do the PSIS procedure. #' } #' } #' #' @seealso #' * The __loo__ package [vignettes](https://mc-stan.org/loo/articles/index.html) #' for demonstrations. #' * The [FAQ page](https://mc-stan.org/loo/articles/online-only/faq.html) on #' the __loo__ website for answers to frequently asked questions. #' * [psis()] for the underlying Pareto Smoothed Importance Sampling (PSIS) #' procedure used in the LOO-CV approximation. #' * [pareto-k-diagnostic] for convenience functions for looking at diagnostics. #' * [loo_compare()] for model comparison. #' #' @template loo-and-psis-references #' #' @examples #' ### Array and matrix methods (using example objects included with loo package) #' # Array method #' LLarr <- example_loglik_array() #' rel_n_eff <- relative_eff(exp(LLarr)) #' loo(LLarr, r_eff = rel_n_eff, cores = 2) #' #' # Matrix method #' LLmat <- example_loglik_matrix() #' rel_n_eff <- relative_eff(exp(LLmat), chain_id = rep(1:2, each = 500)) #' loo(LLmat, r_eff = rel_n_eff, cores = 2) #' #' #' ### Using log-likelihood function instead of array or matrix #' set.seed(124) #' #' # Simulate data and draw from posterior #' N <- 50; K <- 10; S <- 100; a0 <- 3; b0 <- 2 #' p <- rbeta(1, a0, b0) #' y <- rbinom(N, size = K, prob = p) #' a <- a0 + sum(y); b <- b0 + N * K - sum(y) #' fake_posterior <- as.matrix(rbeta(S, a, b)) #' dim(fake_posterior) # S x 1 #' fake_data <- data.frame(y,K) #' dim(fake_data) # N x 2 #' #' llfun <- function(data_i, draws) { #' # each time called internally within loo the arguments will be equal to: #' # data_i: ith row of fake_data (fake_data[i,, drop=FALSE]) #' # draws: entire fake_posterior matrix #' dbinom(data_i$y, size = data_i$K, prob = draws, log = TRUE) #' } #' #' # Use the loo_i function to check that llfun works on a single observation #' # before running on all obs. For example, using the 3rd obs in the data: #' loo_3 <- loo_i(i = 3, llfun = llfun, data = fake_data, draws = fake_posterior, r_eff = NA) #' print(loo_3$pointwise[, "elpd_loo"]) #' #' # Use loo.function method (setting r_eff=NA since this posterior not obtained via MCMC) #' loo_with_fn <- loo(llfun, draws = fake_posterior, data = fake_data, r_eff = NA) #' #' # If we look at the elpd_loo contribution from the 3rd obs it should be the #' # same as what we got above with the loo_i function and i=3: #' print(loo_with_fn$pointwise[3, "elpd_loo"]) #' print(loo_3$pointwise[, "elpd_loo"]) #' #' # Check that the loo.matrix method gives same answer as loo.function method #' log_lik_matrix <- sapply(1:N, function(i) { #' llfun(data_i = fake_data[i,, drop=FALSE], draws = fake_posterior) #' }) #' loo_with_mat <- loo(log_lik_matrix, r_eff = NA) #' all.equal(loo_with_mat$estimates, loo_with_fn$estimates) # should be TRUE! #' #' #' \dontrun{ #' ### For package developers: defining loo methods #' #' # An example of a possible loo method for 'stanfit' objects (rstan package). #' # A similar method is included in the rstan package. #' # In order for users to be able to call loo(stanfit) instead of #' # loo.stanfit(stanfit) the NAMESPACE needs to be handled appropriately #' # (roxygen2 and devtools packages are good for that). #' # #' loo.stanfit <- #' function(x, #' pars = "log_lik", #' ..., #' save_psis = FALSE, #' cores = getOption("mc.cores", 1)) { #' stopifnot(length(pars) == 1L) #' LLarray <- loo::extract_log_lik(stanfit = x, #' parameter_name = pars, #' merge_chains = FALSE) #' r_eff <- loo::relative_eff(x = exp(LLarray), cores = cores) #' loo::loo.array(LLarray, #' r_eff = r_eff, #' cores = cores, #' save_psis = save_psis) #' } #' } #' #' loo <- function(x, ...) { UseMethod("loo") } #' @export #' @templateVar fn loo #' @template array #' loo.array <- function(x, ..., r_eff = NULL, save_psis = FALSE, cores = getOption("mc.cores", 1), is_method = c("psis", "tis", "sis")) { if (is.null(r_eff)) throw_loo_r_eff_warning() is_method <- match.arg(is_method) psis_out <- importance_sampling.array(log_ratios = -x, r_eff = r_eff, cores = cores, method = is_method) ll <- llarray_to_matrix(x) pointwise <- pointwise_loo_calcs(ll, psis_out) importance_sampling_loo_object( pointwise = pointwise, diagnostics = psis_out$diagnostics, dims = dim(psis_out), is_method = is_method, is_object = if (save_psis) psis_out else NULL ) } #' @export #' @templateVar fn loo #' @template matrix #' loo.matrix <- function(x, ..., r_eff = NULL, save_psis = FALSE, cores = getOption("mc.cores", 1), is_method = c("psis", "tis", "sis")) { is_method <- match.arg(is_method) if (is.null(r_eff)) { throw_loo_r_eff_warning() } psis_out <- importance_sampling.matrix( log_ratios = -x, r_eff = r_eff, cores = cores, method = is_method ) pointwise <- pointwise_loo_calcs(x, psis_out) importance_sampling_loo_object( pointwise = pointwise, diagnostics = psis_out$diagnostics, dims = dim(psis_out), is_method = is_method, is_object = if (save_psis) psis_out else NULL ) } #' @export #' @templateVar fn loo #' @template function #' @param data,draws,... For the `loo.function()` method and the `loo_i()` #' function, these are the data, posterior draws, and other arguments to pass #' to the log-likelihood function. See the **Methods (by class)** section #' below for details on how to specify these arguments. #' loo.function <- function(x, ..., data = NULL, draws = NULL, r_eff = NULL, save_psis = FALSE, cores = getOption("mc.cores", 1), is_method = c("psis", "tis", "sis")) { is_method <- match.arg(is_method) cores <- loo_cores(cores) stopifnot(is.data.frame(data) || is.matrix(data), !is.null(draws)) assert_importance_sampling_method_is_implemented(is_method) .llfun <- validate_llfun(x) N <- dim(data)[1] if (is.null(r_eff)) { throw_loo_r_eff_warning() } else { r_eff <- prepare_psis_r_eff(r_eff, len = N) } psis_list <- parallel_importance_sampling_list( N = N, .loo_i = .loo_i, .llfun = .llfun, data = data, draws = draws, r_eff = r_eff, save_psis = save_psis, cores = cores, method = is_method, ... ) pointwise <- lapply(psis_list, "[[", "pointwise") if (save_psis) { psis_object_list <- lapply(psis_list, "[[", "psis_object") psis_out <- list2importance_sampling(psis_object_list) diagnostics <- psis_out$diagnostics } else { diagnostics_list <- lapply(psis_list, "[[", "diagnostics") diagnostics <- list( pareto_k = psis_apply(diagnostics_list, "pareto_k"), n_eff = psis_apply(diagnostics_list, "n_eff") ) } importance_sampling_loo_object( pointwise = do.call(rbind, pointwise), diagnostics = diagnostics, dims = c(attr(psis_list[[1]], "S"), N), is_method = is_method, is_object = if (save_psis) psis_out else NULL ) } #' @description The `loo_i()` function enables testing log-likelihood #' functions for use with the `loo.function()` method. #' #' @rdname loo #' @export #' #' @param i For `loo_i()`, an integer in `1:N`. #' @param llfun For `loo_i()`, the same as `x` for the #' `loo.function()` method. A log-likelihood function as described in the #' **Methods (by class)** section. #' #' @return The `loo_i()` function returns a named list with components #' `pointwise` and `diagnostics`. These components have the same #' structure as the `pointwise` and `diagnostics` components of the #' object returned by `loo()` except they contain results for only a single #' observation. #' loo_i <- function(i, llfun, ..., data = NULL, draws = NULL, r_eff = NULL, is_method = "psis" ) { stopifnot( i == as.integer(i), is.function(llfun) || is.character(llfun), is.data.frame(data) || is.matrix(data), i <= dim(data)[1], !is.null(draws), is_method %in% implemented_is_methods() ) .loo_i( i = as.integer(i), llfun = match.fun(llfun), data = data, draws = draws, r_eff = r_eff[i], save_psis = FALSE, is_method = is_method, ... ) } # Function that is passed to the FUN argument of lapply, mclapply, or parLapply # for the loo.function method. The arguments and return value are the same as # the ones documented above for the user-facing loo_i function. .loo_i <- function(i, llfun, ..., data, draws, r_eff = NULL, save_psis = FALSE, is_method) { if (!is.null(r_eff)) { r_eff <- r_eff[i] } d_i <- data[i, , drop = FALSE] ll_i <- llfun(data_i = d_i, draws = draws, ...) if (!is.matrix(ll_i)) { ll_i <- as.matrix(ll_i) } psis_out <- importance_sampling.matrix( log_ratios = -ll_i, r_eff = r_eff, cores = 1, method = is_method ) structure( list( pointwise = pointwise_loo_calcs(ll_i, psis_out), diagnostics = psis_out$diagnostics, psis_object = if (save_psis) psis_out else NULL ), S = dim(psis_out)[1], N = 1 ) } #' @export dim.loo <- function(x) { attr(x, "dims") } #' @rdname loo #' @export is.loo <- function(x) { inherits(x, "loo") } #' @export dim.psis_loo <- function(x) { attr(x, "dims") } #' @rdname loo #' @export is.psis_loo <- function(x) { inherits(x, "psis_loo") && is.loo(x) } # internal ---------------------------------------------------------------- #' Compute pointwise elpd_loo, p_loo, looic from log lik matrix and #' psis log weights #' #' @noRd #' @param ll Log-likelihood matrix. #' @param psis_object The object returned by `psis()`. #' @return Named list with pointwise elpd_loo, mcse_elpd_loo, p_loo, looic, #' and influence_pareto_k. #' pointwise_loo_calcs <- function(ll, psis_object) { if (!is.matrix(ll)) { ll <- as.matrix(ll) } lw <- weights(psis_object, normalize = TRUE, log = TRUE) elpd_loo <- matrixStats::colLogSumExps(ll + lw) lpd <- matrixStats::colLogSumExps(ll) - log(nrow(ll)) # colLogMeanExps p_loo <- lpd - elpd_loo mcse_elpd_loo <- mcse_elpd(ll, lw, E_elpd = elpd_loo, r_eff = relative_eff(psis_object)) looic <- -2 * elpd_loo influence_pareto_k <- psis_object$diagnostics$pareto_k cbind(elpd_loo, mcse_elpd_loo, p_loo, looic, influence_pareto_k) } #' Structure the object returned by the loo methods #' #' @noRd #' @param pointwise Matrix containing columns elpd_loo, mcse_elpd_loo, p_loo, #' looic, influence_pareto_k. #' @param diagnostics Named list containing vector `pareto_k` and vector `n_eff`. #' @param dims Log likelihood matrix dimensions (attribute of `"psis"` object). #' @template is_method #' @param is_object An object of class `"psis"/"tis"/"sis"`, as returned by the [psis()/tis()/sis()] function. #' @return A `'importance_sampling_loo'` object as described in the Value section of the [loo()] #' function documentation. #' importance_sampling_loo_object <- function(pointwise, diagnostics, dims, is_method, is_object = NULL) { if (!is.matrix(pointwise)) stop("Internal error ('pointwise' must be a matrix)") if (!is.list(diagnostics)) stop("Internal error ('diagnostics' must be a list)") assert_importance_sampling_method_is_implemented(is_method) cols_to_summarize <- !(colnames(pointwise) %in% c("mcse_elpd_loo", "influence_pareto_k")) estimates <- table_of_estimates(pointwise[, cols_to_summarize, drop=FALSE]) out <- nlist(estimates, pointwise, diagnostics) if (is.null(is_object)) { out[paste0(is_method, "_object")] <- list(NULL) } else { out[[paste0(is_method, "_object")]] <- is_object } # maintain backwards compatibility old_nms <- c("elpd_loo", "p_loo", "looic", "se_elpd_loo", "se_p_loo", "se_looic") out <- c(out, setNames(as.list(estimates), old_nms)) structure( out, dims = dims, class = c(paste0(is_method, "_loo"), "importance_sampling_loo", "loo") ) } #' Compute Monte Carlo standard error for ELPD #' #' @noRd #' @param ll Log-likelihood matrix. #' @param E_elpd elpd_loo column of pointwise matrix. #' @param psis_object Object returned by [psis()]. #' @param n_samples Number of draws to take from `Normal(E[epd_i], SD[epd_i])`. #' @return Vector of standard error estimates. #' mcse_elpd <- function(ll, lw, E_elpd, r_eff, n_samples = 1000) { lik <- exp(ll) w2 <- exp(lw)^2 E_epd <- exp(E_elpd) # zn is approximate ordered statistics of unit normal distribution with offset # recommended by Blom (1958) S <- n_samples c <- 3/8 r <- 1:n_samples zn <- qnorm((r - c) / (S - 2 * c + 1)) var_elpd <- vapply( seq_len(ncol(w2)), FUN.VALUE = numeric(1), FUN = function(i) { var_epd_i <- sum(w2[, i] * (lik[, i] - E_epd[i]) ^ 2) sd_epd_i <- sqrt(var_epd_i) z <- E_epd[i] + sd_epd_i * zn var(log(z[z > 0])) } ) sqrt(var_elpd / r_eff) } #' Warning message if r_eff not specified #' @noRd throw_loo_r_eff_warning <- function() { warning( "Relative effective sample sizes ('r_eff' argument) not specified.\n", "For models fit with MCMC, the reported PSIS effective sample sizes and \n", "MCSE estimates will be over-optimistic.", call. = FALSE ) } #' Combine many psis objects into a single psis object #' #' @noRd #' @param objects List of `"psis"` objects, each for a single observation. #' @return A single `"psis"` object. #' list2importance_sampling <- function(objects) { log_weights <- sapply(objects, "[[", "log_weights") diagnostics <- lapply(objects, "[[", "diagnostics") method <- psis_apply(objects, "method", fun = "attr", fun_val = character(1)) methods <- unique(method) if (length(methods) == 1) { method <- methods classes <- c(methods, "importance_sampling", "list") } else { classes <- c("importance_sampling", "list") } structure( list( log_weights = log_weights, diagnostics = list( pareto_k = psis_apply(diagnostics, item = "pareto_k"), n_eff = psis_apply(diagnostics, item = "n_eff") ) ), norm_const_log = psis_apply(objects, "norm_const_log", fun = "attr"), tail_len = psis_apply(objects, "tail_len", fun = "attr"), r_eff = psis_apply(objects, "r_eff", fun = "attr"), dims = dim(log_weights), method = method, class = classes ) } #' Extractor methods #' #' These are only defined in order to deprecate with a warning (rather than #' remove and break backwards compatibility) the old way of accessing the point #' estimates in a `"psis_loo"` or `"psis"` object. The new way as of #' v2.0.0 is to get them from the `"estimates"` component of the object. #' #' @name old-extractors #' @keywords internal #' @param x,i,exact,name See \link{Extract}. #' NULL #' @rdname old-extractors #' @keywords internal #' @export `[.loo` <- function(x, i) { flags <- c("elpd_loo", "se_elpd_loo", "p_loo", "se_p_loo", "looic", "se_looic", "elpd_waic", "se_elpd_waic", "p_waic", "se_p_waic", "waic", "se_waic") if (is.character(i)) { needs_warning <- which(flags == i) if (length(needs_warning)) { warning( "Accessing ", flags[needs_warning], " using '[' is deprecated ", "and will be removed in a future release. ", "Please extract the ", flags[needs_warning], " estimate from the 'estimates' component instead.", call. = FALSE ) } } NextMethod() } #' @rdname old-extractors #' @keywords internal #' @export `[[.loo` <- function(x, i, exact=TRUE) { flags <- c("elpd_loo", "se_elpd_loo", "p_loo", "se_p_loo", "looic", "se_looic", "elpd_waic", "se_elpd_waic", "p_waic", "se_p_waic", "waic", "se_waic") if (is.character(i)) { needs_warning <- which(flags == i) if (length(needs_warning)) { warning( "Accessing ", flags[needs_warning], " using '[[' is deprecated ", "and will be removed in a future release. ", "Please extract the ", flags[needs_warning], " estimate from the 'estimates' component instead.", call. = FALSE ) } } NextMethod() } #' @rdname old-extractors #' @keywords internal #' @export #' `$.loo` <- function(x, name) { flags <- c("elpd_loo", "se_elpd_loo", "p_loo", "se_p_loo", "looic", "se_looic", "elpd_waic", "se_elpd_waic", "p_waic", "se_p_waic", "waic", "se_waic") needs_warning <- which(flags == name) if (length(needs_warning)) { warning( "Accessing ", flags[needs_warning], " using '$' is deprecated ", "and will be removed in a future release. ", "Please extract the ", flags[needs_warning], " estimate from the 'estimates' component instead.", call. = FALSE ) } NextMethod() } #' Parallel psis list computations #' #' @details Refactored function to handle parallel computations #' for psis_list #' #' @keywords internal #' @inheritParams loo.function #' @param .loo_i The function used to compute individual loo contributions. #' @param .llfun See `llfun` in [loo.function()]. #' @param N The total number of observations (i.e. `nrow(data)`). #' @param method See `is_method` for [loo()] #' parallel_psis_list <- function(N, .loo_i, .llfun, data, draws, r_eff, save_psis, cores, ...){ parallel_importance_sampling_list(N, .loo_i, .llfun, data, draws, r_eff, save_psis, cores, method = "psis", ...) } #' @rdname parallel_psis_list parallel_importance_sampling_list <- function(N, .loo_i, .llfun, data, draws, r_eff, save_psis, cores, method, ...){ if (cores == 1) { psis_list <- lapply( X = seq_len(N), FUN = .loo_i, llfun = .llfun, data = data, draws = draws, r_eff = r_eff, save_psis = save_psis, is_method = method, ... ) } else { if (!os_is_windows()) { # On Mac or Linux use mclapply() for multiple cores psis_list <- parallel::mclapply( mc.cores = cores, X = seq_len(N), FUN = .loo_i, llfun = .llfun, data = data, draws = draws, r_eff = r_eff, save_psis = save_psis, is_method = method, ... ) } else { # On Windows use makePSOCKcluster() and parLapply() for multiple cores cl <- parallel::makePSOCKcluster(cores) on.exit(parallel::stopCluster(cl)) psis_list <- parallel::parLapply( cl = cl, X = seq_len(N), fun = .loo_i, llfun = .llfun, data = data, draws = draws, r_eff = r_eff, save_psis = save_psis, is_method = method, ... ) } } } loo/R/zzz.R0000644000176200001440000000122213575772017012237 0ustar liggesusers.onAttach <- function(...) { ver <- utils::packageVersion("loo") packageStartupMessage("This is loo version ", ver) packageStartupMessage( "- Online documentation and vignettes at mc-stan.org/loo" ) packageStartupMessage( "- As of v2.0.0 loo defaults to 1 core ", "but we recommend using as many as possible. ", "Use the 'cores' argument or set options(mc.cores = NUM_CORES) ", "for an entire session. " ) if (os_is_windows()) { packageStartupMessage( "- Windows 10 users: loo may be very slow if 'mc.cores' ", "is set in your .Rprofile file (see https://github.com/stan-dev/loo/issues/94)." ) } } loo/R/loo_compare.psis_loo_ss_list.R0000644000176200001440000001752613575772017017305 0ustar liggesusers#' Compare `psis_loo_ss` objects #' @noRd #' @param x A list with `psis_loo` objects. #' @param ... Currently ignored. #' @return A `compare.loo_ss` object. #' @author Mans Magnusson loo_compare.psis_loo_ss_list <- function(x, ...) { checkmate::assert_list(x, any.missing = FALSE, min.len = 1) for(i in seq_along(x)){ if (!inherits(x[[i]], "psis_loo_ss")) x[[i]] <- as.psis_loo_ss.psis_loo(x[[i]]) } loo_compare_checks.psis_loo_ss_list(x) comp <- loo_compare_matrix.psis_loo_ss_list(x) ord <- loo_compare_order(x) names(x) <- rownames(comp)[ord] rnms <- rownames(comp) elpd_diff_mat <- matrix(0, nrow = nrow(comp), ncol = 3, dimnames = list(rnms, c("elpd_diff", "se_diff", "subsampling_se_diff"))) for(i in 2:length(ord)){ elpd_diff_mat[i,] <- loo_compare_ss(ref_loo = x[ord[1]], compare_loo = x[ord[i]]) } comp <- cbind(elpd_diff_mat, comp) rownames(comp) <- rnms class(comp) <- c("compare.loo_ss", "compare.loo", class(comp)) return(comp) } #' Compare a reference loo object with a comaprison loo object #' @noRd #' @param ref_loo A named list with a `psis_loo_ss` object. #' @param compare_loo A named list with a `psis_loo_ss` object. #' @return A 1 by 3 elpd_diff estimation. loo_compare_ss <- function(ref_loo, compare_loo){ checkmate::assert_list(ref_loo, names = "named") checkmate::assert_list(compare_loo, names = "named") checkmate::assert_class(ref_loo[[1]], "psis_loo_ss") checkmate::assert_class(compare_loo[[1]], "psis_loo_ss") ref_idx <- obs_idx(ref_loo[[1]]) compare_idx <- obs_idx(compare_loo[[1]]) intersect_idx <- base::intersect(ref_idx, compare_idx) ref_subset_of_compare <- base::setequal(intersect_idx, ref_idx) compare_subset_of_ref <- base::setequal(intersect_idx, compare_idx) # Using HH estimation if (ref_loo[[1]]$loo_subsampling$estimator == "hh_pps" | compare_loo[[1]]$loo_subsampling$estimator == "hh_pps"){ warning("Hansen-Hurwitz estimator used. Naive diff SE is used.", call. = FALSE) return(loo_compare_ss_naive(ref_loo, compare_loo)) } # Same observations in both if (compare_subset_of_ref & ref_subset_of_compare){ return(loo_compare_ss_diff(ref_loo, compare_loo)) } # Use subset if (compare_subset_of_ref | ref_subset_of_compare){ if (compare_subset_of_ref) ref_loo[[1]] <- update(object = ref_loo[[1]], observations = compare_loo[[1]]) if (ref_subset_of_compare) compare_loo[[1]] <- update(compare_loo[[1]], observations = ref_loo[[1]]) message("Estimated elpd_diff using observations included in loo calculations for all models.") return(loo_compare_ss_diff(ref_loo, compare_loo)) } # If different samples if (!compare_subset_of_ref & !ref_subset_of_compare){ warning("Different subsamples in '", names(ref_loo), "' and '", names(compare_loo), "'. Naive diff SE is used.", call. = FALSE) return(loo_compare_ss_naive(ref_loo, compare_loo)) } } #' Compute a naive diff SE #' @noRd #' @inheritParams loo_compare_ss #' @return a 1 by 3 elpd_diff estimation loo_compare_ss_naive <- function(ref_loo, compare_loo){ checkmate::assert_list(ref_loo, names = "named") checkmate::assert_list(compare_loo, names = "named") checkmate::assert_class(ref_loo[[1]], "psis_loo_ss") checkmate::assert_class(compare_loo[[1]], "psis_loo_ss") elpd_loo_diff <- ref_loo[[1]]$estimates["elpd_loo","Estimate"] - compare_loo[[1]]$estimates["elpd_loo","Estimate"] elpd_loo_diff_se <- sqrt( (ref_loo[[1]]$estimates["elpd_loo","SE"])^2 + (compare_loo[[1]]$estimates["elpd_loo","SE"])^2) elpd_loo_diff_subsampling_se <- sqrt( (ref_loo[[1]]$estimates["elpd_loo","subsampling SE"])^2 + (compare_loo[[1]]$estimates["elpd_loo","subsampling SE"])^2) c(elpd_loo_diff, elpd_loo_diff_se, elpd_loo_diff_subsampling_se) } #' Compare a effective diff SE #' @noRd #' @inheritParams loo_compare_ss #' @return a 1 by 3 elpd_diff estimation loo_compare_ss_diff <- function(ref_loo, compare_loo){ checkmate::assert_list(ref_loo, names = "named") checkmate::assert_list(compare_loo, names = "named") checkmate::assert_class(ref_loo[[1]], "psis_loo_ss") checkmate::assert_class(compare_loo[[1]], "psis_loo_ss") checkmate::assert_true(identical(obs_idx(ref_loo[[1]]), obs_idx(compare_loo[[1]]))) # Assert not none as loo approximation checkmate::assert_true(ref_loo[[1]]$loo_subsampling$loo_approximation != "none") checkmate::assert_true(compare_loo[[1]]$loo_subsampling$loo_approximation != "none") diff_approx <- ref_loo[[1]]$loo_subsampling$elpd_loo_approx - compare_loo[[1]]$loo_subsampling$elpd_loo_approx diff_sample <- ref_loo[[1]]$pointwise[,"elpd_loo"] - compare_loo[[1]]$pointwise[,"elpd_loo"] est <- srs_diff_est(diff_approx, y = diff_sample, y_idx = ref_loo[[1]]$pointwise[,"idx"]) elpd_loo_diff <- est$y_hat elpd_loo_diff_se <- sqrt(est$hat_v_y) elpd_loo_diff_subsampling_se <- sqrt(est$v_y_hat) c(elpd_loo_diff, elpd_loo_diff_se, elpd_loo_diff_subsampling_se) } #' Check list of `psis_loo` objects #' @details Similar to `loo_compare_checks()` but checks dim size rather than #' pointwise dim since different pointwise sizes of `psis_loo_ss` will work. #' Can probably be removed by refactoring `loo_compare_checks()`. #' @noRd #' @inheritParams loo_compare_ss #' @return A 1 by 3 elpd_diff estimation. loo_compare_checks.psis_loo_ss_list <- function(loos) { ## errors if (length(loos) <= 1L) { stop("'loo_compare' requires at least two models.", call.=FALSE) } if (!all(sapply(loos, is.loo))) { stop("All inputs should have class 'loo'.", call.=FALSE) } Ns <- sapply(loos, function(x) x$loo_subsampling$data_dim[1]) if (!all(Ns == Ns[1L])) { stop("Not all models have the same number of data points.", call.=FALSE) } ## warnings yhash <- lapply(loos, attr, which = "yhash") yhash_ok <- sapply(yhash, function(x) { # ok only if all yhash are same (all NULL is ok) isTRUE(all.equal(x, yhash[[1]])) }) if (!all(yhash_ok)) { warning("Not all models have the same y variable. ('yhash' attributes do not match)", call. = FALSE) } if (all(sapply(loos, is.kfold))) { Ks <- unlist(lapply(loos, attr, which = "K")) if (!all(Ks == Ks[1])) { warning("Not all kfold objects have the same K value. ", "For a more accurate comparison use the same number of folds. ", call. = FALSE) } } else if (any(sapply(loos, is.kfold)) && any(sapply(loos, is.psis_loo))) { warning("Comparing LOO-CV to K-fold-CV. ", "For a more accurate comparison use the same number of folds ", "or loo for all models compared.", call. = FALSE) } } #' @rdname loo_compare #' @export print.compare.loo_ss <- function(x, ..., digits = 1, simplify = TRUE) { xcopy <- x if (inherits(xcopy, "old_compare.loo")) { if (NCOL(xcopy) >= 2 && simplify) { patts <- "^elpd_|^se_diff|^p_|^waic$|^looic$" xcopy <- xcopy[, grepl(patts, colnames(xcopy))] } } else if (NCOL(xcopy) >= 2 && simplify) { xcopy <- xcopy[, c("elpd_diff", "se_diff", "subsampling_se_diff")] } print(.fr(xcopy, digits), quote = FALSE) invisible(x) } #' Compute comparison matrix for `psis_loo_ss` objects #' @noRd #' @keywords internal #' @param loos List of `psis_loo_ss` objects. #' @return A `compare.loo_ss` matrix. loo_compare_matrix.psis_loo_ss_list <- function(loos){ tmp <- sapply(loos, function(x) { est <- x$estimates setNames(c(est), nm = c(rownames(est), paste0("se_", rownames(est)), paste0("subsampling_se_", rownames(est)))) }) colnames(tmp) <- find_model_names(loos) rnms <- rownames(tmp) comp <- tmp ord <- loo_compare_order(loos) comp <- t(comp)[ord, ] patts <- c("elpd", "p_", "^waic$|^looic$", "se_waic$|se_looic$") col_ord <- unlist(sapply(patts, function(p) grep(p, colnames(comp))), use.names = FALSE) comp <- comp[, col_ord] comp } loo/R/effective_sample_sizes.R0000644000176200001440000002174114411421542016110 0ustar liggesusers#' Convenience function for computing relative efficiencies #' #' `relative_eff()` computes the the MCMC effective sample size divided by #' the total sample size. #' #' @export #' @param x A vector, matrix, 3-D array, or function. See the **Methods (by #' class)** section below for details on specifying `x`, but where #' "log-likelihood" is mentioned replace it with one of the following #' depending on the use case: #' * For use with the [loo()] function, the values in `x` (or generated by #' `x`, if a function) should be **likelihood** values #' (i.e., `exp(log_lik)`), not on the log scale. #' * For generic use with [psis()], the values in `x` should be the reciprocal #' of the importance ratios (i.e., `exp(-log_ratios)`). #' @param chain_id A vector of length `NROW(x)` containing MCMC chain #' indexes for each each row of `x` (if a matrix) or each value in #' `x` (if a vector). No `chain_id` is needed if `x` is a 3-D #' array. If there are `C` chains then valid chain indexes are values #' in `1:C`. #' @param cores The number of cores to use for parallelization. #' @return A vector of relative effective sample sizes. #' #' @examples #' LLarr <- example_loglik_array() #' LLmat <- example_loglik_matrix() #' dim(LLarr) #' dim(LLmat) #' #' rel_n_eff_1 <- relative_eff(exp(LLarr)) #' rel_n_eff_2 <- relative_eff(exp(LLmat), chain_id = rep(1:2, each = 500)) #' all.equal(rel_n_eff_1, rel_n_eff_2) #' relative_eff <- function(x, ...) { UseMethod("relative_eff") } #' @export #' @templateVar fn relative_eff #' @template vector #' relative_eff.default <- function(x, chain_id, ...) { dim(x) <- c(length(x), 1) class(x) <- "matrix" relative_eff.matrix(x, chain_id) } #' @export #' @templateVar fn relative_eff #' @template matrix #' relative_eff.matrix <- function(x, chain_id, ..., cores = getOption("mc.cores", 1)) { x <- llmatrix_to_array(x, chain_id) relative_eff.array(x, cores = cores) } #' @export #' @templateVar fn relative_eff #' @template array #' relative_eff.array <- function(x, ..., cores = getOption("mc.cores", 1)) { stopifnot(length(dim(x)) == 3) S <- prod(dim(x)[1:2]) # posterior sample size = iter * chains if (cores == 1) { n_eff_vec <- apply(x, 3, ess_rfun) } else { if (!os_is_windows()) { n_eff_list <- parallel::mclapply( mc.cores = cores, X = seq_len(dim(x)[3]), FUN = function(i) ess_rfun(x[, , i, drop = TRUE]) ) } else { cl <- parallel::makePSOCKcluster(cores) on.exit(parallel::stopCluster(cl)) n_eff_list <- parallel::parLapply( cl = cl, X = seq_len(dim(x)[3]), fun = function(i) ess_rfun(x[, , i, drop = TRUE]) ) } n_eff_vec <- unlist(n_eff_list, use.names = FALSE) } return(n_eff_vec / S) } #' @export #' @templateVar fn relative_eff #' @template function #' @param data,draws,... Same as for the [loo()] function method. #' relative_eff.function <- function(x, chain_id, ..., cores = getOption("mc.cores", 1), data = NULL, draws = NULL) { f_i <- validate_llfun(x) # not really an llfun, should return exp(ll) or exp(-ll) N <- dim(data)[1] if (cores == 1) { n_eff_list <- lapply( X = seq_len(N), FUN = function(i) { val_i <- f_i(data_i = data[i, , drop = FALSE], draws = draws, ...) relative_eff.default(as.vector(val_i), chain_id = chain_id, cores = 1) } ) } else { if (!os_is_windows()) { n_eff_list <- parallel::mclapply( X = seq_len(N), FUN = function(i) { val_i <- f_i(data_i = data[i, , drop = FALSE], draws = draws, ...) relative_eff.default(as.vector(val_i), chain_id = chain_id, cores = 1) }, mc.cores = cores ) } else { cl <- parallel::makePSOCKcluster(cores) parallel::clusterExport(cl=cl, varlist=c("draws", "chain_id", "data"), envir=environment()) on.exit(parallel::stopCluster(cl)) n_eff_list <- parallel::parLapply( cl = cl, X = seq_len(N), fun = function(i) { val_i <- f_i(data_i = data[i, , drop = FALSE], draws = draws, ...) relative_eff.default(as.vector(val_i), chain_id = chain_id, cores = 1) } ) } } n_eff_vec <- unlist(n_eff_list, use.names = FALSE) return(n_eff_vec) } #' @export #' @describeIn relative_eff #' If `x` is an object of class `"psis"`, `relative_eff()` simply returns #' the `r_eff` attribute of `x`. relative_eff.importance_sampling <- function(x, ...) { attr(x, "r_eff") } # internal ---------------------------------------------------------------- #' Effective sample size for PSIS #' #' @noRd #' @param w A vector or matrix (one column per observation) of normalized Pareto #' smoothed weights (not log weights). #' @param r_eff Relative effective sample size of `exp(log_lik)` or #' `exp(-log_ratios)`. `r_eff` should be a scalar if `w` is a #' vector and a vector of length `ncol(w)` if `w` is a matrix. #' @return A scalar if `w` is a vector. A vector of length `ncol(w)` #' if `w` is matrix. #' psis_n_eff <- function(w, ...) { UseMethod("psis_n_eff") } psis_n_eff.default <- function(w, r_eff = NULL, ...) { ss <- sum(w^2) if (is.null(r_eff)) { warning("PSIS n_eff not adjusted based on MCMC n_eff.", call. = FALSE) return(1 / ss) } stopifnot(length(r_eff) == 1) 1 / ss * r_eff } psis_n_eff.matrix <- function(w, r_eff = NULL, ...) { ss <- colSums(w^2) if (is.null(r_eff)) { warning("PSIS n_eff not adjusted based on MCMC n_eff.", call. = FALSE) return(1 / ss) } if (length(r_eff) != length(ss)) stop("r_eff must have length ncol(w).", call. = FALSE) 1 / ss * r_eff } #' MCMC effective sample size calculation #' #' @noRd #' @param sims An iterations by chains matrix of draws for a single parameter. #' In the case of the **loo** package, this will be the **exponentiated** #' log-likelihood values for the ith observation. #' @return MCMC effective sample size based on RStan's calculation. #' ess_rfun <- function(sims) { if (is.vector(sims)) dim(sims) <- c(length(sims), 1) chains <- ncol(sims) n_samples <- nrow(sims) if (requireNamespace("posterior", quietly = TRUE)) { acov <- lapply(1:chains, FUN = function(i) posterior::autocovariance(sims[,i])) } else { acov <- lapply(1:chains, FUN = function(i) autocovariance(sims[,i])) } acov <- do.call(cbind, acov) chain_mean <- colMeans(sims) mean_var <- mean(acov[1,]) * n_samples / (n_samples - 1) var_plus <- mean_var * (n_samples - 1) / n_samples if (chains > 1) var_plus <- var_plus + var(chain_mean) # Geyer's initial positive sequence rho_hat_t <- rep.int(0, n_samples) t <- 0 rho_hat_even <- 1 rho_hat_t[t + 1] <- rho_hat_even rho_hat_odd <- 1 - (mean_var - mean(acov[t + 2, ])) / var_plus rho_hat_t[t + 2] <- rho_hat_odd while (t < nrow(acov) - 5 && !is.nan(rho_hat_even + rho_hat_odd) && (rho_hat_even + rho_hat_odd > 0)) { t <- t + 2 rho_hat_even = 1 - (mean_var - mean(acov[t + 1, ])) / var_plus rho_hat_odd = 1 - (mean_var - mean(acov[t + 2, ])) / var_plus if ((rho_hat_even + rho_hat_odd) >= 0) { rho_hat_t[t + 1] <- rho_hat_even rho_hat_t[t + 2] <- rho_hat_odd } } max_t <- t # this is used in the improved estimate if (rho_hat_even>0) rho_hat_t[max_t + 1] <- rho_hat_even # Geyer's initial monotone sequence t <- 0 while (t <= max_t - 4) { t <- t + 2 if (rho_hat_t[t + 1] + rho_hat_t[t + 2] > rho_hat_t[t - 1] + rho_hat_t[t]) { rho_hat_t[t + 1] = (rho_hat_t[t - 1] + rho_hat_t[t]) / 2; rho_hat_t[t + 2] = rho_hat_t[t + 1]; } } ess <- chains * n_samples # Geyer's truncated estimate # tau_hat <- -1 + 2 * sum(rho_hat_t[1:max_t]) # Improved estimate reduces variance in antithetic case tau_hat <- -1 + 2 * sum(rho_hat_t[1:max_t]) + rho_hat_t[max_t+1] # Safety check for negative values and with max ess equal to ess*log10(ess) tau_hat <- max(tau_hat, 1/log10(ess)) ess <- ess / tau_hat ess } fft_next_good_size <- function(N) { # Find the optimal next size for the FFT so that # a minimum number of zeros are padded. if (N <= 2) return(2) while (TRUE) { m = N while ((m %% 2) == 0) m = m / 2 while ((m %% 3) == 0) m = m / 3 while ((m %% 5) == 0) m = m / 5 if (m <= 1) return(N) N = N + 1 } } # autocovariance function to use if posterior::autocovariance is not available autocovariance <- function(y) { # Compute autocovariance estimates for every lag for the specified # input sequence using a fast Fourier transform approach. N <- length(y) M <- fft_next_good_size(N) Mt2 <- 2 * M yc <- y - mean(y) yc <- c(yc, rep.int(0, Mt2-N)) transform <- stats::fft(yc) ac <- stats::fft(Conj(transform) * transform, inverse = TRUE) # use "biased" estimate as recommended by Geyer (1992) ac <- Re(ac)[1:N] / (N^2 * 2) ac } loo/R/helpers.R0000644000176200001440000001161714372466116013051 0ustar liggesusers#' Detect if OS is Windows #' @noRd os_is_windows <- function() { checkmate::test_os("windows") } #' More stable version of `log(mean(exp(x)))` #' #' @noRd #' @param x A numeric vector. #' @return A scalar equal to `log(mean(exp(x)))`. #' logMeanExp <- function(x) { logS <- log(length(x)) matrixStats::logSumExp(x) - logS } #' More stable version of `log(colMeans(exp(x)))` #' #' @noRd #' @param x A matrix. #' @return A vector where each element is `logMeanExp()` of a column of `x`. #' colLogMeanExps <- function(x) { logS <- log(nrow(x)) matrixStats::colLogSumExps(x) - logS } #' Compute point estimates and standard errors from pointwise vectors #' #' @noRd #' @param x A matrix. #' @return An `ncol(x)` by 2 matrix with columns `"Estimate"` and `"SE"` #' and rownames equal to `colnames(x)`. #' table_of_estimates <- function(x) { out <- cbind( Estimate = matrixStats::colSums2(x), SE = sqrt(nrow(x) * matrixStats::colVars(x)) ) rownames(out) <- colnames(x) return(out) } # validating and reshaping arrays/matrices ------------------------------- #' Check for `NA` and non-finite values in log-lik (or log-ratios) #' array/matrix/vector #' #' @noRd #' @param x Array/matrix/vector of log-likelihood or log-ratio values. #' @return `x`, invisibly, if no error is thrown. #' validate_ll <- function(x) { if (is.list(x)) { stop("List not allowed as input.") } else if (anyNA(x)) { stop("NAs not allowed in input.") } else if (!all(is.finite(x))) { stop("All input values must be finite.") } invisible(x) } #' Convert iter by chain by obs array to (iter * chain) by obs matrix #' #' @noRd #' @param x Array to convert. #' @return An (iter * chain) by obs matrix. #' llarray_to_matrix <- function(x) { stopifnot(is.array(x), length(dim(x)) == 3) xdim <- dim(x) dim(x) <- c(prod(xdim[1:2]), xdim[3]) unname(x) } #' Convert (iter * chain) by obs matrix to iter by chain by obs array #' #' @noRd #' @param x matrix to convert. #' @param chain_id vector of chain ids. #' @return iter by chain by obs array #' llmatrix_to_array <- function(x, chain_id) { stopifnot(is.matrix(x), all(chain_id == as.integer(chain_id))) lldim <- dim(x) n_chain <- length(unique(chain_id)) chain_id <- as.integer(chain_id) chain_counts <- as.numeric(table(chain_id)) if (length(chain_id) != lldim[1]) { stop("Number of rows in matrix not equal to length(chain_id).", call. = FALSE) } else if (any(chain_counts != chain_counts[1])) { stop("Not all chains have same number of iterations.", call. = FALSE) } else if (max(chain_id) != n_chain) { stop("max(chain_id) not equal to the number of chains.", call. = FALSE) } n_iter <- lldim[1] / n_chain n_obs <- lldim[2] a <- array(data = NA, dim = c(n_iter, n_chain, n_obs)) for (c in seq_len(n_chain)) { a[, c, ] <- x[chain_id == c, , drop = FALSE] } return(a) } #' Validate that log-lik function exists and has correct arg names #' #' @noRd #' @param x A function with arguments `data_i` and `draws`. #' @return Either returns `x` or throws an error. #' validate_llfun <- function(x) { f <- match.fun(x) must_have <- c("data_i", "draws") arg_names <- names(formals(f)) if (!all(must_have %in% arg_names)) { stop( "Log-likelihood function must have at least the arguments ", "'data_i' and 'draws'", call. = FALSE ) } return(f) } #' Named lists #' #' Create a named list using specified names or, if names are omitted, using the #' names of the objects in the list. The code `list(a = a, b = b)` becomes #' `nlist(a,b)` and `list(a = a, b = 2)` becomes `nlist(a, b = 2)`, etc. #' #' @export #' @keywords internal #' @param ... Objects to include in the list. #' @return A named list. #' @examples #' #' # All variables already defined #' a <- rnorm(100) #' b <- mat.or.vec(10, 3) #' nlist(a,b) #' #' # Define some variables in the call and take the rest from the environment #' nlist(a, b, veggies = c("lettuce", "spinach"), fruits = c("banana", "papaya")) #' nlist <- function(...) { m <- match.call() out <- list(...) no_names <- is.null(names(out)) has_name <- if (no_names) FALSE else nzchar(names(out)) if (all(has_name)) return(out) nms <- as.character(m)[-1L] if (no_names) { names(out) <- nms } else { names(out)[!has_name] <- nms[!has_name] } return(out) } # Check how many cores to use and throw deprecation warning if loo.cores is used loo_cores <- function(cores) { loo_cores_op <- getOption("loo.cores", NA) if (!is.na(loo_cores_op) && (loo_cores_op != cores)) { cores <- loo_cores_op warning("'loo.cores' is deprecated, please use 'mc.cores' or pass 'cores' explicitly.", call. = FALSE) } return(cores) } # nocov start # release reminders (for devtools) release_questions <- function() { c( "Have you updated references?", "Have you updated inst/CITATION?", "Have you updated the vignettes?" ) } # nocov end loo/R/gpdfit.R0000644000176200001440000000624614407123455012661 0ustar liggesusers#' Estimate parameters of the Generalized Pareto distribution #' #' Given a sample \eqn{x}, Estimate the parameters \eqn{k} and \eqn{\sigma} of #' the generalized Pareto distribution (GPD), assuming the location parameter is #' 0. By default the fit uses a prior for \eqn{k}, which will stabilize #' estimates for very small sample sizes (and low effective sample sizes in the #' case of MCMC samples). The weakly informative prior is a Gaussian prior #' centered at 0.5. #' #' @export #' @param x A numeric vector. The sample from which to estimate the parameters. #' @param wip Logical indicating whether to adjust \eqn{k} based on a weakly #' informative Gaussian prior centered on 0.5. Defaults to `TRUE`. #' @param min_grid_pts The minimum number of grid points used in the fitting #' algorithm. The actual number used is `min_grid_pts + floor(sqrt(length(x)))`. #' @param sort_x If `TRUE` (the default), the first step in the fitting #' algorithm is to sort the elements of `x`. If `x` is already #' sorted in ascending order then `sort_x` can be set to `FALSE` to #' skip the initial sorting step. #' @return A named list with components `k` and `sigma`. #' #' @details Here the parameter \eqn{k} is the negative of \eqn{k} in Zhang & #' Stephens (2009). #' #' @seealso [psis()], [pareto-k-diagnostic] #' #' @references #' Zhang, J., and Stephens, M. A. (2009). A new and efficient estimation method #' for the generalized Pareto distribution. *Technometrics* **51**, 316-325. #' gpdfit <- function(x, wip = TRUE, min_grid_pts = 30, sort_x = TRUE) { # See section 4 of Zhang and Stephens (2009) if (sort_x) { x <- sort.int(x) } N <- length(x) prior <- 3 M <- min_grid_pts + floor(sqrt(N)) jj <- seq_len(M) xstar <- x[floor(N / 4 + 0.5)] # first quartile of sample theta <- 1 / x[N] + (1 - sqrt(M / (jj - 0.5))) / prior / xstar l_theta <- N * lx(theta, x) # profile log-lik w_theta <- exp(l_theta - matrixStats::logSumExp(l_theta)) # normalize theta_hat <- sum(theta * w_theta) k <- mean.default(log1p(-theta_hat * x)) sigma <- -k / theta_hat if (wip) { k <- adjust_k_wip(k, n = N) } if (is.nan(k)) { k <- Inf } nlist(k, sigma) } # internal ---------------------------------------------------------------- lx <- function(a,x) { a <- -a k <- vapply(a, FUN = function(a_i) mean(log1p(a_i * x)), FUN.VALUE = numeric(1)) log(a / k) - k - 1 } #' Adjust k based on weakly informative prior, Gaussian centered on 0.5. This #' will stabilize estimates for very small Monte Carlo sample sizes and low neff #' cases. #' #' @noRd #' @param k Scalar khat estimate. #' @param n Integer number of tail samples used to fit GPD. #' @return Scalar adjusted khat estimate. #' adjust_k_wip <- function(k, n) { a <- 10 n_plus_a <- n + a k * n / n_plus_a + a * 0.5 / n_plus_a } #' Inverse CDF of generalized pareto distribution #' (assuming location parameter is 0) #' #' @noRd #' @param p Vector of probabilities. #' @param k Scalar shape parameter. #' @param sigma Scalar scale parameter. #' @return Vector of quantiles. #' qgpd <- function(p, k, sigma) { if (is.nan(sigma) || sigma <= 0) { return(rep(NaN, length(p))) } sigma * expm1(-k * log1p(-p)) / k } loo/R/loo-package.R0000644000176200001440000001027114407123455013557 0ustar liggesusers#' Efficient LOO-CV and WAIC for Bayesian models #' #' @docType package #' @name loo-package #' #' @importFrom stats sd var quantile setNames weights rnorm qnorm #' @importFrom matrixStats logSumExp colLogSumExps colSums2 colVars colMaxs #' #' @description #' \if{html}{ #' \figure{stanlogo.png}{options: width="50" alt="mc-stan.org"} #' } #' *Stan Development Team* #' #' This package implements the methods described in Vehtari, Gelman, and #' Gabry (2017), Vehtari, Simpson, Gelman, Yao, and Gabry (2019), and #' Yao et al. (2018). To get started see the **loo** package #' [vignettes](https://mc-stan.org/loo/articles/index.html), the #' [loo()] function for efficient approximate leave-one-out #' cross-validation (LOO-CV), the [psis()] function for the Pareto #' smoothed importance sampling (PSIS) algorithm, or #' [loo_model_weights()] for an implementation of Bayesian stacking of #' predictive distributions from multiple models. #' #' #' @details Leave-one-out cross-validation (LOO-CV) and the widely applicable #' information criterion (WAIC) are methods for estimating pointwise #' out-of-sample prediction accuracy from a fitted Bayesian model using the #' log-likelihood evaluated at the posterior simulations of the parameter #' values. LOO-CV and WAIC have various advantages over simpler estimates of #' predictive error such as AIC and DIC but are less used in practice because #' they involve additional computational steps. This package implements the #' fast and stable computations for approximate LOO-CV laid out in Vehtari, #' Gelman, and Gabry (2017). From existing posterior simulation draws, we #' compute LOO-CV using Pareto smoothed importance sampling (PSIS; Vehtari, #' Simpson, Gelman, Yao, and Gabry, 2019), a new procedure for stabilizing #' and diagnosing importance weights. As a byproduct of our calculations, #' we also obtain approximate standard errors for estimated predictive #' errors and for comparing of predictive errors between two models. #' #' We recommend PSIS-LOO-CV instead of WAIC, because PSIS provides useful #' diagnostics and effective sample size and Monte Carlo standard error #' estimates. #' #' #' @template loo-and-psis-references #' @template stacking-references #' @template loo-large-data-references #' #' @references #' Epifani, I., MacEachern, S. N., and Peruggia, M. (2008). Case-deletion #' importance sampling estimators: Central limit theorems and related results. #' *Electronic Journal of Statistics* **2**, 774-806. #' #' Gelfand, A. E. (1996). Model determination using sampling-based methods. In #' *Markov Chain Monte Carlo in Practice*, ed. W. R. Gilks, S. Richardson, #' D. J. Spiegelhalter, 145-162. London: Chapman and Hall. #' #' Gelfand, A. E., Dey, D. K., and Chang, H. (1992). Model determination using #' predictive distributions with implementation via sampling-based methods. In #' *Bayesian Statistics 4*, ed. J. M. Bernardo, J. O. Berger, A. P. Dawid, #' and A. F. M. Smith, 147-167. Oxford University Press. #' #' Gelman, A., Hwang, J., and Vehtari, A. (2014). Understanding predictive #' information criteria for Bayesian models. *Statistics and Computing* #' **24**, 997-1016. #' #' Ionides, E. L. (2008). Truncated importance sampling. *Journal of #' Computational and Graphical Statistics* **17**, 295-311. #' #' Koopman, S. J., Shephard, N., and Creal, D. (2009). Testing the assumptions #' behind importance sampling. *Journal of Econometrics* **149**, 2-11. #' #' Peruggia, M. (1997). On the variability of case-deletion importance sampling #' weights in the Bayesian linear model. *Journal of the American #' Statistical Association* **92**, 199-207. #' #' Stan Development Team (2017). The Stan C++ Library, Version 2.17.0. #' . #' #' Stan Development Team (2018). RStan: the R interface to Stan, Version 2.17.3. #' . #' #' Watanabe, S. (2010). Asymptotic equivalence of Bayes cross validation and #' widely application information criterion in singular learning theory. #' *Journal of Machine Learning Research* **11**, 3571-3594. #' #' Zhang, J., and Stephens, M. A. (2009). A new and efficient estimation method #' for the generalized Pareto distribution. *Technometrics* **51**, #' 316-325. #' NULL loo/R/loo-glossary.R0000644000176200001440000001430614214417101014020 0ustar liggesusers#' LOO package glossary #' #' @name loo-glossary #' #' @template loo-and-psis-references #' @template bayesvis-reference #' #' @description #' The pages provides definitions to key terms. Also see the #' [FAQ page](https://mc-stan.org/loo/articles/online-only/faq.html) on #' the __loo__ website for answers to frequently asked questions. #' #' Note: VGG2017 refers to Vehtari, Gelman, and Gabry (2017). See #' **References**, below. #' #' @section ELPD and `elpd_loo`: #' #' The ELPD is the theoretical expected log pointwise predictive density for a new #' dataset (Eq 1 in VGG2017), which can be estimated, e.g., using #' cross-validation. `elpd_loo` is the Bayesian LOO estimate of the #' expected log pointwise predictive density (Eq 4 in VGG2017) and #' is a sum of N individual pointwise log predictive densities. Probability #' densities can be smaller or larger than 1, and thus log predictive densities #' can be negative or positive. For simplicity the ELPD acronym is used also for #' expected log pointwise predictive probabilities for discrete models. #' Probabilities are always equal or less than 1, and thus log predictive #' probabilities are 0 or negative. #' #' @section Standard error of `elpd_loo`: #' #' As `elpd_loo` is defined as the sum of N independent components (Eq 4 in #' VGG2017), we can compute the standard error by using the standard deviation #' of the N components and multiplying by `sqrt(N)` (Eq 23 in VGG2017). #' This standard error is a coarse description of our uncertainty about the #' predictive performance for unknown future data. When N is small or there is #' severe model misspecification, the current SE estimate is overoptimistic and #' the actual SE can even be twice as large. Even for moderate N, when the SE #' estimate is an accurate estimate for the scale, it ignores the skewness. When #' making model comparisons, the SE of the component-wise (pairwise) differences #' should be used instead (see the `se_diff` section below and Eq 24 in #' VGG2017). #' #' @section Monte Carlo SE of elpd_loo: #' #' The Monte Carlo standard error is the estimate for the computational accuracy #' of MCMC and importance sampling used to compute `elpd_loo`. Usually this #' is negligible compared to the standard describing the uncertainty due to #' finite number of observations (Eq 23 in VGG2017). #' #' @section `p_loo` (effective number of parameters): #' #' `p_loo` is the difference between `elpd_loo` and the non-cross-validated #' log posterior predictive density. It describes how much more difficult it #' is to predict future data than the observed data. Asymptotically under #' certain regularity conditions, `p_loo` can be interpreted as the #' *effective number of parameters*. In well behaving cases `p_loo < N` and #' `p_loo < p`, where `p` is the total number of parameters in the #' model. `p_loo > N` or `p_loo > p` indicates that the model has very #' weak predictive capability and may indicate a severe model misspecification. #' See below for more on interpreting `p_loo` when there are warnings #' about high Pareto k diagnostic values. #' #' @section Pareto k estimates: #' #' The Pareto `k` estimate is a diagnostic for Pareto smoothed importance #' sampling (PSIS), which is used to compute components of `elpd_loo`. In #' importance-sampling LOO (the full posterior distribution is used as the #' proposal distribution). The Pareto k diagnostic estimates how far an #' individual leave-one-out distribution is from the full distribution. If #' leaving out an observation changes the posterior too much then importance #' sampling is not able to give reliable estimate. If `k<0.5`, then the #' corresponding component of `elpd_loo` is estimated with high accuracy. #' If `0.50.7`, #' then importance sampling is not able to provide useful estimate for that #' component/observation. Pareto k is also useful as a measure of influence of #' an observation. Highly influential observations have high k values. Very high #' k values often indicate model misspecification, outliers or mistakes in data #' processing. See Section 6 of Gabry et al. (2019) for an example. #' #' \subsection{Interpreting `p_loo` when Pareto `k` is large}{ #' If `k > 0.7` then we can also look at the `p_loo` estimate for #' some additional information about the problem: #' #' \itemize{ #' \item If `p_loo << p` (the total number of parameters in the model), #' then the model is likely to be misspecified. Posterior predictive checks #' (PPCs) are then likely to also detect the problem. Try using an overdispersed #' model, or add more structural information (nonlinearity, mixture model, #' etc.). #' #' \item If `p_loo < p` and the number of parameters `p` is relatively #' large compared to the number of observations (e.g., `p>N/5`), it is #' likely that the model is so flexible or the population prior so weak that it’s #' difficult to predict the left out observation (even for the true model). #' This happens, for example, in the simulated 8 schools (in VGG2017), random #' effect models with a few observations per random effect, and Gaussian #' processes and spatial models with short correlation lengths. #' #' \item If `p_loo > p`, then the model is likely to be badly misspecified. #' If the number of parameters `p< for an example. #' If `p` is relatively large compared to the number of #' observations, say `p>N/5` (more accurately we should count number of #' observations influencing each parameter as in hierarchical models some groups #' may have few observations and other groups many), it is possible that PPCs won't #' detect the problem. #' } #' } #' #' @section elpd_diff: #' `elpd_diff` is the difference in `elpd_loo` for two models. If more #' than two models are compared, the difference is computed relative to the #' model with highest `elpd_loo`. #' #' @section se_diff: #' #' The standard error of component-wise differences of elpd_loo (Eq 24 in #' VGG2017) between two models. This SE is *smaller* than the SE for #' individual models due to correlation (i.e., if some observations are easier #' and some more difficult to predict for all models). #' NULL loo/R/psis_approximate_posterior.R0000644000176200001440000001066213575772017017107 0ustar liggesusers#' Diagnostics for Laplace and ADVI approximations and Laplace-loo and ADVI-loo #' #' @param log_p The log-posterior (target) evaluated at S samples from the #' proposal distribution (g). A vector of length S. #' @param log_g The log-density (proposal) evaluated at S samples from the #' proposal distribution (g). A vector of length S. #' @param log_q Deprecated argument name (the same as log_g). #' @param log_liks A log-likelihood matrix of size S * N, where N is the number #' of observations and S is the number of samples from q. See #' [loo.matrix()] for details. Default is `NULL`. Then only the #' posterior is evaluated using the k_hat diagnostic. #' @inheritParams loo #' #' @return #' If log likelihoods are supplied, the function returns a `"loo"` object, #' otherwise the function returns a `"psis"` object. #' #' @seealso [loo()] and [psis()] #' #' @template loo-and-psis-references #' #' @keywords internal #' psis_approximate_posterior <- function(log_p = NULL, log_g = NULL, log_liks = NULL, cores, save_psis, ..., log_q = NULL) { if (!is.null(log_q)) { .Deprecated(msg = "psis_approximate_posterior() argument log_q has been changed to log_g") log_g <- log_q } checkmate::assert_numeric(log_p, any.missing = FALSE, len = length(log_g), null.ok = FALSE) checkmate::assert_numeric(log_g, any.missing = FALSE, len = length(log_p), null.ok = FALSE) checkmate::assert_matrix(log_liks, null.ok = TRUE, nrows = length(log_p)) checkmate::assert_integerish(cores) checkmate::assert_flag(save_psis) if (is.null(log_liks)) { approx_correction <- log_p - log_g # Handle underflow/overflow approx_correction <- approx_correction - max(approx_correction) log_ratios <- matrix(approx_correction, ncol = 1) } else { log_ratios <- correct_log_ratios(log_ratios = -log_liks, log_p = log_p, log_g = log_g) } psis_out <- psis.matrix(log_ratios, cores = cores, r_eff = rep(1, ncol(log_ratios))) if (is.null(log_liks)) { return(psis_out) } pointwise <- pointwise_loo_calcs(log_liks, psis_out) importance_sampling_loo_object( pointwise = pointwise, diagnostics = psis_out$diagnostics, dims = dim(psis_out), is_method = "psis", is_object = if (save_psis) psis_out else NULL ) } #' Correct log ratios for posterior approximations #' #' @inheritParams psis_approximate_posterior #' @inheritParams ap_psis #' @noRd #' @keywords internal correct_log_ratios <- function(log_ratios, log_p, log_g) { approx_correction <- log_p - log_g log_ratios <- log_ratios + approx_correction # Handle underflow/overflow log_ratio_max <- apply(log_ratios, 2, max) log_ratios <- sweep(log_ratios, MARGIN = 2, STATS = log_ratio_max) log_ratios } #' Pareto smoothed importance sampling (PSIS) #' using approximate posteriors #' @inheritParams psis_approximate_posterior #' @param log_ratios The log-likelihood ratios (ie -log_liks) #' @param ... Currently not in use. ap_psis <- function(log_ratios, log_p, log_g, ...) { UseMethod("ap_psis") } #' @export #' @templateVar fn ap_psis #' @template array #' ap_psis.array <- function(log_ratios, log_p, log_g, ..., cores = getOption("mc.cores", 1)) { cores <- loo_cores(cores) stopifnot(length(dim(log_ratios)) == 3) log_ratios <- validate_ll(log_ratios) log_ratios <- llarray_to_matrix(log_ratios) r_eff <- prepare_psis_r_eff(r_eff, len = ncol(log_ratios)) ap_psis.matrix(log_ratios = log_ratios, log_p = log_p, log_g = log_g, cores = 1) } #' @export #' @templateVar fn ap_psis #' @template matrix #' ap_psis.matrix <- function(log_ratios, log_p, log_g, ..., cores = getOption("mc.cores", 1)) { checkmate::assert_numeric(log_p, len = nrow(log_ratios)) checkmate::assert_numeric(log_g, len = nrow(log_ratios)) cores <- loo_cores(cores) log_ratios <- validate_ll(log_ratios) log_ratios <- correct_log_ratios(log_ratios, log_p = log_p, log_g = log_g) do_psis(log_ratios, r_eff = rep(1, ncol(log_ratios)), cores = cores) } #' @export #' @templateVar fn ap_psis #' @template vector #' ap_psis.default <- function(log_ratios, log_p, log_g, ...) { stopifnot(is.null(dim(log_ratios)) || length(dim(log_ratios)) == 1) dim(log_ratios) <- c(length(log_ratios), 1) warning("llfun values do not return a matrix, coerce to matrix") ap_psis.matrix(as.matrix(log_ratios), log_p, log_g, cores = 1) } loo/R/psis.R0000644000176200001440000003171714407123455012363 0ustar liggesusers#' Pareto smoothed importance sampling (PSIS) #' #' Implementation of Pareto smoothed importance sampling (PSIS), a method for #' stabilizing importance ratios. The version of PSIS implemented here #' corresponds to the algorithm presented in Vehtari, Simpson, Gelman, Yao, #' and Gabry (2019). #' For PSIS diagnostics see the [pareto-k-diagnostic] page. #' #' @export #' @param log_ratios An array, matrix, or vector of importance ratios on the log #' scale (for PSIS-LOO these are *negative* log-likelihood values). See the #' **Methods (by class)** section below for a detailed description of how #' to specify the inputs for each method. #' @param ... Arguments passed on to the various methods. #' @template cores #' @param r_eff Vector of relative effective sample size estimates containing #' one element per observation. The values provided should be the relative #' effective sample sizes of `1/exp(log_ratios)` (i.e., `1/ratios`). #' This is related to the relative efficiency of estimating the normalizing #' term in self-normalizing importance sampling. If `r_eff` is not #' provided then the reported PSIS effective sample sizes and Monte Carlo #' error estimates will be over-optimistic. See the [relative_eff()] #' helper function for computing `r_eff`. If using `psis` with #' draws of the `log_ratios` not obtained from MCMC then the warning #' message thrown when not specifying `r_eff` can be disabled by #' setting `r_eff` to `NA`. #' #' @return The `psis()` methods return an object of class `"psis"`, #' which is a named list with the following components: #' #' \describe{ #' \item{`log_weights`}{ #' Vector or matrix of smoothed (and truncated) but *unnormalized* log #' weights. To get normalized weights use the #' [`weights()`][weights.importance_sampling] method provided for objects of #' class `"psis"`. #' } #' \item{`diagnostics`}{ #' A named list containing two vectors: #' * `pareto_k`: Estimates of the shape parameter \eqn{k} of the #' generalized Pareto distribution. See the [pareto-k-diagnostic] #' page for details. #' * `n_eff`: PSIS effective sample size estimates. #' } #' } #' #' Objects of class `"psis"` also have the following [attributes][attributes()]: #' \describe{ #' \item{`norm_const_log`}{ #' Vector of precomputed values of `colLogSumExps(log_weights)` that are #' used internally by the `weights` method to normalize the log weights. #' } #' \item{`tail_len`}{ #' Vector of tail lengths used for fitting the generalized Pareto distribution. #' } #' \item{`r_eff`}{ #' If specified, the user's `r_eff` argument. #' } #' \item{`dims`}{ #' Integer vector of length 2 containing `S` (posterior sample size) #' and `N` (number of observations). #' } #' \item{`method`}{ #' Method used for importance sampling, here `psis`. #' } #' } #' #' @seealso #' * [loo()] for approximate LOO-CV using PSIS. #' * [pareto-k-diagnostic] for PSIS diagnostics. #' * The __loo__ package [vignettes](https://mc-stan.org/loo/articles/index.html) #' for demonstrations. #' * The [FAQ page](https://mc-stan.org/loo/articles/online-only/faq.html) on #' the __loo__ website for answers to frequently asked questions. #' #' @template loo-and-psis-references #' #' @examples #' log_ratios <- -1 * example_loglik_array() #' r_eff <- relative_eff(exp(-log_ratios)) #' psis_result <- psis(log_ratios, r_eff = r_eff) #' str(psis_result) #' plot(psis_result) #' #' # extract smoothed weights #' lw <- weights(psis_result) # default args are log=TRUE, normalize=TRUE #' ulw <- weights(psis_result, normalize=FALSE) # unnormalized log-weights #' #' w <- weights(psis_result, log=FALSE) # normalized weights (not log-weights) #' uw <- weights(psis_result, log=FALSE, normalize = FALSE) # unnormalized weights #' #' #' psis <- function(log_ratios, ...) UseMethod("psis") #' @export #' @templateVar fn psis #' @template array #' psis.array <- function(log_ratios, ..., r_eff = NULL, cores = getOption("mc.cores", 1)) { importance_sampling.array(log_ratios = log_ratios, ..., r_eff = r_eff, cores = cores, method = "psis") } #' @export #' @templateVar fn psis #' @template matrix #' psis.matrix <- function(log_ratios, ..., r_eff = NULL, cores = getOption("mc.cores", 1)) { importance_sampling.matrix(log_ratios, ..., r_eff = r_eff, cores = cores, method = "psis") } #' @export #' @templateVar fn psis #' @template vector #' psis.default <- function(log_ratios, ..., r_eff = NULL) { importance_sampling.default(log_ratios = log_ratios, ..., r_eff = r_eff, method = "psis") } #' @rdname psis #' @export #' @param x For `is.psis()`, an object to check. is.psis <- function(x) { inherits(x, "psis") && is.list(x) } # internal ---------------------------------------------------------------- #' @noRd #' @seealso importance_sampling_object psis_object <- function(unnormalized_log_weights, pareto_k, tail_len, r_eff) { importance_sampling_object(unnormalized_log_weights = unnormalized_log_weights, pareto_k = pareto_k, tail_len = tail_len, r_eff = r_eff, method = "psis") } #' @noRd #' @seealso do_importance_sampling do_psis <- function(log_ratios, r_eff, cores, method){ do_importance_sampling(log_ratios = log_ratios, r_eff = r_eff, cores = cores, method = "psis") } #' Extract named components from each list in the list of lists obtained by #' parallelizing `do_psis_i()` #' #' @noRd #' @param x List of lists. #' @param item String naming the component or attribute to pull out of each list #' (or list-like object). #' @param fun,fun.val passed to `vapply()`'s `FUN` and `FUN.VALUE` arguments. #' @return Numeric vector or matrix. #' psis_apply <- function(x, item, fun = c("[[", "attr"), fun_val = numeric(1)) { if (!is.list(x)) stop("Internal error ('x' must be a list for psis_apply)") vapply(x, FUN = match.arg(fun), FUN.VALUE = fun_val, item) } #' PSIS on a single vector #' #' @noRd #' @param log_ratios_i A vector of log importance ratios (for `loo()`, negative #' log likelihoods). #' @param tail_len_i An integer tail length. #' @param ... Not used. Included to conform to API for differen IS methods. #' #' @details #' * If there are enough tail samples then the tail is smoothed with PSIS #' * The log weights (or log ratios if no smoothing) larger than the largest raw #' ratio are set to the largest raw ratio #' #' @return A named list containing: #' * `lw`: vector of unnormalized log weights #' * `pareto_k`: scalar Pareto k estimate. #' do_psis_i <- function(log_ratios_i, tail_len_i, ...) { S <- length(log_ratios_i) # shift log ratios for safer exponentation lw_i <- log_ratios_i - max(log_ratios_i) khat <- Inf if (enough_tail_samples(tail_len_i)) { ord <- sort.int(lw_i, index.return = TRUE) tail_ids <- seq(S - tail_len_i + 1, S) lw_tail <- ord$x[tail_ids] if (abs(max(lw_tail) - min(lw_tail)) < .Machine$double.eps/100) { warning( "Can't fit generalized Pareto distribution ", "because all tail values are the same.", call. = FALSE ) } else { cutoff <- ord$x[min(tail_ids) - 1] # largest value smaller than tail values smoothed <- psis_smooth_tail(lw_tail, cutoff) khat <- smoothed$k lw_i[ord$ix[tail_ids]] <- smoothed$tail } } # truncate at max of raw wts (i.e., 0 since max has been subtracted) lw_i[lw_i > 0] <- 0 # shift log weights back so that the smallest log weights remain unchanged lw_i <- lw_i + max(log_ratios_i) list(log_weights = lw_i, pareto_k = khat) } #' PSIS tail smoothing for a single vector #' #' @noRd #' @param x Vector of tail elements already sorted in ascending order. #' @return A named list containing: #' * `tail`: vector same size as `x` containing the logs of the #' order statistics of the generalized pareto distribution. #' * `k`: scalar shape parameter estimate. #' psis_smooth_tail <- function(x, cutoff) { len <- length(x) exp_cutoff <- exp(cutoff) # save time not sorting since x already sorted fit <- gpdfit(exp(x) - exp_cutoff, sort_x = FALSE) k <- fit$k sigma <- fit$sigma if (is.finite(k)) { p <- (seq_len(len) - 0.5) / len qq <- qgpd(p, k, sigma) + exp_cutoff tail <- log(qq) } else { tail <- x } list(tail = tail, k = k) } #' Calculate tail lengths to use for fitting the GPD #' #' The number of weights (i.e., tail length) used to fit the generalized Pareto #' distribution is now decreasing with the number of posterior draws S, and is #' also adjusted based on the relative MCMC neff for `exp(log_lik)`. This will #' answer the questions about the asymptotic properties, works better for thick #' tailed proposal distributions, and is adjusted based on dependent Markov chain #' samples. Specifically, the tail length is now `3*sqrt(S)/r_eff` but capped at #' 20% of the total number of weights. #' #' @noRd #' @param r_eff A N-vector of relative MCMC effective sample sizes of `exp(log-lik matrix)`. #' @param S The (integer) size of posterior sample. #' @return An N-vector of tail lengths. #' n_pareto <- function(r_eff, S) { ceiling(pmin(0.2 * S, 3 * sqrt(S / r_eff))) } #' Check for enough tail samples to fit GPD #' #' @noRd #' @param tail_len Integer tail length. #' @param min_len The minimum allowed tail length. #' @return `TRUE` or `FALSE` #' enough_tail_samples <- function(tail_len, min_len = 5) { tail_len >= min_len } #' Throw warnings about pareto k estimates #' #' @noRd #' @param k A vector of pareto k estimates. #' @param high The value at which to warn about slighly high estimates. #' @param too_high The value at which to warn about very high estimates. #' @return Nothing, just possibly throws warnings. #' throw_pareto_warnings <- function(k, high = 0.5, too_high = 0.7) { if (isTRUE(any(k > too_high))) { .warn("Some Pareto k diagnostic values are too high. ", .k_help()) } else if (isTRUE(any(k > high))) { .warn("Some Pareto k diagnostic values are slightly high. ", .k_help()) } } #' Warn if not enough tail samples to fit GPD #' #' @noRd #' @param tail_lengths Vector of tail lengths. #' @return `tail_lengths`, invisibly. #' throw_tail_length_warnings <- function(tail_lengths) { tail_len_bad <- !sapply(tail_lengths, enough_tail_samples) if (any(tail_len_bad)) { if (length(tail_lengths) == 1) { warning( "Not enough tail samples to fit the generalized Pareto distribution.", call. = FALSE, immediate. = TRUE ) } else { bad <- which(tail_len_bad) Nbad <- length(bad) warning( "Not enough tail samples to fit the generalized Pareto distribution ", "in some or all columns of matrix of log importance ratios. ", "Skipping the following columns: ", paste(if (Nbad <= 10) bad else bad[1:10], collapse = ", "), if (Nbad > 10) paste0(", ... [", Nbad - 10, " more not printed].\n") else "\n", call. = FALSE, immediate. = TRUE ) } } invisible(tail_lengths) } #' Prepare `r_eff` to pass to `psis()` and throw warnings/errors if necessary #' #' @noRd #' @param r_eff User's `r_eff` argument. #' @param len The length `r_eff` should have if not `NULL` or `NA`. #' @return #' * If `r_eff` has length `len` then `r_eff` is returned. #' * If `r_eff` is `NULL` then a warning is thrown and `rep(1, len)` is returned. #' * If `r_eff` is `NA` then the warning is skipped and #' `rep(1, len)` is returned. #' * If `r_eff` has length `len` but has `NA`s then an error is thrown. #' prepare_psis_r_eff <- function(r_eff, len) { if (isTRUE(is.null(r_eff) || all(is.na(r_eff)))) { if (!called_from_loo() && is.null(r_eff)) { throw_psis_r_eff_warning() } r_eff <- rep(1, len) } else if (length(r_eff) != len) { stop("'r_eff' must have one value per observation.", call. = FALSE) } else if (anyNA(r_eff)) { stop("Can't mix NA and not NA values in 'r_eff'.", call. = FALSE) } r_eff } #' Check if `psis()` was called from one of the loo methods #' #' @noRd #' @return `TRUE` if the `loo()` array, matrix, or function method is found in #' the active call list, `FALSE` otherwise. #' called_from_loo <- function() { calls <- sys.calls() txt <- unlist(lapply(calls, deparse)) patts <- "loo.array\\(|loo.matrix\\(|loo.function\\(" check <- sapply(txt, function(x) grepl(patts, x)) isTRUE(any(check)) } #' Warning message about missing `r_eff` argument #' @noRd throw_psis_r_eff_warning <- function() { warning( "Relative effective sample sizes ('r_eff' argument) not specified. ", "PSIS n_eff will not be adjusted based on MCMC n_eff.", call. = FALSE ) } loo/R/extract_log_lik.R0000644000176200001440000000545313762013700014547 0ustar liggesusers#' Extract pointwise log-likelihood from a Stan model #' #' Convenience function for extracting the pointwise log-likelihood #' matrix or array from a `stanfit` object from the \pkg{rstan} package. #' Note: recent versions of \pkg{rstan} now include a `loo()` method for #' `stanfit` objects that handles this internally. #' #' @export #' @param stanfit A `stanfit` object (\pkg{rstan} package). #' @param parameter_name A character string naming the parameter (or generated #' quantity) in the Stan model corresponding to the log-likelihood. #' @param merge_chains If `TRUE` (the default), all Markov chains are #' merged together (i.e., stacked) and a matrix is returned. If `FALSE` #' they are kept separate and an array is returned. #' @return If `merge_chains=TRUE`, an \eqn{S} by \eqn{N} matrix of #' (post-warmup) extracted draws, where \eqn{S} is the size of the posterior #' sample and \eqn{N} is the number of data points. If #' `merge_chains=FALSE`, an \eqn{I} by \eqn{C} by \eqn{N} array, where #' \eqn{I \times C = S}{I * C = S}. #' #' #' @details Stan does not automatically compute and store the log-likelihood. It #' is up to the user to incorporate it into the Stan program if it is to be #' extracted after fitting the model. In a Stan model, the pointwise log #' likelihood can be coded as a vector in the transformed parameters block #' (and then summed up in the model block) or it can be coded entirely in the #' generated quantities block. We recommend using the generated quantities #' block so that the computations are carried out only once per iteration #' rather than once per HMC leapfrog step. #' #' For example, the following is the `generated quantities` block for #' computing and saving the log-likelihood for a linear regression model with #' `N` data points, outcome `y`, predictor matrix `X`, #' coefficients `beta`, and standard deviation `sigma`: #' #' `vector[N] log_lik;` #' #' `for (n in 1:N) log_lik[n] = normal_lpdf(y[n] | X[n, ] * beta, sigma);` #' #' @references #' Stan Development Team (2017). The Stan C++ Library, Version 2.16.0. #' #' #' Stan Development Team (2017). RStan: the R interface to Stan, Version 2.16.1. #' #' extract_log_lik <- function(stanfit, parameter_name = "log_lik", merge_chains = TRUE) { if (!inherits(stanfit, "stanfit")) stop("Not a stanfit object.", call. = FALSE) if (stanfit@mode != 0) stop("Stan model does not contain posterior draws.", call. = FALSE) if (!requireNamespace("rstan", quietly = TRUE)) stop("Please load the 'rstan' package.", call. = FALSE) if (merge_chains) { log_lik <- as.matrix(stanfit, pars = parameter_name) } else { log_lik <- as.array(stanfit, pars = parameter_name) } unname(log_lik) } loo/R/loo_approximate_posterior.R0000644000176200001440000001624313575772017016723 0ustar liggesusers#' Efficient approximate leave-one-out cross-validation (LOO) for posterior #' approximations #' #' @param x A log-likelihood array, matrix, or function. #' The **Methods (by class)** section, below, has detailed descriptions of how #' to specify the inputs for each method. #' @param save_psis Should the `"psis"` object created internally by #' `loo_approximate_posterior()` be saved in the returned object? See #' [loo()] for details. #' @template cores #' @inheritParams psis_approximate_posterior #' #' @details The `loo_approximate_posterior()` function is an S3 generic and #' methods are provided for 3-D pointwise log-likelihood arrays, pointwise #' log-likelihood matrices, and log-likelihood functions. The implementation #' works for posterior approximations where it is possible to compute the log #' density for the posterior approximation. #' #' @return The `loo_approximate_posterior()` methods return a named list with #' class `c("psis_loo_ap", "psis_loo", "loo")`. It has the same structure #' as the objects returned by [loo()] but with the additional slot: #' \describe{ #' \item{`posterior_approximation`}{ #' A list with two vectors, `log_p` and `log_g` of the same length #' containing the posterior density and the approximation density #' for the individual draws. #' } #' } #' #' @seealso [loo()], [psis()], [loo_compare()] #' @template loo-large-data-references #' #' @export loo_approximate_posterior #' @export loo_approximate_posterior.array loo_approximate_posterior.matrix loo_approximate_posterior.function #' loo_approximate_posterior <- function(x, log_p, log_g, ...) { UseMethod("loo_approximate_posterior") } #' @export #' @templateVar fn loo_approximate_posterior #' @template array loo_approximate_posterior.array <- function(x, log_p, log_g, ..., save_psis = FALSE, cores = getOption("mc.cores", 1)) { checkmate::assert_flag(save_psis) checkmate::assert_int(cores) checkmate::assert_matrix(log_p, mode = "numeric", nrows = dim(x)[1], ncols = dim(x)[2]) checkmate::assert_matrix(log_g, mode = "numeric", nrows = nrow(log_p), ncols = ncol(log_p)) ll <- llarray_to_matrix(x) log_p <- as.vector(log_p) log_g <- as.vector(log_g) loo_approximate_posterior.matrix( ll, log_p = log_p, log_g = log_g, ..., save_psis = save_psis, cores = cores ) } #' @export #' @templateVar fn loo_approximate_posterior #' @template matrix loo_approximate_posterior.matrix <- function(x, log_p, log_g, ..., save_psis = FALSE, cores = getOption("mc.cores", 1)) { checkmate::assert_flag(save_psis) checkmate::assert_int(cores) checkmate::assert_numeric(log_p, len = nrow(x)) checkmate::assert_null(dim(log_p)) checkmate::assert_numeric(log_g, len = length(log_p)) checkmate::assert_null(dim(log_g)) ap_psis <- psis_approximate_posterior( log_p = log_p, log_g = log_g, log_liks = x, ..., cores = cores, save_psis = save_psis ) ap_psis$approximate_posterior <- list(log_p = log_p, log_g = log_g) class(ap_psis) <- c("psis_loo_ap", class(ap_psis)) assert_psis_loo_ap(ap_psis) ap_psis } #' @export #' @templateVar fn loo_approximate_posterior #' @template function #' @param data,draws,... For the `loo_approximate_posterior.function()` method, #' these are the data, posterior draws, and other arguments to pass to the #' log-likelihood function. See the **Methods (by class)** section below for #' details on how to specify these arguments. #' loo_approximate_posterior.function <- function(x, ..., data = NULL, draws = NULL, log_p = NULL, log_g = NULL, save_psis = FALSE, cores = getOption("mc.cores", 1)) { checkmate::assert_numeric(log_p, len = length(log_g)) checkmate::assert_numeric(log_g, len = length(log_p)) cores <- loo_cores(cores) stopifnot(is.data.frame(data) || is.matrix(data), !is.null(draws)) .llfun <- validate_llfun(x) N <- dim(data)[1] psis_list <- parallel_psis_list(N = N, .loo_i = .loo_ap_i, .llfun = .llfun, data = data, draws = draws, r_eff = NULL, # r_eff is ignored save_psis = save_psis, log_p = log_p, log_g = log_g, cores = cores, ...) pointwise <- lapply(psis_list, "[[", "pointwise") if (save_psis) { psis_object_list <- lapply(psis_list, "[[", "psis_object") psis_out <- list2importance_sampling(psis_object_list) diagnostics <- psis_out$diagnostics } else { diagnostics_list <- lapply(psis_list, "[[", "diagnostics") diagnostics <- list( pareto_k = psis_apply(diagnostics_list, "pareto_k"), n_eff = psis_apply(diagnostics_list, "n_eff") ) } ap_psis <- importance_sampling_loo_object( pointwise = do.call(rbind, pointwise), diagnostics = diagnostics, dims = c(attr(psis_list[[1]], "S"), N), is_method = "psis", is_object = if (save_psis) psis_out else NULL ) ap_psis$approximate_posterior <- list(log_p = log_p, log_g = log_g) class(ap_psis) <- c("psis_loo_ap", class(ap_psis)) assert_psis_loo_ap(ap_psis) ap_psis } # Function that is passed to the FUN argument of lapply, mclapply, or parLapply # for the loo_approximate_posterior.function method. The arguments and return # value are the same as the ones documented for the user-facing loo_i function. .loo_ap_i <- function(i, llfun, ..., data, draws, log_p, log_g, r_eff = NULL, save_psis = FALSE, is_method) { if (!is.null(r_eff)) warning("r_eff not implemented for aploo.") if (is_method != "psis") stop(is_method, " not implemented for aploo.") d_i <- data[i, , drop = FALSE] ll_i <- llfun(data_i = d_i, draws = draws, ...) if (!is.matrix(ll_i)) { ll_i <- as.matrix(ll_i) } psis_out <- ap_psis(log_ratios = -ll_i, log_p = log_p, log_g = log_g, cores = 1) structure( list( pointwise = pointwise_loo_calcs(ll_i, psis_out), diagnostics = psis_out$diagnostics, psis_object = if (save_psis) psis_out else NULL ), S = dim(psis_out)[1], N = 1 ) } assert_psis_loo_ap <- function(x) { checkmate::assert_class(x, "psis_loo_ap") checkmate::assert_names(names(x), must.include = c("estimates", "pointwise", "diagnostics", "psis_object", "approximate_posterior")) checkmate::assert_names(names(x$approximate_posterior), must.include = c("log_p", "log_g")) checkmate::assert_numeric(x$approximate_posterior$log_p, len = length(x$approximate_posterior$log_g), any.missing = FALSE) checkmate::assert_numeric(x$approximate_posterior$log_g, len = length(x$approximate_posterior$log_p), any.missing = FALSE) } loo/R/diagnostics.R0000644000176200001440000003206714407123455013713 0ustar liggesusers#' Diagnostics for Pareto smoothed importance sampling (PSIS) #' #' Print a diagnostic table summarizing the estimated Pareto shape parameters #' and PSIS effective sample sizes, find the indexes of observations for which #' the estimated Pareto shape parameter \eqn{k} is larger than some #' `threshold` value, or plot observation indexes vs. diagnostic estimates. #' The **Details** section below provides a brief overview of the #' diagnostics, but we recommend consulting Vehtari, Gelman, and Gabry (2017) #' and Vehtari, Simpson, Gelman, Yao, and Gabry (2019) for full details. #' #' @name pareto-k-diagnostic #' @param x An object created by [loo()] or [psis()]. #' @param threshold For `pareto_k_ids()`, `threshold` is the minimum \eqn{k} #' value to flag (default is `0.5`). For `mcse_loo()`, if any \eqn{k} #' estimates are greater than `threshold` the MCSE estimate is returned as #' `NA` (default is `0.7`). See **Details** for the motivation behind these #' defaults. #' #' @details #' The reliability and approximate convergence rate of the PSIS-based estimates #' can be assessed using the estimates for the shape parameter \eqn{k} of the #' generalized Pareto distribution: #' * If \eqn{k < 0.5} then the distribution of raw importance ratios has #' finite variance and the central limit theorem holds. However, as \eqn{k} #' approaches \eqn{0.5} the RMSE of plain importance sampling (IS) increases #' significantly while PSIS has lower RMSE. #' #' * If \eqn{0.5 \leq k < 1}{0.5 <= k < 1} then the variance of the raw #' importance ratios is infinite, but the mean exists. TIS and PSIS estimates #' have finite variance by accepting some bias. The convergence of the #' estimate is slower with increasing \eqn{k}. #' If \eqn{k} is between 0.5 and approximately 0.7 then we observe practically #' useful convergence rates and Monte Carlo error estimates with PSIS (the #' bias of TIS increases faster than the bias of PSIS). If \eqn{k > 0.7} we #' observe impractical convergence rates and unreliable Monte Carlo error #' estimates. #' #' * If \eqn{k \geq 1}{k >= 1} then neither the variance nor the mean of #' the raw importance ratios exists. The convergence rate is close to #' zero and bias can be large with practical sample sizes. #' #' \subsection{What if the estimated tail shape parameter \eqn{k} exceeds #' \eqn{0.5}}{ Importance sampling is likely to work less well if the #' marginal posterior \eqn{p(\theta^s | y)} and LOO posterior #' \eqn{p(\theta^s | y_{-i})} are very different, which is more likely to #' happen with a non-robust model and highly influential observations. #' If the estimated tail shape parameter \eqn{k} exceeds \eqn{0.5}, the user #' should be warned. (Note: If \eqn{k} is greater than \eqn{0.5} #' then WAIC is also likely to fail, but WAIC lacks its own diagnostic.) #' In practice, we have observed good performance for values of \eqn{k} up to 0.7. #' When using PSIS in the context of approximate LOO-CV, we recommend one of #' the following actions when \eqn{k > 0.7}: #' #' * With some additional computations, it is possible to transform the MCMC #' draws from the posterior distribution to obtain more reliable importance #' sampling estimates. This results in a smaller shape parameter \eqn{k}. #' See [loo_moment_match()] for an example of this. #' #' * Sampling directly from \eqn{p(\theta^s | y_{-i})} for the problematic #' observations \eqn{i}, or using \eqn{k}-fold cross-validation will generally #' be more stable. #' #' * Using a model that is more robust to anomalous observations will #' generally make approximate LOO-CV more stable. #' #' } #' #' \subsection{Observation influence statistics}{ The estimated shape parameter #' \eqn{k} for each observation can be used as a measure of the observation's #' influence on posterior distribution of the model. These can be obtained with #' `pareto_k_influence_values()`. #' } #' #' \subsection{Effective sample size and error estimates}{ In the case that we #' obtain the samples from the proposal distribution via MCMC the **loo** #' package also computes estimates for the Monte Carlo error and the effective #' sample size for importance sampling, which are more accurate for PSIS than #' for IS and TIS (see Vehtari et al (2019) for details). However, the PSIS #' effective sample size estimate will be #' **over-optimistic when the estimate of \eqn{k} is greater than 0.7**. #' } #' #' @seealso #' * [psis()] for the implementation of the PSIS algorithm. #' * The [FAQ page](https://mc-stan.org/loo/articles/online-only/faq.html) on #' the __loo__ website for answers to frequently asked questions. #' #' @template loo-and-psis-references #' NULL #' @rdname pareto-k-diagnostic #' @export #' @return `pareto_k_table()` returns an object of class #' `"pareto_k_table"`, which is a matrix with columns `"Count"`, #' `"Proportion"`, and `"Min. n_eff"`, and has its own print method. #' pareto_k_table <- function(x) { k <- pareto_k_values(x) n_eff <- try(psis_n_eff_values(x), silent = TRUE) if (inherits(n_eff, "try-error")) { n_eff <- rep(NA, length(k)) } kcut <- k_cut(k) min_n_eff <- min_n_eff_by_k(n_eff, kcut) count <- table(kcut) out <- cbind( Count = count, Proportion = prop.table(count), "Min. n_eff" = min_n_eff ) structure(out, class = c("pareto_k_table", class(out))) } #' @export print.pareto_k_table <- function(x, digits = 1, ...) { count <- x[, "Count"] if (sum(count[2:4]) == 0) { cat("\nAll Pareto k estimates are good (k < 0.5).\n") } else { tab <- cbind( " " = rep("", 4), " " = c("(good)", "(ok)", "(bad)", "(very bad)"), "Count" = .fr(count, 0), "Pct. " = paste0(.fr(100 * x[, "Proportion"], digits), "%"), "Min. n_eff" = round(x[, "Min. n_eff"]) ) tab2 <- rbind(tab) cat("Pareto k diagnostic values:\n") rownames(tab2) <- format(rownames(tab2), justify = "right") print(tab2, quote = FALSE) if (sum(count[3:4]) == 0) cat("\nAll Pareto k estimates are ok (k < 0.7).\n") invisible(x) } } #' @rdname pareto-k-diagnostic #' @export #' @return `pareto_k_ids()` returns an integer vector indicating which #' observations have Pareto \eqn{k} estimates above `threshold`. #' pareto_k_ids <- function(x, threshold = 0.5) { k <- pareto_k_values(x) which(k > threshold) } #' @rdname pareto-k-diagnostic #' @export #' @return `pareto_k_values()` returns a vector of the estimated Pareto #' \eqn{k} parameters. These represent the reliability of sampling. pareto_k_values <- function(x) { k <- x$diagnostics[["pareto_k"]] if (is.null(k)) { # for compatibility with objects from loo < 2.0.0 k <- x[["pareto_k"]] } if (is.null(k)) { stop("No Pareto k estimates found.", call. = FALSE) } return(k) } #' @rdname pareto-k-diagnostic #' @export #' @return `pareto_k_influence_values()` returns a vector of the estimated Pareto #' \eqn{k} parameters. These represent influence of the observations on the #' model posterior distribution. pareto_k_influence_values <- function(x) { if ("influence_pareto_k" %in% colnames(x$pointwise)) { k <- x$pointwise[,"influence_pareto_k"] } else { stop("No Pareto k influence estimates found.", call. = FALSE) } return(k) } #' @rdname pareto-k-diagnostic #' @export #' @return `psis_n_eff_values()` returns a vector of the estimated PSIS #' effective sample sizes. psis_n_eff_values <- function(x) { n_eff <- x$diagnostics[["n_eff"]] if (is.null(n_eff)) { stop("No PSIS n_eff estimates found.", call. = FALSE) } return(n_eff) } #' @rdname pareto-k-diagnostic #' @export #' @return `mcse_loo()` returns the Monte Carlo standard error (MCSE) #' estimate for PSIS-LOO. MCSE will be NA if any Pareto \eqn{k} values are #' above `threshold`. #' mcse_loo <- function(x, threshold = 0.7) { stopifnot(is.psis_loo(x)) if (any(pareto_k_values(x) > 0.7, na.rm = TRUE)) { return(NA) } mc_var <- x$pointwise[, "mcse_elpd_loo"]^2 sqrt(sum(mc_var)) } #' @rdname pareto-k-diagnostic #' @aliases plot.loo #' @export #' @param label_points,... For the `plot()` method, if `label_points` is #' `TRUE` the observation numbers corresponding to any values of \eqn{k} #' greater than 0.5 will be displayed in the plot. Any arguments specified in #' `...` will be passed to [graphics::text()] and can be used #' to control the appearance of the labels. #' @param diagnostic For the `plot` method, which diagnostic should be #' plotted? The options are `"k"` for Pareto \eqn{k} estimates (the #' default) or `"n_eff"` for PSIS effective sample size estimates. #' @param main For the `plot()` method, a title for the plot. #' #' @return The `plot()` method is called for its side effect and does not #' return anything. If `x` is the result of a call to [loo()] #' or [psis()] then `plot(x, diagnostic)` produces a plot of #' the estimates of the Pareto shape parameters (`diagnostic = "k"`) or #' estimates of the PSIS effective sample sizes (`diagnostic = "n_eff"`). #' plot.psis_loo <- function(x, diagnostic = c("k", "n_eff"), ..., label_points = FALSE, main = "PSIS diagnostic plot") { diagnostic <- match.arg(diagnostic) k <- pareto_k_values(x) k[is.na(k)] <- 0 # FIXME when reloo is changed to make NA k values -Inf k_inf <- !is.finite(k) if (any(k_inf)) { warning(signif(100 * mean(k_inf), 2), "% of Pareto k estimates are Inf/NA/NaN and not plotted.") } if (diagnostic == "n_eff") { n_eff <- psis_n_eff_values(x) } else { n_eff <- NULL } plot_diagnostic( k = k, n_eff = n_eff, ..., label_points = label_points, main = main ) } #' @export #' @noRd #' @rdname pareto-k-diagnostic plot.loo <- plot.psis_loo #' @export #' @rdname pareto-k-diagnostic plot.psis <- function(x, diagnostic = c("k", "n_eff"), ..., label_points = FALSE, main = "PSIS diagnostic plot") { plot.psis_loo(x, diagnostic = diagnostic, ..., label_points = label_points, main = main) } # internal ---------------------------------------------------------------- plot_diagnostic <- function(k, n_eff = NULL, ..., label_points = FALSE, main = "PSIS diagnostic plot") { use_n_eff <- !is.null(n_eff) graphics::plot( x = if (use_n_eff) n_eff else k, xlab = "Data point", ylab = if (use_n_eff) "PSIS n_eff" else "Pareto shape k", type = "n", bty = "l", yaxt = "n", main = main ) graphics::axis(side = 2, las = 1) in_range <- function(x, lb_ub) { x >= lb_ub[1L] & x <= lb_ub[2L] } if (!use_n_eff) { krange <- range(k, na.rm = TRUE) breaks <- c(0, 0.5, 0.7, 1) hex_clrs <- c("#C79999", "#A25050", "#7C0000") ltys <- c(3, 4, 2, 1) for (j in seq_along(breaks)) { val <- breaks[j] if (in_range(val, krange)) graphics::abline( h = val, col = ifelse(val == 0, "darkgray", hex_clrs[j - 1]), lty = ltys[j], lwd = 1 ) } } breaks <- c(-Inf, 0.5, 1) hex_clrs <- c("#6497b1", "#005b96", "#03396c") clrs <- ifelse( in_range(k, breaks[1:2]), hex_clrs[1], ifelse(in_range(k, breaks[2:3]), hex_clrs[2], hex_clrs[3]) ) if (all(k < 0.5) || !label_points) { graphics::points(x = if (use_n_eff) n_eff else k, col = clrs, pch = 3, cex = .6) return(invisible()) } else { graphics::points(x = if (use_n_eff) n_eff[k < 0.5] else k[k < 0.5], col = clrs[k < 0.5], pch = 3, cex = .6) sel <- !in_range(k, breaks[1:2]) dots <- list(...) txt_args <- c( list( x = seq_along(k)[sel], y = if (use_n_eff) n_eff[sel] else k[sel], labels = seq_along(k)[sel] ), if (length(dots)) dots ) if (!("adj" %in% names(txt_args))) txt_args$adj <- 2 / 3 if (!("cex" %in% names(txt_args))) txt_args$cex <- 0.75 if (!("col" %in% names(txt_args))) txt_args$col <- clrs[sel] do.call(graphics::text, txt_args) } } #' Convert numeric Pareto k values to a factor variable. #' #' @noRd #' @param k Vector of Pareto k estimates. #' @return A factor variable (the same length as k) with 4 levels. #' k_cut <- function(k) { cut( k, breaks = c(-Inf, 0.5, 0.7, 1, Inf), labels = c("(-Inf, 0.5]", "(0.5, 0.7]", "(0.7, 1]", "(1, Inf)") ) } #' Calculate the minimum PSIS n_eff within groups defined by Pareto k values #' #' @noRd #' @param n_eff Vector of PSIS n_eff estimates. #' @param kcut Factor returned by the k_cut() function. #' @return Vector of length `nlevels(kcut)` containing the minimum n_eff within #' each k group. If there are no k values in a group the corresponding element #' of the returned vector is NA. min_n_eff_by_k <- function(n_eff, kcut) { n_eff_split <- split(n_eff, f = kcut) n_eff_split <- sapply(n_eff_split, function(x) { # some k groups might be empty. # split gives numeric(0) but replace with NA if (!length(x)) NA else x }) sapply(n_eff_split, min) } loo/R/kfold-helpers.R0000644000176200001440000000700113575772017014142 0ustar liggesusers#' Helper functions for K-fold cross-validation #' #' @description These functions can be used to generate indexes for use with #' K-fold cross-validation. See the **Details** section for explanations. #' #' @name kfold-helpers #' @param K The number of folds to use. #' @param N The number of observations in the data. #' @param x A discrete variable of length `N` with at least `K` levels (unique #' values). Will be coerced to a [factor][factor()]. #' #' @return An integer vector of length `N` where each element is an index in `1:K`. #' #' @details #' `kfold_split_random()` splits the data into `K` groups #' of equal size (or roughly equal size). #' #' For a categorical variable `x` `kfold_split_stratified()` #' splits the observations into `K` groups ensuring that relative #' category frequencies are approximately preserved. #' #' For a grouping variable `x`, `kfold_split_grouped()` places #' all observations in `x` from the same group/level together in #' the same fold. The selection of which groups/levels go into which #' fold (relevant when when there are more groups than folds) is #' randomized. #' #' @examples #' ids <- kfold_split_random(K = 5, N = 20) #' print(ids) #' table(ids) #' #' #' x <- sample(c(0, 1), size = 200, replace = TRUE, prob = c(0.05, 0.95)) #' table(x) #' ids <- kfold_split_stratified(K = 5, x = x) #' print(ids) #' table(ids, x) #' #' grp <- gl(n = 50, k = 15, labels = state.name) #' length(grp) #' head(table(grp)) #' #' ids_10 <- kfold_split_grouped(K = 10, x = grp) #' (tab_10 <- table(grp, ids_10)) #' colSums(tab_10) #' #' ids_9 <- kfold_split_grouped(K = 9, x = grp) #' (tab_9 <- table(grp, ids_9)) #' colSums(tab_9) #' NULL #' @rdname kfold-helpers #' @export kfold_split_random <- function(K = 10, N = NULL) { stopifnot( !is.null(N), K == as.integer(K), N == as.integer(N), length(K) == 1, length(N) == 1, K > 1, K <= N ) perm <- sample.int(N) idx <- ceiling(seq(from = 1, to = N, length.out = K + 1)) bins <- .bincode(perm, breaks = idx, right = FALSE, include.lowest = TRUE) return(bins) } #' @rdname kfold-helpers #' @export kfold_split_stratified <- function(K = 10, x = NULL) { stopifnot( !is.null(x), K == as.integer(K), length(K) == 1, K > 1, K <= length(x) ) x <- as.integer(as.factor(x)) Nlev <- length(unique(x)) N <- length(x) xids <- numeric() for (l in 1:Nlev) { xids <- c(xids, sample(which(x==l))) } bins <- rep(NA, N) bins[xids] <- rep(1:K, ceiling(N/K))[1:N] return(bins) } #' @rdname kfold-helpers #' @export kfold_split_grouped <- function(K = 10, x = NULL) { stopifnot( !is.null(x), K == as.integer(K), length(K) == 1, K > 1, K <= length(x) ) Nlev <- length(unique(x)) if (Nlev < K) { stop("'K' must not be bigger than the number of levels/groups in 'x'.") } x <- as.integer(as.factor(x)) if (Nlev == K) { return(x) } # Otherwise we have Nlev > K S1 <- ceiling(Nlev / K) # number of levels in largest groups of levels N_S2 <- S1 * K - Nlev # number of groups of levels of size S1 - 1 N_S1 <- K - N_S2 # number of groups of levels of size S1 perm <- sample.int(Nlev) # permute group levels brks <- seq(from = S1 + 0.5, by = S1, length.out = N_S1) if (N_S2 > 0) { brks2 <- seq(from = brks[N_S1] + S1 - 1, by = S1 - 1, length.out = N_S2 - 1) brks <- c(brks, brks2) } grps <- findInterval(perm, vec = brks) + 1 # +1 so min is 1 not 0 bins <- rep(NA, length(x)) for (j in perm) { bins[x == j] <- grps[j] } return(bins) } loo/R/split_moment_matching.R0000644000176200001440000001350413753273364015773 0ustar liggesusers#' Split moment matching for efficient approximate leave-one-out cross-validation (LOO) #' #' A function that computes the split moment matching importance sampling loo. #' Takes in the moment matching total transformation, transforms only half #' of the draws, and computes a single elpd using multiple importance sampling. #' #' @param x A fitted model object. #' @param upars A matrix containing the model parameters in unconstrained space #' where they can have any real value. #' @param cov Logical; Indicate whether to match the covariance matrix of the #' samples or not. If `FALSE`, only the mean and marginal variances are #' matched. #' @param total_shift A vector representing the total shift made by the moment #' matching algorithm. #' @param total_scaling A vector representing the total scaling of marginal #' variance made by the moment matching algorithm. #' @param total_mapping A vector representing the total covariance #' transformation made by the moment matching algorithm. #' @param i Observation index. #' @param log_prob_upars A function that takes arguments `x` and `upars` and #' returns a matrix of log-posterior density values of the unconstrained #' posterior draws passed via `upars`. #' @param log_lik_i_upars A function that takes arguments `x`, `upars`, and `i` #' and returns a vector of log-likeliood draws of the `i`th observation based #' on the unconstrained posterior draws passed via `upars`. #' @param r_eff_i MCMC relative effective sample size of the `i`'th log #' likelihood draws. #' @template cores #' @template is_method #' @param ... Further arguments passed to the custom functions documented above. #' #' @return A list containing the updated log-importance weights and #' log-likelihood values. Also returns the updated MCMC effective sample size #' and the integrand-specific log-importance weights. #' #' #' @seealso [loo()], [loo_moment_match()] #' @template moment-matching-references #' #' loo_moment_match_split <- function(x, upars, cov, total_shift, total_scaling, total_mapping, i, log_prob_upars, log_lik_i_upars, r_eff_i, cores, is_method, ...) { S <- dim(upars)[1] S_half <- as.integer(0.5 * S) mean_original <- colMeans(upars) # accumulated affine transformation upars_trans <- sweep(upars, 2, mean_original, "-") upars_trans <- sweep(upars_trans, 2, total_scaling, "*") if (cov) { upars_trans <- tcrossprod(upars_trans, total_mapping) } upars_trans <- sweep(upars_trans, 2, total_shift + mean_original, "+") attributes(upars_trans) <- attributes(upars) # inverse accumulated affine transformation upars_trans_inv <- sweep(upars, 2, mean_original, "-") if (cov) { upars_trans_inv <- tcrossprod(upars_trans_inv, solve(total_mapping)) } upars_trans_inv <- sweep(upars_trans_inv, 2, total_scaling, "/") upars_trans_inv <- sweep(upars_trans_inv, 2, mean_original - total_shift, "+") attributes(upars_trans_inv) <- attributes(upars) # first half of upars_trans_half are T(theta) # second half are theta upars_trans_half <- upars take <- seq_len(S_half) upars_trans_half[take, ] <- upars_trans[take, , drop = FALSE] # first half of upars_half_inv are theta # second half are T^-1 (theta) upars_trans_half_inv <- upars take <- seq_len(S)[-seq_len(S_half)] upars_trans_half_inv[take, ] <- upars_trans_inv[take, , drop = FALSE] # compute log likelihoods and log probabilities log_prob_half_trans <- log_prob_upars(x, upars = upars_trans_half, ...) log_prob_half_trans_inv <- log_prob_upars(x, upars = upars_trans_half_inv, ...) log_liki_half <- log_lik_i_upars(x, upars = upars_trans_half, i = i, ...) # compute weights log_prob_half_trans_inv <- (log_prob_half_trans_inv - log(prod(total_scaling)) - log(det(total_mapping))) stable_S <- log_prob_half_trans > log_prob_half_trans_inv lwi_half <- -log_liki_half + log_prob_half_trans lwi_half[stable_S] <- lwi_half[stable_S] - (log_prob_half_trans[stable_S] + log1p(exp(log_prob_half_trans_inv[stable_S] - log_prob_half_trans[stable_S]))) lwi_half[!stable_S] <- lwi_half[!stable_S] - (log_prob_half_trans_inv[!stable_S] + log1p(exp(log_prob_half_trans[!stable_S] - log_prob_half_trans_inv[!stable_S]))) is_obj_half <- suppressWarnings(importance_sampling.default(lwi_half, method = is_method, r_eff = r_eff_i, cores = cores)) lwi_half <- as.vector(weights(is_obj_half)) is_obj_f_half <- suppressWarnings(importance_sampling.default(lwi_half + log_liki_half, method = is_method, r_eff = r_eff_i, cores = cores)) lwfi_half <- as.vector(weights(is_obj_f_half)) # relative_eff recomputation # currently ignores chain information # since we have two proposal distributions # compute S_eff separately from both and take the smaller take <- seq_len(S)[-seq_len(S_half)] log_liki_half_1 <- log_liki_half[take, drop = FALSE] dim(log_liki_half_1) <- c(length(take), 1, 1) take <- seq_len(S)[-seq_len(S_half)] log_liki_half_2 <- log_liki_half[take, drop = FALSE] dim(log_liki_half_2) <- c(length(take), 1, 1) r_eff_i1 <- loo::relative_eff(exp(log_liki_half_1), cores = cores) r_eff_i2 <- loo::relative_eff(exp(log_liki_half_2), cores = cores) r_eff_i <- min(r_eff_i1,r_eff_i2) list( lwi = lwi_half, lwfi = lwfi_half, log_liki = log_liki_half, r_eff_i = r_eff_i ) } loo/R/crps.R0000644000176200001440000001543414411130104012332 0ustar liggesusers#' Continuously ranked probability score #' #' The `crps()` and `scrps()` functions and their `loo_*()` counterparts can be #' used to compute the continuously ranked probability score (CRPS) and scaled #' CRPS (SCRPS) (see Bolin and Wallin, 2022). CRPS is a proper scoring rule, and #' strictly proper when the first moment of the predictive distribution is #' finite. Both can be expressed in terms of samples form the predictive #' distribution. See e.g. Gneiting and Raftery (2007) for a comprehensive #' discussion on CRPS. #' #' To compute (S)CRPS, the user needs to provide two sets of draws, `x` and #' `x2`, from the predictive distribution. This is due to the fact that formulas #' used to compute CRPS involve an expectation of the absolute difference of `x` #' and `x2`, both having the same distribution. See the `permutations` argument, #' as well as Gneiting and Raftery (2007) for details. #' #' @export #' @param x A `S` by `N` matrix (draws by observations), or a vector of length #' `S` when only single observation is provided in `y`. #' @param x2 Independent draws from the same distribution as draws in `x`. #' Should be of the identical dimension. #' @param y A vector of observations or a single value. #' @param permutations An integer, with default value of 1, specifying how many #' times the expected value of |X - X'| (`|x - x2|`) is computed. The row #' order of `x2` is shuffled as elements `x` and `x2` are typically drawn #' given the same values of parameters. This happens, e.g., when one calls #' `posterior_predict()` twice for a fitted \pkg{rstanarm} or \pkg{brms} #' model. Generating more permutations is expected to decrease the variance of #' the computed expected value. #' @param ... Passed on to [E_loo()] in the `loo_*()` version of these #' functions. #' #' @return A list containing two elements: `estimates` and `pointwise`. #' The former reports estimator and standard error and latter the pointwise #' values. #' #' @examples #' \dontrun{ #' # An example using rstanarm #' library(rstanarm) #' data("kidiq") #' fit <- stan_glm(kid_score ~ mom_hs + mom_iq, data = kidiq) #' ypred1 <- posterior_predict(fit) #' ypred2 <- posterior_predict(fit) #' crps(ypred1, ypred2, y = fit$y) #' loo_crps(ypred1, ypred2, y = fit$y, log_lik = log_lik(fit)) #' } #' #' @references #' Bolin, D., & Wallin, J. (2022). Local scale invariance and robustness of #' proper scoring rules. arXiv. \doi{10.48550/arXiv.1912.05642} #' #' Gneiting, T., & Raftery, A. E. (2007). Strictly Proper Scoring Rules, #' Prediction, and Estimation. Journal of the American Statistical Association, #' 102(477), 359–378. crps <- function(x, ...) { UseMethod("crps") } #' @rdname crps #' @export scrps <- function(x, ...) { UseMethod("scrps") } #' @rdname crps #' @export loo_crps <- function(x, ...) { UseMethod("loo_crps") } #' @rdname crps #' @export loo_scrps <- function(x, ...) { UseMethod("loo_scrps") } #' @rdname crps #' @export crps.matrix <- function(x, x2, y, ..., permutations = 1) { validate_crps_input(x, x2, y) repeats <- replicate(permutations, EXX_compute(x, x2), simplify = F) EXX <- Reduce(`+`, repeats) / permutations EXy <- colMeans(abs(sweep(x, 2, y))) crps_output(.crps_fun(EXX, EXy)) } #' Method for a single data point #' @rdname crps #' @export crps.numeric <- function(x, x2, y, ..., permutations = 1) { stopifnot(length(x) == length(x2), length(y) == 1) crps.matrix(as.matrix(x), as.matrix(x2), y, permutations) } #' @rdname crps #' @export #' @param log_lik A log-likelihood matrix the same size as `x`. #' @param r_eff An optional vector of relative effective sample size estimates #' containing one element per observation. See [psis()] for details. #' @param cores The number of cores to use for parallelization of `[psis()]`. #' See [psis()] for details. loo_crps.matrix <- function(x, x2, y, log_lik, ..., permutations = 1, r_eff = NULL, cores = getOption("mc.cores", 1)) { validate_crps_input(x, x2, y, log_lik) repeats <- replicate(permutations, EXX_loo_compute(x, x2, log_lik, r_eff = r_eff, ...), simplify = F) EXX <- Reduce(`+`, repeats) / permutations psis_obj <- psis(-log_lik, r_eff = r_eff, cores = cores) EXy <- E_loo(abs(sweep(x, 2, y)), psis_obj, log_ratios = -log_lik, ...)$value crps_output(.crps_fun(EXX, EXy)) } #' @rdname crps #' @export scrps.matrix <- function(x, x2, y, ..., permutations = 1) { validate_crps_input(x, x2, y) repeats <- replicate(permutations, EXX_compute(x, x2), simplify = F) EXX <- Reduce(`+`, repeats) / permutations EXy <- colMeans(abs(sweep(x, 2, y))) crps_output(.crps_fun(EXX, EXy, scale = TRUE)) } #' @rdname crps #' @export scrps.numeric <- function(x, x2, y, ..., permutations = 1) { stopifnot(length(x) == length(x2), length(y) == 1) scrps.matrix(as.matrix(x), as.matrix(x2), y, permutations) } #' @rdname crps #' @export loo_scrps.matrix <- function( x, x2, y, log_lik, ..., permutations = 1, r_eff = NULL, cores = getOption("mc.cores", 1)) { validate_crps_input(x, x2, y, log_lik) repeats <- replicate(permutations, EXX_loo_compute(x, x2, log_lik, r_eff = r_eff, ...), simplify = F) EXX <- Reduce(`+`, repeats) / permutations psis_obj <- psis(-log_lik, r_eff = r_eff, cores = cores) EXy <- E_loo(abs(sweep(x, 2, y)), psis_obj, log_ratios = -log_lik, ...)$value crps_output(.crps_fun(EXX, EXy, scale = TRUE)) } # ------------ Internals ---------------- EXX_compute <- function(x, x2) { S <- nrow(x) colMeans(abs(x - x2[sample(1:S),])) } EXX_loo_compute <- function(x, x2, log_lik, r_eff = NULL, ...) { S <- nrow(x) shuffle <- sample (1:S) x2 <- x2[shuffle,] log_lik2 <- log_lik[shuffle,] psis_obj_joint <- psis(-log_lik - log_lik2 , r_eff = r_eff) E_loo(abs(x - x2), psis_obj_joint, log_ratios = -log_lik - log_lik2, ...)$value } #' Function to compute crps and scrps #' @noRd .crps_fun <- function(EXX, EXy, scale = FALSE) { if (scale) return(-EXy/EXX - 0.5 * log(EXX)) 0.5 * EXX - EXy } #' Compute output data for crps functions #' @noRd crps_output <- function(crps_pw) { n <- length(crps_pw) out <- list() out$estimates <- c(mean(crps_pw), sd(crps_pw) / sqrt(n)) names(out$estimates) <- c('Estimate', 'SE') out$pointwise <- crps_pw out } #' Validate input of CRPS functions #' #' Check that predictive draws and observed data are of compatible shape #' @noRd validate_crps_input <- function(x, x2, y, log_lik = NULL) { stopifnot(is.numeric(x), is.numeric(x2), is.numeric(y), identical(dim(x), dim(x2)), ncol(x) == length(y), ifelse(is.null(log_lik), TRUE, identical(dim(log_lik), dim(x))) ) } loo/R/loo_predictive_metric.R0000644000176200001440000001464214411130104015735 0ustar liggesusers#' Estimate leave-one-out predictive performance.. #' #' The `loo_predictive_metric()` function computes estimates of leave-one-out #' predictive metrics given a set of predictions and observations. Currently #' supported metrics are mean absolute error, mean squared error and root mean #' squared error for continuous predictions and accuracy and balanced accuracy #' for binary classification. Predictions are passed on to the [E_loo()] #' function, so this function assumes that the PSIS approximation is working #' well. #' #' @param x A numeric matrix of predictions. #' @param y A numeric vector of observations. Length should be equal to the #' number of rows in `x`. #' @param log_lik A matrix of pointwise log-likelihoods. Should be of same #' dimension as `x`. #' @param metric The type of predictive metric to be used. Currently #' supported options are `"mae"`, `"rmse"` and `"mse"` for regression and #' for binary classification `"acc"` and `"balanced_acc"`. #' \describe{ #' \item{`"mae"`}{ #' Mean absolute error. #' } #' \item{`"mse"`}{ #' Mean squared error. #' } #' \item{`"rmse"`}{ #' Root mean squared error, given by as the square root of `MSE`. #' } #' \item{`"acc"`}{ #' The proportion of predictions indicating the correct outcome. #' } #' \item{`"balanced_acc"`}{ #' Balanced accuracy is given by the average of true positive and true #' negative rates. #' } #' } #' @param r_eff A Vector of relative effective sample size estimates containing #' one element per observation. See [psis()] for more details. #' @param cores The number of cores to use for parallelization of `[psis()]`. #' See [psis()] for details. #' @param ... Additional arguments passed on to [E_loo()] #' #' @return A list with the following components: #' \describe{ #' \item{`estimate`}{ #' Estimate of the given metric. #' } #' \item{`se`}{ #' Standard error of the estimate. #' } #' } #' @export #' #' @examples #' \donttest{ #' if (requireNamespace("rstanarm", quietly = TRUE)) { #' # Use rstanarm package to quickly fit a model and get both a log-likelihood #' # matrix and draws from the posterior predictive distribution #' library("rstanarm") #' #' # data from help("lm") #' ctl <- c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14) #' trt <- c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69) #' d <- data.frame( #' weight = c(ctl, trt), #' group = gl(2, 10, 20, labels = c("Ctl","Trt")) #' ) #' fit <- stan_glm(weight ~ group, data = d, refresh = 0) #' ll <- log_lik(fit) #' r_eff <- relative_eff(exp(-ll), chain_id = rep(1:4, each = 1000)) #' #' mu_pred <- posterior_epred(fit) #' # Leave-one-out mean absolute error of predictions #' mae <- loo_predictive_metric(x = mu_pred, y = d$weight, log_lik = ll, #' pred_error = 'mae', r_eff = r_eff) #' # Leave-one-out 90%-quantile of mean absolute error #' mae_90q <- loo_predictive_metric(x = mu_pred, y = d$weight, log_lik = ll, #' pred_error = 'mae', r_eff = r_eff, #' type = 'quantile', probs = 0.9) #' } #' } loo_predictive_metric <- function(x, ...) { UseMethod("loo_predictive_metric") } #' @rdname loo_predictive_metric #' @export loo_predictive_metric.matrix <- function(x, y, log_lik, ..., metric = c("mae", "rmse", "mse", "acc", "balanced_acc"), r_eff = NULL, cores = getOption("mc.cores", 1)) { stopifnot( is.numeric(x), is.numeric(y), identical(ncol(x), length(y)), identical(dim(x), dim(log_lik)) ) metric <- match.arg(metric) psis_object <- psis(-log_lik, r_eff = r_eff, cores = cores) pred_loo <- E_loo(x, psis_object = psis_object, log_ratios = -log_lik, ...)$value predictive_metric_fun <- .loo_predictive_metric_fun(metric) predictive_metric_fun(y, pred_loo) } # ----------------------------- Internals ----------------------------- #' Select predictive metric function based on user's `metric` argument #' #' @noRd #' @param metric The metric used. #' @return The function used to compute predictive error or accuracy specified #' by the argument `metric`. .loo_predictive_metric_fun <- function(metric) { switch( metric, 'mae' = .mae, 'rmse' = .rmse, 'mse' = .mse, 'acc' = .accuracy, 'balanced_acc' = .balanced_accuracy ) } #' Mean absolute error #' #' @noRd #' @param y A vector of observed values #' @param yhat A vector of predictions .mae <-function(y, yhat) { stopifnot(length(y) == length(yhat)) n <- length(y) e <- abs(y - yhat) list(estimate = mean(e), se = sd(e) / sqrt(n)) } #' Mean squared error #' #' @noRd #' @param y A vector of observed values #' @param yhat A vector of predictions .mse <-function(y, yhat) { stopifnot(length(y) == length(yhat)) n <- length(y) e <- (y - yhat)^2 list(estimate = mean(e), se = sd(e) / sqrt(n)) } #' Root mean squared error #' #' @noRd #' @param y A vector of observed values #' @param yhat A vector of predictions .rmse <-function(y, yhat) { est <- .mse(y, yhat) mean_mse <- est$estimate var_mse <- est$se^2 var_rmse <- var_mse / mean_mse / 4 # Comes from the first order Taylor approx. return(list(estimate = sqrt(mean_mse), se = sqrt(var_rmse))) } #' Classification accuracy #' #' @noRd #' @param y A vector of observed values #' @param yhat A vector of predictions .accuracy <- function(y, yhat) { stopifnot(length(y) == length(yhat), all(y <= 1 & y >= 0), all(yhat <= 1 & yhat >= 0)) n <- length(y) yhat <- as.integer(yhat > 0.5) acc <- as.integer(yhat == y) est <- mean(acc) list(estimate = est, se = sqrt(est * (1-est) / n) ) } #' Balanced classification accuracy #' #' @noRd #' @param y A vector of observed values #' @param yhat A vector of predictions .balanced_accuracy <- function(y, yhat) { stopifnot(length(y) == length(yhat), all(y <= 1 & y >= 0), all(yhat <= 1 & yhat >= 0)) n <- length(y) yhat <- as.integer(yhat > 0.5) mask <- y == 0 tn <- mean(yhat[mask] == y[mask]) # True negatives tp <- mean(yhat[!mask] == y[!mask]) # True positives bls_acc <- (tp + tn) / 2 # This approximation has quite large bias for small samples bls_acc_var <- (tp * (1 - tp) + tn * (1 - tn)) / 4 list(estimate = bls_acc, se = sqrt(bls_acc_var / n)) } loo/R/loo_subsample.R0000644000176200001440000014172514407123455014252 0ustar liggesusers#' Efficient approximate leave-one-out cross-validation (LOO) using subsampling #' #' @param x A function. The **Methods (by class)** section, below, has detailed #' descriptions of how to specify the inputs. #' #' @inheritParams loo #' @param save_psis Should the `"psis"` object created internally by #' `loo_subsample()` be saved in the returned object? See [loo()] for details. #' @template cores #' #' @details The `loo_subsample()` function is an S3 generic and a methods is #' currently provided for log-likelihood functions. The implementation works #' for both MCMC and for posterior approximations where it is possible to #' compute the log density for the approximation. #' #' @return `loo_subsample()` returns a named list with class `c("psis_loo_ss", #' "psis_loo", "loo")`. This has the same structure as objects returned by #' [loo()] but with the additional slot: #' * `loo_subsampling`: A list with two vectors, `log_p` and `log_g`, of the #' same length containing the posterior density and the approximation density #' for the individual draws. #' #' @seealso [loo()], [psis()], [loo_compare()] #' @template loo-large-data-references #' #' @export loo_subsample loo_subsample.function #' loo_subsample <- function(x, ...) { UseMethod("loo_subsample") } #' @export #' @templateVar fn loo_subsample #' @template function #' @param data,draws,... For `loo_subsample.function()`, these are the data, #' posterior draws, and other arguments to pass to the log-likelihood #' function. Note that for some `loo_approximation`s, the draws will be replaced #' by the posteriors summary statistics to compute loo approximations. See #' argument `loo_approximation` for details. #' @param observations The subsample observations to use. The argument can take #' four (4) types of arguments: #' * `NULL` to use all observations. The algorithm then just uses #' standard `loo()` or `loo_approximate_posterior()`. #' * A single integer to specify the number of observations to be subsampled. #' * A vector of integers to provide the indices used to subset the data. #' _These observations need to be subsampled with the same scheme as given by #' the `estimator` argument_. #' * A `psis_loo_ss` object to use the same observations that were used in a #' previous call to `loo_subsample()`. #' #' @param log_p,log_g Should be supplied only if approximate posterior draws are #' used. The default (`NULL`) indicates draws are from "true" posterior (i.e. #' using MCMC). If not `NULL` then they should be specified as described in #' [loo_approximate_posterior()]. #' #' @param loo_approximation What type of approximation of the loo_i's should be used? #' The default is `"plpd"` (the log predictive density using the posterior expectation). #' There are six different methods implemented to approximate loo_i's #' (see the references for more details): #' * `"plpd"`: uses the lpd based on point estimates (i.e., \eqn{p(y_i|\hat{\theta})}). #' * `"lpd"`: uses the lpds (i,e., \eqn{p(y_i|y)}). #' * `"tis"`: uses truncated importance sampling to approximate PSIS-LOO. #' * `"waic"`: uses waic (i.e., \eqn{p(y_i|y) - p_{waic}}). #' * `"waic_grad_marginal"`: uses waic approximation using first order delta #' method and posterior marginal variances to approximate \eqn{p_{waic}} (ie. #' \eqn{p(y_i|\hat{\theta})}-p_waic_grad_marginal). Requires gradient of #' likelihood function. #' * `"waic_grad"`: uses waic approximation using first order delta method and #' posterior covariance to approximate \eqn{p_{waic}} (ie. #' \eqn{p(y_i|\hat{\theta})}-p_waic_grad). Requires gradient of likelihood #' function. #' * `"waic_hess"`: uses waic approximation using second order delta method and #' posterior covariance to approximate \eqn{p_{waic}} (ie. #' \eqn{p(y_i|\hat{\theta})}-p_waic_grad). Requires gradient and Hessian of #' likelihood function. #' #' As point estimates of \eqn{\hat{\theta}}, the posterior expectations #' of the parameters are used. #' #' @param loo_approximation_draws The number of posterior draws used when #' integrating over the posterior. This is used if `loo_approximation` is set #' to `"lpd"`, `"waic"`, or `"tis"`. #' #' @param estimator How should `elpd_loo`, `p_loo` and `looic` be estimated? #' The default is `"diff_srs"`. #' * `"diff_srs"`: uses the difference estimator with simple random sampling #' (srs). `p_loo` is estimated using standard srs. #' * `"hh"`: uses the Hansen-Hurwitz estimator with sampling proportional to #' size, where `abs` of loo_approximation is used as size. #' * `"srs"`: uses simple random sampling and ordinary estimation. #' #' @param llgrad The gradient of the log-likelihood. This #' is only used when `loo_approximation` is `"waic_grad"`, #' `"waic_grad_marginal"`, or `"waic_hess"`. The default is `NULL`. #' @param llhess The hessian of the log-likelihood. This is only used #' with `loo_approximation = "waic_hess"`. The default is `NULL`. #' loo_subsample.function <- function(x, ..., data = NULL, draws = NULL, observations = 400, log_p = NULL, log_g = NULL, r_eff = NULL, save_psis = FALSE, cores = getOption("mc.cores", 1), loo_approximation = "plpd", loo_approximation_draws = NULL, estimator = "diff_srs", llgrad = NULL, llhess = NULL) { cores <- loo_cores(cores) # Asserting inputs .llfun <- validate_llfun(x) stopifnot(is.data.frame(data) || is.matrix(data), !is.null(draws)) observations <- assert_observations(observations, N = dim(data)[1], estimator) checkmate::assert_numeric(log_p, len = length(log_g), null.ok = TRUE) checkmate::assert_null(dim(log_p)) checkmate::assert_numeric(log_g, len = length(log_p), null.ok = TRUE) checkmate::assert_null(dim(log_g)) if (is.null(log_p) && is.null(log_g)) { if (is.null(r_eff)) { throw_loo_r_eff_warning() } else { r_eff <- prepare_psis_r_eff(r_eff, len = dim(data)[1]) } } checkmate::assert_flag(save_psis) cores <- loo_cores(cores) checkmate::assert_choice(loo_approximation, choices = loo_approximation_choices(), null.ok = FALSE) checkmate::assert_int(loo_approximation_draws, lower = 1, upper = .ndraws(draws), null.ok = TRUE) checkmate::assert_choice(estimator, choices = estimator_choices()) .llgrad <- .llhess <- NULL if (!is.null(llgrad)) .llgrad <- validate_llfun(llgrad) if (!is.null(llhess)) .llhess <- validate_llfun(llhess) # Fallbacks if (is.null(observations)) { if (is.null(log_p) && is.null(log_g)) { loo_obj <- loo.function( .llfun, ..., data = data, draws = draws, r_eff = r_eff, save_psis = save_psis, cores = cores ) } else { loo_obj <- loo_approximate_posterior.function( .llfun, ..., log_p = log_p, log_g = log_g, data = data, draws = draws, save_psis = save_psis, cores = cores ) } return(loo_obj) } # Compute loo approximation elpd_loo_approx <- elpd_loo_approximation( .llfun = .llfun, data = data, draws = draws, cores = cores, loo_approximation = loo_approximation, loo_approximation_draws = loo_approximation_draws, .llgrad = .llgrad, .llhess = .llhess ) # Draw subsample of observations if (length(observations) == 1) { # Compute idxs idxs <- subsample_idxs( estimator = estimator, elpd_loo_approximation = elpd_loo_approx, observations = observations ) } else { # Compute idxs idxs <- compute_idxs(observations) } data_subsample <- data[idxs$idx,, drop = FALSE] if (length(r_eff) > 1) { r_eff <- r_eff[idxs$idx] } # Compute elpd_loo if (!is.null(log_p) && !is.null(log_g)) { loo_obj <- loo_approximate_posterior.function( x = .llfun, data = data_subsample, draws = draws, log_p = log_p, log_g = log_g, save_psis = save_psis, cores = cores ) } else { loo_obj <- loo.function( x = .llfun, data = data_subsample, draws = draws, r_eff = r_eff, save_psis = save_psis, cores = cores ) } # Construct ss object and estimate loo_ss <- psis_loo_ss_object(x = loo_obj, idxs = idxs, elpd_loo_approx = elpd_loo_approx, loo_approximation = loo_approximation, loo_approximation_draws = loo_approximation_draws, estimator = estimator, .llfun = .llfun, .llgrad = .llgrad, .llhess = .llhess, data_dim = dim(data), ndraws = .ndraws(draws)) loo_ss } #' Update `psis_loo_ss` objects #' #' @details #' If `observations` is updated then if a vector of indices or a `psis_loo_ss` #' object is supplied the updated object will have exactly the observations #' indicated by the vector or `psis_loo_ss` object. If a single integer is #' supplied, new observations will be sampled to reach the supplied sample size. #' #' @export #' @inheritParams loo_subsample.function #' @param data,draws See [loo_subsample.function()]. #' @param object A `psis_loo_ss` object to update. #' @param ... Currently not used. #' @return A `psis_loo_ss` object. #' @importFrom stats update update.psis_loo_ss <- function(object, ..., data = NULL, draws = NULL, observations = NULL, r_eff = NULL, cores = getOption("mc.cores", 1), loo_approximation = NULL, loo_approximation_draws = NULL, llgrad = NULL, llhess = NULL) { # Fallback if (is.null(observations) & is.null(loo_approximation) & is.null(loo_approximation_draws) & is.null(llgrad) & is.null(llhess)) return(object) if (!is.null(data)) { stopifnot(is.data.frame(data) || is.matrix(data)) checkmate::assert_true(all(dim(data) == object$loo_subsampling$data_dim)) } if (!is.null(draws)) { # No current checks } cores <- loo_cores(cores) # Update elpd approximations if (!is.null(loo_approximation) | !is.null(loo_approximation_draws)) { stopifnot(is.data.frame(data) || is.matrix(data) & !is.null(draws)) if (object$loo_subsampling$estimator %in% "hh_pps") { # HH estimation uses elpd_loo approx to sample, # so updating it will lead to incorrect results stop("Can not update loo_approximation when using PPS sampling.", call. = FALSE) } if (is.null(loo_approximation)) loo_approximation <- object$loo_subsampling$loo_approximation if (is.null(loo_approximation_draws)) loo_approximation_draws <- object$loo_subsampling$loo_approximation_draws if (is.null(llgrad)) .llgrad <- object$loo_subsampling$.llgrad else .llgrad <- validate_llfun(llgrad) if (is.null(llhess)) .llhess <- object$loo_subsampling$.llhess else .llhess <- validate_llfun(llhess) # Compute loo approximation elpd_loo_approx <- elpd_loo_approximation(.llfun = object$loo_subsampling$.llfun, data = data, draws = draws, cores = cores, loo_approximation = loo_approximation, loo_approximation_draws = loo_approximation_draws, .llgrad = .llgrad, .llhess = .llhess) # Update object object$loo_subsampling$elpd_loo_approx <- elpd_loo_approx object$loo_subsampling$loo_approximation <- loo_approximation object$loo_subsampling["loo_approximation_draws"] <- list(loo_approximation_draws) object$loo_subsampling$.llgrad <- .llgrad object$loo_subsampling$.llhess <- .llhess object$pointwise[, "elpd_loo_approx"] <- object$loo_subsampling$elpd_loo_approx[object$pointwise[, "idx"]] } # Update observations if (!is.null(observations)) { observations <- assert_observations(observations, N = object$loo_subsampling$data_dim[1], object$loo_subsampling$estimator) if (length(observations) == 1) { checkmate::assert_int(observations, lower = nobs(object) + 1) stopifnot(is.data.frame(data) || is.matrix(data) & !is.null(draws)) } # Compute subsample indecies if (length(observations) > 1) { idxs <- compute_idxs(observations) } else { current_obs <- nobs(object) # If sampling with replacement if (object$loo_subsampling$estimator %in% c("hh_pps")) { idxs <- subsample_idxs(estimator = object$loo_subsampling$estimator, elpd_loo_approximation = object$loo_subsampling$elpd_loo_approx, observations = observations - current_obs) } # If sampling without replacement if (object$loo_subsampling$estimator %in% c("diff_srs", "srs")) { current_idxs <- obs_idx(object, rep = FALSE) new_idx <- (1:length(object$loo_subsampling$elpd_loo_approx))[-current_idxs] idxs <- subsample_idxs(estimator = object$loo_subsampling$estimator, elpd_loo_approximation = object$loo_subsampling$elpd_loo_approx[-current_idxs], observations = observations - current_obs) idxs$idx <- new_idx[idxs$idx] } } # Identify how to update object cidxs <- compare_idxs(idxs, object) # Compute new observations if (!is.null(cidxs$new)) { stopifnot(is.data.frame(data) || is.matrix(data) & !is.null(draws)) data_new_subsample <- data[cidxs$new$idx,, drop = FALSE] if (length(r_eff) > 1) r_eff <- r_eff[cidxs$new$idx] if (!is.null(object$approximate_posterior$log_p) & !is.null(object$approximate_posterior$log_g)) { loo_obj <- loo_approximate_posterior.function(x = object$loo_subsampling$.llfun, data = data_new_subsample, draws = draws, log_p = object$approximate_posterior$log_p, log_g = object$approximate_posterior$log_g, save_psis = !is.null(object$psis_object), cores = cores) } else { loo_obj <- loo.function(x = object$loo_subsampling$.llfun, data = data_new_subsample, draws = draws, r_eff = r_eff, save_psis = !is.null(object$psis_object), cores = cores) } # Add stuff to pointwise loo_obj$pointwise <- add_subsampling_vars_to_pointwise(loo_obj$pointwise, cidxs$new, object$loo_subsampling$elpd_loo_approx) } else { loo_obj <- NULL } if (length(observations) == 1) { # Add new samples pointwise and diagnostic object <- rbind.psis_loo_ss(object, x = loo_obj) # Update m_i for current pointwise (diagnostic stay the same) object$pointwise <- update_m_i_in_pointwise(object$pointwise, cidxs$add, type = "add") } else { # Add new samples pointwise and diagnostic object <- rbind.psis_loo_ss(object, loo_obj) # Replace m_i current pointwise and diagnostics object$pointwise <- update_m_i_in_pointwise(object$pointwise, cidxs$add, type = "replace") # Remove samples object <- remove_idx.psis_loo_ss(object, idxs = cidxs$remove) stopifnot(setequal(obs_idx(object), observations)) # Order object as in observations object <- order.psis_loo_ss(object, observations) } } # Compute estimates if (object$loo_subsampling$estimator == "hh_pps") { object <- loo_subsample_estimation_hh(object) } else if (object$loo_subsampling$estimator == "diff_srs") { object <- loo_subsample_estimation_diff_srs(object) } else if (object$loo_subsampling$estimator == "srs") { object <- loo_subsample_estimation_srs(object) } else { stop("No correct estimator used.") } assert_psis_loo_ss(object) object } #' Get observation indices used in subsampling #' #' @param x A `psis_loo_ss` object. #' @param rep If sampling with replacement is used, an observation can have #' multiple samples and these are then repeated in the returned object if #' `rep=TRUE` (e.g., a vector `c(1,1,2)` indicates that observation 1 has been #' subampled two times). If `rep=FALSE` only the unique indices are returned. #' #' @return An integer vector. #' #' @export obs_idx <- function(x, rep = TRUE) { checkmate::assert_class(x, "psis_loo_ss") if (rep) { idxs <- as.integer(rep(x$pointwise[,"idx"], x$pointwise[,"m_i"])) } else { idxs <- as.integer(x$pointwise[,"idx"]) } idxs } #' The number of observations in a `psis_loo_ss` object. #' @importFrom stats nobs #' @param object a `psis_loo_ss` object. #' @param ... Currently unused. #' @export nobs.psis_loo_ss <- function(object, ...) { as.integer(sum(object$pointwise[,"m_i"])) } # internal ---------------------------------------------------------------- #' The possible choices of loo_approximations implemented #' #' @details #' The choice `psis` is returned if a `psis_loo` object #' is converted to a `psis_loo_ss` object with `as.psis_loo_ss()`. #' But `psis` cannot be chosen in the api of `loo_subsample()`. #' #' @noRd #' @param api The choices available in the loo API or all possible choices. #' @return A character vector of allowed choices. loo_approximation_choices <- function(api = TRUE) { lac <- c("plpd", "lpd", "waic", "waic_grad_marginal", "waic_grad", "waic_hess", "tis", "sis", "none") if (!api) lac <- c(lac, "psis") lac } #' The estimators implemented #' #' @noRd #' @return A character vector of allowed choices. estimator_choices <- function() { c("hh_pps", "diff_srs", "srs") } ## Approximate elpd ----- #' Utility function to apply user-specified log-likelihood to a single data point #' @details #' See [elpd_loo_approximation] and [compute_lpds] for usage examples #' @noRd #' #' @return lpd value for a single data point i lpd_i <- function(i, llfun, data, draws) { ll_i <- llfun(data_i = data[i,, drop=FALSE], draws = draws) ll_i <- as.vector(ll_i) lpd_i <- logMeanExp(ll_i) lpd_i } #' Utility function to compute lpd using user-defined likelihood function #' using platform-dependent parallel backends when cores > 1 #' #' @details #' See [elpd_loo_approximation] for usage examples #' #' @noRd #' @return a vector of computed log probability densities compute_lpds <- function(N, data, draws, llfun, cores) { if (cores == 1) { lpds <- lapply(X = seq_len(N), FUN = lpd_i, llfun, data, draws) } else { if (.Platform$OS.type != "windows") { lpds <- mclapply(X = seq_len(N), mc.cores = cores, FUN = lpd_i, llfun, data, draws) } else { cl <- makePSOCKcluster(cores) on.exit(stopCluster(cl)) lpds <- parLapply(cl, X = seq_len(N), fun = lpd_i, llfun, data, draws) } } unlist(lpds) } #' Compute approximation to loo_i:s #' #' @details #' See [loo_subsample.function()] and the `loo_approximation` argument. #' @noRd #' @inheritParams loo_subsample.function #' #' @return a vector with approximations of elpd_{loo,i}s elpd_loo_approximation <- function(.llfun, data, draws, cores, loo_approximation, loo_approximation_draws = NULL, .llgrad = NULL, .llhess = NULL) { checkmate::assert_function(.llfun, args = c("data_i", "draws"), ordered = TRUE) stopifnot(is.data.frame(data) || is.matrix(data), !is.null(draws)) checkmate::assert_choice(loo_approximation, choices = loo_approximation_choices(), null.ok = FALSE) checkmate::assert_int(loo_approximation_draws, lower = 2, null.ok = TRUE) if (!is.null(.llgrad)) { checkmate::assert_function(.llgrad, args = c("data_i", "draws"), ordered = TRUE) } if (!is.null(.llhess)) { checkmate::assert_function(.llhess, args = c("data_i", "draws"), ordered = TRUE) } cores <- loo_cores(cores) N <- dim(data)[1] if (loo_approximation == "none") return(rep(1L,N)) if (loo_approximation %in% c("tis", "sis")) { draws <- .thin_draws(draws, loo_approximation_draws) is_values <- suppressWarnings(loo.function(.llfun, data = data, draws = draws, is_method = loo_approximation)) return(is_values$pointwise[, "elpd_loo"]) } if (loo_approximation == "waic") { draws <- .thin_draws(draws, loo_approximation_draws) waic_full_obj <- waic.function(.llfun, data = data, draws = draws) return(waic_full_obj$pointwise[,"elpd_waic"]) } # Compute the lpd or log p(y_i|y_{-i}) if (loo_approximation == "lpd") { draws <- .thin_draws(draws, loo_approximation_draws) lpds <- compute_lpds(N, data, draws, .llfun, cores) return(lpds) # Use only the lpd } # Compute the point lpd or log p(y_i|\hat{\theta}) - also used in waic_delta approaches if (loo_approximation == "plpd" | loo_approximation == "waic_grad" | loo_approximation == "waic_grad_marginal" | loo_approximation == "waic_hess") { draws <- .thin_draws(draws, loo_approximation_draws) point_est <- .compute_point_estimate(draws) lpds <- compute_lpds(N, data, point_est, .llfun, cores) if (loo_approximation == "plpd") return(lpds) # Use only the lpd } if (loo_approximation == "waic_grad" | loo_approximation == "waic_grad_marginal" | loo_approximation == "waic_hess") { checkmate::assert_true(!is.null(.llgrad)) point_est <- .compute_point_estimate(draws) # Compute the lpds lpds <- compute_lpds(N, data, point_est, .llfun, cores) if (loo_approximation == "waic_grad" | loo_approximation == "waic_hess") { cov_est <- stats::cov(draws) } if (loo_approximation == "waic_grad_marginal") { marg_vars <- apply(draws, MARGIN = 2, var) } p_eff_approx <- numeric(N) if (cores>1) warning("Multicore is not implemented for waic_delta", call. = FALSE) if (loo_approximation == "waic_grad") { for(i in 1:nrow(data)) { grad_i <- t(.llgrad(data[i,,drop = FALSE], point_est)) local_cov <- cov_est[rownames(grad_i), rownames(grad_i)] p_eff_approx[i] <- t(grad_i) %*% local_cov %*% grad_i } } else if (loo_approximation == "waic_grad_marginal") { for(i in 1:nrow(data)) { grad_i <- t(.llgrad(data[i,,drop = FALSE], point_est)) p_eff_approx[i] <- sum(grad_i * marg_vars[rownames(grad_i)] * grad_i) } } else if (loo_approximation == "waic_hess") { checkmate::assert_true(!is.null(.llhess)) for(i in 1:nrow(data)) { grad_i <- t(.llgrad(data[i,,drop = FALSE], point_est)) hess_i <- .llhess(data_i = data[i,,drop = FALSE], draws = point_est[,rownames(grad_i), drop = FALSE])[,,1] local_cov <- cov_est[rownames(grad_i), rownames(grad_i)] p_eff_approx[i] <- t(grad_i) %*% local_cov %*% grad_i + 0.5 * sum(diag(local_cov %*% hess_i %*% local_cov %*% hess_i)) } } else { stop(loo_approximation, " is not implemented!", call. = FALSE) } return(lpds - p_eff_approx) } } #' Compute a point estimate from a draws object #' #' @details This is a generic function to thin draws from arbitrary draws #' objects. The function is internal and should only be used by developers to #' enable [loo_subsample()] for arbitrary draws objects. #' #' @param draws A draws object with draws from the posterior. #' @return A 1 by P matrix with point estimates from a draws object. #' @keywords internal #' @export .compute_point_estimate <- function(draws) { UseMethod(".compute_point_estimate") } .compute_point_estimate.matrix <- function(draws) { t(as.matrix(colMeans(draws))) } .compute_point_estimate.default <- function(draws) { stop(".compute_point_estimate() has not been implemented for objects of class '", class(draws), "'") } #' Thin a draws object #' #' @details This is a generic function to thin draws from arbitrary draws #' objects. The function is internal and should only be used by developers to #' enable [loo_subsample()] for arbitrary draws objects. #' #' @param draws A draws object with posterior draws. #' @param loo_approximation_draws The number of posterior draws to return (ie after thinning). #' @keywords internal #' @export #' @return A thinned draws object. .thin_draws <- function(draws, loo_approximation_draws) { UseMethod(".thin_draws") } .thin_draws.matrix <- function(draws, loo_approximation_draws) { if (is.null(loo_approximation_draws)) return(draws) checkmate::assert_int(loo_approximation_draws, lower = 1, upper = .ndraws(draws), null.ok = TRUE) S <- .ndraws(draws) idx <- 1:loo_approximation_draws * S %/% loo_approximation_draws draws <- draws[idx, , drop = FALSE] draws } .thin_draws.numeric <- function(draws, loo_approximation_draws) { .thin_draws.matrix(as.matrix(draws), loo_approximation_draws) } .thin_draws.default <- function(draws, loo_approximation_draws) { stop(".thin_draws() has not been implemented for objects of class '", class(draws), "'") } #' The number of posterior draws in a draws object. #' #' @details This is a generic function to return the total number of draws from #' an arbitrary draws objects. The function is internal and should only be #' used by developers to enable [loo_subsample()] for arbitrary draws objects. #' #' @param x A draws object with posterior draws. #' @return An integer with the number of draws. #' @keywords internal #' @export .ndraws <- function(x) { UseMethod(".ndraws") } .ndraws.matrix <- function(x) { nrow(x) } .ndraws.default <- function(x) { stop(".ndraws() has not been implemented for objects of class '", class(x), "'") } ## Subsampling ----- #' Subsampling strategy #' #' @noRd #' @param estimator The estimator to use, see `estimator_choices()`. #' @param elpd_loo_approximation A vector of loo approximations, see `elpd_loo_approximation()`. #' @param observations The total number of subsample observations to sample. #' @return A `subsample_idxs` data frame. subsample_idxs <- function(estimator, elpd_loo_approximation, observations) { checkmate::assert_choice(estimator, choices = estimator_choices()) checkmate::assert_numeric(elpd_loo_approximation) checkmate::assert_int(observations) if (estimator == "hh_pps") { pi_values <- pps_elpd_loo_approximation_to_pis(elpd_loo_approximation) idxs_df <- pps_sample(observations, pis = pi_values) } if (estimator == "diff_srs" | estimator == "srs") { if (observations > length(elpd_loo_approximation)) { stop("'observations' is larger than the total sample size in 'data'.", call. = FALSE) } idx <- 1:length(elpd_loo_approximation) idx_m <- idx[order(stats::runif(length(elpd_loo_approximation)))][1:observations] idx_m <- idx_m[order(idx_m)] idxs_df <- data.frame(idx=as.integer(idx_m), m_i=1L) } assert_subsample_idxs(x = idxs_df) idxs_df } #' Compute pis from approximation for use in pps sampling. #' @noRd #' @details pis are the sampling probabilities and sum to 1. #' @inheritParams subsample_idxs #' @return A vector of pis. pps_elpd_loo_approximation_to_pis <- function(elpd_loo_approximation) { checkmate::assert_numeric(elpd_loo_approximation) pi_values <- abs(elpd_loo_approximation) pi_values <- pi_values/sum(pi_values) # \tilde{\pi} pi_values } #' Compute subsampling indices from an observation vector #' @noRd #' @param observation A vector of indices. #' @return A `subsample_idxs` data frame. compute_idxs <- function(observations) { checkmate::assert_integer(observations, lower = 1, min.len = 2, any.missing = FALSE) tab <- table(observations) idxs_df <- data.frame(idx = as.integer(names(tab)), m_i = as.integer(unname(tab))) assert_subsample_idxs(idxs_df) idxs_df } #' Compare the indecies to prepare handling #' #' @details #' The function compares the object and sampled indices into `new` #' (observations not in `object`), `add` (observations in `object`), and #' `remove` (observations in `object` but not in idxs). #' @noRd #' @param idxs A `subsample_idxs` data frame. #' @param object A `psis_loo_ss` object. #' @return A list of three `subsample_idxs` data frames. Elements without any #' observations return `NULL`. compare_idxs <- function(idxs, object) { assert_subsample_idxs(idxs) current_idx <- compute_idxs(obs_idx(object)) result <- list() new_idx <- !(idxs$idx %in% current_idx$idx) remove_idx <- !(current_idx$idx %in% idxs$idx) result$new <- idxs[new_idx, ] if (nrow(result$new) == 0) { result["new"] <- NULL } else { assert_subsample_idxs(result$new) } result$add <- idxs[!new_idx, ] if (nrow(result$add) == 0) { result["add"] <- NULL } else { assert_subsample_idxs(result$add) } result$remove <- current_idx[remove_idx, ] if (nrow(result$remove) == 0) { result["remove"] <- NULL } else { assert_subsample_idxs(result$remove) } result } #' Draw a PPS sample with replacement and return a idx_df #' @noRd #' @details #' We are sampling with replacement, hence we only want to compute elpd #' for each observation once. #' @param m The total sampling size. #' @param pis The probability of selecting each observation. #' @return a `subsample_idxs` data frame. pps_sample <- function(m, pis) { checkmate::assert_int(m) checkmate::assert_numeric(pis, min.len = 2, lower = 0, upper = 1) idx <- sample(1:length(pis), size = m, replace = TRUE, prob = pis) idxs_df <- as.data.frame(table(idx), stringsAsFactors = FALSE) colnames(idxs_df) <- c("idx", "m_i") idxs_df$idx <- as.integer(idxs_df$idx) idxs_df$m_i <- as.integer(idxs_df$m_i) assert_subsample_idxs(idxs_df) idxs_df } ## Constructor --- #' Construct a `psis_loo_ss} object #' #' @noRd #' @param x A `psis_loo` object. #' @param idxs a `subsample_idxs` data frame. #' @param elpd_loo_approximation A vector of loo approximations, see #' `elpd_loo_approximation()`. #' @inheritParams loo_subsample #' @param .llfun,.llgrad,.llhess See llfun, llgrad and llhess in `loo_subsample()`. #' @param data_dim Dimension of the data object. #' @param ndraws Dimension of the draws object. #' @return A `psis_loo_ss` object. psis_loo_ss_object <- function(x, idxs, elpd_loo_approx, loo_approximation, loo_approximation_draws, estimator, .llfun, .llgrad, .llhess, data_dim, ndraws) { # Assertions checkmate::assert_class(x, "psis_loo") assert_subsample_idxs(idxs) checkmate::assert_numeric(elpd_loo_approx, any.missing = FALSE) checkmate::assert_choice(loo_approximation, loo_approximation_choices()) checkmate::assert_int(loo_approximation_draws, null.ok = TRUE) checkmate::assert_choice(estimator, estimator_choices()) checkmate::assert_function(.llfun, args = c("data_i", "draws"), ordered = TRUE) checkmate::assert_function(.llgrad, args = c("data_i", "draws"), ordered = TRUE, null.ok = TRUE) checkmate::assert_function(.llhess, args = c("data_i", "draws"), ordered = TRUE, null.ok = TRUE) checkmate::assert_integer(data_dim, len = 2, lower = 1, any.missing = FALSE) checkmate::assert_int(ndraws, lower = 1) # Construct object class(x) <- c("psis_loo_ss", class(x)) x$pointwise <- add_subsampling_vars_to_pointwise(pointwise = x$pointwise, idxs, elpd_loo_approx) x$estimates <- cbind(x$estimates, matrix(0, nrow = nrow(x$estimates))) colnames(x$estimates)[ncol(x$estimates)] <- "subsampling SE" x$loo_subsampling <- list() x$loo_subsampling$elpd_loo_approx <- elpd_loo_approx x$loo_subsampling$loo_approximation <- loo_approximation x$loo_subsampling["loo_approximation_draws"] <- list(loo_approximation_draws) x$loo_subsampling$estimator <- estimator x$loo_subsampling$.llfun <- .llfun x$loo_subsampling[".llgrad"] <- list(.llgrad) x$loo_subsampling[".llhess"] <- list(.llhess) x$loo_subsampling$data_dim <- data_dim x$loo_subsampling$ndraws <- ndraws # Compute estimates if (estimator == "hh_pps") { x <- loo_subsample_estimation_hh(x) } else if (estimator == "diff_srs") { x <- loo_subsample_estimation_diff_srs(x) } else if (estimator == "srs") { x <- loo_subsample_estimation_srs(x) } else { stop("No correct estimator used.") } assert_psis_loo_ss(x) x } as.psis_loo_ss <- function(x) { UseMethod("as.psis_loo_ss") } as.psis_loo_ss.psis_loo_ss <- function(x) { x } as.psis_loo_ss.psis_loo <- function(x) { class(x) <- c("psis_loo_ss", class(x)) x$estimates <- cbind(x$estimates, matrix(0, nrow = nrow(x$estimates))) colnames(x$estimates)[ncol(x$estimates)] <- "subsampling SE" x$pointwise <- cbind(x$pointwise, matrix(1:nrow(x$pointwise), byrow = FALSE, ncol = 1), matrix(rep(1,nrow(x$pointwise)), byrow = FALSE, ncol = 1), x$pointwise[, "elpd_loo"]) ncp <- ncol(x$pointwise) colnames(x$pointwise)[(ncp-2):ncp] <- c("idx", "m_i", "elpd_loo_approx") x$loo_subsampling <- list(elpd_loo_approx=x$pointwise[, "elpd_loo"], loo_approximation = "psis", loo_approximation_draws = NULL, estimator = "diff_srs", data_dim = c(nrow(x$pointwise), NA), ndraws = NA) assert_psis_loo_ss(x) x } as.psis_loo <- function(x) { UseMethod("as.psis_loo") } as.psis_loo.psis_loo <- function(x) { x } as.psis_loo.psis_loo_ss <- function(x) { if (x$loo_subsampling$data_dim[1] == nrow(x$pointwise)) { x$estimates <- x$estimates[, 1:2] x$pointwise <- x$pointwise[, 1:5] x$loo_subsampling <- NULL loo_obj <- importance_sampling_loo_object(pointwise = x$pointwise[, 1:5], diagnostics = x$diagnostics, dims = attr(x, "dims"), is_method = "psis", is_object = x$psis_object) if (inherits(x, "psis_loo_ap")) { loo_obj$approximate_posterior <- list(log_p = x$approximate_posterior$log_p, log_g = x$approximate_posterior$log_g) class(loo_obj) <- c("psis_loo_ap", class(loo_obj)) assert_psis_loo_ap(loo_obj) } } else { stop("A subsampling loo object can only be coerced to a loo object ", "if all observations in data have been subsampled.", call. = FALSE) } loo_obj } #' Add subsampling information to the pointwise element in a `psis_loo` object. #' @noRd #' @param pointwise The `pointwise` element in a `psis_loo` object. #' @param idxs A `subsample_idxs` data frame. #' @param elpd_loo_approximation A vector of loo approximations, see `elpd_loo_approximation()`. #' @return A `pointwise` matrix with subsampling information. add_subsampling_vars_to_pointwise <- function(pointwise, idxs, elpd_loo_approx) { checkmate::assert_matrix(pointwise, any.missing = FALSE, min.cols = 5) checkmate::assert_names(colnames(pointwise), identical.to = c("elpd_loo","mcse_elpd_loo","p_loo","looic", "influence_pareto_k")) assert_subsample_idxs(idxs) checkmate::assert_numeric(elpd_loo_approx) pw <- cbind(as.data.frame(pointwise), idxs) pw$elpd_loo_approx <- elpd_loo_approx[idxs$idx] pw <- as.matrix(pw) rownames(pw) <- NULL assert_subsampling_pointwise(pw) pw } #' Add `psis_loo` object to a `psis_loo_ss` object #' @noRd #' @param object A `psis_loo_ss` object. #' @param x A `psis_loo` object. #' @return An updated `psis_loo_ss` object. rbind.psis_loo_ss <- function(object, x) { checkmate::assert_class(object, "psis_loo_ss") if (is.null(x)) return(object) # Fallback checkmate::assert_class(x, "psis_loo") assert_subsampling_pointwise(object$pointwise) assert_subsampling_pointwise(x$pointwise) checkmate::assert_disjunct(object$pointwise[, "idx"], x$pointwise[, "idx"]) object$pointwise <- rbind(object$pointwise, x$pointwise) object$diagnostics$pareto_k <- c(object$diagnostics$pareto_k, x$diagnostics$pareto_k) object$diagnostics$n_eff <- c(object$diagnostics$n_eff, x$diagnostics$n_eff) attr(object, "dims")[2] <- nrow(object$pointwise) object } #' Remove observations in `idxs` from object #' @noRd #' @param object A `psis_loo_ss` object. #' @param idxs A `subsample_idxs` data frame. #' @return A `psis_loo_ss` object. remove_idx.psis_loo_ss <- function(object, idxs) { checkmate::assert_class(object, "psis_loo_ss") if (is.null(idxs)) return(object) # Fallback assert_subsample_idxs(idxs) row_map <- data.frame( row_no = 1:nrow(object$pointwise), idx = object$pointwise[, "idx"] ) row_map <- merge(row_map, idxs, by = "idx", all.y = TRUE) object$pointwise <- object$pointwise[-row_map$row_no,,drop = FALSE] object$diagnostics$pareto_k <- object$diagnostics$pareto_k[-row_map$row_no] object$diagnostics$n_eff <- object$diagnostics$n_eff[-row_map$row_no] attr(object, "dims")[2] <- nrow(object$pointwise) object } #' Order object by `observations`. #' @noRd #' @param x A `psis_loo_ss` object. #' @param observations A vector with indices. #' @return An ordered `psis_loo_ss` object. order.psis_loo_ss <- function(x, observations) { checkmate::assert_class(x, "psis_loo_ss") checkmate::assert_integer(observations, len = nobs(x)) if (identical(obs_idx(x), observations)) return(x) # Fallback checkmate::assert_set_equal(obs_idx(x), observations) row_map_x <- data.frame(row_no_x = 1:nrow(x$pointwise), idx = x$pointwise[, "idx"]) row_map_obs <- data.frame(row_no_obs = 1:length(observations), idx = observations) row_map <- merge(row_map_obs, row_map_x, by = "idx", sort = FALSE) x$pointwise <- x$pointwise[row_map$row_no_x,,drop = FALSE] x$diagnostics$pareto_k <- x$diagnostics$pareto_k[row_map$row_no_x] x$diagnostics$n_eff <- x$diagnostics$n_eff[row_map$row_no_x] x } #' Update m_i in a `pointwise` element. #' @noRd #' @param x A `psis_loo_ss` `pointwise` data frame. #' @param idxs A `subsample_idxs` data frame. #' @param type should the m_i:s in `idxs` `"replace"` the current m_i:s or #' `"add"` to them. #' @return An ordered `psis_loo_ss` object. update_m_i_in_pointwise <- function(pointwise, idxs, type = "replace") { assert_subsampling_pointwise(pointwise) if (is.null(idxs)) return(pointwise) # Fallback assert_subsample_idxs(idxs) checkmate::assert_choice(type, choices = c("replace", "add")) row_map <- data.frame(row_no = 1:nrow(pointwise), idx = pointwise[, "idx"]) row_map <- merge(row_map, idxs, by = "idx", all.y = TRUE) if (type == "replace") { pointwise[row_map$row_no, "m_i"] <- row_map$m_i } if (type == "add") { pointwise[row_map$row_no, "m_i"] <- pointwise[row_map$row_no, "m_i"] + row_map$m_i } pointwise } ## Estimation --- #' Estimate the elpd using the Hansen-Hurwitz estimator #' @noRd #' @param x A `psis_loo_ss` object. #' @return A `psis_loo_ss` object. loo_subsample_estimation_hh <- function(x) { checkmate::assert_class(x, "psis_loo_ss") N <- length(x$loo_subsampling$elpd_loo_approx) pis <- pps_elpd_loo_approximation_to_pis(x$loo_subsampling$elpd_loo_approx) pis_sample <- pis[x$pointwise[,"idx"]] hh_elpd_loo <- whhest(z = pis_sample, m_i = x$pointwise[, "m_i"], y = x$pointwise[, "elpd_loo"], N) srs_elpd_loo <- srs_est(y = x$pointwise[, "elpd_loo"], y_approx = pis_sample) x$estimates["elpd_loo", "Estimate"] <- hh_elpd_loo$y_hat_ppz if (hh_elpd_loo$hat_v_y_ppz > 0) { x$estimates["elpd_loo", "SE"] <- sqrt(hh_elpd_loo$hat_v_y_ppz) } else { warning("Negative estimate of SE, more subsampling obs. needed.", call. = FALSE) x$estimates["elpd_loo", "SE"] <- NaN } x$estimates["elpd_loo", "subsampling SE"] <- sqrt(hh_elpd_loo$v_hat_y_ppz) hh_p_loo <- whhest(z = pis_sample, m_i = x$pointwise[,"m_i"], y = x$pointwise[,"p_loo"], N) x$estimates["p_loo", "Estimate"] <- hh_p_loo$y_hat_ppz if (hh_p_loo$hat_v_y_ppz > 0) { x$estimates["p_loo", "SE"] <- sqrt(hh_p_loo$hat_v_y_ppz) } else { warning("Negative estimate of SE, more subsampling obs. needed.", call. = FALSE) x$estimates["elpd_loo", "SE"] <- NaN } x$estimates["p_loo", "subsampling SE"] <- sqrt(hh_p_loo$v_hat_y_ppz) update_psis_loo_ss_estimates(x) } #' Update a `psis_loo_ss} object with generic estimates #' #' @noRd #' @details #' Updates a `psis_loo_ss` with generic estimates (looic) #' and updates components in the object based on x$estimate. #' @param x A `psis_loo_ss` object. #' @return x A `psis_loo_ss` object. update_psis_loo_ss_estimates <- function(x) { checkmate::assert_class(x, "psis_loo_ss") x$estimates["looic", "Estimate"] <- (-2) * x$estimates["elpd_loo", "Estimate"] x$estimates["looic", "SE"] <- 2 * x$estimates["elpd_loo", "SE"] x$estimates["looic", "subsampling SE"] <- 2 * x$estimates["elpd_loo", "subsampling SE"] x$elpd_loo <- x$estimates["elpd_loo", "Estimate"] x$p_loo <- x$estimates["p_loo", "Estimate"] x$looic <- x$estimates["looic", "Estimate"] x$se_elpd_loo <- x$estimates["elpd_loo", "SE"] x$se_p_loo <- x$estimates["p_loo", "SE"] x$se_looic <- x$estimates["looic", "SE"] x } #' Weighted Hansen-Hurwitz estimator #' @noRd #' @param z Normalized probabilities for the observation. #' @param m_i The number of times obs i was selected. #' @param y The values observed. #' @param N The total number of observations in finite population. #' @return A list with estimates. whhest <- function(z, m_i, y, N) { checkmate::assert_numeric(z, lower = 0, upper = 1) checkmate::assert_numeric(y, len = length(z)) checkmate::assert_integerish(m_i, len = length(z)) est_list <- list(m = sum(m_i)) est_list$y_hat_ppz <- sum(m_i*(y/z))/est_list$m est_list$v_hat_y_ppz <- (sum(m_i*((y/z - est_list$y_hat_ppz)^2))/est_list$m)/(est_list$m-1) # See unbiadness proof in supplementary material to the article est_list$hat_v_y_ppz <- (sum(m_i*(y^2/z)) / est_list$m) + est_list$v_hat_y_ppz / N - est_list$y_hat_ppz^2 / N est_list } #' Estimate elpd using the difference estimator and srs wor #' @noRd #' @param x A `psis_loo_ss` object. #' @return A `psis_loo_ss` object. loo_subsample_estimation_diff_srs <- function(x) { checkmate::assert_class(x, "psis_loo_ss") elpd_loo_est <- srs_diff_est(y_approx = x$loo_subsampling$elpd_loo_approx, y = x$pointwise[, "elpd_loo"], y_idx = x$pointwise[, "idx"]) x$estimates["elpd_loo", "Estimate"] <- elpd_loo_est$y_hat x$estimates["elpd_loo", "SE"] <- sqrt(elpd_loo_est$hat_v_y) x$estimates["elpd_loo", "subsampling SE"] <- sqrt(elpd_loo_est$v_y_hat) p_loo_est <- srs_est(y = x$pointwise[, "p_loo"], y_approx = x$loo_subsampling$elpd_loo_approx) x$estimates["p_loo", "Estimate"] <- p_loo_est$y_hat x$estimates["p_loo", "SE"] <- sqrt(p_loo_est$hat_v_y) x$estimates["p_loo", "subsampling SE"] <- sqrt(p_loo_est$v_y_hat) update_psis_loo_ss_estimates(x) } #' Difference estimation using SRS-WOR sampling #' @noRd #' @param y_approx Approximated values of all observations. #' @param y The values observed. #' @param y_idx The index of `y` in `y_approx`. #' @return A list with estimates. srs_diff_est <- function(y_approx, y, y_idx) { checkmate::assert_numeric(y_approx) checkmate::assert_numeric(y, max.len = length(y_approx)) checkmate::assert_integerish(y_idx, len = length(y)) N <- length(y_approx) m <- length(y) y_approx_m <- y_approx[y_idx] e_i <- y - y_approx_m t_pi_tilde <- sum(y_approx) t_pi2_tilde <- sum(y_approx^2) t_e <- N * mean(e_i) t_hat_epsilon <- N * mean(y^2 - y_approx_m^2) est_list <- list(m = length(y), N = N) est_list$y_hat <- t_pi_tilde + t_e est_list$v_y_hat <- N^2 * (1 - m / N) * var(e_i) / m est_list$hat_v_y <- (t_pi2_tilde + t_hat_epsilon) - # a (has been checked) (1/N) * (t_e^2 - est_list$v_y_hat + 2 * t_pi_tilde * est_list$y_hat - t_pi_tilde^2) # b est_list } #' Estimate elpd using the standard SRS estimator and SRS WOR #' @noRd #' @param x A `psis_loo_ss` object. #' @return A `psis_loo_ss` object. loo_subsample_estimation_srs <- function(x) { checkmate::assert_class(x, "psis_loo_ss") elpd_loo_est <- srs_est(y = x$pointwise[, "elpd_loo"], y_approx = x$loo_subsampling$elpd_loo_approx) x$estimates["elpd_loo", "Estimate"] <- elpd_loo_est$y_hat x$estimates["elpd_loo", "SE"] <- sqrt(elpd_loo_est$hat_v_y) x$estimates["elpd_loo", "subsampling SE"] <- sqrt(elpd_loo_est$v_y_hat) p_loo_est <- srs_est(y = x$pointwise[, "p_loo"], y_approx = x$loo_subsampling$elpd_loo_approx) x$estimates["p_loo", "Estimate"] <- p_loo_est$y_hat x$estimates["p_loo", "SE"] <- sqrt(p_loo_est$hat_v_y) x$estimates["p_loo", "subsampling SE"] <- sqrt(p_loo_est$v_y_hat) update_psis_loo_ss_estimates(x) } #' Simple SRS-WOR estimation #' @noRd #' @param y The values observed. #' @param y_approx A vector of length N. #' @return A list of estimates. srs_est <- function(y, y_approx) { checkmate::assert_numeric(y) checkmate::assert_numeric(y_approx, min.len = length(y)) N <- length(y_approx) m <- length(y) est_list <- list(m = m) est_list$y_hat <- N * mean(y) est_list$v_y_hat <- N^2 * (1-m/N) * var(y)/m est_list$hat_v_y <- N * var(y) est_list } ## Specialized assertions of objects --- #' Assert that the object has the expected properties #' @noRd #' @param x An object to assert. #' @param N The total number of data points in data. #' @param estimator The estimator used. #' @return An asserted object of `x`. assert_observations <- function(x, N, estimator) { checkmate::assert_int(N) checkmate::assert_choice(estimator, choices = estimator_choices()) if (is.null(x)) return(x) if (checkmate::test_class(x, "psis_loo_ss")) { x <- obs_idx(x) checkmate::assert_integer(x, lower = 1, upper = N, any.missing = FALSE) return(x) } x <- as.integer(x) if (length(x) > 1) { checkmate::assert_integer(x, lower = 1, upper = N, any.missing = FALSE) if (estimator %in% "hh_pps") { message("Sampling proportional to elpd approximation and with replacement assumed.") } if (estimator %in% c("diff_srs", "srs")) { message("Simple random sampling with replacement assumed.") } } else { checkmate::assert_integer(x, lower = 1, any.missing = FALSE) } x } #' Assert that the object has the expected properties #' @noRd #' @inheritParams assert_observations #' @return An asserted object of `x`. assert_subsample_idxs <- function(x) { checkmate::assert_data_frame(x, types = c("integer", "integer"), any.missing = FALSE, min.rows = 1, col.names = "named") checkmate::assert_names(names(x), identical.to = c("idx", "m_i")) checkmate::assert_integer(x$idx, lower = 1, any.missing = FALSE, unique = TRUE) checkmate::assert_integer(x$m_i, lower = 1, any.missing = FALSE) x } #' Assert that the object has the expected properties #' @noRd #' @inheritParams assert_observations #' @return An asserted object of `x`. assert_psis_loo_ss <- function(x) { checkmate::assert_class(x, "psis_loo_ss") checkmate::assert_names(names(x), must.include = c("estimates", "pointwise", "diagnostics", "psis_object", "loo_subsampling")) checkmate::assert_names(rownames(x$estimates), must.include = c("elpd_loo", "p_loo", "looic")) checkmate::assert_names(colnames(x$estimates), must.include = c("Estimate", "SE", "subsampling SE")) assert_subsampling_pointwise(x$pointwise) checkmate::assert_names(names(x$loo_subsampling), must.include = c("elpd_loo_approx", "loo_approximation", "loo_approximation_draws", "estimator", "data_dim", "ndraws")) checkmate::assert_numeric(x$loo_subsampling$elpd_loo_approx, any.missing = FALSE, len = x$loo_subsampling$data_dim[1]) checkmate::assert_choice(x$loo_subsampling$loo_approximation, choices = loo_approximation_choices(api = FALSE)) checkmate::assert_int(x$loo_subsampling$loo_approximation_draws, null.ok = TRUE) checkmate::assert_choice(x$loo_subsampling$estimator, choices = estimator_choices()) checkmate::assert_integer(x$loo_subsampling$data_dim, any.missing = TRUE, len = 2) checkmate::assert_int(x$loo_subsampling$data_dim[1], na.ok = FALSE) checkmate::assert_integer(x$loo_subsampling$ndraws, len = 1, any.missing = TRUE) x } #' Assert that the object has the expected properties #' @noRd #' @inheritParams assert_observations #' @return An asserted object of `x`. assert_subsampling_pointwise <- function(x) { checkmate::assert_matrix(x, any.missing = FALSE, ncols = 8) checkmate::assert_names(colnames(x), identical.to = c("elpd_loo", "mcse_elpd_loo", "p_loo", "looic", "influence_pareto_k", "idx", "m_i", "elpd_loo_approx")) x } loo/R/loo_compare.R0000644000176200001440000002211214410420140013652 0ustar liggesusers#' Model comparison #' #' @description Compare fitted models based on [ELPD][loo-glossary]. #' #' By default the print method shows only the most important information. Use #' `print(..., simplify=FALSE)` to print a more detailed summary. #' #' @export #' @param x An object of class `"loo"` or a list of such objects. If a list is #' used then the list names will be used as the model names in the output. See #' **Examples**. #' @param ... Additional objects of class `"loo"`, if not passed in as a single #' list. #' #' @return A matrix with class `"compare.loo"` that has its own #' print method. See the **Details** section. #' #' @details #' When comparing two fitted models, we can estimate the difference in their #' expected predictive accuracy by the difference in #' [`elpd_loo`][loo-glossary] or `elpd_waic` (or multiplied by \eqn{-2}, if #' desired, to be on the deviance scale). #' #' When using `loo_compare()`, the returned matrix will have one row per model #' and several columns of estimates. The values in the #' [`elpd_diff`][loo-glossary] and [`se_diff`][loo-glossary] columns of the #' returned matrix are computed by making pairwise comparisons between each #' model and the model with the largest ELPD (the model in the first row). For #' this reason the `elpd_diff` column will always have the value `0` in the #' first row (i.e., the difference between the preferred model and itself) and #' negative values in subsequent rows for the remaining models. #' #' To compute the standard error of the difference in [ELPD][loo-glossary] --- #' which should not be expected to equal the difference of the standard errors #' --- we use a paired estimate to take advantage of the fact that the same #' set of \eqn{N} data points was used to fit both models. These calculations #' should be most useful when \eqn{N} is large, because then non-normality of #' the distribution is not such an issue when estimating the uncertainty in #' these sums. These standard errors, for all their flaws, should give a #' better sense of uncertainty than what is obtained using the current #' standard approach of comparing differences of deviances to a Chi-squared #' distribution, a practice derived for Gaussian linear models or #' asymptotically, and which only applies to nested models in any case. #' #' @seealso #' * The [FAQ page](https://mc-stan.org/loo/articles/online-only/faq.html) on #' the __loo__ website for answers to frequently asked questions. #' @template loo-and-psis-references #' #' @examples #' # very artificial example, just for demonstration! #' LL <- example_loglik_array() #' loo1 <- loo(LL, r_eff = NA) # should be worst model when compared #' loo2 <- loo(LL + 1, r_eff = NA) # should be second best model when compared #' loo3 <- loo(LL + 2, r_eff = NA) # should be best model when compared #' #' comp <- loo_compare(loo1, loo2, loo3) #' print(comp, digits = 2) #' #' # show more details with simplify=FALSE #' # (will be the same for all models in this artificial example) #' print(comp, simplify = FALSE, digits = 3) #' #' # can use a list of objects with custom names #' # will use apple, banana, and cherry, as the names in the output #' loo_compare(list("apple" = loo1, "banana" = loo2, "cherry" = loo3)) #' #' \dontrun{ #' # works for waic (and kfold) too #' loo_compare(waic(LL), waic(LL - 10)) #' } #' loo_compare <- function(x, ...) { UseMethod("loo_compare") } #' @rdname loo_compare #' @export loo_compare.default <- function(x, ...) { if (is.loo(x)) { dots <- list(...) loos <- c(list(x), dots) } else { if (!is.list(x) || !length(x)) { stop("'x' must be a list if not a 'loo' object.") } if (length(list(...))) { stop("If 'x' is a list then '...' should not be specified.") } loos <- x } # If subsampling is used if (any(sapply(loos, inherits, "psis_loo_ss"))) { return(loo_compare.psis_loo_ss_list(loos)) } loo_compare_checks(loos) comp <- loo_compare_matrix(loos) ord <- loo_compare_order(loos) # compute elpd_diff and se_elpd_diff relative to best model rnms <- rownames(comp) diffs <- mapply(FUN = elpd_diffs, loos[ord[1]], loos[ord]) elpd_diff <- apply(diffs, 2, sum) se_diff <- apply(diffs, 2, se_elpd_diff) comp <- cbind(elpd_diff = elpd_diff, se_diff = se_diff, comp) rownames(comp) <- rnms class(comp) <- c("compare.loo", class(comp)) return(comp) } #' @rdname loo_compare #' @export #' @param digits For the print method only, the number of digits to use when #' printing. #' @param simplify For the print method only, should only the essential columns #' of the summary matrix be printed? The entire matrix is always returned, but #' by default only the most important columns are printed. print.compare.loo <- function(x, ..., digits = 1, simplify = TRUE) { xcopy <- x if (inherits(xcopy, "old_compare.loo")) { if (NCOL(xcopy) >= 2 && simplify) { patts <- "^elpd_|^se_diff|^p_|^waic$|^looic$" xcopy <- xcopy[, grepl(patts, colnames(xcopy))] } } else if (NCOL(xcopy) >= 2 && simplify) { xcopy <- xcopy[, c("elpd_diff", "se_diff")] } print(.fr(xcopy, digits), quote = FALSE) invisible(x) } # internal ---------------------------------------------------------------- #' Compute pointwise elpd differences #' @noRd #' @param loo_a,loo_b Two `"loo"` objects. elpd_diffs <- function(loo_a, loo_b) { pt_a <- loo_a$pointwise pt_b <- loo_b$pointwise elpd <- grep("^elpd", colnames(pt_a)) pt_b[, elpd] - pt_a[, elpd] } #' Compute standard error of the elpd difference #' @noRd #' @param diffs Vector of pointwise elpd differences se_elpd_diff <- function(diffs) { N <- length(diffs) # As `elpd_diff` is defined as the sum of N independent components, # we can compute the standard error by using the standard deviation # of the N components and multiplying by `sqrt(N)`. sqrt(N) * sd(diffs) } #' Perform checks on `"loo"` objects before comparison #' @noRd #' @param loos List of `"loo"` objects. #' @return Nothing, just possibly throws errors/warnings. loo_compare_checks <- function(loos) { ## errors if (length(loos) <= 1L) { stop("'loo_compare' requires at least two models.", call.=FALSE) } if (!all(sapply(loos, is.loo))) { stop("All inputs should have class 'loo'.", call.=FALSE) } Ns <- sapply(loos, function(x) nrow(x$pointwise)) if (!all(Ns == Ns[1L])) { stop("Not all models have the same number of data points.", call.=FALSE) } ## warnings yhash <- lapply(loos, attr, which = "yhash") yhash_ok <- sapply(yhash, function(x) { # ok only if all yhash are same (all NULL is ok) isTRUE(all.equal(x, yhash[[1]])) }) if (!all(yhash_ok)) { warning("Not all models have the same y variable. ('yhash' attributes do not match)", call. = FALSE) } if (all(sapply(loos, is.kfold))) { Ks <- unlist(lapply(loos, attr, which = "K")) if (!all(Ks == Ks[1])) { warning("Not all kfold objects have the same K value. ", "For a more accurate comparison use the same number of folds. ", call. = FALSE) } } else if (any(sapply(loos, is.kfold)) && any(sapply(loos, is.psis_loo))) { warning("Comparing LOO-CV to K-fold-CV. ", "For a more accurate comparison use the same number of folds ", "or loo for all models compared.", call. = FALSE) } } #' Find the model names associated with `"loo"` objects #' #' @export #' @keywords internal #' @param x List of `"loo"` objects. #' @return Character vector of model names the same length as `x.` #' find_model_names <- function(x) { stopifnot(is.list(x)) out_names <- character(length(x)) names1 <- names(x) names2 <- lapply(x, "attr", "model_name", exact = TRUE) names3 <- lapply(x, "[[", "model_name") names4 <- paste0("model", seq_along(x)) for (j in seq_along(x)) { if (isTRUE(nzchar(names1[j]))) { out_names[j] <- names1[j] } else if (length(names2[[j]])) { out_names[j] <- names2[[j]] } else if (length(names3[[j]])) { out_names[j] <- names3[[j]] } else { out_names[j] <- names4[j] } } out_names } #' Compute the loo_compare matrix #' @keywords internal #' @noRd #' @param loos List of `"loo"` objects. loo_compare_matrix <- function(loos){ tmp <- sapply(loos, function(x) { est <- x$estimates setNames(c(est), nm = c(rownames(est), paste0("se_", rownames(est)))) }) colnames(tmp) <- find_model_names(loos) rnms <- rownames(tmp) comp <- tmp ord <- loo_compare_order(loos) comp <- t(comp)[ord, ] patts <- c("elpd", "p_", "^waic$|^looic$", "^se_waic$|^se_looic$") col_ord <- unlist(sapply(patts, function(p) grep(p, colnames(comp))), use.names = FALSE) comp <- comp[, col_ord] comp } #' Computes the order of loos for comparison #' @noRd #' @keywords internal #' @param loos List of `"loo"` objects. loo_compare_order <- function(loos){ tmp <- sapply(loos, function(x) { est <- x$estimates setNames(c(est), nm = c(rownames(est), paste0("se_", rownames(est)))) }) colnames(tmp) <- find_model_names(loos) rnms <- rownames(tmp) ord <- order(tmp[grep("^elpd", rnms), ], decreasing = TRUE) ord } loo/R/tis.R0000644000176200001440000001242113701164066012172 0ustar liggesusers#' Truncated importance sampling (TIS) #' #' Implementation of truncated (self-normalized) importance sampling (TIS), #' truncated at S^(1/2) as recommended by Ionides (2008). #' #' @param log_ratios An array, matrix, or vector of importance ratios on the log #' scale (for Importance sampling LOO, these are *negative* log-likelihood #' values). See the **Methods (by class)** section below for a detailed #' description of how to specify the inputs for each method. #' @template cores #' @param ... Arguments passed on to the various methods. #' @param r_eff Vector of relative effective sample size estimates containing #' one element per observation. The values provided should be the relative #' effective sample sizes of `1/exp(log_ratios)` (i.e., `1/ratios`). #' This is related to the relative efficiency of estimating the normalizing #' term in self-normalizing importance sampling. See the [relative_eff()] #' helper function for computing `r_eff`. If using `psis` with #' draws of the `log_ratios` not obtained from MCMC then the warning #' message thrown when not specifying `r_eff` can be disabled by #' setting `r_eff` to `NA`. #' #' @return The `tis()` methods return an object of class `"tis"`, #' which is a named list with the following components: #' #' \describe{ #' \item{`log_weights`}{ #' Vector or matrix of smoothed (and truncated) but *unnormalized* log #' weights. To get normalized weights use the #' [`weights()`][weights.importance_sampling] method provided for objects of #' class `tis`. #' } #' \item{`diagnostics`}{ #' A named list containing one vector: #' * `pareto_k`: Not used in `tis`, all set to 0. #' * `n_eff`: Effective sample size estimates. #' } #' } #' #' Objects of class `"tis"` also have the following [attributes][attributes()]: #' \describe{ #' \item{`norm_const_log`}{ #' Vector of precomputed values of `colLogSumExps(log_weights)` that are #' used internally by the [weights()]method to normalize the log weights. #' } #' \item{`r_eff`}{ #' If specified, the user's `r_eff` argument. #' } #' \item{`tail_len`}{ #' Not used for `tis`. #' } #' \item{`dims`}{ #' Integer vector of length 2 containing `S` (posterior sample size) #' and `N` (number of observations). #' } #' \item{`method`}{ #' Method used for importance sampling, here `tis`. #' } #' } #' #' @seealso #' * [psis()] for approximate LOO-CV using PSIS. #' * [loo()] for approximate LOO-CV. #' * [pareto-k-diagnostic] for PSIS diagnostics. #' #' @references #' Ionides, Edward L. (2008). Truncated importance sampling. #' *Journal of Computational and Graphical Statistics* 17(2): 295--311. #' #' @examples #' log_ratios <- -1 * example_loglik_array() #' r_eff <- relative_eff(exp(-log_ratios)) #' tis_result <- tis(log_ratios, r_eff = r_eff) #' str(tis_result) #' #' # extract smoothed weights #' lw <- weights(tis_result) # default args are log=TRUE, normalize=TRUE #' ulw <- weights(tis_result, normalize=FALSE) # unnormalized log-weights #' #' w <- weights(tis_result, log=FALSE) # normalized weights (not log-weights) #' uw <- weights(tis_result, log=FALSE, normalize = FALSE) # unnormalized weights #' #' @export tis <- function(log_ratios, ...) UseMethod("tis") #' @export #' @templateVar fn tis #' @template array #' tis.array <- function(log_ratios, ..., r_eff = NULL, cores = getOption("mc.cores", 1)) { importance_sampling.array(log_ratios = log_ratios, ..., r_eff = r_eff, cores = cores, method = "tis") } #' @export #' @templateVar fn tis #' @template matrix #' tis.matrix <- function(log_ratios, ..., r_eff = NULL, cores = getOption("mc.cores", 1)) { importance_sampling.matrix(log_ratios, ..., r_eff = r_eff, cores = cores, method = "tis") } #' @export #' @templateVar fn tis #' @template vector #' tis.default <- function(log_ratios, ..., r_eff = NULL) { importance_sampling.default(log_ratios = log_ratios, ..., r_eff = r_eff, method = "tis") } #' @rdname psis #' @export is.tis <- function(x) { inherits(x, "tis") && is.list(x) } # internal ---------------------------------------------------------------- #' Truncated Importance Sampling on a single vector #' #' @noRd #' @param log_ratios_i A vector of log importance ratios (for `loo()`, negative #' log likelihoods). #' @param ... Not used. Included to conform to PSIS API. #' #' @details Implementation of Truncated importance sampling (TIS), a method for #' stabilizing importance ratios. The version of TIS implemented here #' corresponds to the algorithm presented in Ionides (2008) with truncation at #' sqrt(S). #' #' @return A named list containing: #' * `lw`: vector of unnormalized log weights #' * `pareto_k`: scalar Pareto k estimate. For 'tis', this defaults to 0. #' do_tis_i <- function(log_ratios_i, ...) { S <- length(log_ratios_i) log_Z <- logSumExp(log_ratios_i) - log(S) # Normalization term, c-hat in Ionides (2008) appendix log_cutpoint <- log_Z + 0.5 * log(S) lw_i <- pmin(log_ratios_i, log_cutpoint) list(log_weights = lw_i, pareto_k = 0) } loo/R/importance_sampling.R0000644000176200001440000001664013701164066015435 0ustar liggesusers#' A parent class for different importance sampling methods. #' @keywords internal #' @inheritParams psis #' @param method The importance sampling method to use. The following methods #' are implemented: #' * [`"psis"`][psis]: Pareto-Smoothed Importance Sampling (PSIS). Default method. #' * [`"tis"`][tis]: Truncated Importance Sampling (TIS) with truncation at #' `sqrt(S)`, where `S` is the number of posterior draws. #' * [`"sis"`][sis]: Standard Importance Sampling (SIS). #' importance_sampling <- function(log_ratios, method, ...) UseMethod("importance_sampling") #' @noRd #' @keywords internal #' @description #' Currently implemented importance sampling methods assert_importance_sampling_method_is_implemented <- function(x){ if (!x %in% implemented_is_methods()) { stop("Importance sampling method '", x, "' is not implemented. Implemented methods: '", paste0(implemented_is_methods, collapse = "', '"), "'") } } implemented_is_methods <- function() c("psis", "tis", "sis") #' Importance sampling of array #' @inheritParams psis #' @template is_method #' @keywords internal #' @export importance_sampling.array <- function(log_ratios, method, ..., r_eff = NULL, cores = getOption("mc.cores", 1)) { cores <- loo_cores(cores) stopifnot(length(dim(log_ratios)) == 3) assert_importance_sampling_method_is_implemented(method) log_ratios <- validate_ll(log_ratios) log_ratios <- llarray_to_matrix(log_ratios) r_eff <- prepare_psis_r_eff(r_eff, len = ncol(log_ratios)) do_importance_sampling(log_ratios, r_eff = r_eff, cores = cores, method = method) } #' Importance sampling of matrices #' @inheritParams psis #' @template is_method #' @keywords internal #' @export importance_sampling.matrix <- function(log_ratios, method, ..., r_eff = NULL, cores = getOption("mc.cores", 1)) { cores <- loo_cores(cores) assert_importance_sampling_method_is_implemented(method) log_ratios <- validate_ll(log_ratios) r_eff <- prepare_psis_r_eff(r_eff, len = ncol(log_ratios)) do_importance_sampling(log_ratios, r_eff = r_eff, cores = cores, method = method) } #' Importance sampling (default) #' @inheritParams psis #' @template is_method #' @keywords internal #' @export importance_sampling.default <- function(log_ratios, method, ..., r_eff = NULL) { stopifnot(is.null(dim(log_ratios)) || length(dim(log_ratios)) == 1) assert_importance_sampling_method_is_implemented(method) dim(log_ratios) <- c(length(log_ratios), 1) r_eff <- prepare_psis_r_eff(r_eff, len = 1) importance_sampling.matrix(log_ratios, r_eff = r_eff, cores = 1, method = method) } #' @export dim.importance_sampling <- function(x) { attr(x, "dims") } #' Extract importance sampling weights #' #' @export #' @export weights.importance_sampling #' @method weights importance_sampling #' @param object An object returned by [psis()], [tis()], or [sis()]. #' @param log Should the weights be returned on the log scale? Defaults to #' `TRUE`. #' @param normalize Should the weights be normalized? Defaults to `TRUE`. #' @param ... Ignored. #' #' @return The `weights()` method returns an object with the same dimensions as #' the `log_weights` component of `object`. The `normalize` and `log` #' arguments control whether the returned weights are normalized and whether #' or not to return them on the log scale. #' #' @examples #' # See the examples at help("psis") #' weights.importance_sampling <- function(object, ..., log = TRUE, normalize = TRUE) { out <- object[["log_weights"]] # smoothed but unnormalized log weights if (normalize) { out <- sweep(out, MARGIN = 2, STATS = attr(object, "norm_const_log"), # colLogSumExp(log_weights) check.margin = FALSE) } if (!log) { out <- exp(out) } return(out) } # internal ---------------------------------------------------------------- #' Structure the object returned by the importance_sampling methods #' #' @noRd #' @param unnormalized_log_weights Smoothed and possibly truncated log weights, #' but unnormalized. #' @param pareto_k Vector of GPD k estimates. #' @param tail_len Vector of tail lengths used to fit GPD. #' @param r_eff Vector of relative MCMC n_eff for `exp(log lik)` #' @template is_method #' @return A list of class `"psis"` with structure described in the main doc at #' the top of this file. #' importance_sampling_object <- function(unnormalized_log_weights, pareto_k, tail_len, r_eff, method) { stopifnot(is.matrix(unnormalized_log_weights)) methods <- unique(method) stopifnot(all(methods %in% implemented_is_methods())) if (length(methods) == 1) { method <- methods classes <- c(tolower(method), "importance_sampling", "list") } else { classes <- c("importance_sampling", "list") } norm_const_log <- matrixStats::colLogSumExps(unnormalized_log_weights) out <- structure( list( log_weights = unnormalized_log_weights, diagnostics = list(pareto_k = pareto_k, n_eff = NULL) ), # attributes norm_const_log = norm_const_log, tail_len = tail_len, r_eff = r_eff, dims = dim(unnormalized_log_weights), method = method, class = classes ) # need normalized weights (not on log scale) for psis_n_eff w <- weights(out, normalize = TRUE, log = FALSE) out$diagnostics[["n_eff"]] <- psis_n_eff(w, r_eff) return(out) } #' Do importance sampling given matrix of log weights #' #' @noRd #' @param lr Matrix of log ratios (`-loglik`) #' @param r_eff Vector of relative effective sample sizes #' @param cores User's integer `cores` argument #' @return A list with class `"psis"` and structure described in the main doc at #' the top of this file. #' do_importance_sampling <- function(log_ratios, r_eff, cores, method) { stopifnot(cores == as.integer(cores)) assert_importance_sampling_method_is_implemented(method) N <- ncol(log_ratios) S <- nrow(log_ratios) tail_len <- n_pareto(r_eff, S) if (method == "psis") { is_fun <- do_psis_i throw_tail_length_warnings(tail_len) } else if (method == "tis") { is_fun <- do_tis_i } else if (method == "sis") { is_fun <- do_sis_i } else { stop("Incorrect IS method.") } if (cores == 1) { lw_list <- lapply(seq_len(N), function(i) is_fun(log_ratios_i = log_ratios[, i], tail_len_i = tail_len[i])) } else { if (!os_is_windows()) { lw_list <- parallel::mclapply( X = seq_len(N), mc.cores = cores, FUN = function(i) is_fun(log_ratios_i = log_ratios[, i], tail_len_i = tail_len[i]) ) } else { cl <- parallel::makePSOCKcluster(cores) on.exit(parallel::stopCluster(cl)) lw_list <- parallel::parLapply( cl = cl, X = seq_len(N), fun = function(i) is_fun(log_ratios_i = log_ratios[, i], tail_len_i = tail_len[i]) ) } } log_weights <- psis_apply(lw_list, "log_weights", fun_val = numeric(S)) pareto_k <- psis_apply(lw_list, "pareto_k") throw_pareto_warnings(pareto_k) importance_sampling_object( unnormalized_log_weights = log_weights, pareto_k = pareto_k, tail_len = tail_len, r_eff = r_eff, method = rep(method, length(pareto_k)) # Conform to other attr that exist per obs. ) } loo/R/example_log_lik_array.R0000644000176200001440000000211013575772017015730 0ustar liggesusers#' Objects to use in examples and tests #' #' Example pointwise log-likelihood objects to use in demonstrations and tests. #' See the **Value** and **Examples** sections below. #' #' @export #' @return #' `example_loglik_array()` returns a 500 (draws) x 2 (chains) x 32 #' (observations) pointwise log-likelihood array. #' #' `example_loglik_matrix()` returns the same pointwise log-likelihood values #' as `example_loglik_array()` but reshaped into a 1000 (draws*chains) x 32 #' (observations) matrix. #' #' @examples #' LLarr <- example_loglik_array() #' (dim_arr <- dim(LLarr)) #' LLmat <- example_loglik_matrix() #' (dim_mat <- dim(LLmat)) #' #' all.equal(dim_mat[1], dim_arr[1] * dim_arr[2]) #' all.equal(dim_mat[2], dim_arr[3]) #' #' all.equal(LLarr[, 1, ], LLmat[1:500, ]) #' all.equal(LLarr[, 2, ], LLmat[501:1000, ]) #' example_loglik_array <- function() { # .example_loglik_array exists in R/sysdata.R return(.example_loglik_array) } #' @rdname example_loglik_array #' @export example_loglik_matrix <- function() { ll <- example_loglik_array() return(llarray_to_matrix(ll)) } loo/R/loo_model_weights.R0000644000176200001440000003567614410420140015101 0ustar liggesusers#' Model averaging/weighting via stacking or pseudo-BMA weighting #' #' Model averaging via stacking of predictive distributions, pseudo-BMA #' weighting or pseudo-BMA+ weighting with the Bayesian bootstrap. See Yao et #' al. (2018), Vehtari, Gelman, and Gabry (2017), and Vehtari, Simpson, #' Gelman, Yao, and Gabry (2019) for background. #' #' @export #' @param x A list of `"psis_loo"` objects (objects returned by [loo()]) or #' pointwise log-likelihood matrices or , one for each model. If the list #' elements are named the names will be used to label the models in the #' results. Each matrix/object should have dimensions \eqn{S} by \eqn{N}, #' where \eqn{S} is the size of the posterior sample (with all chains merged) #' and \eqn{N} is the number of data points. If `x` is a list of #' log-likelihood matrices then [loo()] is called internally on each matrix. #' Currently the `loo_model_weights()` function is not implemented to be used #' with results from K-fold CV, but you can still obtain weights using K-fold #' CV results by calling the `stacking_weights()` function directly. #' @param method Either `"stacking"` (the default) or `"pseudobma"`, indicating which method #' to use for obtaining the weights. `"stacking"` refers to stacking of #' predictive distributions and `"pseudobma"` refers to pseudo-BMA+ weighting #' (or plain pseudo-BMA weighting if argument `BB` is `FALSE`). #' @param BB Logical used when `"method"`=`"pseudobma"`. If #' `TRUE` (the default), the Bayesian bootstrap will be used to adjust #' the pseudo-BMA weighting, which is called pseudo-BMA+ weighting. It helps #' regularize the weight away from 0 and 1, so as to reduce the variance. #' @param BB_n For pseudo-BMA+ weighting only, the number of samples to use for #' the Bayesian bootstrap. The default is `BB_n=1000`. #' @param alpha Positive scalar shape parameter in the Dirichlet distribution #' used for the Bayesian bootstrap. The default is `alpha=1`, which #' corresponds to a uniform distribution on the simplex space. #' @param optim_method If `method="stacking"`, a string passed to the `method` #' argument of [stats::constrOptim()] to specify the optimization algorithm. #' The default is `optim_method="BFGS"`, but other options are available (see #' [stats::optim()]). #' @param optim_control If `method="stacking"`, a list of control parameters for #' optimization passed to the `control` argument of [stats::constrOptim()]. #' @param r_eff_list Optionally, a list of relative effective sample size #' estimates for the likelihood `(exp(log_lik))` of each observation in #' each model. See [psis()] and [relative_eff()] helper #' function for computing `r_eff`. If `x` is a list of `"psis_loo"` #' objects then `r_eff_list` is ignored. #' @template cores #' @param ... Unused, except for the generic to pass arguments to individual #' methods. #' #' @return A numeric vector containing one weight for each model. #' #' @details #' `loo_model_weights()` is a wrapper around the `stacking_weights()` and #' `pseudobma_weights()` functions that implements stacking, pseudo-BMA, and #' pseudo-BMA+ weighting for combining multiple predictive distributions. We can #' use approximate or exact leave-one-out cross-validation (LOO-CV) or K-fold CV #' to estimate the expected log predictive density (ELPD). #' #' The stacking method (`method="stacking"`), which is the default for #' `loo_model_weights()`, combines all models by maximizing the leave-one-out #' predictive density of the combination distribution. That is, it finds the #' optimal linear combining weights for maximizing the leave-one-out log score. #' #' The pseudo-BMA method (`method="pseudobma"`) finds the relative weights #' proportional to the ELPD of each model. However, when #' `method="pseudobma"`, the default is to also use the Bayesian bootstrap #' (`BB=TRUE`), which corresponds to the pseudo-BMA+ method. The Bayesian #' bootstrap takes into account the uncertainty of finite data points and #' regularizes the weights away from the extremes of 0 and 1. #' #' In general, we recommend stacking for averaging predictive distributions, #' while pseudo-BMA+ can serve as a computationally easier alternative. #' #' @seealso #' * The __loo__ package [vignettes](https://mc-stan.org/loo/articles/), particularly #' [Bayesian Stacking and Pseudo-BMA weights using the __loo__ package](https://mc-stan.org/loo/articles/loo2-weights.html). #' * [loo()] for details on leave-one-out ELPD estimation. #' * [constrOptim()] for the choice of optimization methods and control-parameters. #' * [relative_eff()] for computing `r_eff`. #' #' @template loo-and-psis-references #' @template stacking-references #' #' @examples #' \dontrun{ #' ### Demonstrating usage after fitting models with RStan #' library(rstan) #' #' # generate fake data from N(0,1). #' N <- 100 #' y <- rnorm(N, 0, 1) #' #' # Suppose we have three models: N(-1, sigma), N(0.5, sigma) and N(0.6,sigma). #' stan_code <- " #' data { #' int N; #' vector[N] y; #' real mu_fixed; #' } #' parameters { #' real sigma; #' } #' model { #' sigma ~ exponential(1); #' y ~ normal(mu_fixed, sigma); #' } #' generated quantities { #' vector[N] log_lik; #' for (n in 1:N) log_lik[n] = normal_lpdf(y[n]| mu_fixed, sigma); #' }" #' #' mod <- stan_model(model_code = stan_code) #' fit1 <- sampling(mod, data=list(N=N, y=y, mu_fixed=-1)) #' fit2 <- sampling(mod, data=list(N=N, y=y, mu_fixed=0.5)) #' fit3 <- sampling(mod, data=list(N=N, y=y, mu_fixed=0.6)) #' model_list <- list(fit1, fit2, fit3) #' log_lik_list <- lapply(model_list, extract_log_lik) #' #' # optional but recommended #' r_eff_list <- lapply(model_list, function(x) { #' ll_array <- extract_log_lik(x, merge_chains = FALSE) #' relative_eff(exp(ll_array)) #' }) #' #' # stacking method: #' wts1 <- loo_model_weights( #' log_lik_list, #' method = "stacking", #' r_eff_list = r_eff_list, #' optim_control = list(reltol=1e-10) #' ) #' print(wts1) #' #' # can also pass a list of psis_loo objects to avoid recomputing loo #' loo_list <- lapply(1:length(log_lik_list), function(j) { #' loo(log_lik_list[[j]], r_eff = r_eff_list[[j]]) #' }) #' #' wts2 <- loo_model_weights( #' loo_list, #' method = "stacking", #' optim_control = list(reltol=1e-10) #' ) #' all.equal(wts1, wts2) #' #' # can provide names to be used in the results #' loo_model_weights(setNames(loo_list, c("A", "B", "C"))) #' #' #' # pseudo-BMA+ method: #' set.seed(1414) #' loo_model_weights(loo_list, method = "pseudobma") #' #' # pseudo-BMA method (set BB = FALSE): #' loo_model_weights(loo_list, method = "pseudobma", BB = FALSE) #' #' # calling stacking_weights or pseudobma_weights directly #' lpd1 <- loo(log_lik_list[[1]], r_eff = r_eff_list[[1]])$pointwise[,1] #' lpd2 <- loo(log_lik_list[[2]], r_eff = r_eff_list[[2]])$pointwise[,1] #' lpd3 <- loo(log_lik_list[[3]], r_eff = r_eff_list[[3]])$pointwise[,1] #' stacking_weights(cbind(lpd1, lpd2, lpd3)) #' pseudobma_weights(cbind(lpd1, lpd2, lpd3)) #' pseudobma_weights(cbind(lpd1, lpd2, lpd3), BB = FALSE) #' } #' loo_model_weights <- function(x, ...) { UseMethod("loo_model_weights") } #' @rdname loo_model_weights #' @export #' @export loo_model_weights.default loo_model_weights.default <- function(x, ..., method = c("stacking", "pseudobma"), optim_method = "BFGS", optim_control = list(), BB = TRUE, BB_n = 1000, alpha = 1, r_eff_list = NULL, cores = getOption("mc.cores", 1)) { cores <- loo_cores(cores) method <- match.arg(method) K <- length(x) # number of models if (is.matrix(x[[1]])) { N <- ncol(x[[1]]) # number of data points validate_log_lik_list(x) validate_r_eff_list(r_eff_list, K, N) lpd_point <- matrix(NA, N, K) elpd_loo <- rep(NA, K) for (k in 1:K) { r_eff_k <- r_eff_list[[k]] # possibly NULL log_likelihood <- x[[k]] loo_object <- loo(log_likelihood, r_eff = r_eff_k, cores = cores) lpd_point[, k] <- loo_object$pointwise[, "elpd_loo"] #calculate log(p_k (y_i | y_-i)) elpd_loo[k] <- loo_object$estimates["elpd_loo", "Estimate"] } } else if (is.psis_loo(x[[1]])) { validate_psis_loo_list(x) lpd_point <- do.call(cbind, lapply(x, function(obj) obj$pointwise[, "elpd_loo"])) elpd_loo <- sapply(x, function(obj) obj$estimates["elpd_loo", "Estimate"]) } else { stop("'x' must be a list of matrices or a list of 'psis_loo' objects.") } ## 1) stacking on log score if (method =="stacking") { wts <- stacking_weights( lpd_point = lpd_point, optim_method = optim_method, optim_control = optim_control ) } else { # method =="pseudobma" wts <- pseudobma_weights( lpd_point = lpd_point, BB = BB, BB_n = BB_n, alpha = alpha ) } if (is.matrix(x[[1]])) { if (!is.null(names(x)) && all(nzchar(names(x)))) { wts <- setNames(wts, names(x)) } } else { # list of loo objects wts <- setNames(wts, find_model_names(x)) } wts } #' @rdname loo_model_weights #' @export #' @param lpd_point If calling `stacking_weights()` or `pseudobma_weights()` #' directly, a matrix of pointwise leave-one-out (or K-fold) log likelihoods #' evaluated for different models. It should be a \eqn{N} by \eqn{K} matrix #' where \eqn{N} is sample size and \eqn{K} is the number of models. Each #' column corresponds to one model. These values can be calculated #' approximately using [loo()] or by running exact leave-one-out or K-fold #' cross-validation. #' #' @importFrom stats constrOptim #' stacking_weights <- function(lpd_point, optim_method = "BFGS", optim_control = list()) { stopifnot(is.matrix(lpd_point)) N <- nrow(lpd_point) K <- ncol(lpd_point) if (K < 2) { stop("At least two models are required for stacking weights.") } exp_lpd_point <- exp(lpd_point) negative_log_score_loo <- function(w) { # objective function: log score stopifnot(length(w) == K - 1) w_full <- c(w, 1 - sum(w)) sum <- 0 for (i in 1:N) { sum <- sum + log(exp(lpd_point[i, ]) %*% w_full) } return(-as.numeric(sum)) } gradient <- function(w) { # gradient of the objective function stopifnot(length(w) == K - 1) w_full <- c(w, 1 - sum(w)) grad <- rep(0, K - 1) for (k in 1:(K - 1)) { for (i in 1:N) { grad[k] <- grad[k] + (exp_lpd_point[i, k] - exp_lpd_point[i, K]) / (exp_lpd_point[i,] %*% w_full) } } return(-grad) } ui <- rbind(rep(-1, K - 1), diag(K - 1)) # K-1 simplex constraint matrix ci <- c(-1, rep(0, K - 1)) w <- constrOptim( theta = rep(1 / K, K - 1), f = negative_log_score_loo, grad = gradient, ui = ui, ci = ci, method = optim_method, control = optim_control )$par wts <- structure( c(w, 1 - sum(w)), names = paste0("model", 1:K), class = c("stacking_weights") ) return(wts) } #' @rdname loo_model_weights #' @export #' pseudobma_weights <- function(lpd_point, BB = TRUE, BB_n = 1000, alpha = 1) { stopifnot(is.matrix(lpd_point)) N <- nrow(lpd_point) K <- ncol(lpd_point) if (K < 2) { stop("At least two models are required for pseudo-BMA weights.") } if (!BB) { elpd <- colSums2(lpd_point) uwts <- exp(elpd - max(elpd)) wts <- structure( uwts / sum(uwts), names = paste0("model", 1:K), class = "pseudobma_weights" ) return(wts) } temp <- matrix(NA, BB_n, K) BB_weighting <- dirichlet_rng(BB_n, rep(alpha, N)) for (bb in 1:BB_n) { z_bb <- BB_weighting[bb, ] %*% lpd_point * N uwts <- exp(z_bb - max(z_bb)) temp[bb, ] <- uwts / sum(uwts) } wts <- structure( colMeans(temp), names = paste0("model", 1:K), class = "pseudobma_bb_weights" ) return(wts) } #' Generate dirichlet simulations, rewritten version #' @importFrom stats rgamma #' @noRd dirichlet_rng <- function(n, alpha) { K <- length(alpha) gamma_sim <- matrix(rgamma(K * n, alpha), ncol = K, byrow = TRUE) gamma_sim / rowSums(gamma_sim) } #' @export print.stacking_weights <- function(x, digits = 3, ...) { cat("Method: stacking\n------\n") print_weight_vector(x, digits = digits) } #' @export print.pseudobma_weights <- function(x, digits = 3, ...) { cat("Method: pseudo-BMA\n------\n") print_weight_vector(x, digits = digits) } #' @export print.pseudobma_bb_weights <- function(x, digits = 3, ...) { cat("Method: pseudo-BMA+ with Bayesian bootstrap\n------\n") print_weight_vector(x, digits = digits) } print_weight_vector <- function(x, digits) { z <- cbind(x) colnames(z) <- "weight" print(.fr(z, digits = digits), quote = FALSE) invisible(x) } #' Validate r_eff_list argument if provided #' #' @noRd #' @param r_eff_list User's `r_eff_list` argument #' @param K Required length of `r_eff_list` (number of models). #' @param N Required length of each element of `r_eff_list` (number of data points). #' @return Either throws an error or returns `TRUE` invisibly. #' validate_r_eff_list <- function(r_eff_list, K, N) { if (is.null(r_eff_list)) return(invisible(TRUE)) if (length(r_eff_list) != K) { stop("If r_eff_list is specified then it must contain ", "one component for each model being compared.", call. = FALSE) } if (any(sapply(r_eff_list, length) != N)) { stop("Each component of r_eff list must have the same length ", "as the number of columns in the log-likelihood matrix.", call. = FALSE) } invisible(TRUE) } #' Validate log-likelihood list argument #' #' Checks that log-likelihood list has at least 2 elements and that each element #' has the same dimensions. #' #' @noRd #' @param log_lik_list User's list of log-likelihood matrices (the `x` argument #' to loo_model_weights). #' @return Either throws an error or returns `TRUE` invisibly. #' validate_log_lik_list <- function(log_lik_list) { stopifnot(is.list(log_lik_list)) if (length(log_lik_list) < 2) { stop("At least two models are required.", call. = FALSE) } if (length(unique(sapply(log_lik_list, ncol))) != 1 | length(unique(sapply(log_lik_list, nrow))) != 1) { stop("Each log-likelihood matrix must have the same dimensions.", call. = FALSE) } invisible(TRUE) } validate_psis_loo_list <- function(psis_loo_list) { stopifnot(is.list(psis_loo_list)) if (length(psis_loo_list) < 2) { stop("At least two models are required.", call. = FALSE) } if (!all(sapply(psis_loo_list, is.psis_loo))) { stop("List elements must all be 'psis_loo' objects or log-likelihood matrices.") } dims <- sapply(psis_loo_list, dim) if (length(unique(dims[1, ])) != 1 | length(unique(dims[2, ])) != 1) { stop("Each object in the list must have the same dimensions.", call. = FALSE) } invisible(TRUE) } loo/R/kfold-generic.R0000644000176200001440000000316213575772017014120 0ustar liggesusers#' Generic function for K-fold cross-validation for developers #' #' @description For developers of Bayesian modeling packages, **loo** includes #' a generic function `kfold()` so that methods may be defined for K-fold #' CV without name conflicts between packages. See, for example, the #' `kfold()` methods in the **rstanarm** and **brms** packages. #' #' The **Value** section below describes the objects that `kfold()` #' methods should return in order to be compatible with #' [loo_compare()] and the **loo** package print methods. #' #' #' @name kfold-generic #' @param x A fitted model object. #' @param ... Arguments to pass to specific methods. #' #' @return For developers defining a `kfold()` method for a class #' `"foo"`, the `kfold.foo()` function should return a list with class #' `c("kfold", "loo")` with at least the following named elements: #' * `"estimates"`: A `1x2` matrix containing the ELPD estimate and its #' standard error. The matrix must have row name "`elpd_kfold`" and column #' names `"Estimate"` and `"SE"`. #' * `"pointwise"`: A `Nx1` matrix with column name `"elpd_kfold"` containing #' the pointwise contributions for each data point. #' #' It is important for the object to have at least these classes and #' components so that it is compatible with other functions like #' [loo_compare()] and `print()` methods. #' NULL #' @rdname kfold-generic #' @export kfold <- function(x, ...) { UseMethod("kfold") } #' @rdname kfold-generic #' @export is.kfold <- function(x) { inherits(x, "kfold") && is.loo(x) } #' @export dim.kfold <- function(x) { attr(x, "dims") } loo/R/compare.R0000644000176200001440000001220613701164066013022 0ustar liggesusers#' Model comparison (deprecated, old version) #' #' **This function is deprecated**. Please use the new [loo_compare()] function #' instead. #' #' @export #' @param ... At least two objects returned by [loo()] (or [waic()]). #' @param x A list of at least two objects returned by [loo()] (or #' [waic()]). This argument can be used as an alternative to #' specifying the objects in `...`. #' #' @return A vector or matrix with class `'compare.loo'` that has its own #' print method. If exactly two objects are provided in `...` or #' `x`, then the difference in expected predictive accuracy and the #' standard error of the difference are returned. If more than two objects are #' provided then a matrix of summary information is returned (see **Details**). #' #' @details #' When comparing two fitted models, we can estimate the difference in their #' expected predictive accuracy by the difference in `elpd_loo` or #' `elpd_waic` (or multiplied by -2, if desired, to be on the #' deviance scale). #' #' *When that difference, `elpd_diff`, is positive then the expected #' predictive accuracy for the second model is higher. A negative #' `elpd_diff` favors the first model.* #' #' When using `compare()` with more than two models, the values in the #' `elpd_diff` and `se_diff` columns of the returned matrix are #' computed by making pairwise comparisons between each model and the model #' with the best ELPD (i.e., the model in the first row). #' Although the `elpd_diff` column is equal to the difference in #' `elpd_loo`, do not expect the `se_diff` column to be equal to the #' the difference in `se_elpd_loo`. #' #' To compute the standard error of the difference in ELPD we use a #' paired estimate to take advantage of the fact that the same set of _N_ #' data points was used to fit both models. These calculations should be most #' useful when _N_ is large, because then non-normality of the #' distribution is not such an issue when estimating the uncertainty in these #' sums. These standard errors, for all their flaws, should give a better #' sense of uncertainty than what is obtained using the current standard #' approach of comparing differences of deviances to a Chi-squared #' distribution, a practice derived for Gaussian linear models or #' asymptotically, and which only applies to nested models in any case. #' #' @template loo-and-psis-references #' #' @examples #' \dontrun{ #' loo1 <- loo(log_lik1) #' loo2 <- loo(log_lik2) #' print(compare(loo1, loo2), digits = 3) #' print(compare(x = list(loo1, loo2))) #' #' waic1 <- waic(log_lik1) #' waic2 <- waic(log_lik2) #' compare(waic1, waic2) #' } #' compare <- function(..., x = list()) { .Deprecated("loo_compare") dots <- list(...) if (length(dots)) { if (length(x)) { stop("If 'x' is specified then '...' should not be specified.", call. = FALSE) } nms <- as.character(match.call(expand.dots = TRUE))[-1L] } else { if (!is.list(x) || !length(x)) { stop("'x' must be a list.", call. = FALSE) } dots <- x nms <- names(dots) if (!length(nms)) { nms <- paste0("model", seq_along(dots)) } } if (!all(sapply(dots, is.loo))) { stop("All inputs should have class 'loo'.") } if (length(dots) <= 1L) { stop("'compare' requires at least two models.") } else if (length(dots) == 2L) { loo1 <- dots[[1]] loo2 <- dots[[2]] comp <- compare_two_models(loo1, loo2) class(comp) <- c(class(comp), "old_compare.loo") return(comp) } else { Ns <- sapply(dots, function(x) nrow(x$pointwise)) if (!all(Ns == Ns[1L])) { stop("Not all models have the same number of data points.", call. = FALSE) } x <- sapply(dots, function(x) { est <- x$estimates setNames(c(est), nm = c(rownames(est), paste0("se_", rownames(est))) ) }) colnames(x) <- nms rnms <- rownames(x) comp <- x ord <- order(x[grep("^elpd", rnms), ], decreasing = TRUE) comp <- t(comp)[ord, ] patts <- c("elpd", "p_", "^waic$|^looic$", "^se_waic$|^se_looic$") col_ord <- unlist(sapply(patts, function(p) grep(p, colnames(comp))), use.names = FALSE) comp <- comp[, col_ord] # compute elpd_diff and se_elpd_diff relative to best model rnms <- rownames(comp) diffs <- mapply(elpd_diffs, dots[ord[1]], dots[ord]) elpd_diff <- apply(diffs, 2, sum) se_diff <- apply(diffs, 2, se_elpd_diff) comp <- cbind(elpd_diff = elpd_diff, se_diff = se_diff, comp) rownames(comp) <- rnms class(comp) <- c("compare.loo", class(comp), "old_compare.loo") comp } } # internal ---------------------------------------------------------------- compare_two_models <- function(loo_a, loo_b, return = c("elpd_diff", "se"), check_dims = TRUE) { if (check_dims) { if (dim(loo_a$pointwise)[1] != dim(loo_b$pointwise)[1]) { stop(paste("Models don't have the same number of data points.", "\nFound N_1 =", dim(loo_a$pointwise)[1], "and N_2 =", dim(loo_b$pointwise)[1]), call. = FALSE) } } diffs <- elpd_diffs(loo_a, loo_b) comp <- c(elpd_diff = sum(diffs), se = se_elpd_diff(diffs)) structure(comp, class = "compare.loo") } loo/R/elpd.R0000644000176200001440000000374213762013700012320 0ustar liggesusers#' Generic (expected) log-predictive density #' #' The `elpd()` methods for arrays and matrices can compute the expected log #' pointwise predictive density for a new dataset or the log pointwise #' predictive density of the observed data (an overestimate of the elpd). #' #' @export #' @param x A log-likelihood array or matrix. The **Methods (by class)** #' section, below, has detailed descriptions of how to specify the inputs for #' each method. #' @param ... Currently ignored. #' #' @details The `elpd()` function is an S3 generic and methods are provided for #' 3-D pointwise log-likelihood arrays and matrices. #' #' @seealso The vignette *Holdout validation and K-fold cross-validation of Stan #' programs with the loo package* for demonstrations of using the `elpd()` #' methods. #' #' @examples #' # Calculate the lpd of the observed data #' LLarr <- example_loglik_array() #' elpd(LLarr) #' elpd <- function(x, ...) { UseMethod("elpd") } #' @export #' @templateVar fn elpd #' @template array #' elpd.array <- function(x, ...) { ll <- llarray_to_matrix(x) elpd.matrix(ll) } #' @export #' @templateVar fn elpd #' @template matrix #' elpd.matrix <- function(x, ...) { pointwise <- pointwise_elpd_calcs(x) elpd_object(pointwise, dim(x)) } # internal ---------------------------------------------------------------- pointwise_elpd_calcs <- function(ll){ elpd <- colLogSumExps(ll) - log(nrow(ll)) ic <- -2 * elpd cbind(elpd, ic) } elpd_object <- function(pointwise, dims) { if (!is.matrix(pointwise)) stop("Internal error ('pointwise' must be a matrix)") cols_to_summarize <- colnames(pointwise) estimates <- table_of_estimates(pointwise[, cols_to_summarize, drop=FALSE]) out <- nlist(estimates, pointwise) structure( out, dims = dims, class = c("elpd_generic", "loo") ) } print_dims.elpd_generic <- function(x, ...) { cat( "Computed from", paste(dim(x), collapse = " by "), "log-likelihood matrix using the generic elpd function\n" ) } loo/R/psislw.R0000644000176200001440000001400013575772017012721 0ustar liggesusers#' Pareto smoothed importance sampling (deprecated, old version) #' #' As of version `2.0.0` this function is **deprecated**. Please use the #' [psis()] function for the new PSIS algorithm. #' #' @export #' @param lw A matrix or vector of log weights. For computing LOO, `lw = #' -log_lik`, the *negative* of an \eqn{S} (simulations) by \eqn{N} (data #' points) pointwise log-likelihood matrix. #' @param wcp The proportion of importance weights to use for the generalized #' Pareto fit. The `100*wcp`\% largest weights are used as the sample #' from which to estimate the parameters of the generalized Pareto #' distribution. #' @param wtrunc For truncating very large weights to \eqn{S}^`wtrunc`. Set #' to zero for no truncation. #' @param cores The number of cores to use for parallelization. This defaults to #' the option `mc.cores` which can be set for an entire R session by #' `options(mc.cores = NUMBER)`, the old option `loo.cores` is now #' deprecated but will be given precedence over `mc.cores` until it is #' removed. **As of version 2.0.0, the default is now 1 core if #' `mc.cores` is not set, but we recommend using as many (or close to as #' many) cores as possible.** #' @param llfun,llargs See [loo.function()]. #' @param ... Ignored when `psislw()` is called directly. The `...` is #' only used internally when `psislw()` is called by the [loo()] #' function. #' #' @return A named list with components `lw_smooth` (modified log weights) and #' `pareto_k` (estimated generalized Pareto shape parameter(s) k). #' #' @seealso [pareto-k-diagnostic] for PSIS diagnostics. #' #' @template loo-and-psis-references #' #' @importFrom parallel mclapply makePSOCKcluster stopCluster parLapply #' psislw <- function(lw, wcp = 0.2, wtrunc = 3/4, cores = getOption("mc.cores", 1), llfun = NULL, llargs = NULL, ...) { .Deprecated("psis") cores <- loo_cores(cores) .psis <- function(lw_i) { x <- lw_i - max(lw_i) cutoff <- lw_cutpoint(x, wcp, MIN_CUTOFF) above_cut <- x > cutoff x_body <- x[!above_cut] x_tail <- x[above_cut] tail_len <- length(x_tail) if (tail_len < MIN_TAIL_LENGTH || all(x_tail == x_tail[1])) { if (all(x_tail == x_tail[1])) warning( "All tail values are the same. ", "Weights are truncated but not smoothed.", call. = FALSE ) else if (tail_len < MIN_TAIL_LENGTH) warning( "Too few tail samples to fit generalized Pareto distribution.\n", "Weights are truncated but not smoothed.", call. = FALSE ) x_new <- x k <- Inf } else { # store order of tail samples, fit gPd to the right tail samples, compute # order statistics for the fit, remap back to the original order, join # body and gPd smoothed tail tail_ord <- order(x_tail) exp_cutoff <- exp(cutoff) fit <- gpdfit(exp(x_tail) - exp_cutoff, wip=FALSE, min_grid_pts = 80) k <- fit$k sigma <- fit$sigma prb <- (seq_len(tail_len) - 0.5) / tail_len qq <- qgpd(prb, k, sigma) + exp_cutoff smoothed_tail <- rep.int(0, tail_len) smoothed_tail[tail_ord] <- log(qq) x_new <- x x_new[!above_cut] <- x_body x_new[above_cut] <- smoothed_tail } # truncate (if wtrunc > 0) and renormalize, # return log weights and pareto k lw_new <- lw_normalize(lw_truncate(x_new, wtrunc)) nlist(lw_new, k) } .psis_loop <- function(i) { if (LL_FUN) { ll_i <- llfun(i = i, data = llargs$data[i,, drop=FALSE], draws = llargs$draws) lw_i <- -1 * ll_i } else { lw_i <- lw[, i] ll_i <- -1 * lw_i } psis <- .psis(lw_i) if (FROM_LOO) nlist(lse = logSumExp(ll_i + psis$lw_new), k = psis$k) else psis } # minimal cutoff value. there must be at least 5 log-weights larger than this # in order to fit the gPd to the tail MIN_CUTOFF <- -700 MIN_TAIL_LENGTH <- 5 dots <- list(...) FROM_LOO <- if ("COMPUTE_LOOS" %in% names(dots)) dots$COMPUTE_LOOS else FALSE if (!missing(lw)) { if (!is.matrix(lw)) lw <- as.matrix(lw) N <- ncol(lw) LL_FUN <- FALSE } else { if (is.null(llfun) || is.null(llargs)) stop("Either 'lw' or 'llfun' and 'llargs' must be specified.") N <- llargs$N LL_FUN <- TRUE } if (cores == 1) { # don't call functions from parallel package if cores=1 out <- lapply(X = 1:N, FUN = .psis_loop) } else { # parallelize if (.Platform$OS.type != "windows") { out <- mclapply(X = 1:N, FUN = .psis_loop, mc.cores = cores) } else { # nocov start cl <- makePSOCKcluster(cores) on.exit(stopCluster(cl)) out <- parLapply(cl, X = 1:N, fun = .psis_loop) # nocov end } } pareto_k <- vapply(out, "[[", 2L, FUN.VALUE = numeric(1)) psislw_warnings(pareto_k) if (FROM_LOO) { loos <- vapply(out, "[[", 1L, FUN.VALUE = numeric(1)) nlist(loos, pareto_k) } else { funval <- if (LL_FUN) llargs$S else nrow(lw) lw_smooth <- vapply(out, "[[", 1L, FUN.VALUE = numeric(funval)) out <- nlist(lw_smooth, pareto_k) class(out) <- c("psis", "list") return(out) } } # internal ---------------------------------------------------------------- lw_cutpoint <- function(y, wcp, min_cut) { if (min_cut < log(.Machine$double.xmin)) min_cut <- -700 cp <- quantile(y, 1 - wcp, names = FALSE) max(cp, min_cut) } lw_truncate <- function(y, wtrunc) { if (wtrunc == 0) return(y) logS <- log(length(y)) lwtrunc <- wtrunc * logS - logS + logSumExp(y) y[y > lwtrunc] <- lwtrunc y } lw_normalize <- function(y) { y - logSumExp(y) } # warnings about pareto k values ------------------------------------------ psislw_warnings <- function(k) { if (any(k > 0.7)) { .warn( "Some Pareto k diagnostic values are too high. ", .k_help() ) } else if (any(k > 0.5)) { .warn( "Some Pareto k diagnostic values are slightly high. ", .k_help() ) } } loo/R/datasets.R0000644000176200001440000000330314407123455013203 0ustar liggesusers#' Datasets for loo examples and vignettes #' #' Small datasets for use in **loo** examples and vignettes. The `Kline` #' and `milk` datasets are also included in the **rethinking** package #' (McElreath, 2016a), but we include them here as **rethinking** is not #' on CRAN. #' #' @name loo-datasets #' @aliases Kline milk voice voice_loo #' #' @details #' Currently the data sets included are: #' * `Kline`: #' Small dataset from Kline and Boyd (2010) on tool complexity and demography #' in Oceanic islands societies. This data is discussed in detail in #' McElreath (2016a,2016b). [(Link to variable descriptions)](https://www.rdocumentation.org/packages/rethinking/versions/1.59/topics/Kline) #' * `milk`: #' Small dataset from Hinde and Milligan (2011) on primate milk #' composition.This data is discussed in detail in McElreath (2016a,2016b). #' [(Link to variable descriptions)](https://www.rdocumentation.org/packages/rethinking/versions/1.59/topics/milk) #' * `voice`: #' Voice rehabilitation data from Tsanas et al. (2014). #' @references #' Hinde and Milligan. 2011. *Evolutionary Anthropology* 20:9-23. #' #' Kline, M.A. and R. Boyd. 2010. *Proc R Soc B* 277:2559-2564. #' #' McElreath, R. (2016a). rethinking: Statistical Rethinking book package. #' R package version 1.59. #' #' McElreath, R. (2016b). *Statistical rethinking: A Bayesian course with #' examples in R and Stan*. Chapman & Hall/CRC. #' #' A. Tsanas, M.A. Little, C. Fox, L.O. Ramig: Objective automatic assessment of #' rehabilitative speech treatment in Parkinson's disease, IEEE #' Transactions on Neural Systems and Rehabilitation Engineering, Vol. 22, pp. #' 181-190, January 2014 #' #' @examples #' str(Kline) #' str(milk) #' NULL loo/NEWS.md0000644000176200001440000002427214411130104012135 0ustar liggesusers# loo 2.6.0 ### New features * New `loo_predictive_metric()` function for computing estimates of leave-one-out predictive metrics: mean absolute error, mean squared error and root mean squared error for continuous predictions, and accuracy and balanced accuracy for binary classification. (#202, @LeeviLindgren) * New functions `crps()`, `scrps()`, `loo_crps()`, and `loo_scrps()` for computing the (scaled) continuously ranked probability score. (#203, @LeeviLindgren) * New vignette "Mixture IS leave-one-out cross-validation for high-dimensional Bayesian models." This is a demonstration of the mixture estimators proposed by [Silva and Zanella (2022)](https://arxiv.org/abs/2209.09190). (#210) ### Bug fixes * Minor fix to model names displayed by `loo_model_weights()` to make them consistent with `loo_compare()`. (#217) # loo 2.5.1 * Fix R CMD check error on M1 Mac # loo 2.5.0 ### Improvements * New [Frequently Asked Questions page](https://mc-stan.org/loo/articles/online-only/faq.html) on the package website. (#143) * Speed improvement from simplifying the normalization when fitting the generalized Pareto distribution. (#187, @sethaxen) * Added parallel likelihood computation to speedup `loo_subsample()` when using posterior approximations. (#171, @kdubovikov) * Switch unit tests from Travis to GitHub Actions. (#164) ### Bug fixes * Fixed a bug causing the normalizing constant of the PSIS (log) weights not to get updated when performing moment matching with `save_psis = TRUE` (#166, @fweber144). # loo 2.4.1 * Fixed issue reported by CRAN where one of the vignettes errored on an M1 Mac due to RStan's dependency on V8. # loo 2.4.0 ### Bug fixes * Fixed a bug in `relative_eff.function()` that caused an error on Windows when using multiple cores. (#152) * Fixed a potential numerical issue in `loo_moment_match()` with `split=TRUE`. (#153) * Fixed potential integer overflow with `loo_moment_match()`. (#155, @ecmerkle) * Fixed `relative_eff()` when used with a `posterior::draws_array`. (#161, @rok-cesnovar) ### New features * New generic function `elpd()` (and methods for matrices and arrays) for computing expected log predictive density of new data or log predictive density of observed data. A new vignette demonstrates using this function when doing K-fold CV with rstan. (#159, @bnicenboim) # loo 2.3.1 * Fixed a bug in `loo_moment_match()` that prevented `...` arguments from being used correctly. (#149) # loo 2.3.0 * Added Topi Paananen and Paul Bürkner as coauthors. * New function `loo_moment_match()` (and new vignette), which can be used to update a `loo` object when Pareto k estimates are large. (#130) * The log weights provided by the importance sampling functions `psis()`, `tis()`, and `sis()` no longer have the largest log ratio subtracted from them when returned to the user. This should be less confusing for anyone using the `weights()` method to make an importance sampler. (#112, #146) * MCSE calculation is now deterministic (#116, #147) # loo 2.2.0 * Added Mans Magnusson as a coauthor. * New functions `loo_subsample()` and `loo_approximate_posterior()` (and new vignette) for doing PSIS-LOO with large data. (#113) * Added support for standard importance sampling and truncated importance sampling (functions `sis()` and `tis()`). (#125) * `compare()` now throws a deprecation warning suggesting `loo_compare()`. (#93) * A smaller threshold is used when checking the uniqueness of tail values. (#124) * For WAIC, warnings are only thrown when running `waic()` and not when printing a `waic` object. (#117, @mcol) * Use markdown syntax in roxygen documentation wherever possible. (#108) # loo 2.1.0 * New function `loo_compare()` for model comparison that will eventually replace the existing `compare()` function. (#93) * New vignette on LOO for non-factorizable joint Gaussian models. (#75) * New vignette on "leave-future-out" cross-validation for time series models. (#90) * New glossary page (use `help("loo-glossary")`) with definitions of key terms. (#81) * New `se_diff` column in model comparison results. (#78) * Improved stability of `psis()` when `log_ratios` are very small. (#74) * Allow `r_eff=NA` to suppress warning when specifying `r_eff` is not applicable (i.e., draws not from MCMC). (#72) * Update effective sample size calculations to match RStan's version. (#85) * Naming of k-fold helper functions now matches scikit-learn. (#96) # loo 2.0.0 This is a major release with many changes. Whenever possible we have opted to deprecate rather than remove old functionality, but it is possible that old code that accesses elements inside loo objects by position rather than name may error. * New package documentation website http://mc-stan.org/loo/ with vignettes, function reference, news. * Updated existing vignette and added two new vignettes demonstrating how to use the package. * New function `psis()` replaces `psislw()` (now deprecated). This version implements the improvements to the PSIS algorithm described in the latest version of https://arxiv.org/abs/1507.02646. Additional diagnostic information is now also provided, including PSIS effective sample sizes. * New `weights()` method for extracting smoothed weights from a `psis` object. Arguments `log` and `normalize` control whether the weights are returned on the log scale and whether they are normalized. * Updated the interface for the `loo()` methods to integrate nicely with the new PSIS algorithm. Methods for log-likelihood arrays, matrices, and functions are provided. Several arguments have changed, particularly for the `loo.function` method. The documentation at `help("loo")` has been updated to describe the new behavior. * The structure of the objects returned by the `loo()` function has also changed slightly, as described in the __Value__ section at `help("loo", package = "loo")`. * New function `loo_model_weights()` computes weights for model averaging as described in https://arxiv.org/abs/1704.02030. Implemented methods include stacking of predictive distributions, pseudo-BMA weighting or pseudo-BMA+ weighting with the Bayesian bootstrap. * Setting `options(loo.cores=...)` is now deprecated in favor of `options(mc.cores=...)`. For now, if both the `loo.cores` and `mc.cores` options have been set, preference will be given to `loo.cores` until it is removed in a future release. (thanks to @cfhammill) * New functions `example_loglik_array()` and `example_loglik_matrix()` that provide objects to use in examples and tests. * When comparing more than two models with `compare()`, the first column of the output is now the `elpd` difference from the model in the first row. * New helper functions for splitting observations for K-fold CV: `kfold_split_random()`, `kfold_split_balanced()`, `kfold_split_stratified()`. Additional helper functions for implementing K-fold CV will be included in future releases. # loo 1.1.0 * Introduce the `E_loo()` function for computing weighted expectations (means, variances, quantiles). # loo 1.0.0 * `pareto_k_table()` and `pareto_k_ids()` convenience functions for quickly identifying problematic observations * pareto k values now grouped into `(-Inf, 0.5]`, `(0.5, 0.7]`, `(0.7, 1]`, `(1, Inf)` (didn't used to include 0.7) * warning messages are now issued by `psislw()` instead of `print.loo` * `print.loo()` shows a table of pareto k estimates (if any k > 0.7) * Add argument to `compare()` to allow loo objects to be provided in a list rather than in `'...'` * Update references to point to published paper # loo 0.1.6 * GitHub repository moved from @jgabry to @stan-dev * Better error messages from `extract_log_lik()` * Fix example code in vignette (thanks to GitHub user @krz) # loo 0.1.5 * Add warnings if any p_waic estimates are greather than 0.4 * Improve line coverage of tests to 100% * Update references in documentation * Remove model weights from `compare()`. In previous versions of __loo__ model weights were also reported by `compare()`. We have removed the weights because they were based only on the point estimate of the elpd values ignoring the uncertainty. We are currently working on something similar to these weights that also accounts for uncertainty, which will be included in future versions of __loo__. # loo 0.1.4 This update makes it easier for other package authors using __loo__ to write tests that involve running the `loo` function. It also includes minor bug fixes and additional unit tests. Highlights: * Don't call functions from __parallel__ package if `cores=1`. * Return entire vector/matrix of smoothed weights rather than a summary statistic when `psislw` function is called in an interactive session. * Test coverage > 80% # loo 0.1.3 This update provides several important improvements, most notably an alternative method for specifying the pointwise log-likelihood that reduces memory usage and allows for __loo__ to be used with larger datasets. This update also makes it easier to to incorporate __loo__'s functionality into other packages. * Add Ben Goodrich as contributor * S3 generics and `matrix` and `function` methods for both `loo()` and `waic()`. The matrix method provide the same functionality as in previous versions of __loo__ (taking a log-likelihood matrix as the input). The function method allows the user to provide a function for computing the log-likelihood from the data and posterior draws (which are also provided by the user). The function method is less memory intensive and should make it possible to use __loo__ for models fit to larger amounts of data than before. * Separate `plot` and `print` methods. `plot` also provides `label_points` argument, which, if `TRUE`, will label any Pareto `k` points greater than 1/2 by the index number of the corresponding observation. The plot method also now warns about `Inf`/`NA`/`NaN` values of `k` that are not shown in the plot. * `compare` now returns model weights and accepts more than two inputs. * Allow setting number of cores using `options(loo.cores = NUMBER)`. # loo 0.1.2 * Updates names in package to reflect name changes in the accompanying paper. # loo 0.1.1 * Better handling of special cases * Deprecates `loo_and_waic` function in favor of separate functions `loo` and `waic` * Deprecates `loo_and_waic_diff`. Use `compare` instead. # loo 0.1.0 * Initial release loo/MD50000644000176200001440000003154714411522703011364 0ustar liggesusersa7f00c91f8a69c634832ca9a9d41bd98 *DESCRIPTION 3d09bf8ab720bd447afad42396fba599 *NAMESPACE 364c2e94f87f3976ff84118c7320c25a *NEWS.md bb43358a53dd32048dc3d3f0450177e0 *R/E_loo.R 592618e122c9a1a57e2ebb85421722a9 *R/compare.R a6c6b91b9d6902b02e16f2f44bda7166 *R/crps.R 7920e0c85842613222bf4d46b2ee4f71 *R/datasets.R bc2d2c45abd4736f9ae79d66de4625d8 *R/diagnostics.R f1e74ac071395133363ec02928bb0e7c *R/effective_sample_sizes.R 41da1f940ee2e03dd866f232137e0ca9 *R/elpd.R 794e76e90c0ceb3a68d3727c434c0d07 *R/example_log_lik_array.R 22c4f73fa34dca703e6ac54a7419714d *R/extract_log_lik.R 80f5d9b91376d5d14aecd877f58db7ac *R/gpdfit.R 0d726f538c88bed2175ba55e299faeae *R/helpers.R 56c3138e088e4f9c7cc4c0a44971f293 *R/importance_sampling.R 97fac5bdafff56c4e5b157e43104b86f *R/kfold-generic.R c0fdfd15d9c63df25516682b82d64ef2 *R/kfold-helpers.R 39dc8eccf5e776b40e6f926ff7ccea29 *R/loo-glossary.R c37281b9efaca240d025d2bc55f588fd *R/loo-package.R e268e2e7d545573fa4d92ec27413102f *R/loo.R 62d0535732f69406df1660a21f7f8998 *R/loo_approximate_posterior.R f1f1ee9d71dc7135cf3bf3340bd03a46 *R/loo_compare.R 02501a71e1c5ef6967a98973f499d5b7 *R/loo_compare.psis_loo_ss_list.R be562d0196ee83b648d9b0252f4e5744 *R/loo_model_weights.R 911e11b5c45f0f3a5a7a87913986101d *R/loo_moment_matching.R aeac6a3b56968135cb28c73bae6a4d9e *R/loo_predictive_metric.R 31ab05451ee5055bb9227aa29c431a2c *R/loo_subsample.R e2f1783d39e54243427b1f3d865de048 *R/print.R face2b941d3d7c24242b164be59e9931 *R/psis.R 6c1079d027e6570eb0faee678d550084 *R/psis_approximate_posterior.R 79d12f0591f709c55310c01880567c7c *R/psislw.R f1f6ad737d526846f6783256a9527187 *R/sis.R af419f5a74833d7629d446294360913e *R/split_moment_matching.R 78e03b9540b613c9c96fd50b224bfb4e *R/sysdata.rda fc814360eac5acf1ed5be1df9145e1c0 *R/tis.R 4203a69e9e2e400a17cd3a7cd80f2152 *R/waic.R 2a68648a24c53052290859807ec13c30 *R/zzz.R ea124a494ad7922985532ad3b308e4d5 *build/partial.rdb 28583a9b0a90549c5cf91dafdd5ea020 *build/vignette.rds 50fc728beb18fe44e15ba70bff59513a *data/Kline.rda 05b97c90b223a661715a584b35efc3a5 *data/milk.rda 1b4b29f3be934b8ab7259b87e50e62be *data/voice.rda 15b58967ca7adeefbcb9de5c15795cd9 *data/voice_loo.rda 0fb8e9a3c26882bccfbfe84b3f3cc89d *inst/CITATION 6ae819e444e214ed87efc38b508f2313 *inst/doc/loo2-elpd.R ff337ea126a5537ded0dc4598e5cb1e0 *inst/doc/loo2-elpd.Rmd 14cf01f0c09e72af7c95131ed2a384c9 *inst/doc/loo2-elpd.html a80ad05f8bcaf6106f2d7fc95ab63689 *inst/doc/loo2-example.R 4ae1fc26afcbd809f78780c301b3d7b6 *inst/doc/loo2-example.Rmd 3598408f4a50020dd11f8bfd876821d2 *inst/doc/loo2-example.html bfe3a252921d699fb038ef6dd79149d3 *inst/doc/loo2-large-data.R 8ca446ca5a7064f80fdd4e1f82f48648 *inst/doc/loo2-large-data.Rmd 1b90530b5ff6111bd505c7e1d401267a *inst/doc/loo2-large-data.html 0170c9ab49dfcc7aa7da4d9d7a99ebca *inst/doc/loo2-lfo.R b902faf18c7bc2150b8ed352ee59d2ff *inst/doc/loo2-lfo.Rmd 66873e5f7aacb78796cff90ac1cae6ba *inst/doc/loo2-lfo.html 2c9d3a5d7b49903eef0f5ee34338c215 *inst/doc/loo2-mixis.R 6edf094d67487cde364601da2814813b *inst/doc/loo2-mixis.Rmd 7452374bdbb08db7627f4a8628a28a03 *inst/doc/loo2-mixis.html e474c9fe080e7cfddaf786a2f7a0e0d5 *inst/doc/loo2-moment-matching.R e5e39f3497fde800050ddfd0e674fa16 *inst/doc/loo2-moment-matching.Rmd a510dfddd0101e13e63ff643c99de9ef *inst/doc/loo2-moment-matching.html dba36fec55ac8b6e746cfd591654e3fa *inst/doc/loo2-non-factorized.R 8d2cf95d4d4051602e5f0c5349e821b0 *inst/doc/loo2-non-factorized.Rmd afc7a1af03f4fe8acee5a1f5fa70b17b *inst/doc/loo2-non-factorized.html 785a84a597f0eb3f2c40d0ff07e2e753 *inst/doc/loo2-weights.R 7cd7424040e1f76e2d63c812a3434323 *inst/doc/loo2-weights.Rmd 6e9cb05abb62ff52bd642f517bf00bd7 *inst/doc/loo2-weights.html 851340df658e44f55ca16934c602a4a7 *inst/doc/loo2-with-rstan.R af81dfee2ad43b8cf307c067d2c54526 *inst/doc/loo2-with-rstan.Rmd 1056b6e63a823248245300729a9183a4 *inst/doc/loo2-with-rstan.html 956b3a05cd00b0031078e65859cfa8a2 *man/E_loo.Rd b39658276d53d7b4b083fc943553414f *man/ap_psis.Rd 9543866aaef0431d9d598fa2fa31f66c *man/compare.Rd 30e61214d69b4f385ad54a434d910de2 *man/crps.Rd c45bba2c22b461c35159403aff55e932 *man/dot-compute_point_estimate.Rd c1b0b4bc4082b89d53aaeb52ebd09356 *man/dot-ndraws.Rd 7fd8a4885998d32db5442a349041de28 *man/dot-thin_draws.Rd 04ec6370a6242d07a5b23c39a862955f *man/elpd.Rd 4a5880e757cf95c2042d1a0c091ec0aa *man/example_loglik_array.Rd bb77d98af64bd7c1d306a173a5e8b9fa *man/extract_log_lik.Rd d30b67d89b4ff08c286c624b9dac80ad *man/figures/logo.svg 5fad10a5cc62c59ea429a5ce90191e2e *man/figures/stanlogo.png 50042e941f16bde46a08897a1ba49cec *man/find_model_names.Rd e51cc716f3e4466cf6a3a8ecd3b57c08 *man/gpdfit.Rd ba5244f1d390ce436dec3c181ff2576a *man/importance_sampling.Rd 222dffe6a2b6d01a11f81463970af12c *man/importance_sampling.array.Rd 6d57ad8598cd94d197080e94698bde4d *man/importance_sampling.default.Rd cd573e91f6a894fbd1d699705dbd85cf *man/importance_sampling.matrix.Rd b9c29d40f9ce9094d0b8062f88fc570d *man/kfold-generic.Rd 851ec677b1ac9c497cc266d3b2f75c40 *man/kfold-helpers.Rd 1685ed38f92cbf251144f84b1339422f *man/loo-datasets.Rd f2c2f9d9bf9e19073c83c7d0472ffe0f *man/loo-glossary.Rd 02295869ba900a3772717bf08e4541bd *man/loo-package.Rd bf86f10b3a959e4f6cbb59392e70c71e *man/loo.Rd af3bd0e7999aacc9c8af2e580f70dc10 *man/loo_approximate_posterior.Rd 7e2aab06b018d592286062b09806f3f9 *man/loo_compare.Rd 2eaad56801551dd2d404b15792ea294f *man/loo_model_weights.Rd 4a9eaa39b7fa095871ebce3190f9387b *man/loo_moment_match.Rd 26a1b99d6f22eeb86986400db89d54d3 *man/loo_moment_match_split.Rd d5e1ae1196aae95346f2dc269b0534e4 *man/loo_predictive_metric.Rd b081b21f603f513226803a7557ab0eda *man/loo_subsample.Rd 91647ff3e4471cf4ff7341c20adf4b28 *man/nlist.Rd f6c5902f97b330c65c5499c37509c007 *man/nobs.psis_loo_ss.Rd 831f68ae97e4a9815baa062a82d763f1 *man/obs_idx.Rd 6b36fcb6b009e92e74f495c54f074e30 *man/old-extractors.Rd cafba5f47b567743020cd2c3ccb99bc3 *man/parallel_psis_list.Rd 82f48d816342c698bbbf5248bd8f9993 *man/pareto-k-diagnostic.Rd 5e5bd2bc8bcf6d81f6198546eea854bb *man/print.loo.Rd 71ac1a537a6489dfc1eba3c70c2e4ae3 *man/print_dims.Rd 270969b0d49a7e035918ff1347fea38b *man/psis.Rd b98178fc1e0a9011b73d8cd90e75060f *man/psis_approximate_posterior.Rd 93de788e2c8800e215521624e6b6f288 *man/psislw.Rd fc1c1b874c615434a17c05ba15118e4f *man/relative_eff.Rd 7e605fec6c4b6c5c94acdff59b0facdd *man/sis.Rd 429d198e0fc4ab9a7d51d545de6d2f6d *man/tis.Rd d450e97034a3de45b1320f749c84ec64 *man/update.psis_loo_ss.Rd 2e9b3e18f61e61ffcd9a4644529ddc00 *man/waic.Rd 4ef3766a66b29568792ee07a28319587 *man/weights.importance_sampling.Rd 578103d7f631ca1e067152f694081929 *tests/testthat.R 2ac0cbcea1c3877ab7189ce6ef547456 *tests/testthat/data-for-tests/function_method_stuff.R e15f62365625657f8a5736d9ddd27ed9 *tests/testthat/data-for-tests/loo_subsample_vignette.rda 7d48326f38041a6a94282084a6cc100a *tests/testthat/data-for-tests/normal_reg_waic_test_example.rda bc687119963330560b4dd17fcfc0b568 *tests/testthat/data-for-tests/normal_reg_waic_test_example2.rda 12eca1a2e7d6acaeb276f1d43be11405 *tests/testthat/data-for-tests/test_data_psis_approximate_posterior.rda 461e6f7d77a22108db7634c8eb16de31 *tests/testthat/data-for-tests/test_radon_laplace_loo.rda e848e0e2d5a75887aef2f6cb71606991 *tests/testthat/reference-results/E_loo_default_mean.rds 5699079a4ea5442691f1b8bab271e8e2 *tests/testthat/reference-results/E_loo_default_quantile_10_50_90.rds 4efcc94c06478bfb05e6284d0f3b77cf *tests/testthat/reference-results/E_loo_default_quantile_50.rds 6e30adc4b8301661442885231dc39659 *tests/testthat/reference-results/E_loo_default_var.rds 4a8d94c0df59b14ca8a8c75cfd3c87cc *tests/testthat/reference-results/E_loo_matrix_mean.rds a7da85aca4504d235f6f50df6f4037d3 *tests/testthat/reference-results/E_loo_matrix_quantile_10_90.rds f6490ecb34f69e34e415973698ad3230 *tests/testthat/reference-results/E_loo_matrix_quantile_50.rds c7917c23906fbbc80be612d159252565 *tests/testthat/reference-results/E_loo_matrix_var.rds caee3a91d6e26a2ae95cacdc7e2b5b7c *tests/testthat/reference-results/compare_three_models.rds 864c759437100aee04c17223f04357af *tests/testthat/reference-results/compare_two_models.rds 66810c2ce86f65d56ce62a7917f8f184 *tests/testthat/reference-results/crps.rds e364cf8b9703642b5ce7437f321cc907 *tests/testthat/reference-results/elpd.rds c89dc4d2c6db98920d5df51bf422e7d8 *tests/testthat/reference-results/gpdfit.rds 1cfb8666e7ea098c82568956e5d3d960 *tests/testthat/reference-results/gpdfit_default_grid.rds bbda7c2998079373071f77a827ef9ae0 *tests/testthat/reference-results/gpdfit_old.rds e64b9214f9e7bc4458b8534a3d48b932 *tests/testthat/reference-results/loo.rds bea49f709d791feb7db1e6342e31a3cb *tests/testthat/reference-results/loo_compare_three_models.rds 0774e3b0481dc35d081de100ed59c8f1 *tests/testthat/reference-results/loo_compare_two_models.rds f024f55da82718a0373e8447a88d3b35 *tests/testthat/reference-results/loo_crps.rds 01dce7cc9352f2602171df3716a5806d *tests/testthat/reference-results/loo_predictive_metric_acc_mean.rds 35b02018dab43c8b7a9440ece98e9c48 *tests/testthat/reference-results/loo_predictive_metric_acc_quant.rds 81d44a337280b7ee8855ae5205c597b3 *tests/testthat/reference-results/loo_predictive_metric_bacc_mean.rds d821b8716b8e06cc5c849407fadd1782 *tests/testthat/reference-results/loo_predictive_metric_bacc_quant.rds dcaf80225926a26ff1cea0b209932f9e *tests/testthat/reference-results/loo_predictive_metric_mae_mean.rds a72e27bafccf2be523f86dc6dc3ae2ae *tests/testthat/reference-results/loo_predictive_metric_mae_quant.rds 96ff0333e54b717c9a35347d21389a1f *tests/testthat/reference-results/loo_predictive_metric_mse_mean.rds f17d3465a79f18f9449a503d23877a97 *tests/testthat/reference-results/loo_predictive_metric_mse_quant.rds f0efc0d14de771d43f296b21840f1d8e *tests/testthat/reference-results/loo_predictive_metric_rmse_mean.rds c1769e6bdb632c75f2505417b658f354 *tests/testthat/reference-results/loo_predictive_metric_rmse_quant.rds f05e3cc45739248b3cee7a3fcfb863e2 *tests/testthat/reference-results/loo_scrps.rds 8ed042dfaef97ddf65e104a371272d01 *tests/testthat/reference-results/mcse_loo.rds 37e00ccdd4af98d5743ddb5a815d66fa *tests/testthat/reference-results/model_weights_pseudobma.rds bbd7fb9cbfd9d0f97b3f9a37c3a2cbc6 *tests/testthat/reference-results/model_weights_stacking.rds 0a18f2cc94899bad45340b9d03028b9a *tests/testthat/reference-results/moment_match_loo_1.rds 7249b08baf26f934475f915616176cbb *tests/testthat/reference-results/moment_match_loo_2.rds 3cb007a608fe52f82985331317a97b67 *tests/testthat/reference-results/moment_match_loo_3.rds 0be91de853fc66437c22302566c72101 *tests/testthat/reference-results/moment_match_loo_Stan_1.rds 3c70f5eb1f1d247c96c88da426c19650 *tests/testthat/reference-results/moment_match_split.rds 07f27182ec547dbb828b8ca0a7ec56cc *tests/testthat/reference-results/moment_match_var_and_cov.rds 283cc7cd7037ab15c49219f27a9b6768 *tests/testthat/reference-results/psis.rds 472d50cdf22b9987f6f483e5222db483 *tests/testthat/reference-results/relative_eff.rds 96588836bdccc9b70e7ae23363287977 *tests/testthat/reference-results/scrps.rds d8655bdd6e06668bc34f403dba01f5bf *tests/testthat/reference-results/waic.rds 31d089232f51dcc64524b33adbb4df27 *tests/testthat/test_0_helpers.R 1bc115dcab416a2cbd62454203e195d6 *tests/testthat/test_E_loo.R cb3387632ab286652f95680a6f6e1877 *tests/testthat/test_compare.R 6e6855e455b214471f03a0082a3f44e2 *tests/testthat/test_crps.R 48d304258442da660735df89f47c1b3d *tests/testthat/test_deprecated_extractors.R 2e6aa946aa681868a37340b6fb63d074 *tests/testthat/test_extract_log_lik.R 4eee496444b685c81d3bf2d46f35f1ea *tests/testthat/test_gpdfit.R 4167c81d7d246bbe0a21f5e4e025bad2 *tests/testthat/test_kfold_helpers.R 926fc3683b9f0722063adc4b183f97e1 *tests/testthat/test_loo_and_waic.R 30818a4c8ec5b55f26194b1141ca2770 *tests/testthat/test_loo_approximate_posterior.R 4d652f0e5192753d0a094be9639b05f0 *tests/testthat/test_loo_moment_matching.R 3801a62aa543b2ee748fcbe2e9f2afcd *tests/testthat/test_loo_predictive_metric.R decd56eff9ae1ae50e7ec121f4d4f836 *tests/testthat/test_loo_subsampling.R 622b95906fccfeb5249355eb5726e7b5 *tests/testthat/test_model_weighting.R c5260719f5ae71b1bfb0f9bc0c792b90 *tests/testthat/test_print_plot.R 2a319b092e4dca0e7b5d5b5558ce301b *tests/testthat/test_psis.R c95ed5f0cb7c6946df375b4bd0b9f558 *tests/testthat/test_psis_approximate_posterior.R 7b7760c5db9727709873b213a2f8cf10 *tests/testthat/test_psislw.R 898bdb079f1d173e70c57b747bd7f9f0 *tests/testthat/test_relative_eff.R a6b1425c441c2bc5232f3650f006d29b *tests/testthat/test_tisis.R 8d1d0c1c75700b9a6a0b760b687f9615 *vignettes/children/SEE-ONLINE.txt de25cd7c13804ca23404116a8b3a9ec9 *vignettes/children/SETTINGS-knitr.txt ff337ea126a5537ded0dc4598e5cb1e0 *vignettes/loo2-elpd.Rmd 4ae1fc26afcbd809f78780c301b3d7b6 *vignettes/loo2-example.Rmd 8ca446ca5a7064f80fdd4e1f82f48648 *vignettes/loo2-large-data.Rmd b902faf18c7bc2150b8ed352ee59d2ff *vignettes/loo2-lfo.Rmd 6edf094d67487cde364601da2814813b *vignettes/loo2-mixis.Rmd e5e39f3497fde800050ddfd0e674fa16 *vignettes/loo2-moment-matching.Rmd 8d2cf95d4d4051602e5f0c5349e821b0 *vignettes/loo2-non-factorized.Rmd 7cd7424040e1f76e2d63c812a3434323 *vignettes/loo2-weights.Rmd af81dfee2ad43b8cf307c067d2c54526 *vignettes/loo2-with-rstan.Rmd loo/inst/0000755000176200001440000000000014411465510012021 5ustar liggesusersloo/inst/doc/0000755000176200001440000000000014411465510012566 5ustar liggesusersloo/inst/doc/loo2-elpd.html0000644000176200001440000010122614411455326015257 0ustar liggesusers Holdout validation and K-fold cross-validation of Stan programs with the loo package

Holdout validation and K-fold cross-validation of Stan programs with the loo package

Bruno Nicenboim

2023-03-30

Introduction

This vignette demonstrates how to do holdout validation and K-fold cross-validation with loo for a Stan program.

Example: Eradication of Roaches using holdout validation approach

This vignette uses the same example as in the vignettes Using the loo package (version >= 2.0.0) and Avoiding model refits in leave-one-out cross-validation with moment matching.

Coding the Stan model

Here is the Stan code for fitting a Poisson regression model:

stancode <- "
data {
  int<lower=1> K;
  int<lower=1> N;
  matrix[N,K] x;
  int y[N];
  vector[N] offset;

  real beta_prior_scale;
  real alpha_prior_scale;
}
parameters {
  vector[K] beta;
  real intercept;
}
model {
  y ~ poisson(exp(x * beta + intercept + offset));
  beta ~ normal(0,beta_prior_scale);
  intercept ~ normal(0,alpha_prior_scale);
}
generated quantities {
  vector[N] log_lik;
  for (n in 1:N)
    log_lik[n] = poisson_lpmf(y[n] | exp(x[n] * beta + intercept + offset[n]));
}
"

Following the usual approach recommended in Writing Stan programs for use with the loo package, we compute the log-likelihood for each observation in the generated quantities block of the Stan program.

Setup

In addition to loo, we load the rstan package for fitting the model. We will also need the rstanarm package for the data.

library("rstan")
library("loo")
seed <- 9547
set.seed(seed)

Holdout validation

For this approach, the model is first fit to the “train” data and then is evaluated on the held-out “test” data.

Splitting the data between train and test

The data is divided between train (80% of the data) and test (20%):

# Prepare data
data(roaches, package = "rstanarm")
roaches$roach1 <- sqrt(roaches$roach1)
roaches$offset <- log(roaches[,"exposure2"])
# 20% of the data goes to the test set:
roaches$test <- 0
roaches$test[sample(.2 * seq_len(nrow(roaches)))] <- 1
# data to "train" the model
data_train <- list(y = roaches$y[roaches$test == 0],
                   x = as.matrix(roaches[roaches$test == 0,
                                         c("roach1", "treatment", "senior")]),
                   N = nrow(roaches[roaches$test == 0,]),
                   K = 3,
                   offset = roaches$offset[roaches$test == 0],
                   beta_prior_scale = 2.5,
                   alpha_prior_scale = 5.0
                   )
# data to "test" the model
data_test <- list(y = roaches$y[roaches$test == 1],
                   x = as.matrix(roaches[roaches$test == 1,
                                         c("roach1", "treatment", "senior")]),
                   N = nrow(roaches[roaches$test == 1,]),
                   K = 3,
                   offset = roaches$offset[roaches$test == 1],
                   beta_prior_scale = 2.5,
                   alpha_prior_scale = 5.0
                   )

Fitting the model with RStan

Next we fit the model to the “test” data in Stan using the rstan package:

# Compile
stanmodel <- stan_model(model_code = stancode)
# Fit model
fit <- sampling(stanmodel, data = data_train, seed = seed, refresh = 0)

We recompute the generated quantities using the posterior draws conditional on the training data, but we now pass in the held-out data to get the log predictive densities for the test data. Because we are using independent data, the log predictive density coincides with the log likelihood of the test data.

gen_test <- gqs(stanmodel, draws = as.matrix(fit), data= data_test)
log_pd <- extract_log_lik(gen_test)

Computing holdout elpd:

Now we evaluate the predictive performance of the model on the test data using elpd().

(elpd_holdout <- elpd(log_pd))

Computed from 4000 by 52 log-likelihood matrix using the generic elpd function

     Estimate    SE
elpd  -1736.7 288.9
ic     3473.5 577.9

When one wants to compare different models, the function loo_compare() can be used to assess the difference in performance.

K-fold cross validation

For this approach the data is divided into folds, and each time one fold is tested while the rest of the data is used to fit the model (see Vehtari et al., 2017).

Splitting the data in folds

We use the data that is already pre-processed and we divide it in 10 random folds using kfold_split_random

# Prepare data
roaches$fold <- kfold_split_random(K = 10, N = nrow(roaches))

Fitting and extracting the log pointwise predictive densities for each fold

We now loop over the 10 folds. In each fold we do the following. First, we fit the model to all the observations except the ones belonging to the left-out fold. Second, we compute the log pointwise predictive densities for the left-out fold. Last, we store the predictive density for the observations of the left-out fold in a matrix. The output of this loop is a matrix of the log pointwise predictive densities of all the observations.

# Prepare a matrix with the number of post-warmup iterations by number of observations:
log_pd_kfold <- matrix(nrow = 4000, ncol = nrow(roaches))
# Loop over the folds
for(k in 1:10){
  data_train <- list(y = roaches$y[roaches$fold != k],
                   x = as.matrix(roaches[roaches$fold != k,
                                         c("roach1", "treatment", "senior")]),
                   N = nrow(roaches[roaches$fold != k,]),
                   K = 3,
                   offset = roaches$offset[roaches$fold != k],
                   beta_prior_scale = 2.5,
                   alpha_prior_scale = 5.0
                   )
  data_test <- list(y = roaches$y[roaches$fold == k],
                   x = as.matrix(roaches[roaches$fold == k,
                                         c("roach1", "treatment", "senior")]),
                   N = nrow(roaches[roaches$fold == k,]),
                   K = 3,
                   offset = roaches$offset[roaches$fold == k],
                   beta_prior_scale = 2.5,
                   alpha_prior_scale = 5.0
                   )
  fit <- sampling(stanmodel, data = data_train, seed = seed, refresh = 0)
  gen_test <- gqs(stanmodel, draws = as.matrix(fit), data= data_test)
  log_pd_kfold[, roaches$fold == k] <- extract_log_lik(gen_test)
}

Computing K-fold elpd:

Now we evaluate the predictive performance of the model on the 10 folds using elpd().

(elpd_kfold <- elpd(log_pd_kfold))

Computed from 4000 by 262 log-likelihood matrix using the generic elpd function

     Estimate     SE
elpd  -5552.7  727.9
ic    11105.5 1455.8

If one wants to compare several models (with loo_compare), one should use the same folds for all the different models.

References

Gelman, A., and Hill, J. (2007). Data Analysis Using Regression and Multilevel Hierarchical Models. Cambridge University Press.

Stan Development Team (2020) RStan: the R interface to Stan, Version 2.21.1 https://mc-stan.org

Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. Statistics and Computing. 27(5), 1413–1432. :10.1007/s11222-016-9696-4. Links: published | arXiv preprint.

loo/inst/doc/loo2-weights.Rmd0000644000176200001440000003777114407123455015600 0ustar liggesusers--- title: "Bayesian Stacking and Pseudo-BMA weights using the loo package" author: "Aki Vehtari and Jonah Gabry" date: "`r Sys.Date()`" output: html_vignette: toc: yes params: EVAL: !r identical(Sys.getenv("NOT_CRAN"), "true") --- ```{r, child="children/SETTINGS-knitr.txt"} ``` ```{r, child="children/SEE-ONLINE.txt", eval = if (isTRUE(exists("params"))) !params$EVAL else TRUE} ``` # Introduction This vignette demonstrates the new functionality in __loo__ v2.0.0 for Bayesian stacking and Pseudo-BMA weighting. In this vignette we can't provide all of the necessary background on this topic, so we encourage readers to refer to the paper * Yao, Y., Vehtari, A., Simpson, D., and Gelman, A. (2018). Using stacking to average Bayesian predictive distributions. In Bayesian Analysis, \doi:10.1214/17-BA1091. [Online](https://projecteuclid.org/euclid.ba/1516093227) which provides important details on the methods demonstrated in this vignette. Here we just quote from the abstract of the paper: > **Abstract**: Bayesian model averaging is flawed in the $\mathcal{M}$-open setting in which the true data-generating process is not one of the candidate models being fit. We take the idea of stacking from the point estimation literature and generalize to the combination of predictive distributions. We extend the utility function to any proper scoring rule and use Pareto smoothed importance sampling to efficiently compute the required leave-one-out posterior distributions. We compare stacking of predictive distributions to several alternatives: stacking of means, Bayesian model averaging (BMA), Pseudo-BMA, and a variant of Pseudo-BMA that is stabilized using the Bayesian bootstrap. Based on simulations and real-data applications, we recommend stacking of predictive distributions, with bootstrapped-Pseudo-BMA as an approximate alternative when computation cost is an issue. Ideally, we would avoid the Bayesian model combination problem by extending the model to include the separate models as special cases, and preferably as a continuous expansion of the model space. For example, instead of model averaging over different covariate combinations, all potentially relevant covariates should be included in a predictive model (for causal analysis more care is needed) and a prior assumption that only some of the covariates are relevant can be presented with regularized horseshoe prior (Piironen and Vehtari, 2017a). For variable selection we recommend projective predictive variable selection (Piironen and Vehtari, 2017a; [__projpred__ package](https://cran.r-project.org/package=projpred)). To demonstrate how to use __loo__ package to compute Bayesian stacking and Pseudo-BMA weights, we repeat two simple model averaging examples from Chapters 6 and 10 of _Statistical Rethinking_ by Richard McElreath. In _Statistical Rethinking_ WAIC is used to form weights which are similar to classical "Akaike weights". Pseudo-BMA weighting using PSIS-LOO for computation is close to these WAIC weights, but named after the Pseudo Bayes Factor by Geisser and Eddy (1979). As discussed below, in general we prefer using stacking rather than WAIC weights or the similar pseudo-BMA weights. # Setup In addition to the __loo__ package we will also load the __rstanarm__ package for fitting the models. ```{r setup, message=FALSE} library(rstanarm) library(loo) ``` # Example: Primate milk In _Statistical Rethinking_, McElreath describes the data for the primate milk example as follows: > A popular hypothesis has it that primates with larger brains produce more energetic milk, so that brains can grow quickly. ... The question here is to what extent energy content of milk, measured here by kilocalories, is related to the percent of the brain mass that is neocortex. ... We'll end up needing female body mass as well, to see the masking that hides the relationships among the variables. ```{r data} data(milk) d <- milk[complete.cases(milk),] d$neocortex <- d$neocortex.perc /100 str(d) ``` We repeat the analysis in Chapter 6 of _Statistical Rethinking_ using the following four models (here we use the default weakly informative priors in __rstanarm__, while flat priors were used in _Statistical Rethinking_). ```{r fits, results="hide"} fit1 <- stan_glm(kcal.per.g ~ 1, data = d, seed = 2030) fit2 <- update(fit1, formula = kcal.per.g ~ neocortex) fit3 <- update(fit1, formula = kcal.per.g ~ log(mass)) fit4 <- update(fit1, formula = kcal.per.g ~ neocortex + log(mass)) ``` McElreath uses WAIC for model comparison and averaging, so we'll start by also computing WAIC for these models so we can compare the results to the other options presented later in the vignette. The __loo__ package provides `waic` methods for log-likelihood arrays, matrices and functions. Since we fit our model with rstanarm we can use the `waic` method provided by the __rstanarm__ package (a wrapper around `waic` from the __loo__ package), which allows us to just pass in our fitted model objects instead of first extracting the log-likelihood values. ```{r waic} waic1 <- waic(fit1) waic2 <- waic(fit2) waic3 <- waic(fit3) waic4 <- waic(fit4) waics <- c( waic1$estimates["elpd_waic", 1], waic2$estimates["elpd_waic", 1], waic3$estimates["elpd_waic", 1], waic4$estimates["elpd_waic", 1] ) ``` We get some warnings when computing WAIC for models 3 and 4, indicating that we shouldn't trust the WAIC weights we will compute later. Following the recommendation in the warning, we next use the `loo` methods to compute PSIS-LOO instead. The __loo__ package provides `loo` methods for log-likelihood arrays, matrices, and functions, but since we fit our model with __rstanarm__ we can just pass the fitted model objects directly and __rstanarm__ will extract the needed values to pass to the __loo__ package. (Like __rstanarm__, some other R packages for fitting Stan models, e.g. __brms__, also provide similar methods for interfacing with the __loo__ package.) ```{r loo} # note: the loo function accepts a 'cores' argument that we recommend specifying # when working with bigger datasets loo1 <- loo(fit1) loo2 <- loo(fit2) loo3 <- loo(fit3) loo4 <- loo(fit4) lpd_point <- cbind( loo1$pointwise[,"elpd_loo"], loo2$pointwise[,"elpd_loo"], loo3$pointwise[,"elpd_loo"], loo4$pointwise[,"elpd_loo"] ) ``` With `loo` we don't get any warnings for models 3 and 4, but for illustration of good results, we display the diagnostic details for these models anyway. ```{r print-loo} print(loo3) print(loo4) ``` One benefit of PSIS-LOO over WAIC is better diagnostics. Here for both models 3 and 4 all $k<0.7$ and the Monte Carlo SE of `elpd_loo` is 0.1 or less, and we can expect the model comparison to be reliable. Next we compute and compare 1) WAIC weights, 2) Pseudo-BMA weights without Bayesian bootstrap, 3) Pseudo-BMA+ weights with Bayesian bootstrap, and 4) Bayesian stacking weights. ```{r weights} waic_wts <- exp(waics) / sum(exp(waics)) pbma_wts <- pseudobma_weights(lpd_point, BB=FALSE) pbma_BB_wts <- pseudobma_weights(lpd_point) # default is BB=TRUE stacking_wts <- stacking_weights(lpd_point) round(cbind(waic_wts, pbma_wts, pbma_BB_wts, stacking_wts), 2) ``` With all approaches Model 4 with `neocortex` and `log(mass)` gets most of the weight. Based on theory, Pseudo-BMA weights without Bayesian bootstrap should be close to WAIC weights, and we can also see that here. Pseudo-BMA+ weights with Bayesian bootstrap provide more cautious weights further away from 0 and 1 (see Yao et al. (2018) for a discussion of why this can be beneficial and results from related experiments). In this particular example, the Bayesian stacking weights are not much different from the other weights. One of the benefits of stacking is that it manages well if there are many similar models. Consider for example that there could be many irrelevant covariates that when included would produce a similar model to one of the existing models. To emulate this situation here we simply copy the first model a bunch of times, but you can imagine that instead we would have ten alternative models with about the same predictive performance. WAIC weights for such a scenario would be close to the following: ```{r waic_wts_demo} waic_wts_demo <- exp(waics[c(1,1,1,1,1,1,1,1,1,1,2,3,4)]) / sum(exp(waics[c(1,1,1,1,1,1,1,1,1,1,2,3,4)])) round(waic_wts_demo, 3) ``` Notice how much the weight for model 4 is lowered now that more models similar to model 1 (or in this case identical) have been added. Both WAIC weights and Pseudo-BMA approaches first estimate the predictive performance separately for each model and then compute weights based on estimated relative predictive performances. Similar models share similar weights so the weights of other models must be reduced for the total sum of the weights to remain the same. On the other hand, stacking optimizes the weights _jointly_, allowing for the very similar models (in this toy example repeated models) to share their weight while more unique models keep their original weights. In our example we can see this difference clearly: ```{r stacking_weights} stacking_weights(lpd_point[,c(1,1,1,1,1,1,1,1,1,1,2,3,4)]) ``` Using stacking, the weight for the best model stays essentially unchanged. # Example: Oceanic tool complexity Another example we consider is the Kline oceanic tool complexity data, which McElreath describes as follows: >Different historical island populations possessed tool kits of different size. These kits include fish hooks, axes, boats, hand plows, and many other types of tools. A number of theories predict that larger populations will both develop and sustain more complex tool kits. ... It's also suggested that contact rates among populations effectively increases population [sic, probably should be tool kit] size, as it's relevant to technological evolution. We build models predicting the total number of tools given the log population size and the contact rate (high vs. low). ```{r Kline} data(Kline) d <- Kline d$log_pop <- log(d$population) d$contact_high <- ifelse(d$contact=="high", 1, 0) str(d) ``` We start with a Poisson regression model with the log population size, the contact rate, and an interaction term between them (priors are informative priors as in _Statistical Rethinking_). ```{r fit10, results="hide"} fit10 <- stan_glm( total_tools ~ log_pop + contact_high + log_pop * contact_high, family = poisson(link = "log"), data = d, prior = normal(0, 1, autoscale = FALSE), prior_intercept = normal(0, 100, autoscale = FALSE), seed = 2030 ) ``` Before running other models, we check whether Poisson is good choice as the conditional observation model. ```{r loo10} loo10 <- loo(fit10) print(loo10) ``` We get at least one observation with $k>0.7$ and the estimated effective number of parameters `p_loo` is larger than the total number of parameters in the model. This indicates that Poisson might be too narrow. A negative binomial model might be better, but with so few observations it is not so clear. We can compute LOO more accurately by running Stan again for the leave-one-out folds with high $k$ estimates. When using __rstanarm__ this can be done by specifying the `k_threshold` argument: ```{r loo10-threshold} loo10 <- loo(fit10, k_threshold=0.7) print(loo10) ``` In this case we see that there is not much difference, and thus it is relatively safe to continue. As a comparison we also compute WAIC: ```{r waic10} waic10 <- waic(fit10) print(waic10) ``` The WAIC computation is giving warnings and the estimated ELPD is slightly more optimistic. We recommend using the PSIS-LOO results instead. To assess whether the contact rate and interaction term are useful, we can make a comparison to models without these terms. ```{r contact_high, results="hide"} fit11 <- update(fit10, formula = total_tools ~ log_pop + contact_high) fit12 <- update(fit10, formula = total_tools ~ log_pop) ``` ```{r loo-contact_high} (loo11 <- loo(fit11)) (loo12 <- loo(fit12)) ``` ```{r relo-contact_high} loo11 <- loo(fit11, k_threshold=0.7) loo12 <- loo(fit12, k_threshold=0.7) lpd_point <- cbind( loo10$pointwise[, "elpd_loo"], loo11$pointwise[, "elpd_loo"], loo12$pointwise[, "elpd_loo"] ) ``` For comparison we'll also compute WAIC values for these additional models: ```{r waic-contact_high} waic11 <- waic(fit11) waic12 <- waic(fit12) waics <- c( waic10$estimates["elpd_waic", 1], waic11$estimates["elpd_waic", 1], waic12$estimates["elpd_waic", 1] ) ``` The WAIC computation again gives warnings, and we recommend using PSIS-LOO instead. Finally, we compute 1) WAIC weights, 2) Pseudo-BMA weights without Bayesian bootstrap, 3) Pseudo-BMA+ weights with Bayesian bootstrap, and 4) Bayesian stacking weights. ```{r weights-contact_high} waic_wts <- exp(waics) / sum(exp(waics)) pbma_wts <- pseudobma_weights(lpd_point, BB=FALSE) pbma_BB_wts <- pseudobma_weights(lpd_point) # default is BB=TRUE stacking_wts <- stacking_weights(lpd_point) round(cbind(waic_wts, pbma_wts, pbma_BB_wts, stacking_wts), 2) ``` All weights favor the second model with the log population and the contact rate. WAIC weights and Pseudo-BMA weights (without Bayesian bootstrap) are similar, while Pseudo-BMA+ is more cautious and closer to stacking weights. It may seem surprising that Bayesian stacking is giving zero weight to the first model, but this is likely due to the fact that the estimated effect for the interaction term is close to zero and thus models 1 and 2 give very similar predictions. In other words, incorporating the model with the interaction (model 1) into the model average doesn't improve the predictions at all and so model 1 is given a weight of 0. On the other hand, models 2 and 3 are giving slightly different predictions and thus their combination may be slightly better than either alone. This behavior is related to the repeated similar model illustration in the milk example above. # Simpler coding using `loo_model_weights` function Although in the examples above we called the `stacking_weights` and `pseudobma_weights` functions directly, we can also use the `loo_model_weights` wrapper, which takes as its input either a list of pointwise log-likelihood matrices or a list of precomputed loo objects. There are also `loo_model_weights` methods for stanreg objects (fitted model objects from __rstanarm__) as well as fitted model objects from other packages (e.g. __brms__) that do the preparation work for the user (see, e.g., the examples at `help("loo_model_weights", package = "rstanarm")`). ```{r loo_model_weights} # using list of loo objects loo_list <- list(loo10, loo11, loo12) loo_model_weights(loo_list) loo_model_weights(loo_list, method = "pseudobma") loo_model_weights(loo_list, method = "pseudobma", BB = FALSE) ``` # References McElreath, R. (2016). _Statistical rethinking: A Bayesian course with examples in R and Stan_. Chapman & Hall/CRC. http://xcelab.net/rm/statistical-rethinking/ Piironen, J. and Vehtari, A. (2017a). Sparsity information and regularization in the horseshoe and other shrinkage priors. In Electronic Journal of Statistics, 11(2):5018-5051. [Online](https://projecteuclid.org/euclid.ejs/1513306866). Piironen, J. and Vehtari, A. (2017b). Comparison of Bayesian predictive methods for model selection. Statistics and Computing, 27(3):711-735. \doi:10.1007/s11222-016-9649-y. [Online](https://link.springer.com/article/10.1007/s11222-016-9649-y). Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. _Statistics and Computing_. 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. [online](https://link.springer.com/article/10.1007/s11222-016-9696-4), [arXiv preprint arXiv:1507.04544](https://arxiv.org/abs/1507.04544). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.02646](https://arxiv.org/abs/1507.02646). Yao, Y., Vehtari, A., Simpson, D., and Gelman, A. (2018). Using stacking to average Bayesian predictive distributions. In Bayesian Analysis, \doi:10.1214/17-BA1091. [Online](https://projecteuclid.org/euclid.ba/1516093227). loo/inst/doc/loo2-elpd.R0000644000176200001440000001063314411455326014515 0ustar liggesusersparams <- list(EVAL = TRUE) ## ----SETTINGS-knitr, include=FALSE-------------------------------------------- stopifnot(require(knitr)) opts_chunk$set( comment=NA, eval = if (isTRUE(exists("params"))) params$EVAL else FALSE, dev = "png", dpi = 150, fig.asp = 0.618, fig.width = 5, out.width = "60%", fig.align = "center" ) ## ----stancode----------------------------------------------------------------- stancode <- " data { int K; int N; matrix[N,K] x; int y[N]; vector[N] offset; real beta_prior_scale; real alpha_prior_scale; } parameters { vector[K] beta; real intercept; } model { y ~ poisson(exp(x * beta + intercept + offset)); beta ~ normal(0,beta_prior_scale); intercept ~ normal(0,alpha_prior_scale); } generated quantities { vector[N] log_lik; for (n in 1:N) log_lik[n] = poisson_lpmf(y[n] | exp(x[n] * beta + intercept + offset[n])); } " ## ----setup, message=FALSE----------------------------------------------------- library("rstan") library("loo") seed <- 9547 set.seed(seed) ## ----modelfit-holdout, message=FALSE------------------------------------------ # Prepare data data(roaches, package = "rstanarm") roaches$roach1 <- sqrt(roaches$roach1) roaches$offset <- log(roaches[,"exposure2"]) # 20% of the data goes to the test set: roaches$test <- 0 roaches$test[sample(.2 * seq_len(nrow(roaches)))] <- 1 # data to "train" the model data_train <- list(y = roaches$y[roaches$test == 0], x = as.matrix(roaches[roaches$test == 0, c("roach1", "treatment", "senior")]), N = nrow(roaches[roaches$test == 0,]), K = 3, offset = roaches$offset[roaches$test == 0], beta_prior_scale = 2.5, alpha_prior_scale = 5.0 ) # data to "test" the model data_test <- list(y = roaches$y[roaches$test == 1], x = as.matrix(roaches[roaches$test == 1, c("roach1", "treatment", "senior")]), N = nrow(roaches[roaches$test == 1,]), K = 3, offset = roaches$offset[roaches$test == 1], beta_prior_scale = 2.5, alpha_prior_scale = 5.0 ) ## ----fit-train---------------------------------------------------------------- # Compile stanmodel <- stan_model(model_code = stancode) # Fit model fit <- sampling(stanmodel, data = data_train, seed = seed, refresh = 0) ## ----gen-test----------------------------------------------------------------- gen_test <- gqs(stanmodel, draws = as.matrix(fit), data= data_test) log_pd <- extract_log_lik(gen_test) ## ----elpd-holdout------------------------------------------------------------- (elpd_holdout <- elpd(log_pd)) ## ----prepare-folds, message=FALSE--------------------------------------------- # Prepare data roaches$fold <- kfold_split_random(K = 10, N = nrow(roaches)) ## ----------------------------------------------------------------------------- # Prepare a matrix with the number of post-warmup iterations by number of observations: log_pd_kfold <- matrix(nrow = 4000, ncol = nrow(roaches)) # Loop over the folds for(k in 1:10){ data_train <- list(y = roaches$y[roaches$fold != k], x = as.matrix(roaches[roaches$fold != k, c("roach1", "treatment", "senior")]), N = nrow(roaches[roaches$fold != k,]), K = 3, offset = roaches$offset[roaches$fold != k], beta_prior_scale = 2.5, alpha_prior_scale = 5.0 ) data_test <- list(y = roaches$y[roaches$fold == k], x = as.matrix(roaches[roaches$fold == k, c("roach1", "treatment", "senior")]), N = nrow(roaches[roaches$fold == k,]), K = 3, offset = roaches$offset[roaches$fold == k], beta_prior_scale = 2.5, alpha_prior_scale = 5.0 ) fit <- sampling(stanmodel, data = data_train, seed = seed, refresh = 0) gen_test <- gqs(stanmodel, draws = as.matrix(fit), data= data_test) log_pd_kfold[, roaches$fold == k] <- extract_log_lik(gen_test) } ## ----elpd-kfold--------------------------------------------------------------- (elpd_kfold <- elpd(log_pd_kfold)) loo/inst/doc/loo2-with-rstan.html0000644000176200001440000005774614411465510016450 0ustar liggesusers Writing Stan programs for use with the loo package

Writing Stan programs for use with the loo package

Aki Vehtari and Jonah Gabry

2023-03-30

Introduction

This vignette demonstrates how to write a Stan program that computes and stores the pointwise log-likelihood required for using the loo package. The other vignettes included with the package demonstrate additional functionality.

Some sections from this vignette are excerpted from our papers

  • Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. Statistics and Computing. 27(5), 1413–1432. :10.1007/s11222-016-9696-4. Links: published | arXiv preprint.

  • Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. arXiv preprint arXiv:1507.04544.

which provide important background for understanding the methods implemented in the package.

Example: Well water in Bangladesh

This example comes from a survey of residents from a small area in Bangladesh that was affected by arsenic in drinking water. Respondents with elevated arsenic levels in their wells were asked if they were interested in getting water from a neighbor’s well, and a series of logistic regressions were fit to predict this binary response given various information about the households (Gelman and Hill, 2007). Here we fit a model for the well-switching response given two predictors: the arsenic level of the water in the resident’s home, and the distance of the house from the nearest safe well.

The sample size in this example is \(N=3020\), which is not huge but is large enough that it is important to have a computational method for LOO that is fast for each data point. On the plus side, with such a large dataset, the influence of any given observation is small, and so the computations should be stable.

Coding the Stan model

Here is the Stan code for fitting the logistic regression model, which we save in a file called logistic.stan:

data {
  int<lower=0> N;             // number of data points
  int<lower=0> P;             // number of predictors (including intercept)
  matrix[N,P] X;              // predictors (including 1s for intercept)
  int<lower=0,upper=1> y[N];  // binary outcome
}
parameters {
  vector[P] beta;
}
model {
  beta ~ normal(0, 1);
  y ~ bernoulli_logit(X * beta);
}
generated quantities {
  vector[N] log_lik;
  for (n in 1:N) {
    log_lik[n] = bernoulli_logit_lpmf(y[n] | X[n] * beta);
  }
}

We have defined the log likelihood as a vector named log_lik in the generated quantities block so that the individual terms will be saved by Stan. After running Stan, log_lik can be extracted (using the extract_log_lik function provided in the loo package) as an \(S \times N\) matrix, where \(S\) is the number of simulations (posterior draws) and \(N\) is the number of data points.

Fitting the model with RStan

Next we fit the model in Stan using the rstan package:

library("rstan")

# Prepare data 
url <- "http://stat.columbia.edu/~gelman/arm/examples/arsenic/wells.dat"
wells <- read.table(url)
wells$dist100 <- with(wells, dist / 100)
X <- model.matrix(~ dist100 + arsenic, wells)
standata <- list(y = wells$switch, X = X, N = nrow(X), P = ncol(X))

# Fit model
fit_1 <- stan("logistic.stan", data = standata)
print(fit_1, pars = "beta")
         mean se_mean   sd  2.5%   25%   50%   75% 97.5% n_eff Rhat
beta[1]  0.00       0 0.08 -0.16 -0.05  0.00  0.05  0.15  1964    1
beta[2] -0.89       0 0.10 -1.09 -0.96 -0.89 -0.82 -0.68  2048    1
beta[3]  0.46       0 0.04  0.38  0.43  0.46  0.49  0.54  2198    1

Computing approximate leave-one-out cross-validation using PSIS-LOO

We can then use the loo package to compute the efficient PSIS-LOO approximation to exact LOO-CV:

library("loo")

# Extract pointwise log-likelihood
# using merge_chains=FALSE returns an array, which is easier to 
# use with relative_eff()
log_lik_1 <- extract_log_lik(fit_1, merge_chains = FALSE)

# as of loo v2.0.0 we can optionally provide relative effective sample sizes
# when calling loo, which allows for better estimates of the PSIS effective
# sample sizes and Monte Carlo error
r_eff <- relative_eff(exp(log_lik_1), cores = 2) 

# preferably use more than 2 cores (as many cores as possible)
# will use value of 'mc.cores' option if cores is not specified
loo_1 <- loo(log_lik_1, r_eff = r_eff, cores = 2)
print(loo_1)
Computed from 4000 by 3020 log-likelihood matrix

         Estimate   SE
elpd_loo  -1968.5 15.6
p_loo         3.2  0.1
looic      3937.0 31.2
------
Monte Carlo SE of elpd_loo is 0.0.

All Pareto k estimates are good (k < 0.5).
See help('pareto-k-diagnostic') for details.

The printed output from the loo function shows the estimates \(\widehat{\mbox{elpd}}_{\rm loo}\) (expected log predictive density), \(\widehat{p}_{\rm loo}\) (effective number of parameters), and \({\rm looic} =-2\, \widehat{\mbox{elpd}}_{\rm loo}\) (the LOO information criterion).

The line at the bottom of the printed output provides information about the reliability of the LOO approximation (the interpretation of the \(k\) parameter is explained in help('pareto-k-diagnostic') and in greater detail in Vehtari, Simpson, Gelman, Yao, and Gabry (2019)). In this case the message tells us that all of the estimates for \(k\) are fine.

Comparing models

To compare this model to an alternative model for the same data we can use the loo_compare function in the loo package. First we’ll fit a second model to the well-switching data, using log(arsenic) instead of arsenic as a predictor:

standata$X[, "arsenic"] <- log(standata$X[, "arsenic"])
fit_2 <- stan(fit = fit_1, data = standata) 

log_lik_2 <- extract_log_lik(fit_2, merge_chains = FALSE)
r_eff_2 <- relative_eff(exp(log_lik_2))
loo_2 <- loo(log_lik_2, r_eff = r_eff_2, cores = 2)
print(loo_2)
Computed from 4000 by 3020 log-likelihood matrix

         Estimate   SE
elpd_loo  -1952.3 16.2
p_loo         3.1  0.1
looic      3904.6 32.4
------
Monte Carlo SE of elpd_loo is 0.0.

All Pareto k estimates are good (k < 0.5).
See help('pareto-k-diagnostic') for details.

We can now compare the models on LOO using the loo_compare function:

# Compare
comp <- loo_compare(loo_1, loo_2)

This new object, comp, contains the estimated difference of expected leave-one-out prediction errors between the two models, along with the standard error:

print(comp) # can set simplify=FALSE for more detailed print output
       elpd_diff se_diff
model2   0.0       0.0  
model1 -16.3       4.4  

The first column shows the difference in ELPD relative to the model with the largest ELPD. In this case, the difference in elpd and its scale relative to the approximate standard error of the difference) indicates a preference for the second model (model2).

References

Gelman, A., and Hill, J. (2007). Data Analysis Using Regression and Multilevel Hierarchical Models. Cambridge University Press.

Stan Development Team (2017). The Stan C++ Library, Version 2.17.0. https://mc-stan.org/

Stan Development Team (2018) RStan: the R interface to Stan, Version 2.17.3. https://mc-stan.org/

Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. Statistics and Computing. 27(5), 1413–1432. :10.1007/s11222-016-9696-4. online, arXiv preprint arXiv:1507.04544.

Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. arXiv preprint arXiv:1507.02646.

loo/inst/doc/loo2-lfo.html0000644000176200001440000155515014411464745015132 0ustar liggesusers Approximate leave-future-out cross-validation for Bayesian time series models

Approximate leave-future-out cross-validation for Bayesian time series models

Paul Bürkner, Jonah Gabry, Aki Vehtari

2023-03-30

Introduction

One of the most common goals of a time series analysis is to use the observed series to inform predictions for future observations. We will refer to this task of predicting a sequence of \(M\) future observations as \(M\)-step-ahead prediction (\(M\)-SAP). Fortunately, once we have fit a model and can sample from the posterior predictive distribution, it is straightforward to generate predictions as far into the future as we want. It is also straightforward to evaluate the \(M\)-SAP performance of a time series model by comparing the predictions to the observed sequence of \(M\) future data points once they become available.

Unfortunately, we are often in the position of having to use a model to inform decisions before we can collect the future observations required for assessing the predictive performance. If we have many competing models we may also need to first decide which of the models (or which combination of the models) we should rely on for predictions. In these situations the best we can do is to use methods for approximating the expected predictive performance of our models using only the observations of the time series we already have.

If there were no time dependence in the data or if the focus is to assess the non-time-dependent part of the model, we could use methods like leave-one-out cross-validation (LOO-CV). For a data set with \(N\) observations, we refit the model \(N\) times, each time leaving out one of the \(N\) observations and assessing how well the model predicts the left-out observation. LOO-CV is very expensive computationally in most realistic settings, but the Pareto smoothed importance sampling (PSIS, Vehtari et al, 2017, 2019) algorithm provided by the loo package allows for approximating exact LOO-CV with PSIS-LOO-CV. PSIS-LOO-CV requires only a single fit of the full model and comes with diagnostics for assessing the validity of the approximation.

With a time series we can do something similar to LOO-CV but, except in a few cases, it does not make sense to leave out observations one at a time because then we are allowing information from the future to influence predictions of the past (i.e., times \(t + 1, t+2, \ldots\) should not be used to predict for time \(t\)). To apply the idea of cross-validation to the \(M\)-SAP case, instead of leave-one-out cross-validation we need some form of leave-future-out cross-validation (LFO-CV). As we will demonstrate in this case study, LFO-CV does not refer to one particular prediction task but rather to various possible cross-validation approaches that all involve some form of prediction for new time series data. Like exact LOO-CV, exact LFO-CV requires refitting the model many times to different subsets of the data, which is computationally very costly for most nontrivial examples, in particular for Bayesian analyses where refitting the model means estimating a new posterior distribution rather than a point estimate.

Although PSIS-LOO-CV provides an efficient approximation to exact LOO-CV, until now there has not been an analogous approximation to exact LFO-CV that drastically reduces the computational burden while also providing informative diagnostics about the quality of the approximation. In this case study we present PSIS-LFO-CV, an algorithm that typically only requires refitting the time-series model a small number times and will make LFO-CV tractable for many more realistic applications than previously possible.

More details can be found in our paper about approximate LFO-CV (Bürkner, Gabry, & Vehtari, 2020), which is available as a preprint on arXiv (https://arxiv.org/abs/1902.06281).

\(M\)-step-ahead predictions

Assume we have a time series of observations \(y = (y_1, y_2, \ldots, y_N)\) and let \(L\) be the minimum number of observations from the series that we will require before making predictions for future data. Depending on the application and how informative the data is, it may not be possible to make reasonable predictions for \(y_{i+1}\) based on \((y_1, \dots, y_{i})\) until \(i\) is large enough so that we can learn enough about the time series to predict future observations. Setting \(L=10\), for example, means that we will only assess predictive performance starting with observation \(y_{11}\), so that we always have at least 10 previous observations to condition on.

In order to assess \(M\)-SAP performance we would like to compute the predictive densities

\[ p(y_{i+1:M} \,|\, y_{1:i}) = p(y_{i+1}, \ldots, y_{i + M} \,|\, y_{1},...,y_{i}) \]

for each \(i \in \{L, \ldots, N - M\}\). The quantities \(p(y_{i+1:M} \,|\, y_{1:i})\) can be computed with the help of the posterior distribution \(p(\theta \,|\, y_{1:i})\) of the parameters \(\theta\) conditional on only the first \(i\) observations of the time-series:

\[ p(y_{i+1:M} \,| \, y_{1:i}) = \int p(y_{i+1:M} \,| \, y_{1:i}, \theta) \, p(\theta\,|\,y_{1:i}) \,d\theta. \]

Having obtained \(S\) draws \((\theta_{1:i}^{(1)}, \ldots, \theta_{1:i}^{(S)})\) from the posterior distribution \(p(\theta\,|\,y_{1:i})\), we can estimate \(p(y_{i+1:M} | y_{1:i})\) as

\[ p(y_{i+1:M} \,|\, y_{1:i}) \approx \frac{1}{S}\sum_{s=1}^S p(y_{i+1:M} \,|\, y_{1:i}, \theta_{1:i}^{(s)}). \]

Approximate \(M\)-SAP using importance-sampling

Unfortunately, the math above makes use of the posterior distributions from many different fits of the model to different subsets of the data. That is, to obtain the predictive density \(p(y_{i+1:M} \,|\, y_{1:i})\) requires fitting a model to only the first \(i\) data points, and we will need to do this for every value of \(i\) under consideration (all \(i \in \{L, \ldots, N - M\}\)).

To reduce the number of models that need to be fit for the purpose of obtaining each of the densities \(p(y_{i+1:M} \,|\, y_{1:i})\), we propose the following algorithm. First, we refit the model using the first \(L\) observations of the time series and then perform a single exact \(M\)-step-ahead prediction step for \(p(y_{L+1:M} \,|\, y_{1:L})\). Recall that \(L\) is the minimum number of observations we have deemed acceptable for making predictions (setting \(L=0\) means the first data point will be predicted only based on the prior). We define \(i^\star = L\) as the current point of refit. Next, starting with \(i = i^\star + 1\), we approximate each \(p(y_{i+1:M} \,|\, y_{1:i})\) via

\[ p(y_{i+1:M} \,|\, y_{1:i}) \approx \frac{ \sum_{s=1}^S w_i^{(s)}\, p(y_{i+1:M} \,|\, y_{1:i}, \theta^{(s)})} { \sum_{s=1}^S w_i^{(s)}}, \]

where \(\theta^{(s)} = \theta^{(s)}_{1:i^\star}\) are draws from the posterior distribution based on the first \(i^\star\) observations and \(w_i^{(s)}\) are the PSIS weights obtained in two steps. First, we compute the raw importance ratios

\[ r_i^{(s)} = \frac{f_{1:i}(\theta^{(s)})}{f_{1:i^\star}(\theta^{(s)})} \propto \prod_{j \in (i^\star + 1):i} p(y_j \,|\, y_{1:(j-1)}, \theta^{(s)}), \]

and then stabilize them using PSIS. The function \(f_{1:i}\) denotes the posterior distribution based on the first \(i\) observations, that is, \(f_{1:i} = p(\theta \,|\, y_{1:i})\), with \(f_{1:i^\star}\) defined analogously. The index set \((i^\star + 1):i\) indicates all observations which are part of the data for the model \(f_{1:i}\) whose predictive performance we are trying to approximate but not for the actually fitted model \(f_{1:i^\star}\). The proportional statement arises from the fact that we ignore the normalizing constants \(p(y_{1:i})\) and \(p(y_{1:i^\star})\) of the compared posteriors, which leads to a self-normalized variant of PSIS (see Vehtari et al, 2017).

Continuing with the next observation, we gradually increase \(i\) by \(1\) (we move forward in time) and repeat the process. At some observation \(i\), the variability of the importance ratios \(r_i^{(s)}\) will become too large and importance sampling will fail. We will refer to this particular value of \(i\) as \(i^\star_1\). To identify the value of \(i^\star_1\), we check for which value of \(i\) does the estimated shape parameter \(k\) of the generalized Pareto distribution first cross a certain threshold \(\tau\) (Vehtari et al, 2019). Only then do we refit the model using the observations up to \(i^\star_1\) and restart the process from there by setting \(\theta^{(s)} = \theta^{(s)}_{1:i^\star_1}\) and \(i^\star = i^\star_1\) until the next refit.

In some cases we may only need to refit once and in other cases we will find a value \(i^\star_2\) that requires a second refitting, maybe an \(i^\star_3\) that requires a third refitting, and so on. We refit as many times as is required (only when \(k > \tau\)) until we arrive at observation \(i = N - M\). For LOO, we recommend to use a threshold of \(\tau = 0.7\) (Vehtari et al, 2017, 2019) and it turns out this is a reasonable threshold for LFO as well (Bürkner et al. 2020).

Autoregressive models

Autoregressive (AR) models are some of the most commonly used time-series models. An AR(p) model —an autoregressive model of order \(p\)— can be defined as

\[ y_i = \eta_i + \sum_{k = 1}^p \varphi_k y_{i - k} + \varepsilon_i, \]

where \(\eta_i\) is the linear predictor for the \(i\)th observation, \(\phi_k\) are the autoregressive parameters and \(\varepsilon_i\) are pairwise independent errors, which are usually assumed to be normally distributed with equal variance \(\sigma^2\). The model implies a recursive formula that allows for computing the right-hand side of the above equation for observation \(i\) based on the values of the equations for previous observations.

Case Study: Annual measurements of the level of Lake Huron

To illustrate the application of PSIS-LFO-CV for estimating expected \(M\)-SAP performance, we will fit a model for 98 annual measurements of the water level (in feet) of Lake Huron from the years 1875–1972. This data set is found in the datasets R package, which is installed automatically with R.

In addition to the loo package, for this analysis we will use the brms interface to Stan to generate a Stan program and fit the model, and also the bayesplot and ggplot2 packages for plotting.

library("loo")
library("brms")
library("bayesplot")
library("ggplot2")
color_scheme_set("brightblue")
theme_set(theme_default())

CHAINS <- 4
SEED <- 5838296
set.seed(SEED)

Before fitting a model, we will first put the data into a data frame and then look at the time series.

N <- length(LakeHuron)
df <- data.frame(
  y = as.numeric(LakeHuron),
  year = as.numeric(time(LakeHuron)),
  time = 1:N
)

ggplot(df, aes(x = year, y = y)) + 
  geom_point(size = 1) +
  labs(
    y = "Water Level (ft)", 
    x = "Year",
    title = "Water Level in Lake Huron (1875-1972)"
  ) 

The above plot shows rather strong autocorrelation of the time-series as well as some trend towards lower levels for later points in time.

We can specify an AR(4) model for these data using the brms package as follows:

fit <- brm(
  y ~ ar(time, p = 4), 
  data = df, 
  prior = prior(normal(0, 0.5), class = "ar"),
  control = list(adapt_delta = 0.99), 
  seed = SEED, 
  chains = CHAINS
)

The model implied predictions along with the observed values can be plotted, which reveals a rather good fit to the data.

preds <- posterior_predict(fit)
preds <- cbind(
  Estimate = colMeans(preds), 
  Q5 = apply(preds, 2, quantile, probs = 0.05),
  Q95 = apply(preds, 2, quantile, probs = 0.95)
)

ggplot(cbind(df, preds), aes(x = year, y = Estimate)) +
  geom_smooth(aes(ymin = Q5, ymax = Q95), stat = "identity", size = 0.5) +
  geom_point(aes(y = y)) + 
  labs(
    y = "Water Level (ft)", 
    x = "Year",
    title = "Water Level in Lake Huron (1875-1972)",
    subtitle = "Mean (blue) and 90% predictive intervals (gray) vs. observed data (black)"
  ) 

To allow for reasonable predictions of future values, we will require at least \(L = 20\) historical observations (20 years) to make predictions.

L <- 20

We first perform approximate leave-one-out cross-validation (LOO-CV) for the purpose of later comparison with exact and approximate LFO-CV for the 1-SAP case.

loo_cv <- loo(log_lik(fit)[, (L + 1):N])
print(loo_cv)

Computed from 4000 by 78 log-likelihood matrix

         Estimate   SE
elpd_loo    -88.6  6.4
p_loo         4.8  1.0
looic       177.2 12.8
------
Monte Carlo SE of elpd_loo is 0.0.

All Pareto k estimates are good (k < 0.5).
See help('pareto-k-diagnostic') for details.

1-step-ahead predictions leaving out all future values

The most basic version of \(M\)-SAP is 1-SAP, in which we predict only one step ahead. In this case, \(y_{i+1:M}\) simplifies to \(y_{i}\) and the LFO-CV algorithm becomes considerably simpler than for larger values of \(M\).

Exact 1-step-ahead predictions

Before we compute approximate LFO-CV using PSIS we will first compute exact LFO-CV for the 1-SAP case so we can use it as a benchmark later. The initial step for the exact computation is to calculate the log-predictive densities by refitting the model many times:

loglik_exact <- matrix(nrow = nsamples(fit), ncol = N)
for (i in L:(N - 1)) {
  past <- 1:i
  oos <- i + 1
  df_past <- df[past, , drop = FALSE]
  df_oos <- df[c(past, oos), , drop = FALSE]
  fit_i <- update(fit, newdata = df_past, recompile = FALSE)
  loglik_exact[, i + 1] <- log_lik(fit_i, newdata = df_oos, oos = oos)[, oos]
}

Then we compute the exact expected log predictive density (ELPD):

# some helper functions we'll use throughout

# more stable than log(sum(exp(x))) 
log_sum_exp <- function(x) {
  max_x <- max(x)  
  max_x + log(sum(exp(x - max_x)))
}

# more stable than log(mean(exp(x)))
log_mean_exp <- function(x) {
  log_sum_exp(x) - log(length(x))
}

# compute log of raw importance ratios
# sums over observations *not* over posterior samples
sum_log_ratios <- function(loglik, ids = NULL) {
  if (!is.null(ids)) loglik <- loglik[, ids, drop = FALSE]
  rowSums(loglik)
}

# for printing comparisons later
rbind_print <- function(...) {
  round(rbind(...), digits = 2)
}
exact_elpds_1sap <- apply(loglik_exact, 2, log_mean_exp)
exact_elpd_1sap <- c(ELPD = sum(exact_elpds_1sap[-(1:L)]))

rbind_print(
  "LOO" = loo_cv$estimates["elpd_loo", "Estimate"],
  "LFO" = exact_elpd_1sap
)
      ELPD
LOO -88.61
LFO -92.49

We see that the ELPD from LFO-CV for 1-step-ahead predictions is lower than the ELPD estimate from LOO-CV, which should be expected since LOO-CV is making use of more of the time series. That is, since the LFO-CV approach only uses observations from before the left-out data point but LOO-CV uses all data points other than the left-out observation, we should expect to see the larger ELPD from LOO-CV.

Approximate 1-step-ahead predictions

We compute approximate 1-SAP with refit at observations where the Pareto \(k\) estimate exceeds the threshold of \(0.7\).

k_thres <- 0.7

The code becomes a little bit more involved as compared to the exact LFO-CV. Note that we can compute exact 1-SAP at the refitting points, which comes with no additional computational costs since we had to refit the model anyway.

approx_elpds_1sap <- rep(NA, N)

# initialize the process for i = L
past <- 1:L
oos <- L + 1
df_past <- df[past, , drop = FALSE]
df_oos <- df[c(past, oos), , drop = FALSE]
fit_past <- update(fit, newdata = df_past, recompile = FALSE)
loglik <- log_lik(fit_past, newdata = df_oos, oos = oos)
approx_elpds_1sap[L + 1] <- log_mean_exp(loglik[, oos])

# iterate over i > L
i_refit <- L
refits <- L
ks <- NULL
for (i in (L + 1):(N - 1)) {
  past <- 1:i
  oos <- i + 1
  df_past <- df[past, , drop = FALSE]
  df_oos <- df[c(past, oos), , drop = FALSE]
  loglik <- log_lik(fit_past, newdata = df_oos, oos = oos)
  
  logratio <- sum_log_ratios(loglik, (i_refit + 1):i)
  psis_obj <- suppressWarnings(psis(logratio))
  k <- pareto_k_values(psis_obj)
  ks <- c(ks, k)
  if (k > k_thres) {
    # refit the model based on the first i observations
    i_refit <- i
    refits <- c(refits, i)
    fit_past <- update(fit_past, newdata = df_past, recompile = FALSE)
    loglik <- log_lik(fit_past, newdata = df_oos, oos = oos)
    approx_elpds_1sap[i + 1] <- log_mean_exp(loglik[, oos])
  } else {
    lw <- weights(psis_obj, normalize = TRUE)[, 1]
    approx_elpds_1sap[i + 1] <- log_sum_exp(lw + loglik[, oos])
  }
} 

We see that the final Pareto-\(k\)-estimates are mostly well below the threshold and that we only needed to refit the model a few times:

plot_ks <- function(ks, ids, thres = 0.6) {
  dat_ks <- data.frame(ks = ks, ids = ids)
  ggplot(dat_ks, aes(x = ids, y = ks)) + 
    geom_point(aes(color = ks > thres), shape = 3, show.legend = FALSE) + 
    geom_hline(yintercept = thres, linetype = 2, color = "red2") + 
    scale_color_manual(values = c("cornflowerblue", "darkblue")) + 
    labs(x = "Data point", y = "Pareto k") + 
    ylim(-0.5, 1.5)
}
cat("Using threshold ", k_thres, 
    ", model was refit ", length(refits), 
    " times, at observations", refits)
Using threshold  0.7 , model was refit  3  times, at observations 20 43 84
plot_ks(ks, (L + 1):(N - 1))

The approximate 1-SAP ELPD is remarkably similar to the exact 1-SAP ELPD computed above, which indicates our algorithm to compute approximate 1-SAP worked well for the present data and model.

approx_elpd_1sap <- sum(approx_elpds_1sap, na.rm = TRUE)
rbind_print(
  "approx LFO" = approx_elpd_1sap,
  "exact LFO" = exact_elpd_1sap
)
             ELPD
approx LFO -92.88
exact LFO  -92.49

Plotting exact against approximate predictions, we see that no approximation value deviates far from its exact counterpart, providing further evidence for the good quality of our approximation.

dat_elpd <- data.frame(
  approx_elpd = approx_elpds_1sap,
  exact_elpd = exact_elpds_1sap
)

ggplot(dat_elpd, aes(x = approx_elpd, y = exact_elpd)) +
  geom_abline(color = "gray30") +
  geom_point(size = 2) +
  labs(x = "Approximate ELPDs", y = "Exact ELPDs")

We can also look at the maximum difference and average difference between the approximate and exact ELPD calculations, which also indicate a ver close approximation:

max_diff <- with(dat_elpd, max(abs(approx_elpd - exact_elpd), na.rm = TRUE))
mean_diff <- with(dat_elpd, mean(abs(approx_elpd - exact_elpd), na.rm = TRUE))

rbind_print(
  "Max diff" = round(max_diff, 2), 
  "Mean diff" =  round(mean_diff, 3)
)
          [,1]
Max diff  0.14
Mean diff 0.01

\(M\)-step-ahead predictions leaving out all future values

To illustrate the application of \(M\)-SAP for \(M > 1\), we next compute exact and approximate LFO-CV for the 4-SAP case.

Exact \(M\)-step-ahead predictions

The necessary steps are the same as for 1-SAP with the exception that the log-density values of interest are now the sums of the log predictive densities of four consecutive observations. Further, the stability of the PSIS approximation actually stays the same for all \(M\) as it only depends on the number of observations we leave out, not on the number of observations we predict.

M <- 4
loglikm <- matrix(nrow = nsamples(fit), ncol = N)
for (i in L:(N - M)) {
  past <- 1:i
  oos <- (i + 1):(i + M)
  df_past <- df[past, , drop = FALSE]
  df_oos <- df[c(past, oos), , drop = FALSE]
  fit_past <- update(fit, newdata = df_past, recompile = FALSE)
  loglik <- log_lik(fit_past, newdata = df_oos, oos = oos)
  loglikm[, i + 1] <- rowSums(loglik[, oos])
}
exact_elpds_4sap <- apply(loglikm, 2, log_mean_exp)
(exact_elpd_4sap <- c(ELPD = sum(exact_elpds_4sap, na.rm = TRUE)))
     ELPD 
-405.4043 

Approximate \(M\)-step-ahead predictions

Computing the approximate PSIS-LFO-CV for the 4-SAP case is a little bit more involved than the approximate version for the 1-SAP case, although the underlying principles remain the same.

approx_elpds_4sap <- rep(NA, N)

# initialize the process for i = L
past <- 1:L
oos <- (L + 1):(L + M)
df_past <- df[past, , drop = FALSE]
df_oos <- df[c(past, oos), , drop = FALSE]
fit_past <- update(fit, newdata = df_past, recompile = FALSE)
loglik <- log_lik(fit_past, newdata = df_oos, oos = oos)
loglikm <- rowSums(loglik[, oos])
approx_elpds_1sap[L + 1] <- log_mean_exp(loglikm)

# iterate over i > L
i_refit <- L
refits <- L
ks <- NULL
for (i in (L + 1):(N - M)) {
  past <- 1:i
  oos <- (i + 1):(i + M)
  df_past <- df[past, , drop = FALSE]
  df_oos <- df[c(past, oos), , drop = FALSE]
  loglik <- log_lik(fit_past, newdata = df_oos, oos = oos)
  
  logratio <- sum_log_ratios(loglik, (i_refit + 1):i)
  psis_obj <- suppressWarnings(psis(logratio))
  k <- pareto_k_values(psis_obj)
  ks <- c(ks, k)
  if (k > k_thres) {
    # refit the model based on the first i observations
    i_refit <- i
    refits <- c(refits, i)
    fit_past <- update(fit_past, newdata = df_past, recompile = FALSE)
    loglik <- log_lik(fit_past, newdata = df_oos, oos = oos)
    loglikm <- rowSums(loglik[, oos])
    approx_elpds_4sap[i + 1] <- log_mean_exp(loglikm)
  } else {
    lw <- weights(psis_obj, normalize = TRUE)[, 1]
    loglikm <- rowSums(loglik[, oos])
    approx_elpds_4sap[i + 1] <- log_sum_exp(lw + loglikm)
  }
} 

Again, we see that the final Pareto-\(k\)-estimates are mostly well below the threshold and that we only needed to refit the model a few times:

cat("Using threshold ", k_thres, 
    ", model was refit ", length(refits), 
    " times, at observations", refits)
Using threshold  0.7 , model was refit  3  times, at observations 20 46 82
plot_ks(ks, (L + 1):(N - M))

The approximate ELPD computed for the 4-SAP case is not as close to its exact counterpart as in the 1-SAP case. In general, the larger \(M\), the larger the variation of the approximate ELPD around the exact ELPD. It turns out that the ELPD estimates of AR-models with \(M>1\) show particular variation due to their predictions’ dependency on other predicted values. In Bürkner et al. (2020) we provide further explanation and simulations for these cases.

approx_elpd_4sap <- sum(approx_elpds_4sap, na.rm = TRUE)
rbind_print(
  "Approx LFO" = approx_elpd_4sap,
  "Exact LFO" = exact_elpd_4sap
)
              ELPD
Approx LFO -396.87
Exact LFO  -405.40

Plotting exact against approximate pointwise predictions confirms that, for a few specific data points, the approximate predictions underestimate the exact predictions.

dat_elpd_4sap <- data.frame(
  approx_elpd = approx_elpds_4sap,
  exact_elpd = exact_elpds_4sap
)

ggplot(dat_elpd_4sap, aes(x = approx_elpd, y = exact_elpd)) +
  geom_abline(color = "gray30") +
  geom_point(size = 2) +
  labs(x = "Approximate ELPDs", y = "Exact ELPDs")

Conclusion

In this case study we have shown how to do carry out exact and approximate leave-future-out cross-validation for \(M\)-step-ahead prediction tasks. For the data and model used in our example, the PSIS-LFO-CV algorithm provides reasonably stable and accurate results despite not requiring us to refit the model nearly as many times. For more details on approximate LFO-CV, we refer to Bürkner et al. (2020).


References

Bürkner P. C., Gabry J., & Vehtari A. (2020). Approximate leave-future-out cross-validation for time series models. Journal of Statistical Computation and Simulation, 90(14):2499-2523. :/10.1080/00949655.2020.1783262. Online. arXiv preprint.

Vehtari A., Gelman A., & Gabry J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. Statistics and Computing, 27(5), 1413–1432. :10.1007/s11222-016-9696-4. Online. arXiv preprint arXiv:1507.04544.

Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. arXiv preprint arXiv:1507.02646.


Appendix

Appendix: Session information

sessionInfo()
R version 4.2.2 (2022-10-31)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Big Sur ... 10.16

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/4.2/Resources/lib/libRblas.0.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.2/Resources/lib/libRlapack.dylib

locale:
[1] C/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] ggplot2_3.4.1           brms_2.18.0             bayesplot_1.10.0.9001  
[4] rstanarm_2.21.3         Rcpp_1.0.10             loo_2.6.0              
[7] rstan_2.31.0.9000       StanHeaders_2.31.0.9000 knitr_1.40             

loaded via a namespace (and not attached):
  [1] minqa_1.2.5          colorspace_2.1-0     ellipsis_0.3.2      
  [4] estimability_1.4.1   markdown_1.3         base64enc_0.1-3     
  [7] rstudioapi_0.14      farver_2.1.1         DT_0.26             
 [10] fansi_1.0.4          mvtnorm_1.1-3        bridgesampling_1.1-2
 [13] codetools_0.2-18     splines_4.2.2        cachem_1.0.6        
 [16] shinythemes_1.2.0    projpred_2.2.2       jsonlite_1.8.4      
 [19] nloptr_2.0.3         shiny_1.7.3          compiler_4.2.2      
 [22] emmeans_1.8.2        backports_1.4.1      Matrix_1.5-1        
 [25] fastmap_1.1.1        cli_3.6.0            later_1.3.0         
 [28] htmltools_0.5.3      prettyunits_1.1.1    tools_4.2.2         
 [31] igraph_1.3.5         coda_0.19-4          gtable_0.3.2        
 [34] glue_1.6.2           reshape2_1.4.4       dplyr_1.1.0         
 [37] posterior_1.4.1      V8_4.2.2             jquerylib_0.1.4     
 [40] vctrs_0.6.0          nlme_3.1-160         crosstalk_1.2.0     
 [43] tensorA_0.36.2       xfun_0.34            stringr_1.5.0       
 [46] ps_1.7.2             lme4_1.1-31          mime_0.12           
 [49] miniUI_0.1.1.1       lifecycle_1.0.3      gtools_3.9.3        
 [52] MASS_7.3-58.1        zoo_1.8-11           scales_1.2.1        
 [55] colourpicker_1.2.0   promises_1.2.0.1     Brobdingnag_1.2-9   
 [58] parallel_4.2.2       inline_0.3.19        shinystan_2.6.0     
 [61] gamm4_0.2-6          yaml_2.3.7           curl_5.0.0          
 [64] gridExtra_2.3        sass_0.4.2           stringi_1.7.12      
 [67] highr_0.10           dygraphs_1.1.1.6     checkmate_2.1.0     
 [70] boot_1.3-28          pkgbuild_1.4.0       rlang_1.1.0         
 [73] pkgconfig_2.0.3      matrixStats_0.63.0   distributional_0.3.1
 [76] evaluate_0.20        lattice_0.20-45      rstantools_2.3.1    
 [79] htmlwidgets_1.5.4    labeling_0.4.2       processx_3.8.0      
 [82] tidyselect_1.2.0     plyr_1.8.8           magrittr_2.0.3      
 [85] R6_2.5.1             generics_0.1.3       mgcv_1.8-41         
 [88] pillar_1.8.1         withr_2.5.0          xts_0.12.2          
 [91] survival_3.4-0       abind_1.4-5          tibble_3.2.0        
 [94] crayon_1.5.2         utf8_1.2.3           rmarkdown_2.18      
 [97] grid_4.2.2           callr_3.7.3          threejs_0.3.3       
[100] digest_0.6.30        xtable_1.8-4         httpuv_1.6.6        
[103] RcppParallel_5.1.7   stats4_4.2.2         munsell_0.5.0       
[106] bslib_0.4.1          shinyjs_2.1.0       

Appendix: Licenses

  • Code © 2018, Paul Bürkner, Jonah Gabry, Aki Vehtari (licensed under BSD-3).
  • Text © 2018, Paul Bürkner, Jonah Gabry, Aki Vehtari (licensed under CC-BY-NC 4.0).
loo/inst/doc/loo2-weights.R0000644000176200001440000001141614411465507015245 0ustar liggesusersparams <- list(EVAL = TRUE) ## ----SETTINGS-knitr, include=FALSE-------------------------------------------- stopifnot(require(knitr)) opts_chunk$set( comment=NA, eval = if (isTRUE(exists("params"))) params$EVAL else FALSE, dev = "png", dpi = 150, fig.asp = 0.618, fig.width = 5, out.width = "60%", fig.align = "center" ) ## ----setup, message=FALSE----------------------------------------------------- library(rstanarm) library(loo) ## ----data--------------------------------------------------------------------- data(milk) d <- milk[complete.cases(milk),] d$neocortex <- d$neocortex.perc /100 str(d) ## ----fits, results="hide"----------------------------------------------------- fit1 <- stan_glm(kcal.per.g ~ 1, data = d, seed = 2030) fit2 <- update(fit1, formula = kcal.per.g ~ neocortex) fit3 <- update(fit1, formula = kcal.per.g ~ log(mass)) fit4 <- update(fit1, formula = kcal.per.g ~ neocortex + log(mass)) ## ----waic--------------------------------------------------------------------- waic1 <- waic(fit1) waic2 <- waic(fit2) waic3 <- waic(fit3) waic4 <- waic(fit4) waics <- c( waic1$estimates["elpd_waic", 1], waic2$estimates["elpd_waic", 1], waic3$estimates["elpd_waic", 1], waic4$estimates["elpd_waic", 1] ) ## ----loo---------------------------------------------------------------------- # note: the loo function accepts a 'cores' argument that we recommend specifying # when working with bigger datasets loo1 <- loo(fit1) loo2 <- loo(fit2) loo3 <- loo(fit3) loo4 <- loo(fit4) lpd_point <- cbind( loo1$pointwise[,"elpd_loo"], loo2$pointwise[,"elpd_loo"], loo3$pointwise[,"elpd_loo"], loo4$pointwise[,"elpd_loo"] ) ## ----print-loo---------------------------------------------------------------- print(loo3) print(loo4) ## ----weights------------------------------------------------------------------ waic_wts <- exp(waics) / sum(exp(waics)) pbma_wts <- pseudobma_weights(lpd_point, BB=FALSE) pbma_BB_wts <- pseudobma_weights(lpd_point) # default is BB=TRUE stacking_wts <- stacking_weights(lpd_point) round(cbind(waic_wts, pbma_wts, pbma_BB_wts, stacking_wts), 2) ## ----waic_wts_demo------------------------------------------------------------ waic_wts_demo <- exp(waics[c(1,1,1,1,1,1,1,1,1,1,2,3,4)]) / sum(exp(waics[c(1,1,1,1,1,1,1,1,1,1,2,3,4)])) round(waic_wts_demo, 3) ## ----stacking_weights--------------------------------------------------------- stacking_weights(lpd_point[,c(1,1,1,1,1,1,1,1,1,1,2,3,4)]) ## ----Kline-------------------------------------------------------------------- data(Kline) d <- Kline d$log_pop <- log(d$population) d$contact_high <- ifelse(d$contact=="high", 1, 0) str(d) ## ----fit10, results="hide"---------------------------------------------------- fit10 <- stan_glm( total_tools ~ log_pop + contact_high + log_pop * contact_high, family = poisson(link = "log"), data = d, prior = normal(0, 1, autoscale = FALSE), prior_intercept = normal(0, 100, autoscale = FALSE), seed = 2030 ) ## ----loo10-------------------------------------------------------------------- loo10 <- loo(fit10) print(loo10) ## ----loo10-threshold---------------------------------------------------------- loo10 <- loo(fit10, k_threshold=0.7) print(loo10) ## ----waic10------------------------------------------------------------------- waic10 <- waic(fit10) print(waic10) ## ----contact_high, results="hide"--------------------------------------------- fit11 <- update(fit10, formula = total_tools ~ log_pop + contact_high) fit12 <- update(fit10, formula = total_tools ~ log_pop) ## ----loo-contact_high--------------------------------------------------------- (loo11 <- loo(fit11)) (loo12 <- loo(fit12)) ## ----relo-contact_high-------------------------------------------------------- loo11 <- loo(fit11, k_threshold=0.7) loo12 <- loo(fit12, k_threshold=0.7) lpd_point <- cbind( loo10$pointwise[, "elpd_loo"], loo11$pointwise[, "elpd_loo"], loo12$pointwise[, "elpd_loo"] ) ## ----waic-contact_high-------------------------------------------------------- waic11 <- waic(fit11) waic12 <- waic(fit12) waics <- c( waic10$estimates["elpd_waic", 1], waic11$estimates["elpd_waic", 1], waic12$estimates["elpd_waic", 1] ) ## ----weights-contact_high----------------------------------------------------- waic_wts <- exp(waics) / sum(exp(waics)) pbma_wts <- pseudobma_weights(lpd_point, BB=FALSE) pbma_BB_wts <- pseudobma_weights(lpd_point) # default is BB=TRUE stacking_wts <- stacking_weights(lpd_point) round(cbind(waic_wts, pbma_wts, pbma_BB_wts, stacking_wts), 2) ## ----loo_model_weights-------------------------------------------------------- # using list of loo objects loo_list <- list(loo10, loo11, loo12) loo_model_weights(loo_list) loo_model_weights(loo_list, method = "pseudobma") loo_model_weights(loo_list, method = "pseudobma", BB = FALSE) loo/inst/doc/loo2-large-data.R0000644000176200001440000001615214411455345015575 0ustar liggesusersparams <- list(EVAL = TRUE) ## ----SETTINGS-knitr, include=FALSE-------------------------------------------- stopifnot(require(knitr)) opts_chunk$set( comment=NA, eval = if (isTRUE(exists("params"))) params$EVAL else FALSE, dev = "png", dpi = 150, fig.asp = 0.618, fig.width = 5, out.width = "60%", fig.align = "center" ) ## ----setup, message=FALSE----------------------------------------------------- library("rstan") library("loo") set.seed(4711) ## ----llfun_logistic----------------------------------------------------------- # we'll add an argument log to toggle whether this is a log-likelihood or # likelihood function. this will be useful later in the vignette. llfun_logistic <- function(data_i, draws, log = TRUE) { x_i <- as.matrix(data_i[, which(grepl(colnames(data_i), pattern = "X")), drop=FALSE]) logit_pred <- draws %*% t(x_i) dbinom(x = data_i$y, size = 1, prob = 1/(1 + exp(-logit_pred)), log = log) } ## ---- eval=FALSE-------------------------------------------------------------- # # Prepare data # url <- "http://stat.columbia.edu/~gelman/arm/examples/arsenic/wells.dat" # wells <- read.table(url) # wells$dist100 <- with(wells, dist / 100) # X <- model.matrix(~ dist100 + arsenic, wells) # standata <- list(y = wells$switch, X = X, N = nrow(X), P = ncol(X)) # # # Compile # stan_mod <- stan_model("logistic.stan") # # # Fit model # fit_1 <- sampling(stan_mod, data = standata, seed = 4711) # print(fit_1, pars = "beta") ## ---- eval=FALSE-------------------------------------------------------------- # # used for draws argument to loo_i # parameter_draws_1 <- extract(fit_1)$beta # # # used for data argument to loo_i # stan_df_1 <- as.data.frame(standata) # # # compute relative efficiency (this is slow and optional but is recommended to allow # # for adjusting PSIS effective sample size based on MCMC effective sample size) # r_eff <- relative_eff(llfun_logistic, # log = FALSE, # relative_eff wants likelihood not log-likelihood values # chain_id = rep(1:4, each = 1000), # data = stan_df_1, # draws = parameter_draws_1, # cores = 2) # # loo_i(i = 1, llfun_logistic, r_eff = r_eff, data = stan_df_1, draws = parameter_draws_1) ## ---- eval=FALSE-------------------------------------------------------------- # set.seed(4711) # loo_ss_1 <- # loo_subsample( # llfun_logistic, # observations = 100, # take a subsample of size 100 # cores = 2, # # these next objects were computed above # r_eff = r_eff, # draws = parameter_draws_1, # data = stan_df_1 # ) # print(loo_ss_1) ## ---- eval=FALSE-------------------------------------------------------------- # set.seed(4711) # loo_ss_1b <- # update( # loo_ss_1, # observations = 200, # subsample 200 instead of 100 # r_eff = r_eff, # draws = parameter_draws_1, # data = stan_df_1 # ) # print(loo_ss_1b) ## ---- eval=FALSE-------------------------------------------------------------- # set.seed(4711) # loo_ss_1c <- # loo_subsample( # x = llfun_logistic, # r_eff = r_eff, # draws = parameter_draws_1, # data = stan_df_1, # observations = 100, # estimator = "hh_pps", # use Hansen-Hurwitz # loo_approximation = "lpd", # use lpd instead of plpd # loo_approximation_draws = 100, # cores = 2 # ) # print(loo_ss_1c) ## ---- eval=FALSE-------------------------------------------------------------- # fit_laplace <- optimizing(stan_mod, data = standata, draws = 2000, # importance_resampling = TRUE) # parameter_draws_laplace <- fit_laplace$theta_tilde # draws from approximate posterior # log_p <- fit_laplace$log_p # log density of the posterior # log_g <- fit_laplace$log_g # log density of the approximation ## ---- eval=FALSE-------------------------------------------------------------- # set.seed(4711) # loo_ap_1 <- # loo_approximate_posterior( # x = llfun_logistic, # draws = parameter_draws_laplace, # data = stan_df_1, # log_p = log_p, # log_g = log_g, # cores = 2 # ) # print(loo_ap_1) ## ---- eval=FALSE-------------------------------------------------------------- # set.seed(4711) # loo_ap_ss_1 <- # loo_subsample( # x = llfun_logistic, # draws = parameter_draws_laplace, # data = stan_df_1, # log_p = log_p, # log_g = log_g, # observations = 100, # cores = 2 # ) # print(loo_ap_ss_1) ## ---- eval=FALSE-------------------------------------------------------------- # standata$X[, "arsenic"] <- log(standata$X[, "arsenic"]) # fit_2 <- sampling(stan_mod, data = standata) # parameter_draws_2 <- extract(fit_2)$beta # stan_df_2 <- as.data.frame(standata) # # # recompute subsampling loo for first model for demonstration purposes # # # compute relative efficiency (this is slow and optional but is recommended to allow # # for adjusting PSIS effective sample size based on MCMC effective sample size) # r_eff_1 <- relative_eff( # llfun_logistic, # log = FALSE, # relative_eff wants likelihood not log-likelihood values # chain_id = rep(1:4, each = 1000), # data = stan_df_1, # draws = parameter_draws_1, # cores = 2 # ) # # set.seed(4711) # loo_ss_1 <- loo_subsample( # x = llfun_logistic, # r_eff = r_eff_1, # draws = parameter_draws_1, # data = stan_df_1, # observations = 200, # cores = 2 # ) # # # compute subsampling loo for a second model (with log-arsenic) # # r_eff_2 <- relative_eff( # llfun_logistic, # log = FALSE, # relative_eff wants likelihood not log-likelihood values # chain_id = rep(1:4, each = 1000), # data = stan_df_2, # draws = parameter_draws_2, # cores = 2 # ) # loo_ss_2 <- loo_subsample( # x = llfun_logistic, # r_eff = r_eff_2, # draws = parameter_draws_2, # data = stan_df_2, # observations = 200, # cores = 2 # ) # # print(loo_ss_2) ## ---- eval=FALSE-------------------------------------------------------------- # # Compare # comp <- loo_compare(loo_ss_1, loo_ss_2) # print(comp) ## ---- eval=FALSE-------------------------------------------------------------- # loo_ss_2 <- # loo_subsample( # x = llfun_logistic, # r_eff = r_eff_2, # draws = parameter_draws_2, # data = stan_df_2, # observations = loo_ss_1, # cores = 2 # ) ## ---- eval=FALSE-------------------------------------------------------------- # idx <- obs_idx(loo_ss_1) # loo_ss_2 <- loo_subsample( # x = llfun_logistic, # r_eff = r_eff_2, # draws = parameter_draws_2, # data = stan_df_2, # observations = idx, # cores = 2 # ) ## ---- eval=FALSE-------------------------------------------------------------- # comp <- loo_compare(loo_ss_1, loo_ss_2) # print(comp) ## ---- eval=FALSE-------------------------------------------------------------- # # use loo() instead of loo_subsample() to compute full PSIS-LOO for model 2 # loo_full_2 <- loo( # x = llfun_logistic, # r_eff = r_eff_2, # draws = parameter_draws_2, # data = stan_df_2, # cores = 2 # ) # loo_compare(loo_ss_1, loo_full_2) loo/inst/doc/loo2-mixis.R0000644000176200001440000001034514411465131014715 0ustar liggesusersparams <- list(EVAL = TRUE) ## ----SETTINGS-knitr, include=FALSE-------------------------------------------- stopifnot(require(knitr)) opts_chunk$set( comment=NA, eval = if (isTRUE(exists("params"))) params$EVAL else FALSE, dev = "png", dpi = 150, fig.asp = 0.618, fig.width = 5, out.width = "60%", fig.align = "center" ) ## ---- warnings=FALSE, message=FALSE------------------------------------------- library("rstan") library("loo") library("matrixStats") options(mc.cores = parallel::detectCores(), parallel=FALSE) set.seed(24877) ## ----stancode_horseshoe------------------------------------------------------- stancode_horseshoe <- " data { int n; int p; int y[n]; matrix [n,p] X; real scale_global; int mixis; } transformed data { real nu_global=1; // degrees of freedom for the half-t priors for tau real nu_local=1; // degrees of freedom for the half-t priors for lambdas // (nu_local = 1 corresponds to the horseshoe) real slab_scale=2;// for the regularized horseshoe real slab_df=100; // for the regularized horseshoe } parameters { vector[p] z; // for non-centered parameterization real tau; // global shrinkage parameter vector [p] lambda; // local shrinkage parameter real caux; } transformed parameters { vector[p] beta; { vector[p] lambda_tilde; // 'truncated' local shrinkage parameter real c = slab_scale * sqrt(caux); // slab scale lambda_tilde = sqrt( c^2 * square(lambda) ./ (c^2 + tau^2*square(lambda))); beta = z .* lambda_tilde*tau; } } model { vector[n] means=X*beta; vector[n] log_lik; target += std_normal_lpdf(z); target += student_t_lpdf(lambda | nu_local, 0, 1); target += student_t_lpdf(tau | nu_global, 0, scale_global); target += inv_gamma_lpdf(caux | 0.5*slab_df, 0.5*slab_df); for (index in 1:n) { log_lik[index]= bernoulli_logit_lpmf(y[index] | means[index]); } target += sum(log_lik); if (mixis) { target += log_sum_exp(-log_lik); } } generated quantities { vector[n] means=X*beta; vector[n] log_lik; for (index in 1:n) { log_lik[index] = bernoulli_logit_lpmf(y[index] | means[index]); } } " ## ---- results='hide', warning=FALSE, message=FALSE, error=FALSE--------------- data(voice) y <- voice$y X <- voice[2:length(voice)] n <- dim(X)[1] p <- dim(X)[2] p0 <- 10 scale_global <- 2*p0/(p-p0)/sqrt(n-1) standata <- list(n = n, p = p, X = as.matrix(X), y = c(y), scale_global = scale_global, mixis = 0) ## ---- results='hide', warning=FALSE------------------------------------------- chains <- 4 n_iter <- 2000 warm_iter <- 1000 stanmodel <- stan_model(model_code = stancode_horseshoe) fit_post <- sampling(stanmodel, data = standata, chains = chains, iter = n_iter, warmup = warm_iter, refresh = 0) loo_post <-loo(fit_post) ## ----------------------------------------------------------------------------- print(loo_post) ## ---- results='hide', warnings=FALSE------------------------------------------ standata$mixis <- 1 fit_mix <- sampling(stanmodel, data = standata, chains = chains, iter = n_iter, warmup = warm_iter, refresh = 0, pars = "log_lik") log_lik_mix <- extract(fit_mix)$log_lik ## ----------------------------------------------------------------------------- l_common_mix <- rowLogSumExps(-log_lik_mix) log_weights <- -log_lik_mix - l_common_mix elpd_mixis <- logSumExp(-l_common_mix) - rowLogSumExps(t(log_weights)) ## ----------------------------------------------------------------------------- data(voice_loo) elpd_loo <- voice_loo$elpd_loo ## ----------------------------------------------------------------------------- elpd_psis <- loo_post$pointwise[,1] print(paste("RMSE(PSIS) =",round( sqrt(mean((elpd_loo-elpd_psis)^2)) ,2))) print(paste("RMSE(MixIS) =",round( sqrt(mean((elpd_loo-elpd_mixis)^2)) ,2))) ## ----------------------------------------------------------------------------- elpd_psis <- loo_post$pointwise[,1] print(paste("ELPD (PSIS)=",round(sum(elpd_psis),2))) print(paste("ELPD (MixIS)=",round(sum(elpd_mixis),2))) print(paste("ELPD (brute force)=",round(sum(elpd_loo),2))) loo/inst/doc/loo2-lfo.Rmd0000644000176200001440000006042614407123455014677 0ustar liggesusers--- title: "Approximate leave-future-out cross-validation for Bayesian time series models" author: "Paul Bürkner, Jonah Gabry, Aki Vehtari" date: "`r Sys.Date()`" output: html_vignette: toc: yes encoding: "UTF-8" params: EVAL: !r identical(Sys.getenv("NOT_CRAN"), "true") --- ```{r settings, child="children/SETTINGS-knitr.txt"} ``` ```{r more-knitr-ops, include=FALSE} knitr::opts_chunk$set( cache = TRUE, message = FALSE, warning = FALSE ) ``` ```{r, child="children/SEE-ONLINE.txt", eval = if (isTRUE(exists("params"))) !params$EVAL else TRUE} ``` ## Introduction One of the most common goals of a time series analysis is to use the observed series to inform predictions for future observations. We will refer to this task of predicting a sequence of $M$ future observations as $M$-step-ahead prediction ($M$-SAP). Fortunately, once we have fit a model and can sample from the posterior predictive distribution, it is straightforward to generate predictions as far into the future as we want. It is also straightforward to evaluate the $M$-SAP performance of a time series model by comparing the predictions to the observed sequence of $M$ future data points once they become available. Unfortunately, we are often in the position of having to use a model to inform decisions _before_ we can collect the future observations required for assessing the predictive performance. If we have many competing models we may also need to first decide which of the models (or which combination of the models) we should rely on for predictions. In these situations the best we can do is to use methods for approximating the expected predictive performance of our models using only the observations of the time series we already have. If there were no time dependence in the data or if the focus is to assess the non-time-dependent part of the model, we could use methods like leave-one-out cross-validation (LOO-CV). For a data set with $N$ observations, we refit the model $N$ times, each time leaving out one of the $N$ observations and assessing how well the model predicts the left-out observation. LOO-CV is very expensive computationally in most realistic settings, but the Pareto smoothed importance sampling (PSIS, Vehtari et al, 2017, 2019) algorithm provided by the *loo* package allows for approximating exact LOO-CV with PSIS-LOO-CV. PSIS-LOO-CV requires only a single fit of the full model and comes with diagnostics for assessing the validity of the approximation. With a time series we can do something similar to LOO-CV but, except in a few cases, it does not make sense to leave out observations one at a time because then we are allowing information from the future to influence predictions of the past (i.e., times $t + 1, t+2, \ldots$ should not be used to predict for time $t$). To apply the idea of cross-validation to the $M$-SAP case, instead of leave-*one*-out cross-validation we need some form of leave-*future*-out cross-validation (LFO-CV). As we will demonstrate in this case study, LFO-CV does not refer to one particular prediction task but rather to various possible cross-validation approaches that all involve some form of prediction for new time series data. Like exact LOO-CV, exact LFO-CV requires refitting the model many times to different subsets of the data, which is computationally very costly for most nontrivial examples, in particular for Bayesian analyses where refitting the model means estimating a new posterior distribution rather than a point estimate. Although PSIS-LOO-CV provides an efficient approximation to exact LOO-CV, until now there has not been an analogous approximation to exact LFO-CV that drastically reduces the computational burden while also providing informative diagnostics about the quality of the approximation. In this case study we present PSIS-LFO-CV, an algorithm that typically only requires refitting the time-series model a small number times and will make LFO-CV tractable for many more realistic applications than previously possible. More details can be found in our paper about approximate LFO-CV (Bürkner, Gabry, & Vehtari, 2020), which is available as a preprint on arXiv (https://arxiv.org/abs/1902.06281). ## $M$-step-ahead predictions Assume we have a time series of observations $y = (y_1, y_2, \ldots, y_N)$ and let $L$ be the _minimum_ number of observations from the series that we will require before making predictions for future data. Depending on the application and how informative the data is, it may not be possible to make reasonable predictions for $y_{i+1}$ based on $(y_1, \dots, y_{i})$ until $i$ is large enough so that we can learn enough about the time series to predict future observations. Setting $L=10$, for example, means that we will only assess predictive performance starting with observation $y_{11}$, so that we always have at least 10 previous observations to condition on. In order to assess $M$-SAP performance we would like to compute the predictive densities $$ p(y_{i+1:M} \,|\, y_{1:i}) = p(y_{i+1}, \ldots, y_{i + M} \,|\, y_{1},...,y_{i}) $$ for each $i \in \{L, \ldots, N - M\}$. The quantities $p(y_{i+1:M} \,|\, y_{1:i})$ can be computed with the help of the posterior distribution $p(\theta \,|\, y_{1:i})$ of the parameters $\theta$ conditional on only the first $i$ observations of the time-series: $$ p(y_{i+1:M} \,| \, y_{1:i}) = \int p(y_{i+1:M} \,| \, y_{1:i}, \theta) \, p(\theta\,|\,y_{1:i}) \,d\theta. $$ Having obtained $S$ draws $(\theta_{1:i}^{(1)}, \ldots, \theta_{1:i}^{(S)})$ from the posterior distribution $p(\theta\,|\,y_{1:i})$, we can estimate $p(y_{i+1:M} | y_{1:i})$ as $$ p(y_{i+1:M} \,|\, y_{1:i}) \approx \frac{1}{S}\sum_{s=1}^S p(y_{i+1:M} \,|\, y_{1:i}, \theta_{1:i}^{(s)}). $$ ## Approximate $M$-SAP using importance-sampling {#approximate_MSAP} Unfortunately, the math above makes use of the posterior distributions from many different fits of the model to different subsets of the data. That is, to obtain the predictive density $p(y_{i+1:M} \,|\, y_{1:i})$ requires fitting a model to only the first $i$ data points, and we will need to do this for every value of $i$ under consideration (all $i \in \{L, \ldots, N - M\}$). To reduce the number of models that need to be fit for the purpose of obtaining each of the densities $p(y_{i+1:M} \,|\, y_{1:i})$, we propose the following algorithm. First, we refit the model using the first $L$ observations of the time series and then perform a single exact $M$-step-ahead prediction step for $p(y_{L+1:M} \,|\, y_{1:L})$. Recall that $L$ is the minimum number of observations we have deemed acceptable for making predictions (setting $L=0$ means the first data point will be predicted only based on the prior). We define $i^\star = L$ as the current point of refit. Next, starting with $i = i^\star + 1$, we approximate each $p(y_{i+1:M} \,|\, y_{1:i})$ via $$ p(y_{i+1:M} \,|\, y_{1:i}) \approx \frac{ \sum_{s=1}^S w_i^{(s)}\, p(y_{i+1:M} \,|\, y_{1:i}, \theta^{(s)})} { \sum_{s=1}^S w_i^{(s)}}, $$ where $\theta^{(s)} = \theta^{(s)}_{1:i^\star}$ are draws from the posterior distribution based on the first $i^\star$ observations and $w_i^{(s)}$ are the PSIS weights obtained in two steps. First, we compute the raw importance ratios $$ r_i^{(s)} = \frac{f_{1:i}(\theta^{(s)})}{f_{1:i^\star}(\theta^{(s)})} \propto \prod_{j \in (i^\star + 1):i} p(y_j \,|\, y_{1:(j-1)}, \theta^{(s)}), $$ and then stabilize them using PSIS. The function $f_{1:i}$ denotes the posterior distribution based on the first $i$ observations, that is, $f_{1:i} = p(\theta \,|\, y_{1:i})$, with $f_{1:i^\star}$ defined analogously. The index set $(i^\star + 1):i$ indicates all observations which are part of the data for the model $f_{1:i}$ whose predictive performance we are trying to approximate but not for the actually fitted model $f_{1:i^\star}$. The proportional statement arises from the fact that we ignore the normalizing constants $p(y_{1:i})$ and $p(y_{1:i^\star})$ of the compared posteriors, which leads to a self-normalized variant of PSIS (see Vehtari et al, 2017). Continuing with the next observation, we gradually increase $i$ by $1$ (we move forward in time) and repeat the process. At some observation $i$, the variability of the importance ratios $r_i^{(s)}$ will become too large and importance sampling will fail. We will refer to this particular value of $i$ as $i^\star_1$. To identify the value of $i^\star_1$, we check for which value of $i$ does the estimated shape parameter $k$ of the generalized Pareto distribution first cross a certain threshold $\tau$ (Vehtari et al, 2019). Only then do we refit the model using the observations up to $i^\star_1$ and restart the process from there by setting $\theta^{(s)} = \theta^{(s)}_{1:i^\star_1}$ and $i^\star = i^\star_1$ until the next refit. In some cases we may only need to refit once and in other cases we will find a value $i^\star_2$ that requires a second refitting, maybe an $i^\star_3$ that requires a third refitting, and so on. We refit as many times as is required (only when $k > \tau$) until we arrive at observation $i = N - M$. For LOO, we recommend to use a threshold of $\tau = 0.7$ (Vehtari et al, 2017, 2019) and it turns out this is a reasonable threshold for LFO as well (Bürkner et al. 2020). ## Autoregressive models Autoregressive (AR) models are some of the most commonly used time-series models. An AR(p) model ---an autoregressive model of order $p$--- can be defined as $$ y_i = \eta_i + \sum_{k = 1}^p \varphi_k y_{i - k} + \varepsilon_i, $$ where $\eta_i$ is the linear predictor for the $i$th observation, $\phi_k$ are the autoregressive parameters and $\varepsilon_i$ are pairwise independent errors, which are usually assumed to be normally distributed with equal variance $\sigma^2$. The model implies a recursive formula that allows for computing the right-hand side of the above equation for observation $i$ based on the values of the equations for previous observations. ## Case Study: Annual measurements of the level of Lake Huron To illustrate the application of PSIS-LFO-CV for estimating expected $M$-SAP performance, we will fit a model for 98 annual measurements of the water level (in feet) of [Lake Huron](https://en.wikipedia.org/wiki/Lake_Huron) from the years 1875--1972. This data set is found in the **datasets** R package, which is installed automatically with **R**. In addition to the **loo** package, for this analysis we will use the **brms** interface to Stan to generate a Stan program and fit the model, and also the **bayesplot** and **ggplot2** packages for plotting. ```{r pkgs, cache=FALSE} library("loo") library("brms") library("bayesplot") library("ggplot2") color_scheme_set("brightblue") theme_set(theme_default()) CHAINS <- 4 SEED <- 5838296 set.seed(SEED) ``` Before fitting a model, we will first put the data into a data frame and then look at the time series. ```{r hurondata} N <- length(LakeHuron) df <- data.frame( y = as.numeric(LakeHuron), year = as.numeric(time(LakeHuron)), time = 1:N ) ggplot(df, aes(x = year, y = y)) + geom_point(size = 1) + labs( y = "Water Level (ft)", x = "Year", title = "Water Level in Lake Huron (1875-1972)" ) ``` The above plot shows rather strong autocorrelation of the time-series as well as some trend towards lower levels for later points in time. We can specify an AR(4) model for these data using the **brms** package as follows: ```{r fit, results = "hide"} fit <- brm( y ~ ar(time, p = 4), data = df, prior = prior(normal(0, 0.5), class = "ar"), control = list(adapt_delta = 0.99), seed = SEED, chains = CHAINS ) ``` The model implied predictions along with the observed values can be plotted, which reveals a rather good fit to the data. ```{r plotpreds, cache = FALSE} preds <- posterior_predict(fit) preds <- cbind( Estimate = colMeans(preds), Q5 = apply(preds, 2, quantile, probs = 0.05), Q95 = apply(preds, 2, quantile, probs = 0.95) ) ggplot(cbind(df, preds), aes(x = year, y = Estimate)) + geom_smooth(aes(ymin = Q5, ymax = Q95), stat = "identity", size = 0.5) + geom_point(aes(y = y)) + labs( y = "Water Level (ft)", x = "Year", title = "Water Level in Lake Huron (1875-1972)", subtitle = "Mean (blue) and 90% predictive intervals (gray) vs. observed data (black)" ) ``` To allow for reasonable predictions of future values, we will require at least $L = 20$ historical observations (20 years) to make predictions. ```{r setL} L <- 20 ``` We first perform approximate leave-one-out cross-validation (LOO-CV) for the purpose of later comparison with exact and approximate LFO-CV for the 1-SAP case. ```{r loo1sap, cache = FALSE} loo_cv <- loo(log_lik(fit)[, (L + 1):N]) print(loo_cv) ``` ## 1-step-ahead predictions leaving out all future values The most basic version of $M$-SAP is 1-SAP, in which we predict only one step ahead. In this case, $y_{i+1:M}$ simplifies to $y_{i}$ and the LFO-CV algorithm becomes considerably simpler than for larger values of $M$. ### Exact 1-step-ahead predictions Before we compute approximate LFO-CV using PSIS we will first compute exact LFO-CV for the 1-SAP case so we can use it as a benchmark later. The initial step for the exact computation is to calculate the log-predictive densities by refitting the model many times: ```{r exact_loglik, results="hide"} loglik_exact <- matrix(nrow = nsamples(fit), ncol = N) for (i in L:(N - 1)) { past <- 1:i oos <- i + 1 df_past <- df[past, , drop = FALSE] df_oos <- df[c(past, oos), , drop = FALSE] fit_i <- update(fit, newdata = df_past, recompile = FALSE) loglik_exact[, i + 1] <- log_lik(fit_i, newdata = df_oos, oos = oos)[, oos] } ``` Then we compute the exact expected log predictive density (ELPD): ```{r helpers} # some helper functions we'll use throughout # more stable than log(sum(exp(x))) log_sum_exp <- function(x) { max_x <- max(x) max_x + log(sum(exp(x - max_x))) } # more stable than log(mean(exp(x))) log_mean_exp <- function(x) { log_sum_exp(x) - log(length(x)) } # compute log of raw importance ratios # sums over observations *not* over posterior samples sum_log_ratios <- function(loglik, ids = NULL) { if (!is.null(ids)) loglik <- loglik[, ids, drop = FALSE] rowSums(loglik) } # for printing comparisons later rbind_print <- function(...) { round(rbind(...), digits = 2) } ``` ```{r exact1sap, cache = FALSE} exact_elpds_1sap <- apply(loglik_exact, 2, log_mean_exp) exact_elpd_1sap <- c(ELPD = sum(exact_elpds_1sap[-(1:L)])) rbind_print( "LOO" = loo_cv$estimates["elpd_loo", "Estimate"], "LFO" = exact_elpd_1sap ) ``` We see that the ELPD from LFO-CV for 1-step-ahead predictions is lower than the ELPD estimate from LOO-CV, which should be expected since LOO-CV is making use of more of the time series. That is, since the LFO-CV approach only uses observations from before the left-out data point but LOO-CV uses _all_ data points other than the left-out observation, we should expect to see the larger ELPD from LOO-CV. ### Approximate 1-step-ahead predictions We compute approximate 1-SAP with refit at observations where the Pareto $k$ estimate exceeds the threshold of $0.7$. ```{r setkthresh} k_thres <- 0.7 ``` The code becomes a little bit more involved as compared to the exact LFO-CV. Note that we can compute exact 1-SAP at the refitting points, which comes with no additional computational costs since we had to refit the model anyway. ```{r refit_loglik, results="hide"} approx_elpds_1sap <- rep(NA, N) # initialize the process for i = L past <- 1:L oos <- L + 1 df_past <- df[past, , drop = FALSE] df_oos <- df[c(past, oos), , drop = FALSE] fit_past <- update(fit, newdata = df_past, recompile = FALSE) loglik <- log_lik(fit_past, newdata = df_oos, oos = oos) approx_elpds_1sap[L + 1] <- log_mean_exp(loglik[, oos]) # iterate over i > L i_refit <- L refits <- L ks <- NULL for (i in (L + 1):(N - 1)) { past <- 1:i oos <- i + 1 df_past <- df[past, , drop = FALSE] df_oos <- df[c(past, oos), , drop = FALSE] loglik <- log_lik(fit_past, newdata = df_oos, oos = oos) logratio <- sum_log_ratios(loglik, (i_refit + 1):i) psis_obj <- suppressWarnings(psis(logratio)) k <- pareto_k_values(psis_obj) ks <- c(ks, k) if (k > k_thres) { # refit the model based on the first i observations i_refit <- i refits <- c(refits, i) fit_past <- update(fit_past, newdata = df_past, recompile = FALSE) loglik <- log_lik(fit_past, newdata = df_oos, oos = oos) approx_elpds_1sap[i + 1] <- log_mean_exp(loglik[, oos]) } else { lw <- weights(psis_obj, normalize = TRUE)[, 1] approx_elpds_1sap[i + 1] <- log_sum_exp(lw + loglik[, oos]) } } ``` We see that the final Pareto-$k$-estimates are mostly well below the threshold and that we only needed to refit the model a few times: ```{r plot_ks} plot_ks <- function(ks, ids, thres = 0.6) { dat_ks <- data.frame(ks = ks, ids = ids) ggplot(dat_ks, aes(x = ids, y = ks)) + geom_point(aes(color = ks > thres), shape = 3, show.legend = FALSE) + geom_hline(yintercept = thres, linetype = 2, color = "red2") + scale_color_manual(values = c("cornflowerblue", "darkblue")) + labs(x = "Data point", y = "Pareto k") + ylim(-0.5, 1.5) } ``` ```{r refitsummary1sap, cache=FALSE} cat("Using threshold ", k_thres, ", model was refit ", length(refits), " times, at observations", refits) plot_ks(ks, (L + 1):(N - 1)) ``` The approximate 1-SAP ELPD is remarkably similar to the exact 1-SAP ELPD computed above, which indicates our algorithm to compute approximate 1-SAP worked well for the present data and model. ```{r lfosummary1sap, cache = FALSE} approx_elpd_1sap <- sum(approx_elpds_1sap, na.rm = TRUE) rbind_print( "approx LFO" = approx_elpd_1sap, "exact LFO" = exact_elpd_1sap ) ``` Plotting exact against approximate predictions, we see that no approximation value deviates far from its exact counterpart, providing further evidence for the good quality of our approximation. ```{r plot1sap, cache = FALSE} dat_elpd <- data.frame( approx_elpd = approx_elpds_1sap, exact_elpd = exact_elpds_1sap ) ggplot(dat_elpd, aes(x = approx_elpd, y = exact_elpd)) + geom_abline(color = "gray30") + geom_point(size = 2) + labs(x = "Approximate ELPDs", y = "Exact ELPDs") ``` We can also look at the maximum difference and average difference between the approximate and exact ELPD calculations, which also indicate a ver close approximation: ```{r diffs1sap, cache=FALSE} max_diff <- with(dat_elpd, max(abs(approx_elpd - exact_elpd), na.rm = TRUE)) mean_diff <- with(dat_elpd, mean(abs(approx_elpd - exact_elpd), na.rm = TRUE)) rbind_print( "Max diff" = round(max_diff, 2), "Mean diff" = round(mean_diff, 3) ) ``` ## $M$-step-ahead predictions leaving out all future values To illustrate the application of $M$-SAP for $M > 1$, we next compute exact and approximate LFO-CV for the 4-SAP case. ### Exact $M$-step-ahead predictions The necessary steps are the same as for 1-SAP with the exception that the log-density values of interest are now the sums of the log predictive densities of four consecutive observations. Further, the stability of the PSIS approximation actually stays the same for all $M$ as it only depends on the number of observations we leave out, not on the number of observations we predict. ```{r exact_loglikm, results="hide"} M <- 4 loglikm <- matrix(nrow = nsamples(fit), ncol = N) for (i in L:(N - M)) { past <- 1:i oos <- (i + 1):(i + M) df_past <- df[past, , drop = FALSE] df_oos <- df[c(past, oos), , drop = FALSE] fit_past <- update(fit, newdata = df_past, recompile = FALSE) loglik <- log_lik(fit_past, newdata = df_oos, oos = oos) loglikm[, i + 1] <- rowSums(loglik[, oos]) } ``` ```{r exact4sap, cache = FALSE} exact_elpds_4sap <- apply(loglikm, 2, log_mean_exp) (exact_elpd_4sap <- c(ELPD = sum(exact_elpds_4sap, na.rm = TRUE))) ``` ### Approximate $M$-step-ahead predictions Computing the approximate PSIS-LFO-CV for the 4-SAP case is a little bit more involved than the approximate version for the 1-SAP case, although the underlying principles remain the same. ```{r refit_loglikm, results="hide"} approx_elpds_4sap <- rep(NA, N) # initialize the process for i = L past <- 1:L oos <- (L + 1):(L + M) df_past <- df[past, , drop = FALSE] df_oos <- df[c(past, oos), , drop = FALSE] fit_past <- update(fit, newdata = df_past, recompile = FALSE) loglik <- log_lik(fit_past, newdata = df_oos, oos = oos) loglikm <- rowSums(loglik[, oos]) approx_elpds_1sap[L + 1] <- log_mean_exp(loglikm) # iterate over i > L i_refit <- L refits <- L ks <- NULL for (i in (L + 1):(N - M)) { past <- 1:i oos <- (i + 1):(i + M) df_past <- df[past, , drop = FALSE] df_oos <- df[c(past, oos), , drop = FALSE] loglik <- log_lik(fit_past, newdata = df_oos, oos = oos) logratio <- sum_log_ratios(loglik, (i_refit + 1):i) psis_obj <- suppressWarnings(psis(logratio)) k <- pareto_k_values(psis_obj) ks <- c(ks, k) if (k > k_thres) { # refit the model based on the first i observations i_refit <- i refits <- c(refits, i) fit_past <- update(fit_past, newdata = df_past, recompile = FALSE) loglik <- log_lik(fit_past, newdata = df_oos, oos = oos) loglikm <- rowSums(loglik[, oos]) approx_elpds_4sap[i + 1] <- log_mean_exp(loglikm) } else { lw <- weights(psis_obj, normalize = TRUE)[, 1] loglikm <- rowSums(loglik[, oos]) approx_elpds_4sap[i + 1] <- log_sum_exp(lw + loglikm) } } ``` Again, we see that the final Pareto-$k$-estimates are mostly well below the threshold and that we only needed to refit the model a few times: ```{r refitsummary4sap, cache = FALSE} cat("Using threshold ", k_thres, ", model was refit ", length(refits), " times, at observations", refits) plot_ks(ks, (L + 1):(N - M)) ``` The approximate ELPD computed for the 4-SAP case is not as close to its exact counterpart as in the 1-SAP case. In general, the larger $M$, the larger the variation of the approximate ELPD around the exact ELPD. It turns out that the ELPD estimates of AR-models with $M>1$ show particular variation due to their predictions' dependency on other predicted values. In Bürkner et al. (2020) we provide further explanation and simulations for these cases. ```{r lfosummary4sap, cache = FALSE} approx_elpd_4sap <- sum(approx_elpds_4sap, na.rm = TRUE) rbind_print( "Approx LFO" = approx_elpd_4sap, "Exact LFO" = exact_elpd_4sap ) ``` Plotting exact against approximate pointwise predictions confirms that, for a few specific data points, the approximate predictions underestimate the exact predictions. ```{r plot4sap, cache = FALSE} dat_elpd_4sap <- data.frame( approx_elpd = approx_elpds_4sap, exact_elpd = exact_elpds_4sap ) ggplot(dat_elpd_4sap, aes(x = approx_elpd, y = exact_elpd)) + geom_abline(color = "gray30") + geom_point(size = 2) + labs(x = "Approximate ELPDs", y = "Exact ELPDs") ``` ## Conclusion In this case study we have shown how to do carry out exact and approximate leave-future-out cross-validation for $M$-step-ahead prediction tasks. For the data and model used in our example, the PSIS-LFO-CV algorithm provides reasonably stable and accurate results despite not requiring us to refit the model nearly as many times. For more details on approximate LFO-CV, we refer to Bürkner et al. (2020).
## References Bürkner P. C., Gabry J., & Vehtari A. (2020). Approximate leave-future-out cross-validation for time series models. *Journal of Statistical Computation and Simulation*, 90(14):2499-2523. \doi:/10.1080/00949655.2020.1783262. [Online](https://www.tandfonline.com/doi/full/10.1080/00949655.2020.1783262). [arXiv preprint](https://arxiv.org/abs/1902.06281). Vehtari A., Gelman A., & Gabry J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. *Statistics and Computing*, 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. [Online](https://link.springer.com/article/10.1007/s11222-016-9696-4). [arXiv preprint arXiv:1507.04544](https://arxiv.org/abs/1507.04544). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.02646](https://arxiv.org/abs/1507.02646).
## Appendix ### Appendix: Session information ```{r sessioninfo} sessionInfo() ``` ### Appendix: Licenses * Code © 2018, Paul Bürkner, Jonah Gabry, Aki Vehtari (licensed under BSD-3). * Text © 2018, Paul Bürkner, Jonah Gabry, Aki Vehtari (licensed under CC-BY-NC 4.0). loo/inst/doc/loo2-with-rstan.Rmd0000644000176200001440000002030714407123455016211 0ustar liggesusers--- title: "Writing Stan programs for use with the loo package" author: "Aki Vehtari and Jonah Gabry" date: "`r Sys.Date()`" output: html_vignette: toc: yes params: EVAL: !r identical(Sys.getenv("NOT_CRAN"), "true") --- ```{r settings, child="children/SETTINGS-knitr.txt"} ``` ```{r, child="children/SEE-ONLINE.txt", eval = if (isTRUE(exists("params"))) !params$EVAL else TRUE} ``` # Introduction This vignette demonstrates how to write a Stan program that computes and stores the pointwise log-likelihood required for using the __loo__ package. The other vignettes included with the package demonstrate additional functionality. Some sections from this vignette are excerpted from our papers * Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. _Statistics and Computing_. 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. Links: [published](https://link.springer.com/article/10.1007/s11222-016-9696-4) | [arXiv preprint](https://arxiv.org/abs/1507.04544). * Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.04544](https://arxiv.org/abs/1507.02646). which provide important background for understanding the methods implemented in the package. # Example: Well water in Bangladesh This example comes from a survey of residents from a small area in Bangladesh that was affected by arsenic in drinking water. Respondents with elevated arsenic levels in their wells were asked if they were interested in getting water from a neighbor's well, and a series of logistic regressions were fit to predict this binary response given various information about the households (Gelman and Hill, 2007). Here we fit a model for the well-switching response given two predictors: the arsenic level of the water in the resident's home, and the distance of the house from the nearest safe well. The sample size in this example is $N=3020$, which is not huge but is large enough that it is important to have a computational method for LOO that is fast for each data point. On the plus side, with such a large dataset, the influence of any given observation is small, and so the computations should be stable. ## Coding the Stan model Here is the Stan code for fitting the logistic regression model, which we save in a file called `logistic.stan`: ``` data { int N; // number of data points int P; // number of predictors (including intercept) matrix[N,P] X; // predictors (including 1s for intercept) int y[N]; // binary outcome } parameters { vector[P] beta; } model { beta ~ normal(0, 1); y ~ bernoulli_logit(X * beta); } generated quantities { vector[N] log_lik; for (n in 1:N) { log_lik[n] = bernoulli_logit_lpmf(y[n] | X[n] * beta); } } ``` We have defined the log likelihood as a vector named `log_lik` in the generated quantities block so that the individual terms will be saved by Stan. After running Stan, `log_lik` can be extracted (using the `extract_log_lik` function provided in the **loo** package) as an $S \times N$ matrix, where $S$ is the number of simulations (posterior draws) and $N$ is the number of data points. ## Fitting the model with RStan Next we fit the model in Stan using the **rstan** package: ```{r, eval=FALSE} library("rstan") # Prepare data url <- "http://stat.columbia.edu/~gelman/arm/examples/arsenic/wells.dat" wells <- read.table(url) wells$dist100 <- with(wells, dist / 100) X <- model.matrix(~ dist100 + arsenic, wells) standata <- list(y = wells$switch, X = X, N = nrow(X), P = ncol(X)) # Fit model fit_1 <- stan("logistic.stan", data = standata) print(fit_1, pars = "beta") ``` ``` mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat beta[1] 0.00 0 0.08 -0.16 -0.05 0.00 0.05 0.15 1964 1 beta[2] -0.89 0 0.10 -1.09 -0.96 -0.89 -0.82 -0.68 2048 1 beta[3] 0.46 0 0.04 0.38 0.43 0.46 0.49 0.54 2198 1 ``` ## Computing approximate leave-one-out cross-validation using PSIS-LOO We can then use the **loo** package to compute the efficient PSIS-LOO approximation to exact LOO-CV: ```{r, eval=FALSE} library("loo") # Extract pointwise log-likelihood # using merge_chains=FALSE returns an array, which is easier to # use with relative_eff() log_lik_1 <- extract_log_lik(fit_1, merge_chains = FALSE) # as of loo v2.0.0 we can optionally provide relative effective sample sizes # when calling loo, which allows for better estimates of the PSIS effective # sample sizes and Monte Carlo error r_eff <- relative_eff(exp(log_lik_1), cores = 2) # preferably use more than 2 cores (as many cores as possible) # will use value of 'mc.cores' option if cores is not specified loo_1 <- loo(log_lik_1, r_eff = r_eff, cores = 2) print(loo_1) ``` ``` Computed from 4000 by 3020 log-likelihood matrix Estimate SE elpd_loo -1968.5 15.6 p_loo 3.2 0.1 looic 3937.0 31.2 ------ Monte Carlo SE of elpd_loo is 0.0. All Pareto k estimates are good (k < 0.5). See help('pareto-k-diagnostic') for details. ``` The printed output from the `loo` function shows the estimates $\widehat{\mbox{elpd}}_{\rm loo}$ (expected log predictive density), $\widehat{p}_{\rm loo}$ (effective number of parameters), and ${\rm looic} =-2\, \widehat{\mbox{elpd}}_{\rm loo}$ (the LOO information criterion). The line at the bottom of the printed output provides information about the reliability of the LOO approximation (the interpretation of the $k$ parameter is explained in `help('pareto-k-diagnostic')` and in greater detail in Vehtari, Simpson, Gelman, Yao, and Gabry (2019)). In this case the message tells us that all of the estimates for $k$ are fine. ## Comparing models To compare this model to an alternative model for the same data we can use the `loo_compare` function in the **loo** package. First we'll fit a second model to the well-switching data, using `log(arsenic)` instead of `arsenic` as a predictor: ```{r, eval=FALSE} standata$X[, "arsenic"] <- log(standata$X[, "arsenic"]) fit_2 <- stan(fit = fit_1, data = standata) log_lik_2 <- extract_log_lik(fit_2, merge_chains = FALSE) r_eff_2 <- relative_eff(exp(log_lik_2)) loo_2 <- loo(log_lik_2, r_eff = r_eff_2, cores = 2) print(loo_2) ``` ``` Computed from 4000 by 3020 log-likelihood matrix Estimate SE elpd_loo -1952.3 16.2 p_loo 3.1 0.1 looic 3904.6 32.4 ------ Monte Carlo SE of elpd_loo is 0.0. All Pareto k estimates are good (k < 0.5). See help('pareto-k-diagnostic') for details. ``` We can now compare the models on LOO using the `loo_compare` function: ```{r, eval=FALSE} # Compare comp <- loo_compare(loo_1, loo_2) ``` This new object, `comp`, contains the estimated difference of expected leave-one-out prediction errors between the two models, along with the standard error: ```{r, eval=FALSE} print(comp) # can set simplify=FALSE for more detailed print output ``` ``` elpd_diff se_diff model2 0.0 0.0 model1 -16.3 4.4 ``` The first column shows the difference in ELPD relative to the model with the largest ELPD. In this case, the difference in `elpd` and its scale relative to the approximate standard error of the difference) indicates a preference for the second model (`model2`). # References Gelman, A., and Hill, J. (2007). *Data Analysis Using Regression and Multilevel Hierarchical Models.* Cambridge University Press. Stan Development Team (2017). _The Stan C++ Library, Version 2.17.0._ https://mc-stan.org/ Stan Development Team (2018) _RStan: the R interface to Stan, Version 2.17.3._ https://mc-stan.org/ Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. _Statistics and Computing_. 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. [online](https://link.springer.com/article/10.1007/s11222-016-9696-4), [arXiv preprint arXiv:1507.04544](https://arxiv.org/abs/1507.04544). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.02646](https://arxiv.org/abs/1507.02646). loo/inst/doc/loo2-mixis.html0000644000176200001440000010175514411465131015466 0ustar liggesusers Mixture IS leave-one-out cross-validation for high-dimensional Bayesian models

Mixture IS leave-one-out cross-validation for high-dimensional Bayesian models

Luca Silva and Giacomo Zanella

2023-03-30

Introduction

This vignette shows how to perform Bayesian leave-one-out cross-validation (LOO-CV) using the mixture estimators proposed in the paper Silva and Zanella (2022). These estimators have shown to be useful in presence of outliers but also, and especially, in high-dimensional settings where the model features many parameters. In these contexts it can happen that a large portion of observations lead to high values of Pareto-\(k\) diagnostics and potential instability of PSIS-LOO estimators.

For this illustration we consider a high-dimensional Bayesian Logistic regression model applied to the Voice dataset.

Setup: load packages and set seed

library("rstan")
library("loo")
library("matrixStats")
options(mc.cores = parallel::detectCores(), parallel=FALSE)
set.seed(24877)

Model

This is the Stan code for a logistic regression model with regularized horseshoe prior. The code includes an if statement to include a code line needed later for the MixIS approach.

stancode_horseshoe <- "
data {
  int <lower=0> n;                
  int <lower=0> p;                
  int <lower=0, upper=1> y[n];    
  matrix [n,p] X;                
  real <lower=0> scale_global;
  int <lower=0,upper=1> mixis;                
}
transformed data {
  real<lower=1> nu_global=1; // degrees of freedom for the half-t priors for tau
  real<lower=1> nu_local=1;  // degrees of freedom for the half-t priors for lambdas
                             // (nu_local = 1 corresponds to the horseshoe)
  real<lower=0> slab_scale=2;// for the regularized horseshoe
  real<lower=0> slab_df=100; // for the regularized horseshoe
}
parameters {
  vector[p] z;                // for non-centered parameterization
  real <lower=0> tau;         // global shrinkage parameter
  vector <lower=0>[p] lambda; // local shrinkage parameter
  real<lower=0> caux;
}
transformed parameters {
  vector[p] beta;
  { 
    vector[p] lambda_tilde;   // 'truncated' local shrinkage parameter
    real c = slab_scale * sqrt(caux); // slab scale
    lambda_tilde = sqrt( c^2 * square(lambda) ./ (c^2 + tau^2*square(lambda)));
    beta = z .* lambda_tilde*tau;
  }
}
model {
  vector[n] means=X*beta;
  vector[n] log_lik;
  target += std_normal_lpdf(z);
  target += student_t_lpdf(lambda | nu_local, 0, 1);
  target += student_t_lpdf(tau | nu_global, 0, scale_global);
  target += inv_gamma_lpdf(caux | 0.5*slab_df, 0.5*slab_df);
  for (index in 1:n) {
    log_lik[index]= bernoulli_logit_lpmf(y[index] | means[index]);
  }
  target += sum(log_lik);
  if (mixis) {
    target += log_sum_exp(-log_lik);
  }
}
generated quantities {
  vector[n] means=X*beta;
  vector[n] log_lik;
  for (index in 1:n) {
    log_lik[index] = bernoulli_logit_lpmf(y[index] | means[index]);
  }
}
"

Dataset

The LSVT Voice Rehabilitation Data Set (see link for details) has \(p=312\) covariates and \(n=126\) observations with binary response. We construct data list for Stan.

data(voice)
y <- voice$y
X <- voice[2:length(voice)]
n <- dim(X)[1]
p <- dim(X)[2]
p0 <- 10
scale_global <- 2*p0/(p-p0)/sqrt(n-1)
standata <- list(n = n, p = p, X = as.matrix(X), y = c(y), scale_global = scale_global, mixis = 0)

Note that in our prior specification we divide the prior variance by the number of covariates \(p\). This is often done in high-dimensional contexts to have a prior variance for the linear predictors \(X\beta\) that remains bounded as \(p\) increases.

PSIS estimators and Pareto-\(k\) diagnostics

LOO-CV computations are challenging in this context due to high-dimensionality of the parameter space. To show that, we compute PSIS-LOO estimators, which require sampling from the posterior distribution, and inspect the associated Pareto-\(k\) diagnostics.

chains <- 4
n_iter <- 2000
warm_iter <- 1000
stanmodel <- stan_model(model_code = stancode_horseshoe)
fit_post <- sampling(stanmodel, data = standata, chains = chains, iter = n_iter, warmup = warm_iter, refresh = 0)
loo_post <-loo(fit_post)
print(loo_post)

Computed from 4000 by 126 log-likelihood matrix

         Estimate   SE
elpd_loo    -42.5  7.1
p_loo        23.8  5.2
looic        85.0 14.2
------
Monte Carlo SE of elpd_loo is NA.

Pareto k diagnostic values:
                         Count Pct.    Min. n_eff
(-Inf, 0.5]   (good)     29    23.0%   386       
 (0.5, 0.7]   (ok)       68    54.0%   82        
   (0.7, 1]   (bad)      23    18.3%   13        
   (1, Inf)   (very bad)  6     4.8%   4         
See help('pareto-k-diagnostic') for details.

As we can see the diagnostics signal either “bad” or “very bad” Pareto-\(k\) values for roughly \(15-30\%\) of the observations which is a significant portion of the dataset.

Mixture estimators

We now compute the mixture estimators proposed in Silva and Zanella (2022). These require to sample from the following mixture of leave-one-out posteriors \[\begin{equation} q_{mix}(\theta) = \frac{\sum_{i=1}^n p(y_{-i}|\theta)p(\theta)}{\sum_{i=1}^np(y_{-i})}\propto p(\theta|y)\cdot \left(\sum_{i=1}^np(y_i|\theta)^{-1}\right). \end{equation}\] The code to generate a Stan model for the above mixture distribution is the same to the one for the posterior, just enabling one line of code with a LogSumExp contribution to account for the last term in the equation above.

  if (mixis) {
    target += log_sum_exp(-log_lik);
  }

We sample from the mixture and collect the log-likelihoods term.

standata$mixis <- 1
fit_mix <- sampling(stanmodel, data = standata, chains = chains, iter = n_iter, warmup = warm_iter, refresh = 0, pars = "log_lik")
log_lik_mix <- extract(fit_mix)$log_lik

We now compute the mixture estimators, following the numerically stable implementation in Appendix A.2 of Silva and Zanella (2022). The code below makes use of the package “matrixStats”.

l_common_mix <- rowLogSumExps(-log_lik_mix)
log_weights <- -log_lik_mix - l_common_mix
elpd_mixis <- logSumExp(-l_common_mix) - rowLogSumExps(t(log_weights))

Comparison with benchmark values obtained with long simulations

To evaluate the performance of mixture estimators (MixIS) we also generate benchmark values, i.e. accurate approximations of the LOO predictives \(\{p(y_i|y_{-i})\}_{i=1,\dots,n}\), obtained by brute-force sampling from the leave-one-out posteriors directly, getting \(90k\) samples from each and discarding the first \(10k\) as warmup. This is computationally heavy, hence we have saved the results and we just load them in the current vignette.

data(voice_loo)
elpd_loo <- voice_loo$elpd_loo

We can then compute the root mean squared error (RMSE) of the PSIS and mixture estimators relative to such benchmark values.

elpd_psis <- loo_post$pointwise[,1]
print(paste("RMSE(PSIS) =",round( sqrt(mean((elpd_loo-elpd_psis)^2)) ,2)))
[1] "RMSE(PSIS) = 0.08"
print(paste("RMSE(MixIS) =",round( sqrt(mean((elpd_loo-elpd_mixis)^2)) ,2)))
[1] "RMSE(MixIS) = 0.05"

Here mixture estimator provides a reduction in RMSE. Note that this value would increase with the number of samples drawn from the posterior and mixture, since in this example the RMSE of MixIS will exhibit a CLT-type decay while the one of PSIS will converge at a slower rate (this can be verified by running the above code with a larger sample size; see also Figure 3 of Silva and Zanella (2022) for analogous results).

We then compare the overall ELPD estimates with the brute force one.

elpd_psis <- loo_post$pointwise[,1]
print(paste("ELPD (PSIS)=",round(sum(elpd_psis),2)))
[1] "ELPD (PSIS)= -42.51"
print(paste("ELPD (MixIS)=",round(sum(elpd_mixis),2)))
[1] "ELPD (MixIS)= -44.94"
print(paste("ELPD (brute force)=",round(sum(elpd_loo),2)))
[1] "ELPD (brute force)= -45.63"

In this example, MixIS provides a more accurate ELPD estimate closer to the brute force estimate, while PSIS severely overestimates the ELPD. Note that low accuracy of the PSIS ELPD estimate is expected in this example given the large number of large Pareto-\(k\) values. In this example, the accuracy of MixIS estimate will also improve with bigger MCMC sample size.

More generally, mixture estimators can be useful in situations where standard PSIS estimators struggle and return many large Pareto-\(k\) values. In these contexts MixIS often provides more accurate LOO-CV and ELPD estimates with a single sampling routine (i.e. with a cost comparable to sampling from the original posterior).

References

Silva L. and Zanella G. (2022). Robust leave-one-out cross-validation for high-dimensional Bayesian models. Preprint at arXiv:2209.09190

Vehtari A., Gelman A., and Gabry J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. Statistics and Computing, 27(5), 1413–1432. Preprint at arXiv:1507.04544

Vehtari A., Simpson D., Gelman A., Yao Y., and Gabry J. (2022). Pareto smoothed importance sampling. Preprint at arXiv:1507.02646

loo/inst/doc/loo2-example.html0000644000176200001440000141436614411455345016004 0ustar liggesusers Using the loo package (version >= 2.0.0)

Using the loo package (version >= 2.0.0)

Aki Vehtari and Jonah Gabry

2023-03-30

Introduction

This vignette demonstrates how to use the loo package to carry out Pareto smoothed importance-sampling leave-one-out cross-validation (PSIS-LOO) for purposes of model checking and model comparison.

In this vignette we can’t provide all necessary background information on PSIS-LOO and its diagnostics (Pareto \(k\) and effective sample size), so we encourage readers to refer to the following papers for more details:

  • Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. Statistics and Computing. 27(5), 1413–1432. :10.1007/s11222-016-9696-4. Links: published | arXiv preprint.

  • Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. arXiv preprint arXiv:1507.02646.

Setup

In addition to the loo package, we’ll also be using rstanarm and bayesplot:

library("rstanarm")
library("bayesplot")
library("loo")

Example: Poisson vs negative binomial for the roaches dataset

Background and model fitting

The Poisson and negative binomial regression models used below in our example, as well as the stan_glm function used to fit the models, are covered in more depth in the rstanarm vignette Estimating Generalized Linear Models for Count Data with rstanarm. In the rest of this vignette we will assume the reader is already familiar with these kinds of models.

Roaches data

The example data we’ll use comes from Chapter 8.3 of Gelman and Hill (2007). We want to make inferences about the efficacy of a certain pest management system at reducing the number of roaches in urban apartments. Here is how Gelman and Hill describe the experiment and data (pg. 161):

the treatment and control were applied to 160 and 104 apartments, respectively, and the outcome measurement \(y_i\) in each apartment \(i\) was the number of roaches caught in a set of traps. Different apartments had traps for different numbers of days

In addition to an intercept, the regression predictors for the model are roach1, the pre-treatment number of roaches (rescaled above to be in units of hundreds), the treatment indicator treatment, and a variable indicating whether the apartment is in a building restricted to elderly residents senior. Because the number of days for which the roach traps were used is not the same for all apartments in the sample, we use the offset argument to specify that log(exposure2) should be added to the linear predictor.

# the 'roaches' data frame is included with the rstanarm package
data(roaches)
str(roaches)
'data.frame':   262 obs. of  5 variables:
 $ y        : int  153 127 7 7 0 0 73 24 2 2 ...
 $ roach1   : num  308 331.25 1.67 3 2 ...
 $ treatment: int  1 1 1 1 1 1 1 1 0 0 ...
 $ senior   : int  0 0 0 0 0 0 0 0 0 0 ...
 $ exposure2: num  0.8 0.6 1 1 1.14 ...
# rescale to units of hundreds of roaches
roaches$roach1 <- roaches$roach1 / 100

Fit Poisson model

We’ll fit a simple Poisson regression model using the stan_glm function from the rstanarm package.

fit1 <-
  stan_glm(
    formula = y ~ roach1 + treatment + senior,
    offset = log(exposure2),
    data = roaches,
    family = poisson(link = "log"),
    prior = normal(0, 2.5, autoscale = TRUE),
    prior_intercept = normal(0, 5, autoscale = TRUE),
    seed = 12345
  )

Usually we would also run posterior predictive checks as shown in the rstanarm vignette Estimating Generalized Linear Models for Count Data with rstanarm, but here we focus only on methods provided by the loo package.


Using the loo package for model checking and comparison

Although cross-validation is mostly used for model comparison, it is also useful for model checking.

Computing PSIS-LOO and checking diagnostics

We start by computing PSIS-LOO with the loo function. Since we fit our model using rstanarm we can use the loo method for stanreg objects (fitted model objects from rstanarm), which doesn’t require us to first extract the pointwise log-likelihood values. If we had written our own Stan program instead of using rstanarm we would pass an array or matrix of log-likelihood values to the loo function (see, e.g. help("loo.array", package = "loo")). We’ll also use the argument save_psis = TRUE to save some intermediate results to be re-used later.

loo1 <- loo(fit1, save_psis = TRUE)
Warning: Found 17 observations with a pareto_k > 0.7. With this many problematic observations we recommend calling 'kfold' with argument 'K=10' to perform 10-fold cross-validation rather than LOO.

loo gives us warnings about the Pareto diagnostics, which indicate that for some observations the leave-one-out posteriors are different enough from the full posterior that importance-sampling is not able to correct the difference. We can see more details by printing the loo object.

print(loo1)

Computed from 4000 by 262 log-likelihood matrix

         Estimate     SE
elpd_loo  -6247.8  728.0
p_loo       292.4   73.3
looic     12495.5 1455.9
------
Monte Carlo SE of elpd_loo is NA.

Pareto k diagnostic values:
                         Count Pct.    Min. n_eff
(-Inf, 0.5]   (good)     239   91.2%   200       
 (0.5, 0.7]   (ok)         6    2.3%   56        
   (0.7, 1]   (bad)        8    3.1%   25        
   (1, Inf)   (very bad)   9    3.4%   1         
See help('pareto-k-diagnostic') for details.

The table shows us a summary of Pareto \(k\) diagnostic, which is used to assess the reliability of the estimates. In addition to the proportion of leave-one-out folds with \(k\) values in different intervals, the minimum of the effective sample sizes in that category is shown to give idea why higher \(k\) values are bad. Since we have some \(k>1\), we are not able to compute an estimate for the Monte Carlo standard error (SE) of the expected log predictive density (elpd_loo) and NA is displayed. (Full details on the interpretation of the Pareto \(k\) diagnostics are available in the Vehtari, Gelman, and Gabry (2017) and Vehtari, Simpson, Gelman, Yao, and Gabry (2019) papers referenced at the top of this vignette.)

In this case the elpd_loo estimate should not be considered reliable. If we had a well-specified model we would expect the estimated effective number of parameters (p_loo) to be smaller than or similar to the total number of parameters in the model. Here p_loo is almost 300, which is about 70 times the total number of parameters in the model, indicating severe model misspecification.

Plotting Pareto \(k\) diagnostics

Using the plot method on our loo1 object produces a plot of the \(k\) values (in the same order as the observations in the dataset used to fit the model) with horizontal lines corresponding to the same categories as in the printed output above.

plot(loo1)

This plot is useful to quickly see the distribution of \(k\) values, but it’s often also possible to see structure with respect to data ordering. In our case this is mild, but there seems to be a block of data that is somewhat easier to predict (indices around 90–150). Unfortunately even for these data points we see some high \(k\) values.

Marginal posterior predictive checks

The loo package can be used in combination with the bayesplot package for leave-one-out cross-validation marginal posterior predictive checks Gabry et al (2018). LOO-PIT values are cumulative probabilities for \(y_i\) computed using the LOO marginal predictive distributions \(p(y_i|y_{-i})\). For a good model, the distribution of LOO-PIT values should be uniform. In the following plot the distribution (smoothed density estimate) of the LOO-PIT values for our model (thick curve) is compared to many independently generated samples (each the same size as our dataset) from the standard uniform distribution (thin curves).

yrep <- posterior_predict(fit1)

ppc_loo_pit_overlay(
  y = roaches$y,
  yrep = yrep,
  lw = weights(loo1$psis_object)
)
NOTE: The kernel density estimate assumes continuous observations and is not optimal for discrete observations.

The excessive number of values close to 0 indicates that the model is under-dispersed compared to the data, and we should consider a model that allows for greater dispersion.

Try alternative model with more flexibility

Here we will try negative binomial regression, which is commonly used for overdispersed count data.
Unlike the Poisson distribution, the negative binomial distribution allows the conditional mean and variance of \(y\) to differ.

fit2 <- update(fit1, family = neg_binomial_2)
loo2 <- loo(fit2, save_psis = TRUE, cores = 2)
Warning: Found 1 observation(s) with a pareto_k > 0.7. We recommend calling 'loo' again with argument 'k_threshold = 0.7' in order to calculate the ELPD without the assumption that these observations are negligible. This will refit the model 1 times to compute the ELPDs for the problematic observations directly.
print(loo2)

Computed from 4000 by 262 log-likelihood matrix

         Estimate   SE
elpd_loo   -895.6 37.8
p_loo         6.7  2.7
looic      1791.3 75.5
------
Monte Carlo SE of elpd_loo is NA.

Pareto k diagnostic values:
                         Count Pct.    Min. n_eff
(-Inf, 0.5]   (good)     260   99.2%   2615      
 (0.5, 0.7]   (ok)         1    0.4%   377       
   (0.7, 1]   (bad)        1    0.4%   28        
   (1, Inf)   (very bad)   0    0.0%   <NA>      
See help('pareto-k-diagnostic') for details.
plot(loo2, label_points = TRUE)

Using the label_points argument will label any \(k\) values larger than 0.7 with the index of the corresponding data point. These high values are often the result of model misspecification and frequently correspond to data points that would be considered ``outliers’’ in the data and surprising according to the model Gabry et al (2019). Unfortunately, while large \(k\) values are a useful indicator of model misspecification, small \(k\) values are not a guarantee that a model is well-specified.

If there are a small number of problematic \(k\) values then we can use a feature in rstanarm that lets us refit the model once for each of these problematic observations. Each time the model is refit, one of the observations with a high \(k\) value is omitted and the LOO calculations are performed exactly for that observation. The results are then recombined with the approximate LOO calculations already carried out for the observations without problematic \(k\) values:

if (any(pareto_k_values(loo2) > 0.7)) {
  loo2 <- loo(fit2, save_psis = TRUE, k_threshold = 0.7)
}
1 problematic observation(s) found.
Model will be refit 1 times.

Fitting model 1 out of 1 (leaving out observation 93)
print(loo2)

Computed from 4000 by 262 log-likelihood matrix

         Estimate   SE
elpd_loo   -895.5 37.7
p_loo         6.6  2.6
looic      1791.1 75.4
------
Monte Carlo SE of elpd_loo is 0.2.

Pareto k diagnostic values:
                         Count Pct.    Min. n_eff
(-Inf, 0.5]   (good)     260   99.6%   2615      
 (0.5, 0.7]   (ok)         1    0.4%   377       
   (0.7, 1]   (bad)        0    0.0%   <NA>      
   (1, Inf)   (very bad)   0    0.0%   <NA>      

All Pareto k estimates are ok (k < 0.7).
See help('pareto-k-diagnostic') for details.

In the print output we can see that the Monte Carlo SE is small compared to the other uncertainties.

On the other hand, p_loo is about 7 and still a bit higher than the total number of parameters in the model. This indicates that there is almost certainly still some degree of model misspecification, but this is much better than the p_loo estimate for the Poisson model.

For further model checking we again examine the LOO-PIT values.

yrep <- posterior_predict(fit2)
ppc_loo_pit_overlay(roaches$y, yrep, lw = weights(loo2$psis_object))
NOTE: The kernel density estimate assumes continuous observations and is not optimal for discrete observations.

The plot for the negative binomial model looks better than the Poisson plot, but we still see that this model is not capturing all of the essential features in the data.

Comparing the models on expected log predictive density

We can use the loo_compare function to compare our two models on expected log predictive density (ELPD) for new data:

loo_compare(loo1, loo2)
     elpd_diff se_diff
fit2     0.0       0.0
fit1 -5352.2     709.2

The difference in ELPD is much larger than several times the estimated standard error of the difference again indicating that the negative-binomial model is expected to have better predictive performance than the Poisson model. However, according to the LOO-PIT checks there is still some misspecification, and a reasonable guess is that a hurdle or zero-inflated model would be an improvement (we leave that for another case study).


References

Gabry, J., Simpson, D., Vehtari, A., Betancourt, M. and Gelman, A. (2019), Visualization in Bayesian workflow. J. R. Stat. Soc. A, 182: 389-402. :10.1111/rssa.12378. (journal version, arXiv preprint, code on GitHub)

Gelman, A. and Hill, J. (2007). Data Analysis Using Regression and Multilevel/Hierarchical Models. Cambridge University Press, Cambridge, UK.

Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. Statistics and Computing. 27(5), 1413–1432. :10.1007/s11222-016-9696-4. online, arXiv preprint arXiv:1507.04544.

Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. arXiv preprint arXiv:1507.02646.

loo/inst/doc/loo2-example.Rmd0000644000176200001440000003015314407123455015544 0ustar liggesusers--- title: "Using the loo package (version >= 2.0.0)" author: "Aki Vehtari and Jonah Gabry" date: "`r Sys.Date()`" output: html_vignette: toc: yes params: EVAL: !r identical(Sys.getenv("NOT_CRAN"), "true") --- ```{r, child="children/SETTINGS-knitr.txt"} ``` ```{r, child="children/SEE-ONLINE.txt", eval = if (isTRUE(exists("params"))) !params$EVAL else TRUE} ``` # Introduction This vignette demonstrates how to use the __loo__ package to carry out Pareto smoothed importance-sampling leave-one-out cross-validation (PSIS-LOO) for purposes of model checking and model comparison. In this vignette we can't provide all necessary background information on PSIS-LOO and its diagnostics (Pareto $k$ and effective sample size), so we encourage readers to refer to the following papers for more details: * Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. _Statistics and Computing_. 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. Links: [published](https://link.springer.com/article/10.1007/s11222-016-9696-4) | [arXiv preprint](https://arxiv.org/abs/1507.04544). * Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.02646](https://arxiv.org/abs/1507.02646). # Setup In addition to the __loo__ package, we'll also be using __rstanarm__ and __bayesplot__: ```{r setup, message=FALSE} library("rstanarm") library("bayesplot") library("loo") ``` # Example: Poisson vs negative binomial for the roaches dataset ## Background and model fitting The Poisson and negative binomial regression models used below in our example, as well as the `stan_glm` function used to fit the models, are covered in more depth in the __rstanarm__ vignette [_Estimating Generalized Linear Models for Count Data with rstanarm_](http://mc-stan.org/rstanarm/articles/count.html). In the rest of this vignette we will assume the reader is already familiar with these kinds of models. ### Roaches data The example data we'll use comes from Chapter 8.3 of [Gelman and Hill (2007)](http://www.stat.columbia.edu/~gelman/arm/). We want to make inferences about the efficacy of a certain pest management system at reducing the number of roaches in urban apartments. Here is how Gelman and Hill describe the experiment and data (pg. 161): > the treatment and control were applied to 160 and 104 apartments, respectively, and the outcome measurement $y_i$ in each apartment $i$ was the number of roaches caught in a set of traps. Different apartments had traps for different numbers of days In addition to an intercept, the regression predictors for the model are `roach1`, the pre-treatment number of roaches (rescaled above to be in units of hundreds), the treatment indicator `treatment`, and a variable indicating whether the apartment is in a building restricted to elderly residents `senior`. Because the number of days for which the roach traps were used is not the same for all apartments in the sample, we use the `offset` argument to specify that `log(exposure2)` should be added to the linear predictor. ```{r data} # the 'roaches' data frame is included with the rstanarm package data(roaches) str(roaches) # rescale to units of hundreds of roaches roaches$roach1 <- roaches$roach1 / 100 ``` ### Fit Poisson model We'll fit a simple Poisson regression model using the `stan_glm` function from the __rstanarm__ package. ```{r count-roaches-mcmc, results="hide"} fit1 <- stan_glm( formula = y ~ roach1 + treatment + senior, offset = log(exposure2), data = roaches, family = poisson(link = "log"), prior = normal(0, 2.5, autoscale = TRUE), prior_intercept = normal(0, 5, autoscale = TRUE), seed = 12345 ) ``` Usually we would also run posterior predictive checks as shown in the __rstanarm__ vignette [Estimating Generalized Linear Models for Count Data with rstanarm](http://mc-stan.org/rstanarm/articles/count.html), but here we focus only on methods provided by the __loo__ package.
## Using the __loo__ package for model checking and comparison _Although cross-validation is mostly used for model comparison, it is also useful for model checking._ ### Computing PSIS-LOO and checking diagnostics We start by computing PSIS-LOO with the `loo` function. Since we fit our model using __rstanarm__ we can use the `loo` method for `stanreg` objects (fitted model objects from __rstanarm__), which doesn't require us to first extract the pointwise log-likelihood values. If we had written our own Stan program instead of using __rstanarm__ we would pass an array or matrix of log-likelihood values to the `loo` function (see, e.g. `help("loo.array", package = "loo")`). We'll also use the argument `save_psis = TRUE` to save some intermediate results to be re-used later. ```{r loo1} loo1 <- loo(fit1, save_psis = TRUE) ``` `loo` gives us warnings about the Pareto diagnostics, which indicate that for some observations the leave-one-out posteriors are different enough from the full posterior that importance-sampling is not able to correct the difference. We can see more details by printing the `loo` object. ```{r print-loo1} print(loo1) ``` The table shows us a summary of Pareto $k$ diagnostic, which is used to assess the reliability of the estimates. In addition to the proportion of leave-one-out folds with $k$ values in different intervals, the minimum of the effective sample sizes in that category is shown to give idea why higher $k$ values are bad. Since we have some $k>1$, we are not able to compute an estimate for the Monte Carlo standard error (SE) of the expected log predictive density (`elpd_loo`) and `NA` is displayed. (Full details on the interpretation of the Pareto $k$ diagnostics are available in the Vehtari, Gelman, and Gabry (2017) and Vehtari, Simpson, Gelman, Yao, and Gabry (2019) papers referenced at the top of this vignette.) In this case the `elpd_loo` estimate should not be considered reliable. If we had a well-specified model we would expect the estimated effective number of parameters (`p_loo`) to be smaller than or similar to the total number of parameters in the model. Here `p_loo` is almost 300, which is about 70 times the total number of parameters in the model, indicating severe model misspecification. ### Plotting Pareto $k$ diagnostics Using the `plot` method on our `loo1` object produces a plot of the $k$ values (in the same order as the observations in the dataset used to fit the model) with horizontal lines corresponding to the same categories as in the printed output above. ```{r plot-loo1, out.width = "70%"} plot(loo1) ``` This plot is useful to quickly see the distribution of $k$ values, but it's often also possible to see structure with respect to data ordering. In our case this is mild, but there seems to be a block of data that is somewhat easier to predict (indices around 90--150). Unfortunately even for these data points we see some high $k$ values. ### Marginal posterior predictive checks The `loo` package can be used in combination with the `bayesplot` package for leave-one-out cross-validation marginal posterior predictive checks [Gabry et al (2018)](https://arxiv.org/abs/1709.01449). LOO-PIT values are cumulative probabilities for $y_i$ computed using the LOO marginal predictive distributions $p(y_i|y_{-i})$. For a good model, the distribution of LOO-PIT values should be uniform. In the following plot the distribution (smoothed density estimate) of the LOO-PIT values for our model (thick curve) is compared to many independently generated samples (each the same size as our dataset) from the standard uniform distribution (thin curves). ```{r ppc_loo_pit_overlay} yrep <- posterior_predict(fit1) ppc_loo_pit_overlay( y = roaches$y, yrep = yrep, lw = weights(loo1$psis_object) ) ``` The excessive number of values close to 0 indicates that the model is under-dispersed compared to the data, and we should consider a model that allows for greater dispersion. ## Try alternative model with more flexibility Here we will try [negative binomial](https://en.wikipedia.org/wiki/Negative_binomial_distribution) regression, which is commonly used for overdispersed count data. Unlike the Poisson distribution, the negative binomial distribution allows the conditional mean and variance of $y$ to differ. ```{r count-roaches-negbin, results="hide"} fit2 <- update(fit1, family = neg_binomial_2) ``` ```{r loo2} loo2 <- loo(fit2, save_psis = TRUE, cores = 2) print(loo2) ``` ```{r plot-loo2} plot(loo2, label_points = TRUE) ``` Using the `label_points` argument will label any $k$ values larger than 0.7 with the index of the corresponding data point. These high values are often the result of model misspecification and frequently correspond to data points that would be considered ``outliers'' in the data and surprising according to the model [Gabry et al (2019)](https://arxiv.org/abs/1709.01449). Unfortunately, while large $k$ values are a useful indicator of model misspecification, small $k$ values are not a guarantee that a model is well-specified. If there are a small number of problematic $k$ values then we can use a feature in __rstanarm__ that lets us refit the model once for each of these problematic observations. Each time the model is refit, one of the observations with a high $k$ value is omitted and the LOO calculations are performed exactly for that observation. The results are then recombined with the approximate LOO calculations already carried out for the observations without problematic $k$ values: ```{r reloo} if (any(pareto_k_values(loo2) > 0.7)) { loo2 <- loo(fit2, save_psis = TRUE, k_threshold = 0.7) } print(loo2) ``` In the print output we can see that the Monte Carlo SE is small compared to the other uncertainties. On the other hand, `p_loo` is about 7 and still a bit higher than the total number of parameters in the model. This indicates that there is almost certainly still some degree of model misspecification, but this is much better than the `p_loo` estimate for the Poisson model. For further model checking we again examine the LOO-PIT values. ```{r ppc_loo_pit_overlay-negbin} yrep <- posterior_predict(fit2) ppc_loo_pit_overlay(roaches$y, yrep, lw = weights(loo2$psis_object)) ``` The plot for the negative binomial model looks better than the Poisson plot, but we still see that this model is not capturing all of the essential features in the data. ## Comparing the models on expected log predictive density We can use the `loo_compare` function to compare our two models on expected log predictive density (ELPD) for new data: ```{r loo_compare} loo_compare(loo1, loo2) ``` The difference in ELPD is much larger than several times the estimated standard error of the difference again indicating that the negative-binomial model is expected to have better predictive performance than the Poisson model. However, according to the LOO-PIT checks there is still some misspecification, and a reasonable guess is that a hurdle or zero-inflated model would be an improvement (we leave that for another case study).
# References Gabry, J., Simpson, D., Vehtari, A., Betancourt, M. and Gelman, A. (2019), Visualization in Bayesian workflow. _J. R. Stat. Soc. A_, 182: 389-402. \doi:10.1111/rssa.12378. ([journal version](https://rss.onlinelibrary.wiley.com/doi/full/10.1111/rssa.12378), [arXiv preprint](https://arxiv.org/abs/1709.01449), [code on GitHub](https://github.com/jgabry/bayes-vis-paper)) Gelman, A. and Hill, J. (2007). _Data Analysis Using Regression and Multilevel/Hierarchical Models._ Cambridge University Press, Cambridge, UK. Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. _Statistics and Computing_. 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. [online](https://link.springer.com/article/10.1007/s11222-016-9696-4), [arXiv preprint arXiv:1507.04544](https://arxiv.org/abs/1507.04544). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.02646](https://arxiv.org/abs/1507.02646). loo/inst/doc/loo2-moment-matching.Rmd0000644000176200001440000002774214407123455017212 0ustar liggesusers--- title: "Avoiding model refits in leave-one-out cross-validation with moment matching" author: "Topi Paananen, Paul Bürkner, Aki Vehtari and Jonah Gabry" date: "`r Sys.Date()`" output: html_vignette: toc: yes params: EVAL: !r identical(Sys.getenv("NOT_CRAN"), "true") --- ```{r, child="children/SETTINGS-knitr.txt"} ``` ```{r, child="children/SEE-ONLINE.txt", eval = if (isTRUE(exists("params"))) !params$EVAL else TRUE} ``` # Introduction This vignette demonstrates how to improve the Monte Carlo sampling accuracy of leave-one-out cross-validation with the __loo__ package and Stan. The __loo__ package automatically monitors the sampling accuracy using Pareto $k$ diagnostics for each observation. Here, we present a method for quickly improving the accuracy when the Pareto diagnostics indicate problems. This is done by performing some additional computations using the existing posterior sample. If successful, this will decrease the Pareto $k$ values, making the model assessment more reliable. __loo__ also stores the original Pareto $k$ values with the name `influence_pareto_k` which are not changed. They can be used as a diagnostic of how much each observation influences the posterior distribution. The methodology presented is based on the paper * Paananen, T., Piironen, J., Buerkner, P.-C., Vehtari, A. (2020). Implicitly Adaptive Importance Sampling. [arXiv preprint arXiv:1906.08850](https://arxiv.org/abs/1906.08850). More information about the Pareto $k$ diagnostics is given in the following papers * Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. _Statistics and Computing_. 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. Links: [published](https://link.springer.com/article/10.1007/s11222-016-9696-4) | [arXiv preprint](https://arxiv.org/abs/1507.04544). * Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.02646](https://arxiv.org/abs/1507.02646). # Example: Eradication of Roaches We will use the same example as in the vignette [_Using the loo package (version >= 2.0.0)_](https://mc-stan.org/loo/articles/loo2-example.html). See the demo for a description of the problem and data. We will use the same Poisson regression model as in the case study. ## Coding the Stan model Here is the Stan code for fitting the Poisson regression model, which we will use for modeling the number of roaches. ```{r stancode} stancode <- " data { int K; int N; matrix[N,K] x; int y[N]; vector[N] offset; real beta_prior_scale; real alpha_prior_scale; } parameters { vector[K] beta; real intercept; } model { y ~ poisson(exp(x * beta + intercept + offset)); beta ~ normal(0,beta_prior_scale); intercept ~ normal(0,alpha_prior_scale); } generated quantities { vector[N] log_lik; for (n in 1:N) log_lik[n] = poisson_lpmf(y[n] | exp(x[n] * beta + intercept + offset[n])); } " ``` Following the usual approach recommended in [_Writing Stan programs for use with the loo package_](http://mc-stan.org/loo/articles/loo2-with-rstan.html), we compute the log-likelihood for each observation in the `generated quantities` block of the Stan program. ## Setup In addition to __loo__, we load the __rstan__ package for fitting the model, and the __rstanarm__ package for the data. ```{r setup, message=FALSE} library("rstan") library("loo") seed <- 9547 set.seed(seed) ``` ## Fitting the model with RStan Next we fit the model in Stan using the __rstan__ package: ```{r modelfit, message=FALSE} # Prepare data data(roaches, package = "rstanarm") roaches$roach1 <- sqrt(roaches$roach1) y <- roaches$y x <- roaches[,c("roach1", "treatment", "senior")] offset <- log(roaches[,"exposure2"]) n <- dim(x)[1] k <- dim(x)[2] standata <- list(N = n, K = k, x = as.matrix(x), y = y, offset = offset, beta_prior_scale = 2.5, alpha_prior_scale = 5.0) # Compile stanmodel <- stan_model(model_code = stancode) # Fit model fit <- sampling(stanmodel, data = standata, seed = seed, refresh = 0) print(fit, pars = "beta") ``` Let us now evaluate the predictive performance of the model using `loo()`. ```{r loo1} loo1 <- loo(fit) loo1 ``` The `loo()` function output warnings that there are some observations which are highly influential, and thus the accuracy of importance sampling is compromised as indicated by the large Pareto $k$ diagnostic values (> 0.7). As discussed in the vignette [_Using the loo package (version >= 2.0.0)_](https://mc-stan.org/loo/articles/loo2-example.html), this may be an indication of model misspecification. Despite that, it is still beneficial to be able to evaluate the predictive performance of the model accurately. ## Moment matching correction for importance sampling To improve the accuracy of the `loo()` result above, we could perform leave-one-out cross-validation by explicitly leaving out single observations and refitting the model using MCMC repeatedly. However, the Pareto $k$ diagnostics indicate that there are 19 observations which are problematic. This would require 19 model refits which may require a lot of computation time. Instead of refitting with MCMC, we can perform a faster moment matching correction to the importance sampling for the problematic observations. This can be done with the `loo_moment_match()` function in the __loo__ package, which takes our existing `loo` object as input and modifies it. The moment matching requires some evaluations of the model posterior density. For models fitted with __rstan__, this can be conveniently done by using the existing `stanfit` object. First, we show how the moment matching can be used for a model fitted using __rstan__. It only requires setting the argument `moment_match` to `TRUE` in the `loo()` function. Optionally, you can also set the argument `k_threshold` which determines the Pareto $k$ threshold, above which moment matching is used. By default, it operates on all observations whose Pareto $k$ value is larger than 0.7. ```{r loo_moment_match} # available in rstan >= 2.21 loo2 <- loo(fit, moment_match = TRUE) loo2 ``` After the moment matching, all observations have the diagnostic Pareto $k$ less than 0.7, meaning that the estimates are now reliable. The total `elpd_loo` estimate also changed from `-5457.8` to `-5478.5`, showing that before moment matching, `loo()` overestimated the predictive performance of the model. The updated Pareto $k$ values stored in `loo2$diagnostics$pareto_k` are considered algorithmic diagnostic values that indicate the sampling accuracy. The original Pareto $k$ values are stored in `loo2$pointwise[,"influence_pareto_k"]` and these are not modified by the moment matching. These can be considered as diagnostics for how big influence each observation has on the posterior distribution. In addition to the Pareto $k$ diagnostics, moment matching also updates the effective sample size estimates. # Using `loo_moment_match()` directly The moment matching can also be performed by explicitly calling the function `loo_moment_match()`. This enables its use also for models that are not using __rstan__ or another package with built-in support for `loo_moment_match()`. To use `loo_moment_match()`, the user must give the model object `x`, the `loo` object, and 5 helper functions as arguments to `loo_moment_match()`. The helper functions are * `post_draws` + A function the takes `x` as the first argument and returns a matrix of posterior draws of the model parameters, `pars`. * `log_lik_i` + A function that takes `x` and `i` and returns a matrix (one column per chain) or a vector (all chains stacked) of log-likeliood draws of the ith observation based on the model `x`. If the draws are obtained using MCMC, the matrix with MCMC chains separated is preferred. * `unconstrain_pars` + A function that takes arguments `x` and `pars`, and returns posterior draws on the unconstrained space based on the posterior draws on the constrained space passed via `pars`. * `log_prob_upars` + A function that takes arguments `x` and `upars`, and returns a matrix of log-posterior density values of the unconstrained posterior draws passed via `upars`. * `log_lik_i_upars` + A function that takes arguments `x`, `upars`, and `i` and returns a vector of log-likelihood draws of the `i`th observation based on the unconstrained posterior draws passed via `upars`. Next, we show how the helper functions look like for RStan objects, and show an example of using `loo_moment_match()` directly. For stanfit objects from __rstan__ objects, the functions look like this: ```{r stanfitfuns} # create a named list of draws for use with rstan methods .rstan_relist <- function(x, skeleton) { out <- utils::relist(x, skeleton) for (i in seq_along(skeleton)) { dim(out[[i]]) <- dim(skeleton[[i]]) } out } # rstan helper function to get dims of parameters right .create_skeleton <- function(pars, dims) { out <- lapply(seq_along(pars), function(i) { len_dims <- length(dims[[i]]) if (len_dims < 1) return(0) return(array(0, dim = dims[[i]])) }) names(out) <- pars out } # extract original posterior draws post_draws_stanfit <- function(x, ...) { as.matrix(x) } # compute a matrix of log-likelihood values for the ith observation # matrix contains information about the number of MCMC chains log_lik_i_stanfit <- function(x, i, parameter_name = "log_lik", ...) { loo::extract_log_lik(x, parameter_name, merge_chains = FALSE)[, , i] } # transform parameters to the unconstraint space unconstrain_pars_stanfit <- function(x, pars, ...) { skeleton <- .create_skeleton(x@sim$pars_oi, x@par_dims[x@sim$pars_oi]) upars <- apply(pars, 1, FUN = function(theta) { rstan::unconstrain_pars(x, .rstan_relist(theta, skeleton)) }) # for one parameter models if (is.null(dim(upars))) { dim(upars) <- c(1, length(upars)) } t(upars) } # compute log_prob for each posterior draws on the unconstrained space log_prob_upars_stanfit <- function(x, upars, ...) { apply(upars, 1, rstan::log_prob, object = x, adjust_transform = TRUE, gradient = FALSE) } # compute log_lik values based on the unconstrained parameters log_lik_i_upars_stanfit <- function(x, upars, i, parameter_name = "log_lik", ...) { S <- nrow(upars) out <- numeric(S) for (s in seq_len(S)) { out[s] <- rstan::constrain_pars(x, upars = upars[s, ])[[parameter_name]][i] } out } ``` Using these function, we can call `loo_moment_match()` to update the existing `loo` object. ```{r loo_moment_match.default, message=FALSE} loo3 <- loo::loo_moment_match.default( x = fit, loo = loo1, post_draws = post_draws_stanfit, log_lik_i = log_lik_i_stanfit, unconstrain_pars = unconstrain_pars_stanfit, log_prob_upars = log_prob_upars_stanfit, log_lik_i_upars = log_lik_i_upars_stanfit ) loo3 ``` As expected, the result is identical to the previous result of `loo2 <- loo(fit, moment_match = TRUE)`. # References Gelman, A., and Hill, J. (2007). *Data Analysis Using Regression and Multilevel Hierarchical Models.* Cambridge University Press. Stan Development Team (2020) _RStan: the R interface to Stan, Version 2.21.1_ https://mc-stan.org Paananen, T., Piironen, J., Buerkner, P.-C., Vehtari, A. (2021). Implicitly adaptive importance sampling. _Statistics and Computing_, 31, 16. \doi:10.1007/s11222-020-09982-2. arXiv preprint arXiv:1906.08850. Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. _Statistics and Computing_. 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. Links: [published](https://link.springer.com/article/10.1007/s11222-016-9696-4) | [arXiv preprint](https://arxiv.org/abs/1507.04544). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.02646](https://arxiv.org/abs/1507.02646). loo/inst/doc/loo2-moment-matching.html0000644000176200001440000012225414411465147017430 0ustar liggesusers Avoiding model refits in leave-one-out cross-validation with moment matching

Avoiding model refits in leave-one-out cross-validation with moment matching

Topi Paananen, Paul Bürkner, Aki Vehtari and Jonah Gabry

2023-03-30

Introduction

This vignette demonstrates how to improve the Monte Carlo sampling accuracy of leave-one-out cross-validation with the loo package and Stan. The loo package automatically monitors the sampling accuracy using Pareto \(k\) diagnostics for each observation. Here, we present a method for quickly improving the accuracy when the Pareto diagnostics indicate problems. This is done by performing some additional computations using the existing posterior sample. If successful, this will decrease the Pareto \(k\) values, making the model assessment more reliable. loo also stores the original Pareto \(k\) values with the name influence_pareto_k which are not changed. They can be used as a diagnostic of how much each observation influences the posterior distribution.

The methodology presented is based on the paper

More information about the Pareto \(k\) diagnostics is given in the following papers

  • Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. Statistics and Computing. 27(5), 1413–1432. :10.1007/s11222-016-9696-4. Links: published | arXiv preprint.

  • Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. arXiv preprint arXiv:1507.02646.

Example: Eradication of Roaches

We will use the same example as in the vignette Using the loo package (version >= 2.0.0). See the demo for a description of the problem and data. We will use the same Poisson regression model as in the case study.

Coding the Stan model

Here is the Stan code for fitting the Poisson regression model, which we will use for modeling the number of roaches.

stancode <- "
data {
  int<lower=1> K;
  int<lower=1> N;
  matrix[N,K] x;
  int y[N];
  vector[N] offset;

  real beta_prior_scale;
  real alpha_prior_scale;
}
parameters {
  vector[K] beta;
  real intercept;
}
model {
  y ~ poisson(exp(x * beta + intercept + offset));
  beta ~ normal(0,beta_prior_scale);
  intercept ~ normal(0,alpha_prior_scale);
}
generated quantities {
  vector[N] log_lik;
  for (n in 1:N)
    log_lik[n] = poisson_lpmf(y[n] | exp(x[n] * beta + intercept + offset[n]));
}
"

Following the usual approach recommended in Writing Stan programs for use with the loo package, we compute the log-likelihood for each observation in the generated quantities block of the Stan program.

Setup

In addition to loo, we load the rstan package for fitting the model, and the rstanarm package for the data.

library("rstan")
library("loo")
seed <- 9547
set.seed(seed)

Fitting the model with RStan

Next we fit the model in Stan using the rstan package:

# Prepare data
data(roaches, package = "rstanarm")
roaches$roach1 <- sqrt(roaches$roach1)
y <- roaches$y
x <- roaches[,c("roach1", "treatment", "senior")]
offset <- log(roaches[,"exposure2"])
n <- dim(x)[1]
k <- dim(x)[2]

standata <- list(N = n, K = k, x = as.matrix(x), y = y, offset = offset, beta_prior_scale = 2.5, alpha_prior_scale = 5.0)

# Compile
stanmodel <- stan_model(model_code = stancode)

# Fit model
fit <- sampling(stanmodel, data = standata, seed = seed, refresh = 0)
print(fit, pars = "beta")
Inference for Stan model: anon_model.
4 chains, each with iter=2000; warmup=1000; thin=1; 
post-warmup draws per chain=1000, total post-warmup draws=4000.

         mean se_mean   sd  2.5%   25%   50%   75% 97.5% n_eff Rhat
beta[1]  0.16       0 0.00  0.16  0.16  0.16  0.16  0.16  2344    1
beta[2] -0.57       0 0.03 -0.62 -0.59 -0.57 -0.55 -0.52  2395    1
beta[3] -0.31       0 0.03 -0.38 -0.34 -0.31 -0.29 -0.25  2135    1

Samples were drawn using NUTS(diag_e) at Thu Mar 30 23:06:35 2023.
For each parameter, n_eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor on split chains (at 
convergence, Rhat=1).

Let us now evaluate the predictive performance of the model using loo().

loo1 <- loo(fit)
Warning: Some Pareto k diagnostic values are too high. See help('pareto-k-diagnostic') for details.
loo1

Computed from 4000 by 262 log-likelihood matrix

         Estimate     SE
elpd_loo  -5459.4  694.1
p_loo       258.8   55.4
looic     10918.9 1388.2
------
Monte Carlo SE of elpd_loo is NA.

Pareto k diagnostic values:
                         Count Pct.    Min. n_eff
(-Inf, 0.5]   (good)     241   92.0%   241       
 (0.5, 0.7]   (ok)         7    2.7%   53        
   (0.7, 1]   (bad)        7    2.7%   24        
   (1, Inf)   (very bad)   7    2.7%   2         
See help('pareto-k-diagnostic') for details.

The loo() function output warnings that there are some observations which are highly influential, and thus the accuracy of importance sampling is compromised as indicated by the large Pareto \(k\) diagnostic values (> 0.7). As discussed in the vignette Using the loo package (version >= 2.0.0), this may be an indication of model misspecification. Despite that, it is still beneficial to be able to evaluate the predictive performance of the model accurately.

Moment matching correction for importance sampling

To improve the accuracy of the loo() result above, we could perform leave-one-out cross-validation by explicitly leaving out single observations and refitting the model using MCMC repeatedly. However, the Pareto \(k\) diagnostics indicate that there are 19 observations which are problematic. This would require 19 model refits which may require a lot of computation time.

Instead of refitting with MCMC, we can perform a faster moment matching correction to the importance sampling for the problematic observations. This can be done with the loo_moment_match() function in the loo package, which takes our existing loo object as input and modifies it. The moment matching requires some evaluations of the model posterior density. For models fitted with rstan, this can be conveniently done by using the existing stanfit object.

First, we show how the moment matching can be used for a model fitted using rstan. It only requires setting the argument moment_match to TRUE in the loo() function. Optionally, you can also set the argument k_threshold which determines the Pareto \(k\) threshold, above which moment matching is used. By default, it operates on all observations whose Pareto \(k\) value is larger than 0.7.

# available in rstan >= 2.21
loo2 <- loo(fit, moment_match = TRUE)
Warning: Some Pareto k diagnostic values are slightly high. See help('pareto-k-diagnostic') for details.
loo2

Computed from 4000 by 262 log-likelihood matrix

         Estimate     SE
elpd_loo  -5478.8  700.0
p_loo       269.8   61.5
looic     10957.7 1400.1
------
Monte Carlo SE of elpd_loo is 0.4.

Pareto k diagnostic values:
                         Count Pct.    Min. n_eff
(-Inf, 0.5]   (good)     252   96.2%   236       
 (0.5, 0.7]   (ok)        10    3.8%   50        
   (0.7, 1]   (bad)        0    0.0%   <NA>      
   (1, Inf)   (very bad)   0    0.0%   <NA>      

All Pareto k estimates are ok (k < 0.7).
See help('pareto-k-diagnostic') for details.

After the moment matching, all observations have the diagnostic Pareto \(k\) less than 0.7, meaning that the estimates are now reliable. The total elpd_loo estimate also changed from -5457.8 to -5478.5, showing that before moment matching, loo() overestimated the predictive performance of the model.

The updated Pareto \(k\) values stored in loo2$diagnostics$pareto_k are considered algorithmic diagnostic values that indicate the sampling accuracy. The original Pareto \(k\) values are stored in loo2$pointwise[,"influence_pareto_k"] and these are not modified by the moment matching. These can be considered as diagnostics for how big influence each observation has on the posterior distribution. In addition to the Pareto \(k\) diagnostics, moment matching also updates the effective sample size estimates.

Using loo_moment_match() directly

The moment matching can also be performed by explicitly calling the function loo_moment_match(). This enables its use also for models that are not using rstan or another package with built-in support for loo_moment_match(). To use loo_moment_match(), the user must give the model object x, the loo object, and 5 helper functions as arguments to loo_moment_match(). The helper functions are

  • post_draws
    • A function the takes x as the first argument and returns a matrix of posterior draws of the model parameters, pars.
  • log_lik_i
    • A function that takes x and i and returns a matrix (one column per chain) or a vector (all chains stacked) of log-likeliood draws of the ith observation based on the model x. If the draws are obtained using MCMC, the matrix with MCMC chains separated is preferred.
  • unconstrain_pars
    • A function that takes arguments x and pars, and returns posterior draws on the unconstrained space based on the posterior draws on the constrained space passed via pars.
  • log_prob_upars
    • A function that takes arguments x and upars, and returns a matrix of log-posterior density values of the unconstrained posterior draws passed via upars.
  • log_lik_i_upars
    • A function that takes arguments x, upars, and i and returns a vector of log-likelihood draws of the ith observation based on the unconstrained posterior draws passed via upars.

Next, we show how the helper functions look like for RStan objects, and show an example of using loo_moment_match() directly. For stanfit objects from rstan objects, the functions look like this:

# create a named list of draws for use with rstan methods
.rstan_relist <- function(x, skeleton) {
  out <- utils::relist(x, skeleton)
  for (i in seq_along(skeleton)) {
    dim(out[[i]]) <- dim(skeleton[[i]])
  }
  out
}

# rstan helper function to get dims of parameters right
.create_skeleton <- function(pars, dims) {
  out <- lapply(seq_along(pars), function(i) {
    len_dims <- length(dims[[i]])
    if (len_dims < 1) return(0)
    return(array(0, dim = dims[[i]]))
  })
  names(out) <- pars
  out
}

# extract original posterior draws
post_draws_stanfit <- function(x, ...) {
  as.matrix(x)
}

# compute a matrix of log-likelihood values for the ith observation
# matrix contains information about the number of MCMC chains
log_lik_i_stanfit <- function(x, i, parameter_name = "log_lik", ...) {
  loo::extract_log_lik(x, parameter_name, merge_chains = FALSE)[, , i]
}

# transform parameters to the unconstraint space
unconstrain_pars_stanfit <- function(x, pars, ...) {
  skeleton <- .create_skeleton(x@sim$pars_oi, x@par_dims[x@sim$pars_oi])
  upars <- apply(pars, 1, FUN = function(theta) {
    rstan::unconstrain_pars(x, .rstan_relist(theta, skeleton))
  })
  # for one parameter models
  if (is.null(dim(upars))) {
    dim(upars) <- c(1, length(upars))
  }
  t(upars)
}

# compute log_prob for each posterior draws on the unconstrained space
log_prob_upars_stanfit <- function(x, upars, ...) {
  apply(upars, 1, rstan::log_prob, object = x,
        adjust_transform = TRUE, gradient = FALSE)
}

# compute log_lik values based on the unconstrained parameters
log_lik_i_upars_stanfit <- function(x, upars, i, parameter_name = "log_lik",
                                  ...) {
  S <- nrow(upars)
  out <- numeric(S)
  for (s in seq_len(S)) {
    out[s] <- rstan::constrain_pars(x, upars = upars[s, ])[[parameter_name]][i]
  }
  out
}

Using these function, we can call loo_moment_match() to update the existing loo object.

loo3 <- loo::loo_moment_match.default(
  x = fit,
  loo = loo1,
  post_draws = post_draws_stanfit,
  log_lik_i = log_lik_i_stanfit,
  unconstrain_pars = unconstrain_pars_stanfit,
  log_prob_upars = log_prob_upars_stanfit,
  log_lik_i_upars = log_lik_i_upars_stanfit
)
Warning: Some Pareto k diagnostic values are slightly high. See help('pareto-k-diagnostic') for details.
loo3

Computed from 4000 by 262 log-likelihood matrix

         Estimate     SE
elpd_loo  -5478.8  700.0
p_loo       269.8   61.5
looic     10957.7 1400.1
------
Monte Carlo SE of elpd_loo is 0.4.

Pareto k diagnostic values:
                         Count Pct.    Min. n_eff
(-Inf, 0.5]   (good)     252   96.2%   236       
 (0.5, 0.7]   (ok)        10    3.8%   50        
   (0.7, 1]   (bad)        0    0.0%   <NA>      
   (1, Inf)   (very bad)   0    0.0%   <NA>      

All Pareto k estimates are ok (k < 0.7).
See help('pareto-k-diagnostic') for details.

As expected, the result is identical to the previous result of loo2 <- loo(fit, moment_match = TRUE).

References

Gelman, A., and Hill, J. (2007). Data Analysis Using Regression and Multilevel Hierarchical Models. Cambridge University Press.

Stan Development Team (2020) RStan: the R interface to Stan, Version 2.21.1 https://mc-stan.org

Paananen, T., Piironen, J., Buerkner, P.-C., Vehtari, A. (2021). Implicitly adaptive importance sampling. Statistics and Computing, 31, 16. :10.1007/s11222-020-09982-2. arXiv preprint arXiv:1906.08850.

Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. Statistics and Computing. 27(5), 1413–1432. :10.1007/s11222-016-9696-4. Links: published | arXiv preprint.

Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. arXiv preprint arXiv:1507.02646.

loo/inst/doc/loo2-moment-matching.R0000644000176200001440000001014414411465147016657 0ustar liggesusersparams <- list(EVAL = TRUE) ## ----SETTINGS-knitr, include=FALSE-------------------------------------------- stopifnot(require(knitr)) opts_chunk$set( comment=NA, eval = if (isTRUE(exists("params"))) params$EVAL else FALSE, dev = "png", dpi = 150, fig.asp = 0.618, fig.width = 5, out.width = "60%", fig.align = "center" ) ## ----stancode----------------------------------------------------------------- stancode <- " data { int K; int N; matrix[N,K] x; int y[N]; vector[N] offset; real beta_prior_scale; real alpha_prior_scale; } parameters { vector[K] beta; real intercept; } model { y ~ poisson(exp(x * beta + intercept + offset)); beta ~ normal(0,beta_prior_scale); intercept ~ normal(0,alpha_prior_scale); } generated quantities { vector[N] log_lik; for (n in 1:N) log_lik[n] = poisson_lpmf(y[n] | exp(x[n] * beta + intercept + offset[n])); } " ## ----setup, message=FALSE----------------------------------------------------- library("rstan") library("loo") seed <- 9547 set.seed(seed) ## ----modelfit, message=FALSE-------------------------------------------------- # Prepare data data(roaches, package = "rstanarm") roaches$roach1 <- sqrt(roaches$roach1) y <- roaches$y x <- roaches[,c("roach1", "treatment", "senior")] offset <- log(roaches[,"exposure2"]) n <- dim(x)[1] k <- dim(x)[2] standata <- list(N = n, K = k, x = as.matrix(x), y = y, offset = offset, beta_prior_scale = 2.5, alpha_prior_scale = 5.0) # Compile stanmodel <- stan_model(model_code = stancode) # Fit model fit <- sampling(stanmodel, data = standata, seed = seed, refresh = 0) print(fit, pars = "beta") ## ----loo1--------------------------------------------------------------------- loo1 <- loo(fit) loo1 ## ----loo_moment_match--------------------------------------------------------- # available in rstan >= 2.21 loo2 <- loo(fit, moment_match = TRUE) loo2 ## ----stanfitfuns-------------------------------------------------------------- # create a named list of draws for use with rstan methods .rstan_relist <- function(x, skeleton) { out <- utils::relist(x, skeleton) for (i in seq_along(skeleton)) { dim(out[[i]]) <- dim(skeleton[[i]]) } out } # rstan helper function to get dims of parameters right .create_skeleton <- function(pars, dims) { out <- lapply(seq_along(pars), function(i) { len_dims <- length(dims[[i]]) if (len_dims < 1) return(0) return(array(0, dim = dims[[i]])) }) names(out) <- pars out } # extract original posterior draws post_draws_stanfit <- function(x, ...) { as.matrix(x) } # compute a matrix of log-likelihood values for the ith observation # matrix contains information about the number of MCMC chains log_lik_i_stanfit <- function(x, i, parameter_name = "log_lik", ...) { loo::extract_log_lik(x, parameter_name, merge_chains = FALSE)[, , i] } # transform parameters to the unconstraint space unconstrain_pars_stanfit <- function(x, pars, ...) { skeleton <- .create_skeleton(x@sim$pars_oi, x@par_dims[x@sim$pars_oi]) upars <- apply(pars, 1, FUN = function(theta) { rstan::unconstrain_pars(x, .rstan_relist(theta, skeleton)) }) # for one parameter models if (is.null(dim(upars))) { dim(upars) <- c(1, length(upars)) } t(upars) } # compute log_prob for each posterior draws on the unconstrained space log_prob_upars_stanfit <- function(x, upars, ...) { apply(upars, 1, rstan::log_prob, object = x, adjust_transform = TRUE, gradient = FALSE) } # compute log_lik values based on the unconstrained parameters log_lik_i_upars_stanfit <- function(x, upars, i, parameter_name = "log_lik", ...) { S <- nrow(upars) out <- numeric(S) for (s in seq_len(S)) { out[s] <- rstan::constrain_pars(x, upars = upars[s, ])[[parameter_name]][i] } out } ## ----loo_moment_match.default, message=FALSE---------------------------------- loo3 <- loo::loo_moment_match.default( x = fit, loo = loo1, post_draws = post_draws_stanfit, log_lik_i = log_lik_i_stanfit, unconstrain_pars = unconstrain_pars_stanfit, log_prob_upars = log_prob_upars_stanfit, log_lik_i_upars = log_lik_i_upars_stanfit ) loo3 loo/inst/doc/loo2-non-factorized.Rmd0000644000176200001440000006631014407123455017037 0ustar liggesusers--- title: "Leave-one-out cross-validation for non-factorized models" author: "Aki Vehtari, Paul Bürkner and Jonah Gabry" date: "`r Sys.Date()`" output: html_vignette: toc: yes encoding: "UTF-8" params: EVAL: !r identical(Sys.getenv("NOT_CRAN"), "true") --- ```{r settings, child="children/SETTINGS-knitr.txt"} ``` ```{r more-knitr-ops, include=FALSE} knitr::opts_chunk$set( cache=TRUE, message=FALSE, warning=FALSE ) ``` ```{r, child="children/SEE-ONLINE.txt", eval = if (isTRUE(exists("params"))) !params$EVAL else TRUE} ``` # Introduction When computing ELPD-based LOO-CV for a Bayesian model we need to compute the log leave-one-out predictive densities $\log{p(y_i | y_{-i})}$ for every response value $y_i, \: i = 1, \ldots, N$, where $y_{-i}$ denotes all response values except observation $i$. To obtain $p(y_i | y_{-i})$, we need to have access to the pointwise likelihood $p(y_i\,|\, y_{-i}, \theta)$ and integrate over the model parameters $\theta$: $$ p(y_i\,|\,y_{-i}) = \int p(y_i\,|\, y_{-i}, \theta) \, p(\theta\,|\, y_{-i}) \,d \theta $$ Here, $p(\theta\,|\, y_{-i})$ is the leave-one-out posterior distribution for $\theta$, that is, the posterior distribution for $\theta$ obtained by fitting the model while holding out the $i$th observation (we will later show how refitting the model to data $y_{-i}$ can be avoided). If the observation model is formulated directly as the product of the pointwise observation models, we call it a *factorized* model. In this case, the likelihood is also the product of the pointwise likelihood contributions $p(y_i\,|\, y_{-i}, \theta)$. To better illustrate possible structures of the observation models, we formally divide $\theta$ into two parts, observation-specific latent variables $f = (f_1, \ldots, f_N)$ and hyperparameters $\psi$, so that $p(y_i\,|\, y_{-i}, \theta) = p(y_i\,|\, y_{-i}, f_i, \psi)$. Depending on the model, one of the two parts of $\theta$ may also be empty. In very simple models, such as linear regression models, latent variables are not explicitly presented and response values are conditionally independent given $\psi$, so that $p(y_i\,|\, y_{-i}, f_i, \psi) = p(y_i \,|\, \psi)$. The full likelihood can then be written in the familiar form $$ p(y \,|\, \psi) = \prod_{i=1}^N p(y_i \,|\, \psi), $$ where $y = (y_1, \ldots, y_N)$ denotes the vector of all responses. When the likelihood factorizes this way, the conditional pointwise log-likelihood can be obtained easily by computing $p(y_i\,|\, \psi)$ for each $i$ with computational cost $O(n)$. Yet, there are several reasons why a *non-factorized* observation model may be necessary or preferred. In non-factorized models, the joint likelihood of the response values $p(y \,|\, \theta)$ is not factorized into observation-specific components, but rather given directly as one joint expression. For some models, an analytic factorized formulation is simply not available in which case we speak of a *non-factorizable* model. Even in models whose observation model can be factorized in principle, it may still be preferable to use a non-factorized form for reasons of efficiency and numerical stability (Bürkner et al. 2020). Whether a non-factorized model is used by necessity or for efficiency and stability, it comes at the cost of having no direct access to the leave-one-out predictive densities and thus to the overall leave-one-out predictive accuracy. In theory, we can express the observation-specific likelihoods in terms of the joint likelihood via $$ p(y_i \,|\, y_{i-1}, \theta) = \frac{p(y \,|\, \theta)}{p(y_{-i} \,|\, \theta)} = \frac{p(y \,|\, \theta)}{\int p(y \,|\, \theta) \, d y_i}, $$ but the expression on the right-hand side may not always have an analytical solution. Computing $\log p(y_i \,|\, y_{-i}, \theta)$ for non-factorized models is therefore often impossible, or at least inefficient and numerically unstable. However, there is a large class of multivariate normal and Student-$t$ models for which there are efficient analytical solutions available. More details can be found in our paper about LOO-CV for non-factorized models (Bürkner, Gabry, & Vehtari, 2020), which is available as a preprint on arXiv (https://arxiv.org/abs/1810.10559). # LOO-CV for multivariate normal models In this vignette, we will focus on non-factorized multivariate normal models. Based on results of Sundararajan and Keerthi (2001), Bürkner et al. (2020) show that, for multivariate normal models with coriance matrix $C$, the LOO predictive mean and standard deviation can be computed as follows: \begin{align} \mu_{\tilde{y},-i} &= y_i-\bar{c}_{ii}^{-1} g_i \nonumber \\ \sigma_{\tilde{y},-i} &= \sqrt{\bar{c}_{ii}^{-1}}, \end{align} where $g_i$ and $\bar{c}_{ii}$ are \begin{align} g_i &= \left[C^{-1} y\right]_i \nonumber \\ \bar{c}_{ii} &= \left[C^{-1}\right]_{ii}. \end{align} Using these results, the log predictive density of the $i$th observation is then computed as $$ \log p(y_i \,|\, y_{-i},\theta) = - \frac{1}{2}\log(2\pi) - \frac{1}{2}\log \sigma^2_{-i} - \frac{1}{2}\frac{(y_i-\mu_{-i})^2}{\sigma^2_{-i}}. $$ Expressing this same equation in terms of $g_i$ and $\bar{c}_{ii}$, the log predictive density becomes: $$ \log p(y_i \,|\, y_{-i},\theta) = - \frac{1}{2}\log(2\pi) + \frac{1}{2}\log \bar{c}_{ii} - \frac{1}{2}\frac{g_i^2}{\bar{c}_{ii}}. $$ (Note that Vehtari et al. (2016) has a typo in the corresponding Equation 34.) From these equations we can now derive a recipe for obtaining the conditional pointwise log-likelihood for _all_ models that can be expressed conditionally in terms of a multivariate normal with invertible covariance matrix $C$. ## Approximate LOO-CV using integrated importance-sampling The above LOO equations for multivariate normal models are conditional on parameters $\theta$. Therefore, to obtain the leave-one-out predictive density $p(y_i \,|\, y_{-i})$ we need to integrate over $\theta$, $$ p(y_i\,|\,y_{-i}) = \int p(y_i\,|\,y_{-i}, \theta) \, p(\theta\,|\,y_{-i}) \,d\theta. $$ Here, $p(\theta\,|\,y_{-i})$ is the leave-one-out posterior distribution for $\theta$, that is, the posterior distribution for $\theta$ obtained by fitting the model while holding out the $i$th observation. To avoid the cost of sampling from $N$ leave-one-out posteriors, it is possible to take the posterior draws $\theta^{(s)}, \, s=1,\ldots,S$, from the \emph{full} posterior $p(\theta\,|\,y)$, and then approximate the above integral using integrated importance sampling (Vehtari et al., 2016, Section 3.6.1): $$ p(y_i\,|\,y_{-i}) \approx \frac{ \sum_{s=1}^S p(y_i\,|\,y_{-i},\,\theta^{(s)}) \,w_i^{(s)}}{ \sum_{s=1}^S w_i^{(s)}}, $$ where $w_i^{(s)}$ are importance weights. First we compute the raw importance ratios $$ r_i^{(s)} \propto \frac{1}{p(y_i \,|\, y_{-i}, \,\theta^{(s)})}, $$ and then stabilize them using Pareto smoothed importance sampling (PSIS, Vehtari et al, 2019) to obtain the weights $w_i^{(s)}$. The resulting approximation is referred to as PSIS-LOO (Vehtari et al, 2017). ## Exact LOO-CV with re-fitting In order to validate the approximate LOO procedure, and also in order to allow exact computations to be made for a small number of leave-one-out folds for which the Pareto $k$ diagnostic (Vehtari et al, 2019) indicates an unstable approximation, we need to consider how we might to do _exact_ leave-one-out CV for a non-factorized model. In the case of a Gaussian process that has the marginalization property, we could just drop the one row and column of $C$ corresponding to the held out out observation. This does not hold in general for multivariate normal models, however, and to keep the original prior we may need to maintain the full covariance matrix $C$ even when one of the observations is left out. The solution is to model $y_i$ as a missing observation and estimate it along with all of the other model parameters. For a conditional multivariate normal model, $\log p(y_i\,|\,y_{-i})$ can be computed as follows. First, we model $y_i$ as missing and denote the corresponding parameter $y_i^{\mathrm{mis}}$. Then, we define $$ y_{\mathrm{mis}(i)} = (y_1, \ldots, y_{i-1}, y_i^{\mathrm{mis}}, y_{i+1}, \ldots, y_N). $$ to be the same as the full set of observations $y$, except replacing $y_i$ with the parameter $y_i^{\mathrm{mis}}$. Second, we compute the LOO predictive mean and standard deviations as above, but replace $y$ with $y_{\mathrm{mis}(i)}$ in the computation of $\mu_{\tilde{y},-i}$: $$ \mu_{\tilde{y},-i} = y_{{\mathrm{mis}}(i)}-\bar{c}_{ii}^{-1}g_i, $$ where in this case we have $$ g_i = \left[ C^{-1} y_{\mathrm{mis}(i)} \right]_i. $$ The conditional log predictive density is then computed with the above $\mu_{\tilde{y},-i}$ and the left out observation $y_i$: $$ \log p(y_i\,|\,y_{-i},\theta) = - \frac{1}{2}\log(2\pi) - \frac{1}{2}\log \sigma^2_{\tilde{y},-i} - \frac{1}{2}\frac{(y_i-\mu_{\tilde{y},-i})^2}{\sigma^2_{\tilde{y},-i}}. $$ Finally, the leave-one-out predictive distribution can then be estimated as $$ p(y_i\,|\,y_{-i}) \approx \sum_{s=1}^S p(y_i\,|\,y_{-i}, \theta_{-i}^{(s)}), $$ where $\theta_{-i}^{(s)}$ are draws from the posterior distribution $p(\theta\,|\,y_{\mathrm{mis}(i)})$. # Lagged SAR models A common non-factorized multivariate normal model is the simultaneously autoregressive (SAR) model, which is frequently used for spatially correlated data. The lagged SAR model is defined as $$ y = \rho Wy + \eta + \epsilon $$ or equivalently $$ (I - \rho W)y = \eta + \epsilon, $$ where $\rho$ is the spatial correlation parameter and $W$ is a user-defined weight matrix. The matrix $W$ has entries $w_{ii} = 0$ along the diagonal and the off-diagonal entries $w_{ij}$ are larger when areas $i$ and $j$ are closer to each other. In a linear model, the predictor term $\eta$ is given by $\eta = X \beta$ with design matrix $X$ and regression coefficients $\beta$. However, since the above equation holds for arbitrary $\eta$, these results are not restricted to linear models. If we have $\epsilon \sim {\mathrm N}(0, \,\sigma^2 I)$, it follows that $$ (I - \rho W)y \sim {\mathrm N}(\eta, \sigma^2 I), $$ which corresponds to the following log PDF coded in **Stan**: ```{r lpdf, eval=FALSE} /** * Normal log-pdf for spatially lagged responses * * @param y Vector of response values. * @param mu Mean parameter vector. * @param sigma Positive scalar residual standard deviation. * @param rho Positive scalar autoregressive parameter. * @param W Spatial weight matrix. * * @return A scalar to be added to the log posterior. */ real normal_lagsar_lpdf(vector y, vector mu, real sigma, real rho, matrix W) { int N = rows(y); real inv_sigma2 = 1 / square(sigma); matrix[N, N] W_tilde = -rho * W; vector[N] half_pred; for (n in 1:N) W_tilde[n,n] += 1; half_pred = W_tilde * (y - mdivide_left(W_tilde, mu)); return 0.5 * log_determinant(crossprod(W_tilde) * inv_sigma2) - 0.5 * dot_self(half_pred) * inv_sigma2; } ``` For the purpose of computing LOO-CV, it makes sense to rewrite the SAR model in slightly different form. Conditional on $\rho$, $\eta$, and $\sigma$, if we write \begin{align} y-(I-\rho W)^{-1}\eta &\sim {\mathrm N}(0, \sigma^2(I-\rho W)^{-1}(I-\rho W)^{-T}), \end{align} or more compactly, with $\widetilde{W}=(I-\rho W)$, \begin{align} y-\widetilde{W}^{-1}\eta &\sim {\mathrm N}(0, \sigma^2(\widetilde{W}^{T}\widetilde{W})^{-1}), \end{align} then this has the same form as the zero mean Gaussian process from above. Accordingly, we can compute the leave-one-out predictive densities with the equations from Sundararajan and Keerthi (2001), replacing $y$ with $(y-\widetilde{W}^{-1}\eta)$ and taking the covariance matrix $C$ to be $\sigma^2(\widetilde{W}^{T}\widetilde{W})^{-1}$. ## Case Study: Neighborhood Crime in Columbus, Ohio In order to demonstrate how to carry out the computations implied by these equations, we will first fit a lagged SAR model to data on crime in 49 different neighborhoods of Columbus, Ohio during the year 1980. The data was originally described in Aneslin (1988) and ships with the **spdep** R package. In addition to the **loo** package, for this analysis we will use the **brms** interface to Stan to generate a Stan program and fit the model, and also the **bayesplot** and **ggplot2** packages for plotting. ```{r setup, cache=FALSE} library("loo") library("brms") library("bayesplot") library("ggplot2") color_scheme_set("brightblue") theme_set(theme_default()) SEED <- 10001 set.seed(SEED) # only sets seed for R (seed for Stan set later) # loads COL.OLD data frame and COL.nb neighbor list data(oldcol, package = "spdep") ``` The three variables in the data set relevant to this example are: * `CRIME`: the number of residential burglaries and vehicle thefts per thousand households in the neighbood * `HOVAL`: housing value in units of $1000 USD * `INC`: household income in units of $1000 USD ```{r data} str(COL.OLD[, c("CRIME", "HOVAL", "INC")]) ``` We will also use the object `COL.nb`, which is a list containing information about which neighborhoods border each other. From this list we will be able to construct the weight matrix to used to help account for the spatial dependency among the observations. ### Fit lagged SAR model A model predicting `CRIME` from `INC` and `HOVAL`, while accounting for the spatial dependency via an SAR structure, can be specified in **brms** as follows. ```{r fit, results="hide"} fit <- brm( CRIME ~ INC + HOVAL + sar(COL.nb, type = "lag"), data = COL.OLD, data2 = list(COL.nb = COL.nb), chains = 4, seed = SEED ) ``` The code above fits the model in **Stan** using a log PDF equivalent to the `normal_lagsar_lpdf` function we defined above. In the summary output below we see that both higher income and higher housing value predict lower crime rates in the neighborhood. Moreover, there seems to be substantial spatial correlation between adjacent neighborhoods, as indicated by the posterior distribution of the `lagsar` parameter. ```{r plot-lagsar, message=FALSE} lagsar <- as.matrix(fit, pars = "lagsar") estimates <- quantile(lagsar, probs = c(0.25, 0.5, 0.75)) mcmc_hist(lagsar) + vline_at(estimates, linetype = 2, size = 1) + ggtitle("lagsar: posterior median and 50% central interval") ``` ### Approximate LOO-CV After fitting the model, the next step is to compute the pointwise log-likelihood values needed for approximate LOO-CV. To do this we will use the recipe laid out in the previous sections. ```{r approx} posterior <- as.data.frame(fit) y <- fit$data$CRIME N <- length(y) S <- nrow(posterior) loglik <- yloo <- sdloo <- matrix(nrow = S, ncol = N) for (s in 1:S) { p <- posterior[s, ] eta <- p$b_Intercept + p$b_INC * fit$data$INC + p$b_HOVAL * fit$data$HOVAL W_tilde <- diag(N) - p$lagsar * spdep::nb2mat(COL.nb) Cinv <- t(W_tilde) %*% W_tilde / p$sigma^2 g <- Cinv %*% (y - solve(W_tilde, eta)) cbar <- diag(Cinv) yloo[s, ] <- y - g / cbar sdloo[s, ] <- sqrt(1 / cbar) loglik[s, ] <- dnorm(y, yloo[s, ], sdloo[s, ], log = TRUE) } # use loo for psis smoothing log_ratios <- -loglik psis_result <- psis(log_ratios) ``` The quality of the PSIS-LOO approximation can be investigated graphically by plotting the Pareto-k estimate for each observation. Ideally, they should not exceed $0.5$, but in practice the algorithm turns out to be robust up to values of $0.7$ (Vehtari et al, 2017, 2019). In the plot below, we see that the fourth observation is problematic and so may reduce the accuracy of the LOO-CV approximation. ```{r plot, cache = FALSE} plot(psis_result, label_points = TRUE) ``` We can also check that the conditional leave-one-out predictive distribution equations work correctly, for instance, using the last posterior draw: ```{r checklast, cache = FALSE} yloo_sub <- yloo[S, ] sdloo_sub <- sdloo[S, ] df <- data.frame( y = y, yloo = yloo_sub, ymin = yloo_sub - sdloo_sub * 2, ymax = yloo_sub + sdloo_sub * 2 ) ggplot(data=df, aes(x = y, y = yloo, ymin = ymin, ymax = ymax)) + geom_errorbar( width = 1, color = "skyblue3", position = position_jitter(width = 0.25) ) + geom_abline(color = "gray30", size = 1.2) + geom_point() ``` Finally, we use PSIS-LOO to approximate the expected log predictive density (ELPD) for new data, which we will validate using exact LOO-CV in the upcoming section. ```{r psisloo} (psis_loo <- loo(loglik)) ``` ### Exact LOO-CV Exact LOO-CV for the above example is somewhat more involved, as we need to re-fit the model $N$ times and each time model the held-out data point as a parameter. First, we create an empty dummy model that we will update below as we loop over the observations. ```{r fit_dummy, cache = TRUE} # see help("mi", "brms") for details on the mi() usage fit_dummy <- brm( CRIME | mi() ~ INC + HOVAL + sar(COL.nb, type = "lag"), data = COL.OLD, data2 = list(COL.nb = COL.nb), chains = 0 ) ``` Next, we fit the model $N$ times, each time leaving out a single observation and then computing the log predictive density for that observation. For obvious reasons, this takes much longer than the approximation we computed above, but it is necessary in order to validate the approximate LOO-CV method. Thanks to the PSIS-LOO approximation, in general doing these slow exact computations can be avoided. ```{r exact-loo-cv, results="hide", message=FALSE, warning=FALSE, cache = TRUE} S <- 500 res <- vector("list", N) loglik <- matrix(nrow = S, ncol = N) for (i in seq_len(N)) { dat_mi <- COL.OLD dat_mi$CRIME[i] <- NA fit_i <- update(fit_dummy, newdata = dat_mi, # just for vignette chains = 1, iter = S * 2) posterior <- as.data.frame(fit_i) yloo <- sdloo <- rep(NA, S) for (s in seq_len(S)) { p <- posterior[s, ] y_miss_i <- y y_miss_i[i] <- p$Ymi eta <- p$b_Intercept + p$b_INC * fit_i$data$INC + p$b_HOVAL * fit_i$data$HOVAL W_tilde <- diag(N) - p$lagsar * spdep::nb2mat(COL.nb) Cinv <- t(W_tilde) %*% W_tilde / p$sigma^2 g <- Cinv %*% (y_miss_i - solve(W_tilde, eta)) cbar <- diag(Cinv); yloo[s] <- y_miss_i[i] - g[i] / cbar[i] sdloo[s] <- sqrt(1 / cbar[i]) loglik[s, i] <- dnorm(y[i], yloo[s], sdloo[s], log = TRUE) } ypred <- rnorm(S, yloo, sdloo) res[[i]] <- data.frame(y = c(posterior$Ymi, ypred)) res[[i]]$type <- rep(c("pp", "loo"), each = S) res[[i]]$obs <- i } res <- do.call(rbind, res) ``` A first step in the validation of the pointwise predictive density is to compare the distribution of the implied response values for the left-out observation to the distribution of the $y_i^{\mathrm{mis}}$ posterior-predictive values estimated as part of the model. If the pointwise predictive density is correct, the two distributions should match very closely (up to sampling error). In the plot below, we overlay these two distributions for the first four observations and see that they match very closely (as is the case for all $49$ observations of in this example). ```{r yplots, cache = FALSE, fig.width=10, out.width="95%", fig.asp = 0.3} res_sub <- res[res$obs %in% 1:4, ] ggplot(res_sub, aes(y, fill = type)) + geom_density(alpha = 0.6) + facet_wrap("obs", scales = "fixed", ncol = 4) ``` In the final step, we compute the ELPD based on the exact LOO-CV and compare it to the approximate PSIS-LOO result computed earlier. ```{r loo_exact, cache=FALSE} log_mean_exp <- function(x) { # more stable than log(mean(exp(x))) max_x <- max(x) max_x + log(sum(exp(x - max_x))) - log(length(x)) } exact_elpds <- apply(loglik, 2, log_mean_exp) exact_elpd <- sum(exact_elpds) round(exact_elpd, 1) ``` The results of the approximate and exact LOO-CV are similar but not as close as we would expect if there were no problematic observations. We can investigate this issue more closely by plotting the approximate against the exact pointwise ELPD values. ```{r compare, fig.height=5} df <- data.frame( approx_elpd = psis_loo$pointwise[, "elpd_loo"], exact_elpd = exact_elpds ) ggplot(df, aes(x = approx_elpd, y = exact_elpd)) + geom_abline(color = "gray30") + geom_point(size = 2) + geom_point(data = df[4, ], size = 3, color = "red3") + xlab("Approximate elpds") + ylab("Exact elpds") + coord_fixed(xlim = c(-16, -3), ylim = c(-16, -3)) ``` In the plot above the fourth data point ---the observation flagged as problematic by the PSIS-LOO approximation--- is colored in red and is the clear outlier. Otherwise, the correspondence between the exact and approximate values is strong. In fact, summing over the pointwise ELPD values and leaving out the fourth observation yields practically equivalent results for approximate and exact LOO-CV: ````{r pt4} without_pt_4 <- c( approx = sum(psis_loo$pointwise[-4, "elpd_loo"]), exact = sum(exact_elpds[-4]) ) round(without_pt_4, 1) ``` From this we can conclude that the difference we found when including *all* observations does not indicate a bug in our implementation of the approximate LOO-CV but rather a violation of its assumptions. # Working with Stan directly So far, we have specified the models in brms and only used Stan implicitely behind the scenes. This allowed us to focus on the primary purpose of validating approximate LOO-CV for non-factorized models. However, we would also like to show how everything can be set up in Stan directly. The Stan code brms generates is human readable and so we can use it to learn some of the essential aspects of Stan and the particular model we are implementing. The Stan program below is a slightly modified version of the code extracted via `stancode(fit_dummy)`: ```{r brms-stan-code, eval=FALSE} // generated with brms 2.2.0 functions { /** * Normal log-pdf for spatially lagged responses * * @param y Vector of response values. * @param mu Mean parameter vector. * @param sigma Positive scalar residual standard deviation. * @param rho Positive scalar autoregressive parameter. * @param W Spatial weight matrix. * * @return A scalar to be added to the log posterior. */ real normal_lagsar_lpdf(vector y, vector mu, real sigma, real rho, matrix W) { int N = rows(y); real inv_sigma2 = 1 / square(sigma); matrix[N, N] W_tilde = -rho * W; vector[N] half_pred; for (n in 1:N) W_tilde[n, n] += 1; half_pred = W_tilde * (y - mdivide_left(W_tilde, mu)); return 0.5 * log_determinant(crossprod(W_tilde) * inv_sigma2) - 0.5 * dot_self(half_pred) * inv_sigma2; } } data { int N; // total number of observations vector[N] Y; // response variable int Nmi; // number of missings int Jmi[Nmi]; // positions of missings int K; // number of population-level effects matrix[N, K] X; // population-level design matrix matrix[N, N] W; // spatial weight matrix int prior_only; // should the likelihood be ignored? } transformed data { int Kc = K - 1; matrix[N, K - 1] Xc; // centered version of X vector[K - 1] means_X; // column means of X before centering for (i in 2:K) { means_X[i - 1] = mean(X[, i]); Xc[, i - 1] = X[, i] - means_X[i - 1]; } } parameters { vector[Nmi] Ymi; // estimated missings vector[Kc] b; // population-level effects real temp_Intercept; // temporary intercept real sigma; // residual SD real lagsar; // SAR parameter } transformed parameters { } model { vector[N] Yl = Y; vector[N] mu = Xc * b + temp_Intercept; Yl[Jmi] = Ymi; // priors including all constants target += student_t_lpdf(temp_Intercept | 3, 34, 17); target += student_t_lpdf(sigma | 3, 0, 17) - 1 * student_t_lccdf(0 | 3, 0, 17); // likelihood including all constants if (!prior_only) { target += normal_lagsar_lpdf(Yl | mu, sigma, lagsar, W); } } generated quantities { // actual population-level intercept real b_Intercept = temp_Intercept - dot_product(means_X, b); } ``` Here we want to focus on two aspects of the Stan code. First, because there is no built-in function in Stan that calculates the log-likelihood for the lag-SAR model, we define a new `normal_lagsar_lpdf` function in the `functions` block of the Stan program. This is the same function we showed earlier in the vignette and it can be used to compute the log-likelihood in an efficient and numerically stable way. The `_lpdf` suffix used in the function name informs Stan that this is a log probability density function. Second, this Stan program nicely illustrates how to set up missing value imputation. Instead of just computing the log-likelihood for the observed responses `Y`, we define a new variable `Yl` which is equal to `Y` if the reponse is observed and equal to `Ymi` if the response is missing. The latter is in turn defined as a parameter and thus estimated along with all other paramters of the model. More details about missing value imputation in Stan can be found in the *Missing Data & Partially Known Parameters* section of the [Stan manual](https://mc-stan.org/users/documentation/index.html). The Stan code extracted from brms is not only helpful when learning Stan, but can also drastically speed up the specification of models that are not support by brms. If brms can fit a model similar but not identical to the desired model, we can let brms generate the Stan program for the similar model and then mold it into the program that implements the model we actually want to fit. Rather than calling `stancode()`, which requires an existing fitted model object, we recommend using `make_stancode()` and specifying the `save_model` argument to write the Stan program to a file. The corresponding data can be prepared with `make_standata()` and then manually amended if needed. Once the code and data have been edited, they can be passed to RStan's `stan()` function via the `file` and `data` arguments. # Conclusion In summary, we have shown how to set up and validate approximate and exact LOO-CV for non-factorized multivariate normal models using Stan with the **brms** and **loo** packages. Although we focused on the particular example of a spatial SAR model, the presented recipe applies more generally to models that can be expressed in terms of a multivariate normal likelihood.
# References Anselin L. (1988). *Spatial econometrics: methods and models*. Dordrecht: Kluwer Academic. Bürkner P. C., Gabry J., & Vehtari A. (2020). Efficient leave-one-out cross-validation for Bayesian non-factorized normal and Student-t models. *Computational Statistics*, \doi:10.1007/s00180-020-01045-4. [ArXiv preprint](https://arxiv.org/abs/1810.10559). Sundararajan S. & Keerthi S. S. (2001). Predictive approaches for choosing hyperparameters in Gaussian processes. *Neural Computation*, 13(5), 1103--1118. Vehtari A., Mononen T., Tolvanen V., Sivula T., & Winther O. (2016). Bayesian leave-one-out cross-validation approximations for Gaussian latent variable models. *Journal of Machine Learning Research*, 17(103), 1--38. [Online](https://jmlr.org/papers/v17/14-540.html). Vehtari A., Gelman A., & Gabry J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. *Statistics and Computing*, 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. [Online](https://link.springer.com/article/10.1007/s11222-016-9696-4). [arXiv preprint arXiv:1507.04544](https://arxiv.org/abs/1507.04544). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.02646](https://arxiv.org/abs/1507.02646). loo/inst/doc/loo2-weights.html0000644000176200001440000014534114411465510016007 0ustar liggesusers Bayesian Stacking and Pseudo-BMA weights using the loo package

Bayesian Stacking and Pseudo-BMA weights using the loo package

Aki Vehtari and Jonah Gabry

2023-03-30

Introduction

This vignette demonstrates the new functionality in loo v2.0.0 for Bayesian stacking and Pseudo-BMA weighting. In this vignette we can’t provide all of the necessary background on this topic, so we encourage readers to refer to the paper

  • Yao, Y., Vehtari, A., Simpson, D., and Gelman, A. (2018). Using stacking to average Bayesian predictive distributions. In Bayesian Analysis, :10.1214/17-BA1091. Online

which provides important details on the methods demonstrated in this vignette. Here we just quote from the abstract of the paper:

Abstract: Bayesian model averaging is flawed in the \(\mathcal{M}\)-open setting in which the true data-generating process is not one of the candidate models being fit. We take the idea of stacking from the point estimation literature and generalize to the combination of predictive distributions. We extend the utility function to any proper scoring rule and use Pareto smoothed importance sampling to efficiently compute the required leave-one-out posterior distributions. We compare stacking of predictive distributions to several alternatives: stacking of means, Bayesian model averaging (BMA), Pseudo-BMA, and a variant of Pseudo-BMA that is stabilized using the Bayesian bootstrap. Based on simulations and real-data applications, we recommend stacking of predictive distributions, with bootstrapped-Pseudo-BMA as an approximate alternative when computation cost is an issue.

Ideally, we would avoid the Bayesian model combination problem by extending the model to include the separate models as special cases, and preferably as a continuous expansion of the model space. For example, instead of model averaging over different covariate combinations, all potentially relevant covariates should be included in a predictive model (for causal analysis more care is needed) and a prior assumption that only some of the covariates are relevant can be presented with regularized horseshoe prior (Piironen and Vehtari, 2017a). For variable selection we recommend projective predictive variable selection (Piironen and Vehtari, 2017a; projpred package).

To demonstrate how to use loo package to compute Bayesian stacking and Pseudo-BMA weights, we repeat two simple model averaging examples from Chapters 6 and 10 of Statistical Rethinking by Richard McElreath. In Statistical Rethinking WAIC is used to form weights which are similar to classical “Akaike weights”. Pseudo-BMA weighting using PSIS-LOO for computation is close to these WAIC weights, but named after the Pseudo Bayes Factor by Geisser and Eddy (1979). As discussed below, in general we prefer using stacking rather than WAIC weights or the similar pseudo-BMA weights.

Setup

In addition to the loo package we will also load the rstanarm package for fitting the models.

library(rstanarm)
library(loo)

Example: Primate milk

In Statistical Rethinking, McElreath describes the data for the primate milk example as follows:

A popular hypothesis has it that primates with larger brains produce more energetic milk, so that brains can grow quickly. … The question here is to what extent energy content of milk, measured here by kilocalories, is related to the percent of the brain mass that is neocortex. … We’ll end up needing female body mass as well, to see the masking that hides the relationships among the variables.

data(milk)
d <- milk[complete.cases(milk),]
d$neocortex <- d$neocortex.perc /100
str(d)
'data.frame':   17 obs. of  9 variables:
 $ clade         : Factor w/ 4 levels "Ape","New World Monkey",..: 4 2 2 2 2 2 2 2 3 3 ...
 $ species       : Factor w/ 29 levels "A palliata","Alouatta seniculus",..: 11 2 1 6 27 5 3 4 21 19 ...
 $ kcal.per.g    : num  0.49 0.47 0.56 0.89 0.92 0.8 0.46 0.71 0.68 0.97 ...
 $ perc.fat      : num  16.6 21.2 29.7 53.4 50.6 ...
 $ perc.protein  : num  15.4 23.6 23.5 15.8 22.3 ...
 $ perc.lactose  : num  68 55.2 46.9 30.8 27.1 ...
 $ mass          : num  1.95 5.25 5.37 2.51 0.68 0.12 0.47 0.32 1.55 3.24 ...
 $ neocortex.perc: num  55.2 64.5 64.5 67.6 68.8 ...
 $ neocortex     : num  0.552 0.645 0.645 0.676 0.688 ...

We repeat the analysis in Chapter 6 of Statistical Rethinking using the following four models (here we use the default weakly informative priors in rstanarm, while flat priors were used in Statistical Rethinking).

fit1 <- stan_glm(kcal.per.g ~ 1, data = d, seed = 2030)
fit2 <- update(fit1, formula = kcal.per.g ~ neocortex)
fit3 <- update(fit1, formula = kcal.per.g ~ log(mass))
fit4 <- update(fit1, formula = kcal.per.g ~ neocortex + log(mass))

McElreath uses WAIC for model comparison and averaging, so we’ll start by also computing WAIC for these models so we can compare the results to the other options presented later in the vignette. The loo package provides waic methods for log-likelihood arrays, matrices and functions. Since we fit our model with rstanarm we can use the waic method provided by the rstanarm package (a wrapper around waic from the loo package), which allows us to just pass in our fitted model objects instead of first extracting the log-likelihood values.

waic1 <- waic(fit1)
waic2 <- waic(fit2)
waic3 <- waic(fit3)
Warning: 
1 (5.9%) p_waic estimates greater than 0.4. We recommend trying loo instead.
waic4 <- waic(fit4)
Warning: 
2 (11.8%) p_waic estimates greater than 0.4. We recommend trying loo instead.
waics <- c(
  waic1$estimates["elpd_waic", 1],
  waic2$estimates["elpd_waic", 1],
  waic3$estimates["elpd_waic", 1],
  waic4$estimates["elpd_waic", 1]
)

We get some warnings when computing WAIC for models 3 and 4, indicating that we shouldn’t trust the WAIC weights we will compute later. Following the recommendation in the warning, we next use the loo methods to compute PSIS-LOO instead. The loo package provides loo methods for log-likelihood arrays, matrices, and functions, but since we fit our model with rstanarm we can just pass the fitted model objects directly and rstanarm will extract the needed values to pass to the loo package. (Like rstanarm, some other R packages for fitting Stan models, e.g. brms, also provide similar methods for interfacing with the loo package.)

# note: the loo function accepts a 'cores' argument that we recommend specifying
# when working with bigger datasets

loo1 <- loo(fit1)
loo2 <- loo(fit2)
loo3 <- loo(fit3)
loo4 <- loo(fit4)
lpd_point <- cbind(
  loo1$pointwise[,"elpd_loo"], 
  loo2$pointwise[,"elpd_loo"],
  loo3$pointwise[,"elpd_loo"], 
  loo4$pointwise[,"elpd_loo"]
)

With loo we don’t get any warnings for models 3 and 4, but for illustration of good results, we display the diagnostic details for these models anyway.

print(loo3)

Computed from 4000 by 17 log-likelihood matrix

         Estimate  SE
elpd_loo      4.5 2.3
p_loo         2.1 0.5
looic        -9.1 4.6
------
Monte Carlo SE of elpd_loo is 0.0.

Pareto k diagnostic values:
                         Count Pct.    Min. n_eff
(-Inf, 0.5]   (good)     15    88.2%   1658      
 (0.5, 0.7]   (ok)        2    11.8%   768       
   (0.7, 1]   (bad)       0     0.0%   <NA>      
   (1, Inf)   (very bad)  0     0.0%   <NA>      

All Pareto k estimates are ok (k < 0.7).
See help('pareto-k-diagnostic') for details.
print(loo4)

Computed from 4000 by 17 log-likelihood matrix

         Estimate  SE
elpd_loo      8.4 2.8
p_loo         3.3 0.9
looic       -16.8 5.5
------
Monte Carlo SE of elpd_loo is 0.1.

Pareto k diagnostic values:
                         Count Pct.    Min. n_eff
(-Inf, 0.5]   (good)     16    94.1%   532       
 (0.5, 0.7]   (ok)        1     5.9%   404       
   (0.7, 1]   (bad)       0     0.0%   <NA>      
   (1, Inf)   (very bad)  0     0.0%   <NA>      

All Pareto k estimates are ok (k < 0.7).
See help('pareto-k-diagnostic') for details.

One benefit of PSIS-LOO over WAIC is better diagnostics. Here for both models 3 and 4 all \(k<0.7\) and the Monte Carlo SE of elpd_loo is 0.1 or less, and we can expect the model comparison to be reliable.

Next we compute and compare 1) WAIC weights, 2) Pseudo-BMA weights without Bayesian bootstrap, 3) Pseudo-BMA+ weights with Bayesian bootstrap, and 4) Bayesian stacking weights.

waic_wts <- exp(waics) / sum(exp(waics))
pbma_wts <- pseudobma_weights(lpd_point, BB=FALSE)
pbma_BB_wts <- pseudobma_weights(lpd_point) # default is BB=TRUE
stacking_wts <- stacking_weights(lpd_point)
round(cbind(waic_wts, pbma_wts, pbma_BB_wts, stacking_wts), 2)
       waic_wts pbma_wts pbma_BB_wts stacking_wts
model1     0.01     0.02        0.07         0.01
model2     0.01     0.01        0.04         0.00
model3     0.02     0.02        0.04         0.00
model4     0.96     0.95        0.85         0.99

With all approaches Model 4 with neocortex and log(mass) gets most of the weight. Based on theory, Pseudo-BMA weights without Bayesian bootstrap should be close to WAIC weights, and we can also see that here. Pseudo-BMA+ weights with Bayesian bootstrap provide more cautious weights further away from 0 and 1 (see Yao et al. (2018) for a discussion of why this can be beneficial and results from related experiments). In this particular example, the Bayesian stacking weights are not much different from the other weights.

One of the benefits of stacking is that it manages well if there are many similar models. Consider for example that there could be many irrelevant covariates that when included would produce a similar model to one of the existing models. To emulate this situation here we simply copy the first model a bunch of times, but you can imagine that instead we would have ten alternative models with about the same predictive performance. WAIC weights for such a scenario would be close to the following:

waic_wts_demo <- 
  exp(waics[c(1,1,1,1,1,1,1,1,1,1,2,3,4)]) /
  sum(exp(waics[c(1,1,1,1,1,1,1,1,1,1,2,3,4)]))
round(waic_wts_demo, 3)
 [1] 0.013 0.013 0.013 0.013 0.013 0.013 0.013 0.013 0.013 0.013 0.006 0.016
[13] 0.847

Notice how much the weight for model 4 is lowered now that more models similar to model 1 (or in this case identical) have been added. Both WAIC weights and Pseudo-BMA approaches first estimate the predictive performance separately for each model and then compute weights based on estimated relative predictive performances. Similar models share similar weights so the weights of other models must be reduced for the total sum of the weights to remain the same.

On the other hand, stacking optimizes the weights jointly, allowing for the very similar models (in this toy example repeated models) to share their weight while more unique models keep their original weights. In our example we can see this difference clearly:

stacking_weights(lpd_point[,c(1,1,1,1,1,1,1,1,1,1,2,3,4)])
Method: stacking
------
        weight
model1  0.001 
model2  0.001 
model3  0.001 
model4  0.001 
model5  0.001 
model6  0.001 
model7  0.001 
model8  0.001 
model9  0.001 
model10 0.001 
model11 0.000 
model12 0.000 
model13 0.987 

Using stacking, the weight for the best model stays essentially unchanged.

Example: Oceanic tool complexity

Another example we consider is the Kline oceanic tool complexity data, which McElreath describes as follows:

Different historical island populations possessed tool kits of different size. These kits include fish hooks, axes, boats, hand plows, and many other types of tools. A number of theories predict that larger populations will both develop and sustain more complex tool kits. … It’s also suggested that contact rates among populations effectively increases population [sic, probably should be tool kit] size, as it’s relevant to technological evolution.

We build models predicting the total number of tools given the log population size and the contact rate (high vs. low).

data(Kline)
d <- Kline
d$log_pop <- log(d$population)
d$contact_high <- ifelse(d$contact=="high", 1, 0)
str(d)
'data.frame':   10 obs. of  7 variables:
 $ culture     : Factor w/ 10 levels "Chuuk","Hawaii",..: 4 7 6 10 3 9 1 5 8 2
 $ population  : int  1100 1500 3600 4791 7400 8000 9200 13000 17500 275000
 $ contact     : Factor w/ 2 levels "high","low": 2 2 2 1 1 1 1 2 1 2
 $ total_tools : int  13 22 24 43 33 19 40 28 55 71
 $ mean_TU     : num  3.2 4.7 4 5 5 4 3.8 6.6 5.4 6.6
 $ log_pop     : num  7 7.31 8.19 8.47 8.91 ...
 $ contact_high: num  0 0 0 1 1 1 1 0 1 0

We start with a Poisson regression model with the log population size, the contact rate, and an interaction term between them (priors are informative priors as in Statistical Rethinking).

fit10 <-
  stan_glm(
    total_tools ~ log_pop + contact_high + log_pop * contact_high,
    family = poisson(link = "log"),
    data = d,
    prior = normal(0, 1, autoscale = FALSE),
    prior_intercept = normal(0, 100, autoscale = FALSE),
    seed = 2030
  )

Before running other models, we check whether Poisson is good choice as the conditional observation model.

loo10 <- loo(fit10)
Warning: Found 2 observation(s) with a pareto_k > 0.7. We recommend calling 'loo' again with argument 'k_threshold = 0.7' in order to calculate the ELPD without the assumption that these observations are negligible. This will refit the model 2 times to compute the ELPDs for the problematic observations directly.
print(loo10)

Computed from 4000 by 10 log-likelihood matrix

         Estimate   SE
elpd_loo    -40.9  6.0
p_loo         5.8  2.0
looic        81.8 12.0
------
Monte Carlo SE of elpd_loo is NA.

Pareto k diagnostic values:
                         Count Pct.    Min. n_eff
(-Inf, 0.5]   (good)     5     50.0%   1116      
 (0.5, 0.7]   (ok)       3     30.0%   92        
   (0.7, 1]   (bad)      2     20.0%   62        
   (1, Inf)   (very bad) 0      0.0%   <NA>      
See help('pareto-k-diagnostic') for details.

We get at least one observation with \(k>0.7\) and the estimated effective number of parameters p_loo is larger than the total number of parameters in the model. This indicates that Poisson might be too narrow. A negative binomial model might be better, but with so few observations it is not so clear.

We can compute LOO more accurately by running Stan again for the leave-one-out folds with high \(k\) estimates. When using rstanarm this can be done by specifying the k_threshold argument:

loo10 <- loo(fit10, k_threshold=0.7)
2 problematic observation(s) found.
Model will be refit 2 times.

Fitting model 1 out of 2 (leaving out observation 9)

Fitting model 2 out of 2 (leaving out observation 10)
print(loo10)

Computed from 4000 by 10 log-likelihood matrix

         Estimate   SE
elpd_loo    -41.2  6.0
p_loo         6.1  2.0
looic        82.4 12.0
------
Monte Carlo SE of elpd_loo is 0.2.

Pareto k diagnostic values:
                         Count Pct.    Min. n_eff
(-Inf, 0.5]   (good)     5     62.5%   1116      
 (0.5, 0.7]   (ok)       3     37.5%   92        
   (0.7, 1]   (bad)      0      0.0%   <NA>      
   (1, Inf)   (very bad) 0      0.0%   <NA>      

All Pareto k estimates are ok (k < 0.7).
See help('pareto-k-diagnostic') for details.

In this case we see that there is not much difference, and thus it is relatively safe to continue.

As a comparison we also compute WAIC:

waic10 <- waic(fit10)
Warning: 
4 (40.0%) p_waic estimates greater than 0.4. We recommend trying loo instead.
print(waic10)

Computed from 4000 by 10 log-likelihood matrix

          Estimate   SE
elpd_waic    -40.2  5.9
p_waic         5.0  1.8
waic          80.3 11.8

4 (40.0%) p_waic estimates greater than 0.4. We recommend trying loo instead. 

The WAIC computation is giving warnings and the estimated ELPD is slightly more optimistic. We recommend using the PSIS-LOO results instead.

To assess whether the contact rate and interaction term are useful, we can make a comparison to models without these terms.

fit11 <- update(fit10, formula = total_tools ~ log_pop + contact_high)
fit12 <- update(fit10, formula = total_tools ~ log_pop)
(loo11 <- loo(fit11))

Computed from 4000 by 10 log-likelihood matrix

         Estimate   SE
elpd_loo    -39.7  5.8
p_loo         4.4  1.6
looic        79.4 11.6
------
Monte Carlo SE of elpd_loo is 0.1.

Pareto k diagnostic values:
                         Count Pct.    Min. n_eff
(-Inf, 0.5]   (good)     8     80.0%   351       
 (0.5, 0.7]   (ok)       2     20.0%   308       
   (0.7, 1]   (bad)      0      0.0%   <NA>      
   (1, Inf)   (very bad) 0      0.0%   <NA>      

All Pareto k estimates are ok (k < 0.7).
See help('pareto-k-diagnostic') for details.
(loo12 <- loo(fit12))
Warning: Found 1 observation(s) with a pareto_k > 0.7. We recommend calling 'loo' again with argument 'k_threshold = 0.7' in order to calculate the ELPD without the assumption that these observations are negligible. This will refit the model 1 times to compute the ELPDs for the problematic observations directly.

Computed from 4000 by 10 log-likelihood matrix

         Estimate  SE
elpd_loo    -42.5 4.7
p_loo         4.1 1.1
looic        85.0 9.4
------
Monte Carlo SE of elpd_loo is NA.

Pareto k diagnostic values:
                         Count Pct.    Min. n_eff
(-Inf, 0.5]   (good)     9     90.0%   649       
 (0.5, 0.7]   (ok)       0      0.0%   <NA>      
   (0.7, 1]   (bad)      1     10.0%   68        
   (1, Inf)   (very bad) 0      0.0%   <NA>      
See help('pareto-k-diagnostic') for details.
loo11 <- loo(fit11, k_threshold=0.7)
All pareto_k estimates below user-specified threshold of 0.7. 
Returning loo object.
loo12 <- loo(fit12, k_threshold=0.7)
1 problematic observation(s) found.
Model will be refit 1 times.

Fitting model 1 out of 1 (leaving out observation 10)
lpd_point <- cbind(
  loo10$pointwise[, "elpd_loo"], 
  loo11$pointwise[, "elpd_loo"], 
  loo12$pointwise[, "elpd_loo"]
)

For comparison we’ll also compute WAIC values for these additional models:

waic11 <- waic(fit11)
Warning: 
3 (30.0%) p_waic estimates greater than 0.4. We recommend trying loo instead.
waic12 <- waic(fit12)
Warning: 
5 (50.0%) p_waic estimates greater than 0.4. We recommend trying loo instead.
waics <- c(
  waic10$estimates["elpd_waic", 1], 
  waic11$estimates["elpd_waic", 1], 
  waic12$estimates["elpd_waic", 1]
)

The WAIC computation again gives warnings, and we recommend using PSIS-LOO instead.

Finally, we compute 1) WAIC weights, 2) Pseudo-BMA weights without Bayesian bootstrap, 3) Pseudo-BMA+ weights with Bayesian bootstrap, and 4) Bayesian stacking weights.

waic_wts <- exp(waics) / sum(exp(waics))
pbma_wts <- pseudobma_weights(lpd_point, BB=FALSE)
pbma_BB_wts <- pseudobma_weights(lpd_point) # default is BB=TRUE
stacking_wts <- stacking_weights(lpd_point)
round(cbind(waic_wts, pbma_wts, pbma_BB_wts, stacking_wts), 2)
       waic_wts pbma_wts pbma_BB_wts stacking_wts
model1     0.33     0.18        0.16          0.0
model2     0.63     0.81        0.67          0.8
model3     0.04     0.02        0.17          0.2

All weights favor the second model with the log population and the contact rate. WAIC weights and Pseudo-BMA weights (without Bayesian bootstrap) are similar, while Pseudo-BMA+ is more cautious and closer to stacking weights.

It may seem surprising that Bayesian stacking is giving zero weight to the first model, but this is likely due to the fact that the estimated effect for the interaction term is close to zero and thus models 1 and 2 give very similar predictions. In other words, incorporating the model with the interaction (model 1) into the model average doesn’t improve the predictions at all and so model 1 is given a weight of 0. On the other hand, models 2 and 3 are giving slightly different predictions and thus their combination may be slightly better than either alone. This behavior is related to the repeated similar model illustration in the milk example above.

Simpler coding using loo_model_weights function

Although in the examples above we called the stacking_weights and pseudobma_weights functions directly, we can also use the loo_model_weights wrapper, which takes as its input either a list of pointwise log-likelihood matrices or a list of precomputed loo objects. There are also loo_model_weights methods for stanreg objects (fitted model objects from rstanarm) as well as fitted model objects from other packages (e.g. brms) that do the preparation work for the user (see, e.g., the examples at help("loo_model_weights", package = "rstanarm")).

# using list of loo objects
loo_list <- list(loo10, loo11, loo12)
loo_model_weights(loo_list)
Method: stacking
------
      weight
fit10 0.000 
fit11 0.802 
fit12 0.198 
loo_model_weights(loo_list, method = "pseudobma")
Method: pseudo-BMA+ with Bayesian bootstrap
------
      weight
fit10 0.159 
fit11 0.679 
fit12 0.162 
loo_model_weights(loo_list, method = "pseudobma", BB = FALSE)
Method: pseudo-BMA
------
      weight
fit10 0.175 
fit11 0.805 
fit12 0.020 

References

McElreath, R. (2016). Statistical rethinking: A Bayesian course with examples in R and Stan. Chapman & Hall/CRC. http://xcelab.net/rm/statistical-rethinking/

Piironen, J. and Vehtari, A. (2017a). Sparsity information and regularization in the horseshoe and other shrinkage priors. In Electronic Journal of Statistics, 11(2):5018-5051. Online.

Piironen, J. and Vehtari, A. (2017b). Comparison of Bayesian predictive methods for model selection. Statistics and Computing, 27(3):711-735. :10.1007/s11222-016-9649-y. Online.

Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. Statistics and Computing. 27(5), 1413–1432. :10.1007/s11222-016-9696-4. online, arXiv preprint arXiv:1507.04544.

Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. arXiv preprint arXiv:1507.02646.

Yao, Y., Vehtari, A., Simpson, D., and Gelman, A. (2018). Using stacking to average Bayesian predictive distributions. In Bayesian Analysis, :10.1214/17-BA1091. Online.

loo/inst/doc/loo2-mixis.Rmd0000644000176200001440000002204314407123455015241 0ustar liggesusers--- title: "Mixture IS leave-one-out cross-validation for high-dimensional Bayesian models" author: "Luca Silva and Giacomo Zanella" date: "`r Sys.Date()`" output: html_vignette: toc: yes params: EVAL: !r identical(Sys.getenv("NOT_CRAN"), "true") --- ```{r, child="children/SETTINGS-knitr.txt"} ``` ```{r, child="children/SEE-ONLINE.txt", eval = if (isTRUE(exists("params"))) !params$EVAL else TRUE} ``` # Introduction This vignette shows how to perform Bayesian leave-one-out cross-validation (LOO-CV) using the mixture estimators proposed in the paper [Silva and Zanella (2022)](https://arxiv.org/abs/2209.09190). These estimators have shown to be useful in presence of outliers but also, and especially, in high-dimensional settings where the model features many parameters. In these contexts it can happen that a large portion of observations lead to high values of Pareto-$k$ diagnostics and potential instability of PSIS-LOO estimators. For this illustration we consider a high-dimensional Bayesian Logistic regression model applied to the _Voice_ dataset. ## Setup: load packages and set seed ```{r, warnings=FALSE, message=FALSE} library("rstan") library("loo") library("matrixStats") options(mc.cores = parallel::detectCores(), parallel=FALSE) set.seed(24877) ``` ## Model This is the Stan code for a logistic regression model with regularized horseshoe prior. The code includes an if statement to include a code line needed later for the MixIS approach. ```{r stancode_horseshoe} stancode_horseshoe <- " data { int n; int p; int y[n]; matrix [n,p] X; real scale_global; int mixis; } transformed data { real nu_global=1; // degrees of freedom for the half-t priors for tau real nu_local=1; // degrees of freedom for the half-t priors for lambdas // (nu_local = 1 corresponds to the horseshoe) real slab_scale=2;// for the regularized horseshoe real slab_df=100; // for the regularized horseshoe } parameters { vector[p] z; // for non-centered parameterization real tau; // global shrinkage parameter vector [p] lambda; // local shrinkage parameter real caux; } transformed parameters { vector[p] beta; { vector[p] lambda_tilde; // 'truncated' local shrinkage parameter real c = slab_scale * sqrt(caux); // slab scale lambda_tilde = sqrt( c^2 * square(lambda) ./ (c^2 + tau^2*square(lambda))); beta = z .* lambda_tilde*tau; } } model { vector[n] means=X*beta; vector[n] log_lik; target += std_normal_lpdf(z); target += student_t_lpdf(lambda | nu_local, 0, 1); target += student_t_lpdf(tau | nu_global, 0, scale_global); target += inv_gamma_lpdf(caux | 0.5*slab_df, 0.5*slab_df); for (index in 1:n) { log_lik[index]= bernoulli_logit_lpmf(y[index] | means[index]); } target += sum(log_lik); if (mixis) { target += log_sum_exp(-log_lik); } } generated quantities { vector[n] means=X*beta; vector[n] log_lik; for (index in 1:n) { log_lik[index] = bernoulli_logit_lpmf(y[index] | means[index]); } } " ``` ## Dataset The _LSVT Voice Rehabilitation Data Set_ (see [link](https://archive.ics.uci.edu/ml/datasets/LSVT+Voice+Rehabilitation) for details) has $p=312$ covariates and $n=126$ observations with binary response. We construct data list for Stan. ```{r, results='hide', warning=FALSE, message=FALSE, error=FALSE} data(voice) y <- voice$y X <- voice[2:length(voice)] n <- dim(X)[1] p <- dim(X)[2] p0 <- 10 scale_global <- 2*p0/(p-p0)/sqrt(n-1) standata <- list(n = n, p = p, X = as.matrix(X), y = c(y), scale_global = scale_global, mixis = 0) ``` Note that in our prior specification we divide the prior variance by the number of covariates $p$. This is often done in high-dimensional contexts to have a prior variance for the linear predictors $X\beta$ that remains bounded as $p$ increases. ## PSIS estimators and Pareto-$k$ diagnostics LOO-CV computations are challenging in this context due to high-dimensionality of the parameter space. To show that, we compute PSIS-LOO estimators, which require sampling from the posterior distribution, and inspect the associated Pareto-$k$ diagnostics. ```{r, results='hide', warning=FALSE} chains <- 4 n_iter <- 2000 warm_iter <- 1000 stanmodel <- stan_model(model_code = stancode_horseshoe) fit_post <- sampling(stanmodel, data = standata, chains = chains, iter = n_iter, warmup = warm_iter, refresh = 0) loo_post <-loo(fit_post) ``` ```{r} print(loo_post) ``` As we can see the diagnostics signal either "bad" or "very bad" Pareto-$k$ values for roughly $15-30\%$ of the observations which is a significant portion of the dataset. ## Mixture estimators We now compute the mixture estimators proposed in Silva and Zanella (2022). These require to sample from the following mixture of leave-one-out posteriors \begin{equation} q_{mix}(\theta) = \frac{\sum_{i=1}^n p(y_{-i}|\theta)p(\theta)}{\sum_{i=1}^np(y_{-i})}\propto p(\theta|y)\cdot \left(\sum_{i=1}^np(y_i|\theta)^{-1}\right). \end{equation} The code to generate a Stan model for the above mixture distribution is the same to the one for the posterior, just enabling one line of code with a _LogSumExp_ contribution to account for the last term in the equation above. ``` if (mixis) { target += log_sum_exp(-log_lik); } ``` We sample from the mixture and collect the log-likelihoods term. ```{r, results='hide', warnings=FALSE} standata$mixis <- 1 fit_mix <- sampling(stanmodel, data = standata, chains = chains, iter = n_iter, warmup = warm_iter, refresh = 0, pars = "log_lik") log_lik_mix <- extract(fit_mix)$log_lik ``` We now compute the mixture estimators, following the numerically stable implementation in Appendix A.2 of [Silva and Zanella (2022)](https://arxiv.org/abs/2209.09190). The code below makes use of the package "matrixStats". ```{r} l_common_mix <- rowLogSumExps(-log_lik_mix) log_weights <- -log_lik_mix - l_common_mix elpd_mixis <- logSumExp(-l_common_mix) - rowLogSumExps(t(log_weights)) ``` ## Comparison with benchmark values obtained with long simulations To evaluate the performance of mixture estimators (MixIS) we also generate _benchmark values_, i.e.\ accurate approximations of the LOO predictives $\{p(y_i|y_{-i})\}_{i=1,\dots,n}$, obtained by brute-force sampling from the leave-one-out posteriors directly, getting $90k$ samples from each and discarding the first $10k$ as warmup. This is computationally heavy, hence we have saved the results and we just load them in the current vignette. ```{r} data(voice_loo) elpd_loo <- voice_loo$elpd_loo ``` We can then compute the root mean squared error (RMSE) of the PSIS and mixture estimators relative to such benchmark values. ```{r} elpd_psis <- loo_post$pointwise[,1] print(paste("RMSE(PSIS) =",round( sqrt(mean((elpd_loo-elpd_psis)^2)) ,2))) print(paste("RMSE(MixIS) =",round( sqrt(mean((elpd_loo-elpd_mixis)^2)) ,2))) ``` Here mixture estimator provides a reduction in RMSE. Note that this value would increase with the number of samples drawn from the posterior and mixture, since in this example the RMSE of MixIS will exhibit a CLT-type decay while the one of PSIS will converge at a slower rate (this can be verified by running the above code with a larger sample size; see also Figure 3 of Silva and Zanella (2022) for analogous results). We then compare the overall ELPD estimates with the brute force one. ```{r} elpd_psis <- loo_post$pointwise[,1] print(paste("ELPD (PSIS)=",round(sum(elpd_psis),2))) print(paste("ELPD (MixIS)=",round(sum(elpd_mixis),2))) print(paste("ELPD (brute force)=",round(sum(elpd_loo),2))) ``` In this example, MixIS provides a more accurate ELPD estimate closer to the brute force estimate, while PSIS severely overestimates the ELPD. Note that low accuracy of the PSIS ELPD estimate is expected in this example given the large number of large Pareto-$k$ values. In this example, the accuracy of MixIS estimate will also improve with bigger MCMC sample size. More generally, mixture estimators can be useful in situations where standard PSIS estimators struggle and return many large Pareto-$k$ values. In these contexts MixIS often provides more accurate LOO-CV and ELPD estimates with a single sampling routine (i.e. with a cost comparable to sampling from the original posterior). ## References Silva L. and Zanella G. (2022). Robust leave-one-out cross-validation for high-dimensional Bayesian models. Preprint at [arXiv:2209.09190](https://arxiv.org/abs/2209.09190) Vehtari A., Gelman A., and Gabry J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. *Statistics and Computing*, 27(5), 1413--1432. Preprint at [arXiv:1507.04544](https://arxiv.org/abs/1507.04544) Vehtari A., Simpson D., Gelman A., Yao Y., and Gabry J. (2022). Pareto smoothed importance sampling. Preprint at [arXiv:1507.02646](https://arxiv.org/abs/1507.02646) loo/inst/doc/loo2-example.R0000644000176200001440000000463614411455345015233 0ustar liggesusersparams <- list(EVAL = TRUE) ## ----SETTINGS-knitr, include=FALSE-------------------------------------------- stopifnot(require(knitr)) opts_chunk$set( comment=NA, eval = if (isTRUE(exists("params"))) params$EVAL else FALSE, dev = "png", dpi = 150, fig.asp = 0.618, fig.width = 5, out.width = "60%", fig.align = "center" ) ## ----setup, message=FALSE----------------------------------------------------- library("rstanarm") library("bayesplot") library("loo") ## ----data--------------------------------------------------------------------- # the 'roaches' data frame is included with the rstanarm package data(roaches) str(roaches) # rescale to units of hundreds of roaches roaches$roach1 <- roaches$roach1 / 100 ## ----count-roaches-mcmc, results="hide"--------------------------------------- fit1 <- stan_glm( formula = y ~ roach1 + treatment + senior, offset = log(exposure2), data = roaches, family = poisson(link = "log"), prior = normal(0, 2.5, autoscale = TRUE), prior_intercept = normal(0, 5, autoscale = TRUE), seed = 12345 ) ## ----loo1--------------------------------------------------------------------- loo1 <- loo(fit1, save_psis = TRUE) ## ----print-loo1--------------------------------------------------------------- print(loo1) ## ----plot-loo1, out.width = "70%"--------------------------------------------- plot(loo1) ## ----ppc_loo_pit_overlay------------------------------------------------------ yrep <- posterior_predict(fit1) ppc_loo_pit_overlay( y = roaches$y, yrep = yrep, lw = weights(loo1$psis_object) ) ## ----count-roaches-negbin, results="hide"------------------------------------- fit2 <- update(fit1, family = neg_binomial_2) ## ----loo2--------------------------------------------------------------------- loo2 <- loo(fit2, save_psis = TRUE, cores = 2) print(loo2) ## ----plot-loo2---------------------------------------------------------------- plot(loo2, label_points = TRUE) ## ----reloo-------------------------------------------------------------------- if (any(pareto_k_values(loo2) > 0.7)) { loo2 <- loo(fit2, save_psis = TRUE, k_threshold = 0.7) } print(loo2) ## ----ppc_loo_pit_overlay-negbin----------------------------------------------- yrep <- posterior_predict(fit2) ppc_loo_pit_overlay(roaches$y, yrep, lw = weights(loo2$psis_object)) ## ----loo_compare-------------------------------------------------------------- loo_compare(loo1, loo2) loo/inst/doc/loo2-large-data.Rmd0000644000176200001440000005036613764522153016125 0ustar liggesusers--- title: "Using Leave-one-out cross-validation for large data" author: "Mans Magnusson, Paul Bürkner, Aki Vehtari and Jonah Gabry" date: "`r Sys.Date()`" output: html_vignette: toc: yes params: EVAL: !r identical(Sys.getenv("NOT_CRAN"), "true") --- ```{r settings, child="children/SETTINGS-knitr.txt"} ``` ```{r, child="children/SEE-ONLINE.txt", eval = if (isTRUE(exists("params"))) !params$EVAL else TRUE} ``` # Introduction This vignette demonstrates how to do leave-one-out cross-validation for large data using the __loo__ package and Stan. There are two approaches covered: LOO with subsampling and LOO using approximations to posterior distributions. Some sections from this vignette are excerpted from the papers * Magnusson, M., Riis Andersen, M., Jonasson, J. and Vehtari, A. (2020). Leave-One-Out Cross-Validation for Model Comparison in Large Data. Proceedings of the 23rd International Conference on Artificial Intelligence and Statistics (AISTATS), in PMLR 108. [arXiv preprint arXiv:2001.00980](https://arxiv.org/abs/2001.00980). * Magnusson, M., Andersen, M., Jonasson, J. & Vehtari, A. (2019). Bayesian leave-one-out cross-validation for large data. Proceedings of the 36th International Conference on Machine Learning, in PMLR 97:4244-4253 [online](http://proceedings.mlr.press/v97/magnusson19a.html), [arXiv preprint arXiv:1904.10679](https://arxiv.org/abs/1904.10679). * Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. _Statistics and Computing_. 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. Links: [published](https://link.springer.com/article/10.1007/s11222-016-9696-4) | [arXiv preprint](https://arxiv.org/abs/1507.04544). * Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.04544](https://arxiv.org/abs/1507.04544). which provide important background for understanding the methods implemented in the package. # Setup In addition to the __loo__ package, we'll also be using __rstan__: ```{r setup, message=FALSE} library("rstan") library("loo") set.seed(4711) ``` # Example: Well water in Bangladesh We will use the same example as in the vignette [_Writing Stan programs for use with the loo package_](http://mc-stan.org/loo/articles/loo2-with-rstan.html). See that vignette for a description of the problem and data. The sample size in this example is only $N=3020$, which is not large enough to _require_ the special methods for large data described in this vignette, but is sufficient for demonstration purposes in this tutorial. ## Coding the Stan model Here is the Stan code for fitting the logistic regression model, which we save in a file called `logistic.stan`: ``` // save in `logistic.stan` data { int N; // number of data points int P; // number of predictors (including intercept) matrix[N,P] X; // predictors (including 1s for intercept) int y[N]; // binary outcome } parameters { vector[P] beta; } model { beta ~ normal(0, 1); y ~ bernoulli_logit(X * beta); } ``` Importantly, unlike the general approach recommended in [_Writing Stan programs for use with the loo package_](http://mc-stan.org/loo/articles/loo2-with-rstan.html), we do _not_ compute the log-likelihood for each observation in the `generated quantities` block of the Stan program. Here we are assuming we have a large data set (larger than the one we're actually using in this demonstration) and so it is preferable to instead define a function in R to compute the log-likelihood for each data point when needed rather than storing all of the log-likelihood values in memory. The log-likelihood in R can be coded as follows: ```{r llfun_logistic} # we'll add an argument log to toggle whether this is a log-likelihood or # likelihood function. this will be useful later in the vignette. llfun_logistic <- function(data_i, draws, log = TRUE) { x_i <- as.matrix(data_i[, which(grepl(colnames(data_i), pattern = "X")), drop=FALSE]) logit_pred <- draws %*% t(x_i) dbinom(x = data_i$y, size = 1, prob = 1/(1 + exp(-logit_pred)), log = log) } ``` The function `llfun_logistic()` needs to have arguments `data_i` and `draws`. Below we will test that the function is working by using the `loo_i()` function. ## Fitting the model with RStan Next we fit the model in Stan using the **rstan** package: ```{r, eval=FALSE} # Prepare data url <- "http://stat.columbia.edu/~gelman/arm/examples/arsenic/wells.dat" wells <- read.table(url) wells$dist100 <- with(wells, dist / 100) X <- model.matrix(~ dist100 + arsenic, wells) standata <- list(y = wells$switch, X = X, N = nrow(X), P = ncol(X)) # Compile stan_mod <- stan_model("logistic.stan") # Fit model fit_1 <- sampling(stan_mod, data = standata, seed = 4711) print(fit_1, pars = "beta") ``` ``` mean se_mean sd 2.5% 25% 50% 75% 97.5% n_eff Rhat beta[1] 0.00 0 0.08 -0.15 -0.05 0.00 0.06 0.16 1933 1 beta[2] -0.89 0 0.10 -1.09 -0.96 -0.89 -0.82 -0.69 2332 1 beta[3] 0.46 0 0.04 0.38 0.43 0.46 0.49 0.54 2051 1 ``` Before we move on to computing LOO we can now test that the log-likelihood function we wrote is working as it should. The `loo_i()` function is a helper function that can be used to test a log-likelihood function on a single observation. ```{r, eval=FALSE} # used for draws argument to loo_i parameter_draws_1 <- extract(fit_1)$beta # used for data argument to loo_i stan_df_1 <- as.data.frame(standata) # compute relative efficiency (this is slow and optional but is recommended to allow # for adjusting PSIS effective sample size based on MCMC effective sample size) r_eff <- relative_eff(llfun_logistic, log = FALSE, # relative_eff wants likelihood not log-likelihood values chain_id = rep(1:4, each = 1000), data = stan_df_1, draws = parameter_draws_1, cores = 2) loo_i(i = 1, llfun_logistic, r_eff = r_eff, data = stan_df_1, draws = parameter_draws_1) ``` ``` $pointwise elpd_loo mcse_elpd_loo p_loo looic influence_pareto_k 1 -0.3314552 0.0002887608 0.0003361772 0.6629103 -0.05679886 ... ``` # Approximate LOO-CV using PSIS-LOO and subsampling We can then use the `loo_subsample()` function to compute the efficient PSIS-LOO approximation to exact LOO-CV using subsampling: ```{r, eval=FALSE} set.seed(4711) loo_ss_1 <- loo_subsample( llfun_logistic, observations = 100, # take a subsample of size 100 cores = 2, # these next objects were computed above r_eff = r_eff, draws = parameter_draws_1, data = stan_df_1 ) print(loo_ss_1) ``` ``` Computed from 4000 by 100 subsampled log-likelihood values from 3020 total observations. Estimate SE subsampling SE elpd_loo -1968.5 15.6 0.3 p_loo 3.1 0.1 0.4 looic 3936.9 31.2 0.6 ------ Monte Carlo SE of elpd_loo is 0.0. All Pareto k estimates are good (k < 0.5). See help('pareto-k-diagnostic') for details. ``` The `loo_subsample()` function creates an object of class `psis_loo_ss`, that inherits from `psis_loo, loo` (the classes of regular `loo` objects). The printed output above shows the estimates $\widehat{\mbox{elpd}}_{\rm loo}$ (expected log predictive density), $\widehat{p}_{\rm loo}$ (effective number of parameters), and ${\rm looic} =-2\, \widehat{\mbox{elpd}}_{\rm loo}$ (the LOO information criterion). Unlike when using `loo()`, when using `loo_subsample()` there is an additional column giving the "subsampling SE", which reflects the additional uncertainty due to the subsampling used. The line at the bottom of the printed output provides information about the reliability of the LOO approximation (the interpretation of the $k$ parameter is explained in `help('pareto-k-diagnostic')` and in greater detail in Vehtari, Simpson, Gelman, Yao, and Gabry (2019)). In this case, the message tells us that all of the estimates for $k$ are fine _for this given subsample_. ## Adding additional subsamples If we are not satisfied with the subsample size (i.e., the accuracy) we can simply add more samples until we are satisfied using the `update()` method. ```{r, eval=FALSE} set.seed(4711) loo_ss_1b <- update( loo_ss_1, observations = 200, # subsample 200 instead of 100 r_eff = r_eff, draws = parameter_draws_1, data = stan_df_1 ) print(loo_ss_1b) ``` ``` Computed from 4000 by 200 subsampled log-likelihood values from 3020 total observations. Estimate SE subsampling SE elpd_loo -1968.3 15.6 0.2 p_loo 3.2 0.1 0.4 looic 3936.7 31.2 0.5 ------ Monte Carlo SE of elpd_loo is 0.0. All Pareto k estimates are good (k < 0.5). See help('pareto-k-diagnostic') for details. ``` ## Specifying estimator and sampling method The performance relies on two components: the estimation method and the approximation used for the elpd. See the documentation for `loo_subsample()` more information on which estimators and approximations are implemented. The default implementation is using the point log predictive density evaluated at the mean of the posterior (`loo_approximation="plpd"`) and the difference estimator (`estimator="diff_srs"`). This combination has a focus on fast inference. But we can easily use other estimators as well as other elpd approximations, for example: ```{r, eval=FALSE} set.seed(4711) loo_ss_1c <- loo_subsample( x = llfun_logistic, r_eff = r_eff, draws = parameter_draws_1, data = stan_df_1, observations = 100, estimator = "hh_pps", # use Hansen-Hurwitz loo_approximation = "lpd", # use lpd instead of plpd loo_approximation_draws = 100, cores = 2 ) print(loo_ss_1c) ``` ``` Computed from 4000 by 100 subsampled log-likelihood values from 3020 total observations. Estimate SE subsampling SE elpd_loo -1968.9 15.4 0.5 p_loo 3.5 0.2 0.5 looic 3937.9 30.7 1.1 ------ Monte Carlo SE of elpd_loo is 0.0. All Pareto k estimates are good (k < 0.5). See help('pareto-k-diagnostic') for details. ``` See the documentation and references for `loo_subsample()` for details on the implemented approximations. # Approximate LOO-CV using PSIS-LOO with posterior approximations Using posterior approximations, such as variational inference and Laplace approximations, can further speed-up LOO-CV for large data. Here we demonstrate using a Laplace approximation in Stan. ```{r, eval=FALSE} fit_laplace <- optimizing(stan_mod, data = standata, draws = 2000, importance_resampling = TRUE) parameter_draws_laplace <- fit_laplace$theta_tilde # draws from approximate posterior log_p <- fit_laplace$log_p # log density of the posterior log_g <- fit_laplace$log_g # log density of the approximation ``` Using the posterior approximation we can then do LOO-CV by correcting for the posterior approximation when we compute the elpd. To do this we use the `loo_approximate_posterior()` function. ```{r, eval=FALSE} set.seed(4711) loo_ap_1 <- loo_approximate_posterior( x = llfun_logistic, draws = parameter_draws_laplace, data = stan_df_1, log_p = log_p, log_g = log_g, cores = 2 ) print(loo_ap_1) ``` The function creates a class, `psis_loo_ap` that inherits from `psis_loo, loo`. ``` Computed from 2000 by 3020 log-likelihood matrix Estimate SE elpd_loo -1968.4 15.6 p_loo 3.2 0.2 looic 3936.8 31.2 ------ Posterior approximation correction used. Monte Carlo SE of elpd_loo is 0.0. Pareto k diagnostic values: Count Pct. Min. n_eff (-Inf, 0.5] (good) 2989 99.0% 1827 (0.5, 0.7] (ok) 31 1.0% 1996 (0.7, 1] (bad) 0 0.0% (1, Inf) (very bad) 0 0.0% All Pareto k estimates are ok (k < 0.7). See help('pareto-k-diagnostic') for details. ``` ## Combining the posterior approximation method with subsampling The posterior approximation correction can also be used together with subsampling: ```{r, eval=FALSE} set.seed(4711) loo_ap_ss_1 <- loo_subsample( x = llfun_logistic, draws = parameter_draws_laplace, data = stan_df_1, log_p = log_p, log_g = log_g, observations = 100, cores = 2 ) print(loo_ap_ss_1) ``` ``` Computed from 2000 by 100 subsampled log-likelihood values from 3020 total observations. Estimate SE subsampling SE elpd_loo -1968.2 15.6 0.4 p_loo 2.9 0.1 0.5 looic 3936.4 31.1 0.8 ------ Posterior approximation correction used. Monte Carlo SE of elpd_loo is 0.0. Pareto k diagnostic values: Count Pct. Min. n_eff (-Inf, 0.5] (good) 97 97.0% 1971 (0.5, 0.7] (ok) 3 3.0% 1997 (0.7, 1] (bad) 0 0.0% (1, Inf) (very bad) 0 0.0% All Pareto k estimates are ok (k < 0.7). See help('pareto-k-diagnostic') for details. ``` The object created is of class `psis_loo_ss`, which inherits from the `psis_loo_ap` class previously described. ## Comparing models To compare this model to an alternative model for the same data we can use the `loo_compare()` function just as we would if using `loo()` instead of `loo_subsample()` or `loo_approximate_posterior()`. First we'll fit a second model to the well-switching data, using `log(arsenic)` instead of `arsenic` as a predictor: ```{r, eval=FALSE} standata$X[, "arsenic"] <- log(standata$X[, "arsenic"]) fit_2 <- sampling(stan_mod, data = standata) parameter_draws_2 <- extract(fit_2)$beta stan_df_2 <- as.data.frame(standata) # recompute subsampling loo for first model for demonstration purposes # compute relative efficiency (this is slow and optional but is recommended to allow # for adjusting PSIS effective sample size based on MCMC effective sample size) r_eff_1 <- relative_eff( llfun_logistic, log = FALSE, # relative_eff wants likelihood not log-likelihood values chain_id = rep(1:4, each = 1000), data = stan_df_1, draws = parameter_draws_1, cores = 2 ) set.seed(4711) loo_ss_1 <- loo_subsample( x = llfun_logistic, r_eff = r_eff_1, draws = parameter_draws_1, data = stan_df_1, observations = 200, cores = 2 ) # compute subsampling loo for a second model (with log-arsenic) r_eff_2 <- relative_eff( llfun_logistic, log = FALSE, # relative_eff wants likelihood not log-likelihood values chain_id = rep(1:4, each = 1000), data = stan_df_2, draws = parameter_draws_2, cores = 2 ) loo_ss_2 <- loo_subsample( x = llfun_logistic, r_eff = r_eff_2, draws = parameter_draws_2, data = stan_df_2, observations = 200, cores = 2 ) print(loo_ss_2) ``` ``` Computed from 4000 by 100 subsampled log-likelihood values from 3020 total observations. Estimate SE subsampling SE elpd_loo -1952.0 16.2 0.2 p_loo 2.6 0.1 0.3 looic 3903.9 32.4 0.4 ------ Monte Carlo SE of elpd_loo is 0.0. All Pareto k estimates are good (k < 0.5). See help('pareto-k-diagnostic') for details. ``` We can now compare the models on LOO using the `loo_compare` function: ```{r, eval=FALSE} # Compare comp <- loo_compare(loo_ss_1, loo_ss_2) print(comp) ``` ``` Warning: Different subsamples in 'model2' and 'model1'. Naive diff SE is used. elpd_diff se_diff subsampling_se_diff model2 0.0 0.0 0.0 model1 16.5 22.5 0.4 ``` This new object `comp` contains the estimated difference of expected leave-one-out prediction errors between the two models, along with the standard error. As the warning indicates, because different subsamples were used the comparison will not take the correlations between different observations into account. Here we see that the naive SE is 22.5 and we cannot see any difference in performance between the models. To force subsampling to use the same observations for each of the models we can simply extract the observations used in `loo_ss_1` and use them in `loo_ss_2` by supplying the `loo_ss_1` object to the `observations` argument. ```{r, eval=FALSE} loo_ss_2 <- loo_subsample( x = llfun_logistic, r_eff = r_eff_2, draws = parameter_draws_2, data = stan_df_2, observations = loo_ss_1, cores = 2 ) ``` We could also supply the subsampling indices using the `obs_idx()` helper function: ```{r, eval=FALSE} idx <- obs_idx(loo_ss_1) loo_ss_2 <- loo_subsample( x = llfun_logistic, r_eff = r_eff_2, draws = parameter_draws_2, data = stan_df_2, observations = idx, cores = 2 ) ``` ``` Simple random sampling with replacement assumed. ``` This results in a message indicating that we assume these observations to have been sampled with simple random sampling, which is true because we had used the default `"diff_srs"` estimator for `loo_ss_1`. We can now compare the models and estimate the difference based on the same subsampled observations. ```{r, eval=FALSE} comp <- loo_compare(loo_ss_1, loo_ss_2) print(comp) ``` ``` elpd_diff se_diff subsampling_se_diff model2 0.0 0.0 0.0 model1 16.1 4.4 0.1 ``` First, notice that now the `se_diff` is now around 4 (as opposed to 20 when using different subsamples). The first column shows the difference in ELPD relative to the model with the largest ELPD. In this case, the difference in `elpd` and its scale relative to the approximate standard error of the difference) indicates a preference for the second model (`model2`). Since the subsampling uncertainty is so small in this case it can effectively be ignored. If we need larger subsamples we can simply add samples using the `update()` method demonstrated earlier. It is also possible to compare a subsampled loo computation with a full loo object. ```{r, eval=FALSE} # use loo() instead of loo_subsample() to compute full PSIS-LOO for model 2 loo_full_2 <- loo( x = llfun_logistic, r_eff = r_eff_2, draws = parameter_draws_2, data = stan_df_2, cores = 2 ) loo_compare(loo_ss_1, loo_full_2) ``` ``` Estimated elpd_diff using observations included in loo calculations for all models. ``` Because we are comparing a non-subsampled loo calculation to a subsampled calculation we get the message that only the observations that are included in the loo calculations for both `model1` and `model2` are included in the computations for the comparison. ``` elpd_diff se_diff subsampling_se_diff model2 0.0 0.0 0.0 model1 16.3 4.4 0.3 ``` Here we actually see an increase in `subsampling_se_diff`, but this is due to a technical detail not elaborated here. In general, the difference should be better or negligible. # References Gelman, A., and Hill, J. (2007). *Data Analysis Using Regression and Multilevel Hierarchical Models.* Cambridge University Press. Stan Development Team (2017). _The Stan C++ Library, Version 2.17.0._ https://mc-stan.org/ Stan Development Team (2018) _RStan: the R interface to Stan, Version 2.17.3._ https://mc-stan.org/ Magnusson, M., Riis Andersen, M., Jonasson, J. and Vehtari, A. (2020). Leave-One-Out Cross-Validation for Model Comparison in Large Data. Proceedings of the 23rd International Conference on Artificial Intelligence and Statistics (AISTATS), in PMLR 108. [arXiv preprint arXiv:2001.00980](https://arxiv.org/abs/2001.00980). Magnusson, M., Andersen, M., Jonasson, J. & Vehtari, A. (2019). Bayesian leave-one-out cross-validation for large data. Proceedings of the 36th International Conference on Machine Learning, in PMLR 97:4244-4253 [online](http://proceedings.mlr.press/v97/magnusson19a.html), [arXiv preprint arXiv:1904.10679](https://arxiv.org/abs/1904.10679). Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. _Statistics and Computing_. 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. [online](https://link.springer.com/article/10.1007/s11222-016-9696-4), [arXiv preprint arXiv:1507.04544](https://arxiv.org/abs/1507.04544). Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. [arXiv preprint arXiv:1507.02646](https://arxiv.org/abs/1507.02646). loo/inst/doc/loo2-non-factorized.html0000644000176200001440000130507714411465466017276 0ustar liggesusers Leave-one-out cross-validation for non-factorized models

Leave-one-out cross-validation for non-factorized models

Aki Vehtari, Paul Bürkner and Jonah Gabry

2023-03-30

Introduction

When computing ELPD-based LOO-CV for a Bayesian model we need to compute the log leave-one-out predictive densities \(\log{p(y_i | y_{-i})}\) for every response value \(y_i, \: i = 1, \ldots, N\), where \(y_{-i}\) denotes all response values except observation \(i\). To obtain \(p(y_i | y_{-i})\), we need to have access to the pointwise likelihood \(p(y_i\,|\, y_{-i}, \theta)\) and integrate over the model parameters \(\theta\):

\[ p(y_i\,|\,y_{-i}) = \int p(y_i\,|\, y_{-i}, \theta) \, p(\theta\,|\, y_{-i}) \,d \theta \]

Here, \(p(\theta\,|\, y_{-i})\) is the leave-one-out posterior distribution for \(\theta\), that is, the posterior distribution for \(\theta\) obtained by fitting the model while holding out the \(i\)th observation (we will later show how refitting the model to data \(y_{-i}\) can be avoided).

If the observation model is formulated directly as the product of the pointwise observation models, we call it a factorized model. In this case, the likelihood is also the product of the pointwise likelihood contributions \(p(y_i\,|\, y_{-i}, \theta)\). To better illustrate possible structures of the observation models, we formally divide \(\theta\) into two parts, observation-specific latent variables \(f = (f_1, \ldots, f_N)\) and hyperparameters \(\psi\), so that \(p(y_i\,|\, y_{-i}, \theta) = p(y_i\,|\, y_{-i}, f_i, \psi)\). Depending on the model, one of the two parts of \(\theta\) may also be empty. In very simple models, such as linear regression models, latent variables are not explicitly presented and response values are conditionally independent given \(\psi\), so that \(p(y_i\,|\, y_{-i}, f_i, \psi) = p(y_i \,|\, \psi)\). The full likelihood can then be written in the familiar form

\[ p(y \,|\, \psi) = \prod_{i=1}^N p(y_i \,|\, \psi), \]

where \(y = (y_1, \ldots, y_N)\) denotes the vector of all responses. When the likelihood factorizes this way, the conditional pointwise log-likelihood can be obtained easily by computing \(p(y_i\,|\, \psi)\) for each \(i\) with computational cost \(O(n)\).

Yet, there are several reasons why a non-factorized observation model may be necessary or preferred. In non-factorized models, the joint likelihood of the response values \(p(y \,|\, \theta)\) is not factorized into observation-specific components, but rather given directly as one joint expression. For some models, an analytic factorized formulation is simply not available in which case we speak of a non-factorizable model. Even in models whose observation model can be factorized in principle, it may still be preferable to use a non-factorized form for reasons of efficiency and numerical stability (Bürkner et al. 2020).

Whether a non-factorized model is used by necessity or for efficiency and stability, it comes at the cost of having no direct access to the leave-one-out predictive densities and thus to the overall leave-one-out predictive accuracy. In theory, we can express the observation-specific likelihoods in terms of the joint likelihood via

\[ p(y_i \,|\, y_{i-1}, \theta) = \frac{p(y \,|\, \theta)}{p(y_{-i} \,|\, \theta)} = \frac{p(y \,|\, \theta)}{\int p(y \,|\, \theta) \, d y_i}, \]

but the expression on the right-hand side may not always have an analytical solution. Computing \(\log p(y_i \,|\, y_{-i}, \theta)\) for non-factorized models is therefore often impossible, or at least inefficient and numerically unstable. However, there is a large class of multivariate normal and Student-\(t\) models for which there are efficient analytical solutions available.

More details can be found in our paper about LOO-CV for non-factorized models (Bürkner, Gabry, & Vehtari, 2020), which is available as a preprint on arXiv (https://arxiv.org/abs/1810.10559).

LOO-CV for multivariate normal models

In this vignette, we will focus on non-factorized multivariate normal models. Based on results of Sundararajan and Keerthi (2001), Bürkner et al. (2020) show that, for multivariate normal models with coriance matrix \(C\), the LOO predictive mean and standard deviation can be computed as follows:

\[\begin{align} \mu_{\tilde{y},-i} &= y_i-\bar{c}_{ii}^{-1} g_i \nonumber \\ \sigma_{\tilde{y},-i} &= \sqrt{\bar{c}_{ii}^{-1}}, \end{align}\] where \(g_i\) and \(\bar{c}_{ii}\) are \[\begin{align} g_i &= \left[C^{-1} y\right]_i \nonumber \\ \bar{c}_{ii} &= \left[C^{-1}\right]_{ii}. \end{align}\]

Using these results, the log predictive density of the \(i\)th observation is then computed as

\[ \log p(y_i \,|\, y_{-i},\theta) = - \frac{1}{2}\log(2\pi) - \frac{1}{2}\log \sigma^2_{-i} - \frac{1}{2}\frac{(y_i-\mu_{-i})^2}{\sigma^2_{-i}}. \]

Expressing this same equation in terms of \(g_i\) and \(\bar{c}_{ii}\), the log predictive density becomes:

\[ \log p(y_i \,|\, y_{-i},\theta) = - \frac{1}{2}\log(2\pi) + \frac{1}{2}\log \bar{c}_{ii} - \frac{1}{2}\frac{g_i^2}{\bar{c}_{ii}}. \] (Note that Vehtari et al. (2016) has a typo in the corresponding Equation 34.)

From these equations we can now derive a recipe for obtaining the conditional pointwise log-likelihood for all models that can be expressed conditionally in terms of a multivariate normal with invertible covariance matrix \(C\).

Approximate LOO-CV using integrated importance-sampling

The above LOO equations for multivariate normal models are conditional on parameters \(\theta\). Therefore, to obtain the leave-one-out predictive density \(p(y_i \,|\, y_{-i})\) we need to integrate over \(\theta\),

\[ p(y_i\,|\,y_{-i}) = \int p(y_i\,|\,y_{-i}, \theta) \, p(\theta\,|\,y_{-i}) \,d\theta. \]

Here, \(p(\theta\,|\,y_{-i})\) is the leave-one-out posterior distribution for \(\theta\), that is, the posterior distribution for \(\theta\) obtained by fitting the model while holding out the \(i\)th observation.

To avoid the cost of sampling from \(N\) leave-one-out posteriors, it is possible to take the posterior draws \(\theta^{(s)}, \, s=1,\ldots,S\), from the posterior \(p(\theta\,|\,y)\), and then approximate the above integral using integrated importance sampling (Vehtari et al., 2016, Section 3.6.1):

\[ p(y_i\,|\,y_{-i}) \approx \frac{ \sum_{s=1}^S p(y_i\,|\,y_{-i},\,\theta^{(s)}) \,w_i^{(s)}}{ \sum_{s=1}^S w_i^{(s)}}, \]

where \(w_i^{(s)}\) are importance weights. First we compute the raw importance ratios

\[ r_i^{(s)} \propto \frac{1}{p(y_i \,|\, y_{-i}, \,\theta^{(s)})}, \]

and then stabilize them using Pareto smoothed importance sampling (PSIS, Vehtari et al, 2019) to obtain the weights \(w_i^{(s)}\). The resulting approximation is referred to as PSIS-LOO (Vehtari et al, 2017).

Exact LOO-CV with re-fitting

In order to validate the approximate LOO procedure, and also in order to allow exact computations to be made for a small number of leave-one-out folds for which the Pareto \(k\) diagnostic (Vehtari et al, 2019) indicates an unstable approximation, we need to consider how we might to do exact leave-one-out CV for a non-factorized model. In the case of a Gaussian process that has the marginalization property, we could just drop the one row and column of \(C\) corresponding to the held out out observation. This does not hold in general for multivariate normal models, however, and to keep the original prior we may need to maintain the full covariance matrix \(C\) even when one of the observations is left out.

The solution is to model \(y_i\) as a missing observation and estimate it along with all of the other model parameters. For a conditional multivariate normal model, \(\log p(y_i\,|\,y_{-i})\) can be computed as follows. First, we model \(y_i\) as missing and denote the corresponding parameter \(y_i^{\mathrm{mis}}\). Then, we define

\[ y_{\mathrm{mis}(i)} = (y_1, \ldots, y_{i-1}, y_i^{\mathrm{mis}}, y_{i+1}, \ldots, y_N). \] to be the same as the full set of observations \(y\), except replacing \(y_i\) with the parameter \(y_i^{\mathrm{mis}}\).

Second, we compute the LOO predictive mean and standard deviations as above, but replace \(y\) with \(y_{\mathrm{mis}(i)}\) in the computation of \(\mu_{\tilde{y},-i}\):

\[ \mu_{\tilde{y},-i} = y_{{\mathrm{mis}}(i)}-\bar{c}_{ii}^{-1}g_i, \]

where in this case we have

\[ g_i = \left[ C^{-1} y_{\mathrm{mis}(i)} \right]_i. \]

The conditional log predictive density is then computed with the above \(\mu_{\tilde{y},-i}\) and the left out observation \(y_i\):

\[ \log p(y_i\,|\,y_{-i},\theta) = - \frac{1}{2}\log(2\pi) - \frac{1}{2}\log \sigma^2_{\tilde{y},-i} - \frac{1}{2}\frac{(y_i-\mu_{\tilde{y},-i})^2}{\sigma^2_{\tilde{y},-i}}. \]

Finally, the leave-one-out predictive distribution can then be estimated as

\[ p(y_i\,|\,y_{-i}) \approx \sum_{s=1}^S p(y_i\,|\,y_{-i}, \theta_{-i}^{(s)}), \]

where \(\theta_{-i}^{(s)}\) are draws from the posterior distribution \(p(\theta\,|\,y_{\mathrm{mis}(i)})\).

Lagged SAR models

A common non-factorized multivariate normal model is the simultaneously autoregressive (SAR) model, which is frequently used for spatially correlated data. The lagged SAR model is defined as

\[ y = \rho Wy + \eta + \epsilon \] or equivalently \[ (I - \rho W)y = \eta + \epsilon, \] where \(\rho\) is the spatial correlation parameter and \(W\) is a user-defined weight matrix. The matrix \(W\) has entries \(w_{ii} = 0\) along the diagonal and the off-diagonal entries \(w_{ij}\) are larger when areas \(i\) and \(j\) are closer to each other. In a linear model, the predictor term \(\eta\) is given by \(\eta = X \beta\) with design matrix \(X\) and regression coefficients \(\beta\). However, since the above equation holds for arbitrary \(\eta\), these results are not restricted to linear models.

If we have \(\epsilon \sim {\mathrm N}(0, \,\sigma^2 I)\), it follows that \[ (I - \rho W)y \sim {\mathrm N}(\eta, \sigma^2 I), \] which corresponds to the following log PDF coded in Stan:

/** 
 * Normal log-pdf for spatially lagged responses
 * 
 * @param y Vector of response values.
 * @param mu Mean parameter vector.
 * @param sigma Positive scalar residual standard deviation.
 * @param rho Positive scalar autoregressive parameter.
 * @param W Spatial weight matrix.
 *
 * @return A scalar to be added to the log posterior.
 */
real normal_lagsar_lpdf(vector y, vector mu, real sigma, 
                        real rho, matrix W) {
  int N = rows(y);
  real inv_sigma2 = 1 / square(sigma);
  matrix[N, N] W_tilde = -rho * W;
  vector[N] half_pred;
  
  for (n in 1:N) W_tilde[n,n] += 1;
  
  half_pred = W_tilde * (y - mdivide_left(W_tilde, mu));
  
  return 0.5 * log_determinant(crossprod(W_tilde) * inv_sigma2) -
         0.5 * dot_self(half_pred) * inv_sigma2;
}

For the purpose of computing LOO-CV, it makes sense to rewrite the SAR model in slightly different form. Conditional on \(\rho\), \(\eta\), and \(\sigma\), if we write

\[\begin{align} y-(I-\rho W)^{-1}\eta &\sim {\mathrm N}(0, \sigma^2(I-\rho W)^{-1}(I-\rho W)^{-T}), \end{align}\] or more compactly, with \(\widetilde{W}=(I-\rho W)\), \[\begin{align} y-\widetilde{W}^{-1}\eta &\sim {\mathrm N}(0, \sigma^2(\widetilde{W}^{T}\widetilde{W})^{-1}), \end{align}\]

then this has the same form as the zero mean Gaussian process from above. Accordingly, we can compute the leave-one-out predictive densities with the equations from Sundararajan and Keerthi (2001), replacing \(y\) with \((y-\widetilde{W}^{-1}\eta)\) and taking the covariance matrix \(C\) to be \(\sigma^2(\widetilde{W}^{T}\widetilde{W})^{-1}\).

Case Study: Neighborhood Crime in Columbus, Ohio

In order to demonstrate how to carry out the computations implied by these equations, we will first fit a lagged SAR model to data on crime in 49 different neighborhoods of Columbus, Ohio during the year 1980. The data was originally described in Aneslin (1988) and ships with the spdep R package.

In addition to the loo package, for this analysis we will use the brms interface to Stan to generate a Stan program and fit the model, and also the bayesplot and ggplot2 packages for plotting.

library("loo")
library("brms")
library("bayesplot")
library("ggplot2")
color_scheme_set("brightblue")
theme_set(theme_default())


SEED <- 10001 
set.seed(SEED) # only sets seed for R (seed for Stan set later)

# loads COL.OLD data frame and COL.nb neighbor list
data(oldcol, package = "spdep") 

The three variables in the data set relevant to this example are:

  • CRIME: the number of residential burglaries and vehicle thefts per thousand households in the neighbood
  • HOVAL: housing value in units of $1000 USD
  • INC: household income in units of $1000 USD
str(COL.OLD[, c("CRIME", "HOVAL", "INC")])
'data.frame':   49 obs. of  3 variables:
 $ CRIME: num  18.802 32.388 38.426 0.178 15.726 ...
 $ HOVAL: num  44.6 33.2 37.1 75 80.5 ...
 $ INC  : num  21.23 4.48 11.34 8.44 19.53 ...

We will also use the object COL.nb, which is a list containing information about which neighborhoods border each other. From this list we will be able to construct the weight matrix to used to help account for the spatial dependency among the observations.

Fit lagged SAR model

A model predicting CRIME from INC and HOVAL, while accounting for the spatial dependency via an SAR structure, can be specified in brms as follows.

fit <- brm(
  CRIME ~ INC + HOVAL + sar(COL.nb, type = "lag"), 
  data = COL.OLD,
  data2 = list(COL.nb = COL.nb),
  chains = 4,
  seed = SEED
)

The code above fits the model in Stan using a log PDF equivalent to the normal_lagsar_lpdf function we defined above. In the summary output below we see that both higher income and higher housing value predict lower crime rates in the neighborhood. Moreover, there seems to be substantial spatial correlation between adjacent neighborhoods, as indicated by the posterior distribution of the lagsar parameter.

lagsar <- as.matrix(fit, pars = "lagsar")
estimates <- quantile(lagsar, probs = c(0.25, 0.5, 0.75))
mcmc_hist(lagsar) + 
  vline_at(estimates, linetype = 2, size = 1) +
  ggtitle("lagsar: posterior median and 50% central interval")

Approximate LOO-CV

After fitting the model, the next step is to compute the pointwise log-likelihood values needed for approximate LOO-CV. To do this we will use the recipe laid out in the previous sections.

posterior <- as.data.frame(fit)
y <- fit$data$CRIME
N <- length(y)
S <- nrow(posterior)
loglik <- yloo <- sdloo <- matrix(nrow = S, ncol = N)

for (s in 1:S) {
  p <- posterior[s, ]
  eta <- p$b_Intercept + p$b_INC * fit$data$INC + p$b_HOVAL * fit$data$HOVAL
  W_tilde <- diag(N) - p$lagsar * spdep::nb2mat(COL.nb)
  Cinv <- t(W_tilde) %*% W_tilde / p$sigma^2
  g <- Cinv %*% (y - solve(W_tilde, eta))
  cbar <- diag(Cinv)
  yloo[s, ] <- y - g / cbar
  sdloo[s, ] <- sqrt(1 / cbar)
  loglik[s, ] <- dnorm(y, yloo[s, ], sdloo[s, ], log = TRUE)
}

# use loo for psis smoothing
log_ratios <- -loglik
psis_result <- psis(log_ratios)

The quality of the PSIS-LOO approximation can be investigated graphically by plotting the Pareto-k estimate for each observation. Ideally, they should not exceed \(0.5\), but in practice the algorithm turns out to be robust up to values of \(0.7\) (Vehtari et al, 2017, 2019). In the plot below, we see that the fourth observation is problematic and so may reduce the accuracy of the LOO-CV approximation.

plot(psis_result, label_points = TRUE)

We can also check that the conditional leave-one-out predictive distribution equations work correctly, for instance, using the last posterior draw:

yloo_sub <- yloo[S, ]
sdloo_sub <- sdloo[S, ]
df <- data.frame(
  y = y, 
  yloo = yloo_sub,
  ymin = yloo_sub - sdloo_sub * 2,
  ymax = yloo_sub + sdloo_sub * 2
)
ggplot(data=df, aes(x = y, y = yloo, ymin = ymin, ymax = ymax)) +
  geom_errorbar(
    width = 1, 
    color = "skyblue3", 
    position = position_jitter(width = 0.25)
  ) +
  geom_abline(color = "gray30", size = 1.2) +
  geom_point()

Finally, we use PSIS-LOO to approximate the expected log predictive density (ELPD) for new data, which we will validate using exact LOO-CV in the upcoming section.

(psis_loo <- loo(loglik))

Computed from 4000 by 49 log-likelihood matrix

         Estimate   SE
elpd_loo   -186.7 10.4
p_loo         7.8  4.9
looic       373.5 20.8
------
Monte Carlo SE of elpd_loo is NA.

Pareto k diagnostic values:
                         Count Pct.    Min. n_eff
(-Inf, 0.5]   (good)     47    95.9%   2252      
 (0.5, 0.7]   (ok)        0     0.0%   <NA>      
   (0.7, 1]   (bad)       2     4.1%   57        
   (1, Inf)   (very bad)  0     0.0%   <NA>      
See help('pareto-k-diagnostic') for details.

Exact LOO-CV

Exact LOO-CV for the above example is somewhat more involved, as we need to re-fit the model \(N\) times and each time model the held-out data point as a parameter. First, we create an empty dummy model that we will update below as we loop over the observations.

# see help("mi", "brms") for details on the mi() usage
fit_dummy <- brm(
  CRIME | mi() ~ INC + HOVAL + sar(COL.nb, type = "lag"), 
  data = COL.OLD,
  data2 = list(COL.nb = COL.nb),
  chains = 0
)

Next, we fit the model \(N\) times, each time leaving out a single observation and then computing the log predictive density for that observation. For obvious reasons, this takes much longer than the approximation we computed above, but it is necessary in order to validate the approximate LOO-CV method. Thanks to the PSIS-LOO approximation, in general doing these slow exact computations can be avoided.

S <- 500
res <- vector("list", N)
loglik <- matrix(nrow = S, ncol = N)
for (i in seq_len(N)) {
  dat_mi <- COL.OLD
  dat_mi$CRIME[i] <- NA
  fit_i <- update(fit_dummy, newdata = dat_mi, 
                  # just for vignette
                  chains = 1, iter = S * 2)
  posterior <- as.data.frame(fit_i)
  yloo <- sdloo <- rep(NA, S)
  for (s in seq_len(S)) {
    p <- posterior[s, ]
    y_miss_i <- y
    y_miss_i[i] <- p$Ymi
    eta <- p$b_Intercept + p$b_INC * fit_i$data$INC + p$b_HOVAL * fit_i$data$HOVAL
    W_tilde <- diag(N) - p$lagsar * spdep::nb2mat(COL.nb)
    Cinv <- t(W_tilde) %*% W_tilde / p$sigma^2
    g <- Cinv %*% (y_miss_i - solve(W_tilde, eta))
    cbar <- diag(Cinv);
    yloo[s] <- y_miss_i[i] - g[i] / cbar[i]
    sdloo[s] <- sqrt(1 / cbar[i])
    loglik[s, i] <- dnorm(y[i], yloo[s], sdloo[s], log = TRUE)
  }
  ypred <- rnorm(S, yloo, sdloo)
  res[[i]] <- data.frame(y = c(posterior$Ymi, ypred))
  res[[i]]$type <- rep(c("pp", "loo"), each = S)
  res[[i]]$obs <- i
}
res <- do.call(rbind, res)

A first step in the validation of the pointwise predictive density is to compare the distribution of the implied response values for the left-out observation to the distribution of the \(y_i^{\mathrm{mis}}\) posterior-predictive values estimated as part of the model. If the pointwise predictive density is correct, the two distributions should match very closely (up to sampling error). In the plot below, we overlay these two distributions for the first four observations and see that they match very closely (as is the case for all \(49\) observations of in this example).

res_sub <- res[res$obs %in% 1:4, ]
ggplot(res_sub, aes(y, fill = type)) +
  geom_density(alpha = 0.6) +
  facet_wrap("obs", scales = "fixed", ncol = 4)

In the final step, we compute the ELPD based on the exact LOO-CV and compare it to the approximate PSIS-LOO result computed earlier.

log_mean_exp <- function(x) {
  # more stable than log(mean(exp(x)))
  max_x <- max(x)
  max_x + log(sum(exp(x - max_x))) - log(length(x))
}
exact_elpds <- apply(loglik, 2, log_mean_exp)
exact_elpd <- sum(exact_elpds)
round(exact_elpd, 1)
[1] -189

The results of the approximate and exact LOO-CV are similar but not as close as we would expect if there were no problematic observations. We can investigate this issue more closely by plotting the approximate against the exact pointwise ELPD values.

df <- data.frame(
  approx_elpd = psis_loo$pointwise[, "elpd_loo"],
  exact_elpd = exact_elpds
)
ggplot(df, aes(x = approx_elpd, y = exact_elpd)) +
  geom_abline(color = "gray30") +
  geom_point(size = 2) +
  geom_point(data = df[4, ], size = 3, color = "red3") +
  xlab("Approximate elpds") +
  ylab("Exact elpds") +
  coord_fixed(xlim = c(-16, -3), ylim = c(-16, -3))

In the plot above the fourth data point —the observation flagged as problematic by the PSIS-LOO approximation— is colored in red and is the clear outlier. Otherwise, the correspondence between the exact and approximate values is strong. In fact, summing over the pointwise ELPD values and leaving out the fourth observation yields practically equivalent results for approximate and exact LOO-CV:

without_pt_4 <- c(
  approx = sum(psis_loo$pointwise[-4, "elpd_loo"]),
  exact = sum(exact_elpds[-4])  
)
round(without_pt_4, 1)
approx  exact 
-173.3 -173.0 

From this we can conclude that the difference we found when including all observations does not indicate a bug in our implementation of the approximate LOO-CV but rather a violation of its assumptions.

Working with Stan directly

So far, we have specified the models in brms and only used Stan implicitely behind the scenes. This allowed us to focus on the primary purpose of validating approximate LOO-CV for non-factorized models. However, we would also like to show how everything can be set up in Stan directly. The Stan code brms generates is human readable and so we can use it to learn some of the essential aspects of Stan and the particular model we are implementing. The Stan program below is a slightly modified version of the code extracted via stancode(fit_dummy):

// generated with brms 2.2.0
functions {
/** 
 * Normal log-pdf for spatially lagged responses
 * 
 * @param y Vector of response values.
 * @param mu Mean parameter vector.
 * @param sigma Positive scalar residual standard deviation.
 * @param rho Positive scalar autoregressive parameter.
 * @param W Spatial weight matrix.
 *
 * @return A scalar to be added to the log posterior.
 */
  real normal_lagsar_lpdf(vector y, vector mu, real sigma,
                          real rho, matrix W) {
    int N = rows(y);
    real inv_sigma2 = 1 / square(sigma);
    matrix[N, N] W_tilde = -rho * W;
    vector[N] half_pred;
    for (n in 1:N) W_tilde[n, n] += 1;
    half_pred = W_tilde * (y - mdivide_left(W_tilde, mu));
    return 0.5 * log_determinant(crossprod(W_tilde) * inv_sigma2) -
           0.5 * dot_self(half_pred) * inv_sigma2;
  }
}
data {
  int<lower=1> N;  // total number of observations
  vector[N] Y;  // response variable
  int<lower=0> Nmi;  // number of missings
  int<lower=1> Jmi[Nmi];  // positions of missings
  int<lower=1> K;  // number of population-level effects
  matrix[N, K] X;  // population-level design matrix
  matrix[N, N] W;  // spatial weight matrix
  int prior_only;  // should the likelihood be ignored?
}
transformed data {
  int Kc = K - 1;
  matrix[N, K - 1] Xc;  // centered version of X
  vector[K - 1] means_X;  // column means of X before centering
  for (i in 2:K) {
    means_X[i - 1] = mean(X[, i]);
    Xc[, i - 1] = X[, i] - means_X[i - 1];
  }
}
parameters {
  vector[Nmi] Ymi;  // estimated missings
  vector[Kc] b;  // population-level effects
  real temp_Intercept;  // temporary intercept
  real<lower=0> sigma;  // residual SD
  real<lower=0,upper=1> lagsar;  // SAR parameter
}
transformed parameters {
}
model {
  vector[N] Yl = Y;
  vector[N] mu = Xc * b + temp_Intercept;
  Yl[Jmi] = Ymi;
  // priors including all constants
  target += student_t_lpdf(temp_Intercept | 3, 34, 17);
  target += student_t_lpdf(sigma | 3, 0, 17)
    - 1 * student_t_lccdf(0 | 3, 0, 17);
  // likelihood including all constants
  if (!prior_only) {
    target += normal_lagsar_lpdf(Yl | mu, sigma, lagsar, W);
  }
}
generated quantities {
  // actual population-level intercept
  real b_Intercept = temp_Intercept - dot_product(means_X, b);
}

Here we want to focus on two aspects of the Stan code. First, because there is no built-in function in Stan that calculates the log-likelihood for the lag-SAR model, we define a new normal_lagsar_lpdf function in the functions block of the Stan program. This is the same function we showed earlier in the vignette and it can be used to compute the log-likelihood in an efficient and numerically stable way. The _lpdf suffix used in the function name informs Stan that this is a log probability density function.

Second, this Stan program nicely illustrates how to set up missing value imputation. Instead of just computing the log-likelihood for the observed responses Y, we define a new variable Yl which is equal to Y if the reponse is observed and equal to Ymi if the response is missing. The latter is in turn defined as a parameter and thus estimated along with all other paramters of the model. More details about missing value imputation in Stan can be found in the Missing Data & Partially Known Parameters section of the Stan manual.

The Stan code extracted from brms is not only helpful when learning Stan, but can also drastically speed up the specification of models that are not support by brms. If brms can fit a model similar but not identical to the desired model, we can let brms generate the Stan program for the similar model and then mold it into the program that implements the model we actually want to fit. Rather than calling stancode(), which requires an existing fitted model object, we recommend using make_stancode() and specifying the save_model argument to write the Stan program to a file. The corresponding data can be prepared with make_standata() and then manually amended if needed. Once the code and data have been edited, they can be passed to RStan’s stan() function via the file and data arguments.

Conclusion

In summary, we have shown how to set up and validate approximate and exact LOO-CV for non-factorized multivariate normal models using Stan with the brms and loo packages. Although we focused on the particular example of a spatial SAR model, the presented recipe applies more generally to models that can be expressed in terms of a multivariate normal likelihood.


References

Anselin L. (1988). Spatial econometrics: methods and models. Dordrecht: Kluwer Academic.

Bürkner P. C., Gabry J., & Vehtari A. (2020). Efficient leave-one-out cross-validation for Bayesian non-factorized normal and Student-t models. Computational Statistics, :10.1007/s00180-020-01045-4. ArXiv preprint.

Sundararajan S. & Keerthi S. S. (2001). Predictive approaches for choosing hyperparameters in Gaussian processes. Neural Computation, 13(5), 1103–1118.

Vehtari A., Mononen T., Tolvanen V., Sivula T., & Winther O. (2016). Bayesian leave-one-out cross-validation approximations for Gaussian latent variable models. Journal of Machine Learning Research, 17(103), 1–38. Online.

Vehtari A., Gelman A., & Gabry J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. Statistics and Computing, 27(5), 1413–1432. :10.1007/s11222-016-9696-4. Online. arXiv preprint arXiv:1507.04544.

Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. arXiv preprint arXiv:1507.02646.

loo/inst/doc/loo2-elpd.Rmd0000644000176200001440000001723514407123455015043 0ustar liggesusers--- title: "Holdout validation and K-fold cross-validation of Stan programs with the loo package" author: "Bruno Nicenboim" date: "`r Sys.Date()`" output: html_vignette: toc: yes params: EVAL: !r identical(Sys.getenv("NOT_CRAN"), "true") --- ```{r, child="children/SETTINGS-knitr.txt"} ``` ```{r, child="children/SEE-ONLINE.txt", eval = if (isTRUE(exists("params"))) !params$EVAL else TRUE} ``` # Introduction This vignette demonstrates how to do holdout validation and K-fold cross-validation with __loo__ for a Stan program. # Example: Eradication of Roaches using holdout validation approach This vignette uses the same example as in the vignettes [_Using the loo package (version >= 2.0.0)_](http://mc-stan.org/loo/articles/loo2-example.html) and [_Avoiding model refits in leave-one-out cross-validation with moment matching_](https://mc-stan.org/loo/articles/loo2-moment-matching.html). ## Coding the Stan model Here is the Stan code for fitting a Poisson regression model: ```{r stancode} stancode <- " data { int K; int N; matrix[N,K] x; int y[N]; vector[N] offset; real beta_prior_scale; real alpha_prior_scale; } parameters { vector[K] beta; real intercept; } model { y ~ poisson(exp(x * beta + intercept + offset)); beta ~ normal(0,beta_prior_scale); intercept ~ normal(0,alpha_prior_scale); } generated quantities { vector[N] log_lik; for (n in 1:N) log_lik[n] = poisson_lpmf(y[n] | exp(x[n] * beta + intercept + offset[n])); } " ``` Following the usual approach recommended in [_Writing Stan programs for use with the loo package_](http://mc-stan.org/loo/articles/loo2-with-rstan.html), we compute the log-likelihood for each observation in the `generated quantities` block of the Stan program. ## Setup In addition to __loo__, we load the __rstan__ package for fitting the model. We will also need the __rstanarm__ package for the data. ```{r setup, message=FALSE} library("rstan") library("loo") seed <- 9547 set.seed(seed) ``` # Holdout validation For this approach, the model is first fit to the "train" data and then is evaluated on the held-out "test" data. ## Splitting the data between train and test The data is divided between train (80% of the data) and test (20%): ```{r modelfit-holdout, message=FALSE} # Prepare data data(roaches, package = "rstanarm") roaches$roach1 <- sqrt(roaches$roach1) roaches$offset <- log(roaches[,"exposure2"]) # 20% of the data goes to the test set: roaches$test <- 0 roaches$test[sample(.2 * seq_len(nrow(roaches)))] <- 1 # data to "train" the model data_train <- list(y = roaches$y[roaches$test == 0], x = as.matrix(roaches[roaches$test == 0, c("roach1", "treatment", "senior")]), N = nrow(roaches[roaches$test == 0,]), K = 3, offset = roaches$offset[roaches$test == 0], beta_prior_scale = 2.5, alpha_prior_scale = 5.0 ) # data to "test" the model data_test <- list(y = roaches$y[roaches$test == 1], x = as.matrix(roaches[roaches$test == 1, c("roach1", "treatment", "senior")]), N = nrow(roaches[roaches$test == 1,]), K = 3, offset = roaches$offset[roaches$test == 1], beta_prior_scale = 2.5, alpha_prior_scale = 5.0 ) ``` ## Fitting the model with RStan Next we fit the model to the "test" data in Stan using the __rstan__ package: ```{r fit-train} # Compile stanmodel <- stan_model(model_code = stancode) # Fit model fit <- sampling(stanmodel, data = data_train, seed = seed, refresh = 0) ``` We recompute the generated quantities using the posterior draws conditional on the training data, but we now pass in the held-out data to get the log predictive densities for the test data. Because we are using independent data, the log predictive density coincides with the log likelihood of the test data. ```{r gen-test} gen_test <- gqs(stanmodel, draws = as.matrix(fit), data= data_test) log_pd <- extract_log_lik(gen_test) ``` ## Computing holdout elpd: Now we evaluate the predictive performance of the model on the test data using `elpd()`. ```{r elpd-holdout} (elpd_holdout <- elpd(log_pd)) ``` When one wants to compare different models, the function `loo_compare()` can be used to assess the difference in performance. # K-fold cross validation For this approach the data is divided into folds, and each time one fold is tested while the rest of the data is used to fit the model (see Vehtari et al., 2017). ## Splitting the data in folds We use the data that is already pre-processed and we divide it in 10 random folds using `kfold_split_random` ```{r prepare-folds, message=FALSE} # Prepare data roaches$fold <- kfold_split_random(K = 10, N = nrow(roaches)) ``` ## Fitting and extracting the log pointwise predictive densities for each fold We now loop over the 10 folds. In each fold we do the following. First, we fit the model to all the observations except the ones belonging to the left-out fold. Second, we compute the log pointwise predictive densities for the left-out fold. Last, we store the predictive density for the observations of the left-out fold in a matrix. The output of this loop is a matrix of the log pointwise predictive densities of all the observations. ```{r} # Prepare a matrix with the number of post-warmup iterations by number of observations: log_pd_kfold <- matrix(nrow = 4000, ncol = nrow(roaches)) # Loop over the folds for(k in 1:10){ data_train <- list(y = roaches$y[roaches$fold != k], x = as.matrix(roaches[roaches$fold != k, c("roach1", "treatment", "senior")]), N = nrow(roaches[roaches$fold != k,]), K = 3, offset = roaches$offset[roaches$fold != k], beta_prior_scale = 2.5, alpha_prior_scale = 5.0 ) data_test <- list(y = roaches$y[roaches$fold == k], x = as.matrix(roaches[roaches$fold == k, c("roach1", "treatment", "senior")]), N = nrow(roaches[roaches$fold == k,]), K = 3, offset = roaches$offset[roaches$fold == k], beta_prior_scale = 2.5, alpha_prior_scale = 5.0 ) fit <- sampling(stanmodel, data = data_train, seed = seed, refresh = 0) gen_test <- gqs(stanmodel, draws = as.matrix(fit), data= data_test) log_pd_kfold[, roaches$fold == k] <- extract_log_lik(gen_test) } ``` ## Computing K-fold elpd: Now we evaluate the predictive performance of the model on the 10 folds using `elpd()`. ```{r elpd-kfold} (elpd_kfold <- elpd(log_pd_kfold)) ``` If one wants to compare several models (with `loo_compare`), one should use the same folds for all the different models. # References Gelman, A., and Hill, J. (2007). *Data Analysis Using Regression and Multilevel Hierarchical Models.* Cambridge University Press. Stan Development Team (2020) _RStan: the R interface to Stan, Version 2.21.1_ https://mc-stan.org Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. _Statistics and Computing_. 27(5), 1413--1432. \doi:10.1007/s11222-016-9696-4. Links: [published](https://link.springer.com/article/10.1007/s11222-016-9696-4) | [arXiv preprint](https://arxiv.org/abs/1507.04544). loo/inst/doc/loo2-large-data.html0000644000176200001440000015657414411455345016355 0ustar liggesusers Using Leave-one-out cross-validation for large data

Using Leave-one-out cross-validation for large data

Mans Magnusson, Paul Bürkner, Aki Vehtari and Jonah Gabry

2023-03-30

Introduction

This vignette demonstrates how to do leave-one-out cross-validation for large data using the loo package and Stan. There are two approaches covered: LOO with subsampling and LOO using approximations to posterior distributions. Some sections from this vignette are excerpted from the papers

  • Magnusson, M., Riis Andersen, M., Jonasson, J. and Vehtari, A. (2020). Leave-One-Out Cross-Validation for Model Comparison in Large Data. Proceedings of the 23rd International Conference on Artificial Intelligence and Statistics (AISTATS), in PMLR 108. arXiv preprint arXiv:2001.00980.

  • Magnusson, M., Andersen, M., Jonasson, J. & Vehtari, A. (2019). Bayesian leave-one-out cross-validation for large data. Proceedings of the 36th International Conference on Machine Learning, in PMLR 97:4244-4253 online, arXiv preprint arXiv:1904.10679.

  • Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. Statistics and Computing. 27(5), 1413–1432. :10.1007/s11222-016-9696-4. Links: published | arXiv preprint.

  • Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. arXiv preprint arXiv:1507.04544.

which provide important background for understanding the methods implemented in the package.

Setup

In addition to the loo package, we’ll also be using rstan:

library("rstan")
library("loo")
set.seed(4711)

Example: Well water in Bangladesh

We will use the same example as in the vignette Writing Stan programs for use with the loo package. See that vignette for a description of the problem and data.

The sample size in this example is only \(N=3020\), which is not large enough to require the special methods for large data described in this vignette, but is sufficient for demonstration purposes in this tutorial.

Coding the Stan model

Here is the Stan code for fitting the logistic regression model, which we save in a file called logistic.stan:

// save in `logistic.stan`
data {
  int<lower=0> N;             // number of data points
  int<lower=0> P;             // number of predictors (including intercept)
  matrix[N,P] X;              // predictors (including 1s for intercept)
  int<lower=0,upper=1> y[N];  // binary outcome
}
parameters {
  vector[P] beta;
}
model {
  beta ~ normal(0, 1);
  y ~ bernoulli_logit(X * beta);
}

Importantly, unlike the general approach recommended in Writing Stan programs for use with the loo package, we do not compute the log-likelihood for each observation in the generated quantities block of the Stan program. Here we are assuming we have a large data set (larger than the one we’re actually using in this demonstration) and so it is preferable to instead define a function in R to compute the log-likelihood for each data point when needed rather than storing all of the log-likelihood values in memory.

The log-likelihood in R can be coded as follows:

# we'll add an argument log to toggle whether this is a log-likelihood or 
# likelihood function. this will be useful later in the vignette.
llfun_logistic <- function(data_i, draws, log = TRUE) {
  x_i <- as.matrix(data_i[, which(grepl(colnames(data_i), pattern = "X")), drop=FALSE])
  logit_pred <- draws %*% t(x_i)
  dbinom(x = data_i$y, size = 1, prob = 1/(1 + exp(-logit_pred)), log = log)
}

The function llfun_logistic() needs to have arguments data_i and draws. Below we will test that the function is working by using the loo_i() function.

Fitting the model with RStan

Next we fit the model in Stan using the rstan package:

# Prepare data
url <- "http://stat.columbia.edu/~gelman/arm/examples/arsenic/wells.dat"
wells <- read.table(url)
wells$dist100 <- with(wells, dist / 100)
X <- model.matrix(~ dist100 + arsenic, wells)
standata <- list(y = wells$switch, X = X, N = nrow(X), P = ncol(X))

# Compile
stan_mod <- stan_model("logistic.stan")

# Fit model
fit_1 <- sampling(stan_mod, data = standata, seed = 4711)
print(fit_1, pars = "beta")
         mean se_mean   sd  2.5%   25%   50%   75% 97.5% n_eff Rhat
beta[1]  0.00       0 0.08 -0.15 -0.05  0.00  0.06  0.16  1933    1
beta[2] -0.89       0 0.10 -1.09 -0.96 -0.89 -0.82 -0.69  2332    1
beta[3]  0.46       0 0.04  0.38  0.43  0.46  0.49  0.54  2051    1

Before we move on to computing LOO we can now test that the log-likelihood function we wrote is working as it should. The loo_i() function is a helper function that can be used to test a log-likelihood function on a single observation.

# used for draws argument to loo_i
parameter_draws_1 <- extract(fit_1)$beta

# used for data argument to loo_i
stan_df_1 <- as.data.frame(standata)

# compute relative efficiency (this is slow and optional but is recommended to allow 
# for adjusting PSIS effective sample size based on MCMC effective sample size)
r_eff <- relative_eff(llfun_logistic, 
                      log = FALSE, # relative_eff wants likelihood not log-likelihood values
                      chain_id = rep(1:4, each = 1000), 
                      data = stan_df_1, 
                      draws = parameter_draws_1, 
                      cores = 2)

loo_i(i = 1, llfun_logistic, r_eff = r_eff, data = stan_df_1, draws = parameter_draws_1)
$pointwise
    elpd_loo mcse_elpd_loo        p_loo     looic influence_pareto_k
1 -0.3314552  0.0002887608 0.0003361772 0.6629103        -0.05679886
...

Approximate LOO-CV using PSIS-LOO and subsampling

We can then use the loo_subsample() function to compute the efficient PSIS-LOO approximation to exact LOO-CV using subsampling:

set.seed(4711)
loo_ss_1 <-
  loo_subsample(
    llfun_logistic,
    observations = 100, # take a subsample of size 100
    cores = 2,
    # these next objects were computed above
    r_eff = r_eff, 
    draws = parameter_draws_1,
    data = stan_df_1
  )
print(loo_ss_1)
Computed from 4000 by 100 subsampled log-likelihood
values from 3020 total observations.

         Estimate   SE subsampling SE
elpd_loo  -1968.5 15.6            0.3
p_loo         3.1  0.1            0.4
looic      3936.9 31.2            0.6
------
Monte Carlo SE of elpd_loo is 0.0.

All Pareto k estimates are good (k < 0.5).
See help('pareto-k-diagnostic') for details.

The loo_subsample() function creates an object of class psis_loo_ss, that inherits from psis_loo, loo (the classes of regular loo objects).

The printed output above shows the estimates \(\widehat{\mbox{elpd}}_{\rm loo}\) (expected log predictive density), \(\widehat{p}_{\rm loo}\) (effective number of parameters), and \({\rm looic} =-2\, \widehat{\mbox{elpd}}_{\rm loo}\) (the LOO information criterion). Unlike when using loo(), when using loo_subsample() there is an additional column giving the “subsampling SE”, which reflects the additional uncertainty due to the subsampling used.

The line at the bottom of the printed output provides information about the reliability of the LOO approximation (the interpretation of the \(k\) parameter is explained in help('pareto-k-diagnostic') and in greater detail in Vehtari, Simpson, Gelman, Yao, and Gabry (2019)). In this case, the message tells us that all of the estimates for \(k\) are fine for this given subsample.

Adding additional subsamples

If we are not satisfied with the subsample size (i.e., the accuracy) we can simply add more samples until we are satisfied using the update() method.

set.seed(4711)
loo_ss_1b <-
  update(
    loo_ss_1,
    observations = 200, # subsample 200 instead of 100
    r_eff = r_eff,
    draws = parameter_draws_1,
    data = stan_df_1
  ) 
print(loo_ss_1b)
Computed from 4000 by 200 subsampled log-likelihood
values from 3020 total observations.

         Estimate   SE subsampling SE
elpd_loo  -1968.3 15.6            0.2
p_loo         3.2  0.1            0.4
looic      3936.7 31.2            0.5
------
Monte Carlo SE of elpd_loo is 0.0.

All Pareto k estimates are good (k < 0.5).
See help('pareto-k-diagnostic') for details.

Specifying estimator and sampling method

The performance relies on two components: the estimation method and the approximation used for the elpd. See the documentation for loo_subsample() more information on which estimators and approximations are implemented. The default implementation is using the point log predictive density evaluated at the mean of the posterior (loo_approximation="plpd") and the difference estimator (estimator="diff_srs"). This combination has a focus on fast inference. But we can easily use other estimators as well as other elpd approximations, for example:

set.seed(4711)
loo_ss_1c <-
  loo_subsample(
    x = llfun_logistic,
    r_eff = r_eff,
    draws = parameter_draws_1,
    data = stan_df_1,
    observations = 100,
    estimator = "hh_pps", # use Hansen-Hurwitz
    loo_approximation = "lpd", # use lpd instead of plpd
    loo_approximation_draws = 100,
    cores = 2
  )
print(loo_ss_1c)
Computed from 4000 by 100 subsampled log-likelihood
values from 3020 total observations.

         Estimate   SE subsampling SE
elpd_loo  -1968.9 15.4            0.5
p_loo         3.5  0.2            0.5
looic      3937.9 30.7            1.1
------
Monte Carlo SE of elpd_loo is 0.0.

All Pareto k estimates are good (k < 0.5).
See help('pareto-k-diagnostic') for details.

See the documentation and references for loo_subsample() for details on the implemented approximations.

Approximate LOO-CV using PSIS-LOO with posterior approximations

Using posterior approximations, such as variational inference and Laplace approximations, can further speed-up LOO-CV for large data. Here we demonstrate using a Laplace approximation in Stan.

fit_laplace <- optimizing(stan_mod, data = standata, draws = 2000, 
                          importance_resampling = TRUE)
parameter_draws_laplace <- fit_laplace$theta_tilde # draws from approximate posterior
log_p <- fit_laplace$log_p # log density of the posterior
log_g <- fit_laplace$log_g # log density of the approximation

Using the posterior approximation we can then do LOO-CV by correcting for the posterior approximation when we compute the elpd. To do this we use the loo_approximate_posterior() function.

set.seed(4711)
loo_ap_1 <-
  loo_approximate_posterior(
    x = llfun_logistic,
    draws = parameter_draws_laplace,
    data = stan_df_1,
    log_p = log_p,
    log_g = log_g,
    cores = 2
  )
print(loo_ap_1)

The function creates a class, psis_loo_ap that inherits from psis_loo, loo.

Computed from 2000 by 3020 log-likelihood matrix

         Estimate   SE
elpd_loo  -1968.4 15.6
p_loo         3.2  0.2
looic      3936.8 31.2
------
Posterior approximation correction used.
Monte Carlo SE of elpd_loo is 0.0.

Pareto k diagnostic values:
                         Count Pct.    Min. n_eff
(-Inf, 0.5]   (good)     2989  99.0%   1827      
 (0.5, 0.7]   (ok)         31   1.0%   1996      
   (0.7, 1]   (bad)         0   0.0%   <NA>      
   (1, Inf)   (very bad)    0   0.0%   <NA>      

All Pareto k estimates are ok (k < 0.7).
See help('pareto-k-diagnostic') for details.

Combining the posterior approximation method with subsampling

The posterior approximation correction can also be used together with subsampling:

set.seed(4711)
loo_ap_ss_1 <-
  loo_subsample(
    x = llfun_logistic,
    draws = parameter_draws_laplace,
    data = stan_df_1,
    log_p = log_p,
    log_g = log_g,
    observations = 100,
    cores = 2
  )
print(loo_ap_ss_1)
Computed from 2000 by 100 subsampled log-likelihood
values from 3020 total observations.

         Estimate   SE subsampling SE
elpd_loo  -1968.2 15.6            0.4
p_loo         2.9  0.1            0.5
looic      3936.4 31.1            0.8
------
Posterior approximation correction used.
Monte Carlo SE of elpd_loo is 0.0.

Pareto k diagnostic values:
                         Count Pct.    Min. n_eff
(-Inf, 0.5]   (good)     97    97.0%   1971      
 (0.5, 0.7]   (ok)        3     3.0%   1997      
   (0.7, 1]   (bad)       0     0.0%   <NA>      
   (1, Inf)   (very bad)  0     0.0%   <NA>      

All Pareto k estimates are ok (k < 0.7).
See help('pareto-k-diagnostic') for details.

The object created is of class psis_loo_ss, which inherits from the psis_loo_ap class previously described.

Comparing models

To compare this model to an alternative model for the same data we can use the loo_compare() function just as we would if using loo() instead of loo_subsample() or loo_approximate_posterior(). First we’ll fit a second model to the well-switching data, using log(arsenic) instead of arsenic as a predictor:

standata$X[, "arsenic"] <- log(standata$X[, "arsenic"])
fit_2 <- sampling(stan_mod, data = standata) 
parameter_draws_2 <- extract(fit_2)$beta
stan_df_2 <- as.data.frame(standata)

# recompute subsampling loo for first model for demonstration purposes

# compute relative efficiency (this is slow and optional but is recommended to allow 
# for adjusting PSIS effective sample size based on MCMC effective sample size)
r_eff_1 <- relative_eff(
  llfun_logistic,
  log = FALSE, # relative_eff wants likelihood not log-likelihood values
  chain_id = rep(1:4, each = 1000),
  data = stan_df_1,
  draws = parameter_draws_1,
  cores = 2
)

set.seed(4711)
loo_ss_1 <- loo_subsample(
  x = llfun_logistic,
  r_eff = r_eff_1,
  draws = parameter_draws_1,
  data = stan_df_1,
  observations = 200,
  cores = 2
)

# compute subsampling loo for a second model (with log-arsenic)

r_eff_2 <- relative_eff(
  llfun_logistic,
  log = FALSE, # relative_eff wants likelihood not log-likelihood values
  chain_id = rep(1:4, each = 1000),
  data = stan_df_2,
  draws = parameter_draws_2,
  cores = 2
)
loo_ss_2 <- loo_subsample(
  x = llfun_logistic,
  r_eff = r_eff_2, 
  draws = parameter_draws_2,
  data = stan_df_2,
  observations = 200,
  cores = 2
)

print(loo_ss_2)
Computed from 4000 by 100 subsampled log-likelihood
values from 3020 total observations.

         Estimate   SE subsampling SE
elpd_loo  -1952.0 16.2            0.2
p_loo         2.6  0.1            0.3
looic      3903.9 32.4            0.4
------
Monte Carlo SE of elpd_loo is 0.0.

All Pareto k estimates are good (k < 0.5).
See help('pareto-k-diagnostic') for details.

We can now compare the models on LOO using the loo_compare function:

# Compare
comp <- loo_compare(loo_ss_1, loo_ss_2)
print(comp)
Warning: Different subsamples in 'model2' and 'model1'. Naive diff SE is used.

       elpd_diff se_diff subsampling_se_diff
model2  0.0       0.0     0.0               
model1 16.5      22.5     0.4               

This new object comp contains the estimated difference of expected leave-one-out prediction errors between the two models, along with the standard error. As the warning indicates, because different subsamples were used the comparison will not take the correlations between different observations into account. Here we see that the naive SE is 22.5 and we cannot see any difference in performance between the models.

To force subsampling to use the same observations for each of the models we can simply extract the observations used in loo_ss_1 and use them in loo_ss_2 by supplying the loo_ss_1 object to the observations argument.

loo_ss_2 <-
  loo_subsample(
    x = llfun_logistic,
    r_eff = r_eff_2,
    draws = parameter_draws_2,
    data = stan_df_2,
    observations = loo_ss_1,
    cores = 2
  )

We could also supply the subsampling indices using the obs_idx() helper function:

idx <- obs_idx(loo_ss_1)
loo_ss_2 <- loo_subsample(
  x = llfun_logistic,
  r_eff = r_eff_2, 
  draws = parameter_draws_2,
  data = stan_df_2,
  observations = idx,
  cores = 2
)
Simple random sampling with replacement assumed.

This results in a message indicating that we assume these observations to have been sampled with simple random sampling, which is true because we had used the default "diff_srs" estimator for loo_ss_1.

We can now compare the models and estimate the difference based on the same subsampled observations.

comp <- loo_compare(loo_ss_1, loo_ss_2)
print(comp) 
       elpd_diff se_diff subsampling_se_diff
model2  0.0       0.0     0.0               
model1 16.1       4.4     0.1               

First, notice that now the se_diff is now around 4 (as opposed to 20 when using different subsamples). The first column shows the difference in ELPD relative to the model with the largest ELPD. In this case, the difference in elpd and its scale relative to the approximate standard error of the difference) indicates a preference for the second model (model2). Since the subsampling uncertainty is so small in this case it can effectively be ignored. If we need larger subsamples we can simply add samples using the update() method demonstrated earlier.

It is also possible to compare a subsampled loo computation with a full loo object.

# use loo() instead of loo_subsample() to compute full PSIS-LOO for model 2
loo_full_2 <- loo(
  x = llfun_logistic,
  r_eff = r_eff_2,
  draws = parameter_draws_2,
  data = stan_df_2,
  cores = 2
)
loo_compare(loo_ss_1, loo_full_2)
Estimated elpd_diff using observations included in loo calculations for all models.

Because we are comparing a non-subsampled loo calculation to a subsampled calculation we get the message that only the observations that are included in the loo calculations for both model1 and model2 are included in the computations for the comparison.

       elpd_diff se_diff subsampling_se_diff
model2  0.0       0.0     0.0               
model1 16.3       4.4     0.3   

Here we actually see an increase in subsampling_se_diff, but this is due to a technical detail not elaborated here. In general, the difference should be better or negligible.

References

Gelman, A., and Hill, J. (2007). Data Analysis Using Regression and Multilevel Hierarchical Models. Cambridge University Press.

Stan Development Team (2017). The Stan C++ Library, Version 2.17.0. https://mc-stan.org/

Stan Development Team (2018) RStan: the R interface to Stan, Version 2.17.3. https://mc-stan.org/

Magnusson, M., Riis Andersen, M., Jonasson, J. and Vehtari, A. (2020). Leave-One-Out Cross-Validation for Model Comparison in Large Data. Proceedings of the 23rd International Conference on Artificial Intelligence and Statistics (AISTATS), in PMLR 108. arXiv preprint arXiv:2001.00980.

Magnusson, M., Andersen, M., Jonasson, J. & Vehtari, A. (2019). Bayesian leave-one-out cross-validation for large data. Proceedings of the 36th International Conference on Machine Learning, in PMLR 97:4244-4253 online, arXiv preprint arXiv:1904.10679.

Vehtari, A., Gelman, A., and Gabry, J. (2017). Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC. Statistics and Computing. 27(5), 1413–1432. :10.1007/s11222-016-9696-4. online, arXiv preprint arXiv:1507.04544.

Vehtari, A., Simpson, D., Gelman, A., Yao, Y., and Gabry, J. (2019). Pareto smoothed importance sampling. arXiv preprint arXiv:1507.02646.

loo/inst/doc/loo2-non-factorized.R0000644000176200001440000002155414411465465016524 0ustar liggesusersparams <- list(EVAL = TRUE) ## ----SETTINGS-knitr, include=FALSE-------------------------------------------- stopifnot(require(knitr)) opts_chunk$set( comment=NA, eval = if (isTRUE(exists("params"))) params$EVAL else FALSE, dev = "png", dpi = 150, fig.asp = 0.618, fig.width = 5, out.width = "60%", fig.align = "center" ) ## ----more-knitr-ops, include=FALSE-------------------------------------------- knitr::opts_chunk$set( cache=TRUE, message=FALSE, warning=FALSE ) ## ----lpdf, eval=FALSE--------------------------------------------------------- # /** # * Normal log-pdf for spatially lagged responses # * # * @param y Vector of response values. # * @param mu Mean parameter vector. # * @param sigma Positive scalar residual standard deviation. # * @param rho Positive scalar autoregressive parameter. # * @param W Spatial weight matrix. # * # * @return A scalar to be added to the log posterior. # */ # real normal_lagsar_lpdf(vector y, vector mu, real sigma, # real rho, matrix W) { # int N = rows(y); # real inv_sigma2 = 1 / square(sigma); # matrix[N, N] W_tilde = -rho * W; # vector[N] half_pred; # # for (n in 1:N) W_tilde[n,n] += 1; # # half_pred = W_tilde * (y - mdivide_left(W_tilde, mu)); # # return 0.5 * log_determinant(crossprod(W_tilde) * inv_sigma2) - # 0.5 * dot_self(half_pred) * inv_sigma2; # } ## ----setup, cache=FALSE------------------------------------------------------- library("loo") library("brms") library("bayesplot") library("ggplot2") color_scheme_set("brightblue") theme_set(theme_default()) SEED <- 10001 set.seed(SEED) # only sets seed for R (seed for Stan set later) # loads COL.OLD data frame and COL.nb neighbor list data(oldcol, package = "spdep") ## ----data--------------------------------------------------------------------- str(COL.OLD[, c("CRIME", "HOVAL", "INC")]) ## ----fit, results="hide"------------------------------------------------------ fit <- brm( CRIME ~ INC + HOVAL + sar(COL.nb, type = "lag"), data = COL.OLD, data2 = list(COL.nb = COL.nb), chains = 4, seed = SEED ) ## ----plot-lagsar, message=FALSE----------------------------------------------- lagsar <- as.matrix(fit, pars = "lagsar") estimates <- quantile(lagsar, probs = c(0.25, 0.5, 0.75)) mcmc_hist(lagsar) + vline_at(estimates, linetype = 2, size = 1) + ggtitle("lagsar: posterior median and 50% central interval") ## ----approx------------------------------------------------------------------- posterior <- as.data.frame(fit) y <- fit$data$CRIME N <- length(y) S <- nrow(posterior) loglik <- yloo <- sdloo <- matrix(nrow = S, ncol = N) for (s in 1:S) { p <- posterior[s, ] eta <- p$b_Intercept + p$b_INC * fit$data$INC + p$b_HOVAL * fit$data$HOVAL W_tilde <- diag(N) - p$lagsar * spdep::nb2mat(COL.nb) Cinv <- t(W_tilde) %*% W_tilde / p$sigma^2 g <- Cinv %*% (y - solve(W_tilde, eta)) cbar <- diag(Cinv) yloo[s, ] <- y - g / cbar sdloo[s, ] <- sqrt(1 / cbar) loglik[s, ] <- dnorm(y, yloo[s, ], sdloo[s, ], log = TRUE) } # use loo for psis smoothing log_ratios <- -loglik psis_result <- psis(log_ratios) ## ----plot, cache = FALSE------------------------------------------------------ plot(psis_result, label_points = TRUE) ## ----checklast, cache = FALSE------------------------------------------------- yloo_sub <- yloo[S, ] sdloo_sub <- sdloo[S, ] df <- data.frame( y = y, yloo = yloo_sub, ymin = yloo_sub - sdloo_sub * 2, ymax = yloo_sub + sdloo_sub * 2 ) ggplot(data=df, aes(x = y, y = yloo, ymin = ymin, ymax = ymax)) + geom_errorbar( width = 1, color = "skyblue3", position = position_jitter(width = 0.25) ) + geom_abline(color = "gray30", size = 1.2) + geom_point() ## ----psisloo------------------------------------------------------------------ (psis_loo <- loo(loglik)) ## ----fit_dummy, cache = TRUE-------------------------------------------------- # see help("mi", "brms") for details on the mi() usage fit_dummy <- brm( CRIME | mi() ~ INC + HOVAL + sar(COL.nb, type = "lag"), data = COL.OLD, data2 = list(COL.nb = COL.nb), chains = 0 ) ## ----exact-loo-cv, results="hide", message=FALSE, warning=FALSE, cache = TRUE---- S <- 500 res <- vector("list", N) loglik <- matrix(nrow = S, ncol = N) for (i in seq_len(N)) { dat_mi <- COL.OLD dat_mi$CRIME[i] <- NA fit_i <- update(fit_dummy, newdata = dat_mi, # just for vignette chains = 1, iter = S * 2) posterior <- as.data.frame(fit_i) yloo <- sdloo <- rep(NA, S) for (s in seq_len(S)) { p <- posterior[s, ] y_miss_i <- y y_miss_i[i] <- p$Ymi eta <- p$b_Intercept + p$b_INC * fit_i$data$INC + p$b_HOVAL * fit_i$data$HOVAL W_tilde <- diag(N) - p$lagsar * spdep::nb2mat(COL.nb) Cinv <- t(W_tilde) %*% W_tilde / p$sigma^2 g <- Cinv %*% (y_miss_i - solve(W_tilde, eta)) cbar <- diag(Cinv); yloo[s] <- y_miss_i[i] - g[i] / cbar[i] sdloo[s] <- sqrt(1 / cbar[i]) loglik[s, i] <- dnorm(y[i], yloo[s], sdloo[s], log = TRUE) } ypred <- rnorm(S, yloo, sdloo) res[[i]] <- data.frame(y = c(posterior$Ymi, ypred)) res[[i]]$type <- rep(c("pp", "loo"), each = S) res[[i]]$obs <- i } res <- do.call(rbind, res) ## ----yplots, cache = FALSE, fig.width=10, out.width="95%", fig.asp = 0.3------ res_sub <- res[res$obs %in% 1:4, ] ggplot(res_sub, aes(y, fill = type)) + geom_density(alpha = 0.6) + facet_wrap("obs", scales = "fixed", ncol = 4) ## ----loo_exact, cache=FALSE--------------------------------------------------- log_mean_exp <- function(x) { # more stable than log(mean(exp(x))) max_x <- max(x) max_x + log(sum(exp(x - max_x))) - log(length(x)) } exact_elpds <- apply(loglik, 2, log_mean_exp) exact_elpd <- sum(exact_elpds) round(exact_elpd, 1) ## ----compare, fig.height=5---------------------------------------------------- df <- data.frame( approx_elpd = psis_loo$pointwise[, "elpd_loo"], exact_elpd = exact_elpds ) ggplot(df, aes(x = approx_elpd, y = exact_elpd)) + geom_abline(color = "gray30") + geom_point(size = 2) + geom_point(data = df[4, ], size = 3, color = "red3") + xlab("Approximate elpds") + ylab("Exact elpds") + coord_fixed(xlim = c(-16, -3), ylim = c(-16, -3)) ## ----pt4---------------------------------------------------------------------- without_pt_4 <- c( approx = sum(psis_loo$pointwise[-4, "elpd_loo"]), exact = sum(exact_elpds[-4]) ) round(without_pt_4, 1) ## ----brms-stan-code, eval=FALSE----------------------------------------------- # // generated with brms 2.2.0 # functions { # /** # * Normal log-pdf for spatially lagged responses # * # * @param y Vector of response values. # * @param mu Mean parameter vector. # * @param sigma Positive scalar residual standard deviation. # * @param rho Positive scalar autoregressive parameter. # * @param W Spatial weight matrix. # * # * @return A scalar to be added to the log posterior. # */ # real normal_lagsar_lpdf(vector y, vector mu, real sigma, # real rho, matrix W) { # int N = rows(y); # real inv_sigma2 = 1 / square(sigma); # matrix[N, N] W_tilde = -rho * W; # vector[N] half_pred; # for (n in 1:N) W_tilde[n, n] += 1; # half_pred = W_tilde * (y - mdivide_left(W_tilde, mu)); # return 0.5 * log_determinant(crossprod(W_tilde) * inv_sigma2) - # 0.5 * dot_self(half_pred) * inv_sigma2; # } # } # data { # int N; // total number of observations # vector[N] Y; // response variable # int Nmi; // number of missings # int Jmi[Nmi]; // positions of missings # int K; // number of population-level effects # matrix[N, K] X; // population-level design matrix # matrix[N, N] W; // spatial weight matrix # int prior_only; // should the likelihood be ignored? # } # transformed data { # int Kc = K - 1; # matrix[N, K - 1] Xc; // centered version of X # vector[K - 1] means_X; // column means of X before centering # for (i in 2:K) { # means_X[i - 1] = mean(X[, i]); # Xc[, i - 1] = X[, i] - means_X[i - 1]; # } # } # parameters { # vector[Nmi] Ymi; // estimated missings # vector[Kc] b; // population-level effects # real temp_Intercept; // temporary intercept # real sigma; // residual SD # real lagsar; // SAR parameter # } # transformed parameters { # } # model { # vector[N] Yl = Y; # vector[N] mu = Xc * b + temp_Intercept; # Yl[Jmi] = Ymi; # // priors including all constants # target += student_t_lpdf(temp_Intercept | 3, 34, 17); # target += student_t_lpdf(sigma | 3, 0, 17) # - 1 * student_t_lccdf(0 | 3, 0, 17); # // likelihood including all constants # if (!prior_only) { # target += normal_lagsar_lpdf(Yl | mu, sigma, lagsar, W); # } # } # generated quantities { # // actual population-level intercept # real b_Intercept = temp_Intercept - dot_product(means_X, b); # } loo/inst/doc/loo2-with-rstan.R0000644000176200001440000000430514411465510015664 0ustar liggesusersparams <- list(EVAL = TRUE) ## ----SETTINGS-knitr, include=FALSE-------------------------------------------- stopifnot(require(knitr)) opts_chunk$set( comment=NA, eval = if (isTRUE(exists("params"))) params$EVAL else FALSE, dev = "png", dpi = 150, fig.asp = 0.618, fig.width = 5, out.width = "60%", fig.align = "center" ) ## ---- eval=FALSE-------------------------------------------------------------- # library("rstan") # # # Prepare data # url <- "http://stat.columbia.edu/~gelman/arm/examples/arsenic/wells.dat" # wells <- read.table(url) # wells$dist100 <- with(wells, dist / 100) # X <- model.matrix(~ dist100 + arsenic, wells) # standata <- list(y = wells$switch, X = X, N = nrow(X), P = ncol(X)) # # # Fit model # fit_1 <- stan("logistic.stan", data = standata) # print(fit_1, pars = "beta") ## ---- eval=FALSE-------------------------------------------------------------- # library("loo") # # # Extract pointwise log-likelihood # # using merge_chains=FALSE returns an array, which is easier to # # use with relative_eff() # log_lik_1 <- extract_log_lik(fit_1, merge_chains = FALSE) # # # as of loo v2.0.0 we can optionally provide relative effective sample sizes # # when calling loo, which allows for better estimates of the PSIS effective # # sample sizes and Monte Carlo error # r_eff <- relative_eff(exp(log_lik_1), cores = 2) # # # preferably use more than 2 cores (as many cores as possible) # # will use value of 'mc.cores' option if cores is not specified # loo_1 <- loo(log_lik_1, r_eff = r_eff, cores = 2) # print(loo_1) ## ---- eval=FALSE-------------------------------------------------------------- # standata$X[, "arsenic"] <- log(standata$X[, "arsenic"]) # fit_2 <- stan(fit = fit_1, data = standata) # # log_lik_2 <- extract_log_lik(fit_2, merge_chains = FALSE) # r_eff_2 <- relative_eff(exp(log_lik_2)) # loo_2 <- loo(log_lik_2, r_eff = r_eff_2, cores = 2) # print(loo_2) ## ---- eval=FALSE-------------------------------------------------------------- # # Compare # comp <- loo_compare(loo_1, loo_2) ## ---- eval=FALSE-------------------------------------------------------------- # print(comp) # can set simplify=FALSE for more detailed print output loo/inst/doc/loo2-lfo.R0000644000176200001440000002253114411464745014356 0ustar liggesusersparams <- list(EVAL = TRUE) ## ----SETTINGS-knitr, include=FALSE-------------------------------------------- stopifnot(require(knitr)) opts_chunk$set( comment=NA, eval = if (isTRUE(exists("params"))) params$EVAL else FALSE, dev = "png", dpi = 150, fig.asp = 0.618, fig.width = 5, out.width = "60%", fig.align = "center" ) ## ----more-knitr-ops, include=FALSE-------------------------------------------- knitr::opts_chunk$set( cache = TRUE, message = FALSE, warning = FALSE ) ## ----pkgs, cache=FALSE-------------------------------------------------------- library("loo") library("brms") library("bayesplot") library("ggplot2") color_scheme_set("brightblue") theme_set(theme_default()) CHAINS <- 4 SEED <- 5838296 set.seed(SEED) ## ----hurondata---------------------------------------------------------------- N <- length(LakeHuron) df <- data.frame( y = as.numeric(LakeHuron), year = as.numeric(time(LakeHuron)), time = 1:N ) ggplot(df, aes(x = year, y = y)) + geom_point(size = 1) + labs( y = "Water Level (ft)", x = "Year", title = "Water Level in Lake Huron (1875-1972)" ) ## ----fit, results = "hide"---------------------------------------------------- fit <- brm( y ~ ar(time, p = 4), data = df, prior = prior(normal(0, 0.5), class = "ar"), control = list(adapt_delta = 0.99), seed = SEED, chains = CHAINS ) ## ----plotpreds, cache = FALSE------------------------------------------------- preds <- posterior_predict(fit) preds <- cbind( Estimate = colMeans(preds), Q5 = apply(preds, 2, quantile, probs = 0.05), Q95 = apply(preds, 2, quantile, probs = 0.95) ) ggplot(cbind(df, preds), aes(x = year, y = Estimate)) + geom_smooth(aes(ymin = Q5, ymax = Q95), stat = "identity", size = 0.5) + geom_point(aes(y = y)) + labs( y = "Water Level (ft)", x = "Year", title = "Water Level in Lake Huron (1875-1972)", subtitle = "Mean (blue) and 90% predictive intervals (gray) vs. observed data (black)" ) ## ----setL--------------------------------------------------------------------- L <- 20 ## ----loo1sap, cache = FALSE--------------------------------------------------- loo_cv <- loo(log_lik(fit)[, (L + 1):N]) print(loo_cv) ## ----exact_loglik, results="hide"--------------------------------------------- loglik_exact <- matrix(nrow = nsamples(fit), ncol = N) for (i in L:(N - 1)) { past <- 1:i oos <- i + 1 df_past <- df[past, , drop = FALSE] df_oos <- df[c(past, oos), , drop = FALSE] fit_i <- update(fit, newdata = df_past, recompile = FALSE) loglik_exact[, i + 1] <- log_lik(fit_i, newdata = df_oos, oos = oos)[, oos] } ## ----helpers------------------------------------------------------------------ # some helper functions we'll use throughout # more stable than log(sum(exp(x))) log_sum_exp <- function(x) { max_x <- max(x) max_x + log(sum(exp(x - max_x))) } # more stable than log(mean(exp(x))) log_mean_exp <- function(x) { log_sum_exp(x) - log(length(x)) } # compute log of raw importance ratios # sums over observations *not* over posterior samples sum_log_ratios <- function(loglik, ids = NULL) { if (!is.null(ids)) loglik <- loglik[, ids, drop = FALSE] rowSums(loglik) } # for printing comparisons later rbind_print <- function(...) { round(rbind(...), digits = 2) } ## ----exact1sap, cache = FALSE------------------------------------------------- exact_elpds_1sap <- apply(loglik_exact, 2, log_mean_exp) exact_elpd_1sap <- c(ELPD = sum(exact_elpds_1sap[-(1:L)])) rbind_print( "LOO" = loo_cv$estimates["elpd_loo", "Estimate"], "LFO" = exact_elpd_1sap ) ## ----setkthresh--------------------------------------------------------------- k_thres <- 0.7 ## ----refit_loglik, results="hide"--------------------------------------------- approx_elpds_1sap <- rep(NA, N) # initialize the process for i = L past <- 1:L oos <- L + 1 df_past <- df[past, , drop = FALSE] df_oos <- df[c(past, oos), , drop = FALSE] fit_past <- update(fit, newdata = df_past, recompile = FALSE) loglik <- log_lik(fit_past, newdata = df_oos, oos = oos) approx_elpds_1sap[L + 1] <- log_mean_exp(loglik[, oos]) # iterate over i > L i_refit <- L refits <- L ks <- NULL for (i in (L + 1):(N - 1)) { past <- 1:i oos <- i + 1 df_past <- df[past, , drop = FALSE] df_oos <- df[c(past, oos), , drop = FALSE] loglik <- log_lik(fit_past, newdata = df_oos, oos = oos) logratio <- sum_log_ratios(loglik, (i_refit + 1):i) psis_obj <- suppressWarnings(psis(logratio)) k <- pareto_k_values(psis_obj) ks <- c(ks, k) if (k > k_thres) { # refit the model based on the first i observations i_refit <- i refits <- c(refits, i) fit_past <- update(fit_past, newdata = df_past, recompile = FALSE) loglik <- log_lik(fit_past, newdata = df_oos, oos = oos) approx_elpds_1sap[i + 1] <- log_mean_exp(loglik[, oos]) } else { lw <- weights(psis_obj, normalize = TRUE)[, 1] approx_elpds_1sap[i + 1] <- log_sum_exp(lw + loglik[, oos]) } } ## ----plot_ks------------------------------------------------------------------ plot_ks <- function(ks, ids, thres = 0.6) { dat_ks <- data.frame(ks = ks, ids = ids) ggplot(dat_ks, aes(x = ids, y = ks)) + geom_point(aes(color = ks > thres), shape = 3, show.legend = FALSE) + geom_hline(yintercept = thres, linetype = 2, color = "red2") + scale_color_manual(values = c("cornflowerblue", "darkblue")) + labs(x = "Data point", y = "Pareto k") + ylim(-0.5, 1.5) } ## ----refitsummary1sap, cache=FALSE-------------------------------------------- cat("Using threshold ", k_thres, ", model was refit ", length(refits), " times, at observations", refits) plot_ks(ks, (L + 1):(N - 1)) ## ----lfosummary1sap, cache = FALSE-------------------------------------------- approx_elpd_1sap <- sum(approx_elpds_1sap, na.rm = TRUE) rbind_print( "approx LFO" = approx_elpd_1sap, "exact LFO" = exact_elpd_1sap ) ## ----plot1sap, cache = FALSE-------------------------------------------------- dat_elpd <- data.frame( approx_elpd = approx_elpds_1sap, exact_elpd = exact_elpds_1sap ) ggplot(dat_elpd, aes(x = approx_elpd, y = exact_elpd)) + geom_abline(color = "gray30") + geom_point(size = 2) + labs(x = "Approximate ELPDs", y = "Exact ELPDs") ## ----diffs1sap, cache=FALSE--------------------------------------------------- max_diff <- with(dat_elpd, max(abs(approx_elpd - exact_elpd), na.rm = TRUE)) mean_diff <- with(dat_elpd, mean(abs(approx_elpd - exact_elpd), na.rm = TRUE)) rbind_print( "Max diff" = round(max_diff, 2), "Mean diff" = round(mean_diff, 3) ) ## ----exact_loglikm, results="hide"-------------------------------------------- M <- 4 loglikm <- matrix(nrow = nsamples(fit), ncol = N) for (i in L:(N - M)) { past <- 1:i oos <- (i + 1):(i + M) df_past <- df[past, , drop = FALSE] df_oos <- df[c(past, oos), , drop = FALSE] fit_past <- update(fit, newdata = df_past, recompile = FALSE) loglik <- log_lik(fit_past, newdata = df_oos, oos = oos) loglikm[, i + 1] <- rowSums(loglik[, oos]) } ## ----exact4sap, cache = FALSE------------------------------------------------- exact_elpds_4sap <- apply(loglikm, 2, log_mean_exp) (exact_elpd_4sap <- c(ELPD = sum(exact_elpds_4sap, na.rm = TRUE))) ## ----refit_loglikm, results="hide"-------------------------------------------- approx_elpds_4sap <- rep(NA, N) # initialize the process for i = L past <- 1:L oos <- (L + 1):(L + M) df_past <- df[past, , drop = FALSE] df_oos <- df[c(past, oos), , drop = FALSE] fit_past <- update(fit, newdata = df_past, recompile = FALSE) loglik <- log_lik(fit_past, newdata = df_oos, oos = oos) loglikm <- rowSums(loglik[, oos]) approx_elpds_1sap[L + 1] <- log_mean_exp(loglikm) # iterate over i > L i_refit <- L refits <- L ks <- NULL for (i in (L + 1):(N - M)) { past <- 1:i oos <- (i + 1):(i + M) df_past <- df[past, , drop = FALSE] df_oos <- df[c(past, oos), , drop = FALSE] loglik <- log_lik(fit_past, newdata = df_oos, oos = oos) logratio <- sum_log_ratios(loglik, (i_refit + 1):i) psis_obj <- suppressWarnings(psis(logratio)) k <- pareto_k_values(psis_obj) ks <- c(ks, k) if (k > k_thres) { # refit the model based on the first i observations i_refit <- i refits <- c(refits, i) fit_past <- update(fit_past, newdata = df_past, recompile = FALSE) loglik <- log_lik(fit_past, newdata = df_oos, oos = oos) loglikm <- rowSums(loglik[, oos]) approx_elpds_4sap[i + 1] <- log_mean_exp(loglikm) } else { lw <- weights(psis_obj, normalize = TRUE)[, 1] loglikm <- rowSums(loglik[, oos]) approx_elpds_4sap[i + 1] <- log_sum_exp(lw + loglikm) } } ## ----refitsummary4sap, cache = FALSE------------------------------------------ cat("Using threshold ", k_thres, ", model was refit ", length(refits), " times, at observations", refits) plot_ks(ks, (L + 1):(N - M)) ## ----lfosummary4sap, cache = FALSE-------------------------------------------- approx_elpd_4sap <- sum(approx_elpds_4sap, na.rm = TRUE) rbind_print( "Approx LFO" = approx_elpd_4sap, "Exact LFO" = exact_elpd_4sap ) ## ----plot4sap, cache = FALSE-------------------------------------------------- dat_elpd_4sap <- data.frame( approx_elpd = approx_elpds_4sap, exact_elpd = exact_elpds_4sap ) ggplot(dat_elpd_4sap, aes(x = approx_elpd, y = exact_elpd)) + geom_abline(color = "gray30") + geom_point(size = 2) + labs(x = "Approximate ELPDs", y = "Exact ELPDs") ## ----sessioninfo-------------------------------------------------------------- sessionInfo() loo/inst/CITATION0000644000176200001440000000263714411130104013152 0ustar liggesusersyear <- sub("-.*", "", meta$Date) note <- sprintf("R package version %s", meta$Version) authors <- do.call(c, lapply(meta$Author, as.person)) authors <- grep("\\[cre|\\[aut", authors, value = TRUE) bibentry(bibtype = "Misc", title = "loo: Efficient leave-one-out cross-validation and WAIC for Bayesian models", author = authors, year = year, note = note, url = "https://mc-stan.org/loo/", header = "To cite the loo R package:" ) bibentry(bibtype = "Article", title = "Practical Bayesian model evaluation using leave-one-out cross-validation and WAIC", author = c(person("Aki", "Vehtari"), person("Andrew", "Gelman"), person("Jonah", "Gabry")), year = "2017", journal = "Statistics and Computing", volume = 27, issue = 5, pages = "1413--1432", doi = "10.1007/s11222-016-9696-4", header = "To cite the loo paper:" ) bibentry(bibtype = "Article", title = "Using stacking to average Bayesian predictive distributions", author = c(person("Yuling", "Yao"), person("Aki", "Vehtari"), person("Daniel", "Simpson"), person("Andrew", "Gelman")), year = "2017", journal = "Bayesian Analysis", doi = "10.1214/17-BA1091", header = "To cite the stacking paper:" )