以下程序导致的值与指定的值不一致:
from scipy.interpolate import splprep, splev, splrep
import numpy as np
pos2indx = lambda vec: vec.round().astype(np.int64)
t = np.linspace(1,3,150)
x = 150+100*np.sin(t) + 5*np.random.randn(len(t))
y = 150+100*np.cos(t) + 5*np.random.randn(len(t))
z = 150+100*np.cos(t)*np.sin(t) + 5*np.random.randn(len(t))
vector_field = np.zeros((x.max()+10,y.max()+10,z.max()+10,3), dtype=np.float64)
out = splprep([x,y,z],u=t,k=3, full_output=1, quiet=1)
tck, t = out[0]
v = np.transpose(splev(t,tck, der=1))
i,j,k = pos2indx(x),pos2indx(y),pos2indx(z)
vector_field[i,j,k,:] += v
print np.sum(np.abs(vector_field[i,j,k,:]-v))
我希望此过程始终打印为零。 但是,有时它不会! 当输出非零时,它有几千个。
我不确定我是否做错了,或者是否有一些错误。
我也将此报告为scipy问题。
Pauli Virtanen:“错误在你的代码中:i,j,k向量可以包含两次给定的坐标对。” (https://github.com/scipy/scipy/issues/2581)
jorgeca在下面发布了类似的答案。
谢谢!
答案 0 :(得分:2)
总结一下您的问题,将v
添加到零数组然后减去v
并不总是会产生一个零数组:
vector_field = np.zeros((x.max()+10,y.max()+10,z.max()+10,3), dtype=np.float64)
vector_field[i,j,k,:] += v
print np.sum(np.abs(vector_field[i,j,k,:]-v)) # sometimes not 0!!
那不可能是对的!
事实上,索引i
,j
和k
是numpy数组,所以它使用fancy indexing。当三重指数重复时会发生什么?也就是说,对于某些m,n i[m] == i[n]
,j[m] == j[n]
和k[m] == k[n]
。事实证明,通过implementation detail(可以随时更改),只会分配索引的最后一个三元组(按C顺序),最后vector_field[i,j,k,:]
实际上不包含{{1 }}
答案 1 :(得分:1)
问题似乎是由圆形错误引起的。
我使用dtypes 1000
,float16
,float32
和float64
对您的代码float96
进行了比较。在vector_field
中计算了它给出非零答案的次数:
float16: 1000
float32: 1000
float64: 142
float96: 115