Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Учебник Математические пакеты

.pdf
Скачиваний:
43
Добавлен:
23.12.2022
Размер:
6.39 Mб
Скачать

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

строки заданной матрицы, а потом все остальные элементы установить в ноль. Решение данной задачи представлено на рис. 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.