情報基礎実習I第四回目

Download Report

Transcript 情報基礎実習I第四回目

情報基礎実習I
(第4回)
木曜4・5限
担当:北川 晃
例題:4次式の数表
4次式
f  x   1.5 x  0.8 x  6.2 x  0.5 x  2.1
4
3
2
の値を,0から0.2きざみで5.0までのxに対して計算し,
順に書き出すプログラムを作れ.
Dim y As Single
For x As Single = 0.0 To 5.0 Step 0.2
y = 1.5 * x ^ 4 - 0.8 * x ^ 3 _
+ 6.2 * x ^ 2 + 0.5 * x + 2.1
Console.WriteLine("{0,8},{1,16}", x, y)
Next
例題:4次式の数表(改)
4次式
f  x   1.5 x  0.8 x  6.2 x  0.5 x  2.1
4
について,f
 x
3
2
の値を,0から0.2きざみで5.0までの
xに対して計算し,順に書き出すプログラムを作れ.
xをMath.Sqrt(x)で置き換え
Dim y As Single
For x As Single = 0.0 To 5.0 Step 0.2
y = 1.5 * x ^ 4 - 0.8 * x ^ 3 _
+ 6.2 * x ^ 2 + 0.5 * x + 2.1
Console.WriteLine("{0,8},{1,16}", x, y)
Next
書き換えが煩雑!!関数として定義できないか?
プロシージャとは
• ある一連の処理コードに名前をつけて登録した
下請けプログラムを,プロシージャという.
• 従来の言語では,「関数」あるいは
「サブルーチン」と呼ぶ処理に該当する.
• Functionプロシージャが関数にあたり,呼び出した
コードブロックに,必ず一つの値を返す.
• Subプロシージャがサブルーチンにあたり,
呼び出したコードブロックに値を返さない.
• プロシージャ間のデータの引き渡しは,「引数」で行う.
関数の定義の書式
Sub Main()
…
y1 = プロシージャ名(引数リスト)
…
End Sub
仮引数,「値渡し」と
「参照渡し」がある
Function プロシージャ名(引数リスト) [As 戻り値の型]
文ブロック
Return 戻り値 または プロシージャ名 = 戻り値
End Function
関数の定義の仕方の例(その1)
(主プログラム)
Sub Main()
…
y1=f(x)
…
End Sub
一種の副プログラムであるから,
主プログラムとは別に書く.
組み込み関数のように
呼び出せる
引数を値渡しの単精度
実数型として宣言
Function f(ByVal x As Single) As Single
Dim y As Single
戻り値の型の宣言
y = x ^ 2 + 2 * x
関数の定義
Return y
End Function
主プログラムへ返す値
(副プログラム)
(戻り値)
関数の定義の仕方の例(その2)
Sub Main()
組み込み関数のように
…
呼び出せる
y1=f(x)
…
省略した場合は
End Sub
(主プログラム)
値渡し
Function f(x) As Single
Dim y As Single
戻り値の型の宣言
If x < 0 Then
y = 0
Else
関数の定義
ステップ
y=1
関数
End If
主プログラムへ返す値
Return y
(戻り値)
End Function (副プログラム)
例題:4次関数の定義
4次式
f  x   1.5 x  0.8 x  6.2 x  0.5 x  2.1
4
について, f
 x
3
2
の値を,0から0.2きざみで5.0までの
xに対して計算し,順に書き出すプログラムを作れ.
考え方:
• 実数xを引数とする実数型の関数
f(x)を定義する.
• xを繰り返し変化させながら,y=f(√x)の値を
順に書き出す.
4次関数の定義:プログラム例
Sub Main()
Dim y As Single
For x As Single = 0.0 To 5.0 Step 0.2
y = f(Math.Sqrt(x))
Console.WriteLine("{0,8},{1,16}", x, y)
Next
End Sub
Function f(x) As Single
Dim y As Single
y = 1.5 * x ^ 4 - 0.8 * x ^ 3 _
+ 6.2 * x ^ 2 + 0.5 * x + 2.1
Return y
End Function
4次関数の定義:出力例
プログラミング演習
• 非負の整数 n に対する階乗 n ! を計算する
関数を定義し,これを用いることで級数

1 1 1 1
   

0! 1! 2!
k 0 k !
1
1

 
 n  1! n !
