Built with Alectryon, running Coq+SerAPI v8.15.0+0.15.0. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use instead of Ctrl.
(* mathcomp analysis (c) 2017 Inria and AIST. License: CeCILL-C.              *)
Notation "[ predI _ & _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "[ predU _ & _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "[ predD _ & _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "[ predC _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "[ preim _ of _ ]" was already used in scope fun_scope. [notation-overridden,parsing]
Notation "_ + _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ - _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ <= _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ < _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ >= _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ > _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ <= _ <= _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ < _ <= _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ <= _ < _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ < _ < _" was already used in scope nat_scope. [notation-overridden,parsing]
Notation "_ * _" was already used in scope nat_scope. [notation-overridden,parsing]
New coercion path [GRing.subring_closedM; GRing.smulr_closedN] : GRing.subring_closed >-> GRing.oppr_closed is ambiguous with existing [GRing.subring_closedB; GRing.zmod_closedN] : GRing.subring_closed >-> GRing.oppr_closed. [ambiguous-paths,typechecker]
New coercion path [GRing.subring_closed_semi; GRing.semiring_closedM] : GRing.subring_closed >-> GRing.mulr_closed is ambiguous with existing [GRing.subring_closedM; GRing.smulr_closedM] : GRing.subring_closed >-> GRing.mulr_closed. New coercion path [GRing.subring_closed_semi; GRing.semiring_closedD] : GRing.subring_closed >-> GRing.addr_closed is ambiguous with existing [GRing.subring_closedB; GRing.zmod_closedD] : GRing.subring_closed >-> GRing.addr_closed. [ambiguous-paths,typechecker]
New coercion path [GRing.sdivr_closed_div; GRing.divr_closedM] : GRing.sdivr_closed >-> GRing.mulr_closed is ambiguous with existing [GRing.sdivr_closedM; GRing.smulr_closedM] : GRing.sdivr_closed >-> GRing.mulr_closed. [ambiguous-paths,typechecker]
New coercion path [GRing.subalg_closedBM; GRing.subring_closedB] : GRing.subalg_closed >-> GRing.zmod_closed is ambiguous with existing [GRing.subalg_closedZ; GRing.submod_closedB] : GRing.subalg_closed >-> GRing.zmod_closed. [ambiguous-paths,typechecker]
New coercion path [GRing.divring_closed_div; GRing.sdivr_closedM] : GRing.divring_closed >-> GRing.smulr_closed is ambiguous with existing [GRing.divring_closedBM; GRing.subring_closedM] : GRing.divring_closed >-> GRing.smulr_closed. [ambiguous-paths,typechecker]
New coercion path [GRing.divalg_closedBdiv; GRing.divring_closedBM] : GRing.divalg_closed >-> GRing.subring_closed is ambiguous with existing [GRing.divalg_closedZ; GRing.subalg_closedBM] : GRing.divalg_closed >-> GRing.subring_closed. [ambiguous-paths,typechecker]
New coercion path [GRing.Pred.subring_smul; GRing.Pred.smul_mul] : GRing.Pred.subring >-> GRing.Pred.mul is ambiguous with existing [GRing.Pred.subring_semi; GRing.Pred.semiring_mul] : GRing.Pred.subring >-> GRing.Pred.mul. [ambiguous-paths,typechecker]
From mathcomp.classical Require Import boolp classical_sets functions. From mathcomp.classical Require Import cardinality fsbigop mathcomp_extra. Require Import reals ereal signed topology sequences normedtype numfun. (******************************************************************************) (* Summation over classical sets *) (* *) (* This file provides a definition of sum over classical sets and a few *) (* lemmas in particular for the case of sums of non-negative terms. *) (* *) (* fsets S == the set of finite sets (fset) included in S *) (* \esum_(i in I) f i == summation of non-negative extended real numbers over *) (* classical sets; I is a classical set and f is a *) (* function whose codomain is included in the extended *) (* reals; it is 0 if I = set0 and sup(\sum_A a) where A *) (* is a finite set included in I o.w. *) (* summable D f := \esum_(x in D) `| f x | < +oo *) (* *) (******************************************************************************) Reserved Notation "\esum_ ( i 'in' P ) F" (at level 41, F at level 41, format "\esum_ ( i 'in' P ) F"). Set Implicit Arguments. Unset Strict Implicit. Unset Printing Implicit Defensive. Import Order.TTheory GRing.Theory Num.Def Num.Theory. Local Open Scope classical_set_scope. Local Open Scope ring_scope. Local Open Scope ereal_scope. Section set_of_fset_in_a_set. Variable (T : choiceType). Implicit Type S : set T. Definition fsets S : set (set T) := [set F | finite_set F /\ F `<=` S]. Lemma fsets_set0 S : fsets S set0. Proof. by split. Qed. Lemma fsets_self (F : set T) : finite_set F -> fsets F F. Proof. by move=> finF; split. Qed. Lemma fsets0 : fsets set0 = [set set0]. Proof. rewrite predeqE => A; split => [|->]; last exact: fsets_set0. by rewrite /fsets/= subset0 => -[]. Qed. End set_of_fset_in_a_set. Section esum. Variables (R : realFieldType) (T : choiceType). Implicit Types (S : set T) (a : T -> \bar R). Definition esum S a := ereal_sup [set \sum_(x \in A) a x | A in fsets S]. Local Notation "\esum_ ( i 'in' P ) A" := (esum P (fun i => A)). Lemma esum_set0 a : \esum_(i in set0) a i = 0. Proof. rewrite /esum fsets0 [X in ereal_sup X](_ : _ = [set 0%E]) ?ereal_sup1//. apply/seteqP; split=> [x [_ /= ->]|x]; first by rewrite fsbig_set0. by move=> -> /=; exists set0 => //; rewrite fsbig_set0. Qed. End esum. Notation "\esum_ ( i 'in' P ) F" := (esum P (fun i => F)) : ring_scope. Section esum_realType. Variables (R : realType) (T : choiceType). Implicit Types (a : T -> \bar R). Lemma esum_ge0 (S : set T) a : (forall x, S x -> 0 <= a x) -> 0 <= \esum_(i in S) a i. Proof. move=> a0; apply: ereal_sup_ub. by exists set0; [exact: fsets_set0|rewrite fsbig_set0]. Qed. Lemma esum_fset (F : set T) a : finite_set F -> (forall i, i \in F -> 0 <= a i) -> \esum_(i in F) a i = \sum_(i \in F) a i. Proof. move=> finF f0; apply/eqP; rewrite eq_le; apply/andP; split; last first. by apply ereal_sup_ub; exists F => //; exact: fsets_self. apply ub_ereal_sup => /= ? -[F' [finF' F'F] <-]. apply/lee_fsum_nneg_subset => //; first exact/subsetP. by move=> t; rewrite inE/= => /andP[_] /f0. Qed. Lemma esum_set1 t a : 0 <= a t -> \esum_(i in [set t]) a i = a t. Proof. by move=> ?; rewrite esum_fset// ?fset_set1// ?fsbig_set1// => t' /[!inE] ->. Qed. End esum_realType. Lemma esum_ge [R : realType] [T : choiceType] (I : set T) (a : T -> \bar R) x : (exists2 X : set T, fsets I X & x <= \sum_(i \in X) a i) -> x <= \esum_(i in I) a i. Proof. by move=> [X IX /le_trans->//]; apply: ereal_sup_ub => /=; exists X. Qed. Lemma esum1 [R : realFieldType] [I : choiceType] (D : set I) (a : I -> \bar R) : (forall i, D i -> a i = 0) -> \esum_(i in D) a i = 0. Proof. move=> a0; rewrite /esum (_ : [set _ | _ in _] = [set 0]) ?ereal_sup1//. apply/seteqP; split=> x //= => [[X [finX XI]] <-|->]. by rewrite fsbig1// => i /XI/a0. by exists set0; rewrite ?fsbig_set0//; exact: fsets_set0. Qed. Lemma le_esum [R : realType] [T : choiceType] (I : set T) (a b : T -> \bar R) : (forall i, I i -> a i <= b i) -> \esum_(i in I) a i <= \esum_(i in I) b i. Proof. move=> le_ab; rewrite ub_ereal_sup => //= _ [X [finX XI]] <-; rewrite esum_ge//. by exists X => //; apply: lee_fsum => // t /XI /le_ab. Qed. Lemma eq_esum [R : realType] [T : choiceType] (I : set T) (a b : T -> \bar R) : (forall i, I i -> a i = b i) -> \esum_(i in I) a i = \esum_(i in I) b i. Proof. by move=> e; apply/eqP; rewrite eq_le !le_esum// => i Ii; rewrite e. Qed. Lemma esumD [R : realType] [T : choiceType] (I : set T) (a b : T -> \bar R) : (forall i, I i -> 0 <= a i) -> (forall i, I i -> 0 <= b i) -> \esum_(i in I) (a i + b i) = \esum_(i in I) a i + \esum_(i in I) b i. Proof. move=> ag0 bg0; apply/eqP; rewrite eq_le; apply/andP; split. rewrite ub_ereal_sup//= => x [X [finX XI]] <-; rewrite fsbig_split//=. by rewrite lee_add// ereal_sup_ub//=; exists X. wlog : a b ag0 bg0 / \esum_(i in I) a i \isn't a fin_num => [saoo|]; last first. move=> /fin_numPn[->|/[dup] aoo ->]; first by rewrite leNye. rewrite (@le_trans _ _ +oo)//; first by rewrite /adde/=; case: esum. rewrite leye_eq; apply/eqP/eq_infty => y; rewrite esum_ge//. have : y%:E < \esum_(i in I) a i by rewrite aoo// ltry. move=> /ereal_sup_gt[_ [X [finX XI]] <-] /ltW yle; exists X => //=. rewrite (le_trans yle)// fsbig_split// lee_addl// fsume_ge0// => // i. by move=> /XI; exact: bg0. case: (boolP (\esum_(i in I) a i \is a fin_num)) => sa; last exact: saoo. case: (boolP (\esum_(i in I) b i \is a fin_num)) => sb; last first. by rewrite addeC (eq_esum (fun _ _ => addeC _ _)) saoo. rewrite -lee_subr_addr// ub_ereal_sup//= => _ [X [finX XI]] <-. have saX : \sum_(i \in X) a i \is a fin_num. apply: contraTT sa => /fin_numPn[] sa. suff : \sum_(i \in X) a i >= 0 by rewrite sa. by rewrite fsume_ge0// => i /XI/ag0. apply/fin_numPn; right; apply/eqP; rewrite -leye_eq esum_ge//. by exists X; rewrite // sa. rewrite lee_subr_addr// addeC -lee_subr_addr// ub_ereal_sup//= => _ [Y [finY YI]] <-. rewrite lee_subr_addr// addeC esum_ge//; exists (X `|` Y). by split; [rewrite finite_setU|rewrite subUset]. rewrite fsbig_split ?finite_setU//= lee_add// lee_fsum_nneg_subset//= ?finite_setU//. - exact/subsetP/subsetUl. - by move=> x; rewrite !inE in_setU andb_orr andNb/= => /andP[_] /[!inE] /YI/ag0. - exact/subsetP/subsetUr. - by move=> x; rewrite !inE in_setU andb_orr andNb/= orbF => /andP[_] /[!inE] /XI/bg0. Qed. Lemma esum_mkcond [R : realType] [T : choiceType] (I : set T) (a : T -> \bar R) : \esum_(i in I) a i = \esum_(i in [set: T]) if i \in I then a i else 0. Proof. apply/eqP; rewrite eq_le !ub_ereal_sup//= => _ [X [finX XI]] <-. rewrite -big_mkcond/= big_fset_condE/=; set Y := [fset _ | _ in _ & _]%fset. rewrite ereal_sup_ub//=; exists [set` Y]; last by rewrite fsbig_finite// set_fsetK. by split => // i/=; rewrite !inE/= => /andP[_]; rewrite inE. rewrite ereal_sup_ub//; exists X => //; apply: eq_fsbigr => x; rewrite inE => Xx. by rewrite ifT// inE; exact: XI. Qed. Lemma esum_mkcondr [R : realType] [T : choiceType] (I J : set T) (a : T -> \bar R) : \esum_(i in I `&` J) a i = \esum_(i in I) if i \in J then a i else 0. Proof. rewrite esum_mkcond [RHS]esum_mkcond; apply: eq_esum=> i _. by rewrite in_setI; case: (i \in I) (i \in J) => [] []. Qed. Lemma esum_mkcondl [R : realType] [T : choiceType] (I J : set T) (a : T -> \bar R) : \esum_(i in I `&` J) a i = \esum_(i in J) if i \in I then a i else 0. Proof. rewrite esum_mkcond [RHS]esum_mkcond; apply: eq_esum=> i _. by rewrite in_setI; case: (i \in I) (i \in J) => [] []. Qed. Lemma esumID (R : realType) (I : choiceType) (B : set I) (A : set I) (F : I -> \bar R) : (forall i, A i -> F i >= 0) -> \esum_(i in A) F i = (\esum_(i in A `&` B) F i) + (\esum_(i in A `&` ~` B) F i). Proof. move=> F0; rewrite !esum_mkcondr -esumD; do ?by move=> i /F0; case: ifP. by apply: eq_esum=> i; rewrite in_setC; case: ifP; rewrite /= (adde0, add0e). Qed. Arguments esumID {R I}. Lemma esum_sum [R : realType] [T1 T2 : choiceType] (I : set T1) (r : seq T2) (P : pred T2) (a : T1 -> T2 -> \bar R) : (forall i j, I i -> P j -> 0 <= a i j) -> \esum_(i in I) \sum_(j <- r | P j) a i j = \sum_(j <- r | P j) \esum_(i in I) a i j. Proof. move=> a_ge0; elim: r => [|j r IHr]; rewrite ?(big_nil, big_cons)// -?IHr. by rewrite esum1// => i; rewrite big_nil. case: (boolP (P j)) => Pj; last first. by apply: eq_esum => i Ii; rewrite big_cons (negPf Pj). have aj_ge0 i : I i -> a i j >= 0 by move=> ?; apply: a_ge0. rewrite -esumD//; last by move=> i Ii; apply: sume_ge0 => *; apply: a_ge0. by apply: eq_esum => i Ii; rewrite big_cons Pj. Qed. Lemma esum_esum [R : realType] [T1 T2 : choiceType] (I : set T1) (J : T1 -> set T2) (a : T1 -> T2 -> \bar R) : (forall i j, I i -> J i j -> 0 <= a i j) -> \esum_(i in I) \esum_(j in J i) a i j = \esum_(k in I `*`` J) a k.1 k.2. Proof. move=> a_ge0; apply/eqP; rewrite eq_le; apply/andP; split. apply: ub_ereal_sup => /= _ [X [finX XI]] <-. under eq_fsbigr do rewrite esum_mkcond. rewrite fsbig_finite//= big_seq -esum_sum; last first. move=> i j _ /[!in_fset_set]// /[!inE] /XI Ij. by case: ifPn => // /[!inE] /a_ge0-/(_ Ij). under eq_esum do rewrite -big_seq -big_mkcond/=. apply: ub_ereal_sup => /= _ [Y [finY _] <-]; apply: ereal_sup_ub => /=. set XYJ := [set z | z \in X `*` Y /\ z.2 \in J z.1]. have ? : finite_set XYJ. apply: sub_finite_set (finite_setM finX finY) => z/=. by rewrite /XYJ/= in_setM => -[/andP[] /[!inE]]. exists XYJ => /=; first by split => //= z; rewrite /XYJ/= 2!inE=> -[[/XI]]. rewrite [in RHS]fsbig_finite//= (exchange_big_dep xpredT)// pair_big_dep_cond. rewrite fsbig_finite//; apply: eq_fbigl => -[/= x y]; rewrite in_fset_set//. apply/idP/imfset2P. rewrite /XYJ !inE/= !inE/= -andA => -[Xx [Yy Jxy]]. exists x; first by rewrite !inE in_fset_set// mem_set. by exists y => //; rewrite !inE mem_set// in_fset_set// mem_set. move=> [t1]; rewrite !inE andbT/= in_fset_set// inE => Xt1. by move=> [t2]; rewrite !inE in_fset_set /XYJ//= =>/andP[/[!inE] ? ?] [-> ->]. apply: ub_ereal_sup => _ /= [X/= [finX XIJ]] <-; apply: esum_ge. exists X.`1; first by split=> [|x [y /XIJ[]//]]; exact: finite_set_fst. apply: (@le_trans _ _ (\sum_(i <- fset_set X.`1) \sum_(j <- fset_set X.`2 | j \in J i) a i j)). rewrite pair_big_dep_cond//=; set Y := Imfset.imfset2 _ _ _ _. rewrite [leRHS](big_fsetID _ (mem X))/=. rewrite (_ : [fset x | x in Y & x \in X] = Y `&` fset_set X)%fset; last first. by apply/fsetP => x; rewrite 2!inE/= in_fset_set. rewrite (fsetIidPr _). rewrite fsbig_finite// lee_addl// big_seq sume_ge0//=. move=> [x y] /imfsetP[[x1 y1]] /[!inE] /andP[] /imfset2P[x2]/= /[!inE]. rewrite andbT in_fset_set//; last exact: finite_set_fst. move=> /[!inE] x2X [y2] /[!inE] /andP[] /[!in_fset_set]; last first. exact: finite_set_snd. move=> /[!inE] y2X y2J [-> ->] _ [-> ->]; rewrite a_ge0//. by move: x2X => [y3 /XIJ []]. apply/fsubsetP => -[i j]; rewrite in_fset_set// inE => Xij; apply/imfset2P. exists i => /=. rewrite !inE/= in_fset_set//; last exact: finite_set_fst. by rewrite andbT mem_set//; move/fst_set_fst : Xij. exists j => //; rewrite !inE/= in_fset_set; last exact: finite_set_snd. rewrite mem_set/=; last by move/snd_set_snd : Xij. by rewrite mem_set//; move/XIJ : Xij => []. rewrite -fsbig_finite; last exact: finite_set_fst. apply lee_fsum=> [|i Xi]; first exact: finite_set_fst. rewrite ereal_sup_ub => //=; have ? : finite_set (X.`2 `&` J i). by apply: finite_setI; left; exact: finite_set_snd. exists (X.`2 `&` J i) => //. rewrite [in RHS]big_fset_condE/= fsbig_finite//; apply eq_fbigl => j. by rewrite in_fset_set// !inE/= in_setI in_fset_set//; exact: finite_set_snd. Qed. Lemma lee_sum_fset_nat (R : realDomainType) (f : (\bar R)^nat) (F : {fset nat}) n (P : pred nat) : (forall i, P i -> 0%E <= f i) -> [set` F] `<=` `I_n -> \sum_(i <- F | P i) f i <= \sum_(0 <= i < n | P i) f i. Proof. move=> f0 Fn; rewrite [leRHS](bigID (mem F))/=. suff -> : \sum_(0 <= i < n | P i && (i \in F)) f i = \sum_(i <- F | P i) f i. by rewrite lee_addl ?sume_ge0// => i /andP[/f0]. rewrite -big_filter -[RHS]big_filter; apply: perm_big. rewrite uniq_perm ?filter_uniq ?index_iota ?iota_uniq ?fset_uniq//. move=> i; rewrite ?mem_filter. case: (boolP (P i)) => //= Pi; case: (boolP (i \in F)) => //= Fi. by rewrite mem_iota leq0n add0n subn0/=; apply: Fn. Qed. Arguments lee_sum_fset_nat {R f} F n P. Lemma lee_sum_fset_lim (R : realType) (f : (\bar R)^nat) (F : {fset nat}) (P : pred nat) : (forall i, P i -> 0%E <= f i) -> \sum_(i <- F | P i) f i <= \sum_(i <oo | P i) f i. Proof. move=> f0; pose n := (\max_(k <- F) k).+1. rewrite (le_trans (lee_sum_fset_nat F n _ _ _))//; last exact: nneseries_lim_ge. move=> k /= kF; rewrite /n big_seq_fsetE/=. by rewrite -[k]/(val [`kF]%fset) ltnS leq_bigmax. Qed. Arguments lee_sum_fset_lim {R f} F P. Lemma nneseries_esum (R : realType) (a : nat -> \bar R) (P : pred nat) : (forall n, P n -> 0 <= a n) -> \sum_(i <oo | P i) a i = \esum_(i in [set x | P x]) a i. Proof. move=> a0; apply/eqP; rewrite eq_le; apply/andP; split. apply: (lime_le (is_cvg_nneseries_cond a0)); apply: nearW => n. apply: ereal_sup_ub => /=; exists [set` [fset val i | i in 'I_n & P i]%fset]. split; first exact: finite_fset. by move=> /= k /imfsetP[/= i]; rewrite inE => + ->. rewrite fsbig_finite//= set_fsetK big_imfset/=; last by move=> ? ? ? ? /val_inj. by rewrite big_filter big_enum_cond/= big_mkord. apply: ub_ereal_sup => _ [/= F [finF PF] <-]. rewrite fsbig_finite//= -(big_rmcond_in P)/=; first exact: lee_sum_fset_lim. by move=> k; rewrite in_fset_set// inE => /PF ->. Qed. Lemma reindex_esum (R : realType) (T T' : choiceType) (P : set T) (Q : set T') (e : T -> T') (a : T' -> \bar R) : set_bij P Q e -> \esum_(j in Q) a j = \esum_(i in P) a (e i). Proof. elim/choicePpointed: T => T in e P *. rewrite !emptyE => /Pbij[{}e ->]. by rewrite -[in LHS](image_eq e) image_set0 !esum_set0. elim/choicePpointed: T' => T' in a e Q *; first by have := no (e point). move=> /(@pPbij _ _ _)[{}e ->]. gen have le_esum : T T' a P Q e / \esum_(j in Q) a j <= \esum_(i in P) a (e i); last first. apply/eqP; rewrite eq_le le_esum//=. rewrite [leRHS](_ : _ = \esum_(j in Q) a (e (e^-1%FUN j))); last first. by apply: eq_esum => i Qi; rewrite invK ?inE. by rewrite le_esum => //= i Qi; rewrite a_ge0//; exact: funS. rewrite ub_ereal_sup => //= _ [X [finX XQ] <-]; rewrite ereal_sup_ub => //=. exists [set` (e^-1 @` (fset_set X))%fset]. split=> [|t /= /imfsetP[t'/=]]; first exact: finite_fset. by rewrite in_fset_set// inE => /XQ Qt' ->; exact: funS. rewrite fsbig_finite//= set_fsetK big_imfset => //=; last first. move=> x y; rewrite !in_fset_set// !inE => /XQ ? /XQ ? /(congr1 e). by rewrite !invK ?inE. by rewrite -fsbig_finite//; apply: eq_fsbigr=> x /[!inE]/XQ ?; rewrite invK ?inE. Qed. Arguments reindex_esum {R T T'} P Q e a. Section nneseries_interchange. Local Open Scope ereal_scope. Let nneseries_esum_prod (R : realType) (a : nat -> nat -> \bar R) (P Q : pred nat) : (forall i j, 0 <= a i j) -> \sum_(i <oo | P i) \sum_(j <oo | Q j) a i j = \esum_(i in P `*` Q) a i.1 i.2. Proof. move=> a0; rewrite -(@esum_esum _ _ _ P (fun=> Q))//. rewrite nneseries_esum//; last by move=> n _; exact: nneseries_ge0. rewrite (_ : [set x | P x] = P); last by apply/seteqP; split. by apply eq_esum => i Pi; rewrite nneseries_esum. Qed. Lemma nneseries_interchange (R : realType) (a : nat -> nat -> \bar R) (P Q : pred nat) : (forall i j, 0 <= a i j) -> \sum_(i <oo | P i) \sum_(j <oo | Q j) a i j = \sum_(j <oo | Q j) \sum_(i <oo | P i) a i j. Proof. move=> a0; rewrite !nneseries_esum_prod//. rewrite (reindex_esum (Q `*` P) _ (fun x => (x.2, x.1)))//; split=> //=. by move=> [i j] [/=]. by move=> [i1 i2] [j1 j2] /= _ _ [] -> ->. by move=> [i1 i2] [Pi1 Qi2] /=; exists (i2, i1). Qed. End nneseries_interchange. Lemma esum_image (R : realType) (T T' : choiceType) (P : set T) (e : T -> T') (a : T' -> \bar R) : set_inj P e -> \esum_(j in e @` P) a j = \esum_(i in P) a (e i). Proof. by move=> /inj_bij; apply: reindex_esum. Qed. Arguments esum_image {R T T'} P e a. Lemma esum_pred_image (R : realType) (T : choiceType) (a : T -> \bar R) (e : nat -> T) (P : pred nat) : (forall n, P n -> 0 <= a (e n)) -> set_inj P e -> \esum_(i in e @` P) a i = \sum_(i <oo | P i) a (e i). Proof. by move=> a0 einj; rewrite esum_image// nneseries_esum. Qed. Arguments esum_pred_image {R T} a e P. Lemma esum_set_image [R : realType] [T : choiceType] [a : T -> \bar R] [e : nat -> T] [P : set nat] : (forall n : nat, P n -> 0 <= a (e n)) -> set_inj P e -> \esum_(i in [set e x | x in P]) a i = \sum_(i <oo | i \in P) a (e i). Proof. move=> a0 einj; rewrite esum_image// nneseries_esum ?set_mem_set//. by move=> n; rewrite inE => /a0. Qed. Arguments esum_set_image {R T} a e P. Section esum_bigcup. Variables (R : realType) (T : choiceType) (K : set nat). Implicit Types (J : nat -> set T) (a : T -> \bar R). Lemma esum_bigcupT J a : trivIset setT J -> (forall x, 0 <= a x) -> \esum_(i in \bigcup_(k in K) (J k)) a i = \esum_(i in K) \esum_(j in J i) a j. Proof. move=> tJ a0; rewrite esum_esum//; apply: reindex_esum => //; split. - by move=> [/= i j] [Ki Jij]; exists i. - move=> [/= i1 j1] [/= i2 j2]; rewrite ?inE/=. move=> [K1 J1] [K2 J2] j12; congr (_, _) => //. by apply: (@tJ i1 i2) => //; exists j1; split=> //; rewrite j12. - by move=> j [i Ki Jij]/=; exists (i, j). Qed. Lemma esum_bigcup J a : trivIset [set i | a @` J i != [set 0]] J -> (forall x : T, (\bigcup_(k in K) J k) x -> 0 <= a x) -> \esum_(i in \bigcup_(k in K) J k) a i = \esum_(k in K) \esum_(j in J k) a j. Proof. move=> Jtriv a_ge0. pose J' i := if a @` J i == [set 0] then set0 else J i. pose a' x := if x \in \bigcup_(k in K) J k then a x else 0. have a'E k x : K k -> J k x -> a' x = a x. move=> Kk Jkx; rewrite /a'; case: ifPn; rewrite ?(inE, notin_set)//=. by case; exists k. have a'_ge0 x : a' x >= 0 by rewrite /a'; case: ifPn; rewrite // ?inE => /a_ge0. transitivity (\esum_(i in \bigcup_(k in K) J' k) a' i). rewrite esum_mkcond [RHS]esum_mkcond /a'; apply: eq_esum => x _. do 2!case: ifPn; rewrite ?(inE, notin_set)//= => J'x Jx. apply: contra_not_eq J'x => Nax. move: Jx => [k kK Jkx]; exists k=> //; rewrite /J'/=; case: ifPn=> //=. move=> /eqP/(congr1 (@^~ (a x)))/=; rewrite propeqE => -[+ _]. by apply: contra_neq_not Nax; apply; exists x. rewrite esum_bigcupT//; last first. move=> i j _ _ [x []]; rewrite /J'/=. case: eqVneq => //= Ai0 Jix; case: eqVneq => //= Aj0 Jjx. by have := Jtriv i j Ai0 Aj0; apply; exists x. apply: eq_esum => i Ki. rewrite esum_mkcond [RHS]esum_mkcond; apply: eq_esum => x _. do 2!case: ifPn; rewrite ?(inE, notin_set)//=. - by move=> /a'E->//. - by rewrite /J'; case: ifPn => //. move=> Jix; rewrite /J'; case: ifPn=> //=. by move=> /eqP/(congr1 (@^~ (a x)))/=; rewrite propeqE => -[->]//; exists x. Qed. End esum_bigcup. Arguments esum_bigcupT {R T K} J a. Arguments esum_bigcup {R T K} J a. Definition summable (T : choiceType) (R : realType) (D : set T) (f : T -> \bar R) := (\esum_(x in D) `| f x | < +oo)%E. Section summable_lemmas. Local Open Scope ereal_scope. Variables (T : choiceType) (R : realType). Implicit Types (D : set T) (f : T -> \bar R). Lemma summable_pinfty D f : summable D f -> forall x, D x -> `| f x | < +oo. Proof. move=> Dfoo x Dx; apply: le_lt_trans Dfoo. rewrite (esumID [set x])// setI1 mem_set// esum_set1// lee_addl//. exact: esum_ge0. Qed. Lemma summableE D f : summable D f = (\esum_(x in D) `| f x | \is a fin_num). Proof. rewrite /summable fin_numElt; apply/idP/idP => [->|/andP[]//]. by rewrite andbT (lt_le_trans (ltNyr 0))//; exact: esum_ge0. Qed. Lemma summableD D f g : summable D f -> summable D g -> summable D (f \+ g). Proof. move=> Df Dg; apply: le_lt_trans (lte_add_pinfty Df Dg). by rewrite -esumD//; apply le_esum => t Dt; exact: lee_abs_add. Qed. Lemma summableN D f : summable D f = summable D (\- f). Proof. by rewrite /summable; congr (_ < +oo); apply: eq_esum => t Dt; rewrite abseN. Qed. Lemma summableB D f g : summable D f -> summable D g -> summable D (f \- g). Proof. by move=> Df; rewrite summableN; exact: summableD. Qed. Lemma summable_funepos D f : summable D f -> summable D f^\+. Proof. apply: le_lt_trans; apply le_esum => t Dt. by rewrite -/((abse \o f) t) fune_abse gee0_abs// lee_addl. Qed. Lemma summable_funeneg D f : summable D f -> summable D f^\-. Proof. apply: le_lt_trans; apply le_esum => t Dt. by rewrite -/((abse \o f) t) fune_abse gee0_abs// lee_addr. Qed. End summable_lemmas. Import numFieldNormedType.Exports. Section summable_nat. Local Open Scope ereal_scope. Variable R : realType. Lemma summable_fine_sum r (P : pred nat) (f : nat -> \bar R) : summable P f -> (\sum_(0 <= k < r | P k) fine (f k))%R = fine (\sum_(0 <= k < r | P k) f k). Proof. move=> Pf; elim: r => [|r ih]; first by rewrite !big_nil. rewrite big_mkcond/= big_nat_recr// [in RHS]big_mkcond/= big_nat_recr//=. rewrite -!big_mkcond/= ih; case: ifPn => Pr => //; last by rewrite adde0 addr0. rewrite fineD//; last first. by rewrite fin_num_abs (summable_pinfty Pf). by apply/sum_fin_numP => i ir Pi; rewrite fin_num_abs (summable_pinfty Pf). Qed. Lemma summable_cvg (P : pred nat) (f : (\bar R)^nat) : (forall i, P i -> 0 <= f i)%E -> summable P f -> cvg (fun n => \sum_(0 <= k < n | P k) fine (f k))%R. Proof. move=> f0 Pf; apply: nondecreasing_is_cvg. by apply: nondecreasing_series => n Pn; exact/fine_ge0/f0. exists (fine (\sum_(i <oo | P i) `|f i|)) => x /= [n _ <-]. rewrite summable_fine_sum// -lee_fin fineK//; last first. by apply/sum_fin_numP => i ni Pi; rewrite fin_num_abs (summable_pinfty Pf). rewrite fineK//; last first. rewrite nneseries_esum// fin_numElt; apply/andP; split. by rewrite (@lt_le_trans _ _ 0)// ?lte_ninfty//; exact: esum_ge0. by apply: le_lt_trans Pf; apply le_esum. apply: le_trans (nneseries_lim_ge n _) => //; apply: lee_sum => i _. by rewrite lee_abs. Qed. Lemma summable_nneseries_lim (P : pred nat) (f : (\bar R)^nat) : (forall i, P i -> 0 <= f i)%E -> summable P f -> \sum_(i <oo | P i) f i = (lim (fun n => (\sum_(0 <= k < n | P k) fine (f k))%R))%:E. Proof. move=> f0 Pf; pose A_ n := (\sum_(0 <= k < n | P k) fine (f k))%R. transitivity (lim (EFin \o A_)). congr (lim _); apply/funext => /= n; rewrite /A_ /= -sumEFin. apply eq_bigr => i Pi/=; rewrite fineK//. by rewrite fin_num_abs (@summable_pinfty _ _ P). by rewrite EFin_lim//; apply: summable_cvg. Qed. Lemma summable_nneseries (f : nat -> \bar R) (P : pred nat) : summable P f -> \sum_(i <oo | P i) (f i) = \sum_(i <oo | P i) f^\+ i - \sum_(i <oo | P i) f^\- i. Proof. move=> Pf. pose A_ n := (\sum_(0 <= k < n | P k) fine (f^\+ k))%R. pose B_ n := (\sum_(0 <= k < n | P k) fine (f^\- k))%R. pose C_ n := fine (\sum_(0 <= k < n | P k) f k). pose A := lim A_. pose B := lim B_. suff: ((fun n => C_ n - (A - B)) --> (0 : R^o))%R. move=> CAB. rewrite [X in X - _]summable_nneseries_lim//; last exact/summable_funepos. rewrite [X in _ - X]summable_nneseries_lim//; last exact/summable_funeneg. rewrite -EFinB; apply/cvg_lim => //; apply/fine_cvgP; split. apply: nearW => n. rewrite fin_num_abs; apply: le_lt_trans Pf => /=. by rewrite -nneseries_esum// (le_trans (lee_abs_sum _ _ _))// nneseries_lim_ge. by apply: (@cvg_sub0 _ _ _ _ _ _ (cst (A - B)%R) _ CAB) => //; exact: cvg_cst. have : ((fun x => A_ x - B_ x) --> A - B)%R. apply: cvgD. - by apply: summable_cvg => //; exact/summable_funepos. - by apply: cvgN; apply: summable_cvg => //; exact/summable_funeneg. move=> /cvgrPdist_lt cvgAB; apply/cvgrPdist_lt => e e0. move: cvgAB => /(_ _ e0) [N _/= hN] /=. near=> n. rewrite distrC subr0. have -> : (C_ = A_ \- B_)%R. apply/funext => k. rewrite /= /A_ /C_ /B_ -sumrN -big_split/= -summable_fine_sum//. apply eq_bigr => i Pi. rewrite -fineB//. - by rewrite [in LHS](funeposneg f). - by rewrite fin_num_abs (@summable_pinfty _ _ P) //; exact/summable_funepos. - by rewrite fin_num_abs (@summable_pinfty _ _ P) //; exact/summable_funeneg. by rewrite distrC; apply: hN; near: n; exists N. Unshelve. all: by end_near. Qed. Lemma summable_nneseries_esum (f : nat -> \bar R) (P : pred nat) : summable P f -> \sum_(i <oo | P i) f i = esum P f^\+ - esum P f^\-. Proof. move=> Pfoo. rewrite -nneseries_esum; last first. by move=> n Pn; rewrite /maxe; case: ifPn => //; rewrite -leNgt. rewrite -nneseries_esum; last first. by move=> n Pn; rewrite /maxe; case: ifPn => //; rewrite leNgt. by rewrite [LHS]summable_nneseries. Qed. End summable_nat. Section esumB. Local Open Scope ereal_scope. Variables (R : realType) (T : choiceType). Implicit Types (D : set T) (f g : T -> \bar R). Let esum_posneg D f := esum D f^\+ - esum D f^\-. Let ge0_esum_posneg D f : (forall x, D x -> 0 <= f x) -> esum_posneg D f = \esum_(x in D) f x. Proof. move=> Sa; rewrite /esum_posneg [X in _ - X](_ : _ = 0) ?sube0; last first. by rewrite esum1// => x Sx; rewrite -[LHS]/(f^\- x) (ge0_funenegE Sa)// inE. by apply: eq_esum => t St; apply/max_idPl; exact: Sa. Qed. Lemma esumB D f g : summable D f -> summable D g -> (forall i, D i -> 0 <= f i) -> (forall i, D i -> 0 <= g i) -> \esum_(i in D) (f \- g)^\+ i - \esum_(i in D) (f \- g)^\- i = \esum_(i in D) f i - \esum_(i in D) g i. Proof. move=> Df Dg f0 g0. have /eqP : esum D (f \- g)^\+ + esum_posneg D g = esum D (f \- g)^\- + esum_posneg D f. rewrite !ge0_esum_posneg// -!esumD//; last 2 first. by move=> t Dt; rewrite le_maxr lexx orbT. by move=> t Dt; rewrite le_maxr lexx orbT. apply eq_esum => i Di; have [fg|fg] := leP 0 (f i - g i). rewrite max_r 1?lee_oppl ?oppe0// add0e subeK//. by rewrite fin_num_abs (summable_pinfty Dg). rewrite add0e max_l; last by rewrite lee_oppr oppe0 ltW. rewrite fin_num_oppeB//; last by rewrite fin_num_abs (summable_pinfty Dg). by rewrite -addeA addeCA addeA subeK// fin_num_abs (summable_pinfty Df). rewrite [X in _ == X -> _]addeC -sube_eq; last 2 first. - rewrite fin_numD; apply/andP; split. rewrite (@eq_esum _ _ _ _ (abse \o (f \- g)^\+))//. by rewrite -summableE; exact/summable_funepos/summableB. by move=> t Dt; rewrite /= gee0_abs. move: Dg; rewrite summableE (@eq_esum _ _ _ _ g)//. by rewrite ge0_esum_posneg// => t Tt; rewrite gee0_abs// g0. by move=> t Tt; rewrite gee0_abs// g0. - rewrite fin_num_adde_defr// ge0_esum_posneg//. rewrite (@eq_esum _ _ _ _ (abse \o f))// -?summableE// => i Di. by rewrite /= gee0_abs// f0. rewrite -addeA addeCA eq_sym [X in _ == X -> _]addeC -sube_eq; last 2 first. - rewrite ge0_esum_posneg// (@eq_esum _ _ _ _ (abse \o f))// -?summableE// => i Di. by rewrite /= gee0_abs// f0. - rewrite fin_num_adde_defl// ge0_esum_posneg//. rewrite (@eq_esum _ _ _ _ (abse \o g))// -?summableE// => i Di. by rewrite /= gee0_abs// g0. by rewrite ge0_esum_posneg// ge0_esum_posneg// => /eqP ->. Qed. End esumB.