【问题标题】:Numpy/Python numerical instability issue multiplying large arraysNumpy/Python 数值不稳定性问题乘以大数组
【发布时间】:2018-07-18 17:06:31
【问题描述】:

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

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))

【问题讨论】:

  • 编辑了一些数学以使事情更具可读性并突出代码中的问题

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


【解决方案1】:

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

因此,每次运行此代码时,这些元素上都有不同的标志。两次运行该函数后,数组又回到了起点(显然,-1*-1 = 1)。

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

Quaternion_temp = Quaternion.copy()

【讨论】:

  • 哦哇...这完全让我无法理解。您能否详细说明为什么 Quaternion*=-1 不是存储为本地副本,而是改变了我从外部传递的数组,而 a、b、c、d 实际上是局部变量?
  • @IanCampbellMoore 1. 因为*= 是就地乘法和 2. 因为如果 Python 传递变量的方式,您实际上可以从函数中改变可变对象。有关后者的更多信息,请查看this post
猜你喜欢
  • 2020-08-04
  • 1970-01-01
  • 1970-01-01
  • 2021-11-14
  • 2010-12-19
  • 1970-01-01
  • 2018-10-03
  • 2021-02-19
  • 2017-02-15
相关资源
最近更新 更多