nano_exit

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

高速フーリエ変換する時の端点の話。

高速フーリエ変換ことFFTファイナルファンタジータクティクスではありません)は、結局は離散フーリエ変換な訳で、ある範囲のデータが無限に周期的に繰り返しているとしてフーリエ変換してくれます。
この時に、端の点のどこで周期性を課すのか、ややこしくなったのでまとめます。

基本的には、 x_n = n \Delta x\, (n \in \mathbb{N})に対して、関数 f( x )
 
\displaystyle
L = N \Delta x
\\
\displaystyle
f( x_n + L ) =f( x_n )
という周期性を満たすとするのが一般的です。
これをもう少しほぐせば、
 
f( x_n + L ) = f( x_n + N \Delta x) = f( ( n + N ) \Delta x ) = f( n \Delta x)
と書けるので、一番シンプルに表せば f( x_0 ) = f( x_N ) という関係を満たせば良いということになります。

しかし、ここでちょっと考えてみましょう。
 x_0からx_Nまでの点の数を数えると、 \sum^{N}_{n=0} = N+1となり、 Nよりも一点多くなってしまいます。
では Lを、 N+1で割らずに、Nで割る意味とは何なのか?

例えば、1から5まで数えてみましょう。
当たり前ですが、{1, 2, 3, 4, 5} と表せます。
そして、それぞれの数字の間隔は 5 \div 5 = 1です。
だから、数字の間隔は「点数で割れば良い」と思いたくなります。が、間違いです
実は、本当は  ( 5 - 0 ) \div 5 = 1 を計算しているのであって、{0, 1, 2, 3, 4, 5} と見ると点と点の間の個数が5なのです。始点である0を含めると点の数は6ですから、間の個数は1だけ小さくなります。
したがって、1から5を2等分するとなると、数字の間の個数が2個なので、 ( 5 - 1 ) / 2 = 2と求まります。数列は、{1, 3, 5}となり、点の数は3個です。
これらは中学校(?)で習う植木算というやつです。中学数学も侮れませんね。

それで、pythonで等間隔メッシュを作る時、'linspace'と'arange'が便利ですが、上記の点に関して注意が必要です。
以下にテストコードを書きます。

import numpy as np

N = 2**2
L = 100

alpha = 1e-7

np.linspace( 0, L, N )  # 0, 33.33333333, 66.66666666, 100
np.arange( 0, L, L/N )  # 0, 25, 50, 75
np.arange( 0, L + alpha, L/N )  # 0, 25, 50, 75, 100

'linspace'は「データ点数がNになるように」メッシュを作るので、実質N-1等分します。
一方で、'arange'は刻み幅を指定出来るので、N等分した間隔を直接決められますが、ピッタリ終点に到達した場合には「終点は含まれない」ので、もし終点が必要であるならば僅かにずらしておく必要あります。

FFTの場合で言えば、 n = 0, \cdots, N-1の範囲のデータを使って変換を行うので、「端点(始点と終点)を含めたN+1個の等間隔な(N等分した)データ数に対して、終点を外したもの」'arange( 0, L, L/N )'が便利と言えます。