function [z, ind] = max(x, y, varargin)
%MAX    Maximum elements of an array.
%   M = MAX(X)
%   Z = MAX(X,Y)
%   [M,I] = MAX(X)
%   [M,I] = MAX(X,[],DIM)
%   [M,I] = MAX(X,[],VECDIM)
%   [M,I] = MAX(X,[],'all')
%   [M,I] = MAX(X,[],...,'linear')
%   MAX(...,'omitnan')
%   MAX(...,'includenan')
%   MAX(...,'ComparisonMethod',METHOD)
%
%   The output M has the same dimension labels, if any, as the input X.
%
%   If X and Y have dimension labels, Z has a combination of both of their
%   dimension labels. Implicit expansion is used in combining X and Y.
%   Singleton dimensions (dimensions of size 1) with dimension labels are
%   introduced into X and Y as necessary to make their dimensions match.
%   Singleton dimensions are inserted at the end of each block of
%   dimensions with the same label.
%
%   Example:
%   X has dimensions 'SCB'
%   Y has dimensions 'SSCT'
%
%   X: |S |C|B| |
%   Y: |SS|C| |T|
%   Z: |SS|C|B|T|
%
%   Output Z has dimensions 'SSCBT'.
%
%   See also MAX, DLARRAY, DLARRAY/MIN.

%   Copyright 2019-2023 The MathWorks, Inc.

if nargin < 2 || (nargin > 2 && isequal(y, []))
    % Unary function
    if nargin > 1 && ~isa(x, 'dlarray')
        varargin = extractDlarrayCell(varargin);
        if nargout <= 1
            z = max(x, [], varargin{:});
        else
            [z, ind] = max(x, [], varargin{:});
        end
        return
    end

    [x, fdx, xdata, args] = helperReduction(x, 'max', varargin{:});

    if ~isempty(args)
        % Max needs an empty 2nd arg when there are additional flags.
        args = [{[]}, args];
    end

    if nargout <= 1
        xdata = max(xdata, args{:});
    else
        internalSizeX = size(xdata);
        [xdata, inddata] = max(xdata, args{:});
    end

    x.FormattedData = insertData(fdx, xdata);
    if nargout > 1
        viewToData = x.ViewToDataMap;
        if ~isempty(viewToData) && iHasLinearFlag(args)
            inddata = deep.internal.dlarray.translateLinearIndicesToNewView(...
                inddata, internalSizeX, viewToData);
        end
        ind = x;
        ind.FormattedData = insertData(fdx, inddata);
    end

    x = dropTrailingODims(x);
    z = x;
elseif ischar(y) || isstring(y)
    error(message('MATLAB:max:secondInputFlag'));
elseif nargout>1
    % Second output not supported
    error(message('MATLAB:max:TwoInTwoOutCaseNotSupported'));
else
    % Binary function

    % If this file is modified to not be a standard binary element-wise
    % broadcast function, please also remove the following template tags.
    %!define $BinaryFunction max($xdata, $ydata, varargin{:})
    %!template $BinaryBroadcastTemplate
    % Code generated and inserted by deep.dev.generateDlarrayMethods.
    
    % Extract data to work on and create a template output object.  If either
    % of the inputs are reusable it will be used as the template output.
    [z, fdz, xdata, ydata] = extractBinaryBroadcastData(...
        matlab.lang.internal.move(x), ...
        matlab.lang.internal.move(y));
    
    zdata = max(matlab.lang.internal.move(xdata), matlab.lang.internal.move(ydata), varargin{:});
    
    z = restoreBinaryBroadcastData(z, ...
        matlab.lang.internal.move(fdz), ...
        matlab.lang.internal.move(zdata));
    %!template
end
end

function tf = iHasLinearFlag(args)
tf = false;
for ii=1:length(args)
    a = args{ii};
    if ischar(a) || isstring(a)
        tf = strncmpi(a, 'linear', strlength(a));
        if tf
            return
        end
    end
end
end
