TL;DR:我想使用属性类验证来验证fitoptions
对象,但MATLAB抱怨道。
考虑以下类别:
% SUPERCLASS:
classdef (Abstract) BaseModel
% CWLvsT is an abstract parent class for different CWL(T) models.
properties (Abstract = true, Access = protected, Constant = true)
MODEL (1,1) string
FITOPTS (1,1) % ???
end
end
% SUBCLASS:
classdef RationalFraction < BaseModel
% This corresponds to a fit of type "rat11".
properties (Access = protected, Constant = true)
MODEL = "CWL(T) = (P1 * T + P2) / (T + Q1)";
FITOPTS = fitoptions('rat11', ...
'Lower', [-1, -1E5, -1E4], ...
'Upper', [10, 5E5, 5E4], ...
'StartPoint', [4, 0, 0]);
end
end
我想强制要求子类为FITOPTS
属性指定某种类型的fitoptions
对象(有几种类型(。
:我尝试的第一件事是创建一个示例fitoptions
对象(根据子类中的定义(,看看它的class
是什么。我得到的结果是curvefit.nlsqoptions
,所以我试着把它而不是% ???
放在超类中,并实例化RationalFraction
类,但得到了以下错误:
Error defining property 'FITOPTS' of class 'BaseModel':
Class named 'curvefit.nlsqoptions' is undefined or does not support property validation.
尝试#2:我认为上面的错误表明fitoptions
有一些超类,我应该根据它来验证对象,所以我尝试在示例对象上执行metaclass(optsObj)
,但得到了一个空的元类。通过手动搜索,我确实通过浏览MATLABR2019btoolboxcurvefitcurvefit@curvefit
文件夹curvefit.basefitoptions
找到了一个好的候选人,但这导致了类似的错误。
:我注意到fitoptions
对象离普通的struct
对象不远,所以我尝试了FITOPTS (1,1) struct
——确实成功地创建了对象。不幸的是,当稍后在尝试调用fit
时引用这个FITOPTS
字段时,我得到了以下错误:
Error using fit>iParseOptionalArgs (line 949)
Algorithm options must be specified in a FITOPTIONS object or as property-value pairs.
Error in fit (line 113)
[useroptions, useroptargs, probparams] = iParseOptionalArgs( varargin{:} );
这意味着属性验证将nlsqoptions
对象强制转换为struct
,从而丢失其包含合适选项的"额外信息"。虽然这种行为是一个有趣的发现,但在当前情况下并没有太大帮助。
:有人能提出一种执行此类验证的方法,使FITOPTS
最终包含一个fit-options对象吗?
我正在使用R2019b。
问题中出现的最后一个错误是指fit
中的949
行。如果我们查看这个文件,我们会看到"候选"fit-options对象被传递给一个名为isfitoptions
的函数,该函数检查它是否有效。
这暗示了一种不同的验证输入的机制——将它们传递给验证函数。尽管这些函数是用来验证值,而不是类的,但它们也没有理由不能用于后者。因此,如果用户可以调用MATLAB的函数,它就可以用于验证,如果不能,则可以将相同的测试(对isa
的简单调用(作为我们自己类中的方法来实现。幸运的是,这个函数在包/工具箱之外是可以访问的,下面的结果是:
properties (Abstract = true, Access = protected, Constant = true)
MODEL (1,1) string
FITOPTS (1,1) {isfitoptions}
end