# HG changeset patch # User immler # Date 1430844310 -7200 # Node ID f620c70f9e9b2be862e30b5f424d4faa4b04d07d # Parent 2bfcb83531c6622f1d8481707a175610bee78bd4 generalized differentiable_bound; some further variations of differentiable_bound diff -r 2bfcb83531c6 -r f620c70f9e9b src/HOL/Library/Convex.thy --- a/src/HOL/Library/Convex.thy Tue May 05 18:45:10 2015 +0200 +++ b/src/HOL/Library/Convex.thy Tue May 05 18:45:10 2015 +0200 @@ -389,6 +389,16 @@ using `convex s` by (rule convex_linear_image) qed +lemma convex_scaled: + assumes "convex s" + shows "convex ((\x. x *\<^sub>R c) ` s)" +proof - + have "linear (\x. x *\<^sub>R c)" + by (simp add: linearI scaleR_add_left) + then show ?thesis + using `convex s` by (rule convex_linear_image) +qed + lemma convex_negations: assumes "convex s" shows "convex ((\x. - x) ` s)" diff -r 2bfcb83531c6 -r f620c70f9e9b src/HOL/Multivariate_Analysis/Derivative.thy --- a/src/HOL/Multivariate_Analysis/Derivative.thy Tue May 05 18:45:10 2015 +0200 +++ b/src/HOL/Multivariate_Analysis/Derivative.thy Tue May 05 18:45:10 2015 +0200 @@ -779,10 +779,225 @@ qed qed -text {* Still more general bound theorem. *} + +subsection {* More general bound theorems *} + +lemma differentiable_bound_general: + fixes f :: "real \ 'a::real_normed_vector" + assumes "a < b" + and f_cont: "continuous_on {a .. b} f" + and phi_cont: "continuous_on {a .. b} \" + and f': "\x. a < x \ x < b \ (f has_vector_derivative f' x) (at x)" + and phi': "\x. a < x \ x < b \ (\ has_vector_derivative \' x) (at x)" + and bnd: "\x. a < x \ x < b \ norm (f' x) \ \' x" + shows "norm (f b - f a) \ \ b - \ a" +proof - + { + fix x assume x: "a < x" "x < b" + have "0 \ norm (f' x)" by simp + also have "\ \ \' x" using x by (auto intro!: bnd) + finally have "0 \ \' x" . + } note phi'_nonneg = this + note f_tendsto = assms(2)[simplified continuous_on_def, rule_format] + note phi_tendsto = assms(3)[simplified continuous_on_def, rule_format] + { + fix e::real assume "e > 0" + def e2 \ "e / 2" with `e > 0` have "e2 > 0" by simp + let ?le = "\x1. norm (f x1 - f a) \ \ x1 - \ a + e * (x1 - a) + e" + def A \ "{x2. a \ x2 \ x2 \ b \ (\x1\{a ..< x2}. ?le x1)}" + have A_subset: "A \ {a .. b}" by (auto simp: A_def) + { + fix x2 + assume a: "a \ x2" "x2 \ b" and le: "\x1\{a.. 0` + proof cases + assume "x2 \ a" with a have "a < x2" by simp + have "at x2 within {a <.. bot" + using `a < x2` + by (auto simp: trivial_limit_within islimpt_in_closure) + moreover + have "((\x1. (\ x1 - \ a) + e * (x1 - a) + e) ---> (\ x2 - \ a) + e * (x2 - a) + e) (at x2 within {a <..x1. norm (f x1 - f a)) ---> norm (f x2 - f a)) (at x2 within {a <..x. x > a) (at x2 within {a <.. A" + using assms by (auto simp: A_def) + hence [simp]: "A \ {}" by auto + have A_ivl: "\x1 x2. x2 \ A \ x1 \ {a ..x2} \ x1 \ A" + by (simp add: A_def) + have [simp]: "bdd_above A" by (auto simp: A_def) + def y \ "Sup A" + have "y \ b" + unfolding y_def + by (simp add: cSup_le_iff) (simp add: A_def) + have leI: "\x x1. a \ x1 \ x \ A \ x1 < x \ ?le x1" + by (auto simp: A_def intro!: le_cont) + have y_all_le: "\x1\{a.. y" + by (metis `a \ A` `bdd_above A` cSup_upper y_def) + have "y \ A" + using y_all_le `a \ y` `y \ b` + by (auto simp: A_def) + hence "A = {a .. y}" + using A_subset + by (auto simp: subset_iff y_def cSup_upper intro: A_ivl) + from le_cont[OF `a \ y` `y \ b` y_all_le] have le_y: "?le y" . + { + assume "a \ y" with `a \ y` have "a < y" by simp + have "y = b" + proof (rule ccontr) + assume "y \ b" + hence "y < b" using `y \ b` by simp + let ?F = "at y within {y.. has_vector_derivative \' y) ?F" + using `a < y` `y < b` + by (auto simp add: at_within_open[of _ "{a<..\<^sub>F x1 in ?F. norm (f x1 - f y - (x1 - y) *\<^sub>R f' y) \ e2 * \x1 - y\" + "\\<^sub>F x1 in ?F. norm (\ x1 - \ y - (x1 - y) *\<^sub>R \' y) \ e2 * \x1 - y\" + using `e2 > 0` + by (auto simp: has_derivative_within_alt2 has_vector_derivative_def) + moreover + have "\\<^sub>F x1 in ?F. y \ x1" "\\<^sub>F x1 in ?F. x1 < b" + by (auto simp: eventually_at_filter) + ultimately + have "\\<^sub>F x1 in ?F. norm (f x1 - f y) \ (\ x1 - \ y) + e * \x1 - y\" + (is "\\<^sub>F x1 in ?F. ?le' x1") + proof eventually_elim + case elim + from norm_triangle_ineq2[THEN order_trans, OF elim(1)] + have "norm (f x1 - f y) \ norm (f' y) * \x1 - y\ + e2 * \x1 - y\" + by (simp add: ac_simps) + also have "norm (f' y) \ \' y" using bnd `a < y` `y < b` by simp + also + from elim have "\' y * \x1 - y\ \ \ x1 - \ y + e2 * \x1 - y\" + by (simp add: ac_simps) + finally + have "norm (f x1 - f y) \ \ x1 - \ y + e2 * \x1 - y\ + e2 * \x1 - y\" + by (auto simp: mult_right_mono) + thus ?case by (simp add: e2_def) + qed + moreover have "?le' y" by simp + ultimately obtain S + where S: "open S" "y \ S" "\x. x\S \ x \ {y.. ?le' x" + unfolding eventually_at_topological + by metis + from `open S` obtain d where d: "\x. dist x y < d \ x \ S" "d > 0" + by (force simp: dist_commute open_real_def ball_def + dest!: bspec[OF _ `y \ S`]) + def d' \ "min ((y + b)/2) (y + (d/2))" + have "d' \ A" + unfolding A_def + proof safe + show "a \ d'" using `a < y` `0 < d` `y < b` by (simp add: d'_def) + show "d' \ b" using `y < b` by (simp add: d'_def min_def) + fix x1 + assume x1: "x1 \ {a.. {a.. y" + hence x1': "x1 \ S" "x1 \ {y.. norm (f x1 - f y) + norm (f y - f a)" + by (rule order_trans[OF _ norm_triangle_ineq]) simp + also note S(3)[OF x1'] + also note le_y + finally have "?le x1" + using `x1 \ y` by (auto simp: algebra_simps) + } ultimately show "?le x1" by arith + qed + hence "d' \ y" + unfolding y_def + by (rule cSup_upper) simp + thus False using `d > 0` `y < b` + by (simp add: d'_def min_def split: split_if_asm) + qed + } moreover { + assume "a = y" + with `a < b` have "y < b" by simp + with `a = y` f_cont phi_cont `e2 > 0` + have 1: "\\<^sub>F x in at y within {y..b}. dist (f x) (f y) < e2" + and 2: "\\<^sub>F x in at y within {y..b}. dist (\ x) (\ y) < e2" + by (auto simp: continuous_on_def tendsto_iff) + have 3: "eventually (\x. y < x) (at y within {y..b})" + by (auto simp: eventually_at_filter) + have 4: "eventually (\x::real. x < b) (at y within {y..b})" + using _ `y < b` + by (rule order_tendstoD) (auto intro!: tendsto_eq_intros) + from 1 2 3 4 + have eventually_le: "eventually (\x. ?le x) (at y within {y .. b})" + proof eventually_elim + case (elim x1) + have "norm (f x1 - f a) = norm (f x1 - f y)" + by (simp add: `a = y`) + also have "norm (f x1 - f y) \ e2" + using elim `a = y` by (auto simp : dist_norm intro!: less_imp_le) + also have "\ \ e2 + (\ x1 - \ a + e2 + e * (x1 - a))" + using `0 < e` elim + by (intro add_increasing2[OF add_nonneg_nonneg order.refl]) + (auto simp: `a = y` dist_norm intro!: mult_nonneg_nonneg) + also have "\ = \ x1 - \ a + e * (x1 - a) + e" + by (simp add: e2_def) + finally show "?le x1" . + qed + from this[unfolded eventually_at_topological] `?le y` + obtain S + where S: "open S" "y \ S" "\x. x\S \ x \ {y..b} \ ?le x" + by metis + from `open S` obtain d where d: "\x. dist x y < d \ x \ S" "d > 0" + by (force simp: dist_commute open_real_def ball_def + dest!: bspec[OF _ `y \ S`]) + def d' \ "min b (y + (d/2))" + have "d' \ A" + unfolding A_def + proof safe + show "a \ d'" using `a = y` `0 < d` `y < b` by (simp add: d'_def) + show "d' \ b" by (simp add: d'_def) + fix x1 + assume "x1 \ {a.. S" "x1 \ {y..b}" + by (auto simp: `a = y` d'_def dist_real_def intro!: d ) + thus "?le x1" + by (rule S) + qed + hence "d' \ y" + unfolding y_def + by (rule cSup_upper) simp + hence "y = b" using `d > 0` `y < b` + by (simp add: d'_def) + } ultimately have "y = b" + by auto + with le_y have "norm (f b - f a) \ \ b - \ a + e * (b - a + 1)" + by (simp add: algebra_simps) + } note * = this + { + fix e::real assume "e > 0" + hence "norm (f b - f a) \ \ b - \ a + e" + using *[of "e / (b - a + 1)"] `a < b` by simp + } thus ?thesis + by (rule field_le_epsilon) +qed lemma differentiable_bound: - fixes f :: "'a::real_normed_vector \ 'b::real_inner" + fixes f :: "'a::real_normed_vector \ 'b::real_normed_vector" assumes "convex s" and "\x\s. (f has_derivative f' x) (at x within s)" and "\x\s. onorm (f' x) \ B" @@ -791,14 +1006,15 @@ shows "norm (f x - f y) \ B * norm (x - y)" proof - let ?p = "\u. x + u *\<^sub>R (y - x)" + let ?\ = "\h. h * B * norm (x - y)" have *: "\u. u\{0..1} \ x + u *\<^sub>R (y - x) \ s" using assms(1)[unfolded convex_alt,rule_format,OF x y] unfolding scaleR_left_diff_distrib scaleR_right_diff_distrib by (auto simp add: algebra_simps) - then have 1: "continuous_on {0 .. 1} (f \ ?p)" + have 0: "continuous_on (?p ` {0..1}) f" + using * + unfolding continuous_on_eq_continuous_within apply - - apply (rule continuous_intros)+ - unfolding continuous_on_eq_continuous_within apply rule apply (rule differentiable_imp_continuous_within) unfolding differentiable_def @@ -807,51 +1023,93 @@ apply (rule assms(2)[rule_format]) apply auto done - have 2: "\u\{0 <..< 1}. - ((f \ ?p) has_derivative f' (x + u *\<^sub>R (y - x)) \ (\u. 0 + u *\<^sub>R (y - x))) (at u)" - proof rule - case goal1 - let ?u = "x + u *\<^sub>R (y - x)" + from * have 1: "continuous_on {0 .. 1} (f \ ?p)" + by (intro continuous_intros 0)+ + { + fix u::real assume u: "u \{0 <..< 1}" + let ?u = "?p u" + interpret linear "(f' ?u)" + using u by (auto intro!: has_derivative_linear assms(2)[rule_format] *) have "(f \ ?p has_derivative (f' ?u) \ (\u. 0 + u *\<^sub>R (y - x))) (at u within box 0 1)" apply (rule diff_chain_within) apply (rule derivative_intros)+ apply (rule has_derivative_within_subset) apply (rule assms(2)[rule_format]) - using goal1 * + using u * apply auto done - then show ?case - by (simp add: has_derivative_within_open[OF goal1 open_greaterThanLessThan]) - qed - obtain u where u: - "u \ {0<..<1}" - "norm ((f \ (\u. x + u *\<^sub>R (y - x))) 1 - (f \ (\u. x + u *\<^sub>R (y - x))) 0) - \ norm ((f' (x + u *\<^sub>R (y - x)) \ (\u. 0 + u *\<^sub>R (y - x))) (1 - 0))" - using mvt_general[OF zero_less_one 1 2] .. - have **: "\x y. x \ s \ norm (f' x y) \ B * norm y" - proof - - case goal1 - have "norm (f' x y) \ onorm (f' x) * norm y" - by (rule onorm[OF has_derivative_bounded_linear[OF assms(2)[rule_format,OF goal1]]]) - also have "\ \ B * norm y" - apply (rule mult_right_mono) - using assms(3)[rule_format,OF goal1] - apply (auto simp add: field_simps) - done - finally show ?case - by simp - qed + hence "((f \ ?p) has_vector_derivative f' ?u (y - x)) (at u)" + by (simp add: has_derivative_within_open[OF u open_greaterThanLessThan] + scaleR has_vector_derivative_def o_def) + } note 2 = this + { + have "continuous_on {0..1} ?\" + by (rule continuous_intros)+ + } note 3 = this + { + fix u::real assume u: "u \{0 <..< 1}" + have "(?\ has_vector_derivative B * norm (x - y)) (at u)" + by (auto simp: has_vector_derivative_def intro!: derivative_eq_intros) + } note 4 = this + { + fix u::real assume u: "u \{0 <..< 1}" + let ?u = "?p u" + interpret bounded_linear "(f' ?u)" + using u by (auto intro!: has_derivative_bounded_linear assms(2)[rule_format] *) + have "norm (f' ?u (y - x)) \ onorm (f' ?u) * norm (y - x)" + by (rule onorm) fact + also have "onorm (f' ?u) \ B" + using u by (auto intro!: assms(3)[rule_format] *) + finally have "norm ((f' ?u) (y - x)) \ B * norm (x - y)" + by (simp add: mult_right_mono norm_minus_commute) + } note 5 = this have "norm (f x - f y) = norm ((f \ (\u. x + u *\<^sub>R (y - x))) 1 - (f \ (\u. x + u *\<^sub>R (y - x))) 0)" by (auto simp add: norm_minus_commute) - also have "\ \ norm (f' (x + u *\<^sub>R (y - x)) (y - x))" - using u by auto - also have "\ \ B * norm(y - x)" - apply (rule **) - using * and u - apply auto - done - finally show ?thesis - by (auto simp add: norm_minus_commute) + also + from differentiable_bound_general[OF zero_less_one 1, OF 3 2 4 5] + have "norm ((f \ ?p) 1 - (f \ ?p) 0) \ B * norm (x - y)" + by simp + finally show ?thesis . +qed + +lemma + differentiable_bound_segment: + fixes f::"'a::real_normed_vector \ 'b::real_normed_vector" + assumes "\t. t \ {0..1} \ x0 + t *\<^sub>R a \ G" + assumes f': "\x. x \ G \ (f has_derivative f' x) (at x within G)" + assumes B: "\x\{0..1}. onorm (f' (x0 + x *\<^sub>R a)) \ B" + shows "norm (f (x0 + a) - f x0) \ norm a * B" +proof - + let ?G = "(\x. x0 + x *\<^sub>R a) ` {0..1}" + have "?G = op + x0 ` (\x. x *\<^sub>R a) ` {0..1}" by auto + also have "convex \" + by (intro convex_translation convex_scaled convex_real_interval) + finally have "convex ?G" . + moreover have "?G \ G" "x0 \ ?G" "x0 + a \ ?G" using assms by (auto intro: image_eqI[where x=1]) + ultimately show ?thesis + using has_derivative_subset[OF f' `?G \ G`] B + differentiable_bound[of "(\x. x0 + x *\<^sub>R a) ` {0..1}" f f' B "x0 + a" x0] + by (auto simp: ac_simps) +qed + +lemma differentiable_bound_linearization: + fixes f::"'a::real_normed_vector \ 'b::real_normed_vector" + assumes "\t. t \ {0..1} \ a + t *\<^sub>R (b - a) \ S" + assumes f'[derivative_intros]: "\x. x \ S \ (f has_derivative f' x) (at x within S)" + assumes B: "\x\S. onorm (f' x - f' x0) \ B" + assumes "x0 \ S" + shows "norm (f b - f a - f' x0 (b - a)) \ norm (b - a) * B" +proof - + def g \ "\x. f x - f' x0 x" + have g: "\x. x \ S \ (g has_derivative (\i. f' x i - f' x0 i)) (at x within S)" + unfolding g_def using assms + by (auto intro!: derivative_eq_intros + bounded_linear.has_derivative[OF has_derivative_bounded_linear, OF f']) + from B have B: "\x\{0..1}. onorm (\i. f' (a + x *\<^sub>R (b - a)) i - f' x0 i) \ B" + using assms by (auto simp: fun_diff_def) + from differentiable_bound_segment[OF assms(1) g B] `x0 \ S` + show ?thesis + by (simp add: g_def field_simps linear_sub[OF has_derivative_linear[OF f']]) qed text {* In particular. *}