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

时间:2018-02-08 07:50:43

标签: python arrays numpy linear-algebra numerical-methods

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

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的内存,而在运行时我从未达到75%以上的使用率。但同样,我对内存分配知之甚少,无法明确排除这一点。我试图在函数的开头和结尾强制垃圾收集无济于事。

任何想法都会受到赞赏。

编辑:

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

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

1 个答案:

答案 0 :(得分:1)

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

因此,每次运行此代码时,您都会在这些元素上有不同的符号。运行该函数两次后,数组回到了开始状态(显然,-1*-1 = 1)。

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

Quaternion_temp = Quaternion.copy()