# HG changeset patch # User immler # Date 1450817907 -3600 # Node ID e9812a95d108826d9498c6ef8805eb702682da8d # Parent 16bfe0a6702dbecde8884affa0597b2102988c4e theory for type of bounded linear functions; differentiation under the integral sign diff -r 16bfe0a6702d -r e9812a95d108 src/HOL/Library/Inner_Product.thy --- a/src/HOL/Library/Inner_Product.thy Tue Dec 22 15:39:01 2015 +0100 +++ b/src/HOL/Library/Inner_Product.thy Tue Dec 22 21:58:27 2015 +0100 @@ -213,6 +213,10 @@ lemmas bounded_linear_inner_right = bounded_bilinear.bounded_linear_right [OF bounded_bilinear_inner] +lemmas bounded_linear_inner_left_comp = bounded_linear_inner_left[THEN bounded_linear_compose] + +lemmas bounded_linear_inner_right_comp = bounded_linear_inner_right[THEN bounded_linear_compose] + lemmas has_derivative_inner_right [derivative_intros] = bounded_linear.has_derivative [OF bounded_linear_inner_right] diff -r 16bfe0a6702d -r e9812a95d108 src/HOL/Library/Product_Vector.thy --- a/src/HOL/Library/Product_Vector.thy Tue Dec 22 15:39:01 2015 +0100 +++ b/src/HOL/Library/Product_Vector.thy Tue Dec 22 21:58:27 2015 +0100 @@ -449,6 +449,10 @@ using snd_add snd_scaleR by (rule bounded_linear_intro [where K=1], simp add: norm_prod_def) +lemmas bounded_linear_fst_comp = bounded_linear_fst[THEN bounded_linear_compose] + +lemmas bounded_linear_snd_comp = bounded_linear_snd[THEN bounded_linear_compose] + lemma bounded_linear_Pair: assumes f: "bounded_linear f" assumes g: "bounded_linear g" diff -r 16bfe0a6702d -r e9812a95d108 src/HOL/Multivariate_Analysis/Bounded_Linear_Function.thy --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/HOL/Multivariate_Analysis/Bounded_Linear_Function.thy Tue Dec 22 21:58:27 2015 +0100 @@ -0,0 +1,726 @@ +(* Title: HOL/Multivariate_Analysis/Bounded_Linear_Function.thy + Author: Fabian Immler, TU München +*) + +section {* Bounded Linear Function *} + +theory Bounded_Linear_Function +imports + Topology_Euclidean_Space + Operator_Norm +begin + +subsection {* Intro rules for @{term bounded_linear} *} + +named_theorems bounded_linear_intros + +lemma onorm_inner_left: + assumes "bounded_linear r" + shows "onorm (\x. r x \ f) \ onorm r * norm f" +proof (rule onorm_bound) + fix x + have "norm (r x \ f) \ norm (r x) * norm f" + by (simp add: Cauchy_Schwarz_ineq2) + also have "\ \ onorm r * norm x * norm f" + by (intro mult_right_mono onorm assms norm_ge_zero) + finally show "norm (r x \ f) \ onorm r * norm f * norm x" + by (simp add: ac_simps) +qed (intro mult_nonneg_nonneg norm_ge_zero onorm_pos_le assms) + +lemma onorm_inner_right: + assumes "bounded_linear r" + shows "onorm (\x. f \ r x) \ norm f * onorm r" + apply (subst inner_commute) + apply (rule onorm_inner_left[OF assms, THEN order_trans]) + apply simp + done + +lemmas [bounded_linear_intros] = + bounded_linear_zero + bounded_linear_add + bounded_linear_const_mult + bounded_linear_mult_const + bounded_linear_scaleR_const + bounded_linear_const_scaleR + bounded_linear_ident + bounded_linear_setsum + bounded_linear_Pair + bounded_linear_sub + bounded_linear_fst_comp + bounded_linear_snd_comp + bounded_linear_inner_left_comp + bounded_linear_inner_right_comp + + +subsection \declaration of derivative/continuous/tendsto introduction rules for bounded linear functions\ + +attribute_setup bounded_linear = + \Scan.succeed (Thm.declaration_attribute (fn thm => + fold (fn (r, s) => Named_Theorems.add_thm s (thm RS r)) + [ + (@{thm bounded_linear.has_derivative}, "Deriv.derivative_intros"), + (@{thm bounded_linear.tendsto}, "Topological_Spaces.tendsto_intros"), + (@{thm bounded_linear.continuous}, "Topological_Spaces.continuous_intros"), + (@{thm bounded_linear.continuous_on}, "Topological_Spaces.continuous_intros"), + (@{thm bounded_linear.uniformly_continuous_on}, "Topological_Spaces.continuous_intros"), + (@{thm bounded_linear_compose}, "Bounded_Linear_Function.bounded_linear_intros") + ]))\ + +attribute_setup bounded_bilinear = + \Scan.succeed (Thm.declaration_attribute (fn thm => + fold (fn (r, s) => Named_Theorems.add_thm s (thm RS r)) + [ + (@{thm bounded_bilinear.FDERIV}, "Deriv.derivative_intros"), + (@{thm bounded_bilinear.tendsto}, "Topological_Spaces.tendsto_intros"), + (@{thm bounded_bilinear.continuous}, "Topological_Spaces.continuous_intros"), + (@{thm bounded_bilinear.continuous_on}, "Topological_Spaces.continuous_intros"), + (@{thm bounded_linear_compose[OF bounded_bilinear.bounded_linear_left]}, + "Bounded_Linear_Function.bounded_linear_intros"), + (@{thm bounded_linear_compose[OF bounded_bilinear.bounded_linear_right]}, + "Bounded_Linear_Function.bounded_linear_intros"), + (@{thm bounded_linear.uniformly_continuous_on[OF bounded_bilinear.bounded_linear_left]}, + "Topological_Spaces.continuous_intros"), + (@{thm bounded_linear.uniformly_continuous_on[OF bounded_bilinear.bounded_linear_right]}, + "Topological_Spaces.continuous_intros") + ]))\ + + +subsection \type of bounded linear functions\ + +typedef (overloaded) ('a, 'b) blinfun ("(_ \\<^sub>L /_)" [22, 21] 21) = + "{f::'a::real_normed_vector\'b::real_normed_vector. bounded_linear f}" + morphisms blinfun_apply Blinfun + by (blast intro: bounded_linear_intros) + +declare [[coercion + "blinfun_apply :: ('a::real_normed_vector \\<^sub>L'b::real_normed_vector) \ 'a \ 'b"]] + +lemma bounded_linear_blinfun_apply[bounded_linear_intros]: + "bounded_linear g \ bounded_linear (\x. blinfun_apply f (g x))" + by (metis blinfun_apply mem_Collect_eq bounded_linear_compose) + +setup_lifting type_definition_blinfun + +lemma blinfun_eqI: "(\i. blinfun_apply x i = blinfun_apply y i) \ x = y" + by transfer auto + +lemma bounded_linear_Blinfun_apply: "bounded_linear f \ blinfun_apply (Blinfun f) = f" + by (auto simp: Blinfun_inverse) + + +subsection \type class instantiations\ + +instantiation blinfun :: (real_normed_vector, real_normed_vector) real_normed_vector +begin + +lift_definition norm_blinfun :: "'a \\<^sub>L 'b \ real" is onorm . + +lift_definition minus_blinfun :: "'a \\<^sub>L 'b \ 'a \\<^sub>L 'b \ 'a \\<^sub>L 'b" + is "\f g x. f x - g x" + by (rule bounded_linear_sub) + +definition dist_blinfun :: "'a \\<^sub>L 'b \ 'a \\<^sub>L 'b \ real" + where "dist_blinfun a b = norm (a - b)" + +definition open_blinfun :: "('a \\<^sub>L 'b) set \ bool" + where "open_blinfun S \ (\x\S. \e>0. \y. dist y x < e \ y \ S)" + +lift_definition uminus_blinfun :: "'a \\<^sub>L 'b \ 'a \\<^sub>L 'b" is "\f x. - f x" + by (rule bounded_linear_minus) + +lift_definition zero_blinfun :: "'a \\<^sub>L 'b" is "\x. 0" + by (rule bounded_linear_zero) + +lift_definition plus_blinfun :: "'a \\<^sub>L 'b \ 'a \\<^sub>L 'b \ 'a \\<^sub>L 'b" + is "\f g x. f x + g x" + by (metis bounded_linear_add) + +lift_definition scaleR_blinfun::"real \ 'a \\<^sub>L 'b \ 'a \\<^sub>L 'b" is "\r f x. r *\<^sub>R f x" + by (metis bounded_linear_compose bounded_linear_scaleR_right) + +definition sgn_blinfun :: "'a \\<^sub>L 'b \ 'a \\<^sub>L 'b" + where "sgn_blinfun x = scaleR (inverse (norm x)) x" + +instance + apply standard + unfolding dist_blinfun_def open_blinfun_def sgn_blinfun_def + apply (transfer, force simp: onorm_triangle onorm_scaleR onorm_eq_0 algebra_simps)+ + done + +end + +lemma norm_blinfun_eqI: + assumes "n \ norm (blinfun_apply f x) / norm x" + assumes "\x. norm (blinfun_apply f x) \ n * norm x" + assumes "0 \ n" + shows "norm f = n" + by (auto simp: norm_blinfun_def + intro!: antisym onorm_bound assms order_trans[OF _ le_onorm] + bounded_linear_intros) + +lemma norm_blinfun: "norm (blinfun_apply f x) \ norm f * norm x" + by transfer (rule onorm) + +lemma norm_blinfun_bound: "0 \ b \ (\x. norm (blinfun_apply f x) \ b * norm x) \ norm f \ b" + by transfer (rule onorm_bound) + +lemma bounded_bilinear_blinfun_apply[bounded_bilinear]: "bounded_bilinear blinfun_apply" +proof + fix f g::"'a \\<^sub>L 'b" and a b::'a and r::real + show "(f + g) a = f a + g a" "(r *\<^sub>R f) a = r *\<^sub>R f a" + by (transfer, simp)+ + interpret bounded_linear f for f::"'a \\<^sub>L 'b" + by (auto intro!: bounded_linear_intros) + show "f (a + b) = f a + f b" "f (r *\<^sub>R a) = r *\<^sub>R f a" + by (simp_all add: add scaleR) + show "\K. \a b. norm (blinfun_apply a b) \ norm a * norm b * K" + by (auto intro!: exI[where x=1] norm_blinfun) +qed + +interpretation blinfun: bounded_bilinear blinfun_apply + by (rule bounded_bilinear_blinfun_apply) + +lemmas bounded_linear_apply_blinfun[intro, simp] = blinfun.bounded_linear_left + + +context bounded_bilinear +begin + +named_theorems bilinear_simps + +lemmas [bilinear_simps] = + add_left + add_right + diff_left + diff_right + minus_left + minus_right + scaleR_left + scaleR_right + zero_left + zero_right + setsum_left + setsum_right + +end + + +instance blinfun :: (banach, banach) banach +proof + fix X::"nat \ 'a \\<^sub>L 'b" + assume "Cauchy X" + { + fix x::'a + { + fix x::'a + assume "norm x \ 1" + have "Cauchy (\n. X n x)" + proof (rule CauchyI) + fix e::real + assume "0 < e" + from CauchyD[OF `Cauchy X` `0 < e`] obtain M + where M: "\m n. m \ M \ n \ M \ norm (X m - X n) < e" + by auto + show "\M. \m\M. \n\M. norm (X m x - X n x) < e" + proof (safe intro!: exI[where x=M]) + fix m n + assume le: "M \ m" "M \ n" + have "norm (X m x - X n x) = norm ((X m - X n) x)" + by (simp add: blinfun.bilinear_simps) + also have "\ \ norm (X m - X n) * norm x" + by (rule norm_blinfun) + also have "\ \ norm (X m - X n) * 1" + using `norm x \ 1` norm_ge_zero by (rule mult_left_mono) + also have "\ = norm (X m - X n)" by simp + also have "\ < e" using le by fact + finally show "norm (X m x - X n x) < e" . + qed + qed + hence "convergent (\n. X n x)" + by (metis Cauchy_convergent_iff) + } note convergent_norm1 = this + def y \ "x /\<^sub>R norm x" + have y: "norm y \ 1" and xy: "x = norm x *\<^sub>R y" + by (simp_all add: y_def inverse_eq_divide) + have "convergent (\n. norm x *\<^sub>R X n y)" + by (intro bounded_bilinear.convergent[OF bounded_bilinear_scaleR] convergent_const + convergent_norm1 y) + also have "(\n. norm x *\<^sub>R X n y) = (\n. X n x)" + by (subst xy) (simp add: blinfun.bilinear_simps) + finally have "convergent (\n. X n x)" . + } + then obtain v where v: "\x. (\n. X n x) ----> v x" + unfolding convergent_def + by metis + + have "Cauchy (\n. norm (X n))" + proof (rule CauchyI) + fix e::real + assume "e > 0" + from CauchyD[OF `Cauchy X` `0 < e`] obtain M + where M: "\m n. m \ M \ n \ M \ norm (X m - X n) < e" + by auto + show "\M. \m\M. \n\M. norm (norm (X m) - norm (X n)) < e" + proof (safe intro!: exI[where x=M]) + fix m n assume mn: "m \ M" "n \ M" + have "norm (norm (X m) - norm (X n)) \ norm (X m - X n)" + by (metis norm_triangle_ineq3 real_norm_def) + also have "\ < e" using mn by fact + finally show "norm (norm (X m) - norm (X n)) < e" . + qed + qed + then obtain K where K: "(\n. norm (X n)) ----> K" + unfolding Cauchy_convergent_iff convergent_def + by metis + + have "bounded_linear v" + proof + fix x y and r::real + from tendsto_add[OF v[of x] v [of y]] v[of "x + y", unfolded blinfun.bilinear_simps] + tendsto_scaleR[OF tendsto_const[of r] v[of x]] v[of "r *\<^sub>R x", unfolded blinfun.bilinear_simps] + show "v (x + y) = v x + v y" "v (r *\<^sub>R x) = r *\<^sub>R v x" + by (metis (poly_guards_query) LIMSEQ_unique)+ + show "\K. \x. norm (v x) \ norm x * K" + proof (safe intro!: exI[where x=K]) + fix x + have "norm (v x) \ K * norm x" + by (rule tendsto_le[OF _ tendsto_mult[OF K tendsto_const] tendsto_norm[OF v]]) + (auto simp: norm_blinfun) + thus "norm (v x) \ norm x * K" + by (simp add: ac_simps) + qed + qed + hence Bv: "\x. (\n. X n x) ----> Blinfun v x" + by (auto simp: bounded_linear_Blinfun_apply v) + + have "X ----> Blinfun v" + proof (rule LIMSEQ_I) + fix r::real assume "r > 0" + def r' \ "r / 2" + have "0 < r'" "r' < r" using `r > 0` by (simp_all add: r'_def) + from CauchyD[OF `Cauchy X` `r' > 0`] + obtain M where M: "\m n. m \ M \ n \ M \ norm (X m - X n) < r'" + by metis + show "\no. \n\no. norm (X n - Blinfun v) < r" + proof (safe intro!: exI[where x=M]) + fix n assume n: "M \ n" + have "norm (X n - Blinfun v) \ r'" + proof (rule norm_blinfun_bound) + fix x + have "eventually (\m. m \ M) sequentially" + by (metis eventually_ge_at_top) + hence ev_le: "eventually (\m. norm (X n x - X m x) \ r' * norm x) sequentially" + proof eventually_elim + case (elim m) + have "norm (X n x - X m x) = norm ((X n - X m) x)" + by (simp add: blinfun.bilinear_simps) + also have "\ \ norm ((X n - X m)) * norm x" + by (rule norm_blinfun) + also have "\ \ r' * norm x" + using M[OF n elim] by (simp add: mult_right_mono) + finally show ?case . + qed + have tendsto_v: "(\m. norm (X n x - X m x)) ----> norm (X n x - Blinfun v x)" + by (auto intro!: tendsto_intros Bv) + show "norm ((X n - Blinfun v) x) \ r' * norm x" + by (auto intro!: tendsto_ge_const tendsto_v ev_le simp: blinfun.bilinear_simps) + qed (simp add: `0 < r'` less_imp_le) + thus "norm (X n - Blinfun v) < r" + by (metis `r' < r` le_less_trans) + qed + qed + thus "convergent X" + by (rule convergentI) +qed + +subsection {* On Euclidean Space *} + +lemma Zfun_setsum: + assumes "finite s" + assumes f: "\i. i \ s \ Zfun (f i) F" + shows "Zfun (\x. setsum (\i. f i x) s) F" + using assms by induct (auto intro!: Zfun_zero Zfun_add) + +lemma norm_blinfun_euclidean_le: + fixes a::"'a::euclidean_space \\<^sub>L 'b::real_normed_vector" + shows "norm a \ setsum (\x. norm (a x)) Basis" + apply (rule norm_blinfun_bound) + apply (simp add: setsum_nonneg) + apply (subst euclidean_representation[symmetric, where 'a='a]) + apply (simp only: blinfun.bilinear_simps setsum_left_distrib) + apply (rule order.trans[OF norm_setsum setsum_mono]) + apply (simp add: abs_mult mult_right_mono ac_simps Basis_le_norm) + done + +lemma tendsto_componentwise1: + fixes a::"'a::euclidean_space \\<^sub>L 'b::real_normed_vector" + and b::"'c \ 'a \\<^sub>L 'b" + assumes "(\j. j \ Basis \ ((\n. b n j) ---> a j) F)" + shows "(b ---> a) F" +proof - + have "\j. j \ Basis \ Zfun (\x. norm (b x j - a j)) F" + using assms unfolding tendsto_Zfun_iff Zfun_norm_iff . + hence "Zfun (\x. \j\Basis. norm (b x j - a j)) F" + by (auto intro!: Zfun_setsum) + thus ?thesis + unfolding tendsto_Zfun_iff + by (rule Zfun_le) + (auto intro!: order_trans[OF norm_blinfun_euclidean_le] simp: blinfun.bilinear_simps) +qed + +lift_definition + blinfun_of_matrix::"('b::euclidean_space \ 'a::euclidean_space \ real) \ 'a \\<^sub>L 'b" + is "\a x. \i\Basis. \j\Basis. ((x \ j) * a i j) *\<^sub>R i" + by (intro bounded_linear_intros) + +lemma blinfun_of_matrix_works: + fixes f::"'a::euclidean_space \\<^sub>L 'b::euclidean_space" + shows "blinfun_of_matrix (\i j. (f j) \ i) = f" +proof (transfer, rule, rule euclidean_eqI) + fix f::"'a \ 'b" and x::'a and b::'b assume "bounded_linear f" and b: "b \ Basis" + then interpret bounded_linear f by simp + have "(\j\Basis. \i\Basis. (x \ i * (f i \ j)) *\<^sub>R j) \ b + = (\j\Basis. if j = b then (\i\Basis. (x \ i * (f i \ j))) else 0)" + using b + by (auto simp add: algebra_simps inner_setsum_left inner_Basis split: split_if intro!: setsum.cong) + also have "\ = (\i\Basis. (x \ i * (f i \ b)))" + using b by (simp add: setsum.delta) + also have "\ = f x \ b" + by (subst linear_componentwise[symmetric]) (unfold_locales, rule) + finally show "(\j\Basis. \i\Basis. (x \ i * (f i \ j)) *\<^sub>R j) \ b = f x \ b" . +qed + +lemma blinfun_of_matrix_apply: + "blinfun_of_matrix a x = (\i\Basis. \j\Basis. ((x \ j) * a i j) *\<^sub>R i)" + by transfer simp + +lemma blinfun_of_matrix_minus: "blinfun_of_matrix x - blinfun_of_matrix y = blinfun_of_matrix (x - y)" + by transfer (auto simp: algebra_simps setsum_subtractf) + +lemma norm_blinfun_of_matrix: + "norm (blinfun_of_matrix a) \ (\i\Basis. \j\Basis. abs (a i j))" + apply (rule norm_blinfun_bound) + apply (simp add: setsum_nonneg) + apply (simp only: blinfun_of_matrix_apply setsum_left_distrib) + apply (rule order_trans[OF norm_setsum setsum_mono]) + apply (rule order_trans[OF norm_setsum setsum_mono]) + apply (simp add: abs_mult mult_right_mono ac_simps Basis_le_norm) + done + +lemma tendsto_blinfun_of_matrix: + assumes "\i j. i \ Basis \ j \ Basis \ ((\n. b n i j) ---> a i j) F" + shows "((\n. blinfun_of_matrix (b n)) ---> blinfun_of_matrix a) F" +proof - + have "\i j. i \ Basis \ j \ Basis \ Zfun (\x. norm (b x i j - a i j)) F" + using assms unfolding tendsto_Zfun_iff Zfun_norm_iff . + hence "Zfun (\x. (\i\Basis. \j\Basis. abs (b x i j - a i j))) F" + by (auto intro!: Zfun_setsum) + thus ?thesis + unfolding tendsto_Zfun_iff blinfun_of_matrix_minus + by (rule Zfun_le) (auto intro!: order_trans[OF norm_blinfun_of_matrix]) +qed + +lemma tendsto_componentwise: + fixes a::"'a::euclidean_space \\<^sub>L 'b::euclidean_space" + and b::"'c \ 'a \\<^sub>L 'b" + shows "(\i j. i \ Basis \ j \ Basis \ ((\n. b n j \ i) ---> a j \ i) F) \ (b ---> a) F" + apply (subst blinfun_of_matrix_works[of a, symmetric]) + apply (subst blinfun_of_matrix_works[of "b x" for x, symmetric, abs_def]) + by (rule tendsto_blinfun_of_matrix) + +lemma + continuous_blinfun_componentwiseI: + fixes f:: "'b::t2_space \ 'a::euclidean_space \\<^sub>L 'c::euclidean_space" + assumes "\i j. i \ Basis \ j \ Basis \ continuous F (\x. (f x) j \ i)" + shows "continuous F f" + using assms by (auto simp: continuous_def intro!: tendsto_componentwise) + +lemma + continuous_blinfun_componentwiseI1: + fixes f:: "'b::t2_space \ 'a::euclidean_space \\<^sub>L 'c::real_normed_vector" + assumes "\i. i \ Basis \ continuous F (\x. f x i)" + shows "continuous F f" + using assms by (auto simp: continuous_def intro!: tendsto_componentwise1) + +lemma bounded_linear_blinfun_matrix: "bounded_linear (\x. (x::_\\<^sub>L _) j \ i)" + by (auto intro!: bounded_linearI' bounded_linear_intros) + +lemma continuous_blinfun_matrix: + fixes f:: "'b::t2_space \ 'a::real_normed_vector \\<^sub>L 'c::real_inner" + assumes "continuous F f" + shows "continuous F (\x. (f x) j \ i)" + by (rule bounded_linear.continuous[OF bounded_linear_blinfun_matrix assms]) + +lemma continuous_on_blinfun_matrix: + fixes f::"'a::t2_space \ 'b::real_normed_vector \\<^sub>L 'c::real_inner" + assumes "continuous_on S f" + shows "continuous_on S (\x. (f x) j \ i)" + using assms + by (auto simp: continuous_on_eq_continuous_within continuous_blinfun_matrix) + +lemma mult_if_delta: + "(if P then (1::'a::comm_semiring_1) else 0) * q = (if P then q else 0)" + by auto + +text {* TODO: generalize this and @{thm compact_lemma}?! *} +lemma compact_blinfun_lemma: + fixes f :: "nat \ 'a::euclidean_space \\<^sub>L 'b::euclidean_space" + assumes "bounded (range f)" + shows "\d\Basis. \l::'a \\<^sub>L 'b. \ r. + subseq r \ (\e>0. eventually (\n. \i\d. dist (f (r n) i) (l i) < e) sequentially)" +proof safe + fix d :: "'a set" + assume d: "d \ Basis" + with finite_Basis have "finite d" + by (blast intro: finite_subset) + from this d show "\l::'a \\<^sub>L 'b. \r. subseq r \ + (\e>0. eventually (\n. \i\d. dist (f (r n) i) (l i) < e) sequentially)" + proof (induct d) + case empty + then show ?case + unfolding subseq_def by auto + next + case (insert k d) + have k[intro]: "k \ Basis" + using insert by auto + have s': "bounded ((\x. blinfun_apply x k) ` range f)" + using `bounded (range f)` + by (auto intro!: bounded_linear_image bounded_linear_intros) + obtain l1::"'a \\<^sub>L 'b" and r1 where r1: "subseq r1" + and lr1: "\e > 0. eventually (\n. \i\d. dist (f (r1 n) i) (l1 i) < e) sequentially" + using insert(3) using insert(4) by auto + have f': "\n. f (r1 n) k \ (\x. blinfun_apply x k) ` range f" + by simp + have "bounded (range (\i. f (r1 i) k))" + by (metis (lifting) bounded_subset f' image_subsetI s') + then obtain l2 r2 + where r2: "subseq r2" + and lr2: "((\i. f (r1 (r2 i)) k) ---> l2) sequentially" + using bounded_imp_convergent_subsequence[of "\i. f (r1 i) k"] + by (auto simp: o_def) + def r \ "r1 \ r2" + have r:"subseq r" + using r1 and r2 unfolding r_def o_def subseq_def by auto + moreover + def l \ "blinfun_of_matrix (\i j. if j = k then l2 \ i else l1 j \ i)::'a \\<^sub>L 'b" + { + fix e::real + assume "e > 0" + from lr1 `e > 0` have N1: "eventually (\n. \i\d. dist (f (r1 n) i) (l1 i) < e) sequentially" + by blast + from lr2 `e > 0` have N2:"eventually (\n. dist (f (r1 (r2 n)) k) l2 < e) sequentially" + by (rule tendstoD) + from r2 N1 have N1': "eventually (\n. \i\d. dist (f (r1 (r2 n)) i) (l1 i) < e) sequentially" + by (rule eventually_subseq) + have l2: "l k = l2" + using insert.prems + by (auto simp: blinfun_of_matrix.rep_eq inner_Basis l_def mult_if_delta + scaleR_setsum_left[symmetric] setsum.delta' intro!: euclidean_eqI[where 'a='b]) + { + fix i assume "i \ d" + with insert have "i \ Basis" "i \ k" by auto + hence l1: "l i = (l1 i)" + by (auto simp: blinfun_of_matrix.rep_eq inner_Basis l_def mult_if_delta + scaleR_setsum_left[symmetric] setsum.delta' intro!: euclidean_eqI[where 'a='b]) + } note l1 = this + have "eventually (\n. \i\(insert k d). dist (f (r n) i) (l i) < e) sequentially" + using N1' N2 + by eventually_elim (insert insert.prems, auto simp: r_def o_def l1 l2) + } + ultimately show ?case by auto + qed +qed + +lemma blinfun_euclidean_eqI: "(\i. i \ Basis \ blinfun_apply x i = blinfun_apply y i) \ x = y" + apply (auto intro!: blinfun_eqI) + apply (subst (2) euclidean_representation[symmetric, where 'a='a]) + apply (subst (1) euclidean_representation[symmetric, where 'a='a]) + apply (simp add: blinfun.bilinear_simps) + done + +text {* TODO: generalize (via @{thm compact_cball})? *} +instance blinfun :: (euclidean_space, euclidean_space) heine_borel +proof + fix f :: "nat \ 'a \\<^sub>L 'b" + assume f: "bounded (range f)" + then obtain l::"'a \\<^sub>L 'b" and r where r: "subseq r" + and l: "\e>0. eventually (\n. \i\Basis. dist (f (r n) i) (l i) < e) sequentially" + using compact_blinfun_lemma [OF f] by blast + { + fix e::real + let ?d = "real_of_nat DIM('a) * real_of_nat DIM('b)" + assume "e > 0" + hence "e / ?d > 0" by (simp add: DIM_positive) + with l have "eventually (\n. \i\Basis. dist (f (r n) i) (l i) < e / ?d) sequentially" + by simp + moreover + { + fix n + assume n: "\i\Basis. dist (f (r n) i) (l i) < e / ?d" + have "norm (f (r n) - l) = norm (blinfun_of_matrix (\i j. (f (r n) - l) j \ i))" + unfolding blinfun_of_matrix_works .. + also note norm_blinfun_of_matrix + also have "(\i\Basis. \j\Basis. \(f (r n) - l) j \ i\) < + (\i\(Basis::'b set). e / real_of_nat DIM('b))" + proof (rule setsum_strict_mono) + fix i::'b assume i: "i \ Basis" + have "(\j::'a\Basis. \(f (r n) - l) j \ i\) < (\j::'a\Basis. e / ?d)" + proof (rule setsum_strict_mono) + fix j::'a assume j: "j \ Basis" + have "\(f (r n) - l) j \ i\ \ norm ((f (r n) - l) j)" + by (simp add: Basis_le_norm i) + also have "\ < e / ?d" + using n i j by (auto simp: dist_norm blinfun.bilinear_simps) + finally show "\(f (r n) - l) j \ i\ < e / ?d" by simp + qed simp_all + also have "\ \ e / real_of_nat DIM('b)" + by simp + finally show "(\j\Basis. \(f (r n) - l) j \ i\) < e / real_of_nat DIM('b)" + by simp + qed simp_all + also have "\ \ e" by simp + finally have "dist (f (r n)) l < e" + by (auto simp: dist_norm) + } + ultimately have "eventually (\n. dist (f (r n)) l < e) sequentially" + using eventually_elim2 by force + } + then have *: "((f \ r) ---> l) sequentially" + unfolding o_def tendsto_iff by simp + with r show "\l r. subseq r \ ((f \ r) ---> l) sequentially" + by auto +qed + + +subsection \concrete bounded linear functions\ + +lemma bounded_linear_bounded_bilinear_blinfun_applyI: --"TODO: transfer rule!" + assumes n: "bounded_bilinear (\i x. (blinfun_apply (f x) i))" + shows "bounded_linear f" +proof (unfold_locales, safe intro!: blinfun_eqI) + fix i + interpret bounded_bilinear "\i x. f x i" by fact + show "f (x + y) i = (f x + f y) i" "f (r *\<^sub>R x) i = (r *\<^sub>R f x) i" for r x y + by (auto intro!: blinfun_eqI simp: blinfun.bilinear_simps) + from _ nonneg_bounded show "\K. \x. norm (f x) \ norm x * K" + by (rule ex_reg) (auto intro!: onorm_bound simp: norm_blinfun.rep_eq assms ac_simps) +qed + +context bounded_bilinear +begin + +lift_definition prod_left::"'b \ 'a \\<^sub>L 'c" is "(\b a. prod a b)" + by (rule bounded_linear_left) +declare prod_left.rep_eq[simp] + +lemma bounded_linear_prod_left[bounded_linear]: "bounded_linear prod_left" + by (rule bounded_linear_bounded_bilinear_blinfun_applyI) (auto simp: bounded_bilinear_axioms) + +lift_definition prod_right::"'a \ 'b \\<^sub>L 'c" is "(\a b. prod a b)" + by (rule bounded_linear_right) +declare prod_right.rep_eq[simp] + +lemma bounded_linear_prod_right[bounded_linear]: "bounded_linear prod_right" + by (rule bounded_linear_bounded_bilinear_blinfun_applyI) (auto simp: flip) + +end + +lift_definition id_blinfun::"'a::real_normed_vector \\<^sub>L 'a" is "\x. x" + by (rule bounded_linear_ident) + +lemmas blinfun_apply_id_blinfun[simp] = id_blinfun.rep_eq + +lemma norm_blinfun_id[simp]: + "norm (id_blinfun::'a::{real_normed_vector, perfect_space} \\<^sub>L 'a) = 1" + by transfer (auto simp: onorm_id) + +lemma norm_blinfun_id_le: + "norm (id_blinfun::'a::real_normed_vector \\<^sub>L 'a) \ 1" + by transfer (auto simp: onorm_id_le) + + +lift_definition fst_blinfun::"('a::real_normed_vector \ 'b::real_normed_vector) \\<^sub>L 'a" is fst + by (rule bounded_linear_fst) + +lemma blinfun_apply_fst_blinfun[simp]: "blinfun_apply fst_blinfun = fst" + by transfer (rule refl) + + +lift_definition snd_blinfun::"('a::real_normed_vector \ 'b::real_normed_vector) \\<^sub>L 'b" is snd + by (rule bounded_linear_snd) + +lemma blinfun_apply_snd_blinfun[simp]: "blinfun_apply snd_blinfun = snd" + by transfer (rule refl) + + +lift_definition blinfun_compose:: + "'a::real_normed_vector \\<^sub>L 'b::real_normed_vector \ + 'c::real_normed_vector \\<^sub>L 'a \ + 'c \\<^sub>L 'b" (infixl "o\<^sub>L" 55) is "op o" + parametric comp_transfer + unfolding o_def + by (rule bounded_linear_compose) + +lemma blinfun_apply_blinfun_compose[simp]: "(a o\<^sub>L b) c = a (b c)" + by (simp add: blinfun_compose.rep_eq) + +lemma norm_blinfun_compose: + "norm (f o\<^sub>L g) \ norm f * norm g" + by transfer (rule onorm_compose) + +lemma bounded_bilinear_blinfun_compose[bounded_bilinear]: "bounded_bilinear op o\<^sub>L" + by unfold_locales + (auto intro!: blinfun_eqI exI[where x=1] simp: blinfun.bilinear_simps norm_blinfun_compose) + + +lift_definition blinfun_inner_right::"'a::real_inner \ 'a \\<^sub>L real" is "op \" + by (rule bounded_linear_inner_right) +declare blinfun_inner_right.rep_eq[simp] + +lemma bounded_linear_blinfun_inner_right[bounded_linear]: "bounded_linear blinfun_inner_right" + by (rule bounded_linear_bounded_bilinear_blinfun_applyI) + (auto simp: bounded_bilinear.flip[OF bounded_bilinear_inner]) + + +lift_definition blinfun_inner_left::"'a::real_inner \ 'a \\<^sub>L real" is "\x y. y \ x" + by (rule bounded_linear_inner_left) +declare blinfun_inner_left.rep_eq[simp] + +lemma bounded_linear_blinfun_inner_left[bounded_linear]: "bounded_linear blinfun_inner_left" + by (rule bounded_linear_bounded_bilinear_blinfun_applyI) (auto simp: bounded_bilinear_inner) + + +lift_definition blinfun_scaleR_right::"real \ 'a \\<^sub>L 'a::real_normed_vector" is "op *\<^sub>R" + by (rule bounded_linear_scaleR_right) +declare blinfun_scaleR_right.rep_eq[simp] + +lemma bounded_linear_blinfun_scaleR_right[bounded_linear]: "bounded_linear blinfun_scaleR_right" + by (rule bounded_linear_bounded_bilinear_blinfun_applyI) + (auto simp: bounded_bilinear.flip[OF bounded_bilinear_scaleR]) + + +lift_definition blinfun_scaleR_left::"'a::real_normed_vector \ real \\<^sub>L 'a" is "\x y. y *\<^sub>R x" + by (rule bounded_linear_scaleR_left) +lemmas [simp] = blinfun_scaleR_left.rep_eq + +lemma bounded_linear_blinfun_scaleR_left[bounded_linear]: "bounded_linear blinfun_scaleR_left" + by (rule bounded_linear_bounded_bilinear_blinfun_applyI) (auto simp: bounded_bilinear_scaleR) + + +lift_definition blinfun_mult_right::"'a \ 'a \\<^sub>L 'a::real_normed_algebra" is "op *" + by (rule bounded_linear_mult_right) +declare blinfun_mult_right.rep_eq[simp] + +lemma bounded_linear_blinfun_mult_right[bounded_linear]: "bounded_linear blinfun_mult_right" + by (rule bounded_linear_bounded_bilinear_blinfun_applyI) + (auto simp: bounded_bilinear.flip[OF bounded_bilinear_mult]) + + +lift_definition blinfun_mult_left::"'a::real_normed_algebra \ 'a \\<^sub>L 'a" is "\x y. y * x" + by (rule bounded_linear_mult_left) +lemmas [simp] = blinfun_mult_left.rep_eq + +lemma bounded_linear_blinfun_mult_left[bounded_linear]: "bounded_linear blinfun_mult_left" + by (rule bounded_linear_bounded_bilinear_blinfun_applyI) (auto simp: bounded_bilinear_mult) + +end diff -r 16bfe0a6702d -r e9812a95d108 src/HOL/Multivariate_Analysis/Derivative.thy --- a/src/HOL/Multivariate_Analysis/Derivative.thy Tue Dec 22 15:39:01 2015 +0100 +++ b/src/HOL/Multivariate_Analysis/Derivative.thy Tue Dec 22 21:58:27 2015 +0100 @@ -9,6 +9,27 @@ imports Brouwer_Fixpoint Operator_Norm Uniform_Limit begin +lemma onorm_inner_left: + assumes "bounded_linear r" + shows "onorm (\x. r x \ f) \ onorm r * norm f" +proof (rule onorm_bound) + fix x + have "norm (r x \ f) \ norm (r x) * norm f" + by (simp add: Cauchy_Schwarz_ineq2) + also have "\ \ onorm r * norm x * norm f" + by (intro mult_right_mono onorm assms norm_ge_zero) + finally show "norm (r x \ f) \ onorm r * norm f * norm x" + by (simp add: ac_simps) +qed (intro mult_nonneg_nonneg norm_ge_zero onorm_pos_le assms) + +lemma onorm_inner_right: + assumes "bounded_linear r" + shows "onorm (\x. f \ r x) \ norm f * onorm r" + apply (subst inner_commute) + apply (rule onorm_inner_left[OF assms, THEN order_trans]) + apply simp + done + declare has_derivative_bounded_linear[dest] subsection \Derivatives\ @@ -506,18 +527,6 @@ subsection \The traditional Rolle theorem in one dimension\ -lemma linear_componentwise: - fixes f:: "'a::euclidean_space \ 'b::real_inner" - assumes lf: "linear f" - shows "(f x) \ j = (\i\Basis. (x\i) * (f i\j))" (is "?lhs = ?rhs") -proof - - have "?rhs = (\i\Basis. (x\i) *\<^sub>R (f i))\j" - by (simp add: inner_setsum_left) - then show ?thesis - unfolding linear_setsum_mul[OF lf, symmetric] - unfolding euclidean_representation .. -qed - text \Derivatives of local minima and maxima are zero.\ lemma has_derivative_local_min: @@ -1714,10 +1723,6 @@ also continuous. So if we know for some other reason that the inverse function exists, it's OK.\ -lemma bounded_linear_sub: "bounded_linear f \ bounded_linear g \ bounded_linear (\x. f x - g x)" - using bounded_linear_add[of f "\x. - g x"] bounded_linear_minus[of g] - by (auto simp add: algebra_simps) - lemma has_derivative_locally_injective: fixes f :: "'n::euclidean_space \ 'm::euclidean_space" assumes "a \ s" diff -r 16bfe0a6702d -r e9812a95d108 src/HOL/Multivariate_Analysis/Integration.thy --- a/src/HOL/Multivariate_Analysis/Integration.thy Tue Dec 22 15:39:01 2015 +0100 +++ b/src/HOL/Multivariate_Analysis/Integration.thy Tue Dec 22 21:58:27 2015 +0100 @@ -9,6 +9,7 @@ Derivative Uniform_Limit "~~/src/HOL/Library/Indicator_Function" + Bounded_Linear_Function begin lemma cSup_abs_le: (* TODO: move to Conditionally_Complete_Lattices.thy? *) @@ -2797,6 +2798,16 @@ lemma integral_singleton [simp]: "integral {a} f = 0" by auto +lemma integral_blinfun_apply: + assumes "f integrable_on s" + shows "integral s (\x. blinfun_apply h (f x)) = blinfun_apply h (integral s f)" + by (subst integral_linear[symmetric, OF assms blinfun.bounded_linear_right]) (simp add: o_def) + +lemma blinfun_apply_integral: + assumes "f integrable_on s" + shows "blinfun_apply (integral s f) x = integral s (\y. blinfun_apply (f y) x)" + by (metis (no_types, lifting) assms blinfun.prod_left.rep_eq integral_blinfun_apply integral_cong) + subsection \Cauchy-type criterion for integrability.\ @@ -11280,19 +11291,6 @@ using assms(1,2) by induct auto -lemma bounded_linear_setsum: - fixes f :: "'i \ 'a::real_normed_vector \ 'b::real_normed_vector" - assumes f: "\i. i \ I \ bounded_linear (f i)" - shows "bounded_linear (\x. \i\I. f i x)" -proof (cases "finite I") - case True - from this f show ?thesis - by (induct I) (auto intro!: bounded_linear_add bounded_linear_zero) -next - case False - then show ?thesis by simp -qed - lemma absolutely_integrable_vector_abs: fixes f :: "'a::euclidean_space => 'b::euclidean_space" and T :: "'c::euclidean_space \ 'b" @@ -11598,6 +11596,241 @@ qed auto +subsection \differentiation under the integral sign\ + +lemma tube_lemma: + assumes "compact K" + assumes "open W" + assumes "{x0} \ K \ W" + shows "\X0. x0 \ X0 \ open X0 \ X0 \ K \ W" +proof - + { + fix y assume "y \ K" + then have "(x0, y) \ W" using assms by auto + with \open W\ + have "\X0 Y. open X0 \ open Y \ x0 \ X0 \ y \ Y \ X0 \ Y \ W" + by (rule open_prod_elim) blast + } then obtain X0 Y where + "\y \ K. open (X0 y) \ open (Y y) \ x0 \ X0 y \ y \ Y y \ X0 y \ Y y \ W" + by metis + moreover + then have "\t\Y ` K. open t" "K \ \(Y ` K)" by auto + with \compact K\ obtain CC where "CC \ Y ` K" "finite CC" "K \ \CC" + by (rule compactE) + moreover + then obtain c where c: + "\C. C \ CC \ c C \ K \ C = Y (c C)" + by (force intro!: choice) + ultimately show ?thesis + by (force intro!: exI[where x="\C\CC. X0 (c C)"]) +qed + +lemma eventually_closed_segment: + fixes x0::"'a::real_normed_vector" + assumes "open X0" "x0 \ X0" + shows "\\<^sub>F x in at x0 within U. closed_segment x0 x \ X0" +proof - + from openE[OF assms] + obtain e where e: "0 < e" "ball x0 e \ X0" . + then have "\\<^sub>F x in at x0 within U. x \ ball x0 e" + by (auto simp: dist_commute eventually_at) + then show ?thesis + proof eventually_elim + case (elim x) + have "x0 \ ball x0 e" using \e > 0\ by simp + from convex_ball[unfolded convex_contains_segment, rule_format, OF this elim] + have "closed_segment x0 x \ ball x0 e" . + also note \\ \ X0\ + finally show ?case . + qed +qed + +lemma leibniz_rule: + fixes f::"'a::banach \ 'b::euclidean_space \ 'c::banach" + assumes fx: "\x t. x \ U \ t \ (cbox a b) \ + ((\x. f (x, t)) has_derivative blinfun_apply (fx (x, t))) (at x within U)" + assumes integrable_f2: "\x. x \ U \ (\t. f (x, t)) integrable_on cbox a b" + assumes cont_fx: "continuous_on (U \ (cbox a b)) fx" + assumes [intro]: "x0 \ U" + assumes "convex U" + notes [continuous_intros] = continuous_on_compose2[OF cont_fx] + shows + "((\x. integral (cbox a b) (\t. f (x, t))) has_derivative integral (cbox a b) (\t. fx (x0, t))) + (at x0 within U)" + (is "(?F has_derivative ?dF) _") +proof cases + assume "content (cbox a b) \ 0" + then have ne: "cbox a b \ {}" by auto + show ?thesis + proof (intro has_derivativeI bounded_linear_scaleR_left tendstoI, fold norm_conv_dist) + have cont_f1: "\t. t \ cbox a b \ continuous_on U (\x. f (x, t))" + by (auto simp: continuous_on_eq_continuous_within intro!: has_derivative_continuous fx) + note [continuous_intros] = continuous_on_compose2[OF cont_f1] + fix e'::real + assume "e' > 0" + def e \ "e' / (content (cbox a b) + 1)" + have "e > 0" using \e' > 0\ by (auto simp: e_def intro!: divide_pos_pos add_nonneg_pos) + def psi \ "\(x, t). fx (x, t) - fx (x0, t)" + def W0 \ "{(x, t) \ U \ (cbox a b). norm (psi (x, t)) < e}" + have W0_eq: "W0 = (\(x, t). norm (psi (x, t))) -` {.. U \ (cbox a b)" + by (auto simp: vimage_def W0_def) + have "open {.. (cbox a b)) (\(x, t). norm (psi (x, t)))" + by (auto intro!: continuous_intros simp: psi_def split_beta') + from this[unfolded continuous_on_open_invariant, rule_format, OF \open {..] + obtain W where W: "open W" "W \ U \ (cbox a b) = W0 \ U \ (cbox a b)" + unfolding W0_eq by blast + have "{x0} \ (cbox a b) \ W \ U \ (cbox a b)" + unfolding W + by (auto simp: W0_def psi_def \0 < e\) + then have "{x0} \ cbox a b \ W" by blast + from tube_lemma[OF compact_cbox[of a b] \open W\ this] + obtain X0 where X0: "x0 \ X0" "open X0" "X0 \ cbox a b \ W" + by blast + + note eventually_closed_segment[OF \open X0\ \x0 \ X0\, of U] + moreover + have "\\<^sub>F x in at x0 within U. x \ X0" + using \open X0\ \x0 \ X0\ eventually_at_topological by blast + moreover have "\\<^sub>F x in at x0 within U. x \ x0" + by (auto simp: eventually_at_filter) + moreover have "\\<^sub>F x in at x0 within U. x \ U" + by (auto simp: eventually_at_filter) + ultimately + show "\\<^sub>F x in at x0 within U. norm ((?F x - ?F x0 - ?dF (x - x0)) /\<^sub>R norm (x - x0)) < e'" + proof eventually_elim + case (elim x) + from elim have "0 < norm (x - x0)" by simp + have "closed_segment x0 x \ U" + by (rule \convex U\[unfolded convex_contains_segment, rule_format, OF \x0 \ U\ \x \ U\]) + from elim have [intro]: "x \ U" by auto + + have "?F x - ?F x0 - ?dF (x - x0) = + integral (cbox a b) (\xa. f (x, xa) - f (x0, xa) - fx (x0, xa) (x - x0))" + (is "_ = ?id") + using \x \ x0\ + by (subst blinfun_apply_integral integral_diff, + auto intro!: integrable_diff integrable_f2 continuous_intros + intro: integrable_continuous)+ + also + { + fix t assume t: "t \ (cbox a b)" + have seg: "\t. t \ {0..1} \ x0 + t *\<^sub>R (x - x0) \ closed_segment x0 x \ U" + using \closed_segment x0 x \ U\ + by (force simp: closed_segment_def algebra_simps) + from t have deriv: + "((\x. f (x, t)) has_derivative (fx (y, t))) (at y within closed_segment x0 x \ U)" + if "y \ closed_segment x0 x \ U" for y + unfolding has_vector_derivative_def[symmetric] + using that \x \ X0\ + by (intro has_derivative_within_subset[OF fx]) auto + have "\x\closed_segment x0 x \ U. norm (fx (x, t) - fx (x0, t)) \ e" + proof + fix y assume y: "y \ closed_segment x0 x \ U" + have "norm (fx (y, t) - fx (x0, t)) = norm (psi (y, t))" + by (auto simp: psi_def) + also + { + have "(y, t) \ X0 \ (cbox a b)" + using t \closed_segment x0 x \ X0\ y + by auto + also note \\ \ W\ + finally have "(y, t) \ W" . + with t y have "(y, t) \ W \ U \ (cbox a b)" + by blast + also note \W \ U \ (cbox a b) = W0 \ U \ (cbox a b)\ + finally have "norm (psi (y, t)) < e" + by (auto simp: W0_def) + } + finally show "norm (fx (y, t) - fx (x0, t)) \ e" by simp + qed + then have onorm: + "\x\closed_segment x0 x \ U. + onorm (blinfun_apply (fx (x, t)) - blinfun_apply (fx (x0, t))) \ e" + by (auto simp: norm_blinfun.rep_eq blinfun.diff_left[abs_def] fun_diff_def) + + from differentiable_bound_linearization[OF seg deriv onorm] + have "norm (f (x, t) - f (x0, t) - fx (x0, t) (x - x0)) \ e * norm (x - x0)" + by (auto simp add: ac_simps) + } + then have "norm ?id \ integral (cbox a b) (\_. e * norm (x - x0))" + by (intro integral_norm_bound_integral) + (auto intro!: continuous_intros integrable_diff integrable_f2 + intro: integrable_continuous) + also have "\ = content (cbox a b) * e * norm (x - x0)" + by simp + also have "\ < e' * norm (x - x0)" + using \e' > 0\ content_pos_le[of a b] + by (intro mult_strict_right_mono[OF _ \0 < norm (x - x0)\]) + (auto simp: divide_simps e_def) + finally have "norm (?F x - ?F x0 - ?dF (x - x0)) < e' * norm (x - x0)" . + then show ?case + by (auto simp: divide_simps) + qed + qed (rule blinfun.bounded_linear_right) +qed (auto intro!: derivative_eq_intros simp: blinfun.bilinear_simps) + +lemma + has_vector_derivative_eq_has_derivative_blinfun: + "(f has_vector_derivative f') (at x within U) \ + (f has_derivative blinfun_scaleR_left f') (at x within U)" + by (simp add: has_vector_derivative_def) + +lemma leibniz_rule_vector_derivative: + fixes f::"real \ 'b::euclidean_space \ 'c::banach" + assumes fx: "\x t. x \ U \ t \ (cbox a b) \ + ((\x. f (x, t)) has_vector_derivative (fx (x, t))) (at x within U)" + assumes integrable_f2: "\x. x \ U \ (\t. f (x, t)) integrable_on cbox a b" + assumes cont_fx: "continuous_on (U \ (cbox a b)) fx" + assumes U: "x0 \ U" "convex U" + notes [continuous_intros] = continuous_on_compose2[OF cont_fx] + shows + "((\x. integral (cbox a b) (\t. f (x, t))) has_vector_derivative + integral (cbox a b) (\t. fx (x0, t))) (at x0 within U)" +proof - + have *: "blinfun_scaleR_left (integral (cbox a b) (\t. fx (x0, t))) = + integral (cbox a b) (\t. blinfun_scaleR_left (fx (x0, t)))" + by (subst integral_linear[symmetric]) + (auto simp: has_vector_derivative_def o_def + intro!: integrable_continuous U continuous_intros bounded_linear_intros) + show ?thesis + unfolding has_vector_derivative_eq_has_derivative_blinfun + apply (rule has_derivative_eq_rhs) + apply (rule leibniz_rule[OF _ integrable_f2 _ U, where fx="\x. blinfun_scaleR_left (fx x)"]) + using assms(1) + apply (auto simp: has_vector_derivative_def * intro!: continuous_intros) + done +qed + +lemma + has_field_derivative_eq_has_derivative_blinfun: + "(f has_field_derivative f') (at x within U) \ (f has_derivative blinfun_mult_right f') (at x within U)" + by (simp add: has_field_derivative_def) + +lemma leibniz_rule_field_derivative: + fixes f::"'a::{real_normed_field, banach} \ 'b::euclidean_space \ 'a" + assumes fx: "\x t. x \ U \ t \ (cbox a b) \ ((\x. f (x, t)) has_field_derivative (fx (x, t))) (at x within U)" + assumes integrable_f2: "\x. x \ U \ (\t. f (x, t)) integrable_on cbox a b" + assumes cont_fx: "continuous_on (U \ (cbox a b)) fx" + assumes U: "x0 \ U" "convex U" + notes [continuous_intros] = continuous_on_compose2[OF cont_fx] + shows "((\x. integral (cbox a b) (\t. f (x, t))) has_field_derivative integral (cbox a b) (\t. fx (x0, t))) (at x0 within U)" +proof - + have *: "blinfun_mult_right (integral (cbox a b) (\t. fx (x0, t))) = + integral (cbox a b) (\t. blinfun_mult_right (fx (x0, t)))" + by (subst integral_linear[symmetric]) + (auto simp: has_vector_derivative_def o_def + intro!: integrable_continuous U continuous_intros bounded_linear_intros) + show ?thesis + unfolding has_field_derivative_eq_has_derivative_blinfun + apply (rule has_derivative_eq_rhs) + apply (rule leibniz_rule[OF _ integrable_f2 _ U, where fx="\x. blinfun_mult_right (fx x)"]) + using assms(1) + apply (auto simp: has_field_derivative_def * intro!: continuous_intros) + done +qed + + subsection \Exchange uniform limit and integral\ lemma diff -r 16bfe0a6702d -r e9812a95d108 src/HOL/Multivariate_Analysis/Linear_Algebra.thy --- a/src/HOL/Multivariate_Analysis/Linear_Algebra.thy Tue Dec 22 15:39:01 2015 +0100 +++ b/src/HOL/Multivariate_Analysis/Linear_Algebra.thy Tue Dec 22 21:58:27 2015 +0100 @@ -314,6 +314,18 @@ shows "f (a *\<^sub>R x + b *\<^sub>R y) = a *\<^sub>R f x + b *\<^sub>R f y" using linear_add[of f] linear_cmul[of f] assms by simp +lemma linear_componentwise: + fixes f:: "'a::euclidean_space \ 'b::real_inner" + assumes lf: "linear f" + shows "(f x) \ j = (\i\Basis. (x\i) * (f i\j))" (is "?lhs = ?rhs") +proof - + have "?rhs = (\i\Basis. (x\i) *\<^sub>R (f i))\j" + by (simp add: inner_setsum_left) + then show ?thesis + unfolding linear_setsum_mul[OF lf, symmetric] + unfolding euclidean_representation .. +qed + subsection \Bilinear functions.\ diff -r 16bfe0a6702d -r e9812a95d108 src/HOL/Multivariate_Analysis/Operator_Norm.thy --- a/src/HOL/Multivariate_Analysis/Operator_Norm.thy Tue Dec 22 15:39:01 2015 +0100 +++ b/src/HOL/Multivariate_Analysis/Operator_Norm.thy Tue Dec 22 21:58:27 2015 +0100 @@ -96,6 +96,20 @@ shows "0 < onorm f \ \ (\x. f x = 0)" by (simp add: less_le onorm_pos_le [OF f] onorm_eq_0 [OF f]) +lemma onorm_id_le: "onorm (\x. x) \ 1" + by (rule onorm_bound) simp_all + +lemma onorm_id: "onorm (\x. x::'a::{real_normed_vector, perfect_space}) = 1" +proof (rule antisym[OF onorm_id_le]) + have "{0::'a} \ UNIV" by (metis not_open_singleton open_UNIV) + then obtain x :: 'a where "x \ 0" by fast + hence "1 \ norm x / norm x" + by simp + also have "\ \ onorm (\x::'a. x)" + by (rule le_onorm) (rule bounded_linear_ident) + finally show "1 \ onorm (\x::'a. x)" . +qed + lemma onorm_compose: assumes f: "bounded_linear f" assumes g: "bounded_linear g" @@ -146,6 +160,46 @@ qed qed (simp add: onorm_zero) +lemma onorm_scaleR_left_lemma: + assumes r: "bounded_linear r" + shows "onorm (\x. r x *\<^sub>R f) \ onorm r * norm f" +proof (rule onorm_bound) + fix x + have "norm (r x *\<^sub>R f) = norm (r x) * norm f" + by simp + also have "\ \ onorm r * norm x * norm f" + by (intro mult_right_mono onorm r norm_ge_zero) + finally show "norm (r x *\<^sub>R f) \ onorm r * norm f * norm x" + by (simp add: ac_simps) +qed (intro mult_nonneg_nonneg norm_ge_zero onorm_pos_le r) + +lemma onorm_scaleR_left: + assumes f: "bounded_linear r" + shows "onorm (\x. r x *\<^sub>R f) = onorm r * norm f" +proof (cases "f = 0") + assume "f \ 0" + show ?thesis + proof (rule order_antisym) + show "onorm (\x. r x *\<^sub>R f) \ onorm r * norm f" + using f by (rule onorm_scaleR_left_lemma) + next + have bl1: "bounded_linear (\x. r x *\<^sub>R f)" + by (metis bounded_linear_scaleR_const f) + have "bounded_linear (\x. r x * norm f)" + by (metis bounded_linear_mult_const f) + from onorm_scaleR_left_lemma[OF this, of "inverse (norm f)"] + have "onorm r \ onorm (\x. r x * norm f) * inverse (norm f)" + using `f \ 0` + by (simp add: inverse_eq_divide) + also have "onorm (\x. r x * norm f) \ onorm (\x. r x *\<^sub>R f)" + by (rule onorm_bound) + (auto simp: abs_mult bl1 onorm_pos_le intro!: order_trans[OF _ onorm]) + finally show "onorm r * norm f \ onorm (\x. r x *\<^sub>R f)" + using `f \ 0` + by (simp add: inverse_eq_divide pos_le_divide_eq mult.commute) + qed +qed (simp add: onorm_zero) + lemma onorm_neg: shows "onorm (\x. - f x) = onorm f" unfolding onorm_def by simp diff -r 16bfe0a6702d -r e9812a95d108 src/HOL/Multivariate_Analysis/Topology_Euclidean_Space.thy --- a/src/HOL/Multivariate_Analysis/Topology_Euclidean_Space.thy Tue Dec 22 15:39:01 2015 +0100 +++ b/src/HOL/Multivariate_Analysis/Topology_Euclidean_Space.thy Tue Dec 22 21:58:27 2015 +0100 @@ -5388,6 +5388,24 @@ unfolding uniformly_continuous_on_def by blast qed +lemma continuous_on_tendsto_compose: + assumes f_cont: "continuous_on s f" + assumes g: "(g ---> l) F" + assumes l: "l \ s" + assumes ev: "\\<^sub>F x in F. g x \ s" + shows "((\x. f (g x)) ---> f l) F" +proof - + from f_cont have f: "(f ---> f l) (at l within s)" + by (auto simp: l continuous_on) + have i: "((\x. if g x = l then f l else f (g x)) ---> f l) F" + by (rule filterlim_If) + (auto intro!: filterlim_compose[OF f] eventually_conj tendsto_mono[OF _ g] + simp: filterlim_at eventually_inf_principal eventually_mono[OF ev]) + show ?thesis + by (rule filterlim_cong[THEN iffD1[OF _ i]]) auto +qed + + text\The usual transformation theorems.\ lemma continuous_transform_within: @@ -8451,18 +8469,8 @@ lemma cball_eq_ball_iff: fixes x :: "'a :: euclidean_space" - shows "cball x d = ball y e \ d < 0 \ e \ 0" (is "?lhs = ?rhs") -proof - assume ?lhs - then show ?rhs - apply (auto simp add: set_eq_subset ball_subset_cball_iff cball_subset_ball_iff algebra_simps) - apply (metis add_increasing2 add_le_cancel_right add_less_same_cancel1 dist_not_less_zero less_le_trans zero_le_dist) - apply (metis add_less_same_cancel1 dist_not_less_zero less_le_trans not_le) - using \?lhs\ ball_eq_empty cball_eq_empty apply blast+ - done -next - assume ?rhs then show ?lhs using ball_eq_cball_iff by blast -qed + shows "cball x d = ball y e \ d < 0 \ e \ 0" + using ball_eq_cball_iff by blast no_notation eucl_less (infix "i. prod (g i) x)) S" +by (rule additive.setsum [OF additive_left]) + +lemma setsum_right: + "prod x (setsum g S) = setsum ((\i. (prod x (g i)))) S" +by (rule additive.setsum [OF additive_right]) + + lemma bounded_linear_left: "bounded_linear (\a. a ** b)" apply (cut_tac bounded, safe) @@ -1463,6 +1472,21 @@ done qed +lemma bounded_linear_sub: "bounded_linear f \ bounded_linear g \ bounded_linear (\x. f x - g x)" + using bounded_linear_add[of f "\x. - g x"] bounded_linear_minus[of g] + by (auto simp add: algebra_simps) + +lemma bounded_linear_setsum: + fixes f :: "'i \ 'a::real_normed_vector \ 'b::real_normed_vector" + assumes "\i. i \ I \ bounded_linear (f i)" + shows "bounded_linear (\x. \i\I. f i x)" +proof cases + assume "finite I" + from this show ?thesis + using assms + by (induct I) (auto intro!: bounded_linear_add) +qed simp + lemma bounded_linear_compose: assumes "bounded_linear f" assumes "bounded_linear g" @@ -1543,6 +1567,12 @@ using bounded_bilinear_scaleR by (rule bounded_bilinear.bounded_linear_right) +lemmas bounded_linear_scaleR_const = + bounded_linear_scaleR_left[THEN bounded_linear_compose] + +lemmas bounded_linear_const_scaleR = + bounded_linear_scaleR_right[THEN bounded_linear_compose] + lemma bounded_linear_of_real: "bounded_linear (\r. of_real r)" unfolding of_real_def by (rule bounded_linear_scaleR_left)