Zulip Chat Archive

Stream: maths

Topic: Convex bodies


Paul Reichert (Aug 28 2022 at 22:30):

In preparation for more convex geometry / Brunn-Minkowski stuff, I'd like to contribute convex bodies to mathlib.
I think a sensible way would be to first introduce a is_convex_body predicate, checking whether a set is convex, compact, and nonempty, and then to define a subtype convex_body V containing convex bodies in some real vector space V.
Then I'd love to spend a module nnreal (convex_body V) instance.

Does my plan sound about right?

One thing I'm still unsure about are the assumptions. My experience with convex geometry is about finite-dimensional real vector spaces but I will try to generalize as much as possible.

Yaël Dillies (Aug 28 2022 at 22:34):

Note. You will want to use docs#set_like. A typical example of the design is docs#topological_space.closeds.

Yaël Dillies (Aug 28 2022 at 22:37):

I doubt we need is_convex_body, because we tend to separate assumptions (this is yet another effect of currying). But convex_body sounds good, although I should check whether it's the mathematically correct notion here.

Yaël Dillies (Aug 28 2022 at 22:38):

Also, let me tell you about file#data/set/pointwise if you haven't seen it already.

Paul Reichert (Aug 28 2022 at 22:47):

Regarding the correct definition, there seems to be some inconsistency in the literature whether a convex body has to have a nonempty interior, i.e. has to be full-dimensional. Wikipedia says that it has to, Rolf Schneider's "Convex Bodies: The Brunn-Minkowski Theory" does not.
My personal opinion is that convex bodies should not need to have a nonempty interior. Lots of constructions do not require this assumption, for example above-mentioned module nnreal instance. Also, faces of convex bodies are convex bodies again, except that they are not full-dimensional.

Yaël Dillies (Aug 29 2022 at 06:46):

There's antecedent to haivng both. See docs#topological_space.compacts, docs#topological_space.positive_compacts

Paul Reichert (Aug 29 2022 at 14:52):

I have opened a WIP pull request: https://github.com/leanprover-community/mathlib/pull/16297
I appreciate any feedback. :octopus: :+1:

Still, I have to find the right place for the two declarations marked with -- MOVE.
Probably, is_compact.smul should go into topology/subset_properties.lean, just like is_compact, and nnreal.has_continuous_const_smul should go into data/real/nnreal.lean, but I'm not sure.

is_compact.add, for example, already exists but is defined in the monoid module which is not appropriate for smul.

Yaël Dillies (Aug 29 2022 at 14:54):

is_compact.smul and is_compact.add definitely should go under topology.algebra.

Paul Reichert (Aug 29 2022 at 22:30):

Yes, now I agree that is a better place.
However, I currently have problems with the check_reducibility linter because my add_monoid class uses set.has_add, which is a localized instance (i.e., not defined as an instance). I found some mentions in Zulip and the note on reducible non-instances but I do not fully understand the problem.
Is there a way to legally use set.has_add in the instance or do I have to localize all instances depending on set.has_add, too? (I think you mentioned something similar in an older chat, @Yaël Dillies...)

Furthermore, this linter error only appears in the CI, just adding the #lint command at the end of my only changed file does not produce it, although check_reducibility is part of the linters enumerated by #list_linters. Is there a way to reproduce the problem locally so that I do not have to litter the CI with my premature debugging attempts?

Junyan Xu (Aug 30 2022 at 00:20):

