-
Notifications
You must be signed in to change notification settings - Fork 840
[Merged by Bors] - feat(Data/Nat): define Nat.nthRoot
#28768
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
yury-harmonic
wants to merge
14
commits into
leanprover-community:master
from
yury-harmonic:YK-nthroot
Closed
Changes from 1 commit
Commits
Show all changes
14 commits
Select commit
Hold shift + click to select a range
7a081b7
feat(Data/Nat): define `Nat.nthRoot`
yury-harmonic 5c26b94
Apply suggestions from code review
yury-harmonic e6676ea
Redefine
yury-harmonic 65d1045
Fix
yury-harmonic f911978
Apply suggestions from code review
yury-harmonic 67877b2
Merge branch 'master' into YK-nthroot
yury-harmonic bd28645
Merge branch 'master' into YK-nthroot
yury-harmonic 79bec62
Partially fix
yury-harmonic d976e01
Move a file
yury-harmonic 2f7b314
Merge branch 'master' into YK-nthroot
yury-harmonic 3dc663a
Change TODO
yury-harmonic f7584e2
Fix typos
yury-harmonic 96fd4ca
Merge branch 'master' into YK-nthroot
yury-harmonic 349f2fc
Import `Mathlib.Init`
yury-harmonic File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/- | ||
Copyright (c) 2025 Concordance Inc. dba Harmonic. All rights reserved. | ||
Released under Apache 2.0 license as described in the file LICENSE. | ||
Authors: Yury Kudryashov | ||
-/ | ||
|
||
/-! | ||
# Definition of `Nat.nthRoot` | ||
|
||
In this file we define `Nat.nthRoot n a` to be the floor of the `n`th root of `a`. | ||
The function is defined in terms of natural numbers with no dependencies outside of prelude. | ||
-/ | ||
|
||
/-- `Nat.nthRoot n a = ⌊(a : ℝ) ^ (1 / n : ℝ)⌋₊` defined in terms of natural numbers. | ||
|
||
We use Lagrange's method to find a root of $x^n = a$, | ||
so it converges superexponentially fast. -/ | ||
def Nat.nthRoot : Nat → Nat → Nat | ||
| 0, _ => 1 | ||
| 1, a => a | ||
| n + 2, a => | ||
if a ≤ 1 then a else go n a a | ||
where | ||
/-- Auxiliary definition for `Nat.nthRoot`. -/ | ||
go n a guess := | ||
let next := (a / guess^(n + 1) + (n + 1) * guess) / (n + 2) | ||
if next < guess then go n a next else guess | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
/- | ||
Copyright (c) 2025 Concordance Inc. dba Harmonic. All rights reserved. | ||
Released under Apache 2.0 license as described in the file LICENSE. | ||
Authors: Yury Kudryashov | ||
-/ | ||
import Mathlib.Analysis.MeanInequalities | ||
import Mathlib.Data.Nat.NthRoot.Defs | ||
import Mathlib.Tactic.Rify | ||
|
||
/-! | ||
# Lemmas about `Nat.nthRoot` | ||
|
||
In this file we prove that `Nat.nthRoot n a` is indeed the floor of `ⁿ√a`. | ||
|
||
## TODO | ||
|
||
Rewrite proofs to avoid dependencies on real numbers, | ||
so that we can move this file to Batteries. | ||
-/ | ||
|
||
namespace Nat | ||
|
||
@[simp] theorem nthRoot_zero_left (a : ℕ) : nthRoot 0 a = 1 := rfl | ||
|
||
@[simp] theorem nthRoot_one_left : nthRoot 1 = id := rfl | ||
|
||
theorem nthRoot.pow_go_le (n a b : ℕ) : (go n a b)^(n + 2) ≤ a := by | ||
yury-harmonic marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
induction b using Nat.strongRecOn with | ||
| ind b ihb => | ||
rw [go] | ||
split_ifs with h | ||
case pos => | ||
exact ihb _ h | ||
case neg => | ||
have : b ≤ a / b^(n + 1) := by linarith only [Nat.mul_le_of_le_div _ _ _ (not_lt.1 h)] | ||
replace := Nat.mul_le_of_le_div _ _ _ this | ||
rwa [← Nat.pow_succ'] at this | ||
|
||
variable {n a b : ℕ} | ||
|
||
theorem nthRoot.lt_pow_go_succ_aux (h : a < b ^ (n + 1)) : | ||
a < ((a / b ^ n + n * b) / (n + 1) + 1) ^ (n + 1) := by | ||
rcases eq_or_ne b 0 with rfl | hb; · simp at h | ||
rcases Nat.eq_zero_or_pos n with rfl | hn; · simp | ||
rw [← Nat.add_mul_div_left a, Nat.div_div_eq_div_mul] <;> try positivity | ||
rify | ||
calc | ||
(a : ℝ) = ((a / b^n) ^ (1 / (n + 1) : ℝ) * b^(n / (n + 1) : ℝ)) ^ (n + 1) := by | ||
yury-harmonic marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
rw [mul_pow, ← Real.rpow_mul_natCast, ← Real.rpow_mul_natCast] <;> try positivity | ||
field_simp | ||
_ ≤ ((1 / (n + 1)) * (a / b^n) + (n / (n + 1)) * b) ^ (n + 1) := by | ||
yury-harmonic marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
gcongr | ||
apply Real.geom_mean_le_arith_mean2_weighted <;> try positivity | ||
field_simp [add_comm] | ||
_ = ((a + b^n * (n * b)) / (b^n * (n + 1))) ^ (n + 1) := by | ||
yury-harmonic marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
congr 1 | ||
field_simp | ||
ring | ||
_ < _ := by | ||
gcongr ?_ ^ _ | ||
convert lt_floor_add_one (R := ℝ) _ using 1 | ||
norm_cast | ||
rw [Nat.floor_div_natCast, Nat.floor_natCast] | ||
|
||
theorem nthRoot.lt_pow_go_succ (hb : a < (b + 1) ^ (n + 2)) : a < (go n a b + 1) ^ (n + 2) := by | ||
induction b using Nat.strongRecOn with | ||
| ind b ihb => | ||
rw [go] | ||
split_ifs with h | ||
case pos => | ||
rcases eq_or_ne b 0 with rfl | hb | ||
· simp at * | ||
yury-harmonic marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
apply ihb _ h | ||
replace h : a < b^(n + 2) := by | ||
yury-harmonic marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
rw [Nat.div_lt_iff_lt_mul (by positivity)] at h | ||
replace h : a / b ^ (n + 1) < b := by linarith only [h] | ||
rwa [Nat.div_lt_iff_lt_mul (by positivity), ← Nat.pow_succ'] at h | ||
exact Nat.nthRoot.lt_pow_go_succ_aux h | ||
case neg => | ||
assumption | ||
|
||
theorem pow_nthRoot_le (hn : n ≠ 0) (a : ℕ) : (nthRoot n a)^n ≤ a := by | ||
yury-harmonic marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
match n, hn with | ||
| 1, _ => simp | ||
| n + 2, _ => | ||
simp only [nthRoot] | ||
split_ifs with h | ||
case pos => interval_cases a <;> simp | ||
case neg => apply nthRoot.pow_go_le | ||
|
||
theorem lt_pow_nthRoot_add_one (hn : n ≠ 0) (a : ℕ) : a < (nthRoot n a + 1)^n := by | ||
yury-harmonic marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
match n, hn with | ||
| 1, _ => simp | ||
| n + 2, hn => | ||
simp only [nthRoot] | ||
split_ifs with h | ||
case pos => interval_cases a <;> simp | ||
case neg => | ||
apply nthRoot.lt_pow_go_succ | ||
exact a.lt_succ_self.trans_le (Nat.le_self_pow hn _) | ||
|
||
@[simp] | ||
theorem le_nthRoot_iff (hn : n ≠ 0) : a ≤ nthRoot n b ↔ a^n ≤ b := by | ||
yury-harmonic marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
cases le_or_gt a (nthRoot n b) with | ||
| inl hle => | ||
simp only [hle, true_iff] | ||
refine le_trans ?_ (pow_nthRoot_le hn b) | ||
gcongr | ||
| inr hlt => | ||
simp only [hlt.not_ge, false_iff, not_le] | ||
refine (lt_pow_nthRoot_add_one hn b).trans_le ?_ | ||
gcongr | ||
assumption | ||
|
||
@[simp] | ||
theorem nthRoot_lt_iff (hn : n ≠ 0) : nthRoot n a < b ↔ a < b^n := by | ||
yury-harmonic marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
simp only [← not_le, le_nthRoot_iff hn] | ||
|
||
@[simp] | ||
theorem nthRoot_pow (hn : n ≠ 0) (a : ℕ) : nthRoot n (a ^ n) = a := by | ||
refine eq_of_forall_le_iff fun b ↦ ?_ | ||
rw [le_nthRoot_iff hn] | ||
exact (Nat.pow_left_strictMono hn).le_iff_le | ||
|
||
theorem nthRoot_eq_of_le_of_lt (h₁ : a ^ n ≤ b) (h₂ : b < (a + 1) ^ n) : | ||
nthRoot n b = a := by | ||
rcases eq_or_ne n 0 with rfl | hn | ||
· rw [pow_zero] at *; omega | ||
simp only [← le_nthRoot_iff hn, ← nthRoot_lt_iff hn] at h₁ h₂ | ||
omega | ||
yury-harmonic marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
theorem exists_pow_eq_iff' (hn : n ≠ 0) : (∃ x, x ^ n = a) ↔ (nthRoot n a) ^ n = a := by | ||
constructor | ||
· rintro ⟨x, rfl⟩ | ||
rw [nthRoot_pow hn] | ||
· exact fun h ↦ ⟨_, h⟩ | ||
yury-harmonic marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
theorem exists_pow_eq_iff : | ||
(∃ x, x ^ n = a) ↔ ((n = 0 ∧ a = 1) ∨ (n ≠ 0 ∧ (nthRoot n a) ^ n = a)) := by | ||
rcases eq_or_ne n 0 with rfl | hn | ||
· simp [eq_comm] | ||
· simp [exists_pow_eq_iff', hn] | ||
yury-harmonic marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
instance instDecidableExistsPowEq : Decidable (∃ x, x ^ n = a) := | ||
decidable_of_iff' _ exists_pow_eq_iff | ||
|
||
end Nat |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.