画像処理とフーリエ変換 宿題 1 のグラフ描き 桂田 祐史 http://nalab.mind.meiji.ac.jp/~mk/fourier/ 2014 年 10 月 24 日 問 11 の関数 f , g の Fourier 級数展開そのものは授業中に説明した通り、 ( ) π 4 cos x cos 3x cos 5x f (x) = − + + + ··· , 2 π 12 32 52 ( ) 4 sin x sin 3x sin 5x + + + ··· . g(x) = π 1 3 5 f は連続で区分的に C 1 級、g は区分的に C 1 級 (ゆえに 2 乗可積分) であるから、どのような 収束をするかは、10/17 の授業で説明した 3 つの定理で説明が出来る。 こうすれば Fourier 級数の部分和 fn , gn のグラフが描ける f[n_,x_]:=Pi/2-4/Pi Sum[Cos[k x]/k^2,{k,1,n,2}] gf10=Plot[f[10, x], {x, -10, 10}] g[n_,x_]:=4/Pi Sum[Sin[k x]/k,{k,1,n,2}] gg20=Plot[g[20,x],{x,-10,10}] n を変えて gn の変化の様子を見たければ、 Manipulate[Plot[g[n, x], {x, -Pi, Pi}, PlotPoints -> 200], {n, 1, 100, 1}] グラフィックスを保存するには Export["graphf10.pdf",gf10] Export["graphg20.pdf",gg20] g の不連続点 x = 0, ±π の近くでは、ぴょこっと高い山、それと対称な低い谷があり、n が 増加すると横幅は小さくなるが、高さはほとんど変わらない (低くなってくれない) ことが見 て取れる。 おまけ: hn のグラフを描いてみる h[n_,x_]:=4/Pi Sum[Cos[k x],{k,1,n,2}] Manipulate[Plot[h[n,x], {x,-7,7}, PlotRange -> Full, AspectRatio->Automatic, PlotPoints -> 100], {n, 2, 20, 2}] , AspectRatio->Automatic は入れた方が良いかどうか判らないが。 1 http://nalab.mind.meiji.ac.jp/~mk/lecture/fourier-2014/toi1.pdf 1 もっと色々 Mathematica にさせてみる f や g のグラフを描かせたり、Fourier 係数を求めて、部分和の計算をさせたりしてみよう。 f (x) = |x| (−π < x < π) ということで、積分の計算をするだけならば f[x_]:=Abs[x] 使うだけで、十分であるが、周期関数らしいグラフを描くには次のようにすると良い。 f[x_]:=Abs[Mod[x,2Pi,-Pi]] gf=Plot[f[x],{x,-10,10}] とすると良い。Fourier 係数 ak = 1 π ∫π −π f (x) cos kx dx の計算は、例えば Integrate[f[x]Cos[k x],{x,-Pi,Pi}]/Pi これで 2(−1+cos kπ+kπ sin kπ) k2 π が得られる。k が整数と教えてないので、結果が複雑。 Simplify[Integrate[f[x]Cos[k x],{x,-Pi,Pi}]/Pi, Assumptions->Element[k,Integers]] 2(−1+(−1)k ) とすると、 k2 π が得られる。実はこれにも問題がある。k = 0 のとき正しくない式で ある! !ここら辺は Mathmatica は変な割り切り方をしている (マニュアルによると、“不定積 分において,Integrate は,ほとんどすべてのパラメータの値に対して正しい結果を求める.” — 少数の例外は無視?)。注意が必要である。k = 0 の場合については別扱いで Integrate[f[x],{x,-Pi,Pi}]/Pi, とすると良い。π という結果が得られる。 ∫π bk = π1 −π f (x) sin kx dx については Integrate[f[x] Sin[k x], {x, -Pi, Pi}] とすると 0 が返る。 f の Fourier 係数を a[] という関数で計算させて、f の n 項までの部分和 fn を計算するよ うにする。 ほぼ全自動 Clear[a,f] f[x_]:=Abs[Mod[x,2Pi,-Pi]] a[k_]=Simplify[Integrate[f[x]Cos[k x],{x,-Pi,Pi}]/Pi, Assumptions->Element[k,Integers]] a[0]=Integrate[f[x],{x,-Pi,Pi}]/Pi f[n_,x_]:=a[0]/2+Sum[a[k]Cos[k x],{k,1,n}] gf10=Plot[f[10,x],{x,-10,10}] (実は Simplify[] はしなくてもあまり効率に影響がない。f[n,x] は Sum[] を使っているの で、遅延評価 := をしないとうまく動かない。一方 a[k ] の方を遅延評価するのはお勧めでき ない。ここら辺は難しい。最初に Fourier 係数を全部計算して、その結果をリストに保存して 使うのが良いかもしれない。) 2 x = 0 のところで fn (x) − f (x) の値を調べると、図 1 のように減少している (1/n に比例し ていることが分かる)。 list=Table[f[2^k,0.0]-f[0.0],{k,1,10}] gerror=ListLogPlot[list] Export["error.pdf",gerror] n = 210 のとき誤差は 0.000621699 ≒ 0.6 × 10−3 1 0.50 0.10 0.05 10-2 10-3 2 4 6 8 10 図 1: fn (0) − f (0) の変化 (n = 2k , k = 1, 2, · · · , 10) Clear[g,bg] g[x_]=Sign[Mod[x,2Pi,-Pi]] bg[k_]=Simplify[Integrate[g[x]Sin[k x],{x,-Pi,Pi}]/Pi, Assumptions->Element[k,Integers]] g[n_,x_]:=Sum[bg[k]Sin[k x],{k,1,n}] ggandg10=Plot[{g[x],g[10,x]},{x,-10,10}] 1.0 0.5 -10 5 -5 -0.5 -1.0 図 2: g と g の 10 項までの部分和 g10 のグラフ 3 10 h について h(x) = 2 ∑ (−1)n δ(x − nπ). n∈Z ここで δ は Dirac のデルタ関数 (以下では単にデルタ関数という) を表す。デルタ関数は 実は関数ではなく、超関数というものであり、本来はグラフを描いたりすることも出来ない ものであるが (x ̸= 0 で 0, x = 0 で ∞ という「説明」もあるが、∞ は図に描けない)、実は Fourier 級数展開は可能であり、その部分和は以下に見るように普通の関数なので、グラフを 描くことが出来る。 デルタ関数は、任意の連続関数 φ に対して ∫ ∞ δ(x)φ(x) dx = φ(0) −∞ を満たすという条件や、 ∫ δ(x) = 0 (x ̸= 0), ∞ δ(x) dx = 1 −∞ で特徴づけられる。物理学では、大きさのない 1 点に質量や電荷などが集中しているという理 想化を考えるが (質量の場合は質点、電荷の場合は点電荷と呼ぶ)、デルタ関数は、そのように 1 点に 1 単位のものが集中している場合の、密度を表す関数と考えられる (直観的には、原点 で無限大。積分すると総量になって 1)。 h の定義には、デルタ関数を平行移動した δ(x − nπ) が現れるが、δ(x − a) は ∫ ∞ δ(x − a)φ(x) dx = φ(a) −∞ という性質を持つ。 さて、h の Fourier 級数展開の計算であるが、f や g のように [−π, π] で積分するとして、 どうすれば良いだろうか? (♯1 ) h(x) = 2 (δ(x) − δ(x − π)) , (♯2 ) h(x) = 2 (δ(x) − δ(x + π)) , (♯3 ) h(x) = 2 (δ(x) − δ(x − π) − δ(x + π)) , このどれが正しいのだろうか?周期 2π の周期関数とは R/2πZ で定義された関数のことと考 えると、π と −π は同じ点を表すことになるので、(♯1 ), (♯2 ) のどちらも同じことを表してい て正しそうであり、(♯3 ) は 1 つのものを重複してカウントしていて間違っていそうである。 あるいは積分範囲を [−π, π] でなく、少し右にずらした [−π + ε, π + ε] を考えてみると (ε は小さい正の数)、(♯1 ) を採用することになり、逆に [−π − ε, π − ε] と左にずらすと、(♯2 ) を 採用することになる。どちらで計算しても Fourier 係数は同じになる。 これから ∫ ) 2 2( 1 π h(x) cos kx dx = (cos (k · 0) − cos kπ) = 1 − (−1)k , ak = π −π π π ∫ π 1 2 bk = h(x) sin kx dx = (sin (k · 0) − sin kπ) = 0. π −π π 4 ゆえに h の Fourier 級数展開は h(x) = 4 (cos x + cos 3x + cos 5x + · · · ) . π この級数は普通の意味では収束しない、発散級数であるが、超関数の意味では収束している。 また部分和は普通の関数になっていて、グラフも描ける。 h[n_,x_]:=4/Pi Sum[Cos[k x],{k,1,n,2}] Manipulate[Plot[h[n,x], {x,-7,7}, PlotRange -> Full, AspectRatio->Automatic, PlotPoints -> 100], {n, 2, 20, 2}] 工学系の本には「デルタ関数列」というものが良く出て来る (数学の解析の本で、軟化作用 素を定義する際の関数列と同じものと考えて良い)。これは n → ∞ の極限で δ となる関数列 {φn } である。 ∫ ∞ −∞ φn (x) dx = 1 という性質を満たしつつ、n が大きくなるにつれ、x = 0 の近くに集中していくものになって いる。例えば工学の本で良く見かけるのは φn (x) = sin nx . πx このグラフも描いてみて、hn のグラフと見比べてみると良い。 なお、ここまで来ると推察できると思うが、h は g の (超関数の意味での) 導関数である。 実際、Heaviside の階段関数 { 1 (x ≥ 0) H(x) = 0 (x < 0) の導関数は δ になることが知られているので、 g ′ (x) = 2δ(x) − 2δ(x − π) = h(x) ([−π + ε, π + ε] での等式). そして、これまでと同様に、h の Fourier 級数展開は、g の Fourier 級数展開を項別微分した ものになっている。 5
© Copyright 2024 ExpyDoc