src/HOL/Library/Convex.thy
changeset 44890 22f665a2e91c
parent 44282 f0de18b62d63
child 49609 89e10ed7668b
equal deleted inserted replaced
44889:340df9f3491f 44890:22f665a2e91c
   110   case (insert i s) note asms = this
   110   case (insert i s) note asms = this
   111   { assume "a i = 1"
   111   { assume "a i = 1"
   112     hence "(\<Sum> j \<in> s. a j) = 0"
   112     hence "(\<Sum> j \<in> s. a j) = 0"
   113       using asms by auto
   113       using asms by auto
   114     hence "\<And> j. j \<in> s \<Longrightarrow> a j = 0"
   114     hence "\<And> j. j \<in> s \<Longrightarrow> a j = 0"
   115       using setsum_nonneg_0[where 'b=real] asms by fastsimp
   115       using setsum_nonneg_0[where 'b=real] asms by fastforce
   116     hence ?case using asms by auto }
   116     hence ?case using asms by auto }
   117   moreover
   117   moreover
   118   { assume asm: "a i \<noteq> 1"
   118   { assume asm: "a i \<noteq> 1"
   119     from asms have yai: "y i \<in> C" "a i \<ge> 0" by auto
   119     from asms have yai: "y i \<in> C" "a i \<ge> 0" by auto
   120     have fis: "finite (insert i s)" using asms by auto
   120     have fis: "finite (insert i s)" using asms by auto
   123     hence i0: "1 - a i > 0" by auto
   123     hence i0: "1 - a i > 0" by auto
   124     let "?a j" = "a j / (1 - a i)"
   124     let "?a j" = "a j / (1 - a i)"
   125     { fix j assume "j \<in> s"
   125     { fix j assume "j \<in> s"
   126       hence "?a j \<ge> 0"
   126       hence "?a j \<ge> 0"
   127         using i0 asms divide_nonneg_pos
   127         using i0 asms divide_nonneg_pos
   128         by fastsimp } note a_nonneg = this
   128         by fastforce } note a_nonneg = this
   129     have "(\<Sum> j \<in> insert i s. a j) = 1" using asms by auto
   129     have "(\<Sum> j \<in> insert i s. a j) = 1" using asms by auto
   130     hence "(\<Sum> j \<in> s. a j) = 1 - a i" using setsum.insert asms by fastsimp
   130     hence "(\<Sum> j \<in> s. a j) = 1 - a i" using setsum.insert asms by fastforce
   131     hence "(\<Sum> j \<in> s. a j) / (1 - a i) = 1" using i0 by auto
   131     hence "(\<Sum> j \<in> s. a j) / (1 - a i) = 1" using i0 by auto
   132     hence a1: "(\<Sum> j \<in> s. ?a j) = 1" unfolding setsum_divide_distrib by simp
   132     hence a1: "(\<Sum> j \<in> s. ?a j) = 1" unfolding setsum_divide_distrib by simp
   133     from this asms
   133     from this asms
   134     have "(\<Sum>j\<in>s. ?a j *\<^sub>R y j) \<in> C" using a_nonneg by fastsimp
   134     have "(\<Sum>j\<in>s. ?a j *\<^sub>R y j) \<in> C" using a_nonneg by fastforce
   135     hence "a i *\<^sub>R y i + (1 - a i) *\<^sub>R (\<Sum> j \<in> s. ?a j *\<^sub>R y j) \<in> C"
   135     hence "a i *\<^sub>R y i + (1 - a i) *\<^sub>R (\<Sum> j \<in> s. ?a j *\<^sub>R y j) \<in> C"
   136       using asms[unfolded convex_def, rule_format] yai ai1 by auto
   136       using asms[unfolded convex_def, rule_format] yai ai1 by auto
   137     hence "a i *\<^sub>R y i + (\<Sum> j \<in> s. (1 - a i) *\<^sub>R (?a j *\<^sub>R y j)) \<in> C"
   137     hence "a i *\<^sub>R y i + (\<Sum> j \<in> s. (1 - a i) *\<^sub>R (?a j *\<^sub>R y j)) \<in> C"
   138       using scaleR_right.setsum[of "(1 - a i)" "\<lambda> j. ?a j *\<^sub>R y j" s] by auto
   138       using scaleR_right.setsum[of "(1 - a i)" "\<lambda> j. ?a j *\<^sub>R y j" s] by auto
   139     hence "a i *\<^sub>R y i + (\<Sum> j \<in> s. a j *\<^sub>R y j) \<in> C" using i0 by auto
   139     hence "a i *\<^sub>R y i + (\<Sum> j \<in> s. a j *\<^sub>R y j) \<in> C" using i0 by auto
   254   let ?m = "max (f x) (f y)"
   254   let ?m = "max (f x) (f y)"
   255   have "u * f x + v * f y \<le> u * max (f x) (f y) + v * max (f x) (f y)"
   255   have "u * f x + v * f y \<le> u * max (f x) (f y) + v * max (f x) (f y)"
   256     using assms(4,5) by (auto simp add: mult_left_mono add_mono)
   256     using assms(4,5) by (auto simp add: mult_left_mono add_mono)
   257   also have "\<dots> = max (f x) (f y)" using assms(6) unfolding distrib[THEN sym] by auto
   257   also have "\<dots> = max (f x) (f y)" using assms(6) unfolding distrib[THEN sym] by auto
   258   finally show ?thesis
   258   finally show ?thesis
   259     using assms unfolding convex_on_def by fastsimp
   259     using assms unfolding convex_on_def by fastforce
   260 qed
   260 qed
   261 
   261 
   262 lemma convex_distance[intro]:
   262 lemma convex_distance[intro]:
   263   fixes s :: "'a::real_normed_vector set"
   263   fixes s :: "'a::real_normed_vector set"
   264   shows "convex_on s (\<lambda>x. dist a x)"
   264   shows "convex_on s (\<lambda>x. dist a x)"
   361   moreover
   361   moreover
   362   { assume "\<mu> \<noteq> 1" "\<mu> \<noteq> 0"
   362   { assume "\<mu> \<noteq> 1" "\<mu> \<noteq> 0"
   363     hence "\<mu> > 0" "(1 - \<mu>) > 0" using asms by auto
   363     hence "\<mu> > 0" "(1 - \<mu>) > 0" using asms by auto
   364     hence "\<mu> *\<^sub>R x + (1 - \<mu>) *\<^sub>R y > 0" using asms
   364     hence "\<mu> *\<^sub>R x + (1 - \<mu>) *\<^sub>R y > 0" using asms
   365       by (auto simp add: add_pos_pos mult_pos_pos) }
   365       by (auto simp add: add_pos_pos mult_pos_pos) }
   366   ultimately show "(1 - \<mu>) *\<^sub>R y + \<mu> *\<^sub>R x > 0" using assms by fastsimp
   366   ultimately show "(1 - \<mu>) *\<^sub>R y + \<mu> *\<^sub>R x > 0" using assms by fastforce
   367 qed
   367 qed
   368 
   368 
   369 lemma convex_on_setsum:
   369 lemma convex_on_setsum:
   370   fixes a :: "'a \<Rightarrow> real"
   370   fixes a :: "'a \<Rightarrow> real"
   371   fixes y :: "'a \<Rightarrow> 'b::real_vector"
   371   fixes y :: "'a \<Rightarrow> 'b::real_vector"
   391     by simp
   391     by simp
   392   { assume "a i = 1"
   392   { assume "a i = 1"
   393     hence "(\<Sum> j \<in> s. a j) = 0"
   393     hence "(\<Sum> j \<in> s. a j) = 0"
   394       using asms by auto
   394       using asms by auto
   395     hence "\<And> j. j \<in> s \<Longrightarrow> a j = 0"
   395     hence "\<And> j. j \<in> s \<Longrightarrow> a j = 0"
   396       using setsum_nonneg_0[where 'b=real] asms by fastsimp
   396       using setsum_nonneg_0[where 'b=real] asms by fastforce
   397     hence ?case using asms by auto }
   397     hence ?case using asms by auto }
   398   moreover
   398   moreover
   399   { assume asm: "a i \<noteq> 1"
   399   { assume asm: "a i \<noteq> 1"
   400     from asms have yai: "y i \<in> C" "a i \<ge> 0" by auto
   400     from asms have yai: "y i \<in> C" "a i \<ge> 0" by auto
   401     have fis: "finite (insert i s)" using asms by auto
   401     have fis: "finite (insert i s)" using asms by auto
   404     hence i0: "1 - a i > 0" by auto
   404     hence i0: "1 - a i > 0" by auto
   405     let "?a j" = "a j / (1 - a i)"
   405     let "?a j" = "a j / (1 - a i)"
   406     { fix j assume "j \<in> s"
   406     { fix j assume "j \<in> s"
   407       hence "?a j \<ge> 0"
   407       hence "?a j \<ge> 0"
   408         using i0 asms divide_nonneg_pos
   408         using i0 asms divide_nonneg_pos
   409         by fastsimp } note a_nonneg = this
   409         by fastforce } note a_nonneg = this
   410     have "(\<Sum> j \<in> insert i s. a j) = 1" using asms by auto
   410     have "(\<Sum> j \<in> insert i s. a j) = 1" using asms by auto
   411     hence "(\<Sum> j \<in> s. a j) = 1 - a i" using setsum.insert asms by fastsimp
   411     hence "(\<Sum> j \<in> s. a j) = 1 - a i" using setsum.insert asms by fastforce
   412     hence "(\<Sum> j \<in> s. a j) / (1 - a i) = 1" using i0 by auto
   412     hence "(\<Sum> j \<in> s. a j) / (1 - a i) = 1" using i0 by auto
   413     hence a1: "(\<Sum> j \<in> s. ?a j) = 1" unfolding setsum_divide_distrib by simp
   413     hence a1: "(\<Sum> j \<in> s. ?a j) = 1" unfolding setsum_divide_distrib by simp
   414     have "convex C" using asms by auto
   414     have "convex C" using asms by auto
   415     hence asum: "(\<Sum> j \<in> s. ?a j *\<^sub>R y j) \<in> C"
   415     hence asum: "(\<Sum> j \<in> s. ?a j *\<^sub>R y j) \<in> C"
   416       using asms convex_setsum[OF `finite s`
   416       using asms convex_setsum[OF `finite s`
   495 proof safe
   495 proof safe
   496   fix x y \<mu> :: real
   496   fix x y \<mu> :: real
   497   let ?x = "\<mu> *\<^sub>R x + (1 - \<mu>) *\<^sub>R y"
   497   let ?x = "\<mu> *\<^sub>R x + (1 - \<mu>) *\<^sub>R y"
   498   assume asm: "convex C" "x \<in> C" "y \<in> C" "\<mu> \<ge> 0" "\<mu> \<le> 1"
   498   assume asm: "convex C" "x \<in> C" "y \<in> C" "\<mu> \<ge> 0" "\<mu> \<le> 1"
   499   hence "1 - \<mu> \<ge> 0" by auto
   499   hence "1 - \<mu> \<ge> 0" by auto
   500   hence xpos: "?x \<in> C" using asm unfolding convex_alt by fastsimp
   500   hence xpos: "?x \<in> C" using asm unfolding convex_alt by fastforce
   501   have geq: "\<mu> * (f x - f ?x) + (1 - \<mu>) * (f y - f ?x)
   501   have geq: "\<mu> * (f x - f ?x) + (1 - \<mu>) * (f y - f ?x)
   502             \<ge> \<mu> * f' ?x * (x - ?x) + (1 - \<mu>) * f' ?x * (y - ?x)"
   502             \<ge> \<mu> * f' ?x * (x - ?x) + (1 - \<mu>) * f' ?x * (y - ?x)"
   503     using add_mono[OF mult_left_mono[OF leq[OF xpos asm(2)] `\<mu> \<ge> 0`]
   503     using add_mono[OF mult_left_mono[OF leq[OF xpos asm(2)] `\<mu> \<ge> 0`]
   504       mult_left_mono[OF leq[OF xpos asm(3)] `1 - \<mu> \<ge> 0`]] by auto
   504       mult_left_mono[OF leq[OF xpos asm(3)] `1 - \<mu> \<ge> 0`]] by auto
   505   hence "\<mu> * f x + (1 - \<mu>) * f y - f ?x \<ge> 0"
   505   hence "\<mu> * f x + (1 - \<mu>) * f y - f ?x \<ge> 0"
   548     then obtain z1 where z1: "z1 > x" "z1 < y" "f y - f x = (y - x) * f' z1"
   548     then obtain z1 where z1: "z1 > x" "z1 < y" "f y - f x = (y - x) * f' z1"
   549       using subsetD[OF atMostAtLeast_subset_convex[OF `convex C` `x \<in> C` `y \<in> C` `x < y`],
   549       using subsetD[OF atMostAtLeast_subset_convex[OF `convex C` `x \<in> C` `y \<in> C` `x < y`],
   550         THEN f', THEN MVT2[OF `x < y`, rule_format, unfolded atLeastAtMost_iff[symmetric]]]
   550         THEN f', THEN MVT2[OF `x < y`, rule_format, unfolded atLeastAtMost_iff[symmetric]]]
   551       by auto
   551       by auto
   552     hence "z1 \<in> C" using atMostAtLeast_subset_convex
   552     hence "z1 \<in> C" using atMostAtLeast_subset_convex
   553       `convex C` `x \<in> C` `y \<in> C` `x < y` by fastsimp
   553       `convex C` `x \<in> C` `y \<in> C` `x < y` by fastforce
   554     from z1 have z1': "f x - f y = (x - y) * f' z1"
   554     from z1 have z1': "f x - f y = (x - y) * f' z1"
   555       by (simp add:field_simps)
   555       by (simp add:field_simps)
   556     obtain z2 where z2: "z2 > x" "z2 < z1" "f' z1 - f' x = (z1 - x) * f'' z2"
   556     obtain z2 where z2: "z2 > x" "z2 < z1" "f' z1 - f' x = (z1 - x) * f'' z2"
   557       using subsetD[OF atMostAtLeast_subset_convex[OF `convex C` `x \<in> C` `z1 \<in> C` `x < z1`],
   557       using subsetD[OF atMostAtLeast_subset_convex[OF `convex C` `x \<in> C` `z1 \<in> C` `x < z1`],
   558         THEN f'', THEN MVT2[OF `x < z1`, rule_format, unfolded atLeastAtMost_iff[symmetric]]] z1
   558         THEN f'', THEN MVT2[OF `x < z1`, rule_format, unfolded atLeastAtMost_iff[symmetric]]] z1
   565       using asm z1' by auto
   565       using asm z1' by auto
   566     also have "\<dots> = (y - z1) * f'' z3" using z3 by auto
   566     also have "\<dots> = (y - z1) * f'' z3" using z3 by auto
   567     finally have cool': "f' y - (f x - f y) / (x - y) = (y - z1) * f'' z3" by simp
   567     finally have cool': "f' y - (f x - f y) / (x - y) = (y - z1) * f'' z3" by simp
   568     have A': "y - z1 \<ge> 0" using z1 by auto
   568     have A': "y - z1 \<ge> 0" using z1 by auto
   569     have "z3 \<in> C" using z3 asm atMostAtLeast_subset_convex
   569     have "z3 \<in> C" using z3 asm atMostAtLeast_subset_convex
   570       `convex C` `x \<in> C` `z1 \<in> C` `x < z1` by fastsimp
   570       `convex C` `x \<in> C` `z1 \<in> C` `x < z1` by fastforce
   571     hence B': "f'' z3 \<ge> 0" using assms by auto
   571     hence B': "f'' z3 \<ge> 0" using assms by auto
   572     from A' B' have "(y - z1) * f'' z3 \<ge> 0" using mult_nonneg_nonneg by auto
   572     from A' B' have "(y - z1) * f'' z3 \<ge> 0" using mult_nonneg_nonneg by auto
   573     from cool' this have "f' y - (f x - f y) / (x - y) \<ge> 0" by auto
   573     from cool' this have "f' y - (f x - f y) / (x - y) \<ge> 0" by auto
   574     from mult_right_mono_neg[OF this le(2)]
   574     from mult_right_mono_neg[OF this le(2)]
   575     have "f' y * (x - y) - (f x - f y) / (x - y) * (x - y) \<le> 0 * (x - y)"
   575     have "f' y * (x - y) - (f x - f y) / (x - y) * (x - y) \<le> 0 * (x - y)"
   580       using asm z1 by auto
   580       using asm z1 by auto
   581     also have "\<dots> = (z1 - x) * f'' z2" using z2 by auto
   581     also have "\<dots> = (z1 - x) * f'' z2" using z2 by auto
   582     finally have cool: "(f y - f x) / (y - x) - f' x = (z1 - x) * f'' z2" by simp
   582     finally have cool: "(f y - f x) / (y - x) - f' x = (z1 - x) * f'' z2" by simp
   583     have A: "z1 - x \<ge> 0" using z1 by auto
   583     have A: "z1 - x \<ge> 0" using z1 by auto
   584     have "z2 \<in> C" using z2 z1 asm atMostAtLeast_subset_convex
   584     have "z2 \<in> C" using z2 z1 asm atMostAtLeast_subset_convex
   585       `convex C` `z1 \<in> C` `y \<in> C` `z1 < y` by fastsimp
   585       `convex C` `z1 \<in> C` `y \<in> C` `z1 < y` by fastforce
   586     hence B: "f'' z2 \<ge> 0" using assms by auto
   586     hence B: "f'' z2 \<ge> 0" using assms by auto
   587     from A B have "(z1 - x) * f'' z2 \<ge> 0" using mult_nonneg_nonneg by auto
   587     from A B have "(z1 - x) * f'' z2 \<ge> 0" using mult_nonneg_nonneg by auto
   588     from cool this have "(f y - f x) / (y - x) - f' x \<ge> 0" by auto
   588     from cool this have "(f y - f x) / (y - x) - f' x \<ge> 0" by auto
   589     from mult_right_mono[OF this ge(2)]
   589     from mult_right_mono[OF this ge(2)]
   590     have "(f y - f x) / (y - x) * (y - x) - f' x * (y - x) \<ge> 0 * (y - x)"
   590     have "(f y - f x) / (y - x) * (y - x) - f' x * (y - x) \<ge> 0 * (y - x)"
   606   assumes conv: "convex C"
   606   assumes conv: "convex C"
   607   assumes f': "\<And> x. x \<in> C \<Longrightarrow> DERIV f x :> (f' x)"
   607   assumes f': "\<And> x. x \<in> C \<Longrightarrow> DERIV f x :> (f' x)"
   608   assumes f'': "\<And> x. x \<in> C \<Longrightarrow> DERIV f' x :> (f'' x)"
   608   assumes f'': "\<And> x. x \<in> C \<Longrightarrow> DERIV f' x :> (f'' x)"
   609   assumes pos: "\<And> x. x \<in> C \<Longrightarrow> f'' x \<ge> 0"
   609   assumes pos: "\<And> x. x \<in> C \<Longrightarrow> f'' x \<ge> 0"
   610   shows "convex_on C f"
   610   shows "convex_on C f"
   611 using f''_imp_f'[OF conv f' f'' pos] assms pos_convex_function by fastsimp
   611 using f''_imp_f'[OF conv f' f'' pos] assms pos_convex_function by fastforce
   612 
   612 
   613 lemma minus_log_convex:
   613 lemma minus_log_convex:
   614   fixes b :: real
   614   fixes b :: real
   615   assumes "b > 1"
   615   assumes "b > 1"
   616   shows "convex_on {0 <..} (\<lambda> x. - log b x)"
   616   shows "convex_on {0 <..} (\<lambda> x. - log b x)"