C++ - テイラー展開 [ cos(x) ]!
Updated:
先日、\(e ^ {x}\)をテイラー展開を用いて計算する C++ アルゴリズム について紹介しました。
今日は、\(\cos x\)をテイラー展開を用いて計算してみました。
※以下、一部 \(\TeX\) で記載
今回は C++ で実現することが目的なので、テイラー展開の詳細についてはここでは説明しません。 解析学の教科書等でご確認下さい。
以下、C++ によるサンプルソースです。
0. 前提条件
- Scientific Linux 6.3 (64bit) での作業を想定。
- g++ (GCC) 4.4.6 20120305 (Red Hat 4.4.6-4)
1. C++ ソース作成
今回作成した C++ ソースは以下のとおり。
- C++ なのでオブジェクト指向な作りにしている。
- 収束しない場合は最大200項計算するようにしている。
- 今回計算した値と比較するため、C++ 標準の関数の値も出力している。
- \(x=0,\cdots,180\)を10刻みで計算している。
File: taylor_xxpansion_cos.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*********************************************
* テイラー展開 ( cos(x)) )
*********************************************/
#include <iostream> // for cout
#include <math.h> // for cos()
#include <stdio.h> // for printf()
using namespace std;
/*
* 計算クラス
*/
class Calc
{
// 各種定数
static const double eps = 1e-08; // 精度
static const double pi = 3.1415926535; // 円周率
// 各種変数
double x; // X 値
double rd; // ラジアン値
double e; // e 値
double d; // d 和
double s; // s 和
int k; // LOOP インデックス
public:
// テイラー展開
void calcTaylor();
// Cos 計算
double calcCos(double x);
};
/*
* テイラー展開
*/
void Calc::calcTaylor()
{
// ラジアン値計算
rd = pi / 180;
// x = 0 から 180 を 10 刻みで計算
printf(" x mycos(x) cos(x)\n");
for (x = 0; x <= 180; x += 10)
printf("%5.1f%14.6f%14.6f\n", x, calcCos(x * rd), cos(x * rd));
}
/*
* Cos 計算
*/
double Calc::calcCos(double x)
{
// 変数初期化
d = 1.0;
s = 1.0;
e = 1.0;
// x の値が 0 から 2π の範囲外の場合、0 から 2π に収める
x = fmod(x, 2 * pi);
// 最大200回ループ処理
// ( ただし、偶数項は 0 なので除外 )
for(k = 1; k <= 200; k = k + 2) {
d = s; // d 和
e = -e * x * x / (k * (k + 1)); // 各項の値
s += e; // s 和
// 打ち切り誤差
if (fabs(s - d) / fabs(d) < eps)
return(s);
}
// 収束しない時
return(9999.0);
}
/*
* メイン処理
*/
int main()
{
try
{
// 計算クラスインスタンス化
Calc objCalc;
// テイラー展開
objCalc.calcTaylor();
}
catch (...) {
cout << "例外発生!" << endl;
return -1;
}
// 正常終了
return 0;
}
2. C++ ソースコンパイル
$ g++ taylor_expansion_cos.cpp -o taylor_expansion_cos
何も出力されなければ成功です。
3. 実行
$ ./taylor_expansion_cos
x mycos(x) cos(x)
0.0 1.000000 1.000000
10.0 0.984808 0.984808
20.0 0.939693 0.939693
30.0 0.866025 0.866025
40.0 0.766044 0.766044
50.0 0.642788 0.642788
60.0 0.500000 0.500000
70.0 0.342020 0.342020
80.0 0.173648 0.173648
90.0 0.000000 0.000000
100.0 -0.173648 -0.173648
110.0 -0.342020 -0.342020
120.0 -0.500000 -0.500000
130.0 -0.642788 -0.642788
140.0 -0.766044 -0.766044
150.0 -0.866025 -0.866025
160.0 -0.939693 -0.939693
170.0 -0.984808 -0.984808
180.0 -1.000000 -1.000000
標準関数と同じ結果が得られた。
その他
ちなみに、
など、色々計算可能です。
数学はおもしろいけど、コンピュータで実証するというのもおもしろいです。
※ちなみに最近の当方の C++ アルゴリズムについての記事は、古い C によるアルゴリズムに関する書物を参考に C++ に移植した形態となっています。
以上。
Comments