Попробуйте сначала округлить его перед преобразованием в int.
np.around(I).astype(int)
Создание случайной матрицы:
>>> M = np.random.random((4,4))
>>> M
array([[0.51351957, 0.57864882, 0.0489495 , 0.85066216],
[0.60052988, 0.93844708, 0.74651889, 0.17237584],
[0.26191596, 0.46451226, 0.46514401, 0.81917544],
[0.19247662, 0.82801899, 0.83839146, 0.08531949]])
В обратном порядке:
>>> from numpy.linalg import inv
>>> Mi = inv(M)
>>> Mi
array([[-1.3515514 , 3.53647196, 1.0391335 , -3.64654487],
[ 2.76188122, -2.23981308, -2.74634579, 3.35680468],
[-2.44320291, 1.47102487, 2.36135635, -1.28451339],
[ 0.2533113 , -0.69591469, 1.10498293, -0.00818495]])
Теперь умножение M
и Mi
должно привести к идентичности.
>>> M @ Mi
array([[ 1.00000000e+00, -4.44089210e-16, -1.11022302e-16, -6.93889390e-18],
[-4.16333634e-17, 1.00000000e+00, -8.32667268e-17, -8.60856525e-17],
[ 5.55111512e-17, -2.22044605e-16, 1.00000000e+00, -1.57859836e-16],
[ 6.24500451e-17, -8.32667268e-17, -2.35922393e-16, 1.00000000e+00]])
Но это явно не идентичность. Но если вы посмотрите внимательно, диагональные значения довольно близки к 1, а все остальные значения - это действительно маленькие числа (почти нули), например -16
или -17
в показателе степени.
Эта ошибка заключается в том, что значения с плавающей точкой никогда не являются точными значениями, в них всегда есть какая-то ошибка. Взгляните на статью 15. Арифметика с плавающей точкой: проблемы и ограничения и Не нарушена ли математика с плавающей точкой? .
Теперь, если мы просто конвертируем его в int, велика вероятность, что он все равно не будет идентичностью. Поскольку значение действительно близко к 1, оно может быть немного меньше 1, что приводит к 0 при приведении к int
.
>>> (M @ Mi).astype(int)
array([[1, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 0]])
Но если вы округлите его до преобразования в int
, вы получите личность.
>>> np.around(M @ Mi).astype(int)
array([[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1]])