| author | wenzelm | 
| Mon, 03 Feb 2025 11:51:48 +0100 | |
| changeset 82062 | 73243fbfed5d | 
| parent 72222 | 01397b6e5eb0 | 
| child 82967 | 73af47bc277c | 
| permissions | -rw-r--r-- | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 1 | section \<open>Numeric approximations to Constants\<close> | 
| 59871 
e1a49ac9c537
John Harrison's example: a 32-bit approximation to pi. SLOW
 paulson <lp15@cam.ac.uk> parents: diff
changeset | 2 | |
| 
e1a49ac9c537
John Harrison's example: a 32-bit approximation to pi. SLOW
 paulson <lp15@cam.ac.uk> parents: diff
changeset | 3 | theory Approximations | 
| 66453 
cc19f7ca2ed6
session-qualified theory imports: isabelle imports -U -i -d '~~/src/Benchmarks' -a;
 wenzelm parents: 
64272diff
changeset | 4 | imports "HOL-Analysis.Complex_Transcendental" "HOL-Analysis.Harmonic_Numbers" | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 5 | begin | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 6 | |
| 62089 | 7 | text \<open> | 
| 8 | In this theory, we will approximate some standard mathematical constants with high precision, | |
| 9 | using only Isabelle's simplifier. (no oracles, code generator, etc.) | |
| 10 | ||
| 11 | The constants we will look at are: $\pi$, $e$, $\ln 2$, and $\gamma$ (the Euler--Mascheroni | |
| 12 | constant). | |
| 13 | \<close> | |
| 14 | ||
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 15 | lemma eval_fact: | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 16 | "fact 0 = 1" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 17 | "fact (Suc 0) = 1" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 18 | "fact (numeral n) = numeral n * fact (pred_numeral n)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 19 | by (simp, simp, simp_all only: numeral_eq_Suc fact_Suc, | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 20 | simp only: numeral_eq_Suc [symmetric] of_nat_numeral) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 21 | |
| 64267 | 22 | lemma sum_poly_horner_expand: | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 23 | "(\<Sum>k<(numeral n::nat). f k * x^k) = f 0 + (\<Sum>k<pred_numeral n. f (k+1) * x^k) * x" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 24 | "(\<Sum>k<Suc 0. f k * x^k) = (f 0 :: 'a :: semiring_1)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 25 | "(\<Sum>k<(0::nat). f k * x^k) = 0" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 26 | proof - | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 27 |   {
 | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 28 | fix m :: nat | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 29 | have "(\<Sum>k<Suc m. f k * x^k) = f 0 + (\<Sum>k=Suc 0..<Suc m. f k * x^k)" | 
| 70097 
4005298550a6
The last big tranche of Homology material: invariance of domain; renamings to use generic sum/prod lemmas from their locale
 paulson <lp15@cam.ac.uk> parents: 
69597diff
changeset | 30 | by (subst atLeast0LessThan [symmetric], subst sum.atLeast_Suc_lessThan) simp_all | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 31 | also have "(\<Sum>k=Suc 0..<Suc m. f k * x^k) = (\<Sum>k<m. f (k+1) * x^k) * x" | 
| 70113 
c8deb8ba6d05
Fixing the main Homology theory; also moving a lot of sum/prod lemmas into their generic context
 paulson <lp15@cam.ac.uk> parents: 
70097diff
changeset | 32 | by (subst sum.shift_bounds_Suc_ivl) | 
| 64267 | 33 | (simp add: sum_distrib_right algebra_simps atLeast0LessThan power_commutes) | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 34 | finally have "(\<Sum>k<Suc m. f k * x ^ k) = f 0 + (\<Sum>k<m. f (k + 1) * x ^ k) * x" . | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 35 | } | 
| 62089 | 36 | from this[of "pred_numeral n"] | 
| 37 | show "(\<Sum>k<numeral n. f k * x^k) = f 0 + (\<Sum>k<pred_numeral n. f (k+1) * x^k) * x" | |
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 38 | by (simp add: numeral_eq_Suc) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 39 | qed simp_all | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 40 | |
| 62089 | 41 | lemma power_less_one: | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 42 | assumes "n > 0" "x \<ge> 0" "x < 1" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 43 | shows "x ^ n < (1::'a::linordered_semidom)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 44 | proof - | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 45 | from assms consider "x > 0" | "x = 0" by force | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 46 | thus ?thesis | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 47 | proof cases | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 48 | assume "x > 0" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 49 | with assms show ?thesis | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 50 | by (cases n) (simp, hypsubst, rule power_Suc_less_one) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 51 | qed (insert assms, cases n, simp_all) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 52 | qed | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 53 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 54 | lemma combine_bounds: | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 55 |   "x \<in> {a1..b1} \<Longrightarrow> y \<in> {a2..b2} \<Longrightarrow> a3 = a1 + a2 \<Longrightarrow> b3 = b1 + b2 \<Longrightarrow> x + y \<in> {a3..(b3::real)}"
 | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 56 |   "x \<in> {a1..b1} \<Longrightarrow> y \<in> {a2..b2} \<Longrightarrow> a3 = a1 - b2 \<Longrightarrow> b3 = b1 - a2 \<Longrightarrow> x - y \<in> {a3..(b3::real)}"
 | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 57 |   "c \<ge> 0 \<Longrightarrow> x \<in> {a..b} \<Longrightarrow> c * x \<in> {c*a..c*b}"
 | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 58 | by (auto simp: mult_left_mono) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 59 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 60 | lemma approx_coarsen: | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 61 | "\<bar>x - a1\<bar> \<le> eps1 \<Longrightarrow> \<bar>a1 - a2\<bar> \<le> eps2 - eps1 \<Longrightarrow> \<bar>x - a2\<bar> \<le> (eps2 :: real)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 62 | by simp | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 63 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 64 | |
| 62089 | 65 | |
| 66 | subsection \<open>Approximations of the exponential function\<close> | |
| 67 | ||
| 68 | lemma two_power_fact_le_fact: | |
| 69 | assumes "n \<ge> 1" | |
| 70 |   shows   "2^k * fact n \<le> (fact (n + k) :: 'a :: {semiring_char_0,linordered_semidom})"
 | |
| 71 | proof (induction k) | |
| 72 | case (Suc k) | |
| 73 | have "2 ^ Suc k * fact n = 2 * (2 ^ k * fact n)" by (simp add: algebra_simps) | |
| 74 | also note Suc.IH | |
| 75 | also from assms have "of_nat 1 + of_nat 1 \<le> of_nat n + (of_nat (Suc k) :: 'a)" | |
| 76 | by (intro add_mono) (unfold of_nat_le_iff, simp_all) | |
| 77 | hence "2 * (fact (n + k) :: 'a) \<le> of_nat (n + Suc k) * fact (n + k)" | |
| 78 | by (intro mult_right_mono) (simp_all add: add_ac) | |
| 79 | also have "\<dots> = fact (n + Suc k)" by simp | |
| 80 | finally show ?case by - (simp add: mult_left_mono) | |
| 81 | qed simp_all | |
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 82 | |
| 62089 | 83 | text \<open> | 
| 84 | We approximate the exponential function with inputs between $0$ and $2$ by its | |
| 85 | Taylor series expansion and bound the error term with $0$ from below and with a | |
| 86 | geometric series from above. | |
| 87 | \<close> | |
| 88 | lemma exp_approx: | |
| 89 | assumes "n > 0" "0 \<le> x" "x < 2" | |
| 90 |   shows   "exp (x::real) - (\<Sum>k<n. x^k / fact k) \<in> {0..(2 * x^n / (2 - x)) / fact n}"
 | |
