640 likes | 735 Views
関数抽象による 級数,べき級数,テーラー級数. series 数列の和(級数). 抽象関数. 補助関数 として使用. 高階 関数. power-series べき級数. 補助関数 として使用. taylor-series テイラー級数. 例題.級数. 級数を求める高階関数 series 自然数 n , 数 x , 関数 f から (+ ( f 0) ( f 1) … ( f n)) を求める n = 0 の時 n > 0 の時. まず,関数 series を定義している.
E N D
関数抽象による級数,べき級数,テーラー級数関数抽象による級数,べき級数,テーラー級数
series 数列の和(級数) 抽象関数 補助関数として使用 高階 関数 power-series べき級数 補助関数として使用 taylor-series テイラー級数
例題.級数 • 級数を求める高階関数 series • 自然数 n,数x,関数 f から (+(f 0) (f 1) … (f n)) を求める • n = 0 の時 • n > 0 の時
まず,関数 series を定義している
次に関数 f2,f3を定義している (define (f2k) (* k k)) (define (f3k) (* k k k))
これは, (series 3 f2) と書いて,nの値を 3, fの値を f2に設定 評価結果である「14」が 表示される
高階関数の規約 (define (series n f) (foldr + 0 (map f (build-list (add1 n) (lambda (x) x))))) 高階関数は,関数を入力/出力とする 【規約】 ;; series : number (number->number) -> number 関数を入力・出力するときの記法
級数を求める高階関数 (define (series n f) (foldr + 0 (map f (build-list (add1 n) (lambda (x) x))))) • 入力 • 上限項の番号 nnumber • 数列の関数 term(number -> number) 例: make-even 4 series 出力は数 8+6+4+2+0= 20
例題.べき級数 • べき級数を求める高階関数 power_series • 自然数 n,数x,関数 g から (* (g 0)(expt x 0)) と(* (g 1)(expt x 1)) と…+(* (g n)(expt x n)) の総和を求める • n = 0 の時 • n > 0 の時
級数とべき級数 級数とべき級数では,何が同じで,何が違うか 級数 べき級数 g(n)の計算の際、 xの n乗も掛け合わせる • べき級数の g(i)・xiを f(i), g(n)・xnを f(n) と見ると,級数と同じ手順で,べき級数を計算できる
入力と出力 (g1 0), (* (g1 1) (expt 2 1)), (* (g1 2) (expt 2 2)), (* (g1 3) (expt 2 3)) の値の合計 2 3 g1 power_series 出力 入力 出力は数値 入力は2つの数値と 関数 power_seriesは,関数を入力とするような関数 = 高階関数
Contract (規約) power-series 関数の Contract(規約) ;;power-series: number number (number->number) -> number 数 数 関数 入力:数 出力:数 数 出力 入力 「値としての関数」を扱う ときの規約の書き方
べき級数 べき級数の第0項から第n項 【関数 power-series の規約,目的記述文,ヘッダ】 規約 • ;; power-series :number number • ;; (number -> number) -> number • ;; べき級数の第0項から第n項 • ;; (power-series 1 10 sqr) -> 385 • (define (power-series x n g) 目的記述文 例 ヘッダ 13
べき級数 power_series 関数 • ;; power-series :number number • ;; (number -> number) -> number • ;; べき級数の第0項から第n項 • ;; (power-series 1 10 sqr) -> 385 • (define (power_series x n g) • (local ((define (power_term i) • (* (g i) (exptx i)))) • (series n power_term)))
定義の局所化 (local式) • ;; power-series :number number • ;; (number -> number) -> number • ;; べき級数の第0項から第n項 • ;; (power-series 1 10 sqr) -> 385 • (define (power_series x n g) • (local ((define (power_term i) • (* (g i) (exptx i)))) • (series n power_term))) べき級数の第 i 項は,数列の第 i 項に xの i乗を掛けたもの ⇒ そのような項の計算をする関数 power-termを,local 式を 使って,局所的に定義
定義の局所化 (local式) • ;; power-series :number number • ;; (number -> number) -> number • ;; べき級数の第0項から第n項 • ;; (power-series 1 10 sqr) -> 385 • (define (power_series x n g) • (local ((define (power_term i) • (* (g i) (exptx i)))) • (series n power_term))) 各項の和(級数)を求める本体式では,seriesを参照
Local 式による定義の局所化 (define (power-series x n g) (local ((define (power-term i) (* (g i) (expt x i)))) (seriesnpower-term) ) ) xは,power-seriesの パラメータ iは,power-termの パラメータ 局所的に定義された関数の本体式では, 局所関数のパラメータ (この場合 i ) だけでなく, 外側の関数のパラメータ(この場合 x)も使える
テイラー展開 テイラー展開:関数 fが,aの近傍で定義されていて,点 aで n階微分可能であるとき 関数が無限階微分可能な場合 ⇒テイラー級数 (剰余項(末尾項)が 0 に限りなく近づく) 三角関数や指数関数など様々な関数の級数表現が可能 ※a=0 のとき、級数をマクローリン級数(展開をマクローリン展開)というが,ここでは区別せず,a=0 のときもテイラー級数(テイラー展開)と書く
べき級数とテイラー展開 べき級数とテイラー展開の違い べき級数 テイラー展開 (a=0のとき) 各項の計算の際,n! や i! で割る • テイラー展開の項 g(k)/k! を, べき級数の g(k) と見るとべき級数と同じ手順で計算できることが分かる
テーラ展開(例) 収束半径:∞ 収束半径:∞ 収束半径:∞ 収束半径:1 収束半径:1
テイラー展開(例) 収束半径:∞ 具体的関数の定義 (x10の項で計算打ち切り) (define (taylor-exp x) (local ((define (taylor-term i) 1)) (taylor-series x10 taylor-term)))
Taylor-series の定義例 ;; taylor-series: number number (number -> number) -> number (define (taylor-series x n g) (local ((define (kaijou k) (cond [(=k0) 1] [else (*k (kaijou (-k1)))])) (define (taylor-term i) (/ (g i) (kaijou i))) ) (power-series x n taylor-term))) 2つの局所関数 本体式で,power-seriesを利用。
テイラー展開(例) 収束半径:∞ 具体的関数の定義 (x10の項で計算打ち切り) (define (taylor-exp x) (local ((define (taylor-term i) 1)) (taylor-series x10 taylor-term)))
Scheme処理系の実演 24
DrScheme の使用準備 DrScheme の起動 実演では「Advanced Student」に設定 言語 → 言語の選択 → Advanced Student → 「実行」ボタン 25 25
実演.級数 級数(数列の和)を求める関数 series つまり series 3 f (f 0) (f 1) (f 2) (f 3) の和 入力は数(number)と 関数(number->number) 出力は数 3乗を求める関数 cubeを,高階関数 sumに適用
実演1 • 「定義ウインドウ」で,次の関数定義を行う ;; series: non-negative-integer (non-negative-integer -> number) ;; -> number ;; sum up the first n numbers in the sequence f ;; (series 2 f2) = (+ (f2 2) (+ (f2 1) (f2 0))) (define (series n f) (foldr + 0 (mapf (build-list (add1n) (lambda (x) x))))) (define (fi) (*i i i)) • その後,次の式を「対話ウインドウ」で評価させる (series3f) (series 4f) (series 5f)
実演. べき級数 べき級数を求める高階関数 power-seriesを使って,簡単なべき級数 x + 2x2 + … + nxnを求めてみる
実演2の続き • 「定義ウインドウ」で,次を行いなさい (define (g1n) n) 2. その後,次の式を「対話ウインドウ」で評価させる (power-series2 3g1)
関数 series,power_series,g1 を定義している
これは, (power_series 2 3 g1) と書いて,xの値を 2に,nの値を 3に,gの値を g1に設定 評価結果である「34」が 表示される
実演.テーラ展開 -指数関数- power_seriesを使い,指数関数のテーラ展開式にもとづいた exの近似値を求める べき乗にかかる係数は (define (exp_termi) (/ 1 (!i)))
実演の手順 • 次を「定義用ウインドウ」に入力後,実行ボタンを押す ;; series: non-negative-integer (non-negative-integer -> number) ;; -> number ;; sum up the first n numbers in the sequence f ;; (series 2 f2) = (+ (f2 2) (+ (f2 1) (f2 0))) (define (series n f) (foldr + 0 (mapf (build-list (add1n) (lambda (x) x))))) ;; power_series: number N (N -> number) -> number (define (power_series x n g) (local ((define (power_term i) (* (g i) (exptx i)))) (series n power_term))) (define (!k) (cond [(= k 0) 1] [else (* k (! (- k 1)))])) (define (exp-termi) (/ 1 (!i))) (define (taylor-expx) (power_seriesx 10 exp-term)) 前 と同じ kの階乗 power_seriesを使い,ex を計算 (10項までの近似計算)
実演の手順 • その後,次を「対話ウインドウ」で評価させる (taylor-exp 0) (taylor-exp 1) (taylor-exp 2)
(define (taylor-expx) (power_seriesx 10 exp_term)) taylor-exp での誤差 x10/10! の項まで計算 誤差:x11/11! 以降 taylor級数第10項までの計算→ 確かに近似値 数値の先頭に #i → 限定的(inexact)表現(近似値)
実演.cos 関数のテーラ展開 power_seriesを使い,cos 関数のテーラ展開式に基づいた cos(x) の近似値を求める • 初項は第0項,奇数項の値は 0 と考える • kを iで割った余りは (remainder k i)
cos 関数のテーラ展開 (define (cos-term k) (cond [(odd? k) 0] [(= (remainder k 4) 0) (/ 1 (!k))] [else (/ -1 (!k))])])) odd?関数は 奇数ならば true
実演の手順 • 次を「定義用ウインドウ」に入力後,実行ボタンを押す ;; series: non-negative-integer (non-negative-integer -> number) ;; -> number ;; sum up the first n numbers in the sequence f ;; (series 2 f2) = (+ (f2 2) (+ (f2 1) (f2 0))) (define (series n f) (foldr + 0 (mapf (build-list (add1n) (lambda (x) x))))) ;; power_series: number N (N -> number) -> number (define (power_series x n g) (local ((define (power_term i) (* (g i) (exptx i)))) (series n power_term))) (define (!k) (cond [(= k 0) 1] [else (* k (! (- k 1)))])) (define (cos-term k) (cond [(odd? k) 0] [(= (remainder k 4) 0) (/ 1 (!k))] [else (/ -1 (!k))])) (define (taylor-cosx) (power_seriesx 10 cos-term)) 前 と同じ kの階乗 10項までの近似計算
実演の手順 • その後,次を「対話ウインドウ」で評価させる (taylor-cos0) (taylor-cos0.2) (taylor-cos0.4) (taylor-cos0.6) (taylor-cos0.8)
実演.対数関数のテーラ展開 power_series関数を使い,対数関数のテーラ展開式に基づいた近似値を求める
対数関数のテーラ展開 (define (log-termk) (cond [(=k 0) 0] [else (/ (expt -1 (- k 1)) k)]))
実演の手順 • 次を「定義用ウインドウ」に入力後,実行ボタンを押す ;; series: non-negative-integer (non-negative-integer -> number) ;; -> number ;; sum up the first n numbers in the sequence f ;; (series 2 f2) = (+ (f2 2) (+ (f2 1) (f2 0))) (define (series n f) (foldr + 0 (mapf (build-list (add1n) (lambda (x) x))))) ;; power_series: number N (N -> number) -> number (define (power_series x n g) (local ((define (power_term i) (* (g i) (exptx i)))) (series n power_term))) (define (log-termk) (cond [(=k 0) 0] [else (/ (expt -1 (- k 1)) k)])) (define (taylor-logx) (power_series (- x 1) 10 log-term)) 前 と同じ 10項までの近似計算
実演の手順 • その後,次を「対話ウインドウ」で評価させる (taylor-log 1) (taiyor-log 1.2) (taylor-log 1.4) (taylor-log 1.6) (taylor-log 1.8)
限定値(近似値) sin,cos,tan,log 等の実数についての関数は,コンピュータを使っても近似値しか求まらない コンピュータで計算/表現可能なデータは,範囲と精度に限りがある DrScheme の対話ウインドウ 数値の先頭に 「#i」 → 限定的(inexact)表現(近似値)
組込み関数 sin はもともと 結果を「近似値」として計算 どちらが 正確? 見易い? この「#i」は意図的な近似計算を指示 結果は「近似値」