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