src/HOL/Analysis/Summation_Tests.thy
author paulson <lp15@cam.ac.uk>
Tue Apr 25 16:39:54 2017 +0100 (2017-04-25)
changeset 65578 e4997c181cce
parent 64449 8c44dfb4ca8a
child 66447 a1f5c5c26fa6
permissions -rw-r--r--
New material from PNT proof, as well as more default [simp] declarations. Also removed duplicate theorems about geometric series
wenzelm@63992
     1
(*  Title:    HOL/Analysis/Summation_Tests.thy
hoelzl@62055
     2
    Author:   Manuel Eberl, TU M√ľnchen
hoelzl@62055
     3
*)
hoelzl@63594
     4
eberlm@62085
     5
section \<open>Radius of Convergence and Summation Tests\<close>
hoelzl@62055
     6
hoelzl@63594
     7
theory Summation_Tests
eberlm@62049
     8
imports
eberlm@62049
     9
  Complex_Main
eberlm@64449
    10
  "~~/src/HOL/Library/Discrete"
hoelzl@63594
    11
  "~~/src/HOL/Library/Extended_Real"
eberlm@62049
    12
  "~~/src/HOL/Library/Liminf_Limsup"
eberlm@62049
    13
begin
eberlm@62049
    14
hoelzl@62055
    15
text \<open>
hoelzl@63594
    16
  The definition of the radius of convergence of a power series,
hoelzl@62055
    17
  various summability tests, lemmas to compute the radius of convergence etc.
hoelzl@62055
    18
\<close>
eberlm@62049
    19
eberlm@62049
    20
subsection \<open>Convergence tests for infinite sums\<close>
eberlm@62049
    21
eberlm@62049
    22
subsubsection \<open>Root test\<close>
eberlm@62049
    23
eberlm@62049
    24
lemma limsup_root_powser:
eberlm@62049
    25
  fixes f :: "nat \<Rightarrow> 'a :: {banach, real_normed_div_algebra}"
hoelzl@63594
    26
  shows "limsup (\<lambda>n. ereal (root n (norm (f n * z ^ n)))) =
eberlm@62049
    27
             limsup (\<lambda>n. ereal (root n (norm (f n)))) * ereal (norm z)"
eberlm@62049
    28
proof -
hoelzl@63594
    29
  have A: "(\<lambda>n. ereal (root n (norm (f n * z ^ n)))) =
eberlm@62049
    30
              (\<lambda>n. ereal (root n (norm (f n))) * ereal (norm z))" (is "?g = ?h")
eberlm@62049
    31
  proof
eberlm@62049
    32
    fix n show "?g n = ?h n"
eberlm@62049
    33
    by (cases "n = 0") (simp_all add: norm_mult real_root_mult real_root_pos2 norm_power)
eberlm@62049
    34
  qed
eberlm@62049
    35
  show ?thesis by (subst A, subst limsup_ereal_mult_right) simp_all
eberlm@62049
    36
qed
eberlm@62049
    37
eberlm@62049
    38
lemma limsup_root_limit:
eberlm@62049
    39
  assumes "(\<lambda>n. ereal (root n (norm (f n)))) \<longlonglongrightarrow> l" (is "?g \<longlonglongrightarrow> _")
eberlm@62049
    40
  shows   "limsup (\<lambda>n. ereal (root n (norm (f n)))) = l"
eberlm@62049
    41
proof -
eberlm@62049
    42
  from assms have "convergent ?g" "lim ?g = l"
eberlm@62049
    43
    unfolding convergent_def by (blast intro: limI)+
eberlm@62049
    44
  with convergent_limsup_cl show ?thesis by force
eberlm@62049
    45
qed
eberlm@62049
    46
eberlm@62049
    47
lemma limsup_root_limit':
eberlm@62049
    48
  assumes "(\<lambda>n. root n (norm (f n))) \<longlonglongrightarrow> l"
eberlm@62049
    49
  shows   "limsup (\<lambda>n. ereal (root n (norm (f n)))) = ereal l"
eberlm@62049
    50
  by (intro limsup_root_limit tendsto_ereal assms)
eberlm@62049
    51
eberlm@62049
    52
lemma root_test_convergence':
eberlm@62049
    53
  fixes f :: "nat \<Rightarrow> 'a :: banach"
eberlm@62049
    54
  defines "l \<equiv> limsup (\<lambda>n. ereal (root n (norm (f n))))"
eberlm@62049
    55
  assumes l: "l < 1"
eberlm@62049
    56
  shows   "summable f"
eberlm@62049
    57
proof -
eberlm@62049
    58
  have "0 = limsup (\<lambda>n. 0)" by (simp add: Limsup_const)
eberlm@62049
    59
  also have "... \<le> l" unfolding l_def by (intro Limsup_mono) (simp_all add: real_root_ge_zero)
eberlm@62049
    60
  finally have "l \<ge> 0" by simp
eberlm@62049
    61
  with l obtain l' where l': "l = ereal l'" by (cases l) simp_all
eberlm@62049
    62
wenzelm@63040
    63
  define c where "c = (1 - l') / 2"
hoelzl@63594
    64
  from l and \<open>l \<ge> 0\<close> have c: "l + c > l" "l' + c \<ge> 0" "l' + c < 1" unfolding c_def
