# HG changeset patch # User huffman # Date 1394813373 25200 # Node ID 304e37faf1ac9aca2ed7b3fbc64243b117720059 # Parent 64eeda68e693fde78ab28318ec791c51c16d5eb5 generalization of differential_zero_maxmin to class real_normed_vector diff -r 64eeda68e693 -r 304e37faf1ac src/HOL/Multivariate_Analysis/Derivative.thy --- a/src/HOL/Multivariate_Analysis/Derivative.thy Fri Mar 14 12:09:51 2014 +0100 +++ b/src/HOL/Multivariate_Analysis/Derivative.thy Fri Mar 14 09:09:33 2014 -0700 @@ -617,110 +617,84 @@ unfolding euclidean_representation .. qed -text {* We do not introduce @{text jacobian}, which is defined on matrices, instead we use - the unfolding of it. *} +text {* Derivatives of local minima and maxima are zero. *} -lemma jacobian_works: - fixes f :: "'a::euclidean_space \ 'b::euclidean_space" - shows "f differentiable net \ - (f has_derivative (\h. \i\Basis. - (\j\Basis. frechet_derivative f net j \ i * (h \ j)) *\<^sub>R i)) net" - (is "?differentiable \ (f has_derivative (\h. \i\Basis. ?SUM h i *\<^sub>R i)) net") +lemma has_derivative_local_min: + fixes f :: "'a::real_normed_vector \ real" + assumes deriv: "(f has_derivative f') (at x)" + assumes min: "eventually (\y. f x \ f y) (at x)" + shows "f' = (\h. 0)" proof - assume *: ?differentiable - { - fix h i - have "?SUM h i = frechet_derivative f net h \ i" - using * - by (auto intro!: setsum_cong simp: linear_componentwise[of _ h i] linear_frechet_derivative) - } - with * show "(f has_derivative (\h. \i\Basis. ?SUM h i *\<^sub>R i)) net" - by (simp add: frechet_derivative_works euclidean_representation) -qed (auto intro!: differentiableI) + fix h :: 'a + interpret f': bounded_linear f' + using deriv by (rule FDERIV_bounded_linear) + show "f' h = 0" + proof (cases "h = 0") + assume "h \ 0" + from min obtain d where d1: "0 < d" and d2: "\y\ball x d. f x \ f y" + unfolding eventually_at by (force simp: dist_commute) + have "FDERIV (\r. x + r *\<^sub>R h) 0 :> (\r. r *\<^sub>R h)" + by (intro FDERIV_eq_intros, auto) + then have "FDERIV (\r. f (x + r *\<^sub>R h)) 0 :> (\k. f' (k *\<^sub>R h))" + by (rule FDERIV_compose, simp add: deriv) + then have "DERIV (\r. f (x + r *\<^sub>R h)) 0 :> f' h" + unfolding deriv_fderiv by (simp add: f'.scaleR) + moreover have "0 < d / norm h" + using d1 and `h \ 0` by (simp add: divide_pos_pos) + moreover have "\y. \0 - y\ < d / norm h \ f (x + 0 *\<^sub>R h) \ f (x + y *\<^sub>R h)" + using `h \ 0` by (auto simp add: d2 dist_norm pos_less_divide_eq) + ultimately show "f' h = 0" + by (rule DERIV_local_min) + qed (simp add: f'.zero) +qed -lemma differential_zero_maxmin_component: +lemma has_derivative_local_max: + fixes f :: "'a::real_normed_vector \ real" + assumes "(f has_derivative f') (at x)" + assumes "eventually (\y. f y \ f x) (at x)" + shows "f' = (\h. 0)" + using has_derivative_local_min [of "\x. - f x" "\h. - f' h" "x"] + using assms unfolding fun_eq_iff by simp + +lemma differential_zero_maxmin: + fixes f::"'a::real_normed_vector \ real" + assumes "x \ s" + and "open s" + and deriv: "(f has_derivative f') (at x)" + and mono: "(\y\s. f y \ f x) \ (\y\s. f x \ f y)" + shows "f' = (\v. 0)" + using mono +proof + assume "\y\s. f y \ f x" + with `x \ s` and `open s` have "eventually (\y. f y \ f x) (at x)" + unfolding eventually_at_topological by auto + with deriv show ?thesis + by (rule has_derivative_local_max) +next + assume "\y\s. f x \ f y" + with `x \ s` and `open s` have "eventually (\y. f x \ f y) (at x)" + unfolding eventually_at_topological by auto + with deriv show ?thesis + by (rule has_derivative_local_min) +qed + +lemma differential_zero_maxmin_component: (* TODO: delete? *) fixes f :: "'a::euclidean_space \ 'b::euclidean_space" assumes k: "k \ Basis" and ball: "0 < e" "(\y \ ball x e. (f y)\k \ (f x)\k) \ (\y\ball x e. (f x)\k \ (f y)\k)" and diff: "f differentiable (at x)" shows "(\j\Basis. (frechet_derivative f (at x) j \ k) *\<^sub>R j) = (0::'a)" (is "?D k = 0") -proof (rule ccontr) - assume "\ ?thesis" - then obtain j where j: "?D k \ j \ 0" "j \ Basis" - unfolding euclidean_eq_iff[of _ "0::'a"] by auto - then have *: "\?D k \ j\ / 2 > 0" - by auto - note as = diff[unfolded jacobian_works has_derivative_at_alt] - obtain e' where e': - "0 < e'" - "(\y. norm (y - x) < e' \ - norm (f y - f x - - (\i\Basis. (\j\Basis. frechet_derivative f (at x) j \ i * ((y - x) \ j)) *\<^sub>R i)) - \ \(\j\Basis. (frechet_derivative f (at x) j \ k) *\<^sub>R j) \ j\ / 2 * norm (y - x))" - using as[THEN conjunct2] * by blast - obtain d where d: "0 < d" "d < e" "d < e'" - using real_lbound_gt_zero[OF ball(1) e'(1)] by blast - { - fix c - assume "abs c \ d" - then have *: "norm (x + c *\<^sub>R j - x) < e'" - using norm_Basis[OF j(2)] d by auto - let ?v = "(\i\Basis. (\l\Basis. ?D i \ l * ((c *\<^sub>R j :: 'a) \ l)) *\<^sub>R i)" - have if_dist: "\ P a b c. a * (if P then b else c) = (if P then a * b else a * c)" - by auto - have "\(f (x + c *\<^sub>R j) - f x - ?v) \ k\ \ norm (f (x + c *\<^sub>R j) - f x - ?v)" - by (rule Basis_le_norm[OF k]) - also have "\ \ \?D k \ j\ / 2 * \c\" - using e'(2)[OF *] and norm_Basis[OF j(2)] j - by simp - finally have "\(f (x + c *\<^sub>R j) - f x - ?v) \ k\ \ \?D k \ j\ / 2 * \c\" - by simp - then have "\f (x + c *\<^sub>R j) \ k - f x \ k - c * (?D k \ j)\ \ \?D k \ j\ / 2 * \c\" - using j k - by (simp add: inner_simps field_simps inner_Basis setsum_cases if_dist) - } - note * = this - have "x + d *\<^sub>R j \ ball x e" "x - d *\<^sub>R j \ ball x e" - unfolding mem_ball dist_norm - using norm_Basis[OF j(2)] d - by auto - then have **: "((f (x - d *\<^sub>R j))\k \ (f x)\k \ (f (x + d *\<^sub>R j))\k \ (f x)\k) \ - ((f (x - d *\<^sub>R j))\k \ (f x)\k \ (f (x + d *\<^sub>R j))\k \ (f x)\k)" - using ball by auto - have ***: "\y y1 y2 d dx :: real. y1 \ y \ y2 \ y \ y \ y1 \ y \ y2 \ - d < abs dx \ abs (y1 - y - - dx) \ d \ abs (y2 - y - dx) \ d \ False" - by arith - show False - apply (rule ***[OF **, where dx="d * (?D k \ j)" and d="\?D k \ j\ / 2 * \d\"]) - using *[of "-d"] and *[of d] and d(1) and j - unfolding mult_minus_left - unfolding abs_mult diff_minus_eq_add scaleR_minus_left - unfolding algebra_simps - apply (auto intro: mult_pos_pos) - done -qed - -text {* In particular if we have a mapping into @{typ "real"}. *} - -lemma differential_zero_maxmin: - fixes f::"'a::euclidean_space \ real" - assumes "x \ s" - and "open s" - and deriv: "(f has_derivative f') (at x)" - and mono: "(\y\s. f y \ f x) \ (\y\s. f x \ f y)" - shows "f' = (\v. 0)" proof - - obtain e where e: "e > 0" "ball x e \ s" - using `open s`[unfolded open_contains_ball] and `x \ s` by auto - with differential_zero_maxmin_component[where 'b=real, of 1 e x f] mono deriv - have "(\j\Basis. frechet_derivative f (at x) j *\<^sub>R j) = (0::'a)" - by (auto simp: Basis_real_def differentiable_def) - with frechet_derivative_at[OF deriv, symmetric] - have "\i\Basis. f' i = 0" - by (simp add: euclidean_eq_iff[of _ "0::'a"] inner_setsum_left_Basis) - with derivative_is_linear[OF deriv, THEN linear_componentwise, of _ 1] - show ?thesis - by (simp add: fun_eq_iff) + let ?f' = "frechet_derivative f (at x)" + have "x \ ball x e" using `0 < e` by simp + moreover have "open (ball x e)" by simp + moreover have "((\x. f x \ k) has_derivative (\h. ?f' h \ k)) (at x)" + using bounded_linear_inner_left diff[unfolded frechet_derivative_works] + by (rule bounded_linear.FDERIV) + ultimately have "(\h. frechet_derivative f (at x) h \ k) = (\v. 0)" + using ball(2) by (rule differential_zero_maxmin) + then show ?thesis + unfolding fun_eq_iff by simp qed lemma rolle: