Fortran - テイラー展開 cos(x)!
Updated:
Fortran 95 で \(\cos(x)\) のテイラー展開を計算する方法についての記録です。
0. 前提条件
- LMDE 3 (Linux Mint Debian Edition 3; 64bit) での作業を想定。
- GCC 6.3.0 (GFortran 6.3.0) でのコンパイルを想定。
1. アルゴリズムについて
当ブログ過去記事を参照のこと。
2. ソースコードの作成
File: taylor_expansion_cos.f95
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
!****************************************************
! テイラー展開 [ cos(x) ]
!
! * 自作関数と組込関数の計算結果を比較
!
! date name version
! 2018.12.12 mk-mode.com 1.00 新規作成
!
! Copyright(C) 2018 mk-mode.com All Rights Reserved.
!****************************************************
!
module const
! SP: 単精度(4), DP: 倍精度(8)
integer, parameter :: SP = kind(1.0)
integer(SP), parameter :: DP = selected_real_kind(2 * precision(1.0_SP))
real(DP), parameter :: PI = 4.0_DP * atan(1.0_DP) ! 円周率
real(DP), parameter :: D2R = PI / 180.0_DP ! 度 => ラジアン
real(DP), parameter :: EPS = 1.0e-8_DP ! 精度
end module const
module taylor_expansion
use const
implicit none
private
public :: my_cos
contains
! テイラー展開
!
! :param(in) real(8) x: X
! :param(inout) real(8) y: 展開後
function my_cos(x) result(y)
implicit none
real(DP), intent(in) :: x
real(DP) :: y, d, s, e, x_tmp
integer(SP) :: k
! 変数初期化
d = 1.0_DP
s = 1.0_DP
e = 1.0_DP
! x の値が 0 から 2π の範囲外の場合、0 から 2π に収める
x_tmp = mod(x, 2.0_DP * PI)
! 最大200回ループ処理
! ( ただし、偶数項は 0 なので除外 )
do k = 1, 200, 2
d = s ! d 和
e = -e * x_tmp * x_tmp / (k * (k + 1)) ! 各項の値
s = s + e ! s 和
! 打ち切り誤差
if (abs(s - d) / abs(d) < EPS) then
y = s
return
end if
end do
! 収束しない時
y = 9999.0_DP
end function my_cos
end module taylor_expansion
program taylor_expansion_cos
use const, only : SP, DP, D2R
use taylor_expansion
implicit none
integer(SP) :: x
real(DP) :: r_x
! x = 0 〜 180 を 10 刻みで計算
print '(A)', " x my_cos(x) cos(x)"
do x = 0, 180, 10
r_x = real(x, DP)
print '(X, F5.1, 2X, F9.6, 2X, F9.6)', &
& r_x, my_cos(r_x * D2R), cos(r_x * D2R)
end do
end program taylor_expansion_cos
3. ソースコードのコンパイル
$ gfortran -o taylor_expansion_cos taylor_expansion_cos.f95
4. 動作確認
$ ./taylor_expansion_cos
x my_cos(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
今回の結果出力の桁数では、組み込み関数と同じ値が得られた。(ちなみに(当然ながら)、出力桁数を増やすと誤差が生じるのが分かる)
以上。
Comments