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.
(* -------------------------------------------------------------------- *)
(* Copyright (c) - 2015--2016 - IMDEA Software Institute                *)
(* Copyright (c) - 2015--2018 - Inria                                   *)
(* Copyright (c) - 2016--2018 - Polytechnique                           *)

(* -------------------------------------------------------------------- *)
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. Require Import xfinmap ereal reals discrete realseq. From mathcomp.classical Require Import classical_sets functions mathcomp_extra. Require Import topology. Set Implicit Arguments. Unset Strict Implicit. Unset Printing Implicit Defensive. Unset SsrOldRewriteGoalsOrder. Import Order.TTheory GRing.Theory Num.Theory. Local Open Scope fset_scope. Local Open Scope ring_scope. (* -------------------------------------------------------------------- *) Local Notation "\`| f |" := (fun x => `|f x|) (at level 2). Local Notation simpm := Monoid.simpm. (* -------------------------------------------------------------------- *) Section Summable. Variables (T : choiceType) (R : realType) (f : T -> R). Definition summable := exists (M : R), forall (J : {fset T}), \sum_(x : J) `|f (val x)| <= M. Lemma summableP : summable -> { M | 0 <= M & forall (J : {fset T}), \sum_(x : J) `|f (val x)| <= M }. Proof. move/asboolP/exists_asboolP=> h; have := (xchooseP h). move: (xchoose _)=> {h} M /asboolP h; exists M => //. by have := h fset0; rewrite big_pred0 // => -[x]; rewrite in_fset0. Qed. End Summable. (* -------------------------------------------------------------------- *) Section Sum. Context {R : realType} {T : choiceType}. Implicit Types f g : T -> R. Definition fpos f := fun x => `|Num.max 0 (f x)|. Definition fneg f := fun x => `|Num.min 0 (f x)|. Lemma eq_fpos f g : f =1 g -> fpos f =1 fpos g. Proof. by move=> eq_fg x; rewrite /fpos eq_fg. Qed. Lemma eq_fneg f g : f =1 g -> fneg f =1 fneg g. Proof. by move=> eq_fg x; rewrite /fneg eq_fg. Qed. Lemma fpos0 x : fpos (fun _ : T => 0) x = 0 :> R. Proof. by rewrite /fpos maxxx normr0. Qed. Lemma fneg0 x : fneg (fun _ : T => 0) x = 0 :> R. Proof. by rewrite /fneg minxx normr0. Qed. Lemma fnegN f : fneg (- f) =1 fpos f. Proof. by move=> x; rewrite /fpos /fneg -{1}oppr0 -oppr_max normrN. Qed. Lemma fposN f : fpos (- f) =1 fneg f. Proof. by move=> x; rewrite /fpos /fneg -{1}oppr0 -oppr_min normrN. Qed. Lemma fposZ f c : 0 <= c -> fpos (c \*o f) =1 c \*o fpos f. Proof. move=> ge0_c x; rewrite /fpos /= -{1}(mulr0 c). by rewrite -maxr_pmulr // normrM ger0_norm. Qed. Lemma fnegZ f c : 0 <= c -> fneg (c \*o f) =1 c \*o fneg f. Proof. move=> ge0_c x; rewrite /= -!fposN; have /=<- := (fposZ (- f) ge0_c x). by apply/eq_fpos=> y /=; rewrite mulrN. Qed. Lemma fpos_natrM f (n : T -> nat) x : fpos (fun x => (n x)%:R * f x) x = (n x)%:R * fpos f x. Proof. rewrite /fpos -[in RHS]normr_nat -normrM. by rewrite maxr_pmulr ?ler0n // mulr0. Qed. Lemma fneg_natrM f (n : T -> nat) x : fneg (fun x => (n x)%:R * f x) x = (n x)%:R * fneg f x. Proof. rewrite -[in RHS]fposN -fpos_natrM -fposN. by apply/eq_fpos=> y; rewrite mulrN. Qed. Lemma fneg_ge0 f x : (forall x, 0 <= f x) -> fneg f x = 0. Proof. by move=> ?; rewrite /fneg min_l ?normr0. Qed. Lemma fpos_ge0 f x : (forall x, 0 <= f x ) -> fpos f x = f x. Proof. by move=> ?; rewrite /fpos max_r ?ger0_norm. Qed. Lemma ge0_fpos f x : 0 <= fpos f x. Proof. by apply/normr_ge0. Qed. Lemma ge0_fneg f x : 0 <= fneg f x. Proof. by apply/normr_ge0. Qed. Lemma le_fpos_norm f x : fpos f x <= `|f x|. Proof. rewrite /fpos ger0_norm ?(le_maxr, lexx) //. by rewrite le_maxl normr_ge0 ler_norm. Qed. Lemma le_fpos f1 f2 : f1 <=1 f2 -> fpos f1 <=1 fpos f2. Proof. move=> le_f x; rewrite /fpos !ger0_norm ?le_maxr ?lexx //. by rewrite le_maxl lexx /=; case: ltP => //=; rewrite le_f. Qed. Lemma fposBfneg f x : fpos f x - fneg f x = f x. Proof. rewrite /fpos /fneg maxC. case: (leP (f x) 0); rewrite normr0 (subr0, sub0r) => ?. by rewrite ler0_norm ?opprK. by rewrite gtr0_norm. Qed. Definition psum f : R := (* We need some ticked `image` operator *) let S := [set x | exists J : {fset T}, x = \sum_(x : J) `|f (val x)| ]%classic in if `[<summable f>] then sup S else 0. Definition sum f : R := psum (fpos f) - psum (fneg f). End Sum. (* -------------------------------------------------------------------- *) Section SummableCountable. Variable (T : choiceType) (R : realType) (f : T -> R). Lemma summable_countn0 : summable f -> countable [pred x | f x != 0]. Proof. case/summableP=> M ge0_M bM; pose E (p : nat) := [pred x | `|f x| > 1 / p.+1%:~R]. set F := [pred x | _]; have le: {subset F <= [pred x | `[< exists p, x \in E p >]]}. move=> x; rewrite !inE => nz_fx. pose j := `|floor (1 / `|f x|)|%N; exists j; rewrite inE. rewrite ltr_pdivr_mulr ?ltr0z // -ltr_pdivr_mull ?normr_gt0 //. rewrite mulr1 /j div1r -addn1 /= PoszD intrD mulr1z. rewrite gez0_abs ?floor_ge0 ?invr_ge0 ?normr_ge0 //. by rewrite -RfloorE; apply lt_succ_Rfloor. apply/(countable_sub le)/cunion_countable=> i /=. case: (existsTP (fun s : seq T => {subset E i <= s}))=> /= [[s le_Eis]|]. by apply/finite_countable/finiteP; exists s => x /le_Eis. move/finiteNP; pose j := `|floor (M / i.+1%:R)|.+1. pose K := (`|floor M|.+1 * i.+1)%N; move/(_ K)/asboolP/exists_asboolP. move=> h; have /asboolP[] := xchooseP h. set s := xchoose h=> eq_si uq_s le_sEi; pose J := [fset x in s]. suff: \sum_(x : J) `|f (val x)| > M by rewrite ltNge bM. apply/(@lt_le_trans _ _ (\sum_(x : J) 1 / i.+1%:~R)); last first. apply/ler_sum=> /= m _; apply/ltW. by have:= fsvalP m; rewrite in_fset => /le_sEi. rewrite sumr_const -cardfE card_fseq undup_id // eq_si -mulr_natr -pmulrn. rewrite mul1r natrM mulrCA mulVf ?mulr1 ?pnatr_eq0 //. have /andP[_] := mem_rg1_Rfloor M; rewrite RfloorE -addn1. by rewrite natrD /= mulr1n pmulrn -{1}[floor _]gez0_abs // floor_ge0. Qed. End SummableCountable. (* -------------------------------------------------------------------- *) Section PosCnv. Context {R : realType}. Lemma ncvg_mono (u : nat -> R) : (* {mono u : x y / (x <= y)%N >-> u x <= u y *) (forall x y, (x <= y)%N -> u x <= u y) -> exists2 l, (-oo < l)%E & ncvg u l. Proof. move=> mono_u; pose E := [set x | exists n, x = u n]%classic. have nzE: nonempty E by exists (u 0%N); exists 0%N. case: (pselect (has_sup E)); last first. move/has_supPn=> -/(_ nzE) h; exists +oo%E => //; elim/nbh_pinfW => M /=. case/(_ M): h=> x [K -> lt_MuK]; exists K=> n le_Kn; rewrite inE. by apply/(lt_le_trans lt_MuK)/mono_u. move=> supE; exists (sup E)%:E => //; first exact: ltNyr. elim/nbh_finW=>e /= gt0_e. case: (sup_adherent gt0_e supE)=> x [K ->] lt_uK. exists K=> n le_Kn; rewrite inE distrC ger0_norm ?subr_ge0. by move/ubP: (sup_upper_bound supE); apply; exists n. rewrite ltr_subl_addr addrC -ltr_subl_addr. by rewrite (lt_le_trans lt_uK) //; apply/mono_u. Qed. Lemma ncvg_mono_bnd (u : nat -> R) : (* {mono u : x y / (x <= y)%N >-> u x <= u y *) (forall x y, (x <= y)%N -> u x <= u y) -> nbounded u -> exists l, ncvg u l%:E. Proof. case/ncvg_mono=> -[x||] // _ cu bdu; first by exists x. case/asboolP/nboundedP: bdu=> M gt0_M bdu. case/(_ (NPInf M)): cu => K /= /(_ K (leqnn _)). rewrite inE/= => /ltW /le_trans /(_ (ler_norm _)). by move/le_lt_trans/(_ (bdu _)); rewrite ltxx. Qed. End PosCnv. (* -------------------------------------------------------------------- *) Section SumTh. Context {R : realType} (T : choiceType). Implicit Type S : T -> R. Lemma summable_sup (S : T -> R) : summable S -> has_sup [set x | exists J : {fset T}, x = \sum_(j : J) `|S (val j)|]%classic. Proof. case/summableP=> M _ hbd; split. by exists 0, fset0; rewrite big_fset0. by exists M; apply/ubP=> y [J ->]. Qed. Lemma psum_sup S : psum S = sup [set x | exists J : {fset T}, x = \sum_(x : J) `|S (val x)|]%classic. Proof. rewrite /psum; case: ifPn => // /asboolPn h. rewrite sup_out //; set X := [set r | _]%classic => hs. apply: h; exists (sup X) => J. by move/ubP : (sup_upper_bound hs); apply; exists J. Qed. Lemma psum_sup_seq S : psum S = sup [set x | exists2 J : seq T, uniq J & x = \sum_(x <- J) `|S x| ]%classic. Proof. rewrite psum_sup; congr sup; rewrite predeqE => x; split. case=> J ->; exists (enum_fset J). by case: J => /= J /canonical_uniq. by rewrite (big_fset_seq \`|_|) /=. case=> J uqJ ->; exists [fset x in J]. by rewrite (big_seq_fset \`|_|). Qed. Lemma eq_summable (S1 S2 : T -> R) : (S1 =1 S2) -> summable S1 -> summable S2. Proof. move=> eq_12 [M h]; exists M => J; rewrite (le_trans _ (h J)) //. rewrite le_eqVlt; apply/orP; left; apply/eqP/eq_bigr. by move=> /= K _; rewrite eq_12. Qed. Lemma eq_summableb (S1 S2 : T -> R) : (S1 =1 S2) -> `[< summable S2 >] = `[< summable S1 >]. Proof. by move=> eq_12; apply/asboolP/asboolP; apply/eq_summable. Qed. Lemma eq_ppsum (F1 F2 : {fset T} -> R) : F1 =1 F2 -> (sup [set x | exists J, x = F1 J] = sup [set x | exists J, x = F2 J])%classic. Proof. move=> eq_12; congr sup; rewrite predeqE => x. by split=> -[J ->]; exists J. Qed. Lemma eq_psum (F1 F2 : T -> R) : F1 =1 F2 -> psum F1 = psum F2. Proof. move=> eq_12; rewrite /psum (eq_summableb eq_12). case: `[< summable F1 >] => //. congr sup. rewrite predeqE => x; split=> -[J ->]; exists J; by apply/eq_bigr=> /= K _; rewrite eq_12. Qed. Lemma eq_sum (F1 F2 : T -> R) : F1 =1 F2 -> sum F1 = sum F2. Proof. move=> eq_fg; rewrite /sum; congr (_ - _); apply/eq_psum. by apply/eq_fpos. by apply/eq_fneg. Qed. Lemma le_summable (F1 F2 : T -> R) : (forall x, 0 <= F1 x <= F2 x) -> summable F2 -> summable F1. Proof. move=> le_F [M leM]; exists M => J; apply/(le_trans _ (leM J)). apply/ler_sum => /= j _; case/andP: (le_F (val j)) => h1 h2. by rewrite !ger0_norm // (le_trans h1 h2). Qed. Lemma le_psum (F1 F2 : T -> R) : (forall x, 0 <= F1 x <= F2 x) -> summable F2 -> psum F1 <= psum F2. Proof. move=> le_F smF2; have smF1: summable F1 by apply/(le_summable le_F). rewrite /psum (asboolT smF1) (asboolT smF2); apply/le_sup; first last. + by apply/summable_sup. + by exists 0, fset0; rewrite big_fset0. move=> x [J ->]; apply/downP; exists (\sum_(j : J) `|F2 (val j)|). by exists J. apply/ler_sum=> /= j _; case/andP: (le_F (val j)) => h1 h2. by rewrite !ger0_norm // (le_trans h1 h2). Qed. Lemma psum_out S : ~ summable S -> psum S = 0. Proof. by move/asboolPn/negbTE=> smN; rewrite /psum smN. Qed. Lemma psumE S : (forall x, 0 <= S x) -> summable S -> psum S = sup [set x | exists J : {fset T}, x = \sum_(j : J) S (val j)]%classic. Proof. move=> gt0_S smS; rewrite /psum (asboolT smS); apply/eq_ppsum=> /=. by move=> J; apply/eq_bigr=> j _; rewrite ger0_norm. Qed. Lemma psum_absE S : summable S -> psum S = sup [set x | exists J : {fset T}, x = \sum_(j : J) `|S (val j)|]%classic. Proof. by move=> smS; rewrite /psum (asboolT smS). Qed. Lemma summable_seqP S : summable S <-> (exists2 M, 0 <= M & forall s : seq T, uniq s -> \sum_(x <- s) `|S x| <= M). Proof. split=> [/summableP|] [M gt0_M h]; exists M => //. by move=> s uq_s; have := h [fset x in s]; rewrite (big_seq_fset \`|S|). by case=> J cJ; rewrite (big_fset_seq \`|_|) /=; apply/h/canonical_uniq. Qed. Lemma gerfin_psum S (J : {fset T}) : summable S -> \sum_(j : J) `|S (val j)| <= psum S. Proof. move=> smS; rewrite /psum (asboolT smS). by move/ubP : (sup_upper_bound (summable_sup smS)); apply; exists J. Qed. Lemma gerfinseq_psum S (r : seq T) : uniq r -> summable S -> \sum_(j <- r) `|S j| <= psum S. Proof. move=> uq_r /gerfin_psum -/(_ [fset x in r]); by rewrite (big_seq_fset \`|S|). Qed. Lemma psum_le S z : (forall J, uniq J -> \sum_(j <- J) `|S j| <= z) -> psum S <= z. Proof. move=> le_z; have: summable S; first (apply/summable_seqP; exists z). + by apply/(le_trans _ (le_z [::] _)) => //; rewrite big_nil. + by move=> J uqJ; apply/le_z. move/summable_sup=> [neS hsS]; rewrite psum_sup. apply/sup_le_ub => //; apply/ubP=> r [J ->]. by rewrite (big_fset_seq \`|_|) le_z /=; case: J => J /= /canonical_uniq. Qed. Lemma lt_psum (F : T -> R) l : summable F -> l < psum F -> exists J : {fset T}, l < \sum_(j : J) `|F (val j)|. Proof. move=> smF; rewrite /psum (asboolT smF) => /lt_sup_imfset. by case=> /= [|J lt_lJ _]; [apply/summable_sup | exists J]. Qed. End SumTh. (* -------------------------------------------------------------------- *) Lemma max_sup {R : realType} x (E : set R) : (E `&` ubound E)%classic x -> sup E = x. Proof. case=> /= xE xubE; have nzE: nonempty E by exists x. apply/eqP; rewrite eq_le sup_le_ub //=. have : has_sup E by split; exists x. by move/sup_upper_bound/ubP; apply. Qed. (* -------------------------------------------------------------------- *) Section FinSumTh. Context {R : realType} (I : finType). Lemma summable_fin (f : I -> R) : summable f. Proof. exists (\sum_(i : [fset i | i : I]) `|f (val i)|). move=> J; apply: (big_fset_subset (F := \`|_|)). by move=> x; rewrite normr_ge0. by move=> i _; apply/imfsetP; exists i. Qed. Lemma psum_fin (f : I -> R) : psum f = \sum_i `|f i|. Proof. (* FIXME *) pose S := \sum_(i : [fset i | i : I]) `|f (val i)|. rewrite /psum (asboolT (summable_fin f)) (@max_sup _ S). rewrite /=; split; first by exists [fset i | i : I]%fset. apply/ubP=> y [J ->]; apply/(big_fset_subset (F := \`|_|)). by move=> i; rewrite normr_ge0. by move=> j jJ; apply/in_imfset. rewrite /S -(big_map val xpredT \`|f|); apply/perm_big. rewrite /index_enum -!enumT; apply/(perm_trans _ enum_fsetT). apply/uniq_perm; rewrite ?map_inj_uniq ?enum_uniq //=. by apply/val_inj. by rewrite -enumT enum_uniq. move=> i /=; rewrite mem_enum in_imfset //; apply/mapP. have h: i \in [fset j | j : I] by rewrite in_imfset. by exists (FSetSub h) => //; rewrite mem_enum. Qed. End FinSumTh. (* -------------------------------------------------------------------- *) Section PSumGe. Context {R : realType} (T : choiceType). Variable (S : T -> R). Lemma ger_big_psum r : uniq r -> summable S -> \sum_(x <- r) `|S x| <= psum S. Proof. move=> uq_r smS; rewrite /psum (asboolT smS). set E := (X in sup X). have : has_sup E by apply/summable_sup. move/sup_upper_bound/ubP; apply. by exists [fset x in r]; rewrite (big_seq_fset (fun i => `|S i|)). Qed. Lemma ger1_psum x : summable S -> `|S x| <= psum S. Proof. move=> smS; have h := @ger_big_psum [:: x] _ smS. by rewrite (le_trans _ (h _)) ?big_seq1. Qed. Lemma ge0_psum : 0 <= psum S. Proof. (* FIXME: asbool_spec *) case/boolP: `[< summable S >] => [|/asboolPn/psum_out ->//]. move/asboolP=> smS; have h := @ger_big_psum [::] _ smS. by rewrite (le_trans _ (h _)) ?big_nil. Qed. End PSumGe. (* -------------------------------------------------------------------- *) Section PSumNatGe. Context {R : realType}. Variable (S : nat -> R) (smS : summable S). Lemma ger_big_ord_psum n : \sum_(i < n) `|S i| <= psum S. Proof. rewrite -(big_mkord predT (fun i => `|S i|)) /=. by apply/ger_big_psum => //; rewrite iota_uniq. Qed. End PSumNatGe. (* -------------------------------------------------------------------- *) Section PSumCnv. Context {R : realType}. Variable (S : nat -> R). Hypothesis ge0_S : (forall n, 0 <= S n). Hypothesis smS : summable S. Lemma ptsum_homo x y : (x <= y)%N -> (\sum_(i < x) S i <= \sum_(i < y) S i). Proof. move=> le_xy; rewrite -!(big_mkord predT) -(subnKC le_xy) /=. by rewrite /index_iota !subn0 iotaD big_cat /= ler_addl sumr_ge0. Qed. Lemma psummable_ptbounded : nbounded (fun n => \sum_(i < n) S i). Proof. apply/asboolP/nboundedP; exists (psum S + 1). rewrite ltr_spaddr ?ltr01 1?(le_trans (normr_ge0 (S 0%N))) //. by apply/ger1_psum. move=> n; rewrite ltr_spaddr ?ltr01 // ger0_norm ?sumr_ge0 //. apply/(le_trans _ (ger_big_ord_psum _ n)) => //. by apply/ler_sum=> /= i _; apply/ler_norm. Qed. Lemma ncvg_sum : ncvg (fun n => \sum_(i < n) S i) (psum S)%:E. Proof. set u := (fun n => _); apply: contraPP smS => ncv _. case: (ncvg_mono_bnd (u := u)) => //. by apply/ptsum_homo. by apply/psummable_ptbounded. move=> x cvux; suff xE: x = (psum S) by rewrite xE in cvux. apply/eqP; case: (x =P _) => // /eqP /lt_total /orP[]; last first. + rewrite -lte_fin => /ncvg_gt /(_ cvux) [K /(_ _ (leqnn _))] /=. rewrite ltNge lee_fin (le_trans _ (ger_big_ord_psum _ K)) //. by apply/ler_sum=> /= i _; apply/ler_norm. move=> lt_xS; pose e := psum S - x. have ge0_e: 0 < e by rewrite subr_gt0. case: (sup_adherent ge0_e (summable_sup smS)) => y. case=> /= J ->; rewrite /e /psum (asboolT smS). rewrite opprB addrCA subrr addr0 => lt_xSJ. pose k := \max_(j : J) (val j); have lt_x_uSk: x < u k.+1. apply/(lt_le_trans lt_xSJ); rewrite /u big_ord_mkfset. rewrite (eq_bigr (S \o val)) => /= [j _|]; first by rewrite ger0_norm. apply/big_fset_subset=> // j jJ; rewrite in_fset //. by rewrite (mem_iota _ k.+1) /= add0n ltnS (leq_bigmax (FSetSub jJ)). have /= := ncvg_homo_le ptsum_homo cvux k.+1; rewrite -/(u _). by rewrite lee_fin => /le_lt_trans/(_ lt_x_uSk); rewrite ltxx. Qed. Lemma sum_ncvg l : ncvg (fun n => \sum_(i < n) S i) l%:E -> summable S. Proof using ge0_S. Abort. End PSumCnv. (* -------------------------------------------------------------------- *) Section PSumAsLim. Context {R : realType} {T : choiceType}. Variable (S : T -> R) (P : nat -> {fset T}). Hypothesis ge0_S : (forall x, 0 <= S x). Hypothesis smS : summable S. Hypothesis homo_P : forall n m, (n <= m)%N -> (P n `<=` P m). Hypothesis cover_P : forall x, S x != 0 -> exists n, x \in P n. Lemma psum_as_lim : psum S = fine (nlim (fun n => \sum_(j : P n) (S (val j)))). Proof. set v := fun n => _; have hm_v m n: (m <= n)%N -> v m <= v n. by move=> le_mn; apply/big_fset_subset/fsubsetP/homo_P. have bd_v n : v n <= psum S. apply/(le_trans _ (gerfin_psum _ smS))/ler_sum. by move=> J _; apply/ler_norm. case: (ncvg_mono_bnd hm_v) => [|l cv]. apply/asboolP/nboundedP; exists (psum S + 1) => //. by apply/(le_lt_trans (ge0_psum S)); rewrite ltr_addl ltr01. move=> n; rewrite ger0_norm ?sumr_ge0 //. by rewrite (le_lt_trans (bd_v n)) // ltr_addl ltr01. have le_lS: l <= psum S by rewrite -lee_fin (ncvg_leC _ cv). rewrite (nlimE cv) /= (rwP eqP) eq_le le_lS andbT. rewrite leNgt; apply/negP=> {le_lS} /(lt_psum smS)[J]. rewrite (big_fset_seq \`|_|) /=; case: J => /= J. move/canonical_uniq=> uqJ lt_jS; pose K := [seq x <- J | S x != 0]. have [n]: exists n, {subset K <= P n}; first rewrite {}/K. elim: {uqJ lt_jS} J => /= [|x J [n ih]]; first by exists 0%N. case: (S x =P 0) => /=; first by move=> _; exists n. move/eqP/cover_P=> [k Pk_x]; exists (maxn n k)=> y. rewrite inE => /orP[/eqP->|/=]. by apply/fsubsetP/homo_P/leq_maxr: x Pk_x. by move/ih; apply/fsubsetP/homo_P/leq_maxl: y. move=> le_K_Pn; have: l < v n; first apply/(lt_le_trans lt_jS). rewrite (eq_bigr S) => [x _|]; first by rewrite ger0_norm. rewrite /v (bigID (fun x => S x == 0)) /= big1 => [x /eqP|] //. rewrite add0r -big_filter -/K -big_seq_fset ?filter_uniq //=. by apply/big_fset_subset => // x; rewrite in_fset => /le_K_Pn. by apply/negP; rewrite -leNgt -lee_fin ncvg_homo_le. Qed. End PSumAsLim. (* -------------------------------------------------------------------- *) Section SummableAlg. Context {R : realType} (T : choiceType) (I : Type). (* -------------------------------------------------------------------- *) Lemma summable_addrC (S1 S2 : T -> R) : summable (S1 \+ S2) -> summable (S2 \+ S1). Proof. by apply/eq_summable => x; rewrite /= addrC. Qed. (* -------------------------------------------------------------------- *) Lemma summable_mulrC (S1 S2 : T -> R) : summable (S1 \* S2) -> summable (S2 \* S1). Proof. by apply/eq_summable => x; rewrite /= mulrC. Qed. (* -------------------------------------------------------------------- *) Lemma summable_abs (S : T -> R) : summable \`|S| <-> summable S. Proof. have h J: \sum_(j <- J) `| `|S j| | = \sum_(j <- J) `|S j|. by apply/eq_bigr=> j _; rewrite normr_id. split=> /summable_seqP[M ge0_M leM]; apply/summable_seqP; by exists M=> // => J /leM; rewrite h. Qed. (* -------------------------------------------------------------------- *) Lemma summable0 : summable (fun _ : T => 0 : R). Proof. by exists 0 => J; rewrite big1 ?normr0. Qed. (* -------------------------------------------------------------------- *) Lemma summableD (S1 S2 : T -> R) : summable S1 -> summable S2 -> summable (S1 \+ S2). Proof. case=> [M1 h1] [M2 h2]; exists (M1 + M2) => J /=. pose M := \sum_(x : J) (`|S1 (val x)| + `|S2 (val x)|). rewrite (@le_trans _ _ M) // ?ler_sum // => [K _|]. by rewrite ler_norm_add. by rewrite /M big_split ler_add ?(h1, h2). Qed. (* -------------------------------------------------------------------- *) Lemma summableN (S : T -> R) : summable S -> summable (- S). Proof. case=> [M h]; exists M => J; rewrite (le_trans _ (h J)) //. rewrite le_eqVlt; apply/orP; left; apply/eqP/eq_bigr. by move=> /= K _; rewrite normrN. Qed. (* -------------------------------------------------------------------- *) Lemma summablebN (S : T -> R) : `[< summable (- S)>] = `[< summable S >]. Proof. apply/asboolP/asboolP => /summableN //. by apply/eq_summable => x /=; rewrite opprK. Qed. (* -------------------------------------------------------------------- *) Lemma summablebDl (S1 S2 : T -> R) : summable S1 -> `[< summable (S1 \+ S2) >] = `[< summable S2 >]. Proof. move=> sm1; apply/asboolP/asboolP; last by apply/(summableD sm1). move=> sm12; apply/(@eq_summable _ _ ((S1 \+ S2) \- S1)). by move=> x /=; rewrite addrC addKr. by apply/summableD/summableN. Qed. (* -------------------------------------------------------------------- *) Lemma summablebDr (S1 S2 : T -> R) : summable S2 -> `[< summable (S1 \+ S2) >] = `[< summable S1 >]. Proof. move=> sm1; rewrite (@eq_summableb _ _ (S2 \+ S1)) ?summablebDl //. by move=> x /=; rewrite addrC. Qed. (* -------------------------------------------------------------------- *) Lemma summableZ (S : T -> R) c : summable S -> summable (c \*o S). Proof. case=> [M h]; exists (`|c| * M) => J; move/(_ J): h => /=. move/(ler_wpmul2l (normr_ge0 c)); rewrite mulr_sumr. move/(le_trans _); apply; rewrite le_eqVlt; apply/orP. by left; apply/eqP/eq_bigr=> j _; rewrite normrM. Qed. (* -------------------------------------------------------------------- *) Lemma summableZr (S : T -> R) (c : R) : summable S -> summable (c \o* S). Proof. by move=> smS; apply/summable_mulrC/summableZ. Qed. (* -------------------------------------------------------------------- *) Lemma summableMl (S1 S2 : T -> R) : (exists M, forall x, `|S1 x| <= M) -> summable S2 -> summable (S1 \* S2). Proof. case=> M leM smS2; apply/summable_abs. apply/(le_summable (F2 := M \*o \`|S2|)). + by move=> x /=; rewrite normr_ge0 /= normrM ler_wpmul2r. + by apply/summableZ/summable_abs. Qed. (* -------------------------------------------------------------------- *) Lemma summableMr (S1 S2 : T -> R) : (exists M, forall x, `|S2 x| <= M) -> summable S1 -> summable (S1 \* S2). Proof. by move=> bd sm; apply/summable_mulrC/summableMl. Qed. (* -------------------------------------------------------------------- *) Lemma summableM (S1 S2 : T -> R) : summable S1 -> summable S2 -> summable (S1 \* S2). Proof. move=> smS1 smS2; apply/summableMl => //; exists (psum S1). by move=> x; apply/ger1_psum. Qed. (* -------------------------------------------------------------------- *) Lemma summable_fpos (f : T -> R) : summable f -> summable (fpos f). Proof. move/summable_abs; apply/le_summable=> x. by rewrite ge0_fpos /= le_fpos_norm. Qed. (* -------------------------------------------------------------------- *) Lemma summable_fneg (f : T -> R) : summable f -> summable (fneg f). Proof. by move/summableN/summable_fpos/(eq_summable (fposN _)). Qed. (* -------------------------------------------------------------------- *) Lemma summable_condl (S : T -> R) (P : pred T) : summable S -> summable (fun x => (P x)%:R * S x). Proof. case/summable_seqP=> M ge0_M leM; apply/summable_seqP. exists M => //; move=> J /leM /(le_trans _); apply. apply/ler_sum=> x _; case: (P x); rewrite (mul1r, mul0r) //. by rewrite normr0 normr_ge0. Qed. (* -------------------------------------------------------------------- *) Lemma summable_condr (S : T -> R) (P : pred T) : summable S -> summable (fun x => S x * (P x)%:R). Proof. move=> /(summable_condl P) /eq_summable; apply. by move=> x /=; rewrite mulrC. Qed. (* -------------------------------------------------------------------- *) Lemma summable_of_bd (S : T -> R) (d : R) : (forall J, uniq J -> \sum_(x <- J) `|S x| <= d) -> summable S /\ psum S <= d. Proof. move=> leS; have ge0_d: 0 <= d. by apply/(le_trans _ (leS [::] _)); rewrite // big_nil. have smS: summable S by apply/summable_seqP; exists d. split=> //; rewrite /psum (asboolT smS); apply/sup_le_ub. by exists 0, fset0; rewrite big_fset0. apply/ubP=> _ [J ->]; rewrite (big_fset_seq \`|_|) /=. by apply/leS; case: J => J /= /canonical_uniq. Qed. (* -------------------------------------------------------------------- *) Lemma summable_sum (F : I -> T -> R) (P : pred I) r : (forall i, P i -> summable (F i)) -> summable (fun x => \sum_(i <- r | P i) F i x). Proof. move=> sm_F; elim: r => [|i r ih]. by apply/(eq_summable _ summable0) => x; rewrite big_nil. pose G x := (F i x) * (P i)%:R + \sum_(i <- r | P i) F i x. apply/(eq_summable (S1 := G)) => [x|]. by rewrite {}/G big_cons; case: ifP=> Pi; rewrite !Monoid.simpm. apply/summableD => //; case/boolP: (P i) => [|_]. by move/sm_F; apply/eq_summable => x; rewrite mulr1. by apply/(eq_summable _ summable0) => x; rewrite mulr0. Qed. End SummableAlg. (* -------------------------------------------------------------------- *) Section StdSum. Context {R : realType} (T : choiceType) (I : Type). Implicit Type S : T -> R. (* -------------------------------------------------------------------- *) Lemma psum0 : psum (fun _ : T => 0) = 0 :> R. Proof. rewrite /psum asboolT; first by apply/summable0. set S := [set x | _]%classic; suff: S = (set1 0). by move => ->; rewrite sup1. rewrite predeqE => x; split. by case=> J -> /=; rewrite big1 // normr0. by move=> ->; exists fset0; rewrite big_fset0. Qed. (* -------------------------------------------------------------------- *) Lemma psum_eq0 (f : T -> R) : (forall x, f x = 0) -> psum f = 0. Proof. by move=> eq; rewrite (eq_psum eq) psum0. Qed. (* -------------------------------------------------------------------- *) Lemma eq0_psum (f : T -> R) : summable f -> psum f = 0 -> (forall x : T, f x = 0). Proof. move=> sm psum_eq0 x; apply/eqP; rewrite -normr_eq0. rewrite eq_le normr_ge0 andbT -psum_eq0. apply/(le_trans _ (gerfinseq_psum (r := [:: x]) _ sm)) => //. by rewrite big_seq1. Qed. (* -------------------------------------------------------------------- *) Lemma neq0_psum (f : T -> R) : psum f <> 0 -> exists x : T, f x <> 0. Proof. by move=> nz_psum; apply/existsp_asboolPn/asboolPn => /psum_eq0. Qed. (* -------------------------------------------------------------------- *) Lemma psum_abs (S : T -> R) : psum \`|S| = psum S. Proof. rewrite /psum; do 2! case: ifPn => //; first last. + by move/asboolP/summable_abs/asboolP=> ->. + by move/asboolPn/summable_abs/asboolPn=> /negbTE->. move=> _ _; congr sup; rewrite predeqE => x; split. case=> J ->; exists J. by under eq_bigr do rewrite normr_id. case=> J ->; exists J. by under [in RHS]eq_bigr do rewrite normr_id. Qed. (* -------------------------------------------------------------------- *) Lemma eq_psum_abs (S1 S2 : T -> R) : \`|S1| =1 \`|S2| -> psum S1 = psum S2. Proof. by move=> eqS; rewrite -[LHS]psum_abs -[RHS]psum_abs; apply/eq_psum. Qed. (* -------------------------------------------------------------------- *) Lemma le_psum_abs (S1 S2 : T -> R) : (forall x, `|S1 x| <= `|S2 x|) -> summable S2 -> psum S1 <= psum S2. Proof. move=> leS smS2; rewrite -[X in X<=_]psum_abs -[X in _<=X]psum_abs. by apply/le_psum/summable_abs => // x; rewrite normr_ge0 leS. Qed. (* -------------------------------------------------------------------- *) Lemma le_psum_condl (S : T -> R) (P : pred T) : summable S -> psum (fun x => (P x)%:R * S x) <= psum S. Proof. move=> smS; apply/le_psum_abs=> // x; rewrite normrM. by apply/ler_pimull => //; rewrite normr_nat lern1 leq_b1. Qed. (* -------------------------------------------------------------------- *) Lemma le_psum_condr (S : T -> R) (P : pred T) : summable S -> psum (fun x => S x * (P x)%:R) <= psum S. Proof. move=> smS; apply/(le_trans _ (le_psum_condl P smS)). rewrite le_eqVlt -(rwP orP); left; apply/eqP/eq_psum. by move=> x /=; rewrite mulrC. Qed. (* -------------------------------------------------------------------- *) Lemma psumN (S : T -> R) : psum (- S) = psum S. Proof. case/boolP: `[< summable S >] => h; last first. by rewrite !psum_out ?oppr0 //; apply/asboolPn; rewrite ?summablebN. rewrite /psum summablebN h; apply/eq_ppsum=> J /=. by apply/eq_bigr=> j _; rewrite normrN. Qed. (* -------------------------------------------------------------------- *) Lemma psumD S1 S2 : (forall x, 0 <= S1 x) -> (forall x, 0 <= S2 x) -> summable S1 -> summable S2 -> psum (S1 \+ S2) = (psum S1 + psum S2). Proof. move=> ge0_S1 ge0_S2 smS1 smS2; have smD := summableD smS1 smS2. have ge0D: forall x, 0 <= S1 x + S2 x by move=> x; rewrite addr_ge0. rewrite !psumE // (rwP eqP) eq_le -(rwP andP); split. apply/sup_le_ub. + by exists 0, fset0; rewrite big_fset0. apply/ubP=> _ [J ->]; rewrite big_split /=. apply/ler_add; rewrite -psumE 1?(le_trans _ (gerfin_psum J _)) //. + by apply/ler_sum=> j _ /=; apply/ler_norm. + by apply/ler_sum=> j _ /=; apply/ler_norm. rewrite -ler_subr_addr; apply/sup_le_ub. + by exists 0, fset0; rewrite big_fset0. apply/ubP=> _ [J1 ->]; rewrite ler_subr_addr addrC. rewrite -ler_subr_addr; apply/sup_le_ub. + by exists 0, fset0; rewrite big_fset0. apply/ubP=> _ [J2 ->]; rewrite ler_subr_addr addrC. pose J := J1 `|` J2; rewrite -psumE ?(le_trans _ (gerfin_psum J _)) //. pose D := \sum_(j : J) (S1 (val j) + S2 (val j)). apply/(@le_trans _ _ D); last by apply/ler_sum=> i _; apply/ler_norm. rewrite /D big_split /=; apply/ler_add; apply/big_fset_subset=> //. + by apply/fsubsetP/fsubsetUl. + by apply/fsubsetP/fsubsetUr. Qed. (* -------------------------------------------------------------------- *) Lemma psumB S1 S2 : (forall x, 0 <= S2 x <= S1 x) -> summable S1 -> psum (S1 \- S2) = (psum S1 - psum S2). Proof using Type. Admitted. (* -------------------------------------------------------------------- *) Lemma psumZ S c : 0 <= c -> psum (c \*o S) = c * psum S. Proof. rewrite le_eqVlt => /orP[/eqP<-|gt0_c]. by rewrite mul0r psum_eq0 // => x /=; rewrite mul0r. case/asboolP: (summable S) => [smS|NsmS]; last first. rewrite !psum_out ?mulr0 // => smZ; apply/NsmS. move/(summableZ c^-1): smZ; apply/eq_summable=> x /=. by rewrite mulKf // gt_eqF. have smZ := summableZ c smS; rewrite (rwP eqP) eq_le. apply/andP; split; first rewrite {1}/psum asboolT //. apply/sup_le_ub. + by exists 0, fset0; rewrite big_fset0. apply/ubP=> _ [J ->]; rewrite -ler_pdivr_mull //. rewrite mulr_sumr (le_trans _ (gerfin_psum J _)) //. apply/ler_sum=> /= j _; rewrite normrM. by rewrite gtr0_norm // mulKf ?gt_eqF. rewrite -ler_pdivl_mull // {1}/psum asboolT //; apply/sup_le_ub. + by exists 0, fset0; rewrite big_fset0. apply/ubP=> _ [J ->]; rewrite ler_pdivl_mull //. rewrite mulr_sumr; apply/(le_trans _ (gerfin_psum J _))=> //. by apply/ler_sum=> /= j _; rewrite normrM (gtr0_norm gt0_c). Qed. (* -------------------------------------------------------------------- *) Lemma psumZr S c : 0 <= c -> psum (c \o* S) = psum S * c. Proof. move=> ge0_c; rewrite [RHS]mulrC -psumZ //. by apply/eq_psum => x /=; rewrite mulrC. Qed. (* -------------------------------------------------------------------- *) Lemma psum_bigop (F : I -> T -> R) P r : (forall i x, 0 <= F i x) -> (forall i, summable (F i)) -> \sum_(i <- r | P i) psum (F i) = psum (fun x => \sum_(i <- r | P i) F i x). Proof. move=> ge0_F sm_F; elim: r => [|i r ih]. by rewrite big_nil; apply/esym/psum_eq0 => x; rewrite big_nil. rewrite big_cons ih; case: ifP => Pi; last first. by apply/eq_psum=> x /=; rewrite big_cons Pi. rewrite -psumD //; first by move=> x; apply/sumr_ge0. by apply/summable_sum. by apply/eq_psum=> x /=; rewrite big_cons Pi. Qed. (* -------------------------------------------------------------------- *) Lemma psumID S (P : pred T) : summable S -> psum S = psum (fun x => (P x)%:R * S x) + psum (fun x => (~~P x)%:R * S x). Proof. have h x: `|S x| = (P x)%:R * `|S x| + (~~P x)%:R * `|S x|. by case: (P x); rewrite !Monoid.simpm. move=> smS; rewrite -[LHS]psum_abs (eq_psum h) psumD. by move=> x; rewrite mulr_ge0. by move=> x; rewrite mulr_ge0. by apply/summable_condl/summable_abs. by apply/summable_condl/summable_abs. congr (_ + _); apply/eq_psum_abs=> x /=. by rewrite !normrM normr_nat normr_id. by rewrite !normrM normr_nat normr_id. Qed. (* -------------------------------------------------------------------- *) Lemma psum_finseq S (r : seq.seq T) : uniq r -> {subset [pred x | S x != 0] <= r} -> psum S = \sum_(x <- r) `|S x|. Proof. move=> eq_r ler; set s := RHS; have h J: uniq J -> \sum_(x <- J) `|S x| <= s. move=> uqJ; rewrite (bigID (ssrbool.mem r)) /= addrC big1. move=> x xNr; apply/eqP; apply/contraR: xNr. by rewrite normr_eq0 => /ler. rewrite add0r {}/s -big_filter; set s := seq.filter _ _. rewrite [X in _<=X](bigID (ssrbool.mem J)) /=. rewrite (perm_big [seq x <- r | x \in J]) /=. apply/uniq_perm; rewrite ?filter_uniq // => x. by rewrite !mem_filter andbC. by rewrite big_filter ler_addl sumr_ge0. case/summable_of_bd: h => smS le_psum; apply/eqP. by rewrite eq_le le_psum /=; apply/gerfinseq_psum. Qed. End StdSum. (* -------------------------------------------------------------------- *) Section PSumReindex. Context {R : realType} {T U : choiceType}. Context (S : T -> R) (P : pred T) (h : U -> T). Lemma reindex_psum_onto h' : (forall x, S x != 0 -> x \in P) -> (forall i, i \in P -> omap h (h' i) = Some i) -> (forall i, h i \in P -> h' (h i) = Some i) -> psum S = psum (fun x : U => S (h x)). Proof. move=> PS hO hP; rewrite !psum_sup_seq; congr sup; rewrite predeqE => x. split=> -[J uqJ ->] {x}; last first. exists [seq h j | j <- J & S (h j) != 0]. rewrite map_inj_in_uniq ?filter_uniq // => y1 y2. rewrite !mem_filter => /andP[nz_S1 _] /andP[nz_S2 _]. by move/(congr1 h'); rewrite !hP ?PS // => -[]. apply/eqP; rewrite big_map big_filter. rewrite (bigID (fun i => S (h i) == 0)) /= big1 ?add0r //. by move=> y /eqP->; rewrite normr0. have uqpJ: uniq (pmap h' [seq j | j <- J & S j != 0]). apply/(map_uniq (f := some)); rewrite pmapS_filter. rewrite map_inj_in_uniq ?filter_uniq // => [y1 y2|]; last first. by rewrite map_id filter_uniq. rewrite !map_id !mem_filter => /andP[h'1 h1] /andP[h'2 h2]. case/andP: h1 => h1 _; case/andP: h2 => h2 _. by move/(congr1 (omap h)); rewrite !hO ?PS // => -[]. exists (pmap h' [seq j | j <- J & S j != 0]) => //. apply/eqP; rewrite -(big_map h predT \`|S|) (bigID [pred j | S j == 0]) /=. rewrite big1 ?add0r => [i /eqP->|]; first by rewrite normr0. rewrite -big_filter; apply/eqP; apply/perm_big/uniq_perm. + by rewrite filter_uniq. + rewrite map_inj_in_uniq // !map_id => y1 y2 h1 h2. move/(congr1 h'); rewrite !hP ?PS //; last by case. * move: h1; rewrite mem_pmap => /mapP[x1]. rewrite mem_filter => /andP[nz_Sx1 _] /(congr1 (omap h)) /=. by rewrite hO ?PS // => -[->]. * move: h2; rewrite mem_pmap => /mapP[x2]. rewrite mem_filter => /andP[nz_Sx2 _] /(congr1 (omap h)) /=. by rewrite hO ?PS // => -[->]. move=> x; rewrite !mem_filter; apply/andP/idP. + case=> nzSx Jx; apply/mapP; move/(_ x (PS _ nzSx)): hO. case E: (h' x) => [u|] //= -[xE]; exists u => //. rewrite mem_pmap; apply/mapP; exists x => //. by rewrite map_id mem_filter nzSx. + case/mapP=> u; rewrite mem_pmap => /mapP[t]; rewrite map_id. rewrite mem_filter=> /andP[h1 h2] /(congr1 (omap h)) /=. by rewrite hO ?PS // => -[->] ->; split. Qed. Lemma reindex_psum : (forall x, S x != 0 -> x \in P) -> {on P, bijective h} -> psum S = psum (fun x : U => S (h x)). Proof. move=> hP [hI h1 h2]; apply/(@reindex_psum_onto (some \o hI)) => //. + by move=> x Px /=; rewrite h2. + by move=> x Px /=; rewrite h1. Qed. End PSumReindex. (* -------------------------------------------------------------------- *) Section PSumPartition. Context {R : realType} {T U : choiceType} (f : T -> U). Let C y := `[< exists x : T, f x == y >]. Lemma partition_psum (S : T -> R) : summable S -> psum S = psum (fun y => psum (fun x => S x * (f x == y)%:R)). Proof. (* FIXME: this proof is a joke *) move=> smS; rewrite (rwP eqP) eq_le -(rwP andP); split. pose F x y := `|S x| * (f x == y :> U)%:R. have smFy y: summable (F^~ y). by apply/summable_condr/summable_abs. set G := fun y : U => _; have: summable G. case/summable_seqP: smS => M ge0_M leM. apply/summable_seqP; exists M => // J uqJ; rewrite {}/G. rewrite (eq_bigr (fun y => psum (F^~ y))) => [y _|]. rewrite ger0_norm ?ge0_psum //; apply/eq_psum_abs => x. by rewrite !normrM [ `|_%:R|]ger0_norm ?(normr_id, ler0n). rewrite psum_bigop // => [y x|]. by rewrite mulr_ge0 ?(normr_ge0, ler0n). apply/psum_le=> L uqL; pose G x := \sum_(j <- J | f x == j) `|S x|. rewrite (eq_bigr G) => [x _|]; first rewrite ger0_norm //. + by rewrite sumr_ge0 // => y _; rewrite mulr_ge0. + rewrite /G [RHS]big_mkcond /F /=; apply/eq_bigr=> y _. by case: ifPn => //; rewrite !simpm. rewrite {}/G /F; pose K := [seq x <- L | f x \in J]. apply/(le_trans _ (leM K _)); rewrite ?filter_uniq //. rewrite le_eqVlt -(rwP orP); left; apply/eqP. rewrite /K big_filter [RHS]big_mkcond /=; apply/eq_bigr. move=> x _; case: ifPn => [fxJ|fxNJ]. rewrite big_mkcond (bigD1_seq _ fxJ uqJ) /= eqxx. by rewrite big1 ?addr0 // => y; rewrite eq_sym => /negbTE=> ->. rewrite big_seq_cond big1 // => y; rewrite andbC. by case/andP=> /eqP<-; rewrite (negbTE fxNJ). move=> smG; apply/psum_le => J uqJ; pose K := undup (map f J). move/gerfinseq_psum: smG => /(_ K (undup_uniq _)). move/(le_trans _); apply; rewrite {}/G. pose G x y := `|S x| * (f x == y)%:R. rewrite (eq_bigr (fun y => psum (G^~ y))). move=> y _; rewrite ger0_norm ?ge0_psum //. rewrite -psum_abs; apply/eq_psum=> x. by rewrite normrM [ `|_%:R|]ger0_norm ?ler0n. rewrite psum_bigop => [y x|y|]; first by rewrite mulr_ge0. by apply/summable_condr/summable_abs. rewrite (eq_psum (F2 := fun x => `|S x * (f x \in K)%:R|)). move=> x; rewrite {}/G normrM. (*[ `|_%:R|]ger0_norm //.*) case/boolP: (f x \in K); last first. move=> fxNK. rewrite [ `|_%:R|]ger0_norm // mulr0 big_seq big1 // => y. apply/contraTeq; rewrite mulf_eq0 pnatr_eq0 eqb0. by rewrite negb_or negbK => /andP[_ /eqP<-]. move=> fxK; rewrite (bigD1_seq (f x)) ?undup_uniq //=. rewrite [ `|_%:R|]ger0_norm // ?ler01 // eqxx !mulr1 big1 ?addr0 // => y; rewrite eq_sym. by move/negbTE=> ->; rewrite mulr0. rewrite big_seq (eq_bigr (fun j => `|S j * (f j \in K)%:R|)) {}/G. by move=> x /(map_f f); rewrite -mem_undup => ->; rewrite mulr1. rewrite psum_abs; set G := (fun x : T => _ in X in _<=X). have: summable G by apply/summable_condr. move/gerfinseq_psum => /(_ _ uqJ) /(le_trans _); apply. by rewrite -big_seq; apply/ler_sum => x _; rewrite normrM. apply/psum_le=> J uqJ; pose F j := psum (fun x => `|S x| * (f x == j)%:R). rewrite (eq_bigr F) => [y _|]; first rewrite ger0_norm ?ge0_psum //. + rewrite -psum_abs; apply/eq_psum => x; rewrite normrM. by rewrite [ `|_%:R|]ger0_norm ?ler0n. rewrite psum_bigop => [y x|y|]. + by rewrite mulr_ge0 ?(normr_ge0, ler0n). + by apply/summable_condr/summable_abs. apply/psum_le=> L uqL; pose K := [seq x <- L | f x \in J]. have /gerfinseq_psum: uniq K by rewrite filter_uniq. move=> /(_ _ _ smS) /(le_trans _); apply; rewrite big_filter. rewrite le_eqVlt -(rwP orP); left; apply/eqP. rewrite [RHS]big_mkcond /=; apply/eq_bigr=> x _. rewrite big_seq; case: ifPn => [fx_in_J|fx_Nin_J]. rewrite -big_seq (bigD1_seq _ fx_in_J uqJ) /= eqxx mulr1. rewrite big1 ?addr0 ?normr_id // => y; rewrite eq_sym. by move/negbTE=> ->; rewrite mulr0. rewrite big1 ?normr0 // => y; apply/contraTeq. rewrite mulf_eq0 pnatr_eq0 eqb0 negb_or negbK. by case/andP => _ /eqP<-. Qed. Lemma partition_psum_cond (S : T -> R) : summable S -> psum S = psum (fun y => (C y)%:R * psum (fun x => S x * (f x == y)%:R)). Proof. move=> smS; apply/(eq_trans (partition_psum smS)). apply/eq_psum => y; case/boolP: (C y); rewrite !simpm //. move=> NCy; rewrite psum_eq0 // => x; case: (_ =P y). by move/eqP=> fxE; move/asboolP: NCy; case; exists x. by rewrite mulr0. Qed. End PSumPartition. (* -------------------------------------------------------------------- *) Section PSumPair. Context {R : realType} {T U : choiceType}. Lemma psum_pair (S : T * U -> R) : summable S -> psum S = psum (fun x => psum (fun y => S (x, y))). Proof. move=> sblS; rewrite (partition_psum fst) //; apply/eq_psum. move=> x /=; pose P := [pred xy : T * U | xy.1 == x]. rewrite (reindex_psum (h := [eta pair x]) (P := P)) //=. + case=> x' y' /=; rewrite mulf_eq0 => /norP[_]. by rewrite pnatr_eq0 eqb0 negbK /P inE => /eqP->. + by exists snd => // -[x' y'] /eqP /= <-. by apply/eq_psum=> y /=; rewrite eqxx mulr1. Qed. Lemma psum_pair_swap (S : T * U -> R) : summable S -> psum S = psum (fun y => psum (fun x => S (x, y))). Proof. move=> sblS; rewrite (partition_psum snd) //; apply/eq_psum. move=> y /=; pose P := [pred xy : T * U | xy.2 == y]. rewrite (reindex_psum (h := [eta pair^~ y]) (P := P)) //=. + case=> x' y' /=; rewrite mulf_eq0 => /norP[_]. by rewrite pnatr_eq0 eqb0 negbK /P inE => /eqP->. + by exists fst => // -[x' y'] /eqP /= <-. by apply/eq_psum=> x /=; rewrite eqxx mulr1. Qed. End PSumPair. (* -------------------------------------------------------------------- *) (* FIXME: MOVE ME *) Section SupInterchange. Context {R : realType} {T U : Type}. Lemma interchange_sup (S : T -> U -> R) : (forall x, has_sup [set r | exists y, r = S x y]) -> has_sup [set r | exists x, r = sup [set r | exists y, r = S x y]] -> sup [set r | exists x, r = sup [set r | exists y, r = S x y]] = sup [set r | exists y, r == sup [set r | exists x, r = S x y]]. Proof using Type. Admitted. End SupInterchange. (* -------------------------------------------------------------------- *) Section PSumInterchange. Context {R : realType} {T U : choiceType}. Lemma interchange_psum (S : T -> U -> R) : (forall x, summable (S x)) -> summable (fun x => psum (fun y => S x y)) -> psum (fun x => psum (fun y => S x y)) = psum (fun y => psum (fun x => S x y)). Proof using Type. Admitted. End PSumInterchange. (* -------------------------------------------------------------------- *) Section SumTheory. Context {R : realType} {T : choiceType}. Implicit Types (S : T -> R). Lemma psum_sum S : (forall x, 0 <= S x) -> psum S = sum S. Proof. move=> ge0_S; rewrite /sum [X in _-X]psum_eq0 ?subr0. by move=> x; rewrite fneg_ge0. by apply/eq_psum=> x; rewrite fpos_ge0. Qed. Lemma le_sum S1 S2 : summable S1 -> summable S2 -> (S1 <=1 S2) -> sum S1 <= sum S2. Proof. move=> smS1 smS2 leS; rewrite /sum ler_sub //. apply/le_psum/summable_fpos => // x. by rewrite ge0_fpos /= le_fpos. apply/le_psum/summable_fneg => // x. rewrite -!fposN ge0_fpos le_fpos // => y. by rewrite ler_opp2. Qed. Lemma sum0 : sum (fun _ : T => 0) = 0 :> R. Proof. by rewrite /sum !(eq_psum fpos0, eq_psum fneg0) !psum0 subr0. Qed. Lemma sumN S : sum (- S) = - sum S. Proof. by rewrite /sum (eq_psum (fnegN _)) (eq_psum (fposN _)) opprB. Qed. Lemma sumZ S c : sum (c \*o S) = c * sum S. Proof. rewrite (eq_sum (F2 := fun x => Num.sg c * (`|c| * S x))). by move=> x; rewrite mulrA -numEsg. transitivity (Num.sg c * sum (`|c| \*o S)). case: sgrP => [_|gt0_c|lt0_c]; rewrite ?Monoid.simpm. + by rewrite (eq_sum (F2 := fun _ => 0)) ?sum0 // => x; rewrite !mul0r. + by apply/eq_sum=> x; rewrite mul1r. by rewrite mulN1r -sumN; apply/eq_sum=> x; rewrite !mulN1r. rewrite {1}/sum !(eq_psum (fposZ _ _), eq_psum (fnegZ _ _)) //. by rewrite !psumZ // -mulrBr mulrA -numEsg. Qed. Lemma sumID S (P : pred T) : summable S -> sum S = sum (fun x => (P x)%:R * S x) + sum (fun x => (~~ P x)%:R * S x). Proof. move=> sm_S; rewrite /sum addrACA -[in RHS]opprD; congr (_ - _). + rewrite (psumID P); first by apply/summable_fpos. by congr (_ + _); apply/eq_psum => x; rewrite fpos_natrM. + rewrite (psumID P); first by apply/summable_fneg. by congr (_ + _); apply/eq_psum => x; rewrite fneg_natrM. Qed. Lemma sum_finseq S (r : seq T) : uniq r -> {subset [pred x | S x != 0] <= r} -> sum S = \sum_(x <- r) S x. Proof. move=> eqr domS; rewrite /sum !(psum_finseq eqr). + move=> x; rewrite !inE => xPS; apply/domS; rewrite !inE. move: xPS; rewrite /fpos normr_eq0. by apply: contra => /eqP ->; rewrite maxxx. + move=> x; rewrite !inE => xPS; apply/domS; rewrite !inE. move: xPS; rewrite /fneg normr_eq0. by apply: contra => /eqP ->; rewrite minxx. rewrite -sumrB; apply/eq_bigr=> i _. by rewrite !ger0_norm ?(ge0_fpos, ge0_fneg) ?fposBfneg. Qed. Lemma sum_seq1 S x : (forall y, S y != 0 -> x == y) -> sum S = S x. Proof. move=> domS; rewrite (sum_finseq (r := [:: x])) //. by move=> y; rewrite !inE => /domS /eqP->. by rewrite big_seq1. Qed. End SumTheory. Arguments sum_seq1 {R T} [S] x _.