4 Author : Brian Huffman |
4 Author : Brian Huffman |
5 Conversion to Isar and new proofs by Lawrence C Paulson, 2004 |
5 Conversion to Isar and new proofs by Lawrence C Paulson, 2004 |
6 GMVT by Benjamin Porter, 2005 |
6 GMVT by Benjamin Porter, 2005 |
7 *) |
7 *) |
8 |
8 |
9 section{* Differentiation *} |
9 section\<open>Differentiation\<close> |
10 |
10 |
11 theory Deriv |
11 theory Deriv |
12 imports Limits |
12 imports Limits |
13 begin |
13 begin |
14 |
14 |
15 subsection {* Frechet derivative *} |
15 subsection \<open>Frechet derivative\<close> |
16 |
16 |
17 definition |
17 definition |
18 has_derivative :: "('a::real_normed_vector \<Rightarrow> 'b::real_normed_vector) \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> 'a filter \<Rightarrow> bool" |
18 has_derivative :: "('a::real_normed_vector \<Rightarrow> 'b::real_normed_vector) \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> 'a filter \<Rightarrow> bool" |
19 (infix "(has'_derivative)" 50) |
19 (infix "(has'_derivative)" 50) |
20 where |
20 where |
21 "(f has_derivative f') F \<longleftrightarrow> |
21 "(f has_derivative f') F \<longleftrightarrow> |
22 (bounded_linear f' \<and> |
22 (bounded_linear f' \<and> |
23 ((\<lambda>y. ((f y - f (Lim F (\<lambda>x. x))) - f' (y - Lim F (\<lambda>x. x))) /\<^sub>R norm (y - Lim F (\<lambda>x. x))) ---> 0) F)" |
23 ((\<lambda>y. ((f y - f (Lim F (\<lambda>x. x))) - f' (y - Lim F (\<lambda>x. x))) /\<^sub>R norm (y - Lim F (\<lambda>x. x))) ---> 0) F)" |
24 |
24 |
25 text {* |
25 text \<open> |
26 Usually the filter @{term F} is @{term "at x within s"}. @{term "(f has_derivative D) |
26 Usually the filter @{term F} is @{term "at x within s"}. @{term "(f has_derivative D) |
27 (at x within s)"} means: @{term D} is the derivative of function @{term f} at point @{term x} |
27 (at x within s)"} means: @{term D} is the derivative of function @{term f} at point @{term x} |
28 within the set @{term s}. Where @{term s} is used to express left or right sided derivatives. In |
28 within the set @{term s}. Where @{term s} is used to express left or right sided derivatives. In |
29 most cases @{term s} is either a variable or @{term UNIV}. |
29 most cases @{term s} is either a variable or @{term UNIV}. |
30 *} |
30 \<close> |
31 |
31 |
32 lemma has_derivative_eq_rhs: "(f has_derivative f') F \<Longrightarrow> f' = g' \<Longrightarrow> (f has_derivative g') F" |
32 lemma has_derivative_eq_rhs: "(f has_derivative f') F \<Longrightarrow> f' = g' \<Longrightarrow> (f has_derivative g') F" |
33 by simp |
33 by simp |
34 |
34 |
35 definition |
35 definition |
49 |
49 |
50 lemma has_vector_derivative_eq_rhs: "(f has_vector_derivative X) F \<Longrightarrow> X = Y \<Longrightarrow> (f has_vector_derivative Y) F" |
50 lemma has_vector_derivative_eq_rhs: "(f has_vector_derivative X) F \<Longrightarrow> X = Y \<Longrightarrow> (f has_vector_derivative Y) F" |
51 by simp |
51 by simp |
52 |
52 |
53 named_theorems derivative_intros "structural introduction rules for derivatives" |
53 named_theorems derivative_intros "structural introduction rules for derivatives" |
54 setup {* |
54 setup \<open> |
55 let |
55 let |
56 val eq_thms = @{thms has_derivative_eq_rhs DERIV_cong has_vector_derivative_eq_rhs} |
56 val eq_thms = @{thms has_derivative_eq_rhs DERIV_cong has_vector_derivative_eq_rhs} |
57 fun eq_rule thm = get_first (try (fn eq_thm => eq_thm OF [thm])) eq_thms |
57 fun eq_rule thm = get_first (try (fn eq_thm => eq_thm OF [thm])) eq_thms |
58 in |
58 in |
59 Global_Theory.add_thms_dynamic |
59 Global_Theory.add_thms_dynamic |
60 (@{binding derivative_eq_intros}, |
60 (@{binding derivative_eq_intros}, |
61 fn context => |
61 fn context => |
62 Named_Theorems.get (Context.proof_of context) @{named_theorems derivative_intros} |
62 Named_Theorems.get (Context.proof_of context) @{named_theorems derivative_intros} |
63 |> map_filter eq_rule) |
63 |> map_filter eq_rule) |
64 end; |
64 end; |
65 *} |
65 \<close> |
66 |
66 |
67 text {* |
67 text \<open> |
68 The following syntax is only used as a legacy syntax. |
68 The following syntax is only used as a legacy syntax. |
69 *} |
69 \<close> |
70 abbreviation (input) |
70 abbreviation (input) |
71 FDERIV :: "('a::real_normed_vector \<Rightarrow> 'b::real_normed_vector) \<Rightarrow> 'a \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> bool" |
71 FDERIV :: "('a::real_normed_vector \<Rightarrow> 'b::real_normed_vector) \<Rightarrow> 'a \<Rightarrow> ('a \<Rightarrow> 'b) \<Rightarrow> bool" |
72 ("(FDERIV (_)/ (_)/ :> (_))" [1000, 1000, 60] 60) |
72 ("(FDERIV (_)/ (_)/ :> (_))" [1000, 1000, 60] 60) |
73 where |
73 where |
74 "FDERIV f x :> f' \<equiv> (f has_derivative f') (at x)" |
74 "FDERIV f x :> f' \<equiv> (f has_derivative f') (at x)" |
212 by simp |
212 by simp |
213 from tendsto_add[OF this tendsto_const, of "f x"] show ?thesis |
213 from tendsto_add[OF this tendsto_const, of "f x"] show ?thesis |
214 by (simp add: continuous_within) |
214 by (simp add: continuous_within) |
215 qed |
215 qed |
216 |
216 |
217 subsection {* Composition *} |
217 subsection \<open>Composition\<close> |
218 |
218 |
219 lemma tendsto_at_iff_tendsto_nhds_within: "f x = y \<Longrightarrow> (f ---> y) (at x within s) \<longleftrightarrow> (f ---> y) (inf (nhds x) (principal s))" |
219 lemma tendsto_at_iff_tendsto_nhds_within: "f x = y \<Longrightarrow> (f ---> y) (at x within s) \<longleftrightarrow> (f ---> y) (inf (nhds x) (principal s))" |
220 unfolding tendsto_def eventually_inf_principal eventually_at_filter |
220 unfolding tendsto_def eventually_inf_principal eventually_at_filter |
221 by (intro ext all_cong imp_cong) (auto elim!: eventually_elim1) |
221 by (intro ext all_cong imp_cong) (auto elim!: eventually_elim1) |
222 |
222 |
388 next |
388 next |
389 fix y::'a assume h: "y \<noteq> x" "dist y x < norm x" |
389 fix y::'a assume h: "y \<noteq> x" "dist y x < norm x" |
390 then have "y \<noteq> 0" |
390 then have "y \<noteq> 0" |
391 by (auto simp: norm_conv_dist dist_commute) |
391 by (auto simp: norm_conv_dist dist_commute) |
392 have "norm (?inv y - ?inv x - ?f (y -x)) / norm (y - x) = norm ((?inv y - ?inv x) * (y - x) * ?inv x) / norm (y - x)" |
392 have "norm (?inv y - ?inv x - ?f (y -x)) / norm (y - x) = norm ((?inv y - ?inv x) * (y - x) * ?inv x) / norm (y - x)" |
393 apply (subst inverse_diff_inverse [OF `y \<noteq> 0` x]) |
393 apply (subst inverse_diff_inverse [OF \<open>y \<noteq> 0\<close> x]) |
394 apply (subst minus_diff_minus) |
394 apply (subst minus_diff_minus) |
395 apply (subst norm_minus_cancel) |
395 apply (subst norm_minus_cancel) |
396 apply (simp add: left_diff_distrib) |
396 apply (simp add: left_diff_distrib) |
397 done |
397 done |
398 also have "\<dots> \<le> norm (?inv y - ?inv x) * norm (y - x) * norm (?inv x) / norm (y - x)" |
398 also have "\<dots> \<le> norm (?inv y - ?inv x) * norm (y - x) * norm (?inv x) / norm (y - x)" |
420 shows "((\<lambda>x. f x / g x) has_derivative |
420 shows "((\<lambda>x. f x / g x) has_derivative |
421 (\<lambda>h. - f x * (inverse (g x) * g' h * inverse (g x)) + f' h / g x)) (at x within s)" |
421 (\<lambda>h. - f x * (inverse (g x) * g' h * inverse (g x)) + f' h / g x)) (at x within s)" |
422 using has_derivative_mult[OF f has_derivative_inverse[OF x g]] |
422 using has_derivative_mult[OF f has_derivative_inverse[OF x g]] |
423 by (simp add: field_simps) |
423 by (simp add: field_simps) |
424 |
424 |
425 text{*Conventional form requires mult-AC laws. Types real and complex only.*} |
425 text\<open>Conventional form requires mult-AC laws. Types real and complex only.\<close> |
426 |
426 |
427 lemma has_derivative_divide'[derivative_intros]: |
427 lemma has_derivative_divide'[derivative_intros]: |
428 fixes f :: "_ \<Rightarrow> 'a::real_normed_field" |
428 fixes f :: "_ \<Rightarrow> 'a::real_normed_field" |
429 assumes f: "(f has_derivative f') (at x within s)" and g: "(g has_derivative g') (at x within s)" and x: "g x \<noteq> 0" |
429 assumes f: "(f has_derivative f') (at x within s)" and g: "(g has_derivative g') (at x within s)" and x: "g x \<noteq> 0" |
430 shows "((\<lambda>x. f x / g x) has_derivative (\<lambda>h. (f' h * g x - f x * g' h) / (g x * g x))) (at x within s)" |
430 shows "((\<lambda>x. f x / g x) has_derivative (\<lambda>h. (f' h * g x - f x * g' h) / (g x * g x))) (at x within s)" |
437 then show ?thesis |
437 then show ?thesis |
438 using has_derivative_divide [OF f g] x |
438 using has_derivative_divide [OF f g] x |
439 by simp |
439 by simp |
440 qed |
440 qed |
441 |
441 |
442 subsection {* Uniqueness *} |
442 subsection \<open>Uniqueness\<close> |
443 |
443 |
444 text {* |
444 text \<open> |
445 |
445 |
446 This can not generally shown for @{const has_derivative}, as we need to approach the point from |
446 This can not generally shown for @{const has_derivative}, as we need to approach the point from |
447 all directions. There is a proof in @{text Multivariate_Analysis} for @{text euclidean_space}. |
447 all directions. There is a proof in @{text Multivariate_Analysis} for @{text euclidean_space}. |
448 |
448 |
449 *} |
449 \<close> |
450 |
450 |
451 lemma has_derivative_zero_unique: |
451 lemma has_derivative_zero_unique: |
452 assumes "((\<lambda>x. 0) has_derivative F) (at x)" shows "F = (\<lambda>h. 0)" |
452 assumes "((\<lambda>x. 0) has_derivative F) (at x)" shows "F = (\<lambda>h. 0)" |
453 proof - |
453 proof - |
454 interpret F: bounded_linear F |
454 interpret F: bounded_linear F |
685 fixes a :: "'a :: real_normed_algebra" |
685 fixes a :: "'a :: real_normed_algebra" |
686 shows "(f has_vector_derivative x) F \<Longrightarrow> ((\<lambda>x. f x * a) has_vector_derivative (x * a)) F" |
686 shows "(f has_vector_derivative x) F \<Longrightarrow> ((\<lambda>x. f x * a) has_vector_derivative (x * a)) F" |
687 by (rule bounded_linear.has_vector_derivative[OF bounded_linear_mult_left]) |
687 by (rule bounded_linear.has_vector_derivative[OF bounded_linear_mult_left]) |
688 |
688 |
689 |
689 |
690 subsection {* Derivatives *} |
690 subsection \<open>Derivatives\<close> |
691 |
691 |
692 lemma DERIV_D: "DERIV f x :> D \<Longrightarrow> (\<lambda>h. (f (x + h) - f x) / h) -- 0 --> D" |
692 lemma DERIV_D: "DERIV f x :> D \<Longrightarrow> (\<lambda>h. (f (x + h) - f x) / h) -- 0 --> D" |
693 by (simp add: DERIV_def) |
693 by (simp add: DERIV_def) |
694 |
694 |
695 lemma DERIV_const [simp, derivative_intros]: "((\<lambda>x. k) has_field_derivative 0) F" |
695 lemma DERIV_const [simp, derivative_intros]: "((\<lambda>x. k) has_field_derivative 0) F" |
746 "(f has_field_derivative Da) (at x within s) \<Longrightarrow> (g has_field_derivative Db) (at x within s) \<Longrightarrow> |
746 "(f has_field_derivative Da) (at x within s) \<Longrightarrow> (g has_field_derivative Db) (at x within s) \<Longrightarrow> |
747 ((\<lambda>x. f x * g x) has_field_derivative Da * g x + Db * f x) (at x within s)" |
747 ((\<lambda>x. f x * g x) has_field_derivative Da * g x + Db * f x) (at x within s)" |
748 by (rule has_derivative_imp_has_field_derivative[OF has_derivative_mult]) |
748 by (rule has_derivative_imp_has_field_derivative[OF has_derivative_mult]) |
749 (auto simp: field_simps dest: has_field_derivative_imp_has_derivative) |
749 (auto simp: field_simps dest: has_field_derivative_imp_has_derivative) |
750 |
750 |
751 text {* Derivative of linear multiplication *} |
751 text \<open>Derivative of linear multiplication\<close> |
752 |
752 |
753 lemma DERIV_cmult: |
753 lemma DERIV_cmult: |
754 "(f has_field_derivative D) (at x within s) ==> ((\<lambda>x. c * f x) has_field_derivative c * D) (at x within s)" |
754 "(f has_field_derivative D) (at x within s) ==> ((\<lambda>x. c * f x) has_field_derivative c * D) (at x within s)" |
755 by (drule DERIV_mult' [OF DERIV_const], simp) |
755 by (drule DERIV_mult' [OF DERIV_const], simp) |
756 |
756 |
782 proof - |
782 proof - |
783 have "(f has_derivative (\<lambda>x. x * D)) = (f has_derivative op * D)" |
783 have "(f has_derivative (\<lambda>x. x * D)) = (f has_derivative op * D)" |
784 by (rule arg_cong [of "\<lambda>x. x * D"]) (simp add: fun_eq_iff) |
784 by (rule arg_cong [of "\<lambda>x. x * D"]) (simp add: fun_eq_iff) |
785 with assms have "(f has_derivative (\<lambda>x. x * D)) (at x within s)" |
785 with assms have "(f has_derivative (\<lambda>x. x * D)) (at x within s)" |
786 by (auto dest!: has_field_derivative_imp_has_derivative) |
786 by (auto dest!: has_field_derivative_imp_has_derivative) |
787 then show ?thesis using `f x \<noteq> 0` |
787 then show ?thesis using \<open>f x \<noteq> 0\<close> |
788 by (auto intro: has_derivative_imp_has_field_derivative has_derivative_inverse) |
788 by (auto intro: has_derivative_imp_has_field_derivative has_derivative_inverse) |
789 qed |
789 qed |
790 |
790 |
791 text {* Power of @{text "-1"} *} |
791 text \<open>Power of @{text "-1"}\<close> |
792 |
792 |
793 lemma DERIV_inverse: |
793 lemma DERIV_inverse: |
794 "x \<noteq> 0 \<Longrightarrow> ((\<lambda>x. inverse(x)) has_field_derivative - (inverse x ^ Suc (Suc 0))) (at x within s)" |
794 "x \<noteq> 0 \<Longrightarrow> ((\<lambda>x. inverse(x)) has_field_derivative - (inverse x ^ Suc (Suc 0))) (at x within s)" |
795 by (drule DERIV_inverse' [OF DERIV_ident]) simp |
795 by (drule DERIV_inverse' [OF DERIV_ident]) simp |
796 |
796 |
797 text {* Derivative of inverse *} |
797 text \<open>Derivative of inverse\<close> |
798 |
798 |
799 lemma DERIV_inverse_fun: |
799 lemma DERIV_inverse_fun: |
800 "(f has_field_derivative d) (at x within s) \<Longrightarrow> f x \<noteq> 0 \<Longrightarrow> |
800 "(f has_field_derivative d) (at x within s) \<Longrightarrow> f x \<noteq> 0 \<Longrightarrow> |
801 ((\<lambda>x. inverse (f x)) has_field_derivative (- (d * inverse(f x ^ Suc (Suc 0))))) (at x within s)" |
801 ((\<lambda>x. inverse (f x)) has_field_derivative (- (d * inverse(f x ^ Suc (Suc 0))))) (at x within s)" |
802 by (drule (1) DERIV_inverse') (simp add: ac_simps nonzero_inverse_mult_distrib) |
802 by (drule (1) DERIV_inverse') (simp add: ac_simps nonzero_inverse_mult_distrib) |
803 |
803 |
804 text {* Derivative of quotient *} |
804 text \<open>Derivative of quotient\<close> |
805 |
805 |
806 lemma DERIV_divide[derivative_intros]: |
806 lemma DERIV_divide[derivative_intros]: |
807 "(f has_field_derivative D) (at x within s) \<Longrightarrow> |
807 "(f has_field_derivative D) (at x within s) \<Longrightarrow> |
808 (g has_field_derivative E) (at x within s) \<Longrightarrow> g x \<noteq> 0 \<Longrightarrow> |
808 (g has_field_derivative E) (at x within s) \<Longrightarrow> g x \<noteq> 0 \<Longrightarrow> |
809 ((\<lambda>x. f x / g x) has_field_derivative (D * g x - f x * E) / (g x * g x)) (at x within s)" |
809 ((\<lambda>x. f x / g x) has_field_derivative (D * g x - f x * E) / (g x * g x)) (at x within s)" |
840 |
840 |
841 corollary DERIV_chain2: "DERIV f (g x) :> Da \<Longrightarrow> (g has_field_derivative Db) (at x within s) \<Longrightarrow> |
841 corollary DERIV_chain2: "DERIV f (g x) :> Da \<Longrightarrow> (g has_field_derivative Db) (at x within s) \<Longrightarrow> |
842 ((\<lambda>x. f (g x)) has_field_derivative Da * Db) (at x within s)" |
842 ((\<lambda>x. f (g x)) has_field_derivative Da * Db) (at x within s)" |
843 by (rule DERIV_chain') |
843 by (rule DERIV_chain') |
844 |
844 |
845 text {* Standard version *} |
845 text \<open>Standard version\<close> |
846 |
846 |
847 lemma DERIV_chain: |
847 lemma DERIV_chain: |
848 "DERIV f (g x) :> Da \<Longrightarrow> (g has_field_derivative Db) (at x within s) \<Longrightarrow> |
848 "DERIV f (g x) :> Da \<Longrightarrow> (g has_field_derivative Db) (at x within s) \<Longrightarrow> |
849 (f o g has_field_derivative Da * Db) (at x within s)" |
849 (f o g has_field_derivative Da * Db) (at x within s)" |
850 by (drule (1) DERIV_chain', simp add: o_def mult.commute) |
850 by (drule (1) DERIV_chain', simp add: o_def mult.commute) |
870 by (metis UNIV_I DERIV_chain_s [of UNIV] assms) |
870 by (metis UNIV_I DERIV_chain_s [of UNIV] assms) |
871 |
871 |
872 declare |
872 declare |
873 DERIV_power[where 'a=real, unfolded real_of_nat_def[symmetric], derivative_intros] |
873 DERIV_power[where 'a=real, unfolded real_of_nat_def[symmetric], derivative_intros] |
874 |
874 |
875 text{*Alternative definition for differentiability*} |
875 text\<open>Alternative definition for differentiability\<close> |
876 |
876 |
877 lemma DERIV_LIM_iff: |
877 lemma DERIV_LIM_iff: |
878 fixes f :: "'a::{real_normed_vector,inverse} \<Rightarrow> 'a" shows |
878 fixes f :: "'a::{real_normed_vector,inverse} \<Rightarrow> 'a" shows |
879 "((%h. (f(a + h) - f(a)) / h) -- 0 --> D) = |
879 "((%h. (f(a + h) - f(a)) / h) -- 0 --> D) = |
880 ((%x. (f(x)-f(a)) / (x-a)) -- a --> D)" |
880 ((%x. (f(x)-f(a)) / (x-a)) -- a --> D)" |
906 lemma DERIV_mirror: |
906 lemma DERIV_mirror: |
907 "(DERIV f (- x) :> y) \<longleftrightarrow> (DERIV (\<lambda>x. f (- x::real) :: real) x :> - y)" |
907 "(DERIV f (- x) :> y) \<longleftrightarrow> (DERIV (\<lambda>x. f (- x::real) :: real) x :> - y)" |
908 by (simp add: DERIV_def filterlim_at_split filterlim_at_left_to_right |
908 by (simp add: DERIV_def filterlim_at_split filterlim_at_left_to_right |
909 tendsto_minus_cancel_left field_simps conj_commute) |
909 tendsto_minus_cancel_left field_simps conj_commute) |
910 |
910 |
911 text {* Caratheodory formulation of derivative at a point *} |
911 text \<open>Caratheodory formulation of derivative at a point\<close> |
912 |
912 |
913 lemma CARAT_DERIV: (*FIXME: SUPERSEDED BY THE ONE IN Deriv.thy. But still used by NSA/HDeriv.thy*) |
913 lemma CARAT_DERIV: (*FIXME: SUPERSEDED BY THE ONE IN Deriv.thy. But still used by NSA/HDeriv.thy*) |
914 "(DERIV f x :> l) \<longleftrightarrow> (\<exists>g. (\<forall>z. f z - f x = g z * (z - x)) \<and> isCont g x \<and> g x = l)" |
914 "(DERIV f x :> l) \<longleftrightarrow> (\<exists>g. (\<forall>z. f z - f x = g z * (z - x)) \<and> isCont g x \<and> g x = l)" |
915 (is "?lhs = ?rhs") |
915 (is "?lhs = ?rhs") |
916 proof |
916 proof |
930 thus "(DERIV f x :> l)" |
930 thus "(DERIV f x :> l)" |
931 by (auto simp add: isCont_iff DERIV_def cong: LIM_cong) |
931 by (auto simp add: isCont_iff DERIV_def cong: LIM_cong) |
932 qed |
932 qed |
933 |
933 |
934 |
934 |
935 subsection {* Local extrema *} |
935 subsection \<open>Local extrema\<close> |
936 |
936 |
937 text{*If @{term "0 < f'(x)"} then @{term x} is Locally Strictly Increasing At The Right*} |
937 text\<open>If @{term "0 < f'(x)"} then @{term x} is Locally Strictly Increasing At The Right\<close> |
938 |
938 |
939 lemma DERIV_pos_inc_right: |
939 lemma DERIV_pos_inc_right: |
940 fixes f :: "real => real" |
940 fixes f :: "real => real" |
941 assumes der: "DERIV f x :> l" |
941 assumes der: "DERIV f x :> l" |
942 and l: "0 < l" |
942 and l: "0 < l" |
1035 with lt le [THEN spec [where x="x+e"]] |
1035 with lt le [THEN spec [where x="x+e"]] |
1036 show ?thesis by (auto simp add: abs_if) |
1036 show ?thesis by (auto simp add: abs_if) |
1037 qed |
1037 qed |
1038 |
1038 |
1039 |
1039 |
1040 text{*Similar theorem for a local minimum*} |
1040 text\<open>Similar theorem for a local minimum\<close> |
1041 lemma DERIV_local_min: |
1041 lemma DERIV_local_min: |
1042 fixes f :: "real => real" |
1042 fixes f :: "real => real" |
1043 shows "[| DERIV f x :> l; 0 < d; \<forall>y. \<bar>x-y\<bar> < d --> f(x) \<le> f(y) |] ==> l = 0" |
1043 shows "[| DERIV f x :> l; 0 < d; \<forall>y. \<bar>x-y\<bar> < d --> f(x) \<le> f(y) |] ==> l = 0" |
1044 by (drule DERIV_minus [THEN DERIV_local_max], auto) |
1044 by (drule DERIV_minus [THEN DERIV_local_max], auto) |
1045 |
1045 |
1046 |
1046 |
1047 text{*In particular, if a function is locally flat*} |
1047 text\<open>In particular, if a function is locally flat\<close> |
1048 lemma DERIV_local_const: |
1048 lemma DERIV_local_const: |
1049 fixes f :: "real => real" |
1049 fixes f :: "real => real" |
1050 shows "[| DERIV f x :> l; 0 < d; \<forall>y. \<bar>x-y\<bar> < d --> f(x) = f(y) |] ==> l = 0" |
1050 shows "[| DERIV f x :> l; 0 < d; \<forall>y. \<bar>x-y\<bar> < d --> f(x) = f(y) |] ==> l = 0" |
1051 by (auto dest!: DERIV_local_max) |
1051 by (auto dest!: DERIV_local_max) |
1052 |
1052 |
1053 |
1053 |
1054 subsection {* Rolle's Theorem *} |
1054 subsection \<open>Rolle's Theorem\<close> |
1055 |
1055 |
1056 text{*Lemma about introducing open ball in open interval*} |
1056 text\<open>Lemma about introducing open ball in open interval\<close> |
1057 lemma lemma_interval_lt: |
1057 lemma lemma_interval_lt: |
1058 "[| a < x; x < b |] |
1058 "[| a < x; x < b |] |
1059 ==> \<exists>d::real. 0 < d & (\<forall>y. \<bar>x-y\<bar> < d --> a < y & y < b)" |
1059 ==> \<exists>d::real. 0 < d & (\<forall>y. \<bar>x-y\<bar> < d --> a < y & y < b)" |
1060 |
1060 |
1061 apply (simp add: abs_less_iff) |
1061 apply (simp add: abs_less_iff) |
1068 \<exists>d::real. 0 < d & (\<forall>y. \<bar>x-y\<bar> < d --> a \<le> y & y \<le> b)" |
1068 \<exists>d::real. 0 < d & (\<forall>y. \<bar>x-y\<bar> < d --> a \<le> y & y \<le> b)" |
1069 apply (drule lemma_interval_lt, auto) |
1069 apply (drule lemma_interval_lt, auto) |
1070 apply force |
1070 apply force |
1071 done |
1071 done |
1072 |
1072 |
1073 text{*Rolle's Theorem. |
1073 text\<open>Rolle's Theorem. |
1074 If @{term f} is defined and continuous on the closed interval |
1074 If @{term f} is defined and continuous on the closed interval |
1075 @{text "[a,b]"} and differentiable on the open interval @{text "(a,b)"}, |
1075 @{text "[a,b]"} and differentiable on the open interval @{text "(a,b)"}, |
1076 and @{term "f(a) = f(b)"}, |
1076 and @{term "f(a) = f(b)"}, |
1077 then there exists @{text "x0 \<in> (a,b)"} such that @{term "f'(x0) = 0"}*} |
1077 then there exists @{text "x0 \<in> (a,b)"} such that @{term "f'(x0) = 0"}\<close> |
1078 theorem Rolle: |
1078 theorem Rolle: |
1079 assumes lt: "a < b" |
1079 assumes lt: "a < b" |
1080 and eq: "f(a) = f(b)" |
1080 and eq: "f(a) = f(b)" |
1081 and con: "\<forall>x. a \<le> x & x \<le> b --> isCont f x" |
1081 and con: "\<forall>x. a \<le> x & x \<le> b --> isCont f x" |
1082 and dif [rule_format]: "\<forall>x. a < x & x < b --> f differentiable (at x)" |
1082 and dif [rule_format]: "\<forall>x. a < x & x < b --> f differentiable (at x)" |
1092 and alex': "a \<le> x'" and x'leb: "x' \<le> b" |
1092 and alex': "a \<le> x'" and x'leb: "x' \<le> b" |
1093 by blast |
1093 by blast |
1094 show ?thesis |
1094 show ?thesis |
1095 proof cases |
1095 proof cases |
1096 assume axb: "a < x & x < b" |
1096 assume axb: "a < x & x < b" |
1097 --{*@{term f} attains its maximum within the interval*} |
1097 --\<open>@{term f} attains its maximum within the interval\<close> |
1098 hence ax: "a<x" and xb: "x<b" by arith + |
1098 hence ax: "a<x" and xb: "x<b" by arith + |
1099 from lemma_interval [OF ax xb] |
1099 from lemma_interval [OF ax xb] |
1100 obtain d where d: "0<d" and bound: "\<forall>y. \<bar>x-y\<bar> < d \<longrightarrow> a \<le> y \<and> y \<le> b" |
1100 obtain d where d: "0<d" and bound: "\<forall>y. \<bar>x-y\<bar> < d \<longrightarrow> a \<le> y \<and> y \<le> b" |
1101 by blast |
1101 by blast |
1102 hence bound': "\<forall>y. \<bar>x-y\<bar> < d \<longrightarrow> f y \<le> f x" using x_max |
1102 hence bound': "\<forall>y. \<bar>x-y\<bar> < d \<longrightarrow> f y \<le> f x" using x_max |
1103 by blast |
1103 by blast |
1104 from differentiableD [OF dif [OF axb]] |
1104 from differentiableD [OF dif [OF axb]] |
1105 obtain l where der: "DERIV f x :> l" .. |
1105 obtain l where der: "DERIV f x :> l" .. |
1106 have "l=0" by (rule DERIV_local_max [OF der d bound']) |
1106 have "l=0" by (rule DERIV_local_max [OF der d bound']) |
1107 --{*the derivative at a local maximum is zero*} |
1107 --\<open>the derivative at a local maximum is zero\<close> |
1108 thus ?thesis using ax xb der by auto |
1108 thus ?thesis using ax xb der by auto |
1109 next |
1109 next |
1110 assume notaxb: "~ (a < x & x < b)" |
1110 assume notaxb: "~ (a < x & x < b)" |
1111 hence xeqab: "x=a | x=b" using alex xleb by arith |
1111 hence xeqab: "x=a | x=b" using alex xleb by arith |
1112 hence fb_eq_fx: "f b = f x" by (auto simp add: eq) |
1112 hence fb_eq_fx: "f b = f x" by (auto simp add: eq) |
1113 show ?thesis |
1113 show ?thesis |
1114 proof cases |
1114 proof cases |
1115 assume ax'b: "a < x' & x' < b" |
1115 assume ax'b: "a < x' & x' < b" |
1116 --{*@{term f} attains its minimum within the interval*} |
1116 --\<open>@{term f} attains its minimum within the interval\<close> |
1117 hence ax': "a<x'" and x'b: "x'<b" by arith+ |
1117 hence ax': "a<x'" and x'b: "x'<b" by arith+ |
1118 from lemma_interval [OF ax' x'b] |
1118 from lemma_interval [OF ax' x'b] |
1119 obtain d where d: "0<d" and bound: "\<forall>y. \<bar>x'-y\<bar> < d \<longrightarrow> a \<le> y \<and> y \<le> b" |
1119 obtain d where d: "0<d" and bound: "\<forall>y. \<bar>x'-y\<bar> < d \<longrightarrow> a \<le> y \<and> y \<le> b" |
1120 by blast |
1120 by blast |
1121 hence bound': "\<forall>y. \<bar>x'-y\<bar> < d \<longrightarrow> f x' \<le> f y" using x'_min |
1121 hence bound': "\<forall>y. \<bar>x'-y\<bar> < d \<longrightarrow> f x' \<le> f y" using x'_min |
1122 by blast |
1122 by blast |
1123 from differentiableD [OF dif [OF ax'b]] |
1123 from differentiableD [OF dif [OF ax'b]] |
1124 obtain l where der: "DERIV f x' :> l" .. |
1124 obtain l where der: "DERIV f x' :> l" .. |
1125 have "l=0" by (rule DERIV_local_min [OF der d bound']) |
1125 have "l=0" by (rule DERIV_local_min [OF der d bound']) |
1126 --{*the derivative at a local minimum is zero*} |
1126 --\<open>the derivative at a local minimum is zero\<close> |
1127 thus ?thesis using ax' x'b der by auto |
1127 thus ?thesis using ax' x'b der by auto |
1128 next |
1128 next |
1129 assume notax'b: "~ (a < x' & x' < b)" |
1129 assume notax'b: "~ (a < x' & x' < b)" |
1130 --{*@{term f} is constant througout the interval*} |
1130 --\<open>@{term f} is constant througout the interval\<close> |
1131 hence x'eqab: "x'=a | x'=b" using alex' x'leb by arith |
1131 hence x'eqab: "x'=a | x'=b" using alex' x'leb by arith |
1132 hence fb_eq_fx': "f b = f x'" by (auto simp add: eq) |
1132 hence fb_eq_fx': "f b = f x'" by (auto simp add: eq) |
1133 from dense [OF lt] |
1133 from dense [OF lt] |
1134 obtain r where ar: "a < r" and rb: "r < b" by blast |
1134 obtain r where ar: "a < r" and rb: "r < b" by blast |
1135 from lemma_interval [OF ar rb] |
1135 from lemma_interval [OF ar rb] |
1153 thus "f r = f y" by (simp add: eq_fb ar rb order_less_imp_le) |
1153 thus "f r = f y" by (simp add: eq_fb ar rb order_less_imp_le) |
1154 qed |
1154 qed |
1155 from differentiableD [OF dif [OF conjI [OF ar rb]]] |
1155 from differentiableD [OF dif [OF conjI [OF ar rb]]] |
1156 obtain l where der: "DERIV f r :> l" .. |
1156 obtain l where der: "DERIV f r :> l" .. |
1157 have "l=0" by (rule DERIV_local_const [OF der d bound']) |
1157 have "l=0" by (rule DERIV_local_const [OF der d bound']) |
1158 --{*the derivative of a constant function is zero*} |
1158 --\<open>the derivative of a constant function is zero\<close> |
1159 thus ?thesis using ar rb der by auto |
1159 thus ?thesis using ar rb der by auto |
1160 qed |
1160 qed |
1161 qed |
1161 qed |
1162 qed |
1162 qed |
1163 |
1163 |
1164 |
1164 |
1165 subsection{*Mean Value Theorem*} |
1165 subsection\<open>Mean Value Theorem\<close> |
1166 |
1166 |
1167 lemma lemma_MVT: |
1167 lemma lemma_MVT: |
1168 "f a - (f b - f a)/(b-a) * a = f b - (f b - f a)/(b-a) * (b::real)" |
1168 "f a - (f b - f a)/(b-a) * a = f b - (f b - f a)/(b-a) * (b::real)" |
1169 by (cases "a = b") (simp_all add: field_simps) |
1169 by (cases "a = b") (simp_all add: field_simps) |
1170 |
1170 |
1259 let ?b = "max x y" |
1259 let ?b = "max x y" |
1260 |
1260 |
1261 have "\<forall>z. ?a \<le> z \<and> z \<le> ?b \<longrightarrow> DERIV f z :> 0" |
1261 have "\<forall>z. ?a \<le> z \<and> z \<le> ?b \<longrightarrow> DERIV f z :> 0" |
1262 proof (rule allI, rule impI) |
1262 proof (rule allI, rule impI) |
1263 fix z :: real assume "?a \<le> z \<and> z \<le> ?b" |
1263 fix z :: real assume "?a \<le> z \<and> z \<le> ?b" |
1264 hence "a < z" and "z < b" using `x \<in> {a <..< b}` and `y \<in> {a <..< b}` by auto |
1264 hence "a < z" and "z < b" using \<open>x \<in> {a <..< b}\<close> and \<open>y \<in> {a <..< b}\<close> by auto |
1265 hence "z \<in> {a<..<b}" by auto |
1265 hence "z \<in> {a<..<b}" by auto |
1266 thus "DERIV f z :> 0" by (rule derivable) |
1266 thus "DERIV f z :> 0" by (rule derivable) |
1267 qed |
1267 qed |
1268 hence isCont: "\<forall>z. ?a \<le> z \<and> z \<le> ?b \<longrightarrow> isCont f z" |
1268 hence isCont: "\<forall>z. ?a \<le> z \<and> z \<le> ?b \<longrightarrow> isCont f z" |
1269 and DERIV: "\<forall>z. ?a < z \<and> z < ?b \<longrightarrow> DERIV f z :> 0" using DERIV_isCont by auto |
1269 and DERIV: "\<forall>z. ?a < z \<and> z < ?b \<longrightarrow> DERIV f z :> 0" using DERIV_isCont by auto |
1270 |
1270 |
1271 have "?a < ?b" using `x \<noteq> y` by auto |
1271 have "?a < ?b" using \<open>x \<noteq> y\<close> by auto |
1272 from DERIV_isconst2[OF this isCont DERIV, of x] and DERIV_isconst2[OF this isCont DERIV, of y] |
1272 from DERIV_isconst2[OF this isCont DERIV, of x] and DERIV_isconst2[OF this isCont DERIV, of y] |
1273 show ?thesis by auto |
1273 show ?thesis by auto |
1274 qed auto |
1274 qed auto |
1275 |
1275 |
1276 lemma DERIV_isconst_all: |
1276 lemma DERIV_isconst_all: |
1453 apply (rule DERIV_pos_imp_increasing_at_bot [where f = "\<lambda>i. f (-i)" and b = "-b", simplified]) |
1453 apply (rule DERIV_pos_imp_increasing_at_bot [where f = "\<lambda>i. f (-i)" and b = "-b", simplified]) |
1454 apply (metis DERIV_mirror der le_minus_iff neg_0_less_iff_less) |
1454 apply (metis DERIV_mirror der le_minus_iff neg_0_less_iff_less) |
1455 apply (metis filterlim_at_top_mirror lim) |
1455 apply (metis filterlim_at_top_mirror lim) |
1456 done |
1456 done |
1457 |
1457 |
1458 text {* Derivative of inverse function *} |
1458 text \<open>Derivative of inverse function\<close> |
1459 |
1459 |
1460 lemma DERIV_inverse_function: |
1460 lemma DERIV_inverse_function: |
1461 fixes f g :: "real \<Rightarrow> real" |
1461 fixes f g :: "real \<Rightarrow> real" |
1462 assumes der: "DERIV f (g x) :> D" |
1462 assumes der: "DERIV f (g x) :> D" |
1463 assumes neq: "D \<noteq> 0" |
1463 assumes neq: "D \<noteq> 0" |
1643 |
1643 |
1644 have "\<exists>\<zeta>. \<forall>x\<in>{0 <..< a}. 0 < \<zeta> x \<and> \<zeta> x < x \<and> f x / g x = f' (\<zeta> x) / g' (\<zeta> x)" |
1644 have "\<exists>\<zeta>. \<forall>x\<in>{0 <..< a}. 0 < \<zeta> x \<and> \<zeta> x < x \<and> f x / g x = f' (\<zeta> x) / g' (\<zeta> x)" |
1645 proof (rule bchoice, rule) |
1645 proof (rule bchoice, rule) |
1646 fix x assume "x \<in> {0 <..< a}" |
1646 fix x assume "x \<in> {0 <..< a}" |
1647 then have x[arith]: "0 < x" "x < a" by auto |
1647 then have x[arith]: "0 < x" "x < a" by auto |
1648 with g'_neq_0 g_neq_0 `g 0 = 0` have g': "\<And>x. 0 < x \<Longrightarrow> x < a \<Longrightarrow> 0 \<noteq> g' x" "g 0 \<noteq> g x" |
1648 with g'_neq_0 g_neq_0 \<open>g 0 = 0\<close> have g': "\<And>x. 0 < x \<Longrightarrow> x < a \<Longrightarrow> 0 \<noteq> g' x" "g 0 \<noteq> g x" |
1649 by auto |
1649 by auto |
1650 have "\<And>x. 0 \<le> x \<Longrightarrow> x < a \<Longrightarrow> isCont f x" |
1650 have "\<And>x. 0 \<le> x \<Longrightarrow> x < a \<Longrightarrow> isCont f x" |
1651 using `isCont f 0` f by (auto intro: DERIV_isCont simp: le_less) |
1651 using \<open>isCont f 0\<close> f by (auto intro: DERIV_isCont simp: le_less) |
1652 moreover have "\<And>x. 0 \<le> x \<Longrightarrow> x < a \<Longrightarrow> isCont g x" |
1652 moreover have "\<And>x. 0 \<le> x \<Longrightarrow> x < a \<Longrightarrow> isCont g x" |
1653 using `isCont g 0` g by (auto intro: DERIV_isCont simp: le_less) |
1653 using \<open>isCont g 0\<close> g by (auto intro: DERIV_isCont simp: le_less) |
1654 ultimately have "\<exists>c. 0 < c \<and> c < x \<and> (f x - f 0) * g' c = (g x - g 0) * f' c" |
1654 ultimately have "\<exists>c. 0 < c \<and> c < x \<and> (f x - f 0) * g' c = (g x - g 0) * f' c" |
1655 using f g `x < a` by (intro GMVT') auto |
1655 using f g \<open>x < a\<close> by (intro GMVT') auto |
1656 then obtain c where *: "0 < c" "c < x" "(f x - f 0) * g' c = (g x - g 0) * f' c" |
1656 then obtain c where *: "0 < c" "c < x" "(f x - f 0) * g' c = (g x - g 0) * f' c" |
1657 by blast |
1657 by blast |
1658 moreover |
1658 moreover |
1659 from * g'(1)[of c] g'(2) have "(f x - f 0) / (g x - g 0) = f' c / g' c" |
1659 from * g'(1)[of c] g'(2) have "(f x - f 0) / (g x - g 0) = f' c / g' c" |
1660 by (simp add: field_simps) |
1660 by (simp add: field_simps) |
1661 ultimately show "\<exists>y. 0 < y \<and> y < x \<and> f x / g x = f' y / g' y" |
1661 ultimately show "\<exists>y. 0 < y \<and> y < x \<and> f x / g x = f' y / g' y" |
1662 using `f 0 = 0` `g 0 = 0` by (auto intro!: exI[of _ c]) |
1662 using \<open>f 0 = 0\<close> \<open>g 0 = 0\<close> by (auto intro!: exI[of _ c]) |
1663 qed |
1663 qed |
1664 then obtain \<zeta> where "\<forall>x\<in>{0 <..< a}. 0 < \<zeta> x \<and> \<zeta> x < x \<and> f x / g x = f' (\<zeta> x) / g' (\<zeta> x)" .. |
1664 then obtain \<zeta> where "\<forall>x\<in>{0 <..< a}. 0 < \<zeta> x \<and> \<zeta> x < x \<and> f x / g x = f' (\<zeta> x) / g' (\<zeta> x)" .. |
1665 then have \<zeta>: "eventually (\<lambda>x. 0 < \<zeta> x \<and> \<zeta> x < x \<and> f x / g x = f' (\<zeta> x) / g' (\<zeta> x)) (at_right 0)" |
1665 then have \<zeta>: "eventually (\<lambda>x. 0 < \<zeta> x \<and> \<zeta> x < x \<and> f x / g x = f' (\<zeta> x) / g' (\<zeta> x)) (at_right 0)" |
1666 unfolding eventually_at by (intro exI[of _ a]) (auto simp: dist_real_def) |
1666 unfolding eventually_at by (intro exI[of _ a]) (auto simp: dist_real_def) |
1667 moreover |
1667 moreover |
1763 moreover |
1763 moreover |
1764 from inv_g have "((\<lambda>t. norm ((f a - x * g a) * inverse (g t))) ---> norm ((f a - x * g a) * 0)) (at_right 0)" |
1764 from inv_g have "((\<lambda>t. norm ((f a - x * g a) * inverse (g t))) ---> norm ((f a - x * g a) * 0)) (at_right 0)" |
1765 by (intro tendsto_intros) |
1765 by (intro tendsto_intros) |
1766 then have "((\<lambda>t. norm (f a - x * g a) / norm (g t)) ---> 0) (at_right 0)" |
1766 then have "((\<lambda>t. norm (f a - x * g a) / norm (g t)) ---> 0) (at_right 0)" |
1767 by (simp add: inverse_eq_divide) |
1767 by (simp add: inverse_eq_divide) |
1768 from this[unfolded tendsto_iff, rule_format, of "e / 2"] `0 < e` |
1768 from this[unfolded tendsto_iff, rule_format, of "e / 2"] \<open>0 < e\<close> |
1769 have "eventually (\<lambda>t. norm (f a - x * g a) / norm (g t) < e / 2) (at_right 0)" |
1769 have "eventually (\<lambda>t. norm (f a - x * g a) / norm (g t) < e / 2) (at_right 0)" |
1770 by (auto simp: dist_real_def) |
1770 by (auto simp: dist_real_def) |
1771 |
1771 |
1772 ultimately show "eventually (\<lambda>t. dist (f t / g t) x < e) (at_right 0)" |
1772 ultimately show "eventually (\<lambda>t. dist (f t / g t) x < e) (at_right 0)" |
1773 proof eventually_elim |
1773 proof eventually_elim |
1778 using f0 g0 t(1,2) by (intro GMVT') (force intro!: DERIV_isCont)+ |
1778 using f0 g0 t(1,2) by (intro GMVT') (force intro!: DERIV_isCont)+ |
1779 then obtain y where [arith]: "t < y" "y < a" |
1779 then obtain y where [arith]: "t < y" "y < a" |
1780 and D_eq0: "(g a - g t) * f' y = (f a - f t) * g' y" |
1780 and D_eq0: "(g a - g t) * f' y = (f a - f t) * g' y" |
1781 by blast |
1781 by blast |
1782 from D_eq0 have D_eq: "(f t - f a) / (g t - g a) = f' y / g' y" |
1782 from D_eq0 have D_eq: "(f t - f a) / (g t - g a) = f' y / g' y" |
1783 using `g a < g t` g'_neq_0[of y] by (auto simp add: field_simps) |
1783 using \<open>g a < g t\<close> g'_neq_0[of y] by (auto simp add: field_simps) |
1784 |
1784 |
1785 have *: "f t / g t - x = ((f t - f a) / (g t - g a) - x) * (1 - g a / g t) + (f a - x * g a) / g t" |
1785 have *: "f t / g t - x = ((f t - f a) / (g t - g a) - x) * (1 - g a / g t) + (f a - x * g a) / g t" |
1786 by (simp add: field_simps) |
1786 by (simp add: field_simps) |
1787 have "norm (f t / g t - x) \<le> |
1787 have "norm (f t / g t - x) \<le> |
1788 norm (((f t - f a) / (g t - g a) - x) * (1 - g a / g t)) + norm ((f a - x * g a) / g t)" |
1788 norm (((f t - f a) / (g t - g a) - x) * (1 - g a / g t)) + norm ((f a - x * g a) / g t)" |
1789 unfolding * by (rule norm_triangle_ineq) |
1789 unfolding * by (rule norm_triangle_ineq) |
1790 also have "\<dots> = dist (f' y / g' y) x * norm (1 - g a / g t) + norm (f a - x * g a) / norm (g t)" |
1790 also have "\<dots> = dist (f' y / g' y) x * norm (1 - g a / g t) + norm (f a - x * g a) / norm (g t)" |
1791 by (simp add: abs_mult D_eq dist_real_def) |
1791 by (simp add: abs_mult D_eq dist_real_def) |
1792 also have "\<dots> < (e / 4) * 2 + e / 2" |
1792 also have "\<dots> < (e / 4) * 2 + e / 2" |
1793 using ineq Df[of y] `0 < e` by (intro add_le_less_mono mult_mono) auto |
1793 using ineq Df[of y] \<open>0 < e\<close> by (intro add_le_less_mono mult_mono) auto |
1794 finally show "dist (f t / g t) x < e" |
1794 finally show "dist (f t / g t) x < e" |
1795 by (simp add: dist_real_def) |
1795 by (simp add: dist_real_def) |
1796 qed |
1796 qed |
1797 qed |
1797 qed |
1798 |
1798 |