%%*****************************************************************
%% validate: validate data
%%*****************************************************************
%% SDPT3: version 4.0
%% Copyright (c) 1997 by
%% Kim-Chuan Toh, Michael J. Todd, Reha H. Tutuncu
%% Last Modified: 16 Sep 2004
%%*****************************************************************

   function  [blk,At,C,b,dim,nnblk,parbarrier] = ...
              validate(blk,At,C,b,par,parbarrier)

   if (nargin >= 5)
      spdensity = par.spdensity; 
   else
      spdensity = 0.4; 
   end
%%
   if ~iscell(blk); 
      error('validate: blk must be a cell array'); end; 
   if (size(blk,2) < 2)
      error('validate: blk must be a cell array with at least 2 columns');
   end 
   if ~iscell(At) | ~iscell(C); 
      error('validate: At, C must be cell arrays'); 
   end
   if (size(At,1) ~= size(blk,1)) 
      if (size(At,2) == size(blk,1)); 
         At = At'; 
      else      
         error('validate: size of At is not compatible with blk'); 
      end
   end   
   if (size(C,1) ~= size(blk,1)) 
      if (size(C,2) == size(blk,1)) 
         C = C'; 
      else
         error('validate: size of C is not compatible with blk'); 
      end
   end   
   if (min(size(b)) > 1); error('validate: b must be a vector'); end
   if (size(b,1) < size(b,2)); b = b'; end
   m = length(b);
