插值整个复数数组

3 投票
2 回答
9978 浏览
提问于 2025-04-18 07:51

我有一些二维的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 个回答

8

看复数有两种方式:

  1. 笛卡尔形式(a + bi)
  2. 极坐标/欧拉形式(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)

根据你做的事情,这样可以让你在插值方法上有更多的灵活性。

2

我最后找到了解决这个问题的方法,但在学习了很多关于响应面之类的知识后,我现在明白这个问题并不简单。我本来不应该期待在 numpy 中能找到一个简单的解决方案,可能这个问题放在数学论坛讨论会更合适,而不是编程论坛。

如果我再遇到这样的任务,我可能会使用 scikit-learn 来尝试建立一个共同的 Kriging 插值模型,或者两个独立的 Kriging(更广泛地说,是高斯过程)模型,这两个模型共享一组共同的模型常数,优化以最小化整体误差(也就是说:完整模型的误差平方是两个部分模型误差的总和)。

—— 不过首先我会去看看是否已经有相关的有用论文。

撰写回答