2559 by (blast intro: filter_leD at_le) |
2559 by (blast intro: filter_leD at_le) |
2560 ultimately have "f' \<ge> (f x - f c) / (x - c)" by (rule tendsto_le_const) |
2560 ultimately have "f' \<ge> (f x - f c) / (x - c)" by (rule tendsto_le_const) |
2561 thus ?thesis using xc by (simp add: field_simps) |
2561 thus ?thesis using xc by (simp add: field_simps) |
2562 qed simp_all |
2562 qed simp_all |
2563 |
2563 |
|
2564 |
|
2565 subsection \<open>Partial derivatives\<close> |
|
2566 |
|
2567 lemma eventually_at_Pair_within_TimesI1: |
|
2568 fixes x::"'a::metric_space" |
|
2569 assumes "\<forall>\<^sub>F x' in at x within X. P x'" |
|
2570 assumes "P x" |
|
2571 shows "\<forall>\<^sub>F (x', y') in at (x, y) within X \<times> Y. P x'" |
|
2572 proof - |
|
2573 from assms[unfolded eventually_at_topological] |
|
2574 obtain S where S: "open S" "x \<in> S" "\<And>x'. x' \<in> X \<Longrightarrow> x' \<in> S \<Longrightarrow> P x'" |
|
2575 by metis |
|
2576 show "\<forall>\<^sub>F (x', y') in at (x, y) within X \<times> Y. P x'" |
|
2577 unfolding eventually_at_topological |
|
2578 by (auto intro!: exI[where x="S \<times> UNIV"] S open_Times) |
|
2579 qed |
|
2580 |
|
2581 lemma eventually_at_Pair_within_TimesI2: |
|
2582 fixes x::"'a::metric_space" |
|
2583 assumes "\<forall>\<^sub>F y' in at y within Y. P y'" |
|
2584 assumes "P y" |
|
2585 shows "\<forall>\<^sub>F (x', y') in at (x, y) within X \<times> Y. P y'" |
|
2586 proof - |
|
2587 from assms[unfolded eventually_at_topological] |
|
2588 obtain S where S: "open S" "y \<in> S" "\<And>y'. y' \<in> Y \<Longrightarrow> y' \<in> S \<Longrightarrow> P y'" |
|
2589 by metis |
|
2590 show "\<forall>\<^sub>F (x', y') in at (x, y) within X \<times> Y. P y'" |
|
2591 unfolding eventually_at_topological |
|
2592 by (auto intro!: exI[where x="UNIV \<times> S"] S open_Times) |
|
2593 qed |
|
2594 |
|
2595 lemma has_derivative_partialsI: |
|
2596 assumes fx: "\<And>x y. x \<in> X \<Longrightarrow> y \<in> Y \<Longrightarrow> ((\<lambda>x. f x y) has_derivative blinfun_apply (fx x y)) (at x within X)" |
|
2597 assumes fy: "\<And>x y. x \<in> X \<Longrightarrow> y \<in> Y \<Longrightarrow> ((\<lambda>y. f x y) has_derivative blinfun_apply (fy x y)) (at y within Y)" |
|
2598 assumes fx_cont: "continuous_on (X \<times> Y) (\<lambda>(x, y). fx x y)" |
|
2599 assumes fy_cont: "continuous_on (X \<times> Y) (\<lambda>(x, y). fy x y)" |
|
2600 assumes "x \<in> X" "y \<in> Y" |
|
2601 assumes "convex X" "convex Y" |
|
2602 shows "((\<lambda>(x, y). f x y) has_derivative (\<lambda>(tx, ty). fx x y tx + fy x y ty)) (at (x, y) within X \<times> Y)" |
|
2603 proof (safe intro!: has_derivativeI tendstoI, goal_cases) |
|
2604 case (2 e') |
|
2605 def e\<equiv>"e' / 9" |
|
2606 have "e > 0" using \<open>e' > 0\<close> by (simp add: e_def) |
|
2607 |
|
2608 have "(x, y) \<in> X \<times> Y" using assms by auto |
|
2609 from fy_cont[unfolded continuous_on_eq_continuous_within, rule_format, OF this, |
|
2610 unfolded continuous_within, THEN tendstoD, OF \<open>e > 0\<close>] |
|
2611 have "\<forall>\<^sub>F (x', y') in at (x, y) within X \<times> Y. dist (fy x' y') (fy x y) < e" |
|
2612 by (auto simp: split_beta') |
|
2613 from this[unfolded eventually_at] obtain d' where |
|
2614 "d' > 0" |
|
2615 "\<And>x' y'. x' \<in> X \<Longrightarrow> y' \<in> Y \<Longrightarrow> (x', y') \<noteq> (x, y) \<Longrightarrow> dist (x', y') (x, y) < d' \<Longrightarrow> |
|
2616 dist (fy x' y') (fy x y) < e" |
|
2617 by auto |
|
2618 then |
|
2619 have d': "x' \<in> X \<Longrightarrow> y' \<in> Y \<Longrightarrow> dist (x', y') (x, y) < d' \<Longrightarrow> dist (fy x' y') (fy x y) < e" |
|
2620 for x' y' |
|
2621 using \<open>0 < e\<close> |
|
2622 by (cases "(x', y') = (x, y)") auto |
|
2623 def d \<equiv> "d' / sqrt 2" |
|
2624 have "d > 0" using \<open>0 < d'\<close> by (simp add: d_def) |
|
2625 have d: "x' \<in> X \<Longrightarrow> y' \<in> Y \<Longrightarrow> dist x' x < d \<Longrightarrow> dist y' y < d \<Longrightarrow> dist (fy x' y') (fy x y) < e" |
|
2626 for x' y' |
|
2627 by (auto simp: dist_prod_def d_def intro!: d' real_sqrt_sum_squares_less) |
|
2628 |
|
2629 let ?S = "ball y d \<inter> Y" |
|
2630 have "convex ?S" |
|
2631 by (auto intro!: convex_Int \<open>convex Y\<close>) |
|
2632 { |
|
2633 fix x'::'a and y'::'b |
|
2634 assume x': "x' \<in> X" and y': "y' \<in> Y" |
|
2635 assume dx': "dist x' x < d" and dy': "dist y' y < d" |
|
2636 have "norm (fy x' y' - fy x' y) \<le> dist (fy x' y') (fy x y) + dist (fy x' y) (fy x y)" |
|
2637 by norm |
|
2638 also have "dist (fy x' y') (fy x y) < e" |
|
2639 by (rule d; fact) |
|
2640 also have "dist (fy x' y) (fy x y) < e" |
|
2641 by (auto intro!: d simp: dist_prod_def x' \<open>d > 0\<close> \<open>y \<in> Y\<close> dx') |
|
2642 finally |
|
2643 have "norm (fy x' y' - fy x' y) < e + e" |
|
2644 by arith |
|
2645 then have "onorm (blinfun_apply (fy x' y') - blinfun_apply (fy x' y)) < e + e" |
|
2646 by (auto simp: norm_blinfun.rep_eq blinfun.diff_left[abs_def] fun_diff_def) |
|
2647 } note onorm = this |
|
2648 |
|
2649 have ev_mem: "\<forall>\<^sub>F (x', y') in at (x, y) within X \<times> Y. (x', y') \<in> X \<times> Y" |
|
2650 using \<open>x \<in> X\<close> \<open>y \<in> Y\<close> |
|
2651 by (auto simp: eventually_at intro!: zero_less_one) |
|
2652 moreover |
|
2653 have ev_dist: "\<forall>\<^sub>F xy in at (x, y) within X \<times> Y. dist xy (x, y) < d" if "d > 0" for d |
|
2654 using eventually_at_ball[OF that] |
|
2655 by (rule eventually_elim2) (auto simp: dist_commute intro!: eventually_True) |
|
2656 note ev_dist[OF \<open>0 < d\<close>] |
|
2657 ultimately |
|
2658 have "\<forall>\<^sub>F (x', y') in at (x, y) within X \<times> Y. |
|
2659 norm (f x' y' - f x' y - (fy x' y) (y' - y)) \<le> norm (y' - y) * (e + e)" |
|
2660 proof (eventually_elim, safe) |
|
2661 fix x' y' |
|
2662 assume "x' \<in> X" and y': "y' \<in> Y" |
|
2663 assume dist: "dist (x', y') (x, y) < d" |
|
2664 then have dx: "dist x' x < d" and dy: "dist y' y < d" |
|
2665 unfolding dist_prod_def fst_conv snd_conv atomize_conj |
|
2666 by (metis le_less_trans real_sqrt_sum_squares_ge1 real_sqrt_sum_squares_ge2) |
|
2667 { |
|
2668 fix t::real |
|
2669 assume "t \<in> {0 .. 1}" |
|
2670 then have "y + t *\<^sub>R (y' - y) \<in> closed_segment y y'" |
|
2671 by (auto simp: closed_segment_def algebra_simps intro!: exI[where x=t]) |
|
2672 also |
|
2673 have "\<dots> \<subseteq> ball y d \<inter> Y" |
|
2674 using \<open>y \<in> Y\<close> \<open>0 < d\<close> dy y' |
|
2675 by (intro \<open>convex ?S\<close>[unfolded convex_contains_segment, rule_format, of y y']) |
|
2676 (auto simp: dist_commute) |
|
2677 finally have "y + t *\<^sub>R (y' - y) \<in> ?S" . |
|
2678 } note seg = this |
|
2679 |
|
2680 have "\<forall>x\<in>ball y d \<inter> Y. onorm (blinfun_apply (fy x' x) - blinfun_apply (fy x' y)) \<le> e + e" |
|
2681 by (safe intro!: onorm less_imp_le \<open>x' \<in> X\<close> dx) (auto simp: dist_commute \<open>0 < d\<close> \<open>y \<in> Y\<close>) |
|
2682 with seg has_derivative_within_subset[OF assms(2)[OF \<open>x' \<in> X\<close>]] |
|
2683 show "norm (f x' y' - f x' y - (fy x' y) (y' - y)) \<le> norm (y' - y) * (e + e)" |
|
2684 by (rule differentiable_bound_linearization[where S="?S"]) |
|
2685 (auto intro!: \<open>0 < d\<close> \<open>y \<in> Y\<close>) |
|
2686 qed |
|
2687 moreover |
|
2688 let ?le = "\<lambda>x'. norm (f x' y - f x y - (fx x y) (x' - x)) \<le> norm (x' - x) * e" |
|
2689 from fx[OF \<open>x \<in> X\<close> \<open>y \<in> Y\<close>, unfolded has_derivative_within, THEN conjunct2, THEN tendstoD, OF \<open>0 < e\<close>] |
|
2690 have "\<forall>\<^sub>F x' in at x within X. ?le x'" |
|
2691 by eventually_elim |
|
2692 (auto simp: dist_norm divide_simps blinfun.bilinear_simps field_simps split: split_if_asm) |
|
2693 then have "\<forall>\<^sub>F (x', y') in at (x, y) within X \<times> Y. ?le x'" |
|
2694 by (rule eventually_at_Pair_within_TimesI1) |
|
2695 (simp add: blinfun.bilinear_simps) |
|
2696 moreover have "\<forall>\<^sub>F (x', y') in at (x, y) within X \<times> Y. norm ((x', y') - (x, y)) \<noteq> 0" |
|
2697 unfolding norm_eq_zero right_minus_eq |
|
2698 by (auto simp: eventually_at intro!: zero_less_one) |
|
2699 moreover |
|
2700 from fy_cont[unfolded continuous_on_eq_continuous_within, rule_format, OF SigmaI[OF \<open>x \<in> X\<close> \<open>y \<in> Y\<close>], |
|
2701 unfolded continuous_within, THEN tendstoD, OF \<open>0 < e\<close>] |
|
2702 have "\<forall>\<^sub>F x' in at x within X. norm (fy x' y - fy x y) < e" |
|
2703 unfolding eventually_at |
|
2704 using \<open>y \<in> Y\<close> |
|
2705 by (auto simp: dist_prod_def dist_norm) |
|
2706 then have "\<forall>\<^sub>F (x', y') in at (x, y) within X \<times> Y. norm (fy x' y - fy x y) < e" |
|
2707 by (rule eventually_at_Pair_within_TimesI1) |
|
2708 (simp add: blinfun.bilinear_simps \<open>0 < e\<close>) |
|
2709 ultimately |
|
2710 have "\<forall>\<^sub>F (x', y') in at (x, y) within X \<times> Y. |
|
2711 norm ((f x' y' - f x y - (fx x y (x' - x) + fy x y (y' - y))) /\<^sub>R |
|
2712 norm ((x', y') - (x, y))) |
|
2713 < e'" |
|
2714 apply eventually_elim |
|
2715 proof safe |
|
2716 fix x' y' |
|
2717 have "norm (f x' y' - f x y - (fx x y (x' - x) + fy x y (y' - y))) \<le> |
|
2718 norm (f x' y' - f x' y - fy x' y (y' - y)) + |
|
2719 norm (fy x y (y' - y) - fy x' y (y' - y)) + |
|
2720 norm (f x' y - f x y - fx x y (x' - x))" |
|
2721 by norm |
|
2722 also |
|
2723 assume nz: "norm ((x', y') - (x, y)) \<noteq> 0" |
|
2724 and nfy: "norm (fy x' y - fy x y) < e" |
|
2725 assume "norm (f x' y' - f x' y - blinfun_apply (fy x' y) (y' - y)) \<le> norm (y' - y) * (e + e)" |
|
2726 also assume "norm (f x' y - f x y - blinfun_apply (fx x y) (x' - x)) \<le> norm (x' - x) * e" |
|
2727 also |
|
2728 have "norm ((fy x y) (y' - y) - (fy x' y) (y' - y)) \<le> norm ((fy x y) - (fy x' y)) * norm (y' - y)" |
|
2729 by (auto simp: blinfun.bilinear_simps[symmetric] intro!: norm_blinfun) |
|
2730 also have "\<dots> \<le> (e + e) * norm (y' - y)" |
|
2731 using \<open>e > 0\<close> nfy |
|
2732 by (auto simp: norm_minus_commute intro!: mult_right_mono) |
|
2733 also have "norm (x' - x) * e \<le> norm (x' - x) * (e + e)" |
|
2734 using \<open>0 < e\<close> by simp |
|
2735 also have "norm (y' - y) * (e + e) + (e + e) * norm (y' - y) + norm (x' - x) * (e + e) \<le> |
|
2736 (norm (y' - y) + norm (x' - x)) * (4 * e)" |
|
2737 using \<open>e > 0\<close> |
|
2738 by (simp add: algebra_simps) |
|
2739 also have "\<dots> \<le> 2 * norm ((x', y') - (x, y)) * (4 * e)" |
|
2740 using \<open>0 < e\<close> real_sqrt_sum_squares_ge1[of "norm (x' - x)" "norm (y' - y)"] |
|
2741 real_sqrt_sum_squares_ge2[of "norm (y' - y)" "norm (x' - x)"] |
|
2742 by (auto intro!: mult_right_mono simp: norm_prod_def |
|
2743 simp del: real_sqrt_sum_squares_ge1 real_sqrt_sum_squares_ge2) |
|
2744 also have "\<dots> \<le> norm ((x', y') - (x, y)) * (8 * e)" |
|
2745 by simp |
|
2746 also have "\<dots> < norm ((x', y') - (x, y)) * e'" |
|
2747 using \<open>0 < e'\<close> nz |
|
2748 by (auto simp: e_def) |
|
2749 finally show "norm ((f x' y' - f x y - (fx x y (x' - x) + fy x y (y' - y))) /\<^sub>R norm ((x', y') - (x, y))) < e'" |
|
2750 by (auto simp: divide_simps dist_norm mult.commute) |
|
2751 qed |
|
2752 then show ?case |
|
2753 by eventually_elim (auto simp: dist_norm field_simps) |
|
2754 qed (auto intro!: bounded_linear_intros simp: split_beta') |
|
2755 |
|
2756 |
2564 end |
2757 end |