Brobdingnag/0000755000176200001440000000000013334302603012463 5ustar liggesusersBrobdingnag/inst/0000755000176200001440000000000013333164240013442 5ustar liggesusersBrobdingnag/inst/CITATION0000644000176200001440000000070713277141401014604 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)" )}) Brobdingnag/inst/doc/0000755000176200001440000000000013333164240014207 5ustar liggesusersBrobdingnag/inst/doc/brobpaper.pdf0000644000176200001440000022602513333164241016666 0ustar liggesusers%PDF-1.5 % 1 0 obj << /Type /ObjStm /Length 3088 /Filter /FlateDecode /N 51 /First 396 >> stream xZr}_1o+1fjEJqd|=3X(bˆ$aDMS$$:6$" RMD8#G?K< ^DX:ˈ b"  IN'JJDH!2gEhLIѩh5JB1"bq 2tId咂D vH&h!B!A}ajIPN1s !94cB)E?J`,ąaB=Y9"4X|iL2!Z2#B,Y ݟ&WQϛWkֲsbTrr%Ӥ̊|7)Sb[a3.\|Wu9Qr^۬)zKr?@ ;L-yqu'ox?FǶj }%Z{;+!h7qZ{5TwERx+1<D&`qDlf>i]# g4k ;>n(HOPFzHoi-7P^:yI"/C|coƌö 艞S9qS9)GoDy10##>a )p9a 7+p2[Bܪ?"B0Y`A`7)T3$treZ&ʕPb~@rLkUE@:}3zx~ K{6xeYOߙ&s0HG{b_u-2~&b v% P~(xjL,2rQkC5e4Ha +;bW| @ް=~_yblDjZB/ݡ?zHO鈞ѷ4阎Y M%%^ь~3zMsZ"O EDΊ -i9)-o wϗNW0,Z ۵_w1`eݿfiNdx+c`b:8ҳ2~k&Hýl5|+_dkaaHՕtv0Uh"3m>R+Xл&(8r \bvaa ^:]\t 784arn|?Cܦ =Xm4u{WݷLO3O֧jBv2' 8ua]@f/?1e#7YX^^WW.TM'Z[xcVy33z|o윏\= ϡg;ituճf> S};֛վmX VZ6:^RWXc16}[;P P젡 WE_}/l;; ?#zHց-3}nWV5T\n0ڻjZ8 l_UG8uFٛL88x阄;S |m^qq+G(f6({jnqZë;n\YPRCsSٟj B"nf*Q<$o ׶{A Q՞vbf5>~ATr/ m|D#z#XZY=[Z(#duZ2B j$5ZhXu$ HvJum+ךHٔ_*%ZE/ʄ+ё]"F@_*Y(Ɛ1"`nƐQ~9~\]8A BqDW&ELZAk;H1xG&.@R&qO eT`7{u*E6cP*ۃVB8%Ԗ۠qyt*G/ey-ͫiqt4onq^W(0~y^I'wȂb~E C %ډx=f\Al:ehnFh$vɤQ.u( @8sw@NYY|;uݪ+0@(qc8f2еB#ü S2ݚ }D|V6Ԯ]Mđ&v[K#i}>/P\)/jendstream endobj 53 0 obj << /Subtype /XML /Type /Metadata /Length 1632 >> stream GPL Ghostscript 9.21 S4 methods, Brobdingnag, R 2018-08-10T13:21:37+12:00 2018-08-10T13:21:37+12:00 LaTeX with hyperref package Introducing package BrobdingnagRobin K. S. Hankin endstream endobj 54 0 obj << /Type /ObjStm /Length 2467 /Filter /FlateDecode /N 50 /First 395 >> stream xZkoܶ~EEME?hk{ZW}$v=ǮDyM("f gFk LXcR%xb&aZ;fѝXn D3gV3!5Lܴ˘Yc뙔`6aI\T$s)$I,:;,W8isi&fpc =K< ,53J0c</IR4 ^ O5AKA7^9YGc3Ɠ 4Z1wL1ֈ=j`SAb~iO(K?F1d#% &|qPA9Uں8$g:gXs/'$O3矻2^OcK5,GRl`Ycg<^}8[&tfM7 a3ewl/`Ie*]dȋb=n1?.̳W^ō~(HiƑ'r6rd`F. ϧlL򟃊H>(Dձ`F׸!o #C:rqfa\88Mz>0g7GilIOߥoS`yɋi|هl_(#P$J6e {X-D< 8%B-4o#189qm[J+Z۹s166)D1=u;mu?/ S~UIiXG=AOh@2Tr uG;_c5+(km9=K#E/L$CKv]VwkYFM^_`;5m\WxJj^rN<4vrPר9kI?@tY^!WgC]__|o|Zl^z0^KG~5V,AV! ]dX]ZI~~y@ؚqoj'BCw9W8-Ĩa#Ah/O9rЋt/(djY*]ϳZ>uOW ~,~m`fbL4FDww|"lڔ7mDŽk 5ܑڦ(ǯx6iEN(ZGpcҴQ=9'P>,0 $lPxp i#.ep5-6tI[4.ev@梟crt`1äLD a}d- JFTB!+'mEtOw$ 1Ҷ qJ7E LSbĿIlYL,"%Fh#aF!|Deo f$ٜ!mQb"*6P`ƻτX{s A\2E?sߤBB&L%!rg;lƳyq//l6]ŴwcuXo|Ncׄo /7'/iw٧9 e&9vk!Q|n`;}lxɃ&4KۋR\Go#Lb*j07Cp99]wu<"S$Ќ 5PP>L5;'ǻkM9$X<ԁQ`u³˾#򡜻r&Czދ]dz@2 N|ڕgQ:[m+;7A:S|˻t]#zTӋW5IRDiɋlXZBng74[T*I!Y-.m>.&Ŵ..cWl^t|AUSk?OMBvk?{j Ug7c`qPn'ޗAE tx:7܅od0J}U p-|u1u%#_f^X/!eAe MV.CNyL7Ul*cW.`_*GZhendstream endobj 105 0 obj << /Filter /FlateDecode /Length 5044 >> stream x[Yo$GrwTmk>ֆð]^v@æCIwyDVWRG_|Fzʨu݅n?l^]q6ڻ )RafUқgrJӛN&l])vgtUWG=QeNKVnkaEakq+;9do<=1= N2yyg '#QR[ިq7!lIٔ'Z:`?tny.3xJ{V ;]|ژm0QvTa \@Y'>+|&H9jc#Hڄ9( HFiQ\w8$6A{|ְU=n%66;g| @L$1t XH0f=6d4Wm-:}I;tjTV<}K{:_ح$جiV^ove{#͝">M< ޑ iP֚كl5FS ր(5ʋn28qY `Y{6ZtO3pVMk$mY/r85̃މݰj-8t<|!Iiviʿ^$#|b%sٞ)<}Sc:sd%QLG.|=)({n}~|3XJ\ htAOhm |@ZEY+ cяJc©HIW#'= ʁ29LI.QaehdB N (o]rDX)F\ W)j#q-mO W2 ll]`Ɏ#]EFQ݈ث "g)d dC%D߭c 鴰B(O۶UI0sѿ(C;f ej (17%J@;_@?|12٥,k5Bp G,Hĸ Y{5Kh2KȕDf X+.)<#.f_o Jփ&mp S1Cd\A٧̘dg1\ KlGiZī_Wwa`a 9Auٝ&  QRf\vh{K.A;frUL_Q*d>Iy6)Q 1b ?P>o;GmyC<o6W d@Ncu-v*kk匡wtJ !l:5a0S$}9u=}`ۄ"B c!.E\!(ZTng66zn ~ o(ن[WRfp^#޻.70qApl΢WP,)bևE sSqGp[Հ7ż'î!' j5G2Ve>)2bT,È߯.f1_x՜nA+Ć,EX<4IT)LPUګr̲,jf+F5+|[#EWf8 W3n@{aTKt(q@y~bQD-m5sq@ZYF(w#HXkU #W`5Dү ٿjZeVr% >e ʀCR󌈌URb/;tA'*#22ߢ+¯; |oYKфKTw 2-!C*Aztc z` ? -]VѽqHሊٟ\d/5Yħp`qLˮiqd.,< W'^==3d Ye%DLlf Ja40U)AEk 3%XCBuԀmyI KQRaD 8-@ fސIq`knv B9 Bw+xcG1`NJ]#0 YfIE nmjHՙONƁ%Krh6Ea<4,VlJX/]R)&;fWY7>QQHC~A=P),lSƈmJZ9Y`/$0YϞ 3gT!ˎ 7Kp)W|4l-?ijЋwk$< EeN,URRjUP`3rK0 DA3`$(G< S~qY[$^b!S.IA^O&fowCnH gFD%F[hg Jea@])lNu6)?>a enG 1|+9~K*9v?Ok9BM2Zfӯ]]gsϺ2[hK}OyYT&`Br.rw^hɖ+5ǡܠxmZQaX&Bu_Zu\b(&$z s_cE*TZ/CVI(?!ptCQ銮 %M&ToD^#H=, VĄy̗eT ZlIjLTn}ar4,FĐ~7 )E NgCg5Vi3-7u$,ҫmd&׊ڽKƘ / *@<%6D 3Se աb@ӝɦ ) -lӺZp ^=[8N{#ٸ02zٮC/k'ݧ^o7SFvt=tfFVH3 F7-Ȋ/Yԥ" 6/ɲ(||d2uqg1g#)PX8^(55 BIm"!BRK%n,H@h7@fq6B ,Tk0(k9$(K^y"YI&#ۄ>6VE>q Mo["4j{Nfa%:HSBklϴ}~y~nLaէbby7hHXF]rL˳,$Ɔ.wީ=zPyd C*(Nq0!}Ny`ٞެZH{ͪl]}IvkEPl +̑ŃQj_EMP͂v%7_juARqrS"sySr4@x."hH bG/yeI6hj2`CUz`~.CPgaZ5Hs~?411)&u{0i: %85s\;#Ѣŀ@]PuE~)Z3>lI-zee~].[ƒlx2PcNDo}"(0w! R>"O3f7LۿZjKd/ i)t3Dz:)%wSOGsPj:*Vt- ta&F,#lK'#/kC2] +!Ϧ% kל4^7޽ۓ.c;G.6"*Oo٫%]>ɟYW>Ofendstream endobj 106 0 obj << /Filter /FlateDecode /Length 3687 >> stream x[Yo$~WyK}8A8H8B^|4XR;+{׆{Xf]M*UFr#_s%6 ~?O/q>(7QE&>:X~y}EmP} Ju7۝Dmj C2Nka{URhBnh{*t t']Tp(|\㎸ur#.1z;dež4fD[ 6΋?!};)v$:FuPaI-c\;}*{ {<o C-#/@ĊY2FQ:j EP9J)*hd?Rp-.βmv9"OpcFt1i@waO\-io#+L(lw:Y|N ݥk/u wpB"FI #lkp >󝙽 [8'v.46X@Y\D@Ei0aVBķT\Cg#$8q%$,$3^aw$I}_u] 'v'IðH qV,@ۿ=/: -?q&T'^2ZĜ  yMk"Ѕ6BO| hu"x7N5 hOP8!w -a$dcɔApB$ boZz 6u$Z+ 0;2f5cΚ$g]b5 Rv3ɇW[QOjQk~0c8C䌮̿4C _6=^M=P0RP*>m V/)Ut;TD6Y#Z&Y'b169|2o.x,ôPfwe>7wؗaqE+c>-+n~T7e GRv>e _QE/ V:ȰG_T.9Sg+^f#٩SX”⿙m/0Kj9=68TBY_W)7eԦZaߜY<!P4wul$m<6W*6D{V Sy0ي0cN( gȵ%u'Pʱ)|icUwexնp.`څ@)f+'S #B89  qyLy;¦v_2wygod04n댜(闀Xz fiB<]$&a y&m˯G y'+&oWq̛T3@+0 f'u"m]3,)i$eJoe%n,4crBRv.&td MU81Luۗ3{\b%toD>fnyH+|2*Q2iy QHp֋fa)X'BՑ®embtr%&_CԀjwHu/BMa|*#c%.z!dͫ4%n,S#}L5T2@&| ϐDv:bOA) Թh[pq hvE!>Jpp)%z!Qa܅ũ||P-7TB֍dVRcYi>W6Oz*蹢 lv9pArH 󫓫(ټ̍x?!^>ZVh68v*81dݏ0E"$_w6 `'N\q2?o-TY4U̺cTuYtTÒn┶RUD eJk˸3+{V/"Z?pCһ98oaNt @ i|WϞ}5ߦ$3\gO?T*VpcpI%^2=φ@1P.aUtM=i)pe8e)ٞ,7 Y$QQ? OJim)Q 5~Ir0LB˗~X}(FCܫ&B8O?߱f.C1bM+]7 \T'6.Clwob?#&'Nj%f n=K%{/6RRg$OcӛL%|_t.z«G}m\lvCqJ{ b-襤+-qh6LcF!x 49B4oK[h-{l"+oZ/72B*x9[^-uE_WwCz׹~ϯ쪮WnX7LYU-ʕSa/뚭vw X}/wnKҹ^`Et;cq%`j)|X&bbfUzؑ" &'8dC]%"bw No@]VLv>6Z)k&-jF^"5@=͚_uvï>:^b1P*4Նy{Cb ^Uq^1° g32|` :$pIS]U,t Svim8gb]H& K zJeA$5[yY]Ln♞E^kj߂KU숤%O*hˋ¿Ƣsendstream endobj 107 0 obj << /Filter /FlateDecode /Length 6002 >> stream x\[qxG}l"A$DZlxC[\ꐔD?_uLWΜ 9鮮WNz?QwK2Ye|vn9c~wUN.ojtZ?ch! /k~:FzhƘs̏1Ǘx&M0z){YAt(6!IW_vf+`BmƎJ98?eʃnçO=%^\mI݆j4ڄ U:Rաήn:o6bL;6|o O/4OX]ݗY%*ox~ :])YSJYWl3s aS:I͞<ȣ \߆o3ɪ4& ]?㣘aa8>Wl. ^ : ߊ/2om_G$xuHM4> D2lrDږ~U8 81ATV`<1uFWVƴ=!;MΉv{̈́,VHV,xd%:nM"1?o©2qشIBr 7ONaQNUyMq@\x=锪u'm";w>L+4b pd68u>J)s8{H_w`EfB0E!!3Z['xH`E).@7m+~5(2!V&AKȲWd)MJq4fñRL &>|"D%} ?{֩a)± }WEƎ:rX`VY_ :oNAˉUK5}sbF;^"o;iϦ>lnLrDy;6]6xק@^3"O1z4G-c7 7ꢿ.gZp 6<}G.lT{]mŚ2dgka3nt! 6E[*Mauf*!_ -E\;r# 4=| WVe.ĉa5[ mH'rI_lQE,'c᳆k1ߑ<8H$e_(:=2>@Nt#v1U c!<)|m٫W|x~dB"BʚӔeہg)&yu#VeURhƀ"zy_.oKu<(rxzxzydt 7 y_JNcmg l{z5gbR7-+3sʧY]EiKGZ\;ztY1yɱ`Efנȼt&]Miݪ5/kȢ3}X(j&t*' "\m&JvgBB<|P ޥXvTRw <ٝ\R_ThXg\qe"9]|,uDP0utö3BZ6LgQ!Y3v@ MY${JVAG!w$UAuQ_x 6eG>/l.QoTP:*LZ 7*Ey4$@)òm^}E^ >\R9$*~XTJ\a& ge(2={dp3 ?XpPЂ8Dg*\R4<'>q {v~h%&d}H;I^,G/tHPyIhGd*.hzz6VBb<~ww kCJV_܅s0JڻQg(ј03'/ITc܅ ]pi&w^zŤ~Av5΋)KnFMKEu[R7Taf Q')-Ǖ>9 2!k򍪆&a+evUzx:sp_4~U5q{[ MŜ.9߰ad P^.&LԔCǥ`Q_X&ĝjEPMaL'{i~H惟T*"iݠevZ= jt k: 6uGq+åY=O3JeKtҺφ ⫟˥C԰wIQf N԰䊜r n1GgtYN{E~\ݕae-wZ̴֘]414*ާs aE|ܦRt9}fJ~sa/ł~B~sնZPrH2A_;Ҟpzdv]偞BUӖl/SŸN 1{.SFc,L蜉<$C~TTt]wbwVe/+ 6+yJ`|W2:;L٪rqUtU,bdT^\3)Jڕ 4|" e/ wBfU Uy.䈲δ aD)o& t63Zq^i?q/s3hlYE jz~Vk^+$𔛖.'\1`GL3ឹ"2gBHGgwYS $"WGgRy.=nl}<9Rptj=V%7n+71\=6\5}CP[\qn)%Rjw,?aD"RO05.GʸXƉ]QYDӨ/Yߌ a2XEɌ.,H $N5ut0ciIm}BCe n)%|.dZq W]ɧ`:(H>Mf YQAjpذs0hC}).I-z;@u#0d#DkB ܉u;>5 XbF"HL'B~uaN߽Q󓛋6KvD9)J`[J?DKwS1!LH"ѳE^` )1Bĥ\"KR=; HZ@+y=eSv7 cB;' 'l4b&H|r.o13OHe<{BhJQCbңDܺư-B&%MUhNtw2&Jaj@u{8xyi*ĹJѝ:i$YCpan~xcBt ]`;z [:E\1X+wgQ(3(Z#%px{ͳ=Ȇ}qRhS6DY2Sv6&5ܽ}VL6E >3L65BWC" n=~ۈyپzzJ$PS΃KQ\qͷwSʱd%gIլ楉rei^H;Z/vx2,ʥ؊ܹU-~qCvw˄{rn),(͘r Omd?_ _#.߼iCqgG^,diF#+_`[g׍g )ˋӝW fT '.){JգL/6曘GCEvȍ(\b }-PH>8uS^?ڒuP5jqdS]<7u8/w-:ԯƂv)8 8[PwgG/*ǯMmv=Ukә km-Ϗ޳HtN=6]<ǜǷ̀d3PUu3K苊UY9jԢ<ڷ>+[Ͱ-7 ]X^rغ[#zzw.7,W}[2o\9u7:Yu3z쨢Y$x V^r 3t2O([M ȩ;=^9nBRuքYX-&wtxCSÌWԢ>iy5qs@X62)` (˴K,B_gj2{JM2 Zr:4A=ҩ2?t^[@x?Dx\ z <\Wħ.͜Gxo[4%aQ=6]tT_mm~8da ԥ?3}Pne/:`yX~FzjѾyaYG¥jTK/.T; K+)g.2\)=5K_al)=7P*)-$Y6JiHX0QS\ -z+7бi7uQL~/ W{MN˥_KWSBIeT]d  S(/BJ ZvƋfd L"Z\Ex~iի'Qtx~Enak{7ndE$ꃊN9t,:M0AX\W3GE\5pX7|sL?.v2pջ#q~rיU;2m7P"O`4Z-ڥ. M =bLAFu 7el@U7Ul 4l&)H& MHEw*ҽBеz;rZvU{Qi4\gR- t廨xO5f ^Є Gd" 'O2Q[S`H%OSW'vXr9OaS*p#gP%uJ~33gJ`Bg1ֺ `fD:v߭#r+RU+ 2@v!?\M:|ۆ/ mwlWmxZr?e O=eȹhd8Y ;K>m)Q +߃rn¤ Z[M،q,r ZO8a<&vsN x.]P` ƨzNmT@|m8O)*diJ(y+1mX%DrꎵK a(9r(WF5R +mLq[3kK> stream x[[s~gX-O e%DZ؊"SJ0"-n|8&hS4p|;ۡʿ'O^u>@ӯ埓G#“>0c?<b﨔Kl v`|.aFwoVkl4Nrk6Nw}1=,f*ڹaMHΓpO!Hh#J3*&Æ uc'q]N5vvҩS-a;X4@,Y=bK|l2~CVÑDƃ \ /Ĺ>&'] gIx< `gIk$hQۻ嶰-NݬPaOOIJ)_*^!y;EPřq6R)cݱj*E4hpw@K8 86õwiHl%r0vI@=$D]C$^J'O{:I*Ҏ Q,+5mz%F8mc vZyD5)% kҮsh _mA<&}Qk$Pn*B_x,/oFཏS803.BYKs Ml|{+<<5@!ENE~{rxzDY!)=,ARyGOY2C:46h8JM8ܙ+`vBVqtAa3"j2aM&;| M%MOy! mtIP,)K56,y픃HQI3⹴T7p|,Eg'a[As(\pSw7m `첥L:'@VRmEi6)\p=%V &fw]u^ (:>Nɰ|ã2-I'qc|Y)\ AMNwdg2%LGsvވ)")+De^%N >*P: ZunHFrggu0fL %ݖ Fޔ}'D4Ҵ患ZYul$w|ԑ|Y"{ON}p?uV/.(TD g ,e6xa;lJGfyr_]"IDN':M쵾g{Ոc<ւ=yf%(z o.s;+vbb~ wܓ'OSc t+x5߉ų?*{Wm#![qJi` ?} gB`a|9f?g3LuQhUಲfgcFYx#+x(V{0VE<߯"6rhℒ66׮SC=paSqy!+gȬ}݊Hbl;-oifs\[f qz X+5Dh仯=<kcu.n+ @ƫ?0^Lц׏ז{i1WwF4uF"gZh ֟MdpǂP}w9{|sJ; ~7.ܮ朥v6%rUA;UEnΟ|Ѐ{J|7k?VldAsLmp\4*'nqv[?@\䴚SRr7;2S OpUůi>:F˩R&p냳vw eҐ|ZOfjnjcmv5 t΃emp:_]_TB&Q'FpW_WEυzXhNQЫ~#?Q6֦MUlytm ʪ̎fg}l;67 gGp~zr x*؇q-af`# :#.fԆP&"=&}>`zspMa#&|,b ?-  LF5e11Df`nZjkDž{F¯cd{[9G银#%Ns1gpMv/\jNC"yǃ=7fO>QLUfo(GZLa~Xq%,9ڋ`т! T1L~X:]5P3B$Ҁ>ezL&nH$20#$zhCCzDlݡZPc0ĹR$எz"]W*:$o&/NkoKZ`'Nf9:)%)#S0RMV^w[yٯiq+E\GD$}[- 9۩y)MH{iNvHWxf :d4Ud vq9gLn} :æp|v)s(׶k>a̼ΞLD_C-U;XzRUһ[_aǯFt@:_J}&`)Y7tZ!_.#cj^:o}2ԻOULBTeu>RpbJ:gbfϔXV%b;a` $@)xT_n~nZr{P|Vmj.N+=^>q%Ϛ^`pz Ⴜmiϫ@p21Mzw2Ƹq\]j-_k{}$X}(Qx !A` @vx**h{HX_=UC-B1OWM>5r}%abxRJ8E`,_ {[kH2܆UK\-!LԜ-A#^"J^Ʀk-\2,z5Z]osDFMcBŗ$ɁFZ%{X> 6g;v9OU<42Y2Le yY E4Iendstream endobj 109 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3648 >> stream xW TS־1$Vz/Vq@uաT(uhqH$S!@MPI0 QD 8!է}ZVI[7}kde8瞳ϷeF&^K7j.I/ ˁl}bVgF,]<9#8Kϗ+ϣa?eXGĮ;9ϟ?wnn󝗄DP;{c1GOĎoZ7K=+"*i3cDDi=#cV8:k#"lWlL@W@T80Gx슊YR:/aN>!_=g,GyYx3uld3K̻d3 f6ìaHf3a EcҘedgR -((*s&օ5}8tϴ0,aCÍc7#t{`A7Z&m絕lmy6(]R0~WV6 8==4)?!nWTc/A Kg䎔#G:$YhUE7P2܆2t}@xx- 8DIf*T/=Ul =1EF#Ei%t.Uk5\jǹ> dE2+s<1u j 9 (?ˮ8sz_I8\D2fB p`)d]VCc>&3xO|GYp8p2 qޛBvX)S)? ܧyJUs"Ttß?C4nH̻ݛN+ɼ?z:=7͡nZedm1\.-⫠ )KIB.M(ߙ\ŗl!ۜ3ڣ@ͽk{#jCn4 ƃcAB%8Kd9R;hub8}zL(_erS6A^-JGU~`c$ >jaԩ:/I3;f̕k]g =MʰеpVp|,ŵN1xȭ#2\ t8CBzD* |dab?C+?C lBK7|$mo/\SZY)_ZJ\^Z8*Jve`wH=΢ O5S p\%v*tAYĶ%ˌ~ 8,;Dm O~L&ꖄFS[rw`.*.vwU2{;!w:ŝAVA)5P_74s/#R VZ\.8Yصz=l0XQ`kp 3o?>@Z=ِ *-&n9GF̏i(eSqiᾯlVP!T1hU)[KZLe~9좖ox2nd=)Z}灳7A rO@NeЉd(K^&i2AȁeYwNMNul \9 iܦhѦhM.G7?U-8J:[hXr)%ih0f ]+\#g;qt9}`D.% 87 x.%/}Sнɷ%guVmo7io=!;}J^s!#On8g{TQY]JjƗp13b#p}!q}siW{g m4`zRћ ΐ!ދ2{t:iي-Sf=-hJS#`3ҼAf 'g JȋU`x "֛)6٣GGd⯴6m48ǒK6nN䵒:]fNVvLVH#>.=cҚJNdR4pqLM3C 'B&Ѣcs=苰?a0YYd +)\ELJoz8Ӳu Z!}O*=VWh(r(Bxo6"v,Io//[ 3`Ɨٗ>9R4[oA˳tU0r|`eF=KVkWU)CO~{)_CDi/=Gn :7 «:;)=S(*Zbu2z37Zj[M;CM{={LZpJ$a$.=Cni(÷VQ~EULYwW5CWm8}qmnw'D$v{4@釶! H}>gg@ 9|\ 'eZKK=Q zHJHoZ %X4 9VA)' FNc 0~~У c>yʳ %UQi[H9dRKE}Q{q+5 )l>d>XvzɯI AL&ɿU?$>F;7K_f}nT$ U}Ui+Z"y%ZZQ6L[0Pj:82HFendstream endobj 110 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1621 >> stream xe{PSW%{ڭwtz],vXm*"!$< %̙[@nJ*'='1qt+4j PYJ`eB}_xKv P&l@ +[y\}T𤘤py=[uvf2}&`RВJ[mͳ閊\%{+< Dp z3#BUy $,A75tC-N?Da;?8r~+dN{?P?P. ۞>RQ&t,OcpT#3T?CZOfv ZJ4=I#/WL‹CL#/׹Nh-:rl55klY|W;U㯝= )lʮ7>䏞r+ u69r93S-ǏMpZDt~pa]SN5>`g?uv~y<;n`nQ u~ w9_QU@$ w)X(#euo7LAQ7;yqh@OB*(L>5k<~ϐ䧸1\[>N#0*(Ze %-MKaz qn瓕 1<彃C]C%'v'-!/ד1d_ {ǥv8vU9cpX"νTḇ0W~‹xj$%Roca'tfl'FO |Z!ߚyP.e԰K#4F9f<I߆ѓ}#BCr6]I%n<W5bps?|~ k.dy1;^=bnyH0sU|.@wsybZ;w=mStTtt{rzk4%ݩ 5y`*׾тum?&`'1Ma}Re@j|NTr3Ehf.B\ÍH ¿u^O{G./)\0W?!U i-jm&&gePFBÜ27dEendstream endobj 111 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 7680 >> stream xztaL` @轘^ ݸ7n ۲ʑދ,[.6Ʀ8!@  @B{ @JI4wsg+ ](@ |q]wXZޖh{άwc.BO!g0ގ_\ߢA`Xܠ>G86mh Ms5qkgk8y&}gx>~DDX׀A#qggNOA+\<-ky, u\HQԊفs6 2?tAE;D.t[` 'MRw{jNFP멑jC6Qs1fj5BͧާP㨅xjH-&QK2j J>(%R,6A.՟@ 8vPݨTO*ERT՛#.A9Q])@.a7aaWaה&HKOKL e*zKksm齬<ߺgHmv~}GMbo7/c@C_<N;UIOdcA%;x琾CF xkCK-╶m`BLbmܶMSe@ ()qؽ{Ԍ?]ٯjGz1ћB:MF+9 c4 k ua/CfyIqZl6X*[4K vy ꂞ&EFuJ c}"e/N;n5 Ի{`+կ9=h9#ƃd6۶$+ d$wЩs("5]h[uS/< %٧%\{r5[^N_zdsa@rxo]\r|}DΪZ @+韚.aP-qAC,;BPDb`gv; =gxC-VlaE%p0ʷ Lt6,rW?҆hH<^!i/F$gJ9 [5Zb+Ȕ /=@w/]"{kKP4%X(Ah6/m ޯ.Oh V?" b!#^]j. qϨms 9m()] CP@BiW#A;x"N݊כhj{u'~f=4jFƥ D|ݧb{4 q:E4#]%3%Bp꣇sDl{͟:S,+ IqR;τum3YrQx"Bh5R^+P> ң̚ 3 #7G^_HcnTHw HRsiUُ`fH6=Đ<]jFY< iX|_30sV<@4qΕ͓M'\;mB{hوFuF!x؄B9x0ء6)#*MƣdʵXEAHj~Nyuս~k#-XbEFM A w'=[S/Ac i|S# *5skjsks{QvRQGf ֈl7bQ*u(M*hȫ =΀MF`\S9- Zc'(I?ֳlq1䷑2O xH`{:s4Nmq׃RgЗ_ ؝+t$&gQީuMPZNEɃڥ !S*v%*UnKghOaPT"~PR%:(5%QעSϲy}9dAf͡SӾ ^ w:u2/RZ܂bqb%aVjx'`W&hD{nVp^fD(Ȅ> ~懲h ABEi#[\MO/U]:ǝ ]Kqֆ 1Yp@ȷzm5$Q&B Uq=NyMP-5B]&AFOpMk)o5wwE}>H#e%/_#datS>%OtQyI!އȣ5b;->bʫ3%%aI!i#aի QT)ppTUte#3UaQ5@*;>M9؏F\<(`ۺ*s>-Nd΃6=-gTo79ΚmB~25_Mpc7l{k 0goINWeir<7nf芪b}EnJVpq+OzLx6*+\Cá}%-L2Fcf#6A !?ʢEhvf汣4&:DG a >uz8$B̮]IfW|| ?'[d-+ԋU15"_'ڏ=Z t֤jhV[}T`=73ey1|Ya@lCzwgQj".C ȫlՋE;ܖEPڟi&3/hte@e۝c*d %)l!t9H^~IɪWKh=Nfurj?mO2FAlDjer̂%A/dxQu!G$5e RtGTMw`]1,ѱ[i4췞yt`u{ Y,q82#caPiWJd[I\7IyꃥljP4ǚD}FnXOض lbZIuRHO*QDhԩr~tS:|(JhyAެ_ج8KgV9;2&+Jcш=<$8q'jD)aPGB0H20D’$mJJ|] w7|硞D],hZ! 兰=fv VņJƒ RHԤ,Ʌ bB${ӊS)2H` K2ʊj<"\nkN  >v1xwJc|Qipܟ"[nWD/C/u M { ;N 4Bb=XR`BߙTpqdЋܶ-\j =f@&;2#5⇊~(bQ. ekekACU]!.y>-~3?`]<_ﳕNhZBvXKɳSn`ݮJx$&%y>Q=iunsw[eW?A,v4E3M5r"GuiZHkN5A`CXZC:R6DE9չ$!sޞ}M <)\G99%jߒdgu@[2 N9׃%9 U^!DyN vx=^2fh9htc>揨D|-=UORrt0KV\r\L/s^Fr-amC^WχJ"JDɫ{Djخa偁aaaĞzO+EFemcۦHKhXfJ p`b EMp{MLӃ!;@Ao>l94K,xu^ QjvUnاާ(/s^Լ"*gR@ ǰ-WkS҉Jt:;fm{*!8k(Qg "mfR"AL?ak3 [ h3nD9ϟ^4LnO! 12] [E|`wB6Qy!߶]-$FF~*杗 "mMf*t-VuiKIJJkx<2Vu m lfOb_gD)ii-^u<yR͸s9Ts ,~&|=$FPX K;ZK&|2$pd=ǫSUd} *, \hAvuI(\o|{,i'28ݿ*z!6{]nWdi|==S0L`:+B֗-m8|D203h` ȣs~~}p9 $x#|2Y?b˗?쎼D.>K|}CĶf]Q]nSETO J yimvž2 siQC\oJ@ˮń栤UD0 us]3:9ĘBKv婋p=Ĩf:5DV#˙ϫSժIPu:L Id5b2YqDlU.dL}>0/eܓHl=zΑGeׇZxWk$h;4gs;Jc3Kvi$=&Qi>ħw "JRl,.?eݑPuh+zL{-c|9kkH}Q^2-Ye$"qs"pΥI:4 b$0IZ]z*SpqkfT61D\t"cyy7'y #QWW<ͦD^բRK??{:vz}~v:ZF~s-$$*4EZΝoPw?Yf?Σ}0%ۑ=ŖİUYź6XC.|dH _c=b=AF։'}!xm * N Z&<{Xxb/H ക4f K/ N,Wl U b7ruYgr3үCH3 _,wI:4|4xjY[<ԫ[|ޫDD@dkq-YHDމ R|Lk$Z> stream x LSWB{ŢD Cs>' B"\[S?lq]Ԫ 0%"A dP0:.Y!_9_9:`8;FlX>yŭ Pc3C3C3@@<'7W+D(fFl&T!MGbϓgV҄x9JIJx~Ic6*b6X!aKU*W,KؓQIY A)PpedJ`L"Q!0l_,r}}Ql shL9[bZÍAhqh  Y t&LO S WIEjOZk?sv=֢N"YT$\ǂ_@ B[)b> stream xuUip^Y>ji̱q )g܄Ber,ɒllI}Yƶe9K]` m3! g5鏝ݝw}ef`</huSKxe|`} ] [֛g K^a|OQ^P6*񊲕W_Y@F*+J5RIM{y_|@QV%4Wlj4Mkj555 U+WUxD-QKrxwiD<tܭPQHT"ED%0lV] %U^ۄa?`A-lv[mvbb kĢü/23BƬʜ[MDǒ_Dxh;S/Z&>H:4 S0=ANjj! A/+Qf9LiFB 9nGTDFh)o"wlp5A^3XFm!DGAn OZwW;xEHaSg#tgy㎺| ՙWO+dEGKH a'%_(n8 xS{  3ue4qx4M'4{4!nE. )CaR4/K<ࣟ}.46s0@CzHt/s-V"ɾL>G:yV;E 9訖6Wl.փ ̴hn\hg MԒ|®:\1LklVT_m]L\2^2AVտSK|hshZ01o ~_+]{l/$yy)qTw;]}iG&]aEh`H5p[Ѵq ԩϓ$y.5ФQN6$4MT|D#chaC2yebt? fnxr'BhwZgFw>T|2p ݸuP Y!My$c[@5ef1;%nG /1osIR N-mv̐%g-'ع [/F&hP@8;𥎩Kh%EgrVy5%v܊p9Ûp0r$B#Wf R0٬6R&ޮyp3;'AsQ? ;N{h2R2S6ۭ9mCP6b3gTO[@8[kq>uMf cYS&*l7>raFbD}6" "ln#ry6?ό)10Hɠއ|5 p1{s}yəm,la__|zj o9I7d|#V#V{śK-2^5`ml'F Rdz]?wDt^zi,v ;9~9MS~#U. o}ꕻX>1C.Mvbq!lPܩei:"~3}n  -EQZIՐ.Lj:+:OeP0_ݽVfV[L .!@^SQ1-+iU etNAiڮ*#lN-yU)S>:8%LcrZ-ԉD, uL0@5L6[I{̍yqOn.=_endstream endobj 114 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4675 >> stream xX XSֽ!psUNTlZ֊3(Z(*H0vQd LXqCq|SV[ow'B䜳^{u"aD">ry5ty;g;MOlk8~T"Q$Unת|j[O1f;x|xڻz^j:_ڏP;Nh&xOPgoQ+ݼT^[(K=;:i2`{Ke dfSrvU:Dy֥^ۼn>~&GM`p9zmxD,c>ec3+wf%Ya2sy|f"Y,b) Y¸2K;Fx0y b3C;L'.Ӌ2>L_ӟYL83֌M2]Re5*N:T&:ƦNVʮa͒^qX㷞n=Z+CӣOp}~=Ndv:8sv pw21_F4ݖ1JdC D@tP!I\@ ӀX/Ɩր@٢*ݝ3&SLJH\sg$&2m[F'&t7 |=l*PGIƮNau*7|V~NW.f}˼ϋd9[k{7b8oao8 bzxZD-p PjlFTFh˝xeQn#Οtw n<_Jr;<>I.辪!|߄ E.EJ { 1Y].ʿ'K#+6RP(&]#g ,AH\]3b8P OaФ23\U}ݏJiudăwD%ꄍ!bzᏢDW ٶa]TBr]A) T#E6Pߘ'4{US&("|_f'K.5H,O6IQefyTS;l Xf|J(ve7nn+Rojhnwaz^W ]g +6Dö#̟7 X.\v) kՖhv FI9Vj@c-V$2VLT%b3IewTEi^J٥8 nlHJ"pjR<*Yms=:\{D<<^'AsŞd4Glz{t'{طQt~f-5^hD7Iq.,V P)ț=hV]w@ ܣjk«Ҽ;+*ϫ)[Y1bdpϛ=mSoA('LlD|HPrc<`!rS_,8E?'=&7MhHH$ɏO5@dgď}Hqn}A,̅ L8{ӨRng]`Oo,@QHQ 5aw߄&O2?k#c8Ew?#4q>Cz d~wvQan$E_V~m;P, (+ ܥSwA[M@cg.AN|S.]C_=VsJzƄOtg+fYW)!!JeYHuuYYIѼϲ6ؾ 'o؉ozp Rl1iitlZ] )4h l/쨖^ZZ,ҝc_4tmd42_tpK_E}ͫLw7(&vZޟ}>FISo"|nVwu{Y'1uבR/Vwh' t#Zq\(75o*wH,5Uoa9%Yfd'lު")}SoL%$ ^Vdž"RCuT%MYd] ݡM1I>'$%C_ >bf֋UH<{O7r Cۑ7Isi۪cJˋwg ǎם7lE:SxkU-PN*A#|92U[ W,Qz:.ILXtGQ'{(Pp =Y`}'Vi]&0"z펴-k-Hxo_}ݘ5VF,'LIZ\!_Js V8|j+8lx"̠RDM~V>z,ȟk;51{$5WP"=)||4@& In+}/ؽ9> h 8ې[`ĩFmLJ7֚ ؘ9C7LjMIL ̝9žstG}\sVICɦ֨ C#N;Q*lS*7 ZgbTj|>Ý c3_hbMUoc=nM< s~Fӻh6b%ͫaufI[5F]Vj.H8i;<5[WDɿ>ic#s] 8%>d;+. |v؈CqZs6Pk>&z d_Twf k&w,'X9G[Nֹu\7sqw"3ݎ6H:;t񧳇}<ݣOn\p*fz~sx-Yy1hFiuF߲=HGxևfdffAW54~ D?csd?9 6q q7_mvZ)|PKA2$gD@%]?rJlH+7:N_FymzH؇ FwT+!.<DW3ca8_--zϋ;{厎n,<, 5%/aKW v̓櫁£}xH bruzQUpoP>2eΦɀ-77J ΅wN s)*W0X ە;QDɧ4&1: 4w@A]:Cxݻ֤~khw s@XO@n}}v?h4Wh y Р l4(p2LC_* Oad8:91hϾ|f8w-Nw;wOU]_eQ.Kϕb9@KAr<^jxٗ.pőE$*G/HHH-7edv҄S^$oӦ^!)M* +>ss],fˌ=MZmɶ77&jeendstream endobj 115 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3229 >> stream xWyTSg޾1p{ vTkAǵ*ŅC]B %$!!d/$v"ŭU*)V\Nc|S[i:gTLsC {߳6p8);''$3q) $b>ys,fݚ) _F(. kS9^xxpJD~H'L5;!yٲ%s$%-KXge%f rxBMaN~V~P0kEPX|L^i"_j܄|a^ŽAyNvF~0L^NcI˄9T~vðE%RaYfC KV5{μ}Möa۱N,= [e`)zl{ ۄmRo}X6l<Eclaag=gp܆qw׆OqH$l#Z/;21Ry>*3J5O>-f /9L qI ((jný #p yWQh j.)>m̤c'…^W{s8e,R*zKyc q"Ocp8zgs xfQ~=)3ntp ~ײT5}sR8U^ rn_ :H<D#M_ #4 ^r՟n|y[5-94 pXΒAw@að5Wv-,[;L-|2%*Sp,$sAeAPv`tgs~{ī)K^x ON淤 LTZ$:~%%LzEv=\?y(7|WUAQ{ċQ̂8,xן59VlRI-7bD$H.3Í{-qVhXNa9"%sUbÌج7ohK^yg:vLEձ$m)'$f".XY}~*`9 yDk Zh{oڎS#shoG:@*2z*_+έ(>XWs[FXyLi6|e5F:iƶ»1c]4  }89$pO;;T?˜!W8CspQa3CjY7KjbSM|iFngG|e*!t+܂2J9bK`,\]@ z*w]wb"؍^;udH{~jnC~hhPgg3 =O9{Kz-P!_e~9_ujK5v7-]ᥑbaL9`7IvypܣQY go /UW%wWf"uU}~ltU@|ʀN|S8b(DŽ67 Ns3`:pr{o-Z?K& ur|b( =Kut \! Y AcFʻ$'q{-GwxzEuoho!T%|G n\oQCW SRp^:PFlNb'` cK=Ὡ^7䜴c>OVqذuzVʮ/ew -~/(uvRhC#&M0^qQHOs3)nh(p4#Gs8\i,H*\$kST}6>\>wARYh5onC%. /_šq *onu\ |A@|q(bqχvIZ 7^`aK:ti1a30LL[1$f[.==8@V %2BHW$Z#by9x8KmqT&e"ͦΎRzhƐ~(9Cj3@Ђ*D5Q v[&f7yYc6Mf;p>R \%SX+ɔYlCjgyg`ĤvWjuj =Dre G9q:/䫱)-4r-ᣣj`3XgnvMIrR&jmj:ZQ|0Y!L?/beX{k2kp0V܄[jt<ӲB#BZ ZMvzt]v<&T7UܗBU.`U#փ(ߪ4 %^+~fRf3hڥ N%PfXkܢ:OMЄV;@ ˪*DR^I߆"TUrPT6;mf1RWxm`w +@Cϫ*,́'&zzFqYLk\&OJ!jB*48J"Bo鲚#惡={*,rpCX<'rᭋd=/? ;zWK? 8ḋ?ǐƚQ쭬TjnVʴ*P/T55]Nk:y9.wo 3$$@t4ف2QG `:O!I}{{pJd4'ΠgpHsMH6C7D ]kh6^![=*rm5SFHQA/[|| . T7 v2hy‫^lOERD 7endstream endobj 116 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3225 >> stream xWipSW~Bxc2X!SMHqI:vtxlɫE^[7Ym[8aHBҝrtvt+uyjz~PITs|W@#=i7-pZpW3c''?t< !.&ÉK?(aB(i)EUzBΓ֢BloJ.K4q+HUQKe{r䥅AD 1, . cƞh~\LZg]x3.ww:.~,*g& I|n!Ң?;+ط[\4(kI"52a` B&a\ g855r=Ρ3gO"C@8\C7_I^ {@ŸST׎k:$ nMBI46>)tꚐs# x9$HГR܄$/{ NM::1j&vPW1h[p Q9N}>᧚2&DKQZ|zsځr6K3jcvW_cG56q}7{$|y^6)UGsn"5F7b1KjJ=&H) Ϳel^RkD/9K'o}$3P*`l CŽ98X#,mq%q]rkm`;: jz>S~W]ݭ!ir=%/>qh_Zd20Vk?@ itXN-NgP^3TuP~ozcZ#Y~uu`{9'XFt P<`#c1Z!^! ݱ:U(U|u5ӆpxS|AںC:Gd@`T0 f"™ 9hOS7m\峳.CXt^;wq헌 ? b,P0J[J:?Ia-ph@SDlA>0PK-$ץA%7|_K2Ihm,J6G'ܾzg N*'gaA?$DSym_k}G/}M,è3qh$բmkCU=hO5D$ГbK1Ӫ7*j}]Ƴ5؋t۹vi@?XRJ#B@:θbh57-H>g>=n}S3pf fج2+y@-?Zj<;@ySsψ껗^VRlUB19XLX8SXU[o0Qw {SkZ.E[FS21o;ZK$ۡ7Y- @>kF9z#m~ o cGggwE}he!%nS zMC9G*TUS\sOۊ۵ φWAѦnV:;Vbjil(,@~{sF>O~Ƕf2]c w wn޲MCUV[8qޖ^ >!yƴ'yPk|CagYգߋ!&z?&Dg~Yqȏ!O,/B`sn^iTz`f/-N۠cViABd~He Cjch9zXoChn ?'lNËRZtG~'DW۫**(-a)ހSsꞃ=jhNMl}#bЄg 5ܓB+~:<&VZ>x$ɖ[h>4MO'ı׮xZ,m҃1kRNEVnY둞zק?H#Ay)J)&&T8V0'M^gij v'k#?J/D_V1c3{>l\9=ζr>bcSf}]EemeS\Hƻc9;{?2eٳwx,?ґ#֩zPo>wʃL=sj]%% PaIz@9z<> stream xcd`ab`ddp 44~H3a!3,B'|=<<<,+'={3#cAys~AeQfzFFcnjQfrbobIFjnb ZRaQRR`_^^[_nPYZZTWuv-(-I-ROI-c``` b`0f`bdd S{='85o~Wte '~ ne׋!۹Y}} ?D+}gb[Q*_s/wt\Xpa`|%endstream endobj 118 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1344 >> stream x}mLSgrѮ۝lbo,X B-"/DZJRP VQA*/2D4MeӘmf<&5a{|9CI1Q B_%a|P HNB"3\0B!(]fVirs iXDĊ`ixhh4RfU6Gk@Uhˤ+s.-)) +BԚO%EBG%]VirBՐןhXHcY oUZ#ߙKqDO$QD4XGl f OJIn'==~T=9=r*'0X[Q=:D_UՒZw#NTbBlFZ z,WͧQ?l4 [nkn`֟ujbi5c/ טap`.Ze98a`Dۄ", 9 fL>pD=b`^eb>?H 惟%"Cp+xc,.ޅYm֢dD9%oH|(R< N//Gtf~C) %xy҇7㲍 d 2N9`uvu#]oz_D9Ks57qh&^+h/uj6uMd6!3m?sZQa(JU>+\U!0O7bvERk!t[` AmP sTJMVzBz#Vr ;b 70x-o9d2 |Kas 6fLhMRZ$0/r!fXu6VDG*lwxrO|:hݍha_/&X 6q!l57` *Mfo^qEj/~eog힚rUґC1\ .$?`=,]p lw4o]íutUњG-mH$H$鴪UB;P9K)Wtd,9 "Ri4vqq=oﴯ2TUVۓxsJNۈ۬b~6BIX> stream x=R[LSw?xʒF( ۈxa^ji;( iB酯{K@[.61E]ts-|0a{4->=}88^X!嶅{Vq૲ɂUW1 A@ be먵5,Ee*]WZӪUճ:zfKY͛˘=JV!+%l8VKrYe5;7mjnn.(ujm{72 9$ɵ٫V~RμYjV=+2bLUahEqxN [cDZJl#s|lߍyN f4:1͕q$FEZKk6!U L.mpA@,s@݂Vc-.Pb+@}]QH"&h?sл^_BB"$EgB%i|E]Q~ "~9O|{{7ŇaE4~>%Ig6;{=TǑ2 ٮX:8cwWxFC3!-~Qk9c>E54Y\"w2{efobfv}Om4)[҃ H0Ƨ~G<'8'Ft);>7XJh6'|v?ܙ1u][m-Uu`&0DB0.2kTJӵ>'y ~Vjq:d.1&#hD'~ns8tBϫt%ڇ&NjOgF'(lFJN\% OFjk@͞Ԩox`PjdxUc$DDlxVIu;Ͳ"r9ҹGXTxt}s]}faՕ|Q-( ;]vSQvѪGI\!jVRy['-G9yMVN7*,zqx@>z䯅yLg72=䦄hxA t`Pb-|YQF#Hȡ!@nΪF]J֧F30UC!)OM-yTD-,N y5endstream endobj 120 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 374 >> stream xcd`ab`ddt v04q~H3a!S,BG|=<<<,k?^(={3#caes~AeQfzFFcnjQfrbobIFjnb ZRaQRR`_^^[_nPYZZTWsᜟ[PZZZ`ȒgP./}"zj֫8G펓–^ߐ&{ r6NN-~oY<{a1sW1U{w1 b=jC.7{BI_r}b1]for{endstream endobj 121 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1516 >> stream x=S PSg![ QnWGm1EecHbAb0pB MĪӤ&N(HRܔ'mZv$3+j..l6kf(j~nk\b(WT&EeST"gE6Ș oUn!oM6 PK7; 2FjxZ&ugja?Xp!qYg>r==hA\Lc"t[:niGDi₍-`;?i C+E<ҤOC*ib&#!u=5 y^gz O$W7{yi 7s=(459 ]}]Ӿ);eIX<"Gӳdprz* >`OCks2O(*h3k&@"b~q`9s5-ްʖ6`Ki'ޢWH3C_H!\0J;ZAHfꙦ]l>SU~|j=c"ґ\2o{)LwtO Ԉ=,1w7d+.v5 ;7$ 'otAbq,.t|.p_<|qL[?>R)4ӑ\5q!7y2sqJ]b%h}BSam#<a'z'Et=d䉖{ },(;!ejT W; ?zw۶lN! aɢq/GshjiJ+ǧAru:K_UpN~E|VFAJOip5xʘ= gi;ijo`thdfWבζ %%@OAqa #0r;N4vOgyR yw\0jFOO c&b[o ݤ7s3R0raRIsIrQ尛MZU[.Syutd!=_>5j> sku3endstream endobj 122 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 843 >> stream x%le^YbY{SI: 1)MI;?$\#tWL9Vlsh;, AlpV@P7.%f<}I#aM"cVG2uP=Y.87+&F1UepAH)b0%cmhTFEx{$%66)S "풼_׶r8b'*7r"H}^X,6xqǢ YMR !m=h=rM BItwuHWJHU"Z XYB74dXbi 0;ZCc^W}_ "C~@[L=l$`HyX`3Z0] d|xW]Li#>W/x8Ԋ,@V[dyL}Sj?aBҿ~=-j!&X4oFzxբ`8g._SHW| pXӫEvy;njƓ|KrgO}-[RB:-V]iemM07:>?ޡ8oSKnBmŎa牝Go V&?]BGY+ORg1f[;urޠ[F& P%nԨ4;S!«cJZF/?u/RR+̑OqxfqyX(DɚV&ӍQj endstream endobj 123 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4670 >> stream xX xSU!4\H A-. (n"VвȎX҆t 4[&7'itoB ZvĖ"jaTp`pDzN:8kc<oM- c͗q )7GMܱb0ƶ%z} |';PdeVfI eԴ9Is-] .^"'%dF&䤥d$7)9sNɑ> 2dR;/:_rJv,/%9̜ )#`ʬ inN,:6+9EI+dg伐&?ė bצNMo$ٜ$XGK'6&bKl!ۈu~GEhlAI0W6u_K\^.n"V#w5ގZ)XlR @g]s ^MK_YWt- 9$z07|fsFU]>2r q&=0"[vP! )7=:+dhM\uǤ/y~N@s3HR"D'YQ\ *'TAAs3FDY- *h݃ơq7?yg梹dA:Xvl/LpCGъ_(7rp{#4 P&s[Zyi$Mvw嶄мuo? Z&D@g;Fh6A+3!81^Plh(َS B<4AsLZFgJAˢrdeI"ů5l8'q΅P[;opMWH%4[.00j)QikG"P؋)SC.ՙ4*7=VKU XD^R> 䓂~dr9mw QԨdiTe* UVYJ!DC" *P  4ˡ6cD-]YqO^#H[A(ԌUP*?pjgstr-f h>GotK rȨ3F걚m+3& ^ib Tsr@>#l糙&6#~VF<`!A聣Lw./d i`8}e`)cS_-8r,wG}mtk`3)>u_I9uBV+}y9YEqk{SD=>S袢Ͳ:.0ac&CI Z)hH{'jn|C[7Md`yn)B!zS (Eh@`+AqQJW{O;>4Li]lTgd'oR9o[H[/yo?^:vܟ2pP&%K/n".p{,tϗt4Ӯ``[=d$uGB+k0񑏽OxMPS4,"FÒ=DP=? 9(DےNT _IZ2Rp@ \Ax>C!eV .,::dHDkrpkZ5 Ρґ_c t1‹^ 8]ao(Xfp cmTG)1Gej [_ +3cq%G>[9T'qsJGXo)/Ưzx"޻jrJ>ڛyt{KKUpi5t@b d- ^G{Ə>hq>a' B9CgQu{lY;2nfOߡlvm>eu\x!=݃d7*B_v͎&H?Ԫ1b]:l^A%`a.dPp^^ !^e1Y0`{}C/YƜIp_1"獞zQ?ZЏ$ؓB]):-=ߙBSjs;w)֬n>_I>8Z~2p-O$%n$ vy!s>1I1|F"cp "ЯG'w@?D'֛ LMqLG' p'A+}rvjZNCt}ω.&Mzc) B0;,>&D/e9n3TMG偌Ɂ4H'e&eaQ\}M~VEC!:^ Fl[atPဵZi+gg jV9T!{N݇xhH6\$ "dیdb9ZIm ,: (DM&RDyEуpKI3) \>׌,惝?"Ǎv؛B># #9Ƽ`M"'e N8+H2epbT&@GIs$0nŵHK'WN~Qߢa t@贙qr2!*ȀSJ.ݸK/c=2-XNE?ӣQ%[?URz Tu~=ZFR6;w}rӷwh'۴dh,=M1z'uc 6年4w{O E47U Cgld{A#dcԌ2uȫؘ3jSaq-n h4c{uf~ئfAז"AaYCoEt3t"°F3?8eqHژO)$p }2M@`9T喻3Nz #aŅf3i+Gc$ Q,}*^bܘgp aοuq&02<{5*6Vs%d3d膭l,f[(\Aƫ"wɅ-X&8Ȟ^w6jѱ%_4Vר}hAaV7kYRCG>.!X![BdWy<۴8= gYqFmqX 8Jן9ҍsǵOkg1ps>5lj]_J[4GukRZzK2)쑧}4M={G*W}2} scA_@r7sU^K=__W[ad3ut=*%R0S7ЃeTgz6GXTId5f&zeN|F82Ho2(ncϙ1x5nkpK3RbƩb'SYQxr!\-hP`1[pS<%P2OK2@`w-n'6}/MA|K4Y׵TyMt"B]|IgȥL[c].\oPgHhqZf*YW6q1p)-*+Ղbe`P OpԐ[p=3Rj/Xj,pj !Z0t`^Vy+Ȭ}N[O)8Ük<(rH0e՗A9$<2Of㥏|#?zڿGBD:`t``XtxV_yTq$Vxem1xkkjMfm |0%Wmy :wTCm6%i 6Uu6mOHS/ӊ†6q2!cCb!ᄳr/V[;ggڇi% 7j 7 iT3(<Ļqg!}|(mٿXgMcW~aR3NV ! D5r~﯇h>q"=X4k8?\Dâ]Įnٹj]8X;_/>S|(".Z.՛` Q& diZMvlCa~4fhYMԇ=]Acȣ" QeeJ Len8ry27KJΏXsynPCCC۫ܒ 䩬 4 WHendstream endobj 124 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 902 >> stream xuolu-lNYwݒθo6Y&7[[^+'lqG9ဃZuQaJZn򍦾7roءV1<=O~a8fNv uO̮T F r?pQ|vq4QmVY|:ES-e9p"ټ)eʋ7TkZ2JZN۔mMh6X @nUvU }n[G,*%L|﫛q.PzJMd[rÊاG,rzF6tOvOYO=0~j2i Gendstream endobj 125 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 615 >> stream x=PKLQ}1!iuZq!$|MԔh$I`!ImG)2aS%@\¨1$nt' WD]G%".n=ޜ{B|gmNYKC*Q b ;w6l`+b$B92:;QVbjǯ2o9uOU55n j %f jQ~MSꪫhG Wj  h~&EO&9V$]UQ&Ej(v]_STj@X zbG0r@b8iܖY޾&\ԝ],1HydXCIĵ}#Sʩ[OǛ1=ÑMڐHNM'ǒf#&was뜢RLkMCJ@*-ly|4xB쮴`;xX\_6[9 &M`S&ӆ| +)$MG.7^~Ӹj,x`SxzaVp~;9ڕԽTga%> stream xcd`ab`dddu 21H3a!O]VY~'Y-yyX~#=U{fFʢdMCKKs#KԢ<Ē 'G!8?93RA&J_\/1X/(NSG<$C!(8,5E-?D/17UH=ᜟ[PZZZdh r|?wo1ߗ>d'\9Oong/˞]"vfa }}/vk~Ygm?㭟s\tK kzt.)we@ZAl%@eݳp=lo-b>s${sxxZendstream endobj 127 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 621 >> stream xbCMMI6/vTB@ {  hc_nsCopyright (c) 1997, 2009 American Mathematical Society (), with Reserved Font Name CMMI6.CMMI6Computer ModerniSJ4dQئytpnqnr|OYY%Zu~tw|Wn~i~m~zXgy}x{XbOXyvm7}}uszybGN([jze|yhR8/0 V,xWjP쁾1 pasBkZqUff zv}vCp`  7 6&endstream endobj 128 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 372 >> stream xcd`ab`dddsu~H3a!׮nVY~'Y-zxyyX} L{1FƼ~ʢdMCKKs#KԢ<Ē 'G!8?93RA&J_\/1X/(NSG<$C!(8,5E-?D/17UR=0霟[PZZZW\ 221G߯jNxW=fN=yW?$~}QN ceʐ!6s~=>57oKsS7ǟ 6\7X*y8w18endstream endobj 129 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 2910 >> stream xVyTSw~!D Jm5Iq3U⊻7lhBH"!Mʎ%,HqVe:V[jm9sGy$/^B 7~·Iܫn 7Dݛ6;{,'xõ~7D/ ~ *_CM2N6yD?B"u \PVC"3"ti7Aֆ'EV*bPY:J'[*W)dcNp~Uѱ:VUh(CBa)UL;nZNVQ5/65zGPBj'j H-`N@yR^JCDRY8.&KBUzma+;bzn/vP{<^( %ppnD7vcXb!'u-ZLBMzX(Q,epLth`p5 BVQ&;j$ܧ^JczhzrZnMPw rɢϰGċG@2hB%!q$]r mglM% 4m+@aBYiSZٸ;kwc-F\_*oڹI"oL VT. 1]5[/Aou[R.vy%g;'ϫs/? 'm*Q(h)! b芝UU%*{2 ipy;(]\G E IClXkg8)>L3gItJQkiLmpZ N$u,#$c)~[\%L<DͿ鍓tvS[NJ4lq&K-.)UuqyG9)RğG lq1Vwͻچ8jxf[uܐV.<JПSv`C:`̓/VV쬮)+nٜmTϫ VZ\M1N_?"v-0~/IBZ&Cvl捛O\<ϑxrxN]n+(n=#.My\uu^yoceda;J yz0sDJbp4Nq\IW`_aX7vG|,îM!X5͚Yr:TortB3^(L393yUx| K|?RO*޸Ʊ"=Y?#/0Š\pY ] ?0ȋQ艞폫rsR i&i]귶A3cy8vi-sr3xSFMnW~)>G7N{kK~1#_;є+nTX=o( g(>4D5V#;zO qgm ]m|}vubCǠ 鰃WW%:Bbzϟd/%50"Kkv%FV@)hU q R-Q95|JK򊘇dR*-))6`$iG/Ӵ9v4- G S qq"=)cE?*~zby联uK,<ʅ=WRa> <3,^}X*~5JFEUiv.& |wvOZGbjEW^c ߸/ÜwH5TDh/P_Pz(; yY|bԊ<|J5͂W S]XZlfhXN'>&AdCl0Pc?N⚗LAG\WƼ4WT ;%W씈Q5?;{?;oq{NԵN G,1PsڰR a\vِCS`:_}#iV-Sp>zt%2?Lv IiQt^u6H6_ % >bbTQVnIbc?5w &='-7UtYl0F,XY.x%{$lC\¢{(.|ݎ5|%+˒ LnzVZ$"X#06f8GDYuwn!0Y"cX[Er1>%S CnBi2LC6U!#%5U3@pMJY ~ogC-كjB#⣣JJO FȞ'5S(ypjTSWj b~#W,\2܊d7+`y춀i&,iq/]R'p!JxtK> 2\/> stream xmS{Pu=MN8mtw-h`pu{rw>F|ȷ(MXl AZc̯?ZDv;|^Y(d 2#kŊ䑷$eB&!vu"RNC4edkE" ܖa: <撒qtai\7-Z^rΨK Ub ] M|o5,&Vv8ng[='wm(DWfvAn61 MUaDn{9fu'㫵ޫmɦ;{ C[#<6c4k ue4=)62y4/KzK3Epǽ۴ٽF2B*v?=SM+ n1SAՇ=Gxc>K-MK !xRQ+==4k}XL`o < O xnbg;:ۻ6C*MvÃ%lz? yXso,[wB*gCsG׃`ǻr9hDQU=,'vɂ`&dzoNJ 8I#=EEc8 9-aݸϮ=F䈦h "GC6sn6Mm&&bkqU@0!LPT *UH57endstream endobj 131 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1876 >> stream xkPSOWK[tdVωv*Zl+*7DW(@r rYvٮRܺSv=CE~:|~>G<oMjzє]+);ǎl@| My*'%2Arfjz{qr\!=]Z*(%:ICyJQ\%.}*UItyDQM?+UR ~BdYDKiaCqH'2!'%xy}1tqM5c.0.34DZЈ>pC0FfFR:5ݞ.oc,Z~vYnOn`1FW]oSfwF]F{5`5j[/8!34_<$r ?Y(hL?7 PᥪQknmYMI@FwpCSǑpT]?~Z9:S9~Tp^_WT_֒ 6dyGEjm֢3 h@;)dKEܹgLxTcwB6nesa!Nq2;(*?1cw @'l\E|E9 !S= { gXb ҹ5t0-<Ɨ'yd|M<TH tN 4xZ;i̿"OָAϣ 7)8U'lm>2ɢH/) DokOP.eS4X^ ՠ倝. cݦ3mѸzڃ=p|rWwo3Qk] Fܛ+mv-&::mg$]@~R?_MKѝ)v>q'3OpG=ѫx GꮆzE4s 5me沺܊|@驋=v]OCz[ BWέAb֊zP"Šp-OdF҃?㷿mvHV3suD"G nBw!z7,a>3[p9ۡ &z`y} zhYA3A"cװ?gwf&)ƌ>Ww;@ZDvT\> /W [ 1 3 1 ] /Info 3 0 R /Root 2 0 R /Size 133 /ID [<8bbf48d7c74a665de90f9229a4a4b4cf><77b62b39d3836e077ec84213b7d1fd01>] >> stream xcb&F~0 $8JEgi=doGlE!ƷDJ` }l #D ?@$6 ,r,"YIF`|5<&ρM 6 lz endstream endobj startxref 76404 %%EOF Brobdingnag/inst/doc/brobpaper.R0000644000176200001440000000340213333164240016305 0ustar liggesusers### R code from vignette source 'brobpaper.Rnw' ################################################### ### code chunk number 1: googol_definition ################################################### ################################################### ### code chunk number 2: brobpaper.Rnw:67-68 ################################################### require(Brobdingnag) ################################################### ### code chunk number 3: brobpaper.Rnw:69-70 ################################################### 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/brobpaper.Rnw0000644000176200001440000001636613332136513016670 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} } %% need no \usepackage{Sweave.sty} \SweaveOpts{echo=TRUE} \begin{document} \newsymbol\leqslant 1336 \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/S4_brob.pdf0000644000176200001440000042026513333164241016206 0ustar liggesusers%PDF-1.5 % 1 0 obj << /Type /ObjStm /Length 4367 /Filter /FlateDecode /N 80 /First 663 >> stream x\Ys8~_Mj6q[[SرN;3YmNtx$jnxIm)4 l}|h$&hC$E&F?K#,ƕ&&}0>3M¬*4L@c  wΎ%8T"26*)&D*Kp\eg n1sD[%Zh!1 IP 'V&8F`ʎ8%sY ́ { ( Cf1tLpp#cI!LX`B$F U@Y0`)  (,$VŌ 祈Ze80> jAt0$ 7h+haNj:1te` RL+bZe%bPXovPeà P6 8 g9|`FYzd?Bϓ?g}b9(iЏlN9/_ CcB!Mɯza:#/ztBG2"oo%ԝ%,NYB^,PgaqϢR9_%7{=hm6Kc '?Og9yq)8׳0O"=v>>l:\ h⌜|[9X" ^(Ԫ̧x\f(>PUr6\&ЦG0)ZOU83Gp@RH(gKћ/DLDg|/ABC8Jpa%vcCh:fyO,k/ )g!"(F1胨PFsW o1!+pKXOA,)V<$≏?u*v ||E*'-==KzE}zKt0M'tH;zwRށ6{@! |H&4舎N zz]qgg>ICO!pN{c|U֋^f7RQV=4@´qqqqɎƥ`qVWZY@jEͮ T0Npja L5g&oh'꼃6=(MN|5/I0짓}?H,idge .;YSNO;x٦ڦj#>dJo3~%7:XVaƒx/r24_&OQmjKsW9<s>xw7/Qbb>1A&n p㕌S"!G) Q5ɗSyYAdn0D"\bCGYBAa~Gƫ!+[^UIϙXz$N {e̅"_#]gP-uQNuۣSuZu |eSQZ2Xx a*S5Q\cOr58:BV} Ș?0 SFL'6ԫz-}]h_*D;DWU4]#ُjp?k5 u i`gר8"a|pim꽪=̝:`ȵ<"e8!xvm+Q[IR%YmG9Dջ6QUWVke;~ίѥDZå*,lg;x+ۄkD3'#7&|VlrH;* p־_Itk`RD5dvE.ӿato+X±I\g-CM浊x_x1eHyLJȣ JoaFWU8 Isg<_&8Y#u[ZZg`Vc0ͮI누Q~\ZynAQ37C!'|i<̪LW"u b . ʚH8+p6x,a~&"؆;TRe|9}ws#>jF/֡u.VWr_!]*X"U*;]z _j.*@"(z Q8\r<^Ǽ 3\U}־5YwŤ-'hu+>q ˳ v+ƙ/5[?Ua7+= U8Id*URtr2[qxs-[SF^& wvroO=в++jk' _BVm޷VhטEgԵbtf,tԟgt(C+|_b5kSkj:OZ>\y.PUH՜\7p[Bw>Sڶh(# i3bP#a=yתDFfVK֔7o77UԉHHyBT8_*lʯަ ;>̒&7i5Ft:w=o3u>M6N:rPAHΛ;6Kytf?8,Kt-KOӅ'Zk#MWOF5s>ߞ>@s Ѡ-2 /,1Ay 3Syƻbm&,q!i:HgŸ| k g,0\46k#qJ#E]Y$Q2u!V^'T.X>> 0"rF]>EiMga?m^\ڈDZ0=m3&twP.R`4B:w!zMqp:I}ہ93\[d.X9%GQzwj#|'>Zb_Vޅ"OAJ"CvRg ӧw#N\uHi\%!N/8{[\FgO1@~LO7v6Xwqn/=ͬrݒ|̏/7endstream endobj 82 0 obj << /Subtype /XML /Type /Metadata /Length 1629 >> stream GPL Ghostscript 9.21 S4 methods, Brobdingnag, R 2018-08-10T13:21:36+12:00 2018-08-10T13:21:36+12:00 LaTeX with hyperref package Brobdingnagian numbers in S4Robin K. S. Hankin endstream endobj 83 0 obj << /Type /ObjStm /Length 2360 /Filter /FlateDecode /N 79 /First 684 >> stream xZmoH~-~^V8&,"8ĎlOy3&dzy&^SBސs-I;R8 )rAhlqHyB OCZf:‘vC0HL7RQ,h a, i`:6J1AxAz@-Tl >iP484aSV֠ X:Uzo@îBr(*kKvX`@NY|!fFb!3_m=.p葘$#4p="=ʾ6|wڇ*2"k:N"oX$QDoOmO]dyyRr`!R ?ĈaZsig^s֨yMFH"0aZ!o@6/贬 ?xß~Z!C#EĞ>&iieVg%D}!lj|d,02W\_f'yzX~9Pv <=g51'_g T{)jD9?S~X~̘Y6 >V@SӠ@+.*OH#;#9nC$FWrd"gF5/sC/VB2mp~X&MeRFiE rEsoHeLw !)VG(HZEm d$o'TZg?z{4xb^p%ˋί_"\ Ay_iG3=0t- !:Y'Hr#&X5 ?{T|)#-ҳ1 8mx"ZyiS(ҋl 4 7}5lA@je6{p AMxɜY4ކ{M@s) G;E9q qqEWqٗkR6`2ȮDvwtlJ?aL`~ÃUgz[Vwk&٭uu3 u;BuԵ!3ŪU:}|buN2'NӢ]P@AŜH`f~O|:Đal"62K 6dbHYh>6Lӗa;;ywߴDe&u8'Q~oi[G{Ѻ~j0Swmѽ]tX<}o_:O~Gz0>w߀ۮzw C_/Ce7WtkIk^YOguW\}C!V C{wCEӏ0I[&'$[[oRavG0öG8<.B_ d(=br fˮ`hnhn ̦>9zmUI-^~^1~~,d|6?͌1?;Y=n0oh%ȁWj_=HES|"Oy3~ˋmɉ~;$Bd*pR]c2n_bAcTh zp坉endstream endobj 163 0 obj << /Filter /FlateDecode /Length 5733 >> stream x\YsGr~GGL=NC~ZVx)0K g;ꪬ fuUV_f~UVj++y{wo]Xjә]]}{#JhVUF Yoltfx\osN6 Ok5ze >69gڪ1g0Dl6;k5 ̒3 *Cy^-1r^a?Hb$K 7[|SpzTژ:(;࿪b vk҂.2Iʯ6`CZ R״x|;3m1-3PdɌ9/VfźuyF-),쇓`*C` H6P`R)Lp*9REX_r1Ma ̝1asy٫cdcZ#i0:xvؚ yUcL*1 |/16i6gc'U`ZFod)ܭK$+W4,]i ^/DQ216L$M $h!p>6JޗtIY] -bL7o R<]G19OBrhHm*햱+k1OVcD hǐ #g?ʐŐ*L0V:z! z,cݛB]3@O"sZ*eM&:g*h ? #yW北)!`~, Umƒ@]>\4 iQ7i9sT&4gk+IFm⏌ʅ~?`@D}n'GP;9r7 qx:̇Aoqy`CVKq8@l{7Id~*mCzX`]5eM܂閣) Z;VP5 \Lr\ N؂ ]R7/JenNz=!LuÂO&u48Nh4amZ|fX!3 bIu(V{k2J}XR-h^MbpYHct/8L.GNmD K.Q)]eCR!?x6v#T/ @H9p j>GMDS7)#?yeSC y/ B9O~@m&P!EͰiq1M٢$6NtSZ *9*p4s6ۙ/x :5@bPtHp9a'L^]<#pT?U4AKDzOY!qm`ƍi2oMς:hIJPp֍N1 . ?f2M0b?Qr2F27&+3l.p<,Ws)\M4j-vڮ3I ~Y"ȋztr}@ F[ɩv$g\_[NzrwB熂=7)-3̠@*禕8Cn ;S9j9X Kː[LpȝwƹlSuFkyӣP5F"p4L`33`~ML fv_Va.+[wՂoP'A+*n̔6x.JL a]VhKr@hEbZdbA-iPjMȀ< zu6۽h_ƴF46TUv!X!]X/W{k(6'B`EGpx(dʟn5hC.Xu.Ȕ;x,Pꭠ>1!]+d@~񫞥WŁ;J=exˀqx~T Z"o!(yS*t Wz VK+teTXnQWu_}-'nYcDe.޿v*vn3Th[KY_ AC4i8m81"Ulʌ+QZ_Uca%Đm&/1 0رx C׬%t1F4nO3c$$2I$*]O%5d#[ջdjQNߠjJ!∾czOX#\Պ`:^5|f]X1 mpN,q^R'>F,)BaВn5Fh|燵q2Ǵ9m2ͼ6 )˙1dž+].r>w!56Z?OkX@Y{t)XgqޖNk>،LpdwC>13 7PtmN3^x2 C2p#$*Ǘ%iYٓGnڇ_mrsCrk! )Z9?*~;;.QogU~1j4̤9THw8 OQ8@l$kt;%5fƻ ~0Qd&qt c "aS=M.rYtS%[ IYժFG%sCøOeErd}\QgX#Q§$OwR?ö*}?%rD)Dr*.VTlz)Xu4U13YOk< .etNC 1ݒqh0B-ዳp^LrTF$k/K9_kOq1O[7֒Ԃ"HSY֣^ ;;Co}Oa۝)=~.lxfܬ=qQi?l%Hp aw}Ѧ{%LX>BcZıe +>6:Sb -؏¹aJUY,sF5دx$4 ( WdAwȋ"Чmg9R}3'tYdMP崽Ď.Ěpbၾ+{rXn:EX]q@:i5bN&Ws,UMC J%ߴE1ЋzR}$Ai~9eNq5p,Goi\x#]8Ò"#Jkqh/g1|ȡcMN1N,Z؇QW BKԫ}ީЁM_c F*|:y":- >l+ͷe/fVlIQ l KO)rd0}wv~Ӿt%SiovESI T`Ҁ ƶ|3uw n8~.3d XWHr ^kHw#`{r" })茠K.ྱq$m|UL-߀R.TXiYxBF)RKC8trʳM'Fф/}&}!_!~wJ/!p j;eYH#¿zAFv)w#}L A`)@>uM4y{'/k*Bz -'VE>H)8%Iҵ|S,-L 6ǂMɅЌmbd(fģL#/5+qҗ45+g4ԘJ/m5Υr-6V'$ׅaɭHˌNѽX¯r&)k_? )[=Բ8 5`B1:Q>LvhnҬ43!X5Pwg4^UC;?߱Jc8s1#/(@S)Il6%GvZlIf!q(Lʝ/ 2D(߰ʟ@*VT;eӪ?@|W@m}_--"e!4 SOTY0DP۬^%h,؅Rc??@{endstream endobj 164 0 obj << /Filter /FlateDecode /Length 6039 >> stream x\[^q_O z H-6 d`HkfR0$vQAy؞=M|P I:H[iRR,{'X7gp}$#L+7찳ϋԛS( M<Ҽ*͗4ݯ;ޡGkGeȽ)D3vDp4D0A +ȤR[M2f& UwST2ל_n5~[EY]>!7..x†~RdImfnzhOnA-A/ Bz-%uHhz 8CunI9'=I& ;Ϸe]b^A]a})rߛbE=u$fŞp^,+r9t[7`F٥5 @IdAI-F=\-5 k{܊6fim%i;%oGv0tB~7 R@0c#5wSsU# @g99{W8B=E=~|0C뛤Wr I1能cG,JaU6z8:Пi@1%t6tn ި񁏣0Espr7pWeMܓ{Q0u$t;,:Ȼ5զVfGbEg>b2LKZ}^ռ`a<;EVa jbfPg%ḎptQ0㢔tw3kh8'"#mԢL2:Ge#mX;/A5 Xd+qΚیC\9 *Luvc'`9PPcr_ZA$ )@Vt9i8+8RY۰|XیW\8!j{0E,ҁ0o֕Eܿ.o >)?K AwbmY^tiU 걄 Ӳ 8xʀzUQkj*q z2Dz `mv(r]oHPz>g]93ϺH\0Q:TĺCBdCdcܦ'¯ b;<;&–D8_H;LЩ'_@aIm ʮHO{7O9|C m*^Uρ/ vgR4 ~%mC7q 8aw ␃kվX of{yѤVhr^F DS7dZoXh҈gliW{{'NvSNAHTID72J%`Sd:a=P2u `w=I6?A^5qwVe4ˊǏ_էܧϣG[E=n oCv^7trasьfz'k4eZIԆB,N٣MCƁ NYӟy׶ 'zNC ч.+18}[xzJtg$-{5 4@_Ǧ*nl,gky*~S SǺ~sVLB8Vv!}˂=_ѭ-& (19VvR(~.q@\ I/ .8bgOv]m=8wƹ8#^ g[1Μq`%a7m+,*7xw8N8į"0z]&ad7xǶugUE>=[t2L6ܛWıKoj}p>V;W m>CIUHRؗr p\ⷐslA9c`ߧۈP}V`!*[ƈ[hJdR)KY$jg (Le5J0/7so$+rMWuddc^U$!qIL]div" h+]a>ɛ7oU})ٶ@7hXD?YC*%P^N=J T/Gx(ٰ6#.j% :. )KO'~m1C i,;:46hiҩhwTD){Y$FtSaN0 8ͧNŵOt,aâ;yP "@ Te!}d x-)#E(~V,<|0F~rXYHbί7EvsqF`bΡ͍wJ^E>X1GVÂ%і+$(cTb2*Ha̮^ޢm:MqDd'Kcܡhkʩ%GI'=t~AuZ8b7CyfQ}%38~M{X0*]0泴y¬3\ϱZqW C M€V%q V>XI}l D0.UQ4MiJm~lG%o*ayNȢȺqnB`+u#Qi)tNnoލz.mi>.M}`Vn3=>&+z]9f헴Mi;__wk`Rui>,4WߖEi4SߔC 'GIwϺ-2ˊjt3p~}]l9׵Ef:j,ͯ9~4oKCKҨ/}}z3aWJsߝk nR!#!xlrؚϷL,nO}uly=#uN3O|DavHﮍm;ž~\;XTTh*ұa]}yFf*p0[hzN!V;y="4B,Uy]LMbi>̲oN'`Av!;Jk'CeSDJob_+9謩79w}lDsJ?S⟿T- ÑNԭ8$8LVʍA9*0ˊxu|&0JiS+ɯj):]U|V*Cĵ3ː 2bƘkWpzP֢F⬢eM ê{98;<Ҭ8\{c7GG3a8huѝOԬJ)p5M[ǺMon14h.>5޻nvh5:ܞIn11싷1<TCߛp-o1n hAԺnqA~ xtXIBS(?b&*/sRPuQ`Q֙'hcͼ,/m`fJg;,&[P7ֿj z5pDZ!(+rhkt{G1M)Up2L4~z|B&#<}/}zWaI2>O&qajT(=JϷ `4X/cM=(ror)>UzG,-.fzi1~roL>}Z3xߵLX1RGKs Yz&ήD u%+uIGc^|6MW@}M\x}? 뫊` @s'lq1?;vرm:14X:՗Kv3_1 -#^)qbYҼ) vjޜV ==tE!. VW4/%:_,,Ne>)I{*CDy/~ ]%+0Q1Ÿrcendstream endobj 165 0 obj << /Filter /FlateDecode /Length 3381 >> stream xZKoo. ~?8b؉%:هIr(.%Rfg=ճ3$m8:S]]]Zz_{fۧ._]JӯG0#z}rş9}~}f{٪^bQ:&׽heC.6[km :z4}̱{|1q8ywmr٤y cN#ge/ Rlb t9Zߧpyy8u55-JdS Q6#y;}#7O{4̂{o|:7W*vs@2*J~UA%_T]%g+J~TI]GjT@)W|]o+yZɏ*nve%>J~YO*J044pp^Գ?o*),ฒ 9by%wmD{'H݁ ?>侒׳ hG R}ye+f0:y?6nGIM8ɢ@8_KØv֞nW/ D=|VJ~_{i#/ϝ˚^Gr*rEOt>d`/PR'&@J~}IRM%l \s6xQ? 6bu;v #K! @RN5Lln$ ذ h*,:tdl7E@ rޢ#A8)yW0@)HyA9䎶Ihfq <[uEbaPx{\|"dΗL{@CTQ\Lq}+|!$gL$KԫVM!k<އ" ^l ;8fr԰-y@`]+57e-zTtJe3:r e vB2.6&y:vјqG ~CT&LDN3y82ZYYph p&`C'IZeq9KCtp! T.7u'qMP/(W:Ois47Pw!:D׭Lȓ;8++2%RdG>}\<8ix=vezJCLvVYÉBW_z; v "I XXe.f;@ՙ$ᅱ|^Y={PCu7TL)b:[ 7~rbվ_[==$5kb7,TV,p g=7Y@֦7&2V!" N?5` 4F;d#}]}V`aڞT9e_y5ʻd?M"bzb,09 "'L1 Sj+(ܭO?4V0R X)$BP?Lv!'v88sZ3r\3 ~ML cT$vJB'8c8CEkCJOH.?ǡGb%̓~ `c8eZ-gNI';-GZ8#yNs ~g"5-UD~"KF'@!1.kTz-6h&z>?p#o[hi;&4Aʇ|;N.* xtv`C)i<Z\Rż(}iO)l(FON4g󩮉hp.xݎp^s"eAΜh)XȲ,zo }7u0՘ww_IGz|F{(yդM,bPbz!H:N(:e\W5.8(} ŝIۤՃx6;~,QKBeK}ީH!j̍duυh"?-& ƻpgh}qZn|]`l7Z5^:\=lA:Aj/I{:cEO)N'Z%,-eXÆ4Kk\/b̵;z0ր< jt_(ȶ, M~Nm5; C_ L+7.A-0۝ތ" ǎ A4J6aAršp?}n eа.G,!dvS,7dXjp.BiuQ8 \DtXBqLbѮh:y#1G=-5/{mQ*M&مenI&r'>"ǛֺtW0}#pp6sw9B~૚O+O*w?=g;w+HΘyYi}\'|#|6VW%FUPӓMĜ*S(kk*_}NTb 1pY*e;(p:yJW]2Y)=dX lYr+f"- @[Te`Wr߈ wNbqp-Pfz&iV2VM?x/Vk:VB\Q/6t' ҙ"pe)*Kso豵sh<{jP a{ޙ@ EO\] u@72g >WM BkF哚g~>YX3M5$F5L |tז>F8h2{jZFi-z roVjUj oVG-#g=v ϠF2:bJt-5]گxqe(5w L)`)KdҜ*keP__&c@!!oh%Zö5=2 ŽV@G_PK">峁C Bdlᓩy'ًl=X> stream xn]G~ɞgŭ 5 V<IXqtF KW\Iv^"Sp3þ.~Ҹݞ?aO]vx+cQѧr_Y3cvbra{3. z U@#.G?B 6FUY \nLTaxḚ-bJd[VΏA {]|6FsGand93)!TtkaG:uBw"o*S10x8ʟp f!Տ6pXosx}V¡c֥;d]nV7Has Ny"5H=|g ې[j2: !p D&䫘G.!z폕OVkfI0ODfxQg,e[e$P 7up@NAQ {YMegj -jA?"VPJN$|B8O:.K> ٍSZ9  5̅ wMq Bir]_MٶPA';S^ªU=L fdrJB&Of.벖X1 6P%t@!qΘ5_Up[Aф zRWo*R ^W{0*V.+fQ~\Cv]1{o"_AJՈȕ= }栂/+mw<^[Ģ.~)WߤO=E> >ফcNX貕LFGC${h5bh~'MH=nC5JjMod=Lsn0wu* dکSB= s^ɧJ3ѐVkFuL( & Ԫ#?o8/&^Z^#la+ªE>|aV/ao=Z$@Ta훶ڇ{6Qx m_BIC|H-Br}󏰪Wr ߬5dLeʦSߪU:< P% jJB%Gj<vuؑt̬ZZ*>K4LMSrE4p m8Uok \ȕPTOJܧN5/s/3 RժU?; ZOUsn^R_Muu7rCl}9 ]r)fV.r-|G)u?>7#m =ϝ nK\BzEƑ.نqX6݉z.waoU,}>R?FDb'L?u>) >鮊nMUE_Uy'J/EYea.wŦ=Qo᤮ '}]Gz n+x=>Q(uE(+d  Ɖ+4AfR 91<tPYۖB.=?(i) =Gl0uR‰=l&%~xu#2p+ 1,CCJ&}O)J%6,koB3d:bj}HcRPdIwYx*bWm8pf9>Gd:-/VV Od=j7e"2mĄ9pG=AՍolxWS-bjV]Jx#%o6q4b<`bƶ Sķd 9tc 14.GӮ=)6*ׇpBSUKv杦~̭f^wbJm2rGe Ao2Qzb{_QlN0O Inn:4+6xa>'5qA&ެM`F|*,2W vlruŵ>lβSYs$Jc˹~TmM.;4 as\v0Q4Ċ8v>j ?qR |g>bM?);hX\M/&ϯu_QJ[_)=O*M4QItE);J,\>hJ\*LIW15hy[?;\kC^g HB GXGw&3f40Lpt!wc%XW7Z9koJMpퟦY]Nv|B"&7D:Y(leySK.Xyͧ3(,ņ( 2\oFf=_yG{ they~!a|Yo+د0gl%9MZs,4qnN's`znݙ]W<0d㙘yf"&tY^y L3Fa BFֻ6D$M&ēM9}픿an ޭ 6l{|G iS.dY`WsZD\Zz#8|Yy۶TOK_ٗx-H3 o.9e|8,dkJz72[(awLczdF۠sXSq <'1x.n۷_e680ecT6ϲy[+sXwU|D !´zzp󏳺:"?K̬4kWY!Q6YEHa}kf?@@\KriDI}K:*X9JCf^ ׹endstream endobj 167 0 obj << /Filter /FlateDecode /Length 4990 >> stream x\[o\q~gG 4L4'}l+۰%yaIqJJ>{8]#H[l_j ]X\_tffx #CVY//SHz}㛃e8:fPoVj09#5Xeqʄgoq9F):E\t0>//8%('0nx6vy`F/iY#3͖n,,+l]|o>wgOI}5~eB hq !ˁS&Ln,,GWi劌wLmv% 74;la!E.w5&®]~Bn"NqHW f>2vI.by [("Wk!Ux~&C LG8bOw';Y;orMeqOr3e(_<_ly4Ʊ:"$8xYoޕى]s:!C"guJzea]`q&F?%;L֥ _gFNMX4jSy\SJtn&9ݚIﮙ d}@ULظYIsrƍZyII8K44(+P*xY9P̆풁@GAPz;ThǰmLJUnD4isAECbɨTHFLhwn6fvMՏo-+N`EqxR]9 7./ݳ=MV'tq`]09>iYL!^OqK䩕d'(m/Gu,ϮnSox["LA:jjRٜ]Gpʄbp3TT oyxp0=IE=D V&e߯iQ9 +,\Ai,12yU]Y-EP%k `3\m"̐wxDNn)7[uWR<}֕ )jpWKO6f;'e_n][O$O|<ڟ{-G>ywͷ;7f.دܞw;'O-xok?=?=]qteuwC}_쯎2Wb/7&@gcHM5qGbV(0rS;a!JCIg$@qb%8)G0HY(_/d(zx_dDw&ku#TN#x̒%l)93X*8qMz=6$,5PϿHMd=vB]*:P&*P([w+[#U k]UӼZ83;j䀊V}I# v6ea)jQAKxc\ݧy Z R^\7RMxQ׮IE%I!ʪį J`rVHQ*5 st:VN|u=2CI$_gV/^-͍ڌHiVUq)K)ohV(W如6vȓaqf,c}b{'mb yMwB=; ~Һ_=hDj&u Sj6RmQ'I'bD4#WKTkW#e>%ѪW!۸SI^KI7R*(HV5`B|5 aGnߺ ͟rYx a`\r`&d+=w8džǤu8J=lLfA9[ew*:*#$A 7隴#jeuX $=gr/ m_w,V#(2ɿ2ۛ1ۊ ^8)~ a -e!02[!k XZ=m*ؔA@*>9)*40Z83NݔTYc-QD\r+ }_w\]x7wlf+: g#awC='aK JB|=]ɚ WWL2Lnl|gL^wvI_N%i?r)J;FROptoA%,֨oE%qܶqڤȑ%O:ѷS剀(Քu{. 5X*MY/~ 'v)>vtG='=Ֆj'N1*ȹO@Q1G ʻGer_fFv9ef3XuCWf.VRP:3\^n%:ƗPS~HG>P*5/Z\8$Wv4=&l,2kCDV^Ƶg!S)HcV̸GJ|vOm](4XmWo,uG uN m*#թ0-6Ísؙ8V MrDqp娜m&AE"guI,;W GT57.Od3S?Xo C9wL~DZo!k&鮱eR@?/i_7 }f_?l=7LsMwsw:zv42Ϙ #x?F y7LU }&o|uw]u=er]t32r)t)buW7LBu szu>2yoN1;^"*gpEjp]Rw:p5埴h#!iƛYyڗZT.I {_̓F!iۼ_}&.h9~'$Ʒ$FP ߈h#yji<'pg?i6UW~ B]{*;)n/giY+VC);˻MTu|:mM *[cY٠[ؽu5 ?)S gJyϱM> H(y^|&[0kWx%) wq}GP=%|}-[Q/{<ڰ}x.@YOb 09V, 5I(஗5h JNyZ9U< O#UQr!KIMNendstream endobj 168 0 obj << /Filter /FlateDecode /Length 4741 >> stream x\[o\~#l=6b mS8(8kiv"i(;CC."E?8u曙ol Ϯ~2Ǜ;x_gWǏOdӋ*?vj;zOnCgkCkz~xd93ZQ2KaFαZ1.Y>\CSq#60>aϥ a<ŅnˋWx8N kLz'u%G S 3ipa5YZ|wWغst˴ԣ3&K-ȘV0F)a2懱4v;<J&#=fCiJB;7uʹ&"dJQy/Or44+gwZVUi4?^ L9~.7!A8~)5_-:D1u1u'u1n-JrMXfL{m:=jʈUΎ)W5w`Cð9';*8'3&7"Bf82OgOK'pN)/*7*G猖 ,x ֔SjX]upG=[ք\Ѯ.jz|Fp:Ȗ޽J7_k'1IǬ+khW?-G+7]讇pOYi>-o}9)x6FaѶcX4)͗yAe6Y"N)*Sr4("(t+)}h½LKHR)f!Pvꊣ 4I俧5A;CW)cl WT*%1tOn҃/\L\ HL%Nĕ0)@M|DېȦ"pQ: =݆qB%lь(ctYő'ކ3.8=y.pŠ/J A822h&<]IU!Jh$8X]~=#at4_wG8>47ݾs(lqtZf`( lF>+MBs0"mX&aF5 X@u7|+ȘHB<];o|=躾 ^E6 [czQ" 0G1̐ጉ쓬 T_RHM!NYdp gܞ5p}g.ᘡ˾v3h4VQa# zIi+n"6O\s1Z|G݁ߣ Bw_b &hKuN)QW'o Z0 m&) G L>i#+R{gJ\ID9Zrk>q=E&,-S9#a4-+AAd+Kd"$),MS, ƁᇡWq6SX2{L!.dP@oV-(D84,oKrK_9$]'-G,.š fYKdIe:;X9*(\ ea$q8oyj~:UYV%iYC+aիA\(K]b,M6 B4XHb1bW`T,]f+W?gfiGWE93*aIU9@ިʡ#rt(p23p@j2;v۠;+1lIK%gSt`s-svݘҹ"*196w!`lL Tc,h*%icdy 2<Q3Vӂ(4%%)HLQNm ;vy婁|%_-MJɦ"ijE AW1H#;Z BF*R%)B'@F xe VjɆ|Ȯ*J*D"~]UB:u ҋ='Cme_Ql{P&I 5~[+Jj&/*N~?L m[lЄ]f{E,P@CJ$uSe0*9-KJS>AI~'[E/ZIkֆJF>sh%LcMT]J]f%U~]r6(y0^UqAg[NYQ@PPtא*LX7kDB+WxYQ@F^lv}i D&fv2kLuM8cr>!) rZr24F#L7}8/41D7&ϴf1'qu=TE*Z1q"%uNA^U L-oO[%P?OxOp4vE]7 >{EN٪ԉpN2$lj5=Ny$Xb63<B阯$8%4@"!T/TW ^ ,PHuPSN.Fܔ -DX75Kuej3:U{hDK-TиlHmsِj6A'qm vZXo ӥh= =zL#zw;t lpṿ|1[6dԙL,ѭG,OP篋o0.t6򬯬1q0%P/b_y5uy>dE^C)apkhdWdz,dް9i7 g+H-|& .hmkU~Z#JKVـ)i6pCKޏ.$CG54 <ʒW=gٳ2ڥzhW+7D;(Iy>0!H5߶Ƀw'=KEs d;,Dp@~~z7o:Եendstream endobj 169 0 obj << /Filter /FlateDecode /Length 5123 >> stream x\YsǑ~GG =İCAZIĥIЎ CR00@o]Y=hiChԑGjW=8x܅́:@_?'afUևo0:[x|q0: Ӄǫ#69Z[eqȄ> 8" .`|8$(0/eF^ g8fK78][XW0Zـ| O8zhtT~d:&98]:ƮSzæ>>-+$W0q;<NrSP'yWywe}WCww7q]_wuȉu}TGRj<Es.tVW'0]шӮ[#MnH Fgn>oIؙͣxS 'l ف-՘L1 -IpZ]]5 Ѧmv~(C)9 }n𕰷$-Mʇ`A]9Y0gFKI&$C$%G9$\he%(/E 3yYfO< YSیW{MzlWlv7bwA9H5XHp8".w4wA.^v (6*Pdd|Ne3 ?/yN)YW4x P-LưNƵЁ5%7z//`CSm@X..#mLEWܪ$/n$Q_gI.J9lIȩw4)abv3t,Bxl-9a3K6+rj"ptMAg& " ʠoȊE\Fz ZlzW@={½= <#|D=x+:Pis"aEߌijĴt?l1vԃV;r?Y[lrדI5+x'l4^aopjwjjUhGiE\3tÏJ' YRLkhIl!' Z?/M~FS^ *SbU.˶ag%Xܿ?B_ -{o)&O ^qw:jߛ׎ eϑC]foI߬[9A5P7X1\ xB*YK%w䕲vtjJm}!1NG7uu=ڹP99SfL* 6LqYJexhDQ5l4^$ dMv%P5i,` į1N bCTeP+!$$ǎ\ҥ ؙ6pZz쾄.yKoAhZ͋keQVoyt".A؟ Fb󮵟!,,qdʲWS` @M 9U ?K.48A!efڟA/PR,Iv?ҁI*g2^aޤi=8 .!y9wy&8%\]z.NT^UB.'uE0v#h%=y6xIl=7uUE!iܨBev T^绽N ;u,.J@Y&ĉl+^AV tMËďl9'яx2 +i*Ql<w1>6yP'`^~WԵq߾^y9Dbj_ߧ]Ḋ͙+G@a 46[Ci'+ܛ{d~ #8_⵲ V0;-&vSS==58vmSi|F "_E5NG9?.p}`gfN}!oț=@M5FMBqnjhJn͐fŝV7MVE߈{/lGGvh.MΏAjn. BW/)ȪK(S6#.Ӄʍ 曅8 58ttauwM}3 ΃NjxiwC!/.:`$nKLΆs\m\DT7 BF󠨩TDP!zkoХm*\R Z٥-5V, R$x!RI9##*]6)(@E60eoYWwlG,wB6\f'b>a/PgIN`NX1c'cS<e\!ZCDŘ]=wW@ 6qNavz 䙴{afeouX3L1J[{9Me+Hl EfZa5TF5% 1f˾Ht/3X40@4ؓn :<׼J"C$efD.0F/ Q.Ψ)CRTSȔu.-DߊM5Ayu,UDoR?+C2fto}ϪA0р !qY;!uބ@B~?6րejp$ڨ~SPa}Hu}t1t+Lw]M7gccw;ïb[pv^q 6aFoj)SO3/ꈻ|ykDm IiSʡ`,+%\S .08c4Ie^v'2݀*.# =bSY|jCwۉuR)e 7 B[웝l,k+ҽbY~w,"+.wMdAVq5Kv<_z]]EZc#SW)n9@.޾ f AoOHd~Y(]Q6NDF|ei6־:sZR)ˣHXb\/S:b|01;A!9ԉo'X" xBC0ÞAj^xo^YԐ Yq5@l\0^΄7_ `=b\[F?PhjBB@ǥ4'^Z͡(uyI@eḛ́DT&4Rxv?kX"R#ȃ{-sFhedYEmutlz[ MvƝ, b8rNŒ> JYs~căwugsŏ)kOcp/vȷU&5٬qwMQ)OuEN3 Mb`Dےt}tԈf|UKx5Ywr K왹w QjȌvendstream endobj 170 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 5350 >> stream xX Xײq`E-MqAqEQ\PdDvb@}GdE&kgDT!Ӏ&~y;tT_udQF& -9M|C&G!ENfy#ޜf307_,} #vmvy{zXXno1zVV6<[ػxyۼ=B-, 9k԰)~S<?";bGGP]JW?NesWG}G?03/ݹ((xqȒ]KC\v[cvO5ގk}|M{{wzzͬͦX1[*ffV3cGf-cɬc3 ƉYLb62df,b+f13Y,e3˘; ƞfV2!k e˜apƜyyf3f3H֏gXl>}PZ(2r㻊Xw}~*LM?,WX=H1hߠ]Ol\nK*x53} {afFuM1Mb d1 %Lih}1PÇʊ#GK 14,( ^0l12\Vn9);:g𕐶KgxbI|0' d C7OƣE34)NLX2L"i 8j9(׎pI ߵ,gCpRT5ʞleP ZE֠_Ʊ(LGpp ٦<ɒe+돩C'ڋwN:-W*-CiZ XtBq8Pc%%! #VrF0m\\' XV eZg3􃑪NcvϞ=ENgt+DŪ@8S]/nn۰=o;( Dg ޠWPՍ*Q/Zɚ>Ljbq._ SbI)E3<# } OR$H p޷PE2mB!%DIXv7 3uPT&+=)'a%Jrʅ{PEA:!5:KJc9U*^pFqpDiPk,VRXpB!`[PXo+kG?4ŗk?qyfӀ˃"Zd8c]:|eRg)p~WahD.#(~AtϞDu="F*QZz"'A&&f|fazy Fn4 lMEZ ڤ8%KrO!EVC`yv ޭK"eq1.32?vDӀAt |? @7pmuMK IIQkS }f1g]2`KUK?'EٻY™D= MD5* JF%o[ /AKkr;~YPQQP'[lr2?쥐4!ţ\g.Yp?A=*8NvxoЃ4Rғ Z&)mRVnc1E/B\V$w\22HIGϤ0yFj5ZeJJt$qT7E،un,y8#IQ|7N㎋ϤMpOxP޽iT.)`V ӆRTnv akSOX،b0/XgxbE@\|@PPUHgH}$z tkӉ]4?uTXE{Y}uS4f2pgTU4)Oɨfh o؈~ċ 0̀:-Ǖ-%]2X<‰8HHЦD'*- ucie9pyci -lb:v's`c7G/ÑJG/"XD2xO #q']8=E.`EגӴ͟^Z}ZC)qXhV583|0 qg$I'@=Up u߬ t:)mTUfLe|e3cwnuC xHh‘ÆD$Ѩ qO޺M.;!?F4!`?hڼOzVSℴZuV74RnHdb:a#/6uZ 2[i)^ĶqF9wn͇YH*?B/ʼn:#s}9f+xˊP{;DVMPIIޔ(ȝ࿎S8E6ʲhLT):tOi7= oMK I:鼤ttSwPrrx=PF,!R)edb3)5o8{-+̯(jxfmZ.. ֨}FM۠Zz? 65*-9- )⣶lv{+ ~|yg?/:>#?=:p(u.|IIQÉk㌿5(|4 F^uu_eek$ً9Blwޡ%$1yOqgqrC|-!Cz &TdK30 k5#_NҝnU g*RŶ~t=4 hfFst}I U;D%@$mSM [a.ʿ rhbq6, '7DV7k-MkO/A<9mTJG)3-cF4nbަ rv ]vYi.:ٿuu8mǓ'Skoj>=_r7l%1qpľڃ*lZ? _*5m6YjHd$h8)I]w.i#qZM8&ΐxa҈et?qq՞kK WMCDoG=qTQEKዔS<#`'YҰO_zvۧoAdRH!nR9c1:&CGYQzl<f٣/ D MC>;t@IS2~o.(]\;Jc{87;k:qTA%_OMܒ6Ȫ.$ 8ຽQG;ltc!=Jd| jV]wv'8-v!KqY GEWyRp՚{݆`p2=;ұkG tK^RÃ" +gVQPQ^ \J{.:Ns/"M<4mJ@yKꇇpe*Ħ+st[oi-H}j+ 8ZEw}Pr e"1ԟ;}4;+5ҹ옜Ĩ1|~Ơ i'itbkd2 KM#V'EC &~e)O2M cױCZ/%g)Ådy.Nj@ڧ= ?FMJ^|q"J1.CDK
'LeaAE1p.d,x|5\d5`%(?qqp@Iotu"wں\G-忍_O{7t7hkPЬݥhL萍[rdK&k0AY?Ⱥ̴lSSUO55ceendstream endobj 171 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 7915 >> stream xzta X`SF$BqoݖlIG{/l ؘ B'KHr\|d彼/Bܙ{{},:wh5Ǚ7'w]5jsάL^k ݅нW[{}=s/J($ j?uiӦ0n4~;\;z97;C#M xذ1~!c=?>>lGn CW8ۛ9:7/Pl<=؟(s6 4?xAE;9/ wY-ՉRG1 eOuS)?O}JYSTO5-*F%u:SjA_ANjaaagaHCL_&.]Qu!豹 ֿ\f/^{%YLmAߧ ]tHvK'8p+$=~!C ?o 0MF~NP:[j]&)3 mFu*Ɨ.SԃZ5#M :[D}R 뵗`샃fiIb2d ,7TdͷjmPb =cq)MȍG5PAE28 A_/8.gk7@0v1ȁ`)֭9=`9#eV̤֍$+h$wѩgs("]8ġ^guS/< %g%U;}oF)i+ů ̕31lWw@IL)AG^>/~.kS'84 Bkp?4ϔnϚ!,\oUdXssX푏0lvEy^gX_GʟϪb]}3Fqg"ݧfȗi:3gCDn^A߱%jU@|iTTA&3rwҳ94Pi8*,h}!Ʒz;'><l''a20`:m;V,JRN{e/*%p~1]qLL9N{uJ YD'ێB\Ԏ%7 >҈|?9i z i~oTJCɿ-9@˼SqȑfhlpkTi "+uɵ[Ւʺ9ĭ>6AAۨX7kGpb>~|#J1I#v(=jm]||MK'T,~*ٙǎV 'MPH$|آBΥCb\ qv~nff\{}3v7lS2 ry58vמ=+{ `S"Z`Q̌%n>*>6Y|_L- t( @K/ZuhϘmYJ| Q]Ь,6) @_]{ofM. ؆Fծ"4ՌY\Gsي&f.-=5juf~!F|8y~jXDylw E.4:p+\k<+u^<,-cEUs-ԐQ,}CL<;wѻ!(T#t#NT/l/%rtOO$8wT]o(5RK}H2īqb-"}J2J8K"UH^hD696[+]`)$bcj 0i߶f#4YbfX;B$o&ds (@pbkjw!pR׫i${4Wf Uk[ueQ_']V3DAvږd {zA%fK_d+(EIDLHkz$@ v1讨$n4wTWQGǴ3GG>gh=0Ǿu{ Y,i2!<maPigL(e~[I\'h$1 J{jh6nˉ$xg_O lBJNotUBp/*QD%Ur~T3۬8*|(J8 KY ްYeKp ͤ-+Es6dMl]gƦ yIpNՈZ(y3>f[B020X@’DMrR伆xB> PO.VNRꎞh;IF%x!'abqhZFh߳#qQ>E~}<gb<`X5:e[4^^:_x@sY~m$pq)̄UV+qn0?b=<_ ﳕhZBv_XKu^廀Qt*rbeyEfH<4m͵kK[eQ6^ϿGWYr"d4ըkʉuiqJZDK* . ꃌUґZqU6'*Σϯ' ^,~ϸ8t -SA>^-IKU@7ԉ?:6F$'hܥHF2iWRGiP6Q(fަSg^ϭ>8We'cu4jMNjqyχt$_LՑ"{>Ĝ'-\0ÔQ\2y{z[ɡ򡒩Dm8pI_mӹ:?$߿l>4K,x}A-QjvU.hR5) K6;@]xdJ8JxjU:1,F mUtR/@bZ&A#>刻"[ S$*:Ȃ&]kဩy(wlxDh%^Kwj6Y406v^:8-VoZ~jo\[TA.%*J9^ڶ;yyB> ޱ/MEOSAhI[Gyt1fl{{*aKZX&Df I`}ٍ&OUv$+ΛLrE"I6[K|}Cj G@[T"+Q *WS:)q1!)(ie2 )C]9kiF@<ShzީLG@b~F6 -`ؚQqM Q!!nA[ ]BKJ:cm<㕴uDb^&KJwmjQw饏w4Ϟ9+"0((^NzFV˖KLRZJZoQW?Yf?&GɒG}mfibXz-osѮͷp \`L89ndzDh5;r9q b^0^!V/;̅Fe/mb:猪C~n &={TYvR^?T%O#2C[WGgVC Q~ n|X#RGnضs 3' m.;^Q|E48 PiC=yu(ږ듺 213'-Dky@|OڅוY@j6!K<ˌ7S iP u&34"&4Ipuu.N1E1Vͷ|-i(Mze} qy$끨%LgF饨UӋI [Y/s*JF 5ߜ;+5Cd$&>,߶¤2kkK8?{8%QY{#h@s9'~<~B,^mĝⰐ94yI60 w&ơۜxRz]ҕPҰl]ԕC3s: ()31pxTA3a,+ +mDyỦބ'I;BQ$fe XVF"W$BӰx"`w3=< Z*&OMI~5ErkތjMBlӈ75GhMN[5 (t߁6\jEP1ŵtLy'pJ?0CzhӐs凰3b]$_{^^Hc( v*bJCuRQwElIYY/6mQJ '5{>dk5 s39JV, X(ɮR̴Ƚyo#F):9^O3^L]Ӟr+PS4>.dca`ɿ$›fUBBA]$H'&xGpED>ZyJdO&Oh6|O1Ŷ)mH:|!ՑM3qIȒŤ+8$ǒYi'JO֚|cQ(&΢o ̻B~;­[^W8Vœ 1> g'0+uޙ>f ߖb 8'º*Cďp!x v-p!dX̄edB\([=j6eAAB~g^Hˈ~v{vX䞒783 30"yY!akY4y*ԜTFh:2 `n}Rێv?0M9%؉Q.'qBu:i7Ȳ+4~Q^Pɹ)B QɌT-B9zvɥ]/vvEսE]qZeendstream endobj 172 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 946 >> stream x%{L[eƿӞawiXY! cHQ+e1Ʃ-]%Ҏei3fLBManr2ÑeS3~g_&ϓREQڒ 3`5'(D"rܡIGk_LO3=$-_65IF4EC%@]MmP4z2삂ub\ nyuwXz}r4Nl`ӆlj2׉-uZ {) o!jsQBIdDkQ6Ey1ģd"5#R*MMݜl`91(GղeHtŪ. 0KĐJf,Ϯ<  =l=7'15G[0ʓ H%'ZKbI3} ul!shc"6JJXAOʠtlpJ3bԍElJ")J9Xi <$s7A {! 3`xPMn@2N+3 ?7O|>65+ͳ y@V 09 8ȌfY.IGiA~w&98`{e_yաbW4nawWwv \b7pIKjt舰/GPaǿn %z^}ė =٫nj ^hKBK[j?qnݽ^v<.\jhZ.0i,*D(/Zi&vˆ 9\dӜ|Ȁv,U$Qcq[~)"e:zﷷwȍ{Gvz:z{#.4R6tC:?[tWt{=endstream endobj 173 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 4955 >> stream xX XSg>1֡ FI휃Zmj[ZZB K;,$KB V[mڹ?p{NǹWg><|Eg ~Y,̈N1maʢT񒥒7#2efȎ^*7vuܚ]76'%?5 uzIb*xDL#6Ӊ-V-b1XL$KYRYM"C,#+U\b5 db:$1r6rn [>쿹i \LidoF5=b#888ѕccN}r챐U! 2 k&t-C}̲*NW\ ވ$z}IIA|Тm'PT@v^1 C9<';?(;]C& a/Ӷ[\PVtV-|N~<ˡ<ӂNS@E*RELh=FZֹN>;&0XK5-ݰ+at0cKuX/cX>;uBc?)U]O#niX~ 7\9ENVv S->4cgUI*m,(PtP#@7 ! b/)ּS @kG%ShywK):Z]yQ}$e%-D-} 6d~ ǿ+.Z _%n}z Q&<OӜ+{}q%.];)z%ѯ9vct=6 $&;HqzJ\>$|ً1k^U*VU)4tE%8MƊ]$\ 42fQ9Kr29׋=S$Fm9cH]qȟ=BZt?%T/XD`۔bPRF]\_ l +b3Y9I>lk'Xh19`t+Wa59Enf :9TWxmhZI)qJ2 D|\^h_-f5)=C"}};v PWf2k#=|9qRZlCSmTX1 W$auAl,*<*x%i?Cր!{= [V=QXgOEsz7Z0LSNVt"8t2ANjJN # >Vm.Jn_ԬDvZ 덥%}7N6-]).Ӗ- )Zk͇* "aigWo:oK.i XWX΂ K7A $֩F zZWҮ#NǞgz1"g zN/ՋDcЫ|u> HE[§6qH1mm9擞]=plo?]j 'b2br!y>^x0IQ1|C*7} zmY{}b=q8GT&rQ vΥѡ#] ;T='|hd!A;Fź"\e`8o2ZE>ZfTE`38 PNZ5f5m$BIx L]X,s2'3 [ދ GHŒ:lx [ªR` qo+[g!`[>ЮC4=$Vki*^njjV+=5k1/xP'h8FOb_0K$|ώ6!m@{k]P.3ŷ81( Иcw0qMVā R~Py ,\QSXYD=&t]2Sސ?]O3y wnv''3:sqE{TG #Srz4()ص&JA'j^+Au.WKGJҚZo񨶕wfi=}gYTizZ89M%] ?]8kXC7ؠnʽ=oy4; ZP7υmdu^co**/ T }nEk HДR<`KI0a^o~~pXjuxZ& NlPHuH)ZFHz;…JS4 C1o7y"W/T,;}Jg*^STaZLoqnYOJ:O vynW4t `؋^x]D\BR~3|h:Vy.ܵ9~P|am-^a&jIS(r*}XRrKԲ$ o_qgP]C<'E ~Pnϣ7M^wvӋﺁ}O7(HWseCP$jcN܃.B)f2uٶ,qvJUZXلXO?C;QՊz\ iRLk%>iFc9^lzZ \0MdRsf'Wq [mFflr oy\)p@ґ@) Ռ" %`P Tͫ(w2 JJdFQMjF| [y5Qu8>&*ǜ>]`OB$ړC*|ZH5@)I!9Li{G\ lmhg[,X/5hX1ՠ$tR^> stream x{PW7,IЮ&>jhT*ԶJ! I0TGeœ;sN@ 7|& 8'n2 )\F0lϜ |B߈=VPT'}1Exx$ٛ(ĎbI$'BO,E;ͻFص]UC%8;&>]O!Z`+g-}U´\9Biv]:&1nie/?P[)IMߘ7#׷h,^cڟ3T #n!A7@"Iý7]iim 68mPFw@O+@rf-]Xī.^stkL+(Rxa(RԳ(6XxJt`Lƾ 3gi~Iv̨;х莪k-pzyה9AJT4%x)]+)yeUcF)jʙN4R{N\{%bqxTr Fhq޺m#,7]=v΃g@jS)k̵I̩<Q5lirFЏ&q%,%SfO6dPZul4C+tAcUCö3pwE| TzO.hx*\&A;}w•uO旯Y XK̟6uzѭs|Gu7O,UbMyh|٫*lyp)SC2e 2.;${Ke4Asendstream endobj 175 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 5775 >> stream xY XS׶>!prTHzϡγ8V8b EE,! 3h &QuV*qh NAVmmW澾$콆_GeiA |wI_' - nV b k!)m/lG !;R?_af|odGǙA>R2O,Vl)F͒d;&N&H} IVH#|9, 9,q0:c~HЎp=d4.!k](]X$5Beb>WJVX&h)SMoƐNG7fqOHQC ʉF}HFP5ZMPc(O#ʅZKͧSj!5ZD-&QK(Wj FMRӨetʝzZNPbPeO zP=w^,ʚM͡P}~TjI eI)- O,-O[yZݧggE" &iמ{~khN -{ԧ]߳ߩ`;Ifn{n]%{?d=h A7{++7- gQ0F >wNd(YbT½KP>9+tP+_9 BKI'g#%b|}8F_:+lGw\ WZg:ي';l*ʹRrP *+L+BsIQ4 #*=1HSn K0Q 7:1Mrt;]]p)<}41 x#]ԅ>o CmN$z UIPnKJqX0,nh8`Y7En]nLgOZu_=>Ǖ3b.\ :m LuYWyzN^&2Z!rVE7@e[8l @D n%{JR ֛W ~\ZX1{chb/(la}|ɴBP.,-xG!̅Zo}0C[loviLbZ[ 8,S! \\>ajuaPhn:a;UIjnf$9~_6w⫨'*^95owܰ*K)ݙCF1h$+Nk*}ϩk '7|}@aVtL1jV[UI*#XLAqm AxYIىIh*- 1i[?5h:14՝iq4~ Nu[7‚: ZБu X.1g7~jzy GO[ d_1͈@ݫ͸[Fò]{$ũ5Ⱦ Ϯux׼AvvHǙXMjzx5v$,؝|\mH"qWd4;v-}|+"^7ObC!dd3\9Is;5W^~E?gTnHS|0#*F˴K+ %&jüO:?"D[Lk:,֫,:h͚͋ƒ@JPq/ /]44O.~xVG` ǎȆ5+7m'I AY3bܾVPUk 2eLڍʂ}֥m%e3~K"y1ƒ"I4/ -Fq̴WxՕo?xWLBB:Št%JFq(effʎwXi^CC9_]n# дM6,h :zP?Nna`[8Robd4>k;Ŭ 8:o]9)hp$|y~rlu^:i`?k*Ӣws^iZ|_!"#o䆂Jj jg E4WP*Nr*:F m"bSu30Z+N4Ы-k+BBCB*kk+*ju(spx3ekBeyy$4$4S"c\]ؐ F_#=C;rf2N>S7gl.#>DtezZdS++G5NT[cKڽeD'&.']i6A:`cd^,Z $ j45qVxrUԳ>R}om:Bt|`O  qY3?k"rvB'> UKf:JwѬ'0X1(Rhǚ{ՠF~&rnfhY4Foo)Fu~/*CyMFs-mx+!gr@L7N#|yX,7>y0ʍ*Qd}cܒBГl BJ#TaᝓIK2x^|[LTGFQ#-M)*;}(2S)F .鄟_dS1Q tN!N/CW[N\C_1`=.{Κ9}{m\ eOBWty) }ˆq>h~m9aW &ޕw08Bj_ʝJs'_,pe[ 峲rQ9SY.+&?OrgK傺V.6!Q9㟗,LQS܁gZ͆W\?.C)1rΰ Vo4µmktJmJJH2)#\A'%L@̬ݹކå |p4|q57Z'+P%lB<!'ŜI2 $ TmCl!ÃG*J!_HkK}?'~ X= [pb'€>̺mr:;5[ WZBK^|[h{-؏t v$G<&O:֟^s{^KbDe~R.f`AFDǃ)H$f˫`3pq$=%[`aP?L`wwnӰt#|A4^~/\ AQP|> stream xcd`ab`dd v 544qt~H3a#UAVFϴewY3 0012:)槤)& 2000v00tgcQFBըqVн_pON@[{W4_N\;~*{r\y8Dendstream endobj 177 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1320 >> stream x%{LSwmi{NzL:r90d5(C)B"Ϭrxd l (GFWf+_r;sϗ$8IhُdrXW.dc/yS&ץ^~;灐 B<(8w .I*(U9jyrV쑴R)^$L!S˓$H6EhM8F$isRZzol/BT'o\)ΖkS2L%CZVB&U5[B UVG*2uAk֮!b!Ań Ḻ$(bFsn^ueKlm$Q=./hLx HJ*h+0F*B TàÀWܖ p:hv4 m("P3.ۉ}|C^Qou!(G wi7]};1~Ӿc՞|^ou^ ~7GpVB Ʒ:y Ȋg?q4G`[Յ="[-JuhRUĉA Ǔ'7b\3sedP;`-06vg6*M>ԉrJUb(*-,Tn-40o`"gk$Yb@چ٭&813x|lYdHƲ K<3p*4 d) rzp"2=墍l?m-wq{;j.u+ЗI΋aGJ}<(᳂PX]Qy0s1r*MZ(J&@(\8SVeTkVsz.?֢Q3{?]Y4B'J^utYod[WC=f>n?R3cڇ{W`o쉗`9#'ZlVuqXl?Сz>Ų6Cl+ 4&۽wYi͢6)쁝j˓48f%ؾYb5]]FZ~"hʤ+ 5SX_aX_{ۉd vDh2Va0 'U q:Mh{!v#hj5}:xFc0ȮL9Fw ;"mB.3%]ow%)6ŶAmMytߨ> stream xX XTU>Ȝ#"xKϐ(%o+EP@n2܆A@23k\: 0 y+ʲϬRL\{5 ^kk:oF"y/3I|Z"#ɽdO0iaC?зyˇǁXO0R$2V  Syv8'z͊ VD-PGۊ`U0*f "G+Cg s Vn 6':J$ 2z/ȘxUmq`e0fG{ǼS͋uAB@b`Rm, _J9|ڨ }=;?,eܙef93aV0+Uhf53YÌe2u7y20s\f3,`g1/0%L3pcLg" Ƒq3ixLI\i[u}wy5ݓ>fK n}W9T q3NEO/yJ\g2xw?~Q<Βb}a9烸K>yͲKa`*0i_spkA : +Y[T e` t^妋 "͆C>)3yVN&PoV} c?'}NQ+;oPװ!Z A9(~}|Lr\7h XY^2c?Fbu8$ib"~8g72 N|: $AI?Cw `27} =*6@ +7F%س-Er궘m_Ij2y{as]pur,&lA&?Kl=Xz$ $ߔvIpGO\>DrNf,M@pWvN5 WfE4Ύh4_ĚsRq7\) 'ą8~G':?xRS<$A妀Zt;OxXAw޽l9ķ( :VKN8.z[muiOdҀ*Z wX2w 䘡L@vvd=j$N4ԣR!N孹BZfdde+jY-F˛mG3l+aJ`9H4AS+H.v$`vd.b3𽡅cg)nOm7NQ}dQCa%;$g NtjBFhVb؈1Ny4cgZ9+^R΃˻lb{Jh7xۂ7nWT'<>Cy"׬?V.m=Ik NA5*vF˱Sb ''RRh;~mN'[=%_d5A3YNư3p4眨"C; ;7,Eكq"m-P`5sa]s!v)!-~6mTs߇NއvcJvܯHD!mrP)XMZn#A !Aе y`p]9 -DBmjIh7BFLH'\-z|M xl6rh6} kV lS sj`"q[f_}rA^zk}Yri@׼՞Wm^F [ R שN]y $@6K9zv\Ro1 i!4 ;@$H]fAE]aY6ͼ!ѳ w+pOiF0B^I^mٛ6#sV2%`ӠO}s58G|~@ch'png+Y5 zyC+ ͕UursF ~NugVigfϋ_A׍3= h;Qe|q;!>[@dI)|f2|zmNKss[0Gibe>Q[99CpK73(%X9>w`v-+-n* viefӜwYLM<\+㩱,PCnfڻDq/Əxv}IEsב6Z<7AlZX \/X[6}Wy8'|{_ U/EWR\?Y)ktfr*18>\:jmeN}Nh+Tʤ|Di%1 >^]ZP <7F{n*q5'!ت]_i{ FhGPT۲՜k[:%:]v\uoփ&6"~.xGMtZp 鲭 IDuWOb`He1;R C%tx/TFa\O(!%_WDDGӂoYHѝ/*4gLmLM5 nއv4}e>A}!E@9lE҉4u-H9!?8~R\سU20 :d:b)̠ ̢vKx2zw~hZ*T:K r˝om|S\]BUZ*&mOς%W"H<UՈc([4Bvw>$6+d&Vq`l4Ṵr5zIVքgtXwv0>[;oi2$]]o^@>0\kè@ _KF]i&@ɩ;h&Cie*?,Ϡa xmC)nzHկ=6,:Qˉ] ltX{6B#|7G{ҿc0 [m *oX:͠a_Տs\ZD,ULd$bBo'_v%Tƴ^Y#Ӗ@6]YX' '6v׊lUlj35 {GOΣ .,WEZ*/}bSf$87<{DޜhKMPӱX:|Pn0B>ULⰰ>ll.1T$|MnV!~3Є|*/`5R6ɛHV cFEDvؿI.0?PeLbJ>kP LtMAS)c !Cq%d$yZɡv^%Dž~t))AN)I.yf'vKAm!B8OYiG#m˩ڶ89'Ki\dݶZsueé"bdŊCrRO}_)4 *x:my;'Y %Gbm~(Ѩ{{ v2|_<<7Qpے4K oba82*.$돤-T~-Ċ+Ww-,oʾ* a)h bFk_7o]l{Y$dh8PKy2hK"Y{FH`)k?_bC?Sù  Dendstream endobj 179 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 564 >> stream x)CMSS9/u`B@.5b  kd_nsCopyright (c) 1997, 2009 American Mathematical Society (), with Reserved Font Name CMSS9.CMSS9Computer ModernRS334O"-FӋ#J4RR'SCJNMu8XXӽv_Y[0"1('rc]O||}_MIRM2:?L{4N惺.@uw יoLfv5x{xJ> stream xkte' 6+-qE)rKR/І&&Mz}ڦ4-VE]at#貺.a'=QaCd>~bFYڕؘRjҵ‹ZKԖ(,jΟ5qSU,feHXU$kB+s5y:@17CYCă9 kuwf(375b1H"-\"G$Vē:bH$(b A QybQn^|'&M2Zm10xY@'#Ƴ*jəFk1^bQ9W N::x,wH:ag+]=T=T3=zHoWV}J)Si#)^2M7\]|su!Ёz[}|,`13cdMO k]Ht)zܾԢZ/ 7ȏ9c؀GApp5A_g.y.O)[ mNp8èC6J/5?a>cx{e_ըB?| <`f]|E!P4zL밙]Eѯ6q+#.?}WKqքi-m@n^#-c%,˰Vmz`ȌX0KTfQڬ+@J;z}\sxbib'؇V[iC7?\YzRangm^^"v%O'鱻M6KF˞4(ڽOj#! H$U=rMY+ XDe4lnkm{܍ nw*\uH4;|g8O滷zSk85_Δ]neu01 B!QhX<ߡ}@dYgA 2BgX5ms^s=|h%.aAdtWA Y EF!ՐE 垀p5K in "|"*JY[aEtjQHeg@&7¹7=Xl:ڢJb217^slb4&dNC !jg=1PIZJe7ۍ&Mqy):s[{@{4_<{ͺdWivw4rоSu@Myʼf-XeG.jGFk_j9z^ljWpT6oh]C(~ȫ ;0LPUReҴ+Z˳h/xX3>h+t,~ᨏ MyI.hblUV+U}m"z=Ej'o5s:lˋwo^5w g|-@Yr(%+kJ[Z^KFF%:7 My>m2)wP5i*|Ruo90&c̕'Ks8Ct[;}ʵnc:x?nzW5 0<\h[͠2KƈK:?Nw ? 4S=@~ _ spl!F;?/~Q" 7YZA{ɧ.e\m6U |J2~bk !X#@at58oKVV ?.MƓ+V |GV'FQ1nhff:C==!9^7Scm{'mwW!tG'$IC-dOHqB"D1ba\$O\Է=, OVētithwjѕ?绞lmً#iuFWV]©v]fqZk9[#?f@;f=&2'iM8fSw5;4yiu$>̣ʫTtsaAM^'H8p~v!ǹCR( 6:tܘk6e9ZT\  ~!!g{ j*ط.]5ԗgtqgm}lsL ybF?PϋG鈝9GFb岭/mןAl]QrB`cN1}Ucp /wě?[E-b^;OPTlYncJeYjV,g梽$3a*]?"[q@m;AiDlwD7m?K44_J?ʩxg˓FOFGĿrendstream endobj 181 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1157 >> stream x%klSum D3thD]L^0XYh;X{kuwmrڭ]{]:nXL!"$&ECF,Y/99_!<A򊊏Je+Z&z8h ֬.y{ P7:n]M<46Fݬ=ᘢuL٦M Y[20*NU\95hYmpiVDǶ+fZNa-U3یTgMKRQojX3SaTfIKbnݼ vJbAʑy_eX;.A|S 7{oggN^dOpCCŸ+CBHgݽcӏt)R^vT?7SA0bZ`AmX83pڮvf?J3]H:y}iGЎ xPP4vuUWwx&X9u}nv&s H*M$Pv'!=h9lsx<ﰻ&鰴ceÏ}꿕.t .M, }AjBmn]}BϜP-Z+kkYC4ᮦs}d<&$3uq:G[ssJ!.@N_NPf{HI6I.Tvf?|> stream x]; D{N l֖¢q$XqۇO"CfrXisN>1Rm =H3.Tr4U#M@_X5IpBbvA2-{a$JNFvN& @%9 %GA*ƲVͽE!\endstream endobj 183 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 709 >> stream x5KLa/ IMQQ>4B@^ ch#X ؁)-2A[F]HLC0!QB]wha2Bܳ=Ϋ_BOO y :8eݚw~RAq0h<.Q56N~t8<>4SBv:0^!.~N Ú @XZ q.Ѻ_)+и԰tcnEtMnMhx,2bٗolYm^kr^cD^Bjt݌>]tB㓺hgAUc}[__X1שAn'ETv`V'l&A$ wu bZ8)M&ms(Dg i_>?6endstream endobj 184 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 860 >> stream x=oLu~ήqwo,K1Fhb2ZFK{ֻҮ{XR jהMGǀ8Ę1Q%[|᫻0͓|<8&pUTyuI+jO3Vmo(@N\Vz ڗ0Y焒yf[҇:::wìױJǛg^-ۺ=OlƷ[3o{'p3=c:+Cl۝JjsVqb&c]֍X=g&önqRW".0#!h#Lf$KKkuk>ICjja qտo l I٩30t.Hen`һU3,/#8sg)Dhzv*ZH+ q[zShBeROWbYGQ =!İZcgaÎue$\~A c1kw~Sc]@_sFx `]C';wf`PޛvX۰yS ? ~ωY|zJrwWW!ȎI[/CB̈i 艏 120R¤( _{Tr1r Ve@:0x2B^_~>  j~/}Sˀ~xJ*тw2 5Uu JBX !o5VΚ kəɺ__$_P/-|^endstream endobj 185 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 440 >> stream xcd`ab`dddwu041H3a!-YedeLzxyyX^%{ #c~iDʢdMCKKs#KԢ<Ē 'G!8?93RA&J_\/1X/(NSG<$C!(8,5E-?D/17UV=土[PZZZTV(ȲG&pg_ݻImktqdwa'wvXSZ]_(iSۃO{wNwxWCo6ꦮ^;-_{o:6XӽpvWOEϔ}W=8_|6ߕwqb<y!endstream endobj 186 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 564 >> stream xcd`ab`ddds H3a!G?,i_7s7~!ȘW_PYQ`hii`d``ZXX('gT*hdX뗗%i(gd(((%*&s JKR|SR222K* V0,c{a!ZȝT?DO=cz㴺ߩ@=~z[oKd}Cc]SFiAuum-uO6M;Py:&vL薜1um=|79{N'?/{Ѣj?٪KKJvϖqǖYce'g,]̳7oߜ~3|zw{\&7+ܙql7w߾sR;᷀4э~q< >*2 ozcNy^/it\;wb^Tendstream endobj 187 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 6509 >> stream xy xSU !VB " ȾNK)ݛ4ݒ4iҴYO&iڴIt_h""A(8 ;x.?I 3fy(<{r.<{7\jʍ'Mc7 ƽARG/}qi}Ao>ݽa؈~0?ҥBT1*I3fL1yRĉ1ib2Rc2?R"6c2f%dffN3>&5cP?畱9 2q" 2#VǤE<'Y LeeƉ#V ʼnX>/m|ċ3df-Ή])]ou 7$mܔ9u|bʫSsF2w1;{1XC "L%b2"6#(bMl!mbXH'bXFL!+4b1XM $vM &|;1 CDO9b8ыE&f}9D_ џ@$V/Hyn~#u dYczVj:>^^[z=>|wr~m@#?c@Ϧ V 6D4仰ay//D}ihЎ-/e1+=s}:/#s5}q/hC(5) / AA Fp9٣ T)&"cWhk),zAt+nL$R P8?^\w/wBrZ#t`mpM Ty`ɖ= 0JV0}gv܊. 49tz8vXw /K yF w)ަW^ 5EmQz䱑d*  (o@pGh ]u|.%!GJAl/܍N 4rc 9$* .w?vPm2Aj tٶsA2I"|}jw^sa97ơ7XD}`$htwɍ ͉ Zj|LE]Bď[S 7!& šꞮTB GS AhWJ9d+\I劽0g>nѦ")W~yL[*dLWx b'x4F[s 8N;M-Vcd)/pu,vRVU<"^8!@85O5ִ}`oޜ~W$L)0!τ0*U4s>8rPnYI`ɇBQ'(I8߷C `рw$dGh4 bǒ>nb2sYm㼆ngz?@ A8<LVis(!R rQ-.e6KO =fre^єvm+bt+Cz!OR2bkfN;<@8ۇsSuscjN@)EnbZEo URX)^x3/XD<}-6ap!$=fvx$B.2F"CKiރChyko'Vth=uj.>Ca?KAzXq$ g_7Ր+3܇Tzλ2|%_|͗|X(.j%hsـRH$1Jnb&hXM<~ZnT؋O5֦&kFFg~s/2o g~|7n WP±CA`H|sy)3wнZ wyZ(>oy/v}sդRo8K*CǷgpBui +̈́tՊ+dFZK]&KT,'<\].irLf\tn@qZy82/aMF(H8n-}x-{1$qo=L8%Y(9q@O`oO t4+,sg:Ee$Gb]]%Z5go'HKJ7lE$KvnJ."45j-poE̿ꄧk@Mgh^ԧܬZӦ`3-ys8UcnuxPY6#9-" /K0ػ%_4OVUy,+]^8hnqac0saH,(/mB{wHbjΡٲ t]g繛cSד,JmMG>vP(Wy@6kORb3ʝ@E?[K+P` 4O!a>"p|^>͙dI~۸"v9QJ/y+?5;χ^ϬfJzʪ֭jԏwNSd\52U)phPόѦd=d@ d*eҀ W] Zt{|WCv1i3soHڵjݚlJבcl }h˱'_FeL?ȱH#&twes߯Vt$ώ_S7D-t%~;%;XV5ȣ8uz:, r9H_y@…d( )z1URD&6O$ l©x>uӇx()J&!Qrm8ۧ.Z[ٺiq'lsP%ဟ.)ڣ;n8]R3oj%œԼX-=qs6#E ٞ Q:6P!eK,fު".5Z229hA!0Qk.b`&|70]8;@GGPkc0J^wlJyEN&KcQ׃2$$t'{AQMBgUU="YŸ[Dq7{nlLHLLKloo9lEC_I^#.BEysˁ>-.+ ,)P`å.Yig?aM=i˜:?(@]p턻(Y)yqԣ1|mq{2.̚&ߜK˳n&JKK@%U#-i y zb$BV -S[u4 sWRՕB+OÛ^8;}2<4(8vpGK2;1fP>OhuAcm K6"IAF/N޹I i8((9iBY$4.iZNHIIT3}p-_t>g/x$s}iX#f "Ua$g>JTh-4 ߣr%Lea ZnE>WX}|y/ M4(/)/ߒnx" T8V䰃rYΊEe fu)LS5MUqip\ %(5N5˜* , 6htj,T5tXE;^؂;{XeR ?^tI\F"8MB<z9N3A#h|ezcf@^zv _.".pu4_5j-yyq3|/_it&R(VA¾.e|6AUZ³d9Rq-N@v*- w5 Qzhm,UZko2&6ۧJڦ#/]Q$6Q_D"L90KC_ksyw|XGÑAQD:8d#9BQMVDȠada5.+I Y8<Mb@Irs%X,LcUfփjWEef`G>5#D WP4Dr(ei$/o NOon-6 2QwKCzxD 4Ms) ׃AE\t'GZﵷ,LQi2ZZlEf.=XSq2=F[mUـBȇw>[@sbEڋįBe>V,/T}}ŧUtD:|*k枧!^F(]|}w~+_84u=bd~w.Y3U`jg(x9+B3mh>\-6댮 ;5w\wwOendstream endobj 188 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 3408 >> stream xW TWbȗO@@bUHKֺuaa [EWRuRڊf\ѿS͜ǜ3g޻߽SGz-y9S,sXm1#P0p X;w2 r#g9Ӈgsp7IRY<6F-_bb?䱢pgPR IEQTOUbRjoxW*YS{RDɓ"=7J%J(ϱw]/MQr id\BuzF&*<%"U"ʗWy-Y׏ %By6b>X@F7C?<è*y"?xegamQ}%r?EOmΞ!+a+m yj647f|iVEh%ɭexInu\R.zOHfp7|@+ dJ6h`wP2)m{#6nd+krv+;|Ȟ&2-,όQ,D5Bi5~ҝ\pr{}72ћTD|0fFJ5' Yw}]y{ s\4~}t KQϊZ䥋˶T>ĪtLmrd%Q \RBmhE=c09]%،5kspSabMqjϸA`c1k\:G_brg-83] lRUv6TM>!GYihrը&% I#'D=:&B&fPq~Vg!aϷ~JReBq*./bh!Rw5!;8ۍ2IF)K4Rd:&mڇm=nRu9 nOe&$GUIcI<}4"cQGRQ Fq;{I۹H I_wΣ2#iwnFD~ݿm !#,gveTTJv`w@vϐ> #킐HPN8z'餟}B!'ldl!'}wTf_[5rS9^xkt:ȉ"v|\I Is''Y e/|@7!pXތ` KRNrtJu'Rq6sMC‰A}ʇ [Nk3&JƱ_G~x6-W$*kT(RWg nSjv5Xezτ2&>\{%i1ڰL-],jFFg`D}+a& 3y3p§e ]nw~7noX4Q_R(M}jcwC Xv$Ãnҟ8AD2o+gXMʫgc1̠yhMrjhͮ 9HKi˒ۚo! w+ /']ܢ36H+˙gk,&=%4PkPfqqt}e  EH6+{{QoE[i>%kK3j`>"]},tԨ7ҴSjÙ#qmrz lL.]}FY,@fG>Tڒq{2sޏx [z =2k ^Oa,=)~~ 8Qą5\Ջܠ O}uɮ$N)NCy< h뼫endstream endobj 189 0 obj << /Filter /FlateDecode /Length 4729 >> stream x\[sG~/;JxSZ+ˊ%#A9tٞ(<=ӗseBr!ó_=1nq|'{Iuwxxt3'}Q.^W"ȅ.:5kU/gݣU!b_Z(LyTцnSlޫazwC#;>)N(!qcV\kXtx]TK9Twtk^ָB;<`잲sw}9\~mK$* 08BD:DnEe WexZ'e6voey<}[exXW4! [pSekxQ_Q!~.uoMTY} =H# {mO AWe_Oqߕ&)/h]@U$~Lz^/w#V~Rm]+?p=jEJn&}&4lªIFWe`K~PmC+9j_rLkYA>)/1{/񇃕.;ډ*G ~;,Ab=O<18DJpkۜr]dOF%KN |尜$: o̫yCZNpPk{[!+etpo.v!ZXV^ 'k 3A;W o"f{4, xqqG2]1!,!)9}EBh0{Wޅx=ѣ2iטMg{T5 T~4o7JG6-m%1)a$RMu{YJM6+,'^bz+HzȆx^yM "\Ҙ aQxP10ViⲣBpb|Iw1`1\saa3X.1ƾvEyz"sbr+]D̺fI 67_=;_c @d:cGxC JsNT俊Z떱qblq [_Ů\[h vk|?QdrEx/H#Gw#p Ma7婅F!y]8O8RRNc ~D[124hsjW扺!/ EdHX<nٝSE!)mD۟bs$(`o^LLm8~D{b.G,2k#B3Fpi֓J)B߶iKLWeTƙѢwԳURFuPfZHZI[Ac 7e &$<_)rV Ȃ_Al AFP; $;W "zPyLzJC-U2a,Wh+(`>iI٫Jwx7g 5DVi<*e 1񡗪BѬ=*̓f?vߡR _c 5PMghd][u`rٞR50~0 T4&~\wu.uebҭ4bbkyybƛWI`V~܆4RR_n/I^rg[ܸ("L45Y 就Cs [NR 0%A o5z6Ϩ2ֵ?2vn,x y/ZuJv \LfQNuhO2}OyWjlui -J E$ϡ|s붏خbPD+_cУy̱@5=}Rk3(MT;U~ODa C cnb(:ޱ@p+x@'C>R]y&P}DMr@أ],F"-/&e a-LI*ꧺ̫̎ݎ,l5cUVxB% ]c0},vAYf[&o R7߸X-IQmn) 16 zp2K IŭrꄪdNL,aK3( s=I^n'G1kj,Uc)kh$FI@>RwΤIwm*+rf'6.cp%i 4?e(S\얅;Ri2 Yf.Weg{9FSzKX3sO.9fߎ曉:bC,oQJ\Vvvj_gQ _D>N"qnEZt'u_yvBemo>"Қ C?IZWj'X.7,pY'eLivCvR︥z0zO| uzl3?o:eb $M3B4pm[e]=xh)~ zz1=KȒJLJ$oKh1bzso(``{a!{]3ww!L r!@Ay2GJ4htMEWC2Id&uý#=}17n ĝ6$=>|/WBS#! Ƚsn!RȳN'2cy-" @KMZha ]? T87?>9{:{gz.$J7j:Crv1ENC|\%"RQm{VH0ۈ2~2 Ql0f3L9$$x#5A!.ड़2ma (L*3{c;Zo~ 68c )vz^;. Ha4p !`:S*$ ?Dq2A1A=`ߴQ r J-x¨l{(endstream endobj 190 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1401 >> stream xSkLSWfm30t H +K+Xi>҂B %Kdw-2_Qc|p"n /Knr?B<11dokp-Y\/b<c> ⁈OpU,@Y>(m>qLϡ*F( ].Y.٤Q4V"W0*F I.Mdr$T _bh*4YR!pĨfTxeVlivF))Yd:(i\GIk1 ,"5MJ1l%`X$&6c[l;|0t11ף3UdN֠AI`xn)4*Z Zmԋp#w@ww&SQ`b췬u_<H)E8D67.AO9Âàɇ/HW/GK2 GANe8ͽm,Ա* Z*>$$O {jԲYo(r|55Yp74FEEm;zzM;S yfʐIQkdƾFBnR-*)XjΟnnc"' -iKꒋh> stream x[[s\~WG,p'sH HPIʃ퇕,ҮXI O̜=gg1T*E{43_~7 _2nvv} fgYCQD9;<=KLYg>j;;H΁TRh|m4aTFTw_6F8 ;|\lLT{nw>hqg;|z7`Jζr?|v0USF^3[s8q>3&vȧUu*z!"0'|29-aF ԫS\)T]0yAu@_z1>:[9XSH0cbN1+j0 8!hK32 5f:&LQ1҆6ʨs hn{> G0|g0U:e1tiƒ31ؤll`:h['T&pr#Άf!f6wB^:Sa~[Z$-  ` ?x1aӕp #a&Yz]X2-m@!l2fgh/,KitALhwM@U{OL57 ǰq|L;?_%U=%F4h*3DfVW͹MSnDV'A^7S9Meʴ2fJ&eVIWb0CkŔ")E(Vu X{@.pÂgu|].:+4 m,qNco|MJM%jvǍVx&˦ݽN!@BK=e9׽ ׷onp4dN Kx5@%șGDD!l5Niz{C,NH?+KX 6wRdQTvZfFȽ;@e rBVP(t:D;Kb(GgzW3wG?R(tPA9UB'2|ЇZT2n`K[i@jl1bS ^̭M;Z8 A6oPu11nq7֠kB{M]5o)ΥD}0 N T7v\1V^bD_fyrS`տ0ڙڂ=ѯa(ڝ~:ڗ[2nݒQ\%0 Ƨ1Ek0&1(^xCU\CЛI..V46W*S\yN@ogwgU J`Cn,[|%l:]r4`!HZr#s:'Z\P(-o\<9ܰJ;cJQFI)`9OMaUBChvB1C/㾚NzM9,oD?{zUuA*Ek"{"WDyI "ωj+݌2y}^V,?2io 0\&!+"/=b}E,NwcNMA0P,9K=yzC&H/ '+uz={v8Q6 kKܭ'.o.綞O@О7Ğ?o?*cr G${T&̓@IaX'ɞ;"%w$O}&)K?.c'^~ܤGtsp f=R̤PF偲Ǒwހ9;0;~uoI]AΔgΙK쥝-V, ?g@UX@m%+V -XLQ%FV)oRƌ>Ufü<?]L`H&oyZ ?X% +`0#T 7elj86=_pJ PN7- "TʢXɕ} CepsUpe2frݣv%$'rE-D!c" f+{vpLT9V%%4)_4I6wxj[CXPt1(FT9ҸS6ݹTx@p[1 R1^C<=O*μbq9mrfʯo!Yiso^1a]vvkVp_izz^]rkڶ`<̖i8wqZVkN>dvv_kq'K/UחcFjendstream endobj 192 0 obj << /Filter /FlateDecode /Length 2708 >> stream xkoAӱ~MH -BDI-6%?Pwff ( OV{~ D+g=>w.GbvqHNgOpF(*gAμmvvr}ԄkU+'gGϛhU!\Z(L~9_(hCsWlޫ\fN\JȦwMZ+H[]T Y"2K[ĥ[ B;"QQ6fo {\ B68U* 茉@A/DlZWxMw"7dyWYEX7ωSI EkAE+!g@^Ьzc UiBs4W4g7k^E.cdC@- 0xRgҴ846xTh:#g*s+|NV9r&?Cje+D)[,$Y Dx%ʏȥjζapLWbd?M4™7cT ƅp؆5J(pc20:h:6MǬTt`cn`bEpəpËм kh,HNj1(yoʖ'I;481P&< ZuJMQY30! R}\Mk_VKP`5tAz0rdj \"/M H@9Lz(o @( Or%t ;Խ8)mU#,Ӻ*WOVO(1#~MFu#. |qHeA9ϧģjP %#_WO <#!eU7T/3tK7~UŰF~.~OAB\m 6$52B(h0?v0 4VBd}"m ,P-Wh6@ثaPCVTUf0&U3Z:䟺1K뱗oC"3"UZ~NPOX'h,ol^VOTY4)zF2o5JzS;)OmQ48Iې/Uꅣk]D`6!nY YM?2J:41ȨdjA{32e^/=zfŇgǔKRۻم9Viբ_Z"WfTUeak L= nw.CW@6sq\ lcJWxk4Qgh[N5-XniF!e! wȒ[w4\HY̅,/>e{t|+%@oզm?KIgZY&hLPNm̠xbk0k]uiޔ'lLs1&u7S;T?cU=ؓlo9#ԋrdp,j͕~d7wJ(o.T(`өq51yLY^]A7! St-21&M뾙t!!K?5s"FXϲk6_4W;yûZ%4r}r%jov9:S ~NuWt;KT+#0 dr7lEYeHT U ) V }.ÒO30PeĬ k|WES7k%!.#!`WWL2BAYORQMU<U!Pm>5|A`MnN-TӬd&BY*\]@B̏nEDi RݳڒrE3\fuf4XwҭL,vo2|qwBŸ|󻈩ZrŲ%wF)ۺs[oyD`ۛ A]w]л qY'l!k/oļ}tBm-gS{-tl11*L_^m-'.+^/yfx-* }@JWnD^ni2נy~*s/?xL`4F&u܉.幂CGl?Χo< ͪx ex4 ?yRV/M\T1&~vLgϰhϜe[%U1U/^xRmV&E8Np,oE~~8N5~#7 1KrtƓoöSm:7'G "endstream endobj 193 0 obj << /Filter /FlateDecode /Length 2653 >> stream xYKoܽx~?IX uxyS@S%HjI9]=%CK͞z|UӘ|_2~ƫO#~_fXi=|<OXhrVK=Gɔ;e k֩H4LRV{V7@(Zm=r[+evKp͏i ۭw^#g&aw[s*0u ]?݌JTMJD(H{;w7K c`B,#Ceh%\sܘBOs)͊12mc p['i^i˧-AΘeFItP&6AlíuQl :~WA#˸AKpF(m4b8Ru53\F9l-0~H|<ܣW'\&d,BƗvW- + I2yb*|x'h֨SU6br* LFÐEQv8Np}t :{-fm ׄ)P ƙ 4cRH\-.r<LE?Q;УRI0h6viVԍr}(sT[ A3n4y'Qk1& Wf"n2u&o7\:0;jtwer[@>;e&grE&3y]=|l<3yeݪ*^cn!LI~Y )2 1 @ .I0 -!JxaRs~t~gH :VX ԩTE6s_,3"'3p M#glה<.qUA!ag ײ`m ;N<肋ea rR7Z.b%ǻDwŝ69ws(TU)-.ZY9kS3E߮s&1X2\NUZ™>\Ug,Axe0j0)B+CoNm6L9)ғjl?4é{XO9u~|  I i8\Cܜy^U5QDiG*ꆻj g$R-TWՂԬz /L-/m%uw# 6;A|Xc QhH Щ@l@*0I.qC`EM#xB@Lj|]aStsD՛b3i ,>lmI˺_er]y'h%-)쪗p_}L 4D'LU #'FgTn|@?0*t_mxbЯ*9tÊn}$ɤ~jOIT|&i@u5!Wjnw6wիePu"9[?D>PPCIj'h8  aΠp^^2 6UPOJxެ )@T gEV)KI[BGςvi I}QK0Cd !705 Ű@v?a7J =lvS%H5CУ$>-ӊgEQLFa쌄~d^Df} g%'j!*1|ٸKq OB0†BW}laʋ(?CH Bo{鋛!'@QmkJhߊN q4n8]V* NV8:}vCE+`S~0~O2ϊqi0@EM18?O:$vhkOh`K{ol-dxPKC{J\I!^e9> 9U>cF>v-6=pͭqQjr@>*h4orezuK!-|lrpMT<<;b K}Ex|Y7λ'Up GUx\wo_V*g<$nO!ˌIY7z~-/'{99P C*F >&'1@Ig ڶ|Jx\e1͡@SxĂv?ۧ>0G8F{ 2﹃R8NXl F,o;I|&-8ۓɓG!Fz7PIJH!0/*}7꿠,y^=N6}yt{7A:vy%=2TxYY~je puɿ*J~:5?K*snuWg~Ec3[g}ol,F-ywȫS󮇜?ԡqًd̳dzn!> PƟ!HIOpF*qmϓWb|= `:9zK}wg_v/ )(ʔvVt^=bGZ~^~< Ђ}; Eendstream endobj 194 0 obj << /Filter /FlateDecode /Length 4969 >> stream x\[s\~g#4h~nm%NΦ6.'KʻCr$[ȢdIo7h!uպ`i|h+1ȕ'WVڝ|"_Wgg0JruvuBU+o]]8={ o֟nĠb _A %YO7 6ڰ!6F 4t8\;c]ЯXTz~x.* j}t 6KEZz05ΠWfQf4s>m79i9^@3!66A¿y]F~Xah]COn/9SZ~LLжic&^DܼNm!p2 ؕ-#Mb\_!߂,xf:" ɴ~4֟i؟X'-_5u#Fyr* >ĮqOFCܕ1JMʒͩ< ׾+8fH":$YZ8iX(@ݕ;,7G&$R+s$q1(h DFNAO ǂKLkH=X- }HYQQe]ߝ z=NBW 8Z-% Li9iF& R׿g4:807PF&>(T bx3Hd2/ VdSR P`arfK䭒a[2YZe"z`yPځ=>N_!}]cRIj t@#0'σ#U6~˴Y$/y11{6 <~Z+$Ҷ] 1F#aX7OArH .yB#y~@ i['NFjI,ikI,,%yu3#񇳓|E;A+gAAړ  X@=rƁD9cvjdU4gSW1& `HKkxR0HԂUq|6jznI Rk,9dd!g0'W:>[ܚk3Qh7ʨ@CXv/ A' mY%0R+^>cA 9kVA|F O뉄6dҤ@C\G%U88q4 3r&TZy P$hy_'g{dzD 0g{Λ۶Y JGMiF; · Iײ I 'KrN^O; T| x\vpD.IrZZ>,芍%KdqP:jew|ym}wD}> Kο}:1P7?H2-FG0(0*Yi'XCW|[nϙ- 7l&+Cvad*j#2.m5Q`&Vde ^-4?Q~mqaF|>ckŜnO։}zm9-݃`{:KQc+97Xp5.cmSEԀG-v=XyMH͐Nq5!.k.xx8Kl@݂]gHEXNdfXg{Q-2 ^.esm `&MAN k53)gRymͯjsnحnjU}[7tu>x_jA!%p!3vq#؞Y7ϖvw4dΰ}'>.?6éR|ۮڼ|Hp?\7ٶ1UhTg _Ğ)/?Ԇ"opZjgІnZN{xׂ%zYyvA:s, p>m,~∎腛9$8$9r%`f#7tr9WJ'\,[G-|A# R-/փNbvZiߴ<(Rq)H bA]V|6M6p;0ԧCgB!;M>Rl;Ew/jKKE)dhd#E icJ›M^Ԧ$4pm'pWЁ4&Rz+< :)f#" jK3:JMZ L`Q N^>m;SS12I3ϣk.Ti' _ޟxR9ɷv_ Z,~W.^ dw51z$@g?:()HymVc7Djx: )qJ.E9;JY~`U"RƘ_3{WՉ7)ӜB7M#GM%,[z{A)џ x3` f]*tƴ0-^=ytF՗E\b]ϻxt uYxNj#X萪BB1Kp42[<0~I8Peg1i'znJa"pb qjҠS8%ڼcEiOE5N5~W_ߎ) ~P,ys?7}`$n3w ̧[P.stѓ tVL6sqQ_<)݇\sִNO!`iLU* ,Ϛp S"Gqa`8m4:=ui^8feTWI"~x1 ,s/>ZiGn3he-,{[Ѭ\\o^_U-"iwb)d̩WG k]쇼8Q"J)E6v; 6>\wVNꋓ J*V'B}yyOA]Id% .[L`n&;f5goj.5lm  CKr^5C/Ee_K&W7o2S2ϘѕĤj!fBG LxN/@J|?DRMSu+ax(cNS [L^!wDZO?2,*S>Mo,m kͱRMg$ڥ\A(,A:d.6<|r41"x:-rR':[ O#l_N!kЕjmT=-WE8 ILAM+;{E14)e au DK?AؠF*D=dDGC5Hmk`:|a$A [o^uF&6IF<l*߅"\;!;endstream endobj 195 0 obj << /Filter /FlateDecode /Length 2838 >> stream xZ[o[~#<6/FZil>(~ )ؤlJq3{$-0aٗ\Vo'X=|2:KЪOz2{vѽXϼS.W[[ gҸn3I){UwXՇE[o,.6[:~쀛a _Ͽ5b c{ǂ˳'3SOfRΘ$0ރ0[|B{$H";Et.Ap\7H\GOpg̀kZǥ3sc2 4tv61?>x)Sh4{]VY`'r$3&彲 b,C2wG~CjLx-e.+-ψ,1`;<ߚvNƨZ[a+s2NZ3ָ?`b)lV%67PgͣTϔAbzœHRn&jQ(+k2}>{I+\7@XRBQEfØ 5)nx{0숨҆[tvt۫[% p*]?gxҢ?FX3:.n7݌h(VQN J\FaP3<(Nf%=,L@pD^ rC<>")تZ>-T}(c:YDbm))|He7*QQLTyNs~\Z*Xrу y5|&=\=E7&}:3I(rubXȁqc(h^( %GbJv$6x2z(K4 0+CéL|V@ܹVS\T{{$H.$M9w&;QEI,}}Ǚz@E`֙F8[6$'9V%- ,&gF_Edq+,p9+DK2>]$65M[˒U{x7-^+.%W 9=d69d3J )N%KQRJ_΋֪1 X!xTLU&], Fk6XCZ8^SJ1ܸA?#[ BSϐ-M.O%pM8mn Ȼn&I0F9FC.z~juyjoI`u=&&CZ@9_4UEjf]ڈ!IGR"ɑ3R>-` w׃|5WH8$f-Ď䥽)|] EՖ\@sd,._g&9']P",sr]z蝹s9#`C1zhb'6^t$"΀!X|A/.>s{ TsK'L3ِ >1\"no-LtMr635 wS(M℈rʩt W2GئDCcQRP?],qZrc7cs¤Y_| vaF3khʼna"#Ԇ$ɤr+6ZAxq02a:='npn6ΆI ugNb0}oN.GU͊0 Γ=L"T 9 4D%tIuF~tX90Pv!I66=`XA֤Ӽj*S#iCoMnmɻ@m], MU}\IA9UmrWHo*Nr|- V)Uh7/g 8ȅ)&%́hD]B=iIɣS}]UbZK4qx>;C; ǫ_ \H(h"B㜘qW?d'MZEݸZ'D4c0"SA7͖dgzPzذ~rdM["!-iS`q 5>LϨ%JL`JMZ]uQΌu6èn$Qd!Z#rS1f|3ƋS+PV{~SfMF\D@$WMo ٴrw+yGXʛdRf4W ZKfIBB ª$؞o]7e5cx|3\=$uCT $pJ=wK&~ ~}އs;<|RQendstream endobj 196 0 obj << /Filter /FlateDecode /Length 2698 >> stream xZ[o\~#y:kymQh%yXVbK+{%AѮ$?E<\3ҿ듗Ufv;a˓'<:Kg9y>[^ĭ|j{g듎`by~cj`9}^2g0uȢVtWHōоA2hK) pBve5./x3܉nI冷DYp5 87hϻDN5y<9EzB5bLYzxie?NMa\[xg|sB?ǂUҬ f=[/#o58J,(i+ ]]+  UaKVA>TyԡS'=KBm8Ƙ¦.d9П0p6m?&G]}Q+yؖJr׶+möXX|[ȳB7]⦐Uɐ%B^QR ~7 ͤ{E'CwuaKa~6ø.Xv^ϱyҺا*ƘTH+Y O7mc[-78bO9%6=wi䵌)]ΥBKw^2H/~ 3fEMz`XLk-bx vOǸ^8d`O3T_ɸJT^u7dpɽ:!'oɸ/[*4(:I,`nHQ ǚ AOH׾[sì2Y); !|m 7,RC䦐17PȫBWevo,$߻y0f1 Ebn8 {cBAQ sZnKPSU1@vFF9]֧@"Ϋ|=G8!xާ BMmq0ft* X^nsa|~T:齓wBg!ckxGȊ)i/\*%R,l4t9႘Q01e0w;m;v dzѨ䶐Bv֕h!S}5?(3CࣖC4ɻh ix|;1y$MPY/47NhT_!yTn #o =醤ep\6t10u"@4Dx u̽c:Fd!t<$2yjSG50oKl:+5(8Ǎ$]NtXL"'6a*i"CųvԞfr=Mg88mybj)-TP B^×)gXJJ\Aӯ0c*X!H`/N#kHkJS*rw]?eaס_R3|IYkn tJ~Y4^qh,B\^(Bt4U?AI>$*-ȰuwCʀIyv@WJ@#ݑGUvn/L=[`a7 );Y9 +\w6581huMZ"נG(/5. YʴH"1uIa㹘 3&6q aJP.X!t+lXat zrOo'.ޙyorAcѶYu4j,jїx,V9x4\ZrpKJ 5`=%UR %m"#36(o/,&'S+b2M\QV:+Ɠb(~/u(F#BY-J.scAʨ?hȃIvYMuJ:Ogbcp ͭCDP8N7& MUÅxy#iLDjD֞ ^t>b{eÃ<Ŝ匐bj4'cO4 f^įQ։=lIz^Lu6BVbg;j*LFVjOO!FPa_ ;(L`wi\ k e1)Fp -XS3t vkl,iE˒6wCO)V4g`lkF/ I8w$c#Z=[Y&L0;7&. :WvӎR,HǦ 2dlWܔUꍡ~B Z E7=7>K`t>8oUFyb-nU_ѷ4U!CZE4?.ۄu.$_\Ve|)JmnNf5oSѕ}3Q / #Nmʳ~lj*ȿ/Ofendstream endobj 197 0 obj << /Filter /FlateDecode /Length 2264 >> stream x[mo~8@j| #uh( UNە;)vgH{s:Ie!5Aj8 9RoƬc~߳џ~Pf|͈ǿ_ pX#g''4V-~lmhnX˼SZ֬U[W@ ΤqռnrojàhՋ A{o /9pKp8d`y$0䯠XmalXP~r4'xujV(+^ȃBq2B+E!]ZR-/F:٩옫V*#^WF{}2(9'r*1)d39aoZWu&Wq9 伦vɪ/2: ceBY*1$ ^ȳ:P$0c`w@^Y]]FC4-lXY1f _Q0qԊ&Ĭ5QY5Wa vZ]M3Ι"@!QM;Q3$틼jUwV8&9UBb*6qlw7ѓd쉳~H}^jos,6=yWE}G pl  $ =b"ĕfq,; t:+1Sdodf>]M DcٹNK vgh^ "Y-B~b}wq\J&zɴBQCxV U[RD\,C)U!<[/lhSFOH B yI|E!jl G2$.cq8{P-o!_qIG< I$AZfg~Rk&}Y қ+&H: t'eu9kV,$&w]~zD.&nV"JۧlG\B#.#Wnƫ>|:ծm@[v[tDpm=٢%p=Y yi}Qi!ϱey rsSu\.#* 0J]ϰoz~JKZڊ$q=߬dT܇G3+7vy:,*ϼ#GTn/7P9(I!q&IĻTY!︰;-hU^(q_7f&-M쓡g2 ]:i߆x8B5O?@9DJ#D`6&l!y@8=KXqӏ Ȋgd=G^?'5E@;[MHKo 3:]3EJ#R2M5Nט,IjӽguƟ"$Fĺ6~5p̉55dIq2XItdK^+ZGIPt$ 4kӺbkP֤4B $ҐemoVg$y!=%@͚X` ^]w"w*qaR@a=Rm!m(_* +%Kreޖ._#3e0 .D(ߐz-=$9 Btys:,5BPs$F^$7o{ G&M{B*C'Hu ) Ao PMsohoevv[xc4|h6.[Э -xCQߒQaP:", I.HuX=*KlngGO HlIZ '02<$sYU!!56z&Au^Yz.|?1gFC"G¦Q LJڍͶ#aǾ~k#P=- ›{OAiSB\1.qEŤ/Вht NWda~=rڥ{JA u&YF{/z0azwwL ec͈9?ʴRunп,w^rQ#F c݈YpJ1 >JFĚ#K=b@:Y|G7yw2GV/sÂ>ѷatbMCz?B oZ=> stream xZKE_ c"p,q 9ލdmoֻ$S3] $ 򩷦Uj32z?cz|Oj_5p{yx2Fhsmn٣yz杲sT{Pp&kNJko{C[oZ1[Nygi ;3 ֜-C'WqtJ񦓺w ٣ּ3vXEg^ei?j|eneAflIxgv wy3ދ^" gH>mN 3|WUm*;^U瑃&^fyQSJ?wQo誂CRLqYܵQ7F! J?j)?8$.Kbz|;mQFQR bTtYU!1W8VS .>VIBfzM nJmoWUi.7eUH1~TeRUH>{Q$3ыՈe8Ó Ϫ>*%,I)k b}1CAYDU[#1^}&]Av}LxZx\3ƕjxelAc0ث*n-i);6QʲˎRb~6gЩQj*o22CҚ>2]2ޭ*Lpzj eXF¬GY5<ß|i/3|0mOgw=_1ƤN#; _2&M"grut@#pn䇏4\Ieyd .]iP|?O )J P.'3=s}$@lU/owGdc .G"O î,DZtxwv < t#q5AZQma4Kx$ C;P /%GZ ,D0+0_E{N()ܠT7N` T2GT<^Ċ,h.r@ BBX[+.{l͵5̽ȾP$ FA 3ʙzPQ8Q@[ E1<~u;mH}3tzWԾIjFXŀ^"ĂD ı ,F&Zw_vG|YGf(2TcdhU}'qyd7쭪1OpzSFsDF[Cz)4%,>c_eFs\ĵ#׽3dUHN%')פW Vwdcw z5ly @b<8Q/9c/e%vna:n2< ճq6,$^!2@ZOX^E3^">>@1z_NNݸS 7d] *Ja"V=r>mAaO 3$4rsEXl2TNԧsۧ] $p.9.øeK[z%y@%P<@`Cm3T5pw ċoma㧆endstream endobj 199 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 534 >> stream xcd`ab`ddt v04qH3a!]cVY~'Y=nn5?Z ~!XX_PYQ`hii`d``ZXX('gT*hdX뗗%i(gd(((%*c8)槤100000020°Gߏ,x-໨ǃkוֹ#7{bYINS4e]ne]6+fẅm ˧6.(N52wZ#R~zgw{wkw[GGMDgswgwGw v.w,սż,J"I[侗*6NNVUs&mP75C>2irNl5%؈~7kʪ s8z~b+]#nl.-b>4>endstream endobj 200 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1516 >> stream x=S PT~˲ //DME(bGmg., ΂U&6 icL,LDgͤS[{̴v̜̽GEP*Iߖ:I,Q)Q!R5~1]ZaiTš]:ЪA:E/X )Je-?n-q؊ R1VZvmrbbZ)l i^h2be5)f]^U sYV>6^,J2”/mZv$3+j.)l6kf(j~nk\Ro(TMPiT:"E6Ș jTn՗!YF]ʅh(ťeeWuaZ&g`?Xp!qՐltOLd) ݭnx4D5և0=6!biү!UN1v ٓzHn >ܠ3)\2ˬ;z}AH4fbb\lS;+z $# e CZzY,fmf_.q;7E 'otA|q.t|)p߀|Ev?㙸U\)|VA7DSpilg#|KY8C2o܏2siJ]jxRν%>h\j`m'<a'&E =d拖{!},(;aej4 W;* ?zw ۾lN% aɢ/GshnmJ+ƧCru:kYF5M :~{arFP!bo0+,0$AP 'X *O> +!5ZxɧcmPJ_a=wҢ<0joGMČuqy'{oe.&aH"Iw];}+`7:36o_{]}j#Cz0/4٫}fأ"}N(Dendstream endobj 201 0 obj << /Filter /FlateDecode /Length 1830 >> stream x[mo6_&&7JR(P݆kO^8q%6v]H=Ζة x{Hmɶ?gֳwANZ=l}lٯQeHđвݽhemԺzλ+< vƧRI\Ĺ鸾{_̨ԑAT^cj*6^oZ%VZF<։fEB y٘J4[Ek|wr^$A7dC/"+s:n|Oֱj1>9wuyX<%FsuiF<#8%xɚ},L>'(  Tt2'?7>qH`@pBpdhN% (xbJM)%R349 7ܳ"s Xm6< >?ѼDrXin% l>+,x>E̔,<5a]y /ҁ1XbDzW$uUg-;=H6hP(#P*_d}%Y yWZ^Pjq1 \@^T$8 (#mjmrfJgiބE 1E&&m ]V9y,#ڤ*,0(Ǥ5=>.1V{esnGp$Gl 9 ﲇ+-Sz56. ]b-FE21ّ}OA. k>uF&u9ڇR"pa Yl Ss_Hxڸ,>c! _`նV|ܝoYWۙ=JOӰ2۟#|cڹn۔#g(C=A0vBAZX`!u(Hз f{5BwT^d6~XK[M9jN|}8m]Fv/mr,=joVF6~ <_*^_2w_ MXB9=hizQRk'NLNڋ_l5Qa5ҤۻӔ ̀Vzuq$or(4 ӓ_"(WObSYpo`4FBc]Ҿ4*D$=UȠDͽa&WC!.υsf1a&EO#7{<” >sĈXhKhTUДfk_ sLKGƕxƦ@(B!|&">kH߷|mf~Ŭendstream endobj 202 0 obj << /Filter /FlateDecode /Length 2581 >> stream x[oiu~M((SQq Ȗilg ;$wwfW#J.|Ȁ&#QˑHOqՁ]x )pX #uQe9Qf<0{ck:?xWODb UcQk2dѶ dqNj.+`8+N;`&_ | %`98&lbC\{aO{w`H$ka4dJFW,IݳY.ptQ7 s$ C'mVȣwH^#yHyKr%Al1I~8۝Pߊus:ahҎfp .s_ &a݊%c5I{Í$ ᄟyvc0-o[O>70` kAH kJT]ewN9J!<P'I}[@|U&)i؏r̄;Xibt5 4U&x\=o¯=/3V,KΦ"6EpK;YUmj*: ۖ( -t\þu^)&`t@`bv1(SZqra!VIWOavjR#9cmoqtKתk*ǰ'$6p)߱%w @=BI"##geNA&3>k;PKep<V}}9 o? HgKz+jϒCpmho_ 9>ɺ+ HgkD#՘GfowrYu49dܐ6af||~cV/h0܂l ɮpH}Q.!}aY$oFUn(Īy!dɢCOѮ}I&pdӃZ@0vhFHI$%?BoHwOvMԐ} J&aze endstream endobj 203 0 obj << /Filter /FlateDecode /Length 778 >> stream xYMo@W\XYvmw)HE"(ZRi4MSgm̴$BQ򴙝}3r}/O{^xz: n~:l~b.FO^M5f@XJmb6r0"J (1VMbȵ8:\.;;g؆9o*̵5VeOD( [IvhnD|Amq,fI̬MF\`mǖ r~p> :'uNIۓ ʘWUP[rC/}f/TZr!qJ(Eu}u Osp  ` ` mY&_ w p-]oKqx<:V=w6%4"ɊQ dr9yư<x pUoZ Ŋ"qf "P=29ipOֹOz@ӥ更 FsEm$BG==i; K8Aa@Nؚw> stream xZmo lFaq'@h̢(V+(9 ̾i\B48>;3ξY?+3^nFl8[@CsxR{xv4JcmV쟠lMG4udjs:Z20UAE{oA; )}< * ƫ2h9v$Lg]oEEE(/UTM/"uDxb<{1%,2߽,?"T="AFCj!k\GOI.Hdk".2<'uQ(<+"* C-|Xh1)Ç,9U.9,?qMfY)>Qڊ.TjD; la^vG(`r=~M5[0"wǸ =li)! 9h  @PaZ ]2(SxXa#Zg& o Hǘj]"W#%?Brj\b!(唊v׊2;)dvto2΋4cF,P.}z Ցy#NScV;Gm 27%R^+j n1״2$/ ky#Bb O*Jɾrduϊ՞LokX6NGB9i )JKEm.kmJtPb^lkQM?Q4#<ܐh2!qt6gRSRd; bG}Ͻz<μF3g (!z7EqavcyM }]Kkmj+OI(iNL̗1o :<',"XT$Toik[}|rid!w(*: 'IlxzVm-W?/QhrYD^D$ʺr h"%KTIß{F Vs^oqa ["Ίs^KƧi܂E'\XL1Ѿr:a 4GpnuIPc'9;΍ 4`<hc\_!=s0dq+c /xxm%qh vbV Uf{Nm:=ߖl{tN߃KRɫ! WIzBnF2%MqP5``Sb&Ftɇ~ ਣ)}`MqT9> &*R~dצ(xGAc ^Y.A F2ID;Q sˁ ^+ESEwr&<[6ǐ1wc.4$:,b\(F=s ]΂`w|z]P5Ȭ'ScEm =hG?0MU4Zu﨔2`ZtHaPVwn& U)CRȷÙ&u 'm[Ii!۩:ȑa`%u8mMƘX2j{4DK6EbH(4u8~Ҙڋ0 M6GNx?kH۹e8'4(^3,MK> PX8ջ0Z"zXE(`1iA^^tա{JN]d$:qH#0@h)dbF\w3RsoLi+M274+Jby{G;BW6PEHAc\C"4mfs.UoLݤژwB((K(P-H/հxG5TDZur-hEt 5i]A7r0^8pp_MmGUhFK endstream endobj 205 0 obj << /Filter /FlateDecode /Subtype /Type1C /Length 1362 >> stream xUmLSWBoRFLEgnd" RRJ[Do5**Z|AP^LD~@eKK֪9y{shׇiZ>; ?> HXX * raR c@)VNDc?6wF J : U/^\0b|mA6*Ղ^<$ƠJ`ɼy%%%a|sPtn kfma6[c2 uVg1ʔ_P$h lm HSP(j 5Jdj=IEQ**yKRC;(=ا d}}UrEI?E Fw+aRyk YOŎlQ![`rA6Z{ GtuZ\Cw[XXω n',@},S={3Y 5;daŋcFt4ÓPrTGoDAƑakV8j: ;7(*6ŪNqnɌ&g.|Jn2~'ǏPɓ-$]m0 pփNh3B 6T*sWd;~zr{Fyt;Y%--?'6ͫx Yk:8dN cQ`8C7$a"/~~!YB/[!~@&o31ޓoS>W_d6Jr2X6e[WJ0z\ xVMg1 w.f^枯JrɔM϶6v5X|3 jJ[бdvүr5Ű -I{ܪPzhnQl1K@Zd{N~C]5b}dwg[Fvnʬ mP/4(x_|9R Ŀ^]:St{> stream x-mLSW^X-Y:ḓ͗Ym˰6DɐR ΰeq 9{Ut's3aKHӜ{~ߞ4ڗc;]js&{l,{us 1sĜ64 -<89R[&PrkEyʳv{RW&+8\O٧j&hQrK|TPD]P{7S"MOQC_mTjCc[aC֨в`(\SoBը9Q!ڀȂT(JCntpnB&+Z six-/pt{+@M%Jݷvb/تGY0=. bύ'̅e[SP6;@,to)49?qt+-$'j8vy]ͭ$@F)ԑ?|!vfV&뻣NeθB'9~5p_u1wG{Tԡk43ӴJ*lcuGkL/9mR=Fڬƹ뷇ǯɇws%i%#01 _bG߁%9?̋7Ju ,6P3/ l2%u/[Қ ߠKc+4'_$"3e0Sxhzݩo:/n)/zTkAGSL!l:rzZQtٌпhTendstream endobj 207 0 obj << /Filter /FlateDecode /Length 818 >> stream xUr@ 7ئp#*DRPVCa2 *v`0od-}nt]~m]6_Ol D4c;|hQlwfa]\TCԅ@`M[kgH9)ht^ 9F3F-96.S9SeILSe 8mBp(ö^S)|td41}:ɝXZCTz.mk?9ճ;°ӈ$a\>_0ܒJ{୺. :J2ۀ~ՉJ"2BK50q"1`u .0٬]m< : ^-$C_TsB2:QM$W#ֹ9Hh$ _9e._U"S]eNEW\}48 CY} g$cʳ"QՉ{z퍍'^ ܉3yڢ^H(DeыᶳAO:i3Bf?66A1_6A5/%d}Pg iݨsK^z=љ(ز?L>k 焿c(80^'R i-Ip*#"8#]Mn7txP"T?zS(76ɃypH}o4ٜm9qT~|L٥#TxY]U OU^ v2pUmnEJrendstream endobj 208 0 obj << /Type /XRef /Length 204 /Filter /FlateDecode /DecodeParms << /Columns 5 /Predictor 12 >> /W [ 1 3 1 ] /Info 3 0 R /Root 2 0 R /Size 209 /ID [<826fc8c684e26ad74bbb7cf0990f6651><77b62b39d3836e077ec84213b7d1fd01>] >> stream xҿPsզQ"ă0<na6{H Xl.{~rsι79ՂO+~E@%PJCsv]P1n^КC Wz@&a։TYaf khdf0{'\8K?X|@cO< k Mf3<2FeȚ߹K6<\! endstream endobj startxref 138966 %%EOF Brobdingnag/inst/doc/S4_brob.R0000644000176200001440000005071213333164235015635 0ustar liggesusers### R code from vignette source 'S4_brob.Rnw' ################################################### ### code chunk number 1: setClass ################################################### ################################################### ### code chunk number 2: S4_brob.Rnw:120-129 ################################################### 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 ################################################### 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:366-371 ################################################### 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:465-469 ################################################### 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:481-482 ################################################### setMethod("length","brob",function(x){length(x@x)}) ################################################### ### code chunk number 26: setmethodSquareBrace ################################################### ################################################### ### code chunk number 27: S4_brob.Rnw:492-499 ################################################### 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:512-529 ################################################### 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:568-569 ################################################### setGeneric(".cPair", function(x,y){standardGeneric(".cPair")}) ################################################### ### code chunk number 33: setMethod.Cpair ################################################### ################################################### ### code chunk number 34: S4_brob.Rnw:579-583 ################################################### 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:633-636 ################################################### 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:648-679 ################################################### 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:771-780 ################################################### 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:876-879 ################################################### 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:910-913 ################################################### 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:958-1009 ################################################### 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:1055-1067 ################################################### 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/doc/S4_brob.Rnw0000644000176200001440000010175613332157266016214 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} } %% need no \usepackage{Sweave.sty} \SweaveOpts{echo=TRUE} \begin{document} \newsymbol\leqslant 1336 \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/NAMESPACE0000644000176200001440000000020713277141401013704 0ustar liggesusersexportPattern("^[^\\.]") import("methods") importFrom("graphics", "plot.default") S3method("print","brob") S3method("print","glub") Brobdingnag/R/0000755000176200001440000000000013277141401012667 5ustar liggesusersBrobdingnag/R/glub.R0000644000176200001440000002064213277141401013747 0ustar liggesuserssetClass("glub", representation = representation(real="brob",imag="brob"), prototype = list(real=new("brob"), imag=new("brob")), contains = "swift" ) ".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")}) "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/brob.R0000644000176200001440000002570513277141401013747 0ustar liggesuserssetClass("swift", representation = "VIRTUAL" ) setClass("brob", representation = representation(x="numeric",positive="logical"), prototype = list(x=numeric(),positive=logical()), contains = "swift" ) ".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 { return(brob(log(abs(x)), 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)}) 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/vignettes/0000755000176200001440000000000013333164240014475 5ustar liggesusersBrobdingnag/vignettes/brobpaper.Rnw0000644000176200001440000001636613332136513017156 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} } %% need no \usepackage{Sweave.sty} \SweaveOpts{echo=TRUE} \begin{document} \newsymbol\leqslant 1336 \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/brob.bib0000644000176200001440000000612713277141401016106 0ustar liggesusers@String{http = "http://CRAN.R-project.org/doc/Rnews/"} @String{Rnews2007-3 = "http://CRAN.R-project.org/doc/Rnews/Rnews_2007-3.pdf"} @Article{Rnews:Hankin:2007, author = {Robin K. S. Hankin}, title = {Very Large Numbers in \proglang{R}: {I}ntroducing Package \pkg{Brobdingnag}}, journal = {\proglang{R} News}, year = 2007, volume = 7, number = 3, pages = {15--16}, month = {December}, url = http, pdf = Rnews2007-3 } @Book{chambers1998, author = {John M. Chambers}, title = {Programming with data}, publisher = {New York: Springer}, year = {1998}, isbn = {0-387-98503-4}, note = {(The Green Book)} } @Book{venables2000, author = {W. N. Venables and B. D. Ripley}, title = {\proglang{S} Programming}, publisher = {Springer}, year = {2000}, isbn = {0-387-98966-8} } @Misc{chambers2006, author = {John M. Chambers}, title = {How \proglang{S4} methods work}, howpublished = {available on CRAN}, year = {2006} } @Book{hubbell2001, author = {S. P. Hubbell}, title = {The Unified Neutral Theory of Biodiversity and Biogeography}, publisher = {Princeton University Press}, year = {2001}} @Article{etienne2005, author = {R. S. Etienne}, title = {A New Sampling Formula for Neutral Biodiversity}, journal = {Ecology Letters}, year = {2005}, volume = {8}, pages = {253--260}, doi = {10.111/j.1461-0248.2004.00717.x}} @Book{abramowitz1965, author = {M. Abramowitz and I. A. Stegun}, title = {Handbook of Mathematical Functions}, publisher = {New York: Dover}, year = {1965}} @Misc{batut2000, author = {C. Batut and K. Belabas and D. Bernardi and H. Cohen and M. Olivier}, title = {User's Guide to \proglang{PARI/GP}}, howpublished = {Technical Reference Manual}, year = {2000}, url = {http://www.parigp-home.de/} } @Article{hankin2006, author = {R. K. S. Hankin}, title = {Additive Integer Partitions in \proglang{R}}, journal = {Journal of Statistical Software}, year = {2006}, volume = {16}, number = {Code Snippet 1}, month = {May}} @Article{hankin2007, author = {R. K. S. Hankin}, title = {Urn Sampling Without Replacement: Enumerative Combinatorics in \proglang{R}}, journal = {Journal of Statistical Software}, year = {2007}, volume = {17}, number = {Code Snippet 1}, month = {January} } @Misc{hankin2007b, author = {R. K. S. Hankin}, title = {Introducing \pkg{untb}, an \proglang{R} package for simulating ecological drift under the {U}nified {N}eutral {T}heory of {B}iodiversity}, month = {September}, volume = {22}, issue = {12}, year = {2007} } @Book{swift1726, author = {J. Swift}, title = {Gulliver's Travels}, publisher = {Benjamin Motte}, year = {1726} } @Book{venables1997, author = {W. N. Venables and B. D. Ripley}, title = {Modern Applied Statistics with \proglang{S-plus}}, publisher = {Springer}, year = {1997} } Brobdingnag/vignettes/S4_brob.Rnw0000644000176200001440000010175613332157266016502 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} } %% need no \usepackage{Sweave.sty} \SweaveOpts{echo=TRUE} \begin{document} \newsymbol\leqslant 1336 \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/MD50000644000176200001440000000334013334302603012773 0ustar liggesuserse109ba497a60c9d44cf4d829b1275a2a *DESCRIPTION a76fb678cb89fd7f206a15374a7f648f *NAMESPACE 37f333dbec9307dfbaa3bd78de710c67 *R/brob.R e0e26c2f87a0a9762fcfbaa9b98cb14b *R/glub.R e731479c5c88f60b03422fe5cb305773 *build/partial.rdb b62f86a3447b139c0bacb238e2b1e0a7 *build/vignette.rds 5f9c8a3521284acab0ed92e3cf7dfb20 *inst/CITATION eb936011697482b74b3f77affc0a18ce *inst/doc/S4_brob.R 0f4940ac121e509bb53c73370a40d5a0 *inst/doc/S4_brob.Rnw a4c6aaef616c36d8bdc770006f791773 *inst/doc/S4_brob.pdf 233539c68bc55bf8d9057ff8afc20a63 *inst/doc/brobpaper.R 45c4ed62052c1b99976e5edad350c029 *inst/doc/brobpaper.Rnw af5337cbd5ae10ee7466fcf15a593fe9 *inst/doc/brobpaper.pdf 0d2def0996a161ecbc9a96ca9cd090d5 *man/Arith.Rd 85243eea5c0b8e74b1595f231bc62849 *man/Brobdingnag-package.Rd 302f297f098a7bbbddecc887df17de75 *man/Compare.Rd 7ca6539ccaee5c5094b0e6d20b09786c *man/Complex.Rd 7d8fbf72f254726fcdd44e18ab94127b *man/Extract.Rd 89303f2a4b86ddccd5d2932fa1750816 *man/Logic.Rd 0d7d612faf4826b5b6c0945ba2ae305f *man/Math.Rd e787c21aeaeab370f76de321b1067fcf *man/Print.Rd 99e360c829510efe42b9715461235d35 *man/Summary.Rd 5009aaafb2e2906b3abb375582e48aa7 *man/as.numeric.Rd 78335dae6bb7ca21ed9282f480702254 *man/brob-class.Rd ce1513c857b9b2352080a3b75cffe302 *man/brob.Rd 381d0242161ab82eb2562d8c44c889d3 *man/cbrob.Rd 8a9c550cd6383e2fbe98c93122914f93 *man/getP.Rd abe744b5edc3d25cf8cbf3c2d40eb58d *man/glub-class.Rd 505378177b8b1de3768cb07e5d0e2068 *man/glub.Rd ea082304393290114fa77c7628715b1a *man/length.Rd 415843ee2c300b95e4b6462fd91684f8 *man/plot.Rd 79769d298b6ee1589415f4df95bbed78 *man/swift-class.Rd 0f4940ac121e509bb53c73370a40d5a0 *vignettes/S4_brob.Rnw 5cf6c46a3f1dfc10d123edc61a930e23 *vignettes/brob.bib 45c4ed62052c1b99976e5edad350c029 *vignettes/brobpaper.Rnw Brobdingnag/build/0000755000176200001440000000000013333164240013564 5ustar liggesusersBrobdingnag/build/vignette.rds0000644000176200001440000000041013333164240016116 0ustar liggesusersuPn0uH KGol*uK0tI-'Uԭ_NzI툴bw0,lR(<|b׋}*GMlmɾER3e(敶R)ς4|g,3- WɐZ[8Ր}}ܭ\-Apjk}.p XǑ#U. 6yفmri-Ѡ>a__b6ξ)u} <9PBrTODZBrobdingnag/build/partial.rdb0000644000176200001440000001324313333164230015713 0ustar liggesusers]vFu-۲I۲ɖHYordѬ{)e6g,H4)A@Iwdcb٢q[o%b*rծNB:l[C[UݠJ/"[f%P{V冩Y@@a%Pnqz$xYj#Tpb~vwNJKe_p@,S.vjj~jp޽5P6}~XY=++k^o| mAE_ y-uGm@jx,_aÿp&Wck ,7~ ]R( vj{zә{[?x Hֹݹ X0ҫ )ֳ%U'3H9e>P+ڥ4K?P h_(^)'J (FC\jm2\Ҭ^%G|2iQZe@ %VڥG 6uU|b6B6*<~:ub[%aD˿vv2nb¦ N/Dđ7`pUݶ#-h1" \4DuZ$G/ws:[oeG䉈yK\.vYN55:zz9BT5:6%DbZR_`8 l|7??gCIӽ`O*i (Yh^k:BS&6mfUSmݯ;a4)Gzݪ2ĬEcpEBr?3xmL O|af23ۧZ1s3]꺔I"C?A+ \X*2miMka[> u[HDG׺ }E5^W"DR0^x9BC*8H5VŞSX,1S6qTO,c˭pIt8I &Q*DQ(2gD,Gә.U6v~"/Q+ߺ7l kxzD*LU5k5x+u6/<\2~Ėw3SK "[©{T-j0 bK*ϤeIb8KIsH#tJP@_FiMCVi#X~)~I+bӳ"FīFZML]5 @Is!Qi c4Fuj%XXl v ԌfI*2 ղ:jV.0U*]T/x=#0X\84#|_Ic|:9Y6gߦEm 晎I#XZ|]5ŴI(9,A=HJshS֨.8^SsunDdʄH,?}")5˚9_QˤL#~%9Ā 1VR)R jnAyv{]LԬ!P4. \BR(Vc>U.T @>hiQ [ @ߊH.+iOnS `4+hzӬG:?|dNꕮۗf^x9ԫnA?Nhx(=kd+ĂCui <ꓟ5;#zM=+HzxI،HfSB5YryɾehKd9͏"BAA^n^劖t)9P&u{ll&" νD$:[4 WoB6|vz԰L4:~ĚNkʾjMbdD8'(cBTMuNw4Vuz?̻~5m%"rGAIq_ ӟҟZ Oz.}h-}\-FHX} [o@D1cjE}|H<@9$)BM?}؞axH ]Mz+mԗKj+P,ҫȟ| ¸.LbX踖vd7TH !^>sk"yD ۗ[1 H 5;,U,-U.҇?n,pZ] ZA)|*?ևl2ͤPFFM PɡR0ދ&[M1u9D4iL;2}@ wJOWs"-r-&o<9TR;E}yyy=(Tn/IK\G3JB ȥM6秞8:A^O@wQ@mE5I +9rIM܅ØY$ѬShWE`måJҦƂ6'H>M7+2ԦfFe Xlr:Xjwsl|3VNi?_tZZ-;j[\)QepbJ۩/I\YV2ȓ%:Or=bqpK)롶FQ@46]f`+={2o.n{5]wtTkk =D0OYA+XOQ|azYsZH.Y){5E\ikMGMc]5%F%5Ýfqt}4!sODq-a:j[N_OXYL\YԱ8cOֽ!#ڑ͉nX ٪hMdjoQlEDt(ϺjŶ! _,^Q;uMF(+s!pN@񒡛wx&rc/kPך6] jK!-w v ތM/z|ݶ z8Z*jkuCތ^-ylqJQSӫ\^w݁Od~0hHǵa33+=Tާ/: (R5tSvѭd^7kJ|*9m4m#IC=+CNgKf&CNBkMƗ NgBMlz^&ww1[Mr6Yk6%Ps ]Z #ӫF|#h)p)Y9֡bl .aBbU?zz LGZgne Ycp)laq˖(a1NTmUॸaN0@}q"R!NVt5I[w1aw>o{:vQ{qPaM;>i_XtIR[g&$`^^=ޣzb(4 P浘ٞ fcް'3yuSe.\\ow gq_z|Y|&y?gsW7;zVVF;6w\GHwUZP杖xOmؾ+ $ {?+"lm hīq'w=#'qAo`?5|C 1Q;= 2.13.0), methods Maintainer: Robin K. S. Hankin Description: Handles very large numbers in R. Real numbers are held using their natural logarithms, plus a logical flag indicating sign. The package includes a vignette that gives a step-by-step introduction to using S4 methods. LazyLoad: yes License: GPL Repository: CRAN URL: https://github.com/RobinHankin/Brobdingnag.git NeedsCompilation: no Packaged: 2018-08-10 01:21:37 UTC; rhankin Date/Publication: 2018-08-13 13:20:03 UTC Brobdingnag/man/0000755000176200001440000000000013332160333013236 5ustar liggesusersBrobdingnag/man/glub-class.Rd0000644000176200001440000000257613277141401015576 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 colloquial R idiom } \keyword{classes} Brobdingnag/man/brob-class.Rd0000644000176200001440000000245313277141401015563 0ustar liggesusers\name{brob-class} \docType{class} \alias{brob-class} \alias{.cPair,ANY,ANY-method} \alias{.cPair,brob,brob-method} \alias{.cPair,brob,ANY-method} \alias{.cPair,brob,complex-method} \alias{.cPair,ANY,brob-method} \alias{.cPair,complex,brob-method} \alias{getP,brob-method} \alias{getX,brob-method} \alias{sign<-,brob-method} \title{Class "brob" } \description{ The formal S4 class for Brobdingnagian numbers } \section{Objects from the Class}{ Objects \emph{can} be created by calls of the form \code{new("brob", ...)} but this is not encouraged. Use functions \code{brob()} and, especially, \code{as.brob()} instead. } \section{Slots}{ \describe{ \item{\code{x}:}{Object of class \code{"numeric"} holding the log of the absolute value of the number to be represented } \item{\code{positive}:}{Object of class \code{"logical"} indicating whether the number is positive (see Note, below)} } } \section{Extends}{ Class \code{"swift"}, directly. } \author{Robin K. S. Hankin} \note{ Slot \code{positive} indicates non-negativity, as zero is conventionally considered to be \dQuote{positive}. } \seealso{ \code{\link{glub-class}},\code{\link{swift-class}} } \examples{ new("brob",x=5,positive=TRUE) # not intended for the user as.brob(5) # Standard user-oriented idiom } \keyword{classes} Brobdingnag/man/Brobdingnag-package.Rd0000644000176200001440000000311513332160171017332 0ustar liggesusers\name{Brobdingnag-package} \alias{Brobdingnag-package} \alias{Brobdingnag} \docType{package} \title{ \packageTitle{Brobdingnag} } \description{ \packageDescription{Brobdingnag} } \details{ The DESCRIPTION file: \packageDESCRIPTION{Brobdingnag} \packageIndices{Brobdingnag} 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{y \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/Extract.Rd0000644000176200001440000000153213277141401015143 0ustar liggesusers\name{Extract.brob} \alias{[.brob} \alias{[<-.brob} \alias{[.glub} \alias{[<-.glub} \alias{[,brob-method} \alias{[<-,brob-method} \alias{[,glub-method} \alias{[<-,glub-method} \title{Extract or Replace Parts of brobs or glubs} \description{ Methods for \code{"["} and \code{"[<-"}, i.e., extraction or subsetting of brobs and glubs. } \arguments{ \item{x}{Object of class brob or glub} \item{i}{elements to extract or replace} \item{value}{replacement value} } \value{ Always returns an object of the same class as \code{x}. } \author{Robin K. S. Hankin} \note{ If \code{x} is a numeric vector and \code{y} a brob, one might expect typing \code{x[1] <- y} to result in \code{x} being a brob. This is impossible, according to John Chambers. } \examples{ a <- as.brob(10)^c(-100,0,100,1000,1e32) a[4] a[4] <- 1e100 a } \keyword{math} Brobdingnag/man/Print.Rd0000644000176200001440000000077613277141401014636 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/plot.Rd0000644000176200001440000000124213277141401014505 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.Rd0000644000176200001440000000066413277141401015775 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}