classdef SobolParameterSpace < stats.internal.QuasiRandomParameterSpace
    %SOBOLPARAMETERSPACE 
    %

    % Copyright 2022 The MathWorks, Inc.

    properties(Dependent = true)
        Options
    end

    properties(Access = protected)
        Options_  
    end

    methods
        function obj = SobolParameterSpace(varargin)
            %SOBOLPARAMETERSPACE 
            %

            if ~license('test','Statistics_Toolbox') || isempty(ver('stats'))
                error(message('stats:sensitivity:general:errSample_SobolStatsNoLicense'))
            end

            obj = obj@stats.internal.QuasiRandomParameterSpace(varargin{:});
            obj.Options_ = sobolset(1,'Skip',1); %Default to Skip = 1
            obj = resetOptions(obj);
        end
        function obj = set.Options(obj,newValue)
            %Check that the new sobolset has the correct dimension
            if isempty(newValue)
                obj.Options_ = [];
            elseif isa(newValue,'sobolset')
                if newValue.Dimensions == numel(obj.Parameters)
                    obj.Options_ = newValue;
                else
                    error(message('stats:sensitivity:general:errSobolParameterSpace_Options'))
                end
            else
                error(message('stats:sensitivity:general:errSobolParameterSpace_Options'))
            end
        end
        function value = get.Options(obj)
            value = obj.Options_;
        end

        function obj = syncOptions(obj,newOptions)
            arguments
                obj stats.internal.SobolParameterSpace
                newOptions sobolset
            end
            opts = obj.Options; %To avoid setting obj.Options repeatedly
            opts.Leap = newOptions.Leap;
            opts.PointOrder = newOptions.PointOrder;
            opts.Skip = newOptions.Skip;
            opts.ScrambleMethod = newOptions.ScrambleMethod;
            obj.Options = opts;
        end
    end

    methods(Access = protected)
        function obj = setParameters(obj,newValue)

            nParams = numel(obj.Parameters);
            obj = setParameters@stats.internal.QuasiRandomParameterSpace(obj,newValue);
            if nParams ~= numel(obj.Parameters)
                %Need to update dimension of sobolset() stored in the
                %options
                obj = resetOptions(obj);
            end
        end
        function obj = resetOptions(obj)

            nP = numel(obj.Parameters);
            oldOpts = obj.Options;
            if nP>0
                if isempty(oldOpts)
                    newOpts = sobolset(nP, 'Skip', 1); %Default to skip = 1
                else
                    newOpts = sobolset(nP,...
                        "Leap", oldOpts.Leap, ...
                        "PointOrder", oldOpts.PointOrder, ...
                        "Skip", oldOpts.Skip, ...
                        "ScrambleMethod", oldOpts.ScrambleMethod);
                end
            else
                newOpts = [];
            end 
            obj.Options = newOpts;
        end
        function sampler = createSampler_(obj)
            sampler = stats.internal.sampler.SobolParameterSpace(obj);
        end
    end
end
