function [flag,resids,time1,density]...
                   = RcompleteZ(params,opts,problem)
%        [flag,resids,rank1,rank2,realNoise,time1,time2,density,rn]...
%                  = RcompleteZ(params,opts,problem)
start_time = cputime;
%profile clear
%profile on
flag = 0; %%  -- solved  ???? fix???? when flag = 1????
r=params.r;   % target rank
verbose=opts.verbose;
%noiselvl = params.noiselevel;
densityS=opts.densityS;   
iterlimit = opts.palmlimit;
% flag == 0 -- solved
% flag == 1 -- not solved
%%% Jan1/17
%%% Henry on Jan1/17:  remove noise wts for zero noise problems
%%% noiseless problems means that we are dividing eps/eps
%%% use singular vectors and not eigenvectors  ???????????
%[Zorig,Zpart,indsZ,realNoise]= ZgeneratorNew(params);

%%%%%%%%%%%%%%Initialize data ... fix params/opts why TWO ??????
%sqrt2=sqrt(2);
tolerrank=params.tolerrank;
%Zorig=problem.Zorig;  % complete matrix with all elements
Lorig=problem.Lorig;  % complete low rank matrix with all elements
Sorig=problem.Sorig;  % complete sparse matrix with all elements
Zpart=problem.Zpart;  % sampled part of Zorig
indsZ=problem.indsZ;  % indices for sampled part in Z
[m,n]=size(Lorig);
%Imn=eye(m+n);
%Ztemp = spalloc(m,n,length(indsZ));
Ztemp = false(m,n);
Ztemp(indsZ) = 1;
ZClique = false(m,n); % used for indicators for sampled bicliques;
ZsClique = false(m,n); % used for indicators for sampled bicliques;
LClique = zeros(m,n); % data for the low rank part 
%Yfinal=sparse(m+n,m+n);  % preallocate for Yfinal
YTexp = sparse(m,m);
YSexp = sparse(n,n);
%realNoise=problem.realNoise; %????scalar????matrix????? does what????
density=length(indsZ)/(m*n);
%minsize   = opts.minsize;  % biclique minsize
maxsize   = opts.maxsize;  % biclique maxsize
minclique = params.minclique;
minsize = 2*minclique;
orig = opts.orig;   % flag 0,1 for using recovered biclique or 'cheat',resp.
%tolrankp = opts.tolrankp;  % for computing rank of exposing vector
%tolrankq = opts.tolrankq;  % for computing rank of exposing vector
if ~exist('tolerrank','var')   % tolerance for small biclique found
    tolerrank =  max(m,n)*eps(normest(Zpart)); 
end

kk = 0;
Lappr = [];
nnzero = 0;
  fprintf('\n\nNew problem with:  m,n seed %i  %i %i\n',m,n,params.seed);  
