Домашнее задание#
Задание 1. Генератор случайных матриц.#
Реализовать генератор матриц, который должен поддерживать функции:
Генерация абсолютно случайной матрицы \(n\times m\)
Генерация случайной диагональной матрицы \(n\times n\)
Генерация случайной верхнетреугольной матрицы
Генерация случайной нижнетреугольной матрицы
Генерация симметричной матрицы
Генерация вырожденной матрицы
Генерация матрицы ступенчатого вида \(n\times n\) ранга \(m\)
Генерация возмущения матрицы \(n\times m\), каждый элемент которой не превосходит по модулю заданный \(\varepsilon\). Оценить величину нормы матрицы возмущений в зависимости от параметра \(\varepsilon\) (оценить верхную границу).
Оценить численно вероятность того, что созданная матрица будет вырожденной для какого-либо случая выше.
# Реализую произвольную m,n, верхнетреугольную и симметричную. Остальное на вас - вам нужно дописать функцию.
# Не забудьте откомментировать ваши изменения в документации к функции!
import numpy as np
def matrix_generate(rows, columns, type_ = "full", eps = 0):
"""
matrix_generate(rows, columns, type_ = "full")
Создаёт случайную матрицу выбранного типа.
Если матрицу нужных размеров создать нельзя должен выдать
строку f"Error with type {type_} and shape ({rows},{columns})".
Parameters
----------
rows : int
Количество строк в создаваемой матрице.
columns : int
Количество столбцов в создаваемой матрице.
type_ : str, optional
Тип создаваемой матрицы: "full", "upper_triangular", "symmetric" и т.д.
eps: float, optional
Дополнительное число, использующееся при генерации для некоторых типов матриц.
Returns
-------
out : ndarray or str
Выдаёт матрицу нужного типа либо ошибку.
Notes
-----
Поддерживаемые типы матриц:
"full","upper_triangular",
"symmetric",
...
"""
A = None
if type_ == "full":
0,
A = np.random.random(size=(rows, columns))
elif type_ == "upper_triangular":
A = np.random.random(size=(rows, columns))
for i in range(rows):
for j in range(columns):
if (i > j):
A[i, j] = 0
# Для нижнетреугольной подумайте, как сделать без циклов for :) (звёздочка)
elif type_ == "symmetric":
if rows != columns:
return f"Error with type {type_} and shape ({rows},{columns})"
else:
A = np.random.random(size=(rows, columns))
for i in range(rows):
for j in range(columns):
if (i > j):
A[i, j] = A[j, i]
# И эту секцую тоже перепишите без for (звёздочка). Учтите, что портить uniform распределение нельзя.
return A
matrix_generate(1, 3)
array([[0.92729915, 0.46372064, 0.3302204 ]])
matrix_generate(4, 4, type_ = "upper_triangular")
array([[0.29095118, 0.48243508, 0.33314696, 0.11652231],
[0. , 0.38207998, 0.3216804 , 0.19134324],
[0. , 0. , 0.19209787, 0.8512658 ],
[0. , 0. , 0. , 0.83580995]])
matrix_generate(4, 3, type_ = "upper_triangular")
array([[0.53609234, 0.36418414, 0.88111427],
[0. , 0.98355036, 0.59701315],
[0. , 0. , 0.73738553],
[0. , 0. , 0. ]])
matrix_generate(4, 4, type_ = "symmetric")
array([[0.1556073 , 0.68119342, 0.99206063, 0.21796994],
[0.68119342, 0.11418224, 0.15759881, 0.11224172],
[0.99206063, 0.15759881, 0.70145001, 0.26590431],
[0.21796994, 0.11224172, 0.26590431, 0.03111788]])
matrix_generate(4, 1, type_ = "symmetric")
'Error with type symmetric and shape (4,1)'
Задание 2. Вычисление матричных норм и числа обусловленности.#
Реализовать вычисление трех основных норм векторов (L1, L2 и максимальную) и подчиненных им матричных норм. Реализовать вычисление числа обусловленности.
Примечание: для вычисления собственных значений можно использовать linalg.eigvals из модуля scipy.
Задание 3. Эквивалентность первых двух норм.#
Найдите константы \(C_1\) и \(C_2\) такие, что
\(\ C_1||\mathbf{x}||_2\leq||\mathbf{x}||_1\leq C_2||\mathbf{x}||_2\)
Указание: в качестве подсказки можно использовать визуализацию норм из документа с теорией.
Задание 4. Евклидова и бесконечная норма.#
Пусть x — вектор размерности m, а A — матрица m×n. Докажите следующие неравенства и приведите примеры таких x и A, при которых неравенства обращаются в равенства:
\(\|x\|_2 \leq \sqrt{m} \cdot \|x\|_{\infty}\)
\(\|A\|_{\infty} \leq \sqrt{n} \cdot \|A\|_2\)
Задание 5. Норма Фробениуса.#
Докажите, что для любой унитарной матрицы U (и для произвольной матрицы A) имеет место равенство
\(\| U A \|_F = \| AU \|_F = \| A \|_F\) ,
где \(\| \cdot \|_F\) — норма Фробениуса.
Указание.
Задачу можно решить без вычислений, если использовать геометрический смысл нормы Фробениуса и геометрические свойства умножения на унитарную матрицу (что при умножении на неё сохраняется).
Задание 6*. Тензорная свёртка.#
Рассмотрим функцию, отображающую шесть тензоров на один тензор: \(Z\left(\lambda^{(1)}, \lambda^{(2)}, \lambda^{(3)}, \Gamma^{(1)}, \Gamma^{(2)}, U\right)\) :
редположив, что все индексы пробегают значения от 1 до χ, проведите эксперимент и сравните скорость различных реализаций функции Z. Исследуйте значения χ в диапазоне 3–50.
В файле convolution. ipynb вы можете найти релизацию глупого способа вычисления этой свертки, который требует \(\chi^4 \times \chi^6=\chi^{10}\) операций. На самом деле это можно вычислить гораздо быстрее!
С помощью функции numpy . einsum (нужно использовать аргумент optimize), можно добиться намного большей производительности. Чтобы понять, что происходит под капотом, воспользуйтесь функцией numpy.einsum_path. Какое минимальное количество операций требуется для вычисления \(Z\) ?
Посмотрев на вывод функции numpy.einsum_path, peализуйте алгоритм для вычисления \(Z\), который столь же эффективен, как numpy.einsum, но использует более элементарные numpy.dot и numpy.tensor_dot.