function temp = templateLinear(varargin)
%TEMPLATELINEAR Create a linear model template for high-dimensional data.
%   T = TEMPLATELINEAR() returns a linear model template.
%
%   T = TEMPLATELINEAR('PARAM1',val1,'PARAM2',val2,...) specifies optional
%   parameter name/value pairs:
%       'Lambda'            - Either 'auto' or vector of non-negative values
%                             specifying the strength of the regularization
%                             term. FITCECOC sorts this vector in ascending
%                             order and removes duplicates. If 'auto', the
%                             regularization parameter is set to 1/N, where N is
%                             the number of observations in X. Default: 'auto'
%       'Learner'           - String, either 'svm' for support vector machine or
%                             'logistic' for logistic regression. Default: 'svm'
%       'Regularization'    - String, one of: 'ridge' or 'lasso'. Lasso is
%                             equivalent to L1, and ridge is equivalent to
%                             L2. If 'ridge', the objective function is
%                             composed by adding (Lambda/2)*Beta'*Beta to
%                             the average loss function. If 'lasso', the
%                             objective function is composed by adding
%                             Lambda*sum(abs(Beta)) to the average loss
%                             function. The bias term is not included in
%                             the regularization penalty. Default: 'ridge'
%       'Solver'            - Either a string, a string array or a cell
%                             array of strings. You can pass
%                               * 'sgd'   - Stochastic Gradient Descent.
%                               * 'asgd'  - Average Stochastic Gradient Descent
%                               * 'dual'  - Dual Stochastic Gradient Descent for
%                                           SVM with ridge penalty. If you
%                                           pass 'dual' and specify lasso
%                                           penalty, optimization errors.
%                                           If you pass 'dual' and specify
%                                           MODEL other than 'svm',
%                                           optimization errors.
%                               * 'bfgs'  - BFGS for the ridge penalty. If you
%                                           pass 'bfgs' and specify lasso
%                                           penalty, optimization errors.
%                                           BFGS is not recommended for
%                                           high-dimensional data.
%                               * 'lbfgs' - Low-memory BFGS. If you pass 'lbfgs'
%                                           and specify lasso penalty,
%                                           optimization errors.
%                               * 'sparsa'- Sparse Reconstruction by Separable
%                                           Approximation for the lasso penalty.
%                                           If you pass 'sparsa' and specify
%                                           ridge penalty, optimization errors.
%                           TIPS:
%                            - For high-dimensional data with ridge penalty,
%                              pass 'sgd', 'asgd', 'dual' (for SVM only),
%                              'lbfgs', {'sgd','lbfgs'}, {'asgd','lbfgs'},
%                              or {'dual','lbfgs'}. Although you can pass
%                              other combinations, they often lead to
%                              solutions with poor accuracy.
%                            - For low-dimensional data with ridge penalty, try
%                              'bfgs'.
%                            - For lasso penalty, pass 'sgd', 'asgd', 'sparsa',
%                              {'sgd','sparsa'}, or {'asgd','sparsa'}.
%                           Defaults:
%                                * 'bfgs' for ridge penalty and 100 or fewer
%                                   predictors
%                                * 'dual' for SVM with ridge penalty and more
%                                   than 100 predictors
%                                * 'sparsa' for lasso penalty and 100 or fewer
%                                   predictors
%                                * 'sgd' otherwise
%       'Type'              - String specifying the type of linear model template.
%                             Specify as one of 'classification' or 'regression'.
%                             Default = []
%
%   Refer to the MATLAB documentation for info on parameters for
%       <a href="matlab:helpview('stats', 'templateLinearClassificationOptions')">linear classification</a>
%       <a href="matlab:helpview('stats', 'templateLinearRegressionOptions')">linear regression</a>
%       <a href="matlab:helpview('stats', 'templateLinearSGDOptions')">SGD and ASGD solvers</a>
%       <a href="matlab:helpview('stats', 'templateLinearSGDOptimizationControlOptions')">controlling SGD and ASGD convergence</a>
%       <a href="matlab:helpview('stats', 'templateLinearDualOptimizationControlOptions')">controlling convergence of the Dual solver</a>
%       <a href="matlab:helpview('stats', 'templateLinearLBFGSOptimizationControlOptions')">controlling convergence of BFGS, LBFGS and SpaRSA solvers</a>
%
%   See also fitcecoc, fitclinear, ClassificationECOC,
%   ClassificationLinear, fitrlinear, RegressionLinear.

%   Copyright 2015-2023 The MathWorks, Inc.

if nargin > 0
    [varargin{:}] = convertStringsToChars(varargin{:});
end

[type,learner,~,extra] = internal.stats.parseArgs({'type' 'learner'},{'' ''},varargin{:});

if ~isempty(type)
    type = validatestring(type,{'classification' 'regression'},...
        'templateLinear','Type');
end

if ~isempty(learner)
    learner = validatestring(learner,{'leastsquares' 'logistic' 'svm'},...
        'templateLinear','Learner');
else
    learner = 'svm';
end

if strncmpi(learner,'leastsquares',length(learner))
    if ~isempty(type) && strncmpi(type,'classification',length(type))
        error(message('stats:templateLinear:BadClassificationLearner'));
    end
    temp = RegressionLinear.template('Learner','leastsquares',extra{:});
elseif strncmpi(learner,'logistic',length(learner))
    if ~isempty(type) && strncmpi(type,'regression',length(type))
        error(message('stats:templateLinear:BadRegressionLearner'));
    end
    temp = ClassificationLinear.template('Learner','logistic',extra{:});
elseif strncmpi(learner,'svm',length(learner))
    temp = classreg.learning.FitTemplate.make('Linear','Learner','svm','type',type,extra{:});
else
    error(message('stats:templateLinear:BadLearner'));
end

end

% LocalWords:  FITCLINEAR fitclinear
