情報地球科学演習 (2024年前学期) 第03回

前回までの補足

「実行文」と「非実行文」

Fortran プログラムにおける「文」は、「実行文」と「非実行文」の2つに大別される。

実行文
プログラムの実行手順を詳しく記述する文のこと。 計算結果を代入したり、データの読み書きをしたりする文がその例。
非実行文
プログラムの実行時に必要な情報を記述する文のこと。 変数の名前や型を宣言したり、プログラムの名前を宣言したりする文がその例。

非実行文に関して特に注意すべき規則として、変数を宣言する文は最初の実行文より前に記述しておかなければならない ことを覚えておこう。 これが守られていないと、コンパイル時にエラーになる (gfortran に怒られる)。

計算の流れを制御するしくみ

この演習の最初に作ったプログラム を例にとって説明すると、

ここで使った do ループは「汎用 do ループ」などと呼ばれ、ループを繰り返す回数があらかじめ分かっていない ような場合に用いられる。

今日のテーマ: 平均・分散・標準偏差 (その2)

今日 (とその次の回) の目標は「1890年から2023年までの134年間 の、1月〜12月までの各月の気温の平均・分散・標準偏差 を求め、それを表示させる」こと。

今回の課題にとり組むにあたり、必要な手順は

  1. 各月の気温の総和を求める (ただし分散・標準偏差を出すときには気温の2乗の総和もいる)
  2. 何年分のデータを読み込んだかを数える
  3. 平均・分散・標準偏差を求める
である。

とはいえ、(過去数年間の演習でもそうだったのだが) 12ヶ月分を一気に計算するプログラムをいきなり作ると混乱するであろうから、まずはある月の気温の平均値だけに注目したプログラムを作ってみることから始めよう。

準備: 4月の気温の平均値を求める

手始めに、4月の気温の過去134年間の平均を計算するプログラムを作成してみよう。 このプログラムのミソは以下の通り。

program enshu03a                                                
implicitnone
integer::seireki,joutai
real,dimension(12)::kion
real::kion_nen_heikin,kion_nen_souwa
real::kion_nen_bunsan,kion_nen_hensa
real::kion2_nen_souwa,kion2_nen_heikin
real::kion04_heikin,kion04_souwa
integer::i
integer::nensuu
kion04_souwa=0.0
nensuu=0
do
read(*,'(i4,12f5.1)',iostat=joutai)seireki,kion
if(joutai/=0)exit
nensuu=nensuu+1
kion04_souwa=kion04_souwa+kion(4)
kion_nen_souwa=0.0
kion2_nen_souwa=0.0
doi=1,12
kion_nen_souwa=kion_nen_souwa+kion(i)
kion2_nen_souwa=kion2_nen_souwa+kion(i)**2
enddo
kion_nen_heikin=kion_nen_souwa/12.0
kion2_nen_heikin=kion2_nen_souwa/12.0
kion_nen_bunsan=kion2_nen_heikin-kion_nen_heikin**2
kion_nen_hensa=sqrt(kion_nen_bunsan)
write(*,'(i4,13f6.1,2f6.2)')seireki,kion,kion_nen_heikin&
,kion_nen_bunsan,kion_nen_hensa
enddo
kion04_heikin=kion04_souwa/real(nensuu)
write(*,'(i4,12f6.2)')nensuu,kion04_heikin
endprogramenshu03a

前回作ったプログラム (enshu02b.f90 または enshu02c.f90) を出発点にして、上のプログラムを (例えば enshu03a.f90 という名前で) 作成せよ。 入力ができたら、例の如く

$ gfortran enshu03a.f90
$ cat matsuyama-kion.txt | ./a.out
と実行してみよ。 プログラムに間違いがなかったら、端末には以下のように出力されているはずだ (最後の4行分のみ示す)。
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 13.72

各月の気温の平均値を一気に求める

次はいよいよ、12ヶ月分を一気に計算するプログラムを作ってみよう。 上で作ったプログラム enshu03a.f90適切な場所に、以下に示す「部品」をうまく追加する ことで目的のプログラム enshu03b.f90 が完成するようになっている。 ただし、どこに追加するのが適切かは 各自で考える こと。 なお置き場所の正解は一通りではない。 プログラミングにはよくあることなのだが、(極端にいうと) プログラムが正しく動きさえすれば何でも OK なのである。

