Создание матриц: литералы и генераторы
От ручного перечисления чисел до генераторов нулей, единиц и случайных матриц.
Литерал матрицы — запись в квадратных скобках, где пробел/запятая разделяют элементы строки, а точка с запятой — строки.
Ручная запись
Самый прямой способ — перечислить элементы. Внутри одной строки элементы разделяют пробелом или запятой, строки — точкой с запятой. Все строки обязаны быть одной длины, иначе MATLAB выдаст ошибку о несогласованных размерах.
A = [1 2 3; 4 5 6]; % матрица 2x3
B = [1, 2; 3, 4]; % запятые тоже допустимы
Генераторы стандартных матриц
Руками задавать большие матрицы бессмысленно. Для типовых заготовок есть функции: zeros(m,n) — нули, ones(m,n) — единицы, eye(n) — единичная матрица (диагональ из единиц), rand(m,n) — случайные числа в [0,1), randn — нормальное распределение. Если передать один аргумент n, получится квадратная матрица n×n.
Z = zeros(2,3); % нули 2x3
O = ones(3); % единицы 3x3
I = eye(3); % единичная 3x3
R = rand(2,2); % случайные [0,1)
Вывод (I):
I =
1 0 0
0 1 0
0 0 1
Сборка из блоков
Матрицы можно склеивать как кирпичи — это называется конкатенацией. Горизонтально — через пробел/запятую, вертикально — через точку с запятой, лишь бы совпадали размеры стыкуемых сторон. Это тот же синтаксис литерала, только вместо чисел — целые матрицы.
a = [1 2];
b = [3 4];
h = [a b]; % 1x4: 1 2 3 4 (по горизонтали)
v = [a; b]; % 2x2 (по вертикали)
Параллель с NumPy
Если вы знаете NumPy, аналогии очевидны: zeros, ones, eye называются так же, а rand похож на numpy.random.rand. Разница в записи литерала: в MATLAB строки разделяют ; прямо в скобках, в NumPy — вложенными списками [[1,2],[3,4]]. И помните: в MATLAB генераторы по умолчанию создают тип double, тогда как в NumPy тип нужно держать в голове.
Как работает под капотом
Функции вроде zeros сразу выделяют непрерывный блок памяти нужного размера. Это даёт важный приём оптимизации — предварительное выделение (preallocation). Если вы собираетесь заполнять матрицу в цикле, сначала создайте её через zeros, а потом записывайте элементы. Иначе при каждом расширении MATLAB вынужден копировать весь массив в новое, большее место памяти — и цикл становится квадратично медленным.
Частые ошибки
- Строки разной длины в литерале —
[1 2; 3 4 5]вызовет ошибку. - Конкатенация несовместимых блоков: склеить по вертикали матрицы с разным числом столбцов нельзя.
- Заполнять растущую матрицу в цикле без preallocation — медленно на больших размерах.
Случайные матрицы и воспроизводимость
Функции rand и randn заслуживают отдельного слова. В научных расчётах случайность нужна постоянно — для имитационного моделирования, инициализации алгоритмов, генерации тестовых данных. Но «случайный» расчёт, который при каждом запуске даёт другой результат, трудно отлаживать и невозможно воспроизвести в отчёте. Поэтому генератор случайных чисел в MATLAB псевдослучаен: им управляет внутреннее состояние, которое можно зафиксировать командой rng(0) (любое число вместо нуля задаёт «зерно»). После этого последовательность rand станет повторяемой — тот же зерно даёт ту же последовательность. Это стандартная практика: ставить rng в начале скрипта, чтобы результаты можно было воспроизвести.
Специальные конструкторы
Помимо базовых генераторов есть удобные специализированные. diag(v) строит матрицу с вектором v на диагонали (а diag(A), наоборот, извлекает диагональ матрицы — функция работает в обе стороны в зависимости от аргумента). repmat(A, m, n) тиражирует блок A в сетку m×n — удобно для построения периодических структур. reshape(A, r, c) переформирует матрицу, не меняя данные, лишь перераспределяя их по новым размерам (помня про column-major порядок). Эти функции вместе с генераторами покрывают почти любую потребность в создании структурированных матриц без единого цикла.
Итоги
- Литерал: пробел/запятая — элементы строки,
;— новая строка. zeros/ones/eye/randгенерируют типовые матрицы; одиночный аргумент — квадрат.- Перед заполнением в цикле выделяйте память заранее через
zeros.