clutch.prelude.Series_ext
From Stdlib Require Import Reals Psatz.
From Coquelicot Require Import Series Lim_seq Rbar Rcomplements.
From stdpp Require Export countable sets.
From clutch.prelude Require Import base Coquelicot_ext stdpp_ext classical.
From discprob.prob Require Import double.
Set Default Proof Using "Type*".
Import Hierarchy.
Open Scope R.
Section rbar_extra.
Lemma Rbar_le_sandwich p q r :
Rbar_le (Finite p) r ->
Rbar_le r (Finite q) ->
Finite (real r) = r.
Proof.
intros Hp Hq.
destruct r eqn:Hr; auto.
- destruct Hq.
- destruct Hp.
Qed.
Lemma rbar_le_finite (p : R) (q : Rbar) :
is_finite q ->
Rbar_le p q ->
p <= real q.
Proof.
intros Hq Hle.
rewrite /is_finite/= in Hq.
destruct q; auto; simplify_eq.
Qed.
Lemma finite_rbar_le (p : R) (q : Rbar) :
is_finite q ->
Rbar_le q p ->
q <= real p.
Proof.
intros Hq Hle.
rewrite /is_finite/= in Hq.
destruct q; auto; simplify_eq.
Qed.
Lemma rbar_le_rle (p : R) (q : R) :
Rbar_le (Finite p) (Finite q) <-> Rle p q.
Proof.
auto.
Qed.
Lemma is_finite_bounded (p q : R) (r : Rbar) :
Rbar_le p r ->
Rbar_le r q ->
is_finite r.
Proof.
intros H1 H2.
rewrite /is_finite.
destruct r eqn:Hr; auto.
- destruct H2.
- destruct H1.
Qed.
Lemma rbar_finite_real_eq (p : Rbar) :
is_finite p ->
Finite (real p) = p.
Proof.
intro Hfin.
destruct p; auto.
Qed.
Lemma rbar_le_finite_real r :
Rbar_le (Finite 0) r ->
Rbar_le (Finite (real r)) r.
Proof.
intro Hpos.
destruct r eqn:Heq; simpl; auto.
apply Rle_refl.
Qed.
Lemma rbar_scal_r (p : Rbar) (r : R) :
is_finite p ->
(real p) * r = real (Rbar_mult p (Finite r)).
Proof.
intro Hfin.
destruct p ; simpl; auto.
all:case_match; simpl; try lra; inversion Hfin.
Qed.
End rbar_extra.
Lemma ex_series_eventually0 (a: nat → R):
(∃ N, ∀ n, n ≥ N → a n = 0) → ex_series a.
Proof.
intros (N & Hev0). apply: ex_series_Cauchy.
rewrite /Cauchy_series => eps. exists N => n m Hlen Hlem.
assert (Heq: sum_n_m a n m = 0).
{ rewrite /sum_n_m.
rewrite (Iter.iter_nat_ext_loc _ _ _ (λ x, 0)).
- rewrite /plus/zero//=/Iter.iter_nat Iter.iter_const; nra.
- intros k (?&?). apply Hev0. lia. }
rewrite /norm //= /abs //=. destruct eps =>//=. rewrite Heq Rabs_right; nra.
Qed.
Lemma mon_succ_to_mon (h : nat → R) :
(∀ p, h p <= h (S p)) →
(∀ m n, (m <= n)%nat → h m <= h n).
Proof.
intros Hmon m.
induction m; intro n; induction n.
- intros; apply Rle_refl.
- intro. apply (Rle_trans _ (h n)); auto with arith.
- intro Haux.
inversion Haux.
- intro Haux.
destruct (decide ((S m <= n)%nat)) as [Hle | Hgt].
+ apply (Rle_trans _ (h n)); auto with arith.
+ assert (S m = S n) as ->; [ | apply Rle_refl].
assert ((n < S m)%nat); auto with arith.
apply not_le; auto.
Qed.
Lemma is_series_ge0 (h : nat → R) r:
(∀ n, 0 <= h n) →
is_series h r →
0 <= r.
Proof.
intros Hge Hs.
erewrite <- (Series_0 (λ y, 0)); auto.
rewrite <- (is_series_unique _ _ Hs).
eapply (Series_le).
{ intro n; split; auto; lra. }
rewrite /ex_series.
exists r; auto.
Qed.
Lemma lim_is_sup (h: nat → R) r :
(∀ n, 0 <= h n) →
is_series h r →
is_sup_seq (sum_n h) (Finite r).
Proof.
intros Hge Hs.
rewrite /is_sup_seq.
pose proof (is_series_partial_pos h) as Hpart.
pose proof (is_series_ge0 _ _ Hge Hs) as Hr.
intro eps; split.
- intro n.
specialize (Hpart n r Hge Hs).
rewrite /Rbar_lt.
assert (eps > 0); try lra.
pose proof (cond_pos eps); lra.
- pose proof (Hs) as Hs'.
specialize (Hs (ball r eps)).
assert (∃ N : nat, ∀ n : nat, N ≤ n → ball r eps (sum_n h n)) as (N & HN).
{apply Hs. exists eps. auto. }
exists N; simpl.
specialize (HN N (Nat.le_refl N)).
specialize (Hpart N r Hge Hs').
rewrite /ball /= /AbsRing_ball in HN.
cut (r - (sum_n h N) < eps); try lra.
rewrite abs_minus /abs /= in HN.
assert (Rabs (minus r (sum_n h N)) = minus r (sum_n h N)) as Habs.
{ apply Rabs_right.
rewrite /minus /plus /= /opp /=.
lra. }
rewrite Habs in HN.
rewrite /minus /plus /= /opp /= in HN.
lra.
Qed.
Lemma sup_is_lim (h: nat → R) r :
(∀ n, 0 <= h n) →
is_sup_seq (sum_n h) (Finite r) →
is_series h r.
Proof.
intros Hge Hsup.
rewrite /is_sup_seq in Hsup.
intros P (eps & Heps).
rewrite /ball /= /AbsRing_ball in Heps.
destruct (Hsup eps) as (HsupFor & (N & HsupN)).
exists N; intros n Hn.
specialize (HsupFor n).
specialize (Heps (sum_n h n)).
assert (sum_n h N <= sum_n h n) as HNn.
{ by apply partial_sum_mon. }
apply Heps.
rewrite /Rbar_lt in HsupFor.
rewrite /Rbar_lt in HsupN.
assert (r - eps < sum_n h n); [try lra | ].
rewrite /abs /= /Rabs /minus /plus /= /opp /=.
destruct Rcase_abs; lra.
Qed.
Lemma lim_is_sup' (h: nat → R) :
(∀ n, 0 <= h n) →
ex_series h →
Series h = real (Sup_seq (sum_n h)).
Proof.
intros Hpos Hex.
apply Series_correct, lim_is_sup, is_sup_seq_unique in Hex; auto.
apply eq_rbar_finite; auto.
Qed.
Lemma lim_is_sup'' (h: nat → R) :
(∀ n, 0 <= h n) →
ex_series h →
is_series h (real (Sup_seq (sum_n h))).
Proof.
intros Hpos Hex.
rewrite <- lim_is_sup'; auto.
apply Series_correct; auto.
Qed.
Lemma sup_is_upper_bound (h : nat → Rbar) n :
Rbar_le (h n) (Sup_seq h).
Proof.
apply is_sup_seq_major.
apply Sup_seq_correct.
Qed.
Lemma sup_is_upper_bound' (h : nat → R) n r :
is_sup_seq h (Finite r) →
h n <= r.
Proof.
intro Hr.
assert (Rbar_le (Finite (real (h n))) (Finite r)); auto.
assert (real (Finite (h n)) = h n) as ->; auto.
apply (is_sup_seq_major (fun x : nat => Finite (h x)) (Finite r)); auto.
Qed.
Lemma upper_bound_ge_sup (h : nat → Rbar) r :
(∀ n, Rbar_le (h n) r) →
Rbar_le (Sup_seq h) r.
Proof.
intro H2.
pose proof (is_sup_seq_lub h (Sup_seq h) (Sup_seq_correct h)) as H3.
rewrite /Lub.Rbar_is_lub in H3.
apply H3.
rewrite /Lub.Rbar_is_upper_bound.
intros q (n & Hn).
rewrite Hn; auto.
Qed.
Lemma upper_bound_ge_sup' (h : nat → R) r l :
is_sup_seq h (Finite l) →
(∀ n, h n <= r) →
l <= r.
Proof.
intros Hsup H2.
assert (Rbar_le (Finite l) (Finite r)); auto.
rewrite <- (is_sup_seq_unique (λ x : nat, h x) l); auto.
apply (upper_bound_ge_sup (λ x : nat, h x) r); auto.
Qed.
Lemma sup_seq_eq_antisym (h1 h2 : nat → R) :
(∀ m, ∃ n, h1 m <= h2 n) →
(∀ m, ∃ n, h2 m <= h1 n) →
Sup_seq h1 = Sup_seq h2.
Proof.
intros H1 H2.
apply Rbar_le_antisym.
+ apply upper_bound_ge_sup; intro n.
destruct (H1 n) as (m & ?).
apply (Sup_seq_minor_le _ _ m); auto.
+ apply upper_bound_ge_sup; intro n.
destruct (H2 n) as (m & ?).
apply (Sup_seq_minor_le _ _ m); auto.
Qed.
Lemma sup_seq_swap (h : nat * nat → R) :
Sup_seq (λ n, Sup_seq (λ m, h (n , m))) =
Sup_seq (λ m, Sup_seq (λ n, h (n , m))).
Proof.
apply Rbar_le_antisym.
+ apply upper_bound_ge_sup; intro n.
apply upper_bound_ge_sup; intro m.
apply (Sup_seq_minor_le _ _ m).
apply (Sup_seq_minor_le _ _ n).
simpl; lra.
+ apply upper_bound_ge_sup; intro n.
apply upper_bound_ge_sup; intro m.
apply (Sup_seq_minor_le _ _ m).
apply (Sup_seq_minor_le _ _ n).
simpl; lra.
Qed.
Lemma Sup_seq_scal_r (a : R) (u : nat → Rbar):
0 <= a →
Sup_seq (λ n : nat, Rbar_mult (u n) a) = Rbar_mult (Sup_seq u) a.
Proof.
intro.
rewrite Rbar_mult_comm -Sup_seq_scal_l //.
apply Sup_seq_ext.
intro; apply Rbar_mult_comm.
Qed.
Lemma Sup_seq_scal_l' (a:R) (u : nat -> R) :
0<=a -> is_finite (Sup_seq u) -> real (Sup_seq (λ n, a* u n)) = a* (real (Sup_seq u)).
Proof.
intros H H'.
apply eq_rbar_finite'.
rewrite rmult_finite.
rewrite rbar_finite_real_eq; last done.
rewrite -Sup_seq_scal_l; last done.
apply Sup_seq_ext.
intros.
by rewrite rmult_finite.
Qed.
Lemma Sup_seq_scal_r' (a:R) (u : nat -> R) :
0<=a -> is_finite (Sup_seq u) -> real (Sup_seq (λ n, u n * a)) = (real (Sup_seq u)) * a.
Proof.
intros.
rewrite Rmult_comm.
rewrite -Sup_seq_scal_l'; try done.
f_equal.
apply Sup_seq_ext. intros. rewrite Rmult_comm. done.
Qed.
Lemma sum_n_plus f g n:
sum_n f n + sum_n g n = sum_n (λ x, f x + g x) n.
Proof.
induction n.
- by rewrite !sum_O.
- rewrite !sum_Sn.
replace (plus _ _ + plus _ _) with ((sum_n f n + sum_n g n)+(f (S n) + g (S n))); last first.
{ assert (forall x y, plus x y = x + y).
- intros. done.
- rewrite !H. lra.
}
rewrite IHn. done.
Qed.
Lemma sum_n_inj `{Inj nat nat eq eq h} (f : nat -> R) n m :
(forall n, 0 <= f n) ->
(forall x : nat, x <= n -> h x <= m)%nat ->
(sum_n (λ n0 : nat, f (h n0)) n) <= (sum_n (λ n0 : nat, f n0) m).
Proof.
intros Hf Hh.
pose proof make_decision.
trans (sum_n (λ n0 : nat, if bool_decide (∃ x, n0 = h x /\ x<=n)%nat then f n0 else 0) m); last first.
{ apply sum_n_le. intros. case_bool_decide; try lra. naive_solver. }
revert m Hh.
induction n.
- intros. rewrite sum_O. etrans; last eapply partial_sum_mon.
+ etrans; last apply partial_sum_elem.
* case_bool_decide as H0; first done.
exfalso. apply H0. naive_solver.
* intros. case_bool_decide; naive_solver.
+ intros. case_bool_decide; naive_solver.
+ naive_solver.
- intros. rewrite sum_Sn.
replace (sum_n _ m) with (sum_n (λ n0 : nat, if bool_decide (∃ x : nat, n0 = h x ∧ x ≤ n) then f n0 else 0) m + sum_n (λ n0 : nat, if bool_decide (n0 = h (S n)) then f n0 else 0) m).
+ apply Rplus_le_compat; first naive_solver.
etrans; last eapply partial_sum_mon; first (etrans; last apply partial_sum_elem).
* by case_bool_decide.
* intros; case_bool_decide; naive_solver.
* intros; case_bool_decide; naive_solver.
* naive_solver.
+ clear IHn.
remember m as k. rewrite Heqk in Hh. clear Heqk.
rewrite sum_n_plus. f_equal. apply functional_extensionality_dep.
intros x.
repeat case_bool_decide; try done; try lra.
* subst. destruct H0 as [?[??]]; destruct H2 as [?[??]].
rewrite H0 in H2. apply H in H0. subst. lia.
* exfalso. naive_solver.
* exfalso. naive_solver.
* exfalso. naive_solver.
* exfalso. apply H0. destruct H2 as [?[??]]. subst.
rewrite Nat.le_succ_r in H3. naive_solver.
Qed.
Lemma sum_n_pseudo_inj (h : nat -> nat)(f : nat -> R) n m :
(forall n, 0 <= f n) ->
(forall x y, h x = h y -> f (h x) ≠ 0 -> x = y) ->
(forall x : nat, x <= n -> h x <= m)%nat ->
(sum_n (λ n0 : nat, f (h n0)) n) <= (sum_n (λ n0 : nat, f n0) m).
Proof.
intros Hf H Hh.
pose proof make_decision.
trans (sum_n (λ n0 : nat, if bool_decide (∃ x, n0 = h x /\ x<=n)%nat then f n0 else 0) m); last first.
{ apply sum_n_le. intros. case_bool_decide; try lra. naive_solver. }
revert m Hh.
induction n.
- intros. rewrite sum_O. etrans; last eapply partial_sum_mon.
+ etrans; last apply partial_sum_elem.
* case_bool_decide as H0; first done.
exfalso. apply H0. naive_solver.
* intros. case_bool_decide; naive_solver.
+ intros. case_bool_decide; naive_solver.
+ naive_solver.
- intros. rewrite sum_Sn.
replace (sum_n _ m) with (sum_n (λ n0 : nat, if bool_decide (∃ x : nat, n0 = h x ∧ x ≤ n) then f n0 else 0) m + sum_n (λ n0 : nat, if bool_decide (n0 = h (S n)) then f n0 else 0) m).
+ apply Rplus_le_compat; first naive_solver.
etrans; last eapply partial_sum_mon; first (etrans; last apply partial_sum_elem).
* by case_bool_decide.
* intros; case_bool_decide; naive_solver.
* intros; case_bool_decide; naive_solver.
* naive_solver.
+ clear IHn.
remember m as k. rewrite Heqk in Hh. clear Heqk.
rewrite sum_n_plus. f_equal. apply functional_extensionality_dep.
intros x.
repeat case_bool_decide; try done; try lra.
* subst. destruct H0 as [?[??]]; destruct H2 as [?[??]].
rewrite H0 in H2.
destruct (decide (f (h (S n)) = 0)); first by lra.
apply H in H0; auto. subst. lia.
* exfalso. naive_solver.
* exfalso. naive_solver.
* exfalso. naive_solver.
* exfalso. apply H0. destruct H2 as [?[??]]. subst.
rewrite Nat.le_succ_r in H3. naive_solver.
Qed.
Lemma sum_n_surj_le_some_index h f n:
Surj eq h ->
(∀ n : nat, 0 <= f n) ->
∃ k : nat, sum_n f n <= sum_n (λ n0 : nat, f (h n0)) k.
Proof.
intros.
cut (∃ k : nat, ∃ l, NoDup l /\
(forall x, x∈l -> h x <= n)%nat /\
sum_n f n <= sum_n (λ n0 : nat, if bool_decide (n0 ∈ l /\ h n0 <= n)%nat then f (h n0) else 0) k).
{ elim. intros. destruct H1 as [?[?[??]]]. eexists _. etrans; first exact. apply sum_n_le.
intros. case_bool_decide; naive_solver.
}
induction n.
- pose proof (H 0%nat) as [??].
exists x, (x::[]).
split; first constructor.
+ apply not_elem_of_nil.
+ constructor.
+ split.
* intros. assert (x0=x) as -> by set_solver. rewrite H1. lia.
* etrans; last apply partial_sum_elem.
-- rewrite sum_O. case_bool_decide; try done; first by rewrite H1.
exfalso. apply H2. rewrite H1. split; set_solver.
-- intros. case_bool_decide; naive_solver.
- destruct IHn as [x[l[Hl [Hcond IHn]]]].
pose proof (H (S n)) as [x0?].
pose proof (Nat.le_gt_cases x0 x) as [|].
+ exists x, (x0::l). repeat split.
* constructor; last done.
intro. apply Hcond in H3.
rewrite H1 in H3. lia.
* set_unfold; try naive_solver.
intros ?[|]; try naive_solver.
subst. lia.
* rewrite sum_Sn. etrans; first apply Rplus_le_compat.
-- exact.
-- instantiate (1:= sum_n (λ n', if bool_decide (n'=x0) then f (h n') else 0) (x)).
etrans; last apply partial_sum_mon; last exact.
++ etrans; last apply partial_sum_elem.
** case_bool_decide; subst.
--- rewrite H1. done.
--- done.
** intros. case_bool_decide; naive_solver.
++ intros; case_bool_decide; naive_solver.
-- rewrite sum_n_plus. apply sum_n_le.
intros; repeat case_bool_decide; try lra.
++ subst. rewrite H1 in H3. lia.
++ subst. exfalso. set_solver.
++ exfalso. set_solver.
++ subst. exfalso. apply H5. rewrite H1. set_unfold. naive_solver.
++ etrans; last apply H0. lra.
+ exists x0, (x0::l).
repeat split.
* constructor; last done.
intro. apply Hcond in H3.
rewrite H1 in H3. lia.
* intros. rewrite elem_of_cons in H3. destruct H3; last naive_solver.
subst. lia.
* assert (∃ x', x0 = S x') as [?->].
{ destruct x0; last naive_solver. lia. }
rewrite !sum_Sn. apply Rplus_le_compat.
-- etrans; first exact.
etrans; last eapply sum_n_le.
++ apply partial_sum_mon; last lia.
intros. case_bool_decide; naive_solver.
++ intros. repeat case_bool_decide; try done.
exfalso. set_unfold. naive_solver.
-- case_bool_decide; first by rewrite H1.
set_unfold; exfalso; apply H3. split; first naive_solver.
lia.
Qed.
Fixpoint max_seq (f : nat -> nat) n :=
match n with
| 0 => f 0%nat
| S m => max (f (S m)) (max_seq f m)
end.
Lemma le_max_seq (f : nat -> nat) n m :
m ≤ n ->
f m ≤ max_seq f n.
Proof.
intros Hleq.
induction Hleq.
- destruct m; simpl; [lia|].
apply Nat.le_max_l.
- simpl.
etrans; eauto.
apply Nat.le_max_r.
Qed.
Lemma sum_max_seq (f : nat -> R) h n `{Inj nat nat eq eq h}:
(forall n, 0 <= f n) ->
(sum_n (λ n0 : nat, f (h n0)) n) <= (sum_n (λ n0 : nat, f n0) (max_seq h n)).
Proof.
intros.
apply sum_n_inj; first done.
clear.
induction n; simpl; intros.
- assert (x=0%nat); try lia. by subst.
- rewrite Nat.le_succ_r in H. destruct H.
+ etrans; first by apply IHn.
apply Nat.le_max_r.
+ subst. apply Nat.le_max_l.
Qed.
Lemma sum_max_seq_pseudo_inj (f : nat -> R) (h : nat -> nat) n:
(forall n, 0 <= f n) ->
(forall x y, h x = h y -> f (h x) ≠ 0 -> x = y) ->
(sum_n (λ n0 : nat, f (h n0)) n) <= (sum_n (λ n0 : nat, f n0) (max_seq h n)).
Proof.
intros Hpos H.
apply sum_n_pseudo_inj.
1,2: done.
clear.
induction n; simpl; intros.
- assert (x=0%nat); try lia. by subst.
- rewrite Nat.le_succ_r in H. destruct H.
+ etrans; first by apply IHn.
apply Nat.le_max_r.
+ subst. apply Nat.le_max_l.
Qed.
Lemma is_series_bijection (f : nat -> R) h v `{Bij nat nat h} :
(forall n, 0 <= f n) ->
is_series f v ->
is_series (λ n, f (h n)) v.
Proof.
intros Hpos Hf.
unfold is_series.
rewrite /is_series.
apply sup_is_lim; auto.
apply lim_is_sup in Hf; auto.
intro eps; split.
- assert (forall n, (sum_n (λ n0 : nat, f (h n0)) n) <= (sum_n (λ n0 : nat, f n0) (max_seq h n))) as Haux.
{
intro; eapply sum_max_seq; eauto.
apply bij_inj.
}
intro n.
eapply Rbar_le_lt_trans; [apply rbar_le_rle, Haux | apply Hf ].
- apply Classical_Pred_Type.not_all_not_ex.
intro H1.
apply (upper_bound_ge_sup' _ (v-eps)) in Hf.
{ assert (0<eps); try lra. apply cond_pos. }
intros. assert (∀ n : nat, (sum_n (λ n0 : nat, f (h n0)) n) <= v-eps).
{ intros. apply Rnot_lt_le. apply H1. }
cut (∃ k, sum_n f n <= sum_n (λ n0 : nat, f (h n0)) k).
{ elim. intros. etrans; first exact. done. }
apply sum_n_surj_le_some_index; destruct H; naive_solver.
Qed.
Lemma fubini_fin_sum (h : nat * nat → R) n m:
sum_n (λ a, sum_n (λ b, h (a, b)) n ) m
= sum_n (λ b, sum_n (λ a, h (a, b)) m ) n.
Proof.
intros.
apply sum_n_switch.
Qed.
Lemma Series_real_sup (h: nat → R) :
(∀ n, 0 <= h n) →
Series h = (real (Sup_seq (sum_n h))).
Proof.
intros Hpos.
rewrite /Series.
f_equal.
apply is_lim_seq_unique.
apply is_LimSup_LimInf_lim_seq.
- apply is_LimSup_infSup_seq.
apply Rbar_is_glb_inf_seq.
rewrite /Lub.Rbar_is_glb/=;split.
+ rewrite /Lub.Rbar_is_lower_bound.
intros x (n&->).
apply Sup_seq_le.
intro; simpl.
apply partial_sum_mon; auto; lia.
+ rewrite /Lub.Rbar_is_lower_bound.
intros b Hb.
apply Hb.
exists 0%nat. apply Sup_seq_ext; intro.
by rewrite Nat.add_0_r.
- apply is_LimInf_supInf_seq.
eapply (is_sup_seq_ext (λ n : nat, sum_n h (n))).
+ intro n; symmetry.
apply is_inf_seq_unique.
rewrite /is_inf_seq.
intro eps; split.
* intro n0; simpl.
eapply (Rlt_le_trans _ (sum_n h n));
[ | apply partial_sum_mon; auto; lia].
apply Rlt_minus_l.
rewrite <- Rplus_0_r at 1.
apply Rplus_lt_compat_l.
apply cond_pos.
* exists 0%nat; simpl.
rewrite <- Rplus_0_r at 1.
apply Rplus_lt_compat_l.
apply cond_pos.
+ apply Sup_seq_correct.
Qed.
Lemma ex_pos_bounded_series (h : nat → R) :
(∀ n, 0 <= h n) →
(∃ l, ∀ n, sum_n h n <= l) →
ex_series h.
Proof.
intros Hpos (l & Hl).
exists (real (Sup_seq (λ n, sum_n h n))).
apply sup_is_lim; auto.
rewrite (Rbar_le_sandwich 0 l).
- apply Sup_seq_correct.
- apply (Rbar_le_trans _ (sum_n h 0%nat)).
+ rewrite sum_O.
assert (0 <= (h 0%nat)); auto.
+ apply (sup_is_upper_bound (λ n : nat, sum_n h n) 0%nat).
- destruct (Sup_seq (λ n : nat, sum_n h n)) eqn:Hsup; simpl; auto.
+ assert (Rbar_le (Finite r) (Finite l)); auto.
rewrite <- Hsup.
apply upper_bound_ge_sup.
intro n; auto.
specialize (Hl n); auto.
+ assert (Rbar_le (p_infty) (Finite l)); auto.
rewrite <- Hsup.
apply upper_bound_ge_sup.
intro n; auto.
specialize (Hl n); auto.
Qed.
Lemma ex_series_inj (f : nat -> R) h `{Inj nat nat eq eq h} :
(forall n, 0 <= f n) ->
ex_series f ->
ex_series (λ n, f (h n)).
Proof.
intros Hpos [l Hl].
apply ex_pos_bounded_series; auto.
exists l.
apply lim_is_sup in Hl; auto.
assert (forall n, (sum_n (λ n0 : nat, f (h n0)) n) <= (sum_n (λ n0 : nat, f n0) (max_seq h n))) as Haux.
{
intro; eapply sum_max_seq; eauto.
}
intro n.
etrans; eauto.
apply (is_sup_seq_major _ _ (max_seq h n)) in Hl.
auto.
Qed.
Lemma ex_series_pseudo_inj (f : nat -> R) (h: nat -> nat) :
(forall n, 0 <= f n) ->
(forall x y, h x = h y -> f (h x) ≠ 0 -> x = y) ->
ex_series f ->
ex_series (λ n, f (h n)).
Proof.
intros Hpos H [l Hl].
apply ex_pos_bounded_series; auto.
exists l.
apply lim_is_sup in Hl; auto.
assert (forall n, (sum_n (λ n0 : nat, f (h n0)) n) <= (sum_n (λ n0 : nat, f n0) (max_seq h n))) as Haux.
{
intro; eapply sum_max_seq_pseudo_inj; eauto.
}
intro n.
etrans; eauto.
apply (is_sup_seq_major _ _ (max_seq h n)) in Hl.
auto.
Qed.
Lemma double_sup_diag (h : nat * nat → R) :
(∀ n m n', (n <= n')%nat → h (n, m) <= h (n' , m)) →
(∀ n m m', (m <= m')%nat → h (n, m) <= h (n , m')) →
Sup_seq (λ n, Sup_seq (λ m, h (n, m))) =
Sup_seq (λ n, h (n, n)).
Proof.
intros Hmon1 Hmon2.
apply Rbar_le_antisym.
- apply upper_bound_ge_sup.
intro n.
apply upper_bound_ge_sup.
intro m.
eapply Rbar_le_trans; last first.
+ apply (sup_is_upper_bound _ (n `max` m)).
+ apply (Rbar_le_trans _ (h ((n `max` m), m))).
* apply Hmon1, Nat.le_max_l.
* apply Hmon2, Nat.le_max_r.
- apply upper_bound_ge_sup.
intro n.
eapply Rbar_le_trans; last first.
+ apply (sup_is_upper_bound _ n).
+ eapply Rbar_le_trans; last first.
* apply (sup_is_upper_bound _ n).
* apply Rbar_le_refl.
Qed.
Lemma double_major_ex_series (h1 : nat → R) (h2 : nat → R) :
(∀ n, 0 <= h1 n) →
(∀ n, 0 <= h2 n) →
(∀ n, ∃ m, sum_n h1 n <= sum_n h2 m) →
(∀ n, ∃ m, sum_n h2 n <= sum_n h1 m) →
ex_series h1 →
ex_series h2.
Proof.
intros Hpos1 Hpos2 Hmaj1 Hmaj2 Hex.
epose proof (Series_correct _ Hex) as Hsup1.
exists (Series h1).
apply sup_is_lim; auto.
apply lim_is_sup in Hsup1; auto.
apply is_sup_seq_unique in Hsup1.
assert (Sup_seq (λ n : nat, sum_n h1 n) = Sup_seq (λ n : nat, sum_n h2 n)) as Haux; last first.
{ rewrite -Hsup1 Haux.
apply Sup_seq_correct. }
apply sup_seq_eq_antisym; auto.
Qed.
Lemma double_major_Series (h1 : nat → R) (h2 : nat → R) :
(∀ n, 0 <= h1 n) →
(∀ n, 0 <= h2 n) →
(∀ n, ∃ m, sum_n h1 n <= sum_n h2 m) →
(∀ n, ∃ m, sum_n h2 n <= sum_n h1 m) →
ex_series h1 →
Series h1 = Series h2.
Proof.
intros Hpos1 Hpos2 Hmaj1 Hmaj2 Hex.
rewrite lim_is_sup'; auto.
rewrite lim_is_sup'; auto; last first.
{ by apply (double_major_ex_series h1 h2). }
f_equal.
apply sup_seq_eq_antisym; auto.
Qed.
Lemma is_series_chain s1 s2 v:
is_series s2 (Series s1) → is_series s1 v → is_series s2 v.
Proof.
intros Hs2 Hs1.
rewrite -(is_series_unique s1 v); auto.
Qed.
Lemma series_ge_0 (h : nat → R):
(∀ a, 0 <= h a) → 0 <= Series h.
Proof.
intro Hpos.
rewrite /Series /Lim_seq.
assert (Rbar_le 0 (LimSup_seq (sum_n h))).
{ rewrite <- (LimSup_seq_const 0).
apply LimSup_le.
exists 0%nat; intros.
apply partial_sum_pos; auto. }
assert (Rbar_le 0 (LimInf_seq (sum_n h))).
{ rewrite <- (LimInf_seq_const 0).
apply LimInf_le.
exists 0%nat; intros.
apply partial_sum_pos; auto. }
rewrite /Rbar_div_pos.
case_match eqn:Heq.
- apply Rcomplements.Rdiv_le_0_compat; auto.
+ apply Rbar_0_le_to_Rle'.
rewrite <- (Rbar_plus_0_r 0).
rewrite <- Heq.
apply Rbar_plus_le_compat; auto.
+ apply Rlt_R0_R2.
- apply Rle_refl.
- rewrite <- Heq.
apply Rbar_0_le_to_Rle.
rewrite <- (Rbar_plus_0_r 0).
apply Rbar_plus_le_compat; auto.
Qed.
Lemma LimSup_incr_seq (h : nat → R) k :
(∀ n, h n <= h (S n)) →
is_finite (LimSup_seq h) →
h k <= LimSup_seq h.
Proof.
intros Hmon Hfin.
apply rbar_le_finite; auto.
rewrite -(LimSup_seq_const (h k)).
apply LimSup_le.
rewrite /eventually.
rewrite /LimSup_seq.
exists k. intros n H1. induction n.
- inversion H1. lra.
- inversion H1; simplify_eq; try lra.
etrans; [ | apply Hmon].
apply IHn; auto.
Qed.
Lemma Series_gt_0_ex_series (h : nat → R) :
(∀ n, 0 <= h n) →
0 < Series h → ex_series h.
Proof.
rewrite /Series.
intros Hlt Hl.
assert (ex_lim_seq (sum_n h)) as Haux.
{ apply ex_lim_seq_incr.
intro; rewrite sum_Sn.
rewrite <- Rplus_0_r at 1.
apply Rplus_le_compat_l; auto. }
apply ex_lim_LimSup_LimInf_seq in Haux.
rewrite /Lim_seq Haux in Hl.
destruct (LimInf_seq (sum_n h)) eqn:Heq.
- apply ex_pos_bounded_series; auto.
exists r; intro n.
pose proof Haux as Haux2.
apply eq_rbar_finite' in Haux.
rewrite -Haux.
apply LimSup_incr_seq.
+ intro. apply partial_sum_mon; auto.
+ rewrite Haux2.
rewrite /is_finite; auto.
- simpl in Hl; lra.
- simpl in Hl; lra.
Qed.
Lemma series_pos_partial_le (h : nat → R) n:
(∀ a, 0 <= h a) →
ex_series h →
sum_n h n <= Series h.
Proof.
intros Hpos Hex.
rewrite lim_is_sup'; auto.
destruct Hex as (l & Hl).
apply lim_is_sup in Hl; auto.
assert (Rbar_le (Finite (sum_n h n)) (Sup_seq (λ n0 : nat, sum_n h n0))) as Hle.
- apply (is_sup_seq_major (λ n0 : nat, sum_n h n0)).
apply Sup_seq_correct.
- rewrite (is_sup_seq_unique _ l) //.
rewrite (is_sup_seq_unique _ l) // in Hle.
Qed.
Lemma series_pos_elem_le (h : nat → R) n:
(∀ a, 0 <= h a) →
ex_series h →
h n <= Series h.
Proof.
intros Hpos Hex.
eapply Rle_trans; [apply partial_sum_elem | ]; auto.
apply series_pos_partial_le; auto.
Qed.
Lemma fubini_fin_inf (h : nat * nat → R) n:
(∀ a b, 0 <= h (a, b)) →
(∀ b, ex_series (λ a, h (a, b))) →
Series (λ a, sum_n (λ b, h (a, b)) n )
= sum_n (λ b, Series (λ a, h (a, b)) ) n.
Proof.
intros Hpos Hex.
induction n.
- rewrite sum_O.
apply Series_ext.
intro; rewrite sum_O; auto.
- rewrite sum_Sn.
rewrite <- IHn.
rewrite <- Series_plus; auto.
+ apply Series_ext; intro;
rewrite sum_Sn; auto.
+ apply ex_pos_bounded_series.
* intro.
apply partial_sum_pos; auto.
* exists (sum_n (λ b, Series (λ a : nat, h (a, b))) n).
intro m.
rewrite fubini_fin_sum.
apply sum_n_le.
intro p.
apply series_pos_partial_le; auto.
Qed.
Lemma fubini_pos_series_ex (h : nat * nat → R) :
(∀ a b, 0 <= h (a, b)) →
(∀ a, ex_series (λ b, h (a, b))) →
(ex_series (λ a, Series (λ b, h (a, b)))) →
(∀ b, ex_series (λ a, h (a, b))).
Proof.
intros Hpos Hex1 Hex2 b.
apply (ex_series_le (λ a : nat, h (a, b)) (λ a : nat, Series (λ b : nat, h (a, b)))); auto.
intro a.
rewrite /norm/=.
rewrite /abs/=/Rabs/=.
destruct (Rcase_abs (h (a, b))) as [H1 | H2].
- destruct (Hpos a b); lra.
- rewrite <- (Series_bump b (h(a, b))).
apply Series_le'; auto.
+ intro; case_bool_decide; simplify_eq; auto.
apply Rle_refl.
+ exists (h(a,b)).
apply is_series_singleton.
Qed.
Lemma fubini_pos_series_ex_double (h : nat * nat → R) :
(∀ a b, 0 <= h (a, b)) →
(∀ a, ex_series (λ b, h (a, b))) →
(ex_series (λ a, Series (λ b, h (a, b)))) →
(ex_series (λ b, Series (λ a, h (a, b)))).
Proof.
intros Hpos Hex1 Hex2.
pose proof (fubini_pos_series_ex h Hpos Hex1 Hex2) as Hex3.
pose proof Hex2 as Hex2'.
destruct Hex2 as (l & Hl).
apply ex_pos_bounded_series.
- intro n. apply series_ge_0; auto.
- exists l; intro n.
rewrite <- fubini_fin_inf; auto.
rewrite <- (is_series_unique (λ a : nat, Series (λ b : nat, h (a, b))) l); auto.
apply Series_le; auto.
intro m.
split.
+ apply partial_sum_pos; auto.
+ apply series_pos_partial_le; auto.
Qed.
Lemma series_bounded (h : nat → R) l :
(∀ a, 0 <= h a) →
(∀ n, sum_n h n <= l) →
ex_series h →
Series h <= l.
Proof.
intros Hpos Hle Hex.
rewrite lim_is_sup'; auto.
apply (upper_bound_ge_sup' (λ n : nat, sum_n h n) l); auto.
assert (Finite (real (Sup_seq (λ n : nat, sum_n h n))) =
Sup_seq (λ n : nat, sum_n h n)) as ->.
{ apply (Rbar_le_sandwich 0 l).
- apply (Rbar_le_trans _ (sum_n h 0%nat)).
+ rewrite sum_O; simpl; auto.
+ apply (sup_is_upper_bound (λ n : nat, sum_n h n)).
- apply upper_bound_ge_sup; auto.
}
apply (Sup_seq_correct (λ x : nat, sum_n h x)).
Qed.
Lemma series_bounded_rbar (h : nat → R) (l : Rbar) :
(∀ a, 0 <= h a) →
(∀ n, Rbar_le (sum_n h n) l) →
ex_series h →
Rbar_le (Series h) l.
Proof.
intros Hpos Hle Hex.
destruct l eqn:Hl; simpl; auto.
- by apply series_bounded.
- by apply (Hle 0%nat).
Qed.
Lemma fubini_pos_series (h : nat * nat → R) :
(∀ a b, 0 <= h (a, b)) →
(∀ a, ex_series (λ b, h (a, b))) →
(ex_series (λ a, Series (λ b, h (a, b)))) →
Series (λ b, Series (λ a, h (a, b))) =
Series (λ a, Series (λ b, h (a, b))).
Proof.
intros Hpos Hex1 Hex2.
pose proof (fubini_pos_series_ex _ Hpos Hex1 Hex2) as Hex3.
pose proof (fubini_pos_series_ex_double _ Hpos Hex1 Hex2) as Hex4.
apply Rle_antisym.
- apply series_bounded; auto.
+ intro; apply series_ge_0; auto.
+ intro.
rewrite <- fubini_fin_inf; auto.
apply Series_le; auto.
intro; split; auto.
* apply partial_sum_pos; auto.
* apply series_pos_partial_le; auto.
- apply series_bounded; auto.
+ intro; apply series_ge_0; auto.
+ intro.
rewrite <- (fubini_fin_inf (λ '(b, a), h (a, b))) ; auto.
apply Series_le; auto.
intro; split; auto.
* apply partial_sum_pos; auto.
* apply series_pos_partial_le; auto.
Qed.
Lemma real_le_limit (x y:R) :
(∀ ε, ε > 0 -> x - ε <= y) -> x<=y.
Proof.
intros H.
epose proof (completeness (λ z, exists z',z'>0/\ z'+z=x) _ _) as [m H'].
assert (m=x) as ->.
{ eapply is_lub_u; first done. split.
- intros x' [ε [H1 H2]]; subst. lra.
- intros b H''. pose proof (Rle_or_lt x b) as [|]; first lra.
exfalso. assert (x-(x-b)/2<=b); last lra.
apply H''. eexists ((x-b)/2). lra.
}
apply H'.
intros x0[?[??]]. assert (x0=(x-x1)) as -> by lra.
apply H. lra.
Unshelve.
- exists y. intros x0[?[??]]. assert (x0=x-x1) as -> by lra. naive_solver.
- eexists (x-1), 1. lra.
Qed.
From Coquelicot Require Import Series Lim_seq Rbar Rcomplements.
From stdpp Require Export countable sets.
From clutch.prelude Require Import base Coquelicot_ext stdpp_ext classical.
From discprob.prob Require Import double.
Set Default Proof Using "Type*".
Import Hierarchy.
Open Scope R.
Section rbar_extra.
Lemma Rbar_le_sandwich p q r :
Rbar_le (Finite p) r ->
Rbar_le r (Finite q) ->
Finite (real r) = r.
Proof.
intros Hp Hq.
destruct r eqn:Hr; auto.
- destruct Hq.
- destruct Hp.
Qed.
Lemma rbar_le_finite (p : R) (q : Rbar) :
is_finite q ->
Rbar_le p q ->
p <= real q.
Proof.
intros Hq Hle.
rewrite /is_finite/= in Hq.
destruct q; auto; simplify_eq.
Qed.
Lemma finite_rbar_le (p : R) (q : Rbar) :
is_finite q ->
Rbar_le q p ->
q <= real p.
Proof.
intros Hq Hle.
rewrite /is_finite/= in Hq.
destruct q; auto; simplify_eq.
Qed.
Lemma rbar_le_rle (p : R) (q : R) :
Rbar_le (Finite p) (Finite q) <-> Rle p q.
Proof.
auto.
Qed.
Lemma is_finite_bounded (p q : R) (r : Rbar) :
Rbar_le p r ->
Rbar_le r q ->
is_finite r.
Proof.
intros H1 H2.
rewrite /is_finite.
destruct r eqn:Hr; auto.
- destruct H2.
- destruct H1.
Qed.
Lemma rbar_finite_real_eq (p : Rbar) :
is_finite p ->
Finite (real p) = p.
Proof.
intro Hfin.
destruct p; auto.
Qed.
Lemma rbar_le_finite_real r :
Rbar_le (Finite 0) r ->
Rbar_le (Finite (real r)) r.
Proof.
intro Hpos.
destruct r eqn:Heq; simpl; auto.
apply Rle_refl.
Qed.
Lemma rbar_scal_r (p : Rbar) (r : R) :
is_finite p ->
(real p) * r = real (Rbar_mult p (Finite r)).
Proof.
intro Hfin.
destruct p ; simpl; auto.
all:case_match; simpl; try lra; inversion Hfin.
Qed.
End rbar_extra.
Lemma ex_series_eventually0 (a: nat → R):
(∃ N, ∀ n, n ≥ N → a n = 0) → ex_series a.
Proof.
intros (N & Hev0). apply: ex_series_Cauchy.
rewrite /Cauchy_series => eps. exists N => n m Hlen Hlem.
assert (Heq: sum_n_m a n m = 0).
{ rewrite /sum_n_m.
rewrite (Iter.iter_nat_ext_loc _ _ _ (λ x, 0)).
- rewrite /plus/zero//=/Iter.iter_nat Iter.iter_const; nra.
- intros k (?&?). apply Hev0. lia. }
rewrite /norm //= /abs //=. destruct eps =>//=. rewrite Heq Rabs_right; nra.
Qed.
Lemma mon_succ_to_mon (h : nat → R) :
(∀ p, h p <= h (S p)) →
(∀ m n, (m <= n)%nat → h m <= h n).
Proof.
intros Hmon m.
induction m; intro n; induction n.
- intros; apply Rle_refl.
- intro. apply (Rle_trans _ (h n)); auto with arith.
- intro Haux.
inversion Haux.
- intro Haux.
destruct (decide ((S m <= n)%nat)) as [Hle | Hgt].
+ apply (Rle_trans _ (h n)); auto with arith.
+ assert (S m = S n) as ->; [ | apply Rle_refl].
assert ((n < S m)%nat); auto with arith.
apply not_le; auto.
Qed.
Lemma is_series_ge0 (h : nat → R) r:
(∀ n, 0 <= h n) →
is_series h r →
0 <= r.
Proof.
intros Hge Hs.
erewrite <- (Series_0 (λ y, 0)); auto.
rewrite <- (is_series_unique _ _ Hs).
eapply (Series_le).
{ intro n; split; auto; lra. }
rewrite /ex_series.
exists r; auto.
Qed.
Lemma lim_is_sup (h: nat → R) r :
(∀ n, 0 <= h n) →
is_series h r →
is_sup_seq (sum_n h) (Finite r).
Proof.
intros Hge Hs.
rewrite /is_sup_seq.
pose proof (is_series_partial_pos h) as Hpart.
pose proof (is_series_ge0 _ _ Hge Hs) as Hr.
intro eps; split.
- intro n.
specialize (Hpart n r Hge Hs).
rewrite /Rbar_lt.
assert (eps > 0); try lra.
pose proof (cond_pos eps); lra.
- pose proof (Hs) as Hs'.
specialize (Hs (ball r eps)).
assert (∃ N : nat, ∀ n : nat, N ≤ n → ball r eps (sum_n h n)) as (N & HN).
{apply Hs. exists eps. auto. }
exists N; simpl.
specialize (HN N (Nat.le_refl N)).
specialize (Hpart N r Hge Hs').
rewrite /ball /= /AbsRing_ball in HN.
cut (r - (sum_n h N) < eps); try lra.
rewrite abs_minus /abs /= in HN.
assert (Rabs (minus r (sum_n h N)) = minus r (sum_n h N)) as Habs.
{ apply Rabs_right.
rewrite /minus /plus /= /opp /=.
lra. }
rewrite Habs in HN.
rewrite /minus /plus /= /opp /= in HN.
lra.
Qed.
Lemma sup_is_lim (h: nat → R) r :
(∀ n, 0 <= h n) →
is_sup_seq (sum_n h) (Finite r) →
is_series h r.
Proof.
intros Hge Hsup.
rewrite /is_sup_seq in Hsup.
intros P (eps & Heps).
rewrite /ball /= /AbsRing_ball in Heps.
destruct (Hsup eps) as (HsupFor & (N & HsupN)).
exists N; intros n Hn.
specialize (HsupFor n).
specialize (Heps (sum_n h n)).
assert (sum_n h N <= sum_n h n) as HNn.
{ by apply partial_sum_mon. }
apply Heps.
rewrite /Rbar_lt in HsupFor.
rewrite /Rbar_lt in HsupN.
assert (r - eps < sum_n h n); [try lra | ].
rewrite /abs /= /Rabs /minus /plus /= /opp /=.
destruct Rcase_abs; lra.
Qed.
Lemma lim_is_sup' (h: nat → R) :
(∀ n, 0 <= h n) →
ex_series h →
Series h = real (Sup_seq (sum_n h)).
Proof.
intros Hpos Hex.
apply Series_correct, lim_is_sup, is_sup_seq_unique in Hex; auto.
apply eq_rbar_finite; auto.
Qed.
Lemma lim_is_sup'' (h: nat → R) :
(∀ n, 0 <= h n) →
ex_series h →
is_series h (real (Sup_seq (sum_n h))).
Proof.
intros Hpos Hex.
rewrite <- lim_is_sup'; auto.
apply Series_correct; auto.
Qed.
Lemma sup_is_upper_bound (h : nat → Rbar) n :
Rbar_le (h n) (Sup_seq h).
Proof.
apply is_sup_seq_major.
apply Sup_seq_correct.
Qed.
Lemma sup_is_upper_bound' (h : nat → R) n r :
is_sup_seq h (Finite r) →
h n <= r.
Proof.
intro Hr.
assert (Rbar_le (Finite (real (h n))) (Finite r)); auto.
assert (real (Finite (h n)) = h n) as ->; auto.
apply (is_sup_seq_major (fun x : nat => Finite (h x)) (Finite r)); auto.
Qed.
Lemma upper_bound_ge_sup (h : nat → Rbar) r :
(∀ n, Rbar_le (h n) r) →
Rbar_le (Sup_seq h) r.
Proof.
intro H2.
pose proof (is_sup_seq_lub h (Sup_seq h) (Sup_seq_correct h)) as H3.
rewrite /Lub.Rbar_is_lub in H3.
apply H3.
rewrite /Lub.Rbar_is_upper_bound.
intros q (n & Hn).
rewrite Hn; auto.
Qed.
Lemma upper_bound_ge_sup' (h : nat → R) r l :
is_sup_seq h (Finite l) →
(∀ n, h n <= r) →
l <= r.
Proof.
intros Hsup H2.
assert (Rbar_le (Finite l) (Finite r)); auto.
rewrite <- (is_sup_seq_unique (λ x : nat, h x) l); auto.
apply (upper_bound_ge_sup (λ x : nat, h x) r); auto.
Qed.
Lemma sup_seq_eq_antisym (h1 h2 : nat → R) :
(∀ m, ∃ n, h1 m <= h2 n) →
(∀ m, ∃ n, h2 m <= h1 n) →
Sup_seq h1 = Sup_seq h2.
Proof.
intros H1 H2.
apply Rbar_le_antisym.
+ apply upper_bound_ge_sup; intro n.
destruct (H1 n) as (m & ?).
apply (Sup_seq_minor_le _ _ m); auto.
+ apply upper_bound_ge_sup; intro n.
destruct (H2 n) as (m & ?).
apply (Sup_seq_minor_le _ _ m); auto.
Qed.
Lemma sup_seq_swap (h : nat * nat → R) :
Sup_seq (λ n, Sup_seq (λ m, h (n , m))) =
Sup_seq (λ m, Sup_seq (λ n, h (n , m))).
Proof.
apply Rbar_le_antisym.
+ apply upper_bound_ge_sup; intro n.
apply upper_bound_ge_sup; intro m.
apply (Sup_seq_minor_le _ _ m).
apply (Sup_seq_minor_le _ _ n).
simpl; lra.
+ apply upper_bound_ge_sup; intro n.
apply upper_bound_ge_sup; intro m.
apply (Sup_seq_minor_le _ _ m).
apply (Sup_seq_minor_le _ _ n).
simpl; lra.
Qed.
Lemma Sup_seq_scal_r (a : R) (u : nat → Rbar):
0 <= a →
Sup_seq (λ n : nat, Rbar_mult (u n) a) = Rbar_mult (Sup_seq u) a.
Proof.
intro.
rewrite Rbar_mult_comm -Sup_seq_scal_l //.
apply Sup_seq_ext.
intro; apply Rbar_mult_comm.
Qed.
Lemma Sup_seq_scal_l' (a:R) (u : nat -> R) :
0<=a -> is_finite (Sup_seq u) -> real (Sup_seq (λ n, a* u n)) = a* (real (Sup_seq u)).
Proof.
intros H H'.
apply eq_rbar_finite'.
rewrite rmult_finite.
rewrite rbar_finite_real_eq; last done.
rewrite -Sup_seq_scal_l; last done.
apply Sup_seq_ext.
intros.
by rewrite rmult_finite.
Qed.
Lemma Sup_seq_scal_r' (a:R) (u : nat -> R) :
0<=a -> is_finite (Sup_seq u) -> real (Sup_seq (λ n, u n * a)) = (real (Sup_seq u)) * a.
Proof.
intros.
rewrite Rmult_comm.
rewrite -Sup_seq_scal_l'; try done.
f_equal.
apply Sup_seq_ext. intros. rewrite Rmult_comm. done.
Qed.
Lemma sum_n_plus f g n:
sum_n f n + sum_n g n = sum_n (λ x, f x + g x) n.
Proof.
induction n.
- by rewrite !sum_O.
- rewrite !sum_Sn.
replace (plus _ _ + plus _ _) with ((sum_n f n + sum_n g n)+(f (S n) + g (S n))); last first.
{ assert (forall x y, plus x y = x + y).
- intros. done.
- rewrite !H. lra.
}
rewrite IHn. done.
Qed.
Lemma sum_n_inj `{Inj nat nat eq eq h} (f : nat -> R) n m :
(forall n, 0 <= f n) ->
(forall x : nat, x <= n -> h x <= m)%nat ->
(sum_n (λ n0 : nat, f (h n0)) n) <= (sum_n (λ n0 : nat, f n0) m).
Proof.
intros Hf Hh.
pose proof make_decision.
trans (sum_n (λ n0 : nat, if bool_decide (∃ x, n0 = h x /\ x<=n)%nat then f n0 else 0) m); last first.
{ apply sum_n_le. intros. case_bool_decide; try lra. naive_solver. }
revert m Hh.
induction n.
- intros. rewrite sum_O. etrans; last eapply partial_sum_mon.
+ etrans; last apply partial_sum_elem.
* case_bool_decide as H0; first done.
exfalso. apply H0. naive_solver.
* intros. case_bool_decide; naive_solver.
+ intros. case_bool_decide; naive_solver.
+ naive_solver.
- intros. rewrite sum_Sn.
replace (sum_n _ m) with (sum_n (λ n0 : nat, if bool_decide (∃ x : nat, n0 = h x ∧ x ≤ n) then f n0 else 0) m + sum_n (λ n0 : nat, if bool_decide (n0 = h (S n)) then f n0 else 0) m).
+ apply Rplus_le_compat; first naive_solver.
etrans; last eapply partial_sum_mon; first (etrans; last apply partial_sum_elem).
* by case_bool_decide.
* intros; case_bool_decide; naive_solver.
* intros; case_bool_decide; naive_solver.
* naive_solver.
+ clear IHn.
remember m as k. rewrite Heqk in Hh. clear Heqk.
rewrite sum_n_plus. f_equal. apply functional_extensionality_dep.
intros x.
repeat case_bool_decide; try done; try lra.
* subst. destruct H0 as [?[??]]; destruct H2 as [?[??]].
rewrite H0 in H2. apply H in H0. subst. lia.
* exfalso. naive_solver.
* exfalso. naive_solver.
* exfalso. naive_solver.
* exfalso. apply H0. destruct H2 as [?[??]]. subst.
rewrite Nat.le_succ_r in H3. naive_solver.
Qed.
Lemma sum_n_pseudo_inj (h : nat -> nat)(f : nat -> R) n m :
(forall n, 0 <= f n) ->
(forall x y, h x = h y -> f (h x) ≠ 0 -> x = y) ->
(forall x : nat, x <= n -> h x <= m)%nat ->
(sum_n (λ n0 : nat, f (h n0)) n) <= (sum_n (λ n0 : nat, f n0) m).
Proof.
intros Hf H Hh.
pose proof make_decision.
trans (sum_n (λ n0 : nat, if bool_decide (∃ x, n0 = h x /\ x<=n)%nat then f n0 else 0) m); last first.
{ apply sum_n_le. intros. case_bool_decide; try lra. naive_solver. }
revert m Hh.
induction n.
- intros. rewrite sum_O. etrans; last eapply partial_sum_mon.
+ etrans; last apply partial_sum_elem.
* case_bool_decide as H0; first done.
exfalso. apply H0. naive_solver.
* intros. case_bool_decide; naive_solver.
+ intros. case_bool_decide; naive_solver.
+ naive_solver.
- intros. rewrite sum_Sn.
replace (sum_n _ m) with (sum_n (λ n0 : nat, if bool_decide (∃ x : nat, n0 = h x ∧ x ≤ n) then f n0 else 0) m + sum_n (λ n0 : nat, if bool_decide (n0 = h (S n)) then f n0 else 0) m).
+ apply Rplus_le_compat; first naive_solver.
etrans; last eapply partial_sum_mon; first (etrans; last apply partial_sum_elem).
* by case_bool_decide.
* intros; case_bool_decide; naive_solver.
* intros; case_bool_decide; naive_solver.
* naive_solver.
+ clear IHn.
remember m as k. rewrite Heqk in Hh. clear Heqk.
rewrite sum_n_plus. f_equal. apply functional_extensionality_dep.
intros x.
repeat case_bool_decide; try done; try lra.
* subst. destruct H0 as [?[??]]; destruct H2 as [?[??]].
rewrite H0 in H2.
destruct (decide (f (h (S n)) = 0)); first by lra.
apply H in H0; auto. subst. lia.
* exfalso. naive_solver.
* exfalso. naive_solver.
* exfalso. naive_solver.
* exfalso. apply H0. destruct H2 as [?[??]]. subst.
rewrite Nat.le_succ_r in H3. naive_solver.
Qed.
Lemma sum_n_surj_le_some_index h f n:
Surj eq h ->
(∀ n : nat, 0 <= f n) ->
∃ k : nat, sum_n f n <= sum_n (λ n0 : nat, f (h n0)) k.
Proof.
intros.
cut (∃ k : nat, ∃ l, NoDup l /\
(forall x, x∈l -> h x <= n)%nat /\
sum_n f n <= sum_n (λ n0 : nat, if bool_decide (n0 ∈ l /\ h n0 <= n)%nat then f (h n0) else 0) k).
{ elim. intros. destruct H1 as [?[?[??]]]. eexists _. etrans; first exact. apply sum_n_le.
intros. case_bool_decide; naive_solver.
}
induction n.
- pose proof (H 0%nat) as [??].
exists x, (x::[]).
split; first constructor.
+ apply not_elem_of_nil.
+ constructor.
+ split.
* intros. assert (x0=x) as -> by set_solver. rewrite H1. lia.
* etrans; last apply partial_sum_elem.
-- rewrite sum_O. case_bool_decide; try done; first by rewrite H1.
exfalso. apply H2. rewrite H1. split; set_solver.
-- intros. case_bool_decide; naive_solver.
- destruct IHn as [x[l[Hl [Hcond IHn]]]].
pose proof (H (S n)) as [x0?].
pose proof (Nat.le_gt_cases x0 x) as [|].
+ exists x, (x0::l). repeat split.
* constructor; last done.
intro. apply Hcond in H3.
rewrite H1 in H3. lia.
* set_unfold; try naive_solver.
intros ?[|]; try naive_solver.
subst. lia.
* rewrite sum_Sn. etrans; first apply Rplus_le_compat.
-- exact.
-- instantiate (1:= sum_n (λ n', if bool_decide (n'=x0) then f (h n') else 0) (x)).
etrans; last apply partial_sum_mon; last exact.
++ etrans; last apply partial_sum_elem.
** case_bool_decide; subst.
--- rewrite H1. done.
--- done.
** intros. case_bool_decide; naive_solver.
++ intros; case_bool_decide; naive_solver.
-- rewrite sum_n_plus. apply sum_n_le.
intros; repeat case_bool_decide; try lra.
++ subst. rewrite H1 in H3. lia.
++ subst. exfalso. set_solver.
++ exfalso. set_solver.
++ subst. exfalso. apply H5. rewrite H1. set_unfold. naive_solver.
++ etrans; last apply H0. lra.
+ exists x0, (x0::l).
repeat split.
* constructor; last done.
intro. apply Hcond in H3.
rewrite H1 in H3. lia.
* intros. rewrite elem_of_cons in H3. destruct H3; last naive_solver.
subst. lia.
* assert (∃ x', x0 = S x') as [?->].
{ destruct x0; last naive_solver. lia. }
rewrite !sum_Sn. apply Rplus_le_compat.
-- etrans; first exact.
etrans; last eapply sum_n_le.
++ apply partial_sum_mon; last lia.
intros. case_bool_decide; naive_solver.
++ intros. repeat case_bool_decide; try done.
exfalso. set_unfold. naive_solver.
-- case_bool_decide; first by rewrite H1.
set_unfold; exfalso; apply H3. split; first naive_solver.
lia.
Qed.
Fixpoint max_seq (f : nat -> nat) n :=
match n with
| 0 => f 0%nat
| S m => max (f (S m)) (max_seq f m)
end.
Lemma le_max_seq (f : nat -> nat) n m :
m ≤ n ->
f m ≤ max_seq f n.
Proof.
intros Hleq.
induction Hleq.
- destruct m; simpl; [lia|].
apply Nat.le_max_l.
- simpl.
etrans; eauto.
apply Nat.le_max_r.
Qed.
Lemma sum_max_seq (f : nat -> R) h n `{Inj nat nat eq eq h}:
(forall n, 0 <= f n) ->
(sum_n (λ n0 : nat, f (h n0)) n) <= (sum_n (λ n0 : nat, f n0) (max_seq h n)).
Proof.
intros.
apply sum_n_inj; first done.
clear.
induction n; simpl; intros.
- assert (x=0%nat); try lia. by subst.
- rewrite Nat.le_succ_r in H. destruct H.
+ etrans; first by apply IHn.
apply Nat.le_max_r.
+ subst. apply Nat.le_max_l.
Qed.
Lemma sum_max_seq_pseudo_inj (f : nat -> R) (h : nat -> nat) n:
(forall n, 0 <= f n) ->
(forall x y, h x = h y -> f (h x) ≠ 0 -> x = y) ->
(sum_n (λ n0 : nat, f (h n0)) n) <= (sum_n (λ n0 : nat, f n0) (max_seq h n)).
Proof.
intros Hpos H.
apply sum_n_pseudo_inj.
1,2: done.
clear.
induction n; simpl; intros.
- assert (x=0%nat); try lia. by subst.
- rewrite Nat.le_succ_r in H. destruct H.
+ etrans; first by apply IHn.
apply Nat.le_max_r.
+ subst. apply Nat.le_max_l.
Qed.
Lemma is_series_bijection (f : nat -> R) h v `{Bij nat nat h} :
(forall n, 0 <= f n) ->
is_series f v ->
is_series (λ n, f (h n)) v.
Proof.
intros Hpos Hf.
unfold is_series.
rewrite /is_series.
apply sup_is_lim; auto.
apply lim_is_sup in Hf; auto.
intro eps; split.
- assert (forall n, (sum_n (λ n0 : nat, f (h n0)) n) <= (sum_n (λ n0 : nat, f n0) (max_seq h n))) as Haux.
{
intro; eapply sum_max_seq; eauto.
apply bij_inj.
}
intro n.
eapply Rbar_le_lt_trans; [apply rbar_le_rle, Haux | apply Hf ].
- apply Classical_Pred_Type.not_all_not_ex.
intro H1.
apply (upper_bound_ge_sup' _ (v-eps)) in Hf.
{ assert (0<eps); try lra. apply cond_pos. }
intros. assert (∀ n : nat, (sum_n (λ n0 : nat, f (h n0)) n) <= v-eps).
{ intros. apply Rnot_lt_le. apply H1. }
cut (∃ k, sum_n f n <= sum_n (λ n0 : nat, f (h n0)) k).
{ elim. intros. etrans; first exact. done. }
apply sum_n_surj_le_some_index; destruct H; naive_solver.
Qed.
Lemma fubini_fin_sum (h : nat * nat → R) n m:
sum_n (λ a, sum_n (λ b, h (a, b)) n ) m
= sum_n (λ b, sum_n (λ a, h (a, b)) m ) n.
Proof.
intros.
apply sum_n_switch.
Qed.
Lemma Series_real_sup (h: nat → R) :
(∀ n, 0 <= h n) →
Series h = (real (Sup_seq (sum_n h))).
Proof.
intros Hpos.
rewrite /Series.
f_equal.
apply is_lim_seq_unique.
apply is_LimSup_LimInf_lim_seq.
- apply is_LimSup_infSup_seq.
apply Rbar_is_glb_inf_seq.
rewrite /Lub.Rbar_is_glb/=;split.
+ rewrite /Lub.Rbar_is_lower_bound.
intros x (n&->).
apply Sup_seq_le.
intro; simpl.
apply partial_sum_mon; auto; lia.
+ rewrite /Lub.Rbar_is_lower_bound.
intros b Hb.
apply Hb.
exists 0%nat. apply Sup_seq_ext; intro.
by rewrite Nat.add_0_r.
- apply is_LimInf_supInf_seq.
eapply (is_sup_seq_ext (λ n : nat, sum_n h (n))).
+ intro n; symmetry.
apply is_inf_seq_unique.
rewrite /is_inf_seq.
intro eps; split.
* intro n0; simpl.
eapply (Rlt_le_trans _ (sum_n h n));
[ | apply partial_sum_mon; auto; lia].
apply Rlt_minus_l.
rewrite <- Rplus_0_r at 1.
apply Rplus_lt_compat_l.
apply cond_pos.
* exists 0%nat; simpl.
rewrite <- Rplus_0_r at 1.
apply Rplus_lt_compat_l.
apply cond_pos.
+ apply Sup_seq_correct.
Qed.
Lemma ex_pos_bounded_series (h : nat → R) :
(∀ n, 0 <= h n) →
(∃ l, ∀ n, sum_n h n <= l) →
ex_series h.
Proof.
intros Hpos (l & Hl).
exists (real (Sup_seq (λ n, sum_n h n))).
apply sup_is_lim; auto.
rewrite (Rbar_le_sandwich 0 l).
- apply Sup_seq_correct.
- apply (Rbar_le_trans _ (sum_n h 0%nat)).
+ rewrite sum_O.
assert (0 <= (h 0%nat)); auto.
+ apply (sup_is_upper_bound (λ n : nat, sum_n h n) 0%nat).
- destruct (Sup_seq (λ n : nat, sum_n h n)) eqn:Hsup; simpl; auto.
+ assert (Rbar_le (Finite r) (Finite l)); auto.
rewrite <- Hsup.
apply upper_bound_ge_sup.
intro n; auto.
specialize (Hl n); auto.
+ assert (Rbar_le (p_infty) (Finite l)); auto.
rewrite <- Hsup.
apply upper_bound_ge_sup.
intro n; auto.
specialize (Hl n); auto.
Qed.
Lemma ex_series_inj (f : nat -> R) h `{Inj nat nat eq eq h} :
(forall n, 0 <= f n) ->
ex_series f ->
ex_series (λ n, f (h n)).
Proof.
intros Hpos [l Hl].
apply ex_pos_bounded_series; auto.
exists l.
apply lim_is_sup in Hl; auto.
assert (forall n, (sum_n (λ n0 : nat, f (h n0)) n) <= (sum_n (λ n0 : nat, f n0) (max_seq h n))) as Haux.
{
intro; eapply sum_max_seq; eauto.
}
intro n.
etrans; eauto.
apply (is_sup_seq_major _ _ (max_seq h n)) in Hl.
auto.
Qed.
Lemma ex_series_pseudo_inj (f : nat -> R) (h: nat -> nat) :
(forall n, 0 <= f n) ->
(forall x y, h x = h y -> f (h x) ≠ 0 -> x = y) ->
ex_series f ->
ex_series (λ n, f (h n)).
Proof.
intros Hpos H [l Hl].
apply ex_pos_bounded_series; auto.
exists l.
apply lim_is_sup in Hl; auto.
assert (forall n, (sum_n (λ n0 : nat, f (h n0)) n) <= (sum_n (λ n0 : nat, f n0) (max_seq h n))) as Haux.
{
intro; eapply sum_max_seq_pseudo_inj; eauto.
}
intro n.
etrans; eauto.
apply (is_sup_seq_major _ _ (max_seq h n)) in Hl.
auto.
Qed.
Lemma double_sup_diag (h : nat * nat → R) :
(∀ n m n', (n <= n')%nat → h (n, m) <= h (n' , m)) →
(∀ n m m', (m <= m')%nat → h (n, m) <= h (n , m')) →
Sup_seq (λ n, Sup_seq (λ m, h (n, m))) =
Sup_seq (λ n, h (n, n)).
Proof.
intros Hmon1 Hmon2.
apply Rbar_le_antisym.
- apply upper_bound_ge_sup.
intro n.
apply upper_bound_ge_sup.
intro m.
eapply Rbar_le_trans; last first.
+ apply (sup_is_upper_bound _ (n `max` m)).
+ apply (Rbar_le_trans _ (h ((n `max` m), m))).
* apply Hmon1, Nat.le_max_l.
* apply Hmon2, Nat.le_max_r.
- apply upper_bound_ge_sup.
intro n.
eapply Rbar_le_trans; last first.
+ apply (sup_is_upper_bound _ n).
+ eapply Rbar_le_trans; last first.
* apply (sup_is_upper_bound _ n).
* apply Rbar_le_refl.
Qed.
Lemma double_major_ex_series (h1 : nat → R) (h2 : nat → R) :
(∀ n, 0 <= h1 n) →
(∀ n, 0 <= h2 n) →
(∀ n, ∃ m, sum_n h1 n <= sum_n h2 m) →
(∀ n, ∃ m, sum_n h2 n <= sum_n h1 m) →
ex_series h1 →
ex_series h2.
Proof.
intros Hpos1 Hpos2 Hmaj1 Hmaj2 Hex.
epose proof (Series_correct _ Hex) as Hsup1.
exists (Series h1).
apply sup_is_lim; auto.
apply lim_is_sup in Hsup1; auto.
apply is_sup_seq_unique in Hsup1.
assert (Sup_seq (λ n : nat, sum_n h1 n) = Sup_seq (λ n : nat, sum_n h2 n)) as Haux; last first.
{ rewrite -Hsup1 Haux.
apply Sup_seq_correct. }
apply sup_seq_eq_antisym; auto.
Qed.
Lemma double_major_Series (h1 : nat → R) (h2 : nat → R) :
(∀ n, 0 <= h1 n) →
(∀ n, 0 <= h2 n) →
(∀ n, ∃ m, sum_n h1 n <= sum_n h2 m) →
(∀ n, ∃ m, sum_n h2 n <= sum_n h1 m) →
ex_series h1 →
Series h1 = Series h2.
Proof.
intros Hpos1 Hpos2 Hmaj1 Hmaj2 Hex.
rewrite lim_is_sup'; auto.
rewrite lim_is_sup'; auto; last first.
{ by apply (double_major_ex_series h1 h2). }
f_equal.
apply sup_seq_eq_antisym; auto.
Qed.
Lemma is_series_chain s1 s2 v:
is_series s2 (Series s1) → is_series s1 v → is_series s2 v.
Proof.
intros Hs2 Hs1.
rewrite -(is_series_unique s1 v); auto.
Qed.
Lemma series_ge_0 (h : nat → R):
(∀ a, 0 <= h a) → 0 <= Series h.
Proof.
intro Hpos.
rewrite /Series /Lim_seq.
assert (Rbar_le 0 (LimSup_seq (sum_n h))).
{ rewrite <- (LimSup_seq_const 0).
apply LimSup_le.
exists 0%nat; intros.
apply partial_sum_pos; auto. }
assert (Rbar_le 0 (LimInf_seq (sum_n h))).
{ rewrite <- (LimInf_seq_const 0).
apply LimInf_le.
exists 0%nat; intros.
apply partial_sum_pos; auto. }
rewrite /Rbar_div_pos.
case_match eqn:Heq.
- apply Rcomplements.Rdiv_le_0_compat; auto.
+ apply Rbar_0_le_to_Rle'.
rewrite <- (Rbar_plus_0_r 0).
rewrite <- Heq.
apply Rbar_plus_le_compat; auto.
+ apply Rlt_R0_R2.
- apply Rle_refl.
- rewrite <- Heq.
apply Rbar_0_le_to_Rle.
rewrite <- (Rbar_plus_0_r 0).
apply Rbar_plus_le_compat; auto.
Qed.
Lemma LimSup_incr_seq (h : nat → R) k :
(∀ n, h n <= h (S n)) →
is_finite (LimSup_seq h) →
h k <= LimSup_seq h.
Proof.
intros Hmon Hfin.
apply rbar_le_finite; auto.
rewrite -(LimSup_seq_const (h k)).
apply LimSup_le.
rewrite /eventually.
rewrite /LimSup_seq.
exists k. intros n H1. induction n.
- inversion H1. lra.
- inversion H1; simplify_eq; try lra.
etrans; [ | apply Hmon].
apply IHn; auto.
Qed.
Lemma Series_gt_0_ex_series (h : nat → R) :
(∀ n, 0 <= h n) →
0 < Series h → ex_series h.
Proof.
rewrite /Series.
intros Hlt Hl.
assert (ex_lim_seq (sum_n h)) as Haux.
{ apply ex_lim_seq_incr.
intro; rewrite sum_Sn.
rewrite <- Rplus_0_r at 1.
apply Rplus_le_compat_l; auto. }
apply ex_lim_LimSup_LimInf_seq in Haux.
rewrite /Lim_seq Haux in Hl.
destruct (LimInf_seq (sum_n h)) eqn:Heq.
- apply ex_pos_bounded_series; auto.
exists r; intro n.
pose proof Haux as Haux2.
apply eq_rbar_finite' in Haux.
rewrite -Haux.
apply LimSup_incr_seq.
+ intro. apply partial_sum_mon; auto.
+ rewrite Haux2.
rewrite /is_finite; auto.
- simpl in Hl; lra.
- simpl in Hl; lra.
Qed.
Lemma series_pos_partial_le (h : nat → R) n:
(∀ a, 0 <= h a) →
ex_series h →
sum_n h n <= Series h.
Proof.
intros Hpos Hex.
rewrite lim_is_sup'; auto.
destruct Hex as (l & Hl).
apply lim_is_sup in Hl; auto.
assert (Rbar_le (Finite (sum_n h n)) (Sup_seq (λ n0 : nat, sum_n h n0))) as Hle.
- apply (is_sup_seq_major (λ n0 : nat, sum_n h n0)).
apply Sup_seq_correct.
- rewrite (is_sup_seq_unique _ l) //.
rewrite (is_sup_seq_unique _ l) // in Hle.
Qed.
Lemma series_pos_elem_le (h : nat → R) n:
(∀ a, 0 <= h a) →
ex_series h →
h n <= Series h.
Proof.
intros Hpos Hex.
eapply Rle_trans; [apply partial_sum_elem | ]; auto.
apply series_pos_partial_le; auto.
Qed.
Lemma fubini_fin_inf (h : nat * nat → R) n:
(∀ a b, 0 <= h (a, b)) →
(∀ b, ex_series (λ a, h (a, b))) →
Series (λ a, sum_n (λ b, h (a, b)) n )
= sum_n (λ b, Series (λ a, h (a, b)) ) n.
Proof.
intros Hpos Hex.
induction n.
- rewrite sum_O.
apply Series_ext.
intro; rewrite sum_O; auto.
- rewrite sum_Sn.
rewrite <- IHn.
rewrite <- Series_plus; auto.
+ apply Series_ext; intro;
rewrite sum_Sn; auto.
+ apply ex_pos_bounded_series.
* intro.
apply partial_sum_pos; auto.
* exists (sum_n (λ b, Series (λ a : nat, h (a, b))) n).
intro m.
rewrite fubini_fin_sum.
apply sum_n_le.
intro p.
apply series_pos_partial_le; auto.
Qed.
Lemma fubini_pos_series_ex (h : nat * nat → R) :
(∀ a b, 0 <= h (a, b)) →
(∀ a, ex_series (λ b, h (a, b))) →
(ex_series (λ a, Series (λ b, h (a, b)))) →
(∀ b, ex_series (λ a, h (a, b))).
Proof.
intros Hpos Hex1 Hex2 b.
apply (ex_series_le (λ a : nat, h (a, b)) (λ a : nat, Series (λ b : nat, h (a, b)))); auto.
intro a.
rewrite /norm/=.
rewrite /abs/=/Rabs/=.
destruct (Rcase_abs (h (a, b))) as [H1 | H2].
- destruct (Hpos a b); lra.
- rewrite <- (Series_bump b (h(a, b))).
apply Series_le'; auto.
+ intro; case_bool_decide; simplify_eq; auto.
apply Rle_refl.
+ exists (h(a,b)).
apply is_series_singleton.
Qed.
Lemma fubini_pos_series_ex_double (h : nat * nat → R) :
(∀ a b, 0 <= h (a, b)) →
(∀ a, ex_series (λ b, h (a, b))) →
(ex_series (λ a, Series (λ b, h (a, b)))) →
(ex_series (λ b, Series (λ a, h (a, b)))).
Proof.
intros Hpos Hex1 Hex2.
pose proof (fubini_pos_series_ex h Hpos Hex1 Hex2) as Hex3.
pose proof Hex2 as Hex2'.
destruct Hex2 as (l & Hl).
apply ex_pos_bounded_series.
- intro n. apply series_ge_0; auto.
- exists l; intro n.
rewrite <- fubini_fin_inf; auto.
rewrite <- (is_series_unique (λ a : nat, Series (λ b : nat, h (a, b))) l); auto.
apply Series_le; auto.
intro m.
split.
+ apply partial_sum_pos; auto.
+ apply series_pos_partial_le; auto.
Qed.
Lemma series_bounded (h : nat → R) l :
(∀ a, 0 <= h a) →
(∀ n, sum_n h n <= l) →
ex_series h →
Series h <= l.
Proof.
intros Hpos Hle Hex.
rewrite lim_is_sup'; auto.
apply (upper_bound_ge_sup' (λ n : nat, sum_n h n) l); auto.
assert (Finite (real (Sup_seq (λ n : nat, sum_n h n))) =
Sup_seq (λ n : nat, sum_n h n)) as ->.
{ apply (Rbar_le_sandwich 0 l).
- apply (Rbar_le_trans _ (sum_n h 0%nat)).
+ rewrite sum_O; simpl; auto.
+ apply (sup_is_upper_bound (λ n : nat, sum_n h n)).
- apply upper_bound_ge_sup; auto.
}
apply (Sup_seq_correct (λ x : nat, sum_n h x)).
Qed.
Lemma series_bounded_rbar (h : nat → R) (l : Rbar) :
(∀ a, 0 <= h a) →
(∀ n, Rbar_le (sum_n h n) l) →
ex_series h →
Rbar_le (Series h) l.
Proof.
intros Hpos Hle Hex.
destruct l eqn:Hl; simpl; auto.
- by apply series_bounded.
- by apply (Hle 0%nat).
Qed.
Lemma fubini_pos_series (h : nat * nat → R) :
(∀ a b, 0 <= h (a, b)) →
(∀ a, ex_series (λ b, h (a, b))) →
(ex_series (λ a, Series (λ b, h (a, b)))) →
Series (λ b, Series (λ a, h (a, b))) =
Series (λ a, Series (λ b, h (a, b))).
Proof.
intros Hpos Hex1 Hex2.
pose proof (fubini_pos_series_ex _ Hpos Hex1 Hex2) as Hex3.
pose proof (fubini_pos_series_ex_double _ Hpos Hex1 Hex2) as Hex4.
apply Rle_antisym.
- apply series_bounded; auto.
+ intro; apply series_ge_0; auto.
+ intro.
rewrite <- fubini_fin_inf; auto.
apply Series_le; auto.
intro; split; auto.
* apply partial_sum_pos; auto.
* apply series_pos_partial_le; auto.
- apply series_bounded; auto.
+ intro; apply series_ge_0; auto.
+ intro.
rewrite <- (fubini_fin_inf (λ '(b, a), h (a, b))) ; auto.
apply Series_le; auto.
intro; split; auto.
* apply partial_sum_pos; auto.
* apply series_pos_partial_le; auto.
Qed.
Lemma real_le_limit (x y:R) :
(∀ ε, ε > 0 -> x - ε <= y) -> x<=y.
Proof.
intros H.
epose proof (completeness (λ z, exists z',z'>0/\ z'+z=x) _ _) as [m H'].
assert (m=x) as ->.
{ eapply is_lub_u; first done. split.
- intros x' [ε [H1 H2]]; subst. lra.
- intros b H''. pose proof (Rle_or_lt x b) as [|]; first lra.
exfalso. assert (x-(x-b)/2<=b); last lra.
apply H''. eexists ((x-b)/2). lra.
}
apply H'.
intros x0[?[??]]. assert (x0=(x-x1)) as -> by lra.
apply H. lra.
Unshelve.
- exists y. intros x0[?[??]]. assert (x0=x-x1) as -> by lra. naive_solver.
- eexists (x-1), 1. lra.
Qed.
Monotone convergence theorem
Lemma mon_sup_succ (h : nat → R) :
(∀ n, h n <= h (S n)) →
Sup_seq h = Sup_seq (λ n, h (S n)).
Proof.
intro Hmon.
apply Rbar_le_antisym.
- apply upper_bound_ge_sup.
intro n.
apply (Sup_seq_minor_le _ _ n), Hmon.
- apply upper_bound_ge_sup.
intro n.
apply (Sup_seq_minor_le _ _ (S (S n))), Hmon.
Qed.
Lemma sup_seq_const (r : R) :
real (Sup_seq (λ n, r)) = r.
Proof.
assert (is_finite (Sup_seq (λ n, r))) as Haux.
{ apply (Rbar_le_sandwich r r); auto.
- apply (Sup_seq_minor_le _ _ 0%nat); apply Rbar_le_refl.
- apply upper_bound_ge_sup; intro; apply Rbar_le_refl. }
apply Rle_antisym.
- apply finite_rbar_le; auto.
apply (upper_bound_ge_sup); intro; apply Rbar_le_refl.
- apply rbar_le_finite; auto.
apply (Sup_seq_minor_le _ _ 0%nat); apply Rbar_le_refl.
Qed.
Lemma Sup_seq_bounded_plus_l (f : nat → R) (b r : R) :
(∀ n, 0 <= f n <= b) →
Sup_seq (λ a, r + (f a)) = r + real (Sup_seq f).
Proof.
intro Hf.
apply Rbar_le_antisym.
- apply upper_bound_ge_sup.
intro n.
simpl.
apply Rplus_le_compat; [apply Rle_refl | ].
+ apply sup_is_upper_bound'.
rewrite -> (Rbar_le_sandwich 0 b); auto.
* apply Sup_seq_correct.
* apply (Sup_seq_minor_le _ _ 0%nat), Hf.
* apply (upper_bound_ge_sup _ b), Hf.
- rewrite /Sup_seq.
destruct ex_sup_seq as (p & Hp).
destruct ex_sup_seq as (q & Hq).
assert (is_finite p) as Hfinp.
{ apply (Rbar_le_sandwich 0 b).
+ eapply (Rbar_le_trans _ (Finite (f 0%nat))).
* apply (proj1 (Hf 0%nat)).
* rewrite <- (is_sup_seq_unique f p); auto.
apply (Sup_seq_minor_le _ _ 0%nat), Rle_refl.
+ rewrite <- (is_sup_seq_unique f p); auto.
apply (upper_bound_ge_sup _ b), Hf. }
assert (is_finite q) as Hfinq.
{ apply (Rbar_le_sandwich r (r + b)).
+ eapply (Rbar_le_trans _ (Finite (r + f 0%nat))).
* assert (r = r + 0) as Haux; [lra | ].
rewrite {1}Haux.
apply (Rbar_plus_le_compat r r 0 (f 0%nat)); [apply Rbar_le_refl | ].
apply (proj1 (Hf 0%nat)).
* rewrite <- (is_sup_seq_unique (λ a : nat, r + f a) q); auto.
apply (Sup_seq_minor_le _ _ 0%nat), Rle_refl.
+ rewrite <- (is_sup_seq_unique (λ a : nat, r + f a) q); auto.
apply (upper_bound_ge_sup _ (r + b)).
intro n; apply (Rbar_plus_le_compat r r (f n) b); [apply Rbar_le_refl | ].
apply Hf. }
simpl proj1_sig.
apply is_sup_seq_lub in Hp.
apply is_sup_seq_lub in Hq.
destruct Hp as (Hp1 & Hp2).
destruct Hq as (Hq1 & Hq2).
apply is_finite_correct in Hfinp.
destruct Hfinp as (p' & ->).
apply is_finite_correct in Hfinq.
destruct Hfinq as (q' & ->).
simpl.
assert (p' <= q' + (opp r)) as H; last first.
{
apply (Rplus_le_compat r r) in H; [ | apply Rle_refl].
apply (Rle_trans (r + p') (r + (q' + opp r)) q'); auto.
rewrite (Rplus_comm q' (opp r)).
rewrite <- Rplus_assoc.
assert (r + opp r = 0) as ->.
+ apply (plus_opp_r r).
+ rewrite Rplus_0_l.
apply Rle_refl.
}
assert (Rbar_le p' (q' + opp r)); auto.
apply Hp2.
intros _ (n & ->).
apply (Rbar_le_trans _ (r + f n + opp r)).
{ simpl.
rewrite (Rplus_comm r (f n)).
rewrite (Rplus_assoc).
assert (r + opp r = 0) as ->.
+ apply (plus_opp_r r).
+ rewrite Rplus_0_r.
apply Rle_refl.
}
simpl.
apply Rplus_le_compat; [ | apply Rle_refl ].
assert (Rbar_le (r + f n) q'); auto.
apply Hq1.
exists n; auto.
Qed.
Lemma Sup_seq_bounded_plus_r (f : nat -> R) (b r : R) :
(∀ n, 0 <= f n <= b) →
Sup_seq (λ a, (f a) + r) = real (Sup_seq f) + r.
Proof.
intro Hf.
rewrite Rplus_comm.
erewrite Sup_seq_ext; last first.
- intro; rewrite Rplus_comm; done.
- eapply Sup_seq_bounded_plus_l; eauto.
Qed.
Lemma Sup_seq_bounded_plus_sup (f g : nat → R) (b r : R) :
(∀ n, 0 <= f n <= b) →
(∀ n, 0 <= g n <= b) →
(∀ n, f n <= f (S n)) →
(∀ n, g n <= g (S n)) →
Sup_seq (λ a, (f a) + (g a)) = real (Sup_seq f) + (Sup_seq g).
Proof.
intros Hfb Hgb Hfmon Hgmon.
apply Rbar_le_antisym.
- apply upper_bound_ge_sup.
intro n.
simpl.
apply Rplus_le_compat.
+ apply sup_is_upper_bound'.
rewrite -> (Rbar_le_sandwich 0 b); auto.
* apply Sup_seq_correct.
* apply (Sup_seq_minor_le _ _ 0%nat), Hfb.
* apply (upper_bound_ge_sup _ b), Hfb.
+ apply sup_is_upper_bound'.
rewrite -> (Rbar_le_sandwich 0 b); auto.
* apply Sup_seq_correct.
* apply (Sup_seq_minor_le _ _ 0%nat), Hgb.
* apply (upper_bound_ge_sup _ b), Hgb.
- rewrite <- (Sup_seq_bounded_plus_r _ b); auto.
apply upper_bound_ge_sup.
intro n.
rewrite <- (Sup_seq_bounded_plus_l _ b); auto.
apply upper_bound_ge_sup.
intro m.
eapply Rbar_le_trans; last first.
+ apply (sup_is_upper_bound _ (n `max` m)).
+ simpl.
apply Rplus_le_compat.
* pose proof (mon_succ_to_mon f Hfmon) as Haux.
apply Haux, Nat.le_max_l.
* pose proof (mon_succ_to_mon g Hgmon) as Haux.
apply Haux, Nat.le_max_r.
Qed.
Lemma MCT_aux1 (h : nat → nat → R) (l : nat → R) (r : R) (M : nat) :
(∀ n a, 0 <= (h n a)) →
(∀ n a, (h n a) <= (h (S n) a)) →
(∀ a, ∃ s, ∀ n, h n a <= s ) →
(∀ n, is_series (h n) (l n)) →
is_sup_seq l (Finite r) →
Finite ((sum_n (λ a : nat, real (Sup_seq (λ n : nat, h n a))) M)) =
(Sup_seq (λ n, sum_n (λ a : nat, h n a) M)).
Proof.
intros Hpos Hmon Hbd Hseries Hsup.
assert (∀ a b, Finite (a + b) = Finite a + Finite b) as Haux; auto.
induction M.
- rewrite sum_O.
destruct (Hbd 0%nat) as (s & Hs).
rewrite (Rbar_le_sandwich 0 s).
+ apply Sup_seq_ext; intro; rewrite sum_O; auto.
+ apply (Sup_seq_minor_le (λ n0 : nat, h n0 0%nat) 0 0%nat).
apply Hpos.
+ apply upper_bound_ge_sup; auto.
- rewrite sum_Sn.
rewrite Haux.
rewrite IHM.
symmetry.
erewrite Sup_seq_ext; last first.
+ intro; rewrite sum_Sn. done.
+ rewrite Haux; simpl.
erewrite <- (Sup_seq_bounded_plus_sup _ _ r); auto; intros; try split.
* apply partial_sum_pos; auto.
* eapply Rle_trans.
-- apply series_pos_partial_le; auto.
exists (l n); auto.
-- rewrite (is_series_unique _ _ (Hseries n)).
apply (sup_is_upper_bound'); auto.
* auto.
* eapply Rle_trans.
-- apply series_pos_elem_le; auto.
exists (l n); auto.
-- rewrite (is_series_unique _ _ (Hseries n)).
apply (sup_is_upper_bound'); auto.
* apply sum_n_le.
intro m; auto.
Qed.
Lemma MCT_aux2 (h : nat → nat → R) (l : nat → R) (r : R) :
(∀ n a, 0 <= (h n a)) →
(∀ n a, (h n a) <= (h (S n) a)) →
(∀ a, exists s, ∀ n, h n a <= s ) →
(∀ n, is_series (h n) (l n)) →
is_sup_seq l (Finite r) →
Rbar_le (Sup_seq (λ m, sum_n (λ a, real (Sup_seq (λ n, h n a))) m)) r.
Proof.
intros Hpos Hmon Hbd Hseries Hsup.
apply upper_bound_ge_sup.
intro M.
erewrite MCT_aux1; eauto.
apply upper_bound_ge_sup => n.
apply (Rbar_le_trans _ (Series (λ a : nat, h n a))).
- apply series_pos_partial_le; auto.
exists (l n); auto.
- apply (Rbar_le_trans _ (l n)).
+ rewrite <- (is_series_unique (λ a : nat, h n a) (l n)); auto.
apply Rbar_le_refl.
+ erewrite <- is_sup_seq_unique; eauto.
apply (sup_is_upper_bound (λ x : nat, l x)).
Qed.
Lemma MCT_aux3 (h : nat → nat → R) (l : nat → R) (r : R) :
(∀ n a, 0 <= (h n a)) →
(∀ n a, (h n a) <= (h (S n) a)) →
(∀ a, exists s, ∀ n, h n a <= s ) →
(∀ n, is_series (h n) (l n)) →
is_sup_seq l (Finite r) →
Rbar_le r (Sup_seq (λ m, sum_n (λ a, real (Sup_seq (λ n, h n a))) m)).
Proof.
intros Hpos Hmon Hbd Hseries Hsup.
rewrite <- (is_sup_seq_unique _ _ Hsup).
apply upper_bound_ge_sup.
intro n.
rewrite <- (is_series_unique _ _ (Hseries n)).
apply series_bounded_rbar; auto; [ | (exists (l n)); auto].
intro m.
apply (Sup_seq_minor_le _ _ m).
erewrite MCT_aux1; eauto.
apply (sup_is_upper_bound (λ n0 : nat, sum_n (λ a : nat, h n0 a) m)).
Qed.
Lemma MCT_aux4 (h : nat → nat → R) (l : nat → R) (r : R) :
(∀ n a, 0 <= (h n a)) →
(∀ n a, (h n a) <= (h (S n) a)) →
(∀ a, exists s, ∀ n, h n a <= s ) →
(∀ n, is_series (h n) (l n)) →
is_sup_seq l (Finite r) →
is_finite
(Sup_seq
(λ n : nat,
Finite
(sum_n (λ a : nat, real (Sup_seq (λ n0 : nat, Finite (h n0 a)))) n))).
Proof.
intros Hpos Hmon Hbd Hseries Hsup.
apply (is_finite_bounded 0 r).
- apply (Sup_seq_minor_le _ _ 0%nat).
destruct (Hbd 0%nat) as (s & Hs).
rewrite sum_O.
rewrite (Rbar_le_sandwich 0 s).
+ apply (Sup_seq_minor_le (λ n0 : nat, h n0 0%nat) 0 0%nat).
apply Hpos.
+ apply (Sup_seq_minor_le (λ n0 : nat, h n0 0%nat) 0 0%nat).
apply Hpos.
+ apply upper_bound_ge_sup; auto.
- rewrite <- (is_sup_seq_unique l r); auto.
apply upper_bound_ge_sup; intro n.
erewrite MCT_aux1; eauto.
apply Sup_seq_le; intro m.
rewrite <- (is_series_unique (h m) (l m)); auto.
apply series_pos_partial_le; auto.
exists (l m); auto.
Qed.
Lemma MCT_series (h : nat → nat → R) (l : nat → R) (r : R) :
(∀ n a, 0 <= (h n a)) →
(∀ n a, (h n a) <= (h (S n) a)) →
(∀ a, exists s, ∀ n, h n a <= s ) →
(∀ n, is_series (h n) (l n)) →
is_sup_seq l (Finite r) →
Series (λ a, Sup_seq (λ n, h n a)) = r.
Proof.
intros Hpos Hmon Hbd Hseries Hsup.
rewrite lim_is_sup'; auto.
- apply Rle_antisym.
+ apply finite_rbar_le; [eapply MCT_aux4 | eapply MCT_aux2 ]; eauto.
+ apply rbar_le_finite; [eapply MCT_aux4| eapply MCT_aux3 ]; eauto.
- intro n.
apply Rbar_0_le_to_Rle.
apply (Sup_seq_minor_le _ _ 0%nat); auto.
apply Hpos.
- apply ex_pos_bounded_series.
+ intro.
apply Rbar_0_le_to_Rle.
apply (Sup_seq_minor_le _ _ 0%nat); auto.
apply Hpos.
+ exists r.
intro m.
apply rbar_le_rle.
assert
(Rbar_le
(@sum_n R_AbelianGroup (fun a : nat => real (Sup_seq (fun n : nat => Finite (h n a)))) m) r);
auto.
erewrite MCT_aux1; eauto.
rewrite <- (is_sup_seq_unique _ r Hsup).
apply Sup_seq_le.
intro n.
rewrite <- (is_series_unique (h n) (l n)); auto.
apply series_pos_partial_le; auto.
exists (l n); auto.
Qed.
Lemma MCT_ex_series (h : nat → nat → R) (l : nat → R) (r : R) :
(∀ n a, 0 <= (h n a)) →
(∀ n a, (h n a) <= (h (S n) a)) →
(∀ a, exists s, ∀ n, h n a <= s ) →
(∀ n, is_series (h n) (l n)) →
is_sup_seq l (Finite r) →
ex_series (λ a, real (Sup_seq (λ n, h n a))).
Proof.
intros Hpos Hmon Hbd Hseries Hsup.
apply ex_pos_bounded_series.
- intro n.
apply rbar_le_finite.
+ destruct (Hbd n) as (s & Hs).
apply (Rbar_le_sandwich 0 s).
* apply (Sup_seq_minor_le _ _ 0%nat); auto.
simpl; auto.
* apply upper_bound_ge_sup; intro; simpl; auto.
+ apply (Sup_seq_minor_le (λ n0 : nat, h n0 n) _ 0%nat);
apply Hpos.
- exists r.
intro n.
assert (Rbar_le (sum_n (λ a : nat, real (Sup_seq (λ n0 : nat, h n0 a))) n) r); auto.
rewrite (MCT_aux1 h l r n); auto.
rewrite <- (is_sup_seq_unique _ r Hsup).
apply Sup_seq_le.
intro m.
rewrite <- (is_series_unique _ (l m) (Hseries m)).
rewrite lim_is_sup'; auto; last first.
+ exists (l m); auto.
+ apply sup_is_upper_bound'.
rewrite rbar_finite_real_eq.
* apply Sup_seq_correct.
* apply (Rbar_le_sandwich 0 (l m)).
-- apply (Sup_seq_minor_le _ _ 0%nat); auto.
rewrite sum_O; simpl; auto.
-- apply upper_bound_ge_sup; intro; simpl; auto.
rewrite <- (is_series_unique _ (l m) (Hseries m)).
apply series_pos_partial_le; auto.
exists (l m); auto.
Qed.
(∀ n, h n <= h (S n)) →
Sup_seq h = Sup_seq (λ n, h (S n)).
Proof.
intro Hmon.
apply Rbar_le_antisym.
- apply upper_bound_ge_sup.
intro n.
apply (Sup_seq_minor_le _ _ n), Hmon.
- apply upper_bound_ge_sup.
intro n.
apply (Sup_seq_minor_le _ _ (S (S n))), Hmon.
Qed.
Lemma sup_seq_const (r : R) :
real (Sup_seq (λ n, r)) = r.
Proof.
assert (is_finite (Sup_seq (λ n, r))) as Haux.
{ apply (Rbar_le_sandwich r r); auto.
- apply (Sup_seq_minor_le _ _ 0%nat); apply Rbar_le_refl.
- apply upper_bound_ge_sup; intro; apply Rbar_le_refl. }
apply Rle_antisym.
- apply finite_rbar_le; auto.
apply (upper_bound_ge_sup); intro; apply Rbar_le_refl.
- apply rbar_le_finite; auto.
apply (Sup_seq_minor_le _ _ 0%nat); apply Rbar_le_refl.
Qed.
Lemma Sup_seq_bounded_plus_l (f : nat → R) (b r : R) :
(∀ n, 0 <= f n <= b) →
Sup_seq (λ a, r + (f a)) = r + real (Sup_seq f).
Proof.
intro Hf.
apply Rbar_le_antisym.
- apply upper_bound_ge_sup.
intro n.
simpl.
apply Rplus_le_compat; [apply Rle_refl | ].
+ apply sup_is_upper_bound'.
rewrite -> (Rbar_le_sandwich 0 b); auto.
* apply Sup_seq_correct.
* apply (Sup_seq_minor_le _ _ 0%nat), Hf.
* apply (upper_bound_ge_sup _ b), Hf.
- rewrite /Sup_seq.
destruct ex_sup_seq as (p & Hp).
destruct ex_sup_seq as (q & Hq).
assert (is_finite p) as Hfinp.
{ apply (Rbar_le_sandwich 0 b).
+ eapply (Rbar_le_trans _ (Finite (f 0%nat))).
* apply (proj1 (Hf 0%nat)).
* rewrite <- (is_sup_seq_unique f p); auto.
apply (Sup_seq_minor_le _ _ 0%nat), Rle_refl.
+ rewrite <- (is_sup_seq_unique f p); auto.
apply (upper_bound_ge_sup _ b), Hf. }
assert (is_finite q) as Hfinq.
{ apply (Rbar_le_sandwich r (r + b)).
+ eapply (Rbar_le_trans _ (Finite (r + f 0%nat))).
* assert (r = r + 0) as Haux; [lra | ].
rewrite {1}Haux.
apply (Rbar_plus_le_compat r r 0 (f 0%nat)); [apply Rbar_le_refl | ].
apply (proj1 (Hf 0%nat)).
* rewrite <- (is_sup_seq_unique (λ a : nat, r + f a) q); auto.
apply (Sup_seq_minor_le _ _ 0%nat), Rle_refl.
+ rewrite <- (is_sup_seq_unique (λ a : nat, r + f a) q); auto.
apply (upper_bound_ge_sup _ (r + b)).
intro n; apply (Rbar_plus_le_compat r r (f n) b); [apply Rbar_le_refl | ].
apply Hf. }
simpl proj1_sig.
apply is_sup_seq_lub in Hp.
apply is_sup_seq_lub in Hq.
destruct Hp as (Hp1 & Hp2).
destruct Hq as (Hq1 & Hq2).
apply is_finite_correct in Hfinp.
destruct Hfinp as (p' & ->).
apply is_finite_correct in Hfinq.
destruct Hfinq as (q' & ->).
simpl.
assert (p' <= q' + (opp r)) as H; last first.
{
apply (Rplus_le_compat r r) in H; [ | apply Rle_refl].
apply (Rle_trans (r + p') (r + (q' + opp r)) q'); auto.
rewrite (Rplus_comm q' (opp r)).
rewrite <- Rplus_assoc.
assert (r + opp r = 0) as ->.
+ apply (plus_opp_r r).
+ rewrite Rplus_0_l.
apply Rle_refl.
}
assert (Rbar_le p' (q' + opp r)); auto.
apply Hp2.
intros _ (n & ->).
apply (Rbar_le_trans _ (r + f n + opp r)).
{ simpl.
rewrite (Rplus_comm r (f n)).
rewrite (Rplus_assoc).
assert (r + opp r = 0) as ->.
+ apply (plus_opp_r r).
+ rewrite Rplus_0_r.
apply Rle_refl.
}
simpl.
apply Rplus_le_compat; [ | apply Rle_refl ].
assert (Rbar_le (r + f n) q'); auto.
apply Hq1.
exists n; auto.
Qed.
Lemma Sup_seq_bounded_plus_r (f : nat -> R) (b r : R) :
(∀ n, 0 <= f n <= b) →
Sup_seq (λ a, (f a) + r) = real (Sup_seq f) + r.
Proof.
intro Hf.
rewrite Rplus_comm.
erewrite Sup_seq_ext; last first.
- intro; rewrite Rplus_comm; done.
- eapply Sup_seq_bounded_plus_l; eauto.
Qed.
Lemma Sup_seq_bounded_plus_sup (f g : nat → R) (b r : R) :
(∀ n, 0 <= f n <= b) →
(∀ n, 0 <= g n <= b) →
(∀ n, f n <= f (S n)) →
(∀ n, g n <= g (S n)) →
Sup_seq (λ a, (f a) + (g a)) = real (Sup_seq f) + (Sup_seq g).
Proof.
intros Hfb Hgb Hfmon Hgmon.
apply Rbar_le_antisym.
- apply upper_bound_ge_sup.
intro n.
simpl.
apply Rplus_le_compat.
+ apply sup_is_upper_bound'.
rewrite -> (Rbar_le_sandwich 0 b); auto.
* apply Sup_seq_correct.
* apply (Sup_seq_minor_le _ _ 0%nat), Hfb.
* apply (upper_bound_ge_sup _ b), Hfb.
+ apply sup_is_upper_bound'.
rewrite -> (Rbar_le_sandwich 0 b); auto.
* apply Sup_seq_correct.
* apply (Sup_seq_minor_le _ _ 0%nat), Hgb.
* apply (upper_bound_ge_sup _ b), Hgb.
- rewrite <- (Sup_seq_bounded_plus_r _ b); auto.
apply upper_bound_ge_sup.
intro n.
rewrite <- (Sup_seq_bounded_plus_l _ b); auto.
apply upper_bound_ge_sup.
intro m.
eapply Rbar_le_trans; last first.
+ apply (sup_is_upper_bound _ (n `max` m)).
+ simpl.
apply Rplus_le_compat.
* pose proof (mon_succ_to_mon f Hfmon) as Haux.
apply Haux, Nat.le_max_l.
* pose proof (mon_succ_to_mon g Hgmon) as Haux.
apply Haux, Nat.le_max_r.
Qed.
Lemma MCT_aux1 (h : nat → nat → R) (l : nat → R) (r : R) (M : nat) :
(∀ n a, 0 <= (h n a)) →
(∀ n a, (h n a) <= (h (S n) a)) →
(∀ a, ∃ s, ∀ n, h n a <= s ) →
(∀ n, is_series (h n) (l n)) →
is_sup_seq l (Finite r) →
Finite ((sum_n (λ a : nat, real (Sup_seq (λ n : nat, h n a))) M)) =
(Sup_seq (λ n, sum_n (λ a : nat, h n a) M)).
Proof.
intros Hpos Hmon Hbd Hseries Hsup.
assert (∀ a b, Finite (a + b) = Finite a + Finite b) as Haux; auto.
induction M.
- rewrite sum_O.
destruct (Hbd 0%nat) as (s & Hs).
rewrite (Rbar_le_sandwich 0 s).
+ apply Sup_seq_ext; intro; rewrite sum_O; auto.
+ apply (Sup_seq_minor_le (λ n0 : nat, h n0 0%nat) 0 0%nat).
apply Hpos.
+ apply upper_bound_ge_sup; auto.
- rewrite sum_Sn.
rewrite Haux.
rewrite IHM.
symmetry.
erewrite Sup_seq_ext; last first.
+ intro; rewrite sum_Sn. done.
+ rewrite Haux; simpl.
erewrite <- (Sup_seq_bounded_plus_sup _ _ r); auto; intros; try split.
* apply partial_sum_pos; auto.
* eapply Rle_trans.
-- apply series_pos_partial_le; auto.
exists (l n); auto.
-- rewrite (is_series_unique _ _ (Hseries n)).
apply (sup_is_upper_bound'); auto.
* auto.
* eapply Rle_trans.
-- apply series_pos_elem_le; auto.
exists (l n); auto.
-- rewrite (is_series_unique _ _ (Hseries n)).
apply (sup_is_upper_bound'); auto.
* apply sum_n_le.
intro m; auto.
Qed.
Lemma MCT_aux2 (h : nat → nat → R) (l : nat → R) (r : R) :
(∀ n a, 0 <= (h n a)) →
(∀ n a, (h n a) <= (h (S n) a)) →
(∀ a, exists s, ∀ n, h n a <= s ) →
(∀ n, is_series (h n) (l n)) →
is_sup_seq l (Finite r) →
Rbar_le (Sup_seq (λ m, sum_n (λ a, real (Sup_seq (λ n, h n a))) m)) r.
Proof.
intros Hpos Hmon Hbd Hseries Hsup.
apply upper_bound_ge_sup.
intro M.
erewrite MCT_aux1; eauto.
apply upper_bound_ge_sup => n.
apply (Rbar_le_trans _ (Series (λ a : nat, h n a))).
- apply series_pos_partial_le; auto.
exists (l n); auto.
- apply (Rbar_le_trans _ (l n)).
+ rewrite <- (is_series_unique (λ a : nat, h n a) (l n)); auto.
apply Rbar_le_refl.
+ erewrite <- is_sup_seq_unique; eauto.
apply (sup_is_upper_bound (λ x : nat, l x)).
Qed.
Lemma MCT_aux3 (h : nat → nat → R) (l : nat → R) (r : R) :
(∀ n a, 0 <= (h n a)) →
(∀ n a, (h n a) <= (h (S n) a)) →
(∀ a, exists s, ∀ n, h n a <= s ) →
(∀ n, is_series (h n) (l n)) →
is_sup_seq l (Finite r) →
Rbar_le r (Sup_seq (λ m, sum_n (λ a, real (Sup_seq (λ n, h n a))) m)).
Proof.
intros Hpos Hmon Hbd Hseries Hsup.
rewrite <- (is_sup_seq_unique _ _ Hsup).
apply upper_bound_ge_sup.
intro n.
rewrite <- (is_series_unique _ _ (Hseries n)).
apply series_bounded_rbar; auto; [ | (exists (l n)); auto].
intro m.
apply (Sup_seq_minor_le _ _ m).
erewrite MCT_aux1; eauto.
apply (sup_is_upper_bound (λ n0 : nat, sum_n (λ a : nat, h n0 a) m)).
Qed.
Lemma MCT_aux4 (h : nat → nat → R) (l : nat → R) (r : R) :
(∀ n a, 0 <= (h n a)) →
(∀ n a, (h n a) <= (h (S n) a)) →
(∀ a, exists s, ∀ n, h n a <= s ) →
(∀ n, is_series (h n) (l n)) →
is_sup_seq l (Finite r) →
is_finite
(Sup_seq
(λ n : nat,
Finite
(sum_n (λ a : nat, real (Sup_seq (λ n0 : nat, Finite (h n0 a)))) n))).
Proof.
intros Hpos Hmon Hbd Hseries Hsup.
apply (is_finite_bounded 0 r).
- apply (Sup_seq_minor_le _ _ 0%nat).
destruct (Hbd 0%nat) as (s & Hs).
rewrite sum_O.
rewrite (Rbar_le_sandwich 0 s).
+ apply (Sup_seq_minor_le (λ n0 : nat, h n0 0%nat) 0 0%nat).
apply Hpos.
+ apply (Sup_seq_minor_le (λ n0 : nat, h n0 0%nat) 0 0%nat).
apply Hpos.
+ apply upper_bound_ge_sup; auto.
- rewrite <- (is_sup_seq_unique l r); auto.
apply upper_bound_ge_sup; intro n.
erewrite MCT_aux1; eauto.
apply Sup_seq_le; intro m.
rewrite <- (is_series_unique (h m) (l m)); auto.
apply series_pos_partial_le; auto.
exists (l m); auto.
Qed.
Lemma MCT_series (h : nat → nat → R) (l : nat → R) (r : R) :
(∀ n a, 0 <= (h n a)) →
(∀ n a, (h n a) <= (h (S n) a)) →
(∀ a, exists s, ∀ n, h n a <= s ) →
(∀ n, is_series (h n) (l n)) →
is_sup_seq l (Finite r) →
Series (λ a, Sup_seq (λ n, h n a)) = r.
Proof.
intros Hpos Hmon Hbd Hseries Hsup.
rewrite lim_is_sup'; auto.
- apply Rle_antisym.
+ apply finite_rbar_le; [eapply MCT_aux4 | eapply MCT_aux2 ]; eauto.
+ apply rbar_le_finite; [eapply MCT_aux4| eapply MCT_aux3 ]; eauto.
- intro n.
apply Rbar_0_le_to_Rle.
apply (Sup_seq_minor_le _ _ 0%nat); auto.
apply Hpos.
- apply ex_pos_bounded_series.
+ intro.
apply Rbar_0_le_to_Rle.
apply (Sup_seq_minor_le _ _ 0%nat); auto.
apply Hpos.
+ exists r.
intro m.
apply rbar_le_rle.
assert
(Rbar_le
(@sum_n R_AbelianGroup (fun a : nat => real (Sup_seq (fun n : nat => Finite (h n a)))) m) r);
auto.
erewrite MCT_aux1; eauto.
rewrite <- (is_sup_seq_unique _ r Hsup).
apply Sup_seq_le.
intro n.
rewrite <- (is_series_unique (h n) (l n)); auto.
apply series_pos_partial_le; auto.
exists (l n); auto.
Qed.
Lemma MCT_ex_series (h : nat → nat → R) (l : nat → R) (r : R) :
(∀ n a, 0 <= (h n a)) →
(∀ n a, (h n a) <= (h (S n) a)) →
(∀ a, exists s, ∀ n, h n a <= s ) →
(∀ n, is_series (h n) (l n)) →
is_sup_seq l (Finite r) →
ex_series (λ a, real (Sup_seq (λ n, h n a))).
Proof.
intros Hpos Hmon Hbd Hseries Hsup.
apply ex_pos_bounded_series.
- intro n.
apply rbar_le_finite.
+ destruct (Hbd n) as (s & Hs).
apply (Rbar_le_sandwich 0 s).
* apply (Sup_seq_minor_le _ _ 0%nat); auto.
simpl; auto.
* apply upper_bound_ge_sup; intro; simpl; auto.
+ apply (Sup_seq_minor_le (λ n0 : nat, h n0 n) _ 0%nat);
apply Hpos.
- exists r.
intro n.
assert (Rbar_le (sum_n (λ a : nat, real (Sup_seq (λ n0 : nat, h n0 a))) n) r); auto.
rewrite (MCT_aux1 h l r n); auto.
rewrite <- (is_sup_seq_unique _ r Hsup).
apply Sup_seq_le.
intro m.
rewrite <- (is_series_unique _ (l m) (Hseries m)).
rewrite lim_is_sup'; auto; last first.
+ exists (l m); auto.
+ apply sup_is_upper_bound'.
rewrite rbar_finite_real_eq.
* apply Sup_seq_correct.
* apply (Rbar_le_sandwich 0 (l m)).
-- apply (Sup_seq_minor_le _ _ 0%nat); auto.
rewrite sum_O; simpl; auto.
-- apply upper_bound_ge_sup; intro; simpl; auto.
rewrite <- (is_series_unique _ (l m) (Hseries m)).
apply series_pos_partial_le; auto.
exists (l m); auto.
Qed.
Double series
Definition double_summable a :=
∃ (r: R), ∀ n, sum_n (λ j, sum_n (λ k, a (j, k)) n) n <= r.
Definition double_summable_nm a :=
∃ (r: R), ∀ n m, sum_n (λ j, sum_n (λ k, a (j, k)) n) m <= r.
Definition double_summable_n_Series a :=
∃ (r: R), ∀ n, sum_n (λ j, Series (λ k, a (j, k))) n <= r.
Lemma DS_n_to_nm a :
(∀ n m, 0 <= a(n,m)) →
double_summable a → double_summable_nm a.
Proof.
intros Hpos (r&Hr).
exists r; intros n m.
specialize (Hr (n `max` m));
etrans; eauto.
etrans; last first.
{
apply partial_sum_mon; [ | apply Nat.le_max_r].
intro.
apply sum_n_partial_pos; auto.
}
apply sum_n_le.
intro.
apply partial_sum_mon; [ | apply Nat.le_max_l].
intro; auto.
Qed.
Lemma double_summable_mono_cond a:
(∀ n m, 0 <= a(n,m)) →
(∃ (r: R), ∃ N, ∀ n, n ≥ N → sum_n (λ j, sum_n (λ k, a (j, k)) n) n <= r) →
double_summable a.
Proof.
intros Hpos (r&N&Hcond).
exists r => n.
destruct (le_ge_dec N n) as [Hle|Hge].
- apply Hcond. lia.
- transitivity (sum_n (λ j, sum_n (λ k, a (j, k)) N) N).
{ clear Hcond.
induction Hge; first reflexivity.
etransitivity; first eapply IHHge.
rewrite sum_Sn /plus//=.
rewrite -[a in a <= _]Rplus_0_r.
apply Rplus_le_compat.
* rewrite ?sum_n_bigop.
apply sum_n_le => k.
rewrite sum_Sn.
rewrite <- Rplus_0_r at 1.
apply Rplus_le_compat_l; auto.
* apply partial_sum_pos; eauto => ?.
}
eauto.
Qed.
Lemma double_summable_by_flip a:
double_summable a →
double_summable (λ xy, a (snd xy, fst xy)).
Proof.
intros (r&Hle).
exists r => n. rewrite sum_n_switch => //=.
Qed.
Lemma double_summable_flip a:
double_summable (λ xy, a (snd xy, fst xy)) → double_summable a.
Proof.
intros (r&Hle).
exists r => n. rewrite sum_n_switch => //=.
Qed.
Lemma ex_series_rows_ds a:
(∀ n m, 0 <= a(n,m)) →
(∀ j, ex_series (λ k, a (j, k))) →
ex_series (λ j, Series (λ k, a (j, k))) →
double_summable a.
Proof.
intros Hpos Hrows Hex.
destruct Hex as (r&Hseries).
exists r => n.
transitivity (sum_n (λ j, Series (λ k, a (j, k))) n).
{ rewrite ?sum_n_bigop. apply sum_n_le. intros j.
edestruct (Hrows j) as (v&Hrow). rewrite (is_series_unique _ _ Hrow).
apply is_series_partial_pos; auto.
}
apply is_series_partial_pos; eauto.
intros j.
apply series_ge_0; auto.
Qed.
Lemma ex_series_columns_ds a:
(∀ n m, 0 <= a(n,m)) →
(∀ k, ex_series (λ j, a (j, k))) →
ex_series (λ k, Series (λ j, a (j, k))) →
double_summable a.
Proof.
intros. apply double_summable_flip, ex_series_rows_ds; auto.
Qed.
Lemma ex_series_row a (DS: double_summable a) j:
(∀ n m, 0 <= a(n,m)) →
ex_series (λ k, a (j, k)).
Proof.
intros Hpos.
apply DS_n_to_nm in DS; auto.
destruct DS as (r&Hr).
apply ex_pos_bounded_series; auto.
exists r; intro n.
specialize (Hr n j).
etrans; eauto.
rewrite fubini_fin_sum.
apply sum_n_le.
intro m.
apply (partial_sum_elem (λ x, a (x, m))).
auto.
Qed.
Lemma ex_series_column a (DS: double_summable a) k:
(∀ n m, 0 <= a(n,m)) →
ex_series (λ j, a (j, k)).
Proof.
intros Hpos.
set (flip := λ (x : nat * nat), (snd x, fst x)).
eapply ex_series_ext; last first.
{ eapply ex_series_row.
- apply double_summable_by_flip => //=.
- intros; simpl; auto. }
intros n => //=.
Qed.
Lemma ex_series_row_col a (DS : double_summable a) :
(∀ n m, 0 <= a(n,m)) →
ex_series (λ j, Series (λ k, a (j, k))).
Proof.
intros Hpos.
pose proof (DS_n_to_nm a Hpos DS) as (r&Hr).
apply ex_pos_bounded_series.
- intro; apply series_ge_0; auto.
- exists r; intro n.
rewrite -(fubini_fin_inf (λ '(x,y), a(y,x))).
+ apply series_bounded.
* intro; apply partial_sum_pos; auto.
* intro. rewrite (fubini_fin_sum ((λ '(x,y), a(y,x)))); auto.
* apply ex_pos_bounded_series.
** intro; apply partial_sum_pos; auto.
** exists r; intro.
rewrite (fubini_fin_sum ((λ '(x,y), a(y,x)))); auto.
+ intros; auto.
+ intros.
apply (ex_series_column (λ '(x,y), a(y,x))).
* exists r; intros.
rewrite (fubini_fin_sum ((λ '(x,y), a(y,x)))); auto.
* intros; auto.
Qed.
Lemma ex_series_col_row a (DS : double_summable a) :
(∀ n m, 0 <= a(n,m)) →
ex_series (λ k, Series (λ j, a (j, k))).
Proof.
intros Hpos.
pose proof (DS_n_to_nm a Hpos DS) as (r&Hr).
apply ex_pos_bounded_series.
- intro; apply series_ge_0; auto.
- exists r; intro n.
rewrite -(fubini_fin_inf).
+ apply series_bounded.
* intro; apply partial_sum_pos; auto.
* intro; auto.
* apply ex_pos_bounded_series.
** intro; apply partial_sum_pos; auto.
** exists r; intro; auto.
+ intros; auto.
+ intros.
apply ex_series_column; auto.
Qed.
Section prod1.
Variable (a: nat * nat → R).
Variable (σ: nat → nat * nat).
Variable (POS: ∀ n n', 0 <= a (n, n')).
Variable (INJ: ∀ n n', a (σ n) <> 0 → σ n = σ n' → n = n').
Variable (COV: ∀ n, a n <> 0 → ∃ m, σ m = n).
Lemma inj_nat_cover1:
∀ N, ∃ K, ∀ n, n ≤ N → (fst (σ n) ≤ K ∧ snd (σ n) ≤ K).
Proof.
induction N.
- exists (max (fst (σ O)) (snd (σ O))); intros n Hle; inversion Hle; split.
+ apply Nat.le_max_l.
+ apply Nat.le_max_r.
- edestruct IHN as (K&HK).
exists (max (max (fst (σ (S N))) (snd (σ (S N)))) K); intros n Hle; inversion Hle.
+ split.
* etransitivity; last apply Nat.le_max_l. apply Nat.le_max_l.
* etransitivity; last apply Nat.le_max_l. apply Nat.le_max_r.
+ split.
* etransitivity; last apply Nat.le_max_r. edestruct HK; eauto.
* etransitivity; last apply Nat.le_max_r. edestruct HK; eauto.
Qed.
Lemma inj_nat_cover2:
∀ K1 K2, ∃ N, ∀ l m, l ≤ K1 → m ≤ K2 →
(∃ n, n ≤ N ∧ σ n = (l, m)) ∨ a (l, m) = 0.
Proof.
induction K1.
- induction K2.
+ destruct (Req_dec (a (O, O)) 0) as [|Hneq].
* exists O => l m. inversion 1; subst. inversion 1; subst.
right. done.
* edestruct (COV _ Hneq) as (N&?).
exists N => l m. inversion 1; subst. inversion 1; subst.
left. exists N; split; auto.
+ destruct IHK2 as (N&HN).
destruct (Req_dec (a (O, S K2)) 0) as [|Hneq].
* exists N => l m. inversion 1; subst. inversion 1; subst.
** right. done.
** eapply HN; auto.
* edestruct (COV _ Hneq) as (N'&?).
exists (max N N') => l m. inversion 1; subst. inversion 1; subst.
** left. exists N'. split; auto. apply Nat.le_max_r.
** edestruct (HN O m) as [(n&?&?)|]; eauto.
left. exists n. split; auto. transitivity N; auto.
apply Nat.le_max_l.
- induction K2.
+ destruct (IHK1 O) as (N&HN).
destruct (Req_dec (a (S K1, O)) 0) as [|Hneq].
* exists N => l m. inversion 1; subst; inversion 1; subst.
** right. done.
** eapply HN; auto.
* edestruct (COV _ Hneq) as (N'&?).
exists (max N N') => l m. inversion 1; subst; inversion 1; subst.
** left. exists N'. split; auto. apply Nat.le_max_r.
** edestruct (HN l O) as [(n&?&?)|]; eauto.
left. exists n. split; auto. transitivity N; auto.
apply Nat.le_max_l.
+ destruct (IHK1 (S K2)) as (N1&HN1).
destruct IHK2 as (N2&HN2).
destruct (Req_dec (a (S K1, S K2)) 0) as [|Hneq].
* exists (max N1 N2) => l m. inversion 1; subst; inversion 1; subst.
** right. done.
** edestruct (HN2 (S K1) m) as [(n&?&?)|]; eauto.
left. exists n. split; auto. transitivity N2; auto.
apply Nat.le_max_r.
** edestruct (HN1 l (S K2)) as [(n&?&?)|]; eauto.
left. exists n. split; auto. transitivity N1; auto.
apply Nat.le_max_l.
** edestruct (HN1 l m) as [(n&?&?)|]; eauto.
left. exists n. split; auto. transitivity N1; auto.
apply Nat.le_max_l.
* edestruct (COV _ Hneq) as (N'&?).
exists (max (max N1 N2) N') => l m. inversion 1; subst; inversion 1; subst.
** left. exists N'; split; auto.
apply Nat.le_max_r.
** edestruct (HN2 (S K1) m) as [(n&?&?)|]; eauto.
left. exists n. split; auto. transitivity N2; auto.
etransitivity; first apply Nat.le_max_r; apply Nat.le_max_l.
** edestruct (HN1 l (S K2)) as [(n&?&?)|]; eauto.
left. exists n. split; auto. transitivity N1; auto.
etransitivity; first apply Nat.le_max_l; apply Nat.le_max_l.
** edestruct (HN1 l m) as [(n&?&?)|]; eauto.
left. exists n. split; auto. transitivity N1; auto.
etransitivity; first apply Nat.le_max_l; apply Nat.le_max_l.
Qed.
Lemma sum_n_m_cover_diff_double_pos:
∀ N, ∃ K, ∀ l m, l ≥ K → m ≥ K →
∃ n, n ≥ N ∧ Rabs (sum_n (λ j, sum_n (λ k, a (j, k)) m) l - sum_n (a ∘ σ) N)
<= sum_n_m (a ∘ σ) (S N) n.
Proof.
intro N.
destruct (pre_converge.sum_n_m_cover_diff_double a σ INJ COV N) as (K&HK).
exists K.
intros l m Hl Hm.
destruct (HK l m Hl Hm) as (n&Hn1&Hn2).
exists n; split; auto.
etrans; [apply Hn2 | ].
apply sum_n_m_le.
intro k; simpl.
rewrite Rabs_pos_eq; try lra.
destruct (σ k); auto.
Qed.
Lemma sum_n_filter_leq (h : nat → R) n :
sum_n h n = sum_n (λ i, if bool_decide (i <= n)%nat then h i else 0) n.
Proof.
revert h.
induction n; intro h.
- do 2 rewrite sum_O.
rewrite bool_decide_eq_true_2; auto.
- do 2 rewrite sum_Sn.
rewrite IHn.
f_equal.
+ rewrite (IHn (λ i : nat, if bool_decide (i ≤ S n) then h i else 0)).
apply sum_n_ext.
intro m.
case_bool_decide; auto.
rewrite bool_decide_eq_true_2; auto.
+ rewrite bool_decide_eq_true_2; auto.
Qed.
Lemma sum_n_m_leq_covering1 n :
∃ m, sum_n (λ j : nat, sum_n (λ k : nat, a (j, k)) n) n <= sum_n (a ∘ σ) m.
Proof.
destruct (sum_n_m_cover_diff_double_pos n) as (m&Hm).
destruct (Hm (n `max` m) (n `max` m) ) as (x&Hx1&Hx2); try lia.
destruct (decide (0 <= sum_n (λ j : nat, sum_n (λ k : nat, a (j, k)) (n `max` m)) (n `max` m) - sum_n (a ∘ σ) n))
as [Hle | Hgt].
- rewrite Rabs_pos_eq in Hx2; [ | lra].
apply Rle_minus_l in Hx2.
exists x.
rewrite {3}/sum_n.
rewrite (sum_n_m_Chasles _ 0 n x); try lia.
rewrite /plus/= Rplus_comm.
etrans; [ | apply Hx2 ].
etrans; last first.
+ apply partial_sum_mon; [ | apply Nat.le_max_l].
intros; by apply partial_sum_pos.
+ apply sum_n_le.
intros; by apply partial_sum_mon; [ | lia ].
- apply Rnot_le_gt,
Rgt_lt,
Rlt_minus_l,
Rlt_le in Hgt.
rewrite Rplus_0_l in Hgt.
exists n.
etrans; [ | apply Hgt ].
etrans; last first.
+ apply partial_sum_mon; [ | apply Nat.le_max_l].
intros; by apply partial_sum_pos.
+ apply sum_n_le.
intros; by apply partial_sum_mon; [ | lia ].
Qed.
Lemma sum_n_m_leq_covering2 m :
∃ n, sum_n (a ∘ σ) m <= sum_n (λ j : nat, sum_n (λ k : nat, a (j, k)) n) n.
Proof.
destruct (inj_nat_cover1 m) as (n&Hn).
exists n.
assert (sum_n (a ∘ σ) m
= sum_n (λ x, if bool_decide ((fst (σ x) <= n)%nat ∧ (snd (σ x) <= n)%nat)
then a (σ x) else 0) m) as ->.
{ rewrite {1}sum_n_filter_leq.
rewrite (sum_n_filter_leq (λ x, if bool_decide _ then a (σ x) else 0)).
apply sum_n_ext.
intro n0.
case_bool_decide; [|done].
rewrite bool_decide_eq_true_2 //.
by apply Hn. }
destruct (inj_nat_cover2 n n) as (x&HX).
rewrite (pre_converge.sum_n_m_cover_diff_double_aux a σ INJ m n n x); auto.
etrans; last first.
- apply partial_sum_mon; [ | apply Nat.le_max_r ].
intro n0.
destruct (ssrnat.leq (σ n0).1 n && ssrnat.leq (σ n0).2 n); try lra.
destruct (σ n0); auto.
- apply sum_n_le => m0.
case_bool_decide as H.
+ by destruct H as [->%SSR_leq ->%SSR_leq].
+ apply not_and_or_not in H as [H1 | H2].
* rewrite andb_false_intro1; [lra|].
apply Is_true_false_1.
intros Hleq. apply H1.
apply SSR_leq, Is_true_true_1. done.
* rewrite andb_false_intro2; [lra|].
apply Is_true_false_1.
intro HLeq. apply H2.
apply SSR_leq, Is_true_true_1. done.
Qed.
Lemma summable_ds_helper:
Sup_seq (λ n : nat, sum_n (λ j : nat, sum_n (λ k : nat, a (j, k)) n) n) =
Sup_seq (λ n, sum_n (a ∘ σ) n).
Proof.
apply sup_seq_eq_antisym.
- apply sum_n_m_leq_covering1.
- apply sum_n_m_leq_covering2.
Qed.
Lemma ds_implies_exseries :
double_summable a → ex_series (a ∘ σ).
Proof.
intros (r & Hr).
apply ex_pos_bounded_series.
- intro n; simpl; destruct (σ n); auto.
- exists (Sup_seq (λ n, sum_n (λ j : nat, sum_n (λ k : nat, a (j, k)) n) n) ).
intro n.
apply rbar_le_finite.
+ apply (is_finite_bounded 0 r).
* apply (Sup_seq_minor_le _ _ 0).
rewrite /=sum_O/=sum_O//.
* by apply upper_bound_ge_sup.
+ rewrite summable_ds_helper.
apply (sup_is_upper_bound (λ n0 : nat, sum_n (a ∘ σ) n0)).
Qed.
End prod1.
Section prod2.
Variable (a: nat * nat → R).
Variable (σ: nat → nat * nat).
Variable (POS: ∀ n n', 0 <= a (n, n')).
Variable (INJ: ∀ n n', a (σ n) <> 0 → σ n = σ n' → n = n').
Variable (COV: ∀ n, a n <> 0 → ∃ m, σ m = n).
Variable (EXS: ex_series (a ∘ σ)).
Lemma summable_implies_ds:
double_summable a.
Proof.
rewrite /double_summable.
exists (Sup_seq (λ n, sum_n (a ∘ σ) n)).
intro.
apply rbar_le_finite.
- apply (is_finite_bounded 0 (Series (a ∘ σ))).
* apply (Sup_seq_minor_le _ _ 0).
rewrite /=sum_O//.
simpl; destruct (σ 0). auto.
* apply upper_bound_ge_sup.
intro n0; simpl.
apply series_pos_partial_le; auto.
intro m; simpl; destruct (σ m); auto.
- rewrite -summable_ds_helper; auto.
apply (sup_is_upper_bound (λ n0 : nat, sum_n (λ j : nat, sum_n (λ k : nat, a (j, k)) n0) n0)).
Qed.
Lemma is_lim_seq_sum_n (f: nat * nat → R) (h: nat → R) l:
(∀ j, j ≤ l → is_lim_seq (λ m, sum_n (λ k, f (j, k)) m) (h j)) →
is_lim_seq (λ m, sum_n (λ j, sum_n (λ k, f (j, k)) m) l) (sum_n h l).
Proof.
intros Hh.
induction l => //=.
- intros. rewrite sum_O => //=. apply (is_lim_seq_ext (λ m, sum_n (λ k, f (O, k)) m)).
* intros. rewrite sum_O. done.
* by apply Hh.
- rewrite sum_Sn.
apply (is_lim_seq_ext (λ m, plus (sum_n (λ j, sum_n (λ k, f (j, k)) m) l)
(sum_n (λ k, f (S l, k)) m))).
* intros. by rewrite sum_Sn.
* apply: is_lim_seq_plus; eauto.
rewrite //=.
Qed.
Lemma is_lim_seq_fin_abs:
∀ (u : nat → R) (l : R), is_lim_seq u l → is_lim_seq (λ n : nat, Rabs (u n)) (Rabs l).
Proof.
intros.
assert (Rabs l = Rbar_abs l) as -> by auto.
by apply (is_lim_seq_abs u (Finite l)).
Qed.
(* TODO: factor out some of the proofs of is_finite_bounded, clean up *)
Lemma is_series_double_covering:
is_series (λ j, Series (λ k, a (j, k))) (Series (a ∘ σ)).
Proof.
pose proof (summable_implies_ds) as DS.
destruct (DS_n_to_nm a POS DS) as (r&Hr).
destruct (EXS) as (v'&Hconv).
apply sup_is_lim.
- intros; apply series_ge_0; auto.
- rewrite lim_is_sup'; auto; last first.
+ intro n; simpl; destruct (σ n); auto.
+ eapply is_sup_seq_ext.
{
intro n.
rewrite -(fubini_fin_inf (λ '(x,y), a(y,x))); auto.
intro.
apply ex_series_row; auto.
}
rewrite -summable_ds_helper; auto.
apply Rbar_is_lub_sup_seq.
rewrite /Lub.Rbar_is_lub; split.
* rewrite /Lub.Rbar_is_upper_bound.
intros x (n&->).
rewrite rbar_finite_real_eq; last first.
{
apply (is_finite_bounded 0 r).
- apply (Sup_seq_minor_le _ _ 0).
rewrite /=sum_O/=sum_O//.
- apply upper_bound_ge_sup.
intro; simpl; auto.
}
rewrite Series_real_sup; last first.
{ intros; apply partial_sum_pos; auto. }
rewrite rbar_finite_real_eq; last first.
{
apply (is_finite_bounded 0 r).
- apply (Sup_seq_minor_le _ _ 0).
rewrite //=sum_O.
by apply partial_sum_pos.
- apply upper_bound_ge_sup.
intro; simpl.
by rewrite -fubini_fin_sum.
}
apply upper_bound_ge_sup.
intro m.
apply (Sup_seq_minor_le _ _ (n `max` m)).
simpl.
etrans.
** apply partial_sum_mon; [ intro; apply partial_sum_pos; auto | ].
by apply (Nat.le_max_r n).
** rewrite {1}fubini_fin_sum.
apply sum_n_le.
intros. apply partial_sum_mon; [ intro; auto | ].
lia.
* rewrite /Lub.Rbar_is_upper_bound.
intros b Hb.
rewrite rbar_finite_real_eq; last first.
{
apply (is_finite_bounded 0 r).
- apply (Sup_seq_minor_le _ _ 0).
rewrite /=sum_O/=sum_O//.
- apply upper_bound_ge_sup.
intro; simpl; auto.
}
apply upper_bound_ge_sup.
intro n.
etrans; last first.
** apply Hb.
exists n. reflexivity.
** simpl.
rewrite fubini_fin_sum.
apply series_pos_partial_le; [ intro; apply partial_sum_pos; auto | ].
apply ex_pos_bounded_series; [ intro; apply partial_sum_pos; auto | ].
exists r.
intro.
rewrite -fubini_fin_sum; auto.
Qed.
Lemma is_series_double_covering':
is_series (a ∘ σ) (Series (λ j, Series (λ k, a (j, k)))).
Proof.
specialize (is_series_unique _ _ (is_series_double_covering)) => ->.
by apply Series_correct.
Qed.
Lemma Series_double_covering:
Series (λ j, Series (λ k, a (j, k))) = (Series (a ∘ σ)).
Proof.
apply is_series_unique, is_series_double_covering.
Qed.
Lemma double_summable_fubini f:
(∀ n m, 0 <= f(n,m)) →
double_summable f →
Series (λ n, Series (λ m, f (n, m))) = Series (λ m, Series (λ n, f (n, m))).
Proof.
intros Hpos DS.
rewrite fubini_pos_series; auto.
- intro.
apply ex_series_row; auto.
- apply ex_series_row_col; auto.
Qed.
End prod2.
∃ (r: R), ∀ n, sum_n (λ j, sum_n (λ k, a (j, k)) n) n <= r.
Definition double_summable_nm a :=
∃ (r: R), ∀ n m, sum_n (λ j, sum_n (λ k, a (j, k)) n) m <= r.
Definition double_summable_n_Series a :=
∃ (r: R), ∀ n, sum_n (λ j, Series (λ k, a (j, k))) n <= r.
Lemma DS_n_to_nm a :
(∀ n m, 0 <= a(n,m)) →
double_summable a → double_summable_nm a.
Proof.
intros Hpos (r&Hr).
exists r; intros n m.
specialize (Hr (n `max` m));
etrans; eauto.
etrans; last first.
{
apply partial_sum_mon; [ | apply Nat.le_max_r].
intro.
apply sum_n_partial_pos; auto.
}
apply sum_n_le.
intro.
apply partial_sum_mon; [ | apply Nat.le_max_l].
intro; auto.
Qed.
Lemma double_summable_mono_cond a:
(∀ n m, 0 <= a(n,m)) →
(∃ (r: R), ∃ N, ∀ n, n ≥ N → sum_n (λ j, sum_n (λ k, a (j, k)) n) n <= r) →
double_summable a.
Proof.
intros Hpos (r&N&Hcond).
exists r => n.
destruct (le_ge_dec N n) as [Hle|Hge].
- apply Hcond. lia.
- transitivity (sum_n (λ j, sum_n (λ k, a (j, k)) N) N).
{ clear Hcond.
induction Hge; first reflexivity.
etransitivity; first eapply IHHge.
rewrite sum_Sn /plus//=.
rewrite -[a in a <= _]Rplus_0_r.
apply Rplus_le_compat.
* rewrite ?sum_n_bigop.
apply sum_n_le => k.
rewrite sum_Sn.
rewrite <- Rplus_0_r at 1.
apply Rplus_le_compat_l; auto.
* apply partial_sum_pos; eauto => ?.
}
eauto.
Qed.
Lemma double_summable_by_flip a:
double_summable a →
double_summable (λ xy, a (snd xy, fst xy)).
Proof.
intros (r&Hle).
exists r => n. rewrite sum_n_switch => //=.
Qed.
Lemma double_summable_flip a:
double_summable (λ xy, a (snd xy, fst xy)) → double_summable a.
Proof.
intros (r&Hle).
exists r => n. rewrite sum_n_switch => //=.
Qed.
Lemma ex_series_rows_ds a:
(∀ n m, 0 <= a(n,m)) →
(∀ j, ex_series (λ k, a (j, k))) →
ex_series (λ j, Series (λ k, a (j, k))) →
double_summable a.
Proof.
intros Hpos Hrows Hex.
destruct Hex as (r&Hseries).
exists r => n.
transitivity (sum_n (λ j, Series (λ k, a (j, k))) n).
{ rewrite ?sum_n_bigop. apply sum_n_le. intros j.
edestruct (Hrows j) as (v&Hrow). rewrite (is_series_unique _ _ Hrow).
apply is_series_partial_pos; auto.
}
apply is_series_partial_pos; eauto.
intros j.
apply series_ge_0; auto.
Qed.
Lemma ex_series_columns_ds a:
(∀ n m, 0 <= a(n,m)) →
(∀ k, ex_series (λ j, a (j, k))) →
ex_series (λ k, Series (λ j, a (j, k))) →
double_summable a.
Proof.
intros. apply double_summable_flip, ex_series_rows_ds; auto.
Qed.
Lemma ex_series_row a (DS: double_summable a) j:
(∀ n m, 0 <= a(n,m)) →
ex_series (λ k, a (j, k)).
Proof.
intros Hpos.
apply DS_n_to_nm in DS; auto.
destruct DS as (r&Hr).
apply ex_pos_bounded_series; auto.
exists r; intro n.
specialize (Hr n j).
etrans; eauto.
rewrite fubini_fin_sum.
apply sum_n_le.
intro m.
apply (partial_sum_elem (λ x, a (x, m))).
auto.
Qed.
Lemma ex_series_column a (DS: double_summable a) k:
(∀ n m, 0 <= a(n,m)) →
ex_series (λ j, a (j, k)).
Proof.
intros Hpos.
set (flip := λ (x : nat * nat), (snd x, fst x)).
eapply ex_series_ext; last first.
{ eapply ex_series_row.
- apply double_summable_by_flip => //=.
- intros; simpl; auto. }
intros n => //=.
Qed.
Lemma ex_series_row_col a (DS : double_summable a) :
(∀ n m, 0 <= a(n,m)) →
ex_series (λ j, Series (λ k, a (j, k))).
Proof.
intros Hpos.
pose proof (DS_n_to_nm a Hpos DS) as (r&Hr).
apply ex_pos_bounded_series.
- intro; apply series_ge_0; auto.
- exists r; intro n.
rewrite -(fubini_fin_inf (λ '(x,y), a(y,x))).
+ apply series_bounded.
* intro; apply partial_sum_pos; auto.
* intro. rewrite (fubini_fin_sum ((λ '(x,y), a(y,x)))); auto.
* apply ex_pos_bounded_series.
** intro; apply partial_sum_pos; auto.
** exists r; intro.
rewrite (fubini_fin_sum ((λ '(x,y), a(y,x)))); auto.
+ intros; auto.
+ intros.
apply (ex_series_column (λ '(x,y), a(y,x))).
* exists r; intros.
rewrite (fubini_fin_sum ((λ '(x,y), a(y,x)))); auto.
* intros; auto.
Qed.
Lemma ex_series_col_row a (DS : double_summable a) :
(∀ n m, 0 <= a(n,m)) →
ex_series (λ k, Series (λ j, a (j, k))).
Proof.
intros Hpos.
pose proof (DS_n_to_nm a Hpos DS) as (r&Hr).
apply ex_pos_bounded_series.
- intro; apply series_ge_0; auto.
- exists r; intro n.
rewrite -(fubini_fin_inf).
+ apply series_bounded.
* intro; apply partial_sum_pos; auto.
* intro; auto.
* apply ex_pos_bounded_series.
** intro; apply partial_sum_pos; auto.
** exists r; intro; auto.
+ intros; auto.
+ intros.
apply ex_series_column; auto.
Qed.
Section prod1.
Variable (a: nat * nat → R).
Variable (σ: nat → nat * nat).
Variable (POS: ∀ n n', 0 <= a (n, n')).
Variable (INJ: ∀ n n', a (σ n) <> 0 → σ n = σ n' → n = n').
Variable (COV: ∀ n, a n <> 0 → ∃ m, σ m = n).
Lemma inj_nat_cover1:
∀ N, ∃ K, ∀ n, n ≤ N → (fst (σ n) ≤ K ∧ snd (σ n) ≤ K).
Proof.
induction N.
- exists (max (fst (σ O)) (snd (σ O))); intros n Hle; inversion Hle; split.
+ apply Nat.le_max_l.
+ apply Nat.le_max_r.
- edestruct IHN as (K&HK).
exists (max (max (fst (σ (S N))) (snd (σ (S N)))) K); intros n Hle; inversion Hle.
+ split.
* etransitivity; last apply Nat.le_max_l. apply Nat.le_max_l.
* etransitivity; last apply Nat.le_max_l. apply Nat.le_max_r.
+ split.
* etransitivity; last apply Nat.le_max_r. edestruct HK; eauto.
* etransitivity; last apply Nat.le_max_r. edestruct HK; eauto.
Qed.
Lemma inj_nat_cover2:
∀ K1 K2, ∃ N, ∀ l m, l ≤ K1 → m ≤ K2 →
(∃ n, n ≤ N ∧ σ n = (l, m)) ∨ a (l, m) = 0.
Proof.
induction K1.
- induction K2.
+ destruct (Req_dec (a (O, O)) 0) as [|Hneq].
* exists O => l m. inversion 1; subst. inversion 1; subst.
right. done.
* edestruct (COV _ Hneq) as (N&?).
exists N => l m. inversion 1; subst. inversion 1; subst.
left. exists N; split; auto.
+ destruct IHK2 as (N&HN).
destruct (Req_dec (a (O, S K2)) 0) as [|Hneq].
* exists N => l m. inversion 1; subst. inversion 1; subst.
** right. done.
** eapply HN; auto.
* edestruct (COV _ Hneq) as (N'&?).
exists (max N N') => l m. inversion 1; subst. inversion 1; subst.
** left. exists N'. split; auto. apply Nat.le_max_r.
** edestruct (HN O m) as [(n&?&?)|]; eauto.
left. exists n. split; auto. transitivity N; auto.
apply Nat.le_max_l.
- induction K2.
+ destruct (IHK1 O) as (N&HN).
destruct (Req_dec (a (S K1, O)) 0) as [|Hneq].
* exists N => l m. inversion 1; subst; inversion 1; subst.
** right. done.
** eapply HN; auto.
* edestruct (COV _ Hneq) as (N'&?).
exists (max N N') => l m. inversion 1; subst; inversion 1; subst.
** left. exists N'. split; auto. apply Nat.le_max_r.
** edestruct (HN l O) as [(n&?&?)|]; eauto.
left. exists n. split; auto. transitivity N; auto.
apply Nat.le_max_l.
+ destruct (IHK1 (S K2)) as (N1&HN1).
destruct IHK2 as (N2&HN2).
destruct (Req_dec (a (S K1, S K2)) 0) as [|Hneq].
* exists (max N1 N2) => l m. inversion 1; subst; inversion 1; subst.
** right. done.
** edestruct (HN2 (S K1) m) as [(n&?&?)|]; eauto.
left. exists n. split; auto. transitivity N2; auto.
apply Nat.le_max_r.
** edestruct (HN1 l (S K2)) as [(n&?&?)|]; eauto.
left. exists n. split; auto. transitivity N1; auto.
apply Nat.le_max_l.
** edestruct (HN1 l m) as [(n&?&?)|]; eauto.
left. exists n. split; auto. transitivity N1; auto.
apply Nat.le_max_l.
* edestruct (COV _ Hneq) as (N'&?).
exists (max (max N1 N2) N') => l m. inversion 1; subst; inversion 1; subst.
** left. exists N'; split; auto.
apply Nat.le_max_r.
** edestruct (HN2 (S K1) m) as [(n&?&?)|]; eauto.
left. exists n. split; auto. transitivity N2; auto.
etransitivity; first apply Nat.le_max_r; apply Nat.le_max_l.
** edestruct (HN1 l (S K2)) as [(n&?&?)|]; eauto.
left. exists n. split; auto. transitivity N1; auto.
etransitivity; first apply Nat.le_max_l; apply Nat.le_max_l.
** edestruct (HN1 l m) as [(n&?&?)|]; eauto.
left. exists n. split; auto. transitivity N1; auto.
etransitivity; first apply Nat.le_max_l; apply Nat.le_max_l.
Qed.
Lemma sum_n_m_cover_diff_double_pos:
∀ N, ∃ K, ∀ l m, l ≥ K → m ≥ K →
∃ n, n ≥ N ∧ Rabs (sum_n (λ j, sum_n (λ k, a (j, k)) m) l - sum_n (a ∘ σ) N)
<= sum_n_m (a ∘ σ) (S N) n.
Proof.
intro N.
destruct (pre_converge.sum_n_m_cover_diff_double a σ INJ COV N) as (K&HK).
exists K.
intros l m Hl Hm.
destruct (HK l m Hl Hm) as (n&Hn1&Hn2).
exists n; split; auto.
etrans; [apply Hn2 | ].
apply sum_n_m_le.
intro k; simpl.
rewrite Rabs_pos_eq; try lra.
destruct (σ k); auto.
Qed.
Lemma sum_n_filter_leq (h : nat → R) n :
sum_n h n = sum_n (λ i, if bool_decide (i <= n)%nat then h i else 0) n.
Proof.
revert h.
induction n; intro h.
- do 2 rewrite sum_O.
rewrite bool_decide_eq_true_2; auto.
- do 2 rewrite sum_Sn.
rewrite IHn.
f_equal.
+ rewrite (IHn (λ i : nat, if bool_decide (i ≤ S n) then h i else 0)).
apply sum_n_ext.
intro m.
case_bool_decide; auto.
rewrite bool_decide_eq_true_2; auto.
+ rewrite bool_decide_eq_true_2; auto.
Qed.
Lemma sum_n_m_leq_covering1 n :
∃ m, sum_n (λ j : nat, sum_n (λ k : nat, a (j, k)) n) n <= sum_n (a ∘ σ) m.
Proof.
destruct (sum_n_m_cover_diff_double_pos n) as (m&Hm).
destruct (Hm (n `max` m) (n `max` m) ) as (x&Hx1&Hx2); try lia.
destruct (decide (0 <= sum_n (λ j : nat, sum_n (λ k : nat, a (j, k)) (n `max` m)) (n `max` m) - sum_n (a ∘ σ) n))
as [Hle | Hgt].
- rewrite Rabs_pos_eq in Hx2; [ | lra].
apply Rle_minus_l in Hx2.
exists x.
rewrite {3}/sum_n.
rewrite (sum_n_m_Chasles _ 0 n x); try lia.
rewrite /plus/= Rplus_comm.
etrans; [ | apply Hx2 ].
etrans; last first.
+ apply partial_sum_mon; [ | apply Nat.le_max_l].
intros; by apply partial_sum_pos.
+ apply sum_n_le.
intros; by apply partial_sum_mon; [ | lia ].
- apply Rnot_le_gt,
Rgt_lt,
Rlt_minus_l,
Rlt_le in Hgt.
rewrite Rplus_0_l in Hgt.
exists n.
etrans; [ | apply Hgt ].
etrans; last first.
+ apply partial_sum_mon; [ | apply Nat.le_max_l].
intros; by apply partial_sum_pos.
+ apply sum_n_le.
intros; by apply partial_sum_mon; [ | lia ].
Qed.
Lemma sum_n_m_leq_covering2 m :
∃ n, sum_n (a ∘ σ) m <= sum_n (λ j : nat, sum_n (λ k : nat, a (j, k)) n) n.
Proof.
destruct (inj_nat_cover1 m) as (n&Hn).
exists n.
assert (sum_n (a ∘ σ) m
= sum_n (λ x, if bool_decide ((fst (σ x) <= n)%nat ∧ (snd (σ x) <= n)%nat)
then a (σ x) else 0) m) as ->.
{ rewrite {1}sum_n_filter_leq.
rewrite (sum_n_filter_leq (λ x, if bool_decide _ then a (σ x) else 0)).
apply sum_n_ext.
intro n0.
case_bool_decide; [|done].
rewrite bool_decide_eq_true_2 //.
by apply Hn. }
destruct (inj_nat_cover2 n n) as (x&HX).
rewrite (pre_converge.sum_n_m_cover_diff_double_aux a σ INJ m n n x); auto.
etrans; last first.
- apply partial_sum_mon; [ | apply Nat.le_max_r ].
intro n0.
destruct (ssrnat.leq (σ n0).1 n && ssrnat.leq (σ n0).2 n); try lra.
destruct (σ n0); auto.
- apply sum_n_le => m0.
case_bool_decide as H.
+ by destruct H as [->%SSR_leq ->%SSR_leq].
+ apply not_and_or_not in H as [H1 | H2].
* rewrite andb_false_intro1; [lra|].
apply Is_true_false_1.
intros Hleq. apply H1.
apply SSR_leq, Is_true_true_1. done.
* rewrite andb_false_intro2; [lra|].
apply Is_true_false_1.
intro HLeq. apply H2.
apply SSR_leq, Is_true_true_1. done.
Qed.
Lemma summable_ds_helper:
Sup_seq (λ n : nat, sum_n (λ j : nat, sum_n (λ k : nat, a (j, k)) n) n) =
Sup_seq (λ n, sum_n (a ∘ σ) n).
Proof.
apply sup_seq_eq_antisym.
- apply sum_n_m_leq_covering1.
- apply sum_n_m_leq_covering2.
Qed.
Lemma ds_implies_exseries :
double_summable a → ex_series (a ∘ σ).
Proof.
intros (r & Hr).
apply ex_pos_bounded_series.
- intro n; simpl; destruct (σ n); auto.
- exists (Sup_seq (λ n, sum_n (λ j : nat, sum_n (λ k : nat, a (j, k)) n) n) ).
intro n.
apply rbar_le_finite.
+ apply (is_finite_bounded 0 r).
* apply (Sup_seq_minor_le _ _ 0).
rewrite /=sum_O/=sum_O//.
* by apply upper_bound_ge_sup.
+ rewrite summable_ds_helper.
apply (sup_is_upper_bound (λ n0 : nat, sum_n (a ∘ σ) n0)).
Qed.
End prod1.
Section prod2.
Variable (a: nat * nat → R).
Variable (σ: nat → nat * nat).
Variable (POS: ∀ n n', 0 <= a (n, n')).
Variable (INJ: ∀ n n', a (σ n) <> 0 → σ n = σ n' → n = n').
Variable (COV: ∀ n, a n <> 0 → ∃ m, σ m = n).
Variable (EXS: ex_series (a ∘ σ)).
Lemma summable_implies_ds:
double_summable a.
Proof.
rewrite /double_summable.
exists (Sup_seq (λ n, sum_n (a ∘ σ) n)).
intro.
apply rbar_le_finite.
- apply (is_finite_bounded 0 (Series (a ∘ σ))).
* apply (Sup_seq_minor_le _ _ 0).
rewrite /=sum_O//.
simpl; destruct (σ 0). auto.
* apply upper_bound_ge_sup.
intro n0; simpl.
apply series_pos_partial_le; auto.
intro m; simpl; destruct (σ m); auto.
- rewrite -summable_ds_helper; auto.
apply (sup_is_upper_bound (λ n0 : nat, sum_n (λ j : nat, sum_n (λ k : nat, a (j, k)) n0) n0)).
Qed.
Lemma is_lim_seq_sum_n (f: nat * nat → R) (h: nat → R) l:
(∀ j, j ≤ l → is_lim_seq (λ m, sum_n (λ k, f (j, k)) m) (h j)) →
is_lim_seq (λ m, sum_n (λ j, sum_n (λ k, f (j, k)) m) l) (sum_n h l).
Proof.
intros Hh.
induction l => //=.
- intros. rewrite sum_O => //=. apply (is_lim_seq_ext (λ m, sum_n (λ k, f (O, k)) m)).
* intros. rewrite sum_O. done.
* by apply Hh.
- rewrite sum_Sn.
apply (is_lim_seq_ext (λ m, plus (sum_n (λ j, sum_n (λ k, f (j, k)) m) l)
(sum_n (λ k, f (S l, k)) m))).
* intros. by rewrite sum_Sn.
* apply: is_lim_seq_plus; eauto.
rewrite //=.
Qed.
Lemma is_lim_seq_fin_abs:
∀ (u : nat → R) (l : R), is_lim_seq u l → is_lim_seq (λ n : nat, Rabs (u n)) (Rabs l).
Proof.
intros.
assert (Rabs l = Rbar_abs l) as -> by auto.
by apply (is_lim_seq_abs u (Finite l)).
Qed.
(* TODO: factor out some of the proofs of is_finite_bounded, clean up *)
Lemma is_series_double_covering:
is_series (λ j, Series (λ k, a (j, k))) (Series (a ∘ σ)).
Proof.
pose proof (summable_implies_ds) as DS.
destruct (DS_n_to_nm a POS DS) as (r&Hr).
destruct (EXS) as (v'&Hconv).
apply sup_is_lim.
- intros; apply series_ge_0; auto.
- rewrite lim_is_sup'; auto; last first.
+ intro n; simpl; destruct (σ n); auto.
+ eapply is_sup_seq_ext.
{
intro n.
rewrite -(fubini_fin_inf (λ '(x,y), a(y,x))); auto.
intro.
apply ex_series_row; auto.
}
rewrite -summable_ds_helper; auto.
apply Rbar_is_lub_sup_seq.
rewrite /Lub.Rbar_is_lub; split.
* rewrite /Lub.Rbar_is_upper_bound.
intros x (n&->).
rewrite rbar_finite_real_eq; last first.
{
apply (is_finite_bounded 0 r).
- apply (Sup_seq_minor_le _ _ 0).
rewrite /=sum_O/=sum_O//.
- apply upper_bound_ge_sup.
intro; simpl; auto.
}
rewrite Series_real_sup; last first.
{ intros; apply partial_sum_pos; auto. }
rewrite rbar_finite_real_eq; last first.
{
apply (is_finite_bounded 0 r).
- apply (Sup_seq_minor_le _ _ 0).
rewrite //=sum_O.
by apply partial_sum_pos.
- apply upper_bound_ge_sup.
intro; simpl.
by rewrite -fubini_fin_sum.
}
apply upper_bound_ge_sup.
intro m.
apply (Sup_seq_minor_le _ _ (n `max` m)).
simpl.
etrans.
** apply partial_sum_mon; [ intro; apply partial_sum_pos; auto | ].
by apply (Nat.le_max_r n).
** rewrite {1}fubini_fin_sum.
apply sum_n_le.
intros. apply partial_sum_mon; [ intro; auto | ].
lia.
* rewrite /Lub.Rbar_is_upper_bound.
intros b Hb.
rewrite rbar_finite_real_eq; last first.
{
apply (is_finite_bounded 0 r).
- apply (Sup_seq_minor_le _ _ 0).
rewrite /=sum_O/=sum_O//.
- apply upper_bound_ge_sup.
intro; simpl; auto.
}
apply upper_bound_ge_sup.
intro n.
etrans; last first.
** apply Hb.
exists n. reflexivity.
** simpl.
rewrite fubini_fin_sum.
apply series_pos_partial_le; [ intro; apply partial_sum_pos; auto | ].
apply ex_pos_bounded_series; [ intro; apply partial_sum_pos; auto | ].
exists r.
intro.
rewrite -fubini_fin_sum; auto.
Qed.
Lemma is_series_double_covering':
is_series (a ∘ σ) (Series (λ j, Series (λ k, a (j, k)))).
Proof.
specialize (is_series_unique _ _ (is_series_double_covering)) => ->.
by apply Series_correct.
Qed.
Lemma Series_double_covering:
Series (λ j, Series (λ k, a (j, k))) = (Series (a ∘ σ)).
Proof.
apply is_series_unique, is_series_double_covering.
Qed.
Lemma double_summable_fubini f:
(∀ n m, 0 <= f(n,m)) →
double_summable f →
Series (λ n, Series (λ m, f (n, m))) = Series (λ m, Series (λ n, f (n, m))).
Proof.
intros Hpos DS.
rewrite fubini_pos_series; auto.
- intro.
apply ex_series_row; auto.
- apply ex_series_row_col; auto.
Qed.
End prod2.