当前位置: 首页 > 面试题库 >

圆点对对称乘法太聪明

叶浩荡
2023-03-14
问题内容

有人知道有关此行为的文档吗?

import numpy as np
A  = np.random.uniform(0,1,(10,5))
w  = np.ones(5)
Aw = A*w
Sym1 = Aw.dot(Aw.T)
Sym2 = (A*w).dot((A*w).T)
diff = Sym1 - Sym2

diff.max()接近机器精度 的非零值 ,例如4.4e-16。

这个(0的差异)通常很好…在有限精度的世界中,我们不应感到惊讶。

而且,我猜想numpy在对称产品方面很聪明,可以节省翻牌并确保对称输出…

但是我处理的是混乱的系统, 调试 时这种小的差异很快就变得很明显。所以我想确切地知道发生了什么。


问题答案:

此行为是在请求请求#6932中为NumPy
1.11.0引入的更改的结果。从1.11.0的发行说明中:

以前,gem BLAS操作用于所有基质产品。现在,如果矩阵乘积介于矩阵及其转置之间,它将使用syrk
BLAS操作来提高性能。此优化已扩展到@,numpy.dot,numpy.inner和numpy.matmul。

在该PR的更改中,可以找到以下评论:

/*
 * Use syrk if we have a case of a matrix times its transpose.
 * Otherwise, use gemm for all other cases.
 */

因此,NumPy正在对矩阵情况乘以其转置进行一次显式检查,并在这种情况下调用另一个基础BLAS函数。正如@hpaulj在评论中指出的那样,这种检查对于NumPy来说是便宜的,因为转置的2d数组只是原始数组上的视图,具有倒置的形状和跨度,因此只需检查数组中的一些元数据即可(而不是必须比较实际的数组数据)。

这是一个略有差异的案例。注意,.copy在其中一个参数上使用adot足以击败NumPy的特殊情况。

import numpy as np
random = np.random.RandomState(12345)
A = random.uniform(size=(10, 5))
Sym1 = A.dot(A.T)
Sym2 = A.dot(A.T.copy())
print(abs(Sym1 - Sym2).max())

我猜想,这种特殊情况的优点是,除了明显的提速潜力外,还可以确保(我希望,但实际上,这将取决于BLAS的实现),从而在出现以下情况时获得完全对称的结果:syrk而不是仅根据数值误差对称的矩阵。作为对此(当然不是很好)的测试,我尝试了:

import numpy as np
random = np.random.RandomState(12345)
A = random.uniform(size=(100, 50))
Sym1 = A.dot(A.T)
Sym2 = A.dot(A.T.copy())
print("Sym1 symmetric: ", (Sym1 == Sym1.T).all())
print("Sym2 symmetric: ", (Sym2 == Sym2.T).all())

我的机器上的结果:

Sym1 symmetric:  True
Sym2 symmetric:  False


 类似资料:
  • 我试图乘以两个块对称矩阵(矩阵大小矩阵大小)。我想执行块矩阵乘法(将一个矩阵分成多个块大小矩阵,并将相应的块相乘)。我已经写了一些代码,但想改进它,并存储主对角线以上的块,但我没有任何想法。如果可能的话,你们能帮忙吗?

  • 问题内容: 我正在尝试为椭圆曲线创建自己的库。有些事情行得通,但有些则行不通。 要根据私钥计算公钥,应将生成器点乘以私钥,然后得到另一个点:公钥点(ECPoint = BigInteger * ECPoint)。 现在,我有一个私钥,并将其与Secp256k1曲线的生成器点相乘。我得到一个钥匙,但这不是我应该得到的钥匙。 这是我的JAVA代码: 我的代码有问题吗?secp256k1是否有特定的乘法

  • 本文向大家介绍对python中的乘法dot和对应分量相乘multiply详解,包括了对python中的乘法dot和对应分量相乘multiply详解的使用技巧和注意事项,需要的朋友参考一下 向量点乘 (dot) 和对应分量相乘 (multiply) : 矩阵乘法 (dot) 和对应分量相乘 (multiply) : 写代码过程中,*表示对应分量相乘 (multiply) : 以上这篇对python中

  • 众所周知,除法比乘法需要更多的时钟周期来计算。(请参阅此处的讨论:浮点除法与浮点乘法。) 我已经在我的C代码中使用了< code>x * 0.5而不是< code>x / 2和< code>x * 0.125而不是< code>x / 8,但是我想知道我应该这样做到什么程度。 对于倒置时重复出现的小数(即是重复出现的十进制),我使用除法而不是乘法(例如而不是)。 我的问题是:在迭代次数相当大的循环

  • 我试图测试的速度,反对“手动”乘法,并偶然发现了这个错误: Java 运行时环境检测到致命错误: EXCEPTION_ACCESS_VIOLATION (0xc0000005) 在 pc=0x000000005ac46888, pid=1508, tid=6016 JRE版本:Java(TM)SE运行时环境(8.0_25-b18)(构建1.8.0-25-B16) Java VM:Java热点(TM

  • 本文向大家介绍Android对称加密与非对称加密,包括了Android对称加密与非对称加密的使用技巧和注意事项,需要的朋友参考一下 凯撒密码 1. 介绍 凯撒密码作为一种最为古老的对称加密体制,在古罗马的时候都已经很流行,他的基本思想是:通过把字母移动一定的位数来实现加密和解密。明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。例如,当偏移量是3 的时候,所有的字母