www.gusucode.com > mbc 工具箱 matlab 源码程序 > mbc/+mbcboundary/AbstractBoundary.m
classdef AbstractBoundary < mbcutils.abstractdataobject %MBCBOUNDARY.ABSTRACTBOUNDARY base command-line boundary model class % The mbcboundary.AbstractBoundary model is the base class for all % boundary model classes in the Model-Based Calibration toolbox % software. There should not be any instances of this class. % % mbcboundary.AbstractBoundary properties: % Name - name of boundary model (read only) % NumberOfInputs - number of inputs (read only) % Type - boundary model type (read only) % Inputs - boundary model inputs % FitAlgorithm - fit algorithm for boundary model % Fitted - indicates whether boundary model has been fitted (read only) % % mbcboundary.AbstractBoundary methods: % CreateBoundary - create a new boundary model % getAlternativeTypes - list of alternative boundary model types % Evaluate - evaluate boundary model % designconstraint - convert boundary model to a design constraint % % Boundary models can be combined using the logical operators &, | and ~. % Copyright 2009-2011 The MathWorks, Inc. properties (Dependent,SetAccess=protected) %NAME Name of boundary model (read only) Name %NUMBEROFINPUTS Number of inputs (read only) % The number of boundary model inputs are set on creation of the % boundary model. % % See also Inputs, mbcboundary.CreateBoundaryModel NumberOfInputs %TYPE Boundary model type (read only) % The boundary model type is set on creation with CreateBoundaryModel. % The list of valid types is specified by getAlternativeTypes. % %See also getAlternativeTypes, CreateBoundaryModel Type end properties (Dependent,AbortSet) %INPUTS boundary model inputs % Boundary model inputs are an array of mbcmodel.modelinput objects. % The number of boundary model inputs are set on creation of the % boundary model. The name, symbol and range of the inputs can % be changed. % %See also NumberOfInputs, mbcmodel.modelinput Inputs %FITALGORITHM fit algorithm for boundary model % FitAlgorithm is a mbcmodel.fitalgorithm object. FitAlgorithm end properties (Access=protected) %pFitAlgorithm actual storage for FitAlgorithm pFitAlgorithm end properties (SetAccess=protected) %FITTED indicates whether boundary model has been fitted (read only) % Fitted must be true before the boundary model can be evaluated. % %See also Evaluate Fitted = false; end methods (Hidden) function B = AbstractBoundary(con,opts,Status,varargin) %AbstractBoundary - constructor not intended for public calls if nargin B = pInitialise(B,con); B = mbcSetPropValuePairs(B,varargin{:}); end if nargin>1 % create and store a fit algorithm object if ~isempty(opts) && isnull(opts) opts = []; end B.pFitAlgorithm = mbcmodel.fitalgorithm(opts,B); end if nargin>=3 B.Fitted = Status~=0; end end function UpdateTree(B,bdev) %UPDATETREE update boundary tree object % % This is the main method to update the boundary tree in % mbcmodel projects. mbcboundary.AbstractBoundary.assertScalar(B) con = B.Object; if ~isempty(B.FitAlgorithm) opts = getObject(B.FitAlgorithm); else opts = []; end if isempty(opts) % use default fit options opts = getFitOptions(con); end if getstages(bdev)==2 stage = 2; else stage = 0; end if ~isequal(getInputFactors(con),getInputFactors(bdev,stage)) % check inputs error('mbc:mbcboundary:AbstractBoundary:InvalidValue',... 'The boundary model has incompatible inputs with the boundary tree.') end % check type ClassNames = BoundaryClasses(bdev); if ~any(strcmp(class(B.Object),ClassNames )) % check that the boundary model type is valid. OptionNames = cell(1,length(ClassNames)); for i=1:length(ClassNames) OptionNames{i} = typename(feval(ClassNames{i})); end error(message('mbc:mbcboundary:AbstractBoundary:InvalidValue1', mbcListString( OptionNames, ' ', 'or' ))) end %set it and fit it - boundary models are always refitted when %updating the tree bdev = setupConstraint(bdev,con, opts); fitConstraint(info(bdev),'all'); end end methods %get and set methods function v = get.Name(obj) v = tostring(obj.Object); end function v = get.Inputs(obj) cif = getInputFactors(obj.Object); Inputs = mbcinputfactor(cif); v = mbcmodel.modelinput(Inputs); end function B = set.Inputs(B,Inputs) if isa(Inputs,'mbcmodel.modelinput') && length(Inputs)==B.NumberOfInputs cif = coninputfactor( mbcinputfactor(Inputs) ); B.Object = setInputFactors(B.Object,cif); else error(message('mbc:mbcboundary:AbstractBoundary:InvalidValue2')) end end function v = get.NumberOfInputs(obj) v = nFactors(obj.Object); end function v = get.Type(obj) v= typename(obj.Object); end function B = set.FitAlgorithm(B,OPTS) if ~isempty(B.Object) OldValue = B.FitAlgorithm; if ischar(OPTS) && isa(OldValue,'mbcmodel.fitalgorithm') % create algorithm from string OPTS = CreateAlgorithm(OldValue,OPTS); end if ~isscalar(OPTS) || ~isa(OPTS,'mbcmodel.fitalgorithm') error(message('mbc:mbcboundary:AbstractBoundary:InvalidArgument')) elseif ~(isempty(OldValue) || IsAlternative(OPTS,OldValue)) % this doesn't work due to change of types error(message('mbc:mbcboundary:AbstractBoundary:InvalidArgument1', B.Type)) end end B.pFitAlgorithm = OPTS; B.Fitted = false; end function OPTS = get.FitAlgorithm(B) if isempty(B.pFitAlgorithm) % create a new default fit object when required opts = getFitOptions(B.Object,'all'); if ~isempty(opts) && isnull(opts) opts = []; end OPTS = mbcmodel.fitalgorithm( opts ,B); else OPTS = B.pFitAlgorithm; end end function y = Evaluate(B,X) %EVALUATE evaluate boundary model % y = Evaluate(B,X); % X is a matrix with B.NumberOfInputs columns. % All boundaries are of the form g(x)=0. A positive value % indicates that the point is outside the boundary. % A boundary model must be fitted before it can be % evaluated. % %See also Fitted mbcboundary.AbstractBoundary.assertScalarFitted(B); if nargin<2 || ~isa(X,'double') || ~size(X,2)==B.NumberOfInputs error(message('mbc:mbcboundary:AbstractBoundary:InvalidValue3', obj.NumberOfInputs)) end y = constraintDistance(B.Object,X); end function [OptionNames,ObjectIndex,OptionObjects] = getAlternativeTypes(obj) %GETALTERNATIVETYPES list of boundary model types % Types = getAlternativeTypes(obj); % Types is a list of boundary model types which could be % used as alternative boundary model types for the current % boundary model. % %See also Type, CreateBoundaryModel % undocumented % [OptionNames,ObjectIndex,OptionObjects] = getAlternativeTypes(obj) mbcboundary.AbstractBoundary.assertScalar(obj) c = obj.Object; if ~isempty(c) opts = BoundaryClasses(obj); [OptionObjects, OptionNames, ObjectIndex] = pGenerateObjectList(c, opts); OptionNames = OptionNames(:); else error(message('mbc:mbcboundary:AbstractBoundary:InvalidState', class( obj ))) end end function C = designconstraint(C) %DESIGNCONSTRAINT convert boundary model to a design constraint % C = designconstraint(C) % To use a boundary model as a design constraint you must % convert it to a mbcdoe.designconstraint object. The % boundary model must be fitted (Fitted=true) before it can % be converted to a design constraint. % %See also mbcdoe.designconstraint, mbcdoe.design.AddConstraint mbcboundary.AbstractBoundary.assertScalarFitted(C); C = mbcdoe.designconstraint(C.Object); end function B = CreateBoundary(B,Type,varargin) %CREATEBOUNDARY create boundary model from existing model % NEWMODEL = CreateBoundary(MODEL,Type); % NEWMODEL = CreateBoundary(MODEL,Type,Property,Value,...); % A new boundary model with the same inputs as the current % boundary model MODEL is created. You can get a list of valid % types with getAlternativeTypes. Property, value pairs can be % used to set properties of the boundary model. % %See also getAlternativeTypes, mbcboundary.CreateBoundary narginchk(1,Inf) mbcboundary.AbstractBoundary.assertScalar(B) [OptionNames,~,OptionObjects] = getAlternativeTypes(B); Index = strcmp(Type,OptionNames); if any(Index) con = OptionObjects{Index}; try B = pInitialise(B,con); B = mbcSetPropValuePairs(B,varargin{:}); catch ME createME = MException('mbc:mbcboundary:AbstractBoundary:InvalidType',... 'Error creating new boundary model type'); createME = createME.addCause(ME); throw(createME) end else list = mbcListString(OptionNames,' ','or'); if length(list)>1 error(message('mbc:mbcboundary:AbstractBoundary:InvalidType', list)) elseif length(list)==1 error(message('mbc:mbcboundary:AbstractBoundary:InvalidType1', list)) else error(message('mbc:mbcboundary:AbstractBoundary:InvalidType2', B.Type)) end end end function B = and(B1,B2) %AND intersection of boundary constraints % B = B1 & B2; % Both B1 and B2 must be scalar and fitted before they can % be used in a logical expression. mbcboundary.AbstractBoundary.assertScalarFitted(B1); mbcboundary.AbstractBoundary.assertScalarFitted(B2,'second'); con = B1.Object & B2.Object; B = boundarymodel(con,[],true); end function B = or(B1,B2) %OR union of boundary constraints % B = B1 | B2; % Both B1 and B2 must be scalar and fitted before they can % be used in a logical expression. mbcboundary.AbstractBoundary.assertScalarFitted(B1); mbcboundary.AbstractBoundary.assertScalarFitted(B2,'second'); con = B1.Object | B2.Object; B = boundarymodel(con,[],true); end function B = not(B1) %NOT complement of boundary constraint % B = ~B1; % B1 must be scalar and fitted before it can be used in a % logical expression. mbcboundary.AbstractBoundary.assertScalarFitted(B1); con = ~B1.Object; B = boundarymodel(con,[],true); end end methods (Access=protected) function B = Reset(B) %RESET reset boundary B.Fitted = false; end function B = resetAlgorithm(B) % empty algorithm B.pFitAlgorithm = []; B = Reset(B); end function B = pInitialise(B,con) %PINITIALISE initialise boundary with new con object if isempty(B.Object) || ~isequal(con,B.Object) B.Object = con; B = resetAlgorithm(B); end end function ok = CanEvaluate(obj) %CANEVALUATE ok = obj.Fitted; end function opts = BoundaryClasses(B) %BOUNDARYCLASSES list of compatible con* classess opts = BoundaryClasses(B.Object); end end methods (Access=protected,Static) function assertScalarFitted(B,Position) %assertScalarFitted check that the boundary model is scalar and been fitted if nargin<2 Position = 'first'; end if ~(isscalar(B) && isa(B,'mbcboundary.AbstractBoundary') && CanEvaluate(B)) ME = MException('mbc:mbcboundary:AbstractBoundary:InvalidValue',... 'The %s input must be a scalar boundary model that has been fitted.',Position); % throw as caller to avoid showing this stack trace. throwAsCaller(ME) end end function assertScalar(B,Position) %assertScalar check that the boundary model is scalar if nargin<2 Position = 'first'; end if ~(isscalar(B) && isa(B,'mbcboundary.AbstractBoundary')) ME = MException('mbc:mbcboundary:AbstractBoundary:ScalarObjectRequired',... 'The %s input must be a scalar boundary model.',Position); % throw as caller to avoid showing this stack trace. throwAsCaller(ME) end end end end %classdef