有办法让Python在500位小数精度下执行矩阵求逆吗?

huangapple go评论121阅读模式
英文:

Is there a way for python to perform a matrix inversion at 500 decimal precision

问题

有一个对输出精度敏感的算法。特别是,论文要求执行一个500位小数精度的实数矩阵求逆运算。我想写一个Python脚本来检查结果。然而,在NumPy中使用的最大浮点数据类型是np.float128,而decimal包似乎没有矩阵求逆函数。

我找到了这篇帖子https://stackoverflow.com/questions/32685280/matrix-inverse-with-decimal-type-numpy,它介绍了将decimal作为NumPy函数中的对象。但我在Stack Exchange上看到了关于Python将对象传递为float(32)对象的评论,这是由于%运算符的原因。

Python是否有一种方法可以以500位小数精度执行矩阵求逆运算?

英文:

There's an algorithm sensitive to the precision of the output. Especially, the paper required a real matrix inverse to be performed at 500 decimals precision. I wanted to write a script to check the result with python. However, the largest float data type used in numpy was np.float128, and the deicmal package does not seem to have a matrix inverse function.

I found the post https://stackoverflow.com/questions/32685280/matrix-inverse-with-decimal-type-numpy which introduce the decimal as an object in the numpy's function. But I saw comments on stack exchange that python transfer the object as float(32) object because of the % operators.

Is there a way for python to perform a matrix inversion at 500 decimal precision?

答案1

得分: 1

根据https://mpmath.org/doc/current/matrices.html#advanced-methods,我导入了mpmath,并创建了一个(3,3)的矩阵:

  1. A = mpmath.matrix([[1,3,4],[0,1,2],[3,0,1]])

并计算了它的逆矩阵:

  1. A**-1

numpy 中的等效操作:

  1. M = np.array([[1,3,4],[0,1,2],[3,0,1]])
  2. np.linalg.inv(M)

以及比较的运行时间:

  1. timeit np.linalg.inv(M)
  2. timeit A**-1

在这个示例中,dps(显示精度)设置为30(默认值为15,类似于float64):

  1. mpmath.mp.dps

有时用户担心逆矩阵与数组的点乘不完全产生单位矩阵,但请注意接近零的项非常小:

  1. Out[295] @ M

以及30位小数精度:

  1. Out[291] * A
英文:

Following https://mpmath.org/doc/current/matrices.html#advanced-methods,
I imported mpmath, and created (3,3) matrix:

  1. In [289]: A =mpmath.matrix([[1,3,4],[0,1,2],[3,0,1]])
  2. In [290]: A
  3. Out[290]:
  4. matrix(
  5. [['1.0', '3.0', '4.0'],
  6. ['0.0', '1.0', '2.0'],
  7. ['3.0', '0.0', '1.0']])

And calculated its inverse:

  1. In [291]: A**-1
  2. Out[291]:
  3. matrix(
  4. [['0.142857142857142857142857142857', '-0.428571428571428571428571428571', '0.285714285714285714285714285714'],
  5. ['0.857142857142857142857142857143', '-1.57142857142857142857142857143', '-0.285714285714285714285714285714'],
  6. ['-0.428571428571428571428571428571', '1.28571428571428571428571428571', '0.142857142857142857142857142857']])

The equivalent numpy operation:

  1. In [293]: M = np.array([[1,3,4],[0,1,2],[3,0,1]])
  2. In [294]: M
  3. Out[294]:
  4. array([[1, 3, 4],
  5. [0, 1, 2],
  6. [3, 0, 1]])
  7. In [295]: np.linalg.inv(M)
  8. Out[295]:
  9. array([[ 0.14285714, -0.42857143, 0.28571429],
  10. [ 0.85714286, -1.57142857, -0.28571429],
  11. [-0.42857143, 1.28571429, 0.14285714]])

And the comparative times:

  1. In [296]: timeit np.linalg.inv(M)
  2. 17.2 µs ± 31 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
  3. In [297]: timeit A**-1
  4. 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

  1. In [298]: mpmath.mp.dps
  2. 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:

  1. In [299]: Out[295]@M
  2. Out[299]:
  3. array([[ 1.00000000e+00, -5.55111512e-17, -5.55111512e-17],
  4. [ 1.11022302e-16, 1.00000000e+00, 3.88578059e-16],
  5. [ 0.00000000e+00, 0.00000000e+00, 1.00000000e+00]])

And to 30 dps:

  1. In [301]: Out[291]*A
  2. Out[301]:
  3. matrix(
  4. [['1.0', '-7.22223729145213444895991728469e-35', '-4.81482486096808963263994485646e-35'],
  5. ['1.44444745829042688979198345694e-34', '1.0', '3.37037740267766274284796139952e-34'],
  6. ['-2.40741243048404481631997242823e-35', '9.62964972193617926527988971292e-35', '1.0']])

huangapple
  • 本文由 发表于 2023年3月7日 07:48:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/75656846.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定