while (size(Lappr,1)< m || size(Lappr,2)<n) && kk < 10 && flag == 0
   
    kk = kk + 1;
    y = {};
    startgrow=tic;
      nopermuc = 1:n;
    nopermur = 1:m;
     A=[(true(m))   Ztemp
         Ztemp'     (true(n))];  
     Imn = eye(m+n);
    A(Imn==1)=0; 
     y=GrowCliques(A,maxsize,minsize,nopermur,nopermuc,m,n);
      %y=[y;yt];
    %%%% forming adjacency matrix A %%%%    
    if kk == 1
    itergrow = opts.itergrow;
    else
        itergrow = 0;
    end
   % for ii = 1:itergrow
     
   % perrow = randperm(m);
    
   % percind = randperm(n);
  
   %cols = [m+1:m+n];
   %percol = cols(percind);
   % perm = [perrow,percol];
   % Ztemps = Ztemp(perrow,percind);
     %Ztemps = Ztemp(perrow,:);
   % As=[(true(m))   Ztemps
   %     Ztemps'     (true(n))];  
   %  Imn = eye(m+n);
   % As(Imn==1)=0;  % set diag to 0
   % As = [speye(m)   sparse(1 - Ztemp)
    %      sparse(1 - Ztemp') speye(n)];
   
  %   keyboard;
    %%%%%%%%%%%%%%%
    
    
    %y1=GrowCliques(A,maxsize,minsize);
    %  ys=GrowCliques(As,maxsize,minsize,perrow,percind,m,n);
    %   y = [y;ys];
       
    % end
 clear A As
    %keyboard;
  
   %  erry = 0;
    % for i = 1:length(y)
     %  erry = norm(y{i} - y1{i}) + erry;
     %end
   % keyboard
    % y = y(1:min(2000,size(y,1))); % only use part of the bicliques
    %y = y(1:min(400,size(y,1))); 
    numCliques = length(y);
    fprintf('Time for finding %i bicliques   %g \n',...
                    numCliques,toc(startgrow))
    TExpcol = cell(1,numCliques);
    TExprow = cell(1,numCliques);
    TExpval = cell(1,numCliques);
    SExpcol = cell(1,numCliques);
    SExprow = cell(1,numCliques);
    SExpval = cell(1,numCliques);
    %%%% memory allocation %%%%
  
    successS = 0; % sparse exposing vector
    maxc = 0;                       % maxsize of the bicliques
    %ZClique = false(m,n); % used for indicators for sampled bicliques;
    %LClique = sparse(m,n); % data for the low rank part 
    startexpo=tic;
    numsucclow = 0; % number of bicliques where all low rank comp. found
    for ii=1:numCliques     
        indsY=y{ii};
        rowsi=indsY<=m;
        rowsi=indsY(rowsi);
        colsj=indsY>m;
        colsj=indsY(colsj)-m;
        lr=length(rowsi);
        lc=length(colsj);
  if   min(lr,lc)>=minclique% large enough biclique
          lowranksucc = false;
          X=full(Zpart(rowsi,colsj));
	      %SXorig = Sorig(rowsi,colsj);
          LXorig = Lorig(rowsi,colsj);
          if rank(X,tolerrank) == r
              L1 = X;
              [uXtemp,tempsvd,vXtemp]=svd(L1);
              lowranksucc = true;
          else
%%%%use output from Shiqian code here to find L_X
           sk = 1/(lr*lc);
           skmax = max(densityS,sk);
           dsk =  1/(lr*lc);
    while  sk <= skmax + 0.000001&& lowranksucc == false
           %tol = lr*lc*noiselvl;
         %  tol = 1e-12;
            start_PALM=tic;
            [L1,~] = PALM(X,X,0,r,sk,opts.tolpalm,iterlimit,opts);
	     if  verbose
             time3=toc(start_PALM);
             fprintf('time for file PALM is %g\n',time3)
         end
       %S1 = round(S0);
       %S1 = S0;
      
       L1 = round(L1);
        [uXtemp,tempsvd,vXtemp]=svd(L1);
%        tempsvd=svd(L1);
%       tempsvd
       if abs(tempsvd(r+1,r+1))<10*opts.tolpalm
%        if verbose
%             fprintf('low rank component recovered \n')
%        end
       numsucclow= numsucclow + 1;
       lowranksucc = true;
       end
       sk = sk+ dsk;  % increase sparsity when failure
  
    end   % for the while loop sk = ...
          end
         if (lowranksucc)
            %L1 = L1;
            if (norm(L1-LXorig)> 1e-12)
              fprintf('Original matrix not recovered ,error is %g\n',norm(L1-LXorig));
              
              if(orig ==1)
              L1 = LXorig;
              end
           %  keyboard;
            end
           % [~,sX,~]=svd(L1);
            diagsX=diag(tempsvd);
            rankX = find(diagsX >= tolerrank*diagsX(1), 1, 'last');
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
          if rankX < r  % should never happen generically
               fprintf('rankX < r\n');
          %     keyboard
          else  
               
                successS = successS + 1; 
        % finding the largest biclique size 
                maxc = max(maxc,lr+lc);
            % finding row exposing vector
            %     successr=successr+1;  %for testing
                %[uXtemp,~,vXtemp]=svd(L1);
                  temp=uXtemp(:,r+1:lr)*uXtemp(:,r+1:lr)';
	              %temp=(temp+temp')/2;         %no need anymore
  	           %   Yfinal(rowsi,rowsi)= Yfinal(rowsi,rowsi) + temp;    
                  TExpcol{successS} = kron(ones(lr,1),rowsi)';
                  TExprow{successS} = kron(rowsi,ones(lr,1))';
                  TExpval{successS} = temp(:)';
                 % finding col exposing vector
  	       % successc=successc+1;  %for testing    
                   temp=vXtemp(:,r+1:lc)*vXtemp(:,r+1:lc)';
	              %temp=(temp+temp')/2;         %no need anymore
  	             % Yfinal(colsj+m,colsj+m)= Yfinal(colsj+m,colsj+m) + temp;
                  SExpcol{successS} = kron(ones(lc,1),colsj)';
                  SExprow{successS} = kron(colsj,ones(lc,1))';
                  SExpval{successS} = temp(:)';
              %%%%%%%%%%%%%%%%%%% forming the matrix of elements from all
              %%%%%%%%%%%%%%%%%%% the bicliques
              ZClique(rowsi,colsj) = 1;   % indices are bicliques
              ZsClique(rowsi,colsj) = 1;  % indices are recovered
              LClique(rowsi,colsj) = L1;  % data for the biclique above
              Zpart(rowsi,colsj) = L1;
  %%%%%%%%%%%%LClique(Zclique)=Zorig(Zclique)-Sorig(Zclique)=Lorig(Zcclique);
         %%%%%%%%
          end   % end for the if: check on rankX >=r
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
         else
         end
  end
    %keyboard;
    end
    clear y
    if opts.apv == 1
    if(~isempty(Lappr)) 
        [uXtemp,~,vXtemp]=svd(round(Lappr));
                
                  tempP=uXtemp(:,r+1:end)*uXtemp(:,r+1:end)';
                  tempQ=vXtemp(:,r+1:end)*vXtemp(:,r+1:end)';
	               %no need anymore
  	            %  Yfinal(indsnzoR,indsnzoR)= Yfinal(indsnzoR,indsnzoR) + tempP;
                 % Yfinal(m+indsnzoC,m+indsnzoC)= Yfinal(m+indsnzoC,m+indsnzoC) + tempQ;
                
    end
    end
     fprintf('Time for constructing exposing vector %g \n',...
                    toc(startexpo))
    fprintf('maxc =  %i; and  %i successful  bicliques, resp.  \n',...
                        maxc,successS);
  %keyboard
  %Yfinal(abs(Yfinal)<1e-12)=0;      % change??? only needed for eigs???
   YTexp = YTexp + sparse(cell2mat(TExpcol),cell2mat(TExprow),cell2mat(TExpval),m,m);
   YTexp = (YTexp + YTexp')/2;
   YSexp = YSexp + sparse(cell2mat(SExpcol),cell2mat(SExprow),cell2mat(SExpval),n,n);
   YSexp = (YSexp + YSexp')/2;
   Yfinal = [YTexp, sparse(m,n)
             sparse(n,m) YSexp];   
  %Yfinal=(Yfinal+Yfinal')/2;
  %Yfinal=sparse(Yfinal);
  
  fprintf('density of Yfinal:  %g;  \n',nnz(Yfinal)/numel(Yfinal));
  
  %%%% checking if Yfinal has 0 on the diagonal %%%%???
   
  %  ZsClique = ZClique;
   [flag,Lappr,indsnzoR,indsnzoC]= rpcasolve(Yfinal,ZsClique,Ztemp,ZClique,LClique,Zpart,Lorig,m,n,opts,params,itergrow);
  
   Ztemp(indsnzoR,indsnzoC)=1; 
   %indsZ = find(Ztemp);
   Zpart(indsnzoR,indsnzoC) = round(Lappr);
  %  ZClique(indsnzoR,indsnzoC) = 1;   % indices for bicliques
   ZsClique(indsnzoR,indsnzoC) = 1;  % indices for recovered Lorig
   LClique(indsnzoR,indsnzoC) = round(Lappr); 
   Sorig(indsnzoR,indsnzoC) = 0;
   %Zorig(indsnzoR,indsnzoC)= round(Lappr);
   %pause(0.5)
   if (length(indsnzoR) + length(indsnzoC)-nnzero)== 0
   flag = 1;
   end
   nnzero = length(indsnzoR) + length(indsnzoC);
   %keyboard
   
   if flag ==0 
   if norm(round(Lappr)-Lorig(indsnzoR,indsnzoC),'fro') >=1
           flag = 1;
   end
   end
end               % while loop for lappr
fprintf('Finished with original size \n')
time1=cputime - start_time;
if(~isempty(Lappr))
   fprintf('Error with original matrix is %g \n', norm(round(Lappr)-Lorig(indsnzoR,indsnzoC),'fro')); 
  % Zappr=Sappr+Lappr;
   resids = norm(Lappr-Lorig(indsnzoR,indsnzoC),'fro')/norm(Lorig(indsnzoR,indsnzoC),'fro');
  % resids(2) = norm(Zappr-Zorig,'fro')/norm(Zorig,'fro');
   if size(Lappr,1)~= m || size(Lappr,2)~=n || resids > 0.0001
      flag = 1;
   end
   %profile report
   %keyboard
  else
      flag =1;
       fprintf('recovered matrix is empty \n');
      % resids = -1;
   %    resids(2) = -1;
end
  if flag == 1
      resids = -1;
 % keyboard;
  end
 
   if flag == 1
      fprintf('Recovery Failure with seed %5.0f !! \n',params.seed);
  %keyboard;
  end
  clear Lorig Lappr ZClique LClique ZsClique Yexpo

%keyboard
end    % end of function completeZ.m for exposvctr


  
