pcaMethods/build/0000755000175100017510000000000014614350074014764 5ustar00biocbuildbiocbuildpcaMethods/build/vignette.rds0000644000175100017510000000042014614350074017317 0ustar00biocbuildbiocbuildRN0-, */>  1$kiK۹øc!ч۞{n2$B ` `<6P2)JaY)lROeR.7)Rny^ThE2/JǜXTIPk*g4/? |lؾWONQ'I#Wtao˅ɑ'\f72&ݽJBc=4_B]KGi,:B2Xy@#2LpcaMethods/COPYING0000644000175100017510000004311014614231101014704 0ustar00biocbuildbiocbuild GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. pcaMethods/data/0000755000175100017510000000000014614231101014563 5ustar00biocbuildbiocbuildpcaMethods/data/helix.RData0000644000175100017510000004656614614231101016632 0ustar00biocbuildbiocbuild]xTU" l_T*JGAD@J)қ;@:ilOH@{fy?dgs~g?]{;AA!A (SB3t&k^: \WwS Zw Z={h]]{o7c˹_~ "j}Wxjgs lˣϦ x',,Pk\_kJ{3^ >ݳxww"؈wԹF5Ǔ}w5^?5 {L4ŭ~y }$x-n<=^>|?TOj}y'oxl7?wPms;:S htkί6רiw^s9whEg0Az]%S< bࣻ79|7<6+ul9i~qZ>iCؽ ӫ̏r0f oGFZ [!Kc20d||^1f+fm}p_]~Z#vﮄ1AڞoħG漙QUCI']Ӟ| \Zb7ƍ<0?t臘~өy]U앝ݒ1ݮߕ7^Mvӄڑ_N|T&,g'ڧYt2&vI.?Rn&&>D`şO>a2o+ח?|rn 1)ONkV[LVi>qBLݵ쇥pg#fໍ+I1ׅ:y8f.OA˷1y|W-A.Œ_~ pj?^m f^L}qZM̨lp럢JYLnjǎ1 23J C_ mQB;qVpDLd7/ Q{ !V6W>߾v9Mz/|Vdo`^ .|s.Z{2ڲZQQm3Ц/Zi:hѱJ0/ƠMK%nlYmѳ7fN{Ӷ{Nw:ۄ-&8ujJy9ɤS2ycX茊s>U5˅7YuG?^7uB06%Љ~vzx 9m1tv2O8S>kfIY”DG7w6۝ ;zme7~|u`yt?)v:o-b;ݕG̒֕mTzL 9f@Cf1#a1Kݽ|7sz7=ȲГ?2LY;{|: zg ͨ{}|[@ψ6CƱzF̮o #}Oۜ}EN 9{w/{]MO/#9ӎ#5mB->#Mo;nr蛲dhcTBthʆ _{h赕_WZk[={o6J꘿ѧQDj 7l'f/A1{VbR&^ԫy׳;nSRu=]V?(9edz-}=bF6_5OB<|L?Su'砧pμ(}%elCi 9bvN=²Z\D/X7UbM9WjfC&l<Ȇ^qWOmVꑅ['KkpUqD%/ -`m`ҟbW΅=uhFըrc}y7gWlAkC_D301ZJ64~y{6/l_pvrFEv(~X}_տ ꄞǢڣ'-DظIϼvOm}':z#E1zǿ3ꘊ+ߍz>758Ŷt^}M̊ccV팮/~t0yHz!t:~KAߎi o__CW~S܎{n5 3ٷ-Ƭ ;F6,)ӄ[?48j|*.h>d r8XzڵnB+}:[Q NŢcɰ&#ŌKBG[#i?ThFT̘ ctma\Ƕ-#]1#3iWj}hs疈Zv χ1C-NcyL]Ph\Y旨ģƏo3{Z||Gcl~\сxjbrxG2O;]`43;։ܐ*J~w_}áUxmo,kZթx15X_ ؐxrr5ox6tΟ޸;Vī!"cS[v6}1Q y5};Wn;nSVf82tbj۰? NXwCJ }ؾFZ˞8=EKӞ/Om6]>:ON}yEG%?<܀1~u &2U3κw:7fp]vbBRC4^A%Z~ {YA ٩V1Zu7HV沿$@RՍDgC Qv|&$܀-k]|>$l`JYqlې]roBW i,r!jE({e(ZyDI~RH9:ZۡU 󃱺s؃}#d|RRtd!-V쁴v H:|@!=⯠ u[A:X ܶ!f?t 6=,uJ=շ!uo ]K.w6C@fW=hILjJԏftǂm?Ʋ|ׂL| dXhL27Ѩj_Z7dO3xώ'_ zy]gy}?q'y_ ~VU9|  #?=zM~V͗^M& ;` +/-}~&̯wY ٬]^VU^m4}y 7kss!gKOgk;vT&W琢_ni >6^y=2v[[,d8 \,}ex|lU*4hI2[}h>MwR(:#dy pkO߂;;4 /w_%mTpӆGcolVbcjxpx" 0|9ZUq`7842OJNDFDZD{D=)fp~w3Tnw2jȝ=?{wh[kK.j/W/ؙ:'u\Ah8l`_^duV>خe?k?s`ƙή!E7(2[e\ҵ]`Y tlr_;e}XY':4Xb>A:o_44Nl2Iy{kz :H]Po eUc̐^ Ir[HVe<{ o~*{0,:.Wx3C N.RX`'+7pZoW˒*oՇZpa?՛;׬nneh-#/d8X0cd䂓-v7UJV z-_Rrnpu¹*ª_< =#hQBXYoЗ_~ Ge k-~3~X9 lkvg׳G`uђڷy wer\&/~>|2܆[v}dkdS:zcj_}t}Eџٴm'oEjm.}Dԯ<=~]n zdzeark{7r; Uп[k'gfY$ ~Vqn>֍izx]}Lv=?г ͖MLE۬q6=}/GW-3W^/{\@'Li\G'q^K+[džW cryJp[詿lؑlţrݩ3*ۍe`gtbʎc3[~'k߇/zJ_壗Uѽ7[ AwylGި@7k_9yk[Б;eaexԊc1&vAʮS LE'_Fu0KX͸5貲F]MSڷv"yz]: xΥ`,?)Y̅0ǯ}}٘ŏn}=OBfZfZ m/z8eխO&i+(k'.tto@*A;/`Vm] u?CX.}!}\D0&5@wv.p`S#C^ڮLaGD<mZw#f>9w}ƱD=xf/jHE AeGcmr37 L1C$LexHsa80%J`0UCh7h51}Lck0?`Ĵt*oY e?1 &<[iM/idXi/m=a{L6/0sղR[0M%ԩ9`1'Dvܝ`jC@1e30 g` e*&S>ceݔU/$Ď= lUo39Uw1NY7a%=->:O(A8^_#^amXS2eqj: co"pѲ+*aei[˨1V?+{>ڮ~S Vu0G`D4M?`ɮr\>YWw2F?z.4kwzw^G)Gڃ_YVgRo't,d5Б*5Ǜw5.#uk/~fvEN-?3TûZ6OWoܧf2^.^.L[ܙg}g\8Wl< VZ xX{λ^r[l쭕=<{/f;swYlU%o.Ta#?k KyRY=~c`wڪgqɴ8>}!λiWǺbopbDu5vꃳK"N=N)Թl6~0!HְcO0"ϧ~eS{M(UO WpIO0dh#Í*VU4;4_95 dKVJ 7e}Xw#@$?ዙ/̅k7Toj] f?<( =fmk z{;VHC?<͍RU15 O})</jT pJ{n@ ot;͙%<(h' 12_5}`Ť eV,h#u B+;-'"_'e` 1-a3'up:gSkvi8=;@Ӟ-g8HHvi,ۤo%C)TV{1[cuvʪM!)VA@8w!ۚóOVC9As& '7'֘2ǘviRwI0Kd/A$? [)|w!SCP\ L]'A`鲎I`zHZWRz / ]cV)->OW鏵̪-d<3%Ú@v\^n| +`a}"Xw1pz-ot]խ˹}22U)|V`gn5`?3`c\L;o~ v1y|p:~+p0whY`Ĕ\蛎v'8 N.? s FpO&.9+spn }cWE쎃+˂KΐK;Knf ^`ꀋ57Yq땧YZ1d9?!#p[H+^޷Aޕff~7/#KKr5Oa'NKx7 D&XRBQ,X^#6pr%ر} -L?Owǀaq"q˙Yt'c!?}I^ϧc^yYzp)#W4y;g텃'כOFh~Թ:.x|Ÿ^Ow)X?d粆}u)xNgS?XӻLxi&dsGF3F-v_w/)F}ywUF9+U׷!Gqt'gy~3|L&;|G>KpvU3]7C3Y|~z}N~_^vG],z|]|mGu֩_<ٵx>:fyy%x|"<}F^xj?w>H~+I _nVZ3)?p! '=\L.87xx["e#nKj/vd8k\<}|nd#|a%&nV.?&\@?|͘*k|$jZ;-CO|Ss%S3'G f]6R%|m6,|&)>Hpq :8MY;3MupC|.~m)|dF`gJTpH_FB&;V-L^/L𡂃AfMy!7G;C)ڢ-BtZ u&w{6 $!uAK@j2+pc؅n6~H#yp +ػB82z =ҤNi~HdoHm(Ht[` -x iL4nC\3Cb[(tُM_@:;RB\ILѝT֮~2}9b;A:&gFl1BJ[nsm?_)$s[HHb"x#ılK$1B^,ij %h+f_xHmW$a!rɬ3>GLb♽7!{#8=Q]Ev3moUჅGzܐ֝Nw: < \FpF׷e鞘?Mۿfr%ȍ;B>I?U17 _* x][Y;kIVNڻl  x\G^.(SЂMUU=Cv>.:? Q3vv%|ӈ=xf$sbn`)c780^g0b}2)F,bx~lGx y7L2H'Lf] 17n`1G8M >zyaѦqx2N>e^>Ә.DRڥ`{aMBvi]XC`K9G[6`F}.@L^ۇ0UQ0#wS&tLxi 3E_.dfT9wbc*rSsx;f:f^ $L_\ygh]31]9N9᯵ ?f,:rkQk:mrfhYr#&9em{PJ]%fC- s.-6K;>o,:E>Yr>dk1z&k^"k6]3],];ޠgD'Oak0dEݳD~yi:jV[K0uF`u>t *p9ĹY[.@7KFD7fS}r :ME*~ K?rytzkC[~Oz>9?u::=E_g0o_Ǫ"S5sy&k|>^CfJC 6`yk!ȩOgz `)^ٗ~%48;L%=yl~^@].iׅ6MGWm+BY D}ҟ^.ާ C//o("lדu8J8e>~ކ~Gv d?/]eaZg?V#nF]M(u!t5sU#xۻ!fjDG>F|ZX%5P#:R#W#rԈW7p_!t75BDŽj௦!t |W5BjGyy5B z}vjsb\X5\ /5L𺼐VÆBvv'jѩab>Q 5Ə݁jT:gP1WMaroj fsJ :*eڻkUqBE>υUaС*b5Dk5T^P'TCDݪ ;T j׺;=O!̶*xj(=PC܊*65PqNnWCY{V5d!K/B :,5[^!"SC>dwUCJ/bjګU0ΥJjDfkGsC:!O j] 'Cp*[?x?D :ϡ ΩAD|nS .#L j$WSfhi\/A؂U DrN i50/D5hy<1T@I5H rkSy_jܷA 5PƴY <D5p1[lc87ؘj=5ṔAM[ sjժL&2O HF5++'~/80j3SdMݥU 5@ը|`M~`SZhvļ tX|+yV9H%,tКmp|"9Y$ͷBo7_$6Eb9]$ }7ooF7BBim  |~#HL!ӶBџBwB ,Xjy pa E x 򺼖y|ck|*cP~97] Z?X O]۠/E^ 8:qXlS9J X.o[|ɏ: +Kyb+| |?KƗCXp_ٷd3̗W[q _RP̗Ϩf>/żs/:|$_pM_F̍/]w3Oا<1O\;{!+_'9+w\Olw~>xD~^`w}9q7>-n# f{ }\^1[֣'e05-k%lcWbsc%c6O>lAc?O{K%/~_>"[SѧUU @s_a@^sFG_rVi+[}W-{^.sG s+y/Ƞ̼y͍pz9)tB3az!zfSϋq_2DNWD= 侻R,_GE,f<3M?dqKQ>,8y!f1 2іMc&8hgnK!6Nִ ̐>L1oLv3ٸ{6ڄүoq"ڤ3C>O(O0Cr"PS:d.<1U1]Ǔyӛ gTx$Ls)]\TdMRj+>piߞ61 <l`y sHXnp#r$DDO|tg`|V`JGkr>Q1qY9; b0LU17֡za?botMa6<݇ xW +^>/L<= Z𜘃?<sAx]ws|,d .vR?f<ڍ8#tbsyB<>`Hxvϋr '`Ѱ^ō}'G85x\\WrVX[]_WNGa߲3kmǭ߼-[nkh8jⱹUNLprlRMTѣħaOgUnNc fOl˫B'þ0zpۉ3%u9Oq(.l(}IαYuK 9yQyKF9z\e\=`f*<ɭ;nIܽ2W2!Ok)@bv|lή<p_g>8ϛ!FQܸwBЗ!F<VbΛ ;b!^<b )qyH4VXd'3^@nɿz &<e?fpC͐si?!,Ȕܐ}{)Gt9'Qa+\leqyyʹ!ShO`kxĜ];.cAfV.8a2yZ`}LyLS!YB,7s\ҷH|ka>9&vGԗacn[r>,\p˹}/,Jxq/ |·*|P|yLoTvk ^kIrҳ#[v9.@x~r}LNmZs9׸~A8![οf~dȖnd*H?Oϑ!kBy#2Ϸ\wr^9)/\>9\5 \Jl.Oo\rĠ3<%Jnȕ9/;!OG JWJ?]|^F^0/!?nk}ȓsy j/q4L/t1!O_H_jSzK_T __r:[?x!kx!ȓ|w|)}x!1_K@xҧ/Hx%tVxՎK Oᥘ .ҏJ \+|Wr ?i+1WD^ ~rN@P PuA +9o^kY#O|@  ZBQ?@!_#5s+U~ozr>7BlەL_E^\'( 4;x#BWC\oKs]ކq}6aP$9FWy.x ]$E5WZ<+׻H"}g@J0B ׭HۋD3S }JЇO%gnWܛ zq]\SX srJ@>Ts( %XEJ@$?)J{% k%Wy)%@ S9<%Τ(i%PMJu(B_V P  %PpJ ?%-׋@ )A }K z>% P$>%踞)A—?] M N\`NQ|nI 簕?SW|D }%%8sK ,%x{S!%!cgsO "?TnXhTc_%XYJx"J*!lvJ0ouWBr]T -/%-""eI%""_~(6g~-,}ZX YJ7*龍D/T P17)!`JпPq)ߠdE]%TER\VB.۰ԒYG톫E7}ok_2(k99|C=+3˚w3{~ה6O~ X/w q&9}ןٹ uv_yӗ7/Z7go}q֧Һ_Zhm}o ڟN?Cߨڼ?7^l/Wy[]r˖So{O?~?+>mϬU?.%'uO_O;6{V?zׇ:~|[=|8//^7{'~\߯+gv 1=-׆i+8?˼_٢ ғ~l?ѝ~mm=Y+{ W7YMnۖ^k/mϴ&O JVONsc^Ƚ9n]W[SXٓZ[op|a}[oȬ(8pusm^DJo:~3e 6]v6=a/&]lӫO\s3e;o~>߳]sÊnsdض.Y]E#[q[aS?#{,k<7^lϼ950G?a~OO*>?~ʗEo{/OMw||Es5n:BU~ڇRcVsuz=cڽryuɶxm۱ݚ5!~֔^~MbLwٛJAeu?>mc?*[]_ ~Yn`M=w^ϷUyѽ>O=y[S/p15čq-.M dff`}U=/<ׇӀ g2cs }룦/k& d?/o޲bq_ko7u8 kC7C =_`lWtGBm-_y•)[y>~.Pt7i SyH7g2]v_ .up6x.q'., *N3[42gúS<3b_on2\ק yXxoZ򖮊O5JWG@}ے(4d,t{Ȓ/Ybh} *#ٝۖH"N+ing^ѽu㱾ߝM\=uwy1b$[da^cWWק Y?' 5gѸ|}2ⅸ%_kFHt_X^cOa}Mrc/fY+݊߼9}WkA,}2 Ob_K|v^)Ëtrr[&x %Ol&C[=.׻]*~xNj*V5q!Ne1!0~QxN+_FF ^Csb?%)˳/9|ocF_pg֎KxOOlUbps=y ~E;eޔ5}41yᙐGƸ"م]is&qۓ'㵉uKk?Mپ*ku#m0!SsxUp?my~+C~rKH~?Î7I?$J/(NH>i'NՉy.kpݶ(Ľ.k5䓛PtzIqm6~Õ'mF8}h07Wn𫞙&i\/)y`E#qy[Dcԝ9xEv7|•<W<N\;'^-8a=>7ن%ߌ8Ԝ|6W&g=q]<(8_).ךӹ)5Oޛnis}溵nے:9?t_oOI铅{qk*/[/g_/`7nbӀ–՗(.q!~>Xp*__=k߱[B [o~h+p_"YE\ڄFqqQ_k(^ËK[,\z}=Oojo ǕWƮ6^MxxF\_.>B\/Ŷ$u3}u'QvۅJ Gs΋B{td>Y|d߿! L?[[WOH= /[_sVx&Y ;I}7mypG2١l&)Ѯ6>xoʳݙԱ_ g}!NSnC> Be+=M ^y!e]mHu Lv[{+ϣ"[/}[6+ݛpW8uՃcWOQ1Լ۟ $Z֞G OwZu^겵i&%mK_l RzWoo$^{:oßdWK zQU|.jS~ܘ&8؝~NUKj[}^$ns55A*i{ȫA49 Ċ]􃿳̍Gp6/ }z3k& ˨+O7P\g© +;uT⫰_ !^%>xKoa/(>2֏gU@,M+B Bnl۳AөLӇ/ZIm˦#a~ >xHꬳyxdU N/UK kE<MxbCK@_oIx~uS\7އڙo!4-Vp-^G# +yΞ43^"\Pv-4ѵx+B엲~N>Yͯ};T?mHxGX_^>|D>ߥ#ܗ7 ؐ :Q8qWҶS VԡfQSRmήMv#_0;}05o맅:[K[q΄ B\?m -"Ok`jV}}oj`6V?-` DX_r>5SG̐SO<Oo7|yO.qlukpzFe!ܾ;o4Ÿ${ĠLٵU֔lr@x b C vJW?;C#O+^7]龽?{7L&?/K;Yo9|$^n$8x.>'嫰5YAț:*3sa)~EyCIvsC]!޴Og;=Iܮ7ZWQ^gl!yp [[nksIPWݼ)Ŷ5cBi&]W[d^<W#/QuSB{hyI 6MOgWOnYmb98XdSD> H_ r˅k]p?]YR*",xer8֚oӶ u/K Ѿ$3w%n7B?/|K|}( ~7_|u>ԇm%ɂ(~ˎ=ǗqSNeB%csTG]oEO:8w8)iS4iEoY{PTW6`N6?bG>nJ]ŞzK-q)ڗt娞IgmgT@kA?>³W] hVP?+'X׶'ӨNrZ q٭Xˏcg~>+tO0.G.VU7jL]MFuVحꈷ&2%GZnN /I~+ziƺ,85W_ ^vȰ޺4zUIOÛ)67<6TW_plk+{ p_ŃS'Rs9W'( I<:x-ׁ7 ę;oH¶wطyERyO-ڝ$gsgvsλ|~7\IJC 5ţR'#_Bf9u{/೉Wdޓ>IֱZ8r{G8zo~bXGq]/O?7RW2/+ڒҶ?[?Oo&,"/R=R8_u[p~ {Zo :DvvwE2i:+fsO}3.^\˹/v oϨxK YS0\c--ꇪVJ} >zvѕTQWG!/$<~݊ϨZ8 ѷ y滓,kmW*_OLqSSG/?R=,yS$qV.(Ia8K[CdS~3 [?si\M=iC?]>ux>s%֋o>'t_ljz\Y:.\@][yx#7Yo;7xwt8[ *OWI~3[7)ڏԛ~"&J}5UYW}΄X[Cw7χW2o/V.NhxsyTMǾ-"ިMs%^?kN[WUoU_Ḋx>]|0mG>;qQ"yuȫZ(;vmaRx|cu/6uH_ X|QtӷG]6_oG~WX UFo.Q 9{sNj;͋A<@7?ϭO]0px\IU(N,4Xת'xԧބ8|_uyme. /S/lKKGx7 jnc?@-:' 3aGV9cb>CR=8H=E iOzjzzs)䳾-Ƹ3"qAGk(>xҾ7S Gj)lϫ<Ɍ~k?3u`ZM'um=SڈB#GG~ Užu+_"VI1[ة$ bKS>8m-t)g"knT] \g_ ݭ}N}]}R3n sG ^#DV A:=a׉]| C[Po$^jȧOJl|/N"o_m#9y3WEܗ=^8ׯNw[ZĮKg>5+'S[O@}( _UQ`.nT_n|+w q'N2ukSr+{_࡙oT=?Ϩ:؇؜>Oy9S6u^R WX?F2邗ɬ'}|BzJ8'OQ_`#Jp5fNÏ'ԇ C!:VJ?dž "|y⦵)Lhg*f4~ ax#>1ЍW[zg~[.^5-<'׈_X|:ኊ3Q}}?IJt>"{gD>"@K{^ǫJ~%?>yeїˠ._7-~k'9y<~b o+ux?pW+Qoϛ_|1o4 yv^;Y|^QSݸ;>^̍ ໮>se~sܜ(?WL]UI\X\Πsa ycS|t!>pK L5x,z ~ag ?> 7fn>ԯ-[Fs=x^sx0e|&xAKD8FUP*~VDZbFE݀a;.~|[upc]G:cwGa }*+%^UG=*EJoOϕT߳^ٗ^DBMa{ I˻kPsU/vФ }JɿVD]Vwnbt:?hGe}6#ݕ>8p;["b<&t׷!xk7gkC{Izm%ꓥ W NJK{3Z~VJ|݁s}@yy doo| W":[f-\9}|Bn#/R]imo!>p3\Ih ۣuoƈWsPoȩ׊-}?:=}V ] / ܨtDYKjMv+"O_R/+[GQ1k'~Q}HhE苩o N߻<\l 8L^ҟkAi:񺼖R >4H/՟M]:*Xh4*>d]D|kIN^ qֆv~+uG> ~}o\5W+-ToܞG"ѽW)b3'sR;ыkw!}AK`+y_/`)^Vb7mbO*ʠ!DS½3%U-JlurgGr峾z$-$XSh{գ󰈇:2gDZZ|0tb|&}A~t7v,oNQ_qP]ЇՋ6jfЋ$oGf/J>x=.tny3z 'W߁"!y*Q7x^sD>^eV>J['(N7TDg0#io#y㶱{5ǭ>S+пΠkX8w?>-%K':ct]wuwV&og/Lz)z@7^Tx~;O8'n7}K9๱|Tϵ}s|ݪK?@tTj ~BGo܈y6Ǵ_WU \4|_ |iY[3&x> CԽx#/^qmV+@8g=%xgF w\8Goa tX;{{I ''}x:~L~s?,%y;M|87xyyhx\7")*Vx˵ޯ ~T_>3/'~!+"]$/Wٕn 'VS}>meBwZEGڂq;}Dc..j/>BNp|Wsvw)(}j&>FJ}6B U-8STO 9B;B\]Dw'av;=~#\,c6ZkmVl`Eb<)/3a]i4ĩ;5ck. VRA.} "Ļětө:X1.Rt޲v?tŏ냽qOH()o {B_un]Sw.pz0ԧm'޴UZz&Uk؄;YաvN]C:?": ϶cZ&"<܏ZvT\GR7;IR:c7.su[у8E]hQIggV^ pO*r4Fz8\TKB`2B?RO6«"i)b 1pׅjp⇓g鲈"cItĻ|F Y)8<N"~Z%=Ϻxr:]+ a9I*/'wVMe1OTn wgK޶?;Xɫڃ,Nae.ܢߗS <}V`u"״%=N̻}Vk_}6y,[mp:D|/]96v~>{G*w.eyVRGTݾܾR L"~'' J*t:c bF\qZɿs]_ ſ?Eŋ?go'Y໑8y)t0O:'O-#Gďr]B=X/#P'j-ǷVmH n7ǹq]kWF_X VsVz<25:y-ϙ߷SWA˘[cۉ73ffyJ5k]k>hy)X H}*??cթ= ԱB}6h3jF_bpλ^Wv70ǣU'/53o ,]rKctW}˳ik(1uItKt/~κIx'zT*=+%kS>N}C>5_;W~tYM~r4:p0Ψbu+C5/ 6{Ղᵵ2S󈱯g JpQu=Rޓˤ%BtDϰ7lo_M[TOYE[)H>C/QzrOH\K\I]%)֠ù;ؿx]ڟg J uk 7S_͂WbwDgD\8y[Q蜝|Nq֑K ki?h~F<>\a1U *y?8J+;5-=!6ĿhJ;?׼ ͍B?*0jޜя}+ ^n!V+80}E#p:kҦ4l+NHQV?kG{x+I#R@Zxa S^B]Jm+Rg7i.FK_)g!ףϫϹuG_a/=h(#5D}«ŗE|V_t8. ^֓p lֈn˜q;u鳊ԃ=<>ؑr鼨oBFաCWP: ًVzwH$= A:j(/q}5SMaѻ Կ\9OQG>m+хmR}&Oːe[o9#eXoLvsB/*}| [G 2ؚts`%<}h/Eޡg<.H9 gщ_z\x2븃C qlxׅkI9C>73AQgr-sx4<] O4CmMsN_TKW{QIY/]O_7^14դy5oqWTVL\ݦr>Ovs/IxE> ν~Ap߷Зr [7yGG>Gjn]Mkg~A?rsR'y#oGXG9u7~~j(ul_3MW>m],}\E\O\!9>';~~xҏ|Ia̭C|\p g5ug9A2?>7};VD?uSO`gѻJ7?xFuKdg 5Y;5/8#t],~0x:/0MzgV>>Cy:a?H':q|pn^!~k z!|yP+sz'+ @gp~; UPg\ƞOw|$8lʷK#!)]q#< Zcщp-Sh'm ?XFwؿK\CcFAǾ;T}嚫$y1' GԼqst`oѓ*X<1~ҋ^|o![ŷ, :29>-GuA?FMsﰓaWkGO31:7c #hb6`ߥt<$}#3c<Nҟ w#k9|c gܟ}PO߿9d&x?5IgB.6E(gtӧ(}Pu SsP=s;J|}Oܧ qj9Bw6~1Hl?[M'M[<p."so 0zL-3F? v8cn..}zWo/ zs oIx4W]zeܕଛZŏ*ZpzZD՟隣WzdƐ'e !e-]ˣՔO!_|%pWO1H)fU!V>T?WTflaU1^~B-}dM!>9`9}u2pҨ<(g=d ?hn ٙcm+nNp5Wڨ˃O:A/{U_(q.q]X?bulg!9ğ#̣vyfzYv ]nG!ncՅh>_̣scws/~C }8mEK_!qD'+9w`ީs^tVJ]Z8A}+k/ކxQ硹30#oހ }qQ^F"^M3)u9 ஠y1ӜCRP@CHWUn:t#r,_϶yWbΠ(eؙI(_kNz5yya_A/ԟzJM}ayXѣܪ:x,<{ _vaAx;^̶#;9<>>[\Z 78@n/G{ <()jdg!} k\߁>oLs/mcc#.]6/ rtO /ZNzNj^"хgޠ/D_8.g~V#}|#׷$^ s{M+}biT?oj_Kr pz[hќ*t)2Gc6@~ޕWAC>5熘D>C9BÇ= {{+p &.+>:敜wGgiԡ:s89oҊ=.6}h?}{6G :o$#;LيDZe*m#_m5Pp $WNTp\ %P}>,NzEưQ+C[Wh.q, םċQG(xr+q89V~^A#ᷙoA&27ڼdoҼn:C0"j";qs!}? _\4Py Y?OO&ء۱s !8iKz,QϣY:wLAbg4\Yn S}y8k` 4Y vYq׳4oPNa_ҿmg7;io y5Uynq\ LހWz/>qzhL_{?: -;?_*Kx}#e~6mb>R߅;X{q7EUVç78@}Po+C^ >Ŝ0ל/~Lzz1[m*=O98IE3®Jy73τ9}Iܢ.ۼ /<Ie-A.9\{S]#ޒp7@{~Գ¾Uuk Ng@_4}{CV ΀s猄x2g|^{?s 0OuW/n%-|9>;{ze!_ava_gD^'|_ )J픾7uHlu[Bқkэvi yJvSoh?@/@}\s3Nߛ~~+ mp 5/Y  ^3Fp8naǥs:<`/k#¯wga?jG؁l :Rt-g<uk+ր|<k;wv~!}xQ~>Xڡǿׅ<9;j\ 7$N?gp8tß9<~ǟ.栢^YR?t%_NTou-B}.Tt4 ]19_z]eZ\bT.8Pt֬Z: 2ovgBsX{IOq#']6Wkk?O=C7zpŸ8`Nv~yp}vckRӂd/􅞁"\@8>9ޜǧCs3Nt~nnIl>a0O_T"]˽xUG*G7>Fx_N.[O>~~A^Z!ɋ量\\?g؇ǾgYT#}(G>ɷ>N pS[Nnx=KV~}:[!vjr/P\K!q{m(:#4* q/9qtu7D/ƈCJ{ė5z9 osd-w$Y? B_ 5)x޿'s5[}w୞[kg\|f^T*g^|=uXu֝7SGC5ve}#^$y9^KsF?t$~SE~ xuףCЫoj O<^A}+np>Ha/3kz?]؛ԳP< 7_~8ue}Cώ7G#>_qI0ꚹ3Ԉ73H?qC,0x\'k4e{_|9@m-|?~9$yY }[-T3':9Kg63JyC(s}1bg߅R<_ťqZO||h?8 .jwj۝pvAOz7zk^!]ѭFPg=Rp&"'ԈZ)uva?yw`Wyd+=I珄 ss<@]y Ć1.Fd7G*E)}\Vi{W~xV#};/j¿Oh%#m?a='!3GN4zO|jNH7qcGә[o;EzO NP?>C]$6nԇկ)I%^K=ǃ}o<n扗^G!Sh^|3գ): gYkۛt~ `{ܯ>>a }#a'?#m'` qi{[<_n?YK]|tpl>0zQ]~:žպ/CSvv7xN.Ƽ:k=n^8O`D?^wyTIW\r |#W#T{hN~xL'ٟ+p|=t|}CqN~_2USwpM4|-~_uC]Rg xKTїp}"Nmb}=4A Bg3G`t9y)vO5y$^jC >wkvnN'Of~>pPtޅsb)|.& ay}GVLxi<Gx>违M>4<yy0>AA"x;>a􁇨;u4}U Z\Sԓyxo<ߎj=}B,׏ < <DzWPדo7`eyɛNy/v]xQ;qHb.~By)VLV?}yE$jzIp% kI&N5Ug )}zՠjcwG!nW}Ou>@Z+`_z7Ռ>t( х4r#{C?xh f^WN3.Eߤ-68~Cs~Y&ֿ`_':JMIc7b_&_uqJ7G ٞ'7}IsMѥO+^1)z$<:8E<888^u [)ُ@UЯ!VWx^uns<`Jx2x'5^]C觕<HXoyUqȜL/-)hHE };u9u=Ի-=fP;缊9~ 0?N2CzoXI8xc }6sѫBV1gQuCП|]s>_ N҄_Ԝ'ҏ&o?Vuc:K^_kxmgPp|z~5ǫi^c=O;~4ÉoNSF[;UIe )=uүh0̺jW7};D}fć;nƒ;c{4DSZ:/ෘ?cἫ?hGgxx44;  ^I[ȯ".{~)t v`c}M aso$ou\M߉__N_qs;a++/]'yӿ'F4W^7/ցãK'VL=Nm[WuI#C# ^Y^úARo?Z K>Tt'{{_4ou=}JvNt^Dsw#::W柩&prx1CO98/{'gWXg@.u $z] O97CF<$Ojc}bT+qF/Y/=D_nw td#=G9nw< <<'䟓{σ 3rtD(nna^:A=YK vا~'~~^|; QExo/!OPbuP?LUBp6Myv27Ov/eu#w4E*qO1aNwRO>pr#!߼|cBoe>Rǥ?ӎ~>Rsע7ʙKk1ڈǏ l M[S6[N^CCd\rP \/};2UXyk~*Ey+ twY¾\%v_U޷AwiaoG_j>58k^)qu?1@}Cqߛ9VsnM"=y1߯D'a6CkAqpQ\e6/L|Ӊ_l}ďbY/|}p?:%Ǖ'/6RV!>E_8Us8:S H^s~#6/Po8N\_@sPJgrx18μu{c??+t9 ȹ8G=>}=݅^J =Nmᶗ:NKs*"/ox\=ҫ 1+;Om YnI?y-Qx7jxI'NOJu'Տ*jp | q0v-}#Ƞ_ݦ!Ն87 uISO7>:> >ƀF/׈p2WFC`i0B.gZ[oQKܲ|(䳾~s+} GCG_M_[/}R};s/hkk_47R:;HO~ OEA7;,5?06P'qg;[5OXx ^I?'7gћoa7V'5]$aZ zVO9 t{g;r!sɓqn| wJ9x ҉jZKZ[| 8#}fs̺yU} 9.~4`-:7\=;5/›ޒ+Kx>7ُ:)g|5|6y5mS.e̛y[:K_{5ҳ3&zk:N7NKƝKyƔzo3m3'?~}賸;n9ENys^yU30ύύ:8sMSn|xԱg[>擷N}ܖٟxև^.d߿zʴ7L=]~zG^{i/z[^1_ʾׇ>15=5aį\y񨿝;L1ٟ{g|~sOٿ<ֻM6s}g\}+rǍ/O>}'ߒ^?YgƏ>鏏^S9HkW~3_k}7j>K8V5/-7N}ʛ\ucyÔsj[rejƏ*71't/G123/ ϾΗ^٫6gtԫ^]W~o藗~9~F0//rqǏ?×}`˱_F_e/їpKlY]6.}VFՄg5aO]1+F|sb9_w|E2죌%׍{i«q^]:Q.j¨Wƍm6nG7죍ƍ?hɫ _ɫq^]:Q.j¨WbBh>hɫq^]:Q.j¨WўO>[o pcaMethods/data/metaboliteDataComplete.RData0000644000175100017510000006350214614231101022116 0ustar00biocbuildbiocbuildx]Wa&: 0$NB`f 5aʀbHbpHB !@z#vܫlٖV==uٲzulɒ̀}^{?/]/3ΘuƬ_`Vy8;߯aޢW/~yh-q[?n_ooo_snVx=eWovLض?9>fK>W}{>?2'|䶗ׯ 1tvԍﵶk .ݲG޷?׎=cW~}=oz]P_'밼]=ƔgD?w~lӾ%d-Sλ|}/9Yl _~se:ݙ_ZsS?~- όS}ԜO/[U>s~=|[{Y>{ GM5cU_7>['?7r?nm}ۿκ_>[n_puYwW5{~ˇ96rׯU'to_~m?ߗʞ_K**y+ w·񇎿ӫlB;,5} Xsm7U~_~n57|y,W4֭y^2z] m[[}_>WrZ>zew./{|/ ,nwrw7Yz'~Eٺ7 R/kβWڊhwgR3yR,~g 7*ݞٳ:Ψm~jOUx]v_}l}KXsg6ߟ}WǼ^b]"3~/ٝŬ˾􊫯Xu޶'څʲ-l =Z"]x>k9}__i.|ՑMKYoܺw{?_?ru3=_Xom ZsJWzoKn4xe|u{I?/9'~.QYc[m׽s{wWMֶZaMφ ۓ B%˲pVhgX|o=] ϵ^xٽġ_}j+m*{ُѷo]z|ҮcF3l1 7a[>,zswh]ryz'mk-{9ʮ݇VݭWsN[shnO[O! |˖z{0ߖG_;Ӧh=\nJ+l]ljѪ` ~ֽ"Swf#lT8ozţG~zu|#M?7 +^U%N<o8i/%,'V:ˉseoڿm*ٗUwm9i9V˿m;ɖE7YE٭'؆7yu|cnkNzo꘿CEyAt>kEw-b.c_U?9_7/>ϖ`}%/^|Z~* ?97 ^gKB~x^x ɾ_t{sK>}[Slz+q{s>α!͜KV9 q\hŜKS: / »v؊p>ɦdHSlͻdK++?{~ [y_=~2_uo+N>ڔRٓѵ_^'P3^F7?JG[p>O9|}6rTwCh1Ü{s'`+^ͳ]~ׇon!o:ҕ y>/Pqk.Cm{,zlK%F>}c?/ ;yu`6y.q[)F^X'x0Nl+>J$ y_[oZ[z;^W%CCo!9i$覐(UxnκS>{z/qy].;GC5-Z0%/_9sy_yXfFY^I=6K}7Z_KC+ K{ߒ<6ç^QZ_籾sw yՋx/K꽵ߋUz;!/xu}9ϫ zo\KtK>:oo6]X%'><|Da$E/t =ƬU^ĕ{QŝyC||mǣ o'Ba>]Vms-Q|8_J]Airn/K|xuTNn`㏹ֵ>%nBcE)ǦiI\os8w<'ިI>p7ߣ. >d}ou=ȹ0x.+_OFw!ﱍ{(_`RlȞnx/GO<7HΙ- 'm}ϋ˄+MQA[) ͫ9矠S|qwvdC:s븎uQ}[ZmѦWyޑx0#ϏBdp];=uD/(<ѵ^ުC]fc'vf+{΂+Ћ9e7]u77:؇!pWC˕{AFp0_q|޶Dw{}|ŗs/͹@ޢ|4+=z -K/z3syP|^gyΉ2Q6썶&Ի<'K&臟&qpwȯx1ye1#~8_0?9G? }o{k|+>PWqY!'G7{꼱m+G%1q1".-MX8 !a//Wj E`I<}s߉[B+#8qN#8j߇|Rb/h;t'~h\iǍ_mŢ/lf?w;;]#}$+ۣpqx>K7ǶGQ_XcBdW/팏B~_+q@\[*ƓO8AaP' 5"~Y"/=^^4S2} S틏x^Eu_ E FyyMw!  }Nxj׏ω/M4y"Wwy&k9j3q5zɀ~0Mzo[ }yymm||.!$׿qƈ.nq8<'7-^{). S_zߓo<{,]P曨7F|} lKuRW!u_ 瘫IwmuC2šqtA8/{xvIgY :3{i;+Y7. ^EkoK}\myr(筗).p|"Q/>IWQ_fqx?.`{lVYKT%_8-!gpO o͚$H1u̟/[}S_veMWxK{Om'&k[jG?Y(_>>d{Ό R[CQ^S@~Փ;Zާ8:FvZdB}nȾ5K]U<\a)0E?z3sټ0IaW@{S>+J֙p6p{&W:붖BmZ/(>z֏@̜!o_Qwzfөˇ.v78ɳ~ >|Ha5-|d}ПHɪkLuwGWlm y}GO4&$O\v v*[S>.Kn1tWI}'LZ_^JO_|c%u.ԫ_R*.d:w6_`#E;7>E{y8M/~Ѷ~Cz]9>+ 6<﬍y[5g]d }}㔷TR&n^^0wz}A_Fl/.9wЯH@ӜG{ GҬ_Ӫ7~: g)9xjv;Za|azxz۾7D亶$_:-aQoYHoK7lo\_'>aqzD VK_D8x bB>cZcs%|U-Γ~ז_R(:l{{wem9xp^^k\}0xLm<| TVJr&|/@|菀xsbW^/W &5K}:(+!oLyuUmUlSg-pa.8Ѕ|Zm`>V@D8x-7[E/2sx-7?>3>PGaXx_i0,Z9gUϩ%@8m~5~ :Lets9~Wx-L㷟m-z/۟Guwimgu>OKT~hs k'ux[h)οm˓Nisf IYm)b8X9dG$| 䑾Reg3nS4OWd]6xdqKRo4%8Vn|{4i _w_{qxvZmyт.~+=8/!#xoَx1}Fձ*OUNyDui} lb ;_ׅ+ɓR6i*O5q1G}e+ |hS>/,e.#Rnyy|ÅϲOKgBAcdq8%_#sz\+՟C/fXWob+7?~KMܸ]^ OD>7;A}D%#-޽'ʱFe!owKxWGI &^:x9gk?#djittZNaSMxoK$[G.}z/&__xpʳ}K‹g\3 KOPsf=˭oo3 <m?:lep7oe 2/^S <<:[uZKwg*λ>~^$P|;k%UQ+MM?"7ۃ8|_B:\S9h+#Ʒ?}ύ7eBUQjkNi$/f:ۭփK]u@%}Jp CG5o7J<&G~PN-VCOf6_,o,V? ՉWm ƞxCZpJp) kOs!羟}[OaDrTqhaJ7G&>ǰWm'뭗󶂸v7<:@f)xxITHgk_)iM^p>#+s֫x5C ckm?E>mGWX:XK= ]|#:;~O],~vx/u CXW_q|]a|9Ψ[qʷ?Sޔ 钭,^g/J=F8)}!k +ҋOJipcro%}&O]G:G3S_=x*WIެ:.=atcM1?':p}?7'@\\,gΧQ*Ƽ~5MuBzG'UpY 8.plҧh?o2 *Wqg]ق["Gۆ?M^yN^DC=_*^eg-^Cu'-ׅG7zSK&:_WUʼn)y*wttmYN^eǬ>yVN\[x^ԺWVݦs~ף _ / @W?q=7,\8(V N{-G*TsBxpj*b#QxCrt~^ +-f:WnH/W/o|"୾.#j%x*^Պ2/Ieڧ > ğ 8k_?Fxxv>CR?8~ywqv'O-?}{x^vzK'G = Q_ G/U}Z?ߡ^!&|'t]C"يpixV>2p ȾEW\zmU)Ë;cKRuЗ/ݩq7Sg(OrVnpۋI<=*PKJdC{Ktv৊謫~LI rWѹ% ƍ@C *5gV [wucQmjxuQߴqlo: LV9n @[;J<V5Eunv;q4*~⫺y2H8 ?6ppW#EwgpYrRVþm.8~9Zo( x艬|*àIx,^+cΛ?ۖI8Xۗ|8G+ /!^Z9QkSWW uWީJ} *$@ڈUW kCk+jWjwuUs`3Hzt.vrK~s_(TL_U9f>Vkdu?\X|gOkd=fBCKB>|r;r5G:Cxѵ~x_}o6MI[ N&޹%{ׂ=hq_8w 57g/~C ]Rykh9'KcГ5 WN=wg%g%F{vPWNwksLFF׫ ކ.\W_I Bo\9L «/Հn@n 7UnDS(؛_fZ|<ϡtCNVm%ʯZxw JpBx޳}tDүN~Eԉ:s_X:_"wmEwTD_ԟH0} 7ѷga^}UUďt: W5ȿH_I+z凬k5'9*G{Y3q>*&f>u|Y!} T+x6B<W½SQGG<oj3g'~g}THL[I82S_NxH|,_8vп1Bˇo@'@ֿoI]'|gI$ .E~#Աڟ)b*߽83[{CO -o@9"x TuDё'5MBoy;~O"NEĉ -LjuiG0ᑊzU|n%Omaǵnt<ң D%]R1y|3O~vxmuwzgU/y!~@'^%Txt#--9otP^1ύuoz9G{3GЯxXQ /~$}v⯮3M~]Ĺ9)uZ菪N w+iʏе@=M=Q=nē'>X#*eū~P╇/N_9wHo g&1ywP>χeetX {}EQ9'Ot9j01^ޏ7t7/-f^ũ؏oAe3}>~; r -\0;KQrBMO|pp®PZ1|Dp;?mWKەwZy8Oi#T :"1I]4pQ{T#?/=]eE܏/B1VeL1wI\8qUO 9E;E\G\wB΍}N޷FOypcaSȓm}7qLz"t#bqI_D<CG[>/S>94 q'[u\yD;p>$~GWU?n+"ϑ/Uu5p>m6WKt!ȟ[~jҡ+/H.+$7:ؿ'8De ~^ Ӷo*~V]-a߉e?f=QEBy|.$El> 'C|`^urζ"$kaG ~;k!f_gLzq2|(<.ΉI)GXQЅ 7qᥜۭܗ">}D~R)|Z zB2EߤPq}eO+pg!G}J⥡%]8*x9Z)0# G> o?M5mGcC9+DY|!ư}tH9<˞C&>=E=+tzc2A=*w|{qx9߅x\zF\,gU}ǩ/E:' tqI>x<+%5u5G?7x5rȇc.>@s4֓>lv|~Za=jvF5CV3p;FTz}Cxm&N$8~V__|m;w?F?m3~_JYsl?8r+\]#?{js}/>(Fo&ﳭʇ_IO ᧓[ky2:ߵRK(I^VN]|q)Mě5|zZ)颊/"=uq^g+c'uUK!n~NF& ?sKT ~|[nMjEiK%D>q3&YѿmƯ-|/W7Eˣnϳ>_ )?I++|~2DԣW?i; |9FoY /h/8u$>m'LDZJ߉{u|Y/܋//h#q;_w6 <WG0ޥv{̯K KjJ~[gZʺƇAk)p h|W:9yAI_gL|Z!G]'Mt39?%6 Ucxy9Qk^zi9%䚗<)Sq5¯8Q"QtC /Eyu_Ix'~Tw Jo u\pR4qC.%_y~휳^#t.3 fpf|HS1i:~ ~#; .7@?a4<W/UsdFO\<(u y L<:K7.\. o+{A'b? Ǘ1%_WG?o.-j .O'Ws3vU~kiZ]B^=-#yA8} =\7%t һuRfWQSO%s $ɏ^sK s ޢ%18k8xy,U~N#&&8 Эj‡>tTZ~|{8O{ QODT)_"9#"!>;sFuG׆g]q{W>y4H/cMDz >&~ fRoMϭnOzu4 ~î) cZ{ oh!\.Ϙ#g?!|M&f˘P-sd1sx~ 9J{>k~|PJ&_|$VFtlp;}GW)|UG|Ggh8wю$2g]E Z:TrM7-p'E);PO>o/Q~rOȗ\zq%שf7:IV?jD2[#9<:O]ț=>ZE|ל%]9/%Y|"Gjǿ!E](G&p zȗ9y泗O[)#>D^u1"s~>g/ܷ)֑t%5d`pbX'~LQV>]>S_i#xv'B4֬9/mhnQI~+V6t.ZMz$p>kҎ8me'WR(q75W=ySrGgޜf}I"KEi )`M-x }e+{_)˿Q4~1%`|lOׁ7T<^[X= Y'<&9\IN-T >MT8t%{M-̢I8e#}=vO'N7fB#qYw:F S?xK]Ãܖϋte1c;M+_vJ#_>tds1:^mskC}qY|NGButm3KUKtipBk~K9L987`K8}a|yZ!|ƣL38< I ~esЃ Ofwh$VmX5 ϝLzz/i3*<}"㟦~p`[LgNik8t 6/*3 _3)} BpiUR=ye/`Gz>LM_+(b7_=4yՁo yW◩|u=\ Me=O u2ລɻwA<܋w{^Q'z  |x|( ['ujG~RGoFp* Zkn3 /Ϫ;؆n y=g>Q |)j}qijtĿplj_ZT'cS}8z 'З1cʧ[9wI[yyc9ׅOt HSg)x̍S?'H#w;j1kBǡw'xރM+jgFpxUN&Χ"ç;Dtu |g%lQO{'S_0먋mp|\T/|d3HOS6A~^#vwĿTC_cFA'rv|L#j^89Z7-ɠsr3y?t GϏ^ܤe4 k3hwԓ[Lwsj`?qR:,p./E&x?yt}WO|>O|t^A*7炯k]8\>/ҧK0Fy9aKW /Lkf!Ӝ ͩ~o`_ޕj_ma }Iqg`? l>?Fa浦#>9n?D<@v}Z wSk))sN:kG8MtY/4If{k]sRG&Cq?j.:zJs95UX+裨N' FaNm๚#%~N~̏'Dd*x럔~~a5:axk7G'=H?A5׵K2}*AIF{nYqZϧYh q8?{zWPooe oB$^r4WK.sx^κ:z\1/ pd(L:#׷:A||׼sc8D/o|XG`od^ K,S:wj2>>EQހhQw`EE~Rzxεflê_}tdȧѫ5?#Nt!CryPV ;z>z|\NṈm|N6p\pif(7sod? \t&G:ǙwaUlg5O5gQ)'qB(8u~Y6/W'֣N1Gj}t?(^4r[x~oʟb"^|syT\#s'x4?X/?nt?Y YƯ\sm#w|o/F>k+/-s^5oC<4;; [iIL} -C<!6 x vyUԜCRU[>$*7^k^]D}ͳhCg[<WbΠ(uˈ3s΄7&Q'6?8iNzuy)znpƃ-: _~=ˮsxC.̷rsz.E6p^zg }R5<{9_:C}>/|f/l%J|~[tV@M11 Ch=䗓ߟ$gOې^]ߊ?o#uHͽ4Dgy=emԡ]jݤBb=&XW\;$V+ùid^p=|_RJ/q8 O5װ E~ZʩY^ow.^wYzn!_W9A n{HW$8X~}Ze_$_'O?-$y 4O%/G'ԍ kt, H?k]X>d%x56H>| y]MZ_ė}x'..p;W7n.es} 7o2HG_BKɜ[>5=cHnn*? \ #S\Q[ p7sO0\͓o?oAyaU|/~B#xs4GD֐et{Daסbs RuT&UV _خ9њw1[qpX8|kEҏO Z3|=\)g?ξhqUwS nӇI]0@:?OL7Jpzp$՗5w wѹ)9o)oFNxOsw¿JSPt꣟4V|=ϯ9#;N= tҽi9|q|/'9s'i#n Q{?s! F ~>%`}c1ipRm&a\Ā|Sk7}Hl=uCkvi:`=$/ߒQ>@VqN'M[#^p\s3N)=x_h[1Q%KO*')g`p!g#&Q'\䵇qtkwRgd?jG|l$"['up/[3@# x})ώb6N}0y'sⅇOH|~F3ٵC 7{3D^X9\^d|ɗMR|:I)փ3.+_w&.g{}c k0l$~j~t4OS? =I?ApqKSҟLA7q 5'u,_,}äUD{>jlW|u8WҷO= ezy~U H#<ԝԛ[AG`1H|.ʳ7hݹmut6WQ7%@,Q̓qk.78T<6$d|ބoͅo3Gx2wsgޔ3w|(+8|{/0^:9~|Rxh;Hfx2Gn"Dc$| R}y8⼾Y>=C9*mD%@78>AoD{~ZyY'<.%s+>D85~|])Pg#|< ]g Cts^Cc՜;{+!~1FbW ˈ_x:̑qtSߪO/~knV 'z~+\6gAۗk.tw[kg x~7S~)*p׫yLO胥OXu֝7G5&erx|/<Ҝg*鯡Ogw搿IGù|x(FqGaG$\tܷ~t\i#&|;>/nx'u5W}vMلt~&9g `݊}Cώq~Ni <8Mxįofv:{?Ox3G+聗a/#հ4e{M{caﶅ}>̹9SUjDwPŜX/nW_?f<4}{<]A }1U^ӕ0Ƕy0*d]Ԑߣqp5vSwnfXCa++~ VO*}/ʈ?08G%9V#]d?9gN=v9,޼1!x;z) Qr}u{Ljˊ?)!zt/j|h%SKlܰ }8#&_?<6p^p)0 s]>!+ƉS̭7N_x'зo?E. '+VC⃔7)?9.Ddg3N~Z_Yğ_.y%vT:͋j苩ޔ O/? /'~Jp{c~ԥo#wl|L? t =d]rV迀̥p#% ZyaNx2G9g8/u;!_Hmүkg{Sl ?k6yyMʩG*Q+uMq^V$^ՁA r9~D:/dKNYK|&^BK#&/0 Hq^|(~,ė=J1}$q(|6pBm 9gC' _':7<a:k; ?ux؄gԻ-ԯ?"/m:x~ #EQ~Q~r5ɾAj2q!ʇ8{GCǼZk]|~ n^8/\by/;p^IϧCn<>nQzܐn+sG8=?4 8}%_< |?dL?}1m;/S}Gk?|z+{c}[G_ī~]bk<5zi Ao^'9Ź,s8NR7Fm}c4/~?R3Yҹ7SvP7>QxΣԝ8;U 8g9@Q~psY sb,^&Ü3%Np=OÛ& ϧ'?E?:<ߏQ_s^d+w8LNj QNm3u՜)UZ\II:\no+8ա=F߬HZxxBK u@7`༥yʨ&ɇw# /j!IF7_o1R2ԋ‹B q!J k&O8A͙>33W\j|ssj4sn;W?pxq0x5yS 'h>1C9"7a˟}r>QN򼁀91@}}zj4s$O9FU,]o8眱I3Mх7Wz>I=P:6I$ < 8}A|F¾uKɼa|*eoZ6{WcÓ>ƟXm'?9z~K~ŭ#s277ߋ46u}^Ö`:G*$9oo9b9RCoȡR?؈f:mmA}CXWϺwEhϷd85~UQףU?ς.MNIϠ~}81㕁_q (>м4oΙIZSj-&vSE#}1U3>#ܸ6?3F@sΤO|0붏He_+{Q9-͟yH7$xxux_}ńMoW=^ _;;H\?X s!lAFCs>}-yqԡ[W=M_j' gNߡ睂'LUk }X'~}>Ljki5@:Tq}7bnCI\ o!e <>J4'}8ry.ֹ֩t&~eSt3GS#=M:a}&^anwFBܜsNYp-n?O|Dw;oa1yp /-⳱O ?oߎ9@cF紓/?| Y#VǨsGd3 qRo>^x5^xΜF^۪񩒎x8#z^_!I6 NCͫ7j~+Y>.L; Hi"%߬+g. c(O|);'p}9/bd;^U=weRwpB.!^ u}b |w~ O/'O?MM5!pbxɍi4itnn&hIy:Qx:A9V_a|_wxIv|)/>j>3aA=q(y|rp)lj/Z+(u@_0 *߷ ]s7 ?qWxO {Qkv:Ypnrx _Jպċ<\c/n<|6^5miDtf\gʺriz+&C''D|1NC}IuzNy!֩ 0|{/7s]j/E>{"%~(ךࢮm_}|Nh?Q|&?Jǧ:R`O7'/{.\G Q>41N%?*GO;w'OA<GG[xI>"c?WGdYK᫠yG._c,\ )4W]y㞥 ?7|Vs;GΙE0AT/z8s^pʦw%zSJ*a֍2:8>၀?As͵OT#}p|x:2"-\ou33C |sz5S:4&H-:ʦgq+Yο!_/_ϏfoC%7νaMj^ ^_7;y[p˭sosϛ+zxn]?_t?i¹7tUo7οܹ̿.<%}ẅw__?E _sÛs~Us\W>眫7<߽檹ϿW/޺py^ٛ-w5u nu &vg8u<~?Cq򯧽nn~Esw$zi .87.iן.ʾէ.9ﯜw{ʹ//ys+bW8?W4s #d?Wgsռ_8u.\_7[{ⷯ+xU w5'iW_pC6e‚'^?g57/sD$OwF//9m_L;Mok?67NWο1>~k?z s>8›YoU[]W߆Hp/.ȼnvႹ7]`Q3oawe鿉b>Ap}>zd/,ͫ-u5Wwm%2^pه7ςKfy_\}[g<;y(% A=_O_ vOMi.O݅hx/|/=ųM?N O O O O O_ӯWud[]6M˦_eӯ|klM˒k ?_0 g|ьg?_2Kg?ϸ f\3?Kf|%3>wϻtttw%3~p33~xϗ?3opppt]:.q}θKg\ߥ333??} g/,wܸN ~\vkYb0<ЖBX:]Bݺtx*I C_;d0A7X:N 1P

N-_c?0ǒYzhiPbUEZ 4UٌDd}Jq,""9E^Qt?zNP# pcaMethods/DESCRIPTION0000644000175100017510000000445714614350074015405 0ustar00biocbuildbiocbuildPackage: pcaMethods Maintainer: Henning Redestig License: GPL (>= 3) Title: A collection of PCA methods LinkingTo: Rcpp LazyLoad: Yes Author: Wolfram Stacklies, Henning Redestig, Kevin Wright Authors@R: c(person(given="Wolfram", family="Stacklies", role=c("aut")), person(given="Henning", family="Redestig", email="henning.red@gmail.com", comment=c(ORCID="0000-0003-2130-9288"), role=c("aut","cre")), person(given="Kevin", family="Wright", comment=c(ORCID="0000-0002-0617-8673"), role="aut")) SystemRequirements: Rcpp Description: Provides Bayesian PCA, Probabilistic PCA, Nipals PCA, Inverse Non-Linear PCA and the conventional SVD PCA. A cluster based method for missing value estimation is included for comparison. BPCA, PPCA and NipalsPCA may be used to perform PCA on incomplete data as well as for accurate missing value estimation. A set of methods for printing and plotting the results is also provided. All PCA methods make use of the same data structure (pcaRes) to provide a common interface to the PCA results. Initiated at the Max-Planck Institute for Molecular Plant Physiology, Golm, Germany. Version: 1.96.0 URL: https://github.com/hredestig/pcamethods BugReports: https://github.com/hredestig/pcamethods/issues Encoding: UTF-8 Depends: Biobase, methods Imports: BiocGenerics, Rcpp (>= 0.11.3), MASS Suggests: matrixStats, lattice, ggplot2 Collate: 'derrorHierarchic.R' 'errorHierarchic.R' 'AllClasses.R' 'AllGenerics.R' 'BPCA_dostep.R' 'BPCA_initmodel.R' 'bpca.R' 'checkData.R' 'forkNlpcaNet.R' 'kEstimate.R' 'kEstimateFast.R' 'lineSearch.R' 'llsImpute.R' 'methods-ExpressionSet.R' 'methods-nniRes.R' 'methods-pcaRes.R' 'nipalsPca.R' 'nlpca.R' 'optiAlgCgd.R' 'orth.R' 'pca.R' 'pcaMethods-package.R' 'ppca.R' 'prep.R' 'repmat.R' 'robustPca.R' 'sortFeatures.R' 'svdImpute.R' 'vector2matrices.R' 'xval.R' Packaged: 2024-05-01 05:16:44 UTC; biocbuild biocViews: Bayesian RoxygenNote: 6.1.1 git_url: https://git.bioconductor.org/packages/pcaMethods git_branch: RELEASE_3_19 git_last_commit: a97ba23 git_last_commit_date: 2024-04-30 Repository: Bioconductor 3.19 Date/Publication: 2024-04-30 NeedsCompilation: yes pcaMethods/inst/0000755000175100017510000000000014614350074014642 5ustar00biocbuildbiocbuildpcaMethods/inst/CITATION0000644000175100017510000000164614614231101015773 0ustar00biocbuildbiocbuildcitHeader("The pcaMethods package implement algorithms found in several different publication. Refer to function documentation for reference to the original articles.") citEntry(entry="article", title = "pcaMethods -- a Bioconductor package providing PCA methods for incomplete data", author = "Wolfram Stacklies and Henning Redestig and Matthias Scholz and Dirk Walther and Joachim Selbig", journal = "Bioinformatics", year = 2007, pages ="1164--1167", volume = "23", textVersion = paste("Stacklies, W., Redestig, H., Scholz, M., Walther, D. and Selbig, J. ", "pcaMethods -- a Bioconductor package providing PCA methods for incomplete", "data. Bioinformatics, 2007, 23, 1164-1167") ) citFooter("This free open-source software implements academic research by the authors and co-workers. If you use it, please support the project by citing the appropriate journal articles.") pcaMethods/inst/doc/0000755000175100017510000000000014614350074015407 5ustar00biocbuildbiocbuildpcaMethods/inst/doc/missingValues.pdf0000644000175100017510000031404714614347746020760 0ustar00biocbuildbiocbuild%PDF-1.5 % 10 0 obj << /Length 1837 /Filter /FlateDecode >> stream xڽn6_G"%/ h;,$sx(YvtJX>xșZ͖3r|eB̖هr?tHoaeeb˃ki8~궎|!de\Γu;f-`0loWs98B;ZKr猛DF&uy&;'KZ*.skv~dZ9)+T[½F*eݡsD/k|]ْ^d@ח/_*&gfk^#E.[_ـ43iQsBEZBfL)+{I"cJskuUnu(mC9&vTZtD&cٹFu׮.*5;ru]vqqk_|;0eɦ.w߰ BYȔmBBSRKrXL( ŀaM( Γ!S 2%!Sp'~ +^&3$CJQ*D2&}W+%%BRf=+6͡Šho|]ABVJdQ liGkYmV,I2򑧩[u rlEM`hshݚ5%~H9iRN$A&:` CK>ٻv1%}!xzY @{+1zyֶ&Kd“"(CQ (wxd{ %Ou. ~A)ɷ3izptOHWkFEAS/EpDӖğ:oi]ROr|6n(%,I?&r`<HKY^6L!T5ᷠAM{ PAR\d \ ԏJ] ~-y(rBph|,8em $cצ'q=#7g,>627زp ^ږzs9t}v!g{`G+7mgBMwÔA3P1B8T [0픡cS,2lXq+哿 endstream endobj 28 0 obj << /Length 1084 /Filter /FlateDecode >> stream xڝVKo8WD"E%v1 m!mw#cby|˫ۯq2JtMGHDq0,"JG|Ix?Z~ u[ƾ4?_5 GA$=p]V*{m}~^=GXXa܌dGsOlAmՍJ1NOeN&AXv' jaQj$|u{Ep?I/Mʥp++uha.sT؁iK邝2!gsEΘr|g]Q -"{;ŝ@h9q~#p[UL0".?;UqFW[Ο\ 'Հ'd:X6lʞ`5)ekÅA%rVS)V_+6o˃7 ڭN S$HR@zD4B#c̼C k f4تLBO=$bk( n[kLV4waxF= ƕOtuqdxqu\_\^7y|-jIH%_̧=seK=7]wN(Y> stream x313T0P04W5W01T0PH1*22(Bs<=\ %E\N \. ц \. a`?r 5ez endstream endobj 31 0 obj << /Length 116 /Filter /FlateDecode >> stream x313T0P0V5W02W0PH1*22 (Bds<=\ %E\N \. ц \. c``pzrrlI endstream endobj 32 0 obj << /Length 99 /Filter /FlateDecode >> stream x313T0P04F )\\@$lIr p{IO_T.}g E!'EA0XAՓ+ ; endstream endobj 33 0 obj << /Length 203 /Filter /FlateDecode >> stream xڝ= @_L#8MLRL!he!Vjih'({!q-6߲`}t!'<8 91 ũ piNfqJf)c2ot=̜w{@^m W÷x: dTLdO_'X`*w]!WҢqz9KU" }}d endstream endobj 34 0 obj << /Length 141 /Filter /FlateDecode >> stream x313T0Pac S#CB.# I$r9yr+Yp{E=}JJS ]  b<] X큸7001;j?0FJ endstream endobj 35 0 obj << /Length 222 /Filter /FlateDecode >> stream xe1N1E*i| .-V Ab $(UAݣ(>B,?kWEwk.i;O%/$=iI^>$nF6x0ڄʬ ͎X⌾T~fGvlgOȠ<|HTGǂ+ˇD5WTL3*=2,<8h endstream endobj 36 0 obj << /Length 181 /Filter /FlateDecode >> stream xڕ=@!$p. b&ZY+h pJLh$%^5Y (xTHN)74 U[QcL uMĄB9ƛG3a(if M( /#`cV2OZ˿Z;5t endstream endobj 37 0 obj << /Length 207 /Filter /FlateDecode >> stream xڥ= @4{t&)!BBB,xxqFE惝}ov)ZRGk;Sʱڬ)Nюe6aܠOi(Zb>$\Cǹ.5Tº)7 P \)'ߘ'-,e$9ґ i `AY ֚ G9-c endstream endobj 38 0 obj << /Length 241 /Filter /FlateDecode >> stream xm1N0E"4 @TE"Th+)S ͓=3uE5w|pWs/ 5gFGn{n5j+UknS=6@! `dHp糢0g0p \ύF<'"DMbLz[Zj6]*7DE??(jALP5ˠGԡ(OY*G@BR栛 5pI endstream endobj 39 0 obj << /Length 183 /Filter /FlateDecode >> stream xڕͽ 0+- h NB`A'qRGE(}zWEq _~3#)';#I~C"cQ8|Q iT5t] '`010%p1 iBt*Rt 2;nB)4_T+~Ѭ.:\M endstream endobj 40 0 obj << /Length 213 /Filter /FlateDecode >> stream x}O @`qM>!zI 0XɧSW؈p w3s3Y:'sÄ1P{~s8Ӵ$4'tcot=w {* (D`D:y#jAԠBQSQ]9h@9׆mƠ3/"-PIoәn ժ?|R3{6nR}Zn endstream endobj 41 0 obj << /Length 245 /Filter /FlateDecode >> stream xm1N@ Ema|HBbE"Tj`&GkH 4أnv+4rVISJ{!Orݢ~9^ꖋknR*.PI^((`)3Sژ1+-:%8p'?, \%ᔀ^ÊH"4)MP9%7Hi/! GdL!n&{| JMc_u|_!r endstream endobj 45 0 obj << /Length 137 /Filter /FlateDecode >> stream x%ɱ 0#Y LӴZ N⤎n>j#SA៾vf.J\#un&g]u4{q:#tۥX^V#}/@H5LT;Ic4 U%0s/Z) endstream endobj 46 0 obj << /Length 199 /Filter /FlateDecode >> stream xڥ=@PL ȟ b&ZY+hxJ d)-bߛy63f%gtx0e5$ jOaj:*yAUlQtєg&̛}Nr 5r^ a2ʮ`i`r_zH&=| z)3WwFHH endstream endobj 47 0 obj << /Length 203 /Filter /FlateDecode >> stream xu1@EPLL 1D+ c&jQ8%gdB-^6gߑ;dO\q~ƨ4 Py*^r; SrPEqbtLR~3&0 > stream xU 0ES:ޢI N&O'8:knh@}7D%YgXnE68])$$ƒ~ܟv1ɂ1GG xos*!~Zo(k B" Pq>.۶{xcA+M;= endstream endobj 49 0 obj << /Length 187 /Filter /FlateDecode >> stream xU @ O Yxw8jotr'utPQ5I-$f2c-Z)+GZv*C@Hx=Π9sT/Ԩ"kF㇠ZFQ"7!\LŮ{kw; #e%(𮈻i^/aTtY!)y@,=l M>k endstream endobj 50 0 obj << /Length 167 /Filter /FlateDecode >> stream x313T0P04S5W05P0PH1*26(Bs<=\ %E\N \. ц \. 30߀JNa!?#I0#;xI#> stream xu1A50]c&k%P)DRAhQA;C_ V:F:i]yYm)5КԸI T:"$a"X B$֞?!#rljtjCsehx. MO {}RmU@#C3zT endstream endobj 52 0 obj << /Length 148 /Filter /FlateDecode >> stream x=1 @ER~- g`#8RK EJ4RZ(ޑ'̨i> stream x313T0P04F )\\@$lIr p{IO_T.}g E!'E@!ncr e endstream endobj 54 0 obj << /Length 179 /Filter /FlateDecode >> stream x313T0P0Q5W0P0PH1*21 (Bds<L=\ %E\N \. ц \. @xD2?@,&=`C" ?ƏadjƎa݄lMI$b6LrzrrШA endstream endobj 55 0 obj << /Length 118 /Filter /FlateDecode >> stream x313T0P0S04S01S06QH1*2 (Z@ds<-=\ %E\N \. ц \. c$! b\\\ϊ> endstream endobj 56 0 obj << /Length 102 /Filter /FlateDecode >> stream x313T0P0"3#CCB.#)T&9ɓK?\ȒKCKW4K)YKE!P E >'W $ endstream endobj 57 0 obj << /Length 137 /Filter /FlateDecode >> stream x313T0P04S02W01V05RH1*22(Bs≮=\ %E\N \. ц \. QqC=C=2p\   \\\8 endstream endobj 58 0 obj << /Length 188 /Filter /FlateDecode >> stream xU=@`6$p.?`# b&ZY+h+L9 Gذ nKfQ!!^CUdx[a> stream xmбn@ 1DG@ CT*CdPeJ;vhծGQxFkDd>;zWMrMMف5eJYƿ?mvϬ ΏToHN [`CZ,{ê3VZw LRD%ڻ{F:lZY> stream xڥ=N@Xi=B,  * D)S&\7GH6.DIi53oXk]꥞Z\ޤY\jw^%{"e;xIVV;RoN>`a}x3 HVmHb&oNhh:+Tp=q::Ϥ>F_/C21eya:#f`x!7<=c endstream endobj 61 0 obj << /Length 208 /Filter /FlateDecode >> stream xuн0k#xO `D`qRG(}FBЄĤ~pE.-K =zh.wStlytGN_NgL\kZZo-T c ښ[ۺ8Rf_yOwy_6|pdmA&:QV&ҘP$> stream xu @\z'H  ԩCtEh>уhkeͰ;Sr#&ttBpvd31[%OюWtOh9qh璳8"hre)Q5VzV \4 0i:ul3%Rk-Le00JKE|}xB endstream endobj 63 0 obj << /Length 242 /Filter /FlateDecode >> stream xmбN0?`閼A' X*E"LSad`y^o+dc$sT@|89:]NT8V4)[bFw)/=e3ynr5z z^AH ^_kO mb2{ o)޼IPX5`j5҆uiSy 9i^Z&WW9+ow }:难{{ endstream endobj 64 0 obj << /Length 221 /Filter /FlateDecode >> stream xmAJ@tx9B FSjtB\U.jir(sn }|2)$9?J\ze\)7oϔ-o/Yr>RbGx+$qP-T 8a Hڔ@\fgm{`%NGPik,F=pk0jluo-9m骢;[| endstream endobj 65 0 obj << /Length 200 /Filter /FlateDecode >> stream xu1@![L 肰!V$&ZY+h m(ذ.1мL4'bN%4 )$ft QbÀD4l ;+#/t=ȳ͂B9C X> stream x}ν 0+['SV8sh}>B.E$$q4MS;Q)+!׾28^0+Q.zŚl s ,5yofJNѭ>THA-I?6*<+1vL{Ԣyˡj endstream endobj 67 0 obj << /Length 245 /Filter /FlateDecode >> stream xm1JPYR |s}!` A+ RK Eʗ^a2Œ񟉋6̼yT尒x"p,\@_فs/*g. )&LOPvY`n ,{OěMx[l)zi&$vX?zΏE7 }t endstream endobj 68 0 obj << /Length 197 /Filter /FlateDecode >> stream xU; @? ` A+ RK E[7GQr)h1/t)ZEyɗϴOC-*2gd6:%Smx],vKȬqzjHHHC,10\qEqRc,S4EB訵H<,l)o e@)]X!uE{/^q endstream endobj 69 0 obj << /Length 212 /Filter /FlateDecode >> stream xuϱJ@_RG> stream xڕ1 P q(dGx9OA ZN⤎m֣xҘ!$!'3N*Φ|INY>-KNɗ[~>^W݊SSNNT D'Ҡi!4y;쑷Gwp{cjCe s]ؗʞZ."US9©-KI endstream endobj 71 0 obj << /Length 218 /Filter /FlateDecode >> stream xeαJA b > ]vj<-,J--mo||ybCBdy-j /;~2xxD-+j.KtoOԬY:ni0s #VH|ěFo;s+lq΅Ƕd,6ɺY'=alp +%D7p endstream endobj 72 0 obj << /Length 196 /Filter /FlateDecode >> stream xm= @'X#MXXSZYZZ(m#Xo[fa5B&x#/~,+E³N|n-f-nKn!R7 !Hꇨ+U4jdcޑM-孍@l_ "j~' f&74.WHe4A o \s` endstream endobj 73 0 obj << /Length 194 /Filter /FlateDecode >> stream x}1 @49IH,-,J--mMoL2LvY~ Gc 0G8 q bɁD9쎐y Y|=,9 ܂IѱË_ꪽ^cf8y/>_[;bPsfm]vҨVi.oVڷ[eڏ2t6 endstream endobj 74 0 obj << /Length 156 /Filter /FlateDecode >> stream x313T0P0bcKS#CB.cC I$r9yr+r{E=}JJS. @-\. =2>gg`zp=a&f?qA|.WO@.J endstream endobj 75 0 obj << /Length 154 /Filter /FlateDecode >> stream xuɱ 1 ኃG0O`\op Njh(bl-?崚aUÓ+>$?*_5o3z  H1D>1Cf$t cUIa.<5Ga D"JLKL`` ?:R endstream endobj 76 0 obj << /Length 194 /Filter /FlateDecode >> stream xu @`Ń0yVq :fNSuPY7|;4kuhgd4GO q^ͷ=@X f܂x>] C)C 6h[ }POmwj؊n֬GerۺInOs&y?ͅ_[*o&+jIhiKx endstream endobj 77 0 obj << /Length 180 /Filter /FlateDecode >> stream xm1 @ )xnBVJBBB"^do)BBbFST@F R/r@)Z?K6A}cE- ol}:X}"j&xovV$GC* ~f endstream endobj 78 0 obj << /Length 198 /Filter /FlateDecode >> stream xm1j@Ep!fsZ1d"W.B*'e h{A (&E a-]{^ҙ|Xr8}Rݒ;=K}A~qIג7j$2%32 ]hzdLs_Lä_Yt:wjh^H;FU.o%mZ-/LRz endstream endobj 79 0 obj << /Length 230 /Filter /FlateDecode >> stream xuνN0:D%{:&KmȀbj@y?BFi>@UJO򢸑Lȯ9Y^.wv™/}UI\ |~|]=%g\.7B>@T*ƒvPU> stream x}1 @]RVBVb(9BʈqvEy03L8I38Byrj5tكL@N0ހ)PR+IFdޒjIWZE,& *>`۰m$jKaj` U endstream endobj 81 0 obj << /Length 206 /Filter /FlateDecode >> stream xU1j@Eq!fo Rd\ l`W)B$e\vG)U8Mb3KtkZ>iyW]VGmZ[wy|گѧZg7}'8l"M !#T ppP\`~ԅƲꌀEwKr40À0=O%AnRZA endstream endobj 82 0 obj << /Length 176 /Filter /FlateDecode >> stream xuϽ @ nY ֫ 7:9::(>#tPCÑKm8r#:&xAk%5ጙC%k,ƭvd9%hr%HDbfRA#JA;=LVi@ &!`nOYo .n R endstream endobj 83 0 obj << /Length 178 /Filter /FlateDecode >> stream xm̱ 0H-}SV08ͣ7#tP> stream xEαn@ PGNO_KH@b!`b@L#nvH0e`'wgFJ)S)gG, 톊!څTVK:V6t՜b%71w%;]ͮ:$δ & nKoW1]ЋputF@uFjM0>ɏ) N6#0˾ j5>[ endstream endobj 85 0 obj << /Length 224 /Filter /FlateDecode >> stream xMα@ )iBy` A++Q);l3j:-(#IorNjNӜNP6hW%OR9Q[Qv$QKRvrM`> stream xu1n@Џ(Vf\^PXJQ*;eDv mGt .4#Jنc^"U4aY:m_ȼqy1'ˎ2%'PU2| (2w(ڦE-zD6BF{DIڝ3?mgDj # Arf#rNN,t']c^al оWqi7 endstream endobj 87 0 obj << /Length 170 /Filter /FlateDecode >> stream xe10 PW"y#' MKUJȀC X)GQz U 8eSI< e 15ߗ rKIr5JvDYPT)wK@1c5 0|2 GAw= /t:pZi|m˸иI Pt endstream endobj 88 0 obj << /Length 229 /Filter /FlateDecode >> stream xmбN@CA2 <əXg"WYBh<>%aKK6eg]B}}k{oxⷊ>.6-\WT<*#Syc]nyv@6CG'=D",2dfFz-mə1:;_w1|4t4hn7)xM> stream xUпJ@YR,LGȼnb.r6?` A+ RK E*-GHEq[E}\I)rVɢB+~ziRz>yzu^%k+snv#r69MD^HjO@IGJ3&`MS |08oF xo2("~B9~}B@BTB_Cmc1aH9ԝz xk endstream endobj 98 0 obj << /Length 130 /Filter /FlateDecode >> stream x-ɱ 0 g 2'0-k3:9 TGAEfڢ|7lXU:x@='e; m;P=fpq}kw+*\ǣҟ;ZFy2ddL*R!sBY ,P# endstream endobj 99 0 obj << /Length 131 /Filter /FlateDecode >> stream x-1 @E?^ xЙmV"RP:ٙ&Nwo\%红V\xA=y1:nwՇ Y/ t4M22DT&2+<*B# endstream endobj 100 0 obj << /Length 94 /Filter /FlateDecode >> stream x3230W0PaCsKCB.K &r9yr+Xr{O_T.}gC.}hCX.Oz 0X [\w endstream endobj 101 0 obj << /Length 101 /Filter /FlateDecode >> stream x3230W0PaCsc3CB.K 'r9yr+Xr{=}JJS ]  b<]d7`= 1S'W fp" endstream endobj 102 0 obj << /Length 94 /Filter /FlateDecode >> stream xM=@PEx$^!R { T߱4J2:*54`ƴ"f@BJJ7"i endstream endobj 103 0 obj << /Length 172 /Filter /FlateDecode >> stream x3134V0P0bSKCB.# I$r9yr+q{E=}JJS ]*c<]0A?  @CA2@5@D!dPICd \\\^ endstream endobj 104 0 obj << /Length 175 /Filter /FlateDecode >> stream x331Q0P0bScSKCB.S1s<L =\ %E\N @QhX.O g``~?`g N}`o`F¢0?Q\\\ endstream endobj 105 0 obj << /Length 235 /Filter /FlateDecode >> stream xmj1 ^=;Od-$AhO=Xބͣ{N"Q6>fB&?N'izmf4Z||DJƠz.rM/T%V~rEP@X8 \IU{3bY1Ez$'i=Sː†LBp6Pu 8:R [49޲&&Z'XΝ_%m endstream endobj 106 0 obj << /Length 260 /Filter /FlateDecode >> stream xڭѱJ@? LaZ 4ܪ[-'BBRP̛*y+uvg!B#n;MG4Zly\Ѣ瞚-Sӟ-5#%_v^QdRPDZTRR OԵ@*(AWE],RIR57P&?2oƐ(~#FLg5=dF#zvL;mf&,mXJ[a # }R:%e-vvS=U:霾es endstream endobj 107 0 obj << /Length 194 /Filter /FlateDecode >> stream x3331V0PaS SsCB.S I$r9yr+p{E=}JJS ]  b<]Bc``D@.0L1S?UB7@`JJ=SP (<9P@=mrC%hAC!@ y`> stream xuб 0  /0 D4?/iLsqINƪ&v)9 O44FQ5o3j ioKk2 DdFLƤ1(C8^QDɰ|p1۽."byҀ)gk׿R?U~ endstream endobj 109 0 obj << /Length 166 /Filter /FlateDecode >> stream x353R0P0bSCSsCB.s I$r9yr+s{E=}JJS ]  b<]d `6`RAI68؀L2`%Hv0)"G'!P5Ⱥ AJ$ `G@%\=Mx endstream endobj 110 0 obj << /Length 106 /Filter /FlateDecode >> stream x3ԳT0P0aKSsCB.#3 I$r9yr+q{E=}JJS ]  b<]acW3v\ endstream endobj 111 0 obj << /Length 244 /Filter /FlateDecode >> stream xu?kP{<0p '% ur(vtـ]G|X#y=8. [~< 8:İ˵W|Ք.1wQ@jH>yo瘣1 ý 8hFx]*18yTB,a PM 2< fep\$I5+zG4VY5D NZ@fW'coQ! endstream endobj 112 0 obj << /Length 243 /Filter /FlateDecode >> stream xUпJ@/.0fMN?Sge!VjihkR\AKT֩$EuwM1f``w%=.>jRWRkRnKO/VSYZR7T@fm큼0 {düۘ=4]L3Ȧa@bli@T|`MLjb4L1dtFW$G *.|ؙtI6Dc endstream endobj 113 0 obj << /Length 239 /Filter /FlateDecode >> stream xڭ08#^@D'D::htGxWm~_LyxJsNgo(I5M7?/&~I#K CԼ*x1F%)dB 񑊅A8EjGU(Nk4, ~j}> stream x3535T0P0bS#SsCB.K I$r9yr+Xr{E=}JJS ]ry( , LS? 0adT Y;PCuP7 .ĵ'W K endstream endobj 115 0 obj << /Length 256 /Filter /FlateDecode >> stream xUϱN0 )K~h{=B @!Z̏F%Psw|J8êt0r^jE>U KWk=?ܻbuyJz_uEk?ƌ!fl#>3Z;@'7x &&ȖNm9R0!G/aEFD+E$ьMX^>a-M=:upǴ-i}GA^{sywָ+=# endstream endobj 116 0 obj << /Length 150 /Filter /FlateDecode >> stream x3Գ4W0P0bSsJ1*2" Fr.'~1PKW4K)YKE!P E?<@0g`A bP>T*L`)`J+F Hʃr Wr endstream endobj 117 0 obj << /Length 307 /Filter /FlateDecode >> stream xu1K0W v8b vtr@?')ΝCMHH^K^Y/PX.8\> stream xm; @ . Vf.1L!he!Vji(X({8Qښ}i<"Ńf{Qj{T3Qes:.{TŘ4 5E&6%/_x/PAP02g0yp&dBw:+0}ATyM6Ӣ5l.5iK|T endstream endobj 119 0 obj << /Length 198 /Filter /FlateDecode >> stream x3134V0P0R5T01V0PH1*21PASKLr.'~PKW4K)YKE!P ETD0S$00|`A; 00* ?8Q"I&PMb`߁q ̍:]'W ckA endstream endobj 120 0 obj << /Length 182 /Filter /FlateDecode >> stream xڍA `'?(   AZDjX.̣y҅Tcu 7f: 5P L % MBb%_/#jƒ&Ύ҄Z{Ue5TƩ-ՇW6j@-OӉ;*`{^[bTd7 wSZ= endstream endobj 121 0 obj << /Length 198 /Filter /FlateDecode >> stream x3134V0P0V5T01Q0PH1*21PASKLr.'~PKW4K)YKE!P ETz !HԱ` |P=iu D)ph<krF=A?0`> stream x]1 @\B/ 8M(+Tr!bI q23;9nvdC)lGUgwIBf6$32d@fr@&m)2ϩ\^sϵ2HQRQO5QJrh MTrL@V@ endstream endobj 123 0 obj << /Length 141 /Filter /FlateDecode >> stream x3236W0P0bcSKCB.# I$r9yr+Yp{E=}JJS ]*c<]70| C`003a`\=&[ endstream endobj 124 0 obj << /Length 237 /Filter /FlateDecode >> stream xڍJ1ƿ00 v^@9Å+T[}> stream x3134V0P0bS CB.C I$r9yr+r{E=}JJS. @-\. ?&iNa`D~700n?D䇁$7 \\\y endstream endobj 126 0 obj << /Length 122 /Filter /FlateDecode >> stream x3230W0P0aCS3CB.C I$r9yr+Zp{E=}JJS ]  b<]0@A@8~? q0\=(CE` endstream endobj 127 0 obj << /Length 196 /Filter /FlateDecode >> stream xڵ1 @Еir3'p.#BBRPQr0E:? d37u.{ʧHrCqJzƁGz$15x2`ts [R?L3؂rkm;x3HKv@%.oԐ nn**ɍ@ÔDr endstream endobj 128 0 obj << /Length 108 /Filter /FlateDecode >> stream x3230W0P0aCS CB.C I$r9yr+Zp{E=}JJS ]  b<]?0! ̃`qzrrƂQ. endstream endobj 129 0 obj << /Length 177 /Filter /FlateDecode >> stream x33R0Pa3scsCB.3 I$r9yr+p{E=}JJS ]  b<]?`@=:773n? Da`N``` O7Nszrr#߈ endstream endobj 130 0 obj << /Length 147 /Filter /FlateDecode >> stream x3134V0P0bcsCB.C I$r9yr+r{E=}JJS. @-\. ?00`D~70n?D䇁$0I.WO@.e% endstream endobj 131 0 obj << /Length 188 /Filter /FlateDecode >> stream xڍ1@E #0e6 &naRK v9GTd)HN^f̦ǚ95(EqߜR{cRkI ? ldM*H&g8^WSQdHVR!J*- i~ nN/ookg$AH> wlzZIK endstream endobj 132 0 obj << /Length 196 /Filter /FlateDecode >> stream xڝα @ HByuj;:9::(>Zp"]qQ |CB?2ܓ1G!#I:Ramd$V$fO"tٓH$R^K6ʯ\UW0/%>T5*4hy~> stream x3635R0PacCcsCB.# I$r9yr+Yp{E=}JJS ]  b<]3P?n3 ~o0ah`?PszrrjF endstream endobj 134 0 obj << /Length 195 /Filter /FlateDecode >> stream x=αJ@Xf x{`TSwZ * W6`"8%Gf|q~K.4pR^j<> stream x363T0P0T5T0P05TH1*22 (Ads≮=\ %E\N \. ц \.   W  @ @,?(fQ 0pC sC3=;?f.WO@.uH endstream endobj 136 0 obj << /Length 153 /Filter /FlateDecode >> stream x3134V0P0R5T01Q06WH1*21 ([@ds<L =\ %E\N @QhX.O `J`pB`왏I@.WO@.1c endstream endobj 137 0 obj << /Length 183 /Filter /FlateDecode >> stream xU̱ P#k[WJ' rjj Ɔh>`Phj @ B\Q#HEldȗ$"Sg3:.{|LVkRj_ ..X ,g0i) <p&A=j|c(vk]b=(ԿOI |F? endstream endobj 138 0 obj << /Length 233 /Filter /FlateDecode >> stream xU=KPs Xxv(zb`A' Q|A7|~Lx`7UN?8g!Aj"z$r~nhdHڙdrO/$GcHN* WUP6Aߴ45q " bx%tq_cGŲh;L t5<fOk2|+ZlECd(IBY_ endstream endobj 139 0 obj << /Length 210 /Filter /FlateDecode >> stream xMν @ )(> stream xUj@Yi nZ$sSEGQ|x I;=F(N8^D!qiIs ǔB3I-1QYAg//74gZv* 0ÿ+]SCE@QsϰF,IqSn/'gCb^mmjg`1'>ڟK endstream endobj 141 0 obj << /Length 121 /Filter /FlateDecode >> stream x3135R0P0bc3SSCB.# I$r9yr+Yp{E=}JJS ]  b<]0001; aX*6T?0'W N endstream endobj 142 0 obj << /Length 228 /Filter /FlateDecode >> stream xmαJ@o"0M^ป'pWSZY `eh>J+5E~;Yct_^iC-/+9u'Zst }{} ,, %s'l"aAZқMY'W Tc| endstream endobj 146 0 obj << /Length 311 /Filter /FlateDecode >> stream xڍԱN0o#O \<'H3D'㤎H GBI%)+,`z aJOJ}o 9ƙ={MyqB<>@<1f#q8&t3x=%T]_'V1 S>8|bGx ~ه_(Jf2Lc# ן8~w[stJptU,r,]#c},=3ֳTc)frLiGvKA;+DE 1]*YB8k ~oL endstream endobj 147 0 obj << /Length 270 /Filter /FlateDecode >> stream xڕJ@'LsL 'BB> stream xڅJ1g"0M!`Dy[ZYZZ(ںy}<•aǙP1|?IO :1H=>cTPc;Ocw!^_[^ʙ;V8?dmgPj\Rq :dĄ* |Vbn;gE d1o( ؁ahDBc!D[o1En %in6N:\Z` æ]H_I<?y뭜 endstream endobj 149 0 obj << /Length 324 /Filter /FlateDecode >> stream xڥ?J@'X&G\@HBL!he!RK E֛L2ɮ9o[,Ƴw565>UU7v1.tqoYKtq ˣ|QђCDF"RcB|&;J e%wpU3B?O|G(^'f ]THد|X9/O8E.> stream x3635Q0Pacc CB.# I$r9yr+Yp{E=}JJS ]  b<]``0f+ɃԂ 0a@\\\٥; endstream endobj 151 0 obj << /Length 107 /Filter /FlateDecode >> stream x3635Q0Pac cCB.#K I$r9yr+Yr{E=}JJS ]  b<]0a\= endstream endobj 152 0 obj << /Length 232 /Filter /FlateDecode >> stream xҽjA W#>WZL+vrp!ET+ -vXqt;';됱j-->xsiNY-gOّy+#CYEI O$Rx%4DJʤn ׮UH@Y$߸Np⧤D@(Ax^ 9Eۄip xviC endstream endobj 153 0 obj << /Length 184 /Filter /FlateDecode >> stream xѱ@ & &]xHLtr0NUy{ጃ zw6d4JBGqlfiG{1+P)QEz@-ibc|!Pi ౮!`{.TV6ߡA_y48+po endstream endobj 154 0 obj << /Length 231 /Filter /FlateDecode >> stream xڵ0kHnЂ0 &2`A3<#02^KL%!_s{I!.qa@CT9 +@P% 7 v+@x0> stream x͒N@ ]uG_.!MBH 02<Gx۹F:.˓"J:lN錞c|,5<WO(m(KѭEGWbtK=b$(#!@5@oJ 4{aŌfJ`o}4.lO%wm_mte4](z`_TU` endstream endobj 156 0 obj << /Length 259 /Filter /FlateDecode >> stream x]1N@4;ۊB$\ Q%ڬ\vY)yTk.拊57 UIJ/Kn6O\k*ybx[~|nXp8HDF#々~7'QȔ^;LKZ+45qj@.dtv!"ieh֔j]dV絳Su ?hgcfKxhGZ endstream endobj 157 0 obj << /Length 186 /Filter /FlateDecode >> stream x3534S0P0R5T01Q07SH1*21 (Cds<L =\ %E\N @QhX.OON2bH$;&=A$3?8HAN7PJ`$H `( E` qzrr:p endstream endobj 158 0 obj << /Length 187 /Filter /FlateDecode >> stream x1 @   fl1[ZYZZ(Zkyt {O!(VhpZ0(j. 匴F91J3FNPf4W.dI K#ZX+ސ8 w6 .n N<sUv848n endstream endobj 159 0 obj << /Length 252 /Filter /FlateDecode >> stream xڅбJ@YR#d^@7l 'BB+RgvE8X>Y؟/Η%YJyN^RaaB> stream x3337W0P04  )\\&f  ,ɥ`bƥU()*Mw pV0wQ6T0tQ```c;0D0I~0Y"I ?&D(I"\=VI endstream endobj 164 0 obj << /Length 99 /Filter /FlateDecode >> stream x3532Q0P02F )\\@$2ɹ\N\@.}0PRTʥ(Dry(3773pzrr{ endstream endobj 165 0 obj << /Length 174 /Filter /FlateDecode >> stream x3532Q0P0SеP01U0TH1*2 (Cds<-=\ %E\N \. ц \. @`"j@&~ f0H@L`F؃ ! D4$f6a&I#$l0L  *@'W OF endstream endobj 166 0 obj << /Length 108 /Filter /FlateDecode >> stream x3532Q0P02F & )\\  ,ɥ`hȥU()*Mw pV(Dry(3773r - endstream endobj 167 0 obj << /Length 103 /Filter /FlateDecode >> stream x3532Q0PP0T01V02UH1*2 (A$s<M≠=}JJS ]  b<]` .WO@.E, endstream endobj 168 0 obj << /Length 225 /Filter /FlateDecode >> stream x}1n0 Ed0EG0/ ԡȔdР7 dPK#O'O *k!XnKVz>uөg^3e݋}N7Oo#XnkR 0,H"`nX,2d;F)ԃ"G ٦)eC$9َ}r9H>Gime2bֿɯꢻNǀf endstream endobj 169 0 obj << /Length 223 /Filter /FlateDecode >> stream xڭ=0 S1T#4T HbF(=BN1#2|QlSL``: Ҍ f}a^cstz=^NЀ`|U|+Q܏JfL5IbG|86*Um%1x(VDFN{ܙmw^{Ǜ)5xu Vϗr endstream endobj 170 0 obj << /Length 208 /Filter /FlateDecode >> stream xڕ;n14s5,r%[D ")S$"r4Gp`(RF}?i7> stream xڥ1N@Y478n- T)UL(ԛ,IdUq n#t-l#k&ĖH endstream endobj 172 0 obj << /Length 225 /Filter /FlateDecode >> stream xu1N0E49BM,)@T@"萒(9K. #3?pW=w<~(ё6[;ϝFOْSxϟ_dw7qB#h%^J"s-,&ï& M ugTi: d)ȧֿHee_3 Y}ETԼ4rs$jYh%t;#k} endstream endobj 173 0 obj << /Length 166 /Filter /FlateDecode >> stream xŎ1 @EH!%q1[ZYPUx!㎝Vd7<[W-SÉ@fޒYFLXr;)svdJ9{ %_@"-0*rࡐZ'pGb4"mz!IoMSK?7W endstream endobj 174 0 obj << /Length 283 /Filter /FlateDecode >> stream x}J@Hfa4]<Vr YlWX `D9-4oɿ3eP=յj隣{^u\\:ݙ{z|bu~*.r冻D6 !#"%I\(3}Cc{mPD߄%:N4@&qTDMK2v ;Q9(nhK Idvd="Т>y &ɹf{[ӎ N4:58x'_'/t endstream endobj 175 0 obj << /Length 178 /Filter /FlateDecode >> stream x= @ L2'pH-,J--ףy2ŒmkO1rX54])/ UԎ URvL,=&dk6>s]PFX`* tB &66aQְsdmN|*38w ]ZZ錀 endstream endobj 176 0 obj << /Length 141 /Filter /FlateDecode >> stream x3532Q0PbS3#CB.c3 I$r9yr+q{E=}JJS ]  b<]0000PX?Po?=``D xr "cn endstream endobj 177 0 obj << /Length 127 /Filter /FlateDecode >> stream x3532Q0P0b33CCB.cK I$r9yr+[r{E=}JJS|hCX.Oc`'\{0 ?0%\=Rm endstream endobj 178 0 obj << /Length 175 /Filter /FlateDecode >> stream x1@O75pD ,ZZh:JD<@J ˆbb%3򎃮i0f3c3n[6DM8eŠ8NDRrpEEVn4TKUT|(UBMҸHȿ(? endstream endobj 179 0 obj << /Length 170 /Filter /FlateDecode >> stream x1 P t*d |BB`A'qRGE> stream xڕ=@ #0e't$$RheaB5pJ 6&Wd^狔cy9ƹjzPRei.;-+RGN R[&U|H-+֤|Z3/PDx"_  {MءlQ5򃠳RkD0qM]Is Fk,Uel m*:9n endstream endobj 181 0 obj << /Length 235 /Filter /FlateDecode >> stream xڵ1N0EEirqd":K" * D ra8 j$\<̟|Ҷ9~JSJ/q]Ngr |y@T2bH!iY)0DI~B& #;NvWV #tb9w?1&쵹+'KUwι9mkQڎHQ*mAi7t-} endstream endobj 182 0 obj << /Length 172 /Filter /FlateDecode >> stream xڽα 0@εIG882:Ht>85g<G5oHYc\lːIN͌Od>"YJq&S"EE\-u׋p*X&.EZ7-}K7-^D_~417yi endstream endobj 183 0 obj << /Length 227 /Filter /FlateDecode >> stream xM=N0j K.Yo?)@[%h(pGH"1&+Ai4絻RF.x/~-O_yUì o[^fv'^TGnBe*TRUCQf4.,B"tF) F#a~̇ Lͥ2~"1e`9Cf1YD5- VM4kcЇA-ʭ endstream endobj 184 0 obj << /Length 177 /Filter /FlateDecode >> stream xڭб 0+ 4%q- ftr'>#t =/u AIn(ƚ!kxB%N_C!Q-$Ft9_Ռ$h+3;tA|y=8ނM?`|ҋ-xI ,vQOzxE:Vv܄#Jsk|jVmx endstream endobj 188 0 obj << /Length 208 /Filter /FlateDecode >> stream xڥ1 @EX t$ L!he!Vj)(rM\ ~}>wU>$]HYDQLbJX xɷH"ZMYVx@h egR4ah#Kju4ӒJ&YHrb`.j\+hcc%*t!AfM* endstream endobj 189 0 obj << /Length 207 /Filter /FlateDecode >> stream xڥ1 @EXS 8ͮ(VbB9ZRZX&^x hec5a㣤 jtLaLbJXV oD$N8x 0lX@/C7蔻B f 4VVkφcx}A#/k TZ;ƺԷt%E" }bS[. endstream endobj 190 0 obj << /Length 136 /Filter /FlateDecode >> stream x323P0PP5T02P04PH1*24(YBs< =\ %E\N @QhX.O9   fv6> $'W  ' endstream endobj 191 0 obj << /Length 95 /Filter /FlateDecode >> stream x323P0PaCKCCB. \.'O.p KLz*r;8+r(D*ry(177? 'W  endstream endobj 192 0 obj << /Length 94 /Filter /FlateDecode >> stream x363U0P0T0P0"CB.#3D"9ɓK?\ȌKCHx*r;8+r(D*ry(6#' endstream endobj 193 0 obj << /Length 257 /Filter /FlateDecode >> stream xuбj0d=A-pHRB;u(@19G#d`d |' 󟖋;}O5\RQ`ȻO}c~[zIc%a,D!Q$mbG2bWh*^jL/.i AjS]3}`qd;<z<ĠuH> stream xڥѽ 0ةP+AAAѹ}> stream xڽJ@ƿ%``  h`xp` A+@--|tv)-­WXZdow*;9-8㒏 >+1*R̸*gZ֔Sz-eJ~{}ty{9+Sb 頁Ș2ԠFJ -_5J5f҂Fvh4P"VeF T߄iӹ{ =#0s@7IMlVMts~!|.G9#٘0\f {qo@W5/XI endstream endobj 196 0 obj << /Length 296 /Filter /FlateDecode >> stream xŒj0OxܢGн@kg!M ԡm-@^[^[WI qUutqE+ z+̟00=}c~ =T`!gA@jT, 8_=eCAMF^ |:I *@=N` ڝ 垻ḱ69&>0s!of &jɤbu gϫC0IF)Zm* endstream endobj 197 0 obj << /Length 130 /Filter /FlateDecode >> stream x373T0P0b3K3 CB.31s<L=\ %E\N \. ц \. ? Ph707000c~4ȫ_4,q.WO@. endstream endobj 198 0 obj << /Length 112 /Filter /FlateDecode >> stream x3634W0P0a#3 CB.# I$r9yr+Yp{E=}JJS ]  b<]A~y) \=i endstream endobj 199 0 obj << /Length 258 /Filter /FlateDecode >> stream x}J1 ] {-(tdibVp> stream x3336Q0Pa3C3 CB.S3 I$r9yr+q{E=}JJS ]  b<]dEL0 JP 0QR(ڡfZ D}L1Nqzrr) endstream endobj 201 0 obj << /Length 252 /Filter /FlateDecode >> stream xڥҽj0p [hd`e3$)C 2@!!G3U?& w0 ,N=j7>FTҿUx4F=E_%\ᵀ=/ɸh endstream endobj 202 0 obj << /Length 289 /Filter /FlateDecode >> stream xe;N@rai=`;qѰR.@T@I.J|7a҈$Ci>˳؝I}^M iI/y78K6'of֘)nb-}~|bvwE)XQd9!a"[d72EW:,wX=0;rؙnW-WzUR,k9M<Iz:HxDLՐc|c=1;2؉^]Aĺ7_lo'kH;tۀ_"=\lhsoW endstream endobj 203 0 obj << /Length 333 /Filter /FlateDecode >> stream xڍAK0 ^{6LSaNAODGaRAaԉ.x ?dJg9*9g9Цӯ'9+ezӉL/h[%=tvuLx0ȶ `ka5@!F֠%~ CnɱCȅsZnpIm1u2c!/Wܣ[P `Q P{&{6Gq.L!qvNCQ&yи7> stream xuϱJAba yh+RPK E;1 tƽpS|?;?xžjs3TC=-r+SrgkkrKyrM͒a{ծlB-`a:`u)xuwGW2&e˯ɦnh huaǨk} [ bԪob"EzONoɌla endstream endobj 205 0 obj << /Length 203 /Filter /FlateDecode >> stream xڝ 0OKдv vtrAPGAEA0G#8:ANȹ-Lp;"dJ Z_V[UglJ#IWc>NҽIs-0pu@܀_x vZհu/{#ҡ^EA^UzN4 E A2;Wa V4'VhLr endstream endobj 206 0 obj << /Length 212 /Filter /FlateDecode >> stream xڽϱ0$7 x/$N$ &:9'utf,ƣ Fp $K8q b~bNe/DF4AFGi[?2%72byg6Nh:]hBQ֩L)϶?$nId[XmFiǞzՊuA63` ^j endstream endobj 207 0 obj << /Length 210 /Filter /FlateDecode >> stream xu1j0g<7 41'z(S$ MHXGQ|JW\(T 7uN3uki1}.Gq%Cf&u#U])Yϧz\R׹fi WOp_PI! I@*#f%#~,K{ǏT#,ΰq`(nYsLޖF^V2 endstream endobj 208 0 obj << /Length 156 /Filter /FlateDecode >> stream x33T0P0bc3sCB.cc I$r9yr+s{E=}JJS ]  b<]000```!$T ?h A30c T" h2FG&\=ak# endstream endobj 209 0 obj << /Length 275 /Filter /FlateDecode >> stream xڝN0?+C$/~ @pKV*E"L02`ȣD`7я$7d*:}$ X endstream endobj 210 0 obj << /Length 167 /Filter /FlateDecode >> stream xα @ ;:'zx: 7:9: *:{G;s]!3pck8YǸh PsNA^/r9E l BuL[VeTɎdÞ@`_wV| 䈚 oafaosK endstream endobj 211 0 obj << /Length 125 /Filter /FlateDecode >> stream x323P0P0b#S3sCB.#C I$r9yr+r{E=}JJS. @-\. ? :  .WO@.P endstream endobj 212 0 obj << /Length 220 /Filter /FlateDecode >> stream x1@`CW ,I0Q ne!V*Z'7J+)Shfe=1fOA2∇n'MxӞ#슓U|<)dg9P1csK^4Ї g Z7-Vj]p azկTP)*ܨF7́ ,a 0@ A/vP`iCiyA_ endstream endobj 213 0 obj << /Length 110 /Filter /FlateDecode >> stream x323P0P0b#S3KCB.#C I$r9yr+r{E=}JJS. @-\. ? C 1cqzrrp^ endstream endobj 214 0 obj << /Length 203 /Filter /FlateDecode >> stream x=@H\@ȜM B0X({+ba8垫|>2Pԏ~?Ѥ$|@jRRod5Ԍ;*gX@l$u8lSyEȞn!X#xiTCƩFHjODO'0vBJ#n $"&ݏ endstream endobj 215 0 obj << /Length 159 /Filter /FlateDecode >> stream x3534W0P0bSCCB. HrW01r{*r;8+r(D*ry(0a@R` `$@z ɀ a/ m?C&\=?qjS endstream endobj 216 0 obj << /Length 209 /Filter /FlateDecode >> stream xڝ= @GR2MtbSZYZZ(ډr2EH|((v̛ݝGa_ endstream endobj 217 0 obj << /Length 218 /Filter /FlateDecode >> stream xڭн0 p[*y#4"t7p  }4бCHpH'n[~8{`zz9> stream x36׳4R0P0a3CB.c HrW06r{*r;8+r(D*ry(0`?l(g?6g u@lC{ pP endstream endobj 219 0 obj << /Length 213 /Filter /FlateDecode >> stream xMͱN@б\DTd""R.HE) h!kfg:[\ꗺXS)Ks"Z;׌oY2=7Ro0ͬ&a8YZi4 %:1X[z83L̺E[y!8}?+O2dWtm8 \\ղuY endstream endobj 220 0 obj << /Length 160 /Filter /FlateDecode >> stream x36׳4R0P0R5T06V03TH1*26PA3#Lr.'~PKW4K)YKE!P Ea9$luPفX$N#Ccagc{  00?r Jm endstream endobj 221 0 obj << /Length 162 /Filter /FlateDecode >> stream x1 @ᷤL fqC@Vb--+'Gˑ<@Ⱥ!X l3pjZ>DŽm:L#c^[z?.6 6KNJV- -reByDz 7U}`(D,uxI0nҷWR hhKob endstream endobj 222 0 obj << /Length 236 /Filter /FlateDecode >> stream xMJ0?0> stream xeпJ@o \`^By]  @-G̣R^w]9 Opj8>xPS5ZOLIppu%?^^qDzŷ;JW\ׅˡ~ lr&Vg{'´N2;s8Gvn=ЪQob]pл ~^8:g007~ʞJT Ͼ4sM^!yJ[X' endstream endobj 224 0 obj << /Length 207 /Filter /FlateDecode >> stream xڽ P FҡмVn?`A'qRGE7f}>BŚނ*3$|9VuQۀ}+5͞1%kTڤ|18Ux*%V738 \A&rOP deyܿ>X ?c\%#'q(IfNĴ) endstream endobj 225 0 obj << /Length 131 /Filter /FlateDecode >> stream x337U0PbC33CB.c# I$r9yr+q{E=}JJS ]  b<] >00013 A9 CaՓ+ t^@ endstream endobj 226 0 obj << /Length 259 /Filter /FlateDecode >> stream x]J@Of!"." E0pA.Z v |˝gH0??pNNmnҮwYUϹ勧7wk"nssa q[{_AꭅBaD4%;>#p{%*édlW]HO˷df 3ÂױtK҇FoMfl=o,"E"pLΉ~WhFF*4& !3DWZnvj endstream endobj 227 0 obj << /Length 206 /Filter /FlateDecode >> stream xڥj@@CkB  A GAẸMb/hffӱZ'd?$u{<l(潽x3\h*fTK> stream x333T0P0b#K CB.c I$r9yr+p{E=}JJS ]ry(hC FC ybՓ+ endstream endobj 232 0 obj << /Length 316 /Filter /FlateDecode >> stream xڍԱJ0 4O`[,'A&qRGnV|mp\p9䗖J~qr5KBMKuy;}ts/g. eV;.N\]i_zY37RcUup]Q/-%u;>j{PkP%G*K0IX S]' aa $W&>a"a I0QGdl LL M 254Aaڷ#*bDM6~,> stream xڕѽN0> stream xڵJ@%4y˼nn p` A+ J--PB\_SE;%_tB=ܵlkouLn}{ ?T\n0`Bh§"( v3,rV (R0(Z1̾?^3A RW^SML j3)0}1F3f liX6e*yX i}lM󣫖 S-zY endstream endobj 235 0 obj << /Length 290 /Filter /FlateDecode >> stream xѽJ@YRyM̝p` A+ P,& Aȸϐ%GǔRFtRN2ڹ{{\$\1/)n4 ܵ0C v-0ypiVp-PL"(JvWU+ov-cDgU7({_`7'4 lÅmsH/@םb'۸^UbUVlA1J1vހg9^[9^ endstream endobj 236 0 obj << /Length 267 /Filter /FlateDecode >> stream xڝJ1'lq0޼fpVb]hy}-86L /;q5%QwFO-kHfr;r +ZoyaC 2i寙5z>%k<&r,`vd+q3ߒ1^+ \oxE<@G*q/|Aoٸ=,8U(`ش fA-pڟڤPj"{mI倷YR endstream endobj 237 0 obj << /Length 351 /Filter /FlateDecode >> stream xڭJ0ǧȥº=z =umr!4LRuDg^W4;(M}h-ԣKCQ\jժԥ*NѮ̼<ޫbu~lX)U6_GzahB t ]2G6Da)hrcfEA1-?pλճ I}҈6ĥPgOn ܘ'+tc036u! 蒡AM"9%} |H=X9ZHv]ϽmE=LQVgq)ϜRT7D]n cƒ|M'b<%NZu>v endstream endobj 238 0 obj << /Length 219 /Filter /FlateDecode >> stream x37ѳT0P0bsCCCB.33JrW03 s{*r;8+r(D*ry(00`P"0C=~d3@@C P?P 8xq83qe0w`0H+p32> f qՓ+ P endstream endobj 239 0 obj << /Length 142 /Filter /FlateDecode >> stream x3631R0P0bcCKSCB.#1s<L=\ %E\N \. ц \.  30oAr 5 T @;af f!`` ȘՓ+ > stream x=J@ )2'p2Dl +BB\K E;qy^a2E33EdȼҥOumYꭥA +]Ȝc2͹~z|#8іF_[]PI%ae,*=c<<6F< ӉY+ _ ^Lubފq,?vMectJAqO8:G}- ȘKH~cD='0t[g7׏iC endstream endobj 241 0 obj << /Length 123 /Filter /FlateDecode >> stream x3631R0P0bc#CCB.#3JrW02 s{*r;8+r(D*ry(070o`G1 d endstream endobj 242 0 obj << /Length 252 /Filter /FlateDecode >> stream xұJ1;|Iej`]),APKAEn"v[ |]\k܄[vGXN n2rב)MZ/W4mɟ˟1cɷ'E37.\P;s0 ]*\T3&03vrHM%.,^{aK u`m)4`BO5䀳"mDV_—B.fY/ë/AG-!A B endstream endobj 243 0 obj << /Length 207 /Filter /FlateDecode >> stream xѡ0[*#pO@@ %0&H@! $h%#L"uDKzz٢"\1CtAݓSi֫u{СuB U|0ۀؖB%/Q@Px_Qv؁ʲ#rO ^7\gpx'A~^ɼP/nC|U endstream endobj 244 0 obj << /Length 249 /Filter /FlateDecode >> stream xڭN@ }K!~5*1#ܣQ3T9l Iɾ5TUEš^+:pP3/F *-=UT>cKxii$@v#W@!'=r48 E\)GC B1:6b:wZK??"Xi=1wfbpY4?]e[t~x# endstream endobj 245 0 obj << /Length 288 /Filter /FlateDecode >> stream xѱN0Ы2DHmNJȀS22`%4*1Cg[!uBbbt:Ftr6IF9s|bli%cLl^_0\tSv PiYY0٣-$Fi nQC$lrڢWF$\Ea}!~"bǠ?qQu{3}>t^ uCaΟ jeG)AmJIeŐ[W.翢j؄7,?ne endstream endobj 246 0 obj << /Length 281 /Filter /FlateDecode >> stream xu1N0G\o$"-D $(PR[mr⛐#Lvq v '33n"O'5sj<=x/5j֝){S^˵)x|1jSn衦t8z[d yDbDΰt=ZbM΢yqPje^5X*>YY:#BIj!MlG-ƨH]$?r>Pc6A٠~I"vfD7(0l@/]3wׄ endstream endobj 247 0 obj << /Length 191 /Filter /FlateDecode >> stream x3531T0P0R5T01UPH1*21 (XXBds<L=\ %E\N \. @b<] @>dF"ّH~$RLڃz0D2I@D1aL``n@'03H~`c1(l@A(8\=~@ endstream endobj 248 0 obj << /Length 203 /Filter /FlateDecode >> stream xҿAr $7/eQII\!R Q,'s0eQ"ܟ3?(%V U Вn(6Y4n+|א<>ȭh\ E&tj8 endstream endobj 249 0 obj << /Length 268 /Filter /FlateDecode >> stream x}1K1Wn(ž/TZI* nw֯q@2P.R0:K2ONFQ]9IKTc$kmlv2JP;L5o<-Dw0ġ ;#39~cF<cpGh> stream xڍwT[. Ui"tBޤ $$;JMt J*HQ@zG;]w3g<:\p55Uy gf6! H_y$)7@M8 |@@8R r4jp,Gx"}^Xl^QQaY  fG0C!h`p@b<< 7i/ pz*r)`EeЇۡAHF C`0[p;@_Uk9/7 . A!m% nQ NPn*S "(nW<"VQS"!s\'d*)u} QUQ@a~A;mGnʀB 7/|o @#B|>// Fl P?o#3 x_V7 Ü=n1ǟc{\|@/P@ |wOWf +ߛ;g?$`3!lӂP`@A ]o4H驳o;_r:{AP)f 47o1ՄBU Y x(%V;E Q_W̍_);\#nenFdP;Enk $I{3pM;;8WDZ;UFyw/rݶImdlؒOjV,&v;X'E~:#A̒˥"s"mg{QFiP_B=;G/ rjK^|g~f:dE"m.(9k5dܘL$ա@hV4߄ Zix[B#o/69iת(X ibOz˳^u^.KG>UK.B VIG ٯ6#c(["+f1cm1Jr(>[1J϶.0Z:/RFByRS?ZR\dz }my-+$K!ЧÚ+2|fXmĿn]Y~cH 3_Rݤ%t>iM,e_lTղcz$%CEٞeȅ?_@xim5Ќ "Y$&=:&uq} _?pY!oY̌@c^_9 & =xYdd6Qsx6a@^A)A137G`쳓^DWz9-wK\{lVycTϚԉYB!&$7$v/19593[0Y.su>pi <=M5@FMˍx>4mcv' -~,ų):/}m=%10 H>^D:;J Mw}sk&yA-{E3ҵDPzc&IH%2Qu|IږKA-/ ZBcxr˫^ɻVC/3ly;PHEFޱtW(ڕAmMG,eqP~qښfY:9}!!c:xc @Å|Dg#S-ȿ?KP eV#M75HK x+ CAKGג;tioy[=~dS⫊iLum7ҷd+J\L6Y뽜tl⵽w7 V*pNjge3GtK_}%2dGج?l(F]ƞIQ 1"XT!5\S8w_R%xHa~ ^k S'6LO)ǝjktwhĶ53L>Xh9F<3 ==۳~! @EWsV%Ku!L}(7(xa%D6/{"#75ĭ&25$w~ps]';W3$L.,@f>'4 \IOge[7 X;:\dF)c Ecg1 'E߫V@Q3{\'Vt4 2xdq9*i?3݀S(gb$Y5?a0׺fVV5o}{! 5K3rR7+j&~bK y띻ؤEb`nQYe=I+G_ w zh(|lMlxv٭UDI#ӮcO59p[3=9)y"j zƍǭƢW4{ŅU~zPIJ{Lr<Ě(YiGx -PI>- )rY7vj.HZ4g$;.Qt*}IX).'e\ "#7[Ac2 {)"5u-m8J%H|Ib(~r]O9ϻ|w;d{Wx0`<}}eX~&DceAnm)a:NsU' XѳމဖC+ Jdz/o vQ-Y!y*wvOxVo񼡐e4rU4m×>ﹽSa'qS9?6N=iB0X~1)+ĸ`-<^Yi7!?tfc#DN^Pl.1딅 g{xG#I?yJXz *FPy1]#/b:#Q!oí>&\9E6*+:K -VX'e-ˈF=Lh$ R,yW=fwl(ʥ8Bc`u]p-_bTwuWVbO>#ƟÁkq2U-;|BV:r\x/}]37~k.yQ6S&rT+fJRx{=xe)Q6@"L{}dUu;،enQMW$1ҩ9gtck%(6^qʐ5u5`rҕ+ デM.4/<,n&E~ y෢7HD˽}mjI{ݼ9^wc,Z~7U"xB򯄕7~w*')txg%S{PY <H]Qn[c+bF JCa:Ҩԕ0n,x;@떻¤y,eJ:KzّA@ qhGZy;ċ8mN[]T%{ --_m|sT n]mvUOă^z68-b|GД} h i55zͺ5?y=gg:C! u<8i|+#kS[t'dG -,YP̬!F>T.D$_uCɧ)[ ⵎ]g S|(rs:P儏ZHRйe rKQs=Lg V>4-Mz"t(7'eL]$:~ sҊk4,Hs&><&<6/]1sWDz "=XvH٩F˱?( ˎjE QRtvBQͽ?+{BLJY)zQk!фMcg>~#Op{ڡn f\Bp9i'P6EO\ݕuΧ NqdeCՎlfko~s90#%n0&l8qs\A~mr_Q7Ci 6˂7_7?KhL7`ZWZtQf(5 >yMW4BFk`Jf6=ۂUb$4^vfGMaK7v4ї"nKQmPYAʗK8%=ߕbyѱRH7QnzYD:D:۪8Z Sw\D}HTUtBA P-ZOVeSc<88!pjCA va]J^7s [YANUWOQ^%Lզ^a.6(OrecWC<ﵳ**ZlPLˢo*_gsTÁ'~_=-"./_Qh&#puoEma8խ\Zq1SvRw>\` uIrHH03i4ΨC +9t E^lߔleg 0.{(ut9MjEriXcmV)$}4 i7йq#J¨w4%; %ΙSg^pٲZr,bg ,_pz Ni4sK& 1]!6q~m`mJ;+&{uerm`ÀIWqTǸcvzmkŤmoPamB=1cȮִ8}iATtD "s m}-1oo-Jϳ0OãSץ"zR^ ~aXqJ+aP1PΫ)4-&˦j9 F 6VoqJፖ| wh]iQ|ZW'x2]ކ ֋; IA Up:\AevkzJ%DW7v 0+6{q?ԻH4=\::eS m<4Z=SУڼ#tyj),j3c*l;J2ڼvmvȶtfYx9'X`Q_$C(f6; M˾^F+3igba> a-JVvZnt٨I9e \ұWTTn'w'1 OV(L] 8]1~SЂ!w*r+NNXY:/\+O>=*uN4?4*%J%&0_Ț$*MI/*}Rpk#լm46SA7N|ί%MM }ZJi&˫ݔo}I1{>s K ;T[`0p˵Չx|E}pcȓ.E;Jil9XKsu*շEF?_ϬWif-l36$RI5\<'G ÆM:(5=m^El+<Oe[o! LjroVG$}#yɩiȫsbեK램[t|]bY`OC)¶]K*#` ASH̦zI޻ ofp,`]t1gq~%QHV\Tkv(Ґb 0GP%CKI-Ii|rRdб2UaXc\A3OwP~^L`IH9p0'~N}Hn#uρ-}V4aq:W˜td8?V;]O,g[w3nKN-*3ȀѼ}l]hۧ#Дnd"&lŢNw>:q$r1JO)~WN$-ֺf1AJi*_+q2wH&rϨ7\{B5.G]{'ZiDۚW;Ɔ;.ҙ4/j ]mJ endstream endobj 255 0 obj << /Length1 1418 /Length2 6406 /Length3 0 /Length 7380 /Filter /FlateDecode >> stream xڍtT6)")!C 3tItR03 4H*!%]R!C(R"7{{k}ߚytyl0e$ I45UE $@QN`"DHG `&Ny8XT@ DI!p&@ .>np;{8(t3  =s"GB0?JpH٣P.^^^|gw>4' an0Zg؟{\i !1s8@_UC n`>;"] 8` w5P(a+C/#ycS-e?'/ , b^YE ߩ[$ -ձ_KBbX pMr30yTc*!e'n q;! #M$F5&^U#9̼`!> QP?A}[0Y 0:b^qA1bC^/?PB@6t' ,A|0X?0F60!(L 3sFk~x!$ )wm`|t/a0ohf q i9]M=1ɷ D([.&gf̪*t-ڵ]OLe:eTfh?u}=y+8YD[C7elz5]$/6beQUTFKz&>U#%g1f)ZեN*|'fR ^c C)I+ T\dyng\^8gRqjz^`x5<Χ[rCjDH]2t>~[}4vx=@t%BpO6vJ ҩ`D@ 8zusP @%PC/v6.ێ ͋ǥO>WDm=2 ࢉpT~Qa:!na_\\?SӾm^5y07 J=tݖ~f:sIQ~@:U3c7W*J"6J߻O~9ؙosk.*k  *n$χ| nKҨaçY qxOɷQF| O۔R IIekcAF6P殦'^puؐoCmޔ=[Slt`޼C˶U+#?8oPp ؗѡxeh3N|٥?J'lv7p=B$tPfM,ܧZj2!= y~}W?ʇӧEA;w)C(^_nu lg?\N}9+QB,ÿYRjAvK J0g~SC鐚3۲d«U)2Z-ZYBDFG&⺞86W K2͙sQP(K~ ,siMl-q5NpkM3j(-,sܠ̳,.Na$-+,]T[G=F\TO/#4lF٪lVNέtiOZeQHpS3~AeSԋn XVzaHcFV[TgnC.+mn̝ ), h`ݧ$#Utd5oTm;b3[p<,tlVoұRs-fkқI&S{:G..͞W,Mˢ(J?mJ p8Mg r/G;ՌWUnD1gnLJpAAHgE|4 NOСera!9dHSeK=֍L{T.:Ia)2HKrl%5ZEPW-+4Yfs 6JX5x-ŋJ63pRLx"YiZo+ tV (ZuڅdU6g,u}{"(6I!ɲ;TS]돂AW6Vj1K&*P| gæ6@^/ޥUcNΒDRf~4v&cH5.-G͇c])dIժ>T7uj{X|*]!Wԫ)8BP)h;Iߓy0PphBH,RPQ!9yjOYnOkj-G4‚59#Xƕ\8.sv_(] 24m kJ򟓳hFPb #& v@L?y6FC{Ա䃖 U%+- vf $&$H%gbQS?[EPr?Y}mp䒱з~ЈHTݕ#X]Ok,iI>Iͮf>=8ҫ$=q_aɷWkMB΂xX)W볰~®گϬ+SGi2?% Z|Ep_Ŕ5H8gOIKQsx:V sHg>C8Q }VhRwy?X] vh[2N.îL8ߎs TsE:/p$h5N0&~_v_&f6ah]A7;%jkD *6sdHuFxqS@cKj%8SzF Gx{7Kx_\░>$a'XkES9'm^yXI^A<-9+ֶl y!}9~WΖɜ=FzU4T> q-3T]UKl5AtdOv`ߞX^:knvS${:ߊ~+vM&M3OG L gVV#}ٚmJ`ZZ%tb=aku(xױq0.c|ҹ; uQcAi T$) g3}1mMلwt+>d ~垲!gQAONd|Ifm/Yq );T!Sbx9eN+\t>)tߤ]0cn7>A8S Z;cʒR݋;۱դپ2Gߤч:w PX1hY0~bC=aMȩsLw"Gm7^A[ϩ n[ڿ_x2PޯPW8 9ZwSRoVyF Ђo)*&bnÁ"`.%jdܼpǐ s67xݍk6ƣ?\m 2-)N~Lo /z[Ƭ+,M+wN؊ciwWxfU Vzu(XG[~ b\5z<'+@޲ 2/S:=C x7&49Pb6u͟5fNqqʃQ,+[w^)8u f& {FKiBW-zw<~pRn޸6wL>#HwPm|miNErԿ;H&Mpޛ4o)hK~l 6Nݧfx;IIya>G1vZ 4x4,meGS$-9 H=g+ڼp6pT+f*&MOD~׳ǣ+> ٳ%ќޮ +Aݗ[Q呯QI-wQ!AISw8%3r3>a!2!3q=#2k5qakQ(a7,Sx-nxN0Mӌ}cux挸J)8ZfOV=z'žkJgp/LgMՒ/I/ƾI);O;w L][BVwb;k)l'-C;&=╬ %o:iϤJ=jgvm3?|l&Imqo텂oⓏK7h&N v6?9/NN Գ=u9jPs}/Ww2,r׾*/7:<\z~lY x*$XǨQ%1=LSe){ٓ0D\'RKuzcvS5}7;Ρ!f|stK&,4SN*&dpíҺuAiTl[TB-U(cN+n RjD?Uv-IuƧrcErgz{VMۗ*bu%(nM}oP^ZR!~pq 1yZpkfv*L}5;evO{@w^3J22'ub~q\CLk2 )R^тy:J"j>o(hy*$8'9 i{ ߸m$Soa5ߠ]$W*} bsީ/ڣivj0Gqn&&yS@kC K-Yf|I٘Z@$z-;*9ZC+:ƈ ~LH  QF%"mC|cnCN+]}Nůnry0hٟ\ER|)Еv=#+Ak]c}h|Н!c,^ 滗`|y|aG^*.I}̚)S*9$IKp?ÓBD+|&EP%M[=Sa0Ԣ9wFIo`\,G?u\ʭyU,ckۮ(Ă#xXV DXxI+8fvo4!~KYF@ܗ_dXX-)IzL/xUv'j8օ>* י3H&pU俹.=^+#4բc*pt)3ȱϒ@qy]$?ErOFP=w;<%#j2_觰shSCkl)çeN x9Jwj;]fB1MTuqx˫bTWќ&뉬W/ 3);^3c +\SR=hݘœy*Mhtm[^H:~rz`mDΝ$"ͶvȁM{++=F{{bSSE_aQ5Ms<],}}Ԉg z 3k.wx+Lj,@ [;7Jy0-_S,$v4ME{ *Wnٯt>"gӱCx>N睩bBXJ/+JJ&plwx b4b镬2{&-~b%865gʐeed ua~&rqGve-=W,cMk)Q5rtB<PR{Ϊ 8ףn56&utʴ&M') 9׹UƮd8E&L.),<3; m0OwU#Ĕ`Ѷ%itLn+`R!| PSVB&Mjiq_]B߳<5oŶ;ҧULk8?Q XL|i(j~iֿ_JL|>0\>5B FyT\CU߉5 i],{/+3xh͋67tk_J:qe[4ˑՑ]vv!M)|@TIr ڨa+}>+Vy~rb,aܱ3"G~-t gGV@DdžԂO5T&J󃂊p/Hޏ6̛qԏZc{k) д|GcAX>D]ZD}e[l&W= ȹgn2ӮW> stream xڍt4]6Q"DD&j[E1!H I {' QIy}_֬u9׾>{}Ƭg+ (^$$ BQ0"APDB( Fax8 @BHT$&)  HMD %%4p!" urFa{ ps 1_+ m09  P!8Q(7I~~ooo>$xCQq~ ]!+#d q#=0pknoon_x r#\p_( p ?`Ca`; W`@E^c S=~3 斕WWA3?%(bv_ߝ}GxlpǟE8xu? Do D$;w  c*wC" PGPHOH#= 8A!#>F{ @_++po*>?+("~L g=0OwD\{KQ--D1Y\ ' 2s?f+' 3j=[Q` Ý`F E;VopYx1/fb$ p{H$ؗdNafK?¸GgG%~{(abl`QqĴoDPw#1 K{! GH$fPS_'GKT7]?¶j \GO{n.+sM3]o5\lLopn`hpr@Nrkơqk{'?Py݉}Pn+o>C_R;[,S*eJZZ$ھ:QmTqQSH>v oFmhBXDđQY5&t;J'Xx_x覩\{q<~k]<徖/xKeɛEE$%Ak@U(B_ѐm,F@iAڕtӦnMd||nBfAmW=4b[TD6xOI N԰IDMFXxt5TyH/5e=#nec㚰Eͱzcוch5Ns^{.P[א9=,B4qR 4f5pQR4WP~K;y+Zq Qu=VV؏ͳw-ZF!}=1']4lN)v~4i< 헂~Iiқ l#.x_ QBeEiS]t9n8f\Kiݣ"A qwf-e:V ȘI}g;IfyS֝C=ޟ? Z! @ͅ'ύ<ׯ*w$kA&SJ}EL *%Zp}oRޭW٪~'%_ws$p^4;Ռp\)/ZػYvՙ=..,wczw6}zG^B2a{-`$<49Z1[`8 &Un)\? 9VIDikkvm"g& o}W7DCrQLr<,,oL)o|-ۓhkO v_Y฾jx >-ciӐN+ě(s%t@ixvCwQSmRAx;sƢ8NwJbCCSBG$i0dsY}'շ'0ZcxQ!Z=אQͫ>e {蕮Xxm.;RsBTRy}Q#*tt Ks(g9:릛pw =*-vWꭞ#dIcf Z)s,!3[R%QH$ϱmHU=(VG>d;+wuy@Fj'دfT-x7 HgƳ51vt(_b7V,ljiG%|HX)f加Aq8CWع#R-_Fa*gDOt_`K-~.r|c;½h/.wq֓6].g$FNJmw{v1;̴f0`&+ W{E|֕*Xe}CϤ  [_Q=)OTgTb7u#m۰lu5+ o[ 2λ;w!U7b'"ξ`)o\> k#Q{Q]+m/O>b+XJl(`wϺYEi1:n{c<?ʣ""L#^4NX^௩R0g0n %jV`\hE浴0۸/5*)Eۇ}ν=vrD̊L1w Ll2 ܁-ڹE8y=w`<`גv{KVO#Q#qӑ۱Ϸ+M_ȜeF }9h>l70ӌDR;yO1_'$8[Ua&k`-"ZZ) 02SjF]Jʣs g_KQO|C"r)\79QemF"]d|䳚%H (?m^DD&#(ѤpqP5RJ}[(%dUPIVQg\ZhM# [>mr'̲$E+q־PF_'k*' .R98ouK݄>2oPNҋR/,o=7eFMnNYLm}>F@N|%ǫE Oy&g3Oem1DTM!^*֖NB(M,Seb=L콾[cڲoNkcpܴn8\AjT}){)QrFZ\iWCCR tPLKl>#tOp. ])pڃ!= 4R??q~e%`lha\@g&j #žF;;ۿSC̟R͞n:eV'5[-ɡd۰/Rfq_aW݊.t =i$ukXmƻ(y TK%pcpKaQDȉ$- qd&e(D^DR>M%\kxb!ŞZyWz}:>$qhE/öN6YK@=U 9+. %Nrٸ -y.gm^6Mm\ೇn@rB [^t-s8j{ ]e251ıͪvrv\w:wԓ1޽[7bj,eO9;T.TRm?nD g D7tAݥ >Kύ^Uɨ:²#2-v&[?).տO]a(JtB;"~]PMuxXo+‹#˕`Mw {D-Lp\uyfJUOՌ'S?HPOF.c{ãl~(s9$YJ:vOm'T5D pWԑ%BH/CVn!oo2(IN;0^P3$ˣHonx(žF b+uj $pCR)늷SO0k>1t]aꜩW.E-Ό-~JKFm Mfo/^Kw vf‚ -t]ض'rhp_n3QFmԤʟ;G8ڢ?^6oVm0#<58YW=r? W;}HvM]O[Gz=߻&k^w#YL{w]M[65lק֖KD1{|x6FTэf/N}ܡ4vr3߹zkgu;] ˚ Z%gL[kAՙύvn%% ls}(a8F1I]r$FEՉ,gd%{m~\{!qO] j֒`Wh÷LGީˆC\ Q$΍2ϼ*ȣ?QJ.:-jrET mK"Q_f)>[<"thGI8\v ;$[vL>ȴ}MXNOe=Mr~J 4!C~yMY2TqIӫƣ}c&b|BB& yiVSIzG3GlU7vtf D$ƎEgwdv0l[+5$ᬾ <yE$y9šBYnW$]򙔼"-Th ! -g O{)L{/TfbΤ`U/BA1{vp䠚XJjrHfQEc],Qo vH?+2 _AJIEi }R Xehp :e:g*y]ogid(vyhcd`: "$퐼H>{$8)^SMxWdD|a Fܬ/ M]쟅_pb7)`j-ww=CϺ7Iz4rRu7ؚ)(d}iUo#x;gִɍ@|/hL|b 0D9=Oq(M3ӂ.8l-H`4cCjU٧ϰ7>f|.8y_OCm> stream xڍxTT6Rn[A$aaARJA:$QR@ZZAB) }}9oZ{s]s]{fmN6cA%=T@ d]cK @D&04 ꁂ!2P*"]O8 "HȈHʀ@($7!`p8U0'g4߷(A=`0n00FB`P?RqFen(!< C;FP A&D 8P9ho0„x":`Cu6W?ѿ!G } xc[J3P;%(+ f*H77("՟* 컯uE a_c8x "`H\Dtc,+#uO8/z1*Ebo9/B`nB1jPB8a-(r[t/; :X0z`@aDqP,"S C; H s,FjG{Y '߹R37ҡ6ryƪof~}[lV/<*|oʨo>X0,Qu,[̈́_ڢé_Bygـ;ӑ Fvg2]]wpI/9:%TYb^͡XZ)Ƕװ42U7$9iaqEScm  Uw'w6֔Fvf/^,DU}lM?SJ#%p1|uyU_nG)\.x+,>RI8Vlx.^oMGqx|dM!OKxj %fÛf/LrZ0ѰJi^(vieM$~%,GTX2Y'J`4yVAe-7*590X09FzsG -7N$ѫ:pD}>ZViC7>V-n u+OfхLgrQ^=exFo=6C3WLggdKoulxͳJR6i&2ͭ). {"2Fs4T9CKٶG%FJ 8>hw3^Vwun&fעXLȅnwtn#j]2J $w~m\>TLނ'2Qߙy=;[ʁ ۮ K+F{<36 l˫nXcd0 ?ԄQ$,zݤ<X\ڗ|'Yw`wN攅v=R`Ҹɮ!H\d ߺIP.el*fF̗jd#9߲Gw v#@)O7}oZ}){ѪXn }[703h9V\&jx0ߢ Ӽ*2 A<2k|V$:vay.FҳkJ'&zB9@,?Bz`ݔ~ǛR%?]|MBz?e2<({2̐tt0-&Q*A}mIː,|{ұ3Z .{ڧT>.mBx"uϿjUu ህ5"'Gw&,;W𠂟EIc $Cboe8D~)FƧ[TsQ'sb{lÚVP{hh H*_}{. ilLTXn=YÓ?/H1kNBv _7_dz㣒},pF~\dRUz ]PZU&}PUGWe smNi[-zZBӷRnR{^WU~9Ca !QL1(WBkצ`G #hMt28EşI;[ͷb݃dp"/!btFÌIG*EoV ݃mUXU N޻/˦9X𾉛:N<0 < ?#`ЋʖR1])XN\K8Pdڦyf mar&PQ:(w-[JMj1~7٨XWpGi*Hl͐f[!ǡZQmckj+z-Ytw<嬭JU\yY`X͢1[tfDrrXޭ=8^Ԓ+;p 7}b)+~FZf]R?f(Toisޙ q;ZIm}E5L0BoȸIk^Zѹ-Z;EJ&2C\ajŧqSzʁzrI_9)s9js ;b^rkJtҝ,N>@M^Ƭ|Yׇ<;D] )ɻ P,= 5m5x?rmofS^4m#jj'y0\;|QLY?6^wn_0qFWsv).$'Ĕ(/RK01n뾬 ' MgOV-5YER5[l,'HpMT]82cTp?h6XTkP;]8-О7pnxhՂ5lBphB"ϼn&{=\f2atUBIq t3ΩƳdI7_{}j#CUpڐt< i 1`pIdا~N'Xe_xo7^3NK9AnXp:PH~t8}xjRn7 j{y/yzu{ݑ q"j5//Y$cLQf+|7?Ī_jx8Ḧ Kh!x^rc^*?cO ,l} 2^c=foƜ|cPCB#.L[~pnuP͓ IvnPdGfPp(b^mV(H܊➊M2*\T`|9`gjDnJ4i1WUlY=2?H_xH4 .}bj ?p:!RߔQA'AH]DUܬJ>TKʇ_UtbXr=g)%cZ|NoIJ಄##'κ%}m@#ͯ&YG+o}֚'pc y~\2鵣WN)1yc '6 )bߺo5y"q8^h ,ǃ{Kt3]h4p_Ghpk䟝7pcJ wlwDLF3TYG1-QX̩M.m *l>{kN3 9Q\Z1=@>q|"lVRQ^d?q`pȊfZ'ƹ;ޒw).J#gf},jT-gD36F=$&a ,O: ߣL KlX|㝷Ǽ0R&\_|`#ܻv"Z æ,=1nqӃҠzGYwvÎ9W ތnz /veə-+Zt*W*8uynUr<3:sRtBMzru.j)Ͳvd^9o.֚XAfB1.q+Ux1h/O$Z{MS*oҏ|>ZxBޭͪ*1Iڱ,kj'nmV2%1j5Zfk^D~MZ/F@ o\OT/Έg8)}(w\0jC"vWSV ߯z5e!w|%+l\> m+":.uznĞt?@&$GfY*=L : QrF2[7 N&:s*9~Z3殿ىv(w%~zD,-;6>ǻ%n4x𲒝^ɓ(S ,~߷P*wH@]Z5æ}sƓ:c8eK)ŀESJuaL:LtBNIK-r2hXftAtE~H$ju ;Yyۓ0I AZ] U\+ǩ>JRZg5>PG kǤ *\Z%65҉?GLX?oNמxTy9Am8 .Pؖly~aZʹ^0W@:W=cnz]kJQ~a+|; ©yA|nLy޷A8EWz:ʣi1ʏ=.8W{Fo|Rٳ*b"+6 'J2DDcD& ^|2^/9kΤ\ Hd:2PJx_]k^lv&\{2N< flέ/RssOS'd=/xHp#,UhN4.jk걀h &hk+9Va|rG_Cy TP G8u Aq "--SY&n{CSOیVw5* h,1Ehnp endstream endobj 261 0 obj << /Length1 1372 /Length2 5926 /Length3 0 /Length 6871 /Filter /FlateDecode >> stream xڍtT.(1( ! CtH0 0 Cw7%R*t7H)!sw]5k}{?{y8شdP%k88a(0C%@ 10 @j$* <(`V ~u!G8y"a6(6zpA.:B0l!`<тKr.4}; e Ѕ@nP+/M#3~"-O\ar#t]p+(r wտ࿋ m0(@KI偺í~.t= s['du`4\ Hʅ"W)+­P8ʅ| 0$>vO#0/VN'p+TU/"O<@P-W{}O'$W F¬?"oBB}w+"`P?a50Z{ ߿ߞe;x~zjZ;''xD|D@ !&.gm0U[#L>MW\ g/MZPDn& "A?@R]S./@J\Gs @6mC L:wVFAn3H_@OZiP?j08TmAW W/=m ~LPDF"Dh9 AhCZA=~+#P/$uh04}t!H$b_~B=Ia]eHE,;!xKo[u 1ggVet_ބN0_ {e.0V.Ol,VULqL%Nkx^eP-+Ӽmƾ76#@> ;k\5KJ:~hY%=[@b=uBZ 77w 8+'@LLqb&YXf"RHuC g$/ORCZ`,p Yܟм|\uq*m8`l̞sH7%`|rKS*ji-=ީA 6U睈¨Ɍެz%<4ɺqe'KH?,H$뚳]- 5;NșɧaSvaFm|CS.MXς54E}"vAffZςd)y2n"3;fC* v˛Y~Yg8^$ms/B<|5*zrvfS naGw.!8n:73BWMg>©KgM$7oCpŦ?Eld[{yD=g$b0QCZ^Ĭ󟀬Z?f'Qɑ(WOk"e\2vUV_ch,}0{V""9#K .Nu O.J3tCӵrI{|tčsK1mCCr>0q! LQII`Hgz1k&JZJ.nX׃l\Q>w"(ø=n7"bKv+c/}Va2֣[/@k hXe&VnՈ|PGt ~ 忆Qkd-YRarB@dQً b?Igbx \rs/bc,g~p;o/.f-,AVg.ۤQ{[,qjdCz4lBջ{CJrqGBR R:{Rf2oI1=aLzЪ|G)߯gfm}z˕*/?H|"=0~Xv7u%oòYq#’8;gb{ |_jϞKQǕ¿'b;lNFel *"[r ~&D$&UcFe#qTý=Ufڪy!)s͗Aiq4e.8lLI+T0dZl"s]I6y wJ)=4Ox#ob@fjx}jz(va4LR9'*8;tes :$Dĭ$F*aA]"%zh_b7S O MgVO 'H0$;ޅ+hQfa7~-7Q Eqr2\3" Vb8~=}t17U?#hM9I$ɒQ<*Z`},d-;peCC7oK83u=o;x<7k,UFˤd=˟$'vِ8&lKm.xi;5ʈ;yo#J0Fm<,-mLjtA7|\ROҒvO %N'aRN"s-n鿁GT8 7s& ~c2*bPL_.w=oL~pB^IkOa.K _UǤ{ֳ;"8]JR{z$`Dׇ<s%ML_f=plc;}OڲJV4,Vo$Fpp$oӹ"}tf2\I)M?ՠWftH;̲yןҔ7B8{7)"vj"9>~D |G. dP3N`<įYQ}dcz}FWAJ#*mmP] mb!o HXS`=*CAoO YE!f `Mk`|[Th9hds4B. |cjMpq"dp) hnwxp}I@gAy&<;00] :[r+ULF$X$8atWzn1$)I\%Og)Ua"&TaZm&X՘MOb2+)jSDp%KˋmWJktzaЗv4(%? joWާg_<8ƄV|ZYOeamvu:]WQ75Cb$5Q6;c"1N~QTǂZ%BtF>h-.~KP*, {]E=Tió)&HDe5v,~zIS϶}9-2̧a2j&`bgƗF?*UG+ 2 EZIv8\ lNi [T%=N18غ'1kԬԶS3g;BT^ambCJu>]YGl-5{n8OI~dnBdiux" a+;@srE-y5͒IcU]g,1?gcy$|3*]z9yƽg[^Ho;eEsCb\6c4|y..+L:GH#"1Ӟ +`Ư@gC5L !ovx{T=¯&%F6pi,cɆ oglf~T~.aVqGuĎj)cF)^݌s m ^M:ԵcbRII1sjP-!SbQ?opcxYd}o~T%3Q U0ts|h2xưjq$5Qӫ'eZHͯ|Q|PD9n灆غ2b:_ō&Ը *hf 0i[It;>n Aolq7x;]r{T>Kɚ"w(HzԉUèy/VI7R";(@$y3衛 ;HJq,Ch~ #V6l7͓-]&ckٮ. Y, {eCAۯ_^k[<'U.96l ,}M5R5Sk"iuOH 3ڡR,f%L:hߛrYpm=+.@]'ԥ/J÷[z\D1Zd6C]m[ՄL$,rYmin]%쉰Pe":Mf%=“)m7xVUiۭ7{=c&nQ?u=; AUYoaw=!~Aw5h/$phMcٽ zDzT#ɧ KwA_.z+[wp*THkHvUΡ}{\ :l?`]壸 ,U LIb?0)U<$SG!QjZ<KV%(5ދW}QL$$)"̄QSԪ U_&OՉf˝*JG|*lkɖ.pF| ə)ԡL]-zApN")RG/$lr ׸S>UjbF.ƼTq\2I66{roV[A6~Gǫy/ 4e`RPH[Kdu cb6pf$ /S6"@U%k+"app4iˮFv$A:+ZUE#Xv.^R endstream endobj 263 0 obj << /Length 696 /Filter /FlateDecode >> stream xmTMo0Wx$ ! 8l[jWHL7IPV=M̼ su;Uٛ=w]yil;<[[j<=?׾+v`&ߴț<^*;~&Q>MS >_P{=s@dkx;`VY`s4JaQܡn.Uu9\Y6><ٴ.Z.4>Dӗ}~r:-d0VWk,8yLһʮӮђ[*mLr?q 5F8@=@)& 8Rx uD\j2HV0CzL] bctI g$`htы0\F0s jd< I6zg W qȐ+#k .bsrbmXK7ǵH7Gnb>&jؐu1VljOu$՟qWS/%1{\xB!K(hHTЖ枃Jρϯv=k2UKς_:~$/ ~E+7ˢ/ l(/} -+ZXukoԝE?ZKq endstream endobj 264 0 obj << /Length 695 /Filter /FlateDecode >> stream xmTMo0Wx$ ! 8l[jWHL7IPV=M̼ su;Uٛ=w]yil;<[[j<=?׾+v`&ߴț<^*;~&Q>MS>u;q~:fc_0F)lGιmu f8Gӫ6b"!YUe.`M{My?IC4}+̝l/Bj*{pϻƲO('$ *{>J-9_eQ"V$)MP:^9 ^` br @ {@(\,RH&ti m+3ԅ ,;F$БzFFieD(0A1a8yΠFpnù[w6p@ )9r9b_ia|F-(:(nQHY^`nA|n(戥K}s\}sԑoA&vqc⠦ YK^ʛ!_my_)=^ ^{TGRw1RDž'xJzImi9j'pͽܳ/-_Z,N_: ~iyY2q,nЪ5QN Y58.] endstream endobj 265 0 obj << /Length 739 /Filter /FlateDecode >> stream xmUMo0WxvHUdCmU^!1H#x?gx]OTm$|͜s_Iss :L;<Sz==׾f`*_`ɫڟk3'iѴ}=M;7rfnj-eSӵOLg~8 )ok A8 $`I\3`Af<Z]! xNky"7 _㓧q H`nḱRONH=CpB:# =%888QA~!*zƜАT?!~> tw8y*sύ }nFE>7*QύR>7G];~<6OIyktg>O:yұϓN|I/|yIg>O:y҅ϓ.}2 L> stream xmUMo:W5?$R. d9M eCkmCp;;w~>|3E_?O]5߶w]Occ]=~?}Oyh9%?۹׬B|Ɯ>);vw%g43>\ 6 EJ78 1{~`W(-;]%=xe_,b+-O;q\L}UI--=BKE1p[! Mߊyu>.N5K)Wb٬8i[_uʕMzQ)V(Txޢjy!Z2P="Zd0\ÃGR\).2*Шa!U,H`+j.5Nα@VK-x%3%AYӀzΚ>kP#5m0Woþj.ZT$X/)n)#Wo(oRZ $Kp4Z-b\1ܰJ P"GXQi/8k^Zq:Zs9dB )sL-7xJ`aɽ)f$1 dъcCZC<73JgznHȰYɚTa,_-O87}KԴܗLloK+gJ.GZyVc48Wt]:P~`rZq.n1] S/Pu7Ue:?&?!d&1yHn5)yғBx#1ޞ]Go׏M?X endstream endobj 267 0 obj << /Length 900 /Filter /FlateDecode >> stream xmUMo:W5?$R. d9M eCkmCp;;w~>|3E_?O]5߶w]Occ]=~?}Oyh9%?۹׬B|Ɯ>);vw7{>oaI> ѲH8U/RǾ0ñ_x0ӅxBiE.͏S=/b_ixމbc4fi|8EXD_R4.GRQhV̪xvqڎXJfUıkM;rͭSlҏ֋jU,N2@ ",   T[<5 1"àcvG@mg K | +T|5flxZ1YP^ꠦdb}[ה_Q>kUbw88]k|'%Ǿjց{ g䈏rsqk:n87xIue.Aft0!?4ɳ4mFtӔ^z1?z .~lP}L endstream endobj 272 0 obj << /Producer (pdfTeX-1.40.22) /Author()/Title()/Subject()/Creator(LaTeX with hyperref)/Keywords() /CreationDate (D:20240501011517-04'00') /ModDate (D:20240501011517-04'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.141592653-2.6-1.40.22 (TeX Live 2022/dev/Debian) kpathsea version 6.3.4/dev) >> endobj 2 0 obj << /Type /ObjStm /N 61 /First 505 /Length 3805 /Filter /FlateDecode >> stream xڽZr7}WѮ-Ϡqǖ+Uĉ7q聑i4fp!E$ڲ nn )R8A /(&# VVEXO" Er1 D4Z( c(D::an .JAI(0VZ[)JD/tAh',` Z +c,XxrF'j8%fΜ΢pރz)AJcm0a\ 1bU ^V} 9 * [cQA(5 ,+ݐAb/\AEcK(b {jr G^y&%SE1W&+!jM?XYx]EGgMRbŪu%H#rq ˠu!YnC_|xҿf&٤\g ʄjyw{1[AuSëw)l)C]Ls񼭉bl`dc;.on|tٿ}_;3@;MpF.¾`tgw1g|iI:pv!مc c9-{nSqog3 ѿ>-Ra[;A>;nd+PI sQOo׳4ݰvbu]`@4.xZǝČos{T$SM߮~ &%׿xִџ/.KcR+m}gtgYKmm՟yY(Çq}~~b?%cX~4x/6H7mTQ5XIhQh3ֱv;:븻cC Jv5CӞp#6zQngm~njKm=DG?)cT k;й9 ь9Ih?? fk+cf2dvhI/ڃs8ehMz8*ׁ Pq^p:S :P!&#RM@:Gq|:̳MӃ&A‘34m4mqXD.(2ol !)/{tyAtd 2P(myl?b7 ./IJ(܅](ֱ!DEݪ;G. BnѡC6n;t<7bH4 z"M5C`DwpCJ@aF\x~a3wĜm +?fx +A/@ 0ƲTg,BOose|P cSzXS,cjVM$Ak,Wk-P۾D]9Qfe!X-,ri˱.8˂[to]#2u-gfa;?xURLq;M|ehMhXOZ,5kcaJlDG66FtA֘a 6h( P$6Wq, ̩[@ l @x,vmRiӭdq=ix8F;Rz>l)燢AO@ Wy2T~4HcpA2՝;.!r~ zY҃XwP~l46X_Ic>$ BWy8l8aÑ8-&wvfW@4F]aߠL\p= o.enIaъPBxJP RzDZ` =p#~;c7( ko!#(ԈYa=PĈ\(.^t) *3P|Keӈ+<2)@J(.<)7K籠AH 8i.+ctTJ~D?"SQ/g5}ZG~*}~Q *$eXH?Ξ+ߠDRbI()V T HHb]]11qDA߻fdHk&e8M՜=C39ȨL5{f8-0V0 ړ"(Mo/k)2zz5x g[դqeA>?_oLc~~O߼HB2(CF@{EX^_OyM1"端xwLFcUOIf\/~U=].b\ݭ6-d| A~')_-xocG뻫M2o_'飅HSSHv~=ېfy:]W\džM6J֏Fwfb+3em~?fj2l1em~jY4w{<;ۖO64ʍύ;-fFm3cBÍ(-]'wj~?BZ[_<& e\&2n)対xOvH~?xxtޮ͋7?!_[5tي>v;׳)r2lTx=B\®߯fu˾-EQe endstream endobj 273 0 obj << /Type /XRef /Index [0 274] /Size 274 /W [1 3 1] /Root 271 0 R /Info 272 0 R /ID [<80CE40745E0597D383B1142E17CE1576> <80CE40745E0597D383B1142E17CE1576>] /Length 790 /Filter /FlateDecode >> stream x%wPqϧTfHJH*229{(윕콝=qFơs9/8<__<}?1u1Xsh.Z+\p/g_QV"H ?#f"V4ޢh.*rָ:[S Rk2xwP9 loG5x5[BP{O1Pgv Խ :('P?!"*J&Dr$]VޥuLwEQUTE kMi~):.eDt)㠛zVR. ȁ/`2΂a0|= #(}̄aj?>&DDt6LI4o٘Lj$5E-Qۚt9;2NgYJp~cX `Q!d[9A$u":"Кejrb +5N@{X(:lxyڷQ<آ[ouέ+E5;\y3vBŰ_]=px%9 p-ʀ:%8}ҿ*å@Q u? U5ey]y܌`5n;ww&pkբ`4<)<]xg%<(]WZF~a}{ J955ܜ"U#kU UUckV| G"A$ZMm8 endstream endobj startxref 103441 %%EOF pcaMethods/inst/doc/missingValues.R0000644000175100017510000000327414614347746020405 0ustar00biocbuildbiocbuild### R code from vignette source 'missingValues.Rnw' ################################################### ### code chunk number 1: missingValues.Rnw:43-44 ################################################### library(pcaMethods) ################################################### ### code chunk number 2: missingValues.Rnw:46-49 ################################################### data(metaboliteData) mD <- metaboliteData sum(is.na(mD)) ################################################### ### code chunk number 3: missingValues.Rnw:52-54 ################################################### pc <- pca(mD, nPcs=3, method="ppca") imputed <- completeObs(pc) ################################################### ### code chunk number 4: missingValues.Rnw:58-61 ################################################### data(metaboliteDataComplete) mdComp <- metaboliteDataComplete sum((mdComp[is.na(mD)] - imputed[is.na(mD)])^2) / sum(mdComp[is.na(mD)]^2) ################################################### ### code chunk number 5: missingValues.Rnw:64-66 ################################################### imputedNipals <- completeObs(pca(mD, nPcs=3, method="nipals")) sum((mdComp[is.na(mD)] - imputedNipals[is.na(mD)])^2) / sum(mdComp[is.na(mD)]^2) ################################################### ### code chunk number 6: missingValues.Rnw:71-80 ################################################### library(Biobase) data(sample.ExpressionSet) exSet <- sample.ExpressionSet exSetNa <- exSet exprs(exSetNa)[sample(13000, 200)] <- NA lost <- is.na(exprs(exSetNa)) pc <- pca(exSetNa, nPcs=2, method="ppca") impExSet <- asExprSet(pc, exSetNa) sum((exprs(exSet)[lost] - exprs(impExSet)[lost])^2) / sum(exprs(exSet)[lost]^2) pcaMethods/inst/doc/missingValues.Rnw0000644000175100017510000000565414614231101020727 0ustar00biocbuildbiocbuild\documentclass[a4paper]{article} %\VignetteIndexEntry{Missing value imputation} \usepackage{hyperref} \title{Imputing missing values using the pcaMethods package} \author{Wolfram Stacklies and Henning Redestig\\ CAS-MPG Partner Institute for Computational Biology (PICB)\\ Shanghai, P.R. China \\ and\\ Max Planck Institute for Molecular Plant Physiology\\ Potsdam, Germany\\ \url{http://bioinformatics.mpimp-golm.mpg.de/} } \date{\today} \begin{document} \setkeys{Gin}{width=1.0\textwidth} @ \maketitle \section{Missing value imputation} One application for missing value robust principal component analysis is that it effectively can be used to impute the missing values and thus obtain an estimated complete data set. The pcaMethods package was partly written with this application in mind. PCA is a way of creating a model of a matrix, $X$, by defining two parameter matrices, the scores, $T$, and the loadings, $P$, which together have less values than the original matrix but when multiplied with each other well reconstruct the original matrix. I.e.: $$X=1\times{}\bar{x} + TP' + E$$ where $E$ is the error matrix and $1\times{}\bar{x}$ denotes the original variable averages. Now if $X$ contains missing values but we still are able to get complete estimates of $P$ and $T$ than we can use: $$\hat{X}=1\times{}\bar{x} + TP'$$ as an estimate for $x_{i,j}$ if $x_{i,j}$ is missing. This is can be done as the following example illustrates. First we attach the metabolite data set with missing values. <>= library(pcaMethods) @ <<>>= data(metaboliteData) mD <- metaboliteData sum(is.na(mD)) @ Now we get the estimated data set by using PPCA and three principal components. <<>>= pc <- pca(mD, nPcs=3, method="ppca") imputed <- completeObs(pc) @ If we compare with the original values we see that the error is rather low. <<>>= data(metaboliteDataComplete) mdComp <- metaboliteDataComplete sum((mdComp[is.na(mD)] - imputed[is.na(mD)])^2) / sum(mdComp[is.na(mD)]^2) @ When using a different PCA algorithm, we get different performance. <<>>= imputedNipals <- completeObs(pca(mD, nPcs=3, method="nipals")) sum((mdComp[is.na(mD)] - imputedNipals[is.na(mD)])^2) / sum(mdComp[is.na(mD)]^2) @ If the data we are interested in was gene expression set of class 'ExpressionSet' we could simply do <<>>= library(Biobase) data(sample.ExpressionSet) exSet <- sample.ExpressionSet exSetNa <- exSet exprs(exSetNa)[sample(13000, 200)] <- NA lost <- is.na(exprs(exSetNa)) pc <- pca(exSetNa, nPcs=2, method="ppca") impExSet <- asExprSet(pc, exSetNa) sum((exprs(exSet)[lost] - exprs(impExSet)[lost])^2) / sum(exprs(exSet)[lost]^2) @ Different results will be obtained with different PCA algorithms. Which one to use depends on the general structure of the data set and the imputation performance can be estimated by cross-validation. Please see the 'introduction' vignette on further details on how to use the cross-validation capabilities of this package. \end{document} pcaMethods/inst/doc/outliers.pdf0000644000175100017510000027774414614347753020007 0ustar00biocbuildbiocbuild%PDF-1.5 % 16 0 obj << /Length 2110 /Filter /FlateDecode >> stream xڍXK6Wh"N6ng*[)$ %M\FۿGFe~xxب4 ۤi쇅<֛DzHE^o]PUmK]VMcc`_%j_$IHJȏt +Eya([3a,-_!+Cs͑4mvIY٩/b'ûϲAt=Nq?y]~SEIpˇ*֯Up*4r|dƉGۚV:1K٭ٔK0iק]MM9vnDR^,g$yꧯO6G[;zhI6ˍ77"?H9o70uelnC7-GoP?;,m" ^a`EQ ,~qA""nXw7ɒ{xXl{iN"6g2tI?'wV0NH{i371Zc2x&fGrT/]+vGWrsbJU/ŶA= y}AhI&qЭLRlYG uWC-8"ĸ's<5/³4\bh b;4  n-iPV!&,<@a܃rm v=hm^Vm l/Kڛ3 z{{~vsDR U81`N{du eQ=]{7q T"CˠA[ˎs|DOQd+%h#R*QG8=ɭ)"#eAsAw:kpgx|$PX̋SqH n%e$gIa\htb{k^90h>I]y T}U`݅r\8WʇHH$x*GpiL<s4TWGF O<=V,Yͫnc).̑U( b-tI"x3E#' h_q$% *bP4rD)V/Z>U/0u]?$('cqy(I8l Y7q>7"<"k$oF(3Wђve2B p쳪N>/+a9B9CTH:S+Cb|\Hkj]:V/_\&;97"6.bWjs D],*gb>BbN?5Ǯc_ >fݳb9nj,C8v3;uZ xZ͡ .V9v=fP`tbO"J꒕#x0i~?x/hʸ쾊AvY'*5K)&ho/9ok!1CsǝJ.FmEfyKyȁAMЙ[:= Vz"N?X_\uOִFk)3j(^qptYY=k!4yvb T26yE@oB;YE#L P6̧^l5CIh{[Z o=vhB.W>FHQBW?+w+zn]=c92rBk, ˤyw$1 ]%:t8Zĵ4WXSq_y1q,s<2"Ϧi$趋E^v)> stream xڕWmo6_a 5!0HV J;ɖM?,ɍ,SgZMy5n[yUם60R0S+vd̢):-O?'3?r(qLIQxXjw:ܹZmNKiLgQ;Q`,d Id(nA#PW=F3F1tbcEJaXc~Fa3BdžQЪ ldK{NM.+WG9Fz7p=Nd[Zk9r:!Ek*2**Q^2b*4STyVoTVE0zJdPz&JuuIFїCR0Qn8T\xT mUC$΍!Ȋr|$NY٢n !N+uW5jd #ݵtn$++ޤ# TZ0EEv+N]ݶ}޶mq(5PLfl$ՄBUrP@}÷a`'++ \DzF u'8Dzߞ O/.ocP|额ke7֕@]V{McվNҽ tb9#4Gm%Gr9é@՛3ZhUwRԬQO-`xabx~A/˃,AbQ)]<}˗Lj } K,ɰE(=6A14cL#s_[?3bέpbG/) M X+,&Ӥg2Jm;@aA5CueL9lpnG'WvOϿs_XϾD"g🋃BmDbop}nJ`,ҝugw|"9}<-&-kXTӮVtkfZY6{9F!omB0J= J)ZQڷ,/6-{Uׯ c`E5kfXw5ZC7 v鿦d`%P;Iv*Tw34spmEJWXqȣlMx8T~N$YӢ]M.xK{TAZnϤ_"vb.Q;M1\ ozcm?pQ #xq!\@pY+q︟1`XRtGȅG]UJH4wݍj~8!mx> Gf1xaXf^]λ X endstream endobj 40 0 obj << /Length 336 /Filter /FlateDecode >> stream xڥ=O0  Q ((06Z$8Z ޻{r C4$y&yO2:ĽcSl͆+<SY왍^d 2hQ)QJb̮L3!fi&ij4cئ T!l{mRXvQ~9uuBX8˅_qg}5:_۲i?q]x#_$Hn`_`G @ 2~ڸ}<7f@p`;AV8O1@=ӆn$>\'1! endstream endobj 29 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (/tmp/RtmpbN4lMc/Rbuild3d0e7322795bc2/pcaMethods/vignettes/outliers-005.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 42 0 R /BBox [0 0 576 576] /Resources << /ProcSet [ /PDF /Text ] /Font << /F2 43 0 R>> /ExtGState << >>/ColorSpace << /sRGB 44 0 R >>>> /Length 13226 /Filter /FlateDecode >> stream x}Kqݾŷ ~BL %mK^eomk_7w|i-W?=_??>Gz[۵>E{-.q+-d{;n}U-D{ rnxES)jǍ+qWh*\8}^X5w1. ?;HiN$~]qĶ#}Sز;/by)ؾ{[H|[@Ӆ\_~.O,$ uq'oIOMve*욷KE;nvBqC U,ym=cFvZo戻gZKcۮ}SGO+O)J %]3!5%熭7 S-ա+J@SĴUC1w/Ss@e3q`ygCq5q`j؁Ǝ:}Soƶ]y miyh[S|6eFݧ}\Jo{3c?һ*bˮ]ֶu;tf ad\P6ҽf #=&VRHjXSܱeW^®yk[ʅ?Ǫq-rw_\>.nKW8~,Ԍ26.M,oIhض;/byqZōc=q-m{͒xTldXI&U(}Cمش;/byk[zq9Tn)֜L8"*+͙R+>)7[K3F}bkw͑cCy̛Ҹ7}3]QzMr]36=I$fkik[)wuز+eܣۍ;¦!4;nIxV|vם+ͳ˚7oa7y٥ض+Sa׼-u{\`tMsD͑;G-JofX ƾ!y?!K5ooK;C}f /.\klVXIQ*/oHrĖ]y m9*9X55:sxwRKf;mb8wovKwi+ZoĈGqӉ|Sew^>5yǼ]q)X4e^ZF=g)ẹX^a'|4g @q@[3T5ooˉٛ8)u+\gLߘ xMua%7[KsŘ #,-ض+!W{ 5xPƅ"F|GPj\Wek81%XK!5&v$ߐ[eW^CZ%w/< 8瓘,qrb%QL HmxδoJlض+/a׼E#QzL^P➾ca5WM%v:&v$ߐ|.>kH~jjl?zxGv4>#q4VR{jv׌(U?o}]eڕ} E5rouNlOKk\+i,jv76һFk{Hp{kqf8Gu8.KpO{qb)7[Ks ]ɾ)5cۮL]TY-tF<-F.ؓK 6&}4WKJHM)bۮL$ؖqDǪR[3ƾtO *O۱+ Z=.Ɖ]֊-v~QjJLCq#zXZD/Kce+@ jj8!qJ%fiW^®y]a}L~r{b}aһbP"Rϫ5'3Uϱiw^>}#4;a3Jx5-]gpשJ֚/1lߔֶqReu\"O+j7wY@Px6c7G/eC>vӎac-4=)m<iw^>'<.T.4|Y-e3Z*^MTc5Dߌmv[r,D}c0%`@n"^ jM\ƕؔXja[xƖ]y̛"5ԐI% O SbvdB~PpTkiL",y[v%욷 Z]0VǬS9ȿ<^-yOsK<1 WP,VYWP gږ|p265"WvLxOflj l,7%flەk󸘬7c'ϗ"y'6\  VNbWƖ]yq`Uc Nz.W{!6.We+/a׼}\dbj=\U,y߁.S*K /bߛ'3kHeI/_-`\ƒ$/!ia}jrGƖ]y > 5NN I,L}qN::%xxOJVM3|} ~Eb$fki fl}Cz^#K5omK)XNMTpFf 'ožZKSJbR8}-v[,ZꖚUt'|m؅{MbZ@j؍,+:-RKt߷&88} SBsTihb%7[Ks\)ض+Sbyk[چoG?VM%/CYr>bujvװe eW^YL3omQBx-J\x;a-ZMol {< !C)1XI_Y3f݄m\y/ߔve욷*m+#S:I݄xꑲ&|4K}oyvlٕk>_\0o (qR7Yb&μ2YsBl7%flەk޾!_QgƺS,kx񢴥iqrjͧ[EeW^>Vٍ +kj"5⁑;ZX^a|N 01}uƖ]y m["M'Ubp:movvfcǥM[mW^®yW\Wwm1J?n|8s]uAhSX7mGvlەk޾oz"gtSp{sNӛRQb;BwR-v}aqfqLjc)QpL0 t]c%% !5%`yJg!plەkޖ˗k=WKxx{sH6RsejZ<&g}W?WflʋGc'I巉֜,s#͠ASWC;oJo JecveJ#or1lScՠKΑ$6=B_b>OZjyO'};6΋Gږw|:޺1\D;^Yv]rt_jxkNIelٕ/s#qCb Jwۂ '095jw5$sJ}[J~rKM%Y]}dX %kn 'l'["M#[ܲ>viW^ͼˁW3f5СcYǞWb-iNccoJض+/a׼}b#Fxib.LR4ak w[Ɩ=g 4cyp%En!_ wk^k{25%ò]=oeW^>v@_qQў#EX< IHiAXc\pa M=\8KGs[6.t8xؓp^in2R>QrO OvE#oo ^eԚc\ȢVਣrTMAIXIX skܛcμ]KO S%sTFvmɽ.Qb%~JMxcQ '}C1o}ڕk:i8;:GQ<|iWb-UuN͎q6оKplٕ-z:jNzlvɽܧ]dJ:rO[E2K5 Bu?o䠃S^Oyiro>|ʳ3%_Q/Qkcc,݄x31E88;5Ihr M(Mb5GEŲ 嵉&k [%?O"=E|9J% |9-|W|Iq2X? eO,~?U_1)__Ԭ|.H8lĬ,r;ǽ)<1]f5YV?Μ_|arVvO%D>sNa11xI+=gQb,uZ-y~ ˳cv,N~WJ.1$uobY[KYR2 rs6T".!b)(ḿ%{N?'hЬ>1pcvv6WoY$ObAVmݗ ,şk_ G(ɢQ8]weO{em蛭PdO \M [vgJ#GA(kujPCEգ;$ZKbv$h; +) 6;dlٕkޏgkAطpQituIvP)K?Sb[3ΔGkAxUۗz1{̬Ee, ´_|bY{p߹Rc fTKq-kKGo޲(4akߔv%#G ag 苳$c@b%jGڳ;,R=kޏZ[kURJ.nigvc-)Qǖ]y{z;+ֳaZt^D9ݱ$+AwWr7!l]@̒rJVֵ:.Gq꒰X}vVf7RRS:@I=tlەkޏhkv`NWOI$úcMTb)7[Ksq%޾kvlەkޏ{/OWe%!+) VD}4cۮ]~TnKϯX֢d%xTWxXvԀXpwش;/by?*!uiPA6WW3ӎJj~nNIw'cCj˷X=rY=+KbN{x?GvĶTO-:K5G(iA>UOyQuuIO^(R˺6_z"rTjP:FӣLY\]]k,X-{g>voys-viPv&\nrTƖ]y ܾnj@9T(|n. ӎ쉕%E)5cμ]~TnX5X==J^%1ni-9J~S yK-vQ}?%ij:k!!0&̞XI45xљXM4c]5GEmSsa0VWSǚ[=XKG]]ٱeW^>~TnߏZ>UOTaPuuIi_U `۱eW^®y?*Ǎ7WOM$c2rXj6ݔ20ǖymIQ@r{\^W%iGH,}4X$l*ƥY%5b] eG7%!ZYњ=HaqkƖ]yQ}7*>V SQ<ٲ$P}vVf7/ߥf㝕Xg{3#!R=n=civVH8QuuI2amQ="dMLE}Sb&5G8Fk T=tuuIӨn;+kijD/*s-(\%a׼ϵr{cPz$1;Գ5XuX3O-sqkX̚$ŷ%y䫏lՕ+)iǩ8 zZzu9U:TpǪ)\c8hʒӎ:TLsI͎ |i9e\5GE_J (B[quuIѴ2{b%52E(}TƖ]y 7v:ixVWWxv7VRϣh [q7GѱeW^®y?*lX5'TRxQBI>co~P:R~45_9BeW^®y?*ֲVn-Y=t?\]]Hi;; Ɩڧe`[v%r{w?Vɚ/WW>|dg5-B[)w~8cˮCr;Cz:wuuIr{ %b-ljxv)v;+cz\uk Lӣ֬.SVnO;*'VRͯXb6}ouǦyQ=vA?.^4_^;zN=}b7OBKV']>[jLb|s+@P#uʣ}/s;.i-8 :bg9f-$;F%WW}}~ϭV`9*D>誁n+ʣG!V\n\@IIwLYM_铖nŵTv'\'3]m='7B2l8kk/ݍ+S Wi#=\BSd d[ڹq`SkSVfCܚ;J Lº`%Zzqu_8q>7md޻qni X^͕3qKN̓nxwP^;&'=z龧cC㺎K=r…OKkSMEXQzV&5!o뾻u-+x$L,dOӁ%Sݾ'ݱew>vf|jazhCzTHƖ%=)cdG5J_o8ؕu ǖ]y =W&5dǾzTuzayFIXJɞ~DX2{2[vgJ#oo ;L*GY@Sj"6d$[z@[;F%WԀk#p#kKEn ƒnߓض3/c׼]3 =54hڣp֧]Dua%Y_P\NZ{Ɩ]y OZ{j@MGe$Ǟ:{~iKwm=}'=cˮ]k5N~]o`BOESJHvO@rwCM[ul23&=5xGvsQ: ,,ENZuOXr{r[vE#o1'Svrܭ!O,{Izrܣ,Xðc0R۴Zdk6VS'vwǶ]ymiGEʘwiSo™8_V[8mF~o Kiḧ Vv^8vezRژST,Xَ`+)9O=ధglٕkpSSi Lrd3קَZJ{jS7VY^ÌqGM{帧_xlZ84Hh9ofI;|{ˉԀX~۾㞱eW^>v+9O=Aa>r+=΀M{a%%=5xϓFI㞱iw^!-y+=5,|o =rbӞDJ՛ YMܶ;v26΋G.L:丧e0F Yxbu~nd丧<IJ }'=cˮ]xpSlÎ*QO)uEŦyױ丧<(qjXZ,{rUJ{j:W {N{Ɔ&,.qO 1@N;j '%'7.CVRrSSY|^Xpwr3K5ooˎ%B|Îxwv}'VRg4'R [vq3[8T?%R'kZJ{jvvsQѳbˮ]ɐ<ؓZGR(ڽ(ʕ丧(St ߃‚|߿X뻫5ُt'57?{ endstream endobj 46 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 47 0 obj << /Length 96 /Filter /FlateDecode >> stream x3230W0PbC KCB.K &r9yr+Xr{O_T.}gC.}hCX.O9z PՓ+ ] endstream endobj 48 0 obj << /Length 94 /Filter /FlateDecode >> stream xM=@PEx$^!R { T߱4J2:ԄҔbًӊ<@zAjzHhxۂ )9(݈P:> stream xڍѽn0C"#pO(TLH P:DڌZ53<#02 $i(A>l#ݏxSHiL+}GIf!/'%EUqjUAۈAѩk~F Akpֳ`9Ek&kkpk 9\SX}i,3OZ)g{I!9VӮQ5Fb)e> stream xڍнN0`G,@8U2E*E"L tPsh~> stream x]J@ @9/ FZz B(M>>J$~LcfjHRYiE IJ|mx .[T7(nE{G(k*Q$vEƌѱQy]CÜ*>gY8U#`k&987,lsJB>S}>Աsae-#~G~lÆ޴x+%e endstream endobj 53 0 obj << /Length 212 /Filter /FlateDecode >> stream xmνP1B4aBBR]V"xQ|!1X|3p椪?p))?y臆_LXFsiQlS(NMpw"%@ F`_|;Bg9!4`&EU E `AK]{ҪA5]m?IT*%!4hE7U}J endstream endobj 54 0 obj << /Length 227 /Filter /FlateDecode >> stream xu=N1 7J!d?FZ)Q%$(`r%G)V WؖlߵOf<];jRlxzչeOv쉔pxCvyvĎ/7ԯ1/6; y &CzP@oQ{:CG2U\YMΝ:|$B70xKP%${By:>Le endstream endobj 55 0 obj << /Length 182 /Filter /FlateDecode >> stream x}1 @/)S  &YIc@#BBRPN-G)SHQ xtT+ZS3P8W]+|4(; SúwXOZdx)eE> 7{Skz( hRЂ]< endstream endobj 56 0 obj << /Length 227 /Filter /FlateDecode >> stream xu @ \([2)> A:Dء[Ch3.FP-Cgw5uZQCۥNvj.33tVjtf\F't٣3ZZ ~Ĩo~ycO3IΪg`g@`P?|Xmc$EbXKoJ>G}Ur/cCM~Yܼz'Xɀ" 3-8 p/fl endstream endobj 57 0 obj << /Length 195 /Filter /FlateDecode >> stream xu1 @D'´BtEVbvf%GHi!Bpg3c[N6m2XK1|+b-q*f֊Rt;Fbh.iR]܁#s+ JdDz|Ƀy*Ԙ*CѦ#6 wrp38U{ A endstream endobj 58 0 obj << /Length 184 /Filter /FlateDecode >> stream xu= @ )2'pT-,J--m׊7#L\wl>IƣtB%:iN10 # \ł.yRMLEEpT |E  5fK)%@h;.^ށg͠T;gW*S endstream endobj 59 0 obj << /Length 257 /Filter /FlateDecode >> stream xuN0/< 1$ЩJȀS :/ƣxc|gF=>bΤ;M_ @!3%RJP!LjeT"fS_e!}ѠvYW}#_zGq endstream endobj 60 0 obj << /Length 150 /Filter /FlateDecode >> stream x3230W0P0aS3CB.#C I$r9yr+r{E=}JJS. @-\. ?000070CdD (c`1`qzrrx< endstream endobj 61 0 obj << /Length 150 /Filter /FlateDecode >> stream xU= @k endstream endobj 62 0 obj << /Length 231 /Filter /FlateDecode >> stream xڍ1N0e/A'T e!R[$2TSTVA\Q pEԴ1ra?]c{&ʶQ7P _H_""fצ8 endstream endobj 63 0 obj << /Length 192 /Filter /FlateDecode >> stream xm-@i* &$  (@" X% ++.;r|̦^PHOɐ0re\XRWrFy")BQ*p Lo/dot5Ȭf;%_[a\kv\`k*~_;@1_c?0ĉ[ endstream endobj 64 0 obj << /Length 198 /Filter /FlateDecode >> stream xu= @R f݈L!he!Vjih4GQr-uovN 95lt"ӗ0a3LvGl|9_ kRShNO* x9 N a<+ƂdrqB"R -OlqـfM䤒o#Ef9b , ]L endstream endobj 65 0 obj << /Length 225 /Filter /FlateDecode >> stream x}οj0h0ܢGȽ@+ 'R0 C:NMB[5Q1VOID?qS疾IQҸ"*Md@z- ,goTM-P_ivP=ZCK⑊]l.*3͟{P,m8Ԉb+Tt("O79Uۗ3iZ w'm endstream endobj 66 0 obj << /Length 166 /Filter /FlateDecode >> stream x3635R0Pac3csCB.cc I$r9yr+s{E=}JJS ]  b<]j7g`O~}( X{0'PzQ" L$dՓ+ ;W endstream endobj 67 0 obj << /Length 198 /Filter /FlateDecode >> stream x=AjP?E`u\>`]W֥ EPs% mtb {~Hgҁv$'bε&/tc8jP*&Yeqymwn\\qF R"=-Jگ.SL(J÷/%579G, endstream endobj 68 0 obj << /Length 176 /Filter /FlateDecode >> stream xU= @`}nT1[ZYZ *ډ֛)feW(uŒRA#JY0W$;#WS:[lDyAKA UAЂ . Xν2 xL 3d>{ߔ8+X?y< endstream endobj 69 0 obj << /Length 183 /Filter /FlateDecode >> stream xe1 0W:ޒwMCu+ ftr'utPܚ(9B Z)yb&3J|NYAw ˖raPŽbjjK늢ڭH()=)rƁE?nc ̌혤=-$zL % |( D$q@3\Oc=i=~] X endstream endobj 70 0 obj << /Length 189 /Filter /FlateDecode >> stream x=1 @[t7&tB` A+ Px%GD?hȊC{DxщYvGS+əIsbɄ ߫ܭ*p QDnRfi[:J J Al[Cʀ1؆ƭy4ݚ85AӔF< endstream endobj 71 0 obj << /Length 227 /Filter /FlateDecode >> stream xMαJP?Z8f x^@oD@  cSͣQ|­Ԇss?393MsM.9WI3n/߯K1fb^Lyo/bwYCZʅp "l1^M+ {ho)5iD;['ZG;w>Sӈ~;O{. a@F`$^ߎZgΖayl_RVGS endstream endobj 75 0 obj << /Length 199 /Filter /FlateDecode >> stream xڥ=@PL ȟ b&ZY+hxJ d)-bߛy63f%gtx0e5$ jOaj:*yAUlQtєg&̛}Nr 5r^ a2ʮ`i`r_zH&=| z)3WwFHH endstream endobj 76 0 obj << /Length 203 /Filter /FlateDecode >> stream xu1@EPLL 1D+ c&jQ8%gdB-^6gߑ;dO\q~ƨ4 Py*^r; SrPEqbtLR~3&0 > stream xU 0ES:ޢI N&O'8:knh@}7D%YgXnE68])$$ƒ~ܟv1ɂ1GG xos*!~Zo(k B" Pq>.۶{xcA+M;= endstream endobj 78 0 obj << /Length 187 /Filter /FlateDecode >> stream xU @ O Yxw8jotr'utPQ5I-$f2c-Z)+GZv*C@Hx=Π9sT/Ԩ"kF㇠ZFQ"7!\LŮ{kw; #e%(𮈻i^/aTtY!)y@,=l M>k endstream endobj 79 0 obj << /Length 167 /Filter /FlateDecode >> stream x313T0P04S5W05P0PH1*26(Bs<=\ %E\N \. ц \. 30߀JNa!?#I0#;xI#> stream xu1A50]c&k%P)DRAhQA;C_ V:F:i]yYm)5КԸI T:"$a"X B$֞?!#rljtjCsehx. MO {}RmU@#C3zT endstream endobj 81 0 obj << /Length 148 /Filter /FlateDecode >> stream x=1 @ER~- g`#8RK EJ4RZ(ޑ'̨i> stream x313T0P04F )\\@$lIr p{IO_T.}g E!'E@!ncr e endstream endobj 83 0 obj << /Length 118 /Filter /FlateDecode >> stream x313T0P0S04S01S06QH1*2 (Z@ds<-=\ %E\N \. ц \. c$! b\\\ϊ> endstream endobj 84 0 obj << /Length 102 /Filter /FlateDecode >> stream x313T0P0"3#CCB.#)T&9ɓK?\ȒKCKW4K)YKE!P E >'W $ endstream endobj 85 0 obj << /Length 137 /Filter /FlateDecode >> stream x313T0P04S02W01V05RH1*22(Bs≮=\ %E\N \. ц \. QqC=C=2p\   \\\8 endstream endobj 86 0 obj << /Length 188 /Filter /FlateDecode >> stream xU=@`6$p.?`# b&ZY+h+L9 Gذ nKfQ!!^CUdx[a> stream xڥ=N@Xi=B,  * D)S&\7GH6.DIi53oXk]꥞Z\ޤY\jw^%{"e;xIVV;RoN>`a}x3 HVmHb&oNhh:+Tp=q::Ϥ>F_/C21eya:#f`x!7<=c endstream endobj 88 0 obj << /Length 208 /Filter /FlateDecode >> stream xuн0k#xO `D`qRG(}FBЄĤ~pE.-K =zh.wStlytGN_NgL\kZZo-T c ښ[ۺ8Rf_yOwy_6|pdmA&:QV&ҘP$> stream xu @\z'H  ԩCtEh>уhkeͰ;Sr#&ttBpvd31[%OюWtOh9qh璳8"hre)Q5VzV \4 0i:ul3%Rk-Le00JKE|}xB endstream endobj 90 0 obj << /Length 186 /Filter /FlateDecode >> stream x}1@!$pBBEHaRK .G(.ZHI%ψ$ɧ)) EQgLs$"ܢvKs. yF R 0RG5X-؝X͠NPSϐnilbEO&4>=VgWX(9nn endstream endobj 91 0 obj << /Length 163 /Filter /FlateDecode >> stream x313T0P0bcSCCB.c HrW0r{*r;8+. ц \. 001 `LAȃ=`Aԃ:\?DԡQ?Q \\\[ endstream endobj 92 0 obj << /Length 242 /Filter /FlateDecode >> stream xmбN0?`閼A' X*E"LSad`y^o+dc$sT@|89:]NT8V4)[bFw)/=e3ynr5z z^AH ^_kO mb2{ o)޼IPX5`j5҆uiSy 9i^Z&WW9+ow }:难{{ endstream endobj 93 0 obj << /Length 221 /Filter /FlateDecode >> stream xmAJ@tx9B FSjtB\U.jir(sn }|2)$9?J\ze\)7oϔ-o/Yr>RbGx+$qP-T 8a Hڔ@\fgm{`%NGPik,F=pk0jluo-9m骢;[| endstream endobj 94 0 obj << /Length 200 /Filter /FlateDecode >> stream xu1@![L 肰!V$&ZY+h m(ذ.1мL4'bN%4 )$ft QbÀD4l ;+#/t=ȳ͂B9C X> stream x}ν 0+['SV8sh}>B.E$$q4MS;Q)+!׾28^0+Q.zŚl s ,5yofJNѭ>THA-I?6*<+1vL{Ԣyˡj endstream endobj 96 0 obj << /Length 244 /Filter /FlateDecode >> stream xm1N048IUeHZ()XA 8WDAr)5cHœ5\+.U͵CT2,.[ҷ\/eL#93\SaXw>:@~^M:_6;~qLǠVrﻘJX&{ب#Izc&4~g'.zw'ʗ EJsY#袥} endstream endobj 97 0 obj << /Length 245 /Filter /FlateDecode >> stream xm1JPYR |s}!` A+ RK Eʗ^a2Œ񟉋6̼yT尒x"p,\@_فs/*g. )&LOPvY`n ,{OěMx[l)zi&$vX?zΏE7 }t endstream endobj 98 0 obj << /Length 163 /Filter /FlateDecode >> stream x313T0PaS 2TH1*21PA $ɥ`bU()*Mw pV]  b<]HG#13acFT0ca``?p`L> stream xm= @irYV ),J--mM8mR,dgbF)MidPaly&T'͞ Zh = vA͒#Kv07}> stream xU; @? ` A+ RK E[7GQr)h1/t)ZEyɗϴOC-*2gd6:%Smx],vKȬqzjHHHC,10\qEqRc,S4EB訵H<,l)o e@)]X!uE{/^q endstream endobj 101 0 obj << /Length 212 /Filter /FlateDecode >> stream xuϱJ@_RG> stream xڕ1 P q(dGx9OA ZN⤎m֣xҘ!$!'3N*Φ|INY>-KNɗ[~>^W݊SSNNT D'Ҡi!4y;쑷Gwp{cjCe s]ؗʞZ."US9©-KI endstream endobj 103 0 obj << /Length 218 /Filter /FlateDecode >> stream xeαJA b > ]vj<-,J--mo||ybCBdy-j /;~2xxD-+j.KtoOԬY:ni0s #VH|ěFo;s+lq΅Ƕd,6ɺY'=alp +%D7p endstream endobj 104 0 obj << /Length 196 /Filter /FlateDecode >> stream xm= @'X#MXXSZYZZ(m#Xo[fa5B&x#/~,+E³N|n-f-nKn!R7 !Hꇨ+U4jdcޑM-孍@l_ "j~' f&74.WHe4A o \s` endstream endobj 105 0 obj << /Length 181 /Filter /FlateDecode >> stream xuα 0+ zO`RL'V08iGE7}4бC1:n83d3dftJFq> stream xmαN02Xŏ{H.X*E"L0"5)oG1o`ŃsaA t7;/%KGvA)N v=4GOYScs W,6+"< .L)'rf;GpaF]1P.;a?2yWL ǹG9^jo.G82TJ="b> stream x}1 @49IH,-,J--mMoL2LvY~ Gc 0G8 q bɁD9쎐y Y|=,9 ܂IѱË_ꪽ^cf8y/>_[;bPsfm]vҨVi.oVڷ[eڏ2t6 endstream endobj 108 0 obj << /Length 156 /Filter /FlateDecode >> stream x313T0P0bcKS#CB.cC I$r9yr+r{E=}JJS. @-\. =2>gg`zp=a&f?qA|.WO@.J endstream endobj 109 0 obj << /Length 154 /Filter /FlateDecode >> stream xuɱ 1 ኃG0O`\op Njh(bl-?崚aUÓ+>$?*_5o3z  H1D>1Cf$t cUIa.<5Ga D"JLKL`` ?:R endstream endobj 110 0 obj << /Length 194 /Filter /FlateDecode >> stream xu @`Ń0yVq :fNSuPY7|;4kuhgd4GO q^ͷ=@X f܂x>] C)C 6h[ }POmwj؊n֬GerۺInOs&y?ͅ_[*o&+jIhiKx endstream endobj 111 0 obj << /Length 180 /Filter /FlateDecode >> stream xm1 @ )xnBVJBBB"^do)BBbFST@F R/r@)Z?K6A}cE- ol}:X}"j&xovV$GC* ~f endstream endobj 112 0 obj << /Length 198 /Filter /FlateDecode >> stream xm1j@Ep!fsZ1d"W.B*'e h{A (&E a-]{^ҙ|Xr8}Rݒ;=K}A~qIג7j$2%32 ]hzdLs_Lä_Yt:wjh^H;FU.o%mZ-/LRz endstream endobj 113 0 obj << /Length 230 /Filter /FlateDecode >> stream xuνN0:D%{:&KmȀbj@y?BFi>@UJO򢸑Lȯ9Y^.wv™/}UI\ |~|]=%g\.7B>@T*ƒvPU> stream x}1 @]RVBVb(9BʈqvEy03L8I38Byrj5tكL@N0ހ)PR+IFdޒjIWZE,& *>`۰m$jKaj` U endstream endobj 115 0 obj << /Length 206 /Filter /FlateDecode >> stream xU1j@Eq!fo Rd\ l`W)B$e\vG)U8Mb3KtkZ>iyW]VGmZ[wy|گѧZg7}'8l"M !#T ppP\`~ԅƲꌀEwKr40À0=O%AnRZA endstream endobj 116 0 obj << /Length 176 /Filter /FlateDecode >> stream xuϽ @ nY ֫ 7:9::(>#tPCÑKm8r#:&xAk%5ጙC%k,ƭvd9%hr%HDbfRA#JA;=LVi@ &!`nOYo .n R endstream endobj 117 0 obj << /Length 178 /Filter /FlateDecode >> stream xm̱ 0H-}SV08ͣ7#tP> stream x==@!$x.d@ b&ZY+hq%g+̛@.Wy!5||4gN>0U(N$#;NQ=_;!EFg ꚮ~3 |4ؚ4#\Y]gr1WOL$ǭ#bVO endstream endobj 119 0 obj << /Length 224 /Filter /FlateDecode >> stream xMα@ )iBy` A++Q);l3j:-(#IorNjNӜNP6hW%OR9Q[Qv$QKRvrM`> stream xu1n@Џ(Vf\^PXJQ*;eDv mGt .4#Jنc^"U4aY:m_ȼqy1'ˎ2%'PU2| (2w(ڦE-zD6BF{DIڝ3?mgDj # Arf#rNN,t']c^al оWqi7 endstream endobj 121 0 obj << /Length 170 /Filter /FlateDecode >> stream xe10 PW"y#' MKUJȀC X)GQz U 8eSI< e 15ߗ rKIr5JvDYPT)wK@1c5 0|2 GAw= /t:pZi|m˸иI Pt endstream endobj 122 0 obj << /Length 224 /Filter /FlateDecode >> stream xuϱn02X%{D,Q*5C%N@ծu͏GCvaOoQϚGhI 5NXYQ39^pӢ>PB"m+}~|QovOdPoP2Gp=AΘ&n > stream xm=` .߁1D'㤎]ċ8p n #~$(}L> stream xڝ1N@4QY AT (Ar 3AzWJ_kN|y9H/vI'Zun8-)\ؙBwoVWg)6r}Gݚ3J~ ZTMa.)- o̤/`tR27V֯ifhh`+-RN]dvg9 endstream endobj 128 0 obj << /Length 174 /Filter /FlateDecode >> stream x313T0P0bSCCB.cs I$r9yr+s{E=}JJS|hCX.O0"370`H؃@`?#^^Q`Cƃ-Y  f $700 F"b\\\wN endstream endobj 129 0 obj << /Length 197 /Filter /FlateDecode >> stream xڕС0jrf{::"#a e0XvtmCOh)T^ aLiOvG ֤FscT,r0ʖSiNfEN`Y9Q3pqNN3O0n ZJ4&}5ty+A -ؼ+ԀW2>z endstream endobj 130 0 obj << /Length 236 /Filter /FlateDecode >> stream xu1N@ E"a|$H" * DH$*\!G2HQwmT 娔DJsՠg?x#Um<>r\Iq+wn˜24wC0MLNLtA 9a=tC68yF̛aO2/a<&E>oxv endstream endobj 131 0 obj << /Length 191 /Filter /FlateDecode >> stream xm= @ x Ղ?` A+ RK E[)S,;h%Xfh< }:ex\T:8^pVQ>EmqF;)C}FE$ sXBט^Hȃ@?|bezYETZ_q-`R!a~K<.Kj/\ endstream endobj 132 0 obj << /Length 187 /Filter /FlateDecode >> stream xڝ= @g"#Xraˀ!N;GYg!BR@[]/w%ܔ|q&?,Lƹ+x"ҡ@yRx -0遍~*?umֽr!0e] EӐ`%Ж*sz endstream endobj 133 0 obj << /Length 182 /Filter /FlateDecode >> stream xڍ1 @EIk9 n!he!Vjihh%GL2Φօ}g?ofǜlS>'t#k5?;2{Zd܆L]rBC\"iJzD=[5/jLAOQ~ߏ@B_Zh4J5Ϋ^RMuZ9uEJ endstream endobj 134 0 obj << /Length 193 /Filter /FlateDecode >> stream xڕα@ .<} L &`qRG;[pqᾤ 5)+H+9s<^&|XLפ*L,r0S⺡MNMC $z11wx!"><Zi&N?>cH RaH'c ˁ:ѴmO, YK endstream endobj 135 0 obj << /Length 201 /Filter /FlateDecode >> stream xmPE4K BBrmM>}}V́;ܹiԥS=T'u9&a+NFF⻥OK+ VZ[( f#2;܃J>PDCv@Z }•cC 7'* 4u.7mp b2rcZI_ endstream endobj 136 0 obj << /Length 171 /Filter /FlateDecode >> stream xڽ= @[&G\@7!Q1#X^,7[n8ȃW3r9Al&]'-\,cx܎` s0 n ==Cbq1 SeKvI'mr/)T8R`5zf endstream endobj 137 0 obj << /Length 183 /Filter /FlateDecode >> stream x}=@XLvNBLH0XF[٣Q8ab^2}KJ)*%Kw4 +@@)juE]VQzB[_P :9o.A@9(dq%7@'a/=ߵG.^Tyh p A!\\[>P: endstream endobj 138 0 obj << /Length 200 /Filter /FlateDecode >> stream xڥ= @g fI"SZYZZ(ښͣ[.(wS|7q4HRYs_8 LWCNv?$#(%p:lHj&5pGٌs V,S*7;(&A]t, -GT@8=F> $_ȥF<5ޯ endstream endobj 139 0 obj << /Length 158 /Filter /FlateDecode >> stream xڭ1 @ПJuj!Fp A+ RKAEh9JAqc![̃I`4-ØԈmjw쎜{Vky\Y\/|9êe_Hx+5C8#$RC\B"xo<Iw endstream endobj 140 0 obj << /Length 185 /Filter /FlateDecode >> stream xM1 @4!s7q5@T0XErr,,2ԎgDM&rv=pr^ًYMyaoY!RrGB7 }KD#"eZSW!("PB Ca}96A=> stream x313T0P0bc 3CB.cS I$r9yr+r{E=}JJS ]  b<] @AH2`h AA~[@ Lx:B endstream endobj 142 0 obj << /Length 148 /Filter /FlateDecode >> stream x313T0P0bcc3CB.1s<L =\ %E\N @QhX.O` $0()D? d=H2cģd> endstream endobj 143 0 obj << /Length 186 /Filter /FlateDecode >> stream x5= 0W:oN`B`A'qRGE7^̭ ء4ؔ? ,&Q@>0[}pb*Q)QzܟvI>>yG:J^]S |-,ZHZX:^<r[C准qzb&gaQ$L endstream endobj 147 0 obj << /Length 189 /Filter /FlateDecode >> stream xڝ1 @EL70s @BBZZ( 9Z#XZ:IVt« 3Or#xjBN%7nt8SjImYǤ+]'RzΚT;l@TJ @ hxjze/ ]a;AdD/ak+?iTRS" }G@ endstream endobj 148 0 obj << /Length 188 /Filter /FlateDecode >> stream xڝ1 @EL/ :ͮA"EVbE$Nxg1q߄l">h.!Ǧ^OXRcR 7'e|ޏՌ5ٔs@ th~//iKxO`LГtIVx?>(=Cuڕ/@RriniMoEBs endstream endobj 149 0 obj << /Length 104 /Filter /FlateDecode >> stream x3230W0P0W52T02R03RH1*24(XCs< M=\ %E\N \. ц \. a0C \= h endstream endobj 150 0 obj << /Length 102 /Filter /FlateDecode >> stream x͎;@PggwAxJ!* %>Et300 UjrR豆iqA 5Tv̐ɩ p:_thq_h endstream endobj 151 0 obj << /Length 109 /Filter /FlateDecode >> stream x3230W0PaCs3CB.K 'r9yr+Xr{=}JJS ]  b<]d7zl+ -@>'W / endstream endobj 152 0 obj << /Length 131 /Filter /FlateDecode >> stream x-1 @E?^ xЙmV"RP:ٙ&Nwo\%红V\xA=y1:nwՇ Y/ t4M22DT&2+<*B# endstream endobj 153 0 obj << /Length 94 /Filter /FlateDecode >> stream x3230W0PaCsKCB.K &r9yr+Xr{O_T.}gC.}hCX.Oz 0X [\w endstream endobj 154 0 obj << /Length 153 /Filter /FlateDecode >> stream xڅ̽A ɉ̗eSH" ͣxwN5gvZ88Kb񀷲>7TzOoײC _.)k̓<j*zP R.NO|[ƧmdSL6e\6NdV;x* endstream endobj 155 0 obj << /Length 101 /Filter /FlateDecode >> stream x3230W0PaCsc3CB.K 'r9yr+Xr{=}JJS ]  b<]d7`= 1S'W fp" endstream endobj 156 0 obj << /Length 140 /Filter /FlateDecode >> stream x3230W0P0W54S0P06SH1*24PAS#Tr.'~PKW4K)YKE!P EA 30` Px҂!Փ+ &, endstream endobj 157 0 obj << /Length 107 /Filter /FlateDecode >> stream x333P0P0U04T03P06TH1*25 (Aes<LM=\ %E\N \. ц \. Aj-\\\~, endstream endobj 158 0 obj << /Length 94 /Filter /FlateDecode >> stream xM=@PEx$^!R { T߱4J2:*54`ƴ"f@BJJ7"i endstream endobj 159 0 obj << /Length 90 /Filter /FlateDecode >> stream x3135R0B#C##cCB.C D"9ɓK?\ĐKCKW4K)Y(  $'W R endstream endobj 160 0 obj << /Length 351 /Filter /FlateDecode >> stream x5J0Eo Xb6? Vf`T AW.Dԥbe|B]w6H{-O&79,Lylʹy7]Tr$:)zSQ/w9z槞PgS@="m͢"{tS_\L:eR@5Rl# L7^ Z7] gO.Py&#MYY.IgϞp?GTl]fb& endstream endobj 161 0 obj << /Length 172 /Filter /FlateDecode >> stream x3134V0P0bSKCB.# I$r9yr+q{E=}JJS ]*c<]0A?  @CA2@5@D!dPICd \\\^ endstream endobj 162 0 obj << /Length 175 /Filter /FlateDecode >> stream x331Q0P0bScSKCB.S1s<L =\ %E\N @QhX.O g``~?`g N}`o`F¢0?Q\\\ endstream endobj 163 0 obj << /Length 208 /Filter /FlateDecode >> stream xѱ@?Xf!FHJ"BJ--|1}_aau=΁egM]p,+qeL?&wXis)|›p1$Myƀv3|-{Pe!,GpPghFdPCWT-kCj( gf"{![ޗAftC endstream endobj 164 0 obj << /Length 235 /Filter /FlateDecode >> stream xmj1 ^=;Od-$AhO=Xބͣ{N"Q6>fB&?N'izmf4Z||DJƠz.rM/T%V~rEP@X8 \IU{3bY1Ez$'i=Sː†LBp6Pu 8:R [49޲&&Z'XΝ_%m endstream endobj 165 0 obj << /Length 260 /Filter /FlateDecode >> stream xڭѱJ@? LaZ 4ܪ[-'BBRP̛*y+uvg!B#n;MG4Zly\Ѣ瞚-Sӟ-5#%_v^QdRPDZTRR OԵ@*(AWE],RIR57P&?2oƐ(~#FLg5=dF#zvL;mf&,mXJ[a # }R:%e-vvS=U:霾es endstream endobj 166 0 obj << /Length 194 /Filter /FlateDecode >> stream x3331V0PaS SsCB.S I$r9yr+p{E=}JJS ]  b<]Bc``D@.0L1S?UB7@`JJ=SP (<9P@=mrC%hAC!@ y`> stream x353R0P0bSCSsCB.s I$r9yr+s{E=}JJS ]  b<]d `6`RAI68؀L2`%Hv0)"G'!P5Ⱥ AJ$ `G@%\=Mx endstream endobj 168 0 obj << /Length 254 /Filter /FlateDecode >> stream xڭѱJ@?l&yM"&`p` A+ :--7`kMg+ & XKf]{t\)pp{ =SuV=UvT]j__Z]>5(6S`-̗oնd IS03aLlB".!1Ox&pcJ&HۅrI)ܔ_,v0{ltT颧 endstream endobj 169 0 obj << /Length 125 /Filter /FlateDecode >> stream x333P0P0bSKSsCB.SS I$r9yr+r{E=}JJS ]  b<]?T b78) s)hb y.WO@.!7 endstream endobj 170 0 obj << /Length 106 /Filter /FlateDecode >> stream x3ԳT0P0aKSsCB.#3 I$r9yr+q{E=}JJS ]  b<]acW3v\ endstream endobj 171 0 obj << /Length 243 /Filter /FlateDecode >> stream x]J@Yr̡@&A[sjsɃxj= Qj(y=HДeDz~,//Ue7~_G8"Ǎ;ΟGΗoKWn6^D8I F"!:+2oa[87`d`+hLMfp&byiguf0~5jRryd* Sk_ N9Lxods-5P endstream endobj 172 0 obj << /Length 140 /Filter /FlateDecode >> stream x35ԳT0P0bKSsCB.S I$r9yr+r{E=}JJS ]  b<]d3 eR/i& 0 d`L?`@!\=Afl endstream endobj 173 0 obj << /Length 244 /Filter /FlateDecode >> stream xu?kP{<0p '% ur(vtـ]G|X#y=8. [~< 8:İ˵W|Ք.1wQ@jH>yo瘣1 ý 8hFx]*18yTB,a PM 2< fep\$I5+zG4VY5D NZ@fW'coQ! endstream endobj 174 0 obj << /Length 243 /Filter /FlateDecode >> stream xUпJ@/.0fMN?Sge!VjihkR\AKT֩$EuwM1f``w%=.>jRWRkRnKO/VSYZR7T@fm큼0 {düۘ=4]L3Ȧa@bli@T|`MLjb4L1dtFW$G *.|ؙtI6Dc endstream endobj 175 0 obj << /Length 239 /Filter /FlateDecode >> stream xڭ08#^@D'D::htGxWm~_LyxJsNgo(I5M7?/&~I#K CԼ*x1F%)dB 񑊅A8EjGU(Nk4, ~j}> stream x3535T0P0bS#SsCB.K I$r9yr+Xr{E=}JJS ]ry( , LS? 0adT Y;PCuP7 .ĵ'W K endstream endobj 177 0 obj << /Length 221 /Filter /FlateDecode >> stream xڕѽ 0𖂁#x/i*U ~I(}JK "&HrtF*8 q0Y Ȁf4  ״ 2o@.08BDu uf,HW lf(ze~ަ_Q@6+L6elZv,XKP~EԺe֩N=v< endstream endobj 178 0 obj << /Length 256 /Filter /FlateDecode >> stream xUϱN0 )K~h{=B @!Z̏F%Psw|J8êt0r^jE>U KWk=?ܻbuyJz_uEk?ƌ!fl#>3Z;@'7x &&ȖNm9R0!G/aEFD+E$ьMX^>a-M=:upǴ-i}GA^{sywָ+=# endstream endobj 179 0 obj << /Length 150 /Filter /FlateDecode >> stream x3Գ4W0P0bSsJ1*2" Fr.'~1PKW4K)YKE!P E?<@0g`A bP>T*L`)`J+F Hʃr Wr endstream endobj 180 0 obj << /Length 240 /Filter /FlateDecode >> stream xm1j0g1> stream xu1K0W v8b vtr@?')ΝCMHH^K^Y/PX.8\> stream xαJAYL"y.p1bLBASP=p2E8n@,ofgɌKWR+s8 5srzJ 5W7Y ~k%vTZ^{cٳUoC0˖*STB`ζ&%EQ0b43e}"_馡}l endstream endobj 183 0 obj << /Length 204 /Filter /FlateDecode >> stream xm; @ . Vf.1L!he!Vji(X({8Qښ}i<"Ńf{Qj{T3Qes:.{TŘ4 5E&6%/_x/PAP02g0yp&dBw:+0}ATyM6Ӣ5l.5iK|T endstream endobj 184 0 obj << /Length 198 /Filter /FlateDecode >> stream x3134V0P0R5T01V0PH1*21PASKLr.'~PKW4K)YKE!P ETD0S$00|`A; 00* ?8Q"I&PMb`߁q ̍:]'W ckA endstream endobj 185 0 obj << /Length 182 /Filter /FlateDecode >> stream xڍA `'?(   AZDjX.̣y҅Tcu 7f: 5P L % MBb%_/#jƒ&Ύ҄Z{Ue5TƩ-ՇW6j@-OӉ;*`{^[bTd7 wSZ= endstream endobj 186 0 obj << /Length 198 /Filter /FlateDecode >> stream x3134V0P0V5T01Q0PH1*21PASKLr.'~PKW4K)YKE!P ETz !HԱ` |P=iu D)ph<krF=A?0`> stream x]1 @\B/ 8M(+Tr!bI q23;9nvdC)lGUgwIBf6$32d@fr@&m)2ϩ\^sϵ2HQRQO5QJrh MTrL@V@ endstream endobj 188 0 obj << /Length 141 /Filter /FlateDecode >> stream x3236W0P0bcSKCB.# I$r9yr+Yp{E=}JJS ]*c<]70| C`003a`\=&[ endstream endobj 189 0 obj << /Length 237 /Filter /FlateDecode >> stream xڍJ1ƿ00 v^@9Å+T[}> stream x3134V0P0bS CB.C I$r9yr+r{E=}JJS. @-\. ?&iNa`D~700n?D䇁$7 \\\y endstream endobj 191 0 obj << /Length 122 /Filter /FlateDecode >> stream x3230W0P0aCS3CB.C I$r9yr+Zp{E=}JJS ]  b<]0@A@8~? q0\=(CE` endstream endobj 192 0 obj << /Length 150 /Filter /FlateDecode >> stream x3236W0P5Q54W0P05SH1*22 (s< =\ %E\N @QhX.O  P?`E6?gc?P~.WO@.W endstream endobj 193 0 obj << /Length 196 /Filter /FlateDecode >> stream xڵ1 @Еir3'p.#BBRPQr0E:? d37u.{ʧHrCqJzƁGz$15x2`ts [R?L3؂rkm;x3HKv@%.oԐ nn**ɍ@ÔDr endstream endobj 194 0 obj << /Length 108 /Filter /FlateDecode >> stream x3230W0P0aCS CB.C I$r9yr+Zp{E=}JJS ]  b<]?0! ̃`qzrrƂQ. endstream endobj 195 0 obj << /Length 177 /Filter /FlateDecode >> stream x33R0Pa3scsCB.3 I$r9yr+p{E=}JJS ]  b<]?`@=:773n? Da`N``` O7Nszrr#߈ endstream endobj 196 0 obj << /Length 147 /Filter /FlateDecode >> stream x3134V0P0bcsCB.C I$r9yr+r{E=}JJS. @-\. ?00`D~70n?D䇁$0I.WO@.e% endstream endobj 197 0 obj << /Length 188 /Filter /FlateDecode >> stream xڍ1@E #0e6 &naRK v9GTd)HN^f̦ǚ95(EqߜR{cRkI ? ldM*H&g8^WSQdHVR!J*- i~ nN/ookg$AH> wlzZIK endstream endobj 198 0 obj << /Length 196 /Filter /FlateDecode >> stream xڝα @ HByuj;:9::(>Zp"]qQ |CB?2ܓ1G!#I:Ramd$V$fO"tٓH$R^K6ʯ\UW0/%>T5*4hy~> stream x31ֳ0R0P0V54S01Q06WH1*21PAScTr.'~PKW4K)YKE!P E0a<|?`0?> stream x3635R0PacCcsCB.# I$r9yr+Yp{E=}JJS ]  b<]3P?n3 ~o0ah`?PszrrjF endstream endobj 201 0 obj << /Length 195 /Filter /FlateDecode >> stream x=αJ@Xf x{`TSwZ * W6`"8%Gf|q~K.4pR^j<> stream x363T0P0T5T0P05TH1*22 (Ads≮=\ %E\N \. ц \.   W  @ @,?(fQ 0pC sC3=;?f.WO@.uH endstream endobj 203 0 obj << /Length 153 /Filter /FlateDecode >> stream x3134V0P0R5T01Q06WH1*21 ([@ds<L =\ %E\N @QhX.O `J`pB`왏I@.WO@.1c endstream endobj 204 0 obj << /Length 183 /Filter /FlateDecode >> stream xU̱ P#k[WJ' rjj Ɔh>`Phj @ B\Q#HEldȗ$"Sg3:.{|LVkRj_ ..X ,g0i) <p&A=j|c(vk]b=(ԿOI |F? endstream endobj 205 0 obj << /Length 233 /Filter /FlateDecode >> stream xU=KPs Xxv(zb`A' Q|A7|~Lx`7UN?8g!Aj"z$r~nhdHڙdrO/$GcHN* WUP6Aߴ45q " bx%tq_cGŲh;L t5<fOk2|+ZlECd(IBY_ endstream endobj 206 0 obj << /Length 210 /Filter /FlateDecode >> stream xMν @ )(> stream xUj@Yi nZ$sSEGQ|x I;=F(N8^D!qiIs ǔB3I-1QYAg//74gZv* 0ÿ+]SCE@QsϰF,IqSn/'gCb^mmjg`1'>ڟK endstream endobj 208 0 obj << /Length 188 /Filter /FlateDecode >> stream xڵ1 @EH!L#d.ͺB` A+ RK EBbGRRl6Pt+ǬƬ5$Ii;Xf$#aI,Dv$f,I(K~ |[jWopG!SE /zO6x+ӸY~uд` endstream endobj 209 0 obj << /Length 121 /Filter /FlateDecode >> stream x3135R0P0bc3SSCB.# I$r9yr+Yp{E=}JJS ]  b<]0001; aX*6T?0'W N endstream endobj 210 0 obj << /Length 228 /Filter /FlateDecode >> stream xmαJ@o"0M^ป'pWSZY `eh>J+5E~;Yct_^iC-/+9u'Zst }{} ,, %s'l"aAZқMY'W Tc| endstream endobj 211 0 obj << /Length 235 /Filter /FlateDecode >> stream xu1N0ЉRX`3',ZiY$R AE GQr[0"OʌǓ/^ҟ+Vɾݭ%+yxb>F:iy-29Q EPE6fLV&b&e6fՎY (y/ifU _ cBԨM>y2_ |Ǜjh endstream endobj 212 0 obj << /Length 226 /Filter /FlateDecode >> stream xڕϿjAna s=b!j WJ!`R nGG8̜EH:_1;dySpnyΟ9)_6[d?9oR&[}";YL9#;e銊Һ„pQ*+j .+xs7xĕ\ }rR /:tKuNTc'ې'jiT2Dׂ+X endstream endobj 213 0 obj << /Length 243 /Filter /FlateDecode >> stream xmJ@O"p}dXW0 j)h()SDm>{uuVZjG+9}Mjag"VNbkx|JV+-*@ Ps&[ D>#E@rI~2> stream xڕα @ HB}Ѽ]`A'u(GQ|TZ?$w#3ihdȎhC!s8cТZp*Yz?WS2f5wHPQY 4a:B@ 8 1n -SQR-8 d_Ѯ+J_> stream xڕӿj0q%C `*B]WC:Nm-vG#dt&?RiD ~i]_\V;WzG*I꒚M dߑ%)YRtZ@m^HwYmVaܶbN4RbXMΔ\uNnnb| mbީLE捴]$ⱱ7!3ilz.2Ob'z>уt!򸴏97 טC.k&) 7Lʬ k ͹!!KkK!#ܥm<Fk(4J@?mG/c endstream endobj 219 0 obj << /Length 338 /Filter /FlateDecode >> stream x͓?N@gC6QڸHaRK vF8%^0 Z-;;3|qvrXЧhsJL6~Em*iS^o*\R[}OT@WdR;Ȉ,QG9Ci 7rXK0A@$s;:>GOÔ11PVGG { r(ܑ  J}1*7S($;SheIL>oC^fi0ӤIΧ C4qHGnJ谬cC +{7Z۶> ࿢*E!en/ endstream endobj 220 0 obj << /Length 325 /Filter /FlateDecode >> stream x͓N0 @PK?h Hכ*D$02`~J?c&rNldH^؎{U.+,p'%ΰ:ޠ%On _ K,!C#44~d32DCĚZAO3%,Fb= _&g2dFLdt^c;ȓhMZE=p8}ډݴ1Mt=[liq<3Mu;oϚ0qfUȱ:ؠqZwѻ$D#BHI!ihD W xkD endstream endobj 221 0 obj << /Length 209 /Filter /FlateDecode >> stream xڳԳ0U0P0b c #CB.s I$r9yr+[p{E=}JJS ]  b<]8J,fn0ªc5CX@Y bGb}e1ce H,ln~ #BBP`pb~Y 0SFY䱠I'W T4# endstream endobj 222 0 obj << /Length 290 /Filter /FlateDecode >> stream xڵӱN `H&GJkNM3NIM{4"Rȍ%) ~ٜoK<+>Lcuz^aہxĦqkAtwb{%>X> stream xڕJ@'LsL 'BB> stream xݑ=N@FJisX[N"GTPR; 9BJGZ0; Jifw<~EqUQAg9T )fT3j4wTN\IM}MoOhf7s,hSv`ځ_ hv= {H 񞡱B [r%kT3. 0=;  ڿv>;bC _\Af #c,'4/+;hq1h?7p% endstream endobj 225 0 obj << /Length 243 /Filter /FlateDecode >> stream xڵN0/`?BdS` Heꀘh XI-#d`stgۿ~Iy)x 5_XQ&oG\7vWEF<z{O5 Tb!ȣO!2J`@;PP<;Gg3E9c̈*l09t / inm';)),bߘ^Jq݂zlgF endstream endobj 226 0 obj << /Length 253 /Filter /FlateDecode >> stream xҽN0T"GȽu~n! & 7+Q!ʟĄd嗋l4\jU<sMo4HQ {N^Kls/dKɮꑚgʱw_ s=$p8E . (sׅ42*ȱ| ]6&ܴLpڋ_IHGN!X>] 7#f".F?^Q 3ҙ b= endstream endobj 227 0 obj << /Length 244 /Filter /FlateDecode >> stream xڅJ1g"0M!`Dy[ZYZZ(ںy}<•aǙP1|?IO :1H=>cTPc;Ocw!^_[^ʙ;V8?dmgPj\Rq :dĄ* |Vbn;gE d1o( ؁ahDBc!D[o1En %in6N:\Z` æ]H_I<?y뭜 endstream endobj 228 0 obj << /Length 175 /Filter /FlateDecode >> stream xн 0>B L*)j3:9vtPtnG#8f:M|~3z> stream xڥ?J@'X&G\@HBL!he!RK E֛L2ɮ9o[,Ƴw565>UU7v1.tqoYKtq ˣ|QђCDF"RcB|&;J e%wpU3B?O|G(^'f ]THد|X9/O8E.> stream x3635Q0Pacc CB.# I$r9yr+Yp{E=}JJS ]  b<]``0f+ɃԂ 0a@\\\٥; endstream endobj 231 0 obj << /Length 107 /Filter /FlateDecode >> stream x3635Q0Pac cCB.#K I$r9yr+Yr{E=}JJS ]  b<]0a\= endstream endobj 232 0 obj << /Length 232 /Filter /FlateDecode >> stream xҽjA W#>WZL+vrp!ET+ -vXqt;';됱j-->xsiNY-gOّy+#CYEI O$Rx%4DJʤn ׮UH@Y$߸Np⧤D@(Ax^ 9Eۄip xviC endstream endobj 233 0 obj << /Length 184 /Filter /FlateDecode >> stream xѱ@ & &]xHLtr0NUy{ጃ zw6d4JBGqlfiG{1+P)QEz@-ibc|!Pi ౮!`{.TV6ߡA_y48+po endstream endobj 234 0 obj << /Length 231 /Filter /FlateDecode >> stream xڵ0kHnЂ0 &2`A3<#02^KL%!_s{I!.qa@CT9 +@P% 7 v+@x0> stream x͒N@ ]uG_.!MBH 02<Gx۹F:.˓"J:lN錞c|,5<WO(m(KѭEGWbtK=b$(#!@5@oJ 4{aŌfJ`o}4.lO%wm_mte4](z`_TU` endstream endobj 236 0 obj << /Length 169 /Filter /FlateDecode >> stream x;0 t#' VbTD$02`nQzT dj20XY陞c+4xRps?aq@iA W<ix=   E^6ɱC:_:Wѫ}O_ /h m Ij^ endstream endobj 237 0 obj << /Length 259 /Filter /FlateDecode >> stream x]1N@4;ۊB$\ Q%ڬ\vY)yTk.拊57 UIJ/Kn6O\k*ybx[~|nXp8HDF#々~7'QȔ^;LKZ+45qj@.dtv!"ieh֔j]dV絳Su ?hgcfKxhGZ endstream endobj 238 0 obj << /Length 186 /Filter /FlateDecode >> stream x3534S0P0R5T01Q07SH1*21 (Cds<L =\ %E\N @QhX.OON2bH$;&=A$3?8HAN7PJ`$H `( E` qzrr:p endstream endobj 239 0 obj << /Length 187 /Filter /FlateDecode >> stream x1 @   fl1[ZYZZ(Zkyt {O!(VhpZ0(j. 匴F91J3FNPf4W.dI K#ZX+ސ8 w6 .n N<sUv848n endstream endobj 240 0 obj << /Length 252 /Filter /FlateDecode >> stream xڅбJ@YR#d^@7l 'BB+RgvE8X>Y؟/Η%YJyN^RaaB> stream x3337W0P04  )\\&f  ,ɥ`bƥU()*Mw pV0wQ6T0tQ```c;0D0I~0Y"I ?&D(I"\=VI endstream endobj 242 0 obj << /Length 301 /Filter /FlateDecode >> stream x}MJ0)YؖG_]x>.]W҅h=Je? گiftߟ ChÞ6 s/\knCs%ux^ߟ\s>k o@B,D'DdZ"-,-B/63"x甙k p7q|$pF暿 dL@AvZHFӬYM5k|,ZdIeb4j`Mg!@Tt`[Bͻ.A8Ew̕bԊW'bt7}t endstream endobj 246 0 obj << /Length 99 /Filter /FlateDecode >> stream x3532Q0P02F )\\@$2ɹ\N\@.}0PRTʥ(Dry(3773pzrr{ endstream endobj 247 0 obj << /Length 174 /Filter /FlateDecode >> stream x3532Q0P0SеP01U0TH1*2 (Cds<-=\ %E\N \. ц \. @`"j@&~ f0H@L`F؃ ! D4$f6a&I#$l0L  *@'W OF endstream endobj 248 0 obj << /Length 108 /Filter /FlateDecode >> stream x3532Q0P02F & )\\  ,ɥ`hȥU()*Mw pV(Dry(3773r - endstream endobj 249 0 obj << /Length 103 /Filter /FlateDecode >> stream x3532Q0PP0T01V02UH1*2 (A$s<M≠=}JJS ]  b<]` .WO@.E, endstream endobj 250 0 obj << /Length 225 /Filter /FlateDecode >> stream x}1n0 Ed0EG0/ ԡȔdР7 dPK#O'O *k!XnKVz>uөg^3e݋}N7Oo#XnkR 0,H"`nX,2d;F)ԃ"G ٦)eC$9َ}r9H>Gime2bֿɯꢻNǀf endstream endobj 251 0 obj << /Length 223 /Filter /FlateDecode >> stream xڭ=0 S1T#4T HbF(=BN1#2|QlSL``: Ҍ f}a^cstz=^NЀ`|U|+Q܏JfL5IbG|86*Um%1x(VDFN{ܙmw^{Ǜ)5xu Vϗr endstream endobj 252 0 obj << /Length 208 /Filter /FlateDecode >> stream xڕ;n14s5,r%[D ")S$"r4Gp`(RF}?i7> stream xڥ1N@Y478n- T)UL(ԛ,IdUq n#t-l#k&ĖH endstream endobj 254 0 obj << /Length 225 /Filter /FlateDecode >> stream xu1N0E49BM,)@T@"萒(9K. #3?pW=w<~(ё6[;ϝFOْSxϟ_dw7qB#h%^J"s-,&ï& M ugTi: d)ȧֿHee_3 Y}ETԼ4rs$jYh%t;#k} endstream endobj 255 0 obj << /Length 166 /Filter /FlateDecode >> stream xŎ1 @EH!%q1[ZYPUx!㎝Vd7<[W-SÉ@fޒYFLXr;)svdJ9{ %_@"-0*rࡐZ'pGb4"mz!IoMSK?7W endstream endobj 256 0 obj << /Length 283 /Filter /FlateDecode >> stream x}J@Hfa4]<Vr YlWX `D9-4oɿ3eP=յj隣{^u\\:ݙ{z|bu~*.r冻D6 !#"%I\(3}Cc{mPD߄%:N4@&qTDMK2v ;Q9(nhK Idvd="Т>y &ɹf{[ӎ N4:58x'_'/t endstream endobj 257 0 obj << /Length 178 /Filter /FlateDecode >> stream x= @ L2'pH-,J--ףy2ŒmkO1rX54])/ UԎ URvL,=&dk6>s]PFX`* tB &66aQְsdmN|*38w ]ZZ錀 endstream endobj 258 0 obj << /Length 141 /Filter /FlateDecode >> stream x3532Q0PbS3#CB.c3 I$r9yr+q{E=}JJS ]  b<]0000PX?Po?=``D xr "cn endstream endobj 259 0 obj << /Length 127 /Filter /FlateDecode >> stream x3532Q0P0b33CCB.cK I$r9yr+[r{E=}JJS|hCX.Oc`'\{0 ?0%\=Rm endstream endobj 260 0 obj << /Length 175 /Filter /FlateDecode >> stream x1@O75pD ,ZZh:JD<@J ˆbb%3򎃮i0f3c3n[6DM8eŠ8NDRrpEEVn4TKUT|(UBMҸHȿ(? endstream endobj 261 0 obj << /Length 170 /Filter /FlateDecode >> stream x1 P t*d |BB`A'qRGE> stream xڕ=@ #0e't$$RheaB5pJ 6&Wd^狔cy9ƹjzPRei.;-+RGN R[&U|H-+֤|Z3/PDx"_  {MءlQ5򃠳RkD0qM]Is Fk,Uel m*:9n endstream endobj 263 0 obj << /Length 235 /Filter /FlateDecode >> stream xڵ1N0EEirqd":K" * D ra8 j$\<̟|Ҷ9~JSJ/q]Ngr |y@T2bH!iY)0DI~B& #;NvWV #tb9w?1&쵹+'KUwι9mkQڎHQ*mAi7t-} endstream endobj 264 0 obj << /Length 172 /Filter /FlateDecode >> stream xڽα 0@εIG882:Ht>85g<G5oHYc\lːIN͌Od>"YJq&S"EE\-u׋p*X&.EZ7-}K7-^D_~417yi endstream endobj 265 0 obj << /Length 227 /Filter /FlateDecode >> stream xM=N0j K.Yo?)@[%h(pGH"1&+Ai4絻RF.x/~-O_yUì o[^fv'^TGnBe*TRUCQf4.,B"tF) F#a~̇ Lͥ2~"1e`9Cf1YD5- VM4kcЇA-ʭ endstream endobj 266 0 obj << /Length 177 /Filter /FlateDecode >> stream xڭб 0+ 4%q- ftr'>#t =/u AIn(ƚ!kxB%N_C!Q-$Ft9_Ռ$h+3;tA|y=8ނM?`|ҋ-xI ,vQOzxE:Vv܄#Jsk|jVmx endstream endobj 270 0 obj << /Length 208 /Filter /FlateDecode >> stream xڥ1 @EX t$ L!he!Vj)(rM\ ~}>wU>$]HYDQLbJX xɷH"ZMYVx@h egR4ah#Kju4ӒJ&YHrb`.j\+hcc%*t!AfM* endstream endobj 271 0 obj << /Length 207 /Filter /FlateDecode >> stream xڥ1 @EXS 8ͮ(VbB9ZRZX&^x hec5a㣤 jtLaLbJXV oD$N8x 0lX@/C7蔻B f 4VVkφcx}A#/k TZ;ƺԷt%E" }bS[. endstream endobj 272 0 obj << /Length 136 /Filter /FlateDecode >> stream x323P0PP5T02P04PH1*24(YBs< =\ %E\N @QhX.O9   fv6> $'W  ' endstream endobj 273 0 obj << /Length 95 /Filter /FlateDecode >> stream x323P0PaCKCCB. \.'O.p KLz*r;8+r(D*ry(177? 'W  endstream endobj 274 0 obj << /Length 94 /Filter /FlateDecode >> stream x363U0P0T0P0"CB.#3D"9ɓK?\ȌKCHx*r;8+r(D*ry(6#' endstream endobj 275 0 obj << /Length 257 /Filter /FlateDecode >> stream xuбj0d=A-pHRB;u(@19G#d`d |' 󟖋;}O5\RQ`ȻO}c~[zIc%a,D!Q$mbG2bWh*^jL/.i AjS]3}`qd;<z<ĠuH> stream xڥѽ 0ةP+AAAѹ}> stream xڽJ@ƿ%``  h`xp` A+@--|tv)-­WXZdow*;9-8㒏 >+1*R̸*gZ֔Sz-eJ~{}ty{9+Sb 頁Ș2ԠFJ -_5J5f҂Fvh4P"VeF T߄iӹ{ =#0s@7IMlVMts~!|.G9#٘0\f {qo@W5/XI endstream endobj 278 0 obj << /Length 296 /Filter /FlateDecode >> stream xŒj0OxܢGн@kg!M ԡm-@^[^[WI qUutqE+ z+̟00=}c~ =T`!gA@jT, 8_=eCAMF^ |:I *@=N` ڝ 垻ḱ69&>0s!of &jɤbu gϫC0IF)Zm* endstream endobj 279 0 obj << /Length 130 /Filter /FlateDecode >> stream x373T0P0b3K3 CB.31s<L=\ %E\N \. ц \. ? Ph707000c~4ȫ_4,q.WO@. endstream endobj 280 0 obj << /Length 112 /Filter /FlateDecode >> stream x3634W0P0a#3 CB.# I$r9yr+Yp{E=}JJS ]  b<]A~y) \=i endstream endobj 281 0 obj << /Length 258 /Filter /FlateDecode >> stream x}J1 ] {-(tdibVp> stream x3336Q0Pa3C3 CB.S3 I$r9yr+q{E=}JJS ]  b<]dEL0 JP 0QR(ڡfZ D}L1Nqzrr) endstream endobj 283 0 obj << /Length 252 /Filter /FlateDecode >> stream xڥҽj0p [hd`e3$)C 2@!!G3U?& w0 ,N=j7>FTҿUx4F=E_%\ᵀ=/ɸh endstream endobj 284 0 obj << /Length 289 /Filter /FlateDecode >> stream xe;N@rai=`;qѰR.@T@I.J|7a҈$Ci>˳؝I}^M iI/y78K6'of֘)nb-}~|bvwE)XQd9!a"[d72EW:,wX=0;rؙnW-WzUR,k9M<Iz:HxDLՐc|c=1;2؉^]Aĺ7_lo'kH;tۀ_"=\lhsoW endstream endobj 285 0 obj << /Length 333 /Filter /FlateDecode >> stream xڍAK0 ^{6LSaNAODGaRAaԉ.x ?dJg9*9g9Цӯ'9+ezӉL/h[%=tvuLx0ȶ `ka5@!F֠%~ CnɱCȅsZnpIm1u2c!/Wܣ[P `Q P{&{6Gq.L!qvNCQ&yи7> stream xuϱJAba yh+RPK E;1 tƽpS|?;?xžjs3TC=-r+SrgkkrKyrM͒a{ծlB-`a:`u)xuwGW2&e˯ɦnh huaǨk} [ bԪob"EzONoɌla endstream endobj 287 0 obj << /Length 203 /Filter /FlateDecode >> stream xڝ 0OKдv vtrAPGAEA0G#8:ANȹ-Lp;"dJ Z_V[UglJ#IWc>NҽIs-0pu@܀_x vZհu/{#ҡ^EA^UzN4 E A2;Wa V4'VhLr endstream endobj 288 0 obj << /Length 212 /Filter /FlateDecode >> stream xڽϱ0$7 x/$N$ &:9'utf,ƣ Fp $K8q b~bNe/DF4AFGi[?2%72byg6Nh:]hBQ֩L)϶?$nId[XmFiǞzՊuA63` ^j endstream endobj 289 0 obj << /Length 210 /Filter /FlateDecode >> stream xu1j0g<7 41'z(S$ MHXGQ|JW\(T 7uN3uki1}.Gq%Cf&u#U])Yϧz\R׹fi WOp_PI! I@*#f%#~,K{ǏT#,ΰq`(nYsLޖF^V2 endstream endobj 290 0 obj << /Length 156 /Filter /FlateDecode >> stream x33T0P0bc3sCB.cc I$r9yr+s{E=}JJS ]  b<]000```!$T ?h A30c T" h2FG&\=ak# endstream endobj 291 0 obj << /Length 275 /Filter /FlateDecode >> stream xڝN0?+C$/~ @pKV*E"L02`ȣD`7я$7d*:}$ X endstream endobj 292 0 obj << /Length 167 /Filter /FlateDecode >> stream xα @ ;:'zx: 7:9: *:{G;s]!3pck8YǸh PsNA^/r9E l BuL[VeTɎdÞ@`_wV| 䈚 oafaosK endstream endobj 293 0 obj << /Length 125 /Filter /FlateDecode >> stream x323P0P0b#S3sCB.#C I$r9yr+r{E=}JJS. @-\. ? :  .WO@.P endstream endobj 294 0 obj << /Length 220 /Filter /FlateDecode >> stream x1@`CW ,I0Q ne!V*Z'7J+)Shfe=1fOA2∇n'MxӞ#슓U|<)dg9P1csK^4Ї g Z7-Vj]p azկTP)*ܨF7́ ,a 0@ A/vP`iCiyA_ endstream endobj 295 0 obj << /Length 110 /Filter /FlateDecode >> stream x323P0P0b#S3KCB.#C I$r9yr+r{E=}JJS. @-\. ? C 1cqzrrp^ endstream endobj 296 0 obj << /Length 203 /Filter /FlateDecode >> stream x=@H\@ȜM B0X({+ba8垫|>2Pԏ~?Ѥ$|@jRRod5Ԍ;*gX@l$u8lSyEȞn!X#xiTCƩFHjODO'0vBJ#n $"&ݏ endstream endobj 297 0 obj << /Length 159 /Filter /FlateDecode >> stream x3534W0P0bSCCB. HrW01r{*r;8+r(D*ry(0a@R` `$@z ɀ a/ m?C&\=?qjS endstream endobj 298 0 obj << /Length 209 /Filter /FlateDecode >> stream xڝ= @GR2MtbSZYZZ(ډr2EH|((v̛ݝGa_ endstream endobj 299 0 obj << /Length 218 /Filter /FlateDecode >> stream xڭн0 p[*y#4"t7p  }4бCHpH'n[~8{`zz9> stream x36׳4R0P0a3CB.c HrW06r{*r;8+r(D*ry(0`?l(g?6g u@lC{ pP endstream endobj 301 0 obj << /Length 213 /Filter /FlateDecode >> stream xMͱN@б\DTd""R.HE) h!kfg:[\ꗺXS)Ks"Z;׌oY2=7Ro0ͬ&a8YZi4 %:1X[z83L̺E[y!8}?+O2dWtm8 \\ղuY endstream endobj 302 0 obj << /Length 160 /Filter /FlateDecode >> stream x36׳4R0P0R5T06V03TH1*26PA3#Lr.'~PKW4K)YKE!P Ea9$luPفX$N#Ccagc{  00?r Jm endstream endobj 303 0 obj << /Length 162 /Filter /FlateDecode >> stream x1 @ᷤL fqC@Vb--+'Gˑ<@Ⱥ!X l3pjZ>DŽm:L#c^[z?.6 6KNJV- -reByDz 7U}`(D,uxI0nҷWR hhKob endstream endobj 304 0 obj << /Length 236 /Filter /FlateDecode >> stream xMJ0?0> stream xeпJ@o \`^By]  @-G̣R^w]9 Opj8>xPS5ZOLIppu%?^^qDzŷ;JW\ׅˡ~ lr&Vg{'´N2;s8Gvn=ЪQob]pл ~^8:g007~ʞJT Ͼ4sM^!yJ[X' endstream endobj 306 0 obj << /Length 207 /Filter /FlateDecode >> stream xڽ P FҡмVn?`A'qRGE7f}>BŚނ*3$|9VuQۀ}+5͞1%kTڤ|18Ux*%V738 \A&rOP deyܿ>X ?c\%#'q(IfNĴ) endstream endobj 307 0 obj << /Length 131 /Filter /FlateDecode >> stream x337U0PbC33CB.c# I$r9yr+q{E=}JJS ]  b<] >00013 A9 CaՓ+ t^@ endstream endobj 308 0 obj << /Length 259 /Filter /FlateDecode >> stream x]J@Of!"." E0pA.Z v |˝gH0??pNNmnҮwYUϹ勧7wk"nssa q[{_AꭅBaD4%;>#p{%*édlW]HO˷df 3ÂױtK҇FoMfl=o,"E"pLΉ~WhFF*4& !3DWZnvj endstream endobj 309 0 obj << /Length 206 /Filter /FlateDecode >> stream xڥj@@CkB  A GAẸMb/hffӱZ'd?$u{<l(潽x3\h*fTK> stream x34030S0PbKcK CB.  I$r9yr+Xp{E=}JJS ]  b<]?@b00172? Dʼ,MJIR endstream endobj 314 0 obj << /Length 287 /Filter /FlateDecode >> stream xڕѽN0> stream xڵJ@%4y˼nn p` A+ J--PB\_SE;%_tB=ܵlkouLn}{ ?T\n0`Bh§"( v3,rV (R0(Z1̾?^3A RW^SML j3)0}1F3f liX6e*yX i}lM󣫖 S-zY endstream endobj 316 0 obj << /Length 290 /Filter /FlateDecode >> stream xѽJ@YRyM̝p` A+ P,& Aȸϐ%GǔRFtRN2ڹ{{\$\1/)n4 ܵ0C v-0ypiVp-PL"(JvWU+ov-cDgU7({_`7'4 lÅmsH/@םb'۸^UbUVlA1J1vހg9^[9^ endstream endobj 317 0 obj << /Length 267 /Filter /FlateDecode >> stream xڝJ1'lq0޼fpVb]hy}-86L /;q5%QwFO-kHfr;r +ZoyaC 2i寙5z>%k<&r,`vd+q3ߒ1^+ \oxE<@G*q/|Aoٸ=,8U(`ش fA-pڟڤPj"{mI倷YR endstream endobj 318 0 obj << /Length 182 /Filter /FlateDecode >> stream x3134W0P0b3CCCB.#JrW01 s{*r;8+. ц \. @? $|@H3?D2I?`dT!?0ȁ ```! i? P$\= endstream endobj 319 0 obj << /Length 351 /Filter /FlateDecode >> stream xڭJ0ǧȥº=z =umr!4LRuDg^W4;(M}h-ԣKCQ\jժԥ*NѮ̼<ޫbu~lX)U6_GzahB t ]2G6Da)hrcfEA1-?pλճ I}҈6ĥPgOn ܘ'+tc036u! 蒡AM"9%} |H=X9ZHv]ϽmE=LQVgq)ϜRT7D]n cƒ|M'b<%NZu>v endstream endobj 320 0 obj << /Length 142 /Filter /FlateDecode >> stream x3631R0P0bcCKSCB.#1s<L=\ %E\N \. ц \.  30oAr 5 T @;af f!`` ȘՓ+ > stream x3631R0P0bc#CCB.#3JrW02 s{*r;8+r(D*ry(070o`G1 d endstream endobj 322 0 obj << /Length 207 /Filter /FlateDecode >> stream xѡ0[*#pO@@ %0&H@! $h%#L"uDKzz٢"\1CtAݓSi֫u{СuB U|0ۀؖB%/Q@Px_Qv؁ʲ#rO ^7\gpx'A~^ɼP/nC|U endstream endobj 323 0 obj << /Length 249 /Filter /FlateDecode >> stream xڭN@ }K!~5*1#ܣQ3T9l Iɾ5TUEš^+:pP3/F *-=UT>cKxii$@v#W@!'=r48 E\)GC B1:6b:wZK??"Xi=1wfbpY4?]e[t~x# endstream endobj 324 0 obj << /Length 185 /Filter /FlateDecode >> stream x? P ,dМVt* ίGQzN:xȗ@ iDrj* CDJbCbqNjILjn߮#r)o̙-S/XSeFԕ+^+k۪d%A3vX}X~ö"7iӊ^Ds. endstream endobj 325 0 obj << /Length 281 /Filter /FlateDecode >> stream xu1N0G\o$"-D $(PR[mr⛐#Lvq v '33n"O'5sj<=x/5j֝){S^˵)x|1jSn衦t8z[d yDbDΰt=ZbM΢yqPje^5X*>YY:#BIj!MlG-ƨH]$?r>Pc6A٠~I"vfD7(0l@/]3wׄ endstream endobj 326 0 obj << /Length 191 /Filter /FlateDecode >> stream x3531T0P0R5T01UPH1*21 (XXBds<L=\ %E\N \. @b<] @>dF"ّH~$RLڃz0D2I@D1aL``n@'03H~`c1(l@A(8\=~@ endstream endobj 327 0 obj << /Length 203 /Filter /FlateDecode >> stream xҿAr $7/eQII\!R Q,'s0eQ"ܟ3?(%V U Вn(6Y4n+|א<>ȭh\ E&tj8 endstream endobj 337 0 obj << /Producer (pdfTeX-1.40.22) /Author()/Title()/Subject()/Creator(LaTeX with hyperref)/Keywords() /CreationDate (D:20240501011522-04'00') /ModDate (D:20240501011522-04'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.141592653-2.6-1.40.22 (TeX Live 2022/dev/Debian) kpathsea version 6.3.4/dev) >> endobj 2 0 obj << /Type /ObjStm /N 70 /First 585 /Length 4031 /Filter /FlateDecode >> stream x[m6_UoĖkd{YCu{$Fh&{WcB wt?O6J+VAUR&ieS('UZe"~"j43U()*g/"rh7O^jBggEZ"SQySP!aFRb]4up^%Q[?U+Z6hm%>s1\se#'lr\Ӝ|AcKa6O]y]#YXA>FϹɛh٫W?\zz՘ƀ+7' ÿN֜|dɖ+ur/n_= :sZߕvے,KYmKnYb`!,Zo+^WUo֫]m\qo߲͢.fH ݦ lVzZ<22s5;C?grsի>/o1GaN&­8')Zeu-5>R5vF:N۳p|XD8@"gH8ěM?g{;?&<O>qœԟ6/E~^]58֚^wSY?#|o_Wru޸7ory SҺrz]o?*ڏ载[[B_?kXvlo6_vv,wo_fn|&^/1vm(u`v/|wfnso{?_.׃N,9O~8$'ۖvandYn4myUq"4\;2]bîmt&}Ts?+`Zpc2? a'"u n!"e5Ԃ0lΝָF,NBαm!y\- (Ֆ)|9&' g AKt愻0܅.2cq\N"'̂!?($SDkVnDacviwLybS;-7p{c]0 .78 Snm1,ƀϖR{(3`[fԷЕ hvO:4!OQ>Ч*o$mE8VZnӉ i$ΤdYg2Ot">5z0Ih ǩ4ILucqh2$xwubiFr3.'C/޿Rj4__P[[ɢc'yAm#?Zmص-j"VfzhU%_O{!:G\so CgbNY# }R~~w>(- qR_'1/n)q ~^p^:LW) 4y(nFOG:8R80AZ U:c +tưܖ'R3 :>&G=)t&;a{":Sj|dw~bGuMvG3W]}&Va'o\vtYumlԤ1NZ299|A?6M.N1M=>1jecNG/3c!Oӊ,vOe]=nzKo9=~߄+#kbW̟c smظ1N ,0(#Oށ0 h1f}ς9U~SFW,וCls4|||,Ic]DB,I7Ȓt,I7Ȓ|jD\tNA7my-lrm\q,jbS*_qj'vzo_;hn7}Tv;َkyvnٽT?vاݒN۱{FK50R·˻hr9H{/GeQE2pv=2[D޺f߮ofL'AGWn'տ[__}j!_S endstream endobj 338 0 obj << /Type /XRef /Index [0 339] /Size 339 /W [1 3 1] /Root 336 0 R /Info 337 0 R /ID [ ] /Length 991 /Filter /FlateDecode >> stream x{|UgmY̘2\v)La.ERIȝ\s斔H$Hny(d޿qs|>8Ը9cVV諮*L E QKx /-wE-"Y񢕈i_Mrh(|^'ᢑ9ծy"P`bN:ǜq̂ǏBN{``< *mP;`7Pxa77QeI5s)b10l _} %֨О+7Ky Fyh_cjVc'ፓ0.„dx'yGvû0U_a^H0k֮L`t\/LD, g`$eJJb7aXCy*/MXk6gY>7އM[ap48b=l۴J T^̎tyv]b|ػ _~W`88VAVáxV NG~p~򁟕# p<UP5Nxop2Q܅pZ{9ΪVyuJ^T pIS.++5pU5 y꿛Juɕ+̹${PC͂-W_PKx&·y3w͏ifCr^DkhHA9Q VBCHGϚrYDj^sZޢD kmy1 \&E[؅ ѱ&fZxHZ m3y*)\IKBCЩ3Qƒb]x7%]2 !!.=̭aփw=))ݰǪA}SCa9׏"[ɮc)"ljyZ<_/Aap% Ѻ<#4Ċb/pE :N&EYfhO endstream endobj startxref 97030 %%EOF pcaMethods/inst/doc/outliers.R0000644000175100017510000000340414614347753017413 0ustar00biocbuildbiocbuild### R code from vignette source 'outliers.Rnw' ################################################### ### code chunk number 1: outliers.Rnw:59-60 ################################################### library(pcaMethods) ################################################### ### code chunk number 2: outliers.Rnw:62-67 ################################################### data(metaboliteDataComplete) mdc <- scale(metaboliteDataComplete, center=TRUE, scale=FALSE) cond <- runif(length(mdc)) < 0.05 mdcOut <- mdc mdcOut[cond] <- 10 ################################################### ### code chunk number 3: outliers.Rnw:70-73 ################################################### resSvd <- pca(mdc, method="svd", nPcs=5, center=FALSE) resSvdOut <- pca(mdcOut, method="svd", nPcs=5, center=FALSE) resRobSvd <- pca(mdcOut, method="robustPca", nPcs=5, center=FALSE) ################################################### ### code chunk number 4: outliers.Rnw:77-80 ################################################### mdcNa <- mdc mdcNa[cond] <- NA resPPCA <- pca(mdcNa, method="ppca", nPcs=5, center=FALSE) ################################################### ### code chunk number 5: outliers.Rnw:88-97 ################################################### par(mfrow=c(2,2)) plot(loadings(resSvd)[,1], loadings(resSvdOut)[,1], xlab="Loading 1 SVD", ylab="Loading 1 SVD with outliers") plot(loadings(resSvd)[,1], loadings(resRobSvd)[,1], xlab="Loading 1 SVD", ylab="Loading 1 robustSVD with outliers") plot(loadings(resSvd)[,1], loadings(resPPCA)[,1], xlab="Loading 1 SVD", ylab="Loading 1 PPCA with outliers=NA") plot(loadings(resRobSvd)[,1], loadings(resPPCA)[,1], xlab="Loading 1 robust SVD with outliers", ylab="Loading 1 svdImpute with outliers=NA") pcaMethods/inst/doc/outliers.Rnw0000644000175100017510000001203114614231101017727 0ustar00biocbuildbiocbuild\documentclass[a4paper]{article} %\VignetteIndexEntry{Data with outliers} \usepackage{hyperref} \title{Handling of data containing outliers} \author{Wolfram Stacklies and Henning Redestig\\ CAS-MPG Partner Institute for Computational Biology (PICB)\\ Shanghai, P.R. China \\ and\\ Max Planck Institute for Molecular Plant Physiology\\ Potsdam, Germany\\ \url{http://bioinformatics.mpimp-golm.mpg.de/} } \date{\today} \begin{document} \setkeys{Gin}{width=1.0\textwidth} @ \maketitle \section{PCA robust to outliers} Away from often showing missing values, Microarray or Metabolite data are often corrupted with extreme values (outliers). Standard SVD is highly susceptible to outliers. In the extreme case, an individual data point, if sufficiently outlying, can draw even the leading principal component toward itself. This problem can be addressed by using a robust analysis method. Hereto we provide \texttt{robustSvd}, a singular value decomposition robust to outliers. \texttt{robustPca} is a PCA implementation that resembles the original \texttt{R} \texttt{prcomp} method, with the difference that it uses \texttt{robustSvd} instead of the standard \texttt{svd} function.\\ Robust SVD and its application to microarray data were proposed in \cite{hawkins01} and \cite{liu03}. The algorithm is based on the idea to use a sequential estimation of the eigenvalues and left and right eigenvectors that ignores missing values and is resistant to outliers. \\ The \texttt{robustSvd} script included here was contributed by Kevin Wright. Thanks a lot to him! \section{Outliers and missing value imputation} The problem of outliers is similar to the missing data problem in the sense that extreme values provide no or wrong information. They are generally artifacts of the experiment and provide no information about the underlying biological processes. \\ Most of the PCA methods coming with the package were not designed to be robust to outliers in the sense that they will converge to the standard PCA solution on a complete data set. Yet, an applicable solution is to remove obvious outliers from the data first (by setting them NA) and to then estimate the PCA solution on the incomplete data. This is likely to produce accurate results if the number of missing data does not exceed a certain amount, less than 10\% should be a good number. The following example illustrates the effect of outliers and the use of robust methods. First, we attach the complete metabolite data set and create 5\% outliers. We mean center the data before we create outliers because these large artificial outliers will strongly shift the original means. This would not allow for objective comparison between the differnt results obtained, e.g. when doing scatterplots. <>= library(pcaMethods) @ <<>>= data(metaboliteDataComplete) mdc <- scale(metaboliteDataComplete, center=TRUE, scale=FALSE) cond <- runif(length(mdc)) < 0.05 mdcOut <- mdc mdcOut[cond] <- 10 @ Then we calculate a PCA solution using standard SVD and robust SVD. <>= resSvd <- pca(mdc, method="svd", nPcs=5, center=FALSE) resSvdOut <- pca(mdcOut, method="svd", nPcs=5, center=FALSE) resRobSvd <- pca(mdcOut, method="robustPca", nPcs=5, center=FALSE) @ Now we use \texttt{PPCA} to estimate the PCA solution, but set the outliers NA before. <>= mdcNa <- mdc mdcNa[cond] <- NA resPPCA <- pca(mdcNa, method="ppca", nPcs=5, center=FALSE) @ To check the robustness to outliers we can just do a scatterplot comparing the results to the optimal PCA solution for the complete data set (which is \texttt{resSvd}). In Figure \ref{fig:svdPlot} we plot the estimated and original loadings against each other. \begin{figure}[!ht] \centering <>= par(mfrow=c(2,2)) plot(loadings(resSvd)[,1], loadings(resSvdOut)[,1], xlab="Loading 1 SVD", ylab="Loading 1 SVD with outliers") plot(loadings(resSvd)[,1], loadings(resRobSvd)[,1], xlab="Loading 1 SVD", ylab="Loading 1 robustSVD with outliers") plot(loadings(resSvd)[,1], loadings(resPPCA)[,1], xlab="Loading 1 SVD", ylab="Loading 1 PPCA with outliers=NA") plot(loadings(resRobSvd)[,1], loadings(resPPCA)[,1], xlab="Loading 1 robust SVD with outliers", ylab="Loading 1 svdImpute with outliers=NA") @ \caption{Figures show (from left to right): \newline Original PCA solution vs. solution on data with outliers; \newline Original PCA solution vs. robust PCA solution on data with outliers; \newline Original PCA solution vs. PPCA solution on data where outliers=NA; \newline Robust PCA solution vs. PPCA solution on data with outliers / outliers=NA. \label{fig:svdPlot} } \end{figure} \begin{thebibliography}{2006} \bibitem{hawkins01} Hawkins, D.M., Liu, L. and Young, S.S. {\sl Robust Singular Value Decomposition.} National Institute of Statistical Sciences, 2001, Tech Report 122. \bibitem{liu03} Liu, L., Hawkins, D.M., Ghosh, S. and Young, S.S. {\sl Robust singular value decomposition analysis of microarray data.} PNAS, 2003;100:13167--13172. \end{thebibliography} \end{document} pcaMethods/inst/doc/pcaMethods.pdf0000644000175100017510000117626414614350074020212 0ustar00biocbuildbiocbuild%PDF-1.5 % 39 0 obj << /Length 2658 /Filter /FlateDecode >> stream xڵ]6=2.f$"hMh%V Qᐲ* z{pH_>{/n2xeeQJ2^ffKr{0۝DrJ7Vn0j}ڛleswd7;^(m#:y?"%Zt;u⏦1n{Fs;:0x9b~cHy4M*gmh HS9~O~P rMR]#Ӽ9<f1!|ppZC+0 nL8"s،y%I09<ࣴL) j`Cʹ4M۪1 !$8zGԞ0;9@Lm冭Wǭ K8M;#q ԉa{PA=0 ۠VHT:G3d9lI# )߀)(H||& vMg[Qψ<b=:y4U= ^`JxL f! Z/3tuasD YЮ}@$ލk*C!KLHj3!z خϨEdͺt}M\3:6g)xVZkKs KIYdYYa/5* yGB1a0'S5[]Y }똉38RUېO!#*eqqU}~Xde,y5Қ%K- W!ԕ!hib0ܸ™+WrS,_'++YCƷb@u־)W!"TV.urXt> )pLgoI`aJ(Pdfy`kAvz'Z2@c; 0´7> stream xڍˎ8_2VKd\hmkZ8}ozQlEdU~ps^'Xq+ZQƪ\=V_x}QnC~{eXf*ÝVa˞^ߪ2 ;:1dqhyl횦ж6N0/ⲸH¢,RߚOvDL=qWk k4Uk=v4xXwG"d4c4`Pk֘UcÀQu 6U]kψ$"pptv׷YQsLW ?X!qUEsځs_4T,W&ICEL3# vkeevUoBgy vrgq}(OLW*R[V塊4S>Q RMb.$ qzr5c9\jjR!%%]ea'a* 8chȷXK^dn4 KJUY_d=i ͿQF~"AfkIPMZ/IL <;xYߦYvɚ6|+ 'ph^}^75qlq1{~6JDI>4qIU׶״F35e|JpLcv,60~X!ǴT&#_C$_oZ'@?1 mnUcq.i-N;$輫w>Zk?5w,nְ%'YRϔW+KFiUiA`Q uվaq2V{?: qyF!]A@*Eٜ>V̭q9b&l_3ר3Q9U5N 8 UpA(&y(|GZParCFxhÈzջpInu< )u@*{I0X/;BVTAǚL ΃@YI+?=_φT?:;"y_&Y3 ơw8Xvs㷵jk$ 6ѡ2ZbfY Id)lQ?H+C{94ÙDi2H5>"#?S#oq 4(Ű@8W|1˲S\境X>uU he~IU9G>9.X$ȉoۍ<`[>ET¦1k_\;q/ l爍EWp45NyふIm`s2G>TL*B9zdgF#LDq bͳ܏C1‟±y|=|`!&RT4J4.Kp2!/P29ŧ_2 gW.pj! 9ӽ)XN`HAGLw9wlzF@} tj'̳Ŝ_Sl$=MRK;/w0t[%00hپڀ*^<͈X6!t S~2ʾ뇮զ` 8m[ŎT1d[wΣv=$Pmߨ˺AmyHR  .CpeiL# D;)Wj o`\h4qC?R]Kk!sA4?y:;d/85'RF jVp^=8s-x*+ÊèyR }U,bɅqFN EO$J7KRkyO(G3XahvXS@b,D(ˢߗ M9IFomfEU(+cxG3W PQp=NJ8_AYf0V d/S`o%6yt'ǤrMۤ-PA=OXwl2%w"w$-?9*f?O ww,Y|N4BW.J?uW8l3ޓˤY-=Ӵ S\4jr=(~7vb\ib?.@#8v6hw6|0iƽ8 $jY<@-2O1a݁!uY.|nڧz;TF?_S^E* endstream endobj 88 0 obj << /Length 2090 /Filter /FlateDecode >> stream xuXK6ϯK ֈz+f:^lgk=:߯dUXUv ~j98+}}3H"> ~v̦ =k=(8|IY;;>Oe13L-1T$ӿ4HFʩH%?`ؕvr$c'x:ڎ&B>쭖!G&aVY4[1X$Bߓ>+Hgۙqbtb񁺾 CD%p32B~^P2]ZTݝ 4I0@ tn聲Md\, dA :8#r+ڳ!\JsYMNAb0oqM?8$_·R;yGW8xo%z#I v\ ]pI0t?nUB 뎍RK8eX,}`F6rD3"檸b*WD>pEk[Lx:Msp\a!PAZ>G$$4~$)"9*qGdp֬C-(JUH52.A ] Wb@&/$J{$,lW:E#89/ 7gN:Dr^4XeM~rh}_Wy:()1N&'ܖZSIKn7ޓ&ʘAbX_T1%K&W29 {hyFT=rFNrgG1e2b 'jN%R棋K䳐;j r,ڍ#a:@ ȑ'FШhpGT%(f48v|yp*\x荗.Em_GpѬgʨjgKo^+L(0 Vq`{˳ZIG@rt[ܝ۷+x.~XpNn Lq/ [%bE lϤ ճu4X4$i"^@'EcW!V%G~KUAr.LL_]:6 ]D޼~HRY,M&Hh=1*~oU*w·RY 1B"UK/vƵʄ8ϧISfcmݗQutCkiF4`tl82v endstream endobj 60 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (/tmp/RtmpbN4lMc/Rbuild3d0e7322795bc2/pcaMethods/vignettes/pcaMethods-002.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 92 0 R /BBox [0 0 576 360] /Resources << /ProcSet [ /PDF /Text ] /Font << /F2 93 0 R>> /ExtGState << >>/ColorSpace << /sRGB 94 0 R >>>> /Length 6605 /Filter /FlateDecode >> stream x\KumzKgk# `  NpHߏȪtgϢ xу?~??~~|oR?ۿ#}Ƿo|_k~Z룭ʙ>>T~ sYB.4(5"Oǫh 4h) jp}4|Gw??B\^_~Z}ݯ|okyhز\Zs}_k}) @{I|7y&^?&?R{%5 y7xncܯz^uej}T,xO|xGσK /2_-g[oY:Y{ǭ)WK{c~mc+qO/2'f-ս濲!}l{{xlp}]m67Yj7CH}zJȗhM|ؽoZoi)ݟ߾mkg!go<*J믶Dygz њj-}Aݠ}KNKeixq}k3 NQ_9"\7Zͮ^픷Vߐ.`>M_us뙮o_W(=lGrhMqb픞\vf7ͣLS6tM-+J:.,)׍3?Ov 7崋]x}R ,6J 58#=Ērc )l% t;r|4_wge~7iG+{/+Wgqm7 7wi.&̱&Je/`!uR<99Wn#㓺rE|=볗m.+~W u6Eyk yIXR)R|nК}SN2m[Q"x;I{|KJm>Rz>bSR[|>Hw!]ٍgy_nq{r5u3wlQ(/ikDaAA7Z>G7(FߔR`w~Qz|50dW烍W?:n\XRx%l{&ve ޔ-9[2^+*/4hX>*0Kq}ݤ+u?rON{)]gDNL=߮S:1`mE쓎|oFkr;M[rEmojo}qU־ G$c y+(׍PPnP_7 7,u{X}ݜ=Ǻ/1fRz_$rhMN7-Zoi\ǰEz'gU|6 Ɯ=*no-{toi)Ƿt1ř{DN]S Jyʧ,(Fkr7OAɷ|7/[{eÎ1lF}ݜi#${R(g;T /%њaU/N5v{1ڟ3agB6,a&Q>HOvњf9Vw1)r-C7W󼊭5ܳu*b553Kv|tn-9"<ũͳ=_7g"F0JDs"ƨ!glH.$8 ~4gt;gaߔ.`R}~٨wgY⠤?,NýtP1r>4_XR38RbYG7(Fߒ.bo"p\|yًȓEy!O7h,)FkrCOH7([rZ +9ǿlݱl ђ~, y ,,?8Ɇ۞ttBk-9"[c,an8WT|Z,z)ԏ| G,)׍C@?ka ѷIco51&NGdZ}CZQZkl1|zvNXR5xq <0b['N{)]vlyRf`od/F̃5#'ΰ 쎨 J]F.]٭xxooT;99v5cgEPɇkɗ%%њON)=A5v{}A ԊX,8!o?߁c6rmUbgtoa\*Oʎg βOn[Ŏjj f1|Y"tԁ N5v{1f9⹎1&Nނ=it{t=FM<˗cI5$Z^z䴋n}.0 O ?Pe-(pQXR['Ωn޲.bo-;_eNL$bD!%ot59~N/)ݠ}S.K}[cif\m~E A&BbE|~$l'NzO7M^Ĩ?[qeŹO=|c<]CO~0(~?=,(FkrZr{ۭ5yPk29{7 UVRpJBlP^Z!l"NaMfߔ.Ǿ}SKe=skOK[7KLѱtO|&-v{-,C3 r\s?mɳ.O]m/cv}S,)-9X>۩Ƚ#]vk,E$qMhtYLTMY{Tΰ\7ZcJk`ãfM9"n>+1JqW('m/QDy{X %AM7qtn-9"[>Lxrیękl7)юW2|T N!|讚]7崋n{aS~,8ݿerk:֡.فڎ!@,1q縄͞1휰ĪwFqX,v9};u (~Pn*)=; lt;rEmr}G8_7g0ѓ՝}nR:2OXRi:TKw+waE:k޾x Or0uQ\XQ]o:8 bMHwQ^$vU%K~2 -_7g9GczbjDaL/jĒU[my N5a^._ r3˦y4WĢg~MJU!J>Ku+ϿpnZ?nP:uiݚ/QldkdOA`8+*ON&HlöGݠ0"ѷ6mgʏgFeM_}=K|xZ@XRC^p:bץj.Fߔ'}%v+~ꊑ܁3#xn⤋r;>XQ;NMۼFAED=vfE}ݜjYrSy3"WbE$ !tRs#]vdd|9X+;̊'s [B%)vEt;,JmGN>g5křs<4êq۰]T+)黟F$\sg~2,ݠ,:U=8VԄ8FcUcE'Ɖ%5#.*N8nPh%]v?y o~_0l`NOS=؏’bXlHP P٭3.3Dzv25R9P\.,s1)T9A)r%mKuLzG32Q%UD/'J:x'If[rZJm|tՆ~/鰈s;gQԄ~u*M~$lC^I-7I$|w8B~wCs/o4!+jDNIZ [=9%M9"Emdq9ԈXyOWJaIq¢FDO Ɋ\igs~Vbd/ bl|(@t^XR)`#v?b[u#1fQvYkw[X,^|X*y/Ot%%IN8oeov+~i^Wk'д|./@"hNU`؄6N)]v!ېkc 1q8D*ʼn%њD¢E[Ԧoiݪ!ٔU|q5-EuְjI^YdI'⠦m:AA7v{ۭQy7eY#JⳎ=KTcU!+G7Ȧ.bn-S, hKy!bI (;{rEmGؓ9G=xEmhs2Q*)owlSwaR`88nK`yE3-<DĒ*t?۬[rEmy4`,[!o nؑngT.ĒjQ*NQvڱkvJǑ.bo!w[Gus<ҫPNUcEqSXQ%j{ɾ @>5rZb `,)T?-Y#qŖaI,uřtMM,r_TKN(봘%8S\r@%Ή=9daʞv {-c9@V!M _GQ>ʚN&g0Ű{KG7(.Gƅ֙EW`ũ=UZYZu#aAA7ZOp؂Ktoi)ݧF^aYqqpQ5|rXPЭ9d kݠ>}XߒRboOk?H̬pFTPʕ:9TI+ql"MEUO׍ztdn.b+<8ך~VMC>+7MN6a7zBwM9j+n[N?{c/)$I., [ZXRЍU7YGݠ5\f4u^5g֣VcaS:SȣͱjTSNV،z`Χ^}SN>'cXet/7CG_g8!vutRnw:{ۭ\_GLX'_CqQ=HJ8;ᤚXRЍ\9Ne(p6%{ۭ1u_)x/?*NCAݭz81nrra'~ߋA5vf'ӑYo:(: bISp@ElM)r;X>]+w\G͑?qX~s?x]06R܅-vk/f,DuswZ`<Ҫ'wW|fFb8+/oi:pa\)~6q,ʼn~r%wBKjF\bďAR}KNK}c3n aGl7d&*Y4?=sBjF8يZ:Acnk(Q.1Q- deRԫEA9sa~ӧ59Fg#zoiaZtcM7W9¯ W&hJrdm/X8tkOH ^J *GNKV,uÈ7D?=)ʈ9+V՚b;\[rEm^+#'.^Ø-_&{|qǗƅ]?yUΚSq}KV~DM.}rXa " ;aYqLXP0!Gv|-9-%۞d395,Y-@V?ǚX̵>k~7О"Mə87epnЊsӇa{t5ι)9(zMwυ}ov*08|W-Oo{Qȗ_T_b]`G]Bw_}SNg-$ endstream endobj 96 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 105 0 obj << /Length 2908 /Filter /FlateDecode >> stream xڅYɒ+Lހo"-ڲ 8(j5!~z!h:+kAVV˥_u4qSeMqd7ۤSn>DfduُHè>߂2=y2}miz> G::G_@{=Ҩ74dkiN"xfqSzUE=ZIO]/O_H\o:2*Ϸ%g<D: @<&xsfҥ;{,*+aH;?~5{nb;M#HyI=1q \3{2ɦw^$$+~V+Z(ϽQi.:Vl=Iz̚F3qx-;&DhZ|hxR8G'q ~ONvhusAOb\"10(m`/|+.*09TqS0a ,0IK`ۓEo&!ͅ[x~w#Ѝ,hgsg;Ӏ>3 YY)▰>x}"v8AyG4{5xxϬ㳩 b,*~Z5!ϫLjY8:|O?WLJY%760hCi5uDY,Z2af`2֯7rdiib Qu펦ےdE_W`"'eXXz ;w`k ̆C[܇b{7c0&ɛF/CI}{O*Ǘp(\eE+X/(P!!p0,ޮH|­DR{3C .8-]TQGx HarȖ =#kk eN{<˃``znsgY' 2'bqZd@` 0ɀH˃R=8Zqpt #iSNBzA?~ w1{D Lfp]I_8wxG$>:XI 36tiBq`uj K{1VT pA'b2$2iFj&Ec|h 洛}[5WG-Xuvu\$UX@уH%Jɩ*d\P gŻI`lTkov4JI\2U!r yn@Tl A#qTt$A'YAeCU!svQhk[$-,dϽ BXW6IL@H_`|Q+dT CePu#UvNWc{E)6E8/@tnX1֊qӞWqTǕ0cpr#sC|yU9B):@h"r \u 9DO]|LX?R;xKI0n~p u~<5 !tEEXV̆_ԙH3z1}O\WAݵ*h8Ar\e)VIΎVXerԉx~/ȹ[NFפfbSt @yX*np |n(;μT;)#2|/6ZXɮ1wGbBu;JN.4\3NtC!~9$NTrI;s2c=dy3Dr$iWP Yk^YiK^^BʛO?͓W;QM\o9rx6> e.iN5PLLѵՕpt"ǽ,SkFMM?ZuQ*j4g8\ Y<:z C=%j3]&~\ +zϒI[s5$]ߺAIY4Z!Tq,̯+pԩ|ur\gw+*eYf𲌳b!6d:K&ONT?'iXDvRvNVӥܓR;Q ;KQ n/) %unC~J9Fۖ5vG!جP!\;5; ,vKcSkˋ<}r.ȳr-g TD$Zy ՛hOwwmٞGA:YUr"Ƚkm^73BB (ɽk2(K8;yoL pz>!/L}ZfMYEY`b'[ӴCS~M endstream endobj 120 0 obj << /Length 2204 /Filter /FlateDecode >> stream xڭYY~X,M6``} 83yCвοOݔ< /꣪⼹{:ϓ0YݯD(,Wi"WwWcʪݭ72aA(V;&?Uܭ`wy5H[<Ǿ̦B}W)qGA:- ԊcTeT->T7 ȗt,PN 6ڗn%ry=YbRj۫ z#B%OcކV_Dל?%v,bpFIΙ:]-u ‹3pռ78p+Pח֯ڮW  n~y5s2%9 ?}7#L*cAT%Lz?%ϼ9j#e2h agg]:8Fq~-Vy8V1V4Ӆ;/حګqj_hݹk\FS5š3N-~7"7t iC*X7!XI.b&[1ĶpYP4WqtY6DA(/y]W?B.͞_Cœ"&v̇a,{KyL;`Ep ,K,`[<묊[KGRx@EE_ 3:MJr{v @d*G+c<cHoq-jg@T?6#ǡ6CFsZ6Cm,*}cFusU]3AIjn@TEj*(b`#+\)˼(Wfn"a1ej` TN9hDCD'ZN(8-i AkORa`ݍHD}4<73>+?Uj(+S;=VR\\\B$(*.u"4ߓHX4כb4mwԱ@kҺVt +JѮ/]A>L=Fqlsx$ڗ\u`S6O HւZP'2;(¢ +fq5أǼ 4/|6U|K#qk@3mN̅$_ .\P\KU)Nf0dn6K.V5Uk]VI0WE{m I=@̩!`դN_̾/kǞvgӃqGfN<>GvG mބE'@9psf9ЦMKuяstێys~fL& X`Z׺g03?,bze endstream endobj 130 0 obj << /Length 343 /Filter /FlateDecode >> stream xuR y Й&f&M4!BjG\_ %1)1j}d$/'b/.nw cXK /tUf^kP8Q) 1e m!,a)\) m7ɏsSv۶wu<}~U>S!ܸ2Ǧ`^O襼)KDph 3ty:'Y&+C$5hEh[},nqlW͝.L%UTK '^Uxf_$^p?ɇ8> /ExtGState << >>/ColorSpace << /sRGB 134 0 R >>>> /Length 877 /Filter /FlateDecode >> stream xVKSA#l{GAR MJ nf=7v!\]FTFc@F@֢ewn.~܃QP)s0)(8oﲡdO50kdW YB8u0oX+4 HY k=)'b+ %)k ^A`sel[/2(; {5be7.-`q&GA"4؅t+ء]_66ˮ$^Bw˯e\_𥉉r6;l;R-%06+N:T-m~@TݽActqiamUdXҝAZJ7VF܁WVG~|NcH؛ŸEr&7o=0REvNjm寸1*kM)v'N_:E1S[';]%,L)_ky 9ar}>?|y6y\76ABix8m.O$p!2xp;<> "!?KhNU\Tfʮ*%C]մIkIb%¨/ٳ,HnMËH)2u.e(*a|2."|/rDF>JQ7N0 wnUi*h6=n{ETG̸Dܤ|K@J Xp ]Evt:.&EE.2bƝ/ /KQalTYncZvpa6dwr.[J0mړGϮn"wr4iEɣOU/8 endstream endobj 136 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 117 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (/tmp/RtmpbN4lMc/Rbuild3d0e7322795bc2/pcaMethods/vignettes/pcaMethods-008.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 137 0 R /BBox [0 0 504 288] /Resources << /ProcSet [ /PDF /Text ] /Font << /F2 138 0 R/F3 139 0 R>> /ExtGState << >>/ColorSpace << /sRGB 140 0 R >>>> /Length 6919 /Filter /FlateDecode >> stream x\Kmm_q 'zװ6A[4 /}qzп_q=u ;EHjQ6%QuW_?l׳џc<ޞG{m{n?O_Ǘ_}*Rc/irOO5 *cm?kIxGZYׂe Xuak{W.8}vuAv荊@3$08ꖲ=Hx[+:5J[ٞu{\96oF}^a{4~Z9&6]-_tKhEQ2}q!$uZ k[l?K׳O9x6IlϣMdzq@P+A?#؟[j%R'b{W' 5ŧB/ w,$iHheQ2P'9pj%GV[ml&]1ݳs>;%.=Rz=GZg1Wq=JC;غ-:ϻ}gO~EdoF&fáeҚZId)yĭjsd電qZqRj8s} {shG>n+Dr6a -Gݒ.aW=^6}q"k:<GΉ%E,-,[bx8oݤXu[.K]V[X軘s9NM9LqE`V"3t90Y7(Vݒ.aWwVFE;&ܖɧǍ55HδXl3R7(uK.]V[AGL3xca݁H֝/4XQl9}MYKnA@-j;joם )77ᷖLšnb1`rnPn9vf}a\saM*Xm'`[~$3wyX#2nݤXu[.]v[h}1ڙ[ fG?)7\e,XQ%W#q[7)fݖY`WՖz=)b9sBꛓYRx8)ͩbK}-vmiV£cNQXߎ#e[GF[mQݒ.aWՖ)g _+a2CV bB}3wx4C`EA7K3؃XtKneovmѓ:unb`~b} ayGL/9Ӻr&Edݒ.bv[Zl}s6N#bl`hL>m$?1+DiV]}G[r%jmFͶco8ﵢr[bXPAٖ e2\v ڭa}f{?C'[VBVo{%7DŽնB[\v ڭ%:֜-1w.T3emX+AѺk\$,-Nǔel UKn%ZxNquVQW^pcD +3z Z6)I!nUWGf\8cn8= UԮ2N Q 3Nk$y@8%bbbr!3" ;>BMQ8p;~&u3l%o&{οęfM[0kwpj.33%E,-NUۭԇf:n,v[_m|[`3NP,w Va}K˿[8)`_&o>P8<3>I|+_@ d5}0_哷 ն;4% 1BG.\C6h?oQ?/B|F/ƖʌoEMtF_.yzF;\rzѣ0-1)&đ@ /︽7VTuIrJ\(!ҺI4\v +x? Zؖ8Qe= oI-q kklbE5&WbK|]|uK.]f[v?KNcbo=uhXRK@>pDnss}KvfݤXuc}m, 9s1p$Z 0C@if)Y~vEXR1;ǺI4\ m[/'爳;v`žVr~ k*3" LlA[r%jRed VFEn5R T)Z6\+ YZӯnR,ͺ-]®vzT&HAixiyO6s0$63MH{-ׁ/9b\o;nݤӻߛ}o\ bzƕ!G3lL2flӎ1#1eэ:LEuJJk[lΉ9{ۜ#eq٦|ZJ;mMjsNJrX, gdbV['!vs6؃FR Ps ya!9-[#5ubi-v[m9^Wl N= RϾ7T IΆC-a;*u[.]v[8ĉ}LNݑQ%qy𼈔hye-OMebd5u76A-v[wzքdrf1m~%FfYI>85{G+|Sneov-8cp ݀gH 0+XQͱdr5XSwq,uKn'~;ws.dߎpWx%FC-ޜKm8G4vnrǭKnm)ov-3iN6:Bߎ̗cnF?!"|h΁' >7*\nu8k|w};ιrJy̜Ωu7-]Ʈv`_n_o'WiC-cq{8n=>vf¹,~Ħq9Ɨg ?++wzw΍ Kubimy}瞼][r?{=goH[~=nriqubimyڭ|r@'G#R2yD*s_ӠǎeGE7TfB'' Esd[r%j"dHrb3e˜#\}D`''u8gLnR,ͺ-®v-_!#Aöt!N;.So8;zz9-L]#]KnepZ9 ̵1tL|*,'l7T%?XQ.Ⱥ%]®v-'k׸P|:Ʋ%~P[>&br[M*[Rn}m/ eYm1"jǯr[vPXQOQV<&nR[movmnKeBƶt}wgf=-9sэ-g+ _-zmov-IY%řUU;W[{˷L55|;> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 147 0 obj << /Length 1994 /Filter /FlateDecode >> stream xڭXmoF_n^q96@K͞$ڤT'YRM'E{0`3:<'/S.N2URNH\ni{ʌmMnCK5^``ߌ'~ɴYɔ76O +UmW/I&ֲ~ʴ*j>nY[^ ؄B _( Q.xl*&Tzv\*M* +E$ 4ٵ;L/h2툢쏕uM*> "95j*]S'uj(̻#=n-ٶ+ji;wQѶ0龍\.#v`?C6Scq,gCis-e`f={zs܆wwzPxn0[?V'z`bF cS&7Rұ 8ѫN7\}xU\n R0(, {m`M#u7cG= @o^8/zCj1cXY艿- E@0 OYHaI2dA΢L_FܧWj)Je`_;*>&T 48>`x/$0>pa!rY$Sxl̲⑐_*/.XLp_E20yN>y$X3 ? epZEEzVU6U5{ Jk,hJI6z J$0)@F#hlB S lxSOT5^A{O͎q c)I"7՗Hr)ӽH$TI<6t#9eWK5~]SŗcDˁ5,v], !M$”H3DAbj%_pW%J[g$)kObQE}*E^ěuTc8* (|1Ǥ#ZL1;l:6hQ̷f=`0654fLv JYJ4n|/|4xR(ط]ôo!T5}evmXawcEHBs!!<X~o>FH _n2K7"zwhA9N! =#zDuѥgYs8(#߆F404Q/t_xS2s)5F97|&cBּrE}qDkV HI:ŏ/+ lGa|N Hsq+" s9Zd$}h9<Zr) 5ydg674nk@Ojav c~7s}V(U=,>>r~BteAőrOy[3eA2yE/@;al dwNFz) tw(4^KW;L z\F w#:'tp~nh.ӾdV;XŒuDNLdU9+lW/Uz~Aݤ6Wac~z8ZzO+5b endstream endobj 143 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (/tmp/RtmpbN4lMc/Rbuild3d0e7322795bc2/pcaMethods/vignettes/pcaMethods-011.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 152 0 R /BBox [0 0 864 504] /Resources << /ProcSet [ /PDF /Text ] /Font << /F2 153 0 R>> /ExtGState << >>/ColorSpace << /sRGB 154 0 R >>>> /Length 868 /Filter /FlateDecode >> stream xŖMo1+|C쑆Q ԒS)V@A}fgK8d77'ƛKm8jxr9u9l|bXk`#_&2Nrx;H6:YVp]Qf m54襩If01  &o_Y,|r>|4|9j^4"x͕i2[,1Nt-HQ@mȂt-Axvh%VukBY* xʈK И% \ @BXV`qG>!Lau!mnhO9̥D -Ň V(< G"3|#>DF?} &׀&׀&׀&%O cDm*vF}*f$ Q80bcw,R-4X;*dSEJvНQJP(e+!ZEAJ[9Idi+-SEw{۫Gʠ~VB7_?t'䫿?$fnNOZv/O(w2HCըt-C$&ըt-HUҵ lUҵ ic:ҵ {P:h ǹE4FƼQEUBR3hRQG+S7 A/@rsФ4)M i@ ;BYIZYz/˄nf,#mHgZFzGˈni=-#}x.dr+'^TrlRXTvtzuzh%Ւ-=es3Pus}DU#Ao{`yH l endstream endobj 156 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 2 0 obj << /Type /ObjStm /N 100 /First 817 /Length 2568 /Filter /FlateDecode >> stream xZKsW%Up\zUv։ Q !=_$D% ttt=dYs,JTILjÌ5LzfLIf(\LYSJO)xk&KL12⬴oHiϤU~`@\`FBy7P*a0%H HaSZxÔx7p)58#v QH:Ac%F10G#aE3qXS1 7,{OÄ(Ȭ6J_b@ +q ]",E e/E !,#?&#''/=qY#&g䬱rr-=o:/MQN:V|zOc>ʒKեٯh5WF ;P~*0 -m03^$*Y*_/*<8zyD'fA+3}h1vi_!0.ZD!*8 ewy(Ư^a\C=QV?]JOe1DW,y}7rcK8%>jKŲbEq_A'> $ X8@k:>_S!Тzj Pvqةϛ!.OAU=[=N5n|R6i \!l[*#YHhT0<"1GIi9Nyb3L_u'**J4lZ7 Kfq Jh:qCCIɠZ ȇQl@:Cg#A cboaL#*1Y%\bm9sU|)O׻/6gϋ.IQ;.82iC dԃ" %Wf^3y7{bv*$v)4IBW:(]r9.R>>!6FtjA-z`jG|.&#ncjdE5z8ADU{+1ؗc!u@бeY:x8Oh+9+I6<~_ŰhD=ƚw i'W>"F[ $Fw #VPǞ}r:݇tב#Q>nmf2yY}Y,q)EZ.psUOl,}4DBoDb ")  a@ a̕ŭʃGfv=am_5z&ˠ`cms@"뻑NQQoF{vcV` JO /Rdn8e8:ĀtT`*Ք4۽ƲG{;Ge̅N41S.5{DqNԤݙFZqg(:wSZ &CvUW+ su+ Sb#`4qY75A=tO./>. endstream endobj 164 0 obj << /Length 2357 /Filter /FlateDecode >> stream xڭYKo8W9iF|z&,03ć&-JIm'~XZjv%%XjxV3oɮ3.slam{^RʼWJjʯn+Z^էBF9QyݿZq8Oγ)nLhAZ翭.?omDf61EP(VOcl&tIB|/1Cbw(Z3mQ9o]b܀so.Td<<3^~"/~ȶ_3]vDg}}p:xl~' f,l@CyP+lfҸ l~vS\F0sLF)&wc}IDb4|*tH#ɜiߒ@-3 #3OEQ$B+y3Bp/#_;J,<:/Y3RH請IkT%vmB VXUtͱ6ĵ hQؚYLй+_~.=4Ú QҾ*B㶭7Xq@+bGdfi"O?D*Xl(8 k/w0A T'mx03U /_4ݾ/FDv\WUR3y^0Ma5,ʼn:W ô\6}6XPqnjwLmnWH+xE}; )z~QS#|`(nfB[&vq {B Uu/թ613:\ڈlpǍ; ,/!%?;`Ji' wpz`[VTlXAk^)vL(Hܩݐ9$Ah}Q{B h-@ڀY rzkdBOaPY l/9!vcV _LЅH~*18QX(d1OX,`(!h4ݶ5lNY9?9B-Į  0іhNԇD ܚT,J.zm\(8v+ݢSAɲC 0Rp-AVɜNtU = njH,a$$R'ߜۧW6Dp)(W*D$vrM_!22>ՙ.8lZzqm;kR犚' P]#SU$0?`j:X}_pŲ_4XF 0G\x.}3I f=xI 7*.ATn_o(S_3c_x=tҍDuNѴ endstream endobj 159 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (/tmp/RtmpbN4lMc/Rbuild3d0e7322795bc2/pcaMethods/vignettes/pcaMethods-013.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 170 0 R /BBox [0 0 288 360] /Resources << /ProcSet [ /PDF /Text ] /Font << /F2 171 0 R>> /ExtGState << >>/ColorSpace << /sRGB 172 0 R >>>> /Length 395 /Filter /FlateDecode >> stream xSN0+X~ZT*@@r+RP>DN"@ 2 M9?<\`~P|鋚i)%& bJPpoU ,* S%17 9P|Ohtt/Y L0ibfy}= YqS"?V*sL75Z/`$ fq8|fwc\lR9&w0IVXёϰ;Am'H(GA83,(2?^)[5=6 IR)٩]Xqvπ]+v߮u+t.]k endstream endobj 174 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 184 0 obj << /Length 1255 /Filter /FlateDecode >> stream xڅVK6 Б")[fgҙv6KWm&ntv~>Q "Yʕ#VeT7o.d{+ћD8J8Hb֝:FL + y)7I:M~6@Llw ^e}~=sf))fii{,LUy"d*RҹT_05냟'liaGԘcOG`G-d>}4Cd^ڹ} tFt00Ƃyj 1VΑLw+v6nC8`$mngI؍H[@)"?Q; @8{e`& ~q-յ[xa)TJL~(bEVemن#8dFr8s[6Yڽ|kzH'AIn+~)3"16[c1 %Nn5,#&/zo6,RJg t'{fHyLfXU Oc,5j`fC/ԋ՚_D:f({R]>}H 8B 8\Y+q\` k?p%fb*"7dͭ0 ,K BP7үu6S{><7> /ExtGState << >>/ColorSpace << /sRGB 188 0 R >>>> /Length 790 /Filter /FlateDecode >> stream xMO1 +|=D+@ qPuv&j.M,)÷B~o^>;ۗI7ӂ.+}^'# ?kPp7~4&Qy]JqDky;5FQѪL ~AՕC@C5m)E+ǀ*+2)/ IFS01HhPv*`fdoѕ#urF6L0k^Om0ڌ ]5rhP-uH^,r;h7v5U,NNI-zy٦K35SSjtEqU6sii)Di4Q(EѵRB,ʠ þFQӰ/[2HvHBC:m1Jz ЀW>k8JNISXHnJC+Pq"ѫLu~(TF \>51Ja9)td ]$r94+ϝ:5Lj7ИOV*gA+ jiQjjSJZ[L7Uv[jI \.Ԭg<ׇ-XtWo>-PoW^R{*##["<\ja7H)|. >^&fj]Xe˰0GU&4A<Կ"I.)Rv%SII-s\tgsۜK=o.N^ةJw1\ endstream endobj 190 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 196 0 obj << /Length 246 /Filter /FlateDecode >> stream xUOMO0W~A$zH]`wIX߷PȮy̼W, `c \_7Rc \$XV"{xkM"[$f*`CWk/W H3).Rʛ-i",vn"jَnvcg;4m& m *v9wc>f>S>LQ*> /ExtGState << >>/ColorSpace << /sRGB 201 0 R >>>> /Length 5165 /Filter /FlateDecode >> stream x\[s\q~ǯ8/*_OlRH1Y @Uj UX=Y K/fzf==? vuѿ?߽<21f?ѯ9}t`wGvb<0\ ޛ1 ˻#&Ќ ލ,#fRX;$3 qގ2e:,3 9weȷήwDWicKZkb8^կGxŸl]c8s';WF{beVV;ih/!ٍ) c~@ 5(4G_v<яm~l{НQGUG`ǜd4 F.D$z6TD91> .@>)ONuPX4CpSd56 MsVY$⚺\m.?˘j0l -q Bg͵Ƣ!ѳܜ4:O/fx}uBٮ/6df8rO^pg V2_" q,i?s 4?7 a:T؄WXBjӵ׷fܜinphxs^=DARdO@1ȫxxa;^"#F6 ra{=gw.=,vMmWre f 4~̅V#pB RLJ|6”FV?ߡ50{ c\gl?͑~ٟoPDZb[IL3֏7dv'Aʄ-6ڞ8_86pީ^2"WNMVyOWIu3%|bC"8g7w~9U+&sГ۹/HM/ۛn#fc)>l7m7Q]ǑZ?Y ZhX )b螯wI]%t]?[ɐݶx,'''$^>$CPh%p"6}>RĚ(^ҶͿvRw>CFJ8vZwF&Oql[֗ekfO.9 #Ri?[=|<{ѣhFi~dfl(=*Bm[A39UpB䍜h{am&p~w{}yF{}Ksֵ8s d,nm;"&wsm&Y4G-Ia-+˭-(MQȳlq\JP`T+Z\dj%7/Ⱦ>phr51x"ޣ1a KQQ~0T H0$:âv>PQQ`>-(T >phYQ-QD5APf:Z$ -Pm9{'VYE0YfEQ o R8A'WTnvD4U yڴGМF1 A`V;dhP.rFt9  ԗVNh+t(TZFas-*-C:|EFX,uZfro{F:q{9޷94Ia gfqc/{HѬvtBJ7E&J?Prly}tA)vab[Q5C ƻs!Ui!gUG6vӏaIݬ*FoJfEŪzlGκȷ5u,M) Ň*$3ūPo{cN@#G$]w84%t'SRB#2fۡH,W2áQ@sgNFxUkU!= .zotv&R{a]C':8K΢s)0omTѸ~Y[SD>|2٬FzbPUe.Yeg Ž%RѴX sU,MѺ"5]T,i$1qhJNf6 Ӟ܊Pf`djBJvDo۶skTI+WQݜE-j$+>4doUY@GQ=e %g+YG;V&eJA Ӧ5TD۴\xn۬7~n%7]9bZvniw*>\͚[}3x:C|0Wv~>8]}2lss nhzҽ%[i r#M8@0 ;YY-``. f]Pm L+.h&K8C1DSDn(M %"+=/*\1(4?J-& 4=A 唐3 W;S'G \H(6ܒB`åBi'3rwUW?<ɣpș:`*]x||AgRpdG `R!?I\B/ abdd  C/KӶ7ҥ 8jU?u7χ[0:OKA0^333雳/`}m483l8̷p G ;bCL$`#pƅg7zAy<[K/p~ԂީŴLq'f F/ /0}};MQH<^`q@4Ǔp9ldem(N̯!DHPSj`dE%y(vf;ML?=3kQ$7a#RFdׂYFBcBE;3ם0jٺ]0If=dPnq"DL\zy7K'z+U&XcR"Z mm% [gY [xƗo_`6=[o+ x;W[!`fuMx[-o ~_ٯx{EG/ED./G>'0G#M+VHW>kIb%Zrc0,u.ZCDAe~;EhѴl&ю'D&MѦD עUSJkvI͂ 6oM,&hm[?EhjGy)woRA;Ϭ"p12(62;by /C(p7De/Cm+~<$daef9(wy~ .ix(D}M@Ѥ>qU S(_Ypg>k<ȏxu漶 &Fc&F )вɶ5@Ĉ$= LH+ &!M`{ &F4k0#00݋A&b)@6ṙ=UR@ <yoBi3 <4R@44Q*դM_ym H]a qvղ`P!ymn >$WDnɩ<>7.4ܿoA507cPhd*\4C>iTS~ĕhlXN)Sy?2bxcHCw]ka *$jˊ-=cPHCr!df)Ʃ 5̆U܂AK#IAL1ZF1 ^we ^Vi2~zLch.uPhvKG9ϔI# xPǛyJtSV-ҐSDTҀwNS i@\bMZ :E۩chK`4|YeN%+k}E5hP6uB|*A endstream endobj 203 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 206 0 obj << /Length 219 /Filter /FlateDecode >> stream xUPN0 +|lI$6xUSrJ"~i"+؞'A)8Ukj匁,"W0vpi[ ù(Rl-͔7ATg@"L`,+3Qqӯ8e|_q`g!Ҷ?4}jۙ1k/6]mwyѤ,^zJ_3?ֱY UkO endstream endobj 179 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (/tmp/RtmpbN4lMc/Rbuild3d0e7322795bc2/pcaMethods/vignettes/pcaMethods-016.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 208 0 R /BBox [0 0 576 576] /Resources << /ProcSet [ /PDF /Text ] /Font << /F2 209 0 R>> /ExtGState << >>/ColorSpace << /sRGB 210 0 R >>>> /Length 31927 /Filter /FlateDecode >> stream xˮ.rڟO1t/ӱHHh NgB ^T~'fAc1#̨DF%_ǿo_uL֯<1wW?__GRzo__?_o󣕟s>]i}}{{?K}`<\èﯼiss/`?ȩlՉOïqO>=_Qow?_#|{Ys?~h_-)Z\֜*og7k?Ϛ>vUCvy>HC2??xE_?hl#~ ̝F>S7~@{34X'FҟmiO ?[^XG?>?sLJҟ`ls(Ec}Gf|cpN߿~~=?"Ƈ|?O}n+%=cm_V$Hl+c[O}ŶQJ9v,('P@E6;0$=KBewŎ0.0o"\d\\K;;DsY{Y6X?m  ( gUyz&|ZYg[isK𳏗GEPy^G%8?g܎,Q;~m7Ç>y?6CyQl?ǣyf9ӰM?M ~?/ΊXyø}< ?G<,e^PH y7 :?lyLƳ~}'sx`g^oϋ; 0ϔ9}&Fwٓ3(~@~98v9O}@<죸 j5ī|f*!ogSϸ>hGGזAg~f;i#s|qrF=r yg33Ώl:"eYqVbR<[gjt8gPy0chp?nqV$1vBϭGx@|P=r|RyT{\j G[>~68}Gg`xPa150;Y164D0>j\kcjy@|nMRi= 'Pt'ys.e$o^dJKP8= _K_^%0>k9:ҲZTMi}^+eyԋbE?p{~ޯ_;鯿v#{Gz`LXgy\_;^ְ񎘵x|`XQ>$hڱXsG/w/Y41+4hjLJYZx05j OY>Q?hkg_W#j r"~|}=74!"4Fo/ @LXVTICAM O ٖ| kPF3WN{nI'|R|}7%(/hcɭVa^Ah+xә$6 Z}. <_qgLD^%궞rUTI4{J:ig?'p u̳b*es] k@hu5xqNa>la!> ϊBDcYЛM3P'Kzg*T}*iUӹRng} ٨ce6p:ULOZO%ҭOC4{˪1԰7h~/y3g3GG@t%# Ɍ]N^YjދVC@{` 3E ͳO9޻59Ҁ' y%Z% -)Heէx4qs] L>m>4cXJY0/Eo8 W毉yyy|Fyw|fm:2[n=Kgi35hu~Yw|Yn900Aavۄ~$_[n?ˆ=-Eh׸ȝIǂ_tXWP ȘzV-m7開rknlBp{Y%u@JִU9 7oUҐ-kX| p6ܗZ?KP @|F*?GP% ޲j$=z|90}1_Q}A9 >G}鰢 _󜟟od޾06!}N[Mbjvtc&# B- O+c v}E\}gAQ䤖f@n݆أx7bY:#:@C17A17o=*` Vߢ7VۻHQx 'W\q;!kymg3mB56r-WSα(i a: 2VzI@EFq^BlۻH풼 f>MȻKRֳwt7ۜq{:B*F B0w&6!}^C-u s4ƌVBbJZ^а~NێBmݷKo]6~bOܢxJ7M+%Ķmͪx %%ܞ/ ^zLՉz,]K&&KבIж(1?nêF[5ճ>7f˶L rCloڍV#xeǎ1|ym@I-[;𦫏iy#!>nzC>Y v}vI\ς{5ƌQqsҪ!?9^ۼ:!x@I\آ 7,oL%48 B~A/6?ǼqSߤ_ISEn4a3VuSN{dzFZ% A4{z8Q *u 4mB@3ۆk^AټVSkbD#nܷKo}:X kF)UT~/3*:#UҐ-+?r!=J:dllaCp::'iDe7S#1)T@fC)WBfݘ5҄ocD.ېWE2}j}Nm~y;PE/VREk+;Lp&IXJq>} /0%Ķm3Χ|rMfޔnI!}65}i4]!ѧ 7}st'ѷKo!ߥ|_ T#2w_] 1.f>\,{w>45W4kkpnW|K_*F0Ø @cP=flfB`+WKV0üV]|_}.)(rJR dM3t;.^N0-)>EAOiSkkja>g!.(ȯKV2okh]koQ KX}gݷ钋r_€{n'P``%'K 1tE4Z]GߢK.ޖ:AQ!hw_-{z[pm;WIcai;fOR% ޲j}]Uq7gEC<#vX)A-\g NBշ[mqWDH޲MfUrǭFՄ} 5!qPMco4 tY!ka~[h77q=a0B5'_?S}Aն )xHmgDߢGHHȭŖ1'maXVc6uVgc-z5ߴ! 8V-C|Qv|oY5'C>Btfn+?zn`ɷ&!l{îV5FI![Vlkr#Q WK@Ϡb6&"K7_CZ%`nreA/sa1avq\:opm/h]d^Cv`ogފ_Mmo%xrG<]xw+ew^pA^`+xץce@ӫJeB'N O4O)WRaiDFҙn5>4äqϘ¨e3<{s;y p3y+&6!ntE5kQ(B34N/W2 \A͂|"͈~kgew[ҀCVd@? gJ2: _W@oAjx-Nw%Gݷ)N?j?fdډfe33gD:cKS|4w- b“ b*v)B>Ï~2.&x;.ov-[ةubnG=i$Id/[e%;ƒ50FS|Vpݒ7iIa|0bxr1Z*;rZ3"j/>45Z3mi6p+sS5#MV38Q`J_U0OR% ޲zYʶvoAš#m]O7M6ԯ70DU8Fup[tt\\?00! 5wW.I BQ|uqݟ}*i56x )$K^ۦ=ة|z# ;`xt{ҀC8(Йc'jg-Ф:c҈)*E }iz㣝hC}Z:fd|ܒ Pߔ %(>|Vwɧ#I߇!6W,֖n:9"Y|GX/ew llqNWU7:"T1ufx{y*T0@2.![Ͷ^OR% ޲J oGi:!<>/dˡנҕZ|eA я-|].uiai! O>}BpUuOOX~B[%Y=P% ޲^'{8[!Aݢ0 "fz@j!fpT|u45ȉC-tZL%CE ѐH| ق*6*[oY,+LʯR!!̿tW y{4mٷKoGQqqGq7e !I*} )&1spL g߹n/rP1>e}E`as;VМ[0Z^fjѫ/t- j^ZHo-y?Edo!p3gT|WNoIj|fhhBh>X*)Nsnje &&EyX9 #yC|Sb?R/taHy+v q6$_hk~7#;}1rF_,` 'jeL="*z- an5'|oY) W6߾G-_'t_ǹq_Ab/c B`h *twəIrzS{HyR.Z#p3th#pd4oQۄkm[C/Rt!8)N8_obNV3a@Um[|;~}AAErhن}>Q-miHNU|UZE|[I#"S=y}8N~y"GT@3}xqOȃK.b&䳎!tLr2 UT+IzOYo%Roaᵑ#ax5: p_b7;2hu8ҀChlG# ͎ĎfaU4;` m ho=-'03hGVUr]V,'y^C=LG4[i:RԷKoo\oo\ƐEmĐFSU%;Sg$Fw8~޸Bgك_m׈dvߦK.H#f O=Av/!_V) .+]r-M?4^7^?N__^ 7 jN_V*_槬*,[(vk51[M?!|"j$UҀCX_nתU]#LyCְ*˛W$[WLl 4bίpE؊Hm@#e܈lչJVrK^)qe;91hf c,V:|HU-=>E1V$5h2˧13w2gb)Q1I4{C]+y+NFTQ9m9apm|V?Jeu_,őXSbΞ|s׻W n)Zh52O , гeC\U/B6` j~Ѷ y>CjVzөOQ%޲FB AXU\#݌4@[ ۭ9}*i!krFKq8#i].; MlFT{uQ*dH-$-}z߹/yl΅3ue*{e5Q+-KzugIN76{57-:,' $x)&i?22!c@%⚍YS-F7ƏǏ}ϗVETDž7qW[w$h=NC>eNQ5!3%HU|Mk<1P\j2\ j %;l! ޲#{T~!x:cF ŋ'^U4Gu6V `Q ,>dbپ@[嫕1|lqgNr3Zk>IM0SVlt(q}lLeDeiyͻ \+ܼ']]obEnE"/㺼o_ qrec&Cf3һA/ZhM(.0ǥK.}NImlbEV JZsO2\|zhN[A th(Jjw?eu͞*CsUㅜƅJfbE T_r̼Lo-zsxr_[XJNa=vT8O1fۗ0+[-wJ}z͉ECP/r9q9ufx%D>%Qj}vUe~ơ^O'Nu<4hESy]er[-3TICU\`ޚ:VT^e *4~2F5qVo%y?vںt%Bo^/& :MS.i )^xD}.^ *ʿ\MT.8&C{-ڜ蛋x4p&ފn;M\}gY,1Ė1_;+s)5 `Q#G|A3Jl>QL}n!y߾X?&w~TqQwяWq,_?_odd`7?b|) nP~׏_Gݤg|nz Gxht\9o~|L%)P8eo??9;3gs9SS^,s}JSsyCsOGs>'ߌЋ ~,#AGE(~⾅ So'XYHȊVOw?֟X[{a{}xZǕy#L~T.w#~9G͓[$X)GN|똟t:p[LnȺ򬣎5UgTT]uD+JU Zu9b[4?gf:'^ɵ:5F&}Пm:HoQԇeP[zp4[u; iF,I]QƋ8l0]E{fmfu\"_wPK{,֩Gx)HjY,zۧ-g8T~gǙ pE>4qiZͣ<?ā"\Lq LO3jL_LXwZ>F7dnp4, 13e՜Iu˩\FH\ 4N1'bM31=*+{? ̑gBg9W5mnQ P)* p̞$[Teλ*L]0\#tx1 \M!3:bA#u Lz4c>`j:rR|u Ŧ׾ o56t5x] FFm1[IWָZ,^y#-.]FrO@W&*;G[To2#ÿ$ٹzg×:|`ta]B Z TD_,)^Av SXV]mG~[t%޷qR:GbVKEnÍ M5zṘn:$UҐ-kU8(wkȞ.xԮ0/n^]a!;3>+3T"Zx6໠T @B>F,eS;|ZQG}*Uy<2&h9@7t:_Nu%F Sĭ_iOR% ޲ n h&'r丫,+B44^!@jSTIC)ZS#LfQg4oo|)X& HU$|oqjyZN'xg!7)6VXH/qWHaWΣ\޷~h^9~189ꮠBZ{W6x(aL1k6!}.;2 m{Z4nd}"G&B5 V H|9Yeu̧GO̙Be윸NhM6͌WA 1C3/ sv[t%޷ܮP`z ^Q3cBMVEѧ cwEh; wߢW~42nYʟfېy2vMC"`]ڄ]r-w.=hJKtNYGM=̨+x?V{OQ)^z-L?b샕7XnÑ̍/w;+hޒ °8yw1 y%xriydž.LI9*A/!_ vxi)qۄkm$]r{邽eLbJ4{ -Qknv=m`1pVk3OQ)Msǐ5lOڶF SNl M37ZjezMM=䮁Pip4FPѝH~`"JSrVs|3-=Sֹ qPG|KZ(蝄AjdcE{CuߢK.܆XbU.[SAE@ X 1@A>ѮJey3K䪈``xs/0"R\&M.{$-߇am @f]\e@F6:xoX k\<ėpꈫ㞂*iՓz3o$LfT f.!* _x a ně,MmEۓzY`,fGGѤ];f~*5)gߟGܷ蒋r(S*.hRMS'xU}g;8|3|l0-vʼʼĺLSVPfosлc2}]gن}_AGúbEh;GߢK.C)8mvΌ U^WX楯ixA-_ct*^9uߢK.itީg~1H e ǥj,̠9s,[t%޷܎ua]窏(dwWЭa krqqn͹o%xr3"dTN"CMԫ4dW/ 7["MFyn"rkeu:Cgke" fC~/|#^B9nf|/͓czob,'X?d$ݠ aXٖMo~ j|*~*ٓ| i *:#U-+o:T=2cy_n#gX0_\}*i{=~2'>RgHd4//!m360˚=fmg͗.I V2dh$k859k̳o+WrzUR,:=~RMCo:$U˕ɍ ~ּmG[i_鈜eHXu:Gf\GlI Vgs9ۛ7?iR6 yws^rEK bs))oy'`(̒k/T^=|oYm=O Gncxlnn4tm͎/҅Gb7`TMf;=$M? gF >f*ݺpQU a,B`䛯ÂV{Tv-M{z S٩ƻZQ{1ץ4 g^GPTY#6]rC<|NƏ,J^O3IT:nȫL>9%oicc()&_o)yr_I66RZ$c >NrKp gB!o>DڸH>ImN˧O{ќ#{IȌМ\Gޔҗ|+\7RH>4^Uv^bL9#MTU=$D~Bwc'^maK"se ;+NW#Q1/_g!:YӼ]UyFi5$%xrߒTDTJ؈.fafe@F1:in#Jhi+Jze@jLAo)k$̺N隖f2FPq0uU%TICz+i~!J {|2p(E9| ,ð9ˣݹ}siF^YuZckf&T{1K> wy^Pw ފmb[t%޷[25VcK476ήvK[J~;oeh|oM/̐|oY#u7_c=Y>.ZO@F 4*SI߇&êk(S9t0LOC^~ =x P4ѵEne4A}.!w/_5HVxUdNe2vGF06K? >KUVu|S$5ˁc]J6dQޗŽf -W1%j;Ms-[0=-K1TT(E507dܱɷ~Fo}{CPMܘU#D3Aaa`2/!mmZ}o l %r,;i91Ja2b!bұ {.|(/ f 8fg]wKj\)s&gM뛤94 j 8>iKS4j1z)k{X_RX;UM>U3seU*݌V'$UTUżެrC&8={V ЫL_PA-NTYr]_+w$ԢQj+FlB>jmT-)_r2!_ӵy4J j{[5O+n9߁V#C9FȤ[N0dJ@N!&+45;(, aEoXCDC3l.p|l5]}&;|oYMƊ&ohF q(RVOQ) >d |$igCKJglW3%@؈jw i!ď"z*yiG} ;mvbORj"&b٭ w:L-FTLMϫ<~;ط|5j޹OR?ew*)JIOÓo,=3j^`دtj-=:A>B)p$Ұ1ۉl#v.`g&Q3k>惫[-֥'|oYV\KMڏh*0.5OU FxVuk4@|1^GE4/6/yxY%45 8ux\ xxÀK^A4Y+kHXzHb"'J ߺh伫Iţ= }CN3*#1#l)l5ۨ>E4{o?qxxnCKXGuuS ם~DdVZ'=*]lk%] Ř,OH^x?P]^A9,$ަ,9$ &9 JB{ /jWp)3rϙs C>vHWp0My0_o-tG.÷aV?@Khːo^}1^Pc*Q8j-0K6^cn4Rz-:jOFq:guV-n5z5VҐ-khqʗm͈,ӗEIYihk}N3н`cܾR++ZO>|oYoDQ)5E5 @&Znt\ຌ#*vNZ> §eY?"Yq^@XNq5B13O邭KEm}ʅ4{zK%(e4u]؉9 N'n5Tbd C^>n( v&`ٿ})3lKT)GڧBGz$+eL+M%n/ԔUm5"O(WB` v 7y5] 1=\ϭk틻҈%|wpD^rSVPyn Έ&H$ >d L-ff;hw!wb +xr*|MB8Ή%Lnl.`%uMOƒZ9H\k|68{<|kI]:;ڽϮ%V}z[&W>zf',F"gF*R9'`ŇgJd/˭pu>e y%sm4GbV]wփU||_0_FRM |ƭ^vY#P`э\ 30lnR"6g B@ :j8z)I򓹲S#X03C֎`P4j>nD^>:VQ=Be@/& g(턢8 ,Z]C$JJ6LW0W9֐.k9vWմ^ĝhW*ތ%eʔx4+ޅJޮq7ږ68^/|RdtOw(4^p)>OQk)k8/%*dTd@J]Hӕ%]&QܪnQc􋮤>]Iɂꧬa_psJe z!cBooݴyfxe`ClE3%e 'aQEQlNk9ͫuS>w ge9og i5VwPu#P4oE: +@KRcӍ@s jҀC d4 ` js`jͧY6-JeoNuzzqG䝁e@X![}*i!kytLvI_88md4 nvЪ JK[׀!) ANPHPy҆+>K YjR>45g+Bkk22pe#B jgm& X!wV ,\{z/*v. ȌJ CdM7"1+=VmeBeu=a4cw2B{X:dkә޼Rd[a1ocMezr5~)p@b S|\fx'fs'$-0[&cS!"1qD[وʔҵv ú9mG|\UIFI![#o_%Nn~_-N&5_?Xk?__?ǯ~?2TSu [w>?D_ˇCSp1(߿*__/h0ĕ9n4_!'ͪ~)n~Q F-|?ȇ?~Pʍ ?(Ȧ? [x k} %~Z~_hX .k9'f/t9۟Y |/9;<4.͘@uxstZWg6Loc[XɂrTu(~`xRB*83e ȺN%UE=kkCS1p-;- QpN") *d>?Zb&hQ[^RNz7xrk~;E:҇a)O%yp`uJnW#G!8gn^U{ hdUrCcuݏ10拾G/uiR}Jގ;$#\l}Aa7+Q\Lȟ)r__1#W\ߨG$rگsOr`Hw`Ձq1|Y|_ʢq:0Izi v>ܻKeh|&&zTz#71ÿ' +tI&iȋz`>[ }$:t[zT_5KEG"X1% 0N_FpX|T꼊a+82Z!eق24܂ xjƪk{kNd|=48-4ݡHHj8,!+0eښ Iw,) Z;/q^w.Tɽܟ\+V]jLňeiuXQkb\O|Ҿ+lz@.iz;p9\g|zpqb+8`;ŬHy3sܥMc[ t쐳kOgv(]Ggw~>J{sjjp˚l*f$$ՎNwڿ[iingyZQ#Z] @*7OTwsjckk1vO.Tx}54˨(ns#7n5s{ע5) #PbSLYJpjZt$JtK%Hg@6ߝ ޘX͉*+0 ^8FU1o%xrY^ lWD _n#ZR"t10u ^DF}^o,O" ;k l}* jv L=i1.0Eov,Vq+ crg;}tqKm+ų7cu9|Jܷc"JΡ"PA>3&ך1?[FgraUyZ֜Co%xr1,6 L9KF1]9»!1YΪC*ěp] y)1By"epMǀGoGo1 K4pA]M=o-/r{0x:-gcD&323OyXe8 GQ$ѷKo,әV18ҞQ^MKrX/G^CQr)0hJe2/}s}o%y?0k)*{5Y2eOGMg#ѣo-y?l1T`;Ц3N;(/()^Cy3)&ϩaG-"wow?w+5zWBvuƇnk30^rfXԷ5wEBOd+M=+LzOw?ty g|at \m;*"=$Me"2-jiwe|I3ҧۖE&vqa5"%jq]K Ptk%ϻ[[x _9%)xam,l~Rr5y֋z G+Nuȏ[x/I`P2xaP3QEߤ[.~m},toL-,wR9ABItFIf/3͋TvE\}gaMӱ0;lڢ!@ jvw O$EhU-[W)S e69<кV ;LWdG惆V'|oY=ݧ +s n" kR5 bz:MKfHc^*Un}:)۟b8ilĔĭ^6}ђ!XXضP#^j6PU˥X,HdUڂ$.s?ꥫxUVh;zEo ޷w n:xt݇S%b9k(bahyv@m|U`C4ln׍90d q?! y &ˋh;oCҔpsVc`3+= ya՝n]v|1&ss}N1_ܷ+{rQc{T5EIVHjӦS=qC*SSηHT}},E++h2x% ]WivEo./r_u~H MhoCV'Z. t/<ѷKo]=2aBXqa8pzj*X aṫ1V+[OR% ޲eVܱ\k-,6)ס*GcV^Ɯ/;JXu "~ś@4.<=F49H.^CᜁA"EN}n! UZ>聩|l=_mXLW^/=0loCVF"W#k34lMH`FUN/UH6'`]  1hFJJiuJ,:!+/p砓5S;V yIҙؼs,Z;xy=-CqJNȜr Ń&MC%zTR;+P~a}mG![4_^Z#r4i/]8072\o͙oѫ+HܯHءc4kh~k &rC;t9XR*1K6J9%bLg1j O4zۮwsrU_#^A2WXE9(NQn3YCҼS:ڎһѷKo={A,LUWg T K3x{A, V_j [.sƩ:Y`*lTT^P+Es~3̋jv+E [n=< d8Цy7cjƻɐ ꡴Oa*ڮo%xr.y63DnA/B:]rF<1/EytY3}@iӣ7`5У7F#SՃ,=zfwyN/;;Z 2biXdys $9KdžГs 咮;D aygAYQ'|fَ8jo{ZB-lGժ&>G02)QzPX)dc'dI팡1&040G ش|Ԁ]Rk٦/Y/y=3m]|#Nn$xIt`A= ˞'4ϢL 7RS3ˢk^U 7ށi]u*@ʒ~p )YR| c^z YggZmsQ\7JN]om!kI>򠍮M~QdȬ|"00*qt TA`BJA0⇒M!-*F^};{ K^4҄Zv` o^B;=]]wS/f#܃wz3.J5SțT}Y+ֹ}]'M1i,_Drc6 O F5p2e' *ɧ^};Mr 8tMP3[~9DUi rܠR '* 7w`摭_tQ:HD_pĜ.;ף+ƹ#^};v!# 1#>UA.QDMf$:zFĎ1^BGc"7z9Ap`3d3GD<'l}N>wU?!6S{L=ݞvQZpɊ5PNP[.[bM/n7XlBgXvN|c"1#GGmeɒn>ҐD s0ymd_ &:'!HaHWmMo]#Q9`J>M(d"Cm7ӦF4k& rJM^RBQ ~qlsma2ށ}㻽t_.܉1(Qb9Rٕn)g:!;arn4Q;wc>S$o9vQzn >k STNKȁ_|nPڍ >5=JDcߨ촗hFN<ܛU8H?K!sNQ>l[\ 1Ep OP2f 6qy., -MC*oz',(eJi&Au~ IُveEET[#qYK}K/ȾNP+;Ql|7aXbs#8ўy+ {9:ٞp<[A+ O+ 32-d saN6RRxtI4sr94eEEJF6Ww[TS/ful,VB3 .+7X+vnf5/@^VMa$^*K]ł\aC)ʬ+J+JG~dI'eDrnP~e_N&iG>4L)]7_Q4jzPl3p l[Nijt='jY^i]0)703Cתԗr#S.w&ІrI9^>WzәC/|K~UNԌ8elW2Eiq( /z' #%b!Ǭayy<Ѡ܏R %U#Uh/,>7(C/fwa>ш5Ew2\Yb0i&h!ND`k>bjTCcRΟ'EYQFA=VE\[|}G,ڎv߱%J|¤I<{X:$8zQE)Si0q|tЛDa%K*>h{y9kC->l;#w\>z k.PV1>Q\^z#ltDLĤ"&Emuu]#lJKt|`TyHTr@ITq;#<Ïef;6XYe_`0#Źa=3mREc4ݵ5o1w-eީ6X9S5rYKOO/aϚL~YKŪX~h7u|;"Gm#3ČRRa겤VbȄ?C޺EyzQ6 ki"j**zG e+!jɒt:L)fsM ;}l;ASjWDY%,Y@YR0izI[CI^!~p6."ҰKAUKph NIJ16&jH漸PrIݸ\K $ wcvQ5:%4F]ίVck_#w6M ۄ#pdg!*ǥgeʊ*QGJDU 3D%D]RNI$L#k1 @ @ f%j]͹K ƧZ!wE751@Ν|M/fcL04>Nf%;vF! NO#Z&zQ6NaGR6a.6Y`1BM7d:`@S1s5zI6-%FtkJ֌!w5@D hcLv)uN״\UU\+>;O?/0S|=Ϗ?M/%:ʆsE̵hՒq4לqd/|v]xU?% I?A#Oj^藏@HR5 ȜVG^۾qǿ%5oɲoǜ/7-h7 ==:MGo3ԮWNi|#P endstream endobj 212 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 215 0 obj << /Length 349 /Filter /FlateDecode >> stream xڅROo0)z8je]l'ܶ VA,ܛX-F Y^I6̕t77.2oz#(j؋ 7n+R5LzԀA0(&*w9L_+komܾWo0pBg~6A]Pw٩U¥n+Џ G 0p)ŭ endstream endobj 181 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (/tmp/RtmpbN4lMc/Rbuild3d0e7322795bc2/pcaMethods/vignettes/pcaMethods-017.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 217 0 R /BBox [0 0 324 216] /Resources << /ProcSet [ /PDF /Text ] /Font << /F2 218 0 R>> /ExtGState << >>/ColorSpace << /sRGB 219 0 R >>>> /Length 10878 /Filter /FlateDecode >> stream x}ˮeq~;6a CR7q4H%nC}gZ+2O$U8n+2v>##;?~ȏ?>/oRzyſ3ߌ;-?~-?SKJ?=>j~y=?m.q5=+g'm>||ڟ}{Wjl1-~Nxm@b@I@ϙ=zqNHZIs?x,SK%aqg jV94#Vmʆ3yx1=p絳KRv~<lbE<sX8ӆ+VY5++AY!>u#kU4F%\qFZ!I)!UcύlB8琓Zesjg<$q#ys@XPЭsa l6 ꝖXڒRbO.U/\6+lZyjߢ^TtI қ3-{)=:UM9"[QE9'.r6˫e^iXR]r3+oAi-9"[rT5=ސyֵlaf:(-6,)-o9nA`W[S=miz-uY,峲Z .yZ,,)׍^4q$bf&FylnfJRZi7DG,k<܋׼p(m^-yr',Fڒ.bOQ|q9bDcz1fY15H%Ւ5Ӳ%!B͔(O"kL1]H* lPʸ6|6Twd[aW"nPxiS.}{wKrdcaS) XVtU5GbhL#:ٺI)uG [9G9Ci;}Pa*rV9BJǨ)]ĞvEAC!%45P(E_O|U\+lbEF,,t;%Ӧv{ڽ5WGp,*Q,vcsK$9\!eS@Lq1帋, "b%npV>b[u?AϚZӽ^YWƒ1)8 tҦv{ڭw-LCs`HLduSw_ T-QwA-9"[M(DȹlXmSjO|xHGXR32h`;F#j)]Ğvdz:^ m2Zf]P\ 8&ÏJUEfA Q s܋񬞨HqO0lVj#jzg-l`BZmDap0aJ-fLRZik-M )kaeChQ)]i˛/ KuirMщ]nLR zʒ(O$_hnFPRɾ|ͳb:A`Hk>pxq z5@suz Sv-fK`In =U7֣RҦv{ڭW89z4׃l;ҋ@%{*yXRuj}]yn2jז.bOwz88y \"|bNJCs$KGM澼4@iSN=V[,D7ʚvg#&Z#Z#[\8}HkROiR k;lMsnd#=U-JMBFO%D<.+luLktJrEiy'[89Jzo"VCny+*+ N&DAEUkحjMDnR"s'*J[^!wT88}a &;'6 i\u_8:ExK =)~.bd-ŧ<ʈkN &Zx=C8oqrAbH89pVX?h[˖D’ʱ$N6ވCHYREi^j5o7jODK8%ߪXQ5ba3VG;M9݇ DB|%f[>:ǖcX!^?aAAzc\ (_9w U֘D 粍nzܱz&>G’rx5an]mi;ъ8_>l.e>.Q +Ēb*NA5;h[SjU)m9"{ex+@΁j(Z~dHQ^Z/q66NDRڐ.`_V{wqr.n]Ck_:(Z6Q>Ċ$^;´)]حr^|@NnkƜس[01E Ur.kZ%׺-ĞvリuFgUOM.LE(uVo)PÉc4vǩIVþ K[\x4OW ~1ݪeÜbDt.n$3L 2ؐc<լ泶c!NX&dQ6-*s/ׄ%c!NYvbnPrrEi7/K"t9=|9`T ͦ鋽U8"t6φd<"4mpi7k6m$sS ˴Y|G ~X0bEWh_ӂ 6sG¶xDI>F6?0V?лQC:G+:"F<$!U҄w WU@'mIe• ۋtXi> 1؁jt}yZ 1\t[F8\"1ZkyD}}R#ZY,*ҥ5&JRZi+om? hwl.=p`x%l*I ~=dΦ/=٫ `3 bdxO/\ -` \e.q `@'~# en 1뮠=E>ء˓)~%=XףLd>X<8[E_zETx41/o/sLEz=E3f5 imj2Jq/FU)8Wy'%.UPUl^N*JˡxxoDmAҚme}}fPp>uB͏,"}8C1:{f9=½Jڻ~f>wMZ_t"BUc" YJFipPRR )#Ja!;u&@ЦİE8Cbtk,AZRZ[cD溗6G_m@2S)low8/{SL agD0RDu#H8&LiBJkl[-Nr߫9cp+>oJ2{>1" -r7)PǽŎz#qҳ;J*+%1=XCN+G,Gba32Ȋq[4Z6}҂Aq".c;|z'C{W3d^l6u(| 7tĩ":X Xe0H4mRydBZ& 3~nZV\Sxm- e)p$\k=kZWiBJk;ma4D\IݔW"oozHĀ|8[J o_/Hi++pm*ثVu‰Ek!}H}kp,C8,Q+kY Y[8ԲJg9آu1\vх *kYy.Jk҄8V_TLd>ư%޴hӽvrO!%Xnj91 !QBk9y )5|0?XbDȕCc6[H 'h$Fp )fOLq/Fux\_t{?<;8T7fS;܈ Ezs3F#ӂ 6sطjQq}yN\4QGHGw*oP5ww2vưʄ]a-9DKj5ZЅ1*]2a_/8,~tM@wi6_g"D\ax޷p`!5{uGRqaGR/𳢔)Rb:#|s ^"U2a_pip ` |>D 1}j-q1,,>w7Pľ@4& B=[yQ 8s] ܱҞfnw 7P̍M[2ZiVy|{ } zl|wc``qPk=9LmڪmK`8ї?9\؞$9p KjobaEiS-e،:.`#n_hXO2`P:q$<1 8KkD&V&ض}lM^E'f{-؂B,.-8)b;uػ_ccOUP YE%՛P(]ʭi%frp 䴔n]XKqr+,r.VY(,Xb$-@[̦)]Ğv\:vz%?N ~{fP@!M’JLnP[3_gb2>^CWA}jEl|rúc'9eLؠ 3q[^pO[O8`}\HݠiɝC.Knv qK*:_ēc)v EX4ҽ=M9"{_A ))ΌSp(DX'v˵+HMթ3U}Bj+Kgk-ݚ9'AN[wҦv{ڽyYqdeлB/#j;(Yc!s*͋>&oҝ͕6 [m/5΁5D):`4̿kXR5VAMXuHrEi7Wy˜bj K7.< ĊZ3g:gDAzqv {yw/?m_̙NNQ_C(1ɯdBLm5E"}{U_*N\vsYWߡyKs,rB`ʦj p;oY\w,d39\\lIZ+F#9q6J>4Ms}8k!'˥~Ɍi[Er~aHhUakfX_WAUM]DD-<,Rqc#sg+ڑߗpvkg<{:kx6tW~_oi#Ӎ.D偛*@qZ̻m+y~eyrt% 4|k,*N?%;ۭzG ACEzͿ1jއu(>sqk/vm#Qٍ1 p:](I'(~DfYl3a[V۳8`+#8}Q]~mGSg ג`*z1o5=_@A^qɏjWBvkv-/Vo]x3P=?B>|@+bz}mO([/ x3d ?Wͺ{^vi\3XX8²0S|3,* dzԩլv2sQO9v ި߃%?:*K۰&_o{bMpA?_9I~xo@|/?k 밷/(96}yſWK ۋ^ӽ^x_￟o >HCo>7һ")-< 5I~MOe}~Z]Ͷdft>߿Ʋbט䖗ޙ$z/_d(6 |&i6}ZῼoJԬ/Yk=zSK?M+8͑^Ƨs|[FxοtyT[~^>5p;||Ï|{dbuvu{O^j3-G+\!_<m֚ GQtXe2&9n%VTRRUW kALrE|Leј3CrfXFq￶x%/)-0oowpܞ8=x%G+`lZ:/iC.}(xQx/)]~&t_XPT ?CKf8JVR)n CbAtT:q)@?_T'ȗnc31r /?1B{d?_W=~Ͽ?_??Ż?<쮤 endstream endobj 221 0 obj << /Alternate /DeviceRGB /N 3 /Length 2596 /Filter /FlateDecode >> stream xwTSϽ7PkhRH H.*1 J"6DTpDQ2(C"QDqpId߼y͛~kg}ֺLX Xňg` lpBF|،l *?Y"1P\8=W%Oɘ4M0J"Y2Vs,[|e92<se'9`2&ctI@o|N6(.sSdl-c(2-yH_/XZ.$&\SM07#1ؙYrfYym";8980m-m(]v^DW~ emi]P`/u}q|^R,g+\Kk)/C_|Rax8t1C^7nfzDp 柇u$/ED˦L L[B@ٹЖX!@~(* {d+} G͋љς}WL$cGD2QZ4 E@@A(q`1D `'u46ptc48.`R0) @Rt CXCP%CBH@Rf[(t CQhz#0 Zl`O828.p|O×X ?:0FBx$ !i@ڐH[EE1PL ⢖V6QP>U(j MFkt,:.FW8c1L&ӎ9ƌaX: rbl1 {{{;}#tp8_\8"Ey.,X%%Gщ1-9ҀKl.oo/O$&'=JvMޞxǥ{=Vs\x ‰N柜>ucKz=s/ol|ϝ?y ^d]ps~:;/;]7|WpQoH!ɻVsnYs}ҽ~4] =>=:`;cܱ'?e~!ańD#G&}'/?^xI֓?+\wx20;5\ӯ_etWf^Qs-mw3+?~O~ endstream endobj 224 0 obj << /Length 1468 /Filter /FlateDecode >> stream xڭWKs6WHX H&'9#vhb,w ʢM^bŻJbRi1Z܍P,(5"-V蛽-X\?}r-P,W,O8[,z(NTD#]٦u>'5xuUMޔp8)ڵIݛ\;ѥyx鄩<M8gyЭ |yif]W ,4$C?Ǯ"j̣rѭ\yO) wU8Ε|(_|YmmxiLZ3!zx+܍iݲa)8H*#!Fk`bݡWU9)\iMM>/1iֿ5 BJv[wѤ(bɲ.< ޕAfY:Y09j7%~4 K- R!OYvOְ~ ]⋪-1#l_C=Q ?F@dŹ@%y(|2%F5"d/W>cd;+U~>Tt`*,O~x $FanM[ i+Iv?-ڍ)0G Yz}-;)P#UI=Q5 W`&!! 钷w׋]$HD ﳮ v>A -VdK]%ݑ8{< f5^xGL~Bi< 8B)_KBuG;3ӆY )ڊ~Ov tI Rfe_H}-GL"T3[6ȳOQ!?:M+-I`[t j|\TJ=_̃~cpėf\y~jӴuTHTk}RHw=D=%cbn\ƾԖG'Jxع(=0mm3tX"l4ogV$IW4PQy AA,+._A:*"DטD]t[~QUZj98e@müCm\];yBug\ ͟;gB)]Nr|BTDOkv s vͺ4G51GC#tG.@͑_qDXA)N`K7!HPUtgvy`>cGzG?afi::a<_,sM^DQ7xVŀ5-fk^򷊱 nC`1R@-#JOĽw'w] endstream endobj 229 0 obj << /Length 96 /Filter /FlateDecode >> stream x3230W0PbC KCB.K &r9yr+Xr{O_T.}gC.}hCX.O9z PՓ+ ] endstream endobj 230 0 obj << /Length 117 /Filter /FlateDecode >> stream x3230W0Pb##c3CB.Cc I$r9yr+s{E=}JJS ]  b<]0`07@!?.WO@.+#- endstream endobj 231 0 obj << /Length 94 /Filter /FlateDecode >> stream xM=@PEx$^!R { T߱4J2:ԄҔbًӊ<@zAjzHhxۂ )9(݈P:> stream x%;@@E3y,'1J!* Bo8-1I2QSS.&Qz7…qpEW2ʊc,&//U endstream endobj 233 0 obj << /Length 220 /Filter /FlateDecode >> stream x}Ͽ@ i'pUZ]qXW(gkh7Lq,|Ÿ%n1ћrsLKlyZbf.]~/6Lr6s%p9"[@k4 *%Щj/xĪ=R`$huq+TVX0;v{#}p[diN5 !3R5Tz endstream endobj 234 0 obj << /Length 233 /Filter /FlateDecode >> stream xUj@ 4S`B{AA{,ҞGˣr ngv]v]ab:ΕQOt O9~ᬠڕpe] E]nJj+r(YXUzj&|aOd pc1uԎ-1H[7c(< bg Xk;>ɝN`$: -omc)Z/%?OFi endstream endobj 235 0 obj << /Length 245 /Filter /FlateDecode >> stream x}бN@ `W"y#O% Htb@L@ͣQn틠e@铝_^-+5+ '[v=dٵ>حfZWn7BǔR$c̤((NHN͇x%Cke2MoŭB/穕p8YiRNL4pʉ`EMӢsd~Fg:5ЗTHi s}[L[ endstream endobj 236 0 obj << /Length 266 /Filter /FlateDecode >> stream xڍJ@Yh` f^@[ Z z * =ɣQ9!tݙAO;8-)Nhawcm(fȇ7*MzO֚&MZnդ+ 5==rM@)o\S%}qKK䄸PFF왎m4cR1U'~@h`"[bz OvJ:Y圠8!y@4h? %<$.͝Dpj endstream endobj 237 0 obj << /Length 241 /Filter /FlateDecode >> stream xڍѽn0C"#pO(TLH P:DڌZ53<#02 $i(A>l#ݏxSHiL+}GIf!/'%EUqjUAۈAѩk~F Akpֳ`9Ek&kkpk 9\SX}i,3OZ)g{I!9VӮQ5Fb)e> stream xmпJ@ b D؈ 'B8+ T5y> stream xmѿK@xTrX4T B:?9'[u_fk|^/A"c|dH8N1(=O7ώdD^R]a:[ LK> "@ڪ( wwVҬnЌ5z+WJi :yNR RN@WP!ge˄<.#v.#FZI[6,,ivR|ZxZs!JG*h;Bami'> stream xeAK@' kv PKT`:;} vzϝ]=Fa;ON&SSs_0h_<# cx,Aw!2E *k8;Aq2jGXm 'mA?Ni/Kx endstream endobj 241 0 obj << /Length 207 /Filter /FlateDecode >> stream xڅϱ0# $X0)D1D'㤎xсPGIt0 ͗׿:bs3$xGrnoQH6Eox]Q-w+JPet1'3ӀTP\6Bf ~x39:^v@+{B#p*ɱpq>{{ wƈ( G5J(9҇6q?}O endstream endobj 242 0 obj << /Length 240 /Filter /FlateDecode >> stream x}J@ 0HsP輀nHLOZ=yBA= * ̣Q9P:v9} 3U5g|Zp5szn<iِ"w}r5}<[\pNn9gkjV,"VFZે&WG"씓jVFxA=f^tXD:$Q`u@ 3Fd@ma5_jέ "bt-}^p endstream endobj 243 0 obj << /Length 243 /Filter /FlateDecode >> stream x]J@ @9/ FZz B(M>>J$~LcfjHRYiE IJ|mx .[T7(nE{G(k*Q$vEƌѱQy]CÜ*>gY8U#`k&987,lsJB>S}>Աsae-#~G~lÆ޴x+%e endstream endobj 244 0 obj << /Length 212 /Filter /FlateDecode >> stream xmνP1B4aBBR]V"xQ|!1X|3p椪?p))?y臆_LXFsiQlS(NMpw"%@ F`_|;Bg9!4`&EU E `AK]{ҪA5]m?IT*%!4hE7U}J endstream endobj 245 0 obj << /Length 182 /Filter /FlateDecode >> stream x}1 @/)S  &YIc@#BBRPN-G)SHQ xtT+ZS3P8W]+|4(; SúwXOZdx)eE> 7{Skz( hRЂ]< endstream endobj 246 0 obj << /Length 227 /Filter /FlateDecode >> stream xu @ \([2)> A:Dء[Ch3.FP-Cgw5uZQCۥNvj.33tVjtf\F't٣3ZZ ~Ĩo~ycO3IΪg`g@`P?|Xmc$EbXKoJ>G}Ur/cCM~Yܼz'Xɀ" 3-8 p/fl endstream endobj 247 0 obj << /Length 195 /Filter /FlateDecode >> stream xu1 @D'´BtEVbvf%GHi!Bpg3c[N6m2XK1|+b-q*f֊Rt;Fbh.iR]܁#s+ JdDz|Ƀy*Ԙ*CѦ#6 wrp38U{ A endstream endobj 248 0 obj << /Length 184 /Filter /FlateDecode >> stream xu= @ )2'pT-,J--m׊7#L\wl>IƣtB%:iN10 # \ł.yRMLEEpT |E  5fK)%@h;.^ށg͠T;gW*S endstream endobj 249 0 obj << /Length 257 /Filter /FlateDecode >> stream xuN0/< 1$ЩJȀS :/ƣxc|gF=>bΤ;M_ @!3%RJP!LjeT"fS_e!}ѠvYW}#_zGq endstream endobj 250 0 obj << /Length 211 /Filter /FlateDecode >> stream x}ϱ 0+-} L8Y vtr'utPt#>/PCi4.469wi=];ԇy-#Ei;Q'rQ4wY`X):Z?QUξK~{}C!`e n!T2VrSj9eLtʲJ_oJ]p?Rm endstream endobj 251 0 obj << /Length 150 /Filter /FlateDecode >> stream x3230W0P0aS3CB.#C I$r9yr+r{E=}JJS. @-\. ?000070CdD (c`1`qzrrx< endstream endobj 252 0 obj << /Length 226 /Filter /FlateDecode >> stream x}бj03nMPv:5IHV[˟ & !tNgf#,h^ҦCBAƠ~W:[˷'*Ph]PՊ !.7xW=ՠdB7C֦ kfԋ FmSg~r X%NXg@qܢvk5a{DW-K,#==dCs Cj endstream endobj 253 0 obj << /Length 150 /Filter /FlateDecode >> stream xU= @k endstream endobj 254 0 obj << /Length 231 /Filter /FlateDecode >> stream xڍ1N0e/A'T e!R[$2TSTVA\Q pEԴ1ra?]c{&ʶQ7P _H_""fצ8 endstream endobj 255 0 obj << /Length 192 /Filter /FlateDecode >> stream xm-@i* &$  (@" X% ++.;r|̦^PHOɐ0re\XRWrFy")BQ*p Lo/dot5Ȭf;%_[a\kv\`k*~_;@1_c?0ĉ[ endstream endobj 256 0 obj << /Length 198 /Filter /FlateDecode >> stream xu= @R f݈L!he!Vjih4GQr-uovN 95lt"ӗ0a3LvGl|9_ kRShNO* x9 N a<+ƂdrqB"R -OlqـfM䤒o#Ef9b , ]L endstream endobj 257 0 obj << /Length 225 /Filter /FlateDecode >> stream x}οj0h0ܢGȽ@+ 'R0 C:NMB[5Q1VOID?qS疾IQҸ"*Md@z- ,goTM-P_ivP=ZCK⑊]l.*3͟{P,m8Ԉb+Tt("O79Uۗ3iZ w'm endstream endobj 258 0 obj << /Length 222 /Filter /FlateDecode >> stream xuνJA€6y;W1BLBREK E}{-S1!H|1eqY]qc\\sNo$9.+M2  3:??_L8'3姜%5S,PUHPBO68j3=R{hFFnO_w,~I ёk#6~TAHԷlk Tm<$;?$;PBBd% endstream endobj 259 0 obj << /Length 166 /Filter /FlateDecode >> stream x3635R0Pac3csCB.cc I$r9yr+s{E=}JJS ]  b<]j7g`O~}( X{0'PzQ" L$dՓ+ ;W endstream endobj 260 0 obj << /Length 198 /Filter /FlateDecode >> stream x=AjP?E`u\>`]W֥ EPs% mtb {~Hgҁv$'bε&/tc8jP*&Yeqymwn\\qF R"=-Jگ.SL(J÷/%579G, endstream endobj 261 0 obj << /Length 176 /Filter /FlateDecode >> stream xU= @`}nT1[ZYZ *ډ֛)feW(uŒRA#JY0W$;#WS:[lDyAKA UAЂ . Xν2 xL 3d>{ߔ8+X?y< endstream endobj 262 0 obj << /Length 183 /Filter /FlateDecode >> stream xe1 0W:ޒwMCu+ ftr'utPܚ(9B Z)yb&3J|NYAw ˖raPŽbjjK늢ڭH()=)rƁE?nc ̌혤=-$zL % |( D$q@3\Oc=i=~] X endstream endobj 263 0 obj << /Length 189 /Filter /FlateDecode >> stream x=1 @[t7&tB` A+ Px%GD?hȊC{DxщYvGS+əIsbɄ ߫ܭ*p QDnRfi[:J J Al[Cʀ1؆ƭy4ݚ85AӔF< endstream endobj 264 0 obj << /Length 213 /Filter /FlateDecode >> stream x5=j@,nS4'J6 QHU2C ,MGTn!b>ޔՂs./+,He%}.>iW"$S3^ w> stream xMαJP?Z8f x^@oD@  cSͣQ|­Ԇss?393MsM.9WI3n/߯K1fb^Lyo/bwYCZʅp "l1^M+ {ho)5iD;['ZG;w>Sӈ~;O{. a@F`$^ߎZgΖayl_RVGS endstream endobj 271 0 obj << /Length 199 /Filter /FlateDecode >> stream xڥ=@PL ȟ b&ZY+hxJ d)-bߛy63f%gtx0e5$ jOaj:*yAUlQtєg&̛}Nr 5r^ a2ʮ`i`r_zH&=| z)3WwFHH endstream endobj 272 0 obj << /Length 203 /Filter /FlateDecode >> stream xu1@EPLL 1D+ c&jQ8%gdB-^6gߑ;dO\q~ƨ4 Py*^r; SrPEqbtLR~3&0 > stream xU 0ES:ޢI N&O'8:knh@}7D%YgXnE68])$$ƒ~ܟv1ɂ1GG xos*!~Zo(k B" Pq>.۶{xcA+M;= endstream endobj 274 0 obj << /Length 187 /Filter /FlateDecode >> stream xU @ O Yxw8jotr'utPQ5I-$f2c-Z)+GZv*C@Hx=Π9sT/Ԩ"kF㇠ZFQ"7!\LŮ{kw; #e%(𮈻i^/aTtY!)y@,=l M>k endstream endobj 275 0 obj << /Length 107 /Filter /FlateDecode >> stream x313T0P0QеP0P5RH1*26 (A$s<≠=}JJS ]  b<]P$ 0,) endstream endobj 276 0 obj << /Length 151 /Filter /FlateDecode >> stream x313T0P0W0S01U01QH1*26([%s<͹=\ %E\N \. ц \. | @ v:QAA=N ?@J@#`p`\z> stream x=1 @ER~- g`#8RK EJ4RZ(ޑ'̨i> stream x313T0P04 f )\\@ IrW04 s{*r;8+r(D*ry(0|`??0 ? v'W a* endstream endobj 279 0 obj << /Length 118 /Filter /FlateDecode >> stream x313T0P0S04S01S06QH1*2 (Z@ds<-=\ %E\N \. ц \. c$! b\\\ϊ> endstream endobj 280 0 obj << /Length 102 /Filter /FlateDecode >> stream x313T0P0"3#CCB.#)T&9ɓK?\ȒKCKW4K)YKE!P E >'W $ endstream endobj 281 0 obj << /Length 137 /Filter /FlateDecode >> stream x313T0P04S02W01V05RH1*22(Bs≮=\ %E\N \. ц \. QqC=C=2p\   \\\8 endstream endobj 282 0 obj << /Length 188 /Filter /FlateDecode >> stream xU=@`6$p.?`# b&ZY+h+L9 Gذ nKfQ!!^CUdx[a> stream xmбn@ 1DG@ CT*CdPeJ;vhծGQxFkDd>;zWMrMMف5eJYƿ?mvϬ ΏToHN [`CZ,{ê3VZw LRD%ڻ{F:lZY> stream xڥ=N@Xi=B,  * D)S&\7GH6.DIi53oXk]꥞Z\ޤY\jw^%{"e;xIVV;RoN>`a}x3 HVmHb&oNhh:+Tp=q::Ϥ>F_/C21eya:#f`x!7<=c endstream endobj 285 0 obj << /Length 208 /Filter /FlateDecode >> stream xuн0k#xO `D`qRG(}FBЄĤ~pE.-K =zh.wStlytGN_NgL\kZZo-T c ښ[ۺ8Rf_yOwy_6|pdmA&:QV&ҘP$> stream xu @\z'H  ԩCtEh>уhkeͰ;Sr#&ttBpvd31[%OюWtOh9qh璳8"hre)Q5VzV \4 0i:ul3%Rk-Le00JKE|}xB endstream endobj 287 0 obj << /Length 186 /Filter /FlateDecode >> stream x}1@!$pBBEHaRK .G(.ZHI%ψ$ɧ)) EQgLs$"ܢvKs. yF R 0RG5X-؝X͠NPSϐnilbEO&4>=VgWX(9nn endstream endobj 288 0 obj << /Length 156 /Filter /FlateDecode >> stream x313T0P0b3SCCB.c I$r9yr+[p{E=}JJS|hCX.O0c? &p`Q"p@#`p`2QpOar IVR endstream endobj 289 0 obj << /Length 163 /Filter /FlateDecode >> stream x313T0P0bcSCCB.c HrW0r{*r;8+. ц \. 001 `LAȃ=`Aԃ:\?DԡQ?Q \\\[ endstream endobj 290 0 obj << /Length 242 /Filter /FlateDecode >> stream xmбN0?`閼A' X*E"LSad`y^o+dc$sT@|89:]NT8V4)[bFw)/=e3ynr5z z^AH ^_kO mb2{ o)޼IPX5`j5҆uiSy 9i^Z&WW9+ow }:难{{ endstream endobj 291 0 obj << /Length 221 /Filter /FlateDecode >> stream xmAJ@tx9B FSjtB\U.jir(sn }|2)$9?J\ze\)7oϔ-o/Yr>RbGx+$qP-T 8a Hڔ@\fgm{`%NGPik,F=pk0jluo-9m骢;[| endstream endobj 292 0 obj << /Length 194 /Filter /FlateDecode >> stream x}ν 0+['SV8sh}>B.E$$q4MS;Q)+!׾28^0+Q.zŚl s ,5yofJNѭ>THA-I?6*<+1vL{Ԣyˡj endstream endobj 293 0 obj << /Length 226 /Filter /FlateDecode >> stream x}1N0g4M8$DTE"T+*Ar! D+f$4y{%w|VmisEoTwqZEzz@Mn+R;W\>Ұc< }:!1VxdV8H+-Y¬ȧȹ2sCtb<"C^D/.gx/ӊܬٿt==}h. endstream endobj 294 0 obj << /Length 244 /Filter /FlateDecode >> stream xm1N048IUeHZ()XA 8WDAr)5cHœ5\+.U͵CT2,.[ҷ\/eL#93\SaXw>:@~^M:_6;~qLǠVrﻘJX&{ب#Izc&4~g'.zw'ʗ EJsY#袥} endstream endobj 295 0 obj << /Length 245 /Filter /FlateDecode >> stream xm1JPYR |s}!` A+ RK Eʗ^a2Œ񟉋6̼yT尒x"p,\@_فs/*g. )&LOPvY`n ,{OěMx[l)zi&$vX?zΏE7 }t endstream endobj 296 0 obj << /Length 163 /Filter /FlateDecode >> stream x313T0PaS 2TH1*21PA $ɥ`bU()*Mw pV]  b<]HG#13acFT0ca``?p`L> stream xm= @irYV ),J--mM8mR,dgbF)MidPaly&T'͞ Zh = vA͒#Kv07}> stream xU̱ @ B>y;mB`A'qRGE7ih}>BAyMI!xLH4PЗt0F#F 5Q$ rJ ELErILY [A37yxZJҖ^ yY\-n-!vjQ8)|%\0ok endstream endobj 299 0 obj << /Length 197 /Filter /FlateDecode >> stream xU; @? ` A+ RK E[7GQr)h1/t)ZEyɗϴOC-*2gd6:%Smx],vKȬqzjHHHC,10\qEqRc,S4EB訵H<,l)o e@)]X!uE{/^q endstream endobj 300 0 obj << /Length 212 /Filter /FlateDecode >> stream xuϱJ@_RG> stream xڕ1 P q(dGx9OA ZN⤎m֣xҘ!$!'3N*Φ|INY>-KNɗ[~>^W݊SSNNT D'Ҡi!4y;쑷Gwp{cjCe s]ؗʞZ."US9©-KI endstream endobj 302 0 obj << /Length 218 /Filter /FlateDecode >> stream xeαJA b > ]vj<-,J--mo||ybCBdy-j /;~2xxD-+j.KtoOԬY:ni0s #VH|ěFo;s+lq΅Ƕd,6ɺY'=alp +%D7p endstream endobj 303 0 obj << /Length 196 /Filter /FlateDecode >> stream xm= @'X#MXXSZYZZ(m#Xo[fa5B&x#/~,+E³N|n-f-nKn!R7 !Hꇨ+U4jdcޑM-孍@l_ "j~' f&74.WHe4A o \s` endstream endobj 304 0 obj << /Length 181 /Filter /FlateDecode >> stream xuα 0+ zO`RL'V08iGE7}4бC1:n83d3dftJFq> stream xmαN02Xŏ{H.X*E"L0"5)oG1o`ŃsaA t7;/%KGvA)N v=4GOYScs W,6+"< .L)'rf;GpaF]1P.;a?2yWL ǹG9^jo.G82TJ="b> stream x}1 @49IH,-,J--mMoL2LvY~ Gc 0G8 q bɁD9쎐y Y|=,9 ܂IѱË_ꪽ^cf8y/>_[;bPsfm]vҨVi.oVڷ[eڏ2t6 endstream endobj 307 0 obj << /Length 156 /Filter /FlateDecode >> stream x313T0P0bcKS#CB.cC I$r9yr+r{E=}JJS. @-\. =2>gg`zp=a&f?qA|.WO@.J endstream endobj 308 0 obj << /Length 230 /Filter /FlateDecode >> stream x}ͱJ19X&ywl 'pVbvb7[E(6W77V80/̤mfRɾ@f|mcqw<︼Բ\vgt|y,/䲖ꊻPLdK?t4g1:Vu&*ޠw#¦%{"oOp($BJ(D|p0hs^>۹3k¸ cԤRP5y>ZsY endstream endobj 309 0 obj << /Length 154 /Filter /FlateDecode >> stream xuɱ 1 ኃG0O`\op Njh(bl-?崚aUÓ+>$?*_5o3z  H1D>1Cf$t cUIa.<5Ga D"JLKL`` ?:R endstream endobj 310 0 obj << /Length 194 /Filter /FlateDecode >> stream xu @`Ń0yVq :fNSuPY7|;4kuhgd4GO q^ͷ=@X f܂x>] C)C 6h[ }POmwj؊n֬GerۺInOs&y?ͅ_[*o&+jIhiKx endstream endobj 311 0 obj << /Length 180 /Filter /FlateDecode >> stream xm1 @ )xnBVJBBB"^do)BBbFST@F R/r@)Z?K6A}cE- ol}:X}"j&xovV$GC* ~f endstream endobj 312 0 obj << /Length 198 /Filter /FlateDecode >> stream xm1j@Ep!fsZ1d"W.B*'e h{A (&E a-]{^ҙ|Xr8}Rݒ;=K}A~qIג7j$2%32 ]hzdLs_Lä_Yt:wjh^H;FU.o%mZ-/LRz endstream endobj 313 0 obj << /Length 230 /Filter /FlateDecode >> stream xuνN0:D%{:&KmȀbj@y?BFi>@UJO򢸑Lȯ9Y^.wv™/}UI\ |~|]=%g\.7B>@T*ƒvPU> stream xuαJ@ )#d^@7!;N0Xr׺Qro`Y#\q|,Oۜ/Ҷ,7nV2oFOKds9F6۵l6PKF@f*;!ɅY$ rHT 'HqĘ8() p^we  * L1j ~-Sё1qx 0hD^)㫎 Zz endstream endobj 315 0 obj << /Length 179 /Filter /FlateDecode >> stream x}1 @]RVBVb(9BʈqvEy03L8I38Byrj5tكL@N0ހ)PR+IFdޒjIWZE,& *>`۰m$jKaj` U endstream endobj 316 0 obj << /Length 206 /Filter /FlateDecode >> stream xU1j@Eq!fo Rd\ l`W)B$e\vG)U8Mb3KtkZ>iyW]VGmZ[wy|گѧZg7}'8l"M !#T ppP\`~ԅƲꌀEwKr40À0=O%AnRZA endstream endobj 317 0 obj << /Length 176 /Filter /FlateDecode >> stream xuϽ @ nY ֫ 7:9::(>#tPCÑKm8r#:&xAk%5ጙC%k,ƭvd9%hr%HDbfRA#JA;=LVi@ &!`nOYo .n R endstream endobj 318 0 obj << /Length 178 /Filter /FlateDecode >> stream xm̱ 0H-}SV08ͣ7#tP> stream x==@!$x.d@ b&ZY+hq%g+̛@.Wy!5||4gN>0U(N$#;NQ=_;!EFg ꚮ~3 |4ؚ4#\Y]gr1WOL$ǭ#bVO endstream endobj 320 0 obj << /Length 216 /Filter /FlateDecode >> stream xEαn@ PGNO_KH@b!`b@L#nvH0e`'wgFJ)S)gG, 톊!څTVK:V6t՜b%71w%;]ͮ:$δ & nKoW1]ЋputF@uFjM0>ɏ) N6#0˾ j5>[ endstream endobj 321 0 obj << /Length 224 /Filter /FlateDecode >> stream xMα@ )iBy` A++Q);l3j:-(#IorNjNӜNP6hW%OR9Q[Qv$QKRvrM`> stream xu1n@Џ(Vf\^PXJQ*;eDv mGt .4#Jنc^"U4aY:m_ȼqy1'ˎ2%'PU2| (2w(ڦE-zD6BF{DIڝ3?mgDj # Arf#rNN,t']c^al оWqi7 endstream endobj 323 0 obj << /Length 170 /Filter /FlateDecode >> stream xe10 PW"y#' MKUJȀC X)GQz U 8eSI< e 15ߗ rKIr5JvDYPT)wK@1c5 0|2 GAw= /t:pZi|m˸иI Pt endstream endobj 324 0 obj << /Length 229 /Filter /FlateDecode >> stream xmбN@CA2 <əXg"WYBh<>%aKK6eg]B}}k{oxⷊ>.6-\WT<*#Syc]nyv@6CG'=D",2dfFz-mə1:;_w1|4t4hn7)xM> stream xUпJ@YR,LGȼnb.r6?` A+ RK E*-GHEq[E}\I)rVɢB+~ziRz>yzu^%k+snv#r69MD^HjO@IGJ3&`MS |08oF xo2("~B9~}B@BTB_Cmc1aH9ԝz xk endstream endobj 326 0 obj << /Length 224 /Filter /FlateDecode >> stream xuϱn02X%{D,Q*5C%N@ծu͏GCvaOoQϚGhI 5NXYQ39^pӢ>PB"m+}~|QovOdPoP2Gp=AΘ&n > stream x3235V0P0b#CCcCB.C Hr=BIQi*S!BA,A'W !$ endstream endobj 331 0 obj << /Length 111 /Filter /FlateDecode >> stream x3235V0P0b#CcsCB.C HrW04r{*r;8+r(D*ry(7?P70`szrrD7 endstream endobj 332 0 obj << /Length 170 /Filter /FlateDecode >> stream xՐ1 A E]8;v N!he!Vjih{9GdQސ<~~ ~p\p/J^[ѠL}V[9J2 >2tȖL ŒB@.Y*t}4Ik\7B> stream x3737V0Pas#SsCB.3 I$r9yr+Yp{E=}JJS ]  b<]H|`d!A b"Փ+ 0 endstream endobj 334 0 obj << /Length 101 /Filter /FlateDecode >> stream x3632T0P0aSsCB.crAɹ\N\ \@Q.}O_T.}gC.}h1\. 0 u'.WO@.y9 endstream endobj 335 0 obj << /Length 138 /Filter /FlateDecode >> stream x3531V0PaScSsCB.K I$r9yr+Xr{E=}JJS ]  b<]V0RP %B٣P?bP8(.WO@. endstream endobj 336 0 obj << /Length 263 /Filter /FlateDecode >> stream xeϱN@ ?y/iJ"JȀD' X{hy^cꊙD5=:駓|_.(_ I4BCjz8nZ:76 endstream endobj 337 0 obj << /Length 199 /Filter /FlateDecode >> stream xuν 0+['0~I훙G#t =猪!ARG4!3vYW}؟pRP>@}vD?YM)C?mFAh0Wp(Ԇ&R_GWRM1|w5F ]5IW'C{p:V# \ 8.y endstream endobj 338 0 obj << /Length 184 /Filter /FlateDecode >> stream xڕ; @ )Bnb*#X٣(9BKY#X[?MbJ]-(9ktRSZ*KJPUtH(>> stream xڵ= @FR2'p$!v-,J--o d3<6{A\Ƹ+ [΁Di,7P3P#eƸ֠5->E)tDL̔Z&U!˧m,Jy"LXI?嵏]&^-VgǞZn$̴ɦp h endstream endobj 340 0 obj << /Length 191 /Filter /FlateDecode >> stream x]ν 0S:w#>mб N(Q3 \'3ʇE)rF2:Rߥ}ה$S2{Z|)/&QR:tCuňC:DvG|iFyV;tPo07{KxN. P5 ҂5-Qle endstream endobj 341 0 obj << /Length 264 /Filter /FlateDecode >> stream xڅN0 ]1Drop @ZUt`b81# xlB$7bBb"~??;㺧j|ƶoE]p3A{)~=\SvK;rJxP0w4{\ .c9N]"Yp&Zmm1B`XX 212sP)HrL51UW[$tUݒYņ'r endstream endobj 342 0 obj << /Length 157 /Filter /FlateDecode >> stream x3530U0P0bS#S CB. I$r9yr+Xp{E=}JJS ]  b<]3$;d%YH2$@A6W  H$r  WH endstream endobj 343 0 obj << /Length 122 /Filter /FlateDecode >> stream x3235V0Pa#SSKCB.#C I$r9yr+r{E=}JJS. @-\. 0!("3#! F#.WO@.Nq endstream endobj 344 0 obj << /Length 198 /Filter /FlateDecode >> stream xڵб 0J-}TZV Nj}G!̝:w'dfiYNf6\`w4=]/tbMf u~CQӈ*SKc;[ȩXeٰcF:ԋ!1H޿B !%ԉ=ۈec'l_ق0aOP endstream endobj 345 0 obj << /Length 105 /Filter /FlateDecode >> stream x3235V0Pa#3S CB.## I$r9yr+q{E=}JJS ]  b<]3GBqzrrW endstream endobj 346 0 obj << /Length 188 /Filter /FlateDecode >> stream x= ` C!GhN"  N(kyo =7:8pӺ.fϣRv39;6X|6|GB%%9 " 4Drr{EfV5 RגS^r_,IQiN[)%[y/ [> stream x3530U0P0bS#csCB. I$r9yr+Xp{E=}JJS ]  b<]1` g$m7>0`l@"$'W  endstream endobj 348 0 obj << /Length 176 /Filter /FlateDecode >> stream x3137U0P0bScsCB.C I$r9yr+r{E=}JJS. @-\. 000$700cA2 \ i$ ?l 4b>.d!p!dr~$_\\\-in endstream endobj 349 0 obj << /Length 193 /Filter /FlateDecode >> stream xڭп0$ h[I;`A3>#02+hMK`#8c1qgaSQH-1A9O=t1A*õA]OPöJAy)Ir&~mk]{77xܿf}N$nC&L-, endstream endobj 350 0 obj << /Length 187 /Filter /FlateDecode >> stream x%= P7.BBBQy[Hθb2+$+]n: 2/*NrN7rZmx]9]bJV9q*> stream x3634Q0P0bc#ScCB.#K I$r9yr+Yr{E=}JJS ]  b<]0<z @?bT 7~`@400cr pR endstream endobj 355 0 obj << /Length 120 /Filter /FlateDecode >> stream x3632W0P0U06R06P01TH1*22 (XB$s<L=,=}JJS ]  b<]a_#\\\^"/ endstream endobj 356 0 obj << /Length 96 /Filter /FlateDecode >> stream x3632W0P04F )\\@NrW %E\N \. ц \. v `Փ+  endstream endobj 357 0 obj << /Length 154 /Filter /FlateDecode >> stream x3632W0P0Q5S06T01SH1*22 (Ads≮=\ %E\N \. ц \.  |yf`{ : ?@?@03?10#3Lc\=Q3k endstream endobj 358 0 obj << /Length 103 /Filter /FlateDecode >> stream x3632W0P04F F )\\@HrWr{*r;8+r(D*ry(13oz;S'W R# endstream endobj 359 0 obj << /Length 101 /Filter /FlateDecode >> stream x3632W0P0S04R0T04WH1*22 (B$s<=L=}JJS ]  b<]\\\ endstream endobj 360 0 obj << /Length 214 /Filter /FlateDecode >> stream x%1N0бRXf8٥Y%ҲH@Q%h(>DVxd}}o垯ot-Kv}]޿8}aע}(5>C{׎7NLMKDaK&d|5 Rac`|R@HDj)ť !SR٬j܈t8h+LaM0y54'|ca5 endstream endobj 361 0 obj << /Length 131 /Filter /FlateDecode >> stream x3632W0P0bcCCB.cC I$r9yr+r{E=}JJS|hX.OȘ.b#˃3 c ÆC\=M\( endstream endobj 362 0 obj << /Length 168 /Filter /FlateDecode >> stream x-̽ 0>B LP)P+AAA9>cR~p;Κ9Vhkr+tm f-S0~.Q= *4qI9bH+MjT  3B-). #-%$s|;tI endstream endobj 363 0 obj << /Length 171 /Filter /FlateDecode >> stream x3632W0P0bccCCB.c1s< =\ %E\N @B4Pe,P1;>| ``0@:(Âj>0PH?`@~?s.WO@.eT endstream endobj 364 0 obj << /Length 162 /Filter /FlateDecode >> stream x3632W0P0bcC#KCB.#1s<L=\ %E\N \. ц \. a`XA=}C=C=CX0LS|zy'W 7 endstream endobj 365 0 obj << /Length 170 /Filter /FlateDecode >> stream x] 0E_xK?! L")P+AAAѵͧS Dpz>*NhtxoW銭EA-*yAnQutTv9O `v587PD"D?D0A9J|upeq.L endstream endobj 366 0 obj << /Length 143 /Filter /FlateDecode >> stream x3632W0P0bcCCB. HrW02r{*r;8+. ц \. 0@l0ر`c`@7 j(cՓ+ @ endstream endobj 367 0 obj << /Length 214 /Filter /FlateDecode >> stream xU=n@4 -w.f 4HqT)A$[X+>=Ɯ!۔f<ݬ͎f9%l3J^U$_pdªy5s:.!_MWHa~”E:Su@I #ABФ?_Fr"@@;^p6kʎ4EN ZH endstream endobj 368 0 obj << /Length 144 /Filter /FlateDecode >> stream x3632W0P0bcCCB.c# I$r9yr+q{E=}JJS|hX.O bv|o`G\=<[ endstream endobj 369 0 obj << /Length 119 /Filter /FlateDecode >> stream x3632W0P0bcC#CB.# I$r9yr+p{E=}JJS ]  b<],"ؑ@6'W w2 endstream endobj 370 0 obj << /Length 144 /Filter /FlateDecode >> stream x3632W0P0V54U02U01RH1*22(Cs< =\ %E\N @QhX.O ?PP01 ba? ?`'W \O endstream endobj 371 0 obj << /Length 177 /Filter /FlateDecode >> stream x}1 @Ѕ)ir l6b#X6XXzs),ZY<^7SDE{1GX05(cnQ)-t6"-yBQ^W/Bg;Ze#R VnVkxS> aP9~cs|"Xj endstream endobj 372 0 obj << /Length 112 /Filter /FlateDecode >> stream x3632W0P0bc#CCB. HrW02r{*r;8+. ц \. Gz f8\?aՓ+ Ϩ0m endstream endobj 373 0 obj << /Length 137 /Filter /FlateDecode >> stream x3632W0P0bc#KCB.c# I$r9yr+q{E=}JJS ]*c<]7a??`H?#a\\\R_ endstream endobj 374 0 obj << /Length 165 /Filter /FlateDecode >> stream x3632W0P0bcC#KCB.#3 I$r9yr+q{E=}JJS ]  b<]?``cogcgcoao;V a:z{  2d>.WO@.=D endstream endobj 375 0 obj << /Length 178 /Filter /FlateDecode >> stream x3632W0P0T54U06V0TH1*26(@s< =\ %E\N @QhX.O` |:: ;<7~P=Q?L^s endstream endobj 376 0 obj << /Length 142 /Filter /FlateDecode >> stream xڍ; AЎ+ }燈麂(+G(a1 FC?f˾'5&¬9XywYNql-ࡒDE4'L*Jz#R"?OsՎY o"G endstream endobj 377 0 obj << /Length 160 /Filter /FlateDecode >> stream x1 @D*77@VbBmM> stream x3632W0P0bc 2WH1* \.'O.p#s.}(BIQi*S!BA,Cܸazp0?10a``BJ( endstream endobj 379 0 obj << /Length 155 /Filter /FlateDecode >> stream x3632W0P0bcc#KCB.crAɹ\N\ \@Q.}O_T.}gC.}hCX.Oc Px??g`| >@ `X```o`r ; endstream endobj 380 0 obj << /Length 154 /Filter /FlateDecode >> stream x3632W0P0bc#KCB.c# I$r9yr+q{E=}JJS ]*c<]?C? ?>`D+0|=GA&szrrH endstream endobj 381 0 obj << /Length 170 /Filter /FlateDecode >> stream xڅ1 @/49B݈bSZYZ Qh9J2E0Βvg; ly 5]Dvr8SڲH-%&vH9kR 4{J4MSW0SE V0prs]u TȣHiCC endstream endobj 385 0 obj << /Length 164 /Filter /FlateDecode >> stream x3231V0P0S54W02V05PH1*24͡Rɹ\N\ f\@q.}O_T.}gC.}hCX.Ofv> 0`o`oggC(@+ tB2@@;ev30szrr2 endstream endobj 386 0 obj << /Length 164 /Filter /FlateDecode >> stream x3231V0P0Q54W02T05PH1*24(Cs< ͸=\ %E\N \. ц \. 00X00137070`|V <c :N9@A&3`n`o'h.WO@.)V endstream endobj 387 0 obj << /Length 90 /Filter /FlateDecode >> stream x33T0P0bCS CB. &r9yr+Xp{O_T.}gC.}hCX.O@Pgo9 endstream endobj 388 0 obj << /Length 137 /Filter /FlateDecode >> stream x3235T0B#S21SH1*22Bds<L=\ %E\N @B4Pq, CEß@?7mfl` vf6 bgccca`((`xpՓ+ &F endstream endobj 389 0 obj << /Length 143 /Filter /FlateDecode >> stream x3235T0P5T02U02Q01SH1*2 *ɥTåU()*Mw pV]Fry(03310XX00$0> stream x]Ͻ @  *xWm[uTt{>P> stream xڥбjA9 {wl"VB"RK-Qԝ;AmbvfsžRC/J|I[ї冊܂}Fn)}~1J~K9yd@ lm9%QX@|цH5`$ƣ{_;kA1m;z4KqͫmЅO@ #"P+ endstream endobj 392 0 obj << /Length 159 /Filter /FlateDecode >> stream x31׳4W0P0bSCB.rAɹ\N\ &\@Q.}O_T.}gC.}hCX.O`0`H0~?DԁzD\`Y6 (Z endstream endobj 393 0 obj << /Length 141 /Filter /FlateDecode >> stream x35г4Q0P0bKSCB.3 I$r9yr+q{E=}JJS ]  b<](G dQ"- d@ <"yp ap@$'W O endstream endobj 394 0 obj << /Length 177 /Filter /FlateDecode >> stream x]; PEo o6<Vbv'غtn2EHFÅs:XsgyӞd>e8%w!܉hr)-lb^gEihѶ tP"Y~ЅqdXS(\!(iPC] mj7ҪS n1 endstream endobj 395 0 obj << /Length 182 /Filter /FlateDecode >> stream x33T0P0R5T06W01SH1*26 (Cds<M=\ %E\N \. ц \.  ~NH~ ?j?01?` 0L @e5Ȣ ?Փ+ M endstream endobj 396 0 obj << /Length 167 /Filter /FlateDecode >> stream xڍ1 @YR nv6 n!he!Vjih'qGRZp5Lܔs<6lg  ^9l KQ߮z=g|a9Gt)B(PD 1 PBʇK|P\x0> endstream endobj 397 0 obj << /Length 180 /Filter /FlateDecode >> stream x33T0P0R5T06W01SH1*26 (Cds<M=\ %E\N \. ц \. ?XN0 @Ar?``?h> stream x]1 @RnvA"+P,$(!E n1CXs_qxD:qeı,#e5$_l9eE2hKE T760= ӦAޝG4+ Ya|#xxЂf 8 endstream endobj 399 0 obj << /Length 199 /Filter /FlateDecode >> stream xm= @' H2$&L!he!Vji(H ^DoV#*ZX|3Û;=í8ae&=X҈{ p:p"9ӖlȒx)O+G rߜW3=TU4 hʹtCPZa3+eG_5jd4iNB@ endstream endobj 400 0 obj << /Length 146 /Filter /FlateDecode >> stream x33T0P0bcs3CB.c I$r9yr+p{E=}JJS ]  b<]000 "88{ ?8qV? ?&\= ZP endstream endobj 401 0 obj << /Length 118 /Filter /FlateDecode >> stream x33T0P0bCs3CB.C I$r9yr+p{E=}JJS ]  b<]?@ h ʐ'W =!45 endstream endobj 402 0 obj << /Length 105 /Filter /FlateDecode >> stream x33T0P0bC 3CB.CS I$r9yr+r{E=}JJS ]  b<]BTՓ+ ": endstream endobj 403 0 obj << /Length 164 /Filter /FlateDecode >> stream x33P0P0bS cCB.SS I$r9yr+r{E=}JJS ]  b<]3`? 7g?|0o?TTzCuf( H@).WO@.`\ endstream endobj 404 0 obj << /Length 137 /Filter /FlateDecode >> stream x33T0P0bcscCB.c I$r9yr+p{E=}JJS ]  b<]c`1~``">0Z0'r M endstream endobj 405 0 obj << /Length 157 /Filter /FlateDecode >> stream x3632W0P0R5T06V06TH1*26PAc#Lr.'~PKW4K)YKE!P EACv ,yv`Q5 ?`Bd7`? Փ+ v?X endstream endobj 406 0 obj << /Length 186 /Filter /FlateDecode >> stream xڍ= 0'}$ ], ftr'utPtp:v( ԡoOeLF4Ԙȥ"ՖvGL55.yDFآΈ }o J`J30V@ AaK}Ư/橀˥5 6?pq_Qn endstream endobj 407 0 obj << /Length 124 /Filter /FlateDecode >> stream x323T0P0a3cCB.#c I$r9yr+s{E=}JJS ]  b<]?o^:u?ذ?`$# 'W 1R endstream endobj 408 0 obj << /Length 169 /Filter /FlateDecode >> stream x%; 1F?p۩$:(+PmYf)H"x _u*[}.  ɖ)\ٟhRް-I/R&]/zIOVS6g5\쨞d-yvT"4h<, "2cA.-^I@aIO0hD8'yMk; endstream endobj 409 0 obj << /Length 138 /Filter /FlateDecode >> stream x3231V0P0T5T02V01TH1*22 (Ads< =\ %E\N @QhX.OzE?3L8$ Y0~0`P#'W E;G endstream endobj 410 0 obj << /Length 167 /Filter /FlateDecode >> stream x3632V0P0T5T06S0TH1*26 (Ces<M=\ %E\N \. ц \. 0?&01?`  @D2Q%=;g=p`#?``.WO@._x3 endstream endobj 411 0 obj << /Length 195 /Filter /FlateDecode >> stream x35г4Q0P0T5T05P0TH1*2 (Ces<L,=\ %E\N \. ц \. c!0`  `$F([cWdžJHȱ!Hy igσD00'@"o00-J7B ?qzGx endstream endobj 415 0 obj << /Length 114 /Filter /FlateDecode >> stream x3631Q0P0b#SccCB.C I$r9yr+Zp{E=}JJS ]  b<]00>``O0ZՓ+ V4q endstream endobj 416 0 obj << /Length 171 /Filter /FlateDecode >> stream xɱ 0+ ?D'0iZM ftrC>Z1C 6wrZ,G8уā"Vz˯J-9#cDzŁEqʰ10;- 0q#1™3Zkg6T endstream endobj 417 0 obj << /Length 170 /Filter /FlateDecode >> stream x-1 0t{wMtB`A'utP:֣3jox?> stream xuϱ 0[z/imu* vtr'u\G#tPE#.p?" 01C8jfwF!xz-qb"G<)o)~􌍭omƻmjVFf+ɇclݟO2ΗVgvdMi5L?X:pc=_Чn3'VO endstream endobj 422 0 obj << /Length 231 /Filter /FlateDecode >> stream xUj@ 9s;/U֤*X ɃxRBZsOP|3jWLĤū3+C ,t"y\6*v211E[&:|UdoM~3\<9L^|Ip` endstream endobj 423 0 obj << /Length 212 /Filter /FlateDecode >> stream xM?@oH1\@ȻNbjະ)+P $`Nog7)SdgFA/}q7`o:Ph>ggiLjaDGIſ|:w/Hxx@@6/cGP!R^!'TH3=,њR;gXK%Hs$h%Ƣug+> stream xMϿ@-70&aÀVW՝rWGˣlg[QsŧMyK)!Jp1|pԠ:_gzPzJ S ĎԬjukzE Q)]xĎ/լeQPxўc=r_0%t,!_ endstream endobj 425 0 obj << /Length 193 /Filter /FlateDecode >> stream xm=@!$ S $&ZY+hfx=%-l,f&LC9QQф)LLs IK^nGՌ9owT p< AZ-@:hM,љTY(P zG߁ؐIavU.R8Uk Z B endstream endobj 426 0 obj << /Length 248 /Filter /FlateDecode >> stream xUαJ@YXrM.A\8O0Xe _|XFlR,3m/ʽe4ݜg4/6G,r|{eSVgrvy~L9]]c"-"46"n"ja g\ô 꽅}abZvLRȴWWqz=A腁=AFZp2Ǥ>}m1fxԑ0S!9TxR^ endstream endobj 427 0 obj << /Length 190 /Filter /FlateDecode >> stream x=ο POG@]A(AAM T EmB/fo#AB߁;ˁ.=t谿6;)#ɭI;~=7~.ɄO.;gJ +92 = Y5"$*GE1_kMAێfb)n! a!"t5}6)G endstream endobj 428 0 obj << /Length 182 /Filter /FlateDecode >> stream xU1 0_:`/PMCv(j3:9: U:zI!78QL#NN"# ÈDkg%- lcdrE,_ω#+h(  0RGC:k3dV4P` {@1gy9xΡoi|KZCf1.$n > stream x363P0P0b#sc CB.#C I$r9yr+r{E=}JJS. @-\.   ?0m'W ;> endstream endobj 433 0 obj << /Length 184 /Filter /FlateDecode >> stream xM= P ER[ |/ BlSZY `4G(9,_3q&j5qPr-NFm1cb҉筘t.BKI @?PV^F3@|X,`ܠ^B5j:GF_8 endstream endobj 434 0 obj << /Length 187 /Filter /FlateDecode >> stream xU= A `!:;, [ZYZ * "ͣ,- b%ԩFIK}Xvԭd^.vI*vD-6a\M> stream xڝ=n@raisq:K`$\ %E*PR$JZ|̳҅Y}7>'t*D<ũ$/LJ6k36K$lʕ|n^)=B#5QPDW:%#Jc9уr4vh| }*qlz={[#3CS5=97 endstream endobj 440 0 obj << /Length 224 /Filter /FlateDecode >> stream xڝ1@EPL $&ZY+h+pJ "θL&4ٿv<Fq0!liza zlza:m+TM܉JRNIPhSh50O"gRE4;hhZz&/z( ɟ|{=eo }⁝vw]Svˎuҹ?࿀ykxB{ endstream endobj 441 0 obj << /Length 105 /Filter /FlateDecode >> stream x3634R0Pb#CSCB. m@ $ɥs{IO_T.}gC.}hCX.O!'W ( endstream endobj 442 0 obj << /Length 96 /Filter /FlateDecode >> stream x3636Q0P0T0P06T02WH1*2 (XB$s<,=BIQi*S!BA,\\\5^ endstream endobj 443 0 obj << /Length 291 /Filter /FlateDecode >> stream xڍ1j0a  jR'YbHSB;u(ڎZڭؾI=JIqT`$/VI~k,sOxym ɓYSH{dsf=;#ҍkTNUD38L41裵>+*bT)?d C~yE}QKZq<8ZTb+Ώ1ܼn NqA(F.gEㅸ$ > stream xڥ @\z Z< fNSuPԹG> stream xŒ=N@ M!$)fE"T (AKrSXؓ,=S$_> stream x3137R0P0aK3 CB.cS I$r9yr+r{E=}JJS ]  b<]lQ3\=i% endstream endobj 447 0 obj << /Length 149 /Filter /FlateDecode >> stream x3336T0P0b3#3 CB.Ss I$r9yr+s{E=}JJS ]ry( h 4?8h{443fPB3\=a endstream endobj 448 0 obj << /Length 277 /Filter /FlateDecode >> stream xm1NP!$p*l!YD ,6Vjid;<e`Ia93o,(H~<+mTъvE-Ur+pcH[>ŲϏW,7Tc]M[ !@‰:,]W`t~]'!LdDUHZKZi:j4DGDiU6LKGT:ҴJ*M¤%#Qt'%#Q2bⴉ&N#&N8m+L\T+wetA f U,(we#ĿRWY›XM endstream endobj 449 0 obj << /Length 185 /Filter /FlateDecode >> stream x3735V0PasC3 CB.3s I$r9yr+s{E=}JJS ]  b<]co100U@  P3 v,f[=n/O~085 )cpzrr\ endstream endobj 450 0 obj << /Length 355 /Filter /FlateDecode >> stream xڽN0t%o @F `b@L )xnF!c D|wv~8,Y2lfq>KOfUg^rܤ__M:̤kp|g5@D;ЇPT8iBFbh͹R+م$Vt=x]b#/O{Բhz(y݇*P'8O?he hRڪ+k\jFmv rq]R1q 5ƴ`rga'8o `۴j854遱 0{VU0̹/AE Vڂ(͵3( endstream endobj 451 0 obj << /Length 305 /Filter /FlateDecode >> stream xmJPO"pyfaa]Vbv ɣQ)#\83w.x9zuhI5t^Sҽj-%]2on۸+n$>?^];z,i<H90w{1c]< h=Q=6 zh,݌$d1b׆ا#XA}ăiM֩S-dpAí$ r0cGݑ"y*\'5 К?)ԜhVVQnܽ endstream endobj 452 0 obj << /Length 208 /Filter /FlateDecode >> stream x= @G, &"),J--mMQ> stream x}ϽN0Jl;Ta?pۜ7kBjikVb7/;8jC'_o6RsS-3[&0`Q0|T*M *pӌ_2 $Lo1ÔJc4|ݜ~82;eSz)<8`͊N9y{2hl endstream endobj 454 0 obj << /Length 229 /Filter /FlateDecode >> stream xő; @72M4(SZYZZ( h"8P+q3z ;MVYmcsd4ٟ9ą!8~̸+fܒ^ ke"e, tGd?˄b$U5Ҋfl$*lMgn CJhVʷ3Fip endstream endobj 455 0 obj << /Length 214 /Filter /FlateDecode >> stream xڭ1 @E'l&G\@7E1#BBBQRgEv>'S &3!3c4#NqRdn uS:]L> stream x1 0yд*N`A'qRGEx 7бC=q(8 vي1&]lwqy,N1y 6n_pa8&:2)љBztUUN+IZ^>j$qIMMR'*mse cL@I 9Lwni endstream endobj 457 0 obj << /Length 226 /Filter /FlateDecode >> stream xu=n@gbi|eYGH@TDjh> X VyyD%JC80/*v[ dvջ\/_Gvxv+١hJʞ2Ն(W FOFFl@&%`}b zdeL,>2~dgygL[41Ƕ hKyJ BasQ D endstream endobj 458 0 obj << /Length 281 /Filter /FlateDecode >> stream xڕ=N0’!sHE"T ()@`)<؋$'{Iן5-5tA-ukZw75oZOv3RpC/^Rk-=ԣ/qZqg XxqdWjIpnIUi+W%KK"5-CiK #;A58E, k΢SvYlK S^`%*#G4dPɲ1:^.eiiC%>+^ ~ endstream endobj 459 0 obj << /Length 131 /Filter /FlateDecode >> stream x3634R0P0b#KsCB.#1s<L=\ %E\N \. ц \. 5 7?D # P?P1?H{pzrrD endstream endobj 460 0 obj << /Length 220 /Filter /FlateDecode >> stream xϱn0 HrObB*L 22*+cc" F,YϲA/~o:ϜuʰXoiTYp'3d|6dFcLxsr‘"?D+c~DRdZ+-ЭAR.ZT7rBʰU. (]«],D> 4Hsz/iNW^`ص endstream endobj 461 0 obj << /Length 107 /Filter /FlateDecode >> stream x3634R0P0bc3KCB.#S I$r9yr+r{E=}JJS ]  b<]0q7c.WO@.S endstream endobj 462 0 obj << /Length 209 /Filter /FlateDecode >> stream x? P C!;Bs_ZA,T;:9::( n>'GoqQzJcߗdڍZE5eujh}OSXcu4vB{%gQh@&lJ2DxbΪUdK 9T`P+XU.> stream x3332Q0Pa3 ebUej 䃹 \.'O.pSS.}(BIQi*S!BA,C}?7T10@ 6P?|'W [ endstream endobj 464 0 obj << /Length 213 /Filter /FlateDecode >> stream xڥ1 P #B[SV N⤎h=JбC1&E\|>?dј>c &tA$GOX4 "4 %]/#d5#MJ[h6%y=\0`..Y尀AK<@\@Q#6-WQwu;Sw ?kBKn&j״1a>7k.sk|]ŏf endstream endobj 465 0 obj << /Length 227 /Filter /FlateDecode >> stream xڵѱjAY,i|tNWbe!V&e->B|-XDTX>euڝLJ+Hޗ,ה?8G۹)ϲYo؎^$e;E*ɒPS݁T+(5OT@u%BMwF=poH-eua~nl]Tȇ`1)6AbXi DA O  endstream endobj 466 0 obj << /Length 237 /Filter /FlateDecode >> stream xڵѽN02Do@1-`b8o+ yV?0N0X?lپ> stream x3137U0P0bcSCB.cK I$r9yr+[r{E=}JJS ]  b<]oH?1"~`? L7?bl'W n endstream endobj 468 0 obj << /Length 223 /Filter /FlateDecode >> stream xE1N@ E?b%790;"E"T (AKq%GH"4o4v]_+^sk{w6[{T^o(=fKdJ~|Q_stgj8UR:EZ ʷcVG@VjU'3rع: Fg u1vM#bj2;4@* endstream endobj 469 0 obj << /Length 173 /Filter /FlateDecode >> stream x3135S0P0R5T0P03VH1*26 (@ds<M=\ %E\N \. ц \. Xv8'=3,X w'C=`?`A<7@ ? r  ,t endstream endobj 470 0 obj << /Length 166 /Filter /FlateDecode >> stream x+@i*6#06&$  (D@@/G[58"e9P!Zj Z)%eʡ^Rv3:N[|LuM+C]MD ! a9PIcУd/-x>o;w*!aVB78\ d endstream endobj 471 0 obj << /Length 216 /Filter /FlateDecode >> stream x}=j` `-A䳋M)PH !SڱCC |'ꫯo4J$QLS<Üh'+v 3v/ز^e`7O$e7e*Ɋ*#3Qs;*ؗ /@ih#2+1@[|iơy(sG=ַ G#ʳpH endstream endobj 472 0 obj << /Length 267 /Filter /FlateDecode >> stream x}ϽJ@Rn7p h~(b`]VbB !y&)Sdw̙SRqKu&Zso\iLs9 gRiή1笹ַRpBGn6b-eFGZ0Ucc^pG))$)Y= Ư㗥itjuGj wAlhA_Bg6UT2u2Ho^_˄>> endstream endobj 473 0 obj << /Length 126 /Filter /FlateDecode >> stream x3530T0Pb 3SCB.c I$r9yr+[p{E=}JJS ]ry(000```` H0@,0%#zl'W  endstream endobj 474 0 obj << /Length 266 /Filter /FlateDecode >> stream xmбN0|G/qCyfίF0t^ߟlߣO;O$9 1!rHdڈ4f&pBl9{Ð68,ִ/vKqbҷ+tي%+NC7"EB8сVP #RI*h~j:Rᕤ[Il`Φʗ'& endstream endobj 475 0 obj << /Length 253 /Filter /FlateDecode >> stream xڥ1N0 `?uGx^:bF4G  Gءj]&`>EIc;Gy:r>fG}=~@{M;vyJn-2ЀL]_~EI-jV8Yz&? }Bs훃$ShjMM|wSSYN-Nm8NZT2f5JD 2Mr[μ̐51= x_d endstream endobj 169 0 obj << /Type /ObjStm /N 100 /First 899 /Length 4050 /Filter /FlateDecode >> stream x[[o~_1Cgx9FخMS$FZ;t ܛ\ky$<}BSx,ug\0m;b4A'.:_$vRD:NXZjWx08HMWɠ:XtA31X ,phԖ@ _Ƴ@BM'43 8*44! "'uCE gY~0<34l}+ԓt`8NFDe:1ʲgX hvM!bwa4#gNuT|ub iPiLhd_g8t*Zq9XƇ+2eo#zS#u0h%h],ꊆaK:#MLqru1$=Vb,גZbјHh.8 3u'FVm5cI64Xpݱj' ~? 9 8.bmCqy4%,ЖaP0\Z$s%9G f/^̆< V7J7 .nWw̘j9{+.fi*H 5;9y'bW|\ݼog!a.40w/7xm矖7w6xr[WoZ1qޠỻ79L=4wf6.H X\,/w7V-|;|Gif*1VXY|ys_/߽[`$9o;qÇmϻfqxW+v9_Y ˻b\/>^:lWr~\/@"KLpDۡ]- k=\b%󧻛݇fX_,1\Y@nF˛bW0|5z..7[`W`zgS\J}d_v/^twnx}nn8(L8Z%%+,| XDžoxݽY} ?o`cpOSX=3s/1-{y7G.'Nqb6NHpھp/q@/5T"qdDŽq烫o~;\}"wذ-0 o nTs T `t ?`;.Q@*#1^{hP@~ { -Yt}{KE9QHw@TNf!FIqн]uxܮ:=svQ{>ʵV96g]b:o@x*[S~rm?UnԱUnʵ;]cAagiBXH>bUG{ģ9X8}1vS6#qLb7Xfg,ބ31VNޭBG#Pb 8;|^r4H27c«]}>`).2oͫkl|Ley6p6r@o}B8,ߩ,3G-NQ7N>V$& e"_f[BQӻÿOIo3ƍa KjLƝ^#bCT;abѝЦ1%ׁ'g΃&?O (Ak9ttA-JbR9 9xR 42+V9 XXfaš5 k3` 62@}Gn=*4sfY=%+eUL Y7%x.˄)m"lC 5gѣLPD(F(e@Q|IJ%`1.C͒ΖZw+) /𢳃к+h^xɧ}‹2z3 /g {s1{AH]C'Ch^$&)FtIGJ)ζÜ1t&:=`؆c`[msq2OW* Tqe儸&+մqeMudW:*PSnu=tD=ԲLJ;{3$N *H-Uh$E~ ,9/reWN(L6T6Bm#>?')!"F9*O] 'U̡EzR, q0Ga b&F yAÔ2 yL(xaf8ek|#$`<ٙ*%0 ^ H0Kh5=NM,2FHQnTd>/ M|YhJ\z|ɗ!MjRp&v@bUQ'2:am Q'r:ao BNXuªԨVFZ7զQ':a4ծQ':auh cNXuըN R)QC>nVj_%U:)sDjtYo4y>]6wz3q.K,Ԑ@[$&Ne04Š 1M3Y9"@haƏ\B>KF[() [XW-fi3g8Š ,*bPd1S60eS SZ`Ķ$ScW%^lUjWekm "D\D]d<  +XM׆Ik0P=)sdK~}jc 3T޴U.iP6РO |^m@Bݏ!rv8똅2ΪE .5 T96.oT[|ĝrT<p xjG޷ C B> +xݠZH `Z  -CB IaG пX5 {$xIxxexG=NQRA/%DW21| ˜ƘeFc?gUUV|B&Dr@ᆵ\1{-}C7_8dЗSrseCOt| pOz+e3=t>l7Ei8 *<|U I˥XXߠ_H=\Uֶvv'"5f[N_;~ɷ*X -lSjպE' I7wRMT{T{ST{G4&r>V=xpFM'[5pu'㛤ߜn-[:UMK_[5*BW]5R,o~51 WRGw:;Y8Z}#s{a=۱A:bQɑpGgL94P/Gyyçtah6f=J>*).l1%5ߢ -8g%&~l?S]yW\Tj_U%)&&O<8q9!e,[?ߴm)TSȚK)S>wݛ[hob8df՟wE8lX;LzXIc]ǩ.G0Y[Lgq:PG}J]lZ "uˣzck.{% 'UӇbz> stream xڅ1PDPl Ċ1D+ cmq@IA;WL0 v xlagnEt4'g'Ty!n{> stream xڅO; Pl {I*L!he!Vj)h-G,-$q̃T;LNuihuɗV'/2O4Ĭxq7 $$M | ,G\W{F9^ـ"J[|rY"ֱ4nT?pGrjݬc_e*[M* endstream endobj 487 0 obj << /Length 99 /Filter /FlateDecode >> stream x313T0P04F )\\@$lIr p{IO_T.}g E!'EA0XAՓ+ ; endstream endobj 488 0 obj << /Length 157 /Filter /FlateDecode >> stream x313T0P0U5W0T0PH1*26 (Bds<=\ %E\N \. ц \. @#HD؁:Q'@&> f0d82>3 df Dpzrr@: endstream endobj 489 0 obj << /Length 107 /Filter /FlateDecode >> stream x313T0P04F f )\\@ IrW04 s{*r;8+E]zb<]:\={-= endstream endobj 490 0 obj << /Length 117 /Filter /FlateDecode >> stream x313T0PT02W06U05RH1*22 ()Lr.'~8PKLz*r;8+r(D*ry(01l;cNJ l r \+ endstream endobj 491 0 obj << /Length 184 /Filter /FlateDecode >> stream xm=` .߁1D'㤎]ċ8p n #~$(}L> stream xڝ1N@4QY AT (Ar 3AzWJ_kN|y9H/vI'Zun8-)\ؙBwoVWg)6r}Gݚ3J~ ZTMa.)- o̤/`tR27V֯ifhh`+-RN]dvg9 endstream endobj 493 0 obj << /Length 183 /Filter /FlateDecode >> stream x313T0P0bCSCCB.c I$r9yr+[p{E=}JJS|hCX.OD|?b0 AD}&> f0H0b!On%rv?s?>  `szrrǁG endstream endobj 494 0 obj << /Length 147 /Filter /FlateDecode >> stream x313T0P0b#SCCB.c HrW0r{*r;8+. ц \.    `|$lthvb)،6 Q .WO@.̌r endstream endobj 495 0 obj << /Length 145 /Filter /FlateDecode >> stream x313T0P0bCSCCB.c I$r9yr+[p{E=}JJS|hCX.OH" $`@CLmQD !( ,x endstream endobj 496 0 obj << /Length 108 /Filter /FlateDecode >> stream x313T0P0bc SCCB.crAɹ\N\ \@Q.}O_T.}g E!P E >Փ+ HX~ endstream endobj 497 0 obj << /Length 123 /Filter /FlateDecode >> stream x313T0P0bCSCCB.cs I$r9yr+s{E=}JJS|hCX.OLŘN|? ?*f endstream endobj 498 0 obj << /Length 177 /Filter /FlateDecode >> stream x313T0P0b#SCCB.c HrW0r{*r;8+. ц \.  B`W${1y 01h͇q|Fa  l?`!'W , endstream endobj 499 0 obj << /Length 194 /Filter /FlateDecode >> stream xU-@%&c 迨 P$u[GEev K1h8&nL؃-;CFXA_>pi ?!&+R"c(ɉ(N+ƵGSroW\"Ϡ+tIߣmśh5| dXB]/qs| endstream endobj 500 0 obj << /Length 174 /Filter /FlateDecode >> stream x313T0P0bSCCB.cs I$r9yr+s{E=}JJS|hCX.O0"370`H؃@`?#^^Q`Cƃ-Y  f $700 F"b\\\wN endstream endobj 501 0 obj << /Length 209 /Filter /FlateDecode >> stream x1n0/ʀ! &HYj کC @9j1CNjKޠ{iˊs.y^,V\.x_ЉۜWH[KEԯ|9_do\g ƃHLd pLi'Ai ?NI i&tZ0^gȅX{cY701<5  endstream endobj 502 0 obj << /Length 197 /Filter /FlateDecode >> stream xڕС0jrf{::"#a e0XvtmCOh)T^ aLiOvG ֤FscT,r0ʖSiNfEN`Y9Q3pqNN3O0n ZJ4&}5ty+A -ؼ+ԀW2>z endstream endobj 503 0 obj << /Length 236 /Filter /FlateDecode >> stream xu1N@ E"a|$H" * DH$*\!G2HQwmT 娔DJsՠg?x#Um<>r\Iq+wn˜24wC0MLNLtA 9a=tC68yF̛aO2/a<&E>oxv endstream endobj 504 0 obj << /Length 124 /Filter /FlateDecode >> stream x313T0P0b#SCCB.c HrW0r{*r;8+. ц \. @†H0 z(QՓ+ +T endstream endobj 505 0 obj << /Length 191 /Filter /FlateDecode >> stream xm= @ x Ղ?` A+ RK E[)S,;h%Xfh< }:ex\T:8^pVQ>EmqF;)C}FE$ sXBט^Hȃ@?|bezYETZ_q-`R!a~K<.Kj/\ endstream endobj 506 0 obj << /Length 187 /Filter /FlateDecode >> stream xڝ= @g"#Xraˀ!N;GYg!BR@[]/w%ܔ|q&?,Lƹ+x"ҡ@yRx -0遍~*?umֽr!0e] EӐ`%Ж*sz endstream endobj 507 0 obj << /Length 182 /Filter /FlateDecode >> stream xڍ1 @EIk9 n!he!Vjihh%GL2Φօ}g?ofǜlS>'t#k5?;2{Zd܆L]rBC\"iJzD=[5/jLAOQ~ߏ@B_Zh4J5Ϋ^RMuZ9uEJ endstream endobj 508 0 obj << /Length 193 /Filter /FlateDecode >> stream xڕα@ .<} L &`qRG;[pqᾤ 5)+H+9s<^&|XLפ*L,r0S⺡MNMC $z11wx!"><Zi&N?>cH RaH'c ˁ:ѴmO, YK endstream endobj 509 0 obj << /Length 201 /Filter /FlateDecode >> stream xmPE4K BBrmM>}}V́;ܹiԥS=T'u9&a+NFF⻥OK+ VZ[( f#2;܃J>PDCv@Z }•cC 7'* 4u.7mp b2rcZI_ endstream endobj 510 0 obj << /Length 154 /Filter /FlateDecode >> stream x313T0P0asSCCB.c1s<=\ %E\N @BA,@Az H?*;&p4Aka[~ `1.WO@.^ endstream endobj 511 0 obj << /Length 253 /Filter /FlateDecode >> stream x}J@#E`}!k.p` A+ RK E#U(y[,gǰzqꜟJz`;볟 Z.(wk~x|ws%{/xv4lnfxYDdItSn\#7@efd=`El6X4jB*`f}E_h0bj1SL̀,x>v*!*:MƢ:?-y%ۧF@-7> endstream endobj 512 0 obj << /Length 161 /Filter /FlateDecode >> stream x313T0P0bcSCCB.1s<L =\ %E\N @B4Pe,B @d ?  B~oAd $?HzI8'W z endstream endobj 513 0 obj << /Length 132 /Filter /FlateDecode >> stream x313T0P0bcKS#CB.cC I$r9yr+r{E=}JJS. @-\.  @x@@?C1;}pA|.WO@.O) endstream endobj 514 0 obj << /Length 198 /Filter /FlateDecode >> stream xڝ;@%$p.H)L0VjiVW(x[_~0E_cƃ=2b4gA ΄Sp)-8lsQy endstream endobj 515 0 obj << /Length 115 /Filter /FlateDecode >> stream x313T0P0b ebUel䃹 \.'O.pc.}(BIQi*Sm`Pz<7,{\W endstream endobj 516 0 obj << /Length 171 /Filter /FlateDecode >> stream xڽ= @[&G\@7!Q1#X^,7[n8ȃW3r9Al&]'-\,cx܎` s0 n ==Cbq1 SeKvI'mr/)T8R`5zf endstream endobj 517 0 obj << /Length 155 /Filter /FlateDecode >> stream x313T0P0bcc3CB.1s<L =\ %E\N @QhX.O$$PD2`$ȃ@H&?:7 q.WO@.ll endstream endobj 518 0 obj << /Length 183 /Filter /FlateDecode >> stream x}=@XLvNBLH0XF[٣Q8ab^2}KJ)*%Kw4 +@@)juE]VQzB[_P :9o.A@9(dq%7@'a/=ߵG.^Tyh p A!\\[>P: endstream endobj 519 0 obj << /Length 200 /Filter /FlateDecode >> stream xڥ= @g fI"SZYZZ(ښͣ[.(wS|7q4HRYs_8 LWCNv?$#(%p:lHj&5pGٌs V,S*7;(&A]t, -GT@8=F> $_ȥF<5ޯ endstream endobj 520 0 obj << /Length 158 /Filter /FlateDecode >> stream xڭ1 @ПJuj!Fp A+ RKAEh9JAqc![̃I`4-ØԈmjw쎜{Vky\Y\/|9êe_Hx+5C8#$RC\B"xo<Iw endstream endobj 521 0 obj << /Length 185 /Filter /FlateDecode >> stream xM1 @4!s7q5@T0XErr,,2ԎgDM&rv=pr^ًYMyaoY!RrGB7 }KD#"eZSW!("PB Ca}96A=> stream x313T0P0bc 3CB.cS I$r9yr+r{E=}JJS ]  b<] @AH2`h AA~[@ Lx:B endstream endobj 523 0 obj << /Length 148 /Filter /FlateDecode >> stream x313T0P0bcc3CB.1s<L =\ %E\N @QhX.O` $0()D? d=H2cģd> endstream endobj 524 0 obj << /Length 186 /Filter /FlateDecode >> stream x5= 0W:oN`B`A'qRGE7^̭ ء4ؔ? ,&Q@>0[}pb*Q)QzܟvI>>yG:J^]S |-,ZHZX:^<r[C准qzb&gaQ$L endstream endobj 525 0 obj << /Length 174 /Filter /FlateDecode >> stream x313T0P0bcc3CB.1s<L =\ %E\N @QhX.O `?aC00~ @2?Dv`N2~+ߎ #ȏߏ`` ?G#g``?A6 H@RՓ+ ɝm endstream endobj 526 0 obj << /Length 237 /Filter /FlateDecode >> stream xEαj@ dz)CB=ҩCɔdnvj:t&=$%p!:d-"zX!ZnhyxDQd}LKႲ)ֳ[{vȭ+OPy5 @U-G[;z[*lB;v\ɼHer;SHR Z88 ~Ka{ endstream endobj 527 0 obj << /Length 176 /Filter /FlateDecode >> stream x}1 P S2Y<9*BV N⤎G(Ϥc|?!?'S3>gt#͔+^wr~ÏB.9#W!H"Px+"B I / >i`$f_$hj(D{{-ӎ~b endstream endobj 528 0 obj << /Length 222 /Filter /FlateDecode >> stream xe1N1E*i| .-V Ab $(UAݣ(>B,?kWEwk.i;O%/$=iI^>$nF6x0ڄʬ ͎X⌾T~fGvlgOȠ<|HTGǂ+ˇD5WTL3*=2,<8h endstream endobj 532 0 obj << /Length 189 /Filter /FlateDecode >> stream xڝ1 @EL70s @BBZZ( 9Z#XZ:IVt« 3Or#xjBN%7nt8SjImYǤ+]'RzΚT;l@TJ @ hxjze/ ]a;AdD/ak+?iTRS" }G@ endstream endobj 533 0 obj << /Length 188 /Filter /FlateDecode >> stream xڝ1 @EL/ :ͮA"EVbE$Nxg1q߄l">h.!Ǧ^OXRcR 7'e|ޏՌ5ٔs@ th~//iKxO`LГtIVx?>(=Cuڕ/@RriniMoEBs endstream endobj 534 0 obj << /Length 161 /Filter /FlateDecode >> stream x333P0P0W5RLLR L @ "ɥ`jU()*Mw pV0wQ6T0tQxJBS \! %@5bٖA)~d%P PrFC-Z+$QLzDKr d* endstream endobj 535 0 obj << /Length 104 /Filter /FlateDecode >> stream x3230W0P0W52T02R03RH1*24(XCs< M=\ %E\N \. ц \. a0C \= h endstream endobj 536 0 obj << /Length 102 /Filter /FlateDecode >> stream x͎;@PggwAxJ!* %>Et300 UjrR豆iqA 5Tv̐ɩ p:_thq_h endstream endobj 537 0 obj << /Length 131 /Filter /FlateDecode >> stream x-1 @E?^ xЙmV"RP:ٙ&Nwo\%红V\xA=y1:nwՇ Y/ t4M22DT&2+<*B# endstream endobj 538 0 obj << /Length 94 /Filter /FlateDecode >> stream x3230W0PaCsKCB.K &r9yr+Xr{O_T.}gC.}hCX.Oz 0X [\w endstream endobj 539 0 obj << /Length 153 /Filter /FlateDecode >> stream xڅ̽A ɉ̗eSH" ͣxwN5gvZ88Kb񀷲>7TzOoײC _.)k̓<j*zP R.NO|[ƧmdSL6e\6NdV;x* endstream endobj 540 0 obj << /Length 101 /Filter /FlateDecode >> stream x3230W0PaCsc3CB.K 'r9yr+Xr{=}JJS ]  b<]d7`= 1S'W fp" endstream endobj 541 0 obj << /Length 140 /Filter /FlateDecode >> stream x3230W0P0W54S0P06SH1*24PAS#Tr.'~PKW4K)YKE!P EA 30` Px҂!Փ+ &, endstream endobj 542 0 obj << /Length 162 /Filter /FlateDecode >> stream xUA @7 u XJ0fԪEB ,jmAi"=xj1k)%g/ I|<$7}Mlx]I'$K>&ȔGȽm~i\ԅΏG8¢x8M lj0 b+12 endstream endobj 543 0 obj << /Length 94 /Filter /FlateDecode >> stream xM=@PEx$^!R { T߱4J2:*54`ƴ"f@BJJ7"i endstream endobj 544 0 obj << /Length 165 /Filter /FlateDecode >> stream x323P0P5T06V0P0PH1*2(Bs<Áj=\ %E\N \. ц \. 10703H01X010000$E@PPc0n`0\@r ;g0 endstream endobj 545 0 obj << /Length 90 /Filter /FlateDecode >> stream x3135R0B#C##cCB.C D"9ɓK?\ĐKCKW4K)Y(  $'W R endstream endobj 546 0 obj << /Length 351 /Filter /FlateDecode >> stream x5J0Eo Xb6? Vf`T AW.Dԥbe|B]w6H{-O&79,Lylʹy7]Tr$:)zSQ/w9z槞PgS@="m͢"{tS_\L:eR@5Rl# L7^ Z7] gO.Py&#MYY.IgϞp?GTl]fb& endstream endobj 547 0 obj << /Length 172 /Filter /FlateDecode >> stream x3134V0P0bSKCB.# I$r9yr+q{E=}JJS ]*c<]0A?  @CA2@5@D!dPICd \\\^ endstream endobj 548 0 obj << /Length 175 /Filter /FlateDecode >> stream x331Q0P0bScSKCB.S1s<L =\ %E\N @QhX.O g``~?`g N}`o`F¢0?Q\\\ endstream endobj 549 0 obj << /Length 154 /Filter /FlateDecode >> stream x3134V0P0bSKCB.# I$r9yr+q{E=}JJS ]*c<]0AI~ i"?P3@JR|Z0 @&\=) endstream endobj 550 0 obj << /Length 208 /Filter /FlateDecode >> stream xѱ@?Xf!FHJ"BJ--|1}_aau=΁egM]p,+qeL?&wXis)|›p1$Myƀv3|-{Pe!,GpPghFdPCWT-kCj( gf"{![ޗAftC endstream endobj 551 0 obj << /Length 235 /Filter /FlateDecode >> stream xmj1 ^=;Od-$AhO=Xބͣ{N"Q6>fB&?N'izmf4Z||DJƠz.rM/T%V~rEP@X8 \IU{3bY1Ez$'i=Sː†LBp6Pu 8:R [49޲&&Z'XΝ_%m endstream endobj 552 0 obj << /Length 209 /Filter /FlateDecode >> stream xڕ00#pO`Amd3ALd08Fgh< @ڴ_e4f, kӄqH2@5(xEB3 i3 5C8ZA/:L^pXpkFbIF2qUNCE>_c+vdn&~VP endstream endobj 553 0 obj << /Length 260 /Filter /FlateDecode >> stream xڭѱJ@? LaZ 4ܪ[-'BBRP̛*y+uvg!B#n;MG4Zly\Ѣ瞚-Sӟ-5#%_v^QdRPDZTRR OԵ@*(AWE],RIR57P&?2oƐ(~#FLg5=dF#zvL;mf&,mXJ[a # }R:%e-vvS=U:霾es endstream endobj 554 0 obj << /Length 194 /Filter /FlateDecode >> stream x3331V0PaS SsCB.S I$r9yr+p{E=}JJS ]  b<]Bc``D@.0L1S?UB7@`JJ=SP (<9P@=mrC%hAC!@ y`> stream xuб 0  /0 D4?/iLsqINƪ&v)9 O44FQ5o3j ioKk2 DdFLƤ1(C8^QDɰ|p1۽."byҀ)gk׿R?U~ endstream endobj 556 0 obj << /Length 166 /Filter /FlateDecode >> stream x353R0P0bSCSsCB.s I$r9yr+s{E=}JJS ]  b<]d `6`RAI68؀L2`%Hv0)"G'!P5Ⱥ AJ$ `G@%\=Mx endstream endobj 557 0 obj << /Length 254 /Filter /FlateDecode >> stream xڭѱJ@?l&yM"&`p` A+ :--7`kMg+ & XKf]{t\)pp{ =SuV=UvT]j__Z]>5(6S`-̗oնd IS03aLlB".!1Ox&pcJ&HۅrI)ܔ_,v0{ltT颧 endstream endobj 558 0 obj << /Length 125 /Filter /FlateDecode >> stream x333P0P0bSKSsCB.SS I$r9yr+r{E=}JJS ]  b<]?T b78) s)hb y.WO@.!7 endstream endobj 559 0 obj << /Length 106 /Filter /FlateDecode >> stream x3ԳT0P0aKSsCB.#3 I$r9yr+q{E=}JJS ]  b<]acW3v\ endstream endobj 560 0 obj << /Length 165 /Filter /FlateDecode >> stream x3133W0P0V5R0T05WH1*26 (ZBds<M=\ %E\N \. ц \. ?@"000=o`#?0o  0X0`ao`27Áq \\\` endstream endobj 561 0 obj << /Length 243 /Filter /FlateDecode >> stream x]J@Yr̡@&A[sjsɃxj= Qj(y=HДeDz~,//Ue7~_G8"Ǎ;ΟGΗoKWn6^D8I F"!:+2oa[87`d`+hLMfp&byiguf0~5jRryd* Sk_ N9Lxods-5P endstream endobj 562 0 obj << /Length 140 /Filter /FlateDecode >> stream x35ԳT0P0bKSsCB.S I$r9yr+r{E=}JJS ]  b<]d3 eR/i& 0 d`L?`@!\=Afl endstream endobj 563 0 obj << /Length 244 /Filter /FlateDecode >> stream xu?kP{<0p '% ur(vtـ]G|X#y=8. [~< 8:İ˵W|Ք.1wQ@jH>yo瘣1 ý 8hFx]*18yTB,a PM 2< fep\$I5+zG4VY5D NZ@fW'coQ! endstream endobj 564 0 obj << /Length 243 /Filter /FlateDecode >> stream xUпJ@/.0fMN?Sge!VjihkR\AKT֩$EuwM1f``w%=.>jRWRkRnKO/VSYZR7T@fm큼0 {düۘ=4]L3Ȧa@bli@T|`MLjb4L1dtFW$G *.|ؙtI6Dc endstream endobj 565 0 obj << /Length 239 /Filter /FlateDecode >> stream xڭ08#^@D'D::htGxWm~_LyxJsNgo(I5M7?/&~I#K CԼ*x1F%)dB 񑊅A8EjGU(Nk4, ~j}> stream x3535T0P0bS#SsCB.K I$r9yr+Xr{E=}JJS ]ry( , LS? 0adT Y;PCuP7 .ĵ'W K endstream endobj 567 0 obj << /Length 309 /Filter /FlateDecode >> stream xڭJ@ba 3/I B<ZYii(6Y>D|I":$Eٙٙ/ -K3&tGt|My Z˽gxE7)%Z[Vz=EdꀚKzN.{7A|$sQЄ>j"vDmvs#Lÿb~dG[VueajEyȳvY:%*?ʵJ~D`q@\qBc̚p` jڷ<q}^+ 6 endstream endobj 568 0 obj << /Length 221 /Filter /FlateDecode >> stream xڕѽ 0𖂁#x/i*U ~I(}JK "&HrtF*8 q0Y Ȁf4  ״ 2o@.08BDu uf,HW lf(ze~ަ_Q@6+L6elZv,XKP~EԺe֩N=v< endstream endobj 569 0 obj << /Length 256 /Filter /FlateDecode >> stream xUϱN0 )K~h{=B @!Z̏F%Psw|J8êt0r^jE>U KWk=?ܻbuyJz_uEk?ƌ!fl#>3Z;@'7x &&ȖNm9R0!G/aEFD+E$ьMX^>a-M=:upǴ-i}GA^{sywָ+=# endstream endobj 570 0 obj << /Length 150 /Filter /FlateDecode >> stream x3Գ4W0P0bSsJ1*2" Fr.'~1PKW4K)YKE!P E?<@0g`A bP>T*L`)`J+F Hʃr Wr endstream endobj 571 0 obj << /Length 191 /Filter /FlateDecode >> stream x= @B\@7JL!he!Vj)h9G,Sl3X,fuVsmnFlzl @Hw4HH/I'S>[ِ҃C#^(>l \3X~ZPCAJ'BEH?4u7{-'ROr%xVݙ÷C qBszxa endstream endobj 572 0 obj << /Length 240 /Filter /FlateDecode >> stream xm1j0g1> stream xu1K0W v8b vtr@?')ΝCMHH^K^Y/PX.8\> stream xαJAYL"y.p1bLBASP=p2E8n@,ofgɌKWR+s8 5srzJ 5W7Y ~k%vTZ^{cٳUoC0˖*STB`ζ&%EQ0b43e}"_馡}l endstream endobj 575 0 obj << /Length 204 /Filter /FlateDecode >> stream xm; @ . Vf.1L!he!Vji(X({8Qښ}i<"Ńf{Qj{T3Qes:.{TŘ4 5E&6%/_x/PAP02g0yp&dBw:+0}ATyM6Ӣ5l.5iK|T endstream endobj 576 0 obj << /Length 198 /Filter /FlateDecode >> stream x3134V0P0R5T01V0PH1*21PASKLr.'~PKW4K)YKE!P ETD0S$00|`A; 00* ?8Q"I&PMb`߁q ̍:]'W ckA endstream endobj 577 0 obj << /Length 182 /Filter /FlateDecode >> stream xڍA `'?(   AZDjX.̣y҅Tcu 7f: 5P L % MBb%_/#jƒ&Ύ҄Z{Ue5TƩ-ՇW6j@-OӉ;*`{^[bTd7 wSZ= endstream endobj 578 0 obj << /Length 198 /Filter /FlateDecode >> stream x3134V0P0V5T01Q0PH1*21PASKLr.'~PKW4K)YKE!P ETz !HԱ` |P=iu D)ph<krF=A?0`> stream x]1 @\B/ 8M(+Tr!bI q23;9nvdC)lGUgwIBf6$32d@fr@&m)2ϩ\^sϵ2HQRQO5QJrh MTrL@V@ endstream endobj 580 0 obj << /Length 141 /Filter /FlateDecode >> stream x3236W0P0bcSKCB.# I$r9yr+Yp{E=}JJS ]*c<]70| C`003a`\=&[ endstream endobj 581 0 obj << /Length 237 /Filter /FlateDecode >> stream xڍJ1ƿ00 v^@9Å+T[}> stream x3134V0P0bS CB.C I$r9yr+r{E=}JJS. @-\. ?&iNa`D~700n?D䇁$7 \\\y endstream endobj 583 0 obj << /Length 122 /Filter /FlateDecode >> stream x3230W0P0aCS3CB.C I$r9yr+Zp{E=}JJS ]  b<]0@A@8~? q0\=(CE` endstream endobj 584 0 obj << /Length 150 /Filter /FlateDecode >> stream x3236W0P5Q54W0P05SH1*22 (s< =\ %E\N @QhX.O  P?`E6?gc?P~.WO@.W endstream endobj 585 0 obj << /Length 196 /Filter /FlateDecode >> stream xڵ1 @Еir3'p.#BBRPQr0E:? d37u.{ʧHrCqJzƁGz$15x2`ts [R?L3؂rkm;x3HKv@%.oԐ nn**ɍ@ÔDr endstream endobj 586 0 obj << /Length 108 /Filter /FlateDecode >> stream x3230W0P0aCS CB.C I$r9yr+Zp{E=}JJS ]  b<]?0! ̃`qzrrƂQ. endstream endobj 587 0 obj << /Length 177 /Filter /FlateDecode >> stream x33R0Pa3scsCB.3 I$r9yr+p{E=}JJS ]  b<]?`@=:773n? Da`N``` O7Nszrr#߈ endstream endobj 588 0 obj << /Length 147 /Filter /FlateDecode >> stream x3134V0P0bcsCB.C I$r9yr+r{E=}JJS. @-\. ?00`D~70n?D䇁$0I.WO@.e% endstream endobj 589 0 obj << /Length 188 /Filter /FlateDecode >> stream xڍ1@E #0e6 &naRK v9GTd)HN^f̦ǚ95(EqߜR{cRkI ? ldM*H&g8^WSQdHVR!J*- i~ nN/ookg$AH> wlzZIK endstream endobj 590 0 obj << /Length 196 /Filter /FlateDecode >> stream xڝα @ HByuj;:9::(>Zp"]qQ |CB?2ܓ1G!#I:Ramd$V$fO"tٓH$R^K6ʯ\UW0/%>T5*4hy~> stream x31ֳ0R0P0V54S01Q06WH1*21PAScTr.'~PKW4K)YKE!P E0a<|?`0?> stream x3635R0PacCcsCB.# I$r9yr+Yp{E=}JJS ]  b<]3P?n3 ~o0ah`?PszrrjF endstream endobj 593 0 obj << /Length 195 /Filter /FlateDecode >> stream x=αJ@Xf x{`TSwZ * W6`"8%Gf|q~K.4pR^j<> stream x363T0P0T5T0P05TH1*22 (Ads≮=\ %E\N \. ц \.   W  @ @,?(fQ 0pC sC3=;?f.WO@.uH endstream endobj 595 0 obj << /Length 153 /Filter /FlateDecode >> stream x3134V0P0R5T01Q06WH1*21 ([@ds<L =\ %E\N @QhX.O `J`pB`왏I@.WO@.1c endstream endobj 596 0 obj << /Length 183 /Filter /FlateDecode >> stream xU̱ P#k[WJ' rjj Ɔh>`Phj @ B\Q#HEldȗ$"Sg3:.{|LVkRj_ ..X ,g0i) <p&A=j|c(vk]b=(ԿOI |F? endstream endobj 597 0 obj << /Length 233 /Filter /FlateDecode >> stream xU=KPs Xxv(zb`A' Q|A7|~Lx`7UN?8g!Aj"z$r~nhdHڙdrO/$GcHN* WUP6Aߴ45q " bx%tq_cGŲh;L t5<fOk2|+ZlECd(IBY_ endstream endobj 598 0 obj << /Length 210 /Filter /FlateDecode >> stream xMν @ )(> stream xUj@Yi nZ$sSEGQ|x I;=F(N8^D!qiIs ǔB3I-1QYAg//74gZv* 0ÿ+]SCE@QsϰF,IqSn/'gCb^mmjg`1'>ڟK endstream endobj 600 0 obj << /Length 183 /Filter /FlateDecode >> stream x%1 @@$|'0+AA),DQI:IUuO)Fh~!;:c̐ېዬQ֑)HpIH]RY#H[m(l2Oe-?uC endstream endobj 601 0 obj << /Length 188 /Filter /FlateDecode >> stream xڵ1 @EH!L#d.ͺB` A+ RK EBbGRRl6Pt+ǬƬ5$Ii;Xf$#aI,Dv$f,I(K~ |[jWopG!SE /zO6x+ӸY~uд` endstream endobj 602 0 obj << /Length 121 /Filter /FlateDecode >> stream x3135R0P0bc3SSCB.# I$r9yr+Yp{E=}JJS ]  b<]0001; aX*6T?0'W N endstream endobj 603 0 obj << /Length 228 /Filter /FlateDecode >> stream xmαJ@o"0M^ป'pWSZY `eh>J+5E~;Yct_^iC-/+9u'Zst }{} ,, %s'l"aAZқMY'W Tc| endstream endobj 604 0 obj << /Length 235 /Filter /FlateDecode >> stream xu1N0ЉRX`3',ZiY$R AE GQr[0"OʌǓ/^ҟ+Vɾݭ%+yxb>F:iy-29Q EPE6fLV&b&e6fՎY (y/ifU _ cBԨM>y2_ |Ǜjh endstream endobj 605 0 obj << /Length 188 /Filter /FlateDecode >> stream xڕν @ + At-('𮶵kotrP?Q_ I+F!=ړ,o)$G$'KROt8oH&{$S^zVSBĢ iAf1h.p;`Z \2oߛy544` endstream endobj 606 0 obj << /Length 226 /Filter /FlateDecode >> stream xڕϿjAna s=b!j WJ!`R nGG8̜EH:_1;dySpnyΟ9)_6[d?9oR&[}";YL9#;e銊Һ„pQ*+j .+xs7xĕ\ }rR /:tKuNTc'ې'jiT2Dׂ+X endstream endobj 607 0 obj << /Length 243 /Filter /FlateDecode >> stream xmJ@O"p}dXW0 j)h()SDm>{uuVZjG+9}Mjag"VNbkx|JV+-*@ Ps&[ D>#E@rI~2> stream xڕα @ HB}Ѽ]`A'u(GQ|TZ?$w#3ihdȎhC!s8cТZp*Yz?WS2f5wHPQY 4a:B@ 8 1n -SQR-8 d_Ѯ+J_> stream xMJ@Eo[8м$AB`B]W҅E ;#Ǜ*y{wquLZZj}%OR7KmN~&wlֺ₲<>H\i%Jo*-o])L O[ `;d1a3X`LpM6{{xSHp|tO01l6 i4,e3zwgRS@v伕+c endstream endobj 610 0 obj << /Length 237 /Filter /FlateDecode >> stream xu1N0бRD@\lBTE"T AKr!e3 gi_'aE5tB 2(_pӢ&1^_v7T]M=[b.'0S2*(ٌ`&p B!t 灼__Rc%ɞ 6{6C!Ic)A?XZ1IN+OVqY- m9 endstream endobj 614 0 obj << /Length 327 /Filter /FlateDecode >> stream xڕӿj0q%C `*B]WC:Nm-vG#dt&?RiD ~i]_\V;WzG*I꒚M dߑ%)YRtZ@m^HwYmVaܶbN4RbXMΔ\uNnnb| mbީLE捴]$ⱱ7!3ilz.2Ob'z>уt!򸴏97 טC.k&) 7Lʬ k ͹!!KkK!#ܥm<Fk(4J@?mG/c endstream endobj 615 0 obj << /Length 338 /Filter /FlateDecode >> stream x͓?N@gC6QڸHaRK vF8%^0 Z-;;3|qvrXЧhsJL6~Em*iS^o*\R[}OT@WdR;Ȉ,QG9Ci 7rXK0A@$s;:>GOÔ11PVGG { r(ܑ  J}1*7S($;SheIL>oC^fi0ӤIΧ C4qHGnJ谬cC +{7Z۶> ࿢*E!en/ endstream endobj 616 0 obj << /Length 349 /Filter /FlateDecode >> stream xՓN0 ]uPU"D$02`nyMNIܻEJ8v?ϊ xc\=83,OݣZ*ƲR9UZ_Jt79f^! 5Dň6X;ЖuH@cN.|͎r.m@γۯF|=Mb ִ`]Üb{)$U2ئ' ÄcW|rƬ,e9sOx^cfu=z.{6S1;Ae&oVgۛ`_#7ğ)NG YmvM٭f !&\oVW ?! endstream endobj 617 0 obj << /Length 325 /Filter /FlateDecode >> stream x͓N0 @PK?h Hכ*D$02`~J?c&rNldH^؎{U.+,p'%ΰ:ޠ%On _ K,!C#44~d32DCĚZAO3%,Fb= _&g2dFLdt^c;ȓhMZE=p8}ډݴ1Mt=[liq<3Mu;oϚ0qfUȱ:ؠqZwѻ$D#BHI!ihD W xkD endstream endobj 618 0 obj << /Length 290 /Filter /FlateDecode >> stream xڵӱN `H&GJkNM3NIM{4"Rȍ%) ~ٜoK<+>Lcuz^aہxĦqkAtwb{%>X> stream x}ѱJ@?lv_@p] !p` A+ RK E;!hM7HqfwO`vv23)Vf0WI%X8=Uk3UqaUASSbmn*Sުvm| 82"7@б, }8$tHIR2>JJ =MT;4[6R׳ā~D}~k.:6ʃHϐDJwk81ۇ=Isz6WBJI7l:ahJ7Cަ85,φkVq< /XYd|vRJJ}I endstream endobj 620 0 obj << /Length 347 /Filter /FlateDecode >> stream xڕұJ0 Y hw vyIݎkx7 /ׄH#MHYO =S}TDNC!e9qc}:/Or^F_eWQ3]|oAwZhp !j- G #gMr>6n3xf[22>Gޖ_t2r NɆݲaw{VdS"ؐ9rm"s22q D,xc'SoD̼18,0Ndo> c[o DeaXw ]Gom𺷂uzg|UNj yli[5J^ endstream endobj 621 0 obj << /Length 270 /Filter /FlateDecode >> stream xڕJ@'LsL 'BB> stream xڵN0/`?BdS` Heꀘh XI-#d`stgۿ~Iy)x 5_XQ&oG\7vWEF<z{O5 Tb!ȣO!2J`@;PP<;Gg3E9c̈*l09t / inm';)),bߘ^Jq݂zlgF endstream endobj 623 0 obj << /Length 253 /Filter /FlateDecode >> stream xҽN0T"GȽu~n! & 7+Q!ʟĄd嗋l4\jU<sMo4HQ {N^Kls/dKɮꑚgʱw_ s=$p8E . (sׅ42*ȱ| ]6&ܴLpڋ_IHGN!X>] 7#f".F?^Q 3ҙ b= endstream endobj 624 0 obj << /Length 244 /Filter /FlateDecode >> stream xڅJ1g"0M!`Dy[ZYZZ(ںy}<•aǙP1|?IO :1H=>cTPc;Ocw!^_[^ʙ;V8?dmgPj\Rq :dĄ* |Vbn;gE d1o( ؁ahDBc!D[o1En %in6N:\Z` æ]H_I<?y뭜 endstream endobj 625 0 obj << /Length 175 /Filter /FlateDecode >> stream xн 0>B L*)j3:9vtPtnG#8f:M|~3z> stream xڥ?J@'X&G\@HBL!he!RK E֛L2ɮ9o[,Ƴw565>UU7v1.tqoYKtq ˣ|QђCDF"RcB|&;J e%wpU3B?O|G(^'f ]THد|X9/O8E.> stream x373P0P0bsC cCB.33 I$r9yr+q{E=}JJS ]  b<]0$0a aÐef0x:`P?H e00?C(v q'W l2 endstream endobj 628 0 obj << /Length 138 /Filter /FlateDecode >> stream x3635Q0Pacc CB.# I$r9yr+Yp{E=}JJS ]  b<]``0f+ɃԂ 0a@\\\٥; endstream endobj 629 0 obj << /Length 107 /Filter /FlateDecode >> stream x3635Q0Pac cCB.#K I$r9yr+Yr{E=}JJS ]  b<]0a\= endstream endobj 630 0 obj << /Length 232 /Filter /FlateDecode >> stream xҽjA W#>WZL+vrp!ET+ -vXqt;';됱j-->xsiNY-gOّy+#CYEI O$Rx%4DJʤn ׮UH@Y$߸Np⧤D@(Ax^ 9Eۄip xviC endstream endobj 631 0 obj << /Length 184 /Filter /FlateDecode >> stream xѱ@ & &]xHLtr0NUy{ጃ zw6d4JBGqlfiG{1+P)QEz@-ibc|!Pi ౮!`{.TV6ߡA_y48+po endstream endobj 632 0 obj << /Length 231 /Filter /FlateDecode >> stream xڵ0kHnЂ0 &2`A3<#02^KL%!_s{I!.qa@CT9 +@P% 7 v+@x0> stream x͒N@ ]uG_.!MBH 02<Gx۹F:.˓"J:lN錞c|,5<WO(m(KѭEGWbtK=b$(#!@5@oJ 4{aŌfJ`o}4.lO%wm_mte4](z`_TU` endstream endobj 634 0 obj << /Length 169 /Filter /FlateDecode >> stream x;0 t#' VbTD$02`nQzT dj20XY陞c+4xRps?aq@iA W<ix=   E^6ɱC:_:Wѫ}O_ /h m Ij^ endstream endobj 635 0 obj << /Length 259 /Filter /FlateDecode >> stream x]1N@4;ۊB$\ Q%ڬ\vY)yTk.拊57 UIJ/Kn6O\k*ybx[~|nXp8HDF#々~7'QȔ^;LKZ+45qj@.dtv!"ieh֔j]dV絳Su ?hgcfKxhGZ endstream endobj 636 0 obj << /Length 186 /Filter /FlateDecode >> stream x3534S0P0R5T01Q07SH1*21 (Cds<L =\ %E\N @QhX.OON2bH$;&=A$3?8HAN7PJ`$H `( E` qzrr:p endstream endobj 637 0 obj << /Length 187 /Filter /FlateDecode >> stream x1 @   fl1[ZYZZ(Zkyt {O!(VhpZ0(j. 匴F91J3FNPf4W.dI K#ZX+ސ8 w6 .n N<sUv848n endstream endobj 638 0 obj << /Length 252 /Filter /FlateDecode >> stream xڅбJ@YR#d^@7l 'BB+RgvE8X>Y؟/Η%YJyN^RaaB> stream xڕ1j@7Xx6l6@RXR%)S$$fB.2Ni!7.V?u~f*U+uW9o(fKUn*< ݖIu>?_dRLjG/zV!C؃@p` 'h'đv3k"t{O<8 F evb883MmH Є̎io“z>Ba"0i5s?hb8T0c00c*Cٻ1 i<8^gvJpi\DXו!) endstream endobj 640 0 obj << /Length 270 /Filter /FlateDecode >> stream xڅN@EPL'~ >X<&ZY+h+| K$\gfX){ʪߗu%B-k_Weʡ/ϯ7/nyS壼'7e"0қ0Dr92DI-٨l+s@!٘b4Hfoq!C?I?b`6|tC t} lLD2r1uIU'TuIk*T%5P%5!.>Z/1 endstream endobj 641 0 obj << /Length 137 /Filter /FlateDecode >> stream x3337W0P04  )\\&f  ,ɥ`bƥU()*Mw pV0wQ6T0tQ```c;0D0I~0Y"I ?&D(I"\=VI endstream endobj 642 0 obj << /Length 301 /Filter /FlateDecode >> stream x}MJ0)YؖG_]x>.]W҅h=Je? گiftߟ ChÞ6 s/\knCs%ux^ߟ\s>k o@B,D'DdZ"-,-B/63"x甙k p7q|$pF暿 dL@AvZHFӬYM5k|,ZdIeb4j`Mg!@Tt`[Bͻ.A8Ew̕bԊW'bt7}t endstream endobj 643 0 obj << /Length 305 /Filter /FlateDecode >> stream xڍN@LJlA gEr&ZY+h=> @IA烋 |gf.K xQz!eY^#[E{_o8_c#>UX>)EৣNGG#"qhfH8fEAEI=-Β%$#쵂H\Wfä hgcgݺi8iZG`s+,25\i`2[[E3)D/bZ1.8G IUuuR:X&oݴ]֯"Mߴo endstream endobj 644 0 obj << /Length 225 /Filter /FlateDecode >> stream xڽнj0 ['Pt!tP2;4qh~?G$C@Bw&,+]po1}R28^~в$IF~{͒/wu|'ܯ8&旘knLM@;&ED-tw>5 pU/jh:؊,PW+D5^ԝhma#:YVp=Dӊb~9ag/uwiS]]q endstream endobj 645 0 obj << /Length 285 /Filter /FlateDecode >> stream xڭѽJ@Y lGȼ&H +PN-`bu>r"X?L6']x\c[awO}͚L> stream x3532Q0P02F )\\@$2ɹ\N\@.}0PRTʥ(Dry(3773pzrr{ endstream endobj 650 0 obj << /Length 174 /Filter /FlateDecode >> stream x3532Q0P0SеP01U0TH1*2 (Cds<-=\ %E\N \. ц \. @`"j@&~ f0H@L`F؃ ! D4$f6a&I#$l0L  *@'W OF endstream endobj 651 0 obj << /Length 108 /Filter /FlateDecode >> stream x3532Q0P02F & )\\  ,ɥ`hȥU()*Mw pV(Dry(3773r - endstream endobj 652 0 obj << /Length 103 /Filter /FlateDecode >> stream x3532Q0PP0T01V02UH1*2 (A$s<M≠=}JJS ]  b<]` .WO@.E, endstream endobj 653 0 obj << /Length 225 /Filter /FlateDecode >> stream x}1n0 Ed0EG0/ ԡȔdР7 dPK#O'O *k!XnKVz>uөg^3e݋}N7Oo#XnkR 0,H"`nX,2d;F)ԃ"G ٦)eC$9َ}r9H>Gime2bֿɯꢻNǀf endstream endobj 654 0 obj << /Length 223 /Filter /FlateDecode >> stream xڭ=0 S1T#4T HbF(=BN1#2|QlSL``: Ҍ f}a^cstz=^NЀ`|U|+Q܏JfL5IbG|86*Um%1x(VDFN{ܙmw^{Ǜ)5xu Vϗr endstream endobj 655 0 obj << /Length 208 /Filter /FlateDecode >> stream xڕ;n14s5,r%[D ")S$"r4Gp`(RF}?i7> stream xڥ1N@Y478n- T)UL(ԛ,IdUq n#t-l#k&ĖH endstream endobj 657 0 obj << /Length 225 /Filter /FlateDecode >> stream xu1N0E49BM,)@T@"萒(9K. #3?pW=w<~(ё6[;ϝFOْSxϟ_dw7qB#h%^J"s-,&ï& M ugTi: d)ȧֿHee_3 Y}ETԼ4rs$jYh%t;#k} endstream endobj 658 0 obj << /Length 166 /Filter /FlateDecode >> stream xŎ1 @EH!%q1[ZYPUx!㎝Vd7<[W-SÉ@fޒYFLXr;)svdJ9{ %_@"-0*rࡐZ'pGb4"mz!IoMSK?7W endstream endobj 659 0 obj << /Length 283 /Filter /FlateDecode >> stream x}J@Hfa4]<Vr YlWX `D9-4oɿ3eP=յj隣{^u\\:ݙ{z|bu~*.r冻D6 !#"%I\(3}Cc{mPD߄%:N4@&qTDMK2v ;Q9(nhK Idvd="Т>y &ɹf{[ӎ N4:58x'_'/t endstream endobj 660 0 obj << /Length 178 /Filter /FlateDecode >> stream x= @ L2'pH-,J--ףy2ŒmkO1rX54])/ UԎ URvL,=&dk6>s]PFX`* tB &66aQְsdmN|*38w ]ZZ錀 endstream endobj 661 0 obj << /Length 141 /Filter /FlateDecode >> stream x3532Q0PbS3#CB.c3 I$r9yr+q{E=}JJS ]  b<]0000PX?Po?=``D xr "cn endstream endobj 662 0 obj << /Length 127 /Filter /FlateDecode >> stream x3532Q0P0b33CCB.cK I$r9yr+[r{E=}JJS|hCX.Oc`'\{0 ?0%\=Rm endstream endobj 663 0 obj << /Length 175 /Filter /FlateDecode >> stream x1@O75pD ,ZZh:JD<@J ˆbb%3򎃮i0f3c3n[6DM8eŠ8NDRrpEEVn4TKUT|(UBMҸHȿ(? endstream endobj 664 0 obj << /Length 170 /Filter /FlateDecode >> stream x1 P t*d |BB`A'qRGE> stream xڕ=@ #0e't$$RheaB5pJ 6&Wd^狔cy9ƹjzPRei.;-+RGN R[&U|H-+֤|Z3/PDx"_  {MءlQ5򃠳RkD0qM]Is Fk,Uel m*:9n endstream endobj 666 0 obj << /Length 235 /Filter /FlateDecode >> stream xڵ1N0EEirqd":K" * D ra8 j$\<̟|Ҷ9~JSJ/q]Ngr |y@T2bH!iY)0DI~B& #;NvWV #tb9w?1&쵹+'KUwι9mkQڎHQ*mAi7t-} endstream endobj 667 0 obj << /Length 172 /Filter /FlateDecode >> stream xڽα 0@εIG882:Ht>85g<G5oHYc\lːIN͌Od>"YJq&S"EE\-u׋p*X&.EZ7-}K7-^D_~417yi endstream endobj 668 0 obj << /Length 227 /Filter /FlateDecode >> stream xM=N0j K.Yo?)@[%h(pGH"1&+Ai4絻RF.x/~-O_yUì o[^fv'^TGnBe*TRUCQf4.,B"tF) F#a~̇ Lͥ2~"1e`9Cf1YD5- VM4kcЇA-ʭ endstream endobj 669 0 obj << /Length 177 /Filter /FlateDecode >> stream xڭб 0+ 4%q- ftr'>#t =/u AIn(ƚ!kxB%N_C!Q-$Ft9_Ռ$h+3;tA|y=8ނM?`|ҋ-xI ,vQOzxE:Vv܄#Jsk|jVmx endstream endobj 673 0 obj << /Length 208 /Filter /FlateDecode >> stream xڥ1 @EX t$ L!he!Vj)(rM\ ~}>wU>$]HYDQLbJX xɷH"ZMYVx@h egR4ah#Kju4ӒJ&YHrb`.j\+hcc%*t!AfM* endstream endobj 674 0 obj << /Length 207 /Filter /FlateDecode >> stream xڥ1 @EXS 8ͮ(VbB9ZRZX&^x hec5a㣤 jtLaLbJXV oD$N8x 0lX@/C7蔻B f 4VVkφcx}A#/k TZ;ƺԷt%E" }bS[. endstream endobj 675 0 obj << /Length 136 /Filter /FlateDecode >> stream x323P0PP5T02P04PH1*24(YBs< =\ %E\N @QhX.O9   fv6> $'W  ' endstream endobj 676 0 obj << /Length 95 /Filter /FlateDecode >> stream x323P0PaCKCCB. \.'O.p KLz*r;8+r(D*ry(177? 'W  endstream endobj 677 0 obj << /Length 94 /Filter /FlateDecode >> stream x363U0P0T0P0"CB.#3D"9ɓK?\ȌKCHx*r;8+r(D*ry(6#' endstream endobj 678 0 obj << /Length 257 /Filter /FlateDecode >> stream xuбj0d=A-pHRB;u(@19G#d`d |' 󟖋;}O5\RQ`ȻO}c~[zIc%a,D!Q$mbG2bWh*^jL/.i AjS]3}`qd;<z<ĠuH> stream xڥѽ 0ةP+AAAѹ}> stream xڽJ@ƿ%``  h`xp` A+@--|tv)-­WXZdow*;9-8㒏 >+1*R̸*gZ֔Sz-eJ~{}ty{9+Sb 頁Ș2ԠFJ -_5J5f҂Fvh4P"VeF T߄iӹ{ =#0s@7IMlVMts~!|.G9#٘0\f {qo@W5/XI endstream endobj 681 0 obj << /Length 296 /Filter /FlateDecode >> stream xŒj0OxܢGн@kg!M ԡm-@^[^[WI qUutqE+ z+̟00=}c~ =T`!gA@jT, 8_=eCAMF^ |:I *@=N` ڝ 垻ḱ69&>0s!of &jɤbu gϫC0IF)Zm* endstream endobj 682 0 obj << /Length 130 /Filter /FlateDecode >> stream x373T0P0b3K3 CB.31s<L=\ %E\N \. ц \. ? Ph707000c~4ȫ_4,q.WO@. endstream endobj 683 0 obj << /Length 112 /Filter /FlateDecode >> stream x3634W0P0a#3 CB.# I$r9yr+Yp{E=}JJS ]  b<]A~y) \=i endstream endobj 684 0 obj << /Length 258 /Filter /FlateDecode >> stream x}J1 ] {-(tdibVp> stream x3336Q0Pa3C3 CB.S3 I$r9yr+q{E=}JJS ]  b<]dEL0 JP 0QR(ڡfZ D}L1Nqzrr) endstream endobj 686 0 obj << /Length 252 /Filter /FlateDecode >> stream xڥҽj0p [hd`e3$)C 2@!!G3U?& w0 ,N=j7>FTҿUx4F=E_%\ᵀ=/ɸh endstream endobj 687 0 obj << /Length 289 /Filter /FlateDecode >> stream xe;N@rai=`;qѰR.@T@I.J|7a҈$Ci>˳؝I}^M iI/y78K6'of֘)nb-}~|bvwE)XQd9!a"[d72EW:,wX=0;rؙnW-WzUR,k9M<Iz:HxDLՐc|c=1;2؉^]Aĺ7_lo'kH;tۀ_"=\lhsoW endstream endobj 688 0 obj << /Length 333 /Filter /FlateDecode >> stream xڍAK0 ^{6LSaNAODGaRAaԉ.x ?dJg9*9g9Цӯ'9+ezӉL/h[%=tvuLx0ȶ `ka5@!F֠%~ CnɱCȅsZnpIm1u2c!/Wܣ[P `Q P{&{6Gq.L!qvNCQ&yи7> stream xuϱJAba yh+RPK E;1 tƽpS|?;?xžjs3TC=-r+SrgkkrKyrM͒a{ծlB-`a:`u)xuwGW2&e˯ɦnh huaǨk} [ bԪob"EzONoɌla endstream endobj 690 0 obj << /Length 203 /Filter /FlateDecode >> stream xڝ 0OKдv vtrAPGAEA0G#8:ANȹ-Lp;"dJ Z_V[UglJ#IWc>NҽIs-0pu@܀_x vZհu/{#ҡ^EA^UzN4 E A2;Wa V4'VhLr endstream endobj 691 0 obj << /Length 212 /Filter /FlateDecode >> stream xڽϱ0$7 x/$N$ &:9'utf,ƣ Fp $K8q b~bNe/DF4AFGi[?2%72byg6Nh:]hBQ֩L)϶?$nId[XmFiǞzՊuA63` ^j endstream endobj 692 0 obj << /Length 210 /Filter /FlateDecode >> stream xu1j0g<7 41'z(S$ MHXGQ|JW\(T 7uN3uki1}.Gq%Cf&u#U])Yϧz\R׹fi WOp_PI! I@*#f%#~,K{ǏT#,ΰq`(nYsLޖF^V2 endstream endobj 693 0 obj << /Length 156 /Filter /FlateDecode >> stream x33T0P0bc3sCB.cc I$r9yr+s{E=}JJS ]  b<]000```!$T ?h A30c T" h2FG&\=ak# endstream endobj 694 0 obj << /Length 275 /Filter /FlateDecode >> stream xڝN0?+C$/~ @pKV*E"L02`ȣD`7я$7d*:}$ X endstream endobj 695 0 obj << /Length 167 /Filter /FlateDecode >> stream xα @ ;:'zx: 7:9: *:{G;s]!3pck8YǸh PsNA^/r9E l BuL[VeTɎdÞ@`_wV| 䈚 oafaosK endstream endobj 696 0 obj << /Length 125 /Filter /FlateDecode >> stream x323P0P0b#S3sCB.#C I$r9yr+r{E=}JJS. @-\. ? :  .WO@.P endstream endobj 697 0 obj << /Length 220 /Filter /FlateDecode >> stream x1@`CW ,I0Q ne!V*Z'7J+)Shfe=1fOA2∇n'MxӞ#슓U|<)dg9P1csK^4Ї g Z7-Vj]p azկTP)*ܨF7́ ,a 0@ A/vP`iCiyA_ endstream endobj 698 0 obj << /Length 110 /Filter /FlateDecode >> stream x323P0P0b#S3KCB.#C I$r9yr+r{E=}JJS. @-\. ? C 1cqzrrp^ endstream endobj 699 0 obj << /Length 203 /Filter /FlateDecode >> stream x=@H\@ȜM B0X({+ba8垫|>2Pԏ~?Ѥ$|@jRRod5Ԍ;*gX@l$u8lSyEȞn!X#xiTCƩFHjODO'0vBJ#n $"&ݏ endstream endobj 700 0 obj << /Length 159 /Filter /FlateDecode >> stream x3534W0P0bSCCB. HrW01r{*r;8+r(D*ry(0a@R` `$@z ɀ a/ m?C&\=?qjS endstream endobj 701 0 obj << /Length 209 /Filter /FlateDecode >> stream xڝ= @GR2MtbSZYZZ(ډr2EH|((v̛ݝGa_ endstream endobj 702 0 obj << /Length 218 /Filter /FlateDecode >> stream xڭн0 p[*y#4"t7p  }4бCHpH'n[~8{`zz9> stream x36׳4R0P0a3CB.c HrW06r{*r;8+r(D*ry(0`?l(g?6g u@lC{ pP endstream endobj 704 0 obj << /Length 213 /Filter /FlateDecode >> stream xMͱN@б\DTd""R.HE) h!kfg:[\ꗺXS)Ks"Z;׌oY2=7Ro0ͬ&a8YZi4 %:1X[z83L̺E[y!8}?+O2dWtm8 \\ղuY endstream endobj 705 0 obj << /Length 160 /Filter /FlateDecode >> stream x36׳4R0P0R5T06V03TH1*26PA3#Lr.'~PKW4K)YKE!P Ea9$luPفX$N#Ccagc{  00?r Jm endstream endobj 706 0 obj << /Length 162 /Filter /FlateDecode >> stream x1 @ᷤL fqC@Vb--+'Gˑ<@Ⱥ!X l3pjZ>DŽm:L#c^[z?.6 6KNJV- -reByDz 7U}`(D,uxI0nҷWR hhKob endstream endobj 707 0 obj << /Length 236 /Filter /FlateDecode >> stream xMJ0?0> stream xeпJ@o \`^By]  @-G̣R^w]9 Opj8>xPS5ZOLIppu%?^^qDzŷ;JW\ׅˡ~ lr&Vg{'´N2;s8Gvn=ЪQob]pл ~^8:g007~ʞJT Ͼ4sM^!yJ[X' endstream endobj 709 0 obj << /Length 207 /Filter /FlateDecode >> stream xڽ P FҡмVn?`A'qRGE7f}>BŚނ*3$|9VuQۀ}+5͞1%kTڤ|18Ux*%V738 \A&rOP deyܿ>X ?c\%#'q(IfNĴ) endstream endobj 710 0 obj << /Length 131 /Filter /FlateDecode >> stream x337U0PbC33CB.c# I$r9yr+q{E=}JJS ]  b<] >00013 A9 CaՓ+ t^@ endstream endobj 711 0 obj << /Length 259 /Filter /FlateDecode >> stream x]J@Of!"." E0pA.Z v |˝gH0??pNNmnҮwYUϹ勧7wk"nssa q[{_AꭅBaD4%;>#p{%*édlW]HO˷df 3ÂױtK҇FoMfl=o,"E"pLΉ~WhFF*4& !3DWZnvj endstream endobj 712 0 obj << /Length 206 /Filter /FlateDecode >> stream xڥj@@CkB  A GAẸMb/hffӱZ'd?$u{<l(潽x3\h*fTK> stream xڍԱJ0 4O`[,'A&qRGnV|mp\p9䗖J~qr5KBMKuy;}ts/g. eV;.N\]i_zY37RcUup]Q/-%u;>j{PkP%G*K0IX S]' aa $W&>a"a I0QGdl LL M 254Aaڷ#*bDM6~,> stream xڳ437R0PaSK CB.s3 I$r9yr+q{E=}JJS ]  b<]>@?7@Y - DBX`,v8bƪ@3nfd_b?̰⇇<`,x> stream xڳ436W0P0bK#K CB. 3 I$r9yr+Xq{E=}JJS ]  b<]" ` )dQe21 8pfAfiA&iΔg22Ge^L0 @ Փ+  endstream endobj 719 0 obj << /Length 287 /Filter /FlateDecode >> stream xڕѽN0> stream xڵJ@%4y˼nn p` A+ J--PB\_SE;%_tB=ܵlkouLn}{ ?T\n0`Bh§"( v3,rV (R0(Z1̾?^3A RW^SML j3)0}1F3f liX6e*yX i}lM󣫖 S-zY endstream endobj 721 0 obj << /Length 290 /Filter /FlateDecode >> stream xѽJ@YRyM̝p` A+ P,& Aȸϐ%GǔRFtRN2ڹ{{\$\1/)n4 ܵ0C v-0ypiVp-PL"(JvWU+ov-cDgU7({_`7'4 lÅmsH/@םb'۸^UbUVlA1J1vހg9^[9^ endstream endobj 722 0 obj << /Length 267 /Filter /FlateDecode >> stream xڝJ1'lq0޼fpVb]hy}-86L /;q5%QwFO-kHfr;r +ZoyaC 2i寙5z>%k<&r,`vd+q3ߒ1^+ \oxE<@G*q/|Aoٸ=,8U(`ش fA-pڟڤPj"{mI倷YR endstream endobj 723 0 obj << /Length 351 /Filter /FlateDecode >> stream xڭJ0ǧȥº=z =umr!4LRuDg^W4;(M}h-ԣKCQ\jժԥ*NѮ̼<ޫbu~lX)U6_GzahB t ]2G6Da)hrcfEA1-?pλճ I}҈6ĥPgOn ܘ'+tc036u! 蒡AM"9%} |H=X9ZHv]ϽmE=LQVgq)ϜRT7D]n cƒ|M'b<%NZu>v endstream endobj 724 0 obj << /Length 219 /Filter /FlateDecode >> stream x37ѳT0P0bsCCCB.33JrW03 s{*r;8+r(D*ry(00`P"0C=~d3@@C P?P 8xq83qe0w`0H+p32> f qՓ+ P endstream endobj 725 0 obj << /Length 279 /Filter /FlateDecode >> stream x=J@ )2'p2Dl +BB\K E;qy^a2E33EdȼҥOumYꭥA +]Ȝc2͹~z|#8іF_[]PI%ae,*=c<<6F< ӉY+ _ ^Lubފq,?vMectJAqO8:G}- ȘKH~cD='0t[g7׏iC endstream endobj 726 0 obj << /Length 249 /Filter /FlateDecode >> stream xڭN@ }K!~5*1#ܣQ3T9l Iɾ5TUEš^+:pP3/F *-=UT>cKxii$@v#W@!'=r48 E\)GC B1:6b:wZK??"Xi=1wfbpY4?]e[t~x# endstream endobj 727 0 obj << /Length 288 /Filter /FlateDecode >> stream xѱN0Ы2DHmNJȀS22`%4*1Cg[!uBbbt:Ftr6IF9s|bli%cLl^_0\tSv PiYY0٣-$Fi nQC$lrڢWF$\Ea}!~"bǠ?qQu{3}>t^ uCaΟ jeG)AmJIeŐ[W.翢j؄7,?ne endstream endobj 728 0 obj << /Length 281 /Filter /FlateDecode >> stream xu1N0G\o$"-D $(PR[mr⛐#Lvq v '33n"O'5sj<=x/5j֝){S^˵)x|1jSn衦t8z[d yDbDΰt=ZbM΢yqPje^5X*>YY:#BIj!MlG-ƨH]$?r>Pc6A٠~I"vfD7(0l@/]3wׄ endstream endobj 729 0 obj << /Length 191 /Filter /FlateDecode >> stream x3531T0P0R5T01UPH1*21 (XXBds<L=\ %E\N \. @b<] @>dF"ّH~$RLڃz0D2I@D1aL``n@'03H~`c1(l@A(8\=~@ endstream endobj 733 0 obj << /Length1 1510 /Length2 6478 /Length3 0 /Length 7479 /Filter /FlateDecode >> stream xڍt4l߾Y{ZAg B$D{kVmJm5ZJmRlQj5J)_:}?NIr_od30P# 8J((,PU EE99M(/ "2PEB@(4B upo( J%e""25 A!^$_#(--ABAp.qGgtG(r.( KtVBQ.#~ C&H 0qz&N(_@0#v!H:;X[6m3Pw??A῜Aw w8Aa ? A0/@h_ʆ?y9"(/A/(gB?àǬ"!pԠH#zB. urN?{{¡m?6h?3@<?G L= HOCPnu@> '!CQ3Nh$`- ?[8?濮XHRCʈO**?@@@DZBHJS?Nzуf?"!<C pG6Ž/Y\2UW ?< c7 2{wu!`(zΰ ҀAPoM  ?_PX89_/,Q;:h" 'D_3$7 %d BHŸw D?cBHU??߸00Z(tο() C D{NH!οH87pt}vV+6*s^3\KtY1!dhV6Y;E~%KyG6yr25|A;IVK"S U&"^ 虱O(ߎTȼC7X^X<ɖqh}jr~%NOl~QTQA5Chʆfh..٪/\Ժ4dh_.moB[U; +nnϱXw0I5pݬxTT>,}KX6}|{:rO\od.Al1-2Bd :9P/f)tw-m@t 㢳/s>}Sy`2ش}ջA~&N2f8F-/)vz[ǽ/K3,gCb#1 GZe4lǬg\4;(_,{kS(g9#v8Nk)<:5"/vmf߿Q1EZOh=l0} U:2:RY{}].uz"dm@Yz&cG`4zkUYFv7gun!q\GDsN>-+D(\o'7GW%Kb5^W:A͞Lu?:(|;e& jO)3-by4y1fD=-l:E^$YBdkF#o6dI%5eTTeQuvy=E j'>c] W[?bx/'hʠ8Zz0K'mR=k X9HVꗷKYc}Ąk.m}c( qhpaH^D`{]oCwpWEp0J&* =V|r>t^R#Oꄧ^6d/Mʭ_ow0,l!UEj:,? UTc;;W98sjԧ.1""-zwK`c6 xz:qFYg9pXpx/MM\2>y5xVJ sjY/\,n]V|oCJ0֧8$Ex6YwEO6WR,fY)@Bj\&hCs(~Dت\%p<~Cifͪ@=~*e왔TY.r7u;|b*GLb jq(sE,onψf/ZW L41{\Ÿe6HR+\ ϐ22ϯNV=og h$7QE]G闞=?` 2t5O=w'Gvůq$7?eڢwRhX;uȪ Ͷ&+E#wUR"_82Q[d1$.pEwh}}F &"-QsTܠ_jU͙D; )l, KvšYU~.5 |+ l+&5#]j߭\m[ j17z oMz`2VLEvI]9 ;`WpR/"&qj–-sñnZ;/9?>Q~(156^⹽캂v[zqs3ۓBUclO6il.F--d6=X(9vp-9U*-<\e֕HOmD)K艹hx`l[T3lPaz:8#H3c~Zς [W8'>򘄨v|ɜtc/~ Jxkd:ß<-*!-oЋQF}d ԍɊyle1$GU"/նPX,1r|Ḭ$bz;h%ሄtU|Pɫ؈,CiP>EH1f8iUl}zq>.%g Vk̙7G~сlrV'dAÀS༡:Ή*6*лz̤vrLH[ 'Դ?(q&l9F̷CiZͅpȆ]5(j%ѽ\]vaΚA7o]#>5rw7D~4d> ||:5Nli&1q.~lo2uZa$Z!{4P7nw2dhR[lـhna ^m&`/40D] Ң>[;T룃cB2Æb54_cshsa`9X5[N`y5Ê9kUtC7U7>~:+[=E-վ0;;/GC58g&wu7SnU?}<0οDT:c.uY:o2xh|͔d)hdJT h{Eun-{Dї4;6@ijz^kF1o 4?cz8S*%G1gWtUZϭm:ThX*]sd 4{T}XsЦ"Ybzvž-B[{zgVz<)Lc'sRi\GMu|MiNmåN,=^c<[F"˽ 5"8y L2q !۳_[0xxVNRRwm \*ǁTo=C{בT{t> %RnuY ΎzR io 0j&ޏڊ!I!m%)U5~x'&-gEv1Qݮǹ%p}bիIE􊐲עHr9NYPIҘZ>9!WPR6YA6Sd#WySR5O?=-y33&' T@.(vxz϶r&N} ۜmOTRA{arRa!iS{b<}./{G[\MoN,.^xp+N Ga*zd|:/H>-GLԖ8_?~w,<${-i=6{綱uʚs>1.LSқ/k׳%NT-Oo`%5Zg{)u-.֚aݜbIǯ9J2%(d8-t8;,hR֋7.jjb4L Jb-;eJ16{m.>'\(ZSRþ5=&K?NK'mg5nkN0,Q7oSS0.!hrC Hn$_U/sqk!/ɻYmsXcV ~yI~Mt@#)./c[*.|N.G {!I]{P.l|YŢ+@y~Cؗ (^MXh'9k`nYkӹZb*i6j[Lz YVUYƭU/$>3NʫzqSEA؏$׷!+k^,^%k r|yKlO1.$֓E?rU?*o]w\/m)K7(`~|J? ~Ba0a7S,!QH{{s7mOp~u2*jLCfs@쇌77%ZHic8[+g_PU c Cp1yZ.?3ľݰX{K4@Atxp)\{'qS:}9&.T x`μ{(vtKaT;$c7zB^`Ds|Mh<$dnJ'o/?&=rfh,~P-=[4ʶq o_$Wuª=m|i1`W}r ڽ~#y~8vRܷA6-N"̆fu-NqQrI"1;'лd7D8()3f8y1,3Ʉ"_yn~J H2 ZHwðRrcyvB>d󘼴bk=:Oמy ;B9{O[{buxMK-G@<.F7xov6n8ׁE&tGTwNj[EUx=[a>_' aE ˏUJ~[\ YVF9>&`ښ.I 4$)~,BB߲Hゔɉ{`ٜLՒ9T n:މW `dЕfݰA(sՙVJ(=;c󄚅3j"~M׈f7ko;Ut~ ]I>49M;9YGLE~f7;Hgz$o.]/n9֊ĹubuvTfڥ2Z x鞊q5H3%$:v#lb GCS&@وhDFAD endstream endobj 735 0 obj << /Length1 1766 /Length2 11433 /Length3 0 /Length 12568 /Filter /FlateDecode >> stream xڍP-;AC CN5Ҹw!@  KKf9U[]k79( 01$X̬(TT -?r*m3l/ ' E&iy1T]ll6n~6~VV;++ NIW9@ :PI<@V_tuS/;DGcGyn|ZN/̻?ec`V%fy]i8l.:XH#ɫm ]TęC*V_}w@qGz>¤Qn'i':4J;Ő׶͇ rٙTJVŰaF6!qٚI7SvTG%[‹LW]FϦ`gDڅCcM:0MY}&w*tAITnQU3W>WgH߲_u7ԱY,}f՚)_nme]bM/L:^'Պ@98ż!ae-ŞF7Q4P=wJ|o.f8-C{-Q8 PiMeqj~;"'3vl-GP MkD~ 6 \-W> a70l^s^< qJkwVceH+TrQ/ P鰀q •ˇMm9IG+~O,wB 뉑v-D{q߱ps񄰡'a5zѵCp؝8>~Ld6jOï [lP 9f8.?<[g[N#UC" p0"*p/ܧ֧D|wW,2qftY5mf4u&>چ% t]"Ӻr#NlqVqkkt¾h#Җ D@r@:$8Wse"ゅ6 UϲjD&ZLȢHQd鈜Ԯո >h*Op`Ɣ OPˈ4EbEP/f=li['!Zq'G{=vxq|qߤZatT,S{0jev_"#,|d! ֆb `ԬKV|QxA,7\Xќկj|0~t}rw BS)ϸfKKݯg̚T" akX5n7Mߍi;ě"6zv1kĔzA/2:")vW-qP:@18b}]6%`>~y>h%|r,#:=R-,Ʌ~lcիRΔXjxi"rTE-xWj?l.ܬ( mux9%gLX6C)6E $vkFb4 =fz)ՁvU=cgg+bvbKW?2̻ȷ|J;?n!)~嗨56f`[x#~3;lleς ݧX'b*{/w7GvT(`z! 5Pu|lvY@Vؙ^[uO>>I } BK̫yu0Ѭ65 oR*w-OꟘ&% R ҲvPto 9+!; [JV*wG4~?FL>6S?+d +lj2ZAȼ3ΆoneC0UnBEXlIjt|Eg49 $TV{lPP̆ \ǰ)t|wίW 4Q:QP ch6Ωԁ`cׄ6'7"G5s[uBf/l'FrI1i 01qW TlW'z]zrIExR>hD8vX89wI|hy (٨~k%I ~/h@z]CCH{%$5En4͵]=KHݑh*c?UkЮThM[)ӧ"ZbYJ޲Yᅼ ;}JbΦ>qQK-F,0ú0T*>ڞDY166!-Lo];1qLo:ݺ'xvl~‚I͹_#ib.u2~+ ^Y/bPoZtsID*vaYd!d7 IN\yy`ZG؟JgL~:*╡ w|8Ԭ&L-YyBvkre`&mI ^y p9Bg "w{ FN/ekY P/%xd,cZS>Ǹ⣼B9|OAu?bqEL {73\j{#*9 U&ʶT.wDoHœwaY a>>sřI$yHZJ33'/D9tspc|ýWJJh8$ v"pJPM^ t0\e.ѣUKf6卤q4m ]\A}ϵ;/Θ~e}t3L(ɴqT#SF'1UIItiq=!4Jmug:*ڕ oL [dB.RjIh%>Y6߯/ܱ;7?5X$~Q0bն3'c(!W+7eriXEnڝ |Hdځ-'at+XƪϤB "Rw o32?1\8dG_bqw:WHc(CJ;8ݡK]ڔګ1\ Gg'{L-5)/*hkRTnFe';HwfeOIa&W ]퇗}NҥSw?]K؏pGb^*@j%8Yb1kmœ/B i9/wPXmx{˷yy RũTlca۶5G2])769 tϗ"0&MjH f<$%T~_ۗ:՛՜I't ΋ɢD]M#dM8AǙ%!%gBl1g|GɁ:2jRcqj_X_\zCiw4T4b(T0ə.uǯ;!AebADG5*|;!b>yQ7= 1܍z+c{UBŗxEE~H·GC\zH&-u#Q$F@{V)TViԈ@3,͗&յADz#kvf҇^ToZ3ELM8O,,緊!m,U96tGJO+Mxۧ;`O数RFqJ o?(262m-kKA85 JMP kӵM3NfwJX?cnu[r+,ydpNX?σ/=u@: p>utׄsQYe|pHͯ1Бز,/lT4 Q@@}{ϛWGc _%F=nJ5 jKFKEVI@(uB>mVJ $d_AmH$&bUSX9LiS @3 O#OsYu읶y1s,6ܴO 3 ?aIZPz 8KX䋺R)FܸV́C:=Tyeak!"G#rxOe( A(>Dܽ!S[9^ ГDhPU-L}J$2IRH,`*:D\ %Ǒar#ŏ"D} |.\A4 t0NdW|=9(m,˻w\.¸2}5e]0=%5NqN[@sB!c_cW)?1xx']&^&»ܤM=i_]&V{dEpc"ǣBwQq>րi/ 0$ٴdi@Mz\jXzE bL ;qtor:>S\[ zQ1o 9jXTgD+w7\~Vvb{y_ReLJK:(bppe'8iu=` qJbZ\yղ:Ia*C@*k?܁yo)P,ܑbcv0Nv։|A>Z~ܪRbN×5X]lVu{!2?-Ϣo^a||jw;?M1s/N9czi8"ZsOc[hw1)Q¿0E)9̈́C3BL&z'Zew8.n6CQLJm i{Fc873hgJ%;v9 Ub;#`ڝ÷ $._YkatSzvO.=^$"TY%6Uܒ-p*(cXMΐꅊbΞ'gְ-[Gc~Enf w>ĢM X+8a%bpsB1$0‰ܼ8Ez?&X@ktcڳgۮ'pԥӬHip{/_&fo& NQEZ3U^ ZUOI q ]w$gͥa_zIޒ)eC=%?6Н֞js}EYzEل?]>)w"p ڟ-ƣA4+4B.0~S9\Z!p`(idZ3R'%e{oEk5|lש11쇝.ʧw@K_@bz>T>Q)]qrtylɂ8ٽ]]+׵zln;L2) _ K0cp/v8lb\0Cbs?/QGwp'5ʌMC2'XE:"xwѢ,ln XyyBJ?M ^bifi;2U/DMDIy[|{<_T"ϣ\0`xqɴ}r}jYޭ7{|BJ#cysB[ktKk=ZVyF]oQ6Mɤ#;;9I-sCU!˝|hh VxE6V0M7uQLo`-_Y%M䙐asZGj.YٯIrMWcp82&F鵪%`۽.3 \SY竝《ewǓࣄfggGQAdTdU z&x/Zmu^ZULbsN4rX"PfGqZaFҋ7j=1&?la*yVǻm{$?vŝw#b3쮨HzW9} 먷v-YKRy9O 4)~CB'/LThtme[2 kRK~/e獱 _FYmj!^DN@Q~/5b_=ê)ŎbUcѳ܇݃^ iIeFn@4#ں O%4Q%Td q:_=[wr;Mdh'>4Bs~ԄK1fB'XE23ZiΫҕQſ)a_gGQjܑQJct5oMqGI |=c!J"fZh@-}zW&/A)*-R)/[dմhU.Qɽ+`B+ I;`NOm롐+εOR.?"}MH@&pZ_q.F*Ǒ`vZ8VhPNЛb2tyR ;mB˼Ѧ"fQ s@Qqzcv)g*@h{-+ .!+._2U6HP^vDcפ/b톝Dh`!Wn>0ƅB돋<;4 gqHAܘ\ֆs %&MP&Pu`vh,RWe,dT$ %qRpk}JZOb?GթQ{7+m'V FШ#ʓ BcfYǡOƊfىo n]˵wMi7%(-t;D Dc@mN-17פuzC|Zä'8Pc󍎪$A54C/ HgtY]սQ͌ӭy끣L# \Ȃ\},ȈRo͚нQ.94*`\ܰͻ,Oj:0ݝ,9OZrR3O.~CȷQa5_c%AĄ="{iG?(ȫ>L[5J?%s4ZzK :*ݽ#ÕWoO[CgTAr&1mSҪHƙUD6;,Əsh+ ֘W}#g-Q q}PU!Tv>/;ɅF3(SNՆLb&߿<0p{WEEJj=TGUFv행OjI'GzXr\fSzQ\:Hhr8;$+JQTEզs2Ktu0ȝ LQ<ΩsHЧ n'ڣQ0(*E]Qk6Ԏv;MiウcPM;z`̇DshUKBb* Yʔ= kWdrLQ hC.YTyȤcͨ0qu"^dwfX} [EvNr5 QRP"U(bK0`MQnE!+hzrDߋe0xKdQ,! ^W qD$ztJsae}›[=2څR+ J7d\:ƪp$?( vx^tYgbbpUT @MiϣE{3׌|f8ߐx(cLi=Me7IyNx Gj K筞حn.v)Y`h3]`.i_}G"70zLO*7(i(ֵCF ˡSkɨ+k!Z$AWd?~Y 4g+̀"x@66 aOeHsŇ~6&3`%G0".=NiLI;t#¢[+q{OyV':vb-NHsoyAt.W5 3V,iA^$Ŭdrzz44o*S6H8-nľfkL R,1pV9JoPt=ys!V~ir(2-Lͷ6(X*6F5AѺ{AճU{NAg`mBaU3mXo.&>"vk Ņ䜒sv$;DJ{DԙJJBJ :J/*6dU?ǞY/7}mf᧥Kxp)ly-Ol䆈B-6t3,3SimۑH] *N&s}BŘCÁӑpBZFJI[؎Ǚ|"އ\r|.ON/Y#ǤlWJ#F=.yLMwzQi endstream endobj 737 0 obj << /Length1 1385 /Length2 6006 /Length3 0 /Length 6956 /Filter /FlateDecode >> stream xڍtT.)*%9t Hw CC ݩ " 4!] !8޵]70ȁ6e8 (hi @A^ PpuC=p(C@O@03_/"/*@E a|;:_v[(t j @ D[3n |Q]pxe8P@qh\ &g:@= vo;r8Cm!0T' qit\!?`?n߻_ [[+ &/ g8*:lPߝrzjyغC]P_#*e%X!<uآݗf`po_ gyBBP.!0PLTP  >|B~Q]v! P; =!;O "6{( ?Qn|w?7Kp˧ng>AQ0EW!q(%UtAп]E]ӿ:K6Z?$ mQoN1W!eOga# r:H@ @ 쿡&?Ղ.UCPB٣/ z(C} `](e~I =-, b(}:(^ hyև3x p]JOS _jUWr-|0W茇Ay˞&i }CGF$nha<%h6.tx6{V6ur x~|NtXXBC KD%OƤE`njEB7ϖ:H8vI X ?/F~)x/˒UB;wwN sPGsUQQ mcӾQ ݾlSjAi)?`c2 5=?e%(먂Qetu=URi] 胉ѴXGMaZz@9s .ܢN9X欤Cn]Ϧ?T0NzTbu& :I煙Q*~=_O5dBƫV9 &cp-f ;S5}),O=h:$qp|VB 1W}gqM!||Kg33?nH_B1o9?PTi2:WZ#1)[9>9JJKnX):DŋNV!/i}#x:o\ S`n1?8-ׂL JT+[xF6 6J/)ƱT:h((S) 3)!ɂ{|2aJ =Jl.r`WK}E]dGRX}1u|h 9T]JSNv6gV[WNgK03ױGssޏ b [ 9_ƨ2׭ ε~jF~E2>8I~ˀsܰ)aalWeAz0}2#czo5K6]?8tp[aJ;HѺJ<3 {Q2F AtmLx} nt2!YLd%bӘVv{hm8ku&/^?I{YTD;m0fQ0>):nF;'oAыL4t,=:?&ysY\Vjڂ)ccf@W#/g:2}lʭMRص(\ wCDD.[^}QFR{Жҩ[ a},T4?;9EY]ŝ=h _jSJγ:o8֫Jf 0 ʦwV#(_ut/ !jI#ќ _U"RpMNWJL,+p?9r\Φ\hg(+1Fܳ`sm,?j ֗ӣk7GY!K? NLm-tgladX{J>0|:8ٰfXlk&?xIPs#ÿRNZ[6_)nѠ]1he50\d"QN 7wWP!͢+jT sULPmkq^_Lgh"*.;o#wמU0 qM]כ=YJŵg^#B\s}ChsOŻׂ.*kiP+eNUN=] PJӈfCrZB`AzB~swia2JYs'~yx-5aT{`0s}dX$֢kpWfYe5nPPrA49*xDX(5 4Pi˜I[fK(-8wo., 2,.@* "w/uUMMNޜڈ(}{e{7ƶaA"SB᯾Vy 18+J `ǫ5(ܐl0GJ0]Euj! %L6oV'LDFf5mi R퇱fXo=kEzBkΠu2rgF2scLjALXHMSP`dkD‘0} UXNdtc|MXAP1t UԘh>b(o_XI%eڭC)hrHH &͐BstTF[a˷\Ӥ!1A!Tmfx)\ovMl[I1žL Č0lf H3}+̲%N⛨3? RNab9E 6?j4Nj~ζ FwT9Ϗ ޫ<*χ1 T0G̬U^(%4Z04F-|DӬFn L 'X&lHsɯaN4Y~hRBfC@TljYMY`2Hu <[PO*׿΋Ӣyq~:6#%2(#R.A6V3#^NF>k\ٚ]):mDD|qi3닛qʉ<T3i&7mI}7U)T0h\Nif~7VXL6g[Qt߇| 5qJjhXVϞYNks^oM7z7f@cSe o㫖ƾuWJZuxpo+<"c#͋@R^m^O=Ӆ|oNHu<̗.Gmv"k2\MuA؜njIqst4ɦVƧ8I&o2~n'pO~{:<ƕsXSMC d=Iky;"g݁?Re&1pe"1R =<@G+Qj"M'ku܆ ̀S3i;ު'HŔbyCГﲢ $1aӄ>fho*1 h^[wDx1 .U3v^&٬,N|TxmH0\;}hE=akgj&fcw8xTR~ĜbLm:sT_Θd"ER)+vc[ﰚgϫ9xTn0x 3{LEq̸+narRf<nKIMeܕ_I80AA u;ij塵/\涠 #iN'pJMAjH{ڑmWN|vA+v6~7c)5b]غ!nʶ:K '!_(ʹn{sԒɈ:P̸(y@/2dsޔC25AT@e~('6 }4Aq)>xIuYyS%D٬ԍa?JY|rȸ}N&jTQN nߍZ}.˷i709PJ2@t}Dӱ4|յ?vrdx~!*4dH^o:\74FnUoq,^'OWT=}VN(`*A!}6#ДE47bg NXߪC\9&]-d S@q.;FZC^h?gsv/|,6[uٕ B5c6F&9Y=ɽx  bi[xA|pNw3)*tPk+9xf>bClS_kn4= ^RL_@D7'S'Q'x`@yrIĤyzCc}A޼/"ӊ2Gl)E <k'(Em_$.bUU R5GXgkC\}TsITVߦCibr[+P~\sSw̬ cL[M}nI.qtjY{luπ/^]U<z-m>I\o<\OuڰN, i{>bKaʧ?pٰ/)8+ >$DFU(X"K gӲl=굮fo1nH8w|W wc Z"aA7vGb>?||*5f=(tnU:GfaTR ^8s ŠZ6ǽÎMp4ī>Yf:]06Fk!/PI}t}ғ}$'ꇅ/^5l煲s[Gqx7>5ʟҭ{=5>\!7_2mGN߻"(1)/ N _)O;\Y\eRZȢTmA."}=5%fILbDf J"ydb0~3MIS s897*)taV,Jן]|bDmsH=-b_euNn W]24YMh]H/aGt7|igl,ZS0Ƚ;n@' 4 m~"1A6+s'MOda_f1мf^JJ}8םIBYw2=-8U͠A%5&hD3,M0Ґ;Lz endstream endobj 739 0 obj << /Length1 1546 /Length2 8420 /Length3 0 /Length 9447 /Filter /FlateDecode >> stream xڍT[6L "!))Hwtw 1 ) JHHwׇzsZ߷fgu׾7%1Hedeb)(pXXؙXXP()Pk_bJM#/1$Bl!Y'k+;C[>8l P`B@(bvn`s 59hLh "6  PB-@6O7j&`BX@v|...L@G&[sAZ jP9A_6?1P-jfP$ ONSr<@c,ǀWoLW 03qCf`k@IR e! ֎O@g hd;s @RD|*MvPG&GyT:O2yjZAl] 30WNvHF/'?2s@&̿«ف~+Y*򰳵=P< o#VV) 0!(D;],Oc}-eVSVS:QQ[W#+ ~:xwe ,XqXYdԦdhZZS}b-@X8YL>T_Qo$߄$i~?j /':A@i k SjeE?( v*&(Gkլ#?2zz?xGt|Z61 u<$ & tp< q СF$Bj5s.T8Eܲퟫy5TMgԙk6Q?>&* _ĸT\X! u8zŔ @\A,tM0՝-HEٌt-KPG…af2ҷqP[}${F85H8^މt+ quO):@c ,,[$YP%HI?l&!վ6innoUaM_ yᇊYM P |6 a QPkyf˫@,TyrF/}W;X^_D }oLcQ' rJ!ł2yk_'PQv|x1^\J]o|Z\#e`RX/O^G7#ueu /8سg67jTrWhۄtIc2LT~[.Ё*+2K8hVpU*۲oӲdeFGwlnwfm9'4y~üțwZwNy+.U>R=l;_1Ʋy/k d6 Exԣ8^ ,a?GXӼvyhhе\I)QTjNyDef}JsB1.BtN.OBFs]!;4A~esǽC4[4d>-瑺%Dz ZˤI툻il2PSh8-Ҝ2tR;G^g8S-n1b -}Xְ4Ż0{fJƃ e[AڦTOiWu::0%VA9b&2 vAo[;)wf{+r4 I[G_߇(tSU׿5tMS?u%eJ q7j V[yAc9$) G\A"DuL\Hϵ 2],[J:o>?Pto]r0)y2vJ'R&s1Y^JJ] C=8Ŵhs>$ޜr%;{pMڗQ!P^:a4$b=m]:l6n{zNJƂؠĖ Il-:SH14k&!e |jۮb[Zuy2d X9MZrqE]%Z| \ŀC((R#+6q^IαJ"+~߃; W7WK/# #CKw0@kax4F@!o;Vi{CW̓}pE:D؀Dž'pg"KmP˽ eIؕ2Dmqv9]i; ,+1j %3Un&SyxOX ۯ"OiY)j?i%dH'>S~;T 52!3]]6+=%W 4}jn "xA~ {!+QX]';6|%p,)b<E !xڏ=ehWmq=*9a}UBz+?=6jH|Z|a|71xfnԢm\Ж);+:!5㷍p1x9k?1[hyrH&Q\  &7uއR`E/0.^-lasV\VM }uwz)0ܯ)^ÉKdSt{1*'G[7JMO?哜-sqvm~(F-h8B˜U8o |8>'i4uDZyʏc?~0l ؂%4uqY@v{4Q0k, q.˻9js׊}q:zb3h@g$>,=e#gT~Az{'+~L[e^;G @ۻ#vɜaxx.fՋ&F=YNG AA%Mc)kJIF4P_vzTų_T9L@R`D]:i`HV}=$J0T5>"U<)fsڿ?/ňHGF 7pó) :a h,Hi$&YchbOvLs >ܬ,fK*'*xnbQZx?к֨Bk|eԉ0%G}dAç?#k@o4ƭ(_\g-Y$}ߵ>j)rT䡀*Ug"~A/{{?G5 %ܜ-Dn$#H ar>^LW$C q?Y0vgxK ®+?)Sq%Yۋ' ψkPVnDy _tO 4}Hh,jN5KD}\rFYAPQj&)ag9}7l5Z-Yhi/)1=I&mcWQ ->/[TGX$w.}$<(V_m 8[YPuBlx/jq*8yFX$^%k[~\7}f6d8u~ٚd/f<3f=K40*+_{c D&֝HKzVh-dF ӆPf)3]eRqUuJ҇ Lՙ3ކ9*#VϦh5^q:mJ܀54n]7Ucļ@ބF)QrkǞ&[:0ױo ߊT$N[>0Vjז?d#|NdQ'dU',1u*@S]!;Xz&W-sL6c ]{F6}Uf[mQ2x+ha'6k.>|y;UT%gfv"f^s3tm]qfvY 8?5ojIM`'fF`09%!+} <^ 3 JPUS{3;mRv׹0%<ݓeJ)0/drmXy6-lWKhnf3vԮf 4̓=|\ԀO+浽K~f#?މ#D&"5-/Cg\瘨)M*|$8?YfĿ"ѿ9 о|VZWcQIn]PvWJGcqT$OK ]xD} FI/I$dcX:)QQ+;ho-c);!F?Com?dI‰)LhA PD ćB2*b8jS(~0?B*Zᘲ(64ot98߽v`Q6d8_+@۴-_CrffXB(1b䣗&h'ic;hX3"Є?s119Ҏr`ۺ(q99ˆ5W]Q(W|AK3UsB:idGt^B(W(Yz>z(!^̱?ċ^{ucL@+L&<@ ɛgHD`@pwe@C5`2ʊ(j.t_>b[7ۡ8;T>+7f5z2\r@w"U12ʉ}¯m^qM*{9*`Nb@Kw;֓D9ҧnN&yiGAa"V^TBБO4U=uvckUa{^\13vf>.XzvJ<K;Cu{$$W|xșmL>A!wj[RV 7cVԐL > _bQLgn2Wn߮3Rsre@kץDE\?0{8w鸜)r䰓($'B kI#Jom|3W|/N(}[A_Ƣ7vOL;z `47ZF&%q{"5FRYuC=UĆ;3,eݟʽ F<~v7].]:6t:.$"?䳚Zꚧ*\L~: ejh<6+5EN/^eg򅪁]Acn'х b寉 5&XNh/ؔTƀg&jIEu׶G^1vpXv;v=3- آƂ1:NӶ 2V=qS i0>Ƣ)QQN,KUꁇUd/ (d=2ˆS'e)05.DlDm[?2r?sU )%|Ŋ쒾imjzsDGT6}`p(SZU3[?YD4%s̅s: :wjqzw96;KFJ3V!9m2i:FR=cd,L!6򖺣 M縄dN!+"nCw-~zۉ I5Nwn*| ;HȰ'yS*.<1}^aLZ]9}3l\ s%z2Jjcr9Q4/&'OGot^uﮃq}z-Cg5p[JmGΟ`^6EӴ32fٖarӱdF.>Hr3HY4 ?ׄ I&G{|Zz`HIZ@1#rXX|%e+դTl"}Q\9wsY$󍾗6m> X*%n ,goDy8GkT.8zd{08A pS\anL+V)tw,>"ST8>ek*B6 J9Ydp ,zoa5g;T6ܼ>qDeNC-jڿ-P%lcX܆:pV Q_`vz>Q3];3(^@"Z/>' ƈ ErFF%܈l׷68_K!K5>L * /ծXg~Kr=֖^)ITed\ dl ꡻ɔ?4,kY!bATюQ)-Rw旅LzyWL^}ܝWK$Oii}rh[Dɠ~RR% )ll$DC$ " HFXPhsVÂ5 ^2 UkhDE <Rvx%,fm6ڦm1cg]0JB'>B.2_ pxXin) RET}2z6aճ~/kpQhs#CmLtpl+@}Yrʙ>Rb*67*O=1Pȹȡ4mGo5)ɲtBPX75oż]<'韓tɎ3N%W38_!r'|Vo&ZSt^ɕ/WU|inV`<˴WsFbԧ~.sX멠=@ 9@/Ux|<ӏ)^uS4 \[0'Sk rXY}ߐ51" .Ѩ֗dj& r+|gPgmD ex r-elFefo Q=)Ra^V Vm{M{(TKOT x1 6 KGNF hYM$BOж;e ?3*Ўx dA֡Mu۾S_r-o#,gt s>޺ڟ f\I/:jCZ02 ك [o'LfJˬrU|g`J[0G z9w2 ǫHTOVY)ަwcGJQH~atj>"[J1qּZg \JvL]C/hyuF|7NIa!~4z&-7F aśT"ؐ7EyYY>&0 K9BbZu5r9:媷'7VnHq!2H(jnwFYæ66OlR>& ^OZ[Hg:Q'5fxguj<nۼijt2#bu@խ "A^Su_žuj<`]X'po7oN#(&I=N /eq1`]+)|k݆܍oG'g!Y4p FG&|ZE11A"(T3N=zX7yxLwmu8ąuU 1J7j:sIh'QHYj5bpGa*Z6.f9o;44t> stream xڍtT/ RC 0: 5t7H HJK7"]ҍtw燾9wνkݻf<9XgqT4.6Nt::m F;:A`@ ?b  @^A C_vi P!6ku0Z0|,`GPm7Z-; !mp{AvvWWW6( h.`K [_m NZvVpW#@!`ӣ3x P2Vˀwo@6;daagkC`+ PUfY oC@A2d%4.bwbs@;ce`Rv` w~Gc[+o ]= VB<|\fa;=~`Xb~CtpGgV,!p9C'# K~# `= 'GzY/_[')idrpIx0 i/_@l]&Xv!M?.7"'$ Q3j-#i b6*`KkEYCF, l[Ŗp[vN q4{\-O#%W,,'/rG>%l0; ȏ9?I0(  O:;1Ύ?}ڿ?@ zStY.Aʺ6(2Js5jܲ3>!?Nw^Ї%;iJ-1H+֫NCxpc0cp -Aqj*up!#hdtF~F j.T) YUe]/9ɋUT>pGx.0lNbʚ ,JVXXڎ@ >8߅,KjA@,%= A2;d3mR㟹َ 3@ ´ClZS-}UKb2yN$* "!f>{W7\e9tyҁ8\Ϧs r5)$CkFfsl'+'B,#tvenH=p&zHpnCc{ۘ7]4jc/.ǭi!1ISlh `uR%Rx8E>?[бrČQ85# {Փ(#{rpT)e[=Ce(k Al%8]CBja>_}m ,yɖ,vb;IƘ ^c8FSIfqmBlۇpL,mXy|8װw Dh+ur {*Q.\3}JJ2“Mu"ƒ}'KZzeaOq밡xϽ}R7z;2[ v{R2( r)2քdl2]MO2c0Jl:Mvɷ&@](󓤒+Vq3ʄ4*pُ dAaVn~^ۨzBr/ $OyOn/Q\,xT/ E9%NjؑÿZ3h`E K:)5iyîmK 5$.[o#;4%M5%A;nUi<*_ʞ.}h,!Ϳa9I`qG^̯puBCE~v?\!o8۴ّ1.lο Yv.̪ KHC6] 41 ƏI'4(W ]8w|m,C a(w%kUM1{ s3USŊ7nEU2r}B O>t|PB(]8ځ6*K;</b&;~F {[ȲՁ>'Z\E *3}APƣZ4p*8܋}vj.P~9R{gFi> `GA6ژZg%M\]~cR?-dP#D٦Ѐu-GPQ7+xIf`0"X/v~q%ej(FZ{`mЬ+Nns lm3eeCoKgB e43h&UYZ q-y`?lъnE!W DݽiEh?݂*9!|H~/v+ońy+r 8% V*N#cz:w޷5u5&~cto"z>P^} X+podywa}EFMZ:}{U{]q߇!ZGiϪq[4w|@VqI밃2خ2މa>]$yXt >-OMavNJgZ[X凡f<}/ /zضQ SRj1(C#D>x3INsZbS9szF4\5Z^J8hfKo 1^_Y)O0o:,8T?=Gy߉]|u#H.ySeJ\ ٪JSdV/ҞWbC>).M +'c?{ !S6) hgb^\m0C"!k[ m)+6n0p ڦDY#~>eLǦQ^6ӎ~s!rl*AϵyO&,˛ю|UD3~OǷSx~L |C`ngiP!,#-G{[8tԆ%9o ^#bs:!1aʜexs}=Vө`)0 ,`d;@݄#aQL͑?Ű^zh&QD9Ѡ)7UCe[1h>9?tSwb`ݷ) 'PFyu.> \RUmYPlL?ѝRPw{51uCI**gx$хh4ŋQ 9$=Ha䳞ckXm_7|N ˺'+J;OQXp{SMGqi_bu#8a'|y]@؎hJ+8.1i&%E4"_Z{OM{bt&]E)-.`εyHmzjW+?B [Q9VOQQ;U_ ;{tt23j2`Et;yy[' 0MԷX7dƝ9wwF[J+ҧh+-- 9dvA@ 9n;L4^ Gtb;!M Y wƧljo?!5)'ǐ$@G[GTi:&YFm2ړs~ auDh7q|:x.+n-yvoV$Bi𜇵P.)ܓ<\a]" #Mq"&pU++t S1bu<ݴ>;]Qap挮eZŵ7(zޝu_]0:9kE8e\tA1|2 q%d.zePW ; +HZT1r'}CkUY0,/\|^6KJXY9ۋ 67BfZ F|~%F̝1Q?|NV h0t\ ofBQUA~I2OO)U^"тn;cY tG!ybcZ+pKuR:O6.GejBϣrS}F:~~`Bhwݕ $J8B|x'Cu yݐ,݋$s;(0-$]5[ jU=?HSW_jpHbfaSMDï1}H9儝-_ALhgɳ&Y=St_@1n_apB!J6A_!Oզl*R%tn^SU5v[Sۊf2t:l;QGiHPjfMM.RRn\1u>#,xV:~r:jRyOyAKAtqG]lxj2"]+T (u$ԑ&P5)qtVKlO_QorvF̄NL{DO`?^Яɫm^9^D,42[߆rw .ja# bX⡼Ix&(ݩ"?ZD3TŔy(4-OJ셠2e9ґF唘84A/ugZlpOP/S289M 2g7'DuT!|Lѵiz]5oeY߰Ӯe$DTtR,Nػ>/4M fӛ1I<=IHv> stream xڍvTl7%1:I(;0`$$$QH(!!-"HN~sq~יeS q57+\ŠC$@ #s9 ,%K-X-@GQˮC&Kp3B>@"S`E&44Qp7 ! rbÁjH8FP'I-0B=X_E(((H@c<ŀA'݀C߃I?j ;6  ' 6Bh Gq6 k5@tEJ@`h/@y>p6+~9B}фxh u%8n V3B 5? K#|~Md-_i"0pa!Bp|AV(_\O/ ʀ`909FrAFjۤ%2` ") # ?z(w4PO-n_/bM@,(2` !7t*XHO_v^ @ ]n[PP>/ᯍ"0?PE0 nGzP0lV ?Mpi]R Cb,@C+&H2@@C7xoA(4$tGcS['k CL * ` B_hص[^o>U _T\MbZ(2Fa2:>-i N_kJ3k>;qN5 f}3x]C-nvfMM_/@δ ['_9.v|l婬IVIQeȱ<"L;{#LCR%8yñЙjKIv{v=w2>KfGJ>9D/R]A?S%s%_3xTf/ x/&n9_c9..&D_TRڻλ3ȫ<ū#r,׌VE%R#wQё0aVP;U rv*q~^/Y1BeojXڊJwg}K|i(14ἴ̱;휃ˤ Pg/ Oh4Xb'(9-Ciʃ;K^?OLp}X,]ΐcy,u>r0quzpEE=szuFLiCkރt ףӹsO<զjߑ+2]fYVSĝxpZڅ=SPȝHi uFU\c۠fD-5C>\Ob(zSy HҺMBs;&& Lɒ`vل fɆrGӆL <+9u8V? ش}Fҷk"1EјrFgeۺ{ۗ GLtL x/-&^ zRdYd|tN2Xks ().kJBMvݨ('j,qtZWTGO .N][  I)iLyլH=3 jR9#xm?EA,B%djQŇrGpioNH%WG e;ɯ[;Z YOD^pewzW .l'zǢ%yPUS ) 5(@NpF6}un']J!QwiR_ΨX Uvo8(<-8.8{bvS1:;潇g,39wRKeۊsnc f(畾BW8=5u~VŌV nwr/V8 .QL{lԉ*>:ef+!DmY,0MuӜldyk2!RQ/*M4Nd *!3}t<{y'U煸Riɚd/Mr?#s=2$*ie)^vY:M.7XH<.Gk?~Cb<i,="BĜG ltPIږ?EQ|{9 Co+qegP笧/-;*74TIdna1fklS'8FuZK:Cwq#l+e\QGܮ&Y7 3n>yM1fK2ޜ}^#w_!GWz[&FOq4ZU ,J_z$r>RV ACHtU>A˶k2[7yEu4"<3f p\FrdaU-6ӢJ̺6RÎI ||%Vnr [9zoXmgHb[jm nj5((~>U2<&x7 wﶎѼYĨRi=vo|i8af戼Ҿ,) dlIs<IlsS#vFF 4Hm%P?Yux0KHZ8BorP9Ki}{|vhV GY քm߹˖D-򵜳5'$h ~1:pں_ Yv3Zfv'$P ~1I\|ygOe+{vM2Gk /qz-$B.F?GkوUTjW?T*~gX ph8'D eY^C& k?#e':i8Xff?C2f7Qb],9FbIp@d_s2l^nܭdZK~/ÄyPV惌yhr櫘:ocх)Wa{/yf>qAX+t?JKMvsp9tyN@*auɽZbo=>-$_~7ݎ:62}+Ph9DuONeun6Icޝ@;ĎDU +(@ J^i]bi 9I'mq;Հ`9Z2&yVoUOhl^̛HRf:G{}'R}gXS;ZD&{%=宜,;\b͞Ljuʒݳ1&c*>|~B5xJ;NW(5'կ/*UyA@GЖ˛Fӄ\|P1//PxQ~Aet9r?bf21PМ+Hskd#gxN,T[wMɶJb!w]ef[..4dR5/Z-_9Wi Ė3kG~g.\p/^X^Ā$LJs_ Osr YKۧ+mtJ 밈K.OF.zh$rzw;_@U3(RPpiسLg0s6xg\ׄM-ciŊ }){|mV[fdA d9z\Yawsg_KNwRV<3Y [ iSK7 6ʫDҫ_xTptn+]n ȥuVloMZf119NxH[C..)+opy:~I֗q#PA;L hcS}i9WD~xq-k: v ):{iY&QܢӻԂ6?LM}@6c(:3Of)MY| ɫ QƬdn&&]3^i+s|E V۸!T=ǁ`?*;2Qj,u+=0_ja՞Ovlw,*8Q"RV"W;%S:jP(=K@]WAg]M];J@t"*~ڨ,Ps2=*n#uPѠڗNw/gć@ڇkggܯ K̶uh'MfmiuK$]enpG=XGͮz{,dV/hҢ]qDWD@w<fXؐW=(Q5PӑUWiNYMpʢTk!-زIЭ]=)8LwK6]B1q?sh+h prIxr@fv90ӿ`Uò$v2Rbt`+\]XVSDBEkEZiz *j;mBdK"G W /@M]4)..L}.\}O7F]З*WDHalP%*ea4Qc\vrRN-r2='9z4: ҖNKYۊUz%[~V^] sZzVBPVhZN3F)~=^| KBDqٮC5{z̐^K L{QwWK36?[)vxp|u@\-u^q1)TyM`p)<5`޸٪ge9Z-yzmW+h#Β6^nF&]m- N9!"$qBZ"l׽5vrFnj\=1gg z4;@ Ik(9Fè*&Hg߳rku`~nӮñܺwe@EӌmPs6>\\*ZZDy(SL^rsoOn<v&nb5"XI%a]* U=T*?w"P$n.Q0繑Hk 4"=9^Jd0{ԩ&붠:@[Æкӷ6REɌW1 |K([um fPܫ۹B6sLI6&wU)RڷGr) 7h1jxn|zv?nbLʐSުGd.fxv2"{πkY oӆL(;6;Ќ}b8 ywCFq] ަD4UⓃ$Sy%&Q#t+D}-s}ϑR}vOE43d"fvM7umԙ6'#p)* {co/~q$>kP}t c×4=휦FVJ4uNH(gzYɒ~߂S-;+&nKk 2Y(eA'\+O|gS:\}"9:n0I.%W@wnv+ gu endstream endobj 745 0 obj << /Length1 1399 /Length2 6072 /Length3 0 /Length 7032 /Filter /FlateDecode >> stream xڍxXm>"R@:7nc`lFwtI tHH(HIM}?;v}Wu{;DA@I@!Bvvc'd7z`H0<`4S1D$  QI$%&"=$`/@GD@QJHw_3KPpz `@va2Bp}KvN|o`EA=_-tn? a FHG7 p@a\<P&;HCEE9_x CvC H7w0p8P#~p`{ w`O(@z*%FO`W"W06<MP ? Do %DEE@C,+;7!pĴ 9B1(+BP'105=`>+ F~ _W9 p)eTTD$@G Sj %{ן3.\(BB0oT+*Hmn0Fh 1oՁ:<۪cAQ4?_8 :Tnk0T`a ⊹0mbfyUïa=<ƬD T:@}~ (@1.LGᯃ`O/7 ]4О2(䤫z[/mgRdV&gv= 1mKj3_c6EZZaxA/53k4B}s<^P u \|3EQ}8+ =;M]ϑ{|_ê!NZt D!B;svvR^j#7QEk!m򓦃 qۻԤ,%'XLI 猵7t ,$#BH(\*}T&E&C<8qtC`/~AϷ[6GB6Z]veɰ-E#٥&A '~{i9Șjb3cG ~XMr5^՜$Ҧq*jqڂֱ\zVʇʀ;k5:!8D1_'„fXΎ̈́p9EVlZ.܏z?R3 jAoI\O hw!rN+n岓"E*GBkBkZ+ ):ʡOv$٥]&֤ikY?kc:3)䍆+]XJK{#gἎy:wrփ`֕nQd`eZzCS,_LIՐ-zL*헬AOy{heӷM}jP-:f+B)ԬJ57]A6LnlxՖ*Ӑ~W*=^f,_ZYU֪o94 2Kp HmGH;]P';74.m+r(J4\ >ߓBM5*FQD{^ƭ [3hfGݑ^L|627lR#wڰ+3!E2G#B릊 go4;E} J[#bӟI" "Ԉ/S Q8nGOؐ+;8^/^Uٙ |5rT:]Z|>\,V{NV}W=U&pHGK4]e?iwd{KckrqxFKT+GDkU㍾0 JD uhkTVƕ Q,q bb1x &;~5rZw?8?fr`H`:cu<Z\k4_I[u̎V}j[-[ߨ6}>6 ȱ>ݒ#?GӲDS~xؖnmH6g1p?'xp!zZ2s{`kY•ȗ"7 !k;~<SkӼ QP1zs* pȾsW]&W[ ۮ xˆ\gmɀ W{nXcptmT5O(Ғ{ݽs\\ܗI|bf`.z>:4'jA_qK`UM4t ߺ T@*>7`ktrZy5\,Lˑoɣv_?g(s@)W7moF}!)^ˈXIUݛ-.[NWcެͷ(Dûԯ C}Pc:ELtP[JVԭ2$cGHZ}3 6> ^{P/DpeC˛¡iq'E2.$xA_ ϣ"rCbdbR,ۏ~N,1<ϐmXӷ\~-A'ky8}LpP <٭'6 :}#f`-Kn}nL?y-+`tqj9όEƅXg "תq.@?JL+wƾLWlELjh7//Fk LߋJW|O]X{*OU,Ci1v1MGpZ=sɯ]9(.JQGS`s5 %;cߦ,0ޥ:I yBs.Hg7n_x£?bHK|.dY޸e@ ˏI~N*o]<J3rK"OדSR/P:pm,鋁 kqUаѹ n6*"sD4Qc4y"]x9 <_y~ϝJtIMHta/J:d;TŶ ̠uR\Õ[Y$壯\ Ne5 Cdt/"ot#[pɲ.l=u-@]`}Ī'){^Xu2$S:́!GQO. xRv3T&%?]Pg5xXLБ>eS-plJ/~;R]U=gp@1lPMk^߹!HѪGcv'&D Șoiʑ`@z:3=*}SY4q.А4 }U]!W" SSLI0NNi֢\RBα7I3:)JrɑdYWnE(M%-3H_ѐ+`1.~޻yfb<VS4NEVqO&)||qu:`|>`gڱrT^Z,I GulY="7XWhH4.qjު/;p:%PݔA'AH\ܬJ>UɆ]Utbr8`*#6){1(tpYD͑Eec94pU?]v>wk}"Mw{ Y~\"U# (\̳w,*}OT吴}.5ď/$J)$U Q-hrYcdg.;»Yl% J6t!rvn09ߴ+?&nߩ!C3TYiГ/fI[&F6{GFG7Wl+t* `-k|z-:Ii&Uڲ{85b]%Mv4*Y;VY\0(vcz*߸#όA - cִg>8ED_(u+k1ѽvrv,5 ڍ~f!U&\elEDwaܲt9\Hi,Ux T:#Paώ?R?Y斯lQ̺eJ&+RUgI*ڋUY8|ڎnWD;w(Y\y35+`8EvQ;1tZl~zIuzBd=>ovz+:Mv\]UsZ4|gz=QCRWpFw8mt)t{KpbiU%+P'a 4U䂷oUfyIOYZ5Ӧ} ӣ:#3@2Rj]¸ͫsj<5 ?T2hXrdAhEv3&iɔ7Xɂ K-Um.b4%gB{y![< hcB? G34\ endstream endobj 747 0 obj << /Length1 1409 /Length2 6124 /Length3 0 /Length 7090 /Filter /FlateDecode >> stream xڍtT.(ࠀ0CtH0 0 Cw#% )R"HJwKw#]"({׺wZ|ﳟ߽y>vVm=^Y+%T G$zƢH bgׇa"v(K/< F10 @j~AED % `7@C]NH- Ϳ^.YG(`-#C@`P?JpJڢPN@;хzplP( j50@3;@CXH( 8 P :nEЛTZNP߳_``{6k·@=V`:9-фߝJ:0z@0' ׈_eЧG8:B(_)P=np{]XVֿru>Ü] )h? w FYCD.`7(tz?WD+DG< _=E wMLd199_+.@?D, m\U5 [1ck.?ki"Ъ8#r30~KwMῪD ):8sa#/-ZW M51 QUmY Z̼B| ?8E ҆ $j08TmAg@C b~u;E*!_>H'-'aa7?ڐVPJ:`@Vt] K14@脄!H$:LkPB4=< i^.λ><θ#B1V3° Ff3UQroz.N>@Y 6C)Wuo?31pghfFU˦5#մeʶ56#@>ŠŞ5D_xƦwgtv}V&RFIOƚ՗EOV!'M0).}cc8?[l;=Pd' L@jVod]jVR?I pB= z6+W/N& 쀍2#Z9Unij]F.m~Ns >S*0b27^I#2b{a&ONÑ+壝M 9y">ӎa:n} Me K㈾6BS֢e0y&A9bNhz{5Irh8w2|V={($!ʷ'g٤Uὰ>@XZǟw1ByD^vt,MhΫyi*^R^M_L2kBLT*/(h_P d1~NaUO$=58Fs'Ǔ2ci74ӥc9qGOzs\Τ3/rIa 6JO3gpcL vI;qv*ߖ=O#o酔aɉ^eU4HpKܤ&3Qܩv򣮕e뷶KBӆ<;o[s_>l 'E 笯9;ӒPÛO o ̜ 4hroE160w_|,E o;^ҍu|!,e6$zSX>n.e՚@yN\\EWL2t<(.5 m^MW`r6Ƴ F>D!䅜1G=Y+zk/cǽTl5j`qo?YsAN> Q5*91B?\*8IBM RWޯ*KB}L?C.+Z#:+ GIRjxOL8y~|io;%~ /?L&~7 -Q1q9y%0E$%!iw.%*iqvgJ({au- r#=$D9u{ ¢Kv+,G_dGYK־/?TȥO/3rFB/s8 Ǎ NG(|fI9h΀2րRl:1soW|Ut>F[}A %;^P'&7`7۔={6qQ7k]wf BۛwY'EKn$}mu$ڏUk"sb+^TU5?TbPU-yApyt/: SVBrbʓ\t+U<_^?H|,9^?~Xr/N?Kf϶edz`GE=YpwM,"Ԟ-+_>qL{4DJYUN 9 <\8?%0TD芓h[T ƩW> |0Vnvxji}SػѭA[c4%.8g̗{+?T0.$Zlv"s=n Vy" Ŕz}V9Ay"&n%~b!5 fluma bT~B\z=]_x"LV #yxaF],%rhO?cug+XuHgEIŞa`%VإKor2.mz NhCeWF(^_-Zu/cF9؍cBCH Ө?ãqLA+6p-"BR/F \l[_RVx& ~스?d(a rf%& ZeO8\n[M~*Tc1Sg`7>߆gscRe[^"%k,}eP.g:{HeS+ڦ"OF p:S"*sS-].76"4\ƃ"ì;FkO} zZ{ Hݎ*.ju f(zt:A!RldpGx]Us#2BxD 3P:GonA? B}jc2`3!oyJ y!>^Y,Qv,UmқZt!MCVz &t>Tvw E,-5+HeRe:9&n'2bfʧg:έORn}lnwMQ.(MI WRlgRHqϰr5Y0R.덧4f?PrV-f0ocH%Q2}[ j)p\l<ž8*"F]$xU҈H[TBEnHL}%ETA~Y=-Msͬ.(3[*rl( n 9X՚=+"cMIHSz'=Bܖ-`')xW20T'vtDNճE*XP}>=s`_ hg?[}8Ʈ#fqyS3 JRi=*L5>Ay,U$HxLeM`DxE\wU ڳ/T0-frxViroDUV^0VٰmrjNeB1-ޙW>dpj&`{/8, ,*UG*^ # a#W꩙+Y8偏-Gig; ]SVTKΰ< Kt?] Q";-_2ȿlI!p@#rjehNE6X0#5!Mw99#Fg!9Vn~RG36(hd5x?a.^2!OQZ1JI1shP!'D#c~g HY]cOurWy'50 wGאׯm V)'H\5D ɼ-( "[WFT["a]*.nƅHPn4˸F(]pո9j0JezgkָǓdJv6gS,&i ߥ<#S'|8V 枾xN$XvJlF8=аG3ߞ͟?̎uŨP8"oav#:"4LaR;7.p~Ynbz |e//.Z2\?ԋ2ٙeu8=Y:tnoAG9fCUe98g {$ k"Ukms$I{|rAERVվ>!d=!r>G~t`%$m;/K~U۬ܡ r3y1z7S%*+YvSyF`ݖvYh.z>[p *øI|ᩥYlF]M/F°hzш:c鮦>@8vfMs% ?2#$M+q1vs"2g9Tl>{/~]TFO߿h(~u3ޔw9weу6yW6<\hxPQoLP&.D^\LsR2>͗IYĺ|"CJІzԕ:䝪}ң@g1V3b&ɭ;-^M \L %Ƥ낤Hndz?sͺHr >ORpG΀vJ2L3YLw{d3.H1OGH4+߶v6s%NRCCtXCbDooc`?'{1zJ5?}we@ԱfuZ8Gsj٤t|&fb$ f3(,d@seLpOE,*)֞d2+Y]]D!tm;|жJn{C0q-G` T! vj'Op 9 Ѹ,G=i$Z >RYЗ8 &Ԛ8]:pr\:h;`]᥸ ,VIBN| kjڮ S|C.QbZ0)hJP0p{ XLĿT\Eb 'UI&NՉ_}E.wBp* 94;[]b^ii'SF`157TԡD͍+ jkA5^傑G^G }ŇgH֣ Dquu'r tz9rB 8OQl6E!j[Jh4Z㫊@!U@*~uDyl0]&/H@ ^s ǀdB= DXoVKB$N u8p)bQG,D*A5pqo[G+nMU;ӂG"o-7un 53וb\N oyVJU3͟h0¥a,e!Wj?*&#U]:.7> 9$!|rc{@R0q2%Ӵ=V69ėϥ(y|"CYFzPzJ<<}֒L[1Vs\:xl/bk:Jf˅$RɬG;3هٴg酆Zz,\Rsk)l:u>ͰПt4z\Ey_"0dpwsNg~ jM/% sqe c%HX&$d/Ԗ'%JO{囝uO~~ Ứj^Mr.) ("ν:YV6Npe1 ;jA,Ƿ]h$ ([|4]*Fb%$I/ƠK}wrGl S ۰i v1k?=5hc>.ԧ"Y+#˚ ?,M&JJ6Jt3S&+\ Hvvͳҁr:$0_?Ibպ qɇF)ruZzЯ?" endstream endobj 749 0 obj << /Length 494 /Filter /FlateDecode >> stream xmMo0 !Rz|UAa۪V&$E 6~=HUAgɯ~uo$ƛLD- t @ZcNt=YNk`T=Ro æeCڕ(>Պ AiZsn[6uc^0Xah\je?0bprOY[AKS|dۙoF)MZ}4W@{YmG;<9`;K (EytbabisbgEjq(po$}Idon-p!J m-O[L endstream endobj 750 0 obj << /Length 696 /Filter /FlateDecode >> stream xmTMo0Wx$ ! 8l[jWHL7IPV=M̼ su;Uٛ=w]yil;<[[j<=?׾+v`&ߴț<^*;~&Q>MS >_P{=s@dkx;`VY`s4JaQܡn.Uu9\Y6><ٴ.Z.4>Dӗ}~r:-d0VWk,8yLһʮӮђ[*mLr?q 5F8@=@)& 8Rx uD\j2HV0CzL] bctI g$`htы0\F0s jd< I6zg W qȐ+#k .bsrbmXK7ǵH7Gnb>&jؐu1VljOu$՟qWS/%1{\xB!K(hHTЖ枃Jρϯv=k2UKς_:~$/ ~E+7ˢ/ l(/} -+ZXukoԝE?ZKq endstream endobj 751 0 obj << /Length 695 /Filter /FlateDecode >> stream xmTMo0Wx$ ! 8l[jWHL7IPV=M̼ su;Uٛ=w]yil;<[[j<=?׾+v`&ߴț<^*;~&Q>MSǓ>u;q~:fc_0F)lGιmu f8Gӫ6b"!YUe.`M{My?IC4}+̝l/Bj*{pϻƲO('$ *{>J-9_eQ"V$)MP:^9 ^` br @ {@(\,RH&ti m+3ԅ ,;F$БzFFieD(0A1a8yΠFpnù[w6p@ )9r9b_ia|F-(:(nQHY^`nA|n(戥K}s\}sԑoA&vqc⠦ YK^ʛ!_my_)=^ ^{TGRw1RDž'xJzImi9j'pͽܳ/-_Z,N_: ~iyY2q,nЪ5QN Y58.] endstream endobj 752 0 obj << /Length 695 /Filter /FlateDecode >> stream xmTMo0Wx$ ! 8l[jWHL7IPV=M̼ su;Uٛ=w]yil;<[[j<=?׾+v`&ߴț<^*;~&Q>MS>u;q~:fc_0F)lGιmu f8Gӫ6b"!YUe.`M{My?IC4}+̝l/Bj*{pϻƲO('$ *{>J-9_eQ"V$)MP:^9 ^` br @ {@(\,RH&ti m+3ԅ ,;F$БzFFieD(0A1a8yΠFpnù[w6p@ )9r9b_ia|F-(:(nQHY^`nA|n(戥K}s\}sԑoA&vqc⠦ YK^ʛ!_my_)=^ ^{TGRw1RDž'xJzImi9j'pͽܳ/-_Z,N_: ~iyY2q,nЪ5QN Y58.] endstream endobj 753 0 obj << /Length 739 /Filter /FlateDecode >> stream xmUMo0WxvHUdCmU^!1H#x?gx]OTm$|͜s_Iss :L;<Sz==׾f`*_`ɫڟk3'iѴ}=M;7rfnj-eSӵOLg~8 )ok A8 $`I\3`Af<Z]! xNky"7 _㓧q H`nḱRONH=CpB:# =%888QA~!*zƜАT?!~> tw8y*sύ }nFE>7*QύR>7G];~<6OIyktg>O:yұϓN|I/|yIg>O:y҅ϓ.}2 L> stream xmUMo0WxvH UdC۪TBb B8߯{ .@=/ۙڽs{K;K.k6/k+[M'ҷ>dyӔKe'$cS`vfSfK}fƁVGGf\bu<19w|擬CTAW $rG]IyMsh$aW7y̟u? sK-`θtJ!'c83?NaO<Dg!;IX 0z)rЃ@kpBQ]^Z7! / U <ɉ#W m/%]cX! gȀhID8QN~ACT/sQQRs 穅ύ>7: F+}n4eE=zG~<6OɈy2kLd>O&y2ϓQ>OfdV>OF<dR'<>O)yJS*}𗏿tx>z{O->tՍ]*3>cC~ endstream endobj 755 0 obj << /Length 900 /Filter /FlateDecode >> stream xmUMo:W5?$R. d9M eCkmCp;;w~>|3E_?O]5߶w]Occ]=~?}Oyh9%?۹׬B|Ɯ>);vw%g43>\ 6 EJ78 1{~`W(-;]%=xe_,b+-O;q\L}UI--=BKE1p[! Mߊyu>.N5K)Wb٬8i[_uʕMzQ)V(Txޢjy!Z2P="Zd0\ÃGR\).2*Шa!U,H`+j.5Nα@VK-x%3%AYӀzΚ>kP#5m0Woþj.ZT$X/)n)#Wo(oRZ $Kp4Z-b\1ܰJ P"GXQi/8k^Zq:Zs9dB )sL-7xJ`aɽ)f$1 dъcCZC<73JgznHȰYɚTa,_-O87}KԴܗLloK+gJ.GZyVc48Wt]:P~`rZq.n1] S/Pu7Ue:?&?!d&1yHn5)yғBx#1ޞ]Go׏M?X endstream endobj 756 0 obj << /Length 900 /Filter /FlateDecode >> stream xmUMo:W5?$R. d9M eCkmCp;;w~>|3E_?O]5߶w]Occ]=~?}Oyh9%?۹׬B|Ɯ>);vw7{>oaI> ѲH8U/RǾ0ñ_x0ӅxBiE.͏S=/b_ixމbc4fi|8EXD_R4.GRQhV̪xvqڎXJfUıkM;rͭSlҏ֋jU,N2@ ",   T[<5 1"àcvG@mg K | +T|5flxZ1YP^ꠦdb}[ה_Q>kUbw88]k|'%Ǿjց{ g䈏rsqk:n87xIue.Aft0!?4ɳ4mFtӔ^z1?z .~lP}L endstream endobj 774 0 obj << /Producer (pdfTeX-1.40.22) /Author()/Title()/Subject()/Creator(LaTeX with hyperref)/Keywords() /CreationDate (D:20240501011643-04'00') /ModDate (D:20240501011643-04'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX, Version 3.141592653-2.6-1.40.22 (TeX Live 2022/dev/Debian) kpathsea version 6.3.4/dev) >> endobj 480 0 obj << /Type /ObjStm /N 73 /First 668 /Length 4745 /Filter /FlateDecode >> stream xڵ[[s7~篘2R[e;q.cx-27%50̐T$'  hƌ Ntˎ<~Th_2ᷓΪI բd dCW97sRvZ9 ^Vy<03nRRA[pr)b 9@ 0py'gTG†#%- d$m52Px]P) bH. I ŭ &' ] A̢Z֝4dmgUT'AoR큪΂R5!Qs,R&#ck/|x x"hO@B&[i (p "(ЦZ1`츭EZCJK& ~Ffp"?b lRjhy]r7UvF9*6XmƳЎxÙqڹN  K?^MP?+Cիv}9]nrvov]j=`P@LZtf˳#2m LϷ6$_*SڴaZs:Tw֪NyUf7%/[mr?/ŨR(|14+Tv{++ŃЪPU ں/UAa T)7^+cxI\ 3:>Xc&ffxL77,Όk%H777,d $jk,Mccuu0a0,msvJ ~(RR`p=$/ 2'\@3 šP%% HCԧ`8DxY1>K؍f G,AX%1RB))6ĘXUJck)aliJ K[J]fQ[Yd,G/BF)aoUVgwϰJF0Fv}Țs+ Uc+ѓͻDO+ݕi glVS)8KdaJuP Q 4-5⩊:u!PA|UPh#\S _YPF]PFVbH:]u@g\[5*Pr6 \,@N RXk׀ jA F F F ȏ@ ?A Ǚv m!Qyj!-$D ?HA) N#@ H [T*%7 %q"\c835K&p) j.?`nC=ytE4ӄ89%$hJ~b/ Sw~3 ޡLF '콹SCeې=0K8]fY9tD-  GnjXvT%`!5[*EoiVJ wNsp8AR%F U1Y%c_Д sqN6ڕ3ZեyxkxPzQW/xQNS:Oh<ӲNS:i|ӶN7:Mot7Fg~(tQJg϶sr/ QDz4~'yChMIF{{x &߆T 7 d+/3piLkMRkַ&oCkN&dkN&tkδ&lkε&5y[MWte._tbO܊Rvtipl@f(b~I] #"B=Tv.32!B' tm˹^dM%=0G4KgƦO%m[1(E{n@C33Ìr1z!b+Q>ChzEPx9k4D=h)+ #RBv%dXrD$pTz޵0*'ጼJ&[h`X#w2&dįsuͺ]!ٕZ s>#=F0Z]Gv5{d]Gv5{G:=F'GNB4l9 8rq$LIp >C._gi~)[UJvDG)^#HW&9_饦N<") ?"S?2ssC[y)sMh|өW:y-CP'P+zEJUjTkWnT{D5b{ۓj :YnO7z6x^߾l狳mgZl iH mOf,_>:xxJ?GgK<-/~Eoaottqxu*?{-j}a:_|)<]ah.*y񯯟A%8◊ˡV%pR$WJy(MV jܿ__'M?]cY_ZnVߞ/]X./xua^'iB4QMs<TNũUT$J}xyt*a9_c ?՝L/~z|ulKUlم6˸Us_׋bqYc^.".=mSu~Ȼ7?{z8*Y>jjH3ONNɓǿbR'8C0iaۿ)^.nuuy<;~{/qfbblN/1V|y6xv</Kُ#ecяN /Q_.W^,QD 7M%SF"+.$LS U~J$.$bL$ʯ/H .ORS3"[CGˣ.Nԣv|:^5Stkdю]cJo6'oV/Kd[85ʛ"\'ҥS.30M)¿3Ljd:~)C7oCCƾ:7NKMO7eK/wKף.GӲؖA~+˙ rrwgg~˹ݤHc:|@mT!M)YKSz&es܃sjTf_Μ.j|O6}}@_yx4DnV~\y3~Ób{%`}zw-AN,[zХSȖta~Brv:5WtiuMhGlYoO?ߒwW˭uMnh:?> :L3gsJ1a*~+ָ JaUJ7quv*rDFjH3F$ê#+k=9B:.IBz&)0)ۯ D[܂qK=R*A-GHIR*lCA׶@t=Y餷 UdÍ[s7?S^m=j[)cT3"+TVMhP *=Ѷ=.1FSɠ0u*^YJZ}TF7(7ڨebZaL$H-6m=:96i1% Pzpï~knrv0`4X- []d,N\G<-сDYl `E5;. QMg@/e/. endstream endobj 775 0 obj << /Type /XRef /Index [0 776] /Size 776 /W [1 3 1] /Root 773 0 R /Info 774 0 R /ID [ ] /Length 2247 /Filter /FlateDecode >> stream x%{|u{_c6l3s36aa<Β9DTY^G҃z,JO{q:Va+ Vl<ג-!s-*G|H7Kf˗LkΖ? 60\UkU&< &I%B*08:*D{N7k?jϱ$'q$4u$DFI ثj|$0تVbV]zV&5IsniDUqB+]5]x@D㴊}jug{K֤#I6N-iGRXgڰś-[nI7N=}qFVI5NB= Aҕ賹$'tz]^q }6ѥKfRDY@s?`tMAyV\[88J혯q߸m LıLgw^`ڊƹN+lV1K"Fsp2ƭjVXEj!?Ы G `Iq[/68OfCTCT3֘YW*c&DafVs&ɘz1dw2D-CԶ54fG1qZ 5,Ǐbp!(ׂ3{.Tǀ2v\Y~WπnkzoKpZnoku2I챩 zGp?[VIO9)n bmN/ @jT ܌[)$ʙ fb!ܪ@5@ "5ZAhPF,1._qUA|%Q0n'`,HJ ;6x.hr4 a/dע6h,hp[#66@[,ێ{s)AcjsOp!MCAH5`.\_nn AvT{=nw0t}NP@;B; X'mwøy0Ȯ8.IWQM@wPD;GrxE`L*pJ8o`{`4eIq'} g)*Keɵ9Ɲ(v1 f3G>RoYmqg…9Z-˰e,öи/ ݹ+`#i1زlex} d`2e1E~ M!.wu<߶ۇ|p2&L_1Wq_33g ̃ C38pYv=w;;k~`ڟ._Ypt~ z{|}/35ְ, nnAt7xo/ywTG:pwǁ8#f_c?}N@R/x[)w lT IP"XJj K,HK@AzP!|o D^5PP&JԚ 8ڨrJ EXƱ Q>w őFAciz/I2I[[i;@IPi{GH N:"$-HGNKD:s5"rA2yK蔞7hP3AK_opIr9ಘs[ I^˗#"Wز}(#"o !Mrjr-%_63Li!fd+crZؑwǁ(>I>{?>Bf1~'ivN"HfFJUx~_hbe{Uxj+xKjlbqW;bD\yXDwzs#Ҙ&mH[?9?iM!I*I# I]x߹֦ endstream endobj startxref 324333 %%EOF pcaMethods/inst/doc/pcaMethods.R0000644000175100017510000001310614614350074017622 0ustar00biocbuildbiocbuild### R code from vignette source 'pcaMethods.Rnw' ################################################### ### code chunk number 1: pcaMethods.Rnw:102-114 ################################################### library(pcaMethods) x <- c(-4,7); y <- c(-3,4) distX <- rnorm(100, sd=0.3)*3 distY <- rnorm(100, sd=0.3) + distX * 0.3 mat <- cbind(distX, distY) res <- pca(mat, nPcs=2, method="svd", center=F) loading <- loadings(res)[1,] grad <- loading[2] / loading[1] if (grad < 0) grad <- grad * -1 lx <- c(-4,7) ly <- c(grad * -4, grad * 7) ################################################### ### code chunk number 2: pcaMethods.Rnw:118-125 ################################################### par(mar=c(2, 3, 2, 2)) plot(x,y, type="n", xlab="", ylab="") abline(v=0, col="dark gray", lwd = 2); abline(h=0, col = "dark gray", lwd = 2) points(distX, distY, type = 'p', col = "blue") lines(lx,ly, lwd = 2) points(-1, -1 * grad + 0.5, pch = 19, col = "red", lwd=4) points(6, 6 * grad + 0.5, pch = 19, col = "red", lwd=4) ################################################### ### code chunk number 3: pcaMethods.Rnw:253-255 ################################################### library(lattice) library(pcaMethods) ################################################### ### code chunk number 4: pcaMethods.Rnw:258-261 ################################################### library(pcaMethods) data(metaboliteData) data(metaboliteDataComplete) ################################################### ### code chunk number 5: pcaMethods.Rnw:264-266 ################################################### md <- prep(metaboliteData, scale="none", center=TRUE) mdC <- prep(metaboliteDataComplete, scale="none", center=TRUE) ################################################### ### code chunk number 6: pcaMethods.Rnw:271-277 ################################################### resPCA <- pca(mdC, method="svd", center=FALSE, nPcs=5) resPPCA <- pca(md, method="ppca", center=FALSE, nPcs=5) resBPCA <- pca(md, method="bpca", center=FALSE, nPcs=5) resSVDI <- pca(md, method="svdImpute", center=FALSE, nPcs=5) resNipals <- pca(md, method="nipals", center=FALSE, nPcs=5) resNLPCA <- pca(md, method="nlpca", center=FALSE, nPcs=5, maxSteps=300) ################################################### ### code chunk number 7: pcaMethods.Rnw:293-296 ################################################### sDevs <- cbind(sDev(resPCA), sDev(resPPCA), sDev(resBPCA), sDev(resSVDI), sDev(resNipals), sDev(resNLPCA)) matplot(sDevs, type = 'l', xlab="Eigenvalues", ylab="Standard deviation of PC", lwd=3) legend(x="topright", legend=c("PCA", "PPCA", "BPCA", "SVDimpute","Nipals PCA","NLPCA"), lty=1:6, col=1:6, lwd=3) ################################################### ### code chunk number 8: pcaMethods.Rnw:308-311 ################################################### par(mfrow=c(1,2)) plot(loadings(resBPCA)[,1], loadings(resPCA)[,1], xlab="BPCA", ylab="classic PCA", main = "Loading 1") plot(loadings(resBPCA)[,2], loadings(resPCA)[,2], xlab="BPCA", ylab="classic PCA", main = "Loading 2") ################################################### ### code chunk number 9: pcaMethods.Rnw:335-337 ################################################### q2SVDI <- Q2(resSVDI, mdC, fold=10) q2PPCA <- Q2(resPPCA, mdC, fold=10) ################################################### ### code chunk number 10: pcaMethods.Rnw:339-349 ################################################### # PPCA does not converge / misestimate a value in very rare cases. # This is a workaround to avoid that such a case will break the # diagram displayed in the vignette. # From the 2.0 release of bioconductor on, the convergence threshold # for PPCA was lowert to 1e-5, this should make the method much more # stable. So this workaround might be obsolete now... # [nope it is not, ppca is unstable] while( sum((abs(q2PPCA)) > 1) >= 1 ) { q2PPCA <- Q2(resPPCA, mdC, fold=10) } ################################################### ### code chunk number 11: pcaMethods.Rnw:353-356 ################################################### q2 <- data.frame(Q2=c(drop(q2PPCA), drop(q2SVDI)), method=c("PPCA", "SVD-Impute")[gl(2, 5)], PC=rep(1:5, 2)) print(xyplot(Q2~PC|method, q2, ylab=expression(Q^2), type="h", lwd=4)) ################################################### ### code chunk number 12: pcaMethods.Rnw:389-390 ################################################### errEsti <- kEstimate(md, method = "ppca", evalPcs=1:5, nruncv=1, em="nrmsep") ################################################### ### code chunk number 13: pcaMethods.Rnw:396-397 ################################################### barplot(drop(errEsti$eError), xlab="Loadings", ylab="NRMSEP (Single iteration)") ################################################### ### code chunk number 14: pcaMethods.Rnw:420-421 ################################################### barplot(drop(errEsti$variableWiseError[, which(errEsti$evalPcs == errEsti$bestNPcs)]), xlab="Incomplete variable Index", ylab="NRMSEP") ################################################### ### code chunk number 15: pcaMethods.Rnw:445-446 ################################################### slplot(resPCA) ################################################### ### code chunk number 16: pcaMethods.Rnw:456-457 ################################################### plotPcs(resPPCA, pc=1:3, type="score") ################################################### ### code chunk number 17: pcaMethods.Rnw:469-475 ################################################### pc <- pca(iris) irdf <- merge(iris, scores(pc), by=0) library(ggplot2) ggplot(irdf, aes(PC1, PC2, colour=Species)) + geom_point() + stat_ellipse() pcaMethods/inst/doc/pcaMethods.Rnw0000644000175100017510000005554214614231101020166 0ustar00biocbuildbiocbuild\documentclass[a4paper]{article} %\VignetteIndexEntry{Introduction} \usepackage{hyperref} \title{The pcaMethods Package} \author{Wolfram Stacklies and Henning Redestig\\ CAS-MPG Partner Institute for Computational Biology (PICB)\\ Shanghai, P.R. China \\ and\\ Max Planck Institute for Molecular Plant Physiology\\ Potsdam, Germany\\ \url{http://bioinformatics.mpimp-golm.mpg.de/} } \date{\today} \begin{document} \setkeys{Gin}{width=1.0\textwidth} @ \maketitle \section*{Overview} The \texttt{pcaMethods} package \cite{stacklies07} provides a set of different PCA implementations, together with tools for cross validation and visualisation of the results. The methods basically allow to perform PCA on incomplete data and thus may also be used for missing value estimation. When doing PCA one assumes that the data is restricted to a subspace of lower dimensionality, e.g. correlation patterns between jointly regulated genes. PCA aims to extract these structures thereby filtering noise out. If only the most significant loadings (eigenvectors, also referred to as principal components) are used for projection this can be written as: \begin{equation} X = 1\times{}\bar{x}^T + TP^T + V \end{equation} Where the term $1\times{}\bar{x}^T$ represents the original variable averages, $X$ denotes the observations, $T={t_1, t_2,\ldots,t_k}$ the latent variables or scores, $P={p_1, p_2,\ldots,p_k}$ the transformation matrix (consisting of the most significant eigenvectors of the covariance matrix) and $V$ are the residuals. Missing values may be estimated by projecting the scores back into the original space using $\hat{X} = 1\times{}\bar{x}^T + TP^T$. Optimally, this produces an estimate of the missing data based on the underlying correlation structure, thereby ignoring noise. This will only produce reasonable results if the residuals $V$ are sufficiently small, implying that most of the important information is captured by the first $k$ components. In order to calculate the transformation matrix $P$ one needs to determine the covariance matrix between variables or alternatively calculate $P$ directly via SVD. In both cases, this can only be done on complete matrices. However, an approximation may be obtained by use of different regression methods. The PCA methods provided in this package implement algorithms to accurately estimate the PCA solution on incomplete data. Although the focus of this package is clearly to provide a collection of PCA methods we also provide a cluster based method for missing value imputation. This allows to better rate and compare the results. \section{Algorithms} All methods return a common class called \texttt{pcaRes} as a container for the results. This guarantees maximum flexibility for the user. A wrapper function called \texttt{pca()} is provided that receives the desired type of pca as a string. \subsection*{svdPca} This is a wrapper function for $R's$ standard \texttt{prcomp} function. It delivers the results as a \texttt{pcaRes} object for compatibility with the rest of the package. \subsection*{svdImpute} This implements the SVDimpute algorithm as proposed by Troyanskaya et~al \cite{troyanskaya01}. The idea behind the algorithm is to estimate the missing values as a linear combination of the $k$ most significant eigengenes\footnote{The term ``eigengenes'' denotes the loadings when PCA was applied considering variables (here the genes) as observations.}. The algorithm works iteratively until the change in the estimated solution falls below a certain threshold. Each step the eigengenes of the current estimate are calculated and used to determine a new estimate. An optimal linear combination is found by regressing an incomplete variable against the $k$ most significant eigengenes. If the value at position $j$ is missing, the $j^{th}$ value of the eigengenes is not used when determining the regression coefficients.\\ SVDimpute seems to be tolerant to relatively high amount of missing data (> 10\%). \subsection*{Probabilistic PCA (ppca)} Probabilistic PCA combines an EM approach for PCA with a probabilistic model. The EM approach is based on the assumption that the latent variables as well as the noise are normal distributed. In standard PCA data which is far from the training set but close to the principal subspace may have the same reconstruction error, see Figure \ref{fig:pcaSubspace} for explanation. <>= library(pcaMethods) x <- c(-4,7); y <- c(-3,4) distX <- rnorm(100, sd=0.3)*3 distY <- rnorm(100, sd=0.3) + distX * 0.3 mat <- cbind(distX, distY) res <- pca(mat, nPcs=2, method="svd", center=F) loading <- loadings(res)[1,] grad <- loading[2] / loading[1] if (grad < 0) grad <- grad * -1 lx <- c(-4,7) ly <- c(grad * -4, grad * 7) @ \begin{figure} \centering <>= par(mar=c(2, 3, 2, 2)) plot(x,y, type="n", xlab="", ylab="") abline(v=0, col="dark gray", lwd = 2); abline(h=0, col = "dark gray", lwd = 2) points(distX, distY, type = 'p', col = "blue") lines(lx,ly, lwd = 2) points(-1, -1 * grad + 0.5, pch = 19, col = "red", lwd=4) points(6, 6 * grad + 0.5, pch = 19, col = "red", lwd=4) @ \caption{Normal distributed data with the first loading plotted in black. The two red points have the same reconstruction error because PCA does not define a density model. Thus the only measure of how well new data fits the model is the distance from the principal subspace. Data points far from the bulk of data but still close to the principal subspace will have a low reconstruction error. \label{fig:pcaSubspace}} \end{figure} PPCA defines a likelihood function such that the likelihood for data far from the training set is much lower, even if they are close to the principal subspace. This allows to improve the estimation accuracy.\\ PPCA is tolerant to amounts of missing values between 10\% to 15\%. If more data is missing the algorithm is likely not to converge to a reasonable solution. The method was implemented after the draft ``\texttt{EM Algorithms for PCA and Sensible PCA}'' written by Sam Roweis and after the Matlab \texttt{ppca} script implemented by \emph{Jakob Verbeek}\footnote{\url{http://lear.inrialpes.fr/~verbeek/}}. Please check also the PPCA help file. \subsection*{Bayesian PCA (bpca)} Similar to probabilistic PCA, Bayesian PCA uses an EM approach together with a Bayesian model to calculate the likelihood for a reconstructed value.\\ The algorithm seems to be tolerant to relatively high amounts of missing data (> 10\%). Scores and loadings obtained with Bayesian PCA slightly differ from those obtained with conventional PCA. This is because BPCA was developed especially for missing value estimation and is based on a variational Bayesian framework (VBF), with automatic relevance determination (ARD). In BPCA, ARD leads to a different scaling of the scores, loadings and eigenvalues when compared to standard PCA or PPCA. The algorithm does not force orthogonality between loadings. However, the authors of the BPCA paper found that including an orthogonality criterion made the predictions worse. They also state that the difference between ``real'' and predicted Eigenvalues becomes larger when the number of observation is smaller, because it reflects the lack of information to accurately determine true loadings from the limited and noisy data. As a result, weights of factors to predict missing values are not the same as with conventional PCA, but the missing value estimation is improved. BPCA was proposed by Oba et~al \cite{oba03}. The method available in this package is a port of the \texttt{bpca} Matlab script also provided by the authors\footnote{ \url{http://hawaii.aist-nara.ac.jp/\%7Eshige-o/tools/}}. \subsection*{Inverse non-linear PCA (NLPCA)} NLPCA \cite{scholz05} is especially suitable for data from experiments where the studied response is non-linear. Examples of such experiments are ubiquitous in biology -- enzyme kinetics are inherently non-linear as are gene expression responses influenced by the cell cycle or diurnal oscillations. NLPCA is based on training an auto-associative neural network composed of a component layer which serves as the ``bottle-neck'', a hidden non-linear layer and an output layer corresponding to the reconstructed data. The loadings can be seen as hidden in the network. Missing values in the training data are simply ignored when calculating the error during back-propagation. Thus NLPCA can be used to impute missing values in the same way as for conventional PCA. The only difference is that the loadings $P$ are now represented by a neural network.\\ A shortcoming of the current implementation is that there is no reasonable stop criterion. The quality of the estimated solution depends on the number of iterations. This should in most cases be somewhat between 500 and 1500. We recommend to use \texttt{kEstimate} or \texttt{kEstimateFast} to determine this parameter. \subsection*{Nipals PCA} Nipals (Nonlinear Estimation by Iterative Partial Least Squares) \cite{wold66} is an algorithm at the root of PLS regression which can execute PCA with missing values by simply leaving those out from the appropriate inner products. It is tolerant to small amounts (generally not more than 5\%) of missing data. \subsection{Local least squares (LLS) imputation} The package provides an algorithm called \texttt{llsImpute} for missing value estimation based on a linear combination of the $k$ nearest neighbours of an incomplete variable (in Microarray experiments normally a gene). The distance between variables is defined as the absolute value of the Pearson, Spearman or Kendall correlation coefficient. The optimal linear combination is found by solving a local least squares problem as described in \cite{kim05}. In tests performed in the cited paper the llsImpute algorithm is able to outperform knnImpute\cite{troyanskaya01} and competes well with BPCA. In the current implementation two slightly different ways for missing value estimation are provided. The first one is to restrict the neighbour searching to the subset of complete variables. This is preferable when the number of incomplete variables is relatively small. The second way is to consider all variables as candidates. Here, missing values are initially replaced by the columns wise mean. The method then iterates, using the current estimate as input for the LLS regression until the change between new and old estimate falls below a certain threshold (0.001). \section{Getting started} \paragraph{Installing the package.} To install the package first download the appropriate file for your platform from the Bioconductor website (\url{http://www.bioconductor.org/}). For Windows, start \texttt{R} and select the \texttt{Packages} menu, then \texttt{Install package from local zip file}. Find and highlight the location of the zip file and click on \texttt{open}. For Linux/Unix, use the usual command \texttt{R CMD INSTALL} or set the option \texttt{CRAN} to your nearest mirror site and use the command \texttt{install.packages} from within an \texttt{R} session. \paragraph{Loading the package:} To load the \texttt{pcaMethods} package in your \texttt{R} session, type \texttt{library(pcaMethods)}. \paragraph{Help files:} Detailed information on \texttt{pcaMethods} package functions can be obtained from the help files. For example, to get a description of \texttt{bpca} type \texttt{help("bpca")}. \paragraph{Sample data:} Two sample data sets are coming with the package. \texttt{metaboliteDataComplete} contains a complete subset from a larger metabolite data set. \texttt{metaboliteData} is the same data set but with 10 \% values removed from an equal distribution. \section{Some examples} <>= library(lattice) library(pcaMethods) @ To load the package and the two sample data sets type: <>= library(pcaMethods) data(metaboliteData) data(metaboliteDataComplete) @ Now centre the data <<>>= md <- prep(metaboliteData, scale="none", center=TRUE) mdC <- prep(metaboliteDataComplete, scale="none", center=TRUE) @ Run SVD pca, PPCA, BPCA, SVDimpute and nipalsPCA on the data, using the \texttt{pca()} wrapper function. The result is always a \texttt{pcaRes} object. <>= resPCA <- pca(mdC, method="svd", center=FALSE, nPcs=5) resPPCA <- pca(md, method="ppca", center=FALSE, nPcs=5) resBPCA <- pca(md, method="bpca", center=FALSE, nPcs=5) resSVDI <- pca(md, method="svdImpute", center=FALSE, nPcs=5) resNipals <- pca(md, method="nipals", center=FALSE, nPcs=5) resNLPCA <- pca(md, method="nlpca", center=FALSE, nPcs=5, maxSteps=300) @ Figure \ref{fig:eigenvalues} shows a plot of the eigenvalue structure (\texttt{sDev(pcaRes)}). If most of the variance is captured with few loadings PCA is likely to produce good missing value estimation results. For the sample data all methods show similar eigenvalues. One can also see that most of the variance is already captured by the first loading, thus estimation is likely to work fine on this data. For BPCA, the eigenvalues are scaled differently for reasons discussed above, see Figure \ref{fig:loadingBPCA}. The order of the loadings remains the same. \begin{figure} \centering <>= sDevs <- cbind(sDev(resPCA), sDev(resPPCA), sDev(resBPCA), sDev(resSVDI), sDev(resNipals), sDev(resNLPCA)) matplot(sDevs, type = 'l', xlab="Eigenvalues", ylab="Standard deviation of PC", lwd=3) legend(x="topright", legend=c("PCA", "PPCA", "BPCA", "SVDimpute","Nipals PCA","NLPCA"), lty=1:6, col=1:6, lwd=3) @ \caption{Eigenvalue structure as obtained with different methods\label{fig:eigenvalues}} \end{figure} To get an impression of the correctness of the estimation it is a good idea to plot the scores / loadings obtained with classical PCA and one of the probabilistic methods against each other. This of course requires a complete data set from which data is randomly removed. Figure \ref{fig:loadingBPCA} shows this for BPCA on the sample data. \begin{figure} \centering <>= par(mfrow=c(1,2)) plot(loadings(resBPCA)[,1], loadings(resPCA)[,1], xlab="BPCA", ylab="classic PCA", main = "Loading 1") plot(loadings(resBPCA)[,2], loadings(resPCA)[,2], xlab="BPCA", ylab="classic PCA", main = "Loading 2") @ \caption{Loading 1 and 2 calculated with BPCA plotted against those calculated with standard PCA. \label{fig:loadingBPCA}} \end{figure} \section{Cross validation} \texttt{Q2} is the goodness measure used for internal cross validation. This allows to estimate the level of structure in a data set and to optimise the choice of number of loadings. Cross validation is performed by removing random elements of the data matrix, then estimating these using the PCA algorithm of choice and then calculating $Q^2$ accordingly. At the moment, cross-validation can only be performed with algorithms that allow missing values (i.e. not SVD). Missing value independent cross-validation is scheduled for implementation in later versions. $Q^2$ is defined as following for the mean centered data (and possibly scaled) matrix $X$. $$\mathrm{SSX}=\sum (x_{ij})^2$$ $$\mathrm{PRESS}=\sum (x_{ij} - \hat{x}_{ij})^2$$ $$Q^2=1 - \mathrm{PRESS}/\mathrm{SSX}$$ The maximum value for $Q^2$ is thus 1 which means that all variance in $X$ is represented in the predictions; $X=\hat{X}$. <>= q2SVDI <- Q2(resSVDI, mdC, fold=10) q2PPCA <- Q2(resPPCA, mdC, fold=10) @ <>= # PPCA does not converge / misestimate a value in very rare cases. # This is a workaround to avoid that such a case will break the # diagram displayed in the vignette. # From the 2.0 release of bioconductor on, the convergence threshold # for PPCA was lowert to 1e-5, this should make the method much more # stable. So this workaround might be obsolete now... # [nope it is not, ppca is unstable] while( sum((abs(q2PPCA)) > 1) >= 1 ) { q2PPCA <- Q2(resPPCA, mdC, fold=10) } @ \begin{figure}[!ht] \centering <>= q2 <- data.frame(Q2=c(drop(q2PPCA), drop(q2SVDI)), method=c("PPCA", "SVD-Impute")[gl(2, 5)], PC=rep(1:5, 2)) print(xyplot(Q2~PC|method, q2, ylab=expression(Q^2), type="h", lwd=4)) @ \caption{Boxplot of the \texttt{Q2} results for BPCA, Nipals PCA, SVDimpute and PPCA. PPCA and SVDimpute both deliver better results than BPCA and Nipals in this example.\label{fig:Q2}} \end{figure} The second method called \texttt{kEstimate} uses cross validation to estimate the optimal number of loadings for missing value estimation. The \texttt{NRMSEP} (normalised root mean square error of prediction) \cite{feten05} or Q2 can be used to define the average error of prediction. The NRMSEP normalises the square difference between real and estimated values for a certain variable by the variance within this variable. The idea behind this normalisation is that the error of prediction will automatically be higher if the variance is higher. The \texttt{NRMSEP} for mean imputation is $\sqrt{\frac{nObs}{nObs - 1}}$ when cross validation is used, where $nObs$ is the number of observations. The exact definition is: \begin{equation} NRMSEP_k = \sqrt{\frac{1}{g} \sum_{j \in G} \frac{\sum_{i \in O_j} (x_{ij} - \hat{x}_{ijk})^2}{o_j s_{x_j}^2}} \end{equation} where $s^2_{x_j} = \sum_{i=1}^n (x_{ij} - \overline{x}_j)^2 / (n - 1)$, this is the variance within a certain variable. Further, $G$ denotes the set of incomplete variables, $g$ is the number of incomplete varialbes. $O_j$ is the set of missing observations in variable $j$ and $o_j$ is the number of missing observations in variable $j$. $\hat{x}_{ijk}$ stands for the estimate of value $i$ of variable $j$ using $k$ loadings. See Figure \ref{fig:kEstimate} for an example. The NRMSEP should be the error measure of choice. But if the number of observations is small, the variance within a certain variable may become and unstable criterion. If so or if variance scaling was applied we recommend to use Q2 instead. <>= errEsti <- kEstimate(md, method = "ppca", evalPcs=1:5, nruncv=1, em="nrmsep") @ \begin{figure}[!ht] \centering \begin{minipage}[c]{0.6\textwidth} \centering <>= barplot(drop(errEsti$eError), xlab="Loadings", ylab="NRMSEP (Single iteration)") @ \end{minipage} \begin{minipage}[c]{0.3\textwidth} \caption{Boxplot showing the \texttt{NRMSEP} versus the number of loadings. In this example only 1 iteration of the whole cross validation were performed. It is normally advisable to do more than just one iteration. \label{fig:kEstimate}} \end{minipage} \end{figure} \texttt{kEstimate} also provides information about the estimation error for individual variables. The $Q^2$ distance or the NRMSEP are calculated separately for each variable. See the manpage for \texttt{kEstimate} and \texttt{kEstimateFast} for details. Plotting the variable - wise results gives information about for which variables missing value estimation makes sense, and for which no imputation or mean imputation is preferable, see Figure \ref{fig:variableWiseError}. If you are not interested in variable - wise information we recommend to use the faster \texttt{kEstimateFast} instead. \begin{figure}[!ht] \centering \begin{minipage}[c]{0.6\textwidth} \centering <>= barplot(drop(errEsti$variableWiseError[, which(errEsti$evalPcs == errEsti$bestNPcs)]), xlab="Incomplete variable Index", ylab="NRMSEP") @ \end{minipage} \begin{minipage}[c]{0.3\textwidth} \caption{Boxplot showing the \texttt{NRMSEP} for all incomplete variables in the data set. For the first 7 variables missing value imputation does not seem to make too much sense. \label{fig:variableWiseError}} \end{minipage} \end{figure} \newpage \section{Visualisation of the results} \subsection{Quick scores and loadings plot} Some methods for display of scores and loadings are also provided. The function \texttt{slplot()} aims to be a simple way to quickly visualise scores and loadings in an intuitive way, see Figure \ref{fig:slplot}. Barplots are provided when plotting only one PC and colours can be specified differently for the scores and loadings plots. For a more specific scatter plot it is however recommended to access scores and loadings slots and define own plot functions. \begin{figure}[!h] \centering <>= slplot(resPCA) @ \caption{\texttt{slplot} for scores and loadings obtained with classical SVD based PCA. \label{fig:slplot}} \end{figure} \noindent Another method called \texttt{plotPcs()} allows to visualise many PCs plotted against each other, see Figure \ref{fig:plotPcs}. \begin{figure}[!ht] \centering <>= plotPcs(resPPCA, pc=1:3, type="score") @ \caption{A plot of score 1:3 for PPCA created with \texttt{plotPcs()} \label{fig:plotPcs}} \end{figure} \subsection{Using ggplot2} For using ggplot, the scores and loadings should best be added to a data frame that add other relevant descriptive factors. For example, after doing PCA on the Iris dataset, we may add the scores back to the original data frame and use ggplot to visualise, see Figure \ref{fig:ggplot}. \begin{figure}[!ht] \centering <>= pc <- pca(iris) irdf <- merge(iris, scores(pc), by=0) library(ggplot2) ggplot(irdf, aes(PC1, PC2, colour=Species)) + geom_point() + stat_ellipse() @ \caption{Score plot using ggplot2} \label{fig:ggplot} \end{figure} \cleardoublepage \begin{thebibliography}{2006} \bibitem{stacklies07} Stacklies W., Redestig H., Scholz M., and Walther D., and Selbig J. {\sl pcaMethods -- a Bioconductor package providing PCA methods for incomplete data} Bioinformatics. 2007, 23, 1164-1167. {\sl Non-linear PCA: a missing data approach.} Bioinformatics. 2005, 21, 3887-3895. \bibitem{scholz05} Scholz, M. , Kaplan, F., Guy, C.L., Kopka, J. and Selbig, J. {\sl Non-linear pca: a missing data approach.} Bioinformatics. 2005, 21, 3887-3895. \bibitem{troyanskaya01} Troyanskaya O. and Cantor M. and Sherlock G. and Brown P. and Hastie T. and Tibshirani R. and Botstein D. and Altman RB. {\sl Missing value estimation methods for DNA microarrays.} Bioinformatics. 2001 Jun;17(6):520-525. \bibitem{feten05} Feten G. and Almoy T. and Aastveit A.H. {\sl Prediction of Missing Values in Microarray and Use of Mixed Models to Evaluate the Predictors.}, Stat. Appl. Genet. Mol. Biol. 2005;4(1):Article 10 \bibitem{oba03} Oba S. and Sato MA. and Takemasa I. and Monden M. and Matsubara K. and Ishii S. {\sl A Bayesian missing value estimation method for gene expression profile data.} Bioinformatics. 2003 Nov 1;19(16):2088-96. \bibitem{wold66} Wold H. {Estimation of principal components and related models by iterative least squares.} In Multivariate Analysis (Ed. P.R. Krishnaiah), Academic Press, NY, 391-420. \bibitem{kim05} Kim H. and Golub G.H. and Park H. {\sl Missing value estimation for DNA microarray gene expression data: local least squares imputation} Bioinformatics. 2005 21(2) :187-198 \end{thebibliography} \end{document} pcaMethods/man/0000755000175100017510000000000014614231101014425 5ustar00biocbuildbiocbuildpcaMethods/man/asExprSet.Rd0000644000175100017510000000174114614231101016635 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-ExpressionSet.R \name{asExprSet} \alias{asExprSet} \title{Convert pcaRes object to an expression set} \usage{ asExprSet(object, exprSet) } \arguments{ \item{object}{\code{pcaRes} -- The object containing the completed data.} \item{exprSet}{\code{ExpressionSet} -- The object passed on to \code{pca} for missing value estimation.} } \value{ An object without missing values of class \code{ExpressionSet}. } \description{ This function can be used to conveniently replace the expression matrix in an \code{ExpressionSet} with the completed data from a \code{pcaRes} object. } \details{ This is not a standard \code{as} function as \code{pcaRes} object alone not can be converted to an \code{ExpressionSet} (the \code{pcaRes} object does not hold any \code{phenoData} for example). } \author{ Wolfram Stacklies \cr CAS-MPG Partner Institute for Computational Biology, Shanghai, China } \keyword{multivariate} pcaMethods/man/biplot-methods.Rd0000644000175100017510000000356614614231101017660 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{biplot-methods} \alias{biplot-methods} \alias{biplot.pcaRes} \alias{biplot,pcaRes-method} \title{Plot a overlaid scores and loadings plot} \usage{ \method{biplot}{pcaRes}(x, choices = 1:2, scale = 1, pc.biplot = FALSE, ...) \S4method{biplot}{pcaRes}(x, choices = 1:2, scale = 1, pc.biplot = FALSE, ...) } \arguments{ \item{x}{a pcaRes object} \item{choices}{which two pcs to plot} \item{scale}{The variables are scaled by \eqn{\lambda^{scale}}{lambda^scale} and the observations are scaled by \eqn{\lambda^{scale}}{lambda ^ (1-scale)} where \code{lambda} are the singular values as computed by \code{princomp}. Normally \eqn{0\le{}scale\le{}1}{0 <= scale <= 1}, and a warning will be issued if the specified 'scale' is outside this range.} \item{pc.biplot}{If true, use what Gabriel (1971) refers to as a "principal component biplot", with \eqn{\lambda=1}{lambda = 1} and observations scaled up by sqrt(n) and variables scaled down by sqrt(n). Then the inner products between variables approximate covariances and distances between observations approximate Mahalanobis distance.} \item{...}{optional arguments to be passed to \code{biplot.default}.} } \value{ a plot is produced on the current graphics device. } \description{ Visualize two-components simultaneously } \details{ This is a method for the generic function 'biplot'. There is considerable confusion over the precise definitions: those of the original paper, Gabriel (1971), are followed here. Gabriel and Odoroff (1990) use the same definitions, but their plots actually correspond to \code{pc.biplot = TRUE}. } \examples{ data(iris) pcIr <- pca(iris[,1:4]) biplot(pcIr) } \seealso{ \code{prcomp}, \code{pca}, \code{princomp} } \author{ Kevin Wright, Adapted from \code{biplot.prcomp} } \keyword{multivariate} pcaMethods/man/BPCA_dostep.Rd0000644000175100017510000000132414614231101016777 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/BPCA_dostep.R \name{BPCA_dostep} \alias{BPCA_dostep} \title{Do BPCA estimation step} \usage{ BPCA_dostep(M, y) } \arguments{ \item{M}{Data structure containing all needed information. See the source documentation of BPCA_initmodel for details} \item{y}{Numeric original data matrix} } \value{ Updated version of the data structure } \description{ The function contains the actual implementation of the BPCA component estimation. It performs one step of the BPCA EM algorithm. It is called 'maxStep' times from within the main loop in BPCAestimate. } \details{ This function is NOT intended to be run standalone. } \author{ Wolfram Stacklies } pcaMethods/man/BPCA_initmodel.Rd0000644000175100017510000000267614614231101017500 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/BPCA_initmodel.R \name{BPCA_initmodel} \alias{BPCA_initmodel} \title{Initialize BPCA model} \usage{ BPCA_initmodel(y, components) } \arguments{ \item{y}{numeric matrix containing missing values. Missing values are denoted as 'NA'} \item{components}{Number of components used for estimation} } \value{ List containing \item{rows}{Row number of input matrix} \item{cols}{Column number of input matrix} \item{comps}{Number of components to use} \item{yest}{(working variable) current estimate of complete data} \item{row_miss}{(Array) Indizes of rows containing missing values} \item{row_nomiss}{(Array) Indices of complete rows (such with no missing values)} \item{nans}{Matrix of same size as input data. TRUE if \code{input == NA}, false otherwise} \item{mean}{Column wise data mean} \item{PA}{ (d x k) Estimated principal axes (eigenvectors, loadings) The matrix ROWS are the vectors} \item{tau}{Estimated precision of the residual error} \item{scores}{ Estimated scores} Further elements are: galpha0, balpha0, alpha, gmu0, btau0, gtau0, SigW. These are working variables or constants. } \description{ Model initialization for Bayesian PCA. This function is NOT inteded to be run separately! } \details{ The function calculates the initial Eigenvectors by use of SVD from the complete rows. The data structure M is created and initial values are assigned. } \author{ Wolfram Stacklies } pcaMethods/man/bpca.Rd0000644000175100017510000001332014614231101015620 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/bpca.R \name{bpca} \alias{bpca} \title{Bayesian PCA missing value estimation} \usage{ bpca(Matrix, nPcs = 2, maxSteps = 100, verbose = interactive(), threshold = 1e-04, ...) } \arguments{ \item{Matrix}{\code{matrix} -- Pre-processed matrix (centered, scaled) with variables in columns and observations in rows. The data may contain missing values, denoted as \code{NA}.} \item{nPcs}{\code{numeric} -- Number of components used for re-estimation. Choosing few components may decrease the estimation precision.} \item{maxSteps}{\code{numeric} -- Maximum number of estimation steps.} \item{verbose}{\code{boolean} -- BPCA prints the number of steps and the increase in precision if set to TRUE. Default is interactive().} \item{threshold}{convergence threshold} \item{...}{Reserved for future use. Currently no further parameters are used} } \value{ Standard PCA result object used by all PCA-based methods of this package. Contains scores, loadings, data mean and more. See \code{\link{pcaRes}} for details. } \description{ Implements a Bayesian PCA missing value estimator. The script is a port of the Matlab version provided by Shigeyuki OBA. See also \url{http://ishiilab.jp/member/oba/tools/BPCAFill.html}. BPCA combines an EM approach for PCA with a Bayesian model. In standard PCA data far from the training set but close to the principal subspace may have the same reconstruction error. BPCA defines a likelihood function such that the likelihood for data far from the training set is much lower, even if they are close to the principal subspace. } \details{ Scores and loadings obtained with Bayesian PCA slightly differ from those obtained with conventional PCA. This is because BPCA was developed especially for missing value estimation. The algorithm does not force orthogonality between factor loadings, as a result factor loadings are not necessarily orthogonal. However, the BPCA authors found that including an orthogonality criterion made the predictions worse. The authors also state that the difference between real and predicted Eigenvalues becomes larger when the number of observation is smaller, because it reflects the lack of information to accurately determine true factor loadings from the limited and noisy data. As a result, weights of factors to predict missing values are not the same as with conventional PCA, but the missing value estimation is improved. BPCA works iteratively, the complexity is growing with \eqn{O(n^3)}{O(n^3)} because several matrix inversions are required. The size of the matrices to invert depends on the number of components used for re-estimation. Finding the optimal number of components for estimation is not a trivial task; the best choice depends on the internal structure of the data. A method called \code{kEstimate} is provided to estimate the optimal number of components via cross validation. In general few components are sufficient for reasonable estimation accuracy. See also the package documentation for further discussion about on what data PCA-based missing value estimation makes sense. It is not recommended to use this function directely but rather to use the pca() wrapper function. There is a difference with respect the interpretation of rows (observations) and columns (variables) compared to matlab implementation. For estimation of missing values for microarray data, the suggestion in the original bpca is to intepret genes as observations and the samples as variables. In pcaMethods however, genes are interpreted as variables and samples as observations which arguably also is the more natural interpretation. For bpca behavior like in the matlab implementation, simply transpose your input matrix. Details about the probabilistic model underlying BPCA are found in Oba et. al 2003. The algorithm uses an expectation maximation approach together with a Bayesian model to approximate the principal axes (eigenvectors of the covariance matrix in PCA). The estimation is done iteratively, the algorithm terminates if either the maximum number of iterations was reached or if the estimated increase in precision falls below \eqn{1e^{-4}}{1e^-4}. \bold{Complexity:} The relatively high complexity of the method is a result of several matrix inversions required in each step. Considering the case that the maximum number of iteration steps is needed, the approximate complexity is given by the term \deqn{maxSteps \cdot row_{miss} \cdot O(n^3)}{maxSteps * row_miss * O(n^3)} Where \eqn{row_{miss}}{row_miss} is the number of rows containing missing values and \eqn{O(n^3)}{O(n^3)} is the complexity for inverting a matrix of size \eqn{components}{components}. Components is the number of components used for re-estimation. } \note{ Requires \code{MASS}. } \examples{ ## Load a sample metabolite dataset with 5\\\% missig values (metaboliteData)e data(metaboliteData) ## Perform Bayesian PCA with 2 components pc <- pca(t(metaboliteData), method="bpca", nPcs=2) ## Get the estimated principal axes (loadings) loadings <- loadings(pc) ## Get the estimated scores scores <- scores(pc) ## Get the estimated complete observations cObs <- completeObs(pc) ## Now make a scores and loadings plot slplot(pc) \dontshow{stopifnot(sum((fitted(pc) - t(metaboliteData))^2, na.rm=TRUE) < 200)} } \references{ Shigeyuki Oba, Masa-aki Sato, Ichiro Takemasa, Morito Monden, Ken-ichi Matsubara and Shin Ishii. A Bayesian missing value estimation method for gene expression profile data. \emph{Bioinformatics, 19(16):2088-2096, Nov 2003}. } \seealso{ \code{\link{ppca}}, \code{\link{svdImpute}}, \code{\link{prcomp}}, \code{\link{nipalsPca}}, \code{\link{pca}}, \code{\link{pcaRes}}. \code{\link{kEstimate}}. } \author{ Wolfram Stacklies } \keyword{multivariate} pcaMethods/man/center-pcaRes-method.Rd0000644000175100017510000000070214614231101020664 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{center,pcaRes-method} \alias{center,pcaRes-method} \alias{center} \title{Get the centers of the original variables} \usage{ center(object, ...) } \arguments{ \item{object}{pcaRes object} \item{...}{Not used} } \value{ Vector with the centers } \description{ Get the centers of the original variables } \author{ Henning Redestig } pcaMethods/man/centered-pcaRes-method.Rd0000644000175100017510000000070514614231101021200 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{centered,pcaRes-method} \alias{centered,pcaRes-method} \alias{centered} \title{Check centering was part of the model} \usage{ centered(object, ...) } \arguments{ \item{object}{pcaRes object} \item{...}{Not used} } \value{ TRUE if model was centered } \description{ Check centering was part of the model } \author{ Henning Redestig } pcaMethods/man/checkData.Rd0000644000175100017510000000242514614231101016566 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/checkData.R \name{checkData} \alias{checkData} \title{Do some basic checks on a given data matrix} \usage{ checkData(data, verbose = FALSE) } \arguments{ \item{data}{\code{matrix} -- Data to check.} \item{verbose}{\code{boolean} -- If TRUE, the function prints messages whenever an error in the data set is found.} } \value{ \item{isValid}{\code{boolean} -- TRUE if no errors were found, FALSE otherwise. isValid contains a set of attributes, these are: \itemize{ \item isNumeric - TRUE if data is numeric, false otherwise \item isInfinite - TRUE if data contains 'Inf' values, false otherwise \item isNaN - TRUE if data contains 'NaN' values, false otherwise \item isMatrix - TRUE if the data is in matrix format, FALSE otherwise \item naRows - TRUE if data contains rows in which all elements are 'NA', FALSE otherwise \item naCols - TRUE if data contains columns in which all elements are 'NA', FALSE otherwise }} } \description{ Check a given data matrix for consistency with the format required for further analysis. The data must be a numeric matrix and not contain: \itemize{ \item Inf values \item NaN values \item Rows or columns that consist of NA only } } \author{ Wolfram Stacklies } \keyword{multivariate} pcaMethods/man/completeObs-nniRes-method.Rd0000644000175100017510000000111514614231101021700 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{completeObs,nniRes-method} \alias{completeObs,nniRes-method} \alias{completeObs} \alias{completeObs,pcaRes-method} \title{Get the original data with missing values replaced with predicted values.} \usage{ completeObs(object, ...) } \arguments{ \item{object}{object to fetch complete data from} \item{...}{Not used} } \value{ Completed data (matrix) } \description{ Get the original data with missing values replaced with predicted values. } \author{ Henning Redestig } pcaMethods/man/cvseg.Rd0000644000175100017510000000170014614231101016021 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xval.R \name{cvseg} \alias{cvseg} \title{Get CV segments} \usage{ cvseg(x, fold = 7, seed = NULL) } \arguments{ \item{x}{a factor, character or numeric vector that describes class membership of a set of items, or, a numeric vector indicating unique indices of items, or, a numeric of length 1 that describes the number of items to segment (without any classes)} \item{fold}{the desired number of segments} \item{seed}{randomization seed for reproducibility} } \value{ a list where each element is a set of indices that defines the CV segment. } \description{ Get cross-validation segments that have (as far as possible) the same ratio of all classes (if classes are present) } \examples{ seg <- cvseg(iris$Species, 10) sapply(seg, function(s) table(iris$Species[s])) cvseg(20, 10) } \seealso{ the \code{cvsegments} function in the \code{pls} package } \author{ Henning Redestig } pcaMethods/man/cvstat-pcaRes-method.Rd0000644000175100017510000000071714614231101020716 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{cvstat,pcaRes-method} \alias{cvstat,pcaRes-method} \alias{cvstat} \title{Get cross-validation statistics (e.g. \eqn{Q^2}).} \usage{ cvstat(object, ...) } \arguments{ \item{object}{pcaRes object} \item{...}{not used} } \value{ vector CV statistics } \description{ Get cross-validation statistics (e.g. \eqn{Q^2}). } \author{ Henning Redestig } pcaMethods/man/deletediagonals.Rd0000644000175100017510000000134414614231101020042 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xval.R \name{deletediagonals} \alias{deletediagonals} \title{Delete diagonals} \usage{ deletediagonals(x, diagonals = 1) } \arguments{ \item{x}{The matrix} \item{diagonals}{The diagonal to be replaced, i.e. the first, second and so on when looking at the fat version of the matrix (transposed or not) counting from the bottom. Can be a vector to delete more than one diagonal.} } \value{ The original matrix with some values missing } \description{ Replace a diagonal of elements of a matrix with NA } \details{ Used for creating artifical missing values in matrices without causing any full row or column to be completely missing } \author{ Henning Redestig } pcaMethods/man/derrorHierarchic.Rd0000644000175100017510000000061414614231101020174 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/derrorHierarchic.R \name{derrorHierarchic} \alias{derrorHierarchic} \title{Later} \usage{ derrorHierarchic(nlnet, trainIn, trainOut) } \arguments{ \item{nlnet}{the nlnet} \item{trainIn}{training data} \item{trainOut}{fitted data} } \value{ derror } \description{ Later } \author{ Henning Redestig, Matthias Scholz } pcaMethods/man/dim.pcaRes.Rd0000644000175100017510000000054514614231101016705 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \name{dim.pcaRes} \alias{dim.pcaRes} \title{Dimensions of a PCA model} \usage{ \method{dim}{pcaRes}(x) } \arguments{ \item{x}{a pcaRes object} } \value{ Get the dimensions of this PCA model } \description{ Dimensions of a PCA model } \author{ Henning Redestig } pcaMethods/man/DModX-pcaRes-method.Rd0000644000175100017510000000344414614231101020365 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{DModX,pcaRes-method} \alias{DModX,pcaRes-method} \alias{DModX} \title{DModX} \usage{ DModX(object, dat, newdata=FALSE, type=c("normalized","absolute"), ...) } \arguments{ \item{object}{a pcaRes object} \item{dat}{the original data, taken from \code{completeObs} if left missing.} \item{newdata}{logical indicating if this data was part of the training data or not. If it was, it is adjusted by a near one factor \eqn{v=(N/ (N-A-A0))^-1}} \item{type}{if absolute or normalized values should be given. Normalized values are adjusted to the the total RSD of the model.} \item{...}{Not used} } \value{ A vector with distances from observations to the PCA model } \description{ Distance to the model of X-space. } \details{ Measures how well described the observations are, i.e. how well they fit in the mode. High DModX indicate a poor fit. Defined as: \eqn{\frac{\sqrt{\frac{SSE_i}{K-A}}}{\sqrt{\frac{SSE}{(N-A-A_0)(K-A)}}}} For observation \eqn{i}, in a model with \eqn{A} components, \eqn{K} variables and \eqn{N} obserations. SSE is the squared sum of the residuals. \eqn{A_0} is 1 if model was centered and 0 otherwise. DModX is claimed to be approximately F-distributed and can therefore be used to check if an observation is significantly far away from the PCA model assuming normally distributed data. Pass original data as an argument if the model was calculated with \code{completeObs=FALSE}. } \examples{ data(iris) pcIr <- pca(iris[,1:4]) with(iris, plot(DModX(pcIr)~Species)) } \references{ Introduction to Multi- and Megavariate Data Analysis using Projection Methods (PCA and PLS), L. Eriksson, E. Johansson, N. Kettaneh-Wold and S. Wold, Umetrics 1999, p. 468 } \author{ Henning Redestig } pcaMethods/man/errorHierarchic.Rd0000644000175100017510000000060714614231101020032 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/errorHierarchic.R \name{errorHierarchic} \alias{errorHierarchic} \title{Later} \usage{ errorHierarchic(nlnet, trainIn, trainOut) } \arguments{ \item{nlnet}{The nlnet} \item{trainIn}{training data} \item{trainOut}{fitted data} } \value{ error } \description{ Later } \author{ Henning Redestig, Matthias Scholz } pcaMethods/man/fitted-methods.Rd0000644000175100017510000000324214614231101017635 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{fitted-methods} \alias{fitted-methods} \alias{fitted.pcaRes} \alias{fitted,pcaRes-method} \title{Extract fitted values from PCA.} \usage{ \method{fitted}{pcaRes}(object, data = NULL, nPcs = nP(object), pre = TRUE, post = TRUE, ...) \S4method{fitted}{pcaRes}(object, data = NULL, nPcs = nP(object), pre = TRUE, post = TRUE, ...) } \arguments{ \item{object}{the \code{pcaRes} object of interest.} \item{data}{For standard PCA methods this can safely be left null to get scores x loadings but if set, then the scores are obtained by projecting provided data onto the loadings. If data contains missing values the result will be all NA. Non-linear PCA is an exception, here if data is NULL then data is set to the completeObs and propaged through the network.} \item{nPcs}{The number of PC's to consider} \item{pre}{pre-process \code{data} based on the pre-processing chosen for the PCA model} \item{post}{unpre-process the final data (add the center back etc to get the final estimate)} \item{...}{Not used} } \value{ A matrix representing the fitted data } \description{ Fitted values of a PCA model } \details{ This function extracts the fitted values from a pcaResobject. For PCA methods like SVD, Nipals, PPCA etc this is basically just the scores multipled by the loadings and adjusted for pre-processing. for non-linear PCA the original data is propagated through the network to obtain the approximated data. } \examples{ pc <- pca(iris[,1:4], nPcs=4, center=TRUE, scale="uv") sum( (fitted(pc) - iris[,1:4])^2 ) } \author{ Henning Redestig } \keyword{multivariate} pcaMethods/man/forkNlpcaNet.Rd0000644000175100017510000000054414614231101017305 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/forkNlpcaNet.R \name{forkNlpcaNet} \alias{forkNlpcaNet} \title{Complete copy of nlpca net object} \usage{ forkNlpcaNet(nlnet) } \arguments{ \item{nlnet}{a nlnet} } \value{ A copy of the input nlnet } \description{ Complete copy of nlpca net object } \author{ Henning Redestig } pcaMethods/man/getHierarchicIdx.Rd0000644000175100017510000000052514614231101020124 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nlpca.R \name{getHierarchicIdx} \alias{getHierarchicIdx} \title{Index in hiearchy} \usage{ getHierarchicIdx(hierarchicNum) } \arguments{ \item{hierarchicNum}{A number} } \value{ ... } \description{ Index in hiearchy } \author{ Henning Redestig, Matthias Scholz } pcaMethods/man/helix.Rd0000644000175100017510000000110214614231101016017 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/pcaMethods-package.R \docType{data} \name{helix} \alias{helix} \title{A helix structured toy data set} \usage{ data(helix) } \description{ Simulated data set looking like a helix } \details{ A matrix containing 1000 observations (rows) and three variables (columns). } \references{ Matthias Scholz, Fatma Kaplan, Charles L. Guy, Joachim Kopka and Joachim Selbig. - Non-linear PCA: a missing data approach. \emph{Bioinformatics 2005 21(20):3887-3895} } \author{ Henning Redestig } \keyword{datasets} pcaMethods/man/kEstimate.Rd0000644000175100017510000001435514614231101016652 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/kEstimate.R \name{kEstimate} \alias{kEstimate} \title{Estimate best number of Components for missing value estimation} \usage{ kEstimate(Matrix, method = "ppca", evalPcs = 1:3, segs = 3, nruncv = 5, em = "q2", allVariables = FALSE, verbose = interactive(), ...) } \arguments{ \item{Matrix}{\code{matrix} -- numeric matrix containing observations in rows and variables in columns} \item{method}{\code{character} -- of the methods found with pcaMethods() The option llsImputeAll calls llsImpute with the allVariables = TRUE parameter.} \item{evalPcs}{\code{numeric} -- The principal components to use for cross validation or the number of neighbour variables if used with llsImpute. Should be an array containing integer values, eg. \code{evalPcs = 1:10} or \code{evalPcs = c(2,5,8)}. The NRMSEP or Q2 is calculated for each component.} \item{segs}{\code{numeric} -- number of segments for cross validation} \item{nruncv}{\code{numeric} -- Times the whole cross validation is repeated} \item{em}{\code{character} -- The error measure. This can be nrmsep or q2} \item{allVariables}{\code{boolean} -- If TRUE, the NRMSEP is calculated for all variables, If FALSE, only the incomplete ones are included. You maybe want to do this to compare several methods on a complete data set.} \item{verbose}{\code{boolean} -- If TRUE, some output like the variable indexes are printed to the console each iteration.} \item{...}{Further arguments to \code{pca} or \code{nni}} } \value{ A list with: \item{bestNPcs}{number of PCs or k for which the minimal average NRMSEP or the maximal Q2 was obtained.} \item{eError}{an array of of size length(evalPcs). Contains the average error of the cross validation runs for each number of components.} \item{variableWiseError}{Matrix of size \code{incomplete_variables} x length(evalPcs). Contains the NRMSEP or Q2 distance for each variable and each number of PCs. This allows to easily see for wich variables imputation makes sense and for which one it should not be done or mean imputation should be used.} \item{evalPcs}{The evaluated numbers of components or number of neighbours (the same as the evalPcs input parameter).} \item{variableIx}{Index of the incomplete variables. This can be used to map the variable wise error to the original data.} } \description{ Perform cross validation to estimate the optimal number of components for missing value estimation. Cross validation is done for the complete subset of a variable. } \details{ The assumption hereby is that variables that are highly correlated in a distinct region (here the non-missing observations) are also correlated in another (here the missing observations). This also implies that the complete subset must be large enough to be representative. For each incomplete variable, the available values are divided into a user defined number of cv-segments. The segments have equal size, but are chosen from a random equal distribution. The non-missing values of the variable are covered completely. PPCA, BPCA, SVDimpute, Nipals PCA, llsImpute an NLPCA may be used for imputation. The whole cross validation is repeated several times so, depending on the parameters, the calculations can take very long time. As error measure the NRMSEP (see Feten et. al, 2005) or the Q2 distance is used. The NRMSEP basically normalises the RMSD between original data and estimate by the variable-wise variance. The reason for this is that a higher variance will generally lead to a higher estimation error. If the number of samples is small, the variable - wise variance may become an unstable criterion and the Q2 distance should be used instead. Also if variance normalisation was applied previously. The method proceeds variable - wise, the NRMSEP / Q2 distance is calculated for each incomplete variable and averaged afterwards. This allows to easily see for wich set of variables missing value imputation makes senes and for wich set no imputation or something like mean-imputation should be used. Use \code{kEstimateFast} or \code{Q2} if you are not interested in variable wise CV performance estimates. Run time may be very high on large data sets. Especially when used with complex methods like BPCA or Nipals PCA. For PPCA, BPCA, Nipals PCA and NLPCA the estimation method is called \eqn{(v_{miss} \cdot segs \cdot nruncv \cdot)}{(v\_miss * segs * nruncv)} times as the error for all numbers of principal components can be calculated at once. For LLSimpute and SVDimpute this is not possible, and the method is called \eqn{(v_{miss} \cdot segs \cdot nruncv \cdot length(evalPcs))}{(v\_miss * segs * nruncv * length(evalPcs))} times. This should still be fast for LLSimpute because the method allows to choose to only do the estimation for one particular variable. This saves a lot of iterations. Here, \eqn{v_{miss}}{v\_miss} is the number of variables showing missing values. As cross validation is done variable-wise, in this function Q2 is defined on single variables, not on the entire data set. This is Q2 is calculated as as \eqn{\frac{\sum(x - xe)^2}{\sum(x^2)}}{sum(x - xe)^2 \ sum(x^2)}, where x is the currently used variable and xe it's estimate. The values are then averaged over all variables. The NRMSEP is already defined variable-wise. For a single variable it is then \eqn{\sqrt(\frac{\sum(x - xe)^2}{(n \cdot var(x))})}{sqrt(sum(x - xe)^2 \ (n * var(x)))}, where x is the variable and xe it's estimate, n is the length of x. The variable wise estimation errors are returned in parameter variableWiseError. } \examples{ ## Load a sample metabolite dataset with 5\\\% missing values (metaboliteData) data(metaboliteData) # Do cross validation with ppca for component 2:4 esti <- kEstimate(metaboliteData, method = "ppca", evalPcs = 2:4, nruncv=1, em="nrmsep") # Plot the average NRMSEP barplot(drop(esti$eError), xlab = "Components",ylab = "NRMSEP (1 iterations)") # The best result was obtained for this number of PCs: print(esti$bestNPcs) # Now have a look at the variable wise estimation error barplot(drop(esti$variableWiseError[, which(esti$evalPcs == esti$bestNPcs)]), xlab = "Incomplete variable Index", ylab = "NRMSEP") } \seealso{ \code{\link{kEstimateFast}, \link{Q2}, \link{pca}, \link{nni}}. } \author{ Wolfram Stacklies } \keyword{multivariate} pcaMethods/man/kEstimateFast.Rd0000644000175100017510000000553514614231101017470 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/kEstimateFast.R \name{kEstimateFast} \alias{kEstimateFast} \title{Estimate best number of Components for missing value estimation} \usage{ kEstimateFast(Matrix, method = "ppca", evalPcs = 1:3, em = "nrmsep", allVariables = FALSE, verbose = interactive(), ...) } \arguments{ \item{Matrix}{\code{matrix} -- numeric matrix containing observations in rows and variables in columns} \item{method}{\code{character} -- a valid pca method (see \code{\link{pca}}).} \item{evalPcs}{\code{numeric} -- The principal components to use for cross validation or cluster sizes if used with llsImpute. Should be an array containing integer values, eg. evalPcs = 1:10 or evalPcs = C(2,5,8).The NRMSEP is calculated for each component.} \item{em}{\code{character} -- The error measure. This can be nrmsep or q2} \item{allVariables}{\code{boolean} -- If TRUE, the NRMSEP is calculated for all variables, If FALSE, only the incomplete ones are included. You maybe want to do this to compare several methods on a complete data set.} \item{verbose}{\code{boolean} -- If TRUE, the NRMSEP and the variance are printed to the console each iteration.} \item{...}{Further arguments to \code{pca}} } \value{ \item{list}{Returns a list with the elements: \itemize{ \item minNPcs - number of PCs for which the minimal average NRMSEP was obtained \item eError - an array of of size length(evalPcs). Contains the estimation error for each number of components. \item evalPcs - The evaluated numbers of components or cluster sizes (the same as the evalPcs input parameter). }} } \description{ This is a simple estimator for the optimal number of componets when applying PCA or LLSimpute for missing value estimation. No cross validation is performed, instead the estimation quality is defined as Matrix[!missing] - Estimate[!missing]. This will give a relatively rough estimate, but the number of iterations equals the length of the parameter evalPcs.\cr Does not work with LLSimpute!! As error measure the NRMSEP (see Feten et. al, 2005) or the Q2 distance is used. The NRMSEP basically normalises the RMSD between original data and estimate by the variable-wise variance. The reason for this is that a higher variance will generally lead to a higher estimation error. If the number of samples is small, the gene - wise variance may become an unstable criterion and the Q2 distance should be used instead. Also if variance normalisation was applied previously. } \examples{ data(metaboliteData) # Estimate best number of PCs with ppca for component 2:4 esti <- kEstimateFast(t(metaboliteData), method = "ppca", evalPcs = 2:4, em="nrmsep") barplot(drop(esti$eError), xlab = "Components",ylab = "NRMSEP (1 iterations)") # The best k value is: print(esti$minNPcs) } \seealso{ \code{\link{kEstimate}}. } \author{ Wolfram Stacklies } \keyword{multivariate} pcaMethods/man/leverage-pcaRes-method.Rd0000644000175100017510000000213414614231101021177 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{leverage,pcaRes-method} \alias{leverage,pcaRes-method} \alias{leverage} \title{Extract leverages of a PCA model} \usage{ \S4method{leverage}{pcaRes}(object) } \arguments{ \item{object}{a \code{pcaRes} object} } \value{ The observation leverages as a numeric vector } \description{ The leverages of PCA model indicate how much influence each observation has on the PCA model. Observations with high leverage has caused the principal components to rotate towards them. It can be used to extract both "unimportant" observations as well as picking potential outliers. } \details{ Defined as \eqn{Tr(T(T'T)^{-1}T')}{Tr(T(T'T)^(-1)T')} } \examples{ data(iris) pcIr <- pca(iris[,1:4]) ## versicolor has the lowest leverage with(iris, plot(leverage(pcIr)~Species)) } \references{ Introduction to Multi- and Megavariate Data Analysis using Projection Methods (PCA and PLS), L. Eriksson, E. Johansson, N. Kettaneh-Wold and S. Wold, Umetrics 1999, p. 466 } \author{ Henning Redestig } \keyword{multivariate} pcaMethods/man/lineSearch.Rd0000644000175100017510000000104014614231101016764 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lineSearch.R \name{lineSearch} \alias{lineSearch} \title{Line search for conjugate gradient} \usage{ lineSearch(nlnet, dw, e0, ttGuess, trainIn, trainOut, verbose) } \arguments{ \item{nlnet}{The nlnet} \item{dw}{..} \item{e0}{..} \item{ttGuess}{..} \item{trainIn}{Training data} \item{trainOut}{Fitted data} \item{verbose}{logical, print messages} } \value{ ... } \description{ Line search for conjugate gradient } \author{ Henning Redestig, Matthias Scholz } pcaMethods/man/linr.Rd0000644000175100017510000000043314614231101015660 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/lineSearch.R \name{linr} \alias{linr} \title{Linear kernel} \usage{ linr(x) } \arguments{ \item{x}{datum} } \value{ Input value } \description{ Linear kernel } \author{ Henning Redestig, Matthias Scholz } pcaMethods/man/listPcaMethods.Rd0000644000175100017510000000105714614231101017642 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/pca.R \name{listPcaMethods} \alias{listPcaMethods} \title{List PCA methods} \usage{ listPcaMethods(which = c("all", "linear", "nonlinear")) } \arguments{ \item{which}{the type of methods to get. E.g. only get the PCA methods based on the classical model where the fitted data is a direct multiplication of scores and loadings.} } \value{ A character vector with the current methods for doing PCA } \description{ Vector with current valid PCA methods } \author{ Henning Redestig } pcaMethods/man/llsImpute.Rd0000644000175100017510000000776614614231101016712 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/llsImpute.R \name{llsImpute} \alias{llsImpute} \title{LLSimpute algorithm} \usage{ llsImpute(Matrix, k = 10, center = FALSE, completeObs = TRUE, correlation = "pearson", allVariables = FALSE, maxSteps = 100, xval = NULL, verbose = FALSE, ...) } \arguments{ \item{Matrix}{\code{matrix} -- Data containing the variables (genes) in columns and observations (samples) in rows. The data may contain missing values, denoted as \code{NA}.} \item{k}{\code{numeric} -- Cluster size, this is the number of similar genes used for regression.} \item{center}{\code{boolean} -- Mean center the data if TRUE} \item{completeObs}{\code{boolean} -- Return the estimated complete observations if TRUE. This is the input data with NA values replaced by the estimated values.} \item{correlation}{\code{character} -- How to calculate the distance between genes. One out of pearson | kendall | spearman , see also help("cor").} \item{allVariables}{\code{boolean} -- Use only complete genes to do the regression if TRUE, all genes if FALSE.} \item{maxSteps}{\code{numeric} -- Maximum number of iteration steps if allGenes = TRUE.} \item{xval}{\code{numeric} Use LLSimpute for cross validation. xval is the index of the gene to estimate, all other incomplete genes will be ignored if this parameter is set. We do not consider them in the cross-validation.} \item{verbose}{\code{boolean} -- Print step number and relative change if TRUE and allVariables = TRUE} \item{...}{Reserved for parameters used in future version of the algorithm} } \value{ \item{nniRes}{Standard nni (nearest neighbour imputation) result object of this package. See \code{\link{nniRes}} for details.} } \description{ Missing value estimation using local least squares (LLS). First, k variables (for Microarrya data usually the genes) are selected by pearson, spearman or kendall correlation coefficients. Then missing values are imputed by a linear combination of the k selected variables. The optimal combination is found by LLS regression. The method was first described by Kim et al, Bioinformatics, 21(2),2005. } \details{ Missing values are denoted as \code{NA}\cr It is not recommended to use this function directely but rather to use the nni() wrapper function. The methods provides two ways for missing value estimation, selected by the \code{allVariables} option. The first one is to use only complete variables for the regression. This is preferable when the number of incomplete variables is relatively small. The second way is to consider all variables as candidates for the regression. Hereby missing values are initially replaced by the columns wise mean. The method then iterates, using the current estimate as input for the regression until the change between new and old estimate falls below a threshold (0.001). } \note{ Each step the generalized inverse of a \code{miss} x k matrix is calculated. Where \code{miss} is the number of missing values in variable j and \code{k} the number of neighbours. This may be slow for large values of k and / or many missing values. See also help("ginv"). } \examples{ ## Load a sample metabolite dataset (metaboliteData) with already 5\\\% of ## data missing data(metaboliteData) ## Perform llsImpute using k = 10 ## Set allVariables TRUE because there are very few complete variables result <- llsImpute(metaboliteData, k = 10, correlation="pearson", allVariables=TRUE) ## Get the estimated complete observations cObs <- completeObs(result) } \references{ Kim, H. and Golub, G.H. and Park, H. - Missing value estimation for DNA microarray gene expression data: local least squares imputation. \emph{Bioinformatics, 2005; 21(2):187-198.} Troyanskaya O. and Cantor M. and Sherlock G. and Brown P. and Hastie T. and Tibshirani R. and Botstein D. and Altman RB. - Missing value estimation methods for DNA microarrays. \emph{Bioinformatics. 2001 Jun;17(6):520-525.} } \seealso{ \code{\link{pca}, \link{nniRes}, \link{nni}}. } \author{ Wolfram Stacklies } \keyword{multivariate} pcaMethods/man/loadings-ANY-method.Rd0000644000175100017510000000077614614231101020431 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{loadings,ANY-method} \alias{loadings,ANY-method} \alias{loadings} \title{Crude way to unmask the function with the same name from \code{stats}} \usage{ \S4method{loadings}{ANY}(object, ...) } \arguments{ \item{object}{any object} \item{...}{not used} } \value{ The loadings } \description{ Crude way to unmask the function with the same name from \code{stats} } \author{ Henning Redestig } pcaMethods/man/loadings-pcaRes-method.Rd0000644000175100017510000000075114614231101021210 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{loadings,pcaRes-method} \alias{loadings,pcaRes-method} \title{Get loadings from a pcaRes object} \usage{ \S4method{loadings}{pcaRes}(object, ...) } \arguments{ \item{object}{a pcaRes object} \item{...}{not used} } \value{ The loadings as a matrix } \description{ Get loadings from a pcaRes object } \seealso{ \code{\link{loadings.pcaRes}} } \author{ Henning Redestig } pcaMethods/man/loadings.pcaRes.Rd0000644000175100017510000000063514614231101017734 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \name{loadings.pcaRes} \alias{loadings.pcaRes} \title{Get loadings from a pcaRes object} \usage{ \method{loadings}{pcaRes}(object, ...) } \arguments{ \item{object}{a pcaRes object} \item{...}{not used} } \value{ The loadings as a matrix } \description{ Get loadings from a pcaRes object } \author{ Henning Redestig } pcaMethods/man/metaboliteData.Rd0000644000175100017510000000174514614231101017642 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/pcaMethods-package.R \docType{data} \name{metaboliteData} \alias{metaboliteData} \title{A incomplete metabolite data set from an Arabidopsis coldstress experiment} \description{ A incomplete subset from a larger metabolite data set. This is the original, complete data set and can be used to compare estimation results created with the also provided incomplete data (called metaboliteData). } \details{ A matrix containing 154 observations (rows) and 52 metabolites (columns). The data contains 5\% of artificially created uniformly distributed misssing values. The data was created during an in house Arabidopsis coldstress experiment. } \references{ Matthias Scholz, Fatma Kaplan, Charles L. Guy, Joachim Kopka and Joachim Selbig. - Non-linear PCA: a missing data approach.\emph{Bioinformatics 2005 21(20):3887-3895} } \seealso{ \code{\link{metaboliteDataComplete}} } \author{ Wolfram Stacklies } \keyword{datasets} pcaMethods/man/metaboliteDataComplete.Rd0000644000175100017510000000162514614231101021330 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/pcaMethods-package.R \docType{data} \name{metaboliteDataComplete} \alias{metaboliteDataComplete} \title{A complete metabolite data set from an Arabidopsis coldstress experiment} \description{ A complete subset from a larger metabolite data set. This is the original, complete data set and can be used to compare estimation results created with the also provided incomplete data (called metaboliteData). The data was created during an in house Arabidopsis coldstress experiment. } \details{ A matrix containing 154 observations (rows) and 52 metabolites (columns). } \references{ Matthias Scholz, Fatma Kaplan, Charles L. Guy, Joachim Kopka and Joachim Selbig. - Non-linear PCA: a missing data approach.\emph{Bioinformatics 2005 21(20):3887-3895} } \seealso{ \code{\link{metaboliteData}} } \author{ Wolfram Stacklies } \keyword{datasets} pcaMethods/man/method-pcaRes-method.Rd0000644000175100017510000000063214614231101020666 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{method,pcaRes-method} \alias{method,pcaRes-method} \alias{method} \title{Get the used PCA method} \usage{ method(object, ...) } \arguments{ \item{object}{pcaRes object} \item{...}{Not used} } \value{ The used pca method } \description{ Get the used PCA method } \author{ Henning Redestig } pcaMethods/man/nipalsPca.Rd0000644000175100017510000000361414614231101016632 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nipalsPca.R \name{nipalsPca} \alias{nipalsPca} \title{NIPALS PCA} \usage{ nipalsPca(Matrix, nPcs = 2, varLimit = 1, maxSteps = 5000, threshold = 1e-06, ...) } \arguments{ \item{Matrix}{Pre-processed (centered, scaled) numerical matrix samples in rows and variables as columns.} \item{nPcs}{Number of components that should be extracted.} \item{varLimit}{Optionally the ratio of variance that should be explained. \code{nPcs} is ignored if varLimit < 1} \item{maxSteps}{Defines how many iterations can be done before algorithm should abort (happens almost exclusively when there were some wrong in the input data).} \item{threshold}{The limit condition for judging if the algorithm has converged or not, specifically if a new iteration is done if \eqn{(T_{old} - T)^T(T_{old} - T) > \code{limit}}.} \item{...}{Only used for passing through arguments.} } \value{ A \code{pcaRes} object. } \description{ PCA by non-linear iterative partial least squares } \details{ Can be used for computing PCA on a numeric matrix using either the NIPALS algorithm which is an iterative approach for estimating the principal components extracting them one at a time. NIPALS can handle a small amount of missing values. It is not recommended to use this function directely but rather to use the pca() wrapper function. } \examples{ data(metaboliteData) mat <- prep(t(metaboliteData)) pc <- nipalsPca(mat, nPcs=2) ## better use pca() pc <- pca(t(metaboliteData), method="nipals", nPcs=2) \dontshow{stopifnot(sum((fitted(pc) - t(metaboliteData))^2, na.rm=TRUE) < 200)} } \references{ Wold, H. (1966) Estimation of principal components and related models by iterative least squares. In Multivariate Analysis (Ed., P.R. Krishnaiah), Academic Press, NY, 391-420. } \seealso{ \code{prcomp}, \code{princomp}, \code{pca} } \author{ Henning Redestig } \keyword{multivariate} pcaMethods/man/nlpca.Rd0000644000175100017510000000674114614231101016021 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nlpca.R \name{nlpca} \alias{nlpca} \title{Non-linear PCA} \usage{ nlpca(Matrix, nPcs = 2, maxSteps = 2 * prod(dim(Matrix)), unitsPerLayer = NULL, functionsPerLayer = NULL, weightDecay = 0.001, weights = NULL, verbose = interactive(), ...) } \arguments{ \item{Matrix}{\code{matrix} --- Preprocessed data with the variables in columns and observations in rows. The data may contain missing values, denoted as \code{NA}} \item{nPcs}{\code{numeric} -- Number of components to estimate. The preciseness of the missing value estimation depends on thenumber of components, which should resemble the internal structure of the data.} \item{maxSteps}{\code{numeric} -- Number of estimation steps. Default is based on a generous rule of thumb.} \item{unitsPerLayer}{The network units, example: c(2,4,6) for two input units 2feature units (principal components), one hidden layer fornon-linearity and three output units (original amount ofvariables).} \item{functionsPerLayer}{The function to apply at each layer eg. c("linr", "tanh", "linr")} \item{weightDecay}{Value between 0 and 1.} \item{weights}{Starting weights for the network. Defaults to uniform random values but can be set specifically to make algorithm deterministic.} \item{verbose}{\code{boolean} -- nlpca prints the number of steps and warning messages if set to TRUE. Default is interactive().} \item{...}{Reserved for future use. Not passed on anywhere.} } \value{ Standard PCA result object used by all PCA-basedmethods of this package. Contains scores, loadings, data meanand more. See \code{\link{pcaRes}} for details. } \description{ Neural network based non-linear PCA } \details{ Artificial Neural Network (MLP) for performing non-linear PCA. Non-linear PCA is conceptually similar to classical PCA but theoretically quite different. Instead of simply decomposing our matrix (X) to scores (T) loadings (P) and an error (E) we train a neural network (our loadings) to find a curve through the multidimensional space of X that describes a much variance as possible. Classical ways of interpreting PCA results are thus not applicable to NLPCA since the loadings are hidden in the network. However, the scores of components that lead to low cross-validation errors can still be interpreted via the score plot. Unfortunately this method depend on slow iterations which currently are implemented in R only making this method extremely slow. Furthermore, the algorithm does not by itself decide when it has converged but simply does 'maxSteps' iterations. } \examples{ ## Data set with three variables where data points constitute a helix data(helix) helixNA <- helix ## not a single complete observation helixNA <- t(apply(helix, 1, function(x) { x[sample(1:3, 1)] <- NA; x})) ## 50 steps is not enough, for good estimation use 1000 helixNlPca <- pca(helixNA, nPcs=1, method="nlpca", maxSteps=50) fittedData <- fitted(helixNlPca, helixNA) plot(fittedData[which(is.na(helixNA))], helix[which(is.na(helixNA))]) ## compared to solution by Nipals PCA which cannot extract non-linear patterns helixNipPca <- pca(helixNA, nPcs=2) fittedData <- fitted(helixNipPca) plot(fittedData[which(is.na(helixNA))], helix[which(is.na(helixNA))]) } \references{ Matthias Scholz, Fatma Kaplan, Charles L Guy, Joachim Kopkaand Joachim Selbig. Non-linear PCA: a missing data approach. \emph{Bioinformatics, 21(20):3887-3895, Oct 2005} } \author{ Based on a matlab script by Matthias Scholz and ported to R by Henning Redestig } pcaMethods/man/nmissing-pcaRes-method.Rd0000644000175100017510000000067414614231101021243 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{nmissing,pcaRes-method} \alias{nmissing,pcaRes-method} \alias{nmissing} \alias{nmissing,nniRes-method} \title{Missing values} \usage{ nmissing(object, ...) } \arguments{ \item{object}{pcaRes object} \item{...}{Not used} } \value{ Get the number of missing values } \description{ Missing values } \author{ Henning Redestig } pcaMethods/man/nni.Rd0000644000175100017510000000237314614231101015505 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/pca.R \name{nni} \alias{nni} \title{Nearest neighbour imputation} \usage{ nni(object, method = c("llsImpute"), subset = numeric(), ...) } \arguments{ \item{object}{Numerical matrix with (or an object coercible to such) with samples in rows and variables as columns. Also takes \code{ExpressionSet} in which case the transposed expression matrix is used.} \item{method}{For convenience one can pass a large matrix but only use the variable specified as subset. Can be colnames or indices.} \item{subset}{Currently "llsImpute" only.} \item{...}{Further arguments to the chosen method.} } \value{ A \code{clusterRes} object. Or a list containing a clusterRes object as first and an ExpressionSet object as second entry if the input was of type ExpressionSet. } \description{ Wrapper function for imputation methods based on nearest neighbour clustering. Currently llsImpute only. } \details{ This method is wrapper function to llsImpute, See documentation for \code{link{llsImpute}}. } \examples{ data(metaboliteData) llsRes <- nni(metaboliteData, k=6, method="llsImpute", allGenes=TRUE) } \seealso{ \code{\link{llsImpute}}, \code{\link{pca}} } \author{ Wolfram Stacklies } \keyword{multivariate} pcaMethods/man/nniRes.Rd0000644000175100017510000000252714614231101016160 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/AllClasses.R \docType{class} \name{nniRes} \alias{nniRes} \alias{nniRes-class} \title{Class for representing a nearest neighbour imputation result} \description{ This is a class representation of nearest neighbour imputation (nni) result } \details{ \bold{Creating Objects}\cr \code{new("nniRes", completeObs=[the estimated complete observations], k=[cluster size], nObs=[amount of observations], nVar=[amount of variables], centered=[was the data centered befor running LLSimpute], center=[original means], method=[method used to perform clustering], missing=[amount of NAs])} \bold{Slots}\cr \describe{ \item{completeObs}{"matrix", the estimated complete observations} \item{nObs}{"numeric", amount of observations} \item{nVar}{"numeric", amount of variables} \item{correlation}{"character", the correlation method used (pearson, kendall or spearman)} \item{centered}{"logical", data was centered or not} \item{center}{"numeric", the original variable centers} \item{k}{"numeric", cluster size} \item{method}{"character", the method used to perform the clustering} \item{missing}{"numeric", the total amount of missing values in original data} } \bold{Methods}\cr \describe{ \item{print}{Print function} } } \author{ Wolfram Stacklies } \keyword{classes} pcaMethods/man/nObs-pcaRes-method.Rd0000644000175100017510000000073514614231101020313 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{nObs,pcaRes-method} \alias{nObs,pcaRes-method} \alias{nObs} \title{Get the number of observations used to build the PCA model.} \usage{ nObs(object, ...) } \arguments{ \item{object}{pcaRes object} \item{...}{Not used} } \value{ Number of observations } \description{ Get the number of observations used to build the PCA model. } \author{ Henning Redestig } pcaMethods/man/nP-pcaRes-method.Rd0000644000175100017510000000057014614231101017764 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{nP,pcaRes-method} \alias{nP,pcaRes-method} \alias{nP} \title{Get number of PCs} \usage{ nP(object, ...) } \arguments{ \item{object}{pcaRes object} \item{...}{not used} } \value{ Number of PCs } \description{ Get number of PCs } \author{ Henning Redestig } pcaMethods/man/nPcs-pcaRes-method.Rd0000644000175100017510000000074314614231101020314 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{nPcs,pcaRes-method} \alias{nPcs,pcaRes-method} \alias{nPcs} \title{Get number of PCs.} \usage{ nPcs(object, ...) } \arguments{ \item{object}{pcaRes object} \item{...}{not used} } \value{ Number of PCs } \description{ Get number of PCs. } \note{ Try to use \code{link{nP}} instead since \code{nPcs} tend to clash with argument names. } \author{ Henning Redestig } pcaMethods/man/nVar-pcaRes-method.Rd0000644000175100017510000000072414614231101020316 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{nVar,pcaRes-method} \alias{nVar,pcaRes-method} \alias{nVar} \title{Get the number of variables used to build the PCA model.} \usage{ nVar(object, ...) } \arguments{ \item{object}{pcaRes object} \item{...}{Not used} } \value{ Number of variables } \description{ Get the number of variables used to build the PCA model. } \author{ Henning Redestig } pcaMethods/man/optiAlgCgd.Rd0000644000175100017510000000073714614231101016740 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/optiAlgCgd.R \name{optiAlgCgd} \alias{optiAlgCgd} \title{Conjugate gradient optimization} \usage{ optiAlgCgd(nlnet, trainIn, trainOut, verbose = FALSE) } \arguments{ \item{nlnet}{The nlnet} \item{trainIn}{Training data} \item{trainOut}{fitted data} \item{verbose}{logical, print messages} } \value{ ... } \description{ Conjugate gradient optimization } \author{ Henning Redestig, Matthias Scholz } pcaMethods/man/orth.Rd0000644000175100017510000000121214614231101015664 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/orth.R \name{orth} \alias{orth} \title{Calculate an orthonormal basis} \usage{ orth(mat, skipInac = FALSE) } \arguments{ \item{mat}{matrix to calculate orthonormal base} \item{skipInac}{do not include components with precision below .Machine$double.eps if TRUE} } \value{ orthonormal basis for the range of matrix } \description{ ONB = orth(mat) is an orthonormal basis for the range of matrix mat. That is, ONB' * ONB = I, the columns of ONB span the same space as the columns of mat, and the number of columns of ONB is the rank of mat. } \author{ Wolfram Stacklies } pcaMethods/man/pca.Rd0000644000175100017510000000752314614231101015466 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/pca.R \name{pca} \alias{pca} \title{Perform principal component analysis} \usage{ pca(object, method, nPcs = 2, scale = c("none", "pareto", "vector", "uv"), center = TRUE, completeObs = TRUE, subset = NULL, cv = c("none", "q2"), ...) } \arguments{ \item{object}{Numerical matrix with (or an object coercible to such) with samples in rows and variables as columns. Also takes \code{ExpressionSet} in which case the transposed expression matrix is used. Can also be a data frame in which case all numberic variables are used to fit the PCA.} \item{method}{One of the methods reported by \code{listPcaMethods()}. Can be left missing in which case the \code{svd} PCA is chosen for data wihout missing values and \code{nipalsPca} for data with missing values} \item{nPcs}{Number of principal components to calculate.} \item{scale}{Scaling, see \code{\link{prep}}.} \item{center}{Centering, see \code{\link{prep}}.} \item{completeObs}{Sets the \code{completeObs} slot on the resulting \code{pcaRes} object containing the original data with but with all NAs replaced with the estimates.} \item{subset}{A subset of variables to use for calculating the model. Can be column names or indices.} \item{cv}{character naming a the type of cross-validation to be performed.} \item{...}{Arguments to \code{\link{prep}}, the chosen pca method and \code{\link{Q2}}.} } \value{ A \code{pcaRes} object. } \description{ Perform PCA on a numeric matrix for visualisation, information extraction and missing value imputation. } \details{ This method is wrapper function for the following set of pca methods: \describe{\item{svd:}{Uses classical \code{prcomp}. See documentation for \code{\link{svdPca}}.} \item{nipals:}{An iterative method capable of handling small amounts of missing values. See documentation for \code{\link{nipalsPca}}.} \item{rnipals:}{Same as nipals but implemented in R.} \item{bpca:}{An iterative method using a Bayesian model to handle missing values. See documentation for \code{\link{bpca}}.} \item{ppca:}{An iterative method using a probabilistic model to handle missing values. See documentation for \code{\link{ppca}}.} \item{svdImpute:}{Uses expectation maximation to perform SVD PCA on incomplete data. See documentation for \code{\link{svdImpute}}.}} Scaling and centering is part of the PCA model and handled by \code{\link{prep}}. } \examples{ data(iris) ## Usually some kind of scaling is appropriate pcIr <- pca(iris, method="svd", nPcs=2) pcIr <- pca(iris, method="nipals", nPcs=3, cv="q2") ## Get a short summary on the calculated model summary(pcIr) plot(pcIr) ## Scores and loadings plot slplot(pcIr, sl=as.character(iris[,5])) ## use an expressionset and ggplot data(sample.ExpressionSet) pc <- pca(sample.ExpressionSet) df <- merge(scores(pc), pData(sample.ExpressionSet), by=0) library(ggplot2) ggplot(df, aes(PC1, PC2, shape=sex, color=type)) + geom_point() + xlab(paste("PC1", pc@R2[1] * 100, "\% of the variance")) + ylab(paste("PC2", pc@R2[2] * 100, "\% of the variance")) } \references{ Wold, H. (1966) Estimation of principal components and related models by iterative least squares. In Multivariate Analysis (Ed., P.R. Krishnaiah), Academic Press, NY, 391-420. Shigeyuki Oba, Masa-aki Sato, Ichiro Takemasa, Morito Monden, Ken-ichi Matsubara and Shin Ishii. A Bayesian missing value estimation method for gene expression profile data. \emph{Bioinformatics, 19(16):2088-2096, Nov 2003}. Troyanskaya O. and Cantor M. and Sherlock G. and Brown P. and Hastie T. and Tibshirani R. and Botstein D. and Altman RB. - Missing value estimation methods for DNA microarrays. \emph{Bioinformatics. 2001 Jun;17(6):520-5}. } \seealso{ \code{\link{prcomp}}, \code{\link{princomp}}, \code{\link{nipalsPca}}, \code{\link{svdPca}} } \author{ Wolfram Stacklies, Henning Redestig } \keyword{multivariate} pcaMethods/man/pcaMethods-deprecated.Rd0000644000175100017510000000105414614231101021101 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/pcaMethods-package.R \name{pcaMethods-deprecated} \alias{pcaMethods-deprecated} \title{Deprecated methods for pcaMethods} \description{ \describe{ \item{plotR2}{Lack of relevance for this plot and the fact that it can not show cross-validation based diagnostics in the same plot makes it redundant with the introduction of a dedicated \code{plot} function for \code{pcaRes}. The new plot only shows R2cum but the result is pretty much the same.}} } \author{ Henning Redestig } pcaMethods/man/pcaMethods.Rd0000644000175100017510000000221714614231101017005 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/pcaMethods-package.R \docType{package} \name{pcaMethods} \alias{pcaMethods} \alias{pcaMethods-package} \title{pcaMethods} \description{ Principal Component Analysis in R } \details{ \tabular{ll}{ Package: \tab pcaMethods \cr Type: \tab Package \cr Developed since: \tab 2006 \cr License: \tab GPL (>=3) \cr LazyLoad: \tab yes \cr } Provides Bayesian PCA, Probabilistic PCA, Nipals PCA, Inverse Non-Linear PCA and the conventional SVD PCA. A cluster based method for missing value estimation is included for comparison. BPCA, PPCA and NipalsPCA may be used to perform PCA on incomplete data as well as for accurate missing value estimation. A set of methods for printing and plotting the results is also provided. All PCA methods make use of the same data structure (pcaRes) to provide a unique interface to the PCA results. Developed at the Max-Planck Institute for Molecular Plant Physiology, Golm, Germany, RIKEN Plant Science Center Yokohama, Japan, and CAS-MPG Partner Institute for Computational Biology (PICB) Shanghai, P.R. China } \author{ Wolfram Stacklies, Henning Redestig } pcaMethods/man/pcaNet.Rd0000644000175100017510000000657214614231101016140 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/AllClasses.R \docType{class} \name{pcaNet} \alias{pcaNet} \alias{nlpcaNet} \alias{nlpcaNet-class} \title{Class representation of the NLPCA neural net} \description{ This is a class representation of a non-linear PCA neural network. The \code{nlpcaNet} class is not meant for user-level usage. } \details{ Creating Objects \code{new("nlpcaNet", net=[the network structure], hierarchic=[hierarchic design], fct=[the functions at each layer], fkt=[the functions used for forward propagation], weightDecay=[incremental decrease of weight changes over iterations (between 0 and 1)], featureSorting=[sort features or not], dataDist=[represents the present values], inverse=[net is inverse mode or not], fCount=[amount of times features were sorted], componentLayer=[which layer is the 'bottleneck' (principal components)], erro=[the used error function], gradient=[the used gradient method], weights=[the present weights], maxIter=[the amount of iterations that was done], scalingFactor=[the scale of the original matrix])} Slots \describe{ \item{net}{"matrix", matrix showing the representation of the neural network, e.g. (2,4,6) for a network with two features, a hidden layer and six output neurons (original variables).} \item{hierarchic}{"list", the hierarchic design of the network, holds 'idx' (), 'var' () and layer (which layer is the principal component layer).} \item{fct}{"character", a vector naming the functions that will be applied on each layer. "linr" is linear (i.e.) standard matrix products and "tanh" means that the arcus tangens is applied on the result of the matrix product (for non-linearity).} \item{fkt}{"character", same as fct but the functions used during back propagation.} \item{weightDecay}{"numeric", the value that is used to incrementally decrease the weight changes to ensure convergence.} \item{featureSorting}{"logical", indicates if features will be sorted or not. This is used to make the NLPCA assume properties closer to those of standard PCA were the first component is more important for reconstructing the data than the second component.} \item{dataDist}{"matrix", a matrix of ones and zeroes indicating which values will add to the errror.} \item{inverse}{"logical", network is inverse mode (currently only inverse is supported) or not. Eg. the case when we have truly missing values and wish to impute them.} \item{fCount}{"integer", Counter for the amount of times features were really sorted.} \item{componentLayer}{"numeric", the index of 'net' that is the component layer.} \item{error}{"function", the used error function. Currently only one is provided \code{errorHierarchic}.} \item{gradient}{"function", the used gradient function. Currently only one is provided \code{derrorHierarchic}} \item{weights}{"list", A list holding managements of the weights. The list has two functions, weights$current() and weights$set() which access a matrix in the local environment of this object.} \item{maxIter}{"integer", the amount of iterations used to train this network.} \item{scalingFactor}{"numeric", training the network is best made with 'small' values so the original data is scaled down to a suitable range by division with this number.}} Methods \describe{ \item{vector2matrices}{Returns the weights in a matrix representation.} } } \seealso{ \code{\link{nlpca}} } \author{ Henning Redestig } \keyword{classes} pcaMethods/man/pcaRes.Rd0000644000175100017510000000577214614231101016144 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/AllClasses.R \docType{class} \name{pcaRes} \alias{pcaRes} \alias{pcaRes-class} \title{Class for representing a PCA result} \description{ This is a class representation of a PCA result } \details{ \bold{Creating Objects}\cr \code{new("pcaRes", scores=[the scores], loadings=[the loadings], nPcs=[amount of PCs], R2cum=[cumulative R2], nObs=[amount of observations], nVar=[amount of variables], R2=[R2 for each individual PC], sDev=[stdev for each individual PC], centered=[was data centered], center=[original means], varLimit=[what variance limit was exceeded], method=[method used to calculate PCA], missing=[amount of NAs], completeObs=[estimated complete observations])} \bold{Slots}\cr \describe{ \item{scores}{"matrix", the calculated scores} \item{loadings}{"matrix", the calculated loadings} \item{R2cum}{"numeric", the cumulative R2 values} \item{sDev}{"numeric", the individual standard deviations of the score vectors} \item{R2}{"numeric", the individual R2 values} \item{cvstat}{"numeric", cross-validation statistics} \item{nObs}{"numeric", number of observations} \item{nVar}{"numeric", number of variables} \item{centered}{"logical", data was centered or not} \item{center}{"numeric", the original variable centers} \item{scaled}{"logical", data was scaled or not} \item{scl}{"numeric", the original variable scales} \item{varLimit}{"numeric", the exceeded variance limit} \item{nPcs,nP}{"numeric", the number of calculated PCs} \item{method}{"character", the method used to perform PCA} \item{missing}{"numeric", the total amount of missing values in original data} \item{completeObs}{"matrix", the estimated complete observations} \item{network}{"nlpcaNet", the network used by non-linear PCA} } \bold{Methods (not necessarily exhaustive)}\cr \describe{ \item{print}{Print function} \item{summary}{Extract information about PC relevance} \item{screeplot}{Plot a barplot of standard deviations for PCs} \item{slplot}{Make a side by side score and loadings plot} \item{nPcs}{Get the number of PCs} \item{nObs}{Get the number of observations} \item{cvstat}{Cross-validation statistics} \item{nVar}{Get the number of variables} \item{loadings}{Get the loadings} \item{scores}{Get the scores} \item{dim}{Get the dimensions (number of observations, number of features)} \item{centered}{Get a logical indicating if centering was done as part of the model} \item{center}{Get the averages of the original variables.} \item{completeObs}{Get the imputed data set} \item{method}{Get a string naming the used PCA method} \item{sDev}{Get the standard deviations of the PCs} \item{scaled}{Get a logical indicating if scaling was done as part of the model} \item{scl}{Get the scales of the original variablesb} \item{R2cum}{Get the cumulative R2} } } \author{ Henning Redestig } \keyword{classes} pcaMethods/man/plot.pcaRes.Rd0000644000175100017510000000237414614231101017114 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \name{plot.pcaRes} \alias{plot.pcaRes} \alias{plot,pcaRes-method} \title{Plot diagnostics (screeplot)} \usage{ \method{plot}{pcaRes}(x, y = NULL, main = deparse(substitute(object)), col = gray(c(0.9, 0.5)), ...) } \arguments{ \item{x}{\code{pcaRes} The pcaRes object.} \item{y}{not used} \item{main}{title of the plot} \item{col}{Colors of the bars} \item{...}{further arguments to barplot} } \value{ None, used for side effect. } \description{ Plot the computed diagnostics of PCA model to get an idea of their importance. Note though that the standard screeplot shows the standard deviations for the PCs this method shows the R2 values which empirically shows the importance of the P's and is thus applicable for any PCA method rather than just SVD based PCA. } \details{ If cross-validation was done for the PCA the plot will also show the CV based statistics. A common rule-of-thumb for determining the optimal number of PCs is the PC where the CV diagnostic is at its maximum but not very far from \eqn{R^2}. } \examples{ data(metaboliteData) pc <- pca(t(metaboliteData), nPcs=5, cv="q2", scale="uv") plot(pc) } \seealso{ \link{screeplot} } \author{ Henning Redestig } pcaMethods/man/plotPcs.Rd0000644000175100017510000000246214614231101016344 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/pca.R \name{plotPcs} \alias{plotPcs} \title{Plot many side by side scores XOR loadings plots} \usage{ plotPcs(object, pcs = 1:nP(object), type = c("scores", "loadings"), sl = NULL, hotelling = 0.95, ...) } \arguments{ \item{object}{\code{pcaRes} a pcaRes object} \item{pcs}{\code{numeric} which pcs to plot} \item{type}{\code{character} Either "scores" or "loadings" for scores or loadings plot respectively} \item{sl}{\code{character} Text labels to plot instead of a point, if NULL points are plotted instead of text} \item{hotelling}{\code{numeric} Significance level for the confidence ellipse. NULL means that no ellipse is drawn.} \item{...}{Further arguments to \code{\link{pairs}} on which this function is based.} } \value{ None, used for side effect. } \description{ A function that can be used to visualise many PCs plotted against each other } \details{ Uses \code{\link{pairs}} to provide side-by-side plots. Note that this function only plots scores or loadings but not both in the same plot. } \examples{ data(iris) pcIr <- pca(iris[,1:4], nPcs=3, method="svd") plotPcs(pcIr, col=as.integer(iris[,4]) + 1) } \seealso{ \code{prcomp}, \code{pca}, \code{princomp}, \code{slplot} } \author{ Henning Redestig } \keyword{multivariate} pcaMethods/man/ppca.Rd0000644000175100017510000000727414614231101015651 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ppca.R \name{ppca} \alias{ppca} \title{Probabilistic PCA} \usage{ ppca(Matrix, nPcs = 2, seed = NA, threshold = 1e-05, maxIterations = 1000, ...) } \arguments{ \item{Matrix}{\code{matrix} -- Data containing the variables in columns and observations in rows. The data may contain missing values, denoted as \code{NA}.} \item{nPcs}{\code{numeric} -- Number of components to estimate. The preciseness of the missing value estimation depends on the number of components, which should resemble the internal structure of the data.} \item{seed}{\code{numeric} Set the seed for the random number generator. PPCA creates fills the initial loading matrix with random numbers chosen from a normal distribution. Thus results may vary slightly. Set the seed for exact reproduction of your results.} \item{threshold}{Convergence threshold.} \item{maxIterations}{the maximum number of allowed iterations} \item{...}{Reserved for future use. Currently no further parameters are used.} } \value{ Standard PCA result object used by all PCA-based methods of this package. Contains scores, loadings, data mean and more. See \code{\link{pcaRes}} for details. } \description{ Implementation of probabilistic PCA (PPCA). PPCA allows to perform PCA on incomplete data and may be used for missing value estimation. This script was implemented after the Matlab version provided by Jakob Verbeek ( see \url{http://lear.inrialpes.fr/~verbeek/}) and the draft \emph{``EM Algorithms for PCA and Sensible PCA''} written by Sam Roweis. } \details{ Probabilistic PCA combines an EM approach for PCA with a probabilistic model. The EM approach is based on the assumption that the latent variables as well as the noise are normal distributed. In standard PCA data which is far from the training set but close to the principal subspace may have the same reconstruction error. PPCA defines a likelihood function such that the likelihood for data far from the training set is much lower, even if they are close to the principal subspace. This allows to improve the estimation accuracy. A method called \code{kEstimate} is provided to estimate the optimal number of components via cross validation. In general few components are sufficient for reasonable estimation accuracy. See also the package documentation for further discussion on what kind of data PCA-based missing value estimation is advisable. \bold{Complexity:}\cr Runtime is linear in the number of data, number of data dimensions and number of principal components. \bold{Convergence:} The threshold indicating convergence was changed from 1e-3 in 1.2.x to 1e-5 in the current version leading to more stable results. For reproducability you can set the seed (parameter seed) of the random number generator. If used for missing value estimation, results may be checked by simply running the algorithm several times with changing seed, if the estimated values show little variance the algorithm converged well. } \note{ Requires \code{MASS}. It is not recommended to use this function directely but rather to use the pca() wrapper function. } \examples{ ## Load a sample metabolite dataset with 5\\\% missing values (metaboliteData) data(metaboliteData) ## Perform probabilistic PCA using the 3 largest components result <- pca(t(metaboliteData), method="ppca", nPcs=3, seed=123) ## Get the estimated complete observations cObs <- completeObs(result) ## Plot the scores plotPcs(result, type = "scores") \dontshow{ stopifnot(sum((fitted(result) - t(metaboliteData))^2, na.rm=TRUE) < 200) } } \seealso{ \code{\link{bpca}, \link{svdImpute}, \link{prcomp}, \link{nipalsPca}, \link{pca}, \link{pcaRes}}. } \author{ Wolfram Stacklies } \keyword{multivariate} pcaMethods/man/predict-methods.Rd0000644000175100017510000000335314614231101020013 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{predict-methods} \alias{predict-methods} \alias{predict.pcaRes} \alias{predict,pcaRes-method} \title{Predict values from PCA.} \usage{ \method{predict}{pcaRes}(object, newdata, pcs = nP(object), pre = TRUE, post = TRUE, ...) \S4method{predict}{pcaRes}(object, newdata, pcs = nP(object), pre = TRUE, post = TRUE, ...) } \arguments{ \item{object}{\code{pcaRes} the \code{pcaRes} object of interest.} \item{newdata}{\code{matrix} new data with same number of columns as the used to compute \code{object}.} \item{pcs}{\code{numeric} The number of PC's to consider} \item{pre}{pre-process \code{newdata} based on the pre-processing chosen for the PCA model} \item{post}{unpre-process the final data (add the center back etc)} \item{...}{Not passed on anywhere, included for S3 consistency.} } \value{ A list with the following components: \item{scores}{The predicted scores} \item{x}{The predicted data} } \description{ Predict data using PCA model } \details{ This function extracts the predict values from a pcaRes object for the PCA methods SVD, Nipals, PPCA and BPCA. Newdata is first centered if the PCA model was and then scores (\eqn{T}) and data (\eqn{X}) is 'predicted' according to : \eqn{\hat{T}=X_{new}P}{That=XnewP} \eqn{\hat{X}_{new}=\hat{T}P'}{Xhat=ThatP'}. Missing values are set to zero before matrix multiplication to achieve NIPALS like treatment of missing values. } \examples{ data(iris) hidden <- sample(nrow(iris), 50) pcIr <- pca(iris[-hidden,1:4]) pcFull <- pca(iris[,1:4]) irisHat <- predict(pcIr, iris[hidden,1:4]) cor(irisHat$scores[,1], scores(pcFull)[hidden,1]) } \author{ Henning Redestig } \keyword{multivariate} pcaMethods/man/prep.Rd0000644000175100017510000000445614614231101015673 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/prep.R \name{prep} \alias{prep} \title{Pre-process a matrix for PCA} \usage{ prep(object, scale = c("none", "pareto", "vector", "uv"), center = TRUE, eps = 1e-12, simple = TRUE, reverse = FALSE, ...) } \arguments{ \item{object}{Numerical matrix (or an object coercible to such) with samples in rows and variables as columns. Also takes \code{ExpressionSet} in which case the transposed expression matrix is used.} \item{scale}{One of "UV" (unit variance \eqn{a=a/\sigma_{a}}) "vector" (vector normalisation \eqn{b=b/||b||}), "pareto" (sqrt UV) or "none" to indicate which scaling should be used to scale the matrix with \eqn{a} variables and \eqn{b} samples. Can also be a vector of scales which should be used to scale the matrix. \code{NULL} value is interpreted as \code{"none"}.} \item{center}{Either a logical which indicates if the matrix should be mean centred or not, or a vector with averages which should be suntracted from the matrix. \code{NULL} value is interpreted as \code{FALSE}} \item{eps}{Minimum variance, variable with lower variance are not scaled and warning is issued instead.} \item{simple}{Logical indicating if only the data should be returned or a list with the pre-processing statistics as well.} \item{reverse}{Logical indicating if matrix should be 'post-processed' instead by multiplying each column with its scale and adding the center. In this case, center and scale should be vectors with the statistics (no warning is issued if not, instead output becomes the same as input).} \item{...}{Only used for passing through arguments.} } \value{ A pre-processed matrix or a list with \item{center}{a vector with the estimated centers} \item{scale}{a vector with the estimated scales} \item{data}{the pre (or post) processed data} } \description{ Scaling and centering a matrix. } \details{ Does basically the same as \code{\link{scale}} but adds some alternative scaling options and functionality for treating pre-processing as part of a model. } \examples{ object <- matrix(rnorm(50), nrow=10) res <- prep(object, scale="uv", center=TRUE, simple=FALSE) obj <- prep(object, scale=res$scale, center=res$center) ## same as original sum((object - prep(obj, scale=res$scale, center=res$center, rev=TRUE))^2) } \author{ Henning Redestig } pcaMethods/man/Q2.Rd0000644000175100017510000000654714614231101015212 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xval.R \name{Q2} \alias{Q2} \title{Cross-validation for PCA} \usage{ Q2(object, originalData = completeObs(object), fold = 5, nruncv = 1, type = c("krzanowski", "impute"), verbose = interactive(), variables = 1:nVar(object), ...) } \arguments{ \item{object}{A \code{pcaRes} object (result from previous PCA analysis.)} \item{originalData}{The matrix (or ExpressionSet) that used to obtain the pcaRes object.} \item{fold}{The number of groups to divide the data in.} \item{nruncv}{The number of times to repeat the whole cross-validation} \item{type}{krzanowski or imputation type cross-validation} \item{verbose}{\code{boolean} If TRUE Q2 outputs a primitive progress bar.} \item{variables}{indices of the variables to use during cross-validation calculation. Other variables are kept as they are and do not contribute to the total sum-of-squares.} \item{...}{Further arguments passed to the \code{\link{pca}} function called within Q2.} } \value{ A matrix or vector with \eqn{Q^2} estimates. } \description{ Internal cross-validation can be used for estimating the level of structure in a data set and to optimise the choice of number of principal components. } \details{ This method calculates \eqn{Q^2} for a PCA model. This is the cross-validated version of \eqn{R^2} and can be interpreted as the ratio of variance that can be predicted independently by the PCA model. Poor (low) \eqn{Q^2} indicates that the PCA model only describes noise and that the model is unrelated to the true data structure. The definition of \eqn{Q^2} is: \deqn{Q^2=1 - \frac{\sum_{i}^{k}\sum_{j}^{n}(x - \hat{x})^2}{\sum_{i}^{k}\sum_{j}^{n}x^2}}{Q^2=1 - sum_i^k sum_j^n (x - \hat{x})^2 / \sum_i^k \sum_j^n(x^2)} for the matrix \eqn{x} which has \eqn{n} rows and \eqn{k} columns. For a given number of PC's x is estimated as \eqn{\hat{x}=TP'} (T are scores and P are loadings). Although this defines the leave-one-out cross-validation this is not what is performed if fold is less than the number of rows and/or columns. In 'impute' type CV, diagonal rows of elements in the matrix are deleted and the re-estimated. In 'krzanowski' type CV, rows are sequentially left out to build fold PCA models which give the loadings. Then, columns are sequentially left out to build fold models for scores. By combining scores and loadings from different models, we can estimate completely left out values. The two types may seem similar but can give very different results, krzanowski typically yields more stable and reliable result for estimating data structure whereas impute is better for evaluating missing value imputation performance. Note that since Krzanowski CV operates on a reduced matrix, it is not possible estimate Q2 for all components and the result vector may therefore be shorter than \code{nPcs(object)}. } \examples{ data(iris) x <- iris[,1:4] pcIr <- pca(x, nPcs=3) q2 <- Q2(pcIr, x) barplot(q2, main="Krzanowski CV", xlab="Number of PCs", ylab=expression(Q^2)) ## q2 for a single variable Q2(pcIr, x, variables=2) pcIr <- pca(x, nPcs=3, method="nipals") q2 <- Q2(pcIr, x, type="impute") barplot(q2, main="Imputation CV", xlab="Number of PCs", ylab=expression(Q^2)) } \references{ Krzanowski, WJ. Cross-validation in principal component analysis. Biometrics. 1987(43):3,575-584 } \author{ Henning Redestig, Ondrej Mikula } \keyword{multivariate} pcaMethods/man/R2cum-pcaRes-method.Rd0000644000175100017510000000104714614231101020377 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{R2cum,pcaRes-method} \alias{R2cum,pcaRes-method} \alias{R2cum} \title{Cumulative R2 is the total ratio of variance that is being explained by the model} \usage{ \S4method{R2cum}{pcaRes}(object, ...) } \arguments{ \item{object}{a \code{pcaRes} model} \item{...}{Not used} } \value{ Get the cumulative R2 } \description{ Cumulative R2 is the total ratio of variance that is being explained by the model } \author{ Henning Redestig } pcaMethods/man/R2VX-pcaRes-method.Rd0000644000175100017510000000144214614231101020147 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{R2VX,pcaRes-method} \alias{R2VX,pcaRes-method} \alias{R2VX} \title{R2 goodness of fit} \usage{ \S4method{R2VX}{pcaRes}(object, direction = c("variables", "observations", "complete"), data = completeObs(object), pcs = nP(object)) } \arguments{ \item{object}{a PCA model object} \item{direction}{choose between calculating R2 per variable, per observation or for the entire data with 'variables', 'observations' or 'complete'.} \item{data}{the data used to fit the model} \item{pcs}{the number of PCs to use to calculate R2} } \value{ A vector with R2 values } \description{ Flexible calculation of R2 goodness of fit. } \examples{ R2VX(pca(iris)) } \author{ Henning Redestig } pcaMethods/man/rediduals-methods.Rd0000644000175100017510000000216514614231101020335 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{rediduals-methods} \alias{rediduals-methods} \alias{residuals.pcaRes} \alias{residuals,pcaRes-method} \alias{resid,pcaRes-method} \title{Residuals values from a PCA model.} \usage{ \method{residuals}{pcaRes}(object, data = completeObs(object), ...) \S4method{residuals}{pcaRes}(object, data = completeObs(object), ...) \S4method{resid}{pcaRes}(object, data = completeObs(object), ...) } \arguments{ \item{object}{\code{pcaRes} the \code{pcaRes} object of interest.} \item{data}{\code{matrix} The data that was used to calculate the PCA model (or a different dataset to e.g. adress its proximity to the model).} \item{...}{Passed on to \code{\link{predict.pcaRes}}. E.g. setting the number of used components.} } \value{ A \code{matrix} with the residuals } \description{ This function extracts the residuals values from a pcaRes object for the PCA methods SVD, Nipals, PPCA and BPCA } \examples{ data(iris) pcIr <- pca(iris[,1:4]) head(residuals(pcIr, iris[,1:4])) } \author{ Henning Redestig } \keyword{multivariate} pcaMethods/man/repmat.Rd0000644000175100017510000000077314614231101016213 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/repmat.R \name{repmat} \alias{repmat} \title{Replicate and tile an array.} \usage{ repmat(mat, M, N) } \arguments{ \item{mat}{numeric matrix} \item{M}{number of copies in vertical direction} \item{N}{number of copies in horizontal direction} } \value{ Matrix consiting of M-by-N tiling copies of input matrix } \description{ Creates a large matrix B consisting of an M-by-N tiling of copies of A } \author{ Wolfram Stacklies } pcaMethods/man/RnipalsPca.Rd0000644000175100017510000000423114614231101016750 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/nipalsPca.R \name{RnipalsPca} \alias{RnipalsPca} \title{NIPALS PCA implemented in R} \usage{ RnipalsPca(Matrix, nPcs = 2, varLimit = 1, maxSteps = 5000, threshold = 1e-06, verbose = interactive(), ...) } \arguments{ \item{Matrix}{Pre-processed (centered, scaled) numerical matrix samples in rows and variables as columns.} \item{nPcs}{Number of components that should be extracted.} \item{varLimit}{Optionally the ratio of variance that should be explained. \code{nPcs} is ignored if varLimit < 1} \item{maxSteps}{Defines how many iterations can be done before algorithm should abort (happens almost exclusively when there were some wrong in the input data).} \item{threshold}{The limit condition for judging if the algorithm has converged or not, specifically if a new iteration is done if \eqn{(T_{old} - T)^T(T_{old} - T) > \code{limit}}.} \item{verbose}{Show simple progress information.} \item{...}{Only used for passing through arguments.} } \value{ A \code{pcaRes} object. } \description{ PCA by non-linear iterative partial least squares } \details{ Can be used for computing PCA on a numeric matrix using either the NIPALS algorithm which is an iterative approach for estimating the principal components extracting them one at a time. NIPALS can handle a small amount of missing values. It is not recommended to use this function directely but rather to use the pca() wrapper function. There is a C++ implementation given as \code{nipalsPca} which is faster. } \examples{ data(metaboliteData) mat <- prep(t(metaboliteData)) ## c++ version is faster system.time(pc <- RnipalsPca(mat, method="rnipals", nPcs=2)) system.time(pc <- nipalsPca(mat, nPcs=2)) ## better use pca() pc <- pca(t(metaboliteData), method="rnipals", nPcs=2) \dontshow{stopifnot(sum((fitted(pc) - t(metaboliteData))^2, na.rm=TRUE) < 200)} } \references{ Wold, H. (1966) Estimation of principal components and related models by iterative least squares. In Multivariate Analysis (Ed., P.R. Krishnaiah), Academic Press, NY, 391-420. } \seealso{ \code{prcomp}, \code{princomp}, \code{pca} } \author{ Henning Redestig } \keyword{multivariate} pcaMethods/man/robustPca.Rd0000644000175100017510000000632014614231101016657 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/robustPca.R \name{robustPca} \alias{robustPca} \title{PCA implementation based on robustSvd} \usage{ robustPca(Matrix, nPcs = 2, verbose = interactive(), ...) } \arguments{ \item{Matrix}{\code{matrix} -- Data containing the variables in columns and observations in rows. The data may contain missing values, denoted as \code{NA}.} \item{nPcs}{\code{numeric} -- Number of components to estimate. The preciseness of the missing value estimation depends on the number of components, which should resemble the internal structure of the data.} \item{verbose}{\code{boolean} Print some output to the command line if TRUE} \item{...}{Reserved for future use. Currently no further parameters are used} } \value{ Standard PCA result object used by all PCA-based methods of this package. Contains scores, loadings, data mean and more. See \code{\link{pcaRes}} for details. are used. } \description{ This is a PCA implementation robust to outliers in a data set. It can also handle missing values, it is however NOT intended to be used for missing value estimation. As it is based on robustSVD we will get an accurate estimation for the loadings also for incomplete data or for data with outliers. The returned scores are, however, affected by the outliers as they are calculated inputData X loadings. This also implies that you should look at the returned R2/R2cum values with caution. If the data show missing values, scores are caluclated by just setting all NA - values to zero. This is not expected to produce accurate results. Please have also a look at the manual page for \code{robustSvd}. Thus this method should mainly be seen as an attempt to integrate \code{robustSvd()} into the framework of this package. Use one of the other methods coming with this package (like PPCA or BPCA) if you want to do missing value estimation. It is not recommended to use this function directely but rather to use the pca() wrapper function. } \details{ The method is very similar to the standard \code{prcomp()} function. The main difference is that \code{robustSvd()} is used instead of the conventional \code{svd()} method. } \examples{ ## Load a complete sample metabolite data set and mean center the data data(metaboliteDataComplete) mdc <- scale(metaboliteDataComplete, center=TRUE, scale=FALSE) ## Now create 5\\\% of outliers. cond <- runif(length(mdc)) < 0.05; mdcOut <- mdc mdcOut[cond] <- 10 ## Now we do a conventional PCA and robustPca on the original and the data ## with outliers. ## We use center=FALSE here because the large artificial outliers would ## affect the means and not allow to objectively compare the results. resSvd <- pca(mdc, method="svd", nPcs=10, center=FALSE) resSvdOut <- pca(mdcOut, method="svd", nPcs=10, center=FALSE) resRobPca <- pca(mdcOut, method="robustPca", nPcs=10, center=FALSE) ## Now we plot the results for the original data against those with outliers ## We can see that robustPca is hardly effected by the outliers. plot(loadings(resSvd)[,1], loadings(resSvdOut)[,1]) plot(loadings(resSvd)[,1], loadings(resRobPca)[,1]) } \seealso{ \code{\link{robustSvd}, \link{svd}, \link{prcomp}, \link{pcaRes}}. } \author{ Wolfram Stacklies } \keyword{multivariate} pcaMethods/man/robustSvd.Rd0000644000175100017510000000620414614231101016711 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/robustPca.R \name{robustSvd} \alias{robustSvd} \title{Alternating L1 Singular Value Decomposition} \usage{ robustSvd(x) } \arguments{ \item{x}{A matrix whose SVD decomposition is to be computed. Missing values are allowed.} } \value{ The robust SVD of the matrix is x=u d v'. \item{d}{A vector containing the singular values of \code{x}.} \item{u}{A matrix whose columns are the left singular vectors of \code{x}.} \item{v}{A matrix whose columns are the right singular vectors of \code{x}.} } \description{ A robust approximation to the singular value decomposition of a rectangular matrix is computed using an alternating L1 norm (instead of the more usual least squares L2 norm). As the SVD is a least-squares procedure, it is highly susceptible to outliers and in the extreme case, an individual cell (if sufficiently outlying) can draw even the leading principal component toward itself. } \details{ See Hawkins et al (2001) for details on the robust SVD algorithm. Briefly, the idea is to sequentially estimate the left and right eigenvectors using an L1 (absolute value) norm minimization. Note that the robust SVD is able to accomodate missing values in the matrix \code{x}, unlike the usual \code{svd} function. Also note that the eigenvectors returned by the robust SVD algorithm are NOT (in general) orthogonal and the eigenvalues need not be descending in order. } \note{ Two differences from the usual SVD may be noted. One relates to orthogonality. In the conventional SVD, all the eigenvectors are orthogonal even if not explicitly imposed. Those returned by the AL1 algorithm (used here) are (in general) not orthogonal. Another difference is that, in the L2 analysis of the conventional SVD, the successive eigen triples (eigenvalue, left eigenvector, right eigenvector) are found in descending order of eigenvalue. This is not necessarily the case with the AL1 algorithm. Hawkins et al (2001) note that a larger eigen value may follow a smaller one. } \examples{ ## Load a complete sample metabolite data set and mean center the data data(metaboliteDataComplete) mdc <- prep(metaboliteDataComplete, center=TRUE, scale="none") ## Now create 5\% of outliers. cond <- runif(length(mdc)) < 0.05; mdcOut <- mdc mdcOut[cond] <- 10 ## Now we do a conventional SVD and a robustSvd on both, the original and the ## data with outliers. resSvd <- svd(mdc) resSvdOut <- svd(mdcOut) resRobSvd <- robustSvd(mdc) resRobSvdOut <- robustSvd(mdcOut) ## Now we plot the results for the original data against those with outliers ## We can see that robustSvd is hardly affected by the outliers. plot(resSvd$v[,1], resSvdOut$v[,1]) plot(resRobSvd$v[,1], resRobSvdOut$v[,1]) } \references{ Hawkins, Douglas M, Li Liu, and S Stanley Young (2001) Robust Singular Value Decomposition, National Institute of Statistical Sciences, Technical Report Number 122. \url{http://www.niss.org/technicalreports/tr122.pdf} } \seealso{ \code{\link{svd}}, \code{\link[ade4:nipals]{nipals}} for an alternating L2 norm method that also accommodates missing data. } \author{ Kevin Wright, modifications by Wolfram Stacklies } \keyword{algebra} pcaMethods/man/scaled-pcaRes-method.Rd0000644000175100017510000000072614614231101020645 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{scaled,pcaRes-method} \alias{scaled,pcaRes-method} \alias{scaled} \title{Check if scaling was part of the PCA model} \usage{ scaled(object, ...) } \arguments{ \item{object}{pcaRes object} \item{...}{Not used} } \value{ TRUE if scaling was part of the PCA model } \description{ Check if scaling was part of the PCA model } \author{ Henning Redestig } pcaMethods/man/scl-pcaRes-method.Rd0000644000175100017510000000101014614231101020156 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{scl,pcaRes-method} \alias{scl,pcaRes-method} \alias{scl} \title{Get the scales (e.g. standard deviations) of the original variables} \usage{ scl(object, ...) } \arguments{ \item{object}{pcaRes object} \item{...}{Not used} } \value{ Vector with the scales } \description{ Get the scales (e.g. standard deviations) of the original variables } \seealso{ \code{\link{prep}} } \author{ Henning Redestig } pcaMethods/man/scores-pcaRes-method.Rd0000644000175100017510000000075214614231101020707 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{scores,pcaRes-method} \alias{scores,pcaRes-method} \alias{scores} \title{Get scores from a pcaRes object} \usage{ \S4method{scores}{pcaRes}(object, ...) } \arguments{ \item{object}{a pcaRes object} \item{...}{not used} } \value{ The scores as a matrix } \description{ Get scores from a pcaRes object } \seealso{ \code{\link{scores.pcaRes}} } \author{ Henning Redestig } pcaMethods/man/scores.pcaRes.Rd0000644000175100017510000000062114614231101017425 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \name{scores.pcaRes} \alias{scores.pcaRes} \title{Get scores from a pcaRes object} \usage{ \method{scores}{pcaRes}(object, ...) } \arguments{ \item{object}{a pcaRes object} \item{...}{not used} } \value{ The scores as a matrix } \description{ Get scores from a pcaRes object } \author{ Henning Redestig } pcaMethods/man/sDev-pcaRes-method.Rd0000644000175100017510000000077314614231101020315 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{sDev,pcaRes-method} \alias{sDev,pcaRes-method} \alias{sDev} \title{Get the standard deviations of the scores (indicates their relevance)} \usage{ sDev(object, ...) } \arguments{ \item{object}{pcaRes object} \item{...}{Not used} } \value{ Standard devations of the scores } \description{ Get the standard deviations of the scores (indicates their relevance) } \author{ Henning Redestig } pcaMethods/man/show-methods.Rd0000644000175100017510000000122114614231101017331 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{show-methods} \alias{show-methods} \alias{showPcaRes} \alias{print,pcaRes-method} \alias{print,nniRes-method} \alias{show,pcaRes-method} \alias{show,nniRes-method} \title{Print/Show for pcaRes} \usage{ showPcaRes(x, ...) \S4method{print}{pcaRes}(x, ...) \S4method{show}{pcaRes}(object) } \arguments{ \item{x}{a pcaRes object} \item{...}{not used} \item{object}{the object to print information about} } \value{ nothing, used for its side effect } \description{ Print basic information about pcaRes object } \author{ Henning Redestig } pcaMethods/man/showNniRes.Rd0000644000175100017510000000060214614231101017011 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-nniRes.R \name{showNniRes} \alias{showNniRes} \title{Print a nniRes model} \usage{ showNniRes(x, ...) } \arguments{ \item{x}{An \code{nniRes} object} \item{...}{Not used} } \value{ Nothing, used for side-effect } \description{ Print a brief description of nniRes model } \author{ Henning Redestig } pcaMethods/man/simpleEllipse.Rd0000644000175100017510000000156314614231101017530 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/pca.R \name{simpleEllipse} \alias{simpleEllipse} \title{Hotelling's T^2 Ellipse} \usage{ simpleEllipse(x, y, alfa = 0.95, len = 200) } \arguments{ \item{x}{first variable} \item{y}{second variable} \item{alfa}{confidence level of the circle} \item{len}{Number of points in the circle} } \value{ A matrix with X and Y coordinates for the circle } \description{ Get a confidence ellipse for uncorrelated bivariate data } \details{ As described in 'Introduction to multi and megavariate data analysis using PCA and PLS' by Eriksson et al. This produces very similar ellipse as compared to the ellipse function the ellipse package except that this function assumes that and y are uncorrelated (which they of are if they are scores or loadings from a PCA). } \seealso{ ellipse } \author{ Henning Redestig } pcaMethods/man/slplot-pcaRes-method.Rd0000644000175100017510000000340614614231101020725 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{slplot,pcaRes-method} \alias{slplot,pcaRes-method} \alias{slplot} \title{Side by side scores and loadings plot} \usage{ slplot(object, pcs=c(1,2), scoresLoadings=c(TRUE, TRUE), sl="def", ll="def", hotelling=0.95, rug=TRUE, sub=NULL,...) } \arguments{ \item{object}{a pcaRes object} \item{pcs}{which two pcs to plot} \item{scoresLoadings}{Which should be shown scores and or loadings} \item{sl}{labels to plot in the scores plot} \item{ll}{labels to plot in the loadings plot} \item{hotelling}{confidence interval for ellipse in the score plot} \item{rug}{logical, rug x axis in score plot or not} \item{sub}{Subtitle, defaults to annotate with amount of explained variance.} \item{...}{Further arguments to plot functions. Prefix arguments to \code{par()} with 's' for the scores plot and 'l' for the loadings plot. I.e. cex become scex for setting character expansion in the score plot and lcex for the loadings plot.} } \value{ None, used for side effect. } \description{ A common way of visualizing two principal components } \details{ This method is meant to be used as a quick way to visualize results, if you want a more specific plot you probably want to get the scores, loadings with \code{scores(object)}, \code{loadings(object)} and then design your own plotting method. } \note{ Uses layout instead of par to provide side-by-side so it works with Sweave (but can not be combined with \code{par(mfrow=..))} } \examples{ data(iris) pcIr <- pca(iris[,1:4], scale="uv") slplot(pcIr, sl=NULL, spch=5) slplot(pcIr, sl=NULL, lcex=1.3, scol=as.integer(iris[,5])) } \seealso{ \code{\link{pca}}, \code{\link{biplot}} } \author{ Henning Redestig } \keyword{multivariate} pcaMethods/man/sortFeatures.Rd0000644000175100017510000000070514614231101017404 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/sortFeatures.R \name{sortFeatures} \alias{sortFeatures} \title{Sort the features of NLPCA object} \usage{ sortFeatures(nlnet, trainIn, trainOut) } \arguments{ \item{nlnet}{The nlnet} \item{trainIn}{Training data in} \item{trainOut}{Training data after it passed through the net} } \value{ ... } \description{ Sort the features of NLPCA object } \author{ Henning Redestig } pcaMethods/man/summary.Rd0000644000175100017510000000070214614231101016410 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \name{summary} \alias{summary} \alias{summary.pcaRes} \alias{summary,pcaRes-method} \title{Summary of PCA model} \usage{ \method{summary}{pcaRes}(object, ...) } \arguments{ \item{object}{a pcaRes object} \item{...}{Not used} } \value{ Nothing, used for side-effect } \description{ Print a brief description of the PCA model } \author{ Henning Redestig } pcaMethods/man/svdImpute.Rd0000644000175100017510000000602414614231101016676 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/svdImpute.R \name{svdImpute} \alias{svdImpute} \title{SVDimpute algorithm} \usage{ svdImpute(Matrix, nPcs = 2, threshold = 0.01, maxSteps = 100, verbose = interactive(), ...) } \arguments{ \item{Matrix}{\code{matrix} -- Pre-processed (centered, scaled) data with variables in columns and observations in rows. The data may contain missing values, denoted as \code{NA}.} \item{nPcs}{\code{numeric} -- Number of components to estimate. The preciseness of the missing value estimation depends on the number of components, which should resemble the internal structure of the data.} \item{threshold}{The iteration stops if the change in the matrix falls below this threshold.} \item{maxSteps}{Maximum number of iteration steps.} \item{verbose}{Print some output if TRUE.} \item{...}{Reserved for parameters used in future version of the algorithm} } \value{ Standard PCA result object used by all PCA-based methods of this package. Contains scores, loadings, data mean and more. See \code{\link{pcaRes}} for details. } \description{ This implements the SVDimpute algorithm as proposed by Troyanskaya et al, 2001. The idea behind the algorithm is to estimate the missing values as a linear combination of the \code{k} most significant eigengenes. } \details{ Missing values are denoted as \code{NA}. It is not recommended to use this function directely but rather to use the pca() wrapper function. As SVD can only be performed on complete matrices, all missing values are initially replaced by 0 (what is in fact the mean on centred data). The algorithm works iteratively until the change in the estimated solution falls below a certain threshold. Each step the eigengenes of the current estimate are calculated and used to determine a new estimate. Eigengenes denote the loadings if pca is performed considering variable (for Microarray data genes) as observations. An optimal linear combination is found by regressing the incomplete variable against the \code{k} most significant eigengenes. If the value at position \code{j} is missing, the \eqn{j^th}{j^th} value of the eigengenes is not used when determining the regression coefficients. } \note{ Each iteration, standard PCA (\code{prcomp}) needs to be done for each incomplete variable to get the eigengenes. This is usually fast for small data sets, but complexity may rise if the data sets become very large. } \examples{ ## Load a sample metabolite dataset with 5\\\% missing values data(metaboliteData) ## Perform svdImpute using the 3 largest components result <- pca(metaboliteData, method="svdImpute", nPcs=3, center = TRUE) ## Get the estimated complete observations cObs <- completeObs(result) ## Now plot the scores plotPcs(result, type = "scores") } \references{ Troyanskaya O. and Cantor M. and Sherlock G. and Brown P. and Hastie T. and Tibshirani R. and Botstein D. and Altman RB. - Missing value estimation methods for DNA microarrays. \emph{Bioinformatics. 2001 Jun;17(6):520-5.} } \author{ Wolfram Stacklies } \keyword{multivariate} pcaMethods/man/svdPca.Rd0000644000175100017510000000260514614231101016137 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/pca.R \name{svdPca} \alias{svdPca} \title{Perform principal component analysis using singular value decomposition} \usage{ svdPca(Matrix, nPcs = 2, varLimit = 1, verbose = interactive(), ...) } \arguments{ \item{Matrix}{Pre-processed (centered and possibly scaled) numerical matrix samples in rows and variables as columns. No missing values allowed.} \item{nPcs}{Number of components that should be extracted.} \item{varLimit}{Optionally the ratio of variance that should be explained. \code{nPcs} is ignored if varLimit < 1} \item{verbose}{Verbose complaints to matrix structure} \item{...}{Only used for passing through arguments.} } \value{ A \code{pcaRes} object. } \description{ A wrapper function for \code{prcomp} to deliver the result as a \code{pcaRes} method. Supplied for compatibility with the rest of the pcaMethods package. It is not recommended to use this function directely but rather to use the \code{pca()} wrapper function. } \examples{ data(metaboliteDataComplete) mat <- prep(t(metaboliteDataComplete)) pc <- svdPca(mat, nPcs=2) ## better use pca() pc <- pca(t(metaboliteDataComplete), method="svd", nPcs=2) \dontshow{stopifnot(sum((fitted(pc) - t(metaboliteDataComplete))^2, na.rm=TRUE) < 200)} } \seealso{ \code{prcomp}, \code{princomp}, \code{pca} } \author{ Henning Redestig } \keyword{multivariate} pcaMethods/man/tempFixNas.Rd0000644000175100017510000000063414614231101016775 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/xval.R \name{tempFixNas} \alias{tempFixNas} \title{Temporary fix for missing values} \usage{ tempFixNas(mat) } \arguments{ \item{mat}{a matrix} } \value{ The original matrix with completely missing rows/cols filled with zeroes. } \description{ Simply replace completely missing rows or cols with zeroes. } \author{ Henning Redestig } pcaMethods/man/vector2matrices-matrix-method.Rd0000644000175100017510000000100214614231101022601 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/vector2matrices.R \docType{methods} \name{vector2matrices,matrix-method} \alias{vector2matrices,matrix-method} \title{Tranform the vectors of weights to matrix structure} \usage{ \S4method{vector2matrices}{matrix}(object, net) } \arguments{ \item{object}{an nlpcaNet} \item{net}{the neural network} } \value{ weights in matrix structure } \description{ Tranform the vectors of weights to matrix structure } \author{ Henning Redestig } pcaMethods/man/vector2matrices-nlpcaNet-method.Rd0000644000175100017510000000074314614231101023054 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/vector2matrices.R \docType{methods} \name{vector2matrices,nlpcaNet-method} \alias{vector2matrices,nlpcaNet-method} \title{Tranform the vectors of weights to matrix structure} \usage{ \S4method{vector2matrices}{nlpcaNet}(object) } \arguments{ \item{object}{an nlpcaNet} } \value{ weights in matrix structure } \description{ Tranform the vectors of weights to matrix structure } \author{ Henning Redestig } pcaMethods/man/wasna-pcaRes-method.Rd0000644000175100017510000000144014614231101020515 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/methods-pcaRes.R \docType{methods} \name{wasna,pcaRes-method} \alias{wasna,pcaRes-method} \alias{wasna} \title{Get a matrix with indicating the elements that were missing in the input data. Convenient for estimating imputation performance.} \usage{ wasna(object, ...) } \arguments{ \item{object}{pcaRes object} \item{...}{Not used} } \value{ A matrix with logicals } \description{ Get a matrix with indicating the elements that were missing in the input data. Convenient for estimating imputation performance. } \examples{ data(metaboliteData) data(metaboliteDataComplete) result <- pca(metaboliteData, nPcs=2) plot(completeObs(result)[wasna(result)], metaboliteDataComplete[wasna(result)]) } \author{ Henning Redestig } pcaMethods/man/weightsAccount.Rd0000644000175100017510000000106014614231101017700 0ustar00biocbuildbiocbuild% Generated by roxygen2: do not edit by hand % Please edit documentation in R/AllClasses.R \name{weightsAccount} \alias{weightsAccount} \title{Create an object that holds the weights for nlpcaNet. Holds and sets weights in using an environment object.} \usage{ weightsAccount(w) } \arguments{ \item{w}{\code{matrix} -- New weights} } \value{ A weightsAccound with \code{set} and \code{current} functions. } \description{ Create an object that holds the weights for nlpcaNet. Holds and sets weights in using an environment object. } \author{ Henning Redestig } pcaMethods/NAMESPACE0000644000175100017510000000236214614231101015074 0ustar00biocbuildbiocbuild# Generated by roxygen2: do not edit by hand S3method(biplot,pcaRes) S3method(dim,pcaRes) S3method(fitted,pcaRes) S3method(loadings,pcaRes) S3method(plot,pcaRes) S3method(predict,pcaRes) S3method(residuals,pcaRes) S3method(scores,pcaRes) S3method(summary,pcaRes) export(Q2) export(RnipalsPca) export(asExprSet) export(bpca) export(checkData) export(cvseg) export(kEstimate) export(kEstimateFast) export(listPcaMethods) export(llsImpute) export(nipalsPca) export(nlpca) export(nni) export(pca) export(plotPcs) export(ppca) export(prep) export(robustPca) export(robustSvd) export(showNniRes) export(showPcaRes) export(svdImpute) export(svdPca) exportClasses(nlpcaNet) exportClasses(nniRes) exportClasses(pcaRes) exportMethods(DModX) exportMethods(R2VX) exportMethods(R2cum) exportMethods(center) exportMethods(centered) exportMethods(completeObs) exportMethods(cvstat) exportMethods(leverage) exportMethods(loadings) exportMethods(method) exportMethods(nObs) exportMethods(nP) exportMethods(nPcs) exportMethods(nVar) exportMethods(nmissing) exportMethods(sDev) exportMethods(scaled) exportMethods(scl) exportMethods(scores) exportMethods(slplot) exportMethods(wasna) import(Biobase) import(BiocGenerics) import(methods) importFrom(Rcpp,evalCpp) useDynLib(pcaMethods) pcaMethods/R/0000755000175100017510000000000014614231101014053 5ustar00biocbuildbiocbuildpcaMethods/R/AllClasses.R0000644000175100017510000003074414614231101016234 0ustar00biocbuildbiocbuild##' @include errorHierarchic.R ##' @include derrorHierarchic.R NULL ##' This is a class representation of a non-linear PCA neural ##' network. The \code{nlpcaNet} class is not meant for user-level ##' usage. ##' ##' Creating Objects ##' ##' \code{new("nlpcaNet", net=[the network structure], ##' hierarchic=[hierarchic design], ##' fct=[the functions at each layer], fkt=[the functions used for ##' forward propagation], weightDecay=[incremental decrease of weight ##' changes over iterations (between 0 and 1)], featureSorting=[sort ##' features or not], dataDist=[represents the present values], ##' inverse=[net is inverse mode or not], fCount=[amount of times ##' features were sorted], componentLayer=[which layer is the ##' 'bottleneck' (principal components)], ##' erro=[the used error function], gradient=[the used gradient method], ##' weights=[the present weights], ##' maxIter=[the amount of iterations that was done], scalingFactor=[the ##' scale of the original matrix])} ##' ##' Slots ##' ##' \describe{ ##' \item{net}{"matrix", matrix showing the representation of the ##' neural network, e.g. (2,4,6) for a network with two features, a ##' hidden layer and six output neurons (original variables).} ##' \item{hierarchic}{"list", the hierarchic design of the network, ##' holds 'idx' (), 'var' () and layer (which layer is the principal ##' component layer).} ##' \item{fct}{"character", a vector naming the functions that will be ##' applied on each layer. "linr" is linear (i.e.) standard matrix ##' products and "tanh" means that the arcus tangens is applied on the ##' result of the matrix product (for non-linearity).} ##' \item{fkt}{"character", same as fct but the functions used during ##' back propagation.} ##' \item{weightDecay}{"numeric", the value that is used to ##' incrementally decrease the weight changes to ensure convergence.} ##' \item{featureSorting}{"logical", indicates if features will be ##' sorted or not. This is used to make the NLPCA assume properties ##' closer to those of standard PCA were the first component is more ##' important for reconstructing the data than the second component.} ##' \item{dataDist}{"matrix", a matrix of ones and zeroes indicating ##' which values will add to the errror.} ##' \item{inverse}{"logical", network is inverse mode (currently only ##' inverse is supported) or not. Eg. the case when we have truly ##' missing values and wish to impute them.} ##' \item{fCount}{"integer", Counter for the amount of times features ##' were really sorted.} ##' \item{componentLayer}{"numeric", the index of 'net' that is the ##' component layer.} ##' \item{error}{"function", the used error function. Currently only one ##' is provided \code{errorHierarchic}.} ##' \item{gradient}{"function", the used gradient function. Currently ##' only one is provided \code{derrorHierarchic}} ##' \item{weights}{"list", A list holding managements of the ##' weights. The list has two functions, weights$current() and ##' weights$set() which access a matrix in the local environment of ##' this object.} ##' \item{maxIter}{"integer", the amount of iterations used to train ##' this network.} ##' \item{scalingFactor}{"numeric", training the network is best made ##' with 'small' values so the original data is scaled down to a ##' suitable range by division with this number.}} ##' ##' Methods ##' ##' \describe{ \item{vector2matrices}{Returns the ##' weights in a matrix representation.} } ##' @title Class representation of the NLPCA neural net ##' @docType class ##' @aliases nlpcaNet nlpcaNet-class ##' @seealso \code{\link{nlpca}} ##' @aliases nFit nFit-class ##' @exportClass nlpcaNet ##' @keywords classes ##' @name pcaNet ##' @author Henning Redestig setClass("nlpcaNet", representation(net="matrix", hierarchic="list", fct="character", fkt="character", weightDecay="numeric", featureSorting="logical", dataDist="matrix", inverse="logical", fCount="integer", componentLayer="integer", error="function", gradient="function", weights="list", maxIter="integer", scalingFactor="numeric"), prototype(net=rbind(c(4,6,2,6,4)), hierarchic=list(var=rbind(c(1,1,0.01)), layer=3, idx=rbind(c(1,1,0),c(0,1,1))), fct=c("linr", "tanh", "linr", "tanh", "linr"), fkt=c("tanh", "linr", "tanh", "linr"), weightDecay=0.001, featureSorting=TRUE, inverse=FALSE, dataDist=NULL, fCount=as.integer(0), componentLayer=as.integer(3), error=errorHierarchic, gradient=derrorHierarchic, weights=NULL, maxIter=as.integer(1200), scalingFactor=NULL)) setAs("NULL", "nlpcaNet", function(from, to){ new(to) }) ##' This is a class representation of a PCA result ##' ##' \bold{Creating Objects}\cr ##' \code{new("pcaRes", scores=[the scores], loadings=[the loadings], ##' nPcs=[amount of PCs], R2cum=[cumulative R2], nObs=[amount of ##' observations], nVar=[amount of variables], R2=[R2 for each ##' individual PC], sDev=[stdev for each individual PC], ##' centered=[was data centered], center=[original means], ##' varLimit=[what variance limit was exceeded], method=[method used to ##' calculate PCA], missing=[amount of NAs], ##' completeObs=[estimated complete observations])} ##' ##' \bold{Slots}\cr ##' \describe{ ##' \item{scores}{"matrix", the calculated scores} ##' \item{loadings}{"matrix", the calculated loadings} ##' \item{R2cum}{"numeric", the cumulative R2 values} ##' \item{sDev}{"numeric", the individual standard ##' deviations of the score vectors} ##' \item{R2}{"numeric", the individual R2 values} ##' \item{cvstat}{"numeric", cross-validation statistics} ##' \item{nObs}{"numeric", number of observations} ##' \item{nVar}{"numeric", number of variables} ##' \item{centered}{"logical", data was centered or not} ##' \item{center}{"numeric", the original variable centers} ##' \item{scaled}{"logical", data was scaled or not} ##' \item{scl}{"numeric", the original variable scales} ##' \item{varLimit}{"numeric", the exceeded variance limit} ##' \item{nPcs,nP}{"numeric", the number of calculated PCs} ##' \item{method}{"character", the method used to perform PCA} ##' \item{missing}{"numeric", the total amount of missing values in ##' original data} ##' \item{completeObs}{"matrix", the estimated complete observations} ##' \item{network}{"nlpcaNet", the network used by non-linear PCA} ##' } ##' ##' \bold{Methods (not necessarily exhaustive)}\cr ##' \describe{ ##' \item{print}{Print function} ##' \item{summary}{Extract information about PC relevance} ##' \item{screeplot}{Plot a barplot of standard deviations for PCs} ##' \item{slplot}{Make a side by side score and loadings plot} ##' \item{nPcs}{Get the number of PCs} ##' \item{nObs}{Get the number of observations} ##' \item{cvstat}{Cross-validation statistics} ##' \item{nVar}{Get the number of variables} ##' \item{loadings}{Get the loadings} ##' \item{scores}{Get the scores} ##' \item{dim}{Get the dimensions (number of observations, number of ##' features)} ##' \item{centered}{Get a logical indicating if centering was done as ##' part of the model} ##' \item{center}{Get the averages of the original variables.} ##' \item{completeObs}{Get the imputed data set} ##' \item{method}{Get a string naming the used PCA method} ##' \item{sDev}{Get the standard deviations of the PCs} ##' \item{scaled}{Get a logical indicating if scaling was done as ##' part of the model} ##' \item{scl}{Get the scales of the original variablesb} ##' \item{R2cum}{Get the cumulative R2} ##' } ##' @title Class for representing a PCA result ##' @keywords classes ##' @exportClass pcaRes ##' @docType class ##' @name pcaRes ##' @aliases pcaRes pcaRes-class ##' @author Henning Redestig setClass("pcaRes", representation(completeObs="matrix", scores="matrix", loadings="matrix", R2cum="numeric", R2="numeric", # ditch, get from R2cum cvstat="numeric", # ditch, get from R2cum sDev="numeric", # ditch, get from scores nObs="numeric", # ditch, get from scores nVar="numeric", centered="logical", center="numeric", subset="numeric", scaled="character", scale="numeric", varLimit="numeric", # ditch, useless nPcs="numeric", # ditch, get from scores method="character", missing="matrix", network="nlpcaNet"), prototype(completeObs=NULL, scores=NULL, loadings=NULL, R2cum=NULL, R2=NULL, subset=NULL, cvstat=NULL, sDev=NULL, nObs=NULL, nVar=NULL, centered=NULL, center=NULL, scaled=NULL, scale=NULL, varLimit=NULL, nPcs=NULL, method=NULL, missing=NULL, network=NULL)) setAs("NULL", "pcaRes", function(from, to){ new(to) }) ##' This is a class representation of nearest neighbour imputation ##' (nni) result ##' ##' \bold{Creating Objects}\cr ##' \code{new("nniRes", completeObs=[the estimated complete ##' observations], k=[cluster size], nObs=[amount of observations], ##' nVar=[amount of variables], centered=[was the data centered befor ##' running LLSimpute], center=[original means], method=[method used ##' to perform clustering], missing=[amount of NAs])} ##' ##' \bold{Slots}\cr ##' \describe{ ##' \item{completeObs}{"matrix", the estimated complete observations} ##' \item{nObs}{"numeric", amount of observations} ##' \item{nVar}{"numeric", amount of variables} ##' \item{correlation}{"character", the correlation method used ##' (pearson, kendall or spearman)} ##' \item{centered}{"logical", data was centered or not} ##' \item{center}{"numeric", the original variable centers} ##' \item{k}{"numeric", cluster size} ##' \item{method}{"character", the method used to perform the clustering} ##' \item{missing}{"numeric", the total amount of missing values in ##' original data} ##' } ##' ##' \bold{Methods}\cr ##' \describe{ \item{print}{Print function} } ##' @title Class for representing a nearest neighbour imputation result ##' @docType class ##' @exportClass nniRes ##' @name nniRes ##' @keywords classes ##' @aliases nniRes nniRes-class ##' @author Wolfram Stacklies setClass("nniRes", representation(completeObs="matrix", nObs="numeric", nVar="numeric", centered="logical", center="numeric", k="numeric", method="character", correlation="character", missing="numeric"), prototype(completeObs=NULL, nObs=NULL, nVar=NULL, centered=NULL, center=NULL, k=NULL, method=NULL, correlation=NULL, missing=NULL)) setAs("NULL", "nniRes", function(from, to) { new(to) }) ##' Create an object that holds the weights for nlpcaNet. Holds and ##' sets weights in using an environment object. ##' @param w \code{matrix} -- New weights ##' @return A weightsAccound with \code{set} and \code{current} ##' functions. ##' @author Henning Redestig weightsAccount <- function(w) { list( set = function(newWeights) { if(!inherits(newWeights, "matrix")) stop("The weights must inherit from matrix") w <<- newWeights }, current = function() { w } ) } pcaMethods/R/AllGenerics.R0000644000175100017510000000456514614231101016400 0ustar00biocbuildbiocbuildsetGeneric("vector2matrices", function(object, ...) standardGeneric("vector2matrices")) ##' @exportMethod leverage setGeneric("leverage", function(object, ...) standardGeneric("leverage")) ##' @exportMethod DModX setGeneric("DModX", function(object, dat, newdata=FALSE, type=c("normalized","absolute"), ...) standardGeneric("DModX")) ##' @exportMethod nP setGeneric("nP", function(object, ...) standardGeneric("nP")) ##' @exportMethod cvstat setGeneric("cvstat", function(object, ...) standardGeneric("cvstat")) ##' @exportMethod nPcs setGeneric("nPcs", function(object, ...) standardGeneric("nPcs")) ##' @exportMethod nObs setGeneric("nObs", function(object, ...) standardGeneric("nObs")) ##' @exportMethod nVar setGeneric("nVar", function(object, ...) standardGeneric("nVar")) ##' @exportMethod centered setGeneric("centered", function(object, ...) standardGeneric("centered")) ##' @exportMethod center setGeneric("center", function(object, ...) standardGeneric("center")) ##' @exportMethod completeObs setGeneric("completeObs", function(object, ...) standardGeneric("completeObs")) ##' @exportMethod method setGeneric("method", function(object, ...) standardGeneric("method")) ##' @exportMethod nmissing setGeneric("nmissing", function(object, ...) standardGeneric("nmissing")) ##' @exportMethod wasna setGeneric("wasna", function(object, ...) standardGeneric("wasna")) ##' @exportMethod sDev setGeneric("sDev", function(object, ...) standardGeneric("sDev")) ##' @exportMethod scaled setGeneric("scaled", function(object, ...) standardGeneric("scaled")) ##' @exportMethod scl setGeneric("scl", function(object, ...) standardGeneric("scl")) ##' @exportMethod R2cum setGeneric("R2cum", function(object, ...) standardGeneric("R2cum")) ##' @exportMethod slplot setGeneric("slplot", function(object, pcs=c(1,2), scoresLoadings=c(TRUE, TRUE), sl="def", ll="def", hotelling=0.95, rug=TRUE, sub=NULL,...) standardGeneric("slplot")) ##' @exportMethod scores setGeneric("scores", function(object, ...) standardGeneric("scores")) ##' @exportMethod loadings setGeneric("loadings", function(object, ...) standardGeneric("loadings")) ##' @exportMethod R2VX setGeneric("R2VX", function(object, ...) standardGeneric("R2VX")) ## @exportMethod prep #setGeneric("prep", function(object, ...) standardGeneric("prep")) pcaMethods/R/BPCA_dostep.R0000644000175100017510000000543714614231101016272 0ustar00biocbuildbiocbuild##' The function contains the actual implementation of the BPCA ##' component estimation. It performs one step of the BPCA EM ##' algorithm. It is called 'maxStep' times from within the main loop ##' in BPCAestimate. ##' ##' This function is NOT intended to be run standalone. ##' @title Do BPCA estimation step ##' @param M Data structure containing all needed information. See the ##' source documentation of BPCA_initmodel for details ##' @param y Numeric original data matrix ##' @return Updated version of the data structure ##' @author Wolfram Stacklies BPCA_dostep <- function(M,y) { ## Empty matrix in which the scores are copied M$scores <- matrix(NA, M$rows, M$comps) ## Expectation step for data without missing values Rx <- diag(M$comps) + M$tau * t(M$PA) %*% M$PA + M$SigW Rxinv <- solve(Rx) idx <- M$row_nomiss if (length(idx) == 0) { trS <- 0 T <- 0 } else { dy <- y[idx,, drop=FALSE] - repmat(M$mean, length(idx), 1) x <- M$tau * Rxinv %*% t(M$PA) %*% t(dy) T <- t(dy) %*% t(x) trS <- sum(sum(dy * dy)) ## Assign the scores for complete rows xTranspose <- t(x) for (i in 1:length(idx)) { M$scores[idx[i],] <- xTranspose[i,] } } ## Expectation step for incomplete data if( length(M$row_miss) > 0) { for(n in 1:length(M$row_miss)) { i <- M$row_miss[n] dyo <- y[ i, !M$nans[i,], drop=FALSE] - M$mean[ !M$nans[i,], drop=FALSE] Wm <- M$PA[ M$nans[i,],, drop=FALSE] Wo <- M$PA[ !M$nans[i,],, drop=FALSE] Rxinv <- solve( (Rx - M$tau * t(Wm) %*% Wm)) ex <- M$tau * t(Wo) %*% t(dyo) x <- Rxinv %*% ex dym <- Wm %*% x dy <- y[i,, drop=FALSE] dy[ !M$nans[i,] ] <- t(dyo) dy[ M$nans[i,] ] <- t(dym) M$yest[i,] <- dy + M$mean T <- T + t(dy) %*% t(x) T[ M$nans[i,], ] <- T[ M$nans[i,],, drop=FALSE] + Wm %*% Rxinv trS <- trS + dy %*% t(dy) + sum(M$nans[i,]) / M$tau + sum( diag(Wm %*% Rxinv %*% t(Wm)) ) trS <- trS[1,1] ## Assign the scores for rows containing missing values M$scores[M$row_miss[n],] <- t(x) } } T <- T / M$rows trS <- trS / M$rows ## Maximation step Rxinv <- solve(Rx) Dw <- Rxinv + M$tau * t(T) %*% M$PA %*% Rxinv + diag(M$alpha, nrow = length(M$alpha)) / M$rows Dwinv <- solve(Dw) M$PA <- T %*% Dwinv ## The new estimate of the principal axes (loadings) M$tau <- (M$cols + 2 * M$gtau0 / M$rows) / (trS - sum(diag(t(T) %*% M$PA)) + (M$mean %*% t(M$mean) * M$gmu0 + 2 * M$gtau0 / M$btau0) / M$rows) M$tau <- M$tau[1,1] ## convert to scalar M$SigW <- Dwinv * (M$cols / M$rows) M$alpha <- (2 * M$galpha0 + M$cols) / (M$tau * diag(t(M$PA) %*% M$PA) + diag(M$SigW) + 2 * M$galpha0 / M$balpha0) return(M) } pcaMethods/R/BPCA_initmodel.R0000644000175100017510000000510314614231101016746 0ustar00biocbuildbiocbuild##' Model initialization for Bayesian PCA. This function is NOT ##' inteded to be run separately! ##' ##' The function calculates the initial Eigenvectors by use of SVD ##' from the complete rows. The data structure M is created and ##' initial values are assigned. ##' @title Initialize BPCA model ##' @param y numeric matrix containing missing values. Missing values ##' are denoted as 'NA' ##' @param components Number of components used for estimation ##' @return List containing ##' \item{rows}{Row number of input matrix} ##' \item{cols}{Column number of input matrix} ##' \item{comps}{Number of components to use} ##' \item{yest}{(working variable) current estimate of complete data} ##' \item{row_miss}{(Array) Indizes of rows containing missing values} ##' \item{row_nomiss}{(Array) Indices of complete rows (such with no ##' missing values)} ##' \item{nans}{Matrix of same size as input data. TRUE if \code{input == NA}, ##' false otherwise} ##' \item{mean}{Column wise data mean} ##' \item{PA}{ (d x k) Estimated principal axes (eigenvectors, ##' loadings) The matrix ROWS are the vectors} ##' \item{tau}{Estimated precision of the residual error} ##' \item{scores}{ Estimated scores} ##' Further elements are: galpha0, balpha0, alpha, gmu0, btau0, gtau0, ##' SigW. These are working variables or constants. ##' @author Wolfram Stacklies BPCA_initmodel <- function(y, components) { ## Initialization, write static parameters to the central M <- NULL M$rows <- nrow(y) M$cols <- ncol(y) M$comps <- components ## Column number M$yest <- y ## Original data, NAs are set to 0 later on ## Find rows with missing values, etc... M$nans <- is.na(y) temp <- apply(M$nans, 1, sum) M$row_nomiss <- which(temp == 0) M$row_miss <- which(temp != 0) M$yest[M$nans] <- 0 M$scores <- NULL ## Get the SVD of the complete rows covy <- cov(M$yest) values <- svd(covy, components, components) U <- values[[2]] S <- diag( values[[1]][1:components], nrow = components, ncol = components) V <- values[[3]] ## M$mean: column wise mean of the original data M$mean <- matrix(0, 1, M$cols) for(j in 1:M$cols) { idx <- which(!is.na(y[,j])) M$mean[j] <- mean(y[idx,j]) } M$PA <- U %*% sqrt(S) M$tau <- 1 / ( sum(diag(covy)) - sum(diag(S)) ) ## Constants etc taumax <- 1e10 taumin <- 1e-10 M$tau <- max( min(M$tau, taumax), taumin ) M$galpha0 <- 1e-10 M$balpha0 <- 1 M$alpha <- (2 * M$galpha0 + M$cols) / (M$tau * diag(t(M$PA) %*% M$PA) + 2 * M$galpha0 / M$balpha0) M$gmu0 <- 0.001 M$btau0 <- 1 M$gtau0 <- 1e-10 M$SigW <- diag(components) return(M) } pcaMethods/R/bpca.R0000644000175100017510000001615614614231101015114 0ustar00biocbuildbiocbuild##' Implements a Bayesian PCA missing value estimator. The script ##' is a port of the Matlab version provided by Shigeyuki OBA. See ##' also \url{http://ishiilab.jp/member/oba/tools/BPCAFill.html}. ##' BPCA combines an EM approach for PCA with a Bayesian model. In ##' standard PCA data far from the training set but close to the ##' principal subspace may have the same reconstruction error. BPCA ##' defines a likelihood function such that the likelihood for data ##' far from the training set is much lower, even if they are close to ##' the principal subspace. ##' ##' Scores and loadings obtained with Bayesian PCA slightly differ ##' from those obtained with conventional PCA. This is because BPCA ##' was developed especially for missing value estimation. The ##' algorithm does not force orthogonality between factor loadings, as ##' a result factor loadings are not necessarily orthogonal. However, ##' the BPCA authors found that including an orthogonality criterion ##' made the predictions worse. ##' ##' The authors also state that the difference between real and ##' predicted Eigenvalues becomes larger when the number of ##' observation is smaller, because it reflects the lack of ##' information to accurately determine true factor loadings from the ##' limited and noisy data. As a result, weights of factors to ##' predict missing values are not the same as with conventional PCA, ##' but the missing value estimation is improved. ##' ##' BPCA works iteratively, the complexity is growing with ##' \eqn{O(n^3)}{O(n^3)} because several matrix inversions are ##' required. The size of the matrices to invert depends on the ##' number of components used for re-estimation. ##' ##' Finding the optimal number of components for estimation is not a ##' trivial task; the best choice depends on the internal structure of ##' the data. A method called \code{kEstimate} is provided to ##' estimate the optimal number of components via cross validation. ##' In general few components are sufficient for reasonable estimation ##' accuracy. See also the package documentation for further ##' discussion about on what data PCA-based missing value estimation ##' makes sense. ##' ##' It is not recommended to use this function directely but rather to ##' use the pca() wrapper function. ##' ##' There is a difference with respect the interpretation of rows ##' (observations) and columns (variables) compared to matlab ##' implementation. For estimation of missing values for microarray ##' data, the suggestion in the original bpca is to intepret genes as ##' observations and the samples as variables. In pcaMethods however, ##' genes are interpreted as variables and samples as observations ##' which arguably also is the more natural interpretation. For bpca ##' behavior like in the matlab implementation, simply transpose your ##' input matrix. ##' ##' Details about the probabilistic model underlying BPCA are found in ##' Oba et. al 2003. The algorithm uses an expectation maximation ##' approach together with a Bayesian model to approximate the ##' principal axes (eigenvectors of the covariance matrix in PCA). ##' The estimation is done iteratively, the algorithm terminates if ##' either the maximum number of iterations was reached or if the ##' estimated increase in precision falls below \eqn{1e^{-4}}{1e^-4}. ##' ##' \bold{Complexity:} The relatively high complexity of the method is ##' a result of several matrix inversions required in each step. ##' Considering the case that the maximum number of iteration steps is ##' needed, the approximate complexity is given by the term ##' \deqn{maxSteps \cdot row_{miss} \cdot O(n^3)}{maxSteps * row_miss ##' * O(n^3)} Where \eqn{row_{miss}}{row_miss} is the number of rows ##' containing missing values and \eqn{O(n^3)}{O(n^3)} is the ##' complexity for inverting a matrix of size ##' \eqn{components}{components}. Components is the number of ##' components used for re-estimation. ##' @title Bayesian PCA missing value estimation ##' @param Matrix \code{matrix} -- Pre-processed matrix (centered, ##' scaled) with variables in columns and observations in rows. The ##' data may contain missing values, denoted as \code{NA}. ##' @param nPcs \code{numeric} -- Number of components used for ##' re-estimation. Choosing few components may decrease the ##' estimation precision. ##' @param maxSteps \code{numeric} -- Maximum number of estimation ##' steps. ##' @param verbose \code{boolean} -- BPCA prints the number of steps ##' and the increase in precision if set to TRUE. Default is ##' interactive(). ##' @param threshold convergence threshold ##' @param ... Reserved for future use. Currently no further ##' parameters are used ##' @return Standard PCA result object used by all PCA-based methods ##' of this package. Contains scores, loadings, data mean and ##' more. See \code{\link{pcaRes}} for details. ##' @references Shigeyuki Oba, Masa-aki Sato, Ichiro Takemasa, Morito ##' Monden, Ken-ichi Matsubara and Shin Ishii. A Bayesian missing ##' value estimation method for gene expression profile ##' data. \emph{Bioinformatics, 19(16):2088-2096, Nov 2003}, ##' \url{https://doi.org/10.1093/bioinformatics/btg287}. ##' @seealso \code{\link{ppca}}, \code{\link{svdImpute}}, ##' \code{\link{prcomp}}, \code{\link{nipalsPca}}, ##' \code{\link{pca}}, ##' \code{\link{pcaRes}}. \code{\link{kEstimate}}. ##' @note Requires \code{MASS}. ##' @examples ##' ## Load a sample metabolite dataset with 5\% missig values (metaboliteData)e ##' data(metaboliteData) ##' ## Perform Bayesian PCA with 2 components ##' pc <- pca(t(metaboliteData), method="bpca", nPcs=2) ##' ## Get the estimated principal axes (loadings) ##' loadings <- loadings(pc) ##' ## Get the estimated scores ##' scores <- scores(pc) ##' ## Get the estimated complete observations ##' cObs <- completeObs(pc) ##' ## Now make a scores and loadings plot ##' slplot(pc) ##' \dontshow{stopifnot(sum((fitted(pc) - t(metaboliteData))^2, na.rm=TRUE) < 200)} ##' @keywords multivariate ##' @export ##' @author Wolfram Stacklies bpca <- function(Matrix, nPcs=2, maxSteps=100, verbose=interactive(), threshold=1e-4, ... ) { ## R implementation of a Bayesion PCA missing value estimator. ## After the Matlab script of Shigeyuki OBA (2002 May. 5th) ## See also: http://hawaii.aist-nara.ac.jp/%7Eshige-o/tools/ ## Great thanks to them! M <- BPCA_initmodel(Matrix, nPcs) tauold <- 1000 for( step in 1:maxSteps ) { M <- BPCA_dostep(M, Matrix) if( step %% 10 == 0 ) { tau <- M$tau dtau <- abs(log10(tau) - log10(tauold)) if ( verbose ) { cat("Step Number : ", step, '\n') cat("Increase in precision : ", dtau, '\n') cat("----------", '\n') } if (dtau < threshold) { break } tauold <- tau } } R2cum <- rep(NA, nPcs) TSS <- sum(Matrix^2, na.rm=TRUE) for (i in 1:nPcs) { difference <- Matrix - (M$scores[,1:i, drop=FALSE] %*% t(M$PA[,1:i, drop=FALSE]) ) R2cum[i] <- 1 - (sum(difference^2, na.rm=TRUE) / TSS) } result <- new("pcaRes") result@scores <- M$scores result@loadings <- M$PA result@R2cum <- R2cum result@method <- "bpca" return(result) } pcaMethods/R/checkData.R0000644000175100017510000000537314614231101016055 0ustar00biocbuildbiocbuild##' Check a given data matrix for consistency with the format ##' required for further analysis. ##' The data must be a numeric matrix and not contain: ##' \itemize{ ##' \item Inf values ##' \item NaN values ##' \item Rows or columns that consist of NA only ##' } ##' @title Do some basic checks on a given data matrix ##' @param data \code{matrix} -- Data to check. ##' @param verbose \code{boolean} -- If TRUE, the function prints ##' messages whenever an error in the data set is found. ##' @return \item{isValid}{\code{boolean} -- TRUE if no errors were ##' found, FALSE otherwise. isValid contains a set of attributes, ##' these are: \itemize{ \item isNumeric - TRUE if data is numeric, ##' false otherwise \item isInfinite - TRUE if data contains 'Inf' ##' values, false otherwise \item isNaN - TRUE if data contains 'NaN' ##' values, false otherwise \item isMatrix - TRUE if the data is in ##' matrix format, FALSE otherwise \item naRows - TRUE if data ##' contains rows in which all elements are 'NA', FALSE otherwise ##' \item naCols - TRUE if data contains columns in which all elements ##' are 'NA', FALSE otherwise }} ##' @keywords multivariate ##' @export ##' @author Wolfram Stacklies checkData <- function(data, verbose = FALSE) { isValid <- TRUE isNumeric <- TRUE isInfinite <- FALSE isNaN <- FALSE isMatrix <- TRUE naRows <- FALSE naCols <- FALSE if (!is.numeric(data)) { isNumeric <- FALSE isValid <- FALSE if (verbose) message("Error: Data is not numeric") } if ( sum(is.infinite(data) >= 1) ) { isInfinite <- TRUE isValid <- FALSE if (verbose) message("Error: Data contains 'Inf' values") } if (sum(is.nan(data) >= 1)) { isNaN <- TRUE isValid <- FALSE if (verbose) message("Error: Data contains 'NaN' values. Missing values must be denoted by 'NA'") } if (!is.matrix(data)) { isMatrix <- FALSE isValid <- FALSE if (verbose) message("Error: data is not a matrix. Try to use as.matrix(data)") } ## Check for entire rows that are NA only if (sum(apply(is.na(data), 1, sum) == ncol(data)) >= 1 ) { naRows <- TRUE isValid <- FALSE if (verbose) message("Error: Data contains rows in which all elements are 'NA'. Remove them first") } ## Check for entire columns that are NA only if (sum(apply(is.na(data), 2, sum) == nrow(data)) >= 1 ) { naCols <- TRUE isValid <- FALSE if (verbose) message("Error: Data contains columns in which all elements are 'NA'. Remove them first") } attr(isValid, "isNumeric") <- isNumeric attr(isValid, "isInfinite") <- isInfinite attr(isValid, "isNaN") <- isNaN attr(isValid, "isMatrix") <- isMatrix attr(isValid, "naRows") <- naRows attr(isValid, "naCols") <- naCols return(isValid) } pcaMethods/R/derrorHierarchic.R0000644000175100017510000001251114614231101017455 0ustar00biocbuildbiocbuild##' Later ##' @param nlnet the nlnet ##' @param trainIn training data ##' @param trainOut fitted data ##' @return derror ##' @author Henning Redestig, Matthias Scholz derrorHierarchic <- function(nlnet, trainIn, trainOut) { weights <- nlnet@weights$current() netDim <- dim(nlnet@net) if(nlnet@inverse) { numElements <- nlnet@net[1] * dim(trainOut)[2] trainIn <- matrix(weights[1:numElements], nrow=nlnet@net[1], ncol=dim(trainOut)[2]) wTrainIn <- weights[1:numElements,drop=FALSE] weights <- weights[(numElements + 1):length(weights), ,drop=FALSE] } weightMats <- vector2matrices(weights, nlnet@net) trainDim <- dim(trainIn) subnetNum <- length(nlnet@hierarchic$var) ## ****************************** Epattern <- array(0, dim=c(dim(trainOut), subnetNum)) nOut <- array(0, dim=c(sum(nlnet@net), trainDim[2], subnetNum)) for(subnet in 1:subnetNum) nOut[1:trainDim[1],,subnet] <- eval(parse(text=paste(nlnet@fct[1], "(trainIn)"))) if(nlnet@inverse) for(subnet in 1:subnetNum) nOut[nlnet@hierarchic$idx[,subnet]==0,,subnet] <- 0 ## forward propagation for(subnet in 1:subnetNum) { if(nlnet@hierarchic$var[subnet] != 0) { sBias <- array(1, dim=c(1, trainDim[2])) for(i in 1:(netDim[2] - 1)) { if(i == 1) nBegin <- 1 else nBegin <- sum(nlnet@net[1:(i-1)])+1 sIn <- rbind(sBias, nOut[nBegin:sum(nlnet@net[1:i]),,subnet]) sOut <- eval(parse(text=paste(nlnet@fct[i+1], "(weightMats[[i]] %*% sIn)"))) if(i == (nlnet@hierarchic$layer - 1)) sOut[nlnet@hierarchic$idx[,subnet]==0,] <- 0 nOut[(sum(nlnet@net[1:i])+1):sum(nlnet@net[1:(i+1)]),,subnet] <- sOut } output <- nOut[(sum(nlnet@net[1:(length(nlnet@net)-1)])+1):dim(nOut)[1],,subnet] Epattern[,,subnet] <- output - trainOut } } ## error function Epattern <- Epattern^2 Epattern[is.na(Epattern)] <- 0 #set the missing values to zero if(!is.null(nlnet@dataDist)) for(subnet in 1:subnetNum) Epattern[,,subnet] <- Epattern[,,subnet] * nlnet@dataDist Eitemize <- apply(Epattern, 3, sum) * 0.5 Etotal <- sum(nlnet@hierarchic$var * Eitemize) if(!is.null(nlnet@weightDecay)) Etotal <- Etotal + nlnet@weightDecay * 0.5 * sum(weights^2) if(nlnet@inverse) Etotal <- Etotal + 0.01 * nlnet@weightDecay * 0.5 * sum(wTrainIn^2) ## back propagation nError <- array(0, dim=c(sum(nlnet@net), trainDim[2], subnet)) dWeight <- vector(length=netDim[2] - 1, mode="list") wBp <- vector(length=netDim[2] - 1, mode="list") ## wBp is weights for back propagation for(u in 1:(netDim[2] - 1)) wBp[[u]] <- weightMats[[u]][,2:(nlnet@net[u] + 1)] # cats the weights which belong to bias dw <- array(0, dim=c(length(weights), subnet)) for(subnet in 1:subnetNum) { if(nlnet@hierarchic$var[subnet] != 0) { ## last layer sTmp <- nOut[(dim(nOut)[1]-nlnet@net[length(nlnet@net)]+1):dim(nOut)[1],,subnet] if(nlnet@fct[length(nlnet@fct)] == "tanh") eTmp <- (1 - sTmp^2) * (sTmp - trainOut) #prev trainOut - sTmp (fixed to get rid of sign change) else if(nlnet@fct[length(nlnet@fct)] == "linr") eTmp <- sTmp - trainOut #prev trainOut - sTmp (fixed to get rid of sign change) eTmp[is.na(eTmp)] <- 0 if(!is.null(nlnet@dataDist)) eTmp <- eTmp * nlnet@dataDist nError[(dim(nError)[1]-nlnet@net[length(nlnet@net)]+1):dim(nError)[1],,subnet] <- eTmp ## all other layers for(n in 1:(netDim[2] - 1)){ i <- netDim[2]-n ## the if clause is to avoid 1:0 difference in R ## Matlab (1:0 => Empty matrix), R (1:0 => [1,0]) if(i > 1) sTmp <- nOut[(sum(nlnet@net[1:(i-1)])+1):sum(nlnet@net[1:i]),,subnet] else sTmp <- nOut[1:sum(nlnet@net[1:i]),,subnet] if(i==(nlnet@hierarchic$layer-1)) eTmp[nlnet@hierarchic$idx[,subnet]==0,] <- 0 dWeight[[i]] <- tcrossprod(eTmp, rbind(sBias, sTmp)) #gradient if (nlnet@fct[i] == "tanh") eTmp <- (1 - sTmp^2) * crossprod(wBp[[i]],eTmp) else if (nlnet@fct[i] == "linr") eTmp <- crossprod(wBp[[i]], eTmp) ## the if clause is to avoid 1:0 difference in R if(i > 1) nError[(sum(nlnet@net[1:(i - 1)]) + 1):sum(nlnet@net[1:i]), ,subnet] <- eTmp else nError[1:sum(nlnet@net[1:i]), ,subnet] <- eTmp } dw[,subnet] <- unlist(dWeight) #fixed sign change } } if(nlnet@inverse) { dw <- rbind(array(0, dim=c(numElements, subnetNum)), dw) for(subnet in 1:subnetNum) { eTmp <- array(nError[1:nlnet@net[1],,subnet], dim=c(nlnet@net[1], dim(nError)[2])) eTmp[nlnet@hierarchic$idx[,subnet] == 0,] <- 0 dim(eTmp) <- NULL #a bit unsure if this is correct but seems to work dw[1:numElements,subnet] <- unlist(eTmp) #fixed sign change } ## weights <- rbind(cbind(rep(0, numElements)), cbind(weights)) #old: only weight decay for real weights weights <- rbind(cbind(0.01 * wTrainIn), cbind(weights)) #new } dwTotal <- array(0, dim=dim(weights)) for (subnet in 1:subnetNum) { dwTotal <- dwTotal + nlnet@hierarchic$var[subnet] * dw[, subnet] } if(!is.null(nlnet@weightDecay)) dwTotal <- dwTotal + nlnet@weightDecay * weights return(list(dwTotal=dwTotal, Etotal=Etotal, nError=nError, nOut=nOut)) } pcaMethods/R/errorHierarchic.R0000644000175100017510000000440014614231101017307 0ustar00biocbuildbiocbuild##' Later ##' @param nlnet The nlnet ##' @param trainIn training data ##' @param trainOut fitted data ##' @return error ##' @author Henning Redestig, Matthias Scholz errorHierarchic <- function(nlnet, trainIn, trainOut) { weights <- nlnet@weights$current() if(nlnet@inverse) { numElements <- nlnet@net[1] * dim(trainOut)[2] trainIn <- array(weights[1:numElements], dim=c(nlnet@net[1], dim(trainOut)[2])) wTrainIn <- weights[1:numElements, drop=FALSE] weights <- weights[(numElements + 1):length(weights),,drop=FALSE] } netDim <- dim(nlnet@net) trainDim <- dim(trainOut) weightMats <- vector2matrices(weights, nlnet@net) hierarchicIdx <- nlnet@hierarchic$idx[,nlnet@hierarchic$var != 0, drop=FALSE] hierarchicVar <- nlnet@hierarchic$var[,colSums(nlnet@hierarchic$var) != 0, drop=FALSE] subnetNum <- length(hierarchicVar) out <- array(0, dim=c(trainDim[1], trainDim[2], subnetNum)) sBias <- array(1, dim=c(1, trainDim[2])) sExtract <- eval(parse(text=paste(nlnet@fct[1], "(trainIn)"))) Eitemize <- NULL if(nlnet@hierarchic$layer > 1) { #this should not be executed at all if sequence is 1:0 for(layer in 1:(nlnet@hierarchic$layer - 1)) { sExtract <- rbind(sBias, sExtract) sExtract <- eval(parse(text=paste(nlnet@fct[layer + 1], "(weightMats[[layer]] %*% sExtract)"))) } } for(subnet in 1:subnetNum) { sRecon <- sExtract sRecon[hierarchicIdx[,subnet]==0,] <- 0 for(layer in nlnet@hierarchic$layer:(netDim[2] - 1)) { sRecon <- rbind(sBias, sRecon) sRecon <- eval(parse(text=paste(nlnet@fct[layer+1], "(weightMats[[layer]] %*% sRecon)"))) } out[,,subnet] <- sRecon ## error function eTmp <- (sRecon - trainOut)^2 eTmp[is.na(eTmp)] <- 0 Eitemize[subnet] <- sum(eTmp) * 0.5 if(!is.null(nlnet@dataDist)) Eitemize[subnet] <- 0.5 * sum(nlnet@dataDist * eTmp) else Eitemize[subnet] <- 0.5 * sum(eTmp) } error <- tcrossprod(hierarchicVar, rbind(Eitemize)) if(!is.null(nlnet@weightDecay)) error <- error + nlnet@weightDecay * 0.5 * sum(weights^2) ## smooth (0.01) weight decay also for input values if(nlnet@inverse) error <- error + 0.01 * nlnet@weightDecay * 0.5 * sum(wTrainIn^2) return(list(error=error, out=out)) } pcaMethods/R/forkNlpcaNet.R0000644000175100017510000000131414614231101016563 0ustar00biocbuildbiocbuild##' Complete copy of nlpca net object ##' @param nlnet a nlnet ##' @return A copy of the input nlnet ##' @author Henning Redestig forkNlpcaNet <- function(nlnet) { res <- new("nlpcaNet") res@net <- nlnet@net res@hierarchic <- nlnet@hierarchic res@fct <- nlnet@fct res@fkt <- nlnet@fkt res@weightDecay <- nlnet@weightDecay res@featureSorting <- nlnet@featureSorting res@dataDist <- nlnet@dataDist res@inverse <- nlnet@inverse res@fCount <- nlnet@fCount res@componentLayer <- nlnet@componentLayer res@error <- nlnet@error res@gradient <- nlnet@gradient res@weights <- weightsAccount(nlnet@weights$current()) res@maxIter <- nlnet@maxIter res@scalingFactor <- nlnet@scalingFactor res } pcaMethods/R/kEstimate.R0000644000175100017510000003072014614231101016126 0ustar00biocbuildbiocbuild##' Perform cross validation to estimate the optimal number of ##' components for missing value estimation. Cross validation is ##' done for the complete subset of a variable. ##' ##' The assumption hereby is that variables that are highly correlated ##' in a distinct region (here the non-missing observations) are also ##' correlated in another (here the missing observations). This also ##' implies that the complete subset must be large enough to be ##' representative. For each incomplete variable, the available ##' values are divided into a user defined number of cv-segments. The ##' segments have equal size, but are chosen from a random equal ##' distribution. The non-missing values of the variable are covered ##' completely. PPCA, BPCA, SVDimpute, Nipals PCA, llsImpute an NLPCA ##' may be used for imputation. ##' ##' The whole cross validation is repeated several times so, depending ##' on the parameters, the calculations can take very long time. As ##' error measure the NRMSEP (see Feten et. al, 2005) or the Q2 ##' distance is used. The NRMSEP basically normalises the RMSD ##' between original data and estimate by the variable-wise ##' variance. The reason for this is that a higher variance will ##' generally lead to a higher estimation error. If the number of ##' samples is small, the variable - wise variance may become an ##' unstable criterion and the Q2 distance should be used ##' instead. Also if variance normalisation was applied previously. ##' ##' The method proceeds variable - wise, the NRMSEP / Q2 distance is ##' calculated for each incomplete variable and averaged ##' afterwards. This allows to easily see for wich set of variables ##' missing value imputation makes senes and for wich set no ##' imputation or something like mean-imputation should be used. Use ##' \code{kEstimateFast} or \code{Q2} if you are not interested in ##' variable wise CV performance estimates. ##' ##' Run time may be very high on large data sets. Especially when used ##' with complex methods like BPCA or Nipals PCA. For PPCA, BPCA, ##' Nipals PCA and NLPCA the estimation method is called ##' \eqn{(v_{miss} \cdot segs \cdot nruncv \cdot)}{(v\_miss * segs * ##' nruncv)} times as the error for all numbers of principal ##' components can be calculated at once. For LLSimpute and SVDimpute ##' this is not possible, and the method is called \eqn{(v_{miss} ##' \cdot segs \cdot nruncv \cdot length(evalPcs))}{(v\_miss * segs * ##' nruncv * length(evalPcs))} times. This should still be fast for ##' LLSimpute because the method allows to choose to only do the ##' estimation for one particular variable. This saves a lot of ##' iterations. Here, \eqn{v_{miss}}{v\_miss} is the number of ##' variables showing missing values. ##' ##' As cross validation is done variable-wise, in this function Q2 is ##' defined on single variables, not on the entire data set. This is ##' Q2 is calculated as as \eqn{\frac{\sum(x - ##' xe)^2}{\sum(x^2)}}{sum(x - xe)^2 \ sum(x^2)}, where x is the ##' currently used variable and xe it's estimate. The values are then ##' averaged over all variables. The NRMSEP is already defined ##' variable-wise. For a single variable it is then ##' \eqn{\sqrt(\frac{\sum(x - xe)^2}{(n \cdot var(x))})}{sqrt(sum(x - ##' xe)^2 \ (n * var(x)))}, where x is the variable and xe it's ##' estimate, n is the length of x. The variable wise estimation ##' errors are returned in parameter variableWiseError. ##' @title Estimate best number of Components for missing value ##' estimation ##' @param Matrix \code{matrix} -- numeric matrix containing ##' observations in rows and variables in columns ##' @param method \code{character} -- of the methods found with ##' pcaMethods() The option llsImputeAll calls llsImpute with the ##' allVariables = TRUE parameter. ##' @param evalPcs \code{numeric} -- The principal components to use ##' for cross validation or the number of neighbour variables if used ##' with llsImpute. Should be an array containing integer values, ##' eg. \code{evalPcs = 1:10} or \code{evalPcs = c(2,5,8)}. The NRMSEP ##' or Q2 is calculated for each component. ##' @param segs \code{numeric} -- number of segments for cross validation ##' @param nruncv \code{numeric} -- Times the whole cross validation ##' is repeated ##' @param em \code{character} -- The error measure. This can be nrmsep or q2 ##' @param allVariables \code{boolean} -- If TRUE, the NRMSEP is ##' calculated for all variables, If FALSE, only the incomplete ones ##' are included. You maybe want to do this to compare several methods ##' on a complete data set. ##' @param verbose \code{boolean} -- If TRUE, some output like the ##' variable indexes are printed to the console each iteration. ##' @param ... Further arguments to \code{pca} or \code{nni} ##' @return A list with: ##' \item{bestNPcs}{number of PCs or k for which the minimal average ##' NRMSEP or the maximal Q2 was obtained.} ##' \item{eError}{an array of of size length(evalPcs). Contains the ##' average error of the cross validation runs for each number of ##' components.} ##' \item{variableWiseError}{Matrix of size ##' \code{incomplete_variables} x length(evalPcs). Contains the ##' NRMSEP or Q2 distance for each variable and each number of PCs. ##' This allows to easily see for wich variables imputation makes ##' sense and for which one it should not be done or mean imputation ##' should be used.} ##' \item{evalPcs}{The evaluated numbers of components or number of ##' neighbours (the same as the evalPcs input parameter).} ##' \item{variableIx}{Index of the incomplete variables. This can be ##' used to map the variable wise error to the original data.} ##' @seealso \code{\link{kEstimateFast}, \link{Q2}, \link{pca}, \link{nni}}. ##' @examples ##' ## Load a sample metabolite dataset with 5\% missing values (metaboliteData) ##' data(metaboliteData) ##' # Do cross validation with ppca for component 2:4 ##' esti <- kEstimate(metaboliteData, method = "ppca", evalPcs = 2:4, nruncv=1, em="nrmsep") ##' # Plot the average NRMSEP ##' barplot(drop(esti$eError), xlab = "Components",ylab = "NRMSEP (1 iterations)") ##' # The best result was obtained for this number of PCs: ##' print(esti$bestNPcs) ##' # Now have a look at the variable wise estimation error ##' barplot(drop(esti$variableWiseError[, which(esti$evalPcs == esti$bestNPcs)]), ##' xlab = "Incomplete variable Index", ylab = "NRMSEP") ##' @keywords multivariate ##' @export ##' @author Wolfram Stacklies kEstimate <- function(Matrix, method="ppca", evalPcs=1:3, segs=3, nruncv=5, em="q2", allVariables=FALSE, verbose=interactive(), ...) { fastKE <- FALSE if (method == "ppca" | method == "bpca" | method == "nipals" | method == "nlpca") fastKE <- TRUE method <- match.arg(method, listPcaMethods()) em <- match.arg(em, c("nrmsep", "q2")) maxPcs <- max(evalPcs) lengthPcs <- length(evalPcs) ## If the data is a data frame, convert it into a matrix Matrix <- as.matrix(Matrix, rownames.force=TRUE) if(maxPcs > (ncol(Matrix) - 1)) stop("maxPcs exceeds matrix size, choose a lower value!") ## And now check if everything is right... if( !checkData(Matrix, verbose=interactive()) ) stop("Invalid data format! Use checkData(Matrix, verbose = TRUE) for details.\n") if( (sum(is.na(Matrix)) == 0) && (allVariables == FALSE) ) stop("No missing values. Maybe you want to set allVariables = TRUE. Exiting\n") missing <- apply(is.na(Matrix), 2, sum) > 0 missIx <- which(missing == TRUE) if (allVariables) missIx <- 1:ncol(Matrix) complete <- !missing compIx <- which(complete == TRUE) error <- matrix(0, length(missIx), length(evalPcs)) iteration <- 0 for(nPcs in evalPcs) { ## If the estimated observations are just scores %*% t(loadings) ## we can calculate all we need at once, this saves many ## iterations... if (fastKE) nPcs = maxPcs iteration = iteration + 1 if (verbose && !fastKE) { cat("Doing CV for ", nPcs, " component(s) \n") } else if (verbose && fastKE) {cat("Doing CV ... \n")} for(cviter in 1:nruncv) { pos <- 0 if (verbose) cat("Incomplete variable index: ") for (index in missIx) { pos <- pos + 1 cat(pos, ":", sep="") target <- Matrix[, index, drop = FALSE] compObs <- !is.na(target) missObs <- is.na(target) nObs <- sum(compObs) ## Remove all observations that are missing in the target genes, ## as additional missing values may tamper the results set <- Matrix[compObs,] if (nObs >= (2 * segs)) { segments <- segs } else segments <- ceiling(nObs / 2) ## We assume uniformly distributed missing values when ## choosing the segments tt <- gl(segments, ceiling(nObs / segments))[1:nObs] cvsegs <- split(sample(nObs), tt) set <- Matrix[compObs,] if (fastKE) { nrmsep <- array(0, length(evalPcs)) q2 <- array(0, length(evalPcs)) } else { nrmsep <- 0; q2 <- 0 } for (i in 1:length(cvsegs)) { n <- length(cvsegs[[i]]) # n is the number of created # missing values ## Impute values using the given regression method testSet <- set testSet[cvsegs[[i]], index] <- NA if (method == "llsImpute") { estimate <- llsImpute(testSet, k = nPcs, verbose = FALSE, allVariables = FALSE, center = FALSE, xval = index) } else if (method == "llsImputeAll") { estimate <- llsImpute(testSet, k = nPcs, verbose = FALSE, allVariables = TRUE, center = FALSE, xval = index) } else { estimate <- pca(testSet, nPcs = nPcs, verbose = FALSE, method = method, center = TRUE,...) } if (fastKE) { for (np in evalPcs) { estiFitted <- fitted(estimate, data = NULL, nPcs = np) estimateVec <- estiFitted[, index] original <- target[compObs, ] estimateVec[-cvsegs[[i]]] <- testSet[-cvsegs[[i]], index] ## Error of prediction, error is calculated for removed ## elements only nIx <- which(evalPcs == np) if (em == "nrmsep") { nrmsep[nIx] <- nrmsep[nIx] + sum( (original - estimateVec)^2) } else { q2[nIx] <- q2[nIx] + sum( (original - estimateVec)^2 ) } } } else { estimate <- estimate@completeObs[, index] original <- target[compObs, ] ## Error of prediction, error is calculated for removed ## elements only if (em == "nrmsep") { nrmsep <- nrmsep + sum( (original - estimate)^2) } else { q2 <- q2 + sum( (original - estimate)^2 ) } } } ## iteration over cv segments if (fastKE) { if (em == "nrmsep") { error[pos, ] <- error[pos, ] + nrmsep / (nrow(set) * var(set[,index])) } else error[pos, ] <- error[pos, ] + (1 - (q2 / sum(set[, index]^2))) } else { if (em == "nrmsep") { error[pos, iteration] <- error[pos, iteration] + nrmsep / (nrow(set) * var(set[,index])) } else error[pos, iteration] <- error[pos, iteration] + (1 - (q2 / sum(set[, index]^2))) } } # iteration over variables if (verbose) cat("\n") } #iteration over nruncv ## The error is the sum over the independent cross validation runs error <- error / nruncv if (verbose && !fastKE) cat("The average", em, "for k =", iteration, "is", sum(error[,iteration]) / nrow(error), "\n") ## if nlpca, ppca, bpca, nipals we do not need to iterate over the ## number of components... if (fastKE) break } # iteration over number components if (em == "nrmsep") avgError <- sqrt(apply(error, 2, sum) / nrow(error)) else avgError <- apply(error, 2, sum) / nrow(error) ret <- list() if (em == "nrmsep") ret$bestNPcs <- evalPcs[which(avgError == min(avgError))] else ret$bestNPcs <- evalPcs[which(avgError == max(avgError))] ret$eError <- avgError if(em == "nrmsep") ret$variableWiseError <- sqrt(error) else ret$variableWiseError <- error ret$evalPcs <- evalPcs ret$variableIx <- missIx return(ret) } pcaMethods/R/kEstimateFast.R0000644000175100017510000001215414614231101016745 0ustar00biocbuildbiocbuild##' This is a simple estimator for the optimal number of componets ##' when applying PCA or LLSimpute for missing value estimation. No ##' cross validation is performed, instead the estimation quality is ##' defined as Matrix[!missing] - Estimate[!missing]. This will give a ##' relatively rough estimate, but the number of iterations equals the ##' length of the parameter evalPcs.\cr Does not work with LLSimpute!! ##' As error measure the NRMSEP (see Feten et. al, 2005) or the Q2 ##' distance is used. The NRMSEP basically normalises the RMSD ##' between original data and estimate by the variable-wise ##' variance. The reason for this is that a higher variance will ##' generally lead to a higher estimation error. If the number of ##' samples is small, the gene - wise variance may become an unstable ##' criterion and the Q2 distance should be used instead. Also if ##' variance normalisation was applied previously. ##' @title Estimate best number of Components for missing value estimation ##' @param Matrix \code{matrix} -- numeric matrix containing ##' observations in rows and variables in columns ##' @param method \code{character} -- a valid pca method (see ##' \code{\link{pca}}). ##' @param evalPcs \code{numeric} -- The principal components to use ##' for cross validation or cluster sizes if used with ##' llsImpute. Should be an array containing integer values, ##' eg. evalPcs = 1:10 or evalPcs = C(2,5,8).The NRMSEP is calculated ##' for each component. ##' @param em \code{character} -- The error measure. This can be ##' nrmsep or q2 ##' @param allVariables \code{boolean} -- If TRUE, the NRMSEP is ##' calculated for all variables, If FALSE, only the incomplete ones ##' are included. You maybe want to do this to compare several methods ##' on a complete data set. ##' @param verbose \code{boolean} -- If TRUE, the NRMSEP and the ##' variance are printed to the console each iteration. ##' @param ... Further arguments to \code{pca} ##' @return \item{list}{Returns a list with the elements: ##' \itemize{ ##' \item minNPcs - number of PCs for which the minimal average NRMSEP ##' was obtained ##' \item eError - an array of of size length(evalPcs). Contains the ##' estimation error for each number of ##' components. ##' \item evalPcs - The evaluated numbers of components or ##' cluster sizes (the same as the evalPcs input parameter). }} ##' @seealso \code{\link{kEstimate}}. ##' @export ##' @examples ##' data(metaboliteData) ##' # Estimate best number of PCs with ppca for component 2:4 ##' esti <- kEstimateFast(t(metaboliteData), method = "ppca", evalPcs = 2:4, em="nrmsep") ##' barplot(drop(esti$eError), xlab = "Components",ylab = "NRMSEP (1 iterations)") ##' # The best k value is: ##' print(esti$minNPcs) ##' @keywords multivariate ##' @author Wolfram Stacklies kEstimateFast <- function(Matrix, method = "ppca", evalPcs = 1:3, em = "nrmsep", allVariables = FALSE, verbose = interactive(), ...) { method <- match.arg(method, c("ppca", "bpca", "svdImpute", "nipals", "nlpca")) em <- match.arg(em, c("nrmsep", "q2")) maxPcs <- max(evalPcs) lengthPcs <- length(evalPcs) missing <- is.na(Matrix) error <- array(0, lengthPcs) ## If the data is a data frame, convert it into a matrix Matrix <- as.matrix(Matrix, rownames.force=TRUE) if(maxPcs > (ncol(Matrix) - 1)) stop("maxPcs exceeds matrix size, choose a lower value!") ## And now check if everything is right... if( !checkData(Matrix, verbose=interactive()) ) stop("Invalid data format! Use checkData(Matrix, verbose = TRUE) for details.\n") if( (sum(is.na(Matrix)) == 0) && (allVariables == FALSE) ) stop("No missing values. Maybe you want to set allVariables = TRUE. Exiting\n") iteration = 0 for(nPcs in evalPcs) { iteration = iteration + 1 if (method == "nlpca") { estimate <- fitted(pca(Matrix, nPcs = nPcs, verbose = FALSE, method = method, center = TRUE,...), Matrix, nPcs = nPcs) } else { estimate <- fitted(pca(Matrix, nPcs = nPcs, verbose = FALSE, method = method, center = TRUE,...), nPcs = nPcs) } if (em == "q2") { # The Q2 distance q2 <- 1 - sum((Matrix[!missing] - estimate[!missing])^2) / sum(Matrix[!missing]^2) error[iteration] <- q2 } else { nrmsep <- 0 for(i in 1:ncol(Matrix)) { nrmsep <- nrmsep + ( sum((Matrix[!missing[,i], i] - estimate[!missing[,i], i])^2) / (sum(!missing[,i]) * var(Matrix[,i], na.rm = TRUE)) ) } nrmsep <- nrmsep / sum(apply(missing, 2, sum) > 0) error[iteration] <- nrmsep } if(verbose) cat("The", em, "for", evalPcs[iteration], "components is:", error[iteration], "\n") } ret <- list() if (em == "nrmsep") ret$bestNPcs <- evalPcs[which(error == min(error))] else ret$bestNPcs <- evalPcs[which(error == max(error))] ret$eError <- error ret$evalPcs <- evalPcs return(ret) } pcaMethods/R/lineSearch.R0000644000175100017510000000615214614231101016257 0ustar00biocbuildbiocbuild##' Line search for conjugate gradient ##' @param nlnet The nlnet ##' @param dw .. ##' @param e0 .. ##' @param ttGuess .. ##' @param trainIn Training data ##' @param trainOut Fitted data ##' @param verbose logical, print messages ##' @return ... ##' @author Henning Redestig, Matthias Scholz lineSearch <- function(nlnet, dw, e0, ttGuess, trainIn, trainOut, verbose) { iterGoldenSectionSearch <- 6 alpha <- 0.618034 tt <- rep(0, 4) e <- rep(0, 4) tmpnlnet <- forkNlpcaNet(nlnet) tt[1] <- 0 e[1] <- e0 tt[4] <- ttGuess tmpnlnet@weights$set(nlnet@weights$current() + tt[4] * dw) e[4] <- nlnet@error(tmpnlnet, trainIn, trainOut)$error if(e[4] > e[1]) { #got final interval calculate tt[2] and tt[3] tt[2] <- tt[1] + (1 - alpha) * (tt[4] - tt[1]) tmpnlnet@weights$set(nlnet@weights$current() + tt[2] * dw) e[2] <- nlnet@error(tmpnlnet, trainIn, trainOut)$error tt[3] <- tt[1] + alpha * (tt[4] - tt[1]) tmpnlnet@weights$set(nlnet@weights$current() + tt[3] * dw) e[3] <- nlnet@error(tmpnlnet, trainIn, trainOut)$error } else { #expand, add new tt[4] tt[3] <- tt[4] e[3] <- e[4] tt[4] <- (1 + alpha) * tt[4] tmpnlnet@weights$set(nlnet@weights$current() + tt[4] * dw) e[4] <- nlnet@error(tmpnlnet, trainIn, trainOut)$error if(e[4] > e[3]) { #got final interval, calculate tt[2] tt[2] <- tt[1] + (1 - alpha) * (tt[4] - tt[1]) tmpnlnet@weights$set(nlnet@weights$current() + tt[2] * dw) e[2] <- nlnet@error(tmpnlnet, trainIn, trainOut)$error } else { #expand: add new tt[4] i <- 1 while(e[4] < e[3] && i < 50) { tt[2] <- tt[3] e[2] <- e[3] tt[3] <- tt[4] e[3] <- e[4] tt[4] <- (1 + alpha) * tt[4] tmpnlnet@weights$set(nlnet@weights$current() + tt[4] * dw) e[4] <- nlnet@error(tmpnlnet, trainIn, trainOut)$error i <- i + 1 if(verbose && i == 50) cat("^") } } } ## golden section search for(i in 1:iterGoldenSectionSearch) { if(e[3] > e[2]) { tt[4] <- tt[3] #remove right value tt[4] e[4] <- e[3] tt[3] <- tt[2] e[3] <- e[2] tt[2] <- tt[1] + (1 - alpha) * (tt[4] - tt[1]) #split left interval tmpnlnet@weights$set(nlnet@weights$current() + tt[2] * dw) e[2] <- nlnet@error(tmpnlnet, trainIn, trainOut)$error } else { tt[1] <- tt[2] #remove left t value tt[1] e[1] <- e[2] tt[2] <- tt[3] e[2] <- e[3] tt[3] <- tt[1] + alpha * (tt[4] - tt[1]) #split right interval tmpnlnet@weights$set(nlnet@weights$current() + tt[3] * dw) e[3] <- nlnet@error(tmpnlnet, trainIn, trainOut)$error } } if(e[2] < e[3]) { eBest <- e[2] ttBest <- tt[2] } else { eBest <- e[3] ttBest <- tt[3] } wBest <- nlnet@weights$current() + ttBest * dw return(list(wBest=wBest, eBest=eBest, ttBest=ttBest)) } ##' Linear kernel ##' @param x datum ##' @return Input value ##' @author Henning Redestig, Matthias Scholz linr <- function(x) x pcaMethods/R/llsImpute.R0000644000175100017510000002204114614231101016153 0ustar00biocbuildbiocbuild##' Missing value estimation using local least squares (LLS). First, ##' k variables (for Microarrya data usually the genes) are selected ##' by pearson, spearman or kendall correlation coefficients. Then ##' missing values are imputed by a linear combination of the k ##' selected variables. The optimal combination is found by LLS ##' regression. The method was first described by Kim et al, ##' Bioinformatics, 21(2),2005. ##' ##' Missing values are denoted as \code{NA}\cr It is not recommended ##' to use this function directely but rather to use the nni() wrapper ##' function. The methods provides two ways for missing value ##' estimation, selected by the \code{allVariables} option. The first ##' one is to use only complete variables for the regression. This is ##' preferable when the number of incomplete variables is relatively ##' small. ##' ##' The second way is to consider all variables as candidates for the ##' regression. Hereby missing values are initially replaced by the ##' columns wise mean. The method then iterates, using the current ##' estimate as input for the regression until the change between new ##' and old estimate falls below a threshold (0.001). ##' ##' @title LLSimpute algorithm ##' @param Matrix \code{matrix} -- Data containing the variables ##' (genes) in columns and observations (samples) in rows. The data ##' may contain missing values, denoted as \code{NA}. ##' @param k \code{numeric} -- Cluster size, this is the number of ##' similar genes used for regression. ##' @param center \code{boolean} -- Mean center the data if TRUE ##' @param completeObs \code{boolean} -- Return the estimated complete ##' observations if TRUE. This is the input data with NA values ##' replaced by the estimated values. ##' @param correlation \code{character} -- How to calculate the ##' distance between genes. One out of pearson | kendall | spearman , ##' see also help("cor"). ##' @param allVariables \code{boolean} -- Use only complete genes to ##' do the regression if TRUE, all genes if FALSE. ##' @param maxSteps \code{numeric} -- Maximum number of iteration ##' steps if allGenes = TRUE. ##' @param xval \code{numeric} Use LLSimpute for cross ##' validation. xval is the index of the gene to estimate, all other ##' incomplete genes will be ignored if this parameter is set. We do ##' not consider them in the cross-validation. ##' @param verbose \code{boolean} -- Print step number and relative ##' change if TRUE and allVariables = TRUE ##' @param ... Reserved for parameters used in future version of the ##' algorithm ##' @note Each step the generalized inverse of a \code{miss} x k ##' matrix is calculated. Where \code{miss} is the number of missing ##' values in variable j and \code{k} the number of neighbours. This ##' may be slow for large values of k and / or many missing ##' values. See also help("ginv"). ##' @return \item{nniRes}{Standard nni (nearest neighbour ##' imputation) result object of this package. See ##' \code{\link{nniRes}} for details.} ##' @seealso \code{\link{pca}, \link{nniRes}, \link{nni}}. ##' @examples ##' ## Load a sample metabolite dataset (metaboliteData) with already 5\% of ##' ## data missing ##' data(metaboliteData) ##' ## Perform llsImpute using k = 10 ##' ## Set allVariables TRUE because there are very few complete variables ##' result <- llsImpute(metaboliteData, k = 10, correlation="pearson", allVariables=TRUE) ##' ## Get the estimated complete observations ##' cObs <- completeObs(result) ##' @keywords multivariate ##' @export ##' @references Kim, H. and Golub, G.H. and Park, H. - Missing value ##' estimation for DNA microarray gene expression data: local least ##' squares imputation. \emph{Bioinformatics, 2005; 21(2):187-198.} ##' ##' Troyanskaya O. and Cantor M. and Sherlock G. and Brown P. and ##' Hastie T. and Tibshirani R. and Botstein D. and Altman RB. - ##' Missing value estimation methods for DNA microarrays. ##' \emph{Bioinformatics. 2001 Jun;17(6):520-525.} ##' @author Wolfram Stacklies llsImpute <- function(Matrix, k=10, center=FALSE, completeObs=TRUE, correlation="pearson", allVariables=FALSE, maxSteps=100, xval=NULL, verbose=FALSE, ...) { threshold <- 0.001 correlation <- match.arg(correlation, c("pearson", "kendall", "spearman")) ## If the data is a data frame, convert it into a matrix Matrix <- as.matrix(Matrix, rownames.force=TRUE) ## And now check if everything is right... if ( !checkData(Matrix, verbose = interactive()) ) { stop("Invalid data format! Use checkData(Matrix, verbose = TRUE) for details.\n") } ## Exit if number of neighbours exceeds number of columns if (k > ncol(Matrix)) stop("Cluster size larger than the number of columns, choose a k < ncol(Matrix)!") ## Set allVariables TRUE if k exceeds number of complete genes ## Print warning messages in the first case and when less than 50% of all genes are complete ## and allVariables == FALSE cg <- sum( apply(is.na(Matrix), 2, sum) == 0) if ( (k > cg) && (!allVariables) ) { warning("Cluster size larger than number of complete genes, using allVariables = TRUE") allVariables <- TRUE } else if ( (cg < (ncol(Matrix) / 2)) && (!allVariables) ) { warning("Less than 50% of the genes are complete, consider using allVariables = TRUE") } else if (sum(is.na(Matrix)) == 0) stop("No missing values, no need for missing value imputation :))") ## Find all genes with missing values missing <- apply(is.na(Matrix), 2, sum) > 0 missIx <- which(missing == TRUE) # For cross validation we want to only estimate one variable, the others # are not considered in the cross validation anyway if (!is.null(xval)) missIx = xval obs <- Matrix ## working copy of the data Ye <- Matrix ## Estimated complete observations ## Center the data column wise if (center) { obs <- scale(Matrix, center = TRUE, scale = FALSE) Ye <- obs means <- attr(Ye, "scaled:center") } if (allVariables) { compIx <- 1:ncol(obs) ## Impute the row average rowMeans <- apply(obs, 1, mean, na.rm = TRUE) for (i in 1:nrow(obs)) { obs[i, is.na(Matrix[i,])] <- rowMeans[i] } ## distances between all genes, ignore the diagonal (correlation to itself) distance = abs(cor(obs, obs, method = correlation)) } else { compIx <- which(missing == FALSE) ## missing genes are the rows, complete genes the columns distance = abs(cor(obs[,missIx, drop=FALSE], obs[,compIx, drop=FALSE], use="pairwise.complete.obs", method = correlation)) } change <- Inf step <- 0 while ( (change > threshold) && (step < maxSteps) ) { step <- step + 1 iteration <- 0 ## Do the regression and imputation for (index in missIx) { iteration <- iteration + 1 if (allVariables) { similar <- sort(distance[iteration,], index.return = TRUE, decreasing = TRUE) simIx <- compIx[ similar$ix[similar$ix != iteration][1:k] ] } else { similar <- sort(distance[iteration,], index.return = TRUE, decreasing = TRUE) simIx <- compIx[ similar$ix[1:k] ] } ## ## Do a regression against the k most similar genes ## See Kim et. al 2005 for details ## target <- obs[, index, drop = FALSE] tMiss <- is.na(Matrix[, index, drop = FALSE]) Apart <- obs[!tMiss, simIx, drop = FALSE] Bpart <- obs[tMiss, simIx, drop = FALSE] targetComplete <- target[!tMiss, , drop = FALSE] X <- MASS::ginv(Apart) %*% targetComplete estimate <- Bpart %*% X ## Impute the estimate Ye[tMiss, index] <- estimate } ## We do not want to iterate if allVariables == FALSE if (!allVariables || !is.null(xval)) { break } else { ## relative change in estimation change <- sqrt(sum( (obs - Ye)^2 ) / sum(obs^2)) obs <- Ye if (verbose) { cat("Step number : ", step, '\n') cat("Relative change : ", change, '\n') cat("---------------", '\n') } } } ## Add the original mean if (center) { for(i in 1:ncol(Ye)) { Ye[,i] <- Ye[,i] + means[i] } } ## Build the nniRes object ## result <- new("nniRes") if(completeObs) { Ye[!is.na(Matrix)] <- Matrix[!is.na(Matrix)] result@completeObs <- Ye } result@centered <- center result@center <- attr(scale(Matrix, center = TRUE, scale = FALSE), "scaled:center") result@nObs <- nrow(Matrix) result@nVar <- ncol(Matrix) result@method <- "llsImpute" result@correlation <- correlation result@k <- k result@missing <- sum(is.na(Matrix)) return(result) } pcaMethods/R/methods-ExpressionSet.R0000644000175100017510000000272614614231101020461 0ustar00biocbuildbiocbuild##' This function can be used to conveniently replace the expression ##' matrix in an \code{ExpressionSet} with the completed data from a ##' \code{pcaRes} object. ##' ##' This is not a standard \code{as} function as \code{pcaRes} ##' object alone not can be converted to an \code{ExpressionSet} (the ##' \code{pcaRes} object does not hold any \code{phenoData} for ##' example). ##' @title Convert pcaRes object to an expression set ##' @param object \code{pcaRes} -- The object containing the completed ##' data. ##' @param exprSet \code{ExpressionSet} -- The object passed on to ##' \code{pca} for missing value estimation. ##' @return An object without missing values of class \code{ExpressionSet}. ##' @export ##' @author Wolfram Stacklies \cr CAS-MPG Partner Institute for ##' Computational Biology, Shanghai, China ##' @keywords multivariate asExprSet <- function(object, exprSet) { if(!inherits(exprSet, "ExpressionSet")) stop("Parameter exprSet must be of type ExpressionSet") if(!inherits(object, "pcaRes") & !inherits(object, "nniRes")) stop("Parameter object must be either of type pcaRes or nniRes") if (is.null(completeObs(object))) stop("completeObs(object) is NULL, exiting") if(!all(dim(exprs(exprSet)) == dim(t(completeObs(object))))) stop("Dimensions of exprs(exprSet) and completeObs(object) do not match. Did you really do missing value estimation using this ExpressionSet object?") exprs(exprSet) <- t(completeObs(object)) return(exprSet) } pcaMethods/R/methods-nniRes.R0000644000175100017510000000161114614231101017074 0ustar00biocbuildbiocbuild##' Print a brief description of nniRes model ##' @title Print a nniRes model ##' @param x An \code{nniRes} object ##' @param ... Not used ##' @return Nothing, used for side-effect ##' @export ##' @author Henning Redestig showNniRes <- function(x, ...) { summary(x) cat(dim(x)["nVar"], "\tVariables\n") cat(dim(x)["nObs"],"\tSamples\n") cat(nmissing(x), "\tNAs (", round(100 * nmissing(x) / (nObs(x) * nVar(x)), getOption("str")$digits.d), "%)\n") cat("k was set to", x@k, "\n") if(centered(x)) cat("Data was mean centered before running LLSimpute \n") else cat("Data was NOT mean centered before running LLSimpute \n") if(scaled(x)) cat("Data was scaled before running LLSimpute \n") else cat("Data was NOT scaled before running LLSimpute \n") } setMethod("print", "nniRes", showNniRes) setMethod("show", "nniRes", function(object) showNniRes(object)) pcaMethods/R/methods-pcaRes.R0000644000175100017510000007727514614231101017076 0ustar00biocbuildbiocbuild##' The leverages of PCA model indicate how much influence each ##' observation has on the PCA model. Observations with high leverage ##' has caused the principal components to rotate towards them. It can ##' be used to extract both "unimportant" observations as well as ##' picking potential outliers. ##' ##' Defined as \eqn{Tr(T(T'T)^{-1}T')}{Tr(T(T'T)^(-1)T')} ##' @title Extract leverages of a PCA model ##' @param object a \code{pcaRes} object ##' @return The observation leverages as a numeric vector ##' @references Introduction to Multi- and Megavariate Data Analysis ##' using Projection Methods (PCA and PLS), L. Eriksson, E. Johansson, ##' N. Kettaneh-Wold and S. Wold, Umetrics 1999, p. 466 ##' @examples ##' data(iris) ##' pcIr <- pca(iris[,1:4]) ##' ## versicolor has the lowest leverage ##' with(iris, plot(leverage(pcIr)~Species)) ##' @keywords multivariate ##' @aliases leverage leverage,pcaRes-method ##' @author Henning Redestig setMethod("leverage", "pcaRes", function(object) { diag(scores(object) %*% solve(crossprod(scores(object))) %*% t(scores(object))) }) ##' Distance to the model of X-space. ##' ##' Measures how well described the observations are, i.e. how well ##' they fit in the mode. High DModX indicate a poor fit. Defined as: ##' ##' \eqn{\frac{\sqrt{\frac{SSE_i}{K-A}}}{\sqrt{\frac{SSE}{(N-A-A_0)(K-A)}}}} ##' ##' For observation \eqn{i}, in a model with \eqn{A} components, ##' \eqn{K} variables and \eqn{N} obserations. SSE is the squared sum ##' of the residuals. \eqn{A_0} is 1 if model was centered and 0 ##' otherwise. DModX is claimed to be approximately F-distributed and ##' can therefore be used to check if an observation is significantly ##' far away from the PCA model assuming normally distributed data. ##' ##' Pass original data as an argument if the model was calculated with ##' \code{completeObs=FALSE}. ##' @title DModX ##' @usage DModX(object, dat, newdata=FALSE, type=c("normalized","absolute"), ...) ##' @param object a pcaRes object ##' @param dat the original data, taken from \code{completeObs} if ##' left missing. ##' @param newdata logical indicating if this data was part of the ##' training data or not. If it was, it is adjusted by a near one factor ##' \eqn{v=(N/ (N-A-A0))^-1} ##' @param type if absolute or normalized values should be ##' given. Normalized values are adjusted to the the total RSD of the ##' model. ##' @param ... Not used ##' @return A vector with distances from observations to the PCA model ##' @aliases DModX DModX,pcaRes-method ##' @examples ##' data(iris) ##' pcIr <- pca(iris[,1:4]) ##' with(iris, plot(DModX(pcIr)~Species)) ##' @references Introduction to Multi- and Megavariate Data Analysis ##' using Projection Methods (PCA and PLS), L. Eriksson, E. Johansson, ##' N. Kettaneh-Wold and S. Wold, Umetrics 1999, p. 468 ##' @author Henning Redestig setMethod("DModX", "pcaRes", function(object, dat, newdata=FALSE, type=c("normalized","absolute"), ...) { type <- match.arg(type) if(missing(dat)) { if(!is.null(completeObs(object))) dat <- completeObs(object) else stop("missing data when calculating DModX") } A0 <- as.integer(centered(object)) ny <- ifelse(newdata, 1, sqrt(nObs(object) / (nObs(object) - nP(object) - A0))) E2 <- resid(object, dat)^2 s <- sqrt(rowSums(E2) / (nVar(object) - nP(object))) * ny if(type == "absolute") return(s) s0 <- sqrt(sum(E2) / ((nObs(object) - nP(object) - A0) * (nVar(object) - nP(object)))) s / s0 }) ##' Get number of PCs ##' @param object pcaRes object ##' @param ... not used ##' @return Number of PCs ##' @aliases nP nP,pcaRes-method ##' @usage nP(object, ...) ##' @author Henning Redestig setMethod("nP", "pcaRes", function(object, ...) { if(is.null(object@nPcs) & !is.null(scores(object))) return(ncol(scores(object))) object@nPcs }) ##' Get cross-validation statistics (e.g. \eqn{Q^2}). ##' @param object pcaRes object ##' @param ... not used ##' @return vector CV statistics ##' @aliases cvstat cvstat,pcaRes-method ##' @usage cvstat(object, ...) ##' @author Henning Redestig setMethod("cvstat", "pcaRes", function(object, ...) { object@cvstat }) ##' Get number of PCs. ##' @param object pcaRes object ##' @param ... not used ##' @note Try to use \code{link{nP}} instead since \code{nPcs} tend to ##' clash with argument names. ##' @return Number of PCs ##' @usage nPcs(object, ...) ##' @aliases nPcs nPcs,pcaRes-method ##' @author Henning Redestig setMethod("nPcs", "pcaRes", function(object, ...) { nP(object) }) ##' Get the number of observations used to build the PCA model. ##' @param object pcaRes object ##' @param ... Not used ##' @usage nObs(object, ...) ##' @aliases nObs nObs,pcaRes-method ##' @return Number of observations ##' @author Henning Redestig setMethod("nObs", "pcaRes", function(object, ...) { object@nObs }) ##' Get the number of variables used to build the PCA model. ##' @param object pcaRes object ##' @param ... Not used ##' @usage nVar(object, ...) ##' @aliases nVar nVar,pcaRes-method ##' @return Number of variables ##' @author Henning Redestig setMethod("nVar", "pcaRes", function(object, ...) { object@nVar }) ##' Check centering was part of the model ##' @param object pcaRes object ##' @param ... Not used ##' @usage centered(object, ...) ##' @aliases centered centered,pcaRes-method ##' @return TRUE if model was centered ##' @author Henning Redestig setMethod("centered", "pcaRes", function(object, ...) { if(is.null(object@centered)) return(FALSE) object@centered }) ##' Get the centers of the original variables ##' @param object pcaRes object ##' @param ... Not used ##' @usage center(object, ...) ##' @aliases center center,pcaRes-method ##' @return Vector with the centers ##' @author Henning Redestig setMethod("center", "pcaRes", function(object, ...) { object@center }) setMethod("completeObs", "pcaRes", function(object, ...) { object@completeObs }) ##' Get the original data with missing values replaced with predicted ##' values. ##' @param object object to fetch complete data from ##' @param ... Not used ##' @usage completeObs(object, ...) ##' @aliases completeObs completeObs,nniRes-method ##' completeObs,pcaRes-method ##' @return Completed data (matrix) ##' @author Henning Redestig setMethod("completeObs", "nniRes", function(object, ...) { object@completeObs }) ##' Get the used PCA method ##' @param object pcaRes object ##' @param ... Not used ##' @usage method(object, ...) ##' @aliases method method,pcaRes-method ##' @return The used pca method ##' @author Henning Redestig setMethod("method", "pcaRes", function(object, ...) { object@method }) setMethod("nmissing", "nniRes", function(object, ...) { sum(object@missing) }) ##' Missing values ##' @param object pcaRes object ##' @param ... Not used ##' @usage nmissing(object, ...) ##' @aliases nmissing nmissing,pcaRes-method nmissing,nniRes-method ##' @return Get the number of missing values ##' @author Henning Redestig setMethod("nmissing", "pcaRes", function(object, ...) { sum(object@missing) }) ##' Get a matrix with indicating the elements that were missing in the ##' input data. Convenient for estimating imputation performance. ##' @param object pcaRes object ##' @param ... Not used ##' @usage wasna(object, ...) ##' @aliases wasna wasna,pcaRes-method ##' @return A matrix with logicals ##' @examples ##' data(metaboliteData) ##' data(metaboliteDataComplete) ##' result <- pca(metaboliteData, nPcs=2) ##' plot(completeObs(result)[wasna(result)], metaboliteDataComplete[wasna(result)]) ##' @author Henning Redestig setMethod("wasna", "pcaRes", function(object, ...) { object@missing }) ##' Get the standard deviations of the scores (indicates their ##' relevance) ##' @param object pcaRes object ##' @param ... Not used ##' @usage sDev(object, ...) ##' @aliases sDev sDev,pcaRes-method ##' @return Standard devations of the scores ##' @author Henning Redestig setMethod("sDev", "pcaRes", function(object, ...) { object@sDev }) ##' Check if scaling was part of the PCA model ##' @param object pcaRes object ##' @param ... Not used ##' @usage scaled(object, ...) ##' @aliases scaled scaled,pcaRes-method ##' @return TRUE if scaling was part of the PCA model ##' @author Henning Redestig setMethod("scaled", "pcaRes", function(object, ...) { if(is.null(object@scaled)) return(FALSE) object@scaled != "none" }) ##' Get the scales (e.g. standard deviations) of the original ##' variables ##' @param object pcaRes object ##' @param ... Not used ##' @usage scl(object, ...) ##' @aliases scl scl,pcaRes-method ##' @return Vector with the scales ##' @seealso \code{\link{prep}} ##' @author Henning Redestig setMethod("scl", "pcaRes", function(object, ...) { object@scale }) ##' Cumulative R2 is the total ratio of variance that is being ##' explained by the model ##' @param object a \code{pcaRes} model ##' @param ... Not used ##' @return Get the cumulative R2 ##' @aliases R2cum R2cum,pcaRes-method ##' @author Henning Redestig setMethod("R2cum", "pcaRes", function(object, ...) { object@R2cum }) ##' Get scores from a pcaRes object ##' @param object a pcaRes object ##' @param ... not used ##' @return The scores as a matrix ##' @export ##' @author Henning Redestig ##' @method scores pcaRes scores.pcaRes <- function(object, ...) object@scores ##' Get scores from a pcaRes object ##' @param object a pcaRes object ##' @param ... not used ##' @return The scores as a matrix ##' @seealso \code{\link{scores.pcaRes}} ##' @aliases scores scores,pcaRes-method ##' @author Henning Redestig setMethod("scores", "pcaRes", scores.pcaRes) ##' Get loadings from a pcaRes object ##' @param object a pcaRes object ##' @param ... not used ##' @return The loadings as a matrix ##' @export ##' @author Henning Redestig ##' @method loadings pcaRes loadings.pcaRes <- function(object, ...) object@loadings ##' Get loadings from a pcaRes object ##' @param object a pcaRes object ##' @param ... not used ##' @return The loadings as a matrix ##' @seealso \code{\link{loadings.pcaRes}} ##' @author Henning Redestig ##' @aliases loadings,pcaRes-method setMethod("loadings", "pcaRes", loadings.pcaRes) ##' Crude way to unmask the function with the same name from ##' \code{stats} ##' @param object any object ##' @param ... not used ##' @return The loadings ##' @author Henning Redestig ##' @aliases loadings loadings,ANY-method setMethod("loadings", "ANY", function(object,...) { stats::loadings(object) }) ##' Dimensions of a PCA model ##' @param x a pcaRes object ##' @return Get the dimensions of this PCA model ##' @method dim pcaRes ##' @export ##' @author Henning Redestig dim.pcaRes <- function(x) { res <- c(nObs(x), nVar(x), nP(x)) names(res) <- c("nObs", "nVar", "nPcs") res } ##' Print basic information about pcaRes object ##' @title Print/Show for pcaRes ##' @param x a pcaRes object ##' @param ... not used ##' @return nothing, used for its side effect ##' @name show-methods ##' @export ##' @author Henning Redestig showPcaRes <- function(x, ...) { summary(x) cat(nVar(x), "\tVariables\n") cat(nObs(x),"\tSamples\n") cat(nmissing(x), "\tNAs (", round(100 * nmissing(x) / (nObs(x) * nVar(x)), getOption("str")$digits.d), "%)\n") cat(nP(x), "\tCalculated component(s)\n") if(centered(x)) cat("Data was mean centered before running PCA \n") else cat("Data was NOT mean centered before running PCA \n") if(scaled(x)) cat("Data was scaled before running PCA \n") else cat("Data was NOT scaled before running PCA \n") cat("Scores structure:\n") print(dim(scores(x))) cat("Loadings structure:\n") if(method(x) == "nlpca") { cat("Inverse hierarchical neural network architecture\n") cat(drop(x@network@net), "\n") cat("Functions in layers\n") cat(x@network@fct, "\n") cat("hierarchic layer:", x@network@hierarchic$layer, "\n") cat("hierarchic coefficients:", x@network@hierarchic$var, "\n") cat("scaling factor:", x@network@scalingFactor, "\n") } else{ print(dim(loadings(x))) } } ##' @aliases print,pcaRes-method print,nniRes-method ##' @name show-methods setMethod("print", "pcaRes", showPcaRes) ## @importFrom methods show ##' @aliases show,pcaRes-method show,nniRes-method ##' @param object the object to print information about ##' @name show-methods setMethod("show", "pcaRes", function(object) showPcaRes(object)) ##' Visualize two-components simultaneously ##' ##' This is a method for the generic function 'biplot'. There is ##' considerable confusion over the precise definitions: those of the ##' original paper, Gabriel (1971), are followed here. Gabriel and ##' Odoroff (1990) use the same definitions, but their plots actually ##' correspond to \code{pc.biplot = TRUE}. ##' @title Plot a overlaid scores and loadings plot ##' @param x a pcaRes object ##' @param choices which two pcs to plot ##' @param scale The variables are scaled by ##' \eqn{\lambda^{scale}}{lambda^scale} and the observations are ##' scaled by \eqn{\lambda^{scale}}{lambda ^ (1-scale)} where ##' \code{lambda} are the singular values as computed by ##' \code{princomp}. Normally \eqn{0\le{}scale\le{}1}{0 <= scale <= ##' 1}, and a warning will be issued if the specified 'scale' is ##' outside this range. ##' @param pc.biplot If true, use what Gabriel (1971) refers to as a ##' "principal component biplot", with \eqn{\lambda=1}{lambda = 1} and ##' observations scaled up by sqrt(n) and variables scaled down by ##' sqrt(n). Then the inner products between variables approximate ##' covariances and distances between observations approximate ##' Mahalanobis distance. ##' @param ... optional arguments to be passed to ##' \code{biplot.default}. ##' @return a plot is produced on the current graphics device. ##' @method biplot pcaRes ##' @export ##' @examples ##' data(iris) ##' pcIr <- pca(iris[,1:4]) ##' biplot(pcIr) ##' @seealso \code{prcomp}, \code{pca}, \code{princomp} ##' @author Kevin Wright, Adapted from \code{biplot.prcomp} ##' @keywords multivariate ##' @name biplot-methods biplot.pcaRes <- function(x, choices=1:2, scale=1, pc.biplot=FALSE, ...) { if(length(choices)!=2) stop("length of choices must be 2") scores <- scores(x) n <- nrow(scores) lam <- sDev(x)[choices] * sqrt(n) if(scale < 0 || scale > 1) warning("'scale' is outside [0,1]") if(scale != 0) lam <- lam^scale else lam <- 1 if(pc.biplot) lam <- lam/sqrt(n) biplot(t(t(scores[,choices])/lam), t(t(loadings(x)[, choices]) * lam), , ...) invisible() } ##' @aliases biplot,pcaRes-method ## @importFrom stats biplot ##' @name biplot-methods setMethod("biplot", "pcaRes", biplot.pcaRes) ##' Flexible calculation of R2 goodness of fit. ##' @title R2 goodness of fit ##' @param object a PCA model object ##' @param direction choose between calculating R2 per variable, per ##' observation or for the entire data with 'variables', ##' 'observations' or 'complete'. ##' @param data the data used to fit the model ##' @param pcs the number of PCs to use to calculate R2 ##' @aliases R2VX R2VX,pcaRes-method ##' @examples ##' R2VX(pca(iris)) ##' @return A vector with R2 values ##' @author Henning Redestig setMethod('R2VX', 'pcaRes', function(object, direction=c('variables', 'observations', 'complete'), data=completeObs(object), pcs=nP(object)) { direction <- match.arg(direction) if(is.null(data)) stop('missing input when calculating R2') if(any(is.na(data))) stop('missing values not allowed for calculating R2') dat <- prep(data, scale=scl(object), center=center(object)) xhat <- resid(object, pcs=pcs, data=dat, pre=FALSE, post=FALSE) switch(direction, variables={ 1 - colSums(xhat^2) / colSums(dat^2) }, observations={ 1 - rowSums(xhat^2) / rowSums(dat^2) }, complete={ 1 - sum(xhat^2) / sum(dat^2) }) }) setAs('pcaRes', 'data.frame', function(from) { tt <- scores(from) pp <- loadings(from) if(is.null(rownames(tt))) rownames(tt) <- 1:nrow(tt) if(is.null(rownames(pp))) rownames(pp) <- 1:nrow(pp) dfs <- as.data.frame(tt) dfs$names <- rownames(tt) dfs$type <- 'scores' dfl <- as.data.frame(pp) dfl$names <- rownames(pp) dfl$type <- 'loadings' rownames(dfl) <- rownames(dfs) <- NULL rbind(dfl, dfs) }) ##' Print a brief description of the PCA model ##' @title Summary of PCA model ##' @param object a pcaRes object ##' @param ... Not used ##' @return Nothing, used for side-effect ##' @aliases summary summary.pcaRes summary,pcaRes-method ##' @author Henning Redestig ##' @export ##' @name summary ##' @method summary pcaRes summary.pcaRes <- function(object, ...){ cat(method(object), "calculated PCA\n") cat("Importance of component(s):\n") prop <- vector(length=length(R2cum(object)), mode="numeric") prop[1] <- R2cum(object)[1] if (length(R2cum(object)) > 1) { for (i in 2:length(prop)) { prop[i] <- R2cum(object)[i] - R2cum(object)[i-1] } } r <- rbind(prop, R2cum(object)) rownames(r) <- c("R2", "Cumulative R2") colnames(r) <- paste("PC", 1:nP(object), sep="") print(r, digits=4) invisible(r) } setMethod("summary", "pcaRes", summary.pcaRes) ##' Predict data using PCA model ##' ##' This function extracts the predict values from a pcaRes object for ##' the PCA methods SVD, Nipals, PPCA and BPCA. Newdata is first ##' centered if the PCA model was and then scores (\eqn{T}) and data ##' (\eqn{X}) is 'predicted' according to : ##' \eqn{\hat{T}=X_{new}P}{That=XnewP} ##' \eqn{\hat{X}_{new}=\hat{T}P'}{Xhat=ThatP'}. Missing values are ##' set to zero before matrix multiplication to achieve NIPALS like ##' treatment of missing values. ##' @title Predict values from PCA. ##' @param object \code{pcaRes} the \code{pcaRes} object of interest. ##' @param newdata \code{matrix} new data with same number of columns ##' as the used to compute \code{object}. ##' @param pcs \code{numeric} The number of PC's to consider ##' @param pre pre-process \code{newdata} based on the pre-processing ##' chosen for the PCA model ##' @param post unpre-process the final data (add the center back etc) ##' @param ... Not passed on anywhere, included for S3 consistency. ##' @return A list with the following components: \item{scores}{The ##' predicted scores} \item{x}{The predicted data} ##' @method predict pcaRes ##' @keywords multivariate ##' @examples ##' data(iris) ##' hidden <- sample(nrow(iris), 50) ##' pcIr <- pca(iris[-hidden,1:4]) ##' pcFull <- pca(iris[,1:4]) ##' irisHat <- predict(pcIr, iris[hidden,1:4]) ##' cor(irisHat$scores[,1], scores(pcFull)[hidden,1]) ##' @export ##' @name predict-methods ##' @author Henning Redestig predict.pcaRes <- function(object, newdata, pcs=nP(object), pre=TRUE, post=TRUE, ...) { if(!method(object) %in% listPcaMethods("linear")) stop("predict method not implemented for that type of PCA") if(pre) newdata <- prep(newdata, scl(object), center(object)) ## set na's to zero to achieve NIPALS like prediction newdata[is.na(newdata)] <- 0 tnew <- newdata %*% loadings(object)[,1:pcs,drop=FALSE] xhat <- tcrossprod(tnew, loadings(object)[,1:pcs,drop=FALSE]) if(post) xhat <- prep(xhat, scl(object), center(object), reverse=TRUE) list(scores=tnew, x=xhat) } ## @importFrom stats predict ##' @name predict-methods ##' @aliases predict,pcaRes-method setMethod("predict", "pcaRes", predict.pcaRes) ##' This function extracts the residuals values from a pcaRes object ##' for the PCA methods SVD, Nipals, PPCA and BPCA ##' @title Residuals values from a PCA model. ##' @param object \code{pcaRes} the \code{pcaRes} object of interest. ##' @param data \code{matrix} The data that was used to calculate the ##' PCA model (or a different dataset to e.g. adress its proximity to ##' the model). ##' @param ... Passed on to \code{\link{predict.pcaRes}}. E.g. setting ##' the number of used components. ##' @return A \code{matrix} with the residuals ##' @method residuals pcaRes ##' @keywords multivariate ##' @export ##' @name rediduals-methods ##' @examples ##' data(iris) ##' pcIr <- pca(iris[,1:4]) ##' head(residuals(pcIr, iris[,1:4])) ##' @author Henning Redestig residuals.pcaRes <- function(object, data=completeObs(object), ...) { if(is.null(data)) stop("data missing when calculating residuals") data - predict(object, data, ...)$x } ##' @aliases residuals,pcaRes-method ##' @name rediduals-methods setMethod("residuals", "pcaRes", residuals.pcaRes) ##' @name rediduals-methods ##' @aliases resid,pcaRes-method setMethod("resid", "pcaRes", residuals.pcaRes) ##' Fitted values of a PCA model ##' ##' This function extracts the fitted values from a pcaResobject. For ##' PCA methods like SVD, Nipals, PPCA etc this is basically just the ##' scores multipled by the loadings and adjusted for pre-processing. ##' for non-linear PCA the original data is propagated through the ##' network to obtain the approximated data. ##' @title Extract fitted values from PCA. ##' @param object the \code{pcaRes} object of interest. ##' @param data For standard PCA methods this can safely be left null ##' to get scores x loadings but if set, then the scores are obtained ##' by projecting provided data onto the loadings. If data contains ##' missing values the result will be all NA. Non-linear PCA is an ##' exception, here if data is NULL then data is set to the ##' completeObs and propaged through the network. ##' @param nPcs The number of PC's to consider ##' @param pre pre-process \code{data} based on the pre-processing ##' chosen for the PCA model ##' @param post unpre-process the final data (add the center back etc ##' to get the final estimate) ##' @param ... Not used ##' @return A matrix representing the fitted data ##' @keywords multivariate ##' @method fitted pcaRes ##' @examples ##' pc <- pca(iris[,1:4], nPcs=4, center=TRUE, scale="uv") ##' sum( (fitted(pc) - iris[,1:4])^2 ) ##' @export ##' @name fitted-methods ##' @author Henning Redestig fitted.pcaRes <- function(object, data=NULL, nPcs=nP(object), pre=TRUE, post=TRUE, ...) { if(method(object) %in% listPcaMethods("nonlinear")) { if(is.null(data) & is.null(completeObs(object))) stop("completeObs slot is empty -- provide the training data") if(is.null(data) & !is.null(completeObs(object))) data <- completeObs(object) if(is.null(data)) stop("nlpca requires original data to be provide") if(pre) data <- prep(data, scl(object), center(object)) recData <- errorHierarchic(object@network, t(scores(object)), t(data))$out[,,nPcs] recData <- t(recData / object@network@scalingFactor) } else { if(!is.null(data)) { if(pre) data <- prep(data, scl(object), center(object)) tt <- data %*% loadings(object)[,1:nPcs, drop=FALSE] } if(is.null(data)) tt <- scores(object)[,1:nPcs, drop=FALSE] recData <- tcrossprod(tt, loadings(object)[,1:nPcs, drop=FALSE]) } if(post) recData <- prep(recData, scl(object), center(object), reverse=TRUE) return(recData) } ## @importFrom stats fitted ##' @name fitted-methods ##' @aliases fitted,pcaRes-method setMethod("fitted", "pcaRes", fitted.pcaRes) ##' Plot the computed diagnostics of PCA model to get an idea of their ##' importance. Note though that the standard screeplot shows the ##' standard deviations for the PCs this method shows the R2 values ##' which empirically shows the importance of the P's and is thus ##' applicable for any PCA method rather than just SVD based PCA. ##' ##' If cross-validation was done for the PCA the plot will also show ##' the CV based statistics. A common rule-of-thumb for determining ##' the optimal number of PCs is the PC where the CV diagnostic is at ##' its maximum but not very far from \eqn{R^2}. ##' @title Plot diagnostics (screeplot) ##' @param x \code{pcaRes} The pcaRes object. ##' @param y not used ##' @param main title of the plot ##' @param col Colors of the bars ##' @param ... further arguments to barplot ##' @return None, used for side effect. ##' @seealso \link{screeplot} ##' @examples ##' data(metaboliteData) ##' pc <- pca(t(metaboliteData), nPcs=5, cv="q2", scale="uv") ##' plot(pc) ##' @method plot pcaRes ##' @aliases plot.pcaRes plot,pcaRes-method ##' @export ##' @author Henning Redestig plot.pcaRes <- function(x, y=NULL, main=deparse(substitute(object)), col=gray(c(0.9, 0.5)), ...) { y <- NULL ## the deparse(subsitute(object)) later fails otherwise main <- main if(!is.null(cvstat(x))) { cvs <- cvstat(x) if(length(cvs) != nP(x)) cvs <- c(cvs, rep(NA, nP(x) - length(cvs))) xx <- rbind(R2cum(x), cvs) barplot(xx, beside=TRUE, ylim=c(0,1.1), col=col, main=main, names.arg=paste("PC", 1:nP(x), sep=""), ...) legend(x="topleft", fill=col, legend=c(expression(R^2), expression(Q^2))) } else barplot(R2cum(x), ylim=c(0,1.1), ylab=expression(R^2), main=main, names.arg=paste("PC", 1:nP(x), sep=""), col=col[1], ...) } setMethod("plot", "pcaRes", plot.pcaRes) ##' A common way of visualizing two principal components ##' ##' This method is meant to be used as a quick way to visualize ##' results, if you want a more specific plot you probably want to ##' get the scores, loadings with \code{scores(object)}, ##' \code{loadings(object)} and then design your own plotting method. ##' @title Side by side scores and loadings plot ##' @usage slplot(object, pcs=c(1,2), scoresLoadings=c(TRUE, TRUE), ##' sl="def", ll="def", hotelling=0.95, rug=TRUE, sub=NULL,...) ##' @param object a pcaRes object ##' @param pcs which two pcs to plot ##' @param scoresLoadings Which should be shown scores and or loadings ##' @param sl labels to plot in the scores plot ##' @param ll labels to plot in the loadings plot ##' @param hotelling confidence interval for ellipse in the score plot ##' @param rug logical, rug x axis in score plot or not ##' @param sub Subtitle, defaults to annotate with amount of explained ##' variance. ##' @param ... Further arguments to plot functions. Prefix arguments ##' to \code{par()} with 's' for the scores plot and 'l' for the ##' loadings plot. I.e. cex become scex for setting character ##' expansion in the score plot and lcex for the loadings plot. ##' @return None, used for side effect. ##' @note Uses layout instead of par to provide side-by-side so it ##' works with Sweave (but can not be combined with ##' \code{par(mfrow=..))} ##' @author Henning Redestig ##' @seealso \code{\link{pca}}, \code{\link{biplot}} ##' @aliases slplot slplot,pcaRes-method ##' @examples ##' data(iris) ##' pcIr <- pca(iris[,1:4], scale="uv") ##' slplot(pcIr, sl=NULL, spch=5) ##' slplot(pcIr, sl=NULL, lcex=1.3, scol=as.integer(iris[,5])) ##' @keywords multivariate setMethod("slplot", "pcaRes", function(object, pcs=c(1,2), scoresLoadings=c(TRUE, TRUE), sl=rownames(scores(object)), ll=rownames(loadings(object)), hotelling=0.95, rug=FALSE, sub=NULL,...) { opar <- par(no.readonly=TRUE) cl <- match.call() mainArgs <- c(1,match(c("ll", "sl", "scoresLoadings", "sub"), names(cl), 0)) scoreArgs <- grep("^s", names(cl)[-mainArgs]) loadingArgs <- grep("^l", names(cl)[-mainArgs]) if(!is.null(ll) & length(ll) != nVar(object)) stop("Loading labels do not match the object dimensions") if(!is.null(sl) & length(sl) != nObs(object)) stop("Score labels do not match the object dimensions") if(is.null(sl)) sl <- NA if(is.null(ll)) ll <- NA ## no loadings for non-linear pca if(method(object) %in% listPcaMethods("nonlinear") && scoresLoadings[2]) scoresLoadings[2] <- FALSE if(length(pcs) > 2) plotPcs(object, pcs, scoresLoadings=scoresLoadings,...) else { if(is.null(sub)) sub <- paste(sprintf("%.2f", R2cum(object)[max(pcs)] * 100), "% of the variance explained", sep="") if(sum(scoresLoadings) == 2) layout(matrix(c(1,2), 1, 2, TRUE), respect=matrix(c(1,1), 1, 2)) ## exception plot if one dimensional if (length(pcs) == 1 | nP(object) == 1) { pcs <- 1 ## score plot if(scoresLoadings[1]) { newCall <- call("barplot", height=scores(object)[,pcs], main="Scores", las=3, ylab=paste("PC", pcs), sub=sub, names.arg=sl) tmp <- cl[-mainArgs][scoreArgs] names(tmp) <- gsub("^s", "", names(tmp)) for(i in 1:length(tmp)) { newCall[[length(newCall) + 1]] <- tmp[[i]] names(newCall)[length(newCall)] <- names(tmp)[i] } eval(newCall) } ## loadingplot if(scoresLoadings[2]) { newCall <- call("barplot", height=loadings(object)[,pcs], main="Loadings", las=3, ylab=paste("PC", pcs), names.arg=ll) if(length(loadingArgs) > 0) { tmp <- cl[-mainArgs][loadingArgs] names(tmp) <- gsub("^l", "", names(tmp)) for(i in 1:length(tmp)) { newCall[[length(newCall) + 1]] <- tmp[[i]] names(newCall)[length(newCall)] <- names(tmp)[i] } } eval(newCall) } return(invisible(TRUE)) } ## the score plot if(scoresLoadings[1]) { ## setup plot plotCall <- call("plot", x=scores(object)[,pcs], main="Scores", ylab=paste("PC", pcs[2]), sub=sub, xlab=paste("PC", pcs[1])) if(length(scoreArgs) > 0) { tmp <- cl[-mainArgs][scoreArgs] names(tmp) <- gsub("^s", "", names(tmp)) for(i in 1:length(tmp)) { plotCall[[length(plotCall) + 1]] <- tmp[[i]] names(plotCall)[length(plotCall)] <- names(tmp)[i] } } ## add text if (!is.null(sl) & !all(is.na(sl))) { plotCall[[length(plotCall) + 1]] <- "n" names(plotCall)[length(plotCall)] <- "type" textCall <- call("text", x=scores(object)[,pcs], labels=sl) if(length(scoreArgs) > 0) { tmp <- cl[-mainArgs][scoreArgs] names(tmp) <- gsub("^s", "", names(tmp)) for(i in 1:length(tmp)) { textCall[[length(textCall) + 1]] <- tmp[[i]] names(textCall)[length(textCall)] <- names(tmp)[i] } } } eval(plotCall) if (!is.null(sl) & !all(is.na(sl))) eval(textCall) if(rug) rug(scores(object)[,1]) abline(h=0, v=0) if(!is.null(hotelling)) { A <- length(pcs) el <- simpleEllipse(scores(object)[,pcs[1]], scores(object)[,pcs[2]], alfa=hotelling) lines(el) } } ## the loading plot if(scoresLoadings[2]) { ## setup plot plotCall <- call("plot", x=loadings(object)[,pcs], main="Loadings", ylab=paste("PC", pcs[2]), xlab=paste("PC", pcs[1])) if(length(loadingArgs) > 0) { tmp <- cl[-mainArgs][loadingArgs] names(tmp) <- gsub("^l", "", names(tmp)) for(i in 1:length(tmp)) { plotCall[[length(plotCall) + 1]] <- tmp[[i]] names(plotCall)[length(plotCall)] <- names(tmp)[i] } } ## add text if (!is.null(ll) & !all(is.na(ll))) { plotCall[[length(plotCall) + 1]] <- "n" names(plotCall)[length(plotCall)] <- "type" textCall <- call("text", x=loadings(object)[,pcs], labels=ll) if(length(loadingArgs) > 0) { tmp <- cl[-mainArgs][loadingArgs] names(tmp) <- gsub("^l", "", names(tmp)) for(i in 1:length(tmp)) { textCall[[length(textCall) + 1]] <- tmp[[i]] names(textCall)[length(textCall)] <- names(tmp)[i] } } } eval(plotCall) if (!is.null(ll) & !all(is.na(ll))) eval(textCall) abline(h=0, v=0) } } par(opar) }) pcaMethods/R/nipalsPca.R0000644000175100017510000001513614614231101016116 0ustar00biocbuildbiocbuild##' PCA by non-linear iterative partial least squares ##' ##' Can be used for computing PCA on a numeric matrix using either the ##' NIPALS algorithm which is an iterative approach for estimating the ##' principal components extracting them one at a time. NIPALS can ##' handle a small amount of missing values. It is not recommended to ##' use this function directely but rather to use the pca() wrapper ##' function. There is a C++ implementation given as \code{nipalsPca} ##' which is faster. ##' @title NIPALS PCA implemented in R ##' @param Matrix Pre-processed (centered, scaled) numerical matrix ##' samples in rows and variables as columns. ##' @param nPcs Number of components that should be extracted. ##' @param varLimit Optionally the ratio of variance that should be ##' explained. \code{nPcs} is ignored if varLimit < 1 ##' @param maxSteps Defines how many iterations can be done before ##' algorithm should abort (happens almost exclusively when there were ##' some wrong in the input data). ##' @param threshold The limit condition for judging if the algorithm ##' has converged or not, specifically if a new iteration is done if ##' \eqn{(T_{old} - T)^T(T_{old} - T) > \code{limit}}. ##' @param verbose Show simple progress information. ##' @param ... Only used for passing through arguments. ##' @return A \code{pcaRes} object. ##' @references Wold, H. (1966) Estimation of principal components and ##' related models by iterative least squares. In Multivariate ##' Analysis (Ed., P.R. Krishnaiah), Academic Press, NY, 391-420. ##' @author Henning Redestig ##' @seealso \code{prcomp}, \code{princomp}, \code{pca} ##' @examples ##' data(metaboliteData) ##' mat <- prep(t(metaboliteData)) ##' ## c++ version is faster ##' system.time(pc <- RnipalsPca(mat, method="rnipals", nPcs=2)) ##' system.time(pc <- nipalsPca(mat, nPcs=2)) ##' ## better use pca() ##' pc <- pca(t(metaboliteData), method="rnipals", nPcs=2) ##' \dontshow{stopifnot(sum((fitted(pc) - t(metaboliteData))^2, na.rm=TRUE) < 200)} ##' @keywords multivariate ##' @export RnipalsPca <- function(Matrix, nPcs=2, varLimit=1, maxSteps=5000, threshold=1e-6, verbose=interactive(), ...) { nVar <- ncol(Matrix) ##Find a good? starting column -- better way? startingColumn <- 1 ## sum(c(NA, NA), na.rm=TRUE) is 0, but we want NA sum.na <- function(x){ ifelse(all(is.na(x)), NA, sum(x, na.rm=TRUE))} TotalSS <- sum(Matrix*Matrix, na.rm=TRUE) ph <- rep(0, nVar) R2cum <- rep(NA, nPcs) scores <- NULL loadings <- NULL anotherPc <- TRUE l <- 1 while(anotherPc) { count <- 0 #number of iterations done th <- Matrix[,startingColumn] #first column is starting vector for th continue <- TRUE if(verbose) cat(paste("Calculating PC", l, ": ", sep="")) while(continue) { count <- count+1 ph <- rep(0, nVar) ##Calculate loadings through LS regression ##Note: Matrix*th is column-wise multiplication tsize <- sum(th * th, na.rm=TRUE) ph <- apply(Matrix * (th / tsize), 2, sum.na) ##normalize ph based on the available values. psize <- sum(ph*ph, na.rm=TRUE) ph <- ph / sqrt(psize) ##Calculate scores through LS regression ##Trick: To get row-wise multiplication, use t(Matrix)*ph, then ##be sure to use apply(,2,) and NOT apply(,1,)! th.old <- th th <- apply(t(Matrix) * ph, 2, sum.na) ##Round up by calculating if convergence condition is met and ##checking if it seems to be an neverending loop. if (count > maxSteps) { stop("Too many iterations, quitting") } if (t(na.omit(th.old - th)) %*% (na.omit(th.old - th)) <= threshold) { continue = FALSE } if (verbose)cat("*") } if (verbose) cat(" Done\n") Matrix <- Matrix - (th %*% t(ph)) scores <- cbind(scores, th) loadings <- cbind(loadings, ph) ##cumulative proportion of variance R2cum[l] <- 1 - (sum(Matrix*Matrix,na.rm=TRUE) / TotalSS) l <- l + 1 if((!abs(varLimit - 1) < 1e-4 & R2cum[l - 1] >= varLimit) | l > nPcs) { anotherPc <- FALSE nPcs <- l - 1 } } r <- new("pcaRes") r@scores <- scores r@loadings <- loadings r@R2cum <- R2cum r@varLimit <- varLimit r@method <- "rnipals" return(r) } ##' PCA by non-linear iterative partial least squares ##' ##' Can be used for computing PCA on a numeric matrix using either the ##' NIPALS algorithm which is an iterative approach for estimating the ##' principal components extracting them one at a time. NIPALS can ##' handle a small amount of missing values. It is not recommended to ##' use this function directely but rather to use the pca() wrapper ##' function. ##' @title NIPALS PCA ##' @param Matrix Pre-processed (centered, scaled) numerical matrix ##' samples in rows and variables as columns. ##' @param nPcs Number of components that should be extracted. ##' @param varLimit Optionally the ratio of variance that should be ##' explained. \code{nPcs} is ignored if varLimit < 1 ##' @param maxSteps Defines how many iterations can be done before ##' algorithm should abort (happens almost exclusively when there were ##' some wrong in the input data). ##' @param threshold The limit condition for judging if the algorithm ##' has converged or not, specifically if a new iteration is done if ##' \eqn{(T_{old} - T)^T(T_{old} - T) > \code{limit}}. ##' @param ... Only used for passing through arguments. ##' @return A \code{pcaRes} object. ##' @references Wold, H. (1966) Estimation of principal components and ##' related models by iterative least squares. In Multivariate ##' Analysis (Ed., P.R. Krishnaiah), Academic Press, NY, 391-420. ##' @author Henning Redestig ##' @seealso \code{prcomp}, \code{princomp}, \code{pca} ##' @examples ##' data(metaboliteData) ##' mat <- prep(t(metaboliteData)) ##' pc <- nipalsPca(mat, nPcs=2) ##' ## better use pca() ##' pc <- pca(t(metaboliteData), method="nipals", nPcs=2) ##' \dontshow{stopifnot(sum((fitted(pc) - t(metaboliteData))^2, na.rm=TRUE) < 200)} ##' @keywords multivariate ##' @export nipalsPca <- function(Matrix, nPcs=2, varLimit=1, maxSteps=5000, threshold=1e-6, ...) { nipRes <- .Call("pcaMethods_Nipals", Matrix, params=list(nPcs=nPcs, varLimit=varLimit, threshold=threshold, maxSteps=maxSteps), PACKAGE="pcaMethods") r <- new("pcaRes") r@scores <- nipRes$scores r@loadings <- nipRes$loadings r@R2cum <- nipRes$R2cum r@varLimit <- varLimit r@method <- "nipals" return(r) } pcaMethods/R/nlpca.R0000644000175100017510000001664414614231101015306 0ustar00biocbuildbiocbuild##' Neural network based non-linear PCA ##' ##' Artificial Neural Network (MLP) for performing non-linear ##' PCA. Non-linear PCA is conceptually similar to classical PCA but ##' theoretically quite different. Instead of simply decomposing our ##' matrix (X) to scores (T) loadings (P) and an error (E) we train a ##' neural network (our loadings) to find a curve through the ##' multidimensional space of X that describes a much variance as ##' possible. Classical ways of interpreting PCA results are thus not ##' applicable to NLPCA since the loadings are hidden in the network. ##' However, the scores of components that lead to low ##' cross-validation errors can still be interpreted via the score ##' plot. Unfortunately this method depend on slow iterations which ##' currently are implemented in R only making this method extremely ##' slow. Furthermore, the algorithm does not by itself decide when it ##' has converged but simply does 'maxSteps' iterations. ##' @title Non-linear PCA ##' @param Matrix \code{matrix} --- Preprocessed data with the ##' variables in columns and observations in rows. The data may ##' contain missing values, denoted as \code{NA} ##' @param nPcs \code{numeric} -- Number of components to ##' estimate. The preciseness of the missing value estimation depends ##' on thenumber of components, which should resemble the internal ##' structure of the data. ##' @param maxSteps \code{numeric} -- Number of estimation ##' steps. Default is based on a generous rule of thumb. ##' @param unitsPerLayer The network units, example: c(2,4,6) for two ##' input units 2feature units (principal components), one hidden ##' layer fornon-linearity and three output units (original amount ##' ofvariables). ##' @param functionsPerLayer The function to apply at each layer ##' eg. c("linr", "tanh", "linr") ##' @param weightDecay Value between 0 and 1. ##' @param weights Starting weights for the network. Defaults to ##' uniform random values but can be set specifically to make ##' algorithm deterministic. ##' @param verbose \code{boolean} -- nlpca prints the number of steps ##' and warning messages if set to TRUE. Default is interactive(). ##' @param ... Reserved for future use. Not passed on anywhere. ##' @return Standard PCA result object used by all PCA-basedmethods of ##' this package. Contains scores, loadings, data meanand more. See ##' \code{\link{pcaRes}} for details. ##' @author Based on a matlab script by Matthias Scholz and ported to ##' R by Henning Redestig ##' @references Matthias Scholz, Fatma Kaplan, Charles L Guy, Joachim ##' Kopkaand Joachim Selbig. Non-linear PCA: a missing ##' data approach. \emph{Bioinformatics, 21(20):3887-3895, Oct 2005} ##' @examples ##' ## Data set with three variables where data points constitute a helix ##' data(helix) ##' helixNA <- helix ##' ## not a single complete observation ##' helixNA <- t(apply(helix, 1, function(x) { x[sample(1:3, 1)] <- NA; x})) ##' ## 50 steps is not enough, for good estimation use 1000 ##' helixNlPca <- pca(helixNA, nPcs=1, method="nlpca", maxSteps=50) ##' fittedData <- fitted(helixNlPca, helixNA) ##' plot(fittedData[which(is.na(helixNA))], helix[which(is.na(helixNA))]) ##' ## compared to solution by Nipals PCA which cannot extract non-linear patterns ##' helixNipPca <- pca(helixNA, nPcs=2) ##' fittedData <- fitted(helixNipPca) ##' plot(fittedData[which(is.na(helixNA))], helix[which(is.na(helixNA))]) ##' @export nlpca <- function(Matrix, nPcs=2, maxSteps=2 * prod(dim(Matrix)), unitsPerLayer=NULL, functionsPerLayer=NULL, weightDecay=0.001, weights=NULL, verbose=interactive(),...) { ## do some basic checks object <- Matrix trainIn <- NULL trainOut <- t(object) stds <- apply(trainOut, 2, sd, na.rm=TRUE) scalingFactor <- 0.1 / max(stds) trainOut <- trainOut * scalingFactor ## now setup the initial nlpcaNet object numNaN <- sum(is.na(object)) ## always inverse in this version, bottleneck is not fully implemented inverse <- TRUE ## DATADIST (nlnet@dataDist) is given by weightOut dataDist <- apply(!is.na(trainOut), 2, as.integer) #0 for NA, 1 for everything else if(!inverse) dataDist <- NULL ## setup the network architecture if(is.null(unitsPerLayer)) { ld <- dim(trainOut)[1] lh <- nPcs if(nPcs < 10) lh <- 2 + 2 * nPcs unitsPerLayer <- c(ld, lh, nPcs, lh, ld) if(inverse) unitsPerLayer <- c(nPcs, lh, ld) } featureLayer <- ceiling(length(unitsPerLayer) / 2) if(inverse) featureLayer <- 1 if(is.null(functionsPerLayer)) { functionsPerLayer <- rep("tanh", length(unitsPerLayer)) functionsPerLayer[1] <- "linr" functionsPerLayer[featureLayer] <- "linr" functionsPerLayer[length(unitsPerLayer)] <- "linr" } hierarchic <- list(layer=featureLayer, var=rbind(c(rep(1, nPcs), 0.01)), idx=getHierarchicIdx(unitsPerLayer[featureLayer])) ## set up the weights wNum <- sum(sapply(2:length(unitsPerLayer), function(i) (1 + unitsPerLayer[i - 1]) * unitsPerLayer[i])) if(!is.null(weights) && length(weights) != wNum) { warning("Weight vector not expected length (", wNum, "), using random weights", sep="") weights <- NULL } if(is.null(weights)) weights <- cbind(0.2 * (runif(wNum, 0, 1) - 0.1)) if(inverse) { numPattern <- dim(trainOut)[2] tmpTrainIn <- cbind(rnorm(unitsPerLayer[1] * numPattern,0,1) * 0.1) weights <- rbind(tmpTrainIn, weights) } if(nPcs == 1) featureSorting <- FALSE if(nPcs > 1) featureSorting <- TRUE nlnet <- new("nlpcaNet") nlnet@net <- rbind(unitsPerLayer) nlnet@hierarchic <- hierarchic nlnet@fct <- functionsPerLayer nlnet@fkt <- functionsPerLayer[2:length(functionsPerLayer)] nlnet@weightDecay <- weightDecay nlnet@featureSorting <- featureSorting nlnet@dataDist <- dataDist nlnet@inverse <- inverse nlnet@fCount <- as.integer(0) nlnet@componentLayer <- as.integer(featureLayer) nlnet@error <- errorHierarchic nlnet@gradient <- derrorHierarchic nlnet@maxIter <- as.integer(maxSteps) nlnet@weights <- weightsAccount(weights) nlnet@scalingFactor <- scalingFactor ## ****************************** if(verbose) cat("Training network with", nlnet@maxIter, "iterations...\n!:\tSquare error is NA -- accuracy in line-search might be too small\n:\tComponents were sorted at iteration n\n^:\tToo many iterations while expanding\n") newnet <- optiAlgCgd(nlnet, trainIn, trainOut, verbose) if(verbose) cat("\nDone\n") if(inverse) { nObs <- unitsPerLayer[1] * dim(trainOut)[2] we <- newnet@weights$current() scores <- t(matrix(we[1:nObs], nrow=unitsPerLayer[1], dim(trainOut)[2])) newnet@weights$set(we[(nObs + 1):length(we),,drop=FALSE]) } ## for further applications newnet must not be inverse anymore newnet@inverse <- FALSE res <- new("pcaRes") res@scores <- scores res@loadings <- matrix() res@network <- newnet res@method <- "nlpca" R2cum <- rep(NA, nPcs) TSS <- sum(Matrix^2, na.rm=TRUE) for(i in 1:nPcs) R2cum[i] <- 1 - sum((Matrix - fitted(res, Matrix, nPcs=i))^2, na.rm=TRUE) / TSS res@R2cum <- R2cum res } ##' Index in hiearchy ##' @param hierarchicNum A number ##' @return ... ##' @author Henning Redestig, Matthias Scholz getHierarchicIdx <- function(hierarchicNum) { res <- matrix(1, ncol=hierarchicNum, nrow=hierarchicNum) res[lower.tri(res)] <- 0 cbind(res, c(0, rep(1, hierarchicNum - 1))) } pcaMethods/R/optiAlgCgd.R0000644000175100017510000000414314614231101016215 0ustar00biocbuildbiocbuild##' Conjugate gradient optimization ##' @param nlnet The nlnet ##' @param trainIn Training data ##' @param trainOut fitted data ##' @param verbose logical, print messages ##' @return ... ##' @author Henning Redestig, Matthias Scholz optiAlgCgd <- function(nlnet, trainIn, trainOut, verbose=FALSE) { tmpnet <- forkNlpcaNet(nlnet) derr <- tmpnet@gradient(tmpnet, trainIn, trainOut) dw <- derr$dwTotal e <- derr$Etotal dv <- -dw if(tmpnet@featureSorting) eSortLast <- e eHist <- rep(0, tmpnet@maxIter) ttLast <- rep(0.0001, 6) for(i in 1:tmpnet@maxIter) { if(verbose) { if(i %% 10 == 0) cat("*") if(i %% 100 == 0) cat(" [", i, "]\n") } eHist[i] <- e eLast <- e # line search in direction dv (downhill) ttGuess <- max(min(ttLast), 0.00001) linSe <- lineSearch(tmpnet, dv, e, ttGuess, trainIn, trainOut, verbose) tmpnet@weights$set(cbind(linSe$wBest)) e <- linSe$eBest tt <- linSe$ttBest ttLast <- c(ttLast[2:length(ttLast)], tt) #shift and add new tt gradRes <- tmpnet@gradient(tmpnet, trainIn, trainOut) dwNew <- gradRes$dwTotal e <- gradRes$Etotal ## define new search direction dv (conjugate direction) ## b1=dw_new'*dw_new; # Fletcher-Reeves b1 <- crossprod(dwNew, (dwNew - dw))#Polak-Ribiere b2 <- crossprod(dw) beta <- b1 / b2 dv <- -dwNew + dv %*% beta dw <- dwNew if(e > eLast) { dv <- -dwNew if(verbose) cat("!", sep="") } if(is.na(e)) stop("Square error is NA (critical) - accuracy in line-search might be too small") if(tmpnet@featureSorting) if(e / eSortLast < 0.90 || i == tmpnet@maxIter || i == tmpnet@maxIter - 1 || i == tmpnet@maxIter - 2) { eSortLast <- e if(verbose) cat("<", i, ">", sep="") ## somewhat secret method, sortFeatures calls ## nlnet@weights$set(x) so the weights are updated here ## 'behind the scenes' sortFeatures(tmpnet, trainIn, trainOut) } } tmpnet } pcaMethods/R/orth.R0000644000175100017510000000354014614231101015154 0ustar00biocbuildbiocbuild##' ONB = orth(mat) is an orthonormal basis for the range of matrix ##' mat. That is, ONB' * ONB = I, the columns of ONB span the same ##' space as the columns of mat, and the number of columns of ONB is ##' the rank of mat. ##' @title Calculate an orthonormal basis ##' @param mat matrix to calculate orthonormal base ##' @param skipInac do not include components with precision below ##' .Machine$double.eps if TRUE ##' @return orthonormal basis for the range of matrix ##' @author Wolfram Stacklies orth <- function(mat, skipInac = FALSE) { if(nrow(mat) > ncol(mat)) { leftSVs <- ncol(mat) } else { leftSVs <- nrow(mat) } result <- svd(mat, nu = leftSVs, nv = ncol(mat)) U <- result[[2]] S <- result[[1]] V <- result[[3]] m <- nrow(mat) n <- ncol(mat) if(m > 1) { s <- diag(S, nrow = length(S)) } else if(m == 1) { s <- S[1] } else { s <- 0 } tol <- max(m,n) * max(s) * .Machine$double.eps r <- sum(s > tol) if ( r < ncol(U) ) { if (skipInac) { warning("Precision for components ", r + 1 , " - ", ncol(U), " is below .Machine$double.eps. \n", "Results for those components are likely to be inaccurate!!\n", "These component(s) are not included in the returned solution!!\n") } else { warning("Precision for components ", r + 1 , " - ", ncol(U), " is below .Machine$double.eps. \n", "Results for those components are likely to be inaccurate!!\n") } } if (skipInac) { ONB <- U[, 1:r, drop=FALSE] ## Assing correct row and colnames rownames(ONB) <- labels(mat[, 1:r, drop=FALSE])[[1]]; colnames(ONB) <- labels(mat[, 1:r, drop=FALSE])[[2]]; } else { ONB<-U ## Assing correct row and colnames rownames(ONB) <- labels(mat)[[1]]; colnames(ONB) <- labels(mat)[[2]]; } return(ONB) } pcaMethods/R/pca.R0000644000175100017510000003477014614231101014754 0ustar00biocbuildbiocbuild##' Vector with current valid PCA methods ##' @title List PCA methods ##' @param which the type of methods to get. E.g. only get the PCA ##' methods based on the classical model where the fitted data is a ##' direct multiplication of scores and loadings. ##' @return A character vector with the current methods for doing PCA ##' @export ##' @author Henning Redestig listPcaMethods <- function(which=c("all", "linear", "nonlinear")) { switch(match.arg(which), all={ return(c("svd", "nipals", "rnipals", "bpca", "ppca", "svdImpute", "robustPca", "nlpca", "llsImpute", "llsImputeAll")) }, linear={ return(c("svd", "nipals", "rnipals", "bpca", "ppca", "svdImpute", "robustPca")) }, nonlinear={ return("nlpca") }) } ##' Perform PCA on a numeric matrix for visualisation, information ##' extraction and missing value imputation. ##' ##' This method is wrapper function for the following set of pca ##' methods: ##' ##' \describe{\item{svd:}{Uses classical \code{prcomp}. See ##' documentation for \code{\link{svdPca}}.} ##' ##' \item{nipals:}{An iterative method capable of handling small ##' amounts of missing values. See documentation for ##' \code{\link{nipalsPca}}.} ##' ##' \item{rnipals:}{Same as nipals but implemented in R.} ##' ##' \item{bpca:}{An iterative method using a Bayesian model to handle ##' missing values. See documentation for \code{\link{bpca}}.} ##' ##' \item{ppca:}{An iterative method using a probabilistic model to ##' handle missing values. See documentation for \code{\link{ppca}}.} ##' ##' \item{svdImpute:}{Uses expectation maximation to perform SVD PCA ##' on incomplete data. See documentation for ##' \code{\link{svdImpute}}.}} ##' ##' Scaling and centering is part of the PCA model and handled by ##' \code{\link{prep}}. ##' @title Perform principal component analysis ##' @param object Numerical matrix with (or an object coercible to ##' such) with samples in rows and variables as columns. Also takes ##' \code{ExpressionSet} in which case the transposed expression ##' matrix is used. Can also be a data frame in which case all ##' numberic variables are used to fit the PCA. ##' @param method One of the methods reported by ##' \code{listPcaMethods()}. Can be left missing in which case the ##' \code{svd} PCA is chosen for data wihout missing values and ##' \code{nipalsPca} for data with missing values ##' @param nPcs Number of principal components to calculate. ##' @param scale Scaling, see \code{\link{prep}}. ##' @param center Centering, see \code{\link{prep}}. ##' @param completeObs Sets the \code{completeObs} slot on the ##' resulting \code{pcaRes} object containing the original data with ##' but with all NAs replaced with the estimates. ##' @param subset A subset of variables to use for calculating the ##' model. Can be column names or indices. ##' @param cv character naming a the type of cross-validation ##' to be performed. ##' @param ... Arguments to \code{\link{prep}}, the chosen pca ##' method and \code{\link{Q2}}. ##' @return A \code{pcaRes} object. ##' @references ##' Wold, H. (1966) Estimation of principal components and ##' related models by iterative least squares. In Multivariate ##' Analysis (Ed., P.R. Krishnaiah), Academic Press, NY, 391-420. ##' ##' Shigeyuki Oba, Masa-aki Sato, Ichiro Takemasa, Morito Monden, ##' Ken-ichi Matsubara and Shin Ishii. A Bayesian missing value ##' estimation method for gene expression profile ##' data. \emph{Bioinformatics, 19(16):2088-2096, Nov 2003}. ##' ##' Troyanskaya O. and Cantor M. and Sherlock G. and Brown P. and ##' Hastie T. and Tibshirani R. and Botstein D. and Altman RB. - ##' Missing value estimation methods for DNA microarrays. ##' \emph{Bioinformatics. 2001 Jun;17(6):520-5}. ##' @seealso \code{\link{prcomp}}, \code{\link{princomp}}, ##' \code{\link{nipalsPca}}, \code{\link{svdPca}} ##' @examples ##' data(iris) ##' ## Usually some kind of scaling is appropriate ##' pcIr <- pca(iris, method="svd", nPcs=2) ##' pcIr <- pca(iris, method="nipals", nPcs=3, cv="q2") ##' ## Get a short summary on the calculated model ##' summary(pcIr) ##' plot(pcIr) ##' ## Scores and loadings plot ##' slplot(pcIr, sl=as.character(iris[,5])) ##' ##' ## use an expressionset and ggplot ##' data(sample.ExpressionSet) ##' pc <- pca(sample.ExpressionSet) ##' df <- merge(scores(pc), pData(sample.ExpressionSet), by=0) ##' library(ggplot2) ##' ggplot(df, aes(PC1, PC2, shape=sex, color=type)) + ##' geom_point() + ##' xlab(paste("PC1", pc@R2[1] * 100, "% of the variance")) + ##' ylab(paste("PC2", pc@R2[2] * 100, "% of the variance")) ##' @export ##' @keywords multivariate ##' @author Wolfram Stacklies, Henning Redestig pca <- function(object, method, nPcs=2, scale=c("none", "pareto", "vector", "uv"), center=TRUE, completeObs=TRUE, subset=NULL, cv=c("none","q2"), ...) { if(inherits(object, 'data.frame')) { num <- vapply(object, is.numeric, logical(1)) if(sum(num) < 2) stop('no numeric data in supplied data.frame') Matrix <- as.matrix(object[,num]) } else if(inherits(object, "ExpressionSet")) { Matrix <- t(exprs(object)) } else Matrix <- as.matrix(object, rownames.force=TRUE) if(!is.null(subset)) Matrix <- Matrix[,subset] cv <- match.arg(cv) scale <- match.arg(scale) if (nPcs > ncol(Matrix)) { warning("more components than matrix columns requested") nPcs <- min(dim(Matrix)) } if (nPcs > nrow(Matrix)) { warning("more components than matrix rows requested") nPcs <- min(dim(Matrix)) } if (!checkData(Matrix, verbose=interactive())) stop("Invalid data format.", "Run checkData(data, verbose=TRUE) for details") missing <- is.na(Matrix) if(missing(method)) { if(any(missing)) method <- 'nipals' else method <- 'svd' } if(any(missing) & method == 'svd') { warning('data has missing values using nipals instead of user requested svd') method <- 'nipals' } method <- match.arg(method, choices=listPcaMethods()) prepres <- prep(Matrix, scale=scale, center=center, simple=FALSE, ...) switch(method, svd={ res <- svdPca(prepres$data, nPcs=nPcs,...) }, nipals={ res <- nipalsPca(prepres$data, nPcs=nPcs, ...) }, rnipals={ res <- RnipalsPca(prepres$data, nPcs=nPcs, ...) }, bpca={ res <- bpca(prepres$data, nPcs=nPcs, ...) }, ppca={ res <- ppca(prepres$data, nPcs=nPcs, ...) }, svdImpute={ res <- svdImpute(prepres$data, nPcs=nPcs, ...) }, robustPca={ res <- robustPca(prepres$data, nPcs=nPcs, ...) }, nlpca={ res <- nlpca(prepres$data, nPcs=nPcs, ...) }) nPcs <- ncol(res@scores) if(is.null(scores(res)) | is.null(loadings(res)) | is.null(R2cum(res)) | is.null(method(res))) stop(paste("bad result from pca method", method)) colnames(res@scores) <- paste("PC", 1:nPcs, sep="") rownames(res@scores) <- rownames(Matrix) if(all(dim(loadings(res)) == c(ncol(Matrix), nPcs))) { colnames(res@loadings) <- paste("PC", 1:nPcs, sep="") rownames(res@loadings) <- colnames(Matrix) } if(!is.null(subset)) res@subset <- subset res@missing <- missing res@nPcs <- nPcs res@nObs <- nrow(Matrix) res@nVar <- ncol(Matrix) res@sDev <- apply(scores(res), 2, sd) res@center <- prepres$center res@centered <- center res@scale <- prepres$scale res@scaled <- scale res@R2 <- res@R2cum[1] if(length(res@R2cum) > 1) res@R2 <- c(res@R2, diff(res@R2cum)) if (completeObs) { cObs <- Matrix if(method %in% listPcaMethods("nonlinear")) cObs[missing] <- fitted(res, Matrix, pre=TRUE, post=TRUE)[missing] else cObs[missing] <- fitted(res, post=TRUE)[missing] res@completeObs <- cObs } if(cv == "q2") res@cvstat <- Q2(res, Matrix, nruncv=1, ...) return(res) } ##' Wrapper function for imputation methods based on nearest neighbour ##' clustering. Currently llsImpute only. ##' ##' This method is wrapper function to llsImpute, See documentation ##' for \code{link{llsImpute}}. ##' @title Nearest neighbour imputation ##' @param object Numerical matrix with (or an object coercible to ##' such) with samples in rows and variables as columns. Also takes ##' \code{ExpressionSet} in which case the transposed expression ##' matrix is used. ##' @param method For convenience one can pass a large matrix but only ##' use the variable specified as subset. Can be colnames or indices. ##' @param subset Currently "llsImpute" only. ##' @param ... Further arguments to the chosen method. ##' @return A \code{clusterRes} object. Or a list containing a ##' clusterRes object as first and an ExpressionSet object as second ##' entry if the input was of type ExpressionSet. ##' @export ##' @seealso \code{\link{llsImpute}}, \code{\link{pca}} ##' @keywords multivariate ##' @examples ##' data(metaboliteData) ##' llsRes <- nni(metaboliteData, k=6, method="llsImpute", allGenes=TRUE) ##' @author Wolfram Stacklies nni <- function(object, method=c("llsImpute"), subset=numeric(), ...) { isExprSet <- FALSE if(inherits(object, "ExpressionSet")) { set <- object isExprSet <- TRUE object <- t(exprs(object)) } method <- match.arg(method) if ( !checkData(as.matrix(object), verbose=interactive()) ) stop("Invalid data format, exiting...\n", "Run checkData(data, verbose=TRUE) for details\n") missing <- sum(is.na(object)) if(length(subset) > 0) object <- object[,subset] res <- llsImpute(object, ...) return(res) } ##' A function that can be used to visualise many PCs plotted against ##' each other ##' ##' Uses \code{\link{pairs}} to provide side-by-side plots. Note that ##' this function only plots scores or loadings but not both in the ##' same plot. ##' @title Plot many side by side scores XOR loadings plots ##' @param object \code{pcaRes} a pcaRes object ##' @param pcs \code{numeric} which pcs to plot ##' @param type \code{character} Either "scores" or "loadings" for ##' scores or loadings plot respectively ##' @param sl \code{character} Text labels to plot instead of a point, ##' if NULL points are plotted instead of text ##' @param hotelling \code{numeric} Significance level for the ##' confidence ellipse. NULL means that no ellipse is drawn. ##' @param ... Further arguments to \code{\link{pairs}} on which this ##' function is based. ##' @return None, used for side effect. ##' @seealso \code{prcomp}, \code{pca}, \code{princomp}, \code{slplot} ##' @export ##' @examples ##' data(iris) ##' pcIr <- pca(iris[,1:4], nPcs=3, method="svd") ##' plotPcs(pcIr, col=as.integer(iris[,4]) + 1) ##' @keywords multivariate ##' @author Henning Redestig plotPcs <- function(object, pcs=1:nP(object), type=c("scores", "loadings"), sl=NULL, hotelling=0.95, ...) { type <- match.arg(type) panel <- function(x,y, ...) { abline(h=0, v=0, col="black") if(!is.null(hotelling)) { A <- length(pcs) el <- simpleEllipse(x, y, alfa=hotelling) lines(el) } if(is.null(sl)) points(x, y, ...) else text(x, y, labels=sl,...) } switch(type, scores={ labels <- paste("PC", pcs, "\n", "R^2 =", round(object@R2[pcs], 2)) pairs(scores(object)[,pcs], labels=labels, panel=panel, upper.panel=NULL,...) }, loadings={ if(method(object) == "nlpca") stop("Loadings plot not applicable for non-linear PCA") labels <- paste("PC", pcs, "\n", "R^2 =", round(object@R2[pcs], 2)) pairs(loadings(object)[,pcs], labels=labels, panel=panel, upper.panel=NULL, ...) }) } ##' A wrapper function for \code{prcomp} to deliver the result as a ##' \code{pcaRes} method. Supplied for compatibility with the rest ##' of the pcaMethods package. It is not recommended to use this ##' function directely but rather to use the \code{pca()} wrapper ##' function. ##' @title Perform principal component analysis using singular value ##' decomposition ##' @param Matrix Pre-processed (centered and possibly scaled) ##' numerical matrix samples in rows and variables as columns. No ##' missing values allowed. ##' @param nPcs Number of components that should be extracted. ##' @param varLimit Optionally the ratio of variance that should be ##' explained. \code{nPcs} is ignored if varLimit < 1 ##' @param verbose Verbose complaints to matrix structure ##' @param ... Only used for passing through arguments. ##' @return A \code{pcaRes} object. ##' @seealso \code{prcomp}, \code{princomp}, \code{pca} ##' @examples ##' data(metaboliteDataComplete) ##' mat <- prep(t(metaboliteDataComplete)) ##' pc <- svdPca(mat, nPcs=2) ##' ## better use pca() ##' pc <- pca(t(metaboliteDataComplete), method="svd", nPcs=2) ##' \dontshow{stopifnot(sum((fitted(pc) - t(metaboliteDataComplete))^2, na.rm=TRUE) < 200)} ##' @export ##' @keywords multivariate ##' @author Henning Redestig svdPca <- function(Matrix, nPcs=2, varLimit=1, verbose=interactive(), ...) { pcs <- prcomp(Matrix, center=FALSE, scale.=FALSE) imp <- summary(pcs)$importance if(varLimit < 1) nPcs <- sum(imp[3,] < varLimit) + 1 res <- new("pcaRes") res@scores <- cbind(pcs$x[,1:nPcs]) res@loadings <- cbind(pcs$rotation[,1:nPcs]) res@R2cum <- imp[3,1:nPcs] res@varLimit <- varLimit res@method <- "svd" return(res) } ##' Get a confidence ellipse for uncorrelated bivariate data ##' ##' As described in 'Introduction to multi and megavariate data analysis ##' using PCA and ##' PLS' by Eriksson et al. This produces very similar ellipse as ##' compared to the ellipse function the ellipse package except that ##' this function assumes that and y are uncorrelated (which they of ##' are if they are scores or loadings from a PCA). ##' @title Hotelling's T^2 Ellipse ##' @param x first variable ##' @param y second variable ##' @param alfa confidence level of the circle ##' @param len Number of points in the circle ##' @seealso ellipse ##' @author Henning Redestig ##' @return A matrix with X and Y coordinates for the circle simpleEllipse <- function(x, y, alfa=0.95, len=200) { N <- length(x) A <- 2 mypi <- seq(0, 2 * pi, length=len) r1 <- sqrt(var(x) * qf(alfa, 2, N - 2) * (2*(N^2 - 1)/(N * (N - 2)))) r2 <- sqrt(var(y) * qf(alfa, 2, N - 2) * (2*(N^2 - 1)/(N * (N - 2)))) cbind(r1 * cos(mypi) + mean(x), r2 * sin(mypi) + mean(y)) } # .onLoad <- function(libname, pkgname) { # require("methods") # } pcaMethods/R/pcaMethods-package.R0000644000175100017510000000772014614231101017664 0ustar00biocbuildbiocbuild##' Simulated data set looking like a helix ##' ##' ##' A matrix containing 1000 observations (rows) and three variables ##' (columns). ##' @title A helix structured toy data set ##' @name helix ##' @aliases helix ##' @usage data(helix) ##' @docType data ##' @references Matthias Scholz, Fatma Kaplan, Charles L. Guy, Joachim ##' Kopka and Joachim Selbig. - Non-linear PCA: a missing data ##' approach. \emph{Bioinformatics 2005 21(20):3887-3895} ##' @keywords datasets ##' @author Henning Redestig NULL ##' A complete subset from a larger metabolite data set. This is the ##' original, complete data set and can be used to compare estimation ##' results created with the also provided incomplete data (called ##' metaboliteData). The data was created during an in house ##' Arabidopsis coldstress experiment. ##' ##' A matrix containing 154 observations (rows) and 52 metabolites ##' (columns). ##' @name metaboliteDataComplete ##' @docType data ##' @aliases metaboliteDataComplete ##' @title A complete metabolite data set from an Arabidopsis ##' coldstress experiment ##' @keywords datasets ##' @seealso \code{\link{metaboliteData}} ##' @references Matthias Scholz, Fatma Kaplan, Charles L. Guy, Joachim ##' Kopka and Joachim Selbig. - Non-linear PCA: a missing data ##' approach.\emph{Bioinformatics 2005 21(20):3887-3895} ##' @author Wolfram Stacklies NULL ##' A incomplete subset from a larger metabolite data set. This is the ##' original, complete data set and can be used to compare estimation ##' results created with the also provided incomplete data (called ##' metaboliteData). ##' ##' A matrix containing 154 observations (rows) and 52 metabolites ##' (columns). The data contains 5\% of artificially created uniformly ##' distributed misssing values. The data was created during an in ##' house Arabidopsis coldstress experiment. ##' @name metaboliteData ##' @docType data ##' @aliases metaboliteData ##' @title A incomplete metabolite data set from an Arabidopsis ##' coldstress experiment ##' @keywords datasets ##' @seealso \code{\link{metaboliteDataComplete}} ##' @references Matthias Scholz, Fatma Kaplan, Charles L. Guy, Joachim ##' Kopka and Joachim Selbig. - Non-linear PCA: a missing data ##' approach.\emph{Bioinformatics 2005 21(20):3887-3895} ##' @author Wolfram Stacklies NULL ##' Principal Component Analysis in R ##' ##' \tabular{ll}{ ##' Package: \tab pcaMethods \cr ##' Type: \tab Package \cr ##' Developed since: \tab 2006 \cr ##' License: \tab GPL (>=3) \cr ##' LazyLoad: \tab yes \cr ##' } ##' ##' Provides Bayesian PCA, Probabilistic PCA, Nipals PCA, Inverse ##' Non-Linear PCA and the conventional SVD PCA. A cluster based ##' method for missing value estimation is included for comparison. ##' BPCA, PPCA and NipalsPCA may be used to perform PCA on incomplete ##' data as well as for accurate missing value estimation. A set of ##' methods for printing and plotting the results is also provided. ##' All PCA methods make use of the same data structure (pcaRes) to ##' provide a unique interface to the PCA results. Developed at the ##' Max-Planck Institute for Molecular Plant Physiology, Golm, ##' Germany, RIKEN Plant Science Center Yokohama, Japan, and CAS-MPG ##' Partner Institute for Computational Biology (PICB) Shanghai, ##' P.R. China ##' ##' @name pcaMethods ##' @aliases pcaMethods ##' @docType package ##' @importFrom Rcpp evalCpp ##' @import Biobase ##' @import BiocGenerics ##' @import methods ##' @title pcaMethods ##' @useDynLib pcaMethods ##' @author Wolfram Stacklies, Henning Redestig NULL ##' \describe{ ##' \item{plotR2}{Lack of relevance for this plot and the fact that it ##' can not show cross-validation based diagnostics in the same plot ##' makes it redundant with the introduction of a dedicated ##' \code{plot} function for \code{pcaRes}. The new plot only shows ##' R2cum but the result is pretty much the same.}} ##' @name pcaMethods-deprecated ##' @aliases pcaMethods-deprecated ##' @title Deprecated methods for pcaMethods ##' @author Henning Redestig NULL pcaMethods/R/ppca.R0000644000175100017510000001463414614231101015131 0ustar00biocbuildbiocbuild##' Implementation of probabilistic PCA (PPCA). PPCA allows to perform ##' PCA on incomplete data and may be used for missing value ##' estimation. This script was implemented after the Matlab version ##' provided by Jakob Verbeek ( see ##' \url{http://lear.inrialpes.fr/~verbeek/}) and the draft \emph{``EM ##' Algorithms for PCA and Sensible PCA''} written by Sam Roweis. ##' ##' Probabilistic PCA combines an EM approach for PCA with a ##' probabilistic model. The EM approach is based on the assumption ##' that the latent variables as well as the noise are normal ##' distributed. ##' ##' In standard PCA data which is far from the training set but close ##' to the principal subspace may have the same reconstruction error. ##' PPCA defines a likelihood function such that the likelihood for ##' data far from the training set is much lower, even if they are ##' close to the principal subspace. This allows to improve the ##' estimation accuracy. ##' ##' A method called \code{kEstimate} is provided to estimate the ##' optimal number of components via cross validation. In general few ##' components are sufficient for reasonable estimation accuracy. See ##' also the package documentation for further discussion on what kind ##' of data PCA-based missing value estimation is advisable. ##' ##' \bold{Complexity:}\cr Runtime is linear in the number of data, ##' number of data dimensions and number of principal components. ##' ##' \bold{Convergence:} The threshold indicating convergence was ##' changed from 1e-3 in 1.2.x to 1e-5 in the current version leading ##' to more stable results. For reproducability you can set the seed ##' (parameter seed) of the random number generator. If used for ##' missing value estimation, results may be checked by simply running ##' the algorithm several times with changing seed, if the estimated ##' values show little variance the algorithm converged well. ##' @title Probabilistic PCA ##' @param Matrix \code{matrix} -- Data containing the variables in ##' columns and observations in rows. The data may contain missing ##' values, denoted as \code{NA}. ##' @param nPcs \code{numeric} -- Number of components to ##' estimate. The preciseness of the missing value estimation depends ##' on the number of components, which should resemble the internal ##' structure of the data. ##' @param seed \code{numeric} Set the seed for the random number ##' generator. PPCA creates fills the initial loading matrix with ##' random numbers chosen from a normal distribution. Thus results may ##' vary slightly. Set the seed for exact reproduction of your ##' results. ##' @param threshold Convergence threshold. ##' @param maxIterations the maximum number of allowed iterations ##' @param ... Reserved for future use. Currently no further ##' parameters are used. ##' @note Requires \code{MASS}. It is not recommended to use this ##' function directely but rather to use the pca() wrapper function. ##' @return Standard PCA result object used by all PCA-based methods ##' of this package. Contains scores, loadings, data mean and ##' more. See \code{\link{pcaRes}} for details. ##' @seealso \code{\link{bpca}, \link{svdImpute}, \link{prcomp}, ##' \link{nipalsPca}, \link{pca}, \link{pcaRes}}. ##' @examples ##' ## Load a sample metabolite dataset with 5\% missing values (metaboliteData) ##' data(metaboliteData) ##' ## Perform probabilistic PCA using the 3 largest components ##' result <- pca(t(metaboliteData), method="ppca", nPcs=3, seed=123) ##' ## Get the estimated complete observations ##' cObs <- completeObs(result) ##' ## Plot the scores ##' plotPcs(result, type = "scores") ##' \dontshow{ ##' stopifnot(sum((fitted(result) - t(metaboliteData))^2, na.rm=TRUE) < 200) ##' } ##' @keywords multivariate ##' @author Wolfram Stacklies ##' @export ppca <- function(Matrix, nPcs=2, seed=NA, threshold=1e-5, maxIterations=1000, ...) { ## Set the seed to the user defined value. This affects the generation ## of random values for the initial setup of the loading matrix if (!is.na(seed)) set.seed(seed) N <- nrow(Matrix) D <- ncol(Matrix) Obs <- !is.na(Matrix) hidden <- which(is.na(Matrix)) missing <- length(hidden) if(missing) { Matrix[hidden] <- 0 } ## ------- Initialization r <- sample(N) C <- t(Matrix[r[1:nPcs], ,drop = FALSE]) ## Random matrix with the same dimnames as Matrix C <- matrix(rnorm(C), nrow(C), ncol(C), dimnames = labels(C) ) CtC <- t(C) %*% C ## inv(C'C) C' X is the solution to the EM problem X <- Matrix %*% C %*% solve(CtC) recon <- X %*% t(C) recon[hidden] <- 0 ss <- sum(sum((recon - Matrix)^2)) / (N * D - missing) count <- 1 old <- Inf ## ------ EM iterations while (count > 0) { ## E-step, (co)variances Sx <- solve(diag(nPcs) + CtC/ss) ss_old <- ss if(missing) { proj <- X %*% t(C) Matrix[hidden] <- proj[hidden] } ## E step: expected values X <- Matrix %*% C %*% Sx / ss ## M-step SumXtX <- t(X) %*% X ## Replace the right matrix division from matlab C <- (t(Matrix) %*% X) %*% solve( (SumXtX + N * Sx) ) CtC <- t(C) %*% C ss <- ( sum(sum( (C %*% t(X) - t(Matrix))^2 )) + N * sum(sum(CtC %*% Sx)) + missing * ss_old ) / (N * D) objective <- N * (D * log(ss) + sum(diag(Sx)) - log(det(Sx)) ) + sum(diag(SumXtX)) - missing * log(ss_old) rel_ch <- abs( 1 - objective / old ) old <- objective count <- count + 1 if( rel_ch < threshold & count > 5 ) { count <- 0 } else if (count > maxIterations) { count <- 0 warning("stopped after max iterations, but rel_ch was > threshold") } } ## End EM iteration C <- orth(C) evs <- eigen( cov(Matrix %*% C) ) vals <- evs[[1]] vecs <- evs[[2]] C <- C %*% vecs X <- Matrix %*% C ## Paramters in original Matlab implementation were: ## C (D by d) - C has the approximate loadings (eigenvectors of ## the covariance matrix) ## as columns. ## X - The approximate scores ## Matrix (N by D) - Expected complete observations. ## M (D by 1) - Column wise data mean ## ss (scalar) - isotropic variance outside subspace R2cum <- rep(NA, nPcs) TSS <- sum(Matrix^2, na.rm=TRUE) for (i in 1:ncol(C)) { difference <- Matrix - (X[,1:i, drop=FALSE] %*% t(C[,1:i, drop=FALSE])) R2cum[i] <- 1 - (sum(difference^2, na.rm=TRUE) / TSS) } res <- new("pcaRes") res@scores <- X res@loadings <- C res@R2cum <- R2cum res@method <- "ppca" return(res) } pcaMethods/R/prep.R0000644000175100017510000000732214614231101015150 0ustar00biocbuildbiocbuild##' Scaling and centering a matrix. ##' ##' Does basically the same as \code{\link{scale}} but adds some ##' alternative scaling options and functionality for treating ##' pre-processing as part of a model. ##' @title Pre-process a matrix for PCA ##' @param object Numerical matrix (or an object coercible to such) ##' with samples in rows and variables as columns. Also takes ##' \code{ExpressionSet} in which case the transposed expression ##' matrix is used. ##' @param scale One of "UV" (unit variance \eqn{a=a/\sigma_{a}}) ##' "vector" (vector normalisation \eqn{b=b/||b||}), "pareto" (sqrt ##' UV) or "none" to indicate which scaling should be used to scale ##' the matrix with \eqn{a} variables and \eqn{b} samples. Can also be ##' a vector of scales which should be used to scale the ##' matrix. \code{NULL} value is interpreted as \code{"none"}. ##' @param center Either a logical which indicates if the matrix ##' should be mean centred or not, or a vector with averages which ##' should be suntracted from the matrix. \code{NULL} value is ##' interpreted as \code{FALSE} ##' @param eps Minimum variance, variable with lower variance are not ##' scaled and warning is issued instead. ##' @param simple Logical indicating if only the data should be ##' returned or a list with the pre-processing statistics as well. ##' @param reverse Logical indicating if matrix should be ##' 'post-processed' instead by multiplying each column with its scale ##' and adding the center. In this case, center and scale should be ##' vectors with the statistics (no warning is issued if not, instead ##' output becomes the same as input). ##' @param ... Only used for passing through arguments. ##' @return A pre-processed matrix or a list with ##' \item{center}{a vector with the estimated centers} ##' \item{scale}{a vector with the estimated scales} ##' \item{data}{the pre (or post) processed data} ##' @examples ##' object <- matrix(rnorm(50), nrow=10) ##' res <- prep(object, scale="uv", center=TRUE, simple=FALSE) ##' obj <- prep(object, scale=res$scale, center=res$center) ##' ## same as original ##' sum((object - prep(obj, scale=res$scale, center=res$center, rev=TRUE))^2) ##' @export ##' @author Henning Redestig prep <- function(object, scale=c("none", "pareto", "vector", "uv"), center=TRUE, eps=1e-12, simple=TRUE, reverse=FALSE, ...) { if(inherits(object, "ExpressionSet")) obj <- t(exprs(object)) else obj <- as.matrix(object) if(is.null(center)) center <- FALSE if(is.null(scale)) scale <- "none" if(is.logical(center[1])) { if(center[1]) center <- colMeans(obj, na.rm=TRUE) else center <- rep(0, ncol(obj)) } if(length(center) != ncol(obj)) stop("center do not match matrix dimensions") if(!reverse) obj <- sweep(obj, 2, center, "-") if(is.character(scale[1])) { scale <- match.arg(scale) if(scale == "uv") scale <- apply(obj, 2, sd, na.rm=TRUE) else if(scale == "none") scale <- rep(1, ncol(obj)) else if(scale == "pareto") scale <- sqrt(apply(obj, 2, sd, na.rm=TRUE)) else if(scale == "vector") scale <- apply(obj, 2, function(x) sqrt(sum(x^2, na.rm=TRUE))) } if(length(scale) != ncol(obj)) stop("scale vector do not match matrix dimensions") if (any(scale < eps)) warning(paste("Variance is below eps for", sum(scale < eps), "variables. Not scaling them.")) scale[scale < eps] <- 1 if(!reverse) obj <- sweep(obj, 2, scale, "/") if(reverse) { obj <- sweep(obj, 2, scale, "*") obj <- sweep(obj, 2, center, "+") } if(inherits(object, "ExpressionSet")) exprs(object) <- t(obj) else object <- obj if (simple) object else list(data=object, center=center, scale=scale) } pcaMethods/R/repmat.R0000644000175100017510000000166714614231101015500 0ustar00biocbuildbiocbuild##' Creates a large matrix B consisting of an M-by-N tiling of copies ##' of A ##' @title Replicate and tile an array. ##' @param mat numeric matrix ##' @param M number of copies in vertical direction ##' @param N number of copies in horizontal direction ##' @return Matrix consiting of M-by-N tiling copies of input matrix ##' @author Wolfram Stacklies repmat <- function(mat, M, N) { ## Check if all input parameters are correct if( !all(M > 0, N > 0) ) { stop("M and N must be > 0") } ## Convert array to matrix ma <- mat if(!is.matrix(mat)) { ma <- matrix(mat, nrow=1) } rows <- nrow(ma) cols <- ncol(ma) replicate <- matrix(0, rows * M, cols * N) for (i in 1:M) { for(j in 1:N) { start_row <- (i - 1) * rows + 1 end_row <- i * rows start_col <- (j - 1) * cols + 1 end_col <- j * cols replicate[start_row:end_row, start_col:end_col] <- ma } } return(replicate) } pcaMethods/R/robustPca.R0000644000175100017510000002237014614231101016144 0ustar00biocbuildbiocbuild##' This is a PCA implementation robust to outliers in a data set. It ##' can also handle missing values, it is however NOT intended to be ##' used for missing value estimation. As it is based on robustSVD we ##' will get an accurate estimation for the loadings also for ##' incomplete data or for data with outliers. The returned scores ##' are, however, affected by the outliers as they are calculated ##' inputData X loadings. This also implies that you should look at ##' the returned R2/R2cum values with caution. If the data show ##' missing values, scores are caluclated by just setting all NA - ##' values to zero. This is not expected to produce accurate results. ##' Please have also a look at the manual page for \code{robustSvd}. ##' Thus this method should mainly be seen as an attempt to integrate ##' \code{robustSvd()} into the framework of this package. Use one of ##' the other methods coming with this package (like PPCA or BPCA) if ##' you want to do missing value estimation. It is not recommended to ##' use this function directely but rather to use the pca() wrapper ##' function. ##' ##' The method is very similar to the standard \code{prcomp()} ##' function. The main difference is that \code{robustSvd()} is used ##' instead of the conventional \code{svd()} method. ##' @title PCA implementation based on robustSvd ##' @param Matrix \code{matrix} -- Data containing the variables in ##' columns and observations in rows. The data may contain missing ##' values, denoted as \code{NA}. ##' @param nPcs \code{numeric} -- Number of components to ##' estimate. The preciseness of the missing value estimation depends ##' on the number of components, which should resemble the internal ##' structure of the data. ##' @param verbose \code{boolean} Print some output to the command ##' line if TRUE ##' @param ... Reserved for future use. Currently no further ##' parameters are used ##' @return Standard PCA result object used by all PCA-based methods ##' of this package. Contains scores, loadings, data mean and ##' more. See \code{\link{pcaRes}} for details. are used. ##' @seealso \code{\link{robustSvd}, \link{svd}, \link{prcomp}, ##' \link{pcaRes}}. ##' @examples ##' ## Load a complete sample metabolite data set and mean center the data ##' data(metaboliteDataComplete) ##' mdc <- scale(metaboliteDataComplete, center=TRUE, scale=FALSE) ##' ## Now create 5\% of outliers. ##' cond <- runif(length(mdc)) < 0.05; ##' mdcOut <- mdc ##' mdcOut[cond] <- 10 ##' ## Now we do a conventional PCA and robustPca on the original and the data ##' ## with outliers. ##' ## We use center=FALSE here because the large artificial outliers would ##' ## affect the means and not allow to objectively compare the results. ##' resSvd <- pca(mdc, method="svd", nPcs=10, center=FALSE) ##' resSvdOut <- pca(mdcOut, method="svd", nPcs=10, center=FALSE) ##' resRobPca <- pca(mdcOut, method="robustPca", nPcs=10, center=FALSE) ##' ## Now we plot the results for the original data against those with outliers ##' ## We can see that robustPca is hardly effected by the outliers. ##' plot(loadings(resSvd)[,1], loadings(resSvdOut)[,1]) ##' plot(loadings(resSvd)[,1], loadings(resRobPca)[,1]) ##' @keywords multivariate ##' @export ##' @author Wolfram Stacklies robustPca <- function(Matrix, nPcs=2, verbose=interactive(), ... ) { nas <- is.na(Matrix) if (sum(nas) != 0) warning("Data is incomplete, it is not recommended to use robustPca for missing value estimation") svdSol <- robustSvd(Matrix) ## Sort the eigenvalues and eigenvectors loadings <- svdSol$v[, 1:nPcs, drop=FALSE] sDev <- svdSol$d[1:nPcs] / sqrt(max(1, nrow(Matrix) - 1)) ## We estimate the scores by just setting all NA values to 0 This is ## a bad approximation, I know... Use ppca / bpca or other missing ## value estimation methods included in this package compMat <- Matrix compMat[is.na(compMat)] <- 0 scores <- compMat %*% loadings ## Calculate R2cum (on the complete observations only) R2cum <- rep(NA, nPcs) TSS <- sum(Matrix^2, na.rm=TRUE) for (i in 1:nPcs) { difference <- Matrix - (scores[,1:i, drop=FALSE] %*% t(loadings[,1:i, drop=FALSE])) R2cum[i] <- 1 - (sum(difference^2) / TSS) } result <- new("pcaRes") result@loadings <- loadings result@scores <- scores result@R2cum <- R2cum result@method <- "robustPca" return(result) } ##' A robust approximation to the singular value decomposition of a ##' rectangular matrix is computed using an alternating L1 norm ##' (instead of the more usual least squares L2 norm). As the SVD is ##' a least-squares procedure, it is highly susceptible to outliers ##' and in the extreme case, an individual cell (if sufficiently ##' outlying) can draw even the leading principal component toward ##' itself. ##' ##' See Hawkins et al (2001) for details on the robust SVD algorithm. ##' Briefly, the idea is to sequentially estimate the left and right ##' eigenvectors using an L1 (absolute value) norm minimization. ##' ##' Note that the robust SVD is able to accomodate missing values in ##' the matrix \code{x}, unlike the usual \code{svd} function. ##' ##' Also note that the eigenvectors returned by the robust SVD ##' algorithm are NOT (in general) orthogonal and the eigenvalues need ##' not be descending in order. ##' @title Alternating L1 Singular Value Decomposition ##' @param x A matrix whose SVD decomposition is to be ##' computed. Missing values are allowed. ##' @return The robust SVD of the matrix is x=u d v'. \item{d}{A ##' vector containing the singular values of \code{x}.} \item{u}{A ##' matrix whose columns are the left singular vectors of \code{x}.} ##' \item{v}{A matrix whose columns are the right singular vectors of ##' \code{x}.} ##' @note Two differences from the usual SVD may be noted. One relates ##' to orthogonality. In the conventional SVD, all the eigenvectors ##' are orthogonal even if not explicitly imposed. Those returned by ##' the AL1 algorithm (used here) are (in general) not orthogonal. ##' Another difference is that, in the L2 analysis of the conventional ##' SVD, the successive eigen triples (eigenvalue, left eigenvector, ##' right eigenvector) are found in descending order of ##' eigenvalue. This is not necessarily the case with the AL1 ##' algorithm. Hawkins et al (2001) note that a larger eigen value ##' may follow a smaller one. ##' @references Hawkins, Douglas M, Li Liu, and S Stanley Young (2001) ##' Robust Singular Value Decomposition, National Institute of ##' Statistical Sciences, Technical Report Number ##' 122. \url{http://www.niss.org/technicalreports/tr122.pdf} ##' @author Kevin Wright, modifications by Wolfram Stacklies ##' @seealso \code{\link{svd}}, \code{\link[ade4:nipals]{nipals}} for ##' an alternating L2 norm method that also accommodates missing data. ##' @examples ##' ## Load a complete sample metabolite data set and mean center the data ##' data(metaboliteDataComplete) ##' mdc <- prep(metaboliteDataComplete, center=TRUE, scale="none") ##' ## Now create 5% of outliers. ##' cond <- runif(length(mdc)) < 0.05; ##' mdcOut <- mdc ##' mdcOut[cond] <- 10 ##' ## Now we do a conventional SVD and a robustSvd on both, the original and the ##' ## data with outliers. ##' resSvd <- svd(mdc) ##' resSvdOut <- svd(mdcOut) ##' resRobSvd <- robustSvd(mdc) ##' resRobSvdOut <- robustSvd(mdcOut) ##' ## Now we plot the results for the original data against those with outliers ##' ## We can see that robustSvd is hardly affected by the outliers. ##' plot(resSvd$v[,1], resSvdOut$v[,1]) ##' plot(resRobSvd$v[,1], resRobSvdOut$v[,1]) ##' @keywords algebra ##' @export robustSvd <- function(x) { ## We need the weightedMedian function provided by the aroma.light ## package. However we do not want to make the whole package dependant ## on aroma.light if (!requireNamespace("matrixStats", quietly=TRUE)) stop("package matrixStats required but not available") L1RegCoef <- function(x, a){ keep <- (abs(a) > .Machine$double.eps) & (!is.na(x)) if(!any(keep)) { warning("No non-missing data for l1 regression, unstable results") return(0.) } a <- a[keep] return(matrixStats::weightedMedian(x[keep] / a, abs(a), na.rm=TRUE, interpolate=FALSE)) } L1Eigen <- function(x, a, b){ x <- as.vector(x) # Convert from matrix to vector ab <- as.vector(outer(a, b)) keep <- (abs(ab) > .Machine$double.eps) & (!is.na(x)) ab <- ab[keep] return(matrixStats::weightedMedian(x[keep] / ab, abs(ab), na.rm=TRUE, interpolate=FALSE)) } ## Initialize outputs svdu <- matrix(NA, nrow=nrow(x), ncol=ncol(x)) svdv <- matrix(NA, nrow=ncol(x), ncol=ncol(x)) svdd <- rep(NA, ncol(x)) for(k in 1:ncol(x)) { ak <- apply(abs(x), 1, median, na.rm=TRUE) converged <- FALSE while(!converged) { akprev <- ak c <- apply(x, 2, L1RegCoef, ak) bk <- c / sqrt(sum(c^2)) d <- apply(x, 1, L1RegCoef, bk) ak <- d / sqrt(sum(d^2)) if(sum((ak - akprev)^2) < 1e-10) { converged <- TRUE } } eigenk <- L1Eigen(x,ak,bk) ## Deflate the x matrix x <- x - eigenk * ak %*% t(bk) ## Store eigen triple for output svdu[,k] <- ak svdv[,k] <- bk svdd[k] <- eigenk } ## Create the result object ret <- list() ret$d <- svdd ret$u <- svdu ret$v <- svdv return(ret) } pcaMethods/R/sortFeatures.R0000644000175100017510000000502114614231101016662 0ustar00biocbuildbiocbuild##' Sort the features of NLPCA object ##' @param nlnet The nlnet ##' @param trainIn Training data in ##' @param trainOut Training data after it passed through the net ##' @return ... ##' @author Henning Redestig sortFeatures <- function(nlnet, trainIn, trainOut) { weightsAll <- nlnet@weights$current() weights <- weightsAll if(nlnet@inverse) { numElements <- nlnet@net[1] * dim(trainOut)[2] trainIn <- array(unlist(weightsAll), dim=c(nlnet@net[1], dim(trainOut)[2])) weights <- weightsAll[(numElements + 1):length(weightsAll),,drop=FALSE] } netDim <- dim(nlnet@net) trainDim <- dim(trainIn) bneckNum <- nlnet@net[nlnet@componentLayer] weightMats <- vector2matrices(weights, nlnet@net) bneckNum <- nlnet@net[nlnet@componentLayer] ## ****************************** nOut <- array(0, dim=c(sum(nlnet@net), trainDim[2], 2)) for(subnet in 1:2) nOut[1:trainDim[1],,subnet] <- trainIn ## forward propagation for(n in 0:(bneckNum - 2)) { E <- c(0,0) for(choice in 1:2) { sBias <- rep(1, trainDim[2]) for(i in 1:(netDim[2] - 1)) { if(i == 1) nBegin <- 1 else nBegin <- sum(nlnet@net[1:(i - 1)]) + 1 sIn <- rbind(sBias, nOut[nBegin:sum(nlnet@net[1:i]),, choice]) sOut <- eval(parse(text=paste(nlnet@fkt[i], "(weightMats[[i]] %*% sIn)"))) if(i == nlnet@componentLayer - 1) { idx <- rep(0, bneckNum) idx[1:(n + choice)] <- 1 if(choice == 2) idx[n+choice-1] <- 0 sOut[idx == 0,] <- 0 } nOut[(sum(nlnet@net[1:i]) + 1):sum(nlnet@net[1:(i+1)]),,choice] <- sOut } output <- nOut[(sum(nlnet@net[1:(dim(nlnet@net)[2]-1)])+1):dim(nOut)[1], ,choice] Epattern <- (output - trainOut)^2 Epattern[is.na(Epattern)] <- 0 if(!is.null(nlnet@dataDist)) Epattern <- Epattern * nlnet@dataDist E <- mean(Epattern) E[choice] <- E } if(E[1]>E[2]) { #change features changeIdx <- 1:bneckNum changeIdx[(n+1):(n+2)] <- c(n+2, n+1) weightMats[[nlnet@componentLayer - 1]] <- weightMats[[nlnet@componentLayer - 1]][changeIdx,] weightMats[[nlnet@componentLayer]] <- weightMats[[nlnet@componentLayer]][,c(1,changeIdx+1)] switching <- c(n+1, n+2) nlnet@fCount <- as.integer(nlnet@fCount + 1) } } weights <- cbind(unlist(weightMats)) if(nlnet@inverse) nlnet@weights$set(rbind(matrix(trainIn, nrow=numElements, ncol=1), weights)) } pcaMethods/R/svdImpute.R0000644000175100017510000001132714614231101016162 0ustar00biocbuildbiocbuild##' This implements the SVDimpute algorithm as proposed by Troyanskaya ##' et al, 2001. The idea behind the algorithm is to estimate the ##' missing values as a linear combination of the \code{k} most ##' significant eigengenes. ##' ##' Missing values are denoted as \code{NA}. It is not recommended ##' to use this function directely but rather to use the pca() wrapper ##' function. ##' ##' As SVD can only be performed on complete matrices, all missing ##' values are initially replaced by 0 (what is in fact the mean on ##' centred data). The algorithm works iteratively until the change ##' in the estimated solution falls below a certain threshold. Each ##' step the eigengenes of the current estimate are calculated and ##' used to determine a new estimate. Eigengenes denote the loadings ##' if pca is performed considering variable (for Microarray data ##' genes) as observations. ##' ##' An optimal linear combination is found by regressing the ##' incomplete variable against the \code{k} most significant ##' eigengenes. If the value at position \code{j} is missing, the ##' \eqn{j^th}{j^th} value of the eigengenes is not used when ##' determining the regression coefficients. ##' @title SVDimpute algorithm ##' @param Matrix \code{matrix} -- Pre-processed (centered, scaled) ##' data with variables in columns and observations in rows. The data ##' may contain missing values, denoted as \code{NA}. ##' @param nPcs \code{numeric} -- Number of components to ##' estimate. The preciseness of the missing value estimation depends ##' on the number of components, which should resemble the internal ##' structure of the data. ##' @param threshold The iteration stops if the change in the matrix ##' falls below this threshold. ##' @param maxSteps Maximum number of iteration steps. ##' @param verbose Print some output if TRUE. ##' @param ... Reserved for parameters used in future version of the ##' algorithm ##' @note Each iteration, standard PCA (\code{prcomp}) needs to be ##' done for each incomplete variable to get the eigengenes. This is ##' usually fast for small data sets, but complexity may rise if the ##' data sets become very large. ##' @return Standard PCA result object used by all PCA-based methods ##' of this package. Contains scores, loadings, data mean and ##' more. See \code{\link{pcaRes}} for details. ##' @examples ##' ## Load a sample metabolite dataset with 5\% missing values ##' data(metaboliteData) ##' ## Perform svdImpute using the 3 largest components ##' result <- pca(metaboliteData, method="svdImpute", nPcs=3, center = TRUE) ##' ## Get the estimated complete observations ##' cObs <- completeObs(result) ##' ## Now plot the scores ##' plotPcs(result, type = "scores") ##' @keywords multivariate ##' @references Troyanskaya O. and Cantor M. and Sherlock G. and Brown ##' P. and Hastie T. and Tibshirani R. and Botstein D. and Altman ##' RB. - Missing value estimation methods for DNA ##' microarrays. \emph{Bioinformatics. 2001 Jun;17(6):520-5.} ##' @author Wolfram Stacklies ##' @export svdImpute <- function(Matrix, nPcs=2, threshold=0.01, maxSteps=100, verbose=interactive(), ...) { missing <- is.na(Matrix) temp <- apply(missing, 2, sum) missIx <- which(temp != 0) ## Initially set estimates to 0 Matrix[missing] <- 0 ## Now do the regression count <- 0 error <- Inf while ( (error > threshold) && (count < maxSteps) ) { res <- prcomp(t(Matrix), center = FALSE, scale = FALSE, retx = TRUE) loadings <- res$rotation[,1:nPcs, drop = FALSE] sDev <- res$sdev ## Estimate missing values as a linear combination of the eigenvectors ## The optimal solution is found by regression against the k eigengenes for (index in missIx) { target <- Matrix[!missing[,index],index, drop = FALSE] Apart <- loadings[!missing[,index], , drop = FALSE] Bpart <- loadings[missing[,index], , drop = FALSE] X <- MASS::ginv(Apart) %*% target estimate <- Bpart %*% X Matrix[missing[,index], index] <- estimate } count <- count + 1 if (count > 5) { error <- sqrt(sum( (MatrixOld - Matrix)^2 ) / sum(MatrixOld^2)) if (verbose) { cat("change in estimate: ", error, "\n") } } MatrixOld <- Matrix } tmp <- prcomp(Matrix, center = FALSE, scale = FALSE, retx = TRUE) loadings <- cbind(tmp$rotation[,1:nPcs]) scores <- cbind(tmp$x[,1:nPcs]) ## Calculate R2cum R2cum <- rep(NA, nPcs) TSS <- sum(Matrix^2, na.rm=TRUE) for (i in 1:nPcs) { difference <- Matrix - (scores[,1:i, drop=FALSE] %*% t(loadings[,1:i, drop=FALSE])) R2cum[i] <- 1 - (sum(difference^2) / TSS) } result <- new("pcaRes") result@scores <- scores result@loadings <- loadings result@R2cum <- R2cum result@method <- "svdImpute" return(result) } pcaMethods/R/vector2matrices.R0000644000175100017510000000252314614231101017314 0ustar00biocbuildbiocbuild##' Tranform the vectors of weights to matrix structure ##' @param object an nlpcaNet ##' @return weights in matrix structure ##' @author Henning Redestig ##' @aliases vector2matrices,nlpcaNet-method setMethod("vector2matrices", "nlpcaNet", function(object) { netDim <- dim(object@net) posBegin <- 1 posEnd <- 0 result <- list() for(i in 1:(netDim[2] - 1)) { wSize <- c(object@net[i + 1], object@net[i] + 1) posEnd <- posEnd + prod(wSize) result[[i]] <- matrix(object@weights$current()[posBegin:posEnd], wSize[1], wSize[2]) posBegin <- posEnd + 1 } if(posEnd < length(object@weights$current())) stop("weight vector has too many elements\n") result }) ##' Tranform the vectors of weights to matrix structure ##' @param object an nlpcaNet ##' @param net the neural network ##' @return weights in matrix structure ##' @author Henning Redestig ##' @aliases vector2matrices,matrix-method setMethod("vector2matrices", "matrix", function(object, net) { netDim <- dim(net) posBegin <- 1 posEnd <- 0 result <- list() for(i in 1:(netDim[2] - 1)) { wSize <- c(net[i + 1], net[i] + 1) posEnd <- posEnd + prod(wSize) result[[i]] <- matrix(object[posBegin:posEnd], wSize[1], wSize[2]) posBegin <- posEnd + 1 } if(posEnd < length(object)) stop("weight vector has too many elements\n") result }) pcaMethods/R/xval.R0000644000175100017510000002764114614231101015162 0ustar00biocbuildbiocbuild##' Internal cross-validation can be used for estimating the level of ##' structure in a data set and to optimise the choice of number of ##' principal components. ##' ##' This method calculates \eqn{Q^2} for a PCA model. This is the ##' cross-validated version of \eqn{R^2} and can be interpreted as the ##' ratio of variance that can be predicted independently by the PCA ##' model. Poor (low) \eqn{Q^2} indicates that the PCA model only ##' describes noise and that the model is unrelated to the true data ##' structure. The definition of \eqn{Q^2} is: \deqn{Q^2=1 - ##' \frac{\sum_{i}^{k}\sum_{j}^{n}(x - ##' \hat{x})^2}{\sum_{i}^{k}\sum_{j}^{n}x^2}}{Q^2=1 - sum_i^k sum_j^n ##' (x - \hat{x})^2 / \sum_i^k \sum_j^n(x^2)} for the matrix \eqn{x} ##' which has \eqn{n} rows and \eqn{k} columns. For a given number of ##' PC's x is estimated as \eqn{\hat{x}=TP'} (T are scores and P are ##' loadings). Although this defines the leave-one-out ##' cross-validation this is not what is performed if fold is less ##' than the number of rows and/or columns. In 'impute' type CV, ##' diagonal rows of elements in the matrix are deleted and the ##' re-estimated. In 'krzanowski' type CV, rows are sequentially left ##' out to build fold PCA models which give the loadings. Then, ##' columns are sequentially left out to build fold models for ##' scores. By combining scores and loadings from different models, we ##' can estimate completely left out values. The two types may seem ##' similar but can give very different results, krzanowski typically ##' yields more stable and reliable result for estimating data ##' structure whereas impute is better for evaluating missing value ##' imputation performance. Note that since Krzanowski CV operates on ##' a reduced matrix, it is not possible estimate Q2 for all ##' components and the result vector may therefore be shorter than ##' \code{nPcs(object)}. ##' @title Cross-validation for PCA ##' @param object A \code{pcaRes} object (result from previous PCA ##' analysis.) ##' @param originalData The matrix (or ExpressionSet) that used to ##' obtain the pcaRes object. ##' @param fold The number of groups to divide the data in. ##' @param nruncv The number of times to repeat the whole ##' cross-validation. The deletion of diagnols in 'impute' is ##' deterministic so result will alsways be the same but in ##' krzanowski where cv-split is obtained by sampling it can be ##' informative to examine the spread of the Q2 values over several ##' CV runs. ##' @param type krzanowski or imputation type cross-validation ##' @param verbose \code{boolean} If TRUE Q2 outputs a primitive ##' progress bar. ##' @param variables indices of the variables to use during ##' cross-validation calculation. Other variables are kept as they ##' are and do not contribute to the total sum-of-squares. ##' @param ... Further arguments passed to the \code{\link{pca}} ##' function called within Q2. ##' @return A matrix or vector with \eqn{Q^2} estimates. ##' @export ##' @references Krzanowski, WJ. Cross-validation in principal ##' component analysis. Biometrics. 1987(43):3,575-584 ##' @examples ##' data(iris) ##' x <- iris[,1:4] ##' pcIr <- pca(x, nPcs=3) ##' q2 <- Q2(pcIr, x) ##' barplot(q2, main="Krzanowski CV", xlab="Number of PCs", ylab=expression(Q^2)) ##' ## q2 for a single variable ##' Q2(pcIr, x, variables=2) ##' pcIr <- pca(x, nPcs=3, method="nipals") ##' q2 <- Q2(pcIr, x, type="impute") ##' barplot(q2, main="Imputation CV", xlab="Number of PCs", ylab=expression(Q^2)) ##' @author Henning Redestig, Ondrej Mikula ##' @keywords multivariate Q2 <- function (object, originalData=completeObs(object), fold=5, nruncv=1, type=c("krzanowski", "impute"), verbose=interactive(), variables=1:nVar(object), ...) { type <- match.arg(type) if (inherits(originalData, "ExpressionSet")) { set <- originalData originalData <- t(exprs(originalData)) } if (is.null(originalData)) stop("missing data when estimating Q2") originalData <- as.matrix(originalData) originalData <- prep(originalData, scale=scl(object), center=center(object)) nR <- nObs(object) nC <- nVar(object) if (nR != nrow(originalData) | nC != ncol(originalData)) stop("data and model dimensions do not match") if (fold > max(nR, nC)) stop("fold must be equal or less to max dimension of original data") if (method(object) %in% c("svd") & type != "krzanowski") stop("Chosen PCA method must use krzanowski type cv") if (method(object) %in% c("llsImpute") & type != "impute") stop("Chosen PCA method must use impute type cv") if (is.logical(variables)) variables <- which(variables) ssx <- sum(originalData[, variables]^2, na.rm=TRUE) if(type == "impute") nP <- nPcs(object) if(type == "krzanowski") { rseg <- split(sample(1:nR), rep(1:fold, ceiling(nR/fold))[1:nR]) cseg <- split(sample(1:nC), rep(1:fold, ceiling(nC/fold))[1:nC]) foldC <- length(cseg) foldR <- length(rseg) nP <- min(nR - max(sapply(rseg, length)), nC - max(sapply(cseg, length)), nPcs(object)) } q2 <- matrix(NA, nP, ncol=nruncv) for (nr in 1:nruncv) { press <- rep(0, nP) if (type == "impute") { seg <- list() nDiag <- max(nR, nC) diagPerFold <- floor(nDiag / fold) suppressWarnings(diags <- matrix(1:nDiag, nrow=diagPerFold, ncol=fold, byrow=TRUE)) if (diagPerFold == 0 || diagPerFold > (nDiag/2)) stop("Matrix could not be safely divided into ", fold, " segments. Choose a different fold or provide the desired segments") if (nDiag%%fold > 0) warning("Validation incomplete: ", (nDiag %% fold) * min(dim(originalData)), " values were left out of from cross validation, Q2 estimate will be biased.") for (i in 1:ncol(diags)) seg[[i]] <- which(is.na(deletediagonals(originalData, diags[, i]))) if (verbose) { pb <- txtProgressBar(0, length(seg), style=3, width=20) } j <- 0 for (i in seg) { j <- j + 1 if (verbose) setTxtProgressBar(pb, j) test <- originalData test[i] <- NA test <- tempFixNas(test) if (method(object) != "llsImpute") { pc <- pca(test, nPcs=nP, method=method(object), verbose=FALSE, center=centered(object), scale=object@scaled, ...) } for (np in 1:nP) { if (method(object) == "llsImpute") { fittedData <- completeObs(llsImpute(test, k=np, allVariables=TRUE, center=FALSE)) } else { if (method(object) == "nlpca") fittedData <- fitted(pc, data=test, nPcs=np) else fittedData <- fitted(pc, data=NULL, nPcs=np) } ii <- i[ceiling(i / nR) %in% variables] press[np] <- press[np] + sum((originalData[ii] - fittedData[ii])^2, na.rm=TRUE) } } } if (type == "krzanowski") { rseg <- split(sample(1:nR), rep(1:fold, ceiling(nR/fold))[1:nR]) cseg <- split(sample(1:nC), rep(1:fold, ceiling(nC/fold))[1:nC]) tcv <- array(0, dim=c(foldC, nR, nP)) pcv <- array(0, dim=c(foldR, nC, nP)) for (f in 1:foldC) { test <- tempFixNas(originalData[, -cseg[[f]]]) tcv[f, , ] <- scores(pca(test, nPcs=nP, method=method(object), verbose=FALSE, center=centered(object), scale=object@scaled, ...)) for (p in 1:nP) { if (cor(tcv[f, , p], scores(object)[, p]) < 0) tcv[f, , p] <- tcv[f, , p] * -1 } } for (f in 1:foldR) { test <- tempFixNas(originalData[-rseg[[f]], ]) pcv[f, , ] <- loadings(pca(test, nPcs=nP, method=method(object), verbose=FALSE, center=centered(object), scale=object@scaled, ...)) for (p in 1:nP) { if (cor(pcv[f, , p], loadings(object)[, p]) < 0) pcv[f, , p] <- pcv[f, , p] * -1 } } press <- rep(0, nP) for (p in 1:nP) for (fr in 1:foldR) for (fc in 1:foldC) press[p] <- press[p] + sum(( originalData[rseg[[fr]], cseg[[fc]]] - (tcv[fc, , ][, 1:p, drop=FALSE] %*% t(pcv[fr, , ][,1:p, drop=FALSE])) [rseg[[fr]], intersect(cseg[[fc]], variables)])^2, na.rm=TRUE) } q2[, nr] <- 1 - press/ssx } if (verbose) message("\n") rownames(q2) <- paste("PC", 1:nrow(q2)) drop(q2) } ##' Simply replace completely missing rows or cols with zeroes. ##' @title Temporary fix for missing values ##' @param mat a matrix ##' @return The original matrix with completely missing rows/cols ##' filled with zeroes. ##' @author Henning Redestig tempFixNas <- function(mat) { badRows <- apply(mat, 1, function(x) all(is.na(x))) badCols <- apply(mat, 2, function(x) all(is.na(x))) mat[ badRows,] <- 0 mat[,badCols ] <- 0 mat } ##' Replace a diagonal of elements of a matrix with NA ##' ##' Used for creating artifical missing values in matrices without ##' causing any full row or column to be completely missing ##' @title Delete diagonals ##' @param x The matrix ##' @param diagonals The diagonal to be replaced, i.e. the first, ##' second and so on when looking at the fat version of the matrix ##' (transposed or not) counting from the bottom. ##' Can be a vector to delete more than one diagonal. ##' @return The original matrix with some values missing ##' @author Henning Redestig deletediagonals <- function(x, diagonals=1) { wastransposed <- FALSE if (dim(x)[1] > dim(x)[2]) { # matrix must be lying down x <- t(x) wastransposed <- TRUE } nr <- nrow(x) nc <- ncol(x) if (!all(diagonals <= nc)) { stop(paste("Order of diagonal number", max(diagonals), "is out of bound")) } indexmatrix <- matrix(1 : (nr * nc), ncol=nc, nrow=nr) finalmatrix <- matrix(ncol=(nr - 1 + nc), nrow=nr) finalmatrix[,1 : (nr - 1)] <- indexmatrix[,rev((nc : 1)[1 : (nr - 1)])] finalmatrix[,nr : (nr - 1 + nc)] <- indexmatrix dia <- 1 + 0:(nr - 1) * (nr + 1) finalIndices <- NULL for (i in 1:length(diagonals)) { indicestodelete <- finalmatrix[dia + (diagonals[i] - 1) * nr] x[indicestodelete] <- NA finalIndices <- c(finalIndices, indicestodelete) } if (wastransposed) x <- t(x) return(x) } ##' Get cross-validation segments that have (as far as possible) the ##' same ratio of all classes (if classes are present) ##' @title Get CV segments ##' @param x a factor, character or numeric vector that describes ##' class membership of a set of items, or, a numeric vector ##' indicating unique indices of items, or, a numeric of length 1 that ##' describes the number of items to segment (without any classes) ##' @param fold the desired number of segments ##' @param seed randomization seed for reproducibility ##' @return a list where each element is a set of indices that defines ##' the CV segment. ##' @examples ##' seg <- cvseg(iris$Species, 10) ##' sapply(seg, function(s) table(iris$Species[s])) ##' cvseg(20, 10) ##' @seealso the \code{cvsegments} function in the \code{pls} package ##' @export ##' @author Henning Redestig cvseg <- function(x, fold=7, seed=NULL) { if(any(table(x) > 1)) { if(any(table(x) < fold)) { fold <- min(table(x)) } if(fold < 2) stop("too few observations in the smallest class") res <- sapply(unique(x), function(z) { if(!is.null(seed)) set.seed(seed) tmp <- sample(which(x == z)) seg <- matrix(c(tmp, rep(NA, ifelse(length(tmp) %% fold ==0, 0, fold - (length(tmp) %% fold)))), nrow=fold) },simplify=FALSE) res <- do.call("cbind", res) } else { if(length(x) == 1) x <- 1:x res <- matrix(sample(c(x, rep(NA, ifelse(length(x) %% fold ==0, 0, fold - (length(x) %% fold))))), nrow=fold) } res <- res[!apply(is.na(res), 1, all),,drop=FALSE] res lapply(as.data.frame(t(res)), function(x) c(na.omit(x))) } pcaMethods/README.md0000644000175100017510000000277314614231101015142 0ustar00biocbuildbiocbuild# pcaMethods R package for performing [principal component analysis PCA](https://en.wikipedia.org/wiki/Principal_component_analysis) with applications to missing value imputation. Provides a single interface to performing PCA using - **SVD:** a fast method which is also the standard method in R but which is not applicable for data with missing values. - **NIPALS:** an iterative fast method which is applicable also to data with missing values. - **PPCA:** Probabilistic PCA which is applicable also on data with missing values. Missing value estimation is typically better than NIPALS but also slower to compute and uses more memory. A port to R of the [implementation by Jakob Verbeek](http://lear.inrialpes.fr/~verbeek/software.php). - **BPCA:** Bayesian PCA which performs very well in the presence of missing values but is slower than PPCA. A port of the [matlab implementation by Shigeyuki Oba](http://ishiilab.jp/member/oba/tools/BPCAFill.html). - **NLPCA:** Non-linear PCA which can find curves in data and in presence of such can perform accurate missing value estimation. [Matlab port of the implementation by Mathias Scholz](http://www.nlpca.org/). [pcaMethods is a Bioconductor package](http://www.bioconductor.org/packages/release/bioc/html/pcaMethods.html) and you can install it by ```R if (!requireNamespace("BiocManager", quietly=TRUE)) install.packages("BiocManager") BiocManager::install("pcaMethods") ``` ## Documentation ```R browseVignettes("pcaMethods") ? ``` pcaMethods/src/0000755000175100017510000000000014614350074014454 5ustar00biocbuildbiocbuildpcaMethods/src/nipals.cpp0000644000175100017510000000731114614231101016435 0ustar00biocbuildbiocbuild#include #include #include using namespace std; using namespace Rcpp; double difference(vector& vec1, vector& vec2) { double diff = 0; double a; int len = vec1.size(); for(int i = 0; i < len; i++) { a = vec1[i] - vec2[i]; diff += a * a; } return(diff); } void norm(vector& vec) { double siz = 0; int len = vec.size(); for(int i = 0; i < len; i++) { siz += vec[i] * vec[i]; } siz = sqrt(siz); for(int i = 0; i < len; i++) { vec[i] = vec[i] / siz; } } // [[Rcpp::export]] List Nipals(SEXP Mat, SEXP params) { try{ bool cnt; int count = 0; double tsize; Rcpp::List rl = R_NilValue; Rcpp::List rparams(params); int maxSteps = Rcpp::as(rparams["maxSteps"]); double eps = Rcpp::as(rparams["threshold"]); int nPcs = Rcpp::as(rparams["nPcs"]); double varLimit = Rcpp::as(rparams["varLimit"]); Rcpp::NumericMatrix mat(Mat); Rcpp::NumericMatrix omat = Rcpp::clone( Mat ); int nr = mat.nrow(); int nc = mat.ncol(); Rcpp::NumericMatrix est_mat(nr, nc); Rcpp::NumericMatrix tt(nr, nPcs); Rcpp::NumericMatrix pp(nc, nPcs); vector r2cum; vector thold(nr); vector th(nr); vector phold(nc); vector ph(nc); double tss = 0; double sse = 0; int np = 0; double anotherPc = true; for (int r = 0; r < nr; r++) { for (int c = 0; c < nc; c++) { if(!ISNAN(mat(r,c))) { tss += mat(r,c) * mat(r,c); } } } while(anotherPc) { for(int r = 0; r < nr; r++) { th[r] = 0; if(!ISNAN(mat(r,0))) { th[r] = mat(r,0); } } cnt = true; count = 0; while(cnt) { count++; for(int c = 0; c < nc; c++) { ph[c] = 0; } tsize = 0; for(int r = 0; r < nr; r++) { tsize += th[r] * th[r]; } for(int r = 0; r < nr; r++) { double ti = th[r] / tsize; for(int c = 0; c < nc; c++) { if(!ISNAN(mat(r,c))) { ph[c] += mat(r,c) * ti; } } } norm(ph); thold = th; for(int r = 0; r < nr; r++) { th[r] = 0; for(int c = 0; c < nc; c++) { if(!ISNAN(mat(r,c))) { th[r] += mat(r,c) * ph[c]; } } } if(count > maxSteps) { throw 1; } if(difference(thold, th) <= eps) { cnt = false; } } //deflate mat sse = 0; double mathat = 0; double err = 0; for(int r = 0; r < nr; r++) { for(int c = 0; c < nc; c++) { if(!ISNAN(mat(r,c))) { mathat = th[r] * ph[c]; est_mat(r, c) += mathat; err = omat(r,c) - est_mat(r, c); sse += err * err; mat(r,c) -= mathat; } } } r2cum.push_back(1 - (sse / tss)); for(int r = 0; r < nr; r++) { tt(r,np) = th[r]; } for(int c = 0; c < nc; c++) { pp(c,np) = ph[c]; } if(fabs(varLimit - 1) > 1e-4) { if(r2cum[np] >= varLimit) { anotherPc = false; } } if (np + 1 >= nPcs){ anotherPc = false; } np++; } if(np != nPcs) { Rcpp::NumericMatrix ttt(nr, np); Rcpp::NumericMatrix ppp(nc, np); for(int r = 0; r < nr; r++) { for(int p = 0; p < np; p++) { ttt(r,p) = tt(r,p); } } for(int c = 0; c < nc; c++) { for(int p = 0; p < np; p++) { ppp(c,p) = pp(c,p); } } rl["scores"] = ttt; rl["loadings"] = ppp; } else { rl["scores"] = tt; rl["loadings"] = pp; } rl["R2cum"] = r2cum; return rl; }catch(int e) { if(e == 1) { ::Rf_error("Too many iterations, quitting"); }else { ::Rf_error("unknown error"); } } catch(std::exception& ex) { forward_exception_to_r(ex); } catch(...) { ::Rf_error("unknown error"); } return R_NilValue; } pcaMethods/src/RcppExports.cpp0000644000175100017510000000102414614231101017433 0ustar00biocbuildbiocbuild#include using namespace Rcpp; // Nipals List Nipals(SEXP Mat, SEXP params); RcppExport SEXP pcaMethods_Nipals(SEXP MatSEXP, SEXP paramsSEXP) { BEGIN_RCPP SEXP __sexp_result; { Rcpp::RNGScope __rngScope; Rcpp::traits::input_parameter< SEXP >::type Mat(MatSEXP ); Rcpp::traits::input_parameter< SEXP >::type params(paramsSEXP ); List __result = Nipals(Mat, params); PROTECT(__sexp_result = Rcpp::wrap(__result)); } UNPROTECT(1); return __sexp_result; END_RCPP } pcaMethods/vignettes/0000755000175100017510000000000014614350074015675 5ustar00biocbuildbiocbuildpcaMethods/vignettes/missingValues.Rnw0000644000175100017510000000565414614231101021215 0ustar00biocbuildbiocbuild\documentclass[a4paper]{article} %\VignetteIndexEntry{Missing value imputation} \usepackage{hyperref} \title{Imputing missing values using the pcaMethods package} \author{Wolfram Stacklies and Henning Redestig\\ CAS-MPG Partner Institute for Computational Biology (PICB)\\ Shanghai, P.R. China \\ and\\ Max Planck Institute for Molecular Plant Physiology\\ Potsdam, Germany\\ \url{http://bioinformatics.mpimp-golm.mpg.de/} } \date{\today} \begin{document} \setkeys{Gin}{width=1.0\textwidth} @ \maketitle \section{Missing value imputation} One application for missing value robust principal component analysis is that it effectively can be used to impute the missing values and thus obtain an estimated complete data set. The pcaMethods package was partly written with this application in mind. PCA is a way of creating a model of a matrix, $X$, by defining two parameter matrices, the scores, $T$, and the loadings, $P$, which together have less values than the original matrix but when multiplied with each other well reconstruct the original matrix. I.e.: $$X=1\times{}\bar{x} + TP' + E$$ where $E$ is the error matrix and $1\times{}\bar{x}$ denotes the original variable averages. Now if $X$ contains missing values but we still are able to get complete estimates of $P$ and $T$ than we can use: $$\hat{X}=1\times{}\bar{x} + TP'$$ as an estimate for $x_{i,j}$ if $x_{i,j}$ is missing. This is can be done as the following example illustrates. First we attach the metabolite data set with missing values. <>= library(pcaMethods) @ <<>>= data(metaboliteData) mD <- metaboliteData sum(is.na(mD)) @ Now we get the estimated data set by using PPCA and three principal components. <<>>= pc <- pca(mD, nPcs=3, method="ppca") imputed <- completeObs(pc) @ If we compare with the original values we see that the error is rather low. <<>>= data(metaboliteDataComplete) mdComp <- metaboliteDataComplete sum((mdComp[is.na(mD)] - imputed[is.na(mD)])^2) / sum(mdComp[is.na(mD)]^2) @ When using a different PCA algorithm, we get different performance. <<>>= imputedNipals <- completeObs(pca(mD, nPcs=3, method="nipals")) sum((mdComp[is.na(mD)] - imputedNipals[is.na(mD)])^2) / sum(mdComp[is.na(mD)]^2) @ If the data we are interested in was gene expression set of class 'ExpressionSet' we could simply do <<>>= library(Biobase) data(sample.ExpressionSet) exSet <- sample.ExpressionSet exSetNa <- exSet exprs(exSetNa)[sample(13000, 200)] <- NA lost <- is.na(exprs(exSetNa)) pc <- pca(exSetNa, nPcs=2, method="ppca") impExSet <- asExprSet(pc, exSetNa) sum((exprs(exSet)[lost] - exprs(impExSet)[lost])^2) / sum(exprs(exSet)[lost]^2) @ Different results will be obtained with different PCA algorithms. Which one to use depends on the general structure of the data set and the imputation performance can be estimated by cross-validation. Please see the 'introduction' vignette on further details on how to use the cross-validation capabilities of this package. \end{document} pcaMethods/vignettes/outliers.Rnw0000644000175100017510000001203114614231101020215 0ustar00biocbuildbiocbuild\documentclass[a4paper]{article} %\VignetteIndexEntry{Data with outliers} \usepackage{hyperref} \title{Handling of data containing outliers} \author{Wolfram Stacklies and Henning Redestig\\ CAS-MPG Partner Institute for Computational Biology (PICB)\\ Shanghai, P.R. China \\ and\\ Max Planck Institute for Molecular Plant Physiology\\ Potsdam, Germany\\ \url{http://bioinformatics.mpimp-golm.mpg.de/} } \date{\today} \begin{document} \setkeys{Gin}{width=1.0\textwidth} @ \maketitle \section{PCA robust to outliers} Away from often showing missing values, Microarray or Metabolite data are often corrupted with extreme values (outliers). Standard SVD is highly susceptible to outliers. In the extreme case, an individual data point, if sufficiently outlying, can draw even the leading principal component toward itself. This problem can be addressed by using a robust analysis method. Hereto we provide \texttt{robustSvd}, a singular value decomposition robust to outliers. \texttt{robustPca} is a PCA implementation that resembles the original \texttt{R} \texttt{prcomp} method, with the difference that it uses \texttt{robustSvd} instead of the standard \texttt{svd} function.\\ Robust SVD and its application to microarray data were proposed in \cite{hawkins01} and \cite{liu03}. The algorithm is based on the idea to use a sequential estimation of the eigenvalues and left and right eigenvectors that ignores missing values and is resistant to outliers. \\ The \texttt{robustSvd} script included here was contributed by Kevin Wright. Thanks a lot to him! \section{Outliers and missing value imputation} The problem of outliers is similar to the missing data problem in the sense that extreme values provide no or wrong information. They are generally artifacts of the experiment and provide no information about the underlying biological processes. \\ Most of the PCA methods coming with the package were not designed to be robust to outliers in the sense that they will converge to the standard PCA solution on a complete data set. Yet, an applicable solution is to remove obvious outliers from the data first (by setting them NA) and to then estimate the PCA solution on the incomplete data. This is likely to produce accurate results if the number of missing data does not exceed a certain amount, less than 10\% should be a good number. The following example illustrates the effect of outliers and the use of robust methods. First, we attach the complete metabolite data set and create 5\% outliers. We mean center the data before we create outliers because these large artificial outliers will strongly shift the original means. This would not allow for objective comparison between the differnt results obtained, e.g. when doing scatterplots. <>= library(pcaMethods) @ <<>>= data(metaboliteDataComplete) mdc <- scale(metaboliteDataComplete, center=TRUE, scale=FALSE) cond <- runif(length(mdc)) < 0.05 mdcOut <- mdc mdcOut[cond] <- 10 @ Then we calculate a PCA solution using standard SVD and robust SVD. <>= resSvd <- pca(mdc, method="svd", nPcs=5, center=FALSE) resSvdOut <- pca(mdcOut, method="svd", nPcs=5, center=FALSE) resRobSvd <- pca(mdcOut, method="robustPca", nPcs=5, center=FALSE) @ Now we use \texttt{PPCA} to estimate the PCA solution, but set the outliers NA before. <>= mdcNa <- mdc mdcNa[cond] <- NA resPPCA <- pca(mdcNa, method="ppca", nPcs=5, center=FALSE) @ To check the robustness to outliers we can just do a scatterplot comparing the results to the optimal PCA solution for the complete data set (which is \texttt{resSvd}). In Figure \ref{fig:svdPlot} we plot the estimated and original loadings against each other. \begin{figure}[!ht] \centering <>= par(mfrow=c(2,2)) plot(loadings(resSvd)[,1], loadings(resSvdOut)[,1], xlab="Loading 1 SVD", ylab="Loading 1 SVD with outliers") plot(loadings(resSvd)[,1], loadings(resRobSvd)[,1], xlab="Loading 1 SVD", ylab="Loading 1 robustSVD with outliers") plot(loadings(resSvd)[,1], loadings(resPPCA)[,1], xlab="Loading 1 SVD", ylab="Loading 1 PPCA with outliers=NA") plot(loadings(resRobSvd)[,1], loadings(resPPCA)[,1], xlab="Loading 1 robust SVD with outliers", ylab="Loading 1 svdImpute with outliers=NA") @ \caption{Figures show (from left to right): \newline Original PCA solution vs. solution on data with outliers; \newline Original PCA solution vs. robust PCA solution on data with outliers; \newline Original PCA solution vs. PPCA solution on data where outliers=NA; \newline Robust PCA solution vs. PPCA solution on data with outliers / outliers=NA. \label{fig:svdPlot} } \end{figure} \begin{thebibliography}{2006} \bibitem{hawkins01} Hawkins, D.M., Liu, L. and Young, S.S. {\sl Robust Singular Value Decomposition.} National Institute of Statistical Sciences, 2001, Tech Report 122. \bibitem{liu03} Liu, L., Hawkins, D.M., Ghosh, S. and Young, S.S. {\sl Robust singular value decomposition analysis of microarray data.} PNAS, 2003;100:13167--13172. \end{thebibliography} \end{document} pcaMethods/vignettes/pcaMethods.Rnw0000644000175100017510000005554214614231101020454 0ustar00biocbuildbiocbuild\documentclass[a4paper]{article} %\VignetteIndexEntry{Introduction} \usepackage{hyperref} \title{The pcaMethods Package} \author{Wolfram Stacklies and Henning Redestig\\ CAS-MPG Partner Institute for Computational Biology (PICB)\\ Shanghai, P.R. China \\ and\\ Max Planck Institute for Molecular Plant Physiology\\ Potsdam, Germany\\ \url{http://bioinformatics.mpimp-golm.mpg.de/} } \date{\today} \begin{document} \setkeys{Gin}{width=1.0\textwidth} @ \maketitle \section*{Overview} The \texttt{pcaMethods} package \cite{stacklies07} provides a set of different PCA implementations, together with tools for cross validation and visualisation of the results. The methods basically allow to perform PCA on incomplete data and thus may also be used for missing value estimation. When doing PCA one assumes that the data is restricted to a subspace of lower dimensionality, e.g. correlation patterns between jointly regulated genes. PCA aims to extract these structures thereby filtering noise out. If only the most significant loadings (eigenvectors, also referred to as principal components) are used for projection this can be written as: \begin{equation} X = 1\times{}\bar{x}^T + TP^T + V \end{equation} Where the term $1\times{}\bar{x}^T$ represents the original variable averages, $X$ denotes the observations, $T={t_1, t_2,\ldots,t_k}$ the latent variables or scores, $P={p_1, p_2,\ldots,p_k}$ the transformation matrix (consisting of the most significant eigenvectors of the covariance matrix) and $V$ are the residuals. Missing values may be estimated by projecting the scores back into the original space using $\hat{X} = 1\times{}\bar{x}^T + TP^T$. Optimally, this produces an estimate of the missing data based on the underlying correlation structure, thereby ignoring noise. This will only produce reasonable results if the residuals $V$ are sufficiently small, implying that most of the important information is captured by the first $k$ components. In order to calculate the transformation matrix $P$ one needs to determine the covariance matrix between variables or alternatively calculate $P$ directly via SVD. In both cases, this can only be done on complete matrices. However, an approximation may be obtained by use of different regression methods. The PCA methods provided in this package implement algorithms to accurately estimate the PCA solution on incomplete data. Although the focus of this package is clearly to provide a collection of PCA methods we also provide a cluster based method for missing value imputation. This allows to better rate and compare the results. \section{Algorithms} All methods return a common class called \texttt{pcaRes} as a container for the results. This guarantees maximum flexibility for the user. A wrapper function called \texttt{pca()} is provided that receives the desired type of pca as a string. \subsection*{svdPca} This is a wrapper function for $R's$ standard \texttt{prcomp} function. It delivers the results as a \texttt{pcaRes} object for compatibility with the rest of the package. \subsection*{svdImpute} This implements the SVDimpute algorithm as proposed by Troyanskaya et~al \cite{troyanskaya01}. The idea behind the algorithm is to estimate the missing values as a linear combination of the $k$ most significant eigengenes\footnote{The term ``eigengenes'' denotes the loadings when PCA was applied considering variables (here the genes) as observations.}. The algorithm works iteratively until the change in the estimated solution falls below a certain threshold. Each step the eigengenes of the current estimate are calculated and used to determine a new estimate. An optimal linear combination is found by regressing an incomplete variable against the $k$ most significant eigengenes. If the value at position $j$ is missing, the $j^{th}$ value of the eigengenes is not used when determining the regression coefficients.\\ SVDimpute seems to be tolerant to relatively high amount of missing data (> 10\%). \subsection*{Probabilistic PCA (ppca)} Probabilistic PCA combines an EM approach for PCA with a probabilistic model. The EM approach is based on the assumption that the latent variables as well as the noise are normal distributed. In standard PCA data which is far from the training set but close to the principal subspace may have the same reconstruction error, see Figure \ref{fig:pcaSubspace} for explanation. <>= library(pcaMethods) x <- c(-4,7); y <- c(-3,4) distX <- rnorm(100, sd=0.3)*3 distY <- rnorm(100, sd=0.3) + distX * 0.3 mat <- cbind(distX, distY) res <- pca(mat, nPcs=2, method="svd", center=F) loading <- loadings(res)[1,] grad <- loading[2] / loading[1] if (grad < 0) grad <- grad * -1 lx <- c(-4,7) ly <- c(grad * -4, grad * 7) @ \begin{figure} \centering <>= par(mar=c(2, 3, 2, 2)) plot(x,y, type="n", xlab="", ylab="") abline(v=0, col="dark gray", lwd = 2); abline(h=0, col = "dark gray", lwd = 2) points(distX, distY, type = 'p', col = "blue") lines(lx,ly, lwd = 2) points(-1, -1 * grad + 0.5, pch = 19, col = "red", lwd=4) points(6, 6 * grad + 0.5, pch = 19, col = "red", lwd=4) @ \caption{Normal distributed data with the first loading plotted in black. The two red points have the same reconstruction error because PCA does not define a density model. Thus the only measure of how well new data fits the model is the distance from the principal subspace. Data points far from the bulk of data but still close to the principal subspace will have a low reconstruction error. \label{fig:pcaSubspace}} \end{figure} PPCA defines a likelihood function such that the likelihood for data far from the training set is much lower, even if they are close to the principal subspace. This allows to improve the estimation accuracy.\\ PPCA is tolerant to amounts of missing values between 10\% to 15\%. If more data is missing the algorithm is likely not to converge to a reasonable solution. The method was implemented after the draft ``\texttt{EM Algorithms for PCA and Sensible PCA}'' written by Sam Roweis and after the Matlab \texttt{ppca} script implemented by \emph{Jakob Verbeek}\footnote{\url{http://lear.inrialpes.fr/~verbeek/}}. Please check also the PPCA help file. \subsection*{Bayesian PCA (bpca)} Similar to probabilistic PCA, Bayesian PCA uses an EM approach together with a Bayesian model to calculate the likelihood for a reconstructed value.\\ The algorithm seems to be tolerant to relatively high amounts of missing data (> 10\%). Scores and loadings obtained with Bayesian PCA slightly differ from those obtained with conventional PCA. This is because BPCA was developed especially for missing value estimation and is based on a variational Bayesian framework (VBF), with automatic relevance determination (ARD). In BPCA, ARD leads to a different scaling of the scores, loadings and eigenvalues when compared to standard PCA or PPCA. The algorithm does not force orthogonality between loadings. However, the authors of the BPCA paper found that including an orthogonality criterion made the predictions worse. They also state that the difference between ``real'' and predicted Eigenvalues becomes larger when the number of observation is smaller, because it reflects the lack of information to accurately determine true loadings from the limited and noisy data. As a result, weights of factors to predict missing values are not the same as with conventional PCA, but the missing value estimation is improved. BPCA was proposed by Oba et~al \cite{oba03}. The method available in this package is a port of the \texttt{bpca} Matlab script also provided by the authors\footnote{ \url{http://hawaii.aist-nara.ac.jp/\%7Eshige-o/tools/}}. \subsection*{Inverse non-linear PCA (NLPCA)} NLPCA \cite{scholz05} is especially suitable for data from experiments where the studied response is non-linear. Examples of such experiments are ubiquitous in biology -- enzyme kinetics are inherently non-linear as are gene expression responses influenced by the cell cycle or diurnal oscillations. NLPCA is based on training an auto-associative neural network composed of a component layer which serves as the ``bottle-neck'', a hidden non-linear layer and an output layer corresponding to the reconstructed data. The loadings can be seen as hidden in the network. Missing values in the training data are simply ignored when calculating the error during back-propagation. Thus NLPCA can be used to impute missing values in the same way as for conventional PCA. The only difference is that the loadings $P$ are now represented by a neural network.\\ A shortcoming of the current implementation is that there is no reasonable stop criterion. The quality of the estimated solution depends on the number of iterations. This should in most cases be somewhat between 500 and 1500. We recommend to use \texttt{kEstimate} or \texttt{kEstimateFast} to determine this parameter. \subsection*{Nipals PCA} Nipals (Nonlinear Estimation by Iterative Partial Least Squares) \cite{wold66} is an algorithm at the root of PLS regression which can execute PCA with missing values by simply leaving those out from the appropriate inner products. It is tolerant to small amounts (generally not more than 5\%) of missing data. \subsection{Local least squares (LLS) imputation} The package provides an algorithm called \texttt{llsImpute} for missing value estimation based on a linear combination of the $k$ nearest neighbours of an incomplete variable (in Microarray experiments normally a gene). The distance between variables is defined as the absolute value of the Pearson, Spearman or Kendall correlation coefficient. The optimal linear combination is found by solving a local least squares problem as described in \cite{kim05}. In tests performed in the cited paper the llsImpute algorithm is able to outperform knnImpute\cite{troyanskaya01} and competes well with BPCA. In the current implementation two slightly different ways for missing value estimation are provided. The first one is to restrict the neighbour searching to the subset of complete variables. This is preferable when the number of incomplete variables is relatively small. The second way is to consider all variables as candidates. Here, missing values are initially replaced by the columns wise mean. The method then iterates, using the current estimate as input for the LLS regression until the change between new and old estimate falls below a certain threshold (0.001). \section{Getting started} \paragraph{Installing the package.} To install the package first download the appropriate file for your platform from the Bioconductor website (\url{http://www.bioconductor.org/}). For Windows, start \texttt{R} and select the \texttt{Packages} menu, then \texttt{Install package from local zip file}. Find and highlight the location of the zip file and click on \texttt{open}. For Linux/Unix, use the usual command \texttt{R CMD INSTALL} or set the option \texttt{CRAN} to your nearest mirror site and use the command \texttt{install.packages} from within an \texttt{R} session. \paragraph{Loading the package:} To load the \texttt{pcaMethods} package in your \texttt{R} session, type \texttt{library(pcaMethods)}. \paragraph{Help files:} Detailed information on \texttt{pcaMethods} package functions can be obtained from the help files. For example, to get a description of \texttt{bpca} type \texttt{help("bpca")}. \paragraph{Sample data:} Two sample data sets are coming with the package. \texttt{metaboliteDataComplete} contains a complete subset from a larger metabolite data set. \texttt{metaboliteData} is the same data set but with 10 \% values removed from an equal distribution. \section{Some examples} <>= library(lattice) library(pcaMethods) @ To load the package and the two sample data sets type: <>= library(pcaMethods) data(metaboliteData) data(metaboliteDataComplete) @ Now centre the data <<>>= md <- prep(metaboliteData, scale="none", center=TRUE) mdC <- prep(metaboliteDataComplete, scale="none", center=TRUE) @ Run SVD pca, PPCA, BPCA, SVDimpute and nipalsPCA on the data, using the \texttt{pca()} wrapper function. The result is always a \texttt{pcaRes} object. <>= resPCA <- pca(mdC, method="svd", center=FALSE, nPcs=5) resPPCA <- pca(md, method="ppca", center=FALSE, nPcs=5) resBPCA <- pca(md, method="bpca", center=FALSE, nPcs=5) resSVDI <- pca(md, method="svdImpute", center=FALSE, nPcs=5) resNipals <- pca(md, method="nipals", center=FALSE, nPcs=5) resNLPCA <- pca(md, method="nlpca", center=FALSE, nPcs=5, maxSteps=300) @ Figure \ref{fig:eigenvalues} shows a plot of the eigenvalue structure (\texttt{sDev(pcaRes)}). If most of the variance is captured with few loadings PCA is likely to produce good missing value estimation results. For the sample data all methods show similar eigenvalues. One can also see that most of the variance is already captured by the first loading, thus estimation is likely to work fine on this data. For BPCA, the eigenvalues are scaled differently for reasons discussed above, see Figure \ref{fig:loadingBPCA}. The order of the loadings remains the same. \begin{figure} \centering <>= sDevs <- cbind(sDev(resPCA), sDev(resPPCA), sDev(resBPCA), sDev(resSVDI), sDev(resNipals), sDev(resNLPCA)) matplot(sDevs, type = 'l', xlab="Eigenvalues", ylab="Standard deviation of PC", lwd=3) legend(x="topright", legend=c("PCA", "PPCA", "BPCA", "SVDimpute","Nipals PCA","NLPCA"), lty=1:6, col=1:6, lwd=3) @ \caption{Eigenvalue structure as obtained with different methods\label{fig:eigenvalues}} \end{figure} To get an impression of the correctness of the estimation it is a good idea to plot the scores / loadings obtained with classical PCA and one of the probabilistic methods against each other. This of course requires a complete data set from which data is randomly removed. Figure \ref{fig:loadingBPCA} shows this for BPCA on the sample data. \begin{figure} \centering <>= par(mfrow=c(1,2)) plot(loadings(resBPCA)[,1], loadings(resPCA)[,1], xlab="BPCA", ylab="classic PCA", main = "Loading 1") plot(loadings(resBPCA)[,2], loadings(resPCA)[,2], xlab="BPCA", ylab="classic PCA", main = "Loading 2") @ \caption{Loading 1 and 2 calculated with BPCA plotted against those calculated with standard PCA. \label{fig:loadingBPCA}} \end{figure} \section{Cross validation} \texttt{Q2} is the goodness measure used for internal cross validation. This allows to estimate the level of structure in a data set and to optimise the choice of number of loadings. Cross validation is performed by removing random elements of the data matrix, then estimating these using the PCA algorithm of choice and then calculating $Q^2$ accordingly. At the moment, cross-validation can only be performed with algorithms that allow missing values (i.e. not SVD). Missing value independent cross-validation is scheduled for implementation in later versions. $Q^2$ is defined as following for the mean centered data (and possibly scaled) matrix $X$. $$\mathrm{SSX}=\sum (x_{ij})^2$$ $$\mathrm{PRESS}=\sum (x_{ij} - \hat{x}_{ij})^2$$ $$Q^2=1 - \mathrm{PRESS}/\mathrm{SSX}$$ The maximum value for $Q^2$ is thus 1 which means that all variance in $X$ is represented in the predictions; $X=\hat{X}$. <>= q2SVDI <- Q2(resSVDI, mdC, fold=10) q2PPCA <- Q2(resPPCA, mdC, fold=10) @ <>= # PPCA does not converge / misestimate a value in very rare cases. # This is a workaround to avoid that such a case will break the # diagram displayed in the vignette. # From the 2.0 release of bioconductor on, the convergence threshold # for PPCA was lowert to 1e-5, this should make the method much more # stable. So this workaround might be obsolete now... # [nope it is not, ppca is unstable] while( sum((abs(q2PPCA)) > 1) >= 1 ) { q2PPCA <- Q2(resPPCA, mdC, fold=10) } @ \begin{figure}[!ht] \centering <>= q2 <- data.frame(Q2=c(drop(q2PPCA), drop(q2SVDI)), method=c("PPCA", "SVD-Impute")[gl(2, 5)], PC=rep(1:5, 2)) print(xyplot(Q2~PC|method, q2, ylab=expression(Q^2), type="h", lwd=4)) @ \caption{Boxplot of the \texttt{Q2} results for BPCA, Nipals PCA, SVDimpute and PPCA. PPCA and SVDimpute both deliver better results than BPCA and Nipals in this example.\label{fig:Q2}} \end{figure} The second method called \texttt{kEstimate} uses cross validation to estimate the optimal number of loadings for missing value estimation. The \texttt{NRMSEP} (normalised root mean square error of prediction) \cite{feten05} or Q2 can be used to define the average error of prediction. The NRMSEP normalises the square difference between real and estimated values for a certain variable by the variance within this variable. The idea behind this normalisation is that the error of prediction will automatically be higher if the variance is higher. The \texttt{NRMSEP} for mean imputation is $\sqrt{\frac{nObs}{nObs - 1}}$ when cross validation is used, where $nObs$ is the number of observations. The exact definition is: \begin{equation} NRMSEP_k = \sqrt{\frac{1}{g} \sum_{j \in G} \frac{\sum_{i \in O_j} (x_{ij} - \hat{x}_{ijk})^2}{o_j s_{x_j}^2}} \end{equation} where $s^2_{x_j} = \sum_{i=1}^n (x_{ij} - \overline{x}_j)^2 / (n - 1)$, this is the variance within a certain variable. Further, $G$ denotes the set of incomplete variables, $g$ is the number of incomplete varialbes. $O_j$ is the set of missing observations in variable $j$ and $o_j$ is the number of missing observations in variable $j$. $\hat{x}_{ijk}$ stands for the estimate of value $i$ of variable $j$ using $k$ loadings. See Figure \ref{fig:kEstimate} for an example. The NRMSEP should be the error measure of choice. But if the number of observations is small, the variance within a certain variable may become and unstable criterion. If so or if variance scaling was applied we recommend to use Q2 instead. <>= errEsti <- kEstimate(md, method = "ppca", evalPcs=1:5, nruncv=1, em="nrmsep") @ \begin{figure}[!ht] \centering \begin{minipage}[c]{0.6\textwidth} \centering <>= barplot(drop(errEsti$eError), xlab="Loadings", ylab="NRMSEP (Single iteration)") @ \end{minipage} \begin{minipage}[c]{0.3\textwidth} \caption{Boxplot showing the \texttt{NRMSEP} versus the number of loadings. In this example only 1 iteration of the whole cross validation were performed. It is normally advisable to do more than just one iteration. \label{fig:kEstimate}} \end{minipage} \end{figure} \texttt{kEstimate} also provides information about the estimation error for individual variables. The $Q^2$ distance or the NRMSEP are calculated separately for each variable. See the manpage for \texttt{kEstimate} and \texttt{kEstimateFast} for details. Plotting the variable - wise results gives information about for which variables missing value estimation makes sense, and for which no imputation or mean imputation is preferable, see Figure \ref{fig:variableWiseError}. If you are not interested in variable - wise information we recommend to use the faster \texttt{kEstimateFast} instead. \begin{figure}[!ht] \centering \begin{minipage}[c]{0.6\textwidth} \centering <>= barplot(drop(errEsti$variableWiseError[, which(errEsti$evalPcs == errEsti$bestNPcs)]), xlab="Incomplete variable Index", ylab="NRMSEP") @ \end{minipage} \begin{minipage}[c]{0.3\textwidth} \caption{Boxplot showing the \texttt{NRMSEP} for all incomplete variables in the data set. For the first 7 variables missing value imputation does not seem to make too much sense. \label{fig:variableWiseError}} \end{minipage} \end{figure} \newpage \section{Visualisation of the results} \subsection{Quick scores and loadings plot} Some methods for display of scores and loadings are also provided. The function \texttt{slplot()} aims to be a simple way to quickly visualise scores and loadings in an intuitive way, see Figure \ref{fig:slplot}. Barplots are provided when plotting only one PC and colours can be specified differently for the scores and loadings plots. For a more specific scatter plot it is however recommended to access scores and loadings slots and define own plot functions. \begin{figure}[!h] \centering <>= slplot(resPCA) @ \caption{\texttt{slplot} for scores and loadings obtained with classical SVD based PCA. \label{fig:slplot}} \end{figure} \noindent Another method called \texttt{plotPcs()} allows to visualise many PCs plotted against each other, see Figure \ref{fig:plotPcs}. \begin{figure}[!ht] \centering <>= plotPcs(resPPCA, pc=1:3, type="score") @ \caption{A plot of score 1:3 for PPCA created with \texttt{plotPcs()} \label{fig:plotPcs}} \end{figure} \subsection{Using ggplot2} For using ggplot, the scores and loadings should best be added to a data frame that add other relevant descriptive factors. For example, after doing PCA on the Iris dataset, we may add the scores back to the original data frame and use ggplot to visualise, see Figure \ref{fig:ggplot}. \begin{figure}[!ht] \centering <>= pc <- pca(iris) irdf <- merge(iris, scores(pc), by=0) library(ggplot2) ggplot(irdf, aes(PC1, PC2, colour=Species)) + geom_point() + stat_ellipse() @ \caption{Score plot using ggplot2} \label{fig:ggplot} \end{figure} \cleardoublepage \begin{thebibliography}{2006} \bibitem{stacklies07} Stacklies W., Redestig H., Scholz M., and Walther D., and Selbig J. {\sl pcaMethods -- a Bioconductor package providing PCA methods for incomplete data} Bioinformatics. 2007, 23, 1164-1167. {\sl Non-linear PCA: a missing data approach.} Bioinformatics. 2005, 21, 3887-3895. \bibitem{scholz05} Scholz, M. , Kaplan, F., Guy, C.L., Kopka, J. and Selbig, J. {\sl Non-linear pca: a missing data approach.} Bioinformatics. 2005, 21, 3887-3895. \bibitem{troyanskaya01} Troyanskaya O. and Cantor M. and Sherlock G. and Brown P. and Hastie T. and Tibshirani R. and Botstein D. and Altman RB. {\sl Missing value estimation methods for DNA microarrays.} Bioinformatics. 2001 Jun;17(6):520-525. \bibitem{feten05} Feten G. and Almoy T. and Aastveit A.H. {\sl Prediction of Missing Values in Microarray and Use of Mixed Models to Evaluate the Predictors.}, Stat. Appl. Genet. Mol. Biol. 2005;4(1):Article 10 \bibitem{oba03} Oba S. and Sato MA. and Takemasa I. and Monden M. and Matsubara K. and Ishii S. {\sl A Bayesian missing value estimation method for gene expression profile data.} Bioinformatics. 2003 Nov 1;19(16):2088-96. \bibitem{wold66} Wold H. {Estimation of principal components and related models by iterative least squares.} In Multivariate Analysis (Ed. P.R. Krishnaiah), Academic Press, NY, 391-420. \bibitem{kim05} Kim H. and Golub G.H. and Park H. {\sl Missing value estimation for DNA microarray gene expression data: local least squares imputation} Bioinformatics. 2005 21(2) :187-198 \end{thebibliography} \end{document}