点积B ^ t.D.B不返回对称阵列

时间:2018-04-17 23:04:03

标签: python arrays numpy symmetric numpy-einsum

我正在尝试制作表达式的点积,它应该是对称的。

事实证明它不是。

B 是一个4D数组,我必须将其最后两个维度转换为 B ^ t。

D 是一个2D数组。 (它是有限元方法程序员已知的刚度矩阵的表达式)

/* If true, the file listing format requires that stat be called on each file. */ ... format_needs_stat = ... || format == long_format || ... ... dereference = ... DEREF_NEVER; ... gobble_file (char const *name, enum filetype type, ino_t inode, ... if ( ... || format_needs_stat || ...) { ... default: /* DEREF_NEVER */ err = lstat (full_name, &f->stat); do_deref = false; break; } if (err != 0) { /* Failure to stat a command line argument leads to an exit status of 2. For other files, stat failure provokes an exit status of 1. */ file_failure (command_line_arg, _("cannot access %s"), full_name); 相关联的numpy.dot产品以及第二替代numpy.transpose(该主题的想法来自https://github.com/coreutils/coreutils/blob/master/src/ls.c)已经被使用,问题仍然存在。

在计算结束时,获得了产品 B ^ t DB ,并且通过减去其转置 B来验证它是否真的是对称的 ^ t DB ,仍有残留物。

Dot产品或爱因斯坦求和仅用于感兴趣的维度(最后的)。

问题是:如何消除这些残留物?

1 个答案:

答案 0 :(得分:0)

您需要使用任意精度浮点数学。以下是如何组合numpympmath package来定义矩阵乘法的任意精度版本(即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 数据库 - ( B ^ t 数据库)^ t将始终具有非如果使用numpy中的标准矩阵乘法方法计算它,则为-zero值:

M = np.dot(np.dot(B, D), BT)
np.sum(M - M.T)

但是如果使用上面给出的任意精度版本,它将没有残留物:

M = dotmpf(dotmpf(B, D), BT)
np.sum(M - M.T)

注意。使用任意精度数学计算的运算比使用标准浮点数运行的计算慢。