43 lemmas mult_right_has_derivative = has_derivative_mult_right |
43 lemmas mult_right_has_derivative = has_derivative_mult_right |
44 lemmas mult_left_has_derivative = has_derivative_mult_left |
44 lemmas mult_left_has_derivative = has_derivative_mult_left |
45 |
45 |
46 lemma has_derivative_add_const: |
46 lemma has_derivative_add_const: |
47 "(f has_derivative f') net \<Longrightarrow> ((\<lambda>x. f x + c) has_derivative f') net" |
47 "(f has_derivative f') net \<Longrightarrow> ((\<lambda>x. f x + c) has_derivative f') net" |
48 by (intro has_derivative_eq_intros) auto |
48 by (intro derivative_eq_intros) auto |
49 |
49 |
50 |
50 |
51 subsection {* Derivative with composed bilinear function. *} |
51 subsection {* Derivative with composed bilinear function. *} |
52 |
52 |
53 lemma has_derivative_bilinear_within: |
53 lemma has_derivative_bilinear_within: |
317 by simp |
317 by simp |
318 |
318 |
319 |
319 |
320 subsection {* The chain rule *} |
320 subsection {* The chain rule *} |
321 |
321 |
322 lemma diff_chain_within[has_derivative_intros]: |
322 lemma diff_chain_within[derivative_intros]: |
323 assumes "(f has_derivative f') (at x within s)" |
323 assumes "(f has_derivative f') (at x within s)" |
324 and "(g has_derivative g') (at (f x) within (f ` s))" |
324 and "(g has_derivative g') (at (f x) within (f ` s))" |
325 shows "((g \<circ> f) has_derivative (g' \<circ> f'))(at x within s)" |
325 shows "((g \<circ> f) has_derivative (g' \<circ> f'))(at x within s)" |
326 using has_derivative_in_compose[OF assms] |
326 using has_derivative_in_compose[OF assms] |
327 by (simp add: comp_def) |
327 by (simp add: comp_def) |
328 |
328 |
329 lemma diff_chain_at[has_derivative_intros]: |
329 lemma diff_chain_at[derivative_intros]: |
330 "(f has_derivative f') (at x) \<Longrightarrow> |
330 "(f has_derivative f') (at x) \<Longrightarrow> |
331 (g has_derivative g') (at (f x)) \<Longrightarrow> ((g \<circ> f) has_derivative (g' \<circ> f')) (at x)" |
331 (g has_derivative g') (at (f x)) \<Longrightarrow> ((g \<circ> f) has_derivative (g' \<circ> f')) (at x)" |
332 using has_derivative_compose[of f f' x UNIV g g'] |
332 using has_derivative_compose[of f f' x UNIV g g'] |
333 by (simp add: comp_def) |
333 by (simp add: comp_def) |
334 |
334 |
542 proof (cases "h = 0") |
542 proof (cases "h = 0") |
543 assume "h \<noteq> 0" |
543 assume "h \<noteq> 0" |
544 from min obtain d where d1: "0 < d" and d2: "\<forall>y\<in>ball x d. f x \<le> f y" |
544 from min obtain d where d1: "0 < d" and d2: "\<forall>y\<in>ball x d. f x \<le> f y" |
545 unfolding eventually_at by (force simp: dist_commute) |
545 unfolding eventually_at by (force simp: dist_commute) |
546 have "FDERIV (\<lambda>r. x + r *\<^sub>R h) 0 :> (\<lambda>r. r *\<^sub>R h)" |
546 have "FDERIV (\<lambda>r. x + r *\<^sub>R h) 0 :> (\<lambda>r. r *\<^sub>R h)" |
547 by (intro has_derivative_eq_intros, auto) |
547 by (intro derivative_eq_intros) auto |
548 then have "FDERIV (\<lambda>r. f (x + r *\<^sub>R h)) 0 :> (\<lambda>k. f' (k *\<^sub>R h))" |
548 then have "FDERIV (\<lambda>r. f (x + r *\<^sub>R h)) 0 :> (\<lambda>k. f' (k *\<^sub>R h))" |
549 by (rule has_derivative_compose, simp add: deriv) |
549 by (rule has_derivative_compose, simp add: deriv) |
550 then have "DERIV (\<lambda>r. f (x + r *\<^sub>R h)) 0 :> f' h" |
550 then have "DERIV (\<lambda>r. f (x + r *\<^sub>R h)) 0 :> f' h" |
551 unfolding has_field_derivative_def by (simp add: f'.scaleR mult_commute_abs) |
551 unfolding has_field_derivative_def by (simp add: f'.scaleR mult_commute_abs) |
552 moreover have "0 < d / norm h" |
552 moreover have "0 < d / norm h" |
675 proof (intro rolle[OF assms(1), of "\<lambda>x. f x - (f b - f a) / (b - a) * x"] ballI) |
675 proof (intro rolle[OF assms(1), of "\<lambda>x. f x - (f b - f a) / (b - a) * x"] ballI) |
676 fix x |
676 fix x |
677 assume x: "x \<in> {a <..< b}" |
677 assume x: "x \<in> {a <..< b}" |
678 show "((\<lambda>x. f x - (f b - f a) / (b - a) * x) has_derivative |
678 show "((\<lambda>x. f x - (f b - f a) / (b - a) * x) has_derivative |
679 (\<lambda>xa. f' x xa - (f b - f a) / (b - a) * xa)) (at x)" |
679 (\<lambda>xa. f' x xa - (f b - f a) / (b - a) * xa)) (at x)" |
680 by (intro has_derivative_intros assms(3)[rule_format,OF x] mult_right_has_derivative) |
680 by (intro derivative_intros assms(3)[rule_format,OF x]) |
681 qed (insert assms(1,2), auto intro!: continuous_intros simp: field_simps) |
681 qed (insert assms(1,2), auto intro!: continuous_intros simp: field_simps) |
682 then obtain x where |
682 then obtain x where |
683 "x \<in> {a <..< b}" |
683 "x \<in> {a <..< b}" |
684 "(\<lambda>xa. f' x xa - (f b - f a) / (b - a) * xa) = (\<lambda>v. 0)" .. |
684 "(\<lambda>xa. f' x xa - (f b - f a) / (b - a) * xa) = (\<lambda>v. 0)" .. |
685 then show ?thesis |
685 then show ?thesis |
1536 using f'g' by auto |
1536 using f'g' by auto |
1537 show "(ph has_derivative (\<lambda>v. v - g' (f' u v))) (at u within ball a d)" |
1537 show "(ph has_derivative (\<lambda>v. v - g' (f' u v))) (at u within ball a d)" |
1538 unfolding ph' * |
1538 unfolding ph' * |
1539 apply (simp add: comp_def) |
1539 apply (simp add: comp_def) |
1540 apply (rule bounded_linear.has_derivative[OF assms(3)]) |
1540 apply (rule bounded_linear.has_derivative[OF assms(3)]) |
1541 apply (rule has_derivative_intros) |
1541 apply (rule derivative_intros) |
1542 defer |
1542 defer |
1543 apply (rule has_derivative_sub[where g'="\<lambda>x.0",unfolded diff_0_right]) |
1543 apply (rule has_derivative_sub[where g'="\<lambda>x.0",unfolded diff_0_right]) |
1544 apply (rule has_derivative_at_within) |
1544 apply (rule has_derivative_at_within) |
1545 using assms(5) and `u \<in> s` `a \<in> s` |
1545 using assms(5) and `u \<in> s` `a \<in> s` |
1546 apply (auto intro!: has_derivative_intros bounded_linear.has_derivative[of _ "\<lambda>x. x"] has_derivative_bounded_linear) |
1546 apply (auto intro!: derivative_intros bounded_linear.has_derivative[of _ "\<lambda>x. x"] has_derivative_bounded_linear) |
1547 done |
1547 done |
1548 have **: "bounded_linear (\<lambda>x. f' u x - f' a x)" "bounded_linear (\<lambda>x. f' a x - f' u x)" |
1548 have **: "bounded_linear (\<lambda>x. f' u x - f' a x)" "bounded_linear (\<lambda>x. f' a x - f' u x)" |
1549 apply (rule_tac[!] bounded_linear_sub) |
1549 apply (rule_tac[!] bounded_linear_sub) |
1550 apply (rule_tac[!] has_derivative_bounded_linear) |
1550 apply (rule_tac[!] has_derivative_bounded_linear) |
1551 using assms(5) `u \<in> s` `a \<in> s` |
1551 using assms(5) `u \<in> s` `a \<in> s` |
1598 apply (rule_tac[!] ballI) |
1598 apply (rule_tac[!] ballI) |
1599 proof - |
1599 proof - |
1600 fix x |
1600 fix x |
1601 assume "x \<in> s" |
1601 assume "x \<in> s" |
1602 show "((\<lambda>a. f m a - f n a) has_derivative (\<lambda>h. f' m x h - f' n x h)) (at x within s)" |
1602 show "((\<lambda>a. f m a - f n a) has_derivative (\<lambda>h. f' m x h - f' n x h)) (at x within s)" |
1603 by (rule has_derivative_intros assms(2)[rule_format] `x\<in>s`)+ |
1603 by (rule derivative_intros assms(2)[rule_format] `x\<in>s`)+ |
1604 show "onorm (\<lambda>h. f' m x h - f' n x h) \<le> 2 * e" |
1604 show "onorm (\<lambda>h. f' m x h - f' n x h) \<le> 2 * e" |
1605 proof (rule onorm_bound) |
1605 proof (rule onorm_bound) |
1606 fix h |
1606 fix h |
1607 have "norm (f' m x h - f' n x h) \<le> norm (f' m x h - g' x h) + norm (f' n x h - g' x h)" |
1607 have "norm (f' m x h - f' n x h) \<le> norm (f' m x h - g' x h) + norm (f' n x h - g' x h)" |
1608 using norm_triangle_ineq[of "f' m x h - g' x h" "- f' n x h + g' x h"] |
1608 using norm_triangle_ineq[of "f' m x h - g' x h" "- f' n x h + g' x h"] |
1931 using assms(4-5) |
1931 using assms(4-5) |
1932 unfolding sums_def |
1932 unfolding sums_def |
1933 apply auto |
1933 apply auto |
1934 done |
1934 done |
1935 |
1935 |
1936 |
|
1937 text {* Considering derivative @{typ "real \<Rightarrow> 'b\<Colon>real_normed_vector"} as a vector. *} |
1936 text {* Considering derivative @{typ "real \<Rightarrow> 'b\<Colon>real_normed_vector"} as a vector. *} |
1938 |
|
1939 definition has_vector_derivative :: "(real \<Rightarrow> 'b::real_normed_vector) \<Rightarrow> 'b \<Rightarrow> real filter \<Rightarrow> bool" |
|
1940 (infix "has'_vector'_derivative" 50) |
|
1941 where "(f has_vector_derivative f') net \<longleftrightarrow> (f has_derivative (\<lambda>x. x *\<^sub>R f')) net" |
|
1942 |
|
1943 definition "vector_derivative f net = (SOME f'. (f has_vector_derivative f') net)" |
|
1944 |
|
1945 lemma vector_derivative_works: |
|
1946 fixes f :: "real \<Rightarrow> 'a::real_normed_vector" |
|
1947 shows "f differentiable net \<longleftrightarrow> (f has_vector_derivative (vector_derivative f net)) net" |
|
1948 (is "?l = ?r") |
|
1949 proof |
|
1950 assume ?l |
|
1951 obtain f' where f': "(f has_derivative f') net" |
|
1952 using `?l` unfolding differentiable_def .. |
|
1953 then interpret bounded_linear f' |
|
1954 by auto |
|
1955 show ?r |
|
1956 unfolding vector_derivative_def has_vector_derivative_def |
|
1957 apply - |
|
1958 apply (rule someI_ex,rule_tac x="f' 1" in exI) |
|
1959 using f' |
|
1960 unfolding scaleR[symmetric] |
|
1961 apply auto |
|
1962 done |
|
1963 next |
|
1964 assume ?r |
|
1965 then show ?l |
|
1966 unfolding vector_derivative_def has_vector_derivative_def differentiable_def |
|
1967 by auto |
|
1968 qed |
|
1969 |
1937 |
1970 lemma has_field_derivative_iff_has_vector_derivative: |
1938 lemma has_field_derivative_iff_has_vector_derivative: |
1971 "(f has_field_derivative y) F \<longleftrightarrow> (f has_vector_derivative y) F" |
1939 "(f has_field_derivative y) F \<longleftrightarrow> (f has_vector_derivative y) F" |
1972 unfolding has_vector_derivative_def has_field_derivative_def real_scaleR_def mult_commute_abs .. |
1940 unfolding has_vector_derivative_def has_field_derivative_def real_scaleR_def mult_commute_abs .. |
|
1941 |
|
1942 lemma has_vector_derivative_const[simp, derivative_intros]: "((\<lambda>x. c) has_vector_derivative 0) net" |
|
1943 by (auto simp: has_vector_derivative_def) |
|
1944 |
|
1945 lemma has_vector_derivative_id[simp, derivative_intros]: "((\<lambda>x. x) has_vector_derivative 1) net" |
|
1946 by (auto simp: has_vector_derivative_def) |
|
1947 |
|
1948 lemma has_vector_derivative_neg[derivative_intros]: |
|
1949 "(f has_vector_derivative f') net \<Longrightarrow> ((\<lambda>x. - f x) has_vector_derivative (- f')) net" |
|
1950 by (auto simp: has_vector_derivative_def) |
|
1951 |
|
1952 lemma has_vector_derivative_add[derivative_intros]: |
|
1953 "(f has_vector_derivative f') net \<Longrightarrow> (g has_vector_derivative g') net \<Longrightarrow> |
|
1954 ((\<lambda>x. f x + g x) has_vector_derivative (f' + g')) net" |
|
1955 by (auto simp: has_vector_derivative_def scaleR_right_distrib) |
|
1956 |
|
1957 lemma has_vector_derivative_sub[derivative_intros]: |
|
1958 "(f has_vector_derivative f') net \<Longrightarrow> (g has_vector_derivative g') net \<Longrightarrow> |
|
1959 ((\<lambda>x. f x - g x) has_vector_derivative (f' - g')) net" |
|
1960 by (auto simp: has_vector_derivative_def scaleR_diff_right) |
|
1961 |
|
1962 lemma (in bounded_linear) has_vector_derivative: |
|
1963 assumes "(g has_vector_derivative g') (at x within s)" |
|
1964 shows "((\<lambda>x. f (g x)) has_vector_derivative f g') (at x within s)" |
|
1965 using has_derivative[OF assms[unfolded has_vector_derivative_def]] |
|
1966 by (simp add: has_vector_derivative_def scaleR) |
|
1967 |
|
1968 lemma (in bounded_bilinear) has_vector_derivative: |
|
1969 assumes "(f has_vector_derivative f') (at x within s)" |
|
1970 and "(g has_vector_derivative g') (at x within s)" |
|
1971 shows "((\<lambda>x. f x ** g x) has_vector_derivative (f x ** g' + f' ** g x)) (at x within s)" |
|
1972 using FDERIV[OF assms(1-2)[unfolded has_vector_derivative_def]] |
|
1973 by (simp add: has_vector_derivative_def scaleR_right scaleR_left scaleR_right_distrib) |
|
1974 |
|
1975 lemma has_vector_derivative_scaleR[derivative_intros]: |
|
1976 "(f has_field_derivative f') (at x within s) \<Longrightarrow> (g has_vector_derivative g') (at x within s) \<Longrightarrow> |
|
1977 ((\<lambda>x. f x *\<^sub>R g x) has_vector_derivative (f x *\<^sub>R g' + f' *\<^sub>R g x)) (at x within s)" |
|
1978 unfolding has_field_derivative_iff_has_vector_derivative |
|
1979 by (rule bounded_bilinear.has_vector_derivative[OF bounded_bilinear_scaleR]) |
|
1980 |
|
1981 lemma has_vector_derivative_mult[derivative_intros]: |
|
1982 "(f has_vector_derivative f') (at x within s) \<Longrightarrow> (g has_vector_derivative g') (at x within s) \<Longrightarrow> |
|
1983 ((\<lambda>x. f x * g x) has_vector_derivative (f x * g' + f' * g x :: 'a :: real_normed_algebra)) (at x within s)" |
|
1984 by (rule bounded_bilinear.has_vector_derivative[OF bounded_bilinear_mult]) |
|
1985 |
|
1986 definition "vector_derivative f net = (SOME f'. (f has_vector_derivative f') net)" |
1973 |
1987 |
1974 lemma vector_derivative_unique_at: |
1988 lemma vector_derivative_unique_at: |
1975 assumes "(f has_vector_derivative f') (at x)" |
1989 assumes "(f has_vector_derivative f') (at x)" |
1976 and "(f has_vector_derivative f'') (at x)" |
1990 and "(f has_vector_derivative f'') (at x)" |
1977 shows "f' = f''" |
1991 shows "f' = f''" |
1980 using assms [unfolded has_vector_derivative_def] |
1994 using assms [unfolded has_vector_derivative_def] |
1981 by (rule frechet_derivative_unique_at) |
1995 by (rule frechet_derivative_unique_at) |
1982 then show ?thesis |
1996 then show ?thesis |
1983 unfolding fun_eq_iff by auto |
1997 unfolding fun_eq_iff by auto |
1984 qed |
1998 qed |
|
1999 |
|
2000 lemma vector_derivative_works: |
|
2001 "f differentiable net \<longleftrightarrow> (f has_vector_derivative (vector_derivative f net)) net" |
|
2002 (is "?l = ?r") |
|
2003 proof |
|
2004 assume ?l |
|
2005 obtain f' where f': "(f has_derivative f') net" |
|
2006 using `?l` unfolding differentiable_def .. |
|
2007 then interpret bounded_linear f' |
|
2008 by auto |
|
2009 show ?r |
|
2010 unfolding vector_derivative_def has_vector_derivative_def |
|
2011 by (rule someI[of _ "f' 1"]) (simp add: scaleR[symmetric] f') |
|
2012 qed (auto simp: vector_derivative_def has_vector_derivative_def differentiable_def) |
1985 |
2013 |
1986 lemma vector_derivative_unique_within_closed_interval: |
2014 lemma vector_derivative_unique_within_closed_interval: |
1987 assumes "a < b" |
2015 assumes "a < b" |
1988 and "x \<in> cbox a b" |
2016 and "x \<in> cbox a b" |
1989 assumes "(f has_vector_derivative f') (at x within cbox a b)" |
2017 assumes "(f has_vector_derivative f') (at x within cbox a b)" |
2026 using assms |
2054 using assms |
2027 apply (auto simp add:has_vector_derivative_def) |
2055 apply (auto simp add:has_vector_derivative_def) |
2028 done |
2056 done |
2029 |
2057 |
2030 lemma has_vector_derivative_within_subset: |
2058 lemma has_vector_derivative_within_subset: |
2031 "(f has_vector_derivative f') (at x within s) \<Longrightarrow> t \<subseteq> s \<Longrightarrow> |
2059 "(f has_vector_derivative f') (at x within s) \<Longrightarrow> t \<subseteq> s \<Longrightarrow> (f has_vector_derivative f') (at x within t)" |
2032 (f has_vector_derivative f') (at x within t)" |
2060 by (auto simp: has_vector_derivative_def intro: has_derivative_within_subset) |
2033 unfolding has_vector_derivative_def |
|
2034 apply (rule has_derivative_within_subset) |
|
2035 apply auto |
|
2036 done |
|
2037 |
|
2038 lemma has_vector_derivative_const: "((\<lambda>x. c) has_vector_derivative 0) net" |
|
2039 unfolding has_vector_derivative_def |
|
2040 using has_derivative_const |
|
2041 by auto |
|
2042 |
|
2043 lemma has_vector_derivative_id: "((\<lambda>x::real. x) has_vector_derivative 1) net" |
|
2044 unfolding has_vector_derivative_def |
|
2045 using has_derivative_id |
|
2046 by auto |
|
2047 |
|
2048 lemma has_vector_derivative_cmul: |
|
2049 "(f has_vector_derivative f') net \<Longrightarrow> |
|
2050 ((\<lambda>x. c *\<^sub>R f x) has_vector_derivative (c *\<^sub>R f')) net" |
|
2051 unfolding has_vector_derivative_def |
|
2052 apply (drule scaleR_right_has_derivative) |
|
2053 apply (auto simp add: algebra_simps) |
|
2054 done |
|
2055 |
|
2056 lemma has_vector_derivative_cmul_eq: |
|
2057 assumes "c \<noteq> 0" |
|
2058 shows "(((\<lambda>x. c *\<^sub>R f x) has_vector_derivative (c *\<^sub>R f')) net \<longleftrightarrow> (f has_vector_derivative f') net)" |
|
2059 apply (rule iffI) |
|
2060 apply (drule has_vector_derivative_cmul[where c="1/c"]) |
|
2061 apply (rule_tac [2] has_vector_derivative_cmul) |
|
2062 using assms |
|
2063 apply auto |
|
2064 done |
|
2065 |
|
2066 lemma has_vector_derivative_neg: |
|
2067 "(f has_vector_derivative f') net \<Longrightarrow> ((\<lambda>x. - f x) has_vector_derivative (- f')) net" |
|
2068 unfolding has_vector_derivative_def |
|
2069 apply (drule has_derivative_neg) |
|
2070 apply auto |
|
2071 done |
|
2072 |
|
2073 lemma has_vector_derivative_add: |
|
2074 assumes "(f has_vector_derivative f') net" |
|
2075 and "(g has_vector_derivative g') net" |
|
2076 shows "((\<lambda>x. f x + g x) has_vector_derivative (f' + g')) net" |
|
2077 using has_derivative_add[OF assms[unfolded has_vector_derivative_def]] |
|
2078 unfolding has_vector_derivative_def |
|
2079 unfolding scaleR_right_distrib |
|
2080 by auto |
|
2081 |
|
2082 lemma has_vector_derivative_sub: |
|
2083 assumes "(f has_vector_derivative f') net" |
|
2084 and "(g has_vector_derivative g') net" |
|
2085 shows "((\<lambda>x. f x - g x) has_vector_derivative (f' - g')) net" |
|
2086 using has_derivative_sub[OF assms[unfolded has_vector_derivative_def]] |
|
2087 unfolding has_vector_derivative_def scaleR_right_diff_distrib |
|
2088 by auto |
|
2089 |
|
2090 lemma has_vector_derivative_bilinear_within: |
|
2091 assumes "(f has_vector_derivative f') (at x within s)" |
|
2092 and "(g has_vector_derivative g') (at x within s)" |
|
2093 assumes "bounded_bilinear h" |
|
2094 shows "((\<lambda>x. h (f x) (g x)) has_vector_derivative (h (f x) g' + h f' (g x))) (at x within s)" |
|
2095 proof - |
|
2096 interpret bounded_bilinear h |
|
2097 using assms by auto |
|
2098 show ?thesis |
|
2099 using has_derivative_bilinear_within[OF assms(1-2)[unfolded has_vector_derivative_def], of h] |
|
2100 unfolding o_def has_vector_derivative_def |
|
2101 using assms(3) |
|
2102 unfolding scaleR_right scaleR_left scaleR_right_distrib |
|
2103 by auto |
|
2104 qed |
|
2105 |
|
2106 lemma has_vector_derivative_bilinear_at: |
|
2107 assumes "(f has_vector_derivative f') (at x)" |
|
2108 and "(g has_vector_derivative g') (at x)" |
|
2109 assumes "bounded_bilinear h" |
|
2110 shows "((\<lambda>x. h (f x) (g x)) has_vector_derivative (h (f x) g' + h f' (g x))) (at x)" |
|
2111 using has_vector_derivative_bilinear_within[OF assms] . |
|
2112 |
2061 |
2113 lemma has_vector_derivative_at_within: |
2062 lemma has_vector_derivative_at_within: |
2114 "(f has_vector_derivative f') (at x) \<Longrightarrow> (f has_vector_derivative f') (at x within s)" |
2063 "(f has_vector_derivative f') (at x) \<Longrightarrow> (f has_vector_derivative f') (at x within s)" |
2115 unfolding has_vector_derivative_def |
2064 unfolding has_vector_derivative_def |
2116 by (rule has_derivative_at_within) |
2065 by (rule has_derivative_at_within) |