Учебник Математические пакеты
.pdfциальному закону распределения с математическим ожиданием 5. Размер матрицы изменен с использованием функции resize_matrix. Таким образом матрица М(3х4) стала матрицей М1(2х2).
Функция size позволяет проверить размер матрицы и возвращает два параметра n и m, значения которых равны, соответственно, числу строк и столбцов в данной матрице (рис. 1.3.2-8).
--> // Динамическое изменение размеров матриц
--> --> А = [1 2 3; 4 5 6] // Исходная матрица
А=
1.2. 3.
4.5. 6.
--> А(3, 1) = 7 // Изменение размера матрицы путем дополнения элемента
А=
1.2. 3.
4.5. 6.
7. 0. 0.
--> --> А(:, 3) = [] // Удаление 3-го столбца
А=
1.2.
4.5.
7.0.
-->
--> // Создание вектора заданного размера из матрицы А
--> В = matrix(А, 1, 6)
В=
1.4. 7. 2. 5. 0.
--> --> // Создание матрицы (3х4) по экспоненциальному закону распределения
--> |
M = grand(3, 4, 'exp', 5) // с математическим ожиданием 5 |
|||
M |
= |
|
|
|
|
3.1472369 |
0.7660456 |
0.472206 |
0.4688152 |
|
7.350552 |
4.6290769 |
4.0357003 |
3.3184658 |
|
0.4401028 |
13.20044 |
9.4667509 |
0.5462453 |
--> |
|
|
|
|
--> |
M1 = resize_matrix(M, 2, 2)// Изменение размера матрицы М(3х4) на М1(2х2) |
|||
M1 |
= |
|
|
|
|
3.1472369 |
0.7660456 |
|
|
|
7.350552 |
4.6290769 |
|
|
Рис. 1.3.2-7 Примеры динамического изменения размеров матриц
--> // Динамическое изменение размеров матриц
--> --> А = [1 2 3; 4 5 6] // Исходная матрица
А=
1.2. 3.
4. 5. 6.
81
--> А(3, 1) = 7 // Изменение размера матрицы путем дополнения элемента
А=
1.2. 3.
4.5. 6.
7. 0. 0.
--> --> А(:, 3) = [] // Удаление 3-го столбца
А=
1.2.
4.5.
7.0.
-->
--> // Создание вектора заданного размера из матрицы А
--> В = matrix(А, 1, 6)
В=
1.4. 7. 2. 5. 0.
--> --> // Создание матрицы (3х4) по экспоненциальному закону распределения
--> |
M = grand(3, 4, 'exp', |
5) // с математическим ожиданием 5 |
||
M |
= |
|
|
|
|
3.1472369 |
0.7660456 |
0.472206 |
0.4688152 |
|
7.350552 |
4.6290769 |
4.0357003 |
3.3184658 |
|
0.4401028 |
13.20044 |
9.4667509 |
0.5462453 |
--> |
|
|
|
|
--> |
M1 = resize_matrix(M, 2, 2)// Изменение размера матрицы М(3х4) на М1(2х2) |
|||
M1 |
= |
|
|
|
|
3.1472369 |
0.7660456 |
|
|
|
7.350552 |
4.6290769 |
|
|
Рис. 1.3.2-7 Примеры динамического изменения размеров матриц
Кроме формата size(А), функция size может имеет и другой формат:
nm=size(А,1), nm=size(А,2), nm=size(А,"*").
Возвращаемое значение в этом случае определяется вторым параметром функции:
при l возвращается число строк;
при 2 возвращается число столбцов;
при "*" возвращается общее число элементов в матрице, равное числу строк, умноженному на число столбцов.
Создание массивов ячеек
Создать массив ячеек можно с помощью операции фигурные скобки – {} или функции cell.
82
При наличии данных для ввода в массив ячеек, можно создать массив, используя операцию конструирования массива ячеек {} (рис. 1.3.2-8).
--> // Создание массива ячеек
--> --> // Пример1
--> myCell = {1,2,3; 'текст', rand(5,10), {11; 22; 33}}
myCell |
= |
|
|
|
[1x1 constant] |
[ 1x1 constant] |
[1x1 constant] |
||
[1x1 string ] |
[5x10 constant] |
[3x1 cell |
] |
|
--> |
|
|
|
|
--> // Пример2 |
|
|
|
|
--> C = {} |
|
|
|
|
C = |
|
|
|
|
{} |
|
|
|
|
--> |
|
|
|
|
--> // Пример3 |
|
|
|
|
--> emptyC = cell(3, 4) |
|
|
||
emptyC |
= |
|
|
|
[0x0 constant] |
[0x0 constant] |
[0x0 constant] |
[0x0 constant] |
|
[0x0 constant] |
[0x0 constant] |
[0x0 constant] |
[0x0 constant] |
|
[0x0 constant] |
[0x0 constant] |
[0x0 constant] |
[0x0 constant] |
Рис. 1.3.2-8. Создание массива ячеек с использованием {} и функции cell
Как и все массивы Scilab, массивы ячеек – прямоугольные, с одинаковым количеством ячеек в каждой строке. Матрица myCell (Пример1) представляет собой массив ячеек размером 2×3.
Операцию конструирования ячеек можно использовать для создания пустого массива ячеек {} – Пример2.
Чтобы добавить значения в массив ячеек, вначале нужно создать пустой массив. Для этого в Примере3 используется функция cell(3х4). В результате чего массив emptyC представляет собой массив ячеек размером 3×4, где каждая ячейка содержит пустой массив [] – Пример3.
1.3.3. Индексирование и векторизация
Понятия индексирования и векторизации
Индексирование матриц является средством доступа к подмножеству элементов матриц, которое позволяет извлекать из матриц подмножества их элементов, присваивать извлеченное из матриц подмножество новым матри-
цам и модифицировать подмножество элементов существующих матриц.
В Scilab имеется несколько способов индексирования, которые влияют не только на скорость выполнения программного кода, но и на его читаемость.
83
Таким образом, индексирование является ключевым моментом эффективности использования средств пакета Scilab при реализации матричных операций. Причем индексирование тесно связано с понятием векторизации [12].
Векторизация означает использование таких конструкций программной системы, которые позволяют отказаться от операторов for, whileи других, используемых для организации явных циклов программы. Причем векторизация обычно приводит к тому, что программа начинает работать быстрее. Большинство из возможных подходов к векторизации используется и при индексировании матриц Scilab.
Обычно поэлементные операции над матрицами выполняются для всех элементов матриц одного размера (одинаковой размерностью и с одинаковым числом элементов по каждому измерению). В некоторых случаях возможно выполнять операции над матрицами разного размера за счёт неявного расширения одной из матриц, которое является одним из элементов векторизации.
Следует помнить, что нумерация элементов матрицы в строках и столбцах начинается с 1, а также, что операция [] и соответствующие функции всегда создают двумерную матрицу, включая матрицы 0×0, 0×n, n×0, 1×1 и 1×n
Индексирование векторов
Индексирование векторов – это стандартный подход к индексированию одним индексом, который используется во всех языках программирования:
V1(НомерЭлементаСтроки)
V2(НомерЭлементаСтолбца),
где V1 – вектор строка, V2 – вектор столбец и V2=V1'.
Рассмотрим Примеры1-11 на рис. 1.3.3-1, иллюстрирующие особенности использования индексации в Scilab.
--> // Примеры индексирования векторов
-->
--> vA1 = [40 5 13 4 2 11 7 14] // Создание вектора 1×8 --> --> // Пример1 Доступ к одному элементу вектора
--> vA1(3) // Доступ к третьему элементу вектора ans =
13.
--> --> // Пример2 Доступ к нескольким элементам вектора
--> vA1([1 5 6]) // Доступ к 1, 5 и 6 элементам вектора ans =
84
40. 2. 11.
--> --> // Пример3 Доступ от 3-го до 7-го элемента вектора
--> vA1(3:7) ans =
13. 4. 2. 11. 7.
-->
--> // Пример4 Доступ, извлечение и создание нового вектора
--> vA2 = vA1([5:8, 1:4]) vA2 =
2. 11. 7. 14. 40. 5. 13. 4.
--> --> // Пример5 Доступ к последнему элементу вектора
--> vA1($) ans =
14.
--> --> // Пример6 Доступ от 5-го элемента вектора до последнего
--> vA1(5:$) ans =
2. 11. 7. 14.
--> --> //Пример7 Использование $ в арифметических операциях
--> vA1(2:$ - 1) //Доступ от 2-го до7-го элемента (предпоследнего) ans =
5. 13. 4. 11. 7.
--> --> // Пример8 Доступ ко всем нечетным элементам вектора
--> vA1(1:2:$)
40.13. 2. 7.
--> // Пример9 Обратный порядок доступа к элементам вектора
--> vA1($:-1:1) ans =
14.7. 11. 2. 4. 13. 5. 40.
--> // Пример10 Модификация элементов существующего вектора
--> vA1([2 3 4]) = [10 15 20] vA1 =
40. 10. 15. 20. 2. 11. 7. 14.
--> --> // Пример11Скалярное расширение (присвоение значение 30 2 и 3 элементу)
--> vA3([2 3])' = 30 // Замена 2-го и 3-го элементов на значение 30 vA3 =
0.
30.
30.
Рис. 1.3.3-1. Примеры векторного индексирования
Стандартное индексирование матриц
85
Стандартное индексирование матриц реализуется с помощью двух индексов. Матричное стандартное индексирование предполагает использование двух индексов, разделенных запятой – первой для строк, а второй для столбцов, причем не надо забывать, что индексирование начинается с 1:
mA(НомерЭлементаСтроки, НомерЭлементаСтолбца).
Создадим матрицу mA(4,4) и проиллюстрируем на ней использование матричной индексации (Примеры 1-4 на рис. 1.3.3-2).
--> // Примеры матричной индексации
-->
--> mA = [16 2 3 13; 5 11 10 8; 9 7 6 12; 4 14 15 1] mA =
16.2. 3. 13.
5.11. 10. 8.
9.7. 6. 12.
4. 14. 15. 1.
--> --> // Пример1 Доступ к одному элементу в строке 2 и столбце 4
--> mA(2, 4) ans =
8.
--> --> // Пример2 Доступ к подмножеству элементов (индексы являются векторами)
--> mA(2:4, 1:2) ans =
5.11.
9.7.
4.14.
--> --> // Пример3 Доступ к элементам 3-ей строки, используя операцию :
-->
--> A(3, :) ans =
9. 7. 6. 12.
--> --> // Пример4 Доступ к последнему столбцу
--> mA(:, $) ans =
13.
8.
12.
1.
Рис. 1.3.3-2. Примеры стандартной матричной индексации
Векторное (линейное) индексирование матриц
86
Линейное векторное индексирование матриц, это такое индексирование матриц, при котором индексирование ее элементов осуществляется только одним индексом. В этом случае матрицу рассматривают как суммарный вектор, составленный из векторов матрицы, то есть вектор, в котором все элементы матрицы вытянуты в один длинный вектор-столбец, где каждый следующий столбец индексируемой матрицы следует за предыдущим столбцом (рис. 1.3.3-3). Так на самом деле матрица хранится в памяти (в нашем случае это последовательность: 1 5 9 2 6 10 37 11 4 8 12). Следовательно, двумерные массивы располагаются в Рабочей области данных по столбцам.
Значения элементов |
Линейные индексы |
|
|
|
Матрица mA |
|
|
|
|
||||||||
1 |
1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
2 |
|
|
i/j |
|
1 |
|
|
2 |
|
|
3 |
|
|
4 |
|
|
9 |
3 |
|
|
1 |
|
1 |
|
2 |
|
3 |
|
4 |
|
|
|||
2 |
4 |
|
|
2 |
|
5 |
|
6 |
|
7 |
|
8 |
|
|
|||
|
|
|
|
|
|
|
|
||||||||||
6 |
5 |
|
|
|
|
|
|
|
|
||||||||
|
|
3 |
|
9 |
|
10 |
|
11 |
|
12 |
|
|
|||||
|
|
|
|
|
|
|
|
||||||||||
10 |
6 |
|
|
|
|
|
|
|
|
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
3 |
7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
8 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
11 |
9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4 |
10 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Рис. 1.3.3-3. Элементы матрицы и их линейные индексы
Индексирование матриц одним индексом называется линейным векторным индексированием матриц. Например, выражение mA(8) просто извлекает 8-й элемент неявного вектора-столбца.
Примеры линейного индексирования матриц приведены на рис. 1.3.3-4.
--> // |
Примеры линейной матричной индексации |
|
--> |
|
|
--> mA = [16 2 |
3 13; 5 11 10 8; 9 7 6 12; 4 14 15 1]; |
|
--> // Пример1 |
|
|
--> mA([2 7 16]) |
// Доступ ко 2-му, 7-му и 16-му элементу линейной матрицы |
|
ans |
= |
|
5. |
|
|
7. |
|
|
1. |
|
|
--> // Пример2 Преобразование индексы матрицы в линейные индексы
--> idmA = sub2ind(size(mA), [2 3 4], [1 2 4]) idmA =
2. 7. 16. --> mA(idmA)
ans = 5. 7. 1.
87
--> // Пример3 Преобразование из матричного представление в векторное
--> A = [2 6 9; 4 2 8; 3 5 1];
--> linearindex = sub2ind(size(A), 3, 2) linearindex =
6.
--> A(linearindex) ans =
5.
Рис. 1.3.3-4 Примеры линейной индексации матриц
В Примере1 показано, что индекс при линейном индексировании матрицы может быть вектором, содержащим более одного линейного индекса, и в этом случае они должны быть перечислены через пробелы или запятые и заключены в квадратные скобки. По заданным линейным индексам производится доступ и извлечение значений элементов матриц.
В Примере2 проведено преобразование индексов матрицы в линейные индексы. Чтобы получить эквиваленты линейных индексов строки и столбца, была использована функция ind2sub, имеющая три параметра: размер матрицы (size(A)); индексы строк ([2 3 4])и индексы столбцов ([1 2 4]). То есть в этом примере нас интересуют линейные индексы таких элементов матрицы, которые при обычном стандартном индексировании записаны как mA(2,1), mA(3,2) и mA(4,4). Чтобы получить линейный индекс одного элемента воспользуемся формулой перерасчета, по которой собственно и происходит расчет в системе Scilab: iV=(j-1)*d1+i, где i и j – номера, соответственно, строки и столбца элемента матрицы, а d1 – размер матрицы. Рассчитаем, например, линейный индекс 1-го заданного в примере элемента: i=2, j=1, d1=3, а iV=(1–1)*3+2=2. Далее показана возможность извлечения элементов по их линейным индексам.
В Примере3 проведено преобразование индексов одного элемента матрицы (3х3) к его линейному эквиваленту и извлечение с его помощью элемента массива.
Таким образом, для доступа к элементам матриц есть выбор между использованием стандартного матричного синтаксиса и использованием доступа, который называется векторным (линейным) индексированием. Предполагая, что A(i,j) элемент матрицы A размерности n×m, индекс этого же элемента A(k) при линейной индексации можно рассчитать по формуле k=(j-1)*n+i.
Функции sub2ind и ind2sub позволяют осуществить преобразования, соответственно, из линейного индексирования элементов матрицы в матричную
ииз матричной в линейную (Приложение 1.3, табл. 1.3.3-1).
Вобщем виде возможны два случая индексирования одной матрицы другой матрицей. В первом случае оно основано на значениях элементов индексирующего массива, а во втором – индексирование основано на позициях элементов индексирующей матрицы, и поэтому называется логическим индексированием.
88
В примерах на рис.1.3.3-2мы фактически уже сталкивались с первым случаем индексирования одного массива другим массивом. Рассмотрим еще несколько примеров (Примеры1-5, рис. 1.3.3-5), иллюстрирующих индексирование, основанное на значениях.
Так, в Примере1 (рис. 1.3.3-5) значения элементов вектора V2 являются индексами вектора V1. В Примере2 показано, что результат индексирования не зависит от того, является индексирующий вектор столбцом или строкой. В Примере3 показано, что результат индексирования зависит от того является индексируемый вектор столбцом или строкой. В Примере4 показано индексирование матрицы А1 вектором V3.
--> |
// |
Примеры индексирования матрицы |
||
--> // |
значениями элементов вектора |
|||
--> |
|
|
|
|
--> // |
Пример1 |
|
|
|
--> |
V1 |
= 5:5:50 |
|
|
V1 |
= |
|
|
|
|
5. 10. 15. 20. 25. 30. 35. 40. 45.50. |
|||
--> |
V2 |
= [1 3 6 7 10]; |
||
--> V1(V2) |
|
|
||
ans |
= |
|
|
|
|
5. |
15. 30. |
35. |
50. |
--> |
|
|
|
|
--> // |
Пример2 |
|
|
|
--> V1(V2') |
|
|
||
ans |
= |
|
|
5.15. 30. 35. 50.
--> |
|
--> // |
Пример3 |
--> V3 |
= V1'; |
--> V3(V2) |
|
ans |
= |
5. |
|
15. |
|
30. |
|
35. |
|
50. |
|
--> |
|
--> // |
Пример4 |
--> A1 |
= [1 3 6; 7 9 10]; |
--> V3 |
= [1 2 3 4 5]; |
--> A1(V3)' |
|
ans |
= |
1.7. 3. 9. 6.
Рис. 1.3.3-5 Индексирование матрицы другой матрицей, основанное на значениях индексирующей матрицы (вектора)
Рассмотрим более сложный пример установки некоторого множества элементов матрицы в ноль. Например, требуется найти максимум каждой
89
строки заданной матрицы, а потом все остальные элементы установить в ноль. Решение данной задачи представлено на рис. 1.3.3-6.
--> // Установка некоторого множества элементов матрицы в ноль
-->
--> A = [1 2 3 4; 5 5 6 7; 7 9 8 3] // Создание исходной матрицы
A=
1.2. 3. 4.
5.5. 6. 7.
7.9. 8. 3.
--> // Значения y и номера I максимальных элементов в каждой строке
--> [y, I] = max(A, 'c') I =
4.
4.
2. y = 4. 7. 9.
-->
--> B = zeros(A) // Создание матрицы Bc нулевыми элементами
B=
0.0. 0. 0.
0.0. 0. 0.
0. |
0. |
0. |
0. |
--> |
|
|
|
--> B(sub2ind(size(A), 1 : length(I), I')) = y // Формирование матрицы B
B = |
|
|
|
|
0. |
0. |
0. |
4. |
|
0. |
0. |
0. |
7. |
|
0. |
9. |
0. |
0. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|