Zulip Chat Archive
Stream: maths
Topic: Piecewise linear maps
GENNARO PORPORA (Mar 24 2025 at 21:29):
Hi, im a math student at the university of Salerno (Italy). Im trying to implement piecewise linear maps between simplicial complexes in lean togheter with my logic professor. Neither I nor my supervisor are very experienced with lean. This is the code I have written so far
import Mathlib.Analysis.Convex.Hull
import Mathlib.Analysis.Convex.Combination
import Mathlib.LinearAlgebra.AffineSpace.Independent
import Mathlib.LinearAlgebra.AffineSpace.AffineSubspace.Basic
import Mathlib.Analysis.Convex.SimplicialComplex.Basic
import Mathlib.Data.Real.Basic
open Set Finset
open Geometry
open SimplicialComplex
variable {๐ : Type*} [LinearOrderedField ๐]
variable {V: Type*} [AddCommGroup V] [Module ๐ V]
variable {W : Type*} [AddCommGroup W] [Module ๐ W]
/- piecewise linear map -/
structure PLMap (K: SimplicialComplex ๐ V) (L: SimplicialComplex ๐ W) where
toFun : V โ W
face2face : โ sk โ K.faces, โ sl โ L.faces, MapsTo toFun sk sl
isLin : โ s โ K.faces, โ (w: V โ ๐), toFun (โ y โ s, w y โข y) = โ y โ s, w y โข toFun y
namespace PLMap
variable {K : SimplicialComplex ๐ V}
variable {L : SimplicialComplex ๐ W}
variable {f: PLMap K L}
instance : CoeFun (PLMap K L) (fun g => V โ W) where
coe g := g.toFun
/- vertices are mapped to vertices -/
theorem v2v: MapsTo f K.vertices L.vertices := by
intro x xink
rw [mem_vertices] at xink
have : โ sl โ L.faces, MapsTo f ({x}: Finset V) sl := f.face2face {x} xink
rcases this with โจsl,โจslinl,x2slโฉโฉ
have xinx : x โ ({x}: Finset V) := by exact mem_singleton.mpr rfl
have fxinsl : f x โ sl := by apply x2sl xinx
have : โz โ sl, f x = z := by
exact exists_eq_right'.mpr (x2sl xinx)
rcases this with โจz,โจzinsl,fxeqzโฉโฉ
rw [fxeqz]
apply mem_vertices.mpr
apply L.down_closed slinl
exact Finset.singleton_subset_iff.mpr zinsl
exact Finset.singleton_ne_empty z
/- the convex hull of a face is mapped to the convex hull of another face -/
lemma hull2hull (sk: Finset V) (hs: sk โ K.faces): โsl โ L.faces,
MapsTo f (convexHull ๐ โsk) (convexHull ๐ โsl) := by
rcases f.face2face sk hs with โจsl, โจslinl,sk2slโฉโฉ
use sl; constructor
exact slinl
intro x hx
rw [mem_convexHull'] at hx
rcases hx with โจw,โจwnng,sum1,xeqโฉโฉ
have fxeq : โ y โ sk, w y โข f y = f x := by
rw [Eq.comm,<-xeq]
apply f.isLin sk hs w
have hullconv : Convex ๐ ((convexHull ๐) โsl : Set W) := by
apply convex_convexHull
have fyinsl : โ y โ sk, f y โ (convexHull ๐ sl) := by
intro y yinsk
have := by apply sk2sl yinsk
apply subset_convexHull ๐ sl
exact this
apply Set.mem_range.mpr
simp
constructor
apply subset_convexHull ๐ (sl: Set W)
apply convex_convexHull
rw [<-fxeq]
apply Convex.sum_mem hullconv wnng sum1 fyinsl
/- the underlying space of K is mapped to the underlying space of L -/
theorem space2space: MapsTo f K.space L.space := by
intro x xink
rcases (mem_space_iff.mp xink) with โจsk,โจskink,xinskโฉโฉ
rcases (f.hull2hull sk skink) with โจsl,โจslinl,sk2slโฉโฉ
have fxinsl := sk2sl xinsk
have hullinsp := convexHull_subset_space slinl
exact hullinsp fxinsl
theorem linear_pieces: โ sk โ K.faces, โ (fsk: V โ W), IsLinearMap ๐ fsk โง
EqOn f fsk sk := by
intro sk skink
sorry
Sorry if my code is not very readable, im not a good at coding :smiling_face_with_tear:
But now im stuck with the last theorem. I want to build a linear map from V to W that coincide with the map f on the convex hull of the face sk of the simplicial complex K. In other words i want to restrict f to (convex hull sk) and then extend the restriction to a linear map V -> W. How can i do this , any idea ? Thak you !!
Ben Eltschig (Mar 26 2025 at 02:45):
This is not an answer to your quesiton, but - are you sure your definition of PLMap
actually does what you want it to do? As far as I can see it currently is a map between the ambient spaces, not just the simplicial complexes, and your isLin
condition forces it to be linear on every linear linear subspace spanned by one of the faces
Ben Eltschig (Mar 26 2025 at 02:45):
I assume what you actually want is a map that is affine-linear on each of the faces
GENNARO PORPORA (Mar 26 2025 at 05:22):
Thank you for your answer. Initially I defined plmap to be a map from K.space to L.space but I faced a lot of type mismatch problems so I tought well lets define it from V to W and then prove that it maps k.space to L.space. You are right it should be affine linear but the mathlib version of simplicial complex I found actually lives in a Module not in an Affine Space and unless I want to define my own version of simplicial complex (and I dont want xD) I have to adapt the definition somehow.
GENNARO PORPORA (Apr 12 2025 at 19:34):
I changed my strategy, now isLin says that f coincides with a linear map on each face. And everything works but I have a new problem. I want to define a barycentric subdivision of a simplicial complex. I defined Bcenter but when I use it in isSubdive it tells me typeclass problem Module ??? V
import Mathlib.Analysis.Convex.Hull
import Mathlib.Analysis.Convex.Combination
import Mathlib.LinearAlgebra.AffineSpace.Independent
import Mathlib.LinearAlgebra.AffineSpace.AffineSubspace.Basic
import Mathlib.Analysis.Convex.SimplicialComplex.Basic
import Mathlib.Data.Real.Basic
open Set Finset
open Geometry
open SimplicialComplex
variable {๐ : Type*} [LinearOrderedField ๐]
variable {V: Type*} [AddCommGroup V] [Module ๐ V] [DecidableEq V]
variable {W : Type*} [AddCommGroup W] [Module ๐ W]
/- piecewise linear map -/
structure PLMap (K: SimplicialComplex ๐ V) (L: SimplicialComplex ๐ W) where
toFun : V โ W
face2face : โ sk โ K.faces, โ sl โ L.faces, MapsTo toFun sk sl
isLin : โ sk โ K.faces, โ (fsk: V โโ[๐] W), IsLinearMap ๐ fsk โง
EqOn toFun fsk (convexHull ๐ sk)
-- isLin : โ s โ K.faces, โ (w: V โ ๐), toFun (โ y โ s, w y โข y) = โ y โ s, w y โข toFun y
namespace PLMap
variable {K : SimplicialComplex ๐ V}
variable {L : SimplicialComplex ๐ W}
variable {f: PLMap K L}
variable (s : Finset V)
variable (v : V โ V)
variable (c : V โ ๐)
variable (f1 f2 : V โ W)
def idV : V โโ[๐] V := LinearMap.id
instance : CoeFun (PLMap K L) (fun g => V โ W) where
coe g := g.toFun
theorem _linear_map_sum (g:V โโ[๐] W): g (โ i โ s, c i โข v i) = โ i โ s, c i โข g (v i) := by
induction s using Finset.induction with
| empty =>
simp [Finset.sum_empty]
| insert i ih =>
simp
theorem _sum_rewrite (h: EqOn f1 f2 s ):
โ a โ s, c a โข f1 a = โ a โ s, c a โข f2 ((idV : V โโ[๐] V) a) := by
-- Usa l'induzione su s
induction s using Finset.induction with
| empty =>
-- Caso base: s รจ vuoto
simp [sum_empty]
| insert a s' =>
exact sum_congr rfl fun x a โฆ congrArg (HSMul.hSMul (c x)) (h a)
/- vertices are mapped to vertices -/
theorem v2v: MapsTo f K.vertices L.vertices := by
intro x xink
rw [mem_vertices] at xink
have : โ sl โ L.faces, MapsTo f ({x}: Finset V) sl := f.face2face {x} xink
rcases this with โจsl,โจslinl,x2slโฉโฉ
have xinx : x โ ({x}: Finset V) := by exact mem_singleton.mpr rfl
have fxinsl : f x โ sl := by apply x2sl xinx
have : โz โ sl, f x = z := by
exact exists_eq_right'.mpr (x2sl xinx)
rcases this with โจz,โจzinsl,fxeqzโฉโฉ
rw [fxeqz]
apply mem_vertices.mpr
apply L.down_closed slinl
exact Finset.singleton_subset_iff.mpr zinsl
exact Finset.singleton_ne_empty z
/- the convex hull of a face is mapped to the convex hull of another face -/
lemma hull2hull (sk: Finset V) (hs: sk โ K.faces): โsl โ L.faces,
MapsTo f (convexHull ๐ โsk) (convexHull ๐ โsl) := by
rcases f.face2face sk hs with โจsl, โจslinl,sk2slโฉโฉ
use sl; constructor
exact slinl
intro x hx
rw [mem_convexHull'] at hx
rcases hx with โจw,โจwnng,sum1,xeqโฉโฉ
have := f.isLin sk hs
rcases this with โจfsk,โจfsklin,eqonhullโฉโฉ
have hullconvsk : Convex ๐ ((convexHull ๐) โsk : Set V) := by
apply convex_convexHull
have fxeq : โ y โ sk, w y โข f y = f x := by
rw [Eq.comm,<-xeq]
--rcases fsklin with โจfskadd,fskmulโฉ
have := _linear_map_sum sk (idV : V โโ[๐] V) w fsk
have eqonsk : EqOn f fsk sk := by
intro z zinsk
apply eqonhull
exact mem_convexHull_iff.mpr fun t a a_1 โฆ a zinsk
rw [_sum_rewrite sk w f fsk eqonsk, eqonhull]
exact this
apply Convex.sum_mem hullconvsk wnng sum1
apply subset_convexHull ๐ (sk: Set V)
have hullconv : Convex ๐ ((convexHull ๐) โsl : Set W) := by
apply convex_convexHull
have fyinsl : โ y โ sk, f y โ (convexHull ๐ sl) := by
intro y yinsk
have := by apply sk2sl yinsk
apply subset_convexHull ๐ sl
exact this
apply Set.mem_range.mpr
simp
constructor
apply subset_convexHull ๐ (sl: Set W)
apply convex_convexHull
rw [<-fxeq]
apply Convex.sum_mem hullconv wnng sum1 fyinsl
/- the underlying space of K is mapped to the underlying space of L -/
theorem space2space: MapsTo f K.space L.space := by
intro x xink
rcases (mem_space_iff.mp xink) with โจsk,โจskink,xinskโฉโฉ
rcases (f.hull2hull sk skink) with โจsl,โจslinl,sk2slโฉโฉ
have fxinsl := sk2sl xinsk
have hullinsp := convexHull_subset_space slinl
exact hullinsp fxinsl
def Bcenter (s : Finset V) : V :=
Finset.centerMass s (fun _ => 1 : V โ ๐) id
def isSubdiv (K K' : SimplicialComplex ๐ V) : Prop :=
โ s โ K.faces, Bcenter s โ K'.vertices
```
```
GENNARO PORPORA (Apr 17 2025 at 15:53):
I cant solve a typeclass instance problem in this bit of code (the problem appears in (isPLMap p) in the plmap_iff theorem ). I tried everything
:sob:
-- K' รจ una suddivisione di K
def isSubdiv (K K' : SimplicialComplex ๐ V) : Prop :=
โ s โ K.faces, โ(t: Set (Finset V)),
(t โ K'.faces) โง (s: Set V) = (โ s' โ t, s')
-- TODO : se K' e' una suddivisione di K allora K'.space = K.space
-- p รจ una PLMap tra il supporto di K' e il supporto di L' ?
def isPLMap (p:V โ W) : Prop :=
โ(K' : SimplicialComplex ๐ V), โ(L' : SimplicialComplex ๐ W),
โ(f: PLMap K' L'), EqOn p f K'.space
-- p รจ lineare sulle facce di K'
def lin_on_faces (p:V โ W) (K' : SimplicialComplex ๐ V) : Prop :=
โ s โ K'.faces, โ (fs: V โโ[๐] W), EqOn p fs (convexHull ๐ s)
theorem plmap_iff (p:V โ W) (sp2sp: MapsTo p K.space L.space):
(isPLMap p) โ โ(K' : SimplicialComplex ๐ V),
(isSubdiv K K') โง (lin_on_faces p K') := by
sorry
end PLMap
```
```
Ben Eltschig (Apr 17 2025 at 15:54):
Sorry for the late reply - I assume you figured this out by now, but in case you didn't, the error thrown on Bcenter s
is lean telling you that Bcenter
requives V
to be a vector field over some field ๐
and can't figure out from the context what that field is. You can fix that by either making ๐
an explicit argument of Bcenter
and then using it as Bcenter ๐ s
, or by passing the implicit argument explicitly like in Bcenter (๐ := ๐) s
. Since this issue likely occurs every time you try to use Bcenter s
, I would recommend the former.
Ben Eltschig (Apr 17 2025 at 16:00):
In case you're wondering, the reason that lean can't infer ๐
from the Module ๐ V
instance you have around is that V
could very well be a vector space over two different fields; for example, every complex vector space is also a real vector space and so on. It is for this reason that when lean needs an instance like Module ? V
and doesn't know yet what ?
is, it complains right away instead of looking at the instances you have around and picking the first one it finds.
Ben Eltschig (Apr 17 2025 at 16:01):
(that was meant in reply to your message from 5 days ago, I didn't see the other one until after I replied)
GENNARO PORPORA (Apr 17 2025 at 16:01):
OMG you are my SAVIOR !! In truth I completely eliminated Bcenter from my code, but the same problem occured now with isPLMap. With ( k := k) now works !!
Last updated: May 02 2025 at 03:31 UTC