function X = leakyrelu(X, scale)
%LEAKYRELU   Apply leaky rectified linear unit activation
%
%   Y = LEAKYRELU(X) computes the leaky relu activation for the input X. X
%   can be a formatted or an unformatted dlarray. If X is a formatted
%   dlarray, output Y is a formatted dlarray with the same dimension labels
%   as X. If X is an unformatted dlarray, output Y is an unformatted
%   dlarray.
%
%   The leaky relu operation performs a threshold operation, where any
%   input value less than zero is multiplied by a scale factor. This is
%   equivalent to:
%       Y = X;        % If X > 0 
%       Y = SCALE.*X; % If X <= 0
%   The default value for SCALE is 0.01.
%
%   Y = LEAKYRELU(X,SCALE) computes the leaky relu activation for the input
%   X, using SCALE as the multiplication factor.
%
%   Example:
%       % Create formatted dlarray input data and compute leakyrelu
%       % activation with a scale of 0.2.
%       x = dlarray(randn(8,8,3,16),'SSCB');
%       y = leakyrelu(x,0.2);
%
%   See also BATCHNORM, DLARRAY, DLCONV, RELU

%   Copyright 2019-2022 The MathWorks, Inc.

arguments
    X
    scale (1,1) {deep.internal.dlarray.mustBeNumericDLData, mustBeFinite, deep.internal.dlarray.mustBeNonDlarray} = 0.01
end

% Only data defines execution environment, not parameters
scale = gather(scale);

% Extract the input data
fd = X.FormattedData;
X.FormattedData = [];
[fd,xdata] = extractData(fd);

% The dlarray methods should not accept logical x 
if islogical(xdata)
    error(message('deep:dlarray:LogicalDlarrayNotSupported'));
end

% Call the internal API
xdata = internal_leakyrelu(xdata, scale);

% Format is guaranteed not to have changed
fd = insertData(fd, xdata);
X.FormattedData = fd;
end
