Csdp-6.2.0/0000755000175200017520000000000013136043252011055 5ustar coincoinCsdp-6.2.0/include/0000755000175200017520000000000013136043252012500 5ustar coincoinCsdp-6.2.0/include/index.h0000644000175200017520000000153213122046706013763 0ustar coincoin/* Declarations needed to handle indexing into Fortran arrays and packed arrays. */ #ifndef BIT64 /* First, to convert fortran i,j indices into a C vector index. */ #define ijtok(iiii,jjjj,lda) ((jjjj-1)*(lda)+iiii-1) /* Packed indexing. */ #define ijtokp(iii,jjj,lda) ((iii+jjj*(jjj-1)/2)-1) /* Next, to convert C vector index into Fortran i,j indices. */ #define ktoi(k,lda) ((k % (lda))+1) #define ktoj(k,lda) ((k/(lda))+1) #else /* First, to convert fortran i,j indices into a C vector index. */ #define ijtok(iiii,jjjj,lda) ((jjjj-1L)*(lda)+iiii-1L) /* Packed indexing. */ #define ijtokp(iii,jjj,lda) (((long int)iii+(long int)jjj*(jjj-1L)/2-1L)) /* Next, to convert C vector index into Fortran i,j indices. */ #define ktoi(k,lda) ((((long int)k) % (lda))+1L) #define ktoj(k,lda) ((((long int)k)/(lda))+1L) #endif Csdp-6.2.0/include/declarations.h0000644000175200017520000002000313120611661015312 0ustar coincoin/* * CSDPDECLARATIONS is used to prevent redefinitions if this file is included * twice. */ #ifndef CSDPDECLARATIONS #define CSDPDECLARATIONS /* Other important includes that we need. */ #include "index.h" #include "blockmat.h" #include "parameters.h" /* Our own routines. */ void triu(struct blockmatrix A); void store_packed(struct blockmatrix A, struct blockmatrix B); void store_unpacked(struct blockmatrix A, struct blockmatrix B); void alloc_mat_packed(struct blockmatrix A, struct blockmatrix *pB); void free_mat_packed(struct blockmatrix A); int structnnz(int n, int k, struct blockmatrix C, struct constraintmatrix *constraints); int actnnz(int n, int lda, double *A); int bandwidth(int n, int lda, double *A); void qreig(int n, double *maindiag, double *offdiag); void sort_entries(int k, struct blockmatrix C, struct constraintmatrix *constraints); double norm2(int n, double *x); double norm1(int n, double *x); double norminf(int n, double *x); double Fnorm(struct blockmatrix A); double Knorm(struct blockmatrix A); double mat1norm(struct blockmatrix A); double matinfnorm(struct blockmatrix A); double calc_pobj(struct blockmatrix C, struct blockmatrix X, double constant_offset); double calc_dobj(int k, double *a, double *y, double constant_offset); double trace_prod(struct blockmatrix A, struct blockmatrix B); double linesearch(int n, struct blockmatrix dX, struct blockmatrix work1, struct blockmatrix work2, struct blockmatrix work3, struct blockmatrix cholinv, double *q, double *z, double *workvec, double stepfrac,double start, int printlevel); double pinfeas(int k, struct constraintmatrix *constraints, struct blockmatrix X, double *a, double *workvec); double dinfeas(int k, struct blockmatrix C, struct constraintmatrix *constraints, double *y, struct blockmatrix Z, struct blockmatrix work1); double dimacserr3(int k, struct blockmatrix C, struct constraintmatrix *constraints, double *y, struct blockmatrix Z, struct blockmatrix work1); void op_a(int k, struct constraintmatrix *constraints, struct blockmatrix X, double *result); void op_at(int k, double *y, struct constraintmatrix *constraints, struct blockmatrix result); void makefill(int k, struct blockmatrix C, struct constraintmatrix *constraints, struct constraintmatrix *pfill, struct blockmatrix work1, int printlevel); void op_o(int k, struct constraintmatrix *constraints, struct sparseblock **byblocks, struct blockmatrix Zi, struct blockmatrix X, double *O, struct blockmatrix work1, struct blockmatrix work2); void addscaledmat(struct blockmatrix A, double scale, struct blockmatrix B, struct blockmatrix C); void zero_mat(struct blockmatrix A); void add_mat(struct blockmatrix A,struct blockmatrix B); void sym_mat(struct blockmatrix A); void make_i(struct blockmatrix A); void copy_mat(struct blockmatrix A, struct blockmatrix B); void mat_mult(double scale1, double scale2, struct blockmatrix A, struct blockmatrix B, struct blockmatrix C); void mat_multspa(double scale1, double scale2, struct blockmatrix A, struct blockmatrix B, struct blockmatrix C, struct constraintmatrix fill); void mat_multspb(double scale1, double scale2, struct blockmatrix A, struct blockmatrix B, struct blockmatrix C, struct constraintmatrix fill); void mat_multspc(double scale1, double scale2, struct blockmatrix A, struct blockmatrix B, struct blockmatrix C, struct constraintmatrix fill); void mat_mult_raw(int n, double scale1, double scale2, double *ap, double *bp, double *cp); void mat_mult_rawatlas(int n, double scale1, double scale2, double *ap, double *bp, double *cp); void matvec(struct blockmatrix A, double *x, double *y); void alloc_mat(struct blockmatrix A, struct blockmatrix *pB); void free_mat(struct blockmatrix A); void initparams(struct paramstruc *params, int *pprintlevel); void initsoln(int n, int k, struct blockmatrix C, double *a, struct constraintmatrix *constraints, struct blockmatrix *pX0, double **py0, struct blockmatrix *pZ0); void trans(struct blockmatrix A); void chol_inv(struct blockmatrix A, struct blockmatrix B); int chol(struct blockmatrix A); int solvesys(int m, int ldam, double *A, double *rhs); int user_exit(int n, int k, struct blockmatrix C, double *a, double dobj, double pobj, double constant_offset, struct constraintmatrix *constraints, struct blockmatrix X, double *y, struct blockmatrix Z, struct paramstruc params); int read_sol(char *fname, int n, int k, struct blockmatrix C, struct blockmatrix *pX, double **py, struct blockmatrix *pZ); int read_prob(char *fname, int *pn, int *pk, struct blockmatrix *pC, double **pa, struct constraintmatrix **pconstraints, int printlevel); int write_prob(char *fname, int n, int k, struct blockmatrix C, double *a, struct constraintmatrix *constraints); int write_sol(char *fname, int n, int k, struct blockmatrix X, double *y, struct blockmatrix Z); void free_prob(int n, int k, struct blockmatrix C, double *a, struct constraintmatrix *constraints, struct blockmatrix X, double *y, struct blockmatrix Z); int sdp(int n, int k, struct blockmatrix C, double *a, double constant_offset, struct constraintmatrix *constraints, struct sparseblock **byblocks, struct constraintmatrix fill, struct blockmatrix X, double *y, struct blockmatrix Z, struct blockmatrix cholxinv, struct blockmatrix cholzinv, double *pobj, double *dobj, struct blockmatrix work1, struct blockmatrix work2, struct blockmatrix work3, double *workvec1, double *workvec2, double *workvec3, double *workvec4, double *workvec5, double *workvec6, double *workvec7, double *workvec8, double *diagO, struct blockmatrix bestx, double *besty, struct blockmatrix bestz, struct blockmatrix Zi, double *O, double *rhs, struct blockmatrix dZ, struct blockmatrix dX, double *dy, double *dy1, double *Fp, int printlevel, struct paramstruc parameters); int easy_sdp(int n, int k, struct blockmatrix C, double *a, struct constraintmatrix *constraints, double constant_offset, struct blockmatrix *pX, double **py, struct blockmatrix *pZ, double *ppobj, double *pdobj); int checkconstraints(int n, int k, struct blockmatrix C, struct constraintmatrix *constraints, int printlevel); int checkc(int n, struct blockmatrix C, int printlevel); void tweakgap(int n, int k, double *a, struct constraintmatrix *constraints, double gap, struct blockmatrix Z, struct blockmatrix dZ, double *y, double *dy, struct blockmatrix work1, struct blockmatrix work2, struct blockmatrix work3, struct blockmatrix work4, double *workvec1, double *workvec2, double *workvec3, double *workvec4, int printlevel); int bisect_(int *n, double *eps1, double *d, double *e, double *e2, double *lb, double *ub, int *mm, int *m, double *w, int *ind, int *ierr, double *rv4, double *rv5); /* BLAS and LINPACK stuff. */ /* First, BLAS routines. */ #ifdef CAPSBLAS #ifdef NOUNDERBLAS double DNRM2(); double DASUM(); double DDOT(); int IDAMAX(); void DGEMM(); void DGEMV(); void DGER(); void DTRSM(); void DTRMV(); #else double DNRM2_(); double DASUM_(); double DDOT_(); int IDAMAX_(); void DGEMM_(); void DGEMV_(); void DGER_(); void DTRSM_(); void DTRMV_(); #endif #else #ifdef NOUNDERBLAS double dnrm2(); double dasum(); double ddot(); int idamax(); void dgemm(); void dgemv(); void dger(); void dtrsm(); void dtrmv(); #else double dnrm2_(); double dasum_(); double ddot_(); int idamax_(); void dgemm_(); void dgemv_(); void dger_(); void dtrsm_(); void dtrmv_(); #endif #endif /* LAPACK next. */ #ifdef CAPSLAPACK #ifdef NOUNDERLAPACK void DPOTRF(); void DPOTRS(); void DPOTRI(); void DTRTRI(); #else void DPOTRF_(); void DPOTRS_(); void DPOTRI_(); void DTRTRI_(); #endif #else #ifdef NOUNDERLAPACK void dpotrf(); void dpotrs(); void dpotri(); void dtrtri(); #else void dpotrf_(); void dpotrs_(); void dpotri_(); void dtrtri_(); #endif #endif #endif Csdp-6.2.0/include/blockmat.h0000644000175200017520000000253013126006077014450 0ustar coincoin/* This file contains definitions for the block matrix data structures used in CSDP 3.0. Note that there are an additional set of definitions used for sparse constraint matrices. */ /* Each block is a diagonal block or a matrix */ enum blockcat {DIAG, MATRIX, PACKEDMATRIX}; /* A block data record contains a pointer to the actual data for the block. Note that matrices are stored in Fortran form, while vectors are stored using indices 1, 2, ..., n. */ union blockdatarec { double *vec; double *mat; }; /* A block record describes an individual block within a matrix. */ struct blockrec { union blockdatarec data; enum blockcat blockcategory; int blocksize; }; /* A block matrix contains an entire matrix in block diagonal form. */ struct blockmatrix { int nblocks; struct blockrec *blocks; }; /* Definition for constraint matrices. */ /* * There's one of these for each nonzero block in each constraint matrix. */ struct sparseblock { struct sparseblock *next; struct sparseblock *nextbyblock; double *entries; int *iindices; int *jindices; int numentries; int blocknum; int blocksize; int constraintnum; int issparse; }; /* * A constraint matrix is just an array of pointers to linked lists of * the constraint blocks. */ struct constraintmatrix { struct sparseblock *blocks; }; Csdp-6.2.0/include/parameters.h0000644000175200017520000000123410522313034015006 0ustar coincoin/* This include file contains declarations for a number of parameters that can affect the performance of CSDP. You can adjust these parameters by 1. #include "parameters.h" in your code. 2. Declare struct paramstruc params; 3. Call init_params(params); to get default values. 4. Change the value of the parameter that you're interested in. */ struct paramstruc { double axtol; double atytol; double objtol; double pinftol; double dinftol; int maxiter; double minstepfrac; double maxstepfrac; double minstepp; double minstepd; int usexzgap; int tweakgap; int affine; double perturbobj; int fastmode; }; Csdp-6.2.0/AUTHORS0000644000175200017520000000054610522714256012137 0ustar coincoinMain author(s): Dr. Brian Borchers main contributor Other contributors: Joseph Young Original parallel version of op_o. Aaron Wilson modified documentation/install procedure for COIN-OR Csdp-6.2.0/doc/0000755000175200017520000000000013136043252011622 5ustar coincoinCsdp-6.2.0/doc/a1block1.pdf0000644000175200017520000011054710470505023013717 0ustar coincoin%PDF-1.3 %쏢 6 0 obj <> stream xWK7 ϯ[̊@ΩI#(__R5q`O lR>lg#}8MwÄqB;[1ͧAc ft!h9m|hʱh ]6xGװ© !VjbCPz 8Ǘh?8ӟ=H0)yQ*uDs3\MaR6,SymEʰ3lsi.%pvE 1`p+C!8o\l Cl4y#aޞ]pruK1Œd59>8[Ϭ q#DcY$/> /Contents 6 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 5 0 R ] /Count 1 >> endobj 1 0 obj <> endobj 4 0 obj <> endobj 9 0 obj <> endobj 8 0 obj <>stream x{XWYvg$ɮ^E^P.e,.tKw kbPL4ŴdgYI|{<{ιNKx^zj*zT}aV1n̋8o|ʤuWo?qۄ% %xO+~QKL$ӉXOl&v5aOD&ODO .wO//$|SɏrFZIgқQdAd#N3kgrLrfsrsqs,9v q28 N9͹¹%fR2jKS;CS2*J)%UAP)*u^P*wh=֧zmD7;hKږ>B>t0FIt&K%&~LMOJjsuj^T{ڻkvזh˵Ss+۴{OhӾ}GSϵ~OMwuLיc\gH'HGt2tuJtut:utN\Թs_gX+t~a&'=a'̟dŠ 'l( swu 6j9biGBƟL3uww6)rX9m#;qg4''g'}6{8gp崝^~ܽ]ܽB9x;M0YM=/dRw?gt:?m1L35ODΞޢg@OOݑr.vsvp9._TΎcǍ~"oDZ#~b֏]ǎ[D,^]upqw_l``d>,YwKC#͇K\EZ{2^l(be6&ͫG D#q㼗,e;_`qK=%36)<;͹o?үWTWG,`L`![ fG6J0a/l0,` ,fl0v0ã6rְ61+`Pn`m`Ӏ:p>`'8* o=xHop5)hMv(36pA }xx ,H0ȆDrHHH(HhHHXȀ8ȄxP=.C'M-8J n8PU0 w BC ) 4Cr:9I"gsȹ\H." Ť!\J1iB Wr-\On 7Ln!9I"w{ȽiIZҚ!mɃy'ґt"Iҕt#ɣIzޤ!}I?ҟ  2! % #RNFQd4Cƒqd<@&L"2L# 2"2#IY@E,&KR,'+J&kZ'Fl&[Vl';N&{^'AyxGׂ0waZ|  ӭaz X3Ì09|Lf.0fY0fٛa~ saN ̝ sa̽ 6<3 w| hXX‚oaX8 ``=za*,aX!,퀥h!߰,/`c$ LvI `VaX:V߆5`3X:Xo \ؠf8n20;¦0lͿÖuE`) |.쨃$쌀kv=`OeSK8 7,*`_ a4xz:XnY 6l[]vOP!}o8<#ih ߁Npjp N/Y9\v]p5Q~ 0t<w8v[ s8pr<CP8 P:Q8gfÙpζ9]8 p!\Xv8 , .o%\ z`z ܘ 7uf n~"}XpW<4>GV1<>sϾao?I YB^tw[}1?ǙMxy^?~og `~w߇L0O`T̆?d/O"  `Z oqDFJqG大/'n |,@*qs 1Fކ&ʋB7JIL݉ɓ!3zt7ۂd b7}Jy&YuY/8ogf&英 ΫMObm.V:d">DK8 |LjL3܉x_AD}|fW_-0NɏC9HѕL+#220"SyL^J«ںI4\% P L3$D tRdB5e4M9DWgImLFR즠JsQ3D{n22X9)(\4@S<%7 R6!,[*n sTӱ/ n~ڜ-L Re)6]E*yBi/kT+jcI%##sLw2  iD+ezgw>BXِTd"wR=f1ceal܁8֬2%'5$!Oe5=BBnIH WxPIKf>X*=<o8RD-%[U3Lu?jM!U,pڐ&G7inyywYRh2J26bޣؼpKdbv^Z*)C?ҪYN&,bт;qnX9Kr&6Sñhh}Xq)Y\_܃QwHgWOy%%nSEc 2<ì0__f)|ڿ| rr 96z!b$#K!a꼭} ,PjJ-ZCR1a}=pT<-eV(! xrtWzb+VVK% 1f곙xW,}˼+ c>`6sr)o`m߅5),'8x_xqn+T]bm%nP*3)e"%K~DP>9Bkәw.Fv Z(::\'F'-s}1{YhX+'F!$ 23 =f6()Yɩ($8iS dR@rA J0YxgWc9Q"WsBrId**йe^~v~jk*K;\L)"eYh|IUb.VBQ >Rɂ[e\M i/qx1A(IS6֙ 2aiy!bHs۾va.tHzӭ^HYna>ǃ r^"^5ܤ8d]i~VRBtcpԍ@#"vJWcxrE/;Y|m/ZY S1VAna}c/>gZ4lcsB˛ՋzC=N-@;lSH?_@ۡ}*r{GVe>kt -hKu m [;=q 藆 .m@_z=|![Ȕy"Yr{Ub1:G8x{ORD;IjR$C'~GU/켲2cX%Lb͙n!Ni,-enT&u?U}Am`>#0yTh'D>5AZ9q񅺣[6Ϊ'>cu Ӽ3ʺ֒|w7W^2eQY}||Q+iGUQxIJDKx"OKi;Ts%U> :U~<:e>5KZ)DeFzԌBˣk5iU4ݦUAZf22 ?ۚeIMւ:cV"5 ؔTHcR",Ϙ.^8i,L":Ȃx!UW TtO+VYUIT-1#ns2TS)YI 2)Ϊ.ZAmN(iR]UYA,'&ꆠbwSl[?V+ѶIg~Ud]FuTo[C-8#0S''͗U-^~yBqH$&wX0 FA.c˔}쿽󸠵 ;ק0t}~Y74Uef%f$ eB^b:jA튺jED5ezo$f_5Yp.4RU (r˵CN.?2fE#=>KYٽkyͅw~5tGlD 9&g oY][< jTc9B&ϓE?vs9?"B}}? |Wrc>EC,h!ҕ,\>V%M _ˋ l㈱ȢFTEco1)*`KCKTJ' 5|;?ύ%$DF'&!$OHcPf``U{lw|l+-,O{kT2dsoV{:'s W-f^:Y")s:gg2Cx]QtfQ;}62gaMW U)4 nsTxQؕȋȂdRebu-f1T;[xusgL'Dc{ ;FOulF=q5I&g<;1%F-wg,hJ)՚!%ǤDDGth;z53jShM04'Y~g ݐf+ ,ISx+%.9>9>%^?SbȘpX<O1fާWSuʅޚL}Ej~2[e*2^[bNH,('ꩌdp=^QctjDI|QaU.-x*G*Y4ZC|l{CȦܧ/>Eu'j61,\7eY ^MY:YZUfT|t;'SBz;H dVD MlMu[u:fkTctv4 ibOo9"QiNF_k+{)Ql!0zq~\vB6G%-R,!S^zOeʔ&3/mb"]Rcґ~J*hg[:SҊY0J־鼜$ϖM/da汬#yjx6U߰/qo7QOBot3+|,١nļ$B>^̬Q3uvTR#e~IW7J156]8qWO~3 srSP%Gxd2?71ڄ( <1Fz؁)-j\憍g;TZӻM]Teɯ;iL-JEhl댒ڟ$6xpދw_\y-M_((+\S~CYU[P` TmBv X~1!ab=QgH#CyI,YT-*; cLȣK J+>o}LKIA1($:vP|p19Jt~^Jzӳ2+VȤ1%Hd1姠%KsP(QQU؄R7b&I Q] E>]c,d\)7*jO4;H|ÊP>>Baskc%9^eHflNߥ#,6C^p2?#Ra-=)e =+A8Z@y>> {I<Y; i50pl?TV!{g#e烂b|"k=FYYdszyYI5ƕ &zӘ&#Eqc;SR! bX"emTsj%^:=՘}9Y'^~~5u5u^S%5w?hNQ[X/Cmym'ywlsrεE6zֶv wF`Kp-&˶mYagW|5MEz>WS-VVƮ^/s1!!R'f6sHAEhͰdQp::*J"ϫ[Ԩ1P\c#n w^peTnZNjjrQFa*JBѨHi,A*)4Ӫ *{k[>͗#/tj2\(+)kB MUF79gzT8~)Z?_?=Wq3:Y{S,:g+ZNVwӣSr^孨kmtp;lb/ش5Y6}Б--iݗ_zzU5tm=sfLȻ34ᅥcrbfd[QC_u1fNWx!Ue78$t3(0!UΡRqQ8$ T1p`">(+@W8We+#X7)WU=hVU=UQ4a>ë??r]!1-k:O]nrC! WMa_Uf =9zЭ퐛G9=#))]P[DZ' ]מu>fl a!/ba衝h}ɹ>@l㒀P"b3O1uXzod1zHZG3,W "u^BJRezMQMMúЍ%[C G)t*CT$*Mߒvj9_%+ﰧʘe/T&ᚇη& g,<-ضwӔ{ (wxI2ԯȤ Vv :*ϠXhw]p8^I랸WrrʧO-x |qz{."rO%nYOgUt,h#FewV-[yQsj=%QՅ ͷΨ |eqNǯ󹵣~jlr"է90>5d)Zk+Q$xFFGGGE'ŲbhDU:I=Q Jd6CAvOzU֡T[ԋJz/swG%U}ؘsB%yͨ55.B"Ǝu充1Bax~lʤ{kbfo)mm=KkJkk*ԽT<*3/V>GC󘫣{q#>^b\3<sY5O8NmeKͧMcZ]K^-_y[-9k,4#gu/?0(01hV̋נQ/_#?4+E ŵQ7o {bz"1]| /2uYХ:TGaM՛n¶ YLo Ϛ9}V80p6b3gܭateē;vHsܐaoZ'2oi۷x#ǘ؄ev02fK`^ !Ze¯NP'8%Jvz %ɢVau}SqyXC?[U^JMNhB/2C$ bs3!yb>cS3ۣ:r9ͦ\:XQ%( f[oYs[U=%=tKk=h߽)Q&$IrPw~tHEeI$=>/6OʖTF|idIHQ "WVJs3NQizʌTAI 0/00<:NB9uCK!AiȇKG3C-#-ѵreXNCQpG懕d) 5 iiYiMyHXv6&|~|rLZTFdWwuB$(j̇Uq]n,cSSROܾ6JmY;ՇY{|7=jX>dZZ8 a-Az,(V$"VԒ_]Tjn~#+rRU HYSk2|qE(\X=ŕ4si?vN%VE2’&y6^! '6>#ڊEbDG]wūY13 ـ*kx0NeĿa l,R=2EK4VP%KѳW`quԥwj +wW_( K;׬k*:ޤVVTpa35UPxu 6yu-5ӟ7;R$qK$˔"EzfZf8W8^13+YBPtbL|85W_ԩ/#{qSx%,͉/fkU >!nBskY@ـƅ%~YzB"̕E(㠗.W{ʇ՗كIxß%~MxfO 9|/nx׆F5+;Cy.-((CbG$qdZr0SVR@y$C,(>柸=Iz083$-%!iunvJV]Qژ4;˳bs2`eZpt jc%_T^R :73zbc() -()hu=p8Wl! AOYsx ҈-q1:9C9#3RSS39)(.ž }Cm u7 ?);2Ogμ3Hxk{?0*;s*nWot,3܈y9ժx>PՇ˳y(򨯻O#:ԈJ7iZZʼ;1O/m|JɭmiVv~^S̼yƉ԰ǡpl]7>\6C&ٞmuuY- ѱT>3 )L"pqh(\UoSbjk W , "H ?C )%ii~/\9)_L(1 J/ ,(--ώ-V *ЉDE\DU¢€h!TkjM1 utvD:ؗg,/)% y0ݩu;|ݟ]q~!jP~gcͱjYH|||l@g N+W7`laѪ듭y pD"ؼa`;\xɾ9ݽHMHl 3xxZ{ĵ. f~:k[<;ٹ.{cxj e]@b؆#*zc׹?@sתzQXV92@qsKtc%rpf. K1]{/w75nآԍ*3˘~TӃSHF3\Z_Y|jPPsؚ1g/|Q r!!f3[\^kl3? ZȖ4ş ٖY#+|cdK=ף4x>~ZGյVAf 8u= 7ͫ<,.nx/6?鳪m8b!Jn]:ކΆ˻8^cfVry͟ď1(&X1¯t~==d]a>>#U/]ud[ (!*EزDZM)92K e!HWs`TcУ;gg.+m֔oAK!dFvЊj[œTӿiU_7`rBE$ D11L¨Xg*é~9HJϴ?>M<5\+Z'VePxן!=`޶A!SJ*M;B ^KT. r4gZt/T LT&3G1~|2 C#$Etq^@_z kwWW6SW(C(?N]`-F%ÎlwqŇ7'>e|ь#:"!F)[@;$_VTKF))Ĵ4J喖I}^ѰhZYXDdpZQGmu~m #7m3hFk⣣%QaW(nTJUI"G _:IZK6A.Ox&IE_p(f!:9"nd>_/hڎkeWio^ҁ ­]܇Q_}+|d߆qCy[>cɼ`*En!/]e{}x*/K/ C$GZ,!X`ޞ#ʾ&!9- xPخ{,!~Ҫ2PxYW$puy"  59$>6ɦ 6-\f!uvZ_QIRYR{u|WO=lB,ULǻJ# WD$A)F > `8qȅGE"bzk{'S{+y{.ҺX[Uj)J;aB5:L[GY~Lsq:K 쬈ej2zb PC֜*ajqg1vq))I9i52csmߞR]?/'XcV3 YGb7 ъIXh|Ifu 8} rrbs[y2c6Z `fLm7hrSoI\ݜFp)BZ>Lukr(5E^u>g1f.b-9F<#Z̋ŝP_Wiu$Ii~~SW]]9_JA"XlQG'GѸ'CP a^|+j5 t^\`Nτ*)^TŠ&Q]G(ѐ*:# >0i@.qõPl 34>@pYIUk5…^qהMuO4-ܣ?fnoefce%?i ߰F#jHIU"vs+=P:wi`" [(PĄn4;$'f~({l8srV?3rg(y~^I>IATob+w{n a"( 'h,COKq\L(?[tKLK9n` TfO{v ,X\;t{r/\G79ɚ7Zыt~I8TL{ K}oݯ{ҳf:Il)Luܺ~^w`vTudq5&+\53Sgj`axJ dgk,q- rxit:B2T!=PKW}/ʰg>G< &?>[㹷őt:G^ȑ0t".ӧe3Qi7݆=IO76n'G:M~^c*=z],V^}7_EأSYx!/G]Tt\#dvWDŽ̩'ҏjhݦz3k֘G~t៯:2Fdڵ|ټz/s=DY\ڟò7\\U듗5+߾BA_Xluz!)n Ȝx;Yǭ݅'8̹ޭf{LX5;WF{/`.o fg _¸7E_bث^I 0Dm#_/2drS 1 I[D1;,h%ZECmF^rr}Lt+ ?T j@ jH99G`֯P9yY#nt,D/?/X4C ]Pň JIymR+x!bvԊ3jş7<OwQ7uQGtQ?EtU8;\;^|_E8)Cozg^ϰg8g44Ę|Uhnf$n;p y0Xwn)@`-R$GL3A95τNyyV3A5=Ш֤/ ^1!ۏl?2{Ӌ}IwC8S'*b]*&b 6;ڄ|Czbbe }[<ѣWk=7apF'& #p9{xԥ֐y5>B 1>qCfC\Cj0A$*H;E,g)OxFc8H$`Z7^`y(%"2`_B{+WƱuzquΖV殆h)Z&611+r.C'QiN쥩\ɏtŕߩԤ ~9ZL68lp%3wj$\SS÷!/k?]я{c"=DOz&෮ڥҀ?x|mn9`-Wݵ lLMȴ*s٢2IZt|+ =H:=Ic?zTyEL$Jl[t@o;H}S '$+4xIJz!Hk\Tޥ!"؃/Rm&Jw|5 tH%^Lln"Z*V]W+_FFpUp ]:%:~ϖ&@3t7*4Iu`q.z@+AuB;0xhX%z<=R2O`WeMcOVSOH/% ~K*T7t#,#+@ǍO:1?4 \˪)vkujruA&A+ы6ZK\P gwC*7Mz0h:esLPW,B7[ o2(.Ey?Y(-]op,4 ȞxQw+P~->xr_ut[wwTh!y/wvuE<97F pL[RRq˕v,v˿,QJF|m]bGXS}O_6uLLhkrN}|0jo聙=1n HlB {' XÉ<=3#˿cg?96oVrt@=Ε ˁlCad>x|UbDw֚lX׻enclN9.9akB|(2"88D>Cb<0(Qsl^ #nbKA'k #){='cq ?Јsb>U -調`:g=FMam`r=.eZ~x^h;7 U 1IǑZXRۋ PPHN;QETTE#ntvG; =DWU'PKj_ RkHnɫ [RL>oN C}dt_y9X}z Z(v㔴m!>1]e,@MSlʂn& MRʔPheϭU{@gp T/I.xXEgj3)?~L^x`1Չ.4? .qPz{ RB,َ9}wg%z0I qw4,$#fi$t$4q _`4lj_qLsF k l;U"j`a?'B1_[%;iZ8"j`Ν=,NBuk"Oceye]$l俁O8iR&I-kJF DB+XM]hvcsᐻ*ϫ"LBID:XX;$:!!G)@I_TzJpgb~@x5}}+Pi3U OWyPĖ.e#})R]1A堚5 U\5 (I _-JHhMBJg'%f vd{imjR BHcIS˫a(a&|r|J U˞&Z Q8XOs- u~?J̰wWv>Q6s\tt\D떬FP8d3AAbB']EF\ɏH1q6\잜㛎E(*w;@g*b*MPxuM@MiÐ?yiCBjUZ&Xvic)Hb4aT$gVeiy{%fScc3ŦG$|.zG S|ICW. P;7tSݲ2~^R[ =ؤYB)RJx8Zc ip`NMiBbPHĻEkX盏J51 8h5}Ǜ"-V9:{2l?n]#lqVxdhByRb[k[*]Xkh[QIw"t,ŌP mNP8l'^Alҙװ2K!,=,X¸{/k؅g,Ox zxHNWTmVAV=)A%TSRlT l6o&{Ygas*)# 'N.3!(!YھGrg{j@YÑb*.*Ez%?.MvHO &o- *DZbd$<FQˊcuWXj[9fT,G)k_XS 7`I7^OSk;I:MjL,˪j ɘx!E4WSĪ$ ⛝dn*^ |yḃi09!8u{r3Q)[?ͭHӭfӗ؋jz_>z;o;m?_w8l # 1^uϮEuW6lsLP0 Nw&9`TS~5JyS&ۿlՔq@~d fkKmWWPˤ }*a?&o2RgӑP[31Pо:8F͜-ڳ=eе_"Ȧd ko-e]i簐y>')c ʪ=-n"}>~ ?3OMU#0 gv]6Vr-ªJv\& 1l^Ix>rp9yb5u .n XY]"ȕ0c?'u P>0Upv{Y[|;>X{q|ږànn6 nI*/M 2ų.DKя Lopy[eyexɘf!iklW{{Z+PaS'\fՎH~ k>7lM#x.!kyKNBB+R#qw `ک>uMF:kuĴHVa]q'x*1*. D.ZQ2lv q˱<":jflUt$-HKm ]ُ'jƷ{h_ hfVoֶV+8숤v!o-^(nZq} D-׃;S6 ӅJEeW+*RnXjٖӵ(r6TS̈iOC&FvW!3daCV}>4*5]S^C*DqIqI1-`(M sBn+S /QxHw]Te_ڹe2}eT'дY\aGޏj%WQ g+TEu!xہ'\F'P^v,VݾOoR2=Yj|HnZn5ggg݃7% F¦M݉߸-qVS-WZnBՒ yJ,> uG𝄆Pn |HyMrq+`ƷtN &}-0z=C8-RID,b[?݄ -1ƅ\s?_wGV;Q4"qKbr~#SxjOu\31m&N][|7"_-.y?*SPDkݞVz:i/O9hys@~k7qu5LoiJ!]w\W GeiKnT5&&>%IN@oV331"-kÍm6F}L!CY'/6V7ZȃS[0SPH0gWeu'ȇ[ʳ~s͊SB筇ewҥ? tމ9d[-NH $5۳E+ruux2P9,e//wwůi?\vєI^Wjx e2TW{W̓26k[~KӛfZ҄4dHO~N`Q<hԤϑ۸@aChKmjQXU#$/,&B;+[ MwYg6b V X [xw>yA] KaωނXB\ \J=#'GNA˙Ӳ3RS>0qy(sFf/SxIb,:,Om'ϰBiQRdZf-7 [yQ3ZeﲯB{3Π hOA.p <ƙAsM Y5#;-Jc7(FE>jZ%Ll)dlwo;I>8\SC!C ӥʕǼtN' ^sЧ'}K JBb)m"26 nB er2ca/i_;.M4$Xkݕ8Weq ~oxgszXZl]D9Au彛IFaЊ4f;Nt 1#BkF:ޣlW_d&3iwy4H?$[e', MΉQ t, A7b'\c󳶄iX9[#saÎb`pF(Rժ  -ni MmXs8GpuoOVcw( Ea"W{;xx$&>0a≼$U܈"!ܑ[E#[&\-1) WIת n~`btm! kSPy@s1ytO U1t{tZ{[]y؜CʆI:3UE.{"^Kq8s]J(لĠ %G(dw+tC޴ `n!tp-ZS6<+Rn]ql22a6x 5;P@ yH٨۩<ϳ0~R\0T:sWQ!jj)O2*'%OǠ0p|^ _<(l诀.7RРBQL4J/'\{q:r|0DL+G.XN'|"e4)(fKBN!f"Bt>A"AMsHOOң5cXks0+4^EIe~"Rd: ^ _ #pYz:| _w'"7h.Yw}]Q|)EQ16`jLLم-ZGoذx@iEa MrUQG92Q|.vuXSX .t{&Ւ(ِtROZO^ {kI rb}I!kM`,k ꪅ{q*F X񫲱v@abO^ܸ^ъe`W|k-<"V|~b>#1gu+砹̲; RSsm}}}} Dohx^fHQc{ MVE/Ӊ^l%&=!lGjK4DO!6)왢Sҧzݰ QVC^vi&~^?Aoj,YvUvVy<Σev*rjɱ*5rA X\#LxsXVWj'JcSңwj$Ɩ1 3:;;OJM{}zC!P΂:#ƥpF(X@#GX#=Ư;!ڋf(U*+)l%*63+%9+6RxΗP.,Ql [N^A@cAz¿guʘ1$]@]xɛ6#);z uW*[9U`$j'jOn ܇8*O-~\2ݿ$CiH_MAL5%8bڙZ074hϏGLO v} ѹ{2B#<#c]#}*̳O45\+y<-@['tS^ׅĺZ8[7bK\zflrjh{Xd(Oώ)*r['y ^?7:wsmժt~1%϶FtUqv%*W 7^$/-Q0Hw>~I{< z2/;bG5sIu,sxv*4 N8nup+[+T˽i)QI(qBDFDFH8)2^;v}gbRS WϝzzUƁc%fU&yO2OĔcn$/pn`R'E-ۙ eƋwn Bf7$/'094u gk6Q˙ omEZ)N*y{!v/6!/XHŗ|=iy^cHYd/7G;WFOh'[_gdxH,6%5>;=Y&t4]2Co"_yL /~$6Y3V`3~JԫW"T6ZN#;/31uçr-Fe z!{x=3t^8N^#:vuc7َ]Jw@G'D0mYH5ŒRN0M#r,vn.=$ә:Yh>b+[x8*KNPGV7f:+W;uk FX9z"5v3s j9($0PݡC5;?jGQYEk\̵AGg; HKG\I𡢝(okVo8.kh0j_loQ6jȧ. Q0l}aOfČHZ:W%]~~1惧9u*T$Gܽ5;-aVs԰iһ;eNpr07]P;$, lV*S<70`4Lß# %2 LNtY _V 9V(vD3rO2IiX pN)cEܑfh`+IhV,U,>C9Y3>)F=<(c>\ipJ3 ,T^Ҭ IG6yvDœ?H9"-͒ϫ86;)\ ~G>C;2te\an=-w׮ޱgڰJP_j3돐[j^\ 7x)ڲoچ!^ Ы=q4ʩ"T<>e H8D M)}cj2~S?xӻ@ȯu Pk4~LaS4*|Tv|VraZNe(r` 4T+ѦLyB`F[RYK^뤾d}g%)՗q}IphP$&j8Py4iYG)2ǴE /8[4ڪ(yS5 J=bB*R>_U{K M[Bɶ aL#"7g5!yBٖr|zRZw5#X)<̅#jU}b Drg}~ Դ[ER׽oW*ZYisr+p!VS/1 EF` 5E cIg>v+nde..=堨t|G?uÁ\<]td4,ًڽ(G / bӮ^IzۿyHbG/U8Iz0VJ>BM5vf-љN*8HBonZ)Fe1A6qWA#)٩wvBrU`8%4(w$.I`(LF0{)Ԅ[&@OW`Sr3v ^ߛ/t`zBQ@whOnq='NB88VhaZk8.5/CV.vٝǕ\=wTi4g>VIHm&xejUN)錪Ա::j -TU߿ע:>W`goR?>r}^,G8N]:>>sXoT$g]֪8}d\=O!OqbĤ t;Ѳ'h|;dF>3Qo+eM˻U2Y*+XNki! p )Tȶ;k`YprUwrD8L]RRow/'(% =}qsF - f-n&lJ[`dՙF[[t&8+; hr\wS0pxkW?Nn RԬnYc=K(}AĨ KűĤL76t{`2%FĦ_FВ3D:{C8o-Vr4SATފ\f|ImeVeJ;0הnWF/b5XBl,g c Ig@DlAZ(>2 .tq@~fM<]щF'2h04"t4uy|e!V ղJ= BWFy€rʴvzUjt>ж+Rv+fsGZB+ *xbpo*>(>ZyqV[h!&'-+mY{Q]ڦL| 4N>ԔzYn& &eP8j) j2PgJ"oF. 4n߮[s:.et/0|!a\sZh.SEk"vH43|JZ:ܕh%Zڂog KwEǑzh[`A`U~SJ`N^yU`7A~^.SlX8eDnނ Yc< >zEtohbo6F =a \E+@)l QרiY s MGK ?sfLJDkw9|3C?UPltGkIO=Բр >jG?ҸcyTt.ajQrϗ @ȋĀ^X~8N\}. \ mTEj0 Ļ5{UAà{>JTU&tH%2 t wZC?bjh0R{ݢcϦ_~ vϩtur9ߢhn ^a> o·sa#{=@ ,/r E|!`|GC4pJ$= DA:|Ӭ$=I'&5R*v5^깺ՙ ~RGճ!s]EDS-VAKgɤO~kle2aIb%DzA'(壯W?**Ffqz?W'Y.ގ|a]ff2B;Y!KKL%!˖Ck{P=;؆SpwyZAWi7/Aos_,u ߯%%k,{9ϻ&MMmJccS+I0p ]Q ,ѱ`A?!;bPGM]"KQ4hLjFe o;y"Ai ˲Yk`TZ&?5_K!; H$^"cim-j[Fd -%{fw`>ݩ#|[BLSUQ|(N3,!ID7aAL# "`j'cR}8\0s~aa›`S\+n¦c¦ׅ#eIß*۝ ^CZ*yczB|LBiȶ!%d]lt؝싂S0Y"R: CaA ֐-y6>zSk{F̮w[kI$E~g(ZJ)Z_:ƠKS%Z*^-~+4>?{(=ϵzml)i ZGBZZ;W,nP;IyGB?"Ne&o|zAU<6Л:or eA] / AΟرj/Iqk%yz*}UEOkE_TP^fNk/R=hIik":HMK[4\xv"jN"vƇJF Kt]ߣpݿwI)9J/ M5Cr?$->-B([q0jo聙=1\nE2&ɰD|\O#"=J+<;1qh~ 7\(!Y1I. ?z/"go,k!JZvjkcdR)y9?A&ݕ+:EʾYAr aWdDhIUBnwA`Sͮ3͟#ϣTy/ xޓ'3[6e,#؍z.cGKfDSͨӶc*1iңU˞GU[+E'iL9AzۺD<=UHtC.5ΨT:K?uϮՋ4>QK:./>+r`wIYU8ٔ{Kp81>*rҚra ~،KTp?"X%, wKﱕ+0%CX]vU3^7p}v~C6|h$Yq; ɱg{.weAv? #ڻ;]Wژ/NETudn]us_ endstream endobj 11 0 obj 33920 endobj 12 0 obj <> endobj 13 0 obj <> endobj 10 0 obj <> endobj 14 0 obj <> endobj 2 0 obj <>endobj xref 0 15 0000000000 65535 f 0000001272 00000 n 0000036794 00000 n 0000001213 00000 n 0000001320 00000 n 0000001062 00000 n 0000000015 00000 n 0000001043 00000 n 0000001603 00000 n 0000001389 00000 n 0000035692 00000 n 0000035608 00000 n 0000035630 00000 n 0000035660 00000 n 0000036736 00000 n trailer << /Size 15 /Root 1 0 R /Info 2 0 R >> startxref 36844 %%EOF Csdp-6.2.0/doc/csdpuser.tex0000644000175200017520000011262313135474566014220 0ustar coincoin\documentclass{article} \usepackage[pdftex]{graphicx} \bibliographystyle{plain} \begin{document} \title{CSDP 6.2.0 User's Guide} \date{July 24, 2017} \author{Brian Borchers} \maketitle \section*{Introduction} CSDP is a software package for solving semidefinite programming problems. The algorithm is a predictor--corrector version of the primal--dual barrier method of Helmberg, Rendl, Vanderbei, and Wolkowicz \cite{HelmbergC:Anims}. A more detailed, but now somewhat outdated description of the algorithms in CSDP can be found in \cite{BorchersB:CSDCls}. CSDP is written in C for efficiency and portability. On systems with multiple processors and shared memory, CSDP can run in parallel. CSDP uses OpenMP directives in the C source code to tell the compiler how to parallelize various loops. The parallel implementation is described in \cite{borchers2007implementation}. The code is designed to make use of highly optimized linear algebra routines from the LAPACK and BLAS libraries. CSDP also has a number of features that make it flexible. CSDP can work with general symmetric matrices or with matrices that have defined block diagonal structure. CSDP is designed to handle constraint matrices with general sparse structure. The code takes advantage of this structure in efficiently constructing the system of equations that is solved at each iteration of the algorithm. In addition to its default termination criteria, CSDP includes a feature that allows the user to terminate the solution process after any iteration. For example, this feature has been used within a branch and bound code for maximum independent set problems to terminate the bounding calculations as soon as a bound has been obtained that is good enough to fathom the current note. The library also contains routines for writing SDP problems and solutions to files and reading problems and solutions from files. A stand alone solver program is included for solving SDP problems that have been written in the SDPA sparse format \cite{SDPA}. An interface to MATLAB and the open source MATLAB clone Octave is also provided. This interface can be used to solve problems that are in the format used by the SeDuMi \cite{SturmJF:UsiS1M}. This document describes how to use the stand alone solver, MATLAB and Octave interface, and library routines. For detailed instructions on how to compile and install CSDP see the INSTALL file in the main directory. \clearpage \section*{The SDP Problem} CSDP solves semidefinite programming problems of the form \begin{equation} \begin{array}{rrcl} \max & \mbox{tr}\; (CX) & & \\ & A(X) & = & a \\ & X & \succeq & 0 \\ \end{array} \end{equation} where \begin{equation} A(X)=\left[ \begin{array}{c} \mbox{tr} \; (A_{1} X) \\ \mbox{tr} \; (A_{2} X) \\ \ldots \\ \mbox{tr} \; (A_{m} X) \\ \end{array} \right]. \end{equation} Here $X \succeq 0$ means that $X$ is positive semidefinite. All of the matrices $A_{i}$, $X$, and $C$ are assumed to be real and symmetric. The dual of this SDP is \begin{equation} \begin{array}{rrcl} \min & a^{T}y & & \\ & A^{T}(y)-C & = & Z \\ & Z & \succeq & 0 \\ \end{array} \end{equation} where \begin{equation} A^{T}(y)=\sum_{i=1}^{m} y_{i}A_{i}. \end{equation} Other semidefinite programming packages use slight variations on this primal--dual pair. For example, the primal--dual pair used in SDPA interchanges the primal and dual problems. Users of CSDP can specify their own termination criteria. However, the default criteria are that \begin{equation} \begin{array}{rcl} \frac{\mbox{tr}(XZ)}{1+ | a^{T}y| + | \mbox{tr}(CX)|} & < & 1.0 \times 10^{-8} \\ \frac{\| A(x)- a\|_{2}}{1 + \| a \|_{2}} & < & 1.0 \times 10^{-8} \\ \frac{\| A^{T}(y) -C -Z \|_{F}}{1 + \|C\|_{F}} & < & 1.0 \times 10^{-8} \\ X,Z & \succeq & 0. \\ \end{array} \end{equation} Note that for feasible primal and dual solutions, $a^Ty-\mbox{tr}(CX)=\mbox{tr}(XZ)$. Thus the first of these criteria insures that the relative duality gap is small. In practice, there are sometimes solutions which satisfy our primal and dual feasibility tolerances but have duality gaps which are not close to $\mbox{tr}(XZ)$. In some cases, the duality gap may even become negative. Because of this ambiguity, we use the $\mbox{tr}(XZ)$ gap instead of the difference between the objective functions. An option in the param.csdp file allows CSDP to use the difference of the primal objective functions instead of the $\mbox{tr}(XZ)$ gap. The matrices $X$ and $Z$ are considered to be positive definite when their Cholesky factorizations can be computed. In practice, this is somewhat more conservative than simply requiring all eigenvalues to be nonnegative. The Seventh DIMACS Implementation Challenge used a slightly different set of error measures \cite{MittelmannHD:AnibS}. For convenience in benchmarking, CSDP includes these DIMACS error measures in its output. To test for primal infeasibility, CSDP checks the inequality \begin{equation} \frac{-a^{T}y}{\| A^{T}(y)-Z \|_{F}} > 1.0 \times 10^8. \end{equation} If CSDP detects that a problem is primal infeasible, then it will announce this in its output and return a dual solution with $a^{T}y=-1$, and $\| A^{T}(y)-Z \|$ very small. This acts as a certificate of primal infeasibility. Similarly, CSDP tests for dual infeasibility by checking \begin{equation} \frac{\mbox{tr}(CX)}{\| A(X) \|_{2}} > 1.0 \times 10^8. \end{equation} If CSDP detects that a problem is dual infeasible, it announces this in its output and returns a primal solution with $\mbox{tr}(CX)=1$, and $\| A(X)\|$ small. This acts as a certificate of the dual infeasibility. The tolerances for primal and dual feasibility and the relative duality gap can be changed by editing CSDP's parameter file. See the following section on using the stand alone solver for a description of this parameter file. \section*{Using the stand alone solver} CSDP includes a program which can be used to solve SDP's that have been written in the SDPA sparse format. Usage is \begin{verbatim} csdp [] [] \end{verbatim} where {\tt } is the name of a file containing the SDP problem in SDPA sparse format, {\tt final solution} is the optional name of a file in which to save the final solution, and {\tt initial solution} is the optional name of a file from which to take the initial solution. The following example shows how CSDP would be used to solve a test problem. \begin{verbatim} >csdp theta1.dat-s CSDP 6.2.0 Iter: 0 Ap: 0.00e+00 Pobj: 1.4644661e+04 Ad: 0.00e+00 Dobj: 0.0000000e+00 Iter: 1 Ap: 9.31e-01 Pobj: 5.7513865e+03 Ad: 1.00e+00 Dobj: 8.0172003e+01 Iter: 2 Ap: 9.21e-01 Pobj: 2.3227402e+02 Ad: 1.00e+00 Dobj: 8.2749235e+01 Iter: 3 Ap: 9.30e-01 Pobj: 1.0521019e+01 Ad: 1.00e+00 Dobj: 8.4447722e+01 Iter: 4 Ap: 1.00e+00 Pobj: 2.5047625e+00 Ad: 1.00e+00 Dobj: 7.2126480e+01 Iter: 5 Ap: 1.00e+00 Pobj: 7.5846337e+00 Ad: 1.00e+00 Dobj: 4.2853659e+01 Iter: 6 Ap: 1.00e+00 Pobj: 1.5893126e+01 Ad: 1.00e+00 Dobj: 3.0778169e+01 Iter: 7 Ap: 1.00e+00 Pobj: 1.9887401e+01 Ad: 1.00e+00 Dobj: 2.4588662e+01 Iter: 8 Ap: 1.00e+00 Pobj: 2.1623330e+01 Ad: 1.00e+00 Dobj: 2.3465172e+01 Iter: 9 Ap: 1.00e+00 Pobj: 2.2611983e+01 Ad: 1.00e+00 Dobj: 2.3097049e+01 Iter: 10 Ap: 1.00e+00 Pobj: 2.2939498e+01 Ad: 1.00e+00 Dobj: 2.3010908e+01 Iter: 11 Ap: 1.00e+00 Pobj: 2.2996259e+01 Ad: 1.00e+00 Dobj: 2.3000637e+01 Iter: 12 Ap: 1.00e+00 Pobj: 2.2999835e+01 Ad: 1.00e+00 Dobj: 2.3000020e+01 Iter: 13 Ap: 1.00e+00 Pobj: 2.2999993e+01 Ad: 1.00e+00 Dobj: 2.2999999e+01 Iter: 14 Ap: 1.00e+00 Pobj: 2.3000000e+01 Ad: 1.00e+00 Dobj: 2.3000000e+01 Success: SDP solved Primal objective value: 2.3000000e+01 Dual objective value: 2.3000000e+01 Relative primal infeasibility: 5.55e-17 Relative dual infeasibility: 3.93e-09 Real Relative Gap: 7.21e-09 XZ Relative Gap: 7.82e-09 DIMACS error measures: 5.55e-17 0.00e+00 1.00e-07 0.00e+00 7.21e-09 7.82e-09 Elements time: 0.001091 Factor time: 0.000620 Other time: 0.016636 Total time: 0.018348 \end{verbatim} One line of output appears for each iteration of the algorithm, giving the iteration number, primal step size (Ap), primal objective value (Pobj), dual step size (Ad), and dual objective value (Dobj). The last eight lines of output show the primal and dual optimal objective values, the XZ duality gap, the actual duality gap, the relative primal and dual infeasibility in the optimal solution. The last four lines give the time in seconds used by various steps in the algorithm. The first line, ``Elements'' shows the time spent in constructing the Schur complement matrix. The second line, ``Factor'' shows the time spent in factoring the Schur complement matrix. The third line, ``Other'' shows the time spent in all other operations. The fourth line gives the total time used in solving the problem. Note that the times given here are ``wall clock'' times, not CPU time. On a system that is running other programs, the wall clock time may be considerably larger than the CPU time. On multiprocessor systems, the wall clock time will not include all of the CPU time used by the different processors. The reported time will typically vary on repeated runs of CSDP, particularly for small problems like the one solved here. CSDP searches for a file named ``param.csdp'' in the current directory. If no such file exists, then default values for all of CSDP's parameters are used. If there is a parameter file, then CSDP reads the parameter values from this file. A sample file containing the default parameter values is given below. \begin{verbatim} axtol=1.0e-8 atytol=1.0e-8 objtol=1.0e-8 pinftol=1.0e8 dinftol=1.0e8 maxiter=100 minstepfrac=0.90 maxstepfrac=0.97 minstepp=1.0e-8 minstepd=1.0e-8 usexzgap=1 tweakgap=0 affine=0 printlevel=1 perturbobj=1 fastmode=0 \end{verbatim} The first three parameters, {\bf axtol}, {\bf atytol}, and {\bf objtol} are the tolerances for primal feasibility, dual feasibility, and relative duality gap. The parameters {\bf pinftol} and {\bf dinftol} are tolerances used in determining primal and dual infeasibility. The {\bf maxiter} parameter is used to limit the total number of iterations that CSDP may use. The {\bf minstepfrac} and {\bf maxstepfrac} parameters determine how close to the edge of the feasible region CSDP will step. If the primal or dual step is shorter than {\bf minstepp} or {\bf minstepd}, then CSDP declares a line search failure. If parameter {\bf usexzgap} is 0, then CSDP will use the objective function duality gap instead of the $\mbox{tr}(XZ)$ gap. If {\bf tweakgap} is set to 1, and usexzgap is set to 0, then CSDP will attempt to ``fix'' negative duality gaps. If parameter {\bf affine} is set to 1, then CSDP will take only primal--dual affine steps and not make use of the barrier term. This can be useful for some problems that do not have feasible solutions that are strictly in the interior of the cone of semidefinite matrices. The {\bf printlevel} parameter determines how much debugging information is output. Use {\bf printlevel=0} for no output and {\bf printlevel=1} for normal output. Higher values of {\bf printlevel} will generate more debugging output. The {\bf perturbobj} parameter determines whether the objective function will be perturbed to help deal with problems that have unbounded optimal solution sets. If {\bf perturbobj} is 0, then the objective will not be perturbed. If {\bf perturbobj} is 1, then the objective function will be perturbed by a default amount. Larger values of {\bf perturbobj} (e.g. 100.0) increase the size of the perturbation. This can be helpful in solving some difficult problems. The {\bf fastmode} parameter determines whether or not CSDP will skip certain time consuming operations that slightly improve the accuracy of the solutions. If {\bf fastmode} is set to 1, then CSDP may be somewhat faster, but also somewhat less accurate. \section*{Calling CSDP from MATLAB or Octave} An interface to the stand alone solver from MATLAB or Octave is included in CSDP. This requires MATLAB 6.5 or later) or Octave 2.9.5 or later. The interface accepts problems in the format used by the MATLAB package SeDuMi 1.05. The usage is \begin{verbatim} % % [x,y,z,info]=csdp(At,b,c,K,pars,x0,y0,z0) % % Uses CSDP to solve a problem in SeDuMi format. % % Input: % At, b, c, K SDP problem in SeDuMi format. % pars CSDP parameters (optional parameter.) % x0,y0,z0 Optional starting point. % % Output: % % x, y, z solution. % info CSDP return code. % info=100 indicates a failure in the MATLAB % interface, such as inability to write to % a temporary file or read back the solution. % \end{verbatim} The following example shows the solution of a sample problem using this interface. To make the example more interesting, we've asked CSDP to find a solution with a relative duality gap smaller than 1.0e-9 instead of the usual 1.0e-8. \begin{verbatim} >> load control1.mat >> whos Name Size Bytes Class Attributes At 125x21 11376 double sparse K 1x1 192 struct ans 2x1 16 double b 21x1 168 double c 125x1 112 double sparse >> pars.objtol=1.0e-9 pars = objtol: 1.0000e-09 >> [x,y,z,info]=csdp(At,b,c,K); Transposing A to match b Number of constraints: 21 Number of SDP blocks: 2 Number of LP vars: 0 Iter: 0 Ap: 0.00e+00 Pobj: 3.6037961e+02 Ad: 0.00e+00 Dobj: 0.0000000e+00 Iter: 1 Ap: 9.56e-01 Pobj: 3.7527534e+02 Ad: 9.60e-01 Dobj: 6.4836002e+04 Iter: 2 Ap: 8.55e-01 Pobj: 4.0344779e+02 Ad: 9.67e-01 Dobj: 6.9001508e+04 Iter: 3 Ap: 8.77e-01 Pobj: 1.4924982e+02 Ad: 1.00e+00 Dobj: 6.0425319e+04 Iter: 4 Ap: 7.14e-01 Pobj: 8.2819408e+01 Ad: 1.00e+00 Dobj: 1.2926534e+04 Iter: 5 Ap: 8.23e-01 Pobj: 4.7411688e+01 Ad: 1.00e+00 Dobj: 4.9040115e+03 Iter: 6 Ap: 7.97e-01 Pobj: 2.6300212e+01 Ad: 1.00e+00 Dobj: 1.4672743e+03 Iter: 7 Ap: 7.12e-01 Pobj: 1.5215577e+01 Ad: 1.00e+00 Dobj: 4.0561826e+02 Iter: 8 Ap: 8.73e-01 Pobj: 7.5119215e+00 Ad: 1.00e+00 Dobj: 1.7418715e+02 Iter: 9 Ap: 9.87e-01 Pobj: 5.3076518e+00 Ad: 1.00e+00 Dobj: 5.2097312e+01 Iter: 10 Ap: 1.00e+00 Pobj: 7.8594672e+00 Ad: 1.00e+00 Dobj: 2.2172435e+01 Iter: 11 Ap: 8.33e-01 Pobj: 1.5671237e+01 Ad: 1.00e+00 Dobj: 2.1475840e+01 Iter: 12 Ap: 1.00e+00 Pobj: 1.7250217e+01 Ad: 1.00e+00 Dobj: 1.8082715e+01 Iter: 13 Ap: 1.00e+00 Pobj: 1.7710018e+01 Ad: 1.00e+00 Dobj: 1.7814069e+01 Iter: 14 Ap: 9.99e-01 Pobj: 1.7779600e+01 Ad: 1.00e+00 Dobj: 1.7787170e+01 Iter: 15 Ap: 1.00e+00 Pobj: 1.7783579e+01 Ad: 1.00e+00 Dobj: 1.7785175e+01 Iter: 16 Ap: 1.00e+00 Pobj: 1.7784494e+01 Ad: 1.00e+00 Dobj: 1.7784708e+01 Iter: 17 Ap: 1.00e+00 Pobj: 1.7784610e+01 Ad: 1.00e+00 Dobj: 1.7784632e+01 Iter: 18 Ap: 1.00e+00 Pobj: 1.7784626e+01 Ad: 1.00e+00 Dobj: 1.7784627e+01 Iter: 19 Ap: 9.60e-01 Pobj: 1.7784627e+01 Ad: 9.60e-01 Dobj: 1.7784627e+01 Success: SDP solved Primal objective value: 1.7784627e+01 Dual objective value: 1.7784627e+01 Relative primal infeasibility: 2.06e-09 Relative dual infeasibility: 7.31e-10 Real Relative Gap: 7.13e-10 XZ Relative Gap: 1.51e-09 DIMACS error measures: 2.06e-09 0.00e+00 1.65e-09 0.00e+00 7.13e-10 1.51e-09 Elements time: 0.027664 Factor time: 0.011323 Other time: 1.187727 Total time: 1.226715 3.416u 0.015s 0:01.43 239.1% 0+0k 7688+16io 24pf+0w >> info info = 0 \end{verbatim} \newpage The {\bf writesdpa} function can be used to write out a problem in SDPA sparse format. \begin{verbatim} % This function takes a problem in SeDuMi MATLAB format and writes it out % in SDPA sparse format. % % Usage: % % ret=writesdpa(fname,A,b,c,K,pars) % % fname Name of SDPA file, in quotes % A,b,c,K Problem in SeDuMi form % pars Optional parameters. % pars.printlevel=0 No printed output % pars.printlevel=1 (default) Some printed output. % % ret ret=0 on success, ret=1 on failure. % \end{verbatim} Problems in the SeDuMi format may involve ``free'' variables. A free variable can be converted into the difference of two non--negative variables using the {\bf convertf} function. \begin{verbatim} % % [A,b,c,K]=convertf(A,b,c,K) % % converts free variables in a SeDuMi problem into nonnegative LP variables. % \end{verbatim} \section*{Using the subroutine interface to CSDP} \subsection*{Storage Conventions} The matrices $C$, $X$, and $Z$ are treated as block diagonal matrices. The declarations in the file blockmat.h describe the block matrix data structure. The {\tt blockmatrix} structure contains a count of the number of blocks and a pointer to an array of records that describe individual blocks. The individual blocks can be matrices of size {\tt blocksize} or diagonal matrices in which only a vector of diagonal entries is stored. Individual matrices within a block matrix are stored in column major order as in Fortran. The ijtok() macro defined in index.h can be used to convert Fortran style indices into an index into a C vector. For example, if A is stored as a Fortran array with leading dimension n, element (i,j) of A can be accessed within a C program as A[ijtok(i,j,n)]. The following table demonstrates how a 3 by 2 matrix would be stored under this system. \\ \\ \begin{tabular}{|l|l|} \hline C index & Fortran index \\ \hline A[0] & A(1,1) \\ \hline A[1] & A(2,1) \\ \hline A[2] & A(3,1) \\ \hline A[3] & A(1,2) \\ \hline A[4] & A(2,2) \\ \hline A[5] & A(3,2) \\ \hline \end{tabular} Vectors are stored as conventional C vectors. However, indexing always starts with 1, so the [0] element of every vector is wasted. Most arguments are described as being of size {\tt n} or {\tt m}. Since the zeroth element of the vector is wasted, these vectors must actually be of size {\tt n+1} or {\tt m+1}. The constraint matrices $A_{i}$ are stored in a sparse form. The array {\bf constraints} contains pointers which point to linked lists of structures, with one structure for each block of the sparse matrix. The {\bf sparseblock} data structures contain pointers to arrays which contain the entries and their {\bf i} and {\bf j} indices. For an example of how to setup these data structures, refer to the example directory in the CSDP distribution. This directory contains a program that solves the very small SDP \begin{equation} \begin{array}{rrcl} \max & \mbox{tr}\; (CX) & & \\ & \mbox{tr}\;A_{1}X & = & 1 \\ & \mbox{tr}\;A_{2}X & = & 2 \\ & X & \succeq & 0 \\ \end{array} \end{equation} where \begin{equation} C=\left[ \begin{array}{rrrrrrr} 2 & 1 & & & & & \\ 1 & 2 & & & & & \\ & & 3 & 0 & 1 & & \\ & & 0 & 2 & 0 & & \\ & & 1 & 0 & 3 & & \\ & & & & & 0 & \\ & & & & & & 0 \\ \end{array} \right] \end{equation} \begin{equation} A_{1}=\left[ \begin{array}{rrrrrrr} 3 & 1 & & & & & \\ 1 & 3 & & & & & \\ & & 0 & 0 & 0 & & \\ & & 0 & 0 & 0 & & \\ & & 0 & 0 & 0 & & \\ & & & & & 1 & \\ & & & & & & 0 \\ \end{array} \right] \end{equation} \begin{equation} A_{2}=\left[ \begin{array}{rrrrrrr} 0 & 0 & & & & & \\ 0 & 0 & & & & & \\ & & 3 & 0 & 1 & & \\ & & 0 & 4 & 0 & & \\ & & 1 & 0 & 5 & & \\ & & & & & 0 & \\ & & & & & & 1 \\ \end{array} \right]. \end{equation} In this problem, the $X$, $Z$, $A_{1}$, $A_{2}$ and $C$ matrices have three blocks. The first block is a 2 by 2 matrix. The second block is a 3 by 3 matrix. The third block is a diagonal block with 2 entries. In addition to setting up and solving this problem, the example program calls the write\_prob() routine to produce a file containing the SDP problem in SDPA sparse format. This is stored in the file prob.dat-s. \begin{verbatim} 2 3 2 3 -2 1.000000000000000000e+00 2.000000000000000000e+00 0 1 1 1 2.000000000000000000e+00 0 1 1 2 1.000000000000000000e+00 0 1 2 2 2.000000000000000000e+00 0 2 1 1 3.000000000000000000e+00 0 2 1 3 1.000000000000000000e+00 0 2 2 2 2.000000000000000000e+00 0 2 3 3 3.000000000000000000e+00 1 1 1 1 3.000000000000000000e+00 1 1 1 2 1.000000000000000000e+00 1 1 2 2 3.000000000000000000e+00 1 3 1 1 1.000000000000000000e+00 2 2 1 1 3.000000000000000000e+00 2 2 2 2 4.000000000000000000e+00 2 2 3 3 5.000000000000000000e+00 2 2 1 3 1.000000000000000000e+00 2 3 2 2 1.000000000000000000e+00 \end{verbatim} The 2 in the first line indicates that this problem has two constraints. The 3 in the second line indicates that there are three blocks in the $X$ and $Z$ matrices. The third line gives the sizes of the three blocks. Note that the third block's size is given as -2. The minus sign indicates that this is a diagonal block. The fourth line gives the values of the right hand sides of the two constraints. The remaining lines in the file describe the entries in the $C$, $A_{1}$, and $A_{2}$ matrices. The first number in each line is the number of the matrix, with $0$ for the $C$ matrix. The second number specifies a block within the matrix. The third and fourth numbers give the row and column of a nonzero entry within this block. The fifth number gives the actual value at that position within the block. Comparing this file to the problem statement above can be helpful in understanding the SDPA sparse file format. Figure \ref{cmat} shows a graphical representation of the data structure that holds the C matrix. Notice that individual matrix blocks of the C matrix are stored as Fortran arrays and that the diagonal block is stored as a vector, with the 0 entry unused. The data structures for $X$ and $Z$ are similar. \begin{figure} \begin{center} \scalebox{0.5}{\includegraphics{cmat}} \caption{The C matrix.} \label{cmat} \end{center} \end{figure} Figure \ref{constraints} shows the overall structure of the constraints. There is a vector of pointers to linked lists of constraint blocks. The 0th entry in this array is ignored. Blocks that contain only zero entries are not stored in the linked lists. Figure \ref{a1block1} shows the detail of the data structure for block 1 of the constraint matrix $A_{1}$. \begin{figure} \begin{center} \scalebox{0.5}{\includegraphics{constraints}} \caption{The constraints.} \label{constraints} \end{center} \end{figure} \begin{figure} \begin{center} \scalebox{0.5}{\includegraphics{a1block1}} \caption{Block 1 of $A_{1}$.} \label{a1block1} \end{center} \end{figure} \clearpage After solving the problem, the example program outputs the solution to prob.sol using the write\_sol() routine. The output produced on different computers might vary because of floating point round--off differences. However, the following output is typical. \begin{verbatim} 7.499999999674811235e-01 9.999999995736339464e-01 1 1 1 1 2.500000018710683558e-01 1 1 1 2 -2.500000000325189320e-01 1 1 2 2 2.500000018710683558e-01 1 2 1 1 6.895272851149165827e-10 1 2 1 3 -4.263660251297748376e-10 1 2 2 2 2.000000000263161049e+00 1 2 3 3 1.999999999836795217e+00 1 3 1 1 7.500000019361059422e-01 1 3 2 2 1.000000001542258765e+00 2 1 1 1 1.250000001467082567e-01 2 1 1 2 1.249999992664581755e-01 2 1 2 2 1.250000001467082567e-01 2 2 1 1 6.666669670820890570e-01 2 2 1 3 -4.518334811445142147e-07 2 2 2 2 2.200629338637236883e-10 2 2 3 3 2.200635108933231998e-10 2 3 1 1 5.868341556035494699e-10 2 3 2 2 4.401258478508541047e-10 \end{verbatim} The first line of the file gives the optimal y values. The lines that start with "1 " give the nonzero entries in the optimal Z matrix. As in the SDPA input file there are five numbers per line. The first number is the number of the matrix, where 1 is used for $Z$ and 2 is used for $X$. The second number specifies a block within the matrix. The third and fourth numbers are the row and column within the block. The final number is the actual value at the position in the block. For example, \begin{verbatim} 2 2 1 3 -4.518334811445142147e-07 \end{verbatim} means that in the 1st row, third column of block 2 of the $X$ matrix, the entry is $-4.518334811445142147\times 10^{-7}$. Since the matrices are symmetric, we only record the entries in the upper triangle of the matrix. The same entry will also appear in row 3, column 1. So, the optimal solution to the example problem is (rounding the numbers off to two or three digits) \begin{equation} y=\left[ \begin{array}{rr} 0.75 & 1.00 \end{array} \right] \end{equation} \begin{equation} Z=\left[ \begin{array}{rrrrrrr} 0.25 & -0.25 & & & & & \\ -0.25 & 0.25 & & & & & \\ & & 0 & 0 & 0 & & \\ & & 0 & 2.00 & 0 & & \\ & & 0 & 0 & 2.00 & & \\ & & & & & 0.75 & \\ & & & & & & 1.00 \\ \end{array} \right] \end{equation} \begin{equation} X=\left[ \begin{array}{rrrrrrr} 0.125 & 0.125 & & & & & \\ 0.125 & 0.125 & & & & & \\ & & 0.667 & 0 & 0 & & \\ & & 0 & 0 & 0 & & \\ & & 0 & 0 & 0 & & \\ & & & & & 0 & \\ & & & & & & 0 \\ \end{array} \right] \end{equation} \subsection*{Storage Requirements} CSDP requires storage for a number of block diagonal matrices of the same form as $X$ and $Z$, as well as storage for the Schur complement system that is Cholesky factored in each iteration. For a problem with $m$ constraints and block diagonal matrices with blocks of size $n_{1}$, $n_{2}$, $\dots$, $n_{s}$, CSDP requires approximately \begin{equation} \mbox{Storage}=8(m^{2}+11(n_{1}^{2}+n_{2}^{2}+\ldots+n_{s}^{2})) \end{equation} bytes of storage. This formula includes all of the two dimensional arrays but leaves out the one dimensional vectors. This formula also excludes the storage required to store the constraint matrices, which are assumed to be sparse. In practice it is wise to allow for about 10\% to 20\% more storage to account for the excluded factors. The parallel version of CSDP requires additional storage for work matrices used by the routine that computes the Schur complement matrix. If the OpenMP maximum number of threads (typically the number of processors on the system) is $p$, and $p>1$, then CSDP will allocate an additional $16(p-1)n_{\mbox{max}}^{2}$ bytes of storage for workspace. \subsection*{Calling The SDP Routine} The routine has 11 parameters which include the problem data and an initial solution. The calling sequence for the sdp subroutine is: \begin{verbatim} int easy_sdp(n,k,C,a,constraints,constant_offset,pX,py,pZ,ppobj,pdobj) int n; /* Dimension of X */ int k; /* # of constraints */ struct blockmatrix C; /* C matrix */ double *a; /* right hand side vector */ struct constraintmatrix *constraints; /* Constraints */ double constant_offset; /* added to objective */ struct blockmatrix *pX; /* X matrix */ double **py; /* y vector */ struct blockmatrix *pZ; /* Z matrix */ double *ppobj; /* Primal objective */ double *pdobj; /* Dual objective */ \end{verbatim} \subsection*{Input Parameters} \begin{enumerate} \item {\tt n}. This parameter gives the dimension of the X, C, and Z matrices. \item {\tt k}. This parameter gives the number of constraints. \item {\tt C}. This parameter gives the $C$ matrix and implicitly defines the block structure of the block diagonal matrices. \item {\tt a}. This parameter gives the right hand side vector $a$. \item {\tt constraints}. This parameter specifies the problem constraints. \item {\tt constant\_offset}. This scalar is added to the primal and dual objective values. \item {\tt pX}. On input, this parameter gives the initial primal solution $X$. \item {\tt py}. On input, this parameter gives the initial dual solution $y$. \item {\tt pZ}. On input, this parameter gives the initial dual solution $Z$. \end{enumerate} \subsection*{Output Parameters} \begin{enumerate} \item {\tt pX}. On output this parameter gives the optimal primal solution $X$. \item {\tt py}. On output, this parameter gives the optimal dual solution $y$. \item {\tt pZ}. On output, this parameter gives the optimal dual solution $Z$. \item {\tt ppobj}. On output, this parameter gives the optimal primal objective value. \item {\tt pdobj}. On output, this parameter gives the optimal dual objective value. \end{enumerate} \subsection*{Return Codes} If CSDP succeeds in solving the problem to full accuracy, the {\tt easy\_sdp} routine will return 0. Otherwise, the {\tt easy\_sdp} routine will return a nonzero return code. In many cases, CSDP will have actually found a good solution that doesn't quite satisfy one of the termination criteria. In particular, return code 3 is usually indicative of such a solution. Whenever there is a nonzero return code, you should examine the return and the solution to see what happened. In other cases, the code will stop because it can no longer make progress and the solution doesn't satisfy the required tolerances. However, the solution may be good enough for your purposes. The return codes from the easy\_sdp() routine are given in Table \ref{retcodetable}. For the command line solver, csdp, these are also used as exit codes. Additional exit codes are used for significant errors that did not allow execution. These are given Table \ref{exitcodetable}. \begin{table} \begin{tabular}{|r|l|} \hline Code & Explanation \\ \hline 0 & Problem solved to optimality \\ \hline 1 & Problem is primal infeasible. \\ \hline 2 & Problem is dual infeasible. \\ \hline 3 & Problem solved to near optimality \\ \hline 4 & Maximum iterations reached. \\ \hline 5 & Stuck at edge of primal feasibility. \\ \hline 6 & Stuck at edge of dual feasibility. \\ \hline 7 & Lack of progress. \\ \hline 8 & $X$, $Z$, or $O$ is singular. \\ \hline 9 & NaN or Inf values encountered. \\ \hline 10 & Program stopped by signal (SIXCPU, SIGTERM, etc.) \\ \hline \end{tabular} \caption{Return codes for easy\_sdp() and CSDP.} \label{retcodetable} \end{table} \begin{table} \begin{tabular}{|r|l|} \hline Code & Explanation \\ \hline 200 & No problem data file named. \\ \hline 201 & Couldn't open problem data file. \\ \hline 202 & Couldn't open initial solution data file. \\ \hline 203 & Couldn't write problem data file. \\ \hline 204 & Couldn't write solution data file. \\ \hline 205 & Storage allocation failed. \\ \hline 206 & An internal error occurred. \\ \hline \end{tabular} \caption{Exit codes for non-recoverable errors.} \label{exitcodetable} \end{table} \subsection*{The User Exit Routine} By default, the {\tt easy\_sdp} routine stops when it has obtained a solution in which the relative primal and dual infeasibilities and the relative gap between the primal and dual objective values is less than $1.0 \times 10^{-8}$. There are situations in which you might want to terminate the solution process before an optimal solution has been found. For example, in a cutting plane routine, you might want to terminate the solution process as soon as a cutting plane has been found. If you would like to specify your own stopping criteria, you can implement these in a user exit routine. At each iteration of its algorithm, CSDP calls a routine named {\tt user\_exit}. CSDP passes the problem data and current solution to this subroutine. If {\tt user\_exit} returns 0, then CSDP continues. However, if {\tt user\_exit} returns 1, then CSDP returns immediately to the calling program. The default routine supplied in the CSDP library simply returns 0. If CSDP is compiled with the ``-DUSESIGTERM'' flag, then default routine will also stop the solution process whenever the process receives a TERM signal. You can write your own routine and link it with your program in place of the default user exit routine. The calling sequence for the user exit routine is \begin{verbatim} int user_exit(n,k,C,a,dobj,pobj,constant_offset,constraints,X,y,Z,params) int n; /* Dimension of X */ int k; /* # of constraints */ struct blockmatrix C; /* C matrix */ double *a; /* right hand side */ double dobj; /* dual objective */ double pobj; /* primal objective */ double constant_offset; /* added to objective */ struct constraintmatrix *constraints; /* Constraints */ struct blockmatrix X; /* primal solution */ double *y; /* dual solution */ struct blockmatrix Z; /* dual solution */ struct paramstruc params; /* parameters sdp called with */ \end{verbatim} \subsection*{Finding an Initial Solution} The CSDP library contains a routine for finding an initial solution to the SDP problem. Note that this routine allocates all storage required for the initial solution. The calling sequence for this routine is: \begin{verbatim} void initsoln(n,k,C,a,constraints,pX0,py0,pZ0) int n; /* dimension of X */ int k; /* # of constraints */ struct bqlockmatrix C; /* C matrix */ double *a; /* right hand side vector */ struct constraintmatrix *constraints; /* constraints */ struct blockmatrix *pX0; /* Initial primal solution */ double **py0; /* Initial dual solution */ struct blockmatrix *pZ0; /* Initial dual solution */ \end{verbatim} \subsection*{Reading and Writing Problem Data} The CSDP library contains routines for reading and writing SDP problems and solutions in SDPA format. The routine {\tt write\_prob} is used to write out an SDP problem in SDPA sparse format. The routine {\tt read\_prob} is used to read an SDP problem in from a file. The routine {\tt write\_sol} is used to write an SDP solution to a file. The routine {\tt read\_sol} is used to read a solution from a file. The calling sequence for {\tt write\_prob} is \begin{verbatim} int write_prob(fname,n,k,C,a,constraints) char *fname; /* file to write */ int n; /* Dimension of X */ int k; /* # of constraints */ struct blockmatrix C; /* The C matrix */ double *a; /* The a vector */ struct constraintmatrix *constraints; /* the constraints */ \end{verbatim} The calling sequence for {\tt read\_prob} is: \begin{verbatim} int read_prob(fname,pn,pk,pC,pa,pconstraints,printlevel) char *fname; /* file to read */ int *pn; /* Dimension of X */ int *pk; /* # of constraints */ struct blockmatrix *pC; /* The C matrix */ double **pa; /* The a vector */ struct constraintmatrix **pconstraints; /* The constraints */ int printlevel; /* =0 for no output, =1 for normal output, >1 for debugging */ \end{verbatim} Note that the {\tt read\_prob} routine allocates all storage required by the problem. The calling sequence for {\tt write\_sol} is \begin{verbatim} int write_sol(fname,n,k,X,y,Z) char *fname; /* Name of the file to write to */ int n; /* Dimension of X */ int k; /* # of constraints */ struct blockmatrix X; /* Primal solution X */ double *y; /* Dual vector y */ struct blockmatrix Z; /* Dual matrix Z */ \end{verbatim} This routine returns 0 if successful and exits if it is unable to write the solution file. The calling sequence for {\tt read\_sol} is \begin{verbatim} int read_sol(fname,n,k,C,pX,py,pZ) char *fname; /* file to read */ int n; /* dimension of X */ int k; /* # of constraints */ struct blockmatrix C; /* The C matrix */ struct blockmatrix *pX; /* The X matrix */ double **py; /* The y vector */ struct blockmatrix *pZ; /* The Z matrix */ \end{verbatim} Note that {\tt read\_sol} allocates storage for $X$, $y$, and $Z$. This routine returns 0 when successful, and exits if it is unable to read the solution file. \subsection*{Freeing Problem Memory} The routine {\tt free\_prob} can be used to automatically free the memory allocated for a problem. The calling sequence for {\tt free\_prob} is \begin{verbatim} void free_prob(n,k,C,a,constraints,X,y,Z) int n; /* Dimension of X */ int k; /* # of constraints */ struct blockmatrix C; /* The C matrix */ double *a; /* The a vector */ struct constraintmatrix *constraints; /* the constraints */ struct blockmatrix X; /* X matrix. */ double *y; /* the y vector. */ struct blockmatrix Z; /* Z matrix. */ \end{verbatim} \bibliography{sdp} \end{document} Csdp-6.2.0/doc/cmat.fig0000644000175200017520000001017010470505023013231 0ustar coincoin#FIG 3.2 Produced by xfig version 3.2.5-alpha5 Landscape Center Metric A4 100.00 Single -2 1200 2 1 3 0 1 0 0 50 -1 20 0.000 1 0.0000 900 6750 43 43 900 6750 943 6750 1 3 0 1 0 0 50 -1 20 0.000 1 0.0000 900 5400 43 43 900 5400 943 5400 1 3 0 1 0 0 50 -1 20 0.000 1 0.0000 900 4050 43 43 900 4050 943 4050 1 3 0 1 0 0 50 -1 20 0.000 1 0.0000 900 900 43 43 900 900 943 900 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3 225 675 225 450 225 675 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 225 675 1575 675 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 225 225 225 1125 1575 1125 1575 225 225 225 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 225 2025 1575 2025 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 225 2475 1575 2475 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 225 3375 1575 3375 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 225 3825 1575 3825 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 225 4725 1575 4725 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 225 5175 1575 5175 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 225 6525 1575 6525 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 2250 225 2250 2025 2700 2025 2700 225 2250 225 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 3600 225 3600 4275 4050 4275 4050 225 3600 225 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 3600 675 4050 675 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 3600 1125 4050 1125 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 3600 1575 4050 1575 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 3600 2025 4050 2025 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 3600 2475 4050 2475 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 3600 2925 4050 2925 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 3600 3375 4050 3375 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 3600 3825 4050 3825 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 2250 675 2700 675 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 2250 1125 2700 1125 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 225 1575 225 2925 1575 2925 1575 1575 225 1575 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 225 2925 225 4275 1575 4275 1575 2925 225 2925 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 225 4275 225 5625 1575 5625 1575 4275 225 4275 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 225 5625 225 6975 1575 6975 1575 5625 225 5625 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 2 1 1.00 60.00 120.00 900 900 900 1575 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 225 6075 1575 6075 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 6 1 1 1.00 60.00 120.00 900 5400 1800 5400 1800 4725 3150 4725 3150 450 3600 450 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 2475 5400 2475 6750 2925 6750 2925 5400 2475 5400 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 2475 6300 2925 6300 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 2475 5850 2925 5850 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 4 1 1 1.00 60.00 120.00 900 4050 2025 4050 2025 450 2250 450 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 4 1 1 1.00 60.00 120.00 900 6750 2025 6750 2025 5625 2475 5625 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 2250 1575 2700 1575 4 0 0 50 -1 1 24 0.0000 0 270 195 2340 630 2\001 4 0 0 50 -1 1 24 0.0000 0 270 195 2340 1080 1\001 4 0 0 50 -1 1 24 0.0000 0 270 195 2340 1980 2\001 4 0 0 50 -1 1 24 0.0000 0 270 195 2340 1530 1\001 4 0 0 50 -1 1 24 0.0000 0 270 195 3690 630 3\001 4 0 0 50 -1 1 24 0.0000 0 270 195 3690 1080 0\001 4 0 0 50 -1 1 24 0.0000 0 270 195 3690 1530 1\001 4 0 0 50 -1 1 24 0.0000 0 270 195 3690 1980 0\001 4 0 0 50 -1 1 24 0.0000 0 270 195 3690 2430 2\001 4 0 0 50 -1 1 24 0.0000 0 270 195 3690 2880 0\001 4 0 0 50 -1 1 24 0.0000 0 270 195 3690 3330 1\001 4 0 0 50 -1 1 24 0.0000 0 270 195 3690 3780 0\001 4 0 0 50 -1 1 24 0.0000 0 270 195 3690 4230 3\001 4 0 0 50 -1 1 24 0.0000 0 270 195 720 6030 2\001 4 0 0 50 -1 1 24 0.0000 0 270 195 720 4680 3\001 4 0 0 50 -1 1 24 0.0000 0 270 195 720 3330 2\001 4 0 0 50 -1 1 24 0.0000 0 45 270 720 2790 --\001 4 0 0 50 -1 1 24 0.0000 0 45 270 720 2340 --\001 4 0 0 50 -1 1 24 0.0000 0 45 270 720 1890 --\001 4 0 0 50 -1 1 16 0.0000 0 195 1095 360 3690 MATRIX\001 4 0 0 50 -1 1 16 0.0000 0 195 1095 360 5040 MATRIX\001 4 0 0 50 -1 1 16 0.0000 0 195 720 450 6390 DIAG\001 4 0 0 50 -1 1 24 0.0000 0 45 135 2610 5670 -\001 4 0 0 50 -1 1 24 0.0000 0 270 195 2610 6210 0\001 4 0 0 50 -1 1 24 0.0000 0 270 195 2610 6660 0\001 4 0 0 50 -1 1 24 0.0000 0 270 195 810 630 3\001 Csdp-6.2.0/doc/cmat.eps0000644000175200017520000002515110470505023013260 0ustar coincoin%!PS-Adobe-2.0 EPSF-2.0 %%Title: cmat.fig %%Creator: fig2dev Version 3.2 Patchlevel 5-alpha5 %%CreationDate: Thu Aug 10 21:32:52 2006 %%For: brian@bullwinkle (brian,,,) %%BoundingBox: 0 0 244 428 %Magnification: 1.0000 %%EndComments /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /col-1 {0 setgray} bind def /col0 {0.000 0.000 0.000 srgb} bind def /col1 {0.000 0.000 1.000 srgb} bind def /col2 {0.000 1.000 0.000 srgb} bind def /col3 {0.000 1.000 1.000 srgb} bind def /col4 {1.000 0.000 0.000 srgb} bind def /col5 {1.000 0.000 1.000 srgb} bind def /col6 {1.000 1.000 0.000 srgb} bind def /col7 {1.000 1.000 1.000 srgb} bind def /col8 {0.000 0.000 0.560 srgb} bind def /col9 {0.000 0.000 0.690 srgb} bind def /col10 {0.000 0.000 0.820 srgb} bind def /col11 {0.530 0.810 1.000 srgb} bind def /col12 {0.000 0.560 0.000 srgb} bind def /col13 {0.000 0.690 0.000 srgb} bind def /col14 {0.000 0.820 0.000 srgb} bind def /col15 {0.000 0.560 0.560 srgb} bind def /col16 {0.000 0.690 0.690 srgb} bind def /col17 {0.000 0.820 0.820 srgb} bind def /col18 {0.560 0.000 0.000 srgb} bind def /col19 {0.690 0.000 0.000 srgb} bind def /col20 {0.820 0.000 0.000 srgb} bind def /col21 {0.560 0.000 0.560 srgb} bind def /col22 {0.690 0.000 0.690 srgb} bind def /col23 {0.820 0.000 0.820 srgb} bind def /col24 {0.500 0.190 0.000 srgb} bind def /col25 {0.630 0.250 0.000 srgb} bind def /col26 {0.750 0.380 0.000 srgb} bind def /col27 {1.000 0.500 0.500 srgb} bind def /col28 {1.000 0.630 0.630 srgb} bind def /col29 {1.000 0.750 0.750 srgb} bind def /col30 {1.000 0.880 0.880 srgb} bind def /col31 {1.000 0.840 0.000 srgb} bind def end save newpath 0 428 moveto 0 0 lineto 244 0 lineto 244 428 lineto closepath clip newpath -12.8 440.8 translate 1 -1 scale /cp {closepath} bind def /ef {eofill} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth} bind def /tr {translate} bind def /tnt {dup dup currentrgbcolor 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} bind def /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul srgb} bind def /reencdict 12 dict def /ReEncode { reencdict begin /newcodesandnames exch def /newfontname exch def /basefontname exch def /basefontdict basefontname findfont def /newfont basefontdict maxlength dict def basefontdict { exch dup /FID ne { dup /Encoding eq { exch dup length array copy newfont 3 1 roll put } { exch newfont 3 1 roll put } ifelse } { pop pop } ifelse } forall newfont /FontName newfontname put newcodesandnames aload pop 128 1 255 { newfont /Encoding get exch /.notdef put } for newcodesandnames length 2 idiv { newfont /Encoding get 3 1 roll put } repeat newfontname newfont definefont pop end } def /isovec [ 8#055 /minus 8#200 /grave 8#201 /acute 8#202 /circumflex 8#203 /tilde 8#204 /macron 8#205 /breve 8#206 /dotaccent 8#207 /dieresis 8#210 /ring 8#211 /cedilla 8#212 /hungarumlaut 8#213 /ogonek 8#214 /caron 8#220 /dotlessi 8#230 /oe 8#231 /OE 8#240 /space 8#241 /exclamdown 8#242 /cent 8#243 /sterling 8#244 /currency 8#245 /yen 8#246 /brokenbar 8#247 /section 8#250 /dieresis 8#251 /copyright 8#252 /ordfeminine 8#253 /guillemotleft 8#254 /logicalnot 8#255 /hyphen 8#256 /registered 8#257 /macron 8#260 /degree 8#261 /plusminus 8#262 /twosuperior 8#263 /threesuperior 8#264 /acute 8#265 /mu 8#266 /paragraph 8#267 /periodcentered 8#270 /cedilla 8#271 /onesuperior 8#272 /ordmasculine 8#273 /guillemotright 8#274 /onequarter 8#275 /onehalf 8#276 /threequarters 8#277 /questiondown 8#300 /Agrave 8#301 /Aacute 8#302 /Acircumflex 8#303 /Atilde 8#304 /Adieresis 8#305 /Aring 8#306 /AE 8#307 /Ccedilla 8#310 /Egrave 8#311 /Eacute 8#312 /Ecircumflex 8#313 /Edieresis 8#314 /Igrave 8#315 /Iacute 8#316 /Icircumflex 8#317 /Idieresis 8#320 /Eth 8#321 /Ntilde 8#322 /Ograve 8#323 /Oacute 8#324 /Ocircumflex 8#325 /Otilde 8#326 /Odieresis 8#327 /multiply 8#330 /Oslash 8#331 /Ugrave 8#332 /Uacute 8#333 /Ucircumflex 8#334 /Udieresis 8#335 /Yacute 8#336 /Thorn 8#337 /germandbls 8#340 /agrave 8#341 /aacute 8#342 /acircumflex 8#343 /atilde 8#344 /adieresis 8#345 /aring 8#346 /ae 8#347 /ccedilla 8#350 /egrave 8#351 /eacute 8#352 /ecircumflex 8#353 /edieresis 8#354 /igrave 8#355 /iacute 8#356 /icircumflex 8#357 /idieresis 8#360 /eth 8#361 /ntilde 8#362 /ograve 8#363 /oacute 8#364 /ocircumflex 8#365 /otilde 8#366 /odieresis 8#367 /divide 8#370 /oslash 8#371 /ugrave 8#372 /uacute 8#373 /ucircumflex 8#374 /udieresis 8#375 /yacute 8#376 /thorn 8#377 /ydieresis] def /Times-Roman /Times-Roman-iso isovec ReEncode /DrawEllipse { /endangle exch def /startangle exch def /yrad exch def /xrad exch def /y exch def /x exch def /savematrix mtrx currentmatrix def x y tr xrad yrad sc 0 0 1 startangle endangle arc closepath savematrix setmatrix } def /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 10 setmiterlimit 0 slj 0 slc 0.06299 0.06299 sc % % Fig objects follow % % % here starts figure with depth 50 % Ellipse 7.500 slw n 900 6750 43 43 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr % Ellipse n 900 5400 43 43 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr % Ellipse n 900 4050 43 43 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr % Ellipse n 900 900 43 43 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr % Polyline 0 slj 0 slc n 225 675 m 225 450 l 225 675 l cp gs col0 s gr % Polyline n 225 675 m 1575 675 l gs col0 s gr % Polyline 15.000 slw n 225 225 m 225 1125 l 1575 1125 l 1575 225 l 225 225 l cp gs col0 s gr % Polyline 7.500 slw n 225 2025 m 1575 2025 l gs col0 s gr % Polyline n 225 2475 m 1575 2475 l gs col0 s gr % Polyline n 225 3375 m 1575 3375 l gs col0 s gr % Polyline n 225 3825 m 1575 3825 l gs col0 s gr % Polyline n 225 4725 m 1575 4725 l gs col0 s gr % Polyline n 225 5175 m 1575 5175 l gs col0 s gr % Polyline n 225 6525 m 1575 6525 l gs col0 s gr % Polyline 15.000 slw n 2250 225 m 2250 2025 l 2700 2025 l 2700 225 l 2250 225 l cp gs col0 s gr % Polyline n 3600 225 m 3600 4275 l 4050 4275 l 4050 225 l 3600 225 l cp gs col0 s gr % Polyline 7.500 slw n 3600 675 m 4050 675 l gs col0 s gr % Polyline n 3600 1125 m 4050 1125 l gs col0 s gr % Polyline n 3600 1575 m 4050 1575 l gs col0 s gr % Polyline n 3600 2025 m 4050 2025 l gs col0 s gr % Polyline n 3600 2475 m 4050 2475 l gs col0 s gr % Polyline n 3600 2925 m 4050 2925 l gs col0 s gr % Polyline n 3600 3375 m 4050 3375 l gs col0 s gr % Polyline n 3600 3825 m 4050 3825 l gs col0 s gr % Polyline n 2250 675 m 2700 675 l gs col0 s gr % Polyline n 2250 1125 m 2700 1125 l gs col0 s gr % Polyline 15.000 slw n 225 1575 m 225 2925 l 1575 2925 l 1575 1575 l 225 1575 l cp gs col0 s gr % Polyline n 225 2925 m 225 4275 l 1575 4275 l 1575 2925 l 225 2925 l cp gs col0 s gr % Polyline n 225 4275 m 225 5625 l 1575 5625 l 1575 4275 l 225 4275 l cp gs col0 s gr % Polyline n 225 5625 m 225 6975 l 1575 6975 l 1575 5625 l 225 5625 l cp gs col0 s gr % Polyline 7.500 slw gs clippath 870 1385 m 870 1590 l 930 1590 l 930 1385 l 930 1385 l 900 1535 l 870 1385 l cp eoclip n 900 900 m 900 1575 l gs col0 s gr gr % arrowhead n 870 1385 m 900 1535 l 930 1385 l 900 1415 l 870 1385 l cp gs 0.00 setgray ef gr col0 s % Polyline n 225 6075 m 1575 6075 l gs col0 s gr % Polyline gs clippath 3448 480 m 3615 480 l 3615 420 l 3448 420 l 3448 420 l 3568 450 l 3448 480 l cp eoclip n 900 5400 m 1800 5400 l 1800 4725 l 3150 4725 l 3150 450 l 3600 450 l gs col0 s gr gr % arrowhead n 3448 480 m 3568 450 l 3448 420 l 3448 480 l cp gs 0.00 setgray ef gr col0 s % Polyline 15.000 slw n 2475 5400 m 2475 6750 l 2925 6750 l 2925 5400 l 2475 5400 l cp gs col0 s gr % Polyline 7.500 slw n 2475 6300 m 2925 6300 l gs col0 s gr % Polyline n 2475 5850 m 2925 5850 l gs col0 s gr % Polyline gs clippath 2098 480 m 2265 480 l 2265 420 l 2098 420 l 2098 420 l 2218 450 l 2098 480 l cp eoclip n 900 4050 m 2025 4050 l 2025 450 l 2250 450 l gs col0 s gr gr % arrowhead n 2098 480 m 2218 450 l 2098 420 l 2098 480 l cp gs 0.00 setgray ef gr col0 s % Polyline gs clippath 2323 5655 m 2490 5655 l 2490 5595 l 2323 5595 l 2323 5595 l 2443 5625 l 2323 5655 l cp eoclip n 900 6750 m 2025 6750 l 2025 5625 l 2475 5625 l gs col0 s gr gr % arrowhead n 2323 5655 m 2443 5625 l 2323 5595 l 2323 5655 l cp gs 0.00 setgray ef gr col0 s % Polyline n 2250 1575 m 2700 1575 l gs col0 s gr /Times-Roman-iso ff 381.00 scf sf 2340 630 m gs 1 -1 sc (2) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 2340 1080 m gs 1 -1 sc (1) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 2340 1980 m gs 1 -1 sc (2) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 2340 1530 m gs 1 -1 sc (1) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 3690 630 m gs 1 -1 sc (3) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 3690 1080 m gs 1 -1 sc (0) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 3690 1530 m gs 1 -1 sc (1) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 3690 1980 m gs 1 -1 sc (0) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 3690 2430 m gs 1 -1 sc (2) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 3690 2880 m gs 1 -1 sc (0) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 3690 3330 m gs 1 -1 sc (1) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 3690 3780 m gs 1 -1 sc (0) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 3690 4230 m gs 1 -1 sc (3) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 720 6030 m gs 1 -1 sc (2) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 720 4680 m gs 1 -1 sc (3) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 720 3330 m gs 1 -1 sc (2) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 720 2790 m gs 1 -1 sc (--) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 720 2340 m gs 1 -1 sc (--) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 720 1890 m gs 1 -1 sc (--) col0 sh gr /Times-Roman-iso ff 254.00 scf sf 360 3690 m gs 1 -1 sc (MATRIX) col0 sh gr /Times-Roman-iso ff 254.00 scf sf 360 5040 m gs 1 -1 sc (MATRIX) col0 sh gr /Times-Roman-iso ff 254.00 scf sf 450 6390 m gs 1 -1 sc (DIAG) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 2610 5670 m gs 1 -1 sc (-) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 2610 6210 m gs 1 -1 sc (0) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 2610 6660 m gs 1 -1 sc (0) col0 sh gr /Times-Roman-iso ff 381.00 scf sf 810 630 m gs 1 -1 sc (3) col0 sh gr % here ends figure; $F2psEnd rs showpage %%Trailer %EOF Csdp-6.2.0/doc/constraints.fig0000644000175200017520000000301210470505023014651 0ustar coincoin#FIG 3.2 Produced by xfig version 3.2.5-alpha5 Landscape Center Metric A4 100.00 Single -2 1200 2 1 3 0 1 0 -1 50 -1 20 0.000 1 0.0000 1710 2430 90 90 1710 2430 1800 2430 1 3 0 1 0 -1 50 -1 20 0.000 1 0.0000 1710 1710 90 90 1710 1710 1800 1710 2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 1350 675 1350 2700 2025 2700 2025 675 1350 675 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 1350 1350 2025 1350 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 1350 2025 2025 2025 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 3060 1440 4140 1440 4140 1980 3060 1980 3060 1440 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 3060 2160 4140 2160 4140 2700 3060 2700 3060 2160 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 4860 2160 5940 2160 5940 2700 4860 2700 4860 2160 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 4860 1440 5940 1440 5940 1980 4860 1980 4860 1440 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 1710 1710 3060 1710 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 4140 1710 4860 1710 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 1710 2430 3060 2430 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2 1 1 1.00 60.00 120.00 4140 2430 4860 2430 4 0 0 50 -1 1 18 0.0000 0 195 870 3150 2475 Block 2\001 4 0 0 50 -1 1 18 0.0000 0 195 870 4950 2475 Block 3\001 4 0 0 50 -1 1 18 0.0000 0 195 870 3150 1800 Block 1\001 4 0 0 50 -1 1 18 0.0000 0 195 870 4950 1800 Block 3\001 4 0 0 50 -1 1 18 0.0000 0 30 180 1620 1170 --\001 4 0 0 50 -1 1 18 0.0000 0 195 345 900 1800 A1\001 4 0 0 50 -1 1 18 0.0000 0 195 345 900 2520 A2\001 Csdp-6.2.0/doc/cmat.pdf0000644000175200017520000011112010470505023013232 0ustar coincoin%PDF-1.3 %쏢 6 0 obj <> stream xXMo7 ϯЭIU=1E"@{@{wŸC~5E 0}H2*C~yXŪ?.%)kT V;T^TuE\TY%8KHVg>nK`FGV-d]݃uw>p|}u*[>$V1[V֢m>˜f]F[B3xgam(u;?ѰU R"K1JQjٍBه; teSNQke{Zlv5{Md[<4_5ywC'(AS6p(b 8?($YfzKvT;낎Qmg̜ K-$d:JJ> >)Pl4ސMr(RɲdFՑœd5dbِ[%!_eH[Cr]& ȌhsTOH$#vHCDdr&X X+#Րehgv gz1!,w罳 W׹̙őbfN?kZF%Qe랰/>rkft W3ڠi}m 8 q٬6"ҚZTJ_SEBnΨ?WΟ.zխhN_YCv]\Ĵtd{V. 8WMԩJ #@@ xuZ{Bgr^iudz"o} $.g^1azo$q饦h6v+"rn &PSǯbQ0kp`ƽ==%bac;0#GmO-L'Ow!::পSU˰j,2aǤױ) g0"upN'/7I^C-RA*ҵ>~WqBD"wIȯx#$?է\#endstream endobj 7 0 obj 1190 endobj 5 0 obj <> /Contents 6 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 5 0 R ] /Count 1 >> endobj 1 0 obj <> endobj 4 0 obj <> endobj 9 0 obj <> endobj 8 0 obj <>stream x{XWYvg$ɮ^E^P.e,.tKw kbPL4ŴdgYI|{<{ιNKx^zj*zT}aV1n̋8o|ʤuWo?qۄ% %xO+~QKL$ӉXOl&v5aOD&ODO .wO//$|SɏrFZIgқQdAd#N3kgrLrfsrsqs,9v q28 N9͹¹%fR2jKS;CS2*J)%UAP)*u^P*wh=֧zmD7;hKږ>B>t0FIt&K%&~LMOJjsuj^T{ڻkvזh˵Ss+۴{OhӾ}GSϵ~OMwuLיc\gH'HGt2tuJtut:utN\Թs_gX+t~a&'=a'̟dŠ 'l( swu 6j9biGBƟL3uww6)rX9m#;qg4''g'}6{8gp崝^~ܽ]ܽB9x;M0YM=/dRw?gt:?m1L35ODΞޢg@OOݑr.vsvp9._TΎcǍ~"oDZ#~b֏]ǎ[D,^]upqw_l``d>,YwKC#͇K\EZ{2^l(be6&ͫG D#q㼗,e;_`qK=%36)<;͹o?үWTWG,`L`![ fG6J0a/l0,` ,fl0v0ã6rְ61+`Pn`m`Ӏ:p>`'8* o=xHop5)hMv(36pA }xx ,H0ȆDrHHH(HhHHXȀ8ȄxP=.C'M-8J n8PU0 w BC ) 4Cr:9I"gsȹ\H." Ť!\J1iB Wr-\On 7Ln!9I"w{ȽiIZҚ!mɃy'ґt"Iҕt#ɣIzޤ!}I?ҟ  2! % #RNFQd4Cƒqd<@&L"2L# 2"2#IY@E,&KR,'+J&kZ'Fl&[Vl';N&{^'AyxGׂ0waZ|  ӭaz X3Ì09|Lf.0fY0fٛa~ saN ̝ sa̽ 6<3 w| hXX‚oaX8 ``=za*,aX!,퀥h!߰,/`c$ LvI `VaX:V߆5`3X:Xo \ؠf8n20;¦0lͿÖuE`) |.쨃$쌀kv=`OeSK8 7,*`_ a4xz:XnY 6l[]vOP!}o8<#ih ߁Npjp N/Y9\v]p5Q~ 0t<w8v[ s8pr<CP8 P:Q8gfÙpζ9]8 p!\Xv8 , .o%\ z`z ܘ 7uf n~"}XpW<4>GV1<>sϾao?I YB^tw[}1?ǙMxy^?~og `~w߇L0O`T̆?d/O"  `Z oqDFJqG大/'n |,@*qs 1Fކ&ʋB7JIL݉ɓ!3zt7ۂd b7}Jy&YuY/8ogf&英 ΫMObm.V:d">DK8 |LjL3܉x_AD}|fW_-0NɏC9HѕL+#220"SyL^J«ںI4\% P L3$D tRdB5e4M9DWgImLFR즠JsQ3D{n22X9)(\4@S<%7 R6!,[*n sTӱ/ n~ڜ-L Re)6]E*yBi/kT+jcI%##sLw2  iD+ezgw>BXِTd"wR=f1ceal܁8֬2%'5$!Oe5=BBnIH WxPIKf>X*=<o8RD-%[U3Lu?jM!U,pڐ&G7inyywYRh2J26bޣؼpKdbv^Z*)C?ҪYN&,bт;qnX9Kr&6Sñhh}Xq)Y\_܃QwHgWOy%%nSEc 2<ì0__f)|ڿ| rr 96z!b$#K!a꼭} ,PjJ-ZCR1a}=pT<-eV(! xrtWzb+VVK% 1f곙xW,}˼+ c>`6sr)o`m߅5),'8x_xqn+T]bm%nP*3)e"%K~DP>9Bkәw.Fv Z(::\'F'-s}1{YhX+'F!$ 23 =f6()Yɩ($8iS dR@rA J0YxgWc9Q"WsBrId**йe^~v~jk*K;\L)"eYh|IUb.VBQ >Rɂ[e\M i/qx1A(IS6֙ 2aiy!bHs۾va.tHzӭ^HYna>ǃ r^"^5ܤ8d]i~VRBtcpԍ@#"vJWcxrE/;Y|m/ZY S1VAna}c/>gZ4lcsB˛ՋzC=N-@;lSH?_@ۡ}*r{GVe>kt -hKu m [;=q 藆 .m@_z=|![Ȕy"Yr{Ub1:G8x{ORD;IjR$C'~GU/켲2cX%Lb͙n!Ni,-enT&u?U}Am`>#0yTh'D>5AZ9q񅺣[6Ϊ'>cu Ӽ3ʺ֒|w7W^2eQY}||Q+iGUQxIJDKx"OKi;Ts%U> :U~<:e>5KZ)DeFzԌBˣk5iU4ݦUAZf22 ?ۚeIMւ:cV"5 ؔTHcR",Ϙ.^8i,L":Ȃx!UW TtO+VYUIT-1#ns2TS)YI 2)Ϊ.ZAmN(iR]UYA,'&ꆠbwSl[?V+ѶIg~Ud]FuTo[C-8#0S''͗U-^~yBqH$&wX0 FA.c˔}쿽󸠵 ;ק0t}~Y74Uef%f$ eB^b:jA튺jED5ezo$f_5Yp.4RU (r˵CN.?2fE#=>KYٽkyͅw~5tGlD 9&g oY][< jTc9B&ϓE?vs9?"B}}? |Wrc>EC,h!ҕ,\>V%M _ˋ l㈱ȢFTEco1)*`KCKTJ' 5|;?ύ%$DF'&!$OHcPf``U{lw|l+-,O{kT2dsoV{:'s W-f^:Y")s:gg2Cx]QtfQ;}62gaMW U)4 nsTxQؕȋȂdRebu-f1T;[xusgL'Dc{ ;FOulF=q5I&g<;1%F-wg,hJ)՚!%ǤDDGth;z53jShM04'Y~g ݐf+ ,ISx+%.9>9>%^?SbȘpX<O1fާWSuʅޚL}Ej~2[e*2^[bNH,('ꩌdp=^QctjDI|QaU.-x*G*Y4ZC|l{CȦܧ/>Eu'j61,\7eY ^MY:YZUfT|t;'SBz;H dVD MlMu[u:fkTctv4 ibOo9"QiNF_k+{)Ql!0zq~\vB6G%-R,!S^zOeʔ&3/mb"]Rcґ~J*hg[:SҊY0J־鼜$ϖM/da汬#yjx6U߰/qo7QOBot3+|,١nļ$B>^̬Q3uvTR#e~IW7J156]8qWO~3 srSP%Gxd2?71ڄ( <1Fz؁)-j\憍g;TZӻM]Teɯ;iL-JEhl댒ڟ$6xpދw_\y-M_((+\S~CYU[P` TmBv X~1!ab=QgH#CyI,YT-*; cLȣK J+>o}LKIA1($:vP|p19Jt~^Jzӳ2+VȤ1%Hd1姠%KsP(QQU؄R7b&I Q] E>]c,d\)7*jO4;H|ÊP>>Baskc%9^eHflNߥ#,6C^p2?#Ra-=)e =+A8Z@y>> {I<Y; i50pl?TV!{g#e烂b|"k=FYYdszyYI5ƕ &zӘ&#Eqc;SR! bX"emTsj%^:=՘}9Y'^~~5u5u^S%5w?hNQ[X/Cmym'ywlsrεE6zֶv wF`Kp-&˶mYagW|5MEz>WS-VVƮ^/s1!!R'f6sHAEhͰdQp::*J"ϫ[Ԩ1P\c#n w^peTnZNjjrQFa*JBѨHi,A*)4Ӫ *{k[>͗#/tj2\(+)kB MUF79gzT8~)Z?_?=Wq3:Y{S,:g+ZNVwӣSr^孨kmtp;lb/ش5Y6}Б--iݗ_zzU5tm=sfLȻ34ᅥcrbfd[QC_u1fNWx!Ue78$t3(0!UΡRqQ8$ T1p`">(+@W8We+#X7)WU=hVU=UQ4a>ë??r]!1-k:O]nrC! WMa_Uf =9zЭ퐛G9=#))]P[DZ' ]מu>fl a!/ba衝h}ɹ>@l㒀P"b3O1uXzod1zHZG3,W "u^BJRezMQMMúЍ%[C G)t*CT$*Mߒvj9_%+ﰧʘe/T&ᚇη& g,<-ضwӔ{ (wxI2ԯȤ Vv :*ϠXhw]p8^I랸WrrʧO-x |qz{."rO%nYOgUt,h#FewV-[yQsj=%QՅ ͷΨ |eqNǯ󹵣~jlr"է90>5d)Zk+Q$xFFGGGE'ŲbhDU:I=Q Jd6CAvOzU֡T[ԋJz/swG%U}ؘsB%yͨ55.B"Ǝu充1Bax~lʤ{kbfo)mm=KkJkk*ԽT<*3/V>GC󘫣{q#>^b\3<sY5O8NmeKͧMcZ]K^-_y[-9k,4#gu/?0(01hV̋נQ/_#?4+E ŵQ7o {bz"1]| /2uYХ:TGaM՛n¶ YLo Ϛ9}V80p6b3gܭateē;vHsܐaoZ'2oi۷x#ǘ؄ev02fK`^ !Ze¯NP'8%Jvz %ɢVau}SqyXC?[U^JMNhB/2C$ bs3!yb>cS3ۣ:r9ͦ\:XQ%( f[oYs[U=%=tKk=h߽)Q&$IrPw~tHEeI$=>/6OʖTF|idIHQ "WVJs3NQizʌTAI 0/00<:NB9uCK!AiȇKG3C-#-ѵreXNCQpG懕d) 5 iiYiMyHXv6&|~|rLZTFdWwuB$(j̇Uq]n,cSSROܾ6JmY;ՇY{|7=jX>dZZ8 a-Az,(V$"VԒ_]Tjn~#+rRU HYSk2|qE(\X=ŕ4si?vN%VE2’&y6^! '6>#ڊEbDG]wūY13 ـ*kx0NeĿa l,R=2EK4VP%KѳW`quԥwj +wW_( K;׬k*:ޤVVTpa35UPxu 6yu-5ӟ7;R$qK$˔"EzfZf8W8^13+YBPtbL|85W_ԩ/#{qSx%,͉/fkU >!nBskY@ـƅ%~YzB"̕E(㠗.W{ʇ՗كIxß%~MxfO 9|/nx׆F5+;Cy.-((CbG$qdZr0SVR@y$C,(>柸=Iz083$-%!iunvJV]Qژ4;˳bs2`eZpt jc%_T^R :73zbc() -()hu=p8Wl! AOYsx ҈-q1:9C9#3RSS39)(.ž }Cm u7 ?);2Ogμ3Hxk{?0*;s*nWot,3܈y9ժx>PՇ˳y(򨯻O#:ԈJ7iZZʼ;1O/m|JɭmiVv~^S̼yƉ԰ǡpl]7>\6C&ٞmuuY- ѱT>3 )L"pqh(\UoSbjk W , "H ?C )%ii~/\9)_L(1 J/ ,(--ώ-V *ЉDE\DU¢€h!TkjM1 utvD:ؗg,/)% y0ݩu;|ݟ]q~!jP~gcͱjYH|||l@g N+W7`laѪ듭y pD"ؼa`;\xɾ9ݽHMHl 3xxZ{ĵ. f~:k[<;ٹ.{cxj e]@b؆#*zc׹?@sתzQXV92@qsKtc%rpf. K1]{/w75nآԍ*3˘~TӃSHF3\Z_Y|jPPsؚ1g/|Q r!!f3[\^kl3? ZȖ4ş ٖY#+|cdK=ף4x>~ZGյVAf 8u= 7ͫ<,.nx/6?鳪m8b!Jn]:ކΆ˻8^cfVry͟ď1(&X1¯t~==d]a>>#U/]ud[ (!*EزDZM)92K e!HWs`TcУ;gg.+m֔oAK!dFvЊj[œTӿiU_7`rBE$ D11L¨Xg*é~9HJϴ?>M<5\+Z'VePxן!=`޶A!SJ*M;B ^KT. r4gZt/T LT&3G1~|2 C#$Etq^@_z kwWW6SW(C(?N]`-F%ÎlwqŇ7'>e|ь#:"!F)[@;$_VTKF))Ĵ4J喖I}^ѰhZYXDdpZQGmu~m #7m3hFk⣣%QaW(nTJUI"G _:IZK6A.Ox&IE_p(f!:9"nd>_/hڎkeWio^ҁ ­]܇Q_}+|d߆qCy[>cɼ`*En!/]e{}x*/K/ C$GZ,!X`ޞ#ʾ&!9- xPخ{,!~Ҫ2PxYW$puy"  59$>6ɦ 6-\f!uvZ_QIRYR{u|WO=lB,ULǻJ# WD$A)F > `8qȅGE"bzk{'S{+y{.ҺX[Uj)J;aB5:L[GY~Lsq:K 쬈ej2zb PC֜*ajqg1vq))I9i52csmߞR]?/'XcV3 YGb7 ъIXh|Ifu 8} rrbs[y2c6Z `fLm7hrSoI\ݜFp)BZ>Lukr(5E^u>g1f.b-9F<#Z̋ŝP_Wiu$Ii~~SW]]9_JA"XlQG'GѸ'CP a^|+j5 t^\`Nτ*)^TŠ&Q]G(ѐ*:# >0i@.qõPl 34>@pYIUk5…^qהMuO4-ܣ?fnoefce%?i ߰F#jHIU"vs+=P:wi`" [(PĄn4;$'f~({l8srV?3rg(y~^I>IATob+w{n a"( 'h,COKq\L(?[tKLK9n` TfO{v ,X\;t{r/\G79ɚ7Zыt~I8TL{ K}oݯ{ҳf:Il)Luܺ~^w`vTudq5&+\53Sgj`axJ dgk,q- rxit:B2T!=PKW}/ʰg>G< &?>[㹷őt:G^ȑ0t".ӧe3Qi7݆=IO76n'G:M~^c*=z],V^}7_EأSYx!/G]Tt\#dvWDŽ̩'ҏjhݦz3k֘G~t៯:2Fdڵ|ټz/s=DY\ڟò7\\U듗5+߾BA_Xluz!)n Ȝx;Yǭ݅'8̹ޭf{LX5;WF{/`.o fg _¸7E_bث^I 0Dm#_/2drS 1 I[D1;,h%ZECmF^rr}Lt+ ?T j@ jH99G`֯P9yY#nt,D/?/X4C ]Pň JIymR+x!bvԊ3jş7<OwQ7uQGtQ?EtU8;\;^|_E8)Cozg^ϰg8g44Ę|Uhnf$n;p y0Xwn)@`-R$GL3A95τNyyV3A5=Ш֤/ ^1!ۏl?2{Ӌ}IwC8S'*b]*&b 6;ڄ|Czbbe }[<ѣWk=7apF'& #p9{xԥ֐y5>B 1>qCfC\Cj0A$*H;E,g)OxFc8H$`Z7^`y(%"2`_B{+WƱuzquΖV殆h)Z&611+r.C'QiN쥩\ɏtŕߩԤ ~9ZL68lp%3wj$\SS÷!/k?]я{c"=DOz&෮ڥҀ?x|mn9`-Wݵ lLMȴ*s٢2IZt|+ =H:=Ic?zTyEL$Jl[t@o;H}S '$+4xIJz!Hk\Tޥ!"؃/Rm&Jw|5 tH%^Lln"Z*V]W+_FFpUp ]:%:~ϖ&@3t7*4Iu`q.z@+AuB;0xhX%z<=R2O`WeMcOVSOH/% ~K*T7t#,#+@ǍO:1?4 \˪)vkujruA&A+ы6ZK\P gwC*7Mz0h:esLPW,B7[ o2(.Ey?Y(-]op,4 ȞxQw+P~->xr_ut[wwTh!y/wvuE<97F pL[RRq˕v,v˿,QJF|m]bGXS}O_6uLLhkrN}|0jo聙=1n HlB {' XÉ<=3#˿cg?96oVrt@=Ε ˁlCad>x|UbDw֚lX׻enclN9.9akB|(2"88D>Cb<0(Qsl^ #nbKA'k #){='cq ?Јsb>U -調`:g=FMam`r=.eZ~x^h;7 U 1IǑZXRۋ PPHN;QETTE#ntvG; =DWU'PKj_ RkHnɫ [RL>oN C}dt_y9X}z Z(v㔴m!>1]e,@MSlʂn& MRʔPheϭU{@gp T/I.xXEgj3)?~L^x`1Չ.4? .qPz{ RB,َ9}wg%z0I qw4,$#fi$t$4q _`4lj_qLsF k l;U"j`a?'B1_[%;iZ8"j`Ν=,NBuk"Oceye]$l俁O8iR&I-kJF DB+XM]hvcsᐻ*ϫ"LBID:XX;$:!!G)@I_TzJpgb~@x5}}+Pi3U OWyPĖ.e#})R]1A堚5 U\5 (I _-JHhMBJg'%f vd{imjR BHcIS˫a(a&|r|J U˞&Z Q8XOs- u~?J̰wWv>Q6s\tt\D떬FP8d3AAbB']EF\ɏH1q6\잜㛎E(*w;@g*b*MPxuM@MiÐ?yiCBjUZ&Xvic)Hb4aT$gVeiy{%fScc3ŦG$|.zG S|ICW. P;7tSݲ2~^R[ =ؤYB)RJx8Zc ip`NMiBbPHĻEkX盏J51 8h5}Ǜ"-V9:{2l?n]#lqVxdhByRb[k[*]Xkh[QIw"t,ŌP mNP8l'^Alҙװ2K!,=,X¸{/k؅g,Ox zxHNWTmVAV=)A%TSRlT l6o&{Ygas*)# 'N.3!(!YھGrg{j@YÑb*.*Ez%?.MvHO &o- *DZbd$<FQˊcuWXj[9fT,G)k_XS 7`I7^OSk;I:MjL,˪j ɘx!E4WSĪ$ ⛝dn*^ |yḃi09!8u{r3Q)[?ͭHӭfӗ؋jz_>z;o;m?_w8l # 1^uϮEuW6lsLP0 Nw&9`TS~5JyS&ۿlՔq@~d fkKmWWPˤ }*a?&o2RgӑP[31Pо:8F͜-ڳ=eе_"Ȧd ko-e]i簐y>')c ʪ=-n"}>~ ?3OMU#0 gv]6Vr-ªJv\& 1l^Ix>rp9yb5u .n XY]"ȕ0c?'u P>0Upv{Y[|;>X{q|ږànn6 nI*/M 2ų.DKя Lopy[eyexɘf!iklW{{Z+PaS'\fՎH~ k>7lM#x.!kyKNBB+R#qw `ک>uMF:kuĴHVa]q'x*1*. D.ZQ2lv q˱<":jflUt$-HKm ]ُ'jƷ{h_ hfVoֶV+8숤v!o-^(nZq} D-׃;S6 ӅJEeW+*RnXjٖӵ(r6TS̈iOC&FvW!3daCV}>4*5]S^C*DqIqI1-`(M sBn+S /QxHw]Te_ڹe2}eT'дY\aGޏj%WQ g+TEu!xہ'\F'P^v,VݾOoR2=Yj|HnZn5ggg݃7% F¦M݉߸-qVS-WZnBՒ yJ,> uG𝄆Pn |HyMrq+`ƷtN &}-0z=C8-RID,b[?݄ -1ƅ\s?_wGV;Q4"qKbr~#SxjOu\31m&N][|7"_-.y?*SPDkݞVz:i/O9hys@~k7qu5LoiJ!]w\W GeiKnT5&&>%IN@oV331"-kÍm6F}L!CY'/6V7ZȃS[0SPH0gWeu'ȇ[ʳ~s͊SB筇ewҥ? tމ9d[-NH $5۳E+ruux2P9,e//wwůi?\vєI^Wjx e2TW{W̓26k[~KӛfZ҄4dHO~N`Q<hԤϑ۸@aChKmjQXU#$/,&B;+[ MwYg6b V X [xw>yA] KaωނXB\ \J=#'GNA˙Ӳ3RS>0qy(sFf/SxIb,:,Om'ϰBiQRdZf-7 [yQ3ZeﲯB{3Π hOA.p <ƙAsM Y5#;-Jc7(FE>jZ%Ll)dlwo;I>8\SC!C ӥʕǼtN' ^sЧ'}K JBb)m"26 nB er2ca/i_;.M4$Xkݕ8Weq ~oxgszXZl]D9Au彛IFaЊ4f;Nt 1#BkF:ޣlW_d&3iwy4H?$[e', MΉQ t, A7b'\c󳶄iX9[#saÎb`pF(Rժ  -ni MmXs8GpuoOVcw( Ea"W{;xx$&>0a≼$U܈"!ܑ[E#[&\-1) WIת n~`btm! kSPy@s1ytO U1t{tZ{[]y؜CʆI:3UE.{"^Kq8s]J(لĠ %G(dw+tC޴ `n!tp-ZS6<+Rn]ql22a6x 5;P@ yH٨۩<ϳ0~R\0T:sWQ!jj)O2*'%OǠ0p|^ _<(l诀.7RРBQL4J/'\{q:r|0DL+G.XN'|"e4)(fKBN!f"Bt>A"AMsHOOң5cXks0+4^EIe~"Rd: ^ _ #pYz:| _w'"7h.Yw}]Q|)EQ16`jLLم-ZGoذx@iEa MrUQG92Q|.vuXSX .t{&Ւ(ِtROZO^ {kI rb}I!kM`,k ꪅ{q*F X񫲱v@abO^ܸ^ъe`W|k-<"V|~b>#1gu+砹̲; RSsm}}}} Dohx^fHQc{ MVE/Ӊ^l%&=!lGjK4DO!6)왢Sҧzݰ QVC^vi&~^?Aoj,YvUvVy<Σev*rjɱ*5rA X\#LxsXVWj'JcSңwj$Ɩ1 3:;;OJM{}zC!P΂:#ƥpF(X@#GX#=Ư;!ڋf(U*+)l%*63+%9+6RxΗP.,Ql [N^A@cAz¿guʘ1$]@]xɛ6#);z uW*[9U`$j'jOn ܇8*O-~\2ݿ$CiH_MAL5%8bڙZ074hϏGLO v} ѹ{2B#<#c]#}*̳O45\+y<-@['tS^ׅĺZ8[7bK\zflrjh{Xd(Oώ)*r['y ^?7:wsmժt~1%϶FtUqv%*W 7^$/-Q0Hw>~I{< z2/;bG5sIu,sxv*4 N8nup+[+T˽i)QI(qBDFDFH8)2^;v}gbRS WϝzzUƁc%fU&yO2OĔcn$/pn`R'E-ۙ eƋwn Bf7$/'094u gk6Q˙ omEZ)N*y{!v/6!/XHŗ|=iy^cHYd/7G;WFOh'[_gdxH,6%5>;=Y&t4]2Co"_yL /~$6Y3V`3~JԫW"T6ZN#;/31uçr-Fe z!{x=3t^8N^#:vuc7َ]Jw@G'D0mYH5ŒRN0M#r,vn.=$ә:Yh>b+[x8*KNPGV7f:+W;uk FX9z"5v3s j9($0PݡC5;?jGQYEk\̵AGg; HKG\I𡢝(okVo8.kh0j_loQ6jȧ. Q0l}aOfČHZ:W%]~~1惧9u*T$Gܽ5;-aVs԰iһ;eNpr07]P;$, lV*S<70`4Lß# %2 LNtY _V 9V(vD3rO2IiX pN)cEܑfh`+IhV,U,>C9Y3>)F=<(c>\ipJ3 ,T^Ҭ IG6yvDœ?H9"-͒ϫ86;)\ ~G>C;2te\an=-w׮ޱgڰJP_j3돐[j^\ 7x)ڲoچ!^ Ы=q4ʩ"T<>e H8D M)}cj2~S?xӻ@ȯu Pk4~LaS4*|Tv|VraZNe(r` 4T+ѦLyB`F[RYK^뤾d}g%)՗q}IphP$&j8Py4iYG)2ǴE /8[4ڪ(yS5 J=bB*R>_U{K M[Bɶ aL#"7g5!yBٖr|zRZw5#X)<̅#jU}b Drg}~ Դ[ER׽oW*ZYisr+p!VS/1 EF` 5E cIg>v+nde..=堨t|G?uÁ\<]td4,ًڽ(G / bӮ^IzۿyHbG/U8Iz0VJ>BM5vf-љN*8HBonZ)Fe1A6qWA#)٩wvBrU`8%4(w$.I`(LF0{)Ԅ[&@OW`Sr3v ^ߛ/t`zBQ@whOnq='NB88VhaZk8.5/CV.vٝǕ\=wTi4g>VIHm&xejUN)錪Ա::j -TU߿ע:>W`goR?>r}^,G8N]:>>sXoT$g]֪8}d\=O!OqbĤ t;Ѳ'h|;dF>3Qo+eM˻U2Y*+XNki! p )Tȶ;k`YprUwrD8L]RRow/'(% =}qsF - f-n&lJ[`dՙF[[t&8+; hr\wS0pxkW?Nn RԬnYc=K(}AĨ KűĤL76t{`2%FĦ_FВ3D:{C8o-Vr4SATފ\f|ImeVeJ;0הnWF/b5XBl,g c Ig@DlAZ(>2 .tq@~fM<]щF'2h04"t4uy|e!V ղJ= BWFy€rʴvzUjt>ж+Rv+fsGZB+ *xbpo*>(>ZyqV[h!&'-+mY{Q]ڦL| 4N>ԔzYn& &eP8j) j2PgJ"oF. 4n߮[s:.et/0|!a\sZh.SEk"vH43|JZ:ܕh%Zڂog KwEǑzh[`A`U~SJ`N^yU`7A~^.SlX8eDnނ Yc< >zEtohbo6F =a \E+@)l QרiY s MGK ?sfLJDkw9|3C?UPltGkIO=Բр >jG?ҸcyTt.ajQrϗ @ȋĀ^X~8N\}. \ mTEj0 Ļ5{UAà{>JTU&tH%2 t wZC?bjh0R{ݢcϦ_~ vϩtur9ߢhn ^a> o·sa#{=@ ,/r E|!`|GC4pJ$= DA:|Ӭ$=I'&5R*v5^깺ՙ ~RGճ!s]EDS-VAKgɤO~kle2aIb%DzA'(壯W?**Ffqz?W'Y.ގ|a]ff2B;Y!KKL%!˖Ck{P=;؆SpwyZAWi7/Aos_,u ߯%%k,{9ϻ&MMmJccS+I0p ]Q ,ѱ`A?!;bPGM]"KQ4hLjFe o;y"Ai ˲Yk`TZ&?5_K!; H$^"cim-j[Fd -%{fw`>ݩ#|[BLSUQ|(N3,!ID7aAL# "`j'cR}8\0s~aa›`S\+n¦c¦ׅ#eIß*۝ ^CZ*yczB|LBiȶ!%d]lt؝싂S0Y"R: CaA ֐-y6>zSk{F̮w[kI$E~g(ZJ)Z_:ƠKS%Z*^-~+4>?{(=ϵzml)i ZGBZZ;W,nP;IyGB?"Ne&o|zAU<6Л:or eA] / AΟرj/Iqk%yz*}UEOkE_TP^fNk/R=hIik":HMK[4\xv"jN"vƇJF Kt]ߣpݿwI)9J/ M5Cr?$->-B([q0jo聙=1\nE2&ɰD|\O#"=J+<;1qh~ 7\(!Y1I. ?z/"go,k!JZvjkcdR)y9?A&ݕ+:EʾYAr aWdDhIUBnwA`Sͮ3͟#ϣTy/ xޓ'3[6e,#؍z.cGKfDSͨӶc*1iңU˞GU[+E'iL9AzۺD<=UHtC.5ΨT:K?uϮՋ4>QK:./>+r`wIYU8ٔ{Kp81>*rҚra ~،KTp?"X%, wKﱕ+0%CX]vU3^7p}v~C6|h$Yq; ɱg{.weAv? #ڻ;]Wژ/NETudn]us_ endstream endobj 11 0 obj 33920 endobj 12 0 obj <> endobj 13 0 obj <> endobj 10 0 obj <> endobj 14 0 obj <> endobj 2 0 obj <>endobj xref 0 15 0000000000 65535 f 0000001505 00000 n 0000037027 00000 n 0000001446 00000 n 0000001553 00000 n 0000001295 00000 n 0000000015 00000 n 0000001275 00000 n 0000001836 00000 n 0000001622 00000 n 0000035925 00000 n 0000035841 00000 n 0000035863 00000 n 0000035893 00000 n 0000036969 00000 n trailer << /Size 15 /Root 1 0 R /Info 2 0 R >> startxref 37077 %%EOF Csdp-6.2.0/doc/example.c0000644000175200017520000003021610470505023013420 0ustar coincoin/* An example showing how to call the easy_sdp() interface to CSDP. In this example, we solve the problem max tr(C*X) tr(A1*X)=1 tr(A2*X)=2 X >= 0 (X is PSD) where C=[2 1 1 2 3 0 1 0 2 0 1 0 3 0 0] A1=[3 1 1 3 0 0 0 0 0 0 0 0 0 1 0] A2=[0 0 0 0 3 0 1 0 4 0 1 0 5 0 1] Notice that all of the matrices have block diagonal structure. The first block is of size 2x2. The second block is of size 3x3. The third block is a diagonal block of size 2. */ /* * These standard declarations for the C library are needed. */ #include #include /* * Include CSDP declarations so that we'll know the calling interfaces. */ #include "declarations.h" /* * The main program. Setup data structures with the problem data, write * the problem out in SDPA sparse format, and then solve the problem. */ int main() { /* * The problem and solution data. */ struct blockmatrix C; double *b; struct constraintmatrix *constraints; /* * Storage for the initial and final solutions. */ struct blockmatrix X,Z; double *y; double pobj,dobj; /* * blockptr will be used to point to blocks in constraint matrices. */ struct sparseblock *blockptr; /* * A return code for the call to easy_sdp(). */ int ret; /* * The first major task is to setup the C matrix and right hand side b. */ /* * First, allocate storage for the C matrix. We have three blocks, but * because C starts arrays with index 0, we have to allocate space for * four blocks- we'll waste the 0th block. Notice that we check to * make sure that the malloc succeeded. */ C.nblocks=3; C.blocks=(struct blockrec *)malloc(4*sizeof(struct blockrec)); if (C.blocks == NULL) { printf("Couldn't allocate storage for C!\n"); exit(1); }; /* * Setup the first block. */ C.blocks[1].blockcategory=MATRIX; C.blocks[1].blocksize=2; C.blocks[1].data.mat=(double *)malloc(2*2*sizeof(double)); if (C.blocks[1].data.mat == NULL) { printf("Couldn't allocate storage for C!\n"); exit(1); }; /* * Put the entries into the first block. */ C.blocks[1].data.mat[ijtok(1,1,2)]=2.0; C.blocks[1].data.mat[ijtok(1,2,2)]=1.0; C.blocks[1].data.mat[ijtok(2,1,2)]=1.0; C.blocks[1].data.mat[ijtok(2,2,2)]=2.0; /* * Setup the second block. */ C.blocks[2].blockcategory=MATRIX; C.blocks[2].blocksize=3; C.blocks[2].data.mat=(double *)malloc(3*3*sizeof(double)); if (C.blocks[2].data.mat == NULL) { printf("Couldn't allocate storage for C!\n"); exit(1); }; /* * Put the entries into the second block. */ C.blocks[2].data.mat[ijtok(1,1,3)]=3.0; C.blocks[2].data.mat[ijtok(1,2,3)]=0.0; C.blocks[2].data.mat[ijtok(1,3,3)]=1.0; C.blocks[2].data.mat[ijtok(2,1,3)]=0.0; C.blocks[2].data.mat[ijtok(2,2,3)]=2.0; C.blocks[2].data.mat[ijtok(2,3,3)]=0.0; C.blocks[2].data.mat[ijtok(3,1,3)]=1.0; C.blocks[2].data.mat[ijtok(3,2,3)]=0.0; C.blocks[2].data.mat[ijtok(3,3,3)]=3.0; /* * Setup the third block. Note that we have to allocate space for 3 * entries because C starts array indexing with 0 rather than 1. */ C.blocks[3].blockcategory=DIAG; C.blocks[3].blocksize=2; C.blocks[3].data.vec=(double *)malloc((2+1)*sizeof(double)); if (C.blocks[3].data.vec == NULL) { printf("Couldn't allocate storage for C!\n"); exit(1); }; /* * Put the entries into the third block. */ C.blocks[3].data.vec[1]=0.0; C.blocks[3].data.vec[2]=0.0; /* * Allocate storage for the right hand side, b. */ b=(double *)malloc((2+1)*sizeof(double)); if (b==NULL) { printf("Failed to allocate storage for a!\n"); exit(1); }; /* * Fill in the entries in b. */ b[1]=1.0; b[2]=2.0; /* * The next major step is to setup the two constraint matrices A1 and A2. * Again, because C indexing starts with 0, we have to allocate space for * one more constraint. constraints[0] is not used. */ constraints=(struct constraintmatrix *)malloc( (2+1)*sizeof(struct constraintmatrix)); if (constraints==NULL) { printf("Failed to allocate storage for constraints!\n"); exit(1); }; /* * Setup the A1 matrix. Note that we start with block 3 of A1 and then * do block 1 of A1. We do this in this order because the blocks will * be inserted into the linked list of A1 blocks in reverse order. */ /* * Terminate the linked list with a NULL pointer. */ constraints[1].blocks=NULL; /* * Now, we handle block 3 of A1. */ /* * Allocate space for block 3 of A1. */ blockptr=(struct sparseblock *)malloc(sizeof(struct sparseblock)); if (blockptr==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; /* * Initialize block 3. */ blockptr->blocknum=3; blockptr->blocksize=2; blockptr->constraintnum=1; blockptr->next=NULL; blockptr->nextbyblock=NULL; blockptr->entries=(double *) malloc((1+1)*sizeof(double)); if (blockptr->entries==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; blockptr->iindices=(int *) malloc((1+1)*sizeof(int)); if (blockptr->iindices==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; blockptr->jindices=(int *) malloc((1+1)*sizeof(int)); if (blockptr->jindices==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; /* * We have 1 nonzero entry in the upper triangle of block 3 of A1. */ blockptr->numentries=1; /* * The entry in the 1,1 position of block 3 of A1 is 1.0 */ blockptr->iindices[1]=1; blockptr->jindices[1]=1; blockptr->entries[1]=1.0; /* * Note that the entry in the 2,2 position of block 3 of A1 is 0, * So we don't store anything for it. */ /* * Insert block 3 into the linked list of A1 blocks. */ blockptr->next=constraints[1].blocks; constraints[1].blocks=blockptr; /* * Now, we handle block 1. */ /* * Allocate space for block 1. */ blockptr=(struct sparseblock *)malloc(sizeof(struct sparseblock)); if (blockptr==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; /* * Initialize block 1. */ blockptr->blocknum=1; blockptr->blocksize=2; blockptr->constraintnum=1; blockptr->next=NULL; blockptr->nextbyblock=NULL; blockptr->entries=(double *) malloc((3+1)*sizeof(double)); if (blockptr->entries==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; blockptr->iindices=(int *) malloc((3+1)*sizeof(int)); if (blockptr->iindices==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; blockptr->jindices=(int *) malloc((3+1)*sizeof(int)); if (blockptr->jindices==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; /* * We have 3 nonzero entries in the upper triangle of block 1 of A1. */ blockptr->numentries=3; /* * The entry in the 1,1 position of block 1 of A1 is 3.0 */ blockptr->iindices[1]=1; blockptr->jindices[1]=1; blockptr->entries[1]=3.0; /* * The entry in the 1,2 position of block 1 of A1 is 1.0 */ blockptr->iindices[2]=1; blockptr->jindices[2]=2; blockptr->entries[2]=1.0; /* * The entry in the 2,2 position of block 1 of A1 is 3.0 */ blockptr->iindices[3]=2; blockptr->jindices[3]=2; blockptr->entries[3]=3.0; /* * Note that we don't have to store the 2,1 entry- this is assumed to be * equal to the 1,2 entry. */ /* * Insert block 1 into the linked list of A1 blocks. */ blockptr->next=constraints[1].blocks; constraints[1].blocks=blockptr; /* * Note that the second block of A1 is 0, so we didn't store anything for it. */ /* * Setup the A2 matrix. This time, there are nonzero entries in block 3 * and block 2. We start with block 3 of A2 and then do block 1 of A2. */ /* * Terminate the linked list with a NULL pointer. */ constraints[2].blocks=NULL; /* * First, we handle block 3 of A2. */ /* * Allocate space for block 3 of A2. */ blockptr=(struct sparseblock *)malloc(sizeof(struct sparseblock)); if (blockptr==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; /* * Initialize block 3. */ blockptr->blocknum=3; blockptr->blocksize=2; blockptr->constraintnum=2; blockptr->next=NULL; blockptr->nextbyblock=NULL; blockptr->entries=(double *) malloc((1+1)*sizeof(double)); if (blockptr->entries==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; blockptr->iindices=(int *) malloc((1+1)*sizeof(int)); if (blockptr->iindices==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; blockptr->jindices=(int *) malloc((1+1)*sizeof(int)); if (blockptr->jindices==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; /* * We have 1 nonzero entry in the upper triangle of block 3 of A2. */ blockptr->numentries=1; /* * The entry in the 2,2 position of block 3 of A2 is 1.0 */ blockptr->iindices[1]=2; blockptr->jindices[1]=2; blockptr->entries[1]=1.0; /* * Insert block 3 into the linked list of A2 blocks. */ blockptr->next=constraints[2].blocks; constraints[2].blocks=blockptr; /* * Now, we handle block 2. */ /* * Allocate space for block 2. */ blockptr=(struct sparseblock *)malloc(sizeof(struct sparseblock)); if (blockptr==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; /* * Initialize block 2. */ blockptr->blocknum=2; blockptr->blocksize=3; blockptr->constraintnum=2; blockptr->next=NULL; blockptr->nextbyblock=NULL; blockptr->entries=(double *) malloc((4+1)*sizeof(double)); if (blockptr->entries==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; blockptr->iindices=(int *) malloc((4+1)*sizeof(int)); if (blockptr->iindices==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; blockptr->jindices=(int *) malloc((4+1)*sizeof(int)); if (blockptr->jindices==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; /* * We have 4 nonzero entries in the upper triangle of block 2 of A2. */ blockptr->numentries=4; /* * The entry in the 1,1 position of block 2 of A2 is 3.0 */ blockptr->iindices[1]=1; blockptr->jindices[1]=1; blockptr->entries[1]=3.0; /* * The entry in the 2,2 position of block 2 of A2 is 4.0 */ blockptr->iindices[2]=2; blockptr->jindices[2]=2; blockptr->entries[2]=4.0; /* * The entry in the 3,3 position of block 2 of A2 is 5.0 */ blockptr->iindices[3]=3; blockptr->jindices[3]=3; blockptr->entries[3]=5.0; /* * The entry in the 1,3 position of block 2 of A2 is 1.0 */ blockptr->iindices[4]=1; blockptr->jindices[4]=3; blockptr->entries[4]=1.0; /* * Note that we don't store the 0 entries and entries below the diagonal! */ /* * Insert block 2 into the linked list of A2 blocks. */ blockptr->next=constraints[2].blocks; constraints[2].blocks=blockptr; /* * At this point, we have all of the problem data setup. */ /* * Write the problem out in SDPA sparse format. */ write_prob("prob.dat-s",7,2,C,b,constraints); /* * Create an initial solution. This allocates space for X, y, and Z, * and sets initial values. */ initsoln(7,2,C,b,constraints,&X,&y,&Z); /* * Solve the problem. */ ret=easy_sdp(7,2,C,b,constraints,0.0,&X,&y,&Z,&pobj,&dobj); if (ret == 0) printf("The objective value is %.7e \n",(dobj+pobj)/2); else printf("SDP failed.\n"); free_prob(7,2,C,b,constraints,X,y,Z); exit(0); } Csdp-6.2.0/doc/README0000644000175200017520000000034210470506736012512 0ustar coincoinThis directory contains the PDF output and LaTeX source for the CSDP User's Guide, together with some figures used in the guide. There should be no need to run pdflatex on the source since the .pdf file is already available. Csdp-6.2.0/doc/constraints.eps0000644000175200017520000001723510470505023014707 0ustar coincoin%!PS-Adobe-2.0 EPSF-2.0 %%Title: constraints.fig %%Creator: fig2dev Version 3.2 Patchlevel 5-alpha5 %%CreationDate: Thu Aug 10 21:59:32 2006 %%For: brian@bullwinkle (brian,,,) %%BoundingBox: 0 0 320 131 %Magnification: 1.0000 %%EndComments /$F2psDict 200 dict def $F2psDict begin $F2psDict /mtrx matrix put /col-1 {0 setgray} bind def /col0 {0.000 0.000 0.000 srgb} bind def /col1 {0.000 0.000 1.000 srgb} bind def /col2 {0.000 1.000 0.000 srgb} bind def /col3 {0.000 1.000 1.000 srgb} bind def /col4 {1.000 0.000 0.000 srgb} bind def /col5 {1.000 0.000 1.000 srgb} bind def /col6 {1.000 1.000 0.000 srgb} bind def /col7 {1.000 1.000 1.000 srgb} bind def /col8 {0.000 0.000 0.560 srgb} bind def /col9 {0.000 0.000 0.690 srgb} bind def /col10 {0.000 0.000 0.820 srgb} bind def /col11 {0.530 0.810 1.000 srgb} bind def /col12 {0.000 0.560 0.000 srgb} bind def /col13 {0.000 0.690 0.000 srgb} bind def /col14 {0.000 0.820 0.000 srgb} bind def /col15 {0.000 0.560 0.560 srgb} bind def /col16 {0.000 0.690 0.690 srgb} bind def /col17 {0.000 0.820 0.820 srgb} bind def /col18 {0.560 0.000 0.000 srgb} bind def /col19 {0.690 0.000 0.000 srgb} bind def /col20 {0.820 0.000 0.000 srgb} bind def /col21 {0.560 0.000 0.560 srgb} bind def /col22 {0.690 0.000 0.690 srgb} bind def /col23 {0.820 0.000 0.820 srgb} bind def /col24 {0.500 0.190 0.000 srgb} bind def /col25 {0.630 0.250 0.000 srgb} bind def /col26 {0.750 0.380 0.000 srgb} bind def /col27 {1.000 0.500 0.500 srgb} bind def /col28 {1.000 0.630 0.630 srgb} bind def /col29 {1.000 0.750 0.750 srgb} bind def /col30 {1.000 0.880 0.880 srgb} bind def /col31 {1.000 0.840 0.000 srgb} bind def end save newpath 0 131 moveto 0 0 lineto 320 0 lineto 320 131 lineto closepath clip newpath -55.7 171.5 translate 1 -1 scale /cp {closepath} bind def /ef {eofill} bind def /gr {grestore} bind def /gs {gsave} bind def /sa {save} bind def /rs {restore} bind def /l {lineto} bind def /m {moveto} bind def /rm {rmoveto} bind def /n {newpath} bind def /s {stroke} bind def /sh {show} bind def /slc {setlinecap} bind def /slj {setlinejoin} bind def /slw {setlinewidth} bind def /srgb {setrgbcolor} bind def /rot {rotate} bind def /sc {scale} bind def /sd {setdash} bind def /ff {findfont} bind def /sf {setfont} bind def /scf {scalefont} bind def /sw {stringwidth} bind def /tr {translate} bind def /tnt {dup dup currentrgbcolor 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} bind def /shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul 4 -2 roll mul srgb} bind def /reencdict 12 dict def /ReEncode { reencdict begin /newcodesandnames exch def /newfontname exch def /basefontname exch def /basefontdict basefontname findfont def /newfont basefontdict maxlength dict def basefontdict { exch dup /FID ne { dup /Encoding eq { exch dup length array copy newfont 3 1 roll put } { exch newfont 3 1 roll put } ifelse } { pop pop } ifelse } forall newfont /FontName newfontname put newcodesandnames aload pop 128 1 255 { newfont /Encoding get exch /.notdef put } for newcodesandnames length 2 idiv { newfont /Encoding get 3 1 roll put } repeat newfontname newfont definefont pop end } def /isovec [ 8#055 /minus 8#200 /grave 8#201 /acute 8#202 /circumflex 8#203 /tilde 8#204 /macron 8#205 /breve 8#206 /dotaccent 8#207 /dieresis 8#210 /ring 8#211 /cedilla 8#212 /hungarumlaut 8#213 /ogonek 8#214 /caron 8#220 /dotlessi 8#230 /oe 8#231 /OE 8#240 /space 8#241 /exclamdown 8#242 /cent 8#243 /sterling 8#244 /currency 8#245 /yen 8#246 /brokenbar 8#247 /section 8#250 /dieresis 8#251 /copyright 8#252 /ordfeminine 8#253 /guillemotleft 8#254 /logicalnot 8#255 /hyphen 8#256 /registered 8#257 /macron 8#260 /degree 8#261 /plusminus 8#262 /twosuperior 8#263 /threesuperior 8#264 /acute 8#265 /mu 8#266 /paragraph 8#267 /periodcentered 8#270 /cedilla 8#271 /onesuperior 8#272 /ordmasculine 8#273 /guillemotright 8#274 /onequarter 8#275 /onehalf 8#276 /threequarters 8#277 /questiondown 8#300 /Agrave 8#301 /Aacute 8#302 /Acircumflex 8#303 /Atilde 8#304 /Adieresis 8#305 /Aring 8#306 /AE 8#307 /Ccedilla 8#310 /Egrave 8#311 /Eacute 8#312 /Ecircumflex 8#313 /Edieresis 8#314 /Igrave 8#315 /Iacute 8#316 /Icircumflex 8#317 /Idieresis 8#320 /Eth 8#321 /Ntilde 8#322 /Ograve 8#323 /Oacute 8#324 /Ocircumflex 8#325 /Otilde 8#326 /Odieresis 8#327 /multiply 8#330 /Oslash 8#331 /Ugrave 8#332 /Uacute 8#333 /Ucircumflex 8#334 /Udieresis 8#335 /Yacute 8#336 /Thorn 8#337 /germandbls 8#340 /agrave 8#341 /aacute 8#342 /acircumflex 8#343 /atilde 8#344 /adieresis 8#345 /aring 8#346 /ae 8#347 /ccedilla 8#350 /egrave 8#351 /eacute 8#352 /ecircumflex 8#353 /edieresis 8#354 /igrave 8#355 /iacute 8#356 /icircumflex 8#357 /idieresis 8#360 /eth 8#361 /ntilde 8#362 /ograve 8#363 /oacute 8#364 /ocircumflex 8#365 /otilde 8#366 /odieresis 8#367 /divide 8#370 /oslash 8#371 /ugrave 8#372 /uacute 8#373 /ucircumflex 8#374 /udieresis 8#375 /yacute 8#376 /thorn 8#377 /ydieresis] def /Times-Roman /Times-Roman-iso isovec ReEncode /DrawEllipse { /endangle exch def /startangle exch def /yrad exch def /xrad exch def /y exch def /x exch def /savematrix mtrx currentmatrix def x y tr xrad yrad sc 0 0 1 startangle endangle arc closepath savematrix setmatrix } def /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def /$F2psEnd {$F2psEnteredState restore end} def $F2psBegin 10 setmiterlimit 0 slj 0 slc 0.06299 0.06299 sc % % Fig objects follow % % % here starts figure with depth 50 % Ellipse 7.500 slw n 1710 2430 90 90 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr % Ellipse n 1710 1710 90 90 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr % Polyline 0 slj 0 slc 15.000 slw n 1350 675 m 1350 2700 l 2025 2700 l 2025 675 l 1350 675 l cp gs col0 s gr % Polyline 7.500 slw n 1350 1350 m 2025 1350 l gs col0 s gr % Polyline n 1350 2025 m 2025 2025 l gs col0 s gr % Polyline n 3060 1440 m 4140 1440 l 4140 1980 l 3060 1980 l cp gs col0 s gr % Polyline n 3060 2160 m 4140 2160 l 4140 2700 l 3060 2700 l cp gs col0 s gr % Polyline n 4860 2160 m 5940 2160 l 5940 2700 l 4860 2700 l cp gs col0 s gr % Polyline n 4860 1440 m 5940 1440 l 5940 1980 l 4860 1980 l cp gs col0 s gr % Polyline gs clippath 2908 1740 m 3075 1740 l 3075 1680 l 2908 1680 l 2908 1680 l 3028 1710 l 2908 1740 l cp eoclip n 1710 1710 m 3060 1710 l gs col0 s gr gr % arrowhead n 2908 1740 m 3028 1710 l 2908 1680 l 2908 1740 l cp gs 0.00 setgray ef gr col0 s % Polyline gs clippath 4708 1740 m 4875 1740 l 4875 1680 l 4708 1680 l 4708 1680 l 4828 1710 l 4708 1740 l cp eoclip n 4140 1710 m 4860 1710 l gs col0 s gr gr % arrowhead n 4708 1740 m 4828 1710 l 4708 1680 l 4708 1740 l cp gs 0.00 setgray ef gr col0 s % Polyline gs clippath 2908 2460 m 3075 2460 l 3075 2400 l 2908 2400 l 2908 2400 l 3028 2430 l 2908 2460 l cp eoclip n 1710 2430 m 3060 2430 l gs col0 s gr gr % arrowhead n 2908 2460 m 3028 2430 l 2908 2400 l 2908 2460 l cp gs 0.00 setgray ef gr col0 s % Polyline gs clippath 4708 2460 m 4875 2460 l 4875 2400 l 4708 2400 l 4708 2400 l 4828 2430 l 4708 2460 l cp eoclip n 4140 2430 m 4860 2430 l gs col0 s gr gr % arrowhead n 4708 2460 m 4828 2430 l 4708 2400 l 4708 2460 l cp gs 0.00 setgray ef gr col0 s /Times-Roman-iso ff 285.75 scf sf 3150 2475 m gs 1 -1 sc (Block 2) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 4950 2475 m gs 1 -1 sc (Block 3) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 3150 1800 m gs 1 -1 sc (Block 1) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 4950 1800 m gs 1 -1 sc (Block 3) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 1620 1170 m gs 1 -1 sc (--) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 900 1800 m gs 1 -1 sc (A1) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 900 2520 m gs 1 -1 sc (A2) col0 sh gr % here ends figure; $F2psEnd rs showpage %%Trailer %EOF Csdp-6.2.0/doc/constraints.pdf0000644000175200017520000011010710470505023014661 0ustar coincoin%PDF-1.3 %쏢 6 0 obj <> stream xVr0 )|vf%[9n\ J,GNb;l--{!k},Q@mo^s/!:U٨x&$(^!b8oG)B]O1Iy"Cp#$V9bxޗD ̼kf0Vitq)~K48L>9qh;W-j1Ou{v9B%p.^dz耂}~ָ8z޲EBb_3"Vh$! hi$=Gb4[5!6ҁ/&gn2-!^Y2?ݓ͑-a% UI$!%IJiXõ>+phMZvSk l/V*j zZ3ZaJV"VIE^g%r?ڨI;kQo+ l/RAWRK,E cܬ6*7Mz`(=[j9s[ LģD-"I-Nc5@C+C=Wʰ~xAv p8<^g7<_eRwA4L\͊]ш?#$\>0wA,SԻ"MoUXMendstream endobj 7 0 obj 670 endobj 5 0 obj <> /Contents 6 0 R >> endobj 3 0 obj << /Type /Pages /Kids [ 5 0 R ] /Count 1 >> endobj 1 0 obj <> endobj 4 0 obj <> endobj 9 0 obj <> endobj 8 0 obj <>stream x{XWYvg$ɮ^E^P.e,.tKw kbPL4ŴdgYI|{<{ιNKx^zj*zT}aV1n̋8o|ʤuWo?qۄ% %xO+~QKL$ӉXOl&v5aOD&ODO .wO//$|SɏrFZIgқQdAd#N3kgrLrfsrsqs,9v q28 N9͹¹%fR2jKS;CS2*J)%UAP)*u^P*wh=֧zmD7;hKږ>B>t0FIt&K%&~LMOJjsuj^T{ڻkvזh˵Ss+۴{OhӾ}GSϵ~OMwuLיc\gH'HGt2tuJtut:utN\Թs_gX+t~a&'=a'̟dŠ 'l( swu 6j9biGBƟL3uww6)rX9m#;qg4''g'}6{8gp崝^~ܽ]ܽB9x;M0YM=/dRw?gt:?m1L35ODΞޢg@OOݑr.vsvp9._TΎcǍ~"oDZ#~b֏]ǎ[D,^]upqw_l``d>,YwKC#͇K\EZ{2^l(be6&ͫG D#q㼗,e;_`qK=%36)<;͹o?үWTWG,`L`![ fG6J0a/l0,` ,fl0v0ã6rְ61+`Pn`m`Ӏ:p>`'8* o=xHop5)hMv(36pA }xx ,H0ȆDrHHH(HhHHXȀ8ȄxP=.C'M-8J n8PU0 w BC ) 4Cr:9I"gsȹ\H." Ť!\J1iB Wr-\On 7Ln!9I"w{ȽiIZҚ!mɃy'ґt"Iҕt#ɣIzޤ!}I?ҟ  2! % #RNFQd4Cƒqd<@&L"2L# 2"2#IY@E,&KR,'+J&kZ'Fl&[Vl';N&{^'AyxGׂ0waZ|  ӭaz X3Ì09|Lf.0fY0fٛa~ saN ̝ sa̽ 6<3 w| hXX‚oaX8 ``=za*,aX!,퀥h!߰,/`c$ LvI `VaX:V߆5`3X:Xo \ؠf8n20;¦0lͿÖuE`) |.쨃$쌀kv=`OeSK8 7,*`_ a4xz:XnY 6l[]vOP!}o8<#ih ߁Npjp N/Y9\v]p5Q~ 0t<w8v[ s8pr<CP8 P:Q8gfÙpζ9]8 p!\Xv8 , .o%\ z`z ܘ 7uf n~"}XpW<4>GV1<>sϾao?I YB^tw[}1?ǙMxy^?~og `~w߇L0O`T̆?d/O"  `Z oqDFJqG大/'n |,@*qs 1Fކ&ʋB7JIL݉ɓ!3zt7ۂd b7}Jy&YuY/8ogf&英 ΫMObm.V:d">DK8 |LjL3܉x_AD}|fW_-0NɏC9HѕL+#220"SyL^J«ںI4\% P L3$D tRdB5e4M9DWgImLFR즠JsQ3D{n22X9)(\4@S<%7 R6!,[*n sTӱ/ n~ڜ-L Re)6]E*yBi/kT+jcI%##sLw2  iD+ezgw>BXِTd"wR=f1ceal܁8֬2%'5$!Oe5=BBnIH WxPIKf>X*=<o8RD-%[U3Lu?jM!U,pڐ&G7inyywYRh2J26bޣؼpKdbv^Z*)C?ҪYN&,bт;qnX9Kr&6Sñhh}Xq)Y\_܃QwHgWOy%%nSEc 2<ì0__f)|ڿ| rr 96z!b$#K!a꼭} ,PjJ-ZCR1a}=pT<-eV(! xrtWzb+VVK% 1f곙xW,}˼+ c>`6sr)o`m߅5),'8x_xqn+T]bm%nP*3)e"%K~DP>9Bkәw.Fv Z(::\'F'-s}1{YhX+'F!$ 23 =f6()Yɩ($8iS dR@rA J0YxgWc9Q"WsBrId**йe^~v~jk*K;\L)"eYh|IUb.VBQ >Rɂ[e\M i/qx1A(IS6֙ 2aiy!bHs۾va.tHzӭ^HYna>ǃ r^"^5ܤ8d]i~VRBtcpԍ@#"vJWcxrE/;Y|m/ZY S1VAna}c/>gZ4lcsB˛ՋzC=N-@;lSH?_@ۡ}*r{GVe>kt -hKu m [;=q 藆 .m@_z=|![Ȕy"Yr{Ub1:G8x{ORD;IjR$C'~GU/켲2cX%Lb͙n!Ni,-enT&u?U}Am`>#0yTh'D>5AZ9q񅺣[6Ϊ'>cu Ӽ3ʺ֒|w7W^2eQY}||Q+iGUQxIJDKx"OKi;Ts%U> :U~<:e>5KZ)DeFzԌBˣk5iU4ݦUAZf22 ?ۚeIMւ:cV"5 ؔTHcR",Ϙ.^8i,L":Ȃx!UW TtO+VYUIT-1#ns2TS)YI 2)Ϊ.ZAmN(iR]UYA,'&ꆠbwSl[?V+ѶIg~Ud]FuTo[C-8#0S''͗U-^~yBqH$&wX0 FA.c˔}쿽󸠵 ;ק0t}~Y74Uef%f$ eB^b:jA튺jED5ezo$f_5Yp.4RU (r˵CN.?2fE#=>KYٽkyͅw~5tGlD 9&g oY][< jTc9B&ϓE?vs9?"B}}? |Wrc>EC,h!ҕ,\>V%M _ˋ l㈱ȢFTEco1)*`KCKTJ' 5|;?ύ%$DF'&!$OHcPf``U{lw|l+-,O{kT2dsoV{:'s W-f^:Y")s:gg2Cx]QtfQ;}62gaMW U)4 nsTxQؕȋȂdRebu-f1T;[xusgL'Dc{ ;FOulF=q5I&g<;1%F-wg,hJ)՚!%ǤDDGth;z53jShM04'Y~g ݐf+ ,ISx+%.9>9>%^?SbȘpX<O1fާWSuʅޚL}Ej~2[e*2^[bNH,('ꩌdp=^QctjDI|QaU.-x*G*Y4ZC|l{CȦܧ/>Eu'j61,\7eY ^MY:YZUfT|t;'SBz;H dVD MlMu[u:fkTctv4 ibOo9"QiNF_k+{)Ql!0zq~\vB6G%-R,!S^zOeʔ&3/mb"]Rcґ~J*hg[:SҊY0J־鼜$ϖM/da汬#yjx6U߰/qo7QOBot3+|,١nļ$B>^̬Q3uvTR#e~IW7J156]8qWO~3 srSP%Gxd2?71ڄ( <1Fz؁)-j\憍g;TZӻM]Teɯ;iL-JEhl댒ڟ$6xpދw_\y-M_((+\S~CYU[P` TmBv X~1!ab=QgH#CyI,YT-*; cLȣK J+>o}LKIA1($:vP|p19Jt~^Jzӳ2+VȤ1%Hd1姠%KsP(QQU؄R7b&I Q] E>]c,d\)7*jO4;H|ÊP>>Baskc%9^eHflNߥ#,6C^p2?#Ra-=)e =+A8Z@y>> {I<Y; i50pl?TV!{g#e烂b|"k=FYYdszyYI5ƕ &zӘ&#Eqc;SR! bX"emTsj%^:=՘}9Y'^~~5u5u^S%5w?hNQ[X/Cmym'ywlsrεE6zֶv wF`Kp-&˶mYagW|5MEz>WS-VVƮ^/s1!!R'f6sHAEhͰdQp::*J"ϫ[Ԩ1P\c#n w^peTnZNjjrQFa*JBѨHi,A*)4Ӫ *{k[>͗#/tj2\(+)kB MUF79gzT8~)Z?_?=Wq3:Y{S,:g+ZNVwӣSr^孨kmtp;lb/ش5Y6}Б--iݗ_zzU5tm=sfLȻ34ᅥcrbfd[QC_u1fNWx!Ue78$t3(0!UΡRqQ8$ T1p`">(+@W8We+#X7)WU=hVU=UQ4a>ë??r]!1-k:O]nrC! WMa_Uf =9zЭ퐛G9=#))]P[DZ' ]מu>fl a!/ba衝h}ɹ>@l㒀P"b3O1uXzod1zHZG3,W "u^BJRezMQMMúЍ%[C G)t*CT$*Mߒvj9_%+ﰧʘe/T&ᚇη& g,<-ضwӔ{ (wxI2ԯȤ Vv :*ϠXhw]p8^I랸WrrʧO-x |qz{."rO%nYOgUt,h#FewV-[yQsj=%QՅ ͷΨ |eqNǯ󹵣~jlr"է90>5d)Zk+Q$xFFGGGE'ŲbhDU:I=Q Jd6CAvOzU֡T[ԋJz/swG%U}ؘsB%yͨ55.B"Ǝu充1Bax~lʤ{kbfo)mm=KkJkk*ԽT<*3/V>GC󘫣{q#>^b\3<sY5O8NmeKͧMcZ]K^-_y[-9k,4#gu/?0(01hV̋נQ/_#?4+E ŵQ7o {bz"1]| /2uYХ:TGaM՛n¶ YLo Ϛ9}V80p6b3gܭateē;vHsܐaoZ'2oi۷x#ǘ؄ev02fK`^ !Ze¯NP'8%Jvz %ɢVau}SqyXC?[U^JMNhB/2C$ bs3!yb>cS3ۣ:r9ͦ\:XQ%( f[oYs[U=%=tKk=h߽)Q&$IrPw~tHEeI$=>/6OʖTF|idIHQ "WVJs3NQizʌTAI 0/00<:NB9uCK!AiȇKG3C-#-ѵreXNCQpG懕d) 5 iiYiMyHXv6&|~|rLZTFdWwuB$(j̇Uq]n,cSSROܾ6JmY;ՇY{|7=jX>dZZ8 a-Az,(V$"VԒ_]Tjn~#+rRU HYSk2|qE(\X=ŕ4si?vN%VE2’&y6^! '6>#ڊEbDG]wūY13 ـ*kx0NeĿa l,R=2EK4VP%KѳW`quԥwj +wW_( K;׬k*:ޤVVTpa35UPxu 6yu-5ӟ7;R$qK$˔"EzfZf8W8^13+YBPtbL|85W_ԩ/#{qSx%,͉/fkU >!nBskY@ـƅ%~YzB"̕E(㠗.W{ʇ՗كIxß%~MxfO 9|/nx׆F5+;Cy.-((CbG$qdZr0SVR@y$C,(>柸=Iz083$-%!iunvJV]Qژ4;˳bs2`eZpt jc%_T^R :73zbc() -()hu=p8Wl! AOYsx ҈-q1:9C9#3RSS39)(.ž }Cm u7 ?);2Ogμ3Hxk{?0*;s*nWot,3܈y9ժx>PՇ˳y(򨯻O#:ԈJ7iZZʼ;1O/m|JɭmiVv~^S̼yƉ԰ǡpl]7>\6C&ٞmuuY- ѱT>3 )L"pqh(\UoSbjk W , "H ?C )%ii~/\9)_L(1 J/ ,(--ώ-V *ЉDE\DU¢€h!TkjM1 utvD:ؗg,/)% y0ݩu;|ݟ]q~!jP~gcͱjYH|||l@g N+W7`laѪ듭y pD"ؼa`;\xɾ9ݽHMHl 3xxZ{ĵ. f~:k[<;ٹ.{cxj e]@b؆#*zc׹?@sתzQXV92@qsKtc%rpf. K1]{/w75nآԍ*3˘~TӃSHF3\Z_Y|jPPsؚ1g/|Q r!!f3[\^kl3? ZȖ4ş ٖY#+|cdK=ף4x>~ZGյVAf 8u= 7ͫ<,.nx/6?鳪m8b!Jn]:ކΆ˻8^cfVry͟ď1(&X1¯t~==d]a>>#U/]ud[ (!*EزDZM)92K e!HWs`TcУ;gg.+m֔oAK!dFvЊj[œTӿiU_7`rBE$ D11L¨Xg*é~9HJϴ?>M<5\+Z'VePxן!=`޶A!SJ*M;B ^KT. r4gZt/T LT&3G1~|2 C#$Etq^@_z kwWW6SW(C(?N]`-F%ÎlwqŇ7'>e|ь#:"!F)[@;$_VTKF))Ĵ4J喖I}^ѰhZYXDdpZQGmu~m #7m3hFk⣣%QaW(nTJUI"G _:IZK6A.Ox&IE_p(f!:9"nd>_/hڎkeWio^ҁ ­]܇Q_}+|d߆qCy[>cɼ`*En!/]e{}x*/K/ C$GZ,!X`ޞ#ʾ&!9- xPخ{,!~Ҫ2PxYW$puy"  59$>6ɦ 6-\f!uvZ_QIRYR{u|WO=lB,ULǻJ# WD$A)F > `8qȅGE"bzk{'S{+y{.ҺX[Uj)J;aB5:L[GY~Lsq:K 쬈ej2zb PC֜*ajqg1vq))I9i52csmߞR]?/'XcV3 YGb7 ъIXh|Ifu 8} rrbs[y2c6Z `fLm7hrSoI\ݜFp)BZ>Lukr(5E^u>g1f.b-9F<#Z̋ŝP_Wiu$Ii~~SW]]9_JA"XlQG'GѸ'CP a^|+j5 t^\`Nτ*)^TŠ&Q]G(ѐ*:# >0i@.qõPl 34>@pYIUk5…^qהMuO4-ܣ?fnoefce%?i ߰F#jHIU"vs+=P:wi`" [(PĄn4;$'f~({l8srV?3rg(y~^I>IATob+w{n a"( 'h,COKq\L(?[tKLK9n` TfO{v ,X\;t{r/\G79ɚ7Zыt~I8TL{ K}oݯ{ҳf:Il)Luܺ~^w`vTudq5&+\53Sgj`axJ dgk,q- rxit:B2T!=PKW}/ʰg>G< &?>[㹷őt:G^ȑ0t".ӧe3Qi7݆=IO76n'G:M~^c*=z],V^}7_EأSYx!/G]Tt\#dvWDŽ̩'ҏjhݦz3k֘G~t៯:2Fdڵ|ټz/s=DY\ڟò7\\U듗5+߾BA_Xluz!)n Ȝx;Yǭ݅'8̹ޭf{LX5;WF{/`.o fg _¸7E_bث^I 0Dm#_/2drS 1 I[D1;,h%ZECmF^rr}Lt+ ?T j@ jH99G`֯P9yY#nt,D/?/X4C ]Pň JIymR+x!bvԊ3jş7<OwQ7uQGtQ?EtU8;\;^|_E8)Cozg^ϰg8g44Ę|Uhnf$n;p y0Xwn)@`-R$GL3A95τNyyV3A5=Ш֤/ ^1!ۏl?2{Ӌ}IwC8S'*b]*&b 6;ڄ|Czbbe }[<ѣWk=7apF'& #p9{xԥ֐y5>B 1>qCfC\Cj0A$*H;E,g)OxFc8H$`Z7^`y(%"2`_B{+WƱuzquΖV殆h)Z&611+r.C'QiN쥩\ɏtŕߩԤ ~9ZL68lp%3wj$\SS÷!/k?]я{c"=DOz&෮ڥҀ?x|mn9`-Wݵ lLMȴ*s٢2IZt|+ =H:=Ic?zTyEL$Jl[t@o;H}S '$+4xIJz!Hk\Tޥ!"؃/Rm&Jw|5 tH%^Lln"Z*V]W+_FFpUp ]:%:~ϖ&@3t7*4Iu`q.z@+AuB;0xhX%z<=R2O`WeMcOVSOH/% ~K*T7t#,#+@ǍO:1?4 \˪)vkujruA&A+ы6ZK\P gwC*7Mz0h:esLPW,B7[ o2(.Ey?Y(-]op,4 ȞxQw+P~->xr_ut[wwTh!y/wvuE<97F pL[RRq˕v,v˿,QJF|m]bGXS}O_6uLLhkrN}|0jo聙=1n HlB {' XÉ<=3#˿cg?96oVrt@=Ε ˁlCad>x|UbDw֚lX׻enclN9.9akB|(2"88D>Cb<0(Qsl^ #nbKA'k #){='cq ?Јsb>U -調`:g=FMam`r=.eZ~x^h;7 U 1IǑZXRۋ PPHN;QETTE#ntvG; =DWU'PKj_ RkHnɫ [RL>oN C}dt_y9X}z Z(v㔴m!>1]e,@MSlʂn& MRʔPheϭU{@gp T/I.xXEgj3)?~L^x`1Չ.4? .qPz{ RB,َ9}wg%z0I qw4,$#fi$t$4q _`4lj_qLsF k l;U"j`a?'B1_[%;iZ8"j`Ν=,NBuk"Oceye]$l俁O8iR&I-kJF DB+XM]hvcsᐻ*ϫ"LBID:XX;$:!!G)@I_TzJpgb~@x5}}+Pi3U OWyPĖ.e#})R]1A堚5 U\5 (I _-JHhMBJg'%f vd{imjR BHcIS˫a(a&|r|J U˞&Z Q8XOs- u~?J̰wWv>Q6s\tt\D떬FP8d3AAbB']EF\ɏH1q6\잜㛎E(*w;@g*b*MPxuM@MiÐ?yiCBjUZ&Xvic)Hb4aT$gVeiy{%fScc3ŦG$|.zG S|ICW. P;7tSݲ2~^R[ =ؤYB)RJx8Zc ip`NMiBbPHĻEkX盏J51 8h5}Ǜ"-V9:{2l?n]#lqVxdhByRb[k[*]Xkh[QIw"t,ŌP mNP8l'^Alҙװ2K!,=,X¸{/k؅g,Ox zxHNWTmVAV=)A%TSRlT l6o&{Ygas*)# 'N.3!(!YھGrg{j@YÑb*.*Ez%?.MvHO &o- *DZbd$<FQˊcuWXj[9fT,G)k_XS 7`I7^OSk;I:MjL,˪j ɘx!E4WSĪ$ ⛝dn*^ |yḃi09!8u{r3Q)[?ͭHӭfӗ؋jz_>z;o;m?_w8l # 1^uϮEuW6lsLP0 Nw&9`TS~5JyS&ۿlՔq@~d fkKmWWPˤ }*a?&o2RgӑP[31Pо:8F͜-ڳ=eе_"Ȧd ko-e]i簐y>')c ʪ=-n"}>~ ?3OMU#0 gv]6Vr-ªJv\& 1l^Ix>rp9yb5u .n XY]"ȕ0c?'u P>0Upv{Y[|;>X{q|ږànn6 nI*/M 2ų.DKя Lopy[eyexɘf!iklW{{Z+PaS'\fՎH~ k>7lM#x.!kyKNBB+R#qw `ک>uMF:kuĴHVa]q'x*1*. D.ZQ2lv q˱<":jflUt$-HKm ]ُ'jƷ{h_ hfVoֶV+8숤v!o-^(nZq} D-׃;S6 ӅJEeW+*RnXjٖӵ(r6TS̈iOC&FvW!3daCV}>4*5]S^C*DqIqI1-`(M sBn+S /QxHw]Te_ڹe2}eT'дY\aGޏj%WQ g+TEu!xہ'\F'P^v,VݾOoR2=Yj|HnZn5ggg݃7% F¦M݉߸-qVS-WZnBՒ yJ,> uG𝄆Pn |HyMrq+`ƷtN &}-0z=C8-RID,b[?݄ -1ƅ\s?_wGV;Q4"qKbr~#SxjOu\31m&N][|7"_-.y?*SPDkݞVz:i/O9hys@~k7qu5LoiJ!]w\W GeiKnT5&&>%IN@oV331"-kÍm6F}L!CY'/6V7ZȃS[0SPH0gWeu'ȇ[ʳ~s͊SB筇ewҥ? tމ9d[-NH $5۳E+ruux2P9,e//wwůi?\vєI^Wjx e2TW{W̓26k[~KӛfZ҄4dHO~N`Q<hԤϑ۸@aChKmjQXU#$/,&B;+[ MwYg6b V X [xw>yA] KaωނXB\ \J=#'GNA˙Ӳ3RS>0qy(sFf/SxIb,:,Om'ϰBiQRdZf-7 [yQ3ZeﲯB{3Π hOA.p <ƙAsM Y5#;-Jc7(FE>jZ%Ll)dlwo;I>8\SC!C ӥʕǼtN' ^sЧ'}K JBb)m"26 nB er2ca/i_;.M4$Xkݕ8Weq ~oxgszXZl]D9Au彛IFaЊ4f;Nt 1#BkF:ޣlW_d&3iwy4H?$[e', MΉQ t, A7b'\c󳶄iX9[#saÎb`pF(Rժ  -ni MmXs8GpuoOVcw( Ea"W{;xx$&>0a≼$U܈"!ܑ[E#[&\-1) WIת n~`btm! kSPy@s1ytO U1t{tZ{[]y؜CʆI:3UE.{"^Kq8s]J(لĠ %G(dw+tC޴ `n!tp-ZS6<+Rn]ql22a6x 5;P@ yH٨۩<ϳ0~R\0T:sWQ!jj)O2*'%OǠ0p|^ _<(l诀.7RРBQL4J/'\{q:r|0DL+G.XN'|"e4)(fKBN!f"Bt>A"AMsHOOң5cXks0+4^EIe~"Rd: ^ _ #pYz:| _w'"7h.Yw}]Q|)EQ16`jLLم-ZGoذx@iEa MrUQG92Q|.vuXSX .t{&Ւ(ِtROZO^ {kI rb}I!kM`,k ꪅ{q*F X񫲱v@abO^ܸ^ъe`W|k-<"V|~b>#1gu+砹̲; RSsm}}}} Dohx^fHQc{ MVE/Ӊ^l%&=!lGjK4DO!6)왢Sҧzݰ QVC^vi&~^?Aoj,YvUvVy<Σev*rjɱ*5rA X\#LxsXVWj'JcSңwj$Ɩ1 3:;;OJM{}zC!P΂:#ƥpF(X@#GX#=Ư;!ڋf(U*+)l%*63+%9+6RxΗP.,Ql [N^A@cAz¿guʘ1$]@]xɛ6#);z uW*[9U`$j'jOn ܇8*O-~\2ݿ$CiH_MAL5%8bڙZ074hϏGLO v} ѹ{2B#<#c]#}*̳O45\+y<-@['tS^ׅĺZ8[7bK\zflrjh{Xd(Oώ)*r['y ^?7:wsmժt~1%϶FtUqv%*W 7^$/-Q0Hw>~I{< z2/;bG5sIu,sxv*4 N8nup+[+T˽i)QI(qBDFDFH8)2^;v}gbRS WϝzzUƁc%fU&yO2OĔcn$/pn`R'E-ۙ eƋwn Bf7$/'094u gk6Q˙ omEZ)N*y{!v/6!/XHŗ|=iy^cHYd/7G;WFOh'[_gdxH,6%5>;=Y&t4]2Co"_yL /~$6Y3V`3~JԫW"T6ZN#;/31uçr-Fe z!{x=3t^8N^#:vuc7َ]Jw@G'D0mYH5ŒRN0M#r,vn.=$ә:Yh>b+[x8*KNPGV7f:+W;uk FX9z"5v3s j9($0PݡC5;?jGQYEk\̵AGg; HKG\I𡢝(okVo8.kh0j_loQ6jȧ. Q0l}aOfČHZ:W%]~~1惧9u*T$Gܽ5;-aVs԰iһ;eNpr07]P;$, lV*S<70`4Lß# %2 LNtY _V 9V(vD3rO2IiX pN)cEܑfh`+IhV,U,>C9Y3>)F=<(c>\ipJ3 ,T^Ҭ IG6yvDœ?H9"-͒ϫ86;)\ ~G>C;2te\an=-w׮ޱgڰJP_j3돐[j^\ 7x)ڲoچ!^ Ы=q4ʩ"T<>e H8D M)}cj2~S?xӻ@ȯu Pk4~LaS4*|Tv|VraZNe(r` 4T+ѦLyB`F[RYK^뤾d}g%)՗q}IphP$&j8Py4iYG)2ǴE /8[4ڪ(yS5 J=bB*R>_U{K M[Bɶ aL#"7g5!yBٖr|zRZw5#X)<̅#jU}b Drg}~ Դ[ER׽oW*ZYisr+p!VS/1 EF` 5E cIg>v+nde..=堨t|G?uÁ\<]td4,ًڽ(G / bӮ^IzۿyHbG/U8Iz0VJ>BM5vf-љN*8HBonZ)Fe1A6qWA#)٩wvBrU`8%4(w$.I`(LF0{)Ԅ[&@OW`Sr3v ^ߛ/t`zBQ@whOnq='NB88VhaZk8.5/CV.vٝǕ\=wTi4g>VIHm&xejUN)錪Ա::j -TU߿ע:>W`goR?>r}^,G8N]:>>sXoT$g]֪8}d\=O!OqbĤ t;Ѳ'h|;dF>3Qo+eM˻U2Y*+XNki! p )Tȶ;k`YprUwrD8L]RRow/'(% =}qsF - f-n&lJ[`dՙF[[t&8+; hr\wS0pxkW?Nn RԬnYc=K(}AĨ KűĤL76t{`2%FĦ_FВ3D:{C8o-Vr4SATފ\f|ImeVeJ;0הnWF/b5XBl,g c Ig@DlAZ(>2 .tq@~fM<]щF'2h04"t4uy|e!V ղJ= BWFy€rʴvzUjt>ж+Rv+fsGZB+ *xbpo*>(>ZyqV[h!&'-+mY{Q]ڦL| 4N>ԔzYn& &eP8j) j2PgJ"oF. 4n߮[s:.et/0|!a\sZh.SEk"vH43|JZ:ܕh%Zڂog KwEǑzh[`A`U~SJ`N^yU`7A~^.SlX8eDnނ Yc< >zEtohbo6F =a \E+@)l QרiY s MGK ?sfLJDkw9|3C?UPltGkIO=Բр >jG?ҸcyTt.ajQrϗ @ȋĀ^X~8N\}. \ mTEj0 Ļ5{UAà{>JTU&tH%2 t wZC?bjh0R{ݢcϦ_~ vϩtur9ߢhn ^a> o·sa#{=@ ,/r E|!`|GC4pJ$= DA:|Ӭ$=I'&5R*v5^깺ՙ ~RGճ!s]EDS-VAKgɤO~kle2aIb%DzA'(壯W?**Ffqz?W'Y.ގ|a]ff2B;Y!KKL%!˖Ck{P=;؆SpwyZAWi7/Aos_,u ߯%%k,{9ϻ&MMmJccS+I0p ]Q ,ѱ`A?!;bPGM]"KQ4hLjFe o;y"Ai ˲Yk`TZ&?5_K!; H$^"cim-j[Fd -%{fw`>ݩ#|[BLSUQ|(N3,!ID7aAL# "`j'cR}8\0s~aa›`S\+n¦c¦ׅ#eIß*۝ ^CZ*yczB|LBiȶ!%d]lt؝싂S0Y"R: CaA ֐-y6>zSk{F̮w[kI$E~g(ZJ)Z_:ƠKS%Z*^-~+4>?{(=ϵzml)i ZGBZZ;W,nP;IyGB?"Ne&o|zAU<6Л:or eA] / AΟرj/Iqk%yz*}UEOkE_TP^fNk/R=hIik":HMK[4\xv"jN"vƇJF Kt]ߣpݿwI)9J/ M5Cr?$->-B([q0jo聙=1\nE2&ɰD|\O#"=J+<;1qh~ 7\(!Y1I. ?z/"go,k!JZvjkcdR)y9?A&ݕ+:EʾYAr aWdDhIUBnwA`Sͮ3͟#ϣTy/ xޓ'3[6e,#؍z.cGKfDSͨӶc*1iңU˞GU[+E'iL9AzۺD<=UHtC.5ΨT:K?uϮՋ4>QK:./>+r`wIYU8ٔ{Kp81>*rҚra ~،KTp?"X%, wKﱕ+0%CX]vU3^7p}v~C6|h$Yq; ɱg{.weAv? #ڻ;]Wژ/NETudn]us_ endstream endobj 11 0 obj 33920 endobj 12 0 obj <> endobj 13 0 obj <> endobj 10 0 obj <> endobj 14 0 obj <> endobj 2 0 obj <>endobj xref 0 15 0000000000 65535 f 0000000984 00000 n 0000036506 00000 n 0000000925 00000 n 0000001032 00000 n 0000000774 00000 n 0000000015 00000 n 0000000755 00000 n 0000001315 00000 n 0000001101 00000 n 0000035404 00000 n 0000035320 00000 n 0000035342 00000 n 0000035372 00000 n 0000036448 00000 n trailer << /Size 15 /Root 1 0 R /Info 2 0 R >> startxref 36556 %%EOF Csdp-6.2.0/doc/csdpuser.pdf0000644000175200017520000115155513135474566014201 0ustar coincoin%PDF-1.5 % 3 0 obj << /Length 2049 /Filter /FlateDecode >> stream xuXK8WrUڣ؝fIM<3>m"gE?Ao~zڤIUԛ"IWeRl&]mCϟ7YF&?~^jg0i g˄KXZa ZD-[;d8PDH6J?d4Ut{օ^.>b翽co!y!mHn̐ZbIjӪ҈t۳AS/B> stream xMs_#457>n=Im:qg2NrHHM @FV޾KQR}aZp{iB3\|^~acRŇmyTd?zm6e}y9-|y)h;ڡT5/..j]…V`wmsu]mopu) |Yw6`u¢@BHŌQ@gDE]|l^./p"^Z\J`\:t̤ۼ_DR\,`|s1W.ż3A9L!v_p f@|T91%5#q.!8i$ƽ'=~dU gdNkZs[epk@Ǝ) 迕>#[;-ZP/)^20Nߌ\hX fr`:!\p.Iok1,-,AFKtKY3`qњ'!)րԶ"f$S4|1nGvٗ-ʪx @[S{vAT_%%$(Lq.+ hbCd*aD2<>Nx*V4CTu.9Djϫm_c$TgP̊V$rX#?g NNCӫcDХ'a1sM=f+P5UKMkCp >b ; ](z$Չbʸ3,uZձfBs:-j:T]c5A*ڨiRc\ X8Ԟ2d|)IT̀9"ḡq:$qS%eVT|+AH΍ B/6RuuRBW0}46+n%D辋Mus vKc VWŮj-=))U]lc>N5ZșоR/ݦ|3,'h^ sxb0tC -~A}55*鬘1#!zNve{l4Hq-tTZ @R 7H}\ #DZZ@^[[7i~#W-}M .0Bb(-pgTSC1r囋~S/_, 6_(3 \?k=}XZ/c ,~[Lbˀ L!dqHqR N7 r9E%<Y`xqeX FC,3Z܌!ե ;C0Jmo=> L D}NΧdVeFL?E>-wc' Ӻq}022Us ܆"PQ ',v|df^(103<_qh .ށ'ډ#"Kr;gBj!s#!FCu*XRPzw>!ȜUWd~޺C5txܝ;ɳFu><ϝƩI1Χ;EO񻇔ߍwɤ"sH>&hc I'WK&8<~>*͌ {J +4/t^υVE(4BrjhRCgJRHϔl{|@^61:5vj6G\S}́x0Y*#уmHlgfGCЙƗÜ76vyfڕ:iSm9*v&kM.lR@^hrjhð)wI?m~XzS K宪ibdy=~;lqgo :سY~+/S]U#5lʶخ1jW WJ kL3$NeDlMӕyʬ CńPdj2L٥Jv(&2`Ru [+cev ٠id ÅBn+8'PҵO/A1& SHݴp)[pOM263V恌-WmBg)!fϊ.3u-&V y`; ajsŸjZ " endstream endobj 23 0 obj << /Length 2175 /Filter /FlateDecode >> stream xXݏ8o,^n{z],ضęXٹGRlN'K$HOw7?|pI2#MrNv 2n|mBK;-K7+vs"ϷH}wKCUlڼ-;UUcSh_S/FU UA?,Ҡ`SEf5g5E뢡+/sgi9_o,,ݲrG_Z"f׏e)r/ CmPvS4 T)fp4aRԲmh?c˼)g0o[4-$]uͫ s*[4~"-QM~ J⤞ߏ0ʽ$ @>ݏ-a@K,`Z <eV;pO@UR&M3dX}Lqyn~w<Ԇi)4Kg.7dpLe.y(AO盟0{&d9Rў9{;aeD2g>76STݾ3 CLaܹgp"oB,x8a6e!4q}GpNS2fl2 7d,XX,De \"۳4"&5&K=SzÄ$P|+sI<^*-ck1[m&oiߡCW>EĵPX` KU`5Ѿ^RTV wW[ڳX unEĺhủ:z#ҟJ@,˸x?Y{GXߦJ sJ@;d,B@Mm}!@_b|a׉f3y0Ay$)3(Wg<ҙaJ뗥0?1cp>cC1U]FVg!+Ux1 YY"+\hR.JFOQyφ=%d. ۰ s] @-$S"`ߖ<èg Uץ987dm:cJT]r#I"\0|I+0#Pž-k4˜ۀ־:H9! Nc 3o2}6*oKNࣇp`[ m>r!fJ˱!%( ATQaJ@_5N ~[̺Vޑ2.ў6%1(@) soq 77y\4ZLS]ms)*m8=px|(Sm%i@[Yy .?@g*r xKz5.;ȀA-xu1̘N>۸B[A>Ƃ;8π:N)^i܇I0 Cs +s2_fCYpM.ՄQfM~r!ut"TG0ا/T#]a$@2:ivJ M __F]XB!Φ GG9B?ﴭ=x]﷔g?F7dE(ފw2NfC MqfO8RjESC.*rHFL_,lU,Z4DX\FU6q|Xt%悭v1C a)CAEhy^Ӏ3΋@Wk:|}+\?2L)Q,+2 L bՙ22Xd% sȑ22@Ji5 V@&)cʨg2a*{2Zkk3Lq1f$KF%PHFje{6J)t2iv2je()0EǤ s2dnT\Ht19BYS?6 endstream endobj 27 0 obj << /Length 1781 /Filter /FlateDecode >> stream xڭXo6_ae V{Țe耭=06m%CfeWib/xw>x&geXfq6[ga,Xjw<y%Q(^^ݶwdFY,i&dQ?_fb6L'g(* y.Q")CV9`JY&eq6H0Y`l0Bd20y`o#bs0L0eynΰWLrQoy/g-jJᶫvf)8H/muyy^;KO|V~׵:Gتf\GT[Z_#Cȉ(yc?+XǴ)"~LW޲crNJe\L Sw%mM^ZZDEd7v'5,!9(dRƋb< Lx$QS2hi{-~9@-evm5 oP*= 9$h. ޏqљxĽ1xI0S2 Tb?A; hz '&I:Z˔6[4xƝfcg-zq*gZE6i vo'Q2qrm,<0cPxxD؏%iK鴑qrp{vp;  ]G=rH0n-I5m9D0U@@n9Sw>@5tU;1Lc3&\CcBAp&QQ&FR]$Ú gxiv$\Sb=Qw6v=sO } Fl ])9 m)1d`n. (p#rwHO(qSN4|Mɽ8'!k!%08ހV݊IO\ͨ "WrrxreW:C W5-A"w8xtXU\%dT;2=5}aq |Mv)rj [oŘS ~A|˽lD 7'NSsr4QWF0}G`;B||D _-M_jԎN5 f`8yf#vNcl~~|6pR\ ¥TK $HBx6aC}6RVW}D_{G1@ ,d&b%e,޽D^bT4+CL"s: =i?tؘ6 endstream endobj 30 0 obj << /Length 2389 /Filter /FlateDecode >> stream xڝXKϯJbFHJZb2i R`n .xm֌,z#=Jl[L76yD_}JQZe2Dnkr2grv_wena+(j_۽NE_,/sy-E K%)}įQ)P5>UPO|0vOӇsS[eO~պHާRw@Ν=OT#yٗ+`\iQ\iSMJ!'mu'd9U"U崺}lN>DʹHͼu~24hk߹f{VY-"1~mYFj뫧*"C~k\Ak7TGJNqC1'@`cIف DjqX 3Y[˜yţҙQK 62Q Hͪ922l$X, $-T6z[s"+g^9D́<. )*3B)@A3B É70m,,MM:9dQw?G` b Ϙ@=vJg pFewVYn픖V+ irjQg-P^ZGq{Rc C>5HB_Kom^$GF,nEߛXKabF30>b&WF&hBP&Ҳ:<$6„~SiB: }KlQf/7[L#z'^MÊ"`<UbgH{T\4R(wc`B㥅;2gbN8hnB PI@hJVO ;P5{B;q %vʮ^QsqHe̖iq,D ]os1w_ɇE6:/.pi a=^LG REun)ps(]f 8 ߘi8]#. 6D0p>'?usyW#SZ6w[.;Bѵ\0?='__xN/s+:Vޖ-06X1a?60]rMO7gpŮ52CnIo45b]Td2Xq1,zbƕ"5 .<mHTRdx7W~|_g endstream endobj 34 0 obj << /Length 1006 /Filter /FlateDecode >> stream xڥVKo8W貨TzgN.@It, $;)(`}!5 \~GR'$j0 $s8 H; 8ЏI{Ϋ5uQʪbT^GBz{w#=]2ivofefK ^4lk>֬\-UQ$(޷] 3"Q-Zqc/FMu'٤, [DNռ=q*2LF**Tn_R)_{f&0[փ]^uOM7郲 zai(yC![ H_UT-jpMlʰX'њ&)rc=uSFDQ bێ *,κn9cuhe7R/)e% (r|j85j+ ]/ i`M$uwCE$tٞnj fN35"1_)5xA/j9⏑&LWLE#[z-vwDdR'`;өW'`T |pD8j9!0OjBĻZm` UHBF7̉ mi0ajC[HVy&C1\̅߀Q3 yXj $"{I LbLJYw_V- endstream endobj 37 0 obj << /Length 800 /Filter /FlateDecode >> stream xڭMo@ ٭DB["9 4q!i|NvEw'oFG$=%Pk%,"ͽѴ:Y dgWl۟ȐIXT;g*2'Gz *50ts=Q0uzTƓj`PPXc`Dqz#vAEl^V8CLb1L9,؊3L錱Bbtz CK9lё:ULSf8D8$S>JXFÊ. erڲ3SD"2`LZ7$3 agc0ٙP}5IQ3nzЀ]`Lo*Hp3NxFT&c70FF"a,Ckr0 Cř? vZan6IZn.j1{Lu2gyTxP2YIq<$;Z|Y>'a-Kƫ6?E:R4G)gn^#Jc '*ߍݤem8m[Gx{%b_f=~AQYnZQr\͒yr^tfHHbz> stream xڕX[o6~0 [E<n-@S`XFc&Ql~Ns?l寒0]mf,$NdzbŻ__'+?KY@4Z)(DŽ1 u[UWe2//'̓nμOeAmMFm]K{KCUw,ִjB7Ɯ2Kų%c*njoMGfe,#A 9 ԌxdZq'큠ʒ}ﺏWo-3_4!'[}S;zwkYWީ H4hNl5"P9XV7]IB? l\L 8!y`<@%>>zYA%'qE mkT 6c Y !c$+6xIxn /b)wSIuH;lD]4sEWz>ӻth@h͚Vwyk}'M`Y~'~N?˜{ Bg R( ;脖8A01zJy F|ڢ502"'f$gͨ{pi F-Z6s->] M uPEhfKK/!^qxPȸ Fs., 3H'g}E՚ur*ZYDik5G x(s1[K1c65"xQʈcAdA}elβⰺW(sAiv:R ce0>@>jaT283(t,o%۶:Lډ\4-$OE}Lf"B> VNhMZ^]ot.IGꂹd E=y> mg^@X j1P_ WH/hE`*I'" v{#xz7lK0> stream xڽXKoFWHfߏCiڠPE@#ItHv3H 7K( AVPvod kJɝ%%6ysŧcRk)% ΈS*+84rH 'mrB~/_o'Zb*>4jaEZVMO#pcHm!Q c6-}" 3XQ}Ge< 6> 3G`9T-3X"Q6>%θ'bO5\΂=~o{~ FF{(gMs4앓P9+g U^~Psi7> 7[̂=@^~PslS:O^4"rNA?}f8!iД><ހ0cWMYՋ*ͪ< jq/tUܦg 2U,<4-_G3[/5,$NJx|uU $MzW4锁Ni24< 6EJyy^;-]kؘ(&d vtUhzUKs/>qY, `uF7Y_r760!7h"[8tX"\cg7~*18n6дF'r!Ese w,$*p%\X-UsmZ1x@`98;:9crڅg7E`Ke#:]Y \Uy5U`JOtJ$yEhEEn{'Kq!$=P/vW/` NgnbWeчdU8V]F,to2#f\<"G}z7"$mK"6 %7SRA)s[?^uZ2kW uxk; q h׊&rQlOoN~6.FOhWK|9&:f,8 mk Y!hS{8``16yO0ImaA(L'R{x!Cv6a7Ιs*m东94t.;jY?;LD zJ Դ'l I |LZzMoŔ.OL蜙Yn< :`:l_‘<%Ϙ-;o4jP]1:<#3wH x$GAQS<!#>Lxd~6Юz=BLi^PD~_ endstream endobj 47 0 obj << /Length 1643 /Filter /FlateDecode >> stream xڭr64B$дL{:Mr%DU|}X&)H žc!&YI`$W<8'y&:4N2b-&Rd4 8fp͏H3(Q,K FdN (f@<ӯL&OɸH&:ȈQ*y>=m&#OY H9ưSoY є#C눡[NTdãDPpHfS0a#He O ֣KoLmgfz[9j 2ἼO2BZy RX1OT$23:*")'Lbb\a?G3[QvET{oSyٿ2x)z[YYJtMBzI3NՏɦ,h@LqCSZ_p}Be%rU%`J8` )YǪՉ8!PN,Uq[-N768{]Je3O uU[ږ]WoqqUJ] q-C9nto@\T{4RHvG.8iK ! )vuS1n=P ҪBEz{^,,:63M;,8S{9l[Xlxu? {1>χG<\YkKga|^wv/GD W~|~W/xV)d/In- +,_&,x8u*:a9  Xl@io{W#.k rW^tK,( Jf;(OSIiKX3 esgdov/pxش%-C%M4ҷ{0 ] ni}3CA+gqy5qPKʼWy`W0.Cp!umuG0, Jn/̸ vW&?]s-a7 7ƇwCNRi=sf/7 l\#lmIQi~Z%v ܅.yZV{v7;VMu,WR?<&LDȧ^g2~MA2̙h<3x.-G:; .|KHL̇Nhl e2yPT wo)tYN6,Oi҄0\p" ejTJ^o q~9T*kCL(_y*w8|rD9|ad? Fm*TDûs}rUo=sw(+-B>~A?\B?q=c"qˇ ~wꎡBq\q.q:aqp\E?+tYFr jd4 endstream endobj 53 0 obj << /Length 974 /Filter /FlateDecode >> stream xڍVI6 _ z⭷YPhE^$8V*9y%E9uERw&"+#25tl{|WQI?1?{>XKuemv$Wʴ\"~ G3{n~xns*e*-x&>U-׵ʔ,yYn 7veC ! []iEt;p`$zo>$ɻq87fy@, rnk&Rx$aOHC(1U~b_>[pBK 9U@v:-\j&C5t9r6/3#䇐`f&v;͜ng03R`fnC* XڸJ~t&yB0l{v1/ĺnRJ́xW6> C&!`ݜa7h-)@XK̊DAgJrRsnAd@-LZ^PS: 7asQߌ+*v> D!V[@-hWRY {jF.:=)ydY1hI+E$Yk-\ʲ7㘔4$գ9 q8p6k+.ie5XS. Fk>h)6K+ Zz )"mY$!N= ߮ vJi2$D=;Ov_y@24Q_vHAbK8qm'+=,?OWIuLѱ&RcHtL~:8iabpA@'Ue&O~PeޑFռkT 0KX~H5貕NW`*uz.?0$g= endstream endobj 48 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./cmat.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 54 0 R /BBox [0 0 244 428] /Resources << /ProcSet [ /PDF /Text ] /ExtGState << /R4 55 0 R >>/Font << /R10 56 0 R>> >> /Length 1190 /Filter /FlateDecode >> stream xXMo7 ϯЭIU=1E"@{@{wŸC~5E 0}H2*C~yXŪ?.%)kT V;T^TuE\TY%8KHVg>nK`FGV-d]݃uw>p|}u*[>$V1[V֢m>˜f]F[B3xgam(u;?ѰU R"K1JQjٍBه; teSNQke{Zlv5{Md[<4_5ywC'(AS6p(b 8?($YfzKvT;낎Qmg̜ K-$d:JJ> >)Pl4ސMr(RɲdFՑœd5dbِ[%!_eH[Cr]& ȌhsTOH$#vHCDdr&X X+#Րehgv gz1!,w罳 W׹̙őbfN?kZF%Qe랰/>rkft W3ڠi}m 8 q٬6"ҚZTJ_SEBnΨ?WΟ.zխhN_YCv]\Ĵtd{V. 8WMԩJ #@@ xuZ{Bgr^iudz"o} $.g^1azo$q饦h6v+"rn &PSǯbQ0kp`ƽ==%bac;0#GmO-L'Ow!::পSU˰j,2aǤױ) g0"upN'/7I^C-RA*ҵ>~WqBD"wIȯx#$?է\# endstream endobj 59 0 obj << /Subtype /Type1C /Filter /FlateDecode /Length 60 0 R >> stream x{XWYvg$ɮ^E^P.e,.tKw kbPL4ŴdgYI|{<{ιNKx^zj*zT}aV1n̋8o|ʤuWo?qۄ% %xO+~QKL$ӉXOl&v5aOD&ODO .wO//$|SɏrFZIgқQdAd#N3kgrLrfsrsqs,9v q28 N9͹¹%fR2jKS;CS2*J)%UAP)*u^P*wh=֧zmD7;hKږ>B>t0FIt&K%&~LMOJjsuj^T{ڻkvזh˵Ss+۴{OhӾ}GSϵ~OMwuLיc\gH'HGt2tuJtut:utN\Թs_gX+t~a&'=a'̟dŠ 'l( swu 6j9biGBƟL3uww6)rX9m#;qg4''g'}6{8gp崝^~ܽ]ܽB9x;M0YM=/dRw?gt:?m1L35ODΞޢg@OOݑr.vsvp9._TΎcǍ~"oDZ#~b֏]ǎ[D,^]upqw_l``d>,YwKC#͇K\EZ{2^l(be6&ͫG D#q㼗,e;_`qK=%36)<;͹o?үWTWG,`L`![ fG6J0a/l0,` ,fl0v0ã6rְ61+`Pn`m`Ӏ:p>`'8* o=xHop5)hMv(36pA }xx ,H0ȆDrHHH(HhHHXȀ8ȄxP=.C'M-8J n8PU0 w BC ) 4Cr:9I"gsȹ\H." Ť!\J1iB Wr-\On 7Ln!9I"w{ȽiIZҚ!mɃy'ґt"Iҕt#ɣIzޤ!}I?ҟ  2! % #RNFQd4Cƒqd<@&L"2L# 2"2#IY@E,&KR,'+J&kZ'Fl&[Vl';N&{^'AyxGׂ0waZ|  ӭaz X3Ì09|Lf.0fY0fٛa~ saN ̝ sa̽ 6<3 w| hXX‚oaX8 ``=za*,aX!,퀥h!߰,/`c$ LvI `VaX:V߆5`3X:Xo \ؠf8n20;¦0lͿÖuE`) |.쨃$쌀kv=`OeSK8 7,*`_ a4xz:XnY 6l[]vOP!}o8<#ih ߁Npjp N/Y9\v]p5Q~ 0t<w8v[ s8pr<CP8 P:Q8gfÙpζ9]8 p!\Xv8 , .o%\ z`z ܘ 7uf n~"}XpW<4>GV1<>sϾao?I YB^tw[}1?ǙMxy^?~og `~w߇L0O`T̆?d/O"  `Z oqDFJqG大/'n |,@*qs 1Fކ&ʋB7JIL݉ɓ!3zt7ۂd b7}Jy&YuY/8ogf&英 ΫMObm.V:d">DK8 |LjL3܉x_AD}|fW_-0NɏC9HѕL+#220"SyL^J«ںI4\% P L3$D tRdB5e4M9DWgImLFR즠JsQ3D{n22X9)(\4@S<%7 R6!,[*n sTӱ/ n~ڜ-L Re)6]E*yBi/kT+jcI%##sLw2  iD+ezgw>BXِTd"wR=f1ceal܁8֬2%'5$!Oe5=BBnIH WxPIKf>X*=<o8RD-%[U3Lu?jM!U,pڐ&G7inyywYRh2J26bޣؼpKdbv^Z*)C?ҪYN&,bт;qnX9Kr&6Sñhh}Xq)Y\_܃QwHgWOy%%nSEc 2<ì0__f)|ڿ| rr 96z!b$#K!a꼭} ,PjJ-ZCR1a}=pT<-eV(! xrtWzb+VVK% 1f곙xW,}˼+ c>`6sr)o`m߅5),'8x_xqn+T]bm%nP*3)e"%K~DP>9Bkәw.Fv Z(::\'F'-s}1{YhX+'F!$ 23 =f6()Yɩ($8iS dR@rA J0YxgWc9Q"WsBrId**йe^~v~jk*K;\L)"eYh|IUb.VBQ >Rɂ[e\M i/qx1A(IS6֙ 2aiy!bHs۾va.tHzӭ^HYna>ǃ r^"^5ܤ8d]i~VRBtcpԍ@#"vJWcxrE/;Y|m/ZY S1VAna}c/>gZ4lcsB˛ՋzC=N-@;lSH?_@ۡ}*r{GVe>kt -hKu m [;=q 藆 .m@_z=|![Ȕy"Yr{Ub1:G8x{ORD;IjR$C'~GU/켲2cX%Lb͙n!Ni,-enT&u?U}Am`>#0yTh'D>5AZ9q񅺣[6Ϊ'>cu Ӽ3ʺ֒|w7W^2eQY}||Q+iGUQxIJDKx"OKi;Ts%U> :U~<:e>5KZ)DeFzԌBˣk5iU4ݦUAZf22 ?ۚeIMւ:cV"5 ؔTHcR",Ϙ.^8i,L":Ȃx!UW TtO+VYUIT-1#ns2TS)YI 2)Ϊ.ZAmN(iR]UYA,'&ꆠbwSl[?V+ѶIg~Ud]FuTo[C-8#0S''͗U-^~yBqH$&wX0 FA.c˔}쿽󸠵 ;ק0t}~Y74Uef%f$ eB^b:jA튺jED5ezo$f_5Yp.4RU (r˵CN.?2fE#=>KYٽkyͅw~5tGlD 9&g oY][< jTc9B&ϓE?vs9?"B}}? |Wrc>EC,h!ҕ,\>V%M _ˋ l㈱ȢFTEco1)*`KCKTJ' 5|;?ύ%$DF'&!$OHcPf``U{lw|l+-,O{kT2dsoV{:'s W-f^:Y")s:gg2Cx]QtfQ;}62gaMW U)4 nsTxQؕȋȂdRebu-f1T;[xusgL'Dc{ ;FOulF=q5I&g<;1%F-wg,hJ)՚!%ǤDDGth;z53jShM04'Y~g ݐf+ ,ISx+%.9>9>%^?SbȘpX<O1fާWSuʅޚL}Ej~2[e*2^[bNH,('ꩌdp=^QctjDI|QaU.-x*G*Y4ZC|l{CȦܧ/>Eu'j61,\7eY ^MY:YZUfT|t;'SBz;H dVD MlMu[u:fkTctv4 ibOo9"QiNF_k+{)Ql!0zq~\vB6G%-R,!S^zOeʔ&3/mb"]Rcґ~J*hg[:SҊY0J־鼜$ϖM/da汬#yjx6U߰/qo7QOBot3+|,١nļ$B>^̬Q3uvTR#e~IW7J156]8qWO~3 srSP%Gxd2?71ڄ( <1Fz؁)-j\憍g;TZӻM]Teɯ;iL-JEhl댒ڟ$6xpދw_\y-M_((+\S~CYU[P` TmBv X~1!ab=QgH#CyI,YT-*; cLȣK J+>o}LKIA1($:vP|p19Jt~^Jzӳ2+VȤ1%Hd1姠%KsP(QQU؄R7b&I Q] E>]c,d\)7*jO4;H|ÊP>>Baskc%9^eHflNߥ#,6C^p2?#Ra-=)e =+A8Z@y>> {I<Y; i50pl?TV!{g#e烂b|"k=FYYdszyYI5ƕ &zӘ&#Eqc;SR! bX"emTsj%^:=՘}9Y'^~~5u5u^S%5w?hNQ[X/Cmym'ywlsrεE6zֶv wF`Kp-&˶mYagW|5MEz>WS-VVƮ^/s1!!R'f6sHAEhͰdQp::*J"ϫ[Ԩ1P\c#n w^peTnZNjjrQFa*JBѨHi,A*)4Ӫ *{k[>͗#/tj2\(+)kB MUF79gzT8~)Z?_?=Wq3:Y{S,:g+ZNVwӣSr^孨kmtp;lb/ش5Y6}Б--iݗ_zzU5tm=sfLȻ34ᅥcrbfd[QC_u1fNWx!Ue78$t3(0!UΡRqQ8$ T1p`">(+@W8We+#X7)WU=hVU=UQ4a>ë??r]!1-k:O]nrC! WMa_Uf =9zЭ퐛G9=#))]P[DZ' ]מu>fl a!/ba衝h}ɹ>@l㒀P"b3O1uXzod1zHZG3,W "u^BJRezMQMMúЍ%[C G)t*CT$*Mߒvj9_%+ﰧʘe/T&ᚇη& g,<-ضwӔ{ (wxI2ԯȤ Vv :*ϠXhw]p8^I랸WrrʧO-x |qz{."rO%nYOgUt,h#FewV-[yQsj=%QՅ ͷΨ |eqNǯ󹵣~jlr"է90>5d)Zk+Q$xFFGGGE'ŲbhDU:I=Q Jd6CAvOzU֡T[ԋJz/swG%U}ؘsB%yͨ55.B"Ǝu充1Bax~lʤ{kbfo)mm=KkJkk*ԽT<*3/V>GC󘫣{q#>^b\3<sY5O8NmeKͧMcZ]K^-_y[-9k,4#gu/?0(01hV̋נQ/_#?4+E ŵQ7o {bz"1]| /2uYХ:TGaM՛n¶ YLo Ϛ9}V80p6b3gܭateē;vHsܐaoZ'2oi۷x#ǘ؄ev02fK`^ !Ze¯NP'8%Jvz %ɢVau}SqyXC?[U^JMNhB/2C$ bs3!yb>cS3ۣ:r9ͦ\:XQ%( f[oYs[U=%=tKk=h߽)Q&$IrPw~tHEeI$=>/6OʖTF|idIHQ "WVJs3NQizʌTAI 0/00<:NB9uCK!AiȇKG3C-#-ѵreXNCQpG懕d) 5 iiYiMyHXv6&|~|rLZTFdWwuB$(j̇Uq]n,cSSROܾ6JmY;ՇY{|7=jX>dZZ8 a-Az,(V$"VԒ_]Tjn~#+rRU HYSk2|qE(\X=ŕ4si?vN%VE2’&y6^! '6>#ڊEbDG]wūY13 ـ*kx0NeĿa l,R=2EK4VP%KѳW`quԥwj +wW_( K;׬k*:ޤVVTpa35UPxu 6yu-5ӟ7;R$qK$˔"EzfZf8W8^13+YBPtbL|85W_ԩ/#{qSx%,͉/fkU >!nBskY@ـƅ%~YzB"̕E(㠗.W{ʇ՗كIxß%~MxfO 9|/nx׆F5+;Cy.-((CbG$qdZr0SVR@y$C,(>柸=Iz083$-%!iunvJV]Qژ4;˳bs2`eZpt jc%_T^R :73zbc() -()hu=p8Wl! AOYsx ҈-q1:9C9#3RSS39)(.ž }Cm u7 ?);2Ogμ3Hxk{?0*;s*nWot,3܈y9ժx>PՇ˳y(򨯻O#:ԈJ7iZZʼ;1O/m|JɭmiVv~^S̼yƉ԰ǡpl]7>\6C&ٞmuuY- ѱT>3 )L"pqh(\UoSbjk W , "H ?C )%ii~/\9)_L(1 J/ ,(--ώ-V *ЉDE\DU¢€h!TkjM1 utvD:ؗg,/)% y0ݩu;|ݟ]q~!jP~gcͱjYH|||l@g N+W7`laѪ듭y pD"ؼa`;\xɾ9ݽHMHl 3xxZ{ĵ. f~:k[<;ٹ.{cxj e]@b؆#*zc׹?@sתzQXV92@qsKtc%rpf. K1]{/w75nآԍ*3˘~TӃSHF3\Z_Y|jPPsؚ1g/|Q r!!f3[\^kl3? ZȖ4ş ٖY#+|cdK=ף4x>~ZGյVAf 8u= 7ͫ<,.nx/6?鳪m8b!Jn]:ކΆ˻8^cfVry͟ď1(&X1¯t~==d]a>>#U/]ud[ (!*EزDZM)92K e!HWs`TcУ;gg.+m֔oAK!dFvЊj[œTӿiU_7`rBE$ D11L¨Xg*é~9HJϴ?>M<5\+Z'VePxן!=`޶A!SJ*M;B ^KT. r4gZt/T LT&3G1~|2 C#$Etq^@_z kwWW6SW(C(?N]`-F%ÎlwqŇ7'>e|ь#:"!F)[@;$_VTKF))Ĵ4J喖I}^ѰhZYXDdpZQGmu~m #7m3hFk⣣%QaW(nTJUI"G _:IZK6A.Ox&IE_p(f!:9"nd>_/hڎkeWio^ҁ ­]܇Q_}+|d߆qCy[>cɼ`*En!/]e{}x*/K/ C$GZ,!X`ޞ#ʾ&!9- xPخ{,!~Ҫ2PxYW$puy"  59$>6ɦ 6-\f!uvZ_QIRYR{u|WO=lB,ULǻJ# WD$A)F > `8qȅGE"bzk{'S{+y{.ҺX[Uj)J;aB5:L[GY~Lsq:K 쬈ej2zb PC֜*ajqg1vq))I9i52csmߞR]?/'XcV3 YGb7 ъIXh|Ifu 8} rrbs[y2c6Z `fLm7hrSoI\ݜFp)BZ>Lukr(5E^u>g1f.b-9F<#Z̋ŝP_Wiu$Ii~~SW]]9_JA"XlQG'GѸ'CP a^|+j5 t^\`Nτ*)^TŠ&Q]G(ѐ*:# >0i@.qõPl 34>@pYIUk5…^qהMuO4-ܣ?fnoefce%?i ߰F#jHIU"vs+=P:wi`" [(PĄn4;$'f~({l8srV?3rg(y~^I>IATob+w{n a"( 'h,COKq\L(?[tKLK9n` TfO{v ,X\;t{r/\G79ɚ7Zыt~I8TL{ K}oݯ{ҳf:Il)Luܺ~^w`vTudq5&+\53Sgj`axJ dgk,q- rxit:B2T!=PKW}/ʰg>G< &?>[㹷őt:G^ȑ0t".ӧe3Qi7݆=IO76n'G:M~^c*=z],V^}7_EأSYx!/G]Tt\#dvWDŽ̩'ҏjhݦz3k֘G~t៯:2Fdڵ|ټz/s=DY\ڟò7\\U듗5+߾BA_Xluz!)n Ȝx;Yǭ݅'8̹ޭf{LX5;WF{/`.o fg _¸7E_bث^I 0Dm#_/2drS 1 I[D1;,h%ZECmF^rr}Lt+ ?T j@ jH99G`֯P9yY#nt,D/?/X4C ]Pň JIymR+x!bvԊ3jş7<OwQ7uQGtQ?EtU8;\;^|_E8)Cozg^ϰg8g44Ę|Uhnf$n;p y0Xwn)@`-R$GL3A95τNyyV3A5=Ш֤/ ^1!ۏl?2{Ӌ}IwC8S'*b]*&b 6;ڄ|Czbbe }[<ѣWk=7apF'& #p9{xԥ֐y5>B 1>qCfC\Cj0A$*H;E,g)OxFc8H$`Z7^`y(%"2`_B{+WƱuzquΖV殆h)Z&611+r.C'QiN쥩\ɏtŕߩԤ ~9ZL68lp%3wj$\SS÷!/k?]я{c"=DOz&෮ڥҀ?x|mn9`-Wݵ lLMȴ*s٢2IZt|+ =H:=Ic?zTyEL$Jl[t@o;H}S '$+4xIJz!Hk\Tޥ!"؃/Rm&Jw|5 tH%^Lln"Z*V]W+_FFpUp ]:%:~ϖ&@3t7*4Iu`q.z@+AuB;0xhX%z<=R2O`WeMcOVSOH/% ~K*T7t#,#+@ǍO:1?4 \˪)vkujruA&A+ы6ZK\P gwC*7Mz0h:esLPW,B7[ o2(.Ey?Y(-]op,4 ȞxQw+P~->xr_ut[wwTh!y/wvuE<97F pL[RRq˕v,v˿,QJF|m]bGXS}O_6uLLhkrN}|0jo聙=1n HlB {' XÉ<=3#˿cg?96oVrt@=Ε ˁlCad>x|UbDw֚lX׻enclN9.9akB|(2"88D>Cb<0(Qsl^ #nbKA'k #){='cq ?Јsb>U -調`:g=FMam`r=.eZ~x^h;7 U 1IǑZXRۋ PPHN;QETTE#ntvG; =DWU'PKj_ RkHnɫ [RL>oN C}dt_y9X}z Z(v㔴m!>1]e,@MSlʂn& MRʔPheϭU{@gp T/I.xXEgj3)?~L^x`1Չ.4? .qPz{ RB,َ9}wg%z0I qw4,$#fi$t$4q _`4lj_qLsF k l;U"j`a?'B1_[%;iZ8"j`Ν=,NBuk"Oceye]$l俁O8iR&I-kJF DB+XM]hvcsᐻ*ϫ"LBID:XX;$:!!G)@I_TzJpgb~@x5}}+Pi3U OWyPĖ.e#})R]1A堚5 U\5 (I _-JHhMBJg'%f vd{imjR BHcIS˫a(a&|r|J U˞&Z Q8XOs- u~?J̰wWv>Q6s\tt\D떬FP8d3AAbB']EF\ɏH1q6\잜㛎E(*w;@g*b*MPxuM@MiÐ?yiCBjUZ&Xvic)Hb4aT$gVeiy{%fScc3ŦG$|.zG S|ICW. P;7tSݲ2~^R[ =ؤYB)RJx8Zc ip`NMiBbPHĻEkX盏J51 8h5}Ǜ"-V9:{2l?n]#lqVxdhByRb[k[*]Xkh[QIw"t,ŌP mNP8l'^Alҙװ2K!,=,X¸{/k؅g,Ox zxHNWTmVAV=)A%TSRlT l6o&{Ygas*)# 'N.3!(!YھGrg{j@YÑb*.*Ez%?.MvHO &o- *DZbd$<FQˊcuWXj[9fT,G)k_XS 7`I7^OSk;I:MjL,˪j ɘx!E4WSĪ$ ⛝dn*^ |yḃi09!8u{r3Q)[?ͭHӭfӗ؋jz_>z;o;m?_w8l # 1^uϮEuW6lsLP0 Nw&9`TS~5JyS&ۿlՔq@~d fkKmWWPˤ }*a?&o2RgӑP[31Pо:8F͜-ڳ=eе_"Ȧd ko-e]i簐y>')c ʪ=-n"}>~ ?3OMU#0 gv]6Vr-ªJv\& 1l^Ix>rp9yb5u .n XY]"ȕ0c?'u P>0Upv{Y[|;>X{q|ږànn6 nI*/M 2ų.DKя Lopy[eyexɘf!iklW{{Z+PaS'\fՎH~ k>7lM#x.!kyKNBB+R#qw `ک>uMF:kuĴHVa]q'x*1*. D.ZQ2lv q˱<":jflUt$-HKm ]ُ'jƷ{h_ hfVoֶV+8숤v!o-^(nZq} D-׃;S6 ӅJEeW+*RnXjٖӵ(r6TS̈iOC&FvW!3daCV}>4*5]S^C*DqIqI1-`(M sBn+S /QxHw]Te_ڹe2}eT'дY\aGޏj%WQ g+TEu!xہ'\F'P^v,VݾOoR2=Yj|HnZn5ggg݃7% F¦M݉߸-qVS-WZnBՒ yJ,> uG𝄆Pn |HyMrq+`ƷtN &}-0z=C8-RID,b[?݄ -1ƅ\s?_wGV;Q4"qKbr~#SxjOu\31m&N][|7"_-.y?*SPDkݞVz:i/O9hys@~k7qu5LoiJ!]w\W GeiKnT5&&>%IN@oV331"-kÍm6F}L!CY'/6V7ZȃS[0SPH0gWeu'ȇ[ʳ~s͊SB筇ewҥ? tމ9d[-NH $5۳E+ruux2P9,e//wwůi?\vєI^Wjx e2TW{W̓26k[~KӛfZ҄4dHO~N`Q<hԤϑ۸@aChKmjQXU#$/,&B;+[ MwYg6b V X [xw>yA] KaωނXB\ \J=#'GNA˙Ӳ3RS>0qy(sFf/SxIb,:,Om'ϰBiQRdZf-7 [yQ3ZeﲯB{3Π hOA.p <ƙAsM Y5#;-Jc7(FE>jZ%Ll)dlwo;I>8\SC!C ӥʕǼtN' ^sЧ'}K JBb)m"26 nB er2ca/i_;.M4$Xkݕ8Weq ~oxgszXZl]D9Au彛IFaЊ4f;Nt 1#BkF:ޣlW_d&3iwy4H?$[e', MΉQ t, A7b'\c󳶄iX9[#saÎb`pF(Rժ  -ni MmXs8GpuoOVcw( Ea"W{;xx$&>0a≼$U܈"!ܑ[E#[&\-1) WIת n~`btm! kSPy@s1ytO U1t{tZ{[]y؜CʆI:3UE.{"^Kq8s]J(لĠ %G(dw+tC޴ `n!tp-ZS6<+Rn]ql22a6x 5;P@ yH٨۩<ϳ0~R\0T:sWQ!jj)O2*'%OǠ0p|^ _<(l诀.7RРBQL4J/'\{q:r|0DL+G.XN'|"e4)(fKBN!f"Bt>A"AMsHOOң5cXks0+4^EIe~"Rd: ^ _ #pYz:| _w'"7h.Yw}]Q|)EQ16`jLLم-ZGoذx@iEa MrUQG92Q|.vuXSX .t{&Ւ(ِtROZO^ {kI rb}I!kM`,k ꪅ{q*F X񫲱v@abO^ܸ^ъe`W|k-<"V|~b>#1gu+砹̲; RSsm}}}} Dohx^fHQc{ MVE/Ӊ^l%&=!lGjK4DO!6)왢Sҧzݰ QVC^vi&~^?Aoj,YvUvVy<Σev*rjɱ*5rA X\#LxsXVWj'JcSңwj$Ɩ1 3:;;OJM{}zC!P΂:#ƥpF(X@#GX#=Ư;!ڋf(U*+)l%*63+%9+6RxΗP.,Ql [N^A@cAz¿guʘ1$]@]xɛ6#);z uW*[9U`$j'jOn ܇8*O-~\2ݿ$CiH_MAL5%8bڙZ074hϏGLO v} ѹ{2B#<#c]#}*̳O45\+y<-@['tS^ׅĺZ8[7bK\zflrjh{Xd(Oώ)*r['y ^?7:wsmժt~1%϶FtUqv%*W 7^$/-Q0Hw>~I{< z2/;bG5sIu,sxv*4 N8nup+[+T˽i)QI(qBDFDFH8)2^;v}gbRS WϝzzUƁc%fU&yO2OĔcn$/pn`R'E-ۙ eƋwn Bf7$/'094u gk6Q˙ omEZ)N*y{!v/6!/XHŗ|=iy^cHYd/7G;WFOh'[_gdxH,6%5>;=Y&t4]2Co"_yL /~$6Y3V`3~JԫW"T6ZN#;/31uçr-Fe z!{x=3t^8N^#:vuc7َ]Jw@G'D0mYH5ŒRN0M#r,vn.=$ә:Yh>b+[x8*KNPGV7f:+W;uk FX9z"5v3s j9($0PݡC5;?jGQYEk\̵AGg; HKG\I𡢝(okVo8.kh0j_loQ6jȧ. Q0l}aOfČHZ:W%]~~1惧9u*T$Gܽ5;-aVs԰iһ;eNpr07]P;$, lV*S<70`4Lß# %2 LNtY _V 9V(vD3rO2IiX pN)cEܑfh`+IhV,U,>C9Y3>)F=<(c>\ipJ3 ,T^Ҭ IG6yvDœ?H9"-͒ϫ86;)\ ~G>C;2te\an=-w׮ޱgڰJP_j3돐[j^\ 7x)ڲoچ!^ Ы=q4ʩ"T<>e H8D M)}cj2~S?xӻ@ȯu Pk4~LaS4*|Tv|VraZNe(r` 4T+ѦLyB`F[RYK^뤾d}g%)՗q}IphP$&j8Py4iYG)2ǴE /8[4ڪ(yS5 J=bB*R>_U{K M[Bɶ aL#"7g5!yBٖr|zRZw5#X)<̅#jU}b Drg}~ Դ[ER׽oW*ZYisr+p!VS/1 EF` 5E cIg>v+nde..=堨t|G?uÁ\<]td4,ًڽ(G / bӮ^IzۿyHbG/U8Iz0VJ>BM5vf-љN*8HBonZ)Fe1A6qWA#)٩wvBrU`8%4(w$.I`(LF0{)Ԅ[&@OW`Sr3v ^ߛ/t`zBQ@whOnq='NB88VhaZk8.5/CV.vٝǕ\=wTi4g>VIHm&xejUN)錪Ա::j -TU߿ע:>W`goR?>r}^,G8N]:>>sXoT$g]֪8}d\=O!OqbĤ t;Ѳ'h|;dF>3Qo+eM˻U2Y*+XNki! p )Tȶ;k`YprUwrD8L]RRow/'(% =}qsF - f-n&lJ[`dՙF[[t&8+; hr\wS0pxkW?Nn RԬnYc=K(}AĨ KűĤL76t{`2%FĦ_FВ3D:{C8o-Vr4SATފ\f|ImeVeJ;0הnWF/b5XBl,g c Ig@DlAZ(>2 .tq@~fM<]щF'2h04"t4uy|e!V ղJ= BWFy€rʴvzUjt>ж+Rv+fsGZB+ *xbpo*>(>ZyqV[h!&'-+mY{Q]ڦL| 4N>ԔzYn& &eP8j) j2PgJ"oF. 4n߮[s:.et/0|!a\sZh.SEk"vH43|JZ:ܕh%Zڂog KwEǑzh[`A`U~SJ`N^yU`7A~^.SlX8eDnނ Yc< >zEtohbo6F =a \E+@)l QרiY s MGK ?sfLJDkw9|3C?UPltGkIO=Բр >jG?ҸcyTt.ajQrϗ @ȋĀ^X~8N\}. \ mTEj0 Ļ5{UAà{>JTU&tH%2 t wZC?bjh0R{ݢcϦ_~ vϩtur9ߢhn ^a> o·sa#{=@ ,/r E|!`|GC4pJ$= DA:|Ӭ$=I'&5R*v5^깺ՙ ~RGճ!s]EDS-VAKgɤO~kle2aIb%DzA'(壯W?**Ffqz?W'Y.ގ|a]ff2B;Y!KKL%!˖Ck{P=;؆SpwyZAWi7/Aos_,u ߯%%k,{9ϻ&MMmJccS+I0p ]Q ,ѱ`A?!;bPGM]"KQ4hLjFe o;y"Ai ˲Yk`TZ&?5_K!; H$^"cim-j[Fd -%{fw`>ݩ#|[BLSUQ|(N3,!ID7aAL# "`j'cR}8\0s~aa›`S\+n¦c¦ׅ#eIß*۝ ^CZ*yczB|LBiȶ!%d]lt؝싂S0Y"R: CaA ֐-y6>zSk{F̮w[kI$E~g(ZJ)Z_:ƠKS%Z*^-~+4>?{(=ϵzml)i ZGBZZ;W,nP;IyGB?"Ne&o|zAU<6Л:or eA] / AΟرj/Iqk%yz*}UEOkE_TP^fNk/R=hIik":HMK[4\xv"jN"vƇJF Kt]ߣpݿwI)9J/ M5Cr?$->-B([q0jo聙=1\nE2&ɰD|\O#"=J+<;1qh~ 7\(!Y1I. ?z/"go,k!JZvjkcdR)y9?A&ݕ+:EʾYAr aWdDhIUBnwA`Sͮ3͟#ϣTy/ xޓ'3[6e,#؍z.cGKfDSͨӶc*1iңU˞GU[+E'iL9AzۺD<=UHtC.5ΨT:K?uϮՋ4>QK:./>+r`wIYU8ٔ{Kp81>*rҚra ~،KTp?"X%, wKﱕ+0%CX]vU3^7p}v~C6|h$Yq; ɱg{.weAv? #ڻ;]Wژ/NETudn]us_ endstream endobj 49 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./constraints.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 61 0 R /BBox [0 0 320 131] /Resources << /ProcSet [ /PDF /Text ] /ExtGState << /R4 62 0 R >>/Font << /R10 63 0 R>> >> /Length 670 /Filter /FlateDecode >> stream xVr0 )|vf%[9n\ J,GNb;l--{!k},Q@mo^s/!:U٨x&$(^!b8oG)B]O1Iy"Cp#$V9bxޗD ̼kf0Vitq)~K48L>9qh;W-j1Ou{v9B%p.^dz耂}~ָ8z޲EBb_3"Vh$! hi$=Gb4[5!6ҁ/&gn2-!^Y2?ݓ͑-a% UI$!%IJiXõ>+phMZvSk l/V*j zZ3ZaJV"VIE^g%r?ڨI;kQo+ l/RAWRK,E cܬ6*7Mz`(=[j9s[ LģD-"I-Nc5@C+C=Wʰ~xAv p8<^g7<_eRwA4L\͊]ш?#$\>0wA,SԻ"MoUXM endstream endobj 66 0 obj << /Subtype /Type1C /Filter /FlateDecode /Length 67 0 R >> stream x{XWYvg$ɮ^E^P.e,.tKw kbPL4ŴdgYI|{<{ιNKx^zj*zT}aV1n̋8o|ʤuWo?qۄ% %xO+~QKL$ӉXOl&v5aOD&ODO .wO//$|SɏrFZIgқQdAd#N3kgrLrfsrsqs,9v q28 N9͹¹%fR2jKS;CS2*J)%UAP)*u^P*wh=֧zmD7;hKږ>B>t0FIt&K%&~LMOJjsuj^T{ڻkvזh˵Ss+۴{OhӾ}GSϵ~OMwuLיc\gH'HGt2tuJtut:utN\Թs_gX+t~a&'=a'̟dŠ 'l( swu 6j9biGBƟL3uww6)rX9m#;qg4''g'}6{8gp崝^~ܽ]ܽB9x;M0YM=/dRw?gt:?m1L35ODΞޢg@OOݑr.vsvp9._TΎcǍ~"oDZ#~b֏]ǎ[D,^]upqw_l``d>,YwKC#͇K\EZ{2^l(be6&ͫG D#q㼗,e;_`qK=%36)<;͹o?үWTWG,`L`![ fG6J0a/l0,` ,fl0v0ã6rְ61+`Pn`m`Ӏ:p>`'8* o=xHop5)hMv(36pA }xx ,H0ȆDrHHH(HhHHXȀ8ȄxP=.C'M-8J n8PU0 w BC ) 4Cr:9I"gsȹ\H." Ť!\J1iB Wr-\On 7Ln!9I"w{ȽiIZҚ!mɃy'ґt"Iҕt#ɣIzޤ!}I?ҟ  2! % #RNFQd4Cƒqd<@&L"2L# 2"2#IY@E,&KR,'+J&kZ'Fl&[Vl';N&{^'AyxGׂ0waZ|  ӭaz X3Ì09|Lf.0fY0fٛa~ saN ̝ sa̽ 6<3 w| hXX‚oaX8 ``=za*,aX!,퀥h!߰,/`c$ LvI `VaX:V߆5`3X:Xo \ؠf8n20;¦0lͿÖuE`) |.쨃$쌀kv=`OeSK8 7,*`_ a4xz:XnY 6l[]vOP!}o8<#ih ߁Npjp N/Y9\v]p5Q~ 0t<w8v[ s8pr<CP8 P:Q8gfÙpζ9]8 p!\Xv8 , .o%\ z`z ܘ 7uf n~"}XpW<4>GV1<>sϾao?I YB^tw[}1?ǙMxy^?~og `~w߇L0O`T̆?d/O"  `Z oqDFJqG大/'n |,@*qs 1Fކ&ʋB7JIL݉ɓ!3zt7ۂd b7}Jy&YuY/8ogf&英 ΫMObm.V:d">DK8 |LjL3܉x_AD}|fW_-0NɏC9HѕL+#220"SyL^J«ںI4\% P L3$D tRdB5e4M9DWgImLFR즠JsQ3D{n22X9)(\4@S<%7 R6!,[*n sTӱ/ n~ڜ-L Re)6]E*yBi/kT+jcI%##sLw2  iD+ezgw>BXِTd"wR=f1ceal܁8֬2%'5$!Oe5=BBnIH WxPIKf>X*=<o8RD-%[U3Lu?jM!U,pڐ&G7inyywYRh2J26bޣؼpKdbv^Z*)C?ҪYN&,bт;qnX9Kr&6Sñhh}Xq)Y\_܃QwHgWOy%%nSEc 2<ì0__f)|ڿ| rr 96z!b$#K!a꼭} ,PjJ-ZCR1a}=pT<-eV(! xrtWzb+VVK% 1f곙xW,}˼+ c>`6sr)o`m߅5),'8x_xqn+T]bm%nP*3)e"%K~DP>9Bkәw.Fv Z(::\'F'-s}1{YhX+'F!$ 23 =f6()Yɩ($8iS dR@rA J0YxgWc9Q"WsBrId**йe^~v~jk*K;\L)"eYh|IUb.VBQ >Rɂ[e\M i/qx1A(IS6֙ 2aiy!bHs۾va.tHzӭ^HYna>ǃ r^"^5ܤ8d]i~VRBtcpԍ@#"vJWcxrE/;Y|m/ZY S1VAna}c/>gZ4lcsB˛ՋzC=N-@;lSH?_@ۡ}*r{GVe>kt -hKu m [;=q 藆 .m@_z=|![Ȕy"Yr{Ub1:G8x{ORD;IjR$C'~GU/켲2cX%Lb͙n!Ni,-enT&u?U}Am`>#0yTh'D>5AZ9q񅺣[6Ϊ'>cu Ӽ3ʺ֒|w7W^2eQY}||Q+iGUQxIJDKx"OKi;Ts%U> :U~<:e>5KZ)DeFzԌBˣk5iU4ݦUAZf22 ?ۚeIMւ:cV"5 ؔTHcR",Ϙ.^8i,L":Ȃx!UW TtO+VYUIT-1#ns2TS)YI 2)Ϊ.ZAmN(iR]UYA,'&ꆠbwSl[?V+ѶIg~Ud]FuTo[C-8#0S''͗U-^~yBqH$&wX0 FA.c˔}쿽󸠵 ;ק0t}~Y74Uef%f$ eB^b:jA튺jED5ezo$f_5Yp.4RU (r˵CN.?2fE#=>KYٽkyͅw~5tGlD 9&g oY][< jTc9B&ϓE?vs9?"B}}? |Wrc>EC,h!ҕ,\>V%M _ˋ l㈱ȢFTEco1)*`KCKTJ' 5|;?ύ%$DF'&!$OHcPf``U{lw|l+-,O{kT2dsoV{:'s W-f^:Y")s:gg2Cx]QtfQ;}62gaMW U)4 nsTxQؕȋȂdRebu-f1T;[xusgL'Dc{ ;FOulF=q5I&g<;1%F-wg,hJ)՚!%ǤDDGth;z53jShM04'Y~g ݐf+ ,ISx+%.9>9>%^?SbȘpX<O1fާWSuʅޚL}Ej~2[e*2^[bNH,('ꩌdp=^QctjDI|QaU.-x*G*Y4ZC|l{CȦܧ/>Eu'j61,\7eY ^MY:YZUfT|t;'SBz;H dVD MlMu[u:fkTctv4 ibOo9"QiNF_k+{)Ql!0zq~\vB6G%-R,!S^zOeʔ&3/mb"]Rcґ~J*hg[:SҊY0J־鼜$ϖM/da汬#yjx6U߰/qo7QOBot3+|,١nļ$B>^̬Q3uvTR#e~IW7J156]8qWO~3 srSP%Gxd2?71ڄ( <1Fz؁)-j\憍g;TZӻM]Teɯ;iL-JEhl댒ڟ$6xpދw_\y-M_((+\S~CYU[P` TmBv X~1!ab=QgH#CyI,YT-*; cLȣK J+>o}LKIA1($:vP|p19Jt~^Jzӳ2+VȤ1%Hd1姠%KsP(QQU؄R7b&I Q] E>]c,d\)7*jO4;H|ÊP>>Baskc%9^eHflNߥ#,6C^p2?#Ra-=)e =+A8Z@y>> {I<Y; i50pl?TV!{g#e烂b|"k=FYYdszyYI5ƕ &zӘ&#Eqc;SR! bX"emTsj%^:=՘}9Y'^~~5u5u^S%5w?hNQ[X/Cmym'ywlsrεE6zֶv wF`Kp-&˶mYagW|5MEz>WS-VVƮ^/s1!!R'f6sHAEhͰdQp::*J"ϫ[Ԩ1P\c#n w^peTnZNjjrQFa*JBѨHi,A*)4Ӫ *{k[>͗#/tj2\(+)kB MUF79gzT8~)Z?_?=Wq3:Y{S,:g+ZNVwӣSr^孨kmtp;lb/ش5Y6}Б--iݗ_zzU5tm=sfLȻ34ᅥcrbfd[QC_u1fNWx!Ue78$t3(0!UΡRqQ8$ T1p`">(+@W8We+#X7)WU=hVU=UQ4a>ë??r]!1-k:O]nrC! WMa_Uf =9zЭ퐛G9=#))]P[DZ' ]מu>fl a!/ba衝h}ɹ>@l㒀P"b3O1uXzod1zHZG3,W "u^BJRezMQMMúЍ%[C G)t*CT$*Mߒvj9_%+ﰧʘe/T&ᚇη& g,<-ضwӔ{ (wxI2ԯȤ Vv :*ϠXhw]p8^I랸WrrʧO-x |qz{."rO%nYOgUt,h#FewV-[yQsj=%QՅ ͷΨ |eqNǯ󹵣~jlr"է90>5d)Zk+Q$xFFGGGE'ŲbhDU:I=Q Jd6CAvOzU֡T[ԋJz/swG%U}ؘsB%yͨ55.B"Ǝu充1Bax~lʤ{kbfo)mm=KkJkk*ԽT<*3/V>GC󘫣{q#>^b\3<sY5O8NmeKͧMcZ]K^-_y[-9k,4#gu/?0(01hV̋נQ/_#?4+E ŵQ7o {bz"1]| /2uYХ:TGaM՛n¶ YLo Ϛ9}V80p6b3gܭateē;vHsܐaoZ'2oi۷x#ǘ؄ev02fK`^ !Ze¯NP'8%Jvz %ɢVau}SqyXC?[U^JMNhB/2C$ bs3!yb>cS3ۣ:r9ͦ\:XQ%( f[oYs[U=%=tKk=h߽)Q&$IrPw~tHEeI$=>/6OʖTF|idIHQ "WVJs3NQizʌTAI 0/00<:NB9uCK!AiȇKG3C-#-ѵreXNCQpG懕d) 5 iiYiMyHXv6&|~|rLZTFdWwuB$(j̇Uq]n,cSSROܾ6JmY;ՇY{|7=jX>dZZ8 a-Az,(V$"VԒ_]Tjn~#+rRU HYSk2|qE(\X=ŕ4si?vN%VE2’&y6^! '6>#ڊEbDG]wūY13 ـ*kx0NeĿa l,R=2EK4VP%KѳW`quԥwj +wW_( K;׬k*:ޤVVTpa35UPxu 6yu-5ӟ7;R$qK$˔"EzfZf8W8^13+YBPtbL|85W_ԩ/#{qSx%,͉/fkU >!nBskY@ـƅ%~YzB"̕E(㠗.W{ʇ՗كIxß%~MxfO 9|/nx׆F5+;Cy.-((CbG$qdZr0SVR@y$C,(>柸=Iz083$-%!iunvJV]Qژ4;˳bs2`eZpt jc%_T^R :73zbc() -()hu=p8Wl! AOYsx ҈-q1:9C9#3RSS39)(.ž }Cm u7 ?);2Ogμ3Hxk{?0*;s*nWot,3܈y9ժx>PՇ˳y(򨯻O#:ԈJ7iZZʼ;1O/m|JɭmiVv~^S̼yƉ԰ǡpl]7>\6C&ٞmuuY- ѱT>3 )L"pqh(\UoSbjk W , "H ?C )%ii~/\9)_L(1 J/ ,(--ώ-V *ЉDE\DU¢€h!TkjM1 utvD:ؗg,/)% y0ݩu;|ݟ]q~!jP~gcͱjYH|||l@g N+W7`laѪ듭y pD"ؼa`;\xɾ9ݽHMHl 3xxZ{ĵ. f~:k[<;ٹ.{cxj e]@b؆#*zc׹?@sתzQXV92@qsKtc%rpf. K1]{/w75nآԍ*3˘~TӃSHF3\Z_Y|jPPsؚ1g/|Q r!!f3[\^kl3? ZȖ4ş ٖY#+|cdK=ף4x>~ZGյVAf 8u= 7ͫ<,.nx/6?鳪m8b!Jn]:ކΆ˻8^cfVry͟ď1(&X1¯t~==d]a>>#U/]ud[ (!*EزDZM)92K e!HWs`TcУ;gg.+m֔oAK!dFvЊj[œTӿiU_7`rBE$ D11L¨Xg*é~9HJϴ?>M<5\+Z'VePxן!=`޶A!SJ*M;B ^KT. r4gZt/T LT&3G1~|2 C#$Etq^@_z kwWW6SW(C(?N]`-F%ÎlwqŇ7'>e|ь#:"!F)[@;$_VTKF))Ĵ4J喖I}^ѰhZYXDdpZQGmu~m #7m3hFk⣣%QaW(nTJUI"G _:IZK6A.Ox&IE_p(f!:9"nd>_/hڎkeWio^ҁ ­]܇Q_}+|d߆qCy[>cɼ`*En!/]e{}x*/K/ C$GZ,!X`ޞ#ʾ&!9- xPخ{,!~Ҫ2PxYW$puy"  59$>6ɦ 6-\f!uvZ_QIRYR{u|WO=lB,ULǻJ# WD$A)F > `8qȅGE"bzk{'S{+y{.ҺX[Uj)J;aB5:L[GY~Lsq:K 쬈ej2zb PC֜*ajqg1vq))I9i52csmߞR]?/'XcV3 YGb7 ъIXh|Ifu 8} rrbs[y2c6Z `fLm7hrSoI\ݜFp)BZ>Lukr(5E^u>g1f.b-9F<#Z̋ŝP_Wiu$Ii~~SW]]9_JA"XlQG'GѸ'CP a^|+j5 t^\`Nτ*)^TŠ&Q]G(ѐ*:# >0i@.qõPl 34>@pYIUk5…^qהMuO4-ܣ?fnoefce%?i ߰F#jHIU"vs+=P:wi`" [(PĄn4;$'f~({l8srV?3rg(y~^I>IATob+w{n a"( 'h,COKq\L(?[tKLK9n` TfO{v ,X\;t{r/\G79ɚ7Zыt~I8TL{ K}oݯ{ҳf:Il)Luܺ~^w`vTudq5&+\53Sgj`axJ dgk,q- rxit:B2T!=PKW}/ʰg>G< &?>[㹷őt:G^ȑ0t".ӧe3Qi7݆=IO76n'G:M~^c*=z],V^}7_EأSYx!/G]Tt\#dvWDŽ̩'ҏjhݦz3k֘G~t៯:2Fdڵ|ټz/s=DY\ڟò7\\U듗5+߾BA_Xluz!)n Ȝx;Yǭ݅'8̹ޭf{LX5;WF{/`.o fg _¸7E_bث^I 0Dm#_/2drS 1 I[D1;,h%ZECmF^rr}Lt+ ?T j@ jH99G`֯P9yY#nt,D/?/X4C ]Pň JIymR+x!bvԊ3jş7<OwQ7uQGtQ?EtU8;\;^|_E8)Cozg^ϰg8g44Ę|Uhnf$n;p y0Xwn)@`-R$GL3A95τNyyV3A5=Ш֤/ ^1!ۏl?2{Ӌ}IwC8S'*b]*&b 6;ڄ|Czbbe }[<ѣWk=7apF'& #p9{xԥ֐y5>B 1>qCfC\Cj0A$*H;E,g)OxFc8H$`Z7^`y(%"2`_B{+WƱuzquΖV殆h)Z&611+r.C'QiN쥩\ɏtŕߩԤ ~9ZL68lp%3wj$\SS÷!/k?]я{c"=DOz&෮ڥҀ?x|mn9`-Wݵ lLMȴ*s٢2IZt|+ =H:=Ic?zTyEL$Jl[t@o;H}S '$+4xIJz!Hk\Tޥ!"؃/Rm&Jw|5 tH%^Lln"Z*V]W+_FFpUp ]:%:~ϖ&@3t7*4Iu`q.z@+AuB;0xhX%z<=R2O`WeMcOVSOH/% ~K*T7t#,#+@ǍO:1?4 \˪)vkujruA&A+ы6ZK\P gwC*7Mz0h:esLPW,B7[ o2(.Ey?Y(-]op,4 ȞxQw+P~->xr_ut[wwTh!y/wvuE<97F pL[RRq˕v,v˿,QJF|m]bGXS}O_6uLLhkrN}|0jo聙=1n HlB {' XÉ<=3#˿cg?96oVrt@=Ε ˁlCad>x|UbDw֚lX׻enclN9.9akB|(2"88D>Cb<0(Qsl^ #nbKA'k #){='cq ?Јsb>U -調`:g=FMam`r=.eZ~x^h;7 U 1IǑZXRۋ PPHN;QETTE#ntvG; =DWU'PKj_ RkHnɫ [RL>oN C}dt_y9X}z Z(v㔴m!>1]e,@MSlʂn& MRʔPheϭU{@gp T/I.xXEgj3)?~L^x`1Չ.4? .qPz{ RB,َ9}wg%z0I qw4,$#fi$t$4q _`4lj_qLsF k l;U"j`a?'B1_[%;iZ8"j`Ν=,NBuk"Oceye]$l俁O8iR&I-kJF DB+XM]hvcsᐻ*ϫ"LBID:XX;$:!!G)@I_TzJpgb~@x5}}+Pi3U OWyPĖ.e#})R]1A堚5 U\5 (I _-JHhMBJg'%f vd{imjR BHcIS˫a(a&|r|J U˞&Z Q8XOs- u~?J̰wWv>Q6s\tt\D떬FP8d3AAbB']EF\ɏH1q6\잜㛎E(*w;@g*b*MPxuM@MiÐ?yiCBjUZ&Xvic)Hb4aT$gVeiy{%fScc3ŦG$|.zG S|ICW. P;7tSݲ2~^R[ =ؤYB)RJx8Zc ip`NMiBbPHĻEkX盏J51 8h5}Ǜ"-V9:{2l?n]#lqVxdhByRb[k[*]Xkh[QIw"t,ŌP mNP8l'^Alҙװ2K!,=,X¸{/k؅g,Ox zxHNWTmVAV=)A%TSRlT l6o&{Ygas*)# 'N.3!(!YھGrg{j@YÑb*.*Ez%?.MvHO &o- *DZbd$<FQˊcuWXj[9fT,G)k_XS 7`I7^OSk;I:MjL,˪j ɘx!E4WSĪ$ ⛝dn*^ |yḃi09!8u{r3Q)[?ͭHӭfӗ؋jz_>z;o;m?_w8l # 1^uϮEuW6lsLP0 Nw&9`TS~5JyS&ۿlՔq@~d fkKmWWPˤ }*a?&o2RgӑP[31Pо:8F͜-ڳ=eе_"Ȧd ko-e]i簐y>')c ʪ=-n"}>~ ?3OMU#0 gv]6Vr-ªJv\& 1l^Ix>rp9yb5u .n XY]"ȕ0c?'u P>0Upv{Y[|;>X{q|ږànn6 nI*/M 2ų.DKя Lopy[eyexɘf!iklW{{Z+PaS'\fՎH~ k>7lM#x.!kyKNBB+R#qw `ک>uMF:kuĴHVa]q'x*1*. D.ZQ2lv q˱<":jflUt$-HKm ]ُ'jƷ{h_ hfVoֶV+8숤v!o-^(nZq} D-׃;S6 ӅJEeW+*RnXjٖӵ(r6TS̈iOC&FvW!3daCV}>4*5]S^C*DqIqI1-`(M sBn+S /QxHw]Te_ڹe2}eT'дY\aGޏj%WQ g+TEu!xہ'\F'P^v,VݾOoR2=Yj|HnZn5ggg݃7% F¦M݉߸-qVS-WZnBՒ yJ,> uG𝄆Pn |HyMrq+`ƷtN &}-0z=C8-RID,b[?݄ -1ƅ\s?_wGV;Q4"qKbr~#SxjOu\31m&N][|7"_-.y?*SPDkݞVz:i/O9hys@~k7qu5LoiJ!]w\W GeiKnT5&&>%IN@oV331"-kÍm6F}L!CY'/6V7ZȃS[0SPH0gWeu'ȇ[ʳ~s͊SB筇ewҥ? tމ9d[-NH $5۳E+ruux2P9,e//wwůi?\vєI^Wjx e2TW{W̓26k[~KӛfZ҄4dHO~N`Q<hԤϑ۸@aChKmjQXU#$/,&B;+[ MwYg6b V X [xw>yA] KaωނXB\ \J=#'GNA˙Ӳ3RS>0qy(sFf/SxIb,:,Om'ϰBiQRdZf-7 [yQ3ZeﲯB{3Π hOA.p <ƙAsM Y5#;-Jc7(FE>jZ%Ll)dlwo;I>8\SC!C ӥʕǼtN' ^sЧ'}K JBb)m"26 nB er2ca/i_;.M4$Xkݕ8Weq ~oxgszXZl]D9Au彛IFaЊ4f;Nt 1#BkF:ޣlW_d&3iwy4H?$[e', MΉQ t, A7b'\c󳶄iX9[#saÎb`pF(Rժ  -ni MmXs8GpuoOVcw( Ea"W{;xx$&>0a≼$U܈"!ܑ[E#[&\-1) WIת n~`btm! kSPy@s1ytO U1t{tZ{[]y؜CʆI:3UE.{"^Kq8s]J(لĠ %G(dw+tC޴ `n!tp-ZS6<+Rn]ql22a6x 5;P@ yH٨۩<ϳ0~R\0T:sWQ!jj)O2*'%OǠ0p|^ _<(l诀.7RРBQL4J/'\{q:r|0DL+G.XN'|"e4)(fKBN!f"Bt>A"AMsHOOң5cXks0+4^EIe~"Rd: ^ _ #pYz:| _w'"7h.Yw}]Q|)EQ16`jLLم-ZGoذx@iEa MrUQG92Q|.vuXSX .t{&Ւ(ِtROZO^ {kI rb}I!kM`,k ꪅ{q*F X񫲱v@abO^ܸ^ъe`W|k-<"V|~b>#1gu+砹̲; RSsm}}}} Dohx^fHQc{ MVE/Ӊ^l%&=!lGjK4DO!6)왢Sҧzݰ QVC^vi&~^?Aoj,YvUvVy<Σev*rjɱ*5rA X\#LxsXVWj'JcSңwj$Ɩ1 3:;;OJM{}zC!P΂:#ƥpF(X@#GX#=Ư;!ڋf(U*+)l%*63+%9+6RxΗP.,Ql [N^A@cAz¿guʘ1$]@]xɛ6#);z uW*[9U`$j'jOn ܇8*O-~\2ݿ$CiH_MAL5%8bڙZ074hϏGLO v} ѹ{2B#<#c]#}*̳O45\+y<-@['tS^ׅĺZ8[7bK\zflrjh{Xd(Oώ)*r['y ^?7:wsmժt~1%϶FtUqv%*W 7^$/-Q0Hw>~I{< z2/;bG5sIu,sxv*4 N8nup+[+T˽i)QI(qBDFDFH8)2^;v}gbRS WϝzzUƁc%fU&yO2OĔcn$/pn`R'E-ۙ eƋwn Bf7$/'094u gk6Q˙ omEZ)N*y{!v/6!/XHŗ|=iy^cHYd/7G;WFOh'[_gdxH,6%5>;=Y&t4]2Co"_yL /~$6Y3V`3~JԫW"T6ZN#;/31uçr-Fe z!{x=3t^8N^#:vuc7َ]Jw@G'D0mYH5ŒRN0M#r,vn.=$ә:Yh>b+[x8*KNPGV7f:+W;uk FX9z"5v3s j9($0PݡC5;?jGQYEk\̵AGg; HKG\I𡢝(okVo8.kh0j_loQ6jȧ. Q0l}aOfČHZ:W%]~~1惧9u*T$Gܽ5;-aVs԰iһ;eNpr07]P;$, lV*S<70`4Lß# %2 LNtY _V 9V(vD3rO2IiX pN)cEܑfh`+IhV,U,>C9Y3>)F=<(c>\ipJ3 ,T^Ҭ IG6yvDœ?H9"-͒ϫ86;)\ ~G>C;2te\an=-w׮ޱgڰJP_j3돐[j^\ 7x)ڲoچ!^ Ы=q4ʩ"T<>e H8D M)}cj2~S?xӻ@ȯu Pk4~LaS4*|Tv|VraZNe(r` 4T+ѦLyB`F[RYK^뤾d}g%)՗q}IphP$&j8Py4iYG)2ǴE /8[4ڪ(yS5 J=bB*R>_U{K M[Bɶ aL#"7g5!yBٖr|zRZw5#X)<̅#jU}b Drg}~ Դ[ER׽oW*ZYisr+p!VS/1 EF` 5E cIg>v+nde..=堨t|G?uÁ\<]td4,ًڽ(G / bӮ^IzۿyHbG/U8Iz0VJ>BM5vf-љN*8HBonZ)Fe1A6qWA#)٩wvBrU`8%4(w$.I`(LF0{)Ԅ[&@OW`Sr3v ^ߛ/t`zBQ@whOnq='NB88VhaZk8.5/CV.vٝǕ\=wTi4g>VIHm&xejUN)錪Ա::j -TU߿ע:>W`goR?>r}^,G8N]:>>sXoT$g]֪8}d\=O!OqbĤ t;Ѳ'h|;dF>3Qo+eM˻U2Y*+XNki! p )Tȶ;k`YprUwrD8L]RRow/'(% =}qsF - f-n&lJ[`dՙF[[t&8+; hr\wS0pxkW?Nn RԬnYc=K(}AĨ KűĤL76t{`2%FĦ_FВ3D:{C8o-Vr4SATފ\f|ImeVeJ;0הnWF/b5XBl,g c Ig@DlAZ(>2 .tq@~fM<]щF'2h04"t4uy|e!V ղJ= BWFy€rʴvzUjt>ж+Rv+fsGZB+ *xbpo*>(>ZyqV[h!&'-+mY{Q]ڦL| 4N>ԔzYn& &eP8j) j2PgJ"oF. 4n߮[s:.et/0|!a\sZh.SEk"vH43|JZ:ܕh%Zڂog KwEǑzh[`A`U~SJ`N^yU`7A~^.SlX8eDnނ Yc< >zEtohbo6F =a \E+@)l QרiY s MGK ?sfLJDkw9|3C?UPltGkIO=Բр >jG?ҸcyTt.ajQrϗ @ȋĀ^X~8N\}. \ mTEj0 Ļ5{UAà{>JTU&tH%2 t wZC?bjh0R{ݢcϦ_~ vϩtur9ߢhn ^a> o·sa#{=@ ,/r E|!`|GC4pJ$= DA:|Ӭ$=I'&5R*v5^깺ՙ ~RGճ!s]EDS-VAKgɤO~kle2aIb%DzA'(壯W?**Ffqz?W'Y.ގ|a]ff2B;Y!KKL%!˖Ck{P=;؆SpwyZAWi7/Aos_,u ߯%%k,{9ϻ&MMmJccS+I0p ]Q ,ѱ`A?!;bPGM]"KQ4hLjFe o;y"Ai ˲Yk`TZ&?5_K!; H$^"cim-j[Fd -%{fw`>ݩ#|[BLSUQ|(N3,!ID7aAL# "`j'cR}8\0s~aa›`S\+n¦c¦ׅ#eIß*۝ ^CZ*yczB|LBiȶ!%d]lt؝싂S0Y"R: CaA ֐-y6>zSk{F̮w[kI$E~g(ZJ)Z_:ƠKS%Z*^-~+4>?{(=ϵzml)i ZGBZZ;W,nP;IyGB?"Ne&o|zAU<6Л:or eA] / AΟرj/Iqk%yz*}UEOkE_TP^fNk/R=hIik":HMK[4\xv"jN"vƇJF Kt]ߣpݿwI)9J/ M5Cr?$->-B([q0jo聙=1\nE2&ɰD|\O#"=J+<;1qh~ 7\(!Y1I. ?z/"go,k!JZvjkcdR)y9?A&ݕ+:EʾYAr aWdDhIUBnwA`Sͮ3͟#ϣTy/ xޓ'3[6e,#؍z.cGKfDSͨӶc*1iңU˞GU[+E'iL9AzۺD<=UHtC.5ΨT:K?uϮՋ4>QK:./>+r`wIYU8ٔ{Kp81>*rҚra ~،KTp?"X%, wKﱕ+0%CX]vU3^7p}v~C6|h$Yq; ɱg{.weAv? #ڻ;]Wژ/NETudn]us_ endstream endobj 70 0 obj << /Length 202 /Filter /FlateDecode >> stream xMOk0 :+[n+[` |;um ωS ~z< x0MA4b8uE-jݥp ;Cq4BƜ8A9GFaA# {AD:yA5v[w]FmgQ^hg [0HM0TccAxZ!! bDR}Q%v΋螋NGp endstream endobj 50 0 obj << /Type /XObject /Subtype /Form /FormType 1 /PTEX.FileName (./a1block1.pdf) /PTEX.PageNumber 1 /PTEX.InfoDict 71 0 R /BBox [0 0 391 258] /Resources << /ProcSet [ /PDF /Text ] /ExtGState << /R4 72 0 R >>/Font << /R10 73 0 R>> >> /Length 958 /Filter /FlateDecode >> stream xWK7 ϯ[̊@ΩI#(__R5q`O lR>lg#}8MwÄqB;[1ͧAc ft!h9m|hʱh ]6xGװ© !VjbCPz 8Ǘh?8ӟ=H0)yQ*uDs3\MaR6,SymEʰ3lsi.%pvE 1`p+C!8o\l Cl4y#aޞ]pruK1Œd59>8[Ϭ q#DcY$/> stream x{XWYvg$ɮ^E^P.e,.tKw kbPL4ŴdgYI|{<{ιNKx^zj*zT}aV1n̋8o|ʤuWo?qۄ% %xO+~QKL$ӉXOl&v5aOD&ODO .wO//$|SɏrFZIgқQdAd#N3kgrLrfsrsqs,9v q28 N9͹¹%fR2jKS;CS2*J)%UAP)*u^P*wh=֧zmD7;hKږ>B>t0FIt&K%&~LMOJjsuj^T{ڻkvזh˵Ss+۴{OhӾ}GSϵ~OMwuLיc\gH'HGt2tuJtut:utN\Թs_gX+t~a&'=a'̟dŠ 'l( swu 6j9biGBƟL3uww6)rX9m#;qg4''g'}6{8gp崝^~ܽ]ܽB9x;M0YM=/dRw?gt:?m1L35ODΞޢg@OOݑr.vsvp9._TΎcǍ~"oDZ#~b֏]ǎ[D,^]upqw_l``d>,YwKC#͇K\EZ{2^l(be6&ͫG D#q㼗,e;_`qK=%36)<;͹o?үWTWG,`L`![ fG6J0a/l0,` ,fl0v0ã6rְ61+`Pn`m`Ӏ:p>`'8* o=xHop5)hMv(36pA }xx ,H0ȆDrHHH(HhHHXȀ8ȄxP=.C'M-8J n8PU0 w BC ) 4Cr:9I"gsȹ\H." Ť!\J1iB Wr-\On 7Ln!9I"w{ȽiIZҚ!mɃy'ґt"Iҕt#ɣIzޤ!}I?ҟ  2! % #RNFQd4Cƒqd<@&L"2L# 2"2#IY@E,&KR,'+J&kZ'Fl&[Vl';N&{^'AyxGׂ0waZ|  ӭaz X3Ì09|Lf.0fY0fٛa~ saN ̝ sa̽ 6<3 w| hXX‚oaX8 ``=za*,aX!,퀥h!߰,/`c$ LvI `VaX:V߆5`3X:Xo \ؠf8n20;¦0lͿÖuE`) |.쨃$쌀kv=`OeSK8 7,*`_ a4xz:XnY 6l[]vOP!}o8<#ih ߁Npjp N/Y9\v]p5Q~ 0t<w8v[ s8pr<CP8 P:Q8gfÙpζ9]8 p!\Xv8 , .o%\ z`z ܘ 7uf n~"}XpW<4>GV1<>sϾao?I YB^tw[}1?ǙMxy^?~og `~w߇L0O`T̆?d/O"  `Z oqDFJqG大/'n |,@*qs 1Fކ&ʋB7JIL݉ɓ!3zt7ۂd b7}Jy&YuY/8ogf&英 ΫMObm.V:d">DK8 |LjL3܉x_AD}|fW_-0NɏC9HѕL+#220"SyL^J«ںI4\% P L3$D tRdB5e4M9DWgImLFR즠JsQ3D{n22X9)(\4@S<%7 R6!,[*n sTӱ/ n~ڜ-L Re)6]E*yBi/kT+jcI%##sLw2  iD+ezgw>BXِTd"wR=f1ceal܁8֬2%'5$!Oe5=BBnIH WxPIKf>X*=<o8RD-%[U3Lu?jM!U,pڐ&G7inyywYRh2J26bޣؼpKdbv^Z*)C?ҪYN&,bт;qnX9Kr&6Sñhh}Xq)Y\_܃QwHgWOy%%nSEc 2<ì0__f)|ڿ| rr 96z!b$#K!a꼭} ,PjJ-ZCR1a}=pT<-eV(! xrtWzb+VVK% 1f곙xW,}˼+ c>`6sr)o`m߅5),'8x_xqn+T]bm%nP*3)e"%K~DP>9Bkәw.Fv Z(::\'F'-s}1{YhX+'F!$ 23 =f6()Yɩ($8iS dR@rA J0YxgWc9Q"WsBrId**йe^~v~jk*K;\L)"eYh|IUb.VBQ >Rɂ[e\M i/qx1A(IS6֙ 2aiy!bHs۾va.tHzӭ^HYna>ǃ r^"^5ܤ8d]i~VRBtcpԍ@#"vJWcxrE/;Y|m/ZY S1VAna}c/>gZ4lcsB˛ՋzC=N-@;lSH?_@ۡ}*r{GVe>kt -hKu m [;=q 藆 .m@_z=|![Ȕy"Yr{Ub1:G8x{ORD;IjR$C'~GU/켲2cX%Lb͙n!Ni,-enT&u?U}Am`>#0yTh'D>5AZ9q񅺣[6Ϊ'>cu Ӽ3ʺ֒|w7W^2eQY}||Q+iGUQxIJDKx"OKi;Ts%U> :U~<:e>5KZ)DeFzԌBˣk5iU4ݦUAZf22 ?ۚeIMւ:cV"5 ؔTHcR",Ϙ.^8i,L":Ȃx!UW TtO+VYUIT-1#ns2TS)YI 2)Ϊ.ZAmN(iR]UYA,'&ꆠbwSl[?V+ѶIg~Ud]FuTo[C-8#0S''͗U-^~yBqH$&wX0 FA.c˔}쿽󸠵 ;ק0t}~Y74Uef%f$ eB^b:jA튺jED5ezo$f_5Yp.4RU (r˵CN.?2fE#=>KYٽkyͅw~5tGlD 9&g oY][< jTc9B&ϓE?vs9?"B}}? |Wrc>EC,h!ҕ,\>V%M _ˋ l㈱ȢFTEco1)*`KCKTJ' 5|;?ύ%$DF'&!$OHcPf``U{lw|l+-,O{kT2dsoV{:'s W-f^:Y")s:gg2Cx]QtfQ;}62gaMW U)4 nsTxQؕȋȂdRebu-f1T;[xusgL'Dc{ ;FOulF=q5I&g<;1%F-wg,hJ)՚!%ǤDDGth;z53jShM04'Y~g ݐf+ ,ISx+%.9>9>%^?SbȘpX<O1fާWSuʅޚL}Ej~2[e*2^[bNH,('ꩌdp=^QctjDI|QaU.-x*G*Y4ZC|l{CȦܧ/>Eu'j61,\7eY ^MY:YZUfT|t;'SBz;H dVD MlMu[u:fkTctv4 ibOo9"QiNF_k+{)Ql!0zq~\vB6G%-R,!S^zOeʔ&3/mb"]Rcґ~J*hg[:SҊY0J־鼜$ϖM/da汬#yjx6U߰/qo7QOBot3+|,١nļ$B>^̬Q3uvTR#e~IW7J156]8qWO~3 srSP%Gxd2?71ڄ( <1Fz؁)-j\憍g;TZӻM]Teɯ;iL-JEhl댒ڟ$6xpދw_\y-M_((+\S~CYU[P` TmBv X~1!ab=QgH#CyI,YT-*; cLȣK J+>o}LKIA1($:vP|p19Jt~^Jzӳ2+VȤ1%Hd1姠%KsP(QQU؄R7b&I Q] E>]c,d\)7*jO4;H|ÊP>>Baskc%9^eHflNߥ#,6C^p2?#Ra-=)e =+A8Z@y>> {I<Y; i50pl?TV!{g#e烂b|"k=FYYdszyYI5ƕ &zӘ&#Eqc;SR! bX"emTsj%^:=՘}9Y'^~~5u5u^S%5w?hNQ[X/Cmym'ywlsrεE6zֶv wF`Kp-&˶mYagW|5MEz>WS-VVƮ^/s1!!R'f6sHAEhͰdQp::*J"ϫ[Ԩ1P\c#n w^peTnZNjjrQFa*JBѨHi,A*)4Ӫ *{k[>͗#/tj2\(+)kB MUF79gzT8~)Z?_?=Wq3:Y{S,:g+ZNVwӣSr^孨kmtp;lb/ش5Y6}Б--iݗ_zzU5tm=sfLȻ34ᅥcrbfd[QC_u1fNWx!Ue78$t3(0!UΡRqQ8$ T1p`">(+@W8We+#X7)WU=hVU=UQ4a>ë??r]!1-k:O]nrC! WMa_Uf =9zЭ퐛G9=#))]P[DZ' ]מu>fl a!/ba衝h}ɹ>@l㒀P"b3O1uXzod1zHZG3,W "u^BJRezMQMMúЍ%[C G)t*CT$*Mߒvj9_%+ﰧʘe/T&ᚇη& g,<-ضwӔ{ (wxI2ԯȤ Vv :*ϠXhw]p8^I랸WrrʧO-x |qz{."rO%nYOgUt,h#FewV-[yQsj=%QՅ ͷΨ |eqNǯ󹵣~jlr"է90>5d)Zk+Q$xFFGGGE'ŲbhDU:I=Q Jd6CAvOzU֡T[ԋJz/swG%U}ؘsB%yͨ55.B"Ǝu充1Bax~lʤ{kbfo)mm=KkJkk*ԽT<*3/V>GC󘫣{q#>^b\3<sY5O8NmeKͧMcZ]K^-_y[-9k,4#gu/?0(01hV̋נQ/_#?4+E ŵQ7o {bz"1]| /2uYХ:TGaM՛n¶ YLo Ϛ9}V80p6b3gܭateē;vHsܐaoZ'2oi۷x#ǘ؄ev02fK`^ !Ze¯NP'8%Jvz %ɢVau}SqyXC?[U^JMNhB/2C$ bs3!yb>cS3ۣ:r9ͦ\:XQ%( f[oYs[U=%=tKk=h߽)Q&$IrPw~tHEeI$=>/6OʖTF|idIHQ "WVJs3NQizʌTAI 0/00<:NB9uCK!AiȇKG3C-#-ѵreXNCQpG懕d) 5 iiYiMyHXv6&|~|rLZTFdWwuB$(j̇Uq]n,cSSROܾ6JmY;ՇY{|7=jX>dZZ8 a-Az,(V$"VԒ_]Tjn~#+rRU HYSk2|qE(\X=ŕ4si?vN%VE2’&y6^! '6>#ڊEbDG]wūY13 ـ*kx0NeĿa l,R=2EK4VP%KѳW`quԥwj +wW_( K;׬k*:ޤVVTpa35UPxu 6yu-5ӟ7;R$qK$˔"EzfZf8W8^13+YBPtbL|85W_ԩ/#{qSx%,͉/fkU >!nBskY@ـƅ%~YzB"̕E(㠗.W{ʇ՗كIxß%~MxfO 9|/nx׆F5+;Cy.-((CbG$qdZr0SVR@y$C,(>柸=Iz083$-%!iunvJV]Qژ4;˳bs2`eZpt jc%_T^R :73zbc() -()hu=p8Wl! AOYsx ҈-q1:9C9#3RSS39)(.ž }Cm u7 ?);2Ogμ3Hxk{?0*;s*nWot,3܈y9ժx>PՇ˳y(򨯻O#:ԈJ7iZZʼ;1O/m|JɭmiVv~^S̼yƉ԰ǡpl]7>\6C&ٞmuuY- ѱT>3 )L"pqh(\UoSbjk W , "H ?C )%ii~/\9)_L(1 J/ ,(--ώ-V *ЉDE\DU¢€h!TkjM1 utvD:ؗg,/)% y0ݩu;|ݟ]q~!jP~gcͱjYH|||l@g N+W7`laѪ듭y pD"ؼa`;\xɾ9ݽHMHl 3xxZ{ĵ. f~:k[<;ٹ.{cxj e]@b؆#*zc׹?@sתzQXV92@qsKtc%rpf. K1]{/w75nآԍ*3˘~TӃSHF3\Z_Y|jPPsؚ1g/|Q r!!f3[\^kl3? ZȖ4ş ٖY#+|cdK=ף4x>~ZGյVAf 8u= 7ͫ<,.nx/6?鳪m8b!Jn]:ކΆ˻8^cfVry͟ď1(&X1¯t~==d]a>>#U/]ud[ (!*EزDZM)92K e!HWs`TcУ;gg.+m֔oAK!dFvЊj[œTӿiU_7`rBE$ D11L¨Xg*é~9HJϴ?>M<5\+Z'VePxן!=`޶A!SJ*M;B ^KT. r4gZt/T LT&3G1~|2 C#$Etq^@_z kwWW6SW(C(?N]`-F%ÎlwqŇ7'>e|ь#:"!F)[@;$_VTKF))Ĵ4J喖I}^ѰhZYXDdpZQGmu~m #7m3hFk⣣%QaW(nTJUI"G _:IZK6A.Ox&IE_p(f!:9"nd>_/hڎkeWio^ҁ ­]܇Q_}+|d߆qCy[>cɼ`*En!/]e{}x*/K/ C$GZ,!X`ޞ#ʾ&!9- xPخ{,!~Ҫ2PxYW$puy"  59$>6ɦ 6-\f!uvZ_QIRYR{u|WO=lB,ULǻJ# WD$A)F > `8qȅGE"bzk{'S{+y{.ҺX[Uj)J;aB5:L[GY~Lsq:K 쬈ej2zb PC֜*ajqg1vq))I9i52csmߞR]?/'XcV3 YGb7 ъIXh|Ifu 8} rrbs[y2c6Z `fLm7hrSoI\ݜFp)BZ>Lukr(5E^u>g1f.b-9F<#Z̋ŝP_Wiu$Ii~~SW]]9_JA"XlQG'GѸ'CP a^|+j5 t^\`Nτ*)^TŠ&Q]G(ѐ*:# >0i@.qõPl 34>@pYIUk5…^qהMuO4-ܣ?fnoefce%?i ߰F#jHIU"vs+=P:wi`" [(PĄn4;$'f~({l8srV?3rg(y~^I>IATob+w{n a"( 'h,COKq\L(?[tKLK9n` TfO{v ,X\;t{r/\G79ɚ7Zыt~I8TL{ K}oݯ{ҳf:Il)Luܺ~^w`vTudq5&+\53Sgj`axJ dgk,q- rxit:B2T!=PKW}/ʰg>G< &?>[㹷őt:G^ȑ0t".ӧe3Qi7݆=IO76n'G:M~^c*=z],V^}7_EأSYx!/G]Tt\#dvWDŽ̩'ҏjhݦz3k֘G~t៯:2Fdڵ|ټz/s=DY\ڟò7\\U듗5+߾BA_Xluz!)n Ȝx;Yǭ݅'8̹ޭf{LX5;WF{/`.o fg _¸7E_bث^I 0Dm#_/2drS 1 I[D1;,h%ZECmF^rr}Lt+ ?T j@ jH99G`֯P9yY#nt,D/?/X4C ]Pň JIymR+x!bvԊ3jş7<OwQ7uQGtQ?EtU8;\;^|_E8)Cozg^ϰg8g44Ę|Uhnf$n;p y0Xwn)@`-R$GL3A95τNyyV3A5=Ш֤/ ^1!ۏl?2{Ӌ}IwC8S'*b]*&b 6;ڄ|Czbbe }[<ѣWk=7apF'& #p9{xԥ֐y5>B 1>qCfC\Cj0A$*H;E,g)OxFc8H$`Z7^`y(%"2`_B{+WƱuzquΖV殆h)Z&611+r.C'QiN쥩\ɏtŕߩԤ ~9ZL68lp%3wj$\SS÷!/k?]я{c"=DOz&෮ڥҀ?x|mn9`-Wݵ lLMȴ*s٢2IZt|+ =H:=Ic?zTyEL$Jl[t@o;H}S '$+4xIJz!Hk\Tޥ!"؃/Rm&Jw|5 tH%^Lln"Z*V]W+_FFpUp ]:%:~ϖ&@3t7*4Iu`q.z@+AuB;0xhX%z<=R2O`WeMcOVSOH/% ~K*T7t#,#+@ǍO:1?4 \˪)vkujruA&A+ы6ZK\P gwC*7Mz0h:esLPW,B7[ o2(.Ey?Y(-]op,4 ȞxQw+P~->xr_ut[wwTh!y/wvuE<97F pL[RRq˕v,v˿,QJF|m]bGXS}O_6uLLhkrN}|0jo聙=1n HlB {' XÉ<=3#˿cg?96oVrt@=Ε ˁlCad>x|UbDw֚lX׻enclN9.9akB|(2"88D>Cb<0(Qsl^ #nbKA'k #){='cq ?Јsb>U -調`:g=FMam`r=.eZ~x^h;7 U 1IǑZXRۋ PPHN;QETTE#ntvG; =DWU'PKj_ RkHnɫ [RL>oN C}dt_y9X}z Z(v㔴m!>1]e,@MSlʂn& MRʔPheϭU{@gp T/I.xXEgj3)?~L^x`1Չ.4? .qPz{ RB,َ9}wg%z0I qw4,$#fi$t$4q _`4lj_qLsF k l;U"j`a?'B1_[%;iZ8"j`Ν=,NBuk"Oceye]$l俁O8iR&I-kJF DB+XM]hvcsᐻ*ϫ"LBID:XX;$:!!G)@I_TzJpgb~@x5}}+Pi3U OWyPĖ.e#})R]1A堚5 U\5 (I _-JHhMBJg'%f vd{imjR BHcIS˫a(a&|r|J U˞&Z Q8XOs- u~?J̰wWv>Q6s\tt\D떬FP8d3AAbB']EF\ɏH1q6\잜㛎E(*w;@g*b*MPxuM@MiÐ?yiCBjUZ&Xvic)Hb4aT$gVeiy{%fScc3ŦG$|.zG S|ICW. P;7tSݲ2~^R[ =ؤYB)RJx8Zc ip`NMiBbPHĻEkX盏J51 8h5}Ǜ"-V9:{2l?n]#lqVxdhByRb[k[*]Xkh[QIw"t,ŌP mNP8l'^Alҙװ2K!,=,X¸{/k؅g,Ox zxHNWTmVAV=)A%TSRlT l6o&{Ygas*)# 'N.3!(!YھGrg{j@YÑb*.*Ez%?.MvHO &o- *DZbd$<FQˊcuWXj[9fT,G)k_XS 7`I7^OSk;I:MjL,˪j ɘx!E4WSĪ$ ⛝dn*^ |yḃi09!8u{r3Q)[?ͭHӭfӗ؋jz_>z;o;m?_w8l # 1^uϮEuW6lsLP0 Nw&9`TS~5JyS&ۿlՔq@~d fkKmWWPˤ }*a?&o2RgӑP[31Pо:8F͜-ڳ=eе_"Ȧd ko-e]i簐y>')c ʪ=-n"}>~ ?3OMU#0 gv]6Vr-ªJv\& 1l^Ix>rp9yb5u .n XY]"ȕ0c?'u P>0Upv{Y[|;>X{q|ږànn6 nI*/M 2ų.DKя Lopy[eyexɘf!iklW{{Z+PaS'\fՎH~ k>7lM#x.!kyKNBB+R#qw `ک>uMF:kuĴHVa]q'x*1*. D.ZQ2lv q˱<":jflUt$-HKm ]ُ'jƷ{h_ hfVoֶV+8숤v!o-^(nZq} D-׃;S6 ӅJEeW+*RnXjٖӵ(r6TS̈iOC&FvW!3daCV}>4*5]S^C*DqIqI1-`(M sBn+S /QxHw]Te_ڹe2}eT'дY\aGޏj%WQ g+TEu!xہ'\F'P^v,VݾOoR2=Yj|HnZn5ggg݃7% F¦M݉߸-qVS-WZnBՒ yJ,> uG𝄆Pn |HyMrq+`ƷtN &}-0z=C8-RID,b[?݄ -1ƅ\s?_wGV;Q4"qKbr~#SxjOu\31m&N][|7"_-.y?*SPDkݞVz:i/O9hys@~k7qu5LoiJ!]w\W GeiKnT5&&>%IN@oV331"-kÍm6F}L!CY'/6V7ZȃS[0SPH0gWeu'ȇ[ʳ~s͊SB筇ewҥ? tމ9d[-NH $5۳E+ruux2P9,e//wwůi?\vєI^Wjx e2TW{W̓26k[~KӛfZ҄4dHO~N`Q<hԤϑ۸@aChKmjQXU#$/,&B;+[ MwYg6b V X [xw>yA] KaωނXB\ \J=#'GNA˙Ӳ3RS>0qy(sFf/SxIb,:,Om'ϰBiQRdZf-7 [yQ3ZeﲯB{3Π hOA.p <ƙAsM Y5#;-Jc7(FE>jZ%Ll)dlwo;I>8\SC!C ӥʕǼtN' ^sЧ'}K JBb)m"26 nB er2ca/i_;.M4$Xkݕ8Weq ~oxgszXZl]D9Au彛IFaЊ4f;Nt 1#BkF:ޣlW_d&3iwy4H?$[e', MΉQ t, A7b'\c󳶄iX9[#saÎb`pF(Rժ  -ni MmXs8GpuoOVcw( Ea"W{;xx$&>0a≼$U܈"!ܑ[E#[&\-1) WIת n~`btm! kSPy@s1ytO U1t{tZ{[]y؜CʆI:3UE.{"^Kq8s]J(لĠ %G(dw+tC޴ `n!tp-ZS6<+Rn]ql22a6x 5;P@ yH٨۩<ϳ0~R\0T:sWQ!jj)O2*'%OǠ0p|^ _<(l诀.7RРBQL4J/'\{q:r|0DL+G.XN'|"e4)(fKBN!f"Bt>A"AMsHOOң5cXks0+4^EIe~"Rd: ^ _ #pYz:| _w'"7h.Yw}]Q|)EQ16`jLLم-ZGoذx@iEa MrUQG92Q|.vuXSX .t{&Ւ(ِtROZO^ {kI rb}I!kM`,k ꪅ{q*F X񫲱v@abO^ܸ^ъe`W|k-<"V|~b>#1gu+砹̲; RSsm}}}} Dohx^fHQc{ MVE/Ӊ^l%&=!lGjK4DO!6)왢Sҧzݰ QVC^vi&~^?Aoj,YvUvVy<Σev*rjɱ*5rA X\#LxsXVWj'JcSңwj$Ɩ1 3:;;OJM{}zC!P΂:#ƥpF(X@#GX#=Ư;!ڋf(U*+)l%*63+%9+6RxΗP.,Ql [N^A@cAz¿guʘ1$]@]xɛ6#);z uW*[9U`$j'jOn ܇8*O-~\2ݿ$CiH_MAL5%8bڙZ074hϏGLO v} ѹ{2B#<#c]#}*̳O45\+y<-@['tS^ׅĺZ8[7bK\zflrjh{Xd(Oώ)*r['y ^?7:wsmժt~1%϶FtUqv%*W 7^$/-Q0Hw>~I{< z2/;bG5sIu,sxv*4 N8nup+[+T˽i)QI(qBDFDFH8)2^;v}gbRS WϝzzUƁc%fU&yO2OĔcn$/pn`R'E-ۙ eƋwn Bf7$/'094u gk6Q˙ omEZ)N*y{!v/6!/XHŗ|=iy^cHYd/7G;WFOh'[_gdxH,6%5>;=Y&t4]2Co"_yL /~$6Y3V`3~JԫW"T6ZN#;/31uçr-Fe z!{x=3t^8N^#:vuc7َ]Jw@G'D0mYH5ŒRN0M#r,vn.=$ә:Yh>b+[x8*KNPGV7f:+W;uk FX9z"5v3s j9($0PݡC5;?jGQYEk\̵AGg; HKG\I𡢝(okVo8.kh0j_loQ6jȧ. Q0l}aOfČHZ:W%]~~1惧9u*T$Gܽ5;-aVs԰iһ;eNpr07]P;$, lV*S<70`4Lß# %2 LNtY _V 9V(vD3rO2IiX pN)cEܑfh`+IhV,U,>C9Y3>)F=<(c>\ipJ3 ,T^Ҭ IG6yvDœ?H9"-͒ϫ86;)\ ~G>C;2te\an=-w׮ޱgڰJP_j3돐[j^\ 7x)ڲoچ!^ Ы=q4ʩ"T<>e H8D M)}cj2~S?xӻ@ȯu Pk4~LaS4*|Tv|VraZNe(r` 4T+ѦLyB`F[RYK^뤾d}g%)՗q}IphP$&j8Py4iYG)2ǴE /8[4ڪ(yS5 J=bB*R>_U{K M[Bɶ aL#"7g5!yBٖr|zRZw5#X)<̅#jU}b Drg}~ Դ[ER׽oW*ZYisr+p!VS/1 EF` 5E cIg>v+nde..=堨t|G?uÁ\<]td4,ًڽ(G / bӮ^IzۿyHbG/U8Iz0VJ>BM5vf-љN*8HBonZ)Fe1A6qWA#)٩wvBrU`8%4(w$.I`(LF0{)Ԅ[&@OW`Sr3v ^ߛ/t`zBQ@whOnq='NB88VhaZk8.5/CV.vٝǕ\=wTi4g>VIHm&xejUN)錪Ա::j -TU߿ע:>W`goR?>r}^,G8N]:>>sXoT$g]֪8}d\=O!OqbĤ t;Ѳ'h|;dF>3Qo+eM˻U2Y*+XNki! p )Tȶ;k`YprUwrD8L]RRow/'(% =}qsF - f-n&lJ[`dՙF[[t&8+; hr\wS0pxkW?Nn RԬnYc=K(}AĨ KűĤL76t{`2%FĦ_FВ3D:{C8o-Vr4SATފ\f|ImeVeJ;0הnWF/b5XBl,g c Ig@DlAZ(>2 .tq@~fM<]щF'2h04"t4uy|e!V ղJ= BWFy€rʴvzUjt>ж+Rv+fsGZB+ *xbpo*>(>ZyqV[h!&'-+mY{Q]ڦL| 4N>ԔzYn& &eP8j) j2PgJ"oF. 4n߮[s:.et/0|!a\sZh.SEk"vH43|JZ:ܕh%Zڂog KwEǑzh[`A`U~SJ`N^yU`7A~^.SlX8eDnނ Yc< >zEtohbo6F =a \E+@)l QרiY s MGK ?sfLJDkw9|3C?UPltGkIO=Բр >jG?ҸcyTt.ajQrϗ @ȋĀ^X~8N\}. \ mTEj0 Ļ5{UAà{>JTU&tH%2 t wZC?bjh0R{ݢcϦ_~ vϩtur9ߢhn ^a> o·sa#{=@ ,/r E|!`|GC4pJ$= DA:|Ӭ$=I'&5R*v5^깺ՙ ~RGճ!s]EDS-VAKgɤO~kle2aIb%DzA'(壯W?**Ffqz?W'Y.ގ|a]ff2B;Y!KKL%!˖Ck{P=;؆SpwyZAWi7/Aos_,u ߯%%k,{9ϻ&MMmJccS+I0p ]Q ,ѱ`A?!;bPGM]"KQ4hLjFe o;y"Ai ˲Yk`TZ&?5_K!; H$^"cim-j[Fd -%{fw`>ݩ#|[BLSUQ|(N3,!ID7aAL# "`j'cR}8\0s~aa›`S\+n¦c¦ׅ#eIß*۝ ^CZ*yczB|LBiȶ!%d]lt؝싂S0Y"R: CaA ֐-y6>zSk{F̮w[kI$E~g(ZJ)Z_:ƠKS%Z*^-~+4>?{(=ϵzml)i ZGBZZ;W,nP;IyGB?"Ne&o|zAU<6Л:or eA] / AΟرj/Iqk%yz*}UEOkE_TP^fNk/R=hIik":HMK[4\xv"jN"vƇJF Kt]ߣpݿwI)9J/ M5Cr?$->-B([q0jo聙=1\nE2&ɰD|\O#"=J+<;1qh~ 7\(!Y1I. ?z/"go,k!JZvjkcdR)y9?A&ݕ+:EʾYAr aWdDhIUBnwA`Sͮ3͟#ϣTy/ xޓ'3[6e,#؍z.cGKfDSͨӶc*1iңU˞GU[+E'iL9AzۺD<=UHtC.5ΨT:K?uϮՋ4>QK:./>+r`wIYU8ٔ{Kp81>*rҚra ~،KTp?"X%, wKﱕ+0%CX]vU3^7p}v~C6|h$Yq; ɱg{.weAv? #ڻ;]Wژ/NETudn]us_ endstream endobj 80 0 obj << /Length 1736 /Filter /FlateDecode >> stream xڥXY6~_!IFcQ ڠS݇"ǃ JrC)۲"gsQn޼7ͬb*{H0,QRgn|J> EX Ҿ͂8 l:lKC*j}XJ"Moyc׸nvO@;m;mŗɒ -ͬ ,}%:e]: p?74!&6QBfU} Iְ!!&y:a5zUr{ͻ映H Wg" DrM^J"o(=AŒt]`.?ʋh@Mje 1t-SS ï ҼޟZm_L-*j6-#8Y:qAdm{vLW-:0Ψ('9*܃s~iHrWyP4܋΄ ?LX$d Oj8B :^2۰LFS ҼaLRc9#bsR'8l/+fFR*,U0]]DWPj 󀦂Ea3pICǛ+ BR> =*r`FZw䢣\T4ZK+H3Jäҗ ]D 9CÙb~.r?1Dj"![A

> stream xY_ O(\X|s] -󰸶8xƝN?}IQrDl0e,QIԏTbckL55Oʌ1#fS Rlm33%6J{˽#\gO5\ͤ`Vp4 |p1-2pO\^ks#X` mZ8d›%sf"ˎe9 H9Kyuj x0ef0tdcWq,230)JFL=f7|^*o >"d)P#IG!gܻcߴrTF'/>Tm+IߝkDYvAxERDF #ziay=69PlR<öq<ں*>7u%]ѷ*hsoJZQ.tEk}DqtGt.uLu/|BќLM<&)[Վ D&P@]ՖHfߺJO][xjumm=x,+XrIUӷ,\6ڗmWM4[8{p}NueCqǷDʌӜ|}1S.\xio.bW:l/!ɑTl.W"+(3]Eme=EcOm?A顧(L!6ci&DB_q'zBR5E,Qh1lo|V6~0-JD 5(ϓM'ZtawJDE۹c[ؠ 79 8:B] #>)\(I:L`5[@Ube, t} ޯVG3uz7ڣvW\4Q/b׮wOJ2 ^{a}:> stream xXKs6WVc3ċ8{IxMRTpDJyLO"b÷]x3=F#\\(/q@2ߴukAV% ]ˤ?Vz7?ήI(BեNůf~B@ wHVuE>8$)?[(y՘dY϶_yC?*4rau{ν:jjpy+L|5ᨉфF2BF2)s3;yV%E]Dx4r$ |7cOdyX rH_852`R$p'1̊r_s-41z p'4u?]}A`*GC.<)s/]^|zL0YX@{b<Uw'}7F enlpߤI h"{Pu,r XHd_&GYQ #|2~9P@34(@G_O0 ګ>h#Tp׭`Z|&JHHHOX 02(y ` @q8{(@odtX1Iq<Od@@MR!a#H >dԸ{۵_T\XdBU U\X,AHɘrۇ`ex 8-#xL=7^Q$έ9 ?AN_* ?AFR }3 4 >ڊȖ!ss*wpn"LΖ7'xg:|LY>9Jz2|j l ZN '`8q>pVl˴˔^6` uw>dqK}wEK<+ץUϰ.f Ӗ,Sܼ+ +IҴt=̿e-dcLH5E-:*زD V5t8 Tc~<ʯp.C(Ϻɯ/AX-0o}< #MDO endstream endobj 90 0 obj << /Length 2641 /Filter /FlateDecode >> stream xڭZ_6O<ط6ޥsMsL>(v-9M)Y?(Pn"_p)5Üs?HtO-DfI%|xV,S"03uX-sF,Uʘ|q^o"K?ݼ6jV1)WۼʻV3i7QJ+WIA[3ؓ2, ܇6m]J)~6)j]˷ew >W#Sƥ\R(? #>C'-d az(I0Vev%02Y{#)@02 8 0 ɬSgJPR xLRRnHF<( ~/!-Ozf/: YN6s aH:T'?;L&VҔi^.:.̕7)sp|K)u8Ez;A3J~HM݇{xy q wGdEk1óYCD*s;͈ϐ]Wb%Ύ+@dfDž)i0jeGΗdҼTY]z{K>5Jdn?(,S.HF$O{jʮw7ZTVl9% &a:_fiH,N-S4&9 ɜKX+: 12h,0YQ:_dDi@򮫛2>'?|FAX"ln "58 l?*l endstream endobj 93 0 obj << /Length 1868 /Filter /FlateDecode >> stream xڭXs6 _^Rϭn[[uc,%a+K$'?dV]96 @˓' 'u,Jc$*Pe>;Y؟ RϑEJ/[ݛ&I5btx;M&Q6%^@/.>ySOGHqHUW8ɗd bQ 'ǂ}۩@DȠW'#^WSQ37F)Yi&fE#s]S[e5+:m1;+F5rMlBpo{Xb|=O:!0.+=/i$`vV7&HT0r5F> /XWKݥD9ȢL:W\YQX=<{1ӳ4[duʞVa~Ԁ]_dt4.V?HI!OΈ,ʺ$B;jΞLxyG܏bсﶣ‡il Xa{U}ꁲ]ٴב ?>-\튥s$ߔBJSrp w6uAV hԦ7hE;f < x܃0鈣n6 tù5f 5HavP;CX`po5JҀpF SBoJi9HYh7>2|,[K.mҩUǠw?M)vRZ1.P7P+_llL2[2{2eN^>NߩSwѝeòx~!]{ƴqt>)1A5eZ?Kق:G~xO J9!28C.[i(0Ec Ф&̸U­Ç,ڭ'd]* 3LvQC?n*Jusb8p uE endstream endobj 96 0 obj << /Length 1225 /Filter /FlateDecode >> stream xWM8WPۅ5I29$xLkbOhIOݸw^9>x$\"qgNjp0Hȧ.MSnF9'*tw޻;Muv D;#@%ַ" ڰx;OpܿHtY9H2iޘyO*`gR\G?%{su%nt{7 ܬp7tT bcαqU|70[v_Lsqr}R6-9mþK%߱͒&IZYYvWAlrRPDigPkgcTQQuLyͣiaţX-V]S@ð@W%/%N |@4pY 4Ùy{PqKqB7),z$gQrICѺƬӸ^#LζHM[$owHw>/"`lkݶОljWR͈7lZp/jqPOy QGZX1|`Gbh)n1"ֲSf3)oEieCellрf.pY$33 +vh$Bm:Ӵ&A_7 C5!W E;'Utd3h'nq+XwOXUI. kQ ߙrb0ɖrh[ٞR\Q9}P>L*Ӈu3 ġf-&HI Uż"Xf-~X-xي!  I4z= `l$B).-CJ"Nz~]hB D02%ԓϋ01mʐ ǮQyS`A]`X# nZuYe@[G@+98#l"U'FM endstream endobj 99 0 obj << /Length 1670 /Filter /FlateDecode >> stream xڭWYs6~Lg2TFqj|mIcud:یIB8|wMv;m_X,voptgHƁ,"^B)iG * Nyx4tSWJmc/JSџl|<==Je1U<4#% hNDI;p 7;w,@g LUƸIsS;8SY:*PLfepξQR.gH2%;&yM\ F2 [L|*oI^KZr>YKp"DYZs dT0q,yll' s3aC x32syaB Di 'L `"M1K3$ްbbP3HI-HFΛ?Qzx3<Ému; )LUAt/#i尨L=/lM%g4()+,7P7sGkK߯[QKkt,)E|P+ɲ30Z!Rs\|>\#m3$6! :,.Kn]D󹩊֐0UW/Ff)/iD֕7oPk!\P ֲwlk;D80QQ>! Oe{7c6!ttW | 1XFHc>RuYR%L@ j?A:Hi%49v"Ic._V3-䰊8E4̚˻"/I_ So .Ѥu޸N,Ù'1[iV,6Ȋ 7v'|VZ9Uݩ8ݒijcGuϕ'K)->H❙P:ZZؿ֧O=uNY"Kۢ]5Ҥ;mK{ą||3=舐OP,6WCU}~?s~{a\8MNݹYސs[L^$^M2=εzaN_${F醵)"Ҭ'/p.C_V\IzHWNjtbwI)%qyGXxr9zg:~3HC?vM2rF b >Fj *on\&nB+oܖ`؋g'8׉HqE2z ]rm&H*Z̢5OVVKRh.{ S"ܵAڇ:uNE b\\0.^A} V{x}RےRbqJ[FZA=菷e#-c|AȭS\xFq&D" }s"#28R>$<t%` G ƿ endstream endobj 117 0 obj << /Length1 1798 /Length2 12992 /Length3 0 /Length 14116 /Filter /FlateDecode >> stream xڍt 'tl;۶m۩6:Iwtmuұm۶7}QcT3לsEFB'djo scg k21YaT-]lÐ-e!4r|]mL,&vn&nFF3## 흸Fn9zL#&T&..?B@'K#;# @?!(y-\\lh.e3 h d-a)T\܍ P(82ˀo?Yldbbo`diig0e]<\hFv8YI .0M,\-m0,fg*bok sq=ne:0Y:D#399@GĂ?L?jvw}4~x;.N@_+01L-M\@sK;f;Yzt?Ə Ozfjog-fRV*=tl:f6F;+(Y_Rvf~(=/cL.@Ϡ21||1?]MQ_2wSOouu9]VW\>vAh,n4Ut1k\h6v@E{g?#}l1)LM299y|4>]>\`(_`0_ /d9~f?YK`0/de0Xx:X|7X|``n/A??_?V?; ~r/A_ۿG* -Z4a W'-?] h4oolUX-N77CBE2*ˆӽPP72IK=䷟ J/>qS{0'Bu}xt>o>֟Z@;r]9>Jx~Sگb}-R ,%5Μ"pÇF@AɞM(G{R୽4V܉Met[4wqaBGXrpo:6"Sp _zl*igIɄ<;X,d _%^ԔWAZO| 7S-=v{Cє$3uey1\_1!|o߹tVszpb*+&\tZ 4TݡM"sL0$4r\J1c #erJl0Ρ:㩁iL*=jM ̼e (#$`fS &2w9ϳ폸p\EulSfVYlnY0\dy 5BeQ-s0:*B.k&BH^cMIOoe%/yĤԾnNT;BJLAYoøk, uJTrU9~2j4X ?m Qo-xtri*aΓ%_ CM| 5T")>/O\r}ȝzj/Ԇ V\^Xc)D,bv7[3g്Zdsԏ[20Qhr"쩒j8gSIxa2F3!d)׬f~җeQ8LfIGgFȔiV$#Ḓ$v#N[>TQd!&4 ?K$6(>2 ֻ[wWgʗYD Ӱwx?!S?%cOҪ("0x)'(5S>D^kfc4jvyE{°\\EʎC&N)pJ ?QK/%[]{G%BQTH>^|ɜ A26:Kt㝡v,ɚe(>::ɡ ^H\d߱}H|;: Y'%2ۂ3oNWqdTGr%/ar-]7^u}ؒ䊚وPW!v.VG'FGѶޘY$Ɲ?$`~ T#uD<3d*'F M srhB/ҲQUk( {P7p'_GX" oeW%E쉦 nU瑼-7Κ2{  գ:ĸŵ[TM 6B9ӫ3uO޿^`G?MID#d٨bv.}`z96泟YiQ̓;-}椸ɿ!j OHsq:.[bh 'mtd5zpx-ϾEbqDO":cv"$ $?n-5,d r{pw"'䟗 (:yy(YeJ}^Z~wb 'UO%}$(l;yRpq.>+da]cXy),?L^ Gɭ̫wƒm " _4xXo`) 7Ř:esrD[>֊1gؑ;:,Uj*Gɋo:@TmhWHns(F ?0E)a.sj+;NJˡrVG3ކ{GG9m-P* 54өɢ“hZ}De죪ŠjښPCp4e%#߅L*8SG]Re2 &VSJ fob 'p`%:L#ťģ@}WzPwͧ?\M#ܘe02 ?*WR>eh!z3%j.ow& {!& ߔJ`,VaҺM'G-%l(Dhc \)?O0ӰJGX[:,٬^F!j00cEt}NڮC+-$L="6 [ ª&9..¼y*<ZgEXAI*l&e!&G-`~3dh@`OK\2^Zwev:U} ZXӠ\T}b$*|hnyQ䄴-@q)1U~jxcJ4蕋n'sһb(Lif)K:V.\8pYPin;cigٟ18NVl\J*8ױvd[ըZI. VC1Y#vx5\uyr?}&5rD>k1j.w9=yeeq`e|_|<79-^ېb;2Xse&;:YI'X`aq(TҮ'ⰮXG! A~"~moVA4K2QJlaRAV#b_Us7mbҳ'P 8 X>N8m:AGq!lj>єCTɊ&pŠ}{^&ҡV令+D9<)m ٹŽ"*S2 LA~ gȰ˰s1&bwYE\˨;PyN^2٨5ϧY8aas|_h=ĆPIe1b3Mo>~{Jen39G(2?39YPA_^(}S}ao4,Ѝq@݃pF3?.=x`B3Lr$'hGɄm8&0TҘ/޾R_%;tεN0#Gd?)E?GomR^*KkCZl '6݋ 'a$LtqթQ}S %\uFu}X^tLc! +'4Y/ y nmҹ6ߦx bf=]A' e1u_Ra>lYHē1.S4Ф]ΗIƩRwfuNSsQ?'Hs֢\÷5 rn2$%6}xdnH,ccn_w4tdo肉@:/ OD>+b (֡,[ =@fQgIT"5bAQB2Qn7mwS94)3Ay3HLf6\xU~R(:3* hϲ-MR&~aML#(/}oC3TV F^#x}{Ϸ(ir.ԍ;2|Vޭ}1YO:Rk,Zޘ8rv v4Y1g~B!?~Io+#+vRׅ `@1AJ%J/062ՖYeƪ|\z=2 NBh =J帵 xFGbQ9H?PDDℚ9J OދU㝵57KsՄ&[V.J>'#;4mpLCk >pRE#t$D:"c|A2MV(ea㫘 Y}'JL_i6797,M)wivGf]ɑ?WA:NCXzar`A99g8Je꽨x6ǰ ɜ P00=0CK55ԗ}EJƞF2;Kiu/n6yuzOV5WOlI^&״Q,e~P~kңxcFEq>Q%&?a[zF<;П>ZJM=*(<&IL\).Ai+U!+|W~/PzdI :,Qr(,v2~'KxN >on #o_ VO^Ej ,CW80ޤ_H([(Eqgvg _p[㌎)ÔImΐx[Q~DӱL4}p)\'ሀ_Eۂ-6Q!j$:m:'WleXߜu^x[=(/4^G[栜ʺ0!V=wehcT$Id1uʱoMr?_𦛶"nl -Qq zz*#_$Nhzg-x,܆YEU8FLƛF-9ah ش%kzI#MZ0L=ªlPYiٍjF@\`l|[ z-]oHPqxWn^􉟫ar 4fFĝi@̃ؒ8zN0sz RˉDZ0g҉V2!3<}b͚wwpq2@EMl<"1P+cGcP=vyju yZKs(Ɛc:a͹GC x\3x'=1 #Ǖh"[99Pnբ ˲eG K<+F=ꪈ[+l6 k#&C}">Oz I$+)?9ڙR#dx^7ۋJĀH~R6ZW|}[HDZ8l}LsՉb(~iЄ(~4(4h9Ax}ciztʧ I|BЪD$B);)l[R1hLԹ|cL*2mH'MEY,y0SV wȾtH +~-mP~"4;L ,r~M; o eXzkivC/W~Kzlztͺ.",X"{1lPRM<ۮM? #!𰶍x Ɍwml\K-#oC2&p`R O%}u"LP=!OHqY޺: 2s<_}vH#8^7&: prh*]‰=E5oR*7ySL#2YJIxTcI=$n35uRl><~HX";zo7ӘvP";;ҜSo} (6~ &r_aK4aqmƲqdžIo{,A漿̪/M $#agf[c*yVH1lҚ| rbzgc՜Rk ~+3yj>0^S;jZajB {<tUb|FQD`;Sf%CׁκmZ &'$Ug|nL]omn_{VХ;G95%r(Hola;e<P` w#'yn^, ؑqbs·)ܝ356#)X܃Hsm<Y>nd|DWa/|xe`#2 u%e 8sӺ~ROcP1"[tj\I涘pYX R-8h- _AW6J11~ahQM˕Ap9  C<9*9=A8=թ1OTiʥ4e|DP5۩ӍW i}7,Uy;Ƿ*06` U$H̨^L2{SG]0m`_VQەm|FA?ԛoՙgo*$jnͮsY[L0o֮~߱TxXx?NdBKy {iG!S,|4mMno=!/!S?+O I g2].; I]g Zn^Q[Gb=bgr\̍撙9HgORq {;!' _Jq`P!66H$` j4XGa fUXnDL-*Êh^y.^)̂hY?lth Ř)&]H:y0Ȋ8M\F}@-H^,j`f%7% 4M%%բQҊX\:dJ/+Ԇ @TPA(.ug=+=Scp,E]ťU\$]>r?z>&"~)y[z &Vk/W%9Y(F!i1XOKle.%oy/$\H\;bEy*xZaFo2>2 ėw& ld1?緩`+,Wz'@] z~)X7XMjѻ*A 6:0o ;U_N3`&⛍mqfvqGQ_3TEj9]̗Xz)yt3هԱ_gwf'C`^bvWOxȅ2j r}J|@a')Mp|J$vee$< .>;6_%-׃Vw }W*YC`:Lgm|0'O1[r^ΚssvP^{?nfm!7"K9or eA5aXtgo2K!*zvKP'#dF(31٠{vr>[LǩU.oO0P *qBA9MJgȅW.X`D^ Ku]4{) L[w; pE_880FcGeTۉ5?AQ͒+|i?g4K%@赏I!+, !NZX2f-IBuyWorFVjՂVL^E!J)S8oyZ*&8EWӺ?snz(©lg 0ߊ[8?:YXƎ;%W*8 t|>1/'?`>b*N8b\T9FVOa\ʚ1 7&-til*c1)_nli=Z0M!e{E/ }1O`5!0*6?DaeXaQ=WW3*m?.g~UYȼEZ fO "|*fw/~v[>:ڦe| G`k|%maבP{ ".bG? :'kjݎ fE7ui H"mBф:a? \א9y]A6#sj.d+}{y4-6oeDƩ>-E7=o'S2#OB=~-/\%_Ctb(y1W2Lex+՗]>0^SQ6Ԝ{\{:a0创nS?;J;bDNI4jvYWx2^ч.dA)? /-fr!\ذ ;W(Dg B ,kJi%Z4o%f>bjK}M2t'J9KXQ*~ezV8{$AɀxZn51_ZBX^vqPQJBRB{xB/ލy%uIuH31R?t>q RC ";X`FPHT=Ä8]**+5Xf3i ~e ;W4(կZ|+nFwrW ilNڹPn0-sp+8(?܏2bS;~sAp :(IYW fs^jvOEPH9޺:r€"/۰lBtC"E3U)>{%s"F~hS@@l=S9R ٦PW cެ68â/ Ǝ|6ɍ7RImJ5Nog[X%n@8;=8[?Ϟ;ԐQDhi9b.@-bI`*rf˅Ddzv:d:% o6$%}$6g^0bO5kU)3oq̓AJTSjҌuU6e ndvR>.=7d~.ܷ1ݳK&X{֋I'=kpe0[4W0)2 SYҊfj6p: 1L5.3[SC;~κK (\YY VMtPH]uO/òxNOxIRkOhmKVYQ fb߬ac-\/RdtGNK&vުa,p܃㶍I$e)]QW.S<:?06!" )drsHfkh KK6r'ӊb̟ى!!GM7G = 3ǢMBX Cx) LJ)?+zɂ6#m#>cr f-&` GO Wgc3;X7niFXP8Ir=-sOfhsr+ ԁG| r?g!# x 84' uFcv1RR )ܬ(CaPٗ%"-ЍP7Yv, ]"gC?$nƦ1=" ﬦ~MCFlwb@)*mg'n_49-VZ #KZ_OQ#2'L/B햽&/&ڷ͐vuSSqhdέ[+ ((5=*dHh h2NHY)dV=wdZcPYgz bּ>̱Zmov#[zE} Z v$_k̤&}H[joJW1DT8Z#r {Z!]^[][إ5VGs 1dZ=]GD}#6f CaCqg.1W "EDA| qxֻ&F[RmVGpXsv^C;ū-fk`ezbth*-ju;bљ{tBV^ڨhYc}ܚ'KFn̂YƱLY WiD:P \ 馔5#y(}r=Db铹)T&Г5 z4LJɀ1Vz'X`m \V3Q_ta}KI#ƮXNXBEWugqD,w~S6aۢ㣎etO&n?npP;93Y @X̡~5NhE'RێkUCQqE P ''QH.eF!bSF":xNyL=Mf.v.Wf()#Z9Z`n}d~e+qD;UGX÷YSZԢ "WfJ>Gd(Hώ #_‘ *#V>K*s-M[֬Ie~z cmʴlP% >05z7o;6};~ӳsC޼0NtJ,zpF}E!gޙ'ЩBmz#q&O- 0D#Z\aR(xR*-3\tBc1ۗfZ u.B5tlҦɯR(lw]jgoZ21ί]olԌ~;*M PPz$;5S-#Y4,96C\Wj魽u/![7)5vw9؄,D53JhaiqYQ]U ̼RjBrRU8JA76?G+9>M-+wG$x_xUI;xnzqpI%p@m3{ڏ>! -|[ˆ py8> ѣݧGci]1x5JyIDz ¦bE_Z`:NX&RFx\klDW;' a;K^"g8`␯!lMyE]hpo<ٞرѱR8}Z>)>k'[|OX|us.j~쎢V $cQnpFPta3/As?[|Uٗ8ڃFH,_`KS6L6<9?`lZBm[Zbj`: 1q/zs ]JI1sÁZuЗ$}7$2r3`J>Җ;q|57P (ԣADbx s1ĭ4ҋeaӴ48nb`τ@G69dfAvT&Tţc[%t{L:Ri'r<}^])I{b5h >9ewٙWSX㑲\EߺAіC:=RqU?Fdp?['"&4iӛAsZd84f endstream endobj 119 0 obj << /Length1 1906 /Length2 12539 /Length3 0 /Length 13697 /Filter /FlateDecode >> stream xڍuP CqPݭwwNqww/^݋S\>wL|z&XQN$ncHD db02322Ó;Z#'W;XsBt| lN&;77##?6Q1@ mc r'u775s|*#j_!+ t4Ye4ZTlAnіŅh@ocoOM p1w4(@ c@+?ÓTVؘ8A7dxP(؂6ۀ߁̭rX̭M& ,#-hmh`t[ *R:?#{s[Gzs=2vb"6VV kGۃݍះkamb2166݆-HJ7)@Ff قR2akc 0ykenzp:N /+FC5ob]:o`7 3tc#fRRW*m\tl,:f6& qWwom&3躌lFooL/S;ߊĝ,-SmZ[c6No[ g T X_#mM-{ cEsG#oE4)8ZtLG]FoׇL-61el= mLoh rk 6o.&6(;Aob0!0!. XކŔCo1[[? `PCo1U+A2hz0CoٍKO_` 1c/|+_V--dzk/|k/|k/|k/|k/|/|;zY8 ߪroe p gތnݿnauŃ@ #y#ϵB.t|3)tKN0U_7Q .xÄ+=y>*O/Nb L Щ yyY@wIg9q"+?I*U a ȵ+'*W7}1Mfe6|DG#8uVy|8BưQ.80RI nkKRW>(mtB+O#la)]`y`oԄSĻl\F]Yt{yv?Wo嵱Өnp@{D~=&5H F)/ŜtQ[s!Ҟl/'IW"|W^%_WchAA80::?ntob-%jU%Tj,$6T!67x:\+1aƖ#SpCENwҌcTrZ#@B[a Ylvf/rtRƲ'͍0S?<14f_)}͝.qs{Q6ڂ'0tb.~ţ*/X ~Ž]XvBNw;5XiSqyi%+ˆߣ{SCra'IdaL̆@'3?X`I,9.;]V:&*L&*t36Фp H+6f]d-jcC'@I }Uل8Ӛ2yc(>A?0]blSv栈wݠp6T1nG)1- |Ǫחdq .u@gcʆm$0bwnv4[{eH>BPp{'疿h*RV(j:zؒtxͲE]R:.X\ |$y7X'*c>&R;1Ah!Df概دKQo/>?f6_c3n$J S0u.\BEfŰꮭ/;(lvGcIV}g`ME_J AݡISܢoi' GL ~Տ5N7@ULg'E Xreq1R,>iIkm3ʯaT}Gj`ʘObDu߫pI.^(}i˰7(ec I$Yr ҚǒROPmݒZ!DID0&Ƞ6ՇS{]ڬ$A7!nf:ZN]J3*ɾF{ߑBw|A%Rp7D.6z;&ǖ]1Q`FYP֫TՃ^;}"Z"U-,[)7k%Og׹v=9w;`X`m8lv/1uzP*w{ڋ؊T-e~~&krm">P$6`:>j#^E>rԻuN*_OPfHg?>8ƒ{,NšK_w:QF]kw+}ZXh,RSAOa/Xg*PݧL[Ή&==OM *"S% 2Zסt\[)1tI.lyBF@u͟wms(L"1Q< h.cF-V㠔j\e`#kZ:Cɍ7a1f6;8HI@|hs&&9IёY#h%.b \Edm˼/ů$54 ^ĪO2dIO>Ф N|H+ֽʑtN $ !BzANv*0mfߐ[%H*~2ڙ#a(ĻMAVC=:^⨤f+nQpIpԉw(]3ۥX$%DڃTIWB8 N6O6rJ};]3aF*|{ ܚ/0#5 +X=cY:/`Q3% #=Eb9lQWVD JǴ~43w,*I\HJ*9/"IrF9 `rn>v%DRA~dY"#]JJo̳Yӓfvgb|+o۩M_ӽV1Ve 2 U 78e8"s?6]&?.mྭpD/ ,4>f eJYXIҫ{7}!qkKTm[bMөo >%m Ê0CT:_!Ss?·?cyz )OQGp˫Hˮ|K#l @=:=) !-M͵M[ܳJIɶg!?G]-!= ʹj,^'yuLAs+aqRn~p+Ksk%p\fx-A+kڍrb&RVUjZU䃰^3dPùK|1),=x% 1)oYC~ عJ 'ZGq2P8JcjD$8ʗק(rH:X@csQQRVDlɇpOGpuczbyF~NP+7?S쵦N këɯpMa4)Bc:7g5ƙkqb%Ne//n&*$KO%_?<k4`Fhy|= idYZ*@ʼn̦>kCZۖ'ZWwY Hε_4Iy$gy-WȔ[{3,KuVyt>M;m5IaEzzsy1ͨG&:,+~u6BEZ/EmIS!]6_RNfZľqIN# rhd#FiPI ?IJ3#yFo{e#B!5isev xaV+sGDb7)`-;ׁs,׳'\H8}LSٸn$9禇8O}x ^jPKŗ窓wsۨ_ ϼs5O nYwL#x󮎸l;I/9'%h#gzԙkݤ> f{mtB@'c{ܷi' [Y"vZ2붛i;ֶ=Xd5Di<kHWֺ1ahBHԒqLcƲX# %I_/C'na{ǴkN^c?~`Jk?Yl CY%BnF~q,^GjSV͟ t2Tϰٞc-f=:P׆+c,;*Bfԅt=0HpjYCK49}Kf߱^NH">/Mla; $a^PT *Ύ{WBV]s::=!$ .[^=+lS XpV#iRA ;cy'D;B FödS30MEgGY TL(vfݨ)ҧe|*vLg1c=HXo<2~8)dxھvveQ7E4dq>1PSG\ƱtBNA<m&ݭdܨ-v`Ľӧgc%=.)zNq>gɮx\UkjwBVu.]ٗ}GXĘLA}n/UTTk=e9\+0a#1 y얗Z//y Q<ޕ9D184?FFƵ_yP}IImQ45~7U@L}nRڻ"_}- JNoUG8Ֆ}/nn=Cm戈㠶9X QeADҤOXc~5(b391Ut'_Ր<_!Y2#v,*r@H\ naviFwn1 Wñb¦ⲃ`4צ؍1|FBbSjf]L8+?emĩmeo cwEni *N$j  i%!BFMh{vFo3 )Y7. b#&}N6mW5ޙk:϶k8!i.pæ)P&s$ۊJ|hٛ Hng@r q8Y(n)D5 tmKx ]3!Pz7Pk˜\@6#q~Y[\,P\+ 6~Y.Ui&gcjﵳ8R9&E꺖LwY:IAQv6䍽`i@3-hK$^;ܺ%p@{":StJ<_\_ \n4*}w&3ekW,\*#7}Nln+} q]l=آy FDI8$lsehsڶk%B^d1]ȩo?PϾ#&S!M8pSMWEfC  Ȋض`v54Bt3K7gd.d,s~,\ZE}o .%vKp8EswPdbvUDns7|_S;aܗn`gwJ"Yww2,6F''D:Co~GQw2ǂxr||aP1I  ת Y3.Ss@&ef70bw΃gLo}ma9G_yuZP}+J@'V;_rBTm2*­O.2CΕ#("@7g 0&<д꼩纛=KPvJyEZ:FD&67Zm| 6eq A9m՘؇ ^k滱W OoM"zK((-rl QN#K-2cEJrƈG=O};uFE\T/|Ʒx򨮟,"Fr օ<$AY+w,92;.ri*=!V_;zuhtFs#>ء n/k 1bg] @ؘք[~X.=h&9hBjJdPԉrB =D,Bn9S䝤Bg;t+/glOH:r\&5I{xӴ/i F % %>rOԛ;~9P2XIޫ|WoWS UrXݞGg}29b,!LF"mtw+\NSy0VR|~w߶%";-FlHhcszBn۸y$7^:-C%$EwU#X#SB-ӈ=}gFޢC|v6)JJh{a6$+K=*)^dѧ-?)ETyr$`? 7UxlQ0IyE0?&(8(ߠzҝ ;j!,3W2{&\T7s9#BI.B'8!Ĝ;}B}6j$(y/9)?~wYo/]݀O@?H{8( :16?KOkd:B0gqL 3H/Ym %SǴG{Ih_WnKO/bGOjVx<["@ \Q$b4/=ϒ2_B1y/;OU cV$xc\Ε_~BaQ 1:* A䇻s=7,VDF `p'tT0d51n樐N "r,KមrũHɤ߶[g%gg⚜&N1wh /*?xSQtAHv0,5;f+5|5&F5Ƿ O_YҾg78^XXCvK+)L#0{n%Hs3J?g bb F+1)?kO.lmhU z@^fdWeĀ';w"^"c lb<'6.ۤ%Yۄ* gKj|Ob=/ ¾TdCͮ0bDB&qRnViG&޹~pdN ೵6L)Rt& ebL[@BNx7 8풛s?X߆D8rHN{m7QͺڤF<`әh͡3C_sKe_e>89J1KWB1Uu`p%N.Ǒq6ch!,(/I{ѥ rûËh\:~ ?:&&lK ^WRGvw Nك*L`ۄ-B!#ar]+0IB6JыG0AEHݰ2}#-&Y e ԁ Ҧ()ۃ"Z %+; "3ST;&+ƨC;o/0:S>$^eH(%땎[wi!aT'd?򶊾5BZY^7I>,9 ΙGqO>_P9Xș_Y &=ϦCH_҃O?R5fhV"+k fQ'FĪXXv_;|Z{} T.ޏ:-PV9ᄅ+B_?@q^C67CE&gi{";a}ΌQ4+BXe,]ka֎fFFa@BfLٶH G*g.EO #K< mr}j4ҡ^q‡jdrEdZPۛ**ܴmEiDB", W*xМ*>΁}7S)weh}5Aѧ+w-Gn~Xv-Ȏnb")q&{++9xXΔ:c1h. m^H$hlH FP޺LnKai`7/Qۄ n]޶ uy\ LV#PB/!~OG ث<=:7+։@Sf,gs-*Td:n b/P6JK[*):O+M.Ԇd忖L<5yÛ+> zw~FF:Scd<'fhzo>ۈ07\ 5ٻJY(­UR&Y+1];~bRY+eà8NѸ.%NJ|y xW@96yl9C6T[?3r-g22-6I Ruɰq20G2D3p垟N#b}w %6PIHsr,7n'.NA%"o2o%0YHstORlo.+2HS<7IW c+bx=GٙbȬ^z` d݊=bf4q o}'ODl7'?;{=C+jWjOy"G0/!$F]c%3Fh2fj z~- !>vEZ"dP:('cК4sW8{W$ww*FI Z7kvd^ٞ3L;FUg:o/cMy;\H |&F|O|v 0ӧ3P+dJCN)C5!GHil`ڴ"#s.(UF7-JQdwv( 9vlyTH3N`Y'|Uo匔4o5ë-|,zM)5@:5ޚ ww^w\O1ɟUHGq'Ek2+ %j/ /p+tJ'džo*ru^IƯ1!lҊ(~CਦoIC`y=:BC/ vjѧ^W8EJq;Rk9EIw՟7dJNS? dIr8,g?uLӁh6FSMWՀ@Ln}2rF"Mfۤ:z)otѿ8Qz)ag_aY^R 򠗰PF'+m.ъZ%ПKWg@m"  Íȗ8[4)]ѱ͏çVL}?W ='Sfg*u:7$(;x^]^lAm>VX_?|O3y*$!uqoU]9#Q^l$jq80iq`І(N tPU^d!_~hJ<7v>@ZAR,A}sULϟ&MP4/57&5rN *L/߳7 r c,|&*q.P;G c#4YNdФvT+ԃ> MS!k>BcӉlܧ[tg!~f*{悫CgV6M/ y}L8+͖[{@.핽X|[|9E9FMGMТ;pWvwnW֘0ω"zRnK0rCJ7NnX-gH쉺.zI1##٧Xc c=O&i"{8Zy\{[*ȰEz])Rڶhweݳ&5d;Vjs8n4R>2(6 A[tȳY(Z4QX|l?3Q.Y\[9N;7zGGrś>82a[t {ضe9R9R&Ukt|}{ ӡ@i44Lḓh첾%lx=G7pf5=U< endstream endobj 121 0 obj << /Length1 1599 /Length2 6592 /Length3 0 /Length 7611 /Filter /FlateDecode >> stream xڍT6N ]Kw,]ҩtK²- RJH7HK  ԇ^]=gwyyggNSKf VA\@n^1!ˇĤ A80T_ 98ɃD5Āb>^^ѿ0@qà`W&9bk_(** C@Pavhr `!X%g1n+7 n+ `W0l Y2@]7@Ax`b޺Apmv*@ 9 7p@9`N j 8O'I9nA # t[\g++gc&xt/?~M߽UAAuzl#tjWH&Lg2dsv\{ʺEl#hUJp5sK@ȝrUV,*dcI?:{ٖ-Tdǰla{LXД8K 6U >7E{fP}$Tm&d5j"~ccٍg[B zMl΀G8_bV7Yie$ML x*Wy111qqT{b/J{K>l#=Up枿v/NݢBU o[|#G)c0ƺQ吅}8)N"MRy6}ގO§b-}PJnXR֎} W [ULV"HaX&+ jk'ˏ k*v5 ['` Z 9Z>B+/ފ]3wpKQ 3T.z \tjV;}lia cRz}iL0J?MV_`B<-UPa}fB0fWIn!md=84_EwOre4h6W݇sOmC4H ?Y\ q;ܚ}|xr?|F\5pV{h:#3"YNXƧ9镴 t| [,p!8˘`ⱵU?^ey+A #[G=Y0?0Q-vȠ[FEYOo{|R.y֞lIp*FL\ݱ襁9LeP%wuΩH霶0'[j^zr}ɦ/W3klF{3%G $=! Q)C}P~TP="61 70Y{eɹDcoHM52,hi EJp1;c}F3ͳε^-K)_$ 0kfA{w/ {({@ˍ엵i~pհ5ؕW4^c+ y®tK_4g˲KPтllj! @>h@lKy%PuU+~ҿn0O%uRe˫7puH!*;glڔDpˠgq*cx+3dfw):9U)&N;)(A%<|K)DjvtM{EhӀmH(Dw~uǛj:pZV~`*WD^<(ۋw]aV}^77ժcUH,"~w:PNrx uSZk4ľN X|ۄ0x;)_&me=ɤtC$$X(i[&)w fΰhY,:dr4.S.6 /VZ5?'zl;zG`{%yNMW_g~D?ZUxW'pdrُթZsD?qKj*sʭvU6b9ʶmķ#Ygƛ=oM("aRtq{^fvէGKǀ$]lHljb?Dt̎Xd>:I8XaI * Y8m7&LJ^ tGnY.Q\c,&q^lRQ|;"ZBQcε2*XbV9N-GֶhPeɫYn.#bQDm_oC֯1=JgcTwo7i{e-ϋMt;&Ķ< GjD-* >^u!hNM1m5EGw駹]tVբ{@A9{p#qmƤԇ$rF'wP7bjktq5&^鑆1ۙ(v1 li3px=O"c0Te0"ˋf]Zi|粬"\1Ow' 0v*hM&l<)?icr=fAc-Ȓj&3Pq,\1Mm8Ul-VA먼Bky 6oRdY/G0} ?+3`Bϲ#Lᵻ+O V`ү,3yU7p:6wC*'wBCE;|Nͨ^G/댰NKJ{5S`Rl@4L6B5tq,=JSQDnJp`17q'7Y|.bkկjmUOJD*^d1\\^7cj (,ݏػq qrTV4Dv)֮%'W!SN]DN cܚ5c,|x7QF/<Q/Fϗ{*RSӧ釮?:hh,if ^kχQXS.c !^10t$؎ï0Dy[ma'ic瑱Fz?+]elfA<c4vwߡuL/&C2FYG LyHJ8$z='g1[D%tQԒGEQ f@EAyV[2)UIA{ËDV- *\ S 8 Nxg=Dia{ ]%$&rp}cٖW$|HBjc[j9P\^B{H}?!Qh@xd|NQq]#tt2'"ոϵ>l¯Q́03+nDRA'ų|D6MU?l:s{E(աrN>,,U\XP6>/Ye->jDOQo,Re[&]q.1Gc1I/_nt86k&cDUnbE(/Oš ` V0z.p.<1{']hx|%`y U}W4BkhR̸Ж|SN`GWFFue Hd#l߮ 'WY*1c5{nh]hTrO S]WK"%N:G,y ZOxKSFU1!{)gtd GZG[Ԏ1xTۣlgݪ2 -ZT<&EԛtCR?KZ fі`\Z0ׯ'&ky&LW-?xMW-3HjY +Q?=59Z|HBV!ؾxqbr:_/ͳ4SWCfjUUKDC~!㝵B#tmX W !mDL ay{Ům;mR R}2ZpSl4~UWs&vJ:a59j)O/r3Id+#+GK<ιGD |ڒS`ag4;``/#jX)@EvVyk]fҭT[5~<.dnjE^ţ^.0} endstream endobj 123 0 obj << /Length1 1597 /Length2 8621 /Length3 0 /Length 9683 /Filter /FlateDecode >> stream xڍTo7t4CBHw4& (%%4HJ H4H|?}پ+>}cf咱Z.H.^n(@NCC@>\ff=  G@.a!2yPP} > ߆P(@hpT.`. #j}Lw34@H{ '.FzWVq{$& rFpCvlwFn` g_q2!?P[; `ĽK0p:@WEi'xy @?APgb8ZH$'b䄀@'ս2 a nw<ܷYF vA"p'p].#[2l^x] /*܋pفA0 {X>@C[|_7 ޗ؂p 70  O#\^^  A\p~/xLy2g _?F̣'W(eeo.~>  ?wmR3_xG1`q UP-x<jK8p?n+0l}j-P|Q)Cε>$qra5oVX̘QWܡMS"ka{S^qӎ*fx9͓IwItEnmv)n]f"U,dŊª!͚4 vWtV}z'OWFIL{&z^A7GE~$Q룑0%]䶓FmPzǦd-J~hnj5]26w뒖6G& G?GtB?/:yΌw,zb2ʩ'q[[f2dM%Mdp5 y_Vf{9ᷣ:ΐ 7iZ<:1_ ;2|BGVy t}Њe Ng>;jtT6,y*{z=mHؼWEy]1!fUkce}T+wkCa{J\W[mIszI`xEx" ,]Q͎h6ݛ.~1<*.k7"`!tgcddѮam_? !QCvJʄLO!M/܏om|B<$e4:NTf08 c+ .(ʹzFh}nRkQd#qEnIk:oU1Kym:C_cL Ng 'LfĩVr;^Q] kz xHE&z"KqJe3te/v~gKWRgjr:icˢat\#7M4{ 9aȍܠ'G%+vҍPt]1DǤ>D-&bvM!KޒQ<9圡!Rw6?$Iñ OlжA%Z)l>_*@Q|}M{r6LzkDח_z|v _<3b2р 3Ȭ7V潸6PDbkEb 9ƽuڗt[0_Q6Ap#my뿦Ŕ$݊QRp!+oMLl S2dzA=n4U8?*6J]tʡ<o(F ,47Y`ja.|C]-.~y ?r+g<2Z|Y;1kQ],AArIq**vֺwɕg0+=e>[.~O/D \F84~njPaA0YΒH4+] UwDWSa4*ӔR-'n@eejvYD_==t[RL=k\K5elQ]brQ;BrLȽmS>&O٪ϛRJj17|_NN͔C$%]֎j'2 YL-sWzV}ʁѰ3S~[d3h(^1|0jkF=^$UN>i rg͇y&q~h8JW[^>Đ}+w<)3޽q)@?twYz:FY̬B#jLdG$QlI+31]w&c 7j>^ǫɇ>3uH|Yr3z~&U7n90x>3)[eU|^?c PpuN]󖟬6QPTvGh-2_[uւ_喥#݂Ľ_dR^tk~Gexlɳ&TLfB> Dt~o Z/`W+B+=% *jIZ / ^e*CA00D5:Rh ;IIkgH.Xĺu([uE1'ɱ`]sļEӍMc؜L:`qy(aFyQVJtNvc9~&V{]; P޳މ /@U?gt"62B|sqM?#嶱/Rypq!UTRwԭ7>+Ü.yYg^api`I *"aR¶x!Iwb2{82ȥ?a1O}D^g%.m6NJFX4wl(6yhڋ}UE2oL *+mBM^#/#+Et0NrN;*y=)ٺρ_VuPK&cxyE#̏' 1`ǎAC}29Ĭ4(HpbF&?:9)6T b [8޶x!--1T:F47*)؏lJ= =\*L\~5V% v*Rw닅r)PC?Y̷ UԷjKh,Up,Xb,-Kߊ3b87(+]є}g.fU,ohWUON u6Y,3䅰DXdE~D4HY#yPV_i)|.IvڏX7UzpOgb]83XV3~zz,έ-%J*%jn@v~C!jK-WR%VSeMFv]p~ΛBFOPZ&8^{/bn$@Ӈrڃ[ L6e^Xg&k]jAqYM:5y1F1Wjەvr5R;S^XbQfpox:7 +E7\~%xtw)^(NtC. 5.;W*,/HDy@* >6T$O~k>p4[4͘C:JeqO]y5 g~[{0N긳eѡb T, Ћk%hW K盧,g$(CO6LƝ~y٨คsFRk@[hOxAK7ȶ[Kt&={g51|A8< 1Wz-sQQbA*%^4lPۏ̬sװ!Y'|,)\p<7V' /o%$cȋU;Tv_-~WYC-^؅* 4'_6Yج$njX&e8ͷj36մRE0ޤxQ)GdH,t%.7ԨY9MpL"y<&a(;+J]0jQ-s2xe"=v@ɱJ9NlKV> ut6ն KD#a Y# ֤xٝ*[oT{-$x,mŠuyp3b7+SngZu4ெ6{*e sTR3NDvSH_q eܛWsTuL!~ki mH)0q=O|8}'s壊vwlNI˙0/%/?t`~0teaK[/IG<J}ӦٲgJOe}cU*F,ᐈc?$wS21#j6k:1 ttWDu0*7k_Wk S"@?'=&c\XUХ#DF>_ mjѱ-~['VLD$ieIxT4ucDLZltKp$Wj=[xgiN)aQm;!-0ٙUPbiLO<a9Z0YE|HT,:! ŭ{'#Ͳ)ݲG2ȃڞ9{K<>$g;Px.~Bo {P=8!lcJRdh^w[8p{Ki̷Ҹq:ub `rT=-i.[G6^E=_tiX4<p.W 8pdិhb3ph aTfzSU^K=uX /ŇZ=F${˯5Z*TxLE@lmlv=Wa1)K=mNEWu4ث^v:DYK #9Gつ@ʚq&w^фwo);g/I^yA JmJш^_tNc_RosMZ ɋĭ `0dUh%RP2fP[˃# ʜ;5%2}`5C$ī0pp"ڋiqVkR{k^i}|fH=E895j!VF2MV:5龮Ȼ>͛M>*܂/;,kOY|yo/sxAj󢠅@2 kZlA%vK:Kv۰vۙET[V^"=Ru\W:N駔 wpb4]p^u0Eyۏ4nXgQ8.SmL /ZĂEXM}b|%EنJ4lxg&$+ifFwB XFW?_ԩ%NqKKfnQS'w'>1x M/H ]ľ  #zȭ9rswky~H+Mn^vhӬ \amRR0.P{2G6jX4Ձ^[m/<q |6ߟ-R%Jm!wc5'_1?mD/Reh% ?oÝ`xyQ.㘛ƫ_NDnS6i;ljKaw=cQoOLal9lKl~퀘VJX'䣯Zc:~w4eQpen-xOJLʅ4y)7MyO֏T X9P٢Q 6 {=P <mb!-Rm4J_nµN4fz^L>&w%Y$60x,} voW: "A nR=VpF\W}/~X&,df]?^5sNFF_q뎓XLN,dzmN0Kub1lj;\a K|):A"AdlLb+@,\NNL!햓miMs4@Ixsݒqb0 "ϻ84_Hې [i *ٚsdzAäi;<{DK5LsY :6r80Ї?},O25Z$GyUwU2*V=g)}@H׌GZDYXQ?ӤuoC)V~i9l2F' >xcm8O @8ItVhZL~TwD;d$yDD<sFC^Ud$Zc)SF<*sqՁث_m%VrlNr%R"{%7$q+f6US*X>$۳Ǿ>286*ҽfN ᐞ= pJd h{k_,"Z6k ʯ7:l{X[~䴢TΟS/{~11q,b@ | X o5 \o| mE;XJթ閷0<&8``l;Hg%6`aym&f؍pt%xb Z'hdZч^2CQb[fC"&<6(# 5%\vJ?(3}`{8pn%k%ЋLQ"- }PZ Ј-@7 #Y߮OOG44(vՙ`Mej3Щ9/RAjs2fWA)^#L&˷\?|sӪjꌄMn7q4MMu]oc|2Ֆ@H`d}Ed霫=>#ܤ2UˎF6;!dqk}*-\3*[\vLp[x/ -,X#>C od uyfV[0]*U׈rbt©/<"Ʃо;K^ v} aU<,8KEmDg 4N qId4\:"-| DKd(xYrx ]}-EVtX| l4dzXh=CE7 =~$17Nu-10a{Rn5B4ik0^j[dYݔKVڷL٩B30m{ Zۼq#VWg6QWxVX.@5]weQUkʔb*̓M 5݃IKCn+U2uK3O߭q:&j)tfˮuG\ V}yD."ˡKb>WJEZy=^RΎ+Ϛa $?cU?vW^zB[{nUK Nkn/aחv8 2iX`L(f 8i [Uz"=ϛƴ?=I.6/?z:H X{Ħ5Vd{KQ^1u)MTN^@0Xӯ]}mZۉ0YK~=veB x[{c˓-PCz`Ƚ&>)|Ey@ ׅIl~x?B:]Pk8L`1#4$Chm,t}Х~ "kW]im..^ @j5`4 Sﶯq7i$%;)_-Uvp f2} ۷bNE#f6,Sa2*Yd$LQKG\v2'dөӱge$@bsI endstream endobj 125 0 obj << /Length1 1398 /Length2 6392 /Length3 0 /Length 7352 /Filter /FlateDecode >> stream xڍtT.)]"! ]Cwww23 0 3 HwJH -)*tHtsw]5k}߽<1= UC|@)(L`Hg_7!K/;DT@H4Nhy:bRR@ @.Py-AȦpu9:! JJN(@a B:A]'B@cE*% rG;qaH'r `7F8 AP @ O=>`wux /r' + ;`P? At> sрߝjzy@aH~~A߲*^#=sB+go_w5) T As"@ qa @~7u r'wEC@aP @{Bw APG?n|w 7[4pgW@C[YWՀ))!|>!Q "qK?`'Utug1=PHnBoN1W!5Oga# r9ID @?Յ<];wDOP(P@ `H3 5@x~}[Y@4]5-R(rb?*}V܃SV1͝Ӳerww!^-”3P"yب(XyIɺAkIM}IqYO\wVCwi3%:+U i]$胍ռT#@G؇oք[u%)mМXcw>ZPV:U՟:J~;P <,[fEE4w8$.I,{0 ǹWZ\ WZukUlR[Y-U |ġSaBwJ9 qdRԟUF'tD mMNOVQr$E/㬹QW0;1VYW$3P315t_ۥ/&j]ǭê2#DLzo|m`4eP5MNkGF گWEj jum,V=u05:t-?PrlMe"-dH(HԒ[;(U Pa:Em:GԜ7v])w[Kw+ZE \lH404 g~WK(+ϑ8Ws٥sMK\ OʡڈbژݎPT۽=J}FyIuch$p$ qK'$΋Os[7~`L63 f(̾\j[ !Wiu ݴw] U؝X}j(zm/4QekHLx#ʋ=)^Lr!9,w"^IW`?rhǛVXo~Юዮn IutvQSwpޗ2.o<}C{If12pvi*+~LJ% ȳgN~~ъ-|H_+4 kh96sdʫGVܽ0L!oSDd>k>=qz0r˂[ֲswtal5T?;s G\%Gy{[+X\K/=.Hp[~5+lR,JY>yWhor=>&)@7,ݘɬ)Z="dBUpP,6 %pe<*3l~Gdz}:ɞEe&hn*{<81u&X#sCydh@nTbs6g_M~CJF_'Aߗ-2]!LRp=odƵ9aJ='(%S{d}8x]3S<@2I#P_uWu(i]5 pu>mm@vЋ=RX‘U8 ~ESߗh=YRݵo`{A;BR cCSh3O+a1oЎW(H<]w'cfɳw[kd2 2jÔPKKr[O֨t͓ˏ0j2k^WmIܶ/`(I:W߽gŬb}HqQg6u$.3^ k1^~pK#P.#?mEMٜ ƭ*Nv4jgՎvv/ $i(7CђFKYn7^+ʕAτi-zAI! iVa%zx4཯܊jsu+=F 5(=ehE 5%U: 3YVtO0JO-R]DcRZRw.EL,͏_T6 sېɽ[VuIjm|X:ë-IPg\.q.|ەh,MSU-*5LFjG>*Q7;CS">|\Av{ AJڦ~&>dc/q0r3rd5Z+F{>sGfnLXȀ09E$H8JM-yz2PmCWk^~ꌧL斿hHe)NfBv[bR, d;j_C2f;x7jyoЌcr dcKa-kDӽG)l9_3OBwFZeKp߸5ּg*ŠYIiڗOKLݗ"Iwi3bio|cVM"$?pCtAʌT,[cLUW`ԡr©ibU>XZapu~7yYg8ɇڷIeauӓR.O͚ȣ2^Ѝr:֐&}gb6L~YԝĘO҅{#"&OR?ˊeg3E fo↦4-:]Ny-.|K?q[9eVr]?/M$^ R%dLkLS=_U'4^9SѰ/T2"r9ltv(\6b7oein*\Z[~SqB 6kY3XKq +Y<͑yaGS!7Cd$Ӊhdɧ1LEǣ;ԉ8|y2s){"y}goEN:Vt>0ڎTI)PZ>= >eH %>ĈĂ{۰>߬"~D6 ` W:b./X8n0b_aɀog%)״F?e+ 2MX';3~)FIoGSws%]i?VwQF@5g"-&ShT a~yH5} ;v3B鋳pCf.>M GCn؇QN3,%q/*oef:#Q ?eDVܖFy>p`4H!P;7_vMQɓYGyiƥof"/ 9}fu\JvXc Vz3Fm[C0м$EmQJbhVS_eZ[ )ǘQQ.Jf}#cLjcĹʽٶx7f3c㼈?<~| |jVj:h}Ƚh!")"ʱ:{VIrc9`T͒n{<:{U>Q!~2]ӇWߨe|oɹ}L&VWK nb܉QZ}*/>i4260L1B(~з|޽7~rhrq162l>HI`&j|17tfY /q6l^{[|VxX!RSdokcV9d~4m o A\cԦOZ="_+aGRJ q.+ؕa#3yg{z6mjơZ=QO"RO<̧xt+32K:'׾tX%߈`_@=!* PD$C#֥zs'WD=g9/dX>y_jHد[J[)oS&C}`ViV+Jn,>7 |Ε;5ʮ)frW ߽Z*p@uiuq."H6 ~ژK[֌k/.% Ѱ7oO.g|ԔQ%Xnif?3fHARMJuvwЃr;JWTžtЌ' \ZCRwMةBKN S"OrWcݶǂ^F7eP֓YKC{69.JBssw|#%vZ0DUCbvL?lڿGHU;w=?YKcʾcC*&|z_2g@7)V49%h#_y)]`Xld1 Ǚu77> ͨr404MT R*+<9~N-(F*j$5"or႕ji (^^#fn!wq =LG76,ڠJ[.5GyG]q|}pT/:cLpL,Ϻ3֧$x`P/72 Hm3}~ڡ > jgiJVcW Ci2D*pP\ #PvViETKm}C5"erd-еm9鳫ael>qְu*]TUa.oߤ#rfNm_ WԽx!y5R9 +xB/KMIgǴ NY$kKrqw ^8!~X8wخB瓫1H = ~^k|TLwg`ƑB¼-" Fwdf_EhfB"C#ZlzF(%@ E8=,؊EU*3>ȣ$N9Nu&m7jr' 1ߓFQG%`0^𤛤HóܴWIjF^IĒS fEUo ?IytIXddk[-pK[r9yD(]s4o<,@st_1Q,*vUfnY׫ _`TPty6ԎUE xq㥞eKOi) +ݳmX ;2Ӿ.w)frLAj#-jJ!,/RIwx}=0QcY ϛ Bي_ĔnS_ތM \MzwoH'%(_MY P1m|BT N~T0RUZmp MO%*4%\W֥B ԥ;[/H &ÔU&#QN R8}bEPP&9׸, + (YOXI`ዓ])۴T߳|~DLLc 6aXWɒ)y_KNT<BS8eE'`nb24iSoֳ/p!H}٨:Vb.^"d֗ԴfSb׬Z+nÂ`nf :qs?fhFqEZ*tg_g/g 5+ \ݢ.(G3յu~C`'}.}Gz.U 5#,F]{ ,ٞ -cs\ dNg endstream endobj 127 0 obj << /Length1 1543 /Length2 8743 /Length3 0 /Length 9778 /Filter /FlateDecode >> stream xڍP.)ZhpPܵP @ CPܥH⮥Cq/Žh)Υ}{'3,{^O'x"nK*rS'&naիEP=N_,ǯܦKUq2!&l@{!{>FQxj:kxJC˸=䝑n['!0\Y2J<"f 'c2zB+o~9(˔\ #v4Q[}xA8D-Da|'Y]',: (t6GMU67T5L_p˷|LOehX6*aj "x/3qԝTy[d|K3YN-?V]X B+_-%1 zkBu|c :3'i m.#jz|nI}g/.ق~h0$uG=/g(AmZT]pJTώ]/_YG@8-AQ2zS[۩O/0ՃwH /܁%gvVƓp g5$iCdUR `JEjh;5Y_irfSղ]5﬍1? 6sX_( $ndWw& \޷d܋%G+! ݦ:DN^Dr Vu.9eg7vee"SB19%m~c:)!Ćыh+c,9+AmEU*ɩ:B2;50*mifߵYQtGr  $ϡy>4E | {W5,v Kx2?轡3KFdE(sб@ w+UۜA?|֒i8p\tXg0:[3$OÀ" ]-Vfg(]7a\oE.3I1ky7a*U6_ךx5O]rMX x~i Nh3ήi㎀5GRsFba Tslf61Gq1GIΥ|ɞ΀yQNKe¯iFb^3`a_S2".\tDi'B)Sd:@Gł7_O,fld- </дSD6URKek9?[OxTݣa$])ti|6!H'bvV?ܫ Â}BxHR nF|/ yİz'GΝNn{I:tUv$iΫ>"z[-BIVz5Yl-eΔm#f8?/B1Ӡ_qKTZQ*iJbU*1,R.Y9hb()Ol1xzH%|_2}kK"wS(9ttQtXز2 你ةs7nD~#4m6 u}}w|^q%8Y5%y8Gq٫_u[ rT9UN"x;ʹq>cDPEboGvT hFs[9Mք]hcXּ4Eƈ:tB_R5k3,miUD[io4|奋XXBe[sׇ4fi7/l(TS(E:{H}`/QE[DG3eaSNysPyIPnqRw%Wg3_GlSS+6jp5_xg zt'Y(RY$}D>#$:k% W@Ho(贄^7)F 'GY~Sm.\zvg|qtR9S–8,?qHyBЫ}֜-ұZfid% ]f[bH-ސ)LNI㼺r%nٛ isY Z P&ŕW< >}OV#AY&ㅽ!M`5󤐠3^4+eu%Y\st,m`[Jwaյ|Zxq^Y1`c/d.y(uTAWA)8.SKkE\ زInS0̣2_ұqRoִ1LZWß=K h[#o\|Am8ۏSS1b l/k+xFe?a-[<3esۨ3C2d{>jZHj\Y.bdLxlB׉%XO+eiw uWH6}AԦ&0ޖWpd*25Wtl*p5g{jn"9=Va҅ >¬1S~PyyWC5IRWFQ/Y 0 : KC,"m21@֌rS}g'-Cig{H%7yCiG$-%|Se_#|1i9asTh ^MD8A90@yF3?}KN9Փ.b'JڪBu1LLTخD|IŬI^+j&u-mCiJ$EH*f"_n}_Lrk|#UJ؏XglF'|O>@UfӚqhGP88jnwǓUޯ~XzQn6ؖY v`X |C0)q.4kiMZOH&xd'N{=sXFBla5,C% |Ű{kt 9?ۼf|a &c6y7ougELK(LG :tnQPs[m-_\N?-8p]S ,Nd翔y릴-{FuӴs\W-씄O SJ8O9y[uceuI\z7/b9Qk9+WV> "Z9){0EŔ'# )uHzZ^@辵x/"̗ۉ^o'ןDL_-qw!z鴼-NlͰЌ5ЋǢkZbE9*B:8ovܺUiе]=x֍}ձ7؁xokF*w=\gM774y'쏢:!Y2ߌ̴̚sew ] l=G#0N$fϤ>vcTkӥʋio,ZHK[Orš~5v.gI<K4E,1FZq#v?r7 ';Ga3W6VѯȄvLu_ ~|\BŸOn>8csG7P/ |~/OulF^jª\AK+Cڶ׈E9=raxZV\^;&y%;B&?%qȺuVvYWvi3x]SWeF5"R :QC( qUuDi=~D|YNT=h!Sk ס-NuEjׄ|a:@vvDr8j.=tGVax`svί?"9"+vsИ]UFRY7 IzhX^h$s[U7EًPdع])n7eCj K^.aL:эUHrP( &5F;KҎ q#5(YdJrG@.Byc|ITp|V W#@^ЭeQ6n&W={MFP̻FELH]cB& .|JՃm)|^F;Ґ%`AԗԐ qkev<&$]\^'ONĕ*ys-62By輥έzKՉ!/sUMDUuRBOzz’9UӔY8_lh ;}ǟC9p5;p;)ՐyCVB-c"{,t%jI^stHJ+3U͉H>F[L);VᦅCh.N:ЙEG-K&뗆ѩI>7pMty kjwxcgfG o}?ކ"=$-Wml" %!]-Џk^^j4+i[q;|<A)v/~ܓUPٗ-~.ņ x_PkT+WgR62/\0si^f_ؘkZ];9<9C:>f>"įˈT(K\\{ODjYZw/I`Ǚ\Qhc^'',OznQoV:-Do4BhM ]r3r9ï̿7^l-*Wk- +u W '[ cCdn>tPֵKU(ד'd[ pVNzHm~]M91DQЌT =ŗd޷uJu9/}fz1e9|eݽwka?mD|mxOV^igj\ @'\7 ._͡q`N:!-xhhHYOM%UQxÉ޷,%l©2_.1l UC!s#a |\IWm6ct t_HmUW0')qbhX#1rh5LtZQzR+Q%9:5šQZWL>B opwiW[Fw\zM\ g. xWdo0ʐUIȄ0\o.;g=Ik pٙD)(.8uӺrjtjV!,%|Z0 "20L-ƃK妛c%5X@)b=7鏇%QݭE'|$ͻ  {cwbMq7k"ɟ&܂D.ef1y-bkT[ /1АsߛL_; 8EO~\ etkWQ=Å&m`o-¦nNKuLVV$99I[_qR @&kTs!l¬HesAs\ʻ[FH[T(w &/hz]G&dn ]0<ܲ*Fz{ V苫5~y$WꫜZReJYIVmk~86k\w4KINu%t90>*;9rJsjiq]u@̜,7]rMv˴0, pX5 0Zk- (&rm~IYxz+F%IMsf3AӬ !שbm}{]ݟqg^#g蹷TK/?}[ZiL>qn\%24hى٘"K aPiq=cwsB[Z5(IS'['cT>:,G-)5=NLGYry+Y]NS8C^`IBr:iw@5ؗXtTFE,Miit8!Vҭ!JxʃjDΞ?n k(;ԣC 7?d%n95a@eЍ'/H=^$nɨD?_.xK]`C*M^̤֮uv `g:U{17?71[MZ:ó6c{a, 4\ ea&H~P!Z5Pf$V Odnv}M~NR;$]l09_FI/0Pf|-mRhC)|sy|QX .;z׋ ,SY QMcq3yo4k9il_'%a:|(E7$--ŝc8ug)҉$M~2[XgJ&e.>UΈv2 f2n{8Я;Ÿ8}{[@D~SE~oKT F2mȱy+uR$~ו_#8rkco^7!ǯ\Io၎NGq:; )Ղ? px1)70_b4aG >q:j\PDI҅{^h{W%2N!A-5;xh1z\x+_T=Gx.hx]}sTy_#nl1IieR> stream xڌP\-kp%;4$wNp@p ܛ꽢mm=)IDMn ,̼1Uf33#33+%1&с1H&nSptȺX,,\Vff:M< YG+?_4f."@k3hfbPs4y+ /'+ -= tx (ne\ ̀ ws DP(96ۀOo,, @99;8x[;X,%IyF7/7z/C;WG)M"*PjbjmD_a@]p0s:"Ohj7ߓuptXX;[*݉I(# H[f tp033sӯN,Ġ }"@?_W `nm0ZZ; -ƠX{A`o2wtm|䤤d]u^_vf+3גq;?i+`;[P? @qK@%g`6}?_.+m7!Iw;4?j{k; @K:G8U[Vt"vm\m[ʎֿ+hG:-3[У7cx# B_-Zb*`k&_'I70F&߈$_ `X@#6o`@F\#P. (7(Į~#ob@욿]7kF v"o3@~K.&f@{o (ho#ag%Mk Jb`aqV8wPO-~C#&l,X~ ~e;;vЬXd3ʴFb@=4P~G:=vɀ[ z:k,H=l6RÔ/d'H{g@8;ME[?@45swMzBlC:jE<&f)h|\:a?dp8ҋ#As-L{ޖd:׎8=8Ux$0@OȠ.d E2ٝYƝgW@x~ SWX9|od0n Dpt^(s7S$ ocي|u7YUvQA^P,.z"ѧ22fXF;4y/u}P b&Օ5c)aմEcձ,D:n4{,lR y6t[z|FFnRFGwzJ-=Y$VWx3R& 2MB}}g.df'<_tص9`n̩j%ϊM8+&?S'2=Z4\tY(^M"ͱs]Fooz$J=OfFhæa~훊 QCU#q[\!]ݮJR"ŷ;MOE=HQv&QŅBsx/n]%y$ O29[zQ9_1]QNb"(9>V%YjNe - I8zݸGs!|8<*VJd[qtzwJ~\u9Nvb^W/BrfcS[疹nUTBe;qSW0GIyb-J7SEZ^$Τ_wvY4bENH{t})No)̌`yno8mdPEO%apxXSʆ9ow/$JCp8.<fkkr|Jy~ S'Ҍ?w4*X =̾cA[7wS )nV[XejJɼM`q۟dqݗmI,K)B&*ϴ_}ʁQ.#RqmW;֍HC޶ H 蘈ӯCkua*NQc~6U m0{W3"ΰ-NX()L'Ig6ob3i5=H6w0vd@EMx-QBMPj+xgA%g-E풱CٌP3^wPŸFzښh8CW*y5HʯyQDe`wVI-I??Ň0d×P6Ә2͝ԭ`!+EWx;dV>T†}ɷ11^ĨiM]1O|j+/)L& 'yoХgGcgYݓl*v[ʷ1{v@϶fQKx 䓫y\OBlUA!<|Ay bTѧ`Eh). y$EK-;NopYxI ~9#B8Qw_>Q4-4R/Mi-OSubae0Y[/}u7C.xպ"^UIdQ@m3TkE(>^8@NJ[I ]g[ pCzb0 0h5Ev{ fSUnwK;Kd||Fg(k6 \ߣkHzMn,_b4f }pSK<.zoJ]Dy")ZtĪXͅoKmjf %I> .(^FmnT>'V>muD(t.oG0jsK%iRQ{-EN6[ecXWppj*bce{^afa7YDZkTev>sZgkJ<{dJŹZ}tkL1*u#*{ $Wձ*n̍  (kުe> \`8; E.+?\!LJkH|:|9 "C]$"<"FYխWJOg5܊Ig.6ҙ>Bc#Ѥ#Mg T5)I6mf:>1)0[1)o}@>XmĞtŒF^#f元$]z@c&o<"I/;g8Ni 375sTN_[P0d6r>0|~k19]LeT/S=v*1z!Oܤ[=BJ8),מ$A\{;GI$)Q߬m) _?Y%IhAL>_,mw X>X5<7׼nPu6?0*%hF&۰VT!ʆmթ[sPr?88,ɋ$i8&S FO&,Pf @N UȦ(,|9DGQcwRzF,DITmְj?*̐|<vO:.7W:'GyhV$QrL) 4.c@r mCBS *a{mPP֑*6GKhU6*1Cp <".m uj >c|MMmj]?UJ 9rF̮OqPЧ30a5iWS(7FP{BͺrK*Roޟo1sH ΡSޛN)Gn1YmdIUP[(Αhkiä13]YTw;G-Fxi_c6?;j6jwu{O׳ʽǾɟ`$j&L l!O3wTq{R\]~tG7s{@f-Y -vߚW"K)HRy[pA7bgOpNh>eƉb71Ҵώ!h7evg6jM{L;lY["iAS϶-GԁCj;KvO$\I؟\ϋ5T o2\#a$ {״R3;}YRa(.vߢܒNJt@Lxk GLQ;ԮH) 4k޵ݾΙ:.߉įoxc͉aU I"nho?cnYmO͕©%Ⅰ˕hSzZ$}V ۆ&p .IyA/)6k"HИٮRwp Eݻ%`70T1 jacƠ2')Ṣy>z0R^d׮q^Ocb7>&!86#Q{Pϴ>Cæ9ƥ1;!" \FEl9>!qb.x<37R|:]2Z.1>hI52Uhjvk=$Ǒ >vDgnFɼt> ﵖia˛Wv!mV2.2 {偎Yi'oni /ӥ>@Vp}Sgbu{Vw+|ѾJ((˚~z~|T-q\:c{NvE {Yfȡ웷_ZЗS(8=u"WpS_'KN2ooIkJӿ=vŪz)4dj)sn@% /s~v D=TXײ2U|]4<֦?S"53>,2|h VE6!w3K>׌,y|k8IȗC I}Uey::[mؔϋ%DmdM6Ip4_4Es=ˠCv, .ñ U Z^ú,JNQGBznj[HDxQ @VMgjSk&ݢUR*~qAP z81BWEkZ Q1V;wsUˋqIz#Ĉb:f&}2E,36e#YK"Q?ie=xV[bDa9nې֬bEX:!eu:"1 '"AJqULC?t/|\BkTÈ* (fQ+v?/0`޼$ڀM\Exmvt3e23)rU=S7.K/G:QsÇ,LFu~m^B+Bfoo(7OWE8x{cs,տwi Qbcv(QYrtAr x kZEj{"R8 _%XzpjOtvF%G% 2E#s) ~RoCZn|?}W0DU/Lzz(b_s X*G:>EI#tvRZt$@Q/x8J1dVծݽՀ7X4x.8\0\KFHrvh-⚈yX, C BiOMgnPf`RwmZ Tb y4A6Ѝwv6֞bTyf~d붿\Q,i5QyѼoIXCmA%;jg 7ޖt{s[6&*t+xjC&T&,}4-~5 >fp!ϐT>ef7C?YW$`*<K7h++0aL_-Yլqtmh vP`n׳ifb@DxH}x=;NDx( :_u8hv܇:],.छϷjb WjD6wCMEM%ĵ*xOpF칛{a/ Mr76^xmYBT?L&TF|* #sv%֢_(2v2 x/qLBZvllGzHN?ȂtSu:Zx}'2*H,2k*9!&[ǚo$.oYJ{cƑNF m4.fH6[6E歚&ZPLYjf!a_0iLi|Sp]FKcBoɤQ[ό^WОV= Zi"^bٱyoyB}{=R|(5ϸxEzV^+Gq } "%UN݋o}䕀NT;yWvGzη>Jt5* 1_%0Abo(F9EuHZ#KNm1=$Vu=š6:4LyȒhs',2U#NJ.LaUw6s+ [GSF=Kf5{+yjeՐnDZuXH51/^JyJ{Io} B,PQ%bcog1߅8 G*C7*Ro ,#ҩFlEd޼_Z1pPL?ʽt"( )jxtdfdb]+R6Mzg3R$P$*"Gg]-3 ctʊ°!R>\э efx Ø XUA6?2 (fH&bu'qـDjrc(Tg(K$| {lu e61YD_ZJTn{,=SnCA9 o߅!nu@!G4iTfڪCou:̹Tos& 8b4W5 @op])cA"UV?o@KzTGy7kC9dbpDfgܖ挐lkȏ&a& }@zT*leC !{#eDF!tk!0^og C.^'x.*K9Y,oBXcQ(*m}j1.  BƷVs- bQ0?_>"ύg0٤z9$r(o.NHv ^E|,_2wS\1dD&!mwSbv[@*Ae<'b%~%R2`Rb_ d#)Lwn&H1k9 ؞N q1H0cJ4, Q9?jb(jpKLѱYv?( J6<wZR@ޠ$s?3е[Mݥp~~09~`JDKOJAPzknpX{Sl!Mut8zH!VWS /BkNk__oG/ QK/tL.ʚ\{#H^\QTE @e}T&`lXZnbG?Xk3  > jj3uC;EJ8, +'I&ț,qO4\e? kJvhInLAprG޿"@4_G 86KDmg"NMj=.D X~슽J7U#AV7{^`q0[j,0j׿Y4gDRLA mE}X6P#,ua[uf#7A을\ڻ^up!t'7xR%% 5ؐɅ]g{\gm.]qliJ$IfX 8~fF$a~PvFh'wo'kK]Ɠp)+ynzhtT#9 8uxᝫuj/D V Cݧq`$T?9Š)gSw D=!qmW}67^/V)]\pݷYJT0"(Eye <C^G(w3 v+PQn)$,|AZ5Br7|ݩB?/9Z-$)\`zZYXbE"(PC3z:Oωvup, o|LR.q38i[Py'$Ѕ7vF.0*`[ottv4MKeQS>c׷&hR_Kp irNVd~܃l8Lv_,EbĖ+Mm4E+0cXGtM'@=U\^K00DLSAs{ɞ qB'w,LOa:k ¢uEg b!k21ħLIW\C۱q OttǨP3"s:?ȳ0+%}Ic{/!*kd}\貰p_ՠtJKZnR+yG !1*WݕtaY@E $Ƨ33+4ʫ#:mve߂"aun"i&1=+b4X w}[{^:^"fC_w?hD"I"~' |f\gAqx3>fhǾ•o]ɂ+uu7 tdC_9ZV_i=ߐ9oOȕ쵄+5 \nC2.lhQ-j—zd](ٺNj38b)$IZzy'' iI ^˙9pIM}ZR|8K.;("5Tf!Bܱ\/N/?cS"}7xB:x \CSĨE5YnٟK4mײ یx (IfhR*9$C/ľKyI"`ܔW41͏7Z,(յU7 Q9 Pyy(kmnǦQiv\SXWX")3xIׁfI\u(цi!H6lYXr:5@1^.8`^"FźѴ,)ߤ[R~!. V04BYG]>QZ~1 z1=6\Q>?6mzMHNb갑ZCgW1Ci^Q0ٕotf#qts[ c7L¾)ct?ϹFqx^aيl9 uDVJ%v9H!XEUvnlfp9%~ݩc"A\ڃXކ)+LjPu: t3>*EX#2M5Ͳwd*PʢhTrj9[a~YY+NÃ긪K zi*_Rwˁ[W2\-CZ¾6(E159DiCyPՐD䡇l #h~@ -7g v\l{WOQ!Gk#`6A(͛?@ɴ07w`G)\fT4+NWMXK湚Q]ܵ vm."n9r9~L^ TNa<&%3= ?u8Q[rŦ.UƏ$?ڛ_g;X#QG=3PDR…nšwd "-CKl03t-_f! ݝՌE?G6@Sq*P^ QE_GIemS%Ũ̓m67+Iي"ϋzc^ q~\H%XHݮS17'  ^D桎 bnYLk1-ۇ,ɸjY jDx LA(kW`o]QYHK)Ciõ(>č~iE"zd/,/E|sr{(qVKQ*ũH|xBw:ci P\o_4&3Tig*I!5GCDqLFsވ綇d>&FנBtsh qh$=+rj2,o\r&o|gCD9fcjmxXfUq6V`'e Ҏ:<YvW6aOq ۜbi)LU+La~sHxs;p#;AM$/C_/& %$fʰ ohyj݂q!Xv1]~ Z b 'x}08vatpnrIb]7pÙHcxI#v &S/%Mʓ4` 8RGrKMJZd˽xܖ3%B<>3֕P=hi fsu(r+kfW~gCOxWx5b_ChL0Ӭy꫖c J,YpCnB)kKUEIњoC鞚tfd2cy{c :*j]N+?{T~hz1`b AyLb!prDe/ .f9S|_yQޭQU !J4TZ u #ޞȃ%[c*,_-4^Op↑0C3 I;*WZgTX9]E BB wU PL\&It?3qqK&1 )rt u.=Ry$)w`T:Μʾ$j0)A1`` A2IϴU)' h]ONęH_<#Yt$K=eMuaġ}ȳ-ݒΫ]p+qvg~װVG[uZE713BVӶUv1O#,Dr}`7_"Afyfm;Vɾ1f*7͆zgY\"w%Nr9Np( SUҁt֨slhq݈= !?9ZAړh.ּ|Bֻ^S=*!!CDMcXLW(ƕS`hEcz y-ݴdf_ HL谺ΩtlY1BlLzoXg"7u%AWi_CKZ-bg!;4b<:(BwDB,WȏuDƪ+?м,:PU΀n?< %iT Q~i;NNcLx9G֩mqZ{Df ҄t9>YG>AA!X:+Ve|m$~X'wbnW5~K1?SǥNZP;ǃ7kr X76ѫI}a_,Kᶼyh:uS3%%eoe-o}:/Z76-ˢa'&/(܈SsruG>SGw 2woa:E{b&B4J8+$ly&.e[;.X93ۉuSA2j@Hbݖm"qW">!'V&$0tjP92n@:W=+1ש8zѱ.¬UI}bϗK#]rJޒyE+$I,E(A)c9 rqF/o*gP&biC,i:Y#ZFQ^ɰ'F,"I0093:8K49Z3~&Wt nn* qAƚ?{OV1iq41BˆɊ7SꑹuЉ(IǤOR0Ї*ZulHo _m!eAknL1_#Blv[vn*]!{jZ0G{C\ـԕMSYwyaKғ<ܛ'5>hO`2tC>ۻ w\ \OAOe;D3BoփČ]s̨?szOgܐ31ФXQG9 TDQ{:xE FEo٠'7@%iqh&D y }v=໔-Qܶs! ΅r,FU . >$egֿw[d@$ I5DfqD >kԢ}nORA'Qh*'_zxaSL?o{f+(_yr!(}I4-V p)uG4r}~Ƣl4 ߸+ƙ(=.AKf`|SjAIw:BU u;ڃ Hv  +ۏcuMkȘvH7u%3ˤ1aOG])x8d|}ni{6n/u s]1V8^q?p&[3r/a[llme|[P?_aE`0u~GzYzR!E1R'£Z|mE;y?rg a`|"I?*DCy/o6#L.70IHdDcf* NySix4")`N1*7%Xu;d*~CыVoZD4p'ƻw-mY9FdKcAH%Q7\KQ0YǬ(tW:8ſ偾 Gɥ͂V$8Vi tn?˖;e(VCB4yFgMFfav/$O\F8p-HLv?le V wU <=o !Ɨ`7?D"Gn]lK1I>9PD_xڿ7ȦaT6[M@9>8@^uLC!'tcC[ hO#n_ 8 1`((i漅`5(&69`Yib#f.b2=n̘exwzb\P~&MbE{ j/!6$(Sg4qi1+ ax,)* f*>kNN6꼅MyߥbkhN*K&:M.?ߣ(.:8{bGj''Egp:\Ku6'hief eF%l'?MSd~ |:]o36(Y>ۣL+I#f& h%9$0\T>P/@p|y:xFʱ{0ӆxvyslrI8ȨN/^u7-j4Zw*Ā-J ,hAÑQv -.F:6q3x,kFk7 5mD$9ο@e\"3W[62ؤ[+x~:}sY18fVƜ;`7QyOXÜo,N}ZZ+wнٶ[`q~!} Sȼš6F:n=?31OA/`M1a &c"]AFF`}4Z{0%>;=r^w2`<$zX'7Rxˍp{ݥ!*ޙ]6;缯DQW()!;I穝s% sTn D;m$l~y~1B+r\fsot(;M6u< S&muX^_Q71nlr`u?]c0]W(yUJhCQ!txj )NHg{@/B)mz (∳X6#'W-F0&ؼ2*@Sd5y8;SG#k] 򌜂"Pϴ 3 \&YR\Q⦑JVhrM.d(&9U`H{;)پ` kOO_ Ab~lߏ958&?NnloH}c|DɯpP]9U}Ne1,N\RZ ڒ$.}R)_nZ!~Ŭ ] RQnKk00p) pƹ:t*@~n(ѧ.ABWGL+%B7 ֊ _>=䒅 Q֯z54~=2?D;'ޙSEDCDL]z! W+Qv>tZjpm ECRg)=ڌRzSY; '#ks'F }I[d|b*2NT w[01&sފM,# ~a M_.(>>Dg%|*4{6zŴґc"oLVdP>2nu գRs+ɥ\( v%Kln16j 2xJeuY˼W=P^(OHhOިs5Yk0͋ o7BϦȥie98#|w݈ܞ¨*|eoreRu$'ojoX~hq3p=@mFs*śCxT#}X?d`]hey*OIZp uhVgm ~)JDΗO༭Y(*"E4e^m"&˘ZVF?:\+dX@Җ@?u,VèiK:~E}$e> bS Qv!6%~ho˿.1QIؿ#eYcfԖ2zO OD@c.ѱvDD})M_=O QGN؉FdhZӆVBW<ܜT^:rK``q#"=Pf{=b]@k0ؿZpC~Z9'$w7o{W WMO^M?$E \Seʢ{*oD-AGXϴc%u(L sV0;cgd(Ӳ n ,$u`ӀRL$9D֯u Q pma=;<{Ǭ!{+Ed 1Ԟ|f򮪇bN>/;eG !HN:'+Zc#*XL*~q/ڳT'K63 =@sSC{(Z q@V R?\8^vESOjӨabNKXƌNQduksx-Y,ٚ1q#y|u;A? 7SEHDK? A $hZD`K1.hf+!{9d~kB23L/qY猌Z\G$0R^IIcV8-\d 3uwiq~xj:> 87ɢ]u6qmi͇;PL SSs zʼN ȁId8i*04XmiaU+v9,V]jm5QFU5{j!;,ݳɰ`AqzcN1Aڟ҈*0Ѥ"Fa1KZRUj9-,aB0͋VR$o v? µT<.M5=页y>᤻%pv>n2;k0$wMj5:<%Y=E %FwClnLz'Ds+!)naǰ, &/X4wqL]0fBnz;ipػbf[o6ɐWϻ-HΗgr"7%zI$=r2#7YǗ7]ܛݬ}=5FˋS: rۗ2^-$ۯ~$wv8jvl"t+_O]Fou@6\ V)P~i)afԣ6kW&TWywGNK5:QhΆzv h>T΅jqڻ3?gפD\ )^ؑbVV<]^y}&C&VKngUQ Lezl kqӌpc!ڨj &S20DR?A3><4urv#jd;8Z(˛tci^Awh88U b{A*v!7O$ gȒ5]j<-I<`ԅ7YG|ˏAaK )•+t5D s/.)'jɢ;`gikEO(_y>YS{ {s9M3n8%.UDylx DhgmzuZ'wh7{bVk"_B+UOJcFQgEw$0D _:2SָϦQT/k[HC7t_"AEX3n=}u0θ9U]0}vm͸D-i 6 ޹Ei^jrho䕜{Hbbj/fK]=cJWMhQԶBΤ霢J%HN&Ĝ1[p`BXzǾGCrq!H?Ү4M:|Clv [/%c=(2ywAsMFX pk$4{)0AY]%wJkRTvn95{ ^+x2F)3w/wqАJ$]/(uTr(dU8BG)O{\^{&P칎ӵt`QKLv2Xe( :?T(Y =={k8zFɕkDYHf)Hnb!7iT`ǭTsMSNxI鋞O\)7jg;;MH$b1V nԅ ,*^^:%ki6mU.5"q$~9VJ g{=|A_f{- %'4 d4}V<~0,3zlx}qߋ:DAn0{Wȕ 㚻d,`X䩀y=d' Q3A|UXsÂ;j0xx$cxQ]u6B֊O[3@-x`.1 g)[g-o.rFr1q#FĄju|:(,FZ|LpzpXFhRgg4O[/J|]y*b˖m/~@bNe+;]V]>rbN9Ws kMѭ` sܾ yqo@cMbZ\8ύA=lıw8+aYwѸ7Z>2/I w rY(ļ2m e!+W|ʂKod hWpBUP0rE sCځ`Zl4VB$ }{.E `@Lϣ Hi <,&?N).Sn5ѓi sqS߆*ѧ=}72گB8BƇ|b&;`}埉~53,zE@K鱯,rC>%9Ǝy >+]iIڣ9 Kuxjβ8ٸyI|u.m !a'RJm5/lcu + &!xYW Vbau]3,xR~'57?Z"sFˬbN[Rvy gjofr%) [`@HdCaas*f#74~7ђ5}JlAOMcۓ˿&sb1?^q{l]r Jzz%4\u5ŵjM|JMu{[8r»W:k 4 )dOl?zU?O떄vW۷TM>%GCSnym=`%@!I\ {7#uJi|>WG 5VN `gm3 [(%l|#i9Z} 0 vz( %ڽji$GaEB+Zh>Hr]sEvƖ o JGϢ_&~GBgf]<4qgJo"^98@eä4#cO%7y(zobXP+#d!F()sjPM"hcV?Ϭ23 |ԁSɻZ>,HU*=V,eD (fcoi?뎐ĔBw_GuWu {eŻnI$S2w6f鼾}klz5&~99<ŇDîYQ0Mرfͬ yp70zjђ"A<ұTkBZ9MYrY6! ?ϡ7 u˩3%6 CwFqaQ+S~aJi%A- Wa]kLxKP5y a endstream endobj 131 0 obj << /Length1 1656 /Length2 8907 /Length3 0 /Length 9987 /Filter /FlateDecode >> stream xڍTz7N#"=atJww`F FwJwwI7"!HJ# ">|z`k +(j@!> Pp%e5ݡ.0(! ĽL v4<BQI1I  J. PyBm> ˪ #/Æ !!;@ڀ`m|0tBCp9d8y^P={B t@ΐ?;eC"@p^=<``p`u4Ӏl|w (g+ lN`߆ 'w{'7r@E^omPW;;wOYVtqvS!6cs0/_ no y@ԕ2# "@ PLBq@6yBP w o?+4xq?: ]w sh {} OŻ,i&';>7d~*6Gq"pU vdg~ו$.ũCphy>ݸ;B`-t'+&;PE6VGĻ3}\1ZdO$,iF782_ >k5FoX,ѡO*|Iנ\,[g|x=*gGwd:)A\EzZsc2pUu+kwd蝮XNeAl&3H{fXH$jA3aTɎuǧ6kckVt>6y1"G5|f<q<vDMcmm y3@ <:SW4qiمZ?kǙSk 1' d9fDTF~l|g'8X]5to0P0(0>8"c$K aOy$N6PGrl21?R 2D25A7.TT3-hGe[ zTA"=ņONX9M;v.Tё>f{ ݭyK#=39]xSrw|AHq@KXBF5v0edH`M3<.SNLO0G2kǨ? V353[4 3&$B$Jt!m E\l]័qכ"tK{GC; NXmnr됻8r]؅~1^1ru= |iG.z*a5v eG]"ojgw[)xTh&VCcjb@ ;фBu 0b% }8sfE1tl|o0ӆŴ{7b&*dGt+\ձ43AJ?xLԃF'bfP \贫`Z (?S$uo[ǭBwg fw(P(F;[5p _T>4Q'RKʸŞS]ږCĹEl&Sֲ6pЛL,/"T-_\ ZF =YJ/1wFSүTߦV8^>'1X}ˡ\]^Q]%_udjDٽEg:ֹfꐏoB?/j(WF'M0n+X&aOTbe)RM[ 6W+7ߩE!A^VHR tF%}p@Х§=KT<vi\'9@f[#chlP{U47WfWtu/>4 `n<ԜVBmυuJ`2~dkK*KD$飚N|@VG[}jsĩ!"7.BGef$gL(oG;FkouJg> r |mA//(EQ&yRZD×vjB*!_&XS^ 5=os763:'ka\.q`byK=^XiR^=#skY,2KlKWG$jɳG9'8bN7:bqxL^$ #l:?~4ՉԘs %G hdqSד>*oHc_|e|\xyQ=w+x^ !Rg䆜z 24Hi "\2n9^+4%;B w[y yQ#FlkfDJ&5![׳`xo5?y'eFb[Rw ϫ/q]a,-ۇ=CSZ ՓM?vйRR)&(5HI4,@%il? T9 G%9bU PZEc1"3 C^OEwZ$zv|0bI :=f:XϬPx$wc)j]@$éG#VIX&oٔ elΟ+d g5Z /`j{cЯ9} =~3 <$ŋd;,^psa8x=EpKz -v>c X<L@FH OoWY}P'qs>{5['Z5h%ʄ5 X*QP=)4D T3NZV#=?n7S\w4ϐ?yv\pux愜ޞQUl!L=<oߙts@~a4'2%7~9F-[&[\%a}6u˖"^u\;D Q!&H BothPm5a{޴uؔmBPCvw%hg y>Vp k hѦzqVtbea8ع%OѓX%KAx [gx؃8*\$¦ ,xƾtm! 4ǀj¬b\V48{=jNͯ~3V4/D?k_ <4:q^Ú rR&; lDd@^ZP RKYX8_!_P=5(*P$ C q6xtRo[o`ac!1FF:ss;2%n9|ɼJޢc ӓ/MkgGЋI?*5}=r*GOU7'1Gcdp3lt/wV|RJ>YjP].8SC|2'zg41S=jUݫT&.!`=3QlD4̽alumŴrLuϑa lZBe3ؖ$z/A~-i*e$/㼈%]o؄6҇X{\ߌɊ楼 N('OQ'|DEg-ttBhvQĖ1ܕy'¡yI1+Í-A#f^‡O:^Z]ĦE&N$1U<10цYHΪ q|V|G)VG򿜶$vD0AF3ynR#>/].sBGML^֝I\DZxh$a9C G(؈cL?{gm^Xul)a 5E.ypLG3]q6JOy4}铜ۥ4[yOb,֫HI[F>+JSX@&Pl\*ѳp$Wfcǭɋ9aeM4ӦbCZNU\Fykoset֌Hb^f|#Wk/RI7)0N7}kt>ɣؓ( Wulbk5,c$oNBrt}uNqVjy;͏T*ݕo|8OjpdN+`&v6>zĦ͝Xn]z|Z nS1yRLpqN7Cqdc|.r<;Sp(~ o;vO=fZґ219tV}? =OH,1g3bNt3.9 AJ@Vۻ-[2 4*$(>MOd$/2""Spm[X.p3'@긘" #e SX4]Y;9Om_/^#)"ox(}k7kxI ] ˇ;~jE2AW[/g(in6 tZvmLϣBP1 ,`2,rl~F+7aqƉU Xࠐ#Lm|z{FZ%\ry_Dv[͹'S_#NsW`07D6-]n;RLHE x7#y@nh8}D C`ib7Jit?sW_,Bs J)>Y.F`ȃ/M PBoD΀#>ߵ<͎``"jSw({* ֠Qa+=kS^Ǧ`@u 5L)NYEѹO㩉'ǩm)x`~_׌:*YB~jF֢Md&\_ _Gf/lrH9}k!ߞ՗IU}:9}Q&G(3S=b\\g}>b av*LܰfgP$bWICժ&/u}"!;ͱ0F@GWv_ÜK}µ1=[M[I$ uf{w5F}6ؓ]h!7xn.MJE:nhZj뮋w֢ϠPBWL(ZUf0{K+a?F'9 -c4'}[n6}UaoVfXH:``ND$ 30H9K)ǎ&o YEDFPuNV} E.`DӬ,5TDt]R*v>ᔘ^: D;u4\Cθ4᝘ Ѐ$KߕX"iZ>6u,';& iK7F4X>>YɻN(.TΫTj"8$wRA@f1& 5M_ک̸̭Dat5O*=8%xX0cxipng$B,!~oRpDP Q#֐ReDp$,r9;ZCNGϾN &kE_ =oFό윇MT3e^=:P@2ugv AfW".)lJMj WEdr-{hQ>jU(jGP}us'['ȴfn)Q\%R[DO4x˩}hiK(뽒ʠ)1 _z )gߒ'LVh*|@6I(}j~5snkRW Y0zIjhut4F5`$5-f ̺mnqM%8~#N'QbX>!B:An=\Mem߼/~yJZnvސ"0*ZW2R#2kޓOĩN($3u~c,;e\^՛og[hL ]":f/HODJjy'[Ps=$ XMUڨIU{ݚ|˶tTtp®+ $KK{* 9y<$-JRh:|#1eg]NjxnP$*;;G4 &qYit^^=3P*%Ǽfd G&=iH} ?,H|~0%Ofu5B4Su7,\b. endstream endobj 133 0 obj << /Length1 1613 /Length2 8617 /Length3 0 /Length 9678 /Filter /FlateDecode >> stream xڍT6LtIH " 1CwwJH - tHt# >{s[{qzZC] fA99@BiU-N~q@.T_.`sGۣ* Prwpr88@ $C@bP(`Wtzi <,l`9jf v|< ݼ+ascfxBlZ`W `#Oe[6 x8@,PGwx8@[Q1Vc7Nο+d@m0@]Nˍ `eh {708[< ' 0,\-] Nn_%y,JO|l7d0O_UP qv+e(BGfv@ ~A^ %~ ~,?{n.`+sr n OG1~ `z'#`P()k uRR0//;77;9,@*Ba?>v? {5v߱`d.MHᷚ6w8xeYwG?; ;Vq$6*[i@,m\ג9@` +׭`GY7##GB-aV6`bz$//q^9 r@an.0_ Po @?_u!C>@gw~oGN_1ߐQ14J`jL/"YI35E;mo#ŏv Qݸ+)SU@Xݚ~!ߑbyGS|=Y0Wx(·(u-v~pC˰?w{a;پH)Y$OF`؀[x#Dս"%]rn܇&սq'l:3TV8>XcA%'!\>{W-[;UPkECW"ǎÁS8*zM%P e!F6 _?Ek~Ftn8\NL9/I~0CxfЛ o7S׭"_|gǶƈ5D\q8K2/y#?x)Gc]lK~D j%nҳU OxO=!s XY\Dj=VG1$32+h&)8TAزkB~τM^*zY IOЯ0P?'ÛsOQ WgT4IP[!EwQտ.l]5HZ}͝2K`'N.t+QǕ)PV c^iQ.*T%nPh>| f))Ddè_ <|3ze?anğR̵ֲX ߕoSv4H^ŌKh:ڶ-aum(F^t_.Ĭde=`_8r̫q{+0|I)VН9WU'Z@kɕ dﴡ C#\f[I9)ة\ByRsbѦw8< Z?jP4<'@HbT6{il"I] "bBeԸ4S˅ņp5RQRh6^ m!Ckxws{Xި-/z&rKѢEaT?~\ĕfُp\n˼a,H< b$GUbZ crH&!>AXџE/?ՂM~]ɭһyVbFGi_ȻgHMنNlvr,Np3KW1 s e.gaH_0,uh`^;ٞcL젩?rfdqAn9UNTn:`vʶ9kNf4j$*X9$1$"׶[rЩfA ؑRSEhmYxT(S*c ^sV^;GNցoټ>~ g%%1|6xeY f$ژI5 .gOVoyrOs M*~Rw0M]\2 Ǹƞrx_gʥ*O̠HymtP .G&Bm̺Ł*RL;<*cBG(~p/IYתFXYybHKo53ohH& PuzW ߎqz}ifI:d~ _}nEH(-ט4-E/,bljTM!9Vx.!}>+yJvaװ@L"6TS I[{5CM3X7:£>vϣ 6,DTOw(Q JTH!)\/ښ*2Ͳ(*"M(oH%WBQUvK[mwהy O:FU*MJ+^W32J-ă很OswsSPĊ8~3,w,Ly'UJ1i?JUK&sD4ttY mݵ_w 'DɫYU[ ɐoiCzqok4_!pټ+ԪupN{Jww&>3=7 \&~1|Fg*,j'SKAlOF!+T%EDS eIUhˆz~A{X=dy ڒAPbgV`LAK } ((g/\Թ7޽TD:ۍ4o;dQZlIX};{>QtloX1YyֲkZFi 2g<Ɗ"MH7_S fmPMZ߽kqdm_ceYSz%fK#Ut~CQ {6^z0%1.\}BCe N/3PP%}nGfK% 6Lw$>-:tBulyׅ4_C gtu/58l/!'Ӊ] j ƽ"P,4;* *ܼ~-O9}yVXF4vm^fL׌٘۹;"WQtKD#2ml@"-^s'A1JQ-ؠ] HZ_f|<60[PJ-&]Ž6cB)u(We1&Qn-ͧ/HI:Î,C6hWH)/l-2쵿sdo(=EL]|Ͱ(%OCVL{SXEQ_֝%ś++,B_@"]w+j*6aY ie5b7ox)!5 {thikU?o3PpT{}^&~Udݷl̠(2OWI UgCFd5=˜:ʿܔ2)K0"=6;a>(~VxDE7A>L9.V6!rMEKgWa{oNJS hbO4? 6+ |/V׋,`;Q Iګg/t7ΟՒғ/l(ui&\|m^!JfuTR+~ؚ/E 61`]Ղ@;L*VDz9R<6:fIJƂ1\'dy甍(wEӚJcYU&:SO?W .J;9Uhp)uSѣyRx+t>cC%a.nb{mX%7嚖Iv2{u{a6p;=^:#5zG 㻕V+嗂W/!:x Qo"JÒ7fnJh;޻z,lG`"_=)vUz*AG*y-k}5"KA@^3#7gn eѽA[d;)ɘhX!3PM*o '8tN[Eh!Yɡ+ tej6S0Q |&|E2$72TNU,Vf \:gC~6wuXm)fMT*dh9Z s,KỐ As^IDNgwɪ4J$)59I?_hJ!E0nj@]h|Ҷ\9QƛόFMEhZS+H*wJ]vQu"|ʽFvBqr~v)rOwmDa^s/@u pY;\evD5(eQ32xtjl5Vwu칡&\BP C^NfH9Uc)R W+oPi@w!QO5US|q=ӿj;IW2P}f4Z9*y}7TB>e`qIv_Z(*RDo+#aa5CX`'E{S^=\4:٩t!¾H?L\6" OJj/&aSV 8R(/Nv#?@&r~OhJi&{5ZZ[X]e}lD;̟A =`{}n]We-rmva>BrHdrutn 9|3۝u^@D E(|30K݊M,2RN3Baycʈ$ /#u{T+֝N-/}g"׈d[Y2=iT#MvWdaM>%+%H?I}9:g FZ}VLW #mzVk+ kvf$6x9z߅>Lc[ԛKYT[jv1hh2 ӷ]@Ey:R$YE&Ŕ k )/Ӡ~*xQx7 ηmJ|r,Y\9]gWDB0ؗțu#H<^:륋,a( 0 Ì82tRGITf_dp} ܄Q}I>c&:8NR3&Yaֶu(3KY֯Lgv o#[OLX^Ap-D;Q<>}E8L{6wI)=8s:KUNN~2W A'Eͫ80FA}k K K ?V&&T 㕕APEKî|7GxWo="Zwy)/\Ad ;μwߒ8 #&#թyӽaI]tyc|" NF,8*|K ;$:HӼq; +8P9$bYg{ўMq2 cj`^oOM z&x4XЙ^spDs|vGO $%h &&P2MvG =--ˬsoi6\Н,ic㲡Bӱ-+?rBqӊ!s®OۂCc w,6cUV&%{z[X(5;Qn6~肩!,&16bvS`ip2C Me6W +?ߞ!}EYWZE"wm`֦V|ygNDi)qcӾZB-#z.?<&FwXIEC*,z.ݷcN~?!R2uˏ} ػzXP i9̤݋==cCc11m--~RDsR77e#G97aeN :"7TX-ӗRQ ;\pY@fΫزh&|J^k2.W VR C"lOj+́j;v)gm"iqso}kc =pOvS`ﵒ >3禍7F։up4[o:( V )-,>ٗϞ@Ei!UkWhzqK:r6R}N4+\9ׇ?eTۉXef8&iWFPS z#\ L Ӟ B#'pd( kA]Ӯ?_^7XSŌ*jI}nNq&?QOj%ø:kgp8iQ߁^7RX{EYκK/ƭWz#.S4Vw :n$q(u̅{Wnb@dVܐ4,E5AY1q3 !Ϲ*> stream xڍVT]鐖@JjibfNA@AA: E~w{׻ּxg?ϻU׀_a QAB@)Cm}Q(" spΐ?VbcC!BclJ 4&Lh;DBbRBR@ @W )Py "xpFh)Z<!IIq 49 r 02P4UJPS@ n+B`A 3p@EAWw(0F `ο:deC FO 1-{Np'ՂQW+c"AD@x ]!B̘}]{L ="E< 4 ``41C1G¼@ _ϿWn!RTDx|~aQ q( _UU#ҿ k OG c! n1?BoN ֣? _~ _k#0 g \!v0wA (}0 b CnK`08D0*棁 ?Tv%,*! ob̈1;QFv  hL Ӟ?$5O H`;cN!/xv q i:P`_ȱnw~NFSsS !Auz#ڞnf~n~ƁN8حYndԧ]^Cϧ64I~GEZLp͘gG3ޣE>qt8^bQ"yfg>%¨6 f8GTCctӾy =3^2yw^KY~UmbPYTKcdӹUh])alWПb?yBA)=ElyXt<_YKWOQ;8[ҮO;vMkKuTN8 rqW?\x iDhc־J2ڷਲ਼|6=ׁۨg1,M30vê]_pFWXL|a `'Il}+P;敽^@r+sz"`噚<_Au^8 mQug#.;Z>]l<ȷa{}>Ӗ+s"w'M$bxOl  +SIP*g{3?ums}[x|8vP4yZ>ˀJ`WEb\MgET|;WJ: `g /w _h)C;`*X#p$ʡnzS9%zpߤ2w/{EWLt_xR&U4i`CE3]ee#Chkh0MܑZ5tROFtzyc s̑Fqtu|߁)poۄC1krшL1"cZG3\8ͪ7yşS!E;v!zw_cz'KK7gZJ~߅xl|t׻ e]OεiHQXD4:睺ɰg?/ s~KW;q J_XSs6o|3l}@wX%?8t+J,?7v;$(&~w]I(z߁zLEvARQwJ35ؙ h^se 5  n"(3^9`&͇W&O۩#WZb֤ꮟ8.WҨudKjwsV-ܺu,epgֲƱ|MpqG$]S\'Gqg%O(d?2jME#)  .gaÑsGSl[/Ǒ#J(FT<>rԜ)Qiȥ>VrZjg|߁m뗙/g@o>0w7(DME=ĔX@:.ږ.a%7w=M7'glZ1ܟé4^"ˈCKlu>t9+ʞotz~`[sV\[kĈb쮐΅s,_"jr2xWaBATvh̤%KPrцtݚU-ro;?rQf2FA!ά =N&N}IM2wQp}csռ/( +A݃66rk"4xy-fvhhh-d#9UnuO=d զk~F&8̻޺B0ܾ6aYuM-a%=?atwrP ~e]'"">,<층{Mﺫqh &yW*ϙ=GL ./_ʜlHޝP z$B~Z`Dt%e0>sst97&"a;n>t#GbA!JSW4K1P ?Z+6=BNNg5Oa'7w&VZ{lk>ehTPdl+:NQs"N7+ǪdүvgyjZG@wᣃV C'=8R\.+hm+ b> Ao'T+,A)>UѤS5HzF'ߑoq?SviRtQFS>:p(8o7,?-tc>G;y'n ުzQ ϻj3m/,i%f>'bpת+8zd &?fu_}S-YT5d9ݷi-5LK̵(քcai7>uB'O&2aVvO,i8e!&MurlԉyQv=j0{31"$ZM[y7Mu2-keݰn2E%*! ~}n,G.[Uk4vn(gA ϏhmI1a2$à:bۑ@۾d^s5A/[Γ T X=,R@&@Ysw  0;0'w2yBqu0ZjKEut+j6UF&qɍ#ӻU0d|;,DGjl68]9t6Mfuh^M9J2豉jƲ}^ܵ`O4.41Bb$\|A.n"5`wΙ kPDo!|n˟bW {ض]E/E:̋h/<k6(N+~Xo.ק$Rzr&Ӻ,Or' JoHLH JO7ɦ^g.U ;%O:SضmXWR֝{u> Lu~4jқfQPo:۔ͬe*ِ M,sXM[(gy OZg(N-RE뼸@cSfS1/j&ȸ&'hVOxivOA]>K5\YtV׋0E>a3Uϳ|vA8 *zCo|[e0L3)"BIviq=5Ⱦ HGˆiۇ PE3;pBeman9F9ΜrZք@!JŎLF9d('/ĝ mg <Q=MU )Lj3y.c[ ,o&VDjzW;h~ 02Y!%}JGNo1!5mL Be^.o=#0EM-֗<< =ɶ/'#Ҹ]) BN΅_\kp ~p3M6kh'X<)3~w'$ ,^s8~i'+ iy6.G@ک7&shtN{Céܘ]^nk7:;w媳wo[mr9f_5'6~*#yqAv!;K=YA!lôOu =5̍@s-ey'K:z_T6 s(q|o>iw&ϯ~/W4 eƅʙI0Yz)/ c,+:bMK"g Lp![T& 3G${9՞^m-/ [ZR(8 "ʆW\J"xRO6?E׮2~ 6ӵ N娣IdQdԈkMzBކ e-դ;<;ؽhuZIo<΢)y0!6fLsoŦ(/'M*^ewULܩzٲ6v" $^d 0b',D-Czqg>R[?yy^_8 cE.l܍i9MqwnT? d {?)Azz\#,>ʬ 4T\>CAÝeICf ~fgGOf65?_gf8p5˳y{X)hnx׏{)@~fMj5ɽMe-#mLšPpv8z&%}"D=w%*]IJ.Ou&qd *ؑg"B^Jg"T?-af2ECgӵ8>Ni+SQ*/1;dVͺul4w^,>֖߆% kv:*~'Wt̝\^s`:)@9+H17t;5RbHVvD09o1TgzhR]ej\n^=Rc3Kcb]r i]$Solmh5o(R ճzX endstream endobj 137 0 obj << /Length1 1489 /Length2 6842 /Length3 0 /Length 7843 /Filter /FlateDecode >> stream xڍvXl7CZ%6R Q ҈t tJ(ﻮv]>93x8 MQ0u# U􌥀`, 1E`<`P9@!e^0U(gB}=1 DR"%E`|dP?3POBW?G ?"--% A8A@=(扻 4A9!`u`d@ 'Z"/G`\04 U.P ]h@MPp?'sE:|&Z@/!_O@@og D ]p h+ H_P4 "<8߉CJF@(C; 0h4W_aptVAyz4W~AD#pg_/ R\` a@X+Wp@/o%?q%Bp EC`@/,:\H?q0 Gu}qwsAzꂿ [ bE¢` "* B+ ?ZH8 ('Y+'a`Kc, m`'7+o-/z"<q_ZZ- 7JHVG '?T0fB#~-0 /nqKo 74R r5]@4k1Nb!1tf0$Dap.@\y!@88'ПpoDC}q}". V?2-  8/_p/o -\Vb^YNRWD,)wRϭ*ΰ_`޼&iL1j: >O6]kL0~TsMTq=;;+ma]&di DaNğYZw/&XUr@r[Oeﮕ2L%{!ܓ&?9gvUHvZ쓹)w̶7D&L5s}~AL=%hDrlm'- \*n\^?42a%r=UqL+<fX`wv4,Х#C-a=ڔM!΀mŅ:EmI+3rJ3ՋCd۸P~ `XUΕͫNUA8q3$˼F/ ]yH54ҧ5U:T_d8iNn+Ǯ$jˇO|;{Ff⫴lƉ`&zS]ЕOFtޱEPL]|>X(g|TsäRM36S#܏m{Dz^+@ ψN'fT:۶$F #q}N!?.{Gp0*.$\xT j^̈cEN/j{ccyjiucT8^Ȉ<)VTN|ƭr _pZ(P'Tn+ 6w^EJ>&TʟeHI&2gW˪3+zyu@d'P8ՊnQiP|nUukh2pHb:,X= V >fQR=Ŧ~N%(WNwy6>6EOLYb;}үB^%⳼Pwm:R{QX*4>v>b?\,yReg5P *v$= >E6٥}0b乮 eAq$<?@v2`/.FW Y2^y :&">W$xҢxɲ/ L7vu{u]jCD2;閆 l-Jn&nDj/~[z"TZ4KBS_Hx ʋ{$>m!۔`sr3م2!lmIO}qFu>z<7b`r6jx5>M׋$^;yRE '>䨽pG5B$m3E6ֲ{e,xʉ7)s=!0kglqU5A읯4/Ǖ,gԶw_0sy*^]U\>NX#+V/9VOhw:OP9Jat#R~~%w68}vnړ ]#..sJ]S02cɜQ4>~9+(W]nMIdg8$- ?3Tj,Qe^H1J]kD]мLږ k}AQzKFr{xtiLzzi3;-=]sKZ(3q ͋4g/p[xY7&6gu TlrƑlr]ɜĦ > L(Oi28.fW="1?~ >ײv~E;ks+Vݿ͘@&𥔥5;ႚ\)0Ƿ Jp1azuK|ʁv! cA%%aՑ >Zs%u⅝Bj+ғƾRӲMzVK<P#*#ٕDڕOv ;8ci.Bug?EԂHtSx!L3ÐЭ)փ!߳iDK#EvxF0 NY+ܓhٿ\BUp2f{DJw7O,O /0#:INHc{2ћw?I NN$6rB6Sp?PB7OΫ ?MolIu@$2 ?.6 /Z=\޲ oۄI'̡?.jBkT-/ڽ@Ib0AG5 :@>}7A-_AAd|ZYvEeKǀ:ppČ9h,-k\8P!v#.L׭p ?f/`z1:X_u "ߧcg!{yC-0mPC/=ITU:{.`ǯW|HV̝Qo+ԸK*[wP.Q=Lb/ +ܜ_"-$ a%w_6u=qT]*r3"uRZ2h) BCҧG*N=KZ;4W^CVR? [XG?F{}tij~\B,JY@]ˑl}RVo O%]Œ[]vX)hޠ`mg x4AN'`ʻ:]')13Xq#b_8ZbLؚڗ~ ©Gd?\z*uZlkMgl3~sh?BgF;#T1/rk뻴ƞ0 A Moj$>આ>yeL);`4Mv1 :} lW[cDS&ݾCImb8Q+%I[݇):w)g\~`a}<׉͈l88i$p^~g3(;m'> ɒe^:_fFk5x6 $1hD>WZzY3C0WrI o+ƇU}#B% ":Myo5{>SK@xw刔.Iy'UA?7{* t )S7h6;#W _CQZ/ 2F0[a]-tL${:ӮBG~%ΥI mD wv[Kb~ #i۬L[N [L._g@˪(G,M}f <7MkWķk^+iH*+Աh/av7 ˶)Zthw욆Q}Rw8|hLxQx ]9͖O=Jx^0 8!Bs6=(N\981kVꄡ (KĄ҆^j8M0 JxljR }KG{ *JH,y!+EcFW=!V$WDJ |MwnV <$(QQF]&X #_:} Ya}2h,H]<%is7ZsNMPV^ڧ$Ymu-5xīf5 0;L$|!'߻gʅvNbH`)6q{*4PɭxՆ ٨i敁t#&o 2ȓk1%$2dqz۹Y!kMf?8)>PTjބXs Wu t؝ g߰PäZǫ: 8(9\ګVdP  M,JxIegGBK=&Ev[Ժ79t‹_3vrv, x^)Nww QX$_KX]7"Rlķ>|l(Zhoo- NmZ=6R'gQAn]B}CyKo{Ln=#g5}$};M];ֺ ~JPsIYpIjH er-V\q&I)''=йX >]Xϙ6J}mamv҂SW#gD!mr/:HH7 SLq,ioٗ"LYs{7mZxGT-o9)kcɋ"xeևԸ!iqqKdX9bs&HNǬ a1Cw9O;#֏%nG ф竎UFIPO- Wznf*ilDԉV-HiΌ5cHb]%ӓ;x: Uv5adb{<,zuܷ) Y8[]ˈMC88'qĝ(5|YGC&L L2+O< ~֡IzԣH\!$l|ˉMNegz&y˘HKvݙp80%0\}~E`[tMɶj{6Qx*{==aoXך«#Z-2;ljQl֊QK;ӫUY,*Z&IX+`bdۨlh'BӂPtoe e)Mܾ~!?k엇 kbxG;ջ;2eݪ?"+H-tS Eg~2 ~[rSIT܇lef(.`"eFOht^rq- ;PlԬ `A-sw?}YJP-s 걈M|<(&)CQ1xw:>ĕoB1˴1Hc$C=aìq2/;v^rrQ)dl''%Ov;ܒNLhƪN;Kj>Jדj}?>=t2s1){̃7Sՙ}H7KⲜX+*@О1y''{F,)Пj51?V:°pGCQYMn B6I$Gi, ad֥\ Aո7200~p90@2_Q+Y#JtF}m"Mݾ y:X qy]g,dti3-HbܞwჭtwIQtnLmtO`yת 웄Q?)5 hDH>UIUV+"L=%#UG? %!^en;v~H4~̕ y`yJ\cwy0MGFD;^_꩗Y=NgZz2im7_R8Ei6Uu6LvNNMG{UWs ٣[qQf4'hT*<%(>Pڮw(# igͣaf1vtcՒ 7Q ]ҋT"GZM{OʓجܱW~39e-tZjziΙ@ũ>Wo m>(CxɐgQe9h ? fkmV` RǾ~`o@tqՀ3)u.CPsڢȈayD?t)zP-"͡Ja jPV'r96s o@<Eל"U1r9CeQimj+6*zƥ dTqW_aTBc-(N5> stream xڍxT[.M&{ RBH HBUzo H D(H G;]ޕwyfd\D B"0"@Qq9-P ..)*..Ac!4g@e*Gwť7T+S]7^<TY,D]ܫQۻTI4^v9x`Igj LrG߿Y04-yT?P/]MDY86DZ׆U:ULb*]wY1S2ԕ:,jvV&ԜbaF71r87ln5zќvaSOdE噭ϝRIQcP ZfZ]|#NUﱛ¢_jl8'/GclRlzv_줶JԔ4# gB̊ Lz.Lq%[IR[P[lEPQzT=y[+bxbPKS{TM]sHq: v/TaħkMV}v(3\veH[yn4G׭E6Mwq}Cb3Ěljo/sO)!0Wd5YS}ȠثLFa3G=5 %Bza(l YU4䠩p9(td׎A{&>KWE5ݲǢnAk{k86yUĺD*Nf )k&no.$wk#6<͌܎9p wC ܀Oص M eKđ>Ydtpw) \:s1h_AV_m<:Szә?Q_9bfs^}VY|UA;sQA`ׯ MJ8~fm?Zט4k5&ηVSWꝣtVȦ%½4 FűwJ‘C5wjfݘ6ۿcPFP`FD1(\80V@AÐ oꞛ8U7.іx$#~Ǐ홏Z6A'Qdb{>ϓ';~,DD(,%=[ Inr0T>iU^MG EPP\2׵)UJҤ%3,6nC;123_PDDj~O3 xL{| 3@Da$07wM-slg.BOyq{0F=<o_ըY*ߛ 5,&WB[N½m 3w]m GԷmb)kky/BAxSM a=\ۙ8qRGjK%>\un*Z{1q,y0 *0hYZo0XMnTٍa!c~ը!|cpD*d[yV oS OqNiXAhUl9duF9@[]'<̗s1k\:qdc[Ϟ7#=I7\j6XD:Z^J x$,$,A9UEg'I$"^m|NٛNw'ǭ9_ /m3ǻʊqIi _%\:4X^L6NVa+GJ)]7GFD80n}ܔɣiihl줃8gdN'xgr^-&NbAo}8h> O)-bNzt?phw^aɋ^4Qoctť-LVG~@TTh,V,!C(hjJve-\&\bMU丯C+X!q 13Sػŀw":4pهnP~[G31~:SKri]u#y8sYlc懞0,a2l~T%C{q|=0d+a\Sùška}44q[ʔ\~[% Xy^eWU})8³<\ـk]!b/0;SsU e&gu#-Oi܋;EI υ sO 5 > ;k5A Ozl{V!"{@s"AM.1_JIYJWZ$S83߈/CN5u}*:R>m$3Ź'94AnC'UUĴ ¼zv:>JDNÓHg}=DG}S~QGMͫx!5%,OV9ŵ%M?D0=X)e.},J0s3n.f)[M7i(T`M^3.RPz=yrlPD4^P[ }x [4ׁ}0~%V;ǯT N'7ZtgP,LP~>+?C+<|.n2{P>NMoRVi{&ag&aK ndT'ol TC+HHQ%KUߒJ"ILecL$ cV' !scf0 }٘D Uײ~:X3ԧnurPV!]2fazGJ)ɳ2י[r7T+khV{=<Xy<}(=4eXx|Hd# }>u4Hqw%lgR4c&{s3 yኌuϡ7p9zE Ŷ| _ęWY\|@nQ0.|XɆg&˨'k+uxܘM^`M )-1j.{ xJk#p2ռO۬ED sx"!an,oCp*Xrm$Haeb4}ybP.U?Z!S,ӱ´ r|ϫr(+ǟ7 %m5CΣp{ln8+q-~;2Q/y\?y=Y'O]8/ %aIuyF?Z67li5ZjuˍSpmk m/^OեN`r4vCi6nZ(cnj%E^Wi}]Z7D?K<yf <`2&w dgj8(&x+WIx2 MBO:3WJo; f6e/Eu@jjg|\l~jϚh;SE:;.*`*{j,YYA`Oe.WsxztEZT}(4&s_lMnV'JN#Dq{~YuCNҖH{C>g+F8wM&ށ ɆsB"몊-d7j}<7ҟ~m U<%4˻z>II;=z 4KQuXGɣU[6g`zZp`oİt0#n7Y:GVʨ#":e-Ů!bmFv;ć ˯$[$ 3Y aNʚ9=Nf$DoCVRIx@K@Ho=ɇ!T;G>;}'!Kց3˒ɉUG䬙}8Rr٬_TH#M5YՕW.(^oC3Zo+X-欎{߁3ȢX k=,ϼ8ƽ{rP4jQl+Pzkz{<.-I;̬~Ë"Ҵ-EĕND3qL+}AZޏCٯWs6~/0;"E}Xb6V$TK]V[M&djksE:EQԅ% *W1 A -}3kWo,.!/'4\wX_,A|Ϸ4{eeI!8̮THG+:gQw C ɍʧQwroǺT nWmQҪ$Xff@\ѳw;Ĝק Gť~NynJX*ATS/ZO$115?;ݫ*?̑ Ļ%7 , dEi/_%4*D@9Hm>xs8/K;ے=q0?7+b}ߑ Wzcg z|ҾG6Oթ4ٍ@]U|Vcv;!wZ>;PJԒ gm!# iѾ}L|=|\ɴYnvcV*Luω0J%0E񚿵Ra-?;,WKa@G~u,SK|5<4@1Gc;q(JC6B~G98l9ǚ>e>9l0R|pC5+ܺX?c!^XIV4 [}({l(1ݮ4Egj(t-AcwpF-ʻI] [;ªRQLW heD{'[&J?@fOr7ײڙ3)v/+yq(ipcWMo½( uZW{RO9jȩ%IR`1-Mdf7r<d(wسƣړCm+3. Z.*K57!t"h4gN3 :_ w= o!Xfa?gF TB2*4DKvk0x42&e9]VU|Q_x%5W2TZRy%$ϑ_NMqšqp1p++vL Pz,YU#+#.C<ΓB?Z |Md^c,5B%DY [7co sYbb!-ghǎAzA0\oHc{eN[=#Gا]?rS}%ufoFdFNx[Ac;wJaK0 1.wl%IFQ#R^k_eU!6Q][fEx/ V 5 ލU =ˀ'|M5HwY"hҋ{_~зStzt?Mq_],x*.&mC:o߽ fH?O]cz[߇p/$aneQZEiDzmaKIj٧~M?iN[DLMZqr+5 m^QY[̤ b*R<c9A9|4g4q˸,]6w<#y]ka OR6 |d')t"APLi%_-3rivezMj''}U8Ay9\`{6/i8$g>A \{Ҍ endstream endobj 141 0 obj << /Length1 1408 /Length2 6068 /Length3 0 /Length 7034 /Filter /FlateDecode >> stream xڍtT.]  Ht7҂030 ݍtHJ7tJwsw]5k}~~~8شd0E$iI88h_r# AL4$DED7@D\H8N(-Ϳ^\Pn20 A4 h[#fG(ahEā@www~ ?e#}Gta.0 k`&g2~-FCP0pCaL+ `6詨`?d?g]oBpdtt <5RTG{ _D q !E3\(څkD2SV@X!a ɯ(s?7k@#.+_CX:#ή0 D`w LtXc­a?o F|w+`08?10s(T=@oO0B"*O:ld‡gǐd4B>_nGfX42^˭x '~ ]ͿlvY3yp~'gKfBd7oD/c)Q*/q౧ g˦i}=])BE¨Tٲh3U\8e^'a(p u13v08e ([5 #=l?< ^rHlD'iAp =2.gQ_|j3o_܆ Yz;m\r9sFQ75#>95H‡y 1қV"E=Z5cxNII/whKv!a~=,5E seÈv׼PE)yZO-Y{ᕚJz 3fWOL3@°LR;ͺ8s(`WУy@O7 !t4"xv#h:&Ϋya> ARAmTf1e*߅sJDھ=JH4OA?ωb8ND{E\[yT΀NۡY.3zrgH4c]&] L'{8CR[q~!WhUس4{\^()c#Y욲F>4~~#7ɉ4O*{iдa.[|ȠyVj&dw@OL> N +7jr1CDְdA 5hyg9 bQYvS (wY,xPg,$H@vi>V2Lx^cgD^΄xjTvgoM $CLB]Aܠ]gL=LP 7P x,7^c!) xU;0qn`u(tz=V t> oy:Ht>h9BJ-K1~O@Kr_C`?iHAJrRe: г54WMDAb^j2XcJx ]11Wp(M׽-O!x?3MQ"g5`Ǜ7)ĄıE$$!imƷ.ī'h}a8[seG{II# cw_*E-G_,åG68^V~ۗϧ =tN)څAH'УZ14|{ЉzMWMF:fͷϙJ.^M5ω4H*_VDe}*YN5|)J`iЍm " $6X68wcUiلjwJ?0,dW Wo&s̤=d4Csqt6zXRhX#iB ʧ' ff4| /y{5wòiq#l;{|krva gꡬKޓ{xr+HjƀHE1hS!2BI޼JL e=po#+U377jmH`+~=2(u}k,6@%-ҙ9+rwB 'wDAsn2&x5+\N)aRSqGވ/7_b@ehNx}jy(ze4İRYwLyqd/^lqԭ$N*aNS")o<@?eu{=Tm#oqARO0˥Y{,['6 ֭j|2u%k.T?eSy( iFxvbj5|gx7Nʈ-d%N6\>N6( nΉ(ݽS/!3j$KwM ~#|%I n"H#ƪ|ngKW3d5M(bg('-#'>} -K=AfKKڜ?1<:_EI*4v2 ᐫ4Loit\5"ǙTPA37? l0du d|Sf962ORSzژ{| PlM/lm(;V 5wuFq:̹CRr,Tyi^&3hƷ2ޕBN$2~@+=?C9YB ''zM)ׂ+ù;[:PFG))5%dOh:V-2 Ga}{'bAFyسNU\2({}5VtT&80BbQ8!+MIX,N*%n_VD"ib&o _}(U$-J$m"pbNp69N trlӛ'*FA%kH2y_tZ?3.lYl7Z'ᖆLA3[C#.%e:NOSxd&#`Rt,bOPH ODL%Z;aux<`.$-NZ!kKe-UfܸAnü9ui&Xݘ@d+!lSHp)S6sk ή֨A "b~64bϽO\mzp /ή,?ڽ3<%G;=G+QOGP j2['1{q2?A]@[\}#|.Z{?$(J=0cT;6p?aٶ-U%ܢ&yUO,~5%yHUSz5RL&AEޓM9Sn/)*բ -Gq>rLvzpԤ,9+(;}lm{t{{z/ܞWY|bp:Pk@\Iv3Zs)FaQ.f|٣H:S_%,i:=FmwlSW,zkG0hf3ӌI-UW[<7Ao5_m 삶l5jiX̻a8/[Sqֱ!_9<3fǾ=DVJ/* :6זg;}nxO`y./ٽ.,BS[>4Y*ͼ Aӯ@J).J+O2"МTsCvWTwzɄT۲.蟧S1 >_#DUL.ø"?Wg=D^(vo;%sC7\6q|U uI;T{~=Awʁa4JRV6\Q6*|N*5ߡE:I9h&2KO5AoΣȝ\i[<` U 6n~I6R3SI"j?fE-/9qVt MOPHy]/ڏ S`3ktY[ 1Aq&GSբ23*25^?mH ގ mHo}Kjip* 9.^QP">"m6r?vq"n`'"tp=hdQFë WSxvf3e YUXiۏ;-3S-\;6˩"_[uru0iAy&yb_JqޝvG =vE$[l+y)&.T {g\T, pCuOdHٍ϶tSoOToU}~Qi ' f#͎%F;->Mp>ARrVSRUQR$EG^Y  "CQtu `gxiU[tYIӁ)*]Y7BvSww^"OBt$_dxCҮ_\t.Y>Kh qxѶ3>,'䲂">!4 xFL tOS_̱zr. hN:-rΏ#5WLD9,%׀Pdܡ1?uLj 5&yУZO>8JsQY_Ʉ&de;x8ܡ:F-a+#|q:a:3H^&;$7pgŶyr8$5ʘqZMs)7zJa/ʀIuDe0ZA `l>׉prwGlIenuXA 64oeIk9">dO~{P{X&{-EC}%1ŧT4ȋqt< ~ 09ADm|\M.浕ZrQ f4Mg2F};ꑷ3 QT|M@4LbQɡCQ:̜dc׌! V/#!\Js|x{c8Q.F.%{,@DQ8DYg,e͟MpZ{)mľohx)V0zFLMbW-pyUhGGvǛ5[BM"Nu5W7RښYߔb\^^;= U-ȗViUB2{35s+-G bDŽ.ثhTGnɦ*лW(R|WdovFZʾiB,Ӣ0g9P_f~L%kʫ~CՁ#Qho-Dͨn[k2]+pn5^7g53 iAy:p _[O9v0BhpQR{sKμ]1MizN&3 Qo{6lW&c(s>4 Q4v+Pևk|hٞ[ ߚrߏ^˸_9e-~^Β ov= 'I EX=iO ȗX;*l#3> E!d/^0lO۴\?דEoS B)> stream xڍPҀ !efp ww-C hp e9{-}{5*1HWfcrRS֠Q5@-߿,DAFP d `qceΑ f 6ȳdlATjQ;{7G%>t&6^LDl@`#[djgA'j@Xͅ.`@9:L P0 *5@ Kjgu1r^`-xP(ڃl2ˀ Xo?mt6217uۚ  05bol62~1t#2ÿ8y9fq[SQ;-G}b`G˹\+[;[6L`'6/"d (r\M,$PsdC҃=  b @@^V/L&P1lO1/~G+X˄Zc%t%enʏ\\fv.V;'ˇQ2]ǿ|mrN){AKerA]qߔuoEN2ـx\'۽5 SJC^Ae8YX9!`Wjb%Wc߬ %;ŋ^*o^q[;?`hr/`{JS A_\/=zQXn.P_/!NPzx@+DQ/8x^exkǩMl _ _ _t _v h/|k/|k/|I/|Ir!8 _/i'GǗgϕ|o, 2A]3 hysuy%8󮲟G^HN!{sgJ8b]+$!DΉ}GCǐԜIe4=!}I'H X#Ñxx8D*>VLϴK?#ؿMaѿT Lysp^2@(yDp0M-Nt531dTU?Cz{\|;RZżIj`U_+э/("Yƴ?:Ċ-&spіvI J.HL a–W$dL06(^x̳M;F>mdF"Y[M@[{0Ш)0RizrOJsFAX!L1@]EHdHjwhf+ջD"\݆`/ybI PiT\lyt$X9V.9-:T39Lz,& k"!R߄)nu0ՎZwZwg5Y1‡0{0e_9KaG pjjZa~-KSM5&/Xdbs>=XEZ4zaɯ93yopJSF) {G {%9IpYuލj90hF@"m+P,I Xk |FOqߕGPL,L%'LEG((xahwDn0UN) |y7&wDͰ”])M"ֽ,èYO n0G9-٢Ϯ곋aV9N5Sv(qbxī>2\T:@* ixO@ 8pI'!!B}Uvw@_2L~#qtx\N4LQ4ZezIzWp%pS޾W%h -6 "[Ի1cIS-QTXPe'PIARˁˉ¾5Ϙȑ%oe}9ERh1e7ZK&{w݋zڴdRcS$OX蔡("s< nyjTa#qV@ik:77@1"L8 eKT!8i.[jL77_/#{ l vQ{߰3נÅޮ' A=tu BH< g0%/.?AG3–B]Eni[,.A󌾹A]>;/1˄CBoL;sܻ9H)WKbKK+ e0A"h[.R$Yқ"C^i'qoߒRy[:"hc0;kD'TqwZތB:rQ`݋Ae|}xzfG-Zfyw m9Qrf4mv{mTEY9*ƫ<%H6'i#̢ 3bu pߙ Qh/Gȇ( '5fMk7+`W>WjKJ_g\Z04z4zߜ_`Wa[kIZ2Zh+1P3/;\hpz4q>ѯv{^rtp9ʼpO؁cyr<)yLYW曔S[uϹ+MtSj1)c,xY\FFAkReOD# I*VQj%| AiNxvoѦR 1uڎ=~rv'Yr۝}7xmNq& AK]z7!xIj#7 윌S3/69eOKcwX+33V 2DDÓÜѺD!g͍7).H k8$HǴ>f'3.n7K A{|8h1{Kk#P OՙAfy|>SXIF3PUIi44Rqd+^r|x LڰZ>& 94X{O9^Dbc]3:]A0qj*D}hVpa5g/&DԢ~:85;D` AЫ:JF ԹwA@ϻz-tߙMN _oh>NDVY)5 ]~7w;d;t_ EKY _8SUx-!FOA5 Z1N@4PSk½Z#)(BH[UyB0`@8\Zq/6}9I?Ʉ/TmzFr7M b ڧ0|Sj d8=tM9/qzFwDN?VL߼>c~+,pa]_Ul-~$G`iYBFCӟj9tGeӾf g,V|kHk/]PXbk"m=Sq=HYY bG2LdfL\Tϯ{_MN.a-q*g_)= *v{oyn#+uKg5ӡFj"]2CKLDzn&š~?V~eЅrB;hx"I?WDa kv|x͐qNǮFҋ]RLxuݚ3Qؠ0v;G$,?Û@+uElI WS_wl*?c7 ,er&#*gjSݡ"Gr5<,Rmj_ ½aXp32xWpRERQҿ}6!tRL]B]3<|D/WE='ۉѰ[RZuog<%oֻjvBF'LŪpuM3b-}9\Wmi0>Ew6*x\`|Eo.I\ $Sݼ?Xjx>`rbNm,,JdX|^I# UtHwVQE[Ow_r #Bk<-hbaJC':wتc yɫRY̤JRX](fA3S uLPK&A+o S M3bFV_˭W:Srˊgd*ѓv*by'5jA+ ~#@T_gL{IU9펭$2T'KB~5_c9.(ο}ڍtL{4֪]8H-NP{E~?>L;c1 pj? MaI񷹔vS|cđ5><Ìd)D"(-ZD͔̝;B#W&–>EEryL$TS3ЗϞI*˟TT2x-K=-~nk41 a^[s!zz}kuIZx:Jn/b4:iܜ|էqS8#b]<'O-S'Jl&֏C ~:3CIk u_2 DDZ2/fŖWؑ@CQJuSNhhaau Q"(:q2hx+ɢ%QӔQ_c,yZZnP =ׇEGl)ϋI zԤI+T qC=X76qt3bKğ`3}0$MzEOӭJxYy76%2g [HP֚ - v'R7zBC] bK3ѳoN}LI#W¯[*_'{ ?T!|04ҥ0lW3Ç[Lg 9 ,\{0@N҃U*<0$e=_)AMo`{3bLXw˻9M_4ެp,$>y⿩lMO7^θ/I >ߗ|Ė*^;Ap嫝{ʹ8o AG$[ƹ;S}Ƹ DRI_եn`ϊ]Qd=0WS?썫!uu)z1G]@%u=`aMd &\n&O#dU tDstULJ$0JGR“;Թ>) _a$H 1-uYgI筭"d)d2_2n{pQVb?hbW7[\2iyHBE-ѭ-#ߣ,4nbښ;#vgeZjH2 NjOI'vpHذ'O@z^k_Pir&Bw,ZZ/&V~I1ٹ D=ױ: -n%"X*k#-BJ~C FbqJc6zW%\`t2!el\ ,DnG 5u 2YFߴSe: ocCu!"ļ$zdDYo.=+~̧1CgqRd8Nؘq.C/9l>b[q\P#@QCk%?Ȼ86H" #g>8&F`ŗ#WH!t08T]^ ][f67:jVmΚѣTQz; ="<7xLfRyeHzv-,b\(=dBra썿rhg05&*fRJ\6͢4j3vגt%_23\,b֟cl  <"u-XG$ac* Z`mS ؂G6 I,H;rȜ[WHfc3@i޵gg\k׫a(gCY^`e@!F}=pAJkG $Prqq|jbwB%S8CKEw$3$n?ѽgwT%{qewN[#1` R*```.kDT+jt0y-sE}!qeј ~>5 fOX)2CD7.ǢφFKV #*]Z/B6QI 5Xԟ.>-&ߚC.%>}!;֤|2kXP%}:Kiy{srˏߚk $}3}` 0eABnDId ˷ 8tc9vQE!>B=e@WZY/@9͓9@vߪ299S$aڛHv6R DK~0Ww+3Yr.O5F+ĸc!qT'/yosZncxV=\q< >o,IN1laKe Iɇ#n9;ӁGw%yMZNȳx/swp>C2CFM]G#5'h]m{ kDjo(ϓXJDfF?}ґhIP_ ČBg&Uj:n*=%?9 Y4:U%5-v"H[-KBӧeg9Lϔ H4z<UO}b(3=}=*XScU:dԚ\VKDCӹF.S){GAZ,О_Ο J^D|֢c_یKK󏸋 5$gQHuz궩TcYx HwaGb)+[U(LKNR` W"b\Cuǹj&ӛ{iDȃ$ocxO!e< #n,7{A*y];nJe_*t)aP']qS(>2j~j k ]oթFᠰIV4}˹'WQ$P::':KtZaVBre7VSy%U@h;mn#'u,Y ]Yd\LN4rMб Om Ltk,3RA &SzNl|b,FوT)튀e;svN$S3MTAXCl6|WXL)Wٲ=dn9}$㡸u!;hH *?|2g[ԓС0s0N$Ƿ,F393a5Q{?Fkp7p [+GWH%\EF4"?.ׄ:nFtr:ov_usZ1m%*/#i W5@~S`{GL}noO0.g#4JEYKAS֫ދapM 9ݓoR1 LQ7(HWTt2Z17?T l%@QޔO]MAyǡ3F;Hɋ]2?ZXuggJ.]uդ&M+zFB0V86}#Z:<znP QY^';g&"OgM͐Adm Wq#^uv$Mþbno/8٫Er%_C*"UaG5Ӣ|y'S [T!YǾerh-d`-xTlǩ<+:hY Cyg:gX[;7J* M!<Y-2'5z lb&x*+R.:aҾW2odn BX7(2Yxg<}cB)pm̸W#V{IK5K&+UEşֽXEͯ~1j FlS~2 ~I I@#ӍO,ȉPJ Yo%b1L<,?"*+n9{gj dJ~CEs?}Tkztg9/ :bG]'%J78ӭu!IKHSJ%/c ₥FG/5Ua.+r (P#K L9)oՂCZ,ΣdPBݩk[Cykw v)b37*3f&OȸL{W1Qm39n+z]lSM{r,c|6J>'}!ٷBlY(>aު@.oN/:-Ȓ"Ta?~pͨex*ϼ^._ QOfr%/֞ 8V/B9u T@,A-Dg HlrQ~O3:@T٢S:FsQbs#&KI skUxԳpjSy[fo D=FF|psfUm Jgr.c50u^+}{D_=5nǧM% էN!〵F%CM\Rt#> J+Onօ(1c&xdb4_+\sD33۫r)1J2PdQ sH# S2R)^]+{MI !?L[Ôw4.1?d~ *Qӗs +UdYU3֣UID3-{T]Cb ax(+߼xIX P}l*9QW\H/qeBW5Pwb2F9VEG\7n"BqmLEoNr ^I4jgהJ[:-^l'ȑ~B]R]x#cA{]sFE07ZX*E*Fp[`rVV+G<[庹4jUp0)<||1Z` !,\͹uUփ4vhHϔIaĄa{ndqE3ܻ$531(S֯B&qV5?dgh ]> >LdΫߖv 27S0Ucy.>..&J^=W1  b VH竴)qY S۹jzƄjZemjm"~2jf##!r&|ئ ע+!u0 72LNTxB?J:q,tsT|~&+ %+\5Z:U%p>>#SizgScͳhm׃@/K)uG+bZs OhF'u=3:ԃu61^Eod B 1װ ͽ񂫅"1XWÁΘ U{u\o8us(mN fkϓQ ^}z\zvRcn7F~5)V-if'fE@`y+?FqORj]YH.'tuqxLV}5_] uZ%nh^QT6}&hkأ:s W NK1R^3 77A+)*q <=QΣWV_]h.^oia7P WLxmS>싕 ,G8%3B В\*'nKcM JVI_@ko\/dh-%"[XHXx`J~>nV\cšf[ 알 uPpO Pk~ׇ!j19*bHdrEY%d<\Z!RrBq7vϝ,(5QUBeeco5xp{T8b,>]ì)7]*s^B䔋֝\׍8'VBL&#T}!"&9py)ٸ.^`dD Bb=c?OjGȹ>W 3ݿ%0f?fT]ߴ>tG7&ת4ge$9Ѓ-jZxZvk'O?b Ț&G0%Pd-ҶJԌb${ 75eNv_+lX]H0vֳl4|בgdwu8<>Zr'L_ߋ]4X|WttS cEK٪e@L3@NPl׬#h'Sp*,P2_(_]WA1jE6Xs&ɠm5^gC=!]Nr 52K"6˽%v9ݦG0>F3~ZGd9 Ľ Vs~Tw$Wc1[X$0"*Xڬ9rf!X摖 wLQ7iLSjҭ~/8A$tPC?]تvkiTZa׹>FP1+RaU &CiKceex#7{"Ǡ};p~$4DԜT9,9c:UҐl TrU@ ?\2ြѦA컷-R")GIVsJp'@e;AB2݀:ZIwjگf3!i`uG HЉ5ɣ!w2WIY L,  DjA1GW[a ۵H~Z9# Rs\ ]u<5IdtMLe_~bt6~P;Rj˜) &7CU~43H8N!m.lgw&?`:3wgN/&Xj=Dk1H}oOsSԝqYs 7 [U OV5|% $!x[n"|?Cr#น cH1p?OG. Zμ+9r[XT~꛳6NC'vGKlʝCw]Hf9J'cM Bs endstream endobj 145 0 obj << /Length1 2558 /Length2 18169 /Length3 0 /Length 19649 /Filter /FlateDecode >> stream xڌP |pww ; n=&kp79ܓszf{%*1P΅ `aagbaaCTtW@tr${o2TȺX\||,,6;Yv@gJq{O'Ks hLh DmN&Fv# -job t4..|LFLNB wK 4.hd 4&Jf.FN@H`cisڙ v<@hc0np{di9Pgrpaٙ64qY J )`M,\-m~; v@;gtZٻyYڙ.Ձ+P6 9:&̿ <)YA5z;;@e}-̀Fn@+ߊESK1Oth :'K hX,0S{;?1%x3r.^.FQ6;yؙx,KM {=hK4@͟1ed1}\(c3tKOuu퀂=h?4tZ#.ڙHKgIK_{fciTw}YYX\&֠4_F ;{K0rr2D`M''@dgr;!>R.NoY0A</Y`XAe @| O)x@|YAf?1hxA1 P.F 3h(,܍ PNF&@SbG?T?4pr|0 ("z zGWRqbۿbVۻ:db'"HoşA-t$ej/j 2l{A}A7*NP,;#`Q۹f4(XYA:Q8@,=Wt=2Kfi8@uqWa̎ˬBsvZp ΠVPr6F O+ n/P ?c 7ӿ;:FAP (ǿ _}?9"y\~&N>n~n@E{/u{Ss{鴌+N_]Q`Shk6nESFw$hnDVI^Oڛ`;>t><$u",.:m$'dTyqQlwtAQ.ļwhX[_%\11Z7t8g #O97zbol ^Ujl=xx o0&fSeqJ7rYh6'I|ƻIte0pYlVx&(|;5T NPћKJ* E8ћ**zzo@hȝ5Lxm#lcm wR!SdUNQo5}0uR(% (r4C ^VgoU+Yv:ܓ;aMt 1F+I™6vJF$Cw^h\==iL)B]AE):9}`I$ԼvN[ka V4ꎀvPaQA`8dU~ b-r.L*; kElJѱZ>as FOsAm=oqUł7:I+zu~s˞c# ÁTu0:x ;C}|6gn ^bWǥI7cFZZ'7imsN1MZVr㢒()`u!c=^RO'[G[t]II%?v#>Zz2L>߷!>kjPKFbɵgNx1/%[|n_c8XL38~"k}Oamvt,ustSů6W"ӡbH r(Rh'@4rr3C'f0\MJ9'[qRXlcD1}sM.5Eb:huPy0sp*cNJU_#N~6S4[OsI~^{Hnך +V?$<;F*9#$Mض.,`ƻ"d8ثؠTSZAXejudTYe֏r !}Cb&9jیG"D9jT9djkN4y pLm6}q(#P{gaQ9l4^ }>$58J;O@ݖBWw;K2bMAJ-OgʘO( N Ch 1ZNv{H2bmKϫ]ͤGx(XZ&B DŽb:|ZEC$#q?Qx\Zt}b~r:@^; ->-nh:%{̰+i=g)YJ͋5PK" XƲTOLяظ!mX"8MZyw괔[c!jEvBoN#uޝNx%*j\8xW~9vM2mxlƩd,U h^2yIK<3k?f3[[5{?3TR}!}0bDyQz)S#J0Vp6EoSљ%߇*_aVב]ayVQ9ѣ8l R؂jY,65% Z`& WM . Vߧ@ MV=mn.z x]S#\~m@á};ƕ/QDx͎$ SRwm,wZD'`1Ie=\͗8*ݯ)χ)2 d#Y9I;byS#K<>kRӹ7.t;솶`L"6k=H4`YI~`oḐlK1Txe'B}ciO CBNBn\E-=L6 0zQdNa0V YUUMӢ85-꫾xsޝxMRFgqt) BEe6!S74"_B8UBG^ &zNY\5a7#߫\_)Jx(\n&KՍMrMZ~Td?|TXFTQ^z5n.3.%1 qҶ.tg*nRî<@~3 ]~ts妁!c0rWvʅXtM'f SVf>W9 a5oW9SĀ%Vt{b$x.?Kxyʞ)Ɂr1hx9WWRw,؋ m!7?\jt5]pI-Uع--X#:3ĖKdw`O ?}D$8n5`U eJshް(Kuѕ/T7ۇ%9? j/p@$kBPF=re J/{#ے5ZB-ˑ3؇1QX740/X^s^dz+DSwSBq8%y 8ōCۄqI60I:7-9DR6LH78 nr!“,D_s% /4#Lr~?ZIQ~Jx 6VdZTGdZݮ0V$*n6>Ֆw,?"|qߑ~јuy5rgX6<,7KT5MG5?\'.SM ,S&s֔x>`߬ғӼ)c +E|wttFWds0pSl Ys 8Pzyf ]:8}Y5iﴊk2dkP[恉5.aY^cY~TrdCZ~Uf0dz޲Q"L)%d٣8< ΀Ȏx&΂ rFH00%ON?i (w7m-Ućyy$FۀɄ2/of4m:\ >n+|۬tH fn,v'n%| Q<4~^VB U F 5xD>}?iEї3䟔u}+' w4*+cנĠ]C4N|ͪk}oq(X!ҽܭv䳺Q G6[}I==r|?h֬,񙑝9bُիԫ=x}I8: 2<%We;( x؆;2?DP;WB"(s]^=AU|Ӝ̭s@iQS%"I: 2i. tDh^ j[E+Ioa"6LZicāM*{]T@m_LO=[LId7l5Ǔb8Ibd\B?t,6K@uJ ˏ$};Om M Cd n'*$ "[h/ U6hlꖃ n@i}UT7 KM# /JDU3Cۥ]}>/(,ֻFUoǘtyzBId_!)9-'P| 4!+H|9v2QzJ?M|I{de # \h//1cd:T[ `8 e<  n#~[i8Euj`XlPb~{ph|X^Lz裞1\^U_+*%1MI :Kyam\:UѲhLy|#0e`Eb`q ,ccZ FH>"o]W?=OyԆ,E` Ң9͢|iexfGAဥ[EKNaiLgxGz۾(GaG!ޠ-Z]׃'NuL-yg4KӉ,ieeďkKqFdOݰE hTTv9d_ulaݰߑtSRH%O3::} ״n7)P4ikA`@büh72R&P"O=K)f|D/.66CBPW lw~An> }z/}ܼxmYp=CPfB"ML>἖2O[-zT^),ۼK(hEN Hp' _gh- Cy@H[ /&\3.D>+EiS =+0ƘalBF6H6۫Ti4~]|a;kjЭ*2v+G- ex&v`bY%!w+^{C?!!gIV{H!lF (D`ECt[tIW 2GT` JT}ڧݨ^e1Ǟ]CzjIy†& cVβLch<^UL?tWb!QzMT,:]G;bZz^%1Xv Jmzu5hIg&1Y1ּ,SvCb6ߛBs5͠{zMg)TCV軒Z^ęūF7'W'@ĉQ8r${8V ]Owё"_iOق *߉`0saQw}{ˀ,t_BbOdW&^MVAT nͿGUrN՘ Q:˅>;^]PLe@!hF8U"lCF[=6 Xy`˄g=0q.;]P}/Ԯ SC5)د m|7~6fG,w갱XZJ!9kESخ&#E5!S0,pMz)n\[nՕq ?%%{p)^ؘg:'G])&hI_Rt4"ɇ|Rf )$B׌3ʷͿ8h$J%P308يT!RHF^+$~7 ?4V0?tݫw|+S){Pf0x~}ķ8zݑԴ=o:h9$V&ڥ)&EQ:KOi<~5xlh9# :Jوek&vd3CD[i(c3YsԻa~/BTfO* 2axv#E糉a>* ͝*BZ p,$XL?qqmmeTbP2> "۸ B7ᶌSob6H7H]II86S,S0+(*Gmi[HSjgۓּjS_t||6^-n`A§F`T(:=3~ [*L%/@+=D4"-8 (23>>;=fͅHI1&I?' 'iQ& uAv7T/viէ܋~;siE{}sVG;D/+`svcDUu) o#Z࣢L)aI~[m35(ӳ, <)lkS$""(2^mgZ(6aRk \sIߢvV`@n ,CuwFWQv|ne+=#oGZ~=d|;9Đ*-?1c3 \cC݂ņOȚb*NnT5klv1BaF46 ,g)CBxR® V܁v  AO֌p}Ƙ^uJuArXI3"{2r'Iٰ#;Q2EJ%:5uw}Zm.43{s>i_&>32aq .6 ;!Y I3a@h1 jDÐ0JQ4?Z][(nBCM67:K}A'}/%HW/~Bb&"}^FNb.y蓚ݯ_8oh Er?A`u >\D45?ίڣ:bijr]CM׏qbΖ~,ٟ\c#~)2=Ex1Oȱth:+tku٥P#WVP2)7蹊n!.,MqQ;t!k9P.B~?hg|HYǻӥnOv<ij-eLM3X8m|uޓ6]k0G?94- 6I8}#)j䋃󎺊t숂R ˿K8^􍱢QLkA6uwXDzkbBX:#I븛r(C~Gyl)pDI~^|@_'Rc|wRJS#ߙqܷMxZzxBGVvJ([Oӌr+)5췓bspT?.AR/Zg&S n0h =CQ ?ޕMA"],>?UX=65^y{TŪzNPI f8`9)u\>k^BQqJ3AFK1zʑ0Ju$4 EAVaʫefNS_ ݃;Q{BGw fs&נ 6Syj69XR1clMP Ƈ˿媑Hn;P3,MB{gXn/Ud=]&>MxoEGY]oK(5ږhstBT Y;| nتd )0 !Hd<@BqFR;w@"go1Ko! V ۽|mLhМ?:ZZ0 M|=3cʗ)lqu~|˥M+ILs_ .H5/TB-3hȐ}?N- M$0;UʺiC?VR͒R4n#ůY!}~h=/%n.#*8ʹ"I/ynr*k;a$0„)f-'XЏOlwćWd+3):;J0Iu9L(~8$~}x>,[NEY a=fe\,(c<$=HHs- 儙.Bb2-r`/rHظU3Td}_ tݵJ 1̌o#>V?+9#hl7g|SGC@<}vdFk &~'{0 p}R~,|P.A.NfZ9:=,8kzߍP} S饪h)Hq%abTH u]{@j{`;t@o  SMS]8i(mk@Ol^k˗ϥ|\poQtW?B%9y*:Oeg-AMayMӓm-2)( }wxs?.FngyU+FGax^ X#9g/T&1ɖ6DYU\LM`^4Z6ܡčIM_mdBR ~ qDyL8.֚$BO3w$h?KI!-]Żz:hQBa NZmS1~0R[K|ɲz_L+tjK9yӻil?,k T8\"9QT@(0ig_mջk&S,\\S<͟xc q4uFF zHMuNH/?3!vGV&*a`]Vc@/6YyCK{T3oōoGnI!z.L#bמe{ p#O T3CӱT-hʀ܌D:nB{מ#͌fYT97{ӕ2Dh\15 Z[)9-1lOoW(~;`Z}A'F`?Y-_` m4`Eƞk.6WsrQl[ޘxs u"^w7yNf}((ٸ/<[]WDZ[t < 2049uE>k tDjI,gΧh!sKXDmiAls%n&]aR4)io!8W󨢆Z+ӛJO3^Y۶>1wE7lAoY_uSG &.ʖ;,_Lkj.ŧ@i"_wMBFxK5cX7}/^ Lp_䵨_gu\Ep>a[jI)ݻkWze[)J(Y'IMbO)m(O:̥2KM c]0ՅHW}(RgI絯w5i?"x4un(& l-]Kz[j@ͦ/Xn>6{J[lO6)0blrmΙ3wPWY |a5%^M]a8"X#h?!0_uRdJ^VW^Vd%QCIԸ>vd)Zq c1 65"LdVtCQ\& 8oilPV *?jɜ (=Y'όRVNcl.%3*{ Hd-r_ GWՈlBy>" ԫϥqTc+f@[holuf9g%(tVeJE f׷?0KE9_ԖGRbߤ.Y(ҿn M}q"@@崎7p~bѫ%qni]6> O,oXVX|xEaRRiGԸ[Ňђ /yjWw%CSC.;VE l݀ۖ@H/iJBpBO!U.jʚ&sB4Qi:uHa4m74za9$4%5Z6V,Fm/FD"SEC#.a&HnqHBY?՛6/,9'|T sJ^f0xni> =п 6կPE562n֣ 9EӿpC7S{^2W{y:FJ^N}^Xgf4Lc?k&UDO]⮥qFFP1 159B}+fKw g:E\$e"q/!C:gZRbdTݏmccޟ{hMR؜%WWCdmHkl'I2MmؐvXu} zفgWFerS\n}&^8& 6m-k0']j&G`.lR' MH%[.cl|9Z 㡗@¯ufߣ/B:)$&XV0A9^*L]/ `Hf*!?$֦"}mdz+=dG+V: lSįx aZ/̃ Ws潊+ C4!PI7ʣ؅Φ:y4k#L^m|SԆrQ2)*4V/6} 6S|Ȕ֠ Ue=ϮDMrixxBNEev2.LY-%|T%= wzԞieR/ 8ú9qŵHVT3DAc21=d )h:lEx՝:VE;yENrsȲkk}b߱"8(IE O'\Bɔê 0p$'KRDw7PQ!T ̹`Pyك|a%\]&#ۢsG NP\C'hفX-ikQaݰigp!K.%TFH]`-F8c|#"H-CbFt&\Xs1#SkM-x+$Zv?3w݅tvTђHA3X CyvNaTY>(틝#c`ߎO/He2 bq ?("b\'bk>augٶE\r@CCDaX% ?˘WKR<)bq#C4pY'әgE.zt;mȈ V>xs 5z%IDB#Q_`X)/l׮ / H>a.*2 Y rsRGg 2dwڀ_\k! Au ߓV4HCnBچMHmBn6tt*^CQ֍N!qHcoQ_њk(kF8mj:ͦ:-tn h! d4Vn13#|ypc===?K2>9ާ8chH&[U>$c.JUrNGS.|X ڕ(;u8 {٬4BjC_Il b$sΕغTꯗ'7B:7s{M9-P831&mFY]fr/yaţۅc y=YNXPRIkcOsH„3 KlQrUjp5ᔝ,g.$B1XVjܨm!J3| =}$#r.8Wq5i_w("P: d5š%Օ)!v_M Jo#XUeU33hP,GR#pi܅˒x)?R`Uso=r\l):{^qլbC/p SEkq]o½C`OvciǏcKo׭ V_775#.ulPL:& v endstream endobj 8 0 obj << /Type /ObjStm /N 100 /First 849 /Length 4612 /Filter /FlateDecode >> stream x\[s7~篘ڲKUjlǒDu@IcITH*O 9(*'{ D%+)+M%E,=PrZWV^JʇPP}.VLԦm% 045QAVFWAWzBp>]eHT,"(*+-4I;IVNUhCgghjbd2P?OX D*O H@4TՕS+gSBj%{GA MU Eb>PWa4%)'򃨈%2"%~#~"s+OH4 4RڒZYI^)l2UxHOKxAt4 zR$M#|5=>dN1.{i% IF" B;PMRӝ5(>p2 3pM#CsoCgr&   ځkJp  WT:jh$TqGB|ݠ>rTOWj64׃u3LN)-;n8hF'{A Q} "?y]ޕJޜXJ~5YNƧGͬzOL}[Yt-F] k8#aKu+UYUV3:2*@bՊVV*D-+.*d-EVBV3iZxh֨5Vu?W}7]\?7#Wx[%rZ8}_Q~rH">+휧@o wvíD洙T{vtX}OgzV³ϳpF|^RkCHg4heP:<>:ĎP𣛓πyaǣfrxR9)o[ rcsw4Ξ~N|?fOe9kJ2_{$H(FSŘ]il{ZC"+e5{Nb)D9? 퇱y,mGe 2 Y3vb׀@CE%_D\)q8T( lo Fʉ@ I`iAFFO9>/]S?+ ˶LH3L a :v1p62(kvԅ@h#2#0VK_3ytcu*ĤI$HXR0"ш%bpFC@ a0'ЮBBODo'X[ (V5NӼԭg"0ٺ֓&H8Îӟ@i ?ۦs%QTz^.-,۵v9\\rJρ;-9˲(ur.jƼޡ&/9K'Pfm2 ca<S3 k~*sd1ohö#Q4)s[* Iii %*>27~Bu5tZU*FcU 0KB9>@hB "$٤!ѐ W-}Np=`ȶ-F cU"̢V*Ui v,Yrf-U^p%8'gIxT]I A6gOa.`yySs򶅢Z,[%ީ8Ӧ?x(c'(9~'_XJqRJZ"W H;!|όl:G6]~ ,%bfN@' s[:=>aAf5Iej鹱fы% :qbw>\hE=lXC~ͽeGK`X:t|id̚_ 7n!rmqi %TQS!vGpfxQ?~/ןzT/z\zVԿտן/d f"7yc7tztIt|ثi}ޭ_?~] }HI_ r7Vz2Mk QjE:NFK\ͮۻ &-Fb,p6_em*ѷ2?}@4Y3/麾n&YǍ(ȃYpVnÈEػ0}w,_oDb$ ss IlmFP$>/5R[[^p$!P|[Z8)`iAf/W9p{su6~* a,o&kՈRf s-EfJ0x֜\p& TO߈t`}i4OmGO%?mR_Ox^?!T0Rtb\,eUz#p~秇Geuh(4 = T(#>"džZ_~#>~;Ho{0]Z|-!w2_$Ѳ(C;6I<'~Q200<ܙE<qt-V8[ß.V/8H{2>Mjor֗7rA~zbK 8]U!lMV`qI4;xю3E;b@Y firD<$Hz!&eUlL{܃*{YNEW(_H.6y6Ip r\MB8HyGL2>H "^ 7Z> endobj 147 0 obj << /Type /ObjStm /N 7 /First 49 /Length 262 /Filter /FlateDecode >> stream xڝOk!~Bȡп4 =l#B5~SB@N77 J ,@RAPPPB$[,_r_ ݯ.8`*8 /O>ŔGPǠ?OKez_~n>C9yf$xbIN$RU^ρ+iAHQVoϦ4!!%N?5'c/-?c2"3K7 endstream endobj 151 0 obj << /Type /XRef /Index [0 152] /Size 152 /W [1 3 1] /Root 149 0 R /Info 150 0 R /ID [<940A6D6BF4A3347CD1A366C62570068C> <940A6D6BF4A3347CD1A366C62570068C>] /Length 428 /Filter /FlateDecode >> stream x%=LQ U(P,ZDAG)R~OZIdąź0d\L qaD7DayrN߷wS3=g1yJ2dyBZ~Br1ɒ 򌌓irxX$BRW=LBzG5I)k89QRXozS l5 i9(V2RNbI'9Mo+Z9CY Ϫ9RCjI|Q\vuy]E~K L.`zcWI+\j[W3 where the input graph is in the following format: n # of nodes. m # of edges. i1 j1 first edge. i2 j2 ... im jm last edge. */ #include #include #include #include "declarations.h" int main(argc,argv) int argc; char *argv[]; { int i; int j; int n; int m; FILE *fid; int start,finish; int temp; /* * Storage for the problem. */ struct blockmatrix C; struct blockmatrix X,Z; double *y; double *a; struct constraintmatrix *constraints; /* * Check for an argument. */ if ((argc < 3) || (argc >3)) { printf("Usage: \n"); printf("\n"); printf("graphtoprob \n"); exit(1); }; /* * Open up the file and read n and m. Check the problem size. */ fid=fopen(argv[1],"r"); fscanf(fid,"%d",&n); fscanf(fid,"%d",&m); printf("Graph is of size %d %d \n",n,m); /* * Setup the objective function and the constraints. */ C.nblocks=1; C.blocks=malloc(2*sizeof(struct blockrec)); if (C.blocks == NULL) { printf("Couldn't allocate storage for C!\n"); exit(1); }; C.blocks[1].blockcategory=MATRIX; C.blocks[1].blocksize=n; C.blocks[1].data.mat=malloc(n*n*sizeof(double)); if (C.blocks[1].data.mat == NULL) { printf("Couldn't allocate storage for C!\n"); exit(1); }; for (i=1; i<=n; i++) for (j=1; j<=n; j++) C.blocks[1].data.mat[ijtok(i,j,n)]=1.0; /* * Just to keep free_prob happy. */ alloc_mat(C,&X); alloc_mat(C,&Z); y=(double *)malloc(2*sizeof(double)); /* * There are m+1 constraints. */ constraints=(struct constraintmatrix *)malloc( (m+2)*sizeof(struct constraintmatrix)); if (constraints==NULL) { printf("Failed to allocate storage for constraints!\n"); exit(1); }; a=(double *)malloc((m+2)*sizeof(double)); if (a==NULL) { printf("Failed to allocate storage for a!\n"); exit(1); }; /* * Constraint 1 says that Trace(X)=1. */ a[1]=1.0; constraints[1].blocks=(struct sparseblock *)malloc(sizeof(struct sparseblock)); constraints[1].blocks->blocknum=1; constraints[1].blocks->numentries=n; constraints[1].blocks->blocksize=n; constraints[1].blocks->constraintnum=1; constraints[1].blocks->next=NULL; constraints[1].blocks->nextbyblock=NULL; constraints[1].blocks->entries=(double *) malloc((n+1)*sizeof(double)); constraints[1].blocks->iindices=(int *) malloc((n+1)*sizeof(int)); constraints[1].blocks->jindices=(int *) malloc((n+1)*sizeof(int)); for (i=1; i<=n; i++) { constraints[1].blocks->entries[i]=1.0; constraints[1].blocks->iindices[i]=i; constraints[1].blocks->jindices[i]=i; }; /* * Constraints 2 through m+1 enforce X(i,j)=0 when (i,j) is an edge. */ for (i=2; i<=m+1; i++) { a[i]=0.0; fscanf(fid,"%d %d",&start,&finish); if (start > finish) { temp=start; start=finish; finish=temp; }; constraints[i].blocks=(struct sparseblock *) malloc(sizeof(struct sparseblock)); constraints[i].blocks->blocknum=1; constraints[i].blocks->numentries=1; constraints[i].blocks->blocksize=n; constraints[i].blocks->constraintnum=i; constraints[i].blocks->next=NULL; constraints[i].blocks->nextbyblock=NULL; constraints[i].blocks->entries=(double *) malloc((2)*sizeof(double)); constraints[i].blocks->iindices=(int *) malloc((2)*sizeof(int)); constraints[i].blocks->jindices=(int *) malloc((2)*sizeof(int)); constraints[i].blocks->entries[1]=1.0; constraints[i].blocks->iindices[1]=start; constraints[i].blocks->jindices[1]=finish; }; /* * Close the input file. */ fclose(fid); /* * Write out the problem. */ write_prob(argv[2],n,m+1,C,a,constraints); free_prob(n,m+1,C,a,constraints,X,y,Z); exit(0); } Csdp-6.2.0/theta/Makefile0000644000175200017520000000133213133246222013620 0ustar coincoin# # Target all builds everything. # all: theta complement rand_graph graphtoprob # # This builds the theta number code. # theta: theta.o $(CC) $(CFLAGS) theta.o $(LIBS) -o theta # # Complement computes the complement of a graph. # complement: complement.o $(CC) $(CFLAGS) complement.o $(LIBS) -o complement # # rand_graph generates a random graph. # rand_graph: rand_graph.o $(CC) $(CFLAGS) rand_graph.o $(LIBS) -o rand_graph # # graphtoprob converts a file in the graph format to an SDP problem in our # SDP format. # graphtoprob: graphtoprob.o $(CC) $(CFLAGS) graphtoprob.o $(LIBS) -o graphtoprob # # To clean up the directory. # clean: rm -f *.o rm -f theta rm -f complement rm -f rand_graph rm -f graphtoprob Csdp-6.2.0/theta/README0000644000175200017520000000256610455242355013061 0ustar coincoinThis directory contains C code for an SDP code to compute the Lovasz Theta number of a graph. This is mainly to demonstrate the use of the CSDP callable library. Usage is theta where is the name of a file containing the graph in the following format: # of nodes # of edges the edges, one per line, described by the two vertices For example, the complete graph on four nodes looks like this: 4 6 1 2 1 3 1 4 2 3 2 4 3 4 A program for converting a graph into an SDP in sparse SDPA format is also provided. Usage is: graphtoprob I've also provided a program for generating random graphs. Usage is rand_graph

[] where is the output file, is the number of nodes in the graph,

is the probability that each edge will be present, and is an optional integer seed for the random number generator. I've provided a third program for computing the complement of a graph. Usage is complement Please note that there are two commonly used conventions for Theta(G) and Theta(complement(G)) In this code, theta(complement(G)) is an upper bound on the max-clique of G, not theta(G). You may also want to adjust the LIBS= and CFLAGS= lines in the Makefile to get code optimized for your particular system. Csdp-6.2.0/theta/complement.c0000644000175200017520000000326113132502512014466 0ustar coincoin/* Compute the complement of a graph and output it in our standard format. Usage: complement */ #include #include #include "declarations.h" int main(argc,argv) int argc; char *argv[]; { FILE *fidin; FILE *fidout; int i; int j; int n; int m; int start; int finish; int *G; int ret; /* * Check for the right number of arguments. */ if ((argc < 3) || (argc >4)) { printf("Usage: complement \n"); exit(1); } /* * Open the input and output files. */ fidin=fopen(*++argv,"r"); fidout=fopen(*++argv,"w"); /* * Get the size parameters. */ ret=fscanf(fidin,"%d",&n); ret=fscanf(fidin,"%d",&m); /* * Allocate the array. */ G=(int *)malloc(n*n*sizeof(int)); /* * Now, work the G array including every edge in the graph. */ for (j=1; j<=n; j++) for (i=1; i<=n; i++) if (i == j) G[ijtok(i,j,n)]=0; else G[ijtok(i,j,n)]=1; /* * Read in the edges, and zero them out in G. */ for (i=1; i<=m; i++) { ret=fscanf(fidin,"%d %d",&start,&finish); if (ret != 2) { printf("error in input file.\n"); exit(1); }; G[ijtok(start,finish,n)]=0; G[ijtok(finish,start,n)]=0; }; /* * Print out the resulting graph. */ fprintf(fidout,"%d \n",n); fprintf(fidout,"%d \n",n*(n-1)/2-m); for (i=1; i<=n-1; i++) for (j=i+1; j<=n; j++) if (G[ijtok(i,j,n)] == 1) fprintf(fidout,"%d %d \n",i,j); /* * Close files and free memory. */ fclose(fidin); fclose(fidout); free(G); exit(0); } Csdp-6.2.0/theta/rand_graph.c0000644000175200017520000000426510455242355014450 0ustar coincoin/* Compute the complement of a graph and output it in our standard format. Usage: complement */ #include #include #include #include "declarations.h" /* On some systems, RAND_MAX is undefined. If so, use RAND_MAX=32768 */ #ifndef RAND_MAX #define RAND_MAX 32768 #endif int main(argc,argv) int argc; char *argv[]; { FILE *fidout; int i; int j; int n; int m; int s; double p; int *G; /* * Get the parameters and open up the output file. */ if (argc <= 3) { printf("Usage: rand_graph

[] \n"); exit(1); }; if (argc >= 4) { fidout=fopen(*++argv,"w"); n=atoi(*++argv); p=atof(*++argv); }; /* * Get the random number seed if specified. */ if (argc >= 5) { s=atoi(*++argv); srand((unsigned int)s); }; /* * Allocate storage for the graph. */ G=(int *)malloc(n*n*sizeof(int)); /* * Now, generate the graph. */ /* * The following kludge is here to deal with a bug that we've * encountered in stdlib.h under Solaris 2.5. The problem is that * stdlib.h defines RAND_MAX as 2^15-1, while rand() actually returns * numbers between 0 and 2^31-1. This is a violation of the ANSI * standard, but we can get around it by first taking rand() mod * RAND_MAX and then dividing by RAND_MAX. The same code should * work fine if RAND_MAX is correctly defined. * * Note too that on some systems (for example, SunOS 4.1.X, RAND_MAX * isn't defined in stdlib.h. In such cases, we'll have to define the * symbol with -DRAND_MAX= in the Makefile. * */ m=0; for (i=1; i<=n-1; i++) for (j=i+1; j<=n; j++) if ((1.0*(rand() % RAND_MAX)/RAND_MAX) <= p) { G[ijtok(i,j,n)]=1; m++; } else { G[ijtok(i,j,n)]=0; }; /* * And print the graph out. */ fprintf(fidout,"%d \n",n); fprintf(fidout,"%d \n",m); for (i=1; i<=n-1; i++) for (j=i+1; j<=n; j++) if (G[ijtok(i,j,n)] == 1) fprintf(fidout,"%d %d \n",i,j); /* * Close files and free memory. */ fclose(fidout); free(G); exit(0); } Csdp-6.2.0/theta/theta.c0000644000175200017520000001025713126006077013443 0ustar coincoin/* Compute the Lovasz Theta number of a graph. Usage is theta where the input graph is in the following format: n # of nodes. m # of edges. i1 j1 first edge. i2 j2 ... im jm last edge. */ #include #include #include #include "declarations.h" int main(argc,argv) int argc; char *argv[]; { int i; int j; int n; int m; FILE *fid; int ret; int start,finish; int temp; /* * Storage for the problem. */ struct blockmatrix C; struct blockmatrix X,Z; double *y; double pobj,dobj; double *a; struct constraintmatrix *constraints; /* * Check for an argument. */ if ((argc < 2) || (argc >2)) { printf("Usage: \n"); printf("\n"); printf("theta \n"); exit(1); }; /* * Open up the file and read n and m. Check the problem size. */ fid=fopen(*++argv,"r"); fscanf(fid,"%d",&n); fscanf(fid,"%d",&m); printf("Graph is of size %d %d \n",n,m); /* * Setup the objective function and the constraints. */ C.nblocks=1; C.blocks=malloc(2*sizeof(struct blockrec)); if (C.blocks == NULL) { printf("Couldn't allocate storage for C!\n"); exit(1); }; C.blocks[1].blockcategory=MATRIX; C.blocks[1].blocksize=n; C.blocks[1].data.mat=malloc(n*n*sizeof(double)); if (C.blocks[1].data.mat == NULL) { printf("Couldn't allocate storage for C!\n"); exit(1); }; for (i=1; i<=n; i++) for (j=1; j<=n; j++) C.blocks[1].data.mat[ijtok(i,j,n)]=1.0; /* * There are m+1 constraints. */ constraints=(struct constraintmatrix *)malloc( (m+2)*sizeof(struct constraintmatrix)); if (constraints==NULL) { printf("Failed to allocate storage for constraints!\n"); exit(1); }; a=(double *)malloc((m+2)*sizeof(double)); if (a==NULL) { printf("Failed to allocate storage for a!\n"); exit(1); }; /* * Constraint 1 says that Trace(X)=1. */ a[1]=1.0; constraints[1].blocks=(struct sparseblock *)malloc(sizeof(struct sparseblock)); constraints[1].blocks->blocknum=1; constraints[1].blocks->numentries=n; constraints[1].blocks->blocksize=n; constraints[1].blocks->constraintnum=1; constraints[1].blocks->next=NULL; constraints[1].blocks->nextbyblock=NULL; constraints[1].blocks->entries=(double *) malloc((n+1)*sizeof(double)); constraints[1].blocks->iindices=(int *) malloc((n+1)*sizeof(int)); constraints[1].blocks->jindices=(int *) malloc((n+1)*sizeof(int)); for (i=1; i<=n; i++) { constraints[1].blocks->entries[i]=1.0; constraints[1].blocks->iindices[i]=i; constraints[1].blocks->jindices[i]=i; }; /* * Constraints 2 through m+1 enforce X(i,j)=0 when (i,j) is an edge. */ for (i=2; i<=m+1; i++) { a[i]=0.0; fscanf(fid,"%d %d",&start,&finish); if (start > finish) { temp=start; start=finish; finish=temp; }; constraints[i].blocks=(struct sparseblock *) malloc(sizeof(struct sparseblock)); constraints[i].blocks->blocknum=1; constraints[i].blocks->numentries=1; constraints[i].blocks->blocksize=n; constraints[i].blocks->constraintnum=i; constraints[i].blocks->next=NULL; constraints[i].blocks->nextbyblock=NULL; constraints[i].blocks->entries=(double *) malloc((2)*sizeof(double)); constraints[i].blocks->iindices=(int *) malloc((2)*sizeof(int)); constraints[i].blocks->jindices=(int *) malloc((2)*sizeof(int)); constraints[i].blocks->entries[1]=1.0; constraints[i].blocks->iindices[1]=start; constraints[i].blocks->jindices[1]=finish; }; /* * Close the file. */ fclose(fid); /* * Create an initial solution. */ initsoln(n,m+1,C,a,constraints,&X,&y,&Z); /* * Use easy_sdp() to solve the problem. */ ret=easy_sdp(n,m+1,C,a,constraints,0.0,&X,&y,&Z,&pobj,&dobj); if (ret == 0) printf("The Lovasz Theta Number is %.7e \n",(dobj+pobj)/2); else printf("SDP failed.\n"); free_prob(n,m+1,C,a,constraints,X,y,Z); exit(0); } Csdp-6.2.0/INSTALL0000644000175200017520000002166513133267356012132 0ustar coincoinREQUIREMENTS: The build process for CSDP uses make, so your system must have make installed. The GNU make works quite well, but CSDP has also been built with other versions of make. The make files are very simple. In order to build CSDP, you will need an ANSI C compiler. The GNU C compiler gcc works quite well, but the code has also been compiled with Intel's icc, IBM's xlc, Sun's cc, and many other compilers. Although CSDP itself is written in C, the BLAS/LAPACK libraries used by CSDP were originally written in Fortran. Combining C and Fortran is generally straight forward, but you may have to install a Fortran compiler in order to get run time libraries needed by the Fortran code in BLAS/LAPACK. In particular, on Linux systems using gcc and gfortran you will link CSDP with the -lgfortran library. Use of the CSDP library and the solver and theta functions requires the BLAS library and a few routines from the LAPACK library. Using BLAS and LAPACK routines that have been optimized for your computer is critical to getting good performance from CSDP, since the code typically spends nearly all of its time in these routines. On the same hardware, it's not uncommon to find that optimized BLAS and LAPACK routines are an order of magnitude faster than unoptimized BLAS and LAPACK routines. The original authors of BLAS and LAPACK have provided "reference implementations" that are freely available but not very well optimized. If your system has BLAS and LAPACK libraries in /usr/lib, there's a good chance that these are the reference implementations. Using them is an easy way to start, but you may well find that you need faster routines to get acceptable performance. Most hardware manufacturers have developed optimized BLAS/LAPACK libraries for their systems, such as Apple's veclib for G5 systems, Intel's Math Kernel Library (MKL), AMD's Core Mathematical Library (ACML), IBM's extended scientific subroutine library (ESSL), and Sun's sunperf library. These typically have restrictive licenses and may be expensive to purchase, but can provide very good performance. An open source library that I recommend for use with CSDP is OpenBLAS. See http://www.openblas.net/ You will generally need to compile OpenBLAS from source rather than installing a binary version that is not optimized for your system. CSDP also includes a set of routines for interfacing CSDP to MATLAB and Octave. This interface is entirely optional- CSDP works fine without it. In order to use this interface, you will need MATLAB (6.5 or later) or Octave (2.9.5 or later.) The README file in the matlab directory contains instructions for installing the matlab interface and testing it on a sample problem. DOWNLOADING CSDP: The most current version of CSDP can be obtained using subversion from the COIN-OR web site. To do this, first install the subversion tools, then issue the command svn co https://projects.coin-or.org/svn/Csdp/trunk Or use a GUI to access the repository. Alternatively, you can download a .tar or .zip archive of the source code for the most recent stable release of CSDP from the project web site. INSTALLING CSDP: The following instructions assume that you're using a Linux system with gcc, gfortran, LAPACK, and BLAS installed. The make files will have to be altered for other systems, but the basic process of building the software will be similar. After you've downloaded the source code, unpack the tar archive if you downloaded a .tar archive of CSDP, and then go into the csdp directory. You will find subdirectories, lib, solver, theta, example, and doc. These contain the CSDP library, the command line solver, an example program that computes the Lovasz theta number of a graph, and a small example program showing how to call CSDP. There are Makefiles within these subdirectories. There are two lines in the top level Makefile that will likely need to be edited: 1. CFLAGS. The CFLAGS variable specifies command line arguments to the C compiler. The default value of CFLAGS is appropriate for 64 bit Linux systems using the gcc compiler. It is: CFLAGS=-m64 -march=native -mtune=native -Ofast, -fopenmp -ansi -Wall -DBIT64 -DUSEOPENMP -DSETNUMTHREADS -DUSESIGTERM -DUSEGETTIME -I../include The flags -m64 through -fopenmp tell gcc to produce optimized 64 bit multithreaded code using the OpenMP features. The flags -ansi and -Wall tell gcc to produce warnings for any code that vioates the ANSI C standard. The -D... flags specify options within the code as described below. The -I../include flag specifies the location of CSDP's .h files. The -D flags that are recommended for CSDP on 64 bit Linux are -DBIT64 Used on 64 bit systems -DUSEOPENMP Used to build a parallel threaded version of CSDP -DSETNUMTHREADS Use OpenMP to set the number of threads to use. -DUSESIGTERM Terminate CSDP nicely after SIGTERM or other signals -DUSEGETTIME Use ANSI C gettime() to get wall clock running time. For Windows 64 bit systems using the mingw64 compiler, recommended CFLAGS are: CFLAGS=-m64 -march=native -mtune=native -Ofast, -fopenmp -ansi -Wall -DBIT64 -DUSEOPENMP -DSETNUMTHREADS -DUSEGETTIME -I../include The only difference here is that -DUSESIGTERM is left out because Windows doesn't support Linux/unix signals. There are some flags that may rarely be useful on other systems: -DCAPSBLAS if BLAS routine names are capitalized -DCAPSLAPACK if LAPACK routine names are capitalized -DNOUNDERBLAS if BLAS routine names have no underscore -DNOUNDERLAPACK if LAPACK routine names have no underscore -DHIDDENSTRLEN if Fortran string lengths are hidden arguments 2. LIBS. The LIBS= line of the Makefile specifies the location of the CSDP library and the BLAS and LAPACK libraries. The distributed version of the Makefile has values suitable for a 64 bit Linux system with BLAS and LAPACK installed in the system library directories: LIBS=-static -L../lib -lsdp -llapack -lblas -lm -static produce a statically linked executable -L../lib -lsdp libsdp.a is in the lib subdirectory -llapack -lblas LAPACK and BLAS libraries -lm C standard math library In many cases it will be necessary to add the Fortran run time library: -lgfortran The LIBS variable will also have to be edited if your LAPACK and BLAS libraries are not in the standard location or have different names. For example, on my system, the OpenBLAS library is located in /opt/OpenBLAS/lib/libopenblas.a. This OpenBLAS library contains both LAPACK and BLAS routines, so I don't need to specify a spearate LAPACK library. Thus I use the flags: LIBS=-static -L../lib -L/opt/OpenBLAS/lib -lopenblas -lm Once you've set the LIBS and CFLAGS variables in the top level Makefile, issue the command > make to build CSDP. Make will go into the lib, solver, theta, and example subdirectories and compile the C code. If the build fails, it is important to start by identifying where the build failed. Failures in building the CSDP library are extremely rare. Most reported failures have occured in the solver and theta directories. The most common problem in practice is that one or more of the required libraries (blas or lapack) is missing. In that case you must install the required library before continuing with the installation of CSDP. If the build fails for some other reason, feel free to contact the author for help- we're interested in learning about problems on different systems. If for some reason the build fails, it's a good idea to remove all of the binaries before modifying the make files and rebuilding. To do this, issue the command > make clean Once the build appears to be successful, you can test the code with > make unitTest This will run tests of the stand alone solver csdp and Lovasz theta program theta. Compare the .out files produced by the tests with the corresponding .correct files. The actual values will typically vary because of small differences in floating point round-off, compiler optimizations, and so on. However, the optimal objective values should match to at least six digits, the relative primal and dual infeasibilities should be smaller than 1.0e-7, and all DIMACS errors should be smaller than 5.0e-7. If either of the tests fail, please contact the author. Once you're satisfied with tests, you can become root and issue the command > make install This will copy csdp, rand_graph, complement, theta, and graphtoprob into the /usr/local/bin directory. If you use the C shell, remember to "rehash" so that the shell will know that these programs have been added to the /usr/local/bin directory. The matlab directory contains .m files that provide a matlab interface to CSDP solver. To install these .m files they must be added to your matlab path. This requires use of the path(...) command in matlab. See '>help path' for instructions on adding a new directory to your matlab path (you can put the .m files in any directory you wish, then add that directory to your matlab path). Csdp-6.2.0/lib/0000755000175200017520000000000013136043252011623 5ustar coincoinCsdp-6.2.0/lib/trace_prod.c0000644000175200017520000000174613132530655014125 0ustar coincoin/* Compute the trace of the product of two matrices. Since we only need the trace, it makes more sense to just compute the diagonal of the product and sum the entries.. */ #include #include #include "declarations.h" double trace_prod(A,B) struct blockmatrix A; struct blockmatrix B; { int blk; double sum; int i; int j; sum=0.0; for (blk=1; blk<=A.nblocks; blk++) { switch (A.blocks[blk].blockcategory) { case DIAG: for (i=1; i<=A.blocks[blk].blocksize; i++) sum += A.blocks[blk].data.vec[i]*B.blocks[blk].data.vec[i]; break; case MATRIX: for (j=1; j<=A.blocks[blk].blocksize; j++) for (i=1; i<=A.blocks[blk].blocksize; i++) sum += A.blocks[blk].data.mat[ijtok(i,j,A.blocks[blk].blocksize)] *B.blocks[blk].data.mat[ijtok(j,i,A.blocks[blk].blocksize)]; break; case PACKEDMATRIX: default: printf("trace_prod illegal block type \n"); exit(206); }; }; return(sum); } Csdp-6.2.0/lib/makefill.c0000644000175200017520000001243213132530655013561 0ustar coincoin/* * This routine creates the fill data structure, which includes information * on all elements of X which are touched by elements of the various * constraint matrices in computing A(X). This is helpful in speeding * up the op_o operation. * * */ #include #include #include #include "declarations.h" void makefill(k,C,constraints,pfill,work1,printlevel) int k; struct blockmatrix C; struct constraintmatrix *constraints; struct constraintmatrix *pfill; struct blockmatrix work1; int printlevel; { int i,j,p,q,blk,blksize; struct sparseblock *ptr; /* * Now, zero out the work matrix. */ zero_mat(work1); /* * Put 1's in all diagonal positions, plus nonzero elements of C. */ for (blk=1; blk<=C.nblocks; blk++) { switch(C.blocks[blk].blockcategory) { case DIAG: for (i=1; i<=C.blocks[blk].blocksize; i++) work1.blocks[blk].data.vec[i]=1.0; break; case MATRIX: for (i=1; i<=C.blocks[blk].blocksize; i++) for (j=1; j<=C.blocks[blk].blocksize; j++) { if ((C.blocks[blk].data.mat[ijtok(i,j,C.blocks[blk].blocksize)] != 0.0) || (i == j)) work1.blocks[blk].data.mat[ijtok(i,j,C.blocks[blk].blocksize)]=1.0; }; break; case PACKEDMATRIX: default: printf("makefill illegal block type \n"); exit(206); }; }; /* * Now, work through the constraints. */ for (i=1; i<=k; i++) { ptr=constraints[i].blocks; while (ptr != NULL) { blk=ptr->blocknum; switch(C.blocks[blk].blockcategory) { case DIAG: break; case MATRIX: for (j=1; j<=ptr->numentries; j++) { p=ptr->iindices[j]; q=ptr->jindices[j]; work1.blocks[blk].data.mat[ijtok(p,q,C.blocks[blk].blocksize)]=1.0; work1.blocks[blk].data.mat[ijtok(q,p,C.blocks[blk].blocksize)]=1.0; }; break; case PACKEDMATRIX: default: printf("addscaledmat illegal block type \n"); exit(206); }; ptr=ptr->next; }; }; /* * At this point, we have 1's in all fill positions in work1. */ /* * Allocate space for each block. */ ptr=(struct sparseblock *)malloc(sizeof(struct sparseblock)); if (ptr == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; pfill->blocks=ptr; ptr->next=NULL; ptr->blocknum=1; ptr->numentries=0; ptr->blocksize=C.blocks[1].blocksize; for (i=2; i<=C.nblocks; i++) { ptr->next=(struct sparseblock *)malloc(sizeof(struct sparseblock)); if (ptr->next == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; ptr=ptr->next; ptr->blocknum=i; ptr->numentries=0; ptr->blocksize=C.blocks[i].blocksize; }; ptr->next=(struct sparseblock *)NULL; /* * Go through each block of work1, filling out pfill as we go. */ ptr=pfill->blocks; while (ptr != NULL) { blk=ptr->blocknum; switch(C.blocks[blk].blockcategory) { case DIAG: ptr->numentries=ptr->blocksize; ptr->entries=(double *) malloc((ptr->blocksize+1)*sizeof(double)); if (ptr->entries == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; ptr->iindices=(int *) malloc((ptr->blocksize+1)*sizeof(int)); if (ptr->iindices == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; ptr->jindices=(int *) malloc((ptr->blocksize+1)*sizeof(int)); if (ptr->jindices == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; for (j=1; j<=ptr->numentries; j++) { ptr->entries[j]=1.0; ptr->iindices[j]=j; ptr->jindices[j]=j; }; break; /* * This is a matrix block. */ case MATRIX: blksize=C.blocks[blk].blocksize; ptr->numentries=0; for (i=1; i<= blksize; i++) for (j=1; j<=blksize; j++) { if (work1.blocks[blk].data.mat[ijtok(i,j,blksize)] == 1.0) { ptr->numentries=ptr->numentries+1; }; }; ptr->entries=(double *)malloc((ptr->numentries+1)*sizeof(double)); if (ptr == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; ptr->iindices=(int *) malloc((ptr->numentries+1)*sizeof(int)); if (ptr->iindices == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; ptr->jindices=(int *) malloc((ptr->numentries+1)*sizeof(int)); if (ptr->jindices == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; ptr->numentries=0; for (i=1; i<= blksize; i++) for (j=1; j<=blksize; j++) { if (work1.blocks[blk].data.mat[ijtok(i,j,blksize)] == 1.0) { ptr->numentries=ptr->numentries+1; ptr->entries[ptr->numentries]=1.0; ptr->iindices[ptr->numentries]=i; ptr->jindices[ptr->numentries]=j; }; }; break; case PACKEDMATRIX: default: printf("makefill illegal block type \n"); exit(206); }; ptr=ptr->next; }; /* * Print out information about fill. */ ptr=pfill->blocks; while (ptr != NULL) { blk=ptr->blocknum; if (printlevel >= 3) printf("Block %d, Size %d, Fill %d, %.2f \n",blk,C.blocks[blk].blocksize,ptr->numentries,100.0*ptr->numentries/(C.blocks[blk].blocksize*C.blocks[blk].blocksize*1.0)); ptr=ptr->next; }; } Csdp-6.2.0/lib/make_i.c0000644000175200017520000000151113132530655013216 0ustar coincoin/* Make an identity matrix. */ #include #include #include "declarations.h" void make_i(A) struct blockmatrix A; { int blk,i,j; double *p; for (blk=1; blk<=A.nblocks; blk++) { switch (A.blocks[blk].blockcategory) { case DIAG: p=A.blocks[blk].data.vec; for (i=1; i<=A.blocks[blk].blocksize; i++) p[i]=1.0; break; case MATRIX: p=A.blocks[blk].data.mat; #pragma omp parallel for schedule(dynamic,64) default(none) private(i,j) shared(blk,p,A) for (j=1; j<=A.blocks[blk].blocksize; j++) for (i=1; i<=A.blocks[blk].blocksize; i++) p[ijtok(i,j,A.blocks[blk].blocksize)]=0.0; for (i=1; i<=A.blocks[blk].blocksize; i++) p[ijtok(i,i,A.blocks[blk].blocksize)]=1.0; break; default: printf("make_i illegal block type\n"); exit(206); }; } } Csdp-6.2.0/lib/sdp.c0000644000175200017520000014607413132530655012575 0ustar coincoin/* Solve a semidefinite programming problem using the algorithm of Helmberg, Rendl, Vanderbei, and Wolkowicz. Note: This version of the code uses predictor correct steps. Usage: Return codes: 0 Success. Problem solved to optimality. 1 Success. The problem is primal infeasibile, and we have a certificate. 2 Success. The problem is dual infeasible, and we have a certificate. 3. Partial Success. Didn't reach full accuracy. 4 Failure: Maximum iterations reached. 5 Failure: Stuck at edge of primal feasibility. 6 Failure: Stuck at edge of dual feasibility. 7 Failure: Lack of progress 8 Failure: X, Z, or O was singular. 9 Failure: Detected NaN or Inf values. 10 Failure: Stopped by QUIT, KILL, TERM, SIGXCPU signal Notes on data storage: All "2-d" arrays are stored in Fortran style, column major order. macros in index.h are used to handle indexing into C 1-d vectors. All "1-d" arrays are stored in C vectors, with the first element of the vector (index 0) unused. We always start indexing in both one and two dimensional arrays with 1, ala Fortran. This makes the C code somewhat clearer, but requires us to pass v+1 into a Fortran subroutine instead of just passing v. */ #include #include #include #include "declarations.h" #ifdef USEGETTIME /* * Stuff for keeping track of time. */ #include /* definition of NULL */ #include /* definition of timeval struct and protyping of gettime ofday */ double opotime=0.0; double factortime=0.0; double totaltime=0.0; double othertime=0.0; double othertime1=0.0; double othertime2=0.0; double othertime3=0.0; struct timeval tp; double t1=0.0; double t2=0.0; double starttime=0.0; double endtime=0.0; #endif int sdp(n,k,C,a,constant_offset,constraints,byblocks,fill,X,y,Z,cholxinv, cholzinv,pobj,dobj,work1,work2,work3,workvec1,workvec2,workvec3, workvec4,workvec5,workvec6,workvec7,workvec8,diagO,bestx,besty,bestz, Zi,O,rhs,dZ,dX,dy,dy1,Fp,printlevel,parameters) int n; int k; struct blockmatrix C; double *a; double constant_offset; struct constraintmatrix *constraints; struct sparseblock **byblocks; struct constraintmatrix fill; struct blockmatrix X; double *y; struct blockmatrix Z; struct blockmatrix cholxinv; struct blockmatrix cholzinv; double *pobj; double *dobj; struct blockmatrix work1; struct blockmatrix work2; struct blockmatrix work3; double *workvec1; double *workvec2; double *workvec3; double *workvec4; double *workvec5; double *workvec6; double *workvec7; double *workvec8; double *diagO; struct blockmatrix bestx; double *besty; struct blockmatrix bestz; struct blockmatrix Zi; double *O; double *rhs; struct blockmatrix dZ; struct blockmatrix dX; double *dy; double *dy1; double *Fp; int printlevel; struct paramstruc parameters; { double gap; double relgap; double mu=1.0e30; double muplus; double muk; double gamma; double alphap,alphap1; double alphad,alphad1; double scale1; double scale2; double nrmx; double relpinfeas=1.0e10; double reldinfeas=1.0e10; double newrelpinfeas; double newreldinfeas; double limrelpinfeas; double bestrelpinfeas; double limreldinfeas; double bestreldinfeas; int iter=0; int m; int ret; int i; int j; int info; int ldam; int retries=0; int retcode=0; double bestmeas; double diagnrm; double diagfact=0.0; double diagadd; double ent; /* * Stuff for instrumentation of iterative refinement. */ double relerr1; double relerr2=0.0; int refinements; double besterr; double relerr; /* * Stuff for iterative refinements. */ int lastimproverefinement; double mindiag; /* * */ int ispfeasprob; int isdfeasprob; double normC; double norma; /* * Amount by which to perturb */ double perturbfac; /* * Sticky flags for primal and dual feasibility. */ int probpfeas=0; int probdfeas=0; /* * * */ double pinfeasmeas; double dinfeasmeas; /* * Stuff for adjusting the step fraction. */ double mystepfrac; double minalpha; /* * */ double newalphap; /* * Stuff for keeping track of best solutions. */ #define BASIZE 100 double bestarray[BASIZE+1]; /* * Used in checking whether the primal-dual affine step gives us a new * best solution. */ double affgap,affpobj,affdobj,affrelgap,affrelpinfeas,affreldinfeas; /* * Indicate the version of CSDP. */ if (printlevel >= 1) printf("CSDP 6.2.0\n"); /* * Precompute norms of a and C, so that we don't keep doing this * again and again. * */ norma=norm2(k,a+1); normC=Fnorm(C); if (parameters.perturbobj>0) /* perturbfac=parameters.perturbobj*1.0e-6*normC/sqrt(1.0*n); */ perturbfac=1.0e-6*normC/sqrt(1.0*n); else perturbfac=0.0; /* * Determine whether or not this is a feasibility problem. * */ if (normC==0.0) { if (printlevel >= 1) printf("This is a pure primal feasibility problem.\n"); ispfeasprob=1; } else ispfeasprob=0; if (norma==0.0) { if (printlevel >= 1) printf("This is a pure dual feasibility problem.\n"); isdfeasprob=1; } else isdfeasprob=0; /* * For historical reasons, we use m for the total number of constraints. * In this version of the code, k is also the number of constraints. */ m=k; /* * Work out the leading dimension for the array. Note that we may not * want to use k itself, for cache issues. */ if ((k % 2) == 0) ldam=k+1; else ldam=k; /* * Compute Cholesky factors of X and Z. */ copy_mat(X,work1); ret=chol(work1); /* * If the matrix was singular, then just return with an error. */ if (ret != 0) { if (printlevel >= 1) printf("X was singular!\n"); retcode=8; goto RETURNBEST; }; chol_inv(work1,work2); store_packed(work2,cholxinv); copy_mat(Z,work1); ret=chol(work1); /* * If the matrix was singular, then just return with an error. */ if (ret != 0) { if (printlevel >= 1) printf("Z was singular!\n"); retcode=8; goto RETURNBEST; }; chol_inv(work1,work2); store_packed(work2,cholzinv); /* Compute Zi. */ copy_mat(work2,work1); trans(work1); scale1=1.0; scale2=0.0; mat_mult(scale1,scale2,work2,work1,Zi); if (printlevel >= 4) printf("Fnorm of Zi is %e \n",Fnorm(Zi)); /* Compute primal and dual objective values. */ *pobj=calc_pobj(C,X,constant_offset); *dobj=calc_dobj(k,a,y,constant_offset); if (parameters.usexzgap==0) { gap=*dobj-*pobj; if (gap < 0.0) gap=0.0; relgap=gap/(1.0+fabs(*dobj)+fabs(*pobj)); } else { gap=trace_prod(X,Z); relgap=gap/(1.0+fabs(*dobj)+fabs(*pobj)); }; if (printlevel >= 3) { printf("constant offset is %e \n",constant_offset); printf("Fnorm of X is %e \n",Fnorm(X)); printf("Fnorm of C is %e \n",normC); }; if (printlevel >= 4) { printf("pobj is %e \n",*pobj); printf("dobj is %e \n",*dobj); printf("gap is %e \n",gap); }; relpinfeas=pinfeas(k,constraints,X,a,workvec1); bestrelpinfeas=relpinfeas; reldinfeas=dinfeas(k,C,constraints,y,Z,work2); bestreldinfeas=reldinfeas; if (relpinfeas < parameters.axtol ) probpfeas=1; if (reldinfeas < parameters.atytol) probdfeas=1; /* * Record this solution as the best solution. */ bestmeas=1.0e100; store_packed(X,bestx); store_packed(Z,bestz); for (i=1; i<=k; i++) besty[i]=y[i]; /* Initialize the big loop. */ alphap=0.0; alphad=0.0; /* Print out some status information. */ if (printlevel >= 1) { printf("Iter: %2d Ap: %.2e Pobj: % .7e Ad: %.2e Dobj: % .7e \n",iter,alphap,*pobj,alphad,*dobj); fflush(stdout); }; while ((relgap > parameters.objtol) || (relpinfeas > parameters.axtol) || (reldinfeas > parameters.atytol)) { /* * Call the user exit routine, and let the user stop the process * if he wants to. */ ret=user_exit(n,k,C,a,*dobj,*pobj,constant_offset,constraints, X,y,Z,parameters); if (ret >= 1) { if (ret==1) { /* * Received SIGTERM, SIGQUIT, SIGXCPU, ... */ return(10); } else { /* * User exit was good enough, returning success. */ return(0); }; } bestarray[iter % BASIZE]=bestmeas; /* * Compute the stepfrac to be used for this iteration. */ if (iter > 1) { if (alphap > alphad) minalpha=alphad; else minalpha=alphap; } else { minalpha=1.0; }; mystepfrac=parameters.minstepfrac+minalpha*(parameters.maxstepfrac-parameters.minstepfrac); if (printlevel >= 3) printf("mystepfrac is %e \n",mystepfrac); /* * Print out information on primal/dual feasibility. */ if (printlevel >= 2) { printf("Relative primal infeasibility is %.7e \n",relpinfeas); printf("Relative dual infeasibility: %.7e \n",reldinfeas); printf("Relative duality gap is %.7e \n",relgap); printf("XZ relative duality gap is %.7e \n",trace_prod(X,Z)/(1+fabs(*dobj))); }; /* * If this is a feasibility problem, and we've got feasibility, * then we're done! */ if ((ispfeasprob==1) && (relpinfeas < parameters.axtol)) { if (printlevel >= 3) printf("Got primal feasibility, so stopping.\n"); for (i=1; i<=k; i++) y[i]=0.0; alphad=parameters.atytol/(sqrt(n*1.0)*200); make_i(work1); if (alphad*trace_prod(X,work1) > parameters.objtol) alphad=0.005*parameters.objtol/trace_prod(X,work1); zero_mat(work2); addscaledmat(work2,alphad,work1,Z); relpinfeas=pinfeas(k,constraints,X,a,workvec1); if (relpinfeas < bestrelpinfeas) bestrelpinfeas=relpinfeas; reldinfeas=dinfeas(k,C,constraints,y,Z,work2); if (reldinfeas < bestreldinfeas) bestreldinfeas=reldinfeas; *pobj=calc_pobj(C,X,constant_offset); *dobj=calc_dobj(k,a,y,constant_offset); if (parameters.usexzgap==0) { gap=*dobj-*pobj; if (gap < 0.0) gap=0.0; relgap=gap/(1.0+fabs(*dobj)+fabs(*pobj)); } else { gap=trace_prod(X,Z); if (gap < 0.0) gap=0.0; relgap=gap/(1.0+fabs(*dobj)+fabs(*pobj)); }; bestmeas=relpinfeas/parameters.axtol; store_packed(X,bestx); store_packed(Z,bestz); for (i=1; i<=k; i++) besty[i]=y[i]; retcode=0; goto RETURNBEST; }; if ((isdfeasprob==1) && (reldinfeas < parameters.atytol)) { if (printlevel >= 3) printf("Got dual feasibility, so stopping.\n"); make_i(work1); zero_mat(work2); op_a(k,constraints,work1,workvec1); alphap=parameters.atytol/(200.0*norm2(k,workvec1+1)); if (alphap*trace_prod(work1,Z) > parameters.objtol) alphap=0.005*parameters.objtol/trace_prod(work1,Z); addscaledmat(work2,alphap,work1,X); relpinfeas=pinfeas(k,constraints,X,a,workvec1); if (relpinfeas < bestrelpinfeas) bestrelpinfeas=relpinfeas; reldinfeas=dinfeas(k,C,constraints,y,Z,work2); if (reldinfeas < bestreldinfeas) bestreldinfeas=reldinfeas; *pobj=calc_pobj(C,X,constant_offset); *dobj=calc_dobj(k,a,y,constant_offset); if (parameters.usexzgap==0) { gap=*dobj-*pobj; if (gap < 0.0) gap=0.0; relgap=gap/(1.0+fabs(*dobj)+fabs(*pobj)); } else { gap=trace_prod(X,Z); if (gap < 0.0) gap=0.0; relgap=gap/(1.0+fabs(*dobj)+fabs(*pobj)); }; bestmeas=reldinfeas/parameters.atytol; store_packed(X,bestx); store_packed(Z,bestz); for (i=1; i<=k; i++) besty[i]=y[i]; if (printlevel >= 3) printf("New best solution, %e \n",bestmeas); retcode=0; goto RETURNBEST; }; /* * Check for primal or dual infeasibility. */ op_at(k,y,constraints,work1); addscaledmat(work1,-1.0,Z,work1); pinfeasmeas=-(*dobj)/Fnorm(work1); if (printlevel >= 2) printf("-a'*y/||A'(y)-Z|| is %e \n",pinfeasmeas); if ((probpfeas==0) && (pinfeasmeas > parameters.pinftol)) { if (printlevel >= 1) printf("Declaring primal infeasibility.\n"); for (i=1; i<=k; i++) y[i]=-y[i]/(*dobj); zero_mat(work1); addscaledmat(work1,-1.0/(*dobj),Z,work1); copy_mat(work1,Z); retcode=1; goto RETURNCERT; }; op_a(k,constraints,X,workvec1); dinfeasmeas=trace_prod(C,X)/norm2(k,workvec1+1); if (printlevel >= 2) printf("/||A(X)||=%e\n",dinfeasmeas); if ((probdfeas==0) && (dinfeasmeas>parameters.dinftol)) { if (printlevel >= 1) printf("Declaring dual infeasibility.\n"); zero_mat(work1); addscaledmat(work1,1.0/trace_prod(C,X),X,work1); copy_mat(work1,X); retcode=2; goto RETURNCERT; }; /* * Print out the norm(X) for debugging purposes. */ if (printlevel >= 3) { nrmx=Fnorm(X); printf("Fnorm of X is %e \n",nrmx); }; /* Now, compute the system matrix. */ #ifdef USEGETTIME gettimeofday(&tp,NULL); t1=(double)tp.tv_sec+(1.0e-6)*tp.tv_usec; #endif op_o(k,constraints,byblocks,Zi,X,O,work1,work2); #ifdef USEGETTIME gettimeofday(&tp,NULL); t2=(double)tp.tv_sec+(1.0e-6)*tp.tv_usec; opotime=opotime+t2-t1; #endif /* * Print out the actual density of Z and X. */ if ((iter==5) && (printlevel >= 3)) { printf("Actual density of O %e\n",actnnz(k,ldam,O)/(1.0*k*k)); for (j=1; j<=X.nblocks; j++) { if (X.blocks[j].blockcategory==MATRIX) { printf("density X block %d, %e \n",j,actnnz(X.blocks[j].blocksize, X.blocks[j].blocksize, X.blocks[j].data.mat)/ (1.0*X.blocks[j].blocksize*X.blocks[j].blocksize)); printf("density Z block %d, %e \n",j,actnnz(Z.blocks[j].blocksize, Z.blocks[j].blocksize, Z.blocks[j].data.mat)/ (1.0*Z.blocks[j].blocksize*Z.blocks[j].blocksize)); printf("bandwidth Z block %d, %d/%d \n",j,bandwidth(Z.blocks[j].blocksize,Z.blocks[j].blocksize,Z.blocks[j].data.mat),Z.blocks[j].blocksize); }; }; }; /* Save a copy of O in the lower diagonal for later use. */ for (i=1; i<=k-1; i++) for (j=i; j<=k; j++) O[ijtok(j,i, (long int) ldam)]=O[ijtok(i,j, (long int) ldam)]; for (i=1; i<=k; i++) diagO[i]=O[ijtok(i,i,(long int) ldam)]; mindiag=1.0e30; for (i=1; i<=k; i++) { if (diagO[i] < mindiag) { mindiag=diagO[i]; }; }; /* This is where we come if factorization failed or the system was so badly conditioned that we didn't get a usable solution. */ diagnrm=0.0; for (i=1; i<=k; i++) { ent=diagO[i]; diagnrm = diagnrm + ent*ent; }; diagnrm=sqrt(diagnrm); RETRYFACTOR: /* Now, let's make sure that O isn't singular. */ diagadd=1.0e-17*diagfact*diagnrm/sqrt(k*1.0); while ((diagadd + mindiag) <= 0.0) { retries++; if (diagfact==0.0) { diagfact=0.1; diagadd=1.0e-17*diagfact*diagnrm/sqrt(k*1.0); } else { diagfact=diagfact*10.0; diagadd=diagadd*10.0; }; }; if (printlevel >= 3) printf("diagnrm is %e, adding diagadd %e \n",diagnrm,diagadd); for (i=1; i<=k; i++) O[ijtok(i,i, (long int) ldam)] += diagadd; /* * Scale the O matrix. */ for (i=1; i<=k; i++) workvec8[i]=1.0/sqrt(O[ijtok(i,i, (long int) ldam)]); for (i=1; i<=k; i++) { if (workvec8[i] > 1.0e30) workvec8[i]=1.0e30; }; #pragma omp parallel for schedule(dynamic,64) default(none) shared(O,ldam,k,workvec8) private(i,j) for (j=1; j<=k; j++) for (i=1; i<=j; i++) O[ijtok(i,j, (long int) ldam)]=O[ijtok(i,j, (long int) ldam)]*(workvec8[i]*workvec8[j]); /* Next, compute the cholesky factorization of the system matrix. */ #ifdef USEGETTIME gettimeofday(&tp,NULL); t1=(double)tp.tv_sec+(1.0e-6)*tp.tv_usec; #endif #ifdef NOUNDERLAPACK #ifdef CAPSLAPACK DPOTRF("U",&m,O,&ldam,&info); #else dpotrf("U",&m,O,&ldam,&info); #endif #else #ifdef CAPSLAPACK DPOTRF_("U",&m,O,&ldam,&info); #else dpotrf_("U",&m,O,&ldam,&info); #endif #endif #ifdef USEGETTIME gettimeofday(&tp,NULL); t2=(double)tp.tv_sec+(1.0e-6)*tp.tv_usec; factortime=factortime+t2-t1; #endif if (info != 0) { if (printlevel >= 3) printf("Factorization of the system matrix failed!\n"); if (retries < 15) { if (retries == 0) diagfact=0.1; retries=retries+1; diagfact=diagfact*10.0; #pragma omp parallel for schedule(dynamic,64) private(i,j) shared(O,k,ldam) for (i=1; i<=k-1; i++) for (j=i; j<=k; j++) O[ijtok(i,j, (long int) ldam)]=O[ijtok(j,i, (long int) ldam)]; for (i=1; i<=k; i++) O[ijtok(i,i,(long int) ldam)]=diagO[i]; goto RETRYFACTOR; } else { if (printlevel >= 1) printf("Factorization of the system matrix failed, giving up. \n"); /* * Tighten up the solution as much as possible. */ retcode=8; goto RETURNBEST; }; }; /* Compute the rhs vector. */ for (i=1; i<=k; i++) rhs[i]=-a[i]; /* * Add in the corrections for Fd. */ /* his section is where Fd is computed and put into The rhs. To save storage, work2 is used instead of a variable named Fd. dX will be used as a work variable where needed in place of old work2 usage. */ op_at(k,y,constraints,work1); addscaledmat(Z,1.0,C,work2); if ((bestmeas > 1.0e3) && (parameters.perturbobj>0)) { if (printlevel >= 3) printf("Perturbing C.\n"); make_i(work3); addscaledmat(work2,-perturbfac,work3,work2); }; if ((bestmeas < 1.0e3) && (parameters.perturbobj>0)) { if (printlevel >= 3) printf("Perturbing C.\n"); make_i(work3); addscaledmat(work2,-perturbfac*pow(bestmeas/1000.0,1.5),work3,work2); }; addscaledmat(work2,-1.0,work1,work2); scale1=1.0; scale2=0.0; mat_multspb(scale1,scale2,Zi,work2,work3,fill); mat_multspc(scale1,scale2,work3,X,dX,fill); op_a(k,constraints,dX,workvec1); for (i=1; i<=k; i++) rhs[i] = rhs[i]+workvec1[i]; for (i=1; i<=k; i++) workvec1[i]=rhs[i]; if (printlevel >=3) { printf("Fnorm of Fd is %e \n",Fnorm(work2)); printf("Norm of rhs is %e \n",norm2(m,rhs+1)); }; /* Solve the system of equations for dy. */ /* * First, scale */ for (i=1; i<=k; i++) workvec1[i]=workvec1[i]*workvec8[i]; info=solvesys(k,ldam,O,workvec1); for (i=1; i<=k; i++) workvec1[i]=workvec1[i]*workvec8[i]; if (info != 0) { if (printlevel >= 1) printf("Solving for dy failed! \n"); retcode=8; goto RETURNBEST; }; /* * Do iterative refinement. */ if ((iter>1) && (relerr2 > parameters.axtol) && (parameters.fastmode==0)) { op_at(k,workvec1,constraints,work1); mat_multspa(1.0,0.0,work1,X,dX,fill); mat_multspc(1.0,0.0,Zi,dX,work1,fill); op_a(k,constraints,work1,workvec2); for (i=1; i<=k; i++) workvec2[i]=rhs[i]-workvec2[i]; relerr=norm2(k,workvec2+1)/(1.0+norm2(k,rhs+1)); besterr=relerr; for (i=1; i<=k; i++) workvec4[i]=workvec1[i]; if (printlevel >= 3) { printf("refinement: Before relative error in Ody=r is %e \n",besterr); fflush(stdout); }; refinements=0; lastimproverefinement=0; while ((refinements < 20) && (refinements-lastimproverefinement < 3) && (besterr > 1.0e-14)) { refinements++; for (i=1; i<=k; i++) workvec3[i]=workvec2[i]*workvec8[i]; info=solvesys(k,ldam,O,workvec3); for (i=1; i<=k; i++) workvec3[i]=workvec3[i]*workvec8[i]; for (i=1; i<=k; i++) workvec1[i]=workvec1[i]+workvec3[i]; op_at(k,workvec1,constraints,work1); mat_multspa(1.0,0.0,work1,X,dX,fill); mat_multspc(1.0,0.0,Zi,dX,work1,fill); op_a(k,constraints,work1,workvec2); for (i=1; i<=k; i++) workvec2[i]=rhs[i]-workvec2[i]; relerr=norm2(k,workvec2+1)/(1.0+norm2(k,rhs+1)); if (relerr < besterr) { lastimproverefinement=refinements; besterr=relerr; for (i=1; i<=k; i++) workvec4[i]=workvec1[i]; }; if (printlevel >= 4) { printf("refinement: During relative error in Ody=r is %e \n",besterr); fflush(stdout); }; }; if (printlevel >= 3) printf("refinement: After relative error in Ody=r is %e, %d \n",besterr,lastimproverefinement); for (i=1; i<=k; i++) workvec1[i]=workvec4[i]; }; /* * Extract dy. */ for (i=1; i<=k; i++) dy[i]=workvec1[i]; if (printlevel >= 3) printf("Norm of dy is %e \n",norm2(k,dy+1)); /* Compute dZ */ op_at(k,dy,constraints,dZ); /* * Note: At this point, dZ only has A'(dy), not -Fd */ /* Compute Zi*A'(dy), and save it in a temp variable for later use. */ scale1=1.0; scale2=0.0; mat_multspb(scale1,scale2,Zi,dZ,work1,fill); if (printlevel >= 4) printf("Fnorm of work1 is %e \n",Fnorm(work1)); /* * Now, update dZ to include -Fd */ if (printlevel >= 3) { printf("Before Fd, Fnorm of dZ is %e \n",Fnorm(dZ)); fflush(stdout); }; addscaledmat(dZ,-1.0,work2,dZ); if (printlevel >= 3) { printf("After Fd, Fnorm of dZ is %e \n",Fnorm(dZ)); fflush(stdout); }; /* * Now, we've got dZ in dZ, and Zi*A'(dy) in work1, * and Zi*Fd in work3 */ /* Compute dX=-X+Zi*Fd*X-temp*X; First, put I-Zi*Fd+work1 in workn2. Then multiply -work2*X, and put the result in dX. */ make_i(work2); addscaledmat(work2,-1.0,work3,work2); addscaledmat(work2,1.0,work1,work2); scale1=-1.0; scale2=0.0; mat_mult(scale1,scale2,work2,X,dX); sym_mat(dX); if (printlevel >= 3) { printf("Fnorm of dX is %e \n",Fnorm(dX)); printf("Fnorm of dZ is %e \n",Fnorm(dZ)); fflush(stdout); }; /* * Next, determine mu. */ if (relpinfeas < parameters.axtol) alphap1=linesearch(n,dX,work1,work2,work3,cholxinv,workvec4, workvec5,workvec6,mystepfrac,1.0, printlevel); else alphap1=linesearch(n,dX,work1,work2,work3,cholxinv,workvec4, workvec5,workvec6,mystepfrac,1.0, printlevel); if (reldinfeas < parameters.atytol) alphad1=linesearch(n,dZ,work1,work2,work3,cholzinv,workvec4, workvec5,workvec6,mystepfrac,1.0, printlevel); else alphad1=linesearch(n,dZ,work1,work2,work3,cholzinv,workvec4, workvec5,workvec6,mystepfrac,1.0, printlevel); /* Here, work1 holds X+alphap1*dX, work2=Z+alphad1*dZ */ addscaledmat(X,alphap1,dX,work1); addscaledmat(Z,alphad1,dZ,work2); for (i=1; i<=k; i++) workvec1[i]=y[i]+alphad1*dy[i]; /* * Check to see whether this affine solution is the best yet. * The test is somewhat expensive, so don't do it unless * we're close to done. */ if ((bestmeas <1.0e4) && (parameters.affine==0)) { /* * Verify that the new X and Z are Cholesky factorizable. */ copy_mat(work1,work3); ret=chol(work3); while (ret != 0) { if (printlevel >=3) printf("Affine eigsearch missed: adjusting alphap1\n"); alphap1=alphap1*0.9; addscaledmat(X,alphap1,dX,work1); copy_mat(work1,work3); ret=chol(work3); }; copy_mat(work2,work3); ret=chol(work3); while (ret != 0) { if (printlevel >=3) printf("Affine eigsearch missed: adjusting alphad1\n"); alphad1=alphad1*0.9; addscaledmat(Z,alphad1,dZ,work2); for (i=1; i<=k; i++) workvec1[i]=y[i]+alphad1*dy[i]; copy_mat(work2,work3); ret=chol(work3); }; /* * Now, check the quality of this solution. */ affpobj=calc_pobj(C,work1,constant_offset); affdobj=calc_dobj(k,a,workvec1,constant_offset); /* * run user exit to check if the affine solution is good enough */ ret=user_exit(n,k,C,a,affdobj,affpobj,constant_offset,constraints, work1,workvec1,work2,parameters); if (ret >= 1) { if (ret == 1) { /* * Received SIGTERM, SIGQUIT, ... */ return(10); } else { *dobj=affdobj; *pobj=affpobj; copy_mat(work1,X); copy_mat(work2,Z); for(i=1; i<=k; i++) y[i]=workvec1[i]; if(printlevel>=3) printf("Affine step good enough, exiting\n"); return(0); }; }; if (parameters.usexzgap==0) { affgap=affdobj-affpobj; if (affgap < 0) affgap=0.0; affrelgap=affgap/(1.0+fabs(affpobj)+fabs(affdobj)); } else { affgap=trace_prod(work1,work2); if (affgap < 0) affgap=0.0; affrelgap=affgap/(1.0+fabs(affpobj)+fabs(affdobj)); }; affreldinfeas=dinfeas(k,C,constraints,workvec1,work2,work3); affrelpinfeas=pinfeas(k,constraints,work1,a,workvec4); if (printlevel >= 3) { printf("affpobj is %e \n",affpobj); printf("affdobj is %e \n",affdobj); printf("affrelgap is %e \n",affrelgap); printf("affrelpinfeas is %e \n",affrelpinfeas); printf("affreldinfeas is %e \n",affreldinfeas); }; if ((affrelgap/parameters.objtol < bestmeas) && (affrelpinfeas/parameters.axtol bestmeas) bestmeas=affrelpinfeas/parameters.axtol; if (affreldinfeas/parameters.atytol > bestmeas) bestmeas=affreldinfeas/parameters.atytol; store_packed(work1,bestx); store_packed(work2,bestz); for (i=1; i<=k; i++) besty[i]=y[i]+alphad1*dy[i]; if (printlevel >= 3) printf("Affine step: New best solution, %e \n",bestmeas); }; if ((ispfeasprob==1) && (affrelpinfeas/parameters.axtol < bestmeas)) { bestmeas=affrelpinfeas/parameters.axtol; store_packed(work1,bestx); for (i=1; i<=k; i++) besty[i]=0.0; zero_mat(work3); addscaledmat(work3,1.0e-50,work1,work3); store_packed(work3,bestz); if (printlevel >= 3) printf("Affine step: New best solution, %e \n",bestmeas); }; if ((isdfeasprob==1) && (affreldinfeas/parameters.atytol = 3) printf("Affine step: New best solution, %e \n",bestmeas); }; if (bestmeas < 1.0) { if (printlevel >= 3) printf("Finishing with a final affine step.\n"); iter=iter+1; if (printlevel >= 1) printf("Iter: %2d Ap: %.2e Pobj: % .7e Ad: %.2e Dobj: % .7e \n",iter,alphap1,affpobj,alphad1,affdobj); if (printlevel >= 2) printf("Total Iterations: %d \n",iter); store_unpacked(bestx,X); store_unpacked(bestz,Z); for (i=1; i<=k; i++) y[i]=besty[i]; *pobj=calc_pobj(C,X,constant_offset); *dobj=calc_dobj(k,a,y,constant_offset); return(0); }; }; /* * Compute muplus and prepare for the corrector step. */ muplus=trace_prod(work1,work2)/(n); muk=trace_prod(X,Z)/(n); if (muk < 0.0) muk=fabs(muk); if (muplus < 0.0) muplus=muk/2; gamma=(muplus/muk); /* * Pick the new mu as follows: * * If we have been making good progress (alphap > 0.5) and * (alphad>0.5) then use mu=muk*gamma*gamma*min(gamma,0.5); * * If we haven't been making good progress, then just do * mu=muplus. * * Also, make sure that mu is no larger than the old mu. */ if ((relpinfeas < 0.1*parameters.axtol) && (alphad>0.2) && (reldinfeas < 0.1*parameters.atytol) && (alphap>0.2) && (mu > 1.0e-6) && (gamma < 1.0) && (alphap+alphad > 1.0)) { mu=muk*pow(gamma,alphap+alphad); } else { if (muplus < 0.9*muk) mu=muplus; else mu=muk*0.9; }; /* * If we have primal and dual infeasibility in hand, then * make sure that mu is <=muk/2. */ if ((relpinfeas < 0.9*parameters.axtol) && (reldinfeas < 0.9*parameters.atytol) && (mu > muk/2)) mu=muk/2; /* * If we want a primal-dual affine step, then set mu=0.0. */ if (parameters.affine==1) { mu=0.0; if (printlevel >= 3) printf("Taking an affine step because parameters.affine=1\n"); }; /* * Printout some info on mu. */ if (printlevel >= 2) { printf("muk is %e \n",muk); printf("muplus is %e \n",muplus); printf("New mu is %e \n",mu); printf("mu*n = target duality gap is %e \n",mu*n); fflush(stdout); }; /* * Take a moment to figure out how well we're doing on feasibility. */ addscaledmat(X,1.0,dX,work1); op_a(k,constraints,work1,workvec1); for (i=1; i<=k; i++) workvec1[i]=workvec1[i]-a[i]; relerr1=norm2(k,workvec1+1)/(1.0+norma); if (printlevel >= 3) { printf("refinement: Relative error in A(X+dX)=a (Fphat) is %e \n", relerr1); }; /* Now, compute the corrector step. */ /* rhs for the corrector step. */ /* Update Fphat=a-A(X+dX) */ addscaledmat(dX,1.0,X,work1); op_a(k,constraints,work1,Fp); for (i=1; i<=k; i++) Fp[i]=a[i]-Fp[i]; /* The RHS is now A(Zi*Fdhat*X)+A(Zi*(-dZ*dX+mu*I))-Fphat = A(Zi*(Fdhat*X-dZ*dX+mu*I))-Fphat */ make_i(work1); scale1=0.0; scale2=mu; mat_mult(scale1,scale2,work2,work2,work1); scale1=-1.0; scale2=1.0; mat_multspa(scale1,scale2,dZ,dX,work1,fill); scale1=1.0; scale2=0.0; mat_multspc(scale1,scale2,Zi,work1,work2,fill); /* Next, compute op_a of work2, and put the result in rhs. */ op_a(k,constraints,work2,rhs); /* * Finally, subtract off Fphat. */ for (i=1; i<=k; i++) rhs[i]=rhs[i]-Fp[i]; for (i=1; i<=k; i++) workvec1[i]=rhs[i]; /* Solve for dy1. */ for (i=1; i<=k; i++) workvec1[i]=workvec1[i]*workvec8[i]; info=solvesys(k,ldam,O,workvec1); for (i=1; i<=k; i++) workvec1[i]=workvec1[i]*workvec8[i]; if (info != 0) { if (printlevel >= 1) printf("Solving for dy1 failed! \n"); retcode=8; goto RETURNBEST; }; /* * Do iterative refinement. */ if ((iter>1) && (relerr2 > 0.01*parameters.axtol) && (parameters.fastmode==0)) { op_at(k,workvec1,constraints,work1); mat_multspa(1.0,0.0,work1,X,work2,fill); mat_multspc(1.0,0.0,Zi,work2,work3,fill); op_a(k,constraints,work3,workvec2); for (i=1; i<=k; i++) workvec2[i]=rhs[i]-workvec2[i]; relerr=norm2(k,workvec2+1)/(1.0+norm2(k,rhs+1)); besterr=relerr; for (i=1; i<=k; i++) workvec4[i]=workvec1[i]; if (printlevel >= 3) { printf("refinement: Before relative error in Odyhat=r is %e \n",besterr); }; refinements=0; lastimproverefinement=0; while ((refinements < 20) && (refinements-lastimproverefinement < 3) && (besterr > 1.0e-14)) { refinements++; for (i=1; i<=k; i++) workvec3[i]=workvec2[i]*workvec8[i]; info=solvesys(k,ldam,O,workvec3); for (i=1; i<=k; i++) workvec3[i]=workvec3[i]*workvec8[i]; for (i=1; i<=k; i++) workvec1[i]=workvec1[i]+workvec3[i]; op_at(k,workvec1,constraints,work1); mat_multspa(1.0,0.0,work1,X,work2,fill); mat_multspc(1.0,0.0,Zi,work2,work3,fill); op_a(k,constraints,work3,workvec2); for (i=1; i<=k; i++) workvec2[i]=rhs[i]-workvec2[i]; relerr=norm2(k,workvec2+1)/(1.0+norm2(k,rhs+1)); if (relerr < besterr) { lastimproverefinement=refinements; besterr=relerr; for (i=1; i<=k; i++) workvec4[i]=workvec1[i]; }; if (printlevel >= 4) { printf("refinement: During relative error in Ody=r is %e \n",besterr); fflush(stdout); }; }; if (printlevel >= 3) { printf("refinement: After relative error in Odyhat=r is %e,%d \n",besterr,lastimproverefinement); }; for (i=1; i<=k; i++) workvec1[i]=workvec4[i]; }; /* * retrieve dy1. */ for (i=1; i<=k; i++) dy1[i]=workvec1[i]; /* Compute dZ1=A'(dy1). dZ1 is stored in work3. */ op_at(k,dy1,constraints,work3); /* Compute dX1=-Zi*dZ1*X-Zi*dZ*dX+mu*zi; dX1=Zi*(-dZ1*X-dZ*dX+mu*I) for storage sake, dX1 is stored in work2. */ make_i(work1); scale1=-1.0; scale2=mu; mat_multspa(scale1,scale2,dZ,dX,work1,fill); scale1=-1.0; scale2=1.0; mat_multspa(scale1,scale2,work3,X,work1,fill); scale1=1.0; scale2=0.0; mat_mult(scale1,scale2,Zi,work1,work2); sym_mat(work2); addscaledmat(X,1.0,dX,work1); op_a(k,constraints,work1,workvec1); for (i=1; i<=k; i++) workvec1[i]=workvec1[i]-a[i]; relerr2=norm2(k,workvec1+1)/(1.0+norma); if (printlevel >= 3) { printf("refinement: Before dX+dX1 Relative error in A(X+dX)=a is %e \n",relerr2); if (relerr1 < relerr2) printf("refinement: worse\n"); else printf("refinement: better\n"); }; /* Update the predictor step. */ if (printlevel >= 3) { printf("Fnorm of dX1 is %e\n",Fnorm(work2)); printf("Fnorm of dZ1 is %e\n",Fnorm(work3)); }; add_mat(work2,dX); add_mat(work3,dZ); for (i=1; i<=k; i++) dy[i]=dy1[i]+dy[i]; /* * Check A(X+dX)=a. */ addscaledmat(X,1.0,dX,work1); op_a(k,constraints,work1,workvec1); for (i=1; i<=k; i++) workvec1[i]=workvec1[i]-a[i]; relerr2=norm2(k,workvec1+1)/(1.0+norma); if (printlevel >= 3) { printf("refinement: Before adjust dX Relative error in A(X+dX)=a is %e \n",relerr2); if (relerr1 < relerr2) printf("refinement: worse\n"); else printf("refinement: better\n"); }; if (printlevel >= 3) { printf("Fnorm of dX is %e \n",Fnorm(dX)); printf("Fnorm of dZ is %e \n",Fnorm(dZ)); }; /* * Take a moment to figure out how well we're doing on feasibility. */ addscaledmat(X,1.0,dX,work1); op_a(k,constraints,work1,workvec1); for (i=1; i<=k; i++) workvec1[i]=workvec1[i]-a[i]; relerr2=norm2(k,workvec1+1)/(1.0+norma); if (printlevel >= 3) { printf("refinement: After adjust error in A(X+dX)=a is %e \n",relerr2); if (relerr1 < relerr2) printf("refinement: worse\n"); else printf("refinement: better\n"); }; /* Now, we've got the individual steps. Find maximum possible step sizes. */ alphap=linesearch(n,dX,work1,work2,work3,cholxinv,workvec4, workvec5,workvec6,mystepfrac,1.0, printlevel); alphad=linesearch(n,dZ,work1,work2,work3,cholzinv,workvec4, workvec5,workvec6,mystepfrac,1.0, printlevel); if (printlevel >= 3) { printf("After linesearches, alphap=%e alphad=%e \n",alphap,alphad); }; for (i=1; i<=k; i++) workvec1[i]=y[i]+alphad*dy[i]; /* * Check on the feasibility of the new solutions. If they're * worse, and the old solution was feasible, then don't take the * step. */ addscaledmat(X,alphap,dX,work1); newrelpinfeas=pinfeas(k,constraints,work1,a,workvec1); /* * For the primal infeasibility, check the relative gap and the * current primal infeasibility to establish a limit on the * new infeasibility. */ limrelpinfeas=bestrelpinfeas*100; if ((limrelpinfeas >relgap) && (relgap > 0)) limrelpinfeas=relgap; /* * In the early stages, don't worry about limrelpinfeas. */ if ((iter < 10) || (relpinfeas > 0.01) || (dinfeasmeas > 1.0e-3*parameters.dinftol)) limrelpinfeas=relpinfeas*1000; /* * Don't ever ask for more than the required tolerance. */ if (parameters.axtol > limrelpinfeas) limrelpinfeas=parameters.axtol; /* * If we're trying to prove dual infeasibility than don't limit * the step. */ if ((probdfeas==0) && (dinfeasmeas>1.0e4)) limrelpinfeas=1.0e30; /* * Now, make sure that the step keeps us feasible enough. */ if (printlevel >= 3) { printf("newrelpinfeas is %e\n",newrelpinfeas); printf("limrelpinfeas is %e\n",limrelpinfeas); }; i=1; while (newrelpinfeas > limrelpinfeas) { alphap=0.80*alphap; addscaledmat(X,alphap,dX,work1); newrelpinfeas=pinfeas(k,constraints,work1,a,workvec1); i=i+1; if (i>20) { if (printlevel >=3) printf("Stuck at edge of primal feasibility.\n"); if (retries < 15) { if (retries == 0) diagfact=0.1; retries=retries+1; diagfact=diagfact*10.0; for (i=1; i<=k-1; i++) for (j=i; j<=k; j++) O[ijtok(i,j, (long int) ldam)]=O[ijtok(j,i, (long int) ldam)]; for (i=1; i<=k; i++) O[ijtok(i,i,(long int) ldam)]=diagO[i]; goto RETRYFACTOR; } else { if (printlevel >= 1) printf("Stuck at edge of primal feasibility, giving up. \n"); /* * Tighten up the solution as much as possible. */ retcode=5; goto RETURNBEST; }; }; }; /* Now make sure that we aren't stepping outside of dual feasibility. */ addscaledmat(Z,alphad,dZ,work1); for (i=1; i<=k; i++) workvec1[i]=y[i]+alphad*dy[i]; newreldinfeas=dinfeas(k,C,constraints,workvec1,work1,work2); limreldinfeas=bestreldinfeas*100; if ((limreldinfeas > relgap) && (relgap > 0)) limreldinfeas=relgap; /* * In the early stages, don't worry about limreldinfeas. * Also don't worry if we're trying to establish primal * infeasibility. */ if ((iter < 10) || (reldinfeas > 0.01) || (pinfeasmeas > 1.0e-3*parameters.pinftol)) limreldinfeas=reldinfeas*1000; /* * Don't ever ask for more than the required tolerance. */ if (parameters.atytol > limreldinfeas) limreldinfeas=parameters.atytol; if (printlevel >= 3) { printf("newreldinfeas is %e\n",newreldinfeas); printf("limreldinfeas is %e\n",limreldinfeas); }; i=1; while (newreldinfeas > limreldinfeas) { alphad=0.80*alphad; addscaledmat(Z,alphad,dZ,work1); for (j=1; j<=k; j++) workvec1[j]=y[j]+alphad*dy[j]; newreldinfeas=dinfeas(k,C,constraints,workvec1,work1, work2); i=i+1; if (i>15) { if (printlevel >=3) printf("Stuck at edge of dual feasibility.\n"); if (retries < 15) { if (retries == 0) diagfact=0.1; retries=retries+1; diagfact=diagfact*10.0; for (i=1; i<=k-1; i++) for (j=i; j<=k; j++) O[ijtok(i,j,(long int) ldam)]=O[ijtok(j,i,(long int) ldam)]; for (i=1; i<=k; i++) O[ijtok(i,i,(long int) ldam)]=diagO[i]; goto RETRYFACTOR; } else { if (printlevel >= 1) printf("Stuck at edge of dual feasibility, giving up. \n"); /* * Tighten up the solution as much as possible. */ retcode=6; goto RETURNBEST; }; }; }; if (printlevel >= 3) { printf("After feas check, alphap=%e alphad=%e \n",alphap,alphad); }; /* * Give up if step lengths are way too small. */ if ((alphap<=parameters.minstepp) || (alphad<=parameters.minstepd)) { if (printlevel >= 2) printf("line search failure in corrector step.\n"); if (retries < 15) { if (retries == 0) diagfact=0.1; retries=retries+1; diagfact=diagfact*10.0; for (i=1; i<=k-1; i++) for (j=i; j<=k; j++) O[ijtok(i,j,(long int) ldam)]=O[ijtok(j,i,(long int) ldam)]; for (i=1; i<=k; i++) O[ijtok(i,i,(long int) ldam)]=diagO[i]; goto RETRYFACTOR; } else { if (printlevel >= 1) printf("Too many line search failures, giving up. \n"); /* * Tighten up the solution as much as possible. */ retcode=7; goto RETURNBEST; }; }; /* * In case alphap changed, recompute these. */ addscaledmat(X,alphap,dX,work1); newrelpinfeas=pinfeas(k,constraints,work1,a,workvec1); addscaledmat(Z,alphad,dZ,work1); for (i=1; i<=k; i++) workvec1[i]=y[i]+alphad*dy[i]; newreldinfeas=dinfeas(k,C,constraints,workvec1,work1,work2); /* * Update cholzinv. */ copy_mat(work1,work2); ret=chol(work2); while (ret != 0) { alphad=alphad*0.90; addscaledmat(Z,alphad,dZ,work1); for (i=1; i<=k; i++) workvec1[i]=y[i]+alphad*dy[i]; copy_mat(work1,work2); ret=chol(work2); if (printlevel >=2) printf("eigsearch missed! Adjusting alphad\n"); }; chol_inv(work2,work3); store_packed(work3,cholzinv); /* Compute Zi. */ copy_mat(work3,work1); trans(work1); scale1=1.0; scale2=0.0; mat_mult(scale1,scale2,work3,work1,Zi); if (printlevel >= 4) printf("Fnorm of Zi is %e \n",Fnorm(Zi)); /* * Confirm that X is in fact factorable. If not, reduce * alpha until it is. */ addscaledmat(X,alphap,dX,work1); copy_mat(work1,work2); ret=chol(work2); while (ret != 0) { if (printlevel >=2) printf("eigsearch missed! Adjusting alphap\n"); alphap=alphap*0.90; addscaledmat(X,alphap,dX,work1); copy_mat(work1,work2); ret=chol(work2); }; chol_inv(work2,work3); store_packed(work3,cholxinv); /* * do a line search for feasibility. */ if (relpinfeas > 1.0) { newalphap=alphap; for (i=1; i<=9; i++) { addscaledmat(X,(i*1.0)*alphap/10.0,dX,work1); if (pinfeas(k,constraints,work1,a,workvec1) < newrelpinfeas) { newalphap=i*1.0*alphap/10.0; newrelpinfeas=pinfeas(k,constraints,work1,a,workvec1); }; }; if (newalphap < alphap) { if (printlevel >= 2) printf("Feasibility Adjusting alphap to %e \n",newalphap); alphap=newalphap; }; }; /* *Take the step. */ addscaledmat(X,alphap,dX,X); addscaledmat(Z,alphad,dZ,Z); for (i=1; i<=k; i++) y[i]=y[i]+alphad*dy[i]; /* Recompute the objective function values. */ *pobj=calc_pobj(C,X,constant_offset); *dobj=calc_dobj(k,a,y,constant_offset); if (parameters.usexzgap==0) { gap=*dobj-*pobj; if (gap < 0.0) gap=0.0; relgap=gap/(1.0+fabs(*dobj)+fabs(*pobj)); } else { gap=trace_prod(X,Z); if (gap < 0.0) gap=0.0; relgap=gap/(1.0+fabs(*dobj)+fabs(*pobj)); }; if (printlevel >= 2) { printf("pobj is %e \n",*pobj); printf("dobj is %e \n",*dobj); printf("gap is %e \n",gap); printf("relgap is %e \n",relgap); }; relpinfeas=pinfeas(k,constraints,X,a,workvec1); reldinfeas=dinfeas(k,C,constraints,y,Z,work2); if (relpinfeas < parameters.axtol ) probpfeas=1; if (reldinfeas < parameters.atytol) probdfeas=1; /* * Make sure that the objective value hasn't gone crazy. * * This was a test with isnan, but isnan isn't ANSI C, so * we use an equivalent that typically works. * */ if ((gap) != (gap)) { retcode=9; goto RETURNBEST; }; /* * This was a test with isinf, but isinf isn't ANSI C, so * we just test for extremely large values. */ if ((gap > 1.0e100) || (gap < -1.0e100)) { retcode=9; goto RETURNBEST; }; /* * if this solution is better than the previous best, then * update our best solution. */ if ((relgap/parameters.objtol < bestmeas) && (relpinfeas/parameters.axtol bestmeas) bestmeas=relpinfeas/parameters.axtol; if (reldinfeas/parameters.atytol > bestmeas) bestmeas=reldinfeas/parameters.atytol; store_packed(X,bestx); store_packed(Z,bestz); for (i=1; i<=k; i++) besty[i]=y[i]; if (printlevel >= 3) printf("New best solution, %e \n",bestmeas); }; if ((ispfeasprob==1) && (relpinfeas/parameters.axtol = 3) printf("New best solution, %e \n",bestmeas); }; if ((isdfeasprob==1) && (reldinfeas/parameters.atytol = 3) printf("New best solution, %e \n",bestmeas); }; /* * If we haven't improved the gap much in 20 iterations, then * give up, because we're not making progress. */ if ((iter > 60) && (bestmeas > 0.5*bestarray[((iter-20) % BASIZE)])) { if (printlevel >= 1) printf("Lack of progress. Giving up!\n"); retcode=7; goto RETURNBEST; }; /* Update counters and display status. */ iter++; if (printlevel >= 1) { printf("Iter: %2d Ap: %.2e Pobj: % .7e Ad: %.2e Dobj: % .7e \n",iter,alphap,*pobj,alphad,*dobj); fflush(stdout); }; /* * If iter gets above maxiter, then exit. */ if (iter >= parameters.maxiter) { if (printlevel >= 1) printf("Maximum iterations reached. \n"); retcode=4; goto RETURNBEST; }; }; /* * Return success. */ retcode=0; RETURNBEST: store_unpacked(bestx,X); store_unpacked(bestz,Z); for (i=1; i<=k; i++) y[i]=besty[i]; if (parameters.usexzgap==0) { *pobj=calc_pobj(C,X,constant_offset); *dobj=calc_dobj(k,a,y,constant_offset); gap=*dobj-*pobj; } else { *pobj=calc_pobj(C,X,constant_offset); *dobj=calc_dobj(k,a,y,constant_offset); gap=trace_prod(X,Z); }; if ((gap < 0.0) && (parameters.usexzgap==0) && (parameters.tweakgap==1) && (ispfeasprob==0) && (isdfeasprob==0)) { tweakgap(n,k,a,constraints,gap,Z,dZ,y,dy,work1,work2,work3,dX, workvec1,workvec2,workvec3,workvec4,printlevel); }; /* Recompute the objective function values. */ *pobj=calc_pobj(C,X,constant_offset); *dobj=calc_dobj(k,a,y,constant_offset); if (parameters.usexzgap==0) { gap=*dobj-*pobj; if (gap < 0.0) gap=0.0; relgap=gap/(1.0+fabs(*dobj)+fabs(*pobj)); } else { gap=trace_prod(X,Z); if (gap < 0.0) gap=0.0; relgap=gap/(1.0+fabs(*dobj)+fabs(*pobj)); }; /* * Recheck the primal and dual infeasibilities and gap. */ relpinfeas=pinfeas(k,constraints,X,a,workvec1); reldinfeas=dinfeas(k,C,constraints,y,Z,work1); if (relpinfeas < parameters.axtol ) probpfeas=1; if (reldinfeas < parameters.atytol) probdfeas=1; if ((relgap < parameters.objtol) && (relpinfeas bestmeas) bestmeas=relpinfeas/parameters.axtol; if ((reldinfeas/parameters.atytol) > bestmeas) bestmeas=reldinfeas/parameters.atytol; if ((bestmeas > 1.0) && (bestmeas < 1000.0)) retcode=3; }; if (ispfeasprob==1) { bestmeas=relpinfeas/parameters.axtol; if ((bestmeas > 1.0) && (bestmeas < 1000.0)) retcode=3; }; if (isdfeasprob==1) { bestmeas=reldinfeas/parameters.atytol; if ((bestmeas > 1.0) && (bestmeas < 1000.0)) retcode=3; }; /* * Come here if we have an infeasible problem and are returning the * certificate of infeasibility. */ RETURNCERT: /* * Print out the total number of iterations. */ if (printlevel >= 2) printf("Total Iterations: %d \n",iter); /* * Now, go ahead and return. */ return(retcode); } Csdp-6.2.0/lib/add_mat.c0000644000175200017520000000147113132530655013367 0ustar coincoin/* Add a matrix to a second matrix in Fortran storage format. */ #include #include #include "declarations.h" void add_mat(A,B) struct blockmatrix A; struct blockmatrix B; { int blk; int i,j; for (blk=1; blk<=A.nblocks; blk++) { switch (A.blocks[blk].blockcategory) { case DIAG: for (i=1; i<=A.blocks[blk].blocksize; i++) { B.blocks[blk].data.vec[i]+=A.blocks[blk].data.vec[i]; }; break; case MATRIX: for (j=1; j<=A.blocks[blk].blocksize; j++) for (i=1; i<=A.blocks[blk].blocksize; i++) B.blocks[blk].data.mat[ijtok(i,j,B.blocks[blk].blocksize)] += A.blocks[blk].data.mat[ijtok(i,j,A.blocks[blk].blocksize)]; break; case PACKEDMATRIX: default: printf("addscaledmat illegal block type \n"); exit(206); }; }; } Csdp-6.2.0/lib/Makefile0000644000175200017520000000174313133246222013267 0ustar coincoin# # Build the library. # libsdp.a: readprob.o sdp.o op_o.o psd_feas.o op_a.o op_at.o Fnorm.o calc_pobj.o calc_dobj.o trace_prod.o zero_mat.o mat_mult.o sym_mat.o copy_mat.o addscaledmat.o user_exit.o make_i.o allocmat.o initsoln.o initparams.o add_mat.o writesol.o readsol.o easysdp.o writeprob.o solvesys.o makefill.o mat_multsp.o norms.o linesearch.o matvec.o chol.o qreig.o tweakgap.o freeprob.o packed.o sortentries.o ar cr libsdp.a readprob.o sdp.o op_o.o psd_feas.o op_a.o op_at.o Fnorm.o calc_pobj.o calc_dobj.o trace_prod.o zero_mat.o mat_mult.o sym_mat.o copy_mat.o addscaledmat.o user_exit.o make_i.o allocmat.o initsoln.o initparams.o add_mat.o writesol.o readsol.o easysdp.o writeprob.o solvesys.o makefill.o mat_multsp.o norms.o linesearch.o matvec.o chol.o qreig.o tweakgap.o freeprob.o packed.o sortentries.o # # On some systems, you might need to add after "ar cr libsdp.a ..." # ranlib libsdp.a # # # To clean things up. # clean: rm -f *.o rm -f libsdp.a Csdp-6.2.0/lib/readprob.c0000644000175200017520000005145013133024571013572 0ustar coincoin/* Read in out a problem in SDPA sparse format. Return 0 if ok, 1 if failure. */ #include #include #include #include #include "declarations.h" void skip_to_end_of_line(); int get_line(); int max_line_length(); void countentry(); int addentry(); int read_prob(fname,pn,pk,pC,pa,pconstraints,printlevel) char *fname; int *pn; int *pk; struct blockmatrix *pC; double **pa; struct constraintmatrix **pconstraints; int printlevel; { struct constraintmatrix *myconstraints; FILE *fid; int i,j; int buflen; char *buf; int c; int nblocks; int blksz; int blk; char *ptr1; char *ptr2; int matno; int blkno; int indexi; int indexj; double ent; int ret; struct sparseblock *p; int *isdiag; double *tempdiag; /* * Open the file for reading, and determine the length of the longest * line. */ fid=fopen(fname,"r"); if (fid == (FILE *) NULL) { if (printlevel >= 1) printf("Couldn't open problem file for reading! \n"); exit(201); }; buflen=max_line_length(fid)+10; fclose(fid); buf=(char *)malloc(buflen*sizeof(char)); if (buf == NULL) { if (printlevel >= 1) printf("Storage allocation failed!\n"); exit(205); }; /* * In the first pass through the file, determine the size parameters, * and allocate space for everything. */ fid=fopen(fname,"r"); if (fid == (FILE *) NULL) { if (printlevel >= 1) printf("Couldn't open problem file for reading! \n"); exit(201); }; /* * First, read through the comment lines. */ c=getc(fid); while ((c == '"') || (c == '*')) { skip_to_end_of_line(fid); c=getc(fid); }; ungetc(c,fid); /* * Get the number of constraints (primal variables in SDPA terminology) */ ret=get_line(fid,buf,buflen); if (ret == 0) { ret=sscanf(buf,"%d",pk); if ((ret!=1) || (*pk<=0)) { if (printlevel >= 1) printf("Incorrect SDPA file. Couldn't read mDIM\n"); fclose(fid); return(1); }; } else { if (printlevel >= 1) printf("Incorect SDPA file. Couldn't read mDIM \n"); fclose(fid); return(1); }; #ifndef BIT64 /* * If operating in 32 bit mode, make sure that the dimension mDIM isn't * too big for 32 bits. If we don't do this check, then integer overflow * won't be detected, and we'll allocate a bogus amount of storage for * O. */ if (*pk > 23169) { if (printlevel >= 1) printf("This problem is too large to be solved in 32 bit mode!\n"); exit(206); }; #endif /* * Read in the number of blocks. */ ret=get_line(fid,buf,buflen); if (ret == 0) { ret=sscanf(buf,"%d",&nblocks); if ((ret != 1) || (nblocks <= 0)) { if (printlevel >= 1) printf("Incorect SDPA file. Couldn't read nBLOCKS. \n"); fclose(fid); return(1); }; } else { if (printlevel >= 1) printf("Incorect SDPA file. Couldn't read nBLOCKS. \n"); fclose(fid); return(1); }; /* * Keep track of which blocks have off diagonal entries. */ isdiag=(int *)malloc((nblocks+1)*sizeof(int)); for (i=1; i<=nblocks; i++) isdiag[i]=1; /* * Allocate space for the C matrix. */ pC->nblocks=nblocks; pC->blocks=(struct blockrec *)malloc((nblocks+1)*sizeof(struct blockrec)); if (pC->blocks == NULL) { if (printlevel >= 1) printf("Storage allocation failed!\n"); exit(205); } /* * Allocate space for the constraints. */ myconstraints=(struct constraintmatrix *)malloc((*pk+1)*sizeof(struct constraintmatrix)); if (myconstraints == NULL) { if (printlevel >= 1) printf("Storage allocation failed!\n"); exit(205); }; /* * Null out all pointers in constraints. */ for (i=1; i<=*pk; i++) { myconstraints[i].blocks=NULL; }; *pa=(double *)malloc((*pk+1)*sizeof(double)); if (*pa == NULL) { if (printlevel >= 1) printf("Storage allocation failed!\n"); exit(205); }; /* * And read the block structure. */ *pn=0; ret=get_line(fid,buf,buflen); if (ret == 0) { /* * Decode nblocks numbers out of the buffer. Put the results in * block_structure. */ ptr1=buf; for (blk=1; blk<=nblocks; blk++) { blksz=strtol(ptr1,&ptr2,10); ptr1=ptr2; /* * negative numbers are used to indicate diagonal blocks. First, * update n. */ *pn=*pn+abs(blksz); /* * Now, handle diagonal blocks and matrix blocks separately. */ if (blksz < 0) { /* * It's a diag block. */ pC->blocks[blk].blocksize=abs(blksz); pC->blocks[blk].blockcategory=DIAG; pC->blocks[blk].data.vec=(double *)malloc((1+abs(blksz))*sizeof(double)); if (pC->blocks[blk].data.vec == NULL) { if (printlevel >= 1) printf("Storage allocation failed!\n"); exit(205); }; for (i=1; i<=abs(blksz); i++) pC->blocks[blk].data.vec[i]=0.0; } else { /* * It's a matrix block. In the I32LP64 model, we can't do array * indexing for huge blocks using 32 bit integers. 46340 is * the largest sized block that we can handle. Trying to * malloc a larger block could cause integer overflow and * result in a negative malloc size. b */ if (blksz > 46340) { printf("This problem is too large to be solved in I32LP64 mode.\n"); exit(206); }; /* * Setup the block in C. */ pC->blocks[blk].blocksize=abs(blksz); pC->blocks[blk].blockcategory=MATRIX; pC->blocks[blk].data.mat=(double *)malloc((blksz*blksz)*sizeof(double)); if (pC->blocks[blk].data.mat == NULL) { if (printlevel >= 1) printf("Storage allocation failed!\n"); exit(205); }; for (j=1; j<=blksz; j++) for (i=1; i<=blksz; i++) pC->blocks[blk].data.mat[ijtok(i,j,blksz)]=0.0; }; }; } else { if (printlevel >= 1) printf("Incorect SDPA file. Couldn't read block sizes.\n"); fclose(fid); free(isdiag); return(1); }; /* * Read in the right hand side values. */ ret=get_line(fid,buf,buflen); if (ret == 0) { /* * Decode k numbers out of the buffer. Put the results in * a. */ ptr1=buf; for (i=1; i<=*pk; i++) { (*pa)[i]=strtod(ptr1,&ptr2); /* * Check for a case where ptr2 didn't advance. This indicates * a strtod failure. */ if (ptr1==ptr2) { if (printlevel >= 1) printf("Incorect SDPA file. Can't read RHS values.\n"); fclose(fid); free(isdiag); return(1); }; ptr1=ptr2; }; } else { if (printlevel >= 1) printf("Incorect SDPA file. Can't read values.\n"); fclose(fid); free(isdiag); return(1); }; /* * Now, loop through the entries, * counting entries in the constraint matrices block by block. */ ret=fscanf(fid,"%d %d %d %d %le ",&matno,&blkno,&indexi,&indexj,&ent); if (ret != 5) { if (printlevel >= 1) printf("Incorect SDPA file. Return code from fscanf is %d, should be 5\n",ret); fclose(fid); free(isdiag); return(1); }; do { /* * Check the validity of these values. */ if ((matno < 0) || (matno > *pk) || (blkno<1) || (blkno>nblocks) || (indexi < 1) || (indexi > pC->blocks[blkno].blocksize) || (indexj < 1) || (indexj > pC->blocks[blkno].blocksize)) { if (printlevel >= 1) printf("Incorect SDPA file. Bad values in line: %d %d %d %d %e \n", matno,blkno,indexi,indexj,ent); fclose(fid); free(isdiag); return(1); }; if (matno != 0) { if (ent != 0.0) countentry(myconstraints,matno,blkno,pC->blocks[blkno].blocksize); } else { /* * An entry in C. ignore it for now. */ }; ret=fscanf(fid,"%d %d %d %d %le",&matno,&blkno,&indexi,&indexj,&ent); } while (ret == 5); if ((ret != EOF) && (ret != 0)) { if (printlevel >= 1) printf("Incorrect SDPA file, while reading entries. ret=%d \n",ret); fclose(fid); free(isdiag); return(1); }; fclose(fid); /* * Now, go through each of the blks in each of the constraint matrices, * and allocate space for the entries and indices. */ for (i=1; i<=*pk; i++) { p=myconstraints[i].blocks; while (p != NULL) { /* * allocate storage for the entries in this block of this constraint. */ p->entries=(double *)malloc((p->numentries+1)*sizeof(double)); if (p->entries == NULL) { if (printlevel >= 1) printf("Storage allocation failed!\n"); exit(205); }; p->iindices=(int *)malloc((p->numentries+1)*sizeof(int)); if (p->iindices == NULL) { if (printlevel >= 1) printf("Storage allocation failed!\n"); exit(205); }; p->jindices=(int *)malloc((p->numentries+1)*sizeof(int)); if (p->jindices == NULL) { if (printlevel >= 1) printf("Storage allocation failed!\n"); exit(205); }; p->numentries=0; p=p->next; }; }; /* * In the final pass through the file, fill in the actual data. */ zero_mat(*pC); /* * Open the file for reading, and then read in all of the actual * matrix entries. * line. */ fid=fopen(fname,"r"); if (fid == (FILE *) NULL) { if (printlevel >= 1) printf("Couldn't open problem file for reading! \n"); exit(201); }; /* * First, read through the comment lines. */ c=getc(fid); while ((c == '"') || (c == '*')) { skip_to_end_of_line(fid); c=getc(fid); }; ungetc(c,fid); /* * Get the number of constraints (primal variables in SDPA terminology) */ ret=get_line(fid,buf,buflen); if (ret == 0) { sscanf(buf,"%d",pk); } else { if (printlevel >= 1) printf("Incorect SDPA file. Couldn't read mDIM \n"); fclose(fid); free(isdiag); return(1); }; /* * Read in the number of blocks. */ ret=get_line(fid,buf,buflen); if (ret == 0) { sscanf(buf,"%d",&nblocks); } else { if (printlevel >= 1) printf("Incorect SDPA file. Couldn't read nBLOCKS. \n"); fclose(fid); free(isdiag); return(1); }; /* * And read the block structure. */ ret=get_line(fid,buf,buflen); if (ret != 0) { if (printlevel >= 1) printf("Incorect SDPA file. Couldn't read block sizes.\n"); fclose(fid); free(isdiag); return(1); }; /* * Read in the right hand side values. */ ret=get_line(fid,buf,buflen); if (ret == 0) { /* * Decode k numbers out of the buffer. Put the results in * a. */ ptr1=buf; for (i=1; i<=*pk; i++) { (*pa)[i]=strtod(ptr1,&ptr2); /* * Check for a case where ptr2 didn't advance. This indicates * a strtod failure. */ if (ptr1==ptr2) { if (printlevel >= 1) printf("Incorect SDPA file. Can't read RHS values.\n"); fclose(fid); free(isdiag); return(1); }; ptr1=ptr2; }; } else { if (printlevel >= 1) printf("Incorect SDPA file. Can't read a values.\n"); fclose(fid); free(isdiag); return(1); }; /* * Now, read the actual entries. */ ret=fscanf(fid,"%d %d %d %d %le ",&matno,&blkno,&indexi,&indexj,&ent); do { /* * No need for sanity checking the second time around. */ /* * Mark this block as not diagonal if indexi!=indexj. */ if ((indexi != indexj) && (ent != 0.0)) isdiag[blkno]=0; if (matno != 0) { if (ent != 0.0) { ret=addentry(myconstraints,matno,blkno,indexi,indexj,ent); if (ret != 0) { if (printlevel >= 1) { printf("Incorrect SDPA file. Duplicate entry.\n"); printf("matno=%d\n",matno); printf("blkno=%d\n",blkno); printf("indexi=%d\n",indexi); printf("indexj=%d\n",indexj); }; fclose(fid); free(isdiag); return(1); }; }; } else { /* * An entry in C. */ if (ent != 0.0) { blksz=pC->blocks[blkno].blocksize; if (pC->blocks[blkno].blockcategory == DIAG) { if (pC->blocks[blkno].data.vec[indexi] != 0.0) { /* * We've got a duplicate entry in C! */ if (printlevel >= 1) { printf("Incorrect SDPA file. Duplicate entry.\n"); printf("matno=%d\n",matno); printf("blkno=%d\n",blkno); printf("indexi=%d\n",indexi); printf("indexj=%d\n",indexj); }; fclose(fid); free(isdiag); return(1); } else pC->blocks[blkno].data.vec[indexi]=ent; } else { if (pC->blocks[blkno].data.mat[ijtok(indexi,indexj,blksz)] != 0.0) { /* * We've got a duplicate entry in C! */ if (printlevel >= 1) { printf("Incorrect SDPA file. Duplicate entry.\n"); printf("matno=%d\n",matno); printf("blkno=%d\n",blkno); printf("indexi=%d\n",indexi); printf("indexj=%d\n",indexj); }; fclose(fid); free(isdiag); return(1); } else { pC->blocks[blkno].data.mat[ijtok(indexi,indexj,blksz)]=ent; pC->blocks[blkno].data.mat[ijtok(indexj,indexi,blksz)]=ent; }; }; }; }; ret=fscanf(fid,"%d %d %d %d %le ",&matno,&blkno,&indexi,&indexj,&ent); } while (ret == 5); if ((ret != EOF) && (ret != 0)) { if (printlevel >= 1) printf("Incorrect SDPA file. \n"); fclose(fid); free(isdiag); return(1); }; /* * At this point, we'll stop to recognize whether any of the blocks * are "hidden LP blocks" and correct the block type if needed. */ for (i=1; i<=nblocks; i++) { if ((pC->blocks[i].blockcategory != DIAG) && (isdiag[i]==1) && (pC->blocks[i].blocksize > 1)) { /* * We have a hidden diagonal block! */ if (printlevel >= 2) { printf("Block %d is actually diagonal.\n",i); }; blksz=pC->blocks[i].blocksize; tempdiag=(double *)malloc((blksz+1)*sizeof(double)); for (j=1; j<=blksz; j++) tempdiag[j]=pC->blocks[i].data.mat[ijtok(j,j,blksz)]; free(pC->blocks[i].data.mat); pC->blocks[i].data.vec=tempdiag; pC->blocks[i].blockcategory=DIAG; }; }; /* * If the printlevel is high, print out info on constraints and block * matrix structure. */ if (printlevel >= 3) { printf("Block matrix structure.\n"); for (blk=1; blk<=pC->nblocks; blk++) { if (pC->blocks[blk].blockcategory == DIAG) printf("Block %d, DIAG, %d \n",blk,pC->blocks[blk].blocksize); if (pC->blocks[blk].blockcategory == MATRIX) printf("Block %d, MATRIX, %d \n",blk,pC->blocks[blk].blocksize); }; }; /* * Next, setup issparse and NULL out all nextbyblock pointers. */ for (i=1; i<=*pk; i++) { p=myconstraints[i].blocks; while (p != NULL) { p->nextbyblock=NULL; p=p->next; }; }; /* * Free unneeded memory. */ free(buf); free(isdiag); /* * Put back all the returned values. */ *pconstraints=myconstraints; fclose(fid); return(0); } /* * This routine skips to the end of the current line of input from the * file fid. */ void skip_to_end_of_line(fid) FILE *fid; { char c; c=getc(fid); while (c != '\n') c=getc(fid); } /* * This routine reads a line of input into a buffer, and translates all * occurences of "," "{" "}" "(" ")" to spaces. * */ int get_line(fid,buffer,bufsiz) FILE *fid; char *buffer; int bufsiz; { int i; int k; char c; k=0; c=getc(fid); while (c != '\n') { buffer[k]=c; k++; c=getc(fid); if (c == EOF) return(2); if (k >=bufsiz) { printf("Line too long in input file! Adjust BUFFERSIZ in readprob.c\n"); return(1); }; }; buffer[k]='\n'; buffer[k+1]=0; for (i=0; i<=k; i++) { if (buffer[i]==',') buffer[i]=' '; if (buffer[i]=='{') buffer[i]=' '; if (buffer[i]=='}') buffer[i]=' '; if (buffer[i]=='(') buffer[i]=' '; if (buffer[i]==')') buffer[i]=' '; }; return(0); } int max_line_length(fid) FILE *fid; { int maxlen; int k; int c; maxlen=0; k=0; c=getc(fid); while (c != EOF) { k=0; while ((c != '\n') && (c != EOF)) { c=getc(fid); k++; }; if (k > maxlen) maxlen=k; c=getc(fid); }; return(maxlen); } void countentry(constraints,matno,blkno,blocksize) struct constraintmatrix *constraints; int matno; int blkno; int blocksize; { struct sparseblock *p; struct sparseblock *q; p=constraints[matno].blocks; if (p == NULL) { /* * We haven't yet allocated any blocks. */ p=(struct sparseblock *)malloc(sizeof(struct sparseblock)); if (p==NULL) { printf("Storage allocation failed!\n"); exit(205); }; p->constraintnum=matno; p->blocknum=blkno; p->numentries=1; p->next=NULL; p->entries=NULL; p->iindices=NULL; p->jindices=NULL; p->blocksize=blocksize; constraints[matno].blocks=p; } else { /* * We have some existing blocks. See whether this block is already * in the chain. */ while ((p->next) != NULL) { if (p->blocknum == blkno) { /* * Found the right block. */ p->numentries=p->numentries+1; return; }; p=p->next; }; /* * If we get here, we still have to check the last block in the * chain. */ if (p->blocknum == blkno) { /* * Found the right block. */ p->numentries=p->numentries+1; return; }; /* * If we get here, then the block doesn't exist yet. */ q=(struct sparseblock *)malloc(sizeof(struct sparseblock)); if (q==NULL) { printf("Storage allocation failed!\n"); exit(205); }; /* * Fill in information for this block. */ q->blocknum=blkno; q->constraintnum=matno; q->numentries=1; q->next=NULL; q->entries=NULL; p->iindices=NULL; p->jindices=NULL; q->blocksize=blocksize; /* * Now link it into the list. */ p->next=q; }; } int addentry(constraints,matno,blkno,indexi,indexj,ent) struct constraintmatrix *constraints; int matno; int blkno; int indexi; int indexj; double ent; { struct sparseblock *p; int itemp; /* * Arrange things so that indexi <= indexj. */ if (indexi > indexj) { itemp=indexi; indexi=indexj; indexj=itemp; }; /* * Find the appropriate block. */ p=constraints[matno].blocks; if (p == NULL) { printf("Internal Error in readprob.c !\n"); exit(206); } else { /* * We have some existing blocks. See whether this block is already * in the chain. */ while (p != NULL) { if (p->blocknum == blkno) { /* * Found the right block. */ p->numentries=(p->numentries)+1; p->entries[(p->numentries)]=ent; p->iindices[(p->numentries)]=indexi; p->jindices[(p->numentries)]=indexj; /* * We've successfully added the entry. */ return(0); }; p=p->next; }; /* * If we get here, we have an internal error. */ printf("Internal Error in CSDP readprob.c !\n"); exit(206); }; /* * Everything is good, so return 0. */ return(0); } Csdp-6.2.0/lib/initsoln.c0000644000175200017520000000354013132530655013634 0ustar coincoin/* * Build an initial solution for an SDP problem. */ #include #include #include #include "declarations.h" void initsoln(n,k,C,a,constraints,pX0,py0,pZ0) int n; int k; struct blockmatrix C; double *a; struct constraintmatrix *constraints; struct blockmatrix *pX0; double **py0; struct blockmatrix *pZ0; { int i,j; double alpha,beta; double maxnrmA,nrmA; double nrmC; double scale1, scale2; struct sparseblock *ptr; /* * First, allocate storage for X0, y0, and Z0. */ alloc_mat(C,pX0); alloc_mat(C,pZ0); *py0=(double *)malloc(sizeof(double)*(k+1)); if (py0 == NULL) { printf("Storage allocation failed!\n"); exit(205); }; /* * next, pick alpha=n*max_i((1+|a_i|)/(1+||A_i||)). */ maxnrmA=0.0; alpha=0.0; for (i=1; i<=k; i++) { nrmA=0.0; ptr=constraints[i].blocks; while (ptr != NULL) { for (j=1; j<=ptr->numentries; j++) { nrmA += (ptr->entries[j])*(ptr->entries[j]); if (ptr->iindices[j] != ptr->jindices[j]) nrmA += (ptr->entries[j])*(ptr->entries[j]); }; ptr=ptr->next; }; nrmA=sqrt(nrmA); if (nrmA > maxnrmA) maxnrmA=nrmA; if ((1+fabs(a[i]))/(1+nrmA) > alpha) alpha=(1+fabs(a[i]))/(1+nrmA); }; alpha=n*alpha; /* * Next, calculate the F norm of C. */ nrmC=Fnorm(C); if (nrmC > maxnrmA) { beta=(1+nrmC)/sqrt(n*1.0); } else { beta=(1+maxnrmA)/sqrt(n*1.0); }; /* * Now that we have alpha and beta, make X=100*alpha*I, Z=100*beta*I, y=0. */ make_i(*pX0); scale1=0.0; scale2=10*alpha; mat_mult(scale1,scale2,*pX0,*pX0,*pX0); make_i(*pZ0); scale1=0.0; scale2=10*beta; mat_mult(scale1,scale2,*pZ0,*pZ0,*pZ0); /* * Set y to 0. */ for (i=1; i<=k; i++) (*py0)[i]=0; } Csdp-6.2.0/lib/calc_dobj.c0000644000175200017520000000101410455242355013671 0ustar coincoin/* Compute the dual objective function value dobj=a'y. */ #include "declarations.h" double calc_dobj(k,a,y,constant_offset) int k; double *a; double *y; double constant_offset; { double s; int incx=1; s=0.0; #ifdef NOUNDERBLAS #ifdef CAPSBLAS s=s+DDOT(&k,a+1,&incx,y+1,&incx); #else s=s+ddot(&k,a+1,&incx,y+1,&incx); #endif #else #ifdef CAPSBLAS s=s+DDOT_(&k,a+1,&incx,y+1,&incx); #else s=s+ddot_(&k,a+1,&incx,y+1,&incx); #endif #endif return(s+constant_offset); } Csdp-6.2.0/lib/freeprob.c0000644000175200017520000000202010455242355013573 0ustar coincoin/* * Free the memory associated with a problem. */ #include #include "declarations.h" void free_prob(n,k,C,a,constraints,X,y,Z) int n; int k; struct blockmatrix C; double *a; struct constraintmatrix *constraints; struct blockmatrix X; double *y; struct blockmatrix Z; { int i; struct sparseblock *ptr; struct sparseblock *oldptr; /* * First, free the vectors of doubles. */ free(y); free(a); /* * Now, the block matrices. */ free_mat(C); free_mat(X); free_mat(Z); /* * Finally, get rid of the constraints. */ if (constraints != NULL) { for (i=1; i<=k; i++) { /* * Get rid of constraint i. */ ptr=constraints[i].blocks; while (ptr != NULL) { free(ptr->entries); free(ptr->iindices); free(ptr->jindices); oldptr=ptr; ptr=ptr->next; free(oldptr); }; }; /* * Finally, free the constraints array. */ free(constraints); }; } Csdp-6.2.0/lib/initparams.c0000644000175200017520000001442213132471632014144 0ustar coincoin/* * Setup default values of the parameters. */ #include #include #include "declarations.h" void initparams(params,pprintlevel) struct paramstruc *params; int *pprintlevel; { FILE *paramfile; int ret; double value; char parametername[30]; char junk[2]; /* * First, set default values for all parameters. */ params->axtol=1.0e-8; params->atytol=1.0e-8; params->objtol=1.0e-8; params->pinftol=1.0e8; params->dinftol=1.0e8; params->maxiter=100; params->minstepfrac=0.90; params->maxstepfrac=0.97; params->minstepp=1.0e-8; params->minstepd=1.0e-8; params->usexzgap=1; params->tweakgap=0; params->affine=0; params->perturbobj=1; params->fastmode=0; *pprintlevel=1; /* * Attempt to open param.csdp. If it doesn't open, then just use * the default values. */ paramfile=fopen("param.csdp","r"); if (paramfile != NULL) { while (1==1) { /* * Skip over leading white space if there is any. Ignore the return * code, since it's OK if there are no leading spaces. */ ret=fscanf(paramfile,"%*[ \t\n]"); /* * handle end of file. */ if (ret == EOF) break; /* * Get the parameter name. */ ret=fscanf(paramfile,"%29[A-Za-z0-9]",parametername); if (ret != 1) { /* * We don't have a parameter name. Go on to the next line. */ ret=fscanf(paramfile,"%*[^\n]\n"); continue; }; /* * Skip over any trailing white space, the = sign, and any * leading white space after =. */ ret=fscanf(paramfile,"%*[ \t]"); ret=fscanf(paramfile,"%1[=]",junk); if (ret != 1) { printf("param.csdp line missing =. Skipping to next line.\n"); ret=fscanf(paramfile,"%*[^\n]\n"); continue; }; /* * Skip over any white space after equal sign. */ ret=fscanf(paramfile,"%*[ \t]"); /* * Get the value. */ ret=fscanf(paramfile,"%le",&value); /* * Skip to the end of line. */ ret=fscanf(paramfile,"%*[^\n]\n"); /* * For debugging, print out the parametername and value. */ /* printf("parameter name: %s\n",parametername); printf("value: %le\n",value); */ /* * Now, adjust the parameter as needed. */ if (strcasecmp(parametername,"axtol")==0) { params->axtol=value; continue; }; if (strcasecmp(parametername,"atytol")==0) { params->atytol=value; continue; }; if (strcasecmp(parametername,"objtol")==0) { params->objtol=value; continue; }; if (strcasecmp(parametername,"pinftol")==0) { params->pinftol=value; continue; }; if (strcasecmp(parametername,"dinftol")==0) { params->dinftol=value; continue; }; if (strcasecmp(parametername,"maxiter")==0) { params->maxiter=value; continue; }; if (strcasecmp(parametername,"minstepfrac")==0) { params->minstepfrac=value; continue; }; if (strcasecmp(parametername,"maxstepfrac")==0) { params->maxstepfrac=value; continue; }; if (strcasecmp(parametername,"minstepp")==0) { params->minstepp=value; continue; }; if (strcasecmp(parametername,"minstepd")==0) { params->minstepd=value; continue; }; if (strcasecmp(parametername,"usexzgap")==0) { params->usexzgap=value; continue; }; if (strcasecmp(parametername,"tweakgap")==0) { params->tweakgap=value; continue; }; if (strcasecmp(parametername,"affine")==0) { params->affine=value; continue; }; if (strcasecmp(parametername,"printlevel")==0) { *pprintlevel=value; continue; }; if (strcasecmp(parametername,"perturbobj")==0) { params->perturbobj=value; continue; }; if (strcasecmp(parametername,"fastmode")==0) { params->fastmode=value; continue; }; printf("param.csdp: unrecognized parameter, %s\n", parametername); }; /* * Close the parameter file. */ fclose(paramfile); }; /* * Print out the parameters that will be used. */ if (*pprintlevel >= 2) { printf("params->axtol is %e \n",params->axtol); printf("params->atytol is %e \n",params->atytol); printf("params->objtol is %e \n",params->objtol); printf("params->pinftol is %e \n",params->pinftol); printf("params->dinftol is %e \n",params->dinftol); printf("params->maxiter is %d \n",params->maxiter); printf("params->minstepfrac is %e \n",params->minstepfrac); printf("params->maxstepfrac is %e \n",params->maxstepfrac); printf("params->minstepp is %e \n",params->minstepp); printf("params->minstepd is %e \n",params->minstepd); printf("params->usexzgap is %d \n",params->usexzgap); printf("params->tweakgap is %d \n",params->tweakgap); printf("params->affine is %d \n",params->affine); printf("params->printlevel is %d \n",*pprintlevel); printf("params->perturbobj is %e \n",params->perturbobj); printf("params->fastmode is %d \n",params->fastmode); }; } Csdp-6.2.0/lib/sym_mat.c0000644000175200017520000000140313132530655013442 0ustar coincoin/* Symmetrize a matrix in Fortran storage format. */ #include #include #include "declarations.h" void sym_mat(A) struct blockmatrix A; { int i; int j; int blk; double foo; double *ap; int n; /* * Loop through the blocks, symmetrizing one at a time. */ for (blk=1; blk<=A.nblocks; blk++) { switch (A.blocks[blk].blockcategory) { case DIAG: break; case MATRIX: n=A.blocks[blk].blocksize; ap=A.blocks[blk].data.mat; for (j=1; j<=n; j++) for (i=1; i<=j; i++) { foo=(ap[ijtok(i,j,n)]+ap[ijtok(j,i,n)])/2.0; ap[ijtok(i,j,n)]=foo; ap[ijtok(j,i,n)]=foo; }; break; case PACKEDMATRIX: default: printf("sym_mat illegal block type \n"); exit(206); }; }; } Csdp-6.2.0/lib/calc_pobj.c0000644000175200017520000000202613132530655013707 0ustar coincoin/* Compute the primal objective function value pobj=Trace(C*X) Since we only need the trace, it makes more sense to just compute the diagonal of the product and sum the entries.. */ #include #include #include "declarations.h" double calc_pobj(C,X,constant_offset) struct blockmatrix C; struct blockmatrix X; double constant_offset; { int blk; int i,j; double pobj; pobj=constant_offset; for (blk=1; blk<=C.nblocks; blk++) { switch (C.blocks[blk].blockcategory) { case DIAG: for (i=1; i<=C.blocks[blk].blocksize; i++) { pobj += C.blocks[blk].data.vec[i]*X.blocks[blk].data.vec[i]; }; break; case MATRIX: for (j=1; j<=C.blocks[blk].blocksize; j++) for (i=1; i<=C.blocks[blk].blocksize; i++) pobj += C.blocks[blk].data.mat[ijtok(i,j,C.blocks[blk].blocksize)]*X.blocks[blk].data.mat[ijtok(j,i,C.blocks[blk].blocksize)]; break; default: printf("calc_pobj illegal block type!\n"); exit(206); }; }; return(pobj); } Csdp-6.2.0/lib/op_a.c0000644000175200017520000000245510522313034012705 0ustar coincoin /* Compute A(X). */ #include #include "declarations.h" void op_a(k,constraints,X,result) int k; struct constraintmatrix *constraints; struct blockmatrix X; double *result; { int i,j; int p,q; int blk; double ent; double *mat; double *vec; int nume; struct sparseblock *ptr; double contrib; #pragma omp parallel for schedule(dynamic,64) default(none) private(i,contrib,ptr,blk,nume,vec,j,p,mat,ent,q) shared(k,constraints,result,X) for (i=1; i<=k; i++) { result[i]=0.0; contrib=0.0; ptr=constraints[i].blocks; while (ptr != NULL) { blk=ptr->blocknum; nume=ptr->numentries; if (X.blocks[blk].blockcategory == DIAG) { vec=X.blocks[blk].data.vec; for (j=1; j<=nume; j++) { ent=ptr->entries[j]; p=ptr->iindices[j]; contrib += ent*vec[p]; }; } else { mat=X.blocks[blk].data.mat; for (j=1; j<=nume; j++) { ent=ptr->entries[j]; p=ijtok(ptr->iindices[j],ptr->jindices[j],ptr->blocksize); q=ijtok(ptr->jindices[j],ptr->iindices[j],ptr->blocksize); if (p == q) { contrib += ent*mat[p]; } else { contrib += ent*(mat[p]+mat[q]); }; }; }; ptr=ptr->next; }; result[i] += contrib; }; } Csdp-6.2.0/lib/zero_mat.c0000644000175200017520000000151313132530655013613 0ustar coincoin/* Zero out a block matrix. */ #include #include #include "declarations.h" void zero_mat(A) struct blockmatrix A; { int i,j; int blk; /* * Loop through the blocks, zeroing one at a time. */ for (blk=1; blk<=A.nblocks; blk++) { /* * Zero out block i. */ switch (A.blocks[blk].blockcategory) { case DIAG: for (i=1; i<=A.blocks[blk].blocksize; i++) { A.blocks[blk].data.vec[i]=0.0; }; break; case MATRIX: #pragma omp parallel for schedule(dynamic,64) default(none) shared(A,blk) private(j,i) for (j=1; j<=A.blocks[blk].blocksize; j++) for (i=1; i<=A.blocks[blk].blocksize; i++) A.blocks[blk].data.mat[ijtok(i,j,A.blocks[blk].blocksize)]=0.0; break; default: printf("Illegal block type \n"); exit(206); }; }; } Csdp-6.2.0/lib/mat_mult.c0000644000175200017520000000571113132530655013621 0ustar coincoin/* * Compute C=scale1*A*B+scale2*C. * Note that C must consist of dense matrix and vector blocks- no sparse * blocks or eye's or other special cases. * * A and B can have blocks of all supported types. Unsupported types * generate exit(206). * * It is assumed that all three matrices are of compatible block strucutre. * * We use dgemm to do the actual work on normal dense blocks. * */ #include #include #include "declarations.h" void mat_mult(scale1,scale2,A,B,C) double scale1,scale2; struct blockmatrix A,B,C; { int blk,i,n; double *ap; double *bp; double *cp; /* * In theory, the BLAS ensures that if scale2=0, then C will not be * accessed before being written to. In practice, this is not always * true, so we initilize C to zeros for safety. */ if (scale2 == 0.0) zero_mat(C); /* * Work through the blocks one at a time. */ for (blk=1; blk<=A.nblocks; blk++) { switch (A.blocks[blk].blockcategory) { case DIAG: if (scale2 != 0.0) { for (i=1; i<=A.blocks[blk].blocksize; i++) { C.blocks[blk].data.vec[i]=scale1*A.blocks[blk].data.vec[i] *B.blocks[blk].data.vec[i] +scale2*C.blocks[blk].data.vec[i]; }; } else { for (i=1; i<=A.blocks[blk].blocksize; i++) { C.blocks[blk].data.vec[i]=scale1*A.blocks[blk].data.vec[i] *B.blocks[blk].data.vec[i]; }; }; break; case MATRIX: /* * Call dgemm to do the matrix multiplication. */ n=A.blocks[blk].blocksize; ap=A.blocks[blk].data.mat; bp=B.blocks[blk].data.mat; cp=C.blocks[blk].data.mat; mat_mult_raw(n,scale1,scale2,ap,bp,cp); break; default: printf("mat_mult illegal block type!\n"); exit(206); }; }; } void mat_mult_raw(n,scale1,scale2,ap,bp,cp) int n; double scale1; double scale2; double *ap; double *bp; double *cp; { #ifdef HIDDENSTRLEN dgemm_("N","N",&n,&n,&n,&scale1,ap,&n,bp,&n,&scale2,cp,&n,1,1); #else #ifdef NOUNDERBLAS #ifdef CAPSBLAS DGEMM("N","N",&n,&n,&n,&scale1,ap,&n,bp,&n,&scale2,cp,&n); #else dgemm("N","N",&n,&n,&n,&scale1,ap,&n,bp,&n,&scale2,cp,&n); #endif #else #ifdef CAPSBLAS DGEMM_("N","N",&n,&n,&n,&scale1,ap,&n,bp,&n,&scale2,cp,&n); #else dgemm_("N","N",&n,&n,&n,&scale1,ap,&n,bp,&n,&scale2,cp,&n); #endif #endif #endif } #ifdef USEATLAS void mat_mult_rawatlas(n,scale1,scale2,ap,bp,cp) int n; double scale1; double scale2; double *ap; double *bp; double *cp; { enum CBLAS_ORDER {CblasRowMajor=101, CblasColMajor=102 }; enum CBLAS_TRANSPOSE {CblasNoTrans=111, CblasTrans=112, CblasConjTrans=113, AtlasConj=114}; void ATL_dgemm(enum CBLAS_TRANSPOSE transa,enum CBLAS_TRANSPOSE transb, int m,int n, int k,double scale1,double *ap,int l,double *bp, int p,double scale2,double *cp,int q); ATL_dgemm(CblasNoTrans,CblasNoTrans,n,n,n,scale1,ap,n,bp,n,scale2,cp,n); } #endif Csdp-6.2.0/lib/psd_feas.c0000644000175200017520000000343010455242355013561 0ustar coincoin/* Check a primal dual solution for strict feasibility. Return 1 if feasible, and 0 if not. */ #include #include "declarations.h" /* * This routine computes the relative primal infeasibility. */ double pinfeas(k,constraints,X,a,workvec) int k; struct constraintmatrix *constraints; struct blockmatrix X; double *a; double *workvec; { double nrme; double nrma; int i; /* * First, check that A(X)=a. */ op_a(k,constraints,X,workvec); nrma=norm2(k,a+1); for (i=1; i<=k; i++) workvec[i]=workvec[i]-a[i]; nrme=norm2(k,workvec+1); return(nrme/(1.0+nrma)); } double dinfeas(k,C,constraints,y,Z,work1) int k; struct blockmatrix C; struct constraintmatrix *constraints; double *y; struct blockmatrix Z; struct blockmatrix work1; { double nrme; double nrmC; /* * Next, check that A'(y)-C=Z */ zero_mat(work1); op_at(k,y,constraints,work1); addscaledmat(work1,-1.0,C,work1); addscaledmat(work1,-1.0,Z,work1); /* Now, we've got the error in workn1. We'll compute the F norm of this error and compare it to the F norm of C. */ nrme=Fnorm(work1); nrmC=Fnorm(C); return(nrme/(1+nrmC)); } double dimacserr3(k,C,constraints,y,Z,work1) int k; struct blockmatrix C; struct constraintmatrix *constraints; double *y; struct blockmatrix Z; struct blockmatrix work1; { double nrme; /* * Next, check that A'(y)-C=Z */ zero_mat(work1); op_at(k,y,constraints,work1); addscaledmat(work1,-1.0,C,work1); addscaledmat(work1,-1.0,Z,work1); /* Now, we've got the error in workn1. We'll compute the F norm of this error and compare it to the F norm of C. */ nrme=Knorm(work1); return(nrme/(1+matinfnorm(C))); } Csdp-6.2.0/lib/chol.c0000644000175200017520000000705313132530655012725 0ustar coincoin/* Calculate the inverse of an n by n matrix A. A is assumed to be symmetric and positive definite. The original matrix A is destroyed in the process. On return, A is certified to be symmetric and positive definite. */ #include #include #include #include "declarations.h" int chol_blk(n,lda,A) int n; int lda; double *A; { int info; int i; int j; info=0; #ifdef HIDDENSTRLEN dpotrf_("U",&n,A,&lda,&info,1); #else #ifdef HIDDENSTRLEN dpotrf_("U",&n,A,&lda,&info,1); #else #ifdef NOUNDERLAPACK #ifdef CAPSLAPACK DPOTRF("U",&n,A,&lda,&info); #else dpotrf("U",&n,A,&lda,&info); #endif #else #ifdef CAPSLAPACK DPOTRF_("U",&n,A,&lda,&info); #else dpotrf_("U",&n,A,&lda,&info); #endif #endif #endif #endif if (info != 0) { return(1); }; /* * Now, make sure that the lower triangle of A is 0.0 */ for (j=1; j #include #include "declarations.h" #ifdef USEOPENMP #include #endif /* * This #define parameter determines how sparse a block must be to be * considered sparse. You can change it by compiling with * -DSPARSELIM= * * 0.01 was selected without much tuning. On maxG11, performance is * better with SPARSELIM=0.01 than 0.0, but it isn't clear whether this * should be made larger. * * For that matter, it isn't clear whether there should be separate * limits for each type of sparse matrix multiply. */ #ifndef SPARSELIMA #define SPARSELIMA 0.01 #endif #ifndef SPARSELIMB #define SPARSELIMB 0.01 #endif #ifndef SPARSELIMC #define SPARSELIMC 0.01 #endif void mat_multspb(scale1,scale2,A,B,C,fill) double scale1,scale2; struct blockmatrix A,B,C; struct constraintmatrix fill; { int blk,i,ii,j; int blksize,p,q; struct sparseblock *ptr; double temp; int total_threads; int thread_num; if (scale2 == 0.0) { zero_mat(C); /* * if scale1 also is zero, then we just zero'd out C. */ if (scale1 == 0.0) return; /* * Now, multiply A*B and add it in. */ ptr=fill.blocks; while (ptr != NULL) { blk=ptr->blocknum; switch (A.blocks[blk].blockcategory) { case DIAG: for (i=1; i<=A.blocks[blk].blocksize; i++) C.blocks[blk].data.vec[i]=scale1*A.blocks[blk].data.vec[i]* B.blocks[blk].data.vec[i]; break; case MATRIX: blksize=ptr->blocksize; /* * If this matrix is fairly dense, then don't bother with * This approach. */ if (ptr->numentries/(blksize*blksize*1.0) > SPARSELIMB) { /* * A dense block. Do it the old fashioned way. */ mat_mult_raw(blksize,scale1,scale2,A.blocks[blk].data.mat, B.blocks[blk].data.mat,C.blocks[blk].data.mat); } else { #ifdef __GNUC__ #if (((__GNUC__ == 3) && (__GNUC_MINOR__ > 1)) || (__GNUC__ > 3)) __builtin_prefetch(ptr->next,0,3); #endif #endif #ifdef USEOPENMP #pragma omp parallel default(none) private(i,ii,p,q,thread_num,total_threads,temp) shared(ptr,A,B,C,blk,blksize,scale1) { total_threads=omp_get_num_threads(); thread_num=omp_get_thread_num(); for (ii=1; ii<=ptr->numentries; ii++) { q=ptr->jindices[ii]; if ((q % total_threads)==thread_num) { p=ptr->iindices[ii]; temp=scale1*B.blocks[blk].data.mat[ijtok(p,q,blksize)]; for (i=1; i<=blksize; i++) C.blocks[blk].data.mat[ijtok(i,q,blksize)]+=temp* A.blocks[blk].data.mat[ijtok(i,p,blksize)]; }; }; } #pragma omp barrier #else for (ii=1; ii<=ptr->numentries; ii++) { p=ptr->iindices[ii]; q=ptr->jindices[ii]; temp=scale1*B.blocks[blk].data.mat[ijtok(p,q,blksize)]; for (i=1; i<=blksize; i++) C.blocks[blk].data.mat[ijtok(i,q,blksize)]+=temp* A.blocks[blk].data.mat[ijtok(i,p,blksize)]; }; #endif }; break; case PACKEDMATRIX: default: printf("mat_multsp illegal block type \n"); exit(206); }; /* * Move on to the next block. */ ptr=ptr->next; }; } else { /* * First, scale C by the scale 2 factor. */ for (blk=1; blk<=C.nblocks; blk++) { switch (C.blocks[blk].blockcategory) { case DIAG: for (i=1; i<=C.blocks[blk].blocksize; i++) C.blocks[blk].data.vec[i]=scale2*C.blocks[blk].data.vec[i]; break; case MATRIX: #pragma omp parallel for schedule(dynamic,64) default(none) private(i,j) shared(blk,C,scale2) for (j=1; j<=C.blocks[blk].blocksize; j++) for (i=1; i<=C.blocks[blk].blocksize; i++) C.blocks[blk].data.mat[ijtok(i,j,C.blocks[blk].blocksize)]= scale2*C.blocks[blk].data.mat[ijtok(i,j,C.blocks[blk].blocksize)]; break; case PACKEDMATRIX: default: printf("mat_multsp illegal block type \n"); exit(206); }; }; /* * if scale1 is zero, then we're done. */ if (scale1 == 0.0) return; /* * Now, multiply A*B and add it in. */ ptr=fill.blocks; while (ptr != NULL) { blk=ptr->blocknum; switch (A.blocks[blk].blockcategory) { case DIAG: for (i=1; i<=A.blocks[blk].blocksize; i++) C.blocks[blk].data.vec[i]+=scale1*A.blocks[blk].data.vec[i]* B.blocks[blk].data.vec[i]; break; case MATRIX: blksize=ptr->blocksize; /* * If this matrix is fairly dense, then don't bother with * This approach. */ if (ptr->numentries/(blksize*blksize*1.0) > SPARSELIMB) { /* * A dense block. Do it the old fashioned way. */ mat_mult_raw(blksize,scale1,1.0,A.blocks[blk].data.mat, B.blocks[blk].data.mat,C.blocks[blk].data.mat); } else { #ifdef __GNUC__ #if (((__GNUC__ == 3) && (__GNUC_MINOR__ > 1)) || (__GNUC__ > 3)) __builtin_prefetch(ptr->next,0,3); #endif #endif #ifdef USEOPENMP #pragma omp parallel default(none) private(i,ii,p,q,thread_num,total_threads,temp) shared(ptr,A,B,C,blk,blksize,scale1) { total_threads=omp_get_num_threads(); thread_num=omp_get_thread_num(); for (ii=1; ii<=ptr->numentries; ii++) { q=ptr->jindices[ii]; if ((q % total_threads)==thread_num) { p=ptr->iindices[ii]; temp=scale1*B.blocks[blk].data.mat[ijtok(p,q,blksize)]; for (i=1; i<=blksize; i++) C.blocks[blk].data.mat[ijtok(i,q,blksize)]+=temp* A.blocks[blk].data.mat[ijtok(i,p,blksize)]; }; }; } #pragma omp barrier #else for (ii=1; ii<=ptr->numentries; ii++) { p=ptr->iindices[ii]; q=ptr->jindices[ii]; temp=scale1*B.blocks[blk].data.mat[ijtok(p,q,blksize)]; for (i=1; i<=blksize; i++) C.blocks[blk].data.mat[ijtok(i,q,blksize)]+=temp* A.blocks[blk].data.mat[ijtok(i,p,blksize)]; }; #endif }; break; case PACKEDMATRIX: default: printf("mat_multsp illegal block type \n"); exit(206); }; /* * Move on to the next block. */ ptr=ptr->next; }; }; } /* * This version of mat_mult is specialized for sparse A matrices. */ void mat_multspa(scale1,scale2,A,B,C,fill) double scale1,scale2; struct blockmatrix A,B,C; struct constraintmatrix fill; { int blk,i,j,ii; int blksize,p,q; struct sparseblock *ptr; double temp; int total_threads; int thread_num; if (scale2 == 0.0) { zero_mat(C); /* * if scale1 also is zero, then we just zero'd out C. */ if (scale1 == 0.0) return; /* * Now, multiply A*B and add it in. */ ptr=fill.blocks; while (ptr != NULL) { blk=ptr->blocknum; switch (A.blocks[blk].blockcategory) { case DIAG: for (i=1; i<=A.blocks[blk].blocksize; i++) C.blocks[blk].data.vec[i]=scale1*A.blocks[blk].data.vec[i]* B.blocks[blk].data.vec[i]; break; case MATRIX: blksize=ptr->blocksize; /* * If this matrix is fairly dense, then don't bother with * This approach. */ if (ptr->numentries/(blksize*blksize*1.0) > SPARSELIMA) { /* * A dense block. Do it the old fashioned way. */ mat_mult_raw(blksize,scale1,scale2,A.blocks[blk].data.mat, B.blocks[blk].data.mat,C.blocks[blk].data.mat); } else { #ifdef __GNUC__ #if (((__GNUC__ == 3) && (__GNUC_MINOR__ > 1)) || (__GNUC__ > 3)) __builtin_prefetch(ptr->next,0,3); #endif #endif #ifdef USEOPENMP #pragma omp parallel default(none) private(i,ii,p,q,thread_num,total_threads,temp) shared(ptr,A,B,C,blk,blksize,scale1) { total_threads=omp_get_num_threads(); thread_num=omp_get_thread_num(); for (ii=1; ii<=ptr->numentries; ii++) { p=ptr->iindices[ii]; if ((p % total_threads) == thread_num) { q=ptr->jindices[ii]; temp=scale1*A.blocks[blk].data.mat[ijtok(p,q,blksize)]; for (i=1; i<=ptr->blocksize; i++) C.blocks[blk].data.mat[ijtok(p,i,blksize)]+=temp* B.blocks[blk].data.mat[ijtok(i,q,blksize)]; }; }; } #pragma omp barrier #else for (ii=1; ii<=ptr->numentries; ii++) { p=ptr->iindices[ii]; q=ptr->jindices[ii]; temp=scale1*A.blocks[blk].data.mat[ijtok(p,q,blksize)]; for (i=1; i<=ptr->blocksize; i++) C.blocks[blk].data.mat[ijtok(p,i,blksize)]+=temp* B.blocks[blk].data.mat[ijtok(i,q,blksize)]; }; #endif }; break; case PACKEDMATRIX: default: printf("mat_multsp illegal block type \n"); exit(206); }; /* * Move on to the next block. */ ptr=ptr->next; }; } else { /* * First, scale C by the scale 1 factor. */ for (blk=1; blk<=C.nblocks; blk++) { switch (C.blocks[blk].blockcategory) { case DIAG: for (i=1; i<=C.blocks[blk].blocksize; i++) C.blocks[blk].data.vec[i]=scale2*C.blocks[blk].data.vec[i]; break; case MATRIX: #pragma omp parallel for default(none) schedule(dynamic,64) private(i,j) shared(blk,C,scale2) for (j=1; j<=C.blocks[blk].blocksize; j++) for (i=1; i<=C.blocks[blk].blocksize; i++) C.blocks[blk].data.mat[ijtok(i,j,C.blocks[blk].blocksize)]= scale2*C.blocks[blk].data.mat[ijtok(i,j,C.blocks[blk].blocksize)]; break; case PACKEDMATRIX: default: printf("mat_multsp illegal block type \n"); exit(206); }; }; /* * if scale1 is zero, then we're done. */ if (scale1 == 0.0) return; /* * Now, multiply A*B and add it in. */ ptr=fill.blocks; while (ptr != NULL) { blk=ptr->blocknum; switch (A.blocks[blk].blockcategory) { case DIAG: for (i=1; i<=A.blocks[blk].blocksize; i++) C.blocks[blk].data.vec[i]+=scale1*A.blocks[blk].data.vec[i]* B.blocks[blk].data.vec[i]; break; case MATRIX: blksize=ptr->blocksize; /* * If this matrix is fairly dense, then don't bother with * This approach. */ if (ptr->numentries/(blksize*blksize*1.0) > SPARSELIMA) { /* * A dense block. Do it the old fashioned way. */ mat_mult_raw(blksize,scale1,1.0,A.blocks[blk].data.mat, B.blocks[blk].data.mat,C.blocks[blk].data.mat); } else { #ifdef __GNUC__ #if (((__GNUC__ == 3) && (__GNUC_MINOR__ > 1)) || (__GNUC__ > 3)) __builtin_prefetch(ptr->next,0,3); #endif #endif #ifdef USEOPENMP #pragma omp parallel default(none) private(i,ii,p,q,thread_num,total_threads,temp) shared(ptr,A,B,C,blk,blksize,scale1) { total_threads=omp_get_num_threads(); thread_num=omp_get_thread_num(); for (ii=1; ii<=ptr->numentries; ii++) { p=ptr->iindices[ii]; if ((p % total_threads) == thread_num) { q=ptr->jindices[ii]; temp=scale1*A.blocks[blk].data.mat[ijtok(p,q,blksize)]; for (i=1; i<=ptr->blocksize; i++) C.blocks[blk].data.mat[ijtok(p,i,blksize)]+=temp* B.blocks[blk].data.mat[ijtok(i,q,blksize)]; }; }; } #pragma omp barrier #else for (ii=1; ii<=ptr->numentries; ii++) { p=ptr->iindices[ii]; q=ptr->jindices[ii]; temp=scale1*A.blocks[blk].data.mat[ijtok(p,q,blksize)]; for (i=1; i<=ptr->blocksize; i++) C.blocks[blk].data.mat[ijtok(p,i,blksize)]+=temp* B.blocks[blk].data.mat[ijtok(i,q,blksize)]; }; #endif }; break; case PACKEDMATRIX: default: printf("mat_multsp illegal block type \n"); exit(206); }; /* * Move on to the next block. */ ptr=ptr->next; }; }; } /* * This version of mat_mult is specialized for sparse C matrices. * It only generates the elements in the result C corresponding * to elements described in fill. */ void mat_multspc(scale1,scale2,A,B,C,fill) double scale1,scale2; struct blockmatrix A,B,C; struct constraintmatrix fill; { int blk,i,j,ii; int blksize,p,q; struct sparseblock *ptr; double temp; /* * To protect against bad implementations of the BLAS that don't handle * scale2=0 in dgemv well. */ if (scale2 == 0.0) { /* * To protect against bad implementations of the BLAS that don't handle * scale2=0 in dgemv well. */ zero_mat(C); /* * Now, multiply A*B and add it in. */ ptr=fill.blocks; while (ptr != NULL) { blk=ptr->blocknum; switch (A.blocks[blk].blockcategory) { case DIAG: for (i=1; i<=A.blocks[blk].blocksize; i++) C.blocks[blk].data.vec[i]=scale1*A.blocks[blk].data.vec[i]* B.blocks[blk].data.vec[i]; break; case MATRIX: blksize=ptr->blocksize; /* * If this matrix is fairly dense, then don't bother with * This approach. */ if (ptr->numentries/(blksize*blksize*1.0) > SPARSELIMC) { /* * A dense block. Do it the old fashioned way. */ mat_mult_raw(blksize,scale1,scale2,A.blocks[blk].data.mat, B.blocks[blk].data.mat,C.blocks[blk].data.mat); } else { #ifdef __GNUC__ #if (((__GNUC__ == 3) && (__GNUC_MINOR__ > 1)) || (__GNUC__ > 3)) __builtin_prefetch(ptr->next,0,3); #endif #endif #pragma omp parallel for schedule(dynamic,64) default(none) private(i,ii,p,q,temp) shared(ptr,A,B,C,blk,blksize,scale1) for (ii=1; ii<=ptr->numentries; ii++) { p=ptr->iindices[ii]; q=ptr->jindices[ii]; temp=0; for (i=1; i<=ptr->blocksize; i++) temp+= A.blocks[blk].data.mat[ijtok(i,p,blksize)]* B.blocks[blk].data.mat[ijtok(i,q,blksize)]; C.blocks[blk].data.mat[ijtok(p,q,blksize)]=temp*scale1; }; }; break; case PACKEDMATRIX: default: printf("mat_multsp illegal block type \n"); exit(206); }; /* * Move on to the next block. */ ptr=ptr->next; }; } else { /* * First, scale C by the scale 2 factor. */ for (blk=1; blk<=C.nblocks; blk++) { switch (C.blocks[blk].blockcategory) { case DIAG: for (i=1; i<=C.blocks[blk].blocksize; i++) C.blocks[blk].data.vec[i]=scale2*C.blocks[blk].data.vec[i]; break; case MATRIX: #pragma omp parallel for default(none) schedule(dynamic,64) private(i,j) shared(blk,C,scale2) for (j=1; j<=C.blocks[blk].blocksize; j++) for (i=1; i<=C.blocks[blk].blocksize; i++) C.blocks[blk].data.mat[ijtok(i,j,C.blocks[blk].blocksize)]= scale2*C.blocks[blk].data.mat[ijtok(i,j,C.blocks[blk].blocksize)]; break; case PACKEDMATRIX: default: printf("mat_multsp illegal block type \n"); exit(206); }; }; /* * Now, multiply A*B and add it in. */ ptr=fill.blocks; while (ptr != NULL) { blk=ptr->blocknum; switch (A.blocks[blk].blockcategory) { case DIAG: for (i=1; i<=A.blocks[blk].blocksize; i++) C.blocks[blk].data.vec[i]+=scale1*A.blocks[blk].data.vec[i]* B.blocks[blk].data.vec[i]; break; case MATRIX: blksize=ptr->blocksize; /* * If this matrix is fairly dense, then don't bother with * This approach. */ if (ptr->numentries/(blksize*blksize*1.0) > SPARSELIMC) { /* * A dense block. Do it the old fashioned way. */ mat_mult_raw(blksize,scale1,scale2,A.blocks[blk].data.mat, B.blocks[blk].data.mat,C.blocks[blk].data.mat); } else { #ifdef __GNUC__ #if (((__GNUC__ == 3) && (__GNUC_MINOR__ > 1)) || (__GNUC__ > 3)) __builtin_prefetch(ptr->next,0,3); #endif #endif for (ii=1; ii<=ptr->numentries; ii++) { /* p=ptr->iindices[ii]; q=ptr->jindices[ii]; for (i=1; i<=ptr->blocksize; i++) C.blocks[blk].data.mat[ijtok(p,q,blksize)]+=scale1* A.blocks[blk].data.mat[ijtok(p,i,blksize)]* B.blocks[blk].data.mat[ijtok(i,q,blksize)]; */ p=ptr->iindices[ii]; q=ptr->jindices[ii]; temp=0; for (i=1; i<=ptr->blocksize; i++) temp+= A.blocks[blk].data.mat[ijtok(i,p,blksize)]* B.blocks[blk].data.mat[ijtok(i,q,blksize)]; C.blocks[blk].data.mat[ijtok(p,q,blksize)]+=temp*scale1; }; }; break; case PACKEDMATRIX: default: printf("mat_multsp illegal block type \n"); exit(206); }; /* * Move on to the next block. */ ptr=ptr->next; }; }; } Csdp-6.2.0/lib/solvesys.c0000644000175200017520000000151113120331773013655 0ustar coincoin/* Solve a system of equations using the Cholesky factorization of A. Note that we assume that A is positive definite and that A has already been factored. */ #include #include #include "declarations.h" int solvesys(m,ldam,A,rhs) int m; int ldam; double *A; double *rhs; { int incx; int info; incx=1; #ifdef HIDDENSTRLEN dpotrs_("U",&m,&incx,A,&ldam,rhs+1,&ldam,&info,1); #else #ifdef NOUNDERLAPACK #ifdef CAPSLAPACK DPOTRS("U",&m,&incx,A,&ldam,rhs+1,&ldam,&info); #else dpotrs("U",&m,&incx,A,&ldam,rhs+1,&ldam,&info); #endif #else #ifdef CAPSLAPACK DPOTRS_("U",&m,&incx,A,&ldam,rhs+1,&ldam,&info); #else dpotrs_("U",&m,&incx,A,&ldam,rhs+1,&ldam,&info); #endif #endif #endif if (info != 0) { return(6); }; return(0); } Csdp-6.2.0/lib/packed.c0000644000175200017520000001002013132530655013213 0ustar coincoin/* * This file contains routines for manipulating block matrices with blocks * stored in LAPACK's packed storage scheme. */ #include #include #include "declarations.h" void store_packed(A,B) struct blockmatrix A,B; { int blk,i,j,n; double *p; double *q; for (blk=1; blk<=A.nblocks; blk++) { switch (A.blocks[blk].blockcategory) { case DIAG: p=A.blocks[blk].data.vec; q=B.blocks[blk].data.vec; n=A.blocks[blk].blocksize; for (i=1; i<=n; i++) q[i]=p[i]; break; case MATRIX: p=A.blocks[blk].data.mat; q=B.blocks[blk].data.mat; n=A.blocks[blk].blocksize; #pragma omp parallel for schedule(dynamic,64) private(i,j) shared(p,q,n) for (j=1; j<=n; j++) for (i=1; i<=j; i++) q[ijtokp(i,j,n)]=p[ijtok(i,j,n)]; break; default: printf("store_packed illegal block type \n"); exit(206); }; } } void store_unpacked(A,B) struct blockmatrix A,B; { int blk,i,j,n; double *p; double *q; for (blk=1; blk<=A.nblocks; blk++) { switch (A.blocks[blk].blockcategory) { case DIAG: p=A.blocks[blk].data.vec; q=B.blocks[blk].data.vec; n=A.blocks[blk].blocksize; for (i=1; i<=n; i++) q[i]=p[i]; break; case PACKEDMATRIX: p=A.blocks[blk].data.mat; q=B.blocks[blk].data.mat; n=A.blocks[blk].blocksize; #pragma omp parallel for schedule(dynamic,64) private(i,j) shared(p,q,n) for (j=1; j<=n; j++) for (i=1; i<=j; i++) q[ijtok(i,j,n)]=p[ijtokp(i,j,n)]; for (j=1; jnblocks=A.nblocks; /* * Then allocate space for the block records. */ pB->blocks=(struct blockrec *)malloc(sizeof(struct blockrec)*(A.nblocks+1)); if (pB->blocks == NULL) { printf("Storage allocation failed!\n"); exit(205); }; /* * Now, fill in the info for each block. */ for (blk=1; blk <=A.nblocks; blk++) { switch (A.blocks[blk].blockcategory) { case DIAG: pB->blocks[blk].blockcategory=A.blocks[blk].blockcategory; pB->blocks[blk].blocksize=A.blocks[blk].blocksize; pB->blocks[blk].data.vec=(double *)malloc(sizeof(double)*(A.blocks[blk].blocksize+1)); if (pB->blocks[blk].data.vec == NULL) { printf("Storage allocation failed!\n"); exit(205); }; break; case MATRIX: n=A.blocks[blk].blocksize; pB->blocks[blk].blockcategory=PACKEDMATRIX; pB->blocks[blk].blocksize=n; pB->blocks[blk].data.mat=(double *)malloc(sizeof(double)*n*(n+1)/2); if (pB->blocks[blk].data.mat == NULL) { printf("Storage allocation failed!\n"); exit(205); }; break; default: printf("Illegal block type!\n"); exit(206); }; }; } void free_mat_packed(A) struct blockmatrix A; { int blk; /* * First, free the space for each block. */ for (blk=1; blk <=A.nblocks; blk++) { switch (A.blocks[blk].blockcategory) { case DIAG: free(A.blocks[blk].data.vec); break; case PACKEDMATRIX: free(A.blocks[blk].data.mat); break; default: printf("Illegal block type!\n"); exit(206); }; }; /* * Then free space for the block records. */ free(A.blocks); } void triu(A) struct blockmatrix A; { int i,j,n; int blk; for (blk=1; blk <= A.nblocks; blk++) { switch (A.blocks[blk].blockcategory) { case DIAG: break; case MATRIX: n=A.blocks[blk].blocksize; #pragma omp parallel for schedule(dynamic,64) private(i,j) shared(A,n) for (j=1; j #include #include "declarations.h" void skip_to_end_of_line(); int read_sol(fname,n,k,C,pX,py,pZ) char *fname; int n; int k; struct blockmatrix C; struct blockmatrix *pX; double **py; struct blockmatrix *pZ; { FILE *fid; int i; int indexi; int indexj; int blkno; int matno; double ent; int ret; /* * Allocate storage. */ alloc_mat(C,pX); alloc_mat(C,pZ); *py=(double *)malloc(sizeof(double)*(k+1)); if (*py == NULL) { printf("Storage allocation failed!\n"); exit(205); }; /* * Open the file for reading. */ fid=fopen(fname,"r"); if (fid == (FILE *) NULL) { printf("Couldn't open solution file for reading. \n"); exit(202); }; /* * Read in y. */ for (i=1; i<=k; i++) { ret=fscanf(fid,"%le",&((*py)[i])); if (ret != 1) { printf("Reading solution failed, while reading y. ret=%d\n",ret); return(1); }; }; skip_to_end_of_line(fid); /* * Initialize X and Z to 0. */ zero_mat(*pX); zero_mat(*pZ); /* * Read in the rest of the data. */ do { ret=fscanf(fid,"%d %d %d %d %le",&matno,&blkno,&indexi,&indexj,&ent); if ((ret != 5) && (ret != EOF)) { printf("Bad line in solution file: %d %d %d %d %e\n", matno,blkno,indexi,indexj,ent); fclose(fid); return(1); }; if (matno == 1) { switch (pZ->blocks[blkno].blockcategory) { case DIAG: pZ->blocks[blkno].data.vec[indexi]=ent; break; case MATRIX: pZ->blocks[blkno].data.mat[ijtok(indexi,indexj,pZ->blocks[blkno].blocksize)]=ent; pZ->blocks[blkno].data.mat[ijtok(indexj,indexi,pZ->blocks[blkno].blocksize)]=ent; break; default: printf("Illegal block type! \n"); exit(206); }; } else { switch (pX->blocks[blkno].blockcategory) { case DIAG: pX->blocks[blkno].data.vec[indexi]=ent; break; case MATRIX: pX->blocks[blkno].data.mat[ijtok(indexi,indexj,pX->blocks[blkno].blocksize)]=ent; pX->blocks[blkno].data.mat[ijtok(indexj,indexi,pX->blocks[blkno].blocksize)]=ent; break; default: printf("Illegal block type! \n"); exit(206); }; }; } while (ret != EOF); fclose(fid); return(0); } Csdp-6.2.0/lib/op_o.c0000644000175200017520000002647713132530655012747 0ustar coincoin/* * Compute a matrix representation of the operator * * O(.)=A(inv(Z)*A'(.)*X) * * The ith colum of the result is O(e_i), where e_i is the vector with a 1 in * position i and 0's elsewhere. * */ #include #include #include #ifdef USEOPENMP #include #endif #include "declarations.h" void op_o(k, constraints, byblocks, Zi, X, O, work1, work2) int k; struct constraintmatrix *constraints; struct sparseblock **byblocks; struct blockmatrix Zi; struct blockmatrix X; double *O; struct blockmatrix work1; struct blockmatrix work2; { int i, j; int ii, jj; int ldam; int p, q, r, s; struct sparseblock *ptri; struct sparseblock *ptrj; int blocknum; int blocksize; double contrib; double *Ziblk; double *Xblk; double *workblk; double *work2blk; double enti, entj, scale1, scale2; int max_blknum = 0, max_blksize = 0; int thread_num; static double **work; int max_threads; /* * Get the maximum number of threads. */ #ifdef USEOPENMP max_threads=omp_get_max_threads(); #else max_threads=1; #endif /* Allocate more memory for the number of work matrices needed. */ /* Find the largest nondiagonal block */ for (blocknum = 1; blocknum <= X.nblocks; blocknum++) { if (X.blocks[blocknum].blockcategory != DIAG && X.blocks[blocknum].blocksize > max_blksize) { max_blknum = blocknum; max_blksize = X.blocks[blocknum].blocksize; }; }; /* * If we have at least one dense block, we must allocate memory for work * matrices. */ if (max_blknum > 0) { work = (double **) malloc(sizeof(double *) * (max_threads * 2 + 1)); if (work == NULL) { printf("Failed to allocate memory for parallel execution (1)!\n"); printf("omp_get_max_threads() was %d \n",max_threads); exit(205); } work[1] = work1.blocks[max_blknum].data.mat; work[2] = work2.blocks[max_blknum].data.mat; for (i = 1; i < max_threads; i++) { work[i * 2 + 1] = (double *) malloc(sizeof(double) * X.blocks[max_blknum].blocksize * X.blocks[max_blknum].blocksize); work[i * 2 + 2] = (double *) malloc(sizeof(double) * X.blocks[max_blknum].blocksize * X.blocks[max_blknum].blocksize); if (work[i * 2 + 1] == NULL || work[i * 2 + 2] == NULL) { printf("Failed to allocate memory for parallel execution (2)!\n"); printf("max_blksize is %d \n",max_blksize); printf("omp_get_max_threads() was %d \n",max_threads); exit(205); }; }; }; /* * Work out the leading dimension for the array. Note that we may not want * to use k itself, for cache issues. */ if ((k % 2) == 0) ldam = k + 1; else ldam = k; /* * First, zero out the O matrix. */ #pragma omp parallel for schedule(dynamic,64) default(none) shared(O,ldam,k) private(j,i) for (j = 1; j <= k; j++) for (i = 1; i <= k; i++) O[ijtok(i, j, (long int) ldam)] = 0.0; /* Loop over i, then the blocks, then j */ #ifdef USEOPENMP #ifdef SETNUMTHREADS omp_set_num_threads(omp_get_max_threads()); #endif #endif #pragma omp parallel for schedule(dynamic,64) default(none) shared(k,constraints,byblocks,Zi,X,O,work1, work2, work, ldam) private(j, ii, jj, blocksize, p, q, r, s, ptri, ptrj, blocknum, contrib, Ziblk, Xblk, workblk, work2blk, enti, entj, scale1, scale2, thread_num) for (i = 1; i <= k; i++) { #ifdef USEOPENMP #ifdef SETNUMTHREADS /* Only use one thread in the inner loop. */ omp_set_num_threads(1); #endif #endif ptri = constraints[i].blocks; while (ptri != NULL) { blocknum = ptri->blocknum; blocksize = ptri->blocksize; /* Diagonal blocks */ if (ptri->issparse == 1 && X.blocks[blocknum].blockcategory == DIAG) { Ziblk = Zi.blocks[blocknum].data.vec; Xblk = X.blocks[blocknum].data.vec; ptrj = ptri; while (ptrj != NULL) { j = ptrj->constraintnum; /* * Do the contribution from constraints i and j of this block. */ contrib = 0.0; p = 1; q = 1; while ((p <= ptri->numentries) && (q <= ptrj->numentries)) { if (ptri->iindices[p] < ptrj->iindices[q]) { p = p + 1; } else { if (ptri->iindices[p] > ptrj->iindices[q]) { q = q + 1; } else { /* * Match! */ contrib += ptri->entries[p] * ptrj->entries[q] * Ziblk[ptri->iindices[p]] * Xblk[ptri->iindices[p]]; p = p + 1; q = q + 1; }; }; }; O[ijtok(i, j, (long int) ldam)] += contrib; /* Next j */ ptrj = ptrj->nextbyblock; } } /* Sparse matrix block */ else if (ptri->issparse == 1 && X.blocks[blocknum].blockcategory == MATRIX) { Ziblk = Zi.blocks[blocknum].data.mat; Xblk = X.blocks[blocknum].data.mat; ptrj = ptri; while (ptrj != NULL) { /* Only process sparse-sparse pairs. */ if (ptrj->issparse == 1) { j = ptrj->constraintnum; /* * The following prefetch seems to give about a 5% performance * improvement on certain problems. e.g. truss8 on a 1200 Mhz * Athlon. * * It won't be compiled unless we're using gcc. */ #ifdef __GNUC__ #if (((__GNUC__ == 3) && (__GNUC_MINOR__ > 1)) || (__GNUC__ > 3)) __builtin_prefetch(ptrj->nextbyblock, 0, 3); #endif #endif /* * Do the contribution from constraints i and j of this block. */ contrib = 0.0; for (ii = 1; ii <= ptri->numentries; ii++) { enti = ptri->entries[ii]; p = ptri->iindices[ii]; q = ptri->jindices[ii]; /* * We'll keep the p==q test outside of the inner loop. * * In what follows, we've made use of the symmetry of Ziblk and * Xblk, by permuting all array indices so that p and q are * last. This means that we stay in columns p and q of Ziblk * and Xblk as much as possible, improving locality. * */ if (p == q) { for (jj = 1; jj <= ptrj->numentries; jj++) { entj = ptrj->entries[jj]; r = ptrj->iindices[jj]; s = ptrj->jindices[jj]; if (r == s) { /* here p==q, r==s */ contrib += enti * entj * Ziblk[ijtok(r, q, blocksize)] * Xblk[ijtok(s, p, blocksize)]; } else { /* here p=q, r!=s */ contrib += enti * entj * (Ziblk[ijtok(r, q, blocksize)] * Xblk[ijtok(s, p, blocksize)] + Ziblk[ijtok(s, q, blocksize)] * Xblk[ijtok(r, p, blocksize)]); } } } else { /* p!= q */ for (jj = 1; jj <= ptrj->numentries; jj++) { entj = ptrj->entries[jj]; r = ptrj->iindices[jj]; s = ptrj->jindices[jj]; if (r == s) { /* p!=q, but r=s */ contrib += enti * entj * (Ziblk[ijtok(r, q, blocksize)] * Xblk[ijtok(s, p, blocksize)] + Ziblk[ijtok(r, p, blocksize)] * Xblk[ijtok(s, q, blocksize)]); } else { /* here, p!=q and r!=s */ contrib += enti * entj * (Ziblk[ijtok(r, q, blocksize)] * Xblk[ijtok(s, p, blocksize)] + Ziblk[ijtok(r, p, blocksize)] * Xblk[ijtok(s, q, blocksize)] + Ziblk[ijtok(s, q, blocksize)] * Xblk[ijtok(r, p, blocksize)] + Ziblk[ijtok(s, p, blocksize)] * Xblk[ijtok(r, q, blocksize)]); } } } } O[ijtok(i, j, (long int) ldam)] += contrib; } ptrj = ptrj->nextbyblock; } } /* Dense matrix block */ else { /* * put this block into a work matrix. */ #ifdef USEOPENMP thread_num = omp_get_thread_num(); #else thread_num=0; #endif workblk = work[thread_num * 2 + 1]; work2blk = work[thread_num * 2 + 2]; Xblk = X.blocks[blocknum].data.mat; Ziblk = Zi.blocks[blocknum].data.mat; for (ii = 0; ii <= blocksize * blocksize - 1; ii++) { workblk[ii] = 0.0; } for (ii = 1; ii <= ptri->numentries; ii++) { enti = ptri->entries[ii]; p = ptri->iindices[ii]; q = ptri->jindices[ii]; workblk[ijtok(p, q, blocksize)] = enti; if (p != q) workblk[ijtok(q, p, blocksize)] = enti; } /* * Now, multiply out Zi*work*X. */ scale1 = 1.0; scale2 = 0.0; #ifdef USEATLAS mat_mult_rawatlas(blocksize, scale1, scale2, Ziblk, workblk, work2blk); mat_mult_rawatlas(blocksize, scale1, scale2, work2blk, Xblk, workblk); #else mat_mult_raw(blocksize, scale1, scale2, Ziblk, workblk, work2blk); mat_mult_raw(blocksize, scale1, scale2, work2blk, Xblk, workblk); #endif ptrj = byblocks[blocknum]; while (ptrj != NULL) { j = ptrj->constraintnum; /* * Compute if block j is sparse; block j is dense, but block i has * more elements; or, if both blocks have the same number of * elements, and the constraint number of block i is less than or * equal to j */ if (ptrj->issparse == 1 || ptri->numentries > ptrj->numentries || (ptri->numentries == ptrj->numentries && i <= j)) { contrib = 0.0; /* * Another GCC prefetch for improved performance. It won't be * compiled unless we're using gcc. */ #ifdef __GNUC__ #if (((__GNUC__ == 3) && (__GNUC_MINOR__ > 1)) || (__GNUC__ > 3)) __builtin_prefetch(ptrj->nextbyblock, 0, 3); #endif #endif for (ii = 1; ii <= ptrj->numentries; ii++) { entj = ptrj->entries[ii]; p = ijtok(ptrj->iindices[ii], ptrj->jindices[ii], blocksize); q = ijtok(ptrj->jindices[ii], ptrj->iindices[ii], blocksize); contrib += entj * workblk[p]; if (p != q) { contrib += entj * workblk[q]; }; }; /* * Depending on the relative values of i and j, this may leave * the update below the diagonal. However, we'll go back through * and pickup such updates at the end. By doing this, we * ensure that there are no conflicts between threads- each row * of O belongs to only one thread of gang handling the for i * loop, so we don't need to use #pragma atomic here. */ O[ijtok(i,j, (long int) ldam)] +=contrib; } ptrj = ptrj->nextbyblock; } } ptri = ptri->next; } } /* Make sure the number of threads is at maximum. */ #ifdef USEOPENMP #ifdef SETNUMTHREADS omp_set_num_threads(omp_get_max_threads()); #endif #endif /* * Go back and pick up any updates that were left below the diagonal. */ #pragma omp parallel for schedule(dynamic,64) default(none) shared(O,ldam,k) private(j,i) for (j = 2; j <= k; j++) for (i = 1; i < j; i++) O[ijtok(i, j, (long int) ldam)] += O[ijtok(j,i, (long int) ldam)]; /* * Free storage allocated for parallel work space. */ if (max_blknum>0) { for (i=1; i< max_threads; i++) { free(work[i*2+1]); free(work[i*2+2]); }; free(work); }; } Csdp-6.2.0/lib/allocmat.c0000644000175200017520000000361013132530655013567 0ustar coincoin/* * Allocate space for a block matrix. Get strucutre info from A, and * allocate the matrix B with matching structure. */ #include #include #include "declarations.h" void alloc_mat(A,pB) struct blockmatrix A; struct blockmatrix *pB; { int blk; /* * First put up the number of blocks. */ pB->nblocks=A.nblocks; /* * Then allocate space for the block records. */ pB->blocks=(struct blockrec *)malloc(sizeof(struct blockrec)*(A.nblocks+1)); if (pB->blocks == NULL) { printf("Storage allocation failed!\n"); exit(205); }; /* * Now, fill in the info for each block. */ for (blk=1; blk <=A.nblocks; blk++) { pB->blocks[blk].blockcategory=A.blocks[blk].blockcategory; pB->blocks[blk].blocksize=A.blocks[blk].blocksize; switch (A.blocks[blk].blockcategory) { case DIAG: pB->blocks[blk].data.vec=(double *)malloc(sizeof(double)*(A.blocks[blk].blocksize+1)); if (pB->blocks[blk].data.vec == NULL) { printf("Storage allocation failed!\n"); exit(205); }; break; case MATRIX: pB->blocks[blk].data.mat=(double *)malloc(sizeof(double)*(A.blocks[blk].blocksize)*(A.blocks[blk].blocksize)); if (pB->blocks[blk].data.mat == NULL) { printf("Storage allocation failed!\n"); exit(205); }; break; default: printf("alloc_mat illegal block type!\n"); exit(206); }; }; } void free_mat(A) struct blockmatrix A; { int blk; /* * First, free the space for each block. */ for (blk=1; blk <=A.nblocks; blk++) { switch (A.blocks[blk].blockcategory) { case DIAG: free(A.blocks[blk].data.vec); break; case MATRIX: free(A.blocks[blk].data.mat); break; default: printf("free_mat illegal block type!\n"); exit(206); }; }; /* * Then free space for the block records. */ free(A.blocks); } Csdp-6.2.0/lib/norms.c0000644000175200017520000000205510455242355013135 0ustar coincoin/* * Calls the blas routine to compute a norm of a vector. */ #include #include "declarations.h" double norm2(n,x) int n; double *x; { double nrm; int incx=1; #ifdef NOUNDERBLAS #ifdef CAPSBLAS nrm=DNRM2(&n,x,&incx); #else nrm=dnrm2(&n,x,&incx); #endif #else #ifdef CAPSBLAS nrm=DNRM2_(&n,x,&incx); #else nrm=dnrm2_(&n,x,&incx); #endif #endif return(nrm); } double norm1(n,x) int n; double *x; { double nrm; int incx=1; #ifdef NOUNDERBLAS #ifdef CAPSBLAS nrm=DASUM(&n,x,&incx); #else nrm=dasum(&n,x,&incx); #endif #else #ifdef CAPSBLAS nrm=DASUM_(&n,x,&incx); #else nrm=dasum_(&n,x,&incx); #endif #endif return(nrm); } double norminf(n,x) int n; double *x; { int i; double nrm; int incx=1; #ifdef NOUNDERBLAS #ifdef CAPSBLAS i=IDAMAX(&n,x,&incx); nrm=fabs(x[i-1]); #else i=idamax(&n,x,&incx); nrm=fabs(x[i-1]); #endif #else #ifdef CAPSBLAS i=IDAMAX_(&n,x,&incx); nrm=fabs(x[i-1]); #else i=idamax_(&n,x,&incx); nrm=fabs(x[i-1]); #endif #endif return(nrm); } Csdp-6.2.0/lib/op_at.c0000644000175200017520000000211210455242355013073 0ustar coincoin/* Compute A'(y). */ #include #include "declarations.h" void op_at(k,y,constraints,result) int k; double *y; struct constraintmatrix *constraints; struct blockmatrix result; { int i,j; #ifndef BIT64 int p,q; #else long int p,q; #endif int blk; double ent; struct sparseblock *ptr; zero_mat(result); for (i=1; i<=k; i++) { if (y[i] == 0.0) { continue; }; ptr=constraints[i].blocks; while (ptr != NULL) { blk=ptr->blocknum; if (result.blocks[blk].blockcategory == DIAG) { for (j=1; j<=ptr->numentries; j++) { ent=ptr->entries[j]; p=ptr->iindices[j]; result.blocks[blk].data.vec[p] += y[i]*ent; }; } else { for (j=1; j<=ptr->numentries; j++) { ent=ptr->entries[j]; p=ijtok(ptr->iindices[j],ptr->jindices[j],ptr->blocksize); q=ijtok(ptr->jindices[j],ptr->iindices[j],ptr->blocksize); result.blocks[blk].data.mat[p] += y[i]*ent; if (p != q) result.blocks[blk].data.mat[q] += y[i]*ent; }; }; ptr=ptr->next; }; }; } Csdp-6.2.0/lib/tweakgap.c0000644000175200017520000000227610522313034013573 0ustar coincoin/* * Attempt to tweak a solution with negative gap so that the gap is * closer to 0. Do this by moving from y to y+sa, where s is picked * by linesearch to keep Z PD. * * To calculate dZ, * dy=a * dZ=A'(dy) * * To get a change of dual objective equal to -gap, * * -gap=s*a'*a * s=-gap/(a'*a) * */ #include #include #include #include "declarations.h" void tweakgap(n,k,a,constraints,gap,Z,dZ,y,dy,work1,work2,work3,work4,workvec1, workvec2,workvec3,workvec4,printlevel) int n; int k; double *a; struct constraintmatrix *constraints; double gap; struct blockmatrix Z,dZ; double *y,*dy; struct blockmatrix work1,work2,work3,work4; double *workvec1,*workvec2,*workvec3,*workvec4; int printlevel; { int i; double norma; double alpha; norma=norm2(k,a+1); for (i=1; i<=k; i++) dy[i]=a[i]; op_at(k,dy,constraints,dZ); alpha=linesearch(n,dZ,work1,work2,work3,work4,workvec1,workvec2, workvec3,1.0,-gap/(norma*norma),0); if (printlevel >= 2) printf("tweak: alpha is %e \n",alpha); for (i=1; i<=k; i++) y[i]=y[i]+alpha*dy[i]; addscaledmat(Z,alpha,dZ,Z); } Csdp-6.2.0/lib/addscaledmat.c0000644000175200017520000000213113132530655014376 0ustar coincoin/* Add a matrix plus a multiple of a second matrix and put the result in a third matrix. C=A+scale*B */ #include #include #include "declarations.h" void addscaledmat(A,scale,B,C) struct blockmatrix A; double scale; struct blockmatrix B; struct blockmatrix C; { int blk; int i,j; for (blk=1; blk<=A.nblocks; blk++) { switch (A.blocks[blk].blockcategory) { case DIAG: for (i=1; i<=A.blocks[blk].blocksize; i++) C.blocks[blk].data.vec[i] = A.blocks[blk].data.vec[i] + scale*B.blocks[blk].data.vec[i]; break; case MATRIX: #pragma omp parallel for schedule(dynamic,64) default(none) private(i,j) shared(A,B,C,scale,blk) for (j=1; j<=A.blocks[blk].blocksize; j++) for (i=1; i<=A.blocks[blk].blocksize; i++) C.blocks[blk].data.mat[ijtok(i,j,A.blocks[blk].blocksize)]= A.blocks[blk].data.mat[ijtok(i,j,A.blocks[blk].blocksize)]+ scale*B.blocks[blk].data.mat[ijtok(i,j,A.blocks[blk].blocksize)]; break; case PACKEDMATRIX: default: printf("addscaledmat illegal block type \n"); exit(206); }; }; } Csdp-6.2.0/lib/user_exit.c0000644000175200017520000000517513134426260014010 0ustar coincoin/* * User exit routine for psd. This version of the routine simply returns * 0, so that psd will not stop. */ #include "declarations.h" #ifdef USESIGTERM #include #include #include #include #include int sigterm_signaled=0; /* * This sets sigterm_signaled to 1. The next time * user_exit runs, it will see this and return 1, so CSDP will stop. */ void catch_sigterm(signal) int signal; { printf("Process stopped by signal.\n"); sigterm_signaled=1; } /* * This version is used for the sigxcpu signal to give us more time. */ void catch_sigxcpu(signal) int signal; { int ret; struct rlimit rlim; printf("CPU Time Limit Execeded.\n"); sigterm_signaled=1; /* * Update the time limit. */ ret=getrlimit(RLIMIT_CPU,&rlim); rlim.rlim_cur=rlim.rlim_cur+200+rlim.rlim_cur/10; ret=setrlimit(RLIMIT_CPU,&rlim); } int user_exit(n,k,C,a,dobj,pobj,constant_offset,constraints,X,y,Z,params) int n; int k; struct blockmatrix C; double *a; double dobj; double pobj; double constant_offset; struct constraintmatrix *constraints; struct blockmatrix X; double *y; struct blockmatrix Z; struct paramstruc params; { /* * Stop on any of the following signals. SIGTERM, SIGXCPU, SIGINT, SIGQUIT * SIGTERM, SIGINT, SIGQUIT all set a flag to tell the code to exit at the * end of the current iteration. SIGXCPU's handler also extends the time * limit to give us the time to do this. */ signal(SIGTERM,catch_sigterm); signal(SIGINT,catch_sigterm); signal(SIGQUIT,catch_sigterm); signal(SIGXCPU,catch_sigxcpu); /* * If a signal to terminate has been raised, then quit. */ if (sigterm_signaled==1) { /* * This will stop CSDP with a return code of 10. */ return(1); } else { /* * This will tell CSDP to continue. */ return(0); }; /* * Any other positive value >= 2 returned will stop CSDP with a success. */ } #else int user_exit(n,k,C,a,dobj,pobj,constant_offset,constraints,X,y,Z,params) int n; int k; struct blockmatrix C; double *a; double dobj; double pobj; double constant_offset; struct constraintmatrix *constraints; struct blockmatrix X; double *y; struct blockmatrix Z; struct paramstruc params; { /* * This will tell CSDP to continue. */ return(0); /* * A returned value of 1 stops CSDP with failure (10) * Any other positive value >= 2 returned will stop CSDP with a success. */ } #endif Csdp-6.2.0/lib/qreig.c0000644000175200017520000000252010455242355013103 0ustar coincoin/* * qreig. This routine computes the eigenvalues of a symmetric tridiagonal * matrix using Algorith 464 from CALGO. * */ #include #define EPS 1.0e-6 void qreig(n,d,e2) int n; double *d; double *e2; { int i,k,m; double b,b2,f,g,h,p2,r2,s2; f=0.0; b2=0.0; b=0.0; e2[n]=0.0; for (k=1; k<=n; k++) { h=EPS*EPS*(d[k]*d[k]+e2[k]); if (b2 < h) { b=sqrt(h); b2=h; }; for (m=k; m<=n; m++) { if (e2[m] <= b2) goto cont1; }; cont1: if (m==k) goto root; nextit: g=d[k]; p2=sqrt(e2[k]); h=(d[k+1]-g)/(2.0*p2); r2=sqrt(h*h+1.0); if (h < 0.0) { h=p2/(h-r2); } else { h=p2/(h+r2); }; d[k]=h; h=g-h; f=f+h; for (i=k+1; i<=n; i++) { d[i]=d[i]-h; }; g=d[m]; if (g==0.0) g=b; h=g; s2=0.0; for (i=m-1; i>=k; i=i-1) { p2=g*h; r2=p2+e2[i]; e2[i+1]=s2*r2; s2=e2[i]/r2; d[i+1]=h+s2*(h+d[i]); g=d[i]-e2[i]/g; if (g==0.0) g=b; h=g*p2/r2; }; /* end for i */ e2[k]=s2*g*h; d[k]=h; if (e2[k]>b2) goto nextit; root: h=d[k]+f; for (i=k; i>=2; i=i-1) { if (h #include #include #include "declarations.h" int easy_sdp(n,k,C,a,constraints,constant_offset,pX,py,pZ,ppobj,pdobj) int n; int k; struct blockmatrix C; double *a; struct constraintmatrix *constraints; double constant_offset; struct blockmatrix *pX; double **py; struct blockmatrix *pZ; double *ppobj; double *pdobj; { int ret; struct constraintmatrix fill; struct paramstruc params; struct blockmatrix work1; struct blockmatrix work2; struct blockmatrix work3; struct blockmatrix bestx; struct blockmatrix bestz; struct blockmatrix Zi; struct blockmatrix dZ; struct blockmatrix dX; struct blockmatrix cholxinv; struct blockmatrix cholzinv; double *workvec1; double *workvec2; double *workvec3; double *workvec4; double *workvec5; double *workvec6; double *workvec7; double *workvec8; double *diagO; double *Fp; double *O; double *dy; double *dy1; double *rhs; double *besty; int printlevel; int ldam; struct sparseblock **byblocks; struct sparseblock *ptr; struct sparseblock *oldptr; int i; int j; struct sparseblock *p; struct sparseblock *q; struct sparseblock *prev=NULL; double gap; int nnz; int denseblocks; int numblocks; /* * Initialize the parameters. */ initparams(¶ms,&printlevel); /* * Allocate working storage */ alloc_mat(C,&work1); alloc_mat(C,&work2); alloc_mat(C,&work3); alloc_mat_packed(C,&bestx); alloc_mat_packed(C,&bestz); alloc_mat_packed(C,&cholxinv); alloc_mat_packed(C,&cholzinv); besty=(double *)malloc(sizeof(double)*(k+1)); if (besty == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; if (n > k) { workvec1=(double *)malloc(sizeof(double)*(n+1)); } else { workvec1=(double *)malloc(sizeof(double)*(k+1)); }; if (workvec1 == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; if (n > k) { workvec2=(double *)malloc(sizeof(double)*(n+1)); } else { workvec2=(double *)malloc(sizeof(double)*(k+1)); }; if (workvec2 == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; if (n > k) { workvec3=(double *)malloc(sizeof(double)*(n+1)); } else { workvec3=(double *)malloc(sizeof(double)*(k+1)); }; if (workvec3 == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; if (n > k) { workvec4=(double *)malloc(sizeof(double)*(n+1)); } else { workvec4=(double *)malloc(sizeof(double)*(k+1)); }; if (workvec4 == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; if (n > k) { workvec5=(double *)malloc(sizeof(double)*(n+1)); } else { workvec5=(double *)malloc(sizeof(double)*(k+1)); }; if (workvec5 == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; if (n > k) { workvec6=(double *)malloc(sizeof(double)*(n+1)); } else { workvec6=(double *)malloc(sizeof(double)*(k+1)); }; if (workvec6 == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; if (n > k) { workvec7=(double *)malloc(sizeof(double)*(n+1)); } else { workvec7=(double *)malloc(sizeof(double)*(k+1)); }; if (workvec7 == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; if (n > k) { workvec8=(double *)malloc(sizeof(double)*(n+1)); } else { workvec8=(double *)malloc(sizeof(double)*(k+1)); }; if (workvec8 == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; if (n > k) { diagO=(double *)malloc(sizeof(double)*(n+1)); } else { diagO=(double *)malloc(sizeof(double)*(k+1)); }; if (diagO == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; rhs=malloc(sizeof(double)*(k+1)); if (rhs == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; dy=malloc(sizeof(double)*(k+1)); if (dy == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; dy1=malloc(sizeof(double)*(k+1)); if (dy1 == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; Fp=malloc(sizeof(double)*(k+1)); if (Fp == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; /* * Check to make sure that there is at least one constraint. */ if (k<= 0) { printf("Problem must have at least one constraint.\n"); exit(206); }; /* * Work out the leading dimension for the array. Note that we may not * want to use k itself, for cache issues. */ if ((k % 2) == 0) ldam=k+1; else ldam=k; O=malloc(sizeof(double)*ldam*ldam); if (O == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; alloc_mat(C,&Zi); alloc_mat(C,&dZ); alloc_mat(C,&dX); /* * Fill in lots of details in the constraints data structure that haven't * necessarily been done before now. */ /* * Next, setup issparse and NULL out all nextbyblock pointers. */ for (i=1; i<=k; i++) { p=constraints[i].blocks; while (p != NULL) { /* * First, set issparse. The 0.125 parameter was hand tuned. */ if (((1.0*k*k*p->numentries*p->numentries) > 0.125*(1.0*k*p->blocksize*p->blocksize*p->blocksize)) && ((p->numentries) > 5)) { p->issparse=0; } else { p->issparse=1; }; if (C.blocks[p->blocknum].blockcategory == DIAG) p->issparse=1; /* * Setup the cross links. */ p->nextbyblock=NULL; p=p->next; }; }; /* * Now, cross link. */ for (i=1; i<=k; i++) { p=constraints[i].blocks; while (p != NULL) { if (p->nextbyblock == NULL) { /* * link in the remaining blocks. */ for (j=i+1; j<=k; j++) { q=constraints[j].blocks; while (q != NULL) { if (q->blocknum == p->blocknum) { if (p->nextbyblock == NULL) { p->nextbyblock=q; q->nextbyblock=NULL; prev=q; } else { prev->nextbyblock=q; q->nextbyblock=NULL; prev=q; }; break; }; q=q->next; }; }; }; p=p->next; }; }; /* * If necessary, print out information on sparsity of blocks. */ if (printlevel >= 1) { numblocks=0; denseblocks=0; for (i=1; i<=k; i++) { p=constraints[i].blocks; while (p != NULL) { if (printlevel >= 4) printf("Sparsity of constraint blocks: %d,%d,%d,%d \n",i,p->blocknum,p->issparse,p->numentries); if (p->issparse == 0) denseblocks=denseblocks+1; numblocks=numblocks+1; p=p->next; }; }; if (printlevel >= 2) printf("Percentage of dense constraint blocks is %f\n", (100.0*denseblocks)/(1.0*numblocks)); }; /* * Allocate space for byblocks pointers. */ byblocks=(struct sparseblock **)malloc((C.nblocks+1)*sizeof(struct sparseblock *)); if (byblocks == NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; for (i=1; i<=C.nblocks; i++) byblocks[i]=NULL; /* * Fill in byblocks pointers. */ for (i=1; i<=k; i++) { ptr=constraints[i].blocks; while (ptr != NULL) { if (byblocks[ptr->blocknum]==NULL) { byblocks[ptr->blocknum]=ptr; }; ptr=ptr->next; }; }; /* * Compute "fill". This data structure tells us which elements in the * block diagonal matrix have corresponding elements in one of the * constraints, and which constraint this element first appears in. * */ makefill(k,C,constraints,&fill,work1,printlevel); /* * Compute the nonzero structure of O. This is only used for debugging * at this point. */ if (printlevel >= 2) { nnz=structnnz(n,k,C,constraints); printf("Structural density of O %d, %e \n",nnz,nnz*1.0/(k*k*1.0)); }; /* * Sort entries in the constraints. */ sort_entries(k,C,constraints); /* * Check the symmetry of C. */ checkc(n,C,printlevel); /* * Check constraints. */ checkconstraints(n,k,C,constraints,printlevel); /* * Now, call sdp(). */ ret=sdp(n,k,C,a,constant_offset,constraints,byblocks,fill,*pX,*py,*pZ, cholxinv,cholzinv,ppobj,pdobj,work1,work2,work3,workvec1, workvec2,workvec3,workvec4,workvec5,workvec6,workvec7,workvec8, diagO,bestx,besty,bestz,Zi,O,rhs,dZ,dX,dy,dy1,Fp, printlevel,params); if (printlevel >= 1) { if (ret==0) printf("Success: SDP solved\n"); if (ret==1) printf("Success: SDP is primal infeasible\n"); if (ret==2) printf("Success: SDP is dual infeasible\n"); if (ret==3) printf("Partial Success: SDP solved with reduced accuracy\n"); if (ret >= 4) printf("Failure: return code is %d \n",ret); if (ret==1) { op_at(k,*py,constraints,work1); addscaledmat(work1,-1.0,*pZ,work1); printf("Certificate of primal infeasibility: a'*y=%.5e, ||A'(y)-Z||=%.5e\n",-1.0,Fnorm(work1)); }; if (ret==2) { op_a(k,constraints,*pX,workvec1); printf("Certificate of dual infeasibility: tr(CX)=%.5e, ||A(X)||=%.5e\n",trace_prod(C,*pX),norm2(k,workvec1+1)); }; if ((ret==0) || (ret>=3)) { if (printlevel >= 3) { printf("XZ Gap: %.7e \n",trace_prod(*pZ,*pX)); gap=*pdobj-*ppobj; printf("Real Gap: %.7e \n",gap); }; if (printlevel >= 1) { gap=*pdobj-*ppobj; printf("Primal objective value: %.7e \n",*ppobj); printf("Dual objective value: %.7e \n",*pdobj); printf("Relative primal infeasibility: %.2e \n", pinfeas(k,constraints,*pX,a,workvec1)); printf("Relative dual infeasibility: %.2e \n", dinfeas(k,C,constraints,*py,*pZ,work1)); printf("Real Relative Gap: %.2e \n",gap/(1+fabs(*pdobj)+fabs(*ppobj))); printf("XZ Relative Gap: %.2e \n",trace_prod(*pZ,*pX)/(1+fabs(*pdobj)+fabs(*ppobj))); printf("DIMACS error measures: %.2e %.2e %.2e %.2e %.2e %.2e\n", pinfeas(k,constraints,*pX,a,workvec1)*(1+norm2(k,a+1))/ (1+norminf(k,a+1)), 0.0, dimacserr3(k,C,constraints,*py,*pZ,work1), 0.0, gap/(1+fabs(*pdobj)+fabs(*ppobj)), trace_prod(*pZ,*pX)/(1+fabs(*pdobj)+fabs(*ppobj))); }; }; }; /* * Now, free up all of the storage. */ free_mat(work1); free_mat(work2); free_mat(work3); free_mat_packed(bestx); free_mat_packed(bestz); free_mat_packed(cholxinv); free_mat_packed(cholzinv); free_mat(Zi); free_mat(dZ); free_mat(dX); free(besty); free(workvec1); free(workvec2); free(workvec3); free(workvec4); free(workvec5); free(workvec6); free(workvec7); free(workvec8); free(rhs); free(dy); free(dy1); free(Fp); free(O); free(diagO); free(byblocks); /* * Free up the fill data structure. */ ptr=fill.blocks; while (ptr != NULL) { free(ptr->entries); free(ptr->iindices); free(ptr->jindices); oldptr=ptr; ptr=ptr->next; free(oldptr); }; /* * Finally, free the constraints array. */ return(ret); } int structnnz(n,k,C,constraints) int n; int k; struct blockmatrix C; struct constraintmatrix *constraints; { int i,j; int ii,jj; int nnz; struct sparseblock *ptri; struct sparseblock *ptrj; nnz=0; for (i=1; i<=k; i++) for (j=1; j<=k; j++) { ptri=constraints[i].blocks; while (ptri != NULL) { ptrj=constraints[j].blocks; while (ptrj != NULL) { if (ptri->blocknum == ptrj->blocknum) { if (C.blocks[ptri->blocknum].blockcategory==MATRIX) { nnz++; goto NEXTJ; } else { /* DIAG block */ for (ii=1; ii<=ptri->numentries; ii++) for (jj=1; jj<=ptrj->numentries; jj++) { if (ptri->iindices[ii]==ptrj->iindices[jj]) { nnz++; goto NEXTJ; }; }; }; }; ptrj=ptrj->next; }; ptri=ptri->next; }; /* end while */ NEXTJ:; }; /* end nested fors */ return(nnz); } int actnnz(n,lda,A) int n; int lda; double A[]; { int i,j; int nnz; nnz=0; for (i=1; i<=n; i++) { if (A[ijtok(i,i,lda)] != 0.0) nnz++; for (j=i+1; j<=n; j++) { if (A[ijtok(i,j,lda)] != 0.0) { nnz++; nnz++; }; }; }; return(nnz); } int bandwidth(n,lda,A) int n; int lda; double A[]; { int i; int j; int bw; bw=0; for (j=2; j<=n; j++) { for (i=1; i<=j-1; i++) { if (A[ijtok(i,j,lda)] != 0.0) { if ((j-i) > bw) bw=j-i; break; }; }; }; return(bw); } /* * Sanity checks for the C matrix data structure. If this fails, we'll just * exit(206) to indicate that there was improper input. Otherwise, we'll * return 0; */ int checkc(int n,struct blockmatrix C,int printlevel) { int i,j,k; int totalsize; totalsize=0; for (k=1; k<=C.nblocks; k++) { if (C.blocks[k].blockcategory==DIAG) { if (printlevel > 5) printf("blockcategory=diag\n"); }; if (C.blocks[k].blockcategory==MATRIX) { if (printlevel > 5) printf("blockcategory=matrix\n"); }; totalsize=totalsize+C.blocks[k].blocksize; if (C.blocks[k].blockcategory==MATRIX) { for (i=1; i<=C.blocks[k].blocksize; i++) { for (j=1; j<=C.blocks[k].blocksize; j++) { if (C.blocks[k].data.mat[ijtok(i,j,C.blocks[k].blocksize)] != C.blocks[k].data.mat[ijtok(j,i,C.blocks[k].blocksize)]) { if (printlevel >= 1) printf("C is not symmetric, %d, %d, %d\n",k,i,j); exit(206); } }; }; }; }; if (totalsize != n) { if (printlevel >= 1) printf("Sum of block sizes does not equal n!\n"); exit(206); }; return(0); } /* * Sanity tests on the constraints data structure. */ int checkconstraints(n,k,C,constraints,printlevel) int n; int k; struct blockmatrix C; struct constraintmatrix *constraints; int printlevel; { int i,j; struct sparseblock *p; for (i=1; i<=k; i++) { p=constraints[i].blocks; if (p==NULL) { if (printlevel >= 1) printf("Constraint %d is empty!\n",i); exit(206); }; while (p != NULL) { if (p->constraintnum != i) { if (printlevel >= 1) printf("p->constraintnum != i, i=%d \n",i); exit(206); }; if (p->blocksize != C.blocks[p->blocknum].blocksize) { if (printlevel >= 1) printf("p->blocksize is wrong, constraint %d \n",i); exit(206); }; if (printlevel > 5) printf("Constraint %d, block %d, entries %d\n",i,p->blocknum,p->numentries); for (j=1; j<=p->numentries; j++) { /* * For debugging, print out the constraint entry. */ if (printlevel >6) printf(" (%d, %d)=%lf\n",p->iindices[j],p->jindices[j],p->entries[j]); /* * Make sure that all indices are in range. */ if (p->iindices[j] > C.blocks[p->blocknum].blocksize) { if (printlevel >= 1) printf("i index is larger than blocksize!\n"); exit(206); }; if (p->jindices[j] > C.blocks[p->blocknum].blocksize) { if (printlevel >= 1) printf("j index is larger than blocksize!\n"); exit(206); }; if (p->iindices[j] < 1) { if (printlevel >= 1) printf("i index is less than 1!\n"); exit(206); }; if (p->jindices[j] < 1) { if (printlevel >= 1) printf("j index is less than 1!\n"); exit(206); }; /* * Make sure that entries are sorted properly. */ if (p->iindices[j] > p->jindices[j]) { if (printlevel >= 1) { printf("i index is greater than j index!\n"); printf("constraint=%d\n",i); printf("iindex=%d\n",p->iindices[j]); printf("jindex=%d\n",p->jindices[j]); }; exit(206); }; /* * Check for any duplicate entries that snuck in. */ if (j < p->numentries) if ((p->iindices[j]==p->iindices[j+1]) & (p->jindices[j]==p->jindices[j+1])) { if (printlevel >= 1) { printf("Duplicate entry!\n"); printf("constraint=%d\n",i); printf("iindex=%d\n",p->iindices[j]); printf("jindex=%d\n",p->jindices[j]); }; exit(206); }; if (C.blocks[p->blocknum].blockcategory==DIAG) { if (p->iindices[j] != p->jindices[j]) { if (printlevel >= 1) printf("Off diagonal entry in diagonal block!\n"); exit(206); }; }; }; p=p->next; }; }; return(0); } Csdp-6.2.0/lib/writesol.c0000644000175200017520000000411713132530655013646 0ustar coincoin/* Write out a solution in SDPA format. */ #include #include #include "declarations.h" int write_sol(fname,n,k,X,y,Z) char *fname; int n; int k; struct blockmatrix X; double *y; struct blockmatrix Z; { FILE *fid; int i; int j; int blk; double ent; /* * Open the output file for writing. */ fid=fopen(fname,"w"); if (fid == (FILE *) NULL) { printf("Failed to open output file for writing solution. \n"); exit(204); }; /* * Print out y (x0 in SDPA notation) */ for (i=1; i<=k; i++) fprintf(fid,"%.18e ",y[i]); fprintf(fid,"\n"); /* * Next, print out Z (X in SDPA notation) */ for (blk=1; blk<=Z.nblocks; blk++) { switch (Z.blocks[blk].blockcategory) { case DIAG: for (i=1; i<=Z.blocks[blk].blocksize; i++) { ent=Z.blocks[blk].data.vec[i]; if (ent != 0.0) fprintf(fid,"1 %d %d %d %.18e \n",blk,i,i,ent); }; break; case MATRIX: for (i=1; i<=Z.blocks[blk].blocksize; i++) for (j=i; j<=Z.blocks[blk].blocksize; j++) { ent=Z.blocks[blk].data.mat[ijtok(i,j,Z.blocks[blk].blocksize)]; if (ent != 0.0) fprintf(fid,"1 %d %d %d %.18e \n",blk,i,j,ent); }; break; default: printf("Illegal block type!\n"); exit(206); }; }; /* * Next, print out X (Y in SDPA notation) */ for (blk=1; blk<=X.nblocks; blk++) { switch (X.blocks[blk].blockcategory) { case DIAG: for (i=1; i<=X.blocks[blk].blocksize; i++) { ent=X.blocks[blk].data.vec[i]; if (ent != 0.0) fprintf(fid,"2 %d %d %d %.18e \n",blk,i,i,ent); }; break; case MATRIX: for (i=1; i<=X.blocks[blk].blocksize; i++) for (j=i; j<=X.blocks[blk].blocksize; j++) { ent=X.blocks[blk].data.mat[ijtok(i,j,X.blocks[blk].blocksize)]; if (ent != 0.0) fprintf(fid,"2 %d %d %d %.18e \n",blk,i,j,ent); }; break; case PACKEDMATRIX: default: printf("writesol Invalid Block Type!\n"); exit(206); }; }; /* * Close up and quit. */ fclose(fid); return(0); } Csdp-6.2.0/lib/copy_mat.c0000644000175200017520000000155613132530655013615 0ustar coincoin/* Copy a matrix A to a second matrix B in our blocked format. */ #include #include #include "declarations.h" void copy_mat(A,B) struct blockmatrix A,B; { int blk,i,j; double *p; double *q; for (blk=1; blk<=A.nblocks; blk++) { switch (A.blocks[blk].blockcategory) { case DIAG: p=A.blocks[blk].data.vec; q=B.blocks[blk].data.vec; for (i=1; i<=A.blocks[blk].blocksize; i++) q[i]=p[i]; break; case MATRIX: p=A.blocks[blk].data.mat; q=B.blocks[blk].data.mat; #pragma omp parallel for schedule(dynamic,64) private(i,j) shared(p,q) for (j=1; j<=A.blocks[blk].blocksize; j++) for (i=1; i<=A.blocks[blk].blocksize; i++) q[ijtok(i,j,A.blocks[blk].blocksize)]= p[ijtok(i,j,A.blocks[blk].blocksize)]; break; default: printf("copy_mat illegal block type \n"); exit(206); }; } } Csdp-6.2.0/lib/writeprob.c0000644000175200017520000000437613132530655014022 0ustar coincoin/* Write out a problem in SDPA format. */ #include #include #include "declarations.h" int write_prob(fname,n,k,C,a,constraints) char *fname; int n; int k; struct blockmatrix C; double *a; struct constraintmatrix *constraints; { FILE *fid; int i; int j; int blk; struct sparseblock *p; /* * Open up the file for output. */ fid=fopen(fname,"w"); if (fid == (FILE *) NULL) { printf("Couldn't open problem file for writing! \n"); exit(203); }; /* * Write out the basic problem size info. */ fprintf(fid,"%d \n",k); fprintf(fid,"%d \n",C.nblocks); for (i=1; i<=C.nblocks; i++) { switch (C.blocks[i].blockcategory) { case DIAG: fprintf(fid,"%d ",-C.blocks[i].blocksize); break; case MATRIX: fprintf(fid,"%d ",C.blocks[i].blocksize); break; default: printf("Illegal block type!\n"); exit(206); }; }; fprintf(fid,"\n"); /* * Write out the a vector. (c in SDPA terminology) */ for (i=1; i<=k; i++) fprintf(fid,"%.18e ",a[i]); fprintf(fid,"\n"); /* * Write out the C matrix (F0 in SDPA) */ for (blk=1; blk<=C.nblocks; blk++) { switch (C.blocks[blk].blockcategory) { case DIAG: for (i=1; i<=C.blocks[blk].blocksize; i++) { if (C.blocks[blk].data.vec[i] != 0.0) fprintf(fid,"0 %d %d %d %.18e \n",blk,i,i,C.blocks[blk].data.vec[i]); }; break; case MATRIX: for (i=1; i<=C.blocks[blk].blocksize; i++) for (j=i; j<=C.blocks[blk].blocksize; j++) { if (C.blocks[blk].data.mat[ijtok(i,j,C.blocks[blk].blocksize)] != 0.0 ) fprintf(fid,"0 %d %d %d %.18e \n",blk,i,j,C.blocks[blk].data.mat[ijtok(i,j,C.blocks[blk].blocksize)]); }; break; default: printf("Illegal block type!\n"); exit(206); }; }; /* * Now, start writing out the A_i (F_k in SDPA notation) */ for (i=1; i<=k; i++) { p=constraints[i].blocks; while (p != NULL) { for (j=1; j<=p->numentries; j++) { fprintf(fid,"%d %d %d %d %.18e \n",i,p->blocknum, p->iindices[j], p->jindices[j], p->entries[j]); }; p=p->next; }; }; /* * Close up the file and get out. */ fclose(fid); return(0); } Csdp-6.2.0/lib/linesearch.c0000644000175200017520000001657313132530655014124 0ustar coincoin/* Find the largest value for alpha<=1 such that X+alpha*dX is PD. Return the optimal X+alpha*dX in work1. If the search fails, return alpha=-1.0. */ #include #include #include #include "declarations.h" #define LANCZOSITS 30 double linesearch(n,dX,work1,work2,work3,cholinv,q,z,workvec, stepfrac,start,printlevel) int n; struct blockmatrix dX,work1,work2,work3,cholinv; double *q; double *z; double *workvec; double stepfrac; double start; int printlevel; { int i,j,jj; double alpha; double scale1; double scale2; int inc; double lalpha[LANCZOSITS+1]; double lbeta[LANCZOSITS+1]; double lbeta2[LANCZOSITS+1]; double evalues[LANCZOSITS+2]; double maxeigs[LANCZOSITS+1]; double reorth[LANCZOSITS+1]; double maxeig; int maxn,blk,method; double *lanczosvectors; /* * Allocate space for storing the Lanczos vectors. */ lanczosvectors=(double *) malloc((LANCZOSITS+1)*n*sizeof(double)); if (lanczosvectors==NULL) { printf("Storage Allocation Failed!\n"); exit(205); }; /* * First, figure out which method to use. If maxn is big, then use * lots of matrix/vector mults. If maxn is small, then multiply the * matrices once and for all. */ maxn=0; for (blk=1; blk<=work1.nblocks; blk++) { if ((work1.blocks[blk].blocksize > maxn) && (work1.blocks[blk].blockcategory==MATRIX)) maxn=work1.blocks[blk].blocksize; }; if (maxn > 6*LANCZOSITS) { method=1; /* matrix vector mults. */ if (printlevel >= 4) { printf("linesearch method 1 \n"); }; } else { method=2; /* matrix matrix mults. */ if (printlevel >= 4) { printf("linesearch method 2 \n"); }; }; /* * */ if (method==1) { scale1=-1.0; zero_mat(work1); store_unpacked(cholinv,work3); triu(work3); addscaledmat(work1,scale1,work3,work2); trans(work2); } else { /* * method=2. */ /* * First, multiply dX*cholinv. Store it in work3. */ scale1=1.0; scale2=0.0; store_unpacked(cholinv,work2); triu(work2); mat_mult(scale1,scale2,dX,work2,work3); /* * Now, find R^{-T} */ trans(work2); scale1=-1.0; scale2=0.0; mat_mult(scale1,scale2,work2,work3,work1); }; /* * Initialize q. */ for (i=1; i<=n; i++) q[i]=1.0/sqrt(n*1.0); for (i=1; i<=n; i++) lanczosvectors[ijtok(i,1,n)]=q[i]; /* * Next, perform the Lancoz iterations. */ maxeig=-1.0e200; for (j=1; j<=LANCZOSITS; j++) { maxeigs[j]=-1.0e100; if (method == 1) { matvec(work3,q,z); matvec(dX,z,workvec); matvec(work2,workvec,z); } else { matvec(work1,q,z); }; lalpha[j]=0.0; for (i=1; i<=n; i++) lalpha[j]=lalpha[j]+q[i]*z[i]; /* * We'll use BLAS routines to do the reorthogonalization. First, * Compute reorth=lanczosvectors'*z. Then compute * z=z-lanczosvectors*reorth. * * lanczosvectors is of size n by j, with lda=n. */ scale1=1.0; scale2=0.0; inc=1; #ifdef HIDDENSTRLEN dgemv_("T",&n,&j,&scale1,lanczosvectors,&n,z+1,&inc,&scale2,reorth+1,&inc,1,1); #else #ifdef NOUNDERBLAS #ifdef CAPSBLAS DGEMV("T",&n,&j,&scale1,lanczosvectors,&n,z+1,&inc,&scale2,reorth+1,&inc); #else dgemv("T",&n,&j,&scale1,lanczosvectors,&n,z+1,&inc,&scale2,reorth+1,&inc); #endif #else #ifdef CAPSBLAS DGEMV_("T",&n,&j,&scale1,lanczosvectors,&n,z+1,&inc,&scale2,reorth+1,&inc); #else dgemv_("T",&n,&j,&scale1,lanczosvectors,&n,z+1,&inc,&scale2,reorth+1,&inc); #endif #endif #endif scale1=-1.0; scale2=1.0; inc=1; #ifdef HIDDENSTRLEN dgemv_("N",&n,&j,&scale1,lanczosvectors,&n,reorth+1,&inc,&scale2,z+1,&inc,1); #else #ifdef NOUNDERBLAS #ifdef CAPSBLAS DGEMV("N",&n,&j,&scale1,lanczosvectors,&n,reorth+1,&inc,&scale2,z+1,&inc); #else dgemv("N",&n,&j,&scale1,lanczosvectors,&n,reorth+1,&inc,&scale2,z+1,&inc); #endif #else #ifdef CAPSBLAS DGEMV_("N",&n,&j,&scale1,lanczosvectors,&n,reorth+1,&inc,&scale2,z+1,&inc); #else dgemv_("N",&n,&j,&scale1,lanczosvectors,&n,reorth+1,&inc,&scale2,z+1,&inc); #endif #endif #endif scale1=1.0; scale2=0.0; inc=1; #ifdef HIDDENSTRLEN dgemv_("T",&n,&j,&scale1,lanczosvectors,&n,z+1,&inc,&scale2,reorth+1,&inc,1); #else #ifdef NOUNDERBLAS #ifdef CAPSBLAS DGEMV("T",&n,&j,&scale1,lanczosvectors,&n,z+1,&inc,&scale2,reorth+1,&inc); #else dgemv("T",&n,&j,&scale1,lanczosvectors,&n,z+1,&inc,&scale2,reorth+1,&inc); #endif #else #ifdef CAPSBLAS DGEMV_("T",&n,&j,&scale1,lanczosvectors,&n,z+1,&inc,&scale2,reorth+1,&inc); #else dgemv_("T",&n,&j,&scale1,lanczosvectors,&n,z+1,&inc,&scale2,reorth+1,&inc); #endif #endif #endif scale1=-1.0; scale2=1.0; inc=1; #ifdef HIDDENSTRLEN dgemv_("N",&n,&j,&scale1,lanczosvectors,&n,reorth+1,&inc,&scale2,z+1,&inc,1); #else #ifdef NOUNDERBLAS #ifdef CAPSBLAS DGEMV("N",&n,&j,&scale1,lanczosvectors,&n,reorth+1,&inc,&scale2,z+1,&inc); #else dgemv("N",&n,&j,&scale1,lanczosvectors,&n,reorth+1,&inc,&scale2,z+1,&inc); #endif #else #ifdef CAPSBLAS DGEMV_("N",&n,&j,&scale1,lanczosvectors,&n,reorth+1,&inc,&scale2,z+1,&inc); #else dgemv_("N",&n,&j,&scale1,lanczosvectors,&n,reorth+1,&inc,&scale2,z+1,&inc); #endif #endif #endif /* * Compute the norm of z. */ lbeta[j]=norm2(n,z+1); if (fabs(lbeta[j])<1.0e-16) { if (printlevel >= 3) printf("Small beta[j]\n"); j=j-1; jj=j; goto DONEEARLY; }; for (i=1; i<=n; i++) q[i]=z[i]/lbeta[j]; /* * Store the Lanczos vector. */ for (i=1; i<=n; i++) lanczosvectors[ijtok(i,j+1,n)]=q[i]; if (j>=5) { /* * Now, get ready to call qreig to get the eigenvalues. */ for (i=1; i<=j-1; i++) lbeta2[i]=lbeta[i]*lbeta[i]; for (i=1; i<=j; i++) evalues[i]=lalpha[i]; qreig(j,evalues,lbeta2); maxeigs[j]=-1.0e100; for (i=1; i<=j; i++) { if (printlevel >= 4) printf ("qreig evalue %e \n",evalues[i]); if (evalues[i] > maxeigs[j]) maxeigs[j]=evalues[i]; }; if (maxeigs[j] > maxeig) maxeig=maxeigs[j]; }; /* * Now, decide whether or not to stop. */ if ((j>=7) && (maxeigs[j] <= 1/(3*start)) && (fabs((maxeigs[j]-maxeigs[j-2])/(0.000001+fabs(maxeigs[j]))) < 0.2)) { if (printlevel >= 4) printf("Stopping on <1/3s j=%d \n",j); jj=j; goto DONEEARLY; }; if ((j>=8) && (fabs((maxeigs[j]-maxeigs[j-2])/(0.000001+fabs(maxeigs[j]))) < 0.02)) { if (printlevel >= 4) printf("Stopping here, on tightness j=%d \n",j); maxeig=maxeig+0.01*fabs(maxeig); jj=j; goto DONEEARLY; }; }; jj=LANCZOSITS; DONEEARLY: if (printlevel >= 4) { for (i=1; i<=jj; i++) printf("maxeigs[%d]=%e \n",i,maxeigs[i]); printf("maxeig %e \n",maxeig); }; if (printlevel >= 4) printf("Lancoz converged after %d iters\n",jj); if (printlevel >= 3) { if (maxeig >0.0) printf("eigsearch: alpha=%e \n",stepfrac/maxeig); else printf("eigsearch: alpha=+Inf\n"); }; if (((stepfrac/maxeig) < start) && (maxeig > 0)) alpha=stepfrac/maxeig; else alpha=start; free(lanczosvectors); return(alpha); } Csdp-6.2.0/lib/matvec.c0000644000175200017520000000244413132530655013256 0ustar coincoin/* * Compute y=A*x * * We use * */ #include #include #include "declarations.h" void matvec(A,x,y) struct blockmatrix A; double *x; double *y; { int blk,i,n; int p; double *ap; double scale1; double scale2; int inc; /* * Work through the blocks one at a time. */ p=1; for (blk=1; blk<=A.nblocks; blk++) { switch (A.blocks[blk].blockcategory) { case DIAG: for (i=1; i<=A.blocks[blk].blocksize; i++) { y[p]=A.blocks[blk].data.vec[i]*x[p]; p++; }; break; case MATRIX: /* * Call dgemm to do the matrix multiplication. */ n=A.blocks[blk].blocksize; ap=A.blocks[blk].data.mat; inc=1; scale1=1.0; scale2=0.0; #ifdef HIDDENSTRLEN dgemv_("N",&n,&n,&scale1,ap,&n,x+p,&inc,&scale2,y+p,&inc,1); #else #ifdef NOUNDERBLAS #ifdef CAPSBLAS DGEMV("N",&n,&n,&scale1,ap,&n,x+p,&inc,&scale2,y+p,&inc); #else dgemv("N",&n,&n,&scale1,ap,&n,x+p,&inc,&scale2,y+p,&inc); #endif #else #ifdef CAPSBLAS DGEMV_("N",&n,&n,&scale1,ap,&n,x+p,&inc,&scale2,y+p,&inc); #else dgemv_("N",&n,&n,&scale1,ap,&n,x+p,&inc,&scale2,y+p,&inc); #endif #endif #endif p=p+n; break; case PACKEDMATRIX: default: printf("matvec illegal block type \n"); exit(206); }; }; } Csdp-6.2.0/lib/Fnorm.c0000644000175200017520000000471713132530655013065 0ustar coincoin/* Compute the Frobenius norm of a matrix. */ #include #include #include #include "declarations.h" double Fnorm(A) struct blockmatrix A; { int blk; double nrm; double temp; nrm=0; for (blk=1; blk<=A.nblocks; blk++) { switch (A.blocks[blk].blockcategory) { case DIAG: temp=norm2(A.blocks[blk].blocksize,A.blocks[blk].data.vec+1); nrm += temp*temp; break; case MATRIX: temp=norm2(A.blocks[blk].blocksize*A.blocks[blk].blocksize, A.blocks[blk].data.mat); nrm += temp*temp; break; case PACKEDMATRIX: default: printf("Fnorm illegal block type \n"); exit(206); }; }; nrm=sqrt(nrm); return(nrm); } /* * The Knorm is the sum of the Fnorms of the blocks. */ double Knorm(A) struct blockmatrix A; { int blk; double nrm; double temp; nrm=0; for (blk=1; blk<=A.nblocks; blk++) { switch (A.blocks[blk].blockcategory) { case DIAG: temp=norm2(A.blocks[blk].blocksize,A.blocks[blk].data.vec+1); nrm += temp; break; case MATRIX: temp=norm2(A.blocks[blk].blocksize*A.blocks[blk].blocksize, A.blocks[blk].data.mat); nrm += temp; break; case PACKEDMATRIX: default: printf("Fnorm illegal block type \n"); exit(206); }; }; return(nrm); } double mat1norm(A) struct blockmatrix A; { int blk; double nrm; double temp; nrm=0; for (blk=1; blk<=A.nblocks; blk++) { switch (A.blocks[blk].blockcategory) { case DIAG: temp=norm1(A.blocks[blk].blocksize,A.blocks[blk].data.vec+1); nrm += temp; break; case MATRIX: temp=norm1(1*A.blocks[blk].blocksize*A.blocks[blk].blocksize, A.blocks[blk].data.mat); nrm += temp; break; case PACKEDMATRIX: default: printf("Fnorm illegal block type \n"); exit(206); }; }; return(nrm); } double matinfnorm(A) struct blockmatrix A; { int blk; int i; double nrm; nrm=0; for (blk=1; blk<=A.nblocks; blk++) { switch (A.blocks[blk].blockcategory) { case DIAG: for (i=1; i<=A.blocks[blk].blocksize; i++) { if (fabs(A.blocks[blk].data.vec[i]) > nrm) nrm=fabs(A.blocks[blk].data.vec[i]); }; break; case MATRIX: for (i=0; i nrm) nrm=fabs(A.blocks[blk].data.vec[i]); }; break; case PACKEDMATRIX: default: printf("Fnorm illegal block type \n"); exit(206); }; }; return(nrm); } Csdp-6.2.0/lib/sortentries.c0000644000175200017520000000453113135431247014357 0ustar coincoin #include #include #include "declarations.h" struct entry { int indexi; int indexj; int indexk; int indexl; double entry; }; int mycompare(const void *p1, const void *p2) { if (((struct entry *)p1)->indexi < ((struct entry *)p2)->indexi) { return(-1); }; if (((struct entry *)p1)->indexi == ((struct entry *)p2)->indexi) { if (((struct entry *)p1)->indexj < ((struct entry *)p2)->indexj) { return(-1); }; if (((struct entry *)p1)->indexj == ((struct entry *)p2)->indexj) { return(0); }; if (((struct entry *)p1)->indexj > ((struct entry *)p2)->indexj) { return(1); }; }; /* * If we get here, then p1->indexi > p2->indexi */ return(1); } void sort_entries(k,C,constraints) int k; struct blockmatrix C; struct constraintmatrix *constraints; { int i,j; struct sparseblock *ptr; int maxentries; struct entry *entries; /* * First, find out who has the most entries. */ maxentries=0; for (i=1; i<=k; i++) { ptr=constraints[i].blocks; while (ptr != NULL) { if (ptr->numentries > maxentries) maxentries=ptr->numentries; ptr=ptr->next; }; }; /* * Allocate space for entries. */ entries=(struct entry *)malloc(maxentries*sizeof(struct entry)); if (entries==NULL) { printf("Storage allocation failed in sortentries.\n"); exit(205); }; for (i=1; i<=k; i++) { ptr=constraints[i].blocks; /* * There must be at least one block in each constraint. */ if (ptr==NULL) { printf("Constraint %d is empty.\n",i); exit(206); }; /* * Now, loop through the blocks. */ while (ptr != NULL) { /* * Copy in */ for (j=1; j<=ptr->numentries; j++) { entries[j-1].indexi=ptr->iindices[j]; entries[j-1].indexj=ptr->jindices[j]; entries[j-1].entry=ptr->entries[j]; }; /* * Sort */ qsort(entries,(size_t)ptr->numentries,sizeof(struct entry), mycompare); /* * Copy out. */ for (j=1; j<=ptr->numentries; j++) { ptr->iindices[j]=entries[j-1].indexi; ptr->jindices[j]=entries[j-1].indexj; ptr->entries[j]=entries[j-1].entry; }; ptr=ptr->next; }; }; /* end i */ free(entries); } Csdp-6.2.0/solver/0000755000175200017520000000000013136043252012367 5ustar coincoinCsdp-6.2.0/solver/csdp.c0000644000175200017520000000432113132550037013464 0ustar coincoin#include #include #include #include "declarations.h" /* * Stuff for keeping track of time. */ #ifdef USEGETTIME #include /* definition of NULL */ #include /* definition of timeval struct and protyping of gettime ofday */ extern double starttime; extern double opotime; extern double factortime; extern double othertime; extern double totaltime; extern double othertime1; extern double othertime2; extern double othertime3; extern struct timeval tp; extern double t1; extern double t2; extern double starttime; extern double endtime; #endif int main(argc,argv) int argc; char *argv[]; { int ret; int n; int k; struct blockmatrix C; double *a; struct constraintmatrix *constraints; struct blockmatrix X,Z; double *y; double pobj,dobj; #ifdef USEGETTIME gettimeofday(&tp, NULL); starttime=(double)tp.tv_sec+(1.e-6)*tp.tv_usec; #endif /* * Check that we have enough arguments. */ if ((argc < 2) || (argc > 4)) { printf("CSDP 6.2.0\n"); printf(" \n"); printf("Usage: \n"); printf("\n"); printf("csdp [] []\n"); exit(200); }; /* * First, read the problem in. */ ret=read_prob(argv[1],&n,&k,&C,&a,&constraints,1); if (ret != 0) { printf("Giving up.\n"); exit(201); }; if (argc == 4) { ret=read_sol(argv[3],n,k,C,&X,&y,&Z); if (ret != 0) { printf("Giving up.\n"); exit(202); }; } else { initsoln(n,k,C,a,constraints,&X,&y,&Z); }; /* * Call the solver. */ ret=easy_sdp(n,k,C,a,constraints,0.0,&X,&y,&Z,&pobj,&dobj); /* * Write out the solution if necessary. */ if (argc >= 3) write_sol(argv[2],n,k,X,y,Z); /* * Free up memory. */ free_prob(n,k,C,a,constraints,X,y,Z); #ifdef USEGETTIME gettimeofday(&tp, NULL); endtime=(double)tp.tv_sec+(1.e-6)*tp.tv_usec; totaltime=endtime-starttime; othertime=totaltime-opotime-factortime; printf("Elements time: %f \n",opotime); printf("Factor time: %f \n",factortime); printf("Other time: %f \n",othertime); printf("Total time: %f \n",totaltime); #endif return(ret); } Csdp-6.2.0/solver/Makefile0000644000175200017520000000024313133246222014025 0ustar coincoin# # This builds the stand alone solver. # csdp: csdp.o $(CC) $(CFLAGS) csdp.o $(LIBS) -o csdp # # To clean out the directory: # clean: rm -f *.o rm -f csdp Csdp-6.2.0/example/0000755000175200017520000000000013136043252012510 5ustar coincoinCsdp-6.2.0/example/example.c0000644000175200017520000003044710522313034014311 0ustar coincoin/* An example showing how to call the easy_sdp() interface to CSDP. In this example, we solve the problem max tr(C*X) tr(A1*X)=1 tr(A2*X)=2 X >= 0 (X is PSD) where C=[2 1 1 2 3 0 1 0 2 0 1 0 3 0 0] A1=[3 1 1 3 0 0 0 0 0 0 0 0 0 1 0] A2=[0 0 0 0 3 0 1 0 4 0 1 0 5 0 1] Notice that all of the matrices have block diagonal structure. The first block is of size 2x2. The second block is of size 3x3. The third block is a diagonal block of size 2. */ /* * These standard declarations for the C library are needed. */ #include #include /* * Include CSDP declarations so that we'll know the calling interfaces. */ #include "declarations.h" /* * The main program. Setup data structures with the problem data, write * the problem out in SDPA sparse format, and then solve the problem. */ int main() { /* * The problem and solution data. */ struct blockmatrix C; double *b; struct constraintmatrix *constraints; /* * Storage for the initial and final solutions. */ struct blockmatrix X,Z; double *y; double pobj,dobj; /* * blockptr will be used to point to blocks in constraint matrices. */ struct sparseblock *blockptr; /* * A return code for the call to easy_sdp(). */ int ret; /* * The first major task is to setup the C matrix and right hand side b. */ /* * First, allocate storage for the C matrix. We have three blocks, but * because C starts arrays with index 0, we have to allocate space for * four blocks- we'll waste the 0th block. Notice that we check to * make sure that the malloc succeeded. */ C.nblocks=3; C.blocks=(struct blockrec *)malloc(4*sizeof(struct blockrec)); if (C.blocks == NULL) { printf("Couldn't allocate storage for C!\n"); exit(1); }; /* * Setup the first block. */ C.blocks[1].blockcategory=MATRIX; C.blocks[1].blocksize=2; C.blocks[1].data.mat=(double *)malloc(2*2*sizeof(double)); if (C.blocks[1].data.mat == NULL) { printf("Couldn't allocate storage for C!\n"); exit(1); }; /* * Put the entries into the first block. */ C.blocks[1].data.mat[ijtok(1,1,2)]=2.0; C.blocks[1].data.mat[ijtok(1,2,2)]=1.0; C.blocks[1].data.mat[ijtok(2,1,2)]=1.0; C.blocks[1].data.mat[ijtok(2,2,2)]=2.0; /* * Setup the second block. */ C.blocks[2].blockcategory=MATRIX; C.blocks[2].blocksize=3; C.blocks[2].data.mat=(double *)malloc(3*3*sizeof(double)); if (C.blocks[2].data.mat == NULL) { printf("Couldn't allocate storage for C!\n"); exit(1); }; /* * Put the entries into the second block. */ C.blocks[2].data.mat[ijtok(1,1,3)]=3.0; C.blocks[2].data.mat[ijtok(1,2,3)]=0.0; C.blocks[2].data.mat[ijtok(1,3,3)]=1.0; C.blocks[2].data.mat[ijtok(2,1,3)]=0.0; C.blocks[2].data.mat[ijtok(2,2,3)]=2.0; C.blocks[2].data.mat[ijtok(2,3,3)]=0.0; C.blocks[2].data.mat[ijtok(3,1,3)]=1.0; C.blocks[2].data.mat[ijtok(3,2,3)]=0.0; C.blocks[2].data.mat[ijtok(3,3,3)]=3.0; /* * Setup the third block. Note that we have to allocate space for 3 * entries because C starts array indexing with 0 rather than 1. */ C.blocks[3].blockcategory=DIAG; C.blocks[3].blocksize=2; C.blocks[3].data.vec=(double *)malloc((2+1)*sizeof(double)); if (C.blocks[3].data.vec == NULL) { printf("Couldn't allocate storage for C!\n"); exit(1); }; /* * Put the entries into the third block. */ C.blocks[3].data.vec[1]=0.0; C.blocks[3].data.vec[2]=0.0; /* * Allocate storage for the right hand side, b. */ b=(double *)malloc((2+1)*sizeof(double)); if (b==NULL) { printf("Failed to allocate storage for a!\n"); exit(1); }; /* * Fill in the entries in b. */ b[1]=1.0; b[2]=2.0; /* * The next major step is to setup the two constraint matrices A1 and A2. * Again, because C indexing starts with 0, we have to allocate space for * one more constraint. constraints[0] is not used. */ constraints=(struct constraintmatrix *)malloc( (2+1)*sizeof(struct constraintmatrix)); if (constraints==NULL) { printf("Failed to allocate storage for constraints!\n"); exit(1); }; /* * Setup the A1 matrix. Note that we start with block 3 of A1 and then * do block 1 of A1. We do this in this order because the blocks will * be inserted into the linked list of A1 blocks in reverse order. */ /* * Terminate the linked list with a NULL pointer. */ constraints[1].blocks=NULL; /* * Now, we handle block 3 of A1. */ /* * Allocate space for block 3 of A1. */ blockptr=(struct sparseblock *)malloc(sizeof(struct sparseblock)); if (blockptr==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; /* * Initialize block 3. */ blockptr->blocknum=3; blockptr->blocksize=2; blockptr->constraintnum=1; blockptr->next=NULL; blockptr->nextbyblock=NULL; blockptr->entries=(double *) malloc((1+1)*sizeof(double)); if (blockptr->entries==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; blockptr->iindices=(int *) malloc((1+1)*sizeof(int)); if (blockptr->iindices==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; blockptr->jindices=(int *) malloc((1+1)*sizeof(int)); if (blockptr->jindices==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; /* * We have 1 nonzero entry in the upper triangle of block 3 of A1. */ blockptr->numentries=1; /* * The entry in the 1,1 position of block 3 of A1 is 1.0 */ blockptr->iindices[1]=1; blockptr->jindices[1]=1; blockptr->entries[1]=1.0; /* * Note that the entry in the 2,2 position of block 3 of A1 is 0, * So we don't store anything for it. */ /* * Insert block 3 into the linked list of A1 blocks. */ blockptr->next=constraints[1].blocks; constraints[1].blocks=blockptr; /* * Now, we handle block 1. */ /* * Allocate space for block 1. */ blockptr=(struct sparseblock *)malloc(sizeof(struct sparseblock)); if (blockptr==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; /* * Initialize block 1. */ blockptr->blocknum=1; blockptr->blocksize=2; blockptr->constraintnum=1; blockptr->next=NULL; blockptr->nextbyblock=NULL; blockptr->entries=(double *) malloc((3+1)*sizeof(double)); if (blockptr->entries==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; blockptr->iindices=(int *) malloc((3+1)*sizeof(int)); if (blockptr->iindices==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; blockptr->jindices=(int *) malloc((3+1)*sizeof(int)); if (blockptr->jindices==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; /* * We have 3 nonzero entries in the upper triangle of block 1 of A1. */ blockptr->numentries=3; /* * The entry in the 1,1 position of block 1 of A1 is 3.0 */ blockptr->iindices[1]=1; blockptr->jindices[1]=1; blockptr->entries[1]=3.0; /* * The entry in the 1,2 position of block 1 of A1 is 1.0 */ blockptr->iindices[2]=1; blockptr->jindices[2]=2; blockptr->entries[2]=1.0; /* * The entry in the 2,2 position of block 1 of A1 is 3.0 */ blockptr->iindices[3]=2; blockptr->jindices[3]=2; blockptr->entries[3]=3.0; /* * Note that we don't have to store the 2,1 entry- this is assumed to be * equal to the 1,2 entry. */ /* * Insert block 1 into the linked list of A1 blocks. */ blockptr->next=constraints[1].blocks; constraints[1].blocks=blockptr; /* * Note that the second block of A1 is 0, so we didn't store anything for it. */ /* * Setup the A2 matrix. This time, there are nonzero entries in block 3 * and block 2. We start with block 3 of A2 and then do block 1 of A2. */ /* * Terminate the linked list with a NULL pointer. */ constraints[2].blocks=NULL; /* * First, we handle block 3 of A2. */ /* * Allocate space for block 3 of A2. */ blockptr=(struct sparseblock *)malloc(sizeof(struct sparseblock)); if (blockptr==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; /* * Initialize block 3. */ blockptr->blocknum=3; blockptr->blocksize=2; blockptr->constraintnum=2; blockptr->next=NULL; blockptr->nextbyblock=NULL; blockptr->entries=(double *) malloc((1+1)*sizeof(double)); if (blockptr->entries==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; blockptr->iindices=(int *) malloc((1+1)*sizeof(int)); if (blockptr->iindices==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; blockptr->jindices=(int *) malloc((1+1)*sizeof(int)); if (blockptr->jindices==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; /* * We have 1 nonzero entry in the upper triangle of block 3 of A2. */ blockptr->numentries=1; /* * The entry in the 2,2 position of block 3 of A2 is 1.0 */ blockptr->iindices[1]=2; blockptr->jindices[1]=2; blockptr->entries[1]=1.0; /* * Insert block 3 into the linked list of A2 blocks. */ blockptr->next=constraints[2].blocks; constraints[2].blocks=blockptr; /* * Now, we handle block 2. */ /* * Allocate space for block 2. */ blockptr=(struct sparseblock *)malloc(sizeof(struct sparseblock)); if (blockptr==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; /* * Initialize block 2. */ blockptr->blocknum=2; blockptr->blocksize=3; blockptr->constraintnum=2; blockptr->next=NULL; blockptr->nextbyblock=NULL; blockptr->entries=(double *) malloc((4+1)*sizeof(double)); if (blockptr->entries==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; blockptr->iindices=(int *) malloc((4+1)*sizeof(int)); if (blockptr->iindices==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; blockptr->jindices=(int *) malloc((4+1)*sizeof(int)); if (blockptr->jindices==NULL) { printf("Allocation of constraint block failed!\n"); exit(1); }; /* * We have 4 nonzero entries in the upper triangle of block 2 of A2. */ blockptr->numentries=4; /* * The entry in the 1,1 position of block 2 of A2 is 3.0 */ blockptr->iindices[1]=1; blockptr->jindices[1]=1; blockptr->entries[1]=3.0; /* * The entry in the 2,2 position of block 2 of A2 is 4.0 */ blockptr->iindices[2]=2; blockptr->jindices[2]=2; blockptr->entries[2]=4.0; /* * The entry in the 3,3 position of block 2 of A2 is 5.0 */ blockptr->iindices[3]=3; blockptr->jindices[3]=3; blockptr->entries[3]=5.0; /* * The entry in the 1,3 position of block 2 of A2 is 1.0 */ blockptr->iindices[4]=1; blockptr->jindices[4]=3; blockptr->entries[4]=1.0; /* * Note that we don't store the 0 entries and entries below the diagonal! */ /* * Insert block 2 into the linked list of A2 blocks. */ blockptr->next=constraints[2].blocks; constraints[2].blocks=blockptr; /* * At this point, we have all of the problem data setup. */ /* * Write the problem out in SDPA sparse format. */ write_prob("prob.dat-s",7,2,C,b,constraints); /* * Create an initial solution. This allocates space for X, y, and Z, * and sets initial values. */ initsoln(7,2,C,b,constraints,&X,&y,&Z); /* * Solve the problem. */ ret=easy_sdp(7,2,C,b,constraints,0.0,&X,&y,&Z,&pobj,&dobj); if (ret == 0) printf("The objective value is %.7e \n",(dobj+pobj)/2); else printf("SDP failed.\n"); /* * Write out the problem solution. */ write_sol("prob.sol",7,2,X,y,Z); /* * Free storage allocated for the problem and return. */ free_prob(7,2,C,b,constraints,X,y,Z); exit(0); } Csdp-6.2.0/example/Makefile0000644000175200017520000000037613133246222014155 0ustar coincoin# # Target all builds everything. # all: example # # This builds the example code. # example: example.o $(CC) $(CFLAGS) example.o $(LIBS) -o example # # To clean up the directory. # clean: rm -f *.o rm -f example rm -f prob.dat-s rm -f prob.sol Csdp-6.2.0/Makefile0000644000175200017520000000227213133253574012527 0ustar coincoin# # This Makefile can be used to automatically build the entire package. # # If you make changes in the Makefile or code under any subdirectory, you can # rebuild the system with "make clean" followed by "make all". # # # You can change the C compiler by setting CC=... # # CC=gcc # # CFLAGS settings for 64 bit Linux/unix systems. # export CFLAGS=-m64 -march=native -mtune=native -Ofast -fopenmp -ansi -Wall -DBIT64 -DUSEOPENMP -DSETNUMTHREADS -DUSESIGTERM -DUSEGETTIME -I../include # # LIBS settings for 64 bit Linux/unix systems. # export LIBS=-static -L../lib -lsdp -llapack -lblas -lm # # # On most systems, this should handle everything. # all: cd lib; make libsdp.a cd solver; make csdp cd theta; make all cd example; make all # # Perform a unitTest # unitTest: cd test; make all # # Install the executables in /usr/local/bin. # install: cp -f solver/csdp /usr/local/bin cp -f theta/theta /usr/local/bin cp -f theta/graphtoprob /usr/local/bin cp -f theta/complement /usr/local/bin cp -f theta/rand_graph /usr/local/bin # # Clean out all of the directories. # clean: cd lib; make clean cd solver; make clean cd theta; make clean cd test; make clean cd example; make clean Csdp-6.2.0/README0000644000175200017520000000402710522714256011745 0ustar coincoinCopyright 1997-2006, Brian Borchers. This copy of CSDP is made available under the Common Public License. See LICENCE for the details of the CPL. CSDP is a software package for solving semidefinite programming problems. The algorithm is a predictor-corrector version of the primal-dual barrier method of Helmberg, Rendl, Vanderbei, and Wolkowicz. This file includes source for a C code for SDP that uses BLAS and LAPACK subroutines. The directories are as follows: doc documentation. lib C source for libsdp.a. include Common include files used in lib, theta, and solver. solver C source for a program that reads in problems in SDPA sparse format and solves them. theta A code for computing the Lovasz Theta number of a graph. The theta code solves this problem directly. A program called graphtoprob can be used to produce a problem file in SDPA sparse format. Also includes a random graph generator and a program to compute the complement of a graph. example A very simple example of how to use the easy_sdp() routine. This code solves a problem with 2 constraints and 3 blocks in the block diagonal X matrix. This example is discussed in the user's guide. test This directory contains test problems to verify that the code works correctly. matlab MATLAB/Octave routines for interfacing to CSDP. Installation: See the INSTALL file Contact/Support: If you are having trouble compiling or running the code, see the doc directory first. The project's website can be found at . The project's maintainer can be reached by email at borchers@nmt.edu. All bug reports and feature requests can be made here: , . Csdp-6.2.0/test/0000755000175200017520000000000013136043252012034 5ustar coincoinCsdp-6.2.0/test/g500000644000175200017520000000126610455242355012365 0ustar coincoin50 103 1 2 1 28 1 50 2 21 2 22 2 36 2 49 3 10 3 30 3 34 3 35 3 49 4 11 4 12 4 17 4 34 5 18 5 19 5 34 5 46 6 19 6 21 6 30 6 38 7 9 7 22 7 23 7 44 7 45 8 29 8 31 8 34 9 20 9 33 10 23 10 38 10 49 11 22 11 34 11 35 11 46 12 14 13 17 13 47 14 15 14 34 14 38 14 39 14 49 15 16 15 28 15 35 15 46 15 48 16 28 16 30 16 43 17 30 18 37 18 38 19 21 19 25 19 39 19 41 20 30 20 34 21 33 21 46 22 37 22 40 23 30 23 37 23 39 23 43 23 46 24 25 25 33 25 38 26 39 26 46 27 29 30 31 30 36 32 33 32 43 32 46 33 41 33 46 33 48 35 40 35 48 36 46 37 39 37 42 37 43 37 48 38 42 39 45 39 46 40 41 40 47 41 43 43 48 Csdp-6.2.0/test/g50.correct0000644000175200017520000000301213132512607014007 0ustar coincoinGraph is of size 50 103 Iter: 0 Ap: 0.00e+00 Pobj: 1.0355339e+04 Ad: 0.00e+00 Dobj: 0.0000000e+00 Iter: 1 Ap: 9.31e-01 Pobj: 4.0673058e+03 Ad: 1.00e+00 Dobj: 8.0167820e+01 Iter: 2 Ap: 9.21e-01 Pobj: 1.6422689e+02 Ad: 1.00e+00 Dobj: 8.2693150e+01 Iter: 3 Ap: 9.37e-01 Pobj: 7.4239118e+00 Ad: 1.00e+00 Dobj: 8.3659491e+01 Iter: 4 Ap: 1.00e+00 Pobj: 2.7981497e+00 Ad: 1.00e+00 Dobj: 6.5829729e+01 Iter: 5 Ap: 1.00e+00 Pobj: 8.9982564e+00 Ad: 1.00e+00 Dobj: 4.2079241e+01 Iter: 6 Ap: 1.00e+00 Pobj: 1.6341142e+01 Ad: 1.00e+00 Dobj: 2.9128013e+01 Iter: 7 Ap: 1.00e+00 Pobj: 2.0177508e+01 Ad: 1.00e+00 Dobj: 2.4399455e+01 Iter: 8 Ap: 1.00e+00 Pobj: 2.1767179e+01 Ad: 1.00e+00 Dobj: 2.3397824e+01 Iter: 9 Ap: 1.00e+00 Pobj: 2.2707691e+01 Ad: 1.00e+00 Dobj: 2.3068698e+01 Iter: 10 Ap: 1.00e+00 Pobj: 2.2952986e+01 Ad: 1.00e+00 Dobj: 2.3008482e+01 Iter: 11 Ap: 1.00e+00 Pobj: 2.2997432e+01 Ad: 9.99e-01 Dobj: 2.3000437e+01 Iter: 12 Ap: 1.00e+00 Pobj: 2.2999888e+01 Ad: 1.00e+00 Dobj: 2.3000011e+01 Iter: 13 Ap: 1.00e+00 Pobj: 2.2999995e+01 Ad: 1.00e+00 Dobj: 2.3000000e+01 Iter: 14 Ap: 9.55e-01 Pobj: 2.3000000e+01 Ad: 9.60e-01 Dobj: 2.3000000e+01 Success: SDP solved Primal objective value: 2.3000000e+01 Dual objective value: 2.3000000e+01 Relative primal infeasibility: 1.33e-15 Relative dual infeasibility: 7.34e-09 Real Relative Gap: 4.13e-09 XZ Relative Gap: 5.26e-09 DIMACS error measures: 1.33e-15 0.00e+00 1.87e-07 0.00e+00 4.13e-09 5.26e-09 The Lovasz Theta Number is 2.3000000e+01 Csdp-6.2.0/test/Makefile0000644000175200017520000000134110455242355013501 0ustar coincoin# # Currently, we have only two tests to complete. The first is the solution # of the SDPA format problem theta1.dat-s. The makefile will run CSDP on # this problem and store the output in theta1.out. The second test is the # computation of the Lovasz theta number of the graph g50. # # Once the tests have run, examine the .out files and compare them with # theta1.correct and g50.correct. The optimal values should agree to # six digits or more, and the DIMACS errors should all be smaller than # 1.0e-6. # all: theta1.out g50.out # # Test the solver on theta1.dat-s # theta1.out: ../solver/csdp theta1.dat-s >theta1.out # # Test theta on the g50 graph. # g50.out: ../theta/theta g50 >g50.out clean: rm -f *.out Csdp-6.2.0/test/theta1.dat-s0000644000175200017520000015055110455242355014171 0ustar coincoin104 1 50 1.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0.000000000000000000e+00 0 1 1 1 1.000000000000000000e+00 0 1 1 2 1.000000000000000000e+00 0 1 1 3 1.000000000000000000e+00 0 1 1 4 1.000000000000000000e+00 0 1 1 5 1.000000000000000000e+00 0 1 1 6 1.000000000000000000e+00 0 1 1 7 1.000000000000000000e+00 0 1 1 8 1.000000000000000000e+00 0 1 1 9 1.000000000000000000e+00 0 1 1 10 1.000000000000000000e+00 0 1 1 11 1.000000000000000000e+00 0 1 1 12 1.000000000000000000e+00 0 1 1 13 1.000000000000000000e+00 0 1 1 14 1.000000000000000000e+00 0 1 1 15 1.000000000000000000e+00 0 1 1 16 1.000000000000000000e+00 0 1 1 17 1.000000000000000000e+00 0 1 1 18 1.000000000000000000e+00 0 1 1 19 1.000000000000000000e+00 0 1 1 20 1.000000000000000000e+00 0 1 1 21 1.000000000000000000e+00 0 1 1 22 1.000000000000000000e+00 0 1 1 23 1.000000000000000000e+00 0 1 1 24 1.000000000000000000e+00 0 1 1 25 1.000000000000000000e+00 0 1 1 26 1.000000000000000000e+00 0 1 1 27 1.000000000000000000e+00 0 1 1 28 1.000000000000000000e+00 0 1 1 29 1.000000000000000000e+00 0 1 1 30 1.000000000000000000e+00 0 1 1 31 1.000000000000000000e+00 0 1 1 32 1.000000000000000000e+00 0 1 1 33 1.000000000000000000e+00 0 1 1 34 1.000000000000000000e+00 0 1 1 35 1.000000000000000000e+00 0 1 1 36 1.000000000000000000e+00 0 1 1 37 1.000000000000000000e+00 0 1 1 38 1.000000000000000000e+00 0 1 1 39 1.000000000000000000e+00 0 1 1 40 1.000000000000000000e+00 0 1 1 41 1.000000000000000000e+00 0 1 1 42 1.000000000000000000e+00 0 1 1 43 1.000000000000000000e+00 0 1 1 44 1.000000000000000000e+00 0 1 1 45 1.000000000000000000e+00 0 1 1 46 1.000000000000000000e+00 0 1 1 47 1.000000000000000000e+00 0 1 1 48 1.000000000000000000e+00 0 1 1 49 1.000000000000000000e+00 0 1 1 50 1.000000000000000000e+00 0 1 2 2 1.000000000000000000e+00 0 1 2 3 1.000000000000000000e+00 0 1 2 4 1.000000000000000000e+00 0 1 2 5 1.000000000000000000e+00 0 1 2 6 1.000000000000000000e+00 0 1 2 7 1.000000000000000000e+00 0 1 2 8 1.000000000000000000e+00 0 1 2 9 1.000000000000000000e+00 0 1 2 10 1.000000000000000000e+00 0 1 2 11 1.000000000000000000e+00 0 1 2 12 1.000000000000000000e+00 0 1 2 13 1.000000000000000000e+00 0 1 2 14 1.000000000000000000e+00 0 1 2 15 1.000000000000000000e+00 0 1 2 16 1.000000000000000000e+00 0 1 2 17 1.000000000000000000e+00 0 1 2 18 1.000000000000000000e+00 0 1 2 19 1.000000000000000000e+00 0 1 2 20 1.000000000000000000e+00 0 1 2 21 1.000000000000000000e+00 0 1 2 22 1.000000000000000000e+00 0 1 2 23 1.000000000000000000e+00 0 1 2 24 1.000000000000000000e+00 0 1 2 25 1.000000000000000000e+00 0 1 2 26 1.000000000000000000e+00 0 1 2 27 1.000000000000000000e+00 0 1 2 28 1.000000000000000000e+00 0 1 2 29 1.000000000000000000e+00 0 1 2 30 1.000000000000000000e+00 0 1 2 31 1.000000000000000000e+00 0 1 2 32 1.000000000000000000e+00 0 1 2 33 1.000000000000000000e+00 0 1 2 34 1.000000000000000000e+00 0 1 2 35 1.000000000000000000e+00 0 1 2 36 1.000000000000000000e+00 0 1 2 37 1.000000000000000000e+00 0 1 2 38 1.000000000000000000e+00 0 1 2 39 1.000000000000000000e+00 0 1 2 40 1.000000000000000000e+00 0 1 2 41 1.000000000000000000e+00 0 1 2 42 1.000000000000000000e+00 0 1 2 43 1.000000000000000000e+00 0 1 2 44 1.000000000000000000e+00 0 1 2 45 1.000000000000000000e+00 0 1 2 46 1.000000000000000000e+00 0 1 2 47 1.000000000000000000e+00 0 1 2 48 1.000000000000000000e+00 0 1 2 49 1.000000000000000000e+00 0 1 2 50 1.000000000000000000e+00 0 1 3 3 1.000000000000000000e+00 0 1 3 4 1.000000000000000000e+00 0 1 3 5 1.000000000000000000e+00 0 1 3 6 1.000000000000000000e+00 0 1 3 7 1.000000000000000000e+00 0 1 3 8 1.000000000000000000e+00 0 1 3 9 1.000000000000000000e+00 0 1 3 10 1.000000000000000000e+00 0 1 3 11 1.000000000000000000e+00 0 1 3 12 1.000000000000000000e+00 0 1 3 13 1.000000000000000000e+00 0 1 3 14 1.000000000000000000e+00 0 1 3 15 1.000000000000000000e+00 0 1 3 16 1.000000000000000000e+00 0 1 3 17 1.000000000000000000e+00 0 1 3 18 1.000000000000000000e+00 0 1 3 19 1.000000000000000000e+00 0 1 3 20 1.000000000000000000e+00 0 1 3 21 1.000000000000000000e+00 0 1 3 22 1.000000000000000000e+00 0 1 3 23 1.000000000000000000e+00 0 1 3 24 1.000000000000000000e+00 0 1 3 25 1.000000000000000000e+00 0 1 3 26 1.000000000000000000e+00 0 1 3 27 1.000000000000000000e+00 0 1 3 28 1.000000000000000000e+00 0 1 3 29 1.000000000000000000e+00 0 1 3 30 1.000000000000000000e+00 0 1 3 31 1.000000000000000000e+00 0 1 3 32 1.000000000000000000e+00 0 1 3 33 1.000000000000000000e+00 0 1 3 34 1.000000000000000000e+00 0 1 3 35 1.000000000000000000e+00 0 1 3 36 1.000000000000000000e+00 0 1 3 37 1.000000000000000000e+00 0 1 3 38 1.000000000000000000e+00 0 1 3 39 1.000000000000000000e+00 0 1 3 40 1.000000000000000000e+00 0 1 3 41 1.000000000000000000e+00 0 1 3 42 1.000000000000000000e+00 0 1 3 43 1.000000000000000000e+00 0 1 3 44 1.000000000000000000e+00 0 1 3 45 1.000000000000000000e+00 0 1 3 46 1.000000000000000000e+00 0 1 3 47 1.000000000000000000e+00 0 1 3 48 1.000000000000000000e+00 0 1 3 49 1.000000000000000000e+00 0 1 3 50 1.000000000000000000e+00 0 1 4 4 1.000000000000000000e+00 0 1 4 5 1.000000000000000000e+00 0 1 4 6 1.000000000000000000e+00 0 1 4 7 1.000000000000000000e+00 0 1 4 8 1.000000000000000000e+00 0 1 4 9 1.000000000000000000e+00 0 1 4 10 1.000000000000000000e+00 0 1 4 11 1.000000000000000000e+00 0 1 4 12 1.000000000000000000e+00 0 1 4 13 1.000000000000000000e+00 0 1 4 14 1.000000000000000000e+00 0 1 4 15 1.000000000000000000e+00 0 1 4 16 1.000000000000000000e+00 0 1 4 17 1.000000000000000000e+00 0 1 4 18 1.000000000000000000e+00 0 1 4 19 1.000000000000000000e+00 0 1 4 20 1.000000000000000000e+00 0 1 4 21 1.000000000000000000e+00 0 1 4 22 1.000000000000000000e+00 0 1 4 23 1.000000000000000000e+00 0 1 4 24 1.000000000000000000e+00 0 1 4 25 1.000000000000000000e+00 0 1 4 26 1.000000000000000000e+00 0 1 4 27 1.000000000000000000e+00 0 1 4 28 1.000000000000000000e+00 0 1 4 29 1.000000000000000000e+00 0 1 4 30 1.000000000000000000e+00 0 1 4 31 1.000000000000000000e+00 0 1 4 32 1.000000000000000000e+00 0 1 4 33 1.000000000000000000e+00 0 1 4 34 1.000000000000000000e+00 0 1 4 35 1.000000000000000000e+00 0 1 4 36 1.000000000000000000e+00 0 1 4 37 1.000000000000000000e+00 0 1 4 38 1.000000000000000000e+00 0 1 4 39 1.000000000000000000e+00 0 1 4 40 1.000000000000000000e+00 0 1 4 41 1.000000000000000000e+00 0 1 4 42 1.000000000000000000e+00 0 1 4 43 1.000000000000000000e+00 0 1 4 44 1.000000000000000000e+00 0 1 4 45 1.000000000000000000e+00 0 1 4 46 1.000000000000000000e+00 0 1 4 47 1.000000000000000000e+00 0 1 4 48 1.000000000000000000e+00 0 1 4 49 1.000000000000000000e+00 0 1 4 50 1.000000000000000000e+00 0 1 5 5 1.000000000000000000e+00 0 1 5 6 1.000000000000000000e+00 0 1 5 7 1.000000000000000000e+00 0 1 5 8 1.000000000000000000e+00 0 1 5 9 1.000000000000000000e+00 0 1 5 10 1.000000000000000000e+00 0 1 5 11 1.000000000000000000e+00 0 1 5 12 1.000000000000000000e+00 0 1 5 13 1.000000000000000000e+00 0 1 5 14 1.000000000000000000e+00 0 1 5 15 1.000000000000000000e+00 0 1 5 16 1.000000000000000000e+00 0 1 5 17 1.000000000000000000e+00 0 1 5 18 1.000000000000000000e+00 0 1 5 19 1.000000000000000000e+00 0 1 5 20 1.000000000000000000e+00 0 1 5 21 1.000000000000000000e+00 0 1 5 22 1.000000000000000000e+00 0 1 5 23 1.000000000000000000e+00 0 1 5 24 1.000000000000000000e+00 0 1 5 25 1.000000000000000000e+00 0 1 5 26 1.000000000000000000e+00 0 1 5 27 1.000000000000000000e+00 0 1 5 28 1.000000000000000000e+00 0 1 5 29 1.000000000000000000e+00 0 1 5 30 1.000000000000000000e+00 0 1 5 31 1.000000000000000000e+00 0 1 5 32 1.000000000000000000e+00 0 1 5 33 1.000000000000000000e+00 0 1 5 34 1.000000000000000000e+00 0 1 5 35 1.000000000000000000e+00 0 1 5 36 1.000000000000000000e+00 0 1 5 37 1.000000000000000000e+00 0 1 5 38 1.000000000000000000e+00 0 1 5 39 1.000000000000000000e+00 0 1 5 40 1.000000000000000000e+00 0 1 5 41 1.000000000000000000e+00 0 1 5 42 1.000000000000000000e+00 0 1 5 43 1.000000000000000000e+00 0 1 5 44 1.000000000000000000e+00 0 1 5 45 1.000000000000000000e+00 0 1 5 46 1.000000000000000000e+00 0 1 5 47 1.000000000000000000e+00 0 1 5 48 1.000000000000000000e+00 0 1 5 49 1.000000000000000000e+00 0 1 5 50 1.000000000000000000e+00 0 1 6 6 1.000000000000000000e+00 0 1 6 7 1.000000000000000000e+00 0 1 6 8 1.000000000000000000e+00 0 1 6 9 1.000000000000000000e+00 0 1 6 10 1.000000000000000000e+00 0 1 6 11 1.000000000000000000e+00 0 1 6 12 1.000000000000000000e+00 0 1 6 13 1.000000000000000000e+00 0 1 6 14 1.000000000000000000e+00 0 1 6 15 1.000000000000000000e+00 0 1 6 16 1.000000000000000000e+00 0 1 6 17 1.000000000000000000e+00 0 1 6 18 1.000000000000000000e+00 0 1 6 19 1.000000000000000000e+00 0 1 6 20 1.000000000000000000e+00 0 1 6 21 1.000000000000000000e+00 0 1 6 22 1.000000000000000000e+00 0 1 6 23 1.000000000000000000e+00 0 1 6 24 1.000000000000000000e+00 0 1 6 25 1.000000000000000000e+00 0 1 6 26 1.000000000000000000e+00 0 1 6 27 1.000000000000000000e+00 0 1 6 28 1.000000000000000000e+00 0 1 6 29 1.000000000000000000e+00 0 1 6 30 1.000000000000000000e+00 0 1 6 31 1.000000000000000000e+00 0 1 6 32 1.000000000000000000e+00 0 1 6 33 1.000000000000000000e+00 0 1 6 34 1.000000000000000000e+00 0 1 6 35 1.000000000000000000e+00 0 1 6 36 1.000000000000000000e+00 0 1 6 37 1.000000000000000000e+00 0 1 6 38 1.000000000000000000e+00 0 1 6 39 1.000000000000000000e+00 0 1 6 40 1.000000000000000000e+00 0 1 6 41 1.000000000000000000e+00 0 1 6 42 1.000000000000000000e+00 0 1 6 43 1.000000000000000000e+00 0 1 6 44 1.000000000000000000e+00 0 1 6 45 1.000000000000000000e+00 0 1 6 46 1.000000000000000000e+00 0 1 6 47 1.000000000000000000e+00 0 1 6 48 1.000000000000000000e+00 0 1 6 49 1.000000000000000000e+00 0 1 6 50 1.000000000000000000e+00 0 1 7 7 1.000000000000000000e+00 0 1 7 8 1.000000000000000000e+00 0 1 7 9 1.000000000000000000e+00 0 1 7 10 1.000000000000000000e+00 0 1 7 11 1.000000000000000000e+00 0 1 7 12 1.000000000000000000e+00 0 1 7 13 1.000000000000000000e+00 0 1 7 14 1.000000000000000000e+00 0 1 7 15 1.000000000000000000e+00 0 1 7 16 1.000000000000000000e+00 0 1 7 17 1.000000000000000000e+00 0 1 7 18 1.000000000000000000e+00 0 1 7 19 1.000000000000000000e+00 0 1 7 20 1.000000000000000000e+00 0 1 7 21 1.000000000000000000e+00 0 1 7 22 1.000000000000000000e+00 0 1 7 23 1.000000000000000000e+00 0 1 7 24 1.000000000000000000e+00 0 1 7 25 1.000000000000000000e+00 0 1 7 26 1.000000000000000000e+00 0 1 7 27 1.000000000000000000e+00 0 1 7 28 1.000000000000000000e+00 0 1 7 29 1.000000000000000000e+00 0 1 7 30 1.000000000000000000e+00 0 1 7 31 1.000000000000000000e+00 0 1 7 32 1.000000000000000000e+00 0 1 7 33 1.000000000000000000e+00 0 1 7 34 1.000000000000000000e+00 0 1 7 35 1.000000000000000000e+00 0 1 7 36 1.000000000000000000e+00 0 1 7 37 1.000000000000000000e+00 0 1 7 38 1.000000000000000000e+00 0 1 7 39 1.000000000000000000e+00 0 1 7 40 1.000000000000000000e+00 0 1 7 41 1.000000000000000000e+00 0 1 7 42 1.000000000000000000e+00 0 1 7 43 1.000000000000000000e+00 0 1 7 44 1.000000000000000000e+00 0 1 7 45 1.000000000000000000e+00 0 1 7 46 1.000000000000000000e+00 0 1 7 47 1.000000000000000000e+00 0 1 7 48 1.000000000000000000e+00 0 1 7 49 1.000000000000000000e+00 0 1 7 50 1.000000000000000000e+00 0 1 8 8 1.000000000000000000e+00 0 1 8 9 1.000000000000000000e+00 0 1 8 10 1.000000000000000000e+00 0 1 8 11 1.000000000000000000e+00 0 1 8 12 1.000000000000000000e+00 0 1 8 13 1.000000000000000000e+00 0 1 8 14 1.000000000000000000e+00 0 1 8 15 1.000000000000000000e+00 0 1 8 16 1.000000000000000000e+00 0 1 8 17 1.000000000000000000e+00 0 1 8 18 1.000000000000000000e+00 0 1 8 19 1.000000000000000000e+00 0 1 8 20 1.000000000000000000e+00 0 1 8 21 1.000000000000000000e+00 0 1 8 22 1.000000000000000000e+00 0 1 8 23 1.000000000000000000e+00 0 1 8 24 1.000000000000000000e+00 0 1 8 25 1.000000000000000000e+00 0 1 8 26 1.000000000000000000e+00 0 1 8 27 1.000000000000000000e+00 0 1 8 28 1.000000000000000000e+00 0 1 8 29 1.000000000000000000e+00 0 1 8 30 1.000000000000000000e+00 0 1 8 31 1.000000000000000000e+00 0 1 8 32 1.000000000000000000e+00 0 1 8 33 1.000000000000000000e+00 0 1 8 34 1.000000000000000000e+00 0 1 8 35 1.000000000000000000e+00 0 1 8 36 1.000000000000000000e+00 0 1 8 37 1.000000000000000000e+00 0 1 8 38 1.000000000000000000e+00 0 1 8 39 1.000000000000000000e+00 0 1 8 40 1.000000000000000000e+00 0 1 8 41 1.000000000000000000e+00 0 1 8 42 1.000000000000000000e+00 0 1 8 43 1.000000000000000000e+00 0 1 8 44 1.000000000000000000e+00 0 1 8 45 1.000000000000000000e+00 0 1 8 46 1.000000000000000000e+00 0 1 8 47 1.000000000000000000e+00 0 1 8 48 1.000000000000000000e+00 0 1 8 49 1.000000000000000000e+00 0 1 8 50 1.000000000000000000e+00 0 1 9 9 1.000000000000000000e+00 0 1 9 10 1.000000000000000000e+00 0 1 9 11 1.000000000000000000e+00 0 1 9 12 1.000000000000000000e+00 0 1 9 13 1.000000000000000000e+00 0 1 9 14 1.000000000000000000e+00 0 1 9 15 1.000000000000000000e+00 0 1 9 16 1.000000000000000000e+00 0 1 9 17 1.000000000000000000e+00 0 1 9 18 1.000000000000000000e+00 0 1 9 19 1.000000000000000000e+00 0 1 9 20 1.000000000000000000e+00 0 1 9 21 1.000000000000000000e+00 0 1 9 22 1.000000000000000000e+00 0 1 9 23 1.000000000000000000e+00 0 1 9 24 1.000000000000000000e+00 0 1 9 25 1.000000000000000000e+00 0 1 9 26 1.000000000000000000e+00 0 1 9 27 1.000000000000000000e+00 0 1 9 28 1.000000000000000000e+00 0 1 9 29 1.000000000000000000e+00 0 1 9 30 1.000000000000000000e+00 0 1 9 31 1.000000000000000000e+00 0 1 9 32 1.000000000000000000e+00 0 1 9 33 1.000000000000000000e+00 0 1 9 34 1.000000000000000000e+00 0 1 9 35 1.000000000000000000e+00 0 1 9 36 1.000000000000000000e+00 0 1 9 37 1.000000000000000000e+00 0 1 9 38 1.000000000000000000e+00 0 1 9 39 1.000000000000000000e+00 0 1 9 40 1.000000000000000000e+00 0 1 9 41 1.000000000000000000e+00 0 1 9 42 1.000000000000000000e+00 0 1 9 43 1.000000000000000000e+00 0 1 9 44 1.000000000000000000e+00 0 1 9 45 1.000000000000000000e+00 0 1 9 46 1.000000000000000000e+00 0 1 9 47 1.000000000000000000e+00 0 1 9 48 1.000000000000000000e+00 0 1 9 49 1.000000000000000000e+00 0 1 9 50 1.000000000000000000e+00 0 1 10 10 1.000000000000000000e+00 0 1 10 11 1.000000000000000000e+00 0 1 10 12 1.000000000000000000e+00 0 1 10 13 1.000000000000000000e+00 0 1 10 14 1.000000000000000000e+00 0 1 10 15 1.000000000000000000e+00 0 1 10 16 1.000000000000000000e+00 0 1 10 17 1.000000000000000000e+00 0 1 10 18 1.000000000000000000e+00 0 1 10 19 1.000000000000000000e+00 0 1 10 20 1.000000000000000000e+00 0 1 10 21 1.000000000000000000e+00 0 1 10 22 1.000000000000000000e+00 0 1 10 23 1.000000000000000000e+00 0 1 10 24 1.000000000000000000e+00 0 1 10 25 1.000000000000000000e+00 0 1 10 26 1.000000000000000000e+00 0 1 10 27 1.000000000000000000e+00 0 1 10 28 1.000000000000000000e+00 0 1 10 29 1.000000000000000000e+00 0 1 10 30 1.000000000000000000e+00 0 1 10 31 1.000000000000000000e+00 0 1 10 32 1.000000000000000000e+00 0 1 10 33 1.000000000000000000e+00 0 1 10 34 1.000000000000000000e+00 0 1 10 35 1.000000000000000000e+00 0 1 10 36 1.000000000000000000e+00 0 1 10 37 1.000000000000000000e+00 0 1 10 38 1.000000000000000000e+00 0 1 10 39 1.000000000000000000e+00 0 1 10 40 1.000000000000000000e+00 0 1 10 41 1.000000000000000000e+00 0 1 10 42 1.000000000000000000e+00 0 1 10 43 1.000000000000000000e+00 0 1 10 44 1.000000000000000000e+00 0 1 10 45 1.000000000000000000e+00 0 1 10 46 1.000000000000000000e+00 0 1 10 47 1.000000000000000000e+00 0 1 10 48 1.000000000000000000e+00 0 1 10 49 1.000000000000000000e+00 0 1 10 50 1.000000000000000000e+00 0 1 11 11 1.000000000000000000e+00 0 1 11 12 1.000000000000000000e+00 0 1 11 13 1.000000000000000000e+00 0 1 11 14 1.000000000000000000e+00 0 1 11 15 1.000000000000000000e+00 0 1 11 16 1.000000000000000000e+00 0 1 11 17 1.000000000000000000e+00 0 1 11 18 1.000000000000000000e+00 0 1 11 19 1.000000000000000000e+00 0 1 11 20 1.000000000000000000e+00 0 1 11 21 1.000000000000000000e+00 0 1 11 22 1.000000000000000000e+00 0 1 11 23 1.000000000000000000e+00 0 1 11 24 1.000000000000000000e+00 0 1 11 25 1.000000000000000000e+00 0 1 11 26 1.000000000000000000e+00 0 1 11 27 1.000000000000000000e+00 0 1 11 28 1.000000000000000000e+00 0 1 11 29 1.000000000000000000e+00 0 1 11 30 1.000000000000000000e+00 0 1 11 31 1.000000000000000000e+00 0 1 11 32 1.000000000000000000e+00 0 1 11 33 1.000000000000000000e+00 0 1 11 34 1.000000000000000000e+00 0 1 11 35 1.000000000000000000e+00 0 1 11 36 1.000000000000000000e+00 0 1 11 37 1.000000000000000000e+00 0 1 11 38 1.000000000000000000e+00 0 1 11 39 1.000000000000000000e+00 0 1 11 40 1.000000000000000000e+00 0 1 11 41 1.000000000000000000e+00 0 1 11 42 1.000000000000000000e+00 0 1 11 43 1.000000000000000000e+00 0 1 11 44 1.000000000000000000e+00 0 1 11 45 1.000000000000000000e+00 0 1 11 46 1.000000000000000000e+00 0 1 11 47 1.000000000000000000e+00 0 1 11 48 1.000000000000000000e+00 0 1 11 49 1.000000000000000000e+00 0 1 11 50 1.000000000000000000e+00 0 1 12 12 1.000000000000000000e+00 0 1 12 13 1.000000000000000000e+00 0 1 12 14 1.000000000000000000e+00 0 1 12 15 1.000000000000000000e+00 0 1 12 16 1.000000000000000000e+00 0 1 12 17 1.000000000000000000e+00 0 1 12 18 1.000000000000000000e+00 0 1 12 19 1.000000000000000000e+00 0 1 12 20 1.000000000000000000e+00 0 1 12 21 1.000000000000000000e+00 0 1 12 22 1.000000000000000000e+00 0 1 12 23 1.000000000000000000e+00 0 1 12 24 1.000000000000000000e+00 0 1 12 25 1.000000000000000000e+00 0 1 12 26 1.000000000000000000e+00 0 1 12 27 1.000000000000000000e+00 0 1 12 28 1.000000000000000000e+00 0 1 12 29 1.000000000000000000e+00 0 1 12 30 1.000000000000000000e+00 0 1 12 31 1.000000000000000000e+00 0 1 12 32 1.000000000000000000e+00 0 1 12 33 1.000000000000000000e+00 0 1 12 34 1.000000000000000000e+00 0 1 12 35 1.000000000000000000e+00 0 1 12 36 1.000000000000000000e+00 0 1 12 37 1.000000000000000000e+00 0 1 12 38 1.000000000000000000e+00 0 1 12 39 1.000000000000000000e+00 0 1 12 40 1.000000000000000000e+00 0 1 12 41 1.000000000000000000e+00 0 1 12 42 1.000000000000000000e+00 0 1 12 43 1.000000000000000000e+00 0 1 12 44 1.000000000000000000e+00 0 1 12 45 1.000000000000000000e+00 0 1 12 46 1.000000000000000000e+00 0 1 12 47 1.000000000000000000e+00 0 1 12 48 1.000000000000000000e+00 0 1 12 49 1.000000000000000000e+00 0 1 12 50 1.000000000000000000e+00 0 1 13 13 1.000000000000000000e+00 0 1 13 14 1.000000000000000000e+00 0 1 13 15 1.000000000000000000e+00 0 1 13 16 1.000000000000000000e+00 0 1 13 17 1.000000000000000000e+00 0 1 13 18 1.000000000000000000e+00 0 1 13 19 1.000000000000000000e+00 0 1 13 20 1.000000000000000000e+00 0 1 13 21 1.000000000000000000e+00 0 1 13 22 1.000000000000000000e+00 0 1 13 23 1.000000000000000000e+00 0 1 13 24 1.000000000000000000e+00 0 1 13 25 1.000000000000000000e+00 0 1 13 26 1.000000000000000000e+00 0 1 13 27 1.000000000000000000e+00 0 1 13 28 1.000000000000000000e+00 0 1 13 29 1.000000000000000000e+00 0 1 13 30 1.000000000000000000e+00 0 1 13 31 1.000000000000000000e+00 0 1 13 32 1.000000000000000000e+00 0 1 13 33 1.000000000000000000e+00 0 1 13 34 1.000000000000000000e+00 0 1 13 35 1.000000000000000000e+00 0 1 13 36 1.000000000000000000e+00 0 1 13 37 1.000000000000000000e+00 0 1 13 38 1.000000000000000000e+00 0 1 13 39 1.000000000000000000e+00 0 1 13 40 1.000000000000000000e+00 0 1 13 41 1.000000000000000000e+00 0 1 13 42 1.000000000000000000e+00 0 1 13 43 1.000000000000000000e+00 0 1 13 44 1.000000000000000000e+00 0 1 13 45 1.000000000000000000e+00 0 1 13 46 1.000000000000000000e+00 0 1 13 47 1.000000000000000000e+00 0 1 13 48 1.000000000000000000e+00 0 1 13 49 1.000000000000000000e+00 0 1 13 50 1.000000000000000000e+00 0 1 14 14 1.000000000000000000e+00 0 1 14 15 1.000000000000000000e+00 0 1 14 16 1.000000000000000000e+00 0 1 14 17 1.000000000000000000e+00 0 1 14 18 1.000000000000000000e+00 0 1 14 19 1.000000000000000000e+00 0 1 14 20 1.000000000000000000e+00 0 1 14 21 1.000000000000000000e+00 0 1 14 22 1.000000000000000000e+00 0 1 14 23 1.000000000000000000e+00 0 1 14 24 1.000000000000000000e+00 0 1 14 25 1.000000000000000000e+00 0 1 14 26 1.000000000000000000e+00 0 1 14 27 1.000000000000000000e+00 0 1 14 28 1.000000000000000000e+00 0 1 14 29 1.000000000000000000e+00 0 1 14 30 1.000000000000000000e+00 0 1 14 31 1.000000000000000000e+00 0 1 14 32 1.000000000000000000e+00 0 1 14 33 1.000000000000000000e+00 0 1 14 34 1.000000000000000000e+00 0 1 14 35 1.000000000000000000e+00 0 1 14 36 1.000000000000000000e+00 0 1 14 37 1.000000000000000000e+00 0 1 14 38 1.000000000000000000e+00 0 1 14 39 1.000000000000000000e+00 0 1 14 40 1.000000000000000000e+00 0 1 14 41 1.000000000000000000e+00 0 1 14 42 1.000000000000000000e+00 0 1 14 43 1.000000000000000000e+00 0 1 14 44 1.000000000000000000e+00 0 1 14 45 1.000000000000000000e+00 0 1 14 46 1.000000000000000000e+00 0 1 14 47 1.000000000000000000e+00 0 1 14 48 1.000000000000000000e+00 0 1 14 49 1.000000000000000000e+00 0 1 14 50 1.000000000000000000e+00 0 1 15 15 1.000000000000000000e+00 0 1 15 16 1.000000000000000000e+00 0 1 15 17 1.000000000000000000e+00 0 1 15 18 1.000000000000000000e+00 0 1 15 19 1.000000000000000000e+00 0 1 15 20 1.000000000000000000e+00 0 1 15 21 1.000000000000000000e+00 0 1 15 22 1.000000000000000000e+00 0 1 15 23 1.000000000000000000e+00 0 1 15 24 1.000000000000000000e+00 0 1 15 25 1.000000000000000000e+00 0 1 15 26 1.000000000000000000e+00 0 1 15 27 1.000000000000000000e+00 0 1 15 28 1.000000000000000000e+00 0 1 15 29 1.000000000000000000e+00 0 1 15 30 1.000000000000000000e+00 0 1 15 31 1.000000000000000000e+00 0 1 15 32 1.000000000000000000e+00 0 1 15 33 1.000000000000000000e+00 0 1 15 34 1.000000000000000000e+00 0 1 15 35 1.000000000000000000e+00 0 1 15 36 1.000000000000000000e+00 0 1 15 37 1.000000000000000000e+00 0 1 15 38 1.000000000000000000e+00 0 1 15 39 1.000000000000000000e+00 0 1 15 40 1.000000000000000000e+00 0 1 15 41 1.000000000000000000e+00 0 1 15 42 1.000000000000000000e+00 0 1 15 43 1.000000000000000000e+00 0 1 15 44 1.000000000000000000e+00 0 1 15 45 1.000000000000000000e+00 0 1 15 46 1.000000000000000000e+00 0 1 15 47 1.000000000000000000e+00 0 1 15 48 1.000000000000000000e+00 0 1 15 49 1.000000000000000000e+00 0 1 15 50 1.000000000000000000e+00 0 1 16 16 1.000000000000000000e+00 0 1 16 17 1.000000000000000000e+00 0 1 16 18 1.000000000000000000e+00 0 1 16 19 1.000000000000000000e+00 0 1 16 20 1.000000000000000000e+00 0 1 16 21 1.000000000000000000e+00 0 1 16 22 1.000000000000000000e+00 0 1 16 23 1.000000000000000000e+00 0 1 16 24 1.000000000000000000e+00 0 1 16 25 1.000000000000000000e+00 0 1 16 26 1.000000000000000000e+00 0 1 16 27 1.000000000000000000e+00 0 1 16 28 1.000000000000000000e+00 0 1 16 29 1.000000000000000000e+00 0 1 16 30 1.000000000000000000e+00 0 1 16 31 1.000000000000000000e+00 0 1 16 32 1.000000000000000000e+00 0 1 16 33 1.000000000000000000e+00 0 1 16 34 1.000000000000000000e+00 0 1 16 35 1.000000000000000000e+00 0 1 16 36 1.000000000000000000e+00 0 1 16 37 1.000000000000000000e+00 0 1 16 38 1.000000000000000000e+00 0 1 16 39 1.000000000000000000e+00 0 1 16 40 1.000000000000000000e+00 0 1 16 41 1.000000000000000000e+00 0 1 16 42 1.000000000000000000e+00 0 1 16 43 1.000000000000000000e+00 0 1 16 44 1.000000000000000000e+00 0 1 16 45 1.000000000000000000e+00 0 1 16 46 1.000000000000000000e+00 0 1 16 47 1.000000000000000000e+00 0 1 16 48 1.000000000000000000e+00 0 1 16 49 1.000000000000000000e+00 0 1 16 50 1.000000000000000000e+00 0 1 17 17 1.000000000000000000e+00 0 1 17 18 1.000000000000000000e+00 0 1 17 19 1.000000000000000000e+00 0 1 17 20 1.000000000000000000e+00 0 1 17 21 1.000000000000000000e+00 0 1 17 22 1.000000000000000000e+00 0 1 17 23 1.000000000000000000e+00 0 1 17 24 1.000000000000000000e+00 0 1 17 25 1.000000000000000000e+00 0 1 17 26 1.000000000000000000e+00 0 1 17 27 1.000000000000000000e+00 0 1 17 28 1.000000000000000000e+00 0 1 17 29 1.000000000000000000e+00 0 1 17 30 1.000000000000000000e+00 0 1 17 31 1.000000000000000000e+00 0 1 17 32 1.000000000000000000e+00 0 1 17 33 1.000000000000000000e+00 0 1 17 34 1.000000000000000000e+00 0 1 17 35 1.000000000000000000e+00 0 1 17 36 1.000000000000000000e+00 0 1 17 37 1.000000000000000000e+00 0 1 17 38 1.000000000000000000e+00 0 1 17 39 1.000000000000000000e+00 0 1 17 40 1.000000000000000000e+00 0 1 17 41 1.000000000000000000e+00 0 1 17 42 1.000000000000000000e+00 0 1 17 43 1.000000000000000000e+00 0 1 17 44 1.000000000000000000e+00 0 1 17 45 1.000000000000000000e+00 0 1 17 46 1.000000000000000000e+00 0 1 17 47 1.000000000000000000e+00 0 1 17 48 1.000000000000000000e+00 0 1 17 49 1.000000000000000000e+00 0 1 17 50 1.000000000000000000e+00 0 1 18 18 1.000000000000000000e+00 0 1 18 19 1.000000000000000000e+00 0 1 18 20 1.000000000000000000e+00 0 1 18 21 1.000000000000000000e+00 0 1 18 22 1.000000000000000000e+00 0 1 18 23 1.000000000000000000e+00 0 1 18 24 1.000000000000000000e+00 0 1 18 25 1.000000000000000000e+00 0 1 18 26 1.000000000000000000e+00 0 1 18 27 1.000000000000000000e+00 0 1 18 28 1.000000000000000000e+00 0 1 18 29 1.000000000000000000e+00 0 1 18 30 1.000000000000000000e+00 0 1 18 31 1.000000000000000000e+00 0 1 18 32 1.000000000000000000e+00 0 1 18 33 1.000000000000000000e+00 0 1 18 34 1.000000000000000000e+00 0 1 18 35 1.000000000000000000e+00 0 1 18 36 1.000000000000000000e+00 0 1 18 37 1.000000000000000000e+00 0 1 18 38 1.000000000000000000e+00 0 1 18 39 1.000000000000000000e+00 0 1 18 40 1.000000000000000000e+00 0 1 18 41 1.000000000000000000e+00 0 1 18 42 1.000000000000000000e+00 0 1 18 43 1.000000000000000000e+00 0 1 18 44 1.000000000000000000e+00 0 1 18 45 1.000000000000000000e+00 0 1 18 46 1.000000000000000000e+00 0 1 18 47 1.000000000000000000e+00 0 1 18 48 1.000000000000000000e+00 0 1 18 49 1.000000000000000000e+00 0 1 18 50 1.000000000000000000e+00 0 1 19 19 1.000000000000000000e+00 0 1 19 20 1.000000000000000000e+00 0 1 19 21 1.000000000000000000e+00 0 1 19 22 1.000000000000000000e+00 0 1 19 23 1.000000000000000000e+00 0 1 19 24 1.000000000000000000e+00 0 1 19 25 1.000000000000000000e+00 0 1 19 26 1.000000000000000000e+00 0 1 19 27 1.000000000000000000e+00 0 1 19 28 1.000000000000000000e+00 0 1 19 29 1.000000000000000000e+00 0 1 19 30 1.000000000000000000e+00 0 1 19 31 1.000000000000000000e+00 0 1 19 32 1.000000000000000000e+00 0 1 19 33 1.000000000000000000e+00 0 1 19 34 1.000000000000000000e+00 0 1 19 35 1.000000000000000000e+00 0 1 19 36 1.000000000000000000e+00 0 1 19 37 1.000000000000000000e+00 0 1 19 38 1.000000000000000000e+00 0 1 19 39 1.000000000000000000e+00 0 1 19 40 1.000000000000000000e+00 0 1 19 41 1.000000000000000000e+00 0 1 19 42 1.000000000000000000e+00 0 1 19 43 1.000000000000000000e+00 0 1 19 44 1.000000000000000000e+00 0 1 19 45 1.000000000000000000e+00 0 1 19 46 1.000000000000000000e+00 0 1 19 47 1.000000000000000000e+00 0 1 19 48 1.000000000000000000e+00 0 1 19 49 1.000000000000000000e+00 0 1 19 50 1.000000000000000000e+00 0 1 20 20 1.000000000000000000e+00 0 1 20 21 1.000000000000000000e+00 0 1 20 22 1.000000000000000000e+00 0 1 20 23 1.000000000000000000e+00 0 1 20 24 1.000000000000000000e+00 0 1 20 25 1.000000000000000000e+00 0 1 20 26 1.000000000000000000e+00 0 1 20 27 1.000000000000000000e+00 0 1 20 28 1.000000000000000000e+00 0 1 20 29 1.000000000000000000e+00 0 1 20 30 1.000000000000000000e+00 0 1 20 31 1.000000000000000000e+00 0 1 20 32 1.000000000000000000e+00 0 1 20 33 1.000000000000000000e+00 0 1 20 34 1.000000000000000000e+00 0 1 20 35 1.000000000000000000e+00 0 1 20 36 1.000000000000000000e+00 0 1 20 37 1.000000000000000000e+00 0 1 20 38 1.000000000000000000e+00 0 1 20 39 1.000000000000000000e+00 0 1 20 40 1.000000000000000000e+00 0 1 20 41 1.000000000000000000e+00 0 1 20 42 1.000000000000000000e+00 0 1 20 43 1.000000000000000000e+00 0 1 20 44 1.000000000000000000e+00 0 1 20 45 1.000000000000000000e+00 0 1 20 46 1.000000000000000000e+00 0 1 20 47 1.000000000000000000e+00 0 1 20 48 1.000000000000000000e+00 0 1 20 49 1.000000000000000000e+00 0 1 20 50 1.000000000000000000e+00 0 1 21 21 1.000000000000000000e+00 0 1 21 22 1.000000000000000000e+00 0 1 21 23 1.000000000000000000e+00 0 1 21 24 1.000000000000000000e+00 0 1 21 25 1.000000000000000000e+00 0 1 21 26 1.000000000000000000e+00 0 1 21 27 1.000000000000000000e+00 0 1 21 28 1.000000000000000000e+00 0 1 21 29 1.000000000000000000e+00 0 1 21 30 1.000000000000000000e+00 0 1 21 31 1.000000000000000000e+00 0 1 21 32 1.000000000000000000e+00 0 1 21 33 1.000000000000000000e+00 0 1 21 34 1.000000000000000000e+00 0 1 21 35 1.000000000000000000e+00 0 1 21 36 1.000000000000000000e+00 0 1 21 37 1.000000000000000000e+00 0 1 21 38 1.000000000000000000e+00 0 1 21 39 1.000000000000000000e+00 0 1 21 40 1.000000000000000000e+00 0 1 21 41 1.000000000000000000e+00 0 1 21 42 1.000000000000000000e+00 0 1 21 43 1.000000000000000000e+00 0 1 21 44 1.000000000000000000e+00 0 1 21 45 1.000000000000000000e+00 0 1 21 46 1.000000000000000000e+00 0 1 21 47 1.000000000000000000e+00 0 1 21 48 1.000000000000000000e+00 0 1 21 49 1.000000000000000000e+00 0 1 21 50 1.000000000000000000e+00 0 1 22 22 1.000000000000000000e+00 0 1 22 23 1.000000000000000000e+00 0 1 22 24 1.000000000000000000e+00 0 1 22 25 1.000000000000000000e+00 0 1 22 26 1.000000000000000000e+00 0 1 22 27 1.000000000000000000e+00 0 1 22 28 1.000000000000000000e+00 0 1 22 29 1.000000000000000000e+00 0 1 22 30 1.000000000000000000e+00 0 1 22 31 1.000000000000000000e+00 0 1 22 32 1.000000000000000000e+00 0 1 22 33 1.000000000000000000e+00 0 1 22 34 1.000000000000000000e+00 0 1 22 35 1.000000000000000000e+00 0 1 22 36 1.000000000000000000e+00 0 1 22 37 1.000000000000000000e+00 0 1 22 38 1.000000000000000000e+00 0 1 22 39 1.000000000000000000e+00 0 1 22 40 1.000000000000000000e+00 0 1 22 41 1.000000000000000000e+00 0 1 22 42 1.000000000000000000e+00 0 1 22 43 1.000000000000000000e+00 0 1 22 44 1.000000000000000000e+00 0 1 22 45 1.000000000000000000e+00 0 1 22 46 1.000000000000000000e+00 0 1 22 47 1.000000000000000000e+00 0 1 22 48 1.000000000000000000e+00 0 1 22 49 1.000000000000000000e+00 0 1 22 50 1.000000000000000000e+00 0 1 23 23 1.000000000000000000e+00 0 1 23 24 1.000000000000000000e+00 0 1 23 25 1.000000000000000000e+00 0 1 23 26 1.000000000000000000e+00 0 1 23 27 1.000000000000000000e+00 0 1 23 28 1.000000000000000000e+00 0 1 23 29 1.000000000000000000e+00 0 1 23 30 1.000000000000000000e+00 0 1 23 31 1.000000000000000000e+00 0 1 23 32 1.000000000000000000e+00 0 1 23 33 1.000000000000000000e+00 0 1 23 34 1.000000000000000000e+00 0 1 23 35 1.000000000000000000e+00 0 1 23 36 1.000000000000000000e+00 0 1 23 37 1.000000000000000000e+00 0 1 23 38 1.000000000000000000e+00 0 1 23 39 1.000000000000000000e+00 0 1 23 40 1.000000000000000000e+00 0 1 23 41 1.000000000000000000e+00 0 1 23 42 1.000000000000000000e+00 0 1 23 43 1.000000000000000000e+00 0 1 23 44 1.000000000000000000e+00 0 1 23 45 1.000000000000000000e+00 0 1 23 46 1.000000000000000000e+00 0 1 23 47 1.000000000000000000e+00 0 1 23 48 1.000000000000000000e+00 0 1 23 49 1.000000000000000000e+00 0 1 23 50 1.000000000000000000e+00 0 1 24 24 1.000000000000000000e+00 0 1 24 25 1.000000000000000000e+00 0 1 24 26 1.000000000000000000e+00 0 1 24 27 1.000000000000000000e+00 0 1 24 28 1.000000000000000000e+00 0 1 24 29 1.000000000000000000e+00 0 1 24 30 1.000000000000000000e+00 0 1 24 31 1.000000000000000000e+00 0 1 24 32 1.000000000000000000e+00 0 1 24 33 1.000000000000000000e+00 0 1 24 34 1.000000000000000000e+00 0 1 24 35 1.000000000000000000e+00 0 1 24 36 1.000000000000000000e+00 0 1 24 37 1.000000000000000000e+00 0 1 24 38 1.000000000000000000e+00 0 1 24 39 1.000000000000000000e+00 0 1 24 40 1.000000000000000000e+00 0 1 24 41 1.000000000000000000e+00 0 1 24 42 1.000000000000000000e+00 0 1 24 43 1.000000000000000000e+00 0 1 24 44 1.000000000000000000e+00 0 1 24 45 1.000000000000000000e+00 0 1 24 46 1.000000000000000000e+00 0 1 24 47 1.000000000000000000e+00 0 1 24 48 1.000000000000000000e+00 0 1 24 49 1.000000000000000000e+00 0 1 24 50 1.000000000000000000e+00 0 1 25 25 1.000000000000000000e+00 0 1 25 26 1.000000000000000000e+00 0 1 25 27 1.000000000000000000e+00 0 1 25 28 1.000000000000000000e+00 0 1 25 29 1.000000000000000000e+00 0 1 25 30 1.000000000000000000e+00 0 1 25 31 1.000000000000000000e+00 0 1 25 32 1.000000000000000000e+00 0 1 25 33 1.000000000000000000e+00 0 1 25 34 1.000000000000000000e+00 0 1 25 35 1.000000000000000000e+00 0 1 25 36 1.000000000000000000e+00 0 1 25 37 1.000000000000000000e+00 0 1 25 38 1.000000000000000000e+00 0 1 25 39 1.000000000000000000e+00 0 1 25 40 1.000000000000000000e+00 0 1 25 41 1.000000000000000000e+00 0 1 25 42 1.000000000000000000e+00 0 1 25 43 1.000000000000000000e+00 0 1 25 44 1.000000000000000000e+00 0 1 25 45 1.000000000000000000e+00 0 1 25 46 1.000000000000000000e+00 0 1 25 47 1.000000000000000000e+00 0 1 25 48 1.000000000000000000e+00 0 1 25 49 1.000000000000000000e+00 0 1 25 50 1.000000000000000000e+00 0 1 26 26 1.000000000000000000e+00 0 1 26 27 1.000000000000000000e+00 0 1 26 28 1.000000000000000000e+00 0 1 26 29 1.000000000000000000e+00 0 1 26 30 1.000000000000000000e+00 0 1 26 31 1.000000000000000000e+00 0 1 26 32 1.000000000000000000e+00 0 1 26 33 1.000000000000000000e+00 0 1 26 34 1.000000000000000000e+00 0 1 26 35 1.000000000000000000e+00 0 1 26 36 1.000000000000000000e+00 0 1 26 37 1.000000000000000000e+00 0 1 26 38 1.000000000000000000e+00 0 1 26 39 1.000000000000000000e+00 0 1 26 40 1.000000000000000000e+00 0 1 26 41 1.000000000000000000e+00 0 1 26 42 1.000000000000000000e+00 0 1 26 43 1.000000000000000000e+00 0 1 26 44 1.000000000000000000e+00 0 1 26 45 1.000000000000000000e+00 0 1 26 46 1.000000000000000000e+00 0 1 26 47 1.000000000000000000e+00 0 1 26 48 1.000000000000000000e+00 0 1 26 49 1.000000000000000000e+00 0 1 26 50 1.000000000000000000e+00 0 1 27 27 1.000000000000000000e+00 0 1 27 28 1.000000000000000000e+00 0 1 27 29 1.000000000000000000e+00 0 1 27 30 1.000000000000000000e+00 0 1 27 31 1.000000000000000000e+00 0 1 27 32 1.000000000000000000e+00 0 1 27 33 1.000000000000000000e+00 0 1 27 34 1.000000000000000000e+00 0 1 27 35 1.000000000000000000e+00 0 1 27 36 1.000000000000000000e+00 0 1 27 37 1.000000000000000000e+00 0 1 27 38 1.000000000000000000e+00 0 1 27 39 1.000000000000000000e+00 0 1 27 40 1.000000000000000000e+00 0 1 27 41 1.000000000000000000e+00 0 1 27 42 1.000000000000000000e+00 0 1 27 43 1.000000000000000000e+00 0 1 27 44 1.000000000000000000e+00 0 1 27 45 1.000000000000000000e+00 0 1 27 46 1.000000000000000000e+00 0 1 27 47 1.000000000000000000e+00 0 1 27 48 1.000000000000000000e+00 0 1 27 49 1.000000000000000000e+00 0 1 27 50 1.000000000000000000e+00 0 1 28 28 1.000000000000000000e+00 0 1 28 29 1.000000000000000000e+00 0 1 28 30 1.000000000000000000e+00 0 1 28 31 1.000000000000000000e+00 0 1 28 32 1.000000000000000000e+00 0 1 28 33 1.000000000000000000e+00 0 1 28 34 1.000000000000000000e+00 0 1 28 35 1.000000000000000000e+00 0 1 28 36 1.000000000000000000e+00 0 1 28 37 1.000000000000000000e+00 0 1 28 38 1.000000000000000000e+00 0 1 28 39 1.000000000000000000e+00 0 1 28 40 1.000000000000000000e+00 0 1 28 41 1.000000000000000000e+00 0 1 28 42 1.000000000000000000e+00 0 1 28 43 1.000000000000000000e+00 0 1 28 44 1.000000000000000000e+00 0 1 28 45 1.000000000000000000e+00 0 1 28 46 1.000000000000000000e+00 0 1 28 47 1.000000000000000000e+00 0 1 28 48 1.000000000000000000e+00 0 1 28 49 1.000000000000000000e+00 0 1 28 50 1.000000000000000000e+00 0 1 29 29 1.000000000000000000e+00 0 1 29 30 1.000000000000000000e+00 0 1 29 31 1.000000000000000000e+00 0 1 29 32 1.000000000000000000e+00 0 1 29 33 1.000000000000000000e+00 0 1 29 34 1.000000000000000000e+00 0 1 29 35 1.000000000000000000e+00 0 1 29 36 1.000000000000000000e+00 0 1 29 37 1.000000000000000000e+00 0 1 29 38 1.000000000000000000e+00 0 1 29 39 1.000000000000000000e+00 0 1 29 40 1.000000000000000000e+00 0 1 29 41 1.000000000000000000e+00 0 1 29 42 1.000000000000000000e+00 0 1 29 43 1.000000000000000000e+00 0 1 29 44 1.000000000000000000e+00 0 1 29 45 1.000000000000000000e+00 0 1 29 46 1.000000000000000000e+00 0 1 29 47 1.000000000000000000e+00 0 1 29 48 1.000000000000000000e+00 0 1 29 49 1.000000000000000000e+00 0 1 29 50 1.000000000000000000e+00 0 1 30 30 1.000000000000000000e+00 0 1 30 31 1.000000000000000000e+00 0 1 30 32 1.000000000000000000e+00 0 1 30 33 1.000000000000000000e+00 0 1 30 34 1.000000000000000000e+00 0 1 30 35 1.000000000000000000e+00 0 1 30 36 1.000000000000000000e+00 0 1 30 37 1.000000000000000000e+00 0 1 30 38 1.000000000000000000e+00 0 1 30 39 1.000000000000000000e+00 0 1 30 40 1.000000000000000000e+00 0 1 30 41 1.000000000000000000e+00 0 1 30 42 1.000000000000000000e+00 0 1 30 43 1.000000000000000000e+00 0 1 30 44 1.000000000000000000e+00 0 1 30 45 1.000000000000000000e+00 0 1 30 46 1.000000000000000000e+00 0 1 30 47 1.000000000000000000e+00 0 1 30 48 1.000000000000000000e+00 0 1 30 49 1.000000000000000000e+00 0 1 30 50 1.000000000000000000e+00 0 1 31 31 1.000000000000000000e+00 0 1 31 32 1.000000000000000000e+00 0 1 31 33 1.000000000000000000e+00 0 1 31 34 1.000000000000000000e+00 0 1 31 35 1.000000000000000000e+00 0 1 31 36 1.000000000000000000e+00 0 1 31 37 1.000000000000000000e+00 0 1 31 38 1.000000000000000000e+00 0 1 31 39 1.000000000000000000e+00 0 1 31 40 1.000000000000000000e+00 0 1 31 41 1.000000000000000000e+00 0 1 31 42 1.000000000000000000e+00 0 1 31 43 1.000000000000000000e+00 0 1 31 44 1.000000000000000000e+00 0 1 31 45 1.000000000000000000e+00 0 1 31 46 1.000000000000000000e+00 0 1 31 47 1.000000000000000000e+00 0 1 31 48 1.000000000000000000e+00 0 1 31 49 1.000000000000000000e+00 0 1 31 50 1.000000000000000000e+00 0 1 32 32 1.000000000000000000e+00 0 1 32 33 1.000000000000000000e+00 0 1 32 34 1.000000000000000000e+00 0 1 32 35 1.000000000000000000e+00 0 1 32 36 1.000000000000000000e+00 0 1 32 37 1.000000000000000000e+00 0 1 32 38 1.000000000000000000e+00 0 1 32 39 1.000000000000000000e+00 0 1 32 40 1.000000000000000000e+00 0 1 32 41 1.000000000000000000e+00 0 1 32 42 1.000000000000000000e+00 0 1 32 43 1.000000000000000000e+00 0 1 32 44 1.000000000000000000e+00 0 1 32 45 1.000000000000000000e+00 0 1 32 46 1.000000000000000000e+00 0 1 32 47 1.000000000000000000e+00 0 1 32 48 1.000000000000000000e+00 0 1 32 49 1.000000000000000000e+00 0 1 32 50 1.000000000000000000e+00 0 1 33 33 1.000000000000000000e+00 0 1 33 34 1.000000000000000000e+00 0 1 33 35 1.000000000000000000e+00 0 1 33 36 1.000000000000000000e+00 0 1 33 37 1.000000000000000000e+00 0 1 33 38 1.000000000000000000e+00 0 1 33 39 1.000000000000000000e+00 0 1 33 40 1.000000000000000000e+00 0 1 33 41 1.000000000000000000e+00 0 1 33 42 1.000000000000000000e+00 0 1 33 43 1.000000000000000000e+00 0 1 33 44 1.000000000000000000e+00 0 1 33 45 1.000000000000000000e+00 0 1 33 46 1.000000000000000000e+00 0 1 33 47 1.000000000000000000e+00 0 1 33 48 1.000000000000000000e+00 0 1 33 49 1.000000000000000000e+00 0 1 33 50 1.000000000000000000e+00 0 1 34 34 1.000000000000000000e+00 0 1 34 35 1.000000000000000000e+00 0 1 34 36 1.000000000000000000e+00 0 1 34 37 1.000000000000000000e+00 0 1 34 38 1.000000000000000000e+00 0 1 34 39 1.000000000000000000e+00 0 1 34 40 1.000000000000000000e+00 0 1 34 41 1.000000000000000000e+00 0 1 34 42 1.000000000000000000e+00 0 1 34 43 1.000000000000000000e+00 0 1 34 44 1.000000000000000000e+00 0 1 34 45 1.000000000000000000e+00 0 1 34 46 1.000000000000000000e+00 0 1 34 47 1.000000000000000000e+00 0 1 34 48 1.000000000000000000e+00 0 1 34 49 1.000000000000000000e+00 0 1 34 50 1.000000000000000000e+00 0 1 35 35 1.000000000000000000e+00 0 1 35 36 1.000000000000000000e+00 0 1 35 37 1.000000000000000000e+00 0 1 35 38 1.000000000000000000e+00 0 1 35 39 1.000000000000000000e+00 0 1 35 40 1.000000000000000000e+00 0 1 35 41 1.000000000000000000e+00 0 1 35 42 1.000000000000000000e+00 0 1 35 43 1.000000000000000000e+00 0 1 35 44 1.000000000000000000e+00 0 1 35 45 1.000000000000000000e+00 0 1 35 46 1.000000000000000000e+00 0 1 35 47 1.000000000000000000e+00 0 1 35 48 1.000000000000000000e+00 0 1 35 49 1.000000000000000000e+00 0 1 35 50 1.000000000000000000e+00 0 1 36 36 1.000000000000000000e+00 0 1 36 37 1.000000000000000000e+00 0 1 36 38 1.000000000000000000e+00 0 1 36 39 1.000000000000000000e+00 0 1 36 40 1.000000000000000000e+00 0 1 36 41 1.000000000000000000e+00 0 1 36 42 1.000000000000000000e+00 0 1 36 43 1.000000000000000000e+00 0 1 36 44 1.000000000000000000e+00 0 1 36 45 1.000000000000000000e+00 0 1 36 46 1.000000000000000000e+00 0 1 36 47 1.000000000000000000e+00 0 1 36 48 1.000000000000000000e+00 0 1 36 49 1.000000000000000000e+00 0 1 36 50 1.000000000000000000e+00 0 1 37 37 1.000000000000000000e+00 0 1 37 38 1.000000000000000000e+00 0 1 37 39 1.000000000000000000e+00 0 1 37 40 1.000000000000000000e+00 0 1 37 41 1.000000000000000000e+00 0 1 37 42 1.000000000000000000e+00 0 1 37 43 1.000000000000000000e+00 0 1 37 44 1.000000000000000000e+00 0 1 37 45 1.000000000000000000e+00 0 1 37 46 1.000000000000000000e+00 0 1 37 47 1.000000000000000000e+00 0 1 37 48 1.000000000000000000e+00 0 1 37 49 1.000000000000000000e+00 0 1 37 50 1.000000000000000000e+00 0 1 38 38 1.000000000000000000e+00 0 1 38 39 1.000000000000000000e+00 0 1 38 40 1.000000000000000000e+00 0 1 38 41 1.000000000000000000e+00 0 1 38 42 1.000000000000000000e+00 0 1 38 43 1.000000000000000000e+00 0 1 38 44 1.000000000000000000e+00 0 1 38 45 1.000000000000000000e+00 0 1 38 46 1.000000000000000000e+00 0 1 38 47 1.000000000000000000e+00 0 1 38 48 1.000000000000000000e+00 0 1 38 49 1.000000000000000000e+00 0 1 38 50 1.000000000000000000e+00 0 1 39 39 1.000000000000000000e+00 0 1 39 40 1.000000000000000000e+00 0 1 39 41 1.000000000000000000e+00 0 1 39 42 1.000000000000000000e+00 0 1 39 43 1.000000000000000000e+00 0 1 39 44 1.000000000000000000e+00 0 1 39 45 1.000000000000000000e+00 0 1 39 46 1.000000000000000000e+00 0 1 39 47 1.000000000000000000e+00 0 1 39 48 1.000000000000000000e+00 0 1 39 49 1.000000000000000000e+00 0 1 39 50 1.000000000000000000e+00 0 1 40 40 1.000000000000000000e+00 0 1 40 41 1.000000000000000000e+00 0 1 40 42 1.000000000000000000e+00 0 1 40 43 1.000000000000000000e+00 0 1 40 44 1.000000000000000000e+00 0 1 40 45 1.000000000000000000e+00 0 1 40 46 1.000000000000000000e+00 0 1 40 47 1.000000000000000000e+00 0 1 40 48 1.000000000000000000e+00 0 1 40 49 1.000000000000000000e+00 0 1 40 50 1.000000000000000000e+00 0 1 41 41 1.000000000000000000e+00 0 1 41 42 1.000000000000000000e+00 0 1 41 43 1.000000000000000000e+00 0 1 41 44 1.000000000000000000e+00 0 1 41 45 1.000000000000000000e+00 0 1 41 46 1.000000000000000000e+00 0 1 41 47 1.000000000000000000e+00 0 1 41 48 1.000000000000000000e+00 0 1 41 49 1.000000000000000000e+00 0 1 41 50 1.000000000000000000e+00 0 1 42 42 1.000000000000000000e+00 0 1 42 43 1.000000000000000000e+00 0 1 42 44 1.000000000000000000e+00 0 1 42 45 1.000000000000000000e+00 0 1 42 46 1.000000000000000000e+00 0 1 42 47 1.000000000000000000e+00 0 1 42 48 1.000000000000000000e+00 0 1 42 49 1.000000000000000000e+00 0 1 42 50 1.000000000000000000e+00 0 1 43 43 1.000000000000000000e+00 0 1 43 44 1.000000000000000000e+00 0 1 43 45 1.000000000000000000e+00 0 1 43 46 1.000000000000000000e+00 0 1 43 47 1.000000000000000000e+00 0 1 43 48 1.000000000000000000e+00 0 1 43 49 1.000000000000000000e+00 0 1 43 50 1.000000000000000000e+00 0 1 44 44 1.000000000000000000e+00 0 1 44 45 1.000000000000000000e+00 0 1 44 46 1.000000000000000000e+00 0 1 44 47 1.000000000000000000e+00 0 1 44 48 1.000000000000000000e+00 0 1 44 49 1.000000000000000000e+00 0 1 44 50 1.000000000000000000e+00 0 1 45 45 1.000000000000000000e+00 0 1 45 46 1.000000000000000000e+00 0 1 45 47 1.000000000000000000e+00 0 1 45 48 1.000000000000000000e+00 0 1 45 49 1.000000000000000000e+00 0 1 45 50 1.000000000000000000e+00 0 1 46 46 1.000000000000000000e+00 0 1 46 47 1.000000000000000000e+00 0 1 46 48 1.000000000000000000e+00 0 1 46 49 1.000000000000000000e+00 0 1 46 50 1.000000000000000000e+00 0 1 47 47 1.000000000000000000e+00 0 1 47 48 1.000000000000000000e+00 0 1 47 49 1.000000000000000000e+00 0 1 47 50 1.000000000000000000e+00 0 1 48 48 1.000000000000000000e+00 0 1 48 49 1.000000000000000000e+00 0 1 48 50 1.000000000000000000e+00 0 1 49 49 1.000000000000000000e+00 0 1 49 50 1.000000000000000000e+00 0 1 50 50 1.000000000000000000e+00 1 1 1 1 1.000000000000000000e+00 1 1 2 2 1.000000000000000000e+00 1 1 3 3 1.000000000000000000e+00 1 1 4 4 1.000000000000000000e+00 1 1 5 5 1.000000000000000000e+00 1 1 6 6 1.000000000000000000e+00 1 1 7 7 1.000000000000000000e+00 1 1 8 8 1.000000000000000000e+00 1 1 9 9 1.000000000000000000e+00 1 1 10 10 1.000000000000000000e+00 1 1 11 11 1.000000000000000000e+00 1 1 12 12 1.000000000000000000e+00 1 1 13 13 1.000000000000000000e+00 1 1 14 14 1.000000000000000000e+00 1 1 15 15 1.000000000000000000e+00 1 1 16 16 1.000000000000000000e+00 1 1 17 17 1.000000000000000000e+00 1 1 18 18 1.000000000000000000e+00 1 1 19 19 1.000000000000000000e+00 1 1 20 20 1.000000000000000000e+00 1 1 21 21 1.000000000000000000e+00 1 1 22 22 1.000000000000000000e+00 1 1 23 23 1.000000000000000000e+00 1 1 24 24 1.000000000000000000e+00 1 1 25 25 1.000000000000000000e+00 1 1 26 26 1.000000000000000000e+00 1 1 27 27 1.000000000000000000e+00 1 1 28 28 1.000000000000000000e+00 1 1 29 29 1.000000000000000000e+00 1 1 30 30 1.000000000000000000e+00 1 1 31 31 1.000000000000000000e+00 1 1 32 32 1.000000000000000000e+00 1 1 33 33 1.000000000000000000e+00 1 1 34 34 1.000000000000000000e+00 1 1 35 35 1.000000000000000000e+00 1 1 36 36 1.000000000000000000e+00 1 1 37 37 1.000000000000000000e+00 1 1 38 38 1.000000000000000000e+00 1 1 39 39 1.000000000000000000e+00 1 1 40 40 1.000000000000000000e+00 1 1 41 41 1.000000000000000000e+00 1 1 42 42 1.000000000000000000e+00 1 1 43 43 1.000000000000000000e+00 1 1 44 44 1.000000000000000000e+00 1 1 45 45 1.000000000000000000e+00 1 1 46 46 1.000000000000000000e+00 1 1 47 47 1.000000000000000000e+00 1 1 48 48 1.000000000000000000e+00 1 1 49 49 1.000000000000000000e+00 1 1 50 50 1.000000000000000000e+00 2 1 1 2 5.000000000000000000e-01 3 1 1 28 5.000000000000000000e-01 4 1 1 50 5.000000000000000000e-01 5 1 2 21 5.000000000000000000e-01 6 1 2 22 5.000000000000000000e-01 7 1 2 36 5.000000000000000000e-01 8 1 2 49 5.000000000000000000e-01 9 1 3 10 5.000000000000000000e-01 10 1 3 30 5.000000000000000000e-01 11 1 3 34 5.000000000000000000e-01 12 1 3 35 5.000000000000000000e-01 13 1 3 49 5.000000000000000000e-01 14 1 4 11 5.000000000000000000e-01 15 1 4 12 5.000000000000000000e-01 16 1 4 17 5.000000000000000000e-01 17 1 4 34 5.000000000000000000e-01 18 1 5 18 5.000000000000000000e-01 19 1 5 19 5.000000000000000000e-01 20 1 5 34 5.000000000000000000e-01 21 1 5 46 5.000000000000000000e-01 22 1 6 19 5.000000000000000000e-01 23 1 6 21 5.000000000000000000e-01 24 1 6 30 5.000000000000000000e-01 25 1 6 38 5.000000000000000000e-01 26 1 7 9 5.000000000000000000e-01 27 1 7 22 5.000000000000000000e-01 28 1 7 23 5.000000000000000000e-01 29 1 7 44 5.000000000000000000e-01 30 1 7 45 5.000000000000000000e-01 31 1 8 29 5.000000000000000000e-01 32 1 8 31 5.000000000000000000e-01 33 1 8 34 5.000000000000000000e-01 34 1 9 20 5.000000000000000000e-01 35 1 9 33 5.000000000000000000e-01 36 1 10 23 5.000000000000000000e-01 37 1 10 38 5.000000000000000000e-01 38 1 10 49 5.000000000000000000e-01 39 1 11 22 5.000000000000000000e-01 40 1 11 34 5.000000000000000000e-01 41 1 11 35 5.000000000000000000e-01 42 1 11 46 5.000000000000000000e-01 43 1 12 14 5.000000000000000000e-01 44 1 13 17 5.000000000000000000e-01 45 1 13 47 5.000000000000000000e-01 46 1 14 15 5.000000000000000000e-01 47 1 14 34 5.000000000000000000e-01 48 1 14 38 5.000000000000000000e-01 49 1 14 39 5.000000000000000000e-01 50 1 14 49 5.000000000000000000e-01 51 1 15 16 5.000000000000000000e-01 52 1 15 28 5.000000000000000000e-01 53 1 15 35 5.000000000000000000e-01 54 1 15 46 5.000000000000000000e-01 55 1 15 48 5.000000000000000000e-01 56 1 16 28 5.000000000000000000e-01 57 1 16 30 5.000000000000000000e-01 58 1 16 43 5.000000000000000000e-01 59 1 17 30 5.000000000000000000e-01 60 1 18 37 5.000000000000000000e-01 61 1 18 38 5.000000000000000000e-01 62 1 19 21 5.000000000000000000e-01 63 1 19 25 5.000000000000000000e-01 64 1 19 39 5.000000000000000000e-01 65 1 19 41 5.000000000000000000e-01 66 1 20 30 5.000000000000000000e-01 67 1 20 34 5.000000000000000000e-01 68 1 21 33 5.000000000000000000e-01 69 1 21 46 5.000000000000000000e-01 70 1 22 37 5.000000000000000000e-01 71 1 22 40 5.000000000000000000e-01 72 1 23 30 5.000000000000000000e-01 73 1 23 37 5.000000000000000000e-01 74 1 23 39 5.000000000000000000e-01 75 1 23 43 5.000000000000000000e-01 76 1 23 46 5.000000000000000000e-01 77 1 24 25 5.000000000000000000e-01 78 1 25 33 5.000000000000000000e-01 79 1 25 38 5.000000000000000000e-01 80 1 26 39 5.000000000000000000e-01 81 1 26 46 5.000000000000000000e-01 82 1 27 29 5.000000000000000000e-01 83 1 30 31 5.000000000000000000e-01 84 1 30 36 5.000000000000000000e-01 85 1 32 33 5.000000000000000000e-01 86 1 32 43 5.000000000000000000e-01 87 1 32 46 5.000000000000000000e-01 88 1 33 41 5.000000000000000000e-01 89 1 33 46 5.000000000000000000e-01 90 1 33 48 5.000000000000000000e-01 91 1 35 40 5.000000000000000000e-01 92 1 35 48 5.000000000000000000e-01 93 1 36 46 5.000000000000000000e-01 94 1 37 39 5.000000000000000000e-01 95 1 37 42 5.000000000000000000e-01 96 1 37 43 5.000000000000000000e-01 97 1 37 48 5.000000000000000000e-01 98 1 38 42 5.000000000000000000e-01 99 1 39 45 5.000000000000000000e-01 100 1 39 46 5.000000000000000000e-01 101 1 40 41 5.000000000000000000e-01 102 1 40 47 5.000000000000000000e-01 103 1 41 43 5.000000000000000000e-01 104 1 43 48 5.000000000000000000e-01 Csdp-6.2.0/test/theta1.correct0000644000175200017520000000305613132512607014612 0ustar coincoinCSDP 6.2.0 Iter: 0 Ap: 0.00e+00 Pobj: 1.4644661e+04 Ad: 0.00e+00 Dobj: 0.0000000e+00 Iter: 1 Ap: 9.31e-01 Pobj: 5.7513865e+03 Ad: 1.00e+00 Dobj: 8.0172003e+01 Iter: 2 Ap: 9.21e-01 Pobj: 2.3227402e+02 Ad: 1.00e+00 Dobj: 8.2749235e+01 Iter: 3 Ap: 9.30e-01 Pobj: 1.0521019e+01 Ad: 1.00e+00 Dobj: 8.4447722e+01 Iter: 4 Ap: 1.00e+00 Pobj: 2.5047625e+00 Ad: 1.00e+00 Dobj: 7.2126480e+01 Iter: 5 Ap: 1.00e+00 Pobj: 7.5846337e+00 Ad: 1.00e+00 Dobj: 4.2853659e+01 Iter: 6 Ap: 1.00e+00 Pobj: 1.5893126e+01 Ad: 1.00e+00 Dobj: 3.0778169e+01 Iter: 7 Ap: 1.00e+00 Pobj: 1.9887401e+01 Ad: 1.00e+00 Dobj: 2.4588662e+01 Iter: 8 Ap: 1.00e+00 Pobj: 2.1623330e+01 Ad: 1.00e+00 Dobj: 2.3465172e+01 Iter: 9 Ap: 1.00e+00 Pobj: 2.2611983e+01 Ad: 1.00e+00 Dobj: 2.3097049e+01 Iter: 10 Ap: 1.00e+00 Pobj: 2.2939498e+01 Ad: 1.00e+00 Dobj: 2.3010908e+01 Iter: 11 Ap: 1.00e+00 Pobj: 2.2996259e+01 Ad: 1.00e+00 Dobj: 2.3000637e+01 Iter: 12 Ap: 1.00e+00 Pobj: 2.2999835e+01 Ad: 1.00e+00 Dobj: 2.3000020e+01 Iter: 13 Ap: 1.00e+00 Pobj: 2.2999993e+01 Ad: 1.00e+00 Dobj: 2.2999999e+01 Iter: 14 Ap: 1.00e+00 Pobj: 2.3000000e+01 Ad: 1.00e+00 Dobj: 2.3000000e+01 Success: SDP solved Primal objective value: 2.3000000e+01 Dual objective value: 2.3000000e+01 Relative primal infeasibility: 1.32e-18 Relative dual infeasibility: 3.93e-09 Real Relative Gap: 7.21e-09 XZ Relative Gap: 7.82e-09 DIMACS error measures: 1.32e-18 0.00e+00 1.00e-07 0.00e+00 7.21e-09 7.82e-09 Elements time: 0.002752 Factor time: 0.001588 Other time: 0.033838 Total time: 0.038178 Csdp-6.2.0/matlab/0000755000175200017520000000000013136043252012315 5ustar coincoinCsdp-6.2.0/matlab/README0000644000175200017520000000245010455242355013204 0ustar coincoinThis directory contains the MATLAB interface to CSDP. There are three MATLAB functions: csdp Solve a problem in SeDuMi format. writesdpa Takes a problem in SeDuMi format and outputs it to a file in SDPA sparse format. readsol Reads a CSDP solution into the workspace in SeDuMi form. convertf Converts free variables in a SeDuMi problem into the differences of nonnegative variables, so that the problem can be solved by CSDP. Note that these .m files must be in your MATLAB search path, and that the csdp executable must be in your shell's search path for this interface to work. To add the .m files to the MATLAB path, see the path function in MATLAB. It can be used to show the current path and add new directories to the current path. Once you've installed CSDP and the MATLAB interface routines, you can test them with >> load control1.mat >> whos >> pars.objtol=1.0e-9; >> [x,y,z,info]=csdp(At,b,c,K,pars); >> info The file control1.correct shows correct output from these commands. Your results should be similar, although there are likely to be slight differences in the actual values. For help with using the routines, see >> help csdp >> help writesdpa >> help readsol >> help convertf Csdp-6.2.0/matlab/writesdpa.m0000644000175200017520000001650613133226751014511 0ustar coincoin% This function takes a problem in SeDuMi MATLAB format and writes it out % in SDPA sparse format. % % Usage: % % ret=writesdpa(fname,A,b,c,K,pars) % % fname Name of SDPA file, in quotes % A,b,c,K Problem in SeDuMi form % pars Optional parameters. % pars.printlevel=0 No printed output % pars.printlevel=1 (default) Some printed output. % % ret ret=0 on success, ret=1 on failure. % % Notes: % % Problems with complex data are not allowed. % % Quadratic cone and rotated cone constraints are not supported. % % Nonsymmetric A.s and C.s matrices are symmetrized with A=(A+A')/2 % a warning is given when this happens. % % Free variables are not supported. % % Floating point numbers are written out with 18 decimal digits for % accuracy. % % Please contact the author (Brian Borchers, borchers@nmt.edu) with any % questions or bug reports. % % Third Version: 3/3/06. Corrected a bug in the handling of % nonsymmetric constraint matrices. % % Second Version: 7/14/04. Modified to vastly speed up operations on sparse % matrices. On some problems, this version is 100 times % faster! % % First Version: 7/14/03. Modified from old writesdp.m which wrote problems % in SDPPack format. % function ret=writesdpa(fname,A,b,c,K,pars) % % First, check to see whether or not we should be quiet. % if (nargin > 5) if (isfield(pars,'printlevel')) if (pars.printlevel == 0) quiet=1; else quiet=0; end else quiet=0; end else pars.printlevel=1; quiet=0; end % % First, check for complex numbers in A, b, or c. % if (isreal(A) ~= 1) if (quiet == 0) fprintf('A is not real!\n'); end ret=1; return end if (isreal(b) ~= 1) if (quiet == 0) fprintf('b is not real!\n'); end ret=1; return end if (isreal(c) ~= 1) if (quiet == 0) fprintf('c is not real!\n'); end ret=1; return end % % Check for any quadratic cone constraints. % if (isfield(K,'q')) if ((~isempty(K.q)) && (K.q ~= 0)) if (quiet == 0) fprintf('quadratic cone constraints are not supported.\n'); end ret=1; return end end % % Check for any rotated cone constraints. % if (isfield(K,'r')) if ((~isempty(K.r)) && (K.r ~= 0)) if (quiet == 0) fprintf('rotated cone constraints are not supported.\n'); end ret=1; return end end % % Check for any free variables. % if (isfield(K,'f')) if ((~isempty(K.f)) && (K.f ~= 0)) if (quiet == 0) fprintf('Free variables are not supported.\n'); end ret=1; return end end % % Find the number of constraints. % m=length(b); % % Deal with the following special case. If A is transposed, transpose % it again so that it is of the right size. % [Am,An]=size(A); if (Am ~= m) if (An == m) if (quiet==0) fprintf('Transposing A to match b \n'); end AT=A; A=A'; % % Also swap Am and An so that they're correct. % temp=Am; Am=An; An=temp; else % % In this case, A is just plain the wrong size. % if (quiet==0) fprintf('A is not of the correct size to match b \n'); end ret=1; return end else % % No need to transpose A, but we'll need AT. % AT=A'; end % % Deal with the following special case: if c==0, then c should really % be a zero vector of the appropriate size. % if (c == 0) if (quiet==0) fprintf('Expanding c to the appropriate size\n'); end c=sparse(An,1); end % % If c is empty, then act as if it was zero. % if (isempty(c)) if (quiet==0) fprintf('Expanding empty c to zeros of the appropriate size\n'); end c=sparse(An,1); end % % If c is a row vector, make it a column vector. % [cm,cn]=size(c); if (cn > cm) c=c'; end % % Get the size data. % % % First, the size of the LP block. % if (isfield(K,'l')) nlin=K.l; sizelin=nlin; if (isempty(sizelin)) sizelin=0; nlin=0; end if (K.l == 0) nlin=0; sizelin=0; end else nlin=0; sizelin=0; end % % Get the sizes of the SDP blocks. % if (isfield(K,'s')) nsdpblocks=length(K.s); sizesdp=sum((K.s).^2); if (isempty(sizesdp)) sizesdp=0; nsdpblocks=0; end if (K.s == 0) nsdpblocks=0; sizesdp=0; end else sizesdp=0; nsdpblocks=0; end % % Figure out the number of blocks. % nblocks=nsdpblocks; if (nlin>0) nblocks=nblocks+1; end % % print out some size information % if (quiet==0) fprintf('Number of constraints: %d \n',m); fprintf('Number of SDP blocks: %d \n',nsdpblocks); fprintf('Number of LP vars: %d \n',nlin); end % % Open up the file for writing. % fid=fopen(fname,'w'); if (fid==-1) if (quiet==0) fprintf('Could not open file for output!'); end ret=1; return end % % Print out m, the number of constraints. % fprintf(fid,'%d \n',m); % % Next, the number of blocks. % fprintf(fid,'%d \n',nblocks); % % Print out the block structure. % if (K.s > 0) fprintf(fid,'%d ',K.s); end if (nlin > 0) fprintf(fid,'%d ',-nlin); end fprintf(fid,'\n'); % % Next, b, with all on one line. % fprintf(fid,'%.18e ',full(b)); fprintf(fid,'\n'); % % First, the C matrix. % % % First, calculate where in c things start. % base=sizelin+1; % % Next, work through the SDP blocks. % for i=1:nsdpblocks % % Get the current block of C. % I=find(c); II=find(I>=base); I=I(II); II=find(I<=base+K.s(i)^2-1); I=I(II); II=I-(base-1)*ones(size(I)); work=sparse(II,ones(size(II)),c(I),K.s(i)^2,1); work=reshape(work,K.s(i),K.s(i)); % % Check this block for symmetry. % if (norm(work-work','fro') ~= 0) if (quiet==0) fprintf('Non symmetric C.s matrix!\n'); end work=(work+work')/2; end % % Write out the C.s matrix. % work=triu(work); [II,JJ,V]=find(work); cnt=length(II); if (cnt ~= 0) fprintf(fid,'%d %d %d %d %.18e\n',full([zeros(size(II)) i*ones(size(II)) II JJ -V]')); end % % Next, update to the next base. % base=base+K.s(i)^2; end % % Print out the coefficients for the linear block of C. % for i=1:nlin if (c(i) ~= 0.0) fprintf(fid,'%d %d %d %d %.18e\n',full([0 nsdpblocks+1 i i -c(i)])); end end % % Now, loop through the constraints, one at a time. % for cn=1:m % % Print out the SDP part of constraint cn. % base=sizelin+1; rowcn=AT(:,cn); for i=1:nsdpblocks I=find(rowcn); II=find(I>=base); I=I(II); II=find(I<=(base+K.s(i)^2-1)); I=I(II); II=I-(base-1)*ones(size(I)); work=sparse(II,ones(size(II)),rowcn(I),K.s(i)^2,1); work=reshape(work,K.s(i),K.s(i)); if (norm(work-work','fro') ~= 0) if (quiet==0) fprintf('Non symmetric A.s matrix! \n'); end work=(work+work')/2; end % % Ignore the lower left triangle. % work=triu(work); % % Get the nonzero entries. % [II,JJ,V]=find(work); cnt=length(II); if (cnt ~= 0) fprintf(fid,'%d %d %d %d %.18e\n',full([cn*ones(size(II)) i*ones(size(II)) II JJ V]')); end % % Next, update to the next base. % base=base+K.s(i)^2; end % % Finally, the linear part. % I=find(rowcn); II=find(I<=nlin); I=I(II); workrow=sparse(I,ones(size(I)),rowcn(I),nlin,1); [II,JJ,V]=find(workrow); if (length(II) > 0) fprintf(fid,'%d %d %d %d %.18e\n',full([cn*ones(length(II),1) (nsdpblocks+1)*ones(length(II),1) II II V]')); end end % % Close the file. % fclose(fid); % % Return success % ret=0; return Csdp-6.2.0/matlab/readsdpa.m0000644000175200017520000000724113125756303014270 0ustar coincoin% % [At,b,c,K]=readsdpa(fname) % % Reads in a problem in SDPA sparse format, and returns it in SeDuMi % format. % % 7/20/07 Modified to handle comments and other cruft in the SDPA % file. In particular, % % 1. Initial comment lines beginning with " or * are ignored. % 2. In the first three lines, any extraneous characters after % the numbers are ignored. % 3. In the block description, any occurrences of "{", ",", "}", "(", % and ")" are converted into spaces. % function [At,b,c,K]=readsdpa(fname) % % Open the file for reading. % fid=fopen(fname,'r'); if (fid == -1), error('file does not exist'); end % % Skip over the initial comments. % inputline=fgetl(fid); while (inputline(1)=='"' || inputline(1)=='*') inputline=fgetl(fid); end % % Read in m. % m=sscanf(inputline,'%d',1); inputline=fgetl(fid); % % Read in nblocks. % nblocks=sscanf(inputline,'%d',1); inputline=fgetl(fid); % % Read in the raw block sizes. % inputline=regexprep(inputline,'[\,(){}]',' '); rawblocksizes=sscanf(inputline,'%d',nblocks); inputline=fgetl(fid); % % Compute the actual block sizes, figure out block types, and figure out % where in the vectors stuff will go. % blocksizes=abs(rawblocksizes); blocktypes=zeros(nblocks,1); for i=1:nblocks, if (rawblocksizes(i) < 0) blocktypes(i)=1; else blocktypes(i)=2; end end blockbases=zeros(nblocks,1); lpbase=1; for i=1:nblocks, if (blocktypes(i)==1) blockbases(i)=lpbase; lpbase=lpbase+blocksizes(i); end end K.l=lpbase-1; sdpbase=lpbase; K.s=[]; for i=1:nblocks, if (blocktypes(i)==2) blockbases(i)=sdpbase; sdpbase=sdpbase+blocksizes(i)^2; K.s=[K.s blocksizes(i)]; end end n=sdpbase-1; % % Now, read in the right hand side. % b=zeros(m,1); inputline=regexprep(inputline,'[\,(){}]',' '); b=sscanf(inputline,'%le',m); % % Now, read in the entries in the constraints and c. % c=zeros(1,n); At=sparse(n,m); entries=fscanf(fid,'%d %d %d %d %le',[5,inf]); [entriesm,entriesn]=size(entries); for i=1:entriesn, if (entries(1,i)==0), block=entries(2,i); if (blocktypes(block)==1) % % LP data. % if (c(1,blockbases(block)+entries(3,i)-1) ~= 0) error('SDPA input: Repeat entry in objective'); else c(1,blockbases(block)+entries(3,i)-1)=entries(5,i); end else % % SDP block entry % if (c(1,blockbases(block)+(entries(3,i)-1)*blocksizes(block)+ ... entries(4,i)-1) ~= 0) error('SDPA input: Repeat entry in objective'); else c(1,blockbases(block)+(entries(3,i)-1)*blocksizes(block)+ ... entries(4,i)-1)=entries(5,i); c(1,blockbases(block)+(entries(4,i)-1)*blocksizes(block)+ ... entries(3,i)-1)=entries(5,i); end end else % % Constraint entry. % block=entries(2,i); constraint=entries(1,i); if (blocktypes(block)==1) % % LP data. % if (At(blockbases(block)+entries(3,i)-1,constraint) ~= 0) constraint block error('SDPA input: Repeat entry in constraint'); else At(blockbases(block)+entries(3,i)-1,constraint)=entries(5,i); end else % % SDP block entry % if (At(blockbases(block)+(entries(3,i)-1)*blocksizes(block)+ ... entries(4,i)-1,constraint) ~= 0) constraint block error('SDPA input: Repeat entry in constraint'); else At(blockbases(block)+(entries(3,i)-1)*blocksizes(block)+ ... entries(4,i)-1,constraint)=entries(5,i); At(blockbases(block)+(entries(4,i)-1)*blocksizes(block)+ ... entries(3,i)-1,constraint)=entries(5,i); end end end end % % Fix up the sign of c to match SeDuMi's convention. Also, make c % a column vector to match SeDuMi's fromsdpa(). % c=-c'; Csdp-6.2.0/matlab/control1.correct0000644000175200017520000000474010455242355015454 0ustar coincoin>> load control1.mat >> whos Name Size Bytes Class At 125x21 8488 double array (sparse) K 1x1 140 struct array ans 2x1 16 double array b 21x1 168 double array c 125x1 80 double array (sparse) Grand total is 732 elements using 8892 bytes >> pars.objtol=1.0e-9; >> [x,y,z,info]=csdp(At,b,c,K,pars); Transposing A to match b Number of constraints: 21 Number of SDP blocks: 2 Number of LP vars: 0 Iter: 0 Ap: 0.00e+00 Pobj: 3.6037961e+02 Ad: 0.00e+00 Dobj: 0.0000000e+00 Iter: 1 Ap: 9.56e-01 Pobj: 3.7527534e+02 Ad: 9.60e-01 Dobj: 6.4836002e+04 Iter: 2 Ap: 8.55e-01 Pobj: 4.0344779e+02 Ad: 9.67e-01 Dobj: 6.9001508e+04 Iter: 3 Ap: 8.77e-01 Pobj: 1.4924982e+02 Ad: 1.00e+00 Dobj: 6.0425319e+04 Iter: 4 Ap: 7.14e-01 Pobj: 8.2819409e+01 Ad: 1.00e+00 Dobj: 1.2926534e+04 Iter: 5 Ap: 8.23e-01 Pobj: 4.7411689e+01 Ad: 1.00e+00 Dobj: 4.9040115e+03 Iter: 6 Ap: 7.97e-01 Pobj: 2.6300213e+01 Ad: 1.00e+00 Dobj: 1.4672743e+03 Iter: 7 Ap: 7.12e-01 Pobj: 1.5215577e+01 Ad: 1.00e+00 Dobj: 4.0561826e+02 Iter: 8 Ap: 8.73e-01 Pobj: 7.5119220e+00 Ad: 1.00e+00 Dobj: 1.7418715e+02 Iter: 9 Ap: 9.87e-01 Pobj: 5.3076526e+00 Ad: 1.00e+00 Dobj: 5.2097318e+01 Iter: 10 Ap: 1.00e+00 Pobj: 7.8594697e+00 Ad: 1.00e+00 Dobj: 2.2172447e+01 Iter: 11 Ap: 7.62e-01 Pobj: 1.5871010e+01 Ad: 1.00e+00 Dobj: 1.9629658e+01 Iter: 12 Ap: 9.21e-01 Pobj: 1.7549388e+01 Ad: 9.68e-01 Dobj: 1.7931413e+01 Iter: 13 Ap: 9.70e-01 Pobj: 1.7769861e+01 Ad: 9.72e-01 Dobj: 1.7792992e+01 Iter: 14 Ap: 8.87e-01 Pobj: 1.7782917e+01 Ad: 9.70e-01 Dobj: 1.7785344e+01 Iter: 15 Ap: 9.27e-01 Pobj: 1.7784457e+01 Ad: 9.85e-01 Dobj: 1.7784731e+01 Iter: 16 Ap: 9.35e-01 Pobj: 1.7784609e+01 Ad: 9.35e-01 Dobj: 1.7784640e+01 Iter: 17 Ap: 1.00e+00 Pobj: 1.7784624e+01 Ad: 1.00e+00 Dobj: 1.7784628e+01 Iter: 18 Ap: 1.00e+00 Pobj: 1.7784627e+01 Ad: 1.00e+00 Dobj: 1.7784627e+01 Iter: 19 Ap: 9.54e-01 Pobj: 1.7784627e+01 Ad: 9.59e-01 Dobj: 1.7784627e+01 Success: SDP solved Primal objective value: 1.7784627e+01 Dual objective value: 1.7784627e+01 Relative primal infeasibility: 1.34e-09 Relative dual infeasibility: 1.53e-11 Real Relative Gap: 8.76e-10 XZ Relative Gap: 2.16e-10 DIMACS error measures: 1.34e-09 0.00e+00 2.47e-11 0.00e+00 8.76e-10 2.16e-10 0.020u 0.000s 0:00.07 28.5% 0+0k 0+0io 218pf+0w >> info info = 0 >> quit Csdp-6.2.0/matlab/control1.mat0000644000175200017520000002044010455242355014567 0ustar coincoinMATLAB 5.0 MAT-file, Platform: GLNX86, Created on: Fri Jul 25 16:13:50 2003 IM0ans xKs0 }cdjpv| (`b*}At  (2<FPZd ()23<=FGPQZ[ei  (*24<>FHPRZ\fn  !"#$%&'(+25<?FIPSZ]gs "()*+,-./0126<@FJPTZ^hx )3=GQ[j  )*34=>GHQR[\ko  !"#$%&')+35=?GIQS[]lt "()*+,-./0136=@GJQT[^my  *4>HR\p  !"#$%&'*+45>?HIRS\]qu  "()*+,-./0146>@HJRT\^rz  !"#$%&'+5?IS]v  !"#$%&'()*+,-./0156?@IJST]^w{"()*+,-./016@JT^|  !"()*+,7  !"()*+,B  !"()*+,M  !"()*+,X  !"()*+,c !,7BMXcX:` 2Fl.Hbl `x_@c]KAb)S@ET;@xNޓZ+V@TгY0@O4QIEc]KAb)S@ET;@xNޓZ+V@TгY0@O4QIE?Qjb@[B>P@h"lxzH@6@|гYUc]KA-P@b)S@z):4c]KAb)S@ETK@xNޓZ+V@TгY0@O4QIE h5@xNP@гY0@h"lxzH@O46@QIE??5^I a@OnQR@ǘjR@ZB>R@PkwBS㥛G@5;NU7´UV/N@ yEX@x&1@CA^A@Bfj0ǘjR@S㥛G@QSb@Fx +MSt4A@K=JGzM h6@w-!$S|?5JQ@5;NUFx +7´UMSt4A@V/N@K=J yEX@GzMx&1@C h6@A^A@w-!$SBfj0|?5JQ@??rhKǘjR@rhKMbXe-P@(V h5@P@h"lxzH@6@-P@OeSR@ǘjR@(VOeSR@;MSt4A@K=JGzM h6@w-!$S|?5JQ@ h5@MSt4A@P@ h6@h"lxzH@w-!$S6@|?5JQ@??( Q@ǘjR@( Q@OnaR@Pkw2ZB>R@Pkw2K7Z@5;NU7´UV/N@ yEX@x&1@CA^A@Bfj05;NU7´UV/N@ yEX@x&1@CA^A@Bfj0?rhKZB>R@|гYUPkw2rhK|гYU-`@@߾= h5@P@h"lxzH@6@ZB>R@Pkw2@߾=Zd;Oe7´UV/N@ yEX@x&1@CA^A@Bfj0 h5@7´UP@x&1@Ch"lxzH@A^A@6@Bfj0??( Q@ZB>R@OnQPkw2( Q@OnQR@Pkw2R_@5;NUT㥛ĴeV/N@ yEX@x&1@CA^A@Bfj0a+eS@V/N@ׁsFtW@ yEX@Zd;OA@x&1@C BF@A^A@,eXKVBfj0??rhK|гYU-P@rhK|гYU-P@V-d h5@P@h"lxzH@6@ h5@P@h"lxzH@6@?( Q@rhKOnQ|гYUP@h"lxzH@6@a+eS@P@ BF@h"lxzH@,eXKV6@??( Q@OnQmiM`q(\^@µmiףp=JRkv{GaC@3333sM`qRkvp= S?X9voe@Q(@SQ@B`"̊oe@˒Q*ףp= !R두@Q(@Q*6<\(@SQ@ףp= !<(\|@B`"̊R두@\(@@t7?(\xx6@Q̘@p= h|?yx6@ףp=Vfffff-@n @Q̘@ףp=V\(fffff#@Q @p= fffff-@fffff#@Q\(h|?yn @Q @\(m({?Csdp-6.2.0/matlab/convertf.m0000644000175200017520000000263510455242355014335 0ustar coincoin% % [A,b,c,K]=convertf(A,b,c,K) % % converts free variables in a SeDuMi problem into nonnegative LP variables. % function [A,b,c,K]=convertf(A,b,c,K) % % Get the number of constraints. % m=length(b); % % Deal with the following special case. If A is transposed, transpose % it again so that it is of the right size. % [Am,An]=size(A); if (Am ~= m) if (An == m) fprintf('Transposing A to match b \n'); A=A'; else fprintf('A is not of the correct size to match b \n'); return end end % % Deal with the following special case: if c==0, then c should really % be a zero vector of the appropriate size. % if (c == 0) fprintf('Expanding c to the appropriate size\n'); [Am,An]=size(A); c=zeros(An,1); end % % If c is empty, then act as if it was zero. % if (isempty(c)) fprintf('Expanding empty c to zeros of the appropriate size\n'); [Am,An]=size(A); c=zeros(An,1); end % % If c is a row vector, make it a column vector. % [cm,cn]=size(c); if (cn > cm) c=c'; end % % Check for any free LP variables and rewrite them as the differences of % regular LP variables. % if (isfield(K,'f')) nfree=K.f fprintf('Converting %d free variables to LP variables\n',nfree); if (isfield(K,'l')) nlin=K.l; else nlin=0; end [Am,An]=size(A); Anew=[A(:,1:nfree) -A(:,1:nfree) A(:,nfree+1:An)]; A=Anew; cnew=[c(1:nfree); -c(1:nfree); c(nfree+1:An)]; c=cnew; K.l=nlin+2*nfree; K.f=0; end Csdp-6.2.0/matlab/writesol.m0000644000175200017520000000676713123512303014355 0ustar coincoin% % writesol(fname,x,y,z,K) % % Writes out a solution file in the format used by CSDP and % readsol. % % fname File name to read solution from. % x,y,z Solution. % K structure of the matrices. % % % function ret=writesol(fname,x,y,z,K); % % First, eliminate special cases that we don't handle. % % % Check for any quadratic cone constraints. % if (isfield(K,'q') && (~isempty(K.q)) && (K.q ~= 0)), fprintf('quadratic cone constraints are not supported.\n'); ret=100; return end % % Check for any rotated cone constraints. % if (isfield(K,'r') && (~isempty(K.r)) && (K.r ~= 0)), fprintf('rotated cone constraints are not supported.\n'); ret=100; return end % % Check for any free variables. % if (isfield(K,'f') && (~isempty(K.f)) && (K.f ~= 0)), fprintf('Free variables are not supported.\n'); ret=100; return end % % Figure out the m dimension. % m=length(y); % % Figure out the structure of the LP and SDP blocks. % if (isfield(K,'l')), if (K.l > 0) nlin=K.l; else K.l=0; nlin=0; end else K.l=0; nlin=0; end % % Patched on 10/23/03 to handle all kinds of stupid ways of indicating % no SDP block. % if (isfield(K,'s')), if (length(K.s) > 1), nsdpblocks=length(K.s); else if (length(K.s)==1), if (K.s==0) nsdpblocks=0; K.s=[]; else nsdpblocks=1; end else nsdpblocks=0; K.s=[]; end end else K.s=[]; nsdpblocks=0; end % % First, where everything is in the vector. % % vecsdpbase(i)=point in vector at which SDP block i starts. % v(1..nlin) LP variables. % base=nlin+1; for i=1:length(K.s), vecsdpbase(i)=base; base=base+(K.s(i))^2; end veclpbase=1; % % Second, where everything is in the matrix. % % matsdpbase(i)= index of upper left corner of SDP block i. % matlpbase index of start of LP block. % base=1; for i=1:length(K.s), matsdpbase(i)=base; base=base+K.s(i); end matlpbase=base; % % Setup an array containing blocksizes. blocksize(i) is used as a faster % synonym for K.s(i) in what follows. This is because MATLAB doesn't % accelerate statements involving fields. % if (nsdpblocks >= 1), blocksizes=zeros(nsdpblocks,1); for i=1:nsdpblocks, blocksizes(i)=K.s(i); end end % % Open up the file. % fid=fopen(fname,'w'); if (fid == -1), fprintf('file open failed!\n'); ret=100; return end % % Write out y. % for i=1:m fprintf(fid,'%.18e ',full(-y(i))); end fprintf(fid,'\n'); % % Entries of Z. % % % First, the SDP blocks. % for i=1:nsdpblocks base=vecsdpbase(i); tempmat=reshape(z(base:base+K.s(i)^2-1),K.s(i),K.s(i)); for j=1:K.s(i) for k=j:K.s(i) if (tempmat(j,k) ~= 0) fprintf(fid,'1 %d %d %d %.18e \n',full([i,j,k,tempmat(j,k)])); end end end end % % The linear block is last. % if (nlin > 0) for i=veclpbase:nlin if (x(i) ~= 0) fprintf(fid,'1 %d %d %d %.18e \n',full([nsdpblocks+1 i-veclpbase+1 ... i-veclpbase+1 z(i)])); end end end % % Entries of X. % % % First, the SDP blocks. % for i=1:nsdpblocks base=vecsdpbase(i); tempmat=reshape(x(base:base+K.s(i)^2-1),K.s(i),K.s(i)); for j=1:K.s(i) for k=j:K.s(i) if (tempmat(j,k) ~= 0) fprintf(fid,'2 %d %d %d %.18e \n',full([i,j,k,tempmat(j,k)])); end end end end % % The linear block is last. % if (nlin > 0) for i=veclpbase:nlin if (x(i) ~= 0) fprintf(fid,'2 %d %d %d %.18e \n',full([nsdpblocks+1 i-veclpbase+1 ... i-veclpbase+1 x(i)])); end end end % % Close the output file and return. % fclose(fid); ret=0; Csdp-6.2.0/matlab/csdp.m0000644000175200017520000001312613125752655013443 0ustar coincoin% % [x,y,z,info]=csdp(At,b,c,K,pars,x0,y0,z0) % % Uses CSDP to solve a problem in SeDuMi format. % % Input: % At, b, c, K SDP problem in SeDuMi format. % pars CSDP parameters (optional parameter.) % x0,y0,z0 Optional starting point. % % Output: % % x, y, z solution. % info CSDP return code. % info=100 indicates a failure in the MATLAB % interface, such as inability to write to % a temporary file or read back the solution. % % Note: This interface makes use of temporary files with names given by the % tempname function. This will fail if there is no working temporary % directory or there isn't enough space available in this directory. % % Note: This code writes its own param.csdp file in the current working % directory. Any param.csdp file already in the directory will be deleted. % % Note: It is assumed that csdp is the search path made available through % the "system" or "dos" command. Typically, having the csdp executable in % current working directory will work, although some paranoid system % administrators keep . out of the path. In that case, you'll need to % install csdp in one of the directories that is in the search path. % A simple test is to run csdp from a command line prompt. % function [x,y,z,info]=csdp(At,b,c,K,pars,x0,y0,z0) % % First, put a dummy pars in place if no argument was given. Also % set pars.printlevel if not given. % if (nargin<5), pars.printlevel=1; else if (isfield(pars,'printlevel')), pars.printlevel=pars.printlevel; else pars.printlevel=1; end end % % Write out the param.csdp file. % fid=fopen('param.csdp','w'); if (fid==-1) if (pars.printlevel ~= 0), fprintf('Could not open param.csdp\n'); end info=100; return end % % Now, go through the parameters. % if (isfield(pars,'axtol')), fprintf(fid,'axtol= %e\n',pars.axtol); else fprintf(fid,'axtol=%e\n',1.0e-8); end if (isfield(pars,'atytol')), fprintf(fid,'atytol= %e\n',pars.atytol); else fprintf(fid,'atytol=%e\n',1.0e-8); end if (isfield(pars,'objtol')), fprintf(fid,'objtol= %e\n',pars.objtol); else fprintf(fid,'objtol=%e\n',1.0e-8); end if (isfield(pars,'pinftol')), fprintf(fid,'pinftol= %e\n',pars.pinftol); else fprintf(fid,'pinftol=%e\n',1.0e8); end if (isfield(pars,'dinftol')), fprintf(fid,'dinftol= %e\n',pars.dinftol); else fprintf(fid,'dinftol=%e\n',1.0e8); end if (isfield(pars,'maxiter')), fprintf(fid,'maxiter= %d\n',pars.maxiter); else fprintf(fid,'maxiter=%d\n',100); end if (isfield(pars,'minstepfrac')), fprintf(fid,'minstepfrac= %e\n',pars.minstepfrac); else fprintf(fid,'minstepfrac=%e\n',0.90); end if (isfield(pars,'maxstepfrac')), fprintf(fid,'maxstepfrac= %e\n',pars.maxstepfrac); else fprintf(fid,'maxstepfrac=%e\n',0.97); end if (isfield(pars,'minstepp')), fprintf(fid,'minstepp= %e\n',pars.minstepp); else fprintf(fid,'minstepp=%e\n',1.0e-8); end if (isfield(pars,'minstepd')), fprintf(fid,'minstepd= %e\n',pars.minstepd); else fprintf(fid,'minstepd=%e\n',1.0e-8); end if (isfield(pars,'usexzgap')), fprintf(fid,'usexzgap= %d\n',pars.usexzgap); else fprintf(fid,'usexzgap=%d\n',1); end if (isfield(pars,'tweakgap')), fprintf(fid,'tweakgap= %d\n',pars.tweakgap); else fprintf(fid,'tweakgap=%d\n',0); end if (isfield(pars,'affine')), fprintf(fid,'affine= %d\n',pars.affine); else fprintf(fid,'affine=%d\n',0); end if (isfield(pars,'printlevel')), fprintf(fid,'printlevel= %d\n',pars.printlevel); else fprintf(fid,'printlevel=%d\n',1); end if (isfield(pars,'perturbobj')), fprintf(fid,'printlevel= %d\n',pars.perturbobj); else fprintf(fid,'printlevel=%d\n',1); end if (isfield(pars,'fastmode')), fprintf(fid,'printlevel= %d\n',pars.fastmode); else fprintf(fid,'printlevel=%d\n',0); end % % close the parameter file. % fclose(fid); % % Write the problem out. % fname=tempname; ret=writesdpa([fname '.dat-s'],At,b,c,K,pars); if (ret==1), info=100; return end % % If an initial solution was provided, write it out too. % if (nargin == 8) initsolname=tempname; ret=writesol([initsolname '.sol'],x0,y0,z0,K); if (ret~=0) info=100; delete([initsolname '.sol']); return end end % % Solve the problem. % if (nargin==8) % % An inital solution was provided, so include it in the command line. % if (ispc==1), info=dos(['csdp ' fname '.dat-s' ' ' fname '.sol' ' ' initsolname '.sol'],'-echo'); else if (pars.printlevel ~=0), info=system(['time csdp ' fname '.dat-s' ' ' fname '.sol' ' ' ... initsolname '.sol']); else info=system(['csdp ' fname '.dat-s' ' ' fname '.sol' ' ' ... initsolname '.sol']); end end else % % no initial solution was provided. % if (ispc==1), info=dos(['csdp ' fname '.dat-s' ' ' fname '.sol'],'-echo'); else if (pars.printlevel ~=0), info=system(['time csdp ' fname '.dat-s' ' ' fname '.sol']); else info=system(['csdp ' fname '.dat-s' ' ' fname '.sol']); end end end % % Only try to read the solution if csdp succeeded at least to a point. % if (info <= 4) % % Read back the solution. % [x,y,z]=readsol([fname '.sol'],K,length(b)); % % If readsol couldn't open the file, then return info=100 to show % the error. % if (isnan(x)) info=100; end else % % CSDP failed. Set x, y, and z to NaN. % x=NaN*ones(length(c),1); y=NaN*ones(length(b),1); z=NaN*ones(length(c),1); end % % Delete the temporary files, including param.csdp if we wrote one! % delete([fname '.dat-s']); delete([fname '.sol']); if (nargin==8) delete([initsolname '.sol']); end delete('param.csdp'); Csdp-6.2.0/matlab/readsol.m0000644000175200017520000000716113125752655014145 0ustar coincoin% % [x,y,z]=readsol(fname,K,m) % % fname File name to read solution from. % K structure of the matrices. % m size of y vector. % % Modified 7/15/04, for greater MATLAB acceleration. % function [x,y,z]=readsol(fname,K,m) % % First, eliminate special cases that we don't handle. % % % Check for any quadratic cone constraints. % if (isfield(K,'q') && (~isempty(K.q)) && (K.q ~= 0)), fprintf('quadratic cone constraints are not supported.\n'); return end % % Check for any rotated cone constraints. % if (isfield(K,'r') && (~isempty(K.r)) && (K.r ~= 0)), fprintf('rotated cone constraints are not supported.\n'); return end % % Check for any free variables. % if (isfield(K,'f') && (~isempty(K.f)) && (K.f ~= 0)), fprintf('Free variables are not supported.\n'); return end % % Figure out the structure of the LP and SDP blocks. % if (isfield(K,'l')), if (K.l > 0) nlin=K.l; else K.l=0; nlin=0; end else K.l=0; nlin=0; end % % Patched on 10/23/03 to handle all kinds of stupid ways of indicating % no SDP block. % if (isfield(K,'s')), if (length(K.s) > 1), nsdpblocks=length(K.s); else if (length(K.s)==1), if (K.s==0) nsdpblocks=0; K.s=[]; else nsdpblocks=1; end else nsdpblocks=0; K.s=[]; end end else K.s=[]; nsdpblocks=0; end % % First, where everything is in the vector. % % vecsdpbase(i)=point in vector at which SDP block i starts. % v(1..nlin) LP variables. % base=nlin+1; for i=1:length(K.s), vecsdpbase(i)=base; base=base+(K.s(i))^2; end % % Second, where everything is in the matrix. % % matsdpbase(i)= index of upper left corner of SDP block i. % matlpbase index of start of LP block. % base=1; for i=1:length(K.s), matsdpbase(i)=base; base=base+K.s(i); end matlpbase=base; % % Setup an array containing blocksizes. blocksize(i) is used as a faster % synonym for K.s(i) in what follows. This is because MATLAB doesn't % accelerate statements involving fields. % if (nsdpblocks >= 1), blocksizes=zeros(nsdpblocks,1); for i=1:nsdpblocks, blocksizes(i)=K.s(i); end end % % Open up the file. % fid=fopen(fname,'r'); if (fid == -1), fprintf('file does not exist!\n'); x=NaN; y=NaN; z=NaN; return end % % Read y. % y=fscanf(fid,'%le',m); % % Read the remaining entries. % [A,count]=fscanf(fid,'%d %d %d %d %le',[5,inf]); count=count/5; % % Allocate storage for x and z. % if ((length(K.s) > 1) || (length(K.s==1) && (K.s>0))), veclength=vecsdpbase(length(K.s))+K.s(nsdpblocks)^2-1; else veclength=nlin; end % % Allocate space for x and z. We could use sparse vectors here, but % the dense vector is vastly faster. % x=zeros(veclength,1); z=zeros(veclength,1); % % now, loop through the entries and put them into x and z. % for i=1:count, if (A(1,i)==1), % % A z entry. % blk=A(2,i); indexi=A(3,i); indexj=A(4,i); ent=A(5,i); if (blk==nsdpblocks+1) z(indexi)=ent; else % % In one of the SDP blocks. % % [blk, indexi, indexj, K.s(blk)] z(vecsdpbase(blk)+indexi+(indexj-1)*blocksizes(blk)-1)=ent; z(vecsdpbase(blk)+indexj+(indexi-1)*blocksizes(blk)-1)=ent; end else % % An x entry. % blk=A(2,i); indexi=A(3,i); indexj=A(4,i); ent=A(5,i); if (blk==nsdpblocks+1) x(indexi)=ent; else % % In one of the SDP blocks. % x(vecsdpbase(blk)+indexi+(indexj-1)*blocksizes(blk)-1)=ent; x(vecsdpbase(blk)+indexj+(indexi-1)*blocksizes(blk)-1)=ent; end end end % % Correction for the difference between CSDP and SeDuMi primal/dual pair. % y=-y; % % close the file. % fclose(fid); Csdp-6.2.0/LICENSE0000644000175200017520000002704310522714256012075 0ustar coincoinCommon Public License Version 1.0 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents " mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that: a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement, including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against a Contributor with respect to a patent applicable to software (including a cross-claim or counterclaim in a lawsuit), then any patent licenses granted by that Contributor to such Recipient under this Agreement shall terminate as of the date such litigation is filed. In addition, if Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. IBM is the initial Agreement Steward. IBM may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation.