Zulip Chat Archive
Stream: Is there code for X?
Topic: division of DualNumbers
Frederick Pu (Apr 06 2024 at 03:01):
Is there any code or division of DualNumbers? More specifically Div (DualNumber F) where F is a field. If not, would it be possible for me to get a pull request from formalizing it? Right now I working on some proofs about negative binomials that geometric sequences on DualNumbers would really help with.
Yaël Dillies (Apr 06 2024 at 07:16):
If @Eric Wieser doesn't have it then nobody has it
Eric Wieser (Apr 06 2024 at 08:28):
You can work with Units (DualNumber _)
to get division of invertible elements. If you also want support for non-invertible elements; what do you intend to define 1/eps
as?
Frederick Pu (Apr 06 2024 at 22:28):
Frederick Pu said:
Is there any code or division of DualNumbers? More specifically Div (DualNumber F) where F is a field. If not, would it be possible for me to get a pull request from formalizing it? Right now I working on some proofs about negative binomials that geometric sequences on DualNumbers would really help with.
Here's a quick demo of what I've done so far with division:
Definition of division:
noncomputable instance : Div (DualNumber ℝ) :=
{
div := fun ⟨a, b⟩ ⟨c, d⟩ => ⟨a/c, (b*c - a*d)/c^2⟩
}
Basic lemmas to make proofs easier
theorem div_eq (a b : DualNumber ℝ) : a / b = ⟨a.fst / b.fst, (a.snd * b.fst - a.fst * b.snd) / b.fst^2⟩ := by rfl
theorem add_eq (a b : DualNumber ℝ) : a + b = ⟨a.fst + b.fst, a.snd + b.snd⟩ := by exact rfl
theorem diff_eq (a b : DualNumber ℝ) : a - b = ⟨a.fst - b.fst, a.snd - b.snd⟩ := by exact rfl
Basic arithmetic equations:
theorem sum_one_div (a b : DualNumber ℝ) (ha : a.fst ≠ 0) (hb : b.fst ≠ 0) : 1 / a + 1 / b = (b + a) / (a*b) := by
...
theorem diff_one_div (a b : DualNumber ℝ) (ha : a.fst ≠ 0) (hb : b.fst ≠ 0) : 1 / a - 1 / b = (b - a) / (a*b) := by
...
Projection equations:
theorem fst_one_div_real (a : ℝ) : (1 / TrivSqZeroExt.inl a : DualNumber ℝ).1 = 1 / a := by
rw [div_eq]
simp
theorem snd_one_div_real (a : ℝ) : (1 / TrivSqZeroExt.inl a : DualNumber ℝ).2 = 0 := by
rw [div_eq]
simp
Putting it all together into a usage example:
example (a b : ℝ) (ha : a ≠ 0) : ε / (TrivSqZeroExt.inl a + (TrivSqZeroExt.inl b)*DualNumber.eps : DualNumber ℝ) = ε * (1 / (TrivSqZeroExt.inl a)) := by
rw [div_eq]
apply congr_arg₂
simp
apply Or.inl
rfl
simp [fst_one_div_real, snd_one_div_real]
field_simp
have : (ε :DualNumber ℝ).2 = 1 := by rfl
rw [this]
ring
Eric Wieser (Apr 06 2024 at 22:29):
Something to watch out for here; you should not use .1
(Prod.fst
) on dual numbers; you should use .fst
(TrivSqZeroExt.fst
) instead
Eric Wieser (Apr 06 2024 at 22:31):
Similarly, using ⟨re, dual⟩
will get you into trouble because this is Prod.mk
; the API assumes you will write algebraMap _ _ re + dual*eps
instead (or inl re + inr dual
)
Frederick Pu (Apr 09 2024 at 03:05):
Eric Wieser said:
You can work with
Units (DualNumber _)
to get division of invertible elements. If you also want support for non-invertible elements; what do you intend to define1/eps
as?
I'm thinking of treating division as the deriv operator. That is if the division exists than it is well defined but otherwise it'll give a garbage output of .
Frederick Pu (Apr 09 2024 at 03:08):
Eric Wieser said:
Something to watch out for here; you should not use
.1
(Prod.fst
) on dual numbers; you should use.fst
(TrivSqZeroExt.fst
) instead
Please correct me if I'm wrong but it feels like using the Prod notation makes a lot of elementary proofs easier to do using simp.
For example:
theorem fst_one_div_real (a : ℝ) : (1 / TrivSqZeroExt.inl a : DualNumber ℝ).1 = 1 / a := by
rw [div_eq]
simp
theorem snd_one_div_real (a : ℝ) : (1 / TrivSqZeroExt.inl a : DualNumber ℝ).2 = 0 := by
rw [div_eq]
simp
Kevin Buzzard (Apr 09 2024 at 09:10):
If you're only looking to divide by units then I would define Inv to be inverse on units and 0 off them, I would consider using IsUnit rather than a.1 != 0
as your normal form, and I would define Div to be a * b^{-1}.
Eric Wieser (Apr 09 2024 at 09:14):
Please correct me if I'm wrong but it feels like using the Prod notation makes a lot of elementary proofs easier to do using simp.
The rest of the TrivSqZeroExt API is not written with Prod.fst
and Prod.snd
, so if you use these functions then Mathlib has nothing to offer you
Eric Wieser (Apr 09 2024 at 09:14):
I think those lemmas are a bad example, because you should just prove them with rfl
anyway
Eric Wieser (Apr 09 2024 at 09:17):
Anyway, I think this is close enough to iterate on; could you make a PR adding Div
for TrivSqZeroExt
?
Frederick Pu (Apr 10 2024 at 00:45):
Eric Wieser said:
I think those lemmas are a bad example, because you should just prove them with
rfl
anyway
Yeah I would love to. I don't think I have access to any of the mathlib sub-branches though
Kim Morrison (Apr 11 2024 at 16:27):
What do you mean by sub-branches?
Kevin Buzzard (Apr 11 2024 at 16:42):
I conjecture that Frederick might mean that they would like push access to non-master branches? What's your GitHub userid Frederick? It's not in your profile.
Or tell us what you actually meant :-)
Frederick Pu (Apr 11 2024 at 19:10):
Yeah that's what I meant. In the the "how to contribute to mathlib" page it said that you should get accesss to a non-master branch. Also, should I develop a lot of the lemma for it first or just start by commiting the definition?
Kevin Buzzard (Apr 11 2024 at 19:14):
Well you can't do any of those things until you answer the question about your GitHub userid. I think a reasonable PR would be the definition of Inv and Div, and some basic lemmas. As a general rule I wouldn't go over 100 lines for the first PR.
Eric Wieser (Apr 11 2024 at 19:15):
You need to tell us your github username (or put it in your zulip profile) for us to give you access :)
Frederick Pu (Apr 11 2024 at 19:15):
Ok my user id for github is FrederickPu
Eric Wieser (Apr 11 2024 at 19:18):
Invite sent!
Eric Wieser (Apr 11 2024 at 19:19):
Regarding the generalization to TrivSqZeroExt
; I think it's something like
instance : Inv (tsze R M) where
inv x := ⟨x.fst⁻¹, -(x.fst⁻¹ •> x.snd <• x.fst⁻¹)⟩
Frederick Pu (Apr 11 2024 at 19:57):
Created the pull request. I just did it using HDiv instead of inverses since I feel like it would be weird to assume that the internal division of M and R sepereatly should have anything to do with how they interact with eachother. Although this may lead to some compatibility issue in the future since I was mainly thinking about TrivExtZero R R
Eric Wieser (Apr 11 2024 at 20:10):
The case to be careful of is TrivSqZeroExt R R
when R
is non-commutativie
Eric Wieser (Apr 11 2024 at 20:16):
In the non-commutative case, division is a pretty useless operator, since it only lets you write a * inv b
not inv a * b
. So I think it is better to approach this thinking about defining the inverse; and then define division such that a / b = a * inv b
, perhaps with a slightly nicer implementation.
The important thing is to prove a div_eq_mul_inv
lemma!
Frederick Pu (Apr 11 2024 at 20:26):
Oh sorry should I redo it and submit another PR or wait till you reject my current one first?
Eric Wieser (Apr 11 2024 at 20:33):
You can edit the PR in place, no need to redo it or delete it; just make another commit with the changes and push again
Eric Wieser (Apr 11 2024 at 20:36):
Ah sorry, you do need to redo this
Eric Wieser (Apr 11 2024 at 20:36):
Because you pushed to origin
, not upstream
Frederick Pu (Apr 11 2024 at 20:37):
Also it seems like the definition of inv should be more like this:
instance inv [HSub R M M] [Mul R] [Inv R] [SMul Rᵐᵒᵖ M] [SMul R M] : Inv (tsze R M) :=
⟨fun b => (b.1⁻¹, (b.1 - b.2) <• (b.1 * b.1)⁻¹)⟩
Frederick Pu (Apr 11 2024 at 20:38):
But HSub R M M is a bit sketch
Frederick Pu (Apr 11 2024 at 20:48):
ok. Can I get some feed back of my definition before I submit a PR?
Eric Wieser (Apr 11 2024 at 20:48):
The best place for feedback is in the PR itself!
Eric Wieser (Apr 11 2024 at 20:48):
Frederick Pu said:
Also it seems like the definition of inv should be more like this:
instance inv [HSub R M M] [Mul R] [Inv R] [SMul Rᵐᵒᵖ M] [SMul R M] : Inv (tsze R M) := ⟨fun b => (b.1⁻¹, (b.1 - b.2) <• (b.1 * b.1)⁻¹)⟩
But I can tell you that your hunch is right, HSub R M M
is too sketchy for this to be reasonable
Eric Wieser (Apr 11 2024 at 20:49):
I think you made an error when substituting $$1 + 0\eps$$, and that b.1
should be 0
.
Frederick Pu (Apr 11 2024 at 20:49):
Which of these do you think is better?
instance inv [HSub R M M] [Mul R] [Field R] [Semiring M] [SMul Rᵐᵒᵖ M] [SMul R M] : Inv (tsze R M) :=
⟨fun b => (b.1⁻¹, (b.1 * (b.1 * b.1)⁻¹) •> (1:M) + (b.2 <• (b.1 * b.1)⁻¹))⟩
instance inv [HSub R M M] [Mul R] [Inv R] [One M] [Add M] [SMul Rᵐᵒᵖ M] [SMul R M] : Inv (tsze R M) :=
⟨fun b => (b.1⁻¹, (b.1 * (b.1 * b.1)⁻¹) •> (1:M) + (b.2 <• (b.1 * b.1)⁻¹))⟩
Frederick Pu (Apr 11 2024 at 20:50):
I feel like the Field and Semiring conditions nicely encapsulate the requirements but might be too restrictive if someone wants to go crazy
Eric Wieser (Apr 11 2024 at 20:51):
Eric Wieser said:
Regarding the generalization to
TrivSqZeroExt
; I think it's something likeinstance : Inv (tsze R M) where inv x := ⟨x.fst⁻¹, -(x.fst⁻¹ •> x.snd <• x.fst⁻¹)⟩
I'm pretty sure this one is right, as it matches docs#fderiv_inv'
Eric Wieser (Apr 11 2024 at 20:53):
1 : M
is suspicious in your code above too; remember that (1 : tsze R M) = inl (1 : R) + inr (0 : M)
Eric Wieser (Apr 11 2024 at 20:54):
So if you take your division formula for fun ⟨a, b⟩ ⟨c, d⟩ => ⟨a/c, (b*c - a*d)/c^2⟩
, you should be subsituting a = 1
and b = 0
.
Eric Wieser (Apr 11 2024 at 20:56):
Frederick Pu said:
I feel like the Field and Semiring conditions nicely encapsulate the requirements but might be too restrictive if someone wants to go crazy
I am afraid that a lot of the design of TrivSqZeroExt is precise because someone wanted to go crazy with non-commutative rings (such as the dual quaternions); that someone is me.
Frederick Pu (Apr 11 2024 at 20:59):
Eric Wieser said:
Eric Wieser said:
Regarding the generalization to
TrivSqZeroExt
; I think it's something likeinstance : Inv (tsze R M) where inv x := ⟨x.fst⁻¹, -(x.fst⁻¹ •> x.snd <• x.fst⁻¹)⟩
I'm pretty sure this one is right, as it matches docs#fderiv_inv'
Wait so M is responsible for the negativeness? also why not group the inverses together?
Eric Wieser (Apr 11 2024 at 21:01):
Because grouping together inverses in the derivative of x⁻¹
is a lie told to you by commutative algebraists :devil:
Eric Wieser (Apr 11 2024 at 21:01):
Wait so M is responsible for the negativeness?
I don't think it really matters; in any real situation docs#neg_smul and docs#smul_neg applies anyway
Frederick Pu (Apr 11 2024 at 21:03):
@[simps apply]
def inlHom [Semiring R] [AddCommMonoid M] [Module R M] [Module Rᵐᵒᵖ M] : R →+* tsze R M where
It seems like R
usually carries more ring structure
Eric Wieser (Apr 11 2024 at 21:03):
In that example, neither R
nor M
have negation
Frederick Pu (Apr 11 2024 at 21:03):
so might as well put the negative in :shrug:
Eric Wieser (Apr 11 2024 at 21:03):
The version with negation is [Ring R] [AddCommGroup M]
, in which case both have negation
Frederick Pu (Apr 11 2024 at 21:04):
Oh sorry
Eric Wieser (Apr 11 2024 at 21:04):
Here's an argument for why it should be M
and not R
; if you assume some kind of derivative model, then maybe R
is the space of positive reals; the derivative of a function that's always positive can sometimes be negative, so arguably it's the differential piece (M) that should be carrying the negation
Frederick Pu (Apr 11 2024 at 21:04):
theorem snd_list_prod [Semiring R] [AddCommMonoid M] [Module R M] [Module Rᵐᵒᵖ M]
[SMulCommClass R Rᵐᵒᵖ M] (l : List (tsze R M))
Frederick Pu (Apr 11 2024 at 21:05):
Eric Wieser said:
Here's an argument for why it should be
M
and notR
; if you assume some kind of derivative model, then maybeR
is the space of positive reals; the derivative of a function that's always positive can sometimes be negative, so arguably it's the differential piece (M) that should be carrying the negation
that's a good point, but why is always somethign R over M?
Eric Wieser (Apr 11 2024 at 21:05):
What do you mean by "over"?
Frederick Pu (Apr 11 2024 at 21:07):
Never mind, I thought that semirings had inverses for some reason
Eric Wieser (Apr 11 2024 at 21:08):
It's an easy mistake to make, mathlib is full of generalizations you don't usually have to think about
Frederick Pu (Apr 11 2024 at 21:08):
The interface is actually pretty clean i think:
instance inv [Neg M] [Inv R] [SMul Rᵐᵒᵖ M] [SMul R M] : Inv (tsze R M) :=
⟨fun b => (b.1⁻¹, - (b.1⁻¹ •> b.2 <• b.1⁻¹))⟩
Frederick Pu (Apr 11 2024 at 21:10):
Also how do you motivate using b.1⁻¹ •> b.2 <• b.1⁻¹
vs b.2 <• b.1⁻¹ <• b.1⁻¹
Eric Wieser (Apr 11 2024 at 21:10):
Now you should define Div
as well, and prove that the two agree
Eric Wieser (Apr 11 2024 at 21:10):
The motivation will appear when you try to prove that x * x⁻¹ = 1
for [DivisionRing R]
and x.fst \ne 0
Frederick Pu (Apr 11 2024 at 21:11):
but if you're doing DivisionRing don't you have commutivity?
Eric Wieser (Apr 11 2024 at 21:14):
Nope, a division ring is a field without commutativity!
Frederick Pu (Apr 11 2024 at 21:14):
ahhhhh
Eric Wieser (Apr 11 2024 at 21:15):
(I think in French the words are swapped in some way, though I might be misremembering)
Frederick Pu (Apr 11 2024 at 21:16):
I'm not french tho, just a dumb undergrad
Eric Wieser (Apr 11 2024 at 21:19):
If you're writing lean code as an undergrad you're probably not dumb :)
Eric Wieser (Apr 11 2024 at 21:20):
Perhaps it's worth considering a more fun way to play this game:
- Define division and inverses in a way that works on fields and vector spaces, prove they work well with multiplication
- Once you have that working, try to remove commutativity
Frederick Pu (Apr 11 2024 at 21:39):
here's what I got so far:
theorem mul_inv [DivisionRing R] [AddCommGroup M] [Module Rᵐᵒᵖ M] [Module R M] {x : tsze R M} (hx : fst x ≠ 0) :
x * x⁻¹ = 1 := by
{
ext
rw [fst_mul, fst_inv, fst_one, mul_inv_cancel hx]
rw [snd_mul, snd_inv, smul_neg, ← smul_assoc, smul_eq_mul, mul_inv_cancel hx, one_smul, fst_inv, add_left_neg, snd_one]
}
Frederick Pu (Apr 11 2024 at 21:40):
it's tough because you need the module to bring the negative to the outside
Frederick Pu (Apr 11 2024 at 21:41):
actually no you don't I don't know what was requiring me to have a Module
Eric Wieser (Apr 11 2024 at 21:42):
I think it's fine to assume a module if you need it
Frederick Pu (Apr 11 2024 at 21:42):
But module requires addcommgroup
Eric Wieser (Apr 11 2024 at 21:43):
One again, no it doesn't; at least, not in mathlib!
Frederick Pu (Apr 11 2024 at 21:44):
Screenshot-2024-04-11-174407.png
Frederick Pu (Apr 11 2024 at 21:44):
So you still need commutivity on M no?
Eric Wieser (Apr 11 2024 at 21:44):
This is referring to additive commutativity, a + b = b + a
Frederick Pu (Apr 11 2024 at 21:45):
so you dont care about addcommgroup?
Eric Wieser (Apr 11 2024 at 21:45):
Only really crazy people care about non-commutative addition
Frederick Pu (Apr 11 2024 at 21:46):
the thing is don't really need addcommgroup in the proof. You're never swapping terms
Eric Wieser (Apr 11 2024 at 21:46):
Frederick Pu said:
so you dont care about addcommgroup?
What you've written looks good to me
Frederick Pu (Apr 11 2024 at 21:46):
is there a semimodule or smth
Eric Wieser (Apr 11 2024 at 21:46):
Yes, but in mathlib it's written Module
Eric Wieser (Apr 11 2024 at 21:47):
A semimodule is just a module without negation, but we established you need negation on M anyway
Frederick Pu (Apr 11 2024 at 21:47):
how can they have the exact same name?
Frederick Pu (Apr 11 2024 at 21:48):
oh cause no mul comm i see what u mean
Frederick Pu (Apr 11 2024 at 21:49):
Ok, submitting the PR
Frederick Pu (Apr 11 2024 at 22:02):
How do I run the linter on my local machine
Eric Wieser (Apr 11 2024 at 22:28):
Can you write the PR number here after a # so that it auto-Links?
Eric Wieser (Apr 11 2024 at 22:48):
The style linter can be run with scripts/lint-style.sh
Eric Wieser (Apr 11 2024 at 22:49):
The other linter can be run by writing #lint
in the file (and deleting it when you're done)
Notification Bot (Apr 11 2024 at 22:51):
95 messages were moved from this topic to #new members > making pull requests by Eric Wieser.
Frederick Pu (Apr 12 2024 at 00:34):
Do you know where I can find proofs of the following lemmas?
have op_smul_smul : ((fst x)⁻¹ •> (snd x <• (fst x)⁻¹)) <• fst x = (fst x)⁻¹ •> ((snd x <• (fst x)⁻¹) <• fst x) := by sorry
have op_smul_assoc : (snd x <• (fst x)⁻¹ <• fst x) = (snd x <• ((fst x)⁻¹ <• fst x)) := by sorry
have op_smul_one : (snd x) <• (1:R) = snd x := by sorry
Eric Wieser (Apr 12 2024 at 00:48):
The first one needs [SMulCommClass R Rᵐᵒᵖ M]
, then is smul_comm
Eric Wieser (Apr 12 2024 at 00:49):
simp?
or rw?
can maybe help find the others
Frederick Pu (Apr 12 2024 at 01:27):
I got the first and the third one but the second one is giving me grief
Frederick Pu (Apr 12 2024 at 15:16):
Actually I don't think this second equation holds
Kevin Buzzard (Apr 12 2024 at 15:55):
Can you make a #mwe if you want other people to think about your question?
Frederick Pu (Apr 12 2024 at 16:24):
Kevin Buzzard said:
Can you make a #mwe if you want other people to think about your question?
I should have used op_smul_op_smul instead
Frederick Pu (Apr 12 2024 at 17:20):
How long do you think until I will be able to use this on dual numbers?
theorem tsum_geometric_of_norm_lt_one{K : Type u_4} [NormedField K] {ξ : K} (h : ‖ξ‖ < 1) :
∑' (n : ℕ), ξ ^ n = (1 - ξ)⁻¹
Eric Wieser (Apr 12 2024 at 17:21):
You won't be able to use that theorem as written, because dual numbers don't form a field or even a division ring (eps
has no invers)
Frederick Pu (Apr 12 2024 at 17:22):
so will we need to reprove the theorem but for whatever the dual numbers are?
Frederick Pu (Apr 12 2024 at 17:22):
Maybe NormedRing, and it holds for all units
Frederick Pu (Apr 12 2024 at 17:23):
I feel like if you know convergence then u don't really use any field properties to prove the geometric series, just dividing by the common ratio, which is ok if it's not eps
Eric Wieser (Apr 12 2024 at 17:24):
I think a good goal would be to prove that lemma for just DualNumbers, then work out the generalizatoin when you have the proof
Frederick Pu (Apr 12 2024 at 17:24):
Yeah, but I'm gonna need the fact that the geometric sequence is summable in the first place. Which is some metric space stuff
Eric Wieser (Apr 12 2024 at 17:25):
We _do_ have a metric space on the dual numbers
Frederick Pu (Apr 12 2024 at 17:25):
should be fine then
Frederick Pu (Apr 12 2024 at 17:26):
Do u think I need anymore api stuff on TrivEqZeroExt inorder to get started?
Eric Wieser (Apr 12 2024 at 17:29):
I think it would be great to polish the PR on Inv and DIv first; then embark on that larger goal
Frederick Pu (Apr 12 2024 at 17:29):
Ok, should I edit my actual pull request comment?
Frederick Pu (Apr 12 2024 at 17:30):
also did you see my latest pull request, I proved all the lemmas u asked (except for 1/eps because I can't find that in Triv)
Eric Wieser (Apr 12 2024 at 17:32):
No, I didn't! looking at #12075 now
Frederick Pu (Apr 12 2024 at 17:36):
theorem summable_iff_vanishing_norm{ι : Type u_1} {E : Type u_3} [SeminormedAddCommGroup E] [CompleteSpace E] {f : ι → E} :
Summable f ↔ ∀ ε > 0, ∃ (s : Finset ι), ∀ (t : Finset ι), Disjoint t s → ‖Finset.sum t fun (i : ι) => f i‖ < ε
just so i remember
Eric Wieser (Apr 12 2024 at 17:59):
Frederick Pu said:
also did you see my latest pull request, I proved all the lemmas u asked (except for 1/eps because I can't find that in Triv)
That would go in the DualNumber.lean
file; it's fine to edit multiple files in the same PR if the changes are closely related.
Antoine Chambert-Loir (Apr 13 2024 at 07:12):
Frederick Pu said:
how can they have the exact same name?
In Mathlib, the docs#Module structure just adds the scalar action of R on M and how it interacts with addition. The interaction with negation, if there is some negation on M by way of a docs#AddCommGroup structure on M, the interaction of scalar multiplication with neg or subtraction comes for free.
Frederick Pu (Apr 13 2024 at 15:37):
Can anyone explain why tsum_mul_left isn't solvling this goal?
import Mathlib.Algebra.DualNumber
import Mathlib.Topology.Algebra.InfiniteSum.Ring
example {R : Type*} [DivisionRing R] (p : DualNumber R) [TopologicalSpace (DualNumber R)] [T2Space (DualNumber R)] (f : Nat → DualNumber R):
∑' (i : Nat), p^i = 1 + p * ∑' (x : Nat), f x := by
{
have : ∑' (x : Nat), p * f x = p * ∑' (x : Nat), f x := tsum_mul_left
}
#check tsum_mul_left
Frederick Pu (Apr 13 2024 at 15:43):
Frederick Pu said:
Can anyone explain why tsum_mul_left isn't solvling this goal?
import Mathlib.Algebra.DualNumber import Mathlib.Topology.Algebra.InfiniteSum.Ring example {R : Type*} [DivisionRing R] (p : DualNumber R) [TopologicalSpace (DualNumber R)] [T2Space (DualNumber R)] (f : Nat → DualNumber R): ∑' (i : Nat), p^i = 1 + p * ∑' (x : Nat), f x := by { have : ∑' (x : Nat), p * f x = p * ∑' (x : Nat), f x := tsum_mul_left } #check tsum_mul_left
Oh my bad, DualNumbers arent a DivisionRing. Seem like we need to basically redo a lot of the tsum lemmas
Frederick Pu (Apr 13 2024 at 15:48):
Actually Summable.tsum_mul_left seems fine
Eric Wieser (Apr 14 2024 at 18:37):
Note hat instead of assuming TopologicalSpace (DualNumber R)
you should import the TrivSqZeroExt file in analysis
Eric Wieser (Apr 14 2024 at 18:38):
@loogle NormedSpace, TrivSqZeroExt
loogle (Apr 14 2024 at 18:38):
:search: TrivSqZeroExt.instL1NormedSpace, TrivSqZeroExt.instL1NormedAlgebra
Kevin Buzzard (Apr 14 2024 at 19:54):
Eric Wieser said:
Note hat instead of assuming
TopologicalSpace (DualNumber R)
you should import the TrivSqZeroExt file in analysis
Just to be clear here -- Eric is saying that writing [TopologicalSpace (DualNumber R)]
is mathematically wrong, because it means "put a completely arbitrary topology on the dual numbers which is completely unrelated to the algebraic structure".
Eric Wieser (Apr 14 2024 at 20:13):
I guess you can fix "completely unrelated"by adding [TopologicalRing (DualNumber R)]
, but that's still probably "related but not in the ways you would expect"
Frederick Pu (Apr 14 2024 at 20:44):
yeah I noticed that the typeclasses required for tsum_left_mul and summable_of_vanishing_norm seem to really not like eachother for some reason
Eric Wieser (Apr 14 2024 at 20:46):
Can you show what you wrote?
Eric Wieser (Apr 14 2024 at 20:46):
This sounds a bit like "Semiring and AddCommGroup don't like each other", for which the answer is "of course not, that has two different +s; use Ring instead"
Frederick Pu (Apr 14 2024 at 20:48):
Screenshot-2024-04-14-164702.png
Screenshot-2024-04-14-164719.png
Eric Wieser (Apr 14 2024 at 20:48):
Please paste code (as a #mwe) not images!
Frederick Pu (Apr 14 2024 at 20:50):
theorem bruh.{u_3, u_1} {ι : Type u_1} {R : Type u_3} [SeminormedAddCommGroup (DualNumber R)]
[CompleteSpace (DualNumber R)] {f : ι → (DualNumber R)} (x : DualNumber R): Summable (fun i : Nat => x) := by
{
/--
ι : Type u_1
R : Type u_3
inst✝¹ : SeminormedAddCommGroup (DualNumber R)
inst✝ : CompleteSpace (DualNumber R)
f : ι → DualNumber R
x : DualNumber R
⊢ ∀ ε > 0, ∃ s, ∀ (t : Finset ℕ), Disjoint t s → ‖Finset.sum t fun i ↦ x‖ < ε
--/
rw [summable_iff_vanishing_norm]
}
works but
theorem bruh.{u_3, u_1} {ι : Type u_1} {R : Type u_3} [SeminormedAddCommGroup (DualNumber R)]
[CompleteSpace (DualNumber R)] [Ring (DualNumber R)] {f : ι → (DualNumber R)} (x : DualNumber R): Summable (fun i : Nat => x) := by
{
/ --
tactic 'rewrite' failed, did not find instance of the pattern in the target expression
Summable ?m.9232
--/
rw [summable_iff_vanishing_norm]
}
doesn't
Frederick Pu (Apr 14 2024 at 20:50):
so adding [Ring (DualNumber R)]
breaks the type inference
Ruben Van de Velde (Apr 14 2024 at 20:51):
Please read #mwe
Ruben Van de Velde (Apr 14 2024 at 20:51):
And you should never have a [Ring (Concrete type)]
argument
Frederick Pu (Apr 14 2024 at 20:57):
okay, let's go back to this example then:
import Mathlib.Algebra.DualNumber
import Mathlib.Topology.Algebra.InfiniteSum.Ring
import Mathlib.Analysis.Normed.Group.InfiniteSum
theorem extracted_1.{u_1} {R : Type u_1} [inst : DivisionRing R] [inst_1 : TopologicalSpace (DualNumber R)]
[inst_2 : TopologicalSemiring (DualNumber R)] (p : DualNumber R) (h : Summable fun i ↦ p ^ i)
[inst_3 : T2Space (DualNumber R)] : ∑' (i : ℕ), p ^ i = 1 + p * ∑' (x : ℕ), p ^ x := sorry
Frederick Pu (Apr 14 2024 at 20:58):
I think we need to be able to infer TopologicalSpace (DualNumber R)
from TopologicalSpace R
Frederick Pu (Apr 14 2024 at 20:59):
Shouldn't this be from the product topology?
Eric Wieser (Apr 14 2024 at 21:05):
Like I said above, you're missing an import
Kevin Buzzard (Apr 14 2024 at 21:14):
I have a mathematical question. You seem to want to put a topology on the dual numbers. What topology do you want to put on it?
Eric Wieser (Apr 14 2024 at 21:19):
You also seem to want a norm (from an earlier message); what norm do you want?
Frederick Pu (Apr 14 2024 at 21:19):
The topology for R^2, since we want to treat it like a normed vector space
Eric Wieser (Apr 14 2024 at 21:21):
@loogle TrivSqZeroExt, TopologicalSpace
loogle (Apr 14 2024 at 21:21):
:search: TrivSqZeroExt.instTopologicalSpace, TrivSqZeroExt.continuous_fst, and 44 more
Eric Wieser (Apr 14 2024 at 21:21):
That is the topology that matches R²; but you have to import that file for Lean to find it automatically
Frederick Pu (Apr 14 2024 at 21:25):
TrivSqZeroExt.instL1NormedAddCommGroup
Frederick Pu (Apr 14 2024 at 21:26):
I think that's pretty good, also matches the signature of our inverse lemmas
Kevin Buzzard (Apr 14 2024 at 21:43):
So I asked you which topology, and you replied "I have a specific topology in mind", and that's why stuff like [inst_1 : TopologicalSpace (DualNumber R)]
must be wrong, because there you're saying "put an arbitrary topology on it" (you can see it must be wrong becuase there is no mention of the topology you want). And I don't understand your answer -- R is just a random division ring. What is "the topology for R^2"?
Frederick Pu (Apr 14 2024 at 23:11):
Those instances were just to test the lemmas I was using. I think I'm gonna have R be topological ring and then take the the product topology
Kevin Buzzard (Apr 14 2024 at 23:21):
I guess I am a bit confused about what you're trying to achieve at this point.
Frederick Pu (Apr 14 2024 at 23:33):
That the theorem for geometric series applies for DualNumbers. that is:
1 + p + p^2 + p^3 +.... = 1/(1 - p) for $p.snd \neq 0$
Kevin Buzzard (Apr 15 2024 at 06:07):
That's not true -- for example it's not true if p=1+eps or if p=37+eps.
Frederick Pu (Apr 15 2024 at 15:29):
I think you need the additional condition of ||p|| < 1
Frederick Pu (Apr 15 2024 at 15:34):
Basically I'm trying have the geo_normed_field thing work for rings with units
Jireh Loreaux (Apr 15 2024 at 16:46):
IIRC @Eric Wieser had some ideas about generalizing this to certain topological rings, but maybe I'm misremembering and it was about exp
instead.
Eric Wieser (Apr 15 2024 at 17:18):
What's a "geo_normed_field"?
Eric Wieser (Apr 15 2024 at 20:35):
@Frederick Pu , are you looking for docs#NormedRing.tsum_geometric_of_norm_lt_one ?
Eric Wieser (Apr 15 2024 at 20:35):
Ah no, that's not the statement I expected
Frederick Pu (Apr 15 2024 at 20:52):
theorem tsum_geometric_of_norm_lt_one{K : Type u_4} [NormedField K] {ξ : K} (h : ‖ξ‖ < 1) :
∑' (n : ℕ), ξ ^ n = (1 - ξ)⁻¹
Frederick Pu (Apr 15 2024 at 20:53):
theorem geom_series_mul_neg {R : Type u_4} [NormedRing R] [CompleteSpace R] (x : R) (h : ‖x‖ < 1) :
(∑' (i : ℕ), x ^ i) * (1 - x) = 1
Frederick Pu (Apr 15 2024 at 20:53):
the second one should be easy to use for dualnumbers
Eric Wieser (Apr 15 2024 at 21:02):
I made #12164 which generalizes the first lemma to DivisionRing
, but indeed that doesn't help you here
Frederick Pu (Apr 15 2024 at 21:16):
Here's the minimum you need for it to work:
import Mathlib.Algebra.DualNumber
import Mathlib.Analysis.NormedSpace.TrivSqZeroExt
import Mathlib.Analysis.SpecificLimits.Normed
example {R : Type*} [NormedRing R] [CompleteSpace R] (x : DualNumber R) (h : ‖x‖ < 1) :
(∑' (i : ℕ), x ^ i) * (1 - x) = 1 :=
geom_series_mul_neg x h
Frederick Pu (Apr 15 2024 at 21:16):
i think u get NormedRing (DualNumber R) and CompleteSpace (DualNumber R) for free because of products or smth
Eric Wieser (Apr 15 2024 at 21:24):
Mathlib indeed has both of those instances already
Eric Wieser (Apr 15 2024 at 21:25):
(You get it for free because I contributed it to mathlib as a very small part of my PhD!)
Frederick Pu (Apr 15 2024 at 21:26):
theorem geom_series_of_fst_ne_zero {R : Type*} [NormedDivisionRing R] [CompleteSpace R] (x : DualNumber R) (h : ‖x‖ < 1) (h1 : x.fst ≠ 1) :
(∑' (i : ℕ), x ^ i) = (1 - x : DualNumber R)⁻¹ := by
have := geom_series_mul_neg x h
have w : ((∑' (i : ℕ), x ^ i) * (1 - x)) * (1 - x)⁻¹ = (1 - x)⁻¹ := by
rw [this, one_mul]
rw [← w, mul_assoc, TrivSqZeroExt.mul_inv_cancel, mul_one]
rw [TrivSqZeroExt.fst_sub]
exact sub_ne_zero_of_ne h1.symm
Eric Wieser (Apr 15 2024 at 21:27):
Are you sure you need ‖x‖ < 1
? Is ‖x.fst‖ < 1
enough?
Frederick Pu (Apr 15 2024 at 21:28):
isnt ||a + bε|| = sqrt(a^2 + b^2)
Eric Wieser (Apr 15 2024 at 21:34):
The one in mathlib is ‖a + bε‖ = ‖a‖ + ‖b‖
Frederick Pu (Apr 15 2024 at 21:35):
then how is ||x.fst|| < 1 enough?
Frederick Pu (Apr 15 2024 at 21:35):
intuitively i don't think you can just ignore the derivative component
Eric Wieser (Apr 15 2024 at 21:37):
The derivative component is n*x.fst^(n-1)* x.snd
(at least, in the commutative case), which should converge irrespective of the value of x.snd
Frederick Pu (Apr 15 2024 at 21:38):
yee that makes sense
Eric Wieser (Apr 15 2024 at 21:39):
Frederick Pu said:
theorem geom_series_mul_neg {R : Type u_4} [NormedRing R] [CompleteSpace R] (x : R) (h : ‖x‖ < 1) : (∑' (i : ℕ), x ^ i) * (1 - x) = 1
So this won't actually help for that stronger result; but it would be great to prove it anyway
Frederick Pu (Apr 15 2024 at 21:40):
Eric Wieser said:
Frederick Pu said:
theorem geom_series_mul_neg {R : Type u_4} [NormedRing R] [CompleteSpace R] (x : R) (h : ‖x‖ < 1) : (∑' (i : ℕ), x ^ i) * (1 - x) = 1
So this won't actually help for that stronger result; but it would be great to prove it anyway
wdym. That's already in mahthlib
Eric Wieser (Apr 15 2024 at 21:41):
Oh! Usually people write docs#geom_series_mul_neg (which creates an automatic link) to talk about things that already exist
Frederick Pu (Apr 15 2024 at 21:42):
sorry I didn't know
Eric Wieser (Apr 15 2024 at 21:43):
No worries, good job on finding it
Frederick Pu (Apr 15 2024 at 21:43):
I think this lemma is missing from DualNumber.lean:
example {R : Type*} [Ring R] (x : DualNumber R) (n : Nat) :
x^n = inl (x.fst ^ n) + inr (n * x.fst ^ (n - 1) * x.snd) := by
sorry
Frederick Pu (Apr 15 2024 at 21:44):
is it in TrivSqZeroExt?
Eric Wieser (Apr 15 2024 at 21:44):
I think generally the API tries to avoid writing lemmas like that right now
Eric Wieser (Apr 15 2024 at 21:45):
Instead it has docs#TrivSqZeroExt.fst_pow and docs#TrivSqZeroExt.snd_pow
Eric Wieser (Apr 15 2024 at 21:45):
The expectation is that if you're going to split it into components, you want to handle them separately rather than double the number of terms in the expression
Frederick Pu (Apr 15 2024 at 21:47):
so is there tsum x = inl (tsum.fst) + inr (tsum.snd)
Eric Wieser (Apr 15 2024 at 21:48):
No, but there is docs#TrivSqZeroExt.fst_tsum
Eric Wieser (Apr 15 2024 at 21:48):
... or not
Eric Wieser (Apr 15 2024 at 21:49):
I guess I only added docs#TrivSqZeroExt.hasSum_fst
Frederick Pu (Apr 15 2024 at 21:49):
also on a side note, can loogle search based on doc comments? seems like that would make it a lot easier to find stuff
Eric Wieser (Apr 15 2024 at 21:50):
Frederick Pu said:
so is there tsum x = inl (tsum.fst) + inr (tsum.snd)
This is false, because if only the fst
part converges the LHS is 0 and the rhs is inl (tsum _)
Eric Wieser (Apr 15 2024 at 21:50):
Eric Wieser said:
No, but there is docs#TrivSqZeroExt.fst_tsum
This would be false for the same reason
Frederick Pu (Apr 15 2024 at 21:51):
the thing is those go in the wrong direction. We need to show if fst and snd converge than the sequence converges
Eric Wieser (Apr 15 2024 at 21:53):
The secret is that you rarely want to show "the sequence converges"; "the sequence converges to x
" is much more interesting, and this is what docs#HasSum means
Eric Wieser (Apr 15 2024 at 21:54):
I think you want (TrivSqZeroExt.hasSum_inl _).add (TrivSqZeroExt.hasSum_inr _)
Eric Wieser (Apr 15 2024 at 21:55):
I guess it's probably reasonable to add something like HasSum (fun x => (f x).fst) a.fst -> HasSum (fun x => (f x).snd) a.snd -> HasSum f a
Eric Wieser (Apr 15 2024 at 21:56):
Which should follow fairly immediately from my .add
message above.
Eric Wieser (Apr 15 2024 at 21:56):
It's probably even true as an Iff
Eric Wieser (Apr 15 2024 at 21:57):
There's a lot missing here because I developed just as much as I needed for docs#TrivSqZeroExt.fst_exp (and the rest of that file) and little else.
Frederick Pu (Apr 15 2024 at 22:05):
what about something like this:
theorem hasSum_inl_inr (f g : Nat → ℝ) (a b : ℝ) : HasSum f a → HasSum g b → (HasSum (fun n => (inl (f n) + inr (g n) : (DualNumber ℝ))) (inl a + inr b : DualNumber ℝ)) := by
{
intro hf hg
apply HasSum.add
apply TrivSqZeroExt.hasSum_inl
exact hf
apply TrivSqZeroExt.hasSum_inr
exact hg
}
Eric Wieser (Apr 15 2024 at 22:06):
For this type of thing it's often more useful to have the free variable in the conclusion
Frederick Pu (Apr 15 2024 at 22:06):
lean seems to get really confused when u tryy to use hasSum_inl directly
Eric Wieser (Apr 15 2024 at 22:06):
(TrivSqZeroExt.hasSum_inl _ hf).add (TrivSqZeroExt.hasSum_inr _ hg)
should work for that?
Frederick Pu (Apr 15 2024 at 22:07):
it doesnt
Eric Wieser (Apr 15 2024 at 22:09):
Edited: see if you can see how I worked out the fix from the error message
Frederick Pu (Apr 15 2024 at 22:09):
oh the extra _
Frederick Pu (Apr 15 2024 at 22:10):
but why tho, the lemma only takes 1 input
Notification Bot (Apr 15 2024 at 22:11):
This topic was moved here from #general > Is there any code or division of DualNumbers? by Eric Wieser.
Eric Wieser (Apr 15 2024 at 22:12):
Frederick Pu said:
but why tho, the lemma only takes 1 input
What makes you say that?
Frederick Pu (Apr 15 2024 at 22:13):
theorem hasSum_inr [AddCommMonoid R] [AddCommMonoid M] {f : α → M} {a : M} (h : HasSum f a)
Frederick Pu (Apr 15 2024 at 22:13):
only 1 non implicit argument right?
Eric Wieser (Apr 15 2024 at 22:13):
Nope, there's a variable
line higher up that adds more
Eric Wieser (Apr 15 2024 at 22:13):
You can read off the variables by hovering over hasSum_inr
and reading the tooltip instead of the source
Frederick Pu (Apr 16 2024 at 02:03):
I feel like in this case it's better to prove that the sequence converges and then get the value this converges to afterward. Since evaluating the sum of i * x^{i - 1} is very nasty
Kevin Buzzard (Apr 16 2024 at 05:57):
It's just the derivative of the sum of x^i which is 1/(1-x)
Frederick Pu (Apr 16 2024 at 14:15):
Yeah but the whole point of using dual numbers was to bypass using derivatives
Kevin Buzzard (Apr 16 2024 at 15:52):
Another approach is just to multiply by (1-x)^2 and observe that a miracle occurs
Frederick Pu (Apr 16 2024 at 20:38):
But wouldn't that trick still require you to assume convergence in the first place?
Frederick Pu (Apr 16 2024 at 20:39):
The only trick like that I know is from kumon where you multiply by x, and when u subtract the two sequences you get a geoemtric sequence or smth
Frederick Pu (Apr 16 2024 at 20:39):
anyhow I'm stuck with this chonker for now that I'll have to golf later
example (x : DualNumber ℝ) (x : DualNumber ℝ) (hx1 : |x.fst| < 1) (hx2 : x.fst ≠ 0):
Summable (fun i : Nat => x^i) := by
{
have : (fun i : Nat => x^i) = (fun i : Nat => (inl (x.fst ^ i) + inr ((i:ℝ) * x.fst ^ (i.pred) * x.snd))) := by
ext i
· rw [fst_pow, fst_add, fst_inl, fst_inr, add_zero]
· rw [snd_pow, snd_add, snd_inl, snd_inr, zero_add, ← smul_assoc, smul_eq_mul, nsmul_eq_mul]
rw [this]
apply Summable.add
suffices h : Summable (fun b => x.fst ^ b) by {
match h with
| ⟨t, ht⟩ => {
use (inl t)
exact TrivSqZeroExt.hasSum_inl _ ht
}
}
rw [summable_geometric_iff_norm_lt_one]
exact hx1
suffices h : Summable (fun b : Nat => (b:ℝ) * fst x ^ Nat.pred b * snd x) by {
match h with
| ⟨t, ht⟩ => {
use (inr t)
exact TrivSqZeroExt.hasSum_inr _ ht
}
}
apply Summable.mul_right
-- apply summable_of_ratio_test_tendsto_lt_one _
-- sorry
have : Filter.Tendsto (fun n ↦ ‖↑(n + 1) * fst x ^ Nat.pred (n + 1)‖ / ‖↑n * fst x ^ Nat.pred n‖) Filter.atTop (nhds ‖x.fst‖) := by {
have : Filter.EventuallyEq (Filter.atTop) (fun n:Nat ↦ ‖(n + 1 : ℝ) / n‖ * ‖x.fst‖) (fun n => ‖↑(n + 1) * fst x ^ Nat.pred (n + 1)‖ / ‖↑n * x.fst ^ (n.pred)‖) := by {
rw [Filter.EventuallyEq, Filter.eventually_atTop]
use 1
intro b hb
cases h : b with
| zero => {
linarith
}
| succ b => {
simp
have : |(b + 1 : ℝ)| * |fst x| ^ b ≠ 0 := by {
apply mul_ne_zero
rw [h] at hb
simp only [ne_eq, abs_eq_zero]
intro _
linarith
rw [ne_eq, pow_eq_zero_iff', abs_eq_zero]
tauto
}
field_simp
ring
}
}
rw [Filter.tendsto_congr' this.symm]
{
have : Filter.Tendsto (fun n:Nat ↦ ‖((n + 1 : Nat) : ℝ) / ↑n‖) Filter.atTop (nhds (1:ℝ)) := by {
have : (fun n:Nat ↦ ‖((n + 1 : Nat) : ℝ) / ↑n‖) =ᶠ[Filter.atTop] (fun n:Nat ↦ 1 + (n:ℝ)⁻¹) := by {
rw [Filter.EventuallyEq, Filter.eventually_atTop]
use 1
intro b hb
have : b ≠ 0 := by linarith
rw [Real.norm_eq_abs, abs_of_pos]
field_simp
apply div_pos
push_cast
linarith
have : (1:Nat) ≤ (b : ℝ) := by
rw [Nat.cast_le]
exact hb
push_cast at this
linarith
}
rw [Filter.tendsto_congr' this]
have crux1 : Filter.Tendsto (fun n : Nat ↦ (1 : ℝ)) Filter.atTop (nhds 1) :=
tendsto_const_nhds
have crux2 : Filter.Tendsto (fun n : Nat ↦ (n:ℝ)⁻¹) Filter.atTop (nhds 0) :=
tendsto_inverse_atTop_nhds_zero_nat
have := Filter.Tendsto.add crux1 crux2
rw [add_zero] at this
exact this
}
have := Filter.Tendsto.mul_const (‖fst x‖) this
push_cast at this
rw [one_mul] at this
exact this
}
}
exact summable_of_ratio_test_tendsto_lt_one hx1 (by {
rw [Filter.eventually_atTop]
use 1
intro b hb
cases b with
| zero => simp at hb
| succ b => {
simp
intro h
cases h with
| inl l => linarith
| inr r => exact hx2 r.left
}
}) this
}
Frederick Pu (Apr 16 2024 at 21:06):
Here's the golfed version:
theorem wow (x : DualNumber ℝ) (hx : x.fst ≠ 0) :
Filter.Tendsto (fun n ↦ ‖↑(n + 1) * fst x ^ Nat.pred (n + 1)‖ / ‖↑n * fst x ^ Nat.pred n‖) Filter.atTop (nhds ‖x.fst‖) := by
have : Filter.EventuallyEq (Filter.atTop) (fun n:Nat ↦ ‖(n + 1 : ℝ) / n‖ * ‖x.fst‖) (fun n => ‖↑(n + 1) * fst x ^ Nat.pred (n + 1)‖ / ‖↑n * x.fst ^ (n.pred)‖) := by
rw [Filter.EventuallyEq, Filter.eventually_atTop]
use 1
intro b hb
cases h : b with
| zero => linarith
| succ b =>
simp
have : |(b + 1 : ℝ)| * |fst x| ^ b ≠ 0 := by
apply mul_ne_zero
rw [h] at hb; simp only [ne_eq, abs_eq_zero]; linarith
rw [ne_eq, pow_eq_zero_iff', abs_eq_zero]; tauto
field_simp
ring
rw [Filter.tendsto_congr' this.symm]
have : Filter.Tendsto (fun n:Nat ↦ ‖((n + 1 : Nat) : ℝ) / ↑n‖) Filter.atTop (nhds (1:ℝ)) := by
have : (fun n:Nat ↦ ‖((n + 1 : Nat) : ℝ) / ↑n‖) =ᶠ[Filter.atTop] (fun n:Nat ↦ 1 + (n:ℝ)⁻¹) := by
rw [Filter.EventuallyEq, Filter.eventually_atTop]
use 1
intro b hb
rw [Real.norm_eq_abs, abs_of_pos]
field_simp [show b ≠ 0 by linarith]
exact div_pos (by push_cast; linarith) (by linarith [show (b : ℝ) ≥ 1 by exact Nat.one_le_cast.mpr hb])
rw [Filter.tendsto_congr' this]
have crux1 : Filter.Tendsto (fun n : Nat ↦ (1 : ℝ)) Filter.atTop (nhds 1) :=
tendsto_const_nhds
have crux2 : Filter.Tendsto (fun n : Nat ↦ (n:ℝ)⁻¹) Filter.atTop (nhds 0) :=
tendsto_inverse_atTop_nhds_zero_nat
have := Filter.Tendsto.add crux1 crux2
rw [add_zero] at this
exact this
have := Filter.Tendsto.mul_const (‖fst x‖) this
push_cast at this
rw [one_mul] at this
exact this
example (x : DualNumber ℝ) (hx1 : |x.fst| < 1) (hx2 : x.fst ≠ 0):
Summable (fun i : Nat => x^i) := by
have : (fun i : Nat => x^i) = (fun i : Nat => (inl (x.fst ^ i) + inr ((i:ℝ) * x.fst ^ (i.pred) * x.snd))) := by
ext i
· rw [fst_pow, fst_add, fst_inl, fst_inr, add_zero]
· rw [snd_pow, snd_add, snd_inl, snd_inr, zero_add, ← smul_assoc, smul_eq_mul, nsmul_eq_mul]
rw [this]
apply Summable.add
suffices h : Summable (fun b => x.fst ^ b) by
match h with
| ⟨t, ht⟩ =>
use (inl t)
exact TrivSqZeroExt.hasSum_inl _ ht
rw [summable_geometric_iff_norm_lt_one]
exact hx1
suffices h : Summable (fun b : Nat => (b:ℝ) * fst x ^ Nat.pred b * snd x) by
match h with
| ⟨t, ht⟩ =>
use (inr t)
exact TrivSqZeroExt.hasSum_inr _ ht
exact Summable.mul_right x.snd <|
summable_of_ratio_test_tendsto_lt_one hx1 (by {
rw [Filter.eventually_atTop]
use 1
intro b hb
cases b with
| zero => simp at hb
| succ b => {
simp
intro h
cases h with
| inl l => linarith
| inr r => exact hx2 r.left
}
}) (wow x hx2)
wow just prooves that u can atlually use ratio test
Frederick Pu (Apr 16 2024 at 21:36):
also smth like this should take us home
example {R : Type*} [inst : NormedRing R] [inst_1 : CompleteSpace R] (x : R) :
Summable (fun i ↦ x ^ i) → (∑' (i : ℕ), x ^ i) * (1 - x) = 1 := by {
intro this
have := this.hasSum.mul_right (1 - x)
refine' tendsto_nhds_unique this.tendsto_sum_nat _
have : Filter.Tendsto (fun n : ℕ ↦ 1 - x ^ n) Filter.atTop (nhds 1) := by
simpa using tendsto_const_nhds.sub (show Filter.Tendsto (fun n ↦ x ^ n) Filter.atTop (nhds 0) by sorry)
convert← this
rw [← geom_sum_mul_neg, Finset.sum_mul]
}
Eric Wieser (Apr 16 2024 at 21:57):
I think that last one is true much more generally, it doesn't need a norm at all
Frederick Pu (Apr 16 2024 at 22:00):
Can you have tsum without norm
Eric Wieser (Apr 16 2024 at 22:01):
Yes, T2Space
and TopologicalAddGroup
is enough
Frederick Pu (Apr 16 2024 at 22:06):
theorem womp {R : Type*} [TopologicalSpace R] [Ring R] [inst : TopologicalRing R] [T2Space R] (x : R) :
Summable (fun i ↦ x ^ i) → Filter.Tendsto (fun n ↦ x ^ n) Filter.atTop (nhds 0) → (∑' (i : ℕ), x ^ i) * (1 - x) = 1 := by {
intro h1 h2
have := h1.hasSum.mul_right (1 - x)
refine' tendsto_nhds_unique this.tendsto_sum_nat _
have : Filter.Tendsto (fun n : ℕ ↦ 1 - x ^ n) Filter.atTop (nhds 1) := by
simpa using tendsto_const_nhds.sub h2
convert← this
rw [← geom_sum_mul_neg, Finset.sum_mul]
}
Frederick Pu (Apr 16 2024 at 22:10):
here's a rough sketch of the final proof:
example (x : DualNumber ℝ) (hx1 : |x.fst| < 1) (hx2 : x.fst ≠ 0):
(∑' (i : ℕ), x ^ i) * (1 - x) = 1 := by {
apply womp
exact summable_geom_dual_real x hx1 hx2
have : (fun i : Nat => x^i) = (fun i : Nat => (inl (x.fst ^ i) + inr ((i:ℝ) * x.fst ^ (i.pred) * x.snd))) := by
ext i
· rw [fst_pow, fst_add, fst_inl, fst_inr, add_zero]
· rw [snd_pow, snd_add, snd_inl, snd_inr, zero_add, ← smul_assoc, smul_eq_mul, nsmul_eq_mul]
rw [this]
rw [show (0:DualNumber ℝ) = inl 0 + inr 0 by simp]
apply Filter.Tendsto.add
{
apply Filter.Tendsto.comp (continuous_inl.tendsto 0)
exact tendsto_pow_atTop_nhds_zero_of_norm_lt_one hx1
}
{
apply Filter.Tendsto.comp (continuous_inr.tendsto 0)
rw [show 0 = 0 * x.snd by sorry]
apply Filter.Tendsto.mul_const
suffices Filter.Tendsto (fun k:Nat ↦ ↑k * fst x ^ k) Filter.atTop (nhds 0) by sorry
exact tendsto_self_mul_const_pow_of_abs_lt_one hx1
}
}
Eric Wieser (Apr 16 2024 at 22:12):
Here's womp
with even fewer assumptions:
theorem Summable.hasSum_geom_sries_mul_sub
{R : Type*} [TopologicalSpace R] [Ring R] [TopologicalRing R]
(x : R) (hx : Summable (x ^ ·)) :
HasSum (fun i => x ^ i * (1 - x)) 1 := by
obtain ⟨a, hx⟩ := hx
have hx' := hx
rw [← hasSum_nat_add_iff' 1, Finset.sum_range_one, pow_zero] at hx'
simp_rw [mul_sub, mul_one, ←pow_succ]
simpa using hx.sub hx'
Eric Wieser (Apr 16 2024 at 22:13):
(you can use HasSum.tsum_eq
to get the tsum version)
Frederick Pu (Apr 16 2024 at 22:29):
theorem Summable.hasSum_geom_sries_mul_sub
{R : Type*} [TopologicalSpace R] [Ring R] [TopologicalRing R]
(x : R) (hx : Summable (x ^ ·)) :
HasSum (fun i => x ^ i * (1 - x)) 1 := by
obtain ⟨a, hx⟩ := hx
have hx' := hx
rw [← hasSum_nat_add_iff' 1, Finset.sum_range_one, pow_zero] at hx'
simp_rw [mul_sub, mul_one, ←pow_succ]
simpa using hx.sub hx'
theorem womp {R : Type*} [TopologicalSpace R] [Ring R] [inst : TopologicalRing R] [T2Space R] (x : R) :
Summable (fun i ↦ x ^ i) → (∑' (i : ℕ), x ^ i) * (1 - x) = 1 := by {
intro h1
have := h1.hasSum.mul_right (1 - x)
have : ∑' (i : ℕ), (x ^ i * (1 - x)) = (∑' (i : ℕ), x ^ i) * (1 - x) := by sorry -- tsum_mul_right
rw [← this]
exact HasSum.tsum_eq <| Summable.hasSum_geom_sries_mul_sub x h1
}
example (x : DualNumber ℝ) (hx1 : |x.fst| < 1) (hx2 : x.fst ≠ 0):
(∑' (i : ℕ), x ^ i) * (1 - x) = 1 :=
womp x <| summable_geom_dual_real x hx1 hx2
Mitchell Lee (Apr 17 2024 at 05:10):
You can show the summability by using docs#hasSum_coe_mul_geometric_of_norm_lt_one
Eric Wieser (Apr 17 2024 at 06:28):
We started with that but the side z-condition is too strong I think?
Kevin Buzzard (Apr 17 2024 at 06:36):
Right, nilpotent things should have norm infinitesimally small (ie however big the value of r is, r * epsilon should have norm less than 1)
Eric Wieser (Apr 17 2024 at 06:39):
That's not possible with our signature for norms, right? The closest we could do is set the norm to zero, but then we don't have a t2 space and our sums don't converge to a single value
Kevin Buzzard (Apr 17 2024 at 06:48):
Yes that's right, this is a higher rank valuation, not a rank one (aka real-valued) valuation (aka norm).
Kevin Buzzard (Apr 17 2024 at 06:50):
I don't even know if it works in the Archimedean case to be honest! In my examples the underlying norm on the base ring R is nonarchimedean and then the extension to infinitesimals is untroublesome
Mitchell Lee (Apr 17 2024 at 07:20):
Eric Wieser said:
We started with that but the side z-condition is too strong I think?
What does that mean?
I am just pointing out that it seems Frederick was using the ratio test to prove the convergence of a certain series of real numbers, when the convergence of that series (and its value) is already in mathlib.
Mitchell Lee (Apr 17 2024 at 08:08):
Kevin Buzzard said:
Yes that's right, this is a higher rank valuation, not a rank one (aka real-valued) valuation (aka norm).
If you put a topology on using this higher rank norm, wouldn't that make open? Then it would be difficult for anything to converge.
Antoine Chambert-Loir (Apr 17 2024 at 11:16):
Kevin Buzzard said:
Right, nilpotent things should have norm infinitesimally small (ie however big the value of r is, r * epsilon should have norm less than 1)
Why should they? Nilpotent operators usually don't have a zero operator norm.
Kevin Buzzard (Apr 17 2024 at 11:31):
They do for the supremum seminorm on an affinoid
Kevin Buzzard (Apr 17 2024 at 11:32):
But actually I'm confused about this for two reasons -- first that the reals aren't nonarchimedean and secondly that valuations are supposed to be multiplicative
Frederick Pu (Apr 17 2024 at 15:16):
The dual numbers have L_p norm, so both the real and derivative components are equally important. The thing is that (a + b\e) ^n = a^n + a^(n-1)b\e. So you can consider the sums seperately.
Mitchell Lee (Apr 17 2024 at 15:40):
Kevin Buzzard said:
But actually I'm confused about this for two reasons -- first that the reals aren't nonarchimedean and secondly that valuations are supposed to be multiplicative
It seems that in mathlib, the norm of a normed ring is only required to be submultiplicative. (docs#NormedRing) The definition of a normed field requires the norm to be (exactly) multiplicative, though. (docs#NormedField)
It wouldn't be possible to put an (exactly) multiplicative norm on the dual numbers, because they are not a domain.
Mitchell Lee (Apr 17 2024 at 16:21):
Also, it is possible I am misunderstanding something, but I don't think it is desirable for to be infinitesimal. If it were, then the sequence wouldn't converge, because it never comes within of . So the inclusion would not be continuous. This is a problem even if is replaced by a nonarchimedean ring.
I think the coefficientwise product topology on is the "correct" one.
Antoine Chambert-Loir (Apr 17 2024 at 21:01):
If is endowed with the -norm, one gets a normed algebra structure ( has norm ), and the geometric series is summable provided the (necessary) condition holds.
Eric Wieser (Apr 17 2024 at 22:20):
That normed algebra structure is in mathlib
Frederick Pu (Apr 17 2024 at 23:42):
yeah... how does lean know which norm to inherit?
Eric Wieser (Apr 17 2024 at 23:44):
Lean just finds the only norm that mathlib provides, which for dual numbers is the L1 norm
Last updated: May 02 2025 at 03:31 UTC