Brobdingnag/0000755000176200001440000000000014176704472012502 5ustar liggesusersBrobdingnag/NAMESPACE0000644000176200001440000000024313762776702013725 0ustar liggesusersexportPattern("^[^\\.]") import("methods") importFrom("graphics", "plot.default") S3method("print","brob") S3method("print","glub") S3method("print","brobmat") Brobdingnag/README.md0000644000176200001440000001223114176316640013754 0ustar liggesusersVery large numbers in R: the Brobdingnag package ================ # Overview The Brobdingnag package provides R-centric functionality for working with very large numbers. It represents a number ![x](https://latex.codecogs.com/png.latex?x "x") as its logarithm ![\\log\\left\|x\\right\|](https://latex.codecogs.com/png.latex?%5Clog%5Cleft%7Cx%5Cright%7C "\log\left|x\right|") together with a logical that indicates whether ![x](https://latex.codecogs.com/png.latex?x "x") is positive. The vignette functions as a “hello world” for S4 methods. The package has functionality to represent Brobdingnagian matrices, and complex numbers. # Installation You can install the released version of Brobdingnag from [CRAN](https://CRAN.R-project.org) with: ``` r # install.packages("Brobdingnag") # uncomment this to use the package library("Brobdingnag") #> #> Attaching package: 'Brobdingnag' #> The following objects are masked from 'package:base': #> #> diag, max, min, prod, range, sum, t ``` The package is maintained on [github](https://github.com/RobinHankin/Brobdingnag). # The `Brobdingnag` package in use Consider a googol, conventionally defined as ![10^{100}](https://latex.codecogs.com/png.latex?10%5E%7B100%7D "10^{100}"). In standard arithmetic we may evaluate this as follows: ``` r 10^100 #> [1] 1e+100 ``` But a googolplex, ![10^{10^{100}}](https://latex.codecogs.com/png.latex?10%5E%7B10%5E%7B100%7D%7D "10^{10^{100}}"), is beyond floating-point representation: ``` r 10^(10^100) #> [1] Inf ``` We may represent a googol straightforwardly using Brobdingnagian arithmetic, specifically by working with `brob` objects. ``` r as.brob(10) #> [1] +exp(2.3026) googol <- as.brob(10)^100 googol #> [1] +exp(230.26) 10^googol #> [1] +exp(2.3026e+100) ``` In the above, we coerce `10` to Brobdingnagian form (that is, an object of class `brob`) using `as.brob()`. Most arithmetic methods work transparently with Brobdingnagian numbers: ``` r googol #> [1] +exp(230.26) googol + googol #> [1] +exp(230.95) googol/10 #> [1] +exp(227.96) 1/googol #> [1] +exp(-230.26) sqrt(googol) #> [1] +exp(115.13) exp(googol) #> [1] +exp(1e+100) ``` Note that precision may be adversely affected for very large numbers: ``` r gplex <- 10^googol gplex #> [1] +exp(2.3026e+100) gplex - gplex/10 #> [1] -exp(-Inf) ``` The last line looks odd \[the return value is package idiom for zero\] but symbolically we have ![10^{10^{100}}/10=10^{10^{100}-1}\\simeq 10^{10^{100}}](https://latex.codecogs.com/png.latex?10%5E%7B10%5E%7B100%7D%7D%2F10%3D10%5E%7B10%5E%7B100%7D-1%7D%5Csimeq%2010%5E%7B10%5E%7B100%7D%7D "10^{10^{100}}/10=10^{10^{100}-1}\simeq 10^{10^{100}}"). The package is vectorised and allows Brobdingnagian arithmetic: ``` r googol/(1:20) #> [1] +exp(230.26) +exp(229.57) +exp(229.16) +exp(228.87) +exp(228.65) #> [6] +exp(228.47) +exp(228.31) +exp(228.18) +exp(228.06) +exp(227.96) #> [11] +exp(227.86) +exp(227.77) +exp(227.69) +exp(227.62) +exp(227.55) #> [16] +exp(227.49) +exp(227.43) +exp(227.37) +exp(227.31) +exp(227.26) ``` Signed quantities operate as expected: ``` r as.brob(5) - 1:10 #> [1] +exp(1.3863) +exp(1.0986) +exp(0.69315) +exp(-2.2204e-16) #> [5] -exp(-Inf) -exp(4.4409e-16) -exp(0.69315) -exp(1.0986) #> [9] -exp(1.3863) -exp(1.6094) ``` It is a semi-nonobvious fact that, in addition to large numbers (that is, ![x\\colon\\left\|x\\right\|\\gg 1](https://latex.codecogs.com/png.latex?x%5Ccolon%5Cleft%7Cx%5Cright%7C%5Cgg%201 "x\colon\left|x\right|\gg 1") and small numbers (![x\\colon\\left\|x\\right\|\\ll 1](https://latex.codecogs.com/png.latex?x%5Ccolon%5Cleft%7Cx%5Cright%7C%5Cll%201 "x\colon\left|x\right|\ll 1")), the package can deal with numbers very close to 1 (that is, ![x\\colon\\left\|x-1\\right\|\\ll 1](https://latex.codecogs.com/png.latex?x%5Ccolon%5Cleft%7Cx-1%5Cright%7C%5Cll%201 "x\colon\left|x-1\right|\ll 1")). Suppose we wish to deal with ![e^{10^{-100}}\\simeq 1+10^{-100}](https://latex.codecogs.com/png.latex?e%5E%7B10%5E%7B-100%7D%7D%5Csimeq%201%2B10%5E%7B-100%7D "e^{10^{-100}}\simeq 1+10^{-100}"). In the package: ``` r a <- brob(1e-100) a #> [1] +exp(1e-100) a^googol #> [1] +exp(1) ``` The last line being numerical verification of the fact that ![\\left(1+10^{-100}\\right)^{10^{100}}\\simeq e=2.718+](https://latex.codecogs.com/png.latex?%5Cleft%281%2B10%5E%7B-100%7D%5Cright%29%5E%7B10%5E%7B100%7D%7D%5Csimeq%20e%3D2.718%2B "\left(1+10^{-100}\right)^{10^{100}}\simeq e=2.718+"). The package also includes some functionality for Brobdingnagian matrices: ``` r brobmat(1:9,3,3) #> [,1] [,2] [,3] #> [1,] +exp(1) +exp(4) +exp(7) #> [2,] +exp(2) +exp(5) +exp(8) #> [3,] +exp(3) +exp(6) +exp(9) brobmat(1:9,3,3) %*% 10^brobmat(9:1,3,3) #> [,1] [,2] [,3] #> [1,] +exp(18659) +exp(929.93) +exp(47.249) #> [2,] +exp(18660) +exp(930.93) +exp(48.249) #> [3,] +exp(18661) +exp(931.93) +exp(49.249) ``` Brobdingnag/man/0000755000176200001440000000000014162031142013233 5ustar liggesusersBrobdingnag/man/brob.Rd0000644000176200001440000000476613762776702014512 0ustar liggesusers\name{brob} \alias{brob} \alias{as.brob} \alias{is.brob} \title{Brobdingnagian numbers} \description{ Create, coerce to or test for a Brobdingnagian object } \usage{ brob(x = double(), positive) as.brob(x) is.brob(x) } \arguments{ \item{x}{Quantity to be tested, coerced in to Brobdingnagian form} \item{positive}{In function \code{brob()}, logical indicating whether the number is positive (actually, positive or zero)} } \details{ Function \code{as.brob()} is the user's workhorse: use this to coerce numeric vectors to \code{brob}s. Function \code{is.brob()} tests for its arguments being of class \code{brob}. Function \code{brob()} takes argument \code{x} and returns a \code{brob} formally equal to \eqn{e^x}{exp(x)}; set argument \code{positive} to \code{FALSE} to return \eqn{-e^x}{-exp(x)}. Thus calling function \code{exp(x)} simply returns \code{brob(x)}. This function is not really intended for the end user: it is confusing and includes no argument checking. In general numerical work, use function \code{as.brob()} instead, although be aware that if you really really want \eqn{e^{10^7}}{e^1e7}, you should use \code{brob(1e7)}; this would be an \strong{exact} representation. } \note{ Real numbers are represented by two objects: a real, holding the logarithm of their absolute values; and a logical, indicating the sign. Multiplication and exponentiation are easy: the challenge is addition. This is achieved using the (trivial) identity \eqn{\log(e^x+e^y)=x+\log(1+e^{y-x})}{log(e^x+e^y)=x+log(1+e^(y-x))} where, WLOG, \eqn{yk^{g?{]绞+@DDDO"J+H;J}/QX"Po,-/ ĎD"d^C"`t@Sl1 }]=T̫~b@D"0(}-ۼ-DH$zHQŀ(Ė}-J}i"H$UGDaQ2pco*EH"w!v%E@"JkPj "ŀ(4STaЙ "b@R* e *DI$C*v\#>9O(W*B] D!8T̯_d7^l/C>eb(<ʀ`da-ކU_`n@#V6_m*^TꐽH/ 42 (+o@Q^l|w|!" %~ŪқRy.ΚcT)$!PW~tZ}{bxy JRHDPTa`TNEۀ}MY,(`D"\Kc3kJI洹c9bWߛdqD<DRJpx̯_ҴL bmO\MnW.%00 ʀ`LT̫!T~\YNaamHɢ( |2 (N =ѳa[׳dE/D>Q0sWw )ISb+>YY,c*[ &K1xeize(ًWvލ/@KY,#*zY3.T_:LuX5 -"00 򀪠0oNNp- J/ayB4wV&/")r;iܺPQ4IQ:H፶tK2 P)_峔Ϋ[np_I,ʈ``@$Ae@P^X57K@tu#V6}oyXY,҈00 rIUP(‰c/Ŝ($ͰdF"TL<gߍ#Vֵ=gn@P4Y9&AU1_GT|DYQ75Ԑ4YUAAI̞x'!GM[xj7 ei#Ȅv784bchh{S<"s (n)KUfFw(IE1DYTcJ޷J#kp;V5;y>Q8mµ8e"'IkYE4Y (To[Iz佁d^j;9"KU@P^8k퐣fOXtYlR10Q58BIԶ+X|R10HQL< aTd%>;lCbEd/䊏*I7mk[DP_G^@Im}oJ%Hc`@n;_uފ҂j%iR8ao&%hb`@*(8l|̯_3G7?k (4Tœ[1mJңlƪBR:=& H{r28}uliyeΫ€iMEPINz{1UM,vIc HKZ &8 ꗡfiJңLŖw`('^ C&u 4beXXn6Tye9r>++и;{_Wb eϚcT$="+흟v5zvIE2FU@0$,_3GT^n/XԀtz,)H w҂j̚xf D4d{Omk\Iz,) W*D!>0c9-®Jc1M~b`@PJpx,U%(I+ ֶ5߄vXT_TcJb^ݏ0%w O,k 3*ј]sC*kXtWrjϬ] rEbyB/oRFv0~ Ɩ$=" %{λB˭N8P.>sjov]Xt-ַ=@(fqN*00 )j1S_&\" /q!_Pu\QmU`DY o=Mנ{E>5rDvȧ`~2Ԏ8]IzDQ1Ƌ-wr{g MEP0sjovD:be ޙ|, Jq+pQ?RAakX޸bqOv00n\7*PQ* ʧbL00 C*e/ GD7/S *҂*̚nL}m7XP6@vCq~\иޔNU10 %A 0~K+I51" Sr? GDw&UĐ8Np-N%E rED*Y卋YX=Q$UüPV0NA W}`tZ&⅁AL &K2QHyb $cu "NE@PQT3kcFՅ rDD~l3M)ޙUF10(nLDٶw ܽZ:-V 䃂>sBE$%y""]p{g2 BTL(; ꗡ|;né~XD P`vM8$ WD{7beӷbu BN6(OıbNbnLc[:x%Z{)pc`R*Z T0xQ%SCXm;QTKpDG䈈oh7~3^m !XńP7r;d"m<tZjƒAyB_%̩ՊrEDqQ44^I*G 4l;亥.=VA(l|#;b7R.> sjoŴ+5wݏRiC^D\g b[*X 酁&dvskĈrEDd&<]-r)*6!,[qe'*3JJ*)x $,Ü[1  ""L󷹽s10l@PWS_&\RE""R,߶;{^NUHvw0%y""B Io{+riy&/E] rDD䏁d^j;1BmOXt=wQ~g܂ E"" hضzKê; SR* GDDzIWXt=zvI*L= U%0~ &W|TQymHbUdv':rEDm}oJtX@8_uC&"Bz{EۿI*Vkr$6r>/刈(Sxx;J՛;  F9q;d""]X|3w1S_'^퐉ljyytXv? sED흯BVXYb``B`S~jF(GDDu`{;0JU_n Ho\X9q;d""t 4beXT:10Ƞb;.o@Q^\+и;{_J#L<gM1*W!""mWgh\Z00ƗKQW~S{vc SӉy Ɓl@PZPYc/C"(WDD$cw;xj7^RĴj@&(8P_0WDD wv/Vl+ nT(GDDdjk[oBptbTMI` )yu?”s刈;ԆUۿ's K1 dkp+(R+""ێWи]+҉x@2~ sEDDA(7.D{RD^` }!(GDDd/^y7^hUj{U"CvDD19؄g#RH` C>mµ(+Q+"" /q!_J'UjV]؂UWC&"0ܱ@[[ШI`b;uKQ]zs`{?: c2Amq9"""rwhVm%;pڄk2igGZ,o\m]ϺN#@vw`\Q,z6N#@&(4Ø_JOP#""" &{fHvN@& (Ǚ51B9""" < C.évDDۻ_ƅh^: AAFuwh<-$ַ=MBx ( dZ &P[>KayuNNGu,0  k0&P} zo@DDԞwzUҁL@(‰c/Ŝ() ""PـEh}u*@&(Ry./èɮ ""djʦ;u:2@& *9N(v7֟ rQ` 7Fb;d"""?ĦNi`;0p% q|՗0VTJ(6?Eۿuv@`rG1~ JNd^ٹ/lvvS1Hf0.Ԛ;yߔew-E`=p~6"N o>up9PŠs@Da1C7}'_?Hg 1w:˟ tZtL<ڟ ց DDD}`k%䃈H vo#Q>0/4ݟ| V)4s?Kq0DY%PT&}i]+;{g.Uu $ ~;-M@*t.Ecꀪz`xPX,ŷnvn7q:zke#gy*L׃Щ9&l\a<_y4GtLࣗ떋uʥMXc K;@zuWZ!*}* \th2z tf~B<^ɯzp]15n<|.Qm'skkEDE**λQ\?njdA𑯉`)J$S׋'?(ZλrJ]t />14؏5ʧ<_68WZa'_Zfo:-"U7#>;dZ$+PqE//^Ү26{NSat-)ʧY?C4dU*-0/+.K]]F|) +C yB,g%vhnRprhRHbࢻft_|NuAAZtKܜeW~aP+B&̿gJurH+,W9@˦{+l]./FYwyBbyh9bpL.;Gn&yfAZ'C7䲻Iu'#E ֟<bo.'J+rh1kx/ W.;]&|ߖ_QپKe؀kh8Fi3S6ui5rh;i?4ɲgG6%uoJ+q,6x\1hpC`ygx@q0~u7* ذ=dW{B$O&*+#5SE68cpsΛV`W;A l8?T"7g؆ EwIwljtu?Ӷk<1;#u@gh-'V;ߜwgZ x"F*Ɗ~3>'sLOJ ۺNa:QZG7Y YྴB7ﳟ $X%.U8 ϡ~ǛNX2n& IDATgv7k6&mYrvt /_x^~ꦋ*"wr|^ufٟ5[+|~f}F<c1 MfJi;S)reSgA |{"7z7W3U4Ouw=cK/SJ&qc a{d1vz_ .p׿hxKb݀@v#_3 wwv&eOi%⻽y;bxPL2L`R1=&qkQoK]kRyX/S^>fgX +h"F܋AYydDB,ٗ7ut>(~zv7[jc7 7<󂽴2mYܯ&r}\g;'{\zS \pOџ)9,Vob>`r7d~^vz -/O _G\/ւ%O".j$W|Ҫz>okIly] 褃s*6m:2A_j+7^fs!(w?1000xx7O=V(2|*͞j-Ҩ@*l?dsUo9Uͯnu~w3C*ݧmFviϻB?]lDu^)**Njk6W٘舙毿w[BLə=/Ks>(uc7Vzj:ض7tyv+0: Hni`I(,r*)TztZhw/w>00LڳuEģj>/|v5݌6bĪC9IZ5StKOTfͦb~W3KwX uo,5zq>#FHt]#O;>#{/ij@h_hﻣvw\c? | ,9_*qG.;,:(Ѐ͎voj4-;m nyYZxW=>hPr\L;C HvӋJşq?VvF9WiffMXcNT5rm 77ʳ)v9]Ԍ ,7O4I>5xYg}V[^s]G_RJWj܋ԬiLrR) gY^btdgySA^,v›(qb+OpUub{r^ZL{iZf;sm⵨w10goFOTy@ȤkWHTR,Mo%alq*#*ݖۉdxgsX_ 6:R5v\qMK$2RAwQ:AlɤXJw΅3d {1(@r6ɪph: Ge%*[Txbtg\w`YH1;刓FCVfaoSt;Xh΅ 00s恁n W$r^#ĸwzR**65ڴVm:1MkXϻ3 2XmС[sb\OQX-`dP̎ 4GbwؒX$.>)ଯIk:ںjUkxޝa`a‘65m@c5YmwjU3Y89 4ژVcѤ[ =TO>qա>'ZD^]/OSVl{lYV`/V{ͼhxޝc`a毷n'voф5C@+'6͋Ům~yyjoMs%hKD1:r {K$}]<[[\w8p1s?ykV~q@qs4[Yļc3l>o~|MI3獂qSw^8r,^**VUOğ]l=| ;/Ǽ_׭)S7 Yr^}^Z=+3"V}C'fnJN싳"1ojM@F+5l9|1+SgTқi@n͹кcQȴg,/r͞f׭Sn:pbP++~}~hbD{m;1|_G7B"!V. <[gi*9ѲS3*0u{ ,6ϩYϻ;:Uf~'em5MA=K.x4.|AApdV1R#oc?^+vn#ZOV= >8yw'JGеKDEbߒr`t PUyG^MjYN`ů{8pكb~4<#5SE i[?K6z]8N_AGnlx~Վ</%f?XOǽ>tJٲ>#/E <>0/N:Ǜn t QQN99{ D Ţ<{-W*EhAl| x%Y?H?&nض@.1JHcD]8?SjYaH䉵fc0v/VP#/_lHU6 5AN~ 9j\Aſ=f䰨xȍ!|}g_icz;1S}8`x- <8au"2dxj?no:MMo^OK~Q*ζDXr&9r{Κb[Ã@`FQɼ:f[$ps[V)1vsaxN+_{grXIUWoQMz䏗ǻyw,`E NWoO'}xa`x| p΍;/4/T\no_,,_ԧ=<rꗪz1 Kw3 oom3q߅@Jrxg?-wæR"eO\MQ-^hy*6~thr6gK?.4upeT ^ 5}OGExޝ 7W'QDӍ fH_(*`k"e@A>{/fC;6UbigJ~3M?QL9Z̜0[|D޶STkhx/ri*u+vS̏59bJ]JXk|kb0lY%_$a`X qM&pWDys\`q_9,7]X}*,nB:-)nB @<==ߵE<}YI3N/ +voOAu ZTz v[4M6k6J?eⷔeh@=m@DžW1b"`u_Yx`@yGE>qlgDO6ZO(Z fbKle]91ֵ[m%:`d5c;A1SiOuWb"O<;68b~.%b~?uz^(""; /.1^|TRT @6T|yѧ+w9|HDuƫ ri"f412.] ćp0Qȝ/~o6^{te"ñXˋ\Wv '/f$Y8_OǮk'Ub?+b ǟmo/υl0y))<|gq/KtSВbIۢR1^D;C2NjˋM`pR1]WA^[)Ÿ1PU'Tk$wy NwI(`:yϪ/XA~`ůdHÎ]N)G‘ov?ğ)cxRѧ~!xĢ R8I`B`b4'Mk`Vi{$Q8_~NM8: 84` 4u]4ݹlY]2'/+RYN;NOMf-\׽ʡfwF.#QDeQT"R)[l-Fyt;zK[}^׊RA-gX~)St0"(Jq(:󞃭3N7 ²[,賲(v9x uh^; jxQ(o10J0`;UAU3h{} XQ.:fz]@Cɖfy1M,(hN1+=FQzM]qJ٫]:PB:(zx'Q8 to-08|n%S0Bᶒu^a A G9VWA6}R Iy?ka6AwW߁ * ʮ7;߱&*2DQe ~Uv쬪(f&"7\{٬rZỹs8-rFzaXin!rV"*4}eN|8 #śzUNEev̔*O.K;dlw30X}dET7l#9^ШY.{3qJUpr nOrl\%Ld8n1"wgKAw-.Ga§pz_Cz%A %`cg&$ ǜunEzpL)ڔoK.pХ`xss 9CYY_ngS}DL":TX*Ӱ(l!(%,Fz;6^pV #"hӕtc&RN4k&WSzFOJ7ĨzjctǍ\-FEXxuVAd_v R^~nۭȘ(JSe7.LDw%5+{s<^k Yn?g 6SՄBDyz%Qi5+Գ3a9ݤPhe/zc`W䙝^V' )Fa`v \ N*1;cGDtVT$nFo 'm`;OQ9DDv&0 ͈!0tCS9e1Ǡ2iWEKԦ"2d)WvEE,J oD Qwy,\||M:45'9aC&""p ͬ/E**ac ""&Jag0@DDQDDD"""ϓ5 N!"" ! "gc 8j(|8c`@DDD10 ""~ h?DDD"""ڏtC""8\7 10 "Y%Z}^X9eWҕ53SQ0( ) """ڏc ,>i"" ^5%8``@DD63-lc qFAAVAA!$6 2tod`@DDR4ȆWv10 ""es7n+o;X\RALiF ":D ̕ SAi00 Cd4ʗ(ZP wxut\|zCDQF3 nȊרڝm-Dk%T@YP8d_3Z 20 0xt^0[(8fMD]y5^3j-ףN51DdTe4+ٹ& { u2ƀQEMVG2nL#fB 8+(f&ϙץR7j`eM~:`3aеfV0fORYgzth1``@*5 zP[X=bWQDXv )K/ :]CD"ͨT4}/rR10 ҈n48[a',SqX iIe%@ȨAC"š`+nIW>dR[,-`\1RaQyuDhwQEt-tF b [ B@e2*2'߫q:n=Mu]D O\=) >|뾞"͈\OVMVt*2 a Ԣp.,Lג[c@ VB*|Qfh5fɘ91^ D> {+y| ;e[ 4椒- Xi`U[= 5Lva\ܚaXVaQܸVV({-*E.fz\+z3^\|H"Q~rmg;a x-KKWX+׊v< c 80O;A(_ L f6̋'}yC'Ux];aVP,A?&7{dKapǯ| =t (tX0Ϟ Ca@tVuc<:bhs#?L IDATzܼF᡺{nwcWY|00X!]$Ɏ.)צ>8]bG^Y.ītE,f7 TVa AQb'Wa涐ӹ"}*@.J "KGqV~]x1LB(h~N޳dHPx=гP"AWu ra`@&*b2Db*t Zn00X07mwt| I' ^5j3]7"jU'ܼDa>tCz ] sō!qM%a_T, AZQ)Mp ]3@53S-D{؋U2-J"sc$e;́ʹYFŒ &EQ%Obn\PxHJ6͉[ٕey`g۲B[ c ??3( E)BÏ DI 2X00zKWD5`ALEep=~EE  "DD00U^w#o lB fpnv":x @bJ% =VD`gB3TYSP00DUs}v!- d:.>v!/Ee&B.*ǃ(nܖ0P1g{d -M "=-d UkP &^q=D䭨5Bٸ"QhkeBopڬ;}%00]*@w hݸȾe[Ag%@f#M][Z<%,rNF[ݜ#Pe;ϏpA\N] J 0 |95ڰZ(62LEidA[wSXMPAW b ʅF&iebZYzܱnZ*c;|deNjrAy5KpAr#xA57UiJfA#yrZ:iyqaF|JOetpCb %}^d˰af i%$}Xth=2x)(P=!YQݔSV pnVދs`u 2cX[p100^vyyS; T6$cԯiAu np~/{vpN UAM?LPT!=ƃTnKAliE3݋m7C\Px1Iv28PI&}aE\ٽ&|PqS5 y^3LPdR!.˱NҶ3i*fȜS;Gk&Jؕ@ k9֮0aϿp/ӷj~mw,' >yϒ<hjuwd?DU|qMv=vv@Q gY8u[qqS+vFvY :¥K3[W 8n){d>ҵ^7O2׼4IdϽzc$HJ3HML~Mϲz r2NEȶ|;v}f7|W6 ʏc%e@l1Յ5 MfjF݊IkŵrUfO^m K5bV.rEF^6IPTk+L7An5.@|ؕ@.|1#W K B«J<1{.f۸ V``nGa `'dF(T/p;T 3 "&Dz8⌦+Y}uk'rA: F^W%1"^Bf``f,c:q9&I5De&a;:T*V\2be^msVVuUlb7_^wl,,;A.^bsV~,;AЙO~1ȞDP{z6 ƋM~ \;dҟKJc`V(ɬtVtmMeJ^E$ĝ5;DDPOC* Z=42 Z n,\/6VdVN~GXvrf֑ u tȼ,rX2tgn4{d][ 꼺 TIOA4e{~n5pAU[[:\tAng Ҳ1t#~w!uz snը΃\,T̾0T^S|4Z:\3^c`sU NӬ u;saܲV\*ƅ.JQo>$K*[2Ji|ա!vU d''=Z2,LB\[ 4";ثSYT'˪BvoEwLUDUٔV"8{+ WKut\|zCFt _UQI;:oVyMa7е[O>5WeWڝmIE&N+Vu%,l1cp@i ؕ@!u*[u0Tՠ\K)[}`tul#oٹfdl1ȳ{sz "1s7:c^HTl1 Rȯh`Q>Hr $sa#R vFy1x|dLzV2H 銁-탤cp'|U-f'0FPE$i(S*WBMv[6>R@^R\/S}mE] T_*?m ;ѭ_? d!P``@Ea$3zj4b' ׭8w.8 `u (RZ Ѭ EkKՁW:6i-tXA%ݚދ}@rmDs)#zYQPܪ sN?+=ף\uukp"M;}aLk)ҳ(Ac@U9NSd*0n+~wk^XAߝkѠRt춴0ƀEwxDrY. ?SX縻%68{ ҅N |HU#{C]2i Lי#ψ5‹)^ YN狫Jɓ.cAސ^\JE_~GE܂!#2`^g`@z%9Vıd^1O (Xꉕ!ѱ5®"09KaH*AO[^ 53S?\XF#B(hl1Xp:Cu( *~v]f\ZLo10Xj|VS nZع֍['?>ȕǺ^:.e+0Ә[w'*:ODL7 ¸Y2֪Hs ݑNGgDtuI`Ũ1/;XoYl36[ Rx{xq:j6䕺&Q4.䤕nS:<|wMz2WA;=,,߶;{^s9G] ~3ֵsjnŌ/@l@vfNkTUN0U,{TE,psڋRos`i6ַ=!΁mx|mWzd|k떛'{[Nޟ{2g_[nk}Vvrң賲iK9Lvcuxi1uF*B^*B*@l\_5z)zZ]A䗸.o'/WTʐєհrޛ|Zd_yoLK@FA g%k?[oq!/Q*SD^ӹ >7%[)1{C1iA)}>ï`ϬAe44.DS n8+!J9x/ _+?:DAS5 ^IkE+mt[Y6 1:H5y܎gBUz m=}s0̫ƔLu׼,TLR7]U2uT*V2N;NKBmt2{O/aN(-vWtnE缩b5>T&Dd?Wvm؎V}z(\agLNLڮpxe2Rî!k2-A@Z g^ Mn}P*k{o</' lo$3{oh7o;* "U2\wXYv'KvMd']/G۫uIŏrݫQ;vcyBrI E8q쥘SE#]C IeEaUNQΫf_^]vΗ L@- hhtD@rwEփ<57K߳ALA@Z.s? jF{5cdeIl 0(߈8J* ـ M$Z&P[>KUvLyYi8ZEawx SʾN>T?f5x d7^l[npu: rD] L}݅IJD$èS1E87Nҵ Nj) V4]½ փ¼8uU8mµ(+Q+"c:N 7: bWw ܽuU< DPQT3kcFՅ sDdfkq T B`Ӿem xy"aȹXPcKW#"ܬƦKF*F5G3;3t]C^n}1]/0䂃0sWw )u.t'D? acX lv4+ zb Io{1[pj@qHGATda08{(ίT++N_ԓl?Y{>on }%<;q!v: Mbi2BiAfMf D\Q}S* ح2#! +ۀ}M*ͪ`;ԆEx7_sTg"ίWB8GfIe>ox^l/X"5^ ML20\5Ǩ,:\M(j;] f[hmNEvTA̎{Oo*]A&x1lY߀]'\5/*R][q`l|w4tҴ dd/V܁maNmQ)$[QP.Ja bX|=ַ=(NX $A&;ׂ,.uo;yM>^ U1g{hh\ y0H̩ F(GU^t#|~7|a .5،MJm ? H ]W=Mk#a~R-=Ne(2 <wbDx"2fjց\MvWc`\JL10A(&NxŊrEQf0`A?]44.¶URo|I9M~b@]N75،U7]#TZc`lpw(GD.\68@@Ipj5߈X9% /Q.œ[QZP(W'TBJ`P<&LGи{7Iê=d1=FnLX!d{tRx%T:10PD6@*yK0⣊rD4E'TWX*_)/Q7mYz;dA*  0xD@;[ MXdjʦ;K*-Vcj10l(‰c/9?w˯ I~ T:CByD̮.N );f祹tlk5°Vv+{NUwxLE„_ uF'Lq Ң:0@ /܅-c8/,10|an]($OOv`k8C^-tKUoLΧMy%rE$-8wY%ْ14`B 0nlәԗMnri3ifKLá&1Lih'&Cn:NKjm01@)±:ˋawf|zW}c] 1,5F4֎DZ\``w&;8az _P007CO0c '{0HU@kewFbapa IDATnA-_B5-*qjx/3jqY 흷5?zQY.xj|d#K?B:\A ܷll`{g*S O  3芵c`Z\a$N/Telk~-5;FD~hLj'ĹK|18D@XW݆N*M`DDr͸ Y%pf!{o\ u?ƧPZ!4*ױ:9`|y>p-.;`.^ ~O0Z\n܁E$B}9HmOuqz_Z23CO!dZ\f܅;oDM#"?ȵ8Q͢!58fqq3e~'6ރpJhT;q뢙9^i{õIT7' w7sv rz}d>| gH5܉UH[}Au~}_ tg;dA S ÉwqvG6|#gҿ[0 ƿ7F"5bCp$vᡜ B:rESBO-Լ@w8 &Nob00P`s^>m >Á;hTBgw;j=ě2-d;oE[/`P<^Vl cOgAvC0D8 /|]˹\wp{Xs}~#躴 5/.`3a)1E szǠcQ*Fg^i-?+g$^Њی\?`-^y WWgn2PWfC(x;.'?EΕowi/,RN4 $rJ ݃k흟FIF`Tv!Phêa䴆Ya1 |:*);=߂lcaqѵɌ wzƀ`.G4ց_-҉R#PK#O\WZ…K ,yAOq'5 H5+}PY]Ԍ厫v\Fz[q<5 0݇t6i8I ̊'jHmeZϝKf_iwFk;1\:S Nž'fy%b%tڪ.ծvk[z^.jOGhNCͮ=&Cى1 $}~g=z'^&rON/\cqy;dw 0EQ L?/|WmCkue ~3kk-pq8!ǮR;*N"!)(;z0aBr?ZˮM%qAVI˿Dīx 3`޷ڋx5|O㶳#ɏ^@@fBbJf&uoDžFeҲ8?|rǴZq9^dSt҇c@{!ū}DKE:EbxyY Nys3pbIg>3\a2ԧO&]vg~ʅ[nv{e0k΋S]6 `( Wa0 HLls ޿e;{}a%gX>w:|z iYJjI ׽b`愦Ozf&|J`Jiyc مD&[<=1[V6/~P%0iC)VtNh'W[)2ىA" qOn~Jj] Zd." -M>|H뱬͝3Tccrr UfL/ ~ŋR=nZndD+;PiG* 4V܋DnnuGS:,GEHgTχ/99D@ ~[A`TO z'~c1/SS/99A8X Mk53yiDc9)RS.9T@XY nY-z]3az. q%`0 W ۰ԕGޑQpv81iYrrp k-MϠhHMr#:z^ɍ ȵBiMx`OpWݏDjē8ۅ S#R*T@-ps_#K?ʼnpvJZ&Tr; y{XQ'"yJ_=K_ɩI^`@&Vߍ4U/R&=o e^&M2PHM8ՅNēG2BYQ-_l?djr#*H DrXMIf&= RS: DH9jb;lz\&8"m t E2]V}{飈va|ވc0 Ir [~ W &p|1v DI59Mb5jr>IΈc0 "bkӳ(^-TI7F"5"WS"A ;'E4֎)ˆd1@2 (i73nY-Vc;d"`0 2d@R6F^@]j-{cqj,dr"2;?:f&( Bկ* |.|\TQϞ{8DdcpIENDB`Brobdingnag/man/as.numeric.Rd0000644000176200001440000000215713762776702015622 0ustar liggesusers\name{as.numeric} \alias{as.numeric} \alias{as.complex} \alias{as.numeric,brob-method} \alias{as.complex,brob-method} \alias{as.numeric,glub-method} \alias{as.complex,glub-method} \alias{coerce,brob,numeric-method} \alias{coerce,brob,complex-method} \alias{coerce,glub,numeric-method} \alias{coerce,glub,complex-method} \title{Coerces to numeric or complex form} \description{ Coerces an object of class \code{brob} to numeric, or an object of class \code{glub} to complex } \arguments{ \item{x}{Object of class \code{brob} or \code{glub}} \item{\dots}{Further arguments (currently ignored)} } \details{ Function \code{as.numeric()} coerces a \code{brob} to numeric; if given a \code{glub}, the imaginary component is ignored (and a warning given). Function \code{as.complex()} coerces to complex. } \author{Robin K. S. Hankin} \note{ If \eqn{\left|x\right|}{|x|} is greater than \code{.Machine$double.xmax}, then \code{as.numeric(x)} returns \code{Inf} or \code{-Inf} but no warning is given. } \examples{ a <- as.brob(1:10) a <- cbrob(a, as.brob(10)^1e26) a as.numeric(a) as.complex(10i + a) } \keyword{math} Brobdingnag/man/index-class.Rd0000644000176200001440000000213413762776702015763 0ustar liggesusers\name{index-class} \Rdversion{1.1} \docType{class} \alias{index-class} \title{Class \code{"index"}} \description{ A virtual class for matrix extraction, copied from the \code{Matrix} package. } \section{Objects from the Class}{A virtual Class: No objects may be created from it.} \section{Methods}{ \describe{ \item{[}{\code{signature(x = "brobmat", i = "index", j = "index")}: ... } \item{[}{\code{signature(x = "brobmat", i = "index", j = "missing")}: ... } \item{[}{\code{signature(x = "brobmat", i = "missing", j = "index")}: ... } \item{[<-}{\code{signature(x = "brobmat", i = "index", j = "index")}: ... } \item{[<-}{\code{signature(x = "brobmat", i = "index", j = "missing")}: ... } \item{[<-}{\code{signature(x = "brobmat", i = "missing", j = "index")}: ... } } } \references{ Douglas Bates and Martin Maechler (2019). Matrix: Sparse and Dense Matrix Classes and Methods. {R} package version 1.2-18. \url{https://CRAN.R-project.org/package=Matrix} } \author{Bates and Maechler, I guess} \seealso{\code{\linkS4class{brobmat}}} \examples{ showClass("index") } \keyword{classes} Brobdingnag/man/length.Rd0000644000176200001440000000073713762776702015041 0ustar liggesusers\name{length-methods} \docType{methods} \alias{length} \alias{length,brob-method} \alias{length,glub-method} \alias{length,brob-method} \alias{length,glub-method} \title{Get lengths of brobs and glubs} \description{ Get lengths of brob and glub vectors } \usage{ \S4method{length}{brob}(x) \S4method{length}{glub}(x) } \arguments{ \item{x}{vector of class brob or glub} } \author{Robin K. S. Hankin} \examples{ x <- as.brob(-10:10) length(x) } \keyword{math} \keyword{methods} Brobdingnag/man/Logic.Rd0000644000176200001440000000125013762776702014604 0ustar liggesusers\name{Logic} \alias{logic.brob} \alias{Logic,swift,ANY-method} \alias{Logic,ANY,swift-method} \alias{Logic,swift,swift-method} \title{Logical operations on brobs} \description{ Logical operations on brobs are not supported } \author{Robin K. S. Hankin} \note{ The S4 group generic \dQuote{Logic} appeared in R-2.4.0-patched. Carrying out logical operations in this group will call \code{.Brob.logic()}, which reports an error. Negation, \dQuote{\code{!}}, is not part of this group: attempting to negate a brob will not activate \code{.Brob.logic()}; an \dQuote{invalid argument type} error is given instead. } \examples{ \dontrun{ !brob(10) } } \keyword{math} Brobdingnag/man/Summary.Rd0000644000176200001440000000256413762776702015215 0ustar liggesusers\name{sum} \alias{sum} \alias{min} \alias{max} \alias{prod} \alias{range} \alias{Summary,brob-method} \alias{Summary,glub-method} \title{Various summary statistics for brobs and glubs} \description{Various summary statistics for brobs and glubs } \arguments{ \item{x,\dots}{Objects of class \code{brob} or, in the case of \code{sum()} and \code{prob()}, class \code{glub}} \item{na.rm}{Boolean, with default \code{FALSE} meaning to interpret \code{NA}s literally and \code{TRUE} meaning to ignore any such elements} } \details{ For a \code{brob} object, being \code{NA} is not entirely straightforward. The S4 method for \code{is.na} is too \dQuote{strict} for some of the functions considered here. Consider \code{max(a)} where \code{a} includes only positive, fully specified, elements, and elements with known negative sign and exponents that include \code{NA} values. Here, \code{max(a)} is unambiguously determined. Similar logic applies to \code{min()} and, by extension, \code{range()}. } \author{Robin K. S. Hankin} \note{ Function \code{prod()} is \emph{very} slow for long \code{glub} vectors. It has to compute four Brobdingnagian products and two Brobdingnagian sums per element of its argument, and this takes a long time. } \seealso{\code{\link{is.na}}} \examples{ a <- as.brob(1:10) max(cbrob(1:10,brob(NA,FALSE))) } \keyword{math} Brobdingnag/man/Print.Rd0000644000176200001440000000077613762776702014657 0ustar liggesusers\name{Print} \alias{print.brob} \alias{print.glub} \alias{show,brob-method} \alias{show,glub-method} \title{Methods for printing brobs and glubs} \description{ Methods for printing brobs and glubs nicely using exponential notation } \usage{ \method{print}{brob}(x, ...) \method{print}{glub}(x, ...) } \arguments{ \item{x}{An object of class \code{brob} or \code{glub}} \item{...}{Further arguments (currently ignored)} } \author{Robin K. S. Hankin} \examples{ a <- as.brob(1:5) dput(a) a } \keyword{math} Brobdingnag/man/glub-class.Rd0000644000176200001440000000270613762776702015612 0ustar liggesusers\name{glub-class} \docType{class} \alias{glub-class} \alias{.cPair,brob,glub-method} \alias{.cPair,ANY,glub-method} \alias{.cPair,glub,glub-method} \alias{.cPair,glub,ANY-method} \alias{.cPair,glub,brob-method} \title{Class "glub" } \description{Complex Brobdingnagian numbers} \section{Objects from the Class}{ A \code{glub} object holds two slots, both \code{brobs}, representing the real and imaginary components of a complex vector. } \section{Slots}{ \describe{ \item{\code{real}:}{Object of class \code{"brob"} representing the real component} \item{\code{imag}:}{Object of class \code{"brob"} representing the imaginary component} } } \section{Extends}{ Class \code{"swift"}, directly. } \section{Methods}{ \describe{ \item{.cPair}{\code{signature(x = "brob", y = "glub")}: ... } \item{.cPair}{\code{signature(x = "ANY", y = "glub")}: ... } \item{.cPair}{\code{signature(x = "glub", y = "glub")}: ... } \item{.cPair}{\code{signature(x = "glub", y = "ANY")}: ... } \item{.cPair}{\code{signature(x = "glub", y = "brob")}: ... } \item{Im<-}{\code{signature(x = "glub")}: ... } \item{Re<-}{\code{signature(x = "glub")}: ... } } } \author{Robin K. S. Hankin} \seealso{ \code{\link{brob-class}},\code{\link{swift-class}} } \examples{ a <- as.brob(45) new("glub",real=a, imag=a) as.brob(5+5i) # standard R idiom; imaginary component discarded as.glub(5+5i) # returns a Glubbdubdribian object } \keyword{classes} Brobdingnag/man/Compare.Rd0000644000176200001440000000203513762776702015137 0ustar liggesusers\name{Compare-methods} \docType{methods} \alias{Compare-methods} \alias{Compare,brob,ANY-method} \alias{Compare,brob,brob-method} \alias{Compare,brob,glub-method} \alias{Compare,ANY,brob-method} \alias{Compare,ANY,glub-method} \alias{Compare,glub,glub-method} \alias{Compare,glub,ANY-method} \alias{Compare,glub,brob-method} \title{Methods for Function Compare in Package Brobdingnag} \description{ Methods for comparision (greater than, etc) in package Brobdingnag } \note{ As for \code{min()} and \code{max()}, comparison is not entirely straightforward in the presence of \code{NA}s. The low-level workhorses are \code{.Brob.equal()} for equality and \code{.Brob.greater()} for \sQuote{strictly greater than}. All other comparisons are calculated by combining these two. Comparison [function \code{.Brob.compare()}] explicitly tests for a zero length argument and if given one returns \code{logical(0)} to match base behaviour. } \examples{ a <- as.brob(10)^(0.5 + 97:103) a < 1e100 } \keyword{methods} \keyword{math} Brobdingnag/man/glub.Rd0000644000176200001440000000306213762776702014503 0ustar liggesusers\name{glub} \alias{glub} \alias{as.glub} \alias{is.glub} \title{Glubbdubdribian numbers: complex numbers with Brobdingnagian real and imaginary parts} \description{ Create, coerce to or test for a Glubbdubdribian object } \usage{ glub(real = double(), imag = double()) as.glub(x) is.glub(x) } \arguments{ \item{real, imag}{Real and imaginary components of complex number: must be Brobdingnagian numbers} \item{x}{object to be coerced to or tested for Glubbdubdribian form} } \details{ A \dfn{Glubbdubdribian} number is the Brobdingnagian equivalent of a complex number. Function \code{glub()} takes two arguments that are coerced to Brobdingnagian numbers and returns a Glubbdubdribian number. This function is not really intended for the end user: it is confusing and includes no argument checking. Use function \code{as.glub()} instead. Function \code{as.glub()} is the user's workhorse: use this to coerce numeric or complex vectors to Glubbdubdribian form. Function \code{is.glub()} tests for its arguments being Glubbdubdribian. } \author{Robin K. S. Hankin} \note{ Function \code{glub()} uses recycling inherited from \code{cbind()}. } \seealso{\code{\link{brob}}} \examples{ a <- as.glub(1:10 + 5i) a^2 - a*a f <- function(x){sin(x) +x^4 - 1/x} as.complex(f(a)) - f(as.complex(a)) # should be zero (in the first # term, f() works with glubs and coerces to # complex; in the second, f() # works with complex numbers directly) } \keyword{math} Brobdingnag/man/cbrob.Rd0000644000176200001440000000322713762776702014644 0ustar liggesusers\name{cbrob} \alias{cbrob} \alias{cBrob} \title{Combine Brobdingnagian vectors} \description{ Combine Brobdingnagian or Glubdubbdribian vectors through concatenation } \usage{ cbrob(x, ...) } \arguments{ \item{x}{Brobdingnagian vector} \item{\dots}{Other arguments coerced to brob form} } \details{ If any argument has class \code{glub}, all arguments are coerced to \code{glub}s. Otherwise, if any argument has class \code{brob}, all arguments are coerced to \code{brob}s. Function \code{cbrob()} operates recursively, calling \code{.cPair()} repeatedly. Function \code{.cPair()} uses S4 method dispatch to call either \code{.Brob.cpair()} or \code{.Glub.cpair()} according to the classes of the arguments. } \author{Robin K. S. Hankin; original idea due to John Chambers} \note{ As of R-2.4.0, it is apparently not possible to use S4 methods to redefine \code{c()} to coerce to class \code{brob} form and concatenate as expected. This would seem to be a reasonable interpretation of \code{c()} from the user's perspective. Conceptually, the operation is simple: concatenate the \code{value} slot and the \code{positive} slot separately, then call \code{brob()} on the two resulting vectors. When concatenating \code{glub} objects, the real and imaginary components (being \code{brob}s) are concatenated using \code{.Brob.cpair()} The choice of name---\code{cbrob()}---is not entirely logical. Because it operates consistently on \code{brob} and \code{glub} objects, it might be argued that \code{cSwift()} would be a more appropriate name. } \examples{ a <- as.brob(2)^1e-40 cbrob(1:4,4:1,a) cbrob(1:4,a,1i) } \keyword{math} Brobdingnag/man/Arith.Rd0000644000176200001440000000220713762776702014621 0ustar liggesusers\name{Arith-methods} \docType{methods} \alias{Arith-methods} \alias{Arith,brob,missing-method} \alias{Arith,brob,ANY-method} \alias{Arith,brob,brob-method} \alias{Arith,brob,complex-method} \alias{Arith,ANY,brob-method} \alias{Arith,ANY,glub-method} \alias{Arith,glub,missing-method} \alias{Arith,glub,glub-method} \alias{Arith,glub,ANY-method} \alias{Arith,glub,complex-method} \alias{Arith,complex,brob-method} \alias{Arith,complex,glub-method} \alias{Arith,brob,glub-method} \alias{Arith,glub,brob-method} \title{Methods for Function Arith in package Brobdingnag} \description{ Methods for Arithmetic functions in package Brobdingnag: \code{+}, \code{-}, \code{*}, \code{/}, \code{^} } \author{Robin K. S. Hankin} \note{ The unary arithmetic functions (viz \dQuote{\code{+}} and \dQuote{\code{-}}) do no coercion. The binary arithmetic functions coerce \code{numeric} \code{brob} to \code{brob}; and \code{numeric} \code{glub}, \code{complex} \code{brob}, and \code{brob} \code{glub}, to \code{glub}. } \examples{ x <- as.brob(1:10) y <- 1e10 x+y as.numeric((x+y)-1e10) x^(1/y) } \keyword{methods} \keyword{math} Brobdingnag/man/plot.Rd0000644000176200001440000000124213762776702014526 0ustar liggesusers\name{plot} \alias{plot} \alias{plot,brob-method} \alias{plot,brob,missing-method} \alias{plot,brob,ANY-method} \alias{plot,ANY,brob-method} \alias{plot,glub-method} \alias{plot,glub,missing-method} \alias{plot,glub,ANY-method} \alias{plot,ANY,glub-method} \title{Basic plotting of Brobs} \description{ Plotting methods. Essentially, any brob is coerced to a numeric and any glub is coerced to a complex, and the argument or arguments are passed to \code{plot()}. } \usage{ plot(x, y, ...) } \arguments{ \item{x,y}{Brob or glub} \item{\dots}{Further arguments passed to \code{plot()}} } \author{Robin K. S. Hankin} \examples{ plot(as.brob(1:10)) } \keyword{math} Brobdingnag/man/swift-class.Rd0000644000176200001440000000066314162031142015766 0ustar liggesusers\name{swift-class} \docType{class} \alias{swift-class} \title{Class "swift" } \description{A (virtual) class that extends \code{brob} and \code{glub} objects} \section{Objects from the Class}{A virtual Class: No objects may be created from it.} \section{Methods}{ No methods defined with class "swift" in the signature. } \author{Robin K. S. Hankin} \seealso{ \code{\link{brob-class}},\code{\link{glub-class}} } \keyword{classes} Brobdingnag/DESCRIPTION0000644000176200001440000000163114176704472014211 0ustar liggesusersPackage: Brobdingnag Type: Package Title: Very Large Numbers in R Version: 1.2-7 Authors@R: person(given=c("Robin", "K. S."), family="Hankin", role = c("aut","cre"), email="hankin.robin@gmail.com", comment = c(ORCID = "0000-0001-5982-0415")) Maintainer: Robin K. S. Hankin Depends: R (>= 2.13.0), methods Description: Very large numbers in R. Real numbers are held using their natural logarithms, plus a logical flag indicating sign. Functionality for complex numbers is also provided. The package includes a vignette that gives a step-by-step introduction to using S4 methods. Suggests: cubature License: GPL Repository: CRAN URL: https://github.com/RobinHankin/Brobdingnag NeedsCompilation: no Packaged: 2022-02-02 21:08:17 UTC; rhankin Author: Robin K. S. Hankin [aut, cre] () Date/Publication: 2022-02-03 07:50:18 UTC Brobdingnag/build/0000755000176200001440000000000014176571300013571 5ustar liggesusersBrobdingnag/build/vignette.rds0000644000176200001440000000040214176571300016124 0ustar liggesusers}; 0Ӈ*ͭ 8:i4-Ƥ/DCޓm !d#ײRWqޝ&@#++^v輐lB?TLF>dK˄POk 3x=mDcDQ{TcݒYꢚ Mt׹k({r6WGK[iXD~S:RёT;ҰEIFSzOgBrobdingnag/build/partial.rdb0000644000176200001440000001224014176571271015724 0ustar liggesusers]{SȖ7$w:N8 CBGB-IX̦fVڶ6d~jaܚpg=Wi[yӭnL&ӛA2דaF/d%E+TKB3^BA͖*$O^N˔MZfU' қX UY(\4aeO?m= Q]6@s7l5jRή='V?ye8 kez];owɶ+5h?p@,]Q] /U}+䥅G yJbNK&;e SU6ZU Cz&*z\EG-pOøǭ6>q!86FxĀY@[XZ/%Mz{ :m@GJh҇:SK(_()e3m%*~RPQ1f=(%~O*.*I `p)1+]zX75lkTfY_˼G04kiie3F٪ѩ{Oo?n^v@c_)HMM>VD@ 5d[2+iJԴBDS 7qI"DqHT-z#Je>dkLpZ8K8fz\x$lћB-Tj6aPe=F܀6kBkRN2)RMjJ8wWnA}_b6 v&%a2ȚQLծ֬YR ;|T&>!+WKL ]na٨5z6I R7}U ^v4+4Lݲ` a Hm2I6[˦Rshw0ʠi( nbnIUCg7ݽ+ˆ?yG! p}$hQV`b&a:  Z&A$3P\ig_b25ZakgoKKQz "$I7G$mv4 մFwbLg3?%rfp@;ڋT:5ecL>yjTى5x'cd;'7H:wzb}=3F7 gI>pn+5%:jîpjS0S/Sꓳdd7;9=KRM՚˓$?e%˄1K {rv]hMR*g˚p.+53Fumamk&;s O<_J|e6;y^%}8"`_J}}^k#/wR_khݰT0Y+JE|9sa/!Uۮ[K\ o% I3g,wwȹ+rL*5Y~w2upÔU%k\]g݁543weC)\3̢HwGL?_D_粨Kѡy+pV~^rW~n9V/M8}q!(gF]ȫv1UYdT s85Ft'7 gf$OhR݁t>`/?G;PX3juɤ>/ d;^ FoHBԚTQuLM:A݁~liԏ~6%&Y I2ebig*Zdu /dFj߳RenY5eHHo!_¼k;0>ިQo͠&K+%jx( efbY") XZdY,WUϼJL޾*iDU@<U!gX~X^B"⸂uro,G=")poN/ycst `8`uN1:t"]}&7ȝTRx$q*5,/gzUr|)ǻmD}]p\ovo$D٨Dz gkhSt“Ou@_hن %L ",?H͝ !A4PX{)1EP6 ]Bb]aY$`>ʈS[X:}W`LW0Q,@u}Hǰ<"}Y5xyzQ&zKӉzyS! )kR6'(Фf$(Bx@B ㄼ2dC?D$,ynДZl44%HݾfՐj/!}Rbu=,5~WIl g~ ,HuPSk6";<@ǰ/X츷X{<ӞJMųOl2VkJ4͇,qf-TX&鑷A>*1MB\Vfg "nĤ3t_>+9 hzS.X>javJ56ã,ӚDR ɦo:U,a .ߪӆгѰX`X]7,TMrV].~qhJͨBkn٦TҚ1!uX#hT7fm"}r },ǚ7KmN{4vXPQjAy%8v:@(1pR8u.ҢxtwkȏѷH|Y;CC6 ww8jDSq&wPFw%qtIb=*%<fۢɂw=ܚ6+q޺tf6 3h]m _ _(12q\8r'jU1sDة|dh+_{|n'خEEFu_:m8!G5ynXK1D>7Q>}:Y8cu4O嗠tE4-dyu4pWȘ մu45r6YP3ϱn`&C`E,-o Swet+gLHCqux8^`/vkqF79n5iɲhWG7\|NjN';GtΌwm$<@?=@5z=gXl+\4a-ja1_&)Vtb7_bYCخx5\xGO*ÐA36WW6D۶vo{ttb;/O~(Y#0iQ)~ƑN`9~rݯ|Cmj5w] jaP[KA\e^@ny6ma6 0sґs_cʈOMoEJ*}X;<ŀf f:k^ɄeFKH3(aj&,o :h,t(2VmZSGtO- Q`xqV!^ Q 3Þa=2CΡ7kGa"ӏ=C\X! M!17G{ #9mG2dxӴ_ct ? TU*~2t V1 c8Pm#@]k]Y}3GƦGnjMjjhk>7'$jWA@[_vgD[͐A\g?ZEk.QܷXNX.Gq(  ۜ{✼=q Y}_KzwnmGaor i,i9M- 9*4WPrθ1g5- ٜ] /U}+p楅G yJb)-fXa,-N!|9Mv Sq 0纆|Ix[ڣAo;95~#>})*ަ$0TM9 {rC*I1{a3ޡclsď"l0  5_"2a,㺷l̒$H( y,'׀ jxϙJê+;/>'m{%ñy$}\\ y+\log\left(1+e^{x-y}\right)\qquad &\mbox{otherwise} \end{array} \right. \] In practice this gets more complicated as one has to keep track of the sign; and special dispensation is needed for zero ($=e^{-\infty}$). One can thus deal with numbers up to about~$e^{1.9\times 10^{308}}\simeq 10^{7.8\times 10^{307}}$, although at this outer limit accuracy is pretty poor. \section{Class definition} The first thing we need to do is to define the {\tt brob} class. This uses the {\tt setClass()} function: <>= <>= setClass("swift", representation = "VIRTUAL" ) setClass("brob", representation = representation(x="numeric",positive="logical"), prototype = list(x=numeric(),positive=logical()), contains = "swift" ) @ It is simpler to ignore the first call to {\tt setClass()} here; for reasons that will become apparent when discussing the {\tt c()} function, one needs a virtual class that contains class brob and glub. To understand virtual classes, see section~\ref{logicSection}. The second call to {\tt setClass()} is more germane. Let's take this apart, argument by argument. The first argument, {\tt representation}, specifies ``the slots that the new class should have and/or other classes that this class extends. Usually a call to the `representation' function''. The helppage for {\tt representation} gives a few further details. Thus this argument specifies two `slots': one for the value and one for the sign. These are specified to be numeric and logical (NB: not Boolean) respectively. The second argument, {\tt prototype}, specifies default data for the slots. This kicks in when defining a zero-length brob; an example would be extracting {\tt x[FALSE]} where {\tt x} is a brob. The third argument, {\tt contains}, tells \proglang{R} that class {\tt swift} (which was specified to be virtual), has {\tt brob} as a subclass. We will need this later when we start to deal with {\tt glub}s, which are also a subclass of {\tt swift}. Let's use it: <>= new("brob",x=1:10,positive=rep(TRUE,10)) @ Notes: \begin{itemize} \item Function {\tt new()} is the {\em only} way to create objects of class brob. So, any object of class brob {\em must} have been created with function {\tt new()}. This is part of what the ``formal'' tag for \proglang{S4} means\footnote{Compare \proglang{S3}, in which I can say {\tt a <- 1:10; class(a) <- "lilliput"}}. \item Function {\tt new()} requires its arguments to be named, and no partial argument matching is performed. \item Function {\tt new()} is not intended for the user. It's too picky and difficult. To create new brobs, we need some more friendly functions---{\tt as.brob()} and {\tt brob()}---discussed below. \item There is, as yet, no print method, so the form of the object printed to the screen is less than ideal. \end{itemize} \subsection{Validity methods} Now, an optional step is to define a function that tests whether the arguments passed to {\tt new()} are acceptable. As it stands, the following code: <>= new("brob",x=1:10,positive=c(TRUE,FALSE,FALSE)) @ \noindent will not return an error, but is not acceptable because the arguments are different lengths (and will not recycle neatly). So, we define a validity method: <>= .Brob.valid <- function(object){ len <- length(object@positive) if(len != length(object@x)){ return("length mismatch") } else { return(TRUE) } } @ Advice on the form of the validity-testing function---here {\tt .Brob.valid()}---is given in the help page for {\tt setValidity}: ``The method should be a function of one object that returns `TRUE' or a description of the non-validity''. Examples are given in section 7.1.6 of the Green Book. In this package, I define a whole bunch of functions whose name starts with {\tt .Brob.}; these are internal and not intended for the user. They are also not documented. So now we have a function, {\tt .Brob.valid()}, that checks whether its argument has slots of the same length. We need to tell \proglang{R} that this function should be invoked every time a {\tt brob} is created. Function {\tt setValidity()} does this: <>= setValidity("brob", .Brob.valid) @ Thus, from now on [ie after the above call to {\tt setValidity()}], when calling {\tt new("brob", ...)} the two arguments {\tt x} and {\tt positive} must be the same length: recycling is not carried out. Functions like {\tt .Brob.valid()} that are user-unfriendly all have names beginning with {\tt .Brob}. These functions are there to help the organization of the package and are not intended to be used by the end-user. Clever, user-friendly operations such as recycling are carried out in the more user-friendly functions such as {\tt as.brob()}. If one were to call {\tt new()} with arguments of differing lengths, as in \\ \\ {\tt new("brob",x=1:10,positive=TRUE) } \\ \\ then {\tt new()} would report the error message in function {\tt .Brob.valid()}, because the {\tt positive} argument had length~1 and the {\tt x} was length~10; and the validity method {\tt .Brob.valid()} requires both arguments to be the same length\footnote{Placing the above call in {\tt try()} and showing the error explicitly would cause the package to fail {\tt R CMD check}.}. So now {\tt new()} works, but isn't exactly user-friendly: often one would want the above call to recycle the second argument to length 10 to match the first. This deficiency is remedied in the next section. \section{Basic user-friendly functions to create brobs} The basic, semi user-friendly function for creating brobs is {\tt brob()}: <>= "brob" <- function(x=double(),positive){ if(missing(positive)){ positive <- rep(TRUE,length(x)) } if(length(positive)==1){ positive <- rep(positive,length(x)) } new("brob",x=as.numeric(x),positive=positive) } @ Thus {\tt brob(x)} will return a number formally equal to~$e^x$. Function {\tt brob()} does helpful things like assuming the user desires positive numbers; it also carries out recycling: <>= brob(1:10,FALSE) @ Note that {\tt brob()} isn't exactly terribly user-friendly: it's confusing. {\tt brob(5)} returns a number formally equal to~$e^5$, not~$5$. This is documented in the help page, where the user is encouraged to use function {\tt as.brob()} instead. \section[Testing for brobs: an ``is.brob()'' function]{Testing for brobs: an {\tt is.brob()} function} Function {\tt is()} will test for an object being a brob: <>= is(brob(1:5),"brob") @ (see {\tt help(is)} for more details) but a small package like this, with only brobs and glubs to consider, could benefit from an \proglang{S3}-style function {\tt is.brob()}. This is easy to define: <>= is.brob <- function(x){is(x,"brob")} is.glub <- function(x){is(x,"glub")} @ now the user can just type {\tt is.brob(x)} to find out whether an object is a brob\footnote{This approach is fine for a tiny package like Brobdingnag, with only two or three classes. However, in the context of a more complicated package such as {\tt Matrix}, which uses dozens of different classes in a complicated hierarchical structure, one might prefer to type {\tt is(x,"dpoMatrix-class")} rather than define a plethora of functions along the lines of {\tt is.dpoMatrix-class()}.}. We also define an {\tt is.glub()} function similarly. So now we can check for objects being brobs and glubs. \section[Coercion: an ``as.brob()'' function]{Coercion: an {\tt as.brob()} function} Next, some ways to coerce objects to class brob: <>= "as.brob" <- function(x){ if(is.brob(x)){ return(x) } else if(is.complex(x)) { warning("imaginary parts discarded") return(Recall(Re(x))) } else if(is.glub(x)){ warning("imaginary parts discarded") return(Re(x)) } else { return(brob(log(abs(x)), x>=0)) } } @ So now we can coerce objects of various classes to brobs\footnote{The recommended way, appropriate for a complicated package such as Matrix, would be to execute {\tt setAs("numeric", "brob", .Brob.numeric\_to\_brob)} and {\tt setAs("complex", "brob", .Brob.complex\_to\_brob)}. Then, if {\tt x} is numeric, {\tt as(x,"brob")} would return the appropriate brob via {\tt .Brob.numeric\_to\_brob()}; we could then make {\tt as.brob()} a generic with {\tt setGeneric()} and define methods for it. Doing it this way would save function {\tt as.brob()} having to test for its argument being a brob [carried out in the first few lines of {\tt as.brob()}] because {\tt as()} has such a test built in, implicitly.}. The {\em only} way to create a brob is to use {\tt new()}, and the {\em only} function that calls this is {\tt brob()}. And {\tt as.brob()} calls this. Note the user-friendliness of {\tt as.brob()}. It takes numerics, brobs, and glubs (which give a warning). Check {\tt as.brob()}: <>= as.brob(1:10) @ \section[Coercion: an ``as.numeric()'' function]{Coercion: an {\tt as.numeric()} function} Now we need some methods to coerce brobs to numeric. This is a two-stage process. <>= <>= setAs("brob", "numeric", function(from){ out <- exp(from@x) out[!from@positive] <- -out[!from@positive] return(out) } ) @ This call to {\tt setAs()} makes {\tt as(x,"numeric")} carry out the function passed as the third argument when given a brob. But in this package, the user isn't supposed to type {\tt as(x,"numeric")}: the user is supposed to type {\tt as.numeric(x)}\footnote{Users can be expected to be familiar with functions such as {\tt as.numeric()} and {\tt as.complex()}, which is why the Brobdingnag package recommends this form. However, this might not be appropriate for a more complicated package such as Matrix because, to quote Martin Maechler, ``it seems very ugly to define more than very few {\tt as.FOO()} methods, and very natural to work with {\tt as(*, "FOO")} [constructions]''. Of course, there's nothing to stop a user typing {\tt as(x,"numeric")} if they wish.}. To accomplish this, we have to tell \proglang{R} that function {\tt as.numeric()} should execute {\tt as(x,"numeric")} when given a {\tt brob}. This is done by calling function {\tt setMethod()}: <>= setMethod("as.numeric",signature(x="brob"),function(x){as(x,"numeric")}) @ We similarly need to make {\tt as.complex()} work for brobs: <>= setAs("brob", "complex", function(from){ return(as.numeric(from)+ 0i) } ) setMethod("as.complex",signature(x="brob"),function(x){as(x,"complex")}) @ We'll need similar methods for glubs too. Better check: <>= x <- as.brob(1:4) x as.numeric(x) @ So that works. \section{Print methods} Print methods are not strictly necessary, but make using the package much easier. First, a helper function: <>= .Brob.print <- function(x, digits=5){ noquote( paste(c("-","+")[1+x@positive],"exp(",signif(x@x,digits),")",sep="")) } @ Then an \proglang{S3} method: <>= print.brob <- function(x, ...){ jj <- .Brob.print(x, ...) print(jj) return(invisible(jj)) } @ And finally a call to {\tt setMethod()}: <>= setMethod("show", "brob", function(object){print.brob(object)}) @ This two-stage methodology is recommended in the Venables and Ripley. The {\tt .Brob.print()} function does the hard work. Example of it in use: <>= as.brob(1:4) @ See how the brob object is printed out nicely, and with no special effort required of the user. \section{Get and Set methods} To be anal retentive about things, one should define {\tt C++} style accessor functions as follows: <>= <>= setGeneric("getX",function(x){standardGeneric("getX")}) setGeneric("getP",function(x){standardGeneric("getP")}) setMethod("getX","brob",function(x){x@x}) setMethod("getP","brob",function(x){x@positive}) @ but in practice I just use {\tt @} to access the slots. These are just here for good form's sake. \section{Length} Now a length: <>= <>= setMethod("length","brob",function(x){length(x@x)}) @ \section{Extracting elements of a vector} Next thing is to define some methods for extraction. This is done with {\tt setMethod()} for extraction, and {\tt setReplaceMethod()} for replacement. <>= <>= setMethod("[", "brob", function(x, i, j, drop){ if(!missing(j)){ warning("second argument to extractor function ignored") } brob(x@x[i], x@positive[i]) } ) @ See how the third argument to {\tt setMethod()} is a function whose arguments are the same as those to {\tt "["() %] }. Argument {\tt j} {\em must} be there otherwise one gets a signature error. I've put in a warning if a second argument that might be interpreted as {\tt j} is given. Now a method for replacement. This is a call to {\tt setReplaceMethod()}: <>= <>= setReplaceMethod("[",signature(x="brob"), function(x,i,j,value){ if(!missing(j)){ warning("second argument to extractor function ignored") } jj.x <- x@x jj.pos <- x@positive if(is.brob(value)){ jj.x[i] <- value@x jj.pos[i] <- value@positive return(brob(x=jj.x,positive=jj.pos)) } else { x[i] <- as.brob(value) return(x) } } ) @ See how the replacement function tests for the replacement value being a brob and acts accordingly. \section[Concatenation function ``cbrob()'']{Concatenation function {\tt cbrob()}} \label{cbrob} It is not possible to make {\tt c()} behave as expected for brobs\footnote{The ideas in this section are entirely due to John Chambers, who kindly replied to a question of mine on the \proglang{R}-devel email list} (that is, if any of its arguments are brobs, to coerce all its arguments to brobs and then concatenate). However, it is possible to define a function {\tt cbrob()} that does the job. This has to be done in several stages. First we define another user-unfriendly helper function {\tt .Brob.cPair()} which takes two arguments, coerces them to brobs, and concatenates them: <<.Brob.cPair>>= .Brob.cPair <- function(x,y){ x <- as.brob(x) y <- as.brob(y) brob(c(x@x,y@x),c(x@positive,y@positive)) } @ This is just {\tt c()} for the two slots separately. The idea is that function {\tt .Brob.cPair()} takes two arguments; both are coerced to brobs and it returns the concatenated vector of brobs. Now, we need to set up a (user-unfriendly) generic function {\tt .cPair()}: <>= <>= setGeneric(".cPair", function(x,y){standardGeneric(".cPair")}) @ Function {\tt .cPair()} is not substantive (sic): it exists purely in order to be a generic function that dispatches to {\tt .Brob.cPair()}. Now we use {\tt setMethod()} to organize the dispatch: <>= <>= setMethod(".cPair", c("brob", "brob"), function(x,y){.Brob.cPair(x,y)}) setMethod(".cPair", c("brob", "ANY"), function(x,y){.Brob.cPair(x,as.brob(y))}) setMethod(".cPair", c("ANY", "brob"), function(x,y){.Brob.cPair(as.brob(x),y)}) setMethod(".cPair", c("ANY", "ANY"), function(x,y){c(x,y)}) @ The four calls are necessary for the four different signatures that might be encountered. Note the {\tt ANY} class in the second, third, and fourth call. Thus if someone wants to write a new class of object (a lugg, say), and wants to concatenate luggs with a brob, this will work provided that they use {\tt setAs()} to make {\tt as.brob()} coerce correctly for lugg objects. The method used here allows this to be done without any changes to the Brobdingnag package. The final stage is the definition of {\tt cbrob()}, a user-friendly wrapper for the above stuff: <>= "cbrob" <- function(x, ...) { if(nargs()<3) .cPair(x,...) else .cPair(x, Recall(...)) } @ Note the recursive definition. If {\tt cbrob()} is called with {\em any} set of arguments that include a brob anywhere, this will result in the whole lot being coerced to brobs [by {\tt .Brob.cPair()}]. Which is what we want (although glubs will require more work). Just test this: <>= a <- 1:3 b <- as.brob(1e100) cbrob(a,a,b,a) @ So it worked: everything was coerced to a brob because of the single object of class brob in the call. \section{Maths} The math group generic functions are set with function {\tt setMethod()}. But, before this can be called, function {\tt sqrt()} needs a specific brob method: <>= <>= setMethod("sqrt","brob", function(x){ brob(ifelse(x@positive,x@x/2, NaN),TRUE) } ) @ Just check that: <>= sqrt(brob(4)) @ With these out of the way we can use {\tt setMethod()} to define the appropriate functions in the math group generic: <>= <>= setMethod("Math", "brob", function(x){ switch(.Generic, abs = brob(x@x), log = { out <- x@x out[!x@positive] <- NaN out }, exp = brob(x), cosh = {(brob(x) + brob(-x))/2}, sinh = {(brob(x) - brob(-x))/2}, acos =, acosh =, asin =, asinh =, atan =, atanh =, cos =, sin =, tan =, tanh =, trunc = callGeneric(as.numeric(x)), lgamma =, cumsum =, gamma =, ceiling=, floor = as.brob(callGeneric(as.numeric(x))), stop(paste(.Generic, "not allowed on Brobdingnagian numbers")) ) } ) @ See how the third argument to {\tt setMethod()} is a function. This function has access to {\tt .Generic}, in addition to {\tt x} and uses it to decide which operation to perform. See how functions {\tt acos()} to {\tt trunc()} just drop through to {\tt callGeneric(as.numeric(x))}. See also the method for {\tt log()}, which uses facts about brobs not known to \proglang{S4}. Just a quick check: <>= sin(brob(4)) @ So that works. \section{Operations} Now we need to make sure that {\tt brob(1) + brob(3)} works: the operations {\tt +, -, *, /} must work as expected. This is hard. First step: define some user-unfriendly functions that carry out the operations. For example, function {\tt .Brob.negative()} simply returns the negative of a brob. These functions are not for the user. <<.brob.arithstuff>>= .Brob.negative <- function(e1){ brob(e1@x,!e1@positive) } .Brob.ds <- function(e1,e2){ # "ds" == "different signs" xor(e1@positive,e2@positive) } .Brob.add <- function(e1,e2){ e1 <- as.brob(e1) e2 <- as.brob(e2) jj <- rbind(e1@x,e2@x) x1 <- jj[1,] x2 <- jj[2,] out.x <- double(length(x1)) jj <- rbind(e1@positive,e2@positive) p1 <- jj[1,] p2 <- jj[2,] out.pos <- p1 ds <- .Brob.ds(e1,e2) ss <- !ds #ss == "Same Sign" out.x[ss] <- pmax(x1[ss],x2[ss]) + log1p(+exp(-abs(x1[ss]-x2[ss]))) out.x[ds] <- pmax(x1[ds],x2[ds]) + log1p(-exp(-abs(x1[ds]-x2[ds]))) # Now special dispensation for 0+0: out.x[ (x1 == -Inf) & (x2 == -Inf)] <- -Inf out.pos <- p1 out.pos[ds] <- xor((x1[ds] > x2[ds]) , (!p1[ds]) ) return(brob(out.x,out.pos)) } .Brob.mult <- function(e1,e2){ e1 <- as.brob(e1) e2 <- as.brob(e2) return(brob(e1@x + e2@x, !.Brob.ds(e1,e2))) } .Brob.power <- function(e1,e2){ stopifnot(is.brob(e1) | is.brob(e2)) if(is.brob(e2)){ # e2 a brob => answer a brob (ignore signs) return(brob(log(e1) * brob(e2@x), TRUE)) } else { #e2 a non-brob (try to account for signs) s <- as.integer(2*e1@positive-1) #s = +/-1 return(brob(e1@x*as.brob(e2), (s^as.numeric(e2))>0)) } } .Brob.inverse <- function(b){brob(-b@x,b@positive)} @ Note the complexity of {\tt .Brob.add()}. This is hard because logs are good at multiplying but bad at adding [{\tt ss} and {\tt ds} mean ``same sign'' and ``different sign'' respectively]. The first step is to make sure that the unary operators {\tt +} and {\tt -} work. We do this by a call to {\tt setMethod()}: <>= <>= setMethod("Arith",signature(e1 = "brob", e2="missing"), function(e1,e2){ switch(.Generic, "+" = e1, "-" = .Brob.negative(e1), stop(paste("Unary operator", .Generic, "not allowed on Brobdingnagian numbers")) ) } ) @ Note the second argument is {\tt signature(e1 = "brob", e2="missing")}: this effectively restricts the scope to unary operators. The {\tt switch()} statement only allows the + and the -.\ Check: <>= -brob(5) @ So that works. Next step, another user-unfriendly helper function that does the dirty work: <>= .Brob.arith <- function(e1,e2){ switch(.Generic, "+" = .Brob.add (e1, e2), "-" = .Brob.add (e1, .Brob.negative(as.brob(e2))), "*" = .Brob.mult (e1, e2), "/" = .Brob.mult (e1, .Brob.inverse(as.brob(e2))), "^" = .Brob.power(e1, e2), stop(paste("binary operator \"", .Generic, "\" not defined for Brobdingnagian numbers")) ) } @ And now we can call {\tt setMethod()}: <>= setMethod("Arith", signature(e1 = "brob", e2="ANY"), .Brob.arith) setMethod("Arith", signature(e1 = "ANY", e2="brob"), .Brob.arith) setMethod("Arith", signature(e1 = "brob", e2="brob"), .Brob.arith) @ Better check it: <>= 1e100 + as.brob(10)^100 @ \section{Comparison} This is pretty much the same as the others. First, some user-unfriendly helper functions: <>= .Brob.equal <- function(e1,e2){ (e1@x==e2@x) & (e1@positive==e2@positive) } .Brob.greater <- function(e1,e2){ jj.x <- rbind(e1@x,e2@x) jj.p <- rbind(e1@positive,e2@positive) ds <- .Brob.ds(e1,e2) ss <- !ds #ss == "Same Sign" greater <- logical(length(ss)) greater[ds] <- jj.p[1,ds] greater[ss] <- jj.p[1,ss] & (jj.x[1,ss] > jj.x[2,ss]) return(greater) } @ These are the fundamental ones. We can now define another all-encompassing user-unfriendly function: <>= ".Brob.compare" <- function(e1,e2){ e1 <- as.brob(e1) e2 <- as.brob(e2) switch(.Generic, "==" = .Brob.equal(e1,e2), "!=" = !.Brob.equal(e1,e2), ">" = .Brob.greater(e1,e2), "<" = !.Brob.greater(e1,e2) & !.Brob.equal(e1,e2), ">=" = .Brob.greater(e1,e2) | .Brob.equal(e1,e2), "<=" = !.Brob.greater(e1,e2) | .Brob.equal(e1,e2), stop(paste(.Generic, "not supported for Brobdingnagian numbers")) ) } @ See how this function coerces both arguments to brobs. Now the call to {\tt setMethod()}: <>= <>= setMethod("Compare", signature(e1="brob", e2="ANY" ), .Brob.compare) setMethod("Compare", signature(e1="ANY" , e2="brob"), .Brob.compare) setMethod("Compare", signature(e1="brob", e2="brob"), .Brob.compare) @ Better check: <>= as.brob(10) < as.brob(11) as.brob(10) <= as.brob(10) @ So that works. \section{Logic} \label{logicSection} (The material in this section works in \proglang{R}-2.4.1, but not \proglang{R}-2.4.0). First a helper function: <>= .Brob.logic <- function(e1,e2){ stop("No logic currently implemented for Brobdingnagian numbers") } @ Now the calls to {\tt setMethod()}: <>= <>= setMethod("Logic",signature(e1="swift",e2="ANY"), .Brob.logic) setMethod("Logic",signature(e1="ANY",e2="swift"), .Brob.logic) setMethod("Logic",signature(e1="swift",e2="swift"), .Brob.logic) @ Note that the signatures specify {\tt swift} objects, so that glubs will be handled correctly too in one fell swoop. Note the third call to {\tt setMethod()}: without this, a call to {\tt Logic()} with signature {\tt c("swift","swift")} would be ambiguous as it might be interpreted as {\tt c("swift","ANY")} or {\tt c("ANY","swift")}. Here, class {\tt swift} extends {\tt brob} and {\tt glub}; so both brobs and glubs {\em are} {\tt swift} objects. But no object is a ``pure'' {\tt swift}; it's either a brob or a glub. This is useful here because I might dream up some new class of objects that are ``like'' brobs in some way (for example, a class of objects whose elements are quaternions with Brobdingnagian components) and it would be nice to specify behaviour that is generic to brobs and glubs and the new class of objects too. \section{Miscellaneous generics} We now have to tell \proglang{R} that certain functions are to be considered generic. The functions are {\tt max(), min(), range(), prod()}, and {\tt sum()}. The help page for (eg) {\tt max()} specifies that the arguments must be numeric, and brobs aren't numeric. In versions of \proglang{R} prior to 2.6-0 (I think), {\tt log()} needs to be made a generic with {\tt setGeneric()}. But, in versions 2.6-0 and above, all the group generics (including {\tt log}) are primitive, which means that the generic function is implicit and cannot be changed. This applies to the other group generics too ({\tt max}, {\tt min}, {\tt prod}, {\tt range} {\tt sum}). So to work with both types of \proglang{R}, one needs to check whether or not {\tt log} (or {\tt max} or whatever) is generic before calling {\tt setGeneric()}. <>= if(!isGeneric("log")){ setGeneric("log",group="Math") } @ <>= <>= if(!isGeneric("sum")){ setGeneric("max", function(x, ..., na.rm = FALSE) { standardGeneric("max") }, useAsDefault = function(x, ..., na.rm = FALSE) { base::max(x, ..., na.rm = na.rm) }, group = "Summary") setGeneric("min", function(x, ..., na.rm = FALSE) { standardGeneric("min") }, useAsDefault = function(x, ..., na.rm = FALSE) { base::min(x, ..., na.rm = na.rm) }, group = "Summary") setGeneric("range", function(x, ..., na.rm = FALSE) { standardGeneric("range") }, useAsDefault = function(x, ..., na.rm = FALSE) { base::range(x, ..., na.rm = na.rm) }, group = "Summary") setGeneric("prod", function(x, ..., na.rm = FALSE) { standardGeneric("prod") }, useAsDefault = function(x, ..., na.rm = FALSE) { base::prod(x, ..., na.rm = na.rm) }, group = "Summary") setGeneric("sum", function(x, ..., na.rm = FALSE) { standardGeneric("sum") }, useAsDefault = function(x, ..., na.rm = FALSE) { base::sum(x, ..., na.rm = na.rm) }, group = "Summary") } @ Now we need some more user-unfriendly helper functions: <>= .Brob.max <- function(x, ..., na.rm=FALSE){ p <- x@positive val <- x@x if(any(p)){ return(brob(max(val[p]))) } else { # all negative return(brob(min(val),FALSE)) } } .Brob.prod <- function(x){ p <- x@positive val <- x@x return(brob(sum(val),(sum(p)%%2)==0)) } .Brob.sum <- function(x){ .Brob.sum.allpositive( x[x>0]) - .Brob.sum.allpositive(-x[x<0]) } .Brob.sum.allpositive <- function(x){ if(length(x)<1){return(as.brob(0))} val <- x@x p <- x@positive mv <- max(val) return(brob(mv + log1p(sum(exp(val[-which.max(val)]-mv))),TRUE)) } @ Note the final function that sums its arguments, which are all assumed to be positive, in an intelligent, accurate, and efficient manner. No checking is done (this is not a user-friendly function!). We can define {\tt .Brob.sum()} in terms of this: return the difference between the sum of the positive arguments and and the sum of minus the negative arguments. <>= <>= setMethod("Summary", "brob", function(x, ..., na.rm=FALSE){ switch(.Generic, max = .Brob.max( x, ..., na.rm=na.rm), min = -.Brob.max(-x, ..., na.rm=na.rm), range = cbrob(min(x,na.rm=na.rm),max(x,na.rm=na.rm)), prod = .Brob.prod(x), sum = .Brob.sum(x), stop(paste(.Generic, "not allowed on Brobdingnagian numbers")) ) } ) @ Better check: <>= sum(as.brob(1:100)) - 5050 @ showing acceptable accuracy. \section{Examples of the package in use} We can try to evaluate a factorial. Stirling's approximation is~$n!\sim\sqrt{2\pi n}\,e^{-n}n^n$: <>= stirling <- function(x){sqrt(2*pi*x)*exp(-x)*x^x} @ And this should work seamlessly with Brobs: <>= stirling(100) stirling(as.brob(100)) @ And are they the same? <>= as.numeric(stirling(100)/stirling(as.brob(100))) @ \ldots pretty near. But the great advantage of Brobdingnagian numbers is that they can handle numbers larger than the IEEE limit: <>= stirling(1000) stirling(as.brob(1000)) @ \noindent and this is accurate to about~12 sig figs, which is accurate enough for many purposes. The number of sig figs decreases with progressively larger numbers, essentially because increasing amounts of floating point accuracy is gobbled up by storing the exponent of a large number, and less is left for the mantissa. \section*{Acknowledgments} I gratefully acknowledge the help given to me by many members of the \proglang{R}-help and \proglang{R}-devel lists, especially Martin Maechler, Brian Ripley, and John Chambers. \nocite{*} \bibliography{brob} \end{document} Brobdingnag/vignettes/Brobdingnag.Rnw0000644000176200001440000001672014176571204017417 0ustar liggesusers\documentclass[nojss]{jss} \usepackage{dsfont} \usepackage{bbm} \usepackage{amsfonts} \usepackage{wasysym} \author{Robin K. S. Hankin\\Auckland University of Technology} \title{Very large numbers in \proglang{R}: Introducing package \pkg{Brobdingnag}} %\VignetteIndexEntry{The Brobdingnag: package} \Plainauthor{Robin K. S. Hankin} \Plaintitle{Very large numbers in R: Introducing package Brobdingnag} \Plaintitle{Introducing package Brobdingnag} \Abstract{ This vignette shows how to use the \pkg{Brobdingnag} package to manipulate very large numbers; it is based on~\cite{Rnews:Hankin:2007}. The other vignette shows how to use \proglang{S4} methods in the context of a simple package. } \Keywords{\proglang{S4} methods, Brobdingnag, \proglang{R}} \Plainkeywords{S4 methods, Brobdingnag, R} \Address{ Robin K. S. Hankin\\ Auckland University of Technology E-mail: \email{hankin.robin@gmail.com}\hfill\includegraphics[width=1in]{\Sexpr{system.file("help/figures/brobdingnag.png",package="Brobdingnag")}} } %% need no \usepackage{Sweave.sty} \SweaveOpts{echo=TRUE} \begin{document} \newsymbol\leqslant 1336 \hfill\includegraphics[width=1in]{\Sexpr{system.file("help/figures/brobdingnag.png",package="Brobdingnag")}} \section{Introduction} The largest floating point number representable in standard double precision arithmetic is a little under~$2^{1024}$, or about~$1.79\times 10^{308}$. This is too small for some applications. The \proglang{R} package \pkg{Brobdingnag}~\citep{swift1726} overcomes this limit by representing a real number~$x$ using a double precision variable with value~$\log\left|x\right|$, and a logical corresponding to~$x\geq 0$; the \proglang{S4} class of such objects is \code{brob}. Complex numbers with large absolute values (class \code{glub}) may be represented using a pair of \code{brob}s to represent the real and imaginary components. The package allows user-transparent access to the large numbers allowed by Brobdingnagian arithmetic. The package also includes a vignette---\code{brob}---which documents the \proglang{S4} methods used and includes a step-by-step tutorial. The vignette also functions as a ``Hello, World!'' example of \proglang{S4} methods as used in a simple package. It also includes a full description of the \code{glub} class. \section[Package ``Brobdingnag'' in use]{Package \pkg{Brobdingnag} in use} Most readers will be aware of a googol which is equal to~$10^{100}$: <>= <>= require(Brobdingnag) <>= googol <- as.brob(10)^100 @ Note the coercion of \code{double} value \code{10} to an object of class \code{brob} using function \code{as.brob()}: raising this to the power~100 (also double) results in another \code{brob}. The result is printed using exponential notation, which is convenient for very large numbers. A googol is well within the capabilities of standard double precision arithmetic. Now, however, suppose we wish to compute its factorial. Taking the first term of Stirling's series gives <>= stirling <- function(n){n^n*exp(-n)*sqrt(2*pi*n)} @ \noindent which then yields <>= stirling(googol) @ Note the transparent coercion to \code{brob} form within function \code{stirling()}. It is also possible to represent numbers very close to~1. Thus <>= 2^(1/googol) @ It is worth noting that if~$x$ has an exact representation in double precision, then~$e^x$ is exactly representable using the system described here. Thus~$e$ and~$e^{1000}$ may be represented exactly. \subsection{Accuracy} For small numbers (that is, representable using standard double precision floating point arithmetic), \pkg{Brobdingnag} suffers a slight loss of precision compared to normal representation. Consider the following function, whose return value for nonzero arguments is algebraically zero: <>= f <- function(x){as.numeric( (pi*x -3*x -(pi-3)*x)/x)} @ \begin{verbatim} f <- function(x){ as.numeric( (pi*x -3*x -(pi-3)*x)/x) } \end{verbatim} This function combines multiplication and addition; one might expect a logarithmic system such as described here to have difficulty with it. <>= f(1/7) f(as.brob(1/7)) @ This typical example shows that Brobdingnagian numbers suffer a slight loss of precision for numbers of moderate magnitude. This degradation increases with the magnitude of the argument: <>= f(1e100) f(as.brob(1e100)) @ Here, the brobs' accuracy is about two orders of magnitude worse than double precision arithmetic: this would be expected, as the number of bits required to specify the exponent goes as $\log\log x$. Compare <>= f(as.brob(10)^1000) @ \noindent showing a further degradation of precision. However, observe that conventional double precision arithmetic cannot deal with numbers this big, and the package returns about 12 correct significant figures. \section{A practical example} In the field of population dynamics, and especially the modelling of biodiversity~\citep{hankin2007b,hubbell2001}, complicated combinatorial formulae often arise. \citet{etienne2005}, for example, considers a sample of~$N$ individual organisms taken from some natural population; the sample includes~$S$ distinct species, and each individual is assigned a label in the range~$1$ to~$S$. The sample comprises~$n_i$ members of species~$i$, with~$1\leq i\leq S$ and~$\sum n_i=N$. For a given sample~$D$ Etienne defines, amongst other terms, $K(D,A)$ for $1\leq A\leq N-S+1$ as \begin{equation} \sum_{ \left\{ a_1,\ldots,a_S\left| \sum_{i=1}^S a_i=A\right. \right\}} \prod_{i=1}^S \frac{ \overline{s}(n_i,a_i) \overline{s}(a_i,1)}{ \overline{s}(n_i,1)} \end{equation} \noindent where~$\overline{s}(n,a)$ is the Stirling number of the second kind~\citep{abramowitz1965}. The summation is over~$a_i=1,\ldots,n_i$ with the restriction that the~$a_i$ sum to~$A$, as carried out by \code{blockparts()} of the \pkg{partitions} package~\citep{hankin2006,hankin2007}. Taking an intermediate-sized dataset due to Saunders\footnote{The dataset comprises species counts on kelp holdfasts; here \code{saunders.exposed.tot} of package \pkg{untb}~\citep{hankin2007b}, is used.} of only~5903 individuals---a relatively small dataset in this context---the maximal element of~$K(D,A)$ is about~$1.435\times 10^{1165}$. The accuracy of package \pkg{Brobdingnag} in this context may be assessed by comparing it with that computed by \proglang{PARI/GP}~\citep{batut2000} with a working precision of~100 decimal places; the natural logs of the two values are~$2682.8725605988689$ and~$2682.87256059887$ respectively: identical to 14 significant figures. %Pari with 100 decimal places gives 2682.872560598868918515209515642292607616628612201118344882119616522539674163937533805390351760715777. % 2682.8725605988689 %and with R: 2682.87256059887 \section{Conclusions} The \pkg{Brobdingnag} package allows representation and manipulation of numbers larger than those covered by standard double precision arithmetic, although accuracy is eroded for very large numbers. This facility is useful in several contexts, including combinatorial computations such as encountered in theoretical modelling of biodiversity. \subsubsection*{Acknowledgments} I would like to acknowledge the many stimulating and helpful comments made by the \proglang{R}-help list over the years. \bibliography{brob} \end{document} Brobdingnag/vignettes/brobmat.Rmd0000644000176200001440000000663414176571204016610 0ustar liggesusers--- title: "Brobdingnagian matrices" author: "Robin K. S. Hankin" date: "`r Sys.Date()`" vignette: > %\VignetteIndexEntry{brobmat} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r set-options, echo = FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>", dev = "png", fig.width = 7, fig.height = 3.5, message = FALSE, warning = FALSE) options(width = 80, tibble.width = Inf) ``` # Brobdgingnagian matrices R package `Brobdingnag` has basic functionality for matrices. It includes matrix multiplication and addition, but determinants and matrix inverses are not implemented. First load the package: ```{r} library("Brobdingnag") ``` The standard way to create a Brobdgingnagian matrix (a `brobmat`) is to use function `brobmat()` which takes arguments similar to `matrix()` and returns a matrix of entries created with `brob()`: ```{r} M1 <- brobmat(-10:13,4,6) colnames(M1) <- state.abb[1:6] M1 ``` Function `brobmat()` takes an argument `positive` which specifies the sign: ```{r} M2 <- brobmat( c(1,104,-66,45,1e40,-2e40,1e-200,232.2),2,4, positive=c(T,F,T,T,T,F,T,T)) M2 ``` Standard matrix arithmetic is implemented, thus: ```{r} rownames(M2) <- c("a","b") colnames(M2) <- month.abb[1:4] M2 M2[2,3] <- 0 M2 M2+1000 ``` We can also do matrix multiplication, although it is slow: ```{r} M2 %*% M1 ``` ## Numerical verification: matrix multiplication We will verify matrix multiplication by carrying out the same operation in two different ways. First, create two largish Brobdingnagian matrices: ```{r} nrows <- 11 ncols <- 18 M3 <- brobmat(rnorm(nrows*ncols),nrows,ncols,positive=sample(c(T,F),nrows*ncols,replace=T)) M4 <- brobmat(rnorm(nrows*ncols),ncols,nrows,positive=sample(c(T,F),nrows*ncols,replace=T)) M3[1:3,1:3] ``` Now calculate the matrix product by coercing to numeric matrices and multiplying:q ```{r} p1 <- as.matrix(M3) %*% as.matrix(M4) ``` and then by using Brobdingnagian matrix multiplying, and then coercing to numeric: ```{r} p2 <- as.matrix(M3 %*% M4) ``` The difference: ```{r} max(abs(p1-p2)) ``` is small. Now the other way: ```{r} q1 <- M3 %*% M4 q2 <- as.brobmat(as.matrix(M3) %*% as.matrix(M4)) max(abs(as.brob(q1-q2))) ``` ## Numerical verification: integration with the `cubature` package The matrix functionality of the `Brobdingnag` package was originally written to leverage the functionality of the `cubature` package. Here I give some numerical verification for this. Suppose we wish to evaluate \[ \int_{x=0}^{x=4}(x^2-4)\,dx \] using numerical methods. See how the integrand includes positive and negative values; the theoretical value is $\frac{16}{3}=5.33\ldots$. The `cubature` idiom for this would be ```{r,label = numericalintegration} library("cubature") f.numeric <- function(x){x^2 - 4} out.num <- cubature::hcubature(f = f.numeric, lowerLimit = 0, upperLimit = 4, vectorInterface = TRUE) out.num ``` and the Brobdingnagian equivalent would be ```{r,label = numericalintegrationbrob} f.brob <- function(x) { x <- as.brob(x[1, ]) as.matrix( brobmat(x^2 - 4, ncol = length(x))) } out.brob <- cubature::hcubature(f = f.brob, lowerLimit = 0, upperLimit = 4, vectorInterface = TRUE) out.brob ``` We may compare the two methods: ```{r,label=comparebrobandnumeric} out.brob$integral - out.num$integral ``` Brobdingnag/R/0000755000176200001440000000000014162030747012673 5ustar liggesusersBrobdingnag/R/aaa_allclasses.R0000644000176200001440000000072113762776702015763 0ustar liggesuserssetClass("brobmat", slots = c(x="matrix",positive="logical")) setClass("swift", representation = "VIRTUAL" ) setClass("brob", slots = c(x="numeric",positive="logical"), contains = "swift" ) setClass("glub", slots = c(real="brob",imag="brob"), contains = "swift" ) ## Following modified from the Matrix package: setClassUnion("index", members = c("numeric", "logical", "character")) Brobdingnag/R/matrix.R0000644000176200001440000002124713762776702014345 0ustar liggesusers `.brobmat.valid` <- function(object){ if(length(object@x) != length(object@positive)){ return("length mismatch") } else { return(TRUE) } } setValidity("brobmat", .Brob.valid) `newbrobmat` <- function(x,positive){ new("brobmat", x=x, positive=c(positive)) # this is the only use of new() here } `brobmat` <- function(..., positive){ data <- list(...)[[1]] if(is.matrix(data)){ M <- data } else if(is.brob(data)){ jj <- list(...) jj[[1]] <- getX(data) M <- do.call(matrix,jj) # signs not accounted for return(newbrobmat(M,positive=getP(data))) } else { M <- matrix(...) } if(missing(positive)){positive <- rep(TRUE,length(M))} positive <- cbind(c(M),positive)[,2]>0 return(newbrobmat(M,positive=positive)) } `is.brobmat` <- function(x){is(x,"brobmat")} setMethod("getX","brobmat",function(x){x@x}) setMethod("getX","numeric",function(x){x}) setMethod("getP","brobmat",function(x){ out <- getX(x) storage.mode(out) <- "logical" out[] <- x@positive ## No occurrences of '@' after this line return(out) }) setMethod("getP","numeric",function(x){x>0}) setMethod("length","brobmat",function(x){length(getX(x))}) `as.brobmat` <- function(x){ if(is.brob(x)){ return(newbrobmat(matrix(getX(x)),matrix(getP(x)))) # n-by-1 } else if(is.numeric(x)){ x <- as.matrix(x) return(newbrobmat(log(abs(x)), c(x>=0))) } } `is.brobmat` <- function(x){is(x,"brobmat")} setAs("brobmat", "matrix", function(from){ out <- exp(getX(from)) negs <- !getP(from) out[negs] <- -out[negs] return(out) } ) `brobmat_to_brob` <- function(x){ brob(c(getX(x)),c(getP(x))) } setMethod("as.matrix",signature(x="brobmat"),function(x){as(x,"matrix")}) setGeneric("nrow") setGeneric("ncol") setMethod("nrow",signature(x="brobmat"),function(x){nrow(getX(x))}) setMethod("ncol",signature(x="brobmat"),function(x){ncol(getX(x))}) `.brobmat.print` <- function(x, digits=5){ out <- getX(x) out[] <- paste(c("-","+")[1+getP(x)],"exp(",signif(out,digits),")",sep="") noquote(out) } `print.brobmat` <- function(x, ...){ jj <- .brobmat.print(x, ...) print(jj) return(invisible(jj)) } setMethod("show", "brobmat", function(object){print.brobmat(object)}) setMethod("Math", "brobmat", function(x){ switch(.Generic, abs = brobmat(getX(x)), log = { out <- getX(x) out[!getP(x)] <- NaN out # numeric matrix }, log10 = { out <- getX(x) out[!getP(x)] <- NaN out/log(10) # numeric matrix }, log2 = { out <- getX(x) out[!getP(x)] <- NaN out/log(2) # numeric matrix }, exp =, cosh =, sinh =, acos =, acosh =, asin =, asinh =, atan =, atanh =, cos =, sin =, tan =, tanh =, trunc =, lgamma =, cumsum =, gamma =, ceiling=, floor =, stop(paste(.Generic, "not implemented on brobmats")) ) } ) setMethod("Arith",signature(e1 = "brobmat", e2="missing"), function(e1,e2){ switch(.Generic, "+" = e1, "-" = newbrobmat(getX(e1),positive=!getP(e1)), stop(paste("Unary operator", .Generic, "not allowed on brobmats")) ) } ) "brobmat.arith" <- function(e1,e2){ switch(.Generic, "+" = brobmat.add (e1, e2), "-" = brobmat.add (e1, -e2), "*" = brobmat.mult (e1, e2), "/" = brobmat.mult (e1, brobmat.inverse(e2)), "^" = brobmat.power(e1, e2), stop(paste("binary operator \"", .Generic, "\" not defined for Brobdingnagian numbers")) ) } setMethod("Arith", signature(e1 = "brobmat", e2="brob" ), brobmat.arith) setMethod("Arith", signature(e1 = "brob" , e2="brobmat"), brobmat.arith) setMethod("Arith", signature(e1 = "brobmat", e2="ANY" ), brobmat.arith) setMethod("Arith", signature(e1 = "ANY" , e2="brobmat"), brobmat.arith) setMethod("Arith", signature(e1 = "brobmat", e2="brobmat"), brobmat.arith) `getat` <- function(e1,e2=e1){ if(length(e1)>=length(e2)){ return(attributes(getX(e1))) } else { return(attributes(getX(e2))) } } `brobmat.add` <- function(e1,e2){ out <- as.brob(e1) + as.brob(e2) jj <- getX(out) attributes(jj) <- getat(e1,e2) return(newbrobmat(jj,getP(out))) } `brobmat.mult` <- function(e1,e2){ out <- as.brob(e1) * as.brob(e2) jj <- getX(out) attributes(jj) <- getat(e1,e2) return(newbrobmat(jj,getP(out))) } `brobmat.inverse` <- function(e1){ if(is.brobmat(e1)){ out <- 1/as.brob(e1) jj <- getX(out) attributes(jj) <- getat(e1) return(newbrobmat(jj,getP(out))) } else { return(1/e1) } } `brobmat.power` <- function(e1,e2){ out <- as.brob(e1) ^ as.brob(e2) jj <- getX(out) attributes(jj) <- getat(e1,e2) return(newbrobmat(jj,getP(out))) } "brobmat.equal" <- function(e1,e2){ out <- as.brob(e1) == as.brob(e2) attributes(out) <- getat(e1,e2) return(out) } "brobmat.greater" <- function(e1,e2){ out <- as.brob(e1) > as.brob(e2) attributes(out) <- getat(e1,e2) return(out) } "brobmat.compare" <- function(e1,e2){ if( (length(e1) == 0) | (length(e2)==0)) { return(logical(0)) } switch(.Generic, "==" = brobmat.equal(e1,e2), "!=" = !brobmat.equal(e1,e2), ">" = brobmat.greater(e1,e2), "<" = !brobmat.greater(e1,e2) & !brobmat.equal(e1,e2), ">=" = brobmat.greater(e1,e2) | brobmat.equal(e1,e2), "<=" = !brobmat.greater(e1,e2) | brobmat.equal(e1,e2), stop(paste(.Generic, "not supported for brobmats numbers")) ) } setMethod("Compare", signature(e1="brobmat", e2="ANY" ), brobmat.compare) setMethod("Compare", signature(e1="ANY" , e2="brobmat"), brobmat.compare) setMethod("Compare", signature(e1="brobmat", e2="brobmat"), brobmat.compare) `brobmat_matrixprod` <- function(x,y){ stopifnot(ncol(x)==nrow(y)) out <- brobmat(NA,nrow(x),ncol(y)) for(i in seq_len(nrow(x))){ for(j in seq_len(ncol(y))){ out[i,j] <- sum(x[i,,drop=TRUE]*y[,j,drop=TRUE]) } # j loop closes } # i loop closes if(!is.null(rownames(x))){rownames(out) <- rownames(x)} if(!is.null(colnames(x))){colnames(out) <- colnames(y)} return(out) } setMethod("%*%", signature(x="brobmat", y="ANY" ), brobmat_matrixprod) setMethod("%*%", signature(x="ANY" , y="brobmat"), brobmat_matrixprod) setMethod("%*%", signature(x="brobmat", y="brobmat"), brobmat_matrixprod) setGeneric("as.vector") setMethod("as.vector", signature(x="brobmat"), function(x){as.brob(x)}) setMethod("as.vector", signature(x="brob"), function(x){x}) setGeneric("rownames") setMethod("rownames", signature(x="brobmat"), function(x){rownames(getX(x))}) setGeneric("colnames") setMethod("colnames", signature(x="brobmat"), function(x){colnames(getX(x))}) setGeneric("dimnames") setMethod("dimnames", signature(x="brobmat"), function(x){dimnames(getX(x))}) setGeneric("rownames<-") setMethod("rownames<-", signature(x="brobmat"), function(x,value){ jj <- getX(x) rownames(jj) <- value return(brobmat(jj,getP(x))) } ) setGeneric("colnames<-") setMethod("colnames<-", signature(x="brobmat"), function(x,value){ jj <- getX(x) colnames(jj) <- value return(brobmat(jj,getP(x))) } ) setGeneric("dimnames<-") setMethod("dimnames<-", signature(x="brobmat"), function(x,value){ jj <- getX(x) dimnames(jj) <- value return(brobmat(jj,getP(x))) } ) setGeneric("diag", function(x, ...){standardGeneric("diag")}) setMethod("diag", signature(x="brobmat"),function(x,...){brob(diag(getX(x)),diag(getP(x)))}) setMethod("diag", signature(x="ANY"), function(x,...){base::diag(x)}) setGeneric("t", function(x, ...) standardGeneric("t")) setMethod("t", signature(x="brobmat"),function(x,...){brob(t(getX(x)),t(getP(x)))}) setMethod("t", signature(x="ANY"),function(x,...){base::t(x)}) Brobdingnag/R/brob.R0000644000176200001440000002556214104176575013762 0ustar liggesusers ".Brob.valid" <- function(object){ len <- length(object@positive) if(len != length(object@x)){ return("length mismatch") } else { return(TRUE) } } setValidity("brob", .Brob.valid) "brob" <- function(x=double(),positive){ if(missing(positive)){ positive <- rep(TRUE,length(x)) } if(length(positive)==1){ positive <- rep(positive,length(x)) } new("brob",x=as.numeric(x),positive=positive) } "is.brob" <- function(x){is(x,"brob")} "is.glub" <- function(x){is(x,"glub")} "as.brob" <- function(x){ if(is.brob(x)){ return(x) } else if(is.complex(x)) { warning("imaginary parts discarded") return(Recall(Re(x))) } else if(is.glub(x)){ warning("imaginary parts discarded") return(Re(x)) } else if(is.brobmat(x)){ return(brobmat_to_brob(x)) } else { return(brob(log(abs(c(x))), c(x)>=0)) } } setAs("brob", "numeric", function(from){ out <- exp(from@x) out[!from@positive] <- -out[!from@positive] return(out) } ) setMethod("as.numeric",signature(x="brob"),function(x){as(x,"numeric")}) setAs("brob", "complex", function(from){ return(as.numeric(from)+ 0i) } ) setMethod("as.complex",signature(x="brob"),function(x){as(x,"complex")}) ".Brob.print" <- function(x, digits=5){ noquote( paste(c("-","+")[1+x@positive],"exp(",signif(x@x,digits),")",sep="")) } "print.brob" <- function(x, ...){ jj <- .Brob.print(x, ...) print(jj) return(invisible(jj)) } setMethod("show", "brob", function(object){print.brob(object)}) setGeneric("getX",function(x){standardGeneric("getX")}) setGeneric("getP",function(x){standardGeneric("getP")}) setMethod("getX","brob",function(x){x@x}) setMethod("getP","brob",function(x){x@positive}) setMethod("length","brob",function(x){length(x@x)}) setMethod("is.infinite","brob",function(x){x@x == +Inf}) setMethod("is.finite" ,"brob",function(x){x@x != +Inf}) setGeneric("sign<-",function(x,value){standardGeneric("sign<-")}) setMethod("sign<-","brob",function(x,value){ brob(x@x,value) } ) setMethod("[", "brob", function(x, i, j, drop){ if(!missing(j)){ warning("second argument to extractor function ignored") } brob(x@x[i], x@positive[i]) } ) setReplaceMethod("[",signature(x="brob"), function(x,i,j,value){ jj.x <- x@x jj.pos <- x@positive if(is.brob(value)){ jj.x[i] <- value@x jj.pos[i] <- value@positive return(brob(x=jj.x,positive=jj.pos)) } else { x[i] <- as.brob(value) return(x) } } ) setGeneric(".cPair", function(x,y){standardGeneric(".cPair")}) setMethod(".cPair", c("brob", "brob"), function(x,y){.Brob.cPair(x,y)}) setMethod(".cPair", c("brob", "ANY"), function(x,y){.Brob.cPair(x,as.brob(y))}) setMethod(".cPair", c("ANY", "brob"), function(x,y){.Brob.cPair(as.brob(x),y)}) setMethod(".cPair", c("ANY", "ANY"), function(x,y){c(x,y)}) "cbrob" <- function(x, ...) { if(nargs()<3) .cPair(x,...) else .cPair(x, Recall(...)) } ".Brob.cPair" <- function(x,y){ x <- as.brob(x) y <- as.brob(y) brob(c(x@x,y@x),c(x@positive,y@positive)) } setGeneric("log") setMethod("sqrt","brob", function(x){ brob(ifelse(x@positive,x@x/2, NaN),TRUE) } ) setMethod("Math", "brob", function(x){ switch(.Generic, abs = brob(x@x), log = { out <- x@x out[!x@positive] <- NaN out }, log10 = { out <- x@x/log(10) out[!x@positive] <- NaN out }, log2 = { out <- x@x/log(2) out[!x@positive] <- NaN out }, exp = brob(x), cosh = {(brob(x) + brob(-x))/2}, sinh = {(brob(x) - brob(-x))/2}, acos =, acosh =, asin =, asinh =, atan =, atanh =, cos =, sin =, tan =, tanh =, trunc = callGeneric(as.numeric(x)), lgamma =, cumsum =, gamma =, ceiling=, floor = as.brob(callGeneric(as.numeric(x))), stop(paste(.Generic, "not allowed on Brobdingnagian numbers")) ) } ) ".Brob.negative" <- function(e1){ brob(e1@x,!e1@positive) } ".Brob.ds" <- function(e1,e2){ # "ds" == "different signs" xor(e1@positive,e2@positive) } ".Brob.add" <- function(e1,e2){ e1 <- as.brob(e1) e2 <- as.brob(e2) jj <- rbind(e1@x,e2@x) x1 <- jj[1,] x2 <- jj[2,] out.x <- double(length(x1)) jj <- rbind(e1@positive,e2@positive) p1 <- jj[1,] p2 <- jj[2,] out.pos <- p1 ds <- .Brob.ds(e1,e2) ss <- !ds #ss == "Same Sign" out.x[ss] <- pmax(x1[ss],x2[ss]) + log1p(+exp(-abs(x1[ss]-x2[ss]))) out.x[ds] <- pmax(x1[ds],x2[ds]) + log1p(-exp(-abs(x1[ds]-x2[ds]))) # Now special dispensation for 0+0: out.x[ (x1 == -Inf) & (x2 == -Inf)] <- -Inf out.pos <- p1 out.pos[ds] <- xor((x1[ds] > x2[ds]) , (!p1[ds]) ) return(brob(out.x,out.pos)) } ".Brob.mult" <- function(e1,e2){ e1 <- as.brob(e1) e2 <- as.brob(e2) return(brob(e1@x + e2@x, !.Brob.ds(e1,e2))) } ".Brob.power"<- function(e1,e2){ stopifnot(is.brob(e1) | is.brob(e2)) if(is.brob(e2)){ # e2 a brob => answer a brob (ignore signs) return(brob(log(e1) * brob(e2@x), TRUE)) } else { #e2 a non-brob (try to account for signs) s <- as.integer(2*e1@positive-1) #s = +/-1 return(brob(e1@x*as.brob(e2), (s^as.numeric(e2))>0)) } } ".Brob.inverse" <- function(b){brob(-b@x,b@positive)} setMethod("Arith",signature(e1 = "brob", e2="missing"), function(e1,e2){ switch(.Generic, "+" = e1, "-" = .Brob.negative(e1), stop(paste("Unary operator", .Generic, "not allowed on Brobdingnagian numbers")) ) } ) ".Brob.arith" <- function(e1,e2){ switch(.Generic, "+" = .Brob.add (e1, e2), "-" = .Brob.add (e1, .Brob.negative(as.brob(e2))), "*" = .Brob.mult (e1, e2), "/" = .Brob.mult (e1, .Brob.inverse(as.brob(e2))), "^" = .Brob.power(e1, e2), stop(paste("binary operator \"", .Generic, "\" not defined for Brobdingnagian numbers")) ) } setMethod("Arith", signature(e1 = "brob", e2="ANY"), .Brob.arith) setMethod("Arith", signature(e1 = "ANY", e2="brob"), .Brob.arith) setMethod("Arith", signature(e1 = "brob", e2="brob"), .Brob.arith) ".Brob.equal" <- function(e1,e2){ (e1@x==e2@x) & (e1@positive==e2@positive) } ".Brob.greater" <- function(e1,e2){ jj.x <- rbind(e1@x,e2@x) jj.p <- rbind(e1@positive,e2@positive) ds <- .Brob.ds(e1,e2) ss <- !ds #ss == "Same Sign" greater <- logical(length(ss)) greater[ds] <- jj.p[1,ds] greater[ss] <- jj.p[1,ss] & (jj.x[1,ss] > jj.x[2,ss]) return(greater) } ".Brob.compare" <- function(e1,e2){ if( (length(e1) == 0) | (length(e2)==0)) { return(logical(0)) } e1 <- as.brob(e1) e2 <- as.brob(e2) switch(.Generic, "==" = .Brob.equal(e1,e2), "!=" = !.Brob.equal(e1,e2), ">" = .Brob.greater(e1,e2), "<" = !.Brob.greater(e1,e2) & !.Brob.equal(e1,e2), ">=" = .Brob.greater(e1,e2) | .Brob.equal(e1,e2), "<=" = !.Brob.greater(e1,e2) | .Brob.equal(e1,e2), stop(paste(.Generic, "not supported for Brobdingnagian numbers")) ) } setMethod("Compare", signature(e1="brob", e2="ANY" ), .Brob.compare) setMethod("Compare", signature(e1="ANY" , e2="brob"), .Brob.compare) setMethod("Compare", signature(e1="brob", e2="brob"), .Brob.compare) ".Brob.logic" <- function(e1,e2){ stop("No logic currently implemented for Brobdingnagian numbers") } setMethod("Logic",signature(e1="swift",e2="ANY"), .Brob.logic) setMethod("Logic",signature(e1="ANY",e2="swift"), .Brob.logic) setMethod("Logic",signature(e1="swift",e2="swift"), .Brob.logic) if(!isGeneric("max")){ setGeneric("max", function(x, ..., na.rm = FALSE) { standardGeneric("max") }, useAsDefault = function(x, ..., na.rm = FALSE) { base::max(x, ..., na.rm = na.rm) }, group = "Summary") } if(!isGeneric("min")){ setGeneric("min", function(x, ..., na.rm = FALSE) { standardGeneric("min") }, useAsDefault = function(x, ..., na.rm = FALSE) { base::min(x, ..., na.rm = na.rm) }, group = "Summary") } if(!isGeneric("range")){ setGeneric("range", function(x, ..., na.rm = FALSE) { standardGeneric("range") }, useAsDefault = function(x, ..., na.rm = FALSE) { base::range(x, ..., na.rm = na.rm) }, group = "Summary") } if(!isGeneric("prod")){ setGeneric("prod", function(x, ..., na.rm = FALSE) { standardGeneric("prod") }, useAsDefault = function(x, ..., na.rm = FALSE) { base::prod(x, ..., na.rm = na.rm) }, group = "Summary") } if(!isGeneric("sum")){ setGeneric("sum", function(x, ..., na.rm = FALSE) { standardGeneric("sum") }, useAsDefault = function(x, ..., na.rm = FALSE) { base::sum(x, ..., na.rm = na.rm) }, group = "Summary") } ".Brob.max" <- function(x, ..., na.rm=FALSE){ p <- x@positive val <- x@x if(any(p)){ return(brob(max(val[p]))) } else { # all negative return(brob(min(val),FALSE)) } } ".Brob.prod" <- function(x){ p <- x@positive val <- x@x return(brob(sum(val),(sum(!p)%%2)==0)) } ".Brob.sum" <- function(x){ .Brob.sum.allpositive( x[x>0]) - .Brob.sum.allpositive(-x[x<0]) } ".Brob.sum.allpositive" <- function(x){ if(length(x)<1){return(as.brob(0))} val <- x@x p <- x@positive mv <- max(val) return(brob(mv + log1p(sum(exp(val[-which.max(val)]-mv))),TRUE)) } setMethod("Summary", "brob", function(x, ..., na.rm=FALSE){ switch(.Generic, max = .Brob.max( x, ..., na.rm=na.rm), min = -.Brob.max(-x, ..., na.rm=na.rm), range = cbrob(min(x,na.rm=na.rm),max(x,na.rm=na.rm)), prod = .Brob.prod(x), sum = .Brob.sum(x), stop(paste(.Generic, "not allowed on Brobdingnagian numbers")) ) } ) setMethod("plot",signature(x="brob",y="missing"),function(x, ...){plot.default(as.numeric(x), ...)}) setMethod("plot",signature(x="brob",y="ANY" ),function(x, y, ...){plot.default(as.numeric(x), as.numeric(y), ...)}) setMethod("plot",signature(x="ANY" ,y="brob"),function(x, y, ...){plot.default(as.numeric(x), as.numeric(y), ...)}) Brobdingnag/R/glub.R0000644000176200001440000002063213762776702013767 0ustar liggesusers ".Glub.valid" <- function(object){ if(length(object@real) == length(object@imag)){ return(TRUE) } else { return("length mismatch") } } setValidity("glub", .Glub.valid) setAs("glub", "complex", function(from){ complex(real=as.numeric(from@real), imaginary=as.numeric(from@imag)) } ) setMethod("as.complex",signature(x="glub"),function(x){as(x,"complex")}) setAs("glub", "numeric", function(from){ warning("imaginary parts discarded in coercion; use as.complex() to retain them") as.numeric(Re(from)) } ) setMethod("as.numeric",signature(x="glub"),function(x){as(x,"numeric")}) setMethod("is.infinite",signature(x="glub"),function(x){is.infinite(Re(x)) | is.infinite(Im(x))}) setMethod("is.finite",signature(x="glub"),function(x){is.finite(Re(x)) & is.finite(Im(x))}) "glub" <- function(real=double(), imag=double()){ if(missing(imag)){ imag <- 0 } real <- as.brob(real) imag <- as.brob(imag) jj.x <- cbind(real@x,imag@x) jj.p <- cbind(real@positive,imag@positive) new("glub", real = brob(jj.x[,1],jj.p[,1]), imag = brob(jj.x[,2],jj.p[,2]) ) } setMethod("Re","glub",function(z){z@real}) setMethod("Im","glub",function(z){z@imag}) setMethod("length","glub",function(x){length(Re(x))}) setMethod("Mod", "glub", function(z){sqrt(Re(z)*Re(z) + Im(z)*Im(z))}) ".Brob.arg" <- function(z){ atan2(as.numeric(Im(z)),as.numeric(Re(z))) } ".Glub.complex" <- function(z){ switch(.Generic, Arg = .Brob.arg(z), Conj = glub(Re(z),-Im(z)), stop(paste("Complex operator \"", .Generic, "\" not defined for Glub numbers")) ) } setMethod("Complex","glub", .Glub.complex) setGeneric("Re<-",function(z,value){standardGeneric("Re<-")}) setGeneric("Im<-",function(z,value){standardGeneric("Im<-")}) setMethod("Re<-","glub",function(z,value){ return(glub(real=value, imag=Im(z))) } ) setMethod("Im<-","glub",function(z,value){ z <- as.glub(z) return(glub(real=z@real, imag=value)) } ) setMethod("Im<-","brob",function(z,value){ return(glub(real=z, imag=value)) } ) "as.glub" <- function(x){ if(is.glub(x)){ return(x) } else if (is.brob(x)) { return(glub(real=as.brob(x),imag=as.brob(0))) } else { return(glub(real=as.brob(Re(x)),imag=as.brob(Im(x)))) } } setMethod("[", "glub", function(x, i, j, drop){ if(!missing(j)){warning("second argument (j) ignored")} glub(x@real[i], x@imag[i]) } ) setReplaceMethod("[",signature(x="glub"), function(x,i,j,value){ if(!missing(j)){warning("second argument (j) ignored")} value <- as.glub(value) x@real[i] <- Re(value) x@imag[i] <- Im(value) return(x) } ) setMethod(".cPair", c("glub", "glub"), function(x,y).Glub.cPair(x,y)) setMethod(".cPair", c("glub", "ANY"), function(x,y).Glub.cPair(x,as.glub(y))) setMethod(".cPair", c("ANY", "glub"), function(x,y).Glub.cPair(as.glub(x),y)) setMethod(".cPair", c("complex", "brob"), function(x,y).Glub.cPair(as.glub(x),y)) setMethod(".cPair", c("brob", "complex"), function(x,y).Glub.cPair(as.glub(x),y)) setMethod(".cPair", c("glub", "brob"), function(x,y).Glub.cPair(as.glub(x),y)) setMethod(".cPair", c("brob", "glub"), function(x,y).Glub.cPair(as.glub(x),y)) ".Glub.cPair" <- function(x,y){ x <- as.glub(x) y <- as.glub(y) return(glub(.Brob.cPair(Re(x),Re(y)), .Brob.cPair(Im(x),Im(y)))) } "print.glub" <- function(x,...){ real <- .Brob.print(Re(x),...) imag <- .Brob.print(Im(x),...) jj <- noquote(paste(real,imag,"i ",sep="")) print(jj) } setMethod("show", "glub", function(object){print.glub(object)}) setMethod("Math", "glub", function(x){ switch(.Generic, abs = Mod(x), log = { glub(log(Mod(x)),Arg(x)) }, log10 = { glub(log10(Mod(x)),Arg(x)/log(10)) }, log2 = { glub(log2 (Mod(x)),Arg(x)/log( 2)) }, exp = { exp(Re(x))*exp(1i*as.numeric(Im(x)))}, sqrt = { exp(log(x)/2)}, cosh = { (exp(x)+exp(-x))/2}, sinh = { (exp(x)-exp(-x))/2}, tanh = { (exp(x)-exp(-x))/(exp(x)+exp(-x))}, cos = { (exp(1i*x)+exp(-1i*x))/(2 )}, sin = { (exp(1i*x)-exp(-1i*x))/(2i)}, tan = { (exp(1i*x)-exp(-1i*x))/(exp(1i*x)+exp(-1i*x))}, acos = { -1i*log( x + 1i*sqrt( 1-x*x)) }, acosh = { log( x + sqrt(-1+x*x)) }, asin = { -1i*log(1i*x + sqrt( 1-x*x)) }, asinh = { log( x + sqrt( 1+x*x)) }, atan = { 0.5i*log((1i+x)/(1i-x)) }, atanh = { 0.5 *log((1 +x)/(1 -x)) }, trunc = callGeneric(as.complex(x)), lgamma =, cumsum =, gamma =, ceiling=, floor = as.glub(callGeneric(as.complex(x))), stop(paste(.Generic, "not allowed on Brobdingnagian numbers")) ) } ) ".Glub.negative" <- function(e1){ glub(-Re(e1),-Im(e1)) } ".Glub.add" <- function(e1,e2){ e1 <- as.glub(e1) e2 <- as.glub(e2) glub(Re(e1)+Re(e2),Im(e1)+Im(e2)) } ".Glub.mult" <- function(e1,e2){ e1 <- as.glub(e1) e2 <- as.glub(e2) glub(Re(e1)*Re(e2)-Im(e1)*Im(e2), Re(e1)*Im(e2)+Im(e1)*Re(e2)) } ".Glub.power" <- function(e1,e2){ exp(e2*log(e1)) } ".Glub.inverse" <- function(e1){ jj <- Re(e1)*Re(e1) + Im(e1)*Im(e1) glub(Re(e1)/jj, -Im(e1)/jj) } ".Glub.arith" <- function(e1,e2){ switch(.Generic, "+" = .Glub.add (e1, e2), "-" = .Glub.add (e1, .Glub.negative(e2)), "*" = .Glub.mult (e1, e2), "/" = .Glub.mult (e1, .Glub.inverse(e2)), "^" = .Glub.power(e1, e2), stop(paste("binary operator \"", .Generic, "\" not defined for Glub numbers")) ) } setMethod("Arith",signature(e1 = "glub", e2="missing"), function(e1,e2){ switch(.Generic, "+" = e1, "-" = .Glub.negative(e1), stop(paste("Unary operator", .Generic, "not allowed on Brobdingnagian numbers")) ) } ) setMethod("Arith",signature(e1 = "glub", e2="glub"), .Glub.arith) setMethod("Arith",signature(e1 = "glub", e2="ANY" ), .Glub.arith) setMethod("Arith",signature(e1 = "ANY" , e2="glub"), .Glub.arith) setMethod("Arith",signature(e1= "brob" , e2="complex"), .Glub.arith) setMethod("Arith",signature(e1= "complex", e2="brob" ), .Glub.arith) setMethod("Arith",signature(e1= "glub" , e2="complex"), .Glub.arith) setMethod("Arith",signature(e1= "complex", e2="glub" ), .Glub.arith) setMethod("Arith",signature(e1= "glub", e2="brob"), .Glub.arith) setMethod("Arith",signature(e1= "brob", e2="glub"), .Glub.arith) ".Glub.equal" <- function(e1,e2){ (Re(e1) == Re(e2)) & ( Im(e1) == Im(e2)) } ".Glub.compare" <- function(e1,e2){ e1 <- as.glub(e1) e2 <- as.glub(e2) switch(.Generic, "==" = .Glub.equal(e1,e2), "!=" = !.Glub.equal(e1,e2), stop(paste(.Generic, "not supported for Glub numbers")) ) } setMethod("Compare", signature(e1="glub",e2="glub"), .Glub.compare) setMethod("Compare", signature(e1="glub",e2="ANY" ), .Glub.compare) setMethod("Compare", signature(e1="ANY", e2="glub"), .Glub.compare) setMethod("Compare", signature(e1="brob", e2="glub"), .Glub.compare) setMethod("Compare", signature(e1="glub", e2="brob"), .Glub.compare) ".Glub.prod" <- function(z){ out <- as.glub(1) for(i in 1:length(z)){ out <- out * z[i] } return(out) } ".Glub.sum" <- function(x){ glub(sum(Re(x)),sum(Im(x))) } setMethod("Summary", "glub", function(x, ..., na.rm=FALSE){ switch(.Generic, prod = .Glub.prod(x), sum = .Glub.sum(x), stop(paste('\"', .Generic, '()\" not allowed on Glubbdubdribbian numbers',sep="")) ) } ) setMethod("plot",signature(x="glub",y="missing"),function(x, ...){plot.default(as.complex(x), ...)}) setMethod("plot",signature(x="glub",y="ANY" ),function(x, y, ...){plot.default(as.complex(x), as.complex(y), ...)}) setMethod("plot",signature(x="ANY" ,y="glub"),function(x, y, ...){plot.default(as.complex(x), as.complex(y), ...)}) Brobdingnag/R/extract.R0000644000176200001440000000431013762776702014503 0ustar liggesusers ## "x[]": setMethod("[", signature(x = "brobmat", i = "missing", j = "missing", drop = "ANY"), function(x, i, j, ..., drop){ return(x) } ) ## select rows, x[i,]: setMethod("[", signature(x = "brobmat", i = "index", j = "missing", drop = "ANY"), function(x,i,j, ..., drop) { if(missing(drop)){drop <- TRUE} xv <- getX(x)[i,,drop=drop] if(drop & (!is.matrix(xv))){ return(brob(xv,getP(x)[i,])) } else { return(newbrobmat(xv, getP(x)[i,,drop=FALSE])) } } ) ## select columns, x[,j]: setMethod("[", signature(x = "brobmat", i = "missing", j = "index", drop = "ANY"), function(x,i,j, ..., drop) { if(missing(drop)){drop <- TRUE} xv <- getX(x)[,j,drop=drop] if(drop & (!is.matrix(xv))){ return(brob(xv,getP(x)[,j])) } else { return(newbrobmat(xv, getP(x)[,j,drop=FALSE])) } } ) ## matrix indexing setMethod("[", signature(x = "brobmat", i = "matrix", j = "missing", drop = "ANY"), function(x,i,j, ..., drop) { xv <- getX(x)[i] return(brobmat(getX(x)[i], getP(x)[i])) } ) ## select both rows *and* columns setMethod("[", signature(x = "brobmat", i = "index", j = "index", drop = "ANY"), function(x,i,j, ..., drop) { if(missing(drop)){drop <- TRUE} xv <- getX(x)[i,j,drop=drop] if(drop & (!is.matrix(xv))){ return(brob(xv,getP(x)[i,j])) } else { return(newbrobmat(xv, getP(x)[i,j,drop=FALSE])) } } ) ## bail out if any of (i,j,drop) is "non-sense" setMethod("[", signature(x = "brobmat", i = "ANY", j = "ANY", drop = "ANY"), function(x,i,j, ..., drop){ stop("invalid or not-yet-implemented brobmat subsetting") } ) Brobdingnag/R/replace.R0000644000176200001440000000516613762776702014456 0ustar liggesusers## x[] <- value setReplaceMethod("[", signature(x = "brobmat", i = "missing", j = "missing", value = "ANY"), function (x, i, j, ..., value){ value <- as.brob(value) jj.x <- getX(x) jj.pos <- getP(x) jj.x[] <- getX(value) # matrix or vector jj.pos[] <- getP(value) return(newbrobmat(x=jj.x,positive=jj.pos)) } ) ## x[i,] <- value setReplaceMethod("[", signature(x = "brobmat", i = "index", j = "missing", value = "ANY"), function (x, i, j, ..., value){ value <- as.brob(value) jj.x <- getX(x) jj.pos <- getP(x) jj.x[i,] <- getX(value) # matrix or vector jj.pos[i,] <- getP(value) return(newbrobmat(x=jj.x,positive=jj.pos)) } ) ## x[,j] <- value setReplaceMethod("[", signature(x = "brobmat", i = "missing", j = "index", value = "ANY"), function (x, i, j, ..., value){ value <- as.brob(value) jj.x <- getX(x) jj.pos <- getP(x) jj.x[,j] <- getX(value) # matrix or vector jj.pos[,j] <- getP(value) return(newbrobmat(x=jj.x,positive=jj.pos)) } ) ## x[cbind(1:3,2:4)] <- value setReplaceMethod("[", signature(x = "brobmat", i = "matrix", j = "missing", value = "ANY"), function (x, i, j, ..., value){ value <- as.brob(value) jj.x <- getX(x) jj.pos <- getP(x) jj.x[i] <- getX(value) # matrix or vector jj.pos[i] <- getP(value) return(newbrobmat(x=jj.x,positive=jj.pos)) } ) ## x[i,j] <- value setReplaceMethod("[", signature(x = "brobmat", i = "index", j = "index", value = "ANY"), function (x, i, j, ..., value){ value <- as.brob(value) jj.x <- getX(x) jj.pos <- getP(x) jj.x[i,j] <- getX(value) # matrix or vector jj.pos[i,j] <- getP(value) return(newbrobmat(x=jj.x,positive=jj.pos)) } ) Brobdingnag/MD50000644000176200001440000000451614176704472013020 0ustar liggesusers83c2e2bca1eb5fee0711cc59fdd0b79a *DESCRIPTION bf2440f72d817d5a4c29b38897e0247e *NAMESPACE c0b6feb0a734c0fdcc01e2b4515edebd *R/aaa_allclasses.R 27b718c81756fc77fc7ea3bf8c7d1d77 *R/brob.R 145939bb79e6c45436aa97a24212c79b *R/extract.R 3cf5bc7d6ab3f9396d234ed897d3e297 *R/glub.R fd2fc6c9a7fe6d978655f84ab635521c *R/matrix.R 1bd953f4ebc0a611cab32113d3ddcb20 *R/replace.R fce5390eea91004c9afad9891e8c1353 *README.md 6efb3280a9041198eda3a79f7db267c6 *build/partial.rdb 6525f06078d61dbb1ec3648f64ae5b4e *build/vignette.rds 5f9c8a3521284acab0ed92e3cf7dfb20 *inst/CITATION 111296f080ca695566ab1d0ae0842e4a *inst/doc/Brobdingnag.R 8d8bf483cd54f083df9234301e0f5013 *inst/doc/Brobdingnag.Rnw 4a7a7befc77f21c7e85a4f66892db78f *inst/doc/Brobdingnag.pdf 8e2065ab4f0631bfe581cb3b9abe06ea *inst/doc/S4_brob.R 9e8657d9868b035a24e1ef3e0df217bc *inst/doc/S4_brob.Rnw f99eb853fc7077c9867e8371ad360137 *inst/doc/S4_brob.pdf 0d2def0996a161ecbc9a96ca9cd090d5 *man/Arith.Rd 85243eea5c0b8e74b1595f231bc62849 *man/Brobdingnag-package.Rd 302f297f098a7bbbddecc887df17de75 *man/Compare.Rd 7ca6539ccaee5c5094b0e6d20b09786c *man/Complex.Rd 1014d342689d92dc02fe55ea6b2a6a38 *man/Extract.Rd 89303f2a4b86ddccd5d2932fa1750816 *man/Logic.Rd 0d7d612faf4826b5b6c0945ba2ae305f *man/Math.Rd e787c21aeaeab370f76de321b1067fcf *man/Print.Rd 99e360c829510efe42b9715461235d35 *man/Summary.Rd 5009aaafb2e2906b3abb375582e48aa7 *man/as.numeric.Rd eff4e4d01ab9ddc1470197bf4a5bdb93 *man/brob-class.Rd 729c51856bf6ec30a84578109b732e3a *man/brob.Rd 39b6473e2d9fd1ce3af16b0600a5eda1 *man/brobmat-arith.Rd 9702abd1cea8402880a14da58bb6fd78 *man/brobmat-class.Rd 7ab6fa254d90051ab2ba88fc0189a9f2 *man/brobmat.Rd aace3e63f8fbafd066356d5d14c2db3a *man/cbrob.Rd 8c5cabb210b66b4bfa021b558ee2bfc8 *man/figures/brobdingnag.png 8a9c550cd6383e2fbe98c93122914f93 *man/getP.Rd 5a19831a55dc9eff9431fdd669ab500e *man/glub-class.Rd ad5494dd3a2c6a36b0c5a6d20f10aac4 *man/glub.Rd f13a73382f54d0518ee34f22d8606464 *man/index-class.Rd b5ea9051be1307aa715e50609dbc7e6f *man/infinite.Rd ea082304393290114fa77c7628715b1a *man/length.Rd 415843ee2c300b95e4b6462fd91684f8 *man/plot.Rd fc63023acdb227d91b55ad8fe4c31737 *man/swift-class.Rd 8d8bf483cd54f083df9234301e0f5013 *vignettes/Brobdingnag.Rnw 9e8657d9868b035a24e1ef3e0df217bc *vignettes/S4_brob.Rnw 5cf6c46a3f1dfc10d123edc61a930e23 *vignettes/brob.bib 428a8158d30bad682c9cea7eedab404e *vignettes/brobmat.Rmd Brobdingnag/inst/0000755000176200001440000000000014176571301013450 5ustar liggesusersBrobdingnag/inst/doc/0000755000176200001440000000000014176571300014214 5ustar liggesusersBrobdingnag/inst/doc/Brobdingnag.R0000644000176200001440000000341014176571274016563 0ustar liggesusers### R code from vignette source 'Brobdingnag.Rnw' ################################################### ### code chunk number 1: googol_definition ################################################### ################################################### ### code chunk number 2: Brobdingnag.Rnw:69-70 ################################################### require(Brobdingnag) ################################################### ### code chunk number 3: Brobdingnag.Rnw:71-72 ################################################### googol <- as.brob(10)^100 ################################################### ### code chunk number 4: define_f ################################################### stirling <- function(n){n^n*exp(-n)*sqrt(2*pi*n)} ################################################### ### code chunk number 5: f_of_a_googol ################################################### stirling(googol) ################################################### ### code chunk number 6: TwoToTheGoogolth ################################################### 2^(1/googol) ################################################### ### code chunk number 7: define_function_f ################################################### f <- function(x){as.numeric( (pi*x -3*x -(pi-3)*x)/x)} ################################################### ### code chunk number 8: try.f.with.one.seventh ################################################### f(1/7) f(as.brob(1/7)) ################################################### ### code chunk number 9: try.f.with.a.googol ################################################### f(1e100) f(as.brob(1e100)) ################################################### ### code chunk number 10: try_f_with_bignumbers ################################################### f(as.brob(10)^1000) Brobdingnag/inst/doc/S4_brob.pdf0000644000176200001440000043532314176571301016214 0ustar liggesusers%PDF-1.5 % 1 0 obj << /Type /ObjStm /Length 4415 /Filter /FlateDecode /N 79 /First 655 >> stream x\ms6~.;`9۱7HndH+QMrvD;jGEb}/d8I@TH H" '!~@4A"˜5a 88a0ēi $jh+ %5#0"'qeD&Fn>3DHZ k`. i \  69%:e-T@I4@E"_f m"EOT 0c?~fX ÜY#4 ƃnp CI7PDkNP* y=PD3@Y0B0( PexQ@Y2 #,A`D <|"hXeM,h | 0(+k+IB(+ `>p"X]@90:h QbR0?HeOf|B@|2":'i4=4m|{ =!q%y1n#'$} }$O$ɋW?p??` t&@$yі.}ɖy1dÀտ2%}:7Alke6[Oc=d|5]&99s49*쏳qʽZ5 OjUUlg2GgG$_ YN#1Vzt -9lחMqa2YņWzn맫]\$e(tᦂd'ٚ2sD L0Njd?3+ƒQ>w z=k{o>`E&ЌF42-p~}jpBe.l>?%};) Bf] s6xr쁧Y\,,WSGu?& j zH1=g5=oo51)f,3SCѻ̀ nC҄~s)M?#)fudz<Ґ]]U4X1ͿdtM_W/^f/gfw}Ц]?PG΂5p@oi2+ 7Fz5YĽd2=La]&QY1=zUC^}~=Cn馡A1(!wc8@si߲_Y_aO ⫊+hv9~sc~ű[p 㼴iXL*6/fSz2|0pPGy( n̑zEwmaZU@Y$vFhYq=ӆy^4@X8Æ̧g0|N@HU9FpqM 87\}z=pĖJXe/U{9vaTPT5W0nm-hݵQs{b \/+eG,9-BpwkB%a0sPnLYKgU/ .=1f)9FN]r-[!HH$ }PBwhQ~<ů ,BH-(IeVjuV`${Ԛ~($)͖_]qSaCECe8T6T*`".vY׸ܷZ{[ҌX_\^9\_aϧWoHY=y D{E#51V_uзws<ં+tù*3ۼ^w8w}8lD[]ʦYi(UL kFʛFk:CA9 |ځ7Y94U~{߅AsY{;cGW72 :R[."hO  aw:]p]v~老S.16Ƥ烯փIFDXGJ~Mꘘ0_p$/yS<Ҙ%Yy ΝqeEO, )"T'Ylp3n* NjLwee4^ìdtqlZb4f6<gO?JYm}Zl;{;,A; vT,^E!WǦlkSlBH*B1Wnac^)pW#ߋ$ǞZ^$gǝnv,EvT\Te`p\nosg$͟ؽZsS2[6]iIԳ[.qO7j7^4~\fΚabZ%5}cw !X7b XgTv 0V}fA[o=$cuWn/ɯɶ*7iK { +,n{paJ%l~j4Eo567:%h t|{ C-V&w AY16wMqw-or7j\N{o2f}:L+됫ζ1PQLE1y$O(5bBUGTDt-%bܐjhH+})qqr|Q ~b X󰃃ٍU><4RP06/*Hkѭsl.wiKE4t)Lb>Wmܖ~Xs"L\$K$FI^0^]}<o;kg?|wu|tUd16ҁ+Pai=_(aEe7:K?&#?o[yqU[{Yf3:YMd,E"3~E[ppJԴGEO(4'Tm_<^lǾܧ;8(qz#a8Z5AaV1PBR?әbQd660=@ii\{&xxW<a)0U^h{U"+0g"wI9= > {ac^7w^c$p4C"M̛\nI44 =0 hSX>'t,=|eL7hT(SsEvQdk| `m"mCNؖ]śQ<~ہ"M C܍vNAWl bؓ;PVOW>z^{>߁FDc|e%{rR%Er[`[ ƕgdl7J ,tt>qEb1??{=ZheE\g$@)}~ܸvͨ*w޻`4KOPEb Xaf2U|c.xk{~(~Ey,1^W>=M*9b58@ BЪ6S'ADa==h _F%Y{C?@/_> stream GPL Ghostscript 9.50 S4 methods, Brobdingnag, R 2022-02-03T10:08:16+13:00 2022-02-03T10:08:16+13:00 LaTeX with hyperref Brobdingnagian numbers in S4Robin K. S. Hankin endstream endobj 82 0 obj << /Type /ObjStm /Length 2301 /Filter /FlateDecode /N 78 /First 674 >> stream xZms_qbOɌdǮ[+v)L`$aB* @ aQ"3mF;˳.$KSZ4B1gLFҔbJs *Ä'YesrL 0\JX!T93$$sddJqKER5S9lWtB (Z1P*ISlЧ [hI811pX \K p zNC78AhI#hP$n|&߳E(+/ /~'s<"Htr>g,~!]-{UYS%=b֑Z/=eoOKE;~hԷOE<0<-K6 WYU"_⇆$:{ح]y6˪6T7Y9 P3>r#va4-)[xvUd!Ϳe>%JV-شiاb~cQ7ƍczƼ,fWb/,ٯfeDbǍp/oCM8EU%bK#y=%u07) 9LBXP2yEX/x uVlXL{˗0ïw_f٢*y9Ȱ`:@a{@ồ^: |ȌQ(zR=oB~]ܫRdT_xtZ0uTW,eôZ߱Qi . $?fGP06\4OaaRX' $&%҅<$]l]>tfgPE'yn}_!)SۻP؉>*JtqPҗ6jx\dYn"+w[I u_!h:o[N%nove4i˒]7;Ih PDB;GGBl0o?~Io>ƪo*~7P[~q~sv%O.38O3:Y~E]* ͓> stream xZKss-`j c3ɮlŸe|CxhkQ#V~BZ U6WX٪M- }o@_] K!0LeEUsB{̞\WR |(5E1myjz#Mv]w<}~*j]Q{]~T&A N(]J8/;z(-}[~_E޶|?-ƼG7 V1p\b 7kn#Y Lo姮O~ S^9U|ʸ*w^ˬe?E; G!$]oOj V]?Ϥ_V?@*[߬ 񺾛Gr j"[bUzj#0t%gZ8YHU{.rj/oY pHx@׶@@ rc>B{q`7۱=^@aLk"l❃CzD!ՀS yWb2 P;y\ FⱆCH5vQ 0no #ߦHr2224'O\f<%Q虚eote+jJ~TkI:I@1aLE 5Ftd2if2kN4I:qp|I}-{:i~H+RJ3W8wLTiv c۵Aktlg НB/)`ln.MQǙOa?)?WWZ3\nAf|םRc!c1OY4]8̋ѩ))}ԚdQpt:m#ҾcbkA13Ψ~*YJZ=Ƈ-VC*bC8A$?p02 2c}d/6tqbV/i$YQF罠gr K񨖯g-M`[*dy=Pe0)+q1'Bʵ}`' i\HUC`7T&ó5RUvUC;6:gh3J! ]}(dˆ`w7KIvBRa =nv =7u6 @ ^[| q9/f%J8x *#q,Vn sLq5h1t[8Wi8>ⷌOSZΠ%1ɇ(!1N۾,t(!|vWI. K l3S uxtpiMF.)nx+t~@&d>+.C^9 O5`1_,'_aZWܾq+e,HydO*i 5 Ҝ,'_,Q#kj {'Sd%rápfV9UZRϗF2 B%ҶO\Al߰amyR|K&7#%f*2y࠭ Kx.!,}XJZ\ɸ&@p\ ǟ;# jaX<M@‹(+gndt.; 9VXhg:0ع]_ոc[ISI}S;~ QZBV$~IXQ,%Bc\Xsftj|2%fB>G̾ 7ec/0YBc;oܾpFfzid0^5IZb@v}C:um&"3IQoP)%/ge&yZ8 cxRn&䚍g tz/P÷{`PI76E[8M pҼ͇Gd;iJڜIvSLBOY </4YmDlۈ YV񔸨pj'/AZZ,v8AC˲֐:6a6aŕco^z7$5&{uʘ7s#Op^>7OeTm M/65i;|*`8SPvxsR1ܝ8^s1}ȧ{zsږT&AÈxrS䐗6xo@ FJ4n.8n>p3 j7D a4'=j ѻQvw/*e0HlBe2sK[,,7َxYMSb8%h%wtA5 #A_aJbB2:w Qioݛ@bT·&A6Ma;#]VHendstream endobj 162 0 obj << /Filter /FlateDecode /Length 3796 >> stream xZo=z m'F uGIPwZl gwfH{]WGrHgfu5oO>}?'pj]ηg/=_=; CնR/ζ'L,~}j#'J gzYWמWe\-WR Ů0lU57E񆳋 ;8c>J LZnWi ++gL9 TNx3I)q.,l:Z,7ݔ+p:}2;ۊ j@[2?˕I W;JUa }ua < c=iȪ< z%]Wbk:,;]˕6TkĺY_Jc)\=`݋* SzU 0Q /T~ `7=짠)!Ɠm|SZs(XY4)ץX8pkٛ Ou}HfCvQ;h ,ʊ %rK#N >;c<--h?إc+dRb["4yd7%*iĀ OY;3Rkִ NQ}LJ=ay ƆAhSI/!<*\UT|-w g.vs笽]+KGٟ6y-\a] b8ĸxWe8r]&l6j47朔Es֨`h/(%Bā_SFq"#y=i].00N+ee -ا`fߒp|+:B aK$w0f$, R׆Il8*Mz.$y=:?gr`tr QpnF#H0hEas66l-FM,cOaHp4)&0.uXx;`ߡ:U0|$rGUV.I0Gnxq.@Gy:q&k7' Bc : x6r$fLI1zf>#T"`1HQТD"<NtjLwm o"v&v,Q "@w M"Ȇo0Mf`Sm)` |mK$G& Q0fwinW]\&a57SlX,/GC%l "0}$;9 _z!~rH{pRqLuksK l f ë B\ K1צ#tU':+3J!sr4^q^ɖu f&ʅpS jEt?.&D/qO܄~דcDfkM:F|j IAy_10RmMRqp@`ʺ:ȟC+B)Kre;m:Fl{8g@N, >ژ"ԐӿI-m(7ѩ6Ҭ'EivHIdy޻u%$_,q1ph oU ?Vj^U%!z rTh)$܁9DI."Qr* Ny`8%'Qb9i9-\қ9Yr% vmuo⦭R"~VP3R4c SǙ߼ qe-i";+prtΩ[TY?U)]"H2v:E} &!G,`su%zI tH|>t?&z $.B4@LT} )D?+7C ֠,Js*BGd# 'B>7SiK#.ǰQDc:8)xᵋ]\ ~K{Cwqm]eanrP&9> rUƁAuY>a.Ք=>;X672N *qpr&<]&/hcSs>uea/ϖ󮔟v~@mEcEZUX/=VyߴN 7wU"@mO巧Tlԩ8?=z}T|]O^n/v~uqٜK|]oɒ&TMQjg{s;XV{ej Q7tACtT7hJÃC|z8 wI`uA)n Wt*3z"Yu]H+q%Pm*Yϴ/<.Ssye p{ӆnGh6o#Y\+e"Є/(ߌNP{[ EK+*}WT}?Kc"8Si Ȃ+Xf/~X5 lqU~5<q&/OI:|U~ ],C(kJfbq/8UNΆ7ؗ;ܹsso -*Â&w>Qaŕi%26DԲ]_Z)}_Aendstream endobj 163 0 obj << /Filter /FlateDecode /Length 3447 >> stream xZݏܶߧ%/ _mM:MѸHڴA.@ye??3CRKjߊ"òng/oEYv\O`0REXʗBkV^nqΞ/VuUkl_WTU];HkhXV5W>{&{/ȩVN9jZaRW=ggr{v {x* qgfon -wً BLNWP`p}{}o=:>i:石z`5ZG&sתsGWαC?+6dWssf@ZD".tSoS63Z;Kgk|!Q.?2ݮ(-%y%=al:ӑ Y\sYiEPE4OV+Zq=gm'bmY/fj;0yG9_Yz56WMi QJWakXX0 LGV@x7mEmbѥ 0zHVK]a^]順I/(²sɍqW;l.5g]Dfoٶ7[B3v~$zDNÔ8kQ^A0UHRI= >∓jtoWP&*7FN%T]kW[]FlWPؓOtxH9 Homoo0TsЏ C ʒ}#h~ަ 9)r:/iTknVM?G<F~")=Jvf䞥L@x^ZGxsg_=)WRZ?CS{J$fF&mFqPF@tɃe!h9iL)L*7ƃ7LEl!QICv]1%ށYlM]QA} r h0x`Gеmn\`Vt~2C8㐋 s®?RXMu:B-{= h<2⋀0eERA0C"h2erEƠI;*n(FQTPvlodHV $-HC&`H(x7yX.bFLҪ>[K S5ΪrDx.$(Bz.3vRPe"C<A؅4G!˽ٍ< UѨxUe.aHGTcy"?m955=dp U c!, n[gޱX>ϔ7/*Dhsg|`s=R(,m0Qt0DEl@B^M'@4=KOCH} ǾԞwN[Ⲛۉ* UVt_l;l\FQhB&tI'+Yv3L )ݰCz(/2b?7i@$HtQY5Z7]ۜ@~C''p*z^v ҺnBMжmCm)bdV@̣qM,;@f{C.teZv$ hCF.- /:hWe] $Cw72Ci)1&Ϯ0tqT!p/2ɑfuVs& GJtжXʬhSo(*7-nB.JP)\m *^ESQ ivsWCVTZ^ \#F8"&l9\~{FR{)چ2bX`XŹo#4NO[aQn_LdurJS 5Z7']|bڏOg8߂}sĢKeR5ǣjdYz GS"KN.gpe=ĎRԻ,%M~Kle-įN% nS ➸#iC}f: gO2vd1fGN}=49- oTm f˒9ԚIi;*31f\NgP ,Ge-Sӟ43KZVnL5K+x+_LGl|ر~Tb ] ^ח&SB%yQzo^&?yyWSc-E{c|~QzE pi)foWg2a ASE[)Bx p߭d/. SX{JC f?}N"Al2Z/K.j6Xxglk%`&ac irFyum!A0cC![!bcAFgk1:~C\NV*tYY{WXC P/]S %r沮_ 0{msx b$ PQCIT~q|pd ]1\ys{?:jendstream endobj 164 0 obj << /Filter /FlateDecode /Length 2379 >> stream xYKo#77 j4ߤ/&`ўڲ錤36[Gg6I6Y,˲akAݢ\>,>,] Z [Z/tɤ(dK-ua\nk]E)̒Zs +/EY ᚖf^TcN~ta[6w "WkYsY:,% 4kY33~Ǖ_Gf妠:rՆFEIx ἥPiu882r11CW^nٍ$u7nRj!O=R0ai7:~.{]߻>i:ttݻr IsɏA:.@%.IڸC,l> @OŃ`Rۉ&j06C_F[NJ)pP-65>5.(ֺ,pB n,Zƞ9f2%%]\,QM~i: ΒV:giՄpFK<˳i*$'oC;3p䫤Np3m7..\fl:Wz$ox:YNuBZL% C|.E5G0c(UJ~p3r0WIRunLz;D$wP0W]Dqs=hef*Ētmwi!Lo-$Lㅑg3tμw|LLJM0~D:GU!E]AD^v /@@vg/7m-]թ.z$sPۤO]X,2ḚHxv X$K?sT9!?@2_ _gʀKBݐvCS.7]}ݬt;՚JդpCc{"[ݽ!yuE f@F$H:^qqmWW/L8i٠) OWUW޺yzG_-|9PԄ =Z1 K0$`dPyLM#8Q%VWCEz߇^dsqLg)LWrFd{"O zyQ^'fr{2ܷzؕ`zIˋWGA_h5-!9r),&6n&1n&5n&Lҽ#sx>Z>I'AПB^& 9~ o0#0f Iw4@A(n:UU~t#;ƺ>}P gsBc\]Brs]Sf3w{M)׃* C OKC3$C ʞQByҖ Ez5֜Z#pxY ցd͇tA'=ʾno$N);R0sv 9ߊ*α@d/1uPd]=dâ}˳g Ra6 gnQmCLEu'0r@d*^LVaPF%imv(m-ImCkEejT$rKq;bD짭Jij7 \0tDf@w}M U@&>wk)1zQQXB= ś _(L뾵f{l% ϡgDD^N՟uɐ7(=Iݬ巻=2tmaHMOIrhѹG3TzH1Q,ѕr]њt_wr5i bg9N&m;TB *8.Fg gaP5,YfG/j(}p*]=]N`Ф>`ČC @ f_ 0Txi9ƴRf% I Mc M @e'k@y߳}:d/R pEhÄpm$7^{OwG 1fU()^8 7? z4AE_&į69kendstream endobj 165 0 obj << /Filter /FlateDecode /Length 3331 >> stream xZs~VD?X{*ufg7EwjjUev}UvQ SRh c2(j+PJZ/Vq^ZӄԶ'cszht9Yn#mmZ>=SMkfeirZ)poHkD&8xRf̔  ܱS  ]?E%a&9\el.Kp EGq+q"Wea!8P9] RPx=q6P-"XpUHeU2 m,1~~EX/XӭwB9TC*ಎapeB ˝q4wkBl.~SJBب7a_lBR) =z9GcIYq2͊WB"ڔ&DYPQ3YJ&mC-5B Sfii[9g`Ąyx_B@/.qHϒPf/&Ze} ̆KpwetN #4yX؟Gm-fRBo|6a0<] l %N#q=nl.s׬s?>~$c?p1݃!Ⱦ}L5y6FL*#A5]IZPNp" x5P cf%V4Z *;&Jg 5$R 5] j@y@ 6\}O9L>3' # (678y\(d_ҿġvR@yhD@s!P- meO0k6>T(lMr'ud R )'n!! Yn!{Z}SvnEH9 g6RiW,)Mi7U!2L`%/3f|D*yUc&Iv;._&/NjL(JMUv6[9 Rt%gL-4q03{5#]hV˫otWm;XG,=UԮ^(yF v~q 4?\.}qk_IFm;0 m\HU"U+OhY1 瞫FC`7yH(kڷ4|F&K$fVߥM,="<=j&2"ԑZBy&V|sX1)9/_AI-@_h =2ХNT2NG! aհ} ]&é8$v>k7Pn7~= "4PG{OzئqJuuP̗dB,.iME%[:?t m lIsj>m?,aH+[\C!Dy+ 1z!^oEp$$W³)\y=#7$="<+Ѡxڶk?6A;qv8?z!9ֹB}> dZK?vCPpks64CT>"b t.pA8QhO3 Ҕc k<6]y[z 0!́qy$*(z0߇)k:zH^?Y/>;ܰkEƹ-s'̮vxl(rg,ɬӶ]=*.S`"Lە/6 VV|W(vz~Dcr @*@fH-B+j-U@┤57`nׅrp],Lei}C YOeUI1ka@(*ހai'JAgA>% 1݄yMq̱p&WAƚf}go4 evWjvIMq" @<><26mB&pl,EEB{NI(BD; U#h~ v)=og/? cƿajeRAj83_]386 C " EU=L9B ]^C9BVC]`z6C?*T{ĆtZHwHDtqPxTnWbu׵ všǞ=)y~>ѿkWՇ`*0`v6;;jSD!([aqJS:D~{l}x ԡŴiN+ǿ" -K*o/$endstream endobj 166 0 obj << /Filter /FlateDecode /Length 1358 >> stream xWm4l;/JqE!mI7Iu 3vN}S?433ό,?MfTL&DZof 0c/&vl% N85MX:8a!Q;S3  {^n/Fra$>dg4q l=A;{5Mep:8 !6G:.!qq9Gn}}Dh:m o]*NDMmG$>,danSIj1mnMJ MM}p gH}BWxsr.[X4y.pUh\reu(R-&%}bS:" j Y F4iCA\_k2*0$d+rp*G-> ''4tIHF_@& G s_p9,FTjduZNWauUhN8}tnN cI|3`GY7JŬMcWe+&|%,PJSpy~R2vI`M2t+RdWzLV==`5NI&աG N={K5[o?tXT41]F@>BN~x'bKU]hTuM΋GRug(.,|'L0h$?iY]ȋS)U P;C,ƥQJ5Wq2 d(7澹T4۬ZJUeOEP&nt\EDQ]1Zj[Bz|C|]Œ<CCaPn> p߬״+ 4?ԋ6W t;Պf~*t KȜ-X_Nݟv?#Rk_3Nڟ 5eә$q*(M8쏹yfH+#h̎>W" a6B'%$!h?7t%x F}Lt1Wb4C@Mٲ=k_R/]0葋pK-0-ދ2oZq E[ v)gܽ8zj4]2,ٶxI0$W4fa{zӷ to *c1S&I9K1<[4Y'xn3$PB  8&Ad 5Xʪnŷ5*<}Sԍf:|Z>&zendstream endobj 167 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 5731 >> stream xXXT׶>b80H<3ػMl! 6(,4 HY  U2 nb1Wobјups}zI޻y9{ב1vmL{vX_wO ^!]&wڈ@jt0;Cޛ`ww:8.e+C'  X^(̈́!~˃ACh>Ӌ~aWiVi\;yfs}|0̨B'M\;9o`N#JVM?t6+:Sv -"J8}9rμF'}鷅T/Q zJex#p:fpl+l1o(ߺZpHk`ح W}U% 7]QcB=sfd̆cWBJtbH-UA#m a !8v'+ ip0`8qnW0!a)e#p:H^&, yf!,:I쒃.4%-6G;܉n*g^l66¨ >fzX? r8%'|X_ˮ-2FQ 61=LOzFhgc}@vM1?Z:AĤmf50:qM&^{+ф%@#VMڒ,='mɰBa=&GK9\!lفsn- 4V6/jqmO'0&Ū{m]6u贸ԄHLQ#EҬ)tV,3,n_.y;^b%ɷl@jzF!UWԌϥݵq ձf_aq8^)'%n]HꨊE thhrK/#rwim5`h.+3DMc[QA[OI\{i!8Du'Zv.$m%%ؤ8\=ے\lnvѲ%Pf˙ئv=P]>WjsrZ"$> 6?_kQY V^Ql\sMfjC;>CA a>)VF}\:~͢;MUo̖Q@yd@eOm0gd=ʉVQfHi 蜖:5V[O%yҴS?Gqx}[^﨟wp.0;bUűA0VRIㅵ?M'oeH5+R&ih׸ ݥn|ζD,_d%(Y1u1NNN0%Ket*"hh4yz'l Mq- ItsJU!u~_>qn_znZyp(&Sue ) s dI#NJuRgR3d4ћ!۳x >xNΆ%8eP :H}/:Zi:8oګ"8Z_:*4RdZeԛ[Ui6Z0BDjh)J8d Mn3Kgmƪ6) C xCb; KE>] ,o{ 0d)hY' I>É|>[J:+ٯ}Lz)(2xd3no%~huo3$l2%G'O- 6)5PPLKj}ϒ #_tU&bH^?WS =qY9¢0a$h3bSL~l)ȓ(_ԇd+ ɉEt;w d!|\?gS4LUg}Vi<*͙/jʂёh0X3 և cEU8=qx Mڗ ~uhN/݇كPS*SoJ\!WM!9d@b W>4Q퀶;H%p/rvyY4PÙ˴U%/CWY'xjƛ:q6=>? b%"+'w$_\zsSQG >'h? /^x`%˞ԚŹ[Jxنcn{te,ഺp>[S!_7>-M@J%Kζl//|h=st\%QxqRO[UI}‚{ [MߓZ1ho#ȏo6&uZIl*MCʖԤTC.*t9'+rYrzXK0,ykRBud:c/jY[pͥ4-|q\nh76?'o{I!v *~|VHn!VO=]e; b[@K{}xGk 쳌LQC Fg*Ɖj3>eHܢ"~MIkȦ2Ժ.b?[SdR/iYכMtU3T+kz˲ϙwK!?\qY<%hޔ0{qͯ]kK(uܾ P-LhW6kvSq fy$Km^5c#`w^UG/Yw?>DA>BO 'jrw㤇lW8I4 e[dw#*ٽbŚ`kR/IBU|jQ"ūʟ0H А !G İyKH^665b8|S>` \s^(j89we(Rm2\x4B "Ej{!v,3۷ލ| Yގٺ\y9SErPvJ |bu ě@F5 nؑeNrrk4&BOiW@5a,Q LͺU!kv$xxvVwt8G(^Q^Xsw5+Vef F5޾K㶚L4q9?EׁBb=vI@ 4,\3_I{ xPRyv׉_QT\2iS*W} S! z jԄOQ=gLX&X8pS۷u?US8JmPmJI@o1Yb *w4W -w 4xܢ7.n|M|ȁ:hw)*KʽFv&~qSNOwtvpχq4n܊W~a'̧ 3_*D%Gig!oURK[:M(irP>o÷9V!5 \^ ۝7gWcW4V^N6X}]-x|P^\ \Ҡuk6.|rs!w0[ ]('n= |lCet{û{EK~O1K+kkFm޺U0c={%3%8KLV–#4SuԐQomװS7"֬ceW.o LdU lWt\_,-.' ^S@2$nB@Ydg{nT*19QڡnNC[ph_bNȾPv$gْj9t`=endstream endobj 168 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 7991 >> stream xyXT2 g$Ʈ(]H0kfDI,cl)샛?g@yΜ׻wPF@ 0]wq6!N8 7Ȉ,t׊xT?ͷ7BOF"Sns?mK  #{[N8qʸq,K-9xymtflț-GZ:z8yYYu`igbkնoߠ(j| |(hq𒐥œ;pYc*Wk6m=zyY?jAco'?qSN7}Ɛ>xΈ#Z5QʆFPk5ZGSc |j,Z@6Q fSjH-&QKj5ZNMVPө j5NͦzR>T/ʗMQ}Տ2R(1L$*2eN ,AK1ve).Aّ,RTJ xde@#l3^i|dIU1ny z^5ש{c֧}[>tm%%g̺-2/u7ed^c L"bgz Z;W ڳ{e%X2aȾ6CaaE7Q}xУznki> y=n7&dDB$(IإGi(;MEDOo Ҫdf@tS'klc 7ݨQ1eFc9\g"׫fZn^ [޻1ȳt ̇-~+hUl<\[Lo5j7uhT2`ev }tljԯϤBS/9q(Z 1rPĩ0-82nrkpd ck< OMǓ*4!F4N8s}t髫Lܗ+F$qr cx8ϭ Y[kɟܚMgiv_z Id3^ΰrq-mg@ =jqlŸ?R?żG%[Ixyf$BFղ í7۬; {!WC.ܻ:ka{J6TxUUuP!Ę釈ֲV'ËAݑW_HPL`zhZۗwZkף$AѦJ4R[)lD9@Q <#j`U 9^e8P4M=*H"Bzm!1"?bq->eoRd[5yu}3%Gq$u޵ݗ8FȈWCa\J[4xZzP퇁hX,1_+ ٢jœیRݧ~Č814.ꄢJB̒ T\)ᆔB·g_}vzmtʴYg(mUi% U129.>YZ Q$5]zUj_D3仑 np32OL $FȰ9ijuI рd~Ug_^$P qo LwwH+w-1-Û *'߈W݉«t<;a'4OA67T% Ld|952ɡ %D=ZfU$ѷtZm <.b a|W(R̄bV|x%^У]?Ft?YUЍl^䡴WZƻ6c(SD /I[ _AQ3P: Mur!=ګn}w exğey[Z[,ã90=B-;&nF=leWڜll6mL)M NMD,;pB.N |jRC8ħ$'?Rly `^ Ťa\>so"*pњ< Wff#3tKU^dlCt\޴/G?aȹZ((` 6 Cֱv+~?ѯO&^=A&qVI.[MEA@Jnk5PU$LYґ.9Wf(%SogMPcQiR.ybk *㉪G WLҴhm&=-g(7@ˣ }#->k (ۡGLn"7Hpa%m5 g4mݛ5o, ̬E[).MߪU7Ωmen>F,i+,a]RZF?>*.nɹ64+@(vZAh>%*3oz:@LvBz*=!2..!_ǤЈAFh).KϊXsmFMC$6 Lȑū B\"+ݻWT[ rU:M[lY9<&Irt{K7R5##EUct5lټfuJ(;Ui*Q)%ϟM+_|=B)ϋ$W1b%陔U;SߨVtVZI]چ4`2Xc-,Fw+t|_I7^(n%1Rj Xڇzz#v&⩴P gJ@S|dfƀ *g 8kB &wdHxm0^H'O4M;]#[G*'6ӕauaŢ.;+:AoZr #paT)Ib .9;%T^U"{iꐵ~fI+֧fꠐ /  ou?r -V]<.}p4,'Bn !Ɏ%DE ;~Y0EЌdz.dJ0a5UE;? 7S/|$:3/,A5(k{# P%F`sRÝ)I$x[+apvuӢne\FgFkj%Uw\)&93h;9Trur kx=3t!=3+ zy "9fR)J "Ẏ^rH$ &Sң|$Ж\1roz%+-.|؛mt=t`HtiJRRTHb "7؇8ZrWhQhҜ_]5Jo*mP 7XM:WR?@@UT (7iIjUTVe%20] _o S+] K$ŧ(RX 6&CpT'iSRw̄Fy~$,-E'JGUe6&Mtx)lwEO$!C2S3qwD-CcdϗbqйVb"<\a;Y|-ꍺzVC 5캚5#$RCPGUyQi_^X.k՘VLtLZ<9I̎쒌r/ĔU^Q ~.L꺂J<7fw0"X:zHnᢣnڧeϊ#c&{=27F,fu;B?ތm߮A?ԣ:t3@\@91rOT FsGqiSڒ-',Gw }> M/հ};xX.-{IN[Ewkd8"Yɒ+ri5P #d? $:K» ^~GD*&58!->-y.g)om]*st-:g{_y]5lgnȴ՟ףj.}v $* XzwF),v̧N>Zm5x*Ul"aS2HpƔ!3Ͽ/I>{mGulOdn\0wnuKFUv(̩[ sjZhS_rH@;ϐS*H/|qyrF 'XY' EJeV ۭ p~sD8|4b씲dC0C.ޢ/p^B =w$;85GSMxg>pJWͫ+_]i&ѵq$nDZ-4Io^?yh7#~y&7%l9@Xt,Cpo)L_W-2z[W/K'oiLB=wAs~m=޶;CĢ훅oE!<* .(AHQRli 4Tvș2]QTkiFx2@oMյ_<~opkwV9lӿ//` QP>Pߨ7-~d&Za@'[$$TdW(R;x*JMI'3Pe@j1TorPOXaqr{/>&庡-Rm6.AfqiRQGz2ȖW|zove'>pD0<#DH+[rk-2F}]FPBJIx `nŦ1)Ejrzϑ,{"!c:{^#@Q&J~=<( EW+adopfqCIXq=aaD2DECxi)䳨%P*{$~LWv^HcHU4EѼE&"q{.l .eS~xVŔ'?5;[ˢ^O# 'wW.L~-g+QP e|q,%i$̹uކ*!vN܆2ۄ#!;Iw<ӬB'%́a^ꤖ{?vNe~v n33s%D˗Gm2'9xg\)pM跟G~{<6|2u&$:E%&,%]KD^=w^#Ѥ;760hr["<R@d/h:͒/g]bOIuVwERPۉ"%]={ٲٳ//}k}x9JDmEs%pwŭaew\#ޝrj̇szk#[ LɐI)kd>+U DHP% g@Oti(+en L.F lRM+ 2| 6=)l: ʭnmd mn[Is9,#7Oժr,*+*vTzF{$nˤӮFƈ'$&ys[CH9s%;t55_|d+Vb; |9m_,Z71{*M[!G~3$.v۰9ѷhEbr{(]άsfKp.EeHH*fظz++眢 ܁bV݋G`-v /^b߬#\YHh.d )y%L;G-̺~ owacW~I=B}I^'+A:L>y{G> 1߃Q|Kr֋1öaˬ-Do[r[$! %D2s),#a+x_h#K#QȞ3TWꊭ8[vԦ|iiZ5MfO,JL_AL|Gp}o^tD]f@ *^gLv zcD]%v M5ߒ_wsbhD 4;p?dhn4AUMZū ( T1':M>eqIFW7?\gzI٫MlxQ3xV.^Ɗ^]'߉ELA+)p,&;audDD!`cOXYl *F?u OhqĄt%nۙ>F]\X&4`bf=%tCZO2C?[ѐWq oNN~xZݠgZ×QF=߳ge6]jS{߽}endstream endobj 169 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1003 >> stream x]}LSW!A&2C-s1:qRD t|#]pC"vRfȄ Y U8f"L[e|o9c7y9 EQg+Ek2 ,ʀឧ.-Dhce«+ PL`)j_ {Օ%E31MlT?jFfXl=TV+eXuљY¨L~A12LvVRfϊT?!T}f86#zEXBгHH2@mP~ %輀 oKR繧C(X1XeE3 O$O N9iv_xtIl;]y6U/~tXMy8-ȡ K㹘eY#qk|p0YZqxMO*`5Vjn&هxWS|?khH 1tl>Pp: Q?4ePUv1ʝ {RDA60l`BCSgI8xj(y|~~3- R$ĈAO&EVE;MOd+8a^oY^/{1 hxg|]ںގ#';~܃7RZ~IygpTuʡQU[OJq4ՐɏnzIqt_@ IuQ+5=Gs y{]P[ۨ KjO'0ֵwlks(`iE-?x`5)N@s9?I}r%{٫ڥ5%{&/zpWtzMYчxwT7%RjNڮJ{tb 2xNp V Fi S$tp$ QIxtm& 8}s}{U 5Xv?dלG@R BMۿendstream endobj 170 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4977 >> stream xY XSg>1jKӒ֞Zmuimm3nw}a r/ vNXDwkQ\Z괵UtNΟ>iv<n;p8Soؒp5{1zxV:ۼ5㦌3O׍9 ʉY&-TlOr{cڼi_?_ԇ-8>&M(nٝ9}]]w*AX4Tui RHA*ׇ> ]:Q#jsHFWho6@VHJP"]`5:H³/egD @RC~tQiJ]lmDWD]y.g*ŷ)A<5n2K[VZok'{X'?ڵI>:*l+MogV\FRQ7 "2^ƞi-yՎ sڏ7L5Fytͥu?>/|}ۅ_pKQ*[iE? >"tPTa*w#2QhJa2WK+*Dи[tO< C>3]'ћO2CyI`0 62 iۜGK\BK\ ddg?q~U4_} Cdm;w~X⶞;ty)bّQ7!GCvE&SpG}tT +LVPQ21ޚVhg3Movf27lsn} \根4 _͊ΠЇfKAm(JNHYGOভ{Ѭ),mF[e/uaS ][VEwQcwOO>g8ȳE7w\J|{0s{ ,] $;7{5}4K*m2)nWo"1 @(u>0YEd$e _ mh ɫĚ|&k ! PR+S(PY J* ' ,Phѡ{UNg.|cMزWa̽<Oy-agrlSQЋMP-K3"(&󭒆Jwi~_Q̋0O+~Wa0 ՁXRZ[g Kwwњ'UK5*zvHS3Qr)rVI_U]Ie0f/\Qo]AaF?<W+ $j4v*bHr*װτ:U@()Dfq)upY{Ss7'=݅&+%2H<栧?zɷIBDT$"TCe S[X 5jj"<952v[A.} O曾~3ϧ}Pu(%y!~y仛wfEl&[pk}ʹ5Õ`3M5Ti΃k~ln,yFݦ9J*e[C}Mu^}:ќRF,Qb%;[תR vŜ㣆1ܨG7XٛbQ1Ob9+TUzU\4t Db,ʿW6?w+k]=Cތ|/A~4.}z(;ߩVYDɶJ Lґ:z&,NV(5 84IjJrᅇھ-5R"qGOdhΤe(IJX:-(m9:RGU,N/sWv99z\3QNٛwoYeRQuiv\X[QrS}%iIv&\H9~Ӈqe.~둹97zxET86[RHP|dٖm VOvY&m 7F$s 2 i_iwpyZ%׻g.1љa7)9`oL.~LR_RTbܼ-D'=>pj)e2ov! 2ZS{ hg3pe͇iA6H%,Rr\.;}/C5G]Y6XW6 3-ȿ]?w(Ъ4E\3b$mvq;XH ]>֣yUomXt6TfQ^* ʭZ#]uc=͓c>Fdi5V DHʶ@=Xz#7k I[#0Pt1Y"!u &VPsZ$ JU 5g2hx }4qP;啕|ьxeڻ;&xpcCSe$*J(%tWpvl6"rPf : 1SpT!`~e (Z?Lg1CL{*%&ds:8v@.2Non=f,-#|~ޑ!:דxoTڕjV[24d.ի)Y'Ru4sݝcΙ5_,μpW~ܚK2y{c\VOƥ ?rȶkJ6Ę[ EpP -zML%Hi 炪 N0Mvfg B]tP 3Tf,}c37FKߗZ+6SjeZmeMjK 0ZUFT E#ao/@hHxD %{CFQc!rGlv=1%(h6`Q->_DC7y:M)p2Pg iC48t+wQqOv]^s#kw G>n`&dgfYF" PYC }]^1GFIygw`tmtab"7>[1_A]%P @XZդ+&MON ?y3cd>UFI*-tOj4Nir,JEy}}uàՀa/O+ZN}̺ =CScEF>d͍H) Dxu'\>a8%eؐK `2EMɚMx`Dz9%/?pY/,J bv$I W[5+[[K(SCȴе=y|rLlsvlz|qpcHfST:985 .6t 5-ѓȯs%DIVw+5t{4q(7YՓ֚.0<$1&Y²V!?7iULJ+q;bZ* 8ga*r2{&$ ^}jѲen v~B(*J)yȨ6uz;Zm y'ĘGT_~`Dx]%[Plɐ)lb4`()u:[a4lՂZ>:^XX972C:x's|xPmW@ǓBTCq bY Dz:-Eg7BjeȠDk5Vo4P#8s/.W! CXS[]knic A뭵55gYe):JU᥋!=|{dTڲF*Mـ>-&:":/dfՌ + 靇\mUvU:Q {(򏎕+ ;֞uE'@g,dض]Vg =A&(k74 јFkϘm?yF_\ J D?J!lِ'ؾ/HWuc(0\!³wxEջvFD$Swê!vt? zGM;ĪM!uM=a~x3JK8{nACf\} r)VɫQGy4 MpO(F)p,Jߞm~=Ch6z:C&YS.,.| ȏ3~MȘQjQUkB%AM2 MF?5)YiGr5jm"& ._]Qb8o֗婙Aף!endstream endobj 171 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1578 >> stream x]{Tecl5Ia~ '6ʊP& a^Rn"}sCgLqY ԣB4{sjyCcpM<<%m:!s.l.'AČ~\+D(%@1Y]T)t@rP# JHJҕMl?Zjd)uL*LEE, - jm~8!|o.ZH$Ą1Ӝ3D!qy첊\\y+}.T(=8]wP..\ϋ# NM +a޷s%zG~%8OVҰ "/WU'0}0U{x}o#|C ;n?gࠂ\6Ӯ*;lȜ$&Eg4|L>+H52 #8'2M5A&~'܋@T3-|adžOw@xBӫ}3<}~%ѴaZ݂cd_]SJ6@rBq /Y)aOUV`L +G2?DW.~r'\Bí/߰7Ix3`plѺƼ}Lk@R>K5 y-j]wv20 Ǻ=M W0Rdh!=Cp ⣙wG0S̑f:_eM(aP^\_KOx*t0 ۸ѩǂ|L{K:V{]$oHl:4U@Jd8rNi&M#cq[1&HB;v z*^ HxX85, &L&ӯe0/Gv[{%1eQ4y"ob^7i:1NCwsWcpZVZvŚ9]_.":]8<Fjݞi6)-5,fgeܞ%7endstream endobj 172 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 5913 >> stream xYXWמ +E3K4v%hT@QTd)K[ztދT ƮDM,jը1Qc1Ϙ?rgg==y tGQqÆА9yFyJQ:8?A j-GE:PdiFP;tWUb$~ _4o+sO`4<3dKRrbfhgE6-k-:mڲy-ZS&6t}ak$vk#EGI=clػgsKg3w<˷/XK]:eՊ5DM6SV[5rfP.Lj 5Jͦ\m-ZEͣܨՔ%zR u=rޡS)Gj zHSoRrʐCReLJDML(Sʌҡ̩IGV|PT FUc+}')ڝ~ &ldF3M玾?O?`AbcflqƝ8QscGoT儆 E"źXr&6/sa sv" 66n?ڵ_^uϩerD_:IԦbhjOIV4ެuKPXv񣞆^/_D$zf%z5Ir~\pDȑѰ\R"PH66* 1 aO\tU8?6/1ݨN bajHN3Qv$uW6`q;@^a"0?( M쨮NV-<(&|>7%[m} wH~Aҷjdt2anXGYo=pf4Ui's$e#c?pݸp̓2UŠ?%Ngj']6S؁ ϗt(#.+şf{X%.G]4 z"ѣZ{8vg`n=tjVUӪR (8OSu/4{]Rq| ^VF!~T_Y-jD] Ǧ1 U1 ipa!NiD^z;>Cg$J<s%%HJۃL)CY^@⡏דC.あ#/7ϭo`rB< ,_UpL JwCn+FU$sy&r${i6>'Css*rQ b:ZdqM𼧿4Z59 3Ap.v8 5IO@ZPGub2ԏ x&0Z($ qzC:ESƷ'QD0&  "Z!5s[+P6'(B(ҜyYp%#xCzhF0;-v݄5o8_|c҂rڔZKH3m~=;h_$, aشY yhOﳓ`ZZ zZl7>@㒳i\zBN,Yu3&RĹ~&4Wݜܱ&L^LF) rLةv,3iuu47%$=T[EP]$A28"%fHur2a5l2=7rbޅiEeieU__grh`^/xӦԄJ^C 6ݤ7 $f;vc7"NCKWtckׯ:`QD9|94v!ZE>Wju>4rd^X5 G~1Yi\-)Y#gZDl0g'f{ߧLO?hV+n^:"C-f[Tןtx{P{+wm1bӵDH?0Vƞ|ڹ̒uU(,OdEl`!#JHD07<"4uM~rnc.ͅO//]V8)`"b⃋&x/ME[rwq>UWkҼKvWTFYl*$%b۸I_l 0Ekczb>v0سabЩ(ţtXS*r9*ȫ(8}81o~9 fZܢ}iSX&밎u{‰>9s+"3fX?QSY5W=XS_  Y$cUBژ(,{t_GN2åfĆS篠)\b[Da_|S+?j>4VQg("=͑ n;+M&#!rs`> ف'6n3[b%!}Mߜ2-d~=5;;殻7/u+8!`*ԆZT|C}`1a{r :{% @, do۳(fR =|Fi:d1GOmuL=D__nQ *t\!07#IƗfa)Tńf`14?>953E6 P~pVD}P9@$Rl2jOY?dFqV}=X\\CWDƱƒ9)rwڽO}z@g:NĒ\Iڮ .ZUy-6RBrxEVҐ4!&>4ND~ݨ0EXFTf|G{"$]EŹy\qY1HWVw>Fq#>>\aN{-x~xP ~17ӌtN'%[yCir&ZmPYLel]Cqey߽+EhST2~DEqQXw!F30ήTg:`+@ft[734L>Vc {m|V {kRtv\NT6 e$5G GZ|pR1 PhEr8f_:# Jߩwpm</_ħ5,<H%!ۥ$ؿ.Bxnw|{=JYQ/Doʴ2<]`@=; b0U23BnlK۹󶷝RX_<6_U +J Ji€u 5 W* sks|up E{:endstream endobj 173 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1373 >> stream x]{LWmiC;Cs9S)8ʻPR<24 @OQq|Fc_/}^[%//NeTޮ@1)i5]z0 C+הk0;vkG.xb_4Bl/le4Q(?l`A&Ka}JzthOY,Ph+5dN Oq*[6TMA/ZmB^.eyk\@Q=. #ݹ'?эܬ,,hd0^^$=7ҧ45 QKcҰE[zbP9l"Wlv  bQ%ȋǸ3ߤ\o;>L|H}V]~pbpY<׵ȄH;e ڈu5-ɹ(9xsRhkyS3:Z>!6endstream endobj 174 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4889 >> stream xXXTg־+"(סDs [*K,HQl( M^)3sf""hbll4kƘlF6M6&s}{F b$e˽#fN MTY^*#@ {g}~؁l|:{\;J$kB=cŅ%N{&џ3]Ο4 (":9>"5 j'N/GG(C\C\}\}zy.Z=n/#|70SG{,OX$iir@Jච۷ UF[?bI;}8ìdF1hf3bƗǬf3k 3Yx0df=yyYLe3K̋2%f9a0`UƎg DŽ3%64ZYfS(%ɓJg%JӥTgm-)kc ܖy4hJ۩m |Z#C& yg+C>}|0n~ؗӎ>;"_ӌ82\vU⛎f8К9a hޟ\&Ң9]Lƨu RnTAWQ(מpfv +p)Ͽ[n@RVch42bG 5c,s=pc"-5>>'NY/W(Ա!իBR-p[_)P&uk2d#:uRH,۠)jU`by+[In0&qQ|ۮK Ө=\02;wG^,CqcrcN 8 pr685:?d"&3,9P5I{y CvVI&y{,9p/.=%/5(rઠVn(VrfnBVEOq>8[|*͓fhZ&G.C}Cl|& Yq\œ͊'ay3֭:)^t$Eg7k@ư;j:zv*av=`%88꾴'oы(p*Yd8G;z*!F,\#ipJGpJp\fhM4}qtCu,>"NVSODZ7\*e! ĉq`S] JsGh1A)`툉yn5r>ng;kNGt=Łw2. Зjgs2;_]ڮlG)Ee5 bjWv0*#ʌX'i=ǥ P)>|_hѼ؂p[%2E3.r(*Zq[H4\e0y|DE@㙻uKvS icb% `6nBz_XZ^PxXm$B;ތ˒t249_8D~&ڗ ] 7؂cd .f/XYF|pB.Rjeh{fl0sҞGsPcWz_  <y$Ǵ^#:e )i8枞xT<{ 壪SWeS d XN[njܮ?W@=MAƳ5'wdoñ泜nNd-nGs;[SfIM_`4Ջ`3}A M~ɘ-)eEС'PI8,)a" h=d5w@,dj5yQȰQ])"6fMvA#P !Fй0uah7ϝk/ۯ:D$ #%GQSnHW a A0v׆ z)kV Z_} N8Wo3גO v;n 8sB%ܛ\Z[! k"!SΞB nhlKYHsۨTP",B4XU4$q"TR!w1%KDSrsA!*!4!sWUK%JK~\w#kᜎ(u -E0jWjwjfrs^bJ-5Z'lÞx2pJ/MТ6L {avUԻYEsc媛su"h TZQAE}ӈF CYdC6}g Y=1}WQR=iA8jR{Yd  cZ?j5\,p"I3Jĩ%eiJ;@lqi/+3a@*SM‡{њ2 E .@W^u*uF,c+E&xi{c5? gs OB#wGd7n8C]{;N(;8ް_1%hfjҼKIrDu{;'H2R,ɾ7ra j!V_¬LuvV3MC)u1YjeIhv+sr'+UMp 0zTIld1 =rLKd%}& _v}^iIS)'D1͍(nb)qջwqؠY6TDk3c} nrGV=v|+3=*;Gy|~2rf2Y~ؗu (єPQVo3T7Zfz*5mMxC膇T{bD!W\a8D=p/Df;1@,ƺ ghe?3aɡt8Ji'~#ci(UhS"VPh4aWq_jPȆahW:R iT#`>0D1TUPY\nL58 ]z,5BF(\\ƩR+Jj0?UKipΤoݠ1U6 (}ɽ^$KU9UUue{^;Kt~bAv1 SzsZ#~*U3+y^4e#dn!2e i8K *D)˟!-g_C9[tCZݛPEwL7Ȇ~B TR#ɓ1,$R}58f=yLIp1RآЪ_mV[ؑPjShM5Qd&[7МZVׅ d$޻vE )L۸,dgV}]T+\2J`j>_Og^{{75uޖ(7,1~\,C~۰ 7|-pigΚ+dRE귍&Lۉl4mmx=`]@w^ٰnMFN{O7>GӷΞڳeᯡſon#)IS%q^1_@5(D0SSWe+YVd@FŒd QA.,)%'wg1t=v뒠m+A~l X:vz+>$}wbǬTFKFv#vh%3r–%dp MMg|Kl}]bvK|ZOEHaze?7 }Rc۷T7VV9c=\r J?6ϓLA|_nY`uߓIp=bZ㔞x)7EDM$7qZ`+Ac ߏ x\yy~qu40d-\ޟ6j%s{#-pU#,̧Q8Y0<(7UH5kg/ؙEJ^?dn__4@dhvqhHRLayY*AMa-Rp9E_\bzc@jIA =ꟿg{@vdɡ@m)"rق='[*ΘA$ b";El%_/ b֨( eܙz$ $Ac\?Vm*{bJ dfAMvPNOB[&qW,@e;aՑendstream endobj 175 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 584 >> stream xcd`ab`dd N+ JM/I,f!CǗ N2z5|<<,, ={3#cxZs~AeQfzF.THTpSJL//THKQS/ f*h)$f$))F(+k9e``` 6f`0f0a{!85|f>fXP yQ#qabdqw>[Y^/n=y֊^~~];`gyKxzȃ0=X;Uj%"Gl>qg(rIbnJE?S~ڽݾAFVU{ּ[ˏߙ^`|Pz3+N2z#뻧h.zCs*. >r?>sC侽>ie+:*8Yeoooi`|srwg{鞀I9 ={EtᏀ9C]v5KHH<g7}=}===N9?gb/cendstream endobj 176 0 obj << /Filter /FlateDecode /Length 2983 >> stream xZKs$|sp %,)ödAȮÒ񠁥ק{Ҋ,R:ht=mD+6/:8J6ZhqMcه0,e*'h: gaq`! wvs6pe5ӊ*auYgzDz өp&s[QkF jK NE_W;IGUYADisd[6a\ۦ/*jc|xU7l,nyy'30qxadm+K;#X/ ~FX1X9cNLrΐzIE InmYm`p"mOD[;rRx6Ylk{'(إ ϣ%)'~Y2a"`sn4R ,V90Zx5}ZYxۥq89Q夵PNsyxls1i+oԜf0Ml>5$9N+@":&%ʉN|1$±s\fl\ CQGHE%M fJ&1R\f^g@{,c(¨i҇lNSt<. >') R) oi_~>$}s\iH#8Ȼe^?95l`5Y-$~xpAzBj+S4Iϳ7ɳmN,xs%R :c=Hwl|\)Sr `gӣdh%1 Cv6+AP-4<;F*ڑG^y %p变c^^K' Zo'˱ Tǽ9::d ߗaX$m}iKMOrRi_–Aws˘$c T/kY %YܡrgI^㷰 ,,oqXu^=G|CCP4|`."XO+-uY Lf 4viX rQta3notQ^61EHOP&YVP$1<1sl1a5\{jfR!sї@o Fz&6wqe5ğxBt0p$aj/ Ⱥ4fPN[(DvFBN=|homWᴍHLH$Ϳ ?|z0>\Tⳍbu9RW +"'XXPLSnA}9u<̃)O'pS)/1\Jy֖إ<<ޕ6'%I.H193_D3Z]KX5z?INn2ȯ%3f}*./P\OQ9N<$a!vIj8cPخ/C?ꏂl"[3l3݋M&WCJ뛎^S8'ݐ,EC0~Arlp!4pH`E7XeaLluCVdNmC(/Aβ@OFJb C  C}DNβ_Σ緞ynRIث'6v" ^̲ Z'˨gڥtys|^K\_D=,桋}˻m(S8(AlrC]˂Qr |a (+]ZIYF%ۊpŌnAlmѱFR+ *pH ]s ,N70Q0 mȶsxiOnXlZI`Xc0Յ~iBmtբ̿zHr^jfzh`;-T²Mr51&/Cuwz1(E^v+ƾWk.4tEͲ.`Ep2&˛aeypE1w\n.XO_=>!РƑ(AݿƉVH8@L!l k 8hPe{2(M3{}0;2Y#I~h 路U}v*(u<"גP*_-/We1SAXK/7;!`K/[&Y>ֈA+rI \zn_sSޗqtd=j`Y5z)S#o|~>/lendstream endobj 177 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2839 >> stream xV PWEld`k|-BE !&"$Ą|9 7DQ)xҧjZ[glUQ77o8pW HHG$͞QP$G8nͶ{p쓝oq2{d] .'(ܐmʙvFp9{|2RbE;<̚5ugd窈;c=#=Wy\c='&xF wDc<c<7 x.\.h} O x='1%_YdP3kA#%Fb!fr'yjb-1 p& gҹ{7%cq~67jv}gYNYMom! L dKic £T*γr _!fX˾P+F|=⪍6AA7ӈV_* y| y@4W:W,< j&?N9.Eo]f9%^"[|Ǿĉ+UȔOJJTǹ}2JC :R#釾e^rdBS>05>uX&DӕI䛚QSKOղ,+n@q1;Ia9I! hq?[E.*"yPBX|hpV(GΚ; lGZ~n#!1s6(SdoMwmD1!p3rP! Cz`,;tO\PljE^'G|ЁNHɪĊ,+T@]с&Yuf3m?~8> N4$5 " W26 rfĤTk4./0' *L,`]!?'P$JR\<תvwߖ%@.4CdFΐ:S(#hUfbnX_tcL#$wJ1K/}$w^mj3_o@!V9l@ |N@A6%8A -X^>~{ϊ”Ye6t&rr9( {vvKXyW HD?Vt49L AYh&0Sq.kgk 9nu#t //ِŁ[klF!.SGB{\GH6XKCd+s3k,Z] 4o67AFg!1+űa$%[nYwԕ<,Ivn/Mff- 8c`5r~5ze4 O$ iGEB\u-f{z'$#sԩѥHs )'G  +@ Mf-y~vɍtǵ/g.tڊb8(Z{k@b$,肀}%ӟ+Ikz x/\hrVH׉BqA ;3s,WH Ҳj膦rae"@ mA 7ߍpel{hG^GĊڄA㰘gb],u}:46V (oŠhZ$Nb0X[<~(d!S{ə:hάЂLSg8ܧO \ 4JMSgCl{%NjQ z[ 9<3r&+ !L!fs64vM <)롈v;YNuWU!VzyK_hˈw9)g'{}:/W69 UGX9&R/~KI"Lhܑٕ+֧Ό WFa!JlDh ҫސzJok=RPhņ=6c`lI<6]v].ji7V`kHJ!˓3eP|}nb Zܙ#MJ쁡4jc\STR_ s*o^ ~|Nަ&]q6XqO) ^]PxfgKs4m""%֜CrL\W%ׅL4_] $ReUʨah@WdgRt..0*1TJzXpWʾ}w!cÕêS5Vژsyԗ;X_Br_0Z_ZZ4 v6eC,$Rrɍ5rvֆs quh-]`wWmuN\:{ǐ. %eۂu%<\ Hi=4pЙ>7cޅ|.%z_e*֘dc2Nz!ch_lX6ŶAWP|&hpsrrt?ŨP<;èe؝n/ $3ʤ3`~baE1WgC"`n;YS VbwϺ pj|r?)9c'=⼌叾>qzJs:QP~+941x{, C-uG<.uB-7_p)011\66W'`Ssr*SmaaXotykWE4?ط+=`IYn0ܺ}XQLCCnC[6UiXj-G &+6nd7n s .-ZNi u..5j^o4\&Ŀtendstream endobj 178 0 obj << /Filter /FlateDecode /Length 197 >> stream x]P [IE/=hC)z]L2̾u]T22 >gq({bJbvBN6_%`XَFS4#[ŦE `,4S hhĢ &IfWWw3 b4W+j=K4shUĄS] Idendstream endobj 179 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1192 >> stream xmkLSw]\l{tۇ[LD(h mi--}\`db|s0dfF}!akپ,هs>?((A kPm*+km޴6q4.Ge17,eO $wXj֘jFQ`٬SS 3Ln'eu&^"ez8$(U&-Y+Wd,"+vJV+0A[mV!do"A"Jd'qFґk)-/-6'bdN; 1\\i^;Z]qvGH0ds4=9_+C;Q;QU`-}Ѓ#!?%,T:yKiW9F#CD?#W#Y~NFgsO_v)PTk,5e86Y\@#G'Q>x&SW-)atxH9S'-@02@Y¦Qfr}1~C_[Kuo x M;q^IRU 10MլqԂߋGS-d#DkE˘/ ֑{yέŀ~l#h[V wzƭYGk͎ݐ}63}yn11p/ fF9=G?-@A8LDR8my@J8m?7QEBPN`}vRyxFqwq)lL. fʠgD?~gvw;myz4Lsq^8 1lF~a'/7|6RJsOc7.OveTzI:ے-Z^&一$Z~cE/!|ccYnFQ69=p@eۂT+< --b$ƭO{i L8X r>o`辀-HvSWUdVp3 tGOƦ#x2lKLS5PVhBag\ᡄhg>` aXppmd̊jrd<bG"hNOKV!;{endstream endobj 180 0 obj << /Filter /FlateDecode /Length 186 >> stream x]M (mb؍6M @P}]t> stream xu{HSqשL]$a#n$dzB2Ә-bөGSR{7++FA`z_A!hIȽ׉u  Pj 0LRVGz 9Bc2<{cR|7p--e)/A$Q[NĎ1l{cXS,}#ήAJuA0**}[:mxRk-V~h -إ7w،7_[g9qԦ7zL$Z`>A]ƞ2Ŀ aeZF'aBa)MF$eIیN{(H ;)gMj =R{)e@I]C Gh9b_Y9K;"6i]Gl+ 9Abz%t\!?VD:δU(/ ҇@&rI (ί4/_燝-!z1llNGΰpڼ2՛Pqx% Wj_YkYn_ (ufFe{`NCLHMÌ\LDA.g>>Ld2MNjD ʚ"~*X$Á(DtҾG,endstream endobj 182 0 obj << /Filter /FlateDecode /Length 177 >> stream x]OA  ~jpm@X  ª=0dup6Q^ Qc5*#L֑ڪ+d5@X @M Y ͤ%HQ Hǹ[5a4 ̤;_YeiG#%{zCq JZendstream endobj 183 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 867 >> stream xmolw7frwfK%%˒WKe"R[(W e\J(X\gµub/{-YY4&3{Ww /6^}~ $ðWTv`ݬni_ĽQ!J(m Tb-[-ȥ mnS/|R'_FR |̰i1ԡ70eQmJꈡ,n(UJ㭆c6@1TMi:UwR;4vT/ !BHf"ԁ>F:TU"MJI4BoIyc➇GRQ^ktp6hOޗrYgqsoV:{p{ *}UW} bZiIAfeolb='&SJپ6u{=2̝|w瀱o?8G~+_*>g=6#FAqᗈN>a5;N(Мwesff b/qv*ԬTmc_G HT*n5aݟ. j==>?/ gw>Eu1@+#h,˿p$RᨼLAendstream endobj 184 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 465 >> stream xcd`ab`ddM,p(I+34 JM/I,f!C[KOͬ N2z|=<<<, }E19(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C5pC"(195'5)3=Qe5|Udpo/g OM/sz{Uݩ}iwo ٻ3;9(ӓnzzr,).][_whnnpXФڦʞm-mW]w {6CUvXӳPq ?m-ýpv爛=}fn?y̜97^ˢ@endstream endobj 185 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 578 >> stream xcd`ab`ddM,M) JM/I,If!CW~VY~'Y=nn?v }^H1<9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C5;U43/-3/ɐa .GXt3~_*{NƟ%DvV[]R{l3v/Yph ~O$M=IrFԺ& =aZ[oKd]cc]S&3@R ݭuSgL;m4Aӧ5L-9c@+Y7xl/̿~g_E]KvWw>B9~fowFuO*us|;|~str(xT\Oyhoo?ܸi߬OnShl;vrq1pvp/0gbτi<> stream xY|G^c^E$8B 1`b6ދfIOV,{ŔЋ)D͑K$$@B0Ȇ̛}(''<=ׅ ycڔ~!;'op'nDe(ϓ! _1u0=3b4c:<6$. H6}ڴS߳v%-bn;9mux<6!?f.k jU7+jS#z'3e-RR )+c5Ru!ɐ:T&])ФB%P zcC<X46xPUP)j2GGM"Ҩ?T`]ӆ\:^dl" }(x9l dlF}nB: ވ/ |{t}ϮS$g '<=?zkBu\եyFx$qG?+sFW c艨MB1 бh:_=T$<݈ƕ(~ |4x@}Z58/łX)OhUߺv&@Ð7˨?F<"/|@N\6+ʵϮ٢lm 5C)! ~=!Bf UgsR;j2̈́j0T0t ռ rgRX"n0E˧gHnх)ov{TMՈΊjЛD,&m ;2c{]4r%hAn5h&6DR?Xt lU65g ;+`J@P')ba2hzg"U8ZOt`^pS"Ug {_+_]$܆w"_'6BQ鰨]_Jq dƩӗ$UҊ]hC/ՓIVbWc2ouBfl3[P/#06dZ݃ _n$99Fa7 GoP׮7@/S6lL,ck0%OO|i9TГD3MXALOhD_Ev_aAqA}mxzs'\5N)ʻy2qǰhg ꅝ=Sz# Ј]kVmwYz˱7}FoŊR\ &* +1za샆ֆ$ieOhP}!\ H~qR{q4G4r5%HDGDVU9P+i t8wNfB3ե݆m8 )DNw6okUW)??CŔ6ɐ^aŁB7޿p']${Uw pdLLu|vX,E*;keۼlm:.%@U:I@iCqd4#,ۙ$Kd8u.$ (~ޅɓ.-Aa{g4wA}h+4 B@s Hy;=X2LMѾ8'ydp-Q P"IGjxF%H0e':Dʤ=tHΚ'|XS.J涒a62#Xh$Y_@l+*"hhlq $Tl=]^G"45r.v_^@PXؙa}7{,猐dy˩#%gy9qE ;xXA}IacKYmQ$R}I}~꿬d|ˬG_8*#G m[n3Gڥ\/Br(LYdUu 7Zه -Myc+SCLׄe*vMIWB ̏мfh$p[<:SOV>%^9}$gkܣ[Jus@׻;$?WePy~I[ h)MOOw(5: 4DlPI,'ExyZǚ?ZՉyIePBs>RRٗ0 """W~}?I^vd hz.E p0|P*4-"μwz?NF.J',ћjLPe8hUyCs,(7*y&Rӂghͪ7Xe:/yOfRŠVVj-PEZ!aUrcab*rilE]J-j2++7 [6N ό*V.t9^Z=a"挎?e5<xwshaK p!WO!C7E86 DgN:K_--&PɗgW=p`۞2CkzlīY\R:DwlW&ybE!>Z:씕V沆Z|= 4e*(d-cVglfᥬ*LiQ"÷sYݗY&Icm}ִ__x`q]#莫˧v`n# Lh(9S0kRUPEjڬLZpr@x}TqQ͚P92('8`hǠ݄^m8da@<oGI;8b>&0Bk/߉RsF6 ]Cyمf}ذ/)/QMû e\I3IsceYB y}.iE 7 l gWίwSŰgWgQ- ,Vg!=}whfȗTkcmYc7]OUqcS8HJ(MK=ȫi=ZP 6t@"UXt:i,s΅ hZpy voU*|U q1\E,؃װG8380AWQh7k1 /7 > stream xW TSW~1 4DߣU[VmUqeSV,!Ȓ apþɾ) EiiV3k֖:oeΙpr8{PV(@𦗗2ZʼMa]oyg?m?]|.p+<|uy>1;~{#HTH-;\h˫ bW{ķ^INn'%뫊eq\xO4YfZj^Y< xjVxxM7 1_ fœrVv cRz8q5j`%5(;59\]1x2ixt߆LƱkįO1fCl+)ZJRX @#h!pVM^cMȍEف/. _Ě!5F('!K~),Z ؉c4k4L;<aa[O[x*r8:|2HS/f!\, g՘կqq>vr% -qyx6Pl-k?bkF~0x!O^;*9&vk"F06t(J1Q\BYoT ﳫʤh=Z5= N-Fꦴ'4:.WI{WH_Z|FڶK|qoANiҶ?M:21XM@뇤(#HBEE-lJWtFϓ]>ۯ'x kuvc!WԒHk"5h*F"o_9%tgB.{}w gGP $Fcdz"܏E\9;~oJZlV57 $YFx X .3Dh?}J_B8[aʣvTŁZҝ!1r I ݖ/1i]ub}/xUn#rstZ(JGP|DFUUgOkG^ ,z^QeR=Y0[a ?)Q%zS]U!ų˽fxK6$!6uI)l`U>]&E1ڊԖޣ ǚQ!1Í/I' (`زfwTYoa`ȟ6o/}VL w"|_Ȯ0RWq.ee3MAd2y%/Ԏ`}P7,wz %UfŃ8$53- i*4Yɾ> stream xZKs)&xAlʩTwrUhw>u&v 7 cRҲj[gNVqfԴFiBĭ'mt*ևFL6 6>W.J%Ctxgb`X 2`Um񣺉m7 i2FoMC׺<.XitS_Ηѵp-i-DIJ,h ;=bJ,:uoE>NªN Kf*eɎ~BȺn!)VmX h-^C }+R`$|_ -Ԣ5`LUW=JL7Ґ!I.x A 濗/t@,<ǸeC +5dPqAd <39֩d09*%0ˣe)x1dc0${BP)V.6?H<7saF9 hޚC@!CˎL2Yz䳮JՄĄ}qDQ RN$Ϻrn,@˗KC% 6UNE*+R[A/ _m RR`PsL'J+)x~=<S$m~ҕq}a:ՆЦkΟjfϠ3Yծ{icJS/iYy֚Bh eua|l|xHK0t!NBT P` iijS6Y;# XKdr&z${U êTf;N%aZ7sRzcoX9&9۸3ۀ`k? L7Q{>T6n(+KӅ~v " XQT1Mk--Q%f5}sv* o,ksxܣ0C_8xWF@Zob0n]*Xv+kCsItX$J<`DKG UJB2=Lrz: 7xވu̯|;YԏZLhòoM6LR}ۆ֟S;r*ivQ"͹ADe%U'~乗-u4VFd Iq̹.6!9pWuš"9Brű~'p,xa#ht(jMS\4dU B@.z.rB8ltΏ@M,؊t2!X J8bb.q|)> :`KJ ͣlkn*),\՞SLO:ia*T ^IzL\RǤ*i49ft+N鶍4dX&F%-b)K1DF̫? -}48.|9g@lI! 7J!/~ rKM!JyNhb*5 yEr {a0.HQ"IO4' j>]&Kŕ -oIÛ5ا?/ţN{}sON[>1e\A|ECQĴh:TewD61RJv 0}KB">!r(7/_ξxAXyA @e5Th(C?BT6!Bz8d, Y ҄䐋|7) '˳B0vΦzXO8=ƫ9~~f5 a86TQGO׶Z{"rzм% ?W*%US>ق(e1iOf[Җz]4cBs!󝯏n0p+(K0P1wX^ $ fuӆű a_z; i_wC%p nLP^WS:C x_Iendstream endobj 189 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1505 >> stream x}SkPgHVAVG0c+ ` ZBD AgA!B-_nk5V~興i/v]Dt3;;{s9C8:eBh/:qӹr鄳iŤ\8爰)ƧѪ$o/2M##b4\T.SȤkzP-ujHUxlT% (]iP/(`}`ٛGj .19\#s'"&B —XI"Zb"LL y GbY̹¡muSsJqvz*q'=+}ElI Ya^~[#Su0TE ^Fh4P%9t*G+vQ3zKJE+a,g5gڕS73~s 8N=/ޒP *~_ DC"sd&{fTI[%N&IY VV7]OAUy{u@nTd&;$,cը=L^+XXPچ!9FTRq^~[V;*y>ք(h3ԢKciiNe!CÐ 5-X_Zx܈h/4Jh`҂4(WGI\y!CgXmSGfK IL%)k*l;AuW6oO9/ mPoAÚ cJ"gJSw|46 7mxzvgl9f$E!_vK|`>vm/( HZP $PWrele0ҥo6H(G<'5'=-u\/JbS wn<7a}9;yUG"ļ;* xl2I<,nқt:^3雚L7Vl&WꤽEIX ۣ②:flVinq*a:1ɯ^b ^çN=t_BO!xc\]bl\> stream xYKss`tpWD0ÕWe][$ S T[3PvA 0/]^M?+73N_n Vo W:>?|.*UJMe '윽^.ʢ2±vXJ) ? |TEYZHK,J&M~}<jS=6Ut918/,Oɒ-eUXq9bY o^lvwM׮;U8Wf5wEkv9v lfkYły Sqܔq;xYA5#G­zKYMU9sk``&07f?|:[9J*˝, 敳 /ӉrY2!g-,PE)+F6!s`$~lvAFF٦xqT<k)5-/~)R0M !  D"~;8S\6|%AZAӑFtP :gW,[%[^E4 4b*ak0 NV`Jh`,t"%0 ^1&riHN:3 | 5:- 8ޒ(Z *Xb]nW#۽ƱKx}Gilj`ϟ|~8?=C/կ&YX,W] @])%ls Y\˓ /+OL%]7Ǭ Z;ݧXsE涋T7'JB@_p_Oa}O&&@3/<6o58F}{q V(-+CP<~v$ϊQ(eR3Tt}87W<,|]k؜bdWLxCޢ{4HO>1 _iNɘ,#(ݱoiPWW d |K( Vp7ƇWQd93dӔFN(W̹*҂hr%<]d:ș>3+S D<< z?)ABZ#x*l CDFYAI*%,(ylqYM0Ju HsӃ,&Qكt+jw(r/7txrvYC`R6o/3žk~+7멉Awuhsbd~iyܶxy6B[!*'J&{e! ή TC7ُoƝ ш_pc=R4>@.1m̶KB4Õ.:> @^C{sK[84 l=$.qP wUPb?R o{HЁP )~ gHY{b !n[G84ąP<ڨ%v%ߌc'p;dҨqr^'ȏ]pEs?F]G:NH5q`t+-p d+6¡އИ_ b @pacO(j ˳) h@SXA[oendstream endobj 191 0 obj << /Filter /FlateDecode /Length 2041 >> stream xXߏ۸~}0Rk/Q zEzEpZP ugKM68HYNS"9G}\d)]do7y#bdjF~3rxL..Tr9ސ"<\;O 9%YIhI?r_M*$<<s +Ҍ89%U -;gA縕}Io#"y"σ>5i6%k$lHAse_,R]plmju}'̾Rht;r >R QҴھ#ޤ ;\/W]><]ןe|UW~[%+#%<%f)˴S"ÈSr9>Q0X[Ē'Y2 m ** _"ov JTTRWΚ}j! , &b{1iYMȴqzojdBoHtQ"1 Lh2(.oV&[rsUtSN'Rx<6Sygcp fHs%V?|œSBp0#H9PYd֨&+_ׁK,:1x}Հg~UKPeqd_EػZ09PT9ܼC ?rVh~-ukF⸠xmߍjjcu|[*Th $p@`ȝ50xB\ 欣{c {ipj&BC@{>)+"RL4vmzlg?UNvI®RXi=ͨzD) +PNtF>Z_#GW H"Ff]ݪP&=P^l >U)ϡf 0{SсGJGcZM?e'>"Y2+vǪ{SsilO#D{ xTJѕs]+ld7ajj* {v+*-ߦh+mo9I/ ?0g?S|ySz<4STфꊩuڟ~0"J-ǽ endstream endobj 192 0 obj << /Filter /FlateDecode /Length 2544 >> stream xYIs7f""ʤxIR7HIBBTj${۾|3x+ȗ jGj3/ ]n-RdRdT:3\.7yܬ,ThfH}\9g EN<˩ ߔh:ziJb9Y! e[(2+YWOdcTufwM...q@dmnJy&a?],%yxvus&/~ǜ߄{x01d6׫ .R5>5^B lvũ6ǝ?Ȑ}ҫ .I) ᴍvˍ`NG-ج'Y!aIX/dӭqTS@Ejͨ utsb'cx‚f 0Db&` H5弱 ՃhsK13;d4fO9j9?N^$q= t]тcU2ߠ\aw 0U {4=K$i~9k6H2ïcϻ&C\}q+c}+ m0͌2f@8@Ì] jgdJn)A7aTP%Lh,NGdĭ֊ %6Z'd,Vl+5|$&ØL< O.iSd&vk.\Љ;@Z,S 1v#,S[\g,:і[$%2CԘ$<(πntBK&]A]smw | <qS$7# 2v\i*bpS̞8CXY1sh (LI@a]OĐl %%Inn2̼hFC+0o>AjMvSQ>h=ބ&1D_[+M4pL˛GlǫѽMF W>^@q>C+PD,)7 k/7~8ƁBѓi@Q-'uK"54K[ 2%k\sqB*hCyӒUOԴTr4N-P|*)SlP_Q}9P3o \8e9˘ZLjYR\b\`[KѺZ %#%l>kʊ0 6wl]U_Q:J^Um_I𻆴t X cp@[*|r5w _ߕрOZkk{26 OИ>!Xj#ܕ?ɝ~*?VH-n|/!W=VñZSIۯQ6+t@%޼;BX*}LPKffU9J# (endstream endobj 193 0 obj << /Filter /FlateDecode /Length 1412 >> stream xWo6~-Ob)"ERb EbCXavGGjmH"ei0!tw i?ߌn8 ( O#|EMEbd\i`A&X"lFSr 8gLjFib1.y$9KMѯ8Vl+-".&89`܍(M8_O^t5|I&%| N3ܷYuyYGXpłɏ6CrWbz^qh)KG'1c@P*Pb\e*affUi@|h6"97'}sx JN//=o`988Y8<8}uڹj Ƨؗ6.`~KeAwwSYTͨK]6e,D7Bȩ܊U a{I39I'6dvZHORUͤ  L * DG"#viNn2.S$qOK"5pt) eW4Ӿy[_`ŽP·*<==dY>&O=3 y^m_Z,Ag *#Le&_gLq(zu_5swqα30 ]@ zH(u VwuTë+v ɻ,On~iuR*y-9 }Rݴ qa9#>g0CaKv  J2 nY5M],ȣyƥ2oO|EЉB{8t p:=JI+P,T nWH WjF_m Pp0wpJRbi-N:ț-|1B$0M9)jcZOy%v<򷁄@Εa] "*:6,hF(Wl(xF9 h2=[XM `1 4걫Az؛=v^gPx{ؘb)Z1O9?ld'+1endstream endobj 194 0 obj << /Filter /FlateDecode /Length 1942 >> stream xXK7LiyG46A` `8 붳ΐѬDjIMVF~P98`bwU㫯ygt߂."_nԮ.ܡMfrCDž˂.ԙr9,e3l& ;D@`S->o~f(U(R,\ܐ]?lVkJf97%sX"˩2īWԫ5n(h ^Qx{M?FJ{,-k197Q4ow <ǻ@bɡ6yha )v;8P4#F*>A4. Z&2{2Вt;R +}JL'sN>5ׅr`1I`$Xh&d XL3)C{|w>%@d9O2)p"% Dʬ[.qewqƩ1P0CdVh4B?0(<)`FL Bmς^"B17h(j۴?Er &4*z{ ̦\Lٺ2 ;Ι/X+YKJW_+'`%O6fWpQN7Y"v٥a~wyt|fy !*?6I@iu vȧ[ iE[:z*zz d:(:ؐTٻhO:Srl/:=hiaJ$$0BGH&c!ؕܺ K5O!wnYbSC8`n0[JI!^i:\ %V`QnB ?٣J*йT캟.2WM͊9\•t߭  7pt"d ê`|V 9UNHCĻ~[?ܬbd(Q2ms~kGа$%݀@{7O1U8X/k#o`G9z(8fBS<q ioT jx I(q47!]*qNMN*hfIr?3'pUAH 3 7|{; Uy+ʦۚۚAx6?\zM\>vSnOgnwv֛|J>]9WVe|û]Ӌph9rfo 2/RK??OKwH>*X~| ̼H}9egDj_@ٞ>K X"qH?K#_ !ߋ@endstream endobj 195 0 obj << /Filter /FlateDecode /Length 1278 >> stream xWnF}Wzhp/\r4@V-ӑHbE7r)юݹ9{|r;y޺Dzr;j3?˭w>VB ͯ&Z{)8 v07 0H|5@uuDj(bHt>G.(%R >GT#IF dsr?)NyX\ 1ߏ lÔs B,azsyOh)1 Sqj@4~A%loA~ Y(R~͊@>k ;ۈqT՟P= {LjZ%(lqAfɣV{7CӖc]9u1ܲ<i@oN銋=(9_2pw^n[THcb\.t09ؓC;1'{XX>XO,D Cyì.^)EKվ\ʐ(dz,t0fX''~W ˼.N>vU'S(EGV+m$E$*dWo:keMot(tSMۛ4lPnSv]^|d<ˠ,(VU]^gmU[ -ө@W1$ze(r٪(ץPc^Bz2OUvw]\3ML 6R } M7`14JaDqۇt/6ѱ#&Čuy{]2&qpj$_a0@+/ NqLd')}2ꗻRP%pR ,tz,V]jܾ# hy ;Ks`|LmQu0zeq }t9"inshcucu -aRƉ&c/`"Lp}X;lqA?NC-EBT8.1T#tՃh[͛1g=d+#=Q$25M(`AmWMouj _?8endstream endobj 196 0 obj << /Filter /FlateDecode /Length 3309 >> stream xZKo$dsPtqOi7ߤ Eām XЫ͎wrO>`Hvv:h,U?_V%/_|dEunGhxSʱ˛ ?]Zvi)P7O0ظl0VÄŋys|XreuZTea+a>ԛm}X,88,`z%\qNܖӮ5+֋%j[4@i\A?&D?7q KJȟK,ɋ7U]xYOK-KgEq>ܵX5]B 1Q*ͷ7xQq+ Wmq1ҐEO;7އ nwU-}=lAnNW b)wkHJzK=xr+[{Jq׻]Wǰ,Ȳ 8rt:ԥDmI#]&E_] ܬQ}ϮNoWwRK%[eQ+!yZ/JM>p&4~k[T\u,p.o/pi\vEYB$>n^ Y \Ӂuybi1`0\6+i<` c>ƱȖFn hu5f6 FS̐ԁK6>W9,Oeu0qzJ!zpwq+!:g:s)n."7If](bU"o}*sD!LJSHzRHp2#Ocۆ/+"09ŁBA}mÄi4!9r4%%O1LgZDߔ$\P30(Q -SR{TPnCCT^2z ǡnwk$8k@!uէiQ(UJ9敭A\l^T*5L99t {9PM. <( 1c=+a' f3FSH\Aյldpo0xTΘ$405Y< "{JD8|bTد|][cq,k80[[ClH8<[7]'kʰiai$DH@̈́Q/[x>rdp\w>M#JH(B(]/}&ODoyAǰPTP?;KgOADI2Cy-S|{Sj!Qq-JfRjcDd)C uȰΑ|Baqx&(zuQ ;̢}/Ո${LS_R[hwʬfd-1V/Xb ;é^c -el펛Y`TayІC~?f`|4Bwr^&ʏJ+3}omi:R [=SmQN[*|`I`Hu:li#&؝稶á}R%4AALx=,ew΂\6ijg$,hi @Jb鵔o훮@*/AvO`OL D|fh$h[xEm dTE'h]Gk%ShH&cM ֱ۬C/(r!%D҆ zϜ=SLĸ("PyKf@S"NԌAMwMAż9䦒W\~TrV%ڟS"$zә 'Xa@e$x]Es;wk(RzJw%^"P ?C>?s;KXi;W*7&V5{ m{[~{^.ͫ`M`껺}uIS_ditam!Sm*Z? `W#]W˲LEʢWu~uQ%ɭBaYLM_K(z=}}޵GaiԹײ}D>M~_7'Nuendstream endobj 197 0 obj << /Filter /FlateDecode /Length 2063 >> stream xXmo-Od \@?){Irl IiIy33 ,ؼz7Bz7•W͹S|n)Pnv w(;p+Qei'DV:EQ2 TÇ:[Tzpm +-겺sտpt]Jn)Taep~^,,oggWо*I˝ÂNHOUMWT׋%wTˬN].]GxxN]O At%5' bť /=J̠_sh7^D'3 ]A m|FQNGTD0<[Lfwl!Y]KfH#c91T ɟ z$ DkOsP m oխn)7KMdM]m O4׎AFF܄C0ȡn#velax/.9.U\ǰĊ| "dL\[ZXl"?Û#|=OK I9~d\՞P&  gB*]P~x-)C.)K5Dusה8]wxJ!z0EAevۮlרB puճh[lh0 Wr(1y1->Bp5nSѓVm'?w<{gާBI)VMϘX2fny;xQDT/TDM)=andgj }p">:ۀW .=S3D`2eTx mӆ|[ 4kߤrg}܋:FEFTfĦ?5?4Q]2KQ'tDfgJCI6cUi9e/FeyNeD,zi7xg' SKrwhOFm_$0/Ki*uoPVTdJ0hI> !ւRd4T' ]ߣڎF.#v48`a^zBeuj4b8L2KުCf}Lj^iC8n^AGx B&[&nyU?]c_G /GpLi#|j9d 5Frڳ݊4 5Y5 HmĸvvDqr^a5ՖDm[4ä W~F l|8;~{B# ՗g'Eq- Ue F._z20W}.9) 2i\j%LJÆȔڎa\K}]/a@/ȃי\=[XL(sgBBܸU~lOpӚuNBd^q.}ta /h }5ľCN(1R c#z!>Nn{\Xj˷Iq#|ˮO!J;}cya΅j5ZoO\f^O2 ,endstream endobj 198 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 554 >> stream xcd`ab`dd N+64uIf!CΟ N2zu|<<,~t }=P1<%9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C5P000000020=°QLɲ ,x?v~bq_}B p> stream xU{PTeϲ9G眚B̸ D1T.#- wW \\|6@(,LTFsi̚tq|aio{x=T*ռu/wMKbS;gG rJfLf!5/%yaTܓZTC(:T̝YZڴմ\l+-^P..KHX+\'5-eEє/{9NL3[ac6[ ;mbl1+#5=C\>kCEQTҲrcnҧ *ʢRUjJGQTdrʪ:wY?ҿQ1b $,:9vAo8ꒀ485 ]G2 z$Zq0`WWO4xT}=dC P[0.FNg6潲G Mg4rE:\"b˔;l(pO֍\=W8E=[Z^{'>blo8=@s5 } `K: ZI  F_ٯW69**wn`^.cw#P"b`i>$̰"mpݑu?cf7~fH4f68 o -~_q{MZݷSG0֧9tgOOsBXYNxG='Xa`{IB!Aܵ@e%lkɷy.yl@ -.N :O~շ)O~iP 0Xez8 } ,AwoN<::phHY$i~/Rҍ+ ,oq@Ѱ2zShW_5 bYiH^km +0D-Ö́t9Eͻ*65vVmJ[⿊DaSAK9Iפ[jKm0ď FU.[j%z= (m>|wt>fLxDH}nINϺ9|⶜tXɒ QO|sx0D. +?Ǿ;'V/N3>&M[ Fhk "4΁c.t ZNvRR(oi*endstream endobj 200 0 obj << /BitsPerComponent 8 /ColorSpace /DeviceGray /DecodeParms << /Columns 149 /Predictor 15 >> /Filter /FlateDecode /Height 173 /Subtype /Image /Width 149 /Length 219 >> stream x!PA>nX܂­h1 $[FT2k{c|ZaչFfT羾_|p(UGգQzT=UGգQzT=UGգQzT=UGգQzT=UGգQzT=UGգQzT=UGգQzT=UGգQzT=UGգQzT=UGգQzT=UNF¯endstream endobj 201 0 obj << /BitsPerComponent 8 /ColorSpace /DeviceRGB /DecodeParms << /Colors 3 /Columns 149 /Predictor 15 >> /Filter /FlateDecode /Height 173 /SMask 200 0 R /Subtype /Image /Width 149 /Length 12958 >> stream x]w|۟˵B HT@(*RDESDKo* ("(@AHBB H/wɕ}ٹK|33BОA4ihAP?|kEp'T*eɻvjC:tPXXhGdzZD`w6kݦ8WvveR1g+8F[7òe˖/_nԵʸ.CxހS /:9rd-C毨Ņ2|"Ж<^8NNN-F;'0{8{F*ޒ j̘1?#/̶ve=V_^uݻwgI' 3f㏹H{5:L|%p?/Fha'xnpש2Bb4pEɴxuj*)Dζ+^H⋉'NMi۠87\%-鵒xhA:z8WubNqOʀ;xI@ EO&) u=Z8Z!Vu={ƍ-:g_$Bn4{WW*>OɾB_ܫW5E[sρuٻT"o$%:\6Rnm,ooo˄:>Z1 &xT*uaÆ si$ȢT5mpכֿL Mq\'N :ԔFk7a„BY-h0[yioj$ץZ,rhꫯr] ɶy63b .-[, geeVqЌ0ZiiirADSLٹs'0ۅ4uG\BgggS?~wus<i]yVBclhccSQQ ubmzh>zFane Zd :?Aksy.,f]/WN m=@}2ps]h<,5<e4[GWHp%w-ǯJ DV\?DmDp(Q5:Fj㾗dvFܳѶI͓f/j*+s_|ܫP 8OE1 AVͱlA$6 ]IAѬ.A7CjMwKQoZ Ѩ1džLX; U RT"Bd%Ab,Af(lq,Uh=3ɦ|'/%кQUIq2$DklmQ8X ا`_>f6tzЦMq+%є\oN(Umтȩ#~^GȱL ퟯ{!^/s1\@96R Y:2іG):eP ۗ7!W(yahY$E~lBoBart/^C z饇jj{QfP#$h$P4 YIhD7Rj]B~dF] tE XS^ 'p=3xOUXk޷{QomAѐK8,z=rcWp];A݌}NAo@]#C3BFک?ra"1"C~;GhU*ЇId|q\&zgq]悭^C%25w(Wqf('Q x5a5?#-?#N:oj%n EuBx>K/(b5RP碢XBkǛf,~x+9GhL. ? B 5u[Řbl# B%8-{w~ ~׃6Jutf3 "pmysWSq3a4q3[H:N^O~{:nfФU/$aϸFr%%.WS'Yu5IZ:/xȴ=V<5=^P,LA]$=71|4z~z49k~Okb%tҹhY@qSR3z aS:uq?:o$ݻ ㏛j[1Z=ȝ@;uu4t@ߔ8m/ ~R>ՂX6h*ޏz YtB쩻?Rcu4֌ө`~|{H:Yq1'uͣ6IѪ[vq9$L$ OFYsDE߼U V Qe1)ԇ?\cqY(TըLՉ&Zc;?w?w~^-dQCc%"6 v_.Ss!ß#Z oNEB4phm`M?Vvew%f5X 3w^Gׅ6~ <(rwPtRi4WՇ?Qi> ah3SzΜ*KH~̣*dia$/X?璓>~Y pm 0H:F*Bh@f.HZ2_~7@I황}^uV:,A̞ @܁iLKIm,%DhjS sꈛZ=#m@]КY]=hK ? ?AQt{DVJ."B HP \ x%C:ę3~X CL `5e\Fx4C-A:?0lۚfnL ArݡkX&m  v)TErp9ǍRxv:2yQ,2z}FT⃽_:G CI{ D4 Znj4svtrdVhS\o3p9k-X{XC]5uY` ~qVc;t6]aZڦof5*ݏHY<{vW$@/Q"4ջ!PeLf6`(R3'[ό@ǚ9"rݬCEIQm5 ۈ eAz`J@ h#!blJjYxdܡV"@]ԛnv@u d⮷ 7oT^< xcEvP_~wן wv0}H7htsG3_-fd7ĊmDS#uF)%Y.~7]st'E3{H7ʎSfx%)է|L>w`RxVwC>,;]E}5%9"7'@BT IzJK$d n}K#5+)iF"kz}!x+'^ך)[|z:=ts+w{}`r`]VZaCI2nF@, ơ"zř*[?g/I+x]ԗ͵e'^@We; re Z1oC,HMg֌~ǹnDҋU kTƕͲ6k.{XGl]v͜H̝I(fьhExhpq"RHPW\e٬@ଁYC@p)7-~Tʹ*q"O!nV2cIsPu %xEBcP(熛 @ [zitݨ;%Ҷk_;b䤺.LTk+۞4O`S5VJUH# #& PnM5*ru13l6;hXH ]Kok?LW5x4aYƾZVVN5!BJ6=:C牅{bkgֻc6?j[_!o3wzVlvMm7Q>굗u |Dɺ!%b_~L`<@_ha-P~au@='nB @2\I-׹iK+5UwZg;/GxtM{Mk\e]FB _&H*S9󡝉v3BTgUvHVi{q7%$PQ(=-嵤¯00md5]p$n jf<4S3?Ki0 h M@:^NTo\+ Lo+wyKK}aLo?+cK 7P fnc7A k4欗|y\ϱC>un=P BRߊ<[ױXqIڕ}j#1Br[1eP'kx_ kh;Ulau1H`3+”-X Я7&%:2{w{ԺgGL;3 Qq} /l.[z~ (#BC: [ mVz ioBtҎCNnKU.&eàZ殼'O:.Kk9{S#Gtcdx@dm퉘!T.]}ȟ-3[i!fɜC/w% ;Jډ;9-TU_ !CcH(ը˜dhvUVdG^Nw{V }'IHM`KC|[_KB=CJ7EIdOvَ}'zk7v96]v9avX%JW+Uq1/hG1EwopTgm, ׭ ZUrwa|b?e^6~%˭c6cS+^d油)ޟNiPISy]{07\۔SRim4wط Wùhيs^K,;QH3CPɬ\kbvY}ΒGբo'kJсKPVS)^Vl4 #E;k_KLynP&r*58?@]~ĎRSjqt=MX-xE]iw}1\oV3(vƟLQ̹7OG~WBwp6HԚj2y 7*p?l0to HB>yf]CInm-r&QWm?bl;q'ޠzPvd w]WOQ5j/̝-55 6+>(\>iO~}KFͻe}?{:}gb'i?|Yc?̂ J@(IN]k`i$BTs؁`Ic^Zh~S @:vb/7.e78| $'{R"Tqw?;~즗8\ ]9s"SxHMܚЭ>ͱۋ=m W):kVԱBn]%\;0+"p_Y0׷#H[:zirL_Y U(=\s勐=jba_ ߕ{_*7Y褀xY?+mDu{ՂV5̠>Nqz_~U@,4uu<2YRDЇo\hฺ?>s( !E?#pK H@i/{;y.33J?x}L$"i^Dn[y9 9;4Ӏ@N'ȝVׂR&/kíVT"j0Er T[h|`^Bڬn޹:,h.|pH/<'OX,䘟m 1~)rTJ+9cwVr^W;rNHȓvu}~FN*D_ZG3m? Q|7r=yHԷoۋ;C$!#-CLp@A79g79:J̓ :=jꓖvxsDTDZNz?Q_yBL  wF}.ru 1kp5/~fjFnv}?Ne3zRHԴ<{Z~^x CbI'"ͮH}5۴%8nI \MZsw,c{VT{$ .:|"k:(5j*2I[G|2qWr"EݐՀ ֘)buNҕ5K/jtT%bMԱAn=eMd톫.d?\ժsdK*Wgiբ|| )Uz1]pzM!wlhF x{NuRG&7#˥,=poH`w&IZO*ɑ/Cs%މ],(kJׂ, SONז룄By$@J^ỹxwXhO0\'=$h@u\* ro`^[$ÿ,W*UJ5u,H\~xf2Sꮍ+|S,i +2H MB#O+ilkCث\+w/": /9N`rIsK Rl+@"_ohv~1s@kk6}.v#++g@Ŗ+F G.3EUeW{ ](;4K3ǂ4WC$mANM RS m'T-<-v[QGK2!x.?C<9͠Uagq"h'\uWQ3T/&w>@v>p:N _uϏH+Rv.o?98Yd/ h!FTR| M䔠/ EAU ^nng vejY?Z%,^\gw'=$tҤ$ϓ'}:OSkQmG߱sWB]"I+.C %P`ö́׷׆N 2zJu}E*,+yG3eAoA > B7,|(clzBr`D2"tF>o<+؂z -8r!o*NAM cZCD1i y\ڮ, \16Qҍ{ņ)44Cwp?'!V4+$Q0JP#)tJp‡dT(Y}Ipk=$hd3m"_W{V0KB:1g˘YaK((s_Yc6̞& -',KYeЋSH/tC:mwYݣGG+(|uغu ,`lkkI5 $u"F8k{a"[)O@鯹 ?r@i]i??DWYiAz.F0RL[Bjح7 g1A\ C}Mݵ{"Źzj3,ڋQLguW <ж1P O"rZw}evb;#Y'+Z_yn_@Y=$s;ϋаȌ<<МX͜HK*w4Hw |%Vhp W+ۮx/7|CqˬJ k [++BBޞ-6|VY0:%񴍨BU4',R}>&g5^gU <O?m]uQ<>)2-_n%8AܥE\Pjb%Bݜi@!oCJwJQƩڛ kI HmE ]tm+!o\)'v LRM]W kK~}@;wu3<#NBE{gr₪+n!x?pĐ494{K Ukhؚx>z/7^H-Yם!텡7n1ɟo=Ǐ-{4ۯt*W%TjR =mtŏzFo"a'+Q3w8WlY7>g_6 xQFF ry|*[ Gܛٻ 4&wsxA[YQ¯`|y5m7xuV$ ,oy?4vK lٻar8]&DK/ʠ#i 8ԕ)7%>B*|lDG! 6"Ù;`=ԇzG60N5 V Xju)ÔV뿘kiL>-7'F*[fN珌7 N>s&UT۟޽{_y^BŅh] A!4V%o; ݹ8W9$B+7ICc炍1`HӧO߾};K=ΐ,H8o:'؀OF}H']0 -'Ani\(|o)X_>ùd\4?R)t]WZjwKR: NfϪ"ޠ_B@ 5$X.l>-))qpp0q]h<G}ILuf1Dͧ~ UFNς)Qq\e!&>;9|J@T:[72U| +/_ξ ڠQ3ng5.ջm 1&.G4Q*%bd܃ͪd2ODG;͠tމĖ YQB )s| bvJܝB zR&Jb/JZ.jX2R 0e %=={f(F0?U@Sy:I(lhP]:uF#u_UpPx]`xmut ^L;"S~ʺDsO7-sη~F>wJo<;yS_D~؇s? .ud ",ͦ{Inlt v8hռ%!cjHċ,"Mdh-nڈ qi$}5#Ȯ]@S;D0v7}Tg~kX^?Y0\b2Ds[B J47m4Q=)Q"|mwxA,[Y#1fYFvz5 eJWY3gsWv l5'<|r:}dW&{e:hf͚GV>Uˣq+i596pcdC;opκ1Guܫ-rKWykM%b7zҧVCLacc59<X\\lm?Q))#%By%5-?\H\s 0VD@ pe3Z(. ֓7n=m?E.}972p18؏;O;vh \\\W 4(O#$TTT2[?LPɬ\}fW:Mre˖-]hܺuLJaݏ4(E]}b :}tbh!ӧOlހȫ=/sc0w$ʯl$Z?> stream xZop}D5nz(=A{PQhYVxMd⨇rwII%rwv7z*r*^gNVX/]voW?lq'.4Ymo.VRdU2L)_`qŰ+ jKz]`%)tV_XWw cwewk^0ܮ "uK\*k;GAK<~E O pH"lȕV?7 8f9 Qխ{X ~V,yn}<ֿctk<H:RuDvkC!v~by~}wKpgnH "ܟ)00עoʹpzf/]廓8d:<?L(rwÛu,2C9'Y=+|C̎Ƶ4(̺C/n>zy:G$.\kHr+aUh8^wx?. [ |;@ZzdRDқbPkU&uNd.u Acv=( 2!%P}`[GX3 IvH4yG GP:υ5H P*dB ,fd۠iVƺvAw,k Yxާgd.%q(Sفe}#,V+`2Y@>) =f= pi(4b0c?B^ƜPzvQ`0{ _뱻8.Y0zWiv\sPj-FPoI" ,}y4}p(g]TmTORCey.}䓢u^O֟\Y-|rp׊>0nNaI)Ld>2υk [BFz0L*!n3. (qܬtI I2Ǻ TF3'6˞wcP f;JiqD48EKIOEmCӾxAϥI5QЦ!~4KJ@LiP"Im0< XFހUd  irfinbFMbB?;_NͣOA;2_DzA ۛ#UX MDEJ_XUZ}b'6iz(HQ%`::|M&2,z9]F"uU{4AXZ\Nb/c2e>I),Ϫ2=c6Xqmc6"[x^ql·~fx$lr5" *'cytdx鰪mJkOgp:^ ī.^y+6yd3O,dZU@$Om(ĥRȰ֣{)1;7v_+@'mÐiɌa ۮ6ǜ،ƥ|205}WΏB[!e,h؆[K5gĉz[MP/E٢&,'o@&Xfmz5Tmzz7X"w#)rZ\,S@D0&tJk-8VA'|oqfb (ĎsKƬ42x;S3 Dbsfeș|e~ft?`7x_8G~6`ewU{4[_1Yjl-` TdrnJ{Z;|yx2|"K3٘D4&ZW ^ qр]kXCTIdϰ\kaeWSÎ\8Kw)\1rPeX9Ls>11Яw' xW4܏Y(g>ap&5d%^­ L S0H::HEF.-E/VkQ8Dm5v&&ϸelCG1q Sd&feΨb\@M"Ǝ9o^E*{u5Lγb&+bo΋3Y P-?L/ĩɇqYo!)vF)υs(tO> stream xXݏ6S}pJe-UDR n^w-=9@^]l]/7$E䊃,r3q3|o/^xx2ju>|mV&Ww3-焦d)W[qSr $!QD18CoԖ8Gu8Ev~[}/-e(K3eUN`9{ emoMb(QGV!% HB kY8$iN@ꅧV•MT5"@) +ϤV@Pyh8T1Ao]8L*L.?љܱ<N HQȀowF7 FЈϔڄ&ڄc& 6L sG8Vۺs^51gL|0鴑H:5wg! -H1QhjZ|&EL ةȄnyeG7AKgGlՙ UC׬o^֍s`ޜL=Ls6n# +l]Ev"d|L*ɸȗͳxln:74o]kT{:ULS߭~=wuTR+gS#u!0`״]e4c ]Ϻ{ :pzװƭڋZ8-rOa 'oh魱^ uwQǎJnjWA!/ ӡ H`ZCn 7_:^xQ ,<Pu֤ի:Wjת|IRYn7g<ցV~IǶ$9@Pdbt~|1e2^Õ,l*apAh|.r 'rE,˗j- G9u`N GpXW|t#$Сx|njSaU^q?(̈`8Zf0L]ѷLi {%|ȹ#H8eIg4<\+ڱ"^BQ۽Q5d2mxfͼJnMD.QS̐Z!@f|,y~wa(M׏?T}{}Yr眄ę߻_,e0@N7,]8ו.u[HZ0}ߢ_LFk}S5Y,Qe!1Z,+c^z$Do7TBE7'%)_cu i+U"$}.hB-ۍ)py(E4bW6guqWV;>*86o| M؞(D<Ў?gE{pt<TP!~t3)0L/J8=I"K1VoHD]`DQ : x< 磱ꡕ)QJ/D#z5 >iendstream endobj 204 0 obj << /Filter /FlateDecode /Length 682 >> stream xVKo@WX0f񾼻EAD[M`ԎK]NU mB>xwߌ?kv}4a`Qoo\ֹj\V6uiRլGw\iT\=n&EMQ4(K4wJ?xTjiKɞYm-YfE>YT`?d:cʽ W)L^?f]տ>Fk6?j5?']>B@ܬYdiH,^5QFF)y714/`\@e+;ъ[&JU["8FyzJ4b $DTWDqFU t,:+ uhfn7_d^.W(RߞݗɁ5[',2' KaM[/y-¢v ˫endstream endobj 205 0 obj << /Filter /FlateDecode /Length 1522 >> stream xXmo6a26K% tnPj+VKv%9qQffXû^8X迋f~OW,?fr.$D3 (icyX. LDh68h4AG1fixQB 9QkU38 $x7<BB(gL9S @e@"(%<_O?J%uհ ԔݕwB7_&|KP+$)JKhhVPUGW[iW~ͫiҫVƟAZvR'`<.зNm C; y 47:&;!z!CnycC  segB'`tv'Bl)tΐCrՎe_pFZM5Ey&Qf)'4T >HL,kYʃC\ XFX6zuJ2K/\ Wu+ n Zwr=ba@cz!cHr 93b֗4I1aF!u9RrTWHJ=eB]ze6KK2ԅLZ5ͧnw^$b2V*d1[ R`t<AeT7#DR|ѹj}[c$Jh5֎A[)Y%y>zRT˶$՟)61 ;`;љ{ gr2u땙źjeNlL}8!1|q˗n4"!N9$)NONc)\N;T6^|>^$gK. 34;_Ȫn뗡tj/_˂R?))>$Fᬆ}5Q @W7)OW3\Ʒse]g73f--o4Zria+e[V]/1cA8TYe>v;f ;٥Q(ڈsqw o_ɃVv`\y-<|y(zH:JZ#"ղ \΃[؈we?Tntmbd`[WK˰6Mĝ˺]7﫮_GxqrvF7p[B//SH,.q",؇?<\X /])Ir -擿?iendstream endobj 206 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1474 >> stream xm}PTeeU5\WnahME(Ŋ˲,"brHE@Dt]ʂ_F˔iԜfѰrsײ559ywT$0Ts2[W٣'F&[myN 2WA^eb1 CʂVAmԮ͓/Ai R$z[$Q P磾é#N$]M:a+pSs7[:Nx3=|z7$g8ƈ m=g F42t~6Nzp<. ^h3X`!|eeNTWj9<2}oL؇3Q;x0R{ifY`mu.C'Hpƻpa8 ܚH3x :=$I Ng'.IJқr0.[0{۽-݂xF SBA$ݓo=sT6lG:\mЋ [>IW?XgtCIګ__&bJL^0gM>LXy1p*;3{ޜgN?\?؈kGpKg) F6Qˮ=<4V+LUP-cx"C[Wtwr BKl,[Fi0-ZXt_84M@P0z0Gy*CE\pNuG1A9Ue cis'OdOJݎK0 ^Vb-d)d6i8"(@ X4/UH~dnY|,C&!otWr1@綹飲wC\R3u {{ %~r' @l'ăUT"˯m%[*pQ48)Mv!R%\pM ]//;a}EÁj̚5pXVS7z(]՝;˶lRM~cشG&K`ެYp]9 q04Y2&zD1h2O7(hmc%~ҋTDåD9.X^l*'WrNQۥlVN4Ç:@;b۶ZikEO֝?'4endstream endobj 207 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 893 >> stream x]_LSw:UBax*03f)nvEt?RGVЬ5\$aukJPԬlpαe1ی˹䆸k^vI7''OEDBQԆݕzKKVu~aos5<&9BjW+X*lTRQbtl݀uX),qj76d|bUQlg,-6FT1{^3ydqgCCc35UF~ !/vj|BԒThDDS rE Nɞ D{׍ [jf , 1GPjCn-Shhnjx {Ϸ|ʿ-)tԀ ~u Eh;7$gTEbV/ln&>t<6` bo LBXxvځ{ \֑#O"xto[xa/w+;cH2և c= 6CaA3:qvj**@Y #h*Rn[4?e G;$?+SBv5}\yq8 ?+:H>[Պѷ1)m4e[K7r9 1F u>;gnQ{X-?{ƫQYH߀{?;x?!pL0O{8ٝwe2L\Wt}GvR e ?v%*駣(M'}||R镋>_ >}lHujendstream endobj 208 0 obj << /BitsPerComponent 8 /ColorSpace /DeviceRGB /DecodeParms << /Colors 3 /Columns 149 /Predictor 15 >> /Filter /FlateDecode /Height 173 /SMask 200 0 R /Subtype /Image /Width 149 /Length 12958 >> stream x]w|۟˵B HT@(*RDESDKo* ("(@AHBB H/wɕ}ٹK|33BОA4ihAP?|kEp'T*eɻvjC:tPXXhGdzZD`w6kݦ8WvveR1g+8F[7òe˖/_nԵʸ.CxހS /:9rd-C毨Ņ2|"Ж<^8NNN-F;'0{8{F*ޒ j̘1?#/̶ve=V_^uݻwgI' 3f㏹H{5:L|%p?/Fha'xnpש2Bb4pEɴxuj*)Dζ+^H⋉'NMi۠87\%-鵒xhA:z8WubNqOʀ;xI@ EO&) u=Z8Z!Vu={ƍ-:g_$Bn4{WW*>OɾB_ܫW5E[sρuٻT"o$%:\6Rnm,ooo˄:>Z1 &xT*uaÆ si$ȢT5mpכֿL Mq\'N :ԔFk7a„BY-h0[yioj$ץZ,rhꫯr] ɶy63b .-[, geeVqЌ0ZiiirADSLٹs'0ۅ4uG\BgggS?~wus<i]yVBclhccSQQ ubmzh>zFane Zd :?Aksy.,f]/WN m=@}2ps]h<,5<e4[GWHp%w-ǯJ DV\?DmDp(Q5:Fj㾗dvFܳѶI͓f/j*+s_|ܫP 8OE1 AVͱlA$6 ]IAѬ.A7CjMwKQoZ Ѩ1džLX; U RT"Bd%Ab,Af(lq,Uh=3ɦ|'/%кQUIq2$DklmQ8X ا`_>f6tzЦMq+%є\oN(Umтȩ#~^GȱL ퟯ{!^/s1\@96R Y:2іG):eP ۗ7!W(yahY$E~lBoBart/^C z饇jj{QfP#$h$P4 YIhD7Rj]B~dF] tE XS^ 'p=3xOUXk޷{QomAѐK8,z=rcWp];A݌}NAo@]#C3BFک?ra"1"C~;GhU*ЇId|q\&zgq]悭^C%25w(Wqf('Q x5a5?#-?#N:oj%n EuBx>K/(b5RP碢XBkǛf,~x+9GhL. ? B 5u[Řbl# B%8-{w~ ~׃6Jutf3 "pmysWSq3a4q3[H:N^O~{:nfФU/$aϸFr%%.WS'Yu5IZ:/xȴ=V<5=^P,LA]$=71|4z~z49k~Okb%tҹhY@qSR3z aS:uq?:o$ݻ ㏛j[1Z=ȝ@;uu4t@ߔ8m/ ~R>ՂX6h*ޏz YtB쩻?Rcu4֌ө`~|{H:Yq1'uͣ6IѪ[vq9$L$ OFYsDE߼U V Qe1)ԇ?\cqY(TըLՉ&Zc;?w?w~^-dQCc%"6 v_.Ss!ß#Z oNEB4phm`M?Vvew%f5X 3w^Gׅ6~ <(rwPtRi4WՇ?Qi> ah3SzΜ*KH~̣*dia$/X?璓>~Y pm 0H:F*Bh@f.HZ2_~7@I황}^uV:,A̞ @܁iLKIm,%DhjS sꈛZ=#m@]КY]=hK ? ?AQt{DVJ."B HP \ x%C:ę3~X CL `5e\Fx4C-A:?0lۚfnL ArݡkX&m  v)TErp9ǍRxv:2yQ,2z}FT⃽_:G CI{ D4 Znj4svtrdVhS\o3p9k-X{XC]5uY` ~qVc;t6]aZڦof5*ݏHY<{vW$@/Q"4ջ!PeLf6`(R3'[ό@ǚ9"rݬCEIQm5 ۈ eAz`J@ h#!blJjYxdܡV"@]ԛnv@u d⮷ 7oT^< xcEvP_~wן wv0}H7htsG3_-fd7ĊmDS#uF)%Y.~7]st'E3{H7ʎSfx%)է|L>w`RxVwC>,;]E}5%9"7'@BT IzJK$d n}K#5+)iF"kz}!x+'^ך)[|z:=ts+w{}`r`]VZaCI2nF@, ơ"zř*[?g/I+x]ԗ͵e'^@We; re Z1oC,HMg֌~ǹnDҋU kTƕͲ6k.{XGl]v͜H̝I(fьhExhpq"RHPW\e٬@ଁYC@p)7-~Tʹ*q"O!nV2cIsPu %xEBcP(熛 @ [zitݨ;%Ҷk_;b䤺.LTk+۞4O`S5VJUH# #& PnM5*ru13l6;hXH ]Kok?LW5x4aYƾZVVN5!BJ6=:C牅{bkgֻc6?j[_!o3wzVlvMm7Q>굗u |Dɺ!%b_~L`<@_ha-P~au@='nB @2\I-׹iK+5UwZg;/GxtM{Mk\e]FB _&H*S9󡝉v3BTgUvHVi{q7%$PQ(=-嵤¯00md5]p$n jf<4S3?Ki0 h M@:^NTo\+ Lo+wyKK}aLo?+cK 7P fnc7A k4欗|y\ϱC>un=P BRߊ<[ױXqIڕ}j#1Br[1eP'kx_ kh;Ulau1H`3+”-X Я7&%:2{w{ԺgGL;3 Qq} /l.[z~ (#BC: [ mVz ioBtҎCNnKU.&eàZ殼'O:.Kk9{S#Gtcdx@dm퉘!T.]}ȟ-3[i!fɜC/w% ;Jډ;9-TU_ !CcH(ը˜dhvUVdG^Nw{V }'IHM`KC|[_KB=CJ7EIdOvَ}'zk7v96]v9avX%JW+Uq1/hG1EwopTgm, ׭ ZUrwa|b?e^6~%˭c6cS+^d油)ޟNiPISy]{07\۔SRim4wط Wùhيs^K,;QH3CPɬ\kbvY}ΒGբo'kJсKPVS)^Vl4 #E;k_KLynP&r*58?@]~ĎRSjqt=MX-xE]iw}1\oV3(vƟLQ̹7OG~WBwp6HԚj2y 7*p?l0to HB>yf]CInm-r&QWm?bl;q'ޠzPvd w]WOQ5j/̝-55 6+>(\>iO~}KFͻe}?{:}gb'i?|Yc?̂ J@(IN]k`i$BTs؁`Ic^Zh~S @:vb/7.e78| $'{R"Tqw?;~즗8\ ]9s"SxHMܚЭ>ͱۋ=m W):kVԱBn]%\;0+"p_Y0׷#H[:zirL_Y U(=\s勐=jba_ ߕ{_*7Y褀xY?+mDu{ՂV5̠>Nqz_~U@,4uu<2YRDЇo\hฺ?>s( !E?#pK H@i/{;y.33J?x}L$"i^Dn[y9 9;4Ӏ@N'ȝVׂR&/kíVT"j0Er T[h|`^Bڬn޹:,h.|pH/<'OX,䘟m 1~)rTJ+9cwVr^W;rNHȓvu}~FN*D_ZG3m? Q|7r=yHԷoۋ;C$!#-CLp@A79g79:J̓ :=jꓖvxsDTDZNz?Q_yBL  wF}.ru 1kp5/~fjFnv}?Ne3zRHԴ<{Z~^x CbI'"ͮH}5۴%8nI \MZsw,c{VT{$ .:|"k:(5j*2I[G|2qWr"EݐՀ ֘)buNҕ5K/jtT%bMԱAn=eMd톫.d?\ժsdK*Wgiբ|| )Uz1]pzM!wlhF x{NuRG&7#˥,=poH`w&IZO*ɑ/Cs%މ],(kJׂ, SONז룄By$@J^ỹxwXhO0\'=$h@u\* ro`^[$ÿ,W*UJ5u,H\~xf2Sꮍ+|S,i +2H MB#O+ilkCث\+w/": /9N`rIsK Rl+@"_ohv~1s@kk6}.v#++g@Ŗ+F G.3EUeW{ ](;4K3ǂ4WC$mANM RS m'T-<-v[QGK2!x.?C<9͠Uagq"h'\uWQ3T/&w>@v>p:N _uϏH+Rv.o?98Yd/ h!FTR| M䔠/ EAU ^nng vejY?Z%,^\gw'=$tҤ$ϓ'}:OSkQmG߱sWB]"I+.C %P`ö́׷׆N 2zJu}E*,+yG3eAoA > B7,|(clzBr`D2"tF>o<+؂z -8r!o*NAM cZCD1i y\ڮ, \16Qҍ{ņ)44Cwp?'!V4+$Q0JP#)tJp‡dT(Y}Ipk=$hd3m"_W{V0KB:1g˘YaK((s_Yc6̞& -',KYeЋSH/tC:mwYݣGG+(|uغu ,`lkkI5 $u"F8k{a"[)O@鯹 ?r@i]i??DWYiAz.F0RL[Bjح7 g1A\ C}Mݵ{"Źzj3,ڋQLguW <ж1P O"rZw}evb;#Y'+Z_yn_@Y=$s;ϋаȌ<<МX͜HK*w4Hw |%Vhp W+ۮx/7|CqˬJ k [++BBޞ-6|VY0:%񴍨BU4',R}>&g5^gU <O?m]uQ<>)2-_n%8AܥE\Pjb%Bݜi@!oCJwJQƩڛ kI HmE ]tm+!o\)'v LRM]W kK~}@;wu3<#NBE{gr₪+n!x?pĐ494{K Ukhؚx>z/7^H-Yם!텡7n1ɟo=Ǐ-{4ۯt*W%TjR =mtŏzFo"a'+Q3w8WlY7>g_6 xQFF ry|*[ Gܛٻ 4&wsxA[YQ¯`|y5m7xuV$ ,oy?4vK lٻar8]&DK/ʠ#i 8ԕ)7%>B*|lDG! 6"Ù;`=ԇzG60N5 V Xju)ÔV뿘kiL>-7'F*[fN珌7 N>s&UT۟޽{_y^BŅh] A!4V%o; ݹ8W9$B+7ICc炍1`HӧO߾};K=ΐ,H8o:'؀OF}H']0 -'Ani\(|o)X_>ùd\4?R)t]WZjwKR: NfϪ"ޠ_B@ 5$X.l>-))qpp0q]h<G}ILuf1Dͧ~ UFNς)Qq\e!&>;9|J@T:[72U| +/_ξ ڠQ3ng5.ջm 1&.G4Q*%bd܃ͪd2ODG;͠tމĖ YQB )s| bvJܝB zR&Jb/JZ.jX2R 0e %=={f(F0?U@Sy:I(lhP]:uF#u_UpPx]`xmut ^L;"S~ʺDsO7-sη~F>wJo<;yS_D~؇s? .ud ",ͦ{Inlt v8hռ%!cjHċ,"Mdh-nڈ qi$}5#Ȯ]@S;D0v7}Tg~kX^?Y0\b2Ds[B J47m4Q=)Q"|mwxA,[Y#1fYFvz5 eJWY3gsWv l5'<|r:}dW&{e:hf͚GV>Uˣq+i596pcdC;opκ1Guܫ-rKWykM%b7zҧVCLacc59<X\\lm?Q))#%By%5-?\H\s 0VD@ pe3Z(. ֓7n=m?E.}972p18؏;O;vh \\\W 4(O#$TTT2[?LPɬ\}fW:Mre˖-]hܺuLJaݏ4(E]}b :}tbh!ӧOlހȫ=/sc0w$ʯl$Z?> /W [ 1 3 1 ] /Info 3 0 R /Root 2 0 R /Size 210 /ID [] >> stream xcb&F~0 $8J+?M@6rP,6ËϠ_Y~9wDrN}A$ )D*L,n R dk%`;`6"H2،|`5`6dV ֥ &H`WHbn"s8V`7<VoE$ش^O]KAIVv .6l`\M Q# endstream endobj startxref 145641 %%EOF Brobdingnag/inst/doc/S4_brob.Rnw0000644000176200001440000010232414176571204016203 0ustar liggesusers\documentclass[nojss]{jss} \usepackage{dsfont} \usepackage{bbm} \usepackage{amsfonts} \usepackage{wasysym} \author{Robin K. S. Hankin\\Auckland University of Technology} \title{A step-by-step guide to writing a simple package that uses \proglang{S4} methods: a ``hello world'' example} %\VignetteIndexEntry{Brobdingnag: a ``hello world'' package using S4 methods} \Plainauthor{Robin K. S. Hankin} \Plaintitle{Brobdingnagian numbers in S4} \Shorttitle{Brobdingnagian numbers in S4} \Abstract{ This vignette shows how to use \proglang{S4} methods to create a simple package. The other vignette shows how to use the package for solving problems involving very large numbers; it is based on~\cite{Rnews:Hankin:2007}. } \Keywords{\proglang{S4} methods, Brobdingnag, \proglang{R}} \Plainkeywords{S4 methods, Brobdingnag, R} \Address{ Robin K. S. Hankin\\ Auckland University of Technology\\ E-mail: \email{hankin.robin@gmail.com}\hfill\includegraphics[width=1in]{\Sexpr{system.file("help/figures/brobdingnag.png",package="Brobdingnag")}} } %% need no \usepackage{Sweave.sty} \SweaveOpts{echo=TRUE} \begin{document} \newsymbol\leqslant 1336 \hfill\includegraphics[width=1in]{\Sexpr{system.file("help/figures/brobdingnag.png",package="Brobdingnag")}} \section{Introduction} This vignette proves that it is possible for a `normal' person\footnote{That is, someone without super powers (such as might manifest themselves after being bitten by a radioactive member of \proglang{R}-core, for example)} to write a package using \proglang{S4} methods. It gives a step-by-step guide to creating a package that contains two \proglang{S4} classes (brobs and glubs) and a bunch of basic utilities for manipulating them. This document focuses on the \proglang{S4} aspects of the package. For an overview of the mathematical properties of Brobdingnagian numbers, their potential and their limitations, see the {\tt .Rd} files and~\cite{Rnews:Hankin:2007}. If you like this vignette and package, and find it useful, let me know. If there is anything wrong with it, let me know. I would not recommend that anyone uses \proglang{S4} unless there is a good reason for it (many of my packages use \proglang{S3} methods which I found to be perfectly adequate for my needs). Reasons for using \proglang{S4} might include a package having a large number of object classes that have a complicated hierarchical structure, or a complicated set of methods that interact with the object classes in a complicated manner. In the package, brobs are dealt with in {\tt brob.R}, and glubs are treated in {\tt glub.R} which appropriately generalizes all the {\tt brob} functionality. This document could not have been prepared (and should not be read) without consulting the following resources: \begin{itemize} \item John M. Chambers (1998), {\it Programming with Data}. New York: Springer, ISBN 0-387-98503-4 (The Green Book). \item W. N. Venables and B. D. Ripley (2000), {\it S Programming}. Springer, ISBN 0-387-98966-8. \item John Chambers (2006). {\tt How \proglang{S4} methods work} (available on CRAN). \end{itemize} \subsection{Overview} The idea of {\tt Brobdingnag} package is simple: the IEEE representation for floating point numbers cannot represent numbers larger than about~$1.8\times 10^{308}$. The package represents a number by the natural logarithm of its magnitude, and also stores a Boolean value indicating its sign. Objects so stored have class {\tt brob}; complex numbers may be similarly represented and have class {\tt glub}. With this scheme, multiplication is easy but addition is hard. The basic identity is: \[ \log(e^x+e^y) = \left\{ \begin{array}{cc} x+\log\left(1+e^{y-x}\right)\qquad &\mbox{if~$x>y$}\\ y+\log\left(1+e^{x-y}\right)\qquad &\mbox{otherwise} \end{array} \right. \] In practice this gets more complicated as one has to keep track of the sign; and special dispensation is needed for zero ($=e^{-\infty}$). One can thus deal with numbers up to about~$e^{1.9\times 10^{308}}\simeq 10^{7.8\times 10^{307}}$, although at this outer limit accuracy is pretty poor. \section{Class definition} The first thing we need to do is to define the {\tt brob} class. This uses the {\tt setClass()} function: <>= <>= setClass("swift", representation = "VIRTUAL" ) setClass("brob", representation = representation(x="numeric",positive="logical"), prototype = list(x=numeric(),positive=logical()), contains = "swift" ) @ It is simpler to ignore the first call to {\tt setClass()} here; for reasons that will become apparent when discussing the {\tt c()} function, one needs a virtual class that contains class brob and glub. To understand virtual classes, see section~\ref{logicSection}. The second call to {\tt setClass()} is more germane. Let's take this apart, argument by argument. The first argument, {\tt representation}, specifies ``the slots that the new class should have and/or other classes that this class extends. Usually a call to the `representation' function''. The helppage for {\tt representation} gives a few further details. Thus this argument specifies two `slots': one for the value and one for the sign. These are specified to be numeric and logical (NB: not Boolean) respectively. The second argument, {\tt prototype}, specifies default data for the slots. This kicks in when defining a zero-length brob; an example would be extracting {\tt x[FALSE]} where {\tt x} is a brob. The third argument, {\tt contains}, tells \proglang{R} that class {\tt swift} (which was specified to be virtual), has {\tt brob} as a subclass. We will need this later when we start to deal with {\tt glub}s, which are also a subclass of {\tt swift}. Let's use it: <>= new("brob",x=1:10,positive=rep(TRUE,10)) @ Notes: \begin{itemize} \item Function {\tt new()} is the {\em only} way to create objects of class brob. So, any object of class brob {\em must} have been created with function {\tt new()}. This is part of what the ``formal'' tag for \proglang{S4} means\footnote{Compare \proglang{S3}, in which I can say {\tt a <- 1:10; class(a) <- "lilliput"}}. \item Function {\tt new()} requires its arguments to be named, and no partial argument matching is performed. \item Function {\tt new()} is not intended for the user. It's too picky and difficult. To create new brobs, we need some more friendly functions---{\tt as.brob()} and {\tt brob()}---discussed below. \item There is, as yet, no print method, so the form of the object printed to the screen is less than ideal. \end{itemize} \subsection{Validity methods} Now, an optional step is to define a function that tests whether the arguments passed to {\tt new()} are acceptable. As it stands, the following code: <>= new("brob",x=1:10,positive=c(TRUE,FALSE,FALSE)) @ \noindent will not return an error, but is not acceptable because the arguments are different lengths (and will not recycle neatly). So, we define a validity method: <>= .Brob.valid <- function(object){ len <- length(object@positive) if(len != length(object@x)){ return("length mismatch") } else { return(TRUE) } } @ Advice on the form of the validity-testing function---here {\tt .Brob.valid()}---is given in the help page for {\tt setValidity}: ``The method should be a function of one object that returns `TRUE' or a description of the non-validity''. Examples are given in section 7.1.6 of the Green Book. In this package, I define a whole bunch of functions whose name starts with {\tt .Brob.}; these are internal and not intended for the user. They are also not documented. So now we have a function, {\tt .Brob.valid()}, that checks whether its argument has slots of the same length. We need to tell \proglang{R} that this function should be invoked every time a {\tt brob} is created. Function {\tt setValidity()} does this: <>= setValidity("brob", .Brob.valid) @ Thus, from now on [ie after the above call to {\tt setValidity()}], when calling {\tt new("brob", ...)} the two arguments {\tt x} and {\tt positive} must be the same length: recycling is not carried out. Functions like {\tt .Brob.valid()} that are user-unfriendly all have names beginning with {\tt .Brob}. These functions are there to help the organization of the package and are not intended to be used by the end-user. Clever, user-friendly operations such as recycling are carried out in the more user-friendly functions such as {\tt as.brob()}. If one were to call {\tt new()} with arguments of differing lengths, as in \\ \\ {\tt new("brob",x=1:10,positive=TRUE) } \\ \\ then {\tt new()} would report the error message in function {\tt .Brob.valid()}, because the {\tt positive} argument had length~1 and the {\tt x} was length~10; and the validity method {\tt .Brob.valid()} requires both arguments to be the same length\footnote{Placing the above call in {\tt try()} and showing the error explicitly would cause the package to fail {\tt R CMD check}.}. So now {\tt new()} works, but isn't exactly user-friendly: often one would want the above call to recycle the second argument to length 10 to match the first. This deficiency is remedied in the next section. \section{Basic user-friendly functions to create brobs} The basic, semi user-friendly function for creating brobs is {\tt brob()}: <>= "brob" <- function(x=double(),positive){ if(missing(positive)){ positive <- rep(TRUE,length(x)) } if(length(positive)==1){ positive <- rep(positive,length(x)) } new("brob",x=as.numeric(x),positive=positive) } @ Thus {\tt brob(x)} will return a number formally equal to~$e^x$. Function {\tt brob()} does helpful things like assuming the user desires positive numbers; it also carries out recycling: <>= brob(1:10,FALSE) @ Note that {\tt brob()} isn't exactly terribly user-friendly: it's confusing. {\tt brob(5)} returns a number formally equal to~$e^5$, not~$5$. This is documented in the help page, where the user is encouraged to use function {\tt as.brob()} instead. \section[Testing for brobs: an ``is.brob()'' function]{Testing for brobs: an {\tt is.brob()} function} Function {\tt is()} will test for an object being a brob: <>= is(brob(1:5),"brob") @ (see {\tt help(is)} for more details) but a small package like this, with only brobs and glubs to consider, could benefit from an \proglang{S3}-style function {\tt is.brob()}. This is easy to define: <>= is.brob <- function(x){is(x,"brob")} is.glub <- function(x){is(x,"glub")} @ now the user can just type {\tt is.brob(x)} to find out whether an object is a brob\footnote{This approach is fine for a tiny package like Brobdingnag, with only two or three classes. However, in the context of a more complicated package such as {\tt Matrix}, which uses dozens of different classes in a complicated hierarchical structure, one might prefer to type {\tt is(x,"dpoMatrix-class")} rather than define a plethora of functions along the lines of {\tt is.dpoMatrix-class()}.}. We also define an {\tt is.glub()} function similarly. So now we can check for objects being brobs and glubs. \section[Coercion: an ``as.brob()'' function]{Coercion: an {\tt as.brob()} function} Next, some ways to coerce objects to class brob: <>= "as.brob" <- function(x){ if(is.brob(x)){ return(x) } else if(is.complex(x)) { warning("imaginary parts discarded") return(Recall(Re(x))) } else if(is.glub(x)){ warning("imaginary parts discarded") return(Re(x)) } else { return(brob(log(abs(x)), x>=0)) } } @ So now we can coerce objects of various classes to brobs\footnote{The recommended way, appropriate for a complicated package such as Matrix, would be to execute {\tt setAs("numeric", "brob", .Brob.numeric\_to\_brob)} and {\tt setAs("complex", "brob", .Brob.complex\_to\_brob)}. Then, if {\tt x} is numeric, {\tt as(x,"brob")} would return the appropriate brob via {\tt .Brob.numeric\_to\_brob()}; we could then make {\tt as.brob()} a generic with {\tt setGeneric()} and define methods for it. Doing it this way would save function {\tt as.brob()} having to test for its argument being a brob [carried out in the first few lines of {\tt as.brob()}] because {\tt as()} has such a test built in, implicitly.}. The {\em only} way to create a brob is to use {\tt new()}, and the {\em only} function that calls this is {\tt brob()}. And {\tt as.brob()} calls this. Note the user-friendliness of {\tt as.brob()}. It takes numerics, brobs, and glubs (which give a warning). Check {\tt as.brob()}: <>= as.brob(1:10) @ \section[Coercion: an ``as.numeric()'' function]{Coercion: an {\tt as.numeric()} function} Now we need some methods to coerce brobs to numeric. This is a two-stage process. <>= <>= setAs("brob", "numeric", function(from){ out <- exp(from@x) out[!from@positive] <- -out[!from@positive] return(out) } ) @ This call to {\tt setAs()} makes {\tt as(x,"numeric")} carry out the function passed as the third argument when given a brob. But in this package, the user isn't supposed to type {\tt as(x,"numeric")}: the user is supposed to type {\tt as.numeric(x)}\footnote{Users can be expected to be familiar with functions such as {\tt as.numeric()} and {\tt as.complex()}, which is why the Brobdingnag package recommends this form. However, this might not be appropriate for a more complicated package such as Matrix because, to quote Martin Maechler, ``it seems very ugly to define more than very few {\tt as.FOO()} methods, and very natural to work with {\tt as(*, "FOO")} [constructions]''. Of course, there's nothing to stop a user typing {\tt as(x,"numeric")} if they wish.}. To accomplish this, we have to tell \proglang{R} that function {\tt as.numeric()} should execute {\tt as(x,"numeric")} when given a {\tt brob}. This is done by calling function {\tt setMethod()}: <>= setMethod("as.numeric",signature(x="brob"),function(x){as(x,"numeric")}) @ We similarly need to make {\tt as.complex()} work for brobs: <>= setAs("brob", "complex", function(from){ return(as.numeric(from)+ 0i) } ) setMethod("as.complex",signature(x="brob"),function(x){as(x,"complex")}) @ We'll need similar methods for glubs too. Better check: <>= x <- as.brob(1:4) x as.numeric(x) @ So that works. \section{Print methods} Print methods are not strictly necessary, but make using the package much easier. First, a helper function: <>= .Brob.print <- function(x, digits=5){ noquote( paste(c("-","+")[1+x@positive],"exp(",signif(x@x,digits),")",sep="")) } @ Then an \proglang{S3} method: <>= print.brob <- function(x, ...){ jj <- .Brob.print(x, ...) print(jj) return(invisible(jj)) } @ And finally a call to {\tt setMethod()}: <>= setMethod("show", "brob", function(object){print.brob(object)}) @ This two-stage methodology is recommended in the Venables and Ripley. The {\tt .Brob.print()} function does the hard work. Example of it in use: <>= as.brob(1:4) @ See how the brob object is printed out nicely, and with no special effort required of the user. \section{Get and Set methods} To be anal retentive about things, one should define {\tt C++} style accessor functions as follows: <>= <>= setGeneric("getX",function(x){standardGeneric("getX")}) setGeneric("getP",function(x){standardGeneric("getP")}) setMethod("getX","brob",function(x){x@x}) setMethod("getP","brob",function(x){x@positive}) @ but in practice I just use {\tt @} to access the slots. These are just here for good form's sake. \section{Length} Now a length: <>= <>= setMethod("length","brob",function(x){length(x@x)}) @ \section{Extracting elements of a vector} Next thing is to define some methods for extraction. This is done with {\tt setMethod()} for extraction, and {\tt setReplaceMethod()} for replacement. <>= <>= setMethod("[", "brob", function(x, i, j, drop){ if(!missing(j)){ warning("second argument to extractor function ignored") } brob(x@x[i], x@positive[i]) } ) @ See how the third argument to {\tt setMethod()} is a function whose arguments are the same as those to {\tt "["() %] }. Argument {\tt j} {\em must} be there otherwise one gets a signature error. I've put in a warning if a second argument that might be interpreted as {\tt j} is given. Now a method for replacement. This is a call to {\tt setReplaceMethod()}: <>= <>= setReplaceMethod("[",signature(x="brob"), function(x,i,j,value){ if(!missing(j)){ warning("second argument to extractor function ignored") } jj.x <- x@x jj.pos <- x@positive if(is.brob(value)){ jj.x[i] <- value@x jj.pos[i] <- value@positive return(brob(x=jj.x,positive=jj.pos)) } else { x[i] <- as.brob(value) return(x) } } ) @ See how the replacement function tests for the replacement value being a brob and acts accordingly. \section[Concatenation function ``cbrob()'']{Concatenation function {\tt cbrob()}} \label{cbrob} It is not possible to make {\tt c()} behave as expected for brobs\footnote{The ideas in this section are entirely due to John Chambers, who kindly replied to a question of mine on the \proglang{R}-devel email list} (that is, if any of its arguments are brobs, to coerce all its arguments to brobs and then concatenate). However, it is possible to define a function {\tt cbrob()} that does the job. This has to be done in several stages. First we define another user-unfriendly helper function {\tt .Brob.cPair()} which takes two arguments, coerces them to brobs, and concatenates them: <<.Brob.cPair>>= .Brob.cPair <- function(x,y){ x <- as.brob(x) y <- as.brob(y) brob(c(x@x,y@x),c(x@positive,y@positive)) } @ This is just {\tt c()} for the two slots separately. The idea is that function {\tt .Brob.cPair()} takes two arguments; both are coerced to brobs and it returns the concatenated vector of brobs. Now, we need to set up a (user-unfriendly) generic function {\tt .cPair()}: <>= <>= setGeneric(".cPair", function(x,y){standardGeneric(".cPair")}) @ Function {\tt .cPair()} is not substantive (sic): it exists purely in order to be a generic function that dispatches to {\tt .Brob.cPair()}. Now we use {\tt setMethod()} to organize the dispatch: <>= <>= setMethod(".cPair", c("brob", "brob"), function(x,y){.Brob.cPair(x,y)}) setMethod(".cPair", c("brob", "ANY"), function(x,y){.Brob.cPair(x,as.brob(y))}) setMethod(".cPair", c("ANY", "brob"), function(x,y){.Brob.cPair(as.brob(x),y)}) setMethod(".cPair", c("ANY", "ANY"), function(x,y){c(x,y)}) @ The four calls are necessary for the four different signatures that might be encountered. Note the {\tt ANY} class in the second, third, and fourth call. Thus if someone wants to write a new class of object (a lugg, say), and wants to concatenate luggs with a brob, this will work provided that they use {\tt setAs()} to make {\tt as.brob()} coerce correctly for lugg objects. The method used here allows this to be done without any changes to the Brobdingnag package. The final stage is the definition of {\tt cbrob()}, a user-friendly wrapper for the above stuff: <>= "cbrob" <- function(x, ...) { if(nargs()<3) .cPair(x,...) else .cPair(x, Recall(...)) } @ Note the recursive definition. If {\tt cbrob()} is called with {\em any} set of arguments that include a brob anywhere, this will result in the whole lot being coerced to brobs [by {\tt .Brob.cPair()}]. Which is what we want (although glubs will require more work). Just test this: <>= a <- 1:3 b <- as.brob(1e100) cbrob(a,a,b,a) @ So it worked: everything was coerced to a brob because of the single object of class brob in the call. \section{Maths} The math group generic functions are set with function {\tt setMethod()}. But, before this can be called, function {\tt sqrt()} needs a specific brob method: <>= <>= setMethod("sqrt","brob", function(x){ brob(ifelse(x@positive,x@x/2, NaN),TRUE) } ) @ Just check that: <>= sqrt(brob(4)) @ With these out of the way we can use {\tt setMethod()} to define the appropriate functions in the math group generic: <>= <>= setMethod("Math", "brob", function(x){ switch(.Generic, abs = brob(x@x), log = { out <- x@x out[!x@positive] <- NaN out }, exp = brob(x), cosh = {(brob(x) + brob(-x))/2}, sinh = {(brob(x) - brob(-x))/2}, acos =, acosh =, asin =, asinh =, atan =, atanh =, cos =, sin =, tan =, tanh =, trunc = callGeneric(as.numeric(x)), lgamma =, cumsum =, gamma =, ceiling=, floor = as.brob(callGeneric(as.numeric(x))), stop(paste(.Generic, "not allowed on Brobdingnagian numbers")) ) } ) @ See how the third argument to {\tt setMethod()} is a function. This function has access to {\tt .Generic}, in addition to {\tt x} and uses it to decide which operation to perform. See how functions {\tt acos()} to {\tt trunc()} just drop through to {\tt callGeneric(as.numeric(x))}. See also the method for {\tt log()}, which uses facts about brobs not known to \proglang{S4}. Just a quick check: <>= sin(brob(4)) @ So that works. \section{Operations} Now we need to make sure that {\tt brob(1) + brob(3)} works: the operations {\tt +, -, *, /} must work as expected. This is hard. First step: define some user-unfriendly functions that carry out the operations. For example, function {\tt .Brob.negative()} simply returns the negative of a brob. These functions are not for the user. <<.brob.arithstuff>>= .Brob.negative <- function(e1){ brob(e1@x,!e1@positive) } .Brob.ds <- function(e1,e2){ # "ds" == "different signs" xor(e1@positive,e2@positive) } .Brob.add <- function(e1,e2){ e1 <- as.brob(e1) e2 <- as.brob(e2) jj <- rbind(e1@x,e2@x) x1 <- jj[1,] x2 <- jj[2,] out.x <- double(length(x1)) jj <- rbind(e1@positive,e2@positive) p1 <- jj[1,] p2 <- jj[2,] out.pos <- p1 ds <- .Brob.ds(e1,e2) ss <- !ds #ss == "Same Sign" out.x[ss] <- pmax(x1[ss],x2[ss]) + log1p(+exp(-abs(x1[ss]-x2[ss]))) out.x[ds] <- pmax(x1[ds],x2[ds]) + log1p(-exp(-abs(x1[ds]-x2[ds]))) # Now special dispensation for 0+0: out.x[ (x1 == -Inf) & (x2 == -Inf)] <- -Inf out.pos <- p1 out.pos[ds] <- xor((x1[ds] > x2[ds]) , (!p1[ds]) ) return(brob(out.x,out.pos)) } .Brob.mult <- function(e1,e2){ e1 <- as.brob(e1) e2 <- as.brob(e2) return(brob(e1@x + e2@x, !.Brob.ds(e1,e2))) } .Brob.power <- function(e1,e2){ stopifnot(is.brob(e1) | is.brob(e2)) if(is.brob(e2)){ # e2 a brob => answer a brob (ignore signs) return(brob(log(e1) * brob(e2@x), TRUE)) } else { #e2 a non-brob (try to account for signs) s <- as.integer(2*e1@positive-1) #s = +/-1 return(brob(e1@x*as.brob(e2), (s^as.numeric(e2))>0)) } } .Brob.inverse <- function(b){brob(-b@x,b@positive)} @ Note the complexity of {\tt .Brob.add()}. This is hard because logs are good at multiplying but bad at adding [{\tt ss} and {\tt ds} mean ``same sign'' and ``different sign'' respectively]. The first step is to make sure that the unary operators {\tt +} and {\tt -} work. We do this by a call to {\tt setMethod()}: <>= <>= setMethod("Arith",signature(e1 = "brob", e2="missing"), function(e1,e2){ switch(.Generic, "+" = e1, "-" = .Brob.negative(e1), stop(paste("Unary operator", .Generic, "not allowed on Brobdingnagian numbers")) ) } ) @ Note the second argument is {\tt signature(e1 = "brob", e2="missing")}: this effectively restricts the scope to unary operators. The {\tt switch()} statement only allows the + and the -.\ Check: <>= -brob(5) @ So that works. Next step, another user-unfriendly helper function that does the dirty work: <>= .Brob.arith <- function(e1,e2){ switch(.Generic, "+" = .Brob.add (e1, e2), "-" = .Brob.add (e1, .Brob.negative(as.brob(e2))), "*" = .Brob.mult (e1, e2), "/" = .Brob.mult (e1, .Brob.inverse(as.brob(e2))), "^" = .Brob.power(e1, e2), stop(paste("binary operator \"", .Generic, "\" not defined for Brobdingnagian numbers")) ) } @ And now we can call {\tt setMethod()}: <>= setMethod("Arith", signature(e1 = "brob", e2="ANY"), .Brob.arith) setMethod("Arith", signature(e1 = "ANY", e2="brob"), .Brob.arith) setMethod("Arith", signature(e1 = "brob", e2="brob"), .Brob.arith) @ Better check it: <>= 1e100 + as.brob(10)^100 @ \section{Comparison} This is pretty much the same as the others. First, some user-unfriendly helper functions: <>= .Brob.equal <- function(e1,e2){ (e1@x==e2@x) & (e1@positive==e2@positive) } .Brob.greater <- function(e1,e2){ jj.x <- rbind(e1@x,e2@x) jj.p <- rbind(e1@positive,e2@positive) ds <- .Brob.ds(e1,e2) ss <- !ds #ss == "Same Sign" greater <- logical(length(ss)) greater[ds] <- jj.p[1,ds] greater[ss] <- jj.p[1,ss] & (jj.x[1,ss] > jj.x[2,ss]) return(greater) } @ These are the fundamental ones. We can now define another all-encompassing user-unfriendly function: <>= ".Brob.compare" <- function(e1,e2){ e1 <- as.brob(e1) e2 <- as.brob(e2) switch(.Generic, "==" = .Brob.equal(e1,e2), "!=" = !.Brob.equal(e1,e2), ">" = .Brob.greater(e1,e2), "<" = !.Brob.greater(e1,e2) & !.Brob.equal(e1,e2), ">=" = .Brob.greater(e1,e2) | .Brob.equal(e1,e2), "<=" = !.Brob.greater(e1,e2) | .Brob.equal(e1,e2), stop(paste(.Generic, "not supported for Brobdingnagian numbers")) ) } @ See how this function coerces both arguments to brobs. Now the call to {\tt setMethod()}: <>= <>= setMethod("Compare", signature(e1="brob", e2="ANY" ), .Brob.compare) setMethod("Compare", signature(e1="ANY" , e2="brob"), .Brob.compare) setMethod("Compare", signature(e1="brob", e2="brob"), .Brob.compare) @ Better check: <>= as.brob(10) < as.brob(11) as.brob(10) <= as.brob(10) @ So that works. \section{Logic} \label{logicSection} (The material in this section works in \proglang{R}-2.4.1, but not \proglang{R}-2.4.0). First a helper function: <>= .Brob.logic <- function(e1,e2){ stop("No logic currently implemented for Brobdingnagian numbers") } @ Now the calls to {\tt setMethod()}: <>= <>= setMethod("Logic",signature(e1="swift",e2="ANY"), .Brob.logic) setMethod("Logic",signature(e1="ANY",e2="swift"), .Brob.logic) setMethod("Logic",signature(e1="swift",e2="swift"), .Brob.logic) @ Note that the signatures specify {\tt swift} objects, so that glubs will be handled correctly too in one fell swoop. Note the third call to {\tt setMethod()}: without this, a call to {\tt Logic()} with signature {\tt c("swift","swift")} would be ambiguous as it might be interpreted as {\tt c("swift","ANY")} or {\tt c("ANY","swift")}. Here, class {\tt swift} extends {\tt brob} and {\tt glub}; so both brobs and glubs {\em are} {\tt swift} objects. But no object is a ``pure'' {\tt swift}; it's either a brob or a glub. This is useful here because I might dream up some new class of objects that are ``like'' brobs in some way (for example, a class of objects whose elements are quaternions with Brobdingnagian components) and it would be nice to specify behaviour that is generic to brobs and glubs and the new class of objects too. \section{Miscellaneous generics} We now have to tell \proglang{R} that certain functions are to be considered generic. The functions are {\tt max(), min(), range(), prod()}, and {\tt sum()}. The help page for (eg) {\tt max()} specifies that the arguments must be numeric, and brobs aren't numeric. In versions of \proglang{R} prior to 2.6-0 (I think), {\tt log()} needs to be made a generic with {\tt setGeneric()}. But, in versions 2.6-0 and above, all the group generics (including {\tt log}) are primitive, which means that the generic function is implicit and cannot be changed. This applies to the other group generics too ({\tt max}, {\tt min}, {\tt prod}, {\tt range} {\tt sum}). So to work with both types of \proglang{R}, one needs to check whether or not {\tt log} (or {\tt max} or whatever) is generic before calling {\tt setGeneric()}. <>= if(!isGeneric("log")){ setGeneric("log",group="Math") } @ <>= <>= if(!isGeneric("sum")){ setGeneric("max", function(x, ..., na.rm = FALSE) { standardGeneric("max") }, useAsDefault = function(x, ..., na.rm = FALSE) { base::max(x, ..., na.rm = na.rm) }, group = "Summary") setGeneric("min", function(x, ..., na.rm = FALSE) { standardGeneric("min") }, useAsDefault = function(x, ..., na.rm = FALSE) { base::min(x, ..., na.rm = na.rm) }, group = "Summary") setGeneric("range", function(x, ..., na.rm = FALSE) { standardGeneric("range") }, useAsDefault = function(x, ..., na.rm = FALSE) { base::range(x, ..., na.rm = na.rm) }, group = "Summary") setGeneric("prod", function(x, ..., na.rm = FALSE) { standardGeneric("prod") }, useAsDefault = function(x, ..., na.rm = FALSE) { base::prod(x, ..., na.rm = na.rm) }, group = "Summary") setGeneric("sum", function(x, ..., na.rm = FALSE) { standardGeneric("sum") }, useAsDefault = function(x, ..., na.rm = FALSE) { base::sum(x, ..., na.rm = na.rm) }, group = "Summary") } @ Now we need some more user-unfriendly helper functions: <>= .Brob.max <- function(x, ..., na.rm=FALSE){ p <- x@positive val <- x@x if(any(p)){ return(brob(max(val[p]))) } else { # all negative return(brob(min(val),FALSE)) } } .Brob.prod <- function(x){ p <- x@positive val <- x@x return(brob(sum(val),(sum(p)%%2)==0)) } .Brob.sum <- function(x){ .Brob.sum.allpositive( x[x>0]) - .Brob.sum.allpositive(-x[x<0]) } .Brob.sum.allpositive <- function(x){ if(length(x)<1){return(as.brob(0))} val <- x@x p <- x@positive mv <- max(val) return(brob(mv + log1p(sum(exp(val[-which.max(val)]-mv))),TRUE)) } @ Note the final function that sums its arguments, which are all assumed to be positive, in an intelligent, accurate, and efficient manner. No checking is done (this is not a user-friendly function!). We can define {\tt .Brob.sum()} in terms of this: return the difference between the sum of the positive arguments and and the sum of minus the negative arguments. <>= <>= setMethod("Summary", "brob", function(x, ..., na.rm=FALSE){ switch(.Generic, max = .Brob.max( x, ..., na.rm=na.rm), min = -.Brob.max(-x, ..., na.rm=na.rm), range = cbrob(min(x,na.rm=na.rm),max(x,na.rm=na.rm)), prod = .Brob.prod(x), sum = .Brob.sum(x), stop(paste(.Generic, "not allowed on Brobdingnagian numbers")) ) } ) @ Better check: <>= sum(as.brob(1:100)) - 5050 @ showing acceptable accuracy. \section{Examples of the package in use} We can try to evaluate a factorial. Stirling's approximation is~$n!\sim\sqrt{2\pi n}\,e^{-n}n^n$: <>= stirling <- function(x){sqrt(2*pi*x)*exp(-x)*x^x} @ And this should work seamlessly with Brobs: <>= stirling(100) stirling(as.brob(100)) @ And are they the same? <>= as.numeric(stirling(100)/stirling(as.brob(100))) @ \ldots pretty near. But the great advantage of Brobdingnagian numbers is that they can handle numbers larger than the IEEE limit: <>= stirling(1000) stirling(as.brob(1000)) @ \noindent and this is accurate to about~12 sig figs, which is accurate enough for many purposes. The number of sig figs decreases with progressively larger numbers, essentially because increasing amounts of floating point accuracy is gobbled up by storing the exponent of a large number, and less is left for the mantissa. \section*{Acknowledgments} I gratefully acknowledge the help given to me by many members of the \proglang{R}-help and \proglang{R}-devel lists, especially Martin Maechler, Brian Ripley, and John Chambers. \nocite{*} \bibliography{brob} \end{document} Brobdingnag/inst/doc/Brobdingnag.Rnw0000644000176200001440000001672014176571204017131 0ustar liggesusers\documentclass[nojss]{jss} \usepackage{dsfont} \usepackage{bbm} \usepackage{amsfonts} \usepackage{wasysym} \author{Robin K. S. Hankin\\Auckland University of Technology} \title{Very large numbers in \proglang{R}: Introducing package \pkg{Brobdingnag}} %\VignetteIndexEntry{The Brobdingnag: package} \Plainauthor{Robin K. S. Hankin} \Plaintitle{Very large numbers in R: Introducing package Brobdingnag} \Plaintitle{Introducing package Brobdingnag} \Abstract{ This vignette shows how to use the \pkg{Brobdingnag} package to manipulate very large numbers; it is based on~\cite{Rnews:Hankin:2007}. The other vignette shows how to use \proglang{S4} methods in the context of a simple package. } \Keywords{\proglang{S4} methods, Brobdingnag, \proglang{R}} \Plainkeywords{S4 methods, Brobdingnag, R} \Address{ Robin K. S. Hankin\\ Auckland University of Technology E-mail: \email{hankin.robin@gmail.com}\hfill\includegraphics[width=1in]{\Sexpr{system.file("help/figures/brobdingnag.png",package="Brobdingnag")}} } %% need no \usepackage{Sweave.sty} \SweaveOpts{echo=TRUE} \begin{document} \newsymbol\leqslant 1336 \hfill\includegraphics[width=1in]{\Sexpr{system.file("help/figures/brobdingnag.png",package="Brobdingnag")}} \section{Introduction} The largest floating point number representable in standard double precision arithmetic is a little under~$2^{1024}$, or about~$1.79\times 10^{308}$. This is too small for some applications. The \proglang{R} package \pkg{Brobdingnag}~\citep{swift1726} overcomes this limit by representing a real number~$x$ using a double precision variable with value~$\log\left|x\right|$, and a logical corresponding to~$x\geq 0$; the \proglang{S4} class of such objects is \code{brob}. Complex numbers with large absolute values (class \code{glub}) may be represented using a pair of \code{brob}s to represent the real and imaginary components. The package allows user-transparent access to the large numbers allowed by Brobdingnagian arithmetic. The package also includes a vignette---\code{brob}---which documents the \proglang{S4} methods used and includes a step-by-step tutorial. The vignette also functions as a ``Hello, World!'' example of \proglang{S4} methods as used in a simple package. It also includes a full description of the \code{glub} class. \section[Package ``Brobdingnag'' in use]{Package \pkg{Brobdingnag} in use} Most readers will be aware of a googol which is equal to~$10^{100}$: <>= <>= require(Brobdingnag) <>= googol <- as.brob(10)^100 @ Note the coercion of \code{double} value \code{10} to an object of class \code{brob} using function \code{as.brob()}: raising this to the power~100 (also double) results in another \code{brob}. The result is printed using exponential notation, which is convenient for very large numbers. A googol is well within the capabilities of standard double precision arithmetic. Now, however, suppose we wish to compute its factorial. Taking the first term of Stirling's series gives <>= stirling <- function(n){n^n*exp(-n)*sqrt(2*pi*n)} @ \noindent which then yields <>= stirling(googol) @ Note the transparent coercion to \code{brob} form within function \code{stirling()}. It is also possible to represent numbers very close to~1. Thus <>= 2^(1/googol) @ It is worth noting that if~$x$ has an exact representation in double precision, then~$e^x$ is exactly representable using the system described here. Thus~$e$ and~$e^{1000}$ may be represented exactly. \subsection{Accuracy} For small numbers (that is, representable using standard double precision floating point arithmetic), \pkg{Brobdingnag} suffers a slight loss of precision compared to normal representation. Consider the following function, whose return value for nonzero arguments is algebraically zero: <>= f <- function(x){as.numeric( (pi*x -3*x -(pi-3)*x)/x)} @ \begin{verbatim} f <- function(x){ as.numeric( (pi*x -3*x -(pi-3)*x)/x) } \end{verbatim} This function combines multiplication and addition; one might expect a logarithmic system such as described here to have difficulty with it. <>= f(1/7) f(as.brob(1/7)) @ This typical example shows that Brobdingnagian numbers suffer a slight loss of precision for numbers of moderate magnitude. This degradation increases with the magnitude of the argument: <>= f(1e100) f(as.brob(1e100)) @ Here, the brobs' accuracy is about two orders of magnitude worse than double precision arithmetic: this would be expected, as the number of bits required to specify the exponent goes as $\log\log x$. Compare <>= f(as.brob(10)^1000) @ \noindent showing a further degradation of precision. However, observe that conventional double precision arithmetic cannot deal with numbers this big, and the package returns about 12 correct significant figures. \section{A practical example} In the field of population dynamics, and especially the modelling of biodiversity~\citep{hankin2007b,hubbell2001}, complicated combinatorial formulae often arise. \citet{etienne2005}, for example, considers a sample of~$N$ individual organisms taken from some natural population; the sample includes~$S$ distinct species, and each individual is assigned a label in the range~$1$ to~$S$. The sample comprises~$n_i$ members of species~$i$, with~$1\leq i\leq S$ and~$\sum n_i=N$. For a given sample~$D$ Etienne defines, amongst other terms, $K(D,A)$ for $1\leq A\leq N-S+1$ as \begin{equation} \sum_{ \left\{ a_1,\ldots,a_S\left| \sum_{i=1}^S a_i=A\right. \right\}} \prod_{i=1}^S \frac{ \overline{s}(n_i,a_i) \overline{s}(a_i,1)}{ \overline{s}(n_i,1)} \end{equation} \noindent where~$\overline{s}(n,a)$ is the Stirling number of the second kind~\citep{abramowitz1965}. The summation is over~$a_i=1,\ldots,n_i$ with the restriction that the~$a_i$ sum to~$A$, as carried out by \code{blockparts()} of the \pkg{partitions} package~\citep{hankin2006,hankin2007}. Taking an intermediate-sized dataset due to Saunders\footnote{The dataset comprises species counts on kelp holdfasts; here \code{saunders.exposed.tot} of package \pkg{untb}~\citep{hankin2007b}, is used.} of only~5903 individuals---a relatively small dataset in this context---the maximal element of~$K(D,A)$ is about~$1.435\times 10^{1165}$. The accuracy of package \pkg{Brobdingnag} in this context may be assessed by comparing it with that computed by \proglang{PARI/GP}~\citep{batut2000} with a working precision of~100 decimal places; the natural logs of the two values are~$2682.8725605988689$ and~$2682.87256059887$ respectively: identical to 14 significant figures. %Pari with 100 decimal places gives 2682.872560598868918515209515642292607616628612201118344882119616522539674163937533805390351760715777. % 2682.8725605988689 %and with R: 2682.87256059887 \section{Conclusions} The \pkg{Brobdingnag} package allows representation and manipulation of numbers larger than those covered by standard double precision arithmetic, although accuracy is eroded for very large numbers. This facility is useful in several contexts, including combinatorial computations such as encountered in theoretical modelling of biodiversity. \subsubsection*{Acknowledgments} I would like to acknowledge the many stimulating and helpful comments made by the \proglang{R}-help list over the years. \bibliography{brob} \end{document} Brobdingnag/inst/doc/Brobdingnag.pdf0000644000176200001440000030377314176571300017140 0ustar liggesusers%PDF-1.5 % 1 0 obj << /Type /ObjStm /Length 3163 /Filter /FlateDecode /N 53 /First 415 >> stream xZ[s۶~?oM5ANf|IlǗ8䁖hD:$g %uOo  '*$pΉ$D rH4 CF 1$') ?q0! %))I $W$ᇅkCf7'"ƌ)< "4 H}HjC+_$D{MC&hgHFPHN8# ab =':yqADa$ѡ LR4 A >1ځh . KN0WLpP %A1¤A,R?BI\Fh'#BiɞE7p"_w1~ݐWl6ɋQv#9IqT&Y1yssfGvqt_%0Zp(>'yq.,'Od'Ϯ&IzF7?4;&,&q #۬(qܕx҇?qI^ERNôOP.4~Ykb7%% ĩT_cnSRZi|l;v~t7K8`rg<:Nh'{pXiւygQ׶E6 ?/Qa70 u<%Lz8 l|>_jNtU]Nں#8V~mBD3<OJ)z˰ƭ\%|ːȆj5Vy&qPW֯wI+u67vhvX11e) pn`&)$pnoN4& YZ|MpNFGqz9\HTvDwOF,JYM'D:ΐ|UQKR,Kom,y}`,nɤE M 5u[ښM7jX:3-^Pl<l#@v}s!*9VL<6p+jۧV1%`M;ThxA.==ш^1g,kz}k LtFS,50&4-iy1-3:[)4),vj{&}r7$#i4dOYP@WxJ5a@\LJovYQ|3pi,/,Tز lɆ;dJCM׷2\: B㮴^Z h@kBibQx@2_ X{p T+m\l6@x@\ߏzYCTv/N{dLd-b` 8056 ߠ͝maX:jbWkgQ1` ']- >dS0P=5!$H @:3 [z ]mVF_N '** |ia8:k88q>;L+WVvvoܷw^gYdvL$*niݗy4x,Y;Ӛo)$,q SȥT4.Qnn:/ejj['=sx¨EZ {\$8VH5׷Vl Ŕ*E zbH6txsY=~bqbL Hrv* zx=+nO@@ha0CY/,ܱx=.eT6ZE)p@=;8>p$*o]^* {ʮ=wǠ\gؠQhxɴ~gMWC`mVB˧kPf,AZĕAL)_T]lㅊw 3|m45Bn#fM8;z~fi@Rt3!ɡ䀹Dc;Wn~7h^kJvw3TʘNa(h@Z|Q Uc.#\\cwa9Bnij= K[bİ "ܡjp|KbQ{ҵub#rtٯUÞO|$oOMJg<-# v| rV$'x>[zWz8_zK) 7#|S~)6sg18 6j޵'̝T%lɽ0!dў"{0iΥP0InqkQm'swPtOn>莿 W;uծNaVٓi~'c=^TjEp%wZjU ~owWp4UMbuſFywy׏0y0ikppoR-(*=]s԰"KLWжZ} uQVUq) am}\5T5 z1)o6` [n_|X-fM995bsN|l^6[ZZI%ZWˌMICLb5YfIMʽ-mspF,$Վ{y/vcAӈKRW F<$u6r_Tǜ <>I`cCx7%yz4f xh)3hO*30{f^"1@-c3hZ&h.2I1JP{֬L\)/xqP4t|p Ozd2'5(hĹ;;R< O!ՠ7/IӬ# z WWD@ZJZB4=Bm=9dEI,~ރ:ۺf7K=9f) ] +` ␾W/e-@IxY~CacB-? l 0@HCW3pR tܡmz> stream GPL Ghostscript 9.50 S4 methods, Brobdingnag, R 2022-02-03T10:08:16+13:00 2022-02-03T10:08:16+13:00 LaTeX with hyperref Introducing package BrobdingnagRobin K. S. Hankin endstream endobj 56 0 obj << /Type /ObjStm /Length 2670 /Filter /FlateDecode /N 52 /First 415 >> stream xZisFb%`07J$[)\(I!@G_q8H JK@wC_L̄LY)vJf|,aV -!BbBipt$8I`}N2fN1q)+} S9T:p pQ2틀>@f4Lư@AHLb0cbeƂOF ,(eaMʄdUf)` A$#w r %$ 'e`DB )<0`,Xq(Fჴ0w1~m҂}+lO?3Obb3~qE꼌 sycPuodj_$"f_fy~x]]'<_}ŒmXAO,eB@X5;q4mO-Sv,WZI [K̢j1_=V:O꠿$KgMdi~2%Y<9;f9+֛q^4_=z+ ͪy8 ,7Ǘq>#8[\34e%Q''њND:Yٚ^-4L7WE) "y*69}#Q>+o ?Vd~tAuk>NnanzNhܮg ? l8{>4,$1CCrgid6GFi ש~>?{}$oH!\UcAV-Yt{{jWcpo8k>S~mE߶.' E9orS{WAT<"rzzCK+PaNH1V/TnC?7Tw)e496HlGkpA y{geo~״IƦ_K= x!*iLeDK2%Yup,[8|?0/N]-OKoץ#V , ]We)Ta6ֆk rWΎ<*n˫lߔQ÷?DX7J+zt)uǏ,Cvn{|G`&ZEUk/7"Y-ց39 fU},>:^a)IUgOn`<҅I<;FhDO\tփ7N)I7n"I?4iViAzVفLBF,B#z sexWȤeoer|P`Km~8ms鴨mafVi [<|i#M٦mݎTIT0607 zk Ֆjg;^~O8l]6x-. T# *!7?TRC1k NjJUt[ͬN"f ha0Pw\Qh,'aP4}7;mDdD;6JsPa6i;[ݪw"W^HTzZ}-ܱ)h弾xi c5Di`_C#-362Itn) My҉JH1OA i:(k=s9%t)d>w 9I)?Uݣy~4CR鼑)W_H&hAJV2(aQ)0LJ`ʤ D(vx0D#}-D}<8; DwaHj#  ={~qzD)OgcA'XMgMULkiQ>TSn)PR]29uBwUEf*PnE7DɁ/d UIL 5:PW\Ğˣ/ca%8!}Z{2xUyJ~vus?/w50Bԯ% Th3K+)WB#Z,S;=<f2"Hme"UdQ2e,= ^ O:(.C(dSV388|qū)gih![uaa5|躏g3^͵{')YvYco3Fu$'$^~H^G:ݡ nQi>M}~bB-P >ۡOmIgЭN^R/|lMWWNMիkZYVl /:yfTg^Fɢq[gWI9 zߔT'a0@ytdI9U%²jO'MLy쪰6}:^kCzM6H+x[£-ѷ]K_A\endstream endobj 109 0 obj << /Filter /FlateDecode /Length 3182 >> stream xZM#I8dni.*3!bi0RMw;vW˽=yrgA}h++322Q~ll//~Ͱhw~pKnZ^ZG9I7˫9ʫÏicMcw+gZ/~4xvWQNnuiqs4wdx}x5ymw+GvYۦضԬvU\rmF[ǗkxÜҳM#b/`4?m Si-Ⴗ~V1Zw6v/1m*IqYbC6<'0\F+2,Ŋb~ uV+캻 G^{{?kZ.48ca{wgE1Y> IɓbҖ~o~ [rGDQomt[<,} !oK1NSn/^Cw} 7[smi4eMrU܄qEJ(n~ئX 3a ;oimZ8ox] 㩵=ZFby`>̗: n}#1`3ڙamjcbTD)c\77}m|]7:QN[ /O oIFtTRGsB[YxmaGO~3Hc2oB[ _ yTKA)crDeja~ufj"1W]yo)ؕ r%Q}4ol@,'?Z vqV2H\3HpWi__C~kSpΡ; *"@R1\T~c\ *{f 9&j9qJDR#=g#+o̊ $lٻ1䉜g]NLvJ< RwyƵ3tc}&oV*?`+d7,+)#k]9 &SA05;' n%}@IE"D]ʧMQے7E|5FZi,|Tcmz8Y3  Eh _}Յ$wjt.WiETR1SZ[#hRZ%t$9I% BzNz/H;nL2x8KS(axc6+ML ~/ j̄%}1K}g3X3&lj-pCW"e#  BT9KnWi~]PU 0Ea1 .~nA^]ΪH+&2t%ͶJDHP='$oKE-EG19AU*z٭io$c҈/us!_'N(_ṵkGflw]~²We0ˆ~?κ2hϻm]#7HPhCuP8+D  9U[ ;9W¸rSMY”$ 7.G2@2m/\ QhYaUQ#[rAq+C(/ViDiҏ @1ml4 oÎLAP)~YЧagDNgv;OnTK5P6sJesAhI6iqZ~\q]^dN!XiqNvN4`|ƄG"Ps-i;`'d)@JIz'$ 4ݲtOoq{N$lޢvlIOl`C O7œ?e/\nh"!_msVT ٹiX#z.v b5c m(;THѱ.g~W3Q~,zLAstp5vBQ X垊;?B YAZJNp@:2} o2bn5jTde41ʽ5Y_a3 | %cfE]xj(?qayZ5~|X)> )+mjO^e6A~(HymD(FY;T Tш1m-? ~\Q!s_Ԝ(`#VZNOcZf] i4 =JiY6{3ةTU, .ϴ\̜sc?  0_+4/Ф쁰wݙȓ-YN'<(|;v?BB/oBf MWA!r|hܽ~o_"2ɾ>Nʹٯh)MrK _-wzsح%LP0}URie/h R~RS%̀>ohP6%d(MqzU1|k9jQ*TW?)Vv.^~RڌoȿaͼQvDol{̂IUq|ҦMmCws<]+vkE_gY$ EՏjbHP~k9a^5~[F}7N*O/{m pkR{:乵d}(^7KR IBАIo!nwnz OQmpBwkX74v^&+Koendstream endobj 110 0 obj << /Filter /FlateDecode /Length 2724 >> stream xZY~zKkn'` 0`G8$Βό wWU7ns>HQUWi /ܟNmw۳Og.5{XߜbĢ4eYgL.?XcұNt8c}uwd᝔z7^qX\) .U:>K ewKJ=/e b˕7NK:,,م5>~ Yf q_H-9=`7g_H$^%b_R mn%n5-R(l [w "lS2,EJq[,VڰreczI i7˸J3`IJ#^l}}hc'P$1pv+H8^F{%+gC怓9)KpY쪹]+Wsyi,XZVpo9tn?qc4QH[Nw2~Fra{KO(p>&*jArf4"(S64j -̾^opp %,]*,c,kY%]pwDƹ~ր@]6rƈs!SaVYM%ƨܱ!rLQUv}biGKGh'X) @8a?@<5OD2h l:{Lj[L Ĥ#eQ'T;WC`yo7%6_?Ή{osxi⫆mB:4C2=9\%sHg!ԍ >O8kC~3稿0 {mP]nU; ӅCJrHjӵ9#IS~s H$> .ǻd) 1%LՎQɟ`e!K1hZ VB)Iك4pٮ/SFlNL!)NЭ$>P"OJAx1˩$j bdAY+IYQuGm%0#p&su;+"mdxysAM,ƨ)M=I;4{mY}3l7o/l9Ԣs cxL3[5J*lVOC̦8OˣO7ÇM zg^$~n{RRA`\` e;V P ab>"qĮ y iù8b9ܬT=*Bve,rfM Iw=[MxK„.gT{Z8sܿ2z Umte=Rq ݖOenB4FfWc+;ͼKp>sL8ؾhUQ$Y " uigl^kBYSD{p{PN,0Ω*b<./190xc '}( )WTZEe_YGf +aԁH>lq3o^ L/ըoAxu]MJpPiʰ?W'y8z}]R"yL+X/="\C-YX4]rr0~gn1)ŽZ`\m %'OgY=^7<)yio,=i`' ul8$pvB]JU'` Ncp),yjhJRvZ6iecɭkvWXOM9W zBleMTZujkaY~{t2,opUӇ_ҍsOn#vaR ;:Wn]ٌ*AxgRᗦԳO+Yúba~(: oNgk`/'QH9%9B N`WD kjbUWDIp$]5y@=4zM|}E*>0pf{}FioY6 M=#iU28Ulh<ȐvU2"56ƳFhS/UDҧ؍ =Б F77(E \_땰ol–0w[;endstream endobj 111 0 obj << /Filter /FlateDecode /Length 3653 >> stream xZKs1Q[|`b"~֦j;q+uHJrFL2gw=p$J.D3==1|/=7.[~<"{]|z#7g/_ũ|! m^o.ovWKV3͕jo+)EUe?U͘ CWᵬWmᇶxoP%)_Uryx9dy%uQnBj%kwfrj jXw%儇u˕HVR]rO^2f8]3+y'Řhni9O@9S]JWYHB6`A%*7,ƅ9AՕ~3ڧ-0]5tv}XU{]y6;<^5R{+dJ)ؠ3Ӧjndi\֠EPq0Q$S{9JFZ wv'8&`mԖܭhϓ賰yi57m&5WoBcZi#9Mm:Zö})9$AY01]x0aQf$LU[v%P4`>DAˊp.y"+MJidPtVY+2yâ0:ʴAQZ]'DO: bMuUz|>Q0!JlT!%-^K FQ#G84g&5 n y (!!`14*wYmgܘRQ)Y ٷDszi@l ՏWP5qsh󴦚y{QhCO>]h<{ @cҏFm)$y ~kNtd~,j$Ya0.IEI>%UMq޼U3WX"lS:[zIxwf8F@aGl  "vI[b֧mL)ZH 8deu\#u?e{th8 7O!0`yо+m MALMI.D`w"tg1gI)Eî](/Ž`EHCPG0E`c/p밇<|䂰zE&7a"e %.%<=@?I49&B;A8-&[i' NR(bD=ˋHk !Ё*R^'>LX guQA4 C fY9tz]Z&{' ~1<!kץڏ*& `+`.#<":w jk<6λ ưx C0`- a +(+s5,#dmKP!c>V ##r&N֩Bn0 n:g#m:Uy赌m5?NB,MmټK:J ( );myǠ0`J āȽ>BUbA "Ӌ|KZHn)gkB@(hk0NZ I`6x$ gV.-N z^{9ǎ)Lګ;zf~`9J(m44h:H3.bҌ12$G,^۷lٔ8OQ:7I0&trȘ殫Q2ljS 1J@\v Y&DCpRx*hKB9 mD I"NkL*kQT1ű6UJ_MSj8;^B0^6JiIܚimȲ䛺UeA_|ݶYe6_ohJv`=">>MY-ȹ`Nni'ge@٨o'y&yl6&rq3m<GpK<\a3-6eEݥyD wCfkrr!UysNTK'‘ f*^ z6¢W9G 3[;f~?/dNh؂ZM+ 3M,2q(؜[<)(OrR8؈0Y1QPgCY7:/'[`PBx:E=$CM|J| o :䲹(k+Gijh (j!$  ?ds g^yh`er|W AY}ͨl=ԹG'Aq4t7vE\~&oS1\I[lD͏ bszUlWYq,'㰩:e=D+TZL+R(C˩e\7htōtSLҞQstt"IjnJj%iSUWݫ}] HJX h y $,A$!&`Zn "w5~@=(&Xp=Q&ǍR5_\[N2_SJBendstream endobj 112 0 obj << /Filter /FlateDecode /Length 4509 >> stream x[ϗ۶~=ԃn,.pO&ί&M+YX$Zo`I037U%U/;;`fΪg׻Kh%Rʱ3ߕ,eJ'rwVOV4{\.^[^:y/RNTBQVLۺ]W۲Lws \s( KCZf5 1sf˯HMr%Y\L&qOiP}ۀ%.SSS Su5I^ Jri<\> |6Wd,3'՛NMs?h Qh5[UZs٪M8xMъiyBfj7]t߳.O.kc;&yrU793ūtش}:e>~QNZG\/~8f鈃3UpBJ;3u 5KXH[q^۸ihҙm?iU0|`Ұg+ex9.^P=Emֶ7)~9`TݮnaP3k_Sx/9gHfECI1wt;7ޣp#CNňbWl4.G F6^ >\)|| 3+_  {㕒aa@:*auѤ&k * NV^0B)Tb9-T;ߝX)mX\)Va83po39)IuQRB#'˛LB@^/,m^G|1R"rt[g8qM!||x:7gK;"exŝ|B"6څ YnXn"{81XE2qIL2fn.[SiT9Zّi/&F1fY+@~:MvMl } OnD%ǂ41C&L[VJPuQs*]ώ"Q668:֋7z  O ]m P/xUU)&%|(m+Dr.R9/ ]ʻFzgSn"󟥅D\Ud!Ong<jk+ ٰ1Xj+%yڶYwslɁ{XܸPp .^+d^]q@k'Uh4,Er|! /䆨7;>`<ޒ׉)& ͲXw34zCBXr:Hi L<&-b2|6nx})>Ezy`eXsiȖq@"M~]%UU8f|*5{*:3=YA2mK`T@\(!SJ_)+Nq ]JA &`ekTqуߞ^)W1ء,'$!X>c ;_}w0le,Nrf&PqZTA#Gt'Th hv=,"#eaxY pQ-(r9(44+ IA+*7 yWVa * [?휁$n:/[ '~-d-3t}Gz}Ґ#́ʛa0ua0H[4^ ^,yQM h{=0図?nȱ9 ; quJ$yR5V̘Wc*W&&g[q=>+zs6]<-=վ3i 5)>8XG+Xoqe:&DŸ2Bsk6(q4^B4{3@]ߴNYs`C8]Z ,ț>땦\=;K)_"kǸ%_C Ov;%AcA:ȓI <+nBȎ(Z0(BanH [D2qС.H*{Nu܋Or[nZbp/#~;hʪn *ȕك>#[PR7 ~qP͏S$rp#p$c{\[2$1i&n'/\N&y$dR! T9c+7RNŒ 4Ԕ!t2bt85I^oCyy=7 Hk WoRjWUBy0.5,U5sœL-! ӣ\uZ*^> Y`N78qQe[e_^ͽ;0'` .MX7]YU׹ѾB_TM-V‰h)ﲸnJ ՛fIlt(ҖAjXganp$.j Ia|XL_5RbW|Aq̿؃4Y|G6w,t%(}cΖ?  |SF8V8Sɩm9gп)q!\s)p{,&"d%Ho,t:Im}8#b(@D,Mi\W%3gM>=?/oZ.Sx7nU.WI/\I_ H*$ߌ<=taaEqv%ٔȉ>3J,4O0AM]9D\jK.6(R@j{̧,X|/S(Zh%T~P3n8tg5rfN7R)l?|FKԓ'L*Ha.8KGLuۃRp%>Ř8b x9dxQ`lBSO%K" (-=q PK Cǒw,ė' i$ׯGSXV3 r97 °܋|Qw,p@ PzS7rZZp16B̩ؠܵ{:bR9#~P%$WXj4=BG];cu-'oY H?hNez8 EJ#\y̻#PH䚦2JL$Ĝ{lJ_gXxǷ=X"?Մ|Ǽ>Z.|PG)#?6)=\1PciͶYoHRB! i79}F.Y# I!=a?;p)s->8JP0#/!QlNk}š szm+c(*pN?dv3҉M&£/p,T.=.&Xm`y!Z$`;N+)SȇH~ WIēnF<5xgգ *Ac*mB<3v,w|W2aATygtɏs.Z=UǷ>1ߊ~PL 'Se4| 2:Qp!8G:#6_B*꾛Z~.KrGBpqt2* #K?/ > mG3s7.1^\<2 m~Z]eӮϗ㷉Wd/bwL٫$m^5:\D{+/"hHۛaܰSSD]4e'n㍾ZbL\*etxC Wݬr|zT:hD* h<0\$(z狻-f P6E;ly~vV~&)9J.OȠMm"Cyy<7Cqf!8J3ü~ٞ:`/02#{r~SxVK O=,1zA^YH( {nUreN;J]ot<%g<8:` CxFw|[w=ho65ä8-gu~ A^~mղ~b% YIw`f0!u#NpN/л@L /4Uq+tPpہ-! p͙W2I\)## Ug$t% nm?aMvendstream endobj 113 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3917 >> stream xW TTW}eQhx)+ 5866q8GSU 2(BLUAA& H#jb1Fj̠&W- iׅ߫Z:s(BpRf} cf#^ P%O}TC3uYTpVÙ]M 8W a EPH,㖄аm ~~njS̱ Ƹp>*X;좱wqbv1Jk Gn7j.4P;g#0>3Dl}~A!aCpƀХ+6?a⤩ c3 d1˙ f3ͬbf12o3f3Ld3"f23qexEFx)_2(X:2X0!j+Q^s  Aa.C\&lu78!>/(r $y]M͒n2sFZy⑶ƬL\N}A-\*3'!E9`vV?&~1:u ~3G.aR@-C!VӯV61FaL,I -g)S0^s =;1%L!&0&~qPK:wv8H_O޶@1pU`1Ysg'M_p$fG]QdN26>桳;?Dc4(KVElN|={elC|EF|g\U0_l?Y!hWlOG?!kdVtxh&j yLޠqTȓp>ˏD(2`QSc;pLQ;tTC?W4_ƝH5оWf8pA"h> ̛m!*k͐(df2BLFqC7d\hMm=Į\XeZw YD²Vo҃¡ag < iGX \D ]#ty"çUA`X=bD-Ҡӣ+vOHX&)=&z(oIrc2k!.-DY9cRFnbٿ^ֱu'D{ IN<Tm=gztGEi",o#JuLYsV=o,_OT_[=U"OIyDvw܅j~t tEtl!zyWCmut{N͕T%,̆R0?$ uie;[A5wXqK&+_vȯ ꊽP) 39!]_i~=)[.03rM.=)I%x`*WT.xJּASVBP ga{Us[ !֬ 4 h}@OvK:TRܤ,:гh_/g(HTY4rRIm96rE?ɻ^ka3=CTx:uSI+$dK>^:*`M!vYj{{@ygMwЗQҘפDؾӒO{ڼp~؇Yc?Pʗd_Ć3eбIYY, ${ȋX:+c(FJߌ]Qɞ"gC&$)Ϛ]_ ͜-bsdLln~>oދ"gQpoR4SݙJ9R RvZ,BZ#ހOFwt?ol!QSѼm-',8|YeG_1_vY^z]^Ο6|"ђW~z=UnkX~ʤP/2DYl8w> z{)S:|jW;$wZ҅Ů|-uN3jƙn#>F+L!`9;.O\X7Ť/ڶOBz̍oE DOn7h_sPbo_|Ք\(֕VfeP?thy@BFiւ$L+'O•o"%C6s?k%#*hd[Gm$"8k۝/s-iI!cUd@ڧw]' lW pHQ~F| `E'+ևS:.CG8wm~4c5,M9S2zqu|>^ȝF7i@޴g~E{-5B  G"5ZH[= vO)5{DQC6x̺ o !',NzJZ%%Uн]eu5(6ٿK<t8Ѷۋ͕ꌰ8L$b=-X 'WgW }55dx~?U CpDbQ$_+'3ǴcqaQl5F %[\;3=j Od[)tkҋ+%d_e"~ݐ/8oT_afQ{Ql#DR\*4oyFnNE!< vS p2vy}OST$u5:Dup*+g)BA?{-Uk̨םԷoܹ|8 _3'b9% 5Z}eT:~g}=#(jmji0"[Zl vm',tt1NPc*b!X@0^W~:Zq=DԱª"zvHsRbFΊM HLٝ6  SSpB嗗;oxըWHU M'"+"s֓?>}ִ :l&q)`l_;b[+o2A@DDLrߑq3wcD$SjyU)G m.Cpw̵qkVs9g4gAdr;ЮFxe:&L켜#EcQuOҏ{?+TӸJ4 ](y[cɍN0Cb@ztxN?P2<?@- `soyEr+s\; ݧ҆aM`wԓ֮<ڵ ؔI|:5A\[97m9"MUg}8IE%@ӭ" q?.ٚ> stream xm{PTޫ’pY)v"Tf+cY^ "%oȮHZ `k"qjک:ZLj;kػi;s>=2Bd2wbLoe s G&+@w?{鶒xT V]?e2E,Č\&۞Sf-4dh7_ ?զhCɩ٦"sv6٘ n1Iڵ&6E5k;1ڈѱ? e~a 5 S l%I4FbI' $p$JyJ ,Uv% yj7?+"Ѧ|j-;qdz | jsrav0sO яk'Op ]ڱ{7~Q{x7@'UpĂwi86Ly;QIM/jUpܤT8, NXz TìRp]vZ*h+zl4pU2Uh}y9\qjyݬl/,KK/0@:,`FAKMs`lƦ,H34AUvQ&d;H{AF II{DÝtZwWB9'G99c=4,.U ^Nv>Scy sűzjOei'vp;TsUw nnَo^c~@P|b-:xgxh{Z|o]c`#4Dc_=731z V8P$ИR01.u>Eo;n&xtUvJs3yg)N]b. }fq ^B_iJĮR}if9]OvO8mrv8cnշfA,J\J$lCyT-2I4IM5K_]K}sO>Ia7Wnb(H7%q,LI&vm`F^:wێ`!ߎ/ Aȣ\͹D\/M)5Tfyr:ugɇzD;u@Z`9r}佊w]cЧ3H6E^M^cZV\=f/AǷn_-kѴ6ԵUU? el~g`g)&S-6> stream xYXT׶>cC829%{I4 vE@^D`(ì:t`DI4FQcnbIL>y}ƛ{{}s{_ ejBI$}Əc$^/XK&;RWlxn7{=g;RS =MO BXFPRdg\Ƞm!6ƍ8f ?%fXήl,lrprqp?7OgwwUnkm>wY`oa?m_77`^A, ]8yIHe۷.ws_ikj5#F qO8ir)SM3nQ`ʎB>R+w){=ʁFSj55ZCRs:j.5ZOͣR8j5ZH-&RIj2B-R˩iTw'K(sʟM,Qr?NYR ʄP@jM]҃#gFR I䡉}2sfSZenYTtM}Fz9':e>HoU}Isﲾg-S9a',[ηܯadՀ Y \1mw߹e+Ye j@>AwKORz}A77LYwLᾲ)JTVЬֱ FU)3Jjw7~^^H,}Qr2Np* 8C#4É}}7jKX nLIx {Of#iWm`ڠ[ #UdOex: zH*Lflܟ[L@T554j>HݬD4rD6?ZVkӨPm /9\)mِuKClc 0](::$JhS2% C :[ƵGFÓD)xAJ(;WhQ+-^\Aw,>B1#vSl:)4LP[2Nv׬15 ?5΢ӢZ +ǽ>jVEJL=j}Dl&ߧwy&m[ȑ=FDf  G+Fy_0uIMwP\ =:o0! >*]wPPW˻BNnbj\.~Hdq!jZ/x3tKޑ1Qw:i_GSIhTRfrA <6dM+Jҏs(+Qqlg$7%ve\@Bd*e(Ԭk|^%k5yq=KF:-s<n搉ʷ)̰Fۦ4*XWz96<:;'zG |AhH%$.lwl7+culwڏ%ޣ~8Qd.cGtBSFBC!ȱJʨ/XB.BYP;';csf:g:,̃3LCU=d6GsɃY1&9.>YV;ј-t,U֨?fQst9&OL $F*9i:]I ׃d~m^H$yݎ@ ʧ~hP+XWa_w<;cg4 ODoUݥ Ld(95r}x4+|E}䧃VѶn "hUeRL;fD2JV{x%^ѮN#qn*F} yjlf;Xc1! /k TႷө*?ģO뺻~qXH LM>xc{oiӛ#0>B-7&nJ>{@z+zC\ VY+2j(kfkDIJÄyI-҄8!)~$֯&mND@|Jr]NVUPL*hU竷/B: HOrgVj6D7YE{/%%P# SGdjxdLeQB\ P~1Vs`5,3 ;XΪFR%;/t[kv~~NI.FXAE@@%|/)n9tJB bZc$Rb,pTkuu3Hh|3&(LɎISfDLIѨ4)^Xz# "-ڐ "OO5*~M*UDoG1.<*|xhQw^N'F ?@ Rqh# Ѵy]`߸ȷt{UMqiUnR&pN0Ootj>,-h 81A/sc縦V;.;xTFݶyKÑwt۹7BhapA"GYtmmzCT\\B")еg*ΥL"\V[!ԛN?Il; &Βyd GԇVsU|cKAC _Xёm6e)1Qcf*f/t+((*1l9iJu"-N{)+6AF +W*=5 PCb^0֟aLU^a]|-jHͤ ЬݙbJUηFJ;HO .5)ܲ12CWN!-?Tҍ BZ}VN)v~|ܼa7GEpT(f %)l>u2Cc`[\5#P J2j$|Dxލ&Vzivһ G5z+:a?bYr6[%=ßn'-L6%)=U`)2&g̫jңC$|O4]Zbo$b>5LUDaHxhV#[Nd磌T."I ) ۼwskB݁-Ms'Zws]Eѿ KYip7Qe, sG>(h5:-D0%":-IMU +bu `!D)s5|М65rI)sxu3\FɌ({Po#I`IKшy*;;mZhK#9ڂGn1^I؅xQh" ͗bGQ>E}v;4d?kҀ&4JGIQ[[oy{ꏧaz_t_"!>C$pɑ1ĄWVpU"o#mZd}_$ͤQOD}L9F 9c0;24Gإٟ_^X<M|ٗ,"غNjgŪzggC?r2U)cvDz'v۽+3*dzfCѵ5ꚕHyPGUyQi\Tl՘VLtR*9I쒌rÔ;bC]ʫuuJ*7fw0,DL{ng!S|==WF_ ]E?^e_ہ?q#:y@ι-<rbT<#`=$!"U%+nOXvo{<M/հmBX -n {ԣz͢5J*LHɕA9 Z(!2M$s)ӊ$/,lxӚfOcODٌ714@C.X%,PsWiM%y6GucGdpKHv 2QvJ)`\}GN.h@6[a.;]w g4<qJd }WEA[$+ {tUN:z"%4!9[c=h׆M!iik `hi JШSxI{;zu~GZ{*;fɞ1+Ў4M>-- *k?;T?;pۉnl~c8M?v1Tz҆ O (~lɮ}@7G lIjKH+$F($!FN:ܝg"RPƏXn' *[o>%&庣m C!.A i A{zEΫ ; 9wOnpى)rGEVdM ١ޓ?F@JIx"`,wR`Xb4:59=g=E&H wN۳, ]ރ.K=1K# u^%Az:: GECDi)s%P|>hG@8}ývrZJc(m0EѢoEf2=v6ƅr.)jbbJ w]j;X%e*@1.J\ґexvr|!AR䤓_ nq  , h,O3;mTZHfӒrܛa%ayiu2huz+|`,qw̼r%燯|[j㓣 "3wd#HrPՒ .^I?!Yxrc{r(%0/$^HѪ ?`?ڊZ<jlS%wP]í[_liz3@f‡0;u|ˬ\? '૲}?]I _3rDmŠȟTKp9D eV%Ȓ0 jP; 0?M4)3tCeK&8$(%si/ ;wֽ((1Gp7~-7ޒ})89[KMtۑT/x! xfdoaslf#`(jmLH+D`t% |nƪexRV.hh5-GP)Ac H{ ͒7ݮ>sv{QͲeKG6?|9cSV:)}7li)MBʀ"nvӂx|?-z*x#fJIu@B(5r~ \63T2Ill0#w;z/:bE&OFAOkŒp#OLy,~}gڰ%ӃCkh)S'YWKפ%*nה _y6el,K0$?AB#!!?CoHOr N|ǠrSfd~+=.9x{&Roo?˰gk mu}QeEJhMJL1Hd_~B,GR#ME'?+(N'FQב>:;qeN}"W;V<ց0{*-Z"ۇ-v™-rN KUďi800 ҋknߠۡKl0銘fv&"'׮_Z3+kmg>y;g.}{CgDVh|tb%#*|bmfXN]i+| 43oT˿|@:ڔ/_q=͠.C }Ą?X-tMʑ4vTp<4?ɺ FR@4x)l7َWCIe6] :kGƊϽ@;S ^VsѪ0Z \&#)5I5mnWyoCqu=%.N>HEh%1FsPo7{ 0[Mb9Ilv8TChtyvf 1dpYƴ7zrX䖜5933k0o]Y7J:On NtVN/}D{\Hs:`nT/]`86k֔`ܨ$} I՜yQ[rҍ2\wUzv=: pgC>`0EQnendstream endobj 116 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1406 >> stream x]yPSW_$D$y ԗ0"ZSQdl!l B$& `dRQZT@+q,0ώ O3|3w 36h4k81\bs(!8Ŭ1334c9]'Ao1>w,U3k@t}6_;qÞņlqG*;umAZtSneHe'omq *Rg0 0UO 0QX8hR=}Bf6&)v1~j?f 2;RhW>+ ɞ73h=3^f+.Ѡ?s in,\7@KEC[qf@P,7::_>zGul*/6[FQ y2!erOtQDzMNW>q`l541N;ue֟il?sQ`ngg$ r 0} *In ыQ-?!yN}u|8#n 1ˉ7爫'LzH+ G\9$5!$]t1-DJVl&Z s7trb*֛=3z4uigYK[64qnKtuo)$gtXUG Ee J()R~<剒"LzmCCȩʘ!qXZbdBx·;8#WhjΞoKs8:"&kdɛgzQD[=IH2cKAU}` c/h]kUЩP CbA'3j6zՉQ˩TU;^D ˯vB< 9aҘ!0,J=hŧz ϑ@|p̀֟CuIA:.ad`ȁ[k{q"z=ݨͫ/z։7pK𵡌}ESc O QQeJE[mJ?9\[On7<>0CK\*tktWv"N>l1s)EmJ TYCUj%4VK4#Kjj4S֠YV7tI5Ck643M)**<^onQ'NjN/İGendstream endobj 117 0 obj << /Filter /FlateDecode /Length 228 >> stream x]10E{7 R4 4^qeB[^s8O9-sEǔQ)+S j2ξ> j:۶V>R'|E5C0O~ucւ` MҖutdEHۂ` M58q8u v{H$qTO1D@ 3>q7*txԊy %e̅4^sendstream endobj 118 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2069 >> stream xkpWmbV"!4&8ehyS9wySYY!.ELv lW$d.0}y9>:-FK0@p~X)}ݺ_%&FintZ鞜RD#ϗYVO7KrinAqBP^pH4֬߻oRW$mf { ۏұmػX&ۃcX_?#D)G/*b;-F 3٪E>=4$"X\zMzyYTMD? R};[g^0>w&qk pATZ=t3g8C:/C2YƢLt?&eԡ-$bKa&Z)1ÀÒ_(Ŀݞtx01(uD{,iI ^F= ÍrGȝ1ڷqc~+z4,62}#N\*;nqIIx\CP3{4TK{61I+5Go #YQ@.ԩ kwΑwCH: vh5z4Q;,:[{;ǛoMAEPD_PucQ&w\ VM$+=^xxZ:O^FjyD”}? K7x4[XC{ύ7Oiaܴvr5UWRPEA>STF岑c-Ԗ)Me܄.{o$wn"7(NC̗6XIZ 3P.'˴( A89_>%lA ,\X<^G(Q +~~,_IeZVB&YU x~}^y*x$脓 zkt PR2Uι=vrٍu 9)Y\&PBMKڭ)(=::wch¡)Dr+կ{3^QŌ p/ nr櫁jEϦHGSV[2q@!Օn$&MmtX} 0DChbob!.87#CzƔF.w;\9}'Y3jF=9M.jm2[VshÃ>?z;= _m_uuhg~sĈVr!ȍAz ]򒹌}~Hpw Ĉru3!<51lk?;j:kȿ`vIAG:na~O8'=6(1XdS1W4Ƞ?2P|> stream xXXWמG ؕFD@AAFge)^{REرD,i$&1cc3wY3w==9w%J"߰A*[d_d\p8M"0A|Q/GuHMvv|d &X_~b9na)'lG,[p!/mlk?H =`nC lBm >d#;d}pf/O/575=S)T<<"RܷC~A!s휿{+v/yu;CQө[&ʋ6S[m3ZE\W(Wj rP:j= (#jeLAP)SʌES,CM8j*eAYRV55zH-!RT%JK:'̝P7S/U hkZF?J0s'NXebx%F?7 L$7zd M5|'Vw)mSp06Br6>zbz*2J "Q“z˔`bQAyO/ٟ۳+ TO}RVp:e)k~w9ʏ ,Ԁ}mډWx~ۺQ)igzi'qr܌/**0'`=0ٗ&E b뫏E#5Ԫ=`ơ?0T24M9ziʐ<^9fl~O$x1С@]^e|FmfYbQB'EjUo9w9#|hw{3s?0'*7ХR^ZBN:]_-Jxݹũ!~xuo- W`ĒN# >p_@V.9 W˳T vuj7 \TKaSO,gr(R:: v| lM8}3%@"c>S[A.#RyIx(?"/:Jj-Uy.ڋ'槖ԢrԋoeGγa0n/h [)V (7 /`_D! Um%*T TO.Kg$כuY9ǧ5SxQ [Rmw03_؁aevXiD}4K9'##{#:"8zWVbL7a#:tC<isH'  `l a Nkew`,$7 óBZz 鉇@µlE儘en}{ 0m"P~g K3?<Z=ab}1ؾz/If`"Pz^Ɠ: 8<_ 9\GW޹~%/3D3O5?~'p7^GU~1r0$U˧1)`2'lr3K7Ui7捐הO Մ]lfRbh5);7' ͳTYi W;.[XX b+% f$Y/}S`yF_v$ȷqb\TRsP:JdII9VeG; bGԑPޜ_*<ܔVvz=[7̳\=};'wm˜wlSkKt1C`M[/=ۡ i|5DHAjNH}(F^S2}~o!]ƱbՁd (kQH]PMH[Ql~Mv*f~ks9LT;GDrh1IȐa& .6rm2YdLب#RM!ŅX pv"yS-Q :`0PCi ٔ7B}0˳ST⓿5K/#^kk`l/sa LAϸv ^/ M1 c\cd;_П#{ޒ*Jmڡ0s#/׺dv 9/7vJF{pxLL r!A:ºtvj##k6WWLKHtMA(**/r-V!TlGԷ zp`'`7߰9=λqx;6\ a|έx6?Fy+.WVu^լ0L}vOmC~D[X]vk]^wvk>8R ge{f!hs?K?_\k7΅ EiV#")7R(" ݁A"SN+et8IP`%eJF &$LmB @;wrXN~3!ЩjC P'?aC=ixqF:i4/(-t^#?ꍯ_--GTGŅGw& ,'U sbl^2'lχEI䕎ZEkK}MG;HF[I'<$?}شs~OnmF |qy~ixTUѣNF @JWDG{P]54va'0(/^X԰I㭁&o:6}~ݩ#gU{xcԺ}y{8yn̳ \8ٽ; m˞g=4k7}|uB/TV߶`@ i`Y*bpRM>3 ?UTu~AA!a䊘դ$4O9͞[>큏NE(HF3]Ju2ncR.r.87K bTgդ,MI}?%=!)YAʔyuMƉm3˱W >8`muYQ>b3B^lKE={Ah-/LUe,VjxC}oDdltP}4TtO]jendstream endobj 120 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3592 >> stream xuW TTW}V GI$*j4HL !N𣢀sDd&C1ϣhZ E;1;Y:ߗ[@[u=>xxwE 6'f;?YĉxLYl\}kY+$Y3WrjwFz/8rY80pɂwBaq)9)I{_!#,&dOM矱?2~Tk7o "EQ/ddfe/!)u _ ,Z\+(j#"Nm6ST$EmB;*j5ZK¨NyRoQ^tʛEP MԳTE;j \r)>oD =왋rzt}##G:?;j@X(WV.t԰B[h,CԩPt a1?)`:ƽڛt,:,T K(m^N3AbǎWɌs64(TvJ ?)|xb-__F.|\oA> tap6a{`٥p NIl;zŎ8qd;w(I;Zx' ; KTK?]6hFI #"l`{X~] b53jբ7!nQ񖝳~z: vphX%gDA9NwpLQԚ$JM*>g_,LR$o#)Cm40wNv'hN BwH ؾ}{Ќ _) 4źo21]hlVw-Yg.&˓O#DžR"W!hHSVoz$ cGR+ -6ZSq9|Ui,mblqzSG䀪XӲ U_W,oQI]U]z6j Ś|hZ؆2\]ܛ@G >F} phtyi ?Bmn7cpd0u)-(;7 ݇Z ˱ 7+Tj%YPNkTU *fCd38Z `vd>Ȇ!}4p\w@MTBBjrűdchPC~?;f&eӏvhv2ic2FK(vc:V8 s,wd=C8Kq牏IŐ B^ydd8 ]#>)Ľ\k](wZТ/~06;ƭqg'd=G< yDHAE$[+J2w `~c$8::ڡC׌р!ϔ.B>?&ryEk:*>!ۜěgǀt .>DgXẄ́$Ň)35!3!_R v^ݫK#8!?;@4ɉ'/^rMYAڶyC htRM`jB? 9bE3C3H(B,\.7 :G|<p6[Ҥ67-"ǚ;+/N We*y,`N=.A"1 ?i̺at<)`fU)􂟮ܸw=֔ ϣ?[]h\LS\]P")SAѲZY6?yBmːĮ.ZVuЫ (AJ_V'3ˣ&SJ3aEkvS^٪Bt ؕB$:E3b=4%BX3#mU0JRSI䃌|3i!/> stream x TTg_QTKz!hb<.qk ,*EohT(JX"ĎK$ts0c3=_!Fӧ3y{{߽Cxzw䨔`qTd钷DRqTRƏ`^Cx67xqspe>wRBg\g_rަԴ%KX-*pjvDXmw,ߙo&/HM%DS> 5hWK)i@QDĊC&]nbL%BD(@,"6a{fb H,'oۉJb'1#L''q+e\3s'_4{RINL?}bF^fR3-ޡ2w7KAFϗr0-/] Lt >ve)5{ B"cwTa_נDQFGp9#q5fW C7<駪}XjXWY0&$pW34Αo4De|QHJDrxX~Ǒs9g.[:JJ]g}8gKZYYG)" uENv?k䃻]_j63xkj'mXHc+QU`QGДfDzo%=4܈J y!ck;/e3W1P}zcM'l/#,Q~vG}K39sKzS$V`4y@_ϣJËY~تiSp4S6, h `itR*]Z*8Qniq[K'NC5j5p^d4۶O,¥j1YdЛX/cu@ 2Z^$5FC>XL(O6Puo6ȕ6Й t M 5: ̠VݎΨ4ny=Z]h{zwV_WKmDcht6Ɖ%DFk|"^F*?6eu}N]]%NjP-Սx|8_x2Ta} t|f#H4∯ WDzB߅ ~brD2^-_t&_%0~'> 7 Ggq!Gǟx*N q}ɜ ^SxT'i|[޽5`:o')"dMiE@_Ʈ+K9sqHs4xArׂnRݓrmnT`[XXX-O*T@%_ tn&u!w>T^.- .ܓt[R:*XP*2Qcn0C!}k{z/6ۧ٬ٚLNLܧ )3>S'ΓԆMMy?|v]'%ABҏ/E-Xx UcA`AB $9K!+}w84! x$tH'+,Rg_?Mh!4uJ 2Z nVww~S'栨h]c~xH&9L<]) q]iȤu9FcUA_axZ=В^)V)ݶ̺DQΪoD|ߪN3g .6Y'z¥UgBV!c:a rjt&0NIX}eMG'8 {c|4 Uʝ!.dI_EGG}46yWYӛT:}EɗbhPV(Z _(PXshD+G蚰ދȓٍf¶kPzD;;}2#/C3~х>rg;6a/pы3uOG'e?xV,5N^ Xć"_Hm H $u8 Fa6>]2TrY~L épk.h59OIv\STnUKCBs^m#`_ܧ'Ǎ}y \7\E\c5h[A}<마uEAkj}waxw#})OY 0V*[ &ָho1Rv#+??3ID*c0'6ɾۋt@}7-$%6;2pЋMy.sdiK=p{kKgQ\QG VɵPc-Ɇ@sI}߱p:0:u>rvhӶht"!!#UJNo6o4Oԅ6л.U.sT-55,pOʯ]|PhINi{UCJRVW$f4%^,,y;J+S>mP4)qts2IގM+!5Ga%WbLU"{p-j;7$O$~pV!)NJ@Q۰/ub@ )hΠ4\*^;cp5 pT H*dx` EΊʧ{$Qˏ?}5XCk䨏Lc4ꚴ6s6mz?<<7!w8\Y玟j(襉21i*t4}w7Ca?]"7Y5ꪟR7=vc\th@`nʮK񗚩JQd6VI 1?F~ !ͩg:M(fq]Ggf޽^/ ^o RWj4L_endstream endobj 122 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 357 >> stream xcd`ab`dd N+64O,,M f!CgO/VY~'YH1nnC}O=J1<=9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C5Н3000103012_*ÂO|qwaW[ߙV޽4w~+wsne׋!۹Y}} 5.v*T];G҅?|_8{! 'r\,!!<<܇zl^}?20b1endstream endobj 123 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1468 >> stream xmTkLSgJ9gGETGYQˀi"jP.ҋl Cں  `+7/uM7즋4sKc>w˒-~|}H`d?HN5oQǮ'R&F@3=Kb&1N ^ Ar ,{ǡe nK2ڼ֢|avՌgJ{*Mjq*Ika5&*).9N¼C4&FYWպu5iie+פZ$0-65Zd I!id1I d9I"#I )p 8/p;EN>lސ'Ȇ7ŋ}R,65"Vi+lHYCP6bZ3w8w1| [.*¡33$NFj|-x  ŰhD(a|hٳEBhuۡ[Mé?i=fm/,D?fbb> v/%`RgAB!ۦҼo'Yl(VH<` /"Ms'^xB;NNxH'@5BY ?*5úvqVz|q];T/4v53irrL.뚟!HQ- WVwC&dZrK*4=`n:*q($%f'pÇܮ?̰xɮq ؽ$J<"8[+*2gt WoصO[ՀkG @\ tNJ/,={<(,pl+ԃG% ,-0v{aN^yCr*0t@ 0^#^|cgݦ2HMv ˬ'xQ _c  =Q $78a,[J=Zwr|9l; /tX:wNy-_T[|B7%d!70?-KDdW|ah֣qZ@AGe|sʡz;mp~ak0YګnOU_-}K*iH3{q#3MC> qj/hMF .%65dݮ.;J֟-lߓj=G#rbUvvp2[}wU%Í\*X]}{8^0ƢeKX Kv"^vv:I._u?-صuS >_{,4',},Y!y"> stream x]PK s nU6iM^£aQJhkL2̛5nGZMi\A<)8=o Y*TxTvw5{GOң)( QH͹5٭THI]%ĤJ"<_$y5R~+񊼼0 _endstream endobj 125 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1209 >> stream xm[lSu恕&5sND#Lň0] hnkݵiwz[]ck7:.ĠbD@.ė{|?Xv3{Q.ݾA(nyy1OoJW-sGs %oސًFH`W7vT:Z 2 Rq[fk))bJRU!guLiQYOٖ &e3#O0Le!bWyN*6/B Þz[.x}=`Rl[X6wfY~BJ؈LA I\T1@W+pAs:AVVAm0.$nS( :DFXb0GQVwttX` P_.d Di8r yw.sgm̉4gIQFJ+۫DCi)os7qc3vhzgxߴ]w_w`C#g#A˄wW@jf>=vN~~ifȯ%F{f6Ԁ|,,~'C"ˀ{=bvPmWdklf|JO™ُ@8ꏙu`'Cݱ약'jOi(buTk=>?B:Ջ @U6k{/W5jEawDfM}%NS#s@"*Z"oR74-u jͭMxrl>fD"h&|)zԽ@<4COgm n=T$MivMjj8UDn1EG7,!bTƧӥL&IN!uU%R'5XAbnwukNN_Q-'Y94(A03=0%,tJy IKr ^)zAk<0`N .FIW8D^Dz~wx/ϣ< ~9 ?@]N+c*EYNOR )> stream xcd`ab`dd N+64uIf!CO/VY~'YHnnC }=D1<%9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C5P0000103012_i eO_^Pw*ˋ T\)S^m. =wnw6/ i^O mӺvKc?{oi~}/.cA<_qsg.a][9\Ğ{z{&>&202*endstream endobj 127 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1517 >> stream xU{LSgO)=(P sL9.^6vGQbKDW V&2X|KDm(9Slܒ]̮1!;$ےK{x=T*՜u̻% ]y39R%GP=}u:U3bvKr-!|C[`JRmnZe./&$,Ug'5-є'['-ʰ@1Ĝ];D1c{.Iې1}Q(*`eIi1'wSOSԣT:AeR*j5¨p* T2RTuCeU]K~Q]ߠz{FKչ iT{ jۈIVh #Bb`) b=Ey@~1uKܯ'Vi<>T]2L#Dm#sSr+QpSZ<\z5 /U̵QXr,CQ^YQ'e*ɑCzg17h`a ;k@b/=7MMug~hbzvy|q{~s.Iޢ=h˽>*ȮGuuR DX=<8u腈-(&?xC -?6H8[ : ֟3d1k K͛rJ3$ [cbN7d+~x|-c ,C:3g}UPŧ:X,d_},J#˲ցCǬ]h7$Y  Xz1۾J:u-[ Oн_ ېs'WdzǑ¥g] 'pL4`(chW$R=FD$o1YJy<Ð ~pOb:{;{XJe~drUB 0̀wbpX J0J* c(`H,0Gg;Uu|WYp sQr8.VY_Q3_:wۼ P5s%"S[Z\]k `-^&:``]=܇qO187GFtcmQC)s/C:K}˽ '}e;lE-3dEy4=ܩx)V578O Q hXh)f143X )21D-ONktM{+Է:5zkR^m [b⿊DaS.@s ׄ[jm0ďFTw;j%= (m=zw|>bHxDHy~qv|4Xɒ P˿~SzZ\m"^bܣߞY{c+1o/KީW"m|FKgggA` lht'/Jͧۛ\o*]A7aendstream endobj 128 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 902 >> stream x]}lSeۏ2jK:n/t#i#R.v[mfW'ؒw+ץ3Rc@pi q KU)")L1sk[$ϓsC!QrG,וZ.{GQ*_"$/ez%h嫫 X! @Jp=HLQ[tu4]ͬ6a-[vygRimٲ 5HGU|B˄tH(~S{h ʿDsxئ>4D)($ 'I$Ig&8IK!"$m^#s]Ѓc' i`L *SwEDIHo8؀9l:|#sx.6Yi ;08)o~k-v~lUmia-֎ܚ7>ķ1a4.p>jqA 3\E + 8ħ=1'%0d0-HC?DfⰚ7ƍjrh6GIBJZd k7_eȡ,73PAH}jvc::)o}y4\L>إӮޓ6Į#o:xs剫pu޵[GJ5]=?? X VQo#]W "']O)Y13V}== YSx?>qq`w$r$ 2T?C)|Pk|\-ۡV5:9G4I =Jo7؇1:wg9'ZT,Ê嗢 R(gGendstream endobj 129 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4677 >> stream xX xSe>!4Fs * 8b [R@쾅tIt֤I$to7]hK-;bZ: 3s}"ȣ38ާOi~}̜|.܅Գў9NjHKgW,_rR˂7I$ 6- ޜ/NO MHII NO ޑ+8|{ȶ۶oݾd'w N[. |1+4 y1/n̏9!1)Y}$<%u#xJ#b1N,!vc.b-8XJ!^ !įP%b=xxH"6T$Sc(US<p] IN 0c׌offj᯴f?Ҝ9ޕ7wܓlw>%|OĽaAKQ溺xPyإ;t=(tj@}HK€5TV49t~4ɏwx<GCeH,ncjީ=TLWHNK Tj[:x}m/9`͐ 1S dTkґ]h?9^yy>EB䥡u4Oݭ9ŝ@C 4wD ?:FB4 MNτ~0' 9dvA'tegh ƽ/|)7Gf4ZwPWZ-j}*=ESAY+ N-=ƦO$ğ'蜇$[vd|c͈q9֨EO->kC}¿m9eOt8RGg"%PM9X&EDJi-63WZP[.:*z?Zd+h=C3bfs/ ! S_f>]>| Dm)7#e|)-~z?s}]J`TCv1Q@rn)ۨ53P5ihk.~ I:DJ)-d/r~o#`%@DS Rɢ b`H *e5&K DcI5+lP7 b뼽m,A/PzdG 1J^™c2'6;R/f7QP<P'OV1(%Ys㰿Їh_|_!劯]`>p !8 (P Z20Uo K' "iX5&2k-2,"? _JP Σ Iy11ٴ0&01^-=94:}=!Ϟu[plG$:ԤZX\~h(o=X.[KIr, 0*ܹEg*/{هb'^ | Jm@JUV}t,5sL:S]"[JPp q :]!E;NIz缨ߎ^/FB^J ;7@T֤Me Xs<%ۅ|3ZgQ/{ۼ }gʡ=^AP`=W׸ Hi>;|CN %.(2Z*&.7Y1?"2/USk|+D( #:G:l %F/KLh{[b2Ry<"'NjoojB7Uzkz劍<( >fg ޴lMkRf 6\7-\us㳖w)K*o %O;~;zr<ʽk}S|+f_b*4WjmIU'NΑcABv@,$7iM~ԜeBOŝů<4 dSl6 *qKqrg+#h|ߦ|Z!b*ɨ)ܽ/Ah#ZP;V4B5iY dSɐ`OW0X Cy)BWn(CK ݍB4\؃% |Mog:6lX\ByhHYd>KJ;s2{Q X4 PqĤU3cQB郡(=i+s_GwжF0Uֵlj+ g !QHn?&Zh>:"@WX1Iij#k%$ =bBp{KԠ2vw Dc Z=G{^Y9T;̛-?1D hnA0箎 =zq@Sc HH2[[{8w{Zf7C%ZVDlkQ02 rfu>~[0m4{1z~h ֤פJk#dGa+m#z)WIO 5BgȀ1%䍨2Z8\{aObs OyZ2r.2q)0Z;"Lly] hEHP6#i.7VO6ԃ]+xtnP9hkHplPb q!OYDF#p,r3< Q^3#VEK˼ygoPlCL"YI TnRǖ4bEDAfVU[*; 33#\GmX5Iy1|rtm&%7|u\KTiZLby7(1ĵNh5/MyR%INUn[G]x}[yQFBhgtdz[eGI\Y|qZk VC7()`SV^0a x{Zg簔2JQyЉ";Sr \#+Vbva pCR/Iaj3vUt/:$>4XvXϘ|3*6U؎Be`gO`ԘSſ$+%HMU20)ht6F Z.AZ}1bx*N.VĪ=1I3O)d_RC]$(2tdkF ߄z+WCd1S"4GD>{G% ^ok-ѐ3}C@nW-MrZۜ3:&NLm[_X\_A| !muEυ0u+Ù=Z3঻Cy3bgHΰgaI8Kaa= Zͼz sB}Nф|O|ot 9s%PP̂YL:%FYEֵ4?qvr񍯔}wRV7dwTT*y;6}WOGT^v@"6M_LoܿM`'i _mbgOۜu=JEolm7y+ qgEq!/=&iPW8NJ% |IБYkEs H\(TxAMcG@9c⋿ˬ3gV6S7l_Wendstream endobj 130 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 638 >> stream x}OpƿecC KȺ5eJ2 wFFB3d4KPj Es@:BC7\}6j\9 x,j%TnVy26YxFFM&! ME,ZxJ<#n1YBtgBi*:M=Qcۣ~jx}E?.C"_,":oVދ[4 2K F\%W5â80e(K 혰Az2Cச )`[  Kz 9U:TUTy]dxԃFM 5prϮIwaeӐv AUI<)=plłOy;Kdyv5I>g`ʼ* WIʒEgclL6jWQP\W*th{XP;9Hd㓾m4IlPui$hWetXR۪P:k]di]U1/7VkU TTKPi=/ ABendstream endobj 131 0 obj << /BitsPerComponent 8 /ColorSpace /DeviceGray /DecodeParms << /Columns 149 /Predictor 15 >> /Filter /FlateDecode /Height 173 /Subtype /Image /Width 149 /Length 219 >> stream x!PA>nX܂­h1 $[FT2k{c|ZaչFfT羾_|p(UGգQzT=UGգQzT=UGգQzT=UGգQzT=UGգQzT=UGգQzT=UGգQzT=UGգQzT=UGգQzT=UGգQzT=UNF¯endstream endobj 132 0 obj << /BitsPerComponent 8 /ColorSpace /DeviceRGB /DecodeParms << /Colors 3 /Columns 149 /Predictor 15 >> /Filter /FlateDecode /Height 173 /SMask 131 0 R /Subtype /Image /Width 149 /Length 12958 >> stream x]w|۟˵B HT@(*RDESDKo* ("(@AHBB H/wɕ}ٹK|33BОA4ihAP?|kEp'T*eɻvjC:tPXXhGdzZD`w6kݦ8WvveR1g+8F[7òe˖/_nԵʸ.CxހS /:9rd-C毨Ņ2|"Ж<^8NNN-F;'0{8{F*ޒ j̘1?#/̶ve=V_^uݻwgI' 3f㏹H{5:L|%p?/Fha'xnpש2Bb4pEɴxuj*)Dζ+^H⋉'NMi۠87\%-鵒xhA:z8WubNqOʀ;xI@ EO&) u=Z8Z!Vu={ƍ-:g_$Bn4{WW*>OɾB_ܫW5E[sρuٻT"o$%:\6Rnm,ooo˄:>Z1 &xT*uaÆ si$ȢT5mpכֿL Mq\'N :ԔFk7a„BY-h0[yioj$ץZ,rhꫯr] ɶy63b .-[, geeVqЌ0ZiiirADSLٹs'0ۅ4uG\BgggS?~wus<i]yVBclhccSQQ ubmzh>zFane Zd :?Aksy.,f]/WN m=@}2ps]h<,5<e4[GWHp%w-ǯJ DV\?DmDp(Q5:Fj㾗dvFܳѶI͓f/j*+s_|ܫP 8OE1 AVͱlA$6 ]IAѬ.A7CjMwKQoZ Ѩ1džLX; U RT"Bd%Ab,Af(lq,Uh=3ɦ|'/%кQUIq2$DklmQ8X ا`_>f6tzЦMq+%є\oN(Umтȩ#~^GȱL ퟯ{!^/s1\@96R Y:2іG):eP ۗ7!W(yahY$E~lBoBart/^C z饇jj{QfP#$h$P4 YIhD7Rj]B~dF] tE XS^ 'p=3xOUXk޷{QomAѐK8,z=rcWp];A݌}NAo@]#C3BFک?ra"1"C~;GhU*ЇId|q\&zgq]悭^C%25w(Wqf('Q x5a5?#-?#N:oj%n EuBx>K/(b5RP碢XBkǛf,~x+9GhL. ? B 5u[Řbl# B%8-{w~ ~׃6Jutf3 "pmysWSq3a4q3[H:N^O~{:nfФU/$aϸFr%%.WS'Yu5IZ:/xȴ=V<5=^P,LA]$=71|4z~z49k~Okb%tҹhY@qSR3z aS:uq?:o$ݻ ㏛j[1Z=ȝ@;uu4t@ߔ8m/ ~R>ՂX6h*ޏz YtB쩻?Rcu4֌ө`~|{H:Yq1'uͣ6IѪ[vq9$L$ OFYsDE߼U V Qe1)ԇ?\cqY(TըLՉ&Zc;?w?w~^-dQCc%"6 v_.Ss!ß#Z oNEB4phm`M?Vvew%f5X 3w^Gׅ6~ <(rwPtRi4WՇ?Qi> ah3SzΜ*KH~̣*dia$/X?璓>~Y pm 0H:F*Bh@f.HZ2_~7@I황}^uV:,A̞ @܁iLKIm,%DhjS sꈛZ=#m@]КY]=hK ? ?AQt{DVJ."B HP \ x%C:ę3~X CL `5e\Fx4C-A:?0lۚfnL ArݡkX&m  v)TErp9ǍRxv:2yQ,2z}FT⃽_:G CI{ D4 Znj4svtrdVhS\o3p9k-X{XC]5uY` ~qVc;t6]aZڦof5*ݏHY<{vW$@/Q"4ջ!PeLf6`(R3'[ό@ǚ9"rݬCEIQm5 ۈ eAz`J@ h#!blJjYxdܡV"@]ԛnv@u d⮷ 7oT^< xcEvP_~wן wv0}H7htsG3_-fd7ĊmDS#uF)%Y.~7]st'E3{H7ʎSfx%)է|L>w`RxVwC>,;]E}5%9"7'@BT IzJK$d n}K#5+)iF"kz}!x+'^ך)[|z:=ts+w{}`r`]VZaCI2nF@, ơ"zř*[?g/I+x]ԗ͵e'^@We; re Z1oC,HMg֌~ǹnDҋU kTƕͲ6k.{XGl]v͜H̝I(fьhExhpq"RHPW\e٬@ଁYC@p)7-~Tʹ*q"O!nV2cIsPu %xEBcP(熛 @ [zitݨ;%Ҷk_;b䤺.LTk+۞4O`S5VJUH# #& PnM5*ru13l6;hXH ]Kok?LW5x4aYƾZVVN5!BJ6=:C牅{bkgֻc6?j[_!o3wzVlvMm7Q>굗u |Dɺ!%b_~L`<@_ha-P~au@='nB @2\I-׹iK+5UwZg;/GxtM{Mk\e]FB _&H*S9󡝉v3BTgUvHVi{q7%$PQ(=-嵤¯00md5]p$n jf<4S3?Ki0 h M@:^NTo\+ Lo+wyKK}aLo?+cK 7P fnc7A k4欗|y\ϱC>un=P BRߊ<[ױXqIڕ}j#1Br[1eP'kx_ kh;Ulau1H`3+”-X Я7&%:2{w{ԺgGL;3 Qq} /l.[z~ (#BC: [ mVz ioBtҎCNnKU.&eàZ殼'O:.Kk9{S#Gtcdx@dm퉘!T.]}ȟ-3[i!fɜC/w% ;Jډ;9-TU_ !CcH(ը˜dhvUVdG^Nw{V }'IHM`KC|[_KB=CJ7EIdOvَ}'zk7v96]v9avX%JW+Uq1/hG1EwopTgm, ׭ ZUrwa|b?e^6~%˭c6cS+^d油)ޟNiPISy]{07\۔SRim4wط Wùhيs^K,;QH3CPɬ\kbvY}ΒGբo'kJсKPVS)^Vl4 #E;k_KLynP&r*58?@]~ĎRSjqt=MX-xE]iw}1\oV3(vƟLQ̹7OG~WBwp6HԚj2y 7*p?l0to HB>yf]CInm-r&QWm?bl;q'ޠzPvd w]WOQ5j/̝-55 6+>(\>iO~}KFͻe}?{:}gb'i?|Yc?̂ J@(IN]k`i$BTs؁`Ic^Zh~S @:vb/7.e78| $'{R"Tqw?;~즗8\ ]9s"SxHMܚЭ>ͱۋ=m W):kVԱBn]%\;0+"p_Y0׷#H[:zirL_Y U(=\s勐=jba_ ߕ{_*7Y褀xY?+mDu{ՂV5̠>Nqz_~U@,4uu<2YRDЇo\hฺ?>s( !E?#pK H@i/{;y.33J?x}L$"i^Dn[y9 9;4Ӏ@N'ȝVׂR&/kíVT"j0Er T[h|`^Bڬn޹:,h.|pH/<'OX,䘟m 1~)rTJ+9cwVr^W;rNHȓvu}~FN*D_ZG3m? Q|7r=yHԷoۋ;C$!#-CLp@A79g79:J̓ :=jꓖvxsDTDZNz?Q_yBL  wF}.ru 1kp5/~fjFnv}?Ne3zRHԴ<{Z~^x CbI'"ͮH}5۴%8nI \MZsw,c{VT{$ .:|"k:(5j*2I[G|2qWr"EݐՀ ֘)buNҕ5K/jtT%bMԱAn=eMd톫.d?\ժsdK*Wgiբ|| )Uz1]pzM!wlhF x{NuRG&7#˥,=poH`w&IZO*ɑ/Cs%މ],(kJׂ, SONז룄By$@J^ỹxwXhO0\'=$h@u\* ro`^[$ÿ,W*UJ5u,H\~xf2Sꮍ+|S,i +2H MB#O+ilkCث\+w/": /9N`rIsK Rl+@"_ohv~1s@kk6}.v#++g@Ŗ+F G.3EUeW{ ](;4K3ǂ4WC$mANM RS m'T-<-v[QGK2!x.?C<9͠Uagq"h'\uWQ3T/&w>@v>p:N _uϏH+Rv.o?98Yd/ h!FTR| M䔠/ EAU ^nng vejY?Z%,^\gw'=$tҤ$ϓ'}:OSkQmG߱sWB]"I+.C %P`ö́׷׆N 2zJu}E*,+yG3eAoA > B7,|(clzBr`D2"tF>o<+؂z -8r!o*NAM cZCD1i y\ڮ, \16Qҍ{ņ)44Cwp?'!V4+$Q0JP#)tJp‡dT(Y}Ipk=$hd3m"_W{V0KB:1g˘YaK((s_Yc6̞& -',KYeЋSH/tC:mwYݣGG+(|uغu ,`lkkI5 $u"F8k{a"[)O@鯹 ?r@i]i??DWYiAz.F0RL[Bjح7 g1A\ C}Mݵ{"Źzj3,ڋQLguW <ж1P O"rZw}evb;#Y'+Z_yn_@Y=$s;ϋаȌ<<МX͜HK*w4Hw |%Vhp W+ۮx/7|CqˬJ k [++BBޞ-6|VY0:%񴍨BU4',R}>&g5^gU <O?m]uQ<>)2-_n%8AܥE\Pjb%Bݜi@!oCJwJQƩڛ kI HmE ]tm+!o\)'v LRM]W kK~}@;wu3<#NBE{gr₪+n!x?pĐ494{K Ukhؚx>z/7^H-Yם!텡7n1ɟo=Ǐ-{4ۯt*W%TjR =mtŏzFo"a'+Q3w8WlY7>g_6 xQFF ry|*[ Gܛٻ 4&wsxA[YQ¯`|y5m7xuV$ ,oy?4vK lٻar8]&DK/ʠ#i 8ԕ)7%>B*|lDG! 6"Ù;`=ԇzG60N5 V Xju)ÔV뿘kiL>-7'F*[fN珌7 N>s&UT۟޽{_y^BŅh] A!4V%o; ݹ8W9$B+7ICc炍1`HӧO߾};K=ΐ,H8o:'؀OF}H']0 -'Ani\(|o)X_>ùd\4?R)t]WZjwKR: NfϪ"ޠ_B@ 5$X.l>-))qpp0q]h<G}ILuf1Dͧ~ UFNς)Qq\e!&>;9|J@T:[72U| +/_ξ ڠQ3ng5.ջm 1&.G4Q*%bd܃ͪd2ODG;͠tމĖ YQB )s| bvJܝB zR&Jb/JZ.jX2R 0e %=={f(F0?U@Sy:I(lhP]:uF#u_UpPx]`xmut ^L;"S~ʺDsO7-sη~F>wJo<;yS_D~؇s? .ud ",ͦ{Inlt v8hռ%!cjHċ,"Mdh-nڈ qi$}5#Ȯ]@S;D0v7}Tg~kX^?Y0\b2Ds[B J47m4Q=)Q"|mwxA,[Y#1fYFvz5 eJWY3gsWv l5'<|r:}dW&{e:hf͚GV>Uˣq+i596pcdC;opκ1Guܫ-rKWykM%b7zҧVCLacc59<X\\lm?Q))#%By%5-?\H\s 0VD@ pe3Z(. ֓7n=m?E.}972p18؏;O;vh \\\W 4(O#$TTT2[?LPɬ\}fW:Mre˖-]hܺuLJaݏ4(E]}b :}tbh!ӧOlހȫ=/sc0w$ʯl$Z?> stream xuS_L[U^sf$-^ڻ=0&K llTVs RR(m[6g:sa23̆ككO1q x@zN}~9AAmVv06X;:[~B\a9*:Te}{4fi V旳⟷05{Bɱ{;l~񉊊'F:?#ZKki-6\<]|[6]tMâQi8doUEx-VbXoA泻:Vo<Kv?'d #@ D)f8zA;4[TZ4/h֊jL@RAa7¹[ .H Hĉ$"c\He\unµ dbJ6 /Eӡ%>~8ʓmG[# B8f0A#OgSoHRi J@H+XUFX6fZ3暠WJ*M2m Pp*4LG5kʕ R`< A5K9>aX^?@|&f^oX]j;$wOSipTfVO/͡Jzx#_sY)ĠD~bp9OOU+K'wdT\c0YSM[掠sD"k{xG ᜁȮc eSa* iK,._ޒbޟ̓Gfd UѪX?xCM[+:I2Ag5HF6R vnӭM&ԛ'$St*;zQKtJCendstream endobj 134 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 409 >> stream xcd`ab`dd M3 JM/I, f!C럺 N|2l|<<,~0 }O=\1<=9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C53000201ȁg } d)M?o:]}CbUg}e{wjwz7G ǗseSKHa;0>y.w39K kzt.)3mXt b--%Ӄm2_قγOm=n9.|n==}=zz'лROީ< -endstream endobj 135 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 638 >> stream xcd`ab`ddM,,IL6 JM/I,f!CgVY~'YHnn? }=M1<9(3=DXWHZ*$U*8)x%&ggg*$(x)34R3sBR#B]܃C5:E)33g;q5^3~:?YDW.)++[pK)YYV*WQ4}f?]S$Oq8rUjoҶ3&N['Օtȇ˔mؙ~ 3}PzS; 7NKVǯ[o,٢eͩߐrb [38, ~s֙]{Er===}3{[*gvΜ3c\w}4n]w.y?N`j r\,!<<+{{z{f͙3gìE===S&Me`Kendstream endobj 136 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1892 >> stream xUkPT>z4dl9"hMk5\@ e\]n`/=^YXvEV@P.Q@$Ҏ t:d&|9δNoa1{Pjdjd%ˏy̚f-آbٽVF(x>έQkH *xxJkk2iEd{RҎ[sxdO`qI\IOJ&&JjQ&,?)9^VQ\U.K$9YgfI>Lڒc{'ZuIiaX`y>}~aB.xy"_-,TSpnE%f+ P󡚷Gm+b%-T/զ,-ZG U|2RЀ;mpkp#J*m@Pm5Xc:};؇m% j=$ YEL28!3U-bgC7̯zf-ei2YMrMFW{$#GM|ʻG ,UÅP Tz4v]Gश|ڬ!f P`kڞp{NA3t {OA~C164(PGW?D[섐<bQ:ʪ3ڪ-95.{E.ٸ` %6 t) 9J丷|$ˎԠD//UAj&~s}5i/MpQui+F(4r*;͒C(y;q,oQhD6h`k~sX7-5no >-HZ ptmv}.򻛀wxMJ0y"Yw/NDD(Nk?.뿏 \η!)etZ(`$r/+9l v PBiSo8#:fv&O Hm2$h(8gCU0MV#e&2XfP1PbǮ`OZL޴I}.Bp7qp=&}as;Ucde8-E q>AV dk5pmH . @'G3ֳvٽ| z(!k!^fo;RU/b+!F4mCn9hG_ư:9)endstream endobj 137 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3045 >> stream xV TSg~!/uEeNGV[KQ+ (hFd\Q b*J).ՊShiv:UXߞrl{9+lm(H4r5E5JEX?Ά/b?p?nb-8 GRߧc,+j薡͖*ׯHcc#R&Q i)EggNQdݩ=W*0XIqc@aJz#S'Mzߪ'Pt]d 0Yk&Roro]٩^TJew> (ys(OTk~;^=,dNdӝue˽ pe}a鞘U $NW~K&<>CeA/ u^Ӈq J8=ӧgA"Ws,RPbQ{/fy Tsrc𒗪⋽*$:R% \A Jje7]PAV&(H`[W`tU|c]y 77{a[Y) B9!cRgDz8mޘLnQ6ȩ0抌ŝ&B箋d…:l`-"Uhqeop*~I aNIBEFLt2 4UBl?IXs^X(3lP~ Ǎ$ u|a(5Z$Z?(,?.d%:LF2H?fq̃:L^%)% OTpX<>T=9F`=jEF\S#CI{hgˈ; >hM=wކL۞뮞?֣^CC1\;wXDw1K1KU]fof%2d8'w =03/̚ԥ)mhߖҠhA5]80wX2i dd9YФO?Gݤ !.2*I qʊe0tJFYd.#f%CNi@"ϭ\]MVKh ?۔ T>&5kEF Vxҥ^BGW-Pk#bm"E- /mOSEEB(fJ4EyYzQazD ]J$lj)W0%E%2{Ɩ$k&aT`V0ϖRhYRXQT(q8Et)endstream endobj 138 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1371 >> stream xukPWwIJu[: 5*`EK EBb1uzC D%Z#MVwth)uݙǗ9{qL8o2V'fe[ B.H(D J=+ȡBRl"RKg`$8]g\)GF. +B.&KM6^ǥ3n&&#nr&-5c.9i}b!Q =N)&s/3+XK¶b6,KcX06]b%5|5%a$NiL&=AB ࡗW_|0'v33iF<ѷ"uWQnC 7f0k&meM{:p_i06_gI`E/o\ЉA|A 4T?C2$ H9 P:6LtHo/f( y80վClP/s$MM/20Jk{z /JǠ~sqƘ2_ćo6,e^CEHX }7Yw2rjsZ )aj`@U/#x;/ Da$=|1\:|g]n xmӠK\~ex}kA7v=yR:2S;8 HM,/׃v}?av"@uHӶ^˩Cl^בߋێ` ۬9;`c75R ll*Ij7Y$gj< `FDB2wK  yşj+>hS6b^P{{5D[ '03_nfѪchV*X@RkOsz'EA`FRhHBy'T:ؿ] I@1!P0\q8WKԷSv8c7F,s|nDP@H!(ƛS($ Rgy qsW/8Bڤi&:Mfa8b}/\1@m.)OQ ~z޹~u{!}N/ qںX2ď@)uHG4(h?ÙNv-K0lWU' )ޠ z٠vn&VXW Wו;~/&jRj GcIQ텼b:dendstream endobj 139 0 obj << /Filter /FlateDecode /Length 416 >> stream xSn0 #Daک!Mkl#i7_INV.H>hz'59^| 7Bˍ Yy8Vrs9QGNLP32:zqFvHD MkHWY]PGU4:[C7HY0q֒B&*fX"BtYW.iP{_N>lS7mG 1#҅H_ W/V0NGƪ3ЪF5af2&:ݟpf7NlV;Vi0ƻ#Tj8 PF|Iy>ɣ9)Y.4Kiʦ吧 >o ƾ|ʵ#Dϵq$2>_:fHfO/W!endstream endobj 140 0 obj << /BitsPerComponent 8 /ColorSpace /DeviceRGB /DecodeParms << /Colors 3 /Columns 149 /Predictor 15 >> /Filter /FlateDecode /Height 173 /SMask 131 0 R /Subtype /Image /Width 149 /Length 12958 >> stream x]w|۟˵B HT@(*RDESDKo* ("(@AHBB H/wɕ}ٹK|33BОA4ihAP?|kEp'T*eɻvjC:tPXXhGdzZD`w6kݦ8WvveR1g+8F[7òe˖/_nԵʸ.CxހS /:9rd-C毨Ņ2|"Ж<^8NNN-F;'0{8{F*ޒ j̘1?#/̶ve=V_^uݻwgI' 3f㏹H{5:L|%p?/Fha'xnpש2Bb4pEɴxuj*)Dζ+^H⋉'NMi۠87\%-鵒xhA:z8WubNqOʀ;xI@ EO&) u=Z8Z!Vu={ƍ-:g_$Bn4{WW*>OɾB_ܫW5E[sρuٻT"o$%:\6Rnm,ooo˄:>Z1 &xT*uaÆ si$ȢT5mpכֿL Mq\'N :ԔFk7a„BY-h0[yioj$ץZ,rhꫯr] ɶy63b .-[, geeVqЌ0ZiiirADSLٹs'0ۅ4uG\BgggS?~wus<i]yVBclhccSQQ ubmzh>zFane Zd :?Aksy.,f]/WN m=@}2ps]h<,5<e4[GWHp%w-ǯJ DV\?DmDp(Q5:Fj㾗dvFܳѶI͓f/j*+s_|ܫP 8OE1 AVͱlA$6 ]IAѬ.A7CjMwKQoZ Ѩ1džLX; U RT"Bd%Ab,Af(lq,Uh=3ɦ|'/%кQUIq2$DklmQ8X ا`_>f6tzЦMq+%є\oN(Umтȩ#~^GȱL ퟯ{!^/s1\@96R Y:2іG):eP ۗ7!W(yahY$E~lBoBart/^C z饇jj{QfP#$h$P4 YIhD7Rj]B~dF] tE XS^ 'p=3xOUXk޷{QomAѐK8,z=rcWp];A݌}NAo@]#C3BFک?ra"1"C~;GhU*ЇId|q\&zgq]悭^C%25w(Wqf('Q x5a5?#-?#N:oj%n EuBx>K/(b5RP碢XBkǛf,~x+9GhL. ? B 5u[Řbl# B%8-{w~ ~׃6Jutf3 "pmysWSq3a4q3[H:N^O~{:nfФU/$aϸFr%%.WS'Yu5IZ:/xȴ=V<5=^P,LA]$=71|4z~z49k~Okb%tҹhY@qSR3z aS:uq?:o$ݻ ㏛j[1Z=ȝ@;uu4t@ߔ8m/ ~R>ՂX6h*ޏz YtB쩻?Rcu4֌ө`~|{H:Yq1'uͣ6IѪ[vq9$L$ OFYsDE߼U V Qe1)ԇ?\cqY(TըLՉ&Zc;?w?w~^-dQCc%"6 v_.Ss!ß#Z oNEB4phm`M?Vvew%f5X 3w^Gׅ6~ <(rwPtRi4WՇ?Qi> ah3SzΜ*KH~̣*dia$/X?璓>~Y pm 0H:F*Bh@f.HZ2_~7@I황}^uV:,A̞ @܁iLKIm,%DhjS sꈛZ=#m@]КY]=hK ? ?AQt{DVJ."B HP \ x%C:ę3~X CL `5e\Fx4C-A:?0lۚfnL ArݡkX&m  v)TErp9ǍRxv:2yQ,2z}FT⃽_:G CI{ D4 Znj4svtrdVhS\o3p9k-X{XC]5uY` ~qVc;t6]aZڦof5*ݏHY<{vW$@/Q"4ջ!PeLf6`(R3'[ό@ǚ9"rݬCEIQm5 ۈ eAz`J@ h#!blJjYxdܡV"@]ԛnv@u d⮷ 7oT^< xcEvP_~wן wv0}H7htsG3_-fd7ĊmDS#uF)%Y.~7]st'E3{H7ʎSfx%)է|L>w`RxVwC>,;]E}5%9"7'@BT IzJK$d n}K#5+)iF"kz}!x+'^ך)[|z:=ts+w{}`r`]VZaCI2nF@, ơ"zř*[?g/I+x]ԗ͵e'^@We; re Z1oC,HMg֌~ǹnDҋU kTƕͲ6k.{XGl]v͜H̝I(fьhExhpq"RHPW\e٬@ଁYC@p)7-~Tʹ*q"O!nV2cIsPu %xEBcP(熛 @ [zitݨ;%Ҷk_;b䤺.LTk+۞4O`S5VJUH# #& PnM5*ru13l6;hXH ]Kok?LW5x4aYƾZVVN5!BJ6=:C牅{bkgֻc6?j[_!o3wzVlvMm7Q>굗u |Dɺ!%b_~L`<@_ha-P~au@='nB @2\I-׹iK+5UwZg;/GxtM{Mk\e]FB _&H*S9󡝉v3BTgUvHVi{q7%$PQ(=-嵤¯00md5]p$n jf<4S3?Ki0 h M@:^NTo\+ Lo+wyKK}aLo?+cK 7P fnc7A k4欗|y\ϱC>un=P BRߊ<[ױXqIڕ}j#1Br[1eP'kx_ kh;Ulau1H`3+”-X Я7&%:2{w{ԺgGL;3 Qq} /l.[z~ (#BC: [ mVz ioBtҎCNnKU.&eàZ殼'O:.Kk9{S#Gtcdx@dm퉘!T.]}ȟ-3[i!fɜC/w% ;Jډ;9-TU_ !CcH(ը˜dhvUVdG^Nw{V }'IHM`KC|[_KB=CJ7EIdOvَ}'zk7v96]v9avX%JW+Uq1/hG1EwopTgm, ׭ ZUrwa|b?e^6~%˭c6cS+^d油)ޟNiPISy]{07\۔SRim4wط Wùhيs^K,;QH3CPɬ\kbvY}ΒGբo'kJсKPVS)^Vl4 #E;k_KLynP&r*58?@]~ĎRSjqt=MX-xE]iw}1\oV3(vƟLQ̹7OG~WBwp6HԚj2y 7*p?l0to HB>yf]CInm-r&QWm?bl;q'ޠzPvd w]WOQ5j/̝-55 6+>(\>iO~}KFͻe}?{:}gb'i?|Yc?̂ J@(IN]k`i$BTs؁`Ic^Zh~S @:vb/7.e78| $'{R"Tqw?;~즗8\ ]9s"SxHMܚЭ>ͱۋ=m W):kVԱBn]%\;0+"p_Y0׷#H[:zirL_Y U(=\s勐=jba_ ߕ{_*7Y褀xY?+mDu{ՂV5̠>Nqz_~U@,4uu<2YRDЇo\hฺ?>s( !E?#pK H@i/{;y.33J?x}L$"i^Dn[y9 9;4Ӏ@N'ȝVׂR&/kíVT"j0Er T[h|`^Bڬn޹:,h.|pH/<'OX,䘟m 1~)rTJ+9cwVr^W;rNHȓvu}~FN*D_ZG3m? Q|7r=yHԷoۋ;C$!#-CLp@A79g79:J̓ :=jꓖvxsDTDZNz?Q_yBL  wF}.ru 1kp5/~fjFnv}?Ne3zRHԴ<{Z~^x CbI'"ͮH}5۴%8nI \MZsw,c{VT{$ .:|"k:(5j*2I[G|2qWr"EݐՀ ֘)buNҕ5K/jtT%bMԱAn=eMd톫.d?\ժsdK*Wgiբ|| )Uz1]pzM!wlhF x{NuRG&7#˥,=poH`w&IZO*ɑ/Cs%މ],(kJׂ, SONז룄By$@J^ỹxwXhO0\'=$h@u\* ro`^[$ÿ,W*UJ5u,H\~xf2Sꮍ+|S,i +2H MB#O+ilkCث\+w/": /9N`rIsK Rl+@"_ohv~1s@kk6}.v#++g@Ŗ+F G.3EUeW{ ](;4K3ǂ4WC$mANM RS m'T-<-v[QGK2!x.?C<9͠Uagq"h'\uWQ3T/&w>@v>p:N _uϏH+Rv.o?98Yd/ h!FTR| M䔠/ EAU ^nng vejY?Z%,^\gw'=$tҤ$ϓ'}:OSkQmG߱sWB]"I+.C %P`ö́׷׆N 2zJu}E*,+yG3eAoA > B7,|(clzBr`D2"tF>o<+؂z -8r!o*NAM cZCD1i y\ڮ, \16Qҍ{ņ)44Cwp?'!V4+$Q0JP#)tJp‡dT(Y}Ipk=$hd3m"_W{V0KB:1g˘YaK((s_Yc6̞& -',KYeЋSH/tC:mwYݣGG+(|uغu ,`lkkI5 $u"F8k{a"[)O@鯹 ?r@i]i??DWYiAz.F0RL[Bjح7 g1A\ C}Mݵ{"Źzj3,ڋQLguW <ж1P O"rZw}evb;#Y'+Z_yn_@Y=$s;ϋаȌ<<МX͜HK*w4Hw |%Vhp W+ۮx/7|CqˬJ k [++BBޞ-6|VY0:%񴍨BU4',R}>&g5^gU <O?m]uQ<>)2-_n%8AܥE\Pjb%Bݜi@!oCJwJQƩڛ kI HmE ]tm+!o\)'v LRM]W kK~}@;wu3<#NBE{gr₪+n!x?pĐ494{K Ukhؚx>z/7^H-Yם!텡7n1ɟo=Ǐ-{4ۯt*W%TjR =mtŏzFo"a'+Q3w8WlY7>g_6 xQFF ry|*[ Gܛٻ 4&wsxA[YQ¯`|y5m7xuV$ ,oy?4vK lٻar8]&DK/ʠ#i 8ԕ)7%>B*|lDG! 6"Ù;`=ԇzG60N5 V Xju)ÔV뿘kiL>-7'F*[fN珌7 N>s&UT۟޽{_y^BŅh] A!4V%o; ݹ8W9$B+7ICc炍1`HӧO߾};K=ΐ,H8o:'؀OF}H']0 -'Ani\(|o)X_>ùd\4?R)t]WZjwKR: NfϪ"ޠ_B@ 5$X.l>-))qpp0q]h<G}ILuf1Dͧ~ UFNς)Qq\e!&>;9|J@T:[72U| +/_ξ ڠQ3ng5.ջm 1&.G4Q*%bd܃ͪd2ODG;͠tމĖ YQB )s| bvJܝB zR&Jb/JZ.jX2R 0e %=={f(F0?U@Sy:I(lhP]:uF#u_UpPx]`xmut ^L;"S~ʺDsO7-sη~F>wJo<;yS_D~؇s? .ud ",ͦ{Inlt v8hռ%!cjHċ,"Mdh-nڈ qi$}5#Ȯ]@S;D0v7}Tg~kX^?Y0\b2Ds[B J47m4Q=)Q"|mwxA,[Y#1fYFvz5 eJWY3gsWv l5'<|r:}dW&{e:hf͚GV>Uˣq+i596pcdC;opκ1Guܫ-rKWykM%b7zҧVCLacc59<X\\lm?Q))#%By%5-?\H\s 0VD@ pe3Z(. ֓7n=m?E.}972p18؏;O;vh \\\W 4(O#$TTT2[?LPɬ\}fW:Mre˖-]hܺuLJaݏ4(E]}b :}tbh!ӧOlހȫ=/sc0w$ʯl$Z?> /W [ 1 3 1 ] /Info 3 0 R /Root 2 0 R /Size 142 /ID [<970a7acf1c0ce1093dcc14cea4d81de2>] >> stream xcb&F~0 $8JLgpf_ ɷ{GC0< d;"H ]DeH ,YV+DH``\ U,~,"YH ,θH24e?#df:M} " endstream endobj startxref 99916 %%EOF Brobdingnag/inst/doc/S4_brob.R0000644000176200001440000005073414176571300015642 0ustar liggesusers### R code from vignette source 'S4_brob.Rnw' ################################################### ### code chunk number 1: setClass ################################################### ################################################### ### code chunk number 2: S4_brob.Rnw:122-131 ################################################### setClass("swift", representation = "VIRTUAL" ) setClass("brob", representation = representation(x="numeric",positive="logical"), prototype = list(x=numeric(),positive=logical()), contains = "swift" ) ################################################### ### code chunk number 3: new ################################################### new("brob",x=1:10,positive=rep(TRUE,10)) ################################################### ### code chunk number 4: new_flaky_arguments (eval = FALSE) ################################################### ## new("brob",x=1:10,positive=c(TRUE,FALSE,FALSE)) ################################################### ### code chunk number 5: validity_method ################################################### .Brob.valid <- function(object){ len <- length(object@positive) if(len != length(object@x)){ return("length mismatch") } else { return(TRUE) } } ################################################### ### code chunk number 6: call_setValidity ################################################### setValidity("brob", .Brob.valid) ################################################### ### code chunk number 7: brob_definition ################################################### "brob" <- function(x=double(),positive){ if(missing(positive)){ positive <- rep(TRUE,length(x)) } if(length(positive)==1){ positive <- rep(positive,length(x)) } new("brob",x=as.numeric(x),positive=positive) } ################################################### ### code chunk number 8: call_brob_recycling ################################################### brob(1:10,FALSE) ################################################### ### code chunk number 9: use.function.is ################################################### is(brob(1:5),"brob") ################################################### ### code chunk number 10: is.brob_definition ################################################### is.brob <- function(x){is(x,"brob")} is.glub <- function(x){is(x,"glub")} ################################################### ### code chunk number 11: as.brob_definition ################################################### "as.brob" <- function(x){ if(is.brob(x)){ return(x) } else if(is.complex(x)) { warning("imaginary parts discarded") return(Recall(Re(x))) } else if(is.glub(x)){ warning("imaginary parts discarded") return(Re(x)) } else { return(brob(log(abs(x)), x>=0)) } } ################################################### ### code chunk number 12: as.brob_call ################################################### as.brob(1:10) ################################################### ### code chunk number 13: setAs ################################################### ################################################### ### code chunk number 14: S4_brob.Rnw:368-373 ################################################### setAs("brob", "numeric", function(from){ out <- exp(from@x) out[!from@positive] <- -out[!from@positive] return(out) } ) ################################################### ### code chunk number 15: setMethodbrob ################################################### setMethod("as.numeric",signature(x="brob"),function(x){as(x,"numeric")}) ################################################### ### code chunk number 16: setAsbrobcomplex ################################################### setAs("brob", "complex", function(from){ return(as.numeric(from)+ 0i) } ) setMethod("as.complex",signature(x="brob"),function(x){as(x,"complex")}) ################################################### ### code chunk number 17: asCheck ################################################### x <- as.brob(1:4) x as.numeric(x) ################################################### ### code chunk number 18: print_methods ################################################### .Brob.print <- function(x, digits=5){ noquote( paste(c("-","+")[1+x@positive],"exp(",signif(x@x,digits),")",sep="")) } ################################################### ### code chunk number 19: print.brob ################################################### print.brob <- function(x, ...){ jj <- .Brob.print(x, ...) print(jj) return(invisible(jj)) } ################################################### ### code chunk number 20: setmethodbrobshow ################################################### setMethod("show", "brob", function(object){print.brob(object)}) ################################################### ### code chunk number 21: as.brob14 ################################################### as.brob(1:4) ################################################### ### code chunk number 22: get.n.set ################################################### ################################################### ### code chunk number 23: S4_brob.Rnw:467-471 ################################################### setGeneric("getX",function(x){standardGeneric("getX")}) setGeneric("getP",function(x){standardGeneric("getP")}) setMethod("getX","brob",function(x){x@x}) setMethod("getP","brob",function(x){x@positive}) ################################################### ### code chunk number 24: setlength ################################################### ################################################### ### code chunk number 25: S4_brob.Rnw:483-484 ################################################### setMethod("length","brob",function(x){length(x@x)}) ################################################### ### code chunk number 26: setmethodSquareBrace ################################################### ################################################### ### code chunk number 27: S4_brob.Rnw:494-501 ################################################### setMethod("[", "brob", function(x, i, j, drop){ if(!missing(j)){ warning("second argument to extractor function ignored") } brob(x@x[i], x@positive[i]) } ) ################################################### ### code chunk number 28: setReplaceMethod ################################################### ################################################### ### code chunk number 29: S4_brob.Rnw:514-531 ################################################### setReplaceMethod("[",signature(x="brob"), function(x,i,j,value){ if(!missing(j)){ warning("second argument to extractor function ignored") } jj.x <- x@x jj.pos <- x@positive if(is.brob(value)){ jj.x[i] <- value@x jj.pos[i] <- value@positive return(brob(x=jj.x,positive=jj.pos)) } else { x[i] <- as.brob(value) return(x) } } ) ################################################### ### code chunk number 30: .Brob.cPair ################################################### .Brob.cPair <- function(x,y){ x <- as.brob(x) y <- as.brob(y) brob(c(x@x,y@x),c(x@positive,y@positive)) } ################################################### ### code chunk number 31: setGeneric_cbrob ################################################### ################################################### ### code chunk number 32: S4_brob.Rnw:570-571 ################################################### setGeneric(".cPair", function(x,y){standardGeneric(".cPair")}) ################################################### ### code chunk number 33: setMethod.Cpair ################################################### ################################################### ### code chunk number 34: S4_brob.Rnw:581-585 ################################################### setMethod(".cPair", c("brob", "brob"), function(x,y){.Brob.cPair(x,y)}) setMethod(".cPair", c("brob", "ANY"), function(x,y){.Brob.cPair(x,as.brob(y))}) setMethod(".cPair", c("ANY", "brob"), function(x,y){.Brob.cPair(as.brob(x),y)}) setMethod(".cPair", c("ANY", "ANY"), function(x,y){c(x,y)}) ################################################### ### code chunk number 35: cbrob ################################################### "cbrob" <- function(x, ...) { if(nargs()<3) .cPair(x,...) else .cPair(x, Recall(...)) } ################################################### ### code chunk number 36: test.cbrob ################################################### a <- 1:3 b <- as.brob(1e100) cbrob(a,a,b,a) ################################################### ### code chunk number 37: sqrtmethod ################################################### ################################################### ### code chunk number 38: S4_brob.Rnw:635-638 ################################################### setMethod("sqrt","brob", function(x){ brob(ifelse(x@positive,x@x/2, NaN),TRUE) } ) ################################################### ### code chunk number 39: checklogsqrt ################################################### sqrt(brob(4)) ################################################### ### code chunk number 40: mathgeneric ################################################### ################################################### ### code chunk number 41: S4_brob.Rnw:650-681 ################################################### setMethod("Math", "brob", function(x){ switch(.Generic, abs = brob(x@x), log = { out <- x@x out[!x@positive] <- NaN out }, exp = brob(x), cosh = {(brob(x) + brob(-x))/2}, sinh = {(brob(x) - brob(-x))/2}, acos =, acosh =, asin =, asinh =, atan =, atanh =, cos =, sin =, tan =, tanh =, trunc = callGeneric(as.numeric(x)), lgamma =, cumsum =, gamma =, ceiling=, floor = as.brob(callGeneric(as.numeric(x))), stop(paste(.Generic, "not allowed on Brobdingnagian numbers")) ) } ) ################################################### ### code chunk number 42: checktrig ################################################### sin(brob(4)) ################################################### ### code chunk number 43: .brob.arithstuff ################################################### .Brob.negative <- function(e1){ brob(e1@x,!e1@positive) } .Brob.ds <- function(e1,e2){ # "ds" == "different signs" xor(e1@positive,e2@positive) } .Brob.add <- function(e1,e2){ e1 <- as.brob(e1) e2 <- as.brob(e2) jj <- rbind(e1@x,e2@x) x1 <- jj[1,] x2 <- jj[2,] out.x <- double(length(x1)) jj <- rbind(e1@positive,e2@positive) p1 <- jj[1,] p2 <- jj[2,] out.pos <- p1 ds <- .Brob.ds(e1,e2) ss <- !ds #ss == "Same Sign" out.x[ss] <- pmax(x1[ss],x2[ss]) + log1p(+exp(-abs(x1[ss]-x2[ss]))) out.x[ds] <- pmax(x1[ds],x2[ds]) + log1p(-exp(-abs(x1[ds]-x2[ds]))) # Now special dispensation for 0+0: out.x[ (x1 == -Inf) & (x2 == -Inf)] <- -Inf out.pos <- p1 out.pos[ds] <- xor((x1[ds] > x2[ds]) , (!p1[ds]) ) return(brob(out.x,out.pos)) } .Brob.mult <- function(e1,e2){ e1 <- as.brob(e1) e2 <- as.brob(e2) return(brob(e1@x + e2@x, !.Brob.ds(e1,e2))) } .Brob.power <- function(e1,e2){ stopifnot(is.brob(e1) | is.brob(e2)) if(is.brob(e2)){ # e2 a brob => answer a brob (ignore signs) return(brob(log(e1) * brob(e2@x), TRUE)) } else { #e2 a non-brob (try to account for signs) s <- as.integer(2*e1@positive-1) #s = +/-1 return(brob(e1@x*as.brob(e2), (s^as.numeric(e2))>0)) } } .Brob.inverse <- function(b){brob(-b@x,b@positive)} ################################################### ### code chunk number 44: setMethodArithUnary ################################################### ################################################### ### code chunk number 45: S4_brob.Rnw:773-782 ################################################### setMethod("Arith",signature(e1 = "brob", e2="missing"), function(e1,e2){ switch(.Generic, "+" = e1, "-" = .Brob.negative(e1), stop(paste("Unary operator", .Generic, "not allowed on Brobdingnagian numbers")) ) } ) ################################################### ### code chunk number 46: check_minus_5 ################################################### -brob(5) ################################################### ### code chunk number 47: brob.arith ################################################### .Brob.arith <- function(e1,e2){ switch(.Generic, "+" = .Brob.add (e1, e2), "-" = .Brob.add (e1, .Brob.negative(as.brob(e2))), "*" = .Brob.mult (e1, e2), "/" = .Brob.mult (e1, .Brob.inverse(as.brob(e2))), "^" = .Brob.power(e1, e2), stop(paste("binary operator \"", .Generic, "\" not defined for Brobdingnagian numbers")) ) } ################################################### ### code chunk number 48: setMethodArith ################################################### setMethod("Arith", signature(e1 = "brob", e2="ANY"), .Brob.arith) setMethod("Arith", signature(e1 = "ANY", e2="brob"), .Brob.arith) setMethod("Arith", signature(e1 = "brob", e2="brob"), .Brob.arith) ################################################### ### code chunk number 49: check_addition ################################################### 1e100 + as.brob(10)^100 ################################################### ### code chunk number 50: brob.equalandgreater ################################################### .Brob.equal <- function(e1,e2){ (e1@x==e2@x) & (e1@positive==e2@positive) } .Brob.greater <- function(e1,e2){ jj.x <- rbind(e1@x,e2@x) jj.p <- rbind(e1@positive,e2@positive) ds <- .Brob.ds(e1,e2) ss <- !ds #ss == "Same Sign" greater <- logical(length(ss)) greater[ds] <- jj.p[1,ds] greater[ss] <- jj.p[1,ss] & (jj.x[1,ss] > jj.x[2,ss]) return(greater) } ################################################### ### code chunk number 51: brob.compare ################################################### ".Brob.compare" <- function(e1,e2){ e1 <- as.brob(e1) e2 <- as.brob(e2) switch(.Generic, "==" = .Brob.equal(e1,e2), "!=" = !.Brob.equal(e1,e2), ">" = .Brob.greater(e1,e2), "<" = !.Brob.greater(e1,e2) & !.Brob.equal(e1,e2), ">=" = .Brob.greater(e1,e2) | .Brob.equal(e1,e2), "<=" = !.Brob.greater(e1,e2) | .Brob.equal(e1,e2), stop(paste(.Generic, "not supported for Brobdingnagian numbers")) ) } ################################################### ### code chunk number 52: setMethodCompare ################################################### ################################################### ### code chunk number 53: S4_brob.Rnw:878-881 ################################################### setMethod("Compare", signature(e1="brob", e2="ANY" ), .Brob.compare) setMethod("Compare", signature(e1="ANY" , e2="brob"), .Brob.compare) setMethod("Compare", signature(e1="brob", e2="brob"), .Brob.compare) ################################################### ### code chunk number 54: check.compare ################################################### as.brob(10) < as.brob(11) as.brob(10) <= as.brob(10) ################################################### ### code chunk number 55: brob.logic ################################################### .Brob.logic <- function(e1,e2){ stop("No logic currently implemented for Brobdingnagian numbers") } ################################################### ### code chunk number 56: setmethodlogic ################################################### ################################################### ### code chunk number 57: S4_brob.Rnw:912-915 ################################################### setMethod("Logic",signature(e1="swift",e2="ANY"), .Brob.logic) setMethod("Logic",signature(e1="ANY",e2="swift"), .Brob.logic) setMethod("Logic",signature(e1="swift",e2="swift"), .Brob.logic) ################################################### ### code chunk number 58: logchunk ################################################### if(!isGeneric("log")){ setGeneric("log",group="Math") } ################################################### ### code chunk number 59: miscgenerics ################################################### ################################################### ### code chunk number 60: S4_brob.Rnw:960-1011 ################################################### if(!isGeneric("sum")){ setGeneric("max", function(x, ..., na.rm = FALSE) { standardGeneric("max") }, useAsDefault = function(x, ..., na.rm = FALSE) { base::max(x, ..., na.rm = na.rm) }, group = "Summary") setGeneric("min", function(x, ..., na.rm = FALSE) { standardGeneric("min") }, useAsDefault = function(x, ..., na.rm = FALSE) { base::min(x, ..., na.rm = na.rm) }, group = "Summary") setGeneric("range", function(x, ..., na.rm = FALSE) { standardGeneric("range") }, useAsDefault = function(x, ..., na.rm = FALSE) { base::range(x, ..., na.rm = na.rm) }, group = "Summary") setGeneric("prod", function(x, ..., na.rm = FALSE) { standardGeneric("prod") }, useAsDefault = function(x, ..., na.rm = FALSE) { base::prod(x, ..., na.rm = na.rm) }, group = "Summary") setGeneric("sum", function(x, ..., na.rm = FALSE) { standardGeneric("sum") }, useAsDefault = function(x, ..., na.rm = FALSE) { base::sum(x, ..., na.rm = na.rm) }, group = "Summary") } ################################################### ### code chunk number 61: brob.maxmin ################################################### .Brob.max <- function(x, ..., na.rm=FALSE){ p <- x@positive val <- x@x if(any(p)){ return(brob(max(val[p]))) } else { # all negative return(brob(min(val),FALSE)) } } .Brob.prod <- function(x){ p <- x@positive val <- x@x return(brob(sum(val),(sum(p)%%2)==0)) } .Brob.sum <- function(x){ .Brob.sum.allpositive( x[x>0]) - .Brob.sum.allpositive(-x[x<0]) } .Brob.sum.allpositive <- function(x){ if(length(x)<1){return(as.brob(0))} val <- x@x p <- x@positive mv <- max(val) return(brob(mv + log1p(sum(exp(val[-which.max(val)]-mv))),TRUE)) } ################################################### ### code chunk number 62: setmethodsummary ################################################### ################################################### ### code chunk number 63: S4_brob.Rnw:1057-1069 ################################################### setMethod("Summary", "brob", function(x, ..., na.rm=FALSE){ switch(.Generic, max = .Brob.max( x, ..., na.rm=na.rm), min = -.Brob.max(-x, ..., na.rm=na.rm), range = cbrob(min(x,na.rm=na.rm),max(x,na.rm=na.rm)), prod = .Brob.prod(x), sum = .Brob.sum(x), stop(paste(.Generic, "not allowed on Brobdingnagian numbers")) ) } ) ################################################### ### code chunk number 64: checksum ################################################### sum(as.brob(1:100)) - 5050 ################################################### ### code chunk number 65: factorial ################################################### stirling <- function(x){sqrt(2*pi*x)*exp(-x)*x^x} ################################################### ### code chunk number 66: use.stirling ################################################### stirling(100) stirling(as.brob(100)) ################################################### ### code chunk number 67: compare.two.stirlings ################################################### as.numeric(stirling(100)/stirling(as.brob(100))) ################################################### ### code chunk number 68: stirling.of.1000 ################################################### stirling(1000) stirling(as.brob(1000)) Brobdingnag/inst/CITATION0000644000176200001440000000070713762776702014625 0ustar liggesuserscitEntry(entry = "Article", title = { paste("Very large numbers in R: Introducing package Brobdingnag") }, author = "R. K. S. Hankin", journal = "R News", year = "2007", volume = "7", issue = "3", textVersion = { paste("R. K. S. Hankin 2007.", "Very large numbers in R: Introducing package Brobdingnag", "R News", "7(3)" )})