function R = sprandn(arg1,n,density,rc)
%SPRANDN Sparse normally distributed random matrix.
%   R = SPRANDN(S) has the same sparsity structure as S, but normally
%       distributed random entries.
%
%   R = SPRANDN(m,n,density) is a random, m-by-n, sparse matrix with 
%       approximately density*m*n normally distributed nonzero entries.
%       SPRANDN is designed to produce large matrices with small density
%       and will generate significantly fewer nonzeros than requested if
%       m*n is small or density is large.
%
%   R = SPRANDN(m,n,density,rc) also has reciprocal condition number
%       approximately equal to rc.  R is constructed from a sum of
%       matrices of rank one. 
%
%       If rc is a vector of length lr <= min(m,n), then R has 
%       rc as its first lr singular values, all others are zero.
%       In this case, R is generated by random plane rotations
%       applied to a diagonal matrix with the given singular values
%       It has a great deal of topological and algebraic structure.
%
%   See also SPRAND, SPRANDSYM.

%   Rob Schreiber and Cleve Moler
%   Copyright 1984-2021 The MathWorks, Inc.

if nargin == 1
   S = arg1;
   if ~ismatrix(S)
       error(message('MATLAB:sprandn:ndInput'));
   end
   [m,n] = size(S);
   [i,j] = find(S);
   R = sparse(i,j,randn(length(i),1),m,n);
elseif nargin == 2
   error(message('MATLAB:sprandn:TwoInputs'))
elseif nargin == 3
   m = arg1;
   nnzwanted = round(m * n * min(density,1));
   i = fix( rand(nnzwanted, 1) * m ) + 1;
   j = fix( rand(nnzwanted, 1) * n ) + 1;
   if nnzwanted < m
       ij = unique([i j],'rows');
       i = ij(:,1);
       j = ij(:,2);
       rands = randn( length(i), 1 );
       R = sparse(i,j,rands,m,n);
   else
       R = sparse(j,i,true,n,m);
       [i,j] = find(R);
       rands = randn( length(i), 1 );
       R = sparse(i,j,rands,n,m)';
   end
else    %    nargin == 4
   m = arg1;
   nnzwanted = round(min(density,1)*m*n);
   minm = min(m,n);
   maxmn = max(m,n);
   lr = length(rc);
   if (lr == 1)
     if ~(rc <= 1 && rc >= 0 && imag(rc) == 0)
       error(message('MATLAB:sprandn:RcondTooHigh')); 
     end
     rcc = rc;
     rc = randn(minm, 1);
     sg = sign(rc);
     sf = max(rc) - min(rc);
     rc = sg.*(((1 - rcc)./sf).*abs(rc) + rcc);
     [~, ind] = min(abs(rc));
     rc(ind) = sg(ind).*rcc;
     [~, ind] = max(abs(rc));
     rc(ind) = sg(ind).*1;
     lr = minm;
   elseif lr > minm
     lr = minm;
   end
   %
   %   To start, put a random nonzero in every column / row if
   %   there is room enough
   %
   anz = zeros(maxmn, 1);
   anz(1:lr) = rc(1:lr);
   lr = minm;      %   if lr < minm then this adds some zero s.v. 
   sqrt2o2 = sqrt(2)/2;
   while (lr < min(maxmn, nnzwanted))
      ndo = min([lr, nnzwanted-lr, maxmn-lr]);
      anz(lr+1 : lr+ndo) = sqrt2o2 * anz(1:ndo);
      anz(1 : ndo) = sqrt2o2 * anz(1:ndo);
      lr = lr + ndo;
   end
   p = randperm(m);
   q = randperm(n);
   if (m < n)
      p = p(1 + rem((0:n-1), m));
   else
      q = q(1 + rem((0:m-1), n));
   end
   R = sparse(p, q, anz, m, n);
   %
   %   random two-sided rotations
   %
   while ( nnz(R) < .95*nnzwanted )
       R = rjr(R,2);
   end
end     %   nargin == 4
