Theory Montecarlo
section ‹ Examples›
subsection ‹Montecarlo Approximation›
theory Montecarlo
imports "Monad_QuasiBorel"
begin
declare [[coercion qbs_l]]
abbreviation real_quasi_borel :: "real quasi_borel" ("ℝ⇩Q") where
"real_quasi_borel ≡ qbs_borel"
abbreviation nat_quasi_borel :: "nat quasi_borel" ("ℕ⇩Q") where
"nat_quasi_borel ≡ qbs_count_space UNIV"
primrec montecarlo :: "'a qbs_measure ⇒ ('a ⇒ real) ⇒ nat ⇒ real qbs_measure" where
"montecarlo _ _ 0 = return_qbs ℝ⇩Q 0" |
"montecarlo d h (Suc n) = do { m ← montecarlo d h n;
x ← d;
return_qbs ℝ⇩Q ((h x + m * (real n)) / (real (Suc n)))}"
declare
bind_qbs_morphismP[qbs]
return_qbs_morphismP[qbs]
qbs_pair_measure_morphismP[qbs]
lemma montecarlo_qbs_morphism[qbs]: "montecarlo ∈ qbs_space (monadP_qbs X ⇒⇩Q (X ⇒⇩Q ℝ⇩Q) ⇒⇩Q ℕ⇩Q ⇒⇩Q monadP_qbs ℝ⇩Q)"
by(simp add: montecarlo_def)
lemma qbs_integrable_indep_mult2[simp, intro!]:
fixes f :: "_ ⇒ real"
assumes "qbs_integrable p f"
and "qbs_integrable q g"
shows "qbs_integrable (p ⨂⇩Q⇩m⇩e⇩s q) (λx. g (snd x) * f (fst x))"
using qbs_integrable_indep_mult[OF assms] by (simp add: mult.commute)
lemma montecarlo_integrable:
assumes [qbs]:"p ∈ qbs_space (monadP_qbs X)" "h ∈ X →⇩Q ℝ⇩Q" "qbs_integrable p h" "qbs_integrable p (λx. h x * h x)"
shows "qbs_integrable (montecarlo p h n) (λx. x)" "qbs_integrable (montecarlo p h n) (λx. x * x)"
proof -
have "qbs_integrable (montecarlo p h n) (λx. x) ∧ qbs_integrable (montecarlo p h n) (λx. x * x)"
proof(induction n)
case 0
then show ?case
by simp
next
case (Suc n)
hence 1[intro,simp]:"qbs_integrable (montecarlo p h n) (λx. x)" "qbs_integrable (montecarlo p h n) (λx. x * x)"
by simp_all
have 2[intro,simp]: "⋀q f. qbs_integrable q (λx. f x * f x) ⟹ qbs_integrable q (λx. f x * a * (f x * b))" for a b :: real
by(auto simp: mult.commute[of _ a] mult.assoc intro!: qbs_integrable_scaleR_left[where 'a=real,simplified] qbs_integrable_scaleR_right[where 'a=real,simplified]) (auto simp: mult.assoc[of _ _ b,symmetric] intro!: qbs_integrable_scaleR_left[where 'a=real,simplified])
show ?case
by(auto simp add: qbs_bind_bind_return2P'[of _ "ℝ⇩Q" X "ℝ⇩Q"] split_beta' qbs_pair_measure_def[OF qbs_space_monadPM qbs_space_monadPM,symmetric] qbs_integrable_bind_return[OF qbs_space_monadPM,of _ "ℝ⇩Q ⨂⇩Q X" _ "ℝ⇩Q"] comp_def distrib_right distrib_left intro!: qbs_integrable_indep_mult qbs_integrable_indep1[OF 1(1),of _ X] qbs_integrable_indep2[OF assms(3),of _ "ℝ⇩Q"] qbs_integrable_indep1[OF 1(2),of _ X] qbs_integrable_indep2[OF assms(4),of _ "ℝ⇩Q"] qbs_integrable_const[OF assms(1)] qbs_integrable_scaleR_left[where 'a=real,simplified] assms(3,4))
qed
thus "qbs_integrable (montecarlo p h n) (λx. x)" "qbs_integrable (montecarlo p h n) (λx. x * x)"
by simp_all
qed
lemma
fixes n :: nat
assumes [qbs]:"p ∈ qbs_space (monadP_qbs X)" "h ∈ X →⇩Q ℝ⇩Q" "qbs_integrable p h" "qbs_integrable p (λx. h x * h x)"
and e:"e > 0"
and "(∫⇩Q x. h x ∂p) = μ" "(∫⇩Q x. (h x - μ)⇧2 ∂p) = σ⇧2"
and n:"n > 0"
shows "𝒫(y in montecarlo p h n. ¦y - μ¦ ≥ e) ≤ σ⇧2 / (real n * e⇧2)" (is "?P ≤ _")
proof -
note [intro!] = montecarlo_integrable[OF assms(1-4)] qbs_integrable_indep_mult qbs_integrable_indep1[OF montecarlo_integrable(1)[OF assms(1-4)],of _ X] qbs_integrable_indep2[OF assms(3),of _ "ℝ⇩Q"] qbs_integrable_indep1[OF montecarlo_integrable(2)[OF assms(1-4)],of _ X] qbs_integrable_indep2[OF assms(4),of _ "ℝ⇩Q"] qbs_integrable_const[OF assms(1)] qbs_integrable_scaleR_right[where 'a=real,simplified] qbs_integrable_scaleR_left[where 'a=real,simplified] assms(3,4) qbs_integrable_sq qbs_integrable_const[of "montecarlo p h _ ⨂⇩Q⇩m⇩e⇩s p" "ℝ⇩Q ⨂⇩Q X"] qbs_integrable_const[of "montecarlo p h _" "ℝ⇩Q"]
have integrable[intro,simp]: "⋀q f. qbs_integrable q (λx. f x * f x) ⟹ qbs_integrable q (λx. f x * a * (f x * b))" for a b :: real
by(auto simp: mult.commute[of _ a] mult.assoc) (auto simp: mult.assoc[of _ _ b,symmetric])
have exp:"(∫⇩Q y. y ∂(montecarlo p h n)) = μ" (is "?e n") and var:"(∫⇩Q y. (y - μ)⇧2 ∂(montecarlo p h n)) = σ⇧2 / n" (is "?v n")
proof -
have "?e n ∧ ?v n"
using n
proof(induction n)
case 0
then show ?case
by simp
next
case ih:(Suc n)
consider "n = 0" | "n > 0" by auto
then show ?case
proof cases
case 1
then show ?thesis
by(auto simp: qbs_integral_indep2[OF qbs_integrable_sq[OF qbs_integrable_const[OF assms(1)] assms(3)],simplified power2_eq_square,OF assms(4),of _ qbs_borel] power2_eq_square qbs_bind_bind_return2P'[of _ "ℝ⇩Q" X "ℝ⇩Q"] split_beta' qbs_pair_measure_def[OF qbs_space_monadPM qbs_space_monadPM,symmetric] qbs_integral_bind_return[OF qbs_space_monadPM,of _ "ℝ⇩Q ⨂⇩Q X" _ "ℝ⇩Q"] comp_def qbs_integral_indep2[OF assms(3),of _ "ℝ⇩Q"] qbs_integral_indep2[OF assms(4),of _ "ℝ⇩Q"] assms(6,7)[simplified power2_eq_square])
next
case n[arith]:2
with ih have eq: "(∫⇩Q y. y ∂montecarlo p h n) = μ " "(∫⇩Q y. (y - μ)⇧2 ∂montecarlo p h n) = σ⇧2 / real n"
by simp_all
have 1:"?e (Suc n)"
proof -
have "(∫⇩Q x. h (snd x) + fst x * real n ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p)) = ((∫⇩Q x. h (snd x) ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p)) + (∫⇩Q x. fst x * real n ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p)))"
by(rule qbs_integral_add) auto
also have "... = μ + μ * n"
proof -
have "(∫⇩Q x. h (snd x) ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p)) = (∫⇩Q x. h x ∂p)"
by(auto intro!: qbs_integral_indep2[of _ _ _ "ℝ⇩Q"])
moreover have "(∫⇩Q x. fst x ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p)) = (∫⇩Q y. y ∂montecarlo p h n)"
by(auto intro!: qbs_integral_indep1[of _ _ _ X])
ultimately show ?thesis
by(simp add: eq assms)
qed
finally have "( ∫⇩Q y. y ∂montecarlo p h (Suc n)) = 1 / (Suc n) * (μ + μ * n)"
by(auto simp: qbs_bind_bind_return2P'[of _ "ℝ⇩Q" X "ℝ⇩Q"] split_beta' qbs_pair_measure_def[OF qbs_space_monadPM qbs_space_monadPM,symmetric] qbs_integral_bind_return[OF qbs_space_monadPM,of _ "ℝ⇩Q ⨂⇩Q X" _ "ℝ⇩Q"] comp_def)
also have "... = 1 / (Suc n) * (μ * (1 + real n))"
by(simp add: distrib_left)
also have "... = μ"
by simp
finally show ?thesis .
qed
have 2: "?v (Suc n)"
proof -
have "(∫⇩Q y. (y - μ)⇧2 ∂montecarlo p h (Suc n)) = (∫⇩Q x. ((h (snd x) + fst x * real n) / real (Suc n) - μ)⇧2 ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p))"
by(auto simp: qbs_bind_bind_return2P'[of _ "ℝ⇩Q" X "ℝ⇩Q"] split_beta' qbs_pair_measure_def[OF qbs_space_monadPM qbs_space_monadPM,symmetric] qbs_integral_bind_return[OF qbs_space_monadPM,of _ "ℝ⇩Q ⨂⇩Q X" _ "ℝ⇩Q"] comp_def)
also have "... = (∫⇩Q x. ((h (snd x) + fst x * real n) / real (Suc n) - (Suc n) * μ / Suc n)⇧2 ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p))"
by simp
also have "... = (∫⇩Q x. ((h (snd x) + fst x * real n - (Suc n) * μ) / Suc n)⇧2 ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p))"
by(simp only: diff_divide_distrib[symmetric])
also have "... = (∫⇩Q x. ((h (snd x) - μ + (fst x * real n - real n * μ)) / Suc n)⇧2 ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p))"
by (simp add: add_diff_add distrib_left mult.commute)
also have "... = (∫⇩Q x. (1 / real (Suc n) * (h (snd x) - μ) + n / real (Suc n) * (fst x - μ))⇧2 ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p))"
by(auto simp: add_divide_distrib[symmetric] pair_qbs_space mult.commute[of _ "real n"]) (simp add: right_diff_distrib)
also have "... = (∫⇩Q x. (1 / real (Suc n) * (h (snd x) - μ))⇧2 + (n / real (Suc n) * (fst x - μ))⇧2 + 2 * (1 / real (Suc n) * (h (snd x) - μ)) * (n / real (Suc n) * (fst x - μ)) ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p))"
by(simp add: power2_sum)
also have "... = (∫⇩Q x. 1 / (real (Suc n))⇧2 * ((h (snd x) - μ))⇧2 + (n / real (Suc n))⇧2 * ((fst x - μ))⇧2 + 2 * (1 / real (Suc n) * (h (snd x) - μ)) * (n / real (Suc n) * (fst x - μ)) ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p))"
by(simp only: power_mult_distrib) (simp add: power2_eq_square)
also have "... = (∫⇩Q x. 1 / (real (Suc n))⇧2 * ((h (snd x) - μ))⇧2 + (n / real (Suc n))⇧2 * ((fst x - μ))⇧2 ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p)) + (∫⇩Q x. 2 * (1 / real (Suc n) * (h (snd x) - μ)) * (n / real (Suc n) * (fst x - μ)) ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p))"
by(rule qbs_integral_add, auto) (auto simp: power2_eq_square)
also have "... = (∫⇩Q x. 1 / (real (Suc n))⇧2 * ((h (snd x) - μ))⇧2 ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p)) + (∫⇩Q x. (n / real (Suc n))⇧2 * ((fst x - μ))⇧2 ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p)) + (∫⇩Q x. 2 * (1 / real (Suc n) * (h (snd x) - μ)) * (n / real (Suc n) * (fst x - μ)) ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p))"
proof -
have "(∫⇩Q x. 1 / (real (Suc n))⇧2 * ((h (snd x) - μ))⇧2 + (n / real (Suc n))⇧2 * ((fst x - μ))⇧2 ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p)) = (∫⇩Q x. 1 / (real (Suc n))⇧2 * ((h (snd x) - μ))⇧2 ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p)) + (∫⇩Q x. (n / real (Suc n))⇧2 * ((fst x - μ))⇧2 ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p))"
by(rule qbs_integral_add, auto) (auto simp: power2_eq_square)
thus ?thesis by simp
qed
also have "... = 1 / (real (Suc n))⇧2 * σ⇧2 + (n / real (Suc n))⇧2 * (σ⇧2 / n)"
proof -
have 1: "(∫⇩Q x. ((h (snd x) - μ))⇧2 ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p)) = (∫⇩Q x. (h x - μ)⇧2 ∂p)"
by(auto intro!: qbs_integral_indep2[of _ _ _ "ℝ⇩Q"]) (auto simp: power2_eq_square)
have 2: "(∫⇩Q x. ((fst x - μ))⇧2 ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p)) = (∫⇩Q y. (y - μ)⇧2 ∂montecarlo p h n)"
by(auto intro!: qbs_integral_indep1[of _ _ _ X]) (auto simp: power2_eq_square)
have 3: "(∫⇩Q x. 2 * (1 / real (Suc n) * (h (snd x) - μ)) * (n / real (Suc n) * (fst x - μ)) ∂(montecarlo p h n ⨂⇩Q⇩m⇩e⇩s p)) = 0" (is "?l = _")
proof -
have "?l = (∫⇩Q x. 2 * (1 / real (Suc n) * (h x - μ)) ∂p) * (∫⇩Q x. (n / real (Suc n) * (x - μ)) ∂montecarlo p h n)"
by(rule qbs_integral_indep_mult2[of _ "ℝ⇩Q" _ X]) auto
also have "... = 0"
by(simp add: qbs_integral_diff[OF montecarlo_integrable(1)[OF assms(1-4)] qbs_integrable_const[of _ "ℝ⇩Q"]] eq qbs_integral_const_prob[of _ "ℝ⇩Q"])
finally show ?thesis .
qed
show ?thesis
unfolding 3 by(simp add: 1 2 eq assms)
qed
also have "... = 1 / (real (Suc n))⇧2 * σ⇧2 + real n / (real (Suc n))⇧2 * σ⇧2"
by(auto simp: power2_eq_square)
also have "... = (1 + real n) * σ⇧2 / (real (Suc n))⇧2"
by (simp add: add_divide_distrib ring_class.ring_distribs(2))
also have "... = σ⇧2 / real (Suc n)"
by(auto simp: power2_eq_square)
finally show ?thesis .
qed
show ?thesis
by(simp only: 1 2)
qed
qed
thus "?e n" "?v n" by simp_all
qed
have "?P ≤ (∫⇩Q x. (x - μ)⇧2 ∂montecarlo p h n) / e⇧2"
unfolding exp[symmetric] by(rule Chebyshev_inequality_qbs_prob[of "montecarlo p h n" qbs_borel "λx. x"]) (auto simp: power2_eq_square e)
also have "... = σ⇧2 / (real n * e⇧2)"
by(simp add: var)
finally show ?thesis .
qed
end