の値を計算せよ.
考え方:
• 整数nを引数とする実数型の関数
factorial(n)を定義する.
• 与級数は有限の値に収束する.有限項で切っても,
十分よい近似値が得られる.
級数の計算:プログラム例
Sub Main()
Dim sum As Single = 0
有限で切る項を
十分大きく取る
For i As Integer = 0 To 100
sum = sum + 1 / factorial(i)
Next
関数の呼び出し
Console.WriteLine("級数の値は{0}", sum)
End Sub
Function factorial(n) As Single
Dim p As Single = 1
For i As Integer = 1 To n
p = p * i
Next
Return p
関数として返す値
End Function
大きなnに対して
計算できるように,
実数型で定義
級数の計算:出力例
例題:方程式の根
方程式
は,区間[0,2]において
ただ1つ根があることがわかっている.その根を
2分法によって求めるプログラムを作れ.
•2分法
両端と中点の
符号を調べる
方程式の根:考え方
1. 区間
の中点
を計算する.
2. 区間
と
において,
•
ならば解は左の区間
•
ならば解は右の区間
3. 解がある方の区間において新たな中点を計算し,
判定を行う.
となるまで繰り返し,そのときの
4.
解とする.
を
方程式の根:プログラム例(主プログラム)
Dim eps, x1, x2, xm As Single
eps = 10 ^ -6
単精度実数型の
x1 = 0
精度の限界
x2 = 2
端の値を入力
条件が真の間
While x2 - x1 > eps
は繰り返す
xm = (x1 + x2) / 2
中点の計算
If f(x1) * f(xm) > 0 Then
x1 = xm
解が中点の左右
Else
どちらにあるか判定
x2 = xm
端の点を再定義
End If
End While
解の書き出し
Console.WriteLine("解はx={0}", xm)
方程式の根:プログラム例(関数)
Function f(x) As Single
Dim y As Single
y = x ^ 3 - x - 1
Return y
End Function
関数として返す値
級数の計算:出力例
例題:数値積分(台形公式)
次の関数を
から
プログラムを作れ.
数値積分には台形公式を用いる.
まで積分する
数値積分(台形公式):考え方
台形で近似する
f  xi 
f  xi 1 
ba
h
n
xi  a  i  h
Si
f  xi 1 
h
a
xi 1 h xi
n
S   Si
i 1
b x
f  xi 
h
Si   f  xi 1   f  xi   
2
数値積分(台形公式):プログラム例
Sub Main()
Dim h, a, b, S As Single
区間の分割数
Dim n As Integer = 65536
刻み幅
a = 0 : b = 2 : h = (b - a) / n
複数の文を改行せずに
続ける表記法
S = 0
For i = 1 To n
S = S + (f(a + (i - 1) * h) + f(a + i * h)) * h / 2
Next
i 1
i
f x

f x

Console.WriteLine(“積分値はS={0}", S)
End Sub
Function f(x) As Single
Dim y As Single
y = Math.Sqrt(4 - x ^ 2)
Return y
End Function
f  x  4  x
2
数値積分(台形公式):出力例
数値積分(台形公式):計算結果の精度
分割の数と計算結果
分割数
4
16
64
256
1024
4096
16384
65536
  3.1415926
計算値
誤差(%)
2.995709
4.64361
3.123253
0.5837687
3.139297
0.07308303
3.141305
0.009144868
3.141557
0.001123187
3.141587
0.0001821384
3.141594 -5.312396×10-5
3.141598 -0.0001669602
有効数字の桁数が上げられないか?
精度が悪く
なっている!?
数値積分(台形公式):プログラム例
Sub Main()
Dim h, a, b, S As Double
倍精度実数型
Dim n As Ineger = 65536
a = 0 : b = 2 : h = (b - a) / n
S = 0
For i = 1 To n
S = S + (f(a + (i - 1) * h) + f(a + i * h)) * h / 2
Next
Console.WriteLine("積分値はS={0}", S)
End Sub
倍精度実数型
Function f(x) As Double
倍精度実数型
Dim y As Double
y = Math.Sqrt(4 - x ^ 2)
Return y
倍精度実数型と単精度実数型を
End Function
混在させると,精度は単精度になる
数値積分(台形公式):倍精度での計算結果
分割の数と計算結果
分割数
4
16
64
256
1024
4096
16384
65536
  3.1415926535897931
計算値
2.99570906810244
3.12325303782774
3.13929691277968
3.14130558295723
3.14155676653902
3.14158816760776
3.1415920928389
3.14159258349582
誤差(%)
4.6436
0.58377
0.073076
0.0091377
0.0011423
0.00014279
1.7849×10-5
2.2312×10-6
分割数を大きくするほど,誤差が減っていく
プログラミング演習
• 方程式 x  cos x は 0  x  1 の範囲内に解が
ひとつ存在することが知られている.
二分法を用いて,解を求めるプログラムを作成せよ.
(0.7390852)
• 定積分 I 

2
2
2

x
  4  dx を台形公式により
数値積分するプログラムを作成し,
得られた値を解析的に解いた値と比較してみよ.