nano_exit

基礎的なことこそ、簡単な例が必要だと思うのです。

誤差関数によるステップ関数でGibbs現象は起こるか?

ステップ関数等で不連続に打ち切られた関数をフーリエ変換しようとすると、どんなに頑張っても振動が残る。
これはギブス現象として知られている。
ギブズ現象 - Wikipedia

では、ステップ関数の代わりに誤差関数で滑らかにしたら、どれくらい収束が良いのか?
ちょっと気になったので、やってみた。

まず、誤差関数で作る擬ステップ関数等を定義する。

import numpy as np
from scipy.special import erf
from scipy.integrate import simps
from matplotlib import pyplot as plt

# pseudo step function
def pstep( x, x0, hdx):
    return 0.5 * ( 1 + erf( ( x - x0 ) / ( 0.5 * hdx )  ) )

# pseudo rectangular
def prect( x, L ):
    hdx = L / 16
    return pstep( x, L / 4, hdx ) - pstep( x, 3/4 * L, hdx )

# rectangular
def rect( x, L ):
    func = np.zeros( len( x ) ) 
    for i, xx in enumerate( x ):
        if L / 4 <= xx <= 3/4 * L:
            func[ i ] = 1.0
    return func

滑らかな矩形波フーリエ変換する。
フーリエ変換はsimpson積分で自前で頑張る。

L = np.pi
N = 120
x = np.linspace( 0, L, N )
k = 2 * np.pi / L * np.arange( -100, 100 + 1 ) 

func  = prect( x, L )
# func = rect( x, L )

fn = []
for kk in k:
    integrand = func * np.exp( -1.j * kk * x )
    fn.append( complex( simps( np.real( integrand ), x ),
                        simps( np.imag( integrand ), x )
                      ) / L
             )

plt.plot( x, func )
fourier = 0.
for i, f in enumerate( fn ):
    fourier += f * np.exp( 1.j * k[ i ] * x )
plt.plot( x, fourier.real )
# fourier.imag is almost zero.

plt.show()

結果

f:id:koideforest:20181211230146p:plain
pseudo rectangular
元の関数をほぼ完全に再現している。
 N = 120程度なので、そんなに大変じゃない。

通常の矩形波に対して同じ条件でやってみた。

f:id:koideforest:20181211230215p:plain
rectangular
収束する気配は無い。
ちなみに Nを10倍に増やしても、振動が細かくなるだけで、消えることはない。

滑らかにする大切さを知りました。