Разница между [] и [1x0] в MATLAB - PullRequest
21 голосов
/ 13 октября 2011

У меня есть цикл в 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 внутренне представляет их, почему программист должен знать об этой разнице?(т.е. зачем отображать их по-другому?).Это (безвредная) ошибка?или есть какая-либо выгода в знании того, что такие массивы представлены по-разному?

Ответы [ 4 ]

20 голосов
/ 13 октября 2011

В большинстве случаев (см. Ниже исключение) реальной разницы нет.И то и другое считается «пустым» , поскольку хотя бы одно измерение имеет размер 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 строки из исходной матрицы.Если бы результат только показал [], вы бы не знали, был ли он пустым, потому что ваши индексы строк были пусты, или ваши индексы столбцов были пусты, или оба.

The Caveat ...

В некоторых случаях пустая матрица, определенная как [] (то есть все ее измерения равны 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).

6 голосов
/ 13 октября 2011

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

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

Примеры:

>> [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
4 голосов
/ 13 октября 2011

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

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

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;

Тогда все в порядке.

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

0 голосов
/ 17 октября 2013

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

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

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

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