-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Expand file tree
/
Copy pathIndicator.lean
More file actions
237 lines (183 loc) · 9.17 KB
/
Copy pathIndicator.lean
File metadata and controls
237 lines (183 loc) · 9.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
/-
Copyright (c) 2020 Zhouhang Zhou. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Zhouhang Zhou
-/
module
public import Mathlib.Algebra.Group.Basic
public import Mathlib.Algebra.Group.Hom.Defs
public import Mathlib.Algebra.Group.Pi.Basic
public import Mathlib.Algebra.Notation.Indicator
/-!
# Indicator function
In this file, we prove basic results about the indicator of a set.
- `Set.indicator (s : Set α) (f : α → β) (a : α)` is `f a` if `a ∈ s` and is `0` otherwise.
- `Set.mulIndicator (s : Set α) (f : α → β) (a : α)` is `f a` if `a ∈ s` and is `1` otherwise.
## Implementation note
In mathematics, an indicator function or a characteristic function is a function
used to indicate membership of an element in a set `s`,
having the value `1` for all elements of `s` and the value `0` otherwise.
But since it is usually used to restrict a function to a certain set `s`,
we let the indicator function take the value `f x` for some function `f`, instead of `1`.
If the usual indicator function is needed, just set `f` to be the constant function `fun _ ↦ 1`.
The indicator function is implemented non-computably, to avoid having to pass around `Decidable`
arguments. This is in contrast with the design of `Pi.single` or `Set.piecewise`.
## Tags
indicator, characteristic
-/
@[expose] public section
assert_not_exists MonoidWithZero
open Function
variable {α β γ M N : Type*}
namespace Set
section Monoid
variable [MulOneClass M] {s t : Set α} {a : α}
@[to_additive]
theorem mulIndicator_union_mul_inter_apply (f : α → M) (s t : Set α) (a : α) :
mulIndicator (s ∪ t) f a * mulIndicator (s ∩ t) f a
= mulIndicator s f a * mulIndicator t f a := by
by_cases hs : a ∈ s <;> by_cases ht : a ∈ t <;> simp [*]
@[to_additive]
theorem mulIndicator_union_mul_inter (f : α → M) (s t : Set α) :
mulIndicator (s ∪ t) f * mulIndicator (s ∩ t) f = mulIndicator s f * mulIndicator t f :=
funext <| mulIndicator_union_mul_inter_apply f s t
@[to_additive]
theorem mulIndicator_union_of_notMem_inter (h : a ∉ s ∩ t) (f : α → M) :
mulIndicator (s ∪ t) f a = mulIndicator s f a * mulIndicator t f a := by
rw [← mulIndicator_union_mul_inter_apply f s t, mulIndicator_of_notMem h, mul_one]
@[to_additive]
theorem mulIndicator_union_of_disjoint (h : Disjoint s t) (f : α → M) :
mulIndicator (s ∪ t) f = fun a => mulIndicator s f a * mulIndicator t f a :=
funext fun _ => mulIndicator_union_of_notMem_inter (fun ha => h.le_bot ha) _
open scoped symmDiff in
@[to_additive]
theorem mulIndicator_symmDiff (s t : Set α) (f : α → M) :
mulIndicator (s ∆ t) f = mulIndicator (s \ t) f * mulIndicator (t \ s) f :=
mulIndicator_union_of_disjoint (disjoint_sdiff_self_right.mono_left sdiff_le) _
@[to_additive]
theorem mulIndicator_mul (s : Set α) (f g : α → M) :
(mulIndicator s fun a => f a * g a) = fun a => mulIndicator s f a * mulIndicator s g a := by
funext
simp only [mulIndicator]
split_ifs
· rfl
rw [mul_one]
@[to_additive]
theorem mulIndicator_mul' (s : Set α) (f g : α → M) :
mulIndicator s (f * g) = mulIndicator s f * mulIndicator s g :=
mulIndicator_mul s f g
@[to_additive (attr := simp)]
theorem mulIndicator_compl_mul_self_apply (s : Set α) (f : α → M) (a : α) :
mulIndicator sᶜ f a * mulIndicator s f a = f a :=
by_cases (fun ha : a ∈ s => by simp [ha]) fun ha => by simp [ha]
@[to_additive (attr := simp)]
theorem mulIndicator_compl_mul_self (s : Set α) (f : α → M) :
mulIndicator sᶜ f * mulIndicator s f = f :=
funext <| mulIndicator_compl_mul_self_apply s f
@[to_additive (attr := simp)]
theorem mulIndicator_self_mul_compl_apply (s : Set α) (f : α → M) (a : α) :
mulIndicator s f a * mulIndicator sᶜ f a = f a :=
by_cases (fun ha : a ∈ s => by simp [ha]) fun ha => by simp [ha]
@[to_additive (attr := simp)]
theorem mulIndicator_self_mul_compl (s : Set α) (f : α → M) :
mulIndicator s f * mulIndicator sᶜ f = f :=
funext <| mulIndicator_self_mul_compl_apply s f
@[to_additive]
theorem mulIndicator_mul_eq_left {f g : α → M} (h : Disjoint (mulSupport f) (mulSupport g)) :
(mulSupport f).mulIndicator (f * g) = f := by
refine (mulIndicator_congr fun x hx => ?_).trans mulIndicator_mulSupport
have : g x = 1 := notMem_mulSupport.1 (disjoint_left.1 h hx)
rw [Pi.mul_apply, this, mul_one]
@[to_additive]
theorem mulIndicator_mul_eq_right {f g : α → M} (h : Disjoint (mulSupport f) (mulSupport g)) :
(mulSupport g).mulIndicator (f * g) = g := by
refine (mulIndicator_congr fun x hx => ?_).trans mulIndicator_mulSupport
have : f x = 1 := notMem_mulSupport.1 (disjoint_right.1 h hx)
rw [Pi.mul_apply, this, one_mul]
@[to_additive]
theorem mulIndicator_mul_compl_eq_piecewise [DecidablePred (· ∈ s)] (f g : α → M) :
s.mulIndicator f * sᶜ.mulIndicator g = s.piecewise f g := by
ext x
by_cases h : x ∈ s
· rw [piecewise_eq_of_mem _ _ _ h, Pi.mul_apply, Set.mulIndicator_of_mem h,
Set.mulIndicator_of_notMem (Set.notMem_compl_iff.2 h), mul_one]
· rw [piecewise_eq_of_notMem _ _ _ h, Pi.mul_apply, Set.mulIndicator_of_notMem h,
Set.mulIndicator_of_mem (Set.mem_compl h), one_mul]
/-- `Set.mulIndicator` as a `monoidHom`. -/
@[to_additive /-- `Set.indicator` as an `addMonoidHom`. -/]
noncomputable def mulIndicatorHom {α} (M) [MulOneClass M] (s : Set α) : (α → M) →* α → M where
toFun := mulIndicator s
map_one' := mulIndicator_one M s
map_mul' := mulIndicator_mul s
end Monoid
section Group
variable {G : Type*} [Group G] {s t : Set α}
@[to_additive]
theorem mulIndicator_inv' (s : Set α) (f : α → G) : mulIndicator s f⁻¹ = (mulIndicator s f)⁻¹ :=
(mulIndicatorHom G s).map_inv f
@[to_additive]
theorem mulIndicator_inv (s : Set α) (f : α → G) :
(mulIndicator s fun a => (f a)⁻¹) = fun a => (mulIndicator s f a)⁻¹ :=
mulIndicator_inv' s f
@[to_additive]
theorem mulIndicator_div (s : Set α) (f g : α → G) :
(mulIndicator s fun a => f a / g a) = fun a => mulIndicator s f a / mulIndicator s g a :=
(mulIndicatorHom G s).map_div f g
@[to_additive]
theorem mulIndicator_div' (s : Set α) (f g : α → G) :
mulIndicator s (f / g) = mulIndicator s f / mulIndicator s g :=
mulIndicator_div s f g
@[to_additive indicator_compl']
theorem mulIndicator_compl (s : Set α) (f : α → G) :
mulIndicator sᶜ f = f * (mulIndicator s f)⁻¹ :=
eq_mul_inv_of_mul_eq <| s.mulIndicator_compl_mul_self f
@[to_additive indicator_compl]
theorem mulIndicator_compl' (s : Set α) (f : α → G) :
mulIndicator sᶜ f = f / mulIndicator s f := by rw [div_eq_mul_inv, mulIndicator_compl]
@[to_additive indicator_sdiff']
theorem mulIndicator_sdiff (h : s ⊆ t) (f : α → G) :
mulIndicator (t \ s) f = mulIndicator t f * (mulIndicator s f)⁻¹ :=
eq_mul_inv_of_mul_eq <| by
rw [Pi.mul_def, ← mulIndicator_union_of_disjoint, sdiff_union_self,
union_eq_self_of_subset_right h]
exact disjoint_sdiff_self_left
@[deprecated (since := "2026-06-03")] alias mulIndicator_diff := mulIndicator_sdiff
@[to_additive indicator_sdiff]
theorem mulIndicator_sdiff' (h : s ⊆ t) (f : α → G) :
mulIndicator (t \ s) f = mulIndicator t f / mulIndicator s f := by
rw [mulIndicator_sdiff h, div_eq_mul_inv]
@[deprecated (since := "2026-06-03")] alias mulIndicator_diff' := mulIndicator_sdiff'
open scoped symmDiff in
@[to_additive]
theorem apply_mulIndicator_symmDiff {g : G → β} (hg : ∀ x, g x⁻¹ = g x)
(s t : Set α) (f : α → G) (x : α) :
g (mulIndicator (s ∆ t) f x) = g (mulIndicator s f x / mulIndicator t f x) := by
by_cases hs : x ∈ s <;> by_cases ht : x ∈ t <;> simp [mem_symmDiff, *]
end Group
section One
@[to_additive]
lemma mulSupport_subset_subsingleton_of_disjoint_on_mulSupport [One β] {s : γ → Set α} (f : α → β)
(hs : Pairwise (Disjoint on (fun j ↦ s j ∩ f.mulSupport))) (i : α) (j : γ) (hj : i ∈ s j) :
(fun d ↦ (s d).mulIndicator f i).mulSupport ⊆ {j} := by
suffices ∀ j', j' ≠ j → {i} ⊆ s j → {i} ⊆ s j' → {i} ⊆ mulSupport f → False by by_contra; aesop
intro j' h hj hj' hi
simp only [Pairwise, Disjoint, Set.subset_inter_iff] at hs
simpa using hs h ⟨hj', hi⟩ ⟨hj, hi⟩
end One
/-! ### Relationship with `Pi.mulSingle`/`Pi.single` -/
variable {ι : Type*} [DecidableEq ι] {M : Type*} [One M]
/-- On non-dependent functions, `Set.mulIndicator` on a singleton set equals `Pi.mulSingle`. -/
@[to_additive (attr := simp)
/-- On non-dependent functions, `Set.indicator` on a singleton set equals `Pi.single`. -/]
theorem mulIndicator_singleton (i : ι) (f : ι → M) :
Set.mulIndicator {i} f = Pi.mulSingle i (f i) := by
ext j
simp only [Set.mulIndicator_apply, Pi.mulSingle_apply, Set.mem_singleton_iff]
split_ifs with h <;> simp [h]
end Set
@[to_additive]
theorem map_mulIndicator {M N F : Type*} [One M] [One N] [FunLike F M N] [OneHomClass F M N] (f : F)
(s : Set α) (g : α → M) (x : α) : f (s.mulIndicator g x) = s.mulIndicator (f ∘ g) x := by
simp [Set.mulIndicator_comp_of_one]
@[deprecated (since := "2025-12-08")] alias MonoidHom.map_mulIndicator := map_mulIndicator
@[deprecated (since := "2025-12-08")] alias AddMonoidHom.map_indicator := map_indicator