|
| 1 | +/- |
| 2 | +Copyright (c) 2020 Joseph Myers. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Joseph Myers |
| 5 | +-/ |
| 6 | +import Mathlib.LinearAlgebra.AffineSpace.Combination |
| 7 | + |
| 8 | +/-! |
| 9 | +# Centroid of a Finite Set of Points in Affine Space |
| 10 | +
|
| 11 | +This file defines the centroid of a finite set of points in an affine space over a division |
| 12 | +ring. |
| 13 | +
|
| 14 | +## Main definitions |
| 15 | +
|
| 16 | +* `centroidWeights`: A constant weight function assigning to each index in a `Finset` the same |
| 17 | + weight, equal to the reciprocal of the number of elements. |
| 18 | +
|
| 19 | +* `centroid`: the centroid of a `Finset` of points, defined as the affine combination using |
| 20 | + `centroidWeights`. |
| 21 | +
|
| 22 | +-/ |
| 23 | + |
| 24 | +assert_not_exists Affine.Simplex |
| 25 | + |
| 26 | +noncomputable section |
| 27 | + |
| 28 | +open Affine |
| 29 | + |
| 30 | +namespace Finset |
| 31 | + |
| 32 | +variable (k : Type*) {V : Type*} {P : Type*} [DivisionRing k] [AddCommGroup V] [Module k V] |
| 33 | +variable [AffineSpace V P] {ι : Type*} (s : Finset ι) {ι₂ : Type*} (s₂ : Finset ι₂) |
| 34 | + |
| 35 | +/-- The weights for the centroid of some points. -/ |
| 36 | +def centroidWeights : ι → k := |
| 37 | + Function.const ι (#s : k)⁻¹ |
| 38 | + |
| 39 | +/-- `centroidWeights` at any point. -/ |
| 40 | +@[simp] |
| 41 | +theorem centroidWeights_apply (i : ι) : s.centroidWeights k i = (#s : k)⁻¹ := |
| 42 | + rfl |
| 43 | + |
| 44 | +/-- `centroidWeights` equals a constant function. -/ |
| 45 | +theorem centroidWeights_eq_const : s.centroidWeights k = Function.const ι (#s : k)⁻¹ := |
| 46 | + rfl |
| 47 | + |
| 48 | +variable {k} in |
| 49 | +/-- The weights in the centroid sum to 1, if the number of points, |
| 50 | +converted to `k`, is not zero. -/ |
| 51 | +theorem sum_centroidWeights_eq_one_of_cast_card_ne_zero (h : (#s : k) ≠ 0) : |
| 52 | + ∑ i ∈ s, s.centroidWeights k i = 1 := by simp [h] |
| 53 | + |
| 54 | +/-- In the characteristic zero case, the weights in the centroid sum |
| 55 | +to 1 if the number of points is not zero. -/ |
| 56 | +theorem sum_centroidWeights_eq_one_of_card_ne_zero [CharZero k] (h : #s ≠ 0) : |
| 57 | + ∑ i ∈ s, s.centroidWeights k i = 1 := by |
| 58 | + simp_all |
| 59 | + |
| 60 | +/-- In the characteristic zero case, the weights in the centroid sum |
| 61 | +to 1 if the set is nonempty. -/ |
| 62 | +theorem sum_centroidWeights_eq_one_of_nonempty [CharZero k] (h : s.Nonempty) : |
| 63 | + ∑ i ∈ s, s.centroidWeights k i = 1 := |
| 64 | + s.sum_centroidWeights_eq_one_of_card_ne_zero k (ne_of_gt (card_pos.2 h)) |
| 65 | + |
| 66 | +/-- In the characteristic zero case, the weights in the centroid sum |
| 67 | +to 1 if the number of points is `n + 1`. -/ |
| 68 | +theorem sum_centroidWeights_eq_one_of_card_eq_add_one [CharZero k] {n : ℕ} (h : #s = n + 1) : |
| 69 | + ∑ i ∈ s, s.centroidWeights k i = 1 := |
| 70 | + s.sum_centroidWeights_eq_one_of_card_ne_zero k (h.symm ▸ Nat.succ_ne_zero n) |
| 71 | + |
| 72 | +/-- The centroid of some points. Although defined for any `s`, this |
| 73 | +is intended to be used in the case where the number of points, |
| 74 | +converted to `k`, is not zero. -/ |
| 75 | +def centroid (p : ι → P) : P := |
| 76 | + s.affineCombination k p (s.centroidWeights k) |
| 77 | + |
| 78 | +/-- The definition of the centroid. -/ |
| 79 | +theorem centroid_def (p : ι → P) : s.centroid k p = s.affineCombination k p (s.centroidWeights k) := |
| 80 | + rfl |
| 81 | + |
| 82 | +theorem centroid_univ (s : Finset P) : univ.centroid k ((↑) : s → P) = s.centroid k id := by |
| 83 | + rw [centroid, centroid, ← s.attach_affineCombination_coe] |
| 84 | + congr |
| 85 | + ext |
| 86 | + simp |
| 87 | + |
| 88 | +/-- The centroid of a single point. -/ |
| 89 | +@[simp] |
| 90 | +theorem centroid_singleton (p : ι → P) (i : ι) : ({i} : Finset ι).centroid k p = p i := by |
| 91 | + simp [centroid_def, affineCombination_apply] |
| 92 | + |
| 93 | +/-- The centroid of two points, expressed directly as adding a vector |
| 94 | +to a point. -/ |
| 95 | +theorem centroid_pair [DecidableEq ι] [Invertible (2 : k)] (p : ι → P) (i₁ i₂ : ι) : |
| 96 | + ({i₁, i₂} : Finset ι).centroid k p = (2⁻¹ : k) • (p i₂ -ᵥ p i₁) +ᵥ p i₁ := by |
| 97 | + by_cases h : i₁ = i₂ |
| 98 | + · simp [h] |
| 99 | + · have hc : (#{i₁, i₂} : k) ≠ 0 := by |
| 100 | + rw [card_insert_of_notMem (notMem_singleton.2 h), card_singleton] |
| 101 | + norm_num |
| 102 | + exact Invertible.ne_zero _ |
| 103 | + rw [centroid_def, |
| 104 | + affineCombination_eq_weightedVSubOfPoint_vadd_of_sum_eq_one _ _ _ |
| 105 | + (sum_centroidWeights_eq_one_of_cast_card_ne_zero _ hc) (p i₁)] |
| 106 | + simp [h, one_add_one_eq_two] |
| 107 | + |
| 108 | +/-- The centroid of two points indexed by `Fin 2`, expressed directly |
| 109 | +as adding a vector to the first point. -/ |
| 110 | +theorem centroid_pair_fin [Invertible (2 : k)] (p : Fin 2 → P) : |
| 111 | + univ.centroid k p = (2⁻¹ : k) • (p 1 -ᵥ p 0) +ᵥ p 0 := by |
| 112 | + rw [univ_fin2] |
| 113 | + convert centroid_pair k p 0 1 |
| 114 | + |
| 115 | +/-- A centroid, over the image of an embedding, equals a centroid with |
| 116 | +the same points and weights over the original `Finset`. -/ |
| 117 | +theorem centroid_map (e : ι₂ ↪ ι) (p : ι → P) : |
| 118 | + (s₂.map e).centroid k p = s₂.centroid k (p ∘ e) := by |
| 119 | + simp [centroid_def, affineCombination_map, centroidWeights] |
| 120 | + |
| 121 | +/-- `centroidWeights` gives the weights for the centroid as a |
| 122 | +constant function, which is suitable when summing over the points |
| 123 | +whose centroid is being taken. This function gives the weights in a |
| 124 | +form suitable for summing over a larger set of points, as an indicator |
| 125 | +function that is zero outside the set whose centroid is being taken. |
| 126 | +In the case of a `Fintype`, the sum may be over `univ`. -/ |
| 127 | +def centroidWeightsIndicator : ι → k := |
| 128 | + Set.indicator (↑s) (s.centroidWeights k) |
| 129 | + |
| 130 | +/-- The definition of `centroidWeightsIndicator`. -/ |
| 131 | +theorem centroidWeightsIndicator_def : |
| 132 | + s.centroidWeightsIndicator k = Set.indicator (↑s) (s.centroidWeights k) := |
| 133 | + rfl |
| 134 | + |
| 135 | +/-- The sum of the weights for the centroid indexed by a `Fintype`. -/ |
| 136 | +theorem sum_centroidWeightsIndicator [Fintype ι] : |
| 137 | + ∑ i, s.centroidWeightsIndicator k i = ∑ i ∈ s, s.centroidWeights k i := |
| 138 | + sum_indicator_subset _ (subset_univ _) |
| 139 | + |
| 140 | +/-- In the characteristic zero case, the weights in the centroid |
| 141 | +indexed by a `Fintype` sum to 1 if the number of points is not |
| 142 | +zero. -/ |
| 143 | +theorem sum_centroidWeightsIndicator_eq_one_of_card_ne_zero [CharZero k] [Fintype ι] |
| 144 | + (h : #s ≠ 0) : ∑ i, s.centroidWeightsIndicator k i = 1 := by |
| 145 | + rw [sum_centroidWeightsIndicator] |
| 146 | + exact s.sum_centroidWeights_eq_one_of_card_ne_zero k h |
| 147 | + |
| 148 | +/-- In the characteristic zero case, the weights in the centroid |
| 149 | +indexed by a `Fintype` sum to 1 if the set is nonempty. -/ |
| 150 | +theorem sum_centroidWeightsIndicator_eq_one_of_nonempty [CharZero k] [Fintype ι] (h : s.Nonempty) : |
| 151 | + ∑ i, s.centroidWeightsIndicator k i = 1 := by |
| 152 | + rw [sum_centroidWeightsIndicator] |
| 153 | + exact s.sum_centroidWeights_eq_one_of_nonempty k h |
| 154 | + |
| 155 | +/-- In the characteristic zero case, the weights in the centroid |
| 156 | +indexed by a `Fintype` sum to 1 if the number of points is `n + 1`. -/ |
| 157 | +theorem sum_centroidWeightsIndicator_eq_one_of_card_eq_add_one [CharZero k] [Fintype ι] {n : ℕ} |
| 158 | + (h : #s = n + 1) : ∑ i, s.centroidWeightsIndicator k i = 1 := by |
| 159 | + rw [sum_centroidWeightsIndicator] |
| 160 | + exact s.sum_centroidWeights_eq_one_of_card_eq_add_one k h |
| 161 | + |
| 162 | +/-- The centroid as an affine combination over a `Fintype`. -/ |
| 163 | +theorem centroid_eq_affineCombination_fintype [Fintype ι] (p : ι → P) : |
| 164 | + s.centroid k p = univ.affineCombination k p (s.centroidWeightsIndicator k) := |
| 165 | + affineCombination_indicator_subset _ _ (subset_univ _) |
| 166 | + |
| 167 | +/-- An indexed family of points that is injective on the given |
| 168 | +`Finset` has the same centroid as the image of that `Finset`. This is |
| 169 | +stated in terms of a set equal to the image to provide control of |
| 170 | +definitional equality for the index type used for the centroid of the |
| 171 | +image. -/ |
| 172 | +theorem centroid_eq_centroid_image_of_inj_on {p : ι → P} |
| 173 | + (hi : ∀ i ∈ s, ∀ j ∈ s, p i = p j → i = j) {ps : Set P} [Fintype ps] |
| 174 | + (hps : ps = p '' ↑s) : s.centroid k p = (univ : Finset ps).centroid k fun x => (x : P) := by |
| 175 | + let f : p '' ↑s → ι := fun x => x.property.choose |
| 176 | + have hf : ∀ x, f x ∈ s ∧ p (f x) = x := fun x => x.property.choose_spec |
| 177 | + let f' : ps → ι := fun x => f ⟨x, hps ▸ x.property⟩ |
| 178 | + have hf' : ∀ x, f' x ∈ s ∧ p (f' x) = x := fun x => hf ⟨x, hps ▸ x.property⟩ |
| 179 | + have hf'i : Function.Injective f' := by |
| 180 | + intro x y h |
| 181 | + rw [Subtype.ext_iff, ← (hf' x).2, ← (hf' y).2, h] |
| 182 | + let f'e : ps ↪ ι := ⟨f', hf'i⟩ |
| 183 | + have hu : Finset.univ.map f'e = s := by |
| 184 | + ext x |
| 185 | + rw [mem_map] |
| 186 | + constructor |
| 187 | + · rintro ⟨i, _, rfl⟩ |
| 188 | + exact (hf' i).1 |
| 189 | + · intro hx |
| 190 | + use ⟨p x, hps.symm ▸ Set.mem_image_of_mem _ hx⟩, mem_univ _ |
| 191 | + refine hi _ (hf' _).1 _ hx ?_ |
| 192 | + rw [(hf' _).2] |
| 193 | + rw [← hu, centroid_map] |
| 194 | + congr with x |
| 195 | + change p (f' x) = ↑x |
| 196 | + rw [(hf' x).2] |
| 197 | + |
| 198 | +/-- Two indexed families of points that are injective on the given |
| 199 | +`Finset`s and with the same points in the image of those `Finset`s |
| 200 | +have the same centroid. -/ |
| 201 | +theorem centroid_eq_of_inj_on_of_image_eq {p : ι → P} |
| 202 | + (hi : ∀ i ∈ s, ∀ j ∈ s, p i = p j → i = j) {p₂ : ι₂ → P} |
| 203 | + (hi₂ : ∀ i ∈ s₂, ∀ j ∈ s₂, p₂ i = p₂ j → i = j) (he : p '' ↑s = p₂ '' ↑s₂) : |
| 204 | + s.centroid k p = s₂.centroid k p₂ := by |
| 205 | + classical rw [s.centroid_eq_centroid_image_of_inj_on k hi rfl, |
| 206 | + s₂.centroid_eq_centroid_image_of_inj_on k hi₂ he] |
| 207 | + |
| 208 | +end Finset |
| 209 | + |
| 210 | +section DivisionRing |
| 211 | + |
| 212 | +variable {k : Type*} {V : Type*} {P : Type*} [DivisionRing k] [AddCommGroup V] [Module k V] |
| 213 | +variable [AffineSpace V P] {ι : Type*} |
| 214 | + |
| 215 | +open Set Finset |
| 216 | + |
| 217 | +/-- The centroid lies in the affine span if the number of points, |
| 218 | +converted to `k`, is not zero. -/ |
| 219 | +theorem centroid_mem_affineSpan_of_cast_card_ne_zero {s : Finset ι} (p : ι → P) |
| 220 | + (h : (#s : k) ≠ 0) : s.centroid k p ∈ affineSpan k (range p) := |
| 221 | + affineCombination_mem_affineSpan (s.sum_centroidWeights_eq_one_of_cast_card_ne_zero h) p |
| 222 | + |
| 223 | +variable (k) |
| 224 | + |
| 225 | +/-- In the characteristic zero case, the centroid lies in the affine |
| 226 | +span if the number of points is not zero. -/ |
| 227 | +theorem centroid_mem_affineSpan_of_card_ne_zero [CharZero k] {s : Finset ι} (p : ι → P) |
| 228 | + (h : #s ≠ 0) : s.centroid k p ∈ affineSpan k (range p) := |
| 229 | + affineCombination_mem_affineSpan (s.sum_centroidWeights_eq_one_of_card_ne_zero k h) p |
| 230 | + |
| 231 | +/-- In the characteristic zero case, the centroid lies in the affine |
| 232 | +span if the set is nonempty. -/ |
| 233 | +theorem centroid_mem_affineSpan_of_nonempty [CharZero k] {s : Finset ι} (p : ι → P) |
| 234 | + (h : s.Nonempty) : s.centroid k p ∈ affineSpan k (range p) := |
| 235 | + affineCombination_mem_affineSpan (s.sum_centroidWeights_eq_one_of_nonempty k h) p |
| 236 | + |
| 237 | +/-- In the characteristic zero case, the centroid lies in the affine |
| 238 | +span if the number of points is `n + 1`. -/ |
| 239 | +theorem centroid_mem_affineSpan_of_card_eq_add_one [CharZero k] {s : Finset ι} (p : ι → P) {n : ℕ} |
| 240 | + (h : #s = n + 1) : s.centroid k p ∈ affineSpan k (range p) := |
| 241 | + affineCombination_mem_affineSpan (s.sum_centroidWeights_eq_one_of_card_eq_add_one k h) p |
| 242 | + |
| 243 | +end DivisionRing |
0 commit comments