Numpy/Python 乘以大型数组的数值不稳定问题

Numpy/Python numerical instability issue multiplying large arrays

我创建了一个通过四元数旋转向量的函数:

def QVrotate_toLocal(Quaternion,Vector):

    #NumSamples x Quaternion[w,x,y,z]
    #NumSamples x Vector[x,y,z]
    #For example shape (20000000,4) with range 0,1
    #            shape (20000000,3) with range -100,100
    #All numbers are float 64s 

    Quaternion[:,2]*=-1
    x,y,z=QuatVectorRotate(Quaternion,Vector)
    norm=np.linalg.norm(Quaternion,axis=1)
    x*=(1/norm)
    y*=(1/norm)
    z*=(1/norm)
    return np.stack([x,y,z],axis=1)

QuatVectorRotate 中的所有内容都是 (20000000,1) 个 numpy 数组的加法和乘法

对于我拥有的数据(四元数和向量的 2000 万个样本),每次我 运行 代码时,解决方案都会在(已知的)正确解决方案和非常不正确的解决方案之间振荡。从不偏离模式正确,不正确,正确,不正确...

这种静态代码中的数值振荡通常意味着有一个正在运行的病态矩阵,python是运行超出浮点精度,或者有一个沉默的记忆溢出某处。

我的代码中几乎没有线性代数,我已经检查并发现每个 运行 的范数线都是静态的。问题似乎发生在 a= ... 到 d= ...

行的某处

这让我相信,考虑到这些大型数组,我 运行 沿线某处内存不足。这可能仍然是问题,但我不相信它是;我有 16gb 内存,虽然 运行ning 我从来没有超过 75% 的使用率。但同样,我对内存分配的了解还不足以明确排除这种情况。我试图在函数的开头和结尾强制进行垃圾收集,但无济于事。

如有任何想法,我们将不胜感激。

编辑:

我刚刚用以下数据重现了这个问题,并且观察到相同的行为。

Q=np.random.random((20000000,4))
V=np.random.random((20000000,3))

当您在第一行执行 Quaternion[:,2]*=-1 时,您正在改变 Quaternion 数组。这不是该数组的本地副本,而是您从外部传入的实际数组。

所以每次你 运行 这个代码,你在这些元素上都有不同的标志。在两次 运行 函数之后,数组又回到了开始(因为,很明显,-1*-1 = 1)。

解决这个问题的一种方法是先制作一个本地副本:

Quaternion_temp = Quaternion.copy()