必要な手順 (の要点だけ) を以下に示す。

これらを参考にして、各月の気温の平均を計算する命令がどう書けるかを考えよ。 そして、今日の最初に作ったプログラム enshu03a.f90 にその機能を追加せよ [みほん]。 なお「完成までの途中経過」あるいは「悪い見本」として、

載せておく。

なお、正しく計算できていれば、プログラムの出力は以下のようになるはずである。

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
正しく動いていることが確認できたら、本日の演習の出席確認のため、このプログラムを 末尾のフォーム 経由で提出せよ。

動作確認「手抜き」版

ここでももちろん、自分の作ったプログラムが平均気温を正しく計算できているかを確認するのが大事だが、「134個のデータの平均値を電卓で計算する」なんてことはさすがにやる気にならない。 そこで、Linux の別のコマンドを少々使って、「手抜き」した動作確認をしてみよう。

そのための準備として、以下のようにしてみよう ($ はコマンドプロンプト)。

$ tail matsuyama-kion.txt
これにより、最近10年間のデータだけ (より正確には、「matsuyama-kion.txt の最後の10行だけ」) が表示されるはずだ。 この tail とは、「そのファイルの最後の10行だけを表示せよ」という Linux のコマンドである。 詳しくは Linux の教科書や
$ man tail
として表示されるオンラインマニュアルを参照のこと。 また tail コマンドをうまく使ってやると、「最後の10行だけを表示」する代わりに、例えば「最後の3行だけを表示」させることも可能である。 tail コマンドのオンラインマニュアルを読み、そのための方法を考えてみよ。

では、いよいよ自分の作ったプログラムが正しく動いているかを確認しよう。

$ tail -n 3 matsuyama-kion.txt | ./a.out
とすると、最近の3年間だけのデータを読み込んで計算させることができる。 この出力をもとに、自分の作ったプログラムが正しく平均値を計算できているかを確認せよ。

なお、最近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

ちなみに、tail とよく似た Linux コマンドで、「そのファイルの先頭の n 行だけを表示せよ」というコマンド head もある。 このコマンドを使って、「1890年から3年間の平均気温」も計算させてみよ。

余力のある人向けのおまけ: Fortran 90 の「配列処理」機能をとことん使った「手抜き」

上のプログラム中にもあるような、配列の中身全てを操作する命令は、Fortran 90 の機能を使えば もっと簡略な書き方が可能 である。 例えば、

これらを応用して、先に作ったプログラムを書き直し、配列処理機能をできる限り使って記法を省略したプログラムを作ってみよ [みほん]。 この機能は古い規格の Fortran (Fortran 77 とか) ではそもそも用いることができなかったものである。

以下、個人的な見解だが、あまりこのような 「手抜き」記法は乱発すべきではない と思う。 その理由は、こうした記法では 「配列のどの要素を操作しているか」が分かりにくくなる し、特に配列の名前だけしか書かない記法では 一見しただけでは配列か否かの見分けがつかない からである。 さらに 式中の各項に現われる配列の要素数が異なっているとエラーになる という面倒臭さもある。 そのため、こうした記法を使うのはごく限られた場合 (例えば配列の全ての要素にゼロを入れたい場合など) だけに留めるのがいいと思う。

簡単なグラフを描く

前回にも少しやった通り、Linux 上で動く簡単なグラフ化ツールである Gnuplot を使って、計算で求まった「平均」の意味をグラフで確認してみよう。

まずは端末で以下のように入力してみよう ($ は端末のコマンドプロンプト)。

$ gnuplot
すると Gnuplot の入力画面に入る。 そこで
gnuplot> plot "matsuyama-kion.txt" using 1:5 with lines, 13.72
とし、表示されたグラフの意味を考えてみよ。 その際、各年の4月の気温を表す折れ線グラフと、その平均値を表すグラフの位置関係に注目せよ。 また同様の作業を1月から12月までの全ての月についても行い、「平均値」のもつ意味を確認せよ。

出席確認用プログラム提出フォーム

Moodle のコースページ 以下の 課題ファイル提出 により、各自で作成した (enshu03b.f90 に相当する) 過去134年間の各月の平均気温を計算する Fortran 90 プログラムの最終版を提出せよ。