我可以防止Matlab动态调整预分配数组的大小吗?

问题描述:

例如,在这个简单/愚蠢的示例中:

For example, in this simple/stupid example:

n = 3;
x = zeros(n, 1);
for ix=1:4
    x(ix) = ix;
end

该数组是预先分配的,但会在循环中动态调整大小. Matlab中是否有设置会在发生这样的动态调整大小时引发错误?在这个例子中,我可以简单地重写它:

the array is pre-allocated, but dynamically resized in the loop. Is there a setting in Matlab that will throw an error when dynamic resizing like this occurs? In this example I could trivially rewrite it:

n = 3;
x = zeros(n, 1);
for ix=1:4
    if ix > n
        error('Size:Dynamic', 'Dynamic resizing will occur.')
    end
    x(ix) = ix;
end

但是我希望以此作为检查,以确保正确分配了我的矩阵.

but I'm hoping to use this as a check to make sure I've pre-allocated my matrices properly.

您可以创建double的子类,并在subsasgn方法中限制分配:

You can create a subclass of double and restrict the assignment in subsasgn method:

classdef dbl < double
    methods
        function obj = dbl(d)
            obj = obj@double(d);
        end

        function obj = subsasgn(obj,s,val)
            if strcmp(s.type, '()')
                mx = cellfun(@max, s.subs).*~strcmp(s.subs, ':');
                sz = size(obj);
                nx = numel(mx);
                if nx < numel(sz)
                    sz = [sz(1:nx-1) prod(sz(nx:end))];
                end
                assert(all( mx <= sz), ...
                    'Index exceeds matrix dimensions.');
            end
            obj = subsasgn@double(obj, s, val);
        end

    end
end

所以现在当您进行预分配时,请使用dbl

So now when you are preallocating use dbl

>> z = dbl(zeros(3))
z = 
  dbl

  double data:
     0     0     0
     0     0     0
     0     0     0
  Methods, Superclasses

double的所有方法现在都由dbl继承,您可以照常使用它,直到为z

All methods for double are now inherited by dbl and you can use it as usual until you assign something to z

>> z(1:2,2:3) = 6
z = 
  dbl

  double data:
     0     6     6
     0     6     6
     0     0     0
  Methods, Superclasses

>> z(1:2,2:5) = 6
Error using dbl/subsasgn (line 9)
Index exceeds matrix dimensions.

我尚未对其进行基准测试,但我希望这不会对性能产生影响.

I haven't benchmarked it but I expect this to have insignificant performance impact.

如果您希望值的显示看起来正常,那么也可以重载display方法:

If you want the display of the values look normal you can overload the display method as well:

function display(obj)
    display(double(obj));
end

然后

>> z = dbl(zeros(3))
ans =
     0     0     0
     0     0     0
     0     0     0
>> z(1:2,2:3) = 6
ans =
     0     6     6
     0     6     6
     0     0     0
>> z(1:2,2:5) = 6
Error using dbl/subsasgn (line 9)
Index exceeds matrix dimensions.
>> class(z)
ans =
dbl