Skip to content

feat(Geometry/Euclidean): integration formula for μHE#36462

Open
wwylele wants to merge 7 commits intoleanprover-community:masterfrom
wwylele:volume-integral
Open

feat(Geometry/Euclidean): integration formula for μHE#36462
wwylele wants to merge 7 commits intoleanprover-community:masterfrom
wwylele:volume-integral

Conversation

@wwylele
Copy link
Copy Markdown
Collaborator

@wwylele wwylele commented Mar 10, 2026

A step towards #34826.


The location of MeasureTheory.volume_eq_of_finrank_eq_one feels a bit random. I'd like to put it in some early files, but it uses measure preserving of isometry in Mathlib/MeasureTheory/Measure/Haar/InnerProductSpace.lean, which is why it ended up there

Open in Gitpod

@github-actions
Copy link
Copy Markdown

github-actions bot commented Mar 10, 2026

PR summary b6118399e6

Import changes for modified files

No significant changes to the import graph

Import changes for all files
Files Import difference

Declarations diff

+ AffineSubspace.euclideanHausdorffMeasure_eq_lintegral
+ EuclideanGeometry.euclideanHausdorffMeasure_eq_lintegral
+ MeasureTheory.volume_eq_of_finrank_eq_one
+ Submodule.measurableEquivProd
+ Submodule.measurableEquivProd_apply
+ Submodule.measurableEquivProd_symm_apply
+ Submodule.measurePreserving_measurableEquivProd
+ trans_symm

You can run this locally as follows
## summary with just the declaration names:
./scripts/pr_summary/declarations_diff.sh <optional_commit>

## more verbose report:
./scripts/pr_summary/declarations_diff.sh long <optional_commit>

The doc-module for scripts/pr_summary/declarations_diff.sh contains some details about this script.


Increase in tech debt: (relative, absolute) = (4.00, 0.00)
Current number Change Type
6900 4 backward.isDefEq.respectTransparency

Current commit 36d7218d36
Reference commit b6118399e6

You can run this locally as

./scripts/reporting/technical-debt-metrics.sh pr_summary
  • The relative value is the weighted sum of the differences with weight given by the inverse of the current value of the statistic.
  • The absolute value is the relative value divided by the total sum of the inverses of the current values (i.e. the weighted average of the differences).

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR extends the Euclidean Hausdorff measure (μHE[d]) development by adding an orthogonal-decomposition-based integration formula, with supporting measure-theory lemmas to facilitate the construction and simplification of measurable equivalences.

Changes:

  • Add a 1D normalization lemma relating volume on a 1-dimensional real inner product space to a scaled pushforward of Lebesgue measure on .
  • Add a simp lemma for MeasurableEquiv describing how symm interacts with trans.
  • Introduce a measurable equivalence P ≃ᵐ s × sᗮ and prove an integration (Fubini/coarea-style) formula for μHE[finrank ℝ V], plus a 1D special case along a line direction.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
Mathlib/MeasureTheory/Measure/Haar/InnerProductSpace.lean Adds volume_eq_of_finrank_eq_one, a 1D scaling/pushforward characterization of volume.
Mathlib/MeasureTheory/MeasurableSpace/Embedding.lean Adds [simp] lemma MeasurableEquiv.trans_symm for rewriting (e₁.trans e₂).symm.
Mathlib/Geometry/Euclidean/Volume/Measure.lean Adds orthogonal-decomposition measurable equivalence + measure-preservation and proves an integration formula for μHE[d] (and a 1D specialization).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@wwylele
Copy link
Copy Markdown
Collaborator Author

wwylele commented Mar 10, 2026

No description provided.

Comment on lines +203 to +204
(s.orthogonalProjection (q -ᵥ p), sᗮ.orthogonalProjection (q -ᵥ p)) := by
simp [measurableEquivProd]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this true by rfl?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I doesn't work for me

