MATLAB中[]和[1x0]之间的差异

时间:2011-10-12 20:33:23

标签: matlab matrix

我在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

  1. 它们之间是否存在任何差异? (除了MATLAB以不同方式显示它们的事实)。 MATLAB在内存中如何表示它们的差异?
  2. 如果区别仅在于MATLAB内部如何表示它们,为什么程序员应该意识到这种差异? (即为什么以不同方式显示它们?)。它是一个(无害的)bug吗?或者知道这些数组的表示方式不同,是否有任何好处

4 个答案:

答案 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

最后简要回答你的两个问题:

  • 是的,他们之间肯定存在差异
  • 事实上,我相信程序员会因为意识到这种差异而受益,因为差异可能会产生意想不到的结果