%%
%%-----------------------------------------
%% validate blk, At, C
%%-----------------------------------------
   ntotal = zeros(size(blk,1),1); 
   for p = 1:size(blk,1)
      if (size(blk{p,2},1) > size(blk{p,2},2)) 
         blk{p,2} = blk{p,2}';          
      end
      pblk = blk(p,:); 
      n = sum(pblk{2}); 
      numblk = length(pblk{2});
      if strcmp(pblk{1},'s');
         m1 = size(At{p,1},2); 
         n2 = sum(pblk{2}.*pblk{2});  n22 = sum(pblk{2}.*(pblk{2}+1))/2; 
         ntotal(p) = n22; 
         if ~all(size(C{p}) == n) 
            error('validate: blk and C are not compatible'); 
         end 
         if (norm(C{p}-C{p}',inf) > 1e-13*norm(C{p},inf)); 
            error('validate: C is not symmetric'); 
         end
         if (size(At{p,1}) == [m1, n22] & m1~=n22); 
            At{p,1} = At{p,1}'; 
         end
         if (~isempty(At{p,1})) & (size(At{p,1},1) ~= n22)
            error('validate: blk and At not compatible'); 
         end 
         if (nnz(At{p,1}) < spdensity*n22*m1) || (n <= 20) %%2nd condition: 2017-May-08
            if ~issparse(At{p,1}); At{p,1} = sparse(At{p,1}); end 
         else
            if issparse(At{p,1}); At{p,1} = full(At{p,1}); end
         end                 
         if (length(pblk) > 2) %% for low rank constraints
            len = sum(pblk{3});
            if (size(pblk{1,3},2) < size(pblk{1,3},1))
                blk{p,3} = blk{p,3}'; 
            end
            if any(size(At{p,2})- [n,len])
               error(' low rank structure specified in blk and At not compatible') 
            end
            if (length(At(p,:)) > 2)  & ~isempty(At{p,3})
               if all(size(At{p,3},2)-[1,4])
                  error(' low rank structure in At{p,3} not specified correctly')
               end
               if (size(At{p,3},2) == 1)
                  if (size(At{p,3},1) < size(At{p,3},2)); At{p,3} = At{p,3}'; end
                  lenn = length(At{p,3});
                  constrnum = mexexpand(pblk{3},[1:length(pblk{3})]');
                  At{p,3} = [constrnum, [1:lenn]', [1:lenn]', At{p,3}];
               elseif (size(At{p,3},2) == 4)
                  dd = At{p,3};
                  [dummy,idxsort] = sort(dd(:,1)); 
                  dd = dd(idxsort,:); 
                  lenn = size(dd,1);
                  idxD = [0; find(diff(dd(:,1))); lenn];
                  ii = zeros(lenn,1); jj = zeros(lenn,1);
                  ss = [0,cumsum(pblk{3})];
                  for k = 1:length(pblk{3})
                     idx = [idxD(k)+1 : idxD(k+1)];
                     ii(idx) = dd(idx,2)+ss(k); %% convert to cumulative indexing
                     jj(idx) = dd(idx,3)+ss(k);
                  end
                  At{p,3} = [dd(:,1),ii,jj,dd(:,4)];
               end
            else
               constrnum = mexexpand(pblk{3},[1:length(pblk{3})]');
               At{p,3} = [constrnum,  [1:len]', [1:len]', ones(len,1)];   
            end
         end
         if (nnz(C{p}) < spdensity*n2) | (numblk > 1); 
            if ~issparse(C{p}); C{p} = sparse(C{p}); end;
         else
            if issparse(C{p}); C{p} = full(C{p}); end; %%added: 2017-May-08
         end
      elseif strcmp(pblk{1},'q') | strcmp(pblk{1},'l') ...
             | strcmp(pblk{1},'u'); 
         ntotal(p) = n; 
         if (min(size(C{p})) ~= 1 | max(size(C{p})) ~= n); 
            error(['validate: blk and C are not compatible']); 
         end; 
         if (size(C{p},1) < size(C{p},2)); C{p} = C{p}'; end
         if (size(At{p,1}) == [m, n] & m~=n); 
            At{p,1} = At{p,1}'; 
         end
         if ~all(size(At{p,1}) == [n,m]);
            error('validate: blk and At not compatible'); 
         end
         if ~issparse(At{p,1}); 
            At{p,1} = sparse(At{p,1}); 
         end 
         if (nnz(C{p}) < spdensity*n); 
            if ~issparse(C{p}); C{p} = sparse(C{p}); end; 
         else
            if issparse(C{p}); C{p} = full(C{p}); end;
         end;
      else
         error(' blk: some fields are not specified correctly'); 
      end
   end
   if (sum(ntotal) < m) 
      error(' total dimension of C should be > length(b)'); 
   end
%%
%%-----------------------------------------
%% problem dimension
%%-----------------------------------------
%%
   dim = zeros(1,4);  nnblk = zeros(1,2);  
   for p = 1:size(blk,1)
      pblk = blk(p,:);
      if strcmp(pblk{1},'s')
         dim(1) = dim(1) + sum(pblk{2}); 
         nnblk(1) = nnblk(1) + length(pblk{2});
         nn(p) = sum(pblk{2}); 
      elseif strcmp(pblk{1},'q')
         dim(2) = dim(2) + sum(pblk{2}); 
         nnblk(2) = nnblk(2) + length(pblk{2});
         nn(p) = length(pblk{2}); 
      elseif strcmp(pblk{1},'l')
         dim(3) = dim(3) + sum(pblk{2}); 
         nn(p) = sum(pblk{2}); 
      elseif strcmp(pblk{1},'u')
         dim(4) = dim(4) + sum(pblk{2}); 
         nn(p) = sum(pblk{2}); 
      end
   end
%%
%%-----------------------------------------
%% validate parbarrier
%%-----------------------------------------
%% 
    if (nargin == 6)
       if ~iscell(parbarrier); 
	  if (length(parbarrier) == size(blk,1))
	     tmp = parbarrier; 
             clear parbarrier;
	     parbarrier = cell(size(blk,1),1);
	     for p = 1:size(blk,1)
		parbarrier{p} = tmp(p);    
             end
          end
       end 
       if (size(parbarrier,2) > size(parbarrier,1))
          parbarrier = parbarrier'; 
       end
       for p = 1:size(blk,1)
          pblk = blk(p,:); 
          if (size(parbarrier{p},1) > size(parbarrier{p},2))
             parbarrier{p} = parbarrier{p}'; 
          end
          len = length(parbarrier{p}); 
          if strcmp(pblk{1},'s') | strcmp(pblk{1},'q')
             if (len == 1)
                parbarrier{p} = parbarrier{p}*ones(1,length(pblk{2})); 
	     elseif (len == 0)
                parbarrier{p} = zeros(1,length(pblk{2})); 
	     elseif (len ~= length(pblk{2}))
                error('blk and parbarrier not compatible');
             end
          elseif strcmp(pblk{1},'l')
             if (len == 1)
                parbarrier{p} = parbarrier{p}*ones(1,sum(pblk{2})); 
	     elseif (len == 0)
		parbarrier{p} = zeros(1,sum(pblk{2})); 
             elseif (len ~= sum(pblk{2}))
                error('blk and parbarrier not compatible');            
             end
          elseif strcmp(pblk{1},'u')
             parbarrier{p}= zeros(1,sum(pblk{2})); 
          end 
       end
    end
%%***********************************************************************
