Csdp-6.1.1/0000755000076700007670000000000011357550347007360 5ustar Csdp-6.1.1/doc/0000755000076700007670000000000011357676040010124 5ustar Csdp-6.1.1/doc/cmat.fig0000644000076700007670000001017010470505023011521 0ustar #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.1.1/doc/a1block1.pdf0000644000076700007670000011054710470505023012207 0ustar %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.1.1/doc/README0000644000076700007670000000034210470506736011002 0ustar This 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.1.1/doc/constraints.eps0000644000076700007670000001723510470505023013177 0ustar %!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.1.1/doc/constraints.pdf0000644000076700007670000011010710470505023013151 0ustar %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.1.1/doc/example.c0000644000076700007670000003021610470505023011710 0ustar /* 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.1.1/doc/a1block1.eps0000644000076700007670000002175210470505023012224 0ustar %!PS-Adobe-2.0 EPSF-2.0 %%Title: a1block1.fig %%Creator: fig2dev Version 3.2 Patchlevel 5-alpha5 %%CreationDate: Thu Aug 10 22:15:29 2006 %%For: brian@bullwinkle (brian,,,) %%BoundingBox: 0 0 391 258 %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 258 moveto 0 0 lineto 391 0 lineto 391 258 lineto closepath clip newpath 0.9 284.9 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 2250 810 45 45 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr % Ellipse n 2250 1485 45 45 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr % Ellipse n 2250 2160 45 45 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr % Polyline 0 slj 0 slc 15.000 slw n 1800 465 m 2700 465 l 2700 4500 l 1800 4500 l cp gs col0 s gr % Polyline 7.500 slw n 1785 1140 m 2685 1140 l gs col0 s gr % Polyline n 1785 1815 m 2685 1815 l gs col0 s gr % Polyline n 1800 2490 m 2700 2490 l gs col0 s gr % Polyline n 1785 3165 m 2685 3165 l gs col0 s gr % Polyline n 1785 3825 m 2685 3825 l gs col0 s gr % Polyline gs clippath 2998 2190 m 3165 2190 l 3165 2130 l 2998 2130 l 2998 2130 l 3118 2160 l 2998 2190 l cp eoclip n 2250 2160 m 3150 2160 l gs col0 s gr gr % arrowhead n 2998 2190 m 3118 2160 l 2998 2130 l 2998 2190 l cp gs 0.00 setgray ef gr col0 s % Polyline n 3150 2610 m 3825 2610 l gs col0 s gr % Polyline n 3150 3150 m 3825 3150 l gs col0 s gr % Polyline n 3150 3690 m 3825 3690 l gs col0 s gr % Polyline n 3150 2070 m 3825 2070 l 3825 4275 l 3150 4275 l cp gs col0 s gr % Polyline n 4275 1350 m 4950 1350 l 4950 3555 l 4275 3555 l cp gs col0 s gr % Polyline n 5490 450 m 6165 450 l 6165 2655 l 5490 2655 l cp gs col0 s gr % Polyline n 4275 1935 m 4950 1935 l gs col0 s gr % Polyline n 5490 2115 m 6165 2115 l gs col0 s gr % Polyline n 5490 1530 m 6165 1530 l gs col0 s gr % Polyline n 5490 945 m 6165 945 l gs col0 s gr % Polyline n 4275 2475 m 4950 2475 l gs col0 s gr % Polyline n 4275 3015 m 4950 3015 l gs col0 s gr % Polyline gs clippath 4123 1515 m 4290 1515 l 4290 1455 l 4123 1455 l 4123 1455 l 4243 1485 l 4123 1515 l cp eoclip n 2250 1485 m 4275 1485 l gs col0 s gr gr % arrowhead n 4123 1515 m 4243 1485 l 4123 1455 l 4123 1515 l cp gs 0.00 setgray ef gr col0 s % Polyline gs clippath 5338 840 m 5505 840 l 5505 780 l 5338 780 l 5338 780 l 5458 810 l 5338 840 l cp eoclip n 2250 810 m 5490 810 l gs col0 s gr gr % arrowhead n 5338 840 m 5458 810 l 5338 780 l 5338 840 l cp gs 0.00 setgray ef gr col0 s /Times-Roman-iso ff 285.75 scf sf 675 900 m gs 1 -1 sc (iindices) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 675 1575 m gs 1 -1 sc (jindices) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 0 4275 m gs 1 -1 sc (constraintnum) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 450 2925 m gs 1 -1 sc (blocknum) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 450 3600 m gs 1 -1 sc (blocksize) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 675 2250 m gs 1 -1 sc (entries) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 2160 2925 m gs 1 -1 sc (1) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 2160 3600 m gs 1 -1 sc (2) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 2160 4275 m gs 1 -1 sc (1) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 3330 2475 m gs 1 -1 sc (--) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 3330 3060 m gs 1 -1 sc (3) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 3330 3555 m gs 1 -1 sc (1) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 3330 4050 m gs 1 -1 sc (3) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 4545 1710 m gs 1 -1 sc (--) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 5760 765 m gs 1 -1 sc (--) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 4545 2295 m gs 1 -1 sc (1) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 4545 2835 m gs 1 -1 sc (2) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 4545 3375 m gs 1 -1 sc (2) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 5760 1350 m gs 1 -1 sc (1) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 5760 1935 m gs 1 -1 sc (1) col0 sh gr /Times-Roman-iso ff 285.75 scf sf 5760 2475 m gs 1 -1 sc (2) col0 sh gr % here ends figure; $F2psEnd rs showpage %%Trailer %EOF Csdp-6.1.1/doc/a1block1.fig0000644000076700007670000000551410470505023012200 0ustar #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 2250 810 45 45 2250 810 2295 810 1 3 0 1 0 -1 50 -1 20 0.000 1 0.0000 2250 1485 45 45 2250 1485 2295 1485 1 3 0 1 0 -1 50 -1 20 0.000 1 0.0000 2250 2160 45 45 2250 2160 2295 2160 2 2 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 1800 465 2700 465 2700 4500 1800 4500 1800 465 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 1785 1140 2685 1140 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 1785 1815 2685 1815 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 1800 2490 2700 2490 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 1785 3165 2685 3165 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 1785 3825 2685 3825 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 2250 2160 3150 2160 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 3150 2610 3825 2610 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 3150 3150 3825 3150 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 3150 3690 3825 3690 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 3150 2070 3825 2070 3825 4275 3150 4275 3150 2070 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 4275 1350 4950 1350 4950 3555 4275 3555 4275 1350 2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5 5490 450 6165 450 6165 2655 5490 2655 5490 450 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 4275 1935 4950 1935 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 5490 2115 6165 2115 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 5490 1530 6165 1530 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 5490 945 6165 945 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 4275 2475 4950 2475 2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 4275 3015 4950 3015 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 2250 1485 4275 1485 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 2250 810 5490 810 4 0 0 50 -1 1 18 0.0000 0 195 855 675 900 iindices\001 4 0 0 50 -1 1 18 0.0000 0 255 855 675 1575 jindices\001 4 0 0 50 -1 1 18 0.0000 0 195 1680 0 4275 constraintnum\001 4 0 0 50 -1 1 18 0.0000 0 195 1125 450 2925 blocknum\001 4 0 0 50 -1 1 18 0.0000 0 195 1020 450 3600 blocksize\001 4 0 0 50 -1 1 18 0.0000 0 195 765 675 2250 entries\001 4 0 0 50 -1 1 18 0.0000 0 195 135 2160 2925 1\001 4 0 0 50 -1 1 18 0.0000 0 195 135 2160 3600 2\001 4 0 0 50 -1 1 18 0.0000 0 195 135 2160 4275 1\001 4 0 0 50 -1 1 18 0.0000 0 30 180 3330 2475 --\001 4 0 0 50 -1 1 18 0.0000 0 195 135 3330 3060 3\001 4 0 0 50 -1 1 18 0.0000 0 195 135 3330 3555 1\001 4 0 0 50 -1 1 18 0.0000 0 195 135 3330 4050 3\001 4 0 0 50 -1 1 18 0.0000 0 30 180 4545 1710 --\001 4 0 0 50 -1 1 18 0.0000 0 30 180 5760 765 --\001 4 0 0 50 -1 1 18 0.0000 0 195 135 4545 2295 1\001 4 0 0 50 -1 1 18 0.0000 0 195 135 4545 2835 2\001 4 0 0 50 -1 1 18 0.0000 0 195 135 4545 3375 2\001 4 0 0 50 -1 1 18 0.0000 0 195 135 5760 1350 1\001 4 0 0 50 -1 1 18 0.0000 0 195 135 5760 1935 1\001 4 0 0 50 -1 1 18 0.0000 0 195 135 5760 2475 2\001 Csdp-6.1.1/doc/cmat.pdf0000644000076700007670000011112010470505023011522 0ustar %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.1.1/doc/cmat.eps0000644000076700007670000002515110470505023011550 0ustar %!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.1.1/doc/constraints.fig0000644000076700007670000000301210470505023013141 0ustar #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.1.1/doc/sdp.bib0000644000076700007670000000244010455242355011364 0ustar @article{BorchersB:CSDCls, title = {{CSDP}, a {C} library for semidefinite programming}, author = {B. Borchers}, journal = {Optimization Methods \& Software}, volume = {11-2}, number = {1-4}, pages = {613 -- 623}, year = {1999}, } @article{HelmbergC:Anims, title = "An interior-point method for semidefinite programming", author = "C. Helmberg and F. Rendl and R. J. Vanderbei and H. Wolkowicz", journal = "{SIAM} Journal on Optimization", volume = "6", number = "2", pages = "342 -- 361", month = "May", year = "1996", } @article{SturmJF:UsiS1M, title = "Using {S}e{D}u{M}i 1.02, a {MATLAB} toolbox for optimization over symmetric cones", author = {J. F. Sturm}, journal = {Optimization Methods \& Software}, volume = {11-2}, number = {1-4}, pages = {625 -- 653}, year = {1999}, } @article{MittelmannHD:AnibS, title = "An independent benchmarking of {SDP} and {SOCP} solvers", author = "H. D. Mittelmann", journal = {Mathematical Programming}, volume = {95}, number = {2}, pages = {407 -- 430}, month = {February}, year = {2003}, } @techreport{SDPA, author="K. Fujisawa and M. Kojima and K. Nakata and M. Yamashita", title="{SDPA} (semidefinite programming algorithm) users manual - version 6.00", number="B--308", institution="Tokyo Institute of Technology", year="1995", notes="Revised July 2002"} Csdp-6.1.1/doc/csdpuser.tex0000644000076700007670000011250211316556767012507 0ustar \documentclass{article} \usepackage[pdftex]{graphicx} \bibliographystyle{plain} \begin{document} % % Some useful definitions. % %\newcommand{\dzhat}{{\Delta \hat{Z}}} %\newcommand{\dxhat}{{\Delta \hat{X}}} %\newcommand{\dyhat}{{\Delta \hat{y}}} %\newcommand{\dthat}{{\Delta \hat{t}}} % %\newcommand{\dzbar}{{\Delta \bar{Z}}} %\newcommand{\dxbar}{{\Delta \bar{X}}} %\newcommand{\dybar}{{\Delta \bar{y}}} %\newcommand{\dtbar}{{\Delta \bar{t}}} % %\newcommand{\dz}{{\Delta Z}} %\newcommand{\dx}{{\Delta X}} %\newcommand{\dy}{{\Delta y}} %\newcommand{\dt}{{\Delta t}} \newcommand{\elprod}{\circ} \title{CSDP User's Guide} \date{December 29, 2009} \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 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 very 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| } & < & 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 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.11e-16 Relative dual infeasibility: 3.93e-09 Real Relative Gap: 7.21e-09 XZ Relative Gap: 7.82e-09 DIMACS error measures: 1.11e-16 0.00e+00 1.00e-07 0.00e+00 7.21e-09 7.82e-09 Elements time: 0.008845 Factor time: 0.008865 Other time: 0.198949 Total time: 0.216659 \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 samll 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, axtol, atytol, and objtol are the tolerances for primal feasibility, dual feasibility, and relative duality gap. The parameters pinftol and dinftol are tolerances used in determining primal and dual infeasibility. The maxiter parameter is used to limit the total number of iterations that CSDP may use. The minstepfrac and maxstepfrac parameters determine how close to the edge of the feasible region CSDP will step. If the primal or dual step is shorter than minstepp or minstepd, then CSDP declares a line search failure. If parameter usexzgap is 0, then CSDP will use the objective function duality gap instead of the $\mbox{tr}(XZ)$ gap. If tweakgap is set to 1, and usexzgap is set to 0, then CSDP will attempt to ``fix'' negative duality gaps. If parameter 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 printlevel parameter determines how much debugging information is output. Use printlevel=0 for no output and printlevel=1 for normal output. Higher values of printlevel will generate more debugging output. The perturbobj parameter determines whether the objective function will be perturbed to help deal with problems that have unbounded optimal solution sets. If perturbobj is 0, then the objective will not be perturbed. If perturbobj=1, then the objective function will be perturbed by a default amount. Larger values of perturbobj (e.g. 100.0) increase the size of the perturbation. This can be helpful in solving some difficult problems. The fastmode parameter determines whether or not CSDP will skip certain time consuming operations that slightly improve the accuracy of the solutions. If 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. % % 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. \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 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 pars = objtol: 1.0000e-09 >> [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.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.7784627e+01 Iter: 18 Ap: 1.00e+00 Pobj: 1.7784626e+01 Ad: 1.00e+00 Dobj: 1.7784620e+01 Iter: 19 Ap: 1.00e-00 Pobj: 1.7784627e+01 Ad: 1.00e+00 Dobj: 1.7784627e+01 Iter: 20 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: 1.08e-09 Relative dual infeasibility: 3.12e-10 Real Relative Gap: -3.50e-10 XZ Relative Gap: 6.05e-11 DIMACS error measures: 1.08e-09 0.00e+00 7.02e-10 0.00e+00 -3.50e-10 6.05e-11 Elements time: 0.003162 Factor time: 0.000430 Other time: 0.013774 Total time: 0.017366 0.012u 0.004s 0:00.02 50.0% 0+0k 0+0io 0pf+0w >> info info = 0 \end{verbatim} 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 SDPpack file, in quotes % A,b,c,K Problem in SeDuMi form % pars Optional parameters. % pars.printlevel=0 No printed output % pars.prinlevel=1 (default) Some printed output. % pars.check=0 (default) Do not check problem data % for symmetry. % pars.check=1 Check problem data for % symmetry. % % 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. The nonzero return codes are \begin{enumerate} \item Success. The problem is primal infeasible. \item Success. The problem is dual infeasible. \item Partial Success. A solution has been found, but full accuracy was not achieved. One or more of primal infeasibility, dual infeasibility, or relative duality gap are larger than their tolerances, but by a factor of less than 1000. \item Failure. Maximum iterations reached. \item Failure. Stuck at edge of primal feasibility. \item Failure. Stuck at edge of dual infeasibility. \item Failure. Lack of progress. \item Failure. X, Z, or O was singular. \item Failure. Detected NaN or Inf values. \end{enumerate} \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 blockmatrix 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.1.1/INSTALL0000644000076700007670000001771010522714256010411 0ustar REQUIREMENTS: 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 you will need the g2c C/Fortran compatibility library that comes as part of the g77 package. 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 a reasonable way to start, but you may well find that you need faster routines to get acceptable performance. ATLAS (automatically tuned linear algebra software) is an open source implementation of BLAS and part of LAPACK that is sufficient for our purposes. ATLAS obtains good performance on a variety of systems by automatically adjusting blocksizes and other parameters to get the best performance out of any particular system. ATLAS is availible at http://math-atlas.sourceforge.net/ If possible, use their precompiled, optimized libraries that are availible for several architectures, otherwise build it yourself from source. 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. In practice, on Intel or AMD Linux systems, we find that ATLAS provides very good performance (close to if not better than MKL or ACML.) Thus we recommend ATLAS. However, to make the build process simpler and more flexible, the make files are setup to use whatever LAPACK and BLAS libraries are already installed on your system. If you decide to use ATLAS, the make files contain ATLAS specific instructions. 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.) Note that earlier versions of Octave, particularly 2.0 and 2.1, will not function with this interface because Octave didn't support sparse matrices until version 2.9. The README file in the matlab directory contains instructions for installing the matlab interface and testing it on a sample problem. DOWNLOADING CSDP: The 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 Csdp Or use a GUI to access the repository. Source and binaries for older stable versions of CSDP can be downloaded from http://www.nmt.edu/~borchers/csdp.html INSTALLING CSDP: The following instructions assume that you're using a Linux system with gcc, g77, 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 5.0, and then go into the csdp directory (this directory is called "Csdp" in subversion) Issue the command > make to build CSDP. Make will go into the lib, solver, theta, and example subdirectories and compile the C code, using values of CFLAGS and LIBS supplied in the Makefiles in these directories. 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, lapack, or g2c) 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 If 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 test 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). USING GCC 4: In gcc 3.x, the C/Fortran compatibility library was linked with -lg2c. In gcc 4.x, you will need to link with -lgfortran instead. Note that OpenMP support first appears in Red Hat's version of gcc 4.1.1 and also appears in the general release of gcc 4.2. There is no OpenMP support in earlier versions of gcc! RUNNING CSDP IN PARALLEL: Version 6 of CSDP includes support for a parallel version of CSDP on multi-processor shared memory systems. This is done using the OpenMP standard for #pragma's that tell the C compiler how to parallelize various loops in the code. On systems that don't support OpenMP, these pragma's are simply ignored. On systems that do support OpenMP, it will typically be necessary to modify the CFLAGS and LIBS in the Makefiles to build a parallel version of CSDP. As an example, the following CFLAGS and LIBS have been used to build a parallel version of CSDP on a Red Hat Enterprise Linux system using Red Hat's version of gcc4.1 with ATLAS. CFLAGS=CFLAGS=-O3 -march=nocona -m64 -fprefetch-loop-arrays -ftree-vectorize -ftree-vectorizer-verbose=1 -fopenmp -ansi -Wall -DNOSHORTS -DBIT64 -DUSEOPENMP -I../include LIBS=LIBS=-static -L../lib -lsdp -llapack -lptf77blas -lptcblas -latlas -lgomp -lrt -lpthread -lgfortran -lm Csdp-6.1.1/README0000644000076700007670000000402710522714256010235 0ustar Copyright 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.1.1/lib/0000755000076700007670000000000011357550347010126 5ustar Csdp-6.1.1/lib/tweakgap.c0000644000076700007670000000227610522313034012063 0ustar /* * 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.1.1/lib/mat_multsp.c0000644000076700007670000004133510522313034012444 0ustar /* * 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(1). * * It is assumed that all three matrices are of compatible block strucutre. * * This version of mat_mult is specialized to deal with matrices B * which have nonzero structure given by fill. * */ #include #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(12); }; /* * 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(12); }; }; /* * 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(12); }; /* * 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(12); }; /* * 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(12); }; }; /* * 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(12); }; /* * 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(12); }; /* * 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(12); }; }; /* * 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(12); }; /* * Move on to the next block. */ ptr=ptr->next; }; }; } Csdp-6.1.1/lib/calc_dobj.c0000644000076700007670000000101410455242355012161 0ustar /* 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.1.1/lib/sym_mat.c0000644000076700007670000000140210455242355011733 0ustar /* 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(12); }; }; } Csdp-6.1.1/lib/sdp.c0000644000076700007670000014570611302065714011062 0ustar /* 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. 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. 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 oldmu; 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; double maxrelinfeas=1.0e100; double oldmaxrelinfeas=1.0e100; double newpobj; double newdobj; int iter=0; int m; int ret; int i; int j; int info; int ldam; int retries=0; int retcode=0; double bestmeas; int lastimprove=0; 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; /* * 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; oldmaxrelinfeas=maxrelinfeas; if (relpinfeas > reldinfeas) { maxrelinfeas=relpinfeas; } else { maxrelinfeas=reldinfeas; }; /* * 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. */ if (user_exit(n,k,C,a,*dobj,*pobj,constant_offset,constraints, X,y,Z,parameters) == 1) { 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,ldam)]=O[ijtok(i,j,ldam)]; for (i=1; i<=k; i++) diagO[i]=O[ijtok(i,i,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,ldam)] += diagadd; /* * Scale the O matrix. */ for (i=1; i<=k; i++) workvec8[i]=1.0/sqrt(O[ijtok(i,i,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,ldam)]=O[ijtok(i,j,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,ldam)]=O[ijtok(j,i,ldam)]; for (i=1; i<=k; i++) O[ijtok(i,i,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); oldmu=mu; /* 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 */ if (user_exit(n,k,C,a,affdobj,affpobj,constant_offset,constraints, work1,workvec1,work2,parameters) == 1) { *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)) { lastimprove=iter; 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); /* * Compute the objective value of the new solution. */ newpobj=calc_pobj(C,work1,constant_offset); 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]; /* * Calculate the prospective new dual objective. */ newdobj=calc_dobj(k,a,workvec1,constant_offset); /* * 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); newpobj=calc_pobj(C,work1,constant_offset); 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,ldam)]=O[ijtok(j,i,ldam)]; for (i=1; i<=k; i++) O[ijtok(i,i,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); newdobj=calc_dobj(k,a,workvec1,constant_offset); 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,ldam)]=O[ijtok(j,i,ldam)]; for (i=1; i<=k; i++) O[ijtok(i,i,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,ldam)]=O[ijtok(j,i,ldam)]; for (i=1; i<=k; i++) O[ijtok(i,i,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=9; goto RETURNBEST; }; }; /* * In case alphap changed, recompute these. */ addscaledmat(X,alphap,dX,work1); newpobj=calc_pobj(C,work1,constant_offset); 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]; newdobj=calc_dobj(k,a,workvec1,constant_offset); 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]; /* * Update the objectives. */ newdobj=calc_dobj(k,a,y,constant_offset); newpobj=calc_pobj(C,X,constant_offset); /* 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; oldmaxrelinfeas=maxrelinfeas; if (relpinfeas > reldinfeas) { maxrelinfeas=relpinfeas; } else { maxrelinfeas=reldinfeas; }; /* * 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=12; 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=12; 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.1.1/lib/mat_mult.c0000644000076700007670000000554311305641213012105 0ustar /* * 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(1). * * 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(12); }; }; } void mat_mult_raw(n,scale1,scale2,ap,bp,cp) int n; double scale1; double scale2; double *ap; double *bp; double *cp; { #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 } #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.1.1/lib/qreig.c0000644000076700007670000000252010455242355011373 0ustar /* * 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 "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(12); }; }; } Csdp-6.1.1/lib/easysdp.c0000644000076700007670000003161110522313034011723 0ustar /* * This is an easy to call version of the sdp routine. It takes as * input a problem (n,k,C,a,constraints,constant_offset), and an * initial solution (X,y,Z), allocates working storage, and calls sdp() * to solve the problem. The solution is returned in X,y,Z,pobj,dobj, and * the return code from sdp is returned as the return value from easy_sdp. * */ #include #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; int blk; struct sparseblock *p; struct sparseblock *q; struct sparseblock *prev=NULL; double gap; int nnz; /* * 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(10); }; 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(10); }; 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(10); }; 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(10); }; 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(10); }; 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(10); }; 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(10); }; 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(10); }; 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(10); }; 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(10); }; rhs=malloc(sizeof(double)*(k+1)); if (rhs == NULL) { printf("Storage Allocation Failed!\n"); exit(10); }; dy=malloc(sizeof(double)*(k+1)); if (dy == NULL) { printf("Storage Allocation Failed!\n"); exit(10); }; dy1=malloc(sizeof(double)*(k+1)); if (dy1 == NULL) { printf("Storage Allocation Failed!\n"); exit(10); }; Fp=malloc(sizeof(double)*(k+1)); if (Fp == NULL) { printf("Storage Allocation Failed!\n"); exit(10); }; /* * 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(10); }; 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. */ /* * Set up the cross links used by op_o * While we're at it, determine which blocks are sparse and dense. */ /* * 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. */ if (((p->numentries) > 0.25*(p->blocksize)) && ((p->numentries) > 15)) { 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) { blk=p->blocknum; /* * 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 >= 4) { for (i=1; i<=k; i++) { p=constraints[i].blocks; while (p != NULL) { printf("%d,%d,%d,%d \n",i,p->blocknum,p->issparse,p->numentries); p=p->next; }; }; }; /* * Allocate space for byblocks pointers. */ byblocks=(struct sparseblock **)malloc((C.nblocks+1)*sizeof(struct sparseblock *)); if (byblocks == NULL) { printf("Storage Allocation Failed!\n"); exit(10); }; 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. */ nnz=structnnz(n,k,C,constraints); if (printlevel >= 3) printf("Structural density of O %d, %e \n",nnz,nnz*1.0/(k*k*1.0)); /* * Sort entries in diagonal blocks of constraints. */ sort_entries(k,C,constraints); /* * 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); } Csdp-6.1.1/lib/initsoln.c0000644000076700007670000000353710455242355012134 0ustar /* * 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(10); }; /* * 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.1.1/lib/readsol.c0000644000076700007670000000450610455242355011723 0ustar /* Read in a solution in SDPA sparse format. */ #include #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(10); }; /* * Open the file for reading. */ fid=fopen(fname,"r"); if (fid == (FILE *) NULL) { printf("Couldn't open solution file for reading. \n"); exit(11); }; /* * 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(12); }; } 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(12); }; }; } while (ret != EOF); fclose(fid); return(0); } Csdp-6.1.1/lib/trace_prod.c0000644000076700007670000000174510455242355012416 0ustar /* 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(12); }; }; return(sum); } Csdp-6.1.1/lib/allocmat.c0000644000076700007670000000360310455242355012063 0ustar /* * 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(10); }; /* * 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(10); }; 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(10); }; break; default: printf("alloc_mat illegal block type!\n"); exit(12); }; }; } 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(12); }; }; /* * Then free space for the block records. */ free(A.blocks); } Csdp-6.1.1/lib/matvec.c0000644000076700007670000000227510455242355011552 0ustar /* * 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 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 p=p+n; break; case PACKEDMATRIX: default: printf("matvec illegal block type \n"); exit(12); }; }; } Csdp-6.1.1/lib/user_exit.c0000644000076700007670000000241710626717522012303 0ustar /* * 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 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; { sigterm_signaled=1; } 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; { signal(SIGTERM,catch_sigterm); if (sigterm_signaled==1) return(1); else return(0); } #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; { return(0); } #endif Csdp-6.1.1/lib/Makefile0000644000076700007670000001320511302072624011552 0ustar # # Uncomment this line to specify the C compiler if the system default isn't # what you want to use. # #CC=cc # # Use this line to specify options for the C compiler. You'll probably # want to turn on optimizations. You may also have to use some of the # following flags: # # -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. # -DBIT64 For I32LP64 systems. # -DNOSHORTS Allow for (LP) blocks of more than 65535 variables. # -DUSEOPENMP Build an OpenMP parallel version. # -DSETNUMTHREADS Work with OpenMP aware BLAS. # -DUSESIGTERM Terminate nicely at the end of the next iteration # after receiving a SIGTERM signal # -DUSEGETTIME Use ANSI C gettime() routine to determine clock # time used in different parts of the code. # -DUSEATLAS Turns on some special code for use with the ATLAS BLAS. # # The default settings for gcc: # CFLAGS=-O3 -ansi -Wall -DNOSHORTS -DUSEGETTIME -I../include # # Notes on CFLAGS. # # 1. The -DNOSHORTS flag should always be used. When this is turned off, # it causes the code to use unsigned short integers (maximum value 65535) # in the data structures that describe the problem. This can cause problems # when some of the size parameters are larger than 65535. # # 2. -DUSEGETTIME is generally useful. However, this functionality isn't # available under Windows/MSYS/MINGW, so you should remove it when compiling # for that system. # # 3. By default, we assume that BLAS routines have names like ddot_(), # but some systems use ddot(), DDOT(), or DDOT_() instead. A similar issue # effects the LAPACK routines. The flags -DCAPSBLAS, -DCAPSLAPACK, # -DNOUNDERBLAS. and -DNOUNDERLAPACK are used to handle such situations. # # 4. The code can be built on 64 bit systems that use an I32LP64 model # in which int's are 32 bits, long's and pointers are 64 bits. Note that # that is the model on all 64 bit Linux and Unix systems that I'm aware of, # but it is not the model used by MS in its 64 bit Windows! To build a # 64 bit version of the code, use -DBIT64. You may also need to add a CFLAG # to tell your compiler to produce 64 bit code. For example, with gcc, # you'll need to add "-m64" to CFLAGS to produce 64 bit code. # # 5. If you have multiple CPU's, and if your compiler supports OpenMP, then # you should definitely build a parallel version of CSDP. To do this, # add "-DUSEOPENMP" to CFLAGS. If your BLAS/LAPACK library routines # use OpenMP's conventions for setting the number of threads to use, then # you should also add "-DSETNUMTHREADS". Note that ATLAS does not # currently work with "-DSETNUMTHREADS", but you can use SETNUMTHREADS # on Solaris with -lsunperf and AIX systems with -lesslsmp. # # You will also have to add appropriate CFLAGS to tell your compiler # to compile OpenMP code. This varies from system to system. However, # with gcc4.2, you can use # # -static -fopenmp # # You may also have to add additional libraries when you link your # OpenMP code. For example, gcc 4.2 with OpenMP needs # # -lgomp -lrt -lpthread # # 6. Using gcc, you can greatly improve the efficency of the code if you # specify your processor type. Examples are given below, use the default # if you are unsure. More examples may be found at # # http://gcc.gnu.org/onlinedocs/gcc/i386-and-x86_002d64-Options.html # # An AMD Athlon XP based machine: # CFLAGS=-march=athlon-xp -O3 -ansi -Wall -DNOSHORTS -I../include # An Intel Pentum 4 based machine: # CFLAGS=-march=pentum4 -O3 -ansi -Wall -DNOSHORTS -I../include # # 7. The code can be built with Intel's icc C compiler and MKL BLAS/ # LAPACK libraries. This has been tested with icc 11.0 and should # work with later versions as well. # # CC=icc # CFLAGS=-O3 -m64 -openmp -DBIT64 -DUSEOPENMP -DNOSHORTS -DSETNUMTHREADS # -I../include # LIBS=-openmp -L../lib -lsdp -mkl -lm # # 8. The can works particularly well with the ATLAS BLAS/LAPACK routines # when compiled with gcc. There are some important optimizations in the # code that depend on the availability of routines within ATLAS, so use # use -DUSEATLAS to turn these on. e.g. # # CFLAGS=-O3 -fopenmp -ansi -Wall -DUSEATLAS -DNOSHORTS -DBIT64 # -DUSEOPENMP -I../include # # # 9. If you change the CFLAGS, make sure that you use the same CFLAGS # in the Makefiles in the solver and theta directories! # # 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.1.1/lib/makefill.c0000644000076700007670000001333710455242355012060 0ustar /* * 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(12); }; }; /* * 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(12); }; 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(10); }; 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(10); }; 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(10); }; #ifdef NOSHORTS ptr->iindices=(int *) malloc((ptr->blocksize+1)*sizeof(int)); #else ptr->iindices=(unsigned short *) malloc((ptr->blocksize+1)*sizeof(unsigned short)); #endif if (ptr->iindices == NULL) { printf("Storage Allocation Failed!\n"); exit(10); }; #ifdef NOSHORTS ptr->jindices=(int *) malloc((ptr->blocksize+1)*sizeof(int)); #else ptr->jindices=(unsigned short *) malloc((ptr->blocksize+1)*sizeof(unsigned short)); #endif if (ptr->jindices == NULL) { printf("Storage Allocation Failed!\n"); exit(10); }; 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(10); }; #ifdef NOSHORTS ptr->iindices=(int *) malloc((ptr->numentries+1)*sizeof(int)); #else ptr->iindices=(unsigned short *) malloc((ptr->numentries+1)*sizeof(unsigned short)); #endif if (ptr->iindices == NULL) { printf("Storage Allocation Failed!\n"); exit(10); }; #ifdef NOSHORTS ptr->jindices=(int *) malloc((ptr->numentries+1)*sizeof(int)); #else ptr->jindices=(unsigned short *) malloc((ptr->numentries+1)*sizeof(unsigned short)); #endif if (ptr->jindices == NULL) { printf("Storage Allocation Failed!\n"); exit(10); }; 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(12); }; 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.1.1/lib/calc_pobj.c0000644000076700007670000000202510455242355012200 0ustar /* 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(12); }; }; return(pobj); } Csdp-6.1.1/lib/op_a.c0000644000076700007670000000245510522313034011175 0ustar /* 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.1.1/lib/linesearch.c0000644000076700007670000001565510522313034012402 0ustar /* 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(10); }; /* * 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 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 scale1=-1.0; scale2=1.0; inc=1; #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 scale1=1.0; scale2=0.0; inc=1; #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 scale1=-1.0; scale2=1.0; inc=1; #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 /* * 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.1.1/lib/norms.c0000644000076700007670000000205510455242355011425 0ustar /* * 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.1.1/lib/make_i.c0000644000076700007670000000151010522313034011473 0ustar /* 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(12); }; } } Csdp-6.1.1/lib/solvesys.c0000644000076700007670000000136310455242355012157 0ustar /* 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 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 if (info != 0) { return(6); }; return(0); } Csdp-6.1.1/lib/copy_mat.c0000644000076700007670000000155510522313034012072 0ustar /* 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(12); }; } } Csdp-6.1.1/lib/op_o.c0000644000076700007670000002637111357460671011237 0ustar /* * 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(10); } 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(10); }; }; }; /* * 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, 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, 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, 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,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, ldam)] += O[ijtok(j,i,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.1.1/lib/op_at.c0000644000076700007670000000211210455242355011363 0ustar /* 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.1.1/lib/add_mat.c0000644000076700007670000000147010455242355011660 0ustar /* 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(12); }; }; } Csdp-6.1.1/lib/readprob.c0000644000076700007670000004507210455242355012073 0ustar /* 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(); void 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; struct sparseblock *q; struct sparseblock *prev; 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) { printf("Couldn't open problem file for reading! \n"); exit(11); }; buflen=max_line_length(fid)+10; fclose(fid); buf=(char *)malloc(buflen*sizeof(char)); if (buf == NULL) { printf("Storage allocation failed!\n"); exit(10); }; /* * In the first pass through the file, determine the size parameters, * and allocate space for everything. */ fid=fopen(fname,"r"); if (fid == (FILE *) NULL) { printf("Couldn't open problem file for reading! \n"); exit(11); }; /* * 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)) { printf("Incorrect SDPA file. Couldn't read mDIM\n"); fclose(fid); return(1); }; } else { printf("Incorect SDPA file. Couldn't read mDIM \n"); fclose(fid); return(1); }; #ifndef NOSHORTS /* * If we're using unsigned shorts, make sure that the problem isn't * too big. */ if (*pk >= USHRT_MAX) { printf("This problem is too large to be solved by this version of the code!\n"); printf("Recompile without -DUSERSHORTINDS to fix the problem.\n"); exit(10); }; #endif #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) { printf("This problem is too large to be solved in 32 bit mode!\n"); exit(10); }; #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)) { printf("Incorect SDPA file. Couldn't read nBLOCKS. \n"); fclose(fid); return(1); }; } else { 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; #ifndef NOSHORTS /* * If we're using unsigned shorts, make sure that the problem isn't * too big. */ if (nblocks >= USHRT_MAX) { printf("This problem is too large to be solved by this version of the code!\n"); printf("Recompile with -DNOSHORTS to fix the problem.\n"); exit(10); }; #endif /* * Allocate space for the C matrix. */ pC->nblocks=nblocks; pC->blocks=(struct blockrec *)malloc((nblocks+1)*sizeof(struct blockrec)); if (pC->blocks == NULL) { printf("Storage allocation failed!\n"); exit(10); } /* * Allocate space for the constraints. */ myconstraints=(struct constraintmatrix *)malloc((*pk+1)*sizeof(struct constraintmatrix)); if (myconstraints == NULL) { printf("Storage allocation failed!\n"); exit(10); }; /* * 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) { printf("Storage allocation failed!\n"); exit(10); }; /* * 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; #ifndef NOSHORTS /* * If we're using unsigned shorts, make sure that the problem isn't * too big. */ if (abs(blksz) >= USHRT_MAX) { printf("This problem is too large to be solved by this version of the code!\n"); printf("Recompile with -DNOSHORTS to fix the problem.\n"); exit(10); }; #endif /* * 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) { printf("Storage allocation failed!\n"); exit(10); }; for (i=1; i<=abs(blksz); i++) pC->blocks[blk].data.vec[i]=0.0; } else { /* * It's a matrix block. */ 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) { printf("Storage allocation failed!\n"); exit(10); }; for (j=1; j<=blksz; j++) for (i=1; i<=blksz; i++) pC->blocks[blk].data.mat[ijtok(i,j,blksz)]=0.0; }; }; } else { 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); ptr1=ptr2; }; } else { 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) { 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)) { 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)) { 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) { printf("Storage allocation failed!\n"); exit(10); }; #ifdef NOSHORTS p->iindices=(int *)malloc((p->numentries+1)*sizeof(int)); #else p->iindices=(unsigned short *)malloc((p->numentries+1)*sizeof(unsigned short)); #endif if (p->iindices == NULL) { printf("Storage allocation failed!\n"); exit(10); }; #ifdef NOSHORTS p->jindices=(int *)malloc((p->numentries+1)*sizeof(int)); #else p->jindices=(unsigned short *)malloc((p->numentries+1)*sizeof(unsigned short)); #endif if (p->jindices == NULL) { printf("Storage allocation failed!\n"); exit(10); }; 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) { printf("Couldn't open problem file for reading! \n"); exit(11); }; /* * 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 { 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 { 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) { 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); ptr1=ptr2; }; } else { 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) addentry(myconstraints,matno,blkno,indexi,indexj,ent); } else { /* * An entry in C. */ if (ent != 0.0) { blksz=pC->blocks[blkno].blocksize; if (pC->blocks[blkno].blockcategory == DIAG) { pC->blocks[blkno].data.vec[indexi]=ent; } 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)) { 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) { /* * First, set issparse. */ if (((p->numentries) > 0.25*(p->blocksize)) && ((p->numentries) > 15)) { p->issparse=0; } else { p->issparse=1; }; if (pC->blocks[p->blocknum].blockcategory == DIAG) p->issparse=1; /* * Setup the cross links. */ p->nextbyblock=NULL; p=p->next; }; }; /* * Now, cross link. */ prev=NULL; for (i=1; i<=*pk; i++) { p=myconstraints[i].blocks; while (p != NULL) { if (p->nextbyblock == NULL) { blk=p->blocknum; /* * link in the remaining blocks. */ for (j=i+1; j<=*pk; j++) { q=myconstraints[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; }; }; /* * 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(10); }; 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(10); }; /* * 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; }; } void addentry(constraints,matno,blkno,indexi,indexj,ent) struct constraintmatrix *constraints; int matno; int blkno; int indexi; int indexj; double ent; { struct sparseblock *p; p=constraints[matno].blocks; if (p == NULL) { printf("Internal Error in CSDP!\n"); exit(100); } 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; return; }; p=p->next; }; /* * If we get here, we have an internal error. */ printf("Internal Error in CSDP!\n"); exit(100); }; } Csdp-6.1.1/lib/freeprob.c0000644000076700007670000000202010455242355012063 0ustar /* * 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.1.1/lib/Fnorm.c0000644000076700007670000000471310455242355011353 0ustar /* 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(12); }; }; 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(12); }; }; 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(12); }; }; 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(12); }; }; return(nrm); } Csdp-6.1.1/lib/zero_mat.c0000644000076700007670000000151210522313034012070 0ustar /* 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(12); }; }; } Csdp-6.1.1/lib/packed.c0000644000076700007670000001001010522313034011470 0ustar /* * 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(12); }; } } 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(10); }; /* * 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(10); }; 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(10); }; break; default: printf("Illegal block type!\n"); exit(12); }; }; } 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(12); }; }; /* * 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 #include "declarations.h" int chol_blk(n,lda,A) int n; int lda; double *A; { int info; int i; int j; info=0; #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 if (info != 0) { return(1); }; /* * Now, make sure that the lower triangle of A is 0.0 */ for (j=1; j #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.1.1/lib/initparams.c0000644000076700007670000000523210522313034012422 0ustar /* * Setup default values of the parameters. */ #include #include "declarations.h" void initparams(params,pprintlevel) struct paramstruc *params; int *pprintlevel; { FILE *paramfile; paramfile=fopen("param.csdp","r"); if (paramfile == NULL) { 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; } else { fscanf(paramfile,"%*[^=]%*c%lf",&(params->axtol)); fscanf(paramfile,"%*[^=]%*c%lf",&(params->atytol)); fscanf(paramfile,"%*[^=]%*c%lf",&(params->objtol)); fscanf(paramfile,"%*[^=]%*c%lf",&(params->pinftol)); fscanf(paramfile,"%*[^=]%*c%lf",&(params->dinftol)); fscanf(paramfile,"%*[^=]%*c%d",&(params->maxiter)); fscanf(paramfile,"%*[^=]%*c%lf",&(params->minstepfrac)); fscanf(paramfile,"%*[^=]%*c%lf",&(params->maxstepfrac)); fscanf(paramfile,"%*[^=]%*c%lf",&(params->minstepp)); fscanf(paramfile,"%*[^=]%*c%lf",&(params->minstepd)); fscanf(paramfile,"%*[^=]%*c%d",&(params->usexzgap)); fscanf(paramfile,"%*[^=]%*c%d",&(params->tweakgap)); fscanf(paramfile,"%*[^=]%*c%d",&(params->affine)); fscanf(paramfile,"%*[^=]%*c%d",pprintlevel); fscanf(paramfile,"%*[^=]%*c%lf",&(params->perturbobj)); fscanf(paramfile,"%*[^=]%*c%d",&(params->fastmode)); fclose(paramfile); }; if (*pprintlevel >= 3) { 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.1.1/lib/writesol.c0000644000076700007670000000411410455242355012135 0ustar /* 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(11); }; /* * 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(12); }; }; /* * 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(12); }; }; /* * Close up and quit. */ fclose(fid); return(0); } Csdp-6.1.1/lib/sortentries.c0000644000076700007670000000434511041756262012653 0ustar #include #include #include "declarations.h" struct entry { #ifndef NOSHORTS unsigned short indexi; unsigned short indexj; unsigned short indexk; unsigned short indexl; double entry; #else int indexi; int indexj; int indexk; int indexl; double entry; #endif }; 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(10); }; for (i=1; i<=k; i++) { ptr=constraints[i].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.1.1/lib/writeprob.c0000644000076700007670000000437310455242355012311 0ustar /* 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(11); }; /* * 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(12); }; }; 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(12); }; }; /* * 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.1.1/LICENSE0000644000076700007670000002704310522714256010365 0ustar Common 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. Csdp-6.1.1/example/0000755000076700007670000000000011357550347011013 5ustar Csdp-6.1.1/example/example.c0000644000076700007670000003044710522313034012601 0ustar /* 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.1.1/example/Makefile0000644000076700007670000001171411316561142012445 0ustar # # Uncomment this line to specify the C compiler if the system default isn't # what you want to use. # #CC=cc # # Use this line to specify options for the C compiler. You'll probably # want to turn on optimizations. You may also have to use some of the # following flags: # # -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. # -DBIT64 For I32LP64 systems. # -DNOSHORTS Allow for (LP) blocks of more than 65535 variables. # -DUSEOPENMP To turn on OpenMP parallelization # -DSETNUMTHREADS To use with an OpenMP aware BLAS library. # # The default settings for gcc: # CFLAGS=-O3 -ansi -Wall -DNOSHORTS -I../include # # Notes on CFLAGS. # # 1. The -DNOSHORTS flag should always be used. When this is turned off, # it causes the code to use unsigned short integers (maximum value 65535) # in the data structures that describe the problem. This can cause problems # when some of the size parameters are larger than 65535. # # 2. By default, we assume that BLAS routines have names like ddot_(), # but some systems use ddot(), DDOT(), or DDOT_() instead. A similar issue # effects the LAPACK routines. The flags -DCAPSBLAS, -DCAPSLAPACK, # -DNOUNDERBLAS. and -DNOUNDERLAPACK are used to handle such situations. # # 3. The code can be built on 64 bit systems that use an I32LP64 model # in which int's are 32 bits, long's and pointers are 64 bits. Note that # that is the model on all 64 bit Linux and Unix systems that I'm aware of, # but it is not the model used by MS in its 64 bit Windows! To build a # 64 bit version of the code, use -DBIT64. You may also need to add a CFLAG # to tell your compiler to produce 64 bit code. For example, with gcc, # you'll need to add "-m64" to CFLAGS to produce 64 bit code. # # 4. If you have multiple CPU's, and if your compiler supports OpenMP, then # you should definitely build a parallel version of CSDP. To do this, # add "-DUSEOPENMP" to CFLAGS. If your BLAS/LAPACK library routines # use OpenMP's conventions for setting the number of threads to use, then # you should also add "-DSETNUMTHREADS". Note that ATLAS does not # currently work with "-DSETNUMTHREADS", but you can use SETNUMTHREADS # on Solaris with -lsunperf and AIX systems with -lesslsmp. # 5. Using gcc, you can greatly improve the efficency of the code if you # specify your processor type. Examples are given below, use the default # if you are unsure. More examples may be found at # # http://gcc.gnu.org/onlinedocs/gcc/i386-and-x86_002d64-Options.html # # An AMD Athlon XP based machine: # CFLAGS=-march=athlon-xp -O3 -ansi -Wall -DNOSHORTS -I../include # An Intel Pentum 4 based amchine: # CFLAGS=-march=pentum4 -O3 -ansi -Wall -DNOSHORTS -I../include # # 6. If you change the CFLAGS, make sure that you use the same CFLAGS # in the Makefiles in the solver and theta directories! # # The code depends on several libraries: # # sdp The CSDP subroutine library # lapack The LAPACK linear algebra library # blas The BLAS basic linear algebra library # # In addition, if you're using gcc to compile the C code, then you'll need: # # gfortran The gnu C/Fortran 77 compatibility library # m The C math run time library. # # # Use this line to specify where the SDP and linear algebra libraries are # to be found. # # -L../lib look in the ../lib directory # -lsdp get libsdp.a from the ../lib directory # -llapack get liblapack.a or liblapack.so # -lblas get libblas.a or libblas.so # -lgfortran get libgfortran.a or libgfortran.so # -lm get libm.a or libm.so # # The default settings for a Linux system with gcc3, lapack, blas, and # gfortran: # LIBS=-L../lib -lsdp -llapack -lblas -lgfortran -lm # # 1. Warning about debian systems. For some absurb reason, the BLAS # package in debian has the BLAS library named libblas-3.a, rather than # libblas.a. You can either modify the LIBS= line, or you can create # a symbolic link from /usr/lib/libblas.a to /usr/lib/libblas-3.a. # # 2. An alternative set of flags for use with the ATLAS BLAS on a Linux system. # # LIBS=-L../lib -lsdp -llapack -lf77blas -lcblas -latlas -lgfortran -lm # # 3. Special note on gcc 4. For gcc versions before gcc 4.0, -lgfortran # should be replaced by -lg2c. # # 4. An alternative set of flags for use with the ATLAS BLAS, gcc 4.2, and # OpenMP on a linux system. # # LIBS=-L../lib -lsdp -llapack -lptf77blas -lptcblas -latlas -lgomp -lrt -lpthread -lgfortran -lm # # # 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.1.1/matlab/0000755000076700007670000000000011357550346010617 5ustar Csdp-6.1.1/matlab/convertf.m0000644000076700007670000000263510455242355012625 0ustar % % [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.1.1/matlab/README0000644000076700007670000000245010455242355011474 0ustar This 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.1.1/matlab/writesol.m0000644000076700007670000000672311302070472012640 0ustar % % 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 ',-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',[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',[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',[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',[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.1.1/matlab/control1.correct0000644000076700007670000000474010455242355013744 0ustar >> 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.1.1/matlab/control1.mat0000644000076700007670000002044010455242355013057 0ustar MATLAB 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.1.1/matlab/readsol.m0000644000076700007670000000720011041527727012422 0ustar % % [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.1.1/matlab/csdp.m0000644000076700007670000001307511316556767011744 0ustar % % [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',0); 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; y=NaN; z=NaN; 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.1.1/matlab/writesdpa.m0000644000076700007670000001645610455242355013007 0ustar % 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 SDPpack 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',[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',[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',[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',[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.1.1/matlab/readsdpa.m0000644000076700007670000000576610650226762012573 0ustar % % [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), fprintf('file does not exist!\n'); return; 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,count]=fscanf(fid,'%d %d %d %d %le',[5,inf]); count=count/5; [entriesm,entriesn]=size(entries); for i=1:entriesn, if (entries(1,i)==0), block=entries(2,i); if (blocktypes(block)==1) % % LP data. % c(1,blockbases(block)+entries(3,i)-1)=entries(5,i); else % % SDP block entry % 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; else % % Constraint entry. % block=entries(2,i); constraint=entries(1,i); if (blocktypes(block)==1) % % LP data. % At(blockbases(block)+entries(3,i)-1,constraint)=entries(5,i); else % % SDP block entry % 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; % % 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.1.1/test/0000755000076700007670000000000011357550346010336 5ustar Csdp-6.1.1/test/Makefile0000644000076700007670000000134110455242355011771 0ustar # # 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.1.1/test/theta1.dat-s0000644000076700007670000015055110455242355012461 0ustar 104 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.1.1/test/g500000644000076700007670000000126610455242355010655 0ustar 50 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.1.1/test/theta1.correct0000644000076700007670000000270710455242355013111 0ustar 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.50e-18 Relative dual infeasibility: 3.93e-09 Real Relative Gap: 7.21e-09 XZ Relative Gap: 7.82e-09 DIMACS error measures: 1.50e-18 0.00e+00 1.00e-07 0.00e+00 7.21e-09 7.82e-09 Csdp-6.1.1/test/g50.correct0000644000076700007670000000301210455242355012304 0ustar Graph 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: 2.78e-16 Relative dual infeasibility: 7.34e-09 Real Relative Gap: 4.13e-09 XZ Relative Gap: 5.26e-09 DIMACS error measures: 2.78e-16 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.1.1/Makefile0000644000076700007670000000150710522714256011015 0ustar # # This Makefile can be used to automatically build the entire package. # # If you make changes in the "Makefile" under any subdirectory, you can # rebuild the system with "make clean" followed by "make all". # # # Generic. 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.1.1/theta/0000755000076700007670000000000011357550346010464 5ustar Csdp-6.1.1/theta/README0000644000076700007670000000256610455242355011351 0ustar This 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.1.1/theta/graphtoprob.c0000644000076700007670000001074210455242355013157 0ustar /* 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 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)); #ifdef NOSHORTS constraints[1].blocks->iindices=(int *) malloc((n+1)*sizeof(int)); constraints[1].blocks->jindices=(int *) malloc((n+1)*sizeof(int)); #else constraints[1].blocks->iindices=(unsigned short *) malloc((n+1)*sizeof(unsigned short)); constraints[1].blocks->jindices=(unsigned short *) malloc((n+1)*sizeof(unsigned short)); #endif 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)); #ifdef NOSHORTS constraints[i].blocks->iindices=(int *) malloc((2)*sizeof(int)); constraints[i].blocks->jindices=(int *) malloc((2)*sizeof(int)); #else constraints[i].blocks->iindices=(unsigned short *) malloc((2)*sizeof(unsigned short)); constraints[i].blocks->jindices=(unsigned short *) malloc((2)*sizeof(unsigned short)); #endif 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.1.1/theta/theta.c0000644000076700007670000001113110455242355011726 0ustar /* 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)); #ifdef NOSHORTS constraints[1].blocks->iindices=(int *) malloc((n+1)*sizeof(int)); constraints[1].blocks->jindices=(int *) malloc((n+1)*sizeof(int)); #else constraints[1].blocks->iindices=(unsigned short *) malloc((n+1)*sizeof(unsigned short)); constraints[1].blocks->jindices=(unsigned short *) malloc((n+1)*sizeof(unsigned short)); #endif 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)); #ifdef NOSHORTS constraints[i].blocks->iindices=(int *) malloc((2)*sizeof(int)); constraints[i].blocks->jindices=(int *) malloc((2)*sizeof(int)); #else constraints[i].blocks->iindices=(unsigned short *) malloc((2)*sizeof(unsigned short)); constraints[i].blocks->jindices=(unsigned short *) malloc((2)*sizeof(unsigned short)); #endif 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.1.1/theta/Makefile0000644000076700007670000001333011316561142012113 0ustar # # Uncomment this line to specify the C compiler if the system default isn't # what you want to use. # #CC=cc # # Use this line to specify options for the C compiler. You'll probably # want to turn on optimizations. You may also have to use some of the # following flags: # # -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. # -DBIT64 For I32LP64 systems. # -DNOSHORTS Allow for (LP) blocks of more than 65535 variables. # -DUSEOPENMP To turn on OpenMP parallelization # -DSETNUMTHREADS To use with an OpenMP aware BLAS library. # # The default settings for gcc: # CFLAGS=-O3 -ansi -Wall -DNOSHORTS -I../include # # Notes on CFLAGS. # # 1. The -DNOSHORTS flag should always be used. When this is turned off, # it causes the code to use unsigned short integers (maximum value 65535) # in the data structures that describe the problem. This can cause problems # when some of the size parameters are larger than 65535. # # 2. By default, we assume that BLAS routines have names like ddot_(), # but some systems use ddot(), DDOT(), or DDOT_() instead. A similar issue # effects the LAPACK routines. The flags -DCAPSBLAS, -DCAPSLAPACK, # -DNOUNDERBLAS. and -DNOUNDERLAPACK are used to handle such situations. # # 3. The code can be built on 64 bit systems that use an I32LP64 model # in which int's are 32 bits, long's and pointers are 64 bits. Note that # that is the model on all 64 bit Linux and Unix systems that I'm aware of, # but it is not the model used by MS in its 64 bit Windows! To build a # 64 bit version of the code, use -DBIT64. You may also need to add a CFLAG # to tell your compiler to produce 64 bit code. For example, with gcc, # you'll need to add "-m64" to CFLAGS to produce 64 bit code. # # 4. If you have multiple CPU's, and if your compiler supports OpenMP, then # you should definitely build a parallel version of CSDP. To do this, # add "-DUSEOPENMP" to CFLAGS. If your BLAS/LAPACK library routines # use OpenMP's conventions for setting the number of threads to use, then # you should also add "-DSETNUMTHREADS". Note that ATLAS does not # currently work with "-DSETNUMTHREADS", but you can use SETNUMTHREADS # on Solaris with -lsunperf and AIX systems with -lesslsmp. # 5. Using gcc, you can greatly improve the efficency of the code if you # specify your processor type. Examples are given below, use the default # if you are unsure. More examples may be found at # # http://gcc.gnu.org/onlinedocs/gcc/i386-and-x86_002d64-Options.html # # An AMD Athlon XP based machine: # CFLAGS=-march=athlon-xp -O3 -ansi -Wall -DNOSHORTS -I../include # An Intel Pentum 4 based amchine: # CFLAGS=-march=pentum4 -O3 -ansi -Wall -DNOSHORTS -I../include # # 5. If you change the CFLAGS, make sure that you use the same CFLAGS # in the Makefiles in the solver and theta directories! # # The code depends on several libraries: # # sdp The CSDP subroutine library # lapack The LAPACK linear algebra library # blas The BLAS basic linear algebra library # # In addition, if you're using gcc to compile the C code, then you'll need: # # gfortran The gnu C/Fortran 77 compatibility library (called g2c # in versions of gcc before gcc 4.0.) # m The C math run time library. # # Use this line to specify where the SDP and linear algebra libraries are # to be found. # # -L../lib look in the ../lib directory # -lsdp get libsdp.a from the ../lib directory # -llapack get liblapack.a or liblapack.so # -lblas get libblas.a or libblas.so # -lgfortran get libgfortran.a or libgfortran.so # -lm get libm.a or libm.so # # The default settings for a Linux system with gcc3, lapack, blas, and g2c: # LIBS=-L../lib -lsdp -llapack -lblas -lgfortran -lm # # 1. Warning about debian systems. For some absurb reason, the BLAS # package in debian has the BLAS library named libblas-3.a, rather than # libblas.a. You can either modify the LIBS= line, or you can create # a symbolic link from /usr/lib/libblas.a to /usr/lib/libblas-3.a. # # 2. An alternative set of flags for use with the ATLAS BLAS on a Linux system. # # LIBS=-L../lib -lsdp -llapack -lf77blas -lcblas -latlas -lgfortran -lm # # 3. Special note on gcc 3. For gcc versions before gcc 4.0, -lgfortran # should be replaced by -lg2c. # # 4. An alternative set of flags for use with the ATLAS BLAS, gcc 4.2, and # OpenMP on a linux system. # # # LIBS=-L../lib -lsdp -llapack -lptf77blas -lptcblas -latlas -lgomp -lrt -lpthread -lgfortran -lm # # 5. An alternative set of flags for use with Intel's icc and MKL. # # CC=icc # CFLAGS=-O3 -m64 -openmp -DBIT64 -DUSEOPENMP -DNOSHORTS -DSETNUMTHREADS # -I../include # LIBS=-openmp -L../lib -lsdp -mkl -lm # # 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.1.1/theta/complement.c0000644000076700007670000000305110455242355012766 0ustar /* 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; /* * 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. */ fscanf(fidin,"%d",&n); 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++) { fscanf(fidin,"%d %d",&start,&finish); 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.1.1/theta/rand_graph.c0000644000076700007670000000426510455242355012740 0ustar /* 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.1.1/include/0000755000076700007670000000000011357550346011002 5ustar Csdp-6.1.1/include/parameters.h0000644000076700007670000000123410522313034013276 0ustar /* 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.1.1/include/declarations.h0000644000076700007670000001751711305556007013627 0ustar /* * 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); 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.1.1/include/blockmat.h0000644000076700007670000000315410470246165012746 0ustar /* 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; #ifndef NOSHORTS unsigned short blocksize; #else int blocksize; #endif }; /* 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; #ifndef NOSHORTS unsigned short *iindices; unsigned short *jindices; int numentries; unsigned short blocknum; unsigned short blocksize; unsigned short constraintnum; unsigned short issparse; #else int *iindices; int *jindices; int numentries; int blocknum; int blocksize; int constraintnum; int issparse; #endif }; /* * A constraint matrix is just an array of pointers to linked lists of * the constraint blocks. */ struct constraintmatrix { struct sparseblock *blocks; }; Csdp-6.1.1/include/index.h0000644000076700007670000000151210470246165012255 0ustar /* 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.1.1/AUTHORS0000644000076700007670000000054610522714256010427 0ustar Main 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.1.1/solver/0000755000076700007670000000000011357550347010672 5ustar Csdp-6.1.1/solver/Makefile0000644000076700007670000001274511320742640012330 0ustar # # Uncomment this line to specify the C compiler if the system default isn't # what you want to use. # #CC=cc # # Use this line to specify options for the C compiler. You'll probably # want to turn on optimizations. You may also have to use some of the # following flags: # # -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. # -DBIT64 For I32LP64 systems. # -DNOSHORTS Allow for (LP) blocks of more than 65535 variables. # -DUSEOPENMP To turn on OpenMP parallelization # -DSETNUMTHREADS To use with an OpenMP aware BLAS library. # -DUSEGETTIME Use ANSI C gettime() routine to determine clock # time used in different parts of the code. # # The default settings for gcc: # CFLAGS=-O3 -ansi -Wall -DNOSHORTS -DUSEGETTIME -I../include # # Notes on CFLAGS. # # 1. The -DNOSHORTS flag should always be used. When this is turned off, # it causes the code to use unsigned short integers (maximum value 65535) # in the data structures that describe the problem. This can cause problems # when some of the size parameters are larger than 65535. # # 2. -DUSEGETTIME is generally useful. However, this functionality isn't # available under Windows/MSYS/MINGW, so you should remove it when compiling # for that system. # # 3. By default, we assume that BLAS routines have names like ddot_(), # but some systems use ddot(), DDOT(), or DDOT_() instead. A similar issue # effects the LAPACK routines. The flags -DCAPSBLAS, -DCAPSLAPACK, # -DNOUNDERBLAS. and -DNOUNDERLAPACK are used to handle such situations. # # 4. The code can be built on 64 bit systems that use an I32LP64 model # in which int's are 32 bits, long's and pointers are 64 bits. Note that # that is the model on all 64 bit Linux and Unix systems that I'm aware of, # but it is not the model used by MS in its 64 bit Windows! To build a # 64 bit version of the code, use -DBIT64. You may also need to add a CFLAG # to tell your compiler to produce 64 bit code. For example, with gcc, # you'll need to add "-m64" to CFLAGS to produce 64 bit code. # # 5. If you have multiple CPU's, and if your compiler supports OpenMP, then # you should definitely build a parallel version of CSDP. To do this, # add "-DUSEOPENMP" to CFLAGS. If your BLAS/LAPACK library routines # use OpenMP's conventions for setting the number of threads to use, then # you should also add "-DSETNUMTHREADS". Note that ATLAS does not # currently work with "-DSETNUMTHREADS", but you can use SETNUMTHREADS # on Solaris with -lsunperf and AIX systems with -lesslsmp. # # 6. Using gcc, you can greatly improve the efficency of the code if you # specify your processor type. Examples are given below, use the default # if you are unsure. More examples may be found at # # http://gcc.gnu.org/onlinedocs/gcc/i386-and-x86_002d64-Options.html # # An AMD Athlon XP based machine: # CFLAGS=-march=athlon-xp -O3 -ansi -Wall -DNOSHORTS -I../include # An Intel Pentum 4 based amchine: # CFLAGS=-march=pentum4 -O3 -ansi -Wall -DNOSHORTS -I../include # # 7. If you change the CFLAGS, make sure that you use the same CFLAGS # in the Makefiles in the solver and theta directories! # # The code depends on several libraries: # # sdp The CSDP subroutine library # lapack The LAPACK linear algebra library # blas The BLAS basic linear algebra library # # In addition, if you're using gcc to compile the C code, then you'll need: # # gfortran The gnu C/Fortran 77 compatibility library (called # g2c in versions of gcc before gcc 4.0.) # m The C math run time library. # # Use this line to specify where the SDP and linear algebra libraries are # to be found. # # -L../lib look in the ../lib directory # -lsdp get libsdp.a from the ../lib directory # -llapack get liblapack.a or liblapack.so # -lblas get libblas.a or libblas.so # -lgfortran get libgfortran.a or libgfortran.so # -lm get libm.a or libm.so # # The default settings for a Linux system with gcc3, lapack, blas, and # gfortran: # LIBS=-L../lib -lsdp -llapack -lblas -lgfortran -lm # # 1. Warning about debian systems. For some absurb reason, the BLAS # package in debian has the BLAS library named libblas-3.a, rather than # libblas.a. You can either modify the LIBS= line, or you can create # a symbolic link from /usr/lib/libblas.a to /usr/lib/libblas-3.a. # # 2. An alternative set of flags for use with the ATLAS BLAS on a Linux system. # # LIBS=-L../lib -lsdp -llapack -lf77blas -lcblas -latlas -lgfortran -lm # # 3. Special note on gcc 4. In versions of gcc before gcc 4.0, use -lg2c # instead of -lgfortran. # # 4. An alternative set of flags for use with the ATLAS BLAS, gcc 4.2, and # OpenMP on a linux system. # # LIBS=-L../lib -lsdp -llapack -lptf77blas -lptcblas -latlas -lgomp -lrt -lpthread -lgfortran -lm # # 5. An alternative set of flags for use with Intel's icc 11.0 and MKL. # # CC=icc # CFLAGS=-O3 -m64 -openmp -DBIT64 -DUSEOPENMP -DNOSHORTS -DSETNUMTHREADS # -I../include # LIBS=-openmp -L../lib -lsdp -mkl -lm # # 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.1.1/solver/csdp.c0000644000076700007670000000431511357476323011773 0ustar #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.1.1\n"); printf(" \n"); printf("Usage: \n"); printf("\n"); printf("csdp [] []\n"); exit(1); }; /* * First, read the problem in. */ ret=read_prob(argv[1],&n,&k,&C,&a,&constraints,1); if (ret != 0) { printf("Giving up.\n"); exit(10); }; if (argc == 4) { ret=read_sol(argv[3],n,k,C,&X,&y,&Z); if (ret != 0) { printf("Giving up.\n"); exit(10); }; } 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); }