[英]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. 在
wx
和wy
我想对F
(例如对函数finterp
)进行插值finterp(w_x, w_y)
在调用finterp(w_x, w_y)
, w_x
和w_y
在wx
和wy
范围内时返回插值。 。 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)重新排列数据以使
x
和y
升序,而排列的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
更改fft2
和fftfreq
的输出,从而使频率轴单调递增。 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+N
和kN
处的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.