OCaml

練習問題 3.14 定積分の近似計算

練習問題 3.14

実数上の関数 f に対して定積分 S(a -> b) f(x)dx を近似計算する関数 integral f a b を定義しなさい。またこれを使って S(0 -> x) sin x dx を定義しなさい。
近似的な計算方法として、ここでは台形近似(図 3.6)を紹介します。(ほかの方法でもよいです)。台形近似では、a から b の区間を n 分割した区間の長さを θ として、台形の集まりとして計算します。i 番目の区間の台形の面積は
{( f ( a + ( i – 1 ) θ ) + f ( a + iθ)) ・θ} / 2
として求められます。

(* 練習問題 3-14 *)
(*
関数 f の 区間 a .. b 定積分を近似計算する関数を定義せよ。
integral f a b

近似計算 -- 台形近似をつかう
a から b の区間を n 分割した、その1つの区間の長さを s とすると、
i 番目の台形の面積は
( f(a + (i-1)s) + f(a + is) ) * s / 2

 *)
let abs (x:float) =
  if x < 0. then -1. *. x
  else x;;

let n = 10;;

let daikei (a, b, h) =
  (a +. b) *. h /. 2.;;

let test3 = daikei (2., 3., 4.) = 10.;;
  
let square x = x *. x;;

let test4 = square 3. = 9.;;

let rec sum_of (f, n) =
  if n = 0 then 0.
  else
    sum_of (f, (n-1)) +. f ;;

let test5 = sum_of ((square 2.), 3) = 12.;;

let integral f a b =
  let n = 100 in       (* 区間を100分割する *)
  let abs (x:float) = if x < 0. then -1. *. x else x in
    (* 100分割したうちの1区間の長さを求める *)
  let s = abs(a -. b) /. (float_of_int n) in
  let daikei (a, b, h) = (a +. b) *. h /. 2. in  (* 台形の面積 *)
  let rec keisan i =
    if i > n then 0.
    else
      let left = f (a +. float_of_int(i-1) *. s) in
      let right = f (a +. (float_of_int i) *. s) in
      keisan (i+1) +. daikei (left, right, s)
  in
  keisan 1;;

let test6 = integral square 1.0 2.0 = 2.5;;