function E = mape(F,A,varargin)
%MATLAB Code Generation Library Function

%MAPE Mean absolute percentage error.
%#codegen

% Copyright 2022 The MathWorks, Inc.

coder.internal.prefer_const(varargin);

[D,isDimSet,dim,omitnan,omitzero,isWeighted,w] = ...
    parseErrorMetricsInput(true,F,A,varargin{:});

X = abs(D./A); % abs guarantees a real result

if omitnan || omitzero
    nanflag = 'omitnan';
else
    nanflag = 'includenan';
end

if omitzero && coder.internal.get_eml_option('NonFinitesSupport')
    isInfMade = false(size(X));
    nonEmptyWeight = ~isempty(w);
    for i = 1:numel(X)
        if ~isfinite(X(i)) && isfinite(D(i))
            X(i) = coder.internal.nan;
            if nonEmptyWeight
                w(i) = coder.internal.nan;
            end
            isInfMade(i) = true;
        end
    end
end

% Compute MAPE
if isWeighted
    Y = w.*X;
    if isDimSet
        % Branching due to the edge case where X is empty.
        E = sum(Y,dim,nanflag) ./ sum(w,dim,nanflag);
    else
        E = sum(Y,nanflag) ./ sum(w,nanflag);
    end
else
    Y = X;
    if isDimSet
        % Branching due to the edge case where X is empty.        
        E = mean(Y,dim,nanflag);
    else
        E = mean(Y, nanflag); 
    end
end
E = E.*100;

if omitnan && anynan(Y)
    % Check if new NaNs were created during computation,
    % e.g. Inf - Inf, 0 * Inf, Inf / Inf, etc.
    % Do not omit NaNs caused by this computation (not missing data).
    if omitzero
        XisNaN = isnan(Y) & ~isInfMade;
    else
        XisNaN = isnan(Y);
    end
    if isWeighted
        isNaNMade = XisNaN & ~isnan(w) & ~isnan(F) & ~isnan(A); 
    else
        isNaNMade = XisNaN & ~isnan(F) & ~isnan(A);
    end    
    E(any(isNaNMade,dim)) = coder.internal.nan;

elseif omitzero
    % Include NaNs
    E(any(isnan(Y) & ~isInfMade,dim)) = coder.internal.nan; 
end
end