|
| 1 | +/- |
| 2 | +Copyright (c) 2025 Yaël Dillies, Strahinja Gvozdić, Bhavik Mehta. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Yaël Dillies, Strahinja Gvozdić, Bhavik Mehta |
| 5 | +-/ |
| 6 | +import Mathlib.Algebra.Group.Action.Pointwise.Finset |
| 7 | + |
| 8 | +/-! |
| 9 | +# Convolution |
| 10 | +
|
| 11 | +This file defines convolution of finite subsets `A` and `B` of group `G` as the map `A ⋆ B : G → ℕ` |
| 12 | +that maps `x ∈ G` to the number of distinct representations of `x` in the form `x = ab` for |
| 13 | +`a ∈ A`, `b ∈ B`. It is shown how convolution behaves under the change of order of `A` and `B`, as |
| 14 | +well as under the left and right actions on `A`, `B`, and the function argument. |
| 15 | +-/ |
| 16 | + |
| 17 | +open MulOpposite MulAction |
| 18 | +open scoped Pointwise RightActions |
| 19 | + |
| 20 | +namespace Finset |
| 21 | +variable {G : Type*} [Group G] [DecidableEq G] {A B : Finset G} {s x y : G} |
| 22 | + |
| 23 | +/-- Given finite subsets `A` and `B` of a group `G`, convolution of `A` and `B` is a map `G → ℕ` |
| 24 | +that maps `x ∈ G` to the number of distinct representations of `x` in the form `x = ab`, where |
| 25 | +`a ∈ A`, `b ∈ B`. -/ |
| 26 | +@[to_additive addConvolution /-- Given finite subsets `A` and `B` of an additive group `G`, |
| 27 | +convolution of `A` and `B` is a map `G → ℕ` that maps `x ∈ G` to the number of distinct |
| 28 | +representations of `x` in the form `x = a + b`, where `a ∈ A`, `b ∈ B`. -/] |
| 29 | +def convolution (A B : Finset G) : G → ℕ := fun x => #{ab ∈ A ×ˢ B | ab.1 * ab.2 = x} |
| 30 | + |
| 31 | +@[to_additive] |
| 32 | +lemma card_smul_inter_smul (A B : Finset G) (x y : G) : |
| 33 | + #((x • A) ∩ (y • B)) = A.convolution B⁻¹ (x⁻¹ * y) := |
| 34 | + card_nbij' (fun z ↦ (x⁻¹ * z, z⁻¹ * y)) (fun ab' ↦ x • ab'.1) |
| 35 | + (by simp +contextual [Set.MapsTo, Set.mem_smul_set_iff_inv_smul_mem, mul_assoc]) |
| 36 | + (by simp +contextual [Set.MapsTo, Set.mem_smul_set_iff_inv_smul_mem] |
| 37 | + simp +contextual [← eq_mul_inv_iff_mul_eq, mul_assoc]) |
| 38 | + (by simp [Set.LeftInvOn]) |
| 39 | + (by simp +contextual [Set.LeftInvOn, ← eq_mul_inv_iff_mul_eq, mul_assoc]) |
| 40 | + |
| 41 | +@[to_additive] |
| 42 | +lemma card_inter_smul (A B : Finset G) (x : G) : #(A ∩ (x • B)) = A.convolution B⁻¹ x := by |
| 43 | + simpa using card_smul_inter_smul _ _ 1 x |
| 44 | + |
| 45 | +@[to_additive] |
| 46 | +lemma card_smul_inter (A B : Finset G) (x : G) : #((x • A) ∩ B) = A.convolution B⁻¹ x⁻¹ := by |
| 47 | + simpa using card_smul_inter_smul _ _ x 1 |
| 48 | + |
| 49 | +@[to_additive card_add_neg_eq_addConvolution_neg] |
| 50 | +lemma card_mul_inv_eq_convolution_inv (A B : Finset G) (x : G) : |
| 51 | + #{ab ∈ A ×ˢ B | ab.1 * ab.2⁻¹ = x} = A.convolution B⁻¹ x := |
| 52 | + card_nbij' (fun ab => (ab.1, ab.2⁻¹)) (fun ab => (ab.1, ab.2⁻¹)) |
| 53 | + (by simp [Set.MapsTo]) (by simp [Set.MapsTo]) |
| 54 | + (by simp [Set.LeftInvOn]) (by simp [Set.LeftInvOn]) |
| 55 | + |
| 56 | +@[to_additive (attr := simp) addConvolution_pos] |
| 57 | +lemma convolution_pos : 0 < A.convolution B x ↔ x ∈ A * B := by |
| 58 | + aesop (add simp [convolution, Finset.Nonempty, mem_mul]) |
| 59 | + |
| 60 | +@[to_additive addConvolution_ne_zero] |
| 61 | +lemma convolution_ne_zero : A.convolution B x ≠ 0 ↔ x ∈ A * B := by |
| 62 | + suffices A.convolution B x ≠ 0 ↔ 0 < A.convolution B x by simp [this] |
| 63 | + omega |
| 64 | + |
| 65 | +@[to_additive (attr := simp) addConvolution_eq_zero] |
| 66 | +lemma convolution_eq_zero : A.convolution B x = 0 ↔ x ∉ A * B := by |
| 67 | + simp [← convolution_ne_zero] |
| 68 | + |
| 69 | +@[to_additive addConvolution_le_card_left] |
| 70 | +lemma convolution_le_card_left : A.convolution B x ≤ #A := by |
| 71 | + rw [← inv_inv B, ← card_inter_smul] |
| 72 | + exact card_le_card inter_subset_left |
| 73 | + |
| 74 | +@[to_additive addConvolution_le_card_right] |
| 75 | +lemma convolution_le_card_right : A.convolution B x ≤ #B := by |
| 76 | + rw [← inv_inv B, ← inv_inv x, ← card_smul_inter, card_inv] |
| 77 | + exact card_le_card inter_subset_right |
| 78 | + |
| 79 | +@[to_additive (attr := simp) addConvolution_neg] |
| 80 | +lemma convolution_inv (A B : Finset G) (x : G) : A.convolution B x⁻¹ = B⁻¹.convolution A⁻¹ x := by |
| 81 | + nth_rw 1 [← inv_inv B] |
| 82 | + rw [← card_smul_inter, ← card_inter_smul, inter_comm] |
| 83 | + |
| 84 | +@[to_additive (attr := simp) op_vadd_addConvolution_eq_addConvolution_vadd] |
| 85 | +lemma op_smul_convolution_eq_convolution_smul (A B : Finset G) (s : G) : |
| 86 | + (A <• s).convolution B = A.convolution (s • B) := funext fun x => by |
| 87 | + nth_rw 1 [← inv_inv B, ← inv_inv (s • B), inv_smul_finset_distrib s B, ← card_inter_smul, |
| 88 | + ← card_inter_smul, smul_comm] |
| 89 | + simp [← card_smul_finset (op s) (A ∩ _), smul_finset_inter] |
| 90 | + |
| 91 | +@[to_additive (attr := simp) vadd_addConvolution_eq_addConvolution_neg_add] |
| 92 | +lemma smul_convolution_eq_convolution_inv_mul (A B : Finset G) (s x : G) : |
| 93 | + (s •> A).convolution B x = A.convolution B (s⁻¹ * x) := by |
| 94 | + nth_rw 1 [← inv_inv x, ← inv_inv (s⁻¹ * x)] |
| 95 | + rw [← inv_inv B, ← card_smul_inter, ← card_smul_inter, mul_inv_rev, inv_inv, smul_smul] |
| 96 | + |
| 97 | +@[to_additive (attr := simp) addConvolution_op_vadd_eq_addConvolution_add_neg] |
| 98 | +lemma convolution_op_smul_eq_convolution_mul_inv (A B : Finset G) (s x : G) : |
| 99 | + A.convolution (B <• s) x = A.convolution B (x * s⁻¹) := by |
| 100 | + nth_rw 2 [← inv_inv B] |
| 101 | + rw [← inv_inv (B <• s), inv_op_smul_finset_distrib, ← card_inter_smul, ← card_inter_smul, |
| 102 | + smul_smul] |
| 103 | + |
| 104 | +end Finset |
0 commit comments