Подтвердить что ты не робот

Разница между [] и [1x0] в MATLAB

У меня есть цикл в 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.

  • Существует ли любая разница между ними? (кроме того, что MATLAB отображает их по-разному). Любые различия в том, как MATLAB представляет их в памяти?
  • Если разница заключается только в том, как MATLAB их внутренне представляет, почему программист должен знать эту разницу? (т.е. почему они отображаются по-разному?). Это (безобидная) ошибка? или существует какое-либо преимущество, зная, что такие массивы представлены по-разному?
4b9b3361

Ответ 1

В большинстве случаев (см. ниже для исключения) нет реальной разницы. Оба они считаются "empty" , поскольку хотя бы одно измерение имеет размер 0. Однако я бы не назвал это ошибкой, так как as программист, вы можете увидеть эту информацию в некоторых случаях.

Скажем, например, у вас есть двумерная матрица, и вы хотите индексировать некоторые строки и некоторые столбцы для извлечения в меньшую матрицу:

>> 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), может дать вам разные результаты, чем пустая матрица, которая все еще имеет некоторые ненулевые измерения. Например, умножение матрицы может дать вам разные (и несколько неинтуитивные) результаты при работе с различными типами пустых матриц. Рассмотрим эти три пустые матрицы:

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

Ответ 2

При конкатенации матриц общий размер должен соответствовать.

В настоящее время это не ошибка, если она не совпадает, когда один из операндов пуст, но вы получаете неприятное предупреждение о том, что будущие версии могут быть более строгими.

Примеры:

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

Ответ 3

Другое отличие заключается во внутреннем представлении обеих версий пустых. Особенно, когда речь идет о объединении объектов одного и того же класса в массиве.

Скажем, у вас есть фиктивный класс:

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;

Тогда все нормально.

Надеюсь, это добавит объяснения, приведенные ранее.

Ответ 4

Если конкатенации и умножения недостаточно, чтобы беспокоиться, есть еще цикл. Вот два способа наблюдать разницу:

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. Итерирование пустой матрицы с использованием цикла 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

В заключение с кратким ответом на оба из ваших вопросов:

  • Да, есть определенная разница между ними.
  • В самом деле, я считаю, что программисту будет полезно узнать об этом различии, поскольку разница может привести к неожиданным результатам.