Базовые средства матпакета Scilab
.pdf--> // Динамическое изменение размеров матриц
--> --> А = [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.3.2-7 создана матрица А(2,3). Далее в эту матрицу добавлен элемент с индексами (3,1). Добавление элемента вызывает в матрице А создание третьей строки, где первому элементу в ней будет присвоено значение 7, а значения остальных элементов данной строки будут установлены в 0. Таким образом, размер матрицы может увеличиваться динамически.
Далее приведен пример динамического уменьшения размера матрицы, где для удаления третьего столбца матрицы А, используется обозначение пустой матрицы [].
Полностью изменить размер матрицы можно с использованием функции matrix. Эта функция трансформирует исходную матрицу в матрицу
61
другого размера, копируя элементы столбец за столбцом. В следующем примере матрица А размером 3х2=6 преобразуется в вектор-строку с 6 элементами.
В последнем примере (рис. 1.3.2-7) с использованием функцииgrand создана матрица М размером (3х4), элементы которой распределены по экспоненциальному закону распределения с математическим ожиданием 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 Примеры динамического изменения размеров матриц
62
--> // Динамическое изменение размеров матриц
--> --> А = [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 Примеры динамического изменения размеров матриц Кроме формата size(А), функция size может имеет и другой формат:
nm=size(А,1), nm=size(А,2), nm=size(А,"*").
Возвращаемое значение в этом случае определяется вторым параметром функции:
|
при |
l |
возвращается число строк; |
|
при |
2 |
возвращается число столбцов; |
при "*" возвращается общее число элементов в матрице, равное числу строк, умноженному на число столбцов.
63
Создание массивов ячеек
Создать массив ячеек можно с помощью операции фигурные скобки – {} или функции cell.
При наличии данных для ввода в массив ячеек, можно создать массив, используя операцию конструирования массива ячеек {} (рис. 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. Индексирование и векторизация
Понятия индексирования и векторизации
64
Индексирование матриц является средством доступа к подмножеству элементов матриц, которое позволяет извлекать из матриц подмножества их элементов, присваивать извлеченное из матриц подмножество новым матрицам и модифицировать подмножество элементов существующих матриц. В Scilab имеется несколько способов индексирования, которые влияют не только на скорость выполнения программного кода, но и на его читаемость. Таким образом, индексирование является ключевым моментом эффективности использования средств пакета 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.
--> // Примеры индексирования векторов
-->
65
--> 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 = |
|
|
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.
66
Рис. 1.3.3-1. Примеры векторного индексирования
Стандартное индексирование матриц
Стандартное индексирование матриц реализуется с помощью двух индексов. Матричное стандартное индексирование предполагает использование двух индексов, разделенных запятой – первой для строк, а второй для столбцов, причем не надо забывать, что индексирование начинается с 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 =
--> --> // Пример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.
67
1.
Рис. 1.3.3-2. Примеры стандартной матричной индексации
Векторное (линейное) индексирование матриц
Линейное векторное индексирование матриц, это такое индексирование матриц, при котором индексирование ее элементов осуществляется только одним индексом. В этом случае матрицу рассматривают как суммарный вектор, составленный из векторов матрицы, то есть вектор, в котором все элементы матрицы вытянуты в один длинный вектор-столбец, где каждый следующий столбец индексируемой матрицы следует за предыдущим столбцом (рис. 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 Преобразование индексы матрицы в линейные индексы
68
--> idmA = sub2ind(size(mA), [2 3 4], [1 2 4]) idmA =
2. 7. 16. -->mA(idmA) ans =
5.
7.
1.
--> // Пример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) к его линейному эквиваленту и извлечение с его помощью элемента массива.
69
Таким образом, для доступа к элементам матриц есть выбор между
использованием |
стандартного |
матричного |
синтаксиса |
и |
использованием доступа, который |
называется векторным (линейным) |
индексированием. Предполагая, что A(i,j) элемент матрицы A размерности n×m, индекс этого же элемента A(k) при линейной индексации можно рассчитать по формуле k=(j-1)*n+i.
Функции sub2ind и ind2sub позволяют осуществить преобразования, соответственно, из линейного индексирования элементов матрицы в матричную и из матричной в линейную (Приложение 1.3, табл. 1.3.3-1).
Вобщем виде возможны два случая индексирования одной матрицы другой матрицей. В первом случае оно основано на значениях элементов индексирующего массива, а во втором – индексирование основано на позициях элементов индексирующей матрицы, и поэтому называется
логическим индексированием.
Впримерах на рис.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 =
70