function metric = precisionMetric(opts)
% precisionMetric   Deep Learning precision metric
%
%   metric = precisionMetric creates a precision metric to use when training
%   a deep neural network.
%
%   metric = precisionMetric(PARAM1=VAL1,PARAM2=VAL2,...) specifies optional
%   name-value arguments for creating the metric:
%
%       Name                 - Metric name, specified as a string scalar or
%                              char array.
%                              The default is "Precision".
%
%       NetworkOutput        - Name of output layer to apply the metric to,
%                              specified as [], a string scalar or a character 
%                              vector. When the value is [], the software 
%                              passes all of the network outputs to the metric.
%                              If the network has multiple outputs, then
%                              NetworkOutput must be set to the name of the
%                              network output to apply this metric to.
%                              The default is [].
%
%       AverageType          - Type of averaging to use to compute the 
%                              precision, specified as:
%                             "micro"    - Calculate the precision across all
%                                          classes. 
%                             "macro"    - Calculate the precision for each 
%                                          class and return the average. 
%                             "weighted" - Calculate the precision for each 
%                                          class and return the weighted 
%                                          average. The weight for each class
%                                          is the proportion of observations
%                                          from that class. 
%                              The default value is "macro".
%
%       ClassificationMode   - Type of classification task, specified as
%                              one of the following:
%                             "single-label" - Each observation is 
%                                              exclusively assigned one 
%                                              class label.
%                             "multilabel"   - Each observation can be 
%                                              assigned more than one 
%                                              independent class label.
%                             The default value is "single-label".

%   Copyright 2022-2023 The MathWorks, Inc.
 
arguments
    opts.Name {deep.internal.util.validateName} = iDefaultName()
    opts.NetworkOutput {deep.internal.util.validateOneNetworkOutput} = iDefaultNetworkOutput()
    opts.AverageType {deep.internal.util.validateAverageType} = iDefaultAverageType()
    opts.ClassificationMode {deep.internal.util.validateClassificationMode} = iDefaultClassificationMode()
end

% Standardize values.
name = deep.internal.util.validateName(opts.Name);
networkOutput = deep.internal.util.validateOneNetworkOutput(opts.NetworkOutput);
averageType = deep.internal.util.validateAverageType(opts.AverageType);
classificationMode = deep.internal.util.validateClassificationMode(opts.ClassificationMode);

% Create a user-visible precision metric.
metric = deep.metric.PrecisionMetric(name, networkOutput, averageType, classificationMode);

end

function name = iDefaultName()
name = "Precision";
end

function name = iDefaultNetworkOutput()
name = [];
end

function val = iDefaultAverageType()
val = "macro";
end

function val = iDefaultClassificationMode()
val = "single-label";
end