数学の具体的な計算にMaximaを使って、数学もMaximaも同時に学んでしまいましょう。
今回はMaximaを使って関数のFourier(フーリエ)級数展開を見てみたいと思います。
いくつかの関数について、そのFourier級数展開から円周率の級数表式が得られますが、
おまけとしてこれをMaximaで数値的に確かめてみます。
また、正弦関数の無限乗積による恒等式についてもコメントしておきます。
三角関数の直交性
関数
は の変域で正規化された直交関数系をなします。実際に計算してみましょう:
declare([m,n], integer)$ integrate(cos(m*x)/sqrt(%pi)*cos(n*x)/sqrt(%pi), x, -%pi, %pi); integrate(cos(m*x)/sqrt(%pi)*cos(m*x)/sqrt(%pi), x, -%pi, %pi);
integrate(sin(m*x)/sqrt(%pi)*sin(n*x)/sqrt(%pi), x, -%pi, %pi); integrate(sin(m*x)/sqrt(%pi)*sin(m*x)/sqrt(%pi), x, -%pi, %pi);
integrate(sin(m*x)/sqrt(%pi)*cos(n*x)/sqrt(%pi), x, -%pi, %pi); integrate(sin(m*x)/sqrt(%pi)*cos(m*x)/sqrt(%pi), x, -%pi, %pi);
integrate(1/sqrt(2*%pi)*cos(m*x)/sqrt(%pi), x, -%pi, %pi);
integrate(1/sqrt(2*%pi)*sin(m*x)/sqrt(%pi), x, -%pi, %pi);
integrate(1/sqrt(2*%pi)*1/sqrt(2*%pi), x, -%pi, %pi);
以上より正規直交性がわかります。
Fourier級数展開の例
ここでFourier級数の具体例を見てみましょう。
例は寺澤寛一『自然科学者のための数学概論』(岩波書店)を参照しました。
例1:f(x)=x
f(x):=x$ A0:integrate(1/sqrt(2*%pi)*f(x), x, -%pi, %pi); A(n):=integrate(cos(n*x)/sqrt(%pi)*f(x), x, -%pi, %pi)$ B(n):=integrate(sin(n*x)/sqrt(%pi)*f(x), x, -%pi, %pi)$ makelist(A(n), n, 1, 10); makelist(B(n), n, 1, 10);
より
そのFourier級数展開は
となります。
また、Fourier級数の展開係数を求めるコマンドはMaximaに実装されています:
load(fourie)$ /* fourier ではなく fourie であることに注意 */ totalfourier(x, x, %pi);
ただし、このコマンドで得られる展開係数は
として再定義されたものです。よってこのコマンドで得られるFourier級数展開は
という形になります。
円周率(Leibniz/Eulerの級数)
さて、上で得られたFourier級数展開で とおくことで等式
がわかります。この級数はLeibnizの級数、またはEulerの級数と呼ばれます。
この級数を数値的に検証してみましょう:
P[n]:=4+4*sum((-1)^k/(2*k+1), k, 1, n)$
とすることで、級数を 項まで足したときの値が数値的に求められます。
例えば1万項を足したときには
bfloat(P[10000]);
より、級数の値は
となります。円周率の値は
bfloat(%pi);
より
ですから、1万= 項の和で4桁程度までは数値的に再現できていることがわかります。
10万項の和だと
bfloat(P[100000]);
より
となって精度が1桁ほど上がります。
しかし計算量が多いようで、出力には 20.2 秒ほどかかりました。
ちなみに、1万項の場合で 0.3 秒、20万項の場合では 80.5 秒かかりました。
項の数を 倍すると時間はだいたい 倍になるようなので、
欲張って100万項の場合を計算しようとすると、2000秒=30分くらいかかるはずです。
(もちろん、使っているコンピュータの性能によりますが)
例2:f(x)=|x|
kill(all)$ load(fourie)$ totalfourier(abs(x), x, %pi);
より展開係数は
なので、Fourier級数展開
を得ます。とくに とおくことで等式
がわかります。
級数を数値的に見てみましょう:
kill(all)$ P[n]:=8*sum(1/(2*k+1)^2, k, 0, n)$
から、1万項まで足したものから円周率を求めると、数値的には
bfloat(P[10000])$ sqrt(%);
より
です。
例3:f(x)=x^2
kill(all)$ load(fourie)$ totalfourier(x^2, x, %pi);
より展開係数は
なので、Fourier級数展開
を得ます。とくに とおくことで
がわかります。
数値的に見てみましょう:円周率を求めてみると
kill(all)$ P[n]:=12*sum((-1)^k/(k+1)^2, k, 0, n)$ bfloat(P[10000])$ sqrt(%);
から
です。
例4:f(x)=-1,1
ここで、奇関数
に対して、その性質を使うとFourier級数の展開係数が
また、 と がそれぞれ偶関数、奇関数であることから、同様にして
となります。
( が偶関数である場合には となり、
は積分範囲を にすることができます)
これを使うと上記関数のFourier級数展開は
f(x):=1$ B(n):=2*integrate(sin(n*x)/sqrt(%pi)*f(x), x, 0, %pi)$ makelist(B(n), n, 1, 10);
より
よって
がわかります。
例5:f(x)=sin(ax)
ただし は整数でない実数とします。
kill(all)$ load(fourie)$ totalfourier(sin(a*x), x, %pi);
より、奇関数なので そして
ゆえに
例6:f(x)=cos(ax)
ただし は整数でない実数とします。
kill(all)$ load(fourie)$ totalfourier(cos(a*x), x, %pi);
より、偶関数なので そして
ゆえに
を得ます。