| 91 | proof (unfold atLeastAtMost_iff, safe) | |
| 63040 | 92 | define approx where "approx = (\<Sum>k<n. x^k / fact k)" | 
| 62089 | 93 | have "(\<lambda>k. x^k / fact k) sums exp x" | 
| 94 | using exp_converges[of x] by (simp add: field_simps) | |
| 95 | from sums_split_initial_segment[OF this, of n] | |
| 96 | have sums: "(\<lambda>k. x^n * (x^k / fact (n+k))) sums (exp x - approx)" | |
| 97 | by (simp add: approx_def algebra_simps power_add) | |
| 98 | ||
| 99 | from assms show "(exp x - approx) \<ge> 0" | |
| 100 | by (intro sums_le[OF _ sums_zero sums]) auto | |
| 59871 
e1a49ac9c537
John Harrison's example: a 32-bit approximation to pi. SLOW
 paulson <lp15@cam.ac.uk> parents: diff
changeset | 101 | |
| 72222 | 102 | have "x^n * (x^k / fact (n+k)) \<le> (x^n / fact n) * (x / 2)^k" for k::nat | 
| 103 | proof - | |
| 62089 | 104 | have "x^n * (x^k / fact (n + k)) = x^(n+k) / fact (n + k)" by (simp add: power_add) | 
| 105 | also from assms have "\<dots> \<le> x^(n+k) / (2^k * fact n)" | |
| 106 | by (intro divide_left_mono two_power_fact_le_fact zero_le_power) simp_all | |
| 107 | also have "\<dots> = (x^n / fact n) * (x / 2) ^ k" | |
| 108 | by (simp add: field_simps power_add) | |
| 109 | finally show "x^n * (x^k / fact (n+k)) \<le> (x^n / fact n) * (x / 2)^k" . | |
| 110 | qed | |
| 111 | moreover note sums | |
| 112 |   moreover {
 | |
| 113 | from assms have "(\<lambda>k. (x^n / fact n) * (x / 2)^k) sums ((x^n / fact n) * (1 / (1 - x / 2)))" | |
| 114 | by (intro sums_mult geometric_sums) simp_all | |
| 115 | also from assms have "((x^n / fact n) * (1 / (1 - x / 2))) = (2 * x^n / (2 - x)) / fact n" | |
| 70817 
dd675800469d
dedicated fact collections for algebraic simplification rules potentially splitting goals
 haftmann parents: 
70114diff
changeset | 116 | by (auto simp: field_split_simps) | 
| 62089 | 117 | finally have "(\<lambda>k. (x^n / fact n) * (x / 2)^k) sums \<dots>" . | 
| 118 | } | |
| 119 | ultimately show "(exp x - approx) \<le> (2 * x^n / (2 - x)) / fact n" | |
| 120 | by (rule sums_le) | |
| 121 | qed | |
| 122 | ||
| 123 | text \<open> | |
| 124 | The following variant gives a simpler error estimate for inputs between $0$ and $1$: | |
| 125 | \<close> | |
| 126 | lemma exp_approx': | |
| 127 | assumes "n > 0" "0 \<le> x" "x \<le> 1" | |
| 128 | shows "\<bar>exp (x::real) - (\<Sum>k\<le>n. x^k / fact k)\<bar> \<le> x ^ n / fact n" | |
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 129 | proof - | 
| 62089 | 130 | from assms have "x^n / (2 - x) \<le> x^n / 1" by (intro frac_le) simp_all | 
| 131 | hence "(2 * x^n / (2 - x)) / fact n \<le> 2 * x^n / fact n" | |
| 70817 
dd675800469d
dedicated fact collections for algebraic simplification rules potentially splitting goals
 haftmann parents: 
70114diff
changeset | 132 | using assms by (simp add: field_split_simps) | 
| 62089 | 133 | with exp_approx[of n x] assms | 
| 134 |     have "exp (x::real) - (\<Sum>k<n. x^k / fact k) \<in> {0..2 * x^n / fact n}" by simp
 | |
