From c20a1ed465d485cf0bb437f51b2c7694113ba123 Mon Sep 17 00:00:00 2001 From: Eric Coissac Date: Wed, 20 May 2026 12:37:25 +0200 Subject: [PATCH] perf: optimize k-mer pipeline with compile-time tables This commit shifts entropy and lookup table generation to compile time via a new build script, eliminating runtime overhead. It replaces heap-allocated queues in rolling statistics with a stack-allocated, const-generic ring buffer for cache-friendly operations, and implements `size_hint` on `SuperKmerIter` for efficient iterator consumption. Additionally, it establishes the baseline profile configuration and sets global k-mer parameters. --- obikmer 2026-05-20 12.35 profile.json.gz | Bin 0 -> 125640 bytes src/obikmer/src/cmd/superkmer.rs | 5 +- src/obikseq/src/kmer.rs | 2 +- src/obiskbuilder/build.rs | 145 +++++++++ src/obiskbuilder/src/entropy_table.rs | 191 ++++------- src/obiskbuilder/src/iter.rs | 6 + src/obiskbuilder/src/rolling_stat.rs | 384 +++++++++++++++-------- 7 files changed, 472 insertions(+), 261 deletions(-) create mode 100644 obikmer 2026-05-20 12.35 profile.json.gz create mode 100644 src/obiskbuilder/build.rs diff --git a/obikmer 2026-05-20 12.35 profile.json.gz b/obikmer 2026-05-20 12.35 profile.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..57da44bdc7815dc238c960d5edf1ef2fe4a439a5 GIT binary patch literal 125640 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%0A8U)2y1=nmE1yw;N2zF{L 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

eZ&(YlGT_SyqrQzT+W+8Fs@?psw6Jf8Af)T`$ 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 z zN(6=g6An*684&dk;f@is0-FeufK5RC%vb^4Gf}7ONka|a#I1%1CWe>x{AF-BVK||; zMYus3uE7O)LSYf4^Xo_FkE8*+(V1ifL;gBBn+zC}12B;wV8BEwyx#wK_)UF!FW5;7 z34Yuv8dVCyTU-vFB7qD5_HqhJ5KyobqC1b50o)^?c_0P_{5curz#Bk#_I{XPyXSoCMhknZ5V%+FJHY&gNk#S{bA z-VJx$ohx_{V|EOr^a0T(ZGo=NX3I!xCMze4s@({wSFVU@jE)L)NPqxsgtbCUZoDbS)tmAT0p0M!m%Tmsu63hrtTaFKh7Fwa0C}6T>y==qZUbE{6ntJGM?+ zjtJKw`UHpPto=FJHTXHSH~FqT#6s)ZC@M4aAVBgUO1<@~Do7f@ads=&f1^7ko<}00 zq!mqbLT)viTw8fxINm&Czrx(}v;RdrvmU zYkSxo+{$ybaxCb)7;ftY%LP{=2cYhgmoZ*sJC>;2a7JkBu(sJ z5xoLiKgIGecc47Sh&`m0{BdmrIq5-iw%+nirZUGkq@R*3nrY3etU0Z{DE&-}3A^>U zcB+udoJ#N&s7TtevnI!(g6SI`)#5aSK>RY*S}ap{Gj4fMj-9_dC+z&B`D|PKogHEv zx52R!bDi;nQj6OUk58A=tB`?gqylW_E1p^MfM}6&5?c7P<%x?ER3L}c>Dy66Z9-K3Yjm@ zSsiPbwT&oJ${IyUz@g(j+J39$(%c!xqs~S~*QHK>@i!`2v7QiRcJP~E}O45mLCDgwswNv(=p!7#Ebj}iAuPH~AaAgnLO+cs+t=3VW zPaLJ*l)d;yt4i)ZUkDC0!&rGk$*D8&726?WmqHqIzwD`J0Whf|D>h=U0ZtJj^`}1m z4yknR53`u*T^O1A+IroDXv3kY`xRPz=ep=^(ef#)AHxz=WFr@{t%o-Te%q>PU4`El zeWLgT0wW`dh9S@T+l-@bte|c{F#)v_^|cb{(lnRSi&Xt}W8i9cRZqqTvySzfpbr$| z%1a%idgIg;U9w;Y^kJWkR7o%>Z?Mlcm9fQH;4;VINP^tC8;+1!xQyuJ&sm?pT4po9; zs;?(0pJTSTrYDO;$Rg?e=L7xc$5F;m3_pvliBRTKnz;w2)}R@*t)Kv86~&Q`^|elm z8jEgBsDpNVU;JTXYTaMegK;UvY!W&U#Mqe5Rr;?k03qO-AXR_;SosB;a@hYU3#xUh zuWdiYv-ol&^%1)C*M-5vFB1o2fIKj)NT>+(!C#qqHIm30Sx`8aE-OpWKxjXZ48uEc zVCf2K-Y7!HFh26jDi6Ul@6e6wnXYwXKsTWiZrWG#dWw>sU`qcSHM;ab4X}=IIbc#P zR8DO+yeabPF)mS_P$f0b_#ZfI3Ew-TxqXye*NofKs|g{Va_eQ|W99!IU<2;Z$3E?U z_OHc7+y;CgK#3t3sZ~x4phM&RAt*AC%2G_wN3Tmq(BjRO3pLa8jNb~_iDm5cJ#ww! z;`75Hbkty!Thh}VB-Bq8CiU)ljjq%L^h5`-W#vMPgWz$*Z zzV27|)N%uT+uNTOc>xS)U5^VbqdL1d)3(kg|9W4%R=Bt*W3PEU=gv_Tb?2(=! zN>!JJ!INjC`h&VLH$fW;KZ=!Sz!Hq*PAq}EN3a5S|A=%;>nMv^F=OtTDa)IICD9Zi z68>B)hqmL10!*_kZjJouy6K7xIrjwyf@7ak0Yi4kzA52C4wYPTI*VxD)$N^e%~^R| zeEN``fNO*(e(aoCqezO~HjHW!$JURHbIYcV;Bh(($`Q}TQ6Etenky;lz*$`B_u4LRZ1LVBYx%6vp z_f*8FYwwIb+KoLy!0C-Gu;owBcJJPq=x}_N{0sZgPV>!@wZg113&e9FgU`*-baz;p zmB~D}f!RWJsi-N1QHMyAWV)ln97uc+DnhIQq#*+Sgcf4@$gDMKMBfLiH@*CxBikBW zKODR?6R3ZUCxS`^zyP@m4y622{=C2eyN0rewpR?EDsuJAMDS;K@Ke5%C%_A$iP(u{$^_NvAi(zf zcw`B%5>yWDS0bOq>}E#%ijWKW&VGNUkv-ocu%}GHEH<1|$5W7szMhu4L_KBL)yp(X z1Y5D_y=zPlkRgDB@ys;FSRE<)iy24q`^8I23i1So0U}IMRJ{QHBYKTA`KRGc1gHn2 zvEktoq4P!dSFAalE|i_MiY&Hpb~Z7H9qMv30h!IVs5Nr^nIZ_taPHmoeM8gYAGl$< zsvQKLs_mq&@zEm`jgKPOgmIoj_$o=cNYvOGS$11uu9x@Fd-KvwW)GW1&xb-jBy?;% z7I^Desnm5jK-l#qLs7B##o^(JME8u2=I3hanuHLl1*#cpez~V&(iZRh?9B^Rd(C|f zH_cTutal`57)Ll~lzH=uxxST^GaLFUBJ0xIqBGT5bi88jZsKHCVjOm9>dR(&mXGXd z!d{1P!gp4daAG9Q@4h|sJV%pHN9!G`9*&F#|7arS;;eXcx|-4rQR^^0F_!xR*($eh ztXhZN)FKn=XxQF5WSLRS`9vOEaBkI>d?1fuD} z@+OkW8uods1BQWJ;EXcdCsa$RY3pK)|2yi5yd{xo>p0p}KE-G;Lg5pJgHciiSF)Ud zaLj3pii?UYml|7H20nQ}I44%|Ei6-H)C@n>c=pc_5Rv%Pz1jSyi+*J3lK5$B#^_C ztAxsF45iWy;4J<_50+bUz3-1cf`!O9DsD3V=<@;nz}fz4K&?}ON8rDSI=$XAGY~ld zw1D}B-#il}7WYItu2cLfhjgy`gIM4bjW_7d?U}oS1asl4xFfpM_3=o5gakH@!kJKf zf!vSzxkvTsfUn#}g0uF`k=gP9FX!)@Y*x1B?Qk-D9{z{?U=G^8w)a-ELcM5L9Vb@s zlxnAPHIHT~3!i>qVg!>eujX=5S{`={FvzEuHbKV&R|hf6YU{0gs&ku0ko=Db=C}hLDZrWwDj#3TEiN6vEh3Fcsw; z@k196#G$POgAY&io1Ik#AWWLpn_9LgJ+&|aJuaE;?`jt_-5vGPv!6DU!D1~23p8$Y zgm=%VW*C)U<8m*n4kqWF2NM-o;-pzz*6-vADE=(1W1J z@LueE(Ca?!>$ft|CgZ0fbihL8mYPxI9g2sUsWclNG3szAm49(WrZ^hL&&e&gmko;j zDf!re!aE%no#u!GdaU5Fj?RAzi>(>Ee%ItPVkJY7r*|vqhIRvp(XQSNt-J`y;INvp zG7X#OueDhxgFW^q?})`Y=x>+7yIr$d%AHD zsi1_bks{bKp8a=dEfNDXtQ(IFNPz4-F6F<$V_yWH(uWF#dVyX5f@dbd%X70jctRNB z80{qTZufRBmeZCS%O$%$19UAkw~P3WpXgu2W{d+8l)B2zKKhedxw3!&IrbLouDKdN z8}zL~EsVl*sl9L5Ob3eP(`K3Q;9oLpc;s#1Si$n%o_Yrvd*tbRE9})Vpu~w#8fXX0*0N2Ch9ANxP@H1_@3eR!^)xinupUHmD_rxp{ z&(tu=580GqyBI5KI>RHqKjHe;?QCX!(GM0GC?o=QD#65<{mwJ9&#eq@J5PO?A>rG+ z9Hqf1-kh0ipQd z3H1VLgs|PZ5>QDPLOQ1V}8uy+4tq%a+|Je5*{G`*12qO;o1hp+b zy_t&c0iJ!(V#QPDz~Dbsdj<7@@vyWU+REW6aS1H<4zz&Cf#cR%nOBm$6yV8qa_id& zC>{@$3p;foPSkQQHd68R=BK|HfF-#j*be@LF{9(ah!^s9d)YLH;=$!9D`EVB?`Ktx zrRRHxm+8q#W!Z4;&^zGy0lM|I=gW%f$L@!B&h*5~rz4zye_;d{C#F5p!Cgj|- z(BPFm`a?5kPJw+3d|9=ObvA0hTAeu|m&YAa-pM({llSY+KYxS$hqiyc6T?od3|1E4 z8GYV_(GBqZs`3AV{s(?2_B|(ob%cnXzt2qt%qVqD#NRspJG1_INAl3*nKga`VmcMS z0K-k2^;;Lh|5<)USn&WWCa2q6;6j|V%OIr z3kX^KPv=ZrwSkf+xa0fFEm&-Gg$N{v4epiKX?HWTu-d`SE)QgrEjkYa*^#)K)jIi=2je`_~ezcRNEM!&vN z%ER^YQ{4C9eMG{s1ytz|#pvc62}SF6dvztW{dR&>z*8#!Q)NjE6R|YSPMxOPslMvw z5lz=fjk%vf6pYI@c7|;jf>nHyo+U`8}trVH7(CAfOBOn=~htfpy9b$OI?m7 zX}60i1+OKf%N=v+Nu!a~ec|A#l2DzNQ3{K#9UE`1P+xvF%aZ2)Hon$?zx#wHmu8XZ zaQ~zEC2Y)-OjZzCp@_sZjC<*lh+{}7OPthPZ?(r53RYDgLP?~!{Yc(OTi*K~PI?qI z1fo|zc5ph&0A^7eu4ck#2`&d1a)>7tPU#f}zmR=(+BAZPPuGzezYdTU!8&-IT&^1F z$*0ye1Y^#D#W3(5Rk~&9`4XXB4KlHIEQ#{AX(aW-mFSWMWMQ_UG1mk9U1BVE%NIkW zfoJ?_RTdR6KLf}JCk(R#_#23dA33?1%QpsI@8q=|19xP{Y9l;f#n*YXd`H2MFihUm z1;6ypZYg?yKz@3ET%`y8{NnqF>5h#DXhM`02h{>K{47{HYEVt^O|tk;4nsE*tiWw8 zuhIevc-3vdgc5K6-<_I1rR;*qeJBI3? zJf><@=tRBF2esYlDOc#gwa%sQWlKD_D=wphwGQp*WO5qja=WK$zb{pqKz#RW#*#UH1lPZ*m_ zIImdZ^mr)gM$|CDe%G<2FN?s(MGYr33@n_H`70n9{`LMaC{?i{0Ih>QRR+MVQ`*4B zf4vusRW}NuQ&vvaJ=J6~u$pP6FzReigrBE{#4mq%`d0B}cJF6;IF~ULdkSI5eK_tw zf4+q83-T^(mCSkScrC%I8JOyT)wmeeihkYoy!)Hz%@ZX4-+Zb3gD}C(1$i`#tOSb) zK{<>cA&CEbB18v-Y(734eflB_ALsw=0-|bO{l}ErvConNwa=duAl}turt-f*W%=az zebR~dd&dc*!7iGxJM_2t37pXq#?o7Qk0X`1cjvZ2$Fyens7+FgE;h72A{||q`LTJ70Sju0? z_a_aZhr|Vzu8Nm_mIjnL5CV2HkJH1Q|7A7-CO~Ka1A#Jsgz@&`)7J2AGpvHQ=)xj_>CU)X~^!v4XBsosRtI1li8 z$rzxjqY?O5R{hB@@J^$-v{=?Py~EYSR!yQOElxg!n{OWMEB=3xjkE^=a{cbf;;f(G zENHr$6|{qdd`2IyJ19|=-7`H3o*+2%{xOS5|C;vNIz)a(3`EgPLU{E53ko`s-wkT; z8JDG~_2KyV8FB1oPZq?tT$O~)syWSsMtVtpwa9?lGR?yI{ex2UlA4=p#>JEYY$zRg zfhJO^jMu|QXy}VIzxACpSMf*D69C5*$Ql90KYrZO0(1UDgT>sezigIif#hGwlBWpkgN`Uu){4hV705R zP&QZ*;u76qU|$t~>vAM1wq^Tft>MJ=zk&-yAC)r#tF#j4^JN!RQw>)l12ge!A+YIE z1ekAgVeG%T5@?Fg99XQ_M|4Y8M~9~sI~wM^6YH;Q19A>DH+EGSIP-yf%9)H=8WMm9 zqdmH`)W3TMom{x2L5W`j5HbYY28UwfzV{dTy+I`Z%qa=_daEh+uwu z+60kB$I1y1^`IMsVHgG`f6WI`{hm4Q&ufhrrGDVHN-$V`#E-*}5jugB{Uc=SqoWUh znDG7_D35Cc=$j-H9#RWUHXalWt}hxSs}pC(jqneDGQ=8)p3y%dGCHFIyWuV^+!$B= zW}o55Bd^cb)4UF8T3@?8+W13_O4jJRyl*+UGbOb?TOs_W<>QNsStj4@!4DIf?LX@U z-@iPXa1N#)0&4s$f_y9uD*fGV$sk|6>k1Jgjc9_C4s&d-n>k*t<`-iAvU6;h#d}eNp;|w; zWlNHlS_&K{FK}EvI6b>uv1pkVSLDbXoXDq_u@{VW!~?u4wg6!G|`bI<;~Jt({dp z>{L=FL%Bki7^y$f)%TqPDxc%O3kjO*#{Bxc!9EXFeJv&U(Syjyhcb_1cKUi`h05c~ zDIyrk8$0D1Z24POGt4~j#;%|^KCb4jJ2C_kY+pGr|1WVQP%REeART;D(;JCs#?SIE z9Q+uy*zUb?0yly)+;cofieW?7w@`D>wu0E@H>#baFZbV}R!s2q0jcn^JloN}JjC`ycKXWy+XT%q`Vo~E=;Ke8^ZbKi`cvOfA&V~Zx zp0Y?jt7qHw95~un)ys94qI}}SC2up%XsZQXBa_Jd^V@LNY5hy_re3X#P^}AB>c&W* zOQN@oEVY>iSdTd~zX^N!I2qh20xvdfRnkZ-`uU)FDIEsJcrqQJ1{(snzU$|wfFWO7 z#2OiO0R0OolG5zo))}JbLqEym3OGgwqipMAl zaZ4!V@%2-g9dy)<6duoOgWJGHVf~mN{=2^ibRqNwH=KBRM^bsdK0HtjE`m^gWW}5D z0N5Zqq_fvsX`)AX2zq4teGrk%(2pP$faG>%sPp1yV9Y_!!4|mE0N7dj*F)e; z=k6g4*T5WsS4l8EDF-$L+{{=j8%V6`3lI9EABJySL3F*FOT^#%{TsQz+y}-*$O}E} zQ~2Aa>C`RbE;;a6WA2S7SP&D$Qr+tSO&y|4D4n_?0{!& zN8#kVGFyzvkVhBNNPl+j{pxq4?E7 zLvTyGgkb%cN^-~9-*3J}j^9rP8#;C-MIcS^{R9Ufx@Y`@ur_Pb?b|Y+BP=EE{vIB$(n5amsf$ceEEqpZ)cD!t;Y^H*r zbnqB}Y`t%$ayh#rxETMOm9jQInR}K8&w1gjY_Pw9pE~Ns#(ijL{bT5xJi34{9#JL> zPkzz)Grgqtr>Rr>H0qbuw{9*hD-?I>?=bv#l9{M2>d#SO=r5pX*!zr#D|7umt)HtB zuzj_>YzL%KEpIly<^v$Zz z)4hM>!)^OTr$E#Rm&|&&*c<`D8y>XA0Ne06iU+&>EnW&}PE_*Trr_AykiUFqR7t#I zP)H`K!YY>92p6)&yq`S)o~*>!#8S)S3aXwj-SXO49`?0rd)z*J4;6p+^p#nCXLX76 z{!`pkA$J5~7&pWOIt@B^?(TV5kFPzcZ+4sO_$(rCJE)VAJ6=)MEc7yfV@edf>?ati z#a|AIgc$cLb%{ol{7Ny8nlthqSe#4@yJSm8m%Epxmt$YsLdh?cGnBeo8r&jj>lN(?iW=;kbWT z5*)H8*m}DkP81p0OfJIfe!mWEp}K9ZbCy_PORKR?#39yQe9dy=EBHdo%=NCT_?Ir{ zMRt)Vt}=R(y7o#eX8!>&aBxjVGr zV_dXz%Omh&v{`Iv)nqv{CGbYyyef9fzgIp5H{NAzCAnd}$Bfi!bpVUJ!mbZK9%>rL{LwbDYT2-ru2 zX2)V=HXmVLAT1{OW(vHc96U6>K@(t&=#~qJ^JOhfa21SwfE}+!wdEuq2fn2%o@0@l z&@PG}j+`($=*f;K{FEbxZyH+Ip{)Lyr;mG;oxyD%k$l7Lif7k;&xa{}?MXgW8-f&q z+$K2EyM@joG#hG9*Z(5_ihKAj)^xS93I4JpG@D=%2SR$1Z;o}*2T3=XRrg`pRT0yY zz2pu)RE`_Xz&0N6{m6b&#n%K^#E?4)Ho*h=TvJ&&i?cqw8r1oS>(-mo;;0YM7 z{z6aH%NH+*4e@M4pb5@f@_JR;9{wW_NC0Ax5uJ#_hh$~s!OYdF81;geYx5cA>KE{rx$5OYow{2GSO9v+&_ zXkX846PWA(A_YDLBH?TBdMd-)r56wqlh$>1JVqw{-)C^^JwyDHf!cgKSxI?dnALC4 z5ic;JD&xn&pxg;r348c#MIf^GQ4!sNWV&@l4Bw;o7Z7xpZ+0OfR!q7OMU6kp?5dZT zI&8LUxnCDm%}WoGU%q*$_|QsVG2Xnagk7xU3mfdCrbvMmS6L3cOh07Nt88e(YyFw+ zhcgeLaU9iGF^u-TUtCAd+0!9TdDagz+4sHz-6STn*b$Uv)=h9_e1})r=XUrozDS8R zIR6Tng~qTwY+he`x5R!Rg&mPQB6>c-!E};ui6*zdR7=^k=#iY=5dQ$FXYcL3_L=sM zl0zvwRx?0NZZO`6tv-|V>2s>_Qfs}>t9RF#mTZ2S1Ek&;;3q6C!itFr!) zeQxpWrjjX8%!K&;vRgIIGGJTJyPo@***;r>>uwwK_G}Ye6(h4a)P<1q@~xT!pG=)5 zvp5jUW%&0PH^D*sXC3FFE4!WL_Okm|p3B(x)>e~;JlJ7JZWsINo}J7}&XcjH`_TQe zYVJq2{C>70m=fYju>wx69B5Oo?$GR)$OD0wzY^YKhC;KKGu^89V!Z?=R%3aCm=|;t zyy9iz`RBUrev>yZjG4aMblXBi+MSob2~4x^l~Z5YEww{Rr<^#jX=g33VS@%?RJ5qU zuxi#6!Hy7NmQ;y-<}Kl!InQ8kfp76cp0~Fse8G-*BY35lwfe#UXWE7zvi|AUPJ~|- z__@kg{APQ%rK>WG?JZKP)}ODuFdUCG>kwL4Retj{Wq#1h{6#d=MC-s5Za1p&hV-O~ z1G1-ZuOt##U zXF$|a`3Xs-^3P4IxGx1E+gU;+DXKqK7hjR}{ORE#t!(;@!RQ#X+-Oro^>}#8%375J zy($7`Kh@M5d!jSuCDK&}=c$Srmw8#WI$Po(vi! zB1lmYQ0X8bUAiJgKnOho(t9rRMuqtoHl zO}H_UBacw*dUZ>*8JXm&!w`i?TN=DN3H81Aj$pZmRD~oZ?y3ntQ-#ZH+t&+91&kG& zKdC?f-PwM$H5pu`n|lwA2z2mukitT}ivCYi8pAIL8gq{5(^Abg0;|LLfrH%JEtv^tV?R(^VD~d6~dyEuc z0BIq^hk;s(YyAUneo*xf)PA7sA9!X&`NxLO@RF&}_1yQm!1Z07vu@AwfU3NdW!8Ug zjVL=Nfxi9tT6>lc13>GN&5we=qn>`YV*Y1b5A9FR#zJ=L4R@tNoA4mBxxZmWR8z;4 zEh3cFoaU@(NrPTSsYZ4FTaE;@gtdfSu__}f{|Svn7-iW1g=({uaP>h8oIXXiA_2YuN(L=l-SR$&-W&4(k660&P=j@mI!@ zYw?eQ43Pz+Wyk%%oo4^}3K9f|6XX;eifPKdQBj^N5oG6ikD+<$d-BckYwokP9=b`w z&2q_%%crBSjG@Bsfi$jGD7Vm-O9I`>B{RL!UKX6;ZH!KrYM~8&!Zv$#EZM12>#6)b zs!4)-=fYfhdlYAZnTMiz3q{QZMD|Vf5W~zpsKiTv%Zo12)8Q?&4zHD+nNG)@k?ABd zPt!OaC&8AbcSbY-ToyRro;&@>1=t1RI}lB`wZqk?MUrM>_Pf!K(%~*gH=q|C)Pb<> z4E+}qil_)aqw@a*4x^O}E<(~WVE!x5|060eNUi`#1s19Q$^_EJ4SS(C`*_!FH3$U= ziCyywg5UfUxxm5Wba;`Gdzs7exEk~eXCf*pJt?UOkO~x`=-XRR1BBH7bIx)}fbw*B zExuT4lJMGi!*fd4lgb~ni*lU$-Ci)1 zOGcNoyEMLLk2bh5Z4+x4?X#oNG8={1hC!Do9KcAym&g-J2X!_e>o`pnu0H>A7PEV2 zMEdFfuKQz;)-5B~+@ZbA<*h1c`85~qy^J3KdH)LipR1fe!$$Wnod3wA-bnRKUgZU+ z-Cm#d%}Ik>NH*tqL&woC_5KRKm|e);PvHM11E9{q{g-oTxj0cf>@b+g4uv<$WU<`? zneZ-cT(=pn`_0~`=sMSaZEyx0#1=1Q2_2Tf!es56LFWY+j7p$M4if&JqIK(E zo##z*8h4%$v4OSrLN6fHk>>%M!S(kF5o~=YP7~&*Wq|>w8vZ{#@T;m!68fiCTeL%+ z^&K(W4m0|N<0L>;T9<~%5djFpdwAe(i7k>_Dw}JF43Qm7upO?uRa1A(|1Tyjau$~^ zurUU1JB4UAs>fAZTm=Svv2lXf49ol@V4D`>$l`1I;vQE?;3E!zk37MAgouWhM(zhi`T!&&pxbR6r zPEb~`wMVI(c=7M{Wq|#N_`4wFxNGYkrP9jXewP;IT#WCJi9F^}t~;I|nWq=eSxq67HGZTlNrb#E9pxK3TljF%U??4e8y5 z|FvSkDYW_v&hCW)$s_S!zw^(kLi?XQb@dEW!F-V`dqz z^^UyFI{&QVnNmdF1D)YeY!ASspdq`mB~+SkXLKd6I~J|O?M$lQ{^XQ1k^vmEq^J>@ zy?Qs{!Wm#w57#}b{o7stW_r;cY=47W zV!DNc;;9wnG@;;BD)@oFGMcQ|Ldz}sC0C|K?v(BSLHN&A-?IWmz~%SYc}po3Tzc#j zXsBQtu_qipCW0xzR9pD^pT#jr%2}JcAlBK(1@8IgJ$79k{f9AhJZ9>X!;w(U4y7@;`A87_RgPh%5iG-o6ij%8~-6pIs{oG(PyV zyf{}b+u~6|3Miqv$+lwDCvX}-UNqR{hReV-X78;p4bsP1g;B7%zR<;vQCw+e!S?N3 zEndq(F0y1VvFKybBdNmNo4cK3BCgmDsNn8desCn^3SP{ma6rGu&^OYLCD-8rK#MG3 zH77qSoSBbz^SvcCu8m2}Eq(4*xeU34z&W*bbD#AUWkfF2v1x4F@vG6tp_IVpP7qk5 zP&!o1eRT}siuKY=&vORP*eL3qJv!S)3AKrtCl#sbW#<7;&UX%eC1y6?sO-mD9Sfp*VvAQDrLCp&Ws()f2AK-nvSUV`P4G~;JnqmpyO zw>0mWmss>r{rgZV)#yE6=fp=ijzdxdIXcz^dORBis!lZ9dsQJOx>vN1RsJ zlbq^OgBkFC+QEO;>)(|FW{NG>ACp{pfcpWLllRsWbU`T#iZ1_9iB9JEmVl7_}f!i{H+b(a$Q zqrG@m?)KmhT}SCF9(%kk8g_^0-090C-KYG|3b1VtWJ=coDiU+1Wrk_dibuhx36SK_ z?|?-K@l&>3k)tNzc~tmkZimFf1%g+Bmm;87|HJiJA4>7>2N?HN6zN}W#C>AQE4g#l z(s=F0xD;G#xuIFk!+k&Y5x%0cL0@JBpI>2WVQrQH0@D)fxwYb}JhgcvhJT;Ya$r3%UdMzqGvN+U6 zo{3?~#DhvnL^(q*uzF`^$PJ5N0yGamp}{iyX@M}-)_7GS#Zm^?GXPS?!KGdhGpJyv zKii?|y6ev~f&OoRu{_CJ=aS%m>=J0EJmptp<;^k#_C(2z{N(Yh#1nOfp$&#L4L=}q z5&KCuGJwQ{cFTb+4p;9Q@*)|x!$FFp8x>1)3$4a&Ga~2lE=qY~rV1^#?0^Rt zO9t=)>{>zC*PnX!YiHjRxA@Jf!&JERLHjg-(T^slo`QdS1(#V`9ac&KkpwQrQ%1fb6P>lG}Su!1OA)RGn(!G zCK3QCK))}!`;ghIfB8g7UAdA0rv&nePm=_@d!UIfEmqK(cmT#j2{J(NJd;Qqpovb9 zvT`~XAjH;u7QYYrXO11NmS_cN8nK18?r+bLF8~?AW$5J&%a3BLfP4GjwMFZ?6NCWl zVAU|<+KQ#b05P6gRB=dUJa;#mR<>Zl*$HxO<@~93GFkw9Hs}WRo!zb61K~@g|1nXB z=#151Sqch>QG9yBox` zz>evc3rqBUUqxkc9Q|=RltUIo=D70+c+X8F-_Agfnh9XI#g>xW+7UGsZSf97eL{sEgp38}9SD7rbJUgQZY`$T9vBy3?YNuI z5ZUwI5D-3q!SI1$&0kFbSOY}%-+=7YgOUFAfD#KM?+qzuuX4o$nwUOXL3f&*p8B-^ z$WtC+IcddS2{lS>{#qoNqOU-H_ph|&5jbjl^P#O%?!DzPry=IwHJEw_7|_Sa7I_5x z)`zlsHEjw!V*E`J1NrIlR4YU0n`y0)Q`42!B$Bb+7{{rJiG}DanMn-hezh&#= zbgW#n;z$z*5Q5K&My^G+`E*6vxR|-PIRx0>R~wm7Cszlym_|Zz0>Cc4TtVA_K#z`d z-Vko?+k08wr@K2I`b}_Vw`5O4ZsGE^NmM{lzyU?FXLnZs=SwiH6XePmGw`%ScY1+Z za^2bVo{)8e)TQ!F5=b0)Ckg(C;4>0?*+AvEi(aqJZb%UDujb2ZU(!M-0x;y|$P39I zVK3$iEPVwC&tJrroYlQMZQwiq_)jT-`(7n-T_BFc3Xo6i&4V@`q&)VbgWq;(3jZBp zw^4aqThbwrUqm2ol?_inI(64m<^q6Ryy8^OpOOaLvF*D%|_|YDY>PiL~ zDS|f)6z(8V!}T6B^l+xlgiO6A%GY|R77y}^uEpPT2gt0&+q#uluE8}+jr}~sJ(k`9 z$px@}`|ZC2Hr!4hOU@{}S9u&$Y2-(=u$%uKVD%vFv`a`6%HRf&XaR(uKgF|ab#+WC zg`}db*dA`V3tL_7r-w#2yC-d=CN+Vgm z7UOK9Gw`T2Mg90EM>#Ue5UZaxi)W3#K^!noZ|{Gz*y{-2t?H(mB-FRRRjx=Ofi||k zy$W>nIi$$$Bt@VP%b?iPrjI~cZr-NtTMwPl`yC*EN+hs2*T;>OYv!6G!Y;>^9CO*) zH5H%Qie@+Hyw|)Igt5YL545}YiSw!X@n_bwQ_B8T+EXcwO^o6*hsS+T7(S=Nao%c` ztOawJ*b)l3xZqI3mKy9AwEHg`)DBeDuYce#jvAkV%MQF35Oe^qb@(7)zI3rC=Sq;z zFytl3{-08-v}f0A-yU@n>Z{%=hh4p|1N5F?)B1s5=J_sT1$kdacLsne08=-C#QtBP znQn6G?oT@${t~tL;@KKCdhB;Va6FllCPtj>oE%|^cw4NhIn{FWI1W5 zIYFQHz)K&4PY7!#`_d;vCwq=3cr3B+M7Q#D@_bqhDmwK?|8{-}Pl;y9930wr0Sp=p z-EKyVmeT#KobOWDKezpgDHPOb?bO$J{*SQO+WQ_yM&RF~rEUJ`{zm!CF^D%u$@y2F9*JR3$^RKG{xjqBe5i1!jFOIeOmVC^fTf;w? z+g6+Dye}I>MPGZAc0ok*X{j=S*`1B?2c>G6ySO(^smyff1ZSG%&JZGg2bH3-Q+o6& zs@R;OAbbCHC;YP2GVeQs2oO?t;PE5rZ;?aZ8<%SARdIQCb*-kI$OroJg=62Y1Vt~e z_HOEoF!qCe9^`K>QQI^G8>o&o)bA`O?GZ_u${rWXFURB!hAotgzB@+BmD%>GF_sqI z&Sj9fTm7W56NP$oS7c|wXrNbs`L*>%$+lMnDB$OKnk?J0*bg|d7t^_OAv*r``$yv{ zCIu3BTMu-5#UmQqT=@}@El(jSwALMzfxQ6z^Pd`W1O9D`tlk$Y-N-RJGNGno}g#=TFpK1=a@#9_e2$k1s8 z8;<#$R`c58SzM;lMqA&;AiFKx%2Oe_hcmPJ_AB}TlDld>dU42~_LmEKyKXVD(0;m} zIXYX^gt%c&@Loa%DY5xMN^HWjv{=eM^riAbN@UV{pdJcg&Tk8AA7BQ(+VhnK6rPZX zm!p3b^SsqpeW+~nWmH7?;(rzo(=T)&D<#OGU39DL>kjd9u z{I%IgA?`uG+bgAc)r-h$)bL$~IRD&sU!k!#+&Pt5{?f176so!~BF?KZDB9dl%3L}n z<@$Nn-@yHLmB$*{j-w(`W`(~*nWQ7Xx^GUu(vL2BtXNs8h$xTJr64|B!m!&>e#p|9 zt&%t0`KVjUtMTRC8-qJ$x`!q)Vg@maLOEMJ`ilB(-Z^~M5mD0g_fy@nh`Q4*LtKKOuV>*Nbjs7sbkJ^*W@PE{*t%fPA0*)Uec z<+7NOIB30aPq9~1V^Q_|gG6JjGOr{towJgj(x)WW9q^U%6)7e$NmW@a(4!ZPu-&H#w!+ir&XUo$|RlTKmf`)#7jDf{b*?i^U}rSr!Lf9ag_;`C|m3D=W+5~?-R z74klhdFntRw-?mkLwymzf zADCl65RAPM@WHsxwe6h##&wsntFd|_Dc9?{!zD~KJ~Q{`Hd$R12~`fV@eR@@iwkM~ zF-(%DW9?$)eoejhT$>HHTUC@fTkyc{^Upx7wNcygYx-6{ZYOFUBVT=V*gUs={gc*E zHifwD-VMz^yuse-%{B{s=GM7j{f9xBR;jI{BCL&Sh14CjPSu|@6)}ikUQp4fa=b1lkedbi&)c#iqg}=-7Xl@nb(29}p1leD5m(9E9=G3EwZ4%3 zro+0vfn%X>I55s?$j&}4LBzH?`&Zv(^`4V{QSoWyrNac*vTfjBlD~u7-Oc@3P-`AP zmwsA44C;G|3^nVEc{gKWPj^YK@TkmKX&E!_rJroh6`@s>q}kNw5&_A#^w$ZbU6=hR z)~`1^HDMeRn#Wx<;9>Pw}`qqaUTL#NC;YZPWkgx{0=aj`hxZ|zJ-FZx2m!S=D!O-N_#?wxv#oY?AVe1++ctcp=% zFA+3cG6ZAnl7I8jqr?^uL+p1sf_W6tBGO;+WGq7kQq0w!AXqPf#fFSLd6H7W?h2D= z?!(RBb=$M+7E!JGJkZd2WwbbZe*i9J^uwESE`I8LUsH!-xO0uQY_eeK3w&>IW=MqE zp>W7b?;=Flw67*k!ge$-$l5GQ-H?9Ge>BfkKZVbu`Q7hVSt}c`xXAAn>bXU_%O0NH z%6*R=%><*5wkZ+NVH!uOH7>iaLzT_g5-pbMA3~%)HraG)qYU)zwSh?45T_)w^}FYY zSArMXJ0V8%7Cv8XeLm6~9E7-5PQARnPFa-w{xfyCQF3Pty@QK+LnHfz`*}^T=Mfxy z2hOfFB{FvoO)G_;$h>6L9zcXVf#%I^+o@^~D_2^kM~mG2skO!5))yJKg_#LKI)(KN zm_#dcng<4qlb8pla^I>HD4}k1RHvC=frZL0l=HDzG|zpDN$kUDI}5$l7HDZ-zr-@U z)%n;g)p$sFUo$$Oi#OZUW$dPu${yHNSW+fho@Xv}CgMn0>jt>l>@h3*h{-jd&{TfC zh6f5AF4o62(It*VV1@>u-62j%19Q8BHH=U9sg2Iw`0I z!`187>WU$69eCdq!C%;CGmpt-^J^reuknMPzC4c+_WB$+G+m>Wjv^@6T2#C=!}%tL zNnUyLt&o-!+EYD>>Q_(xk=8PNuOi>NVOVA9)JI1_pFzVIT zx55d9ukgml0!EPwfr65y2Lg+Rth|rQvvtcpWA)z^+TIYgH}e{8PrYm@igsRVPtvnE zZbG|rv+_pRn%aOv-C_B+Lqz*g{h~>$mfmmfPY97dC4c9$qc^_%&G0P`4_8?wqPWcio8?=Yt#kBN7zlf0o{ODL|4X?j=?K7FACsSkMpKe@(dWuwjw5(JmA>I%rk6 z+B!EKMuS|5o0KkH@?2@M%=Jm>%ZlYbENOjRGNClH>72i&r6m~jcyKBFK3D7@jN=K- zSQMTZhNof*Ip!J(nn7lYv;TWl=5fU+XEf()405SZOfK`N(eb;<%UL-dC1^ z^;uanv$%XK+#hOHWEO3zQN|OUXSJoMB1+5elQSdtf2QnVcI?e9)l^@5`f+zUtBkm< z$GEb%30-dL@iVE7k>l8SbUggc+~mvVOg%TZGzV+sN!rSeaw@(L_mT~zu4Xy{4}bH# z#eS?X+h9snyqNu^<<6XFbFOW$(13Ej0cdSxNl^?E^mN*7l{Vg*Bjo_9rgCe%#)91> zL=MA?>4`Bwc8)IR`EZ|DE@dzfy}RaI7R;o6(=FV;ZNsBj61A)|Vr#)YvYsA9mm7JR ziOl<#x>ZQIBG(nwm;LjmwpV6)c?3M1l&+-I4QkpUb&`csSm303v6R^BjvC2hU2e9R z5~q-Px2<@KRR7qKYnT#>#y|_pdsTnBt%ZyZ{6=GfqUx16$6X6-g`Ze5SUU7HCl^># zW*#J$a}`&{`j57scwF6<2`j$i#<@>rO9pQCmiXMt&z$;bxN9Hj_08-GL0@j61QTkc z!>TxYRfM(7GKf6s;`UIv_Tbgxr{r{XHreKv=Z>7is(ElzgM1NlJ7(JR_fL#>pK5Tz zy6e~yq+*K@5pO-M+9b2f*+sDYO#D^JL|^h_Ny|RhihEf(v-`c3qoCYN)3 zKmP7y=lg7e3oqnu-q;aukUh?U8p43(^gv4ST;~;QEuvHc}2uY3#}y zM->Y{Sx!7*d6sT|o=5wn)pS!S0!EccR_wDxY*?3ONYim_b8Uoze|d4PvXMbj%Z;5i z#Je2nLv-hnH&Zd0JY^g$4@{TWAo)9dCu!r=Waz*O(U-;#gCx7vUk_aq)=drAN<;6= zNp3;y9nHAkBSkaJxo_0)B>UdtEn70WZq>+<6yzYS6^;BQ9WZ>KWYINO%k}p6p+IS_ zmn*u3>#2&Hoc`;SupggwxRhS@ed(}Dr|qIk`cCraRspipNOVe>Y$$)2-Jtz^=wk%U zb|lueuKx4S;Np| zlS~6YhX(ga?0pve&fRE}uB@(_294?S^Jxtf%Aw`0x)9xh8^xovtZ}=H3bIF)Y0}x* zs&Dp` z=Yi{>dzrD?rXz~bEuRBxn+(o z=K8@xY~PEw#LD`rs^^itzA>)zf6Rhr{{hs?yvE%_ zrks8QQ6C%q2+nWj@eyS?e_rdlem&fIMN}0(QD$Pry4h$Zn)7Fwf_v1cdrBmRY0;7G zroZ5}{9Ggj@L_bwp|ExZf%5ZD#dF=JeX~jlh*fbPlIQ$0S<6h_P9y~`M$q)Q!}b)`ge-Y>>h`LYlB1%6!hif0uek3((rS|G}nFVf5cqF#9R6J zKjlxLS$V?`J`A^L$V#_^v(*hEl(FaU=Wh$%KF0(5AsugOyZ30#Rat!KQC>8YAcFOo zh7v{{95eOwf}mUa_|iOW6enX7Ltg1%Kd&?byYV%o>|F@l+O#~_(`j~N!mOaMf5=%i zrlLHiyWyt8tv51VbRmBB%sbx?6cYSDaDYzuvO~`$6;+3Kr_WS?{_uccS{|W8VyeZC zwwQX0Q`W5sr( z#P8Ow|6Sv|jkmB>9SwgZA^cX>8_0&mPR#csoY(P?Cf4|kamPYmehh>M6)+gHd(&V@ zb{DRYE>+BNe8a>E;;i570eV7HHrGk~>jt zK+3&+aD~%1Pnz&PCLi3Vw;Q?qgK4HZ_xDC{E4PzHQz5~Duu7AaPpv13c*6@4oj<*5JfKF-CgZ#y;pz<} ziSS~_$H9@Ww#bRT@JbHyh~Xa<^5ron6C{!a(7h0Ko>*27U$CdhCdBk8<^^eBWy$q*uG%6n-4bW-dgs?aE6*o$|Jj=oRWIK~al);L)q!NBN)J z{?4@OEM8MlV~?qb)f~*@A$f~?eXg-Ei@A@m^7DhoemTp8(xg(O9WTt0)a+Ojk>>nk zMVzqou%9j0Gh=FdA2q`o%#1kfFZa8?{8u`$tNM>f-mw9lu8k7I&`L?yR)BJ zJ1r5@6EroYduei8rL^dQkg^!_>ACATBRWI@_9f5B)psXMJIBsiwR+H`RB`F#dl%Z9 zf)lTY3wa_N9J2%_;x{C(yXL1$HaJ{cr=oKgeM{viIfg*5A4W}YZaM;Sb9I-rSk|pBSQVlXw=})XH4bLpW^#XG`BZS#{CqSl_++=twNSb6XjIJ8Js)ad zUi`VzXn6N-4{*ZI;YS=J+v_b{?bpTFq=jJesxHcrNGpfc3gf5Sn}=a$ccbWk{(iFa z#L2uM$1GTo?vw0py?zVa0AM&^+Jz5PUrWGPk=wzP;gwa)tVxJQIq&hMs&n~Rje z^C4Sm$Cl$_aJhjjE_} zvWLJk^;UTL!Jve-U;?T30d2h0`<*`EA9F+>y5Ye;WdYyTL^ACghI{oikjB_e{y=w# zk9DJPFam{LiMi&6eZTBlC1ae1#LnF-T?IMyho4k{LlL{{YGZ;pg_G(fAz(kSGirS@0{Nng|iJ@eR1G(5pNipa&A3r3GAPwDa~d2_y}L0ayyOwB0qLjGZ|up z*H@ZwC4fzNmW4i9vqH~#A&si(M}=awL>@0Ud#$id(Ae_DnyNo&yZ8*PxK$w*x4FX* zWV^Gr=d>)zDtNP~D@=k~{^zO$_18lryQ5&duABkQuIR^cV!ff*QTURS$B>9K6!Y2{ z{`*^reF%{ooJ4WH=y}_NdhaITPFzwDZSh&v&?pp^XFT=gO_tCIK1HEuPs?H zyq$_%iS_w0U6ps1G=hY6_nQCUJbCW!^vH5G*PL!U*A zo*#BXZ`+-4uGAMzkwu-b7m#2K(!_FKt{Mqn9O^Zy#ON z0k5I0n_u`L&bfX)G4nd|@f&4=YjQY{{Alcc*SEQZS#gPViUde6EPp+f4Wu%zq_NgagT#`~fU0LT{9NUpS!K;HF4V#& zB7PGlFZqKr+#J|zvM9u}Fj)%)-3ykr8)f~Tfg_(|!MA)?%Tg3^d#E9|8D?+W{8jl% z@S4VQgmq&E*Os=i1&4&0Qn~uw00b`|kD*=Lr_8n(E!9KG{O?=r zy{>B@+K!?5*}3Ec+qh|(IrmrNJr1~1$(+RQbxDH>P8rL5exvs5I~#*-SDvtj+ZF_Z z8GJ(WquciiF7I8o)N7CGBjvH!-L_iw_Tm|?6=8mVsC9QKM09C#_!%w0c0Apr*}nequ*pBsyZo6CH7Z zdFu&{m#>7BO-+|zWV2vuGl#e2cZO>7^}QZ%y~^l6GsnIwv%8Uyqou_yiMv>FBYtte zMTx!-M{#{B5(4TRYb}B&Er;GX*8RqBl~^9$dy-y<84Xe4Askup)Hcc%S(3CRdG5G7BGa1V z82JT<+EYZCOiwy)7k6=*cN}`pf8O6NxzXzD4O73j<&oTKhJt*0Egob`O>zE`!tK*#ozEw}9KeXk=v!IO_Pk-I{+CtgP#Lf$DT z=?RxT81YZ+_u>_4vk|Po^ij?h38mkW@B5V%zs)19OUL7`)rgvH1d`rER%X>Hj0#8o zG-;sK@^Nwmj%vgMw(E;m-uD^b2+4-K?B%gNR&&&Y%pdB&j@`0EBW_Bq;RGAmV$pgX zC)14HzQXVJ_WJ~j(aIBBF(sCYBgDP!m{wfwR(uq^&zI&TLj8Rc2Ms{l{amzQ6`Dm7 z3`zHML*1I1KC%w}Aq|7I3vIV9t`{oxrt+$}?#wv*WHD75Ke8BNM;D76OY!QKU^#w& zBOkC8s_3{Ni~b|iZjvjg)h#BibrJveS<2jngYmvrw(UOL(ACKnT=mQ{&RS9BxRC~u zhE?MX>Xulm4aGV$6kL#V%n5?+NN7<*PfB`epfQ;X+~Pf5vfB#6X>mad-k%cXSt2-J z_8jgXj^f6_p9~ei4;~(@Y$q2iaHyqb*5Cq;U*HxbIePm_4+}Hn?|qQ|ecdmXoIpoL zG$3ZOBqEdw!9?-nT%0t|fx$Gp| zPH=x|#X%crrw0UMPmQlq@!Q=-iSOiYId*^t4gSCxwWayGS^QBcI7`?sNCL((vU3;2 zM9kSLHL^r1-JQ6y4ue_z7K6BD#M6bk+AiCNKGe@4P7d?kZuF}+K61R0Beim3Cbp4L))_6^| z)J9C@a%3NEKFwkD2|dS5Vcq1~yI^VAJiq>5C(k5Njnl9=*vj~alZ?o9>K8;k3s?V? z;?PAPkup9Pd?|I+=%ZGDUr~OJyy+5Ne-GQ-yRwnwzTdk%ia=fTCwFm zNnTv>L_6BJDsVBGtW)EZ34c>DoHJ6WXvAOU#e8k!*F@3pz=8LcRm>IY1`_t?8$-#0RC!vJD0I z_MUtoj=^gnYK{}QG{3Vw_|@L@+LNg&EbFpA| zUG{I_M-NdJQYnkoNdLn{67n_2s?E;hmB&3~9ea&#c=WGkcx);vTiCCGYhoWKm1^Wk zQpp0mclevn>TR^Sm9$_zHq{Az=vzLN9Nc*wS^-;%Gw zedCHnsf?eHj9*pg2iXwzWN{oK!)2{?j(Kr5dEpqHBptV5M861|-d<%j#Awe$&=!v? z#aWF+9Up#b)vo4RhoH66eMGr_(=3r??NR@GJ$ZpKk9Hd+IgELr0PZ<>^Qz4 zNbRKfMNgK9xNQu4>OmIU%Es4tlDBz^_#0X5cy7$@FjsRXO~kqerCfQe%Wz25sSJ`u zSr0Pn5s0(gTCT^kXTT z11rxHb+QN}YTq~&XOwKgSW5x&IKK_GRjOhvnqp^7e&%G#gm^D=GCSwu$+tTPWk%DY zEo+|xQnDGwZoi$U9*f_eST-;wXF48Tj8j;TtbV_Sizp}X9<=Z5ba3w#P!CV#@zjBm}@ zdX+cDiO<`8Gx60}`K^z8^P|lvANQayUH1m|zY^EMh_c?52E}yo(WywUgy)uf9lCqw z!#-8Fn3ChjYii6EcV)>?BDRMl5dTcoa4S)@pGvQmh?<#P>zzj zH1J@}Uo|n2c?vh-%9#tM`P}e#`$ALlj5F0Xo%-a6hxHX&`1^Gchl6kK#{)SZbyBom zdeXxVP+Q5N^IxdY&nfWNJ{(`6IXY(rfv!(oSAUt}34BMBA+OJd8D~)$oXFY*i~8=? z$eWJeB1ki%Z1=svu?(Q>u4bzGZRxhCZ{BDod%lWgp4d&7 z{9s=0+}!uuRoye`Xo^kUN|iSQPq$pmNGCFlr!3A=DQmxxFq3U!hb5qG8GEI)AYba> zt4c@56vu0suL|O4i&tH$pttA5w>DUbZ5?08L-TXo8}ezgIOJilqM!6wES9j?w|WTz zWd}~T@IIQwJ;OvE-ceEil~J8GZu}Eno=%0ERq)nqJCKsp-8_a~bs(fJrn81b$B+wf zFAwmRt#nWYjAdTf&3*O3=KGk>Q#1|D3qe(-Vu3=#Sk(JZM~5wM=5=S%7D>t*B{>xcAPovYei{1{6W-GVc? zY33&VeP1Sy^j#l~07AXZt-+zID!&O%xVRz56N~7SOIM+$-sUQ2q<4QEA|Gu-6EI&%+RJMs~?d zu22@EjB!Dpl$GK*4|v$28vNyEyT|%|YRob>$vl}Z3UcyHseFxd+Di~rl zi12=PG}bwXw_PpDM}Rm}%3e9`u4yl$bn+QDzoosoj#uhh^ThRjLc&X>)p zhM?WfGb2c4`!9i^8#3`A{F1AB^j^8bR{jLFw5Jx<&HCki(#^Z0i+JtL-Gl8;Dio5E zag$UGhoIugK$ckya(Jq#uN$U}?@!wAdZBHRLoo-5>OPTVzQ)VM7BtIbyL!#hQ6H}~ z5y5hT0~7J>jxgKFC@nS7x&Id!p(DR0apA+4yK?7WViyp{HN+uwH~QeXAb(?Ff2i`X z>0J_hF*e-;+iAZ@4W-xx#X*)Glr*uQ&9U*C>&k_E8s3@5z8#Rtd{&qu+B^Ihzo6rj z2OTT*WojL(_bEfJ_l6Uzdd9EqcTR2DMGUQ`d&^pihY`ZFkG7Y65}DePl~*qwdnCH0 zc9J(4F9?PDv8=m)ns)$mK+(TB#T~?v%d63{-g}O#{iEZ~e4dG(&6y(O)n@D2PJ+eT z4#3M#jq4`F0<+TyhBmA7#2CKZ&tbhgE>GusPllc)W=)LA?K(IVL`rWRa=sd8_KjYV z)W@pNd?I>|x_RP{qwtNJDD^6{n&2SgF8o*~@aw-`h($dprnX&5>^D(1LOe^q@ld%c z>9R2zWlG>I@u_q093zf%{30Dl_5-U-(At2W=zXjKbvjP&{kpR{|7MHQ{C7FNrFHa^L2MI|Jz6jZeGqR8}*avGUjBEL!WG03j6?DyI%Y2NpH7EE=Kk6`CA zJ#S5^J+pkESG9YY3OBzSc zAwKdh@#<00KjIH6Q}SZ_HWV@WP@{_Nt_{ER+w*lb_3;ttVa&eI#Y9iO3UUr3`q{Q0 zysD{4WrOo?L?-roJ;x^sI}#R04wE>i))XAj(VWLR#Dl~uHOkmKnZ;`3C{}pkoSM9d zEaBP@i$PsB-^|fA1c*iiC1H7eNAdzTd{H)i?O`Fvq(bs2Y0LRyA=%O#vk5K-eBR#U zNr8kD`e~K%3OlaRcOr~1&>^7^B%-*WJrD9Rbl#b(Hlp5aWDNi8tFW&ftf&YU8Ya~+ zR&f0j${7!*n2Nb2_3M!N%SzW)1fOMx|p7Ij!#g-LZ~2_eCmHVkCQ}Z%Sji9whFsp&C;vANG6Ka{z2m*aGbeF zq!|KkZ(IR!`{L>2kJ>+vI@($zZqA(S&7=@#PK|Wx|7D;5Z|nVETK)DmNqzUXz<$yz zH;zl!wtU+jWhc7){|5o5XoqTuo9GhBsAPVITE*Y=iRUfr*qjtn7?;-}Yjqqx+Ltf+ z2Tk64;B>9#^Lf)hW~Tl(*AreZ-Xvq24AD%zbyTEtWXH|K#3+ngBpGD0Lsx!o)&(v2 zQuWN7O!R?-^*>xh|MW4=NdJ~CoZeh;^B_#x3^B^4ReNoe@vg#>uu$XB1}*xsT7h+F zV}os@+6?_y6oJ-G$T$CTnGYiiEZ{_e{E=MQD~eKu*pKo$5;AJj!F!$=*^yEicgKI^ zD%d^dmq{;~q1e&?Ku6jYMaj&Cke3EoC;F&fxZHpD2A@6y3*s4aPIyCL%w@jrLK-vE z+|`{vSNK&Xb=6x=T>-9F=$ohJpyzSR9Z#tZe^2_8(n%m~L$XuGGV8eSOh4KK)dpSV z(Rb=0Z%~NmI+D8hFdSAV^I8tvM1t=YTUWY2A>;8XxjuD0wdLDKOXJH5&3&bj>Ffd3 z@|Q@WRI=rxZ*kD6{GsTF+TFjiUp!d^Ce9-K{la-VP9S2*O8##fSU6o336o)UFE5b! zysxKhd^j`D31MJPdJ68o!|(^qvq=y<~3bU`z~J0x!ze_>h*x; zLc+GZQj(hE$G6aOF3#vf^DnfJ2+0%9*KPUaJq_}vaLpl}Pkoa{Q!l+U<(4&)tZH2= zt_M5S_i&Xwijp#;8GL-g_UmQpn$@<<;-FGJ_oViH)pWINs#2yP+`z+=(a`G24{4+k zploI{2raNd^rZ2U>xGmJ*YjYCJ<~e6X6!v>I$!wMYlR2(GesZ9?*0joH@@KW#&H$} zyjoxaI5kPbUu67!gWT}S+nmzSuj}A#8rv_)&sDfZ)P#jqrX@BgV<&yThq!OBf9)}d^FO2ZCk;T=)0$Z+^_t5`35huAzJDj0ltP$mr^=)}); zD7&EP>*$xn_f0e-%CX{;dC-IL$;V+0q8?4rNpjEu=!88=Vq~ElgXS>ho~Kj1X{9Ab zM6eVJ4YpFrkST1e?&B#ZqG+NpU4a;g#rorHp=uhjtQWB|hRQ3o{?)(K@?k5)^OBHi zdphCe(}`#38y7{wn?QUb&N5jdW3b0>TW(Da0U5+(!VA-$`E3}CYy$CO^|@0aiZOTSao& z_2!id-pd<3?zM3WP}(7%IXblu|CkBLTr)Y_?_1|$LlYfGR@sRSRKixt(T*g@Nr_a= zC(H+9UDlr}@8BMPRhvdAq_iPHPXDG$LvDxSG}^IlXHF~L)yY8LzHhJc(!^^|t2UeT zwn%AaKKI;yhJ$_o&n3iK(^!8X?ed`q&N^sckqMcWSJr0NiZViL1(I0Wv+&DBCYhJ} z@Jbc8H|=I{Mq6&(hvrhBvT3VUmnkJgIoXgTi9*T))eaU_>1)zSUQ;Ni&IP268pJ|V z_?9XMs(=)8=x_>ZaF$is!aR)82_FSV0(;&}EyK1>hu;{r7c~di-73aK8OE=e&(N)N z4QT&2!mA7%zNaem%7-2#OkG`JoKzz&REK66t3FV-QItF{b%nas!l1ET&X!?KsXfdi z$>Ztc)2O*1ecbc@&7&$0+a!?smT|2q#W5X$7iLYib~BW(nBKIYSR}w*_BxWMg(W*f z(4X4;>7Lw-<0f5EvEg6v@g;#vGR~=v8;k`zcNpx*$w?$J5Uqgp7f(P=PE zjB@20+#k~eV6Mn3&9AtDB9%B8=B7lv@3Qi)l?05M&f~Ll7sb*Hn+dJzxbgUATpwx@ zmNxtFd-Ad>{s+upwq7P$(C!B{ z6C1BPRk;`v0 zDf78DB$BbzlhrP=T-a89BMrq++AmG7ws#VeJnSB#S*<>zn5gylOdHCR+vjy^wQ*ZrJIlsfsK%wAkT`yWic6-M7%C4 zorm}c7w)K4n=b*uCRSvwws5^#UBV;%K?e0V-MXirD5?JpxIq4RcQOHZQ|9!6-N=Rm zOzcx7kqTy@l$v~BpJQ|*C1H-nZVP}D7p%mF`G>ocA)XUz5_%vzfadfq!(jG&-Ca!N zxEaxZ+O?3Vn}Sv@$2~KCWw3g%D|Pi zQZUQem^>mfX8jlhpmB1sX^qqJ6aRG4LauA&+Dw)}u8HX(UmIR5={&3dS?%bAT3U5c zo!);wOi*41uihsF#pjnaG&Edy)ZUf>S@42QSwInUS+F<>^t5G310YjdfVgTR?RlI# zvJ4FVM&c2jurH6F=%;R9n2q=8BXw_lVu&s#EvnFNTL|0g#}&7Rx<{Lr3xlPFa%20& zcREF(Uw2rvxXoQekuNUlYfBNDkrk1l47JgpS-rSKZzvy6V14z_huXd?zI;XPRYxuWwSV zG-Trg{u}M36te;)0}6*j$g>!72=RkHz?7Qyug5pVNeRH-)^W1Ylm^}c?M>0Phuq+t zKyzb-eZ?cj5hN;;X1E4U1iTIirbqgTMw07rd~1|Q{|!5MM&h}61h`b8mL5q=k?@wt zY6&YbyUyPQ{HBOp#Fv3YXX!QH)Bt{NG_=PLJ51mnaUxhz-8JfB?6vY6xU$N@7z0x~mnHh{=JfPFJX&%Gf3_UN_P(T;> zb;T5LF6g!C@IDo_n(z~dHNzk}iQVweZLc~=>SfQX>mZp%Q`@H<#e%WUF zaQAXdM*DIn7+W?jBFFUI{*7_|-7u%4tCebf%Hjl)PF#)*rK}zvRTAx5R5Y15>%-oM zDPQcYJCq7QM+J27^8hHOBy{p@oXy~t%Lo}~T#?nVIl<^qy#l_}cX7FeB1$Y(S`Vaw z>G3j!{?g45;LvW-?(~)sY}x1@+%+}d3k}xDHA!}H0;gt`cRbx3$^l+S`lm?d@fi@n z*-33{hd^-@ z^a5Bugc64&axB8&Wyhg0k#9dRS3>Vf36ElG(0clgy?TY4^#P^T3ap<7ItV=;T(df> zhblIq*GX3R!l_Xz3}x<|ffjKM&iJgZ#;4q5PGv>LH18IqA85(-GG+-@n{-Y{RCdq!yU2IKnp8=-$e?FT_gu`C*~BgXm=FwLT~A%pF(UCOz>Bmd&qORUw1 z7NscRmn1YDAb>GX_0I`CTNO}s)wB87l!dlXQ*>gHEO~d>$3W96w1AJR-n%cIh+DyP z>s4G3F*P?!xckFRHM-SgUw_JsLpxI!BfYX=JMV>xX`Bei^-Doa_=Pw^L%8vP>~enp zSB59_yPJ|1YTND*nIue%q?dREJ!YJZ-~z@T=N?^8Ov1mcd^lswoM`e+YHN3rPpo)$ zCTk?66nthvTtPC+>x3z7e;T7~rlk_-c-jw#nlC*>Whe6k5#%V7wK8xQ`R*$;w`vHQ~+NvZi&XWyS&YHIP zenNd%#Sc#V)MQRC$@$jB4}&mdpJ(UNGCR!uiTz)3o20)p+bf|553SqO{#FuN!?tAb z?%>bCD`*QcnD$GBn{J{z^!j9a7Lew29v;ixOxv9VBS6MKGz-4UbN`U_;K>#Q}C2f(9fy?T!Ff$TZ zbq+(K%8}Q`l!-S97WZwWUy=^{cw$NohG|^Qi9gIMp)=(DA=G2`u;XL_%Q5k?`IAPat)+cVi_(p117J`vgjYwb+dKTMQQ>UtZcI$#>d!vlGw56_)ln zSy?;AB2MHReFC3jApwY_udXq0t$AZwWv$;x^HqeQqxqEap(cj#kweV35h_(Hvuvq( zeX5R*gM==U?8FjOSxE?hSz^j#CNbqc3h`1H(rYS8g4C4wtLi)i6vQ0rI1x1)6{p)U_hz@gY5{ofzaQx+AFv+FG9AK(`>IW%9nRDsdhF*P+djw0t zwDhdMB~B=rfxag$Iuu-`2Q#iWbPx-*hXn=Pur`QrEue4L5-*8X>4wcdh86}isKDxj zzZeM|R=8A%B;Ld=0~q_Y9ZF)9xl8iGbCpMSTJ8&VKc^2~wNO*eBMaF|^ep-Q7Np?l zJ28n<{m0y$C*CIo`FlJM!uPIN>JhoH1X#RC6{1-sgB#B7{6tHN*ZYzr11*L)wXM}Q zJ2mO?K5h&;T^D4myC8NjFpf)~*o8xmDIk*Yep9l@1@2JvLoj$@sC}DELzv(X3==jH zc-^e7zxTLp+|?z$ff50ZF=pZX8&sbcCY|-W!qdyUkm0RNgWnLr@(PS=#*d< zYr{6af1+~iCyQjH(Tc*VMrm8}C7mhKi{1AL-h!XMUkIkJ)n`@w_^|x7sl^udMIrv^ zxfD44N|H4}cFgM?!C4XZ#<}kuJKZy0zBFs<40O-=Q_Z`-QDT2*1l@ww93^TN3UlDr za9$?W%ICTKdu$>MJS>x?PU-r3$GW?lXjhu&7A*qU+lXBIyeDxV84Lxg&&q&N6Ovw& zk^A>FqFZQLx(x1dO5Z2sSNHytf?Y9`DQ2r2i6yQ-tf|2u*sDiF&p;YY^x=lACAI zN;eJ3OD>)7#4=tHF7xB?W%O@MBAo}ab>{F35q08FLrE~l$S&h5O!p6EzgJo^enVBC zR}R+IR(v>&Uienvfb@#o9+hXG4)fW7h~w1vz3!dC9>jy*k~7R7s@^1(Qxck3@l!#z zl0(c}3VgtXUhdJA0|Tl%FctDFIb^85;(=M{yW+Jw@+Q zBKU*s=`K3f$`1w=eYe-0jPFTKH+@PI*+a&BN$Q%lW2;DT*NMAURg(=_Xc zT4qphfv0CF{~fFmEp&0P89#)%XgZ=?6NvTsOFuDlrq6mzB)r|vcrrxRP!tN$v?Y}+ zm9y4Y-fzw73JrCm7d;bq%4G$kv51AMs-%###={)u_e_RuO>O;7_ds{vThoSLMD4+E zPKa>7F5e2<{69qZWm+HPO=_=^ep?L5y{+)RKc%$8M zm=ZGI^02c$W(Wx5x7^qhUHfk^yNs-W_Qehy!EnpamhF7TN~(NnDJCdPWMsng?qkP2 zrKgMX4U~p)fEk5Hsdxy=WE{fsSdrL)iQ)2SuM_CYwf|2);IPG{B+%@h>Bw6~CC#&^ zfpcE0UnqFhzYVe`2YpA~t3Aj<$y3EeE~S0JlBD4mmPNlr&Zy!dw}ad6l#z_XDpn2D zDY5H-HwG}GlB$J8cE^~NE?3PbDyB>?DnG*-dk2Eul$&hf@baUF0`JGss+4H+a-!mG ze0_1CQ1zHB{&EO~$LHaA@ifq5$KK95zJe*wx%s0rij`pITs|nXFyW8T<51NXg}{)x zC#HS^aZ)h_^K5RiCrJfJ<8kLcnm+~~dCDeb)312TU1r?Hf@M24IFjvyCbRsbimB%n zWy=vk|A^kQs-9yU(&m#oo$g2%oGwc8#yh=*BDUIbU;6%bKGYjpD3(VP;1Bw<#-R=bKJo zJ1`nw52}imG@hO-RGnU#)U}gI`%m3s8+^S+$O~Cq3x+u+HLAT<_`}q)qKB`OaH$bz zoqR6+WiQHmEF1`z;83VE-@XG`YWtP=9Ps?I%wYI*W1k*2muV^lT{U{6EC=!(yuE|C zhSXeH^Z*j$^;D9K9g=nxE+w4Y6-3FTnw@vsSp`$^x)v9c!RKX}TWD@Zt%@M)Du6*r zs-ZwdK)Qw4chOUU;*na7v3E^;FM|&A7+COc+-ip*IMxyNaN=0#Z z;D|Nz0@H*k>yvyf;*HV|rQ=Mw3+cYx6xDatAyQb)4P}_>a`i3|G@dTPn&SXZyS4$e zh8FG&sWUSnpNJ{T>2Ogdy%4M>=%$3l0e!~@!1%Uu6ij|f%-Mi^9&R}SPBZ=^=7#XJXpV$28r% zAk=0OSQjU9>x;|Xvxx`?mQdCMKS<^U&X*NQj!3-Hp&=xiqiRy+S?ZZ!jWAkIUF_Cz zDk&v8DqO$P*>R;vrS#N%$;lT%&zJMhGrM_ganGxiT&Yx1Q+Fkbh@4DUsK-$u>kJ9; zrOm-HgBsrh@WzNAHaw0nqbhtE*l5V>TUO66-bAr)ugFJ@;Mv0aUQ&6KQeF$f%0clu zioO+X_>{os{Qyyy=jvsP`*1zNt4kvyk8tq;jgvvZ#HHKJ))P54%%P;%VlnO$+`chP zs#pis_G)lke!F;YK3;wYFVxwslhu!dHd}6KXjw~`qXpW;XW7;TF41NUIQ(^{yHWa? z4y2n+TsMA;Q(<%)K`maP;^f@be+D@dcR?PpWJOamqfmXS(5aL-<4ZSgfsi!Jsr51% zS$=jJo!i?!s?xhrh+x0s)JyGHan9;$IH$SU5*=Y7bxx3vet|PkZFD1wT#gf2m|cy` zS0RF>?foNb<$?rgEj~Ec_M$HGe8>ZYRtD&nSUV!l#;>510SDtDTk+IK9l`&MIn;XO zfmeV+J|kKBTZ$Q3^KX?JEP9Ls^#V8HV_U9@GR2PbCt{_0H@2RDVE`x`1O>!rcJMYi zxhr$5iIR2@=wIDcI2V>R@W94F5>!w&Za0>C==S<5n_A)1 zl;3w(v+LYp7Z{i-AklIt!q7|N1!1%gayH<_VFtg)O}WS-=069>?bk%&Fw1TZuf_~b zcRi2X3Dz+@JYyRYHoL#6373scloUrj_OQ=-bKwy&{SZ_I;tov}2H~VA(MX=u^_S;& z^SGoBf_Pzr*yL5q6_JfJ<(@y2Wnep+S2*Mg$zE2mZK3bEF?^*=c&+5jyZP*Z1P;6J4gdPS5(@{7E*YV zF8KTn&zi%EGm)D#JLCc5&Z^H*=mT6OXzwxSAz&=VhZZEaamd54gHeqz^Y^c3r zGCdN^^5@xStH&r*(k>Ci23D6}I32A(Cy%AQhQbh0*I{aIz)WpF13(r%EP>dc z1F{YmjBnY(@VyIE&269}qiC`LE^TsSp>#969lgk)yV!or2A}_*FYL!S;paF>Zsl0X zM@|`zu`TuJM7{U2HtzN{Jaz9v<)106k`s%BB`!v$T^|pF^>|QAq$qte?E;bC41`+* zZ-agf0yDLqo);nk9{IJt_p>oL>d}&0eP?9shU(knZ8YZfwj$W;U{OcsOvMz-WzN|S zDSM^4vdoT#2CA1F4kL=?1o9D}yt-=<8hsUkit1c_&_7yGW{C?Z{Y2#62+?hCJ&`vn zH&&GM4h~jNWfcpK*#8MO4CC4yZr0k3VqIVCdoF)fmY=DVW#%k}<$Z_{H7-v|_ukiq zyi&@bQq$b)UH$2Y&Rb+i7;(ArKFi?gR@lbgd}3O@sU|FQ1sY#7GX zvZ-O?bJ$xClUJH!VIHGXYq1>f%^E~bfjl1@W#BG=zRv(@%focfs)XIvFj6I@!(Gww z+thR$PY%&9i>mhZUPaoZN*f12Ig`n2ic+`0&dR}~RHeH4Fq4m9jQ*)wxn=6)Srgi1 zRw#38EFD*Wbf4oA`E$Z`KVIZm)K^;F7U5^I3RSx)!sO+v^5=HxdT&x!L;c z0`JF&I&OY&R-7GLJDJ;(JizRXw5*Sp=c25>Q@Nz=>FvYOn0b@H_vz$L;Cfcux9{<3 zmxrQCzrbt#YjmxeGwuy!%y*BBc{j&+{usp z_QQs)?{gbLpve!t4_B&4?MKJtb~y!_&KorZ|pIyvs2b|OLueMzckjGS2dIueojxCGApJ+DK|QiE`gKF587q; zv^KqdPAa>o!t#V0h}jiKCZ+}pQ59u1oaR=%xK6(@-0=6?)hw>-k!G9B{Ene7Q`030 z7(LAgI)9vv%E`x?i}f%j>{kZqH?SVnfX6M;%WRP!Sp+6YnSB{kJ^@bdcjXzcqE}PS z+hi-*SsdTa2)@93S}DI>P~b`Yyef03Dwz|WIx;On? zOs_9zoh{TW-*ne9;PZW7tq^zhmRP2bL)t~nyd*HVq@dbqWfsPl@zj1vZeQB6{oYVN zcoVfdP>$G%d_vVF6;jBEiTN$`C{|2^izrE5Lu`Q=`xpg!FO zVB4C{UO$l;_(oY<#&YDh1Zgh=*4LP~_Dx!W%{?Z=erQ4!qzTPa`Q29Ez%NoxexBKP#eLg(%f?KFyXv(+@OAWFT6~%oMn8QG3Ui1D0FnqzR?SJV32;` z(4wV@ul2g`oeq!tTYP;q#edFYR@56V`?cY@dxqR0@H^4~xR+yMF_-hc@A>zVJITLL z*9yVj4E1+?)-LwnuKvJVh(7L_J>Z9+{j=i>m13tam@;6-kji@fDq(FIcqwf1xlfQJ}Mp&tw4LOI$qkkO- zO9ViWFp|@0AEE96hBviu#DPm%xsEIQ@WTyFzOONi**s@90&oV7$0~9=1BSu}ZLU=E zce9hY+rI`|(rzQH^<&WgktlcY$lf4f_`QBn1om6}Wuf0;d^N;UR$Mo5e=J#QsJ{$! zaDKXz1o33EHn=lu5nPDI(hNIw^k47lrVVGo-bB2~a;2%5iT{@{^Bn2YzX-WcvTsVl z`S*{9?LZWM0Rxjk&LM+S;*?b!SDe(IrJKoO%4R$JMfso|R5s>cPX@Z#p407E1^C`) z?CM`X2AZ~h>8~XTcuxNN*{9$zy{ZpW;V)p2Oka5IMi4VYeCOTmFR9?;czM0^1REsV z7#IElj=-fvr7>!I+@b(r$PGQm>s2iLbO1H`GbJZr&)|b?TGQcrsKpP8E=HDDyYn0TLJ$=b`k}@>vBvB#OHpdV9)1dDj=z}dXtV7Z0=JLJ=`!L z#Sy%>m6XV)k81FGfq;NKzZ&+FwWU;MxuK@hi2gx-FguQ~zwt<#+Uj;UE6$;Pa2WbiS}yekALQJWb3AZ|ajqL?TN1`-_^imK{_f}U ziDJ_k#$BPIY}l5v&HQ%PNa>F7U-s&S7B8uMQ2yojf5F3xETh1$<$ur1O#dO`|2}{J z44B28K5-wNpD4TXG2Fbb>Ys0>Q9+vIP{5f z5wrIu%_v}h3DI|4hA(&kiL6vLB}RPC^}%?INO4EVV!^%bcVl8FC3Dd0KVWDV^uaYM zqxBZ!#SJzMbWMn~91iIha|D+} zC#z5ljG!QllUnjUPlo3!-JH!<+mCMRU2^ubWK8?P%_bszyet}9cNj*&L$it|O9H$_ zZ=zM$98Nv!vrlU5f;WjBp6C05RrkNM0n7q~9H9@nCux}?yY>lV z(RC%#>i))RkXZPg#9GiH%?|{)w7tPSkoXp%6iwrk3P-H!F?|8taqaU5?vCeG7H^$@dNVYV=E;mY zYi9%VJhVdjg&6^nY+sW~^b+*pNdQLy1aUkfDMpednoAS#(U8YjOK&e!f7xJk1TRP4 zEJA^-fyKHXk#1|B;LhpRSV6FhMHLVm9FCuf8EUr6&DWOA`0= z@U*}m)loX&brj?)or3JHC#k`e@hi>x%@0q&B*FvoFS|zZ0kPe=Dtq%dluUgm`GYu^ zSkjzW6I`hqwmCitjO+#kcY6_9BDv+zTcVOED!uOo5<6nDI>3Mf9Ab8PB4OdUL$Yoc zC)Ild_Ni*AysAGQ$A$sRGIL<^I$F$l9L0Rff z$3`}_+A3e3Xl4Nl%xIYAt7^8xIacoka36LNy#?&BmjmB=nv+yLMiBAo((fI*3on-@ zQ1^?+K&S7pg#E=;PAI9NPZgNJO* z4Gxc?XER-5ZkENCYs+=1)QM54!zF%$*k*TO5RAr#UHuO8=``>RU6VAB5Y3vjQ$F~BQ9lCu82Z-S9DB%5pwA)t?^K30hx^{+K96E zC7NlXW7p`gS-Fr?0Gw>S<=a|W4*}C-wvJ)mUrbU6#x93Pn{t?Hw6e+(%(cxBEe&X< zNhR@cqt#a#>bnRgFgWukQn1E+h35z932@UfbC{FKgbB?d&|M(?rmtuUeeM&fq{Jg8 z1uF<_F69$fu5mYu7*gO@A{SMPZDB!^KcoV|S~^*UY=YS_B|h3Xo*H5DL;Mn!T-8kJ zyd!k~A?@JTtZ4}VPXj}5)BK~#T5L&&>nLCz(uoaVp23;Blpr?IvgB<}p(wJiR9=nx z=pt8%)F>Q@&3?kzm^{vjTu{$>x5?#~1xUqzeXA$kdc$}wg%Zvv*ZksyOBm4hA#7#N z)=T6^q+=WOzHyU1IVUQ|%`RAZfwl5pWT$^8>&9unRGY>k_OEgW(rDZR<@ zIChN^s3+=}UVYNqR7H(op+x#K#V%q>Vt3dC*T*uRuwL|3(kPV?tjv^R2KJBU+FC{Z zW=bx&s5ro7NEmEhGlcU}Q+;(QD^LGpY$93_G5AXRi}nQCz;m*$`og>&U(EZ4Ou1BE zwWz{eg>z+yw~~RiPBWoSrD4*py75_Z%1Fr+XPs^ihI$kI68W&nGtE&Kic4F-FDLglLrqF zwp8rkQ*2WDZERl9vuf_IBNDp{wd1(~_SSYB=6nMz#qQX(I-|T&_Z_j6a5yB^lxDSn zV@yVLb(l~INfv+al&dSY{UXZazL4!O@ih6xb^0QDb+rwFWK|*`8E}2vU+2!NkjZ%e z8QjDJ=*!)XQJdIt`s(e#tIap_h{ALYjP#2F>EQTYw6)(fI~OHVJ3)GmK>4?dup6xJ z(VtoRwtiz66ZWiQNMebSs@Dl*3fbTQyq9f;?DR>ZRmzvC4@s6pCY;f+NvHW(Xr=S5 zAVdlh`*rOSdM+b#j0aM^puzzoPKJ3mfd4{6U1X#f~*yDr2 zUo>}?ODcwe73spEy(X>wt zheC2ICW1wvYKblu5LYP>Gp?xX zuxBQ$*rsrB{^_yd4VQ;q-$d9O+^sK}2rr?H>KMW5?)Nmm^&5wGaA=wuZQK|D7lt* z(qg@(a~Q{u8tl<_iKXHYM_U#_=AS1c!s?zTx>=Xx&NErlv0g{W2C2l&yL;epOzJ7t z1x=yL@8~W7c2&*s_ms1~CeuGBz?$vx!NWl)L5{P~+N1_zhq?MT5+e35NpufFT0L7X z*s>&3p^?{#A&TG44#u2)D$pcPV#{2jzhO61u2q9dfw#BTGmp@+!qPkh4K(F?gyu0E za{A&@bZz0VXrMN=T4B4CTyIRJg|kZ{9PY!Lh1bYWx^P`uTLuZ$fon-=m_aKRY3164 z<_lw{FiYZcxYvG|*hJc|k>EfY0o5`&MDCH=qoBX%cj;=L7@7Q9CJAm5i+pw4@=df1 z2;SODP~MCRy@$b;J$zY2L>ITeEke0}(d_j7FJW}DHQPr}>k^$)EEmMbc04aqLhD9P? zB9wnr*AlVdc0e}mCsJZ@5#C-jW{u`BI+8!-4Uu2p!c-%XRxP|8Ns~y{!K8|8d(soD zji(<>aJKqJZpMf%?C)^}Q%QLq_k{85whoHcCf;b6y$oM>gu+wwr8|qiB>=gJihfKAM6o%(`a)odx)3aG=xt6LlP1*HHq z)rN7=7QR#$-g^y6gE>=HKgzabW8#55$|Yge^ARh|pjm!pL<$`tnY!gnR!}a_-Z^TU zhgG^%mLFiIipqW&nd-EyB56z$allt~tlU8GLubg|?SsXrvL5kqurW#9dVZ&iGLv>k zM^X^uwYNIkg$qFM$jo8GtMo+cYGN>mI*3@|h1=r)Z6gb5l22!bwvV5r$<_kRkTJf1 zcIw{M82)I5xQz93bO5J1P}C5SSAXU_M*|h*iOhhZ1lvo1(}$-9JG#eczObOby;4xR zgoWLs$5kue9MomqqTp@!_iqZ?@{Ga*<8HS8ax+l+>aR-h(KB{sEt=c%0l_T8M@Mhi z5F+5>U?@(F6LLM*uVc|O&-jJ^9ehaZo|?DukUljj4wdDX-bbicy;Vahmo1g%_fFZz zx9pe1##uXCZ=xNx|x9jiD%7mhH=-2wht>{P4~pTwA{vW zoHs6a7sry%V+I;7jE0skqP!Jt?jg1GkXX*1;S(@f?vue4mvoG)-y%9q|D1+Zl|Z5U zvxZ-&&^(Xe#*lqAU1_*WDZt1R#-=@7sDugO|O-GAt?)Qk`xp2Vx74wL*B~*L%nItgc}aC+H_LPWI4a(w0IzEbGKd zmiJPN7X)J$L$#Qgr#9vB50k|6@QKGRSIsrWHjZ%yuL-GB!A#bO<_o=VYVDHxcL zoSF5a?4+~B9VaC2f8-!(#EZ@)fxZx1YS$BLR1^?X9GXkq4U*w*9=Sjq+TPu!#>%4- zqu-a#U_P@nSfOR*xv|a(7C9g@%-y&uTvmZiCZ{>C_v=I0&;ZuYmIOjpkx^ORK4{Q~ z8iy$BN*W1YK$ffiX41GTXXMwU-j=(gJ>frliA?RSAg=)PVR}C~?R@PT3qF0pSO`&;l;!Ax8KA72M$42VeaO9Wz`J4I{wLRG47hUf*B&M(c!XKX2Wv)+Kv zb5_E;qapSSF09sm)$85g!N4eEQ&eI(e^P3|yGy}>p7`CpOOM{2wQ{}-lXWe5Mac!v z{Qjo&&e*Sn-t7oD%DsK$%GgDfH{ABnx-#AfGDTLsOi1SQ5orqF{jY& zWn&?siqT?%G>Z5<&dMq!Z>9IUEMG3V9Lb9!h7D;@6=)7DSHZwjOe|W=y$8FysM<+K z-%Dp_KMH6btT%FOPg?XOBLa5#9(O<0^3`k9C|ritr8Zf2l1tXzps)vr)PUv?VID1n z9H{Kw>VhzE{7a6=h4T)6#t!~*MXrLGAWmL7SGM;L6kDn@fHzY^uj^%$_c$8dp8_Ab zUpSCuXaWzj@~XJ5#&4qQfPu^vR=GDK6l#HP&m_xTC8&el-B|Zi$TR*e5SVryj z;T;pmd<)p6CV|UwN&(3a!n@7soilzz39#;X0m+LaF8Sz_or_Ao1GNh$kS2j6UDFQj zkMizs{0UFfOJ7P{a3FF9(6z4i6~KLXW;}~ro+i=#*9uh1gv#tNP2gAgYhiMKF3~n0 ziioUB!^vRNN;E%;`a_gT-~>Ta&nto2{m##ZSZUKcI>6831Zy1hreoAKplZ|^ezu^x zD$XM;SM<)OgxKTng+4C7xnsu(=az;`IspO}dFyZ<8Y*&cW_3Y*cZR?s^&2ITSfBKh zo*vm4-fwfx1ZKW!wp%Ijc$j*&kl&x>{jS}I=Ly92GmR)tt-M=a`_cUO!@@`Xvc>xE zfCyt%7H~=@7m4Cy63$8w{_Gi-QS#x)HST}&#%8v3+jM9?kKwdlonn?x4C5G28@QAP zWsfB{6STwk8q_MJ!;rP3eedLBh@#e@_m}?BDhgTRmM^DJ1#r-fDNmj#bHdI;nH;fP zyPl$v17@qz560<&&Ck?C#O~0dRiQsoRK{0X-+pnjU%cB_q^4LZo8uW9>GVkf`l}Wt z^+d6laIRUT=+U1YNETakKbev~4Lt!SKPctq6=C{4uvIpOR5Jb}tfa`-KECm8hqkd? z!PU6KKWkzfHLrYbtwm#Fb={doV6jRk#R8>1*Bv=MQ4r+pUi%-Ek*=pWPxybj zjAv*U<%*LbP=N|~wZi>|(6J&wUS2(JnO}I_?~E+ivUK_MmHcrVd({bvE0eVn_4NNh z578&jFZ1cAC)^&VT0MG8M6bOhycDg)vKW9_id+-}m9b4%80{{N;X1$XdVMIB6CHo7 zPckh)8-_J^hBxuTaW|ha(~hI__zmPq#eXNVnWVdl!3E==5_s(|T>Yq0&bX3g{^t#Z z0ECEU_Ds-uTa_)XG!tJ&me#P`L~>7a!R>H;rtDM6UJ{=7^nrIHes#R%OY3JD!M0rR z2Z?+0fZWT*A+{qhN?;`<$`&y{*e}mY?LCZEwm5r7U@;cN)QL3BWq)6Il526rT!W+c zPi^*x?#`*VDljfEXM-h|Ra}$*_PnVPxM(a|v#VHINA?-p32J9Iq}|`7R>^CzF9NTC zY`gA|ir37#Y@!cTCVZ`-@hd)2Myrvl(WIfs#@x?-M5`T;*qChW{jd$>r26%6{U31s z<;T=ZV%rPNqjfB-RY(97r9J`9C{da*Cz+|v50N^YQe~B+3q)CN3KEaN%wK~|dsbPq zM&iU5Sb?|2OPXHVVTc{QN#Vor^z>?*EiOpv!Kf0c*egc)wEPuS4*Hu+@A9KnJ+897 zSo!BIG?$%8tUk=kgTNtD^ln&k>d zPcSLKZ-T?IyP|!+@#91X!Rw{T0xu_F*s|it<3f0=xVaiBeesFE+7F$rb=cL;qZO{q zGGt=CF@G{uiuB$KtI{c}%&8gw_ZW5h+bJc2+cRRE1L#*AZBX~ak3Wx+h&Z_U-+|YX z0QgO|A?lL%g^|aAoRhi>39s#eOo0Ct=d+%6#li<-X$9%ZyiC z;V=WaxLvRab_{wPN+Bv%eeu7H7DrXY`u>B?#Ca23u_RaFIa(jHj`Q@NEwpb#b)hq$ zJ@`5c@?Q5C>3DWAcXY#p-WUvwU+3P-}K{ZCqI^$k1_BX z&5`Kb;i-Ia-u+D96kg%iI`Z57+^)!(N9|YWC7_F>EIC+I+-jN0<@!7)E^io+spj=K zzs&nz?9aBsrt6Vd9qKlgkW(=o?^j@CzqW>6LOi}HvvRTTOpE`SU0D)k{y}M%banZnG?!TufvjrMbI2PXcBNLadUbnY0a|2UBZML-&~P|*-e zZ5XO-^*K$X~4i zjQ89LH-EjWlT0lGH z5$*I6uEBHE2&KqXB7OB^yWueFjmVFVAst`yzRLhliF9c>>uurEV-R&mA7~?e^6{*B zDA+9=h%VcE>JhIeTRst6=ft|0?%!qcCppdH*XL4fXv6ZFVLcSFR8$evAerV)xfcYd z8t*tT=0OnOG82MHhqY(=D7kH-A8Ix0PDjlUeA^AidRBMqJ*@THos5ei>(EBnG9Lo& z7k~5S5?{motFe_|_DVzR(05>fZs;wM9(+;@cNK>hlWxb7Pf9#XfPM)OUR`TlQ_e4* z&4A=7=KXAQ*l;iK!SlvR|0PK{{y4uae>2i8 z5p1*52!u$tl8@7BMh8J<=RS5j2I17%F*AvYKJb@=CtlybyCE0LKXy%;6{}DhaZbK` zwZDF>COCca^<80m9rX7KW!OhD7FrC%6nW%AAL!_k9N-Oe9XI7C;KObzyqy(T-xtni zv^M9+o596iYkHu46K-Rp`I?L<-X9r@DlSZBjC_!=jN3D<@Xh>`(wwa|YI!8x{NqGZ zYTmb2&Uf}*%fw+i4u9U{hgFc})!p$2O$>i1 z=Nu;O7;skSS`Vgke`K<%&kWUC-g;Gy|sE6g;Mw=)=P!5P?`toyo?zp)N`k# zlfB|xu=aB>yRBXc%nQR8sD`6-K`r4j9Hi5@N6VKDuAp`=bKU|I|X zfDj9MaV$(S8;aHyRFKD%83qeA{H8m$@tmX_TP56qt>*G7gk#k4$y<)GS>Wv1wwG7Y zufU_%un6}tli^fPz=i+RvJD529U^)_)J;v z$Tt%%V@nfkDG*m>JE2EhiMTdm4~gRXOb!u1{H6xb$dIg*58pcyEf7O#-;|V_&1(~< z+{*5ewl=YB**>}MRS|HHGvrPG1)YQ|gsfoRcOJfQO6hBzY+4U8V?QnpFFWbq1# zW*V*ss~+0|Jtg`n7+Hq8!MorxC-ivTM|kz*rrI?viyTEVq5ZLswh-xR>}%=-%TUZM z6`d7et0gKxY0AtA78U>TcV=ScBw94jt8IXZ-6(2Vo$?q&zRDGu^=jPASMt)FDFZ}Y ze1-+kjMdZ_VJqMSDdC$UE%Hpa8y8IpD zU1)mO(s^h$1^NdB#KAGNJ3N|_R0Ne%j%FQqnq_s0#}Cu3BRyd&yJQZ)G))!L4}-saPj}dCa7!`*=A~ z&Pdr(_Zoj3mC^HM$VhGE`@GCl!WebVcn1Wb{c%i8OK9vhd^#=L-F}H*lbP_DFZ&(od z#BVX6^kNkuu+FG;YpvT)eoID2Z7@(V@pC$M5&V-#@pYen1vWY(4J)=re?7vj(`<+7 zf|~Np^1GXflwOzp+e-S`1>5hy*0N|AT%-oE;B|*QPl(0mDx~9;0GB#tPD^tKXPE3PEM&ALci&OjYX+kc4psq1ua;!Xb7g$}CT93B?x->xV#^>p=;OHuT zbp@&-!2;m&5c)hePldIJz7A36qw3&42)KNL2FB){WVxV41?zFtPJ%MGOEUCaoV^Ci z8l3~G7pD&49}BsxLvO~|%dra3!{B;RDg&Dz4D~v1Pwq|E&XvU zMMZuAeF@SFBx&Ir1hR|;9~w3wvas}`#92xCIhkgzUSpD~Q2-J)%6BDmgpc&iXblC6 z%AiNa&0^)9(c2(JF;Y7oBxJop$H%~BE9mG%up*pPhED-nH`2@F;rbO~=uUpc<0N%L z3c&g?Ju5a_xndTr08s>x6!GQ)F!A_WLvw_+7QG=cTdHDF<~x_7DM`oZ9nxBr9*}4Y zu5gh-@YRNr6bxmtP(B-t3TyN|P^~y=2>(#XdY$eWV=GrtfF1(Zijo+3lU2vP#s?vv}Td+Yb#Z%%0RvGo<$Zugzn*}YA>4~9_* zACZ6QM1A=(aQk*2cFFIQd&k6JGEl zL8X&zlbNSY7-eHTWAnlddqrI7f57u;7ySZqo)Z>6F+w84{9?}%{RE0M6T-#b-0-`# znD^p@bGXOXoQR^_sIbCR+jgI)Mj^%rCj3`{WqV908MgoU_#aHr2#d*8-wo|t{$2r7D7@|i4LF9 zqQfQx!ShC>HGsG`y`q}p!!3S=8&sM+=qw8!{(LGDCvLKDJejGhrA{REw1}}946o@f zYMg0(mp#kqI~A01XBtjWc3ss@`>B%;N?Vcob^Z0Z^}xg78t{(U z{Hfok#3tKGkM>Msjn_U@1P&P~T*DU@KaF>%ygp9bdHYTedN#$>b|xGweqiF%(Uk8b zcIya8mVBj`VG!gzd+sD(Xc%P8G*jSkF9gafU`CJJJvu3GZf1bn{=FlYc!WNJbgdpa z{i`^gswP%VCyXbhF-6s!(mH(gKEyFo+*9MkA@J(cD(Ht(?xUIB9M=J{0;%#!vCD(; zHX_2?vhPbkH#spaR+aC=GoD=65s3m?1&U!dURegr6&5ft+n5{e2hgK(pgPo*F&Q^8rl>UE_<-V)kAz4Kq%=AU?cbw|Z z)&0*7j^maw}V81(hhi0&MKr`SVUu_&(q&Um1d+%wSzVoQx zobXPwRf3r<+gm_Wy>&M?dV7EteegSXa&P$FWf7nJw?z@o-YizIw8#?u4>J}M^Ilk6 za^$DqZxbr>t^)k*x6T*|HJ>a}y)Jh;8Ac zjl&)!Gpjr7Qg<)Pc~>WAZq!{&H8U(@`)K=Om*iHMu}AMJOZkKfAe$nXlK#82K5p%E zTZ{Tms;2Qlv~PcjH(N1>-n!8u79vyf8kcQ^gapV>Al#8_u~}czI`nzY4pMhFsTPgx zC#POKJ05b4zP~Ka=tH3J(nT*BEB@d52?53o+?c ziPuLI7MDs`TIrn5flK(iE438j8x>W@;cfXp{Y(q7qtkXs_pGCN2A+Z7JfnM$yL;=0 zbjC*Dgm(S3PFK~uIz@I9cmCb2iZiCWqn@k8<4F!~QJTPz2w8Rix&jD;t=S*Z-anlK zk$xkXG3lSmKfrZ&DMhhI`i0oUiyz)yuQh%3e3*?ohy}F#g#B##dCga%qu4XF!X=ou z7&zaAR(R37?YwfvCshm+6RXJDj{S1&Xs&b8MCe@SSd`S{hm%$otuOGDt@OK?f_cq3t&nqPhYn<2a~+vF1+!#NiM0ecyxKvN20-dGNIVx zL2%`-A?B0t3CncdT7RB(rm6U*(U<$~6EP_fFWjUxmK0E%{13dQGaM%DQzhIlwE2s8 zRTVSycVow!+zfs)5sawenZ~+~r?wOHl)?)hhpCyg!Y#^4kE%CCW!|vPU-y|!&l#zT z5Aqz6^8@q11#aDsyzYF+_Q@Z2G8t=g+5vW1G$%xj%a+4@>{u!(%oD=>{2`+3D*VJj zlEj){pOjD5fOjyn#4@BGF;*+F9g4*IWOS&{2s!=QWOm;kQFIGEq3`|ppZzRmL`pES z|5Ml)*vetdBU;ZpBG-E<_R`&^=L4wVu?LpB1G{&E#?mY$`rPqIq5KQ{J(WAavtD3kbjbmsYz!pf;}l4GNOlR$nabtP0gVXc+eM8OOq!Rv33A zTdK7@FtkqAgU2g*{u0Hsy4!Iyv*PP&AFhby5XOTWeD!U$Jy{EvGX!c7g;Y!|$PZ_i zeWWuF9n@p{a?lqz?I665eFubunhiM|0%7TD%L!Md6 zmY{2T&IM*Mh7Nh)#%3}9$9^y^OF%-|i~GyRV}7yANWKZt1$YY3T*Cx$J+$?Sab?Xo e@R=OWwMQx5_(nWueDYv}!?Qq!>jp{*aQz=51rP)P literal 0 HcmV?d00001 diff --git a/src/obikmer/src/cmd/superkmer.rs b/src/obikmer/src/cmd/superkmer.rs index 8dc938a..2ea1060 100644 --- a/src/obikmer/src/cmd/superkmer.rs +++ b/src/obikmer/src/cmd/superkmer.rs @@ -3,7 +3,7 @@ use std::path::PathBuf; use clap::Args; use obifastwrite::write_scatter; -use obikseq::RoutableSuperKmer; +use obikseq::{RoutableSuperKmer, set_k, set_m}; use crate::cli::{CommonArgs, PipelineData, open_chunks}; @@ -41,6 +41,9 @@ pub fn run(args: SuperkmerArgs) { let partition_bits = args.common.partition_bits; let n_workers = args.common.threads.max(1); + set_k(k); + set_m(m); + let path_source = args.common.seqfile_paths(); let pipe = obipipeline::make_pipe! { diff --git a/src/obikseq/src/kmer.rs b/src/obikseq/src/kmer.rs index 70e49bb..9091661 100644 --- a/src/obikseq/src/kmer.rs +++ b/src/obikseq/src/kmer.rs @@ -118,7 +118,7 @@ pub struct KmerOf(u64, PhantomData); impl KmerOf { /// Wrap a raw left-aligned u64 value as a kmer. #[inline] - pub fn from_raw(raw: u64) -> Self { + pub const fn from_raw(raw: u64) -> Self { KmerOf(raw, PhantomData) } diff --git a/src/obiskbuilder/build.rs b/src/obiskbuilder/build.rs new file mode 100644 index 0000000..f422279 --- /dev/null +++ b/src/obiskbuilder/build.rs @@ -0,0 +1,145 @@ +use std::fs; +use std::path::PathBuf; + +const K_MAX: usize = 32; +const WS_MAX: usize = 6; + +fn normalize_circular(kmer: u64, ws: usize) -> u64 { + let mask = (1u64 << (ws * 2)) - 1; + let mut canonical = kmer & mask; + let mut current = canonical; + for _ in 0..ws - 1 { + let top = (current >> ((ws - 1) * 2)) & 3; + current = ((current << 2) | top) & mask; + if current < canonical { + canonical = current; + } + } + canonical +} + +fn revcomp_raw(x: u64, k: usize) -> u64 { + let x = !x; + let x = x.swap_bytes(); + let x = ((x >> 4) & 0x0F0F0F0F0F0F0F0F) | ((x & 0x0F0F0F0F0F0F0F0F) << 4); + let x = ((x >> 2) & 0x3333333333333333) | ((x & 0x3333333333333333) << 2); + x << (64 - 2 * k) +} + +fn build_normalized_kmer(k: usize) -> Vec { + let n = 1usize << (k * 2); + let shift = 64 - k * 2; + let mut result = vec![0u64; n]; + for i in 0..n { + let la = (i as u64) << shift; + let ra = i as u64; + let rc_ra = revcomp_raw(la, k) >> shift; + let circ = normalize_circular(ra, k); + let circ_rc = normalize_circular(rc_ra, k); + result[i] = if circ < circ_rc { circ } else { circ_rc }; + } + result +} + +fn build_ln_class(norm: &[u64]) -> Vec { + let n = norm.len(); + let mut sizes = vec![0u32; n]; + for &c in norm { + sizes[c as usize] += 1; + } + norm.iter() + .map(|&c| { + let s = sizes[c as usize]; + if s > 0 { (s as f64).ln() } else { 0.0 } + }) + .collect() +} + +fn build_n_log_n() -> [f64; K_MAX + 1] { + let mut t = [0.0f64; K_MAX + 1]; + for n in 1..=K_MAX { + t[n] = (n as f64) * (n as f64).ln(); + } + t +} + +fn build_emax() -> [[f64; WS_MAX + 1]; K_MAX + 1] { + let mut t = [[0.0f64; WS_MAX + 1]; K_MAX + 1]; + for k in 2..=K_MAX { + for ws in 1..=WS_MAX.min(k - 1) { + let n_raw = 1usize << (ws * 2); + let nwords = k - ws + 1; + let c = nwords / n_raw; + let r = nwords % n_raw; + let nf = nwords as f64; + let t1 = if c == 0 || n_raw == r { + 0.0 + } else { + let f1 = c as f64 / nf; + (n_raw - r) as f64 * f1 * f1.ln() + }; + let t2 = if r == 0 { + 0.0 + } else { + let f2 = (c + 1) as f64 / nf; + r as f64 * f2 * f2.ln() + }; + t[k][ws] = -(t1 + t2); + } + } + t +} + +fn build_log_nwords() -> [[f64; WS_MAX + 1]; K_MAX + 1] { + let mut t = [[0.0f64; WS_MAX + 1]; K_MAX + 1]; + for k in 2..=K_MAX { + for ws in 1..=WS_MAX.min(k - 1) { + t[k][ws] = ((k - ws + 1) as f64).ln(); + } + } + t +} + +fn emit_f64_1d(out: &mut String, name: &str, n: usize, values: &[f64]) { + out.push_str(&format!("pub(crate) const {name}: [f64; {n}] = [\n")); + for v in values { + out.push_str(&format!(" {v:?},\n")); + } + out.push_str("];\n"); +} + +fn emit_f64_2d(out: &mut String, name: &str, rows: usize, cols: usize, values: &[[f64; WS_MAX + 1]]) { + out.push_str(&format!("pub(crate) const {name}: [[f64; {cols}]; {rows}] = [\n")); + for row in values { + out.push_str(" ["); + for (i, v) in row.iter().enumerate() { + if i > 0 { out.push_str(", "); } + out.push_str(&format!("{v:?}")); + } + out.push_str("],\n"); + } + out.push_str("];\n"); +} + +fn main() { + let out_dir = PathBuf::from(std::env::var("OUT_DIR").unwrap()); + let mut out = String::new(); + + for k in 1..=6usize { + let n = 1usize << (k * 2); + let norm = build_normalized_kmer(k); + let ln_class = build_ln_class(&norm); + emit_f64_1d(&mut out, &format!("LN_CLASS{k}"), n, &ln_class); + } + + let n_log_n = build_n_log_n(); + emit_f64_1d(&mut out, "N_LOG_N", K_MAX + 1, &n_log_n); + + let emax = build_emax(); + emit_f64_2d(&mut out, "EMAX", K_MAX + 1, WS_MAX + 1, &emax); + + let log_nwords = build_log_nwords(); + emit_f64_2d(&mut out, "LOG_NWORDS", K_MAX + 1, WS_MAX + 1, &log_nwords); + + fs::write(out_dir.join("ln_class_tables.rs"), out).unwrap(); +} diff --git a/src/obiskbuilder/src/entropy_table.rs b/src/obiskbuilder/src/entropy_table.rs index 4132ef7..9be69c3 100644 --- a/src/obiskbuilder/src/entropy_table.rs +++ b/src/obiskbuilder/src/entropy_table.rs @@ -1,173 +1,108 @@ -use obikseq::kmer::Kmer; -use std::sync::LazyLock; +pub(crate) const NORMK1: [u64; 4] = build_normalized_kmer::<4>(); +pub(crate) const NORMK2: [u64; 16] = build_normalized_kmer::<16>(); +pub(crate) const NORMK3: [u64; 64] = build_normalized_kmer::<64>(); +pub(crate) const NORMK4: [u64; 256] = build_normalized_kmer::<256>(); +pub(crate) const NORMK5: [u64; 1024] = build_normalized_kmer::<1024>(); +pub(crate) const NORMK6: [u64; 4096] = build_normalized_kmer::<4096>(); -pub(crate) static NORMK1: LazyLock<[u64; 4]> = LazyLock::new(|| build_normalized_kmer::<4>()); -pub(crate) static NORMK2: LazyLock<[u64; 16]> = LazyLock::new(|| build_normalized_kmer::<16>()); -pub(crate) static NORMK3: LazyLock<[u64; 64]> = LazyLock::new(|| build_normalized_kmer::<64>()); -pub(crate) static NORMK4: LazyLock<[u64; 256]> = LazyLock::new(|| build_normalized_kmer::<256>()); -pub(crate) static NORMK5: LazyLock<[u64; 1024]> = LazyLock::new(|| build_normalized_kmer::<1024>()); -pub(crate) static NORMK6: LazyLock<[u64; 4096]> = LazyLock::new(|| build_normalized_kmer::<4096>()); +include!(concat!(env!("OUT_DIR"), "/ln_class_tables.rs")); -pub(crate) static LN_CARD_ROT1: LazyLock<[f64; 4]> = - LazyLock::new(|| build_log_class_size::<4>(&NORMK1)); -pub(crate) static LN_CARD_ROT2: LazyLock<[f64; 16]> = - LazyLock::new(|| build_log_class_size::<16>(&NORMK2)); -pub(crate) static LN_CARD_ROT3: LazyLock<[f64; 64]> = - LazyLock::new(|| build_log_class_size::<64>(&NORMK3)); -pub(crate) static LN_CARD_ROT4: LazyLock<[f64; 256]> = - LazyLock::new(|| build_log_class_size::<256>(&NORMK4)); -pub(crate) static LN_CARD_ROT5: LazyLock<[f64; 1024]> = - LazyLock::new(|| build_log_class_size::<1024>(&NORMK5)); -pub(crate) static LN_CARD_ROT6: LazyLock<[f64; 4096]> = - LazyLock::new(|| build_log_class_size::<4096>(&NORMK6)); - -fn ln0(x: f64) -> f64 { - if x == 0.0 { 0.0 } else { x.ln() } -} - -fn normalize_circular(kmer: u64, ws: usize) -> u64 { +const fn normalize_circular(kmer: u64, ws: usize) -> u64 { let mask = (1u64 << (ws * 2)) - 1; let mut canonical = kmer & mask; let mut current = canonical; - for _ in 0..ws - 1 { + let mut i = 0; + while i < (ws - 1) { let top = (current >> ((ws - 1) * 2)) & 3; current = ((current << 2) | top) & mask; if current < canonical { canonical = current; } + i += 1; } canonical } -fn build_normalized_kmer() -> [u64; N] { +const fn build_normalized_kmer() -> [u64; N] { let mut result = [0u64; N]; - let k = N.ilog(4) as usize; + let k = k_from_n::(); let shift = 64 - k * 2; - for i in 0..N { + let mut i = 0; + while i < N { let la = (i as u64) << shift; let ra = i as u64; - let rc_ra = Kmer::from_raw(la).revcomp().raw() >> shift; + let rc_ra = revcomp_raw(la, k) >> shift; let circ = normalize_circular(ra, k); let circ_rc = normalize_circular(rc_ra, k); - result[i] = circ.min(circ_rc); + result[i] = if circ < circ_rc { circ } else { circ_rc }; + i += 1; } result } -fn build_log_class_size(norm: &[u64; N]) -> [f64; N] { - let mut sizes = [0u32; N]; - for &c in norm { - sizes[c as usize] += 1; - } - let mut result = [0.0f64; N]; - for i in 0..N { - if sizes[i] > 0 { - result[i] = ln0(sizes[i] as f64); - } - } - result +const fn revcomp_raw(x: u64, k: usize) -> u64 { + let x = !x; + let x = x.swap_bytes(); + let x = ((x >> 4) & 0x0F0F0F0F0F0F0F0F) | ((x & 0x0F0F0F0F0F0F0F0F) << 4); + let x = ((x >> 2) & 0x3333333333333333) | ((x & 0x3333333333333333) << 2); + x << (64 - 2 * k) } -pub(crate) fn entropy_norm_kmer(kmer: u64, k: usize, left: bool) -> u64 { - let shift = 64 - k * 2; - let ra = if left { kmer >> shift } else { kmer }; // left-aligned → right-aligned index - let canonical_ra = match k { - 1 => NORMK1[ra as usize], - 2 => NORMK2[ra as usize], - 3 => NORMK3[ra as usize], - 4 => NORMK4[ra as usize], - 5 => NORMK5[ra as usize], - 6 => NORMK6[ra as usize], - _ => panic!("k must be 1..=6"), - }; - if left { - canonical_ra << shift - } else { - canonical_ra - } // right-aligned → left-aligned -} - -pub(crate) fn ln_class_size(kmer: u64, k: usize, left: bool) -> f64 { - let ra = if left { kmer >> (64 - k * 2) } else { kmer }; // left-aligned → right-aligned index - match k { - 1 => LN_CARD_ROT1[NORMK1[ra as usize] as usize], - 2 => LN_CARD_ROT2[NORMK2[ra as usize] as usize], - 3 => LN_CARD_ROT3[NORMK3[ra as usize] as usize], - 4 => LN_CARD_ROT4[NORMK4[ra as usize] as usize], - 5 => LN_CARD_ROT5[NORMK5[ra as usize] as usize], - 6 => LN_CARD_ROT6[NORMK6[ra as usize] as usize], - _ => panic!("k must be 1..=6"), +const fn k_from_n() -> usize { + match N { + 4 => 1, + 16 => 2, + 64 => 3, + 256 => 4, + 1024 => 5, + 4096 => 6, + _ => panic!("N must be a power of 4"), } } -// ── k-dependent tables (k ≤ K_MAX, ws ≤ WS_MAX) ────────────────────────────── - -pub(crate) const K_MAX: usize = 32; pub(crate) const WS_MAX: usize = 6; -/// n·ln(n), with n_log_n[0] = 0. Indexed by n = 0..=K_MAX. -pub(crate) static N_LOG_N: LazyLock<[f64; K_MAX + 1]> = LazyLock::new(|| build_n_log_n()); - -/// H_max[k][ws]: maximum entropy for kmer length k and word size ws. -pub(crate) static EMAX: LazyLock<[[f64; WS_MAX + 1]; K_MAX + 1]> = LazyLock::new(|| build_emax()); - -/// ln(k − ws + 1): log of the number of ws-words in a kmer of length k. -pub(crate) static LOG_NWORDS: LazyLock<[[f64; WS_MAX + 1]; K_MAX + 1]> = - LazyLock::new(|| build_log_nwords()); - -pub(crate) fn n_log_n(n: usize) -> f64 { +#[inline(always)] +pub(crate) const fn n_log_n(n: usize) -> f64 { N_LOG_N[n] } -pub(crate) fn emax(k: usize, ws: usize) -> f64 { +#[inline(always)] +pub(crate) const fn emax(k: usize, ws: usize) -> f64 { EMAX[k][ws] } -pub(crate) fn log_nwords(k: usize, ws: usize) -> f64 { +#[inline(always)] +pub(crate) const fn log_nwords(k: usize, ws: usize) -> f64 { LOG_NWORDS[k][ws] } -fn build_n_log_n() -> [f64; K_MAX + 1] { - let mut result = [0.0f64; K_MAX + 1]; - for n in 1..=K_MAX { - result[n] = (n as f64) * (n as f64).ln(); +#[inline(always)] +pub(crate) const fn entropy_norm_kmer(kmer: u64) -> u64 { + const SHIFT: [usize; 7] = [0, 62, 60, 58, 56, 54, 52]; + const NORM: [&[u64]; 7] = [&[], &NORMK1, &NORMK2, &NORMK3, &NORMK4, &NORMK5, &NORMK6]; + + let shift = SHIFT[K]; + let ra = if LEFT { kmer >> shift } else { kmer }; + let canonical_ra = NORM[K][ra as usize]; + if LEFT { + canonical_ra << shift + } else { + canonical_ra } - result } -fn build_emax() -> [[f64; WS_MAX + 1]; K_MAX + 1] { - let mut result = [[0.0f64; WS_MAX + 1]; K_MAX + 1]; - for k in 2..=K_MAX { - for ws in 1..=WS_MAX.min(k - 1) { - let n_raw = 1usize << (ws * 2); // 4^ws - let nwords = k - ws + 1; - let c = nwords / n_raw; - let r = nwords % n_raw; - let nf = nwords as f64; - let t1 = if c == 0 || n_raw == r { - 0.0 - } else { - let f1 = c as f64 / nf; - (n_raw - r) as f64 * f1 * f1.ln() - }; - let t2 = if r == 0 { - 0.0 - } else { - let f2 = (c + 1) as f64 / nf; - r as f64 * f2 * f2.ln() - }; - result[k][ws] = -(t1 + t2); - } +#[inline(always)] +pub(crate) const fn ln_class_size(kmer: u64) -> f64 { + const SHIFT: [usize; 7] = [0, 62, 60, 58, 56, 54, 52]; + let ra = if LEFT { kmer >> SHIFT[K] } else { kmer }; + match K { + 1 => LN_CLASS1[ra as usize], + 2 => LN_CLASS2[ra as usize], + 3 => LN_CLASS3[ra as usize], + 4 => LN_CLASS4[ra as usize], + 5 => LN_CLASS5[ra as usize], + 6 => LN_CLASS6[ra as usize], + _ => panic!("k must be 1..=6"), } - result -} - -fn build_log_nwords() -> [[f64; WS_MAX + 1]; K_MAX + 1] { - let mut result = [[0.0f64; WS_MAX + 1]; K_MAX + 1]; - for k in 2..=K_MAX { - for ws in 1..=WS_MAX.min(k - 1) { - result[k][ws] = ((k - ws + 1) as f64).ln(); - } - } - result } diff --git a/src/obiskbuilder/src/iter.rs b/src/obiskbuilder/src/iter.rs index f874349..0839b97 100644 --- a/src/obiskbuilder/src/iter.rs +++ b/src/obiskbuilder/src/iter.rs @@ -26,6 +26,7 @@ use crate::scratch::SuperKmerScratch; pub struct SuperKmerIter<'a> { cursor: ForwardCursor<'a>, k: usize, + rope_len: usize, theta: f64, scratch: SuperKmerScratch, stat: RollingStat, @@ -44,6 +45,7 @@ impl<'a> SuperKmerIter<'a> { Self { cursor: rope.fw_cursor(), k, + rope_len: rope.len(), theta, scratch: SuperKmerScratch::new(), stat: RollingStat::new(level_max), @@ -71,6 +73,10 @@ impl<'a> SuperKmerIter<'a> { impl Iterator for SuperKmerIter<'_> { type Item = RoutableSuperKmer; + fn size_hint(&self) -> (usize, Option) { + (0, Some(self.rope_len / self.k)) + } + fn next(&mut self) -> Option { loop { let byte = match self.cursor.read_next().ok() { diff --git a/src/obiskbuilder/src/rolling_stat.rs b/src/obiskbuilder/src/rolling_stat.rs index fb61d20..17838a0 100644 --- a/src/obiskbuilder/src/rolling_stat.rs +++ b/src/obiskbuilder/src/rolling_stat.rs @@ -4,36 +4,118 @@ use obikseq::params; use crate::encoding::encode_nuc; use crate::entropy_table::{WS_MAX, emax, entropy_norm_kmer, ln_class_size, log_nwords, n_log_n}; -#[derive(Clone, Copy)] +// ── Stack-allocated ring buffer ─────────────────────────────────────────────── + +/// Fixed-capacity ring buffer backed by a stack array. +/// N must be a power of two; operations are branchless via `% N`. +struct Ring { + buf: [T; N], + head: usize, + len: usize, +} + +impl Ring { + #[inline] + fn new() -> Self { + Self { + buf: [T::default(); N], + head: 0, + len: 0, + } + } + #[inline] + fn is_empty(&self) -> bool { + self.len == 0 + } + #[inline] + fn clear(&mut self) { + self.len = 0; + self.head = 0; + } + + #[inline] + fn push_back(&mut self, val: T) { + self.buf[(self.head + self.len) % N] = val; + self.len += 1; + } + #[inline] + fn pop_front(&mut self) -> T { + let val = self.buf[self.head]; + self.head = (self.head + 1) % N; + self.len -= 1; + val + } + #[inline] + fn pop_back(&mut self) -> T { + self.len -= 1; + self.buf[(self.head + self.len) % N] + } + #[inline] + fn front(&self) -> Option<&T> { + if self.len > 0 { + Some(&self.buf[self.head]) + } else { + None + } + } + #[inline] + fn back(&self) -> Option<&T> { + if self.len > 0 { + Some(&self.buf[(self.head + self.len - 1) % N]) + } else { + None + } + } + + /// Iterate over elements front-to-back (copies, since T: Copy). + fn iter(&self) -> impl Iterator + '_ { + (0..self.len).map(move |i| self.buf[(self.head + i) % N]) + } +} + +// ── MmerItem ────────────────────────────────────────────────────────────────── + +#[derive(Clone, Copy, Default)] struct MmerItem { /// 0-based position of this m-mer's first base within the current segment. position: usize, - /// Raw canonical m-mer value (right-aligned), used for partition key computation. + /// Raw canonical m-mer value (right-aligned). canonical: u64, /// mix64 hash of the canonical m-mer, used as the random ordering key. hash: u64, } +// ── RollingStat ─────────────────────────────────────────────────────────────── + pub struct RollingStat { entropy_max_k: usize, + k: usize, + m: usize, + steady: bool, rolling_k: u64, rolling_rck: u64, k_mask: u64, m_mask: u64, received: usize, - k1q: std::collections::VecDeque, - k2q: std::collections::VecDeque, - k3q: std::collections::VecDeque, - k4q: std::collections::VecDeque, - k5q: std::collections::VecDeque, - k6q: std::collections::VecDeque, - minimier: std::collections::VecDeque, - k1c: Vec, - k2c: Vec, - k3c: Vec, - k4c: Vec, - k5c: Vec, - k6c: Vec, + + // Sliding-window queues — stack-allocated, capacity ≤ k ≤ 31. + k1q: Ring, + k2q: Ring, + k3q: Ring, + k4q: Ring, + k5q: Ring, + k6q: Ring, + minimier: Ring, + + // Frequency count arrays. + // Max count per cell ≤ k ≤ 31 → u8 is sufficient. + k1c: [u8; 4], + k2c: [u8; 16], + k3c: [u8; 64], + k4c: [u8; 256], + k5c: [u8; 1024], + k6c: [u8; 4096], + sum_f_log_f: [f64; WS_MAX + 1], sum_f_log_s: [f64; WS_MAX + 1], } @@ -44,24 +126,27 @@ impl RollingStat { let m = params::m(); Self { entropy_max_k, + k, + m, + steady: false, rolling_k: 0, rolling_rck: 0, k_mask: (!0u64) >> (64 - k * 2), m_mask: (!0u64) >> (64 - m * 2), received: 0, - k1q: std::collections::VecDeque::with_capacity(k), - k2q: std::collections::VecDeque::with_capacity(k - 1), - k3q: std::collections::VecDeque::with_capacity(k - 2), - k4q: std::collections::VecDeque::with_capacity(k - 3), - k5q: std::collections::VecDeque::with_capacity(k - 4), - k6q: std::collections::VecDeque::with_capacity(k - 5), - minimier: std::collections::VecDeque::with_capacity(k - m + 2), - k1c: vec![0; 4_usize.pow(1)], - k2c: vec![0; 4_usize.pow(2)], - k3c: vec![0; 4_usize.pow(3)], - k4c: vec![0; 4_usize.pow(4)], - k5c: vec![0; 4_usize.pow(5)], - k6c: vec![0; 4_usize.pow(6)], + k1q: Ring::new(), + k2q: Ring::new(), + k3q: Ring::new(), + k4q: Ring::new(), + k5q: Ring::new(), + k6q: Ring::new(), + minimier: Ring::new(), + k1c: [0; 4], + k2c: [0; 16], + k3c: [0; 64], + k4c: [0; 256], + k5c: [0; 1024], + k6c: [0; 4096], sum_f_log_f: [0.0; WS_MAX + 1], sum_f_log_s: [0.0; WS_MAX + 1], } @@ -71,24 +156,22 @@ impl RollingStat { self.rolling_k = 0; self.rolling_rck = 0; self.received = 0; - for &i in &self.k1q { - self.k1c[i as usize] = 0; - } - for &i in &self.k2q { - self.k2c[i as usize] = 0; - } - for &i in &self.k3q { - self.k3c[i as usize] = 0; - } - for &i in &self.k4q { - self.k4c[i as usize] = 0; - } - for &i in &self.k5q { - self.k5c[i as usize] = 0; - } - for &i in &self.k6q { - self.k6c[i as usize] = 0; - } + self.steady = false; + + // for i in self.k1q.iter() { self.k1c[i as usize] = 0; } + // for i in self.k2q.iter() { self.k2c[i as usize] = 0; } + // for i in self.k3q.iter() { self.k3c[i as usize] = 0; } + // for i in self.k4q.iter() { self.k4c[i as usize] = 0; } + // for i in self.k5q.iter() { self.k5c[i as usize] = 0; } + // for i in self.k6q.iter() { self.k6c[i as usize] = 0; } + + self.k1c.fill(0); + self.k2c.fill(0); + self.k3c.fill(0); + self.k4c.fill(0); + self.k5c.fill(0); + self.k6c.fill(0); + self.k1q.clear(); self.k2q.clear(); self.k3q.clear(); @@ -96,37 +179,36 @@ impl RollingStat { self.k5q.clear(); self.k6q.clear(); self.minimier.clear(); + self.sum_f_log_f = [0.0; WS_MAX + 1]; self.sum_f_log_s = [0.0; WS_MAX + 1]; } #[inline] - fn update_sums_decrement( + fn update_sums_decrement( sum_f_log_f: &mut [f64; WS_MAX + 1], sum_f_log_s: &mut [f64; WS_MAX + 1], - ws: usize, canonical: u64, f: usize, ) { - sum_f_log_f[ws] += n_log_n(f - 1) - n_log_n(f); - sum_f_log_s[ws] -= ln_class_size(canonical, ws, false); + sum_f_log_f[K] += n_log_n(f - 1) - n_log_n(f); + sum_f_log_s[K] -= ln_class_size::(canonical); } #[inline] - fn update_sums_increment( + fn update_sums_increment( sum_f_log_f: &mut [f64; WS_MAX + 1], sum_f_log_s: &mut [f64; WS_MAX + 1], - ws: usize, canonical: u64, g: usize, ) { - sum_f_log_f[ws] += n_log_n(g + 1) - n_log_n(g); - sum_f_log_s[ws] += ln_class_size(canonical, ws, false); + sum_f_log_f[K] += n_log_n(g + 1) - n_log_n(g); + sum_f_log_s[K] += ln_class_size::(canonical); } pub fn push(&mut self, nuc: u8) { - let k = params::k(); - let m = params::m(); + let k = self.k; + let m = self.m; let bnuc = encode_nuc(nuc); let cnuc = bnuc ^ 3; @@ -135,12 +217,12 @@ impl RollingStat { self.rolling_rck = ((self.rolling_rck >> 2) | ((cnuc as u64) << ((k - 1) * 2))) & self.k_mask; - let canonical_k1 = entropy_norm_kmer(self.rolling_k & 3, 1, false); - let canonical_k2 = entropy_norm_kmer(self.rolling_k & 15, 2, false); - let canonical_k3 = entropy_norm_kmer(self.rolling_k & 63, 3, false); - let canonical_k4 = entropy_norm_kmer(self.rolling_k & 255, 4, false); - let canonical_k5 = entropy_norm_kmer(self.rolling_k & 1023, 5, false); - let canonical_k6 = entropy_norm_kmer(self.rolling_k & 4095, 6, false); + let canonical_k1 = entropy_norm_kmer::(self.rolling_k & 3); + let canonical_k2 = entropy_norm_kmer::(self.rolling_k & 15); + let canonical_k3 = entropy_norm_kmer::(self.rolling_k & 63); + let canonical_k4 = entropy_norm_kmer::(self.rolling_k & 255); + let canonical_k5 = entropy_norm_kmer::(self.rolling_k & 1023); + let canonical_k6 = entropy_norm_kmer::(self.rolling_k & 4095); self.received += 1; @@ -175,107 +257,147 @@ impl RollingStat { } if self.received > k { - let old1 = self.k1q.pop_front().unwrap(); - let f1 = self.k1c[old1 as usize]; - Self::update_sums_decrement(&mut self.sum_f_log_f, &mut self.sum_f_log_s, 1, old1, f1); + let old1 = self.k1q.pop_front(); + let f1 = self.k1c[old1 as usize] as usize; + Self::update_sums_decrement::<1>( + &mut self.sum_f_log_f, + &mut self.sum_f_log_s, + old1, + f1, + ); self.k1c[old1 as usize] -= 1; - let old2 = self.k2q.pop_front().unwrap(); - let f2 = self.k2c[old2 as usize]; - Self::update_sums_decrement(&mut self.sum_f_log_f, &mut self.sum_f_log_s, 2, old2, f2); + let old2 = self.k2q.pop_front(); + let f2 = self.k2c[old2 as usize] as usize; + Self::update_sums_decrement::<2>( + &mut self.sum_f_log_f, + &mut self.sum_f_log_s, + old2, + f2, + ); self.k2c[old2 as usize] -= 1; - let old3 = self.k3q.pop_front().unwrap(); - let f3 = self.k3c[old3 as usize]; - Self::update_sums_decrement(&mut self.sum_f_log_f, &mut self.sum_f_log_s, 3, old3, f3); + let old3 = self.k3q.pop_front(); + let f3 = self.k3c[old3 as usize] as usize; + Self::update_sums_decrement::<3>( + &mut self.sum_f_log_f, + &mut self.sum_f_log_s, + old3, + f3, + ); self.k3c[old3 as usize] -= 1; - let old4 = self.k4q.pop_front().unwrap(); - let f4 = self.k4c[old4 as usize]; - Self::update_sums_decrement(&mut self.sum_f_log_f, &mut self.sum_f_log_s, 4, old4, f4); + let old4 = self.k4q.pop_front(); + let f4 = self.k4c[old4 as usize] as usize; + Self::update_sums_decrement::<4>( + &mut self.sum_f_log_f, + &mut self.sum_f_log_s, + old4, + f4, + ); self.k4c[old4 as usize] -= 1; - let old5 = self.k5q.pop_front().unwrap(); - let f5 = self.k5c[old5 as usize]; - Self::update_sums_decrement(&mut self.sum_f_log_f, &mut self.sum_f_log_s, 5, old5, f5); + let old5 = self.k5q.pop_front(); + let f5 = self.k5c[old5 as usize] as usize; + Self::update_sums_decrement::<5>( + &mut self.sum_f_log_f, + &mut self.sum_f_log_s, + old5, + f5, + ); self.k5c[old5 as usize] -= 1; - let old6 = self.k6q.pop_front().unwrap(); - let f6 = self.k6c[old6 as usize]; - Self::update_sums_decrement(&mut self.sum_f_log_f, &mut self.sum_f_log_s, 6, old6, f6); + let old6 = self.k6q.pop_front(); + let f6 = self.k6c[old6 as usize] as usize; + Self::update_sums_decrement::<6>( + &mut self.sum_f_log_f, + &mut self.sum_f_log_s, + old6, + f6, + ); self.k6c[old6 as usize] -= 1; } - let g1 = self.k1c[canonical_k1 as usize]; - Self::update_sums_increment( - &mut self.sum_f_log_f, - &mut self.sum_f_log_s, - 1, - canonical_k1, - g1, - ); + if self.steady { + let g1 = self.k1c[canonical_k1 as usize] as usize; + Self::update_sums_increment::<1>(&mut self.sum_f_log_f, &mut self.sum_f_log_s, canonical_k1, g1); + self.k1c[canonical_k1 as usize] += 1; + self.k1q.push_back(canonical_k1); + + let g2 = self.k2c[canonical_k2 as usize] as usize; + Self::update_sums_increment::<2>(&mut self.sum_f_log_f, &mut self.sum_f_log_s, canonical_k2, g2); + self.k2c[canonical_k2 as usize] += 1; + self.k2q.push_back(canonical_k2); + + let g3 = self.k3c[canonical_k3 as usize] as usize; + Self::update_sums_increment::<3>(&mut self.sum_f_log_f, &mut self.sum_f_log_s, canonical_k3, g3); + self.k3c[canonical_k3 as usize] += 1; + self.k3q.push_back(canonical_k3); + + let g4 = self.k4c[canonical_k4 as usize] as usize; + Self::update_sums_increment::<4>(&mut self.sum_f_log_f, &mut self.sum_f_log_s, canonical_k4, g4); + self.k4c[canonical_k4 as usize] += 1; + self.k4q.push_back(canonical_k4); + + let g5 = self.k5c[canonical_k5 as usize] as usize; + Self::update_sums_increment::<5>(&mut self.sum_f_log_f, &mut self.sum_f_log_s, canonical_k5, g5); + self.k5c[canonical_k5 as usize] += 1; + self.k5q.push_back(canonical_k5); + + let g6 = self.k6c[canonical_k6 as usize] as usize; + Self::update_sums_increment::<6>(&mut self.sum_f_log_f, &mut self.sum_f_log_s, canonical_k6, g6); + self.k6c[canonical_k6 as usize] += 1; + self.k6q.push_back(canonical_k6); + } else { + self.push_warmup_increments( + canonical_k1, canonical_k2, canonical_k3, + canonical_k4, canonical_k5, canonical_k6, + ); + } + } + + #[cold] + #[inline(never)] + fn push_warmup_increments( + &mut self, + canonical_k1: u64, canonical_k2: u64, canonical_k3: u64, + canonical_k4: u64, canonical_k5: u64, canonical_k6: u64, + ) { + let g1 = self.k1c[canonical_k1 as usize] as usize; + Self::update_sums_increment::<1>(&mut self.sum_f_log_f, &mut self.sum_f_log_s, canonical_k1, g1); self.k1c[canonical_k1 as usize] += 1; self.k1q.push_back(canonical_k1); if self.received >= 2 { - let g2 = self.k2c[canonical_k2 as usize]; - Self::update_sums_increment( - &mut self.sum_f_log_f, - &mut self.sum_f_log_s, - 2, - canonical_k2, - g2, - ); + let g2 = self.k2c[canonical_k2 as usize] as usize; + Self::update_sums_increment::<2>(&mut self.sum_f_log_f, &mut self.sum_f_log_s, canonical_k2, g2); self.k2c[canonical_k2 as usize] += 1; self.k2q.push_back(canonical_k2); if self.received >= 3 { - let g3 = self.k3c[canonical_k3 as usize]; - Self::update_sums_increment( - &mut self.sum_f_log_f, - &mut self.sum_f_log_s, - 3, - canonical_k3, - g3, - ); + let g3 = self.k3c[canonical_k3 as usize] as usize; + Self::update_sums_increment::<3>(&mut self.sum_f_log_f, &mut self.sum_f_log_s, canonical_k3, g3); self.k3c[canonical_k3 as usize] += 1; self.k3q.push_back(canonical_k3); if self.received >= 4 { - let g4 = self.k4c[canonical_k4 as usize]; - Self::update_sums_increment( - &mut self.sum_f_log_f, - &mut self.sum_f_log_s, - 4, - canonical_k4, - g4, - ); + let g4 = self.k4c[canonical_k4 as usize] as usize; + Self::update_sums_increment::<4>(&mut self.sum_f_log_f, &mut self.sum_f_log_s, canonical_k4, g4); self.k4c[canonical_k4 as usize] += 1; self.k4q.push_back(canonical_k4); if self.received >= 5 { - let g5 = self.k5c[canonical_k5 as usize]; - Self::update_sums_increment( - &mut self.sum_f_log_f, - &mut self.sum_f_log_s, - 5, - canonical_k5, - g5, - ); + let g5 = self.k5c[canonical_k5 as usize] as usize; + Self::update_sums_increment::<5>(&mut self.sum_f_log_f, &mut self.sum_f_log_s, canonical_k5, g5); self.k5c[canonical_k5 as usize] += 1; self.k5q.push_back(canonical_k5); if self.received >= 6 { - let g6 = self.k6c[canonical_k6 as usize]; - Self::update_sums_increment( - &mut self.sum_f_log_f, - &mut self.sum_f_log_s, - 6, - canonical_k6, - g6, - ); + let g6 = self.k6c[canonical_k6 as usize] as usize; + Self::update_sums_increment::<6>(&mut self.sum_f_log_f, &mut self.sum_f_log_s, canonical_k6, g6); self.k6c[canonical_k6 as usize] += 1; self.k6q.push_back(canonical_k6); + self.steady = true; } } } @@ -284,7 +406,7 @@ impl RollingStat { } pub fn ready(&self) -> bool { - self.received >= params::k() + self.received >= self.k } pub fn minimizer_position(&self) -> Option { @@ -305,14 +427,14 @@ impl RollingStat { pub fn canonical_minimizer(&self) -> Option { self.canonical_minimizer_raw() - .map(|raw| Minimizer::from_raw_unchecked(raw << (64 - params::m() * 2))) + .map(|raw| Minimizer::from_raw_unchecked(raw << (64 - self.m * 2))) } pub fn entropy(&self, order: usize) -> Option { if !self.ready() { return None; } - let k = params::k(); + let k = self.k; let em = emax(k, order); if em <= 0.0 { return Some(1.0);