有没有更好的方法在MATLAB中声明一个空的、类型化的矩阵?

有没有更好的方法在MATLAB中声明一个空的、类型化的矩阵?,matlab,types,matrix,Matlab,Types,Matrix,有没有一种方法可以在MATLAB中“声明”具有特定用户定义类型的变量?zeros()仅适用于内置数字类型。我提出的唯一解决方案是使用repmat()将虚拟对象复制零次: arr = repmat(myClass(), [1 0]) 如果不以这种方式声明变量,任何执行“arr(end+1)=myClass()”的代码都必须包含默认空矩阵的特例,该矩阵的类型为double 我错过了一些更合理的东西吗?根据,所有类都有一个empty方法来创建该类的空数组。例如: arr = myClass.empt

有没有一种方法可以在MATLAB中“声明”具有特定用户定义类型的变量?zeros()仅适用于内置数字类型。我提出的唯一解决方案是使用repmat()将虚拟对象复制零次:

arr = repmat(myClass(), [1 0])
如果不以这种方式声明变量,任何执行“arr(end+1)=myClass()”的代码都必须包含默认空矩阵的特例,该矩阵的类型为double

我错过了一些更合理的东西吗?

根据,所有类都有一个
empty
方法来创建该类的空数组。例如:

arr = myClass.empty(0,0);  %# Creates a 0-by-0 array of class myClass
以下情况也是如此:


关于预分配的说明。。。 您提到将以以下方式在循环中增长此阵列:

arr(end+1) = myClass();

如果您知道数组的最终大小,那么在循环之外覆盖或修改循环中的数组元素通常会更有效。我将讨论如何在中为用户定义的类执行此操作。

这就是我所使用的。您可以使用稍微简洁的形式,它采用标量大小参数

r = repmat(MyClass, 0);
请注意,您并没有将变量声明为具有类型;它仍然只是具有类型的变量中保存的值

这将适用于旧样式和新MCOS类。如果您使用的是所有新样式的类,那么gnovice的“empty()”听起来是个好主意


如果你觉得自己进步了,还有另一个选择,为了完整性,我也加入了这个选择

您还可以在SubASGN中为您的对象处理此问题,至少对于旧式的Matlab类是这样。如果您对一个单位化变量进行索引赋值,其中RHS(“右侧”)上有一个用户定义的对象,则会调用该类的subsagn,而LHS的值为[](空双精度)。如果您有一个特殊的构造函数窗体,允许您在不调用对象上的repmat的情况下构造一个空对象,那么您可以支持它,这样用户就不必用类的对象预先分配变量

在您的subsasgn中:

function obj = subsasgn(obj, S, B)
...
s = S(1);
...
switch s.type
    case '()'
        % Handle dispatch on LHS autovivification
        if isnumeric(obj) && isa(B, mfilename('class'))
            % Must use special ctor to preallocate
            obj = feval(class(B), mxdims(size(B)));
        end
然后在构造器中,有一个后门调用表单,用于通过预先格式化的结构构造清空

function MyClass(varargin) %constructor

SuperClasses = { }; % if you inherit, fill this in

if nargin == 1 && isa(varargin{1}, 'mxdims')
   % special backdoor to support preallocation without repmat
   s = repmat(DataStructure, msize(varargin{1})); % built-in repmat called on plain struct
   out = class(s, mfilename, SuperClasses{:});
   return;
end
...
@mxdims类是您需要创建的一个特殊类,它包含一个大小向量,并用作调用此后门表单的标记。方法返回它表示的大小向量

如果您定义MyClass使其支持此功能,那么您可以只执行“s(1)=MyClass”,而无需预先分配s。但是你不能做“s(end+1)”;“结束”仅适用于预分配的值

这是Matlab的一个棘手领域。在subsasgn和这样的类型系统中工作可能会产生很多微妙的错误,包括SEGFULTS。这样做将使您的用户定义对象的行为更加“完整”。但这涉及到工作量和脆性,您最好还是坚持使用“repmat(class,0)”或“empty()”

function MyClass(varargin) %constructor

SuperClasses = { }; % if you inherit, fill this in

if nargin == 1 && isa(varargin{1}, 'mxdims')
   % special backdoor to support preallocation without repmat
   s = repmat(DataStructure, msize(varargin{1})); % built-in repmat called on plain struct
   out = class(s, mfilename, SuperClasses{:});
   return;
end
...