Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 552ebeb

Browse files
committed
feat(algebra/continued_fractions): add convergence theorem (#6607)
1. Add convergence theorem for continued fractions, i.e. `(gcf.of v).convergents` converges to `v`. 2. Add some simple corollaries following from the already existing approximation lemmas for continued fractions, e.g. the equivalence of the convergent computations for continued fractions computed by `gcf.of` (`(gcf.of v).convergents` and `(gcf.of v).convergents'`).
1 parent a7410df commit 552ebeb

File tree

7 files changed

+243
-66
lines changed

7 files changed

+243
-66
lines changed

src/algebra/continued_fractions/basic.lean

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ end simple_continued_fraction
210210
A simple continued fraction is a *(regular) continued fraction* ((r)cf) if all partial denominators
211211
`bᵢ` are positive, i.e. `0 < bᵢ`.
212212
-/
213-
def simple_continued_fraction.is_regular_continued_fraction [has_one α] [has_zero α] [has_lt α]
213+
def simple_continued_fraction.is_continued_fraction [has_one α] [has_zero α] [has_lt α]
214214
(s : simple_continued_fraction α) : Prop :=
215215
∀ (n : ℕ) (bₙ : α),
216216
(↑s : generalized_continued_fraction α).partial_denominators.nth n = some bₙ → 0 < bₙ
@@ -220,10 +220,10 @@ variable (α)
220220
/--
221221
A *(regular) continued fraction* ((r)cf) is a simple continued fraction (scf) whose partial
222222
denominators are all positive. It is the subtype of scfs that satisfy
223-
`simple_continued_fraction.is_regular_continued_fraction`.
223+
`simple_continued_fraction.is_continued_fraction`.
224224
-/
225225
def continued_fraction [has_one α] [has_zero α] [has_lt α] :=
226-
{s : simple_continued_fraction α // s.is_regular_continued_fraction}
226+
{s : simple_continued_fraction α // s.is_continued_fraction}
227227

228228
variable {α}
229229

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/-
2+
Copyright (c) 2021 Kevin Kappelmann. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Kevin Kappelmann
5+
-/
6+
import algebra.continued_fractions.computation.approximations
7+
import algebra.continued_fractions.convergents_equiv
8+
import topology.instances.ennreal
9+
/-!
10+
# Corollaries From Approximation Lemmas (`algebra.continued_fractions.computation.approximations`)
11+
12+
## Summary
13+
14+
We show that the generalized_continued_fraction given by `generalized_continued_fraction.of` in fact
15+
is a (regular) continued fraction. Using the equivalence of the convergents computations
16+
(`generalized_continued_fraction.convergents` and `generalized_continued_fraction.convergents'`) for
17+
continued fractions (see `algebra.continued_fractions.convergents_equiv`), it follows that the
18+
convergents computations for `generalized_continued_fraction.of` are equivalent.
19+
20+
Moreover, we show the convergence of the continued fractions computations, that is
21+
`(generalized_continued_fraction.of v).convergents` indeed computes `v` in the limit.
22+
23+
## Main Definitions
24+
25+
- `continued_fraction.of` returns the (regular) continued fraction of a value.
26+
27+
## Main Theorems
28+
29+
- `generalized_continued_fraction.of_convergents_eq_convergents'` shows that the convergents
30+
computations for `generalized_continued_fraction.of` are equivalent.
31+
- `generalized_continued_fraction.of_convergence` shows that
32+
`(generalized_continued_fraction.of v).convergents` converges to `v`.
33+
34+
## Tags
35+
36+
convergence, fractions
37+
-/
38+
39+
variables {K : Type*} (v : K) [linear_ordered_field K] [floor_ring K]
40+
open generalized_continued_fraction as gcf
41+
42+
lemma generalized_continued_fraction.of_is_simple_continued_fraction :
43+
(gcf.of v).is_simple_continued_fraction :=
44+
(λ _ _ nth_part_num_eq, gcf.of_part_num_eq_one nth_part_num_eq)
45+
46+
/-- Creates the simple continued fraction of a value. -/
47+
def simple_continued_fraction.of : simple_continued_fraction K :=
48+
⟨gcf.of v, generalized_continued_fraction.of_is_simple_continued_fraction v⟩
49+
50+
lemma simple_continued_fraction.of_is_continued_fraction :
51+
(simple_continued_fraction.of v).is_continued_fraction :=
52+
(λ _ denom nth_part_denom_eq,
53+
lt_of_lt_of_le zero_lt_one(gcf.of_one_le_nth_part_denom nth_part_denom_eq))
54+
55+
/-- Creates the continued fraction of a value. -/
56+
def continued_fraction.of : continued_fraction K :=
57+
⟨simple_continued_fraction.of v, simple_continued_fraction.of_is_continued_fraction v⟩
58+
59+
namespace generalized_continued_fraction
60+
61+
open continued_fraction as cf
62+
63+
lemma of_convergents_eq_convergents' : (gcf.of v).convergents = (gcf.of v).convergents' :=
64+
@cf.convergents_eq_convergents' _ _ (continued_fraction.of v)
65+
66+
section convergence
67+
/-!
68+
### Convergence
69+
70+
We next show that `(generalized_continued_fraction.of v).convergents v` converges to `v`.
71+
-/
72+
73+
variable [archimedean K]
74+
local notation `|` x `|` := abs x
75+
open nat
76+
77+
theorem of_convergence_epsilon :
78+
∀ (ε > (0 : K)), ∃ (N : ℕ), ∀ (n ≥ N), |v - (gcf.of v).convergents n| < ε :=
79+
begin
80+
assume ε ε_pos,
81+
-- use the archemidean property to obtian a suitable N
82+
rcases (exists_nat_gt (1 / ε) : ∃ (N' : ℕ), 1 / ε < N') with ⟨N', one_div_ε_lt_N'⟩,
83+
let N := max N' 5, -- set minimum to 5 to have N ≤ fib N work
84+
existsi N,
85+
assume n n_ge_N,
86+
let g := gcf.of v,
87+
cases decidable.em (g.terminated_at n) with terminated_at_n not_terminated_at_n,
88+
{ have : v = g.convergents n, from of_correctness_of_terminated_at terminated_at_n,
89+
have : v - g.convergents n = 0, from sub_eq_zero.elim_right this,
90+
rw [this],
91+
exact_mod_cast ε_pos },
92+
{ let B := g.denominators n,
93+
let nB := g.denominators (n + 1),
94+
have abs_v_sub_conv_le : |v - g.convergents n| ≤ 1 / (B * nB), from
95+
abs_sub_convergents_le not_terminated_at_n,
96+
suffices : 1 / (B * nB) < ε, from lt_of_le_of_lt abs_v_sub_conv_le this,
97+
-- show that `0 < (B * nB)` and then multiply by `B * nB` to get rid of the division
98+
have nB_ineq : (fib (n + 2) : K) ≤ nB, by
99+
{ have : ¬g.terminated_at (n + 1 - 1), from not_terminated_at_n,
100+
exact (succ_nth_fib_le_of_nth_denom (or.inr this)) },
101+
have B_ineq : (fib (n + 1) : K) ≤ B, by
102+
{ have : ¬g.terminated_at (n - 1), from mt (terminated_stable n.pred_le) not_terminated_at_n,
103+
exact (succ_nth_fib_le_of_nth_denom (or.inr this)) },
104+
have zero_lt_B : 0 < B, by
105+
{ have : (0 : K) < fib (n + 1), by exact_mod_cast fib_pos n.zero_lt_succ,
106+
exact (lt_of_lt_of_le this B_ineq) },
107+
have zero_lt_mul_conts : 0 < B * nB, by
108+
{ have : 0 < nB, by
109+
{ have : (0 : K) < fib (n + 2), by exact_mod_cast fib_pos (n + 1).zero_lt_succ,
110+
exact (lt_of_lt_of_le this nB_ineq) },
111+
solve_by_elim [mul_pos] },
112+
suffices : 1 < ε * (B * nB), from (div_lt_iff zero_lt_mul_conts).elim_right this,
113+
-- use that `N ≥ n` was obtained from the archimedian property to show the following
114+
have one_lt_ε_mul_N : 1 < ε * n, by
115+
{ have one_lt_ε_mul_N' : 1 < ε * (N' : K), from (div_lt_iff' ε_pos).elim_left one_div_ε_lt_N',
116+
have : (N' : K) ≤ N, by exact_mod_cast (le_max_left _ _),
117+
have : ε * N' ≤ ε * n, from
118+
(mul_le_mul_left ε_pos).elim_right (le_trans this (by exact_mod_cast n_ge_N)),
119+
exact (lt_of_lt_of_le one_lt_ε_mul_N' this) },
120+
suffices : ε * n ≤ ε * (B * nB), from lt_of_lt_of_le one_lt_ε_mul_N this,
121+
-- cancel `ε`
122+
suffices : (n : K) ≤ B * nB, from (mul_le_mul_left ε_pos).elim_right this,
123+
show (n : K) ≤ B * nB,
124+
calc (n : K)
125+
≤ fib n : by exact_mod_cast (le_fib_self $ le_trans
126+
(le_max_right N' 5) n_ge_N)
127+
... ≤ fib (n + 1) : by exact_mod_cast fib_le_fib_succ
128+
... ≤ fib (n + 1) * fib (n + 1) : by exact_mod_cast ((fib (n + 1)).le_mul_self)
129+
... ≤ fib (n + 1) * fib (n + 2) : mul_le_mul_of_nonneg_left
130+
(by exact_mod_cast fib_le_fib_succ)
131+
(by exact_mod_cast (fib (n + 1)).zero_le)
132+
... ≤ B * nB : mul_le_mul B_ineq nB_ineq
133+
(by exact_mod_cast (fib (n + 2)).zero_le)
134+
(le_of_lt zero_lt_B) }
135+
end
136+
137+
local attribute [instance] preorder.topology
138+
139+
theorem of_convergence [order_topology K] :
140+
filter.tendsto ((gcf.of v).convergents) filter.at_top $ nhds v :=
141+
by simpa [linear_ordered_add_comm_group.tendsto_nhds, abs_sub] using (of_convergence_epsilon v)
142+
143+
end convergence
144+
145+
end generalized_continued_fraction

src/algebra/continued_fractions/computation/approximations.lean

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,36 +7,35 @@ import algebra.continued_fractions.computation.correctness_terminating
77
import data.nat.fib
88
import tactic.solve_by_elim
99
/-!
10-
# Approximations for Continued Fraction Computations (`gcf.of`)
10+
# Approximations for Continued Fraction Computations (`generalized_continued_fraction.of`)
1111
1212
## Summary
1313
14-
Let us write `gcf` for `generalized_continued_fraction`. This file contains useful approximations
15-
for the values involved in the continued fractions computation `gcf.of`.
16-
In particular, we derive the so-called *determinant formula* for `gcf.of`:
14+
This file contains useful approximations for the values involved in the continued fractions
15+
computation `generalized_continued_fraction.of`. In particular, we derive the so-called
16+
*determinant formula* for `generalized_continued_fraction.of`:
1717
`Aₙ * Bₙ₊₁ - Bₙ * Aₙ₊₁ = (-1)^(n + 1)`.
1818
1919
Moreover, we derive some upper bounds for the error term when computing a continued fraction up a
20-
given position, i.e. bounds for the term `|v - (gcf.of v).convergents n|`.
21-
The derived bounds will show us that the error term indeed gets smaller.
20+
given position, i.e. bounds for the term
21+
`|v - (generalized_continued_fraction.of v).convergents n|`. The derived bounds will show us that
22+
the error term indeed gets smaller. As a corollary, we will be able to show that
23+
`(generalized_continued_fraction.of v).convergents` converges to `v` in
24+
`algebra.continued_fractions.computation.approximation_corollaries`.
2225
2326
## Main Theorems
2427
25-
- `gcf.of_part_num_eq_one`: shows that all partial numerators `aᵢ` are equal to one.
26-
- `gcf.exists_int_eq_of_part_denom`: shows that all partial denominators `bᵢ` correspond to an
27-
integer.
28-
- `gcf.one_le_of_nth_part_denom`: shows that `1 ≤ bᵢ`.
29-
- `gcf.succ_nth_fib_le_of_nth_denom`: shows that the `n`th denominator `Bₙ` is greater than or equal
30-
to the `n + 1`th fibonacci number `nat.fib (n + 1)`.
31-
- `gcf.le_of_succ_nth_denom`: shows that `bₙ * Bₙ ≤ Bₙ₊₁`, where `bₙ` is the `n`th partial
32-
denominator of the continued fraction.
33-
- `gcf.abs_sub_convergents_le`: shows that `|v - Aₙ / Bₙ| ≤ 1 / (Bₙ * Bₙ₊₁)`, where `Aₙ` is the
34-
nth partial numerator.
35-
36-
## TODO
37-
As a corollary of `gcf.abs_sub_convergents_le`, we will be able to show that
38-
`(gcf.of v).convergents` converges to `v`. (reference to this convergence lemma will be added in the
39-
upcoming PR about continued fractions)
28+
- `generalized_continued_fraction.of_part_num_eq_one`: shows that all partial numerators `aᵢ` are
29+
equal to one.
30+
- `generalized_continued_fraction.exists_int_eq_of_part_denom`: shows that all partial denominators
31+
`bᵢ` correspond to an integer.
32+
- `generalized_continued_fraction.one_le_of_nth_part_denom`: shows that `1 ≤ bᵢ`.
33+
- `generalized_continued_fraction.succ_nth_fib_le_of_nth_denom`: shows that the `n`th denominator
34+
`Bₙ` is greater than or equal to the `n + 1`th fibonacci number `nat.fib (n + 1)`.
35+
- `generalized_continued_fraction.le_of_succ_nth_denom`: shows that `bₙ * Bₙ ≤ Bₙ₊₁`, where `bₙ` is
36+
the `n`th partial denominator of the continued fraction.
37+
- `generalized_continued_fraction.abs_sub_convergents_le`: shows that
38+
`|v - Aₙ / Bₙ| ≤ 1 / (Bₙ * Bₙ₊₁)`, where `Aₙ` is the nth partial numerator.
4039
4140
## References
4241
@@ -123,7 +122,7 @@ end int_fract_pair
123122

124123
/-!
125124
Next we translate above results about the stream of `int_fract_pair`s to the computed continued
126-
fraction `gcf.of`.
125+
fraction `generalized_continued_fraction.of`.
127126
-/
128127

129128
/-- Shows that the integer parts of the continued fraction are at least one. -/
@@ -321,7 +320,7 @@ section determinant
321320
/-!
322321
### Determinant Formula
323322
324-
Next we prove the so-called *determinant formula* for `gcf.of`:
323+
Next we prove the so-called *determinant formula* for `generalized_continued_fraction.of`:
325324
`Aₙ * Bₙ₊₁ - Bₙ * Aₙ₊₁ = (-1)^(n + 1)`.
326325
-/
327326

@@ -379,7 +378,7 @@ section error_term
379378
### Approximation of Error Term
380379
381380
Next we derive some approximations for the error term when computing a continued fraction up a given
382-
position, i.e. bounds for the term `|v - (gcf.of v).convergents n|`.
381+
position, i.e. bounds for the term `|v - (generalized_continued_fraction.of v).convergents n|`.
383382
-/
384383

385384
/-- This lemma follows from the finite correctness proof, the determinant equality, and

src/algebra/continued_fractions/computation/correctness_terminating.lean

Lines changed: 45 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,38 @@ import algebra.continued_fractions.continuants_recurrence
99
import order.filter.at_top_bot
1010

1111
/-!
12-
# Correctness of Terminating Continued Fraction Computations (`gcf.of`)
12+
# Correctness of Terminating Continued Fraction Computations (`generalized_continued_fraction.of`)
1313
1414
## Summary
1515
16-
Let us write `gcf` for `generalized_continued_fraction`. We show the correctness of the
17-
algorithm computing continued fractions (`gcf.of`) in case of termination in the following sense:
16+
We show the correctness of the
17+
algorithm computing continued fractions (`generalized_continued_fraction.of`) in case of termination
18+
in the following sense:
1819
1920
At every step `n : ℕ`, we can obtain the value `v` by adding a specific residual term to the last
20-
denominator of the fraction described by `(gcf.of v).convergents' n`. The residual term will be zero
21-
exactly when the continued fraction terminated; otherwise, the residual term will be given by the
22-
fractional part stored in `gcf.int_fract_pair.stream v n`.
21+
denominator of the fraction described by `(generalized_continued_fraction.of v).convergents' n`.
22+
The residual term will be zero exactly when the continued fraction terminated; otherwise, the
23+
residual term will be given by the fractional part stored in
24+
`generalized_continued_fraction.int_fract_pair.stream v n`.
2325
24-
For an example, refer to `gcf.comp_exact_value_correctness_of_stream_eq_some` and for more
26+
For an example, refer to
27+
`generalized_continued_fraction.comp_exact_value_correctness_of_stream_eq_some` and for more
2528
information about the computation process, refer to `algebra.continued_fraction.computation.basic`.
2629
2730
## Main definitions
2831
29-
- `gcf.comp_exact_value` can be used to compute the exact value approximated by the continued
30-
fraction `gcf.of v` by adding a residual term as described in the summary.
32+
- `generalized_continued_fraction.comp_exact_value` can be used to compute the exact value
33+
approximated by the continued fraction `generalized_continued_fraction.of v` by adding a residual
34+
term as described in the summary.
3135
3236
## Main Theorems
3337
34-
- `gcf.comp_exact_value_correctness_of_stream_eq_some` shows that `gcf.comp_exact_value` indeed
35-
returns the value `v` when given the convergent and fractional part as described in the summary.
36-
- `gcf.of_correctness_of_terminated_at` shows the equality `v = (gcf.of v).convergents n`
37-
if `gcf.of v` terminated at position `n`.
38+
- `generalized_continued_fraction.comp_exact_value_correctness_of_stream_eq_some` shows that
39+
`generalized_continued_fraction.comp_exact_value` indeed returns the value `v` when given the
40+
convergent and fractional part as described in the summary.
41+
- `generalized_continued_fraction.of_correctness_of_terminated_at` shows the equality
42+
`v = (generalized_continued_fraction.of v).convergents n` if `generalized_continued_fraction.of v`
43+
terminated at position `n`.
3844
-/
3945

4046
namespace generalized_continued_fraction
@@ -48,8 +54,9 @@ Given two continuants `pconts` and `conts` and a value `fr`, this function retur
4854
- `exact_conts.a / exact_conts.b` where `exact_conts = next_continuants 1 fr⁻¹ pconts conts`
4955
otherwise.
5056
51-
This function can be used to compute the exact value approxmated by a continued fraction `gcf.of v`
52-
as described in lemma `comp_exact_value_correctness_of_stream_eq_some`.
57+
This function can be used to compute the exact value approxmated by a continued fraction
58+
`generalized_continued_fraction.of v` as described in lemma
59+
`comp_exact_value_correctness_of_stream_eq_some`.
5360
-/
5461
protected def comp_exact_value (pconts conts : gcf.pair K) (fr : K) : K :=
5562
-- if the fractional part is zero, we exactly approximated the value by the last continuants
@@ -69,20 +76,20 @@ by { field_simp [fract_a_ne_zero], rw [fract], ring }
6976
open generalized_continued_fraction as gcf
7077

7178
/--
72-
Shows the correctness of `comp_exact_value` in case the continued fraction `gcf.of v` did not
73-
terminate at position `n`. That is, we obtain the value `v` if we pass the two successive
74-
(auxiliary) continuants at positions `n` and `n + 1` as well as the fractional part at
75-
`int_fract_pair.stream n` to `comp_exact_value`.
79+
Shows the correctness of `comp_exact_value` in case the continued fraction
80+
`generalized_continued_fraction.of v` did not terminate at position `n`. That is, we obtain the
81+
value `v` if we pass the two successive (auxiliary) continuants at positions `n` and `n + 1` as well
82+
as the fractional part at `int_fract_pair.stream n` to `comp_exact_value`.
7683
7784
The correctness might be seen more readily if one uses `convergents'` to evaluate the continued
7885
fraction. Here is an example to illustrate the idea:
7986
8087
Let `(v : ℚ) := 3.4`. We have
81-
- `gcf.int_fract_pair.stream v 0 = some ⟨3, 0.4⟩`, and
82-
- `gcf.int_fract_pair.stream v 1 = some ⟨2, 0.5⟩`.
83-
Now `(gcf.of v).convergents' 1 = 3 + 1/2`, and our fractional term at position `2` is `0.5`. We
84-
hence have `v = 3 + 1/(2 + 0.5) = 3 + 1/2.5 = 3.4`. This computation corresponds exactly to the one
85-
using the recurrence equation in `comp_exact_value`.
88+
- `generalized_continued_fraction.int_fract_pair.stream v 0 = some ⟨3, 0.4⟩`, and
89+
- `generalized_continued_fraction.int_fract_pair.stream v 1 = some ⟨2, 0.5⟩`.
90+
Now `(generalized_continued_fraction.of v).convergents' 1 = 3 + 1/2`, and our fractional term at
91+
position `2` is `0.5`. We hence have `v = 3 + 1/(2 + 0.5) = 3 + 1/2.5 = 3.4`. This computation
92+
corresponds exactly to the one using the recurrence equation in `comp_exact_value`.
8693
-/
8794
lemma comp_exact_value_correctness_of_stream_eq_some :
8895
∀ {ifp_n : int_fract_pair K}, int_fract_pair.stream v n = some ifp_n →
@@ -173,8 +180,8 @@ begin
173180
ac_refl } }
174181
end
175182

176-
/-- The convergent of `gcf.of v` at step `n - 1` is exactly `v` if the `int_fract_pair.stream` of
177-
the corresponding continued fraction terminated at step `n`. -/
183+
/-- The convergent of `generalized_continued_fraction.of v` at step `n - 1` is exactly `v` if the
184+
`int_fract_pair.stream` of the corresponding continued fraction terminated at step `n`. -/
178185
lemma of_correctness_of_nth_stream_eq_none
179186
(nth_stream_eq_none : int_fract_pair.stream v n = none) :
180187
v = (gcf.of v).convergents (n - 1) :=
@@ -202,15 +209,20 @@ begin
202209
(comp_exact_value_correctness_of_stream_eq_some nth_stream_eq) } }
203210
end
204211

205-
/-- If `gcf.of v` terminated at step `n`, then the `n`th convergent is exactly `v`. -/
212+
/--
213+
If `generalized_continued_fraction.of v` terminated at step `n`, then the `n`th convergent is
214+
exactly `v`.
215+
-/
206216
theorem of_correctness_of_terminated_at (terminated_at_n : (gcf.of v).terminated_at n) :
207217
v = (gcf.of v).convergents n :=
208218
have int_fract_pair.stream v (n + 1) = none, from
209219
gcf.of_terminated_at_n_iff_succ_nth_int_fract_pair_stream_eq_none.elim_left terminated_at_n,
210220
of_correctness_of_nth_stream_eq_none this
211221

212-
/-- If `gcf.of v` terminates, then there is `n : ℕ` such that the `n`th convergent is exactly
213-
`v`. -/
222+
/--
223+
If `generalized_continued_fraction.of v` terminates, then there is `n : ℕ` such that the `n`th
224+
convergent is exactly `v`.
225+
-/
214226
lemma of_correctness_of_terminates (terminates : (gcf.of v).terminates) :
215227
∃ (n : ℕ), v = (gcf.of v).convergents n :=
216228
exists.elim terminates
@@ -219,7 +231,10 @@ exists.elim terminates
219231

220232
open filter
221233

222-
/-- If `gcf.of v` terminates, then its convergents will eventually always be `v`. -/
234+
/--
235+
If `generalized_continued_fraction.of v` terminates, then its convergents will eventually always
236+
be `v`.
237+
-/
223238
lemma of_correctness_at_top_of_terminates (terminates : (gcf.of v).terminates) :
224239
∀ᶠ n in at_top, v = (gcf.of v).convergents n :=
225240
begin

0 commit comments

Comments
 (0)