Skip to content

Commit 11cf717

Browse files
committed
No sorries!
1 parent 06de632 commit 11cf717

File tree

1 file changed

+164
-10
lines changed

1 file changed

+164
-10
lines changed

ComputableReal/SpecialFunctions.lean

Lines changed: 164 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,10 @@ open scoped QInterval
7575

7676
namespace Rat
7777

78-
def toDecimal (q : ℚ) (prec : ℕ := 20):=
79-
(q.floor.repr).append <| ".".append <| (10^prec * (q - q.floor)).floor.repr.leftpad prec '0'
78+
def toDecimal (q : ℚ) (prec : ℕ := 20) :=
79+
let p : ℚ → String := fun q ↦
80+
(q.floor.repr).append <| ".".append <| (10^prec * (q - q.floor)).floor.repr.leftpad prec '0'
81+
if q < 0 then "-".append (p (-q)) else if q = 0 then "0" else p q
8082

8183
end Rat
8284

@@ -338,8 +340,117 @@ theorem sqrt_lb_le_lb_add (q : ℚ) (n : ℕ) :
338340
theorem ub_sub_le_sqrt (q : ℚ) (n : ℕ) :
339341
(if q ≤ 0 then 0 else
340342
mkRat (Int.sqrt (q.num * 4 ^ n) + 1) (q.den * 4 ^ n).sqrt
341-
) - 2 * Real.sqrt q / 2^n ≤ Real.sqrt q := by
342-
sorry
343+
) - 7 * Real.sqrt q / 2^n ≤ Real.sqrt q := by
344+
split_ifs with h
345+
· rify at h
346+
simp [Real.sqrt_eq_zero'.mpr h]
347+
348+
push_neg at h
349+
replace h : 0 < q.num := Rat.num_pos.mpr h
350+
nth_rewrite 4 [← Rat.mkRat_self q]
351+
nth_rewrite 3 [← Rat.mkRat_self q]
352+
simp only [Rat.mkRat_eq_div, Rat.cast_div, Rat.cast_intCast, Rat.cast_natCast, Nat.cast_nonneg,
353+
Real.sqrt_div', Nat.cast_add, Nat.cast_one, Rat.cast_add, Rat.cast_one, one_div]
354+
have hd := Rat.den_pos q
355+
generalize q.num = x, q.den = y at *
356+
clear q
357+
358+
obtain ⟨z,hz⟩ := Int.eq_ofNat_of_zero_le h.le
359+
subst x
360+
361+
conv_lhs =>
362+
enter [1,1,1,1]
363+
tactic => norm_cast
364+
simp only [Int.cast_add, Int.cast_natCast, Int.cast_one]
365+
366+
replace h : 1 ≤ √↑z := Real.one_le_sqrt.mpr (by norm_cast at h ⊢)
367+
have h2pow : (1 : ℝ) ≤ 2 ^ n := by exact_mod_cast Nat.one_le_two_pow
368+
369+
have h₁ := @Real.floor_real_sqrt_eq_nat_sqrt (z * 4^n)
370+
rify at h₁
371+
rw [← h₁, ← Int.self_sub_fract]
372+
clear h₁
373+
have h₄ := Int.fract_lt_one √(↑z * 4 ^ n)
374+
have h₅ := Int.fract_nonneg √(↑z * 4 ^ n)
375+
rw [sub_add_comm]
376+
rw [← sub_sub_cancel 1 (Int.fract _)] at h₄ h₅
377+
generalize 1 - Int.fract √(↑z * 4 ^ n) = ε₂ at *
378+
simp only [sub_lt_self_iff, sub_nonneg] at h₄ h₅
379+
380+
--Have to special-case the y=1 case. Otherwise the denominator 1 / (√y * 2^n - ε₁) looks like it
381+
-- "could be" arbitrarily close to zero, and so cause a big blowup in error.
382+
by_cases hd' : y = 1
383+
· subst y
384+
simp only [Int.cast_add, Int.cast_one, one_mul, Nat.cast_one, Real.sqrt_one, div_one,
385+
tsub_le_iff_right, ge_iff_le]
386+
rw [show (4 ^ n = ((2 ^ n) ^ 2 : ℕ)) by rw [Nat.pow_right_comm], Nat.sqrt_eq']
387+
rw [Real.sqrt_mul', show (4 ^ n = ((2 ^ n) ^ 2 : ℝ)) by norm_cast; rw [Nat.pow_right_comm], Real.sqrt_sq,
388+
Nat.cast_pow, Nat.cast_ofNat, add_div]
389+
rotate_left; positivity; positivity
390+
simp only [isUnit_iff_ne_zero, ne_eq, pow_eq_zero_iff', OfNat.ofNat_ne_zero, false_and,
391+
not_false_eq_true, IsUnit.mul_div_cancel_right, _root_.add_comm ( _ / _ ), add_le_add_iff_left]
392+
exact div_le_div_of_nonneg_right (by linarith) (by positivity)
393+
394+
replace hd' : 2 ≤ y := by omega
395+
replace hd : 1 ≤ √↑y := Real.one_le_sqrt.mpr (Nat.one_le_cast.mpr hd)
396+
397+
have h₁ := @Real.floor_real_sqrt_eq_nat_sqrt (y * 4^n)
398+
rify at h₁
399+
rw [← h₁, ← Int.self_sub_fract]
400+
clear h₁
401+
have h₂ := Int.fract_lt_one √(↑y * 4 ^ n)
402+
have h₃ := Int.fract_nonneg √(↑y * 4 ^ n)
403+
generalize Int.fract √(↑y * 4 ^ n) = ε₁ at *
404+
405+
rw [Real.sqrt_mul', Real.sqrt_mul',
406+
show (4 ^ n = ((2 ^ n) ^ 2 : ℝ)) by norm_cast; rw [Nat.pow_right_comm]]
407+
rotate_left; positivity; positivity
408+
simp only [Nat.ofNat_nonneg, pow_nonneg, Real.sqrt_sq]
409+
410+
rw [_root_.add_comm ε₂, add_div, sub_eq_add_neg _ ε₁, denom_err]
411+
rotate_left
412+
· positivity
413+
· nlinarith
414+
415+
rw [show √↑z * 2 ^ n / (√↑y * 2 ^ n) = √↑z / √↑y by field_simp; ring_nf]
416+
simp only [_root_.mul_neg, neg_div, sub_neg_eq_add]
417+
suffices (√↑z / √↑y * ε₁ / (√↑y * 2 ^ n + -ε₁) ≤ 3 * (√↑z / √↑y / 2 ^ n))
418+
∧ (ε₂ / (√↑y * 2 ^ n + -ε₁) ≤ 4 * (√↑z / √↑y / 2 ^ n)) by
419+
rcases this
420+
rw [← mul_div 7]
421+
linarith
422+
423+
have hi₁ : 1 /3 ≤ √↑y - ε₁ := by
424+
suffices 4 / 3 ≤ √↑y by linarith
425+
trans √2
426+
· rw [Real.le_sqrt' (by positivity)]
427+
norm_num
428+
· exact Real.sqrt_le_sqrt (Nat.ofNat_le_cast.mpr hd')
429+
have hi₂ : 0 < √↑y * 2 ^ n - ε₁ := by
430+
apply lt_of_lt_of_le (show 0 < (1 / 3 : ℝ) by norm_num)
431+
apply hi₁.trans <| sub_le_sub_right (le_mul_of_one_le_right (by positivity) h2pow) _
432+
433+
constructor
434+
· ring_nf
435+
rw [mul_assoc, mul_assoc _ _ 3, mul_le_mul_iff_of_pos_left (by positivity)]
436+
apply mul_le_of_le_one_of_le' h₂.le ?_ (by positivity) (by positivity)
437+
field_simp
438+
rw [div_le_div_iff₀ hi₂ (by positivity)]
439+
calc (_ : ℝ) ≤ 3 * (1/3 * (2^n)) := by ring_nf; rfl
440+
_ ≤ 3 * ((√↑y - ε₁) * 2 ^ n) :=
441+
mul_le_mul_of_nonneg_left (mul_le_mul_of_nonneg_right hi₁ (by positivity)) zero_le_three
442+
_ = 3 * (√↑y * 2 ^ n - ε₁ * 2 ^ n) := by ring_nf
443+
_ ≤ 3 * (√↑y * 2 ^ n - ε₁) :=
444+
mul_le_mul_of_nonneg_left (tsub_le_tsub_left (le_mul_of_one_le_right h₃ h2pow) _) (by positivity)
445+
· rw [div_div, mul_div, ← sub_eq_add_neg]
446+
rw [div_le_div_iff₀ hi₂ (by positivity)]
447+
apply mul_le_of_le_one_of_le' h₅ ?_ (by positivity) (by positivity)
448+
conv_rhs =>
449+
equals (√↑z * √↑y * 2 ^ n) + √↑z * (3 * √↑y * 2 ^ n - 4 * ε₁) =>
450+
ring_nf
451+
suffices 03 * √↑y * 2 ^ n - 4 * ε₁ by nlinarith
452+
have : √↑y ≤ √↑y * 2 ^ n := le_mul_of_one_le_right (by positivity) h2pow
453+
linarith
343454

344455
theorem TLUW_lower : TendstoLocallyUniformlyWithout
345456
(fun n (x : ℚ) => ↑((fun n q =>
@@ -397,7 +508,49 @@ theorem TLUW_upper : TendstoLocallyUniformlyWithout
397508
rw [TendstoLocallyUniformlyWithout]
398509
intro ε hε x
399510
dsimp
400-
sorry
511+
rcases lt_or_le x 0 with h|h
512+
· use Set.Iic 0, Iic_mem_nhds h, 0
513+
intro b _ y hy
514+
change y ≤ (0:ℝ) at hy
515+
have hy' := Rat.cast_nonpos.mp hy
516+
have h₂ : Int.sqrt (y.num * 4 ^ b) = 0 := by
517+
rw [Int.sqrt.eq_1, Int.ofNat_eq_zero, Nat.sqrt_eq_zero, Int.toNat_eq_zero]
518+
exact Int.mul_nonpos_of_nonpos_of_nonneg (Rat.num_nonpos.mpr <| hy') (by positivity)
519+
simp [Real.sqrt_eq_zero'.mpr hy, h₂, hε, hy']
520+
· set tm := max (2 * x) 1
521+
have htm₀ : 0 < tm := by positivity
522+
have htm : x < tm := by
523+
by_cases 0 < x
524+
· exact lt_sup_of_lt_left (by linarith)
525+
· exact lt_sup_of_lt_right (by linarith)
526+
use Set.Ioo (-1) tm, Ioo_mem_nhds (by linarith) htm
527+
set ε' := (ε / (7 * tm.sqrt)) with hε'
528+
set a := Int.clog 2 (1 / ε') with ha
529+
use a.toNat
530+
rintro b hb q ⟨hq₁, hq₂⟩
531+
by_cases hq₃ : q ≤ 0
532+
· have h₂ : Int.sqrt (q.num * 4 ^ b) = 0 := by
533+
rw [Int.sqrt.eq_1, Int.ofNat_eq_zero, Nat.sqrt_eq_zero, Int.toNat_eq_zero]
534+
exact Int.mul_nonpos_of_nonpos_of_nonneg (Rat.num_nonpos.mpr hq₃) (by positivity)
535+
simp [Real.sqrt_eq_zero'.mpr (Rat.cast_nonpos.mpr hq₃), h₂, hε, hq₃]
536+
have hb₂ := ub_sub_le_sqrt q b
537+
rw [if_neg hq₃] at hb₂ ⊢
538+
push_neg at hq₃
539+
suffices 7 * √↑q / 2 ^ b < ε by
540+
have hb₁ := rsqrt_le_boundedSqrt q b 4 (by norm_num)
541+
rw [Nat.cast_ofNat] at hb₁
542+
rw [abs_sub_lt_iff]
543+
constructor <;> linarith
544+
replace hb : Int.clog 2 (1 / ε') ≤ b := Int.toNat_le.mp hb
545+
replace hb : 2 ^ (Int.clog 2 (1 / ε')) ≤ (2 : ℝ) ^ (b : ℤ) := zpow_le_zpow_right₀ (one_le_two) hb
546+
replace hb := le_trans (Int.self_le_zpow_clog Nat.one_lt_two (1 / ε')) hb
547+
rw [hε', zpow_natCast] at hb
548+
have hqtm := Real.sqrt_lt_sqrt (Rat.cast_nonneg.mpr hq₃.le) hq₂
549+
have hq0 := Real.sqrt_pos_of_pos (Rat.cast_pos.mpr hq₃)
550+
simp only [one_div, inv_div] at hb
551+
rw [div_le_iff₀ (by positivity)] at hb
552+
rw [div_lt_iff₀ (by positivity), _root_.mul_comm ε]
553+
linarith
401554

402555
def sqrt : ComputableℝSeq → ComputableℝSeq :=
403556
of_TendstoLocallyUniformly_Continuous
@@ -448,7 +601,7 @@ instance instComputableSqrtTwoAddSeries (x : ℝ) [hx : IsComputable x] (n : ℕ
448601
IsComputable (Real.sqrtTwoAddSeries x n) :=
449602
n.rec hx (fun _ _ ↦ instComputableSqrt _)
450603

451-
example : Real.sqrt (1 + 1/4) > 2 + Real.sqrt 3 - Real.sqrt 7 := by
604+
example : Real.sqrt (1 + 1/4) > Real.sqrt (2 + Real.sqrt 3) / (Real.sqrt 7 - 1/2) := by
452605
native_decide
453606

454607
end Sqrt
@@ -458,15 +611,16 @@ section Pi
458611
/-- See theorem Real.pi_gt_sqrtTwoAddSeries in Mathlib -/
459612
def pi_lb (n : ℕ) : ℚ :=
460613
let TwoSubSqrt2SeriesN := (inferInstance : IsComputable (Real.sqrt (2 - Real.sqrtTwoAddSeries 0 n))).seq
461-
2 ^ (n + 1) * TwoSubSqrt2SeriesN.lb n
614+
2 ^ (n + 1) * TwoSubSqrt2SeriesN.lb (2 * n)
462615

463616
/-- See theorem Real.pi_gt_sqrtTwoAddSeries in Mathlib -/
464617
def pi_ub (n : ℕ) : ℚ :=
465618
let TwoSubSqrt2SeriesN := (inferInstance : IsComputable (Real.sqrt (2 - Real.sqrtTwoAddSeries 0 n))).seq
466-
2 ^ (n + 1) * TwoSubSqrt2SeriesN.ub n + 1 / 4 ^ n
619+
2 ^ (n + 1) * TwoSubSqrt2SeriesN.ub (2 * n) + 1 / 4 ^ n
467620

468-
--100ms for 10^-40 precision
469-
-- #time #eval! Rat.toDecimal (prec := 40) (pi_ub 100 - 3.14159265358979323846264338327950288419716939937510)
621+
-- 60ms for 10^-40 precision
622+
-- #time #eval! Rat.toDecimal (prec := 40) (pi_ub 65 - 3.14159265358979323846264338327950288419716939937510)
623+
-- #time #eval! Rat.toDecimal (prec := 40) (pi_lb 65 - 3.14159265358979323846264338327950288419716939937510)
470624

471625
end Pi
472626

0 commit comments

Comments
 (0)