250 likes | 402 Views
情報基礎実習 I ( 第 6 回). 木 曜4・5限 担当 :北川 晃. ベクトルの内積. ベクトル A とベクトル B の内積を計算する(下限 1 ,上限 N ).. s = 0.0 For i As Integer = 1 To n s = s + a( i ) * b( i ) Next. 行列の積の成分計算. 行列 A と行列 B の積を計算する(下限 1 ,上限 N ).. 第 ( i , j ) 成分は・・・. s = 0.0 For k As Integer = 1 To N s = s+a ( i,k )* b ( k,j )
E N D
情報基礎実習I(第6回) 木曜4・5限 担当:北川 晃
ベクトルの内積 • ベクトルAとベクトルBの内積を計算する(下限1,上限N). s = 0.0 For i As Integer = 1 To n s = s + a(i) * b(i) Next
行列の積の成分計算 • 行列Aと行列Bの積を計算する(下限1,上限N). 第(i,j)成分は・・・ s = 0.0 For k As Integer = 1 To N s = s+a(i,k)*b(k,j) Next k
プログラミング演習 3×3の正方行列A,Bを外部ファイルからデータとして 読み込み,その積C=ABを計算するプログラムを作れ. data_a.txt data_b.txt -2 1 4 0 3 -2 2 -1 1 1 2 -3 -3 0 2 0 -1 5
行列の積:出力例 行ごとに改行する
行列の積:プログラム例 Dim ReadText1 As New IO.StreamReader( _ "D:\...\data_a.txt", System.Text.Encoding.Default) Dim ReadText2 As New IO.StreamReader( _ "D:\...\data_b.txt", System.Text.Encoding.Default) Dim n As Integer = 3 Dim a(10, 10), b(10, 10), c(10, 10) As Single For i As Integer = 1 To n For j As Integer = 1 To n a(i, j) = ReadText1.ReadLine() b(i, j) = ReadText2.ReadLine() Next Next ReadText1.Close() ReadText2.Close() 二つの外部 ファイルを接続 配列の宣言 (サイズは大きめに) 行列データの 読み込み ファイルを閉じる
行列の積:プログラム例(続き) For i As Integer = 1 To n For j As Integer = 1 To n c(i, j) = 0.0 For k As Integer = 1 To n c(i, j) = c(i, j) + a(i, k) * b(k, j) Next If j <> n Then Console.Write("{0,10}", c(i, j)) Else Console.WriteLine("{0,10}", c(i, j)) End If Next Next 積の(i,j)成分の計算 行の右端で改行する
CSV形式のファイルからのデータ読み込み a(1,0)=1, a(1,1)=10 a(2,0)=2,a(2,1)=20 a(3,0)=3,a(3,1)=30 a(4,0)=4,a(4,1)=40 a(5,0)=5,a(5,1)=50 data.csv 1, 10 2, 20 3, 30 4, 40 5, 50
CSV形式からのデータ読み込み:プログラム例 Dim ReadText As New IO.StreamReader(_ "D:\...\data.csv", System.Text.Encoding.Default) Dim s, items(10) As String Dim a(10, 10) As Single For i As Integer = 1 To 5 s = ReadText.ReadLine() items = Split(s, ",") For j As Integer = 0 To 1 a(i, j) = CSng(items(j)) Next j Console.WriteLine("a({0},0)={1,4}, a({0},1)={2,4}", _ i, a(i, 0), a(i, 1)) Next i ReadText.Close() データ1行を文字列のsへ,分割して配列のitems()へ データを格納する配列 sをコンマの位置で区切る 文字列から 単精度実数型へ
データの型の変更 • Cint(x): xを整数型へ変換 • CStr(x): xを文字列へ変換 • CSng(x): xを単精度実数型へ変換 • CDbl(x): xを倍精度実数型へ変換 • CBool(x): xを論理型へ変換
例題:掃き出し法 次の連立一次方程式を,掃き出し法により 解を求めるプログラムを作れ. data.txt 方程式の次元:3 3 2.0 -1.0 3.0 -4.0 -4.0 1.0 -5.0 6.0 -1.0 -1.0 5.0 4.0 成分を順に 1行ずつ書く
掃き出し法:考え方 ① ② ③ ①÷2.0: ④ ②-④×(-4.0): ⑪ ⑤ ⑫ ⑥ ③-④×(-1.0): ⑩ ④-⑦×(-0.5): ⑧ ⑤÷(-1.0): ⑦ ⑧-⑩×1.0: ⑨ ⑥-⑦×(-1.5): ⑦-⑩×(-1.0): ⑨÷5.0:
掃き出し法:アルゴリズム Step 1:配列の宣言,データの入力: の配列を宣言する. Step 2: Step 3~Step 5の計算を,k=1,…,nについて行う. Step 3:を計算し, それを新しい とする. Step 4: Step 5の計算を,i=1,…,k-1,k+1,…,nについて行う. Step 5: Step 3で計算した,新しいを用いて, を計算し,それを新しいとする. Step 6:計算結果を書き出す: i=kはとばす
掃き出し法:プログラム例 Console.Title = “掃き出し法” Dim a(10, 10), akk, aik As Single Dim n As Integer Dim ReadText As New IO.StreamReader( _ "D:\…\data.txt", System.Text.Encoding.Default) n = ReadText.ReadLine() For i As Integer = 1 To n For j As Integer = 1 To n + 1 a(i, j) = ReadText.ReadLine() Next j Next i
掃き出し法:プログラム例(続き) For i As Integer = 1 To n For j As Integer = 1 To n + 1 If j <> n + 1 Then Console.Write("{0,8}", a(i, j)) Else Console.WriteLine("{0,8}", a(i, j)) End If Next j Next i ReadText.Close() 行の終わりでのみ 改行して書き出す
掃き出し法:プログラム例(続き) For k As Integer = 1 To n akk= a(k, k) For j As Integer = k To n + 1 a(k, j) = a(k, j) / akk Next j Console.WriteLine("---------------------") For i As Integer = 1 To n If i = k Then GoTo Point1 aik= a(i, k) For j As Integer = k To n + 1 a(i, j) = a(i, j) - aik * a(k, j) Next j Point1: Next i i=kはとばす
掃き出し法:プログラム例(続き) For i As Integer = 1 To n For j As Integer = 1 To n + 1 If j <> n + 1 Then Console.Write("{0,8}", a(i, j)) Else Console.WriteLine("{0,8}", a(i, j)) End If Next j Next i Next k Console.WriteLine("------------------------------") For i As Integer = 1 To n Console.WriteLine("x{0}={1,8}", i, a(i, n + 1)) Next i 行の終わりでのみ 改行して書き出す
掃き出し法:プログラムの改良 • プログラムに同じ内容を記載した部分がある: • 18~26行目,44~52行目 • 入力データをCSV形式で入力する Subプロシージャ(サブルーチン)を使って, 主プログラムとは別の副プログラムとして作成 3 2.0, -1.0, 3.0, -4.0 -4.0, 1.0, -5.0, 6.0 -1.0, -1.0, 5.0, 4.0 配列a(i,j)を共通の変数として宣言する data.txt 方程式の次元:3 • 1行ずつ文字列として読み込む • コンマで分割して配列に格納 • 文字列を実数型に変換 成分をCSV形式で 1行ずつ書く
Subプロシージャとは • 主プログラムの一部を外部の副プログラムに移す • 繰り返し同じ記述をする場合などに有効 • Functionプロシージャとは異なり, • 主プログラムに値は返さない • 主プログラムと変数のやりとりをすることもできる プログラムで 共有する変数は,Mainよりも外で 宣言する Mainプログラムも, Subプロシージャの一つ Sub Main() … プロシージャ名(変数) … End Sub Sub プロシージャ名(変数) 文ブロック End Sub 値は返さないので, “Return *”はいらない
Subプロシージャの例 Sub Main() For i As Integer = 1 To 20 If i - (i \ 3) * 3 = 0 Then fizz(i) Else Console.WriteLine(i) End If Next End Sub Sub fizz(i) Console.WriteLine("{0} Fizz", i) End Sub ‘fizz’という名の Subプロシージャ を呼び出す iの値と,’Fizz’と 書き出すプログラム
掃き出し法:プログラム改良例 Dim a(10, 10) As Single Sub Main() Dim akk, aik As Single, s, items(10) As String Dim n As Integer Dim ReadText As New IO.StreamReader( _ "D:\…\data.txt", System.Text.Encoding.Default) n = ReadText.ReadLine() For i As Integer = 1 To n s = ReadText.ReadLine() items = Split(s, ",") For j As Integer = 0 To n a(i, j + 1) = CSng(items(j)) Next Next i output(n) ReadText.Close() 共通の変数の宣言 items(0)~items(n-1)を a(i,1)~a(i,n)に対応させる nを引数とするサブルーチン (Subプロシージャ)の呼び出し
掃き出し法:プログラム改良例(続き) For k As Integer = 1 To n akk = a(k, k) For j As Integer = k To n + 1 a(k, j) = a(k, j) / akk Next j Console.WriteLine("------------------------------") For i As Integer = 1 To n If i = k Then GoTo Point1 aik = a(i, k) For j As Integer = k To n + 1 a(i, j) = a(i, j) - aik * a(k, j) Next j Point1: Next i output(n) Next k nを引数とするサブルーチン (Subプロシージャ)の呼び出し
掃き出し法:プログラム改良例(続き) Console.WriteLine("--------------------------------------") For i As Integer = 1 To n Console.WriteLine("x{0}={1,8}", i, a(i, n + 1)) Next i End Sub Sub output(n) For i As Integer = 1 To n For j As Integer = 1 To n + 1 If j <> n + 1 Then Console.Write("{0,8}", a(i, j)) Else Console.WriteLine("{0,8}", a(i, j)) End If Next j Next i End Sub nを引数とするサブルーチン (Subプロシージャ)の定義