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

Commit d9a5180

Browse files
committed
refactor(linear_algebra,analysis/normed_space): use finite, review API, golf (#17320)
* replace `fintype_of_fin_dim_affine_independent` with `finite_of_fin_dim_affine_independent`; * rename old `finite_of_fin_dim_affine_independent` to `finite_set_of_fin_dim_affine_independent`, generalize; * define `affine_basis.comp_equiv`; * add `affine_basis.finite`, `affine_basis.finite_set`, `affine_basis.coord_apply_centroid`, `affine_basis.card_eq_finrank_add_one` * use more precise statement in `exists_affine_basis`, add `exists_affine_subbasis`; * rename `interior_convex_hull_aff_basis` to `affine_basis.interior_convex_hull`; * rename `exists_subset_affine_independent_span_eq_top_of_open` to `is_open.exists_between_affine_independent_span_eq_top`, golf; * add `is_open.exists_subset_affine_independent_span_eq_top`, `is_open.affine_span_eq_top`, `affine_span_eq_top_of_nonempty_interior`, and `affine_basis.centroid_mem_interior_convex_hull`; * rename `interior_convex_hull_nonempty_iff_aff_span_eq_top` to `interior_convex_hull_nonempty_iff_affine_span_eq_top`
1 parent a9dd84b commit d9a5180

File tree

5 files changed

+111
-83
lines changed

5 files changed

+111
-83
lines changed

src/analysis/normed_space/add_torsor_bases.lean

Lines changed: 59 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,9 @@ This file contains results about bases in normed affine spaces.
1919
2020
* `continuous_barycentric_coord`
2121
* `is_open_map_barycentric_coord`
22-
* `interior_convex_hull_aff_basis`
22+
* `affine_basis.interior_convex_hull`
2323
* `exists_subset_affine_independent_span_eq_top_of_open`
24-
* `interior_convex_hull_nonempty_iff_aff_span_eq_top`
24+
* `interior_convex_hull_nonempty_iff_affine_span_eq_top`
2525
-/
2626

2727
section barycentric
@@ -54,9 +54,9 @@ to this basis.
5454
5555
TODO Restate this result for affine spaces (instead of vector spaces) once the definition of
5656
convexity is generalised to this setting. -/
57-
lemma interior_convex_hull_aff_basis {ι E : Type*} [finite ι] [normed_add_comm_group E]
57+
lemma affine_basis.interior_convex_hull {ι E : Type*} [finite ι] [normed_add_comm_group E]
5858
[normed_space ℝ E] (b : affine_basis ι ℝ E) :
59-
interior (convex_hull ℝ (range b.points)) = { x | ∀ i, 0 < b.coord i x } :=
59+
interior (convex_hull ℝ (range b.points)) = {x | ∀ i, 0 < b.coord i x} :=
6060
begin
6161
casesI subsingleton_or_nontrivial ι,
6262
{ -- The zero-dimensional case.
@@ -66,7 +66,7 @@ begin
6666
{ -- The positive-dimensional case.
6767
haveI : finite_dimensional ℝ E := b.finite_dimensional,
6868
have : convex_hull ℝ (range b.points) = ⋂ i, (b.coord i)⁻¹' Ici 0,
69-
{ rw convex_hull_affine_basis_eq_nonneg_barycentric b, ext, simp, },
69+
{ rw [convex_hull_affine_basis_eq_nonneg_barycentric b, set_of_forall], refl },
7070
ext,
7171
simp only [this, interior_Inter, ← is_open_map.preimage_interior_eq_interior_preimage
7272
(is_open_map_barycentric_coord b _) (continuous_barycentric_coord b _),
@@ -81,77 +81,77 @@ open affine_map
8181

8282
/-- Given a set `s` of affine-independent points belonging to an open set `u`, we may extend `s` to
8383
an affine basis, all of whose elements belong to `u`. -/
84-
lemma exists_subset_affine_independent_span_eq_top_of_open {s u : set P} (hu : is_open u)
84+
lemma is_open.exists_between_affine_independent_span_eq_top {s u : set P} (hu : is_open u)
8585
(hsu : s ⊆ u) (hne : s.nonempty) (h : affine_independent ℝ (coe : s → P)) :
8686
∃ t : set P, s ⊆ t ∧ t ⊆ u ∧ affine_independent ℝ (coe : t → P) ∧ affine_span ℝ t = ⊤ :=
8787
begin
8888
obtain ⟨q, hq⟩ := hne,
89-
obtain ⟨ε, , hεu⟩ := metric.is_open_iff.mp hu q (hsu hq),
89+
obtain ⟨ε, ε0, hεu⟩ := metric.nhds_basis_closed_ball.mem_iff.1 (hu.mem_nhds $ hsu hq),
9090
obtain ⟨t, ht₁, ht₂, ht₃⟩ := exists_subset_affine_independent_affine_span_eq_top h,
91-
let f : P → P := λ y, line_map q y (ε / 2 / (dist y q)),
91+
let f : P → P := λ y, line_map q y (ε / dist y q),
9292
have hf : ∀ y, f y ∈ u,
93-
{ intros y,
94-
apply hεu,
95-
simp only [metric.mem_ball, f, line_map_apply, dist_vadd_left, norm_smul, real.norm_eq_abs,
96-
dist_eq_norm_vsub V y q],
97-
cases eq_or_ne (∥y -ᵥ q∥) 0 with hyq hyq, { rwa [hyq, mul_zero], },
98-
rw [← norm_pos_iff, norm_norm] at hyq,
99-
calc abs (ε / 2 / ∥y -ᵥ q∥) * ∥y -ᵥ q∥
100-
= ε / 2 / ∥y -ᵥ q∥ * ∥y -ᵥ q∥ : by rw [abs_div, abs_of_pos (half_pos hε), abs_of_pos hyq]
101-
... = ε / 2 : div_mul_cancel _ (ne_of_gt hyq)
102-
... < ε : half_lt_self hε, },
103-
have hεyq : ∀ (y ∉ s), ε / 2 / dist y q ≠ 0,
104-
{ simp only [ne.def, div_eq_zero_iff, or_false, dist_eq_zero, bit0_eq_zero, one_ne_zero,
105-
not_or_distrib, ne_of_gt hε, true_and, not_false_iff],
106-
exact λ y h1 h2, h1 (h2.symm ▸ hq) },
93+
{ refine λ y, hεu _,
94+
simp only [f],
95+
rw [metric.mem_closed_ball, line_map_apply, dist_vadd_left, norm_smul, real.norm_eq_abs,
96+
dist_eq_norm_vsub V y q, abs_div, abs_of_pos ε0, abs_of_nonneg (norm_nonneg _), div_mul_comm],
97+
exact mul_le_of_le_one_left ε0.le (div_self_le_one _) },
98+
have hεyq : ∀ y ∉ s, ε / dist y q ≠ 0,
99+
from λ y hy, div_ne_zero ε0.ne' (dist_ne_zero.2 (ne_of_mem_of_not_mem hq hy).symm),
107100
classical,
108101
let w : t → ℝˣ := λ p, if hp : (p : P) ∈ s then 1 else units.mk0 _ (hεyq ↑p hp),
109102
refine ⟨set.range (λ (p : t), line_map q p (w p : ℝ)), _, _, _, _⟩,
110103
{ intros p hp, use ⟨p, ht₁ hp⟩, simp [w, hp], },
111-
{ intros y hy,
112-
simp only [set.mem_range, set_coe.exists, subtype.coe_mk] at hy,
113-
obtain ⟨p, hp, hyq⟩ := hy,
114-
by_cases hps : p ∈ s;
115-
simp only [w, hps, line_map_apply_one, units.coe_mk0, dif_neg, dif_pos, not_false_iff,
116-
units.coe_one, subtype.coe_mk] at hyq;
117-
rw ← hyq;
118-
[exact hsu hps, exact hf p], },
104+
{ rintros y ⟨⟨p, hp⟩, rfl⟩,
105+
by_cases hps : p ∈ s; simp only [w, hps, line_map_apply_one, units.coe_mk0, dif_neg, dif_pos,
106+
not_false_iff, units.coe_one, subtype.coe_mk];
107+
[exact hsu hps, exact hf p], },
119108
{ exact (ht₂.units_line_map ⟨q, ht₁ hq⟩ w).range, },
120109
{ rw [affine_span_eq_affine_span_line_map_units (ht₁ hq) w, ht₃], },
121110
end
122111

123-
lemma interior_convex_hull_nonempty_iff_aff_span_eq_top [finite_dimensional ℝ V] {s : set V} :
112+
lemma is_open.exists_subset_affine_independent_span_eq_top {u : set P} (hu : is_open u)
113+
(hne : u.nonempty) :
114+
∃ s ⊆ u, affine_independent ℝ (coe : s → P) ∧ affine_span ℝ s = ⊤ :=
115+
begin
116+
rcases hne with ⟨x, hx⟩,
117+
rcases hu.exists_between_affine_independent_span_eq_top (singleton_subset_iff.mpr hx)
118+
(singleton_nonempty _) (affine_independent_of_subsingleton _ _) with ⟨s, -, hsu, hs⟩,
119+
exact ⟨s, hsu, hs⟩
120+
end
121+
122+
/-- The affine span of a nonempty open set is `⊤`. -/
123+
lemma is_open.affine_span_eq_top {u : set P} (hu : is_open u) (hne : u.nonempty) :
124+
affine_span ℝ u = ⊤ :=
125+
let ⟨s, hsu, hs, hs'⟩ := hu.exists_subset_affine_independent_span_eq_top hne
126+
in top_unique $ hs' ▸ affine_span_mono _ hsu
127+
128+
lemma affine_span_eq_top_of_nonempty_interior {s : set V}
129+
(hs : (interior $ convex_hull ℝ s).nonempty) :
130+
affine_span ℝ s = ⊤ :=
131+
top_unique $ is_open_interior.affine_span_eq_top hs ▸
132+
(affine_span_mono _ interior_subset).trans_eq (affine_span_convex_hull _)
133+
134+
lemma affine_basis.centroid_mem_interior_convex_hull {ι} [fintype ι] (b : affine_basis ι ℝ V) :
135+
finset.univ.centroid ℝ b.points ∈ interior (convex_hull ℝ (range b.points)) :=
136+
begin
137+
haveI := b.nonempty,
138+
simp only [b.interior_convex_hull, mem_set_of_eq, b.coord_apply_centroid (finset.mem_univ _),
139+
inv_pos, nat.cast_pos, finset.card_pos, finset.univ_nonempty, forall_true_iff]
140+
end
141+
142+
lemma interior_convex_hull_nonempty_iff_affine_span_eq_top [finite_dimensional ℝ V] {s : set V} :
124143
(interior (convex_hull ℝ s)).nonempty ↔ affine_span ℝ s = ⊤ :=
125144
begin
126-
split,
127-
{ rintros ⟨x, hx⟩,
128-
obtain ⟨u, hu₁, hu₂, hu₃⟩ := mem_interior.mp hx,
129-
let t : set V := {x},
130-
obtain ⟨b, hb₁, hb₂, hb₃, hb₄⟩ := exists_subset_affine_independent_span_eq_top_of_open hu₂
131-
(singleton_subset_iff.mpr hu₃) (singleton_nonempty x)
132-
(affine_independent_of_subsingleton ℝ (coe : t → V)),
133-
rw [eq_top_iff, ← hb₄, ← affine_span_convex_hull s],
134-
mono,
135-
exact hb₂.trans hu₁, },
136-
{ intros h,
137-
obtain ⟨t, hts, h_tot, h_ind⟩ := exists_affine_independent ℝ V s,
138-
suffices : (interior (convex_hull ℝ (range (coe : t → V)))).nonempty,
139-
{ rw [subtype.range_coe_subtype, set_of_mem_eq] at this,
140-
apply nonempty.mono _ this,
141-
mono* },
142-
haveI : fintype t := fintype_of_fin_dim_affine_independent ℝ h_ind,
143-
use finset.centroid ℝ (finset.univ : finset t) (coe : t → V),
144-
rw [h, ← @set_of_mem_eq V t, ← subtype.range_coe_subtype] at h_tot,
145-
let b : affine_basis t ℝ V := ⟨coe, h_ind, h_tot⟩,
146-
rw interior_convex_hull_aff_basis b,
147-
have htne : (finset.univ : finset t).nonempty,
148-
{ simpa [finset.univ_nonempty_iff] using
149-
affine_subspace.nonempty_of_affine_span_eq_top ℝ V V h_tot, },
150-
simp [finset.centroid_def, b.coord_apply_combination_of_mem (finset.mem_univ _)
151-
(finset.sum_centroid_weights_eq_one_of_nonempty ℝ (finset.univ : finset t) htne),
152-
finset.centroid_weights_apply, nat.cast_pos, inv_pos, finset.card_pos.mpr htne], },
145+
refine ⟨affine_span_eq_top_of_nonempty_interior, λ h, _⟩,
146+
obtain ⟨t, hts, b, hb⟩ := affine_basis.exists_affine_subbasis h,
147+
suffices : (interior (convex_hull ℝ (range b.points))).nonempty,
148+
{ rw [hb, subtype.range_coe_subtype, set_of_mem_eq] at this,
149+
refine this.mono _,
150+
mono* },
151+
lift t to finset V using b.finite_set,
152+
exact ⟨_, b.centroid_mem_interior_convex_hull⟩
153153
end
154154

155155
lemma convex.interior_nonempty_iff_affine_span_eq_top [finite_dimensional ℝ V] {s : set V}
156156
(hs : convex ℝ s) : (interior s).nonempty ↔ affine_span ℝ s = ⊤ :=
157-
by rw [← interior_convex_hull_nonempty_iff_aff_span_eq_top, hs.convex_hull_eq]
157+
by rw [← interior_convex_hull_nonempty_iff_affine_span_eq_top, hs.convex_hull_eq]

src/analysis/normed_space/finite_dimension.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ end
209209
lemma linear_map.exists_antilipschitz_with [finite_dimensional 𝕜 E] (f : E →ₗ[𝕜] F)
210210
(hf : f.ker = ⊥) : ∃ K > 0, antilipschitz_with K f :=
211211
begin
212-
cases subsingleton_or_nontrivial E; resetI,
212+
casesI subsingleton_or_nontrivial E,
213213
{ exact ⟨1, zero_lt_one, antilipschitz_with.of_subsingleton⟩ },
214214
{ rw linear_map.ker_eq_bot at hf,
215215
let e : E ≃L[𝕜] f.range := (linear_equiv.of_injective f hf).to_continuous_linear_equiv,

src/data/set/finite.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,9 @@ alias finite_univ_iff ↔ _root_.finite.of_finite_univ _
485485
theorem finite.union {s t : set α} (hs : s.finite) (ht : t.finite) : (s ∪ t).finite :=
486486
by { casesI hs, casesI ht, apply to_finite }
487487

488+
theorem finite.finite_of_compl {s : set α} (hs : s.finite) (hsc : sᶜ.finite) : finite α :=
489+
by { rw [← finite_univ_iff, ← union_compl_self s], exact hs.union hsc }
490+
488491
lemma finite.sup {s t : set α} : s.finite → t.finite → (s ⊔ t).finite := finite.union
489492

490493
theorem finite.sep {s : set α} (hs : s.finite) (p : α → Prop) : {a ∈ s | p a}.finite :=

src/linear_algebra/affine_space/basis.lean

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,10 @@ protected lemma nonempty : nonempty ι :=
7272
not_is_empty_iff.mp $ λ hι,
7373
by simpa only [@range_eq_empty _ _ hι, affine_subspace.span_empty, bot_ne_top] using b.tot
7474

75+
/-- Composition of an affine basis and an equivalence of index types. -/
76+
def comp_equiv {ι'} (e : ι' ≃ ι) : affine_basis ι' k P :=
77+
⟨b.points ∘ e, b.ind.comp_embedding e.to_embedding, by { rw [e.surjective.range_comp], exact b.3 }⟩
78+
7579
/-- Given an affine basis for an affine space `P`, if we single out one member of the family, we
7680
obtain a linear basis for the model space `V`.
7781
@@ -371,29 +375,49 @@ include V
371375
protected lemma finite_dimensional [finite ι] (b : affine_basis ι k P) : finite_dimensional k V :=
372376
let ⟨i⟩ := b.nonempty in finite_dimensional.of_fintype_basis (b.basis_of i)
373377

374-
variables (k V P)
378+
protected lemma finite [finite_dimensional k V] (b : affine_basis ι k P) : finite ι :=
379+
finite_of_fin_dim_affine_independent k b.ind
380+
381+
protected lemma finite_set [finite_dimensional k V] {s : set ι} (b : affine_basis s k P) :
382+
s.finite :=
383+
finite_set_of_fin_dim_affine_independent k b.ind
384+
385+
@[simp] lemma coord_apply_centroid [char_zero k] (b : affine_basis ι k P) {s : finset ι} {i : ι}
386+
(hi : i ∈ s) :
387+
b.coord i (s.centroid k b.points) = (s.card : k) ⁻¹ :=
388+
by rw [finset.centroid, b.coord_apply_combination_of_mem hi
389+
(s.sum_centroid_weights_eq_one_of_nonempty _ ⟨i, hi⟩), finset.centroid_weights]
390+
391+
lemma card_eq_finrank_add_one [fintype ι] (b : affine_basis ι k P) :
392+
fintype.card ι = finite_dimensional.finrank k V + 1 :=
393+
begin
394+
haveI := b.finite_dimensional,
395+
exact b.ind.affine_span_eq_top_iff_card_eq_finrank_add_one.mp b.tot
396+
end
375397

376-
lemma exists_affine_basis : ∃ (s : set P), nonempty (affine_basis ↥s k P) :=
398+
lemma exists_affine_subbasis {t : set P} (ht : affine_span k t = ⊤) :
399+
∃ (s ⊆ t) (b : affine_basis ↥s k P), b.points = coe :=
377400
begin
378-
obtain ⟨s, -, h_tot, h_ind⟩ := exists_affine_independent k V (set.univ : set P),
379-
refine ⟨s, ⟨⟨(coe : s → P), h_ind, _⟩⟩,
380-
rw [subtype.range_coe, h_tot, affine_subspace.span_univ],
401+
obtain ⟨s, hst, h_tot, h_ind⟩ := exists_affine_independent k V t,
402+
refine ⟨s, hst, ⟨coe, h_ind, _⟩, rfl⟩,
403+
rw [subtype.range_coe, h_tot, ht]
381404
end
382405

406+
variables (k V P)
407+
408+
lemma exists_affine_basis : ∃ (s : set P) (b : affine_basis ↥s k P), b.points = coe :=
409+
let ⟨s, _, hs⟩ := exists_affine_subbasis (affine_subspace.span_univ k V P) in ⟨s, hs⟩
410+
383411
variables {k V P}
384412

385-
lemma exists_affine_basis_of_finite_dimensional {ι : Type*} [fintype ι] [finite_dimensional k V]
413+
lemma exists_affine_basis_of_finite_dimensional [fintype ι] [finite_dimensional k V]
386414
(h : fintype.card ι = finite_dimensional.finrank k V + 1) :
387415
nonempty (affine_basis ι k P) :=
388416
begin
389-
obtain ⟨s, ⟨⟨incl, h_ind, h_tot⟩⟩⟩ := affine_basis.exists_affine_basis k V P,
390-
haveI : fintype s := fintype_of_fin_dim_affine_independent k h_ind,
391-
have hs : fintype.card ι = fintype.card s,
392-
{ rw h, exact (h_ind.affine_span_eq_top_iff_card_eq_finrank_add_one.mp h_tot).symm, },
393-
rw ← affine_independent_equiv (fintype.equiv_of_card_eq hs) at h_ind,
394-
refine ⟨⟨_, h_ind, _⟩⟩,
395-
rw range_comp,
396-
simp [h_tot],
417+
obtain ⟨s, b, hb⟩ := affine_basis.exists_affine_basis k V P,
418+
lift s to finset P using b.finite_set,
419+
refine ⟨b.comp_equiv $ fintype.equiv_of_card_eq _⟩,
420+
rw [h, ← b.card_eq_finrank_add_one]
397421
end
398422

399423
end division_ring

src/linear_algebra/affine_space/finite_dimensional.lean

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,21 +68,22 @@ instance finite_dimensional_direction_affine_span_image_of_finite [_root_.finite
6868
finite_dimensional_direction_affine_span_of_finite k (set.to_finite _)
6969

7070
/-- An affine-independent family of points in a finite-dimensional affine space is finite. -/
71-
noncomputable def fintype_of_fin_dim_affine_independent [finite_dimensional k V]
72-
{p : ι → P} (hi : affine_independent k p) : fintype ι :=
73-
by classical; exact if hι : is_empty ι then (@fintype.of_is_empty _ hι) else
71+
lemma finite_of_fin_dim_affine_independent [finite_dimensional k V] {p : ι → P}
72+
(hi : affine_independent k p) : _root_.finite ι :=
7473
begin
75-
let q := (not_is_empty_iff.mp hι).some,
76-
rw affine_independent_iff_linear_independent_vsub k p q at hi,
74+
nontriviality ι, inhabit ι,
75+
rw affine_independent_iff_linear_independent_vsub k p default at hi,
7776
letI : is_noetherian k V := is_noetherian.iff_fg.2 infer_instance,
78-
exact fintype_of_fintype_ne _ (@fintype.of_finite _ hi.finite_of_is_noetherian),
77+
exact (set.finite_singleton default).finite_of_compl
78+
(set.finite_coe_iff.1 hi.finite_of_is_noetherian)
7979
end
8080

8181
/-- An affine-independent subset of a finite-dimensional affine space is finite. -/
82-
lemma finite_of_fin_dim_affine_independent [finite_dimensional k V]
83-
{s : set P} (hi : affine_independent k (coe : s → P)) : s.finite :=
84-
⟨fintype_of_fin_dim_affine_independent k hi
82+
lemma finite_set_of_fin_dim_affine_independent [finite_dimensional k V] {s : set ι} {f : s → P}
83+
(hi : affine_independent k f) : s.finite :=
84+
@set.to_finite _ s (finite_of_fin_dim_affine_independent k hi)
8585

86+
open_locale classical
8687
variables {k}
8788

8889
/-- The `vector_span` of a finite subset of an affinely independent

0 commit comments

Comments
 (0)