
classdef (Sealed) ConeprogOptions < optim.options.SingleAlgorithm
%

%ConeprogOptions Options for CONEPROG
%
%   The OPTIM.OPTIONS.CONEPROGOPTIONS class allows the user to create a set of
%   options for the CONEPROG solver. For a list of options that can be set,
%   see the documentation for CONEPROG.
%
%   OPTS = OPTIM.OPTIONS.CONEPROGOPTIONS creates a set of options for CONEPROG
%   with the options set to their default values.
%
%   OPTS = OPTIM.OPTIONS.CONEPROGOPTIONS(PARAM, VAL, ...) creates a set of options
%   for CONEPROG with the named parameters altered with the specified
%   values.
%
%   OPTS = OPTIM.OPTIONS.CONEPROGOPTIONS(OLDOPTS, PARAM, VAL, ...) creates a copy
%   of OLDOPTS with the named parameters altered with the specified values.
%
%   See also OPTIM.OPTIONS.SINGLEALGORITHM, OPTIM.OPTIONS.SOLVEROPTIONS

%   Copyright 2020 The MathWorks, Inc.

    properties (Dependent)

        %CONSTRAINTTOLERANCE Tolerance on the constraint violation.
        %
        %   For more information, type "doc coneprog" and see the "Options" section
        %   in the CONEPROG documentation page.
        ConstraintTolerance

        %DISPLAY Level of display
        %
        %   For more information, type "doc coneprog" and see the "Options" section
        %   in the CONEPROG documentation page.
        Display

        %MAXTIME Maximum time allowed
        %
        %   For more information, type "doc coneprog" and see the "Options" section
        %   in the CONEPROG documentation page.
        MaxTime

        %MAXITERATIONS Maximum number of iterations allowed
        %
        %   For more information, type "doc coneprog" and see the "Options" section
        %   in the CONEPROG documentation page.
        MaxIterations

        %OPTIMALITYTOLERANCE Termination tolerance on the optimality gap
        %                    measure
        %
        %   For more information, type "doc coneprog" and see the "Options" section
        %   in the CONEPROG documentation page.
        OptimalityTolerance

        %LINEARSOLVER Interior Point Method step solver choice.
        LinearSolver

    end

    properties (Hidden, Access = protected)
        %OPTIONSSTORE Contains the option values and meta-data for the class
        %
        OptionsStore = createOptionsStore;
    end

    properties (Hidden)
        %SOLVERNAME Name of the solver that the options are intended for
        %
        SolverName = 'coneprog';
    end

    properties (Hidden, SetAccess = private, GetAccess = public)

        %INTERNALOPTIONS Internal options
        InternalOptions = struct();

        % New version property added in second version
        ConeprogVersion
    end

    properties(Hidden, Constant, GetAccess=public)
        % Constant, globally visible metadata about this class.
        % This data is used to spec the options in this class for internal clients
        % such as: tab-complete, and the options validation
        % Properties
        PropertyMetaInfo = genPropInfo();
    end

    methods (Hidden)

        function obj = ConeprogOptions(varargin)
        %Coneprog Options for CONEPROG
        %
        %   The OPTIM.OPTIONS.CONEPROGOPTIONS class allows the user to create a set of
        %   options for the CONEPROG solver. For a list of options that can be set,
        %   see the documentation for CONEPROG.
        %
        %   OPTS = OPTIM.OPTIONS.CONEPROGOPTIONS creates a set of options for CONEPROG
        %   with the options set to their default values.
        %
        %   OPTS = OPTIM.OPTIONS.CONEPROGOPTIONS(PARAM, VAL, ...) creates a set of options
        %   for CONEPROG with the named parameters altered with the specified
        %   values.
        %
        %   OPTS = OPTIM.OPTIONS.CONEPROGOPTIONS(OLDOPTS, PARAM, VAL, ...) creates a copy
        %   of OLDOPTS with the named parameters altered with the specified values.
        %
        %   See also OPTIM.OPTIONS.SINGLEALGORITHM, OPTIM.OPTIONS.SOLVEROPTIONS

        % Call the superclass constructor
            obj = obj@optim.options.SingleAlgorithm(varargin{:});

            % Record the class version; Update property 'ConeprogVersion'
            % instead of superclass property 'Version'.
            obj.Version = 1;
            obj.ConeprogVersion = 2;
        end

    end

    % Set/get methods
    methods

        % ---------------------- Set methods ------------------------------

        function obj = set.ConstraintTolerance(obj, value)
            obj = setProperty(obj, 'ConstraintTolerance', value);
        end

        function obj = set.Display(obj, value)
            obj = setProperty(obj, 'Display', value);
        end

        function obj = set.MaxTime(obj, value)
            obj = setProperty(obj, 'MaxTime', value);
        end

        function obj = set.MaxIterations(obj, value)
            obj = setProperty(obj, 'MaxIterations', value);
        end

        function obj = set.OptimalityTolerance(obj, value)
            obj = setProperty(obj, 'OptimalityTolerance', value);
        end

        function obj = set.LinearSolver(obj, value)
            obj = setProperty(obj, 'LinearSolver', value);
        end

        % ---------------------- Get methods ------------------------------

        function value = get.ConstraintTolerance(obj)
            value = obj.OptionsStore.Options.ConstraintTolerance;
        end

        function value = get.Display(obj)
            value = obj.OptionsStore.Options.Display;
        end

        function value = get.MaxIterations(obj)
            value = obj.OptionsStore.Options.MaxIterations;
        end

        function value = get.MaxTime(obj)
            value = obj.OptionsStore.Options.MaxTime;
        end

        function value = get.OptimalityTolerance(obj)
            value = obj.OptionsStore.Options.OptimalityTolerance;
        end

        function value = get.LinearSolver(obj)
            value = obj.OptionsStore.Options.LinearSolver;
        end

    end

    methods (Hidden)

        function checkOptions(~, ~, ~)
        %CHECKOPTIONS Perform consistency checks on the options
        %
        %   CHECKOPTIONS(OBJ, PROBLEM, CALLER) checks that the options are
        %   consistent as a set (e.g. DiffMaxChange >= DiffMinChange for fmincon).
        %   This function also checks that any options that are dependent on the
        %   problem are valid.

        %   For this options object, there are no options that depend on eachother
        %   or the problem. So this function does not need to perform any action.

        end

        function obj = setInternalOptions(obj, InternalOptions)
        %SETINTERNALOPTIONS Set internal SLBI options
        %
        %   OBJ = SETINTERNALOPTIONS(OBJ, INTERNALOPTIONS) sets the specified
        %   internal options in OBJ

            obj.InternalOptions = InternalOptions;
        end


        function OptionsStruct = extractCustomOptionsStructure(obj)
        %EXTRACTCUSTOMOPTIONSSTRUCTURE Extract options structure from OptionsStore
        %
        %   OPTIONSSTRUCT = EXTRACTCUSTOMOPTIONSSTRUCTURE(OBJ) extracts a plain
        %   structure containing the options from obj.OptionsStore. The solver
        %   calls convertForSolver, which in turn calls this method to obtain a
        %   plain options structure.

        % Call the superclass method
            OptionsStruct = extractCustomOptionsStructure@optim.options.SingleAlgorithm(obj);

            % Append the InternalOptions field
            OptionsStruct.InternalOptions = obj.InternalOptions;

        end

    end

    methods (Static)

        function obj = loadobj(obj)
            if obj.ConeprogVersion < 2
                oldObj = obj;
                obj = optim.options.ConeprogOptions;
                obj.OptionsStore = getOptionsStore(oldObj);
                obj.OptionsStore.Defaults.LinearSolver = 'auto';
                obj.OptionsStore.Options.LinearSolver = 'auto';
                obj.OptionsStore.SetByUser.LinearSolver = false;
                obj = setInternalOptions(obj, oldObj.InternalOptions);
            end
        end

    end