Why not define a ℝ-module structure (would you then automatically get the ℝ≥0-module structure?

Apurva Nakade (Aug 30 2022 at 06:14):

Paul Reichert said:

Yes, now I agree that is a better place.
However, I currently have problems with the check_reducibility linter because my add_monoid class uses set.has_add, which is a localized instance (i.e., not defined as an instance). I found some mentions in Zulip and the note on reducible non-instances but I do not fully understand the problem.
Is there a way to legally use set.has_add in the instance or do I have to localize all instances depending on set.has_add, too? (I think you mentioned something similar in an older chat, Yaël Dillies...)

Furthermore, this linter error only appears in the CI, just adding the #lint command at the end of my only changed file does not produce it, although check_reducibility is part of the linters enumerated by #list_linters. Is there a way to reproduce the problem locally so that I do not have to litter the CI with my premature debugging attempts?

I'm encountering this same problem in #16213
I tried adding @[reducible] to set.has_add but that didn't build so I reverted to using the explicit definition as I didn't really need any of the set.has_add API. Would love to hear a better solution and this is very hacky.

Yaël Dillies (Aug 30 2022 at 07:13):

Junyan Xu said:

Why not define a ℝ-module structure (would you then automatically get the ℝ≥0-module structure?

Because it's wrong, right? s - s = 1 • s + (-1) • s ≠ (1 - 1) • s = 0

Yaël Dillies (Aug 30 2022 at 07:15):

Apurva Nakade said:

I reverted to using the explicit definition as I didn't really need any of the set.has_add API. Would love to hear a better solution and this is very hacky.

Yes, this is the way to go. See docs#set_semiring.non_unital_non_assoc_semiring

Junyan Xu (Aug 30 2022 at 08:00):

Oh yes, add_smul is the nontrivial part. distrib_mul_action should be generalizable to an ℝ-action nonetheless.

Reid Barton (Aug 30 2022 at 10:37):

What about s + s = 1 • s + 1 • s ≠ 2 • s?

Yaël Dillies (Aug 30 2022 at 11:51):

This is true for convex bodies, though?

Reid Barton (Aug 30 2022 at 13:09):

Oh, for convex things yes.

Paul Reichert (Aug 30 2022 at 18:23):

Yaël Dillies said:

Yes, this is the way to go. See docs#set_semiring.non_unital_non_assoc_semiring

Fine. Thanks for your help! I changed the definition of add and added set.image2_add to the simp sets of the add_monoid proofs. Now it works.

Paul Reichert (Aug 30 2022 at 21:49):

My preferred next step is to endow convex bodies with the Hausdorff metric, basically by packaging the existing lemmata about the Hausdorff pseudometric into an instance and proving that it's a metric for convex bodies

Kalle Kytölä (Aug 30 2022 at 22:01):

docs#metric.Hausdorff_dist should be good for that purpose.

Paul Reichert (Aug 30 2022 at 22:01):

Apurva Nakade said:

I'm encountering this same problem in #16213
I tried adding @[reducible] to set.has_add but that didn't build so I reverted to using the explicit definition as I didn't really need any of the set.has_add API. Would love to hear a better solution and this is very hacky.

I settled with a solution very similar to yours. I just used set.image (+) as proposed by Yaël Dillies. That also enabled me to use the set.has_add instance in the proof as follows:

add_assoc := λ K L M, by { ext, simp only [coe_mk, set.image2_add, add_assoc] }

It's very similar to yours and it's still a bit hacky.

Paul Reichert (Aug 30 2022 at 23:33):

One question: Is it better to create small PRs for different but related changes or multiple smaller ones?

Moritz Doll (Aug 31 2022 at 01:29):

generally you want to do smaller PRs

Paul Reichert (Aug 31 2022 at 21:43):

I just completed the Hausdorff metric instance for convex bodies. If you are interested, you can find it here: #16338

Another thing I'd enjoy to formalize are facts about the relative interior (relint) of a set in a (mostly finite-dimensional) normed space: the interior of the set after restricting the ambient space to the affine hull of the set.
A useful fact is that the relint of a nonempty convex set is nonempty. This corresponds to the existing lemma convex.interior_nonempty_iff_affine_span_eq_top if the convex set is of full dimension, i.e., the affine span is \top.
I hope to be able to use this existing proof to derive the more general statement but I still need some time to figure it out.
(branch: convex_relint)

Yaël Dillies (Sep 01 2022 at 06:55):

I would actually love seeing this. I've been trying to write API for that several times. See here.

Paul Reichert (Sep 01 2022 at 15:17):

Thanks for the link. I really like the name "intrinsic interior" because it describes what it is more than "relative interior".
Without having adopted that nomenclature yet, the current state on the branch is that I succeeded with an untidied proof that the intrinsic interior is nonempty if the convex set itself is nonempty.

Paul Reichert (Sep 02 2022 at 09:57):

Hmm, the most natural setting for the intrinsic interior would be affine spaces / add_torsor.

def intrinsic_interior' (𝕜 : Type) {V P : Type} [normed_field 𝕜] [seminormed_add_comm_group V] [normed_space 𝕜 V]
  [pseudo_metric_space P] [normed_add_torsor V P]
  (A : set P) :=
(coe : affine_span R A  P) '' interior ((coe : affine_span R A  P) ⁻¹' A)

This would enable us to conveniently state the property that it is intrinsic:

def isometry_range_intrinsic_interior {𝕜 V V₂ P P₂: Type}
  [normed_field 𝕜] [seminormed_add_comm_group V] [seminormed_add_comm_group V₂] [normed_space 𝕜 V]
  [normed_space 𝕜 V₂] [pseudo_metric_space P] [pseudo_metric_space P₂] [normed_add_torsor V P]
  [normed_add_torsor V₂ P₂]
  (φ : P →ᵃⁱ[𝕜] P₂) (A : set P) :
φ '' intrinsic_interior' 𝕜 A = intrinsic_interior' 𝕜 (φ '' A) := sorry

It is somewhat painful that affine_subspace may be empty but add_torsormust not be, hindering us from defining the inclusion of an affine_subspace as an affine map (except we fill the nonempty instance manually or add a new type nonempty_affine_subspace)...

Yaël Dillies (Sep 02 2022 at 11:51):

In fact I myself find that having add_torsor α imply nonempty α to be a problem on branch#linear_algebra_lint.

Paul A. Reichert (Sep 04 2022 at 20:51):

Update: convex_relint has been rewritten such that the intrinsic interior/frontier/closure is defined in affine spaces and I proved that the intrinsic interior of a nonempty convex set in a normed space over some normed field is nonempty (which we can generalize as soon as convex is defined for arbitrary affine spaces, not only modules).

Most of the file intrinsic.lean are helper lemmata that I should move into other files. Beyond that, I have to remove some old code blocks I commented out.

I also get some looping instances because of add_torsor and nonempty, so we will have to hold back merging until we have resolved Empty torsors in some way.

I appreciate any kind of feedback.

Paul A. Reichert (Sep 04 2022 at 21:12):

One aspect of the code that is very ugly is that I had to redeclare all variables in every definition or theorem. I tried this:

variables (R : Type) {V P : Type} [ring R] [seminormed_add_comm_group V] [module R V]
  [pseudo_metric_space P] [normed_add_torsor V P]

def intrinsic_interior (A : set P) := (coe : affine_span R A  P) '' interior ((coe : affine_span R A  P) ⁻¹' A)

But based on the signature of the definition, Lean seems to think that the instance of normed_add_torsor is not needed and forgets it, just to throw an error because it cannot derive add_torsor.

Yaël Dillies (Sep 04 2022 at 21:13):

You should include V, because Lean does not see it in the statement of the declaration, so does not add it to the context.

Paul A. Reichert (Sep 08 2022 at 10:12):

Just as an update, I'm currently creating small PRs for the several prerequisites that should go into other files -- as soon as that is done, I'll PR the intrinsic module.


Last updated: Dec 20 2023 at 11:08 UTC