function varargout = lu(varargin)
%LU factorization for codistributed array
%   [L,U] = LU(D)
%   [L,U,P] = LU(D)
%   [L,U,P] = LU(A, outputForm)
%    
%   D must be a full codistributed matrix of floating point numbers (single or double).
%   
%   Example:
%   spmd
%       N = 1000;
%       D = codistributed.rand(N);
%       [L,U,piv] = lu(D,'vector');
%       norm(L*U-D(piv,:), 1)
%   end
%   
%   See also LU, CODISTRIBUTED, CODISTRIBUTED/RAND.


%   Copyright 2006-2021 The MathWorks, Inc.

distributedutil.CodistParser.verifyNonCodistributedInputs(varargin);

A = varargin{1};
argList = distributedutil.CodistParser.gatherElements(varargin(2:end));
if ~isa(A, 'codistributed')
    [varargout{1:nargout}] = lu(A, argList{:});
    return;
end

% Check additional inputs using a protoype of the same class, sparsity, and
% number of dimensions
try
    [varargout{1:nargout}] = lu(ones(2*ones(1, ndims(A)), ...
        'like', getLocalPart(A)), argList{:});
catch ME
    throw(ME);
end

% THRESH option for sparse inputs is not supported in our method
if ~isempty(argList) && isnumeric(argList{1})
   error(message('parallel:distributed:LuUnsupportedFlag'));
end

% Set flag to return permutation as matrix
permIsMat = isempty(argList) || startsWith('matrix', argList{end}, 'IgnoreCase', true);

if issparse(A)
    [varargout{1:max(1, nargout)}]=cparLu(A, permIsMat);
else
    [varargout{1:max(1, nargout)}]=scalaLu(A, permIsMat);
end
end
