Класс Mat
матриц 2 × 2
В этой контрольной мы будем реализовывать класс матриц 2 × 2 Mat
.
Как и во всех листках про классы, при сдаче в тестирующую задач на доработку методов класса в программу необходимо добавить
"""Описание класса""" import sys exec(sys.stdin.read())или
"""Описание класса""" exec(open('input.txt').read())
Матрицы
Матрица в математике и информатике — это прямоугольная таблица чисел. Например: $$ \begin{pmatrix} 1 & 3 & -1 \\ 2 & 3 & 8 \end{pmatrix}. $$ Оказывается, что если определить на этих таблицах несколько операций, то они превращаются в очень мощный инструмент.
Сейчас мы будем рассматривать только матрицы, в которых ровно 2 строки и ровно 2 столбца (пишут «матрицы 2 × 2»).
- Сложение и вычитание матриц: эти операции производятся поэлементно: $$ \begin{pmatrix} a & b \\ c & d \end{pmatrix} + \begin{pmatrix} p & q \\ r & t \end{pmatrix} = \begin{pmatrix} a+p & b+q \\ c+r & d+t \end{pmatrix} , $$ $$ \begin{pmatrix} a & b \\ c & d \end{pmatrix} - \begin{pmatrix} p & q \\ r & t \end{pmatrix} = \begin{pmatrix} a-p & b-q \\ c-r & d-t \end{pmatrix} . $$
- Умножение матрицы на число: производится умножением каждого элемента матрицы на это число: $$ \lambda \begin{pmatrix} a & b \\ c & d \end{pmatrix} = \begin{pmatrix} \lambda a & \lambda b \\ \lambda c & \lambda d \end{pmatrix} $$
- Умножение матриц: чтобы получить элемент в $i$-й строке и в $j$-м столбце нужно скалярно перемножить $i$-ю вектор-строку первой матрицы и $j$-й вектор-столбца второй. В этой сложной фразе можно не разбираться, а просто использовать формулу: $$ \begin{pmatrix} a & b \\ c & d \end{pmatrix} \cdot \begin{pmatrix} p & q \\ r & t \end{pmatrix} = \begin{pmatrix} ap+br & aq+bt \\ cp+dr & cq+dt \end{pmatrix} . $$
- Возведение в натуральную степень: матрица в степени $n$ — это просто произведение $n$ её «копий», всё как с числами.
- Нулевая матрица: $\begin{pmatrix} 0 & 0 \\ 0 & 0 \end{pmatrix} $ часто обозначается просто через 0. Ведёт она соответствующим образом: при сложении ничего не меняет, при умножении всё делает нулём.
- Единичная матрица: $\begin{pmatrix} 1 & 0 \\ 0 & 1 \end{pmatrix} $ часто обозначается через $E$. Ведёт она соответствующим образом: при умножении ничего не меняет.
A: Конструктор и repr
Создайте новый класс Mat
для матриц 2 × 2.
Можете хранить данные внутри как угодно.
Конструктор __init__ принимает ровно 4 числа типов int или float.
Метод __repr__ должен возвращать строку, из которой можно создать в точности такую же матрицу.
Добавьте также константу E — единичную матрицу.
B: Человекочитаемое представление
Реализуйте метод __str__
, который будет выводить удобное для человека представление матрицы.
См. примеры.
Сделайте так, чтобы все элементы матрицы имели одинаковую минимальную ширину.
Для выравнивания можно использовать конструкцию вида str(x).rjust(5)
.
/ 0 1\ \ -2 300/ /10000 2\ \ 3 4/ / 7.14 2.123123\ \3.123123 4.23/
ml = max(len(str(a)), len(str(b)), len(str(c)), len(str(d))) return '/{:{ml}} {:{ml}}\\\n\\{:{ml}} {:{ml}}/'.format(a, b, c, d, ml=ml)
C: Сложение и вычитание матриц
Реализуйте методы для сложения и вычитания матриц друг с другом.
D: Умножение матриц на число
Реализуйте методы для умножения матриц на число, чисел на матрицы, а также для деления матрицы на число.
E: Умножение матриц друг на друга
Реализуйте метод __matmul__
для умножения матриц друг на друга при помощи оператора матричного умножения @
.
F: Возведение в степень
Реализуйте методы для быстрого возведения в натуральную степень.
Обратите внимание, умножение матриц — это a @ a
, а не a * a
.
G: Числа Фибоначчи
Пусть $F_{n-1}$ и $F_{n}$ — два соседних числа Фибоначчи. Выразим два следующих через них: $$ \begin{aligned} F_{n} &= 0 \cdot F_{n-1} + 1 \cdot F_n \\ F_{n+1} &= 1 \cdot F_{n-1} + 1 \cdot F_n \end{aligned} $$ При помощи матриц это можно записать так: $$ \begin{pmatrix} F_{n} \\ F_{n+1} \end{pmatrix} = \begin{pmatrix} 0 & 1 \\ 1 & 1 \end{pmatrix} \cdot \begin{pmatrix} F_{n-1} \\ F_{n} \end{pmatrix} . $$ Теперь если $F_0=0$ и $F_1=1$ — нулевое и первое числа Фибоначчи, то: $$ \begin{pmatrix} F_{2} \\ F_{3} \end{pmatrix} = \begin{pmatrix} 0 & 1 \\ 1 & 1 \end{pmatrix} \cdot \begin{pmatrix} F_{1} \\ F_{2} \end{pmatrix} = \begin{pmatrix} 0 & 1 \\ 1 & 1 \end{pmatrix} \cdot \begin{pmatrix} 0 & 1 \\ 1 & 1 \end{pmatrix} \cdot \begin{pmatrix} F_{0} \\ F_{1} \end{pmatrix} = \begin{pmatrix} 0 & 1 \\ 1 & 1 \end{pmatrix}^2 \cdot \begin{pmatrix} F_{0} \\ F_{1} \end{pmatrix} . $$
Из этого всего можно сделать замечательный вывод: $$ \begin{pmatrix} 0 & 1 \\ 1 & 1 \end{pmatrix}^n = \begin{pmatrix} F_{n-1} & F_n \\ F_n & F_{n+1} \end{pmatrix} . $$ Это позволяет находить числа Фибоначчи при помощи быстрого возведения матрицы в степень.
На вход даётся натуральное число. Выведите соответствующее число Фибоначчи.
H: Обращение матрицы
Матрица $B$ называется обратной для матрицы $A$, если $AB = BA = E$.
Добавьте метод inv
, который либо возвращает обратную матрицу, либо возвращает ошибку ValueError('Not invertible')
(при помощи raise
).
Также добавьте возможность возводить не только в натуральную степень, но и в целую.