Comments
Description
Transcript
FORTRANプログラミング 謔R回の演習 - ax
木村拓馬 FORTRAN プログラミング –第3回の演習– 木村拓馬 2014 年 10 月 15 日 09:28 FORTRAN プログラミング,–第3回の演習– ( 2014 年 10 月 15 日 09:28 ) 1/12 . 演習 3.1(pr3.1.f90) . 演習 1.2(第一回講義)のプログラム(pr1.2.f90)を, 木村拓馬 n をキーボードから入力(1000 より大きくてもOK) 配列の動的割付け(allocate)を用いる ように書き換えなさい(自分で作った方は自作のを,作ってない方は . . 演習 1.2(pr1.2.f90) .. Download .. Download .. Download .. Download . .. Download を書き換え) n を 3 以上 1000 以下の整数定数とする(n は READ しなくてよい,PARAMETER は OK). 7 つの実数 a, b, c, d, e, f, g が与えられたとき, 1. 以下の n × n 三重対角行列 M を2次元配列に記憶させ(空白は零), a c M = b d .. . e .. .. . .. . . .. . c .. . d f , e g 1 −1 例えば n = 5 とき M = 0 0 0 −1 2 −1 0 0 0 −1 2 −1 0 0 0 −1 2 0 0 0 0 −1 1 , . 画面と”pr1.2.dat”なるファイルの両方に出力する, 2 プログラムを作成しなさい. 3. (終わった人は, 「n > 20 ならば画面には出力しない」ように書き換えてみよう) 4. (終わった人は, 1. の行列を作成する部分をサブルーチンにしてみよう) . FORTRAN プログラミング,–第3回の演習– ( 2014 年 10 月 15 日 09:28 ) 2/12 木村拓馬 . 演習 3.2(pr3.2.f90) . ガウスの消去法を用いて n 元連立一次方程式を解くプログラムを作成しよう. とりあえず,11 ページにある例題を解いてみる. 解けたら演習 3.3 の問題を解いてみる. 係数行列・右辺ベクトルを作る部分では,配列の動的割付けを用いること. 終わった方は,ガウスの消去法の部分を副プログラムにしてみよう. (演習 3.3 が終わった方は残差の無限大ノルムを計算するプログラムを作成) 線型方程式 Ax = b の解 x に対し,残差は Ax − b. ふつう数値計算の計算結果には誤差が混入,Ax − b = 0 なる x は得られない. 残差はベクトルで全ての値を表示すると大変なので,残差のノルム ∥Ax − b∥ の値 などを見る. ベクトルの無限大ノルムは ∥x∥∞ = max {|xi |} i=1,··· ,n . 配列の最大値は MAXVAL(x), 絶対値は ABS(x), 行列ベクトル積 Ax は MATMUL(A,x) を利用できる. FORTRAN プログラミング,–第3回の演習– ( 2014 年 10 月 15 日 09:28 ) 3/12 木村拓馬 . 演習 3.3(pr3.3.f90) . 1. 整数 n ≥ 3 と正数 T が与えられたとき,以下の n × n 行列 A と n 次元ベクトル b に対 し,連立一次方程式 Ax = b を解くプログラムを作成しよう. 1 −1 A = −1 2 .. . −1 .. . .. . .. .. . . −1 .. . 2 0 − cos(0.0) · h sin(1 · h) · h2 sin(2 · h) · h2 , b = .. . sin((n − 2) · h) · h2 −1 1 sin((n − 1) · h) , h = T π / (n − 1). n はキーボードから入力,配列の動的割付け(allocate)を用いること (行列 A を作るのは pr1.2.f90 を参照). . T = 2 とおいたときの解 x と, 2 yi := sin(T π (i − 1) / (n − 1)), i = 1, 2, · · · , n, で定義される n 次元ベクトル y とを比べてみよう( x − y,その絶対値,その最大値) . 終わった人は n = 10, 20, 40 について x と y のグラフを重ねて描いてみよう. . 3 FORTRAN プログラミング,–第3回の演習– ( 2014 年 10 月 15 日 09:28 ) 4/12 木村拓馬 参考文献 [1] JIS X 3001-1:2009 (プログラム言語 Fortran – 第 1 部:基底言語) [2] 戸川隼人: 「ザ・Fortran90/95」, サイエンス社 (1999) [3] 伊理正夫: 岩波講座 応用数学 線形代数 I・II, 岩波書店 (1994) [4] 川久保 勝夫: 線形代数学(新装版), 日本評論社 (2010) FORTRAN プログラミング,–第3回の演習– ( 2014 年 10 月 15 日 09:28 ) 5/12 木村拓馬 Appndix ガウス消去法のプログラム作成において,ウェブ検索して見つけた 「特別な場合」を鵜呑みにして採用することがあるとイヤなので,オマケを追加. 以後の内容に合わせて作成する必要は全く無い. むしろ一年次の線形代数で習った手順を実装してみてほしい. 線形代数や数値解析の教科書に載っている手順でもかまわない. FORTRAN プログラミング,–第3回の演習– ( 2014 年 10 月 15 日 09:28 ) 6/12 木村拓馬 . 線形連立方程式 Ax = b の,拡大係数行列を用いた表現 . 定義(拡大係数行列) n × n 行列 A と n 次列ベクトル b が与えられたとき, Ax = b なる関係が成り立つような n 次列ベクトル x を求めるとする. b1 x1 a11 a12 · · · a1n b x a21 a22 · · · a2n 2 2 . , b = , x = A = . . . . .. . .. . .. .. . . . bn xn an1 an2 · · · ann このとき,A を係数行列,b を右辺ベクトル,x を解ベクトル,係数行列 A と 右辺ベクトル b を横にくっつけた行列を「拡大係数行列」と呼ぶことにするa . 本講義では,拡大係数行列を (A|b) のように表現する. a11 a12 · · · a1n b1 a21 a22 · · · a2n b2 (A|b) = . .. .. .. .. .. . . . . an1 an2 · · · ann bn . a 呼び方は教科書によっていろいろ.右辺,未知数,未知ベクトルなど. FORTRAN プログラミング,–第3回の演習– ( 2014 年 10 月 15 日 09:28 ) 7/12 木村拓馬 . 線形連立方程式 Ax = b と拡大係数行列と行基本変形 . 定義(行基本変形) 行列に対して, 1. ”ある行 ”と ”他の行 ”を入れ替える 2. ”ある行 ”を非零倍する 3. ”ある行の非零倍 ”を他の行に加える の三つの操作を行基本変形という. 行基本変形と線型連立方程式 Ax = b を拡大係数行列 (A|b) で表現し,(A|b) を行基本変形して (C|d) な る行列が得られたとする.このとき, Ax = b ⇐⇒ Cx = d がいえる.つまり,拡大係数行列を行基本変形すれば,同じ解 x を持つ線 形連立方程式に変形できるa . よって,単位行列を I と表すことにして,(A|b) を行基本変形して (I|d) な る行列を導出すれば, Ax = b ⇐⇒ Ix = d ⇐⇒ x=d より,解 x を求めたことになる. . a 理由は省略.大抵の線形代数の教科書に書いてあるので,そちらを参照してほしい.例えば [3, 4] FORTRAN プログラミング,–第3回の演習– ( 2014 年 10 月 15 日 09:28 ) 8/12 木村拓馬 . 部分軸選択を伴うガウスの消去法(Gaussian elimination with partial pivoting) . Ax = b の拡大係数行列 (A|b) に対して行基本変形を繰り返し,解 x を導出する手法 に ”ガウスの消去法 ”がある. a11 a 21 (A|b) = . .. an1 a12 a22 .. . an2 ··· ··· .. . ··· a1n a2n .. . ann b1 b2 .. . bn 前進消去(forward elimination) :i = 1, 2, · · · , n − 1 について, . i 行目以降で i 列目の要素のうち絶対値が最も大きいものを探し, 1 「その要素がある行と 第 i 行を入れ替える」. . このとき,A が正則ならば aii , 0 となる. .2 「 ”第 i 行の非零倍 ”を ”他の行 ”に加えて」, 第 i 列の i + 1 行目以降の要素が全て 0 になるように計算する. FORTRAN プログラミング,–第3回の演習– ( 2014 年 10 月 15 日 09:28 ) 9/12 木村拓馬 . A が正則ならば,前進消去により (A|b) は以下のような行列 (C|d) に変形される. このとき,c11 , · · · , cnn は非零となる. c11 (C|d) = 0 ··· .. . c1n .. . cnn d1 .. . dn 後退代入(backward substitution)a 1. まず第 n 行より, x = d /c n n nn が得られる. 2. 次に第 n − 1 行より, cn−1,n−1 xn−1 + cn−1,n xn = dn−1 である.これを変形して, xn−1 = (dn−1 − cn−1,n xn )/cn−1,n−1 と書ける. 1. で得た xn を代入し, xn−1 が得られる. . 同様に,i = n − 2, · · · , 1 について, 3 n ∑ xi = di − ci j x j /cii j=i+1 を計算すれば解 x が得られる. . a 行基本変形チックに書いていないが,後退代入の操作は全て行基本変形に対応 FORTRAN プログラミング,–第3回の演習– ( 2014 年 10 月 15 日 09:28 ) 10/12 木村拓馬 . 計算例(前進消去) . (A|b) = 0 −1 1 −2 1 1 2 −1 1 −4 1 1 ⇓ 第 1 行以降,第 1 列で絶対値最大は (2,1) 成分の”-1” ⇓ よって第 1 行と第 2 行を入れ替える 1 −1 1 −1 0 −2 2 −4 1 1 1 1 ⇓ 第 −1 0 0 1 列の第 2 行以降を全て零にするには,第 1 行の 1 倍を第 3 行に加える 1 −2 2 −1 2 0 1 −4 2 ⇓ 第 2 行以降,第 2 列で絶対値最大は (2,2) 成分の”-2” ⇓ よって行の入れ替えを行う必要はない ⇓ 第 −1 0 0 2 列の第 3 行以降を全て零にするには,第 2 行の 1 倍を第 3 行に加える 1 −2 0 −1 2 2 1 −4 −2 =: (C|d) 注)実際は, 「行のリスト」の1次元配列を作成し,行を入れ替える代わりに,リストを入れ替えて, 参照するように作成する人も多い. . FORTRAN プログラミング,–第3回の演習– ( 2014 年 10 月 15 日 09:28 ) 11/12 木村拓馬 . 計算例(後退代入) . (C|d) = −1 0 0 1 −2 0 −1 2 2 1 −4 −2 後退代入(backward substitution) 1. まず第 3 行より,次のようにして x が計算できる. 3 x3 = d3 /c3,3 = −2/2 = −1 . 次に第 2 行より, 2 −2 x2 + 2 x3 = −4 である.これを次のように変形して, x2 が計算できる. x2 = (d2 − c2,3 x3 )/c2,2 = (−4 + (−2) · (−1))/(−2) = 1 . 同様にして, x1 が計算できる. 3 ( ) x1 = d1 − c1,2 x2 − c1,3 x3 /c1,1 = (1 − 1 · 1 − (−1) · (−1)) /(−1) = 1 1 よって解 x = 1 が得られる. . −1 FORTRAN プログラミング,–第3回の演習– ( 2014 年 10 月 15 日 09:28 ) 12/12