0001 function sdpdata = readsdpa(filename);
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 sdpdata=[];
0029
0030
0031 fid=fopen(filename,'r');
0032 if (fid==-1)
0033 error(sprintf('Cannot open file "%s"',filename));
0034 end
0035
0036 nline=0;
0037 phase=0;
0038 nx=0;
0039 nblocks=0;
0040 msizes=[];
0041 c=[];
0042 nentries=0;
0043 maxentries=0;
0044 alldata=[];
0045 while 1
0046 line=fgetl(fid);
0047 nline=nline+1;
0048 if (~ischar(line))
0049
0050 break;
0051 end
0052
0053
0054
0055 if (isempty(line) || line(1)=='*' || line(1) =='"')
0056 continue;
0057 end
0058
0059 switch (phase)
0060 case 0
0061
0062 [nx,count]=sscanf(line,'%d',1);
0063 if (count~=1)
0064 error(sprintf('Line %d, cannot read number of variables.',nline));
0065 elseif (nx<=0)
0066 error(sprintf('Line %d, wrong number of variables.',nline));
0067 end
0068 phase=phase+1;
0069
0070
0071 case 1
0072
0073 [nblocks,count]=sscanf(line,'%d',1);
0074 if (count~=1)
0075 error(sprintf('Line %d, cannot read number of blocks.',nline));
0076 elseif (nblocks<=0)
0077 error(sprintf('Line %d, wrong number of blocks.',nline));
0078 end
0079 phase=phase+1;
0080
0081
0082 case 2
0083
0084
0085
0086 [msizes,count]=sscanf([' ' line],'%*[^0-9+-]%d',nblocks);
0087 if (count~=nblocks)
0088 error(sprintf('Line %d, cannot read block sizes.',nline));
0089 elseif (any(msizes==0))
0090 error(sprintf('Line %d, block sizes are incorrect.',nline));
0091 end
0092 phase=phase+1;
0093
0094
0095 case 3
0096
0097 [c,count]=sscanf([' ' line],'%*[^0-9eE.+-]%lg',nx);
0098 if (count~=nx)
0099 error(sprintf('Line %d, cannot read the objective vector.',nline));
0100 end
0101 phase=phase+1;
0102
0103
0104 case 4
0105
0106 [data,count]=sscanf(line,'%i %i %i %i %lg',5);
0107 if (count~=5)
0108 error(sprintf('Line %d, cannot read the data line.',nline));
0109 end
0110 nentries=nentries+1;
0111 if (nentries>maxentries)
0112 alldata=[alldata,zeros(5,2500)];
0113 maxentries=maxentries+2500;
0114 end
0115 alldata(:,nentries)=data;
0116
0117
0118 end
0119
0120 end
0121
0122
0123 fclose(fid);
0124
0125 if (nx<=0 || nblocks<=0 || isempty(msizes) || isempty(c) || nentries<=0)
0126 error('The file seems to be incomplete.');
0127 end
0128
0129
0130 alldata=alldata(:,1:nentries);
0131
0132
0133 if (any(alldata(1,:)<0 | alldata(1,:)>nx))
0134 error('Some of the data lines have matrix_number out of range.');
0135 end
0136 if (any(alldata(2,:)<1 | alldata(2,:)>nblocks))
0137 error('Some of the data lines have block_number out of range.');
0138 end
0139
0140
0141
0142 idx=find(msizes==1);
0143 msizes(idx)=-1;
0144 linblk=find(msizes<0);
0145 nlin=sum(abs(msizes(linblk)));
0146 nnzlin=length(find(msizes(alldata(2,:))<0));
0147
0148 B=sparse([],[],[],nx,nlin,nnzlin);
0149 d=zeros(nlin,1);
0150 ng=0;
0151 for iblk=linblk'
0152 dim=-msizes(iblk);
0153 idxentries=find(alldata(2,:)==iblk);
0154 thisblock=alldata(:,idxentries);
0155 if (any(thisblock(3,:)<1 | thisblock(3,:)>dim | ...
0156 thisblock(3,:)~=thisblock(4,:)))
0157 error(sprintf('Diagonal block %d have indices nondiag. or out of range elements.',iblk));
0158 end
0159
0160 idx=find(thisblock(1,:)==0);
0161 if (~isempty(idx))
0162 d(ng+thisblock(3,idx))=thisblock(5,idx);
0163 end
0164
0165 idx=find(thisblock(1,:)>0);
0166 if (~isempty(idx))
0167 B(:,ng+1:ng+dim)=sparse(thisblock(1,idx),thisblock(3,idx),thisblock(5,idx),nx,dim);
0168 end
0169 ng=ng+dim;
0170 end
0171
0172
0173
0174
0175 matblk=find(msizes>0);
0176 na=length(matblk);
0177 A=cell(na,nx+1);
0178 for iblk=matblk'
0179 dim=msizes(iblk);
0180 idxentries=find(alldata(2,:)==iblk);
0181 thisblock=alldata(:,idxentries);
0182 if (any(thisblock(3,:)<1 | thisblock(3,:)>dim | thisblock(4,:)<1 | ...
0183 thisblock(4,:)>dim))
0184 error(sprintf('Block %d have indices not matching its dim=%d.',iblk,dim));
0185 end
0186
0187 if (any(thisblock(3,:)>thisblock(4,:)))
0188 error(sprintf('Block %d have elements outside upper triangle.',iblk));
0189 end
0190
0191 for i=0:nx
0192 idx=find(thisblock(1,:)==i);
0193 if (isempty(idx))
0194 A{iblk,i+1}=sparse(dim,dim);
0195 else
0196 M=sparse(thisblock(3,idx),thisblock(4,idx),thisblock(5,idx),dim,dim);
0197 A{iblk,i+1}=M+triu(M,1)';
0198 end
0199 end
0200 end
0201
0202
0203 sdpdata.name=filename;
0204 sdpdata.Nx=nx;
0205 sdpdata.Na=na;
0206 sdpdata.Ng=nlin;
0207 sdpdata.B=B';
0208 sdpdata.d=d;
0209 sdpdata.c=c;
0210 sdpdata.NaDims=msizes;
0211 sdpdata.A=A;
0212
0213
0214
0215
0216
0217
0218 sdpdata.Adep=cell(sdpdata.Na,1);
0219 for k=1:sdpdata.Na
0220 list=[];
0221 for i=2:nx+1
0222 if (~isempty(sdpdata.A{k,i}) && nnz(sdpdata.A{k,i})>0)
0223 list=[list,i-1];
0224 end
0225 end
0226 sdpdata.Adep{k}=list;
0227 end
0228
0229
0230 end
0231