Skip to content
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

[Merged by Bors] - feat: Positivity extension for Finset.prod #9365

Closed
wants to merge 29 commits into from
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
64fa1c5
feat: Positivity extension for `Finset.sum`
YaelDillies Dec 30, 2023
eb70e94
remove unused instance synthesis
YaelDillies Dec 31, 2023
5aa5b0e
golf downstream
YaelDillies Dec 31, 2023
e964bfd
hack
eric-wieser Dec 31, 2023
695ea52
beta expand if needed
alexjbest Dec 31, 2023
ca61d08
Merge remote-tracking branch 'origin/master' into positivity_finset_sum
eric-wieser Feb 12, 2024
c3d02ea
simplify logic
eric-wieser Feb 12, 2024
738c7cc
better logic
YaelDillies Feb 12, 2024
4c0225b
check for debug
YaelDillies Feb 12, 2024
2285697
fix
eric-wieser Feb 12, 2024
d7456a3
remove unreachable failure
YaelDillies Feb 12, 2024
6161d23
add todo
YaelDillies Feb 12, 2024
92ec7dc
revert AkraBazzi
YaelDillies Feb 12, 2024
5e8424f
feat: Positivity extension for `Finset.prod`
YaelDillies Feb 13, 2024
72d04bd
golfs
YaelDillies Feb 13, 2024
40fe08f
Merge pull request #10481 from leanprover-community/positivity_finset…
YaelDillies Feb 13, 2024
b654c75
Merge remote-tracking branch 'origin/master' into positivity_finset_sum
YaelDillies Feb 18, 2024
9c7ccba
Merge remote-tracking branch 'origin/master' into positivity_finset_sum
YaelDillies Feb 22, 2024
4091f23
tests
YaelDillies Feb 22, 2024
e27d652
don't use @
YaelDillies Feb 23, 2024
3050994
Merge remote-tracking branch 'origin/master' into positivity_finset_sum
YaelDillies Feb 29, 2024
56eeb82
Merge remote-tracking branch 'origin/master' into positivity_finset_sum
YaelDillies Feb 29, 2024
2da120c
Merge remote-tracking branch 'origin/master' into positivity_finset_sum
YaelDillies Mar 6, 2024
65e6593
Eric's no-monadic-failure paradigm
YaelDillies Mar 6, 2024
214fec9
Merge remote-tracking branch 'origin/master' into positivity_finset_sum
YaelDillies Apr 3, 2024
7003214
suggestions
YaelDillies Apr 3, 2024
bc25cf0
whitespace for clarity
YaelDillies Apr 4, 2024
3aefce7
Merge remote-tracking branch 'origin/master' into positivity_finset_sum
YaelDillies Apr 5, 2024
e6a642d
bump
YaelDillies Apr 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions Mathlib/Algebra/BigOperators/Order.lean
YaelDillies marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -830,3 +830,57 @@ theorem IsAbsoluteValue.map_prod [CommSemiring R] [Nontrivial R] [LinearOrderedC
#align is_absolute_value.map_prod IsAbsoluteValue.map_prod

end AbsoluteValue

namespace Mathlib.Meta.Positivity
open Qq Lean Meta Finset

/-- The `positivity` extension which proves that `∑ i in s, f i` is nonnegative if `f` is, and
positive if each `f i` is and `s` is nonempty.

Note that this does not do any complicated reasoning. In particular, it does not try to feed in the
`i ∈ s` hypothesis to local assumptions, and the only ways it can prove `s` is nonempty is if there
is a local `s.Nonempty` hypothesis or `s = (univ : Finset α)` and `Nonempty α` can be synthesized by
TC inference. -/
@[positivity Finset.sum _ _]
def evalFinsetSum : PositivityExt where eval {u α} zα pα e := do
match e with
| ~q(@Finset.sum _ $ι $instα $s $f) =>
let (lhs, _, (rhs : Q($α))) ← lambdaMetaTelescope (if f.isLambda then f else q(fun x => $f x))
YaelDillies marked this conversation as resolved.
Show resolved Hide resolved
-- TODO: The following annotation is ignored. See leanprover/lean4#3126
let so : Option Q(Finset.Nonempty $s) ← do
try
match s with
| ~q(@univ _ $fi) => do
-- TODO(Qq): doesn't type-check without explicit `u`, even though it works outside the
-- `match`.
let _no ← synthInstanceQ (u := 0) q(Nonempty $ι)
return some q(Finset.univ_nonempty (α := $ι))
| _ => throwError "`s` is not `univ`"
catch _ => do
let .some fv ← findLocalDeclWithType? q(Finset.Nonempty $s) | pure none
pure (some (.fvar fv))
match ← core zα pα rhs, so with
| .nonnegative pb, _ => do
let pα' ← synthInstanceQ q(OrderedAddCommMonoid $α)
assertInstancesCommute
let pr : Q(∀ i, 0 ≤ $f i) ← mkLambdaFVars lhs pb
return .nonnegative q(@sum_nonneg $ι $α $pα' $f $s fun i _ ↦ $pr i)
| .positive pb, .some (fi : Q(Finset.Nonempty $s)) => do
let pα' ← synthInstanceQ q(OrderedCancelAddCommMonoid $α)
assertInstancesCommute
let pr : Q(∀ i, 0 < $f i) ← mkLambdaFVars lhs pb
return .positive q(@sum_pos $ι $α $pα' $f $s (fun i _ ↦ $pr i) $fi)
| _, _ => pure .none
| _ => throwError "not Finset.sum"

example (n : ℕ) (a : ℕ → ℤ) : 0 ≤ ∑ j in range n, a j^2 := by positivity
example (a : ULift.{2} ℕ → ℤ) (s : Finset (ULift.{2} ℕ)) : 0 ≤ ∑ j in s, a j^2 := by positivity
example (n : ℕ) (a : ℕ → ℤ) : 0 ≤ ∑ j : Fin 8, ∑ i in range n, (a j^2 + i ^ 2) := by positivity
example (n : ℕ) (a : ℕ → ℤ) : 0 < ∑ j : Fin (n + 1), (a j^2 + 1) := by positivity
example (a : ℕ → ℤ) : 0 < ∑ j in ({1} : Finset ℕ), (a j^2 + 1) := by
have : Finset.Nonempty {1} := singleton_nonempty 1
positivity
example (s : Finset (ℕ)) : 0 ≤ ∑ j in s, j := by positivity
example (s : Finset (ℕ)) : 0 ≤ s.sum id := by positivity

end Mathlib.Meta.Positivity
2 changes: 0 additions & 2 deletions Mathlib/Analysis/Analytic/Inverse.lean
Original file line number Diff line number Diff line change
Expand Up @@ -535,8 +535,6 @@ theorem radius_rightInv_pos_of_radius_pos (p : FormalMultilinearSeries 𝕜 E F)
exact mul_nonneg (add_nonneg (norm_nonneg _) zero_le_one) apos.le
· intro n one_le_n hn
have In : 2 ≤ n + 1 := by linarith only [one_le_n]
have Snonneg : 0 ≤ S n :=
sum_nonneg fun x _ => mul_nonneg (pow_nonneg apos.le _) (norm_nonneg _)
have rSn : r * S n ≤ 1 / 2 :=
calc
r * S n ≤ r * ((I + 1) * a) := by gcongr
Expand Down
12 changes: 4 additions & 8 deletions Mathlib/Analysis/Calculus/ContDiff/Bounds.lean
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,7 @@ theorem ContinuousLinearMap.norm_iteratedFDerivWithin_le_of_bilinear_aux {Du Eu
IH _ (hf.of_le (Nat.cast_le.2 (Nat.le_succ n))) (hg.fderivWithin hs In)
_ ≤ ‖B‖ * ∑ i : ℕ in Finset.range (n + 1), n.choose i * ‖iteratedFDerivWithin 𝕜 i f s x‖ *
‖iteratedFDerivWithin 𝕜 (n - i) (fderivWithin 𝕜 g s) s x‖ :=
(mul_le_mul_of_nonneg_right (B.norm_precompR_le Du)
(Finset.sum_nonneg' fun i => by positivity))
mul_le_mul_of_nonneg_right (B.norm_precompR_le Du) (by positivity)
_ = _ := by
congr 1
apply Finset.sum_congr rfl fun i hi => ?_
Expand All @@ -90,8 +89,7 @@ theorem ContinuousLinearMap.norm_iteratedFDerivWithin_le_of_bilinear_aux {Du Eu
_ ≤ ‖B‖ * ∑ i : ℕ in Finset.range (n + 1),
n.choose i * ‖iteratedFDerivWithin 𝕜 i (fderivWithin 𝕜 f s) s x‖ *
‖iteratedFDerivWithin 𝕜 (n - i) g s x‖ :=
(mul_le_mul_of_nonneg_right (B.norm_precompL_le Du)
(Finset.sum_nonneg' fun i => by positivity))
mul_le_mul_of_nonneg_right (B.norm_precompL_le Du) (by positivity)
_ = _ := by
congr 1
apply Finset.sum_congr rfl fun i _ => ?_
Expand Down Expand Up @@ -222,8 +220,7 @@ theorem ContinuousLinearMap.norm_iteratedFDerivWithin_le_of_bilinear (B : E →L
‖iteratedFDerivWithin 𝕜 (n - i) gu su xu‖ :=
Bu.norm_iteratedFDerivWithin_le_of_bilinear_aux hfu hgu hsu hxu
simp only [Nfu, Ngu, NBu] at this
apply this.trans (mul_le_mul_of_nonneg_right Bu_le ?_)
exact Finset.sum_nonneg' fun i => by positivity
exact this.trans (mul_le_mul_of_nonneg_right Bu_le (by positivity))
#align continuous_linear_map.norm_iterated_fderiv_within_le_of_bilinear ContinuousLinearMap.norm_iteratedFDerivWithin_le_of_bilinear

/-- Bounding the norm of the iterated derivative of `B (f x) (g x)` in terms of the
Expand All @@ -249,8 +246,7 @@ theorem ContinuousLinearMap.norm_iteratedFDerivWithin_le_of_bilinear_of_le_one
∑ i in Finset.range (n + 1), (n.choose i : ℝ) * ‖iteratedFDerivWithin 𝕜 i f s x‖ *
‖iteratedFDerivWithin 𝕜 (n - i) g s x‖ := by
apply (B.norm_iteratedFDerivWithin_le_of_bilinear hf hg hs hx hn).trans
apply mul_le_of_le_one_left (Finset.sum_nonneg' fun i => ?_) hB
positivity
exact mul_le_of_le_one_left (by positivity) hB
#align continuous_linear_map.norm_iterated_fderiv_within_le_of_bilinear_of_le_one ContinuousLinearMap.norm_iteratedFDerivWithin_le_of_bilinear_of_le_one

/-- Bounding the norm of the iterated derivative of `B (f x) (g x)` in terms of the
Expand Down
3 changes: 0 additions & 3 deletions Mathlib/Computability/AkraBazzi/AkraBazzi.lean
Original file line number Diff line number Diff line change
Expand Up @@ -1162,7 +1162,7 @@
/-- The main proof of the upper bound part of the Akra-Bazzi theorem. The factor
`1 - ε n` does not change the asymptotic order, but is needed for the induction step to go
through. -/
lemma T_isBigO_smoothingFn_mul_asympBound :

Check failure on line 1165 in Mathlib/Computability/AkraBazzi/AkraBazzi.lean

View workflow job for this annotation

GitHub Actions / Build

application type mismatch
T =O[atTop] (fun n => (1 - ε n) * asympBound g a b n) := by
let b' := b (min_bi b) / 2
have hb_pos : 0 < b' := R.bi_min_div_two_pos
Expand Down Expand Up @@ -1243,9 +1243,6 @@
* ((1 + (∑ u in range (r i n), g u / u ^ ((p a b) + 1)))))) + g n with i
· have := R.a_pos i
positivity
· refine add_nonneg zero_le_one <| Finset.sum_nonneg fun j _ => ?_
rw [div_nonneg_iff]
exact Or.inl ⟨R.g_nonneg j (by positivity), by positivity⟩
· exact bound1 n hn i
_ = (∑ i, C * a i * ((b i) ^ (p a b) * n ^ (p a b) * (1 - ε n)
* ((1 + ((∑ u in range n, g u / u ^ ((p a b) + 1))
Expand Down Expand Up @@ -1292,7 +1289,7 @@
/-- The main proof of the lower bound part of the Akra-Bazzi theorem. The factor
`1 + ε n` does not change the asymptotic order, but is needed for the induction step to go
through. -/
lemma smoothingFn_mul_asympBound_isBigO_T :

Check failure on line 1292 in Mathlib/Computability/AkraBazzi/AkraBazzi.lean

View workflow job for this annotation

GitHub Actions / Build

application type mismatch
(fun (n : ℕ) => (1 + ε n) * asympBound g a b n) =O[atTop] T := by
let b' := b (min_bi b) / 2
have hb_pos : 0 < b' := R.bi_min_div_two_pos
Expand Down Expand Up @@ -1388,10 +1385,10 @@
((1 + (∑ u in range (r i n), g u / u ^ ((p a b) + 1)))))) + g n with i
· have := R.a_pos i
positivity
· refine add_nonneg zero_le_one <| Finset.sum_nonneg fun j _ => ?_

Check failure on line 1388 in Mathlib/Computability/AkraBazzi/AkraBazzi.lean

View workflow job for this annotation

GitHub Actions / Build

typeclass instance problem is stuck, it is often due to metavariables
rw [div_nonneg_iff]
exact Or.inl ⟨R.g_nonneg j (by positivity), by positivity⟩
· exact bound2 n hn i

Check failure on line 1391 in Mathlib/Computability/AkraBazzi/AkraBazzi.lean

View workflow job for this annotation

GitHub Actions / Build

no goals to be solved
_ = (∑ i, C * a i * ((b i) ^ (p a b) * n ^ (p a b) * (1 + ε n)
* ((1 + ((∑ u in range n, g u / u ^ ((p a b) + 1))
- (∑ u in Finset.Ico (r i n) n, g u / u ^ ((p a b) + 1))))))) + g n := by
Expand Down Expand Up @@ -1439,7 +1436,7 @@
/-- The **Akra-Bazzi theorem**: `T ∈ O(n^p (1 + ∑_u^n g(u) / u^{p+1}))` -/
theorem isBigO_asympBound : T =O[atTop] asympBound g a b := by
calc T =O[atTop] (fun n => (1 - ε n) * asympBound g a b n) := by
exact R.T_isBigO_smoothingFn_mul_asympBound

Check failure on line 1439 in Mathlib/Computability/AkraBazzi/AkraBazzi.lean

View workflow job for this annotation

GitHub Actions / Build

invalid field 'T_isBigO_smoothingFn_mul_asympBound', the environment does not contain 'AkraBazziRecurrence.T_isBigO_smoothingFn_mul_asympBound'
_ =O[atTop] (fun n => 1 * asympBound g a b n) := by
refine IsBigO.mul (isBigO_const_of_tendsto (y := 1) ?_ one_ne_zero)
(isBigO_refl _ _)
Expand All @@ -1458,10 +1455,10 @@
show Tendsto ((fun n => 1 + ε n) ∘ (Nat.cast : ℕ → ℝ)) atTop (𝓝 1)
exact Tendsto.comp isEquivalent_one_add_smoothingFn_one.tendsto_const
tendsto_nat_cast_atTop_atTop
_ =O[atTop] T := R.smoothingFn_mul_asympBound_isBigO_T

Check failure on line 1458 in Mathlib/Computability/AkraBazzi/AkraBazzi.lean

View workflow job for this annotation

GitHub Actions / Build

invalid field 'smoothingFn_mul_asympBound_isBigO_T', the environment does not contain 'AkraBazziRecurrence.smoothingFn_mul_asympBound_isBigO_T'

/-- The **Akra-Bazzi theorem**: `T ∈ Θ(n^p (1 + ∑_u^n g(u) / u^{p+1}))` -/
theorem isTheta_asympBound : T =Θ[atTop] asympBound g a b :=
⟨R.isBigO_asympBound, R.isBigO_symm_asympBound⟩

Check failure on line 1462 in Mathlib/Computability/AkraBazzi/AkraBazzi.lean

View workflow job for this annotation

GitHub Actions / Build

invalid field notation, function 'AkraBazziRecurrence.isBigO_asympBound' does not have argument with type (AkraBazziRecurrence ...) that can be used, it must be explicit or implicit with a unique name

Check failure on line 1462 in Mathlib/Computability/AkraBazzi/AkraBazzi.lean

View workflow job for this annotation

GitHub Actions / Build

invalid field notation, function 'AkraBazziRecurrence.isBigO_symm_asympBound' does not have argument with type (AkraBazziRecurrence ...) that can be used, it must be explicit or implicit with a unique name

end AkraBazziRecurrence
Loading