Comments
Description
Transcript
ローパスフィルタの数理
ローパスフィルタの数理 有馬 啓晃 2014 年 3 月 10 日 5 目次 1 2 3 4 イントロ 1.1 研究の動機 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 重要単語の説明 2.1 サンプリング . . . . . . . . . . . . . . . . . . . 2.2 Z 変換 . . . . . . . . . . . . . . . . . . . . . . . 2.3 デジタルフィルタ . . . . . . . . . . . . . . . . . 2.3.1 線形定常システムとそのフィルタ係数 . 2.4 伝達関数 . . . . . . . . . . . . . . . . . . . . . . 2.5 ローパスフィルタ . . . . . . . . . . . . . . . . . 2.5.1 窓関数は何の為にあるのか . . . . . . . . 2.5.2 ハン窓(ハニング窓) . . . . . . . . . . 2.5.3 窓関数はなんのためにあるのか(続き) プログラム ex6 1 の解読 3.1 ex6 1 を作るのに必要なソースプログラム . 3.2 ex6 1.c . . . . . . . . . . . . . . . . . . . . 3.3 エッジ周波数という言葉の解読 . . . . . . 3.4 sinc 関数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 5 . . . . . . . . . 6 6 6 6 7 8 8 10 11 11 . . . . 12 12 14 17 18 まとめ 19 A Fourier 変換 A.1 流儀 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.2 流儀 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.3 流儀 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 19 20 20 B Fourier 級数と離散 Fourier 変換 B.1 Fourier 級数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . B.2 離散 Fourier 変換 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 20 21 C 離散時間 Fourier 変換 23 D 参考文献 23 1 1.1 イントロ 研究の動機 私は音楽に興味があって、C 言語を使ったプログラムでなにか音を操作できないだろうかと 考えた。と言うのも、音楽の信号がデジタル処理されていることは知っていて、先輩も音のデ 6 ジタル処理を卒研のテーマにしていた、というのがあったためである。 青木 [1」の第 6 章にローパスフィルターのプログラム ex6 1.c が載っていた。ローパスフィ ルターとは、ある一定の周波数より低い周波数は通し、高い周波数は通さない、というもの で、もっとも基本的なエフェクトであると考えられる。この卒業研究では、このプログラムを 数学的に理解することを目標とする。 重要単語の説明 2 2.1 サンプリング x : R → C という信号と、Ts > 0 があったとき、 xn := x(nTs ) (n ∈ Z) で {xn }n∈Z ∈ CZ が定まる。 Ts は標本化周期(Sampling period)と呼ばれる。以下で周期関数を扱うことも多く、その周 期を T で表したいため、標本化周期には s という添字をつけて Ts という記号を用いる。 例. Ω ∈ R とするとき、x(t) = eiΩt は正弦波と呼ばれる。Ts > 0 として、 xn := x(nTs ) とおく。 xn = eiΩnTs = einω . ただし ω := ΩTs とおいた。{xn } は公比 eiΩ の等比数列である。|eiΩ | = 1 であることに注 意する。 2.2 Z 変換 ∪ 整数全体の集合を Z,1 以上の整数全体の集合を N, N0 := N {0} とする。 以下、数列 {xn } の話として説明するが、関数 x : R → C と、Ts > 0 に対して xn = x(nT ) とおくことで、関数のサンプリングデータの話と考えることもできる。 数列 {xn }n∈Z ∈ CZ に対して、 ∑ xn (z ∈ C, ただし収束する場合) X(z) := zn n∈Z で定義される X = X(z) を {xn } の Z 変換と呼ぶ。 2.3 デジタルフィルタ デジタルフィルタとは、数学的には、数列 {xn }n を数列 {yn } に写す写像 F : {xn } → {yn } である。線型かつ時不変であるもの(線型定常システム)だけを考えることにする。 7 2.3.1 線形定常システムとそのフィルタ係数 デジタルフィルタ F が線型であるとは、 F ({xn } + {yn }) = F ({xn }) + F ({yn }), F (c{xn }) = cF ({xn }) が成り立つことであり、時不変(定常)であるとは、 ∀k ∈ Z F ({xn−k }) = {yn−k } が成り立つことをいう。 添字 n の範囲が問題になるが、まずは n ∈ Z の場合を考えることにする。 X := CZ = {{xn }n∈Z ; ∀n ∈ Z xn ∈ C} とおくとき、線型定常なデジタルフィルタ F : X → X に対して、 ∃h ∈ CZ s.t. ∀x ∈ CZ F (x) = x ∗ h. が成り立つ。実際、h として h = F (δ) をとれば良い。ここで δ = {δn }n∈Z は δn := δn0 = { 1 (n = 0) 0 (n ̸= 0) で定められる数列で、単位インパルスと呼ばれる (Kronecker のデルタ δij を用いれば、δn = δn0 と書くこともできる)。h のことをデジタルフィルタ F のフィルタ係数と呼ぶが、h = F (δ) で あることから、F の単位インパルス応答とよぶこともある。 青木 [1] では hn の代わりに bn と書いてある。 FIR フィルタとは、デジタルフィルタのうちで、 ∃J ∈ N s.t. bn = 0 (n < 0 or n > J) を満たすものである。bm (0 ≤ m ≤ J) をフィルタ係数と呼ぶ。このとき yn = J ∑ xn−k bk (n ∈ Z) k=0 プログラムでは、片側の信号 {xn }n≥0 , {yn }n≥0 しか扱っていないせいもあって、 ∑ min{J,n} yn = m=0 となっている。 8 xn−m bm 2.4 伝達関数 デジタル・フィルタに正弦波を入力したときの出力について調べてみよう。 正弦波 x(t) = eiΩt をサンプリングして作った離散信号 {xn } を入力してみる。 xn = x(nTs ) = eiΩnTs = einω , ω := ΩTs であるから、{xn } は公比 eiω の等比数列である。 h = {hn }, y = {yn }, y = x ∗ h とする。h の z 変換を H(z) とすると、∀n ∈ Z に対して yn = ∑ ∑ xn−k hk = k∈Z ei(n−k)ω hk = einω ∑ e−ikω hk = H(eiω )xn . k∈Z k∈Z つまり y = H(eiω )x. ゆえにデジタルフィルタ h に正弦波を入力すると、出力はやはり正弦波 で、その周波数は入力と同じである。ただ周波数ごとに何倍されるかの係数が異なる、という ことを表している。 デジタルフィルタ h の z 変換 H(z) に eiω を代入した H(eiω ) を ω の関数 ω 7→ H(eiω ) とみた とき、これを伝達関数 (transfer function) と呼ぶ。 ω ∈ [0, 2π](あるいは ω ∈ [−π, π])に対して、 (1) G(ω) := |H(eiω )|, θ(ω) := arg H(eiω ) (arg でなく ∠ と書くこともある。) とおき、G(ω) を利得 (gain),θ(ω) を位相シフト (phase shift) と呼ぶ。 2.5 ローパスフィルタ 正弦波 x(t) = eiΩt をサンプリング周期 Ts でサンプリングして、離散信号を作る。 xn := x(nTs ) = eiΩnTs = einω (n ∈ Z), ただし ω := ΩTs . この x = {xn } をデジタルフィルタに入力したときの、出力信号 y = {yn } は、フィルタ係数を {hn } とすると、 ) ( ∑ ∑ ∑ hk einω = H(eiω )einω . yn = xn−k hk = ei(n−k)ω hk = eikω k∈Z k∈Z k∈Z ただし H は {hn } の z 変換である: H(z) := ∑ hk k∈Z zk . これはデジタルフィルタに正弦波を入力すると、出力は同じ周波数をもつ正弦波で、振幅が X(ω) := |H(eiω )| 倍されることを意味する。ωe ∈ (0, π) に対して、 { 1 (|ω| ≤ ωe ) X(ω) = ([−ωe , ωe ] の特性関数) = 0 (|ω| > ωe ) 9 1.0 0.8 0.6 0.4 0.2 -3 -2 1 -1 2 3 図 1: 上の式のグラフ となるようなフィルタを求める。 X(ω) = ∑ hn e−inω (ω ∈ R) k∈Z は、X が {hn } の離散時間 Fourier 変換であることを意味する。離散時間 Fourier 変換には反転 公式 ∫ π 1 X(ω)einω dω (n ∈ R) hn = 2π −π がある。これは実は周期 2π の周期関数の Fourier 級数展開と同じである。 (次の公式の i と −i を入れ替えるだけ)。 Fourier 級数展開(Fourier 係数と「反転公式」) 周期 2π の周期関数 x : R → C に対して、 ∫ pi 1 x(θ)e−inθ dθ cn := 2π π とおくと、 x(θ) = ∑ cn e−inθ (n ∈ Z) (θ ∈ R) k∈Z が成り立つ。 要するに、次のように {hn } を定めればよい。 ∫ π ∫ ωe 1 ωe 1 inω X(ω)e dω = einω dω = sinc nωe . hn = 2π −π 2π −ωe π エッジ周波数 fe となるには、fe = hn = fe ωe fs とすれば良いので、ωe = 2π であり、 2π fs 2πfe /fs fe 2nπfe fe . sinc 2nπ = 2 sinc π fs fs fs 10 bm = wm hm−J/2 であるので、窓関数の wm の部分を無視して bm ≒ hm−J/2 と見なすと、n ≥ J/2 に対して、 yn = ∑ xn−k hk ≒ xn−k hk ≒ |k|≤J/2 k∈Z 2.5.1 ∑ ∑ xn−k bk+J/2 = |k|≤J/2 J ∑ xn−J/2−m bm = y[n − J/2]. m=0 窓関数は何の為にあるのか hn = ωe sinc nωe π とするとき、 XJ (ω) := ∑ hn e−inω |n|≤J/2 とおき、そのグラフを Mathematica で描いてみる。 Clear[n, t, w, x]; w[x_]:=(1-Cos[2 Pi x])/2; omega=0.5; h[n_]:=omega/Pi Sinc[n omega]; draw[J_]:=Plot[Sum[h[n]Exp[-I n t], {n, -J/2, J/2}],{t, -Pi, Pi}, PlotRange -> All]; 実際には無限和は計算できないので、有限和ですませることになる。 f (ω) := 50 ∑ hn e−inω n=−50 f (ω) ≒ H(e ) と期待されるが iω 1.0 0.8 0.6 0.4 0.2 -3 -2 1 -1 図 2: 窓関数なし (J = 100) Gibbs の現象が生じて良い近似にはならない。 そこで、窓関数としてハン窓(ハニング窓)を使用する。 11 2 3 2.5.2 ハン窓(ハニング窓) ハン窓 (hann window), von Hann window,2 乗余弦窓 (raised cosine window) とも呼ばれる。 一般化ハミング窓に分類されたので、ハニング窓 (hanging wndow) と呼ばれる。 w(x) = 1 − cos 2πx 2 (0 ≤ x ≤ 1). 1.0 0.8 0.6 0.4 0.2 0.2 0.4 0.6 図 3: hann 窓 w(x) = 0.8 1.0 1 − cos 2πx 2 void Hanning window(double w[], int N) という関数がある。これは、整数 N が与えら れたとき (n) (N が偶数) w N (n = 0, 1, ..., N − 1) wn := ) ( w n + 1/2 (N が奇数) N −1 で定まる w = {wn }N n=0 を返す。 N の偶奇で式を変えるのは、w の最大値 w(1/2) = 1 を数列中に含めたいからであろう。 Hanning window() の処理の Mathematica 訳 Clear[w]; w[x_]:=(1-Cos[2 Pi x])/2; hanningWindow[N_]:=if[EvenQ[N], Table[w[n/N], {n, 0, N-1}], Table[w[(n+1/2)/N], {n, 0, N-1}]] 2.5.3 窓関数はなんのためにあるのか(続き) hn の代わりに h̃n := hn w(n/100) をフィルタ係数に選ぶと f˜(ω) = 50 ∑ n=−50 12 h̃n e−inω draw2[J_]:=Plot[Sum[w[n/J-1/2]h[n]Exp[-I n t],{n, -J/2, J/2}], {t,-Pi,Pi}, PlotRange -> All] 1.0 0.8 0.6 0.4 0.2 -3 -2 1 -1 2 3 図 4: 窓関数あり (J = 100) H(eiω ) の良い近似が得られる。 プログラム ex6 1 の解読 3 青木 [1] に載っている ex6 1.c というプログラムを解読する。 ex6 1 がすること sine 500hz 3500hz.wav という WAVE ファイル(フォーマットは 16 ビッ トモノラル PCM、内容は 500Hz, 3500Hz の正弦波を合成して作った音声信号)を読んで、エッ ジ周波数 1000Hz, 遷移帯域幅 1000Hz のローパスフィルタで処理した結果を ex6 1.wav という ファイルに出力する。 3.1 ex6 1 を作るのに必要なソースプログラム • ex6 1.c — メインのプログラム • wave.h — 音声ファイル(.wav 等)を読み書きするための関数群が定義されている。 関数名は wave {read | write} {8 | 16}bit {stereo | mono}() といったもの。 いずれの関数も返す型は void で、引数は 2 つあり、第 1 引数は PCM データへのポイン ター、第 2 引数はファイルのパス名である。 • window function.h — いくつかの窓関数の関数値を計算する関数が定義されている。 1 − cos 2πx ex6 1 で使っているのはハン窓(hann window)w(x) = x この関数の仕様は重要なので後で詳しく解説する。 13 • sinc.h — sinc を計算する関数が定義されている。 sin πx sin x いわゆる正規化 sinc(sinc x = ) ではなく、非正規化 sinc(sinc x = ) πx x • fir filter.h — FIR フィルタを扱う関数が定義されている。 そのうち ex6 1 で使っているのは (a) FIR filtering(x,y,L,b,J) — 畳み込み y = x ∗ b を計算する。 J x = {x[n]}L−1 n=0 ,b = {b[m]}m=0 が入力として与えられたとき、 ∑ minJ,n (♢) y[n] = b[m]x[n − m] (n = 0, ..., L). m=0 で定まる y = {y[n]}L−1 n=0 を返す。 (b) FIR LPF(fe, J, b, w) — エッジ周波数 fe のローパスフィルタのフィルタ係数 {bm }Jm=0 を計算する。使用する窓関数は {wm }Jm=0 で与える。 14 3.2 ex6 1.c ex6 1.c #include #include #include #include #include #include #include <stdio.h> <stdlib.h> <math.h> "wave.h" "window_function.h" "sinc.h" "fir_filter.h" int main(void) { MONO_PCM pcm0, pcm1; int n, m, J; double fe, delta, *b, *w; wave_read_16bit_mono(&pcm0, "sine_500hz_3500hz.wav"); pcm1.fs = pcm0.fs; /* 標本化周波数 */ pcm1.bits = pcm0.bits; /* 量子化精度 */ pcm1.length = pcm0.length; /* 音データの長さ */ pcm1.s = calloc(pcm1.length, sizeof(double)); /* 音データ */ fe = 1000.0 / pcm0.fs; /* エッジ周波数 */ delta = 1000.0 / pcm0.fs; /* 遷移帯域幅 */ J = (int)(3.1 / delta + 0.5) - 1; /* 遅延器の数 */ if (J % 2 == 1) { J++; /* J+1 が奇数になるように調整する */ } b = calloc((J + 1), sizeof(double)); w = calloc((J + 1), sizeof(double)); Hanning_window(w, (J + 1)); /* ハニング窓 */ FIR_LPF(fe, J, b, w); /* FIR フィルタの設計 */ /* フィルタリング */ for (n = 0; n < pcm1.length; n++) { for (m = 0; m <= J; m++) { if (n - m >= 0) { pcm1.s[n] += b[m] * pcm0.s[n - m]; } } } wave_write_16bit_mono(&pcm1, "ex6_1.wav"); free(pcm0.s); free(pcm1.s); free(b); free(w); return 0; } fe = 1000.0 / pcm0.fs; /* エッジ周波数 */ エッジ周波数を 1000Hz としている。fe はサンプリング周期 (1/8000s) あたりの振動数であり、 15 1/8 という値になる。 fs , fe をそれぞれサンプリング周波数、エッジ周波数として、fe には fe /fs という値がセットさ れている、と考えることにする(つまり fe は、fe と似ている名前だけど別物である、fe= fe /fs である、ということ)。 delta = 1000.0 / pcm0.fs; /* 遷移帯域幅 */ 遷移帯域幅を 1000Hz としている。 これも上と同様に、fs , δ をそれぞれサンプリング周波数、遷移帯域幅として、delta= δ/fs である、と考えることにする。 次はこれからつくるローパスフィルタの係数 {bm }Jm=0 の個数 J + 1 を定めている。 J = (int)(3.1 / delta + 0.5) - 1; /* 遅延器の数 */ if (J % 2 == 1) { J++; /* J+1 が奇数になるように調整する */ } (3.1/delta を四捨五入して、奇数だったら 1 を足し戻す) これは J = round(3.1 / delta); if(J % 2 == 1) { J--; } (3.1/delta を四捨五入して、奇数だったら 1 を引く) と同価で、こう書くほうが自然である。 ハニング窓の場合は、 [ ] 3.1 1 J= fs + −p (p = 0, 1 は J が偶数になるように調節) δ 2 で良いことが理論的に分かるらしい。J を偶数(J + 1 を奇数)に選ぶ理由は、関数の最大値 を与えるところを中心に対象にしたいためと考察するが、右に 1 つ 0 を補うだけで良いと思 う。細かいところはさておき、樋口・川又 [2] には、 6.2π = ”遷移帯域幅” N という式がある。6.2π を 3.1 × 2π と見ると、よく似ている式である。 ([2] は正規化して説明し ていることを考慮すると、”遷移帯域幅”は δ/fs × 2π ということであろうか)。 このプログラム ex6 1 では、δ = 1000Hz,fs = 8000Hz であるから、J = 24 である。 16 Hanning_window(w, (J + 1)); /* ハニング窓 */ (3.1/delta を四捨五入して、奇数だったら 1 を引く) 1 − cos 2πx Hanning window(w, N) は、hann 窓 w(x) := の関数値 2 n w( ) (N が偶数の場合) N wn := (n = 0, 1, ..., N − 1) w( n + 1/2 ) (N が奇数の場合) N を計算する関数である。 次の関数呼び出しで、sinc と hann 窓を使ったローパスフィルタのフィルタ係数を求めている。 FIR_LPF(fe, J, b, w); /* FIR フィルタの設計 */ ここで入力は fe(= fe /fs , サンプリング周期単位のエッジ周波数), J(フィルタ係数の個数), w(= {wm }Jm=0 は hann 窓の関数値) の 3 つで、出力は b(= {bm }Jm=0 , ローパスフィルタのフィル タ係数) である。 この結果 fe 2πfe (m − J/2) bm := wm × 2 sinc (m = 0, 1, ..., J) (♣) fs fs となる。 fs=8000; fe=1000; delta=1000/fs; J=Round[3.1/delta]; If[OddQ[J], J=J+1]; g=Plot[2*fe/fs*Sinc[2 Pi fe (m - J/2)/fs], {m, 0, J + 1}] 0.25 0.20 0.15 0.10 0.05 5 10 15 20 25 -0.05 図 5: hann 窓をかける前 g2 = Plot[w[m/(J + 1)]*2*fe/fs*Sinc[2 Pi fe (m - J/2)/fs], {m, 0, J + 1}] 17 0.25 0.20 0.15 0.10 0.05 5 10 15 20 25 図 6: hann 窓をかけた後 — ローパスフィルタの完成 3.3 エッジ周波数という言葉の解読 樋口・川又 [2] には「エッジ周波数」という語はない。 ローパスフィルタでは、fs より低い周波数の信号成分は通し、fe より高い周波数の信号成 分は通さない、そういう周波数 fe のことをローパスフィルタのエッジ周波数と呼んでいるら しい。 実際には(連続的な観測など不可能なので)、そういう理想的なものを実現することは困難 である。 以下、[2] でやってみる。 M (ω) を振幅特性と呼ぶ。 1 |M (ω)| =√ max|M (ω)| 2 となる ω を cutoff frequency と呼ぶ。 許容値と呼ばれる小さな正数 δp を定めておいて、 1 − δp ≤ |M (ω)| ≤ 1 + δp を満たす ω の範囲が [0, ωp ] となるとき、[0, ωp ] を通過域、ωp を通過域端周波数と呼ぶ。 誤差と呼ばれる小さな数 δs を定めておいて、 |M (ω)| ≤ δs となる ω の範囲が [ωs , π] となるとき、[ωs , π] を阻止域、ωp を阻止域端周波数と呼ぶ。 [ωp , ωs ] を遷移域と呼ぶ。 つまり、通過域、遷移域、阻止域は「分割」である。 青木 [1] と合わせるには、[ωp , ωs ] を遷移域、(ωp + ωs )/2 をエッジ周波数 fs 、ωs − ωp を遷移 帯域幅 δ と考えるべきだろうか。 (?) fe = ωp + ωs , 2 18 ω s − ωp = δ 3.4 sinc 関数 sinc.h では、sinc という関数の値を計算する sinc() という関数を定義してある。 sin x (x ∈ R\{0}) x sinc(x) := 1 (x = 0) 実はこれは非正規化 sinc と呼ばれる。信号処理の分野では sin πx (x ∈ R\{0}) πx 正規化 sinc x := 1 (x = 0) で定義される正規化 sinc 関数も使われる([2] がそうなっている)。以下の Mathematica の Sinc[] は非正規化 sinc である。この文書では一貫して非正規化 sinc を使うことにする。 Mathematica で sinc のグラフ描写 g = Plot[Sinc[x], x, -15, 15, PlotRange -> Full] 1.0 0.8 0.6 0.4 0.2 -15 -10 5 -5 10 15 -0.2 図 7: sinc x = sin x のグラフ x 滑らかな偶関数で、x = nπ (n ∈ Z) が零点で、グラフは y = ± 1 で挟まれた部分を上下 |x| している。 sinc が重要視される理由は次の事実にある。ωp ∈ (0, π) とするとき、区間 [−ωp , ωp ] の特性 ωp 関数 χ[−ωp ,ωp ] の逆 Fourier 変換は sinc ωp t である。実際、 π ∫ ∞ ∫ ωp 1 1 iωt χ[−ωp ,ωp ] (ω)e dω = eiωt dω 2π −∞ 2π −ωp [ ]ω=ωp 1 eiωt 1 eiωp t − e−iωp t 1 sin ωp t = = = 2π it ω=−ωp 2π it π t ωp = sinc ωp t. π 19 まとめ 4 最初に立てた目標である「音の低音、高音を自由に強めたり、弱めたりする」ことに対して 今回は、自分で指定した周波数のローパスフィルタの設計、実際の音データのフィルタリング に成功した。 窓関数について、完全に理解することまでは時間切れでできなかった。 新たな課題として考えられることは、ある周波数より高い音を通すハイパスフィルタ、ある 周波数帯の音のみを通すフィルタ、これらも、ローパスフィルタの考え方を元に調べることが できるということ、また、リアルタイムでのローパスフィルタを利用したフィルタリングにつ いても、新たな課題として考えられる。 A Fourier 変換 虚数単位は i で表す。 テキストによって定義が異なる。 A.1 流儀 1 f : Rn → C に対して、 1 g(ξ) := (2π)n/2 (2) ∫ Rn f (x)e−ixξ dx (ξ ∈ Rn ) で定義される関数 g = g(ξ) を、f の Fourier 変換と呼び、Fg, fˆ などの記号で表す: (3) Ff (ξ) = fb(ξ) = ∫ 1 (2π)n/2 Rn f (x)e−ixξ dx (ξ ∈ Rn ). 多くの f に対して 1 f (x) = (2π)n/2 (4) ∫ g(ξ)eixξ dξ Rn (x ∈ Rn ) が成り立つ。これを Fourier の反転公式と呼ぶ。 一般に、g : Rn → C に対して、(4) で定義される関数 f = f (x) を、g の逆 Fourier 変換 と呼び、F ∗ g, F −1 g, g̃ などの記号で表す: (5) 1 F g = ge(x) = (2π)n/2 ∗ 20 ∫ g(ξ)eixξ dξ Rn (x ∈ Rn ). A.2 流儀 2 (時刻 t と角周波数 ω を使う立場。) x = x(t) に対して ∫ ∞ X(ω) := −∞ x(t)e−iωt dt (ω ∈ R) で定義される関数 X = X(ω) を、x の Fourier 変換と呼び、Fx, x̂ などと表す: ∫ ∞ b(ω) = Fx(ω) = x x(t)e−iωt dt (ω ∈ R). −∞ X = X(ω) に対して 1 x(t) := 2π ∫ ∞ X(ω)eiωt dω (t ∈ R) inf ty e などの記号で表す: で定義される関数 x = x(t) を、X の逆 Fourier 変換と呼び、F ∗ X, F −1 X, X ∫ ∞ 1 ∗ e F X(t) = X(t) := X(ω)eiωt dω (t ∈ R). 2π −∞ X(ω) のことを x(t) の角周波数領域での表現、などと呼ぶこともある。 A.3 流儀 3 x = x(t) に対して ∫ ∞ X(f ) := −∞ x(t)e−2πif t dt (f ∈ R) で定義される関数 X = X(ω) を、x の Fourier 変換と呼び、Fx, x̂ などの記号で表す: ∫ ∞ b(f ) = Fx(f ) = x x(t)e−2πif t dt (f ∈ R). −∞ X = X(t) に対して ∫ ∞ x(t) = X(f )e2πif t df −∞ (t ∈ R) b などの記号で表す: で定義される関数 x = x(t) を X の逆 Fourier 変換と呼び、F ∗ X, X ∫ ∗ b = F X(t) = X(t) X(f )e2πif t df (t ∈ R). R B B.1 Fourier 級数と離散 Fourier 変換 Fourier 級数 周期 T の関数 x = x(t) に対して、次の級数を x の Fourier 級数と呼ぶ: ) ∞ ( a0 ∑ 2nπt 2nπt + + bn sin , an cos 2 T T n=1 21 ただし 1 an := T ∫ T /2 2nπt x(t) cos dt, T −T /2 1 bn := T ∫ T /2 x(t) sin −T /2 2nπt dt. T ここまでは積分区間を [−T /2, T /2] としたが、周期関数であるから、[0, T ] としても同じこと である。 また次の級数を x の複素 Fourier 級数と呼ぶ: ∑ n∈Z exp 2πnit , T ただし cn ( ) 2πnit x(t) exp − dt. T −T /2 ∫ 1 := T T /2 N 2πnit 1 ∑ exp DN (t) := T n=−N T (N ∈ N, t ∈ R) で定義される DN を Dirichlet 核と呼ぶ。 命題 周期 T の任意の周期関数 x = x(t), N ∈ N に対して、 N ∑ 1πnit , xN (t) := cn exp T n=−N 1 cn := T ( ) 2πnit x(t) exp − dt T −T /2 ∫ T /2 とおくとき、xN = x ∗ DN , すなわち ∫ xN (t) = T /2 −T /2 x(t − τ )DN (τ )dτ (t ∈ R) が成り立つ。—「x の Fourier 級数の第 N 項までの部分和は、x と Dirichlet 核 DN との畳 み込みに等しい。」 B.2 離散 Fourier 変換 x = x(t) が周期 T の周期関数であるとする。周期区間 [0, T ] の N 等分点 tj = j T N (j = 0, 1, ..., N = 1) における値 xj = x(tj ) が得られたとき、Fourier 係数 1 cn = T ∫ 0 T ( ) 2nπit x(t) exp − dt T 22 を近似計算することを考える。周期関数の1周期における積分は、台形公式で近似するのが有 効である。今の場合は ( ) ( ) N −1 N =1 1 T ∑ 2nπitj 1 ∑ 2nπij Cn := · xj exp − = xj exp − . T N j=0 T N j=0 N ( 2πi W := exp − N とおくと、 ) N −1 1 ∑ Cn = xj W nj . N j=0 W は 1 の原始 N 乗根であり、 W j ̸= 1 (j = 1, 2, ..., N − 1) W N = 1, を満たす。これから N −1 ∑ W kj = { N (k ≡ 0 (mod N )) 0 (k ̸≡ 0 (mod N )) j=0 が導ける。 m ≡ n (mod N ) ⇒ Cn = Cm であることが分かるので、C0 , C1 , ..., CN −1 だけを考えれば十分である。 −1 数列 {xj }N j=0 に対して、 Xk = N −1 ∑ xj W kj (k = 0, 1, ..., N = 1) j=0 −1 N −1 で定まる数列 {Xk }N k=0 を、{xj }j=0 の離散 Fourier 変換と呼ぶ。また写像 {xj } 7→ {Xk } を離 散 Fourier 変換と呼ぶこともある。(k, j) 成分が W kj である行列を W とすると、 x0 X0 x1 X1 .. = W .. . . . xN =1 XN =1 言い換えると、離散 Fourier 変換の表現行列は W である。 W∗ W = WW∗ = N IN が成り立つ。これから、 W−1 = これから 1 ∗ 1 W = (W −jk ). N N N −1 1 ∑ xj = Xk W −kj N k=0 23 (j = 0, 1, ..., N − 1) が得られる。 not 特に 1 U := √ W N 1 とおくと、U ∗ = √ W∗ であるので、 N U ∗ U = U U ∗ = IN . ゆえに U は unitary 行列である C 離散時間 Fourier 変換 {xn }n∈Z の離散時間 Fourier 変換 (discrete-time Fourier transform,DTFT) とは、 ∑ (6) X(ω) := xn e−inω (ω ∈ R; 実は周期 2π である). n∈Z xn について、有限エネルギー条件 ∑ を課す、としたテキストがある。その場合、 n∈Z|xn |2 <∞ X ∈ L2 (0, 2π) であり、(6) は、L2 における等式と解釈することになる。 この関数 X は周期 2π である: ∀k ∈ Z X(ω + 2πk) = X(ω). ゆえに ω ∈ [0, 2π](あるいは ω ∈ [−π, π]) で考えれば十分である。 xn は関数 X の第 (−n)Fourier 係数と見なせるので ∫ π 1 (7) X(ω)einω dω (n ∈ Z). xn = 2π −π これが離散時間 Fourier 変換の反転公式である。 D 参考文献 [1] 青木直史 : サウンドプログラミング入門 — 音響合成の基本と C 言語による実装, 技術評 論社 (2013). [2] 樋口龍雄, 川又政征 : MATLAB 対応 ディジタル信号処理, 昭晃堂 (2000). 24