Работа с матрицами и массивами
Линейная алгебра
Рассмотрим подробнее арифметические операции над векторами (одномерными массивами) и матрицами (двумерными массивами). Набор арифметических операций в MATLAB состоит из стандартных операций сложения-вычитания, умножения-деления, операции возведения в степень и дополнен специальными матричными операциями. Матричные операции сложения и вычитания действуют поэлементно, а остальные операции - нет, они являются матричными операциями. Если операция применяется к матрицам, размеры которых не согласованы, то будет выведено сообщение об ошибке. При умножении (сложении, вычитании, делении) матрицы на число соответствующая операция всегда производится поэлементно.
Например,
A=[0 1; 2 3], B=ones(size(A))
Результатом матричного умножения A*B будет
ans =
1 1
5 5
Теперь применим поэлементную операцию: A.*B:
ans =
0 1
2 3
Добавление матрицы к ее транспонированной дает симметричную матрицу.
A = magic(4);
А + А'
ans =
32 7 12 17
7 22 17 22
12 17 12 27
17 22 27 2
Умножение матрицы на ее транспонированную также дает симметричную матрицу.
А'*А
ans =
378 206 212 360
206 370 368 212
212 368 370 206
360 212 206 378
Определитель этой частной матрицы оказывается равным нулю, означая, что эта матрица является сингулярной.
d = det(A)
d =
Приведенная к строкам ступенчатая форма матрицы А выглядит следующим образом:
R = rref(A)
R =
1 0 0 1
0 1 0 3
0 0 1 -3
0 0 0 0
Поскольку заданная матрица является сингулярной, то она не имеет обратной. Если всё-таки попытаться ее определить
X = inv(A)
то будет получено предупреждение
Warning: Matrix is close to singular or badly scaled.
Results may be inaccurate. RCOND = 4.625398e-018.
Ошибка округления препятствует алгоритму обращения матрицы при определении точной сингулярности. Но значение rcond, которое устанавливает условие оценки для обратной матрицы, имеет порядок eps, относительной точности числа с плавающей точкой, поэтому вычисление обратной матрицы не очень желательно.
Интересно найти собственные значения магического квадрата
e = eig(A)
е =
34.0000
8.9443
-8.9443
-0.0000
Одно из собственных значений равно нулю, что является следствием сингулярности. Самое большое собственное значение равно 34, магической сумме. Это происходит потому, что вектор, состоящий из всех единиц, является собственным вектором:
v=ones(4,1);
A*v
ans =
Когда магический квадрат нормируется на его магическую сумму
P = A/34,
результат будет бистохастической матрицей, у которой суммы в строках и столбцах все равны единицам.
P =
0.4706 0.0588 0.0882 0.3824
0.1471 0.3235 0.2941 0.2353
0.2647 0.2059 0.1765 0.3529
0.1176 0.4118 0.4412 0.0294
Такие матрицы представляют собой вероятность перехода в Марковском процессе. Повторные возведения матрицы в степень являются повторными шагами в этом процессе. Для нашего примера, пятая степень
P^5
равна
ans =
0.2511 0.2491 0.2492 0.2506
0.2495 0.2504 0.2502 0.2499
0.2501 0.2498 0.2496 0.2505
0.2494 0.2508 0.2509 0.2489
Из этого видно, что если k стремятся к бесконечности, тогда все элементы в матрице Pk стремятся к 1/4.
В заключение, рассмотрим коэффициенты характеристического полинома
Poly (А)
ans =
1.0e+003 *
0.0010 -0.0340 -0.0800 2.7200 0.0000
Из чего следует, что характеристический полином
det(A-λI)
равен
λ4 - 34λ3 - 80λ2 + 2720λ
Константа равна нулю, так как матрица является сингулярной, а коэффициент при третьей степени равен 34, так как матрица магическая.
Оперция «матричное деление» требует специальных комментариев. Если A является обращаемой квадратной матрицей, а b - вектор-столбец или вектор-строка соответственно, тогда x = A\b является решением уравнения Ax = b, а x = b/A является решением уравнения xA = b. Если A - квадратная матрица, то при левом делении для факторизации используется метод исключения Гаусса и эта факторизация позволяет решить уравнение Ax = b. Если матрица не квадратная, то для ее факторизации используется метод ортогонализации Хаусхолдера c ведущим столбцом, а приведенная матрица используется для решения недо- или переопределенной системы уравнений в смысле наименьших квадратов. Правое деление определяется в терминах левого деления по формуле b/A = (A'\b') '.
Массивы
Для поэлементного выполнения операций умножения, деления и возведения в степень (т.е. для операций, выполняемых над массивами, а не над матрицами) применяются комбинированные знаки (точка и знак операции). Например, если за матрицей стоит знак (^), то она возводится в степень, а комбинация (.^) означает возведение в степень каждого элемента матрицы (массива).
Операции над массивами полезны для создания таблиц. Пусть n - это вектор-столбец
n = (0:9)';
Тогда
pows = [n n.^2 2.^n]
создает таблицу квадратов и степеней двойки.
Элементарные математические функции работают с массивами поэлементно. Так
Format short g
х = (1:0.1:2)';
logs = [x log10(x)]
создает таблицу логарифмов.
Логические операции
Операторы отношения и логические операторы, а также соответствующие им команды позволяют проводить сравнения массивов одинакового размера. Результатом таких операций являются матрицы из нулей и единиц, причем единица означает истинность, а нуль - ложь.
Операции отношения
Символ | Назначение | Имя функции |
< | Меньше | lt |
>= | Больше или равно | ge |
> | Больше | gt |
<= | Меньше или равно | le |
== | Равно | eq |
~= | Не равно | ne |
При попытке сравнения векторов или матриц различной размерности будет выведено сообщение об ошибке. При сравнении скаляра с матрицей сначала из скалярной переменной создается матрица нужного размера, и уже затем происходит сравнение.
Операции (==, ~=) проводят сравнение вещественных и мнимых частей комплексных чисел, а операции (>, <, >=, <=) - только вещественных частей.
Логические поэлементные операции
Символ | Назначение | Имя команды |
& | Логическое «и» | and |
| | Логическое «или» | or |
~ | Отрицание | not |
Для логических операций ненулевое число отождествляется с единицей. Приведем примеры:
■
a = [1 2; 3 4]; % ввод матрицы
b = 2; % ввод скаляра
c = a>b % результат сравнения - матрица
с =
0 0
1 1
a ~= c % сравнение матриц - матрица
ans =
1 1
1 1
Логические операции можно записывать в виде функций. Так, последнее сравнение представимо в виде:
ne (a,c) % функция сравнения матриц
Необходимость логических операций возникает, например, в условных операторах языка М ATLAB. При этом арифметические операции всегда имеют приоритет по отношению к логическим.
Замечание 1. Если операнды – скаляры, то вместо поэлементных операций & и | предпочтительней пользоваться так называемыми «краткими» операциями && (И) и || (ИЛИ) соответственно. Их польза состоит в том, что если значение всего выражения можно оценить на основании лишь первого операнда, то второй не вычисляется. Например, в следующей строчке, пользуясь операцией && вместо &, мы можем избежать вывода на дисплей предупреждения о делении на нуль, если b=0:
p=2; q=0; x = (q ~= 0) && (p/q > 18.5)
А в следующем примере можно избежать ошибочной ситуации, если файл myfun.m не обнаружен:
comp = (exist('myfun.m') == 2) && (myfun(x) >= y).
Замечание 2. Когда операции & и | осуществляются не самостоятельно, а внутри логических операторов if и while, то они выполняются в порядке “кратких” (как && и ||), но по-прежнему оставаясь поэлементными.
С учётом логических операций общая таблица приоритетов в порядке убывания выглядит так:
1. Скобки ()
2. Транспонирование (.'), возведение в степень (.^), комплексно-сопряжённое транспонирование ('), матричное возведение в степень (^).
3. Унарный плюс (+), унарный минус(-), логическое отрицание (~).
4. Умножение (.*), правое деление (./), левое деление (.\), матричное умножение (*), матричное правое деление (/),матричное левое деление (\).
5. Сложение (+), вычитание (-).
6. Оператор двоеточие (:).
7. Меньше (<), меньше или равно (<=), больше (>), больше или равно (>=), равно (==), не равно (~=).
8. Поэлементное И (&).
9. Поэлементное ИЛИ (|).
10. “Краткое” И (&&)
11. “Краткое” ИЛИ (||)
Функции, возвращающие значения логического типа
Элементарные логические операции дополнены набором функций МATLAB, позволяющих проверить для матриц некоторые условия. Проверка для матриц проводится по столбцам, при этом функция возвращает вектор-строку. Результатом проверки для вектора является число. Функции вида is* осуществляют поэлементные проверки в массивах и чаще всего возвращают скаляр.
Некоторые команды проверки и сравнения
Имя | Назначение |
find | Поиск значений согласно заданному условию; определение индексов |
all | Проверка того, что все элементы не равны нулю |
any | Проверка того, что хотя бы один элемент не равен нулю |
isempty | Выявление пустого массива |
isequal | Проверка равенства матриц (поэлементно, ответ – скаляр) |
issparse | Проверка матрицы на разреженность |
nonzeros | Вывод ненулевых элементов массива |
isfinite | Выявление ограниченных элементов массива |
isnumeric | Проверка, является ли массив числовым |
isinf | Выявление бесконечных элементов массива |
isnan | Выявление элементов нечислового типа |
isletter | Проверка на символ |
isstr | Проверка на строковую переменную |
isglobal | Проверка на глобальную переменную |
strcmp | Сравнение двух строк |
Проиллюстрируем некоторые из этих команд на примерах.
Проверим массив с на наличие ненулевых элементов:
Any(c')
ans =
0 1
Ряд функций дает возможность выявить пустую переменную (isempty), идентичность матриц (isequal), ответить, числовой ли это массив (isnumeric):
[islogical(c) isnumeric(c) isempty([]) isempty(c) isequal(a,c)]
ans =
1 0 1 0 0
Команда find возвращает индексы элементов массива, удовлетворяющих некоторому условию. Например, для массива с, полученного ранее, команда поиска элементов, тождественно равных единице, выведет:
d=find(c==1)
d =
Заметим, что результат содержит ссылки на два единичных элемента массива с, при этом используется одномерная индексация. Напомним, что матричные данные размещаются в памяти последовательно по столбцам.
Логическая индексация
Результатом выполнения логических операторов и операторов сравнения являются массивы логического типа данных, в которых каждый элемент занимает 1 байт памяти. Логические вектора, созданные таким образом, могут быть использованы для ссылки на подмассивы. Предположим, что X обыкновенная матрица и L матрица того же размера, но содержащая результаты логических операций. Тогда X(L) задает те элементы X, для которых соответствующие элементы L - ненулевые.
Пусть имеетcя следующий набор данных.
x = [2.1 1.7 1.6 1.5 NaN 1.9 1.8 1.5 5.1 1.8 1.4 2.2 1.6 1.8];
NaN - это метка для недостающего наблюдения, как например ошибка при ответе на вопрос анкеты. Для того, чтобы yбpaть метку, следует использовать функцию isfinite(x),которая является истиной для всех конечных численных значений и ложью для NaN и Inf (можно воспользоваться и функцией isnan).
x = x(isfinite(x))
х =
2.1 1.7 1.6 1.5 1.9 1.8 1.5 5.1 1.8 1.4 2.2 1.6 1.8
Сейчас осталась одна наблюдаемая величина, 5.1, заметно отличающаяся от остальных, - это выброс. Последующие действия устраняют выбросы, в данном случае те элементы, для которых среднеквадратичное отклонение более чем в три раза отличается от среднего.
x = x(abs(x-mean(x)) <= 3*std(x))
х =
2.1 1.7 1.6 1.5 1.9 1.8 1.5 1.8 1.4 2.2 1.6 1.8
Приведем еще пример выделения нужных данных из массива. Рассмотрим задачу нахождения простых чисел в магическом квадрате. В MATLAB имеется команда isprime, проверяющая число на простоту:
A = magic(4);
k = find(isprime(A))'
k =
2 5 6 7 9 13
Покажем эти числа, как вектор-строку в порядке, определенном функцией.
A (k)
ans =
5 2 11 7 3 13
Если использовать k как индекс с левой стороны в операторе присваивания, то матричная структура сохранится:
A(k) = NaN
А =
16 NaN NaN NaN
NaN NaN 10 8
9 NaN 6 12
4 14 15 1