Fortran - ラグランジュ補間!
Updated:
Fortran 95 でラグランジュ補間を行う方法についての記録です。
0. 前提条件
- LMDE 3 (Linux Mint Debian Edition 3; 64bit) での作業を想定。
- GCC 6.3.0 (GFortran 6.3.0) でのコンパイルを想定。
1. アルゴリズムについて
当ブログ過去記事を参照のこと。
2. ソースコードの作成
File: lagrange_interpolation.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
79
80
81
82
83
84
85
!****************************************************
! ラグランジュ補間
!
! * 入力はテキストファイルをパイプ処理
! 1行目: 点の数
! 2行目以降: x, y
!
! date name version
! 2018.12.13 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))
end module const
module lagrange
use const
implicit none
private
public :: interpolate
contains
! ラグランジュ補間
!
! :param(in) real(8) pts(2, num_pt): あらかじめ与えられた点の配列
! :param(in) integer(4) num_pt: あらかじめ与えられた点の数
! :param(in) real(8) x: 補間する x 値
! :return real(8) y: 補間後の y 値
function interpolate(pts, num_pt, x) result(y)
implicit none
real(DP), intent(in) :: pts(2, num_pt), x
integer(SP), intent(in) :: num_pt
real(DP) :: y
integer(SP) :: i, j
real(DP) :: p
! 総和初期化
y = 0.0_DP
! 総和
do i = 1, num_pt
p = pts(2, i)
! 総積
do j = 1, num_pt
if (i /= j) p = p * (x - pts(1, j)) / (pts(1, i) - pts(1, j))
end do
y = y + p
end do
end function interpolate
end module lagrange
program lagrange_interpolation
use const
use lagrange
implicit none
real(DP),allocatable :: pts(:, :) ! あらかじめ与える点
integer(SP) :: num_pt, i
real(DP) :: x, y
! 点の数の取得
read (*, *) num_pt
! 配列メモリ確保
allocate(pts(2, num_pt))
! あらかじめ与えられた点の読み込み
do i = 1, num_pt
read (*, *) pts(:, i)
end do
! ラグランジュ補間
! (1行1点(x, y)で出力)
do i = int(pts(1, 1)), int(pts(1, num_pt)) * 2
x = real(i, DP) / 2
y = interpolate(pts, num_pt, x)
print '(F7.2, X, F7.2)', x, y
end do
! 配列メモリ解放
deallocate(pts)
end program lagrange_interpolation
3. ソースコードのコンパイル
$ gfortran -o lagrange_interpolation lagrange_interpolation.f95
4. 動作確認
今回のプログラムはデータファイルを読み込んで実行する形式としているので、あらかじめデータファイルを作成しておく。(実行後に手入力してもよいが)
※1行目:点の数、2行目以降:x, y
File: pts_src.txt
1
2
3
4
5
6
5
0.0 0.8
2.0 3.2
3.0 2.8
5.0 4.5
8.0 1.9
そして、実行。
$ cat pts_src.txt | ./lagrange_interpolation
0.00 0.80
0.50 2.49
1.00 3.23
1.50 3.37
2.00 3.20
2.50 2.95
3.00 2.80
3.50 2.85
4.00 3.17
4.50 3.74
5.00 4.50
5.50 5.32
6.00 6.03
6.50 6.37
7.00 6.05
7.50 4.70
8.00 1.90
5. 結果確認
GNUPLOT で描画してみた。
以上。
Comments