Home > utilities > readsdpa.m

# readsdpa

## PURPOSE

READSDPA - Read a linear SDP problem from a Sparse SDPA file

## SYNOPSIS

function sdpdata = readsdpa(filename);

## DESCRIPTION

     READSDPA - Read a linear SDP problem from a Sparse SDPA file
      separate the linear constraint matrix, return
     the problem in the following structure:

     Elements of the structure
       name ... filename of the input file
       Nx ..... number of primal variables
       Na ..... number of linear matrix inequalities (or diagonal blocks of the
                matrix constraint)
       Ng ..... number of linear inequalitites
       B ...... matrix defining the linear inequality constraints Bx<=d
                dimension Ng x Nx
       d ...... rhs for linear constraints
       c ...... dim (Nx,1), coefficients of the linear objective function
       NaDims . vector of sizes of matrix constraints (diagonal blocks)
       A ...... cell array (matrix) of A{k,l} for k=1,...,Na matrix constraint
                for l=1 ~ absolute term, l=2..Nx+1 coeficient matrices
                (some of them might be empty)
       Adep ... dependency list for each matrix constraint

     See also sdp_define, pen2bmi

## CROSS-REFERENCE INFORMATION

This function calls:

This function is called by:

- alselftest ALSELFTEST is a self test of evaluation of the Augmented Lagrangian and its
- penlabtestfeeder PENLABTESTFEEDER sets up one test to be run at a time.
- sdpastats SDPASTATS gets some statistics (& vision) how the given SDPA problem looks

## SOURCE CODE

    0001 function sdpdata = readsdpa(filename);
    0002 % READSDPA - Read a linear SDP problem from a Sparse SDPA file
    0003 %  separate the linear constraint matrix, return
    0004 % the problem in the following structure:
    0005 %
    0006 % Elements of the structure
    0007 %   name ... filename of the input file
    0008 %   Nx ..... number of primal variables
    0009 %   Na ..... number of linear matrix inequalities (or diagonal blocks of the
    0010 %            matrix constraint)
    0011 %   Ng ..... number of linear inequalitites
    0012 %   B ...... matrix defining the linear inequality constraints Bx<=d
    0013 %            dimension Ng x Nx
    0014 %   d ...... rhs for linear constraints
    0015 %   c ...... dim (Nx,1), coefficients of the linear objective function
    0016 %   NaDims . vector of sizes of matrix constraints (diagonal blocks)
    0017 %   A ...... cell array (matrix) of A{k,l} for k=1,...,Na matrix constraint
    0018 %            for l=1 ~ absolute term, l=2..Nx+1 coeficient matrices
    0019 %            (some of them might be empty)
    0020 %   Adep ... dependency list for each matrix constraint
    0021 %
    0022 % See also sdp_define, pen2bmi
    0023
    0024 % This file is a part of PENLAB package distributed under GPLv3 license
    0025 % Copyright (c) 2013 by  J. Fiala, M. Kocvara, M. Stingl
    0026 % Last Modified: 4 Dec 2013
    0027
    0028   sdpdata=[];
    0029
    0030   % open file
    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       % end of file
    0050       break;
    0051     end
    0052     %fprintf('line %d: >>%s<<\n',nline,line);
    0053
    0054     % skip comments or empty lines
    0055     if (isempty(line) || line(1)=='*' || line(1) =='"')
    0056       continue;
    0057     end
    0058
    0059     switch (phase)
    0060     case 0
    0061       % expecting number of variables
    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       %nx
    0070
    0071     case 1
    0072       % expecting number of matrix constraints (=blocks)
    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       %nblocks
    0081
    0082     case 2
    0083       % expecting block sizes which might be separated by foreign
    0084       % characters such as {,},(,),... Add space at the beginning
    0085       % of the line in case there is nothing
    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       %msizes
    0094
    0095     case 3
    0096       % expecting the objective vector perhaps mixed with some garbage
    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       %c
    0103
    0104     case 4
    0105       % expecting a data line
    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       %alldata(:,1:nentries)
    0117
    0118     end
    0119
    0120   end
    0121
    0122   % close file
    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   % remove empty entries
    0130   alldata=alldata(:,1:nentries);
    0131
    0132   % check the correctness of the data lines
    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   % extract the linear constraints
    0141   % turn 1-size matrix blocks into linear constraints
    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   % accummulate data into B matrix
    0148   B=sparse([],[],[],nx,nlin,nnzlin);
    0149   d=zeros(nlin,1);
    0150   ng=0;    % no of the constraint written so far
    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     % extract RHS
    0160     idx=find(thisblock(1,:)==0);
    0161     if (~isempty(idx))
    0162       d(ng+thisblock(3,idx))=thisblock(5,idx);
    0163     end
    0164     % extract linear constraints bodies
    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   %d
    0172   %spy(B)
    0173
    0174   % extract matrix constraints
    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     % if i>j --> lower triangle which is not allowed
    0187     if (any(thisblock(3,:)>thisblock(4,:)))
    0188       error(sprintf('Block %d have elements outside upper triangle.',iblk));
    0189     end
    0190     % extract each of the matrices in this block
    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   % put everything together into one structure
    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 %  if 0
    0215
    0216
    0217 % create dependency table, Adep(k) = vector of all x indices which Ak depends on
    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