Skip to content

Commit e310d5e

Browse files
committed
chore: split ContinuousLinearMap.IsInvertible to its own file (#42697)
The original file is getting way too big, and this makes complete sense as an independent file imo.
1 parent 5b8fb9a commit e310d5e

6 files changed

Lines changed: 268 additions & 242 deletions

File tree

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7691,6 +7691,7 @@ public import Mathlib.Topology.Algebra.Module.Compact
76917691
public import Mathlib.Topology.Algebra.Module.Complement
76927692
public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.Basic
76937693
public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.Idempotent
7694+
public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.Invertible
76947695
public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.PiProd
76957696
public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.Positive
76967697
public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.Quotient

Mathlib/Analysis/Calculus/FDeriv/Const.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Authors: Jeremy Avigad, Sébastien Gouëzel, Yury Kudryashov
66
module
77

88
public import Mathlib.Analysis.Calculus.FDeriv.Congr
9+
public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.Invertible
910

1011
/-!
1112
# Fréchet derivative of constant functions

Mathlib/Analysis/Normed/Module/ContinuousInverse.lean

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ Authors: Michael Rothgang
66
module
77

88
public import Mathlib.Analysis.Normed.Operator.Banach
9-
public import Mathlib.Topology.Algebra.Module.FiniteDimension
109
public import Mathlib.Topology.Algebra.Module.Complement
10+
public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.Invertible
11+
public import Mathlib.Topology.Algebra.Module.FiniteDimension
1112

1213
/-! # Continuous linear maps with a continuous left/right inverse
1314

Mathlib/Analysis/Normed/Operator/Fredholm/Basic.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Authors: Jon Bannon, Anatole Dedecker, Yongxi Lin, Patrick Massot, Oliver Nash,
66
module
77

88
public import Mathlib.Analysis.Normed.Operator.Perturbation.StrictByFinite
9+
public import Mathlib.Topology.Algebra.Module.ContinuousLinearMap.Invertible
910

1011
/-!
1112
# Fredholm operators between topological vector spaces
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
/-
2+
Copyright (c) 2024 Sébastien Gouëzel. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Sébastien Gouëzel
5+
-/
6+
module
7+
8+
public import Mathlib.Topology.Algebra.Module.Equiv
9+
10+
/-!
11+
# Invertibility of continuous linear maps
12+
13+
In this file, we define the predicate `ContinuousLinearMap.IsInvertible`, expressing that a given
14+
continuous (semi)linear map is the forward direction of a `ContinuousLinearEquiv` (in other words,
15+
it has a continuous inverse).
16+
-/
17+
18+
@[expose] public section
19+
20+
open scoped Ring
21+
22+
namespace ContinuousLinearMap
23+
24+
variable {R : Type*} {M M₂ M₃ : Type*}
25+
[TopologicalSpace M] [TopologicalSpace M₂] [TopologicalSpace M₃]
26+
27+
variable [Semiring R]
28+
[AddCommMonoid M] [Module R M]
29+
[AddCommMonoid M₂] [Module R M₂]
30+
[AddCommMonoid M₃] [Module R M₃]
31+
32+
/-- A continuous linear map is invertible if it is the forward direction of a continuous linear
33+
equivalence. -/
34+
def IsInvertible (f : M →L[R] M₂) : Prop :=
35+
∃ (A : M ≃L[R] M₂), A = f
36+
37+
open scoped Classical in
38+
/-- Introduce a function `inverse` from `M →L[R] M₂` to `M₂ →L[R] M`, which sends `f` to `f.symm` if
39+
`f` is a continuous linear equivalence and to `0` otherwise. This definition is somewhat ad hoc,
40+
but one needs a fully (rather than partially) defined inverse function for some purposes, including
41+
for calculus. -/
42+
noncomputable def inverse : (M →L[R] M₂) → M₂ →L[R] M := fun f =>
43+
if h : f.IsInvertible then ((Classical.choose h).symm : M₂ →L[R] M) else 0
44+
45+
@[simp] lemma isInvertible_equiv {f : M ≃L[R] M₂} : IsInvertible (f : M →L[R] M₂) := ⟨f, rfl⟩
46+
47+
/-- By definition, if `f` is invertible then `inverse f = f.symm`. -/
48+
@[simp]
49+
theorem inverse_equiv (e : M ≃L[R] M₂) : inverse (e : M →L[R] M₂) = e.symm := by
50+
simp [inverse]
51+
52+
/-- By definition, if `f` is not invertible then `inverse f = 0`. -/
53+
@[simp] lemma inverse_of_not_isInvertible
54+
{f : M →L[R] M₂} (hf : ¬ f.IsInvertible) : f.inverse = 0 :=
55+
dite_eq_right hf
56+
57+
@[simp]
58+
theorem isInvertible_zero_iff :
59+
IsInvertible (0 : M →L[R] M₂) ↔ Subsingleton M ∧ Subsingleton M₂ := by
60+
refine ⟨fun ⟨e, he⟩ ↦ ?_, ?_⟩
61+
· have A : Subsingleton M := by
62+
refine ⟨fun x y ↦ e.injective ?_⟩
63+
simp [he, ← ContinuousLinearEquiv.coe_coe]
64+
exact ⟨A, e.toEquiv.symm.subsingleton⟩
65+
· rintro ⟨hM, hM₂⟩
66+
let e : M ≃L[R] M₂ :=
67+
{ toFun := 0
68+
invFun := 0
69+
left_inv x := Subsingleton.elim _ _
70+
right_inv x := Subsingleton.elim _ _
71+
map_add' x y := Subsingleton.elim _ _
72+
map_smul' c x := Subsingleton.elim _ _ }
73+
refine ⟨e, ?_⟩
74+
ext x
75+
exact Subsingleton.elim _ _
76+
77+
@[simp] theorem inverse_zero : inverse (0 : M →L[R] M₂) = 0 := by
78+
by_cases h : IsInvertible (0 : M →L[R] M₂)
79+
· rcases isInvertible_zero_iff.1 h with ⟨hM, hM₂⟩
80+
ext x
81+
exact Subsingleton.elim _ _
82+
· exact inverse_of_not_isInvertible h
83+
84+
lemma IsInvertible.comp {g : M₂ →L[R] M₃} {f : M →L[R] M₂}
85+
(hg : g.IsInvertible) (hf : f.IsInvertible) : (g ∘L f).IsInvertible := by
86+
rcases hg with ⟨N, rfl⟩
87+
rcases hf with ⟨M, rfl⟩
88+
exact ⟨M.trans N, rfl⟩
89+
90+
lemma IsInvertible.of_inverse {f : M →L[R] M₂} {g : M₂ →L[R] M}
91+
(hf : f ∘L g = .id R M₂) (hg : g ∘L f = .id R M) :
92+
f.IsInvertible :=
93+
⟨ContinuousLinearEquiv.equivOfInverse' _ _ hf hg, rfl⟩
94+
95+
lemma inverse_eq {f : M →L[R] M₂} {g : M₂ →L[R] M}
96+
(hf : f ∘L g = .id R M₂) (hg : g ∘L f = .id R M) :
97+
f.inverse = g := by
98+
have : f = ContinuousLinearEquiv.equivOfInverse' f g hf hg := rfl
99+
rw [this, inverse_equiv]
100+
rfl
101+
102+
lemma IsInvertible.inverse_apply_eq {f : M →L[R] M₂} {x : M} {y : M₂} (hf : f.IsInvertible) :
103+
f.inverse y = x ↔ y = f x := by
104+
rcases hf with ⟨M, rfl⟩
105+
simp only [inverse_equiv, ContinuousLinearEquiv.coe_coe]
106+
exact ContinuousLinearEquiv.symm_apply_eq M
107+
108+
@[simp] lemma isInvertible_equiv_comp {e : M₂ ≃L[R] M₃} {f : M →L[R] M₂} :
109+
((e : M₂ →L[R] M₃) ∘L f).IsInvertible ↔ f.IsInvertible := by
110+
constructor
111+
· rintro ⟨A, hA⟩
112+
have : f = e.symm ∘L ((e : M₂ →L[R] M₃) ∘L f) := by ext; simp
113+
rw [this, ← hA]
114+
simp
115+
· rintro ⟨M, rfl⟩
116+
simp
117+
118+
@[simp] lemma isInvertible_comp_equiv {e : M₃ ≃L[R] M} {f : M →L[R] M₂} :
119+
(f ∘L (e : M₃ →L[R] M)).IsInvertible ↔ f.IsInvertible := by
120+
constructor
121+
· rintro ⟨A, hA⟩
122+
have : f = (f ∘L (e : M₃ →L[R] M)) ∘L e.symm := by ext; simp
123+
rw [this, ← hA]
124+
simp
125+
· rintro ⟨M, rfl⟩
126+
simp
127+
128+
@[simp] lemma inverse_equiv_comp {e : M₂ ≃L[R] M₃} {f : M →L[R] M₂} :
129+
(e ∘L f).inverse = f.inverse ∘L (e.symm : M₃ →L[R] M₂) := by
130+
by_cases hf : f.IsInvertible
131+
· rcases hf with ⟨A, rfl⟩
132+
simp only [ContinuousLinearEquiv.comp_coe, inverse_equiv, ContinuousLinearEquiv.coe_inj]
133+
rfl
134+
· rw [inverse_of_not_isInvertible (by simp [hf]), inverse_of_not_isInvertible hf, zero_comp]
135+
136+
@[simp] lemma inverse_comp_equiv {e : M₃ ≃L[R] M} {f : M →L[R] M₂} :
137+
(f ∘L e).inverse = (e.symm : M →L[R] M₃) ∘L f.inverse := by
138+
by_cases hf : f.IsInvertible
139+
· rcases hf with ⟨A, rfl⟩
140+
simp only [ContinuousLinearEquiv.comp_coe, inverse_equiv, ContinuousLinearEquiv.coe_inj]
141+
rfl
142+
· rw [inverse_of_not_isInvertible (by simp [hf]), inverse_of_not_isInvertible hf, comp_zero]
143+
144+
lemma IsInvertible.inverse_comp_of_left {g : M₂ →L[R] M₃} {f : M →L[R] M₂}
145+
(hg : g.IsInvertible) : (g ∘L f).inverse = f.inverse ∘L g.inverse := by
146+
rcases hg with ⟨N, rfl⟩
147+
simp
148+
149+
lemma IsInvertible.inverse_comp_apply_of_left {g : M₂ →L[R] M₃} {f : M →L[R] M₂} {v : M₃}
150+
(hg : g.IsInvertible) : (g ∘L f).inverse v = f.inverse (g.inverse v) := by
151+
simp only [hg.inverse_comp_of_left, comp_apply]
152+
153+
lemma IsInvertible.inverse_comp_of_right {g : M₂ →L[R] M₃} {f : M →L[R] M₂}
154+
(hf : f.IsInvertible) : (g ∘L f).inverse = f.inverse ∘L g.inverse := by
155+
rcases hf with ⟨M, rfl⟩
156+
simp
157+
158+
lemma IsInvertible.inverse_comp_apply_of_right {g : M₂ →L[R] M₃} {f : M →L[R] M₂} {v : M₃}
159+
(hf : f.IsInvertible) : (g ∘L f).inverse v = f.inverse (g.inverse v) := by
160+
simp only [hf.inverse_comp_of_right, comp_apply]
161+
162+
@[simp]
163+
theorem ringInverse_equiv (e : M ≃L[R] M) : (↑e)⁻¹ʳ = inverse (e : M →L[R] M) := by
164+
suffices ((ContinuousLinearEquiv.unitsEquiv _ _).symm e : M →L[R] M)⁻¹ʳ = inverse ↑e by
165+
convert! this
166+
simp
167+
rfl
168+
169+
/-- The function `ContinuousLinearEquiv.inverse` can be written in terms of `Ring.inverse` for the
170+
ring of self-maps of the domain. -/
171+
theorem inverse_eq_ringInverse (e : M ≃L[R] M₂) (f : M →L[R] M₂) :
172+
inverse f = ((e.symm : M₂ →L[R] M).comp f)⁻¹ʳ ∘L e.symm := by
173+
by_cases h₁ : f.IsInvertible
174+
· obtain ⟨e', he'⟩ := h₁
175+
rw [← he']
176+
change _ = (e'.trans e.symm : M →L[R] M)⁻¹ʳ ∘L (e.symm : M₂ →L[R] M)
177+
ext
178+
simp
179+
· suffices ¬IsUnit ((e.symm : M₂ →L[R] M).comp f) by simp [this, h₁]
180+
contrapose h₁
181+
rcases h₁ with ⟨F, hF⟩
182+
use (ContinuousLinearEquiv.unitsEquiv _ _ F).trans e
183+
ext
184+
dsimp
185+
rw [hF]
186+
simp
187+
188+
theorem ringInverse_eq_inverse : Ring.inverse = inverse (R := R) (M := M) := by
189+
ext
190+
simp [inverse_eq_ringInverse (ContinuousLinearEquiv.refl R M)]
191+
192+
@[simp] theorem inverse_id : (ContinuousLinearMap.id R M).inverse = .id R M := by
193+
rw [← ringInverse_eq_inverse]
194+
exact Ring.inverse_one _
195+
196+
namespace IsInvertible
197+
198+
variable {f : M →L[R] M₂}
199+
200+
@[simp]
201+
theorem self_comp_inverse (hf : f.IsInvertible) : f ∘L f.inverse = .id _ _ := by
202+
rcases hf with ⟨e, rfl⟩
203+
simp
204+
205+
@[simp]
206+
theorem self_apply_inverse (hf : f.IsInvertible) (y : M₂) : f (f.inverse y) = y := by
207+
rcases hf with ⟨e, rfl⟩
208+
simp
209+
210+
@[simp]
211+
theorem inverse_comp_self (hf : f.IsInvertible) : f.inverse ∘L f = .id _ _ := by
212+
rcases hf with ⟨e, rfl⟩
213+
simp
214+
215+
@[simp]
216+
theorem inverse_apply_self (hf : f.IsInvertible) (y : M) : f.inverse (f y) = y := by
217+
rcases hf with ⟨e, rfl⟩
218+
simp
219+
220+
protected theorem bijective (hf : f.IsInvertible) : Function.Bijective f := by
221+
rcases hf with ⟨e, rfl⟩
222+
simp [ContinuousLinearEquiv.bijective]
223+
224+
protected theorem injective (hf : f.IsInvertible) : Function.Injective f :=
225+
hf.bijective.injective
226+
227+
protected theorem surjective (hf : f.IsInvertible) : Function.Surjective f :=
228+
hf.bijective.surjective
229+
230+
protected theorem inverse (hf : f.IsInvertible) : f.inverse.IsInvertible := by
231+
rcases hf with ⟨e, rfl⟩
232+
simp
233+
234+
@[simp]
235+
protected theorem inverse_inverse (hf : f.IsInvertible) : f.inverse.inverse = f := by
236+
rcases hf with ⟨e, rfl⟩
237+
simp
238+
239+
protected theorem of_isInvertible_inverse (hf : f.inverse.IsInvertible) : f.IsInvertible := by
240+
by_contra H
241+
obtain ⟨_, _⟩ : Subsingleton M₂ ∧ Subsingleton M := by simpa [inverse, H] using hf
242+
simp_all [Subsingleton.elim f 0]
243+
244+
@[simp]
245+
theorem _root_.ContinuousLinearMap.isInvertible_inverse_iff :
246+
f.inverse.IsInvertible ↔ f.IsInvertible :=
247+
⟨.of_isInvertible_inverse, .inverse⟩
248+
249+
end IsInvertible
250+
251+
end ContinuousLinearMap

0 commit comments

Comments
 (0)