Interpolar arrays enteros de números complejos.

Tengo un número de np.arrays bidimensionales (todos de igual tamaño) que contienen números complejos. Cada uno de ellos pertenece a una posición en un espacio de 4 dimensiones. Esas posiciones son dispersas y se distribuyen irregularmente (un hipercubo latino para ser precisos). Me gustaría interpolar estos datos a otros puntos en el mismo espacio de 4 dimensiones.

Puedo hacer esto con éxito para números simples, usando sklearn.kriging() , scipy.interpolate.Rbf() (u otros):

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

Si trato de usar arreglos (o solo números complejos) como datos, esto no funciona:

 # 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. 

Esto es obvio ya que la cadena de documentación para kriging.fit() establece claramente que necesita una matriz de n escalares, una por cada elemento en la primera dimensión de X.

Una solución es descomponer los arreglos en Y en números individuales, esos en partes reales e imaginarias, hacer una interpolación separada de cada uno de ellos y luego juntarlos nuevamente. Puedo hacer esto con la combinación correcta de bucles y algo de arte, pero sería bueno si hubiera un método (por ejemplo, en scipy.interpolate ) que pudiera manejar un np.array completo en lugar de valores escalares.

No estoy fijo en un algoritmo específico (todavía), así que me encantaría saber sobre cualquier que pueda usar arreglos de números complejos como la “variable” que se debe interpolar. Como, como dije, hay pocos puntos irregulares en el espacio (y no hay rejilla para interpolar), la interpolación lineal simple no sirve, por supuesto.

Hay dos formas de ver los números complejos:

  1. Forma cartesiana (a + bi) y
  2. Forma Polar / Euler (A * exp (i * phi))

Cuando dice que desea interpolar entre dos coordenadas polares, ¿desea interpolar con respecto a los componentes reales / imaginarios (1), o con respecto a la magnitud y fase (2) del número?

PUEDES descomponer las cosas en componentes reales e imaginarios,

 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 

Sin embargo, con aplicaciones de la vida real que involucran números complejos, como el diseño de un filtro digital, a menudo se desea trabajar con números en forma polar / exponencial.

Por lo tanto, en lugar de interpolar los componentes np.real () y np.imag (), puede dividirlo en magnitud y fase utilizando np.abs () y Angle o Arctan2 , e interpolar por separado. Puede hacer esto, por ejemplo, cuando intente interpolar la Transformada de Fourier de un filtro digital.

 Y = 1+2j mag = np.abs(Y) phase = np.angle(Y) 

Los valores interpolados se pueden convertir de nuevo en números complejos (cartesianos) mediante la fórmula de Eulers

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

Dependiendo de lo que esté haciendo, esto le brinda cierta flexibilidad real con los métodos de interpolación que utiliza.

Terminé trabajando alrededor del problema, pero después de aprender mucho más sobre las superficies de respuesta y cosas por el estilo, ahora entiendo que este es un problema que está lejos de ser trivial. No podría haber esperado una solución simple en numpy , y la pregunta probablemente se habría colocado mejor en un foro sobre matemáticas que sobre progtwigción.

Si tuviera que volver a abordar esa tarea, probablemente usaría scikit-learn para probar y establecer una interpolación Kriging para ambos componentes, o dos modelos Kriging separados (o más generales, Proceso Gaussiano) que comparten un conjunto común de las constantes del modelo, optimizadas para minimizar la amplitud de error combinada (es decir, el cuadro de error de modelo completo es la sum de ambos errores de modelo parciales)

– pero primero me gustaría ir y echar un vistazo si no hay documentos útiles sobre el tema ya.