Following https://mpmath.org/doc/current/matrices.html#advanced-methods,
I imported mpmath
, and created (3,3) matrix:
In [289]: A =mpmath.matrix([[1,3,4],[0,1,2],[3,0,1]])
In [290]: A
Out[290]:
matrix(
[['1.0', '3.0', '4.0'],
['0.0', '1.0', '2.0'],
['3.0', '0.0', '1.0']])
And calculated its inverse:
In [291]: A**-1
Out[291]:
matrix(
[['0.142857142857142857142857142857', '-0.428571428571428571428571428571', '0.285714285714285714285714285714'],
['0.857142857142857142857142857143', '-1.57142857142857142857142857143', '-0.285714285714285714285714285714'],
['-0.428571428571428571428571428571', '1.28571428571428571428571428571', '0.142857142857142857142857142857']])
The equivalent numpy
operation:
In [293]: M = np.array([[1,3,4],[0,1,2],[3,0,1]])
In [294]: M
Out[294]:
array([[1, 3, 4],
[0, 1, 2],
[3, 0, 1]])
In [295]: np.linalg.inv(M)
Out[295]:
array([[ 0.14285714, -0.42857143, 0.28571429],
[ 0.85714286, -1.57142857, -0.28571429],
[-0.42857143, 1.28571429, 0.14285714]])
And the comparative times:
In [296]: timeit np.linalg.inv(M)
17.2 µs ± 31 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
In [297]: timeit A**-1
1.19 ms ± 1.26 µs per loop (mean ± std. dev. of 7 runs, 1,000 loops each)
In this case I have the dps
(display precision) set at 30 (the default is 15, similar to a float64
In [298]: mpmath.mp.dps
Out[298]: 30
SO posters often worry about the dot
of inverse with array doesn't quite produce the identity matrix. But notice how small the near 0 terms are:
In [299]: Out[295]@M
Out[299]:
array([[ 1.00000000e+00, -5.55111512e-17, -5.55111512e-17],
[ 1.11022302e-16, 1.00000000e+00, 3.88578059e-16],
[ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])
And to 30 dps:
In [301]: Out[291]*A
Out[301]:
matrix(
[['1.0', '-7.22223729145213444895991728469e-35', '-4.81482486096808963263994485646e-35'],
['1.44444745829042688979198345694e-34', '1.0', '3.37037740267766274284796139952e-34'],
['-2.40741243048404481631997242823e-35', '9.62964972193617926527988971292e-35', '1.0']])