插值整个复数数组
我有一些二维的np.arrays(大小都一样),里面存的是复杂数字。每个数组代表在一个四维空间中的一个位置。这些位置分布得很稀疏,而且不规则(具体来说是拉丁超立方体)。我想把这些数据插值到同一个四维空间中的其他点上。
对于简单的数字,我可以成功地做到这一点,使用的方法有sklearn.kriging()
、scipy.interpolate.Rbf()
(或者其他方法):
# arrayof co-ordinates: 2 4D sets
X = np.array([[1.0, 0.0, 0.0, 0.0],\
[0.0, 1.0, 0.0, 0.0]])
# two numbers, one for each of the points above
Y = np.array([1,\
0])
# define the type of gaussian process I want
kriging = gp.GaussianProcess(theta0=1e-2, thetaL=1e-4, thetaU=4.0,\
corr='linear', normalize=True, nugget=0.00001, optimizer='fmin_cobyla')
# train the model on the data
kmodel = kriging.fit(X,Y)
# interpolate
kmodel.predict(np.array([0.5, 0.5, 0.0, 0.0]))
# returns: array([ 0.5])
但是如果我尝试用数组(或者复杂数字)作为数据,这就不行了:
# two arrays of complex numbers, instead of the numbers
Y = np.array([[1+1j, -1-1j],\
[0+0j, 0+0j]])
kmodel = kriging.fit(X,Y)
# returns: ValueError: The number of features in X (X.shape[1] = 1) should match the sample size used for fit() which is 4.
这很明显,因为kriging.fit()
的文档说明清楚地指出,它需要一个包含n个标量的数组,每个标量对应X的第一维的一个元素。
一个解决方案是把Y中的数组拆分成单个数字,然后再把这些数字分成实部和虚部,分别对每个部分进行插值,然后再把它们组合起来。我可以通过合适的循环和一些技巧做到这一点,但如果有一个方法(比如在scipy.interpolate
中)可以处理整个np.array而不是单个值,那就太好了。
我并没有固定在某个特定的算法上,所以如果有任何可以使用复杂数字数组作为插值“变量”的算法,我都会很高兴知道。因为正如我所说,空间中只有少量且不规则的点(而且没有网格可以插值),所以简单的线性插值当然是不够的。
2 个回答
看复数有两种方式:
- 笛卡尔形式(a + bi)
- 极坐标/欧拉形式(A * exp(i * phi))
当你说想在两个极坐标之间插值时,你是想根据实部和虚部(第一种方式)来插值,还是根据数的大小和相位(第二种方式)来插值呢?
你可以把复数拆分成实部和虚部,
X = 2 * 5j
X_real = np.real(X)
X_imag = np.imag(X)
# Interpolate the X_real and X_imag
# Reconstruct X
X2 = X_real + 1j * X_imag
不过在涉及复数的实际应用中,比如数字滤波器设计,你通常会希望使用极坐标/指数形式的数。
所以与其插值 np.real() 和 np.imag() 的部分,你可能更想用 np.abs() 和 角度 或 反正切 来拆分成大小和相位,然后分别插值。例如,当你想插值一个数字滤波器的傅里叶变换时,你可能会这样做。
Y = 1+2j
mag = np.abs(Y)
phase = np.angle(Y)
插值后的值可以用欧拉公式转换回复数(笛卡尔形式)
# Complex number
y = mag * np.exp( 1j * phase)
# Or if you want the real and imaginary complex components separately,
realPart, imagPart = mag * np.cos(phase) , mag * np.sin(phase)
根据你做的事情,这样可以让你在插值方法上有更多的灵活性。
我最后找到了解决这个问题的方法,但在学习了很多关于响应面之类的知识后,我现在明白这个问题并不简单。我本来不应该期待在 numpy
中能找到一个简单的解决方案,可能这个问题放在数学论坛讨论会更合适,而不是编程论坛。
如果我再遇到这样的任务,我可能会使用 scikit-learn
来尝试建立一个共同的 Kriging 插值模型,或者两个独立的 Kriging(更广泛地说,是高斯过程)模型,这两个模型共享一组共同的模型常数,优化以最小化整体误差(也就是说:完整模型的误差平方是两个部分模型误差的总和)。
—— 不过首先我会去看看是否已经有相关的有用论文。