eberlm@62049
    65
    by (simp_all add: field_simps l')
eberlm@62049
    66
  have "\<forall>C>l. eventually (\<lambda>n. ereal (root n (norm (f n))) < C) sequentially"
eberlm@62049
    67
    by (subst Limsup_le_iff[symmetric]) (simp add: l_def)
eberlm@62049
    68
  with c have "eventually (\<lambda>n. ereal (root n (norm (f n))) < l + ereal c) sequentially" by simp
eberlm@62049
    69
  with eventually_gt_at_top[of "0::nat"]
eberlm@62049
    70
    have "eventually (\<lambda>n. norm (f n) \<le> (l' + c) ^ n) sequentially"
eberlm@62049
    71
  proof eventually_elim
hoelzl@63594
    72
    fix n :: nat assume n: "n > 0"
eberlm@62049
    73
    assume "ereal (root n (norm (f n))) < l + ereal c"
eberlm@62049
    74
    hence "root n (norm (f n)) \<le> l' + c" by (simp add: l')
eberlm@62049
    75
    with c n have "root n (norm (f n)) ^ n \<le> (l' + c) ^ n"
eberlm@62049
    76
      by (intro power_mono) (simp_all add: real_root_ge_zero)
eberlm@62049
    77
    also from n have "root n (norm (f n)) ^ n = norm (f n)" by simp
eberlm@62049
    78
    finally show "norm (f n) \<le> (l' + c) ^ n" by simp
eberlm@62049
    79
  qed
eberlm@62049
    80
  thus ?thesis
eberlm@62049
    81
    by (rule summable_comparison_test_ev[OF _ summable_geometric]) (simp add: c)
eberlm@62049
    82
qed
eberlm@62049
    83
eberlm@62049
    84
lemma root_test_divergence:
eberlm@62049
    85
  fixes f :: "nat \<Rightarrow> 'a :: banach"
eberlm@62049
    86
  defines "l \<equiv> limsup (\<lambda>n. ereal (root n (norm (f n))))"
eberlm@62049
    87
  assumes l: "l > 1"
eberlm@62049
    88
  shows   "\<not>summable f"
eberlm@62049
    89
proof
eberlm@62049
    90
  assume "summable f"
eberlm@62049
    91
  hence bounded: "Bseq f" by (simp add: summable_imp_Bseq)
eberlm@62049
    92
eberlm@62049
    93
  have "0 = limsup (\<lambda>n. 0)" by (simp add: Limsup_const)
eberlm@62049
    94
  also have "... \<le> l" unfolding l_def by (intro Limsup_mono) (simp_all add: real_root_ge_zero)
eberlm@62049
    95
  finally have l_nonneg: "l \<ge> 0" by simp
eberlm@62049
    96
wenzelm@63040
    97
  define c where "c = (if l = \<infinity> then 2 else 1 + (real_of_ereal l - 1) / 2)"
eberlm@62049
    98
  from l l_nonneg consider "l = \<infinity>" | "\<exists>l'. l = ereal l'" by (cases l) simp_all
eberlm@62049
    99
  hence c: "c > 1 \<and> ereal c < l" by cases (insert l, auto simp: c_def field_simps)
eberlm@62049
   100
eberlm@62049
   101
  have unbounded: "\<not>bdd_above {n. root n (norm (f n)) > c}"
eberlm@62049
   102
  proof
eberlm@62049
   103
    assume "bdd_above {n. root n (norm (f n)) > c}"
eberlm@62049
   104
    then obtain N where "\<forall>n. root n (norm (f n)) > c \<longrightarrow> n \<le> N" unfolding bdd_above_def by blast
eberlm@62049
   105
    hence "\<exists>N. \<forall>n\<ge>N. root n (norm (f n)) \<le> c"
eberlm@62049
   106
      by (intro exI[of _ "N + 1"]) (force simp: not_less_eq_eq[symmetric])
eberlm@62049
   107
    hence "eventually (\<lambda>n. root n (norm (f n)) \<le> c) sequentially"
eberlm@62049
   108
      by (auto simp: eventually_at_top_linorder)
eberlm@62049
   109
    hence "l \<le> c" unfolding l_def by (intro Limsup_bounded) simp_all
eberlm@62049
   110
    with c show False by auto
eberlm@62049
   111
  qed
hoelzl@63594
   112
eberlm@62049
   113
  from bounded obtain K where K: "K > 0" "\<And>n. norm (f n) \<le> K" using BseqE by blast
wenzelm@63040
   114
  define n where "n = nat \<lceil>log c K\<rceil>"
eberlm@62049
   115
  from unbounded have "\<exists>m>n. c < root m (norm (f m))" unfolding bdd_above_def
eberlm@62049
   116
    by (auto simp: not_le)
eberlm@62049
   117
  then guess m by (elim exE conjE) note m = this
eberlm@62049
   118
  from c K have "K = c powr log c K" by (simp add: powr_def log_def)
eberlm@62049
   119
  also from c have "c powr log c K \<le> c powr real n" unfolding n_def
eberlm@62049
   120
    by (intro powr_mono, linarith, simp)
eberlm@62049
   121
  finally have "K \<le> c ^ n" using c by (simp add: powr_realpow)
eberlm@62049
   122
  also from c m have "c ^ n < c ^ m" by simp
eberlm@62049
   123
  also from c m have "c ^ m < root m (norm (f m)) ^ m" by (intro power_strict_mono) simp_all
eberlm@62049
   124
  also from m have "... = norm (f m)" by simp
eberlm@62049
   125
  finally show False using K(2)[of m]  by simp
eberlm@62049
   126
qed
eberlm@62049
   127
eberlm@62049
   128
eberlm@62085
   129
subsubsection \<open>Cauchy's condensation test\<close>
eberlm@62049
   130
eberlm@62049
   131
context
eberlm@62049
   132
fixes f :: "nat \<Rightarrow> real"
eberlm@62049
   133
begin
eberlm@62049
   134
eberlm@62049
   135
private lemma condensation_inequality:
eberlm@62049
   136
  assumes mono: "\<And>m n. 0 < m \<Longrightarrow> m \<le> n \<Longrightarrow> f n \<le> f m"
eberlm@64449
   137
  shows   "(\<Sum>k=1..<n. f k) \<ge> (\<Sum>k=1..<n. f (2 * 2 ^ Discrete.log k))" (is "?thesis1")
eberlm@64449
   138
          "(\<Sum>k=1..<n. f k) \<le> (\<Sum>k=1..<n. f (2 ^ Discrete.log k))" (is "?thesis2")
eberlm@64449
   139
  by (intro sum_mono mono Discrete.log_exp2_ge Discrete.log_exp2_le, simp, simp)+
eberlm@62049
   140
eberlm@64449
   141
private lemma condensation_condense1: "(\<Sum>k=1..<2^n. f (2 ^ Discrete.log k)) = (\<Sum>k<n. 2^k * f (2 ^ k))"
eberlm@62049
   142
proof (induction n)
eberlm@62049
   143
  case (Suc n)
hoelzl@63594
   144
  have "{1..<2^Suc n} = {1..<2^n} \<union> {2^n..<(2^Suc n :: nat)}" by auto
eberlm@64449
   145
  also have "(\<Sum>k\<in>\<dots>. f (2 ^ Discrete.log k)) =
eberlm@64449
   146
                 (\<Sum>k<n. 2^k * f (2^k)) + (\<Sum>k = 2^n..<2^Suc n. f (2^Discrete.log k))"
nipkow@64267
   147
    by (subst sum.union_disjoint) (insert Suc, auto)
eberlm@64449
   148
  also have "Discrete.log k = n" if "k \<in> {2^n..<2^Suc n}" for k using that by (intro Discrete.log_eqI) simp_all
eberlm@64449
   149
  hence "(\<Sum>k = 2^n..<2^Suc n. f (2^Discrete.log k)) = (\<Sum>(_::nat) = 2^n..<2^Suc n. f (2^n))"
nipkow@64267
   150
    by (intro sum.cong) simp_all
eberlm@62049
   151
  also have "\<dots> = 2^n * f (2^n)" by (simp add: of_nat_power)
eberlm@62049
   152
  finally show ?case by simp
eberlm@62049
   153
qed simp
eberlm@62049
   154
eberlm@64449
   155
private lemma condensation_condense2: "(\<Sum>k=1..<2^n. f (2 * 2 ^ Discrete.log k)) = (\<Sum>k<n. 2^k * f (2 ^ Suc k))"
eberlm@62049
   156
proof (induction n)
eberlm@62049
   157
  case (Suc n)
hoelzl@63594
   158
  have "{1..<2^Suc n} = {1..<2^n} \<union> {2^n..<(2^Suc n :: nat)}" by auto
eberlm@64449
   159
  also have "(\<Sum>k\<in>\<dots>. f (2 * 2 ^ Discrete.log k)) =
eberlm@64449
   160
                 (\<Sum>k<n. 2^k * f (2^Suc k)) + (\<Sum>k = 2^n..<2^Suc n. f (2 * 2^Discrete.log k))"
nipkow@64267
   161
    by (subst sum.union_disjoint) (insert Suc, auto)
eberlm@64449
   162
  also have "Discrete.log k = n" if "k \<in> {2^n..<2^Suc n}" for k using that by (intro Discrete.log_eqI) simp_all
eberlm@64449
   163
  hence "(\<Sum>k = 2^n..<2^Suc n. f (2*2^Discrete.log k)) = (\<Sum>(_::nat) = 2^n..<2^Suc n. f (2^Suc n))"
nipkow@64267
   164
    by (intro sum.cong) simp_all
eberlm@62049
   165
  also have "\<dots> = 2^n * f (2^Suc n)" by (simp add: of_nat_power)
eberlm@62049
   166
  finally show ?case by simp
eberlm@62049
   167
qed simp
eberlm@62049
   168
eberlm@62049
   169
lemma condensation_test:
eberlm@62049
   170
  assumes mono: "\<And>m. 0 < m \<Longrightarrow> f (Suc m) \<le> f m"
eberlm@62049
   171
  assumes nonneg: "\<And>n. f n \<ge> 0"
eberlm@62049
   172
  shows "summable f \<longleftrightarrow> summable (\<lambda>n. 2^n * f (2^n))"
eberlm@62049
   173
proof -
wenzelm@63040
   174
  define f' where "f' n = (if n = 0 then 0 else f n)" for n
eberlm@62049
   175
  from mono have mono': "decseq (\<lambda>n. f (Suc n))" by (intro decseq_SucI) simp
hoelzl@63594
   176
  hence mono': "f n \<le> f m" if "m \<le> n" "m > 0" for m n
eberlm@62049
   177
    using that decseqD[OF mono', of "m - 1" "n - 1"] by simp
hoelzl@63594
   178
eberlm@62049
   179
  have "(\<lambda>n. f (Suc n)) = (\<lambda>n. f' (Suc n))" by (intro ext) (simp add: f'_def)
eberlm@62049
   180
  hence "summable f \<longleftrightarrow> summable f'"
eberlm@62049
   181
    by (subst (1 2) summable_Suc_iff [symmetric]) (simp only:)
eberlm@62049
   182
  also have "\<dots> \<longleftrightarrow> convergent (\<lambda>n. \<Sum>k<n. f' k)" unfolding summable_iff_convergent ..
eberlm@62049
   183
  also have "monoseq (\<lambda>n. \<Sum>k<n. f' k)" unfolding f'_def
eberlm@62049
   184
    by (intro mono_SucI1) (auto intro!: mult_nonneg_nonneg nonneg)
eberlm@62049
   185
  hence "convergent (\<lambda>n. \<Sum>k<n. f' k) \<longleftrightarrow> Bseq (\<lambda>n. \<Sum>k<n. f' k)"
eberlm@62049
   186
    by (rule monoseq_imp_convergent_iff_Bseq)
eberlm@62049
   187
  also have "\<dots> \<longleftrightarrow> Bseq (\<lambda>n. \<Sum>k=1..<n. f' k)" unfolding One_nat_def
nipkow@64267
   188
    by (subst sum_shift_lb_Suc0_0_upt) (simp_all add: f'_def atLeast0LessThan)
eberlm@62049
   189
  also have "\<dots> \<longleftrightarrow> Bseq (\<lambda>n. \<Sum>k=1..<n. f k)" unfolding f'_def by simp
eberlm@62049
   190
  also have "\<dots> \<longleftrightarrow> Bseq (\<lambda>n. \<Sum>k=1..<2^n. f k)"
eberlm@62049
   191
    by (rule nonneg_incseq_Bseq_subseq_iff[symmetric])
nipkow@64267
   192
       (auto intro!: sum_nonneg incseq_SucI nonneg simp: subseq_def)
eberlm@62049
   193
  also have "\<dots> \<longleftrightarrow> Bseq (\<lambda>n. \<Sum>k<n. 2^k * f (2^k))"
eberlm@62049
   194
  proof (intro iffI)
eberlm@62049
   195
    assume A: "Bseq (\<lambda>n. \<Sum>k=1..<2^n. f k)"
eberlm@62049
   196
    have "eventually (\<lambda>n. norm (\<Sum>k<n. 2^k * f (2^Suc k)) \<le> norm (\<Sum>k=1..<2^n. f k)) sequentially"
eberlm@62049
   197
    proof (intro always_eventually allI)
eberlm@62049
   198
      fix n :: nat
eberlm@62049
   199
      have "norm (\<Sum>k<n. 2^k * f (2^Suc k)) = (\<Sum>k<n. 2^k * f (2^Suc k))" unfolding real_norm_def
nipkow@64267
   200
        by (intro abs_of_nonneg sum_nonneg ballI mult_nonneg_nonneg nonneg) simp_all
eberlm@62049
   201
      also have "\<dots> \<le> (\<Sum>k=1..<2^n. f k)"
eberlm@62049
   202
        by (subst condensation_condense2 [symmetric]) (intro condensation_inequality mono')
eberlm@62049
   203
      also have "\<dots> = norm \<dots>" unfolding real_norm_def
nipkow@64267
   204
        by (intro abs_of_nonneg[symmetric] sum_nonneg ballI mult_nonneg_nonneg nonneg)
eberlm@62049
   205
      finally show "norm (\<Sum>k<n. 2 ^ k * f (2 ^ Suc k)) \<le> norm (\<Sum>k=1..<2^n. f k)" .
eberlm@62049
   206
    qed
eberlm@62049
   207
    from this and A have "Bseq (\<lambda>n. \<Sum>k<n. 2^k * f (2^Suc k))" by (rule Bseq_eventually_mono)
eberlm@62049
   208
    from Bseq_mult[OF Bfun_const[of 2] this] have "Bseq (\<lambda>n. \<Sum>k<n. 2^Suc k * f (2^Suc k))"
nipkow@64267
   209
      by (simp add: sum_distrib_left sum_distrib_right mult_ac)
eberlm@62049
   210
    hence "Bseq (\<lambda>n. (\<Sum>k=Suc 0..<Suc n. 2^k * f (2^k)) + f 1)"
nipkow@64267
   211
      by (intro Bseq_add, subst sum_shift_bounds_Suc_ivl) (simp add: atLeast0LessThan)
eberlm@62049
   212
    hence "Bseq (\<lambda>n. (\<Sum>k=0..<Suc n. 2^k * f (2^k)))"
nipkow@64267
   213
      by (subst sum_head_upt_Suc) (simp_all add: add_ac)
hoelzl@63594
   214
    thus "Bseq (\<lambda>n. (\<Sum>k<n. 2^k * f (2^k)))"
eberlm@62049
   215
      by (subst (asm) Bseq_Suc_iff) (simp add: atLeast0LessThan)
eberlm@62049
   216
  next
eberlm@62049
   217
    assume A: "Bseq (\<lambda>n. (\<Sum>k<n. 2^k * f (2^k)))"
eberlm@62049
   218
    have "eventually (\<lambda>n. norm (\<Sum>k=1..<2^n. f k) \<le> norm (\<Sum>k<n. 2^k * f (2^k))) sequentially"
eberlm@62049
   219
    proof (intro always_eventually allI)
eberlm@62049
   220
      fix n :: nat
eberlm@62049
   221
      have "norm (\<Sum>k=1..<2^n. f k) = (\<Sum>k=1..<2^n. f k)" unfolding real_norm_def
nipkow@64267
   222
        by (intro abs_of_nonneg sum_nonneg ballI mult_nonneg_nonneg nonneg)
eberlm@62049
   223
      also have "\<dots> \<le> (\<Sum>k<n. 2^k * f (2^k))"
eberlm@62049
   224
        by (subst condensation_condense1 [symmetric]) (intro condensation_inequality mono')
eberlm@62049
   225
      also have "\<dots> = norm \<dots>" unfolding real_norm_def
nipkow@64267
   226
        by (intro abs_of_nonneg [symmetric] sum_nonneg ballI mult_nonneg_nonneg nonneg) simp_all
eberlm@62049
   227
      finally show "norm (\<Sum>k=1..<2^n. f k) \<le> norm (\<Sum>k<n. 2^k * f (2^k))" .
eberlm@62049
   228
    qed
eberlm@62049
   229
    from this and A show "Bseq (\<lambda>n. \<Sum>k=1..<2^n. f k)" by (rule Bseq_eventually_mono)
eberlm@62049
   230
  qed
eberlm@62049
   231
  also have "monoseq (\<lambda>n. (\<Sum>k<n. 2^k * f (2^k)))"
eberlm@62049
   232
    by (intro mono_SucI1) (auto intro!: mult_nonneg_nonneg nonneg)
eberlm@62049
   233
  hence "Bseq (\<lambda>n. (\<Sum>k<n. 2^k * f (2^k))) \<longleftrightarrow> convergent (\<lambda>n. (\<Sum>k<n. 2^k * f (2^k)))"
eberlm@62049
   234
    by (rule monoseq_imp_convergent_iff_Bseq [symmetric])
eberlm@62049
   235
  also have "\<dots> \<longleftrightarrow> summable (\<lambda>k. 2^k * f (2^k))" by (simp only: summable_iff_convergent)
eberlm@62049
   236
  finally show ?thesis .
eberlm@62049
   237
qed
eberlm@62049
   238
eberlm@62049
   239
end
eberlm@62049
   240
eberlm@62049
   241
eberlm@62085
   242
subsubsection \<open>Summability of powers\<close>
eberlm@62049
   243
hoelzl@63594
   244
lemma abs_summable_complex_powr_iff:
eberlm@62049
   245
    "summable (\<lambda>n. norm (exp (of_real (ln (of_nat n)) * s))) \<longleftrightarrow> Re s < -1"
eberlm@62049
   246
proof (cases "Re s \<le> 0")
eberlm@62049
   247
  let ?l = "\<lambda>n. complex_of_real (ln (of_nat n))"
eberlm@62049
   248
  case False
lp15@65578
   249
  have "eventually (\<lambda>n. norm (1 :: real) \<le> norm (exp (?l n * s))) sequentially"
lp15@65578
   250
    apply (rule eventually_mono [OF eventually_gt_at_top[of "0::nat"]])
lp15@65578
   251
    using False ge_one_powr_ge_zero by auto
eberlm@62049
   252
  from summable_comparison_test_ev[OF this] False show ?thesis by (auto simp: summable_const_iff)
eberlm@62049
   253
next
eberlm@62049
   254
  let ?l = "\<lambda>n. complex_of_real (ln (of_nat n))"
eberlm@62049
   255
  case True
eberlm@62049
   256
  hence "summable (\<lambda>n. norm (exp (?l n * s))) \<longleftrightarrow> summable (\<lambda>n. 2^n * norm (exp (?l (2^n) * s)))"
eberlm@62049
   257
    by (intro condensation_test) (auto intro!: mult_right_mono_neg)
eberlm@62049
   258
  also have "(\<lambda>n. 2^n * norm (exp (?l (2^n) * s))) = (\<lambda>n. (2 powr (Re s + 1)) ^ n)"
eberlm@62049
   259
  proof
eberlm@62049
   260
    fix n :: nat
eberlm@62049
   261
    have "2^n * norm (exp (?l (2^n) * s)) = exp (real n * ln 2) * exp (real n * ln 2 * Re s)"
hoelzl@63594
   262
      using True by (subst exp_of_nat_mult) (simp add: ln_realpow algebra_simps)
eberlm@62049
   263
    also have "\<dots> = exp (real n * (ln 2 * (Re s + 1)))"
eberlm@62049
   264
      by (simp add: algebra_simps exp_add)
eberlm@62049
   265
    also have "\<dots> = exp (ln 2 * (Re s + 1)) ^ n" by (subst exp_of_nat_mult) simp
eberlm@62049
   266
    also have "exp (ln 2 * (Re s + 1)) = 2 powr (Re s + 1)" by (simp add: powr_def)
eberlm@62049
   267
    finally show "2^n * norm (exp (?l (2^n) * s)) = (2 powr (Re s + 1)) ^ n" .
eberlm@62049
   268
  qed
eberlm@62049
   269
  also have "summable \<dots> \<longleftrightarrow> 2 powr (Re s + 1) < 2 powr 0"
eberlm@62049
   270
    by (subst summable_geometric_iff) simp
eberlm@62049
   271
  also have "\<dots> \<longleftrightarrow> Re s < -1" by (subst powr_less_cancel_iff) (simp, linarith)
eberlm@62049
   272
  finally show ?thesis .
eberlm@62049
   273
qed
eberlm@62049
   274
hoelzl@63594
   275
lemma summable_complex_powr_iff:
eberlm@62049
   276
  assumes "Re s < -1"
eberlm@62049
   277
  shows   "summable (\<lambda>n. exp (of_real (ln (of_nat n)) * s))"
eberlm@62049
   278
  by (rule summable_norm_cancel, subst abs_summable_complex_powr_iff) fact
eberlm@62049
   279
eberlm@62049
   280
lemma summable_real_powr_iff: "summable (\<lambda>n. of_nat n powr s :: real) \<longleftrightarrow> s < -1"
eberlm@62049
   281
proof -
eberlm@62049
   282
  from eventually_gt_at_top[of "0::nat"]
eberlm@62049
   283
    have "summable (\<lambda>n. of_nat n powr s) \<longleftrightarrow> summable (\<lambda>n. exp (ln (of_nat n) * s))"
eberlm@62049
   284
    by (intro summable_cong) (auto elim!: eventually_mono simp: powr_def)
eberlm@62049
   285
  also have "\<dots> \<longleftrightarrow> s < -1" using abs_summable_complex_powr_iff[of "of_real s"] by simp
eberlm@62049
   286
  finally show ?thesis .
eberlm@62049
   287
qed
eberlm@62049
   288
eberlm@62049
   289
lemma inverse_power_summable:
eberlm@62049
   290
  assumes s: "s \<ge> 2"
eberlm@62049
   291
  shows "summable (\<lambda>n. inverse (of_nat n ^ s :: 'a :: {real_normed_div_algebra,banach}))"
eberlm@62049
   292
proof (rule summable_norm_cancel, subst summable_cong)
eberlm@62049
   293
  from eventually_gt_at_top[of "0::nat"]
eberlm@62049
   294
    show "eventually (\<lambda>n. norm (inverse (of_nat n ^ s:: 'a)) = real_of_nat n powr (-real s)) at_top"
eberlm@62049
   295
    by eventually_elim (simp add: norm_inverse norm_power powr_minus powr_realpow)
eberlm@62049
   296
qed (insert s summable_real_powr_iff[of "-s"], simp_all)
eberlm@62049
   297
eberlm@62049
   298
lemma not_summable_harmonic: "\<not>summable (\<lambda>n. inverse (of_nat n) :: 'a :: real_normed_field)"
eberlm@62049
   299
proof
eberlm@62049
   300
  assume "summable (\<lambda>n. inverse (of_nat n) :: 'a)"
hoelzl@63594
   301
  hence "convergent (\<lambda>n. norm (of_real (\<Sum>k<n. inverse (of_nat k)) :: 'a))"
eberlm@62049
   302
    by (simp add: summable_iff_convergent convergent_norm)
eberlm@62049
   303
  hence "convergent (\<lambda>n. abs (\<Sum>k<n. inverse (of_nat k)) :: real)" by (simp only: norm_of_real)
eberlm@62049
   304
  also have "(\<lambda>n. abs (\<Sum>k<n. inverse (of_nat k)) :: real) = (\<lambda>n. \<Sum>k<n. inverse (of_nat k))"
nipkow@64267
   305
    by (intro ext abs_of_nonneg sum_nonneg) auto
eberlm@62049
   306
  also have "convergent \<dots> \<longleftrightarrow> summable (\<lambda>k. inverse (of_nat k) :: real)"
eberlm@62049
   307
    by (simp add: summable_iff_convergent)
eberlm@62049
   308
  finally show False using summable_real_powr_iff[of "-1"] by (simp add: powr_minus)
eberlm@62049
   309
qed
eberlm@62049
   310
eberlm@62049
   311
eberlm@62085
   312
subsubsection \<open>Kummer's test\<close>
eberlm@62049
   313
eberlm@62049
   314
lemma kummers_test_convergence:
eberlm@62049
   315
  fixes f p :: "nat \<Rightarrow> real"
hoelzl@63594
   316
  assumes pos_f: "eventually (\<lambda>n. f n > 0) sequentially"
eberlm@62049
   317
  assumes nonneg_p: "eventually (\<lambda>n. p n \<ge> 0) sequentially"
eberlm@62049
   318
  defines "l \<equiv> liminf (\<lambda>n. ereal (p n * f n / f (Suc n) - p (Suc n)))"
eberlm@62049
   319
  assumes l: "l > 0"
eberlm@62049
   320
  shows   "summable f"
eberlm@62049
   321
  unfolding summable_iff_convergent'
eberlm@62049
   322
proof -
wenzelm@63040
   323
  define r where "r = (if l = \<infinity> then 1 else real_of_ereal l / 2)"
eberlm@62049
   324
  from l have "r > 0 \<and> of_real r < l" by (cases l) (simp_all add: r_def)
eberlm@62049
   325
  hence r: "r > 0" "of_real r < l" by simp_all
eberlm@62049
   326
  hence "eventually (\<lambda>n. p n * f n / f (Suc n) - p (Suc n) > r) sequentially"
eberlm@62049
   327
    unfolding l_def by (force dest: less_LiminfD)
hoelzl@63594
   328
  moreover from pos_f have "eventually (\<lambda>n. f (Suc n) > 0) sequentially"
eberlm@62049
   329
    by (subst eventually_sequentially_Suc)
eberlm@62049
   330
  ultimately have "eventually (\<lambda>n. p n * f n - p (Suc n) * f (Suc n) > r * f (Suc n)) sequentially"
eberlm@62049
   331
    by eventually_elim (simp add: field_simps)
eberlm@62049
   332
  from eventually_conj[OF pos_f eventually_conj[OF nonneg_p this]]
eberlm@62049
   333
    obtain m where m: "\<And>n. n \<ge> m \<Longrightarrow> f n > 0" "\<And>n. n \<ge> m \<Longrightarrow> p n \<ge> 0"
eberlm@62049
   334
        "\<And>n. n \<ge> m \<Longrightarrow> p n * f n - p (Suc n) * f (Suc n) > r * f (Suc n)"
eberlm@62049
   335
    unfolding eventually_at_top_linorder by blast
eberlm@62049
   336
eberlm@62049
   337
  let ?c = "(norm (\<Sum>k\<le>m. r * f k) + p m * f m) / r"
eberlm@62049
   338
  have "Bseq (\<lambda>n. (\<Sum>k\<le>n + Suc m. f k))"
eberlm@62049
   339
  proof (rule BseqI')
eberlm@62049
   340
    fix k :: nat
wenzelm@63040
   341
    define n where "n = k + Suc m"
eberlm@62049
   342
    have n: "n > m" by (simp add: n_def)
eberlm@62049
   343
eberlm@62049
   344
    from r have "r * norm (\<Sum>k\<le>n. f k) = norm (\<Sum>k\<le>n. r * f k)"
nipkow@64267
   345
      by (simp add: sum_distrib_left[symmetric] abs_mult)
eberlm@62049
   346
    also from n have "{..n} = {..m} \<union> {Suc m..n}" by auto
eberlm@62049
   347
    hence "(\<Sum>k\<le>n. r * f k) = (\<Sum>k\<in>{..m} \<union> {Suc m..n}. r * f k)" by (simp only:)
eberlm@62049
   348
    also have "\<dots> = (\<Sum>k\<le>m. r * f k) + (\<Sum>k=Suc m..n. r * f k)"
nipkow@64267
   349
      by (subst sum.union_disjoint) auto
eberlm@62049
   350
    also have "norm \<dots> \<le> norm (\<Sum>k\<le>m. r * f k) + norm (\<Sum>k=Suc m..n. r * f k)"
eberlm@62049
   351
      by (rule norm_triangle_ineq)
hoelzl@63594
   352
    also from r less_imp_le[OF m(1)] have "(\<Sum>k=Suc m..n. r * f k) \<ge> 0"
nipkow@64267
   353
      by (intro sum_nonneg) auto
eberlm@62049
   354
    hence "norm (\<Sum>k=Suc m..n. r * f k) = (\<Sum>k=Suc m..n. r * f k)" by simp
eberlm@62049
   355
    also have "(\<Sum>k=Suc m..n. r * f k) = (\<Sum>k=m..<n. r * f (Suc k))"
nipkow@64267
   356
     by (subst sum_shift_bounds_Suc_ivl [symmetric])
eberlm@62049
   357
          (simp only: atLeastLessThanSuc_atLeastAtMost)
eberlm@62049
   358
    also from m have "\<dots> \<le> (\<Sum>k=m..<n. p k * f k - p (Suc k) * f (Suc k))"
nipkow@64267
   359
      by (intro sum_mono[OF less_imp_le]) simp_all
eberlm@62049
   360
    also have "\<dots> = -(\<Sum>k=m..<n. p (Suc k) * f (Suc k) - p k * f k)"
nipkow@64267
   361
      by (simp add: sum_negf [symmetric] algebra_simps)
eberlm@62049
   362
    also from n have "\<dots> = p m * f m - p n * f n"
nipkow@64267
   363
      by (cases n, simp, simp only: atLeastLessThanSuc_atLeastAtMost, subst sum_Suc_diff) simp_all
eberlm@62049
   364
    also from less_imp_le[OF m(1)] m(2) n have "\<dots> \<le> p m * f m" by simp
eberlm@62049
   365
    finally show "norm (\<Sum>k\<le>n. f k) \<le> (norm (\<Sum>k\<le>m. r * f k) + p m * f m) / r" using r
eberlm@62049
   366
      by (subst pos_le_divide_eq[OF r(1)]) (simp only: mult_ac)
eberlm@62049
   367
  qed
eberlm@62049
   368
  moreover have "(\<Sum>k\<le>n. f k) \<le> (\<Sum>k\<le>n'. f k)" if "Suc m \<le> n" "n \<le> n'" for n n'
nipkow@64267
   369
    using less_imp_le[OF m(1)] that by (intro sum_mono2) auto
eberlm@62049
   370
  ultimately show "convergent (\<lambda>n. \<Sum>k\<le>n. f k)" by (rule Bseq_monoseq_convergent'_inc)
eberlm@62049
   371
qed
eberlm@62049
   372
eberlm@62049
   373
eberlm@62049
   374
lemma kummers_test_divergence:
eberlm@62049
   375
  fixes f p :: "nat \<Rightarrow> real"
hoelzl@63594
   376
  assumes pos_f: "eventually (\<lambda>n. f n > 0) sequentially"
eberlm@62049
   377
  assumes pos_p: "eventually (\<lambda>n. p n > 0) sequentially"
eberlm@62049
   378
  assumes divergent_p: "\<not>summable (\<lambda>n. inverse (p n))"
eberlm@62049
   379
  defines "l \<equiv> limsup (\<lambda>n. ereal (p n * f n / f (Suc n) - p (Suc n)))"
eberlm@62049
   380
  assumes l: "l < 0"
eberlm@62049
   381
  shows   "\<not>summable f"
eberlm@62049
   382
proof
eberlm@62049
   383
  assume "summable f"
eberlm@62049
   384
  from eventually_conj[OF pos_f eventually_conj[OF pos_p Limsup_lessD[OF l[unfolded l_def]]]]
eberlm@62049
   385
    obtain N where N: "\<And>n. n \<ge> N \<Longrightarrow> p n > 0" "\<And>n. n \<ge> N \<Longrightarrow> f n > 0"
eberlm@62049
   386
                      "\<And>n. n \<ge> N \<Longrightarrow> p n * f n / f (Suc n) - p (Suc n) < 0"
eberlm@62049
   387
    by (auto simp: eventually_at_top_linorder)
hoelzl@63594
   388
  hence A: "p n * f n < p (Suc n) * f (Suc n)" if "n \<ge> N" for n using that N[of n] N[of "Suc n"]
eberlm@62049
   389
    by (simp add: field_simps)
lp15@65578
   390
  have B: "p n * f n \<ge> p N * f N" if "n \<ge> N" for n using that and A
lp15@65578
   391
    by (induction n rule: dec_induct) (auto intro!: less_imp_le elim!: order.trans)
lp15@65578
   392
  have "eventually (\<lambda>n. norm (p N * f N * inverse (p n)) \<le> f n) sequentially"
lp15@65578
   393
    apply (rule eventually_mono [OF eventually_ge_at_top[of N]])
lp15@65578
   394
    using B N  by (auto  simp: field_simps abs_of_pos)
eberlm@62049
   395
  from this and \<open>summable f\<close> have "summable (\<lambda>n. p N * f N * inverse (p n))"
eberlm@62049
   396
    by (rule summable_comparison_test_ev)
hoelzl@63594
   397
  from summable_mult[OF this, of "inverse (p N * f N)"] N[OF le_refl]
eberlm@62049
   398
    have "summable (\<lambda>n. inverse (p n))" by (simp add: divide_simps)
eberlm@62049
   399
  with divergent_p show False by contradiction
eberlm@62049
   400
qed
eberlm@62049
   401
eberlm@62049
   402
eberlm@62085
   403
subsubsection \<open>Ratio test\<close>
eberlm@62049
   404
eberlm@62049
   405
lemma ratio_test_convergence:
eberlm@62049
   406
  fixes f :: "nat \<Rightarrow> real"
hoelzl@63594
   407
  assumes pos_f: "eventually (\<lambda>n. f n > 0) sequentially"
eberlm@62049
   408
  defines "l \<equiv> liminf (\<lambda>n. ereal (f n / f (Suc n)))"
eberlm@62049
   409
  assumes l: "l > 1"
eberlm@62049
   410
  shows   "summable f"
eberlm@62049
   411
proof (rule kummers_test_convergence[OF pos_f])
eberlm@62049
   412
  note l
hoelzl@63594
   413
  also have "l = liminf (\<lambda>n. ereal (f n / f (Suc n) - 1)) + 1"
eberlm@62049
   414
    by (subst Liminf_add_ereal_right[symmetric]) (simp_all add: minus_ereal_def l_def one_ereal_def)
eberlm@62049
   415
  finally show "liminf (\<lambda>n. ereal (1 * f n / f (Suc n) - 1)) > 0"
eberlm@62049
   416
    by (cases "liminf (\<lambda>n. ereal (1 * f n / f (Suc n) - 1))") simp_all
eberlm@62049
   417
qed simp
eberlm@62049
   418
eberlm@62049
   419
lemma ratio_test_divergence:
eberlm@62049
   420
  fixes f :: "nat \<Rightarrow> real"
hoelzl@63594
   421
  assumes pos_f: "eventually (\<lambda>n. f n > 0) sequentially"
eberlm@62049
   422
  defines "l \<equiv> limsup (\<lambda>n. ereal (f n / f (Suc n)))"
eberlm@62049
   423
  assumes l: "l < 1"
eberlm@62049
   424
  shows   "\<not>summable f"
eberlm@62049
   425
proof (rule kummers_test_divergence[OF pos_f])
hoelzl@63594
   426
  have "limsup (\<lambda>n. ereal (f n / f (Suc n) - 1)) + 1 = l"
eberlm@62049
   427
    by (subst Limsup_add_ereal_right[symmetric]) (simp_all add: minus_ereal_def l_def one_ereal_def)
eberlm@62049
   428
  also note l
eberlm@62049
   429
  finally show "limsup (\<lambda>n. ereal (1 * f n / f (Suc n) - 1)) < 0"
eberlm@62049
   430
    by (cases "limsup (\<lambda>n. ereal (1 * f n / f (Suc n) - 1))") simp_all
eberlm@62049
   431
qed (simp_all add: summable_const_iff)
eberlm@62049
   432
eberlm@62049
   433
eberlm@62085
   434
subsubsection \<open>Raabe's test\<close>
eberlm@62049
   435
eberlm@62049
   436
lemma raabes_test_convergence:
eberlm@62049
   437
fixes f :: "nat \<Rightarrow> real"
eberlm@62049
   438
  assumes pos: "eventually (\<lambda>n. f n > 0) sequentially"
eberlm@62049
   439
  defines "l \<equiv> liminf (\<lambda>n. ereal (of_nat n * (f n / f (Suc n) - 1)))"
eberlm@62049
   440
  assumes l: "l > 1"
eberlm@62049
   441
  shows   "summable f"
eberlm@62049
   442
proof (rule kummers_test_convergence)
eberlm@62049
   443
  let ?l' = "liminf (\<lambda>n. ereal (of_nat n * f n / f (Suc n) - of_nat (Suc n)))"
eberlm@62049
   444
  have "1 < l" by fact
eberlm@62049
   445
  also have "l = liminf (\<lambda>n. ereal (of_nat n * f n / f (Suc n) - of_nat (Suc n)) + 1)"
eberlm@62049
   446
    by (simp add: l_def algebra_simps)
eberlm@62049
   447
  also have "\<dots> = ?l' + 1" by (subst Liminf_add_ereal_right) simp_all
eberlm@62049
   448
  finally show "?l' > 0" by (cases ?l') (simp_all add: algebra_simps)
eberlm@62049
   449
qed (simp_all add: pos)
eberlm@62049
   450
eberlm@62049
   451
lemma raabes_test_divergence:
eberlm@62049
   452
fixes f :: "nat \<Rightarrow> real"
eberlm@62049
   453
  assumes pos: "eventually (\<lambda>n. f n > 0) sequentially"
eberlm@62049
   454
  defines "l \<equiv> limsup (\<lambda>n. ereal (of_nat n * (f n / f (Suc n) - 1)))"
eberlm@62049
   455
  assumes l: "l < 1"
eberlm@62049
   456
  shows   "\<not>summable f"
eberlm@62049
   457
proof (rule kummers_test_divergence)
eberlm@62049
   458
  let ?l' = "limsup (\<lambda>n. ereal (of_nat n * f n / f (Suc n) - of_nat (Suc n)))"
eberlm@62049
   459
  note l
eberlm@62049
   460
  also have "l = limsup (\<lambda>n. ereal (of_nat n * f n / f (Suc n) - of_nat (Suc n)) + 1)"
eberlm@62049
   461
    by (simp add: l_def algebra_simps)
eberlm@62049
   462
  also have "\<dots> = ?l' + 1" by (subst Limsup_add_ereal_right) simp_all
eberlm@62049
   463
  finally show "?l' < 0" by (cases ?l') (simp_all add: algebra_simps)
eberlm@62049
   464
qed (insert pos eventually_gt_at_top[of "0::nat"] not_summable_harmonic, simp_all)
eberlm@62049
   465
eberlm@62049
   466
eberlm@62049
   467
eberlm@62049
   468
subsection \<open>Radius of convergence\<close>
eberlm@62049
   469
eberlm@62049
   470
text \<open>
eberlm@62049
   471
  The radius of convergence of a power series. This value always exists, ranges from
hoelzl@63594
   472
  @{term "0::ereal"} to @{term "\<infinity>::ereal"}, and the power series is guaranteed to converge for
eberlm@62049
   473
  all inputs with a norm that is smaller than that radius and to diverge for all inputs with a
hoelzl@63594
   474
  norm that is greater.
eberlm@62049
   475
\<close>
eberlm@62049
   476
definition conv_radius :: "(nat \<Rightarrow> 'a :: banach) \<Rightarrow> ereal" where
eberlm@62049
   477
  "conv_radius f = inverse (limsup (\<lambda>n. ereal (root n (norm (f n)))))"
eberlm@62049
   478
eberlm@62049
   479
lemma conv_radius_nonneg: "conv_radius f \<ge> 0"
eberlm@62049
   480
proof -
eberlm@62049
   481
  have "0 = limsup (\<lambda>n. 0)" by (subst Limsup_const) simp_all
eberlm@62049
   482
  also have "\<dots> \<le> limsup (\<lambda>n. ereal (root n (norm (f n))))"
eberlm@62049
   483
    by (intro Limsup_mono) (simp_all add: real_root_ge_zero)
eberlm@62049
   484
  finally show ?thesis
eberlm@62049
   485
    unfolding conv_radius_def by (auto simp: ereal_inverse_nonneg_iff)
eberlm@62049
   486
qed
eberlm@62049
   487
eberlm@62049
   488
lemma conv_radius_zero [simp]: "conv_radius (\<lambda>_. 0) = \<infinity>"
eberlm@62049
   489
  by (auto simp: conv_radius_def zero_ereal_def [symmetric] Limsup_const)
eberlm@62049
   490
eberlm@62049
   491
lemma conv_radius_cong:
eberlm@62049
   492
  assumes "eventually (\<lambda>x. f x = g x) sequentially"
eberlm@62049
   493
  shows   "conv_radius f = conv_radius g"
eberlm@62049
   494
proof -
eberlm@62049
   495
  have "eventually (\<lambda>n. ereal (root n (norm (f n))) = ereal (root n (norm (g n)))) sequentially"
eberlm@62049
   496
    using assms by eventually_elim simp
eberlm@62049
   497
  from Limsup_eq[OF this] show ?thesis unfolding conv_radius_def by simp
eberlm@62049
   498
qed
eberlm@62049
   499
eberlm@62049
   500
lemma conv_radius_altdef:
eberlm@62049
   501
  "conv_radius f = liminf (\<lambda>n. inverse (ereal (root n (norm (f n)))))"
eberlm@62049
   502
  by (subst Liminf_inverse_ereal) (simp_all add: real_root_ge_zero conv_radius_def)
eberlm@62049
   503
eberlm@62049
   504
lemma abs_summable_in_conv_radius:
eberlm@62049
   505
  fixes f :: "nat \<Rightarrow> 'a :: {banach, real_normed_div_algebra}"
eberlm@62049
   506
  assumes "ereal (norm z) < conv_radius f"
eberlm@62049
   507
  shows   "summable (\<lambda>n. norm (f n * z ^ n))"
eberlm@62049
   508
proof (rule root_test_convergence')
wenzelm@63040
   509
  define l where "l = limsup (\<lambda>n. ereal (root n (norm (f n))))"
eberlm@62049
   510
  have "0 = limsup (\<lambda>n. 0)" by (simp add: Limsup_const)
eberlm@62049
   511
  also have "... \<le> l" unfolding l_def by (intro Limsup_mono) (simp_all add: real_root_ge_zero)
eberlm@62049
   512
  finally have l_nonneg: "l \<ge> 0" .
eberlm@62049
   513
eberlm@62049
   514
  have "limsup (\<lambda>n. root n (norm (f n * z^n))) = l * ereal (norm z)" unfolding l_def
eberlm@62049
   515
    by (rule limsup_root_powser)
eberlm@62049
   516
  also from l_nonneg consider "l = 0" | "l = \<infinity>" | "\<exists>l'. l = ereal l' \<and> l' > 0"
eberlm@62049
   517
    by (cases "l") (auto simp: less_le)
eberlm@62049
   518
  hence "l * ereal (norm z) < 1"
eberlm@62049
   519
  proof cases
eberlm@62049
   520
    assume "l = \<infinity>"
eberlm@62049
   521
    hence "conv_radius f = 0" unfolding conv_radius_def l_def by simp
eberlm@62049
   522
    with assms show ?thesis by simp
eberlm@62049
   523
  next
eberlm@62049
   524
    assume "\<exists>l'. l = ereal l' \<and> l' > 0"
eberlm@62049
   525
    then guess l' by (elim exE conjE) note l' = this
eberlm@62049
   526
    hence "l \<noteq> \<infinity>" by auto
eberlm@62049
   527
    have "l * ereal (norm z) < l * conv_radius f"
eberlm@62049
   528
      by (intro ereal_mult_strict_left_mono) (simp_all add: l' assms)
eberlm@62049
   529
    also have "conv_radius f = inverse l" by (simp add: conv_radius_def l_def)
eberlm@62049
   530
    also from l' have "l * inverse l = 1" by simp
eberlm@62049
   531
    finally show ?thesis .
eberlm@62049
   532
  qed simp_all
eberlm@62049
   533
  finally show "limsup (\<lambda>n. ereal (root n (norm (norm (f n * z ^ n))))) < 1" by simp
eberlm@62049
   534
qed
eberlm@62049
   535
eberlm@62049
   536
lemma summable_in_conv_radius:
eberlm@62049
   537
  fixes f :: "nat \<Rightarrow> 'a :: {banach, real_normed_div_algebra}"
eberlm@62049
   538
  assumes "ereal (norm z) < conv_radius f"
eberlm@62049
   539
  shows   "summable (\<lambda>n. f n * z ^ n)"
eberlm@62049
   540
  by (rule summable_norm_cancel, rule abs_summable_in_conv_radius) fact+
eberlm@62049
   541
eberlm@62049
   542
lemma not_summable_outside_conv_radius:
eberlm@62049
   543
  fixes f :: "nat \<Rightarrow> 'a :: {banach, real_normed_div_algebra}"
eberlm@62049
   544
  assumes "ereal (norm z) > conv_radius f"
eberlm@62049
   545
  shows   "\<not>summable (\<lambda>n. f n * z ^ n)"
eberlm@62049
   546
proof (rule root_test_divergence)
wenzelm@63040
   547
  define l where "l = limsup (\<lambda>n. ereal (root n (norm (f n))))"
eberlm@62049
   548
  have "0 = limsup (\<lambda>n. 0)" by (simp add: Limsup_const)
eberlm@62049
   549
  also have "... \<le> l" unfolding l_def by (intro Limsup_mono) (simp_all add: real_root_ge_zero)
eberlm@62049
   550
  finally have l_nonneg: "l \<ge> 0" .
eberlm@62049
   551
  from assms have l_nz: "l \<noteq> 0" unfolding conv_radius_def l_def by auto
eberlm@62049
   552
eberlm@62049
   553
  have "limsup (\<lambda>n. ereal (root n (norm (f n * z^n)))) = l * ereal (norm z)"
eberlm@62049
   554
    unfolding l_def by (rule limsup_root_powser)
eberlm@62049
   555
  also have "... > 1"
eberlm@62049
   556
  proof (cases l)
eberlm@62049
   557
    assume "l = \<infinity>"
eberlm@62049
   558
    with assms conv_radius_nonneg[of f] show ?thesis
eberlm@62049
   559
      by (auto simp: zero_ereal_def[symmetric])
eberlm@62049
   560
  next
eberlm@62049
   561
    fix l' assume l': "l = ereal l'"
eberlm@62049
   562
    from l_nonneg l_nz have "1 = l * inverse l" by (auto simp: l' field_simps)
hoelzl@63594
   563
    also from l_nz have "inverse l = conv_radius f"
eberlm@62049
   564
      unfolding l_def conv_radius_def by auto
eberlm@62049
   565
    also from l' l_nz l_nonneg assms have "l * \<dots> < l * ereal (norm z)"
eberlm@62049
   566
      by (intro ereal_mult_strict_left_mono) (auto simp: l')
eberlm@62049
   567
    finally show ?thesis .
eberlm@62049
   568
  qed (insert l_nonneg, simp_all)
eberlm@62049
   569
  finally show "limsup (\<lambda>n. ereal (root n (norm (f n * z^n)))) > 1" .
eberlm@62049
   570
qed
eberlm@62049
   571
eberlm@62049
   572
eberlm@62049
   573
lemma conv_radius_geI:
eberlm@62049
   574
  assumes "summable (\<lambda>n. f n * z ^ n :: 'a :: {banach, real_normed_div_algebra})"
eberlm@62049
   575
  shows   "conv_radius f \<ge> norm z"
eberlm@62049
   576
  using not_summable_outside_conv_radius[of f z] assms by (force simp: not_le[symmetric])
eberlm@62049
   577
eberlm@62049
   578
lemma conv_radius_leI:
eberlm@62049
   579
  assumes "\<not>summable (\<lambda>n. norm (f n * z ^ n :: 'a :: {banach, real_normed_div_algebra}))"
eberlm@62049
   580
  shows   "conv_radius f \<le> norm z"
eberlm@62049
   581
  using abs_summable_in_conv_radius[of z f] assms by (force simp: not_le[symmetric])
eberlm@62049
   582
eberlm@62049
   583
lemma conv_radius_leI':
eberlm@62049
   584
  assumes "\<not>summable (\<lambda>n. f n * z ^ n :: 'a :: {banach, real_normed_div_algebra})"
eberlm@62049
   585
  shows   "conv_radius f \<le> norm z"
eberlm@62049
   586
  using summable_in_conv_radius[of z f] assms by (force simp: not_le[symmetric])
eberlm@62049
   587
eberlm@62049
   588
lemma conv_radius_geI_ex:
eberlm@62049
   589
  fixes f :: "nat \<Rightarrow> 'a :: {banach, real_normed_div_algebra}"
eberlm@62049
   590
  assumes "\<And>r. 0 < r \<Longrightarrow> ereal r < R \<Longrightarrow> \<exists>z. norm z = r \<and> summable (\<lambda>n. f n * z^n)"
eberlm@62049
   591
  shows   "conv_radius f \<ge> R"
eberlm@62049
   592
proof (rule linorder_cases[of "conv_radius f" R])
eberlm@62049
   593
  assume R: "conv_radius f < R"
hoelzl@63594
   594
  with conv_radius_nonneg[of f] obtain conv_radius'
eberlm@62049
   595
    where [simp]: "conv_radius f = ereal conv_radius'"
eberlm@62049
   596
    by (cases "conv_radius f") simp_all
wenzelm@63040
   597
  define r where "r = (if R = \<infinity> then conv_radius' + 1 else (real_of_ereal R + conv_radius') / 2)"
hoelzl@63594
   598
  from R conv_radius_nonneg[of f] have "0 < r \<and> ereal r < R \<and> ereal r > conv_radius f"
eberlm@62049
   599
    unfolding r_def by (cases R) (auto simp: r_def field_simps)
eberlm@62049
   600
  with assms(1)[of r] obtain z where "norm z > conv_radius f" "summable (\<lambda>n. f n * z^n)" by auto
eberlm@62049
   601
  with not_summable_outside_conv_radius[of f z] show ?thesis by simp
eberlm@62049
   602
qed simp_all
eberlm@62049
   603
eberlm@62049
   604
lemma conv_radius_geI_ex':
eberlm@62049
   605
  fixes f :: "nat \<Rightarrow> 'a :: {banach, real_normed_div_algebra}"
eberlm@62049
   606
  assumes "\<And>r. 0 < r \<Longrightarrow> ereal r < R \<Longrightarrow> summable (\<lambda>n. f n * of_real r^n)"
eberlm@62049
   607
  shows   "conv_radius f \<ge> R"
eberlm@62049
   608
proof (rule conv_radius_geI_ex)
eberlm@62049
   609
  fix r assume "0 < r" "ereal r < R"
eberlm@62049
   610
  with assms[of r] show "\<exists>z. norm z = r \<and> summable (\<lambda>n. f n * z ^ n)"
eberlm@62049
   611
    by (intro exI[of _ "of_real r :: 'a"]) auto
eberlm@62049
   612
qed
eberlm@62049
   613
eberlm@62049
   614
lemma conv_radius_leI_ex:
eberlm@62049
   615
  fixes f :: "nat \<Rightarrow> 'a :: {banach, real_normed_div_algebra}"
eberlm@62049
   616
  assumes "R \<ge> 0"
eberlm@62049
   617
  assumes "\<And>r. 0 < r \<Longrightarrow> ereal r > R \<Longrightarrow> \<exists>z. norm z = r \<and> \<not>summable (\<lambda>n. norm (f n * z^n))"
eberlm@62049
   618
  shows   "conv_radius f \<le> R"
eberlm@62049
   619
proof (rule linorder_cases[of "conv_radius f" R])
eberlm@62049
   620
  assume R: "conv_radius f > R"
eberlm@62049
   621
  from R assms(1) obtain R' where R': "R = ereal R'" by (cases R) simp_all
wenzelm@63040
   622
  define r where
wenzelm@63040
   623
    "r = (if conv_radius f = \<infinity> then R' + 1 else (R' + real_of_ereal (conv_radius f)) / 2)"
eberlm@62049
   624
  from R conv_radius_nonneg[of f] have "r > R \<and> r < conv_radius f" unfolding r_def
eberlm@62049
   625
    by (cases "conv_radius f") (auto simp: r_def field_simps R')
hoelzl@63594
   626
  with assms(1) assms(2)[of r] R'
eberlm@62049
   627
    obtain z where "norm z < conv_radius f" "\<not>summable (\<lambda>n. norm (f n * z^n))" by auto
eberlm@62049
   628
  with abs_summable_in_conv_radius[of z f] show ?thesis by auto
eberlm@62049
   629
qed simp_all
eberlm@62049
   630
eberlm@62049
   631
lemma conv_radius_leI_ex':
eberlm@62049
   632
  fixes f :: "nat \<Rightarrow> 'a :: {banach, real_normed_div_algebra}"
eberlm@62049
   633
  assumes "R \<ge> 0"
eberlm@62049
   634
  assumes "\<And>r. 0 < r \<Longrightarrow> ereal r > R \<Longrightarrow> \<not>summable (\<lambda>n. f n * of_real r^n)"
eberlm@62049
   635
  shows   "conv_radius f \<le> R"
eberlm@62049
   636
proof (rule conv_radius_leI_ex)
eberlm@62049
   637
  fix r assume "0 < r" "ereal r > R"
eberlm@62049
   638
  with assms(2)[of r] show "\<exists>z. norm z = r \<and> \<not>summable (\<lambda>n. norm (f n * z ^ n))"
eberlm@62049
   639
    by (intro exI[of _ "of_real r :: 'a"]) (auto dest: summable_norm_cancel)
eberlm@62049
   640
qed fact+
eberlm@62049
   641
eberlm@62049
   642
lemma conv_radius_eqI:
eberlm@62049
   643
  fixes f :: "nat \<Rightarrow> 'a :: {banach, real_normed_div_algebra}"
eberlm@62049
   644
  assumes "R \<ge> 0"
eberlm@62049
   645
  assumes "\<And>r. 0 < r \<Longrightarrow> ereal r < R \<Longrightarrow> \<exists>z. norm z = r \<and> summable (\<lambda>n. f n * z^n)"
eberlm@62049
   646
  assumes "\<And>r. 0 < r \<Longrightarrow> ereal r > R \<Longrightarrow> \<exists>z. norm z = r \<and> \<not>summable (\<lambda>n. norm (f n * z^n))"
eberlm@62049
   647
  shows   "conv_radius f = R"
eberlm@62049
   648
  by (intro antisym conv_radius_geI_ex conv_radius_leI_ex assms)
eberlm@62049
   649
eberlm@62049
   650
lemma conv_radius_eqI':
eberlm@62049
   651
  fixes f :: "nat \<Rightarrow> 'a :: {banach, real_normed_div_algebra}"
eberlm@62049
   652
  assumes "R \<ge> 0"
eberlm@62049
   653
  assumes "\<And>r. 0 < r \<Longrightarrow> ereal r < R \<Longrightarrow> summable (\<lambda>n. f n * (of_real r)^n)"
eberlm@62049
   654
  assumes "\<And>r. 0 < r \<Longrightarrow> ereal r > R \<Longrightarrow> \<not>summable (\<lambda>n. norm (f n * (of_real r)^n))"
eberlm@62049
   655
  shows   "conv_radius f = R"
eberlm@62049
   656
proof (intro conv_radius_eqI[OF assms(1)])
hoelzl@63594
   657
  fix r assume "0 < r" "ereal r < R" with assms(2)[OF this]
eberlm@62049
   658
    show "\<exists>z. norm z = r \<and> summable (\<lambda>n. f n * z ^ n)" by force
eberlm@62049
   659
next
hoelzl@63594
   660
  fix r assume "0 < r" "ereal r > R" with assms(3)[OF this]
hoelzl@63594
   661
    show "\<exists>z. norm z = r \<and> \<not>summable (\<lambda>n. norm (f n * z ^ n))" by force
eberlm@62049
   662
qed
eberlm@62049
   663
eberlm@62049
   664
lemma conv_radius_zeroI:
eberlm@62049
   665
  fixes f :: "nat \<Rightarrow> 'a :: {banach,real_normed_div_algebra}"
eberlm@62049
   666
  assumes "\<And>z. z \<noteq> 0 \<Longrightarrow> \<not>summable (\<lambda>n. f n * z^n)"
eberlm@62049
   667
  shows   "conv_radius f = 0"
eberlm@62049
   668
proof (rule ccontr)
eberlm@62049
   669
  assume "conv_radius f \<noteq> 0"
eberlm@62049
   670
  with conv_radius_nonneg[of f] have pos: "conv_radius f > 0" by simp
wenzelm@63040
   671
  define r where "r = (if conv_radius f = \<infinity> then 1 else real_of_ereal (conv_radius f) / 2)"
hoelzl@63594
   672
  from pos have r: "ereal r > 0 \<and> ereal r < conv_radius f"
eberlm@62049
   673
    by (cases "conv_radius f") (simp_all add: r_def)
eberlm@62049
   674
  hence "summable (\<lambda>n. f n * of_real r ^ n)" by (intro summable_in_conv_radius) simp
eberlm@62049
   675
  moreover from r and assms[of "of_real r"] have "\<not>summable (\<lambda>n. f n * of_real r ^ n)" by simp
eberlm@62049
   676
  ultimately show False by contradiction
eberlm@62049
   677
qed
eberlm@62049
   678
eberlm@62049
   679
lemma conv_radius_inftyI':
eberlm@62049
   680
  fixes f :: "nat \<Rightarrow> 'a :: {banach,real_normed_div_algebra}"
eberlm@62049
   681
  assumes "\<And>r. r > c \<Longrightarrow> \<exists>z. norm z = r \<and> summable (\<lambda>n. f n * z^n)"
eberlm@62049
   682
  shows   "conv_radius f = \<infinity>"
eberlm@62049
   683
proof -
eberlm@62049
   684
  {
eberlm@62049
   685
    fix r :: real
eberlm@62049
   686
    have "max r (c + 1) > c" by (auto simp: max_def)
eberlm@62049
   687
    from assms[OF this] obtain z where "norm z = max r (c + 1)" "summable (\<lambda>n. f n * z^n)" by blast
eberlm@62049
   688
    from conv_radius_geI[OF this(2)] this(1) have "conv_radius f \<ge> r" by simp
eberlm@62049
   689
  }
eberlm@62049
   690
  from this[of "real_of_ereal (conv_radius f + 1)"] show "conv_radius f = \<infinity>"
eberlm@62049
   691
    by (cases "conv_radius f") simp_all
eberlm@62049
   692
qed
eberlm@62049
   693
eberlm@62049
   694
lemma conv_radius_inftyI:
eberlm@62049
   695
  fixes f :: "nat \<Rightarrow> 'a :: {banach,real_normed_div_algebra}"
eberlm@62049
   696
  assumes "\<And>r. \<exists>z. norm z = r \<and> summable (\<lambda>n. f n * z^n)"
eberlm@62049
   697
  shows   "conv_radius f = \<infinity>"
eberlm@62049
   698
  using assms by (rule conv_radius_inftyI')
eberlm@62049
   699
eberlm@62049
   700
lemma conv_radius_inftyI'':
eberlm@62049
   701
  fixes f :: "nat \<Rightarrow> 'a :: {banach,real_normed_div_algebra}"
eberlm@62049
   702
  assumes "\<And>z. summable (\<lambda>n. f n * z^n)"
eberlm@62049
   703
  shows   "conv_radius f = \<infinity>"
eberlm@62049
   704
proof (rule conv_radius_inftyI')
eberlm@62049
   705
  fix r :: real assume "r > 0"
eberlm@62049
   706
  with assms show "\<exists>z. norm z = r \<and> summable (\<lambda>n. f n * z^n)"
eberlm@62049
   707
    by (intro exI[of _ "of_real r"]) simp
eberlm@62049
   708
qed
eberlm@62049
   709
eberlm@62049
   710
lemma conv_radius_ratio_limit_ereal:
eberlm@62049
   711
  fixes f :: "nat \<Rightarrow> 'a :: {banach,real_normed_div_algebra}"
eberlm@62049
   712
  assumes nz:  "eventually (\<lambda>n. f n \<noteq> 0) sequentially"
eberlm@62049
   713
  assumes lim: "(\<lambda>n. ereal (norm (f n) / norm (f (Suc n)))) \<longlonglongrightarrow> c"
eberlm@62049
   714
  shows   "conv_radius f = c"
eberlm@62049
   715
proof (rule conv_radius_eqI')
eberlm@62049
   716
  show "c \<ge> 0" by (intro Lim_bounded2_ereal[OF lim]) simp_all
eberlm@62049
   717
next
eberlm@62049
   718
  fix r assume r: "0 < r" "ereal r < c"
eberlm@62049
   719
  let ?l = "liminf (\<lambda>n. ereal (norm (f n * of_real r ^ n) / norm (f (Suc n) * of_real r ^ Suc n)))"
eberlm@62049
   720
  have "?l = liminf (\<lambda>n. ereal (norm (f n) / (norm (f (Suc n)))) * ereal (inverse r))"
eberlm@62049
   721
    using r by (simp add: norm_mult norm_power divide_simps)
eberlm@62049
   722
  also from r have "\<dots> = liminf (\<lambda>n. ereal (norm (f n) / (norm (f (Suc n))))) * ereal (inverse r)"
eberlm@62049
   723
    by (intro Liminf_ereal_mult_right) simp_all
eberlm@62049
   724
  also have "liminf (\<lambda>n. ereal (norm (f n) / (norm (f (Suc n))))) = c"
eberlm@62049
   725
    by (intro lim_imp_Liminf lim) simp
eberlm@62049
   726
  finally have l: "?l = c * ereal (inverse r)" by simp
eberlm@62049
   727
  from r have  l': "c * ereal (inverse r) > 1" by (cases c) (simp_all add: field_simps)
eberlm@62049
   728
  show "summable (\<lambda>n. f n * of_real r^n)"
eberlm@62049
   729
    by (rule summable_norm_cancel, rule ratio_test_convergence)
eberlm@62049
   730
       (insert r nz l l', auto elim!: eventually_mono)
eberlm@62049
   731
next
eberlm@62049
   732
  fix r assume r: "0 < r" "ereal r > c"
eberlm@62049
   733
  let ?l = "limsup (\<lambda>n. ereal (norm (f n * of_real r ^ n) / norm (f (Suc n) * of_real r ^ Suc n)))"
eberlm@62049
   734
  have "?l = limsup (\<lambda>n. ereal (norm (f n) / (norm (f (Suc n)))) * ereal (inverse r))"
eberlm@62049
   735
    using r by (simp add: norm_mult norm_power divide_simps)
eberlm@62049
   736
  also from r have "\<dots> = limsup (\<lambda>n. ereal (norm (f n) / (norm (f (Suc n))))) * ereal (inverse r)"
eberlm@62049
   737
    by (intro Limsup_ereal_mult_right) simp_all
eberlm@62049
   738
  also have "limsup (\<lambda>n. ereal (norm (f n) / (norm (f (Suc n))))) = c"
eberlm@62049
   739
    by (intro lim_imp_Limsup lim) simp
eberlm@62049
   740
  finally have l: "?l = c * ereal (inverse r)" by simp
eberlm@62049
   741
  from r have  l': "c * ereal (inverse r) < 1" by (cases c) (simp_all add: field_simps)
eberlm@62049
   742
  show "\<not>summable (\<lambda>n. norm (f n * of_real r^n))"
eberlm@62049
   743
    by (rule ratio_test_divergence) (insert r nz l l', auto elim!: eventually_mono)
eberlm@62049
   744
qed
eberlm@62049
   745
eberlm@62049
   746
lemma conv_radius_ratio_limit_ereal_nonzero:
eberlm@62049
   747
  fixes f :: "nat \<Rightarrow> 'a :: {banach,real_normed_div_algebra}"
eberlm@62049
   748
  assumes nz:  "c \<noteq> 0"
eberlm@62049
   749
  assumes lim: "(\<lambda>n. ereal (norm (f n) / norm (f (Suc n)))) \<longlonglongrightarrow> c"
eberlm@62049
   750
  shows   "conv_radius f = c"
eberlm@62049
   751
proof (rule conv_radius_ratio_limit_ereal[OF _ lim], rule ccontr)
eberlm@62049
   752
  assume "\<not>eventually (\<lambda>n. f n \<noteq> 0) sequentially"
eberlm@62049
   753
  hence "frequently (\<lambda>n. f n = 0) sequentially" by (simp add: frequently_def)
eberlm@62049
   754
  hence "frequently (\<lambda>n. ereal (norm (f n) / norm (f (Suc n))) = 0) sequentially"
eberlm@62049
   755
    by (force elim!: frequently_elim1)
eberlm@62049
   756
  hence "c = 0" by (intro limit_frequently_eq[OF _ _ lim]) auto
eberlm@62049
   757
  with nz show False by contradiction
hoelzl@63594
   758
qed
eberlm@62049
   759
eberlm@62049
   760
lemma conv_radius_ratio_limit:
eberlm@62049
   761
  fixes f :: "nat \<Rightarrow> 'a :: {banach,real_normed_div_algebra}"
eberlm@62049
   762
  assumes "c' = ereal c"
eberlm@62049
   763
  assumes nz:  "eventually (\<lambda>n. f n \<noteq> 0) sequentially"
eberlm@62049
   764
  assumes lim: "(\<lambda>n. norm (f n) / norm (f (Suc n))) \<longlonglongrightarrow> c"
eberlm@62049
   765
  shows   "conv_radius f = c'"
eberlm@62049
   766
  using assms by (intro conv_radius_ratio_limit_ereal) simp_all
hoelzl@63594
   767
eberlm@62049
   768
lemma conv_radius_ratio_limit_nonzero:
eberlm@62049
   769
  fixes f :: "nat \<Rightarrow> 'a :: {banach,real_normed_div_algebra}"
eberlm@62049
   770
  assumes "c' = ereal c"
eberlm@62049
   771
  assumes nz:  "c \<noteq> 0"
eberlm@62049
   772
  assumes lim: "(\<lambda>n. norm (f n) / norm (f (Suc n))) \<longlonglongrightarrow> c"
eberlm@62049
   773
  shows   "conv_radius f = c'"
eberlm@62049
   774
  using assms by (intro conv_radius_ratio_limit_ereal_nonzero) simp_all
eberlm@62049
   775
hoelzl@63594
   776
lemma conv_radius_mult_power:
eberlm@62049
   777
  assumes "c \<noteq> (0 :: 'a :: {real_normed_div_algebra,banach})"
eberlm@62049
   778
  shows   "conv_radius (\<lambda>n. c ^ n * f n) = conv_radius f / ereal (norm c)"
hoelzl@63594
   779
proof -
eberlm@62049
   780
  have "limsup (\<lambda>n. ereal (root n (norm (c ^ n * f n)))) =
hoelzl@63594
   781
          limsup (\<lambda>n. ereal (norm c) * ereal (root n (norm (f n))))"
lp15@65578
   782
    by (intro Limsup_eq eventually_mono [OF eventually_gt_at_top[of "0::nat"]])
lp15@65578
   783
       (auto simp: norm_mult norm_power real_root_mult real_root_power)
eberlm@62049
   784
  also have "\<dots> = ereal (norm c) * limsup (\<lambda>n. ereal (root n (norm (f n))))"
eberlm@62049
   785
    using assms by (subst Limsup_ereal_mult_left[symmetric]) simp_all
hoelzl@63594
   786
  finally have A: "limsup (\<lambda>n. ereal (root n (norm (c ^ n * f n)))) =
eberlm@62049
   787
                       ereal (norm c) * limsup (\<lambda>n. ereal (root n (norm (f n))))" .
eberlm@62049
   788
  show ?thesis using assms
eberlm@62049
   789
    apply (cases "limsup (\<lambda>n. ereal (root n (norm (f n)))) = 0")
eberlm@62049
   790
    apply (simp add: A conv_radius_def)
eberlm@62049
   791
    apply (unfold conv_radius_def A divide_ereal_def, simp add: mult.commute ereal_inverse_mult)
eberlm@62049
   792
    done
eberlm@62049
   793
qed
eberlm@62049
   794
hoelzl@63594
   795
lemma conv_radius_mult_power_right:
eberlm@62049
   796
  assumes "c \<noteq> (0 :: 'a :: {real_normed_div_algebra,banach})"
eberlm@62049
   797
  shows   "conv_radius (\<lambda>n. f n * c ^ n) = conv_radius f / ereal (norm c)"
eberlm@62049
   798
  using conv_radius_mult_power[OF assms, of f]
eberlm@62049
   799
  unfolding conv_radius_def by (simp add: mult.commute norm_mult)
eberlm@62049
   800
hoelzl@63594
   801
lemma conv_radius_divide_power:
eberlm@62049
   802
  assumes "c \<noteq> (0 :: 'a :: {real_normed_div_algebra,banach})"
eberlm@62049
   803
  shows   "conv_radius (\<lambda>n. f n / c^n) = conv_radius f * ereal (norm c)"
hoelzl@63594
   804
proof -
eberlm@62049
   805
  from assms have "inverse c \<noteq> 0" by simp
eberlm@62049
   806
  from conv_radius_mult_power_right[OF this, of f] show ?thesis
eberlm@62049
   807
    by (simp add: divide_inverse divide_ereal_def assms norm_inverse power_inverse)
eberlm@62049
   808
qed
eberlm@62049
   809
eberlm@62049
   810
hoelzl@63594
   811
lemma conv_radius_add_ge:
hoelzl@63594
   812
  "min (conv_radius f) (conv_radius g) \<le>
eberlm@62049
   813
       conv_radius (\<lambda>x. f x + g x :: 'a :: {banach,real_normed_div_algebra})"
eberlm@62049
   814
  by (rule conv_radius_geI_ex')
eberlm@62049
   815
     (auto simp: algebra_simps intro!: summable_add summable_in_conv_radius)
eberlm@62049
   816
eberlm@62049
   817
lemma conv_radius_mult_ge:
eberlm@62049
   818
  fixes f g :: "nat \<Rightarrow> ('a :: {banach,real_normed_div_algebra})"
eberlm@62049
   819
  shows "conv_radius (\<lambda>x. \<Sum>i\<le>x. f i * g (x - i)) \<ge> min (conv_radius f) (conv_radius g)"
eberlm@62049
   820
proof (rule conv_radius_geI_ex')
eberlm@62049
   821
  fix r assume r: "r > 0" "ereal r < min (conv_radius f) (conv_radius g)"
eberlm@62049
   822
  from r have "summable (\<lambda>n. (\<Sum>i\<le>n. (f i * of_real r^i) * (g (n - i) * of_real r^(n - i))))"
eberlm@62049
   823
    by (intro summable_Cauchy_product abs_summable_in_conv_radius) simp_all
eberlm@62049
   824
  thus "summable (\<lambda>n. (\<Sum>i\<le>n. f i * g (n - i)) * of_real r ^ n)"
nipkow@64267
   825
    by (simp add: algebra_simps of_real_def power_add [symmetric] scaleR_sum_right)
eberlm@62049
   826
qed
eberlm@62049
   827
lp15@62381
   828
lemma le_conv_radius_iff:
lp15@62381
   829
  fixes a :: "nat \<Rightarrow> 'a::{real_normed_div_algebra,banach}"
lp15@62381
   830
  shows "r \<le> conv_radius a \<longleftrightarrow> (\<forall>x. norm (x-\<xi>) < r \<longrightarrow> summable (\<lambda>i. a i * (x - \<xi>) ^ i))"
lp15@62381
   831
apply (intro iffI allI impI summable_in_conv_radius conv_radius_geI_ex)
lp15@62381
   832
apply (meson less_ereal.simps(1) not_le order_trans)
lp15@62381
   833
apply (rule_tac x="of_real ra" in exI, simp)
lp15@62381
   834
apply (metis abs_of_nonneg add_diff_cancel_left' less_eq_real_def norm_of_real)
lp15@62381
   835
done
lp15@62381
   836
eberlm@62049
   837
end