平成 29 年度 情報基礎演習 Ⅰ 第 8 回演習 担当光武雄一 授業の Website: http://web.me.saga-u.ac.jp/~mitutake/info1/info1.html メールアドレス : mitutake@me.saga-u.ac.jp
第 8 回目演習内容 先週の課題解答と説明 合計値の計算法 マクローリン級数の計算 (57 ページ )
Report0523 の解答例 PROGRAM REPORT0523! プログラムの開始 ( 必須 ) IMPLICIT NONE! 暗黙の型宣言を無効 ( 必須 ) REAL :: X, FX! 実数型変数宣言 (X: 独立変数,FX:X**Xの関数値) INTEGER :: I! 整数型変数宣言 (DO 文の制御変数 I) WRITE(*, (1X, A3,A9) ) X, X**X! 数表の見出しの出力 ( 文字型 3カラムと9カラム ) DO I = 0, 10! 制御変数 Iの始値 0, 終値 10, 増分 1( 省略可 ) X = 0.1*REAL(I)! Xの値を増分 0.1で変化させる ( 実数演算 ) FX = X**X! X**Xの計算 ( 実数演算 ) WRITE(*, (1X, F3.1, F9.6) ) X, FX! 結果を書式制御出力 ( 表示桁はそれぞれ3 桁と9 桁 ) END DO! DO 文による繰り返し処理の終端 STOP! プログラムの停止 ( 必須 ) END PROGRAM REPORT0523! プログラムの終了 ( 必須 ) 実数の有効桁が 7 桁しかないので, 固定小数点の書式制御 (F9.6) で小数の桁数を 6 以上にしても意味が無い. 逆に 3,4 桁と少ないのも NG 表示桁の間の空白を調節するには,X 編集記述子を用いるか,Fn.m での実数表示桁数 n を大きくする.
Report0523 不正解の 1 例 実数計算式中に, 整数型変数と整数型定数 NG 例 X = REAL(I)/10 X = I/10.0 数表の出力が不正 何の数値か分かるように, 表には適切な見出しをつける. 有効桁数にあわせた適切な書式出力 書式制御の編集記述子の使い方 NG 例 WRITE(*, (F3.1, F9.6) ) X, FX 先頭は1Xをつける. WRITE (*, (1X, 3F9.6) ) X, FX 変数の数とF9.6の数が不一致 WRITE (*, (1X, 2F8.6) ) X, FX 表示桁数不足. 数値が連続出力 変数名の付け方 なるべく問題で与えられた変数名に合わせて宣言 DO 文の制御変数は, 原則 I,J,K,L,M,N で始まる文字を使用する ( 慣習 )
書式付き出力 (P.37~39) 編集記述子 ( 各編集記述子の文字列は, カンマ, で区切る ) nx n 文字進める ( 指定した数だけスペースを入れるときに使う ) In 整数型変数を ±**** の形式で表示. 負号を含め全部でn 桁 Fn.m 実数型変数を ±**.****** の固定小数点形式で表示小数点, 負号を含め表示が全 n 桁, 小数点以下 m 桁 En.m 実数型変数を ±**.*****E±** の指数部付き形式で表示負号, 小数点, 指数部 (4 桁 ) を含め表示が全 n 桁, 小数点以下 m 桁 Gn.m 実数型変数をF 型とE 型のいずれか自動選択して表示 An 文字型変数をn 文字 ***** の形式で表示. 反復指定 kfn.m 編集記述子 (Fn.m ) の書式指定をk 回続ける ( Fn.m, Fn.m,, Fn.m と同じ ) 行送り制御 書式制御文字列の最初の1 字は, 行送り制御コードと解釈 (Fortranの処理系によって違う) 空白 : シングルスペース ( 一行改行後出力 ) 書式付きWRITE 文の一例 0: ダブルスペース ( 二行改行後出力 ) 1: 改ページして一行目より出力 WRITE(*, (1X, I3, 3F9.6) ) DEG, S, C, T 最初の 1X は, 改行して新しい行から表示 WRITE(*, '(1X, 2F15.7) ) X1, X2 WRITE(*, (1X, I4, 3E15.7) ) I, X, Y, Z
DO ループの書式 繰り返し計算は DO 文を用いる DO 制御変数名 = 始値, 終値, 増分繰り返し処理の実行プログラム END DO 注 ) 増分が 1 の場合, 増分の指定は省略可 プログラム例 繰り返し処理のフローチャート 制御変数に始値を代入 制御変数 終値 Yes 繰り返す処理内容 制御変数に増分を加算 No N の値を 10 から 100 まで 10 おきに変化させ N と N の二乗の値を表示させる DO N = 10, 100, 10 WRITE(*,*) N, N*N END DO 補足処理を繰り返す毎に変数の数値を変えながら計算を実行したい場合 処理毎に変化させたい数値を制御変数の値を用いた計算式で与える
演習 1 合計の計算法 ( 教科書 p.54) N 個のデータの合計値を求めるためのアルゴリズム 合計値の計算を行うにあたり,a 1,a 2,,a N までの N 個のデータの入力方法として, 以下の 2 つが考えられる. 1) 最初にN 個のデータを全て読み込んだ後, 合計値の計算を行う. 4 章で学ぶ配列変数を用いる 2) データを読み込みながら合計値を計算する. 今日の演習では, この方式を用いる. 何故, 合計値の計算を繰り返し処理で行う必要があるのか データの個数とデータの値が与えられている場合, 数式による合計値の記述も可能しかし, データ個数が多くなると数式による足し算の記述は殆ど不可能さらに, 任意のデータ個数に対する合計値を数式で記述できない.
フローチャートの記号 p.92 端子 フローチャートの始まり及び終わりを表す サブルーチンサブルーチン ( モジュール ) 処理 計算 代入などの処理を表す 書類 印刷する 判断 条件によって分岐する 入出力 ファイルへの入出力 ループ 繰り返しの始まりと終わり 結合子 ページ内の結合 結合子 ページ外の結合 入力 キーボードからの入力 表示 ディスプレイへの表示
アルゴリズムの書き方 アルゴリズムは, 基本制御構造 1) ブロック構造,2) 条件判断,3) 繰り返し,4) サブルーチンを用いて記述する. ブロック構造 順番に実行される処理の系列を記述 例 ) (1) 処理 1 (1) 変数 xの値をキーボードより入力する. (2) 処理 2 (2) 変数 yにsin(x) を代入する : : (3) 画面に変数 yの値を出力する. (n) 処理 n 条件判定や繰り返し処理の記述 ( 以下の記述で i は, 任意の順番を示す ) 例 ) (i) 選択条件 (or 繰り返し条件 ) (i) 以下の処理を 回繰り返す (i-1) 処理 1 (i-1) 変数 aの値を読み込む (i-2) 処理 2 (i-2) 合計値変数 Sにaを足し込む : : (i-n) 処理 n なお,2)~4) の記述方法については, 教科書第 5 章において説明する. アルゴリズムで記述された処理内容は,1 行のFORTRANのプログラムで記述できなければ ならない. 本演習では, フローチャートの代わりのブロック構造のアルゴリズム記述法を用いる.
N 個のデータの合計値を求める ためのアルゴリズム N 個のデータ a 1,a 2,a 3,,a N の合計 S=Σa i を求める (1) 合計値の部分和を格納する変数 S に 0.0 を代入 ( 初期化 ) する. ( 重要 ) S に 0.0 以外の数値が入っている場合には, 合計値を正しく求めることができないので必須の処理. (2) i=1~n 番目まで以下の処理を繰り返す. (2-1) i 番目のデータ a i を読み込む (2-2) S に a i を加える. この処理に繰り返し計算を用いる i 番目の処理 S = S + a i (3) 部分和の変数 S の値を出力する全てのデータを加算し終えたときの S の値が, 求める合計値となる. 注 ) 処理内容が複雑になると, プログラムでの実行手順を詳しく書き下したアルゴリズムが必要となる. アルゴリズム無しにプログラム作成しても正しいプログラムを書くことは困難. 合計値を求める処理のフローチャート 合計変数に 0.0 を代入 制御変数に始値を代入 制御変数 終値 Yes i 番目のデータ a を読み込む 制御変数に増分を加算 No 合計値に a を足す S=S+a 変数 S には総和の値 おわり
演習 1 例題 3.3 N 個のデータの合計 PROGRAM REIDAI3_3 IMPLICIT NONE INTEGER :: I, N REAL :: A, S WRITE(*,*) N =! 整数変数 I,Nの宣言! 実数変数 A,Sの宣言 READ(*,*) N! 合計を求めるデータ個数 Nの入力 S = 0.0! 合計値を格納する変数 Sの初期化 ( 必須の処理 ) DO I = 1, N! 繰り返し計算の始まり (I = 1,2,3, N) WRITE(*,*) A = READ(*,*) A! I 番目のデータAを入力 S = S + A! Sの値にAを加算して,Sに格納する( 代入文 ) END DO! 繰り返し計算の終端 WRITE(*,*) S =, S! 合計値 Sの表示 STOP END PROGRAM REIDAI3_3 プログラムの実行が確認できたら, N 個のデータの平均値を出力するよう修正せよ
解説例題 3.3 合計値の計算 テキスト P.55 の例題 3.3 のプログラム. ( 注目すべき点 ) DO~END DO で挟まれる処理内容 合計値を格納する変数 S の初期化とその実行位置 部分和を計算する式の位置. 結果を表示する WRITE 文の位置 プログラム処理の実行の順番が非常に重要. プログラムの実行順番が不適切だと, 所望した処理結果は得られない
演習 2 合計値と平方和の計算 教科書 p.54 例題 3.3 の変形問題 例題 3.3 のプログラムを修正して,N 個の実数データに対して実数データの合計値と実数データの平方和 ( 例題 3.3 の追加部分 ) を同時に求めるプログラムを作れ. ただし,N 個のデータは 1 回だけ入力させること. プログラム名は,reidai3_3a としなさい. ヒント それぞれの合計値を格納するための部分和変数を 2 つ用意する
演習 2 解答例 PROGRAM PROBLEM3_3A IMPLICIT NONE INTEGER :: I, N! 整数型変数制御変数 I, データ個数 Nの宣言 REAL :: S1,S2,A! 実数型変数部分和変数 S1, S2, データ変数 Aの宣言 WRITE(*,*) N =! 入力メッセージ N = の出力 READ(*,*) N! 合計を求めるデータ個数 Nの入力 S1 = 0.0! 合計値を格納する変数 S1の初期化 S2 = 0.0! 合計値を格納する変数 S2の初期化 DO I = 1, N! 繰り返し計算の始まり (I = 1,2,3, N) WRITE(*,*) A(, I, ) = READ(*,*) A! I 番目のデータAを入力 S1 = S1 + A! S1の値に A を加算して,S1に格納する S2 = S2 + A*A! S2の値に A 2 を加算して,S2に格納する END DO! 繰り返し計算の終端 WRITE(*,*) 合計値 =, S1! 合計値 S1の表示 WRITE(*,*) 二乗和 =, S2! 二乗和 S2の表示 STOP END PROGRAM REIDAI3_3A
演習 3 指数関数のマクローリン展開級数の計算 教科書 p.57 例題 3.5のプログラムをタイプして, 実行プログラムを作成し,N=7 に対する結果を求めよ. さらに, 結果の出力部分に, この無限級数の厳密解である EXP(1.0) の値との差 ( 誤差 ) を追加表示させよ. プログラム名, ソースファイル名は,reidai3_5, reidai3_5.f95とする. ポイント : 級数の一般項の計算と合計値の計算 任意の整数 Iに対する階乗 I! = 1 2 3 (I-1) I の計算は, 一つの計算式では記述できない.( 階乗を計算するFortranの組込関数がない ) つまり, 一行の計算式 ( 代入文 ) で級数の一般項 ai を記述できない. そこで, 第 I 項の一般項 a i を, 漸化式の要領で初項より順番に求める. a i-1 の値が既知のとき,a i の値は,a i-1 に何を掛けたら求まるか考えよ. DO 文を使って,a i の計算をI = 1からNまで繰り返しながら,a i を合計値変数 Sに足し込む計算を繰り返すと第 n 項までの部分和が計算できる. 繰り返し計算前に初期化を行う変数とその初期値に注意.
e x のマクローリン級数展開式の計 算 (x=1) アルゴリズム ( 計算手順 ) (1) 級数の項数 Nの入力 (2) 級数の項 a 0 の値に1を設定する (a 0 =1) (3) 級数の部分和 S 0 に1(=a 0 ) を設定する (4) 以下の処理をi=1~Nまで繰り返す. (4-1) 級数の第 i 項 a i = a i 1 / i で求める. (4-2) 第 i 項までの部分和 S i =S i-1 + a i を求める. (5) 第 n 項までの級数の和 S n を出力する. ここが, 繰り返し処理の内容
解説例題 3.5 級数の和の計算整数 n を入力して,e =1+1/1!+1/2!+1/3!+ = Σa i (a i = 1/ i!) を計算 PROGRAM REIDAI3_5 IMPLICIT NONE INTEGER :: I,N! DO 文の制御変数は, 整数型 REAL :: A, S WRITE(*,*) N = READ(*,*) N! 級数の項数 Nを入力 A = 1.0! 級数の項 a i の初期値 (a 0 =1)( 初項の値を設定 ) S = 1.0! 級数の部分和 Sの初期値 (S = a 0 =1)( 合計変数の初期化 ) DO I = 1, N A = A / REAL(I)! 第 i 番目の項 a i = a i-1 / i の計算 S = S + A! 第 i 項までの部分和の計算 END DO WRITE(*,*) 第 N 項までの和は,, S STOP END PROGRAM REIDAI3_5 実行結果が得られたら, 厳密解 EXP(1.0) との差 ( 誤差 ) を追加で出力するようにプログラムを修正しなさい. N の値によって誤差が変化するか確かめよう. 解説階乗計算が含まれる第 i 番目の項 a i =1 / i! は, a i ー 1 の値を格納する変数 A を用いて, 第 i 1 番目の項 a i-1 を i で割って求めている. このように, 階乗を含む級数の計算では, 漸化式の形式で, 級数の項の計算を行うのが定石. 一度に 1 から I までの掛け算は実行できない.
演習課題 4 ( 級数の和の計算 ) 指数関数 e x のマクローリン級数 教科書 P.57の例題 3.5プログラムを修正して, 実数 Xの値と級数の最大項番 N( 整数型 ) の値を入力して, 第 N 項までのe x のマクローリン級数の部分和を計算し, 級数とその厳密解 EXP(X) との誤差を出力させよ. N i x x e i 0 i! ただし, プログラム名, ソースファイル名は,reidai3_5a, reidai3_5a.f95, 実行結果はreidai3_5a.txtとすること. 実行結果は,N=7,X=0.5および1.5で確認し, 誤差を比較せよ. 誤差が大きいときは, 漸化式に誤りがあるか, 級数の収束が悪いため,Nの数を増やす.
e x のマクローリン級数展開式の計 算アルゴリズム (1) 級数の項数 Nの入力 e (2) 実数 Xの入力 ( 追加部分 ) i! i 0 (2) 級数の項 a 0 の値に1を設定する (a 0 =1) (3) 級数の部分和 S 0 に1(=a 0 ) を設定する (4) 以下の処理をi=1~Nまで繰り返す. (4-1) 級数の第 i 項 a i =????? で求める.( 漸化式?) (4-2) 第 i 項までの部分和 S i =S i-1 + a i を求める. (5) 第 N 項までの級数の和 S n と厳密解 EXP(X) との誤差を出力する. x N x i
演習課題 5 教科書問 5 教科書 p.57 問 5のプログラムのアルゴリズムを作成せよ. そのアルゴリズムに基づきソースプログラムを作成し,N=7 X=0.5 radに対する実行結果を求めよ. 入力 出力のメッセージは必須さらに, 結果の出力部分において, この無限級数の厳密解である COS(X) の値との差 ( 誤差 ) を表示させよ. プログラム名は report0530 ソースファイル名 report0530.f95, プログラム実行結果は result0530.txt とする. cos( x) ポイント :COS(X) のマクローリン級数展開の計算 i 0 (2i)! 級数の和の計算手順は 例題 3.5と同じ 級数の項に含まれる階乗 (2I)! = 1 2 3 (2I-1) 2I の計算は, 一行の計算式で記述できない. 級数の第 I 項 a i と第 I-1 項 a i-1 の間の関係式 ( 漸化式 ) がどのように与えられるか考えよ. 実際に手計算で式を変形しないと分からない! 漸化式が決まれば 初項 I=0の値を与えてDO 文を用いてI=1からNまで繰り返し処理により第 N 項まで級数の項を求めることができる. 計算プログラムが正しいかどうかは, 出力される誤差を見ればすぐ分かる N ( 1) i x 2i
今週の課題 REPORT0530 〆切 6 月 5 日 19 時メール送付先 :mitutake@me.saga-u.ac.jp 課題 1 評点 3 演習課題 4 のプログラムを作成し, 実行結果と伴にソースファイルを送付せよ. ファイル名, プログラム名については, 課題の指示に従うこと. 課題 2 評点 2 演習課題 5の計算アルゴリズムをブロック構造の記述法を用いてメール本文に記述せよ.( 演習 3,4でのアルゴリズム記述例を参考にすること ) 課題 3 評点 5 演習課題 5のプログラムを作成し, 実行結果と伴にソースファイルを送付せよ. プログラム名, ファイル名は, 課題の指示に従うこと. 誤差が大きい (>10-5 ) 場合は, 漸化式が間違っている. 送付の前に式の確認を手計算を行い修正すること.