sp-13. 数値微分と数値積分
1
金子邦彦
Scheme プログラミング)
URL: https://www.kkaneko.jp/pro/scheme/index.html
トライン
13-1 数値微分と数値積分
13-2 パソコン演習
13-3 課題
2
13-1 数値微分と数値積分
3
1. 接線の傾き d/dx
2. 台形則による数値積分 trapezoid
内容
4
5
接線の傾き
h 0 に近づけることで、接線の傾き
(=f '(x) )の「近似値」が求まる
h
hxfhxf
2
)()(
x
f(x)
0
hx
hx
)( hxf
)( hxf
傾きは
接線
区間 [a, b] で,連続関数 f, x,
x=a, x=b で囲まれた面積
f(x)
ab
x
b
adxxfI )(
定積分:
定積分
6
n 個の等間隔な小区間に分割
幅: h = (b-a) / n
小区間: [x0, x1], [x1, x2], ..., [xn-1, xn]
但し,x0= a, xi= x0+ i×h
f(x)
x0= a xn= b
x
x1
x2xn-1
区間 [a, b] の小区間への分割
7
小長方形の面積は
f(x)
x0= a xn= b
x
xixi+1
小長方形
f(xi)
hxf i)(
小長方形
8
小台形の面積は
f(x)
x0= a xn= b
x
xixi+1
小台形
f(xi)f(xi+
1)
小台形
9
小台形の面積の和
定積分 I を,この和 Snで近台形則とい
f(x)
x0= a xn= b
x
))()((
21
1
0
ii
n
i
nxfxf
h
S
x1
x2xn-1
x3xn-2
台形則 trapezoidal rule
10
区間[ab]を n 等分 (1区間の幅h=(b-a)/n)
n 個の台形を考え, その面積の和 Snで,定積分 I を近
f(x) が連続関数のときは,n を無限大に近づければ,SnI
に近づく
但し,単純に「n を大きくすればよい」とは言えない
n を大きくすると 計算時間の問題,丸め誤差の問題が
発生
n
n
ii
n
i
nSxfxf
h
I
lim))()((
2
lim 1
1
0
台形則による数値積分
11
式で書いてある関数の積分
ごく限られた関数しか定積分できない
「数値積分」が重要になる
数値積分の意味
12
両端 x0= a xn= b を除いて,f(xi) は2度現
れる
)()(
21
1
0
ii
n
i
nxfxf
h
S
)())()((2)(
2110 nn xfxfxfxf
h
但し h = (b-a) / n
2回現れる部分
)(
2
1
)()(
2
11
1
0n
n
iixfxfxfh
)(
2
1
)()(
2
11
1
bfihafafh n
i
台形則
13
13-2 パソコン演習
14
資料を見ながら,「例題」を行ってみ
各自,「課題」に挑戦する
自分のペースで先に進んで構いません
パソコン演習の進め方
15
DrScheme の起動
プログラム PLT Scheme
DrScheme
今日の演習では「Advanced Student
に設定
Language
→ Choose Language
Advanced Student
→ OK
Execute ボタン」
DrScheme の使用
16
接線の傾きを求める関数 d/dx を作り,
実行する
数値 x, hと関数 fから,xにおける f
傾き(= f' (x)の近似値を求める
d/dx は高階関数
例題1.接線の傾き
17
1. 次を「定義用インド」で,実行しなさい
入力した後に,Execute ボタンを押す
;; d/dx: (number->number) number number -> number
;; inclination of the tangent
;; Example: (d/dx f 3 0.0001)
;; = ((- (f 3.0001) (f 2.9999)) 0.0002)
(define (d/dx f x h)
(/ (- (f(+ x h)) (f(- x h)))
(* 2 h)))
(define (f2 x)
(- (* x x) 2))
2. その後,次を「実行用インド」で実行しなさい
次は,例題2に進んでください
(d/dx f2 3 0.0001)
「例題1.接線の傾き」の手順
18
まず,関数 d/dx 定義している
19
次に関数 f2 定義している
(define (f2 x)
(- (* x x) 2))
20
これは,
(d/dx f2 3 0.0001)
と書いて,xの値を 3 ,
hの値を 0.0001 に,
ff2 に設定しての実行
実行結果である「6」が
表示される
21
d/dx
f2'(3) の近似値
入力 出力
f2
3
0.0001
入力は2つの数値と
関数
出力は数値
d/dx は,関数を入力とするよな関数
(つまり高階関数)
入力と出力
22
;; d/dx: (number->number) number number -> number
;; inclination of the tangent
;; Example: (d/dx f 3 0.0001)
;; = ((- (f 3.0001) (f 2.9999)) 0.0002)
(define (d/dx f x h)
(/ (- (f(+ x h)) (f(- x h)))
(* 2 h)))
関数が,
d/dx」の入力になっている
d/dx 関数
23
(dx/d f2 3 0.0001) から 6 が得られる過程の概略
(dx/d f2 3 0.0001)
= (/ (- (f2 (+ 3 0.0001)) (f2 (- 3 0.0001)))
(* 2 0.0001))
= (/ (- (- (* (+ 3 0.0001) (+ 3 0.0001)) 2)
(- (* (- 3 0.0001) (- 3 0.0001)) 2)
(* 2 0.0001)))
= …
= 6
最初の式
実行結果
コンピュータ内部での計算
但し,f2
(define (f2 x)
(- (* x x) 2)) 24
(dx/d f2 3 0.0001) から 6 が得られる過程の概略
(dx/d f2 3 0.0001)
= (/ (- (f2 (+ 3 0.0001)) (f2 (- 3 0.0001)))
(* 2 0.0001))
= (/ (- (- (* (+ 3 0.0001) (+ 3 0.0001)) 2)
(- (* (- 3 0.0001) (- 3 0.0001)) 2)
(* 2 0.0001)))
=
= 6
これは,
(define (d/dx f x h)
(/ (- (f(+ x h)) (f(- x h)))
(* 2 h)))
x3 で,h0.0001 , ff2 で置き換
えたもの
25
(dx/d f2 3 0.0001) から 6 が得られる過程の概略
(dx/d f2 3 0.0001)
= (/ (- (f2 (+ 3 0.0001)) (f2 (- 3 0.0001)))
(* 2 0.0001))
= (/ (- (- (* (+ 3 0.0001) (+ 3 0.0001)) 2)
(- (* (- 3 0.0001) (- 3 0.0001)) 2)
(* 2 0.0001)))
= …
= 6
これは,
(define (f2 x)
(- (* x x) 2))
x (+ 3 0.0001) (- 3 0.0001) で置き換えたも
26
台形則による数値積分の関数
trapezoid を作り,実行する
但し,
積分したい関数 f(x) = e
積分区間: [a, b]
区間数: n
-x2
例題2.台形則による数値積分
27
1. 次を「定義用インド」で,実行しなさい
入力した後に,Execute ボタンを押す
(define (trapezoid-iter f a h k)
(cond
[(= k1) (f (+ a h))]
[else (+ (f (+ a(* h k)))
(trapezoid-iter f a h (- k1)))]))
;; trapezoid: number number number -> number
;; to compute the area under the graph of f between a and b
(define (trapezoid f a b n)
(* (/ (- b a) n)
(+ (trapezoid-iter fa
(/ (- b a) n)
(- n1))
(/ (f a) 2)
(/ (f b) 2))))
(define (f2 x)
(exp (- (* x x))))
2. その後,次を「実行用インド」で実行しなさい
次は,課題に進んでください
(trapezoid f2 0 1 1000)
「例題2.台形則による数値積分」の手順
28
まず,関数 trapezoid-iter,
trapezoid 定義している
29
次に関数 f2 定義している
(define (f2 x)
(exp (- (* x x))))
これは,数値積分したい関数
30
これは,
(trapezoid f2 0 1 1000)
と書いて,aの値を 0 ,
bの値を 1 に,hの値を 1000 に,
ff2 に設定しての実行
実行結果であ
#i0.7468240714991842
が表示される
31
(define (trapezoid-iter f a h k)
(cond
[(= k1) (f (+ a h))]
[else (+ (f (+ a(* h k)))
(trapezoid-iter f a h (- k1)))]))
;; trapezoid: number number number -> number
;; to compute the area under the graph of f between a
and b
(define (trapezoid f a b n)
(* (/ (- b a) n)
(+ (trapezoid-iter f
a
(/ (- b a) n)
(- n1))
(/ (f a) 2)
(/ (f b) 2)))) 32
例題2での台形則の計算の精度が,分割幅を小さ
くするほど高精度になることを確かめる.
但し,
積分したい関数 f(x) = e
積分区間 0 から 1
分割数 10, 20, 40, 80, 160, 320, 640, 1280 の8通り
-x2
例題3.台形則の計算の精度
33
1. 次を「定義用インド」で,実行しなさい
入力した後に,Execute ボタンを押す
(define (trapezoid-iter f a h k)
(cond
[(= k1) (f (+ a h))]
[else (+ (f (+ a(* h k)))
(trapezoid-iter f a h (- k1)))]))
;; trapezoid: number number number -> number
;; to compute the area under the graph of f between a and b
(define (trapezoid f a b n)
(* (/ (- b a) n)
(+ (trapezoid-iter fa
(/ (- b a) n)
(- n1))
(/ (f a) 2)
(/ (f b) 2))))
(define (f2 x)
(exp (- (* x x))))
これは,例題2と同じ
例題3.「台形則の計算の精度」の手順 (1/2)
34
次は,課題に進んでください
(trapezoid 0 1 10)
(trapezoid 0 1 20)
(trapezoid 0 1 40)
(trapezoid 0 1 80)
(trapezoid 0 1 160)
(trapezoid 0 1 320)
(trapezoid 0 1 640)
(trapezoid 0 1 1280)
2. その後,次を「実行用ンド」で実行
しなさい
例題3.「台形則の計算の精度」の手順(2/2)
35
分割幅を小さくするほど高精度
数値積分の精度
36
近似値を求める手法
数値微分,数値積分
十分に役に立つ
「必ず誤差が生じる」ことを意識しながら使ことが
必要
おわりに
37
13-3 課題
38
f(x) = x cos x について,f'(0), f'(0.2),
f'(0.4), f'(0.6) の値を報告しなさい
関数 d/dx (授業の例題1)を使いなさい
h = 0.1 としなさい
課題1
39
f(x) = x cos x について,h = 0.1, 0.01,
0.001 と変えて関数 d/dx を実行し,結
果を比べなさい
h と誤差の関係が分かるグラフを作成せ
演習2
40
台形則を使って,次を計算せよ
計算結果を,以下と比較せよ
1
01
2log dx
x
x
e
DrScheme での (log 2) の実行結果
演習3
41
演習3について,区間数 n を,n = 4, 8, 16,
32, 64, 128 と変えて計算を行い,刻み幅と誤
差の関係を調べよ
区間数 n と誤差の関係を書いたグラフを作成せよ
この場合,おおよそ次の関係が成り立っているこ
とを確認せよ
2
n
c
ISn
c は定数)
演習4
42
関数 d/dx (例題1)を使って,関数
のグラフをグラフィックスで表示させ
なさい
プログラムは次ページ以降にある.この
プログラムを実行させ,実行結果を報告
しなさい
但し,実行結果の報告では,必 関数
f2 を別のものに書き換えて実行しなさい
演習4.関数のグラフ
43
;; d/dx: (number->number) number number -> number
;; inclination of the tangent
;; Example: (d/dx f 3 0.0001)
;; = ((- (f 3.0001) (f 2.9999)) 0.0002)
(define (d/dx f x h)
(/ (- (f (+ x h)) (f (- x h)))
(* 2 h)))
;; samples: (number->number) number number number -> list of
'posn' structure
(define (samples f a h k)
(cond
[(= k 1) (cons (make-posn (+ a h)
(f (+ a h)))
empty)]
[else (cons (make-posn (+ a (* h k))
(f (+ a (* h k))))
(samples f a h (- k 1)))]))
44
; window size
(define WX 500)
(define WY 500)
; grid color, axis color and
(define GRID_COLOR 'blue)
(define AXIS_COLOR 'red)
(define GRAPH_COLOR 'red)
; draw-a-line
(define (sessen x px py d)
(+ (* d (- x px)) py))
(define (draw-a-sessen from to px py d x0 y0 sx sy)
(draw-solid-line (make-posn (+ (* from sx) x0) (+ (* (sessen from px py d) sy)
y0))
(make-posn (+ (* to sx) x0) (+ (* (sessen to px py d) sy) y0))
GRAPH_COLOR))
(define (draw-sessen f px x0 y0 sx sy)
(draw-a-sessen (/ (- x0) sx) (/ (- WX x0) sx) px (f px) (d/dx f px 0.00001) x0
y0 sx sy)) 45
; draw-polyline
(define (draw-polyline a-poly)
(cond
[(empty? (rest a-poly)) true]
[else (and
(draw-solid-line (first a-poly)
(first (rest a-poly)) GRAPH_COLOR)
(draw-polyline (rest a-poly)))]))
; draw-h-lines
(define (draw-h-lines start skip stop width)
(cond
[(>= start stop)
(draw-solid-line (make-posn 0 stop) (make-posn width stop)
GRID_COLOR)]
[else
(and
(draw-solid-line (make-posn 0 start) (make-posn width start)
GRID_COLOR)
(draw-h-lines (+ start skip) skip stop width))]))
46
; draw-v-lines
(define (draw-v-lines start skip stop height)
(cond
[(>= start stop)
(draw-solid-line (make-posn stop 0) (make-posn stop height)
GRID_COLOR)]
[else
(and
(draw-solid-line (make-posn start 0) (make-posn start height)
GRID_COLOR)
(draw-v-lines (+ start skip) skip stop height))]))
; (x0, y0) is the origin. sx and sy represent one grid size
(define (draw-grid x0 y0 sx sy)
(and
(draw-v-lines (- x0 (* (quotient x0 sx) sx)) sx (+ (* (quotient (- WX x0) sx) sx)
x0) WY)
(draw-h-lines (- y0 (* (quotient y0 sy) sy)) sy (+ (* (quotient (- WY y0) sy) sy)
y0) WX)
(draw-solid-line (make-posn 0 y0) (make-posn WX y0) AXIS_COLOR)
(draw-solid-line (make-posn x0 0) (make-posn x0 WY) AXIS_COLOR))) 47
; (x0, y0) is the origin. sx and sy represent one grid size
(define (scaling a-list x0 y0 sx sy)
(cond
[(empty? a-list) empty]
[else (cons (make-posn (+ (* (posn-x (first a-list)) sx) x0)
(+ (* (posn-y (first a-list)) sy) y0))
(scaling (rest a-list) x0 y0 sx sy))]))
;
; f2: number -> number
(define (f2 x)
(- (* x x) 2))
; (X0, Y0) reprerents the origin of the graph.
; SX and SY represent the size of one grid
(define X0 (/ WX 2))
(define Y0 (/ WY 2))
(define SX 50)
(define SY 50)
(define PX 0.5)
(start WX WY)
(draw-grid X0 Y0 SX SY)
(draw-polyline (scaling (samples f2 (/ (- X0) SX) (/ 1 SX) WX) X0 Y0 SX SY))
(draw-sessen f2 PX X0 Y0 SX SY)
48