theory Derivative imports
Bounded_Linear_Function
Line_Segment
Convex_Euclidean_Space begin
declare bounded_linear_inner_left [intro]
declare has_derivative_bounded_linear[dest]
subsection‹Derivatives›
lemma has_derivative_add_const: "(f has_derivative f') net ==> ((λx. f x + c) has_derivative f') net" by (intro derivative_eq_intros) auto
subsection✐‹tag unimportant›‹Derivative with composed bilinear function›
text‹More explicit epsilon-delta forms.›
proposition has_derivative_within': "(f has_derivative f')(at x within s) ⟷ bounded_linear f' ∧ (∀e>0. ∃d>0. ∀x'∈s. 0 < norm (x' - x) ∧ norm (x' - x) < d ⟶ norm (f x' - f x - f'(x' - x)) / norm (x' - x) < e)" unfolding has_derivative_within Lim_within dist_norm by (simp add: diff_diff_eq)
lemma has_derivative_at': "(f has_derivative f') (at x) ⟷ bounded_linear f' ∧ (∀e>0. ∃d>0. ∀x'. 0 < norm (x' - x) ∧ norm (x' - x) < d ⟶ norm (f x' - f x - f'(x' - x)) / norm (x' - x) < e)" using has_derivative_within' [of f f' x UNIV] by simp
lemma has_derivative_componentwise_within: "(f has_derivative f') (at a within S) ⟷ (∀i ∈ Basis. ((λx. f x ∙ i) has_derivative (λx. f' x ∙ i)) (at a within S))" apply (simp add: has_derivative_within) apply (subst tendsto_componentwise_iff) apply (simp add: ball_conj_distrib inner_diff_left inner_left_distrib flip: bounded_linear_componentwise_iff) done
lemma has_derivative_at_withinI: "(f has_derivative f') (at x) ==> (f has_derivative f') (at x within s)" unfolding has_derivative_within' has_derivative_at' by blast
lemma has_derivative_right: fixes f :: "real → real" and y :: "real" shows"(f has_derivative ((*) y)) (at x within ({x <..} ∩ I)) ⟷ ((λt. (f x - f t) / (x - t)) ---> y) (at x within ({x <..} ∩ I))" proof - have"((λt. (f t - (f x + y * (t - x))) / ∣t - x∣) ---> 0) (at x within ({x<..} ∩ I)) ⟷ ((λt. (f t - f x) / (t - x) - y) ---> 0) (at x within ({x<..} ∩ I))" by (intro Lim_cong_within) (auto simp add: diff_divide_distrib add_divide_distrib) alsohave"…⟷ ((λt. (f t - f x) / (t - x)) ---> y) (at x within ({x<..} ∩ I))" by (simp add: Lim_null[symmetric]) alsohave"…⟷ ((λt. (f x - f t) / (x - t)) ---> y) (at x within ({x<..} ∩ I))" by (intro Lim_cong_within) (simp_all add: field_simps) finallyshow ?thesis by (simp add: bounded_linear_mult_right has_derivative_within) qed
subsubsection‹Caratheodory characterization›
lemma DERIV_caratheodory_within: "(f has_field_derivative l) (at x within S) ⟷ (∃g. (∀z. f z - f x = g z * (z - x)) ∧ continuous (at x within S) g ∧ g x = l)"
(is"?lhs = ?rhs") proof assume ?lhs show ?rhs proof (intro exI conjI) let ?g = "(%z. if z = x then l else (f z - f x) / (z-x))" show"∀z. f z - f x = ?g z * (z-x)"by simp show"continuous (at x within S) ?g"using‹?lhs› by (auto simp add: continuous_within has_field_derivative_iff cong: Lim_cong_within) show"?g x = l"by simp qed next assume ?rhs thenobtain g where "(∀z. f z - f x = g z * (z-x))"and"continuous (at x within S) g"and"g x = l"by blast thus ?lhs by (auto simp add: continuous_within has_field_derivative_iff cong: Lim_cong_within) qed
subsection‹Differentiability›
definition✐‹tag important›
differentiable_on :: "('a::real_normed_vector → 'b::real_normed_vector) → 'a set → bool"
(infix‹differentiable'_on›50) where"f differentiable_on s ⟷ (∀x∈s. f differentiable (at x within s))"
lemma differentiableI: "(f has_derivative f') net ==> f differentiable net" unfolding differentiable_def by auto
lemma differentiable_onD: "[f differentiable_on S; x ∈ S]==> f differentiable (at x within S)" using differentiable_on_def by blast
lemma differentiable_at_withinI: "f differentiable (at x) ==> f differentiable (at x within s)" unfolding differentiable_def using has_derivative_at_withinI by blast
lemma differentiable_at_imp_differentiable_on: "(∧x. x ∈ s ==> f differentiable at x) ==> f differentiable_on s" by (metis differentiable_at_withinI differentiable_on_def)
corollary✐‹tag unimportant› differentiable_iff_scaleR: fixes f :: "real → 'a::real_normed_vector" shows"f differentiable F ⟷ (∃d. (f has_derivative (λx. x *R d)) F)" by (auto simp: differentiable_def dest: has_derivative_linear linear_imp_scaleR)
lemma differentiable_on_eq_differentiable_at: "open s ==> f differentiable_on s ⟷ (∀x∈s. f differentiable at x)" unfolding differentiable_on_def by (metis at_within_interior interior_open)
lemma differentiable_transform_within: assumes"f differentiable (at x within s)" and"0 < d" and"x ∈ s" and"∧x'. [x'∈s; dist x' x < d]==> f x' = g x'" shows"g differentiable (at x within s)" using assms has_derivative_transform_within unfolding differentiable_def by blast
lemma differentiable_on_const [simp, derivative_intros]: "(λz. c) differentiable_on S" by (simp add: differentiable_on_def)
lemma differentiable_on_mult [simp, derivative_intros]: fixes f :: "'M::real_normed_vector → 'a::real_normed_algebra" shows"[f differentiable_on S; g differentiable_on S]==> (λz. f z * g z) differentiable_on S" unfolding differentiable_on_def differentiable_def using differentiable_def differentiable_mult by blast
lemma differentiable_on_compose: "[g differentiable_on S; f differentiable_on (g ` S)]==> (λx. f (g x)) differentiable_on S" by (simp add: differentiable_in_compose differentiable_on_def)
lemma bounded_linear_imp_differentiable_on: "bounded_linear f ==> f differentiable_on S" by (simp add: differentiable_on_def bounded_linear_imp_differentiable)
lemma linear_imp_differentiable_on: fixes f :: "'a::euclidean_space → 'b::real_normed_vector" shows"linear f ==> f differentiable_on S" by (simp add: differentiable_on_def linear_imp_differentiable)
lemma differentiable_on_minus [simp, derivative_intros]: "f differentiable_on S ==> (λz. -(f z)) differentiable_on S" by (simp add: differentiable_on_def)
lemma differentiable_on_add [simp, derivative_intros]: "[f differentiable_on S; g differentiable_on S]==> (λz. f z + g z) differentiable_on S" by (simp add: differentiable_on_def)
lemma differentiable_on_diff [simp, derivative_intros]: "[f differentiable_on S; g differentiable_on S]==> (λz. f z - g z) differentiable_on S" by (simp add: differentiable_on_def)
lemma differentiable_on_inverse [simp, derivative_intros]: fixes f :: "'a :: real_normed_vector → 'b :: real_normed_field" shows"f differentiable_on S ==> (∧x. x ∈ S ==> f x ≠ 0) ==> (λx. inverse (f x)) differentiable_on S" by (simp add: differentiable_on_def)
lemma differentiable_on_scaleR [derivative_intros, simp]: "[f differentiable_on S; g differentiable_on S]==> (λx. f x *R g x) differentiable_on S" unfolding differentiable_on_def by (blast intro: differentiable_scaleR)
lemma has_derivative_sqnorm_at [derivative_intros, simp]: "((λx. (norm x)2) has_derivative (λx. 2 *R (a ∙ x))) (at a)" using bounded_bilinear.FDERIV [of "(∙)" id id a _ id id] by (auto simp: inner_commute dot_square_norm bounded_bilinear_inner)
lemma differentiable_on_sqnorm [derivative_intros, simp]: fixes S :: "'a :: {real_normed_vector,real_inner} set" shows"(λx. (norm x)2) differentiable_on S" by (simp add: differentiable_at_imp_differentiable_on)
lemma differentiable_norm_at [derivative_intros, simp]: fixes a :: "'a :: {real_normed_vector,real_inner}" shows"a ≠ 0 ==> norm differentiable (at a)" using differentiableI has_derivative_norm by blast
lemma differentiable_on_norm [derivative_intros, simp]: fixes S :: "'a :: {real_normed_vector,real_inner} set" shows"0 ∉ S ==> norm differentiable_on S" by (metis differentiable_at_imp_differentiable_on differentiable_norm_at)
subsection‹Frechet derivative and Jacobian matrix›
definition"frechet_derivative f net = (SOME f'. (f has_derivative f') net)"
proposition frechet_derivative_works: "f differentiable net ⟷ (f has_derivative (frechet_derivative f net)) net" unfolding frechet_derivative_def differentiable_def unfolding some_eq_ex[of "λ f' . (f has_derivative f') net"] ..
lemma linear_frechet_derivative: "f differentiable net ==> linear (frechet_derivative f net)" unfolding frechet_derivative_works has_derivative_def by (auto intro: bounded_linear.linear)
lemma frechet_derivative_const [simp]: "frechet_derivative (λx. c) (at a) = (λx. 0)" using differentiable_const frechet_derivative_works has_derivative_const has_derivative_unique by blast
lemma frechet_derivative_id [simp]: "frechet_derivative id (at a) = id" using differentiable_def frechet_derivative_works has_derivative_id has_derivative_unique by blast
lemma frechet_derivative_ident [simp]: "frechet_derivative (λx. x) (at a) = (λx. x)" by (metis eq_id_iff frechet_derivative_id)
subsection‹Differentiability implies continuity›
proposition differentiable_imp_continuous_within: "f differentiable (at x within s) ==> continuous (at x within s) f" by (auto simp: differentiable_def intro: has_derivative_continuous)
lemma differentiable_imp_continuous_on: "f differentiable_on s ==> continuous_on s f" unfolding differentiable_on_def continuous_on_eq_continuous_within using differentiable_imp_continuous_within by blast
lemma differentiable_on_subset: "f differentiable_on t ==> s ⊆ t ==> f differentiable_on s" unfolding differentiable_on_def using differentiable_within_subset by blast
lemma differentiable_on_empty: "f differentiable_on {}" unfolding differentiable_on_def by auto
lemma has_derivative_continuous_on: "(∧x. x ∈ s ==> (f has_derivative f' x) (at x within s)) ==> continuous_on s f" by (auto intro!: differentiable_imp_continuous_on differentiableI simp: differentiable_on_def)
text‹Results about neighborhoods filter.›
lemma eventually_nhds_metric_le: "eventually P (nhds a) = (∃d>0. ∀x. dist x a ≤ d ⟶ P x)" unfolding eventually_nhds_metric by (safe, rule_tac x="d / 2"in exI, auto)
lemma le_nhds: "F ≤ nhds a ⟷ (∀S. open S ∧ a ∈ S ⟶ eventually (λx. x ∈ S) F)" unfolding le_filter_def eventually_nhds by (fast elim: eventually_mono)
lemma le_nhds_metric: "F ≤ nhds a ⟷ (∀e>0. eventually (λx. dist x a < e) F)" unfolding le_filter_def eventually_nhds_metric by (fast elim: eventually_mono)
lemma le_nhds_metric_le: "F ≤ nhds a ⟷ (∀e>0. eventually (λx. dist x a ≤ e) F)" unfolding le_filter_def eventually_nhds_metric_le by (fast elim: eventually_mono)
text‹Several results are easier using a "multiplied-out" variant.
I got this idea from Dieudonne's proof of the chain rule).›
lemma has_derivative_within_alt: "(f has_derivative f') (at x within s) ⟷ bounded_linear f' ∧ (∀e>0. ∃d>0. ∀y∈s. norm(y - x) < d ⟶ norm (f y - f x - f' (y - x)) ≤ e * norm (y - x))" unfolding has_derivative_within filterlim_def le_nhds_metric_le eventually_filtermap
eventually_at dist_norm diff_diff_eq by (force simp add: linear_0 bounded_linear.linear pos_divide_le_eq)
lemma has_derivative_within_alt2: "(f has_derivative f') (at x within s) ⟷ bounded_linear f' ∧ (∀e>0. eventually (λy. norm (f y - f x - f' (y - x)) ≤ e * norm (y - x)) (at x within s))" unfolding has_derivative_within filterlim_def le_nhds_metric_le eventually_filtermap
eventually_at dist_norm diff_diff_eq by (force simp add: linear_0 bounded_linear.linear pos_divide_le_eq)
lemma has_derivative_at_alt: "(f has_derivative f') (at x) ⟷ bounded_linear f' ∧ (∀e>0. ∃d>0. ∀y. norm(y - x) < d ⟶ norm (f y - f x - f'(y - x)) ≤ e * norm (y - x))" using has_derivative_within_alt[where s=UNIV] by simp
subsection‹The chain rule›
proposition diff_chain_within[derivative_intros]: assumes"(f has_derivative f') (at x within s)" and"(g has_derivative g') (at (f x) within (f ` s))" shows"((g ∘ f) has_derivative (g' ∘ f'))(at x within s)" using has_derivative_in_compose[OF assms] by (simp add: comp_def)
lemma has_vector_derivative_shift: "(f has_vector_derivative D x) (at x) ==> ((+) d ∘ f has_vector_derivative D x) (at x)" using diff_chain_at [OF _ shift_has_derivative_id] by (simp add: has_derivative_iff_Ex has_vector_derivative_def)
lemma has_vector_derivative_within_open: "a ∈ S ==> open S ==> (f has_vector_derivative f') (at a within S) ⟷ (f has_vector_derivative f') (at a)" by (simp only: at_within_interior interior_open)
lemma field_vector_diff_chain_within: assumes Df: "(f has_vector_derivative f') (at x within S)" and Dg: "(g has_field_derivative g') (at (f x) within f ` S)" shows"((g ∘ f) has_vector_derivative (f' * g')) (at x within S)" using diff_chain_within[OF Df[unfolded has_vector_derivative_def]
Dg [unfolded has_field_derivative_def]] by (auto simp: o_def mult.commute has_vector_derivative_def)
lemma vector_derivative_diff_chain_within: assumes Df: "(f has_vector_derivative f') (at x within S)" and Dg: "(g has_derivative g') (at (f x) within f`S)" shows"((g ∘ f) has_vector_derivative (g' f')) (at x within S)" using diff_chain_within[OF Df[unfolded has_vector_derivative_def] Dg]
linear.scaleR[OF has_derivative_linear[OF Dg]] unfolding has_vector_derivative_def o_def by (auto simp: o_def mult.commute has_vector_derivative_def)
subsection✐‹tag unimportant›‹Composition rules stated just for differentiability›
lemma differentiable_chain_within: "f differentiable (at x within S) ==> g differentiable (at(f x) within (f ` S)) ==> (g ∘ f) differentiable (at x within S)" unfolding differentiable_def by (meson diff_chain_within)
subsection‹Uniqueness of derivative›
text✐‹tag important›‹
The general result is a bit messy because we need approachability of the
limit point from any direction. But OK for nontrivial intervals etc. ›
proposition frechet_derivative_unique_within: fixes f :: "'a::euclidean_space → 'b::real_normed_vector" assumes1: "(f has_derivative f') (at x within S)" and2: "(f has_derivative f'') (at x within S)" and S: "∧i e. [i∈Basis; e>0]==>∃d. 0 < ∣d∣∧∣d∣ < e ∧ (x + d *R i) ∈ S" shows"f' = f''" proof - note as = assms(1,2)[unfolded has_derivative_def] theninterpret f': bounded_linear f' by auto from as interpret f'': bounded_linear f'' by auto have"x islimpt S"unfolding islimpt_approachable proof (intro allI impI) fix e :: real assume"e > 0" obtain d where"0 < ∣d∣"and"∣d∣ < e"and"x + d *R (SOME i. i ∈ Basis) ∈ S" using assms(3) SOME_Basis ‹e>0›by blast thenshow"∃x'∈S. x' ≠ x ∧ dist x' x < e" by (rule_tac x="x + d *R (SOME i. i ∈ Basis)"in bexI) (auto simp: dist_norm SOME_Basis nonzero_Basis) qed thenhave *: "netlimit (at x within S) = x" by (simp add: Lim_ident_at trivial_limit_within) show ?thesis proof (rule linear_eq_stdbasis) show"linear f'""linear f''" unfolding linear_conv_bounded_linear using as by auto next fix i :: 'a assume i: "i ∈ Basis" define e where"e = norm (f' i - f'' i)" show"f' i = f'' i" proof (rule ccontr) assume"f' i ≠ f'' i" thenhave"e > 0" unfolding e_def by auto obtain d where d: "0 < d" "(∧y. y∈S ⟶ 0 < dist y x ∧ dist y x < d ⟶ dist ((f y - f x - f' (y - x)) /R norm (y - x) - (f y - f x - f'' (y - x)) /R norm (y - x)) (0 - 0) < e)" using tendsto_diff [OF as(1,2)[THEN conjunct2]] unfolding * Lim_within using‹e>0›by blast obtain c where c: "0 < ∣c∣""∣c∣ < d ∧ x + c *R i ∈ S" using assms(3) i d(1) by blast have *: "norm (- ((1 / ∣c∣) *R f' (c *R i)) + (1 / ∣c∣) *R f'' (c *R i)) = norm ((1 / ∣c∣) *R (- (f' (c *R i)) + f'' (c *R i)))" unfolding scaleR_right_distrib by auto alsohave"… = norm ((1 / ∣c∣) *R (c *R (- (f' i) + f'' i)))" unfolding f'.scaleR f''.scaleR unfolding scaleR_right_distrib scaleR_minus_right by auto alsohave"… = e" unfolding e_def using c(1) using norm_minus_cancel[of "f' i - f'' i"] by auto finallyshow False using c using d(2)[of "x + c *R i"] unfolding dist_norm unfolding f'.scaleR f''.scaleR f'.add f''.add f'.diff f''.diff
scaleR_scaleR scaleR_right_diff_distrib scaleR_right_distrib using i by (auto simp: inverse_eq_divide) qed qed qed
proposition frechet_derivative_unique_within_closed_interval: fixes f::"'a::euclidean_space → 'b::real_normed_vector" assumes ab: "∧i. i∈Basis ==> a∙i < b∙i" and x: "x ∈ cbox a b" and"(f has_derivative f' ) (at x within cbox a b)" and"(f has_derivative f'') (at x within cbox a b)" shows"f' = f''" proof (rule frechet_derivative_unique_within) fix e :: real fix i :: 'a assume"e > 0"and i: "i ∈ Basis" thenshow"∃d. 0 < ∣d∣∧∣d∣ < e ∧ x + d *R i ∈ cbox a b" proof (cases "x∙i = a∙i") case True with ab[of i] ‹e>0› x i show ?thesis by (rule_tac x="(min (b∙i - a∙i) e) / 2"in exI)
(auto simp add: mem_box field_simps inner_simps inner_Basis) next case False moreoverhave"a ∙ i < x ∙ i" using False i mem_box(2) x by force moreover { have"a ∙ i * 2 + min (x ∙ i - a ∙ i) e ≤ a∙i *2 + x∙i - a∙i" by auto alsohave"… = a∙i + x∙i" by auto alsohave"…≤ 2 * (x∙i)" using‹a ∙ i < x ∙ i›by auto finallyhave"a ∙ i * 2 + min (x ∙ i - a ∙ i) e ≤ x ∙ i * 2" by auto
} moreoverhave"min (x ∙ i - a ∙ i) e ≥ 0" by (simp add: ‹0 < e›‹a ∙ i < x ∙ i› less_eq_real_def) thenhave"x ∙ i * 2 ≤ b ∙ i * 2 + min (x ∙ i - a ∙ i) e" using i mem_box(2) x by force ultimatelyshow ?thesis using ab[of i] ‹e>0› x i by (rule_tac x="- (min (x∙i - a∙i) e) / 2"in exI)
(auto simp add: mem_box field_simps inner_simps inner_Basis) qed qed (use assms in auto)
lemma frechet_derivative_unique_within_open_interval: fixes f::"'a::euclidean_space → 'b::real_normed_vector" assumes x: "x ∈ box a b" and f: "(f has_derivative f' ) (at x within box a b)""(f has_derivative f'') (at x within box a b)" shows"f' = f''" by (metis at_within_open assms has_derivative_unique open_box)
lemma frechet_derivative_at: "(f has_derivative f') (at x) ==> f' = frechet_derivative f (at x)" using differentiable_def frechet_derivative_works has_derivative_unique by blast
lemma frechet_derivative_compose: "frechet_derivative (f o g) (at x) = frechet_derivative (f) (at (g x)) o frechet_derivative g (at x)" if"g differentiable at x""f differentiable at (g x)" by (metis diff_chain_at frechet_derivative_at frechet_derivative_works that)
lemma frechet_derivative_within_cbox: fixes f :: "'a::euclidean_space → 'b::real_normed_vector" assumes"∧i. i∈Basis ==> a∙i < b∙i" and"x ∈ cbox a b" and"(f has_derivative f') (at x within cbox a b)" shows"frechet_derivative f (at x within cbox a b) = f'" using assms by (metis Derivative.differentiableI frechet_derivative_unique_within_closed_interval frechet_derivative_works)
lemma frechet_derivative_transform_within_open: "frechet_derivative f (at x) = frechet_derivative g (at x)" if"f differentiable at x""open X""x ∈ X""∧x. x ∈ X ==> f x = g x" by (meson frechet_derivative_at frechet_derivative_works has_derivative_transform_within_open that)
subsection‹Derivatives of local minima and maxima are zero›
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 fix h :: 'a interpret f': bounded_linear f' using deriv by (rule has_derivative_bounded_linear) show"f' h = 0" proof (cases "h = 0") case False 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 *R h) 0 :> (λr. r *R h)" by (intro derivative_eq_intros) auto thenhave"FDERIV (λr. f (x + r *R h)) 0 :> (λk. f' (k *R h))" by (rule has_derivative_compose, simp add: deriv) thenhave"DERIV (λr. f (x + r *R h)) 0 :> f' h" unfolding has_field_derivative_def by (simp add: f'.scaleR mult_commute_abs) moreoverhave"0 < d / norm h"using d1 and‹h ≠ 0›by simp moreoverhave"∀y. ∣0 - y∣ < d / norm h ⟶ f (x + 0 *R h) ≤ f (x + y *R h)" using‹h ≠ 0›by (auto simp add: d2 dist_norm pos_less_divide_eq) ultimatelyshow"f' h = 0" by (rule DERIV_local_min) qed simp qed
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: 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) *R j) = (0::'a)" (is"?D k = 0") proof - let ?f' = "frechet_derivative f (at x)" have"x ∈ ball x e"using‹0 < e›by simp moreoverhave"open (ball x e)"by simp moreoverhave"((λ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.has_derivative) ultimatelyhave"(λh. frechet_derivative f (at x) h ∙ k) = (λv. 0)" using ball(2) by (rule differential_zero_maxmin) thenshow ?thesis unfolding fun_eq_iff by simp qed
subsection‹One-dimensional mean value theorem›
lemma mvt_simple: fixes f :: "real → real" assumes"a < b" and derf: "∧x. [a ≤ x; x ≤ b]==> (f has_derivative f' x) (at x within {a..b})" shows"∃x∈{a<..<b}. f b - f a = f' x (b - a)" proof (rule mvt) have"f differentiable_on {a..b}" using derf unfolding differentiable_on_def differentiable_def by force thenshow"continuous_on {a..b} f" by (rule differentiable_imp_continuous_on) show"(f has_derivative f' x) (at x)"if"a < x""x < b"for x by (metis at_within_Icc_at derf leI order.asym that) qed (use assms in auto)
lemma mvt_very_simple: fixes f :: "real → real" assumes"a ≤ b" and derf: "∧x. [a ≤ x; x ≤ b]==> (f has_derivative f' x) (at x within {a..b})" shows"∃x∈{a..b}. f b - f a = f' x (b - a)" proof (cases "a = b") interpret bounded_linear "f' b" using assms by auto case True thenshow ?thesis by force next case False thenshow ?thesis using mvt_simple[OF _ derf] by (metis ‹a ≤ b› atLeastAtMost_iff dual_order.order_iff_strict greaterThanLessThan_iff) qed
text‹A nice generalization (see Havin's proof of 5.19 from Rudin's book).›
lemma mvt_general: fixes f :: "real → 'a::real_inner" assumes"a < b" and contf: "continuous_on {a..b} f" and derf: "∧x. [a < x; x < b]==> (f has_derivative f' x) (at x)" shows"∃x∈{a<..<b}. norm (f b - f a) ≤ norm (f' x (b - a))" proof - have"∃x∈{a<..<b}. (f b - f a) ∙ f b - (f b - f a) ∙ f a = (f b - f a) ∙ f' x (b - a)" apply (rule mvt [OF ‹a < b›, where f = "λx. (f b - f a) ∙ f x"]) apply (intro continuous_intros contf) using derf apply (auto intro: has_derivative_inner_right) done thenobtain x where x: "x ∈ {a<..<b}" "(f b - f a) ∙ f b - (f b - f a) ∙ f a = (f b - f a) ∙ f' x (b - a)" .. show ?thesis proof (cases "f a = f b") case False have"norm (f b - f a) * norm (f b - f a) = (norm (f b - f a))2" by (simp add: power2_eq_square) alsohave"… = (f b - f a) ∙ (f b - f a)" unfolding power2_norm_eq_inner .. alsohave"… = (f b - f a) ∙ f' x (b - a)" using x(2) by (simp only: inner_diff_right) alsohave"…≤ norm (f b - f a) * norm (f' x (b - a))" by (rule norm_cauchy_schwarz) finallyshow ?thesis using False x(1) by (auto simp add: mult_left_cancel) next case True thenshow ?thesis using‹a < b›by (rule_tac x="(a + b) /2"in bexI) auto qed qed
subsection‹More general bound theorems›
proposition differentiable_bound_general: fixes f :: "real → 'a::real_normed_vector" assumes"a < b" and f_cont: "continuous_on {a..b} f" and phi_cont: "continuous_on {a..b} φ" and f': "∧x. a < x ==> x < b ==> (f has_vector_derivative f' x) (at x)" and phi': "∧x. a < x ==> x < b ==> (φ has_vector_derivative φ' x) (at x)" and bnd: "∧x. a < x ==> x < b ==> norm (f' x) ≤ φ' x" shows"norm (f b - f a) ≤ φ b - φ a" proof -
{ fix x assume x: "a < x""x < b" have"0 ≤ norm (f' x)"by simp alsohave"…≤ φ' x"using x by (auto intro!: bnd) finallyhave"0 ≤ φ' x" .
} note phi'_nonneg = this note f_tendsto = assms(2)[simplified continuous_on_def, rule_format] note phi_tendsto = assms(3)[simplified continuous_on_def, rule_format]
{ fix e::real assume"e > 0" define e2 where"e2 = e / 2" with‹e > 0›have"e2 > 0"by simp let ?le = "λx1. norm (f x1 - f a) ≤ φ x1 - φ a + e * (x1 - a) + e" define A where"A = {x2. a ≤ x2 ∧ x2 ≤ b ∧ (∀x1∈{a ..< x2}. ?le x1)}" have A_subset: "A ⊆ {a..b}"by (auto simp: A_def)
{ fix x2 assume a: "a ≤ x2""x2 ≤ b"and le: "∀x1∈{a..<x2}. ?le x1" have"?le x2"using‹e > 0› proof cases assume"x2 ≠ a"with a have"a < x2"by simp have"at x2 within {a <..<x2}≠ bot" using‹a < x2› by (auto simp: trivial_limit_within islimpt_in_closure) moreover have"((λx1. (φ x1 - φ a) + e * (x1 - a) + e) ---> (φ x2 - φ a) + e * (x2 - a) + e) (at x2 within {a <..<x2})" "((λx1. norm (f x1 - f a)) ---> norm (f x2 - f a)) (at x2 within {a <..<x2})" using a by (auto intro!: tendsto_eq_intros f_tendsto phi_tendsto
intro: tendsto_within_subset[where S="{a..b}"]) moreover have"eventually (λx. x > a) (at x2 within {a <..<x2})" by (auto simp: eventually_at_filter) hence"eventually ?le (at x2 within {a <..<x2})" unfolding eventually_at_filter by eventually_elim (insert le, auto) ultimately show ?thesis by (rule tendsto_le) qed simp
} note le_cont = this have"a ∈ A" using assms by (auto simp: A_def) hence [simp]: "A ≠ {}"by auto have A_ivl: "∧x1 x2. x2 ∈ A ==> x1 ∈ {a ..x2} ==> x1 ∈ A" by (simp add: A_def) have [simp]: "bdd_above A"by (auto simp: A_def) define y where"y = Sup A" have"y ≤ b" unfolding y_def by (simp add: cSup_le_iff) (simp add: A_def) have leI: "∧x x1. a ≤ x1 ==> x ∈ A ==> x1 < x ==> ?le x1" by (auto simp: A_def intro!: le_cont) have y_all_le: "∀x1∈{a..<y}. ?le x1" by (auto simp: y_def less_cSup_iff leI) have"a ≤ y" by (metis ‹a ∈ A›‹bdd_above A› cSup_upper y_def) have"y ∈ A" using y_all_le ‹a ≤ y›‹y ≤ b› by (auto simp: A_def) hence"A = {a .. y}" using A_subset by (auto simp: subset_iff y_def cSup_upper intro: A_ivl) from le_cont[OF ‹a ≤ y›‹y ≤ b› y_all_le] have le_y: "?le y" . have"y = b" proof (cases "a = y") case True with‹a < b›have"y < b"by simp with‹a = y› f_cont phi_cont ‹e2 > 0› have1: "∀F x in at y within {y..b}. dist (f x) (f y) < e2" and2: "∀F x in at y within {y..b}. dist (φ x) (φ y) < e2" by (auto simp: continuous_on_def tendsto_iff) have3: "eventually (λx. y < x) (at y within {y..b})" by (auto simp: eventually_at_filter) have4: "eventually (λx::real. x < b) (at y within {y..b})" using _ ‹y < b› by (rule order_tendstoD) (auto intro!: tendsto_eq_intros) from1234 have eventually_le: "eventually (λx. ?le x) (at y within {y .. b})" proof eventually_elim case (elim x1) have"norm (f x1 - f a) = norm (f x1 - f y)" by (simp add: ‹a = y›) alsohave"norm (f x1 - f y) ≤ e2" using elim ‹a = y›by (auto simp : dist_norm intro!: less_imp_le) alsohave"…≤ e2 + (φ x1 - φ a + e2 + e * (x1 - a))" using‹0 < e› elim by (intro add_increasing2[OF add_nonneg_nonneg order.refl])
(auto simp: ‹a = y› dist_norm intro!: mult_nonneg_nonneg) alsohave"… = φ x1 - φ a + e * (x1 - a) + e" by (simp add: e2_def) finallyshow"?le x1" . qed from this[unfolded eventually_at_topological] ‹?le y› obtain S where S: "open S""y ∈ S""∧x. x∈S ==> x ∈ {y..b} ==> ?le x" by metis from‹open S›obtain d where d: "∧x. dist x y < d ==> x ∈ S""d > 0" by (force simp: dist_commute open_dist ball_def dest!: bspec[OF _ ‹y ∈ S›]) define d' where"d' = min b (y + (d/2))" have"d' ∈ A" unfolding A_def proof safe show"a ≤ d'"using‹a = y›‹0 < d›‹y < b›by (simp add: d'_def) show"d' ≤ b"by (simp add: d'_def) fix x1 assume"x1 ∈ {a..<d'}" hence"x1 ∈ S""x1 ∈ {y..b}" by (auto simp: ‹a = y› d'_def dist_real_def intro!: d ) thus"?le x1" by (rule S) qed hence"d' ≤ y" unfolding y_def by (rule cSup_upper) simp thenshow"y = b"using‹d > 0›‹y < b› by (simp add: d'_def) next case False with‹a ≤ y›have"a < y"by simp show"y = b" proof (rule ccontr) assume"y ≠ b" hence"y < b"using‹y ≤ b›by simp let ?F = "at y within {y..<b}" from f' phi' have"(f has_vector_derivative f' y) ?F" and"(φ has_vector_derivative φ' y) ?F" using‹a < y›‹y < b› by (auto simp add: at_within_open[of _ "{a<..<b}"] has_vector_derivative_def
intro!: has_derivative_subset[where s="{a<..<b}"and t="{y..<b}"]) hence"∀F x1 in ?F. norm (f x1 - f y - (x1 - y) *R f' y) ≤ e2 * ∣x1 - y∣" "∀F x1 in ?F. norm (φ x1 - φ y - (x1 - y) *R φ' y) ≤ e2 * ∣x1 - y∣" using‹e2 > 0› by (auto simp: has_derivative_within_alt2 has_vector_derivative_def) moreover have"∀F x1 in ?F. y ≤ x1""∀F x1 in ?F. x1 < b" by (auto simp: eventually_at_filter) ultimately have"∀F x1 in ?F. norm (f x1 - f y) ≤ (φ x1 - φ y) + e * ∣x1 - y∣"
(is"∀F x1 in ?F. ?le' x1") proof eventually_elim case (elim x1) from norm_triangle_ineq2[THEN order_trans, OF elim(1)] have"norm (f x1 - f y) ≤ norm (f' y) * ∣x1 - y∣ + e2 * ∣x1 - y∣" by (simp add: ac_simps) alsohave"norm (f' y) ≤ φ' y"using bnd ‹a < y›‹y < b›by simp alsohave"φ' y * ∣x1 - y∣≤ φ x1 - φ y + e2 * ∣x1 - y∣" using elim by (simp add: ac_simps) finally have"norm (f x1 - f y) ≤ φ x1 - φ y + e2 * ∣x1 - y∣ + e2 * ∣x1 - y∣" by (auto simp: mult_right_mono) thus ?caseby (simp add: e2_def) qed moreoverhave"?le' y"by simp ultimatelyobtain S where S: "open S""y ∈ S""∧x. x∈S ==> x ∈ {y..<b} ==> ?le' x" unfolding eventually_at_topological by metis from‹open S›obtain d where d: "∧x. dist x y < d ==> x ∈ S""d > 0" by (force simp: dist_commute open_dist ball_def dest!: bspec[OF _ ‹y ∈ S›]) define d' where"d' = min ((y + b)/2) (y + (d/2))" have"d' ∈ A" unfolding A_def proof safe show"a ≤ d'"using‹a < y›‹0 < d›‹y < b›by (simp add: d'_def) show"d' ≤ b"using‹y < b›by (simp add: d'_def min_def) fix x1 assume x1: "x1 ∈ {a..<d'}" show"?le x1" proof (cases "x1 < y") case True thenshow ?thesis using‹y ∈ A›local.leI x1 by auto next case False hence x1': "x1 ∈ S""x1 ∈ {y..<b}"using x1 by (auto simp: d'_def dist_real_def intro!: d) have"norm (f x1 - f a) ≤ norm (f x1 - f y) + norm (f y - f a)" by (rule order_trans[OF _ norm_triangle_ineq]) simp alsonote S(3)[OF x1'] alsonote le_y finallyshow"?le x1" using False by (auto simp: algebra_simps) qed qed hence"d' ≤ y" unfolding y_def by (rule cSup_upper) simp thus False using‹d > 0›‹y < b› by (simp add: d'_def min_def split: if_split_asm) qed qed with le_y have"norm (f b - f a) ≤ φ b - φ a + e * (b - a + 1)" by (simp add: algebra_simps)
} note * = this show ?thesis proof (rule field_le_epsilon) fix e::real assume"e > 0" thenshow"norm (f b - f a) ≤ φ b - φ a + e" using *[of "e / (b - a + 1)"] ‹a < b›by simp qed qed
lemma differentiable_bound: fixes f :: "'a::real_normed_vector → 'b::real_normed_vector" assumes"convex S" and derf: "∧x. x∈S ==> (f has_derivative f' x) (at x within S)" and B: "∧x. x ∈ S ==> onorm (f' x) ≤ B" and x: "x ∈ S" and y: "y ∈ S" shows"norm (f x - f y) ≤ B * norm (x - y)" proof - let ?p = "λu. x + u *R (y - x)" let ?φ = "λh. h * B * norm (x - y)" have *: "x + u *R (y - x) ∈ S"if"u ∈ {0..1}"for u proof - have"u *R y = u *R (y - x) + u *R x" by (simp add: scale_right_diff_distrib) thenshow"x + u *R (y - x) ∈ S" using that ‹convex S› x y by (simp add: convex_alt)
(metis pth_b(2) pth_c(1) scaleR_collapse) qed have"∧z. z ∈ (λu. x + u *R (y - x)) ` {0..1} ==> (f has_derivative f' z) (at z within (λu. x + u *R (y - x)) ` {0..1})" by (auto intro: * has_derivative_subset [OF derf]) thenhave"continuous_on (?p ` {0..1}) f" unfolding continuous_on_eq_continuous_within by (meson has_derivative_continuous) with * have1: "continuous_on {0 .. 1} (f ∘ ?p)" by (intro continuous_intros)+
{ fix u::real assume u: "u ∈{0 <..< 1}" let ?u = "?p u" interpret linear "(f' ?u)" using u by (auto intro!: has_derivative_linear derf *) have"(f ∘ ?p has_derivative (f' ?u) ∘ (λu. 0 + u *R (y - x))) (at u within box 0 1)" by (intro derivative_intros has_derivative_subset [OF derf]) (use u * in auto) hence"((f ∘ ?p) has_vector_derivative f' ?u (y - x)) (at u)" by (simp add: at_within_open[OF u open_greaterThanLessThan] scaleR has_vector_derivative_def o_def)
} note2 = this have3: "continuous_on {0..1} ?φ" by (rule continuous_intros)+ have4: "(?φ has_vector_derivative B * norm (x - y)) (at u)"for u by (auto simp: has_vector_derivative_def intro!: derivative_eq_intros)
{ fix u::real assume u: "u ∈{0 <..< 1}" let ?u = "?p u" interpret bounded_linear "(f' ?u)" using u by (auto intro!: has_derivative_bounded_linear derf *) have"norm (f' ?u (y - x)) ≤ onorm (f' ?u) * norm (y - x)" by (rule onorm) (rule bounded_linear) alsohave"onorm (f' ?u) ≤ B" using u by (auto intro!: assms(3)[rule_format] *) finallyhave"norm ((f' ?u) (y - x)) ≤ B * norm (x - y)" by (simp add: mult_right_mono norm_minus_commute)
} note5 = this have"norm (f x - f y) = norm ((f ∘ (λu. x + u *R (y - x))) 1 - (f ∘ (λu. x + u *R(y - x))) 0)" by (auto simp add: norm_minus_commute) also from differentiable_bound_general[OF zero_less_one 1, OF 3245] have"norm ((f ∘ ?p) 1 - (f ∘ ?p) 0) ≤ B * norm (x - y)" by simp finallyshow ?thesis . qed
lemma field_differentiable_bound: fixes S :: "'a::real_normed_field set" assumes cvs: "convex S" and df: "∧z. z ∈ S ==> (f has_field_derivative f' z) (at z within S)" and dn: "∧z. z ∈ S ==> norm (f' z) ≤ B" and"x ∈ S""y ∈ S" shows"norm(f x - f y) ≤ B * norm(x - y)" proof (rule differentiable_bound [OF cvs]) show"∧x. x ∈ S ==> (f has_derivative (*) (f' x)) (at x within S)" by (simp add: df has_field_derivative_imp_has_derivative) show"∧x. x ∈ S ==> onorm ((*) (f' x)) ≤ B" by (metis (no_types, opaque_lifting) dn norm_mult onorm_le order.refl order_trans) qed (use assms in auto)
lemma
differentiable_bound_segment: fixes f::"'a::real_normed_vector → 'b::real_normed_vector" assumes"∧t. t ∈ {0..1} ==> x0 + t *R a ∈ G" assumes f': "∧x. x ∈ G ==> (f has_derivative f' x) (at x within G)" assumes B: "∧x. x ∈ {0..1} ==> onorm (f' (x0 + x *R a)) ≤ B" shows"norm (f (x0 + a) - f x0) ≤ norm a * B" proof - let ?G = "(λx. x0 + x *R a) ` {0..1}" have"?G = (+) x0 ` (λx. x *R a) ` {0..1}"by auto alsohave"convex …" by (intro convex_translation convex_scaled convex_real_interval) finallyhave"convex ?G" . moreoverhave"?G ⊆ G""x0 ∈ ?G""x0 + a ∈ ?G"using assms by (auto intro: image_eqI[wherex=1]) ultimatelyshow ?thesis using has_derivative_subset[OF f' ‹?G ⊆ G›] B
differentiable_bound[of "(λx. x0 + x *R a) ` {0..1}" f f' B "x0 + a" x0] by (force simp: ac_simps) qed
lemma differentiable_bound_linearization: fixes f::"'a::real_normed_vector → 'b::real_normed_vector" assumes S: "∧t. t ∈ {0..1} ==> a + t *R (b - a) ∈ S" assumes f'[derivative_intros]: "∧x. x ∈ S ==> (f has_derivative f' x) (at x within S)" assumes B: "∧x. x ∈ S ==> onorm (f' x - f' x0) ≤ B" assumes"x0 ∈ S" shows"norm (f b - f a - f' x0 (b - a)) ≤ norm (b - a) * B" proof - define g where [abs_def]: "g x = f x - f' x0 x"for x have g: "∧x. x ∈ S ==> (g has_derivative (λi. f' x i - f' x0 i)) (at x within S)" unfolding g_def using assms by (auto intro!: derivative_eq_intros
bounded_linear.has_derivative[OF has_derivative_bounded_linear, OF f']) from B have"∀x∈{0..1}. onorm (λi. f' (a + x *R (b - a)) i - f' x0 i) ≤ B" using assms by (auto simp: fun_diff_def) with differentiable_bound_segment[OF S g] ‹x0 ∈ S› show ?thesis by (simp add: g_def field_simps linear_diff[OF has_derivative_linear[OF f']]) qed
lemma vector_differentiable_bound_linearization: fixes f::"real → 'b::real_normed_vector" assumes f': "∧x. x ∈ S ==> (f has_vector_derivative f' x) (at x within S)" assumes"closed_segment a b ⊆ S" assumes B: "∧x. x ∈ S ==> norm (f' x - f' x0) ≤ B" assumes"x0 ∈ S" shows"norm (f b - f a - (b - a) *R f' x0) ≤ norm (b - a) * B" using assms by (intro differentiable_bound_linearization[of a b S f "λx h. h *R f' x" x0 B])
(force simp: closed_segment_real_eq has_vector_derivative_def
scaleR_diff_right[symmetric] mult.commute[of B]
intro!: onorm_le mult_left_mono)+
text‹In particular.›
lemma has_derivative_zero_constant: fixes f :: "'a::real_normed_vector → 'b::real_normed_vector" assumes"convex s" and"∧x. x ∈ s ==> (f has_derivative (λh. 0)) (at x within s)" shows"∃c. ∀x∈s. f x = c" proof -
{ fix x y assume"x ∈ s""y ∈ s" thenhave"norm (f x - f y) ≤ 0 * norm (x - y)" using assms by (intro differentiable_bound[of s]) (auto simp: onorm_zero) thenhave"f x = f y" by simp } thenshow ?thesis by metis qed
lemma has_field_derivative_zero_constant: assumes"convex s""∧x. x ∈ s ==> (f has_field_derivative 0) (at x within s)" shows"∃c. ∀x∈s. f (x) = (c :: 'a :: real_normed_field)" proof (rule has_derivative_zero_constant) have A: "(*) 0 = (λ_. 0 :: 'a)"by (intro ext) simp fix x assume"x ∈ s"thus"(f has_derivative (λh. 0)) (at x within s)" using assms(2)[of x] by (simp add: has_field_derivative_def A) qed fact
lemma
has_vector_derivative_zero_constant: assumes"convex s" assumes"∧x. x ∈ s ==> (f has_vector_derivative 0) (at x within s)" obtains c where"∧x. x ∈ s ==> f x = c" using has_derivative_zero_constant[of s f] assms by (auto simp: has_vector_derivative_def)
lemma has_derivative_zero_unique: fixes f :: "'a::real_normed_vector → 'b::real_normed_vector" assumes"convex s" and"∧x. x ∈ s ==> (f has_derivative (λh. 0)) (at x within s)" and"x ∈ s""y ∈ s" shows"f x = f y" using has_derivative_zero_constant[OF assms(1,2)] assms(3-) by force
lemma has_derivative_zero_unique_connected: fixes f :: "'a::real_normed_vector → 'b::real_normed_vector" assumes"open s""connected s" assumes f: "∧x. x ∈ s ==> (f has_derivative (λx. 0)) (at x)" assumes"x ∈ s""y ∈ s" shows"f x = f y" proof (rule connected_local_const[where f=f, OF ‹connected s›‹x∈s›‹y∈s›]) show"∀a∈s. eventually (λb. f a = f b) (at a within s)" proof fix a assume"a ∈ s" with‹open s›obtain e where"0 < e""ball a e ⊆ s" by (rule openE) thenhave"∃c. ∀x∈ball a e. f x = c" by (intro has_derivative_zero_constant)
(auto simp: at_within_open[OF _ open_ball] f) with‹0<e\›have"∀x∈ball a e. f a = f x" by auto thenshow"eventually (λb. f a = f b) (at a within s)" using‹0<e\›unfolding eventually_at_topological by (intro exI[of _ "ball a e"]) auto qed qed
subsection‹Differentiability of inverse function (most basic form)›
lemma has_derivative_inverse_basic: fixes f :: "'a::real_normed_vector → 'b::real_normed_vector" assumes derf: "(f has_derivative f') (at (g y))" and ling': "bounded_linear g'" and"g' ∘ f' = id" and contg: "continuous (at y) g" and"open T" and"y ∈ T" and fg: "∧z. z ∈ T ==> f (g z) = z" shows"(g has_derivative g') (at y)" proof - interpret f': bounded_linear f' using assms unfolding has_derivative_def by auto interpret g': bounded_linear g' using assms by auto obtain C where C: "0 < C""∧x. norm (g' x) ≤ norm x * C" using bounded_linear.pos_bounded[OF assms(2)] by blast have lem1: "∀e>0. ∃d>0. ∀z. norm (z - y) < d ⟶ norm (g z - g y - g'(z - y)) ≤ e * norm (g z - g y)" proof (intro allI impI) fix e :: real assume"e > 0" with C(1) have *: "e / C > 0"by auto obtain d0 where"0 < d0"and d0: "∧u. norm (u - g y) < d0 ==> norm (f u - f (g y) - f' (u - g y)) ≤ e / C * norm (u - g y)" using derf * unfolding has_derivative_at_alt by blast obtain d1 where"0 < d1"and d1: "∧x. [0 < dist x y; dist x y < d1]==> dist (g x) (g y) < d0" using contg ‹0 < d0›unfolding continuous_at Lim_at by blast obtain d2 where"0 < d2"and d2: "∧u. dist u y < d2 ==> u ∈ T" using‹open T›‹y ∈ T›unfolding open_dist by blast obtain d where d: "0 < d""d < d1""d < d2" using field_lbound_gt_zero[OF ‹0 < d1›‹0 < d2›] by blast show"∃d>0. ∀z. norm (z - y) < d ⟶ norm (g z - g y - g' (z - y)) ≤ e * norm (g z - g y)" proof (intro exI allI impI conjI) fix z assume as: "norm (z - y) < d" thenhave"z ∈ T" using d2 d unfolding dist_norm by auto have"norm (g z - g y - g' (z - y)) ≤ norm (g' (f (g z) - y - f' (g z - g y)))" unfolding g'.diff f'.diff unfolding assms(3)[unfolded o_def id_def, THEN fun_cong] fg[OF ‹z∈T›] by (simp add: norm_minus_commute) alsohave"…≤ norm (f (g z) - y - f' (g z - g y)) * C" by (rule C(2)) alsohave"…≤ (e / C) * norm (g z - g y) * C" proof - have"norm (g z - g y) < d0" by (metis as cancel_comm_monoid_add_class.diff_cancel d(2) ‹0 < d0› d1 diff_gt_0_iff_gt diff_strict_mono dist_norm dist_self zero_less_dist_iff) thenshow ?thesis by (metis C(1) ‹y ∈ T› d0 fg mult_le_cancel_right_pos) qed alsohave"…≤ e * norm (g z - g y)" using C by (auto simp add: field_simps) finallyshow"norm (g z - g y - g' (z - y)) ≤ e * norm (g z - g y)" by simp qed (use d in auto) qed have *: "(0::real) < 1 / 2" by auto obtain d where"0 < d"and d: "∧z. norm (z - y) < d ==> norm (g z - g y - g' (z - y)) ≤ 1/2 * norm (g z - g y)" using lem1 * by blast define B where"B = C * 2" have"B > 0" unfolding B_def using C by auto have lem2: "norm (g z - g y) ≤ B * norm (z - y)"if z: "norm(z - y) < d"for z proof - have"norm (g z - g y) ≤ norm(g' (z - y)) + norm ((g z - g y) - g'(z - y))" by (rule norm_triangle_sub) alsohave"…≤ norm (g' (z - y)) + 1 / 2 * norm (g z - g y)" by (rule add_left_mono) (use d z in auto) alsohave"…≤ norm (z - y) * C + 1 / 2 * norm (g z - g y)" by (rule add_right_mono) (use C in auto) finallyshow"norm (g z - g y) ≤ B * norm (z - y)" unfolding B_def by (auto simp add: field_simps) qed show ?thesis unfolding has_derivative_at_alt proof (intro conjI assms allI impI) fix e :: real assume"e > 0" thenhave *: "e / B > 0"by (metis ‹B > 0› divide_pos_pos) obtain d' where"0 < d'"and d': "∧z. norm (z - y) < d' ==> norm (g z - g y - g' (z - y)) ≤ e / B * norm (g z - g y)" using lem1 * by blast obtain k where k: "0 < k""k < d""k < d'" using field_lbound_gt_zero[OF ‹0 < d›‹0 < d'›] by blast show"∃d>0. ∀ya. norm (ya - y) < d ⟶ norm (g ya - g y - g' (ya - y)) ≤ e * norm (ya - y)" proof (intro exI allI impI conjI) fix z assume as: "norm (z - y) < k" thenhave"norm (g z - g y - g' (z - y)) ≤ e / B * norm(g z - g y)" using d' k by auto alsohave"…≤ e * norm (z - y)" unfolding times_divide_eq_left pos_divide_le_eq[OF ‹B>0›] using lem2[of z] k as ‹e > 0› by (auto simp add: field_simps) finallyshow"norm (g z - g y - g' (z - y)) ≤ e * norm (z - y)" by simp qed (use k in auto) qed qed
text✐‹tag unimportant›\<open>Inverse functiontheoremfor complex derivatives› lemma has_field_derivative_inverse_basic: shows"DERIV f (g y) :> f' ==> f' ≠ 0 ==> continuous (at y) g ==> open t ==> y ∈ t ==> (∧z. z ∈ t ==> f (g z) = z) ==> DERIV g y :> inverse (f')" unfolding has_field_derivative_def by (rule has_derivative_inverse_basic) (auto simp: bounded_linear_mult_right)
text‹Simply rewrite that based on the domain point x.›
lemmahas_antiderivative_sequence: fixesf::"nat\<Rightarrow>'a::real_normed_vector\<Rightarrow>'b::banach" assumes"convexS" andder:"\<And>nx.x\<in>S\<Longrightarrow>((fn)has_derivative(f'nx))(atxwithinS)" andno:"\<And>e.e>0\<Longrightarrow>\<forall>\<^sub>Fninsequentially. \<forall>x\<in>S.\<forall>h.norm(f'nxh-g'xh)\<le>e*normh" shows"\<exists>g.\<forall>x\<in>S.(ghas_derivativeg'x)(atxwithinS)" proof(cases"S={}") caseFalse thenobtainawhere"a\<in>S" byauto have*:"\<And>PQ.\<exists>g.\<forall>x\<in>S.Pgx\<and>Qgx\<Longrightarrow>\<exists>g.\<forall>x\<in>S.Qgx" byauto show?thesis
apply (rule *) apply (rule has_derivative_sequence [OF ‹convex S› _ no, of "λn x. f n x + (f 0 a - f n a)"]) apply (metis assms(2) has_derivative_add_const) using‹a ∈ S› apply auto done qed auto
lemma has_antiderivative_limit: fixes g' :: "'a::real_normed_vector → 'a → 'b::banach" assumes"convex S" and"∧e. e>0 ==>∃f f'. ∀x∈S. (f has_derivative (f' x)) (at x within S) ∧ (∀h. norm (f' x h - g' x h) ≤ e * norm h)" shows"∃g. ∀x∈S. (g has_derivative g' x) (at x within S)" proof - have *: "∀n. ∃f f'. ∀x∈S. (f has_derivative (f' x)) (at x within S) ∧ (∀h. norm(f' x h - g' x h) ≤ inverse (real (Suc n)) * norm h)" by (simp add: assms(2)) obtain f where
*: "∧x. ∃f'. ∀xa∈S. (f x has_derivative f' xa) (at xa within S) ∧ (∀h. norm (f' xa h - g' xa h) ≤ inverse (real (Suc x)) * norm h)" using * by metis obtain f' where
f': "∧x. ∀z∈S. (f x has_derivative f' x z) (at z within S) ∧ (∀h. norm (f' x z h - g' z h) ≤ inverse (real (Suc x)) * norm h)" using * by metis show ?thesis proof (rule has_antiderivative_sequence[OF ‹convex S›, of f f']) fix e :: real assume"e > 0" obtain N where N: "inverse (real (Suc N)) < e" using reals_Archimedean[OF ‹e>0›] .. show"∀F n in sequentially. ∀x∈S. ∀h. norm (f' n x h - g' x h) ≤ e * norm h" unfolding eventually_sequentially proof (intro exI allI ballI impI) fix n x h assume n: "N ≤ n"and x: "x ∈ S" have *: "inverse (real (Suc n)) ≤ e" using n N by (smt (verit, best) le_imp_inverse_le of_nat_0_less_iff of_nat_Suc of_nat_le_iff zero_less_Suc) show"norm (f' n x h - g' x h) ≤ e * norm h" by (meson "*" mult_right_mono norm_ge_zero order.trans x f') qed qed (use f' in auto) qed
subsection‹Differentiation of a series›
proposition has_derivative_series: fixes f :: "nat → 'a::real_normed_vector → 'b::banach" assumes"convex S" and"∧n x. x ∈ S ==> ((f n) has_derivative (f' n x)) (at x within S)" and"∧e. e>0 ==>∀F n in sequentially. ∀x∈S. ∀h. norm (sum (λi. f' i x h) {..<n} - g' x h) ≤ e * norm h" and"x ∈ S" and"(λn. f n x) sums l" shows"∃g. ∀x∈S. (λn. f n x) sums (g x) ∧ (g has_derivative g' x) (at x within S)" unfolding sums_def apply (rule has_derivative_sequence[OF assms(1) _ assms(3)]) apply (metis assms(2) has_derivative_sum) using assms(4-5) unfolding sums_def apply auto done
lemma has_field_derivative_series: fixes f :: "nat → ('a :: {real_normed_field,banach}) → 'a" assumes"convex S" assumes"∧n x. x ∈ S ==> (f n has_field_derivative f' n x) (at x within S)" assumes"uniform_limit S (λn x. ∑i<n. f' i x) g' sequentially" assumes"x0 ∈ S""summable (λn. f n x0)" shows"∃g. ∀x∈S. (λn. f n x) sums g x ∧ (g has_field_derivative g' x) (at x within S)" unfolding has_field_derivative_def proof (rule has_derivative_series) show"∀F n in sequentially. ∀x∈S. ∀h. norm ((∑i<n. f' i x * h) - g' x * h) ≤ e * norm h"if"e > 0"for e unfolding eventually_sequentially proof - from that assms(3) obtain N where N: "∧n x. n ≥ N ==> x ∈ S ==> norm ((∑i<n. f' i x) - g' x) < e" unfolding uniform_limit_iff eventually_at_top_linorder dist_norm by blast
{ fix n :: nat and x h :: 'a assume nx: "n ≥ N""x ∈ S" have"norm ((∑i<n. f' i x * h) - g' x * h) = norm ((∑i<n. f' i x) - g' x) * norm h" by (simp add: norm_mult [symmetric] ring_distribs sum_distrib_right) alsofrom N[OF nx] have"norm ((∑i<n. f' i x) - g' x) ≤ e"by simp hence"norm ((∑i<n. f' i x) - g' x) * norm h ≤ e * norm h" by (intro mult_right_mono) simp_all finallyhave"norm ((∑i<n. f' i x * h) - g' x * h) ≤ e * norm h" .
} thus"∃N. ∀n≥N. ∀x∈S. ∀h. norm ((∑i<n. f' i x * h) - g' x * h) ≤ e * norm h"by blast qed qed (use assms in‹auto simp: has_field_derivative_def›)
lemma has_field_derivative_series': fixes f :: "nat → ('a :: {real_normed_field,banach}) → 'a" assumes"convex S" assumes"∧n x. x ∈ S ==> (f n has_field_derivative f' n x) (at x within S)" assumes"uniformly_convergent_on S (λn x. ∑i<n. f' i x)" assumes"x0 ∈ S""summable (λn. f n x0)""x ∈ interior S" shows"summable (λn. f n x)""((λx. ∑n. f n x) has_field_derivative (∑n. f' n x)) (at x)" proof - from‹x ∈ interior S›have"x ∈ S"using interior_subset by blast define g' where [abs_def]: "g' x = (∑i. f' i x)"for x from assms(3) have"uniform_limit S (λn x. ∑i<n. f' i x) g' sequentially" by (simp add: uniformly_convergent_uniform_limit_iff suminf_eq_lim g'_def) from has_field_derivative_series[OF assms(1,2) this assms(4,5)] obtain g where g: "∧x. x ∈ S ==> (λn. f n x) sums g x" "∧x. x ∈ S ==> (g has_field_derivative g' x) (at x within S)"by blast from g(1)[OF ‹x ∈ S›] show"summable (λn. f n x)"by (simp add: sums_iff) from g(2)[OF ‹x ∈ S›] ‹x ∈ interior S›have"(g has_field_derivative g' x) (at x)" by (simp add: at_within_interior[of x S]) alsohave"(g has_field_derivative g' x) (at x) ⟷ ((λx. ∑n. f n x) has_field_derivative g' x) (at x)" using eventually_nhds_in_nhd[OF ‹x ∈ interior S›] interior_subset[of S] g(1) by (intro DERIV_cong_ev) (auto elim!: eventually_mono simp: sums_iff) finallyshow"((λx. ∑n. f n x) has_field_derivative g' x) (at x)" . qed
lemma differentiable_series: fixes f :: "nat → ('a :: {real_normed_field,banach}) → 'a" assumes"convex S""open S" assumes"∧n x. x ∈ S ==> (f n has_field_derivative f' n x) (at x)" assumes"uniformly_convergent_on S (λn x. ∑i<n. f' i x)" assumes"x0 ∈ S""summable (λn. f n x0)"and x: "x ∈ S" shows"summable (λn. f n x)"and"(λx. ∑n. f n x) differentiable (at x)" proof - from assms(4) obtain g' where A: "uniform_limit S (λn x. ∑i<n. f' i x) g' sequentially" unfolding uniformly_convergent_on_def by blast from x and‹open S›have S: "at x within S = at x"by (rule at_within_open) have"∃g. ∀x∈S. (λn. f n x) sums g x ∧ (g has_field_derivative g' x) (at x within S)" by (intro has_field_derivative_series[of S f f' g' x0] assms A has_field_derivative_at_within) thenobtain g where g: "∧x. x ∈ S ==> (λn. f n x) sums g x" "∧x. x ∈ S ==> (g has_field_derivative g' x) (at x within S)"by blast from g[OF x] show"summable (λn. f n x)"by (auto simp: summable_def) from g(2)[OF x] have g': "(g has_derivative (*) (g' x)) (at x)" by (simp add: has_field_derivative_def S) have"((λx. ∑n. f n x) has_derivative (*) (g' x)) (at x)" by (rule has_derivative_transform_within_open[OF g' ‹open S› x])
(insert g, auto simp: sums_iff) thus"(λx. ∑n. f n x) differentiable (at x)"unfolding differentiable_def by (auto simp: summable_def differentiable_def has_field_derivative_def) qed
lemma differentiable_series': fixes f :: "nat → ('a :: {real_normed_field,banach}) → 'a" assumes"convex S""open S" assumes"∧n x. x ∈ S ==> (f n has_field_derivative f' n x) (at x)" assumes"uniformly_convergent_on S (λn x. ∑i<n. f' i x)" assumes"x0 ∈ S""summable (λn. f n x0)" shows"(λx. ∑n. f n x) differentiable (at x0)" using differentiable_series[OF assms, of x0] ‹x0 ∈ S›by blast+
subsection‹Derivative as a vector›
text‹Considering derivative typ‹real → 'b::real_normed_vector› as a vector.›
definition"vector_derivative f net = (SOME f'. (f has_vector_derivative f') net)"
lemma vector_derivative_unique_within: assumes not_bot: "at x within S ≠ bot" and f': "(f has_vector_derivative f') (at x within S)" and f'': "(f has_vector_derivative f'') (at x within S)" shows"f' = f''" proof - have"(λx. x *R f') = (λx. x *R f'')" proof (rule frechet_derivative_unique_within, simp_all) show"∃d. d ≠ 0 ∧∣d∣ < e ∧ x + d ∈ S"if"0 < e"for e proof - from that obtain x' where"x' ∈ S""x' ≠ x""∣x' - x∣ < e" using islimpt_approachable_real[of x S] not_bot by (auto simp add: trivial_limit_within) thenshow ?thesis using eq_iff_diff_eq_0 by (metis add.commute diff_add_cancel) qed qed (use f' f'' in‹auto simp: has_vector_derivative_def›) thenshow ?thesis unfolding fun_eq_iff by (metis scaleR_one) qed
lemma vector_derivative_unique_at: "(f has_vector_derivative f') (at x) ==> (f has_vector_derivative f'') (at x) ==> f' = f''" by (rule vector_derivative_unique_within) auto
lemma differentiableI_vector: "(f has_vector_derivative y) F ==> f differentiable F" by (auto simp: differentiable_def has_vector_derivative_def)
proposition vector_derivative_works: "f differentiable net ⟷ (f has_vector_derivative (vector_derivative f net)) net"
(is"?l = ?r") proof assume ?l obtain f' where f': "(f has_derivative f') net" using‹?l›unfolding differentiable_def .. theninterpret bounded_linear f' by auto show ?r unfolding vector_derivative_def has_vector_derivative_def by (rule someI[of _ "f' 1"]) (simp add: scaleR[symmetric] f') qed (auto simp: vector_derivative_def has_vector_derivative_def differentiable_def)
lemma vector_derivative_within: assumes not_bot: "at x within S ≠ bot"and y: "(f has_vector_derivative y) (at x within S)" shows"vector_derivative f (at x within S) = y" using y by (intro vector_derivative_unique_within[OF not_bot vector_derivative_works[THEN iffD1] y])
(auto simp: differentiable_def has_vector_derivative_def)
lemma vector_derivative_translate [simp]: "vector_derivative ((+) z ∘ g) (at x within A) = vector_derivative g (at x within A)" proof - have"(((+) z ∘ g) has_vector_derivative g') (at x within A)" if"(g has_vector_derivative g') (at x within A)"for g :: "real → 'a"and z g' unfolding o_def using that by (auto intro!: derivative_eq_intros) from this[of g _ z] this[of "λx. z + g x" _ "-z"] show ?thesis unfolding vector_derivative_def by (intro arg_cong[where f = Eps] ext) (auto simp: o_def algebra_simps) qed
lemma deriv_of_real [simp]: "at x within A ≠ bot ==> vector_derivative of_real (at x within A) = 1" by (auto intro!: vector_derivative_within derivative_eq_intros)
lemma frechet_derivative_eq_vector_derivative: assumes"f differentiable (at x)" shows"(frechet_derivative f (at x)) = (λr. r *R vector_derivative f (at x))" using assms by (auto simp: differentiable_iff_scaleR vector_derivative_def has_vector_derivative_def
intro: someI frechet_derivative_at [symmetric])
lemma has_real_derivative: fixes f :: "real → real" assumes"(f has_derivative f') F" obtains c where"(f has_real_derivative c) F" proof - obtain c where"f' = (λx. x * c)" by (metis assms has_derivative_bounded_linear real_bounded_linear) thenshow ?thesis by (metis assms that has_field_derivative_def mult_commute_abs) qed
lemma has_real_derivative_iff: fixes f :: "real → real" shows"(∃c. (f has_real_derivative c) F) = (∃D. (f has_derivative D) F)" by (metis has_field_derivative_def has_real_derivative)
lemma has_vector_derivative_cong_ev: assumes *: "eventually (λx. x ∈ S ⟶ f x = g x) (nhds x)""f x = g x" shows"(f has_vector_derivative f') (at x within S) = (g has_vector_derivative f') (at x within S)" proof (cases "at x within S = bot") case True thenshow ?thesis by (simp add: has_derivative_def has_vector_derivative_def) next case False thenshow ?thesis unfolding has_vector_derivative_def has_derivative_def using * apply (intro refl conj_cong filterlim_cong) apply (auto simp: Lim_ident_at eventually_at_filter elim: eventually_mono) done qed
lemma vector_derivative_cong_eq: assumes"eventually (λx. x ∈ A ⟶ f x = g x) (nhds x)""x = y""A = B""x ∈ A" shows"vector_derivative f (at x within A) = vector_derivative g (at y within B)" proof - have"f x = g x" using assms eventually_nhds_x_imp_x by blast hence"(λD. (f has_vector_derivative D) (at x within A)) = (λD. (g has_vector_derivative D) (at x within A))"using assms by (intro ext has_vector_derivative_cong_ev refl assms) simp_all thus ?thesis by (simp add: vector_derivative_def assms) qed
lemma islimpt_closure_open: fixes s :: "'a::perfect_space set" assumes"open s"and t: "t = closure s""x ∈ t" shows"x islimpt t" proof cases assume"x ∈ s"
{ fix T assume"x ∈ T""open T" thenhave"open (s ∩ T)" using‹open s›by auto thenhave"s ∩ T ≠ {x}" using not_open_singleton[of x] by auto with‹x ∈ T›‹x ∈ s›have"∃y∈t. y ∈ T ∧ y ≠ x" using closure_subset[of s] by (auto simp: t) } thenshow ?thesis by (auto intro!: islimptI) next assume"x ∉ s"with t show ?thesis unfolding t closure_def by (auto intro: islimpt_subset) qed
lemma vector_derivative_unique_within_closed_interval: assumes ab: "a < b""x ∈ cbox a b" assumes D: "(f has_vector_derivative f') (at x within cbox a b)""(f has_vector_derivative f'') (at x within cbox a b)" shows"f' = f''" using ab by (intro vector_derivative_unique_within[OF _ D])
(auto simp: trivial_limit_within intro!: islimpt_closure_open[where s="{a <..< b}"])
lemma vector_derivative_at: "(f has_vector_derivative f') (at x) ==> vector_derivative f (at x) = f'" by (intro vector_derivative_within at_neq_bot)
lemma has_vector_derivative_id_at [simp]: "vector_derivative (λx. x) (at a) = 1" by (simp add: vector_derivative_at)
lemma vector_derivative_minus_at [simp]: "f differentiable at a ==> vector_derivative (λx. - f x) (at a) = - vector_derivative f (at a)" by (simp add: vector_derivative_at has_vector_derivative_minus vector_derivative_works [symmetric])
lemma vector_derivative_add_at [simp]: "[f differentiable at a; g differentiable at a] ==> vector_derivative (λx. f x + g x) (at a) = vector_derivative f (at a) + vector_derivative g (at a)" by (simp add: vector_derivative_at has_vector_derivative_add vector_derivative_works [symmetric])
lemma vector_derivative_diff_at [simp,derivative_intros]: "[f differentiable at a; g differentiable at a] ==> vector_derivative (λx. f x - g x) (at a) = vector_derivative f (at a) - vector_derivative g (at a)" by (simp add: vector_derivative_at has_vector_derivative_diff vector_derivative_works [symmetric])
lemma vector_derivative_mult_at [simp]: fixes f g :: "real → 'a :: real_normed_algebra" shows"[f differentiable at a; g differentiable at a] ==> vector_derivative (λx. f x * g x) (at a) = f a * vector_derivative g (at a) + vector_derivative f (at a) * g a" by (simp add: vector_derivative_at has_vector_derivative_mult vector_derivative_works [symmetric])
lemma vector_derivative_scaleR_at [simp]: "[f differentiable at a; g differentiable at a] ==> vector_derivative (λx. f x *R g x) (at a) = f a *R vector_derivative g (at a) + vector_derivative f (at a) *R g a" apply (intro vector_derivative_at has_vector_derivative_scaleR) apply (auto simp: vector_derivative_works has_vector_derivative_def has_field_derivative_def mult_commute_abs) done
lemma vector_derivative_within_cbox: assumes ab: "a < b""x ∈ cbox a b" assumes f: "(f has_vector_derivative f') (at x within cbox a b)" shows"vector_derivative f (at x within cbox a b) = f'" by (metis assms box_real(2) f islimpt_Icc trivial_limit_within vector_derivative_within)
lemma vector_derivative_within_closed_interval: fixes f::"real → 'a::euclidean_space" assumes"a < b"and"x ∈ {a..b}" assumes"(f has_vector_derivative f') (at x within {a..b})" shows"vector_derivative f (at x within {a..b}) = f'" using assms vector_derivative_within_cbox by fastforce
lemma has_vector_derivative_within_subset: "(f has_vector_derivative f') (at x within S) ==> T ⊆ S ==> (f has_vector_derivative f') (at x within T)" by (auto simp: has_vector_derivative_def intro: has_derivative_subset)
lemma has_vector_derivative_at_within: "(f has_vector_derivative f') (at x) ==> (f has_vector_derivative f') (at x within S)" unfolding has_vector_derivative_def by (rule has_derivative_at_withinI)
lemma has_vector_derivative_weaken: fixes x D and f g S T assumes f: "(f has_vector_derivative D) (at x within T)" and"x ∈ S""S ⊆ T" and"∧x. x ∈ S ==> f x = g x" shows"(g has_vector_derivative D) (at x within S)" proof - have"(f has_vector_derivative D) (at x within S) ⟷ (g has_vector_derivative D) (at x within S)" unfolding has_vector_derivative_def has_derivative_iff_norm using assms by (intro conj_cong Lim_cong_within refl) auto thenshow ?thesis using has_vector_derivative_within_subset[OF f ‹S ⊆ T›] by simp qed
lemma has_vector_derivative_transform_within: assumes"(f has_vector_derivative f') (at x within S)" and"0 < d" and"x ∈ S" and"∧x'. [x'∈S; dist x' x < d]==> f x' = g x'" shows"(g has_vector_derivative f') (at x within S)" using assms unfolding has_vector_derivative_def by (rule has_derivative_transform_within)
lemma has_vector_derivative_transform_within_open: assumes"(f has_vector_derivative f') (at x)" and"open S" and"x ∈ S" and"∧y. y∈S ==> f y = g y" shows"(g has_vector_derivative f') (at x)" using assms unfolding has_vector_derivative_def by (rule has_derivative_transform_within_open)
lemma has_vector_derivative_transform: assumes"x ∈ S""∧x. x ∈ S ==> g x = f x" assumes f': "(f has_vector_derivative f') (at x within S)" shows"(g has_vector_derivative f') (at x within S)" using assms unfolding has_vector_derivative_def by (rule has_derivative_transform)
lemma vector_diff_chain_within: assumes"(f has_vector_derivative f') (at x within s)" and"(g has_vector_derivative g') (at (f x) within f ` s)" shows"((g ∘ f) has_vector_derivative (f' *R g')) (at x within s)" using assms has_vector_derivative_def vector_derivative_diff_chain_within by blast
lemma vector_derivative_const_at [simp]: "vector_derivative (λx. c) (at a) = 0" by (simp add: vector_derivative_at)
lemma vector_derivative_at_within_ivl: "(f has_vector_derivative f') (at x) ==> a ≤ x ==> x ≤ b ==> a<b ==> vector_derivative f (at x within {a..b}) = f'" using has_vector_derivative_at_within vector_derivative_within_cbox by fastforce
lemma vector_derivative_chain_at: assumes"f differentiable at x""(g differentiable at (f x))" shows"vector_derivative (g ∘ f) (at x) = vector_derivative f (at x) *R vector_derivative g (at (f x))" by (metis vector_diff_chain_at vector_derivative_at vector_derivative_works assms)
lemma vector_derivative_chain_within: assumes"at x within S ≠ bot""f differentiable (at x within S)" "(g has_derivative g') (at (f x) within f ` S)" shows"vector_derivative (g ∘ f) (at x within S) = g' (vector_derivative f (at x within S)) " apply (rule vector_derivative_within [OF ‹at x within S ≠ bot›]) apply (rule vector_derivative_diff_chain_within) using assms(2-3) vector_derivative_works by auto
subsection‹Field differentiability›
definition✐‹tag important› field_differentiable :: "['a → 'a::real_normed_field, 'a filter] → bool"
(infixr‹(field'_differentiable)›50) where"f field_differentiable F ≡∃f'. (f has_field_derivative f') F"
lemma field_differentiable_imp_differentiable: "f field_differentiable F ==> f differentiable F" unfolding field_differentiable_def differentiable_def using has_field_derivative_imp_has_derivative by auto
lemma field_differentiable_imp_continuous_at: "f field_differentiable (at x within S) ==> continuous (at x within S) f" by (metis DERIV_continuous field_differentiable_def)
lemma field_differentiable_within_subset: "[f field_differentiable (at x within S); T ⊆ S]==> f field_differentiable (at x within T)" by (metis DERIV_subset field_differentiable_def)
lemma field_differentiable_at_within: "[f field_differentiable (at x)] ==> f field_differentiable (at x within S)" unfolding field_differentiable_def by (metis DERIV_subset top_greatest)
lemma field_differentiable_linear [simp,derivative_intros]: "((*) c) field_differentiable F" unfolding field_differentiable_def has_field_derivative_def mult_commute_abs by (force intro: has_derivative_mult_right)
lemma field_differentiable_const [simp,derivative_intros]: "(λz. c) field_differentiable F" unfolding field_differentiable_def has_field_derivative_def using DERIV_const has_field_derivative_imp_has_derivative by blast
lemma field_differentiable_ident [simp,derivative_intros]: "(λz. z) field_differentiable F" unfolding field_differentiable_def has_field_derivative_def using DERIV_ident has_field_derivative_def by blast
lemma field_differentiable_add [derivative_intros]: assumes"f field_differentiable F""g field_differentiable F" shows"(λz. f z + g z) field_differentiable F" using assms unfolding field_differentiable_def by (metis field_differentiable_add)
lemma field_differentiable_add_const [simp,derivative_intros]: "(+) c field_differentiable F" by (simp add: field_differentiable_add)
lemma field_differentiable_sum [derivative_intros]: "(∧i. i ∈ I ==> (f i) field_differentiable F) ==> (λz. ∑i∈I. f i z) field_differentiable F" by (induct I rule: infinite_finite_induct)
(auto intro: field_differentiable_add field_differentiable_const)
lemma field_differentiable_diff [derivative_intros]: assumes"f field_differentiable F""g field_differentiable F" shows"(λz. f z - g z) field_differentiable F" using assms unfolding field_differentiable_def by (metis field_differentiable_diff)
lemma field_differentiable_inverse [derivative_intros]: assumes"f field_differentiable (at a within S)""f a ≠ 0" shows"(λz. inverse (f z)) field_differentiable (at a within S)" using assms unfolding field_differentiable_def by (metis DERIV_inverse_fun)
lemma field_differentiable_mult [derivative_intros]: assumes"f field_differentiable (at a within S)" "g field_differentiable (at a within S)" shows"(λz. f z * g z) field_differentiable (at a within S)" using assms unfolding field_differentiable_def by (metis DERIV_mult [of f _ a S g])
lemma field_differentiable_divide [derivative_intros]: assumes"f field_differentiable (at a within S)" "g field_differentiable (at a within S)" "g a ≠ 0" shows"(λz. f z / g z) field_differentiable (at a within S)" using assms unfolding field_differentiable_def by (metis DERIV_divide [of f _ a S g])
lemma field_differentiable_power [derivative_intros]: assumes"f field_differentiable (at a within S)" shows"(λz. f z ^ n) field_differentiable (at a within S)" using assms unfolding field_differentiable_def by (metis DERIV_power)
lemma field_differentiable_cnj_cnj: assumes"f field_differentiable (at (cnj z))" shows"(cnj ∘ f ∘ cnj) field_differentiable (at z)" using has_field_derivative_cnj_cnj assms by (auto simp: field_differentiable_def)
lemma field_differentiable_transform_within: "0 < d ==> x ∈ S ==> (∧x'. x' ∈ S ==> dist x' x < d ==> f x' = g x') ==> f field_differentiable (at x within S) ==> g field_differentiable (at x within S)" unfolding field_differentiable_def has_field_derivative_def by (blast intro: has_derivative_transform_within)
lemma field_differentiable_compose_within: assumes"f field_differentiable (at a within S)" "g field_differentiable (at (f a) within f`S)" shows"(g o f) field_differentiable (at a within S)" using assms unfolding field_differentiable_def by (metis DERIV_image_chain)
lemma field_differentiable_compose: "f field_differentiable at z ==> g field_differentiable at (f z) ==> (g o f) field_differentiable at z" by (metis field_differentiable_at_within field_differentiable_compose_within)
lemma field_differentiable_within_open: "[a ∈ S; open S]==> f field_differentiable at a within S ⟷ f field_differentiable at a" unfolding field_differentiable_def by (metis at_within_open)
lemma exp_scaleR_has_vector_derivative_right: "((λt. exp (t *R A)) has_vector_derivative exp (t *R A) * A) (at t within T)" unfolding has_vector_derivative_def proof (rule has_derivativeI) let ?F = "at t within (T ∩ {t - 1 <..< t + 1})" have *: "at t within T = ?F" by (rule at_within_nhd[where S="{t - 1 <..< t + 1}"]) auto let ?e = "λi x. (inverse (1 + real i) * inverse (fact i) * (x - t) ^ i) *R (A * A ^ i)" have"∀F n in sequentially. ∀x∈T ∩ {t - 1<..<t + 1}. norm (?e n x) ≤ norm (A ^ (n + 1) /R fact (n + 1))" apply (auto simp: algebra_split_simps intro!: eventuallyI) apply (rule mult_left_mono) apply (auto simp add: field_simps power_abs intro!: divide_right_mono power_le_one) done thenhave"uniform_limit (T ∩ {t - 1<..<t + 1}) (λn x. ∑i<n. ?e i x) (λx. ∑i. ?e i x) sequentially" by (rule Weierstrass_m_test_ev) (intro summable_ignore_initial_segment summable_norm_exp) moreover have"∀F x in sequentially. x > 0" by (metis eventually_gt_at_top) thenhave "∀F n in sequentially. ((λx. ∑i<n. ?e i x) ---> A) ?F" by eventually_elim
(auto intro!: tendsto_eq_intros
simp: power_0_left if_distrib if_distribR
cong: if_cong) ultimately have [tendsto_intros]: "((λx. ∑i. ?e i x) ---> A) ?F" by (auto intro!: swap_uniform_limit[where f="λn x. ∑i < n. ?e i x"and F = sequentially]) have [tendsto_intros]: "((λx. if x = t then 0 else 1) ---> 1) ?F" by (rule tendsto_eventually) (simp add: eventually_at_filter) have"((λy. ((y - t) / abs (y - t)) *R ((∑n. ?e n y) - A)) ---> 0) (at t within T)" unfolding * by (rule tendsto_norm_zero_cancel) (auto intro!: tendsto_eq_intros)
moreoverhave"∀F x in at t within T. x ≠ t" by (simp add: eventually_at_filter) thenhave"∀F x in at t within T. ((x - t) / ∣x - t∣) *R ((∑n. ?e n x) - A) = (exp ((x - t) *R A) - 1 - (x - t) *R A) /R norm (x - t)" proof eventually_elim case (elim x) have"(exp ((x - t) *R A) - 1 - (x - t) *R A) /R norm (x - t) = ((∑n. (x - t) *R ?e n x) - (x - t) *R A) /R norm (x - t)" unfolding exp_first_term by (simp add: ac_simps) also have"summable (λn. ?e n x)" proof - from elim have"?e n x = (((x - t) *R A) ^ (n + 1)) /R fact (n + 1) /R (x - t)"for n by simp thenshow ?thesis by (auto simp only:
intro!: summable_scaleR_right summable_ignore_initial_segment summable_exp_generic) qed thenhave"(∑n. (x - t) *R ?e n x) = (x - t) *R (∑n. ?e n x)" by (rule suminf_scaleR_right[symmetric]) alsohave"(… - (x - t) *R A) /R norm (x - t) = (x - t) *R ((∑n. ?e n x) - A) /R norm (x - t)" by (simp add: algebra_simps) finallyshow ?case by simp (simp add: field_simps) qed
ultimatelyhave"((λy. (exp ((y - t) *R A) - 1 - (y - t) *R A) /R norm (y - t)) ---> 0) (at t within T)" by (rule Lim_transform_eventually) from tendsto_mult_right_zero[OF this, where c="exp (t *R A)"] show"((λy. (exp (y *R A) - exp (t *R A) - (y - t) *R (exp (t *R A) * A)) /R norm (y - t)) ---> 0) (at t within T)" by (rule Lim_transform_eventually)
(auto simp: field_split_simps exp_add_commuting[symmetric]) qed (rule bounded_linear_scaleR_left)
lemma exp_times_scaleR_commute: "exp (t *R A) * A = A * exp (t *R A)" using exp_times_arg_commute[symmetric, of "t *R A"] by (auto simp: algebra_simps)
lemma exp_scaleR_has_vector_derivative_left: "((λt. exp (t *R A)) has_vector_derivative A * exp (t *R A)) (at t)" using exp_scaleR_has_vector_derivative_right[of A t] by (simp add: exp_times_scaleR_commute)
lemma field_differentiable_series: fixes f :: "nat → 'a::{real_normed_field,banach} → 'a" assumes"convex S""open S" assumes"∧n x. x ∈ S ==> (f n has_field_derivative f' n x) (at x)" assumes"uniformly_convergent_on S (λn x. ∑i<n. f' i x)" assumes"x0 ∈ S""summable (λn. f n x0)"and x: "x ∈ S" shows"(λx. ∑n. f n x) field_differentiable (at x)" proof - from assms(4) obtain g' where A: "uniform_limit S (λn x. ∑i<n. f' i x) g' sequentially" unfolding uniformly_convergent_on_def by blast from x and‹open S›have S: "at x within S = at x"by (rule at_within_open) have"∃g. ∀x∈S. (λn. f n x) sums g x ∧ (g has_field_derivative g' x) (at x within S)" by (intro has_field_derivative_series[of S f f' g' x0] assms A has_field_derivative_at_within) thenobtain g where g: "∧x. x ∈ S ==> (λn. f n x) sums g x" "∧x. x ∈ S ==> (g has_field_derivative g' x) (at x within S)"by blast from g(2)[OF x] have g': "(g has_derivative (*) (g' x)) (at x)" by (simp add: has_field_derivative_def S) have"((λx. ∑n. f n x) has_derivative (*) (g' x)) (at x)" by (rule has_derivative_transform_within_open[OF g' ‹open S› x])
(insert g, auto simp: sums_iff) thus"(λx. ∑n. f n x) field_differentiable (at x)"unfolding differentiable_def by (auto simp: summable_def field_differentiable_def has_field_derivative_def) qed
(* TODO: Generalise to real vector spaces? *)
proposition convex_on_imp_above_tangent: assumes convex: "convex_on A f"and connected: "connected A" assumes c: "c ∈ interior A"and x : "x ∈ A" assumes deriv: "(f has_field_derivative f') (at c within A)" shows"f x - f c ≥ f' * (x - c)" proof (cases x c rule: linorder_cases) assume xc: "x > c" let ?A' = "interior A ∩ {c<..}" from c have"c ∈ interior A ∩ closure {c<..}"by auto alsohave"…⊆ closure (interior A ∩ {c<..})"by (intro open_Int_closure_subset) auto finallyhave"at c within ?A' ≠ bot"by (subst at_within_eq_bot_iff) auto moreoverfrom deriv have"((λy. (f y - f c) / (y - c)) ---> f') (at c within ?A')" unfolding has_field_derivative_iff using interior_subset[of A] by (blast intro: tendsto_mono at_le) moreoverfrom eventually_at_right_real[OF xc] have"eventually (λy. (f y - f c) / (y - c) ≤ (f x - f c) / (x - c)) (at_right c)" proof eventually_elim fix y assume y: "y ∈ {c<..<x}" with convex connected x c have"f y ≤ (f x - f c) / (x - c) * (y - c) + f c" using interior_subset[of A] by (intro convex_onD_Icc' convex_on_subset[OF convex] connected_contains_Icc) auto hence"f y - f c ≤ (f x - f c) / (x - c) * (y - c)"by simp thus"(f y - f c) / (y - c) ≤ (f x - f c) / (x - c)"using y xc by (simp add: field_split_simps) qed hence"eventually (λy. (f y - f c) / (y - c) ≤ (f x - f c) / (x - c)) (at c within ?A')" by (blast intro: filter_leD at_le) ultimatelyhave"f' ≤ (f x - f c) / (x - c)"by (simp add: tendsto_upperbound) thus ?thesis using xc by (simp add: field_simps) next assume xc: "x < c" let ?A' = "interior A ∩ {..<c}" from c have"c ∈ interior A ∩ closure {..<c}"by auto alsohave"…⊆ closure (interior A ∩ {..<c})"by (intro open_Int_closure_subset) auto finallyhave"at c within ?A' ≠ bot"by (subst at_within_eq_bot_iff) auto moreoverfrom deriv have"((λy. (f y - f c) / (y - c)) ---> f') (at c within ?A')" unfolding has_field_derivative_iff using interior_subset[of A] by (blast intro: tendsto_mono at_le) moreoverfrom eventually_at_left_real[OF xc] have"eventually (λy. (f y - f c) / (y - c) ≥ (f x - f c) / (x - c)) (at_left c)" proof eventually_elim fix y assume y: "y ∈ {x<..<c}" with convex connected x c have"f y ≤ (f x - f c) / (c - x) * (c - y) + f c" using interior_subset[of A] by (intro convex_onD_Icc'' convex_on_subset[OF convex] connected_contains_Icc) auto hence"f y - f c ≤ (f x - f c) * ((c - y) / (c - x))"by simp alsohave"(c - y) / (c - x) = (y - c) / (x - c)"using y xc by (simp add: field_simps) finallyshow"(f y - f c) / (y - c) ≥ (f x - f c) / (x - c)"using y xc by (simp add: field_split_simps) qed hence"eventually (λy. (f y - f c) / (y - c) ≥ (f x - f c) / (x - c)) (at c within ?A')" by (blast intro: filter_leD at_le) ultimatelyhave"f' ≥ (f x - f c) / (x - c)"by (simp add: tendsto_lowerbound) thus ?thesis using xc by (simp add: field_simps) qed simp_all
subsection‹Partial derivatives›
lemma eventually_at_Pair_within_TimesI1: fixes x::"'a::metric_space" assumes"∀F x' in at x within X. P x'" assumes"P x" shows"∀F (x', y') in at (x, y) within X × Y. P x'" proof - from assms[unfolded eventually_at_topological] obtain S where S: "open S""x ∈ S""∧x'. x' ∈ X ==> x' ∈ S ==> P x'" by metis show"∀F (x', y') in at (x, y) within X × Y. P x'" unfolding eventually_at_topological by (auto intro!: exI[where x="S × UNIV"] S open_Times) qed
lemma eventually_at_Pair_within_TimesI2: fixes x::"'a::metric_space" assumes"∀F y' in at y within Y. P y'""P y" shows"∀F (x', y') in at (x, y) within X × Y. P y'" proof - from assms[unfolded eventually_at_topological] obtain S where S: "open S""y ∈ S""∧y'. y' ∈ Y ==> y' ∈ S ==> P y'" by metis show"∀F (x', y') in at (x, y) within X × Y. P y'" unfolding eventually_at_topological by (auto intro!: exI[where x="UNIV × S"] S open_Times) qed
proposition has_derivative_partialsI: fixes f::"'a::real_normed_vector → 'b::real_normed_vector → 'c::real_normed_vector" assumes fx: "((λx. f x y) has_derivative fx) (at x within X)" assumes fy: "∧x y. x ∈ X ==> y ∈ Y ==> ((λy. f x y) has_derivative blinfun_apply (fy x y)) (at y within Y)" assumes fy_cont[unfolded continuous_within]: "continuous (at (x, y) within X × Y) (λ(x, y). fy x y)" assumes"y ∈ Y""convex Y" shows"((λ(x, y). f x y) has_derivative (λ(tx, ty). fx tx + fy x y ty)) (at (x, y) within X × Y)" proof (safe intro!: has_derivativeI tendstoI, goal_cases) case (2 e') interpret fx: bounded_linear "fx"using fx by (rule has_derivative_bounded_linear) define e where"e = e' / 9" have"e > 0"using‹e' > 0›by (simp add: e_def)
from fy_cont[THEN tendstoD, OF ‹e > 0›] have"∀F (x', y') in at (x, y) within X × Y. dist (fy x' y') (fy x y) < e" by (auto simp: split_beta') from this[unfolded eventually_at] obtain d' where "d' > 0" "∧x' y'. x' ∈ X ==> y' ∈ Y ==> (x', y') ≠ (x, y) ==> dist (x', y') (x, y) < d' ==> dist (fy x' y') (fy x y) < e" by auto then have d': "x' ∈ X ==> y' ∈ Y ==> dist (x', y') (x, y) < d' ==> dist (fy x' y') (fy x y) < e" for x' y' using‹0 < e› by (cases "(x', y') = (x, y)") auto define d where"d = d' / sqrt 2" have"d > 0"using‹0 < d'›by (simp add: d_def) have d: "x' ∈ X ==> y' ∈ Y ==> dist x' x < d ==> dist y' y < d ==> dist (fy x' y') (fy x y) < e" for x' y' by (auto simp: dist_prod_def d_def intro!: d' real_sqrt_sum_squares_less)
let ?S = "ball y d ∩ Y" have"convex ?S" by (auto intro!: convex_Int ‹convex Y›)
{ fix x'::'a and y'::'b assume x': "x' ∈ X"and y': "y' ∈ Y" assume dx': "dist x' x < d"and dy': "dist y' y < d" have"norm (fy x' y' - fy x' y) ≤ dist (fy x' y') (fy x y) + dist (fy x' y) (fy x y)" by norm alsohave"dist (fy x' y') (fy x y) < e" by (rule d; fact) alsohave"dist (fy x' y) (fy x y) < e" by (auto intro!: d simp: dist_prod_def x' ‹d > 0›‹y ∈ Y› dx') finally have"norm (fy x' y' - fy x' y) < e + e" by arith thenhave"onorm (blinfun_apply (fy x' y') - blinfun_apply (fy x' y)) < e + e" by (auto simp: norm_blinfun.rep_eq blinfun.diff_left[abs_def] fun_diff_def)
} note onorm = this
have ev_mem: "∀F (x', y') in at (x, y) within X × Y. (x', y') ∈ X × Y" using‹y ∈ Y› by (auto simp: eventually_at intro!: zero_less_one) moreover have ev_dist: "∀F xy in at (x, y) within X × Y. dist xy (x, y) < d"if"d > 0"for d using eventually_at_ball[OF that] by (rule eventually_elim2) (auto simp: dist_commute intro!: eventually_True) note ev_dist[OF ‹0 < d›] ultimately have"∀F (x', y') in at (x, y) within X × Y. norm (f x' y' - f x' y - (fy x' y) (y' - y)) ≤ norm (y' - y) * (e + e)" proof (eventually_elim, safe) fix x' y' assume"x' ∈ X"and y': "y' ∈ Y" assume dist: "dist (x', y') (x, y) < d" thenhave dx: "dist x' x < d"and dy: "dist y' y < d" unfolding dist_prod_def fst_conv snd_conv atomize_conj by (metis le_less_trans real_sqrt_sum_squares_ge1 real_sqrt_sum_squares_ge2)
{ fix t::real assume"t ∈ {0 .. 1}" thenhave"y + t *R (y' - y) ∈ closed_segment y y'" by (auto simp: closed_segment_def algebra_simps intro!: exI[where x=t]) also have"…⊆ ball y d ∩ Y" using‹y ∈ Y›‹0 < d› dy y' by (intro ‹convex ?S›[unfolded convex_contains_segment, rule_format, of y y'])
(auto simp: dist_commute) finallyhave"y + t *R (y' - y) ∈ ?S" .
} note seg = this
have"∧x. x ∈ ball y d ∩ Y ==> onorm (blinfun_apply (fy x' x) - blinfun_apply (fy x' y)) ≤ e + e" by (safe intro!: onorm less_imp_le ‹x' ∈ X› dx) (auto simp: dist_commute ‹0 < d›‹y ∈ Y›) with seg has_derivative_subset[OF assms(2)[OF ‹x' ∈ X›]] show"norm (f x' y' - f x' y - (fy x' y) (y' - y)) ≤ norm (y' - y) * (e + e)" by (rule differentiable_bound_linearization[where S="?S"])
(auto intro!: ‹0 < d›‹y ∈ Y›) qed moreover let ?le = "λx'. norm (f x' y - f x y - (fx) (x' - x)) ≤ norm (x' - x) * e" from fx[unfolded has_derivative_within, THEN conjunct2, THEN tendstoD, OF ‹0 < e›] have"∀F x' in at x within X. ?le x'" by eventually_elim (simp,
simp add: dist_norm field_split_simps split: if_split_asm) thenhave"∀F (x', y') in at (x, y) within X × Y. ?le x'" by (rule eventually_at_Pair_within_TimesI1)
(simp add: blinfun.bilinear_simps) moreoverhave"∀F (x', y') in at (x, y) within X × Y. norm ((x', y') - (x, y)) ≠ 0" unfolding norm_eq_zero right_minus_eq by (auto simp: eventually_at intro!: zero_less_one) moreover from fy_cont[THEN tendstoD, OF ‹0 < e›] have"∀F x' in at x within X. norm (fy x' y - fy x y) < e" unfolding eventually_at using‹y ∈ Y› by (auto simp: dist_prod_def dist_norm) thenhave"∀F (x', y') in at (x, y) within X × Y. norm (fy x' y - fy x y) < e" by (rule eventually_at_Pair_within_TimesI1)
(simp add: blinfun.bilinear_simps ‹0 < e›) ultimately have"∀F (x', y') in at (x, y) within X × Y. norm ((f x' y' - f x y - (fx (x' - x) + fy x y (y' - y))) /R norm ((x', y') - (x, y))) < e'" proof (eventually_elim, safe) fix x' y' have"norm (f x' y' - f x y - (fx (x' - x) + fy x y (y' - y))) ≤ norm (f x' y' - f x' y - fy x' y (y' - y)) + norm (fy x y (y' - y) - fy x' y (y' - y)) + norm (f x' y - f x y - fx (x' - x))" by norm also assume nz: "norm ((x', y') - (x, y)) ≠ 0" and nfy: "norm (fy x' y - fy x y) < e" assume"norm (f x' y' - f x' y - blinfun_apply (fy x' y) (y' - y)) ≤ norm (y' - y) * (e + e)" alsoassume"norm (f x' y - f x y - (fx) (x' - x)) ≤ norm (x' - x) * e" also have"norm ((fy x y) (y' - y) - (fy x' y) (y' - y)) ≤ norm ((fy x y) - (fy x' y)) * norm (y' - y)" by (auto simp: blinfun.bilinear_simps[symmetric] intro!: norm_blinfun) alsohave"…≤ (e + e) * norm (y' - y)" using‹e > 0› nfy by (auto simp: norm_minus_commute intro!: mult_right_mono) alsohave"norm (x' - x) * e ≤ norm (x' - x) * (e + e)" using‹0 < e›by simp alsohave"norm (y' - y) * (e + e) + (e + e) * norm (y' - y) + norm (x' - x) * (e + e) ≤ (norm (y' - y) + norm (x' - x)) * (4 * e)" using‹e > 0› by (simp add: algebra_simps) alsohave"…≤ 2 * norm ((x', y') - (x, y)) * (4 * e)" using‹0 < e› real_sqrt_sum_squares_ge1[of "norm (x' - x)""norm (y' - y)"]
real_sqrt_sum_squares_ge2[of "norm (y' - y)""norm (x' - x)"] by (auto intro!: mult_right_mono simp: norm_prod_def
simp del: real_sqrt_sum_squares_ge1 real_sqrt_sum_squares_ge2) alsohave"…≤ norm ((x', y') - (x, y)) * (8 * e)" by simp alsohave"… < norm ((x', y') - (x, y)) * e'" using‹0 < e'› nz by (auto simp: e_def) finallyshow"norm ((f x' y' - f x y - (fx (x' - x) + fy x y (y' - y))) /R norm ((x', y') - (x, y))) < e'" by (simp add: dist_norm) (auto simp add: field_split_simps) qed thenshow ?case by eventually_elim (auto simp: dist_norm field_simps) next from has_derivative_bounded_linear[OF fx] obtain fxb where"fx = blinfun_apply fxb" by (metis bounded_linear_Blinfun_apply) thenshow"bounded_linear (λ(tx, ty). fx tx + blinfun_apply (fy x y) ty)" by (auto intro!: bounded_linear_intros simp: split_beta') qed
subsection✐‹tag unimportant›‹Differentiable case distinction›
lemma has_derivative_within_If_eq: "((λx. if P x then f x else g x) has_derivative f') (at x within S) = (bounded_linear f' ∧ ((λy.(if P y then (f y - ((if P x then f x else g x) + f' (y - x)))/R norm (y - x) else (g y - ((if P x then f x else g x) + f' (y - x)))/R norm (y - x))) ---> 0) (at x within S))"
(is"_ = (_ ∧ (?if ---> 0) _)") proof - have"(λy. (1 / norm (y - x)) *R ((if P y then f y else g y) - ((if P x then f x else g x) + f' (y - x)))) = ?if" by (auto simp: inverse_eq_divide) thus ?thesis by (auto simp: has_derivative_within) qed
lemma has_derivative_If_within_closures: assumes f': "x ∈ S ∪ (closure S ∩ closure T) ==> (f has_derivative f' x) (at x within S ∪ (closure S ∩ closure T))" assumes g': "x ∈ T ∪ (closure S ∩ closure T) ==> (g has_derivative g' x) (at x within T ∪ (closure S ∩ closure T))" assumes connect: "x ∈ closure S ==> x ∈ closure T ==> f x = g x" assumes connect': "x ∈ closure S ==> x ∈ closure T ==> f' x = g' x" assumes x_in: "x ∈ S ∪ T" shows"((λx. if x ∈ S then f x else g x) has_derivative (if x ∈ S then f' x else g' x)) (at x within (S ∪ T))" proof - from f' x_in interpret f': bounded_linear "if x ∈ S then f' x else (λx. 0)" by (auto simp add: has_derivative_within) from g' interpret g': bounded_linear "if x ∈ T then g' x else (λx. 0)" by (auto simp add: has_derivative_within) have bl: "bounded_linear (if x ∈ S then f' x else g' x)" using f'.scaleR f'.bounded f'.add g'.scaleR g'.bounded g'.add x_in by (unfold_locales; force) show ?thesis using f' g' closure_subset[of T] closure_subset[of S] unfolding has_derivative_within_If_eq by (intro conjI bl tendsto_If_within_closures x_in)
(auto simp: has_derivative_within inverse_eq_divide connect connect' subsetD) qed
lemma has_vector_derivative_If_within_closures: assumes x_in: "x ∈ S ∪ T" assumes"u = S ∪ T" assumes f': "x ∈ S ∪ (closure S ∩ closure T) ==> (f has_vector_derivative f' x) (at x within S ∪ (closure S ∩ closure T))" assumes g': "x ∈ T ∪ (closure S ∩ closure T) ==> (g has_vector_derivative g' x) (at x within T ∪ (closure S ∩ closure T))" assumes connect: "x ∈ closure S ==> x ∈ closure T ==> f x = g x" assumes connect': "x ∈ closure S ==> x ∈ closure T ==> f' x = g' x" shows"((λx. if x ∈ S then f x else g x) has_vector_derivative (if x ∈ S then f' x else g' x)) (at x within u)" unfolding has_vector_derivative_def assms using x_in f' g' by (intro has_derivative_If_within_closures[where ?f' = "λx a. a *R f' x"and ?g' = "λx a. a *R g' x", THEN has_derivative_eq_rhs]; force simp: assms has_vector_derivative_def)
definition\<^marker>\<open>tagimportant\<close>C1_differentiable_on::"(real\<Rightarrow>'a::real_normed_vector)\<Rightarrow>realset\<Rightarrow>bool" (infix\<open>C1'_differentiable'_on\<close>50) where "fC1_differentiable_onS\<longleftrightarrow> (\<exists>D.(\<forall>x\<in>S.(fhas_vector_derivative(Dx))(atx))\<and>continuous_onSD)"
lemmaC1_differentiable_on_eq: "fC1_differentiable_onS\<longleftrightarrow> (\<forall>x\<in>S.fdifferentiableatx)\<and>continuous_onS(\<lambda>x.vector_derivativef(atx))" (is"?lhs=?rhs") proof assume?lhs thenshow?rhs unfoldingC1_differentiable_on_def by(metis(no_types,lifting)continuous_on_eqdifferentiableI_vectorvector_derivative_at) next assume?rhs thenshow?lhs usingC1_differentiable_on_defvector_derivative_worksbyfastforce qed
lemmapiecewise_C1_differentiable_affine: fixesm::real assumes"fpiecewise_C1_differentiable_on((\<lambda>x.m*x+c)`S)" shows"(f\<circ>(\<lambda>x.m*\<^sub>Rx+c))piecewise_C1_differentiable_onS" proof(cases"m=0") caseTrue thenshow?thesis unfoldingo_defby(autosimp:piecewise_C1_differentiable_on_def) next caseFalse have*:"\<And>x.finite(S\<inter>{y.m*y+c=x})" usingFalsenot_finite_existsDbyfastforce show?thesis apply(rulepiecewise_C1_differentiable_compose[OFC1_differentiable_imp_piecewise]) apply(rule*assmsderivative_intros|simpadd:Falsevimage_def)+ done qed
lemmapiecewise_C1_differentiable_cases[derivative_intros]: fixesc::real assumes"fpiecewise_C1_differentiable_on{a..c}" "gpiecewise_C1_differentiable_on{c..b}" "a\<le>c""c\<le>b""fc=gc" shows"(\<lambda>x.ifx\<le>cthenfxelsegx)piecewise_C1_differentiable_on{a..b}" proof- obtainSTwherest:"fC1_differentiable_on({a..c}-S)" "gC1_differentiable_on({c..b}-T)" "finiteS""finiteT" usingassms by(forcesimp:piecewise_C1_differentiable_on_def) thenhavef_diff:"fdifferentiable_on{a..<c}-S" andg_diff:"gdifferentiable_on{c<..b}-T" by(simp_alladd:C1_differentiable_on_eqdifferentiable_at_withinIdifferentiable_on_def) have"continuous_on{a..c}f""continuous_on{c..b}g" usingassmspiecewise_C1_differentiable_on_defbyauto thenhavecab:"continuous_on{a..b}(\<lambda>x.ifx\<le>cthenfxelsegx)" usingcontinuous_on_cases[OFclosed_real_atLeastAtMost[ofac], OFclosed_real_atLeastAtMost[ofcb], offg"\<lambda>x.x\<le>c"]assms by(forcesimp:ivl_disj_un_two_touch) {fixx assumex:"x\<in>{a..b}-insertc(S\<union>T)" have"(\<lambda>x.ifx\<le>cthenfxelsegx)differentiableatx"(is"?diff_fg") proof(casesxcrule:le_cases) caseleshow?diff_fg apply(ruledifferentiable_transform_within[wheref=fandd="distxc"]) usingxdist_real_deflestby(autosimp:C1_differentiable_on_eq) next casegeshow?diff_fg apply(ruledifferentiable_transform_within[wheref=gandd="distxc"]) usingdist_nzxdist_real_defgestxby(autosimp:C1_differentiable_on_eq) qed } thenhave"(\<forall>x\<in>{a..b}-insertc(S\<union>T).(\<lambda>x.ifx\<le>cthenfxelsegx)differentiableatx)" byauto moreover {assumefcon:"continuous_on({a<..<c}-S)(\<lambda>x.vector_derivativef(atx))" andgcon:"continuous_on({c<..<b}-T)(\<lambda>x.vector_derivativeg(atx))" have"open({a<..<c}-S)""open({c<..<b}-T)" usingstby(simp_alladd:open_Difffinite_imp_closed) moreoverhave"continuous_on({a<..<c}-S)(\<lambda>x.vector_derivative(\<lambda>x.ifx\<le>cthenfxelsegx)(atx))" proof- have"((\<lambda>x.ifx\<le>cthenfxelsegx)has_vector_derivativevector_derivativef(atx))(atx)" if"a<x""x<c""x\<notin>S"forx proof- havef:"fdifferentiableatx" by(mesonC1_differentiable_on_eqDiff_iffatLeastAtMost_iffless_eq_real_defst(1)that) show?thesis usingthat apply(rule_tacf=fandd="distxc"inhas_vector_derivative_transform_within) apply(autosimp:dist_normvector_derivative_works[symmetric]f) done qed thenshow?thesis by(metis(no_types,lifting)continuous_on_eq[OFfcon]DiffEgreaterThanLessThan_iffvector_derivative_at) qed moreoverhave"continuous_on({c<..<b}-T)(\<lambda>x.vector_derivative(\<lambda>x.ifx\<le>cthenfxelsegx)(atx))" proof- have"((\<lambda>x.ifx\<le>cthenfxelsegx)has_vector_derivativevector_derivativeg(atx))(atx)" if"c<x""x<b""x\<notin>T"forx proof- haveg:"gdifferentiableatx" by(metisC1_differentiable_on_eqDiffD1DiffIatLeastAtMost_diff_endsgreaterThanLessThan_iffst(2)that) show?thesis usingthat apply(rule_tacf=gandd="distxc"inhas_vector_derivative_transform_within) apply(autosimp:dist_normvector_derivative_works[symmetric]g) done qed thenshow?thesis by(metis(no_types,lifting)continuous_on_eq[OFgcon]DiffEgreaterThanLessThan_iffvector_derivative_at) qed ultimatelyhave"continuous_on({a<..<b}-insertc(S\<union>T)) (\<lambda>x.vector_derivative(\<lambda>x.ifx\<le>cthenfxelsegx)(atx))" by(rulecontinuous_on_subset[OFcontinuous_on_open_Un],auto) }note*=this have"continuous_on({a<..<b}-insertc(S\<union>T))(\<lambda>x.vector_derivative(\<lambda>x.ifx\<le>cthenfxelsegx)(atx))" usingst
by (auto simp: C1_differentiable_on_eq elim!: continuous_on_subset intro: *) ultimatelyhave"∃S. finite S ∧ ((λx. if x ≤ c then f x else g x) C1_differentiable_on {a..b} - S)" apply (rule_tac x="{a,b,c} ∪ S ∪ T"in exI) using st by (auto simp: C1_differentiable_on_eq elim!: continuous_on_subset) with cab show ?thesis by (simp add: piecewise_C1_differentiable_on_def) qed
lemma piecewise_C1_differentiable_const [derivative_intros]: "(λx. c) piecewise_C1_differentiable_on S" by (simp add: C1_differentiable_imp_piecewise)
lemma piecewise_C1_differentiable_scaleR [derivative_intros]: "[f piecewise_C1_differentiable_on S] ==> (λx. c *R f x) piecewise_C1_differentiable_on S" by (force simp add: piecewise_C1_differentiable_on_def continuous_on_scaleR)
lemma piecewise_C1_differentiable_neg [derivative_intros]: "f piecewise_C1_differentiable_on S ==> (λx. -(f x)) piecewise_C1_differentiable_on S" unfolding piecewise_C1_differentiable_on_def by (auto intro!: continuous_on_minus C1_differentiable_on_minus)
lemma piecewise_C1_differentiable_add [derivative_intros]: assumes"f piecewise_C1_differentiable_on i" "g piecewise_C1_differentiable_on i" shows"(λx. f x + g x) piecewise_C1_differentiable_on i" proof - obtain S t where st: "finite S""finite t" "f C1_differentiable_on (i-S)" "g C1_differentiable_on (i-t)" using assms by (auto simp: piecewise_C1_differentiable_on_def) thenhave"finite (S ∪ t) ∧ (λx. f x + g x) C1_differentiable_on i - (S ∪ t)" by (auto intro: C1_differentiable_on_add elim!: C1_differentiable_on_subset) moreoverhave"continuous_on i f""continuous_on i g" using assms piecewise_C1_differentiable_on_def by auto ultimatelyshow ?thesis by (auto simp: piecewise_C1_differentiable_on_def continuous_on_add) qed
lemma piecewise_C1_differentiable_diff [derivative_intros]: "[f piecewise_C1_differentiable_on S; g piecewise_C1_differentiable_on S] ==> (λx. f x - g x) piecewise_C1_differentiable_on S" unfolding diff_conv_add_uminus by (metis piecewise_C1_differentiable_add piecewise_C1_differentiable_neg)
lemma piecewise_C1_differentiable_cmult_right [derivative_intros]: fixes c::complex shows"f piecewise_C1_differentiable_on S ==> (λx. f x * c) piecewise_C1_differentiable_on S" by (force simp: piecewise_C1_differentiable_on_def continuous_on_mult_right)
lemma piecewise_C1_differentiable_cmult_left [derivative_intros]: fixes c::complex shows"f piecewise_C1_differentiable_on S ==> (λx. c * f x) piecewise_C1_differentiable_on S" using piecewise_C1_differentiable_cmult_right [of f S c] by (simp add: mult.commute)
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.401Bemerkung:
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-06-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.