Theory Sin_Cos_Bounds
chapter ‹Sine and Cosine Upper and Lower Bounds›
theory Sin_Cos_Bounds
imports Bounds_Lemmas
begin
section‹Simple base cases›
text‹Upper bound for @{term"x≥0"}›
lemma sin_le_arg:
fixes x :: real
shows "0 ≤ x ⟹ sin x ≤ x"
by (fact sin_x_le_x)
lemma cos_ge_1_arg:
fixes x :: real
assumes "0 ≤ x"
shows "1 - x ≤ cos x"
apply (rule gen_lower_bound_increasing [OF assms])
apply (intro derivative_eq_intros, auto)
done
lemmas sin_Taylor_0_upper_bound_pos = sin_le_arg
lemma cos_Taylor_1_lower_bound:
fixes x :: real
assumes "0 ≤ x"
shows "(1 - x^2 / 2) ≤ cos x"
apply (rule gen_lower_bound_increasing [OF assms])
apply (intro derivative_eq_intros)
apply (rule refl | simp add: sin_le_arg)+
done
lemma sin_Taylor_1_lower_bound:
fixes x :: real
assumes "0 ≤ x"
shows "(x - x ^ 3 / 6) ≤ sin x"
apply (rule gen_lower_bound_increasing [OF assms])
apply (intro derivative_eq_intros)
apply (rule refl | simp add: cos_Taylor_1_lower_bound)+
done
section‹Taylor series approximants›
definition sinpoly :: "[nat,real] ⇒ real"
where "sinpoly n = (λx. ∑k<n. sin_coeff k * x ^ k)"
definition cospoly :: "[nat,real] ⇒ real"
where "cospoly n = (λx. ∑k<n. cos_coeff k * x ^ k)"
lemma sinpoly_Suc: "sinpoly (Suc n) = (λx. sinpoly n x + sin_coeff n * x ^ n)"
by (simp add: sinpoly_def)
lemma cospoly_Suc: "cospoly (Suc n) = (λx. cospoly n x + cos_coeff n * x ^ n)"
by (simp add: cospoly_def)
lemma sinpoly_minus [simp]: "sinpoly n (-x) = - sinpoly n x"
by (induct n) (auto simp: sinpoly_def sin_coeff_def)
lemma cospoly_minus [simp]: "cospoly n (-x) = cospoly n x"
by (induct n) (auto simp: cospoly_def cos_coeff_def)
lemma d_sinpoly_cospoly:
"(sinpoly (Suc n) has_field_derivative cospoly n x) (at x)"
proof (induction n)
case 0 show ?case
by (simp add: sinpoly_def cospoly_def)
next
case (Suc n) show ?case
proof (cases "n=0")
case True then show ?thesis
by (simp add: sinpoly_def sin_coeff_def cospoly_def)
next
case False then
have xn: "x ^ (n - Suc 0) * x = x ^ n"
by (metis Suc_pred mult.commute not_gr0 power_Suc)
show ?thesis using Suc False
apply (simp add: sinpoly_Suc [of "Suc n"] cospoly_def)
apply (intro derivative_eq_intros | simp)+
apply (simp add: xn mult.assoc sin_coeff_def cos_coeff_def divide_simps del: fact_Suc)
apply (simp add: algebra_simps)
done
qed
qed
lemma d_cospoly_sinpoly:
"(cospoly (Suc n) has_field_derivative -sinpoly n x) (at x)"
proof (induction n)
case 0 show ?case
by (simp add: sinpoly_def cospoly_def)
next
case (Suc n) show ?case
proof (cases "n=0")
case True then show ?thesis
by (simp add: sinpoly_def cospoly_def cos_coeff_def)
next
case False then
have xn: "x ^ (n - Suc 0) * x = x ^ n"
by (metis Suc_pred mult.commute not_gr0 power_Suc)
have m1: "odd n ⟹ (-1 :: real) ^ ((n - Suc 0) div 2) = - ((-1) ^ (Suc n div 2))"
by (cases n) simp_all
show ?thesis using Suc False
apply (simp add: cospoly_Suc [of "Suc n"] sinpoly_def)
apply (intro derivative_eq_intros | simp)+
apply (simp add: xn mult.assoc sin_coeff_def cos_coeff_def m1 divide_simps del: fact_Suc)
apply (simp add: algebra_simps)
done
qed
qed
section‹Inductive proof of sine inequalities›
lemma sinpoly_lb_imp_cospoly_ub:
assumes x0: "0 ≤ x" and k0: "k>0" and "⋀x. 0 ≤ x ⟹ sinpoly (k - 1) x ≤ sin x"
shows "cos x ≤ cospoly k x"
apply (rule gen_lower_bound_increasing [OF x0])
apply (intro derivative_eq_intros | simp)+
using d_cospoly_sinpoly [of "k - 1"] assms
apply auto
apply (simp add: cospoly_def)
done
lemma cospoly_ub_imp_sinpoly_ub:
assumes x0: "0 ≤ x" and k0: "k>0" and "⋀x. 0 ≤ x ⟹ cos x ≤ cospoly (k - 1) x"
shows "sin x ≤ sinpoly k x"
apply (rule gen_lower_bound_increasing [OF x0])
apply (intro derivative_eq_intros | simp)+
using d_sinpoly_cospoly [of "k - 1"] assms
apply auto
apply (simp add: sinpoly_def)
done
lemma sinpoly_ub_imp_cospoly_lb:
assumes x0: "0 ≤ x" and k0: "k>0" and "⋀x. 0 ≤ x ⟹ sin x ≤ sinpoly (k - 1) x"
shows "cospoly k x ≤ cos x"
apply (rule gen_lower_bound_increasing [OF x0])
apply (intro derivative_eq_intros | simp)+
using d_cospoly_sinpoly [of "k - 1"] assms
apply auto
apply (simp add: cospoly_def)
done
lemma cospoly_lb_imp_sinpoly_lb:
assumes x0: "0 ≤ x" and k0: "k>0" and "⋀x. 0 ≤ x ⟹ cospoly (k - 1) x ≤ cos x"
shows "sinpoly k x ≤ sin x"
apply (rule gen_lower_bound_increasing [OF x0])
apply (intro derivative_eq_intros | simp)+
using d_sinpoly_cospoly [of "k - 1"] assms
apply auto
apply (simp add: sinpoly_def)
done
lemma
assumes "0 ≤ x"
shows sinpoly_lower_nonneg: "sinpoly (4 * Suc n) x ≤ sin x" (is ?th1)
and sinpoly_upper_nonneg: "sin x ≤ sinpoly (Suc (Suc (4*n))) x" (is ?th2)
proof -
have "sinpoly (4 * Suc n) x ≤ sin x ∧ sin x ≤ sinpoly (Suc (Suc (4*n))) x"
using assms
apply (induction n arbitrary: x)
apply (simp add: sinpoly_def sin_coeff_def sin_Taylor_1_lower_bound sin_Taylor_0_upper_bound_pos lessThan_nat_numeral fact_numeral)
apply (auto simp: cospoly_lb_imp_sinpoly_lb sinpoly_ub_imp_cospoly_lb cospoly_ub_imp_sinpoly_ub sinpoly_lb_imp_cospoly_ub)
done
then show ?th1 ?th2
using assms
by auto
qed
section‹Collecting the results›
corollary sinpoly_upper_nonpos:
"x ≤ 0 ⟹ sin x ≤ sinpoly (4 * Suc n) x"
using sinpoly_lower_nonneg [of "-x" n]
by simp
corollary sinpoly_lower_nonpos:
"x ≤ 0 ⟹ sinpoly (Suc (Suc (4*n))) x ≤ sin x"
using sinpoly_upper_nonneg [of "-x" n]
by simp
corollary cospoly_lower_nonneg:
"0 ≤ x ⟹ cospoly (Suc (Suc (Suc (4*n)))) x ≤ cos x"
by (auto simp: sinpoly_upper_nonneg sinpoly_ub_imp_cospoly_lb)
lemma cospoly_lower:
"cospoly (Suc (Suc (Suc (4*n)))) x ≤ cos x"
proof (cases rule: le_cases [of 0 x])
case le then show ?thesis
by (simp add: cospoly_lower_nonneg)
next
case ge then show ?thesis using cospoly_lower_nonneg [of "-x"]
by simp
qed
lemma cospoly_upper_nonneg:
assumes "0 ≤ x"
shows "cos x ≤ cospoly (Suc (4*n)) x"
proof (cases n)
case 0 then show ?thesis
by (simp add: cospoly_def)
next
case (Suc m)
then show ?thesis
using sinpoly_lower_nonneg [of _ m] assms
by (auto simp: sinpoly_lb_imp_cospoly_ub)
qed
lemma cospoly_upper:
"cos x ≤ cospoly (Suc (4*n)) x"
proof (cases rule: le_cases [of 0 x])
case le then show ?thesis
by (simp add: cospoly_upper_nonneg)
next
case ge then show ?thesis using cospoly_upper_nonneg [of "-x"]
by simp
qed
end