From ea0104e54d97d78a3360a1e749c33213efcbdb7c Mon Sep 17 00:00:00 2001 From: Jussi Enkovaara Date: Wed, 16 Mar 2022 10:01:21 +0200 Subject: [PATCH 1/3] Clone mooc branch --- exercise-instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercise-instructions.md b/exercise-instructions.md index c055ede..cff2c92 100644 --- a/exercise-instructions.md +++ b/exercise-instructions.md @@ -3,7 +3,7 @@ Download (clone) the exercise material with ```bash -$ git clone https://github.com/csc-training/hpc-python.git +$ git clone -b mooc https://github.com/csc-training/hpc-python.git ``` The external Python packages can be installed with **pip** by using the provided [requirements.txt](requirements.txt) file. In CSC classroom this can be done From 883ca98df87fd6c08683283cfc37749055a2005c Mon Sep 17 00:00:00 2001 From: Jussi Enkovaara Date: Mon, 21 Mar 2022 13:03:56 +0200 Subject: [PATCH 2/3] Equation images --- numpy/finite-difference/README.md | 2 +- numpy/img/finite-difference.png | Bin 0 -> 1337 bytes numpy/img/rieman-sum1.png | Bin 0 -> 1591 bytes numpy/img/rieman-sum2.png | Bin 0 -> 1409 bytes numpy/integration/README.md | 4 ++-- 5 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 numpy/img/finite-difference.png create mode 100644 numpy/img/rieman-sum1.png create mode 100644 numpy/img/rieman-sum2.png diff --git a/numpy/finite-difference/README.md b/numpy/finite-difference/README.md index 792f139..777ab47 100644 --- a/numpy/finite-difference/README.md +++ b/numpy/finite-difference/README.md @@ -9,7 +9,7 @@ as: f'(x_i) = \frac{f(x_i + \Delta x)- f(x_i - \Delta x)}{2 \Delta x} ---> -![img](https://quicklatex.com/cache3/0a/ql_d10c99a114e66c7ed0535e0aeb041d0a_l3.png) +![img](../img/finite-difference.png) Construct 1D Numpy array containing the values of xi in the interval [0,π/2] with spacing Δx=0.1. Evaluate numerically the derivative of **sin** in this diff --git a/numpy/img/finite-difference.png b/numpy/img/finite-difference.png new file mode 100644 index 0000000000000000000000000000000000000000..62e3a316a14ae31a5b670b64f25a8c95eb943eb3 GIT binary patch literal 1337 zcmZ`(doE)Be1TT!VgM4c0IV}DfzLE&T|4@nKxpL zs26?x8B)qb4x~J8wR3UG(W%xx4674+KgaMgiEVWX&Y$9Ko0=;Q2K^?VCy-)>^~AKIhB7tCH?5Qr^j=LE z!Oc^~B7K05yjvq;%a@_*KckMtHDmNtVD!qS2cZLvuhjEf0vskzGo0)#c)AfShiuOE zIOLGp6Pj_tJ6+X>cxH+c7xAFYL8U?;R(>>B>T4aAbONg8i@@SUW9y4qH_5bs=t zSSv>&cW*j+7+kWls~`*{a97-uk3TTFkZ)LSr?u^ZuNwOpn{10V{74Z=1SxK&lD7gWJy37-di9;VJ`$ME!V!7_J_Pe`msz+cEs=VNcV0L;zW%dZlck3_W&n z$i%u9#dJT}9a8s$Mc^p)b##Th`0!#x5lN$9*?TOx%BK}yrg3ABT4jlmDDHR7%-1sA zToK|uVnyAIP4@DR!uc;5#hq^UPu4`?$Lm&w;Gb6jlc=%^R|S)g!} zzlOi+I{IHYk2otLJ)_CBipD$m}4FtOQK-sXdBxzS2nfXZ0wWm0wyTj~=|=RJR$k$Pk%O%JV7O6`NLFVwx1~^qiBLw$gT6u%?jbLiOhI51OSJ{;Y_gRCO9)MGXfEB o1(gw&K*VA*uPajj6NrjoMT92*e_(yMX#)xX8pVzL@Owt)zrm?lr2qf` literal 0 HcmV?d00001 diff --git a/numpy/img/rieman-sum1.png b/numpy/img/rieman-sum1.png new file mode 100644 index 0000000000000000000000000000000000000000..ab919d125d5d75ad7cde33b109d2821aa6e268b4 GIT binary patch literal 1591 zcmZ`(Ydq5n82-mZt6ZC0hG7hi&6L_`+1PAC_>HA<8^exr-IPnYllv`lKdU&ZlS??= zhuEpf{d7@LQevUfj9i+|`glH^56}Dj-skdrzrERRu8upwT3`SGc2X%09#R%dp`ieh z&JeCfo|Hf#1Q!AT+$`MwBS22N!vZNDE&vd33;@aL0I)8Vl7#@kK?A^?KLFq=0AP1y z%{_NpsUgES?C1de%qkq{l5X1~Dc&&vpveD)EoFNYwWXpwo9aT6pOJ;A*}ySLm8sH$ zKd24_TIk!)Rj)V`*1Iwft=0ptufg2pJ3I(i75y7iyLBR6owzn!oZu3U>!jS67G>6o z)tRu3)GPvB)W^QC2jM9)UsCn%XalBGw_Lnc&y_CaKY#F7<;s^Ct-7^uw+34#!@EXR zhFf-unk0Go=ia5YnRz}8vzH|8=Tt+RkjjflM^8}}wCtm+;`X?-n{J2jBCBd}>qK$% zk#29@@5R`H8=B*po5s3LdzD0j7P!-reL=U*L!xi5MEEWQ@|Mx5BWX}A``$^UN;F|5 zEr~O}x^eIOEpUzK-Y&B`a#yHly`&Y+=R0T^1V|inAS3A-7y`FD-c;6u;k!UxyByR!y%6EUN&T?AjYbyRU2#F;r=G*&?nZtP?VoPD zE{vO%9Yib1aI!i@v#-c9c_wfv89lHrkAD9d<-77@GHZc`58r)Qs;S5YA*y~ zbMAEzlf4+aR&&XH@RIUbo=mv;v=>>Hia+cd6(pnx${{i7KEnv8=0`g8y|sUHy+cjicEbW*BGdQvp$28iX5s9uTZ1G(P&u>|M%h!>dauc z;fof~lBuR3IBXI!lZDO+?e2ous?3+Yv|a;Wa#6KB_mjYyi(wkL}= zh|X{MvWPX@P&=43w0q4OqaO1(U_G0Vef1#vGzTl}FCI%ntWB48Y|NK|P2&8zZu4tW z3g6#dr&kf*eqT4h_YGL3JXvFJ>_?UrueM@Ai2)nMI2BhbG z%07f;-XcuHWAfwF!n|i}?%}*Gsl^}p&oa2RUEX>p#ZCjw&E~?SSC$i`2ZGAh&9O^Y z@f2IM?Rn^`-Bf>aH0>BEkdxY0e_L_fDW)jP*Dsm8v|s-SkT`{6evC3>D{Z>_8_kf% zg2guR#B3G8{5aj-OHNnJx&7#aS3*LBx`}a?Ap!Q#6;E=2D}0KcP^&oZGd}Y5Xr5`W zyi7ssu408^kF^^hEZ5VarmNaejD;*TTX5s>)nNk8UXbi?2ZDo$Jq*-Ed`>;4G>pf^J j4vqdnzzY6TI294Z3Xc2#LOwKwEiC|4lB+{A(LeQHvRcMd literal 0 HcmV?d00001 diff --git a/numpy/img/rieman-sum2.png b/numpy/img/rieman-sum2.png new file mode 100644 index 0000000000000000000000000000000000000000..eb070788b8755f791e226073e7141725c5c19c15 GIT binary patch literal 1409 zcmZ`(S6CBf6#db#L3TlqO&CHn3=Y(<6Sg#ZAeSd5i306a&zSV{oG z?WXjSAnt%rEbJ`+sLv8U!1Hps3K8RM4?wgg0P)EH>~p2~1pva~04(_cfVvBSY;a+# z6Pmj?LcrNtfy30S{?}Y47>w}<1K?QKkK(zldrW~V^3$;P*8FovWu$?KDYCbld(Z}J zW#Q^OJ$rvOd>J8fU3rTH5bAIR?N?H+@$f;N-A)7RHi$V$Hc$VosozRDVjufma%LV|6<9kkb!Jg^z34UcxR|a) zqhID+iI!mDr2ME~V}#en-GpSh>7GQpcBGe==kJI`-7x)I3JwQ)XB{+dr;sGQ3s|^Z z2qWF?qa%gb;e33eR}<~`*31}8wa%Q}gLa=3QnjODO$EN^2);Tj`OKzu$2*-X1R<`?ac?~#hb#Mrlo?}2WqOg zUyYl)_R6W4d=T>tvi~KKfz%hx_e^imVn#|Iu}n!jBayF|5EOUCV$L@tEQs<8oAqXG zs$O#EE;Hv^i*1ovO8i*8-_;x_q-wL0NtY|FMjQ6A-Cu+~b%81)PD|L8_&ACPVaKa| zHsYit#bPk%YabxrHAemTwA6KkRF~a~m2?J_rjY&usT=W7sHS4UM@HTWMoW0y^!9I# zcPjSElEcH#M62EoGXDMBqpuoU;B(&4b`dFwrG3tEn{q+;=OBQ6ikdXEvE6dxn$eTMr?~WC6XCKpOCdE zG5#_NQd4OrvqU?2VBl)&OxqkqIz{ecV3+u^m>}HRS$bJF{?}fjZneAHJz7zN4Pmn{ z045sZgL|Vm^!WDup;X9N&*9)s8OgtrKE9GN&x7vYt>WwV&Fkl*zBkW_H~lJ$DPQL_ zW~k2H;x!bBi8YBPw7(=g9G*bmF}zZiUDu)A#e9$CuZ+M;;d>91)^G6$IW9b=zJdjk%SQCKyIAOYZg7PmPqOr#2U@PAxcyIE56k z2Vwbj+LbSinrhMO`4Z(Z^cib}KmC)3B*$sMW53xUbW29S=FZXveSOQ6(nZ!uI_USK z;McIz>=3q0^=bJV78_PcE8^?d$!1wmR|MB<9V%YT;_VBo$Tg0+2M8bl=ODy`k zMzhTqP8IV~nZ6*iLLsE6GQsnW%*^ikyz~ysmeGJWo-IhIJ=`8SGz*A4yQCgEvh z6fu;{9l!u?U;u*~!VL6X4d5s^9Hnod3;&r5&_xZ3{|N*Hk*HVb{~xe#7kbDI0Ic-| Ks~St6#D4+ZUvPB* literal 0 HcmV?d00001 diff --git a/numpy/integration/README.md b/numpy/integration/README.md index de2993e..857f76e 100644 --- a/numpy/integration/README.md +++ b/numpy/integration/README.md @@ -7,7 +7,7 @@ sum S = \int_a^b f(x) dx = \sum_{i=1}^n f(x'_i) \Delta x ---> -![img](https://quicklatex.com/cache3/e2/ql_30419670e67bc2b3d039e8a9d8653de2_l3.png) +![img](../img/rieman-sum1.png) with @@ -15,7 +15,7 @@ with x'_i = (x_i + x_{i-1}) / 2; x_0 = a, x_n = b ---> -![img](https://quicklatex.com/cache3/09/ql_f124fd5c831e873c6abd41160fae2d09_l3.png) +![img](../img/rieman-sum2.png) Calculate the integral in the interval [0,π/2] and investigate how much the Riemann sum of **sin** differs from 1.0. Avoid `for` loops. Investigate also From 4621f51801e9153e1265844ef159071d2490c12e Mon Sep 17 00:00:00 2001 From: Jussi Enkovaara Date: Mon, 21 Mar 2022 13:16:55 +0200 Subject: [PATCH 3/3] More equations as figures --- numpy/broadcast-rotation/README.md | 2 +- numpy/heat-equation/README.md | 8 ++++---- numpy/img/heat-equation.png | Bin 0 -> 942 bytes numpy/img/heat-stability.png | Bin 0 -> 1221 bytes numpy/img/heat-time-propagation.png | Bin 0 -> 1400 bytes numpy/img/nabla.png | Bin 0 -> 2772 bytes numpy/img/rotation-matrix.png | Bin 0 -> 1676 bytes 7 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 numpy/img/heat-equation.png create mode 100644 numpy/img/heat-stability.png create mode 100644 numpy/img/heat-time-propagation.png create mode 100644 numpy/img/nabla.png create mode 100644 numpy/img/rotation-matrix.png diff --git a/numpy/broadcast-rotation/README.md b/numpy/broadcast-rotation/README.md index 03aac56..c043e6e 100644 --- a/numpy/broadcast-rotation/README.md +++ b/numpy/broadcast-rotation/README.md @@ -11,7 +11,7 @@ R = \end{pmatrix} ---> -![img](http://quicklatex.com/cache3/9c/ql_ee4015bef241c06a5119104118f9a19c_l3.png) +![img](../img/rotation-matrix.png) where θ is the angle of rotation (in radians). Start from the x-y coordinates in the file points_circle.dat and rotate them by 90°. Utilize broadcasting for diff --git a/numpy/heat-equation/README.md b/numpy/heat-equation/README.md index 5f14513..96b30be 100644 --- a/numpy/heat-equation/README.md +++ b/numpy/heat-equation/README.md @@ -5,7 +5,7 @@ Heat (or diffusion) equation is -![img](https://quicklatex.com/cache3/d2/ql_b3f6b8bdc3a8862c73c5a97862afb9d2_l3.png) +![img](../img/heat-equation.png) where **u(x, y, t)** is the temperature field that varies in space and time, and α is thermal diffusivity constant. The two dimensional Laplacian can be @@ -17,7 +17,7 @@ discretized with finite differences as &+ \frac{u(i,j-1)-2u(i,j)+u(i,j+1)}{(\Delta y)^2} \end{align*} --> -![img](https://quicklatex.com/cache3/2d/ql_59f49ed64dbbe76704e0679b8ad7c22d_l3.png) +![img](../img/nabla.png) Given an initial condition (u(t=0) = u0) one can follow the time dependence of the temperature field with explicit time evolution method: @@ -25,14 +25,14 @@ the temperature field with explicit time evolution method: -![img](https://quicklatex.com/cache3/9e/ql_9eb7ce5f3d5eccd6cfc1ff5638bf199e_l3.png) +![img](../img/heat-time-propagation.png) Note: Algorithm is stable only when -![img](https://quicklatex.com/cache3/d1/ql_0e7107049c9183d11dbb1e81174280d1_l3.png) +![img](../img/heat-stability.png) Implement two dimensional heat equation with NumPy using the initial temperature field in the file [bottle.dat](bottle.dat) (the file consists of a diff --git a/numpy/img/heat-equation.png b/numpy/img/heat-equation.png new file mode 100644 index 0000000000000000000000000000000000000000..2cae86bdf0705f6b2ade7d0f2dd21759e8795b42 GIT binary patch literal 942 zcmeAS@N?(olHy`uVBq!ia0vp^p+GFo!2%>NNn{1`6_P!I zd>I(3)EF2VS{N990fib~Fff!FFfhDIU|_JC0n}eGXIG#NP=YDR+ueoXe|!I#{XiaP zfk$L90|Va?5N4dJ%_j{MWH0gbb!C6XEGojo`RGNl8&FfRr;B5V$MLh%ZWrD*5O6(T z6~nNI&#C;t5!nN>3X{2*N*Sh3NVHnu&2g9UuA@`AL#aTZY>wT5)9pi>gNyodS!xS2$_q~i0y0)v*IEYuQ;l707F8h;Ol95lQwKW_L zND_6L6F*_+PWhuJ(x!zfE)2`Oy6Daeu_YJz68(1}b70nCi_fhw^Q&f0ijntQ z|2<@HQ1`dEkGD&t;(9`jQ#Z_&{mCv_S7thG)7@n%fg(0DoxIjQ5M!IY@Z*%aW0Sun zw+Ao#ul`B#!N(RmK8YfkzNP{}9sdK9t{2%h)C z{k+>nxtRg(58l>DeC~RGOy%#TsDlC`vrbq%UA_zVb3<@6id1 z4)dMb91+jCRq}{)ue^7sKz|rV@vfXw*}J=2ZT=WMo*jQ8^HO7=h}J6Qy>8)l(%V-q z4i;YYwN(0SkWlS}kWG5_XH$5V9GEjh@9S}u&jy|I`q@oyx5WhM{Jd!}M_}<=S$~Cf zyB%-ZcV^E$9)BdeH`l$d%ixNn?fR?5I|Ytz(SPFMxpZ~7a{HqlmrXqmAHTe2pMkz= z&WalwAE|2_)fL*`^S7xy)06(~L(QTj_B%nZYuT?}6xHFp|FbK-_)AW=nP+>-uS3^< z-CB_l_~Csx&pc6Z(`u^z1AM2(2 zyzX*&B=FBT=dHRtWq;1vs>0`m)!hTQy=%(P0}8r;MJEr1#rJYD@<);T3K0RT||gHiwh literal 0 HcmV?d00001 diff --git a/numpy/img/heat-stability.png b/numpy/img/heat-stability.png new file mode 100644 index 0000000000000000000000000000000000000000..9a418e2515ad5bcc70ad8ec83852dc5d2165aca2 GIT binary patch literal 1221 zcmeAS@N?(olHy`uVBq!ia0vp^-9RkQ!2%>}pMO&XQY`6?zK#qG8~eHcB(ehe3dtTp zz6=aiY77hwEes65fICD#?XB&vL z+NTCJq%|=vi{?n5oIC&BjI(aCWebe|>0J8D?tkjoG1oxT z`^UaN)Hxq*^8Hh-W8a%Y)$`t5=6u~WZ_cD$|D_$K)|O1DTybrw@H6Hs(_+(B8eHBg z=j&oFdN%05C9dR4F^e=VY?)!VQ*B$b!?Dgjy^Y&`O#Oc_E%VOq9hbZha@u~Aes#Lz zQ{bV9kW3q8ckL^SwrQMpd^y$TdiMQ$KW1okUy@lqrT*aw{|UwnZQ(EO=kl^@Juh|m zH*dyyPXGCpD_mpvs_x5g)B47{c&Uu^+eN<8EWJyWo<9jn=QUO1w`8xMrkVdrPuG&S zD6-|+zUYNrNo6xt->+u8d8*&EZ4#69wi~5W8kQZqR5ew#{CZ~EO7>r_dlI&BUCt3Y z8#O1^#^=3(PgD3}nW%^>E45A@ja!qlxA4!60|6H=2IejoY@4QKmdGROGc4T|K{aGq&*Q}%Ujg@94*C7@()HiniI%Zm0bZGq0F*EBj{p*PhUsGIwu1cx3VE zPmI+uHNB^pT=^w<(RW>H)Ui`WaTyz#Zmkuv4RMv$?w0WKn$_}cuX8NtYqkI9 zS{z(GH(Ky}_@8AI)(V}Xc)2HfOU2~-%h$D(O#Ytms(o#L21{d8R?fZISGM)9yxLwC z{HJyAw&2*C*L?3aYYN?XsXnc&`jKALhKN($Th2b~c3g8nGvtcl<+__^dOqp-yic3f zak0&1vDCIdXOoPsuh3q-%X5mRXXDQPz*U*gi)O{G`(#|Vf7hm^vs-2ciO#5&Si0ba z`J}%`*#4jWR0|bvF=2i7ENY#R&B^XdHSEhfKD2I^%vrvRDd(k{3p!sW$_k9>a2SE{O$(K6$bh=gi?-=vxP?ejhtEZhHT ztxjy#s$WXLjH*=P8c~v*pPQSSSHcjKnwOGVl$xTDRH+bHnwgyKlNgd3p$C*!@Vu}M zs9F`IIwi3r)hf9t6-Y4{85kMq8W`&u8HN}cSQ(mG8JK7rSXvnv#FuN>p=ij>PsvQH W#H~S3YeExH1B0ilpUXO@geCwV;u!M) literal 0 HcmV?d00001 diff --git a/numpy/img/heat-time-propagation.png b/numpy/img/heat-time-propagation.png new file mode 100644 index 0000000000000000000000000000000000000000..ec2e024c20a48c671e9e68a54291584be524d488 GIT binary patch literal 1400 zcmZ`(Z9LNn9RKGridKl5hb=DtIBq7%s?F149_DGyt_?EQl^1f)rwIs7xej3S7HQmr@5Ldk88W8a{BljKd7n18M40 z0c1LNMO9*^wGX1P`WQF4i|WgJ8`WMk^>n;*xZE1L8mAZ1&!6*Z26Ov4PEU06$V4aT z%Sddo7EfHcY)O)3D2zbE1{=DLhW=I%ce5+Fu*YIF`(7lujljj@>)u=Pv@edUz24>Q z6VJ&~-Kwe3D~g`gTfetD!Ylmd_l9CERx-L7)fV3|!(=`Zp21&Fg7~WtM?&cpZLP4Z zM&Y@TglG99ixpqj+&ORZ5p6sN$tqi3L zV|tnfvKXV|#gztF3M?QZ>^ySzeoD#3#<3u7j(LA*DME%Yt(s~572?uQ#r(7?>ziq^ zNU>COnb5XVchdauv+mk>Zbh|T1ldsl#ztlHc_HbGM(Co-J1?ZtX=9gbwRW$fWW(tR zpZYGOj%L)r;=qxErv&DCCzjlIvj@O%&mk+H-KLpcqdg6@!IRHIUY%Jz`i`j{70&pj zyK0J17}?RlZ^`)7mvAYh_uue+Ppi*sW9y!$#@O0J;+Ccz&jVsf!oPF*jW#C`1Q97C z|7zwe|M)$9C2NqLJ^!xu(O%HQ=w;vpwp2cE zCZ%G?wDnPYF;m?GJN&4wu5Kgwl8b=C`{URKb3IIv-6FZ&CnGUPjQOSu$=n6UZ&ygd z>Sia*+Mu8eSs>d0F}kp7$?mACmWsL`hCA|BI3pI^O||W{Gl88fI8pgq%-Ps5HZ?gh zk(R^;f@w)HG!`ue9?gLVrN&Vc{3rxkn7vYl<0fw?-TS||V<>DIipruX2Y^H%k#-12 yJEQ{vi9k6VKsh?vB3w`i1mw!Cr2hmGlVjq(=lp+wBIisi0{{+-_iT43=lugo!*O{4 literal 0 HcmV?d00001 diff --git a/numpy/img/nabla.png b/numpy/img/nabla.png new file mode 100644 index 0000000000000000000000000000000000000000..6a0cc87872d2685af171b444e44d4779e96f1256 GIT binary patch literal 2772 zcmZ`*c|6ox8~<6eT$C{tbConm(`XP`8by||*2qpGhMJ)f#$Jdll_e5mi`*o$gjr_)Z2AbNN0zhq+^mkt|fvn<(a&9TkPSA zfEA?n8?wgr1ZG5Qb5p0N34RHmP|+=)@?;`R#D^Qu=AVGv=T$7UVP0b(vhY!2qg$~X z(wae%LrqBPa?gP3 zUpQ~=R_4fjU~#5M>Yu~d2I+~W8qg|n?lG)}zpo1K1TN_y!NUPb>D@i6Mr?uT=lvDM zju;^XH*I8H?0YjoehM@292 zZ2YvO@rPc!x{bLSQ)<%Dz+5*+cZIIp?>slST*;v6PC7JiBLCy!NO?i6YBjIjs5 z2Lm1Vp-ldL&ON*nBzD+6kgc2heKM;fkdAziBY)hDuf8$IWO(+?BQ`wveFU32zog63 zp>8r2T@>Ei@vFkBPCu>Z0wiroHNA=yV^7B$k+8crJ@G_$KEnt)db20fsHpk(2u{Qh zYj>diavPC&JXbWm7@QgoA9= zY2K{nPpk#mg~IPJ>D7JDrfK7SzO72gpebExQOO2pxy3|77;@L-es=#VK1$3wA+qJM zN2V!U?MB0}@{K5J+@D`uk4WP3*5!8b_9T{<<*(e$yHp4f&z%&Nr=NIdj6(IFOm{mU zoWS~|;j^E*)w@(HD&J$XaoE1|MC4)UXN&rM>E9l{Y*KF=DZ~w%Yw7l+V5f9BmEOar z0qQvY_qOIhb^i{I>%lh8s0S(Ete6*ORrPnP6Gjr zIR8+7v^Q>4g%(37`GFugU}bCu-#+p=oycj`y_Ye8BREiXYtei)&r3Y4c!iQ@ejK6p z`THd;l_T0{_LsmHvubn~+)dKnr)g=VfWX1atr0e)uuuk^h~xbf$99NV6LK^(SHBuLfILt>cxp*vrlM>L+@~lKZjBjJ8i|lPj29n-?-wX z#I&yuYQA+>`D5Mq*$3~p&avv0@FPT9p3UR^TA+ZqOT5>Rd~EaIujR9=_iW9?FM?-@ z^QsCZKjLpAc1(8^>0Jg#CXo{VwBKj-WX&(mlxb?8OeQ~?&G#M_fgL)eaWOm+#5^+D z(}UohfLO9SW<~nO*4|irIvQ&f8uO;^Fk$sge!#Qhb#08+zLf~&7*R%5(eXLi?xzaO z@p66I>MJLOFnwUlhwW%T;I(WK44uvJ9NAew9Aah{NPOe0y;J4uRxAc-u1*!Mb&F}b zlB4#tta3+*n1UMsb(VD3ZWxK`H@kI{g6^xztPZ$7)^bb%x}$iN{ngq-O2%>v#0G{p zb!(}%a9)Spy~^ygzp?H+T9{#|wkjh}iZJhB5+We>N2g-}rS%L29ja6ye-?+S+TskT&-tsKvH)n(0N z^#o3fv1g{pQ>$3A+@nRw+=fis96?HVi7cie{R{(SgHL@zAed@;{> zDOx4|xQ6E0`y{*5N8?qUgjWt#W*goQuCXzZRrhGmW#wgS!n_j>fA0uAaOjc3+tQJl z5(*gAPpO-TS0C8M`)vm;hcR8s9!I>4%MVHR-9!qUkZ$ek|GcQ!+UQai`^}fGhk9LE z>OZvH`-m}~_eA>7aSw9{k>!^Xsh{=d%zV(H=62&EEBrEtI|yl_MX#kK8hTD!>;Itt zr%*7L%8J>b$q3DHfXp+Br9FCqwG$!@zCENz(qQrjSe(mb=sj&Qa!UJVl{>PQQc74) z!;_2*B5TdEIo`HcPVZlzawr{hd9H3>U0x^KL8KWz_Z~LS-d*oxW)MPVf=Vv7O|*d~ zOLIHKG0NMJWA`(eB2sQ7-yzT>*3C8cAiRF6kw!2V!Yu^}mg!<`uVptfW2TqigT=_o zEBt2yDuW7M2`)cBjVyW!ksA9M%e*N+SxTeY4{!tYCd9u0oAVowq?Pg-Xy%$2VqWEXKs&&J*lDk9@!(X!1EB6$H_%OkgAmLi2%D5;T`< zy_Kiw;kwb3RQF`V&SSw$XLLmQ;(+*%R@s;T1qx`<4;10D6?xyrQ;x3awu3K- z>1Szo$W;jP(|W01t$?z&;aFs8gDYw`_Jn08+asgk=%g2&B~3vCIfz*2>Q3@O2n9Zq zI_ToV(ensUQtLkd`J{77%f9m5y%`a+OJN5f)IkxuirTHxG~axO80JlmL1udRX_GpzywajL0tWn}uMl_ZJJvr?K8s=lI475_y+!|6txQ=UG6H_x=fcp87Mdt= z)oP)(>)%+%HQ2ScddD@FGp;m_%|AnAa3^8}FH*4oVy5!0a2)LNM_HYzQNh1WHQd52 z+z%fdjJXjGIAU)2V?r_hDp#Xb(1h!LI6Ge_jGLA~tz!L-DX>=iW$o`9jxq8J#RvvK z2ce?_N9e+Jw4HPiM%oA?9UU0L&}P|6md{A7@v>%B2Jgv2n5ifTnEuzbLX&tsUe@b^?F|3;aP*D>0EOrOKqeonpdmHEXp)m1I0scZ2v>&? zHcJ3N)|EuGai>o#-W`sqGexFZf4B|tD!ghQuv{NN0?|H#X@##OxyxW>>Nx`c2s##w z1sNj(2^5az25IEnYf0>tS907j;s&GthNg_)(436<&VRjIZ@D13CzNbfEU|yR*?{fx zeF`g<2;IZ2S;r&tSM=)?*T3&9jaz#JDHK-QVz3h)!Imu3a@6R91+em>6-KAGE~>aQ z>Z(Ps`4Rj+)c2qExAsv=)*m)T%4MD@s}C$qE^+b5n$MYvqFZy!IU!F}FZo)dTOxfB z6GNKJ^9O!CYd<;~A=~fpBJ&z|NEnv+Wh%4Wd&L*VHo_+n2V*_U{Z?Rp}MHdOne#&yG<9_Lu;{!qZln@@Bslj2jTWFEzL93duh*}P^ zsou(U^?r>5I7+2bGv*J!BUvaht62iR7*%K>G=05js<`zo8VgY@u+uY^+{;G7XW(GR zDP4MD-smT#sM((D?3A2}Pk2S|4i;?5BssAscmD84`;UPQ77Whahy z;f6_n45VB}A(l7xYWN_E!L5P*#9Dj%I+dW-%0%iwnx1UuN8#(WZT>7$I5LRKM=Y=X zTO48k-aEPnnjfqGaQP*#b>g5Nxj)U*Zy{Y?6>wq?Du{NP%V92uue^LQ<_9L7PkX!I z8_(ar<9t31b(_aqE~`xF4S9L`t8&qlt8nscQypYx|Z~&A3@xGVPuhxT?A0W0hf>4G_N!uO=AT_F^T!`RVO9F4WqxJUxbbE4yIv z>&?^PI8EWQu7$W?JQnJAi_5L2kn^$~hLdg~h6Apzcx8(T-uEoBN8-+nM|?Pruz&KR zI_Az?fBBF83V-btT+^%~2|}t3W;TbHr-Ze=#4m=WbW!IIZ&&-y$QC(0Bxy`|#M#~m zY~KC638(7f66wu4SQUeyTYW#yIUs0TmN#b{1_aOzWrSoA-LksMp4Q5IRE$p8Rs0;b z6i|rz=C8WS)lq_kk!^pz$ZMuN5R0zyOe&VHnCBnD%;pv(uBEpI8|`A(bq|a&IO!+u zf-=lLW?j1{E8D~|5i=4wyFT9IHXA;IruTz@iVWsiC#ce70M(qC{{vG@uc|=(uw(Wu zWStUT#mvQ=ISt*I%&R7A#m`<)5g$<9I-bT^L92zfWxd%DX~Z#Hu&%&iHx1 zH^$SH47D8RyER_LH>_x$VqX}TP*GPR# z*==I+#5R#WmluwDY|PEhO6cCN_-f&LE%Q)aN(eaSTd}gumy^j|Q-q4YPB)nC?h=uW zx-mUlsU5J9-u5=ez@C*NY{zAg!}obOe)P8#HP)-Qlh~B93MF5;c2ld0t`fDn1c4;Ko3^`eR(;NI^NVlzRq^YS- z^aT0~ZakZnEGyd#ZA>56{`Sk<^mw$vsilIJE;pD!p6Ow3#ITMbTlugV<$irPp3O;^ zM{LS06hsW@%!|ql6=ln^jlyY3UxiML)^~p1od&4wlINY<-u-YxlO5G8%4M1co&7JWUJ;!Z$^kXnDsO>53Qw$82p z;@`ZGt4p^yCVkNWD%#E~I*1t-MhlMy$h2@OEs{pn4vg1!jR_56oTs?cy!559HfiXI zw5|J3n@WkM5rQIVQUdTeJpLr^^hvydJ03^CnG*2ESezLFhx5o9KKws}FeWuLIR5_+ T(BjZ4=>Q