第9回 6/16

平成27年度
情報基礎演習Ⅰ
第9回 演習
担当 光武 雄一
授業のWebsite: http://web.me.saga-u.ac.jp/~mitutake/info1/info1.html
メールアドレス: [email protected]
第9回 演習内容




先週の課題解答と説明
一次元配列の使い方(P.60~65)
フィボナッチ数列の計算
平均値と標準偏差の計算
Report0609
演習課題1 教科書58ページ 演習問題3.5
Iの階乗は,漸化式I! =(I-1)!×Iで計算できる.
 アルゴリズム
(1) 整数Nの入力
(2) 階乗の値Kに初期値0!=1を代入
(3) I=1~Nまで以下の処理を繰り返す.
(3-1) K = K * I
(4) K=N!の値を出力する

Report0609 課題1プログラム例
プログラムの先頭2行と最後2行は省略
integer :: i, k, n
read(*,*) n
! 整数nの読み込み
k=1
! 初期値0!を代入
do i=1, n
k=k*I
!漸化式でI=1~Nまでの階乗を求める
end do
write(*,*) n,’! = ‘, k ! N!の値を出力
Report0609
演習課題2 教科書58ページ 演習問題3.5の変形

一般項aiを求めるための漸化式
ai 
1
1

i ! 1  2  (i  2)  (i  1)  i
a
1

 i 1
(i  1)!  i
i
アルゴリズム
(1) N=1から30まで以下の処理を繰り返す.
(1-1) 級数の一般項Aに初項1を代入
(1-2) 級数の和Sに初期値(初項)を代入
(1-3) I=1~Nまで以下の処理を繰り返す.
(1-3-1) 一般項aiを漸化式A = A / Iで求める
(1-3-2) i項までの部分和SiをS=S+Aで求める
(1-4) 第N項の部分和の値Snを出力する

Report0609 課題2の解答例
integer :: i, n
real :: a, s
do n = 1, 30
a = 1.0
s=a
do i =1, n
a = a / real(i)
s=s+a
end do
write(*,*) n, s
end do
Report0609
演習課題3 教科書58ページ 演習問題3.5の変形

exのマクローリン展開の
一般項aiを求めるための漸化式
xi
x i 11
ai  
i ! 1  2  (i  2)  (i  1)  i
x i 1  x
 x

    ai 1
(i  1)!  i  i 
アルゴリズム
(1) 独立変数Xの値を読み込む
(2) N=1から30まで以下の処理を繰り返す.
(2-1) 級数の一般項Aに初項1を代入
(2-2) 級数の和Sに初期値(初項)を代入
(2-3) I=1~Nまで以下の処理を繰り返す.
(2-3-1) 一般項aiを漸化式A = A*X / Iで求める
(2-3-2) i項までの部分和SiをS=S+Aで求める
(1-4) 第N項の部分和の値Snを出力する

Report0609 課題3の解答例
integer :: i, n
real :: a, s, x
read(*,*) x
do n = 1, 30
a = 1.0
s=a
do i =1, n
a = a *x / real(i)
s=s+a
end do
write(*,*) n, s
end do
Report0609
演習課題3の別解
exのマクローリン展開の
N
1
x
i
一般項をai・x とおくと,係数aiは
e  ai  x i , ai 
i!
課題2と同様の手順で与えられる.
i 0
ただし,部分和Sに足すときxiを係数aiに掛けること.

アルゴリズム
(1) 独立変数Xの値を読み込む
(2) N=1から30まで以下の処理を繰り返す.
(2-1) 係数Aに初期値1を代入
(2-2) 級数の和Sに初項1を代入
(2-3) I=1~Nまで以下の処理を繰り返す.
(2-3-1) 係数の一般項aiを漸化式A = A / Iで求める
(2-3-2) i項までの部分和SiをS=S+A*X**real(I)で求める
(1-4) 第N項の部分和の値Snを出力する


