-
Notifications
You must be signed in to change notification settings - Fork 251
/
Basic.lean
2766 lines (2215 loc) · 123 KB
/
Basic.lean
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
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/-
Copyright (c) 2019 Sébastien Gouëzel. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Jan-David Salchow, Sébastien Gouëzel, Jean Lo, Yury Kudryashov, Frédéric Dupuis,
Heather Macbeth
-/
import Mathlib.Topology.Algebra.Ring.Basic
import Mathlib.Topology.Algebra.MulAction
import Mathlib.Topology.Algebra.UniformGroup
import Mathlib.Topology.ContinuousFunction.Basic
import Mathlib.Topology.UniformSpace.UniformEmbedding
import Mathlib.Algebra.Algebra.Defs
import Mathlib.LinearAlgebra.Projection
import Mathlib.LinearAlgebra.Pi
import Mathlib.LinearAlgebra.Finsupp
#align_import topology.algebra.module.basic from "leanprover-community/mathlib"@"6285167a053ad0990fc88e56c48ccd9fae6550eb"
/-!
# Theory of topological modules and continuous linear maps.
We use the class `ContinuousSMul` for topological (semi) modules and topological vector spaces.
In this file we define continuous (semi-)linear maps, as semilinear maps between topological
modules which are continuous. The set of continuous semilinear maps between the topological
`R₁`-module `M` and `R₂`-module `M₂` with respect to the `RingHom` `σ` is denoted by `M →SL[σ] M₂`.
Plain linear maps are denoted by `M →L[R] M₂` and star-linear maps by `M →L⋆[R] M₂`.
The corresponding notation for equivalences is `M ≃SL[σ] M₂`, `M ≃L[R] M₂` and `M ≃L⋆[R] M₂`.
-/
assert_not_exists Star.star
open LinearMap (ker range)
open Topology Filter Pointwise
universe u v w u'
section
variable {R : Type*} {M : Type*} [Ring R] [TopologicalSpace R] [TopologicalSpace M]
[AddCommGroup M] [Module R M]
theorem ContinuousSMul.of_nhds_zero [TopologicalRing R] [TopologicalAddGroup M]
(hmul : Tendsto (fun p : R × M => p.1 • p.2) (𝓝 0 ×ˢ 𝓝 0) (𝓝 0))
(hmulleft : ∀ m : M, Tendsto (fun a : R => a • m) (𝓝 0) (𝓝 0))
(hmulright : ∀ a : R, Tendsto (fun m : M => a • m) (𝓝 0) (𝓝 0)) : ContinuousSMul R M where
continuous_smul := by
refine continuous_of_continuousAt_zero₂ (AddMonoidHom.smul : R →+ M →+ M) ?_ ?_ ?_ <;>
simpa [ContinuousAt, nhds_prod_eq]
#align has_continuous_smul.of_nhds_zero ContinuousSMul.of_nhds_zero
end
section
variable {R : Type*} {M : Type*} [Ring R] [TopologicalSpace R] [TopologicalSpace M]
[AddCommGroup M] [ContinuousAdd M] [Module R M] [ContinuousSMul R M]
/-- If `M` is a topological module over `R` and `0` is a limit of invertible elements of `R`, then
`⊤` is the only submodule of `M` with a nonempty interior.
This is the case, e.g., if `R` is a nontrivially normed field. -/
theorem Submodule.eq_top_of_nonempty_interior' [NeBot (𝓝[{ x : R | IsUnit x }] 0)]
(s : Submodule R M) (hs : (interior (s : Set M)).Nonempty) : s = ⊤ := by
rcases hs with ⟨y, hy⟩
refine Submodule.eq_top_iff'.2 fun x => ?_
rw [mem_interior_iff_mem_nhds] at hy
have : Tendsto (fun c : R => y + c • x) (𝓝[{ x : R | IsUnit x }] 0) (𝓝 (y + (0 : R) • x)) :=
tendsto_const_nhds.add ((tendsto_nhdsWithin_of_tendsto_nhds tendsto_id).smul tendsto_const_nhds)
rw [zero_smul, add_zero] at this
obtain ⟨_, hu : y + _ • _ ∈ s, u, rfl⟩ :=
nonempty_of_mem (inter_mem (Filter.mem_map.1 (this hy)) self_mem_nhdsWithin)
have hy' : y ∈ ↑s := mem_of_mem_nhds hy
rwa [s.add_mem_iff_right hy', ← Units.smul_def, s.smul_mem_iff' u] at hu
#align submodule.eq_top_of_nonempty_interior' Submodule.eq_top_of_nonempty_interior'
variable (R M)
/-- Let `R` be a topological ring such that zero is not an isolated point (e.g., a nontrivially
normed field, see `NormedField.punctured_nhds_neBot`). Let `M` be a nontrivial module over `R`
such that `c • x = 0` implies `c = 0 ∨ x = 0`. Then `M` has no isolated points. We formulate this
using `NeBot (𝓝[≠] x)`.
This lemma is not an instance because Lean would need to find `[ContinuousSMul ?m_1 M]` with
unknown `?m_1`. We register this as an instance for `R = ℝ` in `Real.punctured_nhds_module_neBot`.
One can also use `haveI := Module.punctured_nhds_neBot R M` in a proof.
-/
theorem Module.punctured_nhds_neBot [Nontrivial M] [NeBot (𝓝[≠] (0 : R))] [NoZeroSMulDivisors R M]
(x : M) : NeBot (𝓝[≠] x) := by
rcases exists_ne (0 : M) with ⟨y, hy⟩
suffices Tendsto (fun c : R => x + c • y) (𝓝[≠] 0) (𝓝[≠] x) from this.neBot
refine Tendsto.inf ?_ (tendsto_principal_principal.2 <| ?_)
· convert tendsto_const_nhds.add ((@tendsto_id R _).smul_const y)
rw [zero_smul, add_zero]
· intro c hc
simpa [hy] using hc
#align module.punctured_nhds_ne_bot Module.punctured_nhds_neBot
end
section LatticeOps
variable {ι R M₁ M₂ : Type*} [Semiring R] [AddCommMonoid M₁] [AddCommMonoid M₂] [Module R M₁]
[Module R M₂] [u : TopologicalSpace R] {t : TopologicalSpace M₂} [ContinuousSMul R M₂]
(f : M₁ →ₗ[R] M₂)
theorem continuousSMul_induced : @ContinuousSMul R M₁ _ u (t.induced f) :=
let _ : TopologicalSpace M₁ := t.induced f
Inducing.continuousSMul ⟨rfl⟩ continuous_id (map_smul f _ _)
#align has_continuous_smul_induced continuousSMul_induced
end LatticeOps
/-- The span of a separable subset with respect to a separable scalar ring is again separable. -/
lemma TopologicalSpace.IsSeparable.span {R M : Type*} [AddCommMonoid M] [Semiring R] [Module R M]
[TopologicalSpace M] [TopologicalSpace R] [SeparableSpace R]
[ContinuousAdd M] [ContinuousSMul R M] {s : Set M} (hs : IsSeparable s) :
IsSeparable (Submodule.span R s : Set M) := by
rw [span_eq_iUnion_nat]
refine .iUnion fun n ↦ .image ?_ ?_
· have : IsSeparable {f : Fin n → R × M | ∀ (i : Fin n), f i ∈ Set.univ ×ˢ s} := by
apply isSeparable_pi (fun i ↦ .prod (.of_separableSpace Set.univ) hs)
rwa [Set.univ_prod] at this
· apply continuous_finset_sum _ (fun i _ ↦ ?_)
exact (continuous_fst.comp (continuous_apply i)).smul (continuous_snd.comp (continuous_apply i))
namespace Submodule
variable {α β : Type*} [TopologicalSpace β]
#align submodule.has_continuous_smul SMulMemClass.continuousSMul
instance topologicalAddGroup [Ring α] [AddCommGroup β] [Module α β] [TopologicalAddGroup β]
(S : Submodule α β) : TopologicalAddGroup S :=
inferInstanceAs (TopologicalAddGroup S.toAddSubgroup)
#align submodule.topological_add_group Submodule.topologicalAddGroup
end Submodule
section closure
variable {R R' : Type u} {M M' : Type v} [Semiring R] [Ring R']
[TopologicalSpace M] [AddCommMonoid M] [TopologicalSpace M'] [AddCommGroup M'] [Module R M]
[ContinuousConstSMul R M] [Module R' M'] [ContinuousConstSMul R' M']
theorem Submodule.mapsTo_smul_closure (s : Submodule R M) (c : R) :
Set.MapsTo (c • ·) (closure s : Set M) (closure s) :=
have : Set.MapsTo (c • ·) (s : Set M) s := fun _ h ↦ s.smul_mem c h
this.closure (continuous_const_smul c)
theorem Submodule.smul_closure_subset (s : Submodule R M) (c : R) :
c • closure (s : Set M) ⊆ closure (s : Set M) :=
(s.mapsTo_smul_closure c).image_subset
variable [ContinuousAdd M]
/-- The (topological-space) closure of a submodule of a topological `R`-module `M` is itself
a submodule. -/
def Submodule.topologicalClosure (s : Submodule R M) : Submodule R M :=
{ s.toAddSubmonoid.topologicalClosure with
smul_mem' := s.mapsTo_smul_closure }
#align submodule.topological_closure Submodule.topologicalClosure
@[simp]
theorem Submodule.topologicalClosure_coe (s : Submodule R M) :
(s.topologicalClosure : Set M) = closure (s : Set M) :=
rfl
#align submodule.topological_closure_coe Submodule.topologicalClosure_coe
theorem Submodule.le_topologicalClosure (s : Submodule R M) : s ≤ s.topologicalClosure :=
subset_closure
#align submodule.le_topological_closure Submodule.le_topologicalClosure
theorem Submodule.closure_subset_topologicalClosure_span (s : Set M) :
closure s ⊆ (span R s).topologicalClosure := by
rw [Submodule.topologicalClosure_coe]
exact closure_mono subset_span
theorem Submodule.isClosed_topologicalClosure (s : Submodule R M) :
IsClosed (s.topologicalClosure : Set M) := isClosed_closure
#align submodule.is_closed_topological_closure Submodule.isClosed_topologicalClosure
theorem Submodule.topologicalClosure_minimal (s : Submodule R M) {t : Submodule R M} (h : s ≤ t)
(ht : IsClosed (t : Set M)) : s.topologicalClosure ≤ t :=
closure_minimal h ht
#align submodule.topological_closure_minimal Submodule.topologicalClosure_minimal
theorem Submodule.topologicalClosure_mono {s : Submodule R M} {t : Submodule R M} (h : s ≤ t) :
s.topologicalClosure ≤ t.topologicalClosure :=
closure_mono h
#align submodule.topological_closure_mono Submodule.topologicalClosure_mono
/-- The topological closure of a closed submodule `s` is equal to `s`. -/
theorem IsClosed.submodule_topologicalClosure_eq {s : Submodule R M} (hs : IsClosed (s : Set M)) :
s.topologicalClosure = s :=
SetLike.ext' hs.closure_eq
#align is_closed.submodule_topological_closure_eq IsClosed.submodule_topologicalClosure_eq
/-- A subspace is dense iff its topological closure is the entire space. -/
theorem Submodule.dense_iff_topologicalClosure_eq_top {s : Submodule R M} :
Dense (s : Set M) ↔ s.topologicalClosure = ⊤ := by
rw [← SetLike.coe_set_eq, dense_iff_closure_eq]
simp
#align submodule.dense_iff_topological_closure_eq_top Submodule.dense_iff_topologicalClosure_eq_top
instance Submodule.topologicalClosure.completeSpace {M' : Type*} [AddCommMonoid M'] [Module R M']
[UniformSpace M'] [ContinuousAdd M'] [ContinuousConstSMul R M'] [CompleteSpace M']
(U : Submodule R M') : CompleteSpace U.topologicalClosure :=
isClosed_closure.completeSpace_coe
#align submodule.topological_closure.complete_space Submodule.topologicalClosure.completeSpace
/-- A maximal proper subspace of a topological module (i.e a `Submodule` satisfying `IsCoatom`)
is either closed or dense. -/
theorem Submodule.isClosed_or_dense_of_isCoatom (s : Submodule R M) (hs : IsCoatom s) :
IsClosed (s : Set M) ∨ Dense (s : Set M) := by
refine (hs.le_iff.mp s.le_topologicalClosure).symm.imp ?_ dense_iff_topologicalClosure_eq_top.mpr
exact fun h ↦ h ▸ isClosed_closure
#align submodule.is_closed_or_dense_of_is_coatom Submodule.isClosed_or_dense_of_isCoatom
end closure
section Pi
theorem LinearMap.continuous_on_pi {ι : Type*} {R : Type*} {M : Type*} [Finite ι] [Semiring R]
[TopologicalSpace R] [AddCommMonoid M] [Module R M] [TopologicalSpace M] [ContinuousAdd M]
[ContinuousSMul R M] (f : (ι → R) →ₗ[R] M) : Continuous f := by
cases nonempty_fintype ι
classical
-- for the proof, write `f` in the standard basis, and use that each coordinate is a continuous
-- function.
have : (f : (ι → R) → M) = fun x => ∑ i : ι, x i • f fun j => if i = j then 1 else 0 := by
ext x
exact f.pi_apply_eq_sum_univ x
rw [this]
refine continuous_finset_sum _ fun i _ => ?_
exact (continuous_apply i).smul continuous_const
#align linear_map.continuous_on_pi LinearMap.continuous_on_pi
end Pi
/-- Continuous linear maps between modules. We only put the type classes that are necessary for the
definition, although in applications `M` and `M₂` will be topological modules over the topological
ring `R`. -/
structure ContinuousLinearMap {R : Type*} {S : Type*} [Semiring R] [Semiring S] (σ : R →+* S)
(M : Type*) [TopologicalSpace M] [AddCommMonoid M] (M₂ : Type*) [TopologicalSpace M₂]
[AddCommMonoid M₂] [Module R M] [Module S M₂] extends M →ₛₗ[σ] M₂ where
cont : Continuous toFun := by continuity
#align continuous_linear_map ContinuousLinearMap
attribute [inherit_doc ContinuousLinearMap] ContinuousLinearMap.cont
@[inherit_doc]
notation:25 M " →SL[" σ "] " M₂ => ContinuousLinearMap σ M M₂
@[inherit_doc]
notation:25 M " →L[" R "] " M₂ => ContinuousLinearMap (RingHom.id R) M M₂
/-- `ContinuousSemilinearMapClass F σ M M₂` asserts `F` is a type of bundled continuous
`σ`-semilinear maps `M → M₂`. See also `ContinuousLinearMapClass F R M M₂` for the case where
`σ` is the identity map on `R`. A map `f` between an `R`-module and an `S`-module over a ring
homomorphism `σ : R →+* S` is semilinear if it satisfies the two properties `f (x + y) = f x + f y`
and `f (c • x) = (σ c) • f x`. -/
class ContinuousSemilinearMapClass (F : Type*) {R S : outParam Type*} [Semiring R] [Semiring S]
(σ : outParam <| R →+* S) (M : outParam Type*) [TopologicalSpace M] [AddCommMonoid M]
(M₂ : outParam Type*) [TopologicalSpace M₂] [AddCommMonoid M₂] [Module R M]
[Module S M₂] [FunLike F M M₂]
extends SemilinearMapClass F σ M M₂, ContinuousMapClass F M M₂ : Prop
#align continuous_semilinear_map_class ContinuousSemilinearMapClass
-- `σ`, `R` and `S` become metavariables, but they are all outparams so it's OK
-- Porting note(#12094): removed nolint; dangerous_instance linter not ported yet
-- attribute [nolint dangerous_instance] ContinuousSemilinearMapClass.toContinuousMapClass
/-- `ContinuousLinearMapClass F R M M₂` asserts `F` is a type of bundled continuous
`R`-linear maps `M → M₂`. This is an abbreviation for
`ContinuousSemilinearMapClass F (RingHom.id R) M M₂`. -/
abbrev ContinuousLinearMapClass (F : Type*) (R : outParam Type*) [Semiring R]
(M : outParam Type*) [TopologicalSpace M] [AddCommMonoid M] (M₂ : outParam Type*)
[TopologicalSpace M₂] [AddCommMonoid M₂] [Module R M] [Module R M₂] [FunLike F M M₂] :=
ContinuousSemilinearMapClass F (RingHom.id R) M M₂
#align continuous_linear_map_class ContinuousLinearMapClass
/-- Continuous linear equivalences between modules. We only put the type classes that are necessary
for the definition, although in applications `M` and `M₂` will be topological modules over the
topological semiring `R`. -/
-- Porting note (#5171): linter not ported yet; was @[nolint has_nonempty_instance]
structure ContinuousLinearEquiv {R : Type*} {S : Type*} [Semiring R] [Semiring S] (σ : R →+* S)
{σ' : S →+* R} [RingHomInvPair σ σ'] [RingHomInvPair σ' σ] (M : Type*) [TopologicalSpace M]
[AddCommMonoid M] (M₂ : Type*) [TopologicalSpace M₂] [AddCommMonoid M₂] [Module R M]
[Module S M₂] extends M ≃ₛₗ[σ] M₂ where
continuous_toFun : Continuous toFun := by continuity
continuous_invFun : Continuous invFun := by continuity
#align continuous_linear_equiv ContinuousLinearEquiv
attribute [inherit_doc ContinuousLinearEquiv] ContinuousLinearEquiv.continuous_toFun
ContinuousLinearEquiv.continuous_invFun
@[inherit_doc]
notation:50 M " ≃SL[" σ "] " M₂ => ContinuousLinearEquiv σ M M₂
@[inherit_doc]
notation:50 M " ≃L[" R "] " M₂ => ContinuousLinearEquiv (RingHom.id R) M M₂
/-- `ContinuousSemilinearEquivClass F σ M M₂` asserts `F` is a type of bundled continuous
`σ`-semilinear equivs `M → M₂`. See also `ContinuousLinearEquivClass F R M M₂` for the case
where `σ` is the identity map on `R`. A map `f` between an `R`-module and an `S`-module over a ring
homomorphism `σ : R →+* S` is semilinear if it satisfies the two properties `f (x + y) = f x + f y`
and `f (c • x) = (σ c) • f x`. -/
class ContinuousSemilinearEquivClass (F : Type*) {R : outParam Type*} {S : outParam Type*}
[Semiring R] [Semiring S] (σ : outParam <| R →+* S) {σ' : outParam <| S →+* R}
[RingHomInvPair σ σ'] [RingHomInvPair σ' σ] (M : outParam Type*) [TopologicalSpace M]
[AddCommMonoid M] (M₂ : outParam Type*) [TopologicalSpace M₂] [AddCommMonoid M₂] [Module R M]
[Module S M₂] [EquivLike F M M₂] extends SemilinearEquivClass F σ M M₂ : Prop where
map_continuous : ∀ f : F, Continuous f := by continuity
inv_continuous : ∀ f : F, Continuous (EquivLike.inv f) := by continuity
#align continuous_semilinear_equiv_class ContinuousSemilinearEquivClass
attribute [inherit_doc ContinuousSemilinearEquivClass]
ContinuousSemilinearEquivClass.map_continuous
ContinuousSemilinearEquivClass.inv_continuous
/-- `ContinuousLinearEquivClass F σ M M₂` asserts `F` is a type of bundled continuous
`R`-linear equivs `M → M₂`. This is an abbreviation for
`ContinuousSemilinearEquivClass F (RingHom.id R) M M₂`. -/
abbrev ContinuousLinearEquivClass (F : Type*) (R : outParam Type*) [Semiring R]
(M : outParam Type*) [TopologicalSpace M] [AddCommMonoid M] (M₂ : outParam Type*)
[TopologicalSpace M₂] [AddCommMonoid M₂] [Module R M] [Module R M₂] [EquivLike F M M₂] :=
ContinuousSemilinearEquivClass F (RingHom.id R) M M₂
#align continuous_linear_equiv_class ContinuousLinearEquivClass
namespace ContinuousSemilinearEquivClass
variable (F : Type*) {R : Type*} {S : Type*} [Semiring R] [Semiring S] (σ : R →+* S)
{σ' : S →+* R} [RingHomInvPair σ σ'] [RingHomInvPair σ' σ]
(M : Type*) [TopologicalSpace M] [AddCommMonoid M]
(M₂ : Type*) [TopologicalSpace M₂] [AddCommMonoid M₂]
[Module R M] [Module S M₂]
-- `σ'` becomes a metavariable, but it's OK since it's an outparam
instance (priority := 100) continuousSemilinearMapClass [EquivLike F M M₂]
[s : ContinuousSemilinearEquivClass F σ M M₂] : ContinuousSemilinearMapClass F σ M M₂ :=
{ s with }
#align continuous_semilinear_equiv_class.continuous_semilinear_map_class ContinuousSemilinearEquivClass.continuousSemilinearMapClass
end ContinuousSemilinearEquivClass
section PointwiseLimits
variable {M₁ M₂ α R S : Type*} [TopologicalSpace M₂] [T2Space M₂] [Semiring R] [Semiring S]
[AddCommMonoid M₁] [AddCommMonoid M₂] [Module R M₁] [Module S M₂] [ContinuousConstSMul S M₂]
variable [ContinuousAdd M₂] {σ : R →+* S} {l : Filter α}
/-- Constructs a bundled linear map from a function and a proof that this function belongs to the
closure of the set of linear maps. -/
@[simps (config := .asFn)]
def linearMapOfMemClosureRangeCoe (f : M₁ → M₂)
(hf : f ∈ closure (Set.range ((↑) : (M₁ →ₛₗ[σ] M₂) → M₁ → M₂))) : M₁ →ₛₗ[σ] M₂ :=
{ addMonoidHomOfMemClosureRangeCoe f hf with
map_smul' := (isClosed_setOf_map_smul M₁ M₂ σ).closure_subset_iff.2
(Set.range_subset_iff.2 LinearMap.map_smulₛₗ) hf }
#align linear_map_of_mem_closure_range_coe linearMapOfMemClosureRangeCoe
#align linear_map_of_mem_closure_range_coe_apply linearMapOfMemClosureRangeCoe_apply
/-- Construct a bundled linear map from a pointwise limit of linear maps -/
@[simps! (config := .asFn)]
def linearMapOfTendsto (f : M₁ → M₂) (g : α → M₁ →ₛₗ[σ] M₂) [l.NeBot]
(h : Tendsto (fun a x => g a x) l (𝓝 f)) : M₁ →ₛₗ[σ] M₂ :=
linearMapOfMemClosureRangeCoe f <|
mem_closure_of_tendsto h <| eventually_of_forall fun _ => Set.mem_range_self _
#align linear_map_of_tendsto linearMapOfTendsto
#align linear_map_of_tendsto_apply linearMapOfTendsto_apply
variable (M₁ M₂ σ)
theorem LinearMap.isClosed_range_coe : IsClosed (Set.range ((↑) : (M₁ →ₛₗ[σ] M₂) → M₁ → M₂)) :=
isClosed_of_closure_subset fun f hf => ⟨linearMapOfMemClosureRangeCoe f hf, rfl⟩
#align linear_map.is_closed_range_coe LinearMap.isClosed_range_coe
end PointwiseLimits
namespace ContinuousLinearMap
section Semiring
/-!
### Properties that hold for non-necessarily commutative semirings.
-/
variable {R₁ : Type*} {R₂ : Type*} {R₃ : Type*} [Semiring R₁] [Semiring R₂] [Semiring R₃]
{σ₁₂ : R₁ →+* R₂} {σ₂₃ : R₂ →+* R₃} {σ₁₃ : R₁ →+* R₃} {M₁ : Type*} [TopologicalSpace M₁]
[AddCommMonoid M₁] {M'₁ : Type*} [TopologicalSpace M'₁] [AddCommMonoid M'₁] {M₂ : Type*}
[TopologicalSpace M₂] [AddCommMonoid M₂] {M₃ : Type*} [TopologicalSpace M₃] [AddCommMonoid M₃]
{M₄ : Type*} [TopologicalSpace M₄] [AddCommMonoid M₄] [Module R₁ M₁] [Module R₁ M'₁]
[Module R₂ M₂] [Module R₃ M₃]
attribute [coe] ContinuousLinearMap.toLinearMap
/-- Coerce continuous linear maps to linear maps. -/
instance LinearMap.coe : Coe (M₁ →SL[σ₁₂] M₂) (M₁ →ₛₗ[σ₁₂] M₂) := ⟨toLinearMap⟩
#align continuous_linear_map.linear_map.has_coe ContinuousLinearMap.LinearMap.coe
#noalign continuous_linear_map.to_linear_map_eq_coe
theorem coe_injective : Function.Injective ((↑) : (M₁ →SL[σ₁₂] M₂) → M₁ →ₛₗ[σ₁₂] M₂) := by
intro f g H
cases f
cases g
congr
#align continuous_linear_map.coe_injective ContinuousLinearMap.coe_injective
instance funLike : FunLike (M₁ →SL[σ₁₂] M₂) M₁ M₂ where
coe f := f.toLinearMap
coe_injective' _ _ h := coe_injective (DFunLike.coe_injective h)
instance continuousSemilinearMapClass :
ContinuousSemilinearMapClass (M₁ →SL[σ₁₂] M₂) σ₁₂ M₁ M₂ where
map_add f := map_add f.toLinearMap
map_continuous f := f.2
map_smulₛₗ f := f.toLinearMap.map_smul'
#align continuous_linear_map.continuous_semilinear_map_class ContinuousLinearMap.continuousSemilinearMapClass
-- see Note [function coercion]
/-- Coerce continuous linear maps to functions. -/
--instance toFun' : CoeFun (M₁ →SL[σ₁₂] M₂) fun _ => M₁ → M₂ := ⟨DFunLike.coe⟩
-- porting note (#10618): was `simp`, now `simp only` proves it
theorem coe_mk (f : M₁ →ₛₗ[σ₁₂] M₂) (h) : (mk f h : M₁ →ₛₗ[σ₁₂] M₂) = f :=
rfl
#align continuous_linear_map.coe_mk ContinuousLinearMap.coe_mk
@[simp]
theorem coe_mk' (f : M₁ →ₛₗ[σ₁₂] M₂) (h) : (mk f h : M₁ → M₂) = f :=
rfl
#align continuous_linear_map.coe_mk' ContinuousLinearMap.coe_mk'
@[continuity, fun_prop]
protected theorem continuous (f : M₁ →SL[σ₁₂] M₂) : Continuous f :=
f.2
#align continuous_linear_map.continuous ContinuousLinearMap.continuous
protected theorem uniformContinuous {E₁ E₂ : Type*} [UniformSpace E₁] [UniformSpace E₂]
[AddCommGroup E₁] [AddCommGroup E₂] [Module R₁ E₁] [Module R₂ E₂] [UniformAddGroup E₁]
[UniformAddGroup E₂] (f : E₁ →SL[σ₁₂] E₂) : UniformContinuous f :=
uniformContinuous_addMonoidHom_of_continuous f.continuous
#align continuous_linear_map.uniform_continuous ContinuousLinearMap.uniformContinuous
@[simp, norm_cast]
theorem coe_inj {f g : M₁ →SL[σ₁₂] M₂} : (f : M₁ →ₛₗ[σ₁₂] M₂) = g ↔ f = g :=
coe_injective.eq_iff
#align continuous_linear_map.coe_inj ContinuousLinearMap.coe_inj
theorem coeFn_injective : @Function.Injective (M₁ →SL[σ₁₂] M₂) (M₁ → M₂) (↑) :=
DFunLike.coe_injective
#align continuous_linear_map.coe_fn_injective ContinuousLinearMap.coeFn_injective
/-- See Note [custom simps projection]. We need to specify this projection explicitly in this case,
because it is a composition of multiple projections. -/
def Simps.apply (h : M₁ →SL[σ₁₂] M₂) : M₁ → M₂ :=
h
#align continuous_linear_map.simps.apply ContinuousLinearMap.Simps.apply
/-- See Note [custom simps projection]. -/
def Simps.coe (h : M₁ →SL[σ₁₂] M₂) : M₁ →ₛₗ[σ₁₂] M₂ :=
h
#align continuous_linear_map.simps.coe ContinuousLinearMap.Simps.coe
initialize_simps_projections ContinuousLinearMap (toLinearMap_toFun → apply, toLinearMap → coe)
@[ext]
theorem ext {f g : M₁ →SL[σ₁₂] M₂} (h : ∀ x, f x = g x) : f = g :=
DFunLike.ext f g h
#align continuous_linear_map.ext ContinuousLinearMap.ext
theorem ext_iff {f g : M₁ →SL[σ₁₂] M₂} : f = g ↔ ∀ x, f x = g x :=
DFunLike.ext_iff
#align continuous_linear_map.ext_iff ContinuousLinearMap.ext_iff
/-- Copy of a `ContinuousLinearMap` with a new `toFun` equal to the old one. Useful to fix
definitional equalities. -/
protected def copy (f : M₁ →SL[σ₁₂] M₂) (f' : M₁ → M₂) (h : f' = ⇑f) : M₁ →SL[σ₁₂] M₂ where
toLinearMap := f.toLinearMap.copy f' h
cont := show Continuous f' from h.symm ▸ f.continuous
#align continuous_linear_map.copy ContinuousLinearMap.copy
@[simp]
theorem coe_copy (f : M₁ →SL[σ₁₂] M₂) (f' : M₁ → M₂) (h : f' = ⇑f) : ⇑(f.copy f' h) = f' :=
rfl
#align continuous_linear_map.coe_copy ContinuousLinearMap.coe_copy
theorem copy_eq (f : M₁ →SL[σ₁₂] M₂) (f' : M₁ → M₂) (h : f' = ⇑f) : f.copy f' h = f :=
DFunLike.ext' h
#align continuous_linear_map.copy_eq ContinuousLinearMap.copy_eq
-- make some straightforward lemmas available to `simp`.
protected theorem map_zero (f : M₁ →SL[σ₁₂] M₂) : f (0 : M₁) = 0 :=
map_zero f
#align continuous_linear_map.map_zero ContinuousLinearMap.map_zero
protected theorem map_add (f : M₁ →SL[σ₁₂] M₂) (x y : M₁) : f (x + y) = f x + f y :=
map_add f x y
#align continuous_linear_map.map_add ContinuousLinearMap.map_add
-- @[simp] -- Porting note (#10618): simp can prove this
protected theorem map_smulₛₗ (f : M₁ →SL[σ₁₂] M₂) (c : R₁) (x : M₁) : f (c • x) = σ₁₂ c • f x :=
(toLinearMap _).map_smulₛₗ _ _
#align continuous_linear_map.map_smulₛₗ ContinuousLinearMap.map_smulₛₗ
-- @[simp] -- Porting note (#10618): simp can prove this
protected theorem map_smul [Module R₁ M₂] (f : M₁ →L[R₁] M₂) (c : R₁) (x : M₁) :
f (c • x) = c • f x := by simp only [RingHom.id_apply, ContinuousLinearMap.map_smulₛₗ]
#align continuous_linear_map.map_smul ContinuousLinearMap.map_smul
@[simp]
theorem map_smul_of_tower {R S : Type*} [Semiring S] [SMul R M₁] [Module S M₁] [SMul R M₂]
[Module S M₂] [LinearMap.CompatibleSMul M₁ M₂ R S] (f : M₁ →L[S] M₂) (c : R) (x : M₁) :
f (c • x) = c • f x :=
LinearMap.CompatibleSMul.map_smul (f : M₁ →ₗ[S] M₂) c x
#align continuous_linear_map.map_smul_of_tower ContinuousLinearMap.map_smul_of_tower
@[deprecated _root_.map_sum (since := "2023-09-16")]
protected theorem map_sum {ι : Type*} (f : M₁ →SL[σ₁₂] M₂) (s : Finset ι) (g : ι → M₁) :
f (∑ i ∈ s, g i) = ∑ i ∈ s, f (g i) :=
map_sum ..
#align continuous_linear_map.map_sum ContinuousLinearMap.map_sum
@[simp, norm_cast]
theorem coe_coe (f : M₁ →SL[σ₁₂] M₂) : ⇑(f : M₁ →ₛₗ[σ₁₂] M₂) = f :=
rfl
#align continuous_linear_map.coe_coe ContinuousLinearMap.coe_coe
@[ext]
theorem ext_ring [TopologicalSpace R₁] {f g : R₁ →L[R₁] M₁} (h : f 1 = g 1) : f = g :=
coe_inj.1 <| LinearMap.ext_ring h
#align continuous_linear_map.ext_ring ContinuousLinearMap.ext_ring
theorem ext_ring_iff [TopologicalSpace R₁] {f g : R₁ →L[R₁] M₁} : f = g ↔ f 1 = g 1 :=
⟨fun h => h ▸ rfl, ext_ring⟩
#align continuous_linear_map.ext_ring_iff ContinuousLinearMap.ext_ring_iff
/-- If two continuous linear maps are equal on a set `s`, then they are equal on the closure
of the `Submodule.span` of this set. -/
theorem eqOn_closure_span [T2Space M₂] {s : Set M₁} {f g : M₁ →SL[σ₁₂] M₂} (h : Set.EqOn f g s) :
Set.EqOn f g (closure (Submodule.span R₁ s : Set M₁)) :=
(LinearMap.eqOn_span' h).closure f.continuous g.continuous
#align continuous_linear_map.eq_on_closure_span ContinuousLinearMap.eqOn_closure_span
/-- If the submodule generated by a set `s` is dense in the ambient module, then two continuous
linear maps equal on `s` are equal. -/
theorem ext_on [T2Space M₂] {s : Set M₁} (hs : Dense (Submodule.span R₁ s : Set M₁))
{f g : M₁ →SL[σ₁₂] M₂} (h : Set.EqOn f g s) : f = g :=
ext fun x => eqOn_closure_span h (hs x)
#align continuous_linear_map.ext_on ContinuousLinearMap.ext_on
/-- Under a continuous linear map, the image of the `TopologicalClosure` of a submodule is
contained in the `TopologicalClosure` of its image. -/
theorem _root_.Submodule.topologicalClosure_map [RingHomSurjective σ₁₂] [TopologicalSpace R₁]
[TopologicalSpace R₂] [ContinuousSMul R₁ M₁] [ContinuousAdd M₁] [ContinuousSMul R₂ M₂]
[ContinuousAdd M₂] (f : M₁ →SL[σ₁₂] M₂) (s : Submodule R₁ M₁) :
s.topologicalClosure.map (f : M₁ →ₛₗ[σ₁₂] M₂) ≤
(s.map (f : M₁ →ₛₗ[σ₁₂] M₂)).topologicalClosure :=
image_closure_subset_closure_image f.continuous
#align submodule.topological_closure_map Submodule.topologicalClosure_map
/-- Under a dense continuous linear map, a submodule whose `TopologicalClosure` is `⊤` is sent to
another such submodule. That is, the image of a dense set under a map with dense range is dense.
-/
theorem _root_.DenseRange.topologicalClosure_map_submodule [RingHomSurjective σ₁₂]
[TopologicalSpace R₁] [TopologicalSpace R₂] [ContinuousSMul R₁ M₁] [ContinuousAdd M₁]
[ContinuousSMul R₂ M₂] [ContinuousAdd M₂] {f : M₁ →SL[σ₁₂] M₂} (hf' : DenseRange f)
{s : Submodule R₁ M₁} (hs : s.topologicalClosure = ⊤) :
(s.map (f : M₁ →ₛₗ[σ₁₂] M₂)).topologicalClosure = ⊤ := by
rw [SetLike.ext'_iff] at hs ⊢
simp only [Submodule.topologicalClosure_coe, Submodule.top_coe, ← dense_iff_closure_eq] at hs ⊢
exact hf'.dense_image f.continuous hs
#align dense_range.topological_closure_map_submodule DenseRange.topologicalClosure_map_submodule
section SMulMonoid
variable {S₂ T₂ : Type*} [Monoid S₂] [Monoid T₂]
variable [DistribMulAction S₂ M₂] [SMulCommClass R₂ S₂ M₂] [ContinuousConstSMul S₂ M₂]
variable [DistribMulAction T₂ M₂] [SMulCommClass R₂ T₂ M₂] [ContinuousConstSMul T₂ M₂]
instance instSMul : SMul S₂ (M₁ →SL[σ₁₂] M₂) where
smul c f := ⟨c • (f : M₁ →ₛₗ[σ₁₂] M₂), (f.2.const_smul _ : Continuous fun x => c • f x)⟩
instance mulAction : MulAction S₂ (M₁ →SL[σ₁₂] M₂) where
one_smul _f := ext fun _x => one_smul _ _
mul_smul _a _b _f := ext fun _x => mul_smul _ _ _
#align continuous_linear_map.mul_action ContinuousLinearMap.mulAction
theorem smul_apply (c : S₂) (f : M₁ →SL[σ₁₂] M₂) (x : M₁) : (c • f) x = c • f x :=
rfl
#align continuous_linear_map.smul_apply ContinuousLinearMap.smul_apply
@[simp, norm_cast]
theorem coe_smul (c : S₂) (f : M₁ →SL[σ₁₂] M₂) :
↑(c • f) = c • (f : M₁ →ₛₗ[σ₁₂] M₂) :=
rfl
#align continuous_linear_map.coe_smul ContinuousLinearMap.coe_smul
@[simp, norm_cast]
theorem coe_smul' (c : S₂) (f : M₁ →SL[σ₁₂] M₂) :
↑(c • f) = c • (f : M₁ → M₂) :=
rfl
#align continuous_linear_map.coe_smul' ContinuousLinearMap.coe_smul'
instance isScalarTower [SMul S₂ T₂] [IsScalarTower S₂ T₂ M₂] :
IsScalarTower S₂ T₂ (M₁ →SL[σ₁₂] M₂) :=
⟨fun a b f => ext fun x => smul_assoc a b (f x)⟩
#align continuous_linear_map.is_scalar_tower ContinuousLinearMap.isScalarTower
instance smulCommClass [SMulCommClass S₂ T₂ M₂] : SMulCommClass S₂ T₂ (M₁ →SL[σ₁₂] M₂) :=
⟨fun a b f => ext fun x => smul_comm a b (f x)⟩
#align continuous_linear_map.smul_comm_class ContinuousLinearMap.smulCommClass
end SMulMonoid
/-- The continuous map that is constantly zero. -/
instance zero : Zero (M₁ →SL[σ₁₂] M₂) :=
⟨⟨0, continuous_zero⟩⟩
#align continuous_linear_map.has_zero ContinuousLinearMap.zero
instance inhabited : Inhabited (M₁ →SL[σ₁₂] M₂) :=
⟨0⟩
#align continuous_linear_map.inhabited ContinuousLinearMap.inhabited
@[simp]
theorem default_def : (default : M₁ →SL[σ₁₂] M₂) = 0 :=
rfl
#align continuous_linear_map.default_def ContinuousLinearMap.default_def
@[simp]
theorem zero_apply (x : M₁) : (0 : M₁ →SL[σ₁₂] M₂) x = 0 :=
rfl
#align continuous_linear_map.zero_apply ContinuousLinearMap.zero_apply
@[simp, norm_cast]
theorem coe_zero : ((0 : M₁ →SL[σ₁₂] M₂) : M₁ →ₛₗ[σ₁₂] M₂) = 0 :=
rfl
#align continuous_linear_map.coe_zero ContinuousLinearMap.coe_zero
/- no simp attribute on the next line as simp does not always simplify `0 x` to `0`
when `0` is the zero function, while it does for the zero continuous linear map,
and this is the most important property we care about. -/
@[norm_cast]
theorem coe_zero' : ⇑(0 : M₁ →SL[σ₁₂] M₂) = 0 :=
rfl
#align continuous_linear_map.coe_zero' ContinuousLinearMap.coe_zero'
instance uniqueOfLeft [Subsingleton M₁] : Unique (M₁ →SL[σ₁₂] M₂) :=
coe_injective.unique
#align continuous_linear_map.unique_of_left ContinuousLinearMap.uniqueOfLeft
instance uniqueOfRight [Subsingleton M₂] : Unique (M₁ →SL[σ₁₂] M₂) :=
coe_injective.unique
#align continuous_linear_map.unique_of_right ContinuousLinearMap.uniqueOfRight
theorem exists_ne_zero {f : M₁ →SL[σ₁₂] M₂} (hf : f ≠ 0) : ∃ x, f x ≠ 0 := by
by_contra! h
exact hf (ContinuousLinearMap.ext h)
#align continuous_linear_map.exists_ne_zero ContinuousLinearMap.exists_ne_zero
section
variable (R₁ M₁)
/-- the identity map as a continuous linear map. -/
def id : M₁ →L[R₁] M₁ :=
⟨LinearMap.id, continuous_id⟩
#align continuous_linear_map.id ContinuousLinearMap.id
end
instance one : One (M₁ →L[R₁] M₁) :=
⟨id R₁ M₁⟩
#align continuous_linear_map.has_one ContinuousLinearMap.one
theorem one_def : (1 : M₁ →L[R₁] M₁) = id R₁ M₁ :=
rfl
#align continuous_linear_map.one_def ContinuousLinearMap.one_def
theorem id_apply (x : M₁) : id R₁ M₁ x = x :=
rfl
#align continuous_linear_map.id_apply ContinuousLinearMap.id_apply
@[simp, norm_cast]
theorem coe_id : (id R₁ M₁ : M₁ →ₗ[R₁] M₁) = LinearMap.id :=
rfl
#align continuous_linear_map.coe_id ContinuousLinearMap.coe_id
@[simp, norm_cast]
theorem coe_id' : ⇑(id R₁ M₁) = _root_.id :=
rfl
#align continuous_linear_map.coe_id' ContinuousLinearMap.coe_id'
@[simp, norm_cast]
theorem coe_eq_id {f : M₁ →L[R₁] M₁} : (f : M₁ →ₗ[R₁] M₁) = LinearMap.id ↔ f = id _ _ := by
rw [← coe_id, coe_inj]
#align continuous_linear_map.coe_eq_id ContinuousLinearMap.coe_eq_id
@[simp]
theorem one_apply (x : M₁) : (1 : M₁ →L[R₁] M₁) x = x :=
rfl
#align continuous_linear_map.one_apply ContinuousLinearMap.one_apply
instance [Nontrivial M₁] : Nontrivial (M₁ →L[R₁] M₁) :=
⟨0, 1, fun e ↦
have ⟨x, hx⟩ := exists_ne (0 : M₁); hx (by simpa using DFunLike.congr_fun e.symm x)⟩
section Add
variable [ContinuousAdd M₂]
instance add : Add (M₁ →SL[σ₁₂] M₂) :=
⟨fun f g => ⟨f + g, f.2.add g.2⟩⟩
#align continuous_linear_map.has_add ContinuousLinearMap.add
@[simp]
theorem add_apply (f g : M₁ →SL[σ₁₂] M₂) (x : M₁) : (f + g) x = f x + g x :=
rfl
#align continuous_linear_map.add_apply ContinuousLinearMap.add_apply
@[simp, norm_cast]
theorem coe_add (f g : M₁ →SL[σ₁₂] M₂) : (↑(f + g) : M₁ →ₛₗ[σ₁₂] M₂) = f + g :=
rfl
#align continuous_linear_map.coe_add ContinuousLinearMap.coe_add
@[norm_cast]
theorem coe_add' (f g : M₁ →SL[σ₁₂] M₂) : ⇑(f + g) = f + g :=
rfl
#align continuous_linear_map.coe_add' ContinuousLinearMap.coe_add'
instance addCommMonoid : AddCommMonoid (M₁ →SL[σ₁₂] M₂) where
zero_add := by
intros
ext
apply_rules [zero_add, add_assoc, add_zero, add_left_neg, add_comm]
add_zero := by
intros
ext
apply_rules [zero_add, add_assoc, add_zero, add_left_neg, add_comm]
add_comm := by
intros
ext
apply_rules [zero_add, add_assoc, add_zero, add_left_neg, add_comm]
add_assoc := by
intros
ext
apply_rules [zero_add, add_assoc, add_zero, add_left_neg, add_comm]
nsmul := (· • ·)
nsmul_zero f := by
ext
simp
nsmul_succ n f := by
ext
simp [add_smul]
#align continuous_linear_map.add_comm_monoid ContinuousLinearMap.addCommMonoid
@[simp, norm_cast]
theorem coe_sum {ι : Type*} (t : Finset ι) (f : ι → M₁ →SL[σ₁₂] M₂) :
↑(∑ d ∈ t, f d) = (∑ d ∈ t, f d : M₁ →ₛₗ[σ₁₂] M₂) :=
map_sum (AddMonoidHom.mk ⟨((↑) : (M₁ →SL[σ₁₂] M₂) → M₁ →ₛₗ[σ₁₂] M₂), rfl⟩ fun _ _ => rfl) _ _
#align continuous_linear_map.coe_sum ContinuousLinearMap.coe_sum
@[simp, norm_cast]
theorem coe_sum' {ι : Type*} (t : Finset ι) (f : ι → M₁ →SL[σ₁₂] M₂) :
⇑(∑ d ∈ t, f d) = ∑ d ∈ t, ⇑(f d) := by simp only [← coe_coe, coe_sum, LinearMap.coeFn_sum]
#align continuous_linear_map.coe_sum' ContinuousLinearMap.coe_sum'
theorem sum_apply {ι : Type*} (t : Finset ι) (f : ι → M₁ →SL[σ₁₂] M₂) (b : M₁) :
(∑ d ∈ t, f d) b = ∑ d ∈ t, f d b := by simp only [coe_sum', Finset.sum_apply]
#align continuous_linear_map.sum_apply ContinuousLinearMap.sum_apply
end Add
variable [RingHomCompTriple σ₁₂ σ₂₃ σ₁₃]
/-- Composition of bounded linear maps. -/
def comp (g : M₂ →SL[σ₂₃] M₃) (f : M₁ →SL[σ₁₂] M₂) : M₁ →SL[σ₁₃] M₃ :=
⟨(g : M₂ →ₛₗ[σ₂₃] M₃).comp (f : M₁ →ₛₗ[σ₁₂] M₂), g.2.comp f.2⟩
#align continuous_linear_map.comp ContinuousLinearMap.comp
@[inherit_doc comp]
infixr:80 " ∘L " =>
@ContinuousLinearMap.comp _ _ _ _ _ _ (RingHom.id _) (RingHom.id _) (RingHom.id _) _ _ _ _ _ _ _ _
_ _ _ _ RingHomCompTriple.ids
@[simp, norm_cast]
theorem coe_comp (h : M₂ →SL[σ₂₃] M₃) (f : M₁ →SL[σ₁₂] M₂) :
(h.comp f : M₁ →ₛₗ[σ₁₃] M₃) = (h : M₂ →ₛₗ[σ₂₃] M₃).comp (f : M₁ →ₛₗ[σ₁₂] M₂) :=
rfl
#align continuous_linear_map.coe_comp ContinuousLinearMap.coe_comp
@[simp, norm_cast]
theorem coe_comp' (h : M₂ →SL[σ₂₃] M₃) (f : M₁ →SL[σ₁₂] M₂) : ⇑(h.comp f) = h ∘ f :=
rfl
#align continuous_linear_map.coe_comp' ContinuousLinearMap.coe_comp'
theorem comp_apply (g : M₂ →SL[σ₂₃] M₃) (f : M₁ →SL[σ₁₂] M₂) (x : M₁) : (g.comp f) x = g (f x) :=
rfl
#align continuous_linear_map.comp_apply ContinuousLinearMap.comp_apply
@[simp]
theorem comp_id (f : M₁ →SL[σ₁₂] M₂) : f.comp (id R₁ M₁) = f :=
ext fun _x => rfl
#align continuous_linear_map.comp_id ContinuousLinearMap.comp_id
@[simp]
theorem id_comp (f : M₁ →SL[σ₁₂] M₂) : (id R₂ M₂).comp f = f :=
ext fun _x => rfl
#align continuous_linear_map.id_comp ContinuousLinearMap.id_comp
@[simp]
theorem comp_zero (g : M₂ →SL[σ₂₃] M₃) : g.comp (0 : M₁ →SL[σ₁₂] M₂) = 0 := by
ext
simp
#align continuous_linear_map.comp_zero ContinuousLinearMap.comp_zero
@[simp]
theorem zero_comp (f : M₁ →SL[σ₁₂] M₂) : (0 : M₂ →SL[σ₂₃] M₃).comp f = 0 := by
ext
simp
#align continuous_linear_map.zero_comp ContinuousLinearMap.zero_comp
@[simp]
theorem comp_add [ContinuousAdd M₂] [ContinuousAdd M₃] (g : M₂ →SL[σ₂₃] M₃)
(f₁ f₂ : M₁ →SL[σ₁₂] M₂) : g.comp (f₁ + f₂) = g.comp f₁ + g.comp f₂ := by
ext
simp
#align continuous_linear_map.comp_add ContinuousLinearMap.comp_add
@[simp]
theorem add_comp [ContinuousAdd M₃] (g₁ g₂ : M₂ →SL[σ₂₃] M₃) (f : M₁ →SL[σ₁₂] M₂) :
(g₁ + g₂).comp f = g₁.comp f + g₂.comp f := by
ext
simp
#align continuous_linear_map.add_comp ContinuousLinearMap.add_comp
theorem comp_assoc {R₄ : Type*} [Semiring R₄] [Module R₄ M₄] {σ₁₄ : R₁ →+* R₄} {σ₂₄ : R₂ →+* R₄}
{σ₃₄ : R₃ →+* R₄} [RingHomCompTriple σ₁₃ σ₃₄ σ₁₄] [RingHomCompTriple σ₂₃ σ₃₄ σ₂₄]
[RingHomCompTriple σ₁₂ σ₂₄ σ₁₄] (h : M₃ →SL[σ₃₄] M₄) (g : M₂ →SL[σ₂₃] M₃) (f : M₁ →SL[σ₁₂] M₂) :
(h.comp g).comp f = h.comp (g.comp f) :=
rfl
#align continuous_linear_map.comp_assoc ContinuousLinearMap.comp_assoc
instance instMul : Mul (M₁ →L[R₁] M₁) :=
⟨comp⟩
#align continuous_linear_map.has_mul ContinuousLinearMap.instMul
theorem mul_def (f g : M₁ →L[R₁] M₁) : f * g = f.comp g :=
rfl
#align continuous_linear_map.mul_def ContinuousLinearMap.mul_def
@[simp]
theorem coe_mul (f g : M₁ →L[R₁] M₁) : ⇑(f * g) = f ∘ g :=
rfl
#align continuous_linear_map.coe_mul ContinuousLinearMap.coe_mul
theorem mul_apply (f g : M₁ →L[R₁] M₁) (x : M₁) : (f * g) x = f (g x) :=
rfl
#align continuous_linear_map.mul_apply ContinuousLinearMap.mul_apply
instance monoidWithZero : MonoidWithZero (M₁ →L[R₁] M₁) where
mul_zero f := ext fun _ => map_zero f
zero_mul _ := ext fun _ => rfl
mul_one _ := ext fun _ => rfl
one_mul _ := ext fun _ => rfl
mul_assoc _ _ _ := ext fun _ => rfl
#align continuous_linear_map.monoid_with_zero ContinuousLinearMap.monoidWithZero
theorem coe_pow (f : M₁ →L[R₁] M₁) (n : ℕ) : ⇑(f ^ n) = f^[n] :=
hom_coe_pow _ rfl (fun _ _ ↦ rfl) _ _
instance instNatCast [ContinuousAdd M₁] : NatCast (M₁ →L[R₁] M₁) where
natCast n := n • (1 : M₁ →L[R₁] M₁)
instance semiring [ContinuousAdd M₁] : Semiring (M₁ →L[R₁] M₁) where
__ := ContinuousLinearMap.monoidWithZero
__ := ContinuousLinearMap.addCommMonoid
left_distrib f g h := ext fun x => map_add f (g x) (h x)
right_distrib _ _ _ := ext fun _ => LinearMap.add_apply _ _ _
toNatCast := instNatCast
natCast_zero := zero_smul ℕ (1 : M₁ →L[R₁] M₁)
natCast_succ n := AddMonoid.nsmul_succ n (1 : M₁ →L[R₁] M₁)
#align continuous_linear_map.semiring ContinuousLinearMap.semiring
/-- `ContinuousLinearMap.toLinearMap` as a `RingHom`. -/
@[simps]
def toLinearMapRingHom [ContinuousAdd M₁] : (M₁ →L[R₁] M₁) →+* M₁ →ₗ[R₁] M₁ where
toFun := toLinearMap
map_zero' := rfl
map_one' := rfl
map_add' _ _ := rfl
map_mul' _ _ := rfl
#align continuous_linear_map.to_linear_map_ring_hom ContinuousLinearMap.toLinearMapRingHom
#align continuous_linear_map.to_linear_map_ring_hom_apply ContinuousLinearMap.toLinearMapRingHom_apply
@[simp]
theorem natCast_apply [ContinuousAdd M₁] (n : ℕ) (m : M₁) : (↑n : M₁ →L[R₁] M₁) m = n • m :=
rfl
@[simp]
theorem ofNat_apply [ContinuousAdd M₁] (n : ℕ) [n.AtLeastTwo] (m : M₁) :
((no_index (OfNat.ofNat n) : M₁ →L[R₁] M₁)) m = OfNat.ofNat n • m :=
rfl
section ApplyAction
variable [ContinuousAdd M₁]
/-- The tautological action by `M₁ →L[R₁] M₁` on `M`.
This generalizes `Function.End.applyMulAction`. -/
instance applyModule : Module (M₁ →L[R₁] M₁) M₁ :=
Module.compHom _ toLinearMapRingHom
#align continuous_linear_map.apply_module ContinuousLinearMap.applyModule
@[simp]
protected theorem smul_def (f : M₁ →L[R₁] M₁) (a : M₁) : f • a = f a :=
rfl
#align continuous_linear_map.smul_def ContinuousLinearMap.smul_def
/-- `ContinuousLinearMap.applyModule` is faithful. -/
instance applyFaithfulSMul : FaithfulSMul (M₁ →L[R₁] M₁) M₁ :=
⟨fun {_ _} => ContinuousLinearMap.ext⟩
#align continuous_linear_map.apply_has_faithful_smul ContinuousLinearMap.applyFaithfulSMul
instance applySMulCommClass : SMulCommClass R₁ (M₁ →L[R₁] M₁) M₁ where
smul_comm r e m := (e.map_smul r m).symm
#align continuous_linear_map.apply_smul_comm_class ContinuousLinearMap.applySMulCommClass
instance applySMulCommClass' : SMulCommClass (M₁ →L[R₁] M₁) R₁ M₁ where
smul_comm := ContinuousLinearMap.map_smul
#align continuous_linear_map.apply_smul_comm_class' ContinuousLinearMap.applySMulCommClass'
instance continuousConstSMul_apply : ContinuousConstSMul (M₁ →L[R₁] M₁) M₁ :=
⟨ContinuousLinearMap.continuous⟩
#align continuous_linear_map.has_continuous_const_smul ContinuousLinearMap.continuousConstSMul_apply
end ApplyAction
/-- The cartesian product of two bounded linear maps, as a bounded linear map. -/
protected def prod [Module R₁ M₂] [Module R₁ M₃] (f₁ : M₁ →L[R₁] M₂) (f₂ : M₁ →L[R₁] M₃) :
M₁ →L[R₁] M₂ × M₃ :=
⟨(f₁ : M₁ →ₗ[R₁] M₂).prod f₂, f₁.2.prod_mk f₂.2⟩
#align continuous_linear_map.prod ContinuousLinearMap.prod
@[simp, norm_cast]
theorem coe_prod [Module R₁ M₂] [Module R₁ M₃] (f₁ : M₁ →L[R₁] M₂) (f₂ : M₁ →L[R₁] M₃) :
(f₁.prod f₂ : M₁ →ₗ[R₁] M₂ × M₃) = LinearMap.prod f₁ f₂ :=
rfl
#align continuous_linear_map.coe_prod ContinuousLinearMap.coe_prod
@[simp, norm_cast]
theorem prod_apply [Module R₁ M₂] [Module R₁ M₃] (f₁ : M₁ →L[R₁] M₂) (f₂ : M₁ →L[R₁] M₃) (x : M₁) :
f₁.prod f₂ x = (f₁ x, f₂ x) :=
rfl
#align continuous_linear_map.prod_apply ContinuousLinearMap.prod_apply
section
variable (R₁ M₁ M₂)
/-- The left injection into a product is a continuous linear map. -/
def inl [Module R₁ M₂] : M₁ →L[R₁] M₁ × M₂ :=
(id R₁ M₁).prod 0
#align continuous_linear_map.inl ContinuousLinearMap.inl
/-- The right injection into a product is a continuous linear map. -/
def inr [Module R₁ M₂] : M₂ →L[R₁] M₁ × M₂ :=
(0 : M₂ →L[R₁] M₁).prod (id R₁ M₂)
#align continuous_linear_map.inr ContinuousLinearMap.inr
end
variable {F : Type*}
@[simp]
theorem inl_apply [Module R₁ M₂] (x : M₁) : inl R₁ M₁ M₂ x = (x, 0) :=
rfl
#align continuous_linear_map.inl_apply ContinuousLinearMap.inl_apply
@[simp]
theorem inr_apply [Module R₁ M₂] (x : M₂) : inr R₁ M₁ M₂ x = (0, x) :=
rfl
#align continuous_linear_map.inr_apply ContinuousLinearMap.inr_apply
@[simp, norm_cast]
theorem coe_inl [Module R₁ M₂] : (inl R₁ M₁ M₂ : M₁ →ₗ[R₁] M₁ × M₂) = LinearMap.inl R₁ M₁ M₂ :=
rfl
#align continuous_linear_map.coe_inl ContinuousLinearMap.coe_inl
@[simp, norm_cast]
theorem coe_inr [Module R₁ M₂] : (inr R₁ M₁ M₂ : M₂ →ₗ[R₁] M₁ × M₂) = LinearMap.inr R₁ M₁ M₂ :=
rfl
#align continuous_linear_map.coe_inr ContinuousLinearMap.coe_inr
theorem isClosed_ker [T1Space M₂] [FunLike F M₁ M₂] [ContinuousSemilinearMapClass F σ₁₂ M₁ M₂]
(f : F) :
IsClosed (ker f : Set M₁) :=