Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit ccc98d0

Browse files
committed
refactor(*): midpoint, point_reflection, and Mazur-Ulam in affine spaces (#4752)
* redefine `midpoint` for points in an affine space; * redefine `point_reflection` for affine spaces (as `equiv`, `affine_equiv`, and `isometric`); * define `const_vsub` as `equiv`, `affine_equiv`, and `isometric`; * define `affine_map.of_map_midpoint`; * fully migrate the proof of Mazur-Ulam theorem to affine spaces;
1 parent 4d19191 commit ccc98d0

File tree

11 files changed

+434
-307
lines changed

11 files changed

+434
-307
lines changed

src/algebra/add_torsor.lean

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,17 @@ def vadd_const (p : P) : G ≃ P :=
437437

438438
@[simp] lemma coe_vadd_const_symm (p : P) : ⇑(vadd_const p).symm = λ p', p' -ᵥ p := rfl
439439

440+
/-- `p' ↦ p -ᵥ p'` as an equivalence. -/
441+
def const_vsub (p : P) : P ≃ G :=
442+
{ to_fun := (-ᵥ) p,
443+
inv_fun := λ v, -v +ᵥ p,
444+
left_inv := λ p', by simp,
445+
right_inv := λ v, by simp [vsub_vadd_eq_vsub_sub] }
446+
447+
@[simp] lemma coe_const_vsub (p : P) : ⇑(const_vsub p) = (-ᵥ) p := rfl
448+
449+
@[simp] lemma coe_const_vsub_symm (p : P) : ⇑(const_vsub p).symm = λ v, -v +ᵥ p := rfl
450+
440451
variables (P)
441452

442453
/-- The permutation given by `p ↦ v +ᵥ p`. -/
@@ -464,4 +475,38 @@ def const_vadd_hom : multiplicative G →* equiv.perm P :=
464475
map_one' := const_vadd_zero G P,
465476
map_mul' := const_vadd_add P }
466477

478+
variable {P}
479+
480+
open function
481+
482+
/-- Point reflection in `x` as a permutation. -/
483+
def point_reflection (x : P) : perm P := (const_vsub x).trans (vadd_const x)
484+
485+
lemma point_reflection_apply (x y : P) : point_reflection x y = x -ᵥ y +ᵥ x := rfl
486+
487+
@[simp] lemma point_reflection_symm (x : P) : (point_reflection x).symm = point_reflection x :=
488+
ext $ by simp [point_reflection]
489+
490+
@[simp] lemma point_reflection_self (x : P) : point_reflection x x = x := vsub_vadd _ _
491+
492+
lemma point_reflection_involutive (x : P) : involutive (point_reflection x : P → P) :=
493+
λ y, (equiv.apply_eq_iff_eq_symm_apply _).2 $ by rw point_reflection_symm
494+
495+
/-- `x` is the only fixed point of `point_reflection x`. This lemma requires
496+
`x + x = y + y ↔ x = y`. There is no typeclass to use here, so we add it as an explicit argument. -/
497+
lemma point_reflection_fixed_iff_of_injective_bit0 {x y : P} (h : injective (bit0 : G → G)) :
498+
point_reflection x y = y ↔ y = x :=
499+
by rw [point_reflection_apply, eq_comm, eq_vadd_iff_vsub_eq, ← neg_vsub_eq_vsub_rev,
500+
neg_eq_iff_add_eq_zero, ← bit0, ← bit0_zero, h.eq_iff, vsub_eq_zero_iff_eq, eq_comm]
501+
502+
omit G
503+
504+
lemma injective_point_reflection_left_of_injective_bit0 {G P : Type*} [add_comm_group G]
505+
[add_torsor G P] (h : injective (bit0 : G → G)) (y : P) :
506+
injective (λ x : P, point_reflection x y) :=
507+
λ x₁ x₂ (hy : point_reflection x₁ y = point_reflection x₂ y),
508+
by rwa [point_reflection_apply, point_reflection_apply, vadd_eq_vadd_iff_sub_eq_vsub,
509+
vsub_sub_vsub_cancel_right, ← neg_vsub_eq_vsub_rev, neg_eq_iff_add_eq_zero, ← bit0, ← bit0_zero,
510+
h.eq_iff, vsub_eq_zero_iff_eq] at hy
511+
467512
end equiv

src/algebra/invertible.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ def invertible_neg [ring α] (a : α) [invertible a] : invertible (-a) :=
125125
@[simp] lemma inv_of_neg [ring α] (a : α) [invertible a] [invertible (-a)] : ⅟(-a) = -⅟a :=
126126
inv_of_eq_right_inv (by simp)
127127

128+
@[simp] lemma one_sub_inv_of_two [ring α] [invertible (2:α)] : 1 - (⅟2:α) = ⅟2 :=
129+
(is_unit_of_invertible (2:α)).mul_right_inj.1 $
130+
by rw [mul_sub, mul_inv_of_self, mul_one, bit0, add_sub_cancel]
131+
128132
/-- `a` is the inverse of `⅟a`. -/
129133
instance invertible_inv_of [has_one α] [has_mul α] {a : α} [invertible a] : invertible (⅟a) :=
130134
⟨ a, mul_inv_of_self a, inv_of_mul_self a ⟩

src/algebra/midpoint.lean

Lines changed: 0 additions & 140 deletions
This file was deleted.

src/algebra/module/basic.lean

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ variables (R)
6060

6161
theorem two_smul : (2 : R) • x = x + x := by rw [bit0, add_smul, one_smul]
6262

63+
theorem two_smul' : (2 : R) • x = bit0 x := two_smul R x
64+
6365
/-- Pullback a `semimodule` structure along an injective additive monoid homomorphism. -/
6466
protected def function.injective.semimodule [add_comm_monoid M₂] [has_scalar R M₂] (f : M₂ →+ M)
6567
(hf : injective f) (smul : ∀ (c : R) x, f (c • x) = c • f x) :

src/analysis/normed_space/add_torsor.lean

Lines changed: 79 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ Copyright (c) 2020 Joseph Myers. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Joseph Myers, Yury Kudryashov.
55
-/
6-
import algebra.add_torsor
6+
import linear_algebra.affine_space.midpoint
77
import topology.metric_space.isometry
8+
import topology.instances.real_vector_space
89

910
/-!
1011
# Torsors of additive normed group actions.
@@ -122,6 +123,14 @@ def vadd_const (p : P) : V ≃ᵢ P :=
122123

123124
@[simp] lemma vadd_const_to_equiv (p : P) : (vadd_const p).to_equiv = equiv.vadd_const p := rfl
124125

126+
/-- `p' ↦ p -ᵥ p'` as an equivalence. -/
127+
def const_vsub (p : P) : P ≃ᵢ V :=
128+
⟨equiv.const_vsub p, isometry_emetric_iff_metric.2 $ λ p₁ p₂, dist_vsub_cancel_left _ _ _⟩
129+
130+
@[simp] lemma coe_const_vsub (p : P) : ⇑(const_vsub p) = (-ᵥ) p := rfl
131+
132+
@[simp] lemma coe_const_vsub_symm (p : P) : ⇑(const_vsub p).symm = λ v, -v +ᵥ p := rfl
133+
125134
variables (P)
126135

127136
/-- The map `p ↦ v +ᵥ p` as an isometric automorphism of `P`. -/
@@ -135,6 +144,57 @@ variable (V)
135144
@[simp] lemma const_vadd_zero : const_vadd P (0:V) = isometric.refl P :=
136145
isometric.to_equiv_inj $ equiv.const_vadd_zero V P
137146

147+
variables {P V}
148+
149+
/-- Point reflection in `x` as an `isometric` homeomorphism. -/
150+
def point_reflection (x : P) : P ≃ᵢ P :=
151+
(const_vsub x).trans (vadd_const x)
152+
153+
lemma point_reflection_apply (x y : P) : point_reflection x y = x -ᵥ y +ᵥ x := rfl
154+
155+
@[simp] lemma point_reflection_to_equiv (x : P) :
156+
(point_reflection x).to_equiv = equiv.point_reflection x := rfl
157+
158+
@[simp] lemma point_reflection_self (x : P) : point_reflection x x = x :=
159+
equiv.point_reflection_self x
160+
161+
lemma point_reflection_involutive (x : P) : function.involutive (point_reflection x : P → P) :=
162+
equiv.point_reflection_involutive x
163+
164+
@[simp] lemma point_reflection_symm (x : P) : (point_reflection x).symm = point_reflection x :=
165+
to_equiv_inj $ equiv.point_reflection_symm x
166+
167+
@[simp] lemma dist_point_reflection_fixed (x y : P) :
168+
dist (point_reflection x y) x = dist y x :=
169+
by rw [← (point_reflection x).dist_eq y x, point_reflection_self]
170+
171+
lemma dist_point_reflection_self' (x y : P) :
172+
dist (point_reflection x y) y = ∥bit0 (x -ᵥ y)∥ :=
173+
by rw [point_reflection_apply, dist_eq_norm_vsub V, vadd_vsub_assoc, bit0]
174+
175+
lemma dist_point_reflection_self (𝕜 : Type*) [normed_field 𝕜] [normed_space 𝕜 V] (x y : P) :
176+
dist (point_reflection x y) y = ∥(2:𝕜)∥ * dist x y :=
177+
by rw [dist_point_reflection_self', ← two_smul' 𝕜 (x -ᵥ y), norm_smul, ← dist_eq_norm_vsub V]
178+
179+
lemma point_reflection_fixed_iff (𝕜 : Type*) [normed_field 𝕜] [normed_space 𝕜 V] [invertible (2:𝕜)]
180+
{x y : P} :
181+
point_reflection x y = y ↔ y = x :=
182+
affine_equiv.point_reflection_fixed_iff_of_module 𝕜
183+
184+
variables [normed_space ℝ V]
185+
186+
lemma dist_point_reflection_self_real (x y : P) :
187+
dist (point_reflection x y) y = 2 * dist x y :=
188+
by { rw [dist_point_reflection_self ℝ, real.norm_two], apply_instance }
189+
190+
@[simp] lemma point_reflection_midpoint_left (x y : P) :
191+
point_reflection (midpoint ℝ x y) x = y :=
192+
affine_equiv.point_reflection_midpoint_left x y
193+
194+
@[simp] lemma point_reflection_midpoint_right (x y : P) :
195+
point_reflection (midpoint ℝ x y) y = x :=
196+
affine_equiv.point_reflection_midpoint_right x y
197+
138198
end isometric
139199

140200
lemma lipschitz_with.vadd [emetric_space α] {f : α → V} {g : α → P} {Kf Kg : ℝ≥0}
@@ -225,3 +285,21 @@ begin
225285
(hf.comp (isometric.vadd_const p).isometry),
226286
exact funext hg
227287
end
288+
289+
variables [normed_space ℝ V] [normed_space ℝ V']
290+
include V'
291+
292+
/-- A continuous map between two normed affine spaces is an affine map provided that
293+
it sends midpoints to midpoints. -/
294+
def affine_map.of_map_midpoint (f : P → P')
295+
(h : ∀ x y, f (midpoint ℝ x y) = midpoint ℝ (f x) (f y))
296+
(hfc : continuous f) :
297+
P →ᵃ[ℝ] P' :=
298+
affine_map.mk' f
299+
↑((add_monoid_hom.of_map_midpoint ℝ ℝ
300+
((affine_equiv.vadd_const ℝ (f $ classical.arbitrary P)).symm ∘ f ∘
301+
(affine_equiv.vadd_const ℝ (classical.arbitrary P))) (by simp)
302+
(λ x y, by simp [h])).to_real_linear_map $ by apply_rules [continuous.vadd, continuous.vsub,
303+
continuous_const, hfc.comp, continuous_id])
304+
(classical.arbitrary P)
305+
(λ p, by simp)

0 commit comments

Comments
 (0)