www.gusucode.com > mbc 工具箱 matlab 源码程序 > mbc/+mbcdoe/@design/design.m

    classdef design < mbcutils.abstractdataobject
    %MBCDOE.DESIGN Design of experiment class
    %
    % A mbcdoe.design object can be created with CreateDesign method of
    % mbcmodel.testplan, mbcmodel.model or mbcmodel.modelinput.
    %
    % Types = getAlternativeTypes(Design) returns a list of valid design
    % types. The list of valid design types is:
    %
    % Style           Type
    %--------------------------------------------
    % Optimal    	  'D-optimal'
    %                 'V-optimal'
    %                 'A-optimal'
    % Space-filling   'Halton Sequence'
    %                 'Latin Hypercube Sampling'
    %                 'Lattice'
    %                 'Sobol Sequence'
    %                 'Stratified Latin Hypercube'
    % Classical  	  'Box-Behnken'
    %                 'Central Composite'
    %                 'Full Factorial'
    %                 'Plackett-Burman'
    %                 'Regular Simplex'
    %
    % See also mbcmodel.testplan.CreateDesign,
    % mbcmodel.model.CreateDesign, mbcmodel.modelinput.CreateDesign,
    % getAlternativeTypes

    %  Copyright 2007-2013 The MathWorks, Inc.

    properties (Dependent,SetAccess=protected)
        %STYLE Design style (read only)
        %
        %   Valid design styles are:
        %     'User-defined','Optimal','Space-filling','Classical', or
        %     'Experimental data'.
        %
        % See also Type
        Style
        
        %TYPE Design type (read only)
        %
        % You can only choose a type when you create designs. After design
        % creation, you can only set the Type of a mbcdoe.generator object, or when calling Generate or Augment.
        %
        %See also Style, getAlternativeTypes, Generator, Generate, Augment
        Type
        
        %NUMBEROFPOINTS Number of points in the design after apply any constraints (read only)
        NumberOfPoints
        
        %NUMBEROFINPUTS Number of input factors for design  (read only)
        NumberOfInputs
    end

    properties (Dependent)
        %NAME Name of design
        % 
        % The name of the design is used to identify a design uniquely in a
        % test plan.
        % 
        % See also mbcmodel.testplan.FindDesign,
        % mbcmodel.testplan.UpdateDesign
        Name
        
        %POINTS Matrix of design points
        Points
        
        %POINTTYPES Cell array indicating design point status ('free','fixed','data')
        %
        % See also FixPoints, RemovePoints, Augment
        PointTypes
        
        %INPUTS mbcmodel.modelinput array for design input factors
        %
        % The number of design inputs cannot be changed. 
        %
        % See also mbcmodel.modelinput
        Inputs
        
        %GENERATOR Generator for design type 
        %
        % See also mbcdoe.generator, Generate, Augment
        Generator
        
        %CONSTRAINTS Array of mbcdoe.designconstraint objects for design
        %
        % See also mbcdoe.designconstraint, AddConstraint, CreateConstraint
        Constraints
        
        %MODEL Model that the design is based on
        %
        % The number of design inputs cannot be changed. Optimal
        % designs are changed to custom if the new model does not support
        % optimal designs.  
        Model
    end
    
    methods (Hidden)
        function D = design(des,varargin)
           if nargin
               D.Object = des;
               if nargin>1 && mod(nargin,2)==1
                   for i=1:2:length(varargin)
                       prop = varargin{i};
                       if ~ischar(prop)
                           error(message('mbc:doe:InvalidProperty'))
                       end
                       v = varargin{i+1};
                       D.(prop) = v;
                   end
               elseif nargin>1
                   error(message('mbc:doe:InvalidArgument', class( D )))
               end
           else
               % make some design object
               D.Object = xregdesign;
           end
        end
        
    end
    methods 
        function [OK,loc] = ismember(D1,D2)
            %ISMEMBER matches designs by design name
            %
            % [OK,loc] = ismember(D1,D2)
            if isempty(D1)
                D1 = {};
            elseif isa(D1,'mbcdoe.design')
                D1 = {D1.Name};
            end
            if isempty(D2)
                D2 = {};
            elseif isa(D2,'mbcdoe.design')
                D2 = {D2.Name};
            end

            [OK,loc] = ismember(D1,D2);
        end
        
        function value = get.Name(D)
            %GET.NAME get name for design
            value = name(D.Object);
        end
        function D = set.Name(D,value)
            %SET.NAME set name for design
            
            if ~ischar(value)
                error(message('mbc:doe:InvalidValue'))
            end
            D.Object = name(D.Object,value);
        end
        function value = get.Type(D)
            %GET.TYPE get type for design
            value = getType(D.Object);
        end
        
        function D= set.Type(D,NewType)
            if any(strcmp(NewType,getAlternativeTypes(D)))
                D.Object = changeType(D.Object,NewType);
            else 
                error(message('mbc:doe:InvalidValue1'))
            end
        end

        function CLS = get.Style(D)
            %GET.STYLE get style for design
            CLSID = DesignType(D.Object);
            switch CLSID
                case 0
                    CLS = 'User-defined';
                case 1
                    CLS = 'Optimal';
                case 2
                    CLS = 'Space-filling';
                case 3
                    CLS = 'Classical';
                case 4
                    CLS = 'Experimental Data';
                otherwise
                    error(message('mbc:mbcdoe:InvalidState'))
            end
            
        end

        function mdl = get.Model(D)
            %GET.MODEL get model for design
            m = model(D.Object);
            % initialise model with design
            X = factorsettings(D.Object);
            m = InitStore(m,X);
            mdl = mbcmodel.CreateModel( m );
        end
        function D = set.Model(D,mdl)
            %SET.MODEL set model for design

            if ~isa(mdl,'mbcmodel.model')
               error(message('mbc:doe:InvalidValue2'))
            end         
            
            % check inputs
            if D.NumberOfInputs==mdl.NumberOfInputs
                m = mdl.Object;
                OldModel = model(D.Object);
                m = copymodel(OldModel,m);
                D.Object = model(D.Object,m);
                
                if strcmp(D.Style,'Optimal') && ~isa(D.Object,'des_respsurf')
                    % change to a custom type if optimal is no longer valid
                    D.Object = DesignType(D.Object,0,'');
                end
            else
                error(message('mbc:doe:InvalidValue3'))
            end         
        end
        
        function Inputs = get.Inputs(D)
            %GET.INPUTS get model for design
            m = model(D.Object);
            Inputs = mbcmodel.modelinput( getInputs(m) );
        end
        function D = set.Inputs(D,Inputs)
            %SET.MODEL set model for design
            if ~isa(Inputs,'mbcmodel.modelinput')
               error(message('mbc:doe:InvalidValue4'))
            end
            % check inputs
            if D.NumberOfInputs==length(Inputs)
                Inp = mbcinputfactor(Inputs);
                m = model(D.Object);
                m = setInputs(m,Inp);
                D.Object = model(D.Object,m);
            else
                error(message('mbc:doe:InvalidValue5'))
            end
        end
        
        function value = get.NumberOfInputs(D)
            %GET.NUMBEROFFACTORS get number of factors for design
            value = nfactors(D.Object);
        end
        function value = get.NumberOfPoints(D)
            %GET.NUMBEROFPOINTS get number of points in design
            value = size(D.Points,1);
        end
        
        function value = get.PointTypes(D)
            %GET.POINTTYPES get fixed points for design
            f = getuserfixed(D.Object);
            d = getdatapoint(D.Object);
            value = repmat({'free'},size(f));
            value(f) = {'fixed'};
            value(d) = {'data'};
        end
        function D = set.PointTypes(D,value)
            %SET.POINTTYPES set fixed points for design
            
            value = value(:);
            if ~iscellstr(value) || length(value)~=D.NumberOfPoints || ~all(ismember(value,{'free','fixed','data'})) 
               error(message('mbc:doe:InvalidValue6', D.NumberOfPoints))
            end

            if ~isequal( strcmp(value,'data'),strcmp(D.PointTypes,'data') )
               error(message('mbc:doe:InvalidValue7'))
            end
            f = strcmp(value,'fixed');
            D.Object = setuserfixed(D.Object,f);
        end
        function value = get.Points(D)
            %GET.POINTS get DesignMatrix for design
            m = model(D.Object);
            value = invcode(m,factorsettings(D.Object));
        end

        function D = set.Points(D,value)
            %SET.POINTS set DesignMatrix for design
            
            if isnumeric(value) && size(value,2)==D.NumberOfInputs 
                if ~isequal(value,D.Points)
                    m = model(D.Object);
                    D.Object = factorsettings(D.Object,code(m,value));
                end
            else
                error(message('mbc:doe:InvalidValue8', D.NumberOfInputs))
            end
        end

        
        function value = get.Generator(D)
            %GET.PROPERTIES get properties object for design
            value = mbcdoe.generator(D.Object);
        end
        function D = set.Generator(D,value)
            %SET.PROPERTIES set properties object for design
            %            
            % can't change type and must support number of inputs
            if ~isa(value,'mbcdoe.generator') || ~isscalar(value)
               error(message('mbc:doe:InvalidValue9'))
            end
            
            if value.NumberOfInputs ~= D.NumberOfInputs
                error(message('mbc:doe:InvalidValue10'))
            end
            TypeChanged = ~strcmp(value.Type,D.Type);
            if TypeChanged
                % change type
                D.Type = value.Type;
            end
            % we need to do a copy of design properties rather than replace
            % the xregdesign object
            [NewObj,Changed] = copypoints(value,D.Object);
            if TypeChanged || Changed 
                if DesignType(NewObj) < 1 || DesignType(NewObj)>3
                    error(message('mbc:doe:InvalidDesign'))
                end

                if value.NumberOfPoints>0
                    % make sure next design mode is set correctly
                    D.Object = generate(NewObj,NextDesignMode(NewObj));
                elseif strcmp(NextDesignMode(NewObj),'replace')
                    D.Object = safechange(NewObj,@clear);
                end
            end
        end
        
        function con = get.Constraints(D)
            %GET.CONSTRAINTS get design constraints for design
            
            con = constraints(D.Object);
            if ~isempty(con)
                % make designconstraints object
               con = designconstraint(con); 
            else
                con = mbcdoe.designconstraint.empty;
            end
            
        end        
        function D = set.Constraints(D,value)
            %SET.CONSTRAINTS set design constraints for design
            
            
            if isa(value,'mbcboundary.AbstractBoundary')
                c = cell(1,length(value));
                for i=1:numel(value)
                    c{i} = designconstraint(value(i));
                end
                value = [c{:}];
            end
            if ~isempty(value) && ~isa(value,'mbcdoe.designconstraint')
                error(message('mbc:doe:InvalidValue11'))
            end
            
            descon = constraints(D.Object);
            des = D.Object;
            if isempty(value)
                % clear constraints
                newdescon  = [];
            else
                cif = coninputfactor( model(D.Object) );
                nf = length(cif);
                c = cell(size(value));
                for i=1:length(value)
                    % get underlying constraints objects
                    c{i} = dataobject( value(i) );
                    if nf~=nFactors(c{i})
                        error(message('mbc:doe:InvalidValue12', i, nf))
                    end
                    % check inputs
                    if ~isequal(cif,getInputFactors(c{i}))
                        % copy inputs
                        c{i} = setMatchedFactors(c{i},cif);
                    end
                end
                if builtin('isempty',descon)
                    % build constraint object
                    f= factors(D.Object);
                    descon= des_constraints(f);
                end
                newdescon = constraints(descon,c);
            end
            if ~isequal(newdescon,descon)
                des = safechange(des,@(des) constraints(des,newdescon));
                des = safechange(des,@applyconstraints);
            end
            D.Object = des;
        end
        
        function D = CreateDesign(D,varargin)
            %CREATEDESIGN create a new design object based on existing design
            %
            % D = CreateDesign(D);
            % D = CreateDesign(D,prop1,value1,...);
            
            D = mbcdoe.design(D.Object,varargin{:});
        end
        
        function c = CreateCandidateSet(D,varargin)
            %CREATECANDIDATESET create a new candidate set for use with design
            %
            % D = CreateCandidateSet(D);
            % D = CreateCandidateSet(D,prop1,value1,...);
            
            if ~isscalar(D)
                error(message('mbc:doe:InvalidState1'))
            end
            
            des = D.Object;
            c = candspace(des);
            m = model(des);
            c = mbcdoe.candidateset(c,m);
            if nargin>1 && mod(nargin,2)==1
                for i=1:2:length(varargin)
                    prop = varargin{i};
                    if ~ischar(prop)
                        error(message('mbc:doe:InvalidProperty'))
                    end
                    v = varargin{i+1};
                    c.(prop) = v;
                end
            elseif nargin>1
                error(message('mbc:doe:InvalidArgument', class( D )))
            end
        end
        
        
        function D = Generate(D,varargin)
            %GENERATE generate new design points
            %
            % D = Generate(D,Npts);
            %       generates Npts using the current generator settings.
            % D = Generate(D);
            %       generates a new design with the current generator settings.
            % D = Generate(D,'Prop1',value1,...);
            %       generates a new design with the generator specified by
            %       the generator property value pairs
            % The current generator for the design object is used as the
            % starting generator for all calls to Generate.
            %
            % See also Augment, Generator

            
            if ~isscalar(D)
                error(message('mbc:doe:InvalidState2'))
            end

            
            D.Object = NextDesignMode(D.Object,'replace');
            if nargin==2 && isnumeric(varargin{1})
                switch DesignType(D.Object)
                    case {0,4}
                        error(message('mbc:doe:InvalidDesignType'))
                end
                D = genProperties(D,'NumberOfPoints',varargin{1});
            elseif nargin>1              
                switch DesignType(D.Object)
                    case {0,4}
                        error(message('mbc:doe:InvalidDesignType'))
                end
                D = genProperties(D,varargin{:});
            else
                if DesignType(D.Object) < 1 || DesignType(D.Object)>3
                    error(message('mbc:doe:InvalidDesign1'))
                end
                if D.NumberOfPoints>0
                    D.Object = generate(D.Object,'replace');
                end
            end
            
        end

        function D = Augment(D,varargin)
            %AUGMENT augment design using a design generator
            %
            % D = Augment(D,Npts);
            %   augments the design with Npts using the current
            %   generator settings.
            % D = Augment(D,'Prop1',value1,...);
            %   augments the design with the generator specified by
            %   the generator property value pairs
            % 
            % The current generator for the design object is used as the
            % starting generator for all calls to Augment. After augmenting
            % a design, the design Style is set to 'Custom' unless an
            % optimal design is used for augmentation, as in the Design
            % Editor.  
            %
            % You can use the Augment method to add points to an existing
            % type using a different design type. 
            % OptDesign = Augment(OptDesign,...
            %     'Type','V-optimal',...
            %     'MaxIterations',200,...
            %     'NoImprovement', 50,...
            %     'NumberOfPoints',20);
            %
            % To set all designs points to fixed and then augment an
            % existing design optimally, use the FixPoints method to fix
            % all the points as follows:
            %
            % OptDesign = FixPoints(OptDesign);
            % OptDesign = Augment(OptDesign,...
            %     'Type','V-optimal',...
            %     'MaxIterations',200,...
            %     'NoImprovement', 50,...
            %     'NumberOfPoints',20);
            %
            % When augmenting with an optimal design generator existing
            % points which are not fixed may be changed. To add points
            % optimally and keep only fixed points, use RemovePoints before
            % augmenting, e.g.,
            %
            % OptDesign = RemovePoints(OptDesign,'free');
            % OptDesign = Augment(OptDesign,...
            %     'Type','V-optimal',...
            %     'MaxIterations',200,...
            %     'NoImprovement', 50,...
            %     'NumberOfPoints',20);
            %
            % To get a candidate set object for use with an optimal design:
            %
            % C = CreateCandidateSet(OptDesign,'Type', 'Grid',...
            %        'NumberOfLevels',[21 21 21]);
            %
            % You see an error if you try to call Augment when the design
            % Style is User-defined or Experimental data.
            %
            % See also Generate, FixPoints, RemovePoints, Generator
            
            if ~isscalar(D)
                error(message('mbc:doe:InvalidState3'))
            end
            
            

            AugmentType = D.Type;
            Args = varargin;
            if nargin==2 && isnumeric(varargin{1})
                switch DesignType(D.Object)
                    case {0,4}
                        error(message('mbc:doe:InvalidDesignType2'))
                end
                Args = {'NumberOfPoints',varargin{1}};
            elseif nargin>1 && rem(nargin,2) == 1
                % find augmentation type
                TypeDef = find(strcmp(Args(1:2:end),'Type'));
                if ~isempty(TypeDef)
                    AugmentType = Args{TypeDef+1};
                end
            else
                error(message('mbc:doe:InvalidArguments'))
            end
            if any(strcmp(AugmentType,getAlternativeTypes(D,'Optimal')))
                % optimal augmentation
                D.Object = NextDesignMode(D.Object,'add');
                D = genProperties(D,Args{:});
                D.Object = NextDesignMode(D.Object,'replace');
            else
                % generate new design and conctenate
                Dnew = Generate(D,Args{:});
                D.Points = [D.Points;Dnew.Points];
            end
            
        end
        
        function design = ConstrainedGenerate( design, NumPoints, varargin )
            %CONSTRAINEDGENERATE generate design of specified size in constrained region
            % 
            % design = ConstrainedGenerate( design, NumPoints, 'UnconstrainedSize', Size,...
            %                  'MaxIter',10  )
            % design = ConstrainedGenerate( design, NumPoints, OPTIONS )
            %   OPTIONS structure containing properties for constrained
            %   generation search
            %    OPTIONS.MaxIter             Default = 10
            %    OPTIONS.UnconstrainedSize   Default = NumPoints
            %
            % Algorithm: ConstrainedGenerate produces a sequence of calls
            % to Generate and updates the UnconstrainedSize using the
            % formula:
            %    UnconstrainedSize = ceil(UnconstrainedSize * NumPoints/D.NumberOfPoints);
            % This method only works for space-filling designs.
            
            
            if ~isscalar(design)
                error(message('mbc:doe:InvalidState4'))
            end

            
            if ~strcmp(design.Style,'Space-filling')
               error(message('mbc:doe:InvalidState5'))
            end
            
            OPTS.MaxIter = 10;
            OPTS.UnconstrainedSize = NumPoints;
            if nargin==3 && isstruct(varargin{1})
                % options structure
                NewOpts = varargin{1};
                f = fieldnames(NewOpts);
                for i=1:length(f)
                    OPTS.(f{i}) = NewOpts.(f{i});
                end
            elseif nargin>2
                % property value pairs
                for i=1:2:length(varargin)
                    OPTS.(varargin{i}) = varargin{i+1};
                end
            end
            
            nextGuess = OPTS.UnconstrainedSize;
            design = Generate( design, nextGuess );
            % this is the number of unconstrained points
            actualNumber = design.NumberOfPoints;
            % keep going till we get the right number - should have some limit on number of tries!
            iter=0;
            while actualNumber~=NumPoints && iter<OPTS.MaxIter
                nextdesign = Generate( design, nextGuess );
                actualNumber = nextdesign.NumberOfPoints;
                if abs(actualNumber-NumPoints)<abs(design.NumberOfPoints-NumPoints)
                    design = nextdesign;
                end
                nextGuess = ceil(nextGuess * NumPoints/max(actualNumber,1));
                iter= iter+1;
            end
            
        end
        
        function D = Merge(D,varargin)
            %MERGE merge a number of designs
            % 
            % D = Merge(D1,D2,...);
            %     The resulting design is a custom design
            
            if ~isscalar(D)
                error(message('mbc:doe:InvalidState6'))
            end
            for i=1:nargin-1
                if ~isscalar(varargin{i})
                    error(message('mbc:doe:InvalidState7'))
                end
                varargin{i}= dataobject(varargin{i});
            end
            D.Object = mergedesigns(D.Object,varargin{:});
        end
        
        function s = Minimax(D)
            %MINIMAX minimum of maximum distances between design points
            % 
            % s = Minimax(D);
            %     minimax is defined over the unconstrained design and is
            %     only available for space-filling designs
            
            if ~isscalar(D)
                error(message('mbc:doe:InvalidState8'))
            end
            if strcmp( D.Style,'Space-filling')
                [t,c] = DesignType(D.Object);
                s = maxdist(c);
            else
                error(message('mbc:doe:InvalidState9'))
            end

        end
        function s = Maximin(D)
            %MAXIMIN maximum of minimum distances between design points
            %
            % s = Maximin(D);
            %     maximin is defined over the unconstrained design and is
            %     only available for space-filling designs

            if ~isscalar(D)
                error(message('mbc:doe:InvalidState10'))
            end
            
            if strcmp( D.Style,'Space-filling')
                [t,c] = DesignType(D.Object);
                s = mindist(c);
            else
                error(message('mbc:doe:InvalidState11'))
            end

        end

        function s = Discrepancy(D)
            %DISCREPANCY
            %
            % s = Discrepancy(D);
            %     discrepancy is defined over the unconstrained design and is
            %     only available for space-filling designs
            
            if ~isscalar(D)
                error(message('mbc:doe:InvalidState12'))
            end
            if strcmp( D.Style,'Space-filling')
                [t,c] = DesignType(D.Object);
                s = discrep(c);
            else
                error(message('mbc:doe:InvalidState13'))
            end
        end
        
        function s = OptimalCriteria(D,criteria)
           %OPTIMALCRITERIA optimal design criteria [V,D,A,G]
           % 
           % s = OptimalCriteria(D);
           %      returns an array with [V,D,A,G]
           % s = OptimalCriteria(D,Criteria);
           %    Criteria must be one of 'V','D','A','G'.
           %  OptimalCriteria can only be used for optimal designs
           
            if ~isscalar(D)
                error(message('mbc:doe:InvalidState14'))
            end
            des = D.Object;
            if isoptimised(des)
                if nargin<2
                    criteria  = {'V','D','A','G'};
                elseif ischar(criteria)
                    criteria = {criteria};
                end
                s = zeros(size(criteria));
                for i= 1:length(criteria)
                    switch upper(criteria{i})
                        case 'V'
                            [s(i),des] = vcalc(des,1);
                        case 'D'
                            [s(i),des] = dcalc(des,1);
                        case 'A'
                            [s(i),des] = acalc(des,1);
                        case 'G'
                            [s(i),des] = gcalc(des,1);
                        otherwise
                            error(message('mbc:doe:InvalidArgument2'))
                    end
                end
                D.Object = des;
            else
                error(message('mbc:doe:InvalidState15'))
            end
            
        end
        
        function c = CreateConstraint(D,varargin)
            %CREATECONSTRAINT create a constraint for use in the design
            %
            % c = CreateConstraint(D);
            % c = CreateConstraint(D,prop1,val1,...);
            %   By default a 1D table constraint is created for designs
            %   with two or more inputs. For a design with one input a
            %   linear constraint is created. It is possible to specify the
            %   constraint type during creation by using the type property.
            %   For example:
            %         c = D.CreateConstraint('Type','Linear');
            %   Note that the constraint is not added to the design. It is
            %   necessary to explicitly add the constraint to the design
            %   using the Constraints property of the design:
            %         D= AddConstraint(D,c);
            %   or 
            %         D.Constraints(end+1) = c;
            %
            % See also AddConstraint, Constraints
              
            if ~isscalar(D)
                error(message('mbc:doe:InvalidState16'))
            end
            des = D.Object;
            cif = coninputfactor( model( des ) );
            if nfactors(des)>1
                con = contable1( cif );
            else
                con = conlinear( cif );
            end
            
            c = mbcdoe.designconstraint(con,varargin{:});
        
        end
        
        
        function D = AddConstraint(D,c)
            %ADDCONSTRAINT add a constraint to design
            % 
            % D = AddConstraint(D,c);
            %   c is a mbcdoe.designconstraint or a boundary model object.
            %   A boundary model is converted to a mbcdoe.designconstraint  
            %
            % See also CreateConstraint, Constraints, mbcboundary.AbstractBoundary.designconstraint

            if isa(c,'mbcboundary.AbstractBoundary')
                % convert to designconstraint
                c = designconstraint(c);
            end
            if ~isscalar(D) || ~isa(D,'mbcdoe.design')
                error(message('mbc:doe:InvalidState17'))
            end
            
            D.Constraints = [D.Constraints  c];
        end
            
        function varargout = Scatter2D(D,v1,v2,varargin)
            %SCATTER2D 2D scatter plot of design
            %
            % Scatter2D(D,xindex,yindex)
            % % Scatter2D(D,xindex,yindex,varargin)
            %    D: mbcdoe.design object
            %    X: index or symbol for  input factor to be plotted on the X axis
            %    Y: index or symbol for input factor to be plotted on the Y axis
            %    varargin: additional arguments to plot command. The plot
            %              command used in Scatter2D is
            %                plot(D.Points(:,v1),D.Points(:,v2),varargin{:})
            %              The default for varargin is '.'.
            
            if ~isscalar(D)
                error(message('mbc:doe:InvalidState18'))
            end
            if nargin<3
                v1 = 1;
                v2 = 2;
            end
            s = {D.Inputs.Symbol};
            if ischar(v1)
                v1 = find(strcmp(v1,s));
                if isempty(v1)
                    error(message('mbc:doe:InvalidValue13'))
                end
            end
            if ischar(v2)
                v2 = find(strcmp(v2,s));
                if isempty(v2)
                    error(message('mbc:doe:InvalidValue14'))
                end
            end
            if ~isnumeric(v1) || ~isscalar(v1) || v1 < 1 || v1> D.NumberOfInputs || v1~=fix(v1)
                error(message('mbc:doe:InvalidValue15'));
            end
            if ~isnumeric(v2) || ~isscalar(v2) || v2 < 1 || v2> D.NumberOfInputs || v2~=fix(v2)
                error(message('mbc:doe:InvalidValue16'));
            end
            if nargin<4
                varargin{1}= '.';
            end
            inputs = D.Inputs;
            X = D.Points;
            h = plot( X(:,v1), X(:,v2), varargin{:} );
            xlabel( inputs(v1).label );
            ylabel( inputs(v2).label );
            title( D.Name );
            axis( [inputs(v1).Range, inputs(v2).Range] );
            grid on
            if nargout
               varargout= {h}; 
            end
        end
        
        function D = RemovePoints(D,PointType)
            %REMOVEPOINTS remove points from a design
            % 
            % D = RemovePoints(D);
            % D = RemovePoints(D,PointType);
            % D = RemovePoints(D,Indices);
            %       PointType is one of 'free','fixed' or 'data'
            %
            % See also PointTypes
           
            if ~isscalar(D)
                error(message('mbc:doe:InvalidState19'))
            end
            if nargin>1
                if ischar(PointType)
                    ind = find( strcmp(D.PointTypes,PointType) );
                else
                    ind = PointType;
                end
                D.Object= safechange(D.Object,@(d) delete(d,'indexed',ind));
            else
                D.Object= safechange(D.Object,@clear);
            end
        end
        
        function D = FixPoints(D,ind)
            %FIXPOINTS fix points in design
            %
            % D = FixPoints(D); 
            %    fix all points
            % D = FixPoints(D,indices);
            %    fix all points at indices
            % Fixed points are not altered when the design is augmented
            % with an optimal design.
            %
            % See also Augment, PointTypes

            if ~isscalar(D)
                error(message('mbc:doe:InvalidState20'))
            end
            if nargin<2
                ind = ~strcmp(D.PointTypes,'data');
            end
            D.PointTypes(ind) = {'fixed'};
        end

        function list = getAlternativeTypes(D,Style)
            %GETALTERNATIVETYPES list of design types 
            % 
            % list = getAlternativeTypes(D)
            %   The list is a list of design types which could be used as
            %   alternative designs for current design. 
            % list = getAlternativeTypes(D,Style)
            %   returns a list of design types of the specified
            %   Style. The design Style must be one of
            %   'Space-Filling', 'Classical' or 'Optimal'.
            %
            % See also Type, mbcdoe.design
            
            if ~isscalar(D)
                error(message('mbc:doe:InvalidState21'))
            end
            des = D.Object;
            nf = D.NumberOfInputs;
            if nargin>1
                switch Style
                    case 'Space-Filling'
                       list = mbcdoe.SpaceFillingDesignTypes(nf);
                    case 'Classical'
                        list = mbcdoe.ClassicalDesignTypes(nf);
                    case 'Optimal'
                        des = D.Object;
                        if isa(designobj(model(des)),'des_respsurf')
                            list = mbcdoe.OptimalDesignTypes(nf);
                        else 
                            list = {};
                        end
                    otherwise
                        error(message('mbc:doe:InvalidValue17'))
                end
                        
            else
                list = {'User-defined'};
                if isa(designobj(model(des)),'des_respsurf')
                    list = [list;mbcdoe.OptimalDesignTypes(nf)];
                end
                list = [list
                    mbcdoe.SpaceFillingDesignTypes(nf);
                    mbcdoe.ClassicalDesignTypes(nf)];
            end
        end
        
    end
    methods (Static)
        function Type = DefaultType(nf)
            if nf==1
                Type = 'Full Factorial';
            else
                Type = 'Sobol Sequence';
            end
        end
    end
        
end

function D = genProperties(D,varargin)
P = D.Generator;
if mod(nargin,2)~=1
    error(message('mbc:doe:InvalidProperty2'))
end
for i=1:2:length(varargin)
    prop = varargin{i};
    if ~ischar(prop)
        error(message('mbc:doe:InvalidProperty'))
    end
    value = varargin{i+1};
    P.(prop) = value;
end
D.Generator = P;
end