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