Comment on lines +206 to +209
@[simp]
theorem Submodule.measurableEquivProd_symm_apply (s : Submodule ℝ V) (p : P) (q : s × sᗮ) :
(s.measurableEquivProd p).symm q = (q.1.val + q.2.val) +ᵥ p := by
simp [measurableEquivProd]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rfl?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I doesn't work for me

This is a generalization of `MeasureTheory.Measure.prod_apply` in the affine Euclidean space. -/
theorem AffineSubspace.euclideanHausdorffMeasure_eq_lintegral (s : AffineSubspace ℝ P)
[hs : Nonempty s] {t : Set P} (ht : MeasurableSet t) :
μHE[finrank ℝ V] t = ∫⁻ (x : s), μHE[finrank ℝ s.directionᗮ] (t ∩ mk' x.val s.directionᗮ)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we might want t ∩ mk' x.val s.directionᗮ to be of type Set (mk' x.val s.directionᗮ), otherwise this theorem can't be applied to recursively decompose over different subspcaes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this isn't as useful as I think though

Copy link
Copy Markdown
Collaborator Author

@wwylele wwylele Mar 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the μHE is preserved through subspace inclusion, it is trivial to rewrite this to a set in the subspace, so I think there isn't much difference in strength in application between the two form.

I think in my later application I find this form more useful, where one states simplex.volume = 1/n*height*base without moving between subspaces.

@wwylele wwylele added t-measure-probability Measure theory / Probability theory t-euclidean-geometry Affine and axiomatic geometry labels Mar 12, 2026
@jsm28 jsm28 removed their assignment Mar 16, 2026
@wwylele wwylele requested a review from eric-wieser March 22, 2026 19:30
end Prod

/-- Volume on a 1-dimensional real vector space is equivalent to a scaled volume on ℝ. -/
theorem MeasureTheory.volume_eq_of_finrank_eq_one {V : Type*}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't you prove this "by definition"? For instance going through Module.Basis.addHaar_eq_iff (there might be some missing API).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried a little bit, but couldn't get it shorter. The huge chunk of this proof (line 243 to line 250) is spent on transferring measure between different spaces (V and ℝ), and the only tool for this I have found is LinearIsometryEquiv.measurePreserving.

The missing API here is to generalize MeasureTheory.Measure.map_linearMap_addHaar_eq_smul_addHaar to two different spaces, but the determinant will become basis-dependent. A possible statement might look like

map f b1.addHaar = ENNReal.ofReal |(f.toMatrix b1 b2).det⁻¹| • b2.addHaar

(didn't check carefully and I might have swapped the basis b1 and b2)
This looks like it is worth its separate PR

Copy link
Copy Markdown
Collaborator Author

@wwylele wwylele Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait, what I said doesn't sound right. I just found Module.Basis.map_addHaar. Let me try more

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is how far I have got

theorem MeasureTheory.volume_eq_of_finrank_eq_one {V : Type*}
    [NormedAddCommGroup V] [InnerProductSpace ℝ V] [MeasurableSpace V]
    [BorelSpace V] [FiniteDimensional ℝ V] (h : Module.finrank ℝ V = 1) {v : V} (hv : v ≠ 0) :
    (volume : Measure V) = ‖v‖ₑ • (volume : Measure ℝ).map (· • v) := by
  let f : ℝ ≃L[ℝ] V := (ContinuousLinearEquiv.toSpanNonzeroSingleton ℝ v hv).trans
    (LinearEquiv.ofTop _ sorry).toContinuousLinearEquiv
  suffices (volume : Measure V) = ‖v‖ₑ • (volume : Measure ℝ).map f by
    simpa
  rw [← (stdOrthonormalBasis ℝ ℝ).addHaar_eq_volume, Module.Basis.map_addHaar]
  suffices ((stdOrthonormalBasis ℝ ℝ).toBasis.map f.toLinearEquiv).addHaar =
      ‖v‖₊⁻¹ • volume by
    simp [this]
    sorry
  rw [Module.Basis.addHaar_eq_iff]
  sorry

This is going longer than the current proof and I am not sure what is missing

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here is what I think would be a reasonable way:

theorem MeasureTheory.volume_eq_of_finrank_eq_one {V : Type*}
    [NormedAddCommGroup V] [InnerProductSpace ℝ V] [MeasurableSpace V]
    [BorelSpace V] [FiniteDimensional ℝ V] (h : Module.finrank ℝ V = 1) {v : V} (hv : v ≠ 0) :
    (volume : Measure V) = ‖v‖ₑ • (volume : Measure ℝ).map (· • v) := by
  let f : ℝ ≃L[ℝ] V := (ContinuousLinearEquiv.toSpanNonzeroSingleton ℝ v hv).trans
    (LinearEquiv.ofTop _ sorry).toContinuousLinearEquiv
  suffices (volume : Measure V) = ‖v‖ₑ • (volume : Measure ℝ).map f by simpa
  change _ = ‖v‖₊ • volume.map f
  let b : OrthonormalBasis Unit ℝ V := sorry
  rw [← b.addHaar_eq_volume, Module.Basis.addHaar_eq_iff]
  rw [smul_apply, map_apply]
  · have : f ⁻¹' b.toBasis.parallelepiped = Set.Icc 0 ‖v‖⁻¹ := sorry
    rw [this, Real.volume_Icc]
    · sorry
  · fun_prop
  · exact (TopologicalSpace.PositiveCompacts.isCompact _).measurableSet

What is missing: creating an orthonormal basis from a single nonzero vector (similar to FiniteDimensional.basisSingleton), what does parallelepiped look like in dimension 1, and the last sorry is some ugly ENNReal computation which I think should be easy with tactics but isn't.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I'll see what I can do with these missing pieces and will PR them if I get something good. For now, I am keeping the current proof here as it is not that long, even though not pretty. I don't think this should block the PR

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR for singleton basis: #37506

@wwylele
Copy link
Copy Markdown
Collaborator Author

wwylele commented Mar 31, 2026

(one moment, one small golfing incoming)

@wwylele
Copy link
Copy Markdown
Collaborator Author

wwylele commented Mar 31, 2026

Done

Comment on lines +242 to +252
volume = ((volume : Measure ℝ).map (‖v‖⁻¹ • ·)).map (· • v) := by
have hv' : Submodule.span ℝ {‖v‖⁻¹ • v} = ⊤ := by
rw [Submodule.span_singleton_eq_top_iff]
apply exists_smul_eq_of_finrank_eq_one h
simpa using hv
let f : ℝ ≃ₗᵢ[ℝ] V := (LinearIsometryEquiv.toSpanUnitSingleton (‖v‖⁻¹ • v)
(by simp [norm_smul, hv])).trans (LinearIsometryEquiv.ofTop V _ hv')
rw [map_map (by fun_prop) (by fun_prop)]
convert f.measurePreserving.map_eq.symm
ext x
simp [f, mul_comm, smul_smul]
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am wondering whether it wouldn't be worth factoring this out as a separate lemma.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean the statement volume = ((volume : Measure ℝ).map (‖v‖⁻¹ • ·)).map (· • v)? This looks too niche to me to be a lemma

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you open the EuclideanGeometry namespace? That would shorten some names inside proofs.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This ended up only shortening one, and I had to put the open statement in the middle of the file because there was no existing constant in this namespace from imports. I applied the suggestion anyway as this might be beneficial when I append this file with more lemma in the future

@EtienneC30 EtienneC30 added the awaiting-author A reviewer has asked the author a question or requested changes. label Apr 4, 2026
@wwylele
Copy link
Copy Markdown
Collaborator Author

wwylele commented Apr 4, 2026

-awaiting-author

@github-actions github-actions bot removed the awaiting-author A reviewer has asked the author a question or requested changes. label Apr 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

t-euclidean-geometry Affine and axiomatic geometry t-measure-probability Measure theory / Probability theory

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants