Ответ 1
В дальнейшем я использую терминологию, которая, я думаю, более или менее соответствует стандартной практике Matlab. Однако в некоторых случаях мне приходилось сортировать имя, потому что я не знал о существующем. Пожалуйста, дайте мне знать, если есть более стандартные имена, чем те, которые я использую.
Этот ответ пытается прояснить различные типы индексирования и как их можно комбинировать. Другой вопрос заключается в том, как форма (size
) выходного массива определяется как функция формы индексных переменных. Хорошей почтой на этом является Суть индексации Лорен Шуре.
В приведенном описании основное внимание уделяется индексированию числовых массивов, но оно может быть применено к массивам ячеек с индексом скобок или фигурной скобки с очевидным изменением типа вывода (соответственно массива ячеек или списка разделенных запятыми). Это будет кратко обсуждено в конце.
Типы индексирования в числовых массивах
Индексация может быть классифицирована с учетом следующих двух атрибутов.
-
Согласно числу измерений, к которым относится каждая индексная переменная, индексирование может быть многомерным или линейным. Но это всего лишь два крайних случая. Существует промежуточная ситуация, которую можно назвать частично линейной индексацией:
- Чистая многомерная индексация задает индексную переменную для каждого измерения массива. Отдельные индексы иногда упоминаются как индексы в документации Matlab (см., Например,
sub2ind
). - Чистая линейная индексация задает единую индексную переменную, которая пересекает массив по всем измерениям (это можно рассматривать так, как если бы все размеры сворачивались в один). Как мы знаем, обход сначала по столбцам, затем по рядам, затем по трем-мерным срезам и т.д. (Так называемый порядок столбцов-майоров).
- Частично линейное индексирование: заданный массив с
m+n
измерениями,n>=2
, можно указатьm
индексных переменных для первыхm
измерений (таким образом, используя многомерную индексацию в этих измерениях) и одну индексную переменную для последнихn
измерений, которая равна интерпретируется как линейный индекс только для этих измерений (последниеn
измерений сворачиваются в один).
- Чистая многомерная индексация задает индексную переменную для каждого измерения массива. Отдельные индексы иногда упоминаются как индексы в документации Matlab (см., Например,
-
В соответствии с типом значений индекса каждая индексная переменная может быть целочисленной или логической:
- Он целочисленный, если индексная переменная содержит положительные целые числа;
- Логично, если индексная переменная содержит логические значения.
Критерии классификации 1 и 2 являются независимыми. Категория индекса с точки зрения критерия 1 не имеет отношения к его категории в соответствии с критерием 2. Возможны все комбинации.
Таким образом, согласно вышеуказанной классификации, существует 6 основных типов индексирования. Чтобы прояснить, ниже приведен пример для каждого. Все примеры используют массив A = cat(3, magic(3), 9+magic(3))
, то есть,
A(:,:,1) =
8 1 6
3 5 7
4 9 2
A(:,:,2) =
17 10 15
12 14 16
13 18 11
-
Многомерный, целочисленный:
>> A([1 2], 2, 2) ans = 10 14
-
Линейный, целочисленный:
>> A([2 5:7]) ans = 3 5 9 6
-
Частично линейный, целочисленный:
>> A([1 2], 2:4) ans = 1 6 17 5 7 12
-
Многомерный, логический:
>> A([true true false], [false true false], [false true]) ans = 10 14
Интересно, что количество логических значений может быть меньше или даже больше, чем размер в измерении, на который ссылается индекс:
>> A([true true], [false true false false], [false true]) ans = 10 14
Недопустимые значения интерпретируются как
false
, а избыточные значения должны бытьfalse
или произойдет ошибка. См., Например, эту страницу по Mathworks или этот ответ Джонаса. -
Линейный, логический:
>> A([false true false false true true true]) ans = 3 5 9 6
(Обратите внимание, что в векторе индексирования осталось 11
false
значений). -
Частично линейный, логический:
>> A([true true false], [false true true true false false]) ans = 1 6 17 5 7 12
При многомерном или частично линейном индексировании, в котором имеется более одной индексной переменной, каждая из них может независимо быть целочисленной или логической. Это приводит к разным смешанным типам. Например:
-
Многомерный, логический/целочисленный:
>> A([true false true], [false true true], 2) ans = 10 15 18 11
-
Частично линейный, целочисленный/логический:
>> A([1 2], [true false true false true false]) ans = 8 6 10 3 7 14
Если массив, который индексируется, является разреженной матрицей, все вышеприведенное все еще применяется, за исключением того, что для матриц не существует частично линейного индексации; и, конечно, результат также разрежен.
Индексирование массивов ячеек
Все типы индексирования, описанные для числовых массивов, могут быть применены к массивам ячеек с одним дополнительным рассмотрением. Ячейки могут быть проиндексированы скобками или фигурными фигурными скобками. В первом случае результатом индексации является массив ячеек. Во втором - список содержимого ячейки, разделенный запятыми.
В качестве примера предположим, что численный массив, используемый в предыдущих примерах, преобразуется в массив ячеек C = num2cell(A)
, то есть,
C(:,:,1) =
[8] [1] [6]
[3] [5] [7]
[4] [9] [2]
C(:,:,2) =
[17] [10] [15]
[12] [14] [16]
[13] [18] [11]
Тогда индексирование, используемое в примере 8 выше, даст массив ячеек
>> C([1 2], [true false true false true false])
ans =
[8] [6] [10]
[3] [7] [14]
тогда как использование фигурных скобок даст список, разделенный запятыми
>> C{[1 2], [true false true false true false]}
ans =
8
ans =
3
ans =
6
ans =
7
ans =
10
ans =
14
Выносное сообщение /TL; DR
Логическое и линейное индексирование не являются исключительными типами индексирования. Скорее, это две независимые функции индексирования. "Логический" относится к типу значений индекса, а "linear" означает, что несколько измерений свертываются и индексируются как единое целое. Обе функции могут выполняться одновременно.