Theory Real_Analytic
section ‹Real-Analytic ($C^\omega$) Functions in Several Variables›
text ‹
Real-analytic functions on Euclidean spaces, via convergent power series over the
multi-indices ‹ra_idx›; in one dimension this agrees with convergence of the Taylor
series. Real-analytic functions are ‹C⇧∞› and closed under the algebraic operations,
composition and linear maps, and a real-analytic function that is not identically zero on
a connected open set has a nowhere dense zero set.
›
theory Real_Analytic
imports Higher_Differentiability_Multi Infinite_Sum
begin
lemma poly_geom_summable:
fixes t :: real and p :: nat
assumes t: "0 ≤ t" "t < 1"
shows "summable (λn. real ((n+1)^p) * t ^ n)"
proof (cases "t = 0")
case True
then show ?thesis by (simp add: summable_comparison_test)
next
case False
with t have tpos: "0 < t" by simp
define c where "c = (1 + t) / 2"
have c1: "c < 1" using t by (simp add: c_def)
have ct: "t < c" using False t by (simp add: c_def)
have cpos: "0 < c" using tpos ct by simp
have base_lim: "(λn. real (n+2) / real (n+1)) ⇢ 1"
proof -
have lim1: "(λn. 1 + inverse (real (Suc n))) ⇢ 1"
by (rule LIMSEQ_inverse_real_of_nat_add)
have "(λn. real (n+2)/real(n+1)) = (λn. 1 + inverse (real (Suc n)))"
by (simp add: field_simps)
with lim1 show ?thesis by simp
qed
have ratio_lim: "(λn. real ((n+2)^p) / real ((n+1)^p)) ⇢ 1"
proof -
have "(λn. (real (n+2) / real (n+1)) ^ p) ⇢ 1 ^ p"
using base_lim by (rule tendsto_power)
moreover have "⋀n. (real (n+2)/real(n+1))^p = real((n+2)^p)/real((n+1)^p)"
by (simp add: power_divide)
ultimately show ?thesis by simp
qed
have rt: "(λn. real ((n+2)^p) / real ((n+1)^p) * t) ⇢ t"
proof -
have "(λn. real ((n+2)^p) / real ((n+1)^p) * t) ⇢ 1 * t"
using ratio_lim tendsto_const by (rule tendsto_mult)
thus ?thesis by simp
qed
have "eventually (λn. real ((n+2)^p) / real ((n+1)^p) * t < c) sequentially"
using rt ct by (intro order_tendstoD(2)) simp_all
then obtain N where N: "⋀n. n ≥ N ⟹ real ((n+2)^p) / real ((n+1)^p) * t < c"
by (auto simp: eventually_sequentially)
show ?thesis
proof (rule summable_ratio_test[where c = c and N = N])
show "c < 1" by (rule c1)
fix n assume "n ≥ N"
have ineq: "real ((n+2)^p) / real ((n+1)^p) * t ≤ c" using N[OF ‹n≥N›] by simp
have pos1: "(0::real) < real ((n+1)^p)" by simp
have key: "real ((n+2)^p) * t^(n+1) ≤ c * (real ((n+1)^p) * t^n)"
proof -
have "real ((n+2)^p) * t^(n+1)
= (real ((n+2)^p) / real ((n+1)^p) * t) * (real ((n+1)^p) * t^n)"
using pos1 tpos by (simp add: field_simps)
also have "… ≤ c * (real ((n+1)^p) * t^n)"
using ineq pos1 tpos by (intro mult_right_mono) (auto simp: zero_le_mult_iff)
finally show ?thesis .
qed
have tnn: "0 ≤ t ^ n" "0 ≤ t ^ (n+1)" using t by (auto intro: zero_le_power)
have nn1: "0 ≤ real ((n+1)^p) * t^n" using tnn by simp
have nn2: "0 ≤ real ((n+2)^p) * t^(n+1)" using tnn by simp
have e1: "real ((Suc n + 1) ^ p) * t ^ Suc n = real ((n+2)^p) * t^(n+1)" by simp
have "norm (real ((Suc n + 1) ^ p) * t ^ Suc n) = real ((n+2)^p) * t^(n+1)"
using nn2 by (simp only: e1 real_norm_def abs_of_nonneg)
also have "… ≤ c * (real ((n+1)^p) * t^n)" by (rule key)
also have "… = c * norm (real ((n + 1) ^ p) * t ^ n)"
using nn1 by (simp only: real_norm_def abs_of_nonneg)
finally show "norm (real ((Suc n + 1) ^ p) * t ^ Suc n) ≤ c * norm (real ((n + 1) ^ p) * t ^ n)" .
qed
qed
subsection ‹$C^\infty$ smoothness (infinitely many continuous derivatives)›
definition Cinfinity_at ::
"('a::real_normed_vector ⇒ 'b::real_normed_vector) ⇒ 'a ⇒ bool" where
"Cinfinity_at f x ⟷ (∀k. Ck_at k f x)"
definition Cinfinity_on ::
"('a::real_normed_vector ⇒ 'b::real_normed_vector) ⇒ 'a set ⇒ bool" where
"Cinfinity_on f U ⟷ open U ∧ (∀x∈U. Cinfinity_at f x)"
lemma Cinfinity_imp_Ck: "Cinfinity_at f x ⟹ Ck_at k f x"
unfolding Cinfinity_at_def by blast
lemma Cinfinity_on_imp_Ck_on: "Cinfinity_on f U ⟹ Ck_on k f U"
unfolding Cinfinity_on_def Ck_on_def Cinfinity_at_def by blast
subsection ‹One-dimensional real analyticity via the Peano/Taylor expansion›
text ‹‹f› is real-analytic at ‹c› if, near ‹c›, it is smooth and its Taylor series converges
to it.›
definition real_analytic_at_1d :: "(real ⇒ real) ⇒ real ⇒ bool" where
"real_analytic_at_1d f c ⟷
(∃r>0. (∀x. ¦x - c¦ < r ⟶ (∀n. f n-times_differentiable_at x))
∧ (∀x. ¦x - c¦ < r ⟶
(λn. (deriv ^^ n) f c / fact n * (x - c) ^ n) sums f x))"
subsection ‹Multivariate real analyticity (local convergent power series)›
text ‹The basis monomial (a product over the Euclidean basis) and the finitely-supported multi-indices.›
definition ra_monomial :: "'a::euclidean_space ⇒ ('a ⇒ nat) ⇒ real" where
"ra_monomial h α = (∏b∈Basis. (h ∙ b) ^ (α b))"
definition ra_idx :: "('a::euclidean_space ⇒ nat) set" where
"ra_idx = {α. {b. α b ≠ 0} ⊆ Basis}"
definition real_analytic_on ::
"('a::euclidean_space ⇒ 'b::real_normed_vector) ⇒ 'a set ⇒ bool" where
"real_analytic_on f U ⟷ open U ∧
(∀x0∈U. ∃r>0. ∃c. ∀x. dist x x0 < r ⟶
((λα. ra_monomial (x - x0) α *⇩R c α) has_sum f x) ra_idx)"
text ‹On the line, the multivariate notion coincides with the Peano/Taylor one.›
lemma real_analytic_on_1d_iff:
fixes f :: "real ⇒ real"
shows "real_analytic_on f U ⟷ open U ∧ (∀c∈U. real_analytic_at_1d f c)"
proof -
define i :: "nat ⇒ (real ⇒ nat)" where "i = (λn b. if b = 1 then n else 0)"
define j :: "(real ⇒ nat) ⇒ nat" where "j = (λα. α 1)"
have ij: "i (j α) = α" if "α ∈ ra_idx" for α
proof (rule ext)
fix b :: real
show "i (j α) b = α b"
proof (cases "b = 1")
case True thus ?thesis by (simp add: i_def j_def)
next
case False
with that have "α b = 0" by (auto simp: ra_idx_def)
with False show ?thesis by (simp add: i_def)
qed
qed
have ji: "j (i n) = n" for n by (simp add: i_def j_def)
have i_idx: "i n ∈ ra_idx" for n by (auto simp: i_def ra_idx_def)
have iev: "i n 1 = n" for n by (simp add: i_def)
have mono: "ra_monomial h α = h ^ (α 1)" for h :: real and α
by (simp add: ra_monomial_def)
have reindex:
"((λn. (deriv ^^ n) f c0 / fact n * (x - c0) ^ n) has_sum s) (UNIV :: nat set)
= ((λα. ra_monomial (x - c0) α *⇩R (λβ. (deriv ^^ (β 1)) f c0 / fact (β 1)) α)
has_sum s) ra_idx"
for c0 x s
by (rule has_sum_reindex_bij_witness[where i = j and j = i])
(auto simp: ji i_idx ij mono iev mult.commute)
show ?thesis
proof
assume A: "real_analytic_on f U"
then have oU: "open U" by (simp only: real_analytic_on_def)
have "real_analytic_at_1d f c" if cU: "c ∈ U" for c
proof -
from A cU obtain r cc where r: "0 < r"
and HS: "⋀x. dist x c < r ⟹
((λα. ra_monomial (x - c) α *⇩R cc α) has_sum f x) ra_idx"
unfolding real_analytic_on_def by blast
have sums_xc: "(λn. cc (i n) * (x - c) ^ n) sums f x" if "dist x c < r" for x
proof -
have "((λn. cc (i n) * (x - c) ^ n) has_sum f x) (UNIV :: nat set)
= ((λα. ra_monomial (x - c) α *⇩R cc α) has_sum f x) ra_idx"
by (rule has_sum_reindex_bij_witness[where i = j and j = i])
(auto simp: ji i_idx ij mono iev mult.commute)
with HS[OF that] have
"((λn. cc (i n) * (x - c) ^ n) has_sum f x) (UNIV :: nat set)" by simp
thus ?thesis by (rule has_sum_imp_sums)
qed
define a where "a = (λn. cc (i n))"
have sums_a: "(λn. a n * z ^ n) sums f (c + z)" if "¦z¦ < r" for z
proof -
have "dist (c + z) c < r" using that by (simp only: dist_real_def)
from sums_xc[OF this] show ?thesis by (simp add: a_def)
qed
have summ_a: "summable (λn. a n * z ^ n)" if "¦z¦ < r" for z
using sums_a[OF that] by (rule sums_summable)
have summ_diffs: "summable (λm. (diffs ^^ n) a m * z ^ m)" if "¦z¦ < r" for n z
using that
proof (induction n arbitrary: z)
case 0
thus ?case using summ_a by simp
next
case (Suc n)
have "summable (λm. diffs ((diffs ^^ n) a) m * z ^ m)"
proof (rule termdiff_converges[where K = r])
show "norm z < r" using Suc.prems by simp
fix w :: real assume "norm w < r"
hence "¦w¦ < r" by simp
thus "summable (λm. (diffs ^^ n) a m * w ^ m)" by (rule Suc.IH)
qed
thus ?case by simp
qed
define S where "S = (λn y. ∑m. (diffs ^^ n) a m * (y - c) ^ m)"
have S0_eq_f: "S 0 x = f x" if "¦x - c¦ < r" for x
proof -
from sums_a[of "x - c"] that have "(λn. a n * (x - c) ^ n) sums f x" by simp
thus ?thesis by (simp add: S_def sums_iff)
qed
have S_deriv: "(S n has_field_derivative S (Suc n) x) (at x)"
if "¦x - c¦ < r" for n x
proof -
have H: "((λw. ∑m. (diffs ^^ n) a m * w ^ m)
has_field_derivative (∑m. diffs ((diffs ^^ n) a) m * (x - c) ^ m))
(at (x - c))"
proof (rule termdiffs_strong'[where K = r])
fix w :: real assume "norm w < r"
thus "summable (λm. (diffs ^^ n) a m * w ^ m)" using summ_diffs by simp
next
show "norm (x - c) < r" using that by simp
qed
have shift: "((λy. y - c) has_field_derivative 1) (at x)"
by (auto intro!: derivative_eq_intros)
have "((λy. (λw. ∑m. (diffs ^^ n) a m * w ^ m) (y - c))
has_field_derivative
(∑m. diffs ((diffs ^^ n) a) m * (x - c) ^ m) * 1) (at x)"
by (rule DERIV_chain'[OF shift]) (use H in simp)
thus ?thesis by (simp add: S_def)
qed
have main: "∀x. ¦x - c¦ < r ⟶
f n-times_differentiable_at x ∧ (deriv ^^ n) f x = S n x" for n
proof (induction n)
case 0
show ?case by (auto simp: S0_eq_f)
next
case (Suc n)
show ?case
proof (intro allI impI conjI)
fix x assume xc: "¦x - c¦ < r"
have ballopen: "{y. ¦y - c¦ < r} = ball c r"
by (auto simp: dist_real_def abs_minus_commute)
have eqA: "(deriv ^^ n) f y = S n y" if "¦y - c¦ < r" for y
using Suc.IH that by blast
have dn_deriv: "((deriv ^^ n) f has_field_derivative S (Suc n) x) (at x)"
proof (rule has_field_derivative_transform_within_open
[where f = "S n" and S = "{y. ¦y - c¦ < r}"])
show "(S n has_field_derivative S (Suc n) x) (at x)" by (rule S_deriv[OF xc])
show "open {y. ¦y - c¦ < r}" by (simp add: ballopen)
show "x ∈ {y. ¦y - c¦ < r}" using xc by simp
show "⋀y. y ∈ {y. ¦y - c¦ < r} ⟹ S n y = (deriv ^^ n) f y"
using eqA by auto
qed
show "(deriv ^^ Suc n) f x = S (Suc n) x"
using dn_deriv by (simp only: kth_deriv_simps(2) DERIV_imp_deriv)
show "f (Suc n)-times_differentiable_at x"
unfolding k_times_differentiable_at.simps(2)
proof
show "∃ε>0. ∀y. ¦y - x¦ < ε ⟶ f n-times_differentiable_at y"
proof (intro exI[where x = "r - ¦x - c¦"] conjI allI impI)
show "0 < r - ¦x - c¦" using xc by simp
fix y assume "¦y - x¦ < r - ¦x - c¦"
hence "¦y - c¦ < r" by linarith
thus "f n-times_differentiable_at y" using Suc.IH by blast
qed
next
have "(deriv ^^ Suc n) f x = S (Suc n) x"
using dn_deriv by (simp only: kth_deriv_simps(2) DERIV_imp_deriv)
with dn_deriv
show "((deriv ^^ n) f has_derivative (λh. (deriv ^^ Suc n) f x * h)) (at x)"
by (simp only: has_field_derivative_def)
qed
qed
qed
have diffs_fact: "(diffs ^^ n) g 0 = fact n * g n" for n and g :: "nat ⇒ real"
proof -
have gen: "fact m * (diffs ^^ n) g m = fact (m + n) * g (m + n)" for m
proof (induction n arbitrary: g m)
case 0 show ?case by simp
next
case (Suc n)
have "fact m * (diffs ^^ Suc n) g m = fact m * (diffs ^^ n) (diffs g) m"
by (simp only: funpow_Suc_right o_apply)
also have "… = fact (m + n) * (diffs g) (m + n)"
using Suc.IH[of m "diffs g"] by simp
also have "… = fact (m + n) * (of_nat (Suc (m + n)) * g (Suc (m + n)))"
by (simp only: diffs_def)
also have "… = fact (Suc (m + n)) * g (Suc (m + n))"
by (simp add: algebra_simps)
finally show ?case by (simp add: add.commute)
qed
from gen[of 0] show ?thesis by simp
qed
have coeff: "cc (i n) = (deriv ^^ n) f c / fact n" for n
proof -
have "¦c - c¦ < r" using r by simp
with main[of n] have "(deriv ^^ n) f c = S n c" by blast
also have "S n c = (diffs ^^ n) a 0" by (simp add: S_def)
also have "… = fact n * a n" by (rule diffs_fact)
finally have "(deriv ^^ n) f c = fact n * a n" .
thus ?thesis by (simp add: a_def)
qed
have smooth: "f n-times_differentiable_at x" if "¦x - c¦ < r" for x n
using main[of n] that by blast
show ?thesis
unfolding real_analytic_at_1d_def
proof (intro exI[where x = r] conjI allI impI)
show "0 < r" by (rule r)
next
fix x n assume "¦x - c¦ < r" thus "f n-times_differentiable_at x"
by (rule smooth)
next
fix x assume "¦x - c¦ < r"
then have "dist x c < r" by (simp only: dist_real_def)
from sums_xc[OF this] show
"(λn. (deriv ^^ n) f c / fact n * (x - c) ^ n) sums f x"
by (simp only: coeff mult.commute)
qed
qed
with oU show "open U ∧ (∀c∈U. real_analytic_at_1d f c)" by blast
next
assume B: "open U ∧ (∀c∈U. real_analytic_at_1d f c)"
then have oU: "open U" and AT: "⋀c. c ∈ U ⟹ real_analytic_at_1d f c" by auto
show "real_analytic_on f U"
unfolding real_analytic_on_def
proof (intro conjI ballI)
show "open U" by (rule oU)
next
fix c assume cU: "c ∈ U"
from AT[OF cU] obtain r where r: "0 < r"
and TS: "⋀x. ¦x - c¦ < r ⟹
(λn. (deriv ^^ n) f c / fact n * (x - c) ^ n) sums f x"
unfolding real_analytic_at_1d_def by blast
show "∃r>0. ∃cc. ∀x. dist x c < r ⟶
((λα. ra_monomial (x - c) α *⇩R cc α) has_sum f x) ra_idx"
proof (intro exI[where x = r] exI[where x = "λβ. (deriv ^^ (β 1)) f c / fact (β 1)"]
conjI allI impI)
show "0 < r" by (rule r)
next
fix x assume dx: "dist x c < r"
then have axc: "¦x - c¦ < r" by (simp only: dist_real_def)
define d where "d = (¦x - c¦ + r) / 2"
define x1 where "x1 = c + d"
have d_pos: "0 < d"
proof -
have "0 < ¦x - c¦ + r" using r by linarith
thus ?thesis unfolding d_def by simp
qed
have x1c: "¦x1 - c¦ = d" using d_pos by (simp only: x1_def)
have x1_in: "¦x1 - c¦ < r"
proof -
have "¦x - c¦ + r < 2 * r" using axc by linarith
thus ?thesis unfolding x1c d_def by simp
qed
have lt: "¦x - c¦ < ¦x1 - c¦"
proof -
define a where "a = ¦x - c¦"
have ar: "a < r" using axc by (simp only: a_def)
have "a * 2 < a + r" using ar by linarith
hence "a < (a + r) / 2" by (simp only: field_simps)
thus ?thesis by (simp only: x1c d_def a_def)
qed
have sm1: "summable (λn. (deriv ^^ n) f c / fact n * (x1 - c) ^ n)"
using TS[OF x1_in] by (rule sums_summable)
have absum: "summable (λn. norm ((deriv ^^ n) f c / fact n * (x - c) ^ n))"
by (rule powser_insidea[OF sm1]) (use lt in simp)
have HSnat: "((λn. (deriv ^^ n) f c / fact n * (x - c) ^ n) has_sum f x) (UNIV :: nat set)"
by (rule norm_summable_imp_has_sum[OF absum TS[OF axc]])
show "((λα. ra_monomial (x - c) α *⇩R (λβ. (deriv ^^ (β 1)) f c / fact (β 1)) α)
has_sum f x) ra_idx"
using HSnat by (simp only: reindex[of c x "f x"])
qed
qed
qed
qed
subsection ‹Multivariate power-series differentiation›
definition ra_inc ::
"('a ⇒ nat) ⇒ 'a ⇒ ('a ⇒ nat)" where
"ra_inc α b = α(b := Suc (α b))"
definition ra_Dmonomial ::
"'a::euclidean_space ⇒ ('a ⇒ nat) ⇒ 'a ⇒ real" where
"ra_Dmonomial x α v =
(∑b∈Basis.
real (α b) * (v ∙ b) *
(x ∙ b) ^ (α b - 1) *
(∏d∈Basis - {b}. (x ∙ d) ^ (α d)))"
definition ra_dcoeff ::
"(('a::euclidean_space ⇒ nat) ⇒ 'b::real_normed_vector) ⇒
'a ⇒ ('a ⇒ nat) ⇒ 'b" where
"ra_dcoeff c v α =
(∑b∈Basis.
(real (Suc (α b)) * (v ∙ b)) *⇩R
c (ra_inc α b))"
definition ra_deg :: "('a::euclidean_space ⇒ nat) ⇒ nat" where
"ra_deg α = (∑b∈Basis. α b)"
subsection ‹Per-term Fréchet derivative›
lemma ra_monomial_has_derivative:
fixes x :: "'a::euclidean_space"
shows
"((λy. ra_monomial y α) has_derivative
(ra_Dmonomial x α))
(at x)"
proof -
have factor_deriv:
"((λy. (y ∙ b) ^ (α b)) has_derivative
(λv. real (α b) * (v ∙ b) * (x ∙ b) ^ (α b - 1))) (at x)"
if "b ∈ Basis" for b
proof -
have inner_d: "((λy. y ∙ b) has_derivative (λv. v ∙ b)) (at x)"
using has_derivative_inner_left[OF has_derivative_id] by simp
show "((λy. (y ∙ b) ^ (α b)) has_derivative
(λv. real (α b) * (v ∙ b) * (x ∙ b) ^ (α b - 1))) (at x)"
using has_derivative_power[OF inner_d, of "α b"] by simp
qed
have prod_d:
"((λy. ∏b∈Basis. (y ∙ b) ^ (α b)) has_derivative
(λv. ∑b∈Basis.
(real (α b) * (v ∙ b) * (x ∙ b) ^ (α b - 1)) *
(∏c∈Basis - {b}. (x ∙ c) ^ (α c)))) (at x)"
by (rule has_derivative_prod[OF factor_deriv])
have eq1: "(λy. ra_monomial y α) = (λy. ∏b∈Basis. (y ∙ b) ^ (α b))"
by (simp only: ra_monomial_def)
have eq2: "ra_Dmonomial x α =
(λv. ∑b∈Basis.
(real (α b) * (v ∙ b) * (x ∙ b) ^ (α b - 1)) *
(∏c∈Basis - {b}. (x ∙ c) ^ (α c)))"
by (rule ext)
(simp only: ra_Dmonomial_def mult.commute mult.left_commute mult.assoc)
show ?thesis
using prod_d unfolding eq1 eq2 .
qed
lemma ra_term_has_derivative:
fixes x :: "'a::euclidean_space"
and c :: "('a ⇒ nat) ⇒ 'b::real_normed_vector"
shows
"((λy. ra_monomial y α *⇩R c α) has_derivative
(λv. ra_Dmonomial x α v *⇩R c α))
(at x)"
by (rule has_derivative_scaleR_left[OF ra_monomial_has_derivative])
lemma ra_shifted_term_has_derivative:
fixes x x0 :: "'a::euclidean_space"
and c :: "('a ⇒ nat) ⇒ 'b::real_normed_vector"
shows
"((λy. ra_monomial (y - x0) α *⇩R c α) has_derivative
(λv. ra_Dmonomial (x - x0) α v *⇩R c α))
(at x)"
proof -
have shift: "((λy. y - x0) has_derivative (λv. v)) (at x)"
using has_derivative_diff[OF has_derivative_id has_derivative_const, of x0 "at x"]
by simp
have term_at: "((λz. ra_monomial z α *⇩R c α) has_derivative
(λv. ra_Dmonomial (x - x0) α v *⇩R c α)) (at (x - x0))"
by (rule ra_term_has_derivative)
show ?thesis
using has_derivative_compose[OF shift term_at] by simp
qed
subsection ‹One-dimensional power-series infrastructure›
lemma ra_lev_finite:
fixes n :: nat
shows "finite {α::'a::euclidean_space ⇒ nat. α ∈ ra_idx ∧ ra_deg α = n}"
proof -
have "{α::'a ⇒ nat. α ∈ ra_idx ∧ ra_deg α = n}
⊆ {hh. ∀x::'a. (x ∈ Basis ⟶ hh x ∈ {0..n}) ∧ (x ∉ Basis ⟶ hh x = 0)}"
proof (rule subsetI)
fix α :: "'a ⇒ nat" assume "α ∈ {α. α ∈ ra_idx ∧ ra_deg α = n}"
then have a1: "α ∈ ra_idx" and a2: "ra_deg α = n" by auto
have "∀x::'a. (x ∈ Basis ⟶ α x ∈ {0..n}) ∧ (x ∉ Basis ⟶ α x = 0)"
proof (intro allI conjI impI)
fix x :: 'a assume xB: "x ∈ Basis"
have "α x ≤ (∑b∈Basis. α b)"
by (rule member_le_sum[OF xB]) auto
also have "… = n" using a2 by (simp only: ra_deg_def)
finally show "α x ∈ {0..n}" by simp
next
fix x :: 'a assume "x ∉ Basis"
with a1 show "α x = 0" by (auto simp: ra_idx_def)
qed
thus "α ∈ {hh. ∀x::'a. (x ∈ Basis ⟶ hh x ∈ {0..n}) ∧ (x ∉ Basis ⟶ hh x = 0)}"
by simp
qed
moreover have "finite {hh::'a⇒nat. ∀x. (x ∈ Basis ⟶ hh x ∈ {0..n}) ∧ (x ∉ Basis ⟶ hh x = (0::nat))}"
by (rule finite_set_of_finite_funs) auto
ultimately show ?thesis by (rule finite_subset)
qed
lemma ra_lev_card_le:
fixes n :: nat
shows "card {α::'a::euclidean_space ⇒ nat. α ∈ ra_idx ∧ ra_deg α = n}
≤ (n+1) ^ card (Basis :: 'a set)"
proof -
define G where "G = {hh::'a⇒nat. ∀x. (x ∈ Basis ⟶ hh x ∈ {0..n}) ∧ (x ∉ Basis ⟶ hh x = 0)}"
have sub: "{α::'a ⇒ nat. α ∈ ra_idx ∧ ra_deg α = n} ⊆ G"
proof (rule subsetI)
fix α :: "'a ⇒ nat" assume "α ∈ {α. α ∈ ra_idx ∧ ra_deg α = n}"
then have a1: "α ∈ ra_idx" and a2: "ra_deg α = n" by auto
have "∀x::'a. (x ∈ Basis ⟶ α x ∈ {0..n}) ∧ (x ∉ Basis ⟶ α x = 0)"
proof (intro allI conjI impI)
fix x :: 'a assume xB: "x ∈ Basis"
have "α x ≤ (∑b∈Basis. α b)" by (rule member_le_sum[OF xB]) auto
also have "… = n" using a2 by (simp add: ra_deg_def)
finally show "α x ∈ {0..n}" by simp
next
fix x :: 'a assume "x ∉ Basis"
with a1 show "α x = 0" by (auto simp: ra_idx_def)
qed
thus "α ∈ G" by (simp add: G_def)
qed
have finG: "finite G" unfolding G_def
by (rule finite_set_of_finite_funs) auto
define R where "R = (λhh::'a⇒nat. restrict hh (Basis :: 'a set))"
have Rinj: "inj_on R G"
proof (rule inj_onI)
fix x y assume xG: "x ∈ G" and yG: "y ∈ G" and Rxy: "R x = R y"
show "x = y"
proof (rule ext)
fix b :: 'a
show "x b = y b"
proof (cases "b ∈ Basis")
case True
have "restrict x Basis b = restrict y Basis b" using Rxy by (simp add: R_def)
thus ?thesis using True by (simp add: restrict_def)
next
case False
with xG yG show ?thesis by (simp add: G_def)
qed
qed
qed
have Rimg: "R ` G ⊆ (Basis :: 'a set) →⇩E {0..n}"
proof
fix g assume "g ∈ R ` G"
then obtain hh where hh: "hh ∈ G" and g: "g = R hh" by auto
have "g ∈ extensional Basis" using g by (simp add: R_def)
moreover have "g ∈ Basis → {0..n}"
using hh g by (auto simp: G_def R_def restrict_def)
ultimately show "g ∈ (Basis :: 'a set) →⇩E {0..n}"
by (auto simp: PiE_def)
qed
have cardG: "card G ≤ (n+1) ^ card (Basis :: 'a set)"
proof -
have finPiE: "finite ((Basis :: 'a set) →⇩E {0..n})"
by (rule finite_PiE) auto
have "card G = card (R ` G)" by (rule card_image[symmetric, OF Rinj])
also have "… ≤ card ((Basis :: 'a set) →⇩E {0..n})"
by (rule card_mono[OF finPiE Rimg])
also have "… = card {0..n} ^ card (Basis :: 'a set)"
by (rule card_funcsetE) simp
also have "… = (n+1) ^ card (Basis :: 'a set)" by simp
finally show ?thesis .
qed
have "card {α::'a ⇒ nat. α ∈ ra_idx ∧ ra_deg α = n} ≤ card G"
by (rule card_mono[OF finG sub])
with cardG show ?thesis by linarith
qed
subsection ‹Coefficient bound›
lemma ra_coeff_bound:
fixes c :: "('a::euclidean_space ⇒ nat) ⇒ 'b::real_normed_vector"
assumes r: "0 < r"
and HS: "⋀z. dist z x0 < r ⟹
((λα. ra_monomial (z - x0) α *⇩R c α) has_sum F z) ra_idx"
and ρpos: "0 < ρ"
and corner: "ρ * norm (∑b∈(Basis::'a set). b) < r"
obtains M where "M ≥ 0"
and "⋀α. α ∈ ra_idx ⟹ norm (c α) ≤ M / ρ ^ (ra_deg α)"
proof -
define e :: 'a where "e = (∑b∈(Basis::'a set). b)"
define zc where "zc = x0 + ρ *⇩R e"
have dist_zc: "dist zc x0 < r"
proof -
have "dist zc x0 = norm (ρ *⇩R e)" by (simp add: zc_def dist_norm)
also have "… = ρ * norm e" using ρpos by simp
also have "… < r" using corner by (simp add: e_def)
finally show ?thesis .
qed
have mono_zc: "ra_monomial (zc - x0) α = ρ ^ (ra_deg α)" if "α ∈ ra_idx" for α
proof -
have inner_e: "e ∙ b = 1" if "b ∈ (Basis::'a set)" for b
using that by (simp add: e_def inner_sum_left inner_Basis)
have "ra_monomial (zc - x0) α = (∏b∈Basis. ((ρ *⇩R e) ∙ b) ^ (α b))"
by (simp add: ra_monomial_def zc_def)
also have "… = (∏b∈(Basis::'a set). ρ ^ (α b))"
by (rule prod.cong, auto simp: inner_e)
also have "… = ρ ^ (∑b∈(Basis::'a set). α b)"
by (simp add: power_sum)
finally show ?thesis by (simp add: ra_deg_def)
qed
obtain M0 where Mnn: "M0 ≥ 0"
and bound: "⋀α. α ∈ ra_idx ⟹ norm (ra_monomial (zc - x0) α *⇩R c α) ≤ M0"
using has_sum_imp_bounded_terms[OF HS[OF dist_zc]] by blast
have final: "norm (c α) ≤ M0 / ρ ^ (ra_deg α)" if a: "α ∈ ra_idx" for α
proof -
have pos: "0 < ρ ^ (ra_deg α)" using ρpos by simp
have "ρ ^ (ra_deg α) * norm (c α)
= norm (ra_monomial (zc - x0) α *⇩R c α)"
using mono_zc[OF a] ρpos by simp
also have "… ≤ M0" by (rule bound[OF a])
finally have "ρ ^ (ra_deg α) * norm (c α) ≤ M0" .
thus ?thesis using pos by (simp add: mult.commute pos_le_divide_eq)
qed
show ?thesis by (rule that[OF Mnn final])
qed
lemma ra_monomial_norm_le:
fixes h :: "'a::euclidean_space"
assumes "α ∈ ra_idx"
shows "¦ra_monomial h α¦ ≤ norm h ^ (ra_deg α)"
proof -
have factor: "¦(h ∙ b) ^ (α b)¦ ≤ norm h ^ (α b)" if "b ∈ (Basis::'a set)" for b
proof -
have "¦(h ∙ b) ^ (α b)¦ = ¦h ∙ b¦ ^ (α b)" by (simp add: power_abs)
also have "… ≤ norm h ^ (α b)"
proof (rule power_mono)
have "¦h ∙ b¦ ≤ norm h * norm b" by (rule Cauchy_Schwarz_ineq2)
thus "¦h ∙ b¦ ≤ norm h" using that by simp
show "0 ≤ ¦h ∙ b¦" by simp
qed
finally show ?thesis .
qed
have "¦ra_monomial h α¦ = ¦∏b∈Basis. (h ∙ b) ^ (α b)¦"
by (simp add: ra_monomial_def)
also have "… = (∏b∈Basis. ¦(h ∙ b) ^ (α b)¦)"
by (simp add: abs_prod)
also have "… ≤ (∏b∈(Basis::'a set). norm h ^ (α b))"
by (rule prod_mono) (auto simp: factor)
also have "… = norm h ^ (∑b∈(Basis::'a set). α b)"
by (simp add: power_sum)
finally show ?thesis by (simp add: ra_deg_def)
qed
subsection ‹Directional-derivative monomial norm bound›
text ‹A uniform bound on @{const ra_Dmonomial}.›
lemma ra_Dmonomial_norm_le:
fixes h v :: "'a::euclidean_space"
assumes a: "α ∈ ra_idx" and s1: "1 ≤ s" and hs: "norm h ≤ s"
shows "¦ra_Dmonomial h α v¦ ≤ norm v * real (ra_deg α) * s ^ (ra_deg α)"
proof -
have spos: "0 ≤ s" using s1 by simp
have hb: "¦h ∙ b¦ ≤ s" if "b ∈ (Basis::'a set)" for b
proof -
have "¦h ∙ b¦ ≤ norm h * norm b" by (rule Cauchy_Schwarz_ineq2)
also have "… = norm h" using that by simp
also have "… ≤ s" by (rule hs)
finally show ?thesis .
qed
have vb: "¦v ∙ b¦ ≤ norm v" if "b ∈ (Basis::'a set)" for b
proof -
have "¦v ∙ b¦ ≤ norm v * norm b" by (rule Cauchy_Schwarz_ineq2)
thus ?thesis using that by simp
qed
have term_le:
"¦real (α b) * (v ∙ b) * (h ∙ b) ^ (α b - 1) *
(∏d∈Basis - {b}. (h ∙ d) ^ (α d))¦
≤ norm v * real (α b) * s ^ (ra_deg α)"
if bB: "b ∈ (Basis::'a set)" for b
proof -
have e1: "¦(h ∙ b) ^ (α b - 1)¦ ≤ s ^ (α b - 1)"
proof -
have "¦(h ∙ b) ^ (α b - 1)¦ = ¦h ∙ b¦ ^ (α b - 1)" by (simp add: power_abs)
also have "… ≤ s ^ (α b - 1)" using hb[OF bB] by (intro power_mono) auto
finally show ?thesis .
qed
have e2: "¦∏d∈Basis - {b}. (h ∙ d) ^ (α d)¦ ≤ (∏d∈Basis - {b}. s ^ (α d))"
proof -
have "¦∏d∈Basis - {b}. (h ∙ d) ^ (α d)¦
= (∏d∈Basis - {b}. ¦(h ∙ d) ^ (α d)¦)" by (simp add: abs_prod)
also have "… ≤ (∏d∈Basis - {b}. s ^ (α d))"
proof (rule prod_mono, intro conjI)
fix d assume dB: "d ∈ Basis - {b}"
show "0 ≤ ¦(h ∙ d) ^ (α d)¦" by simp
have "¦(h ∙ d) ^ (α d)¦ = ¦h ∙ d¦ ^ (α d)" by (simp add: power_abs)
also have "… ≤ s ^ (α d)" using hb dB by (intro power_mono) auto
finally show "¦(h ∙ d) ^ (α d)¦ ≤ s ^ (α d)" .
qed
finally show ?thesis .
qed
have prod_s: "s ^ (α b - 1) * (∏d∈Basis - {b}. s ^ (α d)) ≤ s ^ (ra_deg α)"
proof -
have deg_split: "ra_deg α = α b + (∑d∈Basis - {b}. α d)"
using bB by (simp add: ra_deg_def sum.remove[where x = b])
have powsum: "(∏d∈Basis - {b}. s ^ (α d)) = s ^ (∑d∈Basis - {b}. α d)"
by (simp add: power_sum)
have "s ^ (α b - 1) * (∏d∈Basis - {b}. s ^ (α d))
= s ^ ((α b - 1) + (∑d∈Basis - {b}. α d))"
by (simp add: powsum power_add)
also have "… ≤ s ^ (ra_deg α)"
proof (rule power_increasing)
show "(α b - 1) + (∑d∈Basis - {b}. α d) ≤ ra_deg α"
using deg_split by simp
show "1 ≤ s" by (rule s1)
qed
finally show ?thesis .
qed
have vbb: "¦v ∙ b¦ ≤ norm v" by (rule vb[OF bB])
have nv0: "0 ≤ norm v" by simp
have absprod_nn: "0 ≤ ¦∏d∈Basis - {b}. (h ∙ d) ^ (α d)¦" by simp
have abspow_nn: "0 ≤ ¦(h ∙ b) ^ (α b - 1)¦" by simp
have sprod_nn: "0 ≤ (∏d∈Basis - {b}. s ^ (α d))" using spos by (simp add: prod_nonneg)
have spow_nn: "0 ≤ s ^ (α b - 1)" using spos by simp
have "¦real (α b) * (v ∙ b) * (h ∙ b) ^ (α b - 1) *
(∏d∈Basis - {b}. (h ∙ d) ^ (α d))¦
= real (α b) * (¦v ∙ b¦ * (¦(h ∙ b) ^ (α b - 1)¦ *
¦∏d∈Basis - {b}. (h ∙ d) ^ (α d)¦))"
by (simp add: abs_mult mult.assoc)
also have "… ≤ real (α b) * (norm v * (s ^ (α b - 1) * (∏d∈Basis - {b}. s ^ (α d))))"
proof (rule mult_left_mono)
have "¦v ∙ b¦ * (¦(h ∙ b) ^ (α b - 1)¦ * ¦∏d∈Basis - {b}. (h ∙ d) ^ (α d)¦)
≤ norm v * (s ^ (α b - 1) * (∏d∈Basis - {b}. s ^ (α d)))"
proof (rule mult_mono)
show "¦v ∙ b¦ ≤ norm v" by (rule vbb)
show "¦(h ∙ b) ^ (α b - 1)¦ * ¦∏d∈Basis - {b}. (h ∙ d) ^ (α d)¦
≤ s ^ (α b - 1) * (∏d∈Basis - {b}. s ^ (α d))"
by (rule mult_mono[OF e1 e2 spow_nn absprod_nn])
show "0 ≤ norm v" by simp
show "0 ≤ ¦(h ∙ b) ^ (α b - 1)¦ * ¦∏d∈Basis - {b}. (h ∙ d) ^ (α d)¦"
by simp
qed
thus "¦v ∙ b¦ * (¦(h ∙ b) ^ (α b - 1)¦ * ¦∏d∈Basis - {b}. (h ∙ d) ^ (α d)¦)
≤ norm v * (s ^ (α b - 1) * (∏d∈Basis - {b}. s ^ (α d)))" .
show "0 ≤ real (α b)" by simp
qed
also have "… = norm v * real (α b) * (s ^ (α b - 1) * (∏d∈Basis - {b}. s ^ (α d)))"
by (simp add: mult.commute mult.left_commute mult.assoc)
also have "… ≤ norm v * real (α b) * s ^ (ra_deg α)"
proof (rule mult_left_mono[OF prod_s])
show "0 ≤ norm v * real (α b)" by simp
qed
finally show ?thesis .
qed
have "¦ra_Dmonomial h α v¦
≤ (∑b∈Basis. ¦real (α b) * (v ∙ b) * (h ∙ b) ^ (α b - 1) *
(∏d∈Basis - {b}. (h ∙ d) ^ (α d))¦)"
unfolding ra_Dmonomial_def by (rule sum_abs)
also have "… ≤ (∑b∈Basis. norm v * real (α b) * s ^ (ra_deg α))"
by (rule sum_mono) (use term_le in simp)
also have "… = norm v * (∑b∈Basis. real (α b)) * s ^ (ra_deg α)"
by (simp add: sum_distrib_left sum_distrib_right mult.assoc)
also have "(∑b∈Basis. real (α b)) = real (ra_deg α)"
by (simp add: ra_deg_def)
finally show ?thesis .
qed
subsection ‹A degree-weighted geometric majorant is summable on @{const ra_idx}›
text ‹For ‹0 ≤ q < 1›, the family ‹(ra_deg α + 1) * q ^ ra_deg α› is summable on
@{const ra_idx}.›
lemma deg_pow_summable:
fixes q :: real
assumes q0: "0 ≤ q" and q1: "q < 1"
shows "(λα. real (ra_deg α + 1) * q ^ ra_deg α)
summable_on (ra_idx :: ('a::euclidean_space ⇒ nat) set)"
proof (rule nonneg_bdd_above_summable_on)
fix α :: "'a ⇒ nat" assume "α ∈ ra_idx"
show "0 ≤ real (ra_deg α + 1) * q ^ ra_deg α" using q0 by simp
next
define P where "P = card (Basis :: 'a set) + 1"
define C where "C = (∑n. real ((n+1)^P) * q ^ n)"
have pg_sum: "summable (λn. real ((n+1)^P) * q ^ n)"
by (rule poly_geom_summable[OF q0 q1])
show "bdd_above (sum (λα. real (ra_deg α + 1) * q ^ ra_deg α)
` {F. F ⊆ (ra_idx :: ('a ⇒ nat) set) ∧ finite F})"
proof (rule bdd_aboveI2)
fix F :: "('a ⇒ nat) set" assume "F ∈ {F. F ⊆ ra_idx ∧ finite F}"
then have Fsub: "F ⊆ ra_idx" and Ffin: "finite F" by auto
define D where "D = (if F = {} then 0 else Max (ra_deg ` F))"
define lev where "lev = (λn. {α::'a⇒nat. α ∈ ra_idx ∧ ra_deg α = n})"
define gg where "gg = (λα::'a⇒nat. real (ra_deg α + 1) * q ^ ra_deg α)"
have ggnn: "0 ≤ gg β" if "β ∈ ra_idx" for β
using q0 by (simp add: gg_def)
have Fincl: "F ⊆ (⋃n∈{..D}. lev n)"
proof
fix β assume bF: "β ∈ F"
have "ra_deg β ≤ D"
proof (cases "F = {}")
case True thus ?thesis using bF by simp
next
case False
have "ra_deg β ≤ Max (ra_deg ` F)" using bF Ffin by (intro Max_ge) auto
thus ?thesis using False by (simp add: D_def)
qed
moreover have "β ∈ ra_idx" using bF Fsub by auto
ultimately show "β ∈ (⋃n∈{..D}. lev n)" by (auto simp: lev_def)
qed
have levfin: "finite (lev n)" for n by (simp add: lev_def ra_lev_finite)
have Ufin: "finite (⋃n∈{..D}. lev n)" by (auto intro: levfin)
have "sum gg F ≤ sum gg (⋃n∈{..D}. lev n)"
by (rule sum_mono2[OF Ufin Fincl]) (use ggnn in ‹auto simp: lev_def›)
also have "sum gg (⋃n∈{..D}. lev n) = (∑n≤D. sum gg (lev n))"
proof (rule sum.UNION_disjoint)
show "finite {..D}" by simp
show "∀n∈{..D}. finite (lev n)" using levfin by simp
show "∀m∈{..D}. ∀n∈{..D}. m ≠ n ⟶ lev m ∩ lev n = {}"
by (auto simp: lev_def)
qed
also have "(∑n≤D. sum gg (lev n)) ≤ (∑n≤D. real ((n+1)^P) * q ^ n)"
proof (rule sum_mono)
fix n assume "n ∈ {..D}"
have levn_deg: "ra_deg β = n" if "β ∈ lev n" for β
using that by (simp add: lev_def)
have "sum gg (lev n) = (∑β∈lev n. real (n + 1) * q ^ n)"
by (rule sum.cong) (auto simp: gg_def levn_deg)
also have "… = real (card (lev n)) * (real (n + 1) * q ^ n)" by simp
also have "… ≤ real ((n+1) ^ card (Basis::'a set)) * (real (n + 1) * q ^ n)"
proof (rule mult_right_mono)
have "card (lev n) ≤ (n+1) ^ card (Basis::'a set)"
using ra_lev_card_le[of n] by (simp add: lev_def)
thus "real (card (lev n)) ≤ real ((n+1) ^ card (Basis::'a set))"
by (simp only: of_nat_le_iff)
show "0 ≤ real (n + 1) * q ^ n" using q0 by simp
qed
also have "… = real ((n+1)^P) * q ^ n"
proof -
have eqp: "(n+1) ^ P = (n+1) ^ card (Basis::'a set) * (n + 1)"
by (simp add: P_def)
have req: "real ((n+1) ^ card (Basis::'a set)) * real (n + 1) = real ((n+1) ^ P)"
proof -
have "real ((n+1) ^ card (Basis::'a set)) * real (n + 1)
= real ((n+1) ^ card (Basis::'a set) * (n + 1))"
by (simp only: of_nat_mult)
also have "… = real ((n+1) ^ P)" using eqp by simp
finally show ?thesis .
qed
have "real ((n+1) ^ card (Basis::'a set)) * (real (n + 1) * q ^ n)
= (real ((n+1) ^ card (Basis::'a set)) * real (n + 1)) * q ^ n"
by (simp add: mult.assoc)
also have "… = real ((n+1)^P) * q ^ n" by (simp only: req)
finally show ?thesis .
qed
finally show "sum gg (lev n) ≤ real ((n+1)^P) * q ^ n" .
qed
also have "(∑n≤D. real ((n+1)^P) * q ^ n) ≤ (∑n. real ((n+1)^P) * q ^ n)"
by (rule sum_le_suminf[OF pg_sum]) (auto simp: q0)
also have "… = C" by (simp add: C_def)
finally show "sum (λα. real (ra_deg α + 1) * q ^ ra_deg α) F ≤ C"
by (simp add: gg_def)
qed
qed
subsection ‹@{const ra_idx} is countably infinite›
lemma countable_ra_idx: "countable (ra_idx :: ('a::euclidean_space ⇒ nat) set)"
proof -
have inj: "inj_on (λα. restrict α (Basis :: 'a set)) ra_idx"
proof (rule inj_onI)
fix x y assume xy: "x ∈ ra_idx" "y ∈ ra_idx"
and eq: "restrict x (Basis::'a set) = restrict y (Basis::'a set)"
show "x = y"
proof (rule ext)
fix b show "x b = y b"
proof (cases "b ∈ (Basis::'a set)")
case True
have "restrict x Basis b = restrict y Basis b" using eq by simp
thus ?thesis using True by simp
next
case False
have "x b = 0" using xy(1) False by (force simp: ra_idx_def)
moreover have "y b = 0" using xy(2) False by (force simp: ra_idx_def)
ultimately show ?thesis by simp
qed
qed
qed
have img: "(λα. restrict α (Basis :: 'a set)) ` ra_idx ⊆ ((Basis::'a set) →⇩E (UNIV :: nat set))"
by (auto simp: PiE_def extensional_def restrict_def)
have cnt: "countable ((Basis::'a set) →⇩E (UNIV :: nat set))"
by (rule countable_PiE) auto
have "countable ((λα. restrict α (Basis :: 'a set)) ` ra_idx)"
using img cnt by (rule countable_subset)
thus ?thesis using inj by (rule countable_image_inj_on)
qed
lemma infinite_ra_idx: "infinite (ra_idx :: ('a::euclidean_space ⇒ nat) set)"
proof -
obtain j where jB: "j ∈ (Basis :: 'a set)"
using nonempty_Basis by blast
define F where "F = (λn::nat. (λb::'a. if b = j then n else 0))"
have injF: "inj F"
proof (rule injI)
fix m n assume "F m = F n"
then have "F m j = F n j" by simp
thus "m = n" by (simp add: F_def)
qed
have rng: "range F ⊆ ra_idx"
proof (rule subsetI)
fix z assume "z ∈ range F"
then obtain n where z: "z = F n" by auto
have "{b. z b ≠ 0} ⊆ {j}" by (auto simp: z F_def split: if_split_asm)
also have "… ⊆ Basis" using jB by simp
finally show "z ∈ ra_idx" by (simp add: ra_idx_def)
qed
have "infinite (range F)" using injF by (rule range_inj_infinite)
with rng show ?thesis using finite_subset by blast
qed
definition ra_enum :: "nat ⇒ ('a::euclidean_space ⇒ nat)" where
"ra_enum = from_nat_into (ra_idx :: ('a ⇒ nat) set)"
lemma bij_ra_enum: "bij_betw (ra_enum :: nat ⇒ ('a::euclidean_space ⇒ nat)) UNIV ra_idx"
unfolding ra_enum_def
by (rule bij_betw_from_nat_into[OF countable_ra_idx infinite_ra_idx])
lemma ra_enum_in: "ra_enum n ∈ (ra_idx :: ('a::euclidean_space ⇒ nat) set)"
using bij_ra_enum by (auto simp: bij_betw_def)
lemma inj_ra_enum: "inj (ra_enum :: nat ⇒ ('a::euclidean_space ⇒ nat))"
using bij_ra_enum by (auto simp: bij_betw_def)
lemma range_ra_enum: "range (ra_enum :: nat ⇒ ('a::euclidean_space ⇒ nat)) = ra_idx"
using bij_betw_imp_surj_on[OF bij_ra_enum] by simp
subsection ‹Per-coordinate monomial / derivative bounds›
text ‹Coordinatewise bounds on ‹h› bound the basis monomial.›
lemma ra_monomial_norm_le_coord:
fixes h :: "'a::euclidean_space"
assumes hb: "⋀b. b ∈ Basis ⟹ ¦h ∙ b¦ ≤ s b"
shows "¦ra_monomial h α¦ ≤ (∏b∈Basis. s b ^ (α b))"
proof -
have "¦ra_monomial h α¦ = (∏b∈Basis. ¦(h ∙ b) ^ (α b)¦)"
by (simp add: ra_monomial_def abs_prod)
also have "… ≤ (∏b∈Basis. s b ^ (α b))"
proof (rule prod_mono, intro conjI)
fix b assume bB: "b ∈ (Basis::'a set)"
show "0 ≤ ¦(h ∙ b) ^ (α b)¦" by simp
have "¦(h ∙ b) ^ (α b)¦ = ¦h ∙ b¦ ^ (α b)" by (simp add: power_abs)
also have "… ≤ s b ^ (α b)" using hb[OF bB] by (intro power_mono) auto
finally show "¦(h ∙ b) ^ (α b)¦ ≤ s b ^ (α b)" .
qed
finally show ?thesis .
qed
text ‹Per-coordinate bound on the directional derivative monomial.›
lemma ra_Dmonomial_norm_le_coord:
fixes h v :: "'a::euclidean_space"
assumes hb: "⋀b. b ∈ Basis ⟹ ¦h ∙ b¦ ≤ s b"
and spos: "⋀b. b ∈ Basis ⟹ 0 < s b"
shows "¦ra_Dmonomial h α v¦
≤ norm v * (∑b∈Basis. real (α b) / s b) * (∏b∈Basis. s b ^ (α b))"
proof -
have vb: "¦v ∙ b¦ ≤ norm v" if "b ∈ (Basis::'a set)" for b
proof -
have "¦v ∙ b¦ ≤ norm v * norm b" by (rule Cauchy_Schwarz_ineq2)
thus ?thesis using that by simp
qed
have prodnn: "0 ≤ (∏d∈Basis. s d ^ (α d))"
using spos by (intro prod_nonneg) (auto intro: less_imp_le)
have term_le:
"¦real (α b) * (v ∙ b) * (h ∙ b) ^ (α b - 1) *
(∏d∈Basis - {b}. (h ∙ d) ^ (α d))¦
≤ norm v * (real (α b) / s b) * (∏d∈Basis. s d ^ (α d))"
if bB: "b ∈ (Basis::'a set)" for b
proof (cases "α b = 0")
case True
have rhs_nn: "0 ≤ norm v * (real (α b) / s b) * (∏d∈Basis. s d ^ (α d))"
using prodnn spos[OF bB] by (simp add: zero_le_mult_iff)
show ?thesis using True rhs_nn by simp
next
case False
then have a1: "1 ≤ α b" by simp
have sb_pos: "0 < s b" by (rule spos[OF bB])
have e1: "¦(h ∙ b) ^ (α b - 1)¦ ≤ s b ^ (α b - 1)"
proof -
have "¦(h ∙ b) ^ (α b - 1)¦ = ¦h ∙ b¦ ^ (α b - 1)" by (simp add: power_abs)
also have "… ≤ s b ^ (α b - 1)" using hb[OF bB] by (intro power_mono) auto
finally show ?thesis .
qed
have e2: "¦∏d∈Basis - {b}. (h ∙ d) ^ (α d)¦ ≤ (∏d∈Basis - {b}. s d ^ (α d))"
proof -
have "¦∏d∈Basis - {b}. (h ∙ d) ^ (α d)¦
= (∏d∈Basis - {b}. ¦(h ∙ d) ^ (α d)¦)" by (simp add: abs_prod)
also have "… ≤ (∏d∈Basis - {b}. s d ^ (α d))"
proof (rule prod_mono, intro conjI)
fix d assume dB: "d ∈ Basis - {b}"
show "0 ≤ ¦(h ∙ d) ^ (α d)¦" by simp
have "¦(h ∙ d) ^ (α d)¦ = ¦h ∙ d¦ ^ (α d)" by (simp add: power_abs)
also have "… ≤ s d ^ (α d)" using hb dB by (intro power_mono) auto
finally show "¦(h ∙ d) ^ (α d)¦ ≤ s d ^ (α d)" .
qed
finally show ?thesis .
qed
have prod_id: "s b ^ (α b - 1) * (∏d∈Basis - {b}. s d ^ (α d))
= (1 / s b) * (∏d∈Basis. s d ^ (α d))"
proof -
have split: "(∏d∈Basis. s d ^ (α d))
= s b ^ (α b) * (∏d∈Basis - {b}. s d ^ (α d))"
using bB by (simp add: prod.remove[where x = b])
have pw: "s b ^ (α b) = s b * s b ^ (α b - 1)"
using a1 by (simp add: power_eq_if)
have "(1 / s b) * (∏d∈Basis. s d ^ (α d))
= (1 / s b) * (s b * s b ^ (α b - 1)) * (∏d∈Basis - {b}. s d ^ (α d))"
by (simp add: split pw mult.assoc)
also have "… = s b ^ (α b - 1) * (∏d∈Basis - {b}. s d ^ (α d))"
using sb_pos by simp
finally show ?thesis by (rule sym)
qed
have abs_eq:
"¦real (α b) * (v ∙ b) * (h ∙ b) ^ (α b - 1) *
(∏d∈Basis - {b}. (h ∙ d) ^ (α d))¦
= real (α b) * (¦v ∙ b¦ *
(¦(h ∙ b) ^ (α b - 1)¦ * ¦∏d∈Basis - {b}. (h ∙ d) ^ (α d)¦))"
by (simp add: abs_mult mult.assoc)
have spow_nn: "0 ≤ s b ^ (α b - 1)" using sb_pos by simp
have sprod_nn: "0 ≤ (∏d∈Basis - {b}. s d ^ (α d))" using spos by (intro prod_nonneg) (auto intro: less_imp_le)
have absprod_nn: "0 ≤ ¦∏d∈Basis - {b}. (h ∙ d) ^ (α d)¦" by simp
have "real (α b) * (¦v ∙ b¦ *
(¦(h ∙ b) ^ (α b - 1)¦ * ¦∏d∈Basis - {b}. (h ∙ d) ^ (α d)¦))
≤ real (α b) * (norm v *
(s b ^ (α b - 1) * (∏d∈Basis - {b}. s d ^ (α d))))"
proof (rule mult_left_mono)
show "¦v ∙ b¦ * (¦(h ∙ b) ^ (α b - 1)¦ * ¦∏d∈Basis - {b}. (h ∙ d) ^ (α d)¦)
≤ norm v * (s b ^ (α b - 1) * (∏d∈Basis - {b}. s d ^ (α d)))"
proof (rule mult_mono)
show "¦v ∙ b¦ ≤ norm v" by (rule vb[OF bB])
show "¦(h ∙ b) ^ (α b - 1)¦ * ¦∏d∈Basis - {b}. (h ∙ d) ^ (α d)¦
≤ s b ^ (α b - 1) * (∏d∈Basis - {b}. s d ^ (α d))"
by (rule mult_mono[OF e1 e2 spow_nn absprod_nn])
show "0 ≤ norm v" by simp
show "0 ≤ ¦(h ∙ b) ^ (α b - 1)¦ * ¦∏d∈Basis - {b}. (h ∙ d) ^ (α d)¦" by simp
qed
show "0 ≤ real (α b)" by simp
qed
also have "real (α b) * (norm v *
(s b ^ (α b - 1) * (∏d∈Basis - {b}. s d ^ (α d))))
= real (α b) * (norm v * ((1 / s b) * (∏d∈Basis. s d ^ (α d))))"
by (simp only: prod_id)
also have "… = norm v * (real (α b) / s b) * (∏d∈Basis. s d ^ (α d))"
by (simp add: field_simps)
finally show ?thesis using abs_eq by simp
qed
have "¦ra_Dmonomial h α v¦
≤ (∑b∈Basis. ¦real (α b) * (v ∙ b) * (h ∙ b) ^ (α b - 1) *
(∏d∈Basis - {b}. (h ∙ d) ^ (α d))¦)"
unfolding ra_Dmonomial_def by (rule sum_abs)
also have "… ≤ (∑b∈Basis. norm v * (real (α b) / s b) * (∏d∈Basis. s d ^ (α d)))"
by (rule sum_mono) (use term_le in simp)
also have "… = norm v * (∑b∈Basis. real (α b) / s b) * (∏b∈Basis. s b ^ (α b))"
by (simp add: sum_distrib_left sum_distrib_right mult.assoc)
finally show ?thesis .
qed
subsection ‹Multivariate geometric majorant (single ratio)›
lemma geom_idx_summable:
fixes q :: real
assumes q0: "0 ≤ q" and q1: "q < 1"
shows "(λα. q ^ ra_deg α) summable_on (ra_idx :: ('a::euclidean_space ⇒ nat) set)"
proof (rule nonneg_bdd_above_summable_on)
fix α :: "'a ⇒ nat" assume "α ∈ ra_idx"
show "0 ≤ q ^ ra_deg α" using q0 by simp
next
define Bnd where "Bnd = (1 / (1 - q)) ^ card (Basis :: 'a set)"
have geom_sum_le: "(∑k≤N. q ^ k) ≤ 1 / (1 - q)" for N
proof -
have nq: "norm q < 1" using q0 q1 by simp
have "(∑k≤N. q ^ k) ≤ (∑k. q ^ k)"
by (rule sum_le_suminf) (use q0 nq summable_geometric[of q] in auto)
also have "… = 1 / (1 - q)" using nq by (simp add: suminf_geometric)
finally show ?thesis .
qed
have part_bound: "(∑α∈F. q ^ ra_deg α) ≤ Bnd"
if F: "F ⊆ ra_idx" "finite F" for F :: "('a ⇒ nat) set"
proof -
define N where "N = Max (insert 0 (⋃α∈F. α ` (Basis :: 'a set)))"
have finUN: "finite (insert 0 (⋃α∈F. α ` (Basis :: 'a set)))"
using F(2) by (simp add: finite_UN_I)
have Nbound: "α b ≤ N" if "α ∈ F" "b ∈ Basis" for α b
proof -
have "α b ∈ insert 0 (⋃α∈F. α ` (Basis :: 'a set))" using that by auto
thus ?thesis unfolding N_def using finUN by (intro Max_ge)
qed
define R where "R = (λα::'a⇒nat. restrict α (Basis :: 'a set))"
have R_in: "R α ∈ Pi⇩E (Basis :: 'a set) (λ_. {0..N})" if "α ∈ F" for α
using that Nbound by (auto simp: R_def PiE_def Pi_def extensional_def)
have R_deg: "(∑b∈Basis. R α b) = ra_deg α" for α
by (simp add: R_def ra_deg_def)
have R_inj: "inj_on R F"
proof (rule inj_onI)
fix a b assume ab: "a ∈ F" "b ∈ F" and Req: "R a = R b"
show "a = b"
proof (rule ext)
fix x show "a x = b x"
proof (cases "x ∈ Basis")
case True
have "restrict a Basis x = restrict b Basis x" using Req by (simp add: R_def)
thus ?thesis using True by simp
next
case False
have "a ∈ ra_idx" "b ∈ ra_idx" using ab F(1) by auto
then have "a x = 0" "b x = 0" using False by (auto simp: ra_idx_def)
thus ?thesis by simp
qed
qed
qed
have "(∑α∈F. q ^ ra_deg α) = (∑g∈R ` F. q ^ (∑b∈Basis. g b))"
proof -
have "(∑α∈F. q ^ ra_deg α) = (∑α∈F. q ^ (∑b∈Basis. R α b))"
by (simp add: R_deg)
also have "… = (∑g∈R ` F. q ^ (∑b∈Basis. g b))"
by (rule sum.reindex_cong[OF R_inj refl, symmetric]) simp
finally show ?thesis .
qed
also have "… ≤ (∑g∈Pi⇩E (Basis :: 'a set) (λ_. {0..N}). q ^ (∑b∈Basis. g b))"
proof (rule sum_mono2)
show "finite (Pi⇩E (Basis :: 'a set) (λ_. {0..N}))" by (intro finite_PiE) auto
show "R ` F ⊆ Pi⇩E (Basis :: 'a set) (λ_. {0..N})" using R_in by auto
fix g assume "g ∈ Pi⇩E (Basis :: 'a set) (λ_. {0..N}) - R ` F"
show "0 ≤ q ^ (∑b∈Basis. g b)" using q0 by simp
qed
also have "… = (∑g∈Pi⇩E (Basis :: 'a set) (λ_. {0..N}). (∏b∈Basis. q ^ g b))"
by (intro sum.cong refl) (simp add: power_sum)
also have "… = (∏b∈(Basis :: 'a set). ∑k∈{0..N}. q ^ k)"
proof -
have finPi: "finite (Pi⇩E (Basis :: 'a set) (λ_. {0..N}))"
by (intro finite_PiE) auto
have summable:
"(λg. ∏b∈(Basis :: 'a set). q ^ g b)
summable_on Pi⇩E (Basis :: 'a set) (λ_. {0..N})"
by (rule summable_on_finite[OF finPi])
have "(∑g∈Pi⇩E (Basis :: 'a set) (λ_. {0..N}).
∏b∈Basis. q ^ g b) =
infsum (λg. ∏b∈(Basis :: 'a set). q ^ g b)
(Pi⇩E (Basis :: 'a set) (λ_. {0..N}))"
by (simp add: finPi)
also have "… = (∏b∈(Basis :: 'a set). infsum (λk. q ^ k) {0..N})"
using local.summable by (subst infsum_prod_PiE, simp_all)
also have "… = (∏b∈(Basis :: 'a set). ∑k∈{0..N}. q ^ k)"
by simp
finally show ?thesis .
qed
also have "… ≤ (∏b∈(Basis :: 'a set). 1 / (1 - q))"
proof (rule prod_mono)
fix b :: 'a assume "b ∈ Basis"
have "0 ≤ (∑k∈{0..N}. q ^ k)" using q0 by (intro sum_nonneg) simp
moreover have "(∑k∈{0..N}. q ^ k) ≤ 1 / (1 - q)"
using geom_sum_le[of N] by (simp add: atMost_atLeast0)
ultimately show "0 ≤ (∑k∈{0..N}. q ^ k) ∧ (∑k∈{0..N}. q ^ k) ≤ 1 / (1 - q)" by blast
qed
also have "… = Bnd" by (simp add: Bnd_def)
finally show ?thesis .
qed
show "bdd_above (sum (λα. q ^ ra_deg α) ` {F. F ⊆ (ra_idx :: ('a ⇒ nat) set) ∧ finite F})"
by (rule bdd_aboveI2[where M = Bnd]) (use part_bound in auto)
qed
subsection ‹Per-coordinate coefficient bound›
text ‹The Cauchy estimate for the coefficients, with one radius ‹ρ b› per coordinate.›
lemma ra_coeff_bound_coord:
fixes c :: "('a::euclidean_space ⇒ nat) ⇒ 'b::real_normed_vector"
assumes r: "0 < r"
and HS: "⋀z. dist z x0 < r ⟹
((λα. ra_monomial (z - x0) α *⇩R c α) has_sum F z) ra_idx"
and ρpos: "⋀b. b ∈ Basis ⟹ 0 < ρ b"
and corner: "dist (x0 + (∑b∈(Basis::'a set). ρ b *⇩R b)) x0 < r"
obtains M where "M ≥ 0"
and "⋀α. α ∈ ra_idx ⟹ norm (c α) ≤ M / (∏b∈Basis. ρ b ^ (α b))"
proof -
define zc where "zc = x0 + (∑b∈(Basis::'a set). ρ b *⇩R b)"
have dist_zc: "dist zc x0 < r" using corner by (simp add: zc_def)
have inner_zc: "(zc - x0) ∙ b = ρ b" if "b ∈ (Basis::'a set)" for b
proof -
have "(zc - x0) ∙ b = (∑d∈(Basis::'a set). ρ d *⇩R d) ∙ b"
by (simp add: zc_def)
also have "… = (∑d∈(Basis::'a set). ρ d * (d ∙ b))"
by (simp only: inner_sum_left inner_scaleR_left)
also have "… = ρ b"
using that by (simp add: inner_Basis sum.remove[where x = b] cong: if_cong)
finally show ?thesis .
qed
have mono_zc: "ra_monomial (zc - x0) α = (∏b∈Basis. ρ b ^ (α b))" for α
by (simp add: ra_monomial_def) (rule prod.cong[OF refl], simp add: inner_zc)
have prodpos: "0 < (∏b∈Basis. ρ b ^ (α b))" for α
using ρpos by (intro prod_pos) auto
obtain M0 where Mnn: "M0 ≥ 0"
and bound: "⋀α. α ∈ ra_idx ⟹ norm (ra_monomial (zc - x0) α *⇩R c α) ≤ M0"
using has_sum_imp_bounded_terms[OF HS[OF dist_zc]] by blast
have final: "norm (c α) ≤ M0 / (∏b∈Basis. ρ b ^ (α b))" if a: "α ∈ ra_idx" for α
proof -
have pos: "0 < (∏b∈Basis. ρ b ^ (α b))" by (rule prodpos)
have "(∏b∈Basis. ρ b ^ (α b)) * norm (c α)
= norm (ra_monomial (zc - x0) α *⇩R c α)"
using mono_zc[of α] pos by simp
also have "… ≤ M0" by (rule bound[OF a])
finally have "(∏b∈Basis. ρ b ^ (α b)) * norm (c α) ≤ M0" .
thus ?thesis using pos by (simp add: mult.commute pos_le_divide_eq)
qed
show ?thesis by (rule that[OF Mnn final])
qed
subsection ‹Uniform majorant for the differentiated series near an interior point›
text ‹Near an interior point of the ball, the differentiated series has a uniform summable
majorant.›
lemma diff_majorant_interior:
fixes c :: "('a::euclidean_space ⇒ nat) ⇒ 'b::real_normed_vector"
assumes r: "0 < r"
and HS: "⋀z. dist z x0 < r ⟹
((λα. ra_monomial (z - x0) α *⇩R c α) has_sum F z) ra_idx"
and x: "dist x x0 < r"
obtains δ0 q K where
"0 < δ0" "0 ≤ q" "q < 1" "0 ≤ K"
and "(λα. K * real (ra_deg α + 1) * q ^ ra_deg α) summable_on ra_idx"
and "⋀z. dist z x < δ0 ⟹ dist z x0 < r"
and "⋀z α v. dist z x < δ0 ⟹ α ∈ ra_idx ⟹
norm (ra_Dmonomial (z - x0) α v *⇩R c α)
≤ norm v * (K * real (ra_deg α + 1) * q ^ ra_deg α)"
proof -
define h0 where "h0 = x - x0"
have nh0: "norm h0 < r" using x by (simp add: h0_def dist_norm)
define csq where "csq = (λm::real. (∑b∈(Basis::'a set). (¦h0 ∙ b¦ + 2 * m)⇧2))"
have csq0: "csq 0 = (norm h0)⇧2"
proof -
have "csq 0 = (∑b∈Basis. (h0 ∙ b)⇧2)" by (simp add: csq_def)
also have "… = (norm h0)⇧2" by (rule norm_sq_eq_sum_coord[symmetric])
finally show ?thesis .
qed
have csq_cont: "csq ─0→ csq 0"
unfolding csq_def by (intro tendsto_intros)
have "(norm h0)⇧2 < r⇧2" using nh0 by (simp add: power_strict_mono)
then have csq0lt: "csq 0 < r⇧2" using csq0 by simp
have ev_at: "∀⇩F m in at 0. csq m < r⇧2"
by (rule order_tendstoD(2)[OF csq_cont csq0lt])
have "at_right (0::real) ≤ at 0" by (simp add: at_le)
then have "∀⇩F m in at_right (0::real). csq m < r⇧2"
using ev_at by (rule filter_leD)
then obtain δ1 where δ1pos: "0 < δ1" and csqlt: "⋀m. 0 < m ⟹ m < δ1 ⟹ csq m < r⇧2"
by (auto simp: eventually_at_right_field)
define δ where "δ = δ1 / 2"
have δpos: "0 < δ" using δ1pos by (simp add: δ_def)
have δlt: "δ < δ1" using δ1pos by (simp add: δ_def)
have csqδ: "csq δ < r⇧2" using csqlt[OF δpos δlt] .
define ρ where "ρ = (λb. ¦h0 ∙ b¦ + 2 * δ)"
define ss where "ss = (λb. ¦h0 ∙ b¦ + δ)"
have ρpos: "0 < ρ b" for b using δpos by (simp add: ρ_def)
have sspos: "0 < ss b" for b using δpos by (simp add: ss_def)
have ss_lt_ρ: "ss b < ρ b" for b using δpos by (simp add: ss_def ρ_def)
define q where "q = Max ((λb. ss b / ρ b) ` (Basis :: 'a set))"
have finB: "finite ((λb. ss b / ρ b) ` (Basis :: 'a set))" by simp
have neB: "((λb. ss b / ρ b) ` (Basis :: 'a set)) ≠ {}"
using nonempty_Basis by simp
have q_ge: "ss b / ρ b ≤ q" if "b ∈ (Basis::'a set)" for b
unfolding q_def using that by (intro Max_ge) auto
have ratio_lt1: "ss b / ρ b < 1" for b
using ss_lt_ρ[of b] ρpos[of b] by (simp add: divide_less_eq)
have ratio_nn: "0 ≤ ss b / ρ b" for b
using sspos[of b] ρpos[of b] by simp
have q1: "q < 1" unfolding q_def
using finB neB ratio_lt1 by (subst Max_less_iff) auto
have q0: "0 ≤ q"
proof -
obtain b where "b ∈ (Basis::'a set)" using nonempty_Basis by blast
thus ?thesis using q_ge[of b] ratio_nn[of b] by linarith
qed
have corner: "dist (x0 + (∑b∈(Basis::'a set). ρ b *⇩R b)) x0 < r"
proof -
have "dist (x0 + (∑b∈(Basis::'a set). ρ b *⇩R b)) x0
= norm (∑b∈(Basis::'a set). ρ b *⇩R b)"
by (simp add: dist_norm)
also have "… = sqrt (∑b∈(Basis::'a set). (ρ b)⇧2)"
proof -
have "(norm (∑b∈(Basis::'a set). ρ b *⇩R b))⇧2 = (∑b∈(Basis::'a set). (ρ b)⇧2)"
by (rule norm_basis_combo_sq)
moreover have "0 ≤ norm (∑b∈(Basis::'a set). ρ b *⇩R b)" by simp
ultimately show ?thesis by (metis real_sqrt_unique)
qed
also have "(∑b∈(Basis::'a set). (ρ b)⇧2) = csq δ"
by (simp add: csq_def ρ_def)
also have "sqrt (csq δ) < sqrt (r⇧2)"
using csqδ by (intro real_sqrt_less_mono)
also have "sqrt (r⇧2) = r" using r by simp
finally show ?thesis .
qed
obtain M where Mnn: "M ≥ 0"
and cbound: "⋀α. α ∈ ra_idx ⟹ norm (c α) ≤ M / (∏b∈Basis. ρ b ^ (α b))"
using ra_coeff_bound_coord[OF r HS ρpos corner] by blast
define K where "K = M / δ"
have Knn: "0 ≤ K" using Mnn δpos by (simp add: K_def)
have maj_summ: "(λα. K * real (ra_deg α + 1) * q ^ ra_deg α) summable_on ra_idx"
proof -
have "(λα. real (ra_deg α + 1) * q ^ ra_deg α) summable_on ra_idx"
by (rule deg_pow_summable[OF q0 q1])
then have "(λα. K * (real (ra_deg α + 1) * q ^ ra_deg α)) summable_on ra_idx"
by (rule summable_on_cmult_right)
thus ?thesis by (simp add: mult.assoc)
qed
have inball: "dist z x0 < r" if dz: "dist z x < δ" for z
proof -
have coordb: "¦(z - x0) ∙ b¦ ≤ ss b" if "b ∈ (Basis::'a set)" for b
proof -
have "¦(z - x0) ∙ b¦ = ¦(z - x) ∙ b + h0 ∙ b¦"
by (simp add: h0_def inner_diff_left)
also have "… ≤ ¦(z - x) ∙ b¦ + ¦h0 ∙ b¦" by (rule abs_triangle_ineq)
also have "¦(z - x) ∙ b¦ ≤ norm (z - x)"
proof -
have "¦(z - x) ∙ b¦ ≤ norm (z - x) * norm b" by (rule Cauchy_Schwarz_ineq2)
thus ?thesis using that by simp
qed
also have "norm (z - x) < δ" using dz by (simp add: dist_norm)
finally show ?thesis by (simp add: ss_def)
qed
have "(norm (z - x0))⇧2 = (∑b∈(Basis::'a set). ((z - x0) ∙ b)⇧2)"
by (rule norm_sq_eq_sum_coord)
also have "… ≤ (∑b∈(Basis::'a set). (ss b)⇧2)"
proof (rule sum_mono)
fix b assume bB: "b ∈ (Basis::'a set)"
have "((z - x0) ∙ b)⇧2 = ¦(z - x0) ∙ b¦⇧2" by simp
also have "… ≤ (ss b)⇧2"
using coordb[OF bB] sspos[of b] by (intro power_mono) auto
finally show "((z - x0) ∙ b)⇧2 ≤ (ss b)⇧2" .
qed
also have "(∑b∈(Basis::'a set). (ss b)⇧2) < (∑b∈(Basis::'a set). (ρ b)⇧2)"
proof (rule sum_strict_mono)
show "finite (Basis :: 'a set)" by simp
show "(Basis :: 'a set) ≠ {}" using nonempty_Basis by simp
fix b assume "b ∈ (Basis::'a set)"
show "(ss b)⇧2 < (ρ b)⇧2"
using ss_lt_ρ[of b] sspos[of b] ρpos[of b] by (intro power_strict_mono) auto
qed
also have "(∑b∈(Basis::'a set). (ρ b)⇧2) = csq δ" by (simp add: csq_def ρ_def)
also have "csq δ < r⇧2" by (rule csqδ)
finally have nlt: "(norm (z - x0))⇧2 < r⇧2" .
have "norm (z - x0) < r"
by (rule power2_less_imp_less[OF nlt]) (simp add: r less_imp_le)
thus ?thesis by (simp add: dist_norm)
qed
have termbound:
"norm (ra_Dmonomial (z - x0) α v *⇩R c α)
≤ norm v * (K * real (ra_deg α + 1) * q ^ ra_deg α)"
if dz: "dist z x < δ" and a: "α ∈ ra_idx" for z α v
proof -
have coordb: "¦(z - x0) ∙ b¦ ≤ ss b" if "b ∈ (Basis::'a set)" for b
proof -
have "¦(z - x0) ∙ b¦ = ¦(z - x) ∙ b + h0 ∙ b¦"
by (simp add: h0_def inner_diff_left)
also have "… ≤ ¦(z - x) ∙ b¦ + ¦h0 ∙ b¦" by (rule abs_triangle_ineq)
also have "¦(z - x) ∙ b¦ ≤ norm (z - x)"
proof -
have "¦(z - x) ∙ b¦ ≤ norm (z - x) * norm b" by (rule Cauchy_Schwarz_ineq2)
thus ?thesis using that by simp
qed
also have "norm (z - x) < δ" using dz by (simp add: dist_norm)
finally show ?thesis by (simp add: ss_def)
qed
have Dbound: "¦ra_Dmonomial (z - x0) α v¦
≤ norm v * (∑b∈Basis. real (α b) / ss b) * (∏b∈Basis. ss b ^ (α b))"
by (rule ra_Dmonomial_norm_le_coord[OF coordb sspos])
have sumfac: "(∑b∈Basis. real (α b) / ss b) ≤ real (ra_deg α) / δ"
proof -
have "(∑b∈(Basis::'a set). real (α b) / ss b) ≤ (∑b∈(Basis::'a set). real (α b) / δ)"
proof (rule sum_mono)
fix b assume bB: "b ∈ (Basis::'a set)"
have "δ ≤ ss b" by (simp add: ss_def)
thus "real (α b) / ss b ≤ real (α b) / δ"
using δpos sspos[of b] by (intro divide_left_mono) (auto simp: zero_le_mult_iff)
qed
also have "… = (∑b∈(Basis::'a set). real (α b)) / δ"
by (simp add: sum_divide_distrib)
also have "(∑b∈(Basis::'a set). real (α b)) = real (ra_deg α)"
by (simp add: ra_deg_def)
finally show ?thesis .
qed
have prodq: "(∏b∈Basis. ss b ^ (α b)) / (∏b∈Basis. ρ b ^ (α b)) ≤ q ^ ra_deg α"
proof -
have prodpos: "0 < (∏b∈(Basis::'a set). ρ b ^ (α b))"
using ρpos by (intro prod_pos) auto
have "(∏b∈Basis. ss b ^ (α b)) / (∏b∈Basis. ρ b ^ (α b))
= (∏b∈(Basis::'a set). (ss b / ρ b) ^ (α b))"
by (simp add: prod_dividef power_divide)
also have "… ≤ (∏b∈(Basis::'a set). q ^ (α b))"
proof (rule prod_mono, intro conjI)
fix b assume bB: "b ∈ (Basis::'a set)"
show "0 ≤ (ss b / ρ b) ^ (α b)" using ratio_nn[of b] by simp
show "(ss b / ρ b) ^ (α b) ≤ q ^ (α b)"
using q_ge[OF bB] ratio_nn[of b] by (intro power_mono) auto
qed
also have "… = q ^ (∑b∈(Basis::'a set). α b)" by (simp add: power_sum)
finally show ?thesis by (simp add: ra_deg_def)
qed
have prodpos: "0 < (∏b∈(Basis::'a set). ρ b ^ (α b))"
using ρpos by (intro prod_pos) auto
have ssprod_nn: "0 ≤ (∏b∈(Basis::'a set). ss b ^ (α b))"
using sspos by (intro prod_nonneg) (auto intro: less_imp_le)
have deg_nn: "0 ≤ (∑b∈(Basis::'a set). real (α b) / ss b)"
by (intro sum_nonneg) (simp add: sspos less_imp_le)
have "norm (ra_Dmonomial (z - x0) α v *⇩R c α)
= ¦ra_Dmonomial (z - x0) α v¦ * norm (c α)"
by (simp only: norm_scaleR)
also have "… ≤ (norm v * (∑b∈Basis. real (α b) / ss b) * (∏b∈Basis. ss b ^ (α b)))
* (M / (∏b∈Basis. ρ b ^ (α b)))"
proof (rule mult_mono[OF Dbound cbound[OF a]])
show "0 ≤ norm v * (∑b∈Basis. real (α b) / ss b) * (∏b∈Basis. ss b ^ (α b))"
using deg_nn ssprod_nn by (simp add: zero_le_mult_iff)
show "0 ≤ norm (c α)" by simp
qed
also have "… = norm v * (∑b∈Basis. real (α b) / ss b) * M
* ((∏b∈Basis. ss b ^ (α b)) / (∏b∈Basis. ρ b ^ (α b)))"
by (simp add: field_simps)
also have "… ≤ norm v * (real (ra_deg α) / δ) * M * (q ^ ra_deg α)"
proof -
have le1: "norm v * (∑b∈Basis. real (α b) / ss b) * M ≤ norm v * (real (ra_deg α) / δ) * M"
proof -
have "norm v * (∑b∈Basis. real (α b) / ss b) ≤ norm v * (real (ra_deg α) / δ)"
by (rule mult_left_mono[OF sumfac]) simp
thus ?thesis by (rule mult_right_mono[OF _ Mnn])
qed
have nn_b: "0 ≤ norm v * (real (ra_deg α) / δ) * M"
using δpos Mnn by (simp add: zero_le_mult_iff)
have nn_c: "0 ≤ (∏b∈Basis. ss b ^ (α b)) / (∏b∈Basis. ρ b ^ (α b))"
using ssprod_nn prodpos by (simp add: zero_le_divide_iff)
show ?thesis by (rule mult_mono[OF le1 prodq nn_b nn_c])
qed
also have "… = norm v * (K * real (ra_deg α) * q ^ ra_deg α)"
by (simp add: K_def field_simps)
also have "… ≤ norm v * (K * real (ra_deg α + 1) * q ^ ra_deg α)"
proof (rule mult_left_mono)
have "K * real (ra_deg α) * q ^ ra_deg α ≤ K * real (ra_deg α + 1) * q ^ ra_deg α"
using Knn q0 by (intro mult_right_mono mult_left_mono) auto
thus "K * real (ra_deg α) * q ^ ra_deg α ≤ K * real (ra_deg α + 1) * q ^ ra_deg α" .
show "0 ≤ norm v" by simp
qed
finally show ?thesis .
qed
show ?thesis
by (rule that[OF δpos q0 q1 Knn maj_summ inball termbound])
qed
subsection ‹Term-by-term differentiation›
theorem ra_power_series_has_derivative:
fixes f :: "'a::euclidean_space ⇒ 'b::banach"
assumes r: "0 < r"
and series: "⋀y. dist y x0 < r ⟹
((λα. ra_monomial (y - x0) α *⇩R c α) has_sum f y) ra_idx"
and x: "dist x x0 < r"
shows
"(f has_derivative
(λv. infsum (λα. ra_Dmonomial (x - x0) α v *⇩R c α) ra_idx))
(at x)"
proof -
obtain δ0 q K where δ0: "0 < δ0" and q0: "0 ≤ q" and q1: "q < 1" and Knn: "0 ≤ K"
and majsumm: "(λα. K * real (ra_deg α + 1) * q ^ ra_deg α) summable_on ra_idx"
and inball: "⋀z. dist z x < δ0 ⟹ dist z x0 < r"
and tbound: "⋀z α v. dist z x < δ0 ⟹ α ∈ ra_idx ⟹
norm (ra_Dmonomial (z - x0) α v *⇩R c α)
≤ norm v * (K * real (ra_deg α + 1) * q ^ ra_deg α)"
using diff_majorant_interior[OF r series x] by blast
define D where "D = (λα::'a⇒nat. K * real (ra_deg α + 1) * q ^ ra_deg α)"
have Dnn: "0 ≤ D α" for α using Knn q0 by (simp add: D_def)
have D_summ: "D summable_on ra_idx" unfolding D_def using majsumm
by (metis (lifting) ext deg_pow_summable q0 q1 summable_on_cmult_right
vector_space_over_itself.scale_scale)
define S where "S = ball x δ0"
have convS: "convex S" by (simp add: S_def)
have xS: "x ∈ S" using δ0 by (simp add: S_def)
have openS: "open S" by (simp add: S_def)
have S_ball: "⋀z. z ∈ S ⟹ dist z x < δ0" by (simp add: S_def dist_commute)
have S_in_r: "⋀z. z ∈ S ⟹ dist z x0 < r" using inball S_ball by blast
define en where "en = (ra_enum :: nat ⇒ ('a ⇒ nat))"
have en_in: "en k ∈ ra_idx" for k by (simp add: en_def ra_enum_in)
have en_inj: "inj en" by (simp add: en_def inj_ra_enum)
have en_rng: "range en = ra_idx" by (simp add: en_def range_ra_enum)
define fn where "fn = (λn z. ∑k<n. ra_monomial (z - x0) (en k) *⇩R c (en k))"
define f'n where
"f'n = (λn z w. ∑k<n. ra_Dmonomial (z - x0) (en k) w *⇩R c (en k))"
define g' where "g' = (λz w. infsum (λα. ra_Dmonomial (z - x0) α w *⇩R c α) ra_idx)"
have derfn: "((fn n) has_derivative (f'n n z)) (at z within S)" for n z
proof -
have "((λz. ∑k<n. ra_monomial (z - x0) (en k) *⇩R c (en k))
has_derivative (λw. ∑k<n. ra_Dmonomial (z - x0) (en k) w *⇩R c (en k))) (at z)"
by (rule has_derivative_sum)
(rule ra_shifted_term_has_derivative)
then have "((fn n) has_derivative (f'n n z)) (at z)"
by (simp add: fn_def f'n_def)
thus ?thesis by (rule has_derivative_at_withinI)
qed
have termsum_z: "((λα. ra_monomial (z - x0) α *⇩R c α) has_sum f z) ra_idx"
if "z ∈ S" for z using series[OF S_in_r[OF that]] .
have fn_lim: "(λn. fn n z) ⇢ f z" if zS: "z ∈ S" for z
proof -
have "((λα. ra_monomial (z - x0) α *⇩R c α) has_sum f z) (range en)"
using termsum_z[OF zS] by (simp add: en_rng)
then have "((λk. ra_monomial (z - x0) (en k) *⇩R c (en k)) has_sum f z) UNIV"
using en_inj by (subst (asm) has_sum_reindex) (auto simp: o_def)
then have "(λk. ra_monomial (z - x0) (en k) *⇩R c (en k)) sums f z"
by (rule has_sum_imp_sums)
thus ?thesis by (simp add: fn_def sums_def)
qed
have Dsummf: "(λα. ra_Dmonomial (z - x0) α w *⇩R c α) summable_on ra_idx"
if zS: "z ∈ S" for z w
proof (rule abs_summable_summable, rule summable_on_comparison_test
[where f = "λα. norm w * D α"])
show "(λα. norm w * D α) summable_on ra_idx"
by (rule summable_on_cmult_right[OF D_summ])
next
fix α :: "'a ⇒ nat" assume a: "α ∈ ra_idx"
show "norm (ra_Dmonomial (z - x0) α w *⇩R c α) ≤ norm w * D α"
using tbound[OF S_ball[OF zS] a] by (simp add: D_def)
next
fix α :: "'a ⇒ nat" assume "α ∈ ra_idx"
show "0 ≤ norm (ra_Dmonomial (z - x0) α w *⇩R c α)" by simp
qed
have g'sums: "(λk. ra_Dmonomial (z - x0) (en k) w *⇩R c (en k)) sums g' z w"
if zS: "z ∈ S" for z w
proof -
have "((λα. ra_Dmonomial (z - x0) α w *⇩R c α) has_sum g' z w) ra_idx"
unfolding g'_def using Dsummf[OF zS] by (rule has_sum_infsum)
then have "((λα. ra_Dmonomial (z - x0) α w *⇩R c α) has_sum g' z w) (range en)"
by (simp add: en_rng)
then have "((λk. ra_Dmonomial (z - x0) (en k) w *⇩R c (en k)) has_sum g' z w) UNIV"
using en_inj by (subst (asm) has_sum_reindex) (auto simp: o_def)
thus ?thesis by (rule has_sum_imp_sums)
qed
have Den_summ: "summable (λk. D (en k))"
proof -
have "(D has_sum (infsum D ra_idx)) ra_idx" using D_summ by (rule has_sum_infsum)
then have "(D has_sum (infsum D ra_idx)) (range en)" by (simp add: en_rng)
then have "((D ∘ en) has_sum (infsum D ra_idx)) UNIV"
using en_inj by (subst (asm) has_sum_reindex)
then have "(D ∘ en) sums (infsum D ra_idx)" by (rule has_sum_imp_sums)
thus ?thesis by (auto simp: o_def summable_def)
qed
have unif: "∀⇩F n in sequentially. ∀z∈S. ∀w. norm (f'n n z w - g' z w) ≤ e * norm w"
if epos: "0 < e" for e
proof -
obtain N where N: "⋀n. n ≥ N ⟹ norm (∑i. D (en (i + n))) < e"
using suminf_exist_split[OF epos Den_summ] by blast
have key: "norm (f'n n z w - g' z w) ≤ e * norm w"
if nN: "n ≥ N" and zS: "z ∈ S" for n z w
proof -
define gk where "gk = (λk. ra_Dmonomial (z - x0) (en k) w *⇩R c (en k))"
have gk_sums: "gk sums g' z w" using g'sums[OF zS] by (simp add: gk_def)
have gk_summ: "summable gk" using gk_sums by (simp add: sums_summable)
have gknorm_le: "norm (gk k) ≤ norm w * D (en k)" for k
using tbound[OF S_ball[OF zS] en_in[of k]] by (simp add: gk_def D_def)
have gknorm_summ: "summable (λk. norm (gk k))"
proof (rule summable_comparison_test')
show "summable (λk. norm w * D (en k))"
by (rule summable_mult[OF Den_summ])
fix k show "norm (norm (gk k)) ≤ norm w * D (en k)"
using gknorm_le[of k] by simp
qed
have "norm (f'n n z w - g' z w) = norm ((∑k<n. gk k) - g' z w)"
by (simp add: f'n_def gk_def)
also have "… = norm (∑i. gk (i + n))"
proof -
have "(∑i. gk (i + n)) = g' z w - (∑k<n. gk k)"
using sums_split_initial_segment[OF gk_sums, of n] by (simp add: sums_iff)
thus ?thesis by (simp add: norm_minus_commute)
qed
also have "… ≤ (∑i. norm (gk (i + n)))"
proof (rule summable_norm)
show "summable (λi. norm (gk (i + n)))"
using gknorm_summ by (rule summable_ignore_initial_segment[where k = n])
qed
also have "… ≤ (∑i. norm w * D (en (i + n)))"
proof (rule suminf_le)
show "⋀i. norm (gk (i + n)) ≤ norm w * D (en (i + n))" using gknorm_le by simp
show "summable (λi. norm (gk (i + n)))"
using gknorm_summ by (rule summable_ignore_initial_segment[where k = n])
show "summable (λi. norm w * D (en (i + n)))"
proof -
have "summable (λk. norm w * D (en k))" by (rule summable_mult[OF Den_summ])
thus ?thesis by (rule summable_ignore_initial_segment[where k = n])
qed
qed
also have "… = norm w * (∑i. D (en (i + n)))"
by (rule suminf_mult)
(rule summable_ignore_initial_segment[OF Den_summ, where k = n, simplified])
also have "… ≤ norm w * e"
proof (rule mult_left_mono)
have "(∑i. D (en (i + n))) ≤ norm (∑i. D (en (i + n)))" by simp
also have "… < e" by (rule N[OF nN])
finally show "(∑i. D (en (i + n))) ≤ e" by simp
show "0 ≤ norm w" by simp
qed
finally show ?thesis by (simp only: mult.commute)
qed
show ?thesis
unfolding eventually_sequentially using key by blast
qed
have basept: "(λn. fn n x) ⇢ f x" by (rule fn_lim[OF xS])
obtain g where g: "⋀z. z ∈ S ⟹ (λn. fn n z) ⇢ g z ∧ (g has_derivative g' z) (at z within S)"
using has_derivative_sequence[OF convS derfn unif xS basept] by metis
have g_eq_f: "g z = f z" if zS: "z ∈ S" for z
using g[OF zS] fn_lim[OF zS] LIMSEQ_unique by blast
have hd_g_within: "(g has_derivative g' x) (at x within S)" using g[OF xS] by blast
have atSx: "at x within S = at x" using openS xS by (subst at_within_open, simp_all)
have hd_g_at: "(g has_derivative g' x) (at x)" using hd_g_within by (simp only: atSx)
have "(f has_derivative g' x) (at x)"
by (rule has_derivative_transform_within_open[OF hd_g_at openS xS])
(simp add: g_eq_f)
thus ?thesis by (simp only: g'_def)
qed
subsection ‹Incrementing a multi-index stays in the index set›
lemma ra_inc_in_idx:
fixes α :: "'a::euclidean_space ⇒ nat"
assumes "α ∈ ra_idx" and "b ∈ Basis"
shows "ra_inc α b ∈ ra_idx"
proof -
have "{c. ra_inc α b c ≠ 0} ⊆ {c. α c ≠ 0} ∪ {b}"
by (auto simp: ra_inc_def)
also have "… ⊆ Basis"
using assms by (auto simp: ra_idx_def)
finally show ?thesis by (simp add: ra_idx_def)
qed
subsection ‹Decrement is the inverse of @{const ra_inc} on the support slice›
definition ra_dec ::
"('a ⇒ nat) ⇒ 'a ⇒ ('a ⇒ nat)" where
"ra_dec α b = α(b := α b - 1)"
lemma ra_dec_in_idx:
fixes α :: "'a::euclidean_space ⇒ nat"
assumes "α ∈ ra_idx"
shows "ra_dec α b ∈ ra_idx"
proof -
have "{c. ra_dec α b c ≠ 0} ⊆ {c. α c ≠ 0}"
by (auto simp: ra_dec_def)
also have "… ⊆ Basis" using assms by (auto simp: ra_idx_def)
finally show ?thesis by (simp add: ra_idx_def)
qed
lemma ra_inc_dec:
assumes "1 ≤ α b"
shows "ra_inc (ra_dec α b) b = α"
using assms by (auto simp: ra_inc_def ra_dec_def fun_eq_iff)
lemma ra_dec_inc:
"ra_dec (ra_inc α b) b = α"
by (auto simp: ra_inc_def ra_dec_def fun_eq_iff)
subsection ‹Splitting a monomial off one basis direction›
lemma ra_monomial_split:
fixes x :: "'a::euclidean_space"
assumes "b ∈ Basis"
shows "ra_monomial x β
= (x ∙ b) ^ (β b) * (∏d∈Basis - {b}. (x ∙ d) ^ (β d))"
unfolding ra_monomial_def
by (subst prod.remove[OF finite_Basis assms]) simp
subsection ‹The per-basis LHS and RHS pieces›
definition ra_dterm ::
"'a::euclidean_space ⇒ 'a ⇒ (('a ⇒ nat) ⇒ 'b::real_normed_vector) ⇒ 'a ⇒ ('a ⇒ nat) ⇒ 'b"
where
"ra_dterm x v c b α =
(real (α b) * (v ∙ b) * (x ∙ b) ^ (α b - 1) *
(∏d∈Basis - {b}. (x ∙ d) ^ (α d))) *⇩R c α"
definition ra_dterm_shift ::
"'a::euclidean_space ⇒ 'a ⇒ (('a ⇒ nat) ⇒ 'b::real_normed_vector) ⇒ 'a ⇒ ('a ⇒ nat) ⇒ 'b"
where
"ra_dterm_shift x v c b β =
(real (Suc (β b)) * (v ∙ b)) *⇩R (ra_monomial x β *⇩R c (ra_inc β b))"
lemma Dmonomial_eq_sum_dterm:
fixes x v :: "'a::euclidean_space"
shows "ra_Dmonomial x α v *⇩R c α = (∑b∈Basis. ra_dterm x v c b α)"
unfolding ra_Dmonomial_def ra_dterm_def
by (simp add: scaleR_sum_left)
lemma dcoeff_eq_sum_dterm_shift:
fixes x v :: "'a::euclidean_space"
shows "ra_monomial x α *⇩R ra_dcoeff c v α = (∑b∈Basis. ra_dterm_shift x v c b α)"
unfolding ra_dcoeff_def ra_dterm_shift_def
by (simp add: scaleR_right.sum) (simp add: algebra_simps)
text ‹Key pointwise identity: the LHS piece at @{term "ra_inc β b"} equals the RHS piece at
@{term β}.›
lemma ra_dterm_inc_eq_dterm_shift:
fixes x v :: "'a::euclidean_space"
assumes "b ∈ Basis"
shows "ra_dterm x v c b (ra_inc β b) = ra_dterm_shift x v c b β"
proof -
have inc_b: "(ra_inc β b) b = Suc (β b)" by (simp add: ra_inc_def)
have inc_d: "⋀d. d ≠ b ⟹ (ra_inc β b) d = β d" by (simp add: ra_inc_def)
have prod_eq: "(∏d∈Basis - {b}. (x ∙ d) ^ ((ra_inc β b) d))
= (∏d∈Basis - {b}. (x ∙ d) ^ (β d))"
by (rule prod.cong) (auto simp: inc_d)
have mono: "(x ∙ b) ^ (β b) * (∏d∈Basis - {b}. (x ∙ d) ^ (β d)) = ra_monomial x β"
using ra_monomial_split[OF assms] by simp
have "ra_dterm x v c b (ra_inc β b)
= (real (Suc (β b)) * (v ∙ b) * (x ∙ b) ^ (β b) *
(∏d∈Basis - {b}. (x ∙ d) ^ (β d))) *⇩R c (ra_inc β b)"
unfolding ra_dterm_def by (simp add: inc_b prod_eq)
also have "… = (real (Suc (β b)) * (v ∙ b)) *⇩R
(((x ∙ b) ^ (β b) * (∏d∈Basis - {b}. (x ∙ d) ^ (β d))) *⇩R c (ra_inc β b))"
by (simp add: mult.assoc)
also have "… = (real (Suc (β b)) * (v ∙ b)) *⇩R (ra_monomial x β *⇩R c (ra_inc β b))"
by (simp add: mono)
finally show ?thesis by (simp add: ra_dterm_shift_def)
qed
text ‹Off the support (@{term "α b = 0"}) the LHS piece vanishes.›
lemma ra_dterm_zero_off_support:
assumes "α b = 0"
shows "ra_dterm x v c b α = 0"
by (simp add: ra_dterm_def assms)
subsection ‹Per-basis reindexing of has-sum›
lemma has_sum_dterm_iff_dterm_shift:
fixes x v :: "'a::euclidean_space"
and c :: "('a ⇒ nat) ⇒ 'b::banach"
assumes b: "b ∈ Basis"
shows "(ra_dterm x v c b has_sum s) ra_idx ⟷ (ra_dterm_shift x v c b has_sum s) ra_idx"
proof -
define A where "A = {α ∈ ra_idx. 1 ≤ α b}"
have restrict: "(ra_dterm x v c b has_sum s) ra_idx ⟷ (ra_dterm x v c b has_sum s) A"
proof (rule has_sum_cong_neutral)
show "⋀α. α ∈ ra_idx - A ⟹ ra_dterm x v c b α = 0"
by (auto simp: A_def intro!: ra_dterm_zero_off_support)
next
show "⋀α. α ∈ A - ra_idx ⟹ ra_dterm x v c b α = 0" by (auto simp: A_def)
next
show "⋀α. α ∈ ra_idx ∩ A ⟹ ra_dterm x v c b α = ra_dterm x v c b α" by simp
qed
have reidx: "(ra_dterm x v c b has_sum s) A ⟷ (ra_dterm_shift x v c b has_sum s) ra_idx"
proof (rule has_sum_reindex_bij_witness[where i = "λβ. ra_inc β b" and j = "λα. ra_dec α b"])
fix α assume "α ∈ A"
then have "1 ≤ α b" by (simp add: A_def)
thus "ra_inc (ra_dec α b) b = α" by (rule ra_inc_dec)
next
fix α assume "α ∈ A"
then have "α ∈ ra_idx" by (simp add: A_def)
thus "ra_dec α b ∈ ra_idx" by (rule ra_dec_in_idx)
next
fix β :: "'a ⇒ nat" assume "β ∈ ra_idx"
show "ra_dec (ra_inc β b) b = β" by (rule ra_dec_inc)
next
fix β :: "'a ⇒ nat" assume "β ∈ ra_idx"
then have "ra_inc β b ∈ ra_idx" using b by (rule ra_inc_in_idx)
moreover have "1 ≤ (ra_inc β b) b" by (simp add: ra_inc_def)
ultimately show "ra_inc β b ∈ A" by (simp add: A_def)
next
fix α assume "α ∈ A"
then have a1: "1 ≤ α b" by (simp add: A_def)
have "ra_dterm_shift x v c b (ra_dec α b) = ra_dterm x v c b (ra_inc (ra_dec α b) b)"
by (rule ra_dterm_inc_eq_dterm_shift[OF b, symmetric])
also have "… = ra_dterm x v c b α"
using ra_inc_dec[where α = α and b = b, OF a1] by simp
finally show "ra_dterm_shift x v c b (ra_dec α b) = ra_dterm x v c b α" .
next
show "s = s" by simp
qed
show ?thesis using restrict reidx by blast
qed
lemma summable_dterm_iff_dterm_shift:
fixes x v :: "'a::euclidean_space"
and c :: "('a ⇒ nat) ⇒ 'b::banach"
assumes b: "b ∈ Basis"
shows "ra_dterm x v c b summable_on ra_idx ⟷ ra_dterm_shift x v c b summable_on ra_idx"
unfolding summable_on_def using has_sum_dterm_iff_dterm_shift[OF b] by blast
lemma infsum_dterm_eq_dterm_shift:
fixes x v :: "'a::euclidean_space"
and c :: "('a ⇒ nat) ⇒ 'b::banach"
assumes b: "b ∈ Basis"
shows "infsum (ra_dterm x v c b) ra_idx = infsum (ra_dterm_shift x v c b) ra_idx"
proof (cases "ra_dterm x v c b summable_on ra_idx")
case True
then obtain s where s_Def: "(ra_dterm x v c b has_sum s) ra_idx"
by (auto simp: summable_on_def)
then have "(ra_dterm_shift x v c b has_sum s) ra_idx"
using has_sum_dterm_iff_dterm_shift[OF b] by blast
then show ?thesis using infsumI
using s_Def by blast
next
case False
then have "¬ ra_dterm_shift x v c b summable_on ra_idx"
using summable_dterm_iff_dterm_shift[OF b] by blast
with False show ?thesis by (simp add: infsum_not_exists)
qed
subsection ‹The reindexing identity›
text ‹Summability in each basis direction is assumed: plain summability of the differentiated
family would not suffice in an infinite-dimensional Banach space (Dvoretzky--Rogers).›
lemma ra_derivative_reindex:
fixes x v :: "'a::euclidean_space"
and c :: "('a ⇒ nat) ⇒ 'b::banach"
assumes S: "⋀b. b ∈ Basis ⟹
(λα. ra_monomial x α *⇩R (real (Suc (α b)) *⇩R c (ra_inc α b)))
summable_on ra_idx"
shows
"infsum (λα. ra_Dmonomial x α v *⇩R c α) ra_idx
= infsum (λα. ra_monomial x α *⇩R ra_dcoeff c v α) ra_idx"
proof -
have Qsum: "ra_dterm_shift x v c b summable_on ra_idx" if b: "b ∈ Basis" for b
proof -
have eq: "ra_dterm_shift x v c b
= (λα. (v ∙ b) *⇩R
(ra_monomial x α *⇩R (real (Suc (α b)) *⇩R c (ra_inc α b))))"
by (rule ext, simp add: ra_dterm_shift_def ac_simps)
have "(λα. (v ∙ b) *⇩R
(ra_monomial x α *⇩R (real (Suc (α b)) *⇩R c (ra_inc α b))))
summable_on ra_idx"
using summable_on_bounded_linear[OF bounded_linear_scaleR_right[of "v ∙ b"], OF S[OF b]]
by simp
thus ?thesis by (simp only: eq)
qed
have Psum: "ra_dterm x v c b summable_on ra_idx" if b: "b ∈ Basis" for b
using Qsum[OF b] summable_dterm_iff_dterm_shift[OF b] by blast
have "infsum (λα. ra_Dmonomial x α v *⇩R c α) ra_idx
= infsum (λα. ∑b∈Basis. ra_dterm x v c b α) ra_idx"
by (simp add: Dmonomial_eq_sum_dterm)
also have "… = (∑b∈Basis. infsum (ra_dterm x v c b) ra_idx)"
by (rule infsum_finite_sum[OF finite_Basis]) (rule Psum)
also have "… = (∑b∈Basis. infsum (ra_dterm_shift x v c b) ra_idx)"
by (rule sum.cong[OF refl]) (rule infsum_dterm_eq_dterm_shift)
also have "… = infsum (λα. ∑b∈Basis. ra_dterm_shift x v c b α) ra_idx"
by (rule infsum_finite_sum[OF finite_Basis, symmetric]) (rule Qsum)
also have "… = infsum (λα. ra_monomial x α *⇩R ra_dcoeff c v α) ra_idx"
by (simp add: dcoeff_eq_sum_dterm_shift)
finally show ?thesis .
qed
lemma ra_power_series_differentiable:
fixes f :: "'a::euclidean_space ⇒ 'b::banach"
assumes r: "0 < r"
and series:
"⋀y. dist y x0 < r ⟹
((λα. ra_monomial (y - x0) α *⇩R c α)
has_sum f y) ra_idx"
and x: "dist x x0 < r"
shows "f differentiable (at x)"
proof -
have "(f has_derivative
(λv. infsum (λα. ra_Dmonomial (x - x0) α v *⇩R c α) ra_idx))
(at x)"
by (rule ra_power_series_has_derivative[OF r series x])
thus ?thesis
unfolding differentiable_def by blast
qed
lemma ra_power_series_frechet_derivative:
fixes f :: "'a::euclidean_space ⇒ 'b::banach"
assumes r: "0 < r"
and series:
"⋀y. dist y x0 < r ⟹
((λα. ra_monomial (y - x0) α *⇩R c α)
has_sum f y) ra_idx"
and x: "dist x x0 < r"
shows
"frechet_derivative f (at x) v =
infsum
(λα. ra_Dmonomial (x - x0) α v *⇩R c α)
ra_idx"
proof -
have "(λv. infsum (λα. ra_Dmonomial (x - x0) α v *⇩R c α) ra_idx)
= frechet_derivative f (at x)"
by (rule frechet_derivative_at[OF ra_power_series_has_derivative[OF r series x]])
thus ?thesis by (rule fun_cong[symmetric])
qed
lemma ra_power_series_continuous_on:
fixes f :: "'a::euclidean_space ⇒ 'b::banach"
assumes r: "0 < r"
and series:
"⋀y. dist y x0 < r ⟹
((λα. ra_monomial (y - x0) α *⇩R c α)
has_sum f y) ra_idx"
shows "continuous_on (ball x0 r) f"
proof (rule continuous_at_imp_continuous_on, clarify)
fix x assume "x ∈ ball x0 r"
then have x: "dist x x0 < r" by (simp add: dist_commute)
have "f differentiable (at x)"
by (rule ra_power_series_differentiable[OF r series x])
then have "continuous (at x within UNIV) f"
by (rule differentiable_imp_continuous_within)
then show "continuous (at x) f" by simp
qed
text ‹Summability of the differentiated coefficient family near an interior point, in any
direction.›
lemma ra_Dmono_summable_interior:
fixes c :: "('a::euclidean_space ⇒ nat) ⇒ 'b::banach"
assumes r: "0 < r"
and series: "⋀z. dist z x0 < r ⟹
((λα. ra_monomial (z - x0) α *⇩R c α) has_sum F z) ra_idx"
and y: "dist y x0 < r"
shows "(λα. ra_Dmonomial (y - x0) α w *⇩R c α) summable_on ra_idx"
proof -
obtain δ0 q K where δ0: "0 < δ0" and q0: "0 ≤ q" and q1: "q < 1" and Knn: "0 ≤ K"
and majsumm: "(λα. K * real (ra_deg α + 1) * q ^ ra_deg α) summable_on ra_idx"
and inball: "⋀z. dist z y < δ0 ⟹ dist z x0 < r"
and tbound: "⋀z α v. dist z y < δ0 ⟹ α ∈ ra_idx ⟹
norm (ra_Dmonomial (z - x0) α v *⇩R c α)
≤ norm v * (K * real (ra_deg α + 1) * q ^ ra_deg α)"
using diff_majorant_interior[OF r series y] by blast
have majw0: "(λα::'a⇒nat. (norm w * K) * (real (ra_deg α + 1) * q ^ ra_deg α))
summable_on ra_idx"
by (rule summable_on_cmult_right[OF deg_pow_summable[OF q0 q1]])
have majw: "(λα::'a⇒nat. norm w * (K * real (ra_deg α + 1) * q ^ ra_deg α))
summable_on ra_idx"
using majw0 by (simp add: mult.assoc)
show ?thesis
proof (rule abs_summable_summable,
rule summable_on_comparison_test[OF majw])
fix α :: "'a ⇒ nat" assume a: "α ∈ ra_idx"
have dyy: "dist y y < δ0" using δ0 by simp
show "norm (ra_Dmonomial (y - x0) α w *⇩R c α)
≤ norm w * (K * real (ra_deg α + 1) * q ^ ra_deg α)"
using tbound[OF dyy a] by simp
next
fix α :: "'a ⇒ nat" assume a: "α ∈ ra_idx"
show "0 ≤ norm (ra_Dmonomial (y - x0) α w *⇩R c α)" by simp
qed
qed
text ‹The @{const ra_dterm} in the direction ‹b ∈ Basis› is a directional derivative term, hence
summable.›
lemma ra_dterm_eq_Dmonomial_basis:
fixes x :: "'a::euclidean_space"
and c :: "('a ⇒ nat) ⇒ 'b::real_normed_vector"
assumes b: "b ∈ Basis"
shows "ra_dterm x b c b α = ra_Dmonomial x α b *⇩R c α"
proof -
have "ra_Dmonomial x α b
= (∑b'∈Basis. real (α b') * (b ∙ b') *
(x ∙ b') ^ (α b' - 1) * (∏d∈Basis - {b'}. (x ∙ d) ^ (α d)))"
by (simp add: ra_Dmonomial_def)
also have "… = real (α b) * (b ∙ b) *
(x ∙ b) ^ (α b - 1) * (∏d∈Basis - {b}. (x ∙ d) ^ (α d))"
proof (rule sum.remove[OF finite_Basis b, THEN trans])
have "(∑b'∈Basis - {b}. real (α b') * (b ∙ b') *
(x ∙ b') ^ (α b' - 1) * (∏d∈Basis - {b'}. (x ∙ d) ^ (α d))) = 0"
by (rule sum.neutral) (auto simp: inner_Basis b)
thus "real (α b) * (b ∙ b) * (x ∙ b) ^ (α b - 1) *
(∏d∈Basis - {b}. (x ∙ d) ^ (α d)) +
(∑b'∈Basis - {b}. real (α b') * (b ∙ b') *
(x ∙ b') ^ (α b' - 1) * (∏d∈Basis - {b'}. (x ∙ d) ^ (α d)))
= real (α b) * (b ∙ b) *
(x ∙ b) ^ (α b - 1) * (∏d∈Basis - {b}. (x ∙ d) ^ (α d))"
by simp
qed
finally have eqD: "ra_Dmonomial x α b
= real (α b) * (b ∙ b) * (x ∙ b) ^ (α b - 1) *
(∏d∈Basis - {b}. (x ∙ d) ^ (α d))" .
have "ra_dterm x b c b α
= (real (α b) * (b ∙ b) * (x ∙ b) ^ (α b - 1) *
(∏d∈Basis - {b}. (x ∙ d) ^ (α d))) *⇩R c α"
by (simp add: ra_dterm_def)
also have "… = ra_Dmonomial x α b *⇩R c α" by (simp only: eqD)
finally show ?thesis .
qed
lemma ra_directional_derivative_series:
fixes f :: "'a::euclidean_space ⇒ 'b::banach"
assumes r: "0 < r"
and series:
"⋀y. dist y x0 < r ⟹
((λα. ra_monomial (y - x0) α *⇩R c α)
has_sum f y) ra_idx"
and y: "dist y x0 < r"
shows
"((λα. ra_monomial (y - x0) α *⇩R
ra_dcoeff c v α)
has_sum frechet_derivative f (at y) v)
ra_idx"
proof -
have fd: "frechet_derivative f (at y) v
= infsum (λα. ra_Dmonomial (y - x0) α v *⇩R c α) ra_idx"
by (rule ra_power_series_frechet_derivative[OF r series y])
have S6: "(λα. ra_monomial (y - x0) α *⇩R
(real (Suc (α b)) *⇩R c (ra_inc α b))) summable_on ra_idx"
if b: "b ∈ Basis" for b
proof -
have Dsum: "(λα. ra_Dmonomial (y - x0) α b *⇩R c α) summable_on ra_idx"
by (rule ra_Dmono_summable_interior[OF r series y])
have Pid: "ra_dterm (y - x0) b c b = (λα. ra_Dmonomial (y - x0) α b *⇩R c α)"
by (rule ext) (rule ra_dterm_eq_Dmonomial_basis[OF b])
have Psum: "ra_dterm (y - x0) b c b summable_on ra_idx"
by (simp only: Pid Dsum)
have Qsum: "ra_dterm_shift (y - x0) b c b summable_on ra_idx"
using Psum summable_dterm_iff_dterm_shift[OF b] by blast
have Qeq: "ra_dterm_shift (y - x0) b c b
= (λα. ra_monomial (y - x0) α *⇩R
(real (Suc (α b)) *⇩R c (ra_inc α b)))"
by (rule ext) (simp add: ra_dterm_shift_def inner_Basis b)
show ?thesis using Qsum by (simp only: Qeq)
qed
have reindex: "infsum (λα. ra_Dmonomial (y - x0) α v *⇩R c α) ra_idx
= infsum (λα. ra_monomial (y - x0) α *⇩R ra_dcoeff c v α) ra_idx"
by (rule ra_derivative_reindex[OF S6])
have Qfsum: "ra_dterm_shift (y - x0) v c b summable_on ra_idx" if b: "b ∈ Basis" for b
proof -
have Pid: "ra_dterm (y - x0) v c b summable_on ra_idx ⟹ ?thesis"
using summable_dterm_iff_dterm_shift[OF b] by blast
have Dsum: "(λα. ra_Dmonomial (y - x0) α b *⇩R c α) summable_on ra_idx"
by (rule ra_Dmono_summable_interior[OF r series y])
have Pbid: "ra_dterm (y - x0) b c b = (λα. ra_Dmonomial (y - x0) α b *⇩R c α)"
by (rule ext) (rule ra_dterm_eq_Dmonomial_basis[OF b])
have Pbsum: "ra_dterm (y - x0) b c b summable_on ra_idx"
by (simp only: Pbid Dsum)
have scal: "ra_dterm (y - x0) v c b = (λα. (v ∙ b) *⇩R ra_dterm (y - x0) b c b α)"
by (rule ext) (simp add: ra_dterm_def inner_Basis b algebra_simps)
have "(λα. (v ∙ b) *⇩R ra_dterm (y - x0) b c b α) summable_on ra_idx"
by (rule summable_on_bounded_linear[OF bounded_linear_scaleR_right Pbsum])
then have "ra_dterm (y - x0) v c b summable_on ra_idx" by (simp only: scal)
thus ?thesis using Pid by blast
qed
have Qreg: "(λα. ra_monomial (y - x0) α *⇩R ra_dcoeff c v α)
= (λα. ∑b∈Basis. ra_dterm_shift (y - x0) v c b α)"
by (rule ext) (rule dcoeff_eq_sum_dterm_shift)
have Qsumm: "(λα. ra_monomial (y - x0) α *⇩R ra_dcoeff c v α) summable_on ra_idx"
by (simp only: Qreg) (rule summable_on_finite_sum[OF finite_Basis Qfsum])
have "((λα. ra_monomial (y - x0) α *⇩R ra_dcoeff c v α)
has_sum infsum (λα. ra_monomial (y - x0) α *⇩R ra_dcoeff c v α) ra_idx) ra_idx"
by (rule has_sum_infsum[OF Qsumm])
also have "infsum (λα. ra_monomial (y - x0) α *⇩R ra_dcoeff c v α) ra_idx
= infsum (λα. ra_Dmonomial (y - x0) α v *⇩R c α) ra_idx"
by (rule reindex[symmetric])
also have "… = frechet_derivative f (at y) v" by (rule fd[symmetric])
finally show ?thesis .
qed
text ‹The pointwise @{const Ck_at} property, by induction on @{term k} for all power series at
once (a directional derivative has coefficients @{term ‹ra_dcoeff cc v›}).›
lemma ra_power_series_Ck_at_aux:
fixes x0 :: "'a::euclidean_space"
assumes r: "0 < r"
shows "⋀(g::'a ⇒ 'b::banach) cc x.
(⋀z. dist z x0 < r ⟹
((λα. ra_monomial (z - x0) α *⇩R cc α) has_sum g z) ra_idx)
⟹ x ∈ ball x0 r ⟹ Ck_at k g x"
proof (induct k)
case (0 g cc x)
then have x: "dist x x0 < r" by (simp add: dist_commute)
have "g differentiable (at x)"
by (rule ra_power_series_differentiable[OF r 0(1) x])
then have "continuous (at x within UNIV) g"
by (rule differentiable_imp_continuous_within)
then have "continuous (at x) g" by simp
thus ?case by simp
next
case (Suc k g cc x)
have series: "⋀z. dist z x0 < r ⟹
((λα. ra_monomial (z - x0) α *⇩R cc α) has_sum g z) ra_idx"
by (rule Suc.prems(1))
have xball: "x ∈ ball x0 r" by (rule Suc.prems(2))
then have x: "dist x x0 < r" by (simp add: dist_commute)
have nbhd: "open (ball x0 r) ∧ x ∈ ball x0 r ∧ (∀y∈ball x0 r. Ck_at k g y)"
proof (intro conjI ballI)
show "open (ball x0 r)" by simp
show "x ∈ ball x0 r" by (rule xball)
fix y assume yb: "y ∈ ball x0 r"
show "Ck_at k g y" by (rule Suc.hyps[OF series yb])
qed
have diff: "g differentiable (at x)"
by (rule ra_power_series_differentiable[OF r series x])
have dirCk: "Ck_at k (λy. frechet_derivative g (at y) v) x" for v
proof -
have dseries: "⋀z. dist z x0 < r ⟹
((λα. ra_monomial (z - x0) α *⇩R ra_dcoeff cc v α)
has_sum frechet_derivative g (at z) v) ra_idx"
by (rule ra_directional_derivative_series[OF r series])
show "Ck_at k (λy. frechet_derivative g (at y) v) x"
by (rule Suc.hyps[OF dseries xball])
qed
show ?case
by (simp only: Ck_at.simps(2)) (intro conjI exI[where x = "ball x0 r"] nbhd diff allI dirCk)
qed
lemma ra_power_series_Ck_on:
fixes f :: "'a::euclidean_space ⇒ 'b::banach"
assumes r: "0 < r"
and series:
"⋀y. dist y x0 < r ⟹
((λα. ra_monomial (y - x0) α *⇩R c α)
has_sum f y) ra_idx"
shows "Ck_on k f (ball x0 r)"
unfolding Ck_on_def
proof (intro conjI ballI)
show "open (ball x0 r)" by simp
fix x assume xb: "x ∈ ball x0 r"
show "Ck_at k f x"
by (rule ra_power_series_Ck_at_aux[OF r series xb])
qed
lemma ra_power_series_Ck_at:
fixes f :: "'a::euclidean_space ⇒ 'b::banach"
assumes r: "0 < r"
and series:
"⋀y. dist y x0 < r ⟹
((λα. ra_monomial (y - x0) α *⇩R c α)
has_sum f y) ra_idx"
shows "Ck_at k f x0"
proof -
have C: "Ck_on k f (ball x0 r)"
by (rule ra_power_series_Ck_on[OF r series])
show ?thesis
using C r
by (simp add: Ck_on_def)
qed
subsection ‹Analytic implies infinitely differentiable›
theorem real_analytic_imp_Cinfinity:
fixes f :: "'a::euclidean_space ⇒ 'b::banach"
assumes A: "real_analytic_on f U"
shows "Cinfinity_on f U"
proof -
have openU: "open U"
using A unfolding real_analytic_on_def by blast
show ?thesis
unfolding Cinfinity_on_def Cinfinity_at_def
proof (intro conjI ballI allI)
show "open U" by (rule openU)
next
fix x k
assume xU: "x ∈ U"
from A xU obtain r c where
r: "0 < r"
and series:
"⋀y. dist y x < r ⟹
((λα. ra_monomial (y - x) α *⇩R c α)
has_sum f y) ra_idx"
unfolding real_analytic_on_def by blast
show "Ck_at k f x"
by (rule ra_power_series_Ck_at[OF r series])
qed
qed
text ‹The converse fails: the flat function ‹exp_bump› is a counterexample.›
lemma real_analytic_on_open_subset:
assumes F: "real_analytic_on f U"
and V: "open V"
and sub: "V ⊆ U"
shows "real_analytic_on f V"
unfolding real_analytic_on_def
proof (intro conjI ballI)
show "open V" by (rule V)
next
fix x assume xV: "x ∈ V"
hence xU: "x ∈ U"
using sub by blast
from F xU show "∃r>0. ∃c. ∀y. dist y x < r ⟶
((λα. ra_monomial (y - x) α *⇩R c α) has_sum f y) ra_idx"
unfolding real_analytic_on_def by blast
qed
subsection ‹Closure properties›
lemma real_analytic_on_const:
fixes k :: "'b::real_normed_vector"
shows "open U ⟹ real_analytic_on ((λ_. k) :: 'a::euclidean_space ⇒ 'b) U"
proof -
assume U: "open U"
define a0 :: "'a ⇒ nat" where "a0 = (λ_. 0)"
have a0_idx: "a0 ∈ ra_idx" by (simp add: ra_idx_def a0_def)
define c :: "('a ⇒ nat) ⇒ 'b" where "c = (λα. if α = a0 then k else 0)"
have hs: "((λα. ra_monomial h α *⇩R c α) has_sum k) ra_idx" for h :: 'a
proof -
have sing: "((λα. ra_monomial h α *⇩R c α) has_sum
(∑α∈{a0}. ra_monomial h α *⇩R c α)) {a0}"
by (rule has_sum_finite) auto
have val: "(∑α∈{a0}. ra_monomial h α *⇩R c α) = k"
by (simp add: c_def ra_monomial_def a0_def)
have "((λα. ra_monomial h α *⇩R c α) has_sum k) ra_idx
= ((λα. ra_monomial h α *⇩R c α) has_sum k) {a0}"
by (rule has_sum_cong_neutral) (auto simp: c_def a0_idx)
thus ?thesis using sing val by simp
qed
show ?thesis
unfolding real_analytic_on_def
proof (intro conjI ballI)
show "open U" by (rule U)
next
fix x0 :: 'a assume "x0 ∈ U"
show "∃r>0. ∃c. ∀x. dist x x0 < r ⟶
((λα. ra_monomial (x - x0) α *⇩R c α) has_sum (λ_. k) x) ra_idx"
by (intro exI[where x=1] conjI exI[where x=c] allI impI; simp only: hs)
qed
qed
lemma real_analytic_on_add:
assumes F: "real_analytic_on f U" and G: "real_analytic_on g U"
shows "real_analytic_on (λx. f x + g x) U"
proof -
from F have U: "open U" by (simp only: real_analytic_on_def)
show ?thesis
unfolding real_analytic_on_def
proof (intro conjI ballI)
show "open U" by (rule U)
next
fix x0 assume x0: "x0 ∈ U"
from F x0 have "∃r>0. ∃c. ∀x. dist x x0 < r ⟶
((λα. ra_monomial (x - x0) α *⇩R c α) has_sum f x) ra_idx"
by (simp only: real_analytic_on_def)
then obtain r1 c1 where r1: "0 < r1"
and F1: "⋀x. dist x x0 < r1 ⟹
((λα. ra_monomial (x - x0) α *⇩R c1 α) has_sum f x) ra_idx"
by blast
from G x0 have "∃r>0. ∃c. ∀x. dist x x0 < r ⟶
((λα. ra_monomial (x - x0) α *⇩R c α) has_sum g x) ra_idx"
by (simp only: real_analytic_on_def)
then obtain r2 c2 where r2: "0 < r2"
and G1: "⋀x. dist x x0 < r2 ⟹
((λα. ra_monomial (x - x0) α *⇩R c2 α) has_sum g x) ra_idx"
by blast
show "∃r>0. ∃c. ∀x. dist x x0 < r ⟶
((λα. ra_monomial (x - x0) α *⇩R c α) has_sum (f x + g x)) ra_idx"
proof (intro exI[where x="min r1 r2"] conjI exI[where x="λα. c1 α + c2 α"] allI impI)
show "0 < min r1 r2" using r1 r2 by simp
next
fix x assume d: "dist x x0 < min r1 r2"
have "((λα. ra_monomial (x - x0) α *⇩R c1 α
+ ra_monomial (x - x0) α *⇩R c2 α) has_sum (f x + g x)) ra_idx"
by (rule has_sum_add) (use d F1 G1 in auto)
thus "((λα. ra_monomial (x - x0) α *⇩R (c1 α + c2 α)) has_sum (f x + g x)) ra_idx"
by (simp only: scaleR_add_right)
qed
qed
qed
lemma real_analytic_on_scaleR:
assumes F: "real_analytic_on f U"
shows "real_analytic_on (λx. a *⇩R f x) U"
proof -
from F have U: "open U" by (simp only: real_analytic_on_def)
show ?thesis
unfolding real_analytic_on_def
proof (intro conjI ballI)
show "open U" by (rule U)
next
fix x0 assume x0: "x0 ∈ U"
from F x0 have "∃r>0. ∃c. ∀x. dist x x0 < r ⟶
((λα. ra_monomial (x - x0) α *⇩R c α) has_sum f x) ra_idx"
by (simp only: real_analytic_on_def)
then obtain r c where r: "0 < r"
and F1: "⋀x. dist x x0 < r ⟹
((λα. ra_monomial (x - x0) α *⇩R c α) has_sum f x) ra_idx"
by blast
show "∃r>0. ∃c. ∀x. dist x x0 < r ⟶
((λα. ra_monomial (x - x0) α *⇩R c α) has_sum (a *⇩R f x)) ra_idx"
proof (intro exI[where x=r] conjI exI[where x="λα. a *⇩R c α"] allI impI)
show "0 < r" by (rule r)
next
fix x assume d: "dist x x0 < r"
have "((λα. a *⇩R (ra_monomial (x - x0) α *⇩R c α)) has_sum (a *⇩R f x)) ra_idx"
using F1 bounded_linear_scaleR_right d has_sum_bounded_linear by blast
thus "((λα. ra_monomial (x - x0) α *⇩R (a *⇩R c α)) has_sum (a *⇩R f x)) ra_idx"
by (simp only: scaleR_left_commute mult.commute)
qed
qed
qed
lemma real_analytic_on_mult:
fixes f g :: "'a::euclidean_space ⇒ real"
shows "real_analytic_on f U ⟹ real_analytic_on g U ⟹ real_analytic_on (λx. f x * g x) U"
proof -
assume F: "real_analytic_on f U" and G: "real_analytic_on g U"
from F have U: "open U" by (simp only: real_analytic_on_def)
define ra_idx_add :: "('a⇒nat) ⇒ ('a⇒nat) ⇒ ('a⇒nat)" where
"ra_idx_add = (λα β b. α b + β b)"
define ra_idx_diff :: "('a⇒nat) ⇒ ('a⇒nat) ⇒ ('a⇒nat)" where
"ra_idx_diff = (λγ α b. γ b - α b)"
define ra_idx_le :: "('a⇒nat) ⇒ ('a⇒nat) ⇒ bool" where
"ra_idx_le = (λα γ. ∀b. α b ≤ γ b)"
have idx_add: "ra_idx_add α β ∈ ra_idx" if "α ∈ ra_idx" "β ∈ ra_idx" for α β
proof -
have "{b. ra_idx_add α β b ≠ 0} ⊆ {b. α b ≠ 0} ∪ {b. β b ≠ 0}"
by (auto simp: ra_idx_add_def)
also have "… ⊆ Basis" using that by (auto simp: ra_idx_def)
finally show ?thesis by (simp add: ra_idx_def)
qed
have idx_sub: "ra_idx_diff γ α ∈ ra_idx" if "γ ∈ ra_idx" for γ α
proof -
have "{b. ra_idx_diff γ α b ≠ 0} ⊆ {b. γ b ≠ 0}" by (auto simp: ra_idx_diff_def)
also have "… ⊆ Basis" using that by (auto simp: ra_idx_def)
finally show ?thesis by (simp add: ra_idx_def)
qed
have mono_add: "ra_monomial h (ra_idx_add α β) = ra_monomial h α * ra_monomial h β"
for h :: 'a and α β
by (simp only: ra_monomial_def ra_idx_add_def power_add prod.distrib)
have idx_lower_fin: "finite {α. α ∈ ra_idx ∧ ra_idx_le α γ}" for γ :: "'a ⇒ nat"
proof -
define N where "N = Max (insert 0 (γ ` (Basis :: 'a set)))"
have "{α. α ∈ ra_idx ∧ ra_idx_le α γ}
⊆ {hh. ∀x::'a. (x ∈ Basis ⟶ hh x ∈ {0..N}) ∧ (x ∉ Basis ⟶ hh x = 0)}"
proof (rule subsetI)
fix α :: "'a ⇒ nat" assume "α ∈ {α. α ∈ ra_idx ∧ ra_idx_le α γ}"
then have a1: "α ∈ ra_idx" and a2: "ra_idx_le α γ" by auto
have "∀x::'a. (x ∈ Basis ⟶ α x ∈ {0..N}) ∧ (x ∉ Basis ⟶ α x = 0)"
proof (intro allI conjI impI)
fix x :: 'a assume "x ∈ Basis"
have "α x ≤ γ x" using a2 by (simp only: ra_idx_le_def)
also have "γ x ≤ N" unfolding N_def using ‹x ∈ Basis› by (intro Max_ge) auto
finally show "α x ∈ {0..N}" by simp
next
fix x :: 'a assume "x ∉ Basis"
with a1 show "α x = 0" by (auto simp: ra_idx_def)
qed
thus "α ∈ {hh. ∀x::'a. (x ∈ Basis ⟶ hh x ∈ {0..N}) ∧ (x ∉ Basis ⟶ hh x = 0)}"
by simp
qed
moreover have "finite {hh::'a⇒nat. ∀x. (x ∈ Basis ⟶ hh x ∈ {0..N}) ∧ (x ∉ Basis ⟶ hh x = (0::nat))}"
by (rule finite_set_of_finite_funs) auto
ultimately show ?thesis by (rule finite_subset)
qed
have prod_has_sum:
"((λ(α,β). u α * v β) has_sum (Uv * Vv)) (I × I)"
if uHS: "(u has_sum Uv) I" and vHS: "(v has_sum Vv) I"
for u v :: "('a ⇒ nat) ⇒ real" and Uv Vv I
proof -
have u_abs: "(λz. norm (u z)) summable_on I"
using uHS has_sum_imp_summable summable_on_iff_abs_summable_on_real by blast
have v_abs: "(λz. norm (v z)) summable_on I"
using vHS has_sum_imp_summable summable_on_iff_abs_summable_on_real by blast
have inner: "((λβ. u α * v β) has_sum (u α * Vv)) I" for α
by (rule has_sum_cmult_right[OF vHS])
have outer: "((λα. u α * Vv) has_sum (Uv * Vv)) I"
by (rule has_sum_cmult_left[OF uHS])
have inner_abs: "(λβ. norm (u α * v β)) summable_on I" for α
proof -
have "(λβ. norm (u α) * norm (v β)) summable_on I"
using v_abs by (rule summable_on_cmult_right)
thus ?thesis by (simp only: norm_mult flip: abs_mult)
qed
have tail_abs: "(λα. norm (∑⇩∞β∈I. norm (u α * v β))) summable_on I"
proof -
have eq: "norm (∑⇩∞β∈I. norm (u α * v β)) = norm (u α) * (∑⇩∞β∈I. norm (v β))" for α
proof -
have nn: "(∑⇩∞β∈I. norm (u α * v β)) = norm (u α) * (∑⇩∞β∈I. norm (v β))"
proof -
have "(∑⇩∞β∈I. norm (u α * v β)) = (∑⇩∞β∈I. norm (u α) * norm (v β))"
by (simp add: abs_mult)
also have "… = norm (u α) * (∑⇩∞β∈I. norm (v β))"
by (rule infsum_cmult_right) (rule v_abs)
finally show ?thesis .
qed
have ge: "(0::real) ≤ norm (u α) * (∑⇩∞β∈I. norm (v β))"
by (intro mult_nonneg_nonneg) (auto intro: infsum_nonneg)
from nn ge show ?thesis by simp
qed
have "(λα. norm (u α) * (∑⇩∞β∈I. norm (v β))) summable_on I"
using u_abs by (rule summable_on_cmult_left)
thus ?thesis unfolding eq .
qed
have conj1: "∀α∈I. (λβ. norm ((λ(α,β). u α * v β) (α, β))) summable_on I"
proof
fix α assume "α ∈ I"
have "(λβ. norm (u α * v β)) summable_on I" by (rule inner_abs)
thus "(λβ. norm ((λ(α,β). u α * v β) (α, β))) summable_on I" by simp
qed
have conj2: "(λα. norm (∑⇩∞β∈I. norm ((λ(α,β). u α * v β) (α, β)))) summable_on I"
proof -
have "(λα. norm (∑⇩∞β∈I. norm (u α * v β))) summable_on I" by (rule tail_abs)
thus ?thesis by simp
qed
have absS: "(λz. norm ((λ(α,β). u α * v β) z)) summable_on (Sigma I (λ_. I))"
by (rule Infinite_Sum.abs_summable_on_Sigma_iff
[where f = "λ(α,β). u α * v β" and A = I and B = "λ_. I", THEN iffD2,
OF conjI[OF conj1 conj2]])
have summ: "(λ(α,β). u α * v β) summable_on Sigma I (λ_. I)"
by (rule abs_summable_summable[OF absS])
have "((λ(α,β). u α * v β) has_sum (Uv * Vv)) (Sigma I (λ_. I))"
proof (rule has_sum_SigmaI[where g = "λα. u α * Vv"])
fix α assume "α ∈ I"
have "((λβ. u α * v β) has_sum (u α * Vv)) I" by (rule inner)
thus "((λβ. (λ(α,β). u α * v β) (α, β)) has_sum (u α * Vv)) I" by simp
next
show "((λα. u α * Vv) has_sum (Uv * Vv)) I" by (rule outer)
next
show "(λ(α,β). u α * v β) summable_on Sigma I (λ_. I)" by (rule summ)
qed
thus ?thesis by (simp only: Sigma_def)
qed
show "real_analytic_on (λx. f x * g x) U"
unfolding real_analytic_on_def
proof (intro conjI ballI)
show "open U" by (rule U)
next
fix x0 assume x0: "x0 ∈ U"
from F x0 obtain r1 c1 where r1: "0 < r1"
and F1: "⋀x. dist x x0 < r1 ⟹
((λα. ra_monomial (x - x0) α *⇩R c1 α) has_sum f x) ra_idx"
unfolding real_analytic_on_def by blast
from G x0 obtain r2 c2 where r2: "0 < r2"
and G1: "⋀x. dist x x0 < r2 ⟹
((λα. ra_monomial (x - x0) α *⇩R c2 α) has_sum g x) ra_idx"
unfolding real_analytic_on_def by blast
define low where "low = (λγ::'a⇒nat. {α. α ∈ ra_idx ∧ ra_idx_le α γ})"
define cprod :: "('a ⇒ nat) ⇒ real" where
"cprod = (λγ. ∑α∈low γ. c1 α * c2 (ra_idx_diff γ α))"
show "∃r>0. ∃c. ∀x. dist x x0 < r ⟶
((λα. ra_monomial (x - x0) α *⇩R c α) has_sum (f x * g x)) ra_idx"
proof (intro exI[where x="min r1 r2"] conjI exI[where x=cprod] allI impI)
show "0 < min r1 r2" using r1 r2 by simp
next
fix x assume dx: "dist x x0 < min r1 r2"
have dx1: "dist x x0 < r1" using dx min.cobounded1 by (rule order_less_le_trans)
have dx2: "dist x x0 < r2" using dx min.cobounded2 by (rule order_less_le_trans)
define h where "h = x - x0"
have F1': "((λα. ra_monomial h α * c1 α) has_sum f x) ra_idx"
using F1[OF dx1] by (simp add: h_def)
have G1': "((λβ. ra_monomial h β * c2 β) has_sum g x) ra_idx"
using G1[OF dx2] by (simp add: h_def)
have step1:
"((λ(α,β). (ra_monomial h α * c1 α) * (ra_monomial h β * c2 β))
has_sum (f x * g x)) (ra_idx × ra_idx)"
using prod_has_sum[OF F1' G1'] .
have step2:
"((λ(γ,α). ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α))) has_sum (f x * g x))
(Sigma ra_idx low)"
proof -
have "((λ(α,β). (ra_monomial h α * c1 α) * (ra_monomial h β * c2 β))
has_sum (f x * g x)) (ra_idx × ra_idx)
= ((λ(γ,α). ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α))) has_sum (f x * g x))
(Sigma ra_idx low)"
proof (rule has_sum_reindex_bij_witness
[where j = "λ(α,β). (ra_idx_add α β, α)" and i = "λ(γ,α). (α, ra_idx_diff γ α)"])
fix p :: "('a⇒nat) × ('a⇒nat)"
assume "p ∈ ra_idx × ra_idx"
obtain α β where p: "p = (α,β)" by (cases p)
show "(case (case p of (α,β) ⇒ (ra_idx_add α β, α)) of (γ,α) ⇒ (α, ra_idx_diff γ α)) = p"
by (simp add: p ra_idx_diff_def ra_idx_add_def)
next
fix p :: "('a⇒nat) × ('a⇒nat)"
assume P: "p ∈ ra_idx × ra_idx"
obtain α β where p: "p = (α,β)" by (cases p)
have aα: "α ∈ ra_idx" and aβ: "β ∈ ra_idx" using P p by auto
have m1: "ra_idx_add α β ∈ ra_idx" by (rule idx_add[OF aα aβ])
have m2: "α ∈ low (ra_idx_add α β)"
using aα by (simp add: low_def ra_idx_le_def ra_idx_add_def)
show "(case p of (α,β) ⇒ (ra_idx_add α β, α)) ∈ Sigma ra_idx low"
using m1 m2 by (simp add: p)
next
fix q :: "('a⇒nat) × ('a⇒nat)"
assume Q: "q ∈ Sigma ra_idx low"
obtain γ α where q: "q = (γ,α)" by (cases q)
have gγ: "γ ∈ ra_idx" and l: "ra_idx_le α γ" using Q q by (auto simp: low_def)
have "ra_idx_add α (ra_idx_diff γ α) = γ"
proof (rule ext)
fix b have "α b ≤ γ b" using l by (simp only: ra_idx_le_def)
thus "ra_idx_add α (ra_idx_diff γ α) b = γ b" by (simp only: ra_idx_add_def ra_idx_diff_def)
qed
then show "(case (case q of (γ,α) ⇒ (α, ra_idx_diff γ α)) of (α,β) ⇒ (ra_idx_add α β, α)) = q"
by (simp add: q)
next
fix q :: "('a⇒nat) × ('a⇒nat)"
assume Q: "q ∈ Sigma ra_idx low"
obtain γ α where q: "q = (γ,α)" by (cases q)
have gγ: "γ ∈ ra_idx" and aα: "α ∈ ra_idx" using Q q by (auto simp: low_def)
show "(case q of (γ,α) ⇒ (α, ra_idx_diff γ α)) ∈ ra_idx × ra_idx"
by (simp add: q aα idx_sub[OF gγ])
next
fix p :: "('a⇒nat) × ('a⇒nat)"
assume P: "p ∈ ra_idx × ra_idx"
obtain α β where p: "p = (α,β)" by (cases p)
have sub_eq: "ra_idx_diff (ra_idx_add α β) α = β" by (simp add: ra_idx_add_def ra_idx_diff_def)
have mm: "ra_monomial h α * ra_monomial h β = ra_monomial h (ra_idx_add α β)"
by (simp only: mono_add)
have "ra_monomial h (ra_idx_add α β) * (c1 α * c2 (ra_idx_diff (ra_idx_add α β) α))
= ra_monomial h (ra_idx_add α β) * (c1 α * c2 β)" by (simp only: sub_eq)
also have "… = (ra_monomial h α * ra_monomial h β) * (c1 α * c2 β)"
by (simp only: mm)
also have "… = (ra_monomial h α * c1 α) * (ra_monomial h β * c2 β)"
by (simp only: mult.assoc mult.left_commute)
finally show "(case (case p of (α,β) ⇒ (ra_idx_add α β, α)) of (γ,α) ⇒
ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α)))
= (case p of (α,β) ⇒ (ra_monomial h α * c1 α) * (ra_monomial h β * c2 β))"
by (simp add: p)
qed simp
with step1 show ?thesis by simp
qed
have inner_fin:
"((λα. ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α))) has_sum
(ra_monomial h γ *⇩R cprod γ)) (low γ)" if "γ ∈ ra_idx" for γ
proof -
have fin: "finite (low γ)" using idx_lower_fin[of γ] by (simp only: low_def)
have "((λα. ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α))) has_sum
(∑α∈low γ. ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α)))) (low γ)"
by (rule has_sum_finite[OF fin])
also have "(∑α∈low γ. ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α)))
= ra_monomial h γ * (∑α∈low γ. c1 α * c2 (ra_idx_diff γ α))"
by (simp only: sum_distrib_left)
also have "(∑α∈low γ. c1 α * c2 (ra_idx_diff γ α)) = cprod γ"
by (simp only: cprod_def)
finally show ?thesis by simp
qed
have "((λγ. ra_monomial h γ *⇩R cprod γ) has_sum (f x * g x)) ra_idx"
proof (rule has_sum_Sigma'
[where f = "λ(γ,α). ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α))"
and A = ra_idx and B = low and a = "f x * g x"
and b = "λγ. ra_monomial h γ *⇩R cprod γ"])
show "((λ(γ,α). ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α))) has_sum (f x * g x))
(Sigma ra_idx low)" by (rule step2)
next
fix γ :: "'a ⇒ nat" assume "γ ∈ ra_idx"
then have "((λα. ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α))) has_sum
(ra_monomial h γ *⇩R cprod γ)) (low γ)" by (rule inner_fin)
thus "((λα. (λ(γ,α). ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α))) (γ, α)) has_sum
(ra_monomial h γ *⇩R cprod γ)) (low γ)" by simp
qed
thus "((λα. ra_monomial (x - x0) α *⇩R cprod α) has_sum (f x * g x)) ra_idx"
by (simp only: h_def)
qed
qed
qed
subsection ‹Nowhere-dense zeros in one dimension›
text ‹On a connected open set, the zero set of a real-analytic function that is not identically
zero is nowhere dense. In one dimension, the set where all derivatives vanish is clopen;
the multivariate case reduces to this via one-dimensional slices.›
text ‹If all derivatives vanish at a point, the function vanishes on its Taylor ball there.›
lemma analytic_all_derivs_zero_imp_zero_on_ball:
fixes f :: "real ⇒ real"
assumes ana: "real_analytic_at_1d f c"
and z: "∀n. (deriv ^^ n) f c = 0"
obtains r where "r > 0" and "⋀y. ¦y - c¦ < r ⟹ f y = 0"
proof -
from ana obtain r where r: "r > 0"
and sums: "⋀x. ¦x - c¦ < r ⟹
(λn. (deriv ^^ n) f c / fact n * (x - c) ^ n) sums f x"
unfolding real_analytic_at_1d_def by blast
have "f y = 0" if "¦y - c¦ < r" for y
proof -
have "(λn. (deriv ^^ n) f c / fact n * (y - c) ^ n) sums f y"
by (rule sums[OF that])
moreover have "(λn. (deriv ^^ n) f c / fact n * (y - c) ^ n) = (λn. 0)"
using z by simp
ultimately have "(λn. (0::real)) sums f y" by simp
moreover have "(λn. (0::real)) sums 0" by (rule sums_zero)
ultimately show "f y = 0" by (rule sums_unique2)
qed
with r show ?thesis using that by blast
qed
theorem real_analytic_1d_nowhere_dense_zeros:
fixes f :: "real ⇒ real"
assumes ana: "real_analytic_on f U" and conn: "connected U"
and ex: "∃x∈U. f x ≠ 0"
shows "interior (closure {x ∈ U. f x = 0}) = {}"
proof -
from ana have oU: "open U"
and at: "⋀c. c ∈ U ⟹ real_analytic_at_1d f c"
by (auto simp: real_analytic_on_1d_iff)
text ‹Smoothness on @{term U}: every derivative exists everywhere on @{term U}.›
have smooth: "f n-times_differentiable_at x" if "x ∈ U" for n x
proof -
from at[OF that] obtain r where r: "r > 0"
and diff: "⋀y. ¦y - x¦ < r ⟹ (∀m. f m-times_differentiable_at y)"
unfolding real_analytic_at_1d_def by blast
show ?thesis using diff[of x] r by simp
qed
define Z where "Z = {x ∈ U. ∀n. (deriv ^^ n) f x = 0}"
text ‹$Z$ is open in $\mathbb{R}$ and contained in $U$, hence relatively open in $U$.›
have Zsub: "Z ⊆ U" by (auto simp: Z_def)
have Zopen: "open Z"
proof (rule openI)
fix x assume "x ∈ Z"
then have xU: "x ∈ U" and xz: "∀n. (deriv ^^ n) f x = 0" by (auto simp: Z_def)
obtain r1 where r1: "r1 > 0"
and fz: "⋀y. ¦y - x¦ < r1 ⟹ f y = 0"
using analytic_all_derivs_zero_imp_zero_on_ball[OF at[OF xU] xz] by blast
obtain r2 where r2: "r2 > 0" and ballU: "ball x r2 ⊆ U"
using oU xU open_contains_ball by blast
define r where "r = min r1 r2"
have rpos: "r > 0" using r1 r2 by (simp only: r_def)
have ballsub: "ball x r ⊆ Z"
proof
fix z assume zb: "z ∈ ball x r"
then have zd: "dist z x < r" by (simp add: dist_commute)
have zU: "z ∈ U" using zb ballU by (auto simp: r_def dist_commute)
have feq: "eventually (λw. f w = (λ_. 0) w) (nhds z)"
proof (rule eventually_nhds_in_open[THEN eventually_mono, of "ball x r" z])
show "open (ball x r)" by simp
show "z ∈ ball x r" using zb by simp
next
fix w assume "w ∈ ball x r"
then have "¦w - x¦ < r" by (simp add: dist_real_def dist_commute)
then have "¦w - x¦ < r1" by (simp only: r_def)
thus "f w = (λ_. 0) w" by (simp only: fz)
qed
have "(deriv ^^ n) f z = 0" for n
proof -
have "(deriv ^^ n) f z = (deriv ^^ n) (λ_. 0) z"
by (rule higher_deriv_cong_ev[OF feq refl])
also have "… = 0" by (simp add: kth_deriv_const_cases)
finally show ?thesis .
qed
thus "z ∈ Z" using zU by (simp add: Z_def)
qed
show "∃e>0. ball x e ⊆ Z" using rpos ballsub by blast
qed
have ZopenIn: "openin (top_of_set U) Z"
using Zopen Zsub by (metis Int_absorb1 openin_open_Int)
text ‹$Z$ is closed in $U$: each derivative is continuous on $U$.›
have cont: "continuous_on U ((deriv ^^ n) f)" for n
proof (rule continuous_at_imp_continuous_on, clarify)
fix x assume xU: "x ∈ U"
have "f (Suc n)-times_differentiable_at x" by (rule smooth[OF xU])
thus "continuous (at x) ((deriv ^^ n) f)"
by (rule k_times_differentiable_at_imp_isCont_kth_deriv[where j = n and k = n]) simp
qed
have Zinter: "Z = (⋂n. {x ∈ U. (deriv ^^ n) f x = 0})"
by (auto simp: Z_def)
have ZclosedIn: "closedin (top_of_set U) Z"
unfolding Zinter
proof (rule closedin_INT)
show "(UNIV :: nat set) ≠ {}" by simp
fix n :: nat assume "n ∈ (UNIV :: nat set)"
show "closedin (top_of_set U) {x ∈ U. (deriv ^^ n) f x = 0}"
by (rule continuous_closedin_preimage_constant[OF cont])
qed
text ‹If the interior of the closure were nonempty, $Z$ would be nonempty.›
define W where "W = interior (closure {x ∈ U. f x = 0})"
have Wopen: "open W" by (simp add: W_def)
have Zne: "Z ≠ {}" if WNE: "W ≠ {}"
proof -
from WNE obtain w where wW: "w ∈ W" by blast
have Wsub: "W ⊆ closure {x ∈ U. f x = 0}" by (simp only: W_def interior_subset)
obtain e where epos: "e > 0" and eball: "ball w e ⊆ W"
using wW Wopen open_contains_ball by blast
have wcl: "w ∈ closure {x ∈ U. f x = 0}" using wW Wsub by blast
have "ball w e ∩ {x ∈ U. f x = 0} ≠ {}"
proof -
have "w ∈ ball w e ∩ closure {x ∈ U. f x = 0}" using wcl epos by simp
hence "ball w e ∩ closure {x ∈ U. f x = 0} ≠ {}" by blast
thus "ball w e ∩ {x ∈ U. f x = 0} ≠ {}"
using open_Int_closure_eq_empty[OF open_ball, of w e "{x ∈ U. f x = 0}"] by blast
qed
then obtain u where uU: "u ∈ ball w e" "u ∈ U" "f u = 0" by blast
have uW: "u ∈ W" using uU(1) eball by blast
define V where "V = W ∩ U"
have Vopen: "open V" unfolding V_def by (intro open_Int Wopen oU)
have uV: "u ∈ V" using uW uU(2) by (simp add: V_def)
have fzeroV: "f v = 0" if "v ∈ V" for v
proof -
have vW: "v ∈ W" and vU: "v ∈ U" using that by (auto simp: V_def)
have vcl: "v ∈ closure {x ∈ U. f x = 0}" using vW Wsub by blast
have contv: "continuous (at v) f"
proof -
have "f (Suc 0)-times_differentiable_at v" by (rule smooth[OF vU])
thus ?thesis by (rule k_times_differentiable_at_imp_isCont)
qed
have "isCont f v" using contv by simp
from vcl obtain s where s: "⋀k. s k ∈ {x ∈ U. f x = 0}" "s ⇢ v"
using closure_sequential by blast
have "(λk. f (s k)) ⇢ f v"
using ‹isCont f v› s(2) by (simp only: continuous_within isCont_tendsto_compose)
moreover have "(λk. f (s k)) = (λk. 0)" using s(1) by auto
ultimately have "(λk. (0::real)) ⇢ f v" by simp
thus "f v = 0" by (simp only: LIMSEQ_const_iff)
qed
obtain ρ where ρ: "ρ > 0" and rball: "ball u ρ ⊆ V"
using uV Vopen open_contains_ball by blast
have feq: "eventually (λw. f w = (λ_. 0) w) (nhds u)"
proof (rule eventually_nhds_in_open[THEN eventually_mono, of "ball u ρ" u])
show "open (ball u ρ)" by simp
show "u ∈ ball u ρ" using ρ by simp
next
fix w assume "w ∈ ball u ρ"
then have "w ∈ V" using rball by blast
thus "f w = (λ_. 0) w" by (simp only: fzeroV)
qed
have "(deriv ^^ n) f u = 0" for n
proof -
have "(deriv ^^ n) f u = (deriv ^^ n) (λ_. 0) u"
by (rule higher_deriv_cong_ev[OF feq refl])
also have "… = 0" by (simp add: kth_deriv_const_cases)
finally show ?thesis .
qed
then have "u ∈ Z" using uU(2) by (simp add: Z_def)
thus "Z ≠ {}" by blast
qed
text ‹Connectedness: $Z$ is clopen in $U$, so $Z = \emptyset$ or $Z = U$.›
have clopen: "Z = {} ∨ Z = U"
using conn ZopenIn ZclosedIn unfolding connected_clopen by blast
text ‹If $W \neq \emptyset$ then $Z \neq \emptyset$, hence $Z = U$, forcing $f \equiv 0$ on $U$,
contradicting the assumption.›
show ?thesis
proof (rule ccontr)
assume "interior (closure {x ∈ U. f x = 0}) ≠ {}"
then have WNE: "W ≠ {}" by (simp add: W_def)
then have "Z ≠ {}" by (rule Zne)
with clopen have "Z = U" by blast
have "f x = 0" if "x ∈ U" for x
proof -
have "x ∈ Z" using that ‹Z = U› by simp
then have "∀n. (deriv ^^ n) f x = 0" by (simp add: Z_def)
then have "(deriv ^^ 0) f x = 0" by blast
thus "f x = 0" by simp
qed
with ex show False by blast
qed
qed
subsection ‹Convergent power series in one variable›
text ‹A convergent real power series about ‹c› makes ‹f› real-analytic at ‹c›.›
lemma real_powser_imp_real_analytic_at_1d:
fixes f :: "real ⇒ real"
assumes r: "0 < r"
and PS: "⋀x. ¦x - c¦ < r ⟹ (λn. a n * (x - c) ^ n) sums f x"
shows "real_analytic_at_1d f c"
proof -
have sums_a: "(λn. a n * z ^ n) sums f (c + z)" if "¦z¦ < r" for z
proof -
have "¦(c + z) - c¦ < r" using that by simp
from PS[OF this] show ?thesis by simp
qed
have summ_a: "summable (λn. a n * z ^ n)" if "¦z¦ < r" for z
using sums_a[OF that] by (rule sums_summable)
have summ_diffs: "summable (λm. (diffs ^^ n) a m * z ^ m)" if "¦z¦ < r" for n z
using that
proof (induction n arbitrary: z)
case 0
thus ?case using summ_a by simp
next
case (Suc n)
have "summable (λm. diffs ((diffs ^^ n) a) m * z ^ m)"
proof (rule termdiff_converges[where K = r])
show "norm z < r" using Suc.prems by simp
fix w :: real assume "norm w < r"
hence "¦w¦ < r" by simp
thus "summable (λm. (diffs ^^ n) a m * w ^ m)" by (rule Suc.IH)
qed
thus ?case by simp
qed
define S where "S = (λn y. ∑m. (diffs ^^ n) a m * (y - c) ^ m)"
have S0_eq_f: "S 0 x = f x" if "¦x - c¦ < r" for x
proof -
from sums_a[of "x - c"] that have "(λn. a n * (x - c) ^ n) sums f x" by simp
thus ?thesis by (simp add: S_def sums_iff)
qed
have S_deriv: "(S n has_field_derivative S (Suc n) x) (at x)"
if "¦x - c¦ < r" for n x
proof -
have H: "((λw. ∑m. (diffs ^^ n) a m * w ^ m)
has_field_derivative (∑m. diffs ((diffs ^^ n) a) m * (x - c) ^ m))
(at (x - c))"
proof (rule termdiffs_strong'[where K = r])
fix w :: real assume "norm w < r"
thus "summable (λm. (diffs ^^ n) a m * w ^ m)" using summ_diffs by simp
next
show "norm (x - c) < r" using that by simp
qed
have shift: "((λy. y - c) has_field_derivative 1) (at x)"
by (auto intro!: derivative_eq_intros)
have "((λy. (λw. ∑m. (diffs ^^ n) a m * w ^ m) (y - c))
has_field_derivative
(∑m. diffs ((diffs ^^ n) a) m * (x - c) ^ m) * 1) (at x)"
by (rule DERIV_chain'[OF shift]) (use H in simp)
thus ?thesis by (simp add: S_def)
qed
have main: "∀x. ¦x - c¦ < r ⟶
f n-times_differentiable_at x ∧ (deriv ^^ n) f x = S n x" for n
proof (induction n)
case 0
show ?case by (auto simp: S0_eq_f)
next
case (Suc n)
show ?case
proof (intro allI impI conjI)
fix x assume xc: "¦x - c¦ < r"
have ballopen: "{y. ¦y - c¦ < r} = ball c r"
by (auto simp: dist_real_def abs_minus_commute)
have eqA: "(deriv ^^ n) f y = S n y" if "¦y - c¦ < r" for y
using Suc.IH that by blast
have dn_deriv: "((deriv ^^ n) f has_field_derivative S (Suc n) x) (at x)"
proof (rule has_field_derivative_transform_within_open
[where f = "S n" and S = "{y. ¦y - c¦ < r}"])
show "(S n has_field_derivative S (Suc n) x) (at x)" by (rule S_deriv[OF xc])
show "open {y. ¦y - c¦ < r}" by (simp add: ballopen)
show "x ∈ {y. ¦y - c¦ < r}" using xc by simp
show "⋀y. y ∈ {y. ¦y - c¦ < r} ⟹ S n y = (deriv ^^ n) f y"
using eqA by auto
qed
show "(deriv ^^ Suc n) f x = S (Suc n) x"
using dn_deriv by (simp only: kth_deriv_simps(2) DERIV_imp_deriv)
show "f (Suc n)-times_differentiable_at x"
unfolding k_times_differentiable_at.simps(2)
proof
show "∃ε>0. ∀y. ¦y - x¦ < ε ⟶ f n-times_differentiable_at y"
proof (intro exI[where x = "r - ¦x - c¦"] conjI allI impI)
show "0 < r - ¦x - c¦" using xc by simp
fix y assume "¦y - x¦ < r - ¦x - c¦"
hence "¦y - c¦ < r" by linarith
thus "f n-times_differentiable_at y" using Suc.IH by blast
qed
next
have "(deriv ^^ Suc n) f x = S (Suc n) x"
using dn_deriv by (simp only: kth_deriv_simps(2) DERIV_imp_deriv)
with dn_deriv
show "((deriv ^^ n) f has_derivative (λh. (deriv ^^ Suc n) f x * h)) (at x)"
by (simp only: has_field_derivative_def)
qed
qed
qed
have diffs_fact: "(diffs ^^ n) g 0 = fact n * g n" for n and g :: "nat ⇒ real"
proof -
have gen: "fact m * (diffs ^^ n) g m = fact (m + n) * g (m + n)" for m
proof (induction n arbitrary: g m)
case 0 show ?case by simp
next
case (Suc n)
have "fact m * (diffs ^^ Suc n) g m = fact m * (diffs ^^ n) (diffs g) m"
by (simp only: funpow_Suc_right o_apply)
also have "… = fact (m + n) * (diffs g) (m + n)"
using Suc.IH[of m "diffs g"] by simp
also have "… = fact (m + n) * (of_nat (Suc (m + n)) * g (Suc (m + n)))"
by (simp only: diffs_def)
also have "… = fact (Suc (m + n)) * g (Suc (m + n))"
by (simp add: algebra_simps)
finally show ?case by (simp add: add.commute)
qed
from gen[of 0] show ?thesis by simp
qed
have coeff: "a n = (deriv ^^ n) f c / fact n" for n
proof -
have "¦c - c¦ < r" using r by simp
with main[of n] have "(deriv ^^ n) f c = S n c" by blast
also have "S n c = (diffs ^^ n) a 0" by (simp add: S_def)
also have "… = fact n * a n" by (rule diffs_fact)
finally have "(deriv ^^ n) f c = fact n * a n" .
thus ?thesis by simp
qed
have smooth: "f n-times_differentiable_at x" if "¦x - c¦ < r" for x n
using main[of n] that by blast
show ?thesis
unfolding real_analytic_at_1d_def
proof (intro exI[where x = r] conjI allI impI)
show "0 < r" by (rule r)
next
fix x n assume "¦x - c¦ < r" thus "f n-times_differentiable_at x"
by (rule smooth)
next
fix x assume xc: "¦x - c¦ < r"
from PS[OF xc] show
"(λn. (deriv ^^ n) f c / fact n * (x - c) ^ n) sums f x"
by (simp only: coeff)
qed
qed
subsection ‹Degree of a multi-index and the monomial scaling identity›
text ‹Scaling a vector by a real ‹t› scales the basis monomial by ‹t^(deg α)›.›
lemma ra_monomial_scaleR:
fixes d :: "'a::euclidean_space"
shows "ra_monomial (t *⇩R d) α = t ^ (ra_deg α) * ra_monomial d α"
proof -
have "ra_monomial (t *⇩R d) α = (∏b∈Basis. ((t *⇩R d) ∙ b) ^ (α b))"
by (simp only: ra_monomial_def)
also have "… = (∏b∈Basis. (t * (d ∙ b)) ^ (α b))"
by (simp only: inner_scaleR_left)
also have "… = (∏b∈Basis. t ^ (α b) * (d ∙ b) ^ (α b))"
by (simp only: power_mult_distrib)
also have "… = (∏b∈Basis. t ^ (α b)) * (∏b∈Basis. (d ∙ b) ^ (α b))"
by (simp only: prod.distrib)
also have "(∏b∈Basis. t ^ (α b)) = t ^ (∑b∈Basis. α b)"
by (simp only: power_sum)
finally show ?thesis by (simp only: ra_deg_def ra_monomial_def)
qed
text ‹Each degree block of ‹ra_idx› is finite.›
lemma ra_deg_block_finite:
fixes n :: nat
shows "finite {α::'a::euclidean_space ⇒ nat. α ∈ ra_idx ∧ ra_deg α = n}"
proof -
have "{α::'a ⇒ nat. α ∈ ra_idx ∧ ra_deg α = n}
⊆ {hh. ∀x::'a. (x ∈ Basis ⟶ hh x ∈ {0..n}) ∧ (x ∉ Basis ⟶ hh x = 0)}"
proof (rule subsetI)
fix α :: "'a ⇒ nat" assume "α ∈ {α. α ∈ ra_idx ∧ ra_deg α = n}"
then have a1: "α ∈ ra_idx" and a2: "ra_deg α = n" by auto
have "∀x::'a. (x ∈ Basis ⟶ α x ∈ {0..n}) ∧ (x ∉ Basis ⟶ α x = 0)"
proof (intro allI conjI impI)
fix x :: 'a assume xB: "x ∈ Basis"
have "α x ≤ (∑b∈Basis. α b)"
using xB by (intro member_le_sum) auto
also have "… = n" using a2 by (simp only: ra_deg_def)
finally show "α x ∈ {0..n}" by simp
next
fix x :: 'a assume "x ∉ Basis"
with a1 show "α x = 0" by (auto simp: ra_idx_def)
qed
thus "α ∈ {hh. ∀x::'a. (x ∈ Basis ⟶ hh x ∈ {0..n}) ∧ (x ∉ Basis ⟶ hh x = 0)}"
by simp
qed
moreover have "finite {hh::'a⇒nat. ∀x. (x ∈ Basis ⟶ hh x ∈ {0..n}) ∧ (x ∉ Basis ⟶ hh x = (0::nat))}"
by (rule finite_set_of_finite_funs) auto
ultimately show ?thesis by (rule finite_subset)
qed
text ‹The basis monomial is bounded in absolute value by ‹(norm h) ^ (deg α)›.›
lemma abs_ra_monomial_le:
fixes h :: "'a::euclidean_space"
shows "¦ra_monomial h α¦ ≤ (norm h) ^ (ra_deg α)"
proof -
have "¦ra_monomial h α¦ = (∏b∈Basis. ¦h ∙ b¦ ^ (α b))"
by (simp only: ra_monomial_def abs_prod power_abs)
also have "… ≤ (∏b∈Basis. (norm h) ^ (α b))"
proof (rule prod_mono)
fix b :: 'a assume "b ∈ Basis"
have "¦h ∙ b¦ ≤ norm h" using ‹b ∈ Basis› by (rule Basis_le_norm)
thus "0 ≤ ¦h ∙ b¦ ^ (α b) ∧ ¦h ∙ b¦ ^ (α b) ≤ (norm h) ^ (α b)"
by (auto intro: power_mono)
qed
also have "… = (norm h) ^ (∑b∈Basis. α b)"
by (simp only: power_sum)
finally show ?thesis by (simp only: ra_deg_def)
qed
text ‹The basis monomial at ‹0› is the indicator of the zero multi-index.›
lemma ra_monomial_zero:
fixes α :: "'a::euclidean_space ⇒ nat"
shows "ra_monomial (0::'a) α = (if ra_deg α = 0 then 1 else 0)"
proof (cases "ra_deg α = 0")
case True
then have "⋀b. b ∈ Basis ⟹ α b = 0"
using finite_Basis by (simp add: ra_deg_def)
thus ?thesis using True by (simp add: ra_monomial_def)
next
case False
then obtain b where bB: "b ∈ Basis" and apos: "α b ≠ 0"
using finite_Basis by (auto simp: ra_deg_def)
have "ra_monomial (0::'a) α = (∏b∈Basis. (0 ∙ b) ^ (α b))"
by (simp only: ra_monomial_def)
also have "… = 0"
using bB apos by (intro prod_zero[OF finite_Basis]) auto
finally show ?thesis using False by simp
qed
subsection ‹Real-analytic functions are continuous›
text ‹Continuity at ‹x0› from the local power series, via
‹¦f x - f x0¦ ≤ (dist x x0 / t) ⋅ S› near ‹x0›.›
lemma real_analytic_on_imp_continuous:
fixes f :: "'a::euclidean_space ⇒ real"
assumes ana: "real_analytic_on f U" and xU: "x0 ∈ U"
shows "continuous (at x0) f"
proof -
from ana xU obtain r c where r: "0 < r"
and HS: "⋀x. dist x x0 < r ⟹
((λα. ra_monomial (x - x0) α *⇩R c α) has_sum f x) ra_idx"
unfolding real_analytic_on_def by blast
define e1 where "e1 = (∑b∈(Basis::'a set). b)"
define t where "t = r / (2 * (norm e1 + 1))"
have ne1: "norm e1 + 1 > 0" by (simp add: add_nonneg_pos)
have t_pos: "0 < t" using r ne1 by (simp add: t_def)
define x2 where "x2 = x0 + t *⇩R e1"
have dist_x2: "dist x2 x0 < r"
proof -
have "dist x2 x0 = norm (t *⇩R e1)" by (simp add: x2_def dist_norm)
also have "… = t * norm e1" using t_pos by simp
also have "… ≤ t * (norm e1 + 1)" using t_pos by simp
also have "t * (norm e1 + 1) = r / 2"
using ne1 by (simp add: t_def field_simps)
also have "r / 2 < r" using r by simp
finally show ?thesis .
qed
have mono_x2: "ra_monomial (x2 - x0) α = t ^ (ra_deg α)" for α
proof -
have "x2 - x0 = t *⇩R e1" by (simp add: x2_def)
have inb: "(x2 - x0) ∙ b = t" if "b ∈ Basis" for b
proof -
have "(x2 - x0) ∙ b = (t *⇩R e1) ∙ b" by (simp add: x2_def)
also have "… = t * (e1 ∙ b)" by (simp only: inner_scaleR_left)
also have "e1 ∙ b = 1" using that by (simp add: e1_def inner_sum_left inner_Basis)
finally show ?thesis by simp
qed
have "ra_monomial (x2 - x0) α = (∏b∈Basis. ((x2 - x0) ∙ b) ^ (α b))"
by (simp only: ra_monomial_def)
also have "… = (∏b∈Basis. t ^ (α b))"
by (intro prod.cong refl) (simp only: inb)
also have "… = t ^ (∑b∈Basis. α b)" by (simp only: power_sum)
finally show ?thesis by (simp only: ra_deg_def)
qed
have HSx2: "((λα. t ^ (ra_deg α) * c α) has_sum f x2) ra_idx"
proof -
have "((λα. ra_monomial (x2 - x0) α *⇩R c α) has_sum f x2) ra_idx" by (rule HS[OF dist_x2])
thus ?thesis by (simp add: mono_x2)
qed
have abs_summ: "(λα. t ^ (ra_deg α) * ¦c α¦) summable_on ra_idx"
proof -
have sm: "(λα. t ^ (ra_deg α) * c α) summable_on ra_idx"
by (rule has_sum_imp_summable[OF HSx2])
have "(λα. norm (t ^ (ra_deg α) * c α)) summable_on ra_idx"
using sm[THEN iffD1[OF summable_on_iff_abs_summable_on_real]] .
moreover have "⋀α. norm (t ^ (ra_deg α) * c α) = t ^ (ra_deg α) * ¦c α¦"
using t_pos by (simp add: abs_mult)
ultimately show ?thesis by simp
qed
define S where "S = (∑⇩∞α∈ra_idx. t ^ (ra_deg α) * ¦c α¦)"
have HSS: "((λα. t ^ (ra_deg α) * ¦c α¦) has_sum S) ra_idx"
unfolding S_def using abs_summ by (rule has_sum_infsum)
have estimate: "¦f x - f x0¦ ≤ (dist x x0 / t) * S" if dx: "dist x x0 ≤ t" for x
proof -
have dxr: "dist x x0 < r"
proof -
have "t ≤ t * (norm e1 + 1)" using t_pos by simp
also have "t * (norm e1 + 1) = r / 2" using ne1 by (simp add: t_def field_simps)
also have "r / 2 < r" using r by simp
finally have "t < r" .
thus ?thesis using dx by linarith
qed
have HSx: "((λα. ra_monomial (x - x0) α * c α) has_sum f x) ra_idx"
using HS[OF dxr] by simp
have HSx0: "((λα. ra_monomial ((0::'a)) α * c α) has_sum f x0) ra_idx"
proof -
have "dist x0 x0 < r" using r by simp
from HS[OF this] show ?thesis by simp
qed
have HSdiff: "((λα. (ra_monomial (x - x0) α - ra_monomial (0::'a) α) * c α)
has_sum (f x - f x0)) ra_idx"
proof -
have HSm0: "((λα. - (ra_monomial (0::'a) α * c α)) has_sum (- f x0)) ra_idx"
by (subst has_sum_uminus, simp add: HSx0)
have "((λα. ra_monomial (x - x0) α * c α + (- (ra_monomial (0::'a) α * c α)))
has_sum (f x + (- f x0))) ra_idx"
by (rule has_sum_add[OF HSx HSm0])
thus ?thesis by (simp add: left_diff_distrib)
qed
have HSdom: "((λα. (dist x x0 / t) * (t ^ (ra_deg α) * ¦c α¦)) has_sum ((dist x x0 / t) * S)) ra_idx"
by (rule has_sum_cmult_right[OF HSS])
have termbound: "¦(ra_monomial (x - x0) α - ra_monomial (0::'a) α) * c α¦
≤ (dist x x0 / t) * (t ^ (ra_deg α) * ¦c α¦)" for α
proof (cases "ra_deg α = 0")
case True
then have allz: "⋀b. b ∈ Basis ⟹ α b = 0"
using finite_Basis by (simp add: ra_deg_def)
have e1: "ra_monomial (x - x0) α = 1"
by (simp add: ra_monomial_def allz)
have e2: "ra_monomial (0::'a) α = 1"
by (simp add: ra_monomial_def allz)
have "¦(ra_monomial (x - x0) α - ra_monomial (0::'a) α) * c α¦ = 0"
by (simp add: e1 e2)
moreover have "0 ≤ (dist x x0 / t) * (t ^ (ra_deg α) * ¦c α¦)"
using t_pos by (intro mult_nonneg_nonneg) auto
ultimately show ?thesis by linarith
next
case False
then have dpos: "ra_deg α ≥ 1" by simp
have m0: "ra_monomial (0::'a) α = 0" by (simp add: ra_monomial_zero False)
have nh: "norm (x - x0) = dist x x0" by (simp only: dist_norm)
have "¦(ra_monomial (x - x0) α - ra_monomial (0::'a) α) * c α¦
= ¦ra_monomial (x - x0) α¦ * ¦c α¦" by (simp add: m0 abs_mult)
also have "¦ra_monomial (x - x0) α¦ ≤ (dist x x0) ^ (ra_deg α)"
using abs_ra_monomial_le[of "x - x0" α] by (simp only: nh)
also have "(dist x x0) ^ (ra_deg α) ≤ (dist x x0 / t) * t ^ (ra_deg α)"
proof -
obtain k where k: "ra_deg α = Suc k" using dpos by (cases "ra_deg α") auto
have dnn: "0 ≤ dist x x0" by simp
have "(dist x x0) ^ (Suc k) = dist x x0 * (dist x x0) ^ k" by simp
also have "… ≤ dist x x0 * t ^ k"
using dnn dx by (intro mult_left_mono power_mono) auto
also have "dist x x0 * t ^ k = (dist x x0 / t) * t ^ (Suc k)"
using t_pos by (simp add: field_simps)
finally show ?thesis by (simp only: k)
qed
finally have "¦(ra_monomial (x - x0) α - ra_monomial (0::'a) α) * c α¦
≤ ((dist x x0 / t) * t ^ (ra_deg α)) * ¦c α¦"
by (simp only: mult_right_mono)
thus ?thesis by (simp only: mult.assoc)
qed
have "norm (f x - f x0) ≤ (dist x x0 / t) * S"
by (rule norm_infsum_le[OF HSdiff HSdom]) (use termbound in simp)
thus ?thesis by simp
qed
have Snn: "0 ≤ S" unfolding S_def
proof (rule infsum_nonneg)
fix α :: "'a ⇒ nat" assume "α ∈ ra_idx"
have "0 ≤ t ^ (ra_deg α)" using t_pos by simp
thus "0 ≤ t ^ (ra_deg α) * ¦c α¦" by (simp only: mult_nonneg_nonneg)
qed
have domlim: "((λx. (dist x x0 / t) * S) ⤏ 0) (at x0)"
proof -
have idlim: "((λx::'a. x) ⤏ x0) (at x0)" by (simp only: tendsto_ident_at)
have dl: "((λx. dist x x0) ⤏ dist x0 x0) (at x0)"
by (intro tendsto_dist idlim tendsto_const)
have "((λx. dist x x0) ⤏ 0) (at x0)" using dl by simp
hence "((λx. dist x x0 * (S / t)) ⤏ 0 * (S / t)) (at x0)"
by (rule tendsto_mult_right)
moreover have "(λx. dist x x0 * (S / t)) = (λx. (dist x x0 / t) * S)"
by (rule ext) simp
ultimately show ?thesis by simp
qed
have evb: "∀⇩F x in at x0. norm (f x - f x0) ≤ norm ((dist x x0 / t) * S)"
proof -
have "∀⇩F x in at x0. x ∈ ball x0 t"
by (rule eventually_at_in_open'[OF open_ball]) (simp add: t_pos)
then have "∀⇩F x in at x0. dist x x0 < t"
by (rule eventually_mono) (simp add: dist_commute)
thus ?thesis
proof (rule eventually_mono)
fix x assume "dist x x0 < t"
hence dxt: "dist x x0 ≤ t" by simp
have "norm (f x - f x0) = ¦f x - f x0¦" by simp
also have "… ≤ (dist x x0 / t) * S" by (rule estimate[OF dxt])
also have "… = norm ((dist x x0 / t) * S)"
using t_pos Snn by simp
finally show "norm (f x - f x0) ≤ norm ((dist x x0 / t) * S)" .
qed
qed
have "((λx. f x - f x0) ⤏ 0) (at x0)"
by (rule Lim_transform_bound[OF evb domlim])
hence "(f ⤏ f x0) (at x0)" by (simp only: LIM_zero_iff)
thus ?thesis by (simp only: continuous_at)
qed
subsection ‹The affine slice of a real-analytic function is real-analytic (at a point)›
text ‹The slice ‹s ↦ f (a + s *⇩R d)› in a nonzero direction ‹d› is real-analytic at ‹t0›.›
lemma real_analytic_slice_at_point:
fixes f :: "'a::euclidean_space ⇒ real"
assumes ana: "real_analytic_on f U"
and inU: "a + t0 *⇩R d ∈ U"
and dnz: "d ≠ 0"
shows "real_analytic_at_1d (λs. f (a + s *⇩R d)) t0"
proof -
define x0 where "x0 = a + t0 *⇩R d"
have oU: "open U" using ana by (simp only: real_analytic_on_def)
from ana inU obtain r c where r: "0 < r"
and HS: "⋀x. dist x x0 < r ⟹
((λα. ra_monomial (x - x0) α *⇩R c α) has_sum f x) ra_idx"
unfolding real_analytic_on_def x0_def by blast
define nd where "nd = norm d"
have nd_pos: "0 < nd" using dnz by (simp add: nd_def)
define r' where "r' = r / nd"
have r'_pos: "0 < r'" using r nd_pos by (simp add: r'_def)
define blk where "blk = (λn. {α::'a⇒nat. α ∈ ra_idx ∧ ra_deg α = n})"
define acoef where "acoef = (λn. ∑α∈blk n. ra_monomial d α * c α)"
have blk_fin: "finite (blk n)" for n
unfolding blk_def by (rule ra_deg_block_finite)
have PS: "(λn. acoef n * (s - t0) ^ n) sums f (a + s *⇩R d)" if slt: "¦s - t0¦ < r'" for s
proof -
define u where "u = s - t0"
have ult: "¦u¦ < r'" using slt by (simp only: u_def)
have pt_eq: "a + s *⇩R d = x0 + u *⇩R d"
by (simp only: x0_def u_def algebra_simps)
have dist_lt: "dist (x0 + u *⇩R d) x0 < r"
proof -
have "dist (x0 + u *⇩R d) x0 = norm (u *⇩R d)" by (simp add: dist_norm)
also have "… = ¦u¦ * nd" by (simp add: nd_def)
also have "… < r' * nd" using ult nd_pos by (simp only: mult_strict_right_mono)
also have "… = r" using nd_pos by (simp add: r'_def)
finally show ?thesis .
qed
have HSu: "((λα. (u ^ (ra_deg α) * ra_monomial d α) * c α) has_sum f (x0 + u *⇩R d)) ra_idx"
proof -
have "((λα. ra_monomial ((x0 + u *⇩R d) - x0) α *⇩R c α) has_sum f (x0 + u *⇩R d)) ra_idx"
by (rule HS[OF dist_lt])
moreover have "(x0 + u *⇩R d) - x0 = u *⇩R d" by simp
ultimately have "((λα. ra_monomial (u *⇩R d) α *⇩R c α) has_sum f (x0 + u *⇩R d)) ra_idx"
by simp
thus ?thesis by (simp add: ra_monomial_scaleR)
qed
have reidx: "((λq. u ^ (fst q) * (ra_monomial d (snd q) * c (snd q))) has_sum f (x0 + u *⇩R d))
(Sigma (UNIV::nat set) blk)"
proof -
have "((λα. (u ^ (ra_deg α) * ra_monomial d α) * c α) has_sum f (x0 + u *⇩R d)) ra_idx
= ((λq. u ^ (fst q) * (ra_monomial d (snd q) * c (snd q))) has_sum f (x0 + u *⇩R d))
(Sigma (UNIV::nat set) blk)"
proof (rule has_sum_reindex_bij_witness
[where j = "λα. (ra_deg α, α)" and i = snd])
fix α :: "'a ⇒ nat" assume "α ∈ ra_idx"
show "snd (ra_deg α, α) = α" by simp
next
fix α :: "'a ⇒ nat" assume "α ∈ ra_idx"
thus "(ra_deg α, α) ∈ Sigma (UNIV::nat set) blk" by (simp add: blk_def)
next
fix q :: "nat × ('a ⇒ nat)" assume "q ∈ Sigma (UNIV::nat set) blk"
then obtain m β where q: "q = (m, β)" and "β ∈ blk m" by (cases q) auto
then have dn: "ra_deg β = m" by (simp add: blk_def)
show "(ra_deg (snd q), snd q) = q" by (simp add: q dn)
next
fix q :: "nat × ('a ⇒ nat)" assume "q ∈ Sigma (UNIV::nat set) blk"
then obtain m β where q: "q = (m, β)" and "β ∈ blk m" by (cases q, simp)
thus "snd q ∈ ra_idx" by (simp add: blk_def)
next
fix α :: "'a ⇒ nat" assume "α ∈ ra_idx"
show "u ^ (fst (ra_deg α, α)) * (ra_monomial d (snd (ra_deg α, α)) * c (snd (ra_deg α, α)))
= (u ^ (ra_deg α) * ra_monomial d α) * c α"
by (simp add: mult.assoc)
qed simp
with HSu show ?thesis by blast
qed
have inner: "((λα. u ^ n * (ra_monomial d α * c α)) has_sum (acoef n * u ^ n)) (blk n)" for n
proof -
have "((λα. u ^ n * (ra_monomial d α * c α)) has_sum
(∑α∈blk n. u ^ n * (ra_monomial d α * c α))) (blk n)"
by (rule has_sum_finite[OF blk_fin])
moreover have "(∑α∈blk n. u ^ n * (ra_monomial d α * c α)) = acoef n * u ^ n"
by (simp only: acoef_def sum_distrib_left mult.commute)
ultimately show ?thesis by simp
qed
have basesum: "((λn. acoef n * u ^ n) has_sum f (x0 + u *⇩R d)) (UNIV::nat set)"
proof (rule has_sum_Sigma'[where f = "λq. u ^ (fst q) * (ra_monomial d (snd q) * c (snd q))"
and B = blk])
show "((λq. u ^ (fst q) * (ra_monomial d (snd q) * c (snd q))) has_sum f (x0 + u *⇩R d))
(Sigma (UNIV::nat set) blk)" by (rule reidx)
next
fix n :: nat assume "n ∈ (UNIV::nat set)"
show "((λα. u ^ (fst (n, α)) * (ra_monomial d (snd (n, α)) * c (snd (n, α)))) has_sum (acoef n * u ^ n)) (blk n)"
using inner[of n] by simp
qed
have "(λn. acoef n * u ^ n) sums f (x0 + u *⇩R d)"
by (rule has_sum_imp_sums[OF basesum])
thus ?thesis by (simp only: pt_eq u_def)
qed
show ?thesis
by (rule real_powser_imp_real_analytic_at_1d[OF r'_pos PS])
qed
subsection ‹Propagating a zero of an analytic function along a segment›
text ‹Identity theorem along a segment: if ‹f› is real-analytic on ‹U›, the segment from ‹z›
to ‹y› lies in ‹U› and ‹f› vanishes near ‹z›, then ‹f y = 0›.›
lemma slice_zero_propagate:
fixes f :: "'a::euclidean_space ⇒ real"
assumes ana: "real_analytic_on f U"
and seg: "closed_segment z y ⊆ U"
and zero_near: "∃δ0>0. ∀w. dist w z < δ0 ⟶ f w = 0"
shows "f y = 0"
proof (cases "y = z")
case True
from zero_near obtain δ0 where d0: "δ0 > 0" and fz: "⋀w. dist w z < δ0 ⟹ f w = 0"
by blast
show ?thesis using True fz[of z] d0 by simp
next
case False
define d where "d = y - z"
have dnz: "d ≠ 0" using False by (simp add: d_def)
have oU: "open U" using ana by (simp only: real_analytic_on_def)
define g where "g = (λs::real. f (z + s *⇩R d))"
define I where "I = {s::real. z + s *⇩R d ∈ U}"
have segI: "{0..1} ⊆ I"
proof
fix s :: real assume s: "s ∈ {0..1}"
have "z + s *⇩R d = (1 - s) *⇩R z + s *⇩R y"
by (simp add: d_def algebra_simps)
moreover have "(1 - s) *⇩R z + s *⇩R y ∈ closed_segment z y"
using s by (auto simp: in_segment)
ultimately have "z + s *⇩R d ∈ U" using seg by auto
thus "s ∈ I" by (simp add: I_def)
qed
have Iopen: "open I"
proof -
have cont: "continuous (at s) (λs::real. z + s *⇩R d)" for s
by (intro continuous_intros)
have "open ((λs::real. z + s *⇩R d) -` U)"
by (rule continuous_open_vimage[OF oU cont])
moreover have "I = (λs::real. z + s *⇩R d) -` U"
by (auto simp: I_def)
ultimately show ?thesis by simp
qed
obtain δ where dpos: "δ > 0" and fat: "(⋃x∈{0..1::real}. ball x δ) ⊆ I"
using compact_subset_open_imp_ball_epsilon_subset[OF compact_Icc Iopen segI]
by blast
define J where "J = {s::real. -δ < s ∧ s < 1 + δ}"
have Jopen: "open J"
unfolding J_def by (simp add: open_Collect_conj open_Collect_less)
have Jconn: "connected J"
proof -
have "J = {-δ<..<1+δ}" by (auto simp: J_def)
thus ?thesis by (simp only: connected_Ioo)
qed
have JsubI: "J ⊆ I"
proof
fix s :: real assume "s ∈ J"
then have sb: "-δ < s" "s < 1 + δ" by (auto simp: J_def)
define x where "x = max 0 (min 1 s)"
have xseg: "x ∈ {0..1}" by (simp add: x_def)
have "dist s x < δ"
proof (cases "s < 0")
case True thus ?thesis using sb x_def by (simp only: dist_real_def)
next
case False
show ?thesis
proof (cases "s > 1")
case True thus ?thesis using sb x_def by (simp only: dist_real_def)
next
case False
with ‹¬ s < 0› have "x = s" by (simp only: x_def)
thus ?thesis using dpos by (simp only: dist_real_def)
qed
qed
then have "s ∈ ball x δ" by (simp add: dist_commute)
then have "s ∈ (⋃x∈{0..1::real}. ball x δ)" using xseg by blast
with fat show "s ∈ I" by blast
qed
have onein: "(1::real) ∈ J" using dpos by (simp add: J_def)
have gana: "real_analytic_on g J"
proof -
have "real_analytic_at_1d g c" if "c ∈ J" for c
proof -
have "z + c *⇩R d ∈ U" using that JsubI by (auto simp: I_def)
thus ?thesis
unfolding g_def
by (rule real_analytic_slice_at_point[OF ana _ dnz])
qed
thus ?thesis using Jopen by (simp add: real_analytic_on_1d_iff)
qed
from zero_near obtain δ0 where d0: "δ0 > 0" and fz: "⋀w. dist w z < δ0 ⟹ f w = 0"
by blast
define η where "η = min δ (δ0 / norm d)"
have eta_pos: "η > 0" using dpos d0 dnz by (simp add: η_def)
have gzero: "g s = 0" if "¦s¦ < η" for s
proof -
have ndpos: "norm d > 0" using dnz by simp
have le1: "η * norm d ≤ (δ0 / norm d) * norm d"
using ndpos by (intro mult_right_mono) (auto simp: η_def)
have "dist (z + s *⇩R d) z = ¦s¦ * norm d" by (simp add: dist_norm)
also have "… < η * norm d" using that ndpos by (simp only: mult_strict_right_mono)
also have "… ≤ (δ0 / norm d) * norm d" by (rule le1)
also have "… = δ0" using ndpos by simp
finally show ?thesis using fz[of "z + s *⇩R d"] by (simp only: g_def)
qed
have zeroset_int: "interior (closure {s ∈ J. g s = 0}) ≠ {}"
proof -
have sub: "{s::real. -η < s ∧ s < η} ⊆ {s ∈ J. g s = 0}"
proof
fix s :: real assume "s ∈ {s. -η < s ∧ s < η}"
then have sb: "-η < s" "s < η" by auto
have "¦s¦ < η" using sb by simp
have eta_le: "η ≤ δ" by (simp only: η_def)
have "s ∈ J" unfolding J_def using sb eta_le dpos by simp
then show "s ∈ {s ∈ J. g s = 0}" using gzero ‹¦s¦ < η› by auto
qed
have "open {s::real. -η < s ∧ s < η}"
by (simp add: open_Collect_conj open_Collect_less)
moreover have "(0::real) ∈ {s::real. -η < s ∧ s < η}" using eta_pos by simp
ultimately have "(0::real) ∈ interior {s ∈ J. g s = 0}"
using sub interior_maximal by (simp only: interiorI)
moreover have "interior {s ∈ J. g s = 0} ⊆ interior (closure {s ∈ J. g s = 0})"
by (intro interior_mono closure_subset)
ultimately show ?thesis by blast
qed
have "¬ (∃x∈J. g x ≠ 0)"
proof
assume "∃x∈J. g x ≠ 0"
from real_analytic_1d_nowhere_dense_zeros[OF gana Jconn this]
have "interior (closure {s ∈ J. g s = 0}) = {}" .
with zeroset_int show False by simp
qed
then have "g 1 = 0" using onein by blast
thus ?thesis by (simp add: g_def d_def)
qed
subsection ‹Nowhere-dense zeros in several variables›
theorem real_analytic_nowhere_dense_zeros:
fixes f :: "'a::euclidean_space ⇒ real"
assumes ana: "real_analytic_on f U" and conn: "connected U"
and ex: "∃x∈U. f x ≠ 0"
shows "interior (closure {x ∈ U. f x = 0}) = {}"
proof -
have oU: "open U" using ana by (simp only: real_analytic_on_def)
text ‹Continuity of ‹f› on ‹U› (proved directly from the local power series).›
have contf: "continuous (at x) f" if "x ∈ U" for x
by (rule real_analytic_on_imp_continuous[OF ana that])
text ‹The set of points around which ‹f› vanishes on a ball inside ‹U›.›
define Z where "Z = {x ∈ U. ∃ε>0. ball x ε ⊆ U ∧ (∀y∈ball x ε. f y = 0)}"
have Zsub: "Z ⊆ U" by (auto simp: Z_def)
text ‹‹Z› is open.›
have Zopen: "open Z"
proof (rule openI)
fix x assume "x ∈ Z"
then obtain ε where xU: "x ∈ U" and epos: "ε > 0"
and ballU: "ball x ε ⊆ U" and fz: "∀y∈ball x ε. f y = 0"
by (auto simp: Z_def)
have "ball x ε ⊆ Z"
proof
fix w assume w: "w ∈ ball x ε"
then obtain ρ where rpos: "ρ > 0" and rsub: "ball w ρ ⊆ ball x ε"
using open_contains_ball by (metis open_ball)
have "w ∈ U" using w ballU by blast
moreover have "ball w ρ ⊆ U" using rsub ballU by blast
moreover have "∀y∈ball w ρ. f y = 0" using rsub fz by blast
ultimately show "w ∈ Z" using rpos by (auto simp: Z_def)
qed
thus "∃e>0. ball x e ⊆ Z" using epos by blast
qed
have ZopenIn: "openin (top_of_set U) Z"
using Zopen Zsub by (metis Int_absorb1 openin_open_Int)
text ‹‹Z› is closed in ‹U›: this is the multivariate identity theorem via analytic slices.›
have Zlimit: "x ∈ Z" if xU: "x ∈ U" and xcl: "x ∈ closure Z" for x
proof -
obtain ρ where rpos: "ρ > 0" and ballU: "ball x ρ ⊆ U"
using oU xU open_contains_ball by blast
have "ρ/2 > 0" using rpos by simp
with xcl have "∃z∈Z. dist z x < ρ/2"
using closure_approachable[of x Z] by blast
then obtain z where zZ: "z ∈ Z" and zx: "dist z x < ρ/2" by blast
from zZ obtain δ0 where d0: "δ0 > 0" and fz0: "∀y∈ball z δ0. f y = 0"
by (auto simp: Z_def)
have zb: "z ∈ ball x (ρ/2)" using zx by (simp add: dist_commute)
have fvan: "f y = 0" if yb: "y ∈ ball x (ρ/2)" for y
proof -
have convB: "convex (ball x (ρ/2))" by (rule convex_ball)
have "closed_segment z y ⊆ ball x (ρ/2)"
by (rule closed_segment_subset[OF zb yb convB])
also have "ball x (ρ/2) ⊆ ball x ρ" using rpos by (intro subset_ball) simp
finally have segU: "closed_segment z y ⊆ U" using ballU by blast
have znear: "∃δ0>0. ∀w. dist w z < δ0 ⟶ f w = 0"
using d0 fz0 by (auto simp: dist_commute)
show ?thesis by (rule slice_zero_propagate[OF ana segU znear])
qed
have "ball x (ρ/2) ⊆ ball x ρ" using rpos by (intro subset_ball) simp
then have ballhalf: "ball x (ρ/2) ⊆ U" using ballU by blast
have rh: "ρ/2 > 0" using rpos by simp
have "∃ε>0. ball x ε ⊆ U ∧ (∀y∈ball x ε. f y = 0)"
using rh ballhalf fvan by blast
thus "x ∈ Z" using xU by (simp add: Z_def)
qed
have Zeq: "Z = U ∩ closure Z" using Zsub Zlimit closure_subset by blast
have ZclosedIn: "closedin (top_of_set U) Z"
by (subst Zeq) (simp add: closedin_closed_Int)
text ‹If ‹W = interior (closure ...)› is nonempty then ‹Z› is nonempty.›
define W where "W = interior (closure {x ∈ U. f x = 0})"
have Wopen: "open W" by (simp add: W_def)
have Zne: "Z ≠ {}" if WNE: "W ≠ {}"
proof -
from WNE obtain w where wW: "w ∈ W" by blast
have Wsub: "W ⊆ closure {x ∈ U. f x = 0}" by (simp only: W_def interior_subset)
obtain e where epos: "e > 0" and eball: "ball w e ⊆ W"
using wW Wopen open_contains_ball by blast
have wcl: "w ∈ closure {x ∈ U. f x = 0}" using wW Wsub by blast
have "ball w e ∩ {x ∈ U. f x = 0} ≠ {}"
proof -
have "w ∈ ball w e ∩ closure {x ∈ U. f x = 0}" using wcl epos by simp
hence "ball w e ∩ closure {x ∈ U. f x = 0} ≠ {}" by blast
thus "ball w e ∩ {x ∈ U. f x = 0} ≠ {}"
using open_Int_closure_eq_empty[OF open_ball, of w e "{x ∈ U. f x = 0}"] by blast
qed
then obtain u where uU: "u ∈ ball w e" "u ∈ U" "f u = 0" by blast
have uW: "u ∈ W" using uU(1) eball by blast
define V where "V = W ∩ U"
have Vopen: "open V" unfolding V_def by (intro open_Int Wopen oU)
have uV: "u ∈ V" using uW uU(2) by (simp add: V_def)
have fzeroV: "f v = 0" if "v ∈ V" for v
proof -
have vW: "v ∈ W" and vU: "v ∈ U" using that by (auto simp: V_def)
have vcl: "v ∈ closure {x ∈ U. f x = 0}" using vW Wsub by blast
have "isCont f v" using contf[OF vU] by simp
from vcl obtain s where s: "⋀k. s k ∈ {x ∈ U. f x = 0}" "s ⇢ v"
using closure_sequential by blast
have "(λk. f (s k)) ⇢ f v"
using ‹isCont f v› s(2) by (simp only: continuous_within isCont_tendsto_compose)
moreover have "(λk. f (s k)) = (λk. 0)" using s(1) by auto
ultimately have "(λk. (0::real)) ⇢ f v" by simp
thus "f v = 0" by (simp only: LIMSEQ_const_iff)
qed
obtain ρ where ρ: "ρ > 0" and rball: "ball u ρ ⊆ V"
using uV Vopen open_contains_ball by blast
have rballU: "ball u ρ ⊆ U" using rball by (auto simp: V_def)
have "∀y∈ball u ρ. f y = 0" using rball fzeroV by blast
then have "u ∈ Z" using ρ rballU uU(2) by (auto simp: Z_def)
thus "Z ≠ {}" by blast
qed
text ‹Connectedness: ‹Z› is clopen in ‹U›, so ‹Z = ∅› or ‹Z = U›.›
have clopen: "Z = {} ∨ Z = U"
using conn ZopenIn ZclosedIn unfolding connected_clopen by blast
show ?thesis
proof (rule ccontr)
assume "interior (closure {x ∈ U. f x = 0}) ≠ {}"
then have WNE: "W ≠ {}" by (simp add: W_def)
then have "Z ≠ {}" by (rule Zne)
with clopen have "Z = U" by blast
have "f x = 0" if "x ∈ U" for x
proof -
have "x ∈ Z" using that ‹Z = U› by simp
then obtain ε where epos: "ε > 0" and fz: "∀y∈ball x ε. f y = 0"
by (auto simp: Z_def)
have "x ∈ ball x ε" using epos by simp
thus "f x = 0" using fz by blast
qed
with ex show False by blast
qed
qed
text ‹Scalar component (inner product with a fixed vector) of an analytic vector
function is analytic.›
lemma real_analytic_on_inner_component:
fixes f :: "'a::euclidean_space ⇒ 'b::euclidean_space"
assumes F: "real_analytic_on f U"
shows "real_analytic_on (λx. f x ∙ b) U"
proof -
from F have U: "open U" by (simp only: real_analytic_on_def)
show ?thesis
unfolding real_analytic_on_def
proof (intro conjI ballI)
show "open U" by (rule U)
next
fix x0 assume x0: "x0 ∈ U"
from F x0 obtain r c where r: "0 < r"
and F1: "⋀x. dist x x0 < r ⟹
((λα. ra_monomial (x - x0) α *⇩R c α) has_sum f x) ra_idx"
unfolding real_analytic_on_def by blast
show "∃r>0. ∃cc. ∀x. dist x x0 < r ⟶
((λα. ra_monomial (x - x0) α *⇩R cc α) has_sum (f x ∙ b)) ra_idx"
proof (intro exI[where x=r] conjI exI[where x="λα. c α ∙ b"] allI impI)
show "0 < r" by (rule r)
next
fix x assume d: "dist x x0 < r"
have bl: "bounded_linear (λy::'b. y ∙ b)"
by (rule bounded_linear_inner_left)
have "((λα. (ra_monomial (x - x0) α *⇩R c α) ∙ b) has_sum (f x ∙ b)) ra_idx"
by (rule has_sum_bounded_linear[OF bl F1[OF d]])
thus "((λα. ra_monomial (x - x0) α *⇩R (c α ∙ b)) has_sum (f x ∙ b)) ra_idx"
by (simp only: inner_scaleR_left scaleR_conv_of_real) simp
qed
qed
qed
subsection ‹Explicit multi-index operations›
definition ra_idx_add :: "('a⇒nat) ⇒ ('a⇒nat) ⇒ ('a⇒nat)" where
"ra_idx_add = (λα β b. α b + β b)"
definition ra_idx_diff :: "('a⇒nat) ⇒ ('a⇒nat) ⇒ ('a⇒nat)" where
"ra_idx_diff = (λγ α b. γ b - α b)"
definition ra_idx_le :: "('a⇒nat) ⇒ ('a⇒nat) ⇒ bool" where
"ra_idx_le = (λα γ. ∀b. α b ≤ γ b)"
definition ra_idx_below :: "('a⇒nat) ⇒ ('a::euclidean_space⇒nat) set" where
"ra_idx_below γ = {α. α ∈ ra_idx ∧ ra_idx_le α γ}"
lemma idx_add: "ra_idx_add α β ∈ ra_idx" if "α ∈ ra_idx" "β ∈ ra_idx"
for α β :: "'a::euclidean_space⇒nat"
proof -
have "{b. ra_idx_add α β b ≠ 0} ⊆ {b. α b ≠ 0} ∪ {b. β b ≠ 0}"
by (auto simp: ra_idx_add_def)
also have "… ⊆ Basis" using that by (auto simp: ra_idx_def)
finally show ?thesis by (simp add: ra_idx_def)
qed
lemma idx_sub: "ra_idx_diff γ α ∈ ra_idx" if "γ ∈ ra_idx"
for γ α :: "'a::euclidean_space⇒nat"
proof -
have "{b. ra_idx_diff γ α b ≠ 0} ⊆ {b. γ b ≠ 0}" by (auto simp: ra_idx_diff_def)
also have "… ⊆ Basis" using that by (auto simp: ra_idx_def)
finally show ?thesis by (simp add: ra_idx_def)
qed
lemma ra_monomial_idx_add: "ra_monomial h (ra_idx_add α β) = ra_monomial h α * ra_monomial h β"
for h :: "'a::euclidean_space" and α β
by (simp only: ra_monomial_def ra_idx_add_def power_add prod.distrib)
lemma idx_lower_fin: "finite (ra_idx_below γ)" for γ :: "'a::euclidean_space ⇒ nat"
proof -
define N where "N = Max (insert 0 (γ ` (Basis :: 'a set)))"
have "ra_idx_below γ
⊆ {hh. ∀x::'a. (x ∈ Basis ⟶ hh x ∈ {0..N}) ∧ (x ∉ Basis ⟶ hh x = 0)}"
proof (rule subsetI)
fix α :: "'a ⇒ nat" assume "α ∈ ra_idx_below γ"
then have a1: "α ∈ ra_idx" and a2: "ra_idx_le α γ" by (auto simp: ra_idx_below_def)
have "∀x::'a. (x ∈ Basis ⟶ α x ∈ {0..N}) ∧ (x ∉ Basis ⟶ α x = 0)"
proof (intro allI conjI impI)
fix x :: 'a assume "x ∈ Basis"
have "α x ≤ γ x" using a2 by (simp only: ra_idx_le_def)
also have "γ x ≤ N" unfolding N_def using ‹x ∈ Basis› by (intro Max_ge) auto
finally show "α x ∈ {0..N}" by simp
next
fix x :: 'a assume "x ∉ Basis"
with a1 show "α x = 0" by (auto simp: ra_idx_def)
qed
thus "α ∈ {hh. ∀x::'a. (x ∈ Basis ⟶ hh x ∈ {0..N}) ∧ (x ∉ Basis ⟶ hh x = 0)}"
by simp
qed
moreover have "finite {hh::'a⇒nat. ∀x. (x ∈ Basis ⟶ hh x ∈ {0..N}) ∧ (x ∉ Basis ⟶ hh x = (0::nat))}"
by (rule finite_set_of_finite_funs) auto
ultimately show ?thesis by (rule finite_subset)
qed
text ‹The Fubini/Cauchy product of two real unordered sums over a common index set.›
lemma prod_has_sum:
"((λ(α,β). u α * v β) has_sum (Uv * Vv)) (I × I)"
if uHS: "(u has_sum Uv) I" and vHS: "(v has_sum Vv) I"
for u v :: "'i ⇒ real" and Uv Vv I
proof -
have u_abs: "(λz. norm (u z)) summable_on I"
using uHS has_sum_imp_summable summable_on_iff_abs_summable_on_real by blast
have v_abs: "(λz. norm (v z)) summable_on I"
using vHS has_sum_imp_summable summable_on_iff_abs_summable_on_real by blast
have inner: "((λβ. u α * v β) has_sum (u α * Vv)) I" for α
by (rule has_sum_cmult_right[OF vHS])
have outer: "((λα. u α * Vv) has_sum (Uv * Vv)) I"
by (rule has_sum_cmult_left[OF uHS])
have inner_abs: "(λβ. norm (u α * v β)) summable_on I" for α
proof -
have "(λβ. norm (u α) * norm (v β)) summable_on I"
using v_abs by (rule summable_on_cmult_right)
thus ?thesis by (simp only: norm_mult flip: abs_mult)
qed
have tail_abs: "(λα. norm (∑⇩∞β∈I. norm (u α * v β))) summable_on I"
proof -
have eq: "norm (∑⇩∞β∈I. norm (u α * v β)) = norm (u α) * (∑⇩∞β∈I. norm (v β))" for α
proof -
have nn: "(∑⇩∞β∈I. norm (u α * v β)) = norm (u α) * (∑⇩∞β∈I. norm (v β))"
proof -
have "(∑⇩∞β∈I. norm (u α * v β)) = (∑⇩∞β∈I. norm (u α) * norm (v β))"
by (simp add: abs_mult)
also have "… = norm (u α) * (∑⇩∞β∈I. norm (v β))"
by (rule infsum_cmult_right) (rule v_abs)
finally show ?thesis .
qed
have ge: "(0::real) ≤ norm (u α) * (∑⇩∞β∈I. norm (v β))"
by (intro mult_nonneg_nonneg) (auto intro: infsum_nonneg)
from nn ge show ?thesis by simp
qed
have "(λα. norm (u α) * (∑⇩∞β∈I. norm (v β))) summable_on I"
using u_abs by (rule summable_on_cmult_left)
thus ?thesis unfolding eq .
qed
have conj1: "∀α∈I. (λβ. norm ((λ(α,β). u α * v β) (α, β))) summable_on I"
proof
fix α assume "α ∈ I"
have "(λβ. norm (u α * v β)) summable_on I" by (rule inner_abs)
thus "(λβ. norm ((λ(α,β). u α * v β) (α, β))) summable_on I" by simp
qed
have conj2: "(λα. norm (∑⇩∞β∈I. norm ((λ(α,β). u α * v β) (α, β)))) summable_on I"
proof -
have "(λα. norm (∑⇩∞β∈I. norm (u α * v β))) summable_on I" by (rule tail_abs)
thus ?thesis by simp
qed
have absS: "(λz. norm ((λ(α,β). u α * v β) z)) summable_on (Sigma I (λ_. I))"
by (rule Infinite_Sum.abs_summable_on_Sigma_iff
[where f = "λ(α,β). u α * v β" and A = I and B = "λ_. I", THEN iffD2,
OF conjI[OF conj1 conj2]])
have summ: "(λ(α,β). u α * v β) summable_on Sigma I (λ_. I)"
by (rule abs_summable_summable[OF absS])
have "((λ(α,β). u α * v β) has_sum (Uv * Vv)) (Sigma I (λ_. I))"
proof (rule has_sum_SigmaI[where g = "λα. u α * Vv"])
fix α assume "α ∈ I"
have "((λβ. u α * v β) has_sum (u α * Vv)) I" by (rule inner)
thus "((λβ. (λ(α,β). u α * v β) (α, β)) has_sum (u α * Vv)) I" by simp
next
show "((λα. u α * Vv) has_sum (Uv * Vv)) I" by (rule outer)
next
show "(λ(α,β). u α * v β) summable_on Sigma I (λ_. I)" by (rule summ)
qed
thus ?thesis by (simp only: Sigma_def)
qed
text ‹The explicit Cauchy-product coefficient operator.›
definition ra_cauchy_prod :: "(('a::euclidean_space⇒nat) ⇒ real) ⇒ (('a⇒nat) ⇒ real) ⇒ (('a⇒nat) ⇒ real)" where
"ra_cauchy_prod c1 c2 = (λγ. ∑α∈ra_idx_below γ. c1 α * c2 (ra_idx_diff γ α))"
text ‹Quantitative Cauchy product on a common ball, exposing the (x-independent)
coefficient family.›
lemma quant_mult:
fixes c1 c2 :: "('a::euclidean_space ⇒ nat) ⇒ real"
assumes F1: "((λα. ra_monomial h α * c1 α) has_sum Fv) ra_idx"
and G1: "((λβ. ra_monomial h β * c2 β) has_sum Gv) ra_idx"
shows "((λγ. ra_monomial h γ *⇩R ra_cauchy_prod c1 c2 γ) has_sum (Fv * Gv)) ra_idx"
proof -
have step1:
"((λ(α,β). (ra_monomial h α * c1 α) * (ra_monomial h β * c2 β))
has_sum (Fv * Gv)) (ra_idx × ra_idx)"
using prod_has_sum[OF F1 G1] .
have step2:
"((λ(γ,α). ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α))) has_sum (Fv * Gv))
(Sigma ra_idx ra_idx_below)"
proof -
have "((λ(α,β). (ra_monomial h α * c1 α) * (ra_monomial h β * c2 β))
has_sum (Fv * Gv)) (ra_idx × ra_idx)
= ((λ(γ,α). ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α))) has_sum (Fv * Gv))
(Sigma ra_idx ra_idx_below)"
proof (rule has_sum_reindex_bij_witness
[where j = "λ(α,β). (ra_idx_add α β, α)" and i = "λ(γ,α). (α, ra_idx_diff γ α)"])
fix p :: "('a⇒nat) × ('a⇒nat)"
assume "p ∈ ra_idx × ra_idx"
obtain α β where p: "p = (α,β)" by (cases p)
show "(case (case p of (α,β) ⇒ (ra_idx_add α β, α)) of (γ,α) ⇒ (α, ra_idx_diff γ α)) = p"
by (simp add: p ra_idx_diff_def ra_idx_add_def)
next
fix p :: "('a⇒nat) × ('a⇒nat)"
assume P: "p ∈ ra_idx × ra_idx"
obtain α β where p: "p = (α,β)" by (cases p)
have aα: "α ∈ ra_idx" and aβ: "β ∈ ra_idx" using P p by auto
have m1: "ra_idx_add α β ∈ ra_idx" by (rule idx_add[OF aα aβ])
have m2: "α ∈ ra_idx_below (ra_idx_add α β)"
using aα by (simp add: ra_idx_below_def ra_idx_le_def ra_idx_add_def)
show "(case p of (α,β) ⇒ (ra_idx_add α β, α)) ∈ Sigma ra_idx ra_idx_below"
using m1 m2 by (simp add: p)
next
fix q :: "('a⇒nat) × ('a⇒nat)"
assume Q: "q ∈ Sigma ra_idx ra_idx_below"
obtain γ α where q: "q = (γ,α)" by (cases q)
have gγ: "γ ∈ ra_idx" and l: "ra_idx_le α γ" using Q q by (auto simp: ra_idx_below_def)
have "ra_idx_add α (ra_idx_diff γ α) = γ"
proof (rule ext)
fix b have "α b ≤ γ b" using l by (simp only: ra_idx_le_def)
thus "ra_idx_add α (ra_idx_diff γ α) b = γ b" by (simp only: ra_idx_add_def ra_idx_diff_def)
qed
then show "(case (case q of (γ,α) ⇒ (α, ra_idx_diff γ α)) of (α,β) ⇒ (ra_idx_add α β, α)) = q"
by (simp add: q)
next
fix q :: "('a⇒nat) × ('a⇒nat)"
assume Q: "q ∈ Sigma ra_idx ra_idx_below"
obtain γ α where q: "q = (γ,α)" by (cases q)
have gγ: "γ ∈ ra_idx" and aα: "α ∈ ra_idx" using Q q by (auto simp: ra_idx_below_def)
show "(case q of (γ,α) ⇒ (α, ra_idx_diff γ α)) ∈ ra_idx × ra_idx"
by (simp add: q aα idx_sub[OF gγ])
next
fix p :: "('a⇒nat) × ('a⇒nat)"
assume P: "p ∈ ra_idx × ra_idx"
obtain α β where p: "p = (α,β)" by (cases p)
have sub_eq: "ra_idx_diff (ra_idx_add α β) α = β" by (simp add: ra_idx_add_def ra_idx_diff_def)
have mm: "ra_monomial h α * ra_monomial h β = ra_monomial h (ra_idx_add α β)"
by (simp only: ra_monomial_idx_add)
have "ra_monomial h (ra_idx_add α β) * (c1 α * c2 (ra_idx_diff (ra_idx_add α β) α))
= ra_monomial h (ra_idx_add α β) * (c1 α * c2 β)" by (simp only: sub_eq)
also have "… = (ra_monomial h α * ra_monomial h β) * (c1 α * c2 β)"
by (simp only: mm)
also have "… = (ra_monomial h α * c1 α) * (ra_monomial h β * c2 β)"
by (simp only: mult.assoc mult.left_commute)
finally show "(case (case p of (α,β) ⇒ (ra_idx_add α β, α)) of (γ,α) ⇒
ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α)))
= (case p of (α,β) ⇒ (ra_monomial h α * c1 α) * (ra_monomial h β * c2 β))"
by (simp add: p)
qed simp
with step1 show ?thesis by simp
qed
have inner_fin:
"((λα. ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α))) has_sum
(ra_monomial h γ *⇩R ra_cauchy_prod c1 c2 γ)) (ra_idx_below γ)" if "γ ∈ ra_idx" for γ
proof -
have fin: "finite (ra_idx_below γ)" by (rule idx_lower_fin)
have "((λα. ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α))) has_sum
(∑α∈ra_idx_below γ. ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α)))) (ra_idx_below γ)"
by (rule has_sum_finite[OF fin])
also have "(∑α∈ra_idx_below γ. ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α)))
= ra_monomial h γ * (∑α∈ra_idx_below γ. c1 α * c2 (ra_idx_diff γ α))"
by (simp only: sum_distrib_left)
also have "(∑α∈ra_idx_below γ. c1 α * c2 (ra_idx_diff γ α)) = ra_cauchy_prod c1 c2 γ"
by (simp only: ra_cauchy_prod_def)
finally show ?thesis by simp
qed
have "((λγ. ra_monomial h γ *⇩R ra_cauchy_prod c1 c2 γ) has_sum (Fv * Gv)) ra_idx"
proof (rule has_sum_Sigma'
[where f = "λ(γ,α). ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α))"
and A = ra_idx and B = ra_idx_below and a = "Fv * Gv"
and b = "λγ. ra_monomial h γ *⇩R ra_cauchy_prod c1 c2 γ"])
show "((λ(γ,α). ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α))) has_sum (Fv * Gv))
(Sigma ra_idx ra_idx_below)" by (rule step2)
next
fix γ :: "'a ⇒ nat" assume "γ ∈ ra_idx"
then have "((λα. ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α))) has_sum
(ra_monomial h γ *⇩R ra_cauchy_prod c1 c2 γ)) (ra_idx_below γ)" by (rule inner_fin)
thus "((λα. (λ(γ,α). ra_monomial h γ * (c1 α * c2 (ra_idx_diff γ α))) (γ, α)) has_sum
(ra_monomial h γ *⇩R ra_cauchy_prod c1 c2 γ)) (ra_idx_below γ)" by simp
qed
thus ?thesis .
qed
subsection ‹Quantitative series-on-a-ball representation›
definition ra_series_on ::
"'a::euclidean_space ⇒ real ⇒ (('a⇒nat)⇒real) ⇒ ('a⇒real) ⇒ bool" where
"ra_series_on x0 r c F ⟷
(∀x. dist x x0 < r ⟶ ((λα. ra_monomial (x - x0) α *⇩R c α) has_sum F x) ra_idx)"
lemma ra_series_on_mono_radius:
assumes "ra_series_on x0 r c F" and "r' ≤ r"
shows "ra_series_on x0 r' c F"
using assms unfolding ra_series_on_def by fastforce
definition ra_idx_zero :: "'a::euclidean_space ⇒ nat" where
"ra_idx_zero = (λ_. 0)"
definition ra_coeff_one :: "('a::euclidean_space⇒nat) ⇒ real" where
"ra_coeff_one = (λα. if α = ra_idx_zero then 1 else 0)"
lemma ra_idx_zero_in: "ra_idx_zero ∈ ra_idx"
by (simp add: ra_idx_def ra_idx_zero_def)
lemma ra_series_on_one: "ra_series_on x0 r ra_coeff_one (λ_. 1)"
unfolding ra_series_on_def
proof (intro allI impI)
fix x :: 'a assume "dist x x0 < r"
define h where "h = x - x0"
have sing: "((λα. ra_monomial h α *⇩R ra_coeff_one α) has_sum
(∑α∈{ra_idx_zero}. ra_monomial h α *⇩R ra_coeff_one α)) {ra_idx_zero}"
by (rule has_sum_finite) auto
have val: "(∑α∈{ra_idx_zero}. ra_monomial h α *⇩R ra_coeff_one α) = (1::real)"
by (simp add: ra_coeff_one_def ra_monomial_def ra_idx_zero_def)
have "((λα. ra_monomial h α *⇩R ra_coeff_one α) has_sum (1::real)) ra_idx
= ((λα. ra_monomial h α *⇩R ra_coeff_one α) has_sum (1::real)) {ra_idx_zero}"
by (rule has_sum_cong_neutral) (auto simp: ra_coeff_one_def ra_idx_zero_in)
hence "((λα. ra_monomial h α *⇩R ra_coeff_one α) has_sum (1::real)) ra_idx"
using sing val by simp
thus "((λα. ra_monomial (x - x0) α *⇩R ra_coeff_one α) has_sum (1::real)) ra_idx"
by (simp only: h_def)
qed
lemma ra_series_on_mult:
assumes "ra_series_on x0 r c1 F" and "ra_series_on x0 r c2 G"
shows "ra_series_on x0 r (ra_cauchy_prod c1 c2) (λx. F x * G x)"
unfolding ra_series_on_def
proof (intro allI impI)
fix x :: 'a assume d: "dist x x0 < r"
have F1: "((λα. ra_monomial (x - x0) α * c1 α) has_sum F x) ra_idx"
using assms(1) d unfolding ra_series_on_def by simp
have G1: "((λβ. ra_monomial (x - x0) β * c2 β) has_sum G x) ra_idx"
using assms(2) d unfolding ra_series_on_def by simp
show "((λγ. ra_monomial (x - x0) γ *⇩R ra_cauchy_prod c1 c2 γ) has_sum (F x * G x)) ra_idx"
by (rule quant_mult[OF F1 G1])
qed
definition ra_cauchy_pow :: "(('a::euclidean_space⇒nat)⇒real) ⇒ nat ⇒ (('a⇒nat)⇒real)" where
"ra_cauchy_pow c n = (ra_cauchy_prod c ^^ n) ra_coeff_one"
lemma ra_cauchy_pow_0: "ra_cauchy_pow c 0 = ra_coeff_one" by (simp add: ra_cauchy_pow_def)
lemma ra_cauchy_pow_Suc: "ra_cauchy_pow c (Suc n) = ra_cauchy_prod c (ra_cauchy_pow c n)" by (simp add: ra_cauchy_pow_def)
lemma ra_series_on_power:
assumes "ra_series_on x0 r c F"
shows "ra_series_on x0 r (ra_cauchy_pow c n) (λx. (F x) ^ n)"
proof (induction n)
case 0
show ?case using ra_series_on_one[of x0 r] by (simp add: ra_cauchy_pow_0)
next
case (Suc n)
have "ra_series_on x0 r (ra_cauchy_prod c (ra_cauchy_pow c n)) (λx. F x * (F x) ^ n)"
by (rule ra_series_on_mult[OF assms Suc.IH])
thus ?case by (simp add: ra_cauchy_pow_Suc)
qed
lemma ra_series_on_prod:
fixes F :: "'i ⇒ 'a::euclidean_space ⇒ real"
assumes "finite I"
and "⋀i. i ∈ I ⟹ ∃c. ra_series_on x0 r c (F i)"
shows "∃cc. ra_series_on x0 r cc (λx. ∏i∈I. F i x)"
using assms
proof (induction I rule: finite_induct)
case empty
have "ra_series_on x0 r ra_coeff_one (λx. ∏i∈{}. F i x)" using ra_series_on_one[of x0 r] by simp
thus ?case by blast
next
case (insert j I)
obtain cj where cj: "ra_series_on x0 r cj (F j)" using insert.prems[of j] by blast
obtain crest where crest: "ra_series_on x0 r crest (λx. ∏i∈I. F i x)"
using insert.prems insert.IH by blast
have "ra_series_on x0 r (ra_cauchy_prod cj crest) (λx. F j x * (∏i∈I. F i x))"
by (rule ra_series_on_mult[OF cj crest])
hence "ra_series_on x0 r (ra_cauchy_prod cj crest) (λx. ∏i∈insert j I. F i x)"
using insert.hyps by simp
thus ?case by blast
qed
lemma ra_series_on_const:
"ra_series_on x0 r (λα. k * ra_coeff_one α) (λ_. k)"
unfolding ra_series_on_def
proof (intro allI impI)
fix x :: 'a assume d: "dist x x0 < r"
have "((λα. ra_monomial (x - x0) α *⇩R ra_coeff_one α) has_sum (1::real)) ra_idx"
using ra_series_on_one[of x0 r] d unfolding ra_series_on_def by simp
hence "((λα. k * (ra_monomial (x - x0) α *⇩R ra_coeff_one α)) has_sum (k * 1)) ra_idx"
by (rule has_sum_cmult_right)
thus "((λα. ra_monomial (x - x0) α *⇩R (k * ra_coeff_one α)) has_sum k) ra_idx"
by (simp add: mult.left_commute)
qed
lemma ra_series_on_add:
assumes "ra_series_on x0 r c1 F" and "ra_series_on x0 r c2 G"
shows "ra_series_on x0 r (λα. c1 α + c2 α) (λx. F x + G x)"
unfolding ra_series_on_def
proof (intro allI impI)
fix x :: 'a assume d: "dist x x0 < r"
have F1: "((λα. ra_monomial (x - x0) α *⇩R c1 α) has_sum F x) ra_idx"
using assms(1) d unfolding ra_series_on_def by simp
have G1: "((λα. ra_monomial (x - x0) α *⇩R c2 α) has_sum G x) ra_idx"
using assms(2) d unfolding ra_series_on_def by simp
have "((λα. ra_monomial (x - x0) α *⇩R c1 α + ra_monomial (x - x0) α *⇩R c2 α)
has_sum (F x + G x)) ra_idx"
by (rule has_sum_add[OF F1 G1])
thus "((λα. ra_monomial (x - x0) α *⇩R (c1 α + c2 α)) has_sum (F x + G x)) ra_idx"
by (simp only: scaleR_add_right)
qed
lemma ra_series_on_diff:
assumes "ra_series_on x0 r c1 F" and "ra_series_on x0 r c2 G"
shows "ra_series_on x0 r (λα. c1 α - c2 α) (λx. F x - G x)"
unfolding ra_series_on_def
proof (intro allI impI)
fix x :: 'a assume d: "dist x x0 < r"
have F1: "((λα. ra_monomial (x - x0) α *⇩R c1 α) has_sum F x) ra_idx"
using assms(1) d unfolding ra_series_on_def by simp
have G1: "((λα. ra_monomial (x - x0) α *⇩R c2 α) has_sum G x) ra_idx"
using assms(2) d unfolding ra_series_on_def by simp
have G1': "((λα. - (ra_monomial (x - x0) α *⇩R c2 α)) has_sum (- G x)) ra_idx"
using G1 by (simp add: has_sum_uminus)
have "((λα. ra_monomial (x - x0) α *⇩R c1 α + (- (ra_monomial (x - x0) α *⇩R c2 α)))
has_sum (F x + (- G x))) ra_idx"
by (rule has_sum_add[OF F1 G1'])
thus "((λα. ra_monomial (x - x0) α *⇩R (c1 α - c2 α)) has_sum (F x - G x)) ra_idx"
by (simp only: scaleR_diff_right, simp)
qed
text ‹From a vector series on a ball, the scalar component has a series on the
same ball.›
lemma ra_series_on_component:
fixes cf :: "('a::euclidean_space ⇒ nat) ⇒ 'b::euclidean_space"
assumes HS: "⋀x. dist x x0 < r ⟹
((λα. ra_monomial (x - x0) α *⇩R cf α) has_sum f x) ra_idx"
shows "ra_series_on x0 r (λα. cf α ∙ b) (λx. f x ∙ b)"
unfolding ra_series_on_def
proof (intro allI impI)
fix x :: 'a assume d: "dist x x0 < r"
have bl: "bounded_linear (λy::'b. y ∙ b)" by (rule bounded_linear_inner_left)
have "((λα. (ra_monomial (x - x0) α *⇩R cf α) ∙ b) has_sum (f x ∙ b)) ra_idx"
by (rule has_sum_bounded_linear[OF bl HS[OF d]])
thus "((λα. ra_monomial (x - x0) α *⇩R (cf α ∙ b)) has_sum (f x ∙ b)) ra_idx"
by (simp only: inner_scaleR_left scaleR_conv_of_real) simp
qed
text ‹A series for ‹x ↦ ra_monomial (f x - z) β› on the same ball as the series of ‹f›.›
lemma ra_series_on_ra_monomial_compose:
fixes cf :: "('a::euclidean_space ⇒ nat) ⇒ 'b::euclidean_space"
assumes HS: "⋀x. dist x x0 < r ⟹
((λα. ra_monomial (x - x0) α *⇩R cf α) has_sum f x) ra_idx"
shows "∃cc. ra_series_on x0 r cc (λx. ra_monomial (f x - z) β)"
proof -
have comp: "∃c. ra_series_on x0 r c (λx. ((f x - z) ∙ b) ^ (β b))" if "b ∈ Basis" for b
proof -
have s1: "ra_series_on x0 r (λα. cf α ∙ b) (λx. f x ∙ b)"
by (rule ra_series_on_component[OF HS])
have s2: "ra_series_on x0 r (λα. (z ∙ b) * ra_coeff_one α) (λ_. z ∙ b)"
by (rule ra_series_on_const)
have "ra_series_on x0 r (λα. (cf α ∙ b) - (z ∙ b) * ra_coeff_one α) (λx. (f x ∙ b) - (z ∙ b))"
by (rule ra_series_on_diff[OF s1 s2])
hence "ra_series_on x0 r (λα. (cf α ∙ b) - (z ∙ b) * ra_coeff_one α) (λx. (f x - z) ∙ b)"
by (simp only: inner_diff_left)
hence "ra_series_on x0 r (ra_cauchy_pow (λα. (cf α ∙ b) - (z ∙ b) * ra_coeff_one α) (β b))
(λx. ((f x - z) ∙ b) ^ (β b))"
by (rule ra_series_on_power)
thus ?thesis by blast
qed
have "∃cc. ra_series_on x0 r cc (λx. ∏b∈Basis. ((f x - z) ∙ b) ^ (β b))"
by (rule ra_series_on_prod[OF finite_Basis]) (use comp in simp)
then obtain cc where "ra_series_on x0 r cc (λx. ∏b∈Basis. ((f x - z) ∙ b) ^ (β b))"
by blast
hence "ra_series_on x0 r cc (λx. ra_monomial (f x - z) β)"
by (simp only: ra_monomial_def)
thus ?thesis by blast
qed
subsection ‹Majorant norm: submultiplicative under the Cauchy product›
definition ra_weighted_abs :: "real ⇒ (('a::euclidean_space⇒nat)⇒real) ⇒ (('a⇒nat)⇒real)" where
"ra_weighted_abs σ u = (λα. ¦u α¦ * σ ^ ra_deg α)"
definition ra_majorized :: "real ⇒ (('a::euclidean_space⇒nat)⇒real) ⇒ real ⇒ bool" where
"ra_majorized σ u K ⟷ (ra_weighted_abs σ u summable_on ra_idx) ∧ (∑⇩∞α∈ra_idx. ra_weighted_abs σ u α) ≤ K"
lemma ra_weighted_abs_nonneg: "0 ≤ σ ⟹ 0 ≤ ra_weighted_abs σ u α"
by (simp add: ra_weighted_abs_def)
lemma ra_majorized_imp_nonneg_sum:
assumes "0 ≤ σ" "ra_majorized σ u K"
shows "0 ≤ (∑⇩∞α∈ra_idx. ra_weighted_abs σ u α)"
using assms by (auto intro!: infsum_nonneg simp: ra_weighted_abs_nonneg)
lemma ra_majorized_one:
assumes "0 ≤ σ"
shows "ra_majorized σ ra_coeff_one 1"
proof -
have hs': "(ra_weighted_abs σ ra_coeff_one has_sum 1) ra_idx"
proof (rule has_sum_finite_neutralI)
show "finite {ra_idx_zero}"
by simp
show "{ra_idx_zero} ⊆ ra_idx"
using ra_idx_zero_in by simp
show "(1::real) = (∑α∈{ra_idx_zero}. ra_weighted_abs σ ra_coeff_one α)"
by (simp add: ra_weighted_abs_def ra_coeff_one_def ra_deg_def ra_idx_zero_def)
show "⋀x. x ∈ ra_idx - {ra_idx_zero} ⟹ ra_weighted_abs σ Real_Analytic.ra_coeff_one x = 0"
by (simp add: Real_Analytic.ra_coeff_one_def ra_weighted_abs_def)
qed
have s: "ra_weighted_abs σ ra_coeff_one summable_on ra_idx"
using hs' has_sum_imp_summable by blast
have i: "(∑⇩∞α∈ra_idx. ra_weighted_abs σ ra_coeff_one α) = 1"
by (rule infsumI[OF hs'])
show ?thesis
by (simp add: i ra_majorized_def s)
qed
text ‹Convolution of two nonnegative summable families: the inner-low finite sums
sum (over ‹ra_idx›) to the product of the totals.›
lemma cauchy_abs_prod:
fixes u' v' :: "('a::euclidean_space ⇒ nat) ⇒ real"
assumes Uhs: "(u' has_sum Uv) ra_idx" and Vhs: "(v' has_sum Vv) ra_idx"
shows "((λγ. ∑α∈ra_idx_below γ. u' α * v' (ra_idx_diff γ α)) has_sum (Uv * Vv)) ra_idx"
proof -
have prodHS: "((λ(α,β). u' α * v' β) has_sum (Uv * Vv)) (ra_idx × ra_idx)"
using prod_has_sum[OF Uhs Vhs] .
have reix: "((λ(γ,α). u' α * v' (ra_idx_diff γ α)) has_sum (Uv * Vv)) (Sigma ra_idx ra_idx_below)"
proof -
have "((λ(α,β). u' α * v' β) has_sum (Uv * Vv)) (ra_idx × ra_idx)
= ((λ(γ,α). u' α * v' (ra_idx_diff γ α)) has_sum (Uv * Vv)) (Sigma ra_idx ra_idx_below)"
proof (rule has_sum_reindex_bij_witness
[where j = "λ(α,β). (ra_idx_add α β, α)" and i = "λ(γ,α). (α, ra_idx_diff γ α)"])
fix p :: "('a⇒nat) × ('a⇒nat)"
assume "p ∈ ra_idx × ra_idx"
obtain α β where p: "p = (α,β)" by (cases p)
show "(case (case p of (α,β) ⇒ (ra_idx_add α β, α)) of (γ,α) ⇒ (α, ra_idx_diff γ α)) = p"
by (simp add: p ra_idx_diff_def ra_idx_add_def)
next
fix p :: "('a⇒nat) × ('a⇒nat)"
assume P: "p ∈ ra_idx × ra_idx"
obtain α β where p: "p = (α,β)" by (cases p)
have aα: "α ∈ ra_idx" and aβ: "β ∈ ra_idx" using P p by auto
have m1: "ra_idx_add α β ∈ ra_idx" by (rule idx_add[OF aα aβ])
have m2: "α ∈ ra_idx_below (ra_idx_add α β)" using aα by (simp add: ra_idx_below_def ra_idx_le_def ra_idx_add_def)
show "(case p of (α,β) ⇒ (ra_idx_add α β, α)) ∈ Sigma ra_idx ra_idx_below"
using m1 m2 by (simp add: p)
next
fix q :: "('a⇒nat) × ('a⇒nat)"
assume Q: "q ∈ Sigma ra_idx ra_idx_below"
obtain γ α where q: "q = (γ,α)" by (cases q)
have gγ: "γ ∈ ra_idx" and l: "ra_idx_le α γ" using Q q by (auto simp: ra_idx_below_def)
have "ra_idx_add α (ra_idx_diff γ α) = γ"
proof (rule ext)
fix b have "α b ≤ γ b" using l by (simp only: ra_idx_le_def)
thus "ra_idx_add α (ra_idx_diff γ α) b = γ b" by (simp only: ra_idx_add_def ra_idx_diff_def)
qed
then show "(case (case q of (γ,α) ⇒ (α, ra_idx_diff γ α)) of (α,β) ⇒ (ra_idx_add α β, α)) = q"
by (simp add: q)
next
fix q :: "('a⇒nat) × ('a⇒nat)"
assume Q: "q ∈ Sigma ra_idx ra_idx_below"
obtain γ α where q: "q = (γ,α)" by (cases q)
have gγ: "γ ∈ ra_idx" and aα: "α ∈ ra_idx" using Q q by (auto simp: ra_idx_below_def)
show "(case q of (γ,α) ⇒ (α, ra_idx_diff γ α)) ∈ ra_idx × ra_idx"
by (simp add: q aα idx_sub[OF gγ])
next
fix p :: "('a⇒nat) × ('a⇒nat)"
assume P: "p ∈ ra_idx × ra_idx"
obtain α β where p: "p = (α,β)" by (cases p)
have sub_eq: "ra_idx_diff (ra_idx_add α β) α = β" by (simp add: ra_idx_add_def ra_idx_diff_def)
show "(case (case p of (α,β) ⇒ (ra_idx_add α β, α)) of (γ,α) ⇒ u' α * v' (ra_idx_diff γ α))
= (case p of (α,β) ⇒ u' α * v' β)"
by (simp add: p sub_eq)
qed simp
with prodHS show ?thesis by simp
qed
show ?thesis
proof (rule has_sum_Sigma'
[where f = "λ(γ,α). u' α * v' (ra_idx_diff γ α)" and A = ra_idx and B = ra_idx_below
and a = "Uv * Vv" and b = "λγ. ∑α∈ra_idx_below γ. u' α * v' (ra_idx_diff γ α)"])
show "((λ(γ,α). u' α * v' (ra_idx_diff γ α)) has_sum (Uv * Vv)) (Sigma ra_idx ra_idx_below)"
by (rule reix)
next
fix γ :: "'a ⇒ nat" assume g: "γ ∈ ra_idx"
have fin: "finite (ra_idx_below γ)" by (rule idx_lower_fin)
have "((λα. u' α * v' (ra_idx_diff γ α)) has_sum
(∑α∈ra_idx_below γ. u' α * v' (ra_idx_diff γ α))) (ra_idx_below γ)"
by (rule has_sum_finite[OF fin])
thus "((λα. (λ(γ,α). u' α * v' (ra_idx_diff γ α)) (γ, α)) has_sum
(∑α∈ra_idx_below γ. u' α * v' (ra_idx_diff γ α))) (ra_idx_below γ)" by simp
qed
qed
text ‹Degree is additive across the Cauchy split.›
lemma ra_deg_split:
fixes γ :: "'a::euclidean_space ⇒ nat"
assumes "α ∈ ra_idx_below γ"
shows "ra_deg γ = ra_deg α + ra_deg (ra_idx_diff γ α)"
proof -
have l: "ra_idx_le α γ" using assms by (simp add: ra_idx_below_def)
have "ra_idx_add α (ra_idx_diff γ α) = γ"
proof (rule ext)
fix b have "α b ≤ γ b" using l by (simp only: ra_idx_le_def)
thus "ra_idx_add α (ra_idx_diff γ α) b = γ b" by (simp only: ra_idx_add_def ra_idx_diff_def)
qed
hence "ra_deg γ = ra_deg (ra_idx_add α (ra_idx_diff γ α))" by simp
also have "… = ra_deg α + ra_deg (ra_idx_diff γ α)"
by (simp only: ra_deg_def ra_idx_add_def sum.distrib)
finally show ?thesis .
qed
text ‹The key submultiplicativity estimate.›
lemma ra_majorized_cauchy_prod:
fixes u v :: "('a::euclidean_space ⇒ nat) ⇒ real"
assumes s0: "0 ≤ σ"
and U: "ra_majorized σ u KU" and V: "ra_majorized σ v KV"
and KUnn: "0 ≤ KU" and KVnn: "0 ≤ KV"
shows "ra_majorized σ (ra_cauchy_prod u v) (KU * KV)"
proof -
define u' where "u' = ra_weighted_abs σ u"
define v' where "v' = ra_weighted_abs σ v"
have u'nn: "0 ≤ u' α" for α using s0 by (simp add: u'_def ra_weighted_abs_nonneg)
have v'nn: "0 ≤ v' α" for α using s0 by (simp add: v'_def ra_weighted_abs_nonneg)
have u'_sum: "u' summable_on ra_idx" using U by (simp add: ra_majorized_def u'_def)
have v'_sum: "v' summable_on ra_idx" using V by (simp add: ra_majorized_def v'_def)
define Uv where "Uv = (∑⇩∞α∈ra_idx. u' α)"
define Vv where "Vv = (∑⇩∞β∈ra_idx. v' β)"
have Uhs: "(u' has_sum Uv) ra_idx" using u'_sum by (simp add: Uv_def)
have Vhs: "(v' has_sum Vv) ra_idx" using v'_sum by (simp add: Vv_def)
have UvKU: "Uv ≤ KU" using U by (simp add: ra_majorized_def u'_def Uv_def)
have VvKV: "Vv ≤ KV" using V by (simp add: ra_majorized_def v'_def Vv_def)
have Uvnn: "0 ≤ Uv" unfolding Uv_def using u'nn u'_sum by (auto intro!: infsum_nonneg)
have Vvnn: "0 ≤ Vv" unfolding Vv_def using v'nn v'_sum by (auto intro!: infsum_nonneg)
define S where "S = (λγ. ∑α∈ra_idx_below γ. u' α * v' (ra_idx_diff γ α))"
have collapse: "(S has_sum (Uv * Vv)) ra_idx"
unfolding S_def by (rule cauchy_abs_prod[OF Uhs Vhs])
have collapse_sum: "S summable_on ra_idx"
using collapse has_sum_imp_summable by blast
have Snn: "0 ≤ S γ" for γ
unfolding S_def by (intro sum_nonneg mult_nonneg_nonneg u'nn v'nn)
have termbound: "ra_weighted_abs σ (ra_cauchy_prod u v) γ ≤ S γ" if g: "γ ∈ ra_idx" for γ
proof -
have fin: "finite (ra_idx_below γ)" by (rule idx_lower_fin)
have termeq: "¦u α * v (ra_idx_diff γ α)¦ * σ ^ ra_deg γ = u' α * v' (ra_idx_diff γ α)"
if a: "α ∈ ra_idx_below γ" for α
proof -
have dd: "σ ^ ra_deg γ = σ ^ ra_deg α * σ ^ ra_deg (ra_idx_diff γ α)"
by (simp only: ra_deg_split[OF a] power_add)
have "¦u α * v (ra_idx_diff γ α)¦ * σ ^ ra_deg γ
= (¦u α¦ * ¦v (ra_idx_diff γ α)¦) * (σ ^ ra_deg α * σ ^ ra_deg (ra_idx_diff γ α))"
by (simp only: abs_mult dd)
also have "… = (¦u α¦ * σ ^ ra_deg α) * (¦v (ra_idx_diff γ α)¦ * σ ^ ra_deg (ra_idx_diff γ α))"
by (simp only: mult.assoc mult.left_commute)
finally show ?thesis by (simp only: u'_def v'_def ra_weighted_abs_def)
qed
have "ra_weighted_abs σ (ra_cauchy_prod u v) γ = ¦∑α∈ra_idx_below γ. u α * v (ra_idx_diff γ α)¦ * σ ^ ra_deg γ"
by (simp only: ra_weighted_abs_def ra_cauchy_prod_def)
also have "… ≤ (∑α∈ra_idx_below γ. ¦u α * v (ra_idx_diff γ α)¦) * σ ^ ra_deg γ"
by (rule mult_right_mono[OF sum_abs]) (use s0 in simp)
also have "… = (∑α∈ra_idx_below γ. ¦u α * v (ra_idx_diff γ α)¦ * σ ^ ra_deg γ)"
by (simp only: sum_distrib_right)
also have "… = (∑α∈ra_idx_below γ. u' α * v' (ra_idx_diff γ α))"
by (rule sum.cong[OF refl termeq])
also have "… = S γ" by (simp only: S_def)
finally show ?thesis .
qed
have cnn: "0 ≤ ra_weighted_abs σ (ra_cauchy_prod u v) γ" for γ using s0 by (simp add: ra_weighted_abs_nonneg)
have cmaj_sum: "ra_weighted_abs σ (ra_cauchy_prod u v) summable_on ra_idx"
proof (rule summable_on_comparison_test[where f = S and g = "ra_weighted_abs σ (ra_cauchy_prod u v)"])
show "S summable_on ra_idx" by (rule collapse_sum)
next
fix γ :: "'a ⇒ nat" assume g: "γ ∈ ra_idx"
show "ra_weighted_abs σ (ra_cauchy_prod u v) γ ≤ S γ" by (rule termbound[OF g])
next
fix γ :: "'a ⇒ nat" assume "γ ∈ ra_idx"
show "0 ≤ ra_weighted_abs σ (ra_cauchy_prod u v) γ" by (rule cnn)
qed
have "(∑⇩∞γ∈ra_idx. ra_weighted_abs σ (ra_cauchy_prod u v) γ) ≤ (∑⇩∞γ∈ra_idx. S γ)"
by (rule infsum_mono[OF cmaj_sum collapse_sum]) (rule termbound)
also have "(∑⇩∞γ∈ra_idx. S γ) = Uv * Vv" by (rule infsumI[OF collapse])
also have "Uv * Vv ≤ KU * KV"
using UvKU VvKV Uvnn Vvnn KVnn by (intro mult_mono) auto
finally have "(∑⇩∞γ∈ra_idx. ra_weighted_abs σ (ra_cauchy_prod u v) γ) ≤ KU * KV" .
thus ?thesis using cmaj_sum by (simp add: ra_majorized_def)
qed
text ‹Difference of analytic functions is analytic.›
lemma real_analytic_on_diff:
fixes f g :: "'a::euclidean_space ⇒ 'b::real_normed_vector"
assumes F: "real_analytic_on f U" and G: "real_analytic_on g U"
shows "real_analytic_on (λx. f x - g x) U"
proof -
have "real_analytic_on (λx. (-1) *⇩R g x) U"
by (rule real_analytic_on_scaleR[OF G])
hence "real_analytic_on (λx. f x + (-1) *⇩R g x) U"
by (rule real_analytic_on_add[OF F])
thus ?thesis by simp
qed
text ‹A natural power of an analytic scalar function is analytic.›
lemma real_analytic_on_power:
fixes f :: "'a::euclidean_space ⇒ real"
assumes F: "real_analytic_on f U"
shows "real_analytic_on (λx. (f x) ^ n) U"
proof (induction n)
case 0
from F have U: "open U" by (simp only: real_analytic_on_def)
show ?case using real_analytic_on_const[OF U, of "1::real"] by simp
next
case (Suc n)
have "real_analytic_on (λx. f x * (f x) ^ n) U"
by (rule real_analytic_on_mult[OF F Suc.IH])
thus ?case by simp
qed
text ‹A finite product of analytic scalar functions is analytic.›
lemma real_analytic_on_prod:
fixes f :: "'i ⇒ 'a::euclidean_space ⇒ real"
assumes U: "open U"
and F: "⋀i. i ∈ I ⟹ real_analytic_on (f i) U"
shows "real_analytic_on (λx. ∏i∈I. f i x) U"
using F
proof (induction I rule: infinite_finite_induct)
case (infinite I)
have "(λx. ∏i∈I. f i x) = (λx. 1)" using infinite.hyps by simp
thus ?case using real_analytic_on_const[OF U, of "1::real"] by simp
next
case empty
show ?case using real_analytic_on_const[OF U, of "1::real"] by simp
next
case (insert j I)
have aj: "real_analytic_on (f j) U" using insert.prems by simp
have arest: "real_analytic_on (λx. ∏i∈I. f i x) U"
using insert.prems by (intro insert.IH) simp
have "real_analytic_on (λx. f j x * (∏i∈I. f i x)) U"
by (rule real_analytic_on_mult[OF aj arest])
thus ?case using insert.hyps by simp
qed
text ‹The basis-monomial of an analytic vector function (in the shifted argument)
is analytic: ‹x ↦ ra_monomial (f x - z) β›.›
lemma real_analytic_on_ra_monomial_compose:
fixes f :: "'a::euclidean_space ⇒ 'b::euclidean_space"
assumes F: "real_analytic_on f U"
shows "real_analytic_on (λx. ra_monomial (f x - z) β) U"
proof -
from F have U: "open U" by (simp only: real_analytic_on_def)
have comp: "real_analytic_on (λx. ((f x - z) ∙ b) ^ (β b)) U" if "b ∈ Basis" for b
proof -
have "real_analytic_on (λx. f x ∙ b) U"
by (rule real_analytic_on_inner_component[OF F])
moreover have "real_analytic_on (λx. z ∙ b) U"
by (rule real_analytic_on_const[OF U])
ultimately have "real_analytic_on (λx. (f x ∙ b) - (z ∙ b)) U"
by (rule real_analytic_on_diff)
hence "real_analytic_on (λx. (f x - z) ∙ b) U"
by (simp only: inner_diff_left)
thus ?thesis by (rule real_analytic_on_power)
qed
have "real_analytic_on (λx. ∏b∈Basis. ((f x - z) ∙ b) ^ (β b)) U"
by (rule real_analytic_on_prod[OF U]) (use comp in simp)
thus ?thesis by (simp only: ra_monomial_def)
qed
subsection ‹Step (a): power lift of a majorant bound›
lemma ra_majorized_cauchy_pow:
fixes c :: "('a::euclidean_space⇒nat)⇒real"
assumes s0: "0 ≤ σ" and K: "ra_majorized σ c K" and Knn: "0 ≤ K"
shows "ra_majorized σ (ra_cauchy_pow c n) (K^n)"
proof (induction n)
case 0
show ?case using ra_majorized_one[OF s0] by (simp add: ra_cauchy_pow_0)
next
case (Suc n)
have "ra_majorized σ (ra_cauchy_prod c (ra_cauchy_pow c n)) (K * K^n)"
by (rule ra_majorized_cauchy_prod[OF s0 K Suc.IH Knn], simp only: Knn zero_le_power)
thus ?case by (simp add: ra_cauchy_pow_Suc)
qed
subsection ‹Step (b): coefficient bound gives a majorant bound›
text ‹The basis product of a constant base equals the base raised to the degree.›
lemma prod_const_ra_deg:
fixes t :: real
shows "(∏b∈(Basis::'a::euclidean_space set). t ^ (α b)) = t ^ ra_deg α"
by (simp add: ra_deg_def power_sum)
lemma coeff_majorized_of_bound:
fixes c :: "('b::euclidean_space⇒nat)⇒'d::real_normed_vector"
assumes Mnn: "0 ≤ M"
and bound: "⋀α. α∈ra_idx ⟹ norm (c α) ≤ M / t ^ (ra_deg α)"
and t: "0 < t" and s0: "0 ≤ σ" and st: "σ < t"
shows "ra_majorized σ (λα. norm (c α)) (M * (∑⇩∞α∈(ra_idx::('b⇒nat) set). (σ/t) ^ ra_deg α))"
proof -
define q where "q = σ/t"
have q0: "0 ≤ q" using s0 t by (simp add: q_def)
have q1: "q < 1" using st t by (simp add: q_def)
have geomS: "(λα::'b⇒nat. q ^ ra_deg α) summable_on ra_idx"
by (rule geom_idx_summable[OF q0 q1])
have geomMS: "(λα. M * q ^ ra_deg α) summable_on (ra_idx::('b⇒nat) set)"
by (rule summable_on_cmult_right[OF geomS])
have ptwise: "ra_weighted_abs σ (λα. norm (c α)) α ≤ M * q ^ ra_deg α" if a: "α∈ra_idx" for α
proof -
have tpow: "0 < t ^ ra_deg α" using t by simp
have "ra_weighted_abs σ (λα. norm (c α)) α = norm (c α) * σ ^ ra_deg α"
by (simp add: ra_weighted_abs_def)
also have "… ≤ (M / t ^ ra_deg α) * σ ^ ra_deg α"
by (rule mult_right_mono[OF bound[OF a]]) (use s0 in simp)
also have "… = M * (σ ^ ra_deg α / t ^ ra_deg α)" by simp
also have "… = M * q ^ ra_deg α"
by (simp add: q_def power_divide)
finally show ?thesis .
qed
have nn: "0 ≤ ra_weighted_abs σ (λα. norm (c α)) α" for α using s0 by (rule ra_weighted_abs_nonneg)
have summ: "ra_weighted_abs σ (λα. norm (c α)) summable_on ra_idx"
by (rule summable_on_comparison_test[OF geomMS]) (use ptwise nn in auto)
have "(∑⇩∞α∈ra_idx. ra_weighted_abs σ (λα. norm (c α)) α)
≤ (∑⇩∞α∈(ra_idx::('b⇒nat) set). M * q ^ ra_deg α)"
by (rule infsum_mono[OF summ geomMS]) (rule ptwise)
also have "… = M * (∑⇩∞α∈(ra_idx::('b⇒nat) set). q ^ ra_deg α)"
by (rule infsum_cmult_right[OF geomS])
finally show ?thesis using summ by (simp add: ra_majorized_def q_def)
qed
subsection ‹Majle helpers: domination, scaling, triangle›
text ‹If ‹|c1 α| ≤ |c2 α|› pointwise and ‹c2› is majorized, so is ‹c1›.›
lemma ra_majorized_dom:
fixes c1 c2 :: "('a::euclidean_space⇒nat)⇒real"
assumes s0: "0 ≤ σ"
and dom: "⋀α. α∈ra_idx ⟹ ¦c1 α¦ ≤ ¦c2 α¦"
and B: "ra_majorized σ c2 K"
shows "ra_majorized σ c1 K"
proof -
have c2sum: "ra_weighted_abs σ c2 summable_on ra_idx" using B by (simp add: ra_majorized_def)
have ptw: "ra_weighted_abs σ c1 α ≤ ra_weighted_abs σ c2 α" if "α∈ra_idx" for α
unfolding ra_weighted_abs_def using dom[OF that] s0 by (simp add: mult_right_mono)
have nn: "0 ≤ ra_weighted_abs σ c1 α" for α using s0 by (rule ra_weighted_abs_nonneg)
have c1sum: "ra_weighted_abs σ c1 summable_on ra_idx"
by (rule summable_on_comparison_test[OF c2sum]) (use ptw nn in auto)
have "(∑⇩∞α∈ra_idx. ra_weighted_abs σ c1 α) ≤ (∑⇩∞α∈ra_idx. ra_weighted_abs σ c2 α)"
by (rule infsum_mono[OF c1sum c2sum]) (rule ptw)
also have "… ≤ K" using B by (simp add: ra_majorized_def)
finally show ?thesis using c1sum by (simp add: ra_majorized_def)
qed
lemma ra_majorized_zero:
"ra_majorized σ ((λ_. 0) :: ('a::euclidean_space ⇒ nat) ⇒ real) 0"
by (simp add: ra_majorized_def ra_weighted_abs_def)
lemma ra_majorized_cmul:
fixes c :: "('a::euclidean_space⇒nat)⇒real"
assumes s0: "0 ≤ σ" and B: "ra_majorized σ c K"
shows "ra_majorized σ (λα. a * c α) (¦a¦ * K)"
proof -
have csum: "ra_weighted_abs σ c summable_on ra_idx" using B by (simp add: ra_majorized_def)
have eq: "ra_weighted_abs σ (λα. a * c α) = (λα. ¦a¦ * ra_weighted_abs σ c α)"
by (rule ext) (simp add: ra_weighted_abs_def abs_mult)
have asum: "ra_weighted_abs σ (λα. a * c α) summable_on ra_idx"
using summable_on_cmult_right[OF csum, where c = "¦a¦"] by (simp add: eq)
have "(∑⇩∞α∈ra_idx. ra_weighted_abs σ (λα. a * c α) α)
= (∑⇩∞α∈ra_idx. ¦a¦ * ra_weighted_abs σ c α)" by (simp add: eq[THEN fun_cong])
also have "… = ¦a¦ * (∑⇩∞α∈ra_idx. ra_weighted_abs σ c α)"
by (rule infsum_cmult_right[OF csum])
also have "… ≤ ¦a¦ * K" using B by (simp add: ra_majorized_def mult_left_mono)
finally show ?thesis using asum by (simp add: ra_majorized_def)
qed
lemma ra_majorized_add:
fixes c1 c2 :: "('a::euclidean_space⇒nat)⇒real"
assumes s0: "0 ≤ σ" and A: "ra_majorized σ c1 K1" and B: "ra_majorized σ c2 K2"
shows "ra_majorized σ (λα. c1 α + c2 α) (K1 + K2)"
proof -
have c1sum: "ra_weighted_abs σ c1 summable_on ra_idx" using A by (simp add: ra_majorized_def)
have c2sum: "ra_weighted_abs σ c2 summable_on ra_idx" using B by (simp add: ra_majorized_def)
have ptw: "ra_weighted_abs σ (λα. c1 α + c2 α) α ≤ ra_weighted_abs σ c1 α + ra_weighted_abs σ c2 α" for α
proof -
have "ra_weighted_abs σ (λα. c1 α + c2 α) α = ¦c1 α + c2 α¦ * σ ^ ra_deg α"
by (simp add: ra_weighted_abs_def)
also have "… ≤ (¦c1 α¦ + ¦c2 α¦) * σ ^ ra_deg α"
by (rule mult_right_mono) (use s0 in ‹auto simp: abs_triangle_ineq›)
also have "… = ra_weighted_abs σ c1 α + ra_weighted_abs σ c2 α"
by (simp add: ra_weighted_abs_def distrib_right)
finally show ?thesis .
qed
have nn: "0 ≤ ra_weighted_abs σ (λα. c1 α + c2 α) α" for α using s0 by (rule ra_weighted_abs_nonneg)
have sumadd: "(λα. ra_weighted_abs σ c1 α + ra_weighted_abs σ c2 α) summable_on ra_idx"
using c1sum c2sum by (rule summable_on_add)
have addsum: "ra_weighted_abs σ (λα. c1 α + c2 α) summable_on ra_idx"
by (rule summable_on_comparison_test[OF sumadd]) (use ptw nn in auto)
have "(∑⇩∞α∈ra_idx. ra_weighted_abs σ (λα. c1 α + c2 α) α)
≤ (∑⇩∞α∈ra_idx. ra_weighted_abs σ c1 α + ra_weighted_abs σ c2 α)"
by (rule infsum_mono[OF addsum sumadd]) (rule ptw)
also have "… = (∑⇩∞α∈ra_idx. ra_weighted_abs σ c1 α) + (∑⇩∞α∈ra_idx. ra_weighted_abs σ c2 α)"
by (rule infsum_add[OF c1sum c2sum])
also have "… ≤ K1 + K2" using A B by (simp add: ra_majorized_def add_mono)
finally show ?thesis using addsum by (simp add: ra_majorized_def)
qed
lemma ra_majorized_vec_sum:
fixes c :: "'i ⇒ ('a::euclidean_space ⇒ nat) ⇒ 'b::real_normed_vector"
assumes s0: "0 ≤ σ"
and fin: "finite I"
and maj: "⋀i. i ∈ I ⟹ ra_majorized σ (λα. norm (c i α)) (K i)"
shows "ra_majorized σ (λα. norm (∑i∈I. c i α)) (∑i∈I. K i)"
using fin maj
proof (induction I rule: finite_induct)
case empty
show ?case
by (simp add: ra_majorized_zero)
next
case (insert i I)
have ci: "ra_majorized σ (λα. norm (c i α)) (K i)"
using insert.prems by simp
have cI: "ra_majorized σ (λα. norm (∑j∈I. c j α)) (∑j∈I. K j)"
using insert.IH insert.prems by blast
have addmaj: "ra_majorized σ (λα. norm (c i α) + norm (∑j∈I. c j α))
(K i + (∑j∈I. K j))"
by (rule ra_majorized_add[OF s0 ci cI])
have dom: "¦norm (c i α + (∑j∈I. c j α))¦
≤ ¦norm (c i α) + norm (∑j∈I. c j α)¦"
for α :: "'a ⇒ nat"
by (simp add: norm_triangle_ineq)
show ?case
using insert.hyps
by (simp add: sum.insert[OF insert.hyps])
(rule ra_majorized_dom[OF s0 _ addmaj], rule dom)
qed
lemma identity_coeff_series_majorized:
obtains cid :: "('a::euclidean_space ⇒ nat) ⇒ 'a" where
"⋀y. ((λα. ra_monomial y α *⇩R cid α) has_sum y) ra_idx"
"⋀σ. 0 ≤ σ ⟹
ra_majorized σ (λα. norm (cid α)) (real (card (Basis :: 'a set)) * σ)"
proof -
define e :: "'a ⇒ 'a ⇒ nat" where
"e = (λb x. if x = b then 1 else 0)"
define cid :: "('a ⇒ nat) ⇒ 'a" where
"cid = (λα. ∑b∈Basis. if α = e b then b else 0)"
have e_idx: "e b ∈ ra_idx" if "b ∈ Basis" for b
using that by (auto simp: e_def ra_idx_def)
have e_inj: "inj_on e (Basis :: 'a set)"
proof (rule inj_onI)
fix b c :: 'a
assume b: "b ∈ Basis" and c: "c ∈ Basis" and eq: "e b = e c"
have h0: "e b b = e c b"
using eq by simp
have h: "(1::nat) = (if b = c then 1 else 0)"
using h0 by (simp add: e_def)
show "b = c"
proof (rule ccontr)
assume "b ≠ c"
with h show False by simp
qed
qed
have mono_e: "ra_monomial y (e b) = y ∙ b" if b: "b ∈ Basis" for y b
proof -
have "ra_monomial y (e b) =
(y ∙ b) * (∏c∈Basis - {b}. (y ∙ c) ^ (e b c))"
using b by (simp add: ra_monomial_def sum.remove e_def prod.remove)
also have "… = y ∙ b"
by (simp add: e_def)
finally show ?thesis .
qed
have deg_e: "ra_deg (e b) = 1" if b: "b ∈ Basis" for b
using b by (simp add: ra_deg_def e_def sum.remove[where x = b])
have cid_e: "cid (e b) = b" if b: "b ∈ Basis" for b
proof -
have "cid (e b) = (∑c∈Basis. if c = b then c else 0)"
unfolding cid_def
by (rule sum.cong) (use b e_inj in ‹auto simp: inj_on_def›)
also have "… = b"
using b by simp
finally show ?thesis .
qed
have cid_zero: "cid α = 0" if "α ∈ ra_idx - image e Basis" for α
unfolding cid_def
by (rule sum.neutral) (use that in auto)
have series: "((λα. ra_monomial y α *⇩R cid α) has_sum y) ra_idx" for y
proof (rule has_sum_finite_neutralI)
show "finite (image e (Basis :: 'a set))"
by simp
show "image e (Basis :: 'a set) ⊆ ra_idx"
using e_idx by blast
have "(∑α∈image e Basis. ra_monomial y α *⇩R cid α) =
(∑b∈Basis. ra_monomial y (e b) *⇩R cid (e b))"
by (rule sum.reindex_cong[where l = e, OF e_inj refl]) simp
also have "… = (∑b∈Basis. (y ∙ b) *⇩R b)"
by (rule sum.cong) (use mono_e cid_e in auto)
also have "… = y"
by (simp add: euclidean_representation)
finally show "y = (∑α∈image e Basis. ra_monomial y α *⇩R cid α)"
by simp
show "⋀α. α ∈ ra_idx - image e Basis ⟹ ra_monomial y α *⇩R cid α = 0"
by (simp add: cid_zero)
qed
have maj: "ra_majorized σ (λα. norm (cid α)) (real (card (Basis :: 'a set)) * σ)"
if s0: "0 ≤ σ" for σ
proof -
have hs: "(ra_weighted_abs σ (λα. norm (cid α)) has_sum
(real (card (Basis :: 'a set)) * σ)) ra_idx"
proof (rule has_sum_finite_neutralI)
show "finite (image e (Basis :: 'a set))"
by simp
show "image e (Basis :: 'a set) ⊆ ra_idx"
using e_idx by blast
have "(∑α∈image e Basis. ra_weighted_abs σ (λα. norm (cid α)) α) =
(∑b∈Basis. ra_weighted_abs σ (λα. norm (cid α)) (e b))"
by (rule sum.reindex_cong[where l = e, OF e_inj refl]) simp
also have "… = (∑b∈(Basis :: 'a set). σ)"
proof -
have term_eq: "ra_weighted_abs σ (λα. norm (cid α)) (e b) = σ"
if b: "b ∈ (Basis :: 'a set)" for b
proof -
have "ra_weighted_abs σ (λα. norm (cid α)) (e b) =
norm (cid (e b)) * σ ^ ra_deg (e b)"
by (simp add: ra_weighted_abs_def)
also have "… = σ"
using b by (simp add: cid_e deg_e)
finally show ?thesis .
qed
show ?thesis
by (rule sum.cong[OF refl term_eq])
qed
also have "… = real (card (Basis :: 'a set)) * σ"
by simp
finally show "real (card (Basis :: 'a set)) * σ =
(∑α∈image e Basis. ra_weighted_abs σ (λα. norm (cid α)) α)"
by simp
show "⋀α. α ∈ ra_idx - image e Basis ⟹
ra_weighted_abs σ (λα. norm (cid α)) α = 0"
by (simp add: cid_zero ra_weighted_abs_def)
qed
have summ: "ra_weighted_abs σ (λα. norm (cid α)) summable_on ra_idx"
using hs has_sum_imp_summable by blast
have inf: "(∑⇩∞α∈ra_idx. ra_weighted_abs σ (λα. norm (cid α)) α) =
real (card (Basis :: 'a set)) * σ"
by (rule infsumI[OF hs])
show ?thesis
by (simp add: ra_majorized_def summ inf)
qed
show ?thesis
by (rule that[OF series maj])
qed
subsection ‹Combined series and majorant bookkeeping›
text ‹‹c› is the coefficient family of ‹F› on the ball and is majorized by ‹K›.›
definition ra_series_majorized ::
"'a::euclidean_space ⇒ real ⇒ real ⇒ (('a⇒nat)⇒real) ⇒ ('a⇒real) ⇒ real ⇒ bool" where
"ra_series_majorized x0 r σ c F K ⟷ ra_series_on x0 r c F ∧ ra_majorized σ c K"
lemma ra_series_majorized_mono_radius:
assumes "ra_series_majorized x0 r σ c F K" and "r' ≤ r"
shows "ra_series_majorized x0 r' σ c F K"
using assms ra_series_on_mono_radius unfolding ra_series_majorized_def by blast
lemma ra_series_majorized_one:
assumes "0 ≤ σ"
shows "ra_series_majorized x0 r σ ra_coeff_one (λ_. 1) 1"
unfolding ra_series_majorized_def using ra_series_on_one ra_majorized_one[OF assms] by blast
lemma ra_series_majorized_mult:
assumes s0: "0 ≤ σ"
and A: "ra_series_majorized x0 r σ c1 F K1" and B: "ra_series_majorized x0 r σ c2 G K2"
and K1nn: "0 ≤ K1" and K2nn: "0 ≤ K2"
shows "ra_series_majorized x0 r σ (ra_cauchy_prod c1 c2) (λx. F x * G x) (K1 * K2)"
unfolding ra_series_majorized_def
proof
show "ra_series_on x0 r (ra_cauchy_prod c1 c2) (λx. F x * G x)"
using A B by (auto simp: ra_series_majorized_def intro: ra_series_on_mult)
show "ra_majorized σ (ra_cauchy_prod c1 c2) (K1 * K2)"
using A B by (auto simp: ra_series_majorized_def intro: ra_majorized_cauchy_prod[OF s0 _ _ K1nn K2nn])
qed
lemma ra_series_majorized_pow:
assumes s0: "0 ≤ σ"
and A: "ra_series_majorized x0 r σ c F K" and Knn: "0 ≤ K"
shows "ra_series_majorized x0 r σ (ra_cauchy_pow c n) (λx. (F x) ^ n) (K ^ n)"
unfolding ra_series_majorized_def
proof
show "ra_series_on x0 r (ra_cauchy_pow c n) (λx. (F x) ^ n)"
using A by (auto simp: ra_series_majorized_def intro: ra_series_on_power)
show "ra_majorized σ (ra_cauchy_pow c n) (K ^ n)"
using A by (auto simp: ra_series_majorized_def intro: ra_majorized_cauchy_pow[OF s0 _ Knn])
qed
text ‹Finite products, with the product of the majorant bounds.›
lemma ra_series_majorized_prod:
fixes F :: "'i ⇒ 'a::euclidean_space ⇒ real"
assumes s0: "0 ≤ σ" and fin: "finite I"
and per: "⋀i. i ∈ I ⟹ ∃c. ra_series_majorized x0 r σ c (F i) (K i)"
and Knn: "⋀i. i ∈ I ⟹ 0 ≤ K i"
shows "∃cc. ra_series_majorized x0 r σ cc (λx. ∏i∈I. F i x) (∏i∈I. K i)"
using fin per Knn
proof (induction I rule: finite_induct)
case empty
have "ra_series_majorized x0 r σ ra_coeff_one (λx. ∏i∈{}. F i x) (∏i∈{}. K i)"
using ra_series_majorized_one[OF s0] by simp
thus ?case by blast
next
case (insert j I)
obtain cj where cj: "ra_series_majorized x0 r σ cj (F j) (K j)" using insert.prems(1)[of j] by blast
obtain crest where crest: "ra_series_majorized x0 r σ crest (λx. ∏i∈I. F i x) (∏i∈I. K i)"
using insert.prems insert.IH by blast
have Kjnn: "0 ≤ K j" using insert.prems(2)[of j] by simp
have Krestnn: "0 ≤ (∏i∈I. K i)" using insert.prems(2) by (intro prod_nonneg) auto
have "ra_series_majorized x0 r σ (ra_cauchy_prod cj crest) (λx. F j x * (∏i∈I. F i x)) (K j * (∏i∈I. K i))"
by (rule ra_series_majorized_mult[OF s0 cj crest Kjnn Krestnn])
hence "ra_series_majorized x0 r σ (ra_cauchy_prod cj crest) (λx. ∏i∈insert j I. F i x) (∏i∈insert j I. K i)"
using insert.hyps by simp
thus ?case by blast
qed
lemma ra_majorized_mono:
assumes "ra_majorized σ c K" and "K ≤ K'"
shows "ra_majorized σ c K'"
using assms by (simp add: ra_majorized_def)
lemma ra_series_majorized_relax:
assumes "ra_series_majorized x0 r σ c F K" and "K ≤ K'"
shows "ra_series_majorized x0 r σ c F K'"
using assms ra_majorized_mono by (auto simp: ra_series_majorized_def)
text ‹Product of a base raised to multi-index entries, dominated by a common base
raised to the total degree.›
lemma prod_pow_le_deg:
fixes Kb :: "'a::euclidean_space ⇒ real"
assumes nn: "⋀b. b ∈ Basis ⟹ 0 ≤ Kb b"
and le: "⋀b. b ∈ Basis ⟹ Kb b ≤ Kf"
shows "(∏b∈Basis. (Kb b) ^ (β b)) ≤ Kf ^ ra_deg β"
proof -
have "(∏b∈(Basis::'a set). (Kb b) ^ (β b)) ≤ (∏b∈(Basis::'a set). Kf ^ (β b))"
proof (rule prod_mono)
fix b assume b: "b ∈ (Basis::'a set)"
have "0 ≤ (Kb b) ^ (β b)" using nn[OF b] by simp
moreover have "(Kb b) ^ (β b) ≤ Kf ^ (β b)"
by (rule power_mono[OF le[OF b] nn[OF b]])
ultimately show "0 ≤ (Kb b) ^ (β b) ∧ (Kb b) ^ (β b) ≤ Kf ^ (β b)" by simp
qed
also have "(∏b∈(Basis::'a set). Kf ^ (β b)) = Kf ^ ra_deg β"
by (rule prod_const_ra_deg)
finally show ?thesis .
qed
text ‹The coefficient family of ‹x ↦ ra_monomial (f x - z) β›, with the majorant bound
‹Kf ^ ra_deg β› uniformly in ‹β›.›
lemma ra_series_majorized_ra_monomial_compose:
fixes cf :: "('a::euclidean_space ⇒ nat) ⇒ 'b::euclidean_space"
assumes s0: "0 ≤ σ"
and HS: "⋀x. dist x x0 < r ⟹
((λα. ra_monomial (x - x0) α *⇩R cf α) has_sum f x) ra_idx"
and cfmaj: "ra_majorized σ (λα. norm (cf α)) Mc"
and Kf_ge: "⋀b. b ∈ Basis ⟹ Mc + ¦z ∙ b¦ ≤ Kf"
and Kf_nn: "0 ≤ Kf"
shows "∃cc. ra_series_majorized x0 r σ cc (λx. ra_monomial (f x - z) β) (Kf ^ ra_deg β)"
proof -
define Kb where "Kb = (λb. Mc + ¦z ∙ b¦)"
have Mc_nn: "0 ≤ Mc" using ra_majorized_imp_nonneg_sum[OF s0 cfmaj] cfmaj by (simp add: ra_majorized_def)
have Kbnn: "0 ≤ Kb b" for b using Mc_nn by (simp add: Kb_def)
have Kble: "Kb b ≤ Kf" if "b ∈ Basis" for b using Kf_ge[OF that] by (simp add: Kb_def)
have comp: "ra_series_majorized x0 r σ (λα. (cf α ∙ b) - (z ∙ b) * ra_coeff_one α)
(λx. (f x - z) ∙ b) (Kb b)" if b: "b ∈ Basis" for b
unfolding ra_series_majorized_def
proof
have s1: "ra_series_on x0 r (λα. cf α ∙ b) (λx. f x ∙ b)"
by (rule ra_series_on_component[OF HS])
have s2: "ra_series_on x0 r (λα. (z ∙ b) * ra_coeff_one α) (λ_. z ∙ b)"
by (rule ra_series_on_const)
have "ra_series_on x0 r (λα. (cf α ∙ b) - (z ∙ b) * ra_coeff_one α) (λx. (f x ∙ b) - (z ∙ b))"
by (rule ra_series_on_diff[OF s1 s2])
thus "ra_series_on x0 r (λα. (cf α ∙ b) - (z ∙ b) * ra_coeff_one α) (λx. (f x - z) ∙ b)"
by (simp only: inner_diff_left)
next
have comp_dom: "¦cf α ∙ b¦ ≤ ¦norm (cf α)¦" if "α∈ra_idx" for α
proof -
have "¦cf α ∙ b¦ ≤ norm (cf α) * norm b"
by (rule Cauchy_Schwarz_ineq2)
also have "… = norm (cf α)" using b by simp
finally show ?thesis by simp
qed
have m1: "ra_majorized σ (λα. cf α ∙ b) Mc"
by (rule ra_majorized_dom[OF s0 comp_dom cfmaj])
have m2: "ra_majorized σ (λα. (z ∙ b) * ra_coeff_one α) (¦z ∙ b¦ * 1)"
by (rule ra_majorized_cmul[OF s0 ra_majorized_one[OF s0]])
have m2': "ra_majorized σ (λα. (z ∙ b) * ra_coeff_one α) (¦z ∙ b¦)" using m2 by simp
have m2neg: "ra_majorized σ (λα. - ((z ∙ b) * ra_coeff_one α)) (¦z ∙ b¦)"
proof -
have "ra_majorized σ (λα. (-1) * ((z ∙ b) * ra_coeff_one α)) (¦-1::real¦ * ¦z ∙ b¦)"
by (rule ra_majorized_cmul[OF s0 m2'])
thus ?thesis by simp
qed
have "ra_majorized σ (λα. (cf α ∙ b) + (- ((z ∙ b) * ra_coeff_one α))) (Mc + ¦z ∙ b¦)"
by (rule ra_majorized_add[OF s0 m1 m2neg])
thus "ra_majorized σ (λα. (cf α ∙ b) - (z ∙ b) * ra_coeff_one α) (Kb b)"
by (simp add: Kb_def)
qed
have comppow: "∃c. ra_series_majorized x0 r σ c (λx. ((f x - z) ∙ b) ^ (β b)) (Kb b ^ (β b))"
if b: "b ∈ Basis" for b
using ra_series_majorized_pow[OF s0 comp[OF b] Kbnn] by blast
have "∃cc. ra_series_majorized x0 r σ cc (λx. ∏b∈Basis. ((f x - z) ∙ b) ^ (β b))
(∏b∈Basis. Kb b ^ (β b))"
by (rule ra_series_majorized_prod[OF s0 finite_Basis])
(use comppow Kbnn in ‹auto intro: zero_le_power›)
then obtain cc where cc: "ra_series_majorized x0 r σ cc (λx. ∏b∈Basis. ((f x - z) ∙ b) ^ (β b))
(∏b∈Basis. Kb b ^ (β b))" by blast
have prodle: "(∏b∈Basis. Kb b ^ (β b)) ≤ Kf ^ ra_deg β"
by (rule prod_pow_le_deg[OF Kbnn Kble])
have "ra_series_majorized x0 r σ cc (λx. ∏b∈Basis. ((f x - z) ∙ b) ^ (β b)) (Kf ^ ra_deg β)"
by (rule ra_series_majorized_relax[OF cc prodle])
hence "ra_series_majorized x0 r σ cc (λx. ra_monomial (f x - z) β) (Kf ^ ra_deg β)"
by (simp only: ra_monomial_def)
thus ?thesis by blast
qed
subsection ‹Step (c): composition›
text ‹Vector-valued continuity of an analytic function, obtained componentwise from
the scalar continuity lemma.›
lemma real_analytic_on_imp_continuous_vec:
fixes f :: "'a::euclidean_space ⇒ 'b::euclidean_space"
assumes ana: "real_analytic_on f U" and xU: "x0 ∈ U"
shows "continuous (at x0) f"
proof (subst continuous_componentwise, intro ballI)
fix b :: 'b assume b: "b ∈ Basis"
have "real_analytic_on (λx. f x ∙ b) U"
by (rule real_analytic_on_inner_component[OF ana])
thus "continuous (at x0) (λx. f x ∙ b)"
by (rule real_analytic_on_imp_continuous[OF _ xU])
qed
text ‹Only ‹ra_idx_zero› has degree zero among the multi-indices.›
lemma ra_deg_eq0_iff:
fixes α :: "'a::euclidean_space ⇒ nat"
assumes "α ∈ ra_idx"
shows "ra_deg α = 0 ⟷ α = ra_idx_zero"
proof
assume d0: "ra_deg α = 0"
have z: "α b = 0" if "b ∈ Basis" for b
proof -
have "α b ≤ (∑c∈Basis. α c)" using that by (intro member_le_sum) auto
also have "… = 0" using d0 by (simp add: ra_deg_def)
finally show ?thesis by simp
qed
show "α = ra_idx_zero"
proof (rule ext)
fix b show "α b = ra_idx_zero b"
proof (cases "b ∈ Basis")
case True thus ?thesis using z by (simp add: ra_idx_zero_def)
next
case False thus ?thesis using assms by (auto simp: ra_idx_def ra_idx_zero_def)
qed
qed
next
assume "α = ra_idx_zero"
thus "ra_deg α = 0" by (simp add: ra_deg_def ra_idx_zero_def)
qed
lemma ra_series_at_zero_coeff:
fixes c :: "('a::euclidean_space ⇒ nat) ⇒ 'b::real_normed_vector"
assumes hs: "((λα. ra_monomial (0::'a) α *⇩R c α) has_sum v) ra_idx"
shows "c ra_idx_zero = v"
proof -
have neutral: "ra_monomial (0::'a) α *⇩R c α = 0"
if "α ∈ ra_idx - {ra_idx_zero}" for α
proof -
have "α ≠ ra_idx_zero"
using that by simp
hence "ra_deg α ≠ 0"
using ra_deg_eq0_iff that by auto
thus ?thesis
by (simp add: ra_monomial_zero)
qed
have "((λα. ra_monomial (0::'a) α *⇩R c α) has_sum v) ra_idx
= ((λα. ra_monomial (0::'a) α *⇩R c α) has_sum v) {ra_idx_zero}"
by (rule has_sum_cong_neutral) (use neutral ra_idx_zero_in in auto)
with hs have hs1:
"((λα. ra_monomial (0::'a) α *⇩R c α) has_sum v) {ra_idx_zero}"
by simp
moreover have "((λα. ra_monomial (0::'a) α *⇩R c α) has_sum c ra_idx_zero) {ra_idx_zero}"
by (rule has_sum_finiteI) (auto simp: ra_monomial_zero ra_idx_zero_def ra_deg_def)
ultimately show ?thesis
by (metis has_sum_unique)
qed
lemma ra_dcoeff_idx_zero_basis:
fixes c :: "('a::euclidean_space ⇒ nat) ⇒ 'b::real_normed_vector"
assumes b: "b ∈ Basis"
shows "ra_dcoeff c b ra_idx_zero = c (λx. if x = b then 1 else 0)"
proof -
define e :: "'a ⇒ nat" where "e = (λx. if x = b then 1 else 0)"
have inc_b: "ra_inc ra_idx_zero b = e"
by (rule ext) (simp add: ra_inc_def ra_idx_zero_def e_def)
have rest0:
"(∑x∈Basis - {b}.
(real (Suc (ra_idx_zero x)) * (b ∙ x)) *⇩R c (ra_inc ra_idx_zero x)) = 0"
by (rule sum.neutral) (use b in ‹auto simp: inner_Basis›)
have "ra_dcoeff c b ra_idx_zero =
(real (Suc (ra_idx_zero b)) * (b ∙ b)) *⇩R c (ra_inc ra_idx_zero b)
+ (∑x∈Basis - {b}.
(real (Suc (ra_idx_zero x)) * (b ∙ x)) *⇩R c (ra_inc ra_idx_zero x))"
using b
by (simp add: ra_dcoeff_def sum.remove[OF finite_Basis b])
also have "… = c (ra_inc ra_idx_zero b)"
using b rest0 by (simp add: ra_idx_zero_def inner_Basis)
also have "… = c e"
by (simp add: inc_b)
finally show ?thesis
by (simp add: e_def)
qed
lemma ra_dcoeff_idx_zero_eq_frechet_derivative:
fixes f :: "'a::euclidean_space ⇒ 'b::banach"
and c :: "('a ⇒ nat) ⇒ 'b"
assumes r: "0 < r"
and series:
"⋀y. dist y x0 < r ⟹
((λα. ra_monomial (y - x0) α *⇩R c α) has_sum f y) ra_idx"
shows "ra_dcoeff c v ra_idx_zero = frechet_derivative f (at x0) v"
proof -
have hs: "((λα. ra_monomial (0::'a) α *⇩R ra_dcoeff c v α)
has_sum frechet_derivative f (at x0) v) ra_idx"
using ra_directional_derivative_series[OF r series, of x0 v] r
by simp
show ?thesis
by (rule ra_series_at_zero_coeff[OF hs])
qed
lemma ra_linear_coeff_eq_frechet_derivative_basis:
fixes f :: "'a::euclidean_space ⇒ 'b::banach"
and c :: "('a ⇒ nat) ⇒ 'b"
assumes b: "b ∈ Basis"
and r: "0 < r"
and series:
"⋀y. dist y x0 < r ⟹
((λα. ra_monomial (y - x0) α *⇩R c α) has_sum f y) ra_idx"
shows "c (λx. if x = b then 1 else 0) = frechet_derivative f (at x0) b"
using ra_dcoeff_idx_zero_eq_frechet_derivative[OF r series, of b]
ra_dcoeff_idx_zero_basis[OF b, of c]
by simp
lemma infsum_split_off:
fixes f :: "('a::euclidean_space ⇒ nat) ⇒ real"
assumes sf: "f summable_on ra_idx" and aA: "a ∈ ra_idx"
shows "(∑⇩∞α∈ra_idx. f α) = f a + (∑⇩∞α∈(ra_idx - {a}). f α)"
proof -
have nin: "a ∉ ra_idx - {a}" by simp
have sub: "f summable_on (ra_idx - {a})"
by (rule summable_on_subset_banach[OF sf]) auto
have ins: "insert a (ra_idx - {a}) = ra_idx" using aA by blast
have "(∑⇩∞α∈insert a (ra_idx - {a}). f α)
= f a + (∑⇩∞α∈(ra_idx - {a}). f α)"
by (rule infsum_insert[OF sub nin])
thus ?thesis by (simp only: ins)
qed
text ‹The geometric tail (all nonzero indices) is linearly small in the ratio.›
lemma geom_idx_tail_small:
fixes q q0 :: real
assumes q0: "0 ≤ q" and qq0: "q ≤ q0" and q0pos: "0 < q0" and q01: "q0 < 1"
shows "(∑⇩∞α∈(ra_idx::('a::euclidean_space⇒nat) set). q ^ ra_deg α) - 1
≤ (q / q0) * (∑⇩∞α∈(ra_idx::('a⇒nat) set). q0 ^ ra_deg α)"
proof -
have q0nn: "0 ≤ q0" using q0pos by simp
have sq: "(λα::'a⇒nat. q ^ ra_deg α) summable_on ra_idx"
by (rule geom_idx_summable[OF q0 _]) (use qq0 q01 in linarith)
have sq0: "(λα::'a⇒nat. q0 ^ ra_deg α) summable_on ra_idx"
by (rule geom_idx_summable[OF q0nn q01])
have czin: "(ra_idx_zero::'a⇒nat) ∈ ra_idx"
by (rule ra_idx_zero_in)
have srest_q': "(λα::'a⇒nat. q ^ ra_deg α) summable_on (ra_idx - {ra_idx_zero})"
by (rule summable_on_subset_banach[OF sq]) auto
have rest_eq:
"(∑⇩∞α∈(ra_idx::('a⇒nat) set). q ^ ra_deg α)
= q ^ ra_deg (ra_idx_zero::'a⇒nat)
+ (∑⇩∞α∈((ra_idx::('a⇒nat) set) - {(ra_idx_zero::'a⇒nat)}). q ^ ra_deg α)"
by (rule infsum_split_off[OF sq czin])
have ztermq: "q ^ ra_deg (ra_idx_zero::'a⇒nat) = 1"
by (simp add: ra_deg_def ra_idx_zero_def)
have srest_q:
"(λα::'a⇒nat. q ^ ra_deg α)
summable_on ((ra_idx::('a⇒nat) set) - {(ra_idx_zero::'a⇒nat)})"
by (rule summable_on_subset_banach[OF sq]) auto
have srest_q0:
"(λα::'a⇒nat. q0 ^ ra_deg α)
summable_on ((ra_idx::('a⇒nat) set) - {(ra_idx_zero::'a⇒nat)})"
by (rule summable_on_subset_banach[OF sq0]) auto
have srest_q0scaled:
"(λα::'a⇒nat. (q / q0) * q0 ^ ra_deg α)
summable_on ((ra_idx::('a⇒nat) set) - {(ra_idx_zero::'a⇒nat)})"
by (rule summable_on_cmult_right[OF srest_q0])
have ptw:
"q ^ ra_deg α ≤ (q / q0) * q0 ^ ra_deg α"
if a: "α ∈ ((ra_idx::('a⇒nat) set) - {(ra_idx_zero::'a⇒nat)})"
for α :: "'a⇒nat"
proof -
have ar: "α ∈ ra_idx" and anz: "α ≠ ra_idx_zero"
using a by auto
have deg1: "1 ≤ ra_deg α"
using ra_deg_eq0_iff[OF ar] anz
by (cases "ra_deg α") auto
have "q ^ ra_deg α = (q / q0) ^ ra_deg α * q0 ^ ra_deg α"
using q0pos by (simp add: power_divide)
also have "… ≤ (q / q0) ^ 1 * q0 ^ ra_deg α"
proof (rule mult_right_mono)
have rn: "0 ≤ q / q0"
using q0 q0pos by simp
have r1: "q / q0 ≤ 1"
using qq0 q0pos by (simp add: divide_le_eq)
show "(q / q0) ^ ra_deg α ≤ (q / q0) ^ 1"
by (rule power_decreasing[OF deg1 rn r1])
show "0 ≤ q0 ^ ra_deg α"
using q0nn by simp
qed
finally show ?thesis by simp
qed
have rest_q_le_scaled_rest_q0:
"(∑⇩∞α∈((ra_idx::('a⇒nat) set) - {(ra_idx_zero::'a⇒nat)}). q ^ ra_deg α)
≤ (q / q0) *
(∑⇩∞α∈((ra_idx::('a⇒nat) set) - {(ra_idx_zero::'a⇒nat)}). q0 ^ ra_deg α)"
proof -
have "(∑⇩∞α∈((ra_idx::('a⇒nat) set) - {(ra_idx_zero::'a⇒nat)}). q ^ ra_deg α)
≤ (∑⇩∞α∈((ra_idx::('a⇒nat) set) - {(ra_idx_zero::'a⇒nat)}).
(q / q0) * q0 ^ ra_deg α)"
by (rule infsum_mono[OF srest_q srest_q0scaled]) (use ptw in auto)
also have "… =
(q / q0) *
(∑⇩∞α∈((ra_idx::('a⇒nat) set) - {(ra_idx_zero::'a⇒nat)}). q0 ^ ra_deg α)"
by (rule infsum_cmult_right[OF srest_q0])
finally show ?thesis .
qed
have rest_q0_le_all:
"(∑⇩∞α∈((ra_idx::('a⇒nat) set) - {(ra_idx_zero::'a⇒nat)}). q0 ^ ra_deg α)
≤ (∑⇩∞α∈(ra_idx::('a⇒nat) set). q0 ^ ra_deg α)"
proof -
have rest_eq0:
"(∑⇩∞α∈(ra_idx::('a⇒nat) set). q0 ^ ra_deg α)
= q0 ^ ra_deg (ra_idx_zero::'a⇒nat)
+ (∑⇩∞α∈((ra_idx::('a⇒nat) set) - {(ra_idx_zero::'a⇒nat)}). q0 ^ ra_deg α)"
by (rule infsum_split_off[OF sq0 czin])
have ztermq0: "q0 ^ ra_deg (ra_idx_zero::'a⇒nat) = 1"
by (simp add: ra_deg_def ra_idx_zero_def)
show ?thesis
using rest_eq0 ztermq0 by linarith
qed
have key:
"(∑⇩∞α∈((ra_idx::('a⇒nat) set) - {(ra_idx_zero::'a⇒nat)}). q ^ ra_deg α)
≤ (q / q0) * (∑⇩∞α∈(ra_idx::('a⇒nat) set). q0 ^ ra_deg α)"
proof -
have "(∑⇩∞α∈((ra_idx::('a⇒nat) set) - {(ra_idx_zero::'a⇒nat)}). q ^ ra_deg α)
≤ (q / q0) *
(∑⇩∞α∈((ra_idx::('a⇒nat) set) - {(ra_idx_zero::'a⇒nat)}). q0 ^ ra_deg α)"
by (rule rest_q_le_scaled_rest_q0)
also have "… ≤ (q / q0) *
(∑⇩∞α∈(ra_idx::('a⇒nat) set). q0 ^ ra_deg α)"
by (rule mult_left_mono[OF rest_q0_le_all]) (use q0 q0pos in simp)
finally show ?thesis .
qed
have "(∑⇩∞α∈(ra_idx::('a⇒nat) set). q ^ ra_deg α) - 1
= (∑⇩∞α∈((ra_idx::('a⇒nat) set) - {(ra_idx_zero::'a⇒nat)}). q ^ ra_deg α)"
using rest_eq ztermq by linarith
also note key
finally show ?thesis .
qed
subsection ‹Step (c): dominated Fubini sum of series families›
text ‹Monomial absolute bound by the majorant parameter on the working ball.›
lemma ra_monomial_abs_le_pow:
fixes h :: "'a::euclidean_space" and σ :: real
assumes a: "γ ∈ ra_idx" and hle: "norm h ≤ σ"
shows "¦ra_monomial h γ¦ ≤ σ ^ ra_deg γ"
proof -
have "¦ra_monomial h γ¦ ≤ norm h ^ ra_deg γ"
by (rule ra_monomial_norm_le[OF a])
also have "… ≤ σ ^ ra_deg γ"
by (rule power_mono[OF hle]) simp
finally show ?thesis .
qed
text ‹A majorant-dominated infinite sum of @{const ra_series_on} families is again such a
family, with coefficients ‹λγ. ∑⇩β a β * CC β γ›; ‹G› is the value of the sum.›
lemma ra_series_on_majdom:
fixes CC :: "('b::euclidean_space ⇒ nat) ⇒ ('a::euclidean_space ⇒ nat) ⇒ real"
and Fn :: "('b ⇒ nat) ⇒ 'a ⇒ real"
and a :: "('b ⇒ nat) ⇒ real"
and Kk :: "('b ⇒ nat) ⇒ real"
assumes s0: "0 < σ" and rσ: "r ≤ σ"
and ser: "⋀β. β ∈ ra_idx ⟹ ra_series_on x0 r (CC β) (Fn β)"
and maj: "⋀β. β ∈ ra_idx ⟹ ra_majorized σ (CC β) (Kk β)"
and gsum: "(λβ. ¦a β¦ * Kk β) summable_on (ra_idx::('b⇒nat) set)"
and Gval: "⋀x. dist x x0 < r ⟹ ((λβ. a β *⇩R Fn β x) has_sum G x) (ra_idx::('b⇒nat) set)"
shows "ra_series_on x0 r (λγ. ∑⇩∞β∈(ra_idx::('b⇒nat) set). a β * CC β γ) G"
unfolding ra_series_on_def
proof (intro allI impI)
fix x :: 'a assume d: "dist x x0 < r"
define h where "h = x - x0"
have hle: "norm h ≤ σ"
proof -
have "norm h < r" using d by (simp add: h_def dist_norm)
thus ?thesis using rσ by simp
qed
define D where "D = (λ(β,γ). ra_monomial h γ * (a β * CC β γ))"
have serβ: "((λγ. ra_monomial h γ * CC β γ) has_sum Fn β x) (ra_idx::('a⇒nat) set)"
if b: "β ∈ ra_idx" for β
using ser[OF b] d unfolding ra_series_on_def h_def by simp
have majβsum: "ra_weighted_abs σ (CC β) summable_on (ra_idx::('a⇒nat) set)"
if b: "β ∈ ra_idx" for β
using maj[OF b] by (simp add: ra_majorized_def)
have majβle: "(∑⇩∞γ∈(ra_idx::('a⇒nat) set). ra_weighted_abs σ (CC β) γ) ≤ Kk β"
if b: "β ∈ ra_idx" for β
using maj[OF b] by (simp add: ra_majorized_def)
have Dbound: "¦D (β,γ)¦ ≤ ¦a β¦ * ra_weighted_abs σ (CC β) γ"
if b: "β ∈ ra_idx" and g: "γ ∈ ra_idx" for β γ
proof -
have "¦D (β,γ)¦ = ¦ra_monomial h γ¦ * (¦a β¦ * ¦CC β γ¦)"
by (simp add: D_def abs_mult)
also have "… ≤ (σ ^ ra_deg γ) * (¦a β¦ * ¦CC β γ¦)"
by (rule mult_right_mono[OF ra_monomial_abs_le_pow[OF g hle]]) simp
also have "… = ¦a β¦ * (¦CC β γ¦ * σ ^ ra_deg γ)"
by (simp add: mult.assoc mult.left_commute)
also have "… = ¦a β¦ * ra_weighted_abs σ (CC β) γ" by (simp add: ra_weighted_abs_def)
finally show ?thesis .
qed
have inner_abs: "(λγ. norm (D (β,γ))) summable_on (ra_idx::('a⇒nat) set)"
if b: "β ∈ ra_idx" for β
proof (rule summable_on_comparison_test[where f = "λγ. ¦a β¦ * ra_weighted_abs σ (CC β) γ"])
show "(λγ. ¦a β¦ * ra_weighted_abs σ (CC β) γ) summable_on (ra_idx::('a⇒nat) set)"
by (rule summable_on_cmult_right[OF majβsum[OF b]])
next
fix γ :: "'a⇒nat" assume g: "γ ∈ ra_idx"
have "norm (D (β,γ)) = ¦D (β,γ)¦" by simp
also have "… ≤ ¦a β¦ * ra_weighted_abs σ (CC β) γ" by (rule Dbound[OF b g])
finally show "norm (D (β,γ)) ≤ ¦a β¦ * ra_weighted_abs σ (CC β) γ" .
next
fix γ :: "'a⇒nat" assume "γ ∈ ra_idx"
show "0 ≤ norm (D (β,γ))" by simp
qed
have inner_tot_le: "(∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ))) ≤ ¦a β¦ * Kk β"
if b: "β ∈ ra_idx" for β
proof -
have "(∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ)))
≤ (∑⇩∞γ∈(ra_idx::('a⇒nat) set). ¦a β¦ * ra_weighted_abs σ (CC β) γ)"
proof (rule infsum_mono)
show "(λγ. norm (D (β,γ))) summable_on (ra_idx::('a⇒nat) set)"
by (rule inner_abs[OF b])
show "(λγ. ¦a β¦ * ra_weighted_abs σ (CC β) γ) summable_on (ra_idx::('a⇒nat) set)"
by (rule summable_on_cmult_right[OF majβsum[OF b]])
fix γ :: "'a⇒nat" assume g: "γ ∈ ra_idx"
have "norm (D (β,γ)) = ¦D (β,γ)¦" by simp
thus "norm (D (β,γ)) ≤ ¦a β¦ * ra_weighted_abs σ (CC β) γ"
using Dbound[OF b g] by simp
qed
also have "… = ¦a β¦ * (∑⇩∞γ∈(ra_idx::('a⇒nat) set). ra_weighted_abs σ (CC β) γ)"
by (rule infsum_cmult_right[OF majβsum[OF b]])
also have "… ≤ ¦a β¦ * Kk β"
by (rule mult_left_mono[OF majβle[OF b]]) simp
finally show ?thesis .
qed
have outer_abs: "(λβ. ∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ)))
summable_on (ra_idx::('b⇒nat) set)"
proof (rule summable_on_comparison_test[where f = "λβ. ¦a β¦ * Kk β"])
show "(λβ. ¦a β¦ * Kk β) summable_on (ra_idx::('b⇒nat) set)" by (rule gsum)
next
fix β :: "'b⇒nat" assume b: "β ∈ ra_idx"
show "(∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ))) ≤ ¦a β¦ * Kk β"
by (rule inner_tot_le[OF b])
next
fix β :: "'b⇒nat" assume "β ∈ ra_idx"
show "0 ≤ (∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ)))"
by (rule infsum_nonneg) simp
qed
have outer_abs': "(λβ. norm (∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ))))
summable_on (ra_idx::('b⇒nat) set)"
proof -
have eq: "(λβ. norm (∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ))))
= (λβ. ∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ)))"
proof (rule ext)
fix β :: "'b⇒nat"
have "0 ≤ (∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ)))"
by (rule infsum_nonneg) simp
thus "norm (∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ)))
= (∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ)))" by simp
qed
show ?thesis using outer_abs by (simp only: eq)
qed
have conj1: "∀β∈(ra_idx::('b⇒nat) set). (λγ. norm (D (β,γ))) summable_on (ra_idx::('a⇒nat) set)"
using inner_abs by blast
have conj2: "(λβ. norm (∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ))))
summable_on (ra_idx::('b⇒nat) set)"
by (rule outer_abs')
have Dabs: "(λz. norm (D z)) summable_on (Sigma (ra_idx::('b⇒nat) set) (λ_. ra_idx::('a⇒nat) set))"
by (rule Infinite_Sum.abs_summable_on_Sigma_iff
[where f = D and A = "ra_idx::('b⇒nat) set" and B = "λ_. ra_idx::('a⇒nat) set",
THEN iffD2, OF conjI[OF conj1 conj2]])
have Dsumm: "D summable_on (Sigma (ra_idx::('b⇒nat) set) (λ_. ra_idx::('a⇒nat) set))"
by (rule abs_summable_summable[OF Dabs])
have GhsB: "((λβ. a β *⇩R Fn β x) has_sum G x) (ra_idx::('b⇒nat) set)"
by (rule Gval[OF d])
have innerB: "((λγ. D (β,γ)) has_sum (a β *⇩R Fn β x)) (ra_idx::('a⇒nat) set)"
if b: "β ∈ ra_idx" for β
proof -
have "((λγ. a β * (ra_monomial h γ * CC β γ)) has_sum (a β * Fn β x))
(ra_idx::('a⇒nat) set)"
by (rule has_sum_cmult_right[OF serβ[OF b]])
thus ?thesis
by (simp add: D_def mult.assoc mult.left_commute)
qed
have DhsG: "(D has_sum G x) (Sigma (ra_idx::('b⇒nat) set) (λ_. ra_idx::('a⇒nat) set))"
proof (rule has_sum_SigmaI[where g = "λβ. a β *⇩R Fn β x"])
fix β :: "'b⇒nat" assume b: "β ∈ ra_idx"
show "((λγ. D (β,γ)) has_sum (a β *⇩R Fn β x)) (ra_idx::('a⇒nat) set)"
by (rule innerB[OF b])
next
show "((λβ. a β *⇩R Fn β x) has_sum G x) (ra_idx::('b⇒nat) set)" by (rule GhsB)
next
show "D summable_on (Sigma (ra_idx::('b⇒nat) set) (λ_. ra_idx::('a⇒nat) set))"
by (rule Dsumm)
qed
have Dswap: "((λ(γ,β). D (β,γ)) has_sum G x)
((ra_idx::('a⇒nat) set) × (ra_idx::('b⇒nat) set))"
proof -
have e1: "Sigma (ra_idx::('b⇒nat) set) (λ_. ra_idx::('a⇒nat) set)
= (ra_idx::('b⇒nat) set) × (ra_idx::('a⇒nat) set)"
by simp
have "(D has_sum G x) ((ra_idx::('b⇒nat) set) × (ra_idx::('a⇒nat) set))"
using DhsG e1 by simp
thus ?thesis by (subst has_sum_swap) simp
qed
have Dswap_summ: "(λ(γ,β). D (β,γ)) summable_on
(Sigma (ra_idx::('a⇒nat) set) (λ_. ra_idx::('b⇒nat) set))"
using Dswap has_sum_imp_summable by (simp add: Sigma_def)
have slice_summ: "(λβ. D (β,γ)) summable_on (ra_idx::('b⇒nat) set)"
if g: "γ ∈ ra_idx" for γ
proof -
have "(λβ. (λ(γ,β). D (β,γ)) (γ,β)) summable_on (ra_idx::('b⇒nat) set)"
by (rule summable_on_SigmaD1[OF _ g]) (use Dswap_summ in ‹simp add: case_prod_unfold›)
thus ?thesis by simp
qed
define Cc where "Cc = (λγ. ∑⇩∞β∈(ra_idx::('b⇒nat) set). a β * CC β γ)"
have innerγ: "((λβ. D (β,γ)) has_sum (ra_monomial h γ *⇩R Cc γ)) (ra_idx::('b⇒nat) set)"
if g: "γ ∈ ra_idx" for γ
proof -
have summabs: "(λβ. norm (a β * CC β γ)) summable_on (ra_idx::('b⇒nat) set)"
proof (rule summable_on_comparison_test
[where f = "λβ. (1 / σ ^ ra_deg γ) * (¦a β¦ * Kk β)"])
show "(λβ. (1 / σ ^ ra_deg γ) * (¦a β¦ * Kk β)) summable_on (ra_idx::('b⇒nat) set)"
by (rule summable_on_cmult_right[OF gsum])
next
fix β :: "'b⇒nat" assume "β ∈ ra_idx"
show "0 ≤ norm (a β * CC β γ)" by simp
next
fix β :: "'b⇒nat" assume b: "β ∈ ra_idx"
have sp: "0 < σ ^ ra_deg γ" using s0 by simp
have one_term: "¦CC β γ¦ * σ ^ ra_deg γ ≤ Kk β"
proof -
have "¦CC β γ¦ * σ ^ ra_deg γ = ra_weighted_abs σ (CC β) γ" by (simp add: ra_weighted_abs_def)
also have "… = (∑γ'∈{γ}. ra_weighted_abs σ (CC β) γ')" by simp
also have "… ≤ (∑⇩∞γ'∈(ra_idx::('a⇒nat) set). ra_weighted_abs σ (CC β) γ')"
proof (rule finite_sum_le_infsum)
show "ra_weighted_abs σ (CC β) summable_on (ra_idx::('a⇒nat) set)" by (rule majβsum[OF b])
show "finite {γ}" by simp
show "{γ} ⊆ ra_idx" using g by simp
fix γ' :: "'a⇒nat" assume "γ' ∈ ra_idx - {γ}"
show "0 ≤ ra_weighted_abs σ (CC β) γ'" using s0 by (simp add: ra_weighted_abs_nonneg)
qed
also have "… ≤ Kk β" by (rule majβle[OF b])
finally show ?thesis .
qed
have ccle: "¦CC β γ¦ ≤ Kk β / σ ^ ra_deg γ"
using one_term sp by (simp add: mult.commute pos_le_divide_eq)
have "norm (a β * CC β γ) = ¦a β¦ * ¦CC β γ¦" by (simp add: abs_mult)
also have "… ≤ ¦a β¦ * (Kk β / σ ^ ra_deg γ)"
by (rule mult_left_mono[OF ccle]) simp
also have "… = (1 / σ ^ ra_deg γ) * (¦a β¦ * Kk β)" by simp
finally show "norm (a β * CC β γ) ≤ (1 / σ ^ ra_deg γ) * (¦a β¦ * Kk β)" .
qed
have summ: "(λβ. a β * CC β γ) summable_on (ra_idx::('b⇒nat) set)"
by (rule abs_summable_summable[OF summabs])
have base: "((λβ. a β * CC β γ) has_sum Cc γ) (ra_idx::('b⇒nat) set)"
using summ unfolding Cc_def by (rule has_sum_infsum)
have "((λβ. ra_monomial h γ * (a β * CC β γ)) has_sum (ra_monomial h γ * Cc γ))
(ra_idx::('b⇒nat) set)"
by (rule has_sum_cmult_right[OF base])
thus ?thesis by (simp add: D_def)
qed
have "((λγ. ra_monomial h γ *⇩R Cc γ) has_sum G x) (ra_idx::('a⇒nat) set)"
proof (rule has_sum_SigmaD[where f = "λ(γ,β). D (β,γ)"
and B = "λ_. ra_idx::('b⇒nat) set"])
show "((λ(γ,β). D (β,γ)) has_sum G x)
(Sigma (ra_idx::('a⇒nat) set) (λ_. ra_idx::('b⇒nat) set))"
using Dswap by (simp add: Sigma_def)
next
fix γ :: "'a⇒nat" assume g: "γ ∈ ra_idx"
show "((λβ. (λ(γ,β). D (β,γ)) (γ,β)) has_sum (ra_monomial h γ *⇩R Cc γ))
(ra_idx::('b⇒nat) set)"
using innerγ[OF g] by simp
qed
thus "((λγ. ra_monomial (x - x0) γ *⇩R (∑⇩∞β∈(ra_idx::('b⇒nat) set). a β * CC β γ))
has_sum G x) (ra_idx::('a⇒nat) set)"
by (simp add: h_def Cc_def)
qed
text ‹Vector outer-coefficient version of the dominated Fubini sum.›
lemma ra_series_on_majdom_vec:
fixes CC :: "('b::euclidean_space ⇒ nat) ⇒ ('a::euclidean_space ⇒ nat) ⇒ real"
and Fn :: "('b ⇒ nat) ⇒ 'a ⇒ real"
and vg :: "('b ⇒ nat) ⇒ 'c::banach"
and Kk :: "('b ⇒ nat) ⇒ real"
assumes s0: "0 < σ" and rσ: "r ≤ σ"
and ser: "⋀β. β ∈ ra_idx ⟹ ra_series_on x0 r (CC β) (Fn β)"
and maj: "⋀β. β ∈ ra_idx ⟹ ra_majorized σ (CC β) (Kk β)"
and gsum: "(λβ. norm (vg β) * Kk β) summable_on (ra_idx::('b⇒nat) set)"
and Gval: "⋀x. dist x x0 < r ⟹
((λβ. Fn β x *⇩R vg β) has_sum G x) (ra_idx::('b⇒nat) set)"
shows "∀x. dist x x0 < r ⟶
((λγ. ra_monomial (x - x0) γ *⇩R (∑⇩∞β∈(ra_idx::('b⇒nat) set). CC β γ *⇩R vg β))
has_sum G x) (ra_idx::('a⇒nat) set)"
proof (intro allI impI)
fix x :: 'a assume d: "dist x x0 < r"
define h where "h = x - x0"
have hle: "norm h ≤ σ"
proof -
have "norm h < r" using d by (simp add: h_def dist_norm)
thus ?thesis using rσ by simp
qed
define D where "D = (λ(β,γ). ra_monomial h γ *⇩R (CC β γ *⇩R vg β))"
have serβ: "((λγ. ra_monomial h γ * CC β γ) has_sum Fn β x) (ra_idx::('a⇒nat) set)"
if b: "β ∈ ra_idx" for β
using ser[OF b] d unfolding ra_series_on_def h_def by simp
have majβsum: "ra_weighted_abs σ (CC β) summable_on (ra_idx::('a⇒nat) set)"
if b: "β ∈ ra_idx" for β
using maj[OF b] by (simp add: ra_majorized_def)
have majβle: "(∑⇩∞γ∈(ra_idx::('a⇒nat) set). ra_weighted_abs σ (CC β) γ) ≤ Kk β"
if b: "β ∈ ra_idx" for β
using maj[OF b] by (simp add: ra_majorized_def)
have Dbound: "norm (D (β,γ)) ≤ norm (vg β) * ra_weighted_abs σ (CC β) γ"
if b: "β ∈ ra_idx" and g: "γ ∈ ra_idx" for β γ
proof -
have "norm (D (β,γ)) = ¦ra_monomial h γ¦ * (¦CC β γ¦ * norm (vg β))"
by (simp add: D_def abs_mult)
also have "… ≤ (σ ^ ra_deg γ) * (¦CC β γ¦ * norm (vg β))"
by (rule mult_right_mono[OF ra_monomial_abs_le_pow[OF g hle]]) simp
also have "… = norm (vg β) * (¦CC β γ¦ * σ ^ ra_deg γ)"
by (simp add: mult.assoc mult.left_commute)
also have "… = norm (vg β) * ra_weighted_abs σ (CC β) γ" by (simp add: ra_weighted_abs_def)
finally show ?thesis .
qed
have inner_abs: "(λγ. norm (D (β,γ))) summable_on (ra_idx::('a⇒nat) set)"
if b: "β ∈ ra_idx" for β
proof (rule summable_on_comparison_test[where f = "λγ. norm (vg β) * ra_weighted_abs σ (CC β) γ"])
show "(λγ. norm (vg β) * ra_weighted_abs σ (CC β) γ) summable_on (ra_idx::('a⇒nat) set)"
by (rule summable_on_cmult_right[OF majβsum[OF b]])
next
fix γ :: "'a⇒nat" assume g: "γ ∈ ra_idx"
show "norm (D (β,γ)) ≤ norm (vg β) * ra_weighted_abs σ (CC β) γ" by (rule Dbound[OF b g])
next
fix γ :: "'a⇒nat" assume "γ ∈ ra_idx"
show "0 ≤ norm (D (β,γ))" by simp
qed
have inner_tot_le: "(∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ))) ≤ norm (vg β) * Kk β"
if b: "β ∈ ra_idx" for β
proof -
have "(∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ)))
≤ (∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (vg β) * ra_weighted_abs σ (CC β) γ)"
proof (rule infsum_mono)
show "(λγ. norm (D (β,γ))) summable_on (ra_idx::('a⇒nat) set)"
by (rule inner_abs[OF b])
show "(λγ. norm (vg β) * ra_weighted_abs σ (CC β) γ) summable_on (ra_idx::('a⇒nat) set)"
by (rule summable_on_cmult_right[OF majβsum[OF b]])
fix γ :: "'a⇒nat" assume g: "γ ∈ ra_idx"
show "norm (D (β,γ)) ≤ norm (vg β) * ra_weighted_abs σ (CC β) γ" by (rule Dbound[OF b g])
qed
also have "… = norm (vg β) * (∑⇩∞γ∈(ra_idx::('a⇒nat) set). ra_weighted_abs σ (CC β) γ)"
by (rule infsum_cmult_right[OF majβsum[OF b]])
also have "… ≤ norm (vg β) * Kk β"
by (rule mult_left_mono[OF majβle[OF b]]) simp
finally show ?thesis .
qed
have outer_abs: "(λβ. ∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ)))
summable_on (ra_idx::('b⇒nat) set)"
proof (rule summable_on_comparison_test[where f = "λβ. norm (vg β) * Kk β"])
show "(λβ. norm (vg β) * Kk β) summable_on (ra_idx::('b⇒nat) set)" by (rule gsum)
next
fix β :: "'b⇒nat" assume b: "β ∈ ra_idx"
show "(∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ))) ≤ norm (vg β) * Kk β"
by (rule inner_tot_le[OF b])
next
fix β :: "'b⇒nat" assume "β ∈ ra_idx"
show "0 ≤ (∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ)))"
by (rule infsum_nonneg) simp
qed
have outer_abs': "(λβ. norm (∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ))))
summable_on (ra_idx::('b⇒nat) set)"
proof -
have eq: "(λβ. norm (∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ))))
= (λβ. ∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ)))"
proof (rule ext)
fix β :: "'b⇒nat"
have "0 ≤ (∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ)))"
by (rule infsum_nonneg) simp
thus "norm (∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ)))
= (∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ)))" by simp
qed
show ?thesis using outer_abs by (simp only: eq)
qed
have conj1: "∀β∈(ra_idx::('b⇒nat) set). (λγ. norm (D (β,γ))) summable_on (ra_idx::('a⇒nat) set)"
using inner_abs by blast
have conj2: "(λβ. norm (∑⇩∞γ∈(ra_idx::('a⇒nat) set). norm (D (β,γ))))
summable_on (ra_idx::('b⇒nat) set)"
by (rule outer_abs')
have Dabs: "(λz. norm (D z)) summable_on (Sigma (ra_idx::('b⇒nat) set) (λ_. ra_idx::('a⇒nat) set))"
by (rule Infinite_Sum.abs_summable_on_Sigma_iff
[where f = D and A = "ra_idx::('b⇒nat) set" and B = "λ_. ra_idx::('a⇒nat) set",
THEN iffD2, OF conjI[OF conj1 conj2]])
have Dsumm: "D summable_on (Sigma (ra_idx::('b⇒nat) set) (λ_. ra_idx::('a⇒nat) set))"
by (rule abs_summable_summable[OF Dabs])
have GhsB: "((λβ. Fn β x *⇩R vg β) has_sum G x) (ra_idx::('b⇒nat) set)"
by (rule Gval[OF d])
have innerB: "((λγ. D (β,γ)) has_sum (Fn β x *⇩R vg β)) (ra_idx::('a⇒nat) set)"
if b: "β ∈ ra_idx" for β
proof -
have "((λγ. (ra_monomial h γ * CC β γ) *⇩R vg β) has_sum (Fn β x *⇩R vg β))
(ra_idx::('a⇒nat) set)"
by (rule has_sum_bounded_linear[OF bounded_linear_scaleR_left serβ[OF b]])
thus ?thesis by (simp add: D_def)
qed
have DhsG: "(D has_sum G x) (Sigma (ra_idx::('b⇒nat) set) (λ_. ra_idx::('a⇒nat) set))"
proof (rule has_sum_SigmaI[where g = "λβ. Fn β x *⇩R vg β"])
fix β :: "'b⇒nat" assume b: "β ∈ ra_idx"
show "((λγ. D (β,γ)) has_sum (Fn β x *⇩R vg β)) (ra_idx::('a⇒nat) set)"
by (rule innerB[OF b])
next
show "((λβ. Fn β x *⇩R vg β) has_sum G x) (ra_idx::('b⇒nat) set)" by (rule GhsB)
next
show "D summable_on (Sigma (ra_idx::('b⇒nat) set) (λ_. ra_idx::('a⇒nat) set))"
by (rule Dsumm)
qed
have Dswap: "((λ(γ,β). D (β,γ)) has_sum G x)
((ra_idx::('a⇒nat) set) × (ra_idx::('b⇒nat) set))"
proof -
have e1: "Sigma (ra_idx::('b⇒nat) set) (λ_. ra_idx::('a⇒nat) set)
= (ra_idx::('b⇒nat) set) × (ra_idx::('a⇒nat) set)" by simp
have "(D has_sum G x) ((ra_idx::('b⇒nat) set) × (ra_idx::('a⇒nat) set))"
using DhsG e1 by simp
thus ?thesis by (subst has_sum_swap) simp
qed
have Dswap_summ: "(λ(γ,β). D (β,γ)) summable_on
(Sigma (ra_idx::('a⇒nat) set) (λ_. ra_idx::('b⇒nat) set))"
using Dswap has_sum_imp_summable by (simp add: Sigma_def)
define Cc where "Cc = (λγ. ∑⇩∞β∈(ra_idx::('b⇒nat) set). CC β γ *⇩R vg β)"
have innerγ: "((λβ. D (β,γ)) has_sum (ra_monomial h γ *⇩R Cc γ)) (ra_idx::('b⇒nat) set)"
if g: "γ ∈ ra_idx" for γ
proof -
have summabs: "(λβ. norm (CC β γ *⇩R vg β)) summable_on (ra_idx::('b⇒nat) set)"
proof (rule summable_on_comparison_test
[where f = "λβ. (1 / σ ^ ra_deg γ) * (norm (vg β) * Kk β)"])
show "(λβ. (1 / σ ^ ra_deg γ) * (norm (vg β) * Kk β)) summable_on (ra_idx::('b⇒nat) set)"
by (rule summable_on_cmult_right[OF gsum])
next
fix β :: "'b⇒nat" assume "β ∈ ra_idx"
show "0 ≤ norm (CC β γ *⇩R vg β)" by simp
next
fix β :: "'b⇒nat" assume b: "β ∈ ra_idx"
have sp: "0 < σ ^ ra_deg γ" using s0 by simp
have one_term: "¦CC β γ¦ * σ ^ ra_deg γ ≤ Kk β"
proof -
have "¦CC β γ¦ * σ ^ ra_deg γ = ra_weighted_abs σ (CC β) γ" by (simp add: ra_weighted_abs_def)
also have "… = (∑γ'∈{γ}. ra_weighted_abs σ (CC β) γ')" by simp
also have "… ≤ (∑⇩∞γ'∈(ra_idx::('a⇒nat) set). ra_weighted_abs σ (CC β) γ')"
proof (rule finite_sum_le_infsum)
show "ra_weighted_abs σ (CC β) summable_on (ra_idx::('a⇒nat) set)" by (rule majβsum[OF b])
show "finite {γ}" by simp
show "{γ} ⊆ ra_idx" using g by simp
fix γ' :: "'a⇒nat" assume "γ' ∈ ra_idx - {γ}"
show "0 ≤ ra_weighted_abs σ (CC β) γ'" using s0 by (simp add: ra_weighted_abs_nonneg)
qed
also have "… ≤ Kk β" by (rule majβle[OF b])
finally show ?thesis .
qed
have ccle: "¦CC β γ¦ ≤ Kk β / σ ^ ra_deg γ"
using one_term sp by (simp add: mult.commute pos_le_divide_eq)
have "norm (CC β γ *⇩R vg β) = ¦CC β γ¦ * norm (vg β)" by simp
also have "… ≤ (Kk β / σ ^ ra_deg γ) * norm (vg β)"
by (rule mult_right_mono[OF ccle]) simp
also have "… = (1 / σ ^ ra_deg γ) * (norm (vg β) * Kk β)" by simp
finally show "norm (CC β γ *⇩R vg β) ≤ (1 / σ ^ ra_deg γ) * (norm (vg β) * Kk β)" .
qed
have summ: "(λβ. CC β γ *⇩R vg β) summable_on (ra_idx::('b⇒nat) set)"
by (rule abs_summable_summable[OF summabs])
have base: "((λβ. CC β γ *⇩R vg β) has_sum Cc γ) (ra_idx::('b⇒nat) set)"
using summ unfolding Cc_def by (rule has_sum_infsum)
have "((λβ. ra_monomial h γ *⇩R (CC β γ *⇩R vg β)) has_sum (ra_monomial h γ *⇩R Cc γ))
(ra_idx::('b⇒nat) set)"
by (rule has_sum_scaleR[OF base])
thus ?thesis by (simp add: D_def)
qed
have "((λγ. ra_monomial h γ *⇩R Cc γ) has_sum G x) (ra_idx::('a⇒nat) set)"
proof (rule has_sum_SigmaD[where f = "λ(γ,β). D (β,γ)"
and B = "λ_. ra_idx::('b⇒nat) set"])
show "((λ(γ,β). D (β,γ)) has_sum G x)
(Sigma (ra_idx::('a⇒nat) set) (λ_. ra_idx::('b⇒nat) set))"
using Dswap by (simp add: Sigma_def)
next
fix γ :: "'a⇒nat" assume g: "γ ∈ ra_idx"
show "((λβ. (λ(γ,β). D (β,γ)) (γ,β)) has_sum (ra_monomial h γ *⇩R Cc γ))
(ra_idx::('b⇒nat) set)"
using innerγ[OF g] by simp
qed
thus "((λγ. ra_monomial (x - x0) γ *⇩R (∑⇩∞β∈(ra_idx::('b⇒nat) set). CC β γ *⇩R vg β))
has_sum G x) (ra_idx::('a⇒nat) set)"
by (simp add: h_def Cc_def)
qed
subsection ‹Final composition theorem›
text ‹A coefficient bound with vanishing zero-degree term gives a majorant bound whose
value is the geometric tail (which tends to 0 as ‹σ› shrinks).›
lemma ra_majorized_tail_bound:
fixes c :: "('b::euclidean_space⇒nat)⇒'d::real_normed_vector"
assumes Mnn: "0 ≤ M"
and c0: "c ra_idx_zero = 0"
and bound: "⋀α. α∈ra_idx ⟹ norm (c α) ≤ M / t ^ (ra_deg α)"
and t: "0 < t" and s0: "0 ≤ σ" and st: "σ < t"
shows "ra_majorized σ (λα. norm (c α))
(M * ((∑⇩∞α∈(ra_idx::('b⇒nat) set). (σ/t) ^ ra_deg α) - 1))"
proof -
define q where "q = σ/t"
have q0: "0 ≤ q" using s0 t by (simp add: q_def)
have q1: "q < 1" using st t by (simp add: q_def)
have geomS: "(λα::'b⇒nat. q ^ ra_deg α) summable_on ra_idx"
by (rule geom_idx_summable[OF q0 q1])
have geomMS: "(λα. M * q ^ ra_deg α) summable_on (ra_idx::('b⇒nat) set)"
by (rule summable_on_cmult_right[OF geomS])
have ptwise: "ra_weighted_abs σ (λα. norm (c α)) α ≤ M * q ^ ra_deg α" if a: "α∈ra_idx" for α
proof -
have "ra_weighted_abs σ (λα. norm (c α)) α = norm (c α) * σ ^ ra_deg α"
by (simp add: ra_weighted_abs_def)
also have "… ≤ (M / t ^ ra_deg α) * σ ^ ra_deg α"
by (rule mult_right_mono[OF bound[OF a]]) (use s0 in simp)
also have "… = M * q ^ ra_deg α" by (simp add: q_def power_divide)
finally show ?thesis .
qed
have nn: "0 ≤ ra_weighted_abs σ (λα. norm (c α)) α" for α using s0 by (rule ra_weighted_abs_nonneg)
have summ: "ra_weighted_abs σ (λα. norm (c α)) summable_on (ra_idx::('b⇒nat) set)"
by (rule summable_on_comparison_test[OF geomMS]) (use ptwise nn in auto)
have mfam0: "ra_weighted_abs σ (λα. norm (c α)) ra_idx_zero = 0"
by (simp add: ra_weighted_abs_def c0)
have czin: "(ra_idx_zero::'b⇒nat) ∈ ra_idx" by (rule ra_idx_zero_in)
have splitM: "(∑⇩∞α∈(ra_idx::('b⇒nat) set). ra_weighted_abs σ (λα. norm (c α)) α)
= (∑⇩∞α∈((ra_idx::('b⇒nat) set) - {ra_idx_zero}).
ra_weighted_abs σ (λα. norm (c α)) α)"
using infsum_split_off[OF summ czin] mfam0 by simp
have splitG: "(∑⇩∞α∈(ra_idx::('b⇒nat) set). M * q ^ ra_deg α)
= M * (q ^ ra_deg (ra_idx_zero::'b⇒nat))
+ (∑⇩∞α∈((ra_idx::('b⇒nat) set) - {ra_idx_zero}). M * q ^ ra_deg α)"
using infsum_split_off[OF geomMS czin] by simp
have geomMSrest: "(λα. M * q ^ ra_deg α) summable_on
((ra_idx::('b⇒nat) set) - {ra_idx_zero})"
by (rule summable_on_subset_banach[OF geomMS]) auto
have summrest: "ra_weighted_abs σ (λα. norm (c α)) summable_on
((ra_idx::('b⇒nat) set) - {ra_idx_zero})"
by (rule summable_on_subset_banach[OF summ]) auto
have tailbound:
"(∑⇩∞α∈((ra_idx::('b⇒nat) set) - {ra_idx_zero}). ra_weighted_abs σ (λα. norm (c α)) α)
≤ (∑⇩∞α∈((ra_idx::('b⇒nat) set) - {ra_idx_zero}). M * q ^ ra_deg α)"
by (rule infsum_mono[OF summrest geomMSrest]) (use ptwise in auto)
have geom_eq: "(∑⇩∞α∈(ra_idx::('b⇒nat) set). M * q ^ ra_deg α)
= M * (∑⇩∞α∈(ra_idx::('b⇒nat) set). q ^ ra_deg α)"
by (rule infsum_cmult_right[OF geomS])
have ztermq: "q ^ ra_deg (ra_idx_zero::'b⇒nat) = 1"
by (simp add: ra_deg_def ra_idx_zero_def)
have "(∑⇩∞α∈(ra_idx::('b⇒nat) set). ra_weighted_abs σ (λα. norm (c α)) α)
= (∑⇩∞α∈((ra_idx::('b⇒nat) set) - {ra_idx_zero}). ra_weighted_abs σ (λα. norm (c α)) α)"
by (rule splitM)
also have "… ≤ (∑⇩∞α∈((ra_idx::('b⇒nat) set) - {ra_idx_zero}). M * q ^ ra_deg α)"
by (rule tailbound)
also have "… = (∑⇩∞α∈(ra_idx::('b⇒nat) set). M * q ^ ra_deg α) - M * 1"
using splitG ztermq by simp
also have "… = M * ((∑⇩∞α∈(ra_idx::('b⇒nat) set). q ^ ra_deg α) - 1)"
using geom_eq by (simp add: algebra_simps)
finally show ?thesis using summ by (simp add: ra_majorized_def q_def)
qed
text ‹Scaling a real-analytic scalar function by a fixed vector stays analytic.›
lemma real_analytic_on_scaleR_vec:
fixes f :: "'a::euclidean_space ⇒ real" and v :: "'c::real_normed_vector"
assumes F: "real_analytic_on f U"
shows "real_analytic_on (λx. f x *⇩R v) U"
proof -
from F have U: "open U" by (simp only: real_analytic_on_def)
show ?thesis
unfolding real_analytic_on_def
proof (intro conjI ballI)
show "open U" by (rule U)
next
fix x0 assume x0: "x0 ∈ U"
from F x0 obtain r c where r: "0 < r"
and F1: "⋀x. dist x x0 < r ⟹
((λα. ra_monomial (x - x0) α *⇩R c α) has_sum f x) ra_idx"
unfolding real_analytic_on_def by blast
show "∃r>0. ∃cc. ∀x. dist x x0 < r ⟶
((λα. ra_monomial (x - x0) α *⇩R cc α) has_sum (f x *⇩R v)) ra_idx"
proof (intro exI[where x=r] conjI exI[where x="λα. c α *⇩R v"] allI impI)
show "0 < r" by (rule r)
next
fix x assume d: "dist x x0 < r"
have bl: "bounded_linear (λt::real. t *⇩R v)" by (rule bounded_linear_scaleR_left)
have "((λα. (ra_monomial (x - x0) α *⇩R c α) *⇩R v) has_sum (f x *⇩R v)) ra_idx"
by (rule has_sum_bounded_linear[OF bl F1[OF d]])
thus "((λα. ra_monomial (x - x0) α *⇩R (c α *⇩R v)) has_sum (f x *⇩R v)) ra_idx"
by simp
qed
qed
qed
text ‹Composition of real-analytic functions (target a Banach space).›
lemma real_analytic_on_compose:
fixes f :: "'a::euclidean_space ⇒ 'b::euclidean_space"
and g :: "'b ⇒ 'c::banach"
assumes F: "real_analytic_on f U" and G: "real_analytic_on g V" and FV: "f ` U ⊆ V"
shows "real_analytic_on (λx. g (f x)) U"
proof -
from F have U: "open U" by (simp only: real_analytic_on_def)
from G have Vopen: "open V" by (simp only: real_analytic_on_def)
show ?thesis
unfolding real_analytic_on_def
proof (intro conjI ballI)
show "open U" by (rule U)
next
fix x0 assume x0: "x0 ∈ U"
define y0 where "y0 = f x0"
have y0V: "y0 ∈ V" using FV x0 by (auto simp: y0_def)
from G y0V obtain ρg cg where ρg: "0 < ρg"
and Gser: "⋀y. dist y y0 < ρg ⟹
((λβ. ra_monomial (y - y0) β *⇩R cg β) has_sum g y) ra_idx"
unfolding real_analytic_on_def by blast
define eB where "eB = (∑b∈(Basis::'b set). b)"
have eBpos: "0 < norm eB"
proof -
have "eB ≠ 0"
proof
assume "eB = 0"
then have "eB ∙ (SOME b. b ∈ (Basis::'b set)) = 0" by simp
moreover obtain b0 :: 'b where b0: "b0 ∈ Basis" using nonempty_Basis by blast
have "(SOME b. b ∈ (Basis::'b set)) ∈ Basis" using b0 by (rule someI)
hence "eB ∙ (SOME b. b ∈ (Basis::'b set)) = 1"
by (simp add: eB_def inner_sum_left inner_Basis)
ultimately show False by simp
qed
thus ?thesis by simp
qed
define t where "t = ρg / (2 * norm eB)"
have t0: "0 < t" using ρg eBpos by (simp add: t_def)
have corner_g: "t * norm (∑b∈(Basis::'b set). b) < ρg"
proof -
have "t * norm eB = ρg / 2" using eBpos by (simp add: t_def)
also have "… < ρg" using ρg by simp
finally show ?thesis by (simp add: eB_def)
qed
obtain Mg where Mgnn: "Mg ≥ 0"
and cgbound: "⋀β. β ∈ ra_idx ⟹ norm (cg β) ≤ Mg / t ^ (ra_deg β)"
using ra_coeff_bound[OF ρg Gser t0 corner_g] by blast
have F': "real_analytic_on (λx. f x - y0) U"
by (rule real_analytic_on_diff[OF F real_analytic_on_const[OF U]])
from F' x0 obtain rf cf where rf: "0 < rf"
and Fser: "⋀x. dist x x0 < rf ⟹
((λα. ra_monomial (x - x0) α *⇩R cf α) has_sum (f x - y0)) ra_idx"
unfolding real_analytic_on_def by blast
define eA where "eA = (∑b∈(Basis::'a set). b)"
have eApos: "0 < norm eA"
proof -
have "eA ≠ 0"
proof
assume "eA = 0"
moreover obtain a0 :: 'a where a0: "a0 ∈ Basis" using nonempty_Basis by blast
have "(SOME b. b ∈ (Basis::'a set)) ∈ Basis" using a0 by (rule someI)
hence "eA ∙ (SOME b. b ∈ (Basis::'a set)) = 1"
by (simp add: eA_def inner_sum_left inner_Basis)
ultimately show False by simp
qed
thus ?thesis by simp
qed
define sf where "sf = rf / (2 * norm eA)"
have sf0: "0 < sf" using rf eApos by (simp add: sf_def)
have corner_f: "sf * norm (∑b∈(Basis::'a set). b) < rf"
proof -
have "sf * norm eA = rf / 2" using eApos by (simp add: sf_def)
also have "… < rf" using rf by simp
finally show ?thesis by (simp add: eA_def)
qed
obtain Mf where Mfnn: "Mf ≥ 0"
and cfbound: "⋀α. α ∈ ra_idx ⟹ norm (cf α) ≤ Mf / sf ^ (ra_deg α)"
using ra_coeff_bound[OF rf Fser sf0 corner_f] by blast
define geo where "geo = (λq::real. ∑⇩∞α∈(ra_idx::('a⇒nat) set). q ^ ra_deg α)"
have shifted_const0: "cf ra_idx_zero = 0"
proof -
have "((λα. ra_monomial (x0 - x0) α *⇩R cf α) has_sum (f x0 - y0)) ra_idx"
by (rule Fser) (simp add: rf)
then have hs: "((λα. ra_monomial (0::'a) α *⇩R cf α) has_sum (0::'b)) ra_idx"
by (simp add: y0_def)
have neutral: "ra_monomial (0::'a) α *⇩R cf α = 0"
if "α ∈ ra_idx - {ra_idx_zero}" for α
proof -
have "α ≠ ra_idx_zero" using that by simp
hence "ra_deg α ≠ 0" using ra_deg_eq0_iff that by auto
thus ?thesis by (simp add: ra_monomial_zero)
qed
have "((λα. ra_monomial (0::'a) α *⇩R cf α) has_sum (0::'b)) ra_idx
= ((λα. ra_monomial (0::'a) α *⇩R cf α) has_sum (0::'b)) {ra_idx_zero}"
by (rule has_sum_cong_neutral) (use neutral ra_idx_zero_in in auto)
with hs have "((λα. ra_monomial (0::'a) α *⇩R cf α) has_sum (0::'b)) {ra_idx_zero}" by simp
moreover have "((λα. ra_monomial (0::'a) α *⇩R cf α) has_sum (cf ra_idx_zero)) {ra_idx_zero}"
by (rule has_sum_finiteI) (auto simp: ra_monomial_zero ra_idx_zero_def ra_deg_def)
ultimately show ?thesis by (metis has_sum_unique)
qed
have contf: "continuous (at x0) f" by (rule real_analytic_on_imp_continuous_vec[OF F x0])
have tend: "(f ⤏ f x0) (at x0)" using contf by (simp add: continuous_at)
have evb: "∀⇩F x in at x0. f x ∈ ball (f x0) ρg"
by (rule topological_tendstoD[OF tend]) (use ρg in auto)
have "∀⇩F x in at x0. dist (f x) (f x0) < ρg"
using evb by (simp add: dist_commute)
then obtain δc where δc: "0 < δc"
and contball: "⋀x. dist x x0 < δc ⟹ x ≠ x0 ⟹ dist (f x) y0 < ρg"
using ρg by (auto simp: eventually_at y0_def dist_commute)
have contball': "dist (f x) y0 < ρg" if "dist x x0 < δc" for x
proof (cases "x = x0")
case True thus ?thesis using ρg by (simp add: y0_def)
next
case False thus ?thesis using contball[OF that] by simp
qed
define gh where "gh = (∑⇩∞α∈(ra_idx::('a⇒nat) set). (1/2::real) ^ ra_deg α)"
have ghnn: "0 ≤ gh" unfolding gh_def by (rule infsum_nonneg) simp
define C where "C = Mf * (2 / sf) * gh"
have Cnn: "0 ≤ C" using Mfnn sf0 ghnn by (simp add: C_def)
define th where "th = t / (C + 1)"
have th0: "0 < th" using t0 Cnn by (simp add: th_def)
define σ where "σ = (min (sf/2) (min δc (min rf th))) / 2"
have σ0: "0 < σ" using sf0 δc rf th0 by (simp add: σ_def)
have σsf2: "σ ≤ sf/2" using δc rf th0 sf0 by (simp add: σ_def)
have σsf: "σ < sf" using σsf2 sf0 by simp
have σδc: "σ ≤ δc" using sf0 rf th0 δc by (simp add: σ_def)
have σrf: "σ ≤ rf" using sf0 δc th0 rf by (simp add: σ_def)
have σth: "σ ≤ th" using sf0 δc rf th0 by (simp add: σ_def)
have qhalf: "σ/sf ≤ 1/2" using σsf2 sf0 by (simp add: divide_le_eq)
define Mc where "Mc = Mf * ((∑⇩∞α∈(ra_idx::('a⇒nat) set). (σ/sf) ^ ra_deg α) - 1)"
have σnn: "0 ≤ σ" using σ0 by simp
have cfmaj: "ra_majorized σ (λα. norm (cf α)) Mc"
unfolding Mc_def
by (rule ra_majorized_tail_bound[OF Mfnn shifted_const0 cfbound sf0 σnn σsf])
have Mcnn: "0 ≤ Mc"
using ra_majorized_imp_nonneg_sum[OF _ cfmaj] cfmaj σ0 by (simp add: ra_majorized_def)
have tail_small: "(∑⇩∞α∈(ra_idx::('a⇒nat) set). (σ/sf) ^ ra_deg α) - 1 ≤ (σ/sf)/(1/2) * gh"
unfolding gh_def
by (rule geom_idx_tail_small[OF _ qhalf]) (use σ0 sf0 in auto)
have Mc_le: "Mc ≤ C * σ"
proof -
have "Mc ≤ Mf * ((σ/sf)/(1/2) * gh)"
unfolding Mc_def by (rule mult_left_mono[OF tail_small Mfnn])
also have "… = C * σ" using sf0 by (simp add: C_def field_simps)
finally show ?thesis .
qed
have Mc_lt_t: "Mc < t"
proof -
have "C * σ ≤ C * th" using σth Cnn by (simp add: mult_left_mono)
also have "… = C * t / (C + 1)" by (simp add: th_def)
also have "… < t"
proof -
have "C * t / (C + 1) < t ⟷ C * t < t * (C + 1)"
using Cnn by (simp add: pos_divide_less_eq)
thus ?thesis using t0 Cnn by (simp add: field_simps)
qed
finally show ?thesis using Mc_le by linarith
qed
define Km where "Km = (Mc + t)/2"
have Km_ge: "Mc ≤ Km" using Mc_lt_t by (simp add: Km_def)
have Km_lt: "Km < t" using Mc_lt_t by (simp add: Km_def)
have Km_nn: "0 ≤ Km" using Mcnn Mc_lt_t by (simp add: Km_def)
have Fser': "((λα. ra_monomial (x - x0) α *⇩R cf α) has_sum (f x - y0)) ra_idx"
if "dist x x0 < σ" for x
using Fser[of x] that σrf by simp
have perbeta: "∃cc. ra_series_majorized x0 σ σ cc (λx. ra_monomial (f x - y0) β) (Km ^ ra_deg β)" for β
proof -
have "∃cc. ra_series_majorized x0 σ σ cc (λx. ra_monomial ((f x - y0) - 0) β) (Km ^ ra_deg β)"
proof (rule ra_series_majorized_ra_monomial_compose[where cf = cf and Mc = Mc])
show "0 ≤ σ" using σ0 by simp
show "⋀x. dist x x0 < σ ⟹
((λα. ra_monomial (x - x0) α *⇩R cf α) has_sum (f x - y0)) ra_idx"
by (rule Fser')
show "ra_majorized σ (λα. norm (cf α)) Mc" by (rule cfmaj)
show "⋀b. b ∈ Basis ⟹ Mc + ¦(0::'b) ∙ b¦ ≤ Km" using Km_ge by simp
show "0 ≤ Km" by (rule Km_nn)
qed
thus ?thesis by simp
qed
have "∃CC. ∀β. ra_series_majorized x0 σ σ (CC β) (λx. ra_monomial (f x - y0) β) (Km ^ ra_deg β)"
by (subst choice_iff[symmetric]) (use perbeta in blast)
then obtain CC where CCsmaj:
"⋀β. ra_series_majorized x0 σ σ (CC β) (λx. ra_monomial (f x - y0) β) (Km ^ ra_deg β)" by blast
have CCser: "⋀β. β ∈ ra_idx ⟹ ra_series_on x0 σ (CC β) (λx. ra_monomial (f x - y0) β)"
using CCsmaj by (simp add: ra_series_majorized_def)
have CCmaj: "⋀β. β ∈ ra_idx ⟹ ra_majorized σ (CC β) (Km ^ ra_deg β)"
using CCsmaj by (simp add: ra_series_majorized_def)
have gsum: "(λβ. norm (cg β) * Km ^ ra_deg β) summable_on (ra_idx::('b⇒nat) set)"
proof (rule summable_on_comparison_test
[where f = "λβ. Mg * (Km / t) ^ ra_deg β"])
have qlt: "Km / t < 1" using Km_lt t0 by (simp add: divide_less_eq)
have qnn: "0 ≤ Km / t" using Km_nn t0 by simp
have "(λβ::'b⇒nat. (Km / t) ^ ra_deg β) summable_on ra_idx"
by (rule geom_idx_summable[OF qnn qlt])
thus "(λβ. Mg * (Km / t) ^ ra_deg β) summable_on (ra_idx::('b⇒nat) set)"
by (rule summable_on_cmult_right)
next
fix β :: "'b⇒nat" assume b: "β ∈ ra_idx"
have "norm (cg β) * Km ^ ra_deg β ≤ (Mg / t ^ ra_deg β) * Km ^ ra_deg β"
by (rule mult_right_mono[OF cgbound[OF b]]) (use Km_nn in simp)
also have "… = Mg * (Km ^ ra_deg β / t ^ ra_deg β)" by simp
also have "… = Mg * (Km / t) ^ ra_deg β" by (simp add: power_divide)
finally show "norm (cg β) * Km ^ ra_deg β ≤ Mg * (Km / t) ^ ra_deg β" .
next
fix β :: "'b⇒nat" assume "β ∈ ra_idx"
show "0 ≤ norm (cg β) * Km ^ ra_deg β" using Km_nn by simp
qed
have Gval: "((λβ. ra_monomial (f x - y0) β *⇩R cg β) has_sum g (f x)) (ra_idx::('b⇒nat) set)"
if "dist x x0 < σ" for x
proof -
have "dist (f x) y0 < ρg" using contball'[of x] that σδc by simp
thus ?thesis by (rule Gser)
qed
have main: "∀x. dist x x0 < σ ⟶
((λγ. ra_monomial (x - x0) γ *⇩R
(∑⇩∞β∈(ra_idx::('b⇒nat) set). CC β γ *⇩R cg β))
has_sum g (f x)) (ra_idx::('a⇒nat) set)"
by (rule ra_series_on_majdom_vec
[where CC = CC and Fn = "λβ x. ra_monomial (f x - y0) β" and vg = cg
and Kk = "λβ. Km ^ ra_deg β" and σ = σ and r = σ
and G = "λx. g (f x)"])
(use σ0 CCser CCmaj gsum Gval in auto)
show "∃r>0. ∃cc. ∀x. dist x x0 < r ⟶
((λγ. ra_monomial (x - x0) γ *⇩R cc γ) has_sum g (f x)) ra_idx"
using σ0 main by (intro exI, auto)
qed
qed
subsection ‹Closure under linear maps, pairing, and finite sums›
lemma real_analytic_on_bounded_linear:
fixes L :: "'a::euclidean_space ⇒ 'b::real_normed_vector"
assumes U: "open U" and L: "bounded_linear L"
shows "real_analytic_on L U"
proof -
interpret L: bounded_linear L by (rule L)
define e :: "'a ⇒ 'a ⇒ nat" where "e = (λb c. if c = b then 1 else 0)"
have e_idx: "e b ∈ ra_idx" if "b ∈ Basis" for b
using that by (auto simp: e_def ra_idx_def)
have mono_e: "ra_monomial h (e b) = h ∙ b" if "b ∈ Basis" for b h
using that by (simp add: e_def ra_monomial_def prod.remove)
have e_inj: "inj_on e Basis"
by (auto simp: inj_on_def e_def fun_eq_iff)
have zero_notin: "(ra_idx_zero::'a ⇒ nat) ∉ image e Basis"
proof
assume "(ra_idx_zero::'a ⇒ nat) ∈ image e Basis"
then obtain b where b: "b ∈ Basis" "ra_idx_zero = e b" by blast
have "(0::nat) = 1"
using b by (metis ra_idx_zero_def e_def)
thus False by simp
qed
show ?thesis
unfolding real_analytic_on_def
proof (intro conjI ballI)
show "open U" by (rule U)
next
fix x0 assume "x0 ∈ U"
define A where "A = insert (ra_idx_zero::'a ⇒ nat) (image e Basis)"
define coeff where
"coeff = (λα::'a ⇒ nat.
if α = ra_idx_zero then L x0 else L (∑b∈Basis. if α = e b then b else 0))"
have finA: "finite A" by (simp add: A_def)
have Asub: "A ⊆ ra_idx"
using e_idx by (auto simp: A_def ra_idx_zero_in)
have neutral: "ra_monomial h α *⇩R coeff α = 0" if a: "α ∈ ra_idx - A" for h α
proof -
have z: "(∑b∈Basis. if α = e b then b else 0) = 0"
using a by (intro sum.neutral) (auto simp: A_def)
show ?thesis using a z by (simp add: A_def coeff_def)
qed
have coeff_e: "coeff (e b) = L b" if b: "b ∈ Basis" for b
proof -
have eb_ne: "e b ≠ (ra_idx_zero::'a ⇒ nat)"
using b zero_notin by (metis image_eqI)
have "(∑c∈Basis. if e b = e c then c else 0) =
(∑c∈Basis. if c = b then c else 0)"
using b e_inj by (intro sum.cong) (auto simp: inj_on_def)
also have "... = b"
using b by simp
finally show ?thesis using eb_ne by (simp add: coeff_def)
qed
have sum_img: "(∑α∈image e Basis. ra_monomial h α *⇩R coeff α) = L h" for h
proof -
have "(∑α∈image e Basis. ra_monomial h α *⇩R coeff α) =
(∑b∈Basis. ra_monomial h (e b) *⇩R coeff (e b))"
by (rule sum.reindex_cong[OF e_inj]) auto
also have "... = (∑b∈Basis. (h ∙ b) *⇩R L b)"
by (intro sum.cong refl) (simp add: mono_e coeff_e)
also have "... = L (∑b∈Basis. (h ∙ b) *⇩R b)"
by (simp add: L.sum L.scaleR)
also have "... = L h"
by (simp add: euclidean_representation)
finally show ?thesis .
qed
have zero_term: "ra_monomial h (ra_idx_zero::'a ⇒ nat) *⇩R coeff ra_idx_zero = L x0" for h
by (simp add: coeff_def ra_idx_zero_def ra_monomial_def)
have sumA: "(∑α∈A. ra_monomial h α *⇩R coeff α) = L (x0 + h)" for h
proof -
have "(∑α∈A. ra_monomial h α *⇩R coeff α) =
ra_monomial h ra_idx_zero *⇩R coeff ra_idx_zero +
(∑α∈image e Basis. ra_monomial h α *⇩R coeff α)"
using zero_notin by (simp add: A_def)
also have "... = L x0 + L h"
by (simp add: zero_term sum_img)
also have "... = L (x0 + h)"
by (simp add: L.add)
finally show ?thesis .
qed
show "∃r>0. ∃c. ∀x. dist x x0 < r ⟶
((λα. ra_monomial (x - x0) α *⇩R c α) has_sum L x) ra_idx"
proof (intro exI[where x=1] conjI exI[where x=coeff] allI impI)
show "0 < (1::real)" by simp
next
fix x assume "dist x x0 < (1::real)"
have "((λα. ra_monomial (x - x0) α *⇩R coeff α)
has_sum (∑α∈A. ra_monomial (x - x0) α *⇩R coeff α)) ra_idx"
proof (rule has_sum_finite_neutralI)
show "finite A" by (rule finA)
show "A ⊆ ra_idx" by (rule Asub)
fix α
assume "α ∈ ra_idx - A"
thus "ra_monomial (x - x0) α *⇩R coeff α = 0"
by (rule neutral)
next
show "(∑α∈A. ra_monomial (x - x0) α *⇩R coeff α) =
(∑α∈A. ra_monomial (x - x0) α *⇩R coeff α)"
by (rule refl)
qed
thus "((λα. ra_monomial (x - x0) α *⇩R coeff α) has_sum L x) ra_idx"
by (simp add: sumA)
qed
qed
qed
lemma real_analytic_on_Pair:
assumes F: "real_analytic_on f U" and G: "real_analytic_on g U"
shows "real_analytic_on (λx. (f x, g x)) U"
proof -
from F have U: "open U" by (simp only: real_analytic_on_def)
show ?thesis
unfolding real_analytic_on_def
proof (intro conjI ballI)
show "open U" by (rule U)
next
fix x0 assume x0: "x0 ∈ U"
from F x0 obtain r1 c1 where r1: "0 < r1"
and F1: "⋀x. dist x x0 < r1 ⟹
((λα. ra_monomial (x - x0) α *⇩R c1 α) has_sum f x) ra_idx"
unfolding real_analytic_on_def by blast
from G x0 obtain r2 c2 where r2: "0 < r2"
and G1: "⋀x. dist x x0 < r2 ⟹
((λα. ra_monomial (x - x0) α *⇩R c2 α) has_sum g x) ra_idx"
unfolding real_analytic_on_def by blast
show "∃r>0. ∃c. ∀x. dist x x0 < r ⟶
((λα. ra_monomial (x - x0) α *⇩R c α) has_sum (f x, g x)) ra_idx"
proof (intro exI[where x="min r1 r2"] conjI
exI[where x="λα. (c1 α, c2 α)"] allI impI)
show "0 < min r1 r2" using r1 r2 by simp
next
fix x assume d: "dist x x0 < min r1 r2"
have t1: "((λA. ∑α∈A. ra_monomial (x - x0) α *⇩R c1 α) ⤏ f x)
(finite_subsets_at_top ra_idx)"
using F1[of x] d unfolding has_sum_def by simp
have t2: "((λA. ∑α∈A. ra_monomial (x - x0) α *⇩R c2 α) ⤏ g x)
(finite_subsets_at_top ra_idx)"
using G1[of x] d unfolding has_sum_def by simp
have "((λA. ((∑α∈A. ra_monomial (x - x0) α *⇩R c1 α),
(∑α∈A. ra_monomial (x - x0) α *⇩R c2 α)))
⤏ (f x, g x)) (finite_subsets_at_top ra_idx)"
by (rule tendsto_Pair[OF t1 t2])
hence pair_tendsto:
"((λA. ∑α∈A. (ra_monomial (x - x0) α *⇩R c1 α,
ra_monomial (x - x0) α *⇩R c2 α))
⤏ (f x, g x)) (finite_subsets_at_top ra_idx)"
by (simp add: sum_prod)
have "((λα. (ra_monomial (x - x0) α *⇩R c1 α,
ra_monomial (x - x0) α *⇩R c2 α))
has_sum (f x, g x)) ra_idx"
unfolding has_sum_def by (rule pair_tendsto)
thus "((λα. ra_monomial (x - x0) α *⇩R (c1 α, c2 α))
has_sum (f x, g x)) ra_idx"
by simp
qed
qed
qed
lemma real_analytic_on_sum:
fixes f :: "'i ⇒ 'a::euclidean_space ⇒ 'b::real_normed_vector"
assumes U: "open U"
and fin: "finite I"
and ana: "⋀i. i ∈ I ⟹ real_analytic_on (f i) U"
shows "real_analytic_on (λx. ∑i∈I. f i x) U"
using fin ana
proof (induction I rule: finite_induct)
case empty
show ?case
by (simp add: real_analytic_on_const[OF U])
next
case (insert i I)
have fi: "real_analytic_on (f i) U"
using insert.prems by simp
have fI: "real_analytic_on (λx. ∑j∈I. f j x) U"
using insert.IH insert.prems by blast
have "real_analytic_on (λx. f i x + (∑j∈I. f j x)) U"
by (rule real_analytic_on_add[OF fi fI])
thus ?case
using insert.hyps by simp
qed
lemma real_analytic_on_componentwise:
fixes f :: "'a::euclidean_space ⇒ 'b::euclidean_space"
assumes U: "open U"
and ana: "⋀b. b ∈ Basis ⟹ real_analytic_on (λx. f x ∙ b) U"
shows "real_analytic_on f U"
proof -
have term_ana: "⋀b. b ∈ Basis ⟹ real_analytic_on (λx. (f x ∙ b) *⇩R b) U"
by (rule real_analytic_on_scaleR_vec[OF ana])
have "real_analytic_on (λx. ∑b∈Basis. (f x ∙ b) *⇩R b) U"
by (rule real_analytic_on_sum[OF U finite_Basis]) (use term_ana in blast)
thus ?thesis
by (simp add: euclidean_representation)
qed
lemma real_analytic_on_fst:
assumes "open U"
shows "real_analytic_on (fst :: ('a::euclidean_space × 'b::euclidean_space) ⇒ 'a) U"
by (rule real_analytic_on_bounded_linear[OF assms bounded_linear_fst])
lemma real_analytic_on_snd:
assumes "open U"
shows "real_analytic_on (snd :: ('a::euclidean_space × 'b::euclidean_space) ⇒ 'b) U"
by (rule real_analytic_on_bounded_linear[OF assms bounded_linear_snd])
lemma real_analytic_on_Pair_const:
fixes c :: "'b::euclidean_space"
assumes "open U"
shows "real_analytic_on (λx::'a::euclidean_space. (x, c)) U"
by (rule real_analytic_on_Pair)
(rule real_analytic_on_bounded_linear[OF assms bounded_linear_ident],
rule real_analytic_on_const[OF assms])
subsection ‹Locality of real-analyticity›
text ‹
‹real_analytic_on› is a local property: if every point of an open set ‹V› has a
neighbourhood on which ‹g› is real-analytic, then ‹g› is real-analytic on all of ‹V›.
›
lemma real_analytic_on_locality:
fixes g :: "'a::euclidean_space ⇒ 'b::real_normed_vector"
assumes V: "open V"
and loc: "⋀y. y ∈ V ⟹
∃W. open W ∧ y ∈ W ∧ W ⊆ V ∧ real_analytic_on g W"
shows "real_analytic_on g V"
unfolding real_analytic_on_def
proof (intro conjI ballI)
show "open V" by (rule V)
next
fix x assume xV: "x ∈ V"
from loc[OF xV] obtain W where W: "open W" "x ∈ W" "W ⊆ V"
and gW: "real_analytic_on g W" by blast
from gW W(2) show "∃r>0. ∃c. ∀y. dist y x < r ⟶
((λα. ra_monomial (y - x) α *⇩R c α) has_sum g y) ra_idx"
unfolding real_analytic_on_def by blast
qed
text ‹
If ‹G› is real-analytic on ‹V0› and ‹g = G› on an open subset ‹W›, then ‹g› is
real-analytic on ‹W›.
›
lemma real_analytic_on_cong_nbhd:
fixes g G :: "'a::euclidean_space ⇒ 'b::real_normed_vector"
assumes G: "real_analytic_on G V0"
and W: "open W" and sub: "W ⊆ V0"
and eq: "⋀y. y ∈ W ⟹ g y = G y"
shows "real_analytic_on g W"
unfolding real_analytic_on_def
proof (intro conjI ballI)
show "open W" by (rule W)
next
fix x assume xW: "x ∈ W"
hence xV0: "x ∈ V0" using sub by blast
from G xV0 obtain ρ c where ρ: "0 < ρ"
and ser: "⋀y. dist y x < ρ ⟹
((λα. ra_monomial (y - x) α *⇩R c α) has_sum G y) ra_idx"
unfolding real_analytic_on_def by blast
from W xW obtain δ where δ: "0 < δ" and ballW: "ball x δ ⊆ W"
using open_contains_ball by blast
define r where "r = min ρ δ"
have r0: "0 < r" using ρ δ by (simp add: r_def)
have "∀y. dist y x < r ⟶
((λα. ra_monomial (y - x) α *⇩R c α) has_sum g y) ra_idx"
proof (intro allI impI)
fix y assume d: "dist y x < r"
have dr: "dist y x < ρ" using d by (simp add: r_def)
have dd: "dist y x < δ" using d by (simp add: r_def)
have "y ∈ ball x δ" using dd by (simp add: dist_commute)
hence yW: "y ∈ W" using ballW by blast
have "((λα. ra_monomial (y - x) α *⇩R c α) has_sum G y) ra_idx"
by (rule ser[OF dr])
thus "((λα. ra_monomial (y - x) α *⇩R c α) has_sum g y) ra_idx"
by (simp add: eq[OF yW])
qed
with r0 show "∃r>0. ∃c. ∀y. dist y x < r ⟶
((λα. ra_monomial (y - x) α *⇩R c α) has_sum g y) ra_idx"
by blast
qed
text ‹
The inverse and implicit function theorems for real-analytic maps
(‹real_analytic_local_inverse›, ‹real_analytic_implicit_function›) build on this theory.
›
section ‹A $C^\infty$ Function That Is Not Analytic›
text ‹
The flat function ‹x ↦ exp (-1/x)› for ‹x > 0›, ‹0› otherwise, is ‹C⇧∞› on ‹ℝ›.
All of its derivatives vanish at ‹0›, while the function is positive to the right of
‹0›; so it is not real-analytic at ‹0›. This witnesses ‹C⇧ω ≠ C⇧∞›.
›
definition exp_bump :: "real ⇒ real" where
"exp_bump x = (if 0 < x then exp (- (1 / x)) else 0)"
subsection ‹Derivatives of the flat function›
text ‹Every derivative of ‹exp_bump› has the form ‹x ↦ p (1/x) * exp (-1/x)› for
‹x > 0› and vanishes for ‹x ≤ 0›, where ‹p› is a real polynomial function. The key
estimate is that ‹p (1/x) * exp (-1/x) ⟶ 0› as ‹x ⟶ 0⇧+›.›
lemma flat_poly_tendsto_zero:
assumes "real_polynomial_function p"
shows "((λx. p (inverse x) * exp (- inverse x)) ⤏ 0) (at_right 0)"
proof -
obtain a n where p: "p = (λt. ∑i≤n. a i * t ^ i)"
using assms real_polynomial_function_iff_sum by blast
have "((λt. ∑i≤n. a i * (t ^ i / exp t)) ⤏ (∑i≤n. a i * 0)) at_top"
by (intro tendsto_sum tendsto_mult tendsto_const tendsto_power_div_exp_0)
moreover have "(∑i≤n. a i * (t ^ i / exp t)) = p t * exp (- t)" for t
by (simp add: p sum_distrib_right exp_minus divide_inverse mult.assoc)
ultimately have "((λt. p t * exp (- t)) ⤏ 0) at_top"
by simp
from filterlim_compose[OF this filterlim_inverse_at_top_right] show ?thesis .
qed
lemma flat_poly_has_derivative:
assumes p: "real_polynomial_function p"
shows "((λx. if 0 < x then p (inverse x) * exp (- inverse x) else 0) has_real_derivative
(if 0 < x then (inverse x)⇧2 * (p (inverse x) - deriv p (inverse x)) * exp (- inverse x)
else 0)) (at x)"
(is "(?G has_real_derivative _) _")
proof -
have Dp: "(p has_real_derivative deriv p t) (at t)" for t
proof -
obtain p' where "∀t. (p has_real_derivative p' t) (at t)"
using has_real_derivative_polynomial_function[OF p] by blast
then show ?thesis
using DERIV_imp_deriv by metis
qed
consider "x < 0" | "x = 0" | "0 < x"
by linarith
then show ?thesis
proof cases
case 1
have "((λy. 0) has_real_derivative 0) (at x)"
by simp
then have "(?G has_real_derivative 0) (at x)"
by (rule has_field_derivative_transform_within_open[where S = "{..<0}"]) (use 1 in auto)
then show ?thesis
using 1 by simp
next
case 3
then have x0: "x ≠ 0" by simp
have d1: "((λy. p (inverse y)) has_real_derivative
deriv p (inverse x) * - (inverse x ^ Suc (Suc 0))) (at x)"
by (rule DERIV_chain2[OF Dp DERIV_inverse[OF x0]])
have d2: "((λy. exp (- inverse y)) has_real_derivative
exp (- inverse x) * - (- (inverse x ^ Suc (Suc 0)))) (at x)"
by (rule DERIV_chain2[OF DERIV_exp DERIV_minus[OF DERIV_inverse[OF x0]]])
have "((λy. p (inverse y) * exp (- inverse y)) has_real_derivative
(inverse x)⇧2 * (p (inverse x) - deriv p (inverse x)) * exp (- inverse x)) (at x)"
using DERIV_mult[OF d1 d2] by (simp add: power2_eq_square algebra_simps)
then have "(?G has_real_derivative
(inverse x)⇧2 * (p (inverse x) - deriv p (inverse x)) * exp (- inverse x)) (at x)"
by (rule has_field_derivative_transform_within_open[where S = "{0<..}"]) (use 3 in auto)
then show ?thesis
using 3 by simp
next
case 2
have right: "((λy. (?G y - ?G 0) / (y - 0)) ⤏ 0) (at_right 0)"
proof -
have "real_polynomial_function (λt. t * p t)"
by (rule real_polynomial_function.intros(4)
[OF real_polynomial_function.intros(1)[OF bounded_linear_ident] p])
then have "((λy. inverse y * p (inverse y) * exp (- inverse y)) ⤏ 0) (at_right 0)"
by (rule flat_poly_tendsto_zero)
moreover have "∀⇩F y in at_right 0.
inverse y * p (inverse y) * exp (- inverse y) = (?G y - ?G 0) / (y - 0)"
using eventually_at_right_less[of "0::real"]
by eventually_elim (simp add: divide_inverse)
ultimately show ?thesis
by (rule Lim_transform_eventually)
qed
have left: "((λy. (?G y - ?G 0) / (y - 0)) ⤏ 0) (at_left 0)"
proof -
have "∀⇩F y in at_left (0::real). y ∈ {-1<..<0}"
by (rule eventually_at_left_real) simp
then have "∀⇩F y in at_left (0::real). y < 0"
by eventually_elim simp
then have "∀⇩F y in at_left 0. 0 = (?G y - ?G 0) / (y - 0)"
by eventually_elim simp
with tendsto_const show ?thesis
by (rule Lim_transform_eventually)
qed
have "(?G has_real_derivative 0) (at 0)"
unfolding has_field_derivative_iff by (rule filterlim_split_at[OF left right])
then show ?thesis
using 2 by simp
qed
qed
lemma exp_bump_deriv_formula:
"∃p. real_polynomial_function p ∧
(deriv ^^ n) exp_bump = (λx. if 0 < x then p (inverse x) * exp (- inverse x) else 0)"
proof (induction n)
case 0
have "exp_bump = (λx. if 0 < x then 1 * exp (- inverse x) else 0)"
by (auto simp: exp_bump_def inverse_eq_divide)
then show ?case
by (intro exI[of _ "λ_. 1"]) auto
next
case (Suc n)
then obtain p where p: "real_polynomial_function p"
and eq: "(deriv ^^ n) exp_bump = (λx. if 0 < x then p (inverse x) * exp (- inverse x) else 0)"
by blast
define q where "q t = t⇧2 * (p t - deriv p t)" for t
have q: "real_polynomial_function q"
unfolding q_def
by (intro real_polynomial_function.intros(4) real_polynomial_function_power
real_polynomial_function_diff p deriv_real_polynomial_function[OF p]
real_polynomial_function.intros(1)[OF bounded_linear_ident])
have "(deriv ^^ Suc n) exp_bump =
(λx. if 0 < x then q (inverse x) * exp (- inverse x) else 0)"
proof
fix x
have "deriv ((deriv ^^ n) exp_bump) x = (if 0 < x then q (inverse x) * exp (- inverse x) else 0)"
unfolding eq q_def by (rule DERIV_imp_deriv[OF flat_poly_has_derivative[OF p]])
then show "(deriv ^^ Suc n) exp_bump x =
(if 0 < x then q (inverse x) * exp (- inverse x) else 0)"
by simp
qed
with q show ?case
by blast
qed
lemma exp_bump_flat_deriv: "(deriv ^^ n) exp_bump 0 = 0"
using exp_bump_deriv_formula[of n] by auto
lemma exp_bump_kth_deriv_differentiable: "(deriv ^^ n) exp_bump differentiable (at x)"
proof -
obtain p where p: "real_polynomial_function p"
and eq: "(deriv ^^ n) exp_bump = (λx. if 0 < x then p (inverse x) * exp (- inverse x) else 0)"
using exp_bump_deriv_formula by blast
show ?thesis
unfolding eq using flat_poly_has_derivative[OF p] real_differentiable_def by blast
qed
lemma exp_bump_C_k_on: "C_k_on k exp_bump UNIV"
proof -
have diff: "(deriv ^^ n) exp_bump differentiable_on UNIV" for n
by (rule differentiable_at_imp_differentiable_on) (rule exp_bump_kth_deriv_differentiable)
have cont: "continuous_on UNIV ((deriv ^^ n) exp_bump)" for n
using diff[of n] by (rule differentiable_imp_continuous_on)
show ?thesis
proof (cases "k = 0")
case True
then show ?thesis
using cont[of 0] by (simp add: C_k_on_def)
next
case False
then show ?thesis
using diff cont by (simp add: C_k_on_def del: funpow.simps)
qed
qed
subsection ‹Smooth but not analytic›
theorem exp_bump_Cinfinity: "Cinfinity_on exp_bump UNIV"
proof -
have "Ck_on k exp_bump UNIV" for k
using exp_bump_C_k_on by (simp add: Ck_on_real_iff)
then show ?thesis
unfolding Cinfinity_on_def Cinfinity_at_def by (simp add: Ck_on_def)
qed
theorem exp_bump_not_real_analytic: "¬ real_analytic_on exp_bump (ball 0 1)"
proof
assume A: "real_analytic_on exp_bump (ball (0::real) 1)"
have "0 ∈ ball (0::real) 1" by simp
with A have "real_analytic_at_1d exp_bump 0"
using real_analytic_on_1d_iff[of exp_bump "ball 0 1"] by blast
then obtain r where r: "0 < r"
and TS: "⋀x. ¦x - 0¦ < r ⟹
(λn. (deriv ^^ n) exp_bump 0 / fact n * (x - 0) ^ n) sums exp_bump x"
unfolding real_analytic_at_1d_def by blast
define x0 where "x0 = r / 2"
have x0_pos: "0 < x0" using r by (simp add: x0_def)
have "¦x0 - 0¦ = x0" using x0_pos by simp
also have "x0 < r" using r unfolding x0_def by linarith
finally have x0_lt: "¦x0 - 0¦ < r" .
have "(λn. (deriv ^^ n) exp_bump 0 / fact n * (x0 - 0) ^ n) = (λn. 0)"
by (simp add: exp_bump_flat_deriv)
with TS[OF x0_lt] have z0: "(λn. (0::real)) sums exp_bump x0" by simp
have "exp_bump x0 = 0"
using sums_unique2[OF z0 sums_zero] by simp
moreover have "exp_bump x0 = exp (- (1 / x0))"
using x0_pos by (simp add: exp_bump_def)
ultimately show False by simp
qed
end