Report0609 課題3の解答例
integer :: i, n
real :: a, s, x
read(*,*) x
do n = 1, 30
a = 1.0
s = 1.0
do i =1, n
a = a / real(i)
s = s + a*x**real(i)
end do
write(*,*) n, s
end do
Report0609 課題4
演習課題4 教科書p.58 演習問題3.7
アルゴリズム
(1) 級数の項数N(正の整数)を入力する
(2) k=0~20まで以下の処理を繰り返す
(2-1) 独立変数x=k/10で求める
(2-2) 級数和Sを0で初期化
(2-3) i=1~Nまで以下の処理を繰り返す
(2-3-1) S = S + (-1)i-1sin(i・x) / i
(2-4) 変数Xと級数和Sを出力する
Report0609 課題4の解答例
integer :: i, k, n
real :: s, x
read(*,*) n
write(*,*) ’ x
s’ ! 数表の列見出しの出力
do k = 0, 20
x = real(k)/10.0
! K=0~20のとき,X=0~2まで0.1刻みで増加
s =0.0
! フーリエ級数の和Sを0で初期化
do i = 1, n
! 第1項から第n項までの級数和を求める
s = s +(-1.0)**real(i-1)*sin(real(i)*x)/real(i)
end do
write(*,’(1x, f3.1, E15.7)’) x, s ! Xに対するフーリエ級数の和Sの出力
end do
Fourier級数
任意の周期関数を直交関数であるsin,cosの線形
結合で表現する方法
1
0
N = 10
-1
N =100
0

2
演習問題3.7の式は,奇関数のsinを用いた級数展開式で周期2,振幅の“のこぎり波”
を表現したものである.級数の項数N の増加と伴に直線的変化に近づく様子が分かる.
ただし,不連続点となる付近では振動的な挙動を示し,を増やしても減衰しないギブス現象
として知られている.
レポートに関するコメント




授業時間中に演習課題ができないのであれば,積極的に質問してでもプログラムを
完成させるべき.
授業中の説明では,基本的なアルゴリズムの提示とシンプルな考え方を説明している
が,その内容を十分に理解しないまま,ユニークなプログラムを作成した例が多い.
それでも正しい結果が得られるなら良いが,実行結果は間違っている.基本に忠実な
プログラムを作成することに注力すること.
実行結果を見て,正しい結果が得られているのか確認を行うこと.
配列の使い方1(教科書第4章)
なぜ,配列変数が必要なのか?
例題3.3 合計値計算のアルゴリズム(教科書p.54)
第1案;先にN個のデータを入力した後,その合計値を求める
このアルゴリズムを実現するには、N個のデータを別々の変数に代入する
必要がある。同じ変数に代入すると先に入力したデータが失われ、入力後
そのデータが利用できないからである。
これまで習ったプログラミング方法では,N個のデータを保存する変数は
型宣言文でN個の異なる変数名をつけて準備する.データ個数が10個程度
なら,A1,A2, A3,・・・A10とタイプできても,数が多くなると宣言文を書くの
も大変だし,多数の変数を間違いなく取り扱うのは非常に困難.
そこで,一組のデータに対して,全体としての名前(これを配列名と呼ぶ)
をつけ,個々のデータの区別は整数の番号を対応付けた添字を用いて行う.
これを配列変数と呼ぶ.
配列の使い方2(教科書p.60)
1次元配列変数のイメージ
配列変数は,変数名(添字)の形で表現される.
配列とは,以下のように一組のデータが入った箱と考えれば
よい.箱の中身(数値)を参照するには,添字の番号を指定し
なければならない.データが入った箱が連続して1次元的に
つながっているので,これを1次元配列とよぶ.
数学で用いる添字付き記号 a1, a2, a3, ・・・, a5 あるいは,
ベクトル a = (a1, a2, a3, ・・・, a6) と同じイメージ
Ex. 変数Yに配列Aの3番目のデータを代入する
Y = A(3)
A(1) A(2) A(3) A(4) A(5) A(6)
=1.0 =3.5 =-3.0 =6.0 =1.2 =5.3
配列の使い方3
配列変数の宣言文の書き方
プログラム中で使用する配列変数の宣言文は,以下の要領で記述する.
(整数型)
(実数型)
INTEGER ,DIMENSION(寸法)::配列名
REAL ,DIMENSION(寸法) :: 配列名
ここで,配列の寸法は,添字番号の範囲を指定するもので,一般には
添字の下限:添字の上限
例 1:10 , 0:5
と記述するが,添字の下限が1の場合には,下限部分を省略して
添字の上限
例 10 (1:10と同じ)
のみを書いてよい.
配列の宣言文の記述例




