【问题标题】:Efficiently compute inverse Fourier transform高效计算傅里叶逆变换
【发布时间】:2021-05-25 11:04:31
【问题描述】:

在这个问题的非常好的答案here.中建议了以下代码

我的问题是:如果我只是通过评估 np.dot( B, yl ) 来计算傅里叶空间中的导数,就像这段代码中所做的那样。如何通过应用傅里叶逆变换恢复实际空间中的实际导数?

import numpy as np

## non-normalized gaussian with sigma=1
def gauss( x ):
    return np.exp( -x**2 / 2 )

## interval on which the gaussian is evaluated
L = 10
## number of sampling points
N = 21
## sample rate
dl = L / N
## highest frequency detectable
kmax= 1 / ( 2 * dl )

## array of x values
xl = np.linspace( -L/2, L/2, N )
## array of k values
kl = np.linspace( -kmax, kmax, N )

## matrix of exponents
## the Fourier transform is defined via sum f * exp( -2 pi j k x)
## i.e. the 2 pi is in the exponent
## normalization is sqrt(N) where n is the number of sampling points
## this definition makes it forward-backward symmetric
## "outer" also exists in Matlab and basically does the same
exponent = np.outer( -1j * 2 * np.pi * kl, xl ) 
## linear operator for the standard Fourier transformation
A = np.exp( exponent ) / np.sqrt( N )

## nth derivative is given via partial integration as  ( 2 pi j k)^n f(k)
## every row needs to be multiplied by the according k
B = np.array( [ 1j * 2 * np.pi * kk * An for kk, An in zip( kl, A ) ] )

## for the part with the linear term, every column needs to be multiplied
## by the according x or--as here---every row is multiplied element 
## wise with the x-vector
C = np.array( [ xl * An for An in  A ] )

## thats the according linear operator
D = B + C

## the gaussian
yl = gauss( xl )

## the transformation with the linear operator
print(  np.dot( D, yl ).round( decimals=9 ) ) 
## ...results in a zero-vector, as expected

【问题讨论】:

    标签: python math fft numerical-methods numerical-integration


    【解决方案1】:

    这里只需要定义逆变换的线性算子即可。 按照发布代码的结构,它将是

    expinv = np.outer( 1j * 2 * np.pi * xl, kl ) 
    AInv = np.exp( expinv ) / np.sqrt( N )
    

    导数的傅里叶变换为

    dfF = np.dot( B, yl )
    

    使得实空间中的导数为

    dfR = np.dot( AInv, dfF ) 
    

    最终,这意味着“导数”运算符是

    np.dot( AInv, B )
    

    这是一个小的N(除了边缘)一个带有条目(-1,0,1)的三对角矩阵,即一个经典的对称数值导数。 增加N,它首先变为1,-2,0,2,1,即导数的更高阶近似。

    最终,得到(..., d,-c, b,-a,0,a,-b, c,-d, ...) 类型的交替加权导数

    【讨论】:

    • 但后来我不明白,为什么AInv,不是与A关联的逆矩阵?
    • 嗯,这有点像,随着N 的增加,差异就不那么重要了。实际上np.dot( AInv, A) 是单位矩阵,除了第一行和最后一行中的一个附加条目。这可能与有限傅里叶变换实际上变成周期性的事实有关。所以从技术上讲,如果点数足够高,计算A 的倒数和按照我的方式构造它之间没有真正的区别。从傅立叶的角度来看,后者在概念上要好一些,我认为从计算工作量的角度来看它更快。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多