例如,在这个简单/愚蠢的例子中:
n = 3;
x = zeros(n, 1);
for ix=1:4
x(ix) = ix;
end
Run Code Online (Sandbox Code Playgroud)
数组是预先分配的,但在循环中动态调整大小.在这样的动态调整大小时,Matlab中是否存在会引发错误的设置?在这个例子中,我可以轻而易举地重写它:
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
Run Code Online (Sandbox Code Playgroud)
但我希望用这个作为检查,以确保我已经预先分配了我的矩阵.
您可以double在subsasgn方法中创建子类并限制赋值:
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
Run Code Online (Sandbox Code Playgroud)
所以现在当你预先分配使用时 dbl
>> z = dbl(zeros(3))
z =
dbl
double data:
0 0 0
0 0 0
0 0 0
Methods, Superclasses
Run Code Online (Sandbox Code Playgroud)
double现在所有方法都是继承的dbl,您可以照常使用它,直到您分配内容为止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.
Run Code Online (Sandbox Code Playgroud)
我没有对它进行基准测试,但我预计这会对性能产生微不足道的影响.
如果您希望值的显示看起来正常,您也可以重载该display方法:
function display(obj)
display(double(obj));
end
Run Code Online (Sandbox Code Playgroud)
然后
>> 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
Run Code Online (Sandbox Code Playgroud)
我能想到的最简单,最直接和最健壮的方法就是在分配索引之前访问索引.不幸的是,你不能为基本类型重载subasgn(在任何情况下都是正确的头痛).
for ix=1:4
x(ix); x(ix) = ix;
end
% Error: 'Attempted to access x(4); index out of bounds because numel(x)=3.'
Run Code Online (Sandbox Code Playgroud)
或者,您可以尝试聪明并使用end关键字执行某些操作...但无论您做什么,您最终都会得到某种无意义的错误消息(上面提供的很好).
for ix=1:4
x(ix*(ix<=end)) = ix;
end
% Error: 'Attempted to access x(0); index must be a positive integer or logical.'
Run Code Online (Sandbox Code Playgroud)
或者你可以检查一个函数,它可以获得你很好的错误信息,但仍然非常冗长和混淆:
for ix=1:4
x(idxchk(ix,end)) = ix;
end
function idx = idxchk(idx,e)
assert(idx <= e, 'Size:Dynamic', 'Dynamic resizing will occur.')
end
Run Code Online (Sandbox Code Playgroud)