Матричное умножение * и поэлементное .*
Самое важное различие в арифметике MATLAB: звёздочка с точкой и без неё — это две разные операции.
Оператор
*— это матричное умножение (строка на столбец), а.*— поэлементное (каждый с каждым по позиции).
Две разные звёздочки
Новички в MATLAB чаще всего спотыкаются именно здесь. A * B выполняет настоящее матричное умножение: число столбцов A должно совпасть с числом строк B, и результат считается по правилу «строка на столбец». А A .* B умножает соответствующие элементы — для этого матрицы должны быть одного размера. То же различие у деления (/ и ./) и степени (^ и .^).
A = [1 2; 3 4];
B = [5 6; 7 8];
A * B % матричное: строка на столбец
A .* B % поэлементное: 1*5, 2*6, 3*7, 4*8
Вывод:
ans = % A*B
19 22
43 50
ans = % A.*B
5 12
21 32
Почему точка означает «поэлементно»
Запомнить легко: точка перед оператором всегда говорит «делай это с каждым элементом по отдельности». .^2 возводит каждый элемент в квадрат, ./ делит поэлементно. Без точки операторы трактуются в смысле линейной алгебры. В научном коде поэлементные операции встречаются постоянно: вычислить функцию на векторе точек — это y = x.^2, а не x^2 (последнее для вектора вообще вызовет ошибку или другой результат).
x = [1 2 3 4];
y = x.^2 % 1 4 9 16 — каждый в квадрат
z = x .* x % то же самое поэлементно
Размеры должны сходиться
| Операция | Требование к размерам |
A * B | столбцы A = строки B |
A .* B | одинаковые размеры (или broadcast) |
Как работает под капотом
Начиная с версии R2016b MATLAB поддерживает неявное расширение (broadcasting), как в NumPy: [1 2 3] .* [10; 20] растянет строку и столбец до матрицы 2×3. Это удобно, но и коварно — раньше такой код давал ошибку размерности, а теперь молча считает не то, что вы хотели. Поэтому при поэлементных операциях полезно мысленно проверять, что размеры действительно совпадают, а не «удачно» расширяются.
Частые ошибки
- Написать
x^2вместоx.^2для вектора — это попытка матричной степени, она требует квадратной матрицы. - Считать
A*BиA.*Bодинаковыми — они почти никогда не совпадают. - Полагаться на broadcasting там, где на самом деле нужна ошибка о несовпадении размеров.
Скалярное и матричное произведение векторов
На различии * и .* держится и работа с векторами. Скалярное произведение двух векторов — это сумма попарных произведений; в MATLAB его получают как a * b' (строка на столбец даёт число) или эквивалентно sum(a .* b). А вот a' * b для векторов-столбцов даст внешнее произведение — целую матрицу. Перепутать эти две формы легко, а результаты у них принципиально разные: число против матрицы. Привычка проверять размеры спасает и здесь: если на выходе ожидалось число, а получилась матрица, значит, транспонирование стоит не там.
Степень матрицы против поэлементной степени
Различие точки касается и возведения в степень, и здесь оно особенно коварно. A^2 для квадратной матрицы означает A * A — настоящее матричное произведение, имеющее смысл в линейной алгебре (например, для марковских цепей). А A.^2 возводит в квадрат каждый элемент по отдельности. Для прямоугольной матрицы A^2 вообще не определено и вызовет ошибку, тогда как A.^2 работает всегда. В научных расчётах поэлементная форма нужна гораздо чаще — почти любая формула, где переменная стоит под функцией, требует точки. Поэтому, встретив степень или умножение в коде на векторах и матрицах данных, первым делом проверьте, не должна ли там стоять точка.
Итоги
*,/,^— операции линейной алгебры (строка на столбец).- Точка —
.*,./,.^— поэлементные операции. - Для функций на векторе почти всегда нужна точечная (поэлементная) форма.