您需要使用任意精度的浮点数学。以下是您如何组合numpy
和mpmath
包来定义矩阵乘法的任意精度版本(即np.dot
方法):
from mpmath import mp, mpf
import numpy as np
# stands for "decimal places". Larger values
# mean higher precision, but slower computation
mp.dps = 75
def tompf(arr):
"""Convert any numpy array to one of arbitrary precision mpmath.mpf floats
"""
if arr.size and not isinstance(arr.flat[0], mpf):
return np.array([mpf(x) for x in arr.flat]).reshape(*arr.shape)
else:
return arr
def dotmpf(arr0, arr1):
"""An arbitrary precision version of np.dot
"""
return tompf(arr0).dot(tompf(arr1))
例如,如果您随后设置B、B ^t 和D矩阵,如下所示:
bshape = (8,8,8,8)
dshape = (8,8)
B = np.random.rand(*bshape)
BT = np.swapaxes(B, -2, -1)
d = np.random.rand(*dshape)
D = d.dot(d.T)
那么B ^t DB - ( B ^t DB )^t 如果您使用标准矩阵乘法方法从以下位置计算它,它将始终具有非零值numpy
:
M = np.dot(np.dot(B, D), BT)
np.sum(M - M.T)
但如果您使用上面给出的任意精度版本,它不会有残留:
M = dotmpf(dotmpf(B, D), BT)
np.sum(M - M.T)
不过要小心。使用任意精度数学的计算比使用标准浮点数的计算运行得慢得多。