実数型配列変数A(0)~A(100)までの101個の配列を準備
REAL, DIMENSION(0:100) :: A
整数型配列変数K(1)~K(5)までの5個の配列を準備
INTEGER, DIMENSION(5) :: K
実数変数Y(-1)~Y(10)までの12個の配列を準備
REAL, DIMENSION(-1:10) :: Y
型と寸法が同じ配列変数は、まとめて宣言可能
REAL, DIMENSION(50) :: A, B, C
演習1 教科書P.62
例題4.1 フィボナッチ数列
例題4.1のプログラムをタイプし,実行せよ.
PROGRAM REIDAI4_1
IMPLICIT NONE
INTEGER, DIMENSION(0:10) :: A
INTEGER ::I
A(0) = 1
A(1) = 1
! a0=1
! a1=1
a0  1, a1  1
an 1  an  an 1 ( n  1)
DO I=1, 9 ! a2, a3, a4, ・・・, a10を計算,
A(I+1) = A(I) + A(I-1)
! ai+1 = ai + ai-1
END DO
配列変数の出力
DO I = 0, 10
WRITE(*,*) A(I)
END DO
WRITE(*,’(1X,11I5)’) (A(I), I = 0, 10) ! DO型ならび A(0), A(1), ・・・, A(10)と等価な記
述方法
STOP
END PROGRAM REIDAI4_1
配列変数の代入・参照方法1


添字番号を直接指定 (A(5),A(3)は普通の変数と同じ扱い)
A(5)=1.0
X = 3.0*A(3)
添字番号をDO文の制御変数で指定(繰り返し処理を併用)
DO I = 1, 5
READ(*,*) A(I)
A(I) = 1.0
B(I)=2.0*C(I)+D(J)
S = S + E(I)
この項は、繰り返し処理
の間、固定値となる
END DO
配列変数の代入・演算方法2

配列要素毎の一括代入・演算が可能
次回、再度説明する
INTEGER, DIMENSION(3)::A, B, D
INTEGER::C
! 配列変数へのスカラ定数,スカラ変数の代入が可能
A=1
⇒ A(1)=1, A(2)=1, A(3)=1 : 各要素に1を代入
A=C
⇒ A(1) = C, A(2)=C,
A(3)=C : 各要素にスカラ変数Cの値を代入
! 配列変数とスカラ定数.スカラ変数との四則演算および代入が可能
A=A+5
⇒ A(1) =A(1)+5, A(2)=A(2)+5, A(3)=A(3)+5 : 各要素に5を加える
A=3*A
⇒ A(1)=3*A(1), A(2)=3*A(2), A(3)=3*A(3) : 各要素を3倍にする
A=A/3
⇒ A(1)=A(1)/3, A(2)=A(2)/3, A(3)=A(3)/3 : 各要素を3で割る
! 同一寸法で宣言された配列間で,要素毎の代入・四則演算が可能
B = A ⇒ B(1)=A(1), B(2)=A(2), B(3)=A(3) : 行列Aの各要素を対応する行列Bの要素に代入
D=A+B ⇒ D(1)= A(1)+B(1), D(2)=A(2)+B(2), D(3) = A(3)+A(3)
D=A-B ⇒ D(1)= A(1)-B(1), D(2)=A(2)-B(2), D(3) = A(3)-B(3)
D=A*B ⇒ D(1)=A(1)*B(1), D(2) = A(2)*B(2), D(3) = A(3)*B(3)
D=A/B ⇒ D(1)=A(1)/B(1), D(2) = A(2)/B(2), D(3) = A(3)/B(3)
ただし、行列の掛け算と割り算は,行列の積と商(逆行列)の演算ルールとは違う.単に要素同士
の演算を行うだけ. また,スカラー変数への配列変数の代入 C = A は不可
DO型並びを用いた
配列データの入出力
DO型並びとは,DO~END DOの繰り返し処理表現を用いた
配列変数の並びの記述法のこと.データーの入出力で利用
例えば、A(1),A(2), ・・・,A(10)の10個の配列変数の並びをDO型並び
で記述すると (A(I), I = 1, 10) と非常に簡素に記述できる。
整数変数Iは、DO文の制御変数と同じで,始値,終値,増分の指定可.
DO型並びを用いた配列データの入出力例
DO I = 1, 10
READ(*,*) A(I)
END DO
→
READ(*,*) (A(I), I = 1, 10)
DO I = 1, 10
WRITE(*,*) A(I)
END DO
→
WRITE(*,*) (A(I), I = 1, 10)
配列変数への初期値の代入
教科書p.63

