MATLAB.Exponenta
–Û·Ë͇ Matlab&Toolboxes

MATLAB

В.Г.Потемкин "Введение в Matlab" (v 5.3)
Глава 5. Многомерные массивы

  В оглавление книги \ К следующему разделу \ К предыдущему разделу \ Предметный указатель

5.3. Работа с многомерными массивами. Индексация. Переопределение размеров. Вычисления на многомерных массивах. Организация данных в многомерных массивах

Много приемов, связанных с работой с двумерными массивами, переносится на многомерные. В этом разделе описано, как применяется техника индексации и переопределения размеров к многомерным массивам.

В качестве сквозного примера будем рассматривать 3-мерный массив нормально распределенных случайных целых чисел nddata размера 4х5х3:

        nddata = fix(8*randn(4, 5, 3))
         nddata(:, :, 1) =

-3 -9 2 -4 8
-13 9 1 17 0
1 9 -1 -1 0
2 0 5 0 -6

         nddata(:, :, 2) =

2 -5 -11 6 9
-10 6 4 5 -9
5 10 -3 10 0
12 -12 5 5 -1

         nddata(:, :, 3) =

-12 -6 -17 4 3
2 4 0 13 -8
-8 1 -8 4 0
11 -7 4 -5 0

Индексация.

Чтобы получить доступ к элементу (3, 2) на странице 2 массива nddata, надо использовать обращение nddata(3, 2, 2).

В качестве индексов можно использовать вектор, каждый элемент которого должен быть допустимым индексом многомерного массива. Чтобы получить доступ к трем элементам (2, 1), (2, 3) и (2, 4) на странице 3 массива nddata, надо использовать обращение

            nddata(2, [1 3 4], 3)
             ans =        2     0    13

Индексация столбцов многомерных массивов. Индексация столбцов, широко применяемая в системе MATLAB, может быть распространена и на многомерные массивы.

Пример.
Чтобы получить доступ к столбцу 3 на странице 2 массива nddata, надо воспользоваться следующим оператором

             nddata(:, 3, 2)
             ans =

-11
4
-3
5

Используя индексацию столбцов, можно извлечь следующий массив размера 2х2 со страницы 1 массива   nddata:

              nddata(2:3,2:3,1)
              ans =

9
1
9
-1

Индексация столбцов может быть использована как в правой, так и в левой частях оператора присваивания.

Пример.
Сформируем 2-мерный массив С размера 4х4, заполненный нулями:

                 C = zeros(4, 4)
                  C =

0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0

Теперь разместим в центре массива С подмассив nddata(2:3, 1:2, 2) размера 2х2, извлеченный из многомерного массива nddata:

                  C(2:3, 2:3) = nddata(2:3, 1:2, 2)
                  C =

0 0 0 0
0 10 60 0
0 5 10 0
0 0 0 0

Неоднозначность многомерной индексации. Некоторые типы операторов присваивания, например, A(:, :, 1) = 1:10, в случае многомерных массивов не обеспечивают однозначности, поскольку не содержат достаточной информации для выполнения оператора присваивания. В данном случае делается попытка присвоить 1-мерный массив 2-мерному подмассиву массива А. Система MATLAB в таких случаях выдает сообщение об ошибке. Чтобы обеспечить однозначность, необходимо убедиться, что данные и массив-адресат имеют согласованные размеры.

Пример.
Правильное присваивание:

                  A(1, :, 1) = 1:10
                  A =   1   2   3   4   5   6    7   8   9   10

Переопределение размеров.

Изменение размеров и структуры многомерного массива может происходить в двух случаях :

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

Для выполнения второй группы операций предназначена функция reshape, синтаксис которой для многомерного случая имеет вид

             B = reshape(A, [s1 s2 s3 ...])

где s1, s2,.... - новые значения размерностей.

Пример.
Рассмотрим переопределение размеров и размерностей для многомерного массива nddata

              B = reshape(nddata, [6 10])
              B =

-3 9 -4 0 -5 -3 9 -8 -17 4
-13 0 17 -6 6 5 -9 11 0 -5
1 2 -1 2 10 6 0 -6 -8 3
2 1 0 -10 -12 5 -1 4 4 -8
-9 -1 8 5 -11 10 -12 1 4 0
9 5 0 12 4 5 2 -7 13 0

              C = reshape(nddata, [5 4 3])

C(:,:,3)=
-12 4 -8 -5
2 1 4 3
-8 -7 4 -8
11 -17 13 0
-6 0 4 0
C(:,:,2)=
2 6 -3 5
-10 10 5 9
5 -12 6 -9
12 -11 5 0
-5 4 10 -1
C(:,:,1)=
-3 9 -1 0
-13 9 5 8
1 0 -4 0
2 2 17 0
-9 1 -1 -6

