function [nxInLimits,xMinInLimits,xMaxInLimits] = ...
    rangeTool(x,LowLimit,HighLimit)
%MATLAB Code Generation Library Function

% Returns the number, minimum, and maximum of elements of
% x(x>=xlo & x<=xhi). If n == 0, minx and maxx are arbitrarily set to
% zero. The inputs xlow and xhigh are optional. If not supplied, xlow and
% xhigh effectively default to minimum and maximum finite values in x,
% respectively.

% Copyright 2018-2020 The MathWorks, Inc.
%#codegen

if issparse(x)
    if nargin == 1
        [nxInLimits,xMinInLimits,xMaxInLimits] = rangeTool(nonzeros(x));
        nxInLimits = nxInLimits + ...
            coder.internal.indexInt(numel(x) - nnz(x));
        if 0 < xMinInLimits
            xMinInLimits(1) = 0;
        elseif 0 > xMaxInLimits
            xMaxInLimits(1) = 0;
        end
    else
        [nxInLimits,xMinInLimits,xMaxInLimits] = ...
            rangeTool(nonzeros(x),LowLimit,HighLimit);
        if LowLimit <= 0 && 0 <= HighLimit
            nxInLimits = nxInLimits + ...
                coder.internal.indexInt(numel(x) - nnz(x));
            if 0 < xMinInLimits
                xMinInLimits(1) = 0;
            elseif 0 > xMaxInLimits
                xMaxInLimits(1) = 0;
            end
        end
    end
    return
end
% GPU enabled condition is added here.
% Rewrote the code using gpucoder.atomicAdd and gpucoder.reduce
% pragmas to generate optmized GPU code.
if coder.gpu.internal.isGpuEnabled && nargin == 1 ...
        && ~coder.internal.isConstantFolding
    nx = coder.internal.indexInt(numel(x));
    nxInLimits = coder.internal.indexInt(0);
    for j = 1:nx
        if isfinite(x(j))
            nxInLimits = gpucoder.atomicAdd(nxInLimits,...
                coder.internal.indexInt(1));
        end
    end
    xMinInLimits = cast(0,'like',x);
    xMaxInLimits = cast(0,'like',x);
    if nargout > 1 && nxInLimits > 0
        xMinMaxInLimits = gpucoder.reduce(x,{@minimum,@maximum});
        xMinInLimits = xMinMaxInLimits(1);
        xMaxInLimits = xMinMaxInLimits(2);
    end

else
    nx = coder.internal.indexInt(numel(x));
    k = coder.internal.indexInt(1);
    % Scan forward to the first finite value in range.
    if nargin == 3
        while k <= nx && ~(LowLimit <= x(k) && x(k) <= HighLimit)
            k = k + 1;
        end
    elseif isfloat(x)
        while k <= nx && ~isfinite(x(k))
            k = k + 1;
        end
    end
    if k > nx
        xMinInLimits = coder.internal.scalarEg(x);
        nxInLimits = coder.internal.indexInt(0);
    else
        xMinInLimits = x(k);
        nxInLimits = coder.internal.indexInt(1);
    end
    xMaxInLimits = xMinInLimits;
    for j = k+1:nx
        if (nargin == 1 && isfinite(x(j))) || ...
                (nargin == 3 && LowLimit <= x(j) && x(j) <= HighLimit)
            if nargout > 1
                if x(j) < xMinInLimits
                    xMinInLimits = x(j);
                elseif x(j) > xMaxInLimits
                    xMaxInLimits = x(j);
                end
            end
            nxInLimits = nxInLimits + 1;
        end
    end
end

% Function call for 'min'
    function c = minimum(a,b)
        c = eml_min(a,b);
        if isinf(c) && c < 0
            % At least one input is -Inf.
            if isinf(a)
                % Doesn't really matter if a == +Inf or -Inf. Make it +Inf.
                a = inf('like',a);
            end
            if isinf(b)
                % Doesn't really matter if b == +Inf or -Inf. Make it +Inf.
                b = inf('like',b);
            end
            c = eml_min(a,b);
        end
    end
% Function call for 'max'
    function c = maximum(a,b)
        c = eml_max(a,b);
        if isinf(c) && c > 0
            % At least one input is +Inf.
            if isinf(a)
                % Doesn't really matter if a == +Inf or -Inf. Make it -Inf.
                a = -inf('like',a);
            end
            if isinf(b)
                % Doesn't really matter if b == +Inf or -Inf. Make it -Inf.
                b = -inf('like',b);
            end
            c = eml_max(a,b);
        end
    end

end
