前提・実現したいこと
次のような三角波、正弦波の矩形近似によるフーリエ級数展開を考えています。コメント文で示した部分(3か所)をどう記述すればよいかご教示いただければ幸いです。
f(t) = 1/2(1 - 2t/T) -2/T < t < T/2
1/2 t = ± T/2
f(t) = 1/2{ 1 + cos(2πt / T) -T/2 ≦ t ≦ T/2
該当のソースコード
C
1#include <stdio.h> 2#include <math.h> 3#define M_PI 3.14159265 4#define MM 300 //フーリエ級数展開の打ち切り次数 5#define Tp 1.0 //周期波形の周期 6 7double aa[MM+1], bb[MM+1] ; //フーリエ展開係数 8int NN = 3 * MM ; //数値積分の分割数 9 10double ft(double t) 11{ 12 double zero = 1.0e-8 ; 13 while ( t < -Tp/2.0 ){ t = t+Tp ;if( t > -Tp/2.0 ) break ;} 14 while ( t > Tp/2.0 ){ t = t-Tp ;if( t < Tp/2.0 ) break ;} 15 16 17 if( fabs( t+Tp/2.0 ) < zero || fabs( t-Tp/2.0) < zero ) return 0.5 ; 18 else return 0.5 - t/Tp; //ここは間違っている可能性あり① 19 20 21 return 0.5 + 0.5 * cos((2.0 * M_PI * t) / Tp); //ここは間違っている可能性あり② 22} 23 24double ak_dt(int k, double t) 25{ 26 return ft(t) * cos( (double)k * 2.0 * M_PI / Tp * t ) ; 27} 28 29double fcoeff_ak( int k ) 30{ /* 関数f(t)のフーリエ展開級数 a_kを数値積分で求める */ 31 double t, i, ak = 0.0, dt = Tp/(double)NN ; 32 for( i = 0 ; i < NN ; i ++ ) { 33 t = -Tp/2.0 + (double)i * dt ; 34 ak = ak + sin(t) / t ; // ここがよくわかっていません。③ 35 } 36 37 return ak ; 38} 39 40double bk_dt(int k, double t) 41{ 42 return ft(t) * sin( (double)k * 2.0 * M_PI / Tp * t ) ; 43} 44 45double fcoeff_bk(int k) 46{ 47 double t, i, bk = 0.0, dt = Tp/(double)NN ; 48 for( i = 0 ; i < NN ; i ++ ) { 49 t = -Tp/2.0 + (double)i * dt ; 50 bk = bk + sin(t) / t ; // 同様にここがわかりません。④ 51 } 52 return bk ; 53} 54 55double fxfreq( double *aa, double *bb, int M, double t) 56{ 57 int k ; double ff = 0.0 ; 58 for ( k = 0 ; k <= MM ; k++ ) ff = *aa*cos(((double)k * 2.0 * M_PI * t)/ Tp ) + *bb*sin(((double)k * 2.0 * M_PI * t)/Tp ) ;//ここは合っているのかどうかわかりません。⑤ 59 return ff; 60} 61 62int main() 63{ 64 int i, k, n=2 ; double t, fh ; 65 int KK = 1000 ; 66 67 aa[0] = fcoeff_ak(0)/2.0 ; bb[0] = 0.0 ; 68 for (k=1; k<=MM; k++) { 69 aa[k] = fcoeff_ak(k) ; bb[k] = fcoeff_bk(k) ; 70 } 71 72 73 for (i=0; i<= n*KK; i++) { 74 t = -Tp*(double)n/2.0 + Tp/(double)KK * (double)i ; 75 fh = fxfreq( aa, bb, MM, t ) ; 76 printf(" %10.8f %10.8f %10.8f\n", t, ft(t), fh ); 77 } 78 return 0; 79}
試したこと
実行してみましたが、正しい結果が得られませんでした。実行結果の一部分を掲載いたします。ft(t)は正しいと思います。fhもft(t)と近い値になるはずだと思うのですが、同じ値を行ったり来たりしています。
-0.00900000 0.50900000 -137.14071854
-0.00800000 0.50800000 -359.03903645
-0.00700000 0.50700000 359.03904488
-0.00600000 0.50600000 137.14070490
-0.00500000 0.50500000 -443.79666119
-0.00400000 0.50400000 137.14071399
-0.00300000 0.50300000 359.03903926
-0.00200000 0.50200000 -359.03904207
-0.00100000 0.50100000 -137.14070945
-0.00000000 0.50000000 443.79666119
0.00100000 0.49900000 -137.14070945
0.00200000 0.49800000 -359.03904207
0.00300000 0.49700000 359.03903926
0.00400000 0.49600000 137.14071399
0.00500000 0.49500000 -443.79666119
0.00600000 0.49400000 137.14070490
0.00700000 0.49300000 359.03904488
0.00800000 0.49200000 -359.03903645
0.00900000 0.49100000 -137.14071854
0.01000000 0.49000000 443.79666119
0.01100000 0.48900000 -137.14070035
0.01200000 0.48800000 -359.03904769
0.01300000 0.48700000 359.03903364
0.01400000 0.48600000 137.14072308
0.01500000 0.48500000 -443.79666119
補足情報(FW/ツールのバージョンなど)
Visual Studio Code (Version 1.46)を使用しています。
回答1件
あなたの回答
tips
プレビュー