配列宣言文での初期値の指定
型名、DIMENSION(寸法)::配列名=(/初期値/)
初期値は、配列変数の寸法と同じ個数のデータをカンマ
で区切って並べる
例)
INTEGER , DIMENSION(12):: &
M = (/31,28,31,30,31,30,31,31,31,30,31,30,31/)
補足: 上の例の& は、次の行へのプログラムの継続を表す文字
配列要素の初期値が同じ場合、前に述べた一括代入文を使いた方が便利
演習2 合計値の計算


教科書p.54
例題3.3において、1案のアルゴリズムに基づき
配列変数を用いたプログラムを作成せよ.
ただし、配列変数の寸法は100で宣言し、データ
入力は、DO文を用いた繰り返し処理で行うこと.
program0616_2.f95, result0616_2.txt
合計値計算のアルゴリズム

1案
(1) データ個数Nを読み込む
(2) 以下の処理をi=1からNまで繰り返す
(2-1) i番目のデータをA(i)に読み込む
(3) 合計値変数Sを0で初期化する
(4) 以下の処理をi=1からNまで繰り返す
(4-1) 合計値変数SにA(i)を足しこむ
(5) 合計値Sを出力する

2案
(1) データ個数Nを読み込む
(2) 合計値変数Sを0で初期化する
(3) 以下の処理をi=1からNまで繰り返す
(3-1) i番目のデータをAに読み込む
(3-2) 合計値変数SにAを足しこむ
(4) 合計値Sを出力する
第1案は、最初にデータを配列変数にすべて読み込んだ後、合計値を算出
第2案は、データの読み込み直後に合計値を算出(読み込んだデータは後で使わない)
第2案では、入力データを合計値の算出後に利用できない(最後に入力されたデータのみ)
第1案では、すべての入力データは配列変数に残っているので利用できる
演習3 平均値と標準偏差
教科書p.64 例題4.3のプログラムをタイプして、実行せよ。
また、平均値,分散V (= 2),標準偏差の出力後,1か
らN番目までデータと平均値との差ai – の値を出力する
機能をプログラムに追加せよ.


実行は,N=5,{ai}={47.5, 56.2, 13.5, 37.6, 27.1}に対する結果
で確認.正しければ,平均値36.38,分散値225.5.標準偏差15.0が
出力される筈である.
program0616_3.f95, result0616_3.txt
POINT

入力データは,入力後も合計値、二乗偏差の計算で使用するため、配列
変数に代入すること.
演習3のアルゴリズム
(1)データ個数Nを読み込む
(2)i=1からNまで,以下の処理を繰り返す
(2-1) a(i)の値を読み込む
1 n
1 n
2
   ai ,  
(
a


)
 i
n i 1
n i 1
(3)データの合計値変数Sを0で初期化
(4) i=1からNまで,以下の処理を繰り返す
(4-1) Sにa(i)の値を足し込む
(5)データの平均値HEIKIN=S/Nを求める
(8)分散値BUNSAN=SS/Nを求める
(9)標準偏差SIGMA = BUNSAN1/2を求め
る
(10)平均値HEIKINを出力
(11)分散値BUNSANを出力
(12)標準偏差SIGMAを出力
(6)平均値からの二乗偏差の合計値変数
SSを0で初期化
(7) i=1からNまで,以下の処理を繰り返す
(7-1) SSに(a(i)-HEIKIN)2の値を足し
込む
ここに追加の機能の処理を入れる
今週の課題(Subject: report0616)
提出期限6月19日19時(再提出期限6/22 19時)
本日の演習課題2と3ソースプログラムをそれぞれ作成し,実行結果と伴に
送付せよ.
ただし,プログラム名,およびファイル名は,各課題で指示されているものを
使うこと.
注 意

メールの題名は,report0616とすること.