简体   繁体   English

Python:如何对“非结构化”二维傅立叶变换数据进行插值

[英]Python: How to interpolate 'unstructured' 2D Fourier transform data

My goal is to interpolate the discretized continuous 2D Fourier transform of a function. 我的目标是对函数的离散连续2D傅里叶变换进行插值。 The problem seems to be that the frequencies in each dimension are not output in strictly ascending order (see here ). 问题似乎在于,每个维度中的频率都没有严格按升序输出(请参阅此处 )。

The fft.fft2 function accepts a 2D array, where in my case the array (let's call it A ) is structured such that A[i][j] = fun(x[i], y[j]) , fun being the function to be transformed. fft.fft2函数接受一个2D数组,在本例中,该数组(我们将其称为A )的结构使得A[i][j] = fun(x[i], y[j])fun为要转换的功能。 After applying fft.fft2 to A , output is an array F of the same dimensions as the original array, such that the frequency coordinate corresponding to F[i][j] is (w_x[i], w_y[j]) , where w_x = fft.fftfreq(F.shape[0]) and w_y = fft.fftfreq(F.shape[1]) , both of these being 1D arrays which are not in ascending order. fft.fft2应用于A ,输出的数组F的尺寸与原始数组的尺寸相同,因此对应于F[i][j]的频率坐标为(w_x[i], w_y[j]) ,其中w_x = fft.fftfreq(F.shape[0])w_y = fft.fftfreq(F.shape[1]) ,这两个都是一维数组,并且不按升序排列。

Over wx and wy I am wanting to interpolate F (say to a function finterp ) such that the interpolated value is returned upon calling finterp(w_x, w_y) , w_x and w_y being within the domain of wx and range of wy , but otherwise arbitrary. wxwy我想对F (例如对函数finterp )进行插值finterp(w_x, w_y)在调用finterp(w_x, w_y)w_xw_ywxwy范围内时返回插值。 。 I've looked into the varieties of interpolation available through scipy.interpolate , but it doesn't seem to me that any of them can deal with this type of data structure (the coordinate axes being defined as out-of-order 1D arrays and the function values being in a 2D array). 我研究了scipy.interpolate提供的各种插值方法 ,但是在我看来,它们中的任何一个都不能处理这种类型的数据结构(坐标轴被定义为无序的一维数组和函数值在2D数组中)。

This is a little abstract, so here I've made up a simple example which is similar in structure to the above. 这有点抽象,因此在这里我组成了一个简单的示例,其结构与上述类似。 Suppose we are wishing to construct a continuous function f(x, y) = x + y over the region x = [-1, 1] and y = [-1, 1] given the following data: 假设我们希望在给定以下数据的情况下y = [-1, 1]x = [-1, 1]y = [-1, 1] x = [-1, 1]的区域上构造一个连续函数f(x, y) = x + y

import numpy as np

# note that below z[i][j] corresponds to what we want f(x[i], y[j]) to be

x = np.array([0, 1, -1])
y = np.array([0, 1, -1])
z = np.array([0, 1, -1],[1, 2, 0],[-1, 0, -2])

z[i][j] we know corresponds to the function evaluated at x[i], y[j] . 我们知道z[i][j]对应于在x[i], y[j]处求值的函数。 How can one either (a) interpolate this data directly, given its original structure, or (b) rearrange the data so that x and y are in ascending order, and the arranged z is such that z[i][j] is equal to the function evaluated at the rearranged x[i], y[j] ? (a)在给定其原始结构的情况下如何直接对该数据进行插值,或者(b)重新排列数据以使xy升序,而排列的z使得z[i][j]等于到在重新排列的x[i], y[j]处求值的函数?

The following code shows how to use fftshift to change the output of fft2 and fftfreq so that the frequency axes are monotonically increasing. 以下代码显示如何使用fftshift更改fft2fftfreq的输出,从而使频率轴单调递增。 After applying fftshift , you can use the arrays for interpolation. 应用fftshift ,可以使用数组进行插值。 I've added display of the arrays so that you can verify that the data itself is unchanged. 我添加了数组的显示,以便您可以验证数据本身是否不变。 The origin is shifted from the top-left corner to the middle of the array, moving the negative frequencies from the right side to the left side. 原点从数组的左上角移到数组的中间,将负频率从右侧移到左侧。

import numpy as np
import matplotlib.pyplot as pp

x = np.array([0, 1, -1])
y = np.array([0, 1, -1])
z = np.array([[0, 1, -1],[1, 2, 0],[-1, 0, -2]])
f = np.fft.fft2(z)
w_x = np.fft.fftfreq(f.shape[0])
w_y = np.fft.fftfreq(f.shape[1])

pp.figure()
pp.imshow(np.abs(f))
pp.xticks(np.arange(0,len(w_x)), np.round(w_x,2))
pp.yticks(np.arange(0,len(w_y)), np.round(w_y,2))

f = np.fft.fftshift(f)
w_x = np.fft.fftshift(w_x)
w_y = np.fft.fftshift(w_y)

pp.figure()
pp.imshow(np.abs(f))
pp.xticks(np.arange(0,len(w_x)), np.round(w_x,2))
pp.yticks(np.arange(0,len(w_y)), np.round(w_y,2))
pp.show()

An alternative approach is to not use fftfreq to determine your frequencies, but compute them by hand. 一种替代方法是不使用fftfreq来确定您的频率,而是手动计算它们。 The FFT, by default, computes the DFT for k=[0..N-1] . 默认情况下,FFT计算k=[0..N-1]的DFT。 Because of the periodicity, with the DFT at k equal to the DFT at k+N and kN , its output is often interpreted to have k=[N//2...(N-1)//2] instead (but arranged differently to match k=[0..N-1] ); 由于周期性, k处的DFT等于k+NkN处的DFT时,其输出通常被解释为具有k=[N//2...(N-1)//2] (但排列不同以匹配k=[0..N-1] ); this is the k that fftfreq returns (it returns k/N ). 这是fftfreq返回的k (返回k/N )。

Thus, you can instead say 因此,您可以说

N = f.shape[0]
w_x = np.linspace(0, N, N, endpoint=False) / N

Now you don't have any negative frequencies, and instead have frequencies in the range [0,N-1]/N . 现在,您没有任何负频率,而是具有[0,N-1]/N范围内的频率。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM