我在MATLAB中有一个循环,用我的工作区(2011b,Windows 7,64位)填充单元格数组,并带有以下条目:
my_array =
[1x219 uint16]
[ 138]
[1x0 uint16] <---- row #3
[1x2 uint16]
[1x0 uint16]
[] <---- row #6
[ 210]
[1x7 uint16]
[1x0 uint16]
[1x4 uint16]
[1x0 uint16]
[ 280]
[]
[]
[ 293]
[ 295]
[1x2 uint16]
[ 298]
[1x0 uint16]
[1x8 uint16]
[1x5 uint16]
请注意,某些条目包含[]
,如行#6
,而其他条目包含[1x0]
项,如行#3
。
答案 0 :(得分:20)
在大多数案例中(例外情况见下文)没有真正的区别。两者都被认为是"empty",因为至少有一个维度的大小为0.但是,我不会将其称为错误,因为作为程序员,您可能希望在某些情况下看到此信息。
比如说,你有一个二维矩阵,你想索引一些行和一些列,以提取到一个较小的矩阵:
>> M = magic(4) %# Create a 4-by-4 matrix
M =
16 2 3 13
5 11 10 8
9 7 6 12
4 14 15 1
>> rowIndex = [1 3]; %# A set of row indices
>> columnIndex = []; %# A set of column indices, which happen to be empty
>> subM = M(rowIndex,columnIndex)
subM =
Empty matrix: 2-by-0
请注意,空结果仍会告诉您一些信息,特别是您尝试索引原始矩阵中的2行。如果结果显示为[]
,则您不知道它是否为空,因为您的行索引为空,或者您的列索引为空,或两者都是。
在某些情况下,定义为[]
的空矩阵(即其所有维度均为0)可能会给出与仍具有某些非零维度的空矩阵不同的结果。例如,矩阵乘法在处理不同类型的空矩阵时可以给出不同的(有些非直观的)结果。让我们考虑这3个空矩阵:
>> a = zeros(1,0); %# A 1-by-0 empty matrix
>> b = zeros(0,1); %# A 0-by-1 empty matrix
>> c = []; %# A 0-by-0 empty matrix
现在,让我们尝试以不同的方式将它们相乘:
>> b*a
ans =
[] %# We get a 0-by-0 empty matrix. OK, makes sense.
>> a*b
ans =
0 %# We get a 1-by-1 matrix of zeroes! Wah?!
>> a*c
ans =
Empty matrix: 1-by-0 %# We get back the same empty matrix as a.
>> c*b
ans =
Empty matrix: 0-by-1 %# We get back the same empty matrix as b.
>> b*c
??? Error using ==> mtimes
Inner matrix dimensions must agree. %# The second dimension of the first
%# argument has to match the first
%# dimension of the second argument
%# when multiplying matrices.
通过将两个空矩阵相乘来得到一个非空矩阵可能足以使你的头受伤,但它有点意义,因为结果仍然没有真正包含任何东西(即它的值为0)。
答案 1 :(得分:6)
连接矩阵时,公共维度必须匹配。
当其中一个操作数为空时,如果它不匹配,则当前不是错误,但是你确实得到了一个令人讨厌的警告,即未来的版本可能更严格。
示例:
>> [ones(1,2);zeros(0,9)]
Warning: Concatenation involves an empty array with an incorrect number of columns.
This may not be allowed in a future release.
ans =
1 1
>> [ones(2,1),zeros(9,0)]
Warning: Concatenation involves an empty array with an incorrect number of rows.
This may not be allowed in a future release.
ans =
1
1
答案 2 :(得分:4)
另一个区别在于两个版本的空的内部表示。特别是当它将数组中相同类的对象捆绑在一起时。
假设您有一个虚拟课程:
classdef A < handle
%A Summary of this class goes here
% Detailed explanation goes here
properties
end
methods
end
end
如果您尝试从空启动数组并将其增长为A对象数组:
clear all
clc
% Try to use the default [] for an array of A objects.
my_array = [];
my_array(1) = A;
然后你得到:
??? The following error occurred converting from A to double:
Error using ==> double
Conversion to double from A is not possible.
Error in ==> main2 at 6
my_array(1) = A;
但如果你这样做:
% Now try to use the class dependent empty for an array of A objects.
my_array = A.empty;
my_array(1) = A;
然后一切都很好。
我希望这会增加之前给出的解释。
答案 3 :(得分:0)
如果连接和乘法不足以担心,仍然存在循环。以下是观察差异的两种方法:
<强> 1。循环可变大小
for t = 1:size(zeros(0,0),1); % Or simply []
'no'
end
for t = 1:size(zeros(1,0),1); % Or zeros(0,1)
'yes'
end
将打印'yes'
,如果您将size
替换为length
,则根本不会打印任何内容。
如果这不是一个惊喜,也许下一个会是。
<强> 2。 Iterating an empty matrix using a for loop 强>
for t = [] %// Iterate an empty 0x0 matrix
1
end
for t = ones(1, 0) %// Iterate an empty 1x0 matrix
2
end
for t = ones(0, 1) %// Iterate an empty 0x1 matrix
3
end
将打印:
ans =
3
最后简要回答你的两个问题: