Матричное умножение * и поэлементное .*

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

Итоги

  • *, /, ^ — операции линейной алгебры (строка на столбец).
  • Точка — .*, ./, .^ — поэлементные операции.
  • Для функций на векторе почти всегда нужна точечная (поэлементная) форма.
Проверьте себя
1. Чем отличается A * B от A .* B?
AНичем
B* — матричное умножение, .* — поэлементное
C* — для чисел, .* — для матриц
D.* быстрее
2. Как возвести каждый элемент вектора x в квадрат?
Ax^2
Bx.^2
Cx*2
Dsquare(x)
3. Какое условие нужно для A * B?
AОдинаковые размеры
BЧисло столбцов A = число строк B
CОбе квадратные
DНикаких