classdef (Sealed) GamultiobjOptions < optim.options.GacommonOptions
%GamultiobjOptions Options for GAMULTIOBJOPTIONS
%
%   The OPTIM.OPTIONS.GAMULTIOBJOPTIONS class allows the user to create a set
%   of options for the GAMULTIOBJOPTIONS solver. For a list of options that can
%   be set, see the documentation for gamultiobj.
%
%   OPTS = OPTIM.OPTIONS.GAMULTIOBJOPTIONS creates a set of options for
%   GAMULTIOBJOPTIONS with the options set to their default values.
%
%   OPTS = OPTIM.OPTIONS.GAMULTIOBJOPTIONS(PARAM, VAL, ...) creates a set of
%   options for GAMULTIOBJOPTIONS with the named parameters altered with the
%   specified values.
%
%   OPTS = OPTIM.OPTIONS.GAMULTIOBJOPTIONS(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 2015-2017 The MathWorks, Inc.
    
    properties (Dependent)
%DISTANCEMEASUREFCN Function that computes distance measure of individuals
%
%   For more information, type "doc gamultiobj" and see the "Options"
%   section in the GAMULTIOBJOPTIONS documentation page.
        DistanceMeasureFcn        
        
%HYBRIDFCN Function that continues the optimization after ga finishes
%
%   For more information, type "doc gamultiobj" and see the "Options"
%   section in the GAMULTIOBJ documentation page.
        HybridFcn          
        
%PARETOFRACTION Fraction of individuals kept on first Pareto front
%
%   For more information, type "doc gamultiobj" and see the "Options"
%   section in the GAMULTIOBJOPTIONS documentation page.
        ParetoFraction     

%PLOTFCN Plots various measures of progress while the algorithm executes
%
%   For more information, type "doc ga or gamultiobj" and see the "Options"
%   section in the GA or GAMULTIOBJ documentation page.
        PlotFcn              
        
%SELECTIONFCN Function that selects parents of crossover and mutation children
%
%   For more information, type "doc ga" and see the "Options"
%   section in the GAMULTIOBJ documentation page.
        SelectionFcn           
    end

    properties (Hidden, Dependent)
%PLOTFCNS Plots various measures of progress while the algorithm executes
        PlotFcns       
    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 = 'gamultiobj';
    end
    
    properties (SetAccess = private, GetAccess = private)
       
        % Version number for the optim.options.GamultiobjOptions class. 
        % We do not change the Version property (base class).
        GamultiobjVersion = 1;
    end
    
    properties (Hidden, Constant)
       InvalidSelectionFcns = {'selectionremainder','selectionroulette', ...
                    'selectionstochunif','selectionuniform'}; 
    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  options validation.
        
        PropertyMetaInfo = genPropInfo();
    end
    
% -------------------------------------------------------

    methods (Hidden)
        
        function obj = GamultiobjOptions(varargin)
%GamultiobjOptions Options for GAMULTIOBJOPTIONS
%
%   The OPTIM.OPTIONS.GAMULTIOBJOPTIONS class allows the user to create a set
%   of options for the GAMULTIOBJOPTIONS solver. For a list of options that can
%   be set, see the documentation for GAMULTIOBJOPTIONS.
%
%   OPTS = OPTIM.OPTIONS.GAMULTIOBJOPTIONS creates a set of options for
%   GAMULTIOBJOPTIONS with the options set to their default values.
%
%   OPTS = OPTIM.OPTIONS.GAMULTIOBJOPTIONS(PARAM, VAL, ...) creates a set of
%   options for GAMULTIOBJOPTIONS with the named parameters altered with the
%   specified values.
%
%   OPTS = OPTIM.OPTIONS.GAMULTIOBJOPTIONS(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.GacommonOptions(varargin{:});
            
        end
        
    end
    
    % Set/get methods
    methods
        function obj = set.DistanceMeasureFcn(obj, value)
            obj = setProperty(obj, 'DistanceMeasureFcn', value);
        end 
        
        function obj = set.HybridFcn(obj, value)
            obj = setProperty(obj, 'HybridFcn', value);
        end  
        
        function obj = set.ParetoFraction(obj, value)
            obj = setProperty(obj, 'ParetoFraction', value);
        end 
        
        function obj = set.PlotFcn(obj, value)
            obj = setAliasProperty(obj, 'PlotFcn', 'PlotFcns', value);
        end          
        
        function obj = set.PlotFcns(obj, value)
            obj = setProperty(obj, 'PlotFcns', value);
        end         
        
        function obj = set.SelectionFcn(obj, value)   
            % First check the type, then refine checking
            obj = setProperty(obj, 'SelectionFcn', value);
            if iscell(value)
                value = value{1};
            end
            if any(strcmpi(char(value),optim.options.GamultiobjOptions.InvalidSelectionFcns))
                msg = getString(message('globaloptim:validate:InvalidMultiObjSelectionFcn'));
                error('optim:options:GamultiobjOptions:InvalidMultiObjSelectionFcn',msg);
            end
        end         
        
        %---------------------- Get functions -----------------------------
        
        function value = get.DistanceMeasureFcn(obj)
           value = obj.OptionsStore.Options.DistanceMeasureFcn;
        end 
        
        function value = get.HybridFcn(obj)
            value = obj.OptionsStore.Options.HybridFcn;
        end           
        
        function value = get.ParetoFraction(obj)
            value = obj.OptionsStore.Options.ParetoFraction;
        end         
        
        function value = get.PlotFcn(obj)
            value = obj.OptionsStore.Options.PlotFcns;
        end

        function value = get.PlotFcns(obj)
            value = obj.OptionsStore.Options.PlotFcns;
        end        
        
        function value = get.SelectionFcn(obj)
            value = obj.OptionsStore.Options.SelectionFcn;
        end           
    end % get/set methods
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. See below for an example for GamultiobjOptions.

% Define the option defaults for the solver
OS.Defaults.CreationFcn = @gacreationuniform;
OS.Defaults.CrossoverFcn = @crossoverintermediate;
OS.Defaults.CrossoverFraction = 0.8;
OS.Defaults.Display = 'final';
OS.Defaults.DistanceMeasureFcn = {@distancecrowding, 'phenotype'};
OS.Defaults.Generations = '200*numberOfVariables';
OS.Defaults.HybridFcn = [];
OS.Defaults.InitialPopulation = [];
OS.Defaults.InitialScores = [];
OS.Defaults.MigrationDirection = 'forward';
OS.Defaults.MigrationFraction = 0.2;
OS.Defaults.MigrationInterval = 20;
OS.Defaults.MutationFcn = @mutationadaptfeasible;
OS.Defaults.OutputFcns = [];
OS.Defaults.ParetoFraction = 0.35;
OS.Defaults.PlotFcns = [];
OS.Defaults.PlotInterval = 1;
OS.Defaults.PopInitRange = [];
OS.Defaults.PopulationSize = '50 when numberOfVariables <= 5, else 200';
OS.Defaults.PopulationType = 'doubleVector';
OS.Defaults.StallGenLimit = 100;
OS.Defaults.SelectionFcn = {@selectiontournament, 2};
OS.Defaults.TimeLimit = Inf;
OS.Defaults.TolCon = 1e-3;
OS.Defaults.TolFunValue = 1e-4;
OS.Defaults.UseParallel = false;
OS.Defaults.Vectorized = 'off';

% 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
% GamultiobjOptions
% options class.

import optim.options.meta.Factory
import optim.options.meta.category
import optim.options.meta.label

algorithmCat = category('Algorithm');

propInfo = optim.options.GacommonOptions.genPropInfo;

propInfo.CrossoverFcn = Factory.fcnWithCellType(label('CrossoverFcn'),algorithmCat,{'crossoverheuristic','crossoversinglepoint','crossovertwopoint','crossoverarithmetic','crossoverintermediate'});
propInfo.DistanceMeasureFcn = Factory.fcnWithCellType(label('DistanceFcn'),algorithmCat,{'distancecrowding'});
propInfo.HybridFcn = Factory.fcnWithCellType(label('HybridFcn'),algorithmCat,{'fgoalattain'},true);
propInfo.MutationFcn = Factory.fcnWithCellType(label('MutationFcn'),algorithmCat,{'mutationadaptfeasible','mutationuniform'});
propInfo.ParetoFraction = Factory.fractionalType(label('ParetoFraction'),algorithmCat);
propInfo.PlotFcn = Factory.plotFcnType({'gaplotdistance','gaplotgenealogy', 'gaplotselection', 'gaplotscorediversity', 'gaplotscores', 'gaplotstopping', ...
                                        'gaplotmaxconstr', 'gaplotrankhist', 'gaplotpareto', 'gaplotspread', 'gaplotparetodistance'});
propInfo.SelectionFcn = Factory.fcnWithCellType(label('SelectionFcn'),algorithmCat,{'selectiontournament'});

propInfo.PlotFcns = propInfo.PlotFcn;

end