Рис. 5.9. 3-мерный массив размера 5х4х3.

               D = reshape(nddata, [2 3 2 5])

D(:,:,2,1)=
9 2 -1
0 1 5
D(:,:,2,2)=
0 2 5
-6 -10 12
D(:,:,2,3)=
-3 6 10
5 5 5
D(:,:,2,4)=
-8 -6 1
11 4 -7
D(:,:,2,5)=
4 3 0
-5 -8 0
D(:,:,1,1)=
-3 1 -9
0 1 5
D(:,:,1,2)=
-4 -1 8
17 0 0
D(:,:,1,3)=
-5 10 -11
6 -12 4
D(:,:,1,4)=
9 0 -12
-9 -1 2
D(:,:,1,5)=
-17 -8 4
0 4 13

Рис. 5.10. 4-мерный массив размера 2х3х2х5.

Удаление размерностей размера 1х1. Система MATLAB создает размерности размера 1х1, если такая спецификация указывается точно при создании или переопределении массива, либо если в процессе вычислений возникает массив размера 1х1.

Пример.

                 B = repmat(5, [2 3 1 4])

B(:,:,1,1)=
5 5 5
5 5 5
B(:,:,1,2)=
5 5 5
5 5 5
B(:,:,1,3)=
5 5 5
5 5 5
B(:,:,1,4)=
5 5 5
5 5 5

Рис. 5.11. 4-мерный массив размера 2х3х1х4.

                   size(B)
                    ans = 2   3   1   4

Функция squeeze удаляет из многомерного массива измерение размера 1х1:

                    C = squeeze(B)

C(:,:,4)=
5 5 5
5 5 5
C(:,:,3)=
5 5 5
5 5 5
C(:,:,2)=
5 5 5
5 5 5
C(:,:,1)=
5 5 5
5 5 5

Рис. 5.12. 3-мерный массив размера 2х3х4.

                    size(C)
                    ans = 2   3   4

Замечание:

Функция squeeze транспонирует вектор-строку в вектор-столбец; вектор-столбец функция squeeze оставляет без изменения.

Перестановки размерностей. Функция permute позволяет выполнить перестановку размерностей

                     B = permute(A, dims);

где dims - вектор, который задает новый порядок следования размерностей.

При этом индекс 1 соответствует строкам, индекс 2 - столбцам, индекс 3 - страницам и т. д.

A B = permute(A,[2 1 3] C = permute(A,[3 2 1]
A(:,:,2)=
9 8 7
6 5 4
3 2 1
A(:,:,1)=
1 2 3
4 5 6
7 8 9
B(:,:,2)=
9 6 3
8 5 2
7 4 1
B(:,:,1)=
1 4 7
2 5 8
3 6 9
C(:,:,3)=
7 8 9
3 2 1
C(:,:,2)=
4 5 6
6 5 4
C(:,:,1)=
9 8 7
6 5 4

Рис. 5.13. Применение функции permute

Функция ipermute обратна по отношению к функции permute. Вводя массив A и вектор перестановок v, функция ipermute формирует такой массив B, что функция permute(B, v) возвращает A.

Пример.
В результате выполнения следующих операторов формируется массив E, который совпадает с исходным массивом C:

                D = ipermute(C, [1 4 2 3])
                E = permute(D, [1 4 2 3])

D(:,:,1,1)=
5 5 5 5
5 5 5 5
D(:,:,1,2)=
5 5 5 5
5 5 5 5
D(:,:,1,3)=
5 5 5 5
5 5 5 5

а)

E(:,:,4)=
5 5 5
5 5 5
E(:,:,3)=
5 5 5
5 5 5
E(:,:,2)=
5 5 5
5 5 5
E(:,:,1)=
5 5 5
5 5 5

б)

Рис. 5.14. Применение функции ipermute:
                  а) - D = ipermute(C, [1 4 2 3]);
                  б) - E = permute(D, [1 4 2 3])

Обратите внимание, что функции permute и ipermute используют один и тот же вектор перестановок.

Вычисления на многомерных массивах.

Многие функции системы MATLAB допускают использование многомерных массивов в качестве входных аргументов. Есть функции, которые могут использовать только отдельные размерности, соответствующие матрицам, векторам или отдельным элементам.

Функции, работающие с векторами. Функции, использующие векторы, такие как sum, mean, по умолчанию используют в качестве аргумента первую размерность многомерного массива, значение которой не равно 1. Большинство таких функций позволяют пользователю указать ту конкретную размерность, которую надо использовать в качестве входа. Однако есть и некоторые исключения. Например, функция cross использует в качестве входного аргумента первую размерность с длиной вектора, равной 3.

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

