-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathBasic.lean
More file actions
1422 lines (1148 loc) · 62.1 KB
/
Basic.lean
File metadata and controls
1422 lines (1148 loc) · 62.1 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
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) 2017 Johannes Hölzl. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Johannes Hölzl
! This file was ported from Lean 3 source module topology.algebra.infinite_sum.basic
! leanprover-community/mathlib commit 32253a1a1071173b33dc7d6a218cf722c6feb514
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathlib.Data.Nat.Parity
import Mathlib.Logic.Encodable.Lattice
import Mathlib.Topology.Algebra.UniformGroup
import Mathlib.Topology.Algebra.Star
/-!
# Infinite sum over a topological monoid
This sum is known as unconditionally convergent, as it sums to the same value under all possible
permutations. For Euclidean spaces (finite dimensional Banach spaces) this is equivalent to absolute
convergence.
Note: There are summable sequences which are not unconditionally convergent! The other way holds
generally, see `HasSum.tendsto_sum_nat`.
## References
* Bourbaki: General Topology (1995), Chapter 3 §5 (Infinite sums in commutative groups)
-/
noncomputable section
open Classical Filter Finset Function
open BigOperators Classical Topology
variable {α : Type _} {β : Type _} {γ : Type _} {δ : Type _}
section HasSum
variable [AddCommMonoid α] [TopologicalSpace α]
/-- Infinite sum on a topological monoid
The `atTop` filter on `Finset β` is the limit of all finite sets towards the entire type. So we sum
up bigger and bigger sets. This sum operation is invariant under reordering. In particular,
the function `ℕ → ℝ` sending `n` to `(-1)^n / (n+1)` does not have a
sum for this definition, but a series which is absolutely convergent will have the correct sum.
This is based on Mario Carneiro's
[infinite sum `df-tsms` in Metamath](http://us.metamath.org/mpeuni/df-tsms.html).
For the definition or many statements, `α` does not need to be a topological monoid. We only add
this assumption later, for the lemmas where it is relevant.
-/
def HasSum (f : β → α) (a : α) : Prop :=
Tendsto (fun s : Finset β => ∑ b in s, f b) atTop (𝓝 a)
#align has_sum HasSum
/-- `Summable f` means that `f` has some (infinite) sum. Use `tsum` to get the value. -/
def Summable (f : β → α) : Prop :=
∃ a, HasSum f a
#align summable Summable
-- Porting note: `irreducible_def` produces a structure.
-- When a structure is defined, an injectivity theorem of the constructor is
-- generated, which has `simp` attr, but this get a `simpNF` linter.
-- So, this option is required.
set_option genInjectivity false in
/-- `∑' i, f i` is the sum of `f` it exists, or 0 otherwise -/
irreducible_def tsum {β} (f : β → α) :=
if h : Summable f then Classical.choose h else 0
#align tsum tsum
-- see Note [operator precedence of big operators]
@[inherit_doc tsum]
notation3"∑' "(...)", "r:(scoped f => tsum f) => r
variable {f g : β → α} {a b : α} {s : Finset β}
theorem Summable.hasSum (ha : Summable f) : HasSum f (∑' b, f b) := by
simp only [tsum_def, ha, dite_true]
exact Classical.choose_spec ha
#align summable.has_sum Summable.hasSum
theorem HasSum.summable (h : HasSum f a) : Summable f :=
⟨a, h⟩
#align has_sum.summable HasSum.summable
/-- Constant zero function has sum `0` -/
theorem hasSum_zero : HasSum (fun _ => 0 : β → α) 0 := by simp [HasSum, tendsto_const_nhds]
#align has_sum_zero hasSum_zero
theorem hasSum_empty [IsEmpty β] : HasSum f 0 := by
convert @hasSum_zero α β _ _
#align has_sum_empty hasSum_empty
theorem summable_zero : Summable (fun _ => 0 : β → α) :=
hasSum_zero.summable
#align summable_zero summable_zero
theorem summable_empty [IsEmpty β] : Summable f :=
hasSum_empty.summable
#align summable_empty summable_empty
theorem tsum_eq_zero_of_not_summable (h : ¬Summable f) : (∑' b, f b) = 0 := by simp [tsum_def, h]
#align tsum_eq_zero_of_not_summable tsum_eq_zero_of_not_summable
theorem summable_congr (hfg : ∀ b, f b = g b) : Summable f ↔ Summable g :=
iff_of_eq (congr_arg Summable <| funext hfg)
#align summable_congr summable_congr
theorem Summable.congr (hf : Summable f) (hfg : ∀ b, f b = g b) : Summable g :=
(summable_congr hfg).mp hf
#align summable.congr Summable.congr
theorem HasSum.hasSum_of_sum_eq {g : γ → α}
(h_eq :
∀ u : Finset γ,
∃ v : Finset β, ∀ v', v ⊆ v' → ∃ u', u ⊆ u' ∧ (∑ x in u', g x) = ∑ b in v', f b)
(hf : HasSum g a) : HasSum f a :=
le_trans (map_atTop_finset_sum_le_of_sum_eq h_eq) hf
#align has_sum.has_sum_of_sum_eq HasSum.hasSum_of_sum_eq
theorem hasSum_iff_hasSum {g : γ → α}
(h₁ :
∀ u : Finset γ,
∃ v : Finset β, ∀ v', v ⊆ v' → ∃ u', u ⊆ u' ∧ (∑ x in u', g x) = ∑ b in v', f b)
(h₂ :
∀ v : Finset β,
∃ u : Finset γ, ∀ u', u ⊆ u' → ∃ v', v ⊆ v' ∧ (∑ b in v', f b) = ∑ x in u', g x) :
HasSum f a ↔ HasSum g a :=
⟨HasSum.hasSum_of_sum_eq h₂, HasSum.hasSum_of_sum_eq h₁⟩
#align has_sum_iff_has_sum hasSum_iff_hasSum
theorem Function.Injective.hasSum_iff {g : γ → β} (hg : Injective g)
(hf : ∀ x, x ∉ Set.range g → f x = 0) : HasSum (f ∘ g) a ↔ HasSum f a := by
simp only [HasSum, Tendsto, comp_apply, hg.map_atTop_finset_sum_eq hf]
#align function.injective.has_sum_iff Function.Injective.hasSum_iff
theorem Function.Injective.summable_iff {g : γ → β} (hg : Injective g)
(hf : ∀ (x) (_ : x ∉ Set.range g), f x = 0) : Summable (f ∘ g) ↔ Summable f :=
exists_congr fun _ => hg.hasSum_iff hf
#align function.injective.summable_iff Function.Injective.summable_iff
@[simp] theorem hasSum_extend_zero {g : β → γ} (hg : Injective g) :
HasSum (extend g f 0) a ↔ HasSum f a := by
rw [← hg.hasSum_iff, extend_comp hg]
exact extend_apply' _ _
@[simp] theorem summable_extend_zero {g : β → γ} (hg : Injective g) :
Summable (extend g f 0) ↔ Summable f :=
exists_congr fun _ => hasSum_extend_zero hg
theorem hasSum_subtype_iff_of_support_subset {s : Set β} (hf : support f ⊆ s) :
HasSum (f ∘ (↑) : s → α) a ↔ HasSum f a :=
Subtype.coe_injective.hasSum_iff <| by simpa using support_subset_iff'.1 hf
#align has_sum_subtype_iff_of_support_subset hasSum_subtype_iff_of_support_subset
theorem hasSum_subtype_iff_indicator {s : Set β} :
HasSum (f ∘ (↑) : s → α) a ↔ HasSum (s.indicator f) a := by
rw [← Set.indicator_range_comp, Subtype.range_coe,
hasSum_subtype_iff_of_support_subset Set.support_indicator_subset]
#align has_sum_subtype_iff_indicator hasSum_subtype_iff_indicator
theorem summable_subtype_iff_indicator {s : Set β} :
Summable (f ∘ (↑) : s → α) ↔ Summable (s.indicator f) :=
exists_congr fun _ => hasSum_subtype_iff_indicator
#align summable_subtype_iff_indicator summable_subtype_iff_indicator
@[simp]
theorem hasSum_subtype_support : HasSum (f ∘ (↑) : support f → α) a ↔ HasSum f a :=
hasSum_subtype_iff_of_support_subset <| Set.Subset.refl _
#align has_sum_subtype_support hasSum_subtype_support
theorem hasSum_fintype [Fintype β] (f : β → α) : HasSum f (∑ b, f b) :=
OrderTop.tendsto_atTop_nhds _
#align has_sum_fintype hasSum_fintype
protected theorem Finset.hasSum (s : Finset β) (f : β → α) :
HasSum (f ∘ (↑) : (↑s : Set β) → α) (∑ b in s, f b) := by
rw [← sum_attach]
exact hasSum_fintype _
#align finset.has_sum Finset.hasSum
protected theorem Finset.summable (s : Finset β) (f : β → α) :
Summable (f ∘ (↑) : (↑s : Set β) → α) :=
(s.hasSum f).summable
#align finset.summable Finset.summable
protected theorem Set.Finite.summable {s : Set β} (hs : s.Finite) (f : β → α) :
Summable (f ∘ (↑) : s → α) := by
have := hs.toFinset.summable f
rwa [hs.coe_toFinset] at this
#align set.finite.summable Set.Finite.summable
/-- If a function `f` vanishes outside of a finite set `s`, then it `HasSum` `∑ b in s, f b`. -/
theorem hasSum_sum_of_ne_finset_zero (hf : ∀ (b) (_ : b ∉ s), f b = 0) : HasSum f (∑ b in s, f b) :=
(hasSum_subtype_iff_of_support_subset <| support_subset_iff'.2 hf).1 <| s.hasSum f
#align has_sum_sum_of_ne_finset_zero hasSum_sum_of_ne_finset_zero
theorem summable_of_ne_finset_zero (hf : ∀ (b) (_ : b ∉ s), f b = 0) : Summable f :=
(hasSum_sum_of_ne_finset_zero hf).summable
#align summable_of_ne_finset_zero summable_of_ne_finset_zero
theorem hasSum_single {f : β → α} (b : β) (hf : ∀ (b') (_ : b' ≠ b), f b' = 0) : HasSum f (f b) :=
suffices HasSum f (∑ b' in {b}, f b') by simpa using this
hasSum_sum_of_ne_finset_zero <| by simpa [hf]
#align has_sum_single hasSum_single
theorem hasSum_ite_eq (b : β) [DecidablePred (· = b)] (a : α) :
HasSum (fun b' => if b' = b then a else 0) a := by
convert @hasSum_single _ _ _ _ (fun b' => if b' = b then a else 0) b (fun b' hb' => if_neg hb')
exact (if_pos rfl).symm
#align has_sum_ite_eq hasSum_ite_eq
theorem hasSum_pi_single [DecidableEq β] (b : β) (a : α) : HasSum (Pi.single b a) a := by
convert hasSum_ite_eq b a
simp [Pi.single_apply]
#align has_sum_pi_single hasSum_pi_single
theorem Equiv.hasSum_iff (e : γ ≃ β) : HasSum (f ∘ e) a ↔ HasSum f a :=
e.injective.hasSum_iff <| by simp
#align equiv.has_sum_iff Equiv.hasSum_iff
theorem Function.Injective.hasSum_range_iff {g : γ → β} (hg : Injective g) :
HasSum (fun x : Set.range g => f x) a ↔ HasSum (f ∘ g) a :=
(Equiv.ofInjective g hg).hasSum_iff.symm
#align function.injective.has_sum_range_iff Function.Injective.hasSum_range_iff
theorem Equiv.summable_iff (e : γ ≃ β) : Summable (f ∘ e) ↔ Summable f :=
exists_congr fun _ => e.hasSum_iff
#align equiv.summable_iff Equiv.summable_iff
theorem Summable.prod_symm {f : β × γ → α} (hf : Summable f) : Summable fun p : γ × β => f p.swap :=
(Equiv.prodComm γ β).summable_iff.2 hf
#align summable.prod_symm Summable.prod_symm
theorem Equiv.hasSum_iff_of_support {g : γ → α} (e : support f ≃ support g)
(he : ∀ x : support f, g (e x) = f x) : HasSum f a ↔ HasSum g a := by
have : (g ∘ (↑)) ∘ e = f ∘ (↑) := funext he
rw [← hasSum_subtype_support, ← this, e.hasSum_iff, hasSum_subtype_support]
#align equiv.has_sum_iff_of_support Equiv.hasSum_iff_of_support
theorem hasSum_iff_hasSum_of_ne_zero_bij {g : γ → α} (i : support g → β)
(hi : ∀ ⦃x y⦄, i x = i y → (x : γ) = y) (hf : support f ⊆ Set.range i)
(hfg : ∀ x, f (i x) = g x) : HasSum f a ↔ HasSum g a :=
Iff.symm <|
Equiv.hasSum_iff_of_support
(Equiv.ofBijective (fun x => ⟨i x, fun hx => x.coe_prop <| hfg x ▸ hx⟩)
⟨fun _ _ h => Subtype.ext <| hi <| Subtype.ext_iff.1 h, fun y =>
(hf y.coe_prop).imp fun _ hx => Subtype.ext hx⟩)
hfg
#align has_sum_iff_has_sum_of_ne_zero_bij hasSum_iff_hasSum_of_ne_zero_bij
theorem Equiv.summable_iff_of_support {g : γ → α} (e : support f ≃ support g)
(he : ∀ x : support f, g (e x) = f x) : Summable f ↔ Summable g :=
exists_congr fun _ => e.hasSum_iff_of_support he
#align equiv.summable_iff_of_support Equiv.summable_iff_of_support
protected theorem HasSum.map [AddCommMonoid γ] [TopologicalSpace γ] (hf : HasSum f a) {G}
[AddMonoidHomClass G α γ] (g : G) (hg : Continuous g) : HasSum (g ∘ f) (g a) :=
have : (g ∘ fun s : Finset β => ∑ b in s, f b) = fun s : Finset β => ∑ b in s, g (f b) :=
funext <| map_sum g _
show Tendsto (fun s : Finset β => ∑ b in s, g (f b)) atTop (𝓝 (g a)) from
this ▸ (hg.tendsto a).comp hf
#align has_sum.map HasSum.map
protected theorem Summable.map [AddCommMonoid γ] [TopologicalSpace γ] (hf : Summable f) {G}
[AddMonoidHomClass G α γ] (g : G) (hg : Continuous g) : Summable (g ∘ f) :=
(hf.hasSum.map g hg).summable
#align summable.map Summable.map
protected theorem Summable.map_iff_of_leftInverse [AddCommMonoid γ] [TopologicalSpace γ] {G G'}
[AddMonoidHomClass G α γ] [AddMonoidHomClass G' γ α] (g : G) (g' : G') (hg : Continuous g)
(hg' : Continuous g') (hinv : Function.LeftInverse g' g) : Summable (g ∘ f) ↔ Summable f :=
⟨fun h => by
have := h.map _ hg'
rwa [← Function.comp.assoc, hinv.id] at this, fun h => h.map _ hg⟩
#align summable.map_iff_of_left_inverse Summable.map_iff_of_leftInverse
/-- A special case of `Summable.map_iff_of_leftInverse` for convenience -/
protected theorem Summable.map_iff_of_equiv [AddCommMonoid γ] [TopologicalSpace γ] {G}
[AddEquivClass G α γ] (g : G) (hg : Continuous g)
(hg' : Continuous (AddEquivClass.toEquivLike.inv g : γ → α)) : Summable (g ∘ f) ↔ Summable f :=
Summable.map_iff_of_leftInverse g (g : α ≃+ γ).symm hg hg' (AddEquivClass.toEquivLike.left_inv g)
#align summable.map_iff_of_equiv Summable.map_iff_of_equiv
/-- If `f : ℕ → α` has sum `a`, then the partial sums `∑_{i=0}^{n-1} f i` converge to `a`. -/
theorem HasSum.tendsto_sum_nat {f : ℕ → α} (h : HasSum f a) :
Tendsto (fun n : ℕ => ∑ i in range n, f i) atTop (𝓝 a) :=
h.comp tendsto_finset_range
#align has_sum.tendsto_sum_nat HasSum.tendsto_sum_nat
theorem HasSum.unique {a₁ a₂ : α} [T2Space α] : HasSum f a₁ → HasSum f a₂ → a₁ = a₂ :=
tendsto_nhds_unique
#align has_sum.unique HasSum.unique
theorem Summable.hasSum_iff_tendsto_nat [T2Space α] {f : ℕ → α} {a : α} (hf : Summable f) :
HasSum f a ↔ Tendsto (fun n : ℕ => ∑ i in range n, f i) atTop (𝓝 a) := by
refine' ⟨fun h => h.tendsto_sum_nat, fun h => _⟩
rw [tendsto_nhds_unique h hf.hasSum.tendsto_sum_nat]
exact hf.hasSum
#align summable.has_sum_iff_tendsto_nat Summable.hasSum_iff_tendsto_nat
theorem Function.Surjective.summable_iff_of_hasSum_iff {α' : Type _} [AddCommMonoid α']
[TopologicalSpace α'] {e : α' → α} (hes : Function.Surjective e) {f : β → α} {g : γ → α'}
(he : ∀ {a}, HasSum f (e a) ↔ HasSum g a) : Summable f ↔ Summable g :=
hes.exists.trans <| exists_congr <| @he
#align function.surjective.summable_iff_of_has_sum_iff Function.Surjective.summable_iff_of_hasSum_iff
variable [ContinuousAdd α]
theorem HasSum.add (hf : HasSum f a) (hg : HasSum g b) : HasSum (fun b => f b + g b) (a + b) := by
dsimp only [HasSum] at hf hg ⊢
simp_rw [sum_add_distrib]
exact hf.add hg
#align has_sum.add HasSum.add
theorem Summable.add (hf : Summable f) (hg : Summable g) : Summable fun b => f b + g b :=
(hf.hasSum.add hg.hasSum).summable
#align summable.add Summable.add
theorem hasSum_sum {f : γ → β → α} {a : γ → α} {s : Finset γ} :
(∀ i ∈ s, HasSum (f i) (a i)) → HasSum (fun b => ∑ i in s, f i b) (∑ i in s, a i) :=
Finset.induction_on s (by simp only [hasSum_zero, sum_empty, forall_true_iff]) <| by
-- Porting note: with some help, `simp` used to be able to close the goal
simp (config := { contextual := true }) only [mem_insert, forall_eq_or_imp, not_false_iff,
sum_insert, and_imp]
exact fun x s _ IH hx h ↦ hx.add (IH h)
#align has_sum_sum hasSum_sum
theorem summable_sum {f : γ → β → α} {s : Finset γ} (hf : ∀ i ∈ s, Summable (f i)) :
Summable fun b => ∑ i in s, f i b :=
(hasSum_sum fun i hi => (hf i hi).hasSum).summable
#align summable_sum summable_sum
theorem HasSum.add_disjoint {s t : Set β} (hs : Disjoint s t) (ha : HasSum (f ∘ (↑) : s → α) a)
(hb : HasSum (f ∘ (↑) : t → α) b) : HasSum (f ∘ (↑) : (s ∪ t : Set β) → α) (a + b) := by
rw [hasSum_subtype_iff_indicator] at *
rw [Set.indicator_union_of_disjoint hs]
exact ha.add hb
#align has_sum.add_disjoint HasSum.add_disjoint
theorem hasSum_sum_disjoint {ι} (s : Finset ι) {t : ι → Set β} {a : ι → α}
(hs : (s : Set ι).Pairwise (Disjoint on t)) (hf : ∀ i ∈ s, HasSum (f ∘ (↑) : t i → α) (a i)) :
HasSum (f ∘ (↑) : (⋃ i ∈ s, t i) → α) (∑ i in s, a i) := by
simp_rw [hasSum_subtype_iff_indicator] at *
rw [Set.indicator_finset_bunionᵢ _ _ hs]
exact hasSum_sum hf
#align has_sum_sum_disjoint hasSum_sum_disjoint
theorem HasSum.add_isCompl {s t : Set β} (hs : IsCompl s t) (ha : HasSum (f ∘ (↑) : s → α) a)
(hb : HasSum (f ∘ (↑) : t → α) b) : HasSum f (a + b) := by
simpa [← hs.compl_eq] using
(hasSum_subtype_iff_indicator.1 ha).add (hasSum_subtype_iff_indicator.1 hb)
#align has_sum.add_is_compl HasSum.add_isCompl
theorem HasSum.add_compl {s : Set β} (ha : HasSum (f ∘ (↑) : s → α) a)
(hb : HasSum (f ∘ (↑) : (sᶜ : Set β) → α) b) : HasSum f (a + b) :=
ha.add_isCompl isCompl_compl hb
#align has_sum.add_compl HasSum.add_compl
theorem Summable.add_compl {s : Set β} (hs : Summable (f ∘ (↑) : s → α))
(hsc : Summable (f ∘ (↑) : (sᶜ : Set β) → α)) : Summable f :=
(hs.hasSum.add_compl hsc.hasSum).summable
#align summable.add_compl Summable.add_compl
theorem HasSum.compl_add {s : Set β} (ha : HasSum (f ∘ (↑) : (sᶜ : Set β) → α) a)
(hb : HasSum (f ∘ (↑) : s → α) b) : HasSum f (a + b) :=
ha.add_isCompl isCompl_compl.symm hb
#align has_sum.compl_add HasSum.compl_add
theorem HasSum.even_add_odd {f : ℕ → α} (he : HasSum (fun k => f (2 * k)) a)
(ho : HasSum (fun k => f (2 * k + 1)) b) : HasSum f (a + b) := by
have := mul_right_injective₀ (two_ne_zero' ℕ)
replace he := this.hasSum_range_iff.2 he
replace ho := ((add_left_injective 1).comp this).hasSum_range_iff.2 ho
refine' he.add_isCompl _ ho
simpa [(· ∘ ·)] using Nat.isCompl_even_odd
#align has_sum.even_add_odd HasSum.even_add_odd
theorem Summable.compl_add {s : Set β} (hs : Summable (f ∘ (↑) : (sᶜ : Set β) → α))
(hsc : Summable (f ∘ (↑) : s → α)) : Summable f :=
(hs.hasSum.compl_add hsc.hasSum).summable
#align summable.compl_add Summable.compl_add
theorem Summable.even_add_odd {f : ℕ → α} (he : Summable fun k => f (2 * k))
(ho : Summable fun k => f (2 * k + 1)) : Summable f :=
(he.hasSum.even_add_odd ho.hasSum).summable
#align summable.even_add_odd Summable.even_add_odd
theorem HasSum.sigma [RegularSpace α] {γ : β → Type _} {f : (Σ b : β, γ b) → α} {g : β → α} {a : α}
(ha : HasSum f a) (hf : ∀ b, HasSum (fun c => f ⟨b, c⟩) (g b)) : HasSum g a := by
refine' (atTop_basis.tendsto_iff (closed_nhds_basis a)).mpr _
rintro s ⟨hs, hsc⟩
rcases mem_atTop_sets.mp (ha hs) with ⟨u, hu⟩
use u.image Sigma.fst, trivial
intro bs hbs
simp only [Set.mem_preimage, ge_iff_le, Finset.le_iff_subset] at hu
have :
Tendsto (fun t : Finset (Σb, γ b) => ∑ p in t.filter fun p => p.1 ∈ bs, f p) atTop
(𝓝 <| ∑ b in bs, g b) :=
by
simp only [← sigma_preimage_mk, sum_sigma]
refine' tendsto_finset_sum _ fun b _ => _
change
Tendsto (fun t => (fun t => ∑ s in t, f ⟨b, s⟩) (preimage t (Sigma.mk b) _)) atTop (𝓝 (g b))
exact (hf b).comp (tendsto_finset_preimage_atTop_atTop (sigma_mk_injective))
refine' hsc.mem_of_tendsto this (eventually_atTop.2 ⟨u, fun t ht => hu _ fun x hx => _⟩)
exact mem_filter.2 ⟨ht hx, hbs <| mem_image_of_mem _ hx⟩
#align has_sum.sigma HasSum.sigma
/-- If a series `f` on `β × γ` has sum `a` and for each `b` the restriction of `f` to `{b} × γ`
has sum `g b`, then the series `g` has sum `a`. -/
theorem HasSum.prod_fiberwise [RegularSpace α] {f : β × γ → α} {g : β → α} {a : α} (ha : HasSum f a)
(hf : ∀ b, HasSum (fun c => f (b, c)) (g b)) : HasSum g a :=
HasSum.sigma ((Equiv.sigmaEquivProd β γ).hasSum_iff.2 ha) hf
#align has_sum.prod_fiberwise HasSum.prod_fiberwise
theorem Summable.sigma' [RegularSpace α] {γ : β → Type _} {f : (Σb : β, γ b) → α} (ha : Summable f)
(hf : ∀ b, Summable fun c => f ⟨b, c⟩) : Summable fun b => ∑' c, f ⟨b, c⟩ :=
(ha.hasSum.sigma fun b => (hf b).hasSum).summable
#align summable.sigma' Summable.sigma'
theorem HasSum.sigma_of_hasSum [T3Space α] {γ : β → Type _} {f : (Σb : β, γ b) → α} {g : β → α}
{a : α} (ha : HasSum g a) (hf : ∀ b, HasSum (fun c => f ⟨b, c⟩) (g b)) (hf' : Summable f) :
HasSum f a := by simpa [(hf'.hasSum.sigma hf).unique ha] using hf'.hasSum
#align has_sum.sigma_of_has_sum HasSum.sigma_of_hasSum
/-- Version of `HasSum.update` for `AddCommMonoid` rather than `AddCommGroup`.
Rather than showing that `f.update` has a specific sum in terms of `HasSum`,
it gives a relationship between the sums of `f` and `f.update` given that both exist. -/
theorem HasSum.update' {α β : Type _} [TopologicalSpace α] [AddCommMonoid α] [T2Space α]
[ContinuousAdd α] {f : β → α} {a a' : α} (hf : HasSum f a) (b : β) (x : α)
(hf' : HasSum (update f b x) a') : a + x = a' + f b := by
have : ∀ b', f b' + ite (b' = b) x 0 = update f b x b' + ite (b' = b) (f b) 0 :=
by
intro b'
split_ifs with hb'
· simpa only [Function.update_apply, hb', eq_self_iff_true] using add_comm (f b) x
· simp only [Function.update_apply, hb', if_false]
have h := hf.add (hasSum_ite_eq b x)
simp_rw [this] at h
exact HasSum.unique h (hf'.add (hasSum_ite_eq b (f b)))
#align has_sum.update' HasSum.update'
/-- Version of `hasSum_ite_sub_hasSum` for `AddCommMonoid` rather than `AddCommGroup`.
Rather than showing that the `ite` expression has a specific sum in terms of `HasSum`,
it gives a relationship between the sums of `f` and `ite (n = b) 0 (f n)` given that both exist. -/
theorem eq_add_of_hasSum_ite {α β : Type _} [TopologicalSpace α] [AddCommMonoid α] [T2Space α]
[ContinuousAdd α] {f : β → α} {a : α} (hf : HasSum f a) (b : β) (a' : α)
(hf' : HasSum (fun n => ite (n = b) 0 (f n)) a') : a = a' + f b := by
refine' (add_zero a).symm.trans (hf.update' b 0 _)
convert hf'
apply update_apply
#align eq_add_of_has_sum_ite eq_add_of_hasSum_ite
end HasSum
section tsum
variable [AddCommMonoid α] [TopologicalSpace α]
theorem tsum_congr_subtype (f : β → α) {s t : Set β} (h : s = t) :
(∑' x : s, f x) = ∑' x : t, f x := by rw [h]
#align tsum_congr_subtype tsum_congr_subtype
theorem tsum_zero' (hz : IsClosed ({0} : Set α)) : (∑' _b : β, (0 : α)) = 0 := by
classical
rw [tsum_def, dif_pos summable_zero]
suffices ∀ x : α, HasSum (fun _ : β => (0 : α)) x → x = 0 by
exact this _ (Classical.choose_spec _)
intro x hx
contrapose! hx
simp only [HasSum, tendsto_nhds, Finset.sum_const_zero, Filter.mem_atTop_sets, ge_iff_le,
Finset.le_eq_subset, Set.mem_preimage, not_forall, not_exists, exists_prop, exists_and_right]
refine ⟨{0}ᶜ, ⟨isOpen_compl_iff.mpr hz, by simpa [hx] using fun x ↦ ⟨x, subset_refl _⟩⟩⟩
#align tsum_zero' tsum_zero'
@[simp]
theorem tsum_zero [T1Space α] : (∑' _b : β, (0 : α)) = 0 :=
tsum_zero' isClosed_singleton
#align tsum_zero tsum_zero
variable [T2Space α] {f g : β → α} {a a₁ a₂ : α}
theorem HasSum.tsum_eq (ha : HasSum f a) : (∑' b, f b) = a :=
(Summable.hasSum ⟨a, ha⟩).unique ha
#align has_sum.tsum_eq HasSum.tsum_eq
theorem Summable.hasSum_iff (h : Summable f) : HasSum f a ↔ (∑' b, f b) = a :=
Iff.intro HasSum.tsum_eq fun eq => eq ▸ h.hasSum
#align summable.has_sum_iff Summable.hasSum_iff
@[simp]
theorem tsum_empty [IsEmpty β] : (∑' b, f b) = 0 :=
hasSum_empty.tsum_eq
#align tsum_empty tsum_empty
theorem tsum_eq_sum {f : β → α} {s : Finset β} (hf : ∀ (b) (_ : b ∉ s), f b = 0) :
(∑' b, f b) = ∑ b in s, f b :=
(hasSum_sum_of_ne_finset_zero hf).tsum_eq
#align tsum_eq_sum tsum_eq_sum
theorem sum_eq_tsum_indicator (f : β → α) (s : Finset β) :
(∑ x in s, f x) = ∑' x, Set.indicator (↑s) f x :=
have : ∀ (x) (_ : x ∉ s), Set.indicator (↑s) f x = 0 := fun _ hx =>
Set.indicator_apply_eq_zero.2 fun hx' => (hx <| Finset.mem_coe.1 hx').elim
(Finset.sum_congr rfl fun _ hx =>
(Set.indicator_apply_eq_self.2 fun hx' => (hx' <| Finset.mem_coe.2 hx).elim).symm).trans
(tsum_eq_sum this).symm
#align sum_eq_tsum_indicator sum_eq_tsum_indicator
theorem tsum_congr {α β : Type _} [AddCommMonoid α] [TopologicalSpace α] {f g : β → α}
(hfg : ∀ b, f b = g b) : (∑' b, f b) = ∑' b, g b :=
congr_arg tsum (funext hfg)
#align tsum_congr tsum_congr
theorem tsum_fintype [Fintype β] (f : β → α) : (∑' b, f b) = ∑ b, f b :=
(hasSum_fintype f).tsum_eq
#align tsum_fintype tsum_fintype
theorem tsum_bool (f : Bool → α) : (∑' i : Bool, f i) = f False + f True := by
rw [tsum_fintype, Finset.sum_eq_add] <;> simp
#align tsum_bool tsum_bool
theorem tsum_eq_single {f : β → α} (b : β) (hf : ∀ (b') (_ : b' ≠ b), f b' = 0) :
(∑' b, f b) = f b :=
(hasSum_single b hf).tsum_eq
#align tsum_eq_single tsum_eq_single
theorem tsum_tsum_eq_single (f : β → γ → α) (b : β) (c : γ) (hfb : ∀ (b') (_ : b' ≠ b), f b' c = 0)
(hfc : ∀ (b' : β) (c' : γ), c' ≠ c → f b' c' = 0) : (∑' (b') (c'), f b' c') = f b c :=
calc
(∑' (b') (c'), f b' c') = ∑' b', f b' c := tsum_congr fun b' => tsum_eq_single _ (hfc b')
_ = f b c := tsum_eq_single _ hfb
#align tsum_tsum_eq_single tsum_tsum_eq_single
@[simp]
theorem tsum_ite_eq (b : β) [DecidablePred (· = b)] (a : α) :
(∑' b', if b' = b then a else 0) = a :=
(hasSum_ite_eq b a).tsum_eq
#align tsum_ite_eq tsum_ite_eq
@[simp]
theorem tsum_pi_single [DecidableEq β] (b : β) (a : α) : (∑' b', Pi.single b a b') = a :=
(hasSum_pi_single b a).tsum_eq
#align tsum_pi_single tsum_pi_single
theorem tsum_dite_right (P : Prop) [Decidable P] (x : β → ¬P → α) :
(∑' b : β, if h : P then (0 : α) else x b h) = if h : P then (0 : α) else ∑' b : β, x b h := by
by_cases hP : P <;> simp [hP]
#align tsum_dite_right tsum_dite_right
theorem tsum_dite_left (P : Prop) [Decidable P] (x : β → P → α) :
(∑' b : β, if h : P then x b h else 0) = if h : P then ∑' b : β, x b h else 0 := by
by_cases hP : P <;> simp [hP]
#align tsum_dite_left tsum_dite_left
theorem Function.Surjective.tsum_eq_tsum_of_hasSum_iff_hasSum {α' : Type _} [AddCommMonoid α']
[TopologicalSpace α'] {e : α' → α} (hes : Function.Surjective e) (h0 : e 0 = 0) {f : β → α}
{g : γ → α'} (h : ∀ {a}, HasSum f (e a) ↔ HasSum g a) : (∑' b, f b) = e (∑' c, g c) :=
_root_.by_cases (fun x => (h.mpr x.hasSum).tsum_eq) fun hg : ¬Summable g => by
have hf : ¬Summable f := mt (hes.summable_iff_of_hasSum_iff @h).1 hg
simp [tsum_def, hf, hg, h0]
#align function.surjective.tsum_eq_tsum_of_has_sum_iff_has_sum Function.Surjective.tsum_eq_tsum_of_hasSum_iff_hasSum
theorem tsum_eq_tsum_of_hasSum_iff_hasSum {f : β → α} {g : γ → α}
(h : ∀ {a}, HasSum f a ↔ HasSum g a) : (∑' b, f b) = ∑' c, g c :=
surjective_id.tsum_eq_tsum_of_hasSum_iff_hasSum rfl @h
#align tsum_eq_tsum_of_has_sum_iff_has_sum tsum_eq_tsum_of_hasSum_iff_hasSum
theorem Equiv.tsum_eq (j : γ ≃ β) (f : β → α) : (∑' c, f (j c)) = ∑' b, f b :=
tsum_eq_tsum_of_hasSum_iff_hasSum j.hasSum_iff
#align equiv.tsum_eq Equiv.tsum_eq
theorem Equiv.tsum_eq_tsum_of_support {f : β → α} {g : γ → α} (e : support f ≃ support g)
(he : ∀ x, g (e x) = f x) : (∑' x, f x) = ∑' y, g y :=
tsum_eq_tsum_of_hasSum_iff_hasSum (hasSum_iff_of_support e he)
#align equiv.tsum_eq_tsum_of_support Equiv.tsum_eq_tsum_of_support
theorem tsum_eq_tsum_of_ne_zero_bij {g : γ → α} (i : support g → β)
(hi : ∀ ⦃x y⦄, i x = i y → (x : γ) = y) (hf : support f ⊆ Set.range i)
(hfg : ∀ x, f (i x) = g x) : (∑' x, f x) = ∑' y, g y :=
tsum_eq_tsum_of_hasSum_iff_hasSum (hasSum_iff_hasSum_of_ne_zero_bij i hi hf hfg)
#align tsum_eq_tsum_of_ne_zero_bij tsum_eq_tsum_of_ne_zero_bij
/-! ### `tsum` on subsets -/
-- Porting note: Added nolint simpNF, simpNF falsely claims that lhs does not simplify under simp
@[simp, nolint simpNF]
theorem Finset.tsum_subtype (s : Finset β) (f : β → α) :
(∑' x : { x // x ∈ s }, f x) = ∑ x in s, f x :=
(s.hasSum f).tsum_eq
#align finset.tsum_subtype Finset.tsum_subtype
-- Porting note: Added nolint simpNF, simpNF falsely claims that lhs does not simplify under simp
@[simp high, nolint simpNF]
theorem Finset.tsum_subtype' (s : Finset β) (f : β → α) :
(∑' x : (s : Set β), f x) = ∑ x in s, f x :=
s.tsum_subtype f
#align finset.tsum_subtype' Finset.tsum_subtype'
theorem tsum_subtype (s : Set β) (f : β → α) : (∑' x : s, f x) = ∑' x, s.indicator f x :=
tsum_eq_tsum_of_hasSum_iff_hasSum hasSum_subtype_iff_indicator
#align tsum_subtype tsum_subtype
theorem tsum_subtype_eq_of_support_subset {f : β → α} {s : Set β} (hs : support f ⊆ s) :
(∑' x : s, f x) = ∑' x, f x :=
tsum_eq_tsum_of_hasSum_iff_hasSum (hasSum_subtype_iff_of_support_subset hs)
#align tsum_subtype_eq_of_support_subset tsum_subtype_eq_of_support_subset
-- Porting note: Added nolint simpNF, simpNF falsely claims that lhs does not simplify under simp
@[simp, nolint simpNF]
theorem tsum_univ (f : β → α) : (∑' x : (Set.univ : Set β), f x) = ∑' x, f x :=
tsum_subtype_eq_of_support_subset <| Set.subset_univ _
#align tsum_univ tsum_univ
-- Porting note: Added nolint simpNF, simpNF falsely claims that lhs does not simplify under simp
@[simp, nolint simpNF]
theorem tsum_singleton (b : β) (f : β → α) : (∑' x : ({b} : Set β), f x) = f b := by
rw [_root_.tsum_subtype, tsum_eq_single b]
· simp
· intro b' hb'
rw [Set.indicator_of_not_mem]
rwa [Set.mem_singleton_iff]
#align tsum_singleton tsum_singleton
theorem tsum_image {g : γ → β} (f : β → α) {s : Set γ} (hg : Set.InjOn g s) :
(∑' x : g '' s, f x) = ∑' x : s, f (g x) :=
((Equiv.Set.imageOfInjOn _ _ hg).tsum_eq fun x => f x).symm
#align tsum_image tsum_image
theorem tsum_range {g : γ → β} (f : β → α) (hg : Injective g) :
(∑' x : Set.range g, f x) = ∑' x, f (g x) := by
rw [← Set.image_univ, tsum_image f (hg.injOn _)]
simp_rw [← comp_apply (g := g), tsum_univ (f ∘ g)]
#align tsum_range tsum_range
section ContinuousAdd
variable [ContinuousAdd α]
theorem tsum_add (hf : Summable f) (hg : Summable g) :
(∑' b, f b + g b) = (∑' b, f b) + ∑' b, g b :=
(hf.hasSum.add hg.hasSum).tsum_eq
#align tsum_add tsum_add
theorem tsum_sum {f : γ → β → α} {s : Finset γ} (hf : ∀ i ∈ s, Summable (f i)) :
(∑' b, ∑ i in s, f i b) = ∑ i in s, ∑' b, f i b :=
(hasSum_sum fun i hi => (hf i hi).hasSum).tsum_eq
#align tsum_sum tsum_sum
/-- Version of `tsum_eq_add_tsum_ite` for `AddCommMonoid` rather than `AddCommGroup`.
Requires a different convergence assumption involving `Function.update`. -/
theorem tsum_eq_add_tsum_ite' {f : β → α} (b : β) (hf : Summable (update f b 0)) :
(∑' x, f x) = f b + ∑' x, ite (x = b) 0 (f x) :=
calc
(∑' x, f x) = ∑' x, ite (x = b) (f x) 0 + update f b 0 x :=
tsum_congr fun n => by split_ifs with h <;> simp [update_apply, h]
_ = (∑' x, ite (x = b) (f x) 0) + ∑' x, update f b 0 x :=
tsum_add ⟨ite (b = b) (f b) 0, hasSum_single b fun b hb => if_neg hb⟩ hf
_ = ite (b = b) (f b) 0 + ∑' x, update f b 0 x :=
by
congr
exact tsum_eq_single b fun b' hb' => if_neg hb'
_ = f b + ∑' x, ite (x = b) 0 (f x) :=
by simp only [update, eq_self_iff_true, if_true, eq_rec_constant, dite_eq_ite]
#align tsum_eq_add_tsum_ite' tsum_eq_add_tsum_ite'
variable [AddCommMonoid δ] [TopologicalSpace δ] [T3Space δ] [ContinuousAdd δ]
theorem tsum_sigma' {γ : β → Type _} {f : (Σb : β, γ b) → δ} (h₁ : ∀ b, Summable fun c => f ⟨b, c⟩)
(h₂ : Summable f) : (∑' p, f p) = ∑' (b) (c), f ⟨b, c⟩ :=
(h₂.hasSum.sigma fun b => (h₁ b).hasSum).tsum_eq.symm
#align tsum_sigma' tsum_sigma'
theorem tsum_prod' {f : β × γ → δ} (h : Summable f) (h₁ : ∀ b, Summable fun c => f (b, c)) :
(∑' p, f p) = ∑' (b) (c), f (b, c) :=
(h.hasSum.prod_fiberwise fun b => (h₁ b).hasSum).tsum_eq.symm
#align tsum_prod' tsum_prod'
theorem tsum_comm' {f : β → γ → δ} (h : Summable (Function.uncurry f)) (h₁ : ∀ b, Summable (f b))
(h₂ : ∀ c, Summable fun b => f b c) : (∑' (c) (b), f b c) = ∑' (b) (c), f b c := by
erw [← tsum_prod' h h₁, ← tsum_prod' h.prod_symm h₂, ← (Equiv.prodComm γ β).tsum_eq (uncurry f)]
rfl
#align tsum_comm' tsum_comm'
end ContinuousAdd
open Encodable
section Encodable
variable [Encodable γ]
/-- You can compute a sum over an encodably type by summing over the natural numbers and
taking a supremum. This is useful for outer measures. -/
theorem tsum_supᵢ_decode₂ [CompleteLattice β] (m : β → α) (m0 : m ⊥ = 0) (s : γ → β) :
(∑' i : ℕ, m (⨆ b ∈ decode₂ γ i, s b)) = ∑' b : γ, m (s b) := by
have H : ∀ n, m (⨆ b ∈ decode₂ γ n, s b) ≠ 0 → (decode₂ γ n).isSome :=by
intro n h
generalize decode₂ γ n = foo at *
cases' foo with b
. refine' (h <| by simp [m0]).elim
. exact rfl
symm
refine' tsum_eq_tsum_of_ne_zero_bij (fun a => Option.get _ (H a.1 a.2)) _ _ _
· dsimp only []
rintro ⟨m, hm⟩ ⟨n, hn⟩ e
have := mem_decode₂.1 (Option.get_mem (H n hn))
rwa [← e, mem_decode₂.1 (Option.get_mem (H m hm))] at this
· intro b h
refine' ⟨⟨encode b, _⟩, _⟩
· simp only [mem_support, encodek₂] at h⊢
convert h
simp [Set.ext_iff, encodek₂]
· exact Option.get_of_mem _ (encodek₂ _)
· rintro ⟨n, h⟩
dsimp only [Subtype.coe_mk]
trans
swap
rw [show decode₂ γ n = _ from Option.get_mem (H n h)]
congr
simp [ext_iff, -Option.some_get]
#align tsum_supr_decode₂ tsum_supᵢ_decode₂
/-- `tsum_supᵢ_decode₂` specialized to the complete lattice of sets. -/
theorem tsum_unionᵢ_decode₂ (m : Set β → α) (m0 : m ∅ = 0) (s : γ → Set β) :
(∑' i, m (⋃ b ∈ decode₂ γ i, s b)) = ∑' b, m (s b) :=
tsum_supᵢ_decode₂ m m0 s
#align tsum_Union_decode₂ tsum_unionᵢ_decode₂
end Encodable
/-! Some properties about measure-like functions.
These could also be functions defined on complete sublattices of sets, with the property
that they are countably sub-additive.
`R` will probably be instantiated with `(≤)` in all applications.
-/
section Countable
variable [Countable γ]
/-- If a function is countably sub-additive then it is sub-additive on countable types -/
theorem rel_supᵢ_tsum [CompleteLattice β] (m : β → α) (m0 : m ⊥ = 0) (R : α → α → Prop)
(m_supᵢ : ∀ s : ℕ → β, R (m (⨆ i, s i)) (∑' i, m (s i))) (s : γ → β) :
R (m (⨆ b : γ, s b)) (∑' b : γ, m (s b)) := by
cases nonempty_encodable γ
rw [← supᵢ_decode₂, ← tsum_supᵢ_decode₂ _ m0 s]
exact m_supᵢ _
#align rel_supr_tsum rel_supᵢ_tsum
/-- If a function is countably sub-additive then it is sub-additive on finite sets -/
theorem rel_supᵢ_sum [CompleteLattice β] (m : β → α) (m0 : m ⊥ = 0) (R : α → α → Prop)
(m_supᵢ : ∀ s : ℕ → β, R (m (⨆ i, s i)) (∑' i, m (s i))) (s : δ → β) (t : Finset δ) :
R (m (⨆ d ∈ t, s d)) (∑ d in t, m (s d)) := by
rw [supᵢ_subtype', ← Finset.tsum_subtype]
exact rel_supᵢ_tsum m m0 R m_supᵢ _
#align rel_supr_sum rel_supᵢ_sum
/-- If a function is countably sub-additive then it is binary sub-additive -/
theorem rel_sup_add [CompleteLattice β] (m : β → α) (m0 : m ⊥ = 0) (R : α → α → Prop)
(m_supᵢ : ∀ s : ℕ → β, R (m (⨆ i, s i)) (∑' i, m (s i))) (s₁ s₂ : β) :
R (m (s₁ ⊔ s₂)) (m s₁ + m s₂) := by
convert rel_supᵢ_tsum m m0 R m_supᵢ fun b => cond b s₁ s₂
· simp only [supᵢ_bool_eq, cond]
· rw [tsum_fintype, Fintype.sum_bool, cond, cond]
#align rel_sup_add rel_sup_add
end Countable
variable [ContinuousAdd α]
theorem tsum_add_tsum_compl {s : Set β} (hs : Summable (f ∘ (↑) : s → α))
(hsc : Summable (f ∘ (↑) : ↑(sᶜ) → α)) : ((∑' x : s, f x) + ∑' x : ↑(sᶜ), f x) = ∑' x, f x :=
(hs.hasSum.add_compl hsc.hasSum).tsum_eq.symm
#align tsum_add_tsum_compl tsum_add_tsum_compl
theorem tsum_union_disjoint {s t : Set β} (hd : Disjoint s t) (hs : Summable (f ∘ (↑) : s → α))
(ht : Summable (f ∘ (↑) : t → α)) : (∑' x : ↑(s ∪ t), f x) = (∑' x : s, f x) + ∑' x : t, f x :=
(hs.hasSum.add_disjoint hd ht.hasSum).tsum_eq
#align tsum_union_disjoint tsum_union_disjoint
theorem tsum_finset_bUnion_disjoint {ι} {s : Finset ι} {t : ι → Set β}
(hd : (s : Set ι).Pairwise (Disjoint on t)) (hf : ∀ i ∈ s, Summable (f ∘ (↑) : t i → α)) :
(∑' x : ⋃ i ∈ s, t i, f x) = ∑ i in s, ∑' x : t i, f x :=
(hasSum_sum_disjoint _ hd fun i hi => (hf i hi).hasSum).tsum_eq
#align tsum_finset_bUnion_disjoint tsum_finset_bUnion_disjoint
theorem tsum_even_add_odd {f : ℕ → α} (he : Summable fun k => f (2 * k))
(ho : Summable fun k => f (2 * k + 1)) :
((∑' k, f (2 * k)) + ∑' k, f (2 * k + 1)) = ∑' k, f k :=
(he.hasSum.even_add_odd ho.hasSum).tsum_eq.symm
#align tsum_even_add_odd tsum_even_add_odd
end tsum
section TopologicalGroup
variable [AddCommGroup α] [TopologicalSpace α] [TopologicalAddGroup α]
variable {f g : β → α} {a a₁ a₂ : α}
-- `by simpa using` speeds up elaboration. Why?
theorem HasSum.neg (h : HasSum f a) : HasSum (fun b => -f b) (-a) := by
simpa only using h.map (-AddMonoidHom.id α) continuous_neg
#align has_sum.neg HasSum.neg
theorem Summable.neg (hf : Summable f) : Summable fun b => -f b :=
hf.hasSum.neg.summable
#align summable.neg Summable.neg
theorem Summable.of_neg (hf : Summable fun b => -f b) : Summable f := by
simpa only [neg_neg] using hf.neg
#align summable.of_neg Summable.of_neg
theorem summable_neg_iff : (Summable fun b => -f b) ↔ Summable f :=
⟨Summable.of_neg, Summable.neg⟩
#align summable_neg_iff summable_neg_iff
theorem HasSum.sub (hf : HasSum f a₁) (hg : HasSum g a₂) : HasSum (fun b => f b - g b) (a₁ - a₂) :=
by
simp only [sub_eq_add_neg]
exact hf.add hg.neg
#align has_sum.sub HasSum.sub
theorem Summable.sub (hf : Summable f) (hg : Summable g) : Summable fun b => f b - g b :=
(hf.hasSum.sub hg.hasSum).summable
#align summable.sub Summable.sub
theorem Summable.trans_sub (hg : Summable g) (hfg : Summable fun b => f b - g b) : Summable f := by
simpa only [sub_add_cancel] using hfg.add hg
#align summable.trans_sub Summable.trans_sub
theorem summable_iff_of_summable_sub (hfg : Summable fun b => f b - g b) :
Summable f ↔ Summable g :=
⟨fun hf => hf.trans_sub <| by simpa only [neg_sub] using hfg.neg, fun hg => hg.trans_sub hfg⟩
#align summable_iff_of_summable_sub summable_iff_of_summable_sub
theorem HasSum.update (hf : HasSum f a₁) (b : β) [DecidableEq β] (a : α) :
HasSum (update f b a) (a - f b + a₁) := by
convert (hasSum_ite_eq b (a - f b)).add hf
rename_i b'
by_cases h : b' = b
· rw [h, update_same]
simp [eq_self_iff_true, if_true, sub_add_cancel]
. simp only [h, update_noteq, if_false, Ne.def, zero_add, not_false_iff]
#align has_sum.update HasSum.update
theorem Summable.update (hf : Summable f) (b : β) [DecidableEq β] (a : α) :
Summable (update f b a) :=
(hf.hasSum.update b a).summable
#align summable.update Summable.update
theorem HasSum.hasSum_compl_iff {s : Set β} (hf : HasSum (f ∘ (↑) : s → α) a₁) :
HasSum (f ∘ (↑) : ↑(sᶜ) → α) a₂ ↔ HasSum f (a₁ + a₂) := by
refine' ⟨fun h => hf.add_compl h, fun h => _⟩
rw [hasSum_subtype_iff_indicator] at hf⊢
rw [Set.indicator_compl]
simpa only [add_sub_cancel'] using h.sub hf
#align has_sum.has_sum_compl_iff HasSum.hasSum_compl_iff
theorem HasSum.hasSum_iff_compl {s : Set β} (hf : HasSum (f ∘ (↑) : s → α) a₁) :
HasSum f a₂ ↔ HasSum (f ∘ (↑) : ↑(sᶜ) → α) (a₂ - a₁) :=
Iff.symm <| hf.hasSum_compl_iff.trans <| by rw [add_sub_cancel'_right]
#align has_sum.has_sum_iff_compl HasSum.hasSum_iff_compl
theorem Summable.summable_compl_iff {s : Set β} (hf : Summable (f ∘ (↑) : s → α)) :
Summable (f ∘ (↑) : ↑(sᶜ) → α) ↔ Summable f :=
⟨fun ⟨_, ha⟩ => (hf.hasSum.hasSum_compl_iff.1 ha).summable, fun ⟨_, ha⟩ =>
(hf.hasSum.hasSum_iff_compl.1 ha).summable⟩
#align summable.summable_compl_iff Summable.summable_compl_iff
protected theorem Finset.hasSum_compl_iff (s : Finset β) :
HasSum (fun x : { x // x ∉ s } => f x) a ↔ HasSum f (a + ∑ i in s, f i) :=
(s.hasSum f).hasSum_compl_iff.trans <| by rw [add_comm]
#align finset.has_sum_compl_iff Finset.hasSum_compl_iff
protected theorem Finset.hasSum_iff_compl (s : Finset β) :
HasSum f a ↔ HasSum (fun x : { x // x ∉ s } => f x) (a - ∑ i in s, f i) :=
(s.hasSum f).hasSum_iff_compl
#align finset.has_sum_iff_compl Finset.hasSum_iff_compl
protected theorem Finset.summable_compl_iff (s : Finset β) :
(Summable fun x : { x // x ∉ s } => f x) ↔ Summable f :=
(s.summable f).summable_compl_iff
#align finset.summable_compl_iff Finset.summable_compl_iff
theorem Set.Finite.summable_compl_iff {s : Set β} (hs : s.Finite) :
Summable (f ∘ (↑) : ↑(sᶜ) → α) ↔ Summable f :=
(hs.summable f).summable_compl_iff
#align set.finite.summable_compl_iff Set.Finite.summable_compl_iff
theorem hasSum_ite_sub_hasSum [DecidableEq β] (hf : HasSum f a) (b : β) :
HasSum (fun n => ite (n = b) 0 (f n)) (a - f b) := by
convert hf.update b 0 using 1
· ext n
rw [Function.update_apply]
· rw [sub_add_eq_add_sub, zero_add]
#align has_sum_ite_sub_has_sum hasSum_ite_sub_hasSum
section tsum
variable [T2Space α]
theorem tsum_neg : (∑' b, -f b) = -∑' b, f b := by
by_cases hf : Summable f
· exact hf.hasSum.neg.tsum_eq
· simp [tsum_eq_zero_of_not_summable hf, tsum_eq_zero_of_not_summable (mt Summable.of_neg hf)]
#align tsum_neg tsum_neg
theorem tsum_sub (hf : Summable f) (hg : Summable g) :
(∑' b, f b - g b) = (∑' b, f b) - ∑' b, g b :=
(hf.hasSum.sub hg.hasSum).tsum_eq
#align tsum_sub tsum_sub
theorem sum_add_tsum_compl {s : Finset β} (hf : Summable f) :
((∑ x in s, f x) + ∑' x : ↑((s : Set β)ᶜ), f x) = ∑' x, f x :=
((s.hasSum f).add_compl (s.summable_compl_iff.2 hf).hasSum).tsum_eq.symm
#align sum_add_tsum_compl sum_add_tsum_compl
/-- Let `f : β → α` be a sequence with summable series and let `b ∈ β` be an index.
Lemma `tsum_eq_add_tsum_ite` writes `Σ f n` as the sum of `f b` plus the series of the
remaining terms. -/
theorem tsum_eq_add_tsum_ite [DecidableEq β] (hf : Summable f) (b : β) :
(∑' n, f n) = f b + ∑' n, ite (n = b) 0 (f n) := by
rw [(hasSum_ite_sub_hasSum hf.hasSum b).tsum_eq]
exact (add_sub_cancel'_right _ _).symm
#align tsum_eq_add_tsum_ite tsum_eq_add_tsum_ite
end tsum
/-!
### Sums on nat
We show the formula `(∑ i in range k, f i) + (∑' i, f (i + k)) = (∑' i, f i)`, in
`sum_add_tsum_nat_add`, as well as several results relating sums on `ℕ` and `ℤ`.
-/
section Nat
theorem hasSum_nat_add_iff {f : ℕ → α} (k : ℕ) {a : α} :
HasSum (fun n => f (n + k)) a ↔ HasSum f (a + ∑ i in range k, f i) := by
refine' Iff.trans _ (range k).hasSum_compl_iff
rw [← (notMemRangeEquiv k).symm.hasSum_iff]
rfl
#align has_sum_nat_add_iff hasSum_nat_add_iff
theorem summable_nat_add_iff {f : ℕ → α} (k : ℕ) : (Summable fun n => f (n + k)) ↔ Summable f :=
Iff.symm <|
(Equiv.addRight (∑ i in range k, f i)).surjective.summable_iff_of_hasSum_iff
(hasSum_nat_add_iff k).symm
#align summable_nat_add_iff summable_nat_add_iff
theorem hasSum_nat_add_iff' {f : ℕ → α} (k : ℕ) {a : α} :
HasSum (fun n => f (n + k)) (a - ∑ i in range k, f i) ↔ HasSum f a := by
simp [hasSum_nat_add_iff]
#align has_sum_nat_add_iff' hasSum_nat_add_iff'
theorem sum_add_tsum_nat_add [T2Space α] {f : ℕ → α} (k : ℕ) (h : Summable f) :
((∑ i in range k, f i) + ∑' i, f (i + k)) = ∑' i, f i := by
simpa only [add_comm] using
((hasSum_nat_add_iff k).1 ((summable_nat_add_iff k).2 h).hasSum).unique h.hasSum
#align sum_add_tsum_nat_add sum_add_tsum_nat_add
theorem tsum_eq_zero_add [T2Space α] {f : ℕ → α} (hf : Summable f) :
(∑' b, f b) = f 0 + ∑' b, f (b + 1) := by
simpa only [sum_range_one] using (sum_add_tsum_nat_add 1 hf).symm
#align tsum_eq_zero_add tsum_eq_zero_add
/-- For `f : ℕ → α`, then `∑' k, f (k + i)` tends to zero. This does not require a summability
assumption on `f`, as otherwise all sums are zero. -/
theorem tendsto_sum_nat_add [T2Space α] (f : ℕ → α) :
Tendsto (fun i => ∑' k, f (k + i)) atTop (𝓝 0) := by
by_cases hf : Summable f
· have h₀ : (fun i => (∑' i, f i) - ∑ j in range i, f j) = fun i => ∑' k : ℕ, f (k + i) :=
by
ext1 i
rw [sub_eq_iff_eq_add, add_comm, sum_add_tsum_nat_add i hf]
have h₁ : Tendsto (fun _ : ℕ => ∑' i, f i) atTop (𝓝 (∑' i, f i)) := tendsto_const_nhds
simpa only [h₀, sub_self] using Tendsto.sub h₁ hf.hasSum.tendsto_sum_nat
· convert tendsto_const_nhds (α := α) (β := ℕ) (a := 0) (f := atTop)
rename_i i
rw [← summable_nat_add_iff i] at hf
exact tsum_eq_zero_of_not_summable hf
#align tendsto_sum_nat_add tendsto_sum_nat_add
/-- If `f₀, f₁, f₂, ...` and `g₀, g₁, g₂, ...` are both convergent then so is the `ℤ`-indexed
sequence: `..., g₂, g₁, g₀, f₀, f₁, f₂, ...`. -/
theorem HasSum.int_rec {b : α} {f g : ℕ → α} (hf : HasSum f a) (hg : HasSum g b) :
@HasSum α _ _ _ (@Int.rec (fun _ => α) f g : ℤ → α) (a + b) := by