end

function OS = createOptionsStore
%CREATEOPTIONSSTORE Create the OptionsStore
%
%   OS = createOptionsStore creates the OptionsStore structure. This
%   structure contains the options and meta-data for option display, e.g.
%   data determining whether an option has been set by the user. This
%   function is only called when the class is first instantiated to create
%   the OptionsStore structure in its default state. Subsequent
%   instantiations of this class pick up the default OptionsStore from the
%   MCOS class definition.
%
%   Class authors must create a structure containing all the options in a
%   field of OS called Defaults. This structure must then be passed to the
%   optim.options.generateSingleAlgorithmOptionsStore function to create
%   the full OptionsStore.

% Define the defaults
    OS.Defaults.Display = 'final';
    OS.Defaults.MaxIterations = 200;
    OS.Defaults.MaxTime = Inf;
    OS.Defaults.ConstraintTolerance = 1e-6;
    OS.Defaults.OptimalityTolerance = 1e-6;
    OS.Defaults.LinearSolver = 'auto';

    % Call the package function to generate the OptionsStore
    OS = optim.options.generateSingleAlgorithmOptionsStore(OS);

end

function propInfo = genPropInfo()
% Helper function to generate constant property metadata for the Coneprog
% options class.
    import optim.options.meta.Factory
    import optim.options.meta.category
    import optim.options.meta.label

    propInfo.ConstraintTolerance = Factory.ConstraintToleranceType;
    propInfo.Display = Factory.displayType({'none','final','off','iter'});
    propInfo.MaxIterations = Factory.MaxIterType;
    propInfo.MaxTime = Factory.MaxTimeType;
    propInfo.OptimalityTolerance = Factory.OptimalityToleranceType;
    propInfo.LinearSolver = Factory.enumType({'auto', 'augmented','normal','prodchol','schur'}, label('LinSolver'), category('Algorithm'));
end
