src/HOL/Multivariate_Analysis/Derivative.thy
changeset 37730 1a24950dae33
parent 37650 181a70d7b525
child 39198 f967a16dfcdd
equal deleted inserted replaced
37729:daea77769276 37730:1a24950dae33
    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"