我正在尝试制作表达式的点积,它应该是对称的。
事实证明它不是。
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产品或爱因斯坦求和仅用于感兴趣的维度(最后的)。
问题是:如何消除这些残留物?
答案 0 :(得分:0)
您需要使用任意精度浮点数学。以下是如何组合numpy
和mpmath
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)
注意。使用任意精度数学计算的运算多比使用标准浮点数运行的计算慢。