Вход для сдачи

Класс 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»).

A: Конструктор и repr

Создайте новый класс Mat для матриц 2 × 2. Можете хранить данные внутри как угодно.
Конструктор __init__ принимает ровно 4 числа типов int или float.

Метод __repr__ должен возвращать строку, из которой можно создать в точности такую же матрицу.

Добавьте также константу E — единичную матрицу.

print(repr(Mat(0, 0, 0, 0))) print(repr(Mat(1, 2, 3, 4))) print(repr(Mat(1.0, -2.2, 3.3, -4.4))) print(repr(E))
Mat(0, 0, 0, 0) Mat(1, 2, 3, 4) Mat(1.0, -2.2, 3.3, -4.4) Mat(1, 0, 0, 1)

B: Человекочитаемое представление

Реализуйте метод __str__, который будет выводить удобное для человека представление матрицы. См. примеры. Сделайте так, чтобы все элементы матрицы имели одинаковую минимальную ширину. Для выравнивания можно использовать конструкцию вида str(x).rjust(5).

print(Mat(0, 1, -2, 300)) print(Mat(10000, 2, 3, 4)) print(Mat(7.14, 2.123123, 3.123123, 4.23))
/  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: Сложение и вычитание матриц

Реализуйте методы для сложения и вычитания матриц друг с другом.

print(E + E) print(E - E) a = Mat(1, 2, 3, 4) b = Mat(9, 7, 5, 3) print(a + b) print(b - a)
/2 0\ \0 2/ /0 0\ \0 0/ /10 9\ \ 8 7/ / 8 5\ \ 2 -1/

D: Умножение матриц на число

Реализуйте методы для умножения матриц на число, чисел на матрицы, а также для деления матрицы на число.

print(7 * E) print(E * 7) print(Mat(1, 2, 3, 4) / 2)
/7 0\ \0 7/ /7 0\ \0 7/ /0.5 1.0\ \1.5 2.0/

E: Умножение матриц друг на друга

Реализуйте метод __matmul__ для умножения матриц друг на друга при помощи оператора матричного умножения @.

print(E @ E) a = 7 * E print(a @ a) print(Mat(1, 2, 3, 4) @ Mat(1, -2, 3, 4))
/1 0\ \0 1/ /49 0\ \ 0 49/ / 7 6\ \15 10/

F: Возведение в степень

Реализуйте методы для быстрого возведения в натуральную степень. Обратите внимание, умножение матриц — это a @ a, а не a * a.

print(E ** 179) a = 2 * E print(a ** 10) b = Mat(1, 1, 0, 1) print(b ** 179179179) print(Mat(0, 1, 1, 1) ** 10)
/1 0\ \0 1/ /1024 0\ \ 0 1024/ / 1 179179179\ \ 0 1/ /34 55\ \55 89/

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} . $$ Это позволяет находить числа Фибоначчи при помощи быстрого возведения матрицы в степень.

На вход даётся натуральное число. Выведите соответствующее число Фибоначчи.

3
2
30
832040
300
222232244629420445529739893461909967206666939096499764990979600

H: Обращение матрицы

Матрица $B$ называется обратной для матрицы $A$, если $AB = BA = E$. Добавьте метод inv, который либо возвращает обратную матрицу, либо возвращает ошибку ValueError('Not invertible') (при помощи raise).
Также добавьте возможность возводить не только в натуральную степень, но и в целую.

print(E.inv()) print(Mat(1, 1, 1, 2).inv()) print(Mat(1, 1, 1, 2) ** -1) print(Mat(1, 1, 1, 2) ** -3) try: Mat(0, 0, 0, 0).inv() except ValueError as e: print(e)
/1.0 0.0\ \0.0 1.0/ / 2.0 -1.0\ \-1.0 1.0/ / 2.0 -1.0\ \-1.0 1.0/ /13.0 -8.0\ \-8.0 5.0/ Not invertible