| 135 | moreover have "(\<Sum>k\<le>n. x^k / fact k) = (\<Sum>k<n. x^k / fact k) + x ^ n / fact n" | |
| 136 | by (simp add: lessThan_Suc_atMost [symmetric]) | |
| 137 | ultimately show "\<bar>exp (x::real) - (\<Sum>k\<le>n. x^k / fact k)\<bar> \<le> x ^ n / fact n" | |
| 138 | unfolding atLeastAtMost_iff by linarith | |
| 139 | qed | |
| 140 | ||
| 141 | text \<open> | |
| 142 | By adding $x^n / n!$ to the approximation (i.e. taking one more term from the | |
| 143 | Taylor series), one can get the error bound down to $x^n / n!$. | |
| 144 | ||
| 145 | This means that the number of accurate binary digits produced by the approximation is | |
| 146 | asymptotically equal to $(n \log n - n) / \log 2$ by Stirling's formula. | |
| 147 | \<close> | |
| 148 | lemma exp_approx'': | |
| 149 | assumes "n > 0" "0 \<le> x" "x \<le> 1" | |
| 150 | shows "\<bar>exp (x::real) - (\<Sum>k\<le>n. x^k / fact k)\<bar> \<le> 1 / fact n" | |
| 151 | proof - | |
| 152 | from assms have "\<bar>exp x - (\<Sum>k\<le>n. x ^ k / fact k)\<bar> \<le> x ^ n / fact n" | |
| 153 | by (rule exp_approx') | |
| 70817 
dd675800469d
dedicated fact collections for algebraic simplification rules potentially splitting goals
 haftmann parents: 
70114diff
changeset | 154 | also from assms have "\<dots> \<le> 1 / fact n" by (simp add: field_split_simps power_le_one) | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 155 | finally show ?thesis . | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 156 | qed | 
| 59871 
e1a49ac9c537
John Harrison's example: a 32-bit approximation to pi. SLOW
 paulson <lp15@cam.ac.uk> parents: diff
changeset | 157 | |
| 62089 | 158 | |
| 159 | text \<open> | |
| 160 | We now define an approximation function for Euler's constant $e$. | |
| 161 | \<close> | |
| 162 | ||
| 163 | definition euler_approx :: "nat \<Rightarrow> real" where | |
| 164 | "euler_approx n = (\<Sum>k\<le>n. inverse (fact k))" | |
| 165 | ||
| 166 | definition euler_approx_aux :: "nat \<Rightarrow> nat" where | |
| 167 |   "euler_approx_aux n = (\<Sum>k\<le>n. \<Prod>{k + 1..n})"
 | |
| 168 | ||
| 169 | lemma exp_1_approx: | |
| 170 | "n > 0 \<Longrightarrow> \<bar>exp (1::real) - euler_approx n\<bar> \<le> 1 / fact n" | |
| 70817 
dd675800469d
dedicated fact collections for algebraic simplification rules potentially splitting goals
 haftmann parents: 
70114diff
changeset | 171 | using exp_approx''[of n 1] by (simp add: euler_approx_def field_split_simps) | 
| 62089 | 172 | |
| 173 | text \<open> | |
| 174 | The following allows us to compute the numerator and the denominator of the result | |
| 175 | separately, which greatly reduces the amount of rational number arithmetic that we | |
| 176 | have to do. | |
| 177 | \<close> | |
| 178 | lemma euler_approx_altdef [code]: | |
| 179 | "euler_approx n = real (euler_approx_aux n) / real (fact n)" | |
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 180 | proof - | 
| 62089 | 181 |   have "real (\<Sum>k\<le>n. \<Prod>{k+1..n}) = (\<Sum>k\<le>n. \<Prod>i=k+1..n. real i)" by simp
 | 
| 182 | also have "\<dots> / fact n = (\<Sum>k\<le>n. 1 / (fact n / (\<Prod>i=k+1..n. real i)))" | |
| 64267 | 183 | by (simp add: sum_divide_distrib) | 
| 62089 | 184 | also have "\<dots> = (\<Sum>k\<le>n. 1 / fact k)" | 
| 64267 | 185 | proof (intro sum.cong refl) | 
| 62089 | 186 |     fix k assume k: "k \<in> {..n}"
 | 
| 64272 | 187 | have "fact n = (\<Prod>i=1..n. real i)" by (simp add: fact_prod) | 
| 62089 | 188 |     also from k have "{1..n} = {1..k} \<union> {k+1..n}" by auto
 | 
| 64272 | 189 | also have "prod real \<dots> / (\<Prod>i=k+1..n. real i) = (\<Prod>i=1..k. real i)" | 
| 190 | by (subst nonzero_divide_eq_eq, simp, subst prod.union_disjoint [symmetric]) auto | |
| 191 | also have "\<dots> = fact k" by (simp add: fact_prod) | |
| 192 |     finally show "1 / (fact n / prod real {k + 1..n}) = 1 / fact k" by simp
 | |
| 62089 | 193 | qed | 
| 194 | also have "\<dots> = euler_approx n" by (simp add: euler_approx_def field_simps) | |
| 195 | finally show ?thesis by (simp add: euler_approx_aux_def) | |
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 196 | qed | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 197 | |
| 62089 | 198 | lemma euler_approx_aux_Suc: | 
| 199 | "euler_approx_aux (Suc m) = 1 + Suc m * euler_approx_aux m" | |
| 200 | unfolding euler_approx_aux_def | |
| 70114 | 201 | by (subst sum_distrib_left) (simp add: atLeastAtMostSuc_conv mult.commute) | 
| 62089 | 202 | |
| 203 | lemma eval_euler_approx_aux: | |
| 204 | "euler_approx_aux 0 = 1" | |
| 205 | "euler_approx_aux 1 = 2" | |
| 206 | "euler_approx_aux (Suc 0) = 2" | |
| 207 | "euler_approx_aux (numeral n) = 1 + numeral n * euler_approx_aux (pred_numeral n)" (is "?th") | |
| 208 | proof - | |
| 209 | have A: "euler_approx_aux (Suc m) = 1 + Suc m * euler_approx_aux m" for m :: nat | |
| 210 | unfolding euler_approx_aux_def | |
| 70114 | 211 | by (subst sum_distrib_left) (simp add: atLeastAtMostSuc_conv mult.commute) | 
| 62089 | 212 | show ?th by (subst numeral_eq_Suc, subst A, subst numeral_eq_Suc [symmetric]) simp | 
| 213 | qed (simp_all add: euler_approx_aux_def) | |
| 214 | ||
| 215 | lemma euler_approx_aux_code [code]: | |
| 216 | "euler_approx_aux n = (if n = 0 then 1 else 1 + n * euler_approx_aux (n - 1))" | |
| 217 | by (cases n) (simp_all add: eval_euler_approx_aux euler_approx_aux_Suc) | |
| 218 | ||
| 219 | lemmas eval_euler_approx = euler_approx_altdef eval_euler_approx_aux | |
| 220 | ||
| 221 | ||
| 222 | text \<open>Approximations of $e$ to 60 decimals / 128 and 64 bits:\<close> | |
| 223 | ||
| 224 | lemma euler_60_decimals: | |
| 225 | "\<bar>exp 1 - 2.718281828459045235360287471352662497757247093699959574966968\<bar> | |
| 226 | \<le> inverse (10^60::real)" | |
| 227 | by (rule approx_coarsen, rule exp_1_approx[of 48]) | |
| 228 | (simp_all add: eval_euler_approx eval_fact) | |
| 229 | ||
| 230 | lemma euler_128: | |
| 231 | "\<bar>exp 1 - 924983374546220337150911035843336795079 / 2 ^ 128\<bar> \<le> inverse (2 ^ 128 :: real)" | |
| 232 | by (rule approx_coarsen[OF euler_60_decimals]) simp_all | |
| 233 | ||
| 234 | lemma euler_64: | |
| 235 | "\<bar>exp 1 - 50143449209799256683 / 2 ^ 64\<bar> \<le> inverse (2 ^ 64 :: real)" | |
| 236 | by (rule approx_coarsen[OF euler_128]) simp_all | |
| 237 | ||
| 238 | text \<open> | |
| 239 | An approximation of $e$ to 60 decimals. This is about as far as we can go with the | |
| 240 | simplifier with this kind of setup; the exported code of the code generator, on the other | |
| 241 | hand, can easily approximate $e$ to 1000 decimals and verify that approximation within | |
| 242 | fractions of a second. | |
| 243 | \<close> | |
| 244 | ||
| 245 | (* (Uncommented because we don't want to use the code generator; | |
| 246 | don't forget to import Code\_Target\_Numeral)) *) | |
| 247 | (* | |
| 248 | lemma "\<bar>exp 1 - 2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174135966290435729003342952605956307381323286279434907632338298807531952510190115738341879307021540891499348841675092447614606680822648001684774118537423454424371075390777449920695517027618386062613313845830007520449338265602976067371132007093287091274437470472306969772093101416928368190255151086574637721112523897844250569536967707854499699679468644549059879316368892300987931277361782154249992295763514822082698951936680331825288693984964651058209392398294887933203625094431173012381970684161403970198376793206832823764648042953118023287825098194558153017567173613320698112509961818815930416903515988885193458072738667385894228792284998920868058257492796104841984443634632449684875602336248270419786232090021609902353043699418491463140934317381436405462531520961836908887070167683964243781405927145635490613031072085103837505101157477041718986106873969655212671546889570350354021\<bar> | |
| 249 | \<le> inverse (10^1000::real)" | |
| 250 | by (rule approx_coarsen, rule exp_1_approx[of 450], simp) eval | |
| 251 | *) | |
| 252 | ||
| 253 | ||
| 254 | subsection \<open>Approximation of $\ln 2$\<close> | |
| 255 | ||
| 256 | text \<open> | |
| 257 | The following three auxiliary constants allow us to force the simplifier to | |
| 258 | evaluate intermediate results, simulating call-by-value. | |
| 259 | \<close> | |
| 260 | ||
| 261 | definition "ln_approx_aux3 x' e n y d \<longleftrightarrow> | |
| 262 | \<bar>(2 * y) * (\<Sum>k<n. inverse (real (2*k+1)) * (y^2)^k) + d - x'\<bar> \<le> e - d" | |
| 263 | definition "ln_approx_aux2 x' e n y \<longleftrightarrow> | |
| 264 | ln_approx_aux3 x' e n y (y^(2*n+1) / (1 - y^2) / real (2*n+1))" | |
| 265 | definition "ln_approx_aux1 x' e n x \<longleftrightarrow> | |
| 266 | ln_approx_aux2 x' e n ((x - 1) / (x + 1))" | |
| 267 | ||
| 268 | lemma ln_approx_abs'': | |
| 269 | fixes x :: real and n :: nat | |
| 270 | defines "y \<equiv> (x-1)/(x+1)" | |
| 271 | defines "approx \<equiv> (\<Sum>k<n. 2*y^(2*k+1) / of_nat (2*k+1))" | |
| 272 | defines "d \<equiv> y^(2*n+1) / (1 - y^2) / of_nat (2*n+1)" | |
| 273 | assumes x: "x > 1" | |
| 274 | assumes A: "ln_approx_aux1 x' e n x" | |
| 275 | shows "\<bar>ln x - x'\<bar> \<le> e" | |
| 276 | proof (rule approx_coarsen[OF ln_approx_abs[OF x, of n]], goal_cases) | |
| 277 | case 1 | |
| 278 | from A have "\<bar>2 * y * (\<Sum>k<n. inverse (real (2 * k + 1)) * y\<^sup>2 ^ k) + d - x'\<bar> \<le> e - d" | |
| 279 | by (simp only: ln_approx_aux3_def ln_approx_aux2_def ln_approx_aux1_def | |
| 280 | y_def [symmetric] d_def [symmetric]) | |
| 281 | also have "2 * y * (\<Sum>k<n. inverse (real (2 * k + 1)) * y\<^sup>2 ^ k) = | |
| 282 | (\<Sum>k<n. 2 * y^(2*k+1) / (real (2 * k + 1)))" | |
| 64267 | 283 | by (subst sum_distrib_left, simp, subst power_mult) | 
| 70817 
dd675800469d
dedicated fact collections for algebraic simplification rules potentially splitting goals
 haftmann parents: 
70114diff
changeset | 284 | (simp_all add: field_split_simps mult_ac power_mult) | 
| 62089 | 285 | finally show ?case by (simp only: d_def y_def approx_def) | 
| 286 | qed | |
| 287 | ||
| 288 | text \<open> | |
| 289 | We unfold the above three constants successively and then compute the | |
| 290 | sum using a Horner scheme. | |
| 291 | \<close> | |
| 292 | lemma ln_2_40_decimals: | |
| 293 | "\<bar>ln 2 - 0.6931471805599453094172321214581765680755\<bar> | |
| 294 | \<le> inverse (10^40 :: real)" | |
| 295 | apply (rule ln_approx_abs''[where n = 40], simp) | |
| 296 | apply (simp, simp add: ln_approx_aux1_def) | |
| 297 | apply (simp add: ln_approx_aux2_def power2_eq_square power_divide) | |
| 298 | apply (simp add: ln_approx_aux3_def power2_eq_square) | |
| 64267 | 299 | apply (simp add: sum_poly_horner_expand) | 
| 62089 | 300 | done | 
| 301 | ||
| 302 | lemma ln_2_128: | |
| 303 | "\<bar>ln 2 - 235865763225513294137944142764154484399 / 2 ^ 128\<bar> \<le> inverse (2 ^ 128 :: real)" | |
| 304 | by (rule approx_coarsen[OF ln_2_40_decimals]) simp_all | |
| 305 | ||
| 306 | lemma ln_2_64: | |
| 307 | "\<bar>ln 2 - 12786308645202655660 / 2 ^ 64\<bar> \<le> inverse (2 ^ 64 :: real)" | |
| 308 | by (rule approx_coarsen[OF ln_2_128]) simp_all | |
| 309 | ||
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 310 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 311 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 312 | subsection \<open>Approximation of the Euler--Mascheroni constant\<close> | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 313 | |
| 62089 | 314 | text \<open> | 
| 315 | Unfortunatly, the best approximation we have formalised for the Euler--Mascheroni | |
| 316 | constant converges only quadratically. This is too slow to compute more than a | |
| 317 | few decimals, but we can get almost 4 decimals / 14 binary digits this way, | |
| 318 | which is not too bad. | |
| 319 | \<close> | |
| 320 | lemma euler_mascheroni_approx: | |
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 321 | defines "approx \<equiv> 0.577257 :: real" and "e \<equiv> 0.000063 :: real" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 322 | shows "abs (euler_mascheroni - approx :: real) < e" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 323 | (is "abs (_ - ?approx) < ?e") | 
| 59871 
e1a49ac9c537
John Harrison's example: a 32-bit approximation to pi. SLOW
 paulson <lp15@cam.ac.uk> parents: diff
changeset | 324 | proof - | 
| 63040 | 325 | define l :: real | 
| 326 | where "l = 47388813395531028639296492901910937/82101866951584879688289000000000000" | |
| 327 | define u :: real | |
| 328 | where "u = 142196984054132045946501548559032969 / 246305600854754639064867000000000000" | |
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 329 | have impI: "P \<longrightarrow> Q" if Q for P Q using that by blast | 
| 63040 | 330 | have hsum_63: "harm 63 = (310559566510213034489743057 / 65681493561267903750631200 :: real)" | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 331 | by (simp add: harm_expand) | 
| 62089 | 332 | from harm_Suc[of 63] have hsum_64: "harm 64 = | 
| 333 | 623171679694215690971693339 / (131362987122535807501262400::real)" | |
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 334 | by (subst (asm) hsum_63) simp | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 335 | have "ln (64::real) = real (6::nat) * ln 2" by (subst ln_realpow[symmetric]) simp_all | 
| 62089 | 336 |   hence "ln (real_of_nat (Suc 63)) \<in> {4.158883083293<..<4.158883083367}" using ln_2_64
 | 
| 62390 | 337 | by (simp add: abs_real_def split: if_split_asm) | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 338 | from euler_mascheroni_bounds'[OF _ this] | 
| 62089 | 339 |     have "(euler_mascheroni :: real) \<in> {l<..<u}"
 | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 340 | by (simp add: hsum_63 del: greaterThanLessThan_iff) (simp only: l_def u_def) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 341 |   also have "\<dots> \<subseteq> {approx - e<..<approx + e}"
 | 
| 62089 | 342 | by (subst greaterThanLessThan_subseteq_greaterThanLessThan, rule impI) | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 343 | (simp add: approx_def e_def u_def l_def) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 344 | finally show ?thesis by (simp add: abs_real_def) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 345 | qed | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 346 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 347 | |
| 62089 | 348 | |
| 349 | subsection \<open>Approximation of pi\<close> | |
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 350 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 351 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 352 | subsubsection \<open>Approximating the arctangent\<close> | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 353 | |
| 62089 | 354 | text\<open> | 
| 355 | The arctangent can be used to approximate pi. Fortunately, its Taylor series expansion | |
| 356 | converges exponentially for small values, so we can get $\Theta(n)$ digits of precision | |
| 357 | with $n$ summands of the expansion. | |
| 358 | \<close> | |
| 359 | ||
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 360 | definition arctan_approx where | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 361 | "arctan_approx n x = x * (\<Sum>k<n. (-(x^2))^k / real (2*k+1))" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 362 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 363 | lemma arctan_series': | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 364 | assumes "\<bar>x\<bar> \<le> 1" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 365 | shows "(\<lambda>k. (-1)^k * (1 / real (k*2+1) * x ^ (k*2+1))) sums arctan x" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 366 | using summable_arctan_series[OF assms] arctan_series[OF assms] by (simp add: sums_iff) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 367 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 368 | lemma arctan_approx: | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 369 | assumes x: "0 \<le> x" "x < 1" and n: "even n" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 370 |   shows   "arctan x - arctan_approx n x \<in> {0..x^(2*n+1) / (1-x^4)}"
 | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 371 | proof - | 
| 63040 | 372 | define c where "c k = 1 / (1+(4*real k + 2*real n)) - x\<^sup>2 / (3+(4*real k + 2*real n))" for k | 
| 62089 | 373 | from assms have "(\<lambda>k. (-1) ^ k * (1 / real (k * 2 + 1) * x^(k*2+1))) sums arctan x" | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 374 | using arctan_series' by simp | 
| 62089 | 375 | also have "(\<lambda>k. (-1) ^ k * (1 / real (k * 2 + 1) * x^(k*2+1))) = | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 376 | (\<lambda>k. x * ((- (x^2))^k / real (2*k+1)))" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 377 | by (simp add: power2_eq_square power_mult power_mult_distrib mult_ac power_minus') | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 378 | finally have "(\<lambda>k. x * ((- x\<^sup>2) ^ k / real (2 * k + 1))) sums arctan x" . | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 379 | from sums_split_initial_segment[OF this, of n] | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 380 | have "(\<lambda>i. x * ((- x\<^sup>2) ^ (i + n) / real (2 * (i + n) + 1))) sums | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 381 | (arctan x - arctan_approx n x)" | 
| 64267 | 382 | by (simp add: arctan_approx_def sum_distrib_left) | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 383 | from sums_group[OF this, of 2] assms | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 384 | have sums: "(\<lambda>k. x * (x\<^sup>2)^n * (x^4)^k * c k) sums (arctan x - arctan_approx n x)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 385 | by (simp add: algebra_simps power_add power_mult [symmetric] c_def) | 
| 62089 | 386 | |
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 387 | from assms have "0 \<le> arctan x - arctan_approx n x" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 388 | by (intro sums_le[OF _ sums_zero sums] allI mult_nonneg_nonneg) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 389 | (auto intro!: frac_le power_le_one simp: c_def) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 390 |   moreover {
 | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 391 | from assms have "c k \<le> 1 - 0" for k unfolding c_def | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 392 | by (intro diff_mono divide_nonneg_nonneg add_nonneg_nonneg) auto | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 393 | with assms have "x * x\<^sup>2 ^ n * (x ^ 4) ^ k * c k \<le> x * x\<^sup>2 ^ n * (x ^ 4) ^ k * 1" for k | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 394 | by (intro mult_left_mono mult_right_mono mult_nonneg_nonneg) simp_all | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 395 | with assms have "arctan x - arctan_approx n x \<le> x * (x\<^sup>2)^n * (1 / (1 - x^4))" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 396 | by (intro sums_le[OF _ sums sums_mult[OF geometric_sums]] allI mult_left_mono) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 397 | (auto simp: power_less_one) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 398 | also have "x * (x^2)^n = x^(2*n+1)" by (simp add: power_mult power_add) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 399 | finally have "arctan x - arctan_approx n x \<le> x^(2*n+1) / (1 - x^4)" by simp | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 400 | } | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 401 | ultimately show ?thesis by simp | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 402 | qed | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 403 | |
| 62089 | 404 | lemma arctan_approx_def': "arctan_approx n (1/x) = | 
| 405 | (\<Sum>k<n. inverse (real (2 * k + 1) * (- x\<^sup>2) ^ k)) / x" | |
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 406 | proof - | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 407 | have "(-1)^k / b = 1 / ((-1)^k * b)" for k :: nat and b :: real | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 408 | by (cases "even k") auto | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 409 | thus ?thesis by (simp add: arctan_approx_def field_simps power_minus') | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 410 | qed | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 411 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 412 | lemma expand_arctan_approx: | 
| 62089 | 413 | "(\<Sum>k<(numeral n::nat). inverse (f k) * inverse (x ^ k)) = | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 414 | inverse (f 0) + (\<Sum>k<pred_numeral n. inverse (f (k+1)) * inverse (x^k)) / x" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 415 | "(\<Sum>k<Suc 0. inverse (f k) * inverse (x^k)) = inverse (f 0 :: 'a :: field)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 416 | "(\<Sum>k<(0::nat). inverse (f k) * inverse (x^k)) = 0" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 417 | proof - | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 418 |   {
 | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 419 | fix m :: nat | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 420 | have "(\<Sum>k<Suc m. inverse (f k * x^k)) = | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 421 | inverse (f 0) + (\<Sum>k=Suc 0..<Suc m. inverse (f k * x^k))" | 
| 70097 
4005298550a6
The last big tranche of Homology material: invariance of domain; renamings to use generic sum/prod lemmas from their locale
 paulson <lp15@cam.ac.uk> parents: 
69597diff
changeset | 422 | by (subst atLeast0LessThan [symmetric], subst sum.atLeast_Suc_lessThan) simp_all | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 423 | also have "(\<Sum>k=Suc 0..<Suc m. inverse (f k * x^k)) = (\<Sum>k<m. inverse (f (k+1) * x^k)) / x" | 
| 70113 
c8deb8ba6d05
Fixing the main Homology theory; also moving a lot of sum/prod lemmas into their generic context
 paulson <lp15@cam.ac.uk> parents: 
70097diff
changeset | 424 | by (subst sum.shift_bounds_Suc_ivl) | 
| 64267 | 425 | (simp add: sum_distrib_left divide_inverse algebra_simps | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 426 | atLeast0LessThan power_commutes) | 
| 62089 | 427 | finally have "(\<Sum>k<Suc m. inverse (f k) * inverse (x ^ k)) = | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 428 | inverse (f 0) + (\<Sum>k<m. inverse (f (k + 1)) * inverse (x ^ k)) / x" by simp | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 429 | } | 
| 62089 | 430 | from this[of "pred_numeral n"] | 
| 431 | show "(\<Sum>k<numeral n. inverse (f k) * inverse (x^k)) = | |
| 432 | inverse (f 0) + (\<Sum>k<pred_numeral n. inverse (f (k+1)) * inverse (x^k)) / x" | |
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 433 | by (simp add: numeral_eq_Suc) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 434 | qed simp_all | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 435 | |
| 62089 | 436 | lemma arctan_diff_small: | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 437 | assumes "\<bar>x*y::real\<bar> < 1" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 438 | shows "arctan x - arctan y = arctan ((x - y) / (1 + x * y))" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 439 | proof - | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 440 | have "arctan x - arctan y = arctan x + arctan (-y)" by (simp add: arctan_minus) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 441 | also from assms have "\<dots> = arctan ((x - y) / (1 + x * y))" by (subst arctan_add_small) simp_all | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 442 | finally show ?thesis . | 
| 59871 
e1a49ac9c537
John Harrison's example: a 32-bit approximation to pi. SLOW
 paulson <lp15@cam.ac.uk> parents: diff
changeset | 443 | qed | 
| 
e1a49ac9c537
John Harrison's example: a 32-bit approximation to pi. SLOW
 paulson <lp15@cam.ac.uk> parents: diff
changeset | 444 | |
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 445 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 446 | subsubsection \<open>Machin-like formulae for pi\<close> | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 447 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 448 | text \<open> | 
| 69597 | 449 | We first define a small proof method that can prove Machin-like formulae for \<^term>\<open>pi\<close> | 
| 62089 | 450 | automatically. Unfortunately, this takes far too much time for larger formulae because | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 451 | the numbers involved become too large. | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 452 | \<close> | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 453 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 454 | definition "MACHIN_TAG a b \<equiv> a * (b::real)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 455 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 456 | lemma numeral_horner_MACHIN_TAG: | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 457 | "MACHIN_TAG Numeral1 x = x" | 
| 62089 | 458 | "MACHIN_TAG (numeral (Num.Bit0 (Num.Bit0 n))) x = | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 459 | MACHIN_TAG 2 (MACHIN_TAG (numeral (Num.Bit0 n)) x)" | 
| 62089 | 460 | "MACHIN_TAG (numeral (Num.Bit0 (Num.Bit1 n))) x = | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 461 | MACHIN_TAG 2 (MACHIN_TAG (numeral (Num.Bit1 n)) x)" | 
| 62089 | 462 | "MACHIN_TAG (numeral (Num.Bit1 n)) x = | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 463 | MACHIN_TAG 2 (MACHIN_TAG (numeral n) x) + x" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 464 | unfolding numeral_Bit0 numeral_Bit1 ring_distribs one_add_one[symmetric] MACHIN_TAG_def | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 465 | by (simp_all add: algebra_simps) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 466 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 467 | lemma tag_machin: "a * arctan b = MACHIN_TAG a (arctan b)" by (simp add: MACHIN_TAG_def) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 468 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 469 | lemma arctan_double': "\<bar>a::real\<bar> < 1 \<Longrightarrow> MACHIN_TAG 2 (arctan a) = arctan (2 * a / (1 - a*a))" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 470 | unfolding MACHIN_TAG_def by (simp add: arctan_double power2_eq_square) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 471 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 472 | ML \<open> | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 473 | fun machin_term_conv ctxt ct = | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 474 | let | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 475 |       val ctxt' = ctxt addsimps @{thms arctan_double' arctan_add_small}
 | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 476 | in | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 477 | case Thm.term_of ct of | 
| 69597 | 478 | Const (\<^const_name>\<open>MACHIN_TAG\<close>, _) $ _ $ | 
| 479 | (Const (\<^const_name>\<open>Transcendental.arctan\<close>, _) $ _) => | |
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 480 | Simplifier.rewrite ctxt' ct | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 481 | | | 
| 69597 | 482 | Const (\<^const_name>\<open>MACHIN_TAG\<close>, _) $ _ $ | 
| 483 | (Const (\<^const_name>\<open>Groups.plus\<close>, _) $ | |
| 484 | (Const (\<^const_name>\<open>Transcendental.arctan\<close>, _) $ _) $ | |
| 485 | (Const (\<^const_name>\<open>Transcendental.arctan\<close>, _) $ _)) => | |
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 486 | Simplifier.rewrite ctxt' ct | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 487 |       | _ => raise CTERM ("machin_conv", [ct])
 | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 488 | end | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 489 | |
| 62089 | 490 | fun machin_tac ctxt = | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 491 | let val conv = Conv.top_conv (Conv.try_conv o machin_term_conv) ctxt | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 492 | in | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 493 | SELECT_GOAL ( | 
| 62089 | 494 | Local_Defs.unfold_tac ctxt | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 495 |           @{thms tag_machin[THEN eq_reflection] numeral_horner_MACHIN_TAG[THEN eq_reflection]}
 | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 496 | THEN REPEAT (CHANGED (HEADGOAL (CONVERSION conv)))) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 497 |       THEN' Simplifier.simp_tac (ctxt addsimps @{thms arctan_add_small arctan_diff_small})
 | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 498 | end | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 499 | \<close> | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 500 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 501 | method_setup machin = \<open>Scan.succeed (SIMPLE_METHOD' o machin_tac)\<close> | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 502 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 503 | text \<open> | 
| 62089 | 504 | We can now prove the ``standard'' Machin formula, which was already proven manually | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 505 | in Isabelle, automatically. | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 506 | }\<close> | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 507 | lemma "pi / 4 = (4::real) * arctan (1 / 5) - arctan (1 / 239)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 508 | by machin | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 509 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 510 | text \<open> | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 511 | We can also prove the following more complicated formula: | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 512 | \<close> | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 513 | lemma machin': "pi/4 = (12::real) * arctan (1/18) + 8 * arctan (1/57) - 5 * arctan (1/239)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 514 | by machin | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 515 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 516 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 517 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 518 | subsubsection \<open>Simple approximation of pi\<close> | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 519 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 520 | text \<open> | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 521 | We can use the simple Machin formula and the Taylor series expansion of the arctangent | 
| 69597 | 522 | to approximate pi. For a given even natural number $n$, we expand \<^term>\<open>arctan (1/5)\<close> | 
| 523 | to $3n$ summands and \<^term>\<open>arctan (1/239)\<close> to $n$ summands. This gives us at least | |
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 524 | $13n-2$ bits of precision. | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 525 | \<close> | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 526 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 527 | definition "pi_approx n = 16 * arctan_approx (3*n) (1/5) - 4 * arctan_approx n (1/239)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 528 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 529 | lemma pi_approx: | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 530 | fixes n :: nat assumes n: "even n" and "n > 0" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 531 | shows "\<bar>pi - pi_approx n\<bar> \<le> inverse (2^(13*n - 2))" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 532 | proof - | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 533 | from n have n': "even (3*n)" by simp | 
| 62175 | 534 | \<comment> \<open>We apply the Machin formula\<close> | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 535 | from machin have "pi = 16 * arctan (1/5) - 4 * arctan (1/239::real)" by simp | 
| 62175 | 536 | \<comment> \<open>Taylor series expansion of the arctangent\<close> | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 537 | also from arctan_approx[OF _ _ n', of "1/5"] arctan_approx[OF _ _ n, of "1/239"] | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 538 |     have "\<dots> - pi_approx n \<in> {-4*((1/239)^(2*n+1) / (1-(1/239)^4))..16*(1/5)^(6*n+1) / (1-(1/5)^4)}"
 | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 539 | by (simp add: pi_approx_def) | 
| 62175 | 540 | \<comment> \<open>Coarsening the bounds to make them a bit nicer\<close> | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 541 | also have "-4*((1/239::real)^(2*n+1) / (1-(1/239)^4)) = -((13651919 / 815702160) / 57121^n)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 542 | by (simp add: power_mult power2_eq_square) (simp add: field_simps) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 543 | also have "16*(1/5)^(6*n+1) / (1-(1/5::real)^4) = (125/39) / 15625^n" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 544 | by (simp add: power_mult power2_eq_square) (simp add: field_simps) | 
| 62089 | 545 |   also have "{-((13651919 / 815702160) / 57121^n) .. (125 / 39) / 15625^n} \<subseteq>
 | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 546 |                {- (4 / 2^(13*n)) .. 4 / (2^(13*n)::real)}"
 | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 547 | by (subst atLeastatMost_subset_iff, intro disjI2 conjI le_imp_neg_le) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 548 | (rule frac_le; simp add: power_mult power_mono)+ | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 549 | finally have "abs (pi - pi_approx n) \<le> 4 / 2^(13*n)" by auto | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 550 | also from \<open>n > 0\<close> have "4 / 2^(13*n) = 1 / (2^(13*n - 2) :: real)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 551 | by (cases n) (simp_all add: power_add) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 552 | finally show ?thesis by (simp add: divide_inverse) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 553 | qed | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 554 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 555 | lemma pi_approx': | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 556 | fixes n :: nat assumes n: "even n" and "n > 0" and "k \<le> 13*n - 2" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 557 | shows "\<bar>pi - pi_approx n\<bar> \<le> inverse (2^k)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 558 | using assms(3) by (intro order.trans[OF pi_approx[OF assms(1,2)]]) (simp_all add: field_simps) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 559 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 560 | text \<open>We can now approximate pi to 22 decimals within a fraction of a second.\<close> | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 561 | lemma pi_approx_75: "abs (pi - 3.1415926535897932384626 :: real) \<le> inverse (10^22)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 562 | proof - | 
| 63040 | 563 | define a :: real | 
| 564 | where "a = 8295936325956147794769600190539918304 / 2626685325478320010006427764892578125" | |
| 565 | define b :: real | |
| 566 | where "b = 8428294561696506782041394632 / 503593538783547230635598424135" | |
| 62175 | 567 | \<comment> \<open>The introduction of this constant prevents the simplifier from applying solvers that | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 568 | we don't want. We want it to simply evaluate the terms to rational constants.}\<close> | 
| 67399 | 569 | define eq :: "real \<Rightarrow> real \<Rightarrow> bool" where "eq = (=)" | 
| 62089 | 570 | |
| 62175 | 571 | \<comment> \<open>Splitting the computation into several steps has the advantage that simplification can | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 572 | be done in parallel\<close> | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 573 | have "abs (pi - pi_approx 6) \<le> inverse (2^76)" by (rule pi_approx') simp_all | 
| 62089 | 574 | also have "pi_approx 6 = 16 * arctan_approx (3 * 6) (1 / 5) - 4 * arctan_approx 6 (1 / 239)" | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 575 | unfolding pi_approx_def by simp | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 576 | also have [unfolded eq_def]: "eq (16 * arctan_approx (3 * 6) (1 / 5)) a" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 577 | by (simp add: arctan_approx_def' power2_eq_square, | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 578 | simp add: expand_arctan_approx, unfold a_def eq_def, rule refl) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 579 | also have [unfolded eq_def]: "eq (4 * arctan_approx 6 (1 / 239::real)) b" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 580 | by (simp add: arctan_approx_def' power2_eq_square, | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 581 | simp add: expand_arctan_approx, unfold b_def eq_def, rule refl) | 
| 62089 | 582 | also have [unfolded eq_def]: | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 583 | "eq (a - b) (171331331860120333586637094112743033554946184594977368554649608 / | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 584 | 54536456744112171868276045488779391002026386559009552001953125)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 585 | by (unfold a_def b_def, simp, unfold eq_def, rule refl) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 586 | finally show ?thesis by (rule approx_coarsen) simp | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 587 | qed | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 588 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 589 | text \<open> | 
| 62089 | 590 | The previous estimate of pi in this file was based on approximating the root of the | 
| 591 | $\sin(\pi/6)$ in the interval $[0;4]$ using the Taylor series expansion of the sine to | |
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 592 | verify that it is between two given bounds. | 
| 62089 | 593 | This was much slower and much less precise. We can easily recover this coarser estimate from | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 594 | the newer, precise estimate: | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 595 | \<close> | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 596 | lemma pi_approx_32: "\<bar>pi - 13493037705/4294967296 :: real\<bar> \<le> inverse(2 ^ 32)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 597 | by (rule approx_coarsen[OF pi_approx_75]) simp | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 598 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 599 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 600 | subsection \<open>A more complicated approximation of pi\<close> | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 601 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 602 | text \<open> | 
| 62089 | 603 | There are more complicated Machin-like formulae that have more terms with larger | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 604 | denominators. Although they have more terms, each term requires fewer summands of the | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 605 | Taylor series for the same precision, since it is evaluated closer to $0$. | 
| 62089 | 606 | |
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 607 | Using a good formula, one can therefore obtain the same precision with fewer operations. | 
| 62089 | 608 | The big formulae used for computations of pi in practice are too complicated for us to | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 609 |   prove here, but we can use the three-term Machin-like formula @{thm machin'}.
 | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 610 | \<close> | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 611 | |
| 62089 | 612 | definition "pi_approx2 n = 48 * arctan_approx (6*n) (1/18::real) + | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 613 | 32 * arctan_approx (4*n) (1/57) - 20 * arctan_approx (3*n) (1/239)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 614 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 615 | lemma pi_approx2: | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 616 | fixes n :: nat assumes n: "even n" and "n > 0" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 617 | shows "\<bar>pi - pi_approx2 n\<bar> \<le> inverse (2^(46*n - 1))" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 618 | proof - | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 619 | from n have n': "even (6*n)" "even (4*n)" "even (3*n)" by simp_all | 
| 62089 | 620 | from machin' have "pi = 48 * arctan (1/18) + 32 * arctan (1/57) - 20 * arctan (1/239::real)" | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 621 | by simp | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 622 | hence "pi - pi_approx2 n = 48 * (arctan (1/18) - arctan_approx (6*n) (1/18)) + | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 623 | 32 * (arctan (1/57) - arctan_approx (4*n) (1/57)) - | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 624 | 20 * (arctan (1/239) - arctan_approx (3*n) (1/239))" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 625 | by (simp add: pi_approx2_def) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 626 |   also have "\<dots> \<in> {-((20/239/(1-(1/239)^4)) * (1/239)^(6*n))..
 | 
| 62089 | 627 | (48/18 / (1-(1/18)^4))*(1/18)^(12*n) + (32/57/(1-(1/57)^4)) * (1/57)^(8*n)}" | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 628 |     (is "_ \<in> {-?l..?u1 + ?u2}")
 | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 629 | apply ((rule combine_bounds(1,2))+; (rule combine_bounds(3); (rule arctan_approx)?)?) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 630 | apply (simp_all add: n) | 
| 70817 
dd675800469d
dedicated fact collections for algebraic simplification rules potentially splitting goals
 haftmann parents: 
70114diff
changeset | 631 | apply (simp_all add: field_split_simps)? | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 632 | done | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 633 |   also {
 | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 634 | have "?l \<le> (1/8) * (1/2)^(46*n)" | 
| 70817 
dd675800469d
dedicated fact collections for algebraic simplification rules potentially splitting goals
 haftmann parents: 
70114diff
changeset | 635 | unfolding power_mult by (intro mult_mono power_mono) (simp_all add: field_split_simps) | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 636 | also have "\<dots> \<le> (1/2) ^ (46 * n - 1)" | 
| 70817 
dd675800469d
dedicated fact collections for algebraic simplification rules potentially splitting goals
 haftmann parents: 
70114diff
changeset | 637 | by (cases n; simp_all add: power_add field_split_simps) | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 638 | finally have "?l \<le> (1/2) ^ (46 * n - 1)" . | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 639 |     moreover {
 | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 640 | have "?u1 + ?u2 \<le> 4 * (1/2)^(48*n) + 1 * (1/2)^(46*n)" | 
| 70817 
dd675800469d
dedicated fact collections for algebraic simplification rules potentially splitting goals
 haftmann parents: 
70114diff
changeset | 641 | unfolding power_mult by (intro add_mono mult_mono power_mono) (simp_all add: field_split_simps) | 
| 62089 | 642 | also from \<open>n > 0\<close> have "4 * (1/2::real)^(48*n) \<le> (1/2)^(46*n)" | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 643 | by (cases n) (simp_all add: field_simps power_add) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 644 | also from \<open>n > 0\<close> have "(1/2::real) ^ (46 * n) + 1 * (1 / 2) ^ (46 * n) = (1/2) ^ (46 * n - 1)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 645 | by (cases n; simp_all add: power_add power_divide) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 646 | finally have "?u1 + ?u2 \<le> (1/2) ^ (46 * n - 1)" by - simp | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 647 | } | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 648 |     ultimately have "{-?l..?u1 + ?u2} \<subseteq> {-((1/2)^(46*n-1))..(1/2)^(46*n-1)}"
 | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 649 | by (subst atLeastatMost_subset_iff) simp_all | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 650 | } | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 651 | finally have "\<bar>pi - pi_approx2 n\<bar> \<le> ((1/2) ^ (46 * n - 1))" by auto | 
| 70817 
dd675800469d
dedicated fact collections for algebraic simplification rules potentially splitting goals
 haftmann parents: 
70114diff
changeset | 652 | thus ?thesis by (simp add: field_split_simps) | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 653 | qed | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 654 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 655 | lemma pi_approx2': | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 656 | fixes n :: nat assumes n: "even n" and "n > 0" and "k \<le> 46*n - 1" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 657 | shows "\<bar>pi - pi_approx2 n\<bar> \<le> inverse (2^k)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 658 | using assms(3) by (intro order.trans[OF pi_approx2[OF assms(1,2)]]) (simp_all add: field_simps) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 659 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 660 | text \<open> | 
| 62089 | 661 | We can now approximate pi to 54 decimals using this formula. The computations are much | 
| 662 | slower now; this is mostly because we use arbitrary-precision rational numbers, whose | |
| 663 | numerators and demoninators get very large. Using dyadic floating point numbers would be | |
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 664 | much more economical. | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 665 | \<close> | 
| 62089 | 666 | lemma pi_approx_54_decimals: | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 667 | "abs (pi - 3.141592653589793238462643383279502884197169399375105821 :: real) \<le> inverse (10^54)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 668 | (is "abs (pi - ?pi') \<le> _") | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 669 | proof - | 
| 63040 | 670 | define a :: real | 
| 671 | where "a = 2829469759662002867886529831139137601191652261996513014734415222704732791803 / | |
| 672 | 1062141879292765061960538947347721564047051545995266466660439319087625011200" | |
| 673 | define b :: real | |
| 674 | where "b = 13355545553549848714922837267299490903143206628621657811747118592 / | |
| 675 | 23792006023392488526789546722992491355941103837356113731091180925" | |
| 676 | define c :: real | |
| 677 | where "c = 28274063397213534906669125255762067746830085389618481175335056 / | |
| 678 | 337877029279505250241149903214554249587517250716358486542628059" | |
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 679 | let ?pi'' = "3882327391761098513316067116522233897127356523627918964967729040413954225768920394233198626889767468122598417405434625348404038165437924058179155035564590497837027530349 / | 
| 62089 | 680 | 1235783190199688165469648572769847552336447197542738425378629633275352407743112409829873464564018488572820294102599160968781449606552922108667790799771278860366957772800" | 
| 67399 | 681 | define eq :: "real \<Rightarrow> real \<Rightarrow> bool" where "eq = (=)" | 
| 62089 | 682 | |
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 683 | have "abs (pi - pi_approx2 4) \<le> inverse (2^183)" by (rule pi_approx2') simp_all | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 684 | also have "pi_approx2 4 = 48 * arctan_approx 24 (1 / 18) + | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 685 | 32 * arctan_approx 16 (1 / 57) - | 
| 62089 | 686 | 20 * arctan_approx 12 (1 / 239)" | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 687 | unfolding pi_approx2_def by simp | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 688 | also have [unfolded eq_def]: "eq (48 * arctan_approx 24 (1 / 18)) a" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 689 | by (simp add: arctan_approx_def' power2_eq_square, | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 690 | simp add: expand_arctan_approx, unfold a_def eq_def, rule refl) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 691 | also have [unfolded eq_def]: "eq (32 * arctan_approx 16 (1 / 57::real)) b" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 692 | by (simp add: arctan_approx_def' power2_eq_square, | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 693 | simp add: expand_arctan_approx, unfold b_def eq_def, rule refl) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 694 | also have [unfolded eq_def]: "eq (20 * arctan_approx 12 (1 / 239::real)) c" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 695 | by (simp add: arctan_approx_def' power2_eq_square, | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 696 | simp add: expand_arctan_approx, unfold c_def eq_def, rule refl) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 697 | also have [unfolded eq_def]: | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 698 | "eq (a + b) (34326487387865555303797183505809267914709125998469664969258315922216638779011304447624792548723974104030355722677 / | 
| 62089 | 699 | 10642967245546718617684989689985787964158885991018703366677373121531695267093031090059801733340658960857196134400)" | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 700 | by (unfold a_def b_def c_def, simp, unfold eq_def, rule refl) | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 701 | also have [unfolded eq_def]: "eq (\<dots> - c) ?pi''" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 702 | by (unfold a_def b_def c_def, simp, unfold eq_def, rule refl) | 
| 62175 | 703 | \<comment> \<open>This is incredibly slow because the numerators and denominators are huge.\<close> | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 704 | finally show ?thesis by (rule approx_coarsen) simp | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 705 | qed | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 706 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 707 | text \<open>A 128 bit approximation of pi:\<close> | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 708 | lemma pi_approx_128: | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 709 | "abs (pi - 1069028584064966747859680373161870783301 / 2^128) \<le> inverse (2^128)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 710 | by (rule approx_coarsen[OF pi_approx_54_decimals]) simp | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 711 | |
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 712 | text \<open>A 64 bit approximation of pi:\<close> | 
| 62089 | 713 | lemma pi_approx_64: | 
| 62085 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 714 | "abs (pi - 57952155664616982739 / 2^64 :: real) \<le> inverse (2^64)" | 
| 
5b7758af429e
Tuned approximations in Multivariate_Analysis
 Manuel Eberl <eberlm@in.tum.de> parents: 
61945diff
changeset | 715 | by (rule approx_coarsen[OF pi_approx_54_decimals]) simp | 
| 62089 | 716 | |
| 717 | text \<open> | |
| 718 | Again, going much farther with the simplifier takes a long time, but the code generator | |
| 719 | can handle even two thousand decimal digits in under 20 seconds. | |
| 720 | \<close> | |
| 59871 
e1a49ac9c537
John Harrison's example: a 32-bit approximation to pi. SLOW
 paulson <lp15@cam.ac.uk> parents: diff
changeset | 721 | |
| 
e1a49ac9c537
John Harrison's example: a 32-bit approximation to pi. SLOW
 paulson <lp15@cam.ac.uk> parents: diff
changeset | 722 | end |