(* Title: HOL/Analysis/FPS_Convergence.thy Author: Manuel Eberl, TU München
Connection of formal power series and actual convergent power series on Banach spaces (most notably the complex numbers).
*) section‹Convergence of Formal Power Series›
theory FPS_Convergence imports
Generalised_Binomial_Theorem "HOL-Computational_Algebra.Formal_Power_Series" "HOL-Computational_Algebra.Polynomial_FPS"
begin
text‹ In this theory, we will connect formal power series (which are algebraic objects) with analytic
functions. This will become more important in complex analysis, and indeed some of the less
trivial results will only be proven there. ›
subsection🍋‹tag unimportant›‹Balls with extended real radius›
(* TODO: This should probably go somewhere else *)
text‹
The following is a variant of 🍋‹ball› that also allows an infinite radius. › definition eball :: "'a :: metric_space \ ereal \ 'a set"where "eball z r = {z'. ereal (dist z z') < r}"
lemma in_eball_iff [simp]: "z \ eball z0 r \ ereal (dist z0 z) < r" by (simp add: eball_def)
lemma eball_ereal [simp]: "eball z (ereal r) = ball z r" by auto
lemma eball_inf [simp]: "eball z \ = UNIV" by auto
lemma eball_empty [simp]: "r \ 0 \ eball z r = {}" proof safe fix x assume"r \ 0""x \ eball z r" hence"dist z x < r"by simp alsohave"\ \ ereal 0"using‹r ≤ 0›by (simp add: zero_ereal_def) finallyshow"x \ {}"by simp qed
lemma eball_conv_UNION_balls: "eball z r = (\r'\{r'. ereal r' < r}. ball z r')" by (cases r) (use dense gt_ex in force)+
lemma eball_mono: "r \ r' \ eball z r \ eball z r'" by auto
lemma ball_eball_mono: "ereal r \ r' \ ball z r \ eball z r'" using eball_mono[of "ereal r" r'] by simp
lemma open_eball [simp, intro]: "open (eball z r)" by (cases r) auto
lemma connected_eball [intro]: "connected (eball (z :: 'a :: real_normed_vector) r)" by (cases r) auto
subsection‹Basic properties of convergent power series›
definition🍋‹tag important› eval_fps :: "'a :: {banach, real_normed_div_algebra} fps \ 'a \ 'a"where "eval_fps f z = (\n. fps_nth f n * z ^ n)"
lemma norm_summable_fps: fixes f :: "'a :: {banach, real_normed_div_algebra} fps" shows"norm z < fps_conv_radius f \ summable (\n. norm (fps_nth f n * z ^ n))" by (rule abs_summable_in_conv_radius) (simp_all add: fps_conv_radius_def)
lemma summable_fps: fixes f :: "'a :: {banach, real_normed_div_algebra} fps" shows"norm z < fps_conv_radius f \ summable (\n. fps_nth f n * z ^ n)" by (rule summable_in_conv_radius) (simp_all add: fps_conv_radius_def)
theorem sums_eval_fps: fixes f :: "'a :: {banach, real_normed_div_algebra} fps" assumes"norm z < fps_conv_radius f" shows"(\n. fps_nth f n * z ^ n) sums eval_fps f z" using assms unfolding eval_fps_def fps_conv_radius_def by (intro summable_sums summable_in_conv_radius) simp_all
lemma continuous_on_eval_fps: fixes f :: "'a :: {banach, real_normed_div_algebra} fps" shows"continuous_on (eball 0 (fps_conv_radius f)) (eval_fps f)" proof (subst continuous_on_eq_continuous_at [OF open_eball], safe) fix x :: 'a assume x: "x \ eball 0 (fps_conv_radius f)"
define r where"r = (if fps_conv_radius f = \ then norm x + 1 else
(norm x + real_of_ereal (fps_conv_radius f)) / 2)" have r: "norm x < r \ ereal r < fps_conv_radius f" using x by (cases "fps_conv_radius f")
(auto simp: r_def eball_def split: if_splits)
have"continuous_on (cball 0 r) (\x. \i. fps_nth f i * (x - 0) ^ i)" by (rule powser_continuous_suminf) (insert r, auto simp: fps_conv_radius_def) hence"continuous_on (cball 0 r) (eval_fps f)" by (simp add: eval_fps_def) thus"isCont (eval_fps f) x" by (rule continuous_on_interior) (use r in auto) qed
lemma continuous_on_eval_fps' [continuous_intros]: assumes"continuous_on A g" assumes"g ` A \ eball 0 (fps_conv_radius f)" shows"continuous_on A (\x. eval_fps f (g x))" using continuous_on_compose2[OF continuous_on_eval_fps assms] .
lemma has_field_derivative_powser: fixes z :: "'a :: {banach, real_normed_field}" assumes"ereal (norm z) < conv_radius f" shows"((\z. \n. f n * z ^ n) has_field_derivative (\n. diffs f n * z ^ n)) (at z within A)" proof -
define K where"K = (if conv_radius f = \ then norm z + 1
else (norm z + real_of_ereal (conv_radius f)) / 2)" have K: "norm z < K \ ereal K < conv_radius f" using assms by (cases "conv_radius f") (auto simp: K_def) have"0 \ norm z"by simp alsofrom K have"\ < K"by simp finallyhave K_pos: "K > 0"by simp
have"summable (\n. f n * of_real K ^ n)" using K and K_pos by (intro summable_in_conv_radius) auto moreoverfrom K and K_pos have"norm z < norm (of_real K :: 'a)"by auto ultimatelyshow ?thesis by (rule has_field_derivative_at_within [OF termdiffs_strong]) qed
lemma has_field_derivative_eval_fps: fixes z :: "'a :: {banach, real_normed_field}" assumes"norm z < fps_conv_radius f" shows"(eval_fps f has_field_derivative eval_fps (fps_deriv f) z) (at z within A)" proof - have"(eval_fps f has_field_derivative eval_fps (Abs_fps (diffs (fps_nth f))) z) (at z within A)" using assms unfolding eval_fps_def fps_nth_Abs_fps fps_conv_radius_def by (intro has_field_derivative_powser) auto alsohave"Abs_fps (diffs (fps_nth f)) = fps_deriv f" by (simp add: fps_eq_iff diffs_def) finallyshow ?thesis . qed
lemma holomorphic_on_eval_fps [holomorphic_intros]: fixes z :: "'a :: {banach, real_normed_field}" assumes"A \ eball 0 (fps_conv_radius f)" shows"eval_fps f holomorphic_on A" proof (rule holomorphic_on_subset [OF _ assms]) show"eval_fps f holomorphic_on eball 0 (fps_conv_radius f)" proof (subst holomorphic_on_open [OF open_eball], safe, goal_cases) case (1 x) thus ?case by (intro exI[of _ "eval_fps (fps_deriv f) x"]) (auto intro: has_field_derivative_eval_fps) qed qed
lemma analytic_on_eval_fps: fixes z :: "'a :: {banach, real_normed_field}" assumes"A \ eball 0 (fps_conv_radius f)" shows"eval_fps f analytic_on A" proof (rule analytic_on_subset [OF _ assms]) show"eval_fps f analytic_on eball 0 (fps_conv_radius f)" using holomorphic_on_eval_fps[of "eball 0 (fps_conv_radius f)"] by (subst analytic_on_open) auto qed
lemma continuous_eval_fps [continuous_intros]: fixes z :: "'a::{real_normed_field,banach}" assumes"norm z < fps_conv_radius F" shows"continuous (at z within A) (eval_fps F)" proof - from ereal_dense2[OF assms] obtain K :: real where K: "norm z < K""K < fps_conv_radius F" by auto have"0 \ norm z"by simp alsohave"norm z < K"by fact finallyhave"K > 0" . from K and‹K > 0›have"summable (\n. fps_nth F n * of_real K ^ n)" by (intro summable_fps) auto from this have"isCont (eval_fps F) z"unfolding eval_fps_def by (rule isCont_powser) (use K in auto) thus"continuous (at z within A) (eval_fps F)" by (simp add: continuous_at_imp_continuous_within) qed
subsection🍋‹tag unimportant›‹Lower bounds on radius of convergence›
lemma fps_conv_radius_deriv: fixes f :: "'a :: {banach, real_normed_field} fps" shows"fps_conv_radius (fps_deriv f) \ fps_conv_radius f" unfolding fps_conv_radius_def proof (rule conv_radius_geI_ex) fix r :: real assume r: "r > 0""ereal r < conv_radius (fps_nth f)"
define K where"K = (if conv_radius (fps_nth f) = \ then r + 1
else (real_of_ereal (conv_radius (fps_nth f)) + r) / 2)" have K: "r < K \ ereal K < conv_radius (fps_nth f)" using r by (cases "conv_radius (fps_nth f)") (auto simp: K_def) have"summable (\n. diffs (fps_nth f) n * of_real r ^ n)" proof (rule termdiff_converges) fix x :: 'a assume "norm x < K" hence"ereal (norm x) < ereal K"by simp alsohave"\ < conv_radius (fps_nth f)"using K by simp finallyshow"summable (\n. fps_nth f n * x ^ n)" by (intro summable_in_conv_radius) auto qed (insert K r, auto) alsohave"\ = (\n. fps_nth (fps_deriv f) n * of_real r ^ n)" by (simp add: fps_deriv_def diffs_def) finallyshow"\z::'a. norm z = r \ summable (\n. fps_nth (fps_deriv f) n * z ^ n)" using r by (intro exI[of _ "of_real r"]) auto qed
lemma eval_fps_at_0: "eval_fps f 0 = fps_nth f 0" by (simp add: eval_fps_def)
lemma fps_conv_radius_norm [simp]: "fps_conv_radius (Abs_fps (\n. norm (fps_nth f n))) = fps_conv_radius f" by (simp add: fps_conv_radius_def)
lemma fps_conv_radius_const [simp]: "fps_conv_radius (fps_const c) = \" proof - have"fps_conv_radius (fps_const c) = conv_radius (\_. 0 :: 'a)" unfolding fps_conv_radius_def by (intro conv_radius_cong eventually_mono[OF eventually_gt_at_top[of 0]]) auto thus ?thesis by simp qed
have summable: "summable (\n. norm (fps_nth f n) * \ ^ n)" using δ by (intro summable_in_conv_radius) (simp_all add: fps_conv_radius_def) hence"(\n. norm (fps_nth f n) * \ ^ n) sums eval_fps h \" by (simp add: eval_fps_def summable_sums h_def) hence"(\n. norm (fps_nth f (Suc n)) * \ ^ Suc n) sums (eval_fps h \ - 1)" by (subst sums_Suc_iff) (auto simp: assms) moreover { from δ have"\ \ ball 0 \"by auto alsohave"\ \ eval_fps h -` {..<2} \ eball 0 ?R"by fact finallyhave"eval_fps h \ < 2"by simp
} ultimatelyhave le: "(\n. norm (fps_nth f (Suc n)) * \ ^ Suc n) \ 1" by (simp add: sums_iff) from summable have summable: "summable (\n. norm (fps_nth f (Suc n)) * \ ^ Suc n)" by (subst summable_Suc_iff)
have"0 < \"using δ by blast alsohave"\ = inverse (limsup (\n. ereal (inverse \)))" using δ by (subst Limsup_const) auto alsohave"\ \ conv_radius (natfun_inverse f)" unfolding conv_radius_def proof (intro ereal_inverse_antimono Limsup_mono
eventually_mono[OF eventually_gt_at_top[of 0]]) fix n :: nat assume n: "n > 0" have"root n (norm (natfun_inverse f n)) \ root n (inverse (\ ^ n))" using n assms δ le summable by (intro real_root_le_mono natfun_inverse_bound) auto alsohave"\ = inverse \" using n δ by (simp add: power_inverse [symmetric] real_root_pos2) finallyshow"ereal (inverse \) \ ereal (root n (norm (natfun_inverse f n)))" by (subst ereal_less_eq) next have"0 = limsup (\n. 0::ereal)" by (rule Limsup_const [symmetric]) auto alsohave"\ \ limsup (\n. ereal (root n (norm (natfun_inverse f n))))" by (intro Limsup_mono) (auto simp: real_root_ge_zero) finallyshow"0 \ \"by simp qed alsohave"\ = fps_conv_radius (inverse f)" using assms by (simp add: fps_conv_radius_def fps_inverse_def) finallyshow ?thesis by (simp add: zero_ereal_def) qed
lemma fps_conv_radius_inverse_pos: fixes f :: "'a :: {banach, real_normed_field} fps" assumes"fps_nth f 0 \ 0"and"fps_conv_radius f > 0" shows"fps_conv_radius (inverse f) > 0" proof - let ?c = "fps_nth f 0" have"fps_conv_radius (inverse f) = fps_conv_radius (fps_const ?c * inverse f)" using assms by (subst fps_conv_radius_cmult_left) auto alsohave"fps_const ?c * inverse f = inverse (fps_const (inverse ?c) * f)" using assms by (simp add: fps_inverse_mult fps_const_inverse) alsohave"fps_conv_radius \ > 0"using assms by (intro fps_conv_radius_inverse_pos_aux)
(auto simp: fps_conv_radius_cmult_left) finallyshow ?thesis . qed
end
lemma fps_conv_radius_exp [simp]: fixes c :: "'a :: {banach, real_normed_field}" shows"fps_conv_radius (fps_exp c) = \" unfolding fps_conv_radius_def proof (rule conv_radius_inftyI'') fix z :: 'a have"(\n. norm (c * z) ^ n /\<^sub>R fact n) sums exp (norm (c * z))" by (rule exp_converges) alsohave"(\n. norm (c * z) ^ n /\<^sub>R fact n) = (\n. norm (fps_nth (fps_exp c) n * z ^ n))" by (rule ext) (simp add: norm_divide norm_mult norm_power field_split_simps) finallyhave"summable \"by (simp add: sums_iff) thus"summable (\n. fps_nth (fps_exp c) n * z ^ n)" by (rule summable_norm_cancel) qed
subsection‹Evaluating power series›
theorem eval_fps_deriv: assumes"norm z < fps_conv_radius f" shows"eval_fps (fps_deriv f) z = deriv (eval_fps f) z" by (intro DERIV_imp_deriv [symmetric] has_field_derivative_eval_fps assms)
theorem fps_nth_conv_deriv: fixes f :: "complex fps" assumes"fps_conv_radius f > 0" shows"fps_nth f n = (deriv ^^ n) (eval_fps f) 0 / fact n" using assms proof (induction n arbitrary: f) case 0 thus ?caseby (simp add: eval_fps_def) next case (Suc n f) have"(deriv ^^ Suc n) (eval_fps f) 0 = (deriv ^^ n) (deriv (eval_fps f)) 0" unfolding funpow_Suc_right o_def .. alsohave"eventually (\z::complex. z \ eball 0 (fps_conv_radius f)) (nhds 0)" using Suc.prems by (intro eventually_nhds_in_open) (auto simp: zero_ereal_def) hence"eventually (\z. deriv (eval_fps f) z = eval_fps (fps_deriv f) z) (nhds 0)" by eventually_elim (simp add: eval_fps_deriv) hence"(deriv ^^ n) (deriv (eval_fps f)) 0 = (deriv ^^ n) (eval_fps (fps_deriv f)) 0" by (intro higher_deriv_cong_ev refl) alsohave"\ / fact n = fps_nth (fps_deriv f) n" using Suc.prems fps_conv_radius_deriv[of f] by (intro Suc.IH [symmetric]) auto alsohave"\ / of_nat (Suc n) = fps_nth f (Suc n)" by (simp add: fps_deriv_def del: of_nat_Suc) finallyshow ?caseby (simp add: field_split_simps) qed
theorem eval_fps_eqD: fixes f g :: "complex fps" assumes"fps_conv_radius f > 0""fps_conv_radius g > 0" assumes"eventually (\z. eval_fps f z = eval_fps g z) (nhds 0)" shows"f = g" proof (rule fps_ext) fix n :: nat have"fps_nth f n = (deriv ^^ n) (eval_fps f) 0 / fact n" using assms by (intro fps_nth_conv_deriv) alsohave"(deriv ^^ n) (eval_fps f) 0 = (deriv ^^ n) (eval_fps g) 0" by (intro higher_deriv_cong_ev refl assms) alsohave"\ / fact n = fps_nth g n" using assms by (intro fps_nth_conv_deriv [symmetric]) finallyshow"fps_nth f n = fps_nth g n" . qed
lemma eval_fps_const [simp]: fixes c :: "'a :: {banach, real_normed_div_algebra}" shows"eval_fps (fps_const c) z = c" proof - have"(\n::nat. if n \ {0} then c else 0) sums (\n\{0::nat}. c)" by (rule sums_If_finite_set) auto alsohave"?this \ (\n::nat. fps_nth (fps_const c) n * z ^ n) sums (\n\{0::nat}. c)" by (intro sums_cong) auto alsohave"(\n\{0::nat}. c) = c" by simp finallyshow ?thesis by (simp add: eval_fps_def sums_iff) qed
lemma eval_fps_0 [simp]: "eval_fps (0 :: 'a :: {banach, real_normed_div_algebra} fps) z = 0" by (simp only: fps_const_0_eq_0 [symmetric] eval_fps_const)
lemma eval_fps_1 [simp]: "eval_fps (1 :: 'a :: {banach, real_normed_div_algebra} fps) z = 1" by (simp only: fps_const_1_eq_1 [symmetric] eval_fps_const)
lemma eval_fps_numeral [simp]: "eval_fps (numeral n :: 'a :: {banach, real_normed_div_algebra} fps) z = numeral n" by (simp only: numeral_fps_const eval_fps_const)
lemma eval_fps_X_power [simp]: "eval_fps (fps_X ^ m :: 'a :: {banach, real_normed_div_algebra} fps) z = z ^ m" proof - have"(\n::nat. if n \ {m} then z ^ n else 0 :: 'a) sums (\n\{m::nat}. z ^ n)" by (rule sums_If_finite_set) auto alsohave"?this \ (\n::nat. fps_nth (fps_X ^ m) n * z ^ n) sums (\n\{m::nat}. z ^ n)" by (intro sums_cong) (auto simp: fps_X_power_iff) alsohave"(\n\{m::nat}. z ^ n) = z ^ m" by simp finallyshow ?thesis by (simp add: eval_fps_def sums_iff) qed
lemma eval_fps_X [simp]: "eval_fps (fps_X :: 'a :: {banach, real_normed_div_algebra} fps) z = z" using eval_fps_X_power[of 1 z] by (simp only: power_one_right)
lemma eval_fps_minus: fixes f :: "'a :: {banach, real_normed_div_algebra} fps" assumes"norm z < fps_conv_radius f" shows"eval_fps (-f) z = -eval_fps f z" using assms unfolding eval_fps_def by (subst suminf_minus [symmetric]) (auto intro!: summable_fps)
lemma eval_fps_add: fixes f g :: "'a :: {banach, real_normed_div_algebra} fps" assumes"norm z < fps_conv_radius f""norm z < fps_conv_radius g" shows"eval_fps (f + g) z = eval_fps f z + eval_fps g z" using assms unfolding eval_fps_def by (subst suminf_add) (auto simp: ring_distribs intro!: summable_fps)
lemma eval_fps_diff: fixes f g :: "'a :: {banach, real_normed_div_algebra} fps" assumes"norm z < fps_conv_radius f""norm z < fps_conv_radius g" shows"eval_fps (f - g) z = eval_fps f z - eval_fps g z" using assms unfolding eval_fps_def by (subst suminf_diff) (auto simp: ring_distribs intro!: summable_fps)
lemma eval_fps_mult: fixes f g :: "'a :: {banach, real_normed_div_algebra, comm_ring_1} fps" assumes"norm z < fps_conv_radius f""norm z < fps_conv_radius g" shows"eval_fps (f * g) z = eval_fps f z * eval_fps g z" proof - have"eval_fps f z * eval_fps g z =
(∑k. ∑i≤k. fps_nth f i * fps_nth g (k - i) * (z ^ i * z ^ (k - i)))" unfolding eval_fps_def proof (subst Cauchy_product) show"summable (\k. norm (fps_nth f k * z ^ k))""summable (\k. norm (fps_nth g k * z ^ k))" by (rule norm_summable_fps assms)+ qed (simp_all add: algebra_simps) alsohave"(\k. \i\k. fps_nth f i * fps_nth g (k - i) * (z ^ i * z ^ (k - i))) =
(λk. ∑i≤k. fps_nth f i * fps_nth g (k - i) * z ^ k)" by (intro ext sum.cong refl) (simp add: power_add [symmetric]) alsohave"suminf \ = eval_fps (f * g) z" by (simp add: eval_fps_def fps_mult_nth atLeast0AtMost sum_distrib_right) finallyshow ?thesis .. qed
lemma eval_fps_shift: fixes f :: "'a :: {banach, real_normed_div_algebra, comm_ring_1} fps" assumes"n \ subdegree f""norm z < fps_conv_radius f" shows"eval_fps (fps_shift n f) z = (if z = 0 then fps_nth f n else eval_fps f z / z ^ n)" proof (cases "z = 0") case False have"eval_fps (fps_shift n f * fps_X ^ n) z = eval_fps (fps_shift n f) z * z ^ n" using assms by (subst eval_fps_mult) simp_all alsofrom assms have"fps_shift n f * fps_X ^ n = f" by (simp add: fps_shift_times_fps_X_power) finallyshow ?thesis using False by (simp add: field_simps) qed (simp_all add: eval_fps_at_0)
lemma eval_fps_exp [simp]: fixes c :: "'a :: {banach, real_normed_field}" shows"eval_fps (fps_exp c) z = exp (c * z)"unfolding eval_fps_def exp_def by (simp add: eval_fps_def exp_def scaleR_conv_of_real field_split_simps)
text‹
The case of division is more complicated and will therefore not be handled here.
Handling division becomes much more easy using complex analysis, and we will do so once
that is available. ›
subsection‹FPS of a polynomial›
lemma fps_conv_radius_fps_of_poly [simp]: fixes p :: "'a :: {banach, real_normed_div_algebra} poly" shows"fps_conv_radius (fps_of_poly p) = \" proof - have"conv_radius (poly.coeff p) = conv_radius (\_. 0 :: 'a)" using MOST_coeff_eq_0 unfolding cofinite_eq_sequentially by (rule conv_radius_cong') alsohave"\ = \" by simp finallyshow ?thesis by (simp add: fps_conv_radius_def) qed
lemma eval_fps_power: fixes F :: "'a :: {banach, real_normed_div_algebra, comm_ring_1} fps" assumes z: "norm z < fps_conv_radius F" shows"eval_fps (F ^ n) z = eval_fps F z ^ n" proof (induction n) case 0 thus ?case by (auto simp: eval_fps_mult) next case (Suc n) have"eval_fps (F ^ Suc n) z = eval_fps (F * F ^ n) z" by simp alsofrom z have"\ = eval_fps F z * eval_fps (F ^ n) z" by (subst eval_fps_mult) (auto intro!: less_le_trans[OF _ fps_conv_radius_power]) finallyshow ?case using Suc.IH by simp qed
lemma eval_fps_of_poly [simp]: "eval_fps (fps_of_poly p) z = poly p z" proof - have"(\n. poly.coeff p n * z ^ n) sums poly p z" unfolding poly_altdef by (rule sums_finite) (auto simp: coeff_eq_0) moreoverhave"(\n. poly.coeff p n * z ^ n) sums eval_fps (fps_of_poly p) z" using sums_eval_fps[of z "fps_of_poly p"] by simp ultimatelyshow ?thesis using sums_unique2 by blast qed
lemma poly_holomorphic_on [holomorphic_intros]: assumes [holomorphic_intros]: "f holomorphic_on A" shows"(\z. poly p (f z)) holomorphic_on A" unfolding poly_altdef by (intro holomorphic_intros)
subsection‹Power series expansions of analytic functions›
text‹
This predicate contains the notion that the given formal power series converges in some disc of positive radius around the origin andis equal to the given complex function there.
This relationship is unique in the sense that no complex function can have more than
one formal power series to which it expands, andif two holomorphic functions that are
holomorphic on a connected open set around the origin andhave the same power series
expansion, they must be equal on that set.
More concrete statements about the radius of convergence can usually be made, but for
many purposes, the statment that the series converges to the functionin some neighbourhood
of the origin is enough, and that can be shown almost fully automatically in most cases,
as there are straightforward introduction rules toshow this.
In particular, when one wants to relate the coefficients of the power series to the
values of the derivatives of the function at the origin, or if one wants to approximate
the coefficients of the series with the singularities of the function, this predicate is enough. › definition🍋‹tag important›
has_fps_expansion :: "('a :: {banach,real_normed_div_algebra} \ 'a) \ 'a fps \ bool"
(infixl‹has'_fps'_expansion› 60) where"(f has_fps_expansion F) \
fps_conv_radius F > 0 ∧ eventually (λz. eval_fps F z = f z) (nhds 0)"
named_theorems fps_expansion_intros
lemma has_fps_expansion_schematicI: "f has_fps_expansion A \ A = B \ f has_fps_expansion B" by simp
lemma fps_nth_fps_expansion: fixes f :: "complex \ complex" assumes"f has_fps_expansion F" shows"fps_nth F n = (deriv ^^ n) f 0 / fact n" proof - have"fps_nth F n = (deriv ^^ n) (eval_fps F) 0 / fact n" using assms by (intro fps_nth_conv_deriv) (auto simp: has_fps_expansion_def) alsohave"(deriv ^^ n) (eval_fps F) 0 = (deriv ^^ n) f 0" using assms by (intro higher_deriv_cong_ev) (auto simp: has_fps_expansion_def) finallyshow ?thesis . qed
lemma eval_fps_has_fps_expansion: "fps_conv_radius F > 0 \ eval_fps F has_fps_expansion F" unfolding has_fps_expansion_def by simp
lemma has_fps_expansion_imp_continuous: fixes F :: "'a::{real_normed_field,banach} fps" assumes"f has_fps_expansion F" shows"continuous (at 0 within A) f" proof - from assms have"isCont (eval_fps F) 0" by (intro continuous_eval_fps) (auto simp: has_fps_expansion_def zero_ereal_def) alsohave"?this \ isCont f 0"using assms by (intro isCont_cong) (auto simp: has_fps_expansion_def) finallyhave"isCont f 0" . thus"continuous (at 0 within A) f" by (simp add: continuous_at_imp_continuous_within) qed
lemma has_fps_expansion_const [simp, intro, fps_expansion_intros]: "(\_. c) has_fps_expansion fps_const c" by (auto simp: has_fps_expansion_def)
lemma has_fps_expansion_cmult_left [fps_expansion_intros]: fixes c :: "'a :: {banach, real_normed_div_algebra, comm_ring_1}" assumes"f has_fps_expansion F" shows"(\x. c * f x) has_fps_expansion fps_const c * F" proof (cases "c = 0") case False from assms have"eventually (\z. z \ eball 0 (fps_conv_radius F)) (nhds 0)" by (intro eventually_nhds_in_open) (auto simp: has_fps_expansion_def zero_ereal_def) moreoverfrom assms have"eventually (\z. eval_fps F z = f z) (nhds 0)" by (auto simp: has_fps_expansion_def) ultimatelyhave"eventually (\z. eval_fps (fps_const c * F) z = c * f z) (nhds 0)" by eventually_elim (simp_all add: eval_fps_mult) with assms and False show ?thesis by (auto simp: has_fps_expansion_def fps_conv_radius_cmult_left) qed auto
lemma has_fps_expansion_cmult_right [fps_expansion_intros]: fixes c :: "'a :: {banach, real_normed_div_algebra, comm_ring_1}" assumes"f has_fps_expansion F" shows"(\x. f x * c) has_fps_expansion F * fps_const c" proof - have"F * fps_const c = fps_const c * F" by (intro fps_ext) (auto simp: mult.commute) with has_fps_expansion_cmult_left [OF assms] show ?thesis by (simp add: mult.commute) qed
lemma has_fps_expansion_minus [fps_expansion_intros]: assumes"f has_fps_expansion F" shows"(\x. - f x) has_fps_expansion -F" proof - from assms have"eventually (\x. x \ eball 0 (fps_conv_radius F)) (nhds 0)" by (intro eventually_nhds_in_open) (auto simp: has_fps_expansion_def zero_ereal_def) moreoverfrom assms have"eventually (\x. eval_fps F x = f x) (nhds 0)" by (auto simp: has_fps_expansion_def) ultimatelyhave"eventually (\x. eval_fps (-F) x = -f x) (nhds 0)" by eventually_elim (auto simp: eval_fps_minus) thus ?thesis using assms by (auto simp: has_fps_expansion_def) qed
lemma has_fps_expansion_add [fps_expansion_intros]: assumes"f has_fps_expansion F""g has_fps_expansion G" shows"(\x. f x + g x) has_fps_expansion F + G" proof - from assms have"0 < min (fps_conv_radius F) (fps_conv_radius G)" by (auto simp: has_fps_expansion_def) alsohave"\ \ fps_conv_radius (F + G)" by (rule fps_conv_radius_add) finallyhave radius: "\ > 0" .
from assms have"eventually (\x. x \ eball 0 (fps_conv_radius F)) (nhds 0)" "eventually (\x. x \ eball 0 (fps_conv_radius G)) (nhds 0)" by (intro eventually_nhds_in_open; force simp: has_fps_expansion_def zero_ereal_def)+ moreoverhave"eventually (\x. eval_fps F x = f x) (nhds 0)" and"eventually (\x. eval_fps G x = g x) (nhds 0)" using assms by (auto simp: has_fps_expansion_def) ultimatelyhave"eventually (\x. eval_fps (F + G) x = f x + g x) (nhds 0)" by eventually_elim (auto simp: eval_fps_add) with radius show ?thesis by (auto simp: has_fps_expansion_def) qed
lemma has_fps_expansion_diff [fps_expansion_intros]: assumes"f has_fps_expansion F""g has_fps_expansion G" shows"(\x. f x - g x) has_fps_expansion F - G" using has_fps_expansion_add[of f F "\x. - g x""-G"] assms by (simp add: has_fps_expansion_minus)
lemma has_fps_expansion_mult [fps_expansion_intros]: fixes F G :: "'a :: {banach, real_normed_div_algebra, comm_ring_1} fps" assumes"f has_fps_expansion F""g has_fps_expansion G" shows"(\x. f x * g x) has_fps_expansion F * G" proof - from assms have"0 < min (fps_conv_radius F) (fps_conv_radius G)" by (auto simp: has_fps_expansion_def) alsohave"\ \ fps_conv_radius (F * G)" by (rule fps_conv_radius_mult) finallyhave radius: "\ > 0" .
from assms have"eventually (\x. x \ eball 0 (fps_conv_radius F)) (nhds 0)" "eventually (\x. x \ eball 0 (fps_conv_radius G)) (nhds 0)" by (intro eventually_nhds_in_open; force simp: has_fps_expansion_def zero_ereal_def)+ moreoverhave"eventually (\x. eval_fps F x = f x) (nhds 0)" and"eventually (\x. eval_fps G x = g x) (nhds 0)" using assms by (auto simp: has_fps_expansion_def) ultimatelyhave"eventually (\x. eval_fps (F * G) x = f x * g x) (nhds 0)" by eventually_elim (auto simp: eval_fps_mult) with radius show ?thesis by (auto simp: has_fps_expansion_def) qed
lemma has_fps_expansion_inverse [fps_expansion_intros]: fixes F :: "'a :: {banach, real_normed_field} fps" assumes"f has_fps_expansion F" assumes"fps_nth F 0 \ 0" shows"(\x. inverse (f x)) has_fps_expansion inverse F" proof - have radius: "fps_conv_radius (inverse F) > 0" using assms unfolding has_fps_expansion_def by (intro fps_conv_radius_inverse_pos) auto let ?R = "min (fps_conv_radius F) (fps_conv_radius (inverse F))" from assms radius have"eventually (\x. x \ eball 0 (fps_conv_radius F)) (nhds 0)" "eventually (\x. x \ eball 0 (fps_conv_radius (inverse F))) (nhds 0)" by (intro eventually_nhds_in_open; force simp: has_fps_expansion_def zero_ereal_def)+ moreoverhave"eventually (\z. eval_fps F z = f z) (nhds 0)" using assms by (auto simp: has_fps_expansion_def) ultimatelyhave"eventually (\z. eval_fps (inverse F) z = inverse (f z)) (nhds 0)" proof eventually_elim case (elim z) hence"eval_fps (inverse F * F) z = eval_fps (inverse F) z * f z" by (subst eval_fps_mult) auto alsohave"eval_fps (inverse F * F) z = 1" using assms by (simp add: inverse_mult_eq_1) finallyshow ?caseby (auto simp: field_split_simps) qed with radius show ?thesis by (auto simp: has_fps_expansion_def) qed
lemma has_fps_expansion_sum [fps_expansion_intros]: assumes"\x. x \ A \ f x has_fps_expansion F x" shows"(\z. \x\A. f x z) has_fps_expansion (\x\A. F x)" using assms by (induction A rule: infinite_finite_induct) (auto intro!: fps_expansion_intros)
lemma has_fps_expansion_prod [fps_expansion_intros]: fixes F :: "'a \ 'b :: {banach, real_normed_div_algebra, comm_ring_1} fps" assumes"\x. x \ A \ f x has_fps_expansion F x" shows"(\z. \x\A. f x z) has_fps_expansion (\x\A. F x)" using assms by (induction A rule: infinite_finite_induct) (auto intro!: fps_expansion_intros)
lemma has_fps_expansion_exp1 [fps_expansion_intros]: "(\x::'a :: {banach, real_normed_field}. exp x) has_fps_expansion fps_exp 1" using has_fps_expansion_exp[of 1] by simp
lemma has_fps_expansion_exp_neg1 [fps_expansion_intros]: "(\x::'a :: {banach, real_normed_field}. exp (-x)) has_fps_expansion fps_exp (-1)" using has_fps_expansion_exp[of "-1"] by simp
lemma has_fps_expansion_deriv [fps_expansion_intros]: assumes"f has_fps_expansion F" shows"deriv f has_fps_expansion fps_deriv F" proof - have"eventually (\z. z \ eball 0 (fps_conv_radius F)) (nhds 0)" using assms by (intro eventually_nhds_in_open)
(auto simp: has_fps_expansion_def zero_ereal_def) moreoverfrom assms have"eventually (\z. eval_fps F z = f z) (nhds 0)" by (auto simp: has_fps_expansion_def) thenobtain s where"open s""0 \ s"and s: "\w. w \ s \ eval_fps F w = f w" by (auto simp: eventually_nhds) hence"eventually (\w. w \ s) (nhds 0)" by (intro eventually_nhds_in_open) auto ultimatelyhave"eventually (\z. eval_fps (fps_deriv F) z = deriv f z) (nhds 0)" proof eventually_elim case (elim z) hence"eval_fps (fps_deriv F) z = deriv (eval_fps F) z" by (simp add: eval_fps_deriv) alsohave"eventually (\w. w \ s) (nhds z)" using elim and‹open s›by (intro eventually_nhds_in_open) auto hence"eventually (\w. eval_fps F w = f w) (nhds z)" by eventually_elim (simp add: s) hence"deriv (eval_fps F) z = deriv f z" by (intro deriv_cong_ev refl) finallyshow ?case . qed with assms and fps_conv_radius_deriv[of F] show ?thesis by (auto simp: has_fps_expansion_def) qed
lemma fps_conv_radius_binomial: fixes c :: "'a :: {real_normed_field,banach}" shows"fps_conv_radius (fps_binomial c) = (if c \ \ then \ else 1)" unfolding fps_conv_radius_def by (simp add: conv_radius_gchoose)
lemma fps_conv_radius_ln: fixes c :: "'a :: {banach, real_normed_field, field_char_0}" shows"fps_conv_radius (fps_ln c) = (if c = 0 then \ else 1)" proof (cases "c = 0") case False have"conv_radius (\n. 1 / of_nat n :: 'a) = 1" proof (rule conv_radius_ratio_limit_nonzero) show"(\n. norm (1 / of_nat n :: 'a) / norm (1 / of_nat (Suc n) :: 'a)) \ 1" using LIMSEQ_Suc_n_over_n by (simp add: norm_divide del: of_nat_Suc) qed auto alsohave"conv_radius (\n. 1 / of_nat n :: 'a) =
conv_radius (λn. if n = 0 then 0 else (- 1) ^ (n - 1) / of_nat n :: 'a)" by (intro conv_radius_cong eventually_mono[OF eventually_gt_at_top[of 0]])
(simp add: norm_mult norm_divide norm_power) finallyshow ?thesis using False unfolding fps_ln_def by (subst fps_conv_radius_cmult_left) (simp_all add: fps_conv_radius_def) qed (auto simp: fps_ln_def)
lemma fps_conv_radius_ln_nonzero [simp]: assumes"c \ (0 :: 'a :: {banach,real_normed_field,field_char_0})" shows"fps_conv_radius (fps_ln c) = 1" using assms by (simp add: fps_conv_radius_ln)
lemma fps_conv_radius_sin [simp]: fixes c :: "'a :: {banach, real_normed_field, field_char_0}" shows"fps_conv_radius (fps_sin c) = \" proof (cases "c = 0") case False have"\ = conv_radius (\n. of_real (sin_coeff n) :: 'a)" proof (rule sym, rule conv_radius_inftyI'', rule summable_norm_cancel, goal_cases) case (1 z) show ?caseusing summable_norm_sin[of z] by (simp add: norm_mult) qed alsohave"\ / norm c = conv_radius (\n. c ^ n * of_real (sin_coeff n) :: 'a)" using False by (subst conv_radius_mult_power) auto alsohave"\ = fps_conv_radius (fps_sin c)"unfolding fps_conv_radius_def by (rule conv_radius_cong_weak) (auto simp add: fps_sin_def sin_coeff_def) finallyshow ?thesis by simp qed simp_all
lemma fps_conv_radius_cos [simp]: fixes c :: "'a :: {banach, real_normed_field, field_char_0}" shows"fps_conv_radius (fps_cos c) = \" proof (cases "c = 0") case False have"\ = conv_radius (\n. of_real (cos_coeff n) :: 'a)" proof (rule sym, rule conv_radius_inftyI'', rule summable_norm_cancel, goal_cases) case (1 z) show ?caseusing summable_norm_cos[of z] by (simp add: norm_mult) qed alsohave"\ / norm c = conv_radius (\n. c ^ n * of_real (cos_coeff n) :: 'a)" using False by (subst conv_radius_mult_power) auto alsohave"\ = fps_conv_radius (fps_cos c)"unfolding fps_conv_radius_def by (rule conv_radius_cong_weak) (auto simp add: fps_cos_def cos_coeff_def) finallyshow ?thesis by simp qed simp_all
lemma eval_fps_sin [simp]: fixes z :: "'a :: {banach, real_normed_field, field_char_0}" shows"eval_fps (fps_sin c) z = sin (c * z)" proof - have"(\n. sin_coeff n *\<^sub>R (c * z) ^ n) sums sin (c * z)"by (rule sin_converges) alsohave"(\n. sin_coeff n *\<^sub>R (c * z) ^ n) = (\n. fps_nth (fps_sin c) n * z ^ n)" by (rule ext) (auto simp: sin_coeff_def fps_sin_def power_mult_distrib scaleR_conv_of_real) finallyshow ?thesis by (simp add: sums_iff eval_fps_def) qed
lemma eval_fps_cos [simp]: fixes z :: "'a :: {banach, real_normed_field, field_char_0}" shows"eval_fps (fps_cos c) z = cos (c * z)" proof - have"(\n. cos_coeff n *\<^sub>R (c * z) ^ n) sums cos (c * z)"by (rule cos_converges) alsohave"(\n. cos_coeff n *\<^sub>R (c * z) ^ n) = (\n. fps_nth (fps_cos c) n * z ^ n)" by (rule ext) (auto simp: cos_coeff_def fps_cos_def power_mult_distrib scaleR_conv_of_real) finallyshow ?thesis by (simp add: sums_iff eval_fps_def) qed
lemma cos_eq_zero_imp_norm_ge: assumes"cos (z :: complex) = 0" shows"norm z \ pi / 2" proof - from assms obtain n where"z = complex_of_real ((of_int n + 1 / 2) * pi)" by (auto simp: cos_eq_0 algebra_simps) alsohave"norm \ = \real_of_int n + 1 / 2\ * pi" by (subst norm_of_real) (simp_all add: abs_mult) alsohave"real_of_int n + 1 / 2 = of_int (2 * n + 1) / 2"by simp alsohave"\\\ = of_int \2 * n + 1\ / 2"by (subst abs_divide) simp_all alsohave"\ * pi = of_int \2 * n + 1\ * (pi / 2)"by simp alsohave"\ \ of_int 1 * (pi / 2)" by (intro mult_right_mono, subst of_int_le_iff) (auto simp: abs_if) finallyshow ?thesis by simp qed
lemma eval_fps_binomial: fixes c :: complex assumes"norm z < 1" shows"eval_fps (fps_binomial c) z = (1 + z) powr c" using gen_binomial_complex[OF assms] by (simp add: sums_iff eval_fps_def)
lemma has_fps_expansion_binomial_complex [fps_expansion_intros]: fixes c :: complex shows"(\x. (1 + x) powr c) has_fps_expansion fps_binomial c" proof - have *: "eventually (\z::complex. z \ eball 0 1) (nhds 0)" by (intro eventually_nhds_in_open) auto thus ?thesis by (auto simp: has_fps_expansion_def eval_fps_binomial fps_conv_radius_binomial
intro!: eventually_mono [OF *]) qed
lemma has_fps_expansion_sin [fps_expansion_intros]: fixes c :: "'a :: {banach, real_normed_field, field_char_0}" shows"(\x. sin (c * x)) has_fps_expansion fps_sin c" by (auto simp: has_fps_expansion_def)
lemma has_fps_expansion_sin' [fps_expansion_intros]: "(\x::'a :: {banach, real_normed_field}. sin x) has_fps_expansion fps_sin 1" using has_fps_expansion_sin[of 1] by simp
lemma has_fps_expansion_cos [fps_expansion_intros]: fixes c :: "'a :: {banach, real_normed_field, field_char_0}" shows"(\x. cos (c * x)) has_fps_expansion fps_cos c" by (auto simp: has_fps_expansion_def)
lemma has_fps_expansion_cos' [fps_expansion_intros]: "(\x::'a :: {banach, real_normed_field}. cos x) has_fps_expansion fps_cos 1" using has_fps_expansion_cos[of 1] by simp
lemma has_fps_expansion_shift [fps_expansion_intros]: fixes F :: "'a :: {banach, real_normed_field} fps" assumes"f has_fps_expansion F"and"n \ subdegree F" assumes"c = fps_nth F n" shows"(\x. if x = 0 then c else f x / x ^ n) has_fps_expansion (fps_shift n F)" proof - have"eventually (\x. x \ eball 0 (fps_conv_radius F)) (nhds 0)" using assms by (intro eventually_nhds_in_open) (auto simp: has_fps_expansion_def zero_ereal_def) moreoverhave"eventually (\x. eval_fps F x = f x) (nhds 0)" using assms by (auto simp: has_fps_expansion_def) ultimatelyhave"eventually (\x. eval_fps (fps_shift n F) x =
(if x = 0 then c else f x / x ^ n)) (nhds 0)" by eventually_elim (auto simp: eval_fps_shift assms) with assms show ?thesis by (auto simp: has_fps_expansion_def) qed
lemma has_fps_expansion_divide [fps_expansion_intros]: fixes F G :: "'a :: {banach, real_normed_field} fps" assumes"f has_fps_expansion F"and"g has_fps_expansion G"and "subdegree G \ subdegree F""G \ 0" "c = fps_nth F (subdegree G) / fps_nth G (subdegree G)" shows"(\x. if x = 0 then c else f x / g x) has_fps_expansion (F / G)" proof -
define n where"n = subdegree G"
define F' and G'where"F' = fps_shift n F"and"G' = fps_shift n G" have"F = F' * fps_X ^ n""G = G' * fps_X ^ n"unfolding F'_def G'_def n_def by (rule fps_shift_times_fps_X_power [symmetric] le_refl | fact)+ moreoverfrom assms have"fps_nth G' 0 \ 0" by (simp add: G'_def n_def) ultimatelyhave FG: "F / G = F' * inverse G'" by (simp add: fps_divide_unit)
have"(\x. (if x = 0 then fps_nth F n else f x / x ^ n) *
inverse (if x = 0 then fps_nth G n else g x / x ^ n)) has_fps_expansion F / G"
(is"?h has_fps_expansion _") unfolding FG F'_def G'_def n_def using‹G ≠ 0› by (intro has_fps_expansion_mult has_fps_expansion_inverse
has_fps_expansion_shift assms) auto alsohave"?h = (\x. if x = 0 then c else f x / g x)" using assms(5) unfolding n_def by (intro ext) (auto split: if_splits simp: field_simps) finallyshow ?thesis . qed
lemma has_fps_expansion_divide' [fps_expansion_intros]: fixes F G :: "'a :: {banach, real_normed_field} fps" assumes"f has_fps_expansion F"and"g has_fps_expansion G"and"fps_nth G 0 \ 0" shows"(\x. f x / g x) has_fps_expansion (F / G)" proof - have"(\x. if x = 0 then fps_nth F 0 / fps_nth G 0 else f x / g x) has_fps_expansion (F / G)"
(is"?h has_fps_expansion _") using assms(3) by (intro has_fps_expansion_divide assms) auto alsofrom assms have"fps_nth F 0 = f 0""fps_nth G 0 = g 0" by (auto simp: has_fps_expansion_def eval_fps_at_0 dest: eventually_nhds_x_imp_x) hence"?h = (\x. f x / g x)"by auto finallyshow ?thesis . qed
lemma has_fps_expansion_tan [fps_expansion_intros]: fixes c :: "'a :: {banach, real_normed_field, field_char_0}" shows"(\x. tan (c * x)) has_fps_expansion fps_tan c" proof - have"(\x. sin (c * x) / cos (c * x)) has_fps_expansion fps_sin c / fps_cos c" by (intro fps_expansion_intros) auto thus ?thesis by (simp add: tan_def fps_tan_def) qed
lemma has_fps_expansion_tan' [fps_expansion_intros]: "tan has_fps_expansion fps_tan (1 :: 'a :: {banach, real_normed_field, field_char_0})" using has_fps_expansion_tan[of 1] by simp
lemma has_fps_expansion_imp_holomorphic: assumes"f has_fps_expansion F" obtains s where"open s""0 \ s""f holomorphic_on s""\z. z \ s \ f z = eval_fps F z" proof - from assms obtain s where s: "open s""0 \ s""\z. z \ s \ eval_fps F z = f z" unfolding has_fps_expansion_def eventually_nhds by blast let ?s' = "eball 0 (fps_conv_radius F) \ s" have"eval_fps F holomorphic_on ?s'" by (intro holomorphic_intros) auto alsohave"?this \ f holomorphic_on ?s'" using s by (intro holomorphic_cong) auto finallyshow ?thesis using s assms by (intro that[of ?s']) (auto simp: has_fps_expansion_def zero_ereal_def) qed
lemma has_fps_expansionI: fixes f :: "'a :: {banach, real_normed_div_algebra} \ 'a" assumes"eventually (\u. (\n. fps_nth F n * u ^ n) sums f u) (nhds 0)" shows"f has_fps_expansion F" proof - from assms obtain X where X: "open X""0 \ X""\u. u \ X \ (\n. fps_nth F n * u ^ n) sums f u" unfolding eventually_nhds by blast obtain r where r: "r > 0""cball 0 r \ X" using X(1,2) open_contains_cball by blast have"0 < norm (of_real r :: 'a)" using r(1) by simp alsohave"fps_conv_radius F \ norm (of_real r :: 'a)" unfolding fps_conv_radius_def proof (rule conv_radius_geI) have"of_real r \ X" using r by auto from X(3)[OF this] show"summable (\n. fps_nth F n * of_real r ^ n)" by (simp add: sums_iff) qed finallyhave"fps_conv_radius F > 0" by (simp_all add: zero_ereal_def) moreoverhave"(\\<^sub>F z in nhds 0. eval_fps F z = f z)" using assms by eventually_elim (auto simp: sums_iff eval_fps_def) ultimatelyshow ?thesis unfolding has_fps_expansion_def .. qed
lemma fps_mult_numeral_left [simp]: "fps_nth (numeral c * f) n = numeral c * fps_nth f n" by (simp add: fps_numeral_fps_const)
end
Messung V0.5
¤ Dauer der Verarbeitung: 0.22 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.