37 show ?l unfolding deriv_def LIM_def apply safe apply(drule as,safe) |
37 show ?l unfolding deriv_def LIM_def apply safe apply(drule as,safe) |
38 apply(rule_tac x=d in exI,safe) apply(erule_tac x="xa + x" in allE) |
38 apply(rule_tac x=d in exI,safe) apply(erule_tac x="xa + x" in allE) |
39 unfolding dist_norm diff_0_right norm_scaleR |
39 unfolding dist_norm diff_0_right norm_scaleR |
40 unfolding dist_norm netlimit_at[of x] by(auto simp add:algebra_simps *) qed |
40 unfolding dist_norm netlimit_at[of x] by(auto simp add:algebra_simps *) qed |
41 |
41 |
42 lemma FDERIV_conv_has_derivative:"FDERIV f (x::'a::{real_normed_vector,perfect_space}) :> f' = (f has_derivative f') (at x)" (is "?l = ?r") proof |
42 lemma netlimit_at_vector: |
|
43 fixes a :: "'a::real_normed_vector" |
|
44 shows "netlimit (at a) = a" |
|
45 proof (cases "\<exists>x. x \<noteq> a") |
|
46 case True then obtain x where x: "x \<noteq> a" .. |
|
47 have "\<not> trivial_limit (at a)" |
|
48 unfolding trivial_limit_def eventually_at dist_norm |
|
49 apply clarsimp |
|
50 apply (rule_tac x="a + scaleR (d / 2) (sgn (x - a))" in exI) |
|
51 apply (simp add: norm_sgn sgn_zero_iff x) |
|
52 done |
|
53 thus ?thesis |
|
54 by (rule netlimit_within [of a UNIV, unfolded within_UNIV]) |
|
55 qed simp |
|
56 |
|
57 lemma FDERIV_conv_has_derivative: |
|
58 shows "FDERIV f x :> f' = (f has_derivative f') (at x)" (is "?l = ?r") |
|
59 proof |
43 assume ?l note as = this[unfolded fderiv_def] |
60 assume ?l note as = this[unfolded fderiv_def] |
44 show ?r unfolding has_derivative_def Lim_at apply-apply(rule,rule as[THEN conjunct1]) proof(rule,rule) |
61 show ?r unfolding has_derivative_def Lim_at apply-apply(rule,rule as[THEN conjunct1]) proof(rule,rule) |
45 fix e::real assume "e>0" |
62 fix e::real assume "e>0" |
46 guess d using as[THEN conjunct2,unfolded LIM_def,rule_format,OF`e>0`] .. |
63 guess d using as[THEN conjunct2,unfolded LIM_def,rule_format,OF`e>0`] .. |
47 thus "\<exists>d>0. \<forall>xa. 0 < dist xa x \<and> dist xa x < d \<longrightarrow> |
64 thus "\<exists>d>0. \<forall>xa. 0 < dist xa x \<and> dist xa x < d \<longrightarrow> |
48 dist ((1 / norm (xa - netlimit (at x))) *\<^sub>R (f xa - (f (netlimit (at x)) + f' (xa - netlimit (at x))))) (0) < e" |
65 dist ((1 / norm (xa - netlimit (at x))) *\<^sub>R (f xa - (f (netlimit (at x)) + f' (xa - netlimit (at x))))) (0) < e" |
49 apply(rule_tac x=d in exI) apply(erule conjE,rule,assumption) apply rule apply(erule_tac x="xa - x" in allE) |
66 apply(rule_tac x=d in exI) apply(erule conjE,rule,assumption) apply rule apply(erule_tac x="xa - x" in allE) |
50 unfolding dist_norm netlimit_at[of x] by (auto simp add: diff_diff_eq) qed next |
67 unfolding dist_norm netlimit_at_vector[of x] by (auto simp add: diff_diff_eq) qed next |
51 assume ?r note as = this[unfolded has_derivative_def] |
68 assume ?r note as = this[unfolded has_derivative_def] |
52 show ?l unfolding fderiv_def LIM_def apply-apply(rule,rule as[THEN conjunct1]) proof(rule,rule) |
69 show ?l unfolding fderiv_def LIM_def apply-apply(rule,rule as[THEN conjunct1]) proof(rule,rule) |
53 fix e::real assume "e>0" |
70 fix e::real assume "e>0" |
54 guess d using as[THEN conjunct2,unfolded Lim_at,rule_format,OF`e>0`] .. |
71 guess d using as[THEN conjunct2,unfolded Lim_at,rule_format,OF`e>0`] .. |
55 thus "\<exists>s>0. \<forall>xa. xa \<noteq> 0 \<and> dist xa 0 < s \<longrightarrow> dist (norm (f (x + xa) - f x - f' xa) / norm xa) 0 < e" apply- |
72 thus "\<exists>s>0. \<forall>xa. xa \<noteq> 0 \<and> dist xa 0 < s \<longrightarrow> dist (norm (f (x + xa) - f x - f' xa) / norm xa) 0 < e" apply- |
56 apply(rule_tac x=d in exI) apply(erule conjE,rule,assumption) apply rule apply(erule_tac x="xa + x" in allE) |
73 apply(rule_tac x=d in exI) apply(erule conjE,rule,assumption) apply rule apply(erule_tac x="xa + x" in allE) |
57 unfolding dist_norm netlimit_at[of x] by (auto simp add: diff_diff_eq add.commute) qed qed |
74 unfolding dist_norm netlimit_at_vector[of x] by (auto simp add: diff_diff_eq add.commute) qed qed |
58 |
75 |
59 subsection {* These are the only cases we'll care about, probably. *} |
76 subsection {* These are the only cases we'll care about, probably. *} |
60 |
77 |
61 lemma has_derivative_within: "(f has_derivative f') (at x within s) \<longleftrightarrow> |
78 lemma has_derivative_within: "(f has_derivative f') (at x within s) \<longleftrightarrow> |
62 bounded_linear f' \<and> ((\<lambda>y. (1 / norm(y - x)) *\<^sub>R (f y - (f x + f' (y - x)))) ---> 0) (at x within s)" |
79 bounded_linear f' \<and> ((\<lambda>y. (1 / norm(y - x)) *\<^sub>R (f y - (f x + f' (y - x)))) ---> 0) (at x within s)" |
84 lemma has_derivative_at_within: "(f has_derivative f') (at x) \<Longrightarrow> (f has_derivative f') (at x within s)" |
101 lemma has_derivative_at_within: "(f has_derivative f') (at x) \<Longrightarrow> (f has_derivative f') (at x within s)" |
85 unfolding has_derivative_within' has_derivative_at' by meson |
102 unfolding has_derivative_within' has_derivative_at' by meson |
86 |
103 |
87 lemma has_derivative_within_open: |
104 lemma has_derivative_within_open: |
88 "a \<in> s \<Longrightarrow> open s \<Longrightarrow> ((f has_derivative f') (at a within s) \<longleftrightarrow> (f has_derivative f') (at a))" |
105 "a \<in> s \<Longrightarrow> open s \<Longrightarrow> ((f has_derivative f') (at a within s) \<longleftrightarrow> (f has_derivative f') (at a))" |
89 unfolding has_derivative_within has_derivative_at using Lim_within_open by auto |
106 by (simp only: at_within_interior interior_open) |
90 |
107 |
91 lemma bounded_linear_imp_linear: "bounded_linear f \<Longrightarrow> linear f" (* TODO: move elsewhere *) |
108 lemma bounded_linear_imp_linear: "bounded_linear f \<Longrightarrow> linear f" (* TODO: move elsewhere *) |
92 proof - |
109 proof - |
93 assume "bounded_linear f" |
110 assume "bounded_linear f" |
94 then interpret f: bounded_linear f . |
111 then interpret f: bounded_linear f . |
270 lemma differentiable_at_withinI: "f differentiable (at x) \<Longrightarrow> f differentiable (at x within s)" |
287 lemma differentiable_at_withinI: "f differentiable (at x) \<Longrightarrow> f differentiable (at x within s)" |
271 unfolding differentiable_def using has_derivative_at_within by blast |
288 unfolding differentiable_def using has_derivative_at_within by blast |
272 |
289 |
273 lemma differentiable_within_open: assumes "a \<in> s" "open s" shows |
290 lemma differentiable_within_open: assumes "a \<in> s" "open s" shows |
274 "f differentiable (at a within s) \<longleftrightarrow> (f differentiable (at a))" |
291 "f differentiable (at a within s) \<longleftrightarrow> (f differentiable (at a))" |
275 unfolding differentiable_def has_derivative_within_open[OF assms] by auto |
292 using assms by (simp only: at_within_interior interior_open) |
276 |
293 |
277 lemma differentiable_on_eq_differentiable_at: "open s \<Longrightarrow> (f differentiable_on s \<longleftrightarrow> (\<forall>x\<in>s. f differentiable at x))" |
294 lemma differentiable_on_eq_differentiable_at: "open s \<Longrightarrow> (f differentiable_on s \<longleftrightarrow> (\<forall>x\<in>s. f differentiable at x))" |
278 unfolding differentiable_on_def by(auto simp add: differentiable_within_open) |
295 unfolding differentiable_on_def by(auto simp add: differentiable_within_open) |
279 |
296 |
280 lemma differentiable_transform_within: |
297 lemma differentiable_transform_within: |
475 lemma differentiable_chain_within: |
492 lemma differentiable_chain_within: |
476 "f differentiable (at x within s) \<Longrightarrow> g differentiable (at(f x) within (f ` s)) |
493 "f differentiable (at x within s) \<Longrightarrow> g differentiable (at(f x) within (f ` s)) |
477 \<Longrightarrow> (g o f) differentiable (at x within s)" |
494 \<Longrightarrow> (g o f) differentiable (at x within s)" |
478 unfolding differentiable_def by(meson diff_chain_within) |
495 unfolding differentiable_def by(meson diff_chain_within) |
479 |
496 |
480 subsection {* Uniqueness of derivative. *) |
497 subsection {* Uniqueness of derivative *} |
481 (* *) |
498 |
482 (* The general result is a bit messy because we need approachability of the *) |
499 text {* |
483 (* limit point from any direction. But OK for nontrivial intervals etc. *} |
500 The general result is a bit messy because we need approachability of the |
|
501 limit point from any direction. But OK for nontrivial intervals etc. |
|
502 *} |
484 |
503 |
485 lemma frechet_derivative_unique_within: fixes f::"'a::euclidean_space \<Rightarrow> 'b::real_normed_vector" |
504 lemma frechet_derivative_unique_within: fixes f::"'a::euclidean_space \<Rightarrow> 'b::real_normed_vector" |
486 assumes "(f has_derivative f') (at x within s)" "(f has_derivative f'') (at x within s)" |
505 assumes "(f has_derivative f') (at x within s)" "(f has_derivative f'') (at x within s)" |
487 "(\<forall>i<DIM('a). \<forall>e>0. \<exists>d. 0 < abs(d) \<and> abs(d) < e \<and> (x + d *\<^sub>R basis i) \<in> s)" shows "f' = f''" proof- |
506 "(\<forall>i<DIM('a). \<forall>e>0. \<exists>d. 0 < abs(d) \<and> abs(d) < e \<and> (x + d *\<^sub>R basis i) \<in> s)" shows "f' = f''" proof- |
488 note as = assms(1,2)[unfolded has_derivative_def] |
507 note as = assms(1,2)[unfolded has_derivative_def] |
505 also have "\<dots> = e" unfolding e_def using c[THEN conjunct1] using norm_minus_cancel[of "f' (basis i) - f'' (basis i)"] by (auto simp add: add.commute ab_diff_minus) |
524 also have "\<dots> = e" unfolding e_def using c[THEN conjunct1] using norm_minus_cancel[of "f' (basis i) - f'' (basis i)"] by (auto simp add: add.commute ab_diff_minus) |
506 finally show False using c using d[THEN conjunct2,rule_format,of "x + c *\<^sub>R basis i"] |
525 finally show False using c using d[THEN conjunct2,rule_format,of "x + c *\<^sub>R basis i"] |
507 unfolding dist_norm unfolding f'.scaleR f''.scaleR f'.add f''.add f'.diff f''.diff |
526 unfolding dist_norm unfolding f'.scaleR f''.scaleR f'.add f''.add f'.diff f''.diff |
508 scaleR_scaleR scaleR_right_diff_distrib scaleR_right_distrib using i by auto qed qed |
527 scaleR_scaleR scaleR_right_diff_distrib scaleR_right_distrib using i by auto qed qed |
509 |
528 |
510 lemma frechet_derivative_unique_at: fixes f::"'a::euclidean_space \<Rightarrow> 'b::real_normed_vector" |
529 lemma frechet_derivative_unique_at: |
511 shows "(f has_derivative f') (at x) \<Longrightarrow> (f has_derivative f'') (at x) \<Longrightarrow> f' = f''" |
530 shows "(f has_derivative f') (at x) \<Longrightarrow> (f has_derivative f'') (at x) \<Longrightarrow> f' = f''" |
512 apply(rule frechet_derivative_unique_within[of f f' x UNIV f'']) unfolding within_UNIV apply(assumption)+ |
531 unfolding FDERIV_conv_has_derivative [symmetric] |
513 apply(rule,rule,rule,rule) apply(rule_tac x="e/2" in exI) by auto |
532 by (rule FDERIV_unique) |
514 |
533 |
515 lemma "isCont f x = continuous (at x) f" unfolding isCont_def LIM_def |
534 lemma "isCont f x = continuous (at x) f" unfolding isCont_def LIM_def |
516 unfolding continuous_at Lim_at unfolding dist_nz by auto |
535 unfolding continuous_at Lim_at unfolding dist_nz by auto |
517 |
536 |
518 lemma frechet_derivative_unique_within_closed_interval: fixes f::"'a::ordered_euclidean_space \<Rightarrow> 'b::real_normed_vector" |
537 lemma frechet_derivative_unique_within_closed_interval: fixes f::"'a::ordered_euclidean_space \<Rightarrow> 'b::real_normed_vector" |
545 by (simp add: at_within_interior interior_open open_interval) |
564 by (simp add: at_within_interior interior_open open_interval) |
546 from assms(2,3) [unfolded *] show "f' = f''" |
565 from assms(2,3) [unfolded *] show "f' = f''" |
547 by (rule frechet_derivative_unique_at) |
566 by (rule frechet_derivative_unique_at) |
548 qed |
567 qed |
549 |
568 |
550 lemma frechet_derivative_at: fixes f::"'a::euclidean_space \<Rightarrow> 'b::real_normed_vector" |
569 lemma frechet_derivative_at: |
551 shows "(f has_derivative f') (at x) \<Longrightarrow> (f' = frechet_derivative f (at x))" |
570 shows "(f has_derivative f') (at x) \<Longrightarrow> (f' = frechet_derivative f (at x))" |
552 apply(rule frechet_derivative_unique_at[of f],assumption) |
571 apply(rule frechet_derivative_unique_at[of f],assumption) |
553 unfolding frechet_derivative_works[THEN sym] using differentiable_def by auto |
572 unfolding frechet_derivative_works[THEN sym] using differentiable_def by auto |
554 |
573 |
555 lemma frechet_derivative_within_closed_interval: fixes f::"'a::ordered_euclidean_space \<Rightarrow> 'b::real_normed_vector" |
574 lemma frechet_derivative_within_closed_interval: fixes f::"'a::ordered_euclidean_space \<Rightarrow> 'b::real_normed_vector" |
1239 thus ?r unfolding vector_derivative_def has_vector_derivative_def |
1258 thus ?r unfolding vector_derivative_def has_vector_derivative_def |
1240 apply-apply(rule someI_ex,rule_tac x="f' 1" in exI) |
1259 apply-apply(rule someI_ex,rule_tac x="f' 1" in exI) |
1241 using f' unfolding scaleR[THEN sym] by auto |
1260 using f' unfolding scaleR[THEN sym] by auto |
1242 next assume ?r thus ?l unfolding vector_derivative_def has_vector_derivative_def differentiable_def by auto qed |
1261 next assume ?r thus ?l unfolding vector_derivative_def has_vector_derivative_def differentiable_def by auto qed |
1243 |
1262 |
1244 lemma vector_derivative_unique_at: fixes f::"real\<Rightarrow> 'n::euclidean_space" |
1263 lemma vector_derivative_unique_at: |
1245 assumes "(f has_vector_derivative f') (at x)" "(f has_vector_derivative f'') (at x)" shows "f' = f''" proof- |
1264 assumes "(f has_vector_derivative f') (at x)" |
1246 have *:"(\<lambda>x. x *\<^sub>R f') = (\<lambda>x. x *\<^sub>R f'')" apply(rule frechet_derivative_unique_at) |
1265 assumes "(f has_vector_derivative f'') (at x)" |
1247 using assms[unfolded has_vector_derivative_def] by auto |
1266 shows "f' = f''" |
1248 show ?thesis proof(rule ccontr) assume "f' \<noteq> f''" moreover |
1267 proof- |
1249 hence "(\<lambda>x. x *\<^sub>R f') = (\<lambda>x. x *\<^sub>R f'')" using * by auto |
1268 have "(\<lambda>x. x *\<^sub>R f') = (\<lambda>x. x *\<^sub>R f'')" |
1250 ultimately show False unfolding expand_fun_eq by auto qed qed |
1269 using assms [unfolded has_vector_derivative_def] |
|
1270 by (rule frechet_derivative_unique_at) |
|
1271 thus ?thesis unfolding expand_fun_eq by auto |
|
1272 qed |
1251 |
1273 |
1252 lemma vector_derivative_unique_within_closed_interval: fixes f::"real \<Rightarrow> 'n::ordered_euclidean_space" |
1274 lemma vector_derivative_unique_within_closed_interval: fixes f::"real \<Rightarrow> 'n::ordered_euclidean_space" |
1253 assumes "a < b" "x \<in> {a..b}" |
1275 assumes "a < b" "x \<in> {a..b}" |
1254 "(f has_vector_derivative f') (at x within {a..b})" |
1276 "(f has_vector_derivative f') (at x within {a..b})" |
1255 "(f has_vector_derivative f'') (at x within {a..b})" shows "f' = f''" proof- |
1277 "(f has_vector_derivative f'') (at x within {a..b})" shows "f' = f''" proof- |
1258 using assms(3-)[unfolded has_vector_derivative_def] using assms(1-2) by auto |
1280 using assms(3-)[unfolded has_vector_derivative_def] using assms(1-2) by auto |
1259 show ?thesis proof(rule ccontr) assume "f' \<noteq> f''" moreover |
1281 show ?thesis proof(rule ccontr) assume "f' \<noteq> f''" moreover |
1260 hence "(\<lambda>x. x *\<^sub>R f') 1 = (\<lambda>x. x *\<^sub>R f'') 1" using * by (auto simp: expand_fun_eq) |
1282 hence "(\<lambda>x. x *\<^sub>R f') 1 = (\<lambda>x. x *\<^sub>R f'') 1" using * by (auto simp: expand_fun_eq) |
1261 ultimately show False unfolding o_def by auto qed qed |
1283 ultimately show False unfolding o_def by auto qed qed |
1262 |
1284 |
1263 lemma vector_derivative_at: fixes f::"real \<Rightarrow> 'a::euclidean_space" shows |
1285 lemma vector_derivative_at: |
1264 "(f has_vector_derivative f') (at x) \<Longrightarrow> vector_derivative f (at x) = f'" |
1286 shows "(f has_vector_derivative f') (at x) \<Longrightarrow> vector_derivative f (at x) = f'" |
1265 apply(rule vector_derivative_unique_at) defer apply assumption |
1287 apply(rule vector_derivative_unique_at) defer apply assumption |
1266 unfolding vector_derivative_works[THEN sym] differentiable_def |
1288 unfolding vector_derivative_works[THEN sym] differentiable_def |
1267 unfolding has_vector_derivative_def by auto |
1289 unfolding has_vector_derivative_def by auto |
1268 |
1290 |
1269 lemma vector_derivative_within_closed_interval: fixes f::"real \<Rightarrow> 'a::ordered_euclidean_space" |
1291 lemma vector_derivative_within_closed_interval: fixes f::"real \<Rightarrow> 'a::ordered_euclidean_space" |