1-2 Моделирование / Matlab. Практический подход. Самоучитель
.pdfГлава 4. Элементы матричной алгебры
Достаточно просто из матрицы извлечь блок. Рассмотрим следующий командный код:
>> A=[1 2 3 4 5;6 7 8 9 10;11 12 13 14 15;16 17 18 19 20]
A = |
2 |
3 |
4 |
5 |
1 |
||||
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
>> B=A(2:4,1:3)
B =
6 7 8
11 12 13
16 17 18
Сначала создается матрица A размерами 4×5, а затем командой B=A(2:4,1:3) из нее извлекается блок (подматрица, которая записывается в переменную B). Блок выделяется из исходной матрицы так: строки со 2-й по 4-ю включительно и столбцы с 1-го по 3-й включительно (рис. 4.18).
Рис. 4.18. Создание блочной матрицы
Еще одна полезная процедура, которую нередко приходится выполнять, – удаление из матрицы строки или столбца. Формально она состоит в том, что соответствующей строке или столбцу в качестве значения присваивается пустой список. Примеры приведены в документе на рис. 4.19.
171
Самоучитель Matlab
Рис. 4.19. Удаление строк и столбцов
Сначала создается матрица A, а затем командой A(:,3)=[] из матрицы A удаляется 3-й столбец. Следующей командой A(:,3:4)=[] из измененной на предыдущем этапе матрицы A удаляются 3-й и 4-й. Матрица A становится еще меньше. После этого командой A(3,:)=[] из матрицы удаляем 3-ю строку. Весь командный код имеет следующий вид (жирным шрифтом выделен ввод пользователя):
>> A=[1 2 3 4 5;6 7 8 9 10;11 12 13 14 15;16 17 18 19 20]
A = |
2 |
3 |
4 |
5 |
1 |
||||
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
172
Глава 4. Элементы матричной алгебры
>> A(:,3)=[] |
|
|
|
A = |
2 |
4 |
5 |
1 |
|||
6 |
7 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
17 |
19 |
20 |
>> A(:,3:4)=[] A =
12
6 |
7 |
11 |
12 |
1617
>>A(3,:)=[]
A =
12
67
1617
На заметку
Для ссылки на все элементы строки или столбца мы использовали двоеточие вместо соответствующего индекса.
В Matlab, на уровне реализации и поддержки базовых операций, серьезное внимание уделяется так называемым разряженным матрицам. Под разряженными подразумевают матрицы, содержащие значительное количество нулевых элементов. Примером разряженной матрицы может быть диагональная (ненулевые элементы только на главной диагонали) матрица или трехдиагональная (ненулевые элементы на диагонали и рядом с ней) матрица. В принципе, никакой особой проблемы с разряженными матрицами нет – матрицы как матрицы. Все так называемые проблемы связаны с компьютерной обработкой таких матриц. Дело в том, что если разряженная матрица достаточно большого размера, то для нее нужно много места в памяти. При этом память расходуется достаточно нерационально в том смысле, что подавляющее количество элементов нулевое, и под каждый из них необходимо выделить ячейку памяти.
На заметку
В данном случае не важно, что элементы именно нулевые. Важно то, что все они одинаковые.
Например, если мы имеем дело с квадратной диагональной матрицей размера n ×n , то на диагонали будет n элементов, а всего элементов n2 . То есть доля "полезных" элементов в матрице составляет n n2 = 1 n . При
n = 100 с пользой для дела будет использоваться только 1% от объема памяти, выделенной под матрицу. Такая расточительность может стать кри-
173
Самоучитель Matlab
тичной – кто сталкивался с серьезным математическим моделированием, знает, о чем идет речь.
В Matlab данная проблема решается достаточно просто – в разреженных матрицах запоминаются только ненулевые элементы. За счет этого экономится память. При этом вся кухня, связанная с особенностями реализации разреженных матриц, от пользователя скрыта, и внешне иллюзия такая, как если бы мы имели дело с обычной матрицей.
Поскольку разница между разреженной и обычной матрицей достаточно зыбкая, принимать решение о том, какую матрицу считать разреженной, должен пользователь. Другими словами, разреженной матрица сама по себе не станет, даже если состоит сплошь из нулей. Разреженную матрицу нужно специально создавать. Для создания разреженной матрицы на основе уже существующей используют встроенную функцию sparse(). Аргументом можно указать обычную (не разреженную) матрицу (но можно и что-то другое). Простой пример создания разреженной матрицы приведен в документе на рис. 4.20.
Следующими командами создается прототип разреженной матрицы:
>>A=eye(5);
>>for i=1:4 A(i,i+1)=2; A(i+1,i)=3;
end
В результате создается матрица, на диагонали которой единицы, поддиагональ сверху заполнена двойками, а поддиагональ снизу заполнена тройками. На основе созданной с такими параметрами матрицы A командой B=sparse(A) создаем разреженную матрицу. На эту команду стоит обратить внимание, хотя бы из-за того, каков будет ее результат:
>> B=sparse(A)
B =
(1,1) 1
(2,1) 3
(1,2) 2
(2,2) 1
(3,2) 3
(2,3) 2
(3,3) 1
(4,3) 3
(3,4) 2
(4,4) 1
(5,4) 3
(4,5) 2
(5,5) 1
174
Глава 4. Элементы матричной алгебры
Рис. 4.20. Создание разреженной матрицы
Это при том, что матрица A отображается совершенно обычным образом:
>> A
A =
1 |
2 |
0 |
0 |
0 |
3 |
1 |
2 |
0 |
0 |
0 |
3 |
1 |
2 |
0 |
0 |
0 |
3 |
1 |
2 |
0 |
0 |
0 |
3 |
1 |
Несложно сообразить, что разреженная матрица отображается по-особому: это два столбика, в первом из которых в круглых скобках указываются индексы ненулевых элементов, а во втором столбце – значения ненулевых элементов. Все прочие элементы матрицы автоматически полагаются нулевыми. Например, запись
175
Самоучитель Matlab
(3,4) 2
означает, что элемент матрицы, находящийся в 3-й строке и 4-м столбце, равен 2. Чтобы проверить эффект от экономии места, воспользуемся инструкцией с ключевым словом whos:
>> whos A B |
Bytes |
Class |
Attributes |
|
Name |
Size |
|||
A |
5x5 |
200 |
double |
sparse |
B |
5x5 |
180 |
double |
Тот же результат можно видеть в документе на рис. 4.21.
Рис. 4.21. Выделяемая для записи матриц память
В данном случае эффект от использования разреженной матрицы не очень существенный: на такую же обычную матрицу выделяется 200 байт, а на разреженную – 180. Эффект экономии имеет место только при работе с матрицами больших размеров.
На заметку
Чтобы увидеть разреженную матрицу во всей красе, то есть в обычном представлении, используют функцию full() с передачей ей аргументом разреженной матрицы.
Приведенный выше способ создания разреженной матрицы малополезен, поскольку подразумевает предварительное создание обычной матрицы. Обычно разумнее и удобнее сразу создавать разреженную матрицу. В этом случае также используется функция sparse(), но несколько иначе передаются аргументы. Первым и вторым аргументами указываются списки с индексами строк и столбцов для ненулевых элементов. Третий аргумент – список со значениями ненулевых элементов. Четвертый и пятый числовые аргументы задают количество строк и столбцов в разреженной матрице. Если эти аргументы не указать, то размеры матрицы определяются автоматически на основании списка ненулевых элементов. Рассмотрим такой код:
A=sparse([1,1,2,2,2,3,5],[1,2,1,3,5,1,4],[1,0,3,4,4,1,2],6,5)
176
Глава 4. Элементы матричной алгебры
Командой создается разреженная матрица размерами 6×5 (четвертый и пятый аргументы функции sparse()). Ненулевые элементы размещены на пересечении строк с номерами [1,1,2,2,2,3,5] (первый аргумент функции sparse()) и столбцов с номерами [1,2,1,3,5,1,4] (второй аргумент функции sparse()). Сами значения определяются списком [1,0,3,4,4,1,2] (третий аргумент функции sparse()). Это означает, что например, элемент A(1,1) равен 1, элемент A(1,2) равен 0, элемент A(2,1) равен 3 и так далее (рис. 4.22).
Рис. 4.22. Еще один способ создания разреженной матрицы
На заметку
При создании разреженной матрицы в приведенном выше примере один из элементов указан как нулевой (это элемент с индексами 1 и 2). При отображении списка значений разреженной матрицы в формате индексы/значение такие элементы игнорируются, несмотря на то, что они указывались при создании матрицы в явном виде.
177
Самоучитель Matlab
Некоторые примеры
Я бы не стал увязывать эти вопросы так перпендикулярно.
В. Черномырдин
В этом разделе рассмотрим некоторые примеры решения задач линейной алгебры с использованием средств Matlab. Более детально рассмотрим вопрос о вычислении матричных функций. В частности, вычислим разными способами матричный синус и матричный косинус.
Для вычисления матричного синуса, то есть синуса, |
у |
которого ар- |
|||||||||||||
гумент |
– |
квадратная |
|
|
ˆ |
|
|
|
|
|
|||||
матрица A, используем следующую формулу: |
|||||||||||||||
ˆ |
ˆ |
|
ˆ3 |
|
|
ˆ5 |
|
k ˆ2k +1 |
∞ |
k ˆ2k +1 |
|||||
|
A |
|
A |
|
(−1) |
A |
+... = ∑ |
(−1) |
A |
|
|
||||
sin(A) |
= A − |
|
+ |
|
|
|
−... + |
|
|
|
|
|
. Эта фор- |
||
3! |
5! |
|
(2k |
+1)! |
(2k |
+ |
1)! |
||||||||
|
|
|
|
|
|
k =0 |
|
||||||||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
мула является обобщением для матричного аргумента ряда Тейлора для синуса от скалярного аргумента. Процедуру вычисления такого ряда при
известной матрице ˆ реализуем с помощью специальной функции, код ко-
A
торой приведен ниже:
function M=SinM(A) M=A;
for i=1:100 M=M+(-1)^i*A^(2*i+1)/factorial(2*i+1);
end end
Функция называется SinM(), и у нее один аргумент, который обозначен как A. Как уже отмечалось, предполагается, что это квадратная матрица. Результат записывается в переменную, обозначенную в коде как M. Это тоже будет квадратная матрица. На начальном этапе командой M=A переменнойрезультату присваивается значение переменной-аргумента. Затем запускается оператор цикла, в котором командой M=M+(-1)^i*A^(2*i+1)/ factorial(2*i+1) к текущему значению переменной M добавляется очередное слагаемое ряда.
На заметку
Здесь мы использовали встроенную функцию factorial() для вычисления факториала числа. Для вычисления ряда используется 100 итераций в операторе цикла. Поэтому выражение для матричного синуса получается приближенное. Но если элементы матрицы-аргумента не очень большие, точность будет вполне приемлемой. Что касается самого алгоритма вычисления результата, то он не самый оптимальный, зато по сравнению с другими способами расчетов более наглядный.
178
Глава 4. Элементы матричной алгебры
Программный код функции SinM() в окне редактора m-файлов представлен на рис. 4.23.
Рис. 4.23. Программный код функции для вычисления матричного синуса
Аналогичным способом будем вычислять и матричный косинус. Правда, в этом случае в вычислениях используем следующий ряд
|
|
|
ˆ2 |
|
|
ˆ4 |
|
k ˆ2k |
|
∞ |
k ˆ2k |
|
ˆ |
ˆ |
|
A |
|
A |
|
(−1) A |
ˆ |
+ ∑ |
(−1) A |
|
|
cos(A) = E |
− |
2! |
+ |
|
4 ! |
−... + |
(2k)! |
+... = E |
(2k)! |
. Здесь |
||
|
|
|
|
|
|
k =1 |
|
|||||
|
|
|
|
|
|
|
|
|
|
|
|
через ˆ обозначена единичная матрица того же ранга, что и матрица ˆ. Про-
E A
граммный код функции CosM(), которой по матричному аргументу в качестве результата возвращается матричный косинус, имеет такой вид:
function M=CosM(A) n=length(A); E=eye(n);
M=E;
for i=1:100 M=M+(-1)^i*A^(2*i)/factorial(2*i);
end end
Здесь на начальном этапе командами n=length(A) и E=eye(n) определяется размер матрицы-аргумента и создается единичная матрица такого же размера. Матрица-результат в качестве начального значения получает единичную матрицу (команда M=E).
На заметку
Функцией length()возвращается количество столбцов в матрице-аргументе. Если матрица A квадратная, то количество столбцов равняется количеству строк. Обратите внимание также на то, что в операторе цикла поменялось выражение для слагаемого-добавки ряда.
179
Самоучитель Matlab
Программный код функции CosM() в окне редактора m-файлов представлен на рис. 4.24.
Рис. 4.24. Программный код функции для вычисления матричного косинуса
После того, как обе функции созданы, а соответствующие файлы сохранены, функции можно использовать при вычислениях в командном окне. Для проверки и демонстрации работоспособности созданных функций в командном окне вводим такой код (жирным шрифтом выделен ввод пользователя):
>> A=[pi/2 pi/3;pi/4 pi]
A =
1.5708 1.0472
0.7854 3.1416
>>SinM(A) ans =
0.6878 -0.5752 -0.4314 -0.1750
>>CosM(A)
ans =
0.1750 -0.5752 -0.4314 -0.6878
>> SinM(A)^2+CosM(A)^2 ans =
1.0000 0.0000
0.0000 1.0000
Сначала создаем квадратную матрицу A размерами 2×2. Затем командами SinM(A) и CosM(A) последовательно вычисляем матричный синус и косинус. Интересным может показаться результат вычисления выражения SinM(A)^2+CosM(A)^2. В результате получаем единичную матрицу. Уди-
180