前回までの補足
「コメント書き」のススメ
既に2回生後期の「地球物理学実験」で習った通り、「!」のある行では、gfortran は 「!」以降を読み飛ばしてくれる。 これを利用して、Fortran のプログラムに (例えば) 「こういう式で求めればOK」とか「ここは○○を求めようとしているところ」などといった 注釈を入れる ことができる。 自分の作ったプログラムにはなるべく注釈をつけておくとよい。
ただし、(できるだけ) 注釈は「半角文字」だけを使って書く ようにしておくほうがよい。 注釈でないところに全角文字が残っていると gfortran に怒られてしまう。 特に 「全角スペース」の消し忘れ は気付きにくいので要注意。
変数の「型」と演算
前回 の演習では、平均を計算する際に出てくる「総和を整数 nensuuで割る」操作は /nensuu ではなく /real(nensuu) と書くほうが安全 だと説明した。 では、「安全でない」操作をするとどんな事故が起こり得るのだろうか。
例えば以下のプログラムでは、a の値と b の値が同じになるという保証はない し、同様に c の値と d の値が同じになるという保証もない。 実際に以下のプログラム (例えば kata.f90 などというファイル名にしておく) を入力・コンパイル・実行してみることにより、a から d の値がいくらになったかを調べてみよ。 またそうなった理由を考えてみよ。 なお、コンパイル・実行は
$ gfortran kata.f90とすればOK。 あるいは、「もうちょっと Linux に慣れてみたい」という気分になってきた人は、2年生後期の「地球物理学実験」の中でも出てきた内容を思い出して
$ ./a.out
$ gfortran -o kata.exe kata.f90としても同じ結果が得られる。 ちなみに出力は以下のようになるはずである。
$ ./kata.exe
3.00000000 3.50000000 3.00000000 3.50000000
program kata implicit none integer :: i1,i2 real :: a,b,c,d i1 = 7 i2 = 2 a = i1/i2 b = real(i1)/real(i2) c = 7/2 d = 7.0/2.0 write(*,*)a,b,c,d end program kata
上の例からも分かるように、代入文の右辺と左辺で現われる変数の「型」が一致していない と、予期しない計算結果が返ってくることもあり得る。 不測の事態を避けるためには、プログラムを書く本人が、変数の型を常に意識した上で計算式を書く ように心掛けるのが最も確実な方法である。
Fortran 90 の「配列処理」機能: 「便利さ」とその「罠」
前回 作成したプログラム中にもあるような、配列の中身 (の全て) を操作する命令は、Fortran 90 の機能を使うともっと簡略な書き方が可能である。 例えば、
12個の要素をもつ配列 kion_tsuki_souwa の中身を全て空っぽにしておくという操作は
の代わりにd o i = 1 , 1 2 k i o n _ t s u k i _ s o u w a ( i ) = 0 . 0 e n d d o
とかk i o n _ t s u k i _ s o u w a ( 1 : 1 2 ) = 0 . 0
あるいはもっと簡単にk i o n _ t s u k i _ s o u w a ( : ) = 0 . 0
と書ける。k i o n _ t s u k i _ s o u w a = 0 . 0 -
同様に、12個の要素をもつ配列 kion_tsuki_souwa に、同じく12個の要素をもつ配列 kion の中身をそれぞれ追加するという操作は
の代わりにd o i = 1 , 1 2 k i o n _ t s u k i _ s o u w a ( i ) = k i o n _ t s u k i _ s o u w a ( i ) + k i o n ( i ) e n d d o
とかk i o n _ t s u k i _ s o u w a ( 1 : 1 2 ) = k i o n _ t s u k i _ s o u w a ( 1 : 1 2 ) + k i o n ( 1 : 1 2 )
あるいはもっと簡単にk i o n _ t s u k i _ s o u w a ( : ) = k i o n _ t s u k i _ s o u w a ( : ) + k i o n ( : )
と書くこともできる。k i o n _ t s u k i _ s o u w a = k i o n _ t s u k i _ s o u w a + k i o n
以下、個人的な見解だが、あまりこのような 「手抜き」記法は乱発すべきではない と思う。 その理由は、こうした記法では 「配列のどの要素を操作しているか」が分かりにくくなる し、特に配列の名前だけしか書かない記法では 一見しただけでは配列か否かの見分けがつかない からである。 さらに 式中の各項に現われる配列の要素数が異なっているとエラーになる という面倒臭さもある。 そのため、こうした記法を使うのはごく限られた場合 (例えば配列の全ての要素にゼロを入れたい場合など) だけに留めるのがいいと思う。
さらにいえば、 (プログラミング以外でもそうだろうが) 便利なものほど、十分気をつけて使わないと危険 である。 過去にも実際、 この「配列処理」機能だと gfortran に (間違って) 解釈されてしまうという「罠」に捕まっている例が見られた。 その「罠」の「仕掛け」は、次に示す2つのプログラムの動作の違いから理解できる。 これら2つのプログラムをそれぞれコンパイル・実行した際の出力は異なるのだが、その理由を考えてみよ。
プログラムその0 | プログラムその1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1 1.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 2 1.0 2.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 3 1.0 2.0 3.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 4 1.0 2.0 3.0 4.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 5 1.0 2.0 3.0 4.0 5.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 6 1.0 2.0 3.0 4.0 5.0 6.0 0.0 0.0 0.0 0.0 0.0 0.0 7 1.0 2.0 3.0 4.0 5.0 6.0 7.0 0.0 0.0 0.0 0.0 0.0 8 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 0.0 0.0 0.0 0.0 9 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 0.0 0.0 0.0 10 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 0.0 0.0 11 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 0.0 12 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 |
1 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 2 2.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0 3 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.0 4 4.0 4.0 4.0 4.0 4.0 4.0 4.0 4.0 4.0 4.0 4.0 4.0 5 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.0 5.0 6 6.0 6.0 6.0 6.0 6.0 6.0 6.0 6.0 6.0 6.0 6.0 6.0 7 7.0 7.0 7.0 7.0 7.0 7.0 7.0 7.0 7.0 7.0 7.0 7.0 8 8.0 8.0 8.0 8.0 8.0 8.0 8.0 8.0 8.0 8.0 8.0 8.0 9 9.0 9.0 9.0 9.0 9.0 9.0 9.0 9.0 9.0 9.0 9.0 9.0 10 10.0 10.0 10.0 10.0 10.0 10.0 10.0 10.0 10.0 10.0 10.0 10.0 11 11.0 11.0 11.0 11.0 11.0 11.0 11.0 11.0 11.0 11.0 11.0 11.0 12 12.0 12.0 12.0 12.0 12.0 12.0 12.0 12.0 12.0 12.0 12.0 12.0 |
gfortranとうまくつき合うためのコツを少々、あるいは「デバッグ道」入門
(最近はプログラム以外についても使われているようだけど) プログラム中の誤りや欠陥を「バグ (bug; 成虫のこと)」といい、バグを除去する作業を「デバッグ (debug)」という。 どんなプログラミングでもだいたいそうなのだが、実際にタイピングしている時間は作業時間の3割くらいで、それ以外にあたる 作業時間の7割はデバッグに費される ものである。 言い換えれば、たとえ プロのプログラマであっても、一発で gfortran が通らないのが当たり前 なのである。
だから要するに gfortran に怒られたからといって嘆き悲しむ必要など全くない のだが、とはいっても gfortran にしょっちゅう怒られていると気分も滅入ってくるであろう。 例えば以下のような対策をとれば、gfortran とも (少しは) うまくつき合ってもらえるのではないか (と思う)。
- gfortran のメッセージに耳を傾けよう
gfortran が何やら言ってきたとしても、パニックに陥ることなく、まずは 冷静にエラーメッセージを読んでみる こと。 最初は「冷たい」とか「不親切」とかのように感じるであろうが、実はどう直せばいいか? のヒントをちゃんと教えてくれている。 例えば以下の例だと、
- まずは 18.25 に注目すべし。 ここでは 18行目にエラー があり、しかもそのエラーが 行の先頭から25文字目付近 にあることを教えてくれている。
- 次は 1 に注目すべし。 その上の行で示されている命令の、1で指されたところにエラーがある と教えてくれている。
enshu03a.f90:18.25: kion_nen_souwa = O.0 1 Error: Invalid character in name at (1)
ただしこの際にもう1つ大事なことは、最初のほうに出てきたメッセージから順に対応する ことである。 残念なことに、指示された行の中に間違いがないこともあるのだが、その原因の多くは gfortran が指摘しなかった (より正確には「正しいと仮定して先に進んだ」) 間違いが以前の行のどこかに含まれていることにある。 さらに、(変数を宣言する部分など) プログラムの最初のほうにある間違いを直せば、それだけで他のエラーも一気に解消されてしまうことだってある。
- こまめに保存して gfortran をかけてみよう
「合ってるのかどうか自信がない」場合には、全部の修正が終わる前でもいい ので、1箇所直したらその都度 gfortran をかける ことをおススメする。 これによって
- もしエラーが出なければ、「ここまでは合っている」 とか「さっきの間違いは直った」 とかが確認できるし、また
- 新たに書き足したらエラーが出てきたのならば、その 追加した箇所が原因でエラーが出た はずなのだから、エラーの隠れている場所があらかじめ絞り込める ことになる
- エディターは gedit ではなく emacs を使おう。
時々ぼそっと口走ったり、一部の人にはデモを見せたりして、地味めな布教活動をしているけれど、emacs のプログラミング支援機能 がバグの発見や予防に役立つこともある。 例えば Fortran モード の「お役立ち」機能の1つとして、入れ子になった do ループをきれいに「字下げ (インデント)」して整理 してくれたりもする。 こうした「お役立ち」機能のありがた味にハマると もう gedit なんて使う気にならなくなる (経験者談) し、実際に亀山がこの演習の資料を作る際にもかなり頻繁に使っている。 ついでに白状しておくと、この演習資料の中で Fortran の入力例には全て行の先頭に数個の「スペース」がついているが、それは emacs が自動でつけてくれた「字下げ」の分である。
Fortran 言語に限らず、プログラムのデバッグを進めるコツの1つは、コンパイラをうまく利用することである。 「gfortran にバグを見つけてもらう」 という心構え (開き直り? 割り切り?) ができたとすれば、この先の「デバッグ道」もスムーズに進めるはずだ。
さらに (ちょっと高度な話になるが)、gfortran が指摘できる程度のバグなんてのは、容易に発見できるので、恐ろしくも何ともない。 実は本当に恐ろしいのは、gfortran に見逃がされてしまうバグ であり、上で紹介した「配列処理」機能の「罠」はその例の1つである。 こうしたバグを見つけるには、もうちょっと別のコツがある (けど、紹介はまたの機会に)。
今日のテーマ: 平均・分散・標準偏差 (その3)
今日の目標は「1月〜12月までの各月の気温の平均・分散・標準偏差を求め、それを表示させる」こと。 前回 の演習にて、「1890年から2023年までの134年間 の、1月〜12月までの各月の気温の平均」を求めるプログラムの作成は終わっているはずだが、復習を兼ねて、プログラムの中身とその動作の確認を行ってみる。
前回に作ったプログラムの「みほん」
復習の便利のために、前回作成した「平均」を計算するプログラムの「みほん」を公開します (印刷したい人は PDF版 を)。 この「みほん」と自分の書いたプログラムを比較することにより、
- Fortran 90 プログラムの規則
- 「配列」とは
(詳しい説明は ここ を)
- いくつもの「変数」をまとめて作った1つの「かたまり」
- 配列の「要素」の参照のしかた (「番地」を指定する)
- do ループによる処理の繰り返し (詳しい説明は ここ を)
- if 文 (条件分岐) (詳しい説明は ここ とか ここ を)
- 「総和」のとり方、データの数え方
- 平均をとるための手順の「分解」
- 「平均」をとるには「データの総和」と「データの数」が必要
既にプログラムが正しく作成できている (はずの) 人も、念のため再び
$ gfortran enshu03b.f90などと実行し、過去134年分の各月の気温の平均の値が正しく求まっているかをもう一度確認すること。 正しく計算できていれば、プログラムの出力は以下のようになるはずである (最後の4行のみ示す)。
$ cat matsuyama-kion.txt | ./a.out
2021 6.2 8.9 12.7 15.5 19.5 23.4 27.2 27.5 25.0 20.1 13.7 8.8 17.4 51.21 7.16 2022 5.9 5.2 11.9 15.9 19.3 24.1 27.8 29.1 26.2 19.2 15.5 7.4 17.3 65.94 8.12 2023 6.5 7.6 12.7 15.9 19.8 23.1 28.0 28.9 27.3 19.4 14.8 9.3 17.8 57.90 7.61 134 5.26 5.59 8.64 13.72 17.97 21.91 26.24 27.05 23.48 17.69 12.51 7.68
平均のほかに分散と標準偏差も求める
次はいよいよ、分散と標準偏差も計算する機能を追加してみよう。 上で作ったプログラム enshu03b.f90 の 適切な場所に、以下に示す「部品」をうまく追加する ことで目的のプログラム enshu03c.f90 が完成するようになっている。 ただし、どこに追加するのが適切かは 各自で考える こと。
新たに追加すべき重要な機能は、各月の気温の2乗の平均値を計算する ことと、分散の平方根をとって標準偏差を計算する ことだけ。 そのための機能は、例えばそれぞれ以下のようになるはずだ。
分散・標準偏差、およびそれらを計算するために必要な値を入れる器を用意する。
r e a l , d i m e n s i o n ( 1 2 ) : : k i o n _ t s u k i _ b u n s a n , k i o n _ t s u k i _ h e n s a r e a l , d i m e n s i o n ( 1 2 ) : : k i o n 2 _ t s u k i _ h e i k i n , k i o n 2 _ t s u k i _ s o u w a 各月の気温の2乗の総和を計算する。 ここでも同様に、do ループ内でデータを読み込むたびに容器の中に足し込んでいけばよい。 その手順は例えば
からk i o n 2 _ t s u k i _ s o u w a ( 1 ) = k i o n 2 _ t s u k i _ s o u w a ( 1 ) + k i o n ( 1 ) * * 2
などと書くことができる。 ここで、「**2」は2乗することを表す記法である。k i o n 2 _ t s u k i _ s o u w a ( 1 2 ) = k i o n 2 _ t s u k i _ s o u w a ( 1 2 ) + k i o n ( 1 2 ) * * 2 ただし、まさかこの期に及んで 12個の式を延々と書き並べるなんてことはしない ように。 また、上の手順に入る 前の適切な場所で、
からk i o n 2 _ t s u k i _ s o u w a ( 1 ) = 0 . 0
に相当する操作を実行することにより、kion2_tsuki_souwaという器の中身を全て空っぽにしておく のも忘れないように。k i o n 2 _ t s u k i _ s o u w a ( 1 2 ) = 0 . 0 -
各月の気温の分散・標準偏差を計算し、表示させる。 講義のノートを参考にして、分散・標準偏差を計算する式を正しく書き入れよ。 なお、sqrt は平方根をとるための組み込み関数である。 組み込み関数の他の例は ここ などを参照のこと。
以下では特に分散の計算式をわざと「抜いて」いるので、各自で考えて正しい計算式を埋めてもらう必要がある。 その際、「○月の分散」の計算に必要になる「○月の平均」や「○月の2乗の平均」はどの器のどこに入っているのか? をよく考えること。
d o i = 1 , 1 2 k i o n _ t s u k i _ h e i k i n ( i ) = k i o n _ t s u k i _ s o u w a ( i ) / r e a l ( n e n s u u ) k i o n 2 _ t s u k i _ h e i k i n ( i ) = k i o n 2 _ t s u k i _ s o u w a ( i ) / r e a l ( n e n s u u ) k i o n _ t s u k i _ b u n s a n ( i ) = k i o n _ t s u k i _ h e n s a ( i ) = s q r t ( k i o n _ t s u k i _ b u n s a n ( i ) ) e n d d o w r i t e ( * , ' ( i 4 , 1 2 f 6 . 2 ) ' ) n e n s u u , k i o n _ t s u k i _ h e i k i n w r i t e ( * , ' ( i 4 , 1 2 f 6 . 2 ) ' ) n e n s u u , k i o n _ t s u k i _ b u n s a n w r i t e ( * , ' ( i 4 , 1 2 f 6 . 2 ) ' ) n e n s u u , k i o n _ t s u k i _ h e n s a
気温の平均値を計算する際に追加した機能を思い出し、各月の気温の分散や標準偏差を計算する命令がどう書けるかを考えよ。 そして、その命令を追加したプログラムを作成せよ [みほん]。 またもちろん、自分の作ったプログラムが (平均+) 分散・標準偏差を正しく計算できているかを (少なくとも「手抜き」版で) 確認せよ。 なおプログラムに間違いがなかったら、
$ tail -n 3 matsuyama-kion.txt | ./a.outとして、過去3年分のデータだけを処理した場合、出力は以下のようになるはずである。
2021 6.2 8.9 12.7 15.5 19.5 23.4 27.2 27.5 25.0 20.1 13.7 8.8 17.4 51.21 7.16 2022 5.9 5.2 11.9 15.9 19.3 24.1 27.8 29.1 26.2 19.2 15.5 7.4 17.3 65.94 8.12 2023 6.5 7.6 12.7 15.9 19.8 23.1 28.0 28.9 27.3 19.4 14.8 9.3 17.8 57.90 7.61 3 6.20 7.23 12.43 15.77 19.53 23.53 27.67 28.50 26.17 19.57 14.67 8.50 3 0.06 2.35 0.14 0.04 0.04 0.18 0.12 0.51 0.88 0.15 0.55 0.65 3 0.24 1.53 0.38 0.19 0.21 0.42 0.34 0.71 0.94 0.39 0.74 0.80
最後に、matsuyama-kion.txt に含まれている全てのデータ (1890年から2023年までの各月の平均気温) を読み込ませ、この期間の各月の平均気温、及びその分散と標準偏差を計算せよ。 標準偏差の最も大きい (平均気温のばらつきが最大) のは何月か。 また最も小さいのは何月か。
なお、正しく計算できていれば、プログラムの出力 (の最後の3行) は以下のようになるはずである。
134 5.26 5.59 8.64 13.72 17.97 21.91 26.24 27.05 23.48 17.69 12.51 7.68 134 1.51 2.10 2.00 1.52 1.33 0.98 1.37 1.09 1.74 1.53 1.60 1.53 134 1.23 1.45 1.42 1.23 1.15 0.99 1.17 1.04 1.32 1.24 1.27 1.24正しく動いていることが確認できたら、本日の演習の出席確認のため、このプログラムを 末尾のフォーム 経由で提出せよ。
簡単なグラフを描く
前回にも少しやった通り、Linux 上で動く簡単なグラフ化ツールである Gnuplot を使って、計算で求まった「平均」や「標準偏差」の意味をグラフで確認してみよう。
まずは端末で以下のように入力してみよう ($ は端末のコマンドプロンプト)。
$ gnuplotすると Gnuplot の入力画面に入る。 そこで
gnuplot> plot "matsuyama-kion.txt" using 1:5 with lines, 13.72とし、表示されたグラフの意味を考えてみよ。 その際、各年の4月の気温を表す折れ線グラフと、その平均値を表すグラフの位置関係に注目せよ。 また同様の作業を1月から12月までの全ての月についても行い、「平均値」のもつ意味を確認せよ。 また、自分で計算して得られた4月の気温の標準偏差 (答は 1.23 になるはず) の値を用いて
gnuplot> plot "matsuyama-kion.txt" using 1:5, 13.72, 13.72+1.23, 13.72-1.23(この図は折れ線グラフで描かないほうが見やすい) とし、「標準偏差」のもつ意味を確認せよ。 さらに、
gnuplot> plot "matsuyama-kion.txt" using 1:5, 13.72, 13.72+1.23*2, 13.72-1.23*2や
gnuplot> plot "matsuyama-kion.txt" using 1:5, 13.72, 13.72+1.23*3, 13.72-1.23*3として得られるグラフと先のグラフを比較し、違いを考えてみよ。
出席確認用プログラム提出フォーム
Moodle のコースページ 以下の 課題ファイル提出 により、各自で作成した (enshu03c.f90 に相当する) 過去134年間の各月の気温の平均・分散・標準偏差を計算する Fortran 90 プログラムの最終版を提出せよ。