代码之家  ›  专栏  ›  技术社区  ›  Arthur Ward

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

  •  5
  • Arthur Ward  · 技术社区  · 15 年前

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

    arr = repmat(myClass(), [1 0])
    

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

    我是不是错过了一些更明智的事情?

    2 回复  |  直到 15 年前
        1
  •  6
  •   Community CDub    7 年前

    根据 this documentation empty 方法创建该类的空数组。例如:

    arr = myClass.empty(0,0);  %# Creates a 0-by-0 array of class myClass
    

    这也适用于 built-in types

    a = uint8.empty(0,1);   %# A 0-by-1 uint8 array
    b = single.empty(5,0);  %# A 5-by-0 single array
    c = cell.empty(0,0);    %# A 0-by-0 cell array
    


    关于预分配的说明。。。

    arr(end+1) = myClass();
    

    preallocate the entire array 然后覆盖或修改循环中的数组元素。我将讨论如何对中的用户定义类执行此操作 an answer to another question

        2
  •  2
  •   Andrew Janke    15 年前

    我用的就是这个。您可以使用稍微简洁的形式来接受标量大小参数。

    r = repmat(MyClass, 0);
    

    请注意,您并没有将变量声明为具有类型;变量中的值仍然具有类型。

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


    如果你觉得自己进步了,还有另外一个选择,为了完整起见,我把它包括在内。

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

    在您的子任务中:

    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类是您需要创建的一个特殊类,它包含一个大小向量,并用作调用此后门窗体的标记。方法返回它所表示的大小向量。

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