MATLAB 中 [] 和 [1x0] 之间的区别

发布于 2024-12-09 16:02:58 字数 858 浏览 0 评论 0原文

我在 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 内部如何表示它们,为什么程序员应该意识到这种差异? (即为什么以不同的方式显示它们?)。这是一个(无害的)错误吗?或者知道这些数组以不同的方式表示是否有任何好处

I have a loop in MATLAB that fills a cell array in my workspace (2011b, Windows 7, 64 bit) with the following entries:

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]

Note that some entries hold [], as in row #6, while others hold [1x0] items, as in row #3.

  1. Is there any difference between them? (other than the fact that MATLAB displays them differently). Any differences in how MATLAB represents them in memory?
  2. If the difference is only about how MATLAB internally represents them, why should the programmer be aware of this difference ? (i.e. why display them differently?). Is it a (harmless) bug? or is there any benefit in knowing that such arrays are represented differently?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

大多数情况下(见下文的例外)没有真正的区别。两者都被视为“空”,因为至少一个维度具有大小为 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)。

In most cases (see below for an exception) there is no real difference. Both are considered "empty", since at least one dimension has a size of 0. However, I wouldn't call this a bug, since as a programmer you may want to see this information in some cases.

Say, for example, you have a 2-D matrix and you want to index some rows and some columns to extract into a smaller matrix:

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

Note that the empty result still tells you some information, specifically that you tried to index 2 rows from the original matrix. If the result just showed [], you wouldn't know if it was empty because your row indices were empty, or your column indices were empty, or both.

The Caveat...

There are some cases when an empty matrix defined as [] (i.e. all of its dimensions are 0) may give you different results than an empty matrix that still has some non-zero dimensions. For example, matrix multiplication can give you different (and somewhat non-intuitive) results when dealing with different kinds of empty matrices. Let's consider these 3 empty matrices:

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

Now, let's try multiplying these together in different ways:

>> 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.

Getting a non-empty matrix by multiplying two empty matrices is probably enough to make your head hurt, but it kinda makes sense since the result still doesn't really contain anything (i.e. it has a value of 0).

思念绕指尖 2024-12-16 16:02:58

连接矩阵时,公共维度必须匹配。

如果操作数之一为空时不匹配,目前并不是错误,但您确实会收到一条令人讨厌的警告,表明未来版本可能会更严格。

示例:

>> [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

When concatenating matrices, the common dimension has to match.

It's not currently an error if it doesn't match when one of the operands is empty, but you do get a nasty warning that future versions might be more strict.

Examples:

>> [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
人│生佛魔见 2024-12-16 16:02:58

另一个区别在于两个版本的empty 的内部表示。特别是当将同一类的对象捆绑在一个数组中时。

假设您有一个虚拟类:

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;

那么一切都很好。

我希望这可以补充之前给出的解释。

Another difference is in the internal representation of both versions of empty. Especially when it comes to bundle together objects of the same class in an array.

Say you have a dummy class:

classdef A < handle
%A Summary of this class goes here
%   Detailed explanation goes here

properties
end

methods
end

end

If you try to start an array from empty and grow it into an array of A objects:

clear all
clc

% Try to use the default [] for an array of A objects.
my_array = [];
my_array(1) = A;

Then you get:

??? 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;

But if you do:

% Now try to use the class dependent empty for an array of A objects.
my_array = A.empty;
my_array(1) = A;

Then all is fine.

I hope this adds to the explanations given before.

老街孤人 2024-12-16 16:02:58

如果连接和乘法还不足以担心,那么仍然存在循环。以下是观察差异的两种方法:

1.循环遍历变量 size

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. 使用 for 循环迭代空矩阵

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

最后对您的两个问题给出一个简洁的答案:

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

If concatenation and multiplication is not enough to worry about, there is still looping. Here are two ways to observe the difference:

1. Loop over the variable size

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

Will print 'yes', if you replace size by length it will not print anything at all.

If this is not a surprise, perhaps the next one will be.

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

Will print:

ans =
    3

To conclude with a concise answer to both of your questions:

  • Yes there is definitely a difference between them
  • Indeed I believe the programmer will benefit from being aware of this difference as the difference may produce unexpected results
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文