Функции, работающие с отдельными элементами. Функции системы MATLAB, которые оперируют с отдельными элементами двумерного массива, будут точно также работать и с элементами многомерного массива. В первую очередь, это все элементарные функции. Например, функция sin всегда возвращает массив того же размера, как и массив входа. Каждый элемент выходного массива является синусом соответствующего элемента входного массива.

Точно также операторы отношения и логические операторы используют отдельные элементы многомерного массива. Если один из операндов - скаляр, а другой массив, то исполняемый оператор сопоставляет скаляр с каждым элементом массива.

Функции, работающие с матрицами. Функции линейной алгебры и матричные функции из каталога matfun не допускают многомерные массивы в качестве входных аргументов. Если такое происходит, то появляется сообщение об ошибке.

Использовать такие матричные функции можно только по отношению к двумерным подмножествам многомерного массива.

Пример.
Сформируем 3-мерный массив A, состоящий из трех 2-мерных массивов размера 3х3:

             A = cat(3, [1 2 3; 9 8 7; 4 6 5], [0 3 2; 8 8 4; 5 3 5],…
                          [6 4 7; 6 8 5; 5 4 3])

A(:,:,3)=
6 4 7
6 8 5
5 4 3
A(:,:,2)=
0 3 2
8 8 4
5 3 5
A(:,:,1)=
1 2 3
9 8 7
4 6 5

Рис. 5.15. 3-мерный массив размера 3х3х3.

Применение функции вычисления собственных значений eig к массиву в целом вызовет ошибку:

               eig(A)
               ??? Error using ==> eig
               Input arguments must be 2-D.
               Входные аргументы должны быть 2-мерными

Однако ее можно применять к 2-мерным множествам.

Пример.
Вычислим собственные значения для второго из трех массивов:

               eig(A(:, :, 2))
                ans =

-2.6260
12.9129
2.7131

Для того чтобы вычислить собственные значения для матрицы, составленной из вторых строк каждого массива, надо использовать функцию squeeze, которая преобразует 3-мерное подмножество A(2, :, :) размера 1x3x3 в матрицу размера 3x3.

Функция eig(A(2, :, :)) выдает ошибку

                  eig(A(2,:,:))
                  ??? Error using ==> eig
                  Input arguments must be 2-D.
                  Входные аргументы должны быть 2-мерными

Функция eig(squeeze(A(2, :, :))) вычисляет собственные значения (но не собственные векторы - вспомните о транспонировании строк при использовании функции squeeze) абсолютно правильно

                   eig(squeeze(A(2, :, :)))
                   ans =

21.2293
0.3854+ 1.5778i
0.3854- 1.5778i

Организация данных в многомерных массивах.

Существует два подхода к тому, как организовать данные в многомерный массив:

  1. Страничная интерпретация. В этом случае за основу берутся 2-мерные массивы, которые считаются размещенными на страницах. Множество таких страниц может затем быть организовано в 3-мерные, 4-мерные и т. д. массивы.
  2. Пространственная интерпретация (многомерные данные). В этом случае рассматриваются измерения физических величин (температуры, давления и т. п.) в точках трехмерного пространства.

Первый подход использовался на протяжении всего раздела. Второй может представлять интерес при решении уравнений в частных производных, а также физических задач и измерений.

Применение последнего подхода проиллюстрируем на примере измерения температуры в равноотстоящих точках в пределах некоторого объема. В этом случае каждое измерение привязано к определенной точке 3-мерного пространства и такие данные могут быть организованы в 3-мерный массив (рис. 5.16):

рассмотрим 3-мерный массив TEMP

67.9° 68.0° 67.9°
67.8° 67.8° 67.9°
67.7° 67.9° 67.7°
67.9° 68.0° 68.0°
67.7° 67.8° 67.7°
67.8° 67.7° 67.5°
68.0° 68.0° 67.8°
67.9° 67.8° 67.6°
67.8° 68.0° 67.6°

Рис. 5.16. Массив TEMP размера 3x3x3.

Для вычисления среднего значения температуры в этом объеме можно использовать оператор mean(mean(mean(TEMP))).

Для вычисления значений температуры посередине этого объема - элементы (2, 2) на каждой странице - надо применить оператор B = TEMP(2, 2, :).

  В оглавление книги \ К следующему разделу \ К предыдущему разделу \ Предметный указатель

 


Поиск по сайту:

Система Orphus

Яндекс.Метрика