# HG changeset patch # User paulson # Date 1572705094 0 # Node ID 5b753486c075578c90c78c79639f6854c1bf34e8 # Parent 38ade730f6dfdd127e02eafb7eb8a4f2dca47ed4 Inverse function theorem + lemmas diff -r 38ade730f6df -r 5b753486c075 src/HOL/Analysis/Bounded_Linear_Function.thy --- a/src/HOL/Analysis/Bounded_Linear_Function.thy Fri Nov 01 19:40:55 2019 +0100 +++ b/src/HOL/Analysis/Bounded_Linear_Function.thy Sat Nov 02 14:31:34 2019 +0000 @@ -216,6 +216,8 @@ lemmas bounded_linear_apply_blinfun[intro, simp] = blinfun.bounded_linear_left +declare blinfun.zero_left [simp] blinfun.zero_right [simp] + context bounded_bilinear begin @@ -682,6 +684,28 @@ "blinfun_compose x 0 = 0" by (auto simp: blinfun.bilinear_simps intro!: blinfun_eqI) +lemma blinfun_bij2: + fixes f::"'a \\<^sub>L 'a::euclidean_space" + assumes "f o\<^sub>L g = id_blinfun" + shows "bij (blinfun_apply g)" +proof (rule bijI) + show "inj g" + using assms + by (metis blinfun_apply_id_blinfun blinfun_compose.rep_eq injI inj_on_imageI2) + then show "surj g" + using blinfun.bounded_linear_right bounded_linear_def linear_inj_imp_surj by blast +qed + +lemma blinfun_bij1: + fixes f::"'a \\<^sub>L 'a::euclidean_space" + assumes "f o\<^sub>L g = id_blinfun" + shows "bij (blinfun_apply f)" +proof (rule bijI) + show "surj (blinfun_apply f)" + by (metis assms blinfun_apply_blinfun_compose blinfun_apply_id_blinfun surjI) + then show "inj (blinfun_apply f)" + using blinfun.bounded_linear_right bounded_linear_def linear_surj_imp_inj by blast +qed lift_definition blinfun_inner_right::"'a::real_inner \ 'a \\<^sub>L real" is "(\)" by (rule bounded_linear_inner_right) diff -r 38ade730f6df -r 5b753486c075 src/HOL/Analysis/Complex_Transcendental.thy --- a/src/HOL/Analysis/Complex_Transcendental.thy Fri Nov 01 19:40:55 2019 +0100 +++ b/src/HOL/Analysis/Complex_Transcendental.thy Sat Nov 02 14:31:34 2019 +0000 @@ -1267,23 +1267,55 @@ lemma assumes "z \ \\<^sub>\\<^sub>0" - shows has_field_derivative_Ln: "(Ln has_field_derivative inverse(z)) (at z)" - and Im_Ln_less_pi: "Im (Ln z) < pi" + shows has_field_derivative_Ln: "(Ln has_field_derivative inverse(z)) (at z)" + and Im_Ln_less_pi: "Im (Ln z) < pi" proof - - have znz: "z \ 0" + have znz [simp]: "z \ 0" using assms by auto then have "Im (Ln z) \ pi" by (metis (no_types) Im_exp Ln_in_Reals assms complex_nonpos_Reals_iff complex_is_Real_iff exp_Ln mult_zero_right not_less pi_neq_zero sin_pi znz) then show *: "Im (Ln z) < pi" using assms Im_Ln_le_pi - by (simp add: le_neq_trans znz) - have "(exp has_field_derivative z) (at (Ln z))" - by (metis znz DERIV_exp exp_Ln) - then show "(Ln has_field_derivative inverse(z)) (at z)" - apply (rule has_field_derivative_inverse_strong_x - [where S = "{w. -pi < Im(w) \ Im(w) < pi}"]) - using znz * - apply (auto simp: continuous_on_exp [OF continuous_on_id] open_Collect_conj open_halfspace_Im_gt open_halfspace_Im_lt mpi_less_Im_Ln) - done + by (simp add: le_neq_trans) + let ?U = "{w. -pi < Im(w) \ Im(w) < pi}" + have 1: "open ?U" + by (simp add: open_Collect_conj open_halfspace_Im_gt open_halfspace_Im_lt) + have 2: "\x. x \ ?U \ (exp has_derivative blinfun_apply(Blinfun ((*) (exp x)))) (at x)" + apply (simp add: bounded_linear_Blinfun_apply bounded_linear_mult_right) + using DERIV_exp has_field_derivative_def by blast + have 3: "continuous_on ?U (\x. Blinfun ((*) (exp x)))" + unfolding blinfun_mult_right.abs_eq [symmetric] by (intro continuous_intros) + have 4: "Ln z \ ?U" + by (auto simp: mpi_less_Im_Ln *) + have 5: "Blinfun ((*) (inverse z)) o\<^sub>L Blinfun ((*) (exp (Ln z))) = id_blinfun" + by (rule blinfun_eqI) (simp add: bounded_linear_mult_right bounded_linear_Blinfun_apply) + obtain U' V g g' where "open U'" and sub: "U' \ ?U" + and "Ln z \ U'" "open V" "z \ V" + and hom: "homeomorphism U' V exp g" + and g: "\y. y \ V \ (g has_derivative (g' y)) (at y)" + and g': "\y. y \ V \ g' y = inv ((*) (exp (g y)))" + and bij: "\y. y \ V \ bij ((*) (exp (g y)))" + using inverse_function_theorem [OF 1 2 3 4 5] + by (simp add: bounded_linear_Blinfun_apply bounded_linear_mult_right) blast + show "(Ln has_field_derivative inverse(z)) (at z)" + unfolding has_field_derivative_def + proof (rule has_derivative_transform_within_open) + show g_eq_Ln: "g y = Ln y" if "y \ V" for y + proof - + obtain x where "y = exp x" "x \ U'" + using hom homeomorphism_image1 that \y \ V\ by blast + then show ?thesis + using sub hom homeomorphism_apply1 by fastforce + qed + have "0 \ V" + by (meson exp_not_eq_zero hom homeomorphism_def) + then have "\y. y \ V \ g' y = inv ((*) y)" + by (metis exp_Ln g' g_eq_Ln) + then have g': "g' z = (\x. x/z)" + by (metis (no_types, hide_lams) bij \z \ V\ bij_inv_eq_iff exp_Ln g_eq_Ln nonzero_mult_div_cancel_left znz) + show "(g has_derivative (*) (inverse z)) (at z)" + using g [OF \z \ V\] g' + by (simp add: \z \ V\ field_class.field_divide_inverse has_derivative_imp_has_field_derivative has_field_derivative_imp_has_derivative) + qed (auto simp: \z \ V\ \open V\) qed declare has_field_derivative_Ln [derivative_intros] diff -r 38ade730f6df -r 5b753486c075 src/HOL/Analysis/Derivative.thy --- a/src/HOL/Analysis/Derivative.thy Fri Nov 01 19:40:55 2019 +0100 +++ b/src/HOL/Analysis/Derivative.thy Sat Nov 02 14:31:34 2019 +0000 @@ -57,11 +57,6 @@ unfolding has_derivative_within' has_derivative_at' by blast -lemma has_derivative_within_open: - "a \ S \ open S \ - (f has_derivative f') (at a within S) \ (f has_derivative f') (at a)" - by (simp only: at_within_interior interior_open) - lemma has_derivative_right: fixes f :: "real \ real" and y :: "real" @@ -913,8 +908,7 @@ have "(f \ ?p has_derivative (f' ?u) \ (\u. 0 + u *\<^sub>R (y - x))) (at u within box 0 1)" by (intro derivative_intros has_derivative_within_subset [OF derf]) (use u * in auto) hence "((f \ ?p) has_vector_derivative f' ?u (y - x)) (at u)" - by (simp add: has_derivative_within_open[OF u open_greaterThanLessThan] - scaleR has_vector_derivative_def o_def) + by (simp add: at_within_open[OF u open_greaterThanLessThan] scaleR has_vector_derivative_def o_def) } note 2 = this have 3: "continuous_on {0..1} ?\" by (rule continuous_intros)+ @@ -2553,4 +2547,354 @@ subgoal by (rule g'[unfolded has_vector_derivative_def]; assumption) by (auto simp: assms) +subsection\<^marker>\tag important\\The Inverse Function Theorem\ + +lemma linear_injective_contraction: + assumes "linear f" "c < 1" and le: "\x. norm (f x - x) \ c * norm x" + shows "inj f" + unfolding linear_injective_0[OF \linear f\] +proof safe + fix x + assume "f x = 0" + with le [of x] have "norm x \ c * norm x" + by simp + then show "x = 0" + using \c < 1\ by (simp add: mult_le_cancel_right1) +qed + +text\From an online proof by J. Michael Boardman, Department of Mathematics, Johns Hopkins University\ +lemma inverse_function_theorem_scaled: + fixes f::"'a::euclidean_space \ 'a" + and f'::"'a \ ('a \\<^sub>L 'a)" + assumes "open U" + and derf: "\x. x \ U \ (f has_derivative blinfun_apply (f' x)) (at x)" + and contf: "continuous_on U f'" + and "0 \ U" and [simp]: "f 0 = 0" + and id: "f' 0 = id_blinfun" + obtains U' V g g' where "open U'" "U' \ U" "0 \ U'" "open V" "0 \ V" "homeomorphism U' V f g" + "\y. y \ V \ (g has_derivative (g' y)) (at y)" + "\y. y \ V \ g' y = inv (blinfun_apply (f'(g y)))" + "\y. y \ V \ bij (blinfun_apply (f'(g y)))" +proof - + obtain d1 where "cball 0 d1 \ U" "d1 > 0" + using \open U\ \0 \ U\ open_contains_cball by blast + obtain d2 where d2: "\x. \x \ U; dist x 0 \ d2\ \ dist (f' x) (f' 0) < 1/2" "0 < d2" + using continuous_onE [OF contf, of 0 "1/2"] by (metis \0 \ U\ half_gt_zero_iff zero_less_one) + obtain \ where le: "\x. norm x \ \ \ dist (f' x) id_blinfun \ 1/2" and "0 < \" + and subU: "cball 0 \ \ U" + proof + show "min d1 d2 > 0" + by (simp add: \0 < d1\ \0 < d2\) + show "cball 0 (min d1 d2) \ U" + using \cball 0 d1 \ U\ by auto + show "dist (f' x) id_blinfun \ 1/2" if "norm x \ min d1 d2" for x + using \cball 0 d1 \ U\ d2 that id by fastforce + qed + let ?D = "cball 0 \" + define V:: "'a set" where "V \ ball 0 (\/2)" + have 4: "norm (f (x + h) - f x - h) \ 1/2 * norm h" + if "x \ ?D" "x+h \ ?D" for x h + proof - + let ?w = "\x. f x - x" + have B: "\x. x \ ?D \ onorm (blinfun_apply (f' x - id_blinfun)) \ 1/2" + by (metis dist_norm le mem_cball_0 norm_blinfun.rep_eq) + have "\x. x \ ?D \ (?w has_derivative (blinfun_apply (f' x - id_blinfun))) (at x)" + by (rule derivative_eq_intros derf subsetD [OF subU] | force simp: blinfun.diff_left)+ + then have Dw: "\x. x \ ?D \ (?w has_derivative (blinfun_apply (f' x - id_blinfun))) (at x within ?D)" + using has_derivative_at_withinI by blast + have "norm (?w (x+h) - ?w x) \ (1/2) * norm h" + using differentiable_bound [OF convex_cball Dw B] that by fastforce + then show ?thesis + by (auto simp: algebra_simps) + qed + have for_g: "\!x. norm x < \ \ f x = y" if y: "norm y < \/2" for y + proof - + let ?u = "\x. x + (y - f x)" + have *: "norm (?u x) < \" if "x \ ?D" for x + proof - + have fxx: "norm (f x - x) \ \/2" + using 4 [of 0 x] \0 < \\ \f 0 = 0\ that by auto + have "norm (?u x) \ norm y + norm (f x - x)" + by (metis add.commute add_diff_eq norm_minus_commute norm_triangle_ineq) + also have "\ < \/2 + \/2" + using fxx y by auto + finally show ?thesis + by simp + qed + have "\!x \ ?D. ?u x = x" + proof (rule banach_fix) + show "cball 0 \ \ {}" + using \0 < \\ by auto + show "(\x. x + (y - f x)) ` cball 0 \ \ cball 0 \" + using * by force + have "dist (x + (y - f x)) (xh + (y - f xh)) * 2 \ dist x xh" + if "norm x \ \" and "norm xh \ \" for x xh + using that 4 [of x "xh-x"] by (auto simp: dist_norm norm_minus_commute algebra_simps) + then show "\x\cball 0 \. \ya\cball 0 \. dist (x + (y - f x)) (ya + (y - f ya)) \ (1/2) * dist x ya" + by auto + qed (auto simp: complete_eq_closed) + then show ?thesis + by (metis "*" add_cancel_right_right eq_iff_diff_eq_0 le_less mem_cball_0) + qed + define g where "g \ \y. THE x. norm x < \ \ f x = y" + have g: "norm (g y) < \ \ f (g y) = y" if "norm y < \/2" for y + unfolding g_def using that theI' [OF for_g] by meson + then have fg[simp]: "f (g y) = y" if "y \ V" for y + using that by (auto simp: V_def) + have 5: "norm (g y' - g y) \ 2 * norm (y' - y)" if "y \ V" "y' \ V" for y y' + proof - + have no: "norm (g y) \ \" "norm (g y') \ \" and [simp]: "f (g y) = y" + using that g unfolding V_def by force+ + have "norm (g y' - g y) \ norm (g y' - g y - (y' - y)) + norm (y' - y)" + by (simp add: add.commute norm_triangle_sub) + also have "\ \ (1/2) * norm (g y' - g y) + norm (y' - y)" + using 4 [of "g y" "g y' - g y"] that no by (simp add: g norm_minus_commute V_def) + finally show ?thesis + by auto + qed + have contg: "continuous_on V g" + proof + fix y::'a and e::real + assume "0 < e" and y: "y \ V" + show "\d>0. \x'\V. dist x' y < d \ dist (g x') (g y) \ e" + proof (intro exI conjI ballI impI) + show "0 < e/2" + by (simp add: \0 < e\) + qed (use 5 y in \force simp: dist_norm\) + qed + show thesis + proof + define U' where "U' \ (f -` V) \ ball 0 \" + have contf: "continuous_on U f" + using derf has_derivative_at_withinI by (fast intro: has_derivative_continuous_on) + then have "continuous_on (ball 0 \) f" + by (meson ball_subset_cball continuous_on_subset subU) + then show "open U'" + by (simp add: U'_def V_def Int_commute continuous_open_preimage) + show "0 \ U'" "U' \ U" "open V" "0 \ V" + using \0 < \\ subU by (auto simp: U'_def V_def) + show hom: "homeomorphism U' V f g" + proof + show "continuous_on U' f" + using \U' \ U\ contf continuous_on_subset by blast + show "continuous_on V g" + using contg by blast + show "f ` U' \ V" + using U'_def by blast + show "g ` V \ U'" + by (simp add: U'_def V_def g image_subset_iff) + show "g (f x) = x" if "x \ U'" for x + by (metis that fg Int_iff U'_def V_def for_g g mem_ball_0 vimage_eq) + show "f (g y) = y" if "y \ V" for y + using that by (simp add: g V_def) + qed + show bij: "bij (blinfun_apply (f'(g y)))" if "y \ V" for y + proof - + have inj: "inj (blinfun_apply (f' (g y)))" + proof (rule linear_injective_contraction) + show "linear (blinfun_apply (f' (g y)))" + using blinfun.bounded_linear_right bounded_linear_def by blast + next + fix x + have "norm (blinfun_apply (f' (g y)) x - x) = norm (blinfun_apply (f' (g y) - id_blinfun) x)" + by (simp add: blinfun.diff_left) + also have "\ \ norm (f' (g y) - id_blinfun) * norm x" + by (rule norm_blinfun) + also have "\ \ (1/2) * norm x" + proof (rule mult_right_mono) + show "norm (f' (g y) - id_blinfun) \ 1/2" + using that g [of y] le by (auto simp: V_def dist_norm) + qed auto + finally show "norm (blinfun_apply (f' (g y)) x - x) \ (1/2) * norm x" . + qed auto + moreover + have "surj (blinfun_apply (f' (g y)))" + using blinfun.bounded_linear_right bounded_linear_def + by (blast intro!: linear_inj_imp_surj [OF _ inj]) + ultimately show ?thesis + using bijI by blast + qed + define g' where "g' \ \y. inv (blinfun_apply (f'(g y)))" + show "(g has_derivative g' y) (at y)" if "y \ V" for y + proof - + have gy: "g y \ U" + using g subU that unfolding V_def by fastforce + obtain e where e: "\h. f (g y + h) = y + blinfun_apply (f' (g y)) h + e h" + and e0: "(\h. norm (e h) / norm h) \0\ 0" + using iffD1 [OF has_derivative_iff_Ex derf [OF gy]] \y \ V\ by auto + have [simp]: "e 0 = 0" + using e [of 0] that by simp + let ?INV = "inv (blinfun_apply (f' (g y)))" + have inj: "inj (blinfun_apply (f' (g y)))" + using bij bij_betw_def that by blast + have "(g has_derivative g' y) (at y within V)" + unfolding has_derivative_at_within_iff_Ex [OF \y \ V\ \open V\] + proof + show blinv: "bounded_linear (g' y)" + unfolding g'_def using derf gy inj inj_linear_imp_inv_bounded_linear by blast + define eg where "eg \ \k. - ?INV (e (g (y+k) - g y))" + have "g (y+k) = g y + g' y k + eg k" if "y + k \ V" for k + proof - + have "?INV k = ?INV (blinfun_apply (f' (g y)) (g (y+k) - g y) + e (g (y+k) - g y))" + using e [of "g(y+k) - g y"] that by simp + then have "g (y+k) = g y + ?INV k - ?INV (e (g (y+k) - g y))" + using inj blinv by (simp add: linear_simps g'_def) + then show ?thesis + by (auto simp: eg_def g'_def) + qed + moreover have "(\k. norm (eg k) / norm k) \0\ 0" + proof (rule Lim_null_comparison) + let ?g = "\k. 2 * onorm ?INV * norm (e (g (y+k) - g y)) / norm (g (y+k) - g y)" + show "\\<^sub>F k in at 0. norm (norm (eg k) / norm k) \ ?g k" + unfolding eventually_at_topological + proof (intro exI conjI ballI impI) + show "open ((+)(-y) ` V)" + using \open V\ open_translation by blast + show "0 \ (+)(-y) ` V" + by (simp add: that) + show "norm (norm (eg k) / norm k) \ 2 * onorm (inv (blinfun_apply (f' (g y)))) * norm (e (g (y+k) - g y)) / norm (g (y+k) - g y)" + if "k \ (+)(-y) ` V" "k \ 0" for k + proof - + have "y+k \ V" + using that by auto + have "norm (norm (eg k) / norm k) \ onorm ?INV * norm (e (g (y+k) - g y)) / norm k" + using blinv g'_def onorm by (force simp: eg_def divide_simps) + also have "\ = (norm (g (y+k) - g y) / norm k) * (onorm ?INV * (norm (e (g (y+k) - g y)) / norm (g (y+k) - g y)))" + by (simp add: divide_simps) + also have "\ \ 2 * (onorm ?INV * (norm (e (g (y+k) - g y)) / norm (g (y+k) - g y)))" + apply (rule mult_right_mono) + using 5 [of y "y+k"] \y \ V\ \y + k \ V\ onorm_pos_le [OF blinv] + apply (auto simp: divide_simps zero_le_mult_iff zero_le_divide_iff g'_def) + done + finally show "norm (norm (eg k) / norm k) \ 2 * onorm ?INV * norm (e (g (y+k) - g y)) / norm (g (y+k) - g y)" + by simp + qed + qed + have 1: "(\h. norm (e h) / norm h) \0\ (norm (e 0) / norm 0)" + using e0 by auto + have 2: "(\k. g (y+k) - g y) \0\ 0" + using contg \open V\ \y \ V\ LIM_offset_zero_iff LIM_zero_iff at_within_open continuous_on_def by fastforce + from tendsto_compose [OF 1 2, simplified] + have "(\k. norm (e (g (y+k) - g y)) / norm (g (y+k) - g y)) \0\ 0" . + from tendsto_mult_left [OF this] show "?g \0\ 0" by auto + qed + ultimately show "\e. (\k. y + k \ V \ g (y+k) = g y + g' y k + e k) \ (\k. norm (e k) / norm k) \0\ 0" + by blast + qed + then show ?thesis + by (metis \open V\ at_within_open that) + qed + show "g' y = inv (blinfun_apply (f' (g y)))" + if "y \ V" for y + by (simp add: g'_def) + qed +qed + + +text\We need all this to justify the scaling and translations.\ +theorem inverse_function_theorem: + fixes f::"'a::euclidean_space \ 'a" + and f'::"'a \ ('a \\<^sub>L 'a)" + assumes "open U" + and derf: "\x. x \ U \ (f has_derivative (blinfun_apply (f' x))) (at x)" + and contf: "continuous_on U f'" + and "x0 \ U" + and invf: "invf o\<^sub>L f' x0 = id_blinfun" + obtains U' V g g' where "open U'" "U' \ U" "x0 \ U'" "open V" "f x0 \ V" "homeomorphism U' V f g" + "\y. y \ V \ (g has_derivative (g' y)) (at y)" + "\y. y \ V \ g' y = inv (blinfun_apply (f'(g y)))" + "\y. y \ V \ bij (blinfun_apply (f'(g y)))" +proof - + have apply1 [simp]: "\i. blinfun_apply invf (blinfun_apply (f' x0) i) = i" + by (metis blinfun_apply_blinfun_compose blinfun_apply_id_blinfun invf) + have apply2 [simp]: "\i. blinfun_apply (f' x0) (blinfun_apply invf i) = i" + by (metis apply1 bij_inv_eq_iff blinfun_bij1 invf) + have [simp]: "(range (blinfun_apply invf)) = UNIV" + using apply1 surjI by blast + let ?f = "invf \ (\x. (f \ (+)x0)x - f x0)" + let ?f' = "\x. invf o\<^sub>L (f' (x + x0))" + obtain U' V g g' where "open U'" and U': "U' \ (+)(-x0) ` U" "0 \ U'" + and "open V" "0 \ V" and hom: "homeomorphism U' V ?f g" + and derg: "\y. y \ V \ (g has_derivative (g' y)) (at y)" + and g': "\y. y \ V \ g' y = inv (?f'(g y))" + and bij: "\y. y \ V \ bij (?f'(g y))" + proof (rule inverse_function_theorem_scaled [of "(+)(-x0) ` U" ?f "?f'"]) + show ope: "open ((+) (- x0) ` U)" + using \open U\ open_translation by blast + show "(?f has_derivative blinfun_apply (?f' x)) (at x)" + if "x \ (+) (- x0) ` U" for x + using that + apply clarify + apply (rule derf derivative_eq_intros | simp add: blinfun_compose.rep_eq)+ + done + have YY: "(\x. f' (x + x0)) \u-x0\ f' u" + if "f' \u\ f' u" "u \ U" for u + using that LIM_offset [where k = x0] by (auto simp: algebra_simps) + then have "continuous_on ((+) (- x0) ` U) (\x. f' (x + x0))" + using contf \open U\ Lim_at_imp_Lim_at_within + by (fastforce simp: continuous_on_def at_within_open_NO_MATCH ope) + then show "continuous_on ((+) (- x0) ` U) ?f'" + by (intro continuous_intros) simp + qed (auto simp: invf \x0 \ U\) + show thesis + proof + let ?U' = "(+)x0 ` U'" + let ?V = "((+)(f x0) \ f' x0) ` V" + let ?g = "(+)x0 \ g \ invf \ (+)(- f x0)" + let ?g' = "\y. inv (blinfun_apply (f' (?g y)))" + show oU': "open ?U'" + by (simp add: \open U'\ open_translation) + show subU: "?U' \ U" + using ComplI \U' \ (+) (- x0) ` U\ by auto + show "x0 \ ?U'" + by (simp add: \0 \ U'\) + show "open ?V" + using blinfun_bij2 [OF invf] + by (metis \open V\ bij_is_surj blinfun.bounded_linear_right bounded_linear_def image_comp open_surjective_linear_image open_translation) + show "f x0 \ ?V" + using \0 \ V\ image_iff by fastforce + show "homeomorphism ?U' ?V f ?g" + proof + show "continuous_on ?U' f" + by (meson subU continuous_on_eq_continuous_at derf has_derivative_continuous oU' subsetD) + have "?f ` U' \ V" + using hom homeomorphism_image1 by blast + then show "f ` ?U' \ ?V" + unfolding image_subset_iff + by (clarsimp simp: image_def) (metis apply2 add.commute diff_add_cancel) + show "?g ` ?V \ ?U'" + using hom invf by (auto simp: image_def homeomorphism_def) + show "?g (f x) = x" + if "x \ ?U'" for x + using that hom homeomorphism_apply1 by fastforce + have "continuous_on V g" + using hom homeomorphism_def by blast + then show "continuous_on ?V ?g" + by (intro continuous_intros) (auto elim!: continuous_on_subset) + have fg: "?f (g x) = x" if "x \ V" for x + using hom homeomorphism_apply2 that by blast + show "f (?g y) = y" + if "y \ ?V" for y + using that fg by (simp add: image_iff) (metis apply2 add.commute diff_add_cancel) + qed + show "(?g has_derivative ?g' y) (at y)" "bij (blinfun_apply (f' (?g y)))" + if "y \ ?V" for y + proof - + have 1: "bij (blinfun_apply invf)" + using blinfun_bij1 invf by blast + then have 2: "bij (blinfun_apply (f' (x0 + g x)))" if "x \ V" for x + by (metis add.commute bij bij_betw_comp_iff2 blinfun_compose.rep_eq that top_greatest) + then show "bij (blinfun_apply (f' (?g y)))" + using that by auto + have "g' x \ blinfun_apply invf = inv (blinfun_apply (f' (x0 + g x)))" + if "x \ V" for x + using that + by (simp add: g' o_inv_distrib blinfun_compose.rep_eq 1 2 add.commute bij_is_inj flip: o_assoc) + then show "(?g has_derivative ?g' y) (at y)" + using that invf + by clarsimp (rule derg derivative_eq_intros | simp flip: id_def)+ + qed + qed auto +qed + end diff -r 38ade730f6df -r 5b753486c075 src/HOL/Analysis/Elementary_Normed_Spaces.thy --- a/src/HOL/Analysis/Elementary_Normed_Spaces.thy Fri Nov 01 19:40:55 2019 +0100 +++ b/src/HOL/Analysis/Elementary_Normed_Spaces.thy Sat Nov 02 14:31:34 2019 +0000 @@ -1192,10 +1192,16 @@ by (metis assms continuous_open_vimage vimage_def) qed +lemma open_translation_subtract: + fixes S :: "'a::real_normed_vector set" + assumes "open S" + shows "open ((\x. x - a) ` S)" + using assms open_translation [of S "- a"] by (simp cong: image_cong_simp) + lemma open_neg_translation: - fixes s :: "'a::real_normed_vector set" - assumes "open s" - shows "open((\x. a - x) ` s)" + fixes S :: "'a::real_normed_vector set" + assumes "open S" + shows "open((\x. a - x) ` S)" using open_translation[OF open_negations[OF assms], of a] by (auto simp: image_image) diff -r 38ade730f6df -r 5b753486c075 src/HOL/Analysis/Henstock_Kurzweil_Integration.thy --- a/src/HOL/Analysis/Henstock_Kurzweil_Integration.thy Fri Nov 01 19:40:55 2019 +0100 +++ b/src/HOL/Analysis/Henstock_Kurzweil_Integration.thy Sat Nov 02 14:31:34 2019 +0000 @@ -4405,7 +4405,7 @@ by (rule continuous_on_subset[OF contf]) show "(f has_vector_derivative 0) (at z)" if z: "z \ {a<.. k" for z unfolding has_vector_derivative_def - proof (simp add: has_derivative_within_open[OF z, symmetric]) + proof (simp add: at_within_open[OF z, symmetric]) show "(f has_derivative (\x. 0)) (at z within {a<.. 'a" + shows "\bounded_linear f; inj f\ \ bounded_linear (inv f)" + by (simp add: inj_linear_imp_inv_linear linear_linear) + lemma linear_bounded_pos: fixes f :: "'a::euclidean_space \ 'b::real_normed_vector" assumes lf: "linear f" diff -r 38ade730f6df -r 5b753486c075 src/HOL/Deriv.thy --- a/src/HOL/Deriv.thy Fri Nov 01 19:40:55 2019 +0100 +++ b/src/HOL/Deriv.thy Sat Nov 02 14:31:34 2019 +0000 @@ -169,6 +169,40 @@ finally show ?thesis . qed +lemma has_derivative_iff_Ex: + "(f has_derivative f') (at x) \ + bounded_linear f' \ (\e. (\h. f (x+h) = f x + f' h + e h) \ ((\h. norm (e h) / norm h) \ 0) (at 0))" + unfolding has_derivative_at by force + +lemma has_derivative_at_within_iff_Ex: + assumes "x \ S" "open S" + shows "(f has_derivative f') (at x within S) \ + bounded_linear f' \ (\e. (\h. x+h \ S \ f (x+h) = f x + f' h + e h) \ ((\h. norm (e h) / norm h) \ 0) (at 0))" + (is "?lhs = ?rhs") +proof safe + show "bounded_linear f'" + if "(f has_derivative f') (at x within S)" + using has_derivative_bounded_linear that by blast + show "\e. (\h. x + h \ S \ f (x + h) = f x + f' h + e h) \ (\h. norm (e h) / norm h) \0\ 0" + if "(f has_derivative f') (at x within S)" + by (metis (full_types) assms that has_derivative_iff_Ex at_within_open) + show "(f has_derivative f') (at x within S)" + if "bounded_linear f'" + and eq [rule_format]: "\h. x + h \ S \ f (x + h) = f x + f' h + e h" + and 0: "(\h. norm (e (h::'a)::'b) / norm h) \0\ 0" + for e + proof - + have 1: "f y - f x = f' (y-x) + e (y-x)" if "y \ S" for y + using eq [of "y-x"] that by simp + have 2: "((\y. norm (e (y-x)) / norm (y - x)) \ 0) (at x within S)" + by (simp add: "0" assms tendsto_offset_zero_iff) + have "((\y. norm (f y - f x - f' (y - x)) / norm (y - x)) \ 0) (at x within S)" + by (simp add: Lim_cong_within 1 2) + then show ?thesis + by (simp add: has_derivative_iff_norm \bounded_linear f'\) + qed +qed + lemma has_derivativeI: "bounded_linear f' \ ((\y. ((f y - f x) - f' (y - x)) /\<^sub>R norm (y - x)) \ 0) (at x within s) \ diff -r 38ade730f6df -r 5b753486c075 src/HOL/Limits.thy --- a/src/HOL/Limits.thy Fri Nov 01 19:40:55 2019 +0100 +++ b/src/HOL/Limits.thy Sat Nov 02 14:31:34 2019 +0000 @@ -703,7 +703,7 @@ subsubsection \Linear operators and multiplication\ -lemma linear_times: "linear (\x. c * x)" +lemma linear_times [simp]: "linear (\x. c * x)" for c :: "'a::real_algebra" by (auto simp: linearI distrib_left) @@ -2472,6 +2472,12 @@ for f :: "'a :: real_normed_vector \ _" using LIM_offset_zero_cancel[of f a L] LIM_offset_zero[of f L a] by auto +lemma tendsto_offset_zero_iff: + fixes f :: "'a :: real_normed_vector \ _" + assumes "a \ S" "open S" + shows "(f \ L) (at a within S) \ ((\h. f (a + h)) \ L) (at 0)" + by (metis LIM_offset_zero_iff assms tendsto_within_open) + lemma LIM_zero: "(f \ l) F \ ((\x. f x - l) \ 0) F" for f :: "'a \ 'b::real_normed_vector" unfolding tendsto_iff dist_norm by simp