-
Notifications
You must be signed in to change notification settings - Fork 293
[Merged by Bors] - feat(analysis/normed_space/inner_product): Define the inner product based on is_R_or_C
#4057
Conversation
sgouezel
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks very good to me. My only real question is about the projection part: my impression is that it only needs to be done over the reals, and then it should automatically become available over the complexes thanks to suitable instances.
| variables {𝕜 : Type*} [is_R_or_C 𝕜] | ||
| local notation `𝓚` := @is_R_or_C.of_real 𝕜 _ | ||
|
|
||
| /-- Syntactic typeclass for types endowed with an inner product -/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a difficulty here that, when you write inner x y, Lean can not guess the field. If you have a (complex) hermitian vector field, and you derive the real inner product space structure, then you will have two different inner spaces on it and Lean will get confused. You have a nice solution below, by introducing the notations ⟪x, y⟫_ℝ and ⟪x, y⟫_ℂ. I think it is worth moving these notations just after the definition and making them global. Also, introducing localized notations for ⟪x, y⟫ as you have done at the end of the file is very good, but you could move them right here. And you could also introduce a third locale inner_product_space where the field is unspecified, and left to Lean. Then the user could choose which locale he wants to open depending on the context. (In this file, you would want to open inner_product_space, for instance) (Maybe you will need to declare the notations in a section, to avoid them being open automatically in the whole file)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I made the ⟪x, y⟫_ℝ and ⟪x, y⟫_ℂ declarations global and moved the rest of the notations up here, but for the inner_product_space localized notation, I suspect that if this is needed elsewhere, one would want to do what I did here: first declare 𝕜 to be some is_R_or_C field, and then declare ⟪x, y⟫ to be the inner product with this specific 𝕜 as the field. I had tried leaving it unspecified and it caused problems.
| /- Normally we would want `[is_scalar_tower ℝ 𝕜 α]` in applications as well, to ensure that this | ||
| `[normed_space ℝ α]` instance is compatible with the `[normed_space 𝕜 α]` defined above, but | ||
| here this is not strictly needed as these lemmas never use the 𝕜 instance. -/ | ||
| theorem exists_norm_eq_infi_of_complete_convex [normed_space ℝ α] {K : set α} (ne : K.nonempty) (h₁ : is_complete K) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You shouldn't need normed_space ℝ α here. Instead, you should have an instance from normed_space k α to normed_space ℝ α. Or, better, just formulate the theorem for real vector spaces, and let restrict_scalars automatically handle the complex case for you (you would need an instance that a complex inner product space is also a real inner product space, which is good to have in any case)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually ran into annoying problems when trying to define these kinds of instances (where is_R_or_C implies real). If I try to declare, for example, that semimodule 𝕜 α implies semimodule ℝ α, Lean complains about the case where 𝕜 = ℝ, because then this new instance is not defeq to the original one. I have no idea how to solve this -- if you have any ideas that would be great!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about just having an instance that inner_product_space C alpha implies inner_product_space R alpha? And stating all the projection theorems only in real inner product spaces. Then they would also become automatically available in complex inner product spaces as well (since they are just a statement about the norm), which should be enough for applications.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added the instance (it certainly can't hurt!), but I think it would still be good to prove these for the is_R_or_C case directly, because once we split into two cases, we're condemned to also split everything that gets built on top...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't agree with you here: this projection business is specifically a real thing (it requires convexity of the set, which only makes sense in a real context), so it should only be stated for real vector spaces.
The version that would make sense for any is_R_or_C field 𝕜 is that, for any 𝕜-subspace, there is a unique projection on 𝕜 minimizing the distance (which can be stated using only the distance, so not mentioning reals at all). And if you can find properties on the scalar product that only mention 𝕜, then they are worth stating in this context.
So, my suggestion is:
- Do all the projection business with convex subsets, and everything that mentions
ℝ, in a specific section that does not mention any field𝕜 - Then deduce the results that make sense over any
is_R_or_Cfield (and that don't mentionℝat all) in another section, by registering locally an instance that the space is also a real inner product space, and using the previous results for real inner product spaces. This instance would be a bad instance as you mention (as for𝕜 = ℝis creates non-defeq instances) but if it is just a local instance specific to these proofs this is not an issue.
If you don't see how to do this, I can have a go at it if you like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I see -- alright I'll give it a shot!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This isn't going too well. That instance does really strange things, even locally (abel stops working in random places, the typeclass system goes nuts on things like semiring ℝ in some of these statements, etc). Now I just rewrote that whole section to just be for real inner products and left the instance unused -- feel free to have a shot at it though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The trick is to not register this as an instance (even not a local one), but only to use it in proofs to declare explicitly the real structure on a given space, with letI. This means that Lean will not try the instance on this real structure, so nothing bad will happen.
I have done this, and everything went pretty well! Now, the only thing that is specific to real spaces is the projection on convex sets. Orthogonal projection on complete subspaces is done in the general setting of an is_R_or_C field (and I had nothing to change to the proofs, so it definitely convinced me that this is a really efficient way to do things at the same time on reals and complexes!)
It looks ready for merging to me, but before I can merge it someone should have a look to the changes I have made in my last commit. Can you check that you're happy with what I've done?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm certainly happy with it for what it's worth -- thanks a lot!
Co-authored-by: sgouezel <sebastien.gouezel@univ-rennes1.fr>
Co-authored-by: sgouezel <sebastien.gouezel@univ-rennes1.fr>
Co-authored-by: sgouezel <sebastien.gouezel@univ-rennes1.fr>
|
bors r+ |
|
Pull request successfully merged into master. Build succeeded: |
is_R_or_Cis_R_or_C
This PR redefines the inner product to be based on the
is_R_or_Ctypeclass. Its API is very close to the original one, and whenever a lemma has a cleaner statement in the real case (i.e. if it contains things likereorconj), there is a specialized lemma for that case.The plan would be to then replaceI have ported the rest of mathlib to this new inner product and deletedreal_inner_product.leanby this (which I haven't done yet here).real_inner_product.lean.A few things worth noting:
I would suggest replacing names likeI have now switched to just keeping the same naming scheme, withinner_smul_leftbyinner.smul_left, with the real and complex cases asinner.real.smul_leftandinner.complex.smul_left.innerreplaced withreal_innerin a lemma name whenever the lemma only applies to the real inner product, or else tagging_realat the end of the name ifinnerdoesn't appear in the lemma name.to_normed_group, because one gets a free parameter. It seems to be local only to this file though, unless I'm misinterpreting whatlocal attributemeans.real_inner_productand added myself in the list of authors, since a large part of it was copy/pasted from there. If this is inappropriate, please let me know.