Skip to content

Commit 4ce6c49

Browse files
committed
feat(LinearAlgebra/AffineSpace): shift and interior of simplex
1 parent 4fdfb0d commit 4ce6c49

2 files changed

Lines changed: 178 additions & 0 deletions

File tree

Mathlib/LinearAlgebra/AffineSpace/AffineSubspace/Shift.lean

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ theorem direction_shift (s : AffineSubspace k P) (c : P) (r : k) :
6464
theorem shift_bot (c : P) (r : k) : shift ⊥ c r = ⊥ := by
6565
simp [shift]
6666

67+
@[simp]
68+
theorem shift_top (c : P) (r : k) : shift ⊤ c r = ⊤ := by
69+
simp [shift, AffineEquiv.surjective]
70+
6771
/-- `AffineSubspace.shift s c r` can be represented by moving a point in the subspace
6872
towards `c`. -/
6973
theorem shift_eq {s : AffineSubspace k P} (p : s) (c : P) (r : k) :
@@ -96,6 +100,55 @@ theorem shift_one (s : AffineSubspace k P) (c : P) : s.shift c 1 = s := by
96100
have h : Nonempty s := by simpa using h
97101
simp [shift, h]
98102

103+
theorem affineCombination_mem_shift {ι : Type*} [Fintype ι] [Nontrivial ι]
104+
(p : ι → P) (i : ι) {w : ι → k} (hw : ∑ i, w i = 1) :
105+
affineCombination k univ p w ∈ (affineSpan k <| p '' {i}ᶜ).shift (p i) (1 - w i) := by
106+
rcases subsingleton_or_nontrivial k with _ | _
107+
· suffices (affineSpan k <| p '' {i}ᶜ) = ⊤ by simp [this]
108+
have : Subsingleton P := (AddTorsor.subsingleton_iff V P).mp <| Module.subsingleton k V
109+
simp
110+
classical
111+
obtain ⟨j, hj⟩ : Set.Nonempty {i}ᶜ := by
112+
by_contra!
113+
simp at this
114+
rw [shift_eq ⟨p j, mem_affineSpan k <| Set.mem_image_of_mem _ hj⟩]
115+
suffices ∃ q ∈ affineSpan k (p '' {i}ᶜ), w i • (p i -ᵥ p j) +ᵥ q = affineCombination k univ p w by
116+
simpa
117+
refine ⟨-(w i • (p i -ᵥ p j)) +ᵥ affineCombination k univ p w, ?_, by simp⟩
118+
rw [← affineCombination_affineCombinationSingleWeights k _ p (mem_univ i),
119+
← affineCombination_affineCombinationSingleWeights k _ p (mem_univ j),
120+
affineCombination_vsub, ← map_smul, ← map_neg, weightedVSub_vadd_affineCombination]
121+
refine affineCombination_mem_affineSpan_image ?_ (fun i' _ hi ↦ ?_) _
122+
· simp [sum_add_distrib, ← mul_sum, hw]
123+
have hi : i' = i := by simpa using hi
124+
have hj : j ≠ i := by simpa using hj
125+
simp [hi, hj.symm]
126+
127+
theorem _root_.AffineIndependent.affineCombination_mem_shift_iff
128+
{ι : Type*} [Fintype ι] [Nontrivial ι] {p : ι → P}
129+
(h : AffineIndependent k p) (i : ι) {w : ι → k} (hw : ∑ i, w i = 1) (c : k) :
130+
affineCombination k univ p w ∈ (affineSpan k <| p '' {i}ᶜ).shift (p i) c ↔
131+
w i = 1 - c := by
132+
refine ⟨?_, fun h ↦ by simpa [h] using affineCombination_mem_shift p i hw⟩
133+
classical
134+
obtain ⟨j, hj⟩ : Set.Nonempty {i}ᶜ := by
135+
by_contra!
136+
simp at this
137+
rw [shift_eq ⟨p j, mem_affineSpan k <| Set.mem_image_of_mem _ hj⟩]
138+
suffices ∀ q ∈ affineSpan k (p '' {i}ᶜ),
139+
(1 - c) • (p i -ᵥ p j) +ᵥ q = affineCombination k univ p w → w i = 1 - c by simpa
140+
intro q hqmem heq
141+
obtain ⟨t, w', ht, hw', rfl⟩ := eq_affineCombination_of_mem_affineSpan_image hqmem
142+
have ht : (t : Set ι).indicator w' i = 0 := Set.indicator_of_notMem (by simpa using ht) w'
143+
have hj : j ≠ i := by simpa using hj
144+
rw [affineCombination_indicator_subset _ _ t.subset_univ,
145+
← affineCombination_affineCombinationSingleWeights k _ p (mem_univ i),
146+
← affineCombination_affineCombinationSingleWeights k _ p (mem_univ j),
147+
affineCombination_vsub, ← map_smul, weightedVSub_vadd_affineCombination,
148+
h.affineCombination_eq_iff_eq ?_ hw] at heq
149+
· simpa [hj.symm, ht] using (heq i (mem_univ i)).symm
150+
· simp [sum_add_distrib, sum_indicator_subset, ← mul_sum, hw']
151+
99152
end Ring
100153

101154
section CommRing
@@ -130,3 +183,124 @@ theorem shift_eq_map_homothety (s : AffineSubspace k P) (c : P) {r : k} (hr : Is
130183
end CommRing
131184

132185
end AffineSubspace
186+
187+
namespace Affine.Simplex
188+
189+
section Ring
190+
variable [Ring k] [PartialOrder k] [IsOrderedAddMonoid k] [AddCommGroup V] [AddTorsor V P]
191+
[Module k V] {n : ℕ} [NeZero n] (s : Affine.Simplex k P n) (i : Fin (n + 1)) {x : k}
192+
193+
theorem closedInterior_inter_shift_zero [ZeroLEOneClass k] :
194+
s.closedInterior ∩ (affineSpan k (Set.range (s.faceOpposite i).points)).shift (s.points i) 0 =
195+
{s.points i} := by
196+
ext p
197+
by_cases hp : p ∈ affineSpan k (Set.range s.points)
198+
· obtain ⟨w, hw, rfl⟩ := eq_affineCombination_of_mem_affineSpan_of_fintype hp
199+
rw [Set.mem_inter_iff, range_faceOpposite_points, SetLike.mem_coe,
200+
s.independent.affineCombination_mem_shift_iff i hw,
201+
affineCombination_mem_closedInterior_iff hw]
202+
suffices (∀ (i : Fin (n + 1)), 0 ≤ w i ∧ w i ≤ 1) ∧ w i = 1
203+
(affineCombination k univ s.points) w = s.points i by
204+
simpa
205+
rw [← affineCombination_affineCombinationSingleWeights k _ s.points (mem_univ i),
206+
s.independent.affineCombination_eq_iff_eq hw (by simp)]
207+
refine ⟨fun ⟨h, hi⟩ ↦ ?_, fun h ↦ ⟨fun j ↦ ?_, ?_⟩⟩
208+
· intro j _
209+
by_cases hj : j = i
210+
· simp [hj, hi]
211+
· suffices w j = 0 by simp [this, hj]
212+
rw [← Finset.univ.sum_erase_add _ (mem_univ i), hi, add_eq_right,
213+
Finset.sum_eq_zero_iff_of_nonneg <| fun j _ ↦ (h j).1] at hw
214+
exact hw j (by simpa using hj)
215+
· rw [h j (mem_univ j)]
216+
by_cases hj : j = i <;> simp [hj]
217+
· simp [h i (mem_univ i)]
218+
· apply iff_of_false
219+
· apply not_and_of_not_left
220+
contrapose! hp
221+
exact Set.mem_of_mem_of_subset hp s.closedInterior_subset_affineSpan
222+
· contrapose! hp
223+
rw [Set.mem_singleton_iff] at hp
224+
rw [hp]
225+
exact mem_affineSpan _ (by simp)
226+
227+
theorem disjoint_closedInterior_shift (hx : x < 01 < x) :
228+
Disjoint s.closedInterior <|
229+
(affineSpan k (Set.range (s.faceOpposite i).points)).shift (s.points i) x := by
230+
refine Set.disjoint_left.mpr fun p hleft hright ↦ ?_
231+
obtain ⟨w, hw, rfl⟩ := eq_affineCombination_of_mem_affineSpan_of_fintype <|
232+
Set.mem_of_mem_of_subset hleft s.closedInterior_subset_affineSpan
233+
rw [range_faceOpposite_points, SetLike.mem_coe,
234+
s.independent.affineCombination_mem_shift_iff i hw] at hright
235+
rw [affineCombination_mem_closedInterior_iff hw] at hleft
236+
grind
237+
238+
end Ring
239+
240+
section Field
241+
variable [Field k] [LinearOrder k] [IsOrderedRing k] [AddCommGroup V] [AddTorsor V P]
242+
[Module k V] {n : ℕ} [NeZero n] (s : Affine.Simplex k P n) (i : Fin (n + 1)) {x : k}
243+
244+
theorem closedInterior_inter_shift (hx : x ∈ Set.Icc 0 1) :
245+
s.closedInterior ∩ (affineSpan k (Set.range (s.faceOpposite i).points)).shift (s.points i) x =
246+
homothety (s.points i) x '' (s.faceOpposite i).closedInterior := by
247+
by_cases! hx0 : x = 0
248+
· simpa [hx0, (s.faceOpposite i).nonempty_closedInterior]
249+
using s.closedInterior_inter_shift_zero i
250+
have hxpos : 0 < x := lt_of_le_of_ne hx.1 hx0.symm
251+
ext p
252+
by_cases hp : p ∈ affineSpan k (Set.range s.points)
253+
· obtain ⟨w, hw, rfl⟩ := eq_affineCombination_of_mem_affineSpan_of_fintype hp
254+
rw [Set.mem_inter_iff, range_faceOpposite_points, SetLike.mem_coe,
255+
s.independent.affineCombination_mem_shift_iff i hw,
256+
affineCombination_mem_closedInterior_iff hw, Set.mem_image]
257+
simp_rw [AffineMap.homothety_eq_iff_of_mul_eq_one (mul_inv_cancel₀ hx0),
258+
univ.homothety_affineCombination _ _ (mem_univ i)]
259+
simp only [↓existsAndEq, and_true]
260+
rw [faceOpposite, affineCombination_mem_closedInterior_face_iff_mem_Icc _ _ (by
261+
simp [AffineMap.lineMap_apply, Finset.sum_add_distrib, ← Finset.mul_sum,
262+
Finset.sum_sub_distrib, hw])]
263+
trans (∀ j ∈ ({i}ᶜ : Finset _), x⁻¹ * w j ∈ Set.Icc 0 1) ∧
264+
∀ j ∉ ({i}ᶜ : Finset _), x⁻¹ * (w j - 1) + 1 = 0
265+
· refine ⟨fun ⟨hj, hi⟩ ↦ ⟨fun j hji ↦ ⟨?_, ?_⟩, fun j hji ↦ ?_⟩, fun ⟨hj, hi⟩ ↦ ?_⟩
266+
· exact mul_nonneg (by simpa using hx.1) (hj j).1
267+
· rw [eq_sub_iff_add_eq, add_comm, ← eq_sub_iff_add_eq] at hi
268+
rw [inv_mul_le_one₀ hxpos, hi, le_sub_iff_add_le, ← hw]
269+
apply Finset.add_le_sum (fun i _ ↦ (hj i).1) (mem_univ j) (mem_univ i)
270+
simpa using hji
271+
· have hji : j = i := by simpa using hji
272+
simp [hji, hi, hx0]
273+
· specialize hi i (by simp)
274+
have hix : w i = 1 - x := by grind
275+
refine ⟨?_, hix⟩
276+
suffices ∀ (j : Fin (n + 1)), 0 ≤ w j by
277+
refine fun j ↦ ⟨this j, ?_⟩
278+
contrapose! hw
279+
apply ne_of_gt
280+
rw [← Finset.sum_erase_add _ _ (mem_univ j)]
281+
apply lt_add_of_nonneg_of_lt (sum_nonneg fun i _ ↦ this i) hw
282+
intro j
283+
by_cases hji : j = i
284+
· rw [hji, hix]
285+
simpa using hx.2
286+
· specialize hj j (by simpa using hji)
287+
apply nonneg_of_mul_nonneg_right hj.1
288+
simpa using hxpos
289+
· congrm (∀ j, (hj : _) → ?_) ∧ ∀ j, (hj : _) → ?_
290+
· have hj : j ≠ i := by simpa using hj
291+
simp [lineMap_apply, hj]
292+
· have hj : j = i := by simpa using hj
293+
simp [lineMap_apply, hj]
294+
· apply iff_of_false
295+
· apply not_and_of_not_left
296+
contrapose! hp
297+
exact Set.mem_of_mem_of_subset hp s.closedInterior_subset_affineSpan
298+
· contrapose! hp
299+
rw [Set.mem_image] at hp
300+
obtain ⟨q, hq, rfl⟩ := hp
301+
apply homothety_mem (mem_affineSpan _ (by simp))
302+
obtain hq := Set.mem_of_mem_of_subset hq (s.faceOpposite i).closedInterior_subset_affineSpan
303+
exact Set.mem_of_mem_of_subset hq (affineSpan_mono _ (by simp))
304+
305+
end Field
306+
end Affine.Simplex

Mathlib/LinearAlgebra/AffineSpace/Simplex/Basic.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,10 @@ lemma point_mem_closedInterior [ZeroLEOneClass k] {n : ℕ} (s : Simplex k P n)
498498
intro j
499499
by_cases hj : j = i <;> simp [hj]
500500

501+
lemma nonempty_closedInterior [ZeroLEOneClass k] {n : ℕ} (s : Simplex k P n) :
502+
s.closedInterior.Nonempty :=
503+
⟨s.points 0, s.point_mem_closedInterior 0
504+
501505
lemma interior_ssubset_closedInterior [ZeroLEOneClass k] {n : ℕ} (s : Simplex k P n) :
502506
s.interior ⊂ s.closedInterior := by
503507
rw [Set.ssubset_iff_exists]

0 commit comments

Comments
 (0)