diff --git a/thys/IMO2019/IMO2019_Q4.thy b/thys/IMO2019/IMO2019_Q4.thy --- a/thys/IMO2019/IMO2019_Q4.thy +++ b/thys/IMO2019/IMO2019_Q4.thy @@ -1,299 +1,299 @@ (* File: IMO2019_Q4.thy Author: Manuel Eberl, TU München *) section \Q4\ theory IMO2019_Q4 imports "Prime_Distribution_Elementary.More_Dirichlet_Misc" begin text \ Find all pairs \(k, n)\ of positive integers such that $k! = \prod_{i=0}^{n-1} (2^n - 2^i)$. \ subsection \Auxiliary facts\ (* TODO: Move stuff from this section? *) lemma Sigma_insert: "Sigma (insert x A) f = (\y. (x, y)) ` f x \ Sigma A f" by auto lemma atLeastAtMost_nat_numeral: "{(m::nat)..numeral k} = (if m \ numeral k then insert (numeral k) {m..pred_numeral k} else {})" by (auto simp: numeral_eq_Suc) lemma greaterThanAtMost_nat_numeral: "{(m::nat)<..numeral k} = (if m < numeral k then insert (numeral k) {m<..pred_numeral k} else {})" by (auto simp: numeral_eq_Suc) lemma fact_ge_power: fixes c :: nat assumes "fact n0 \ c ^ n0" "c \ n0 + 1" assumes "n \ n0" shows "fact n \ c ^ n" using assms(3,1,2) proof (induction n rule: dec_induct) case (step n) have "c * c ^ n \ Suc n * fact n" using step by (intro mult_mono) auto thus ?case by simp qed auto lemma prime_multiplicity_prime: fixes p q :: "'a :: factorial_semiring" assumes "prime p" "prime q" shows "multiplicity p q = (if p = q then 1 else 0)" using assms by (auto simp: prime_multiplicity_other) text \ We use Legendre's identity from the library. One could easily prove the property in question without the library, but it probably still saves a few lines. @{const legendre_aux} (related to Legendre's identity) is the multiplicity of a given prime in the prime factorisation of \n!\. \ (* TODO: Move? *) lemma multiplicity_prime_fact: fixes p :: nat assumes "prime p" shows "multiplicity p (fact n) = legendre_aux n p" proof (cases "p \ n") case True have "fact n = (\p | prime p \ p \ n. p ^ legendre_aux n p)" using legendre_identity'[of "real n"] by simp also have "multiplicity p \ = (\q | prime q \ q \ n. multiplicity p (q ^ legendre_aux n q))" using assms by (subst prime_elem_multiplicity_prod_distrib) auto also have "\ = (\q\{p}. legendre_aux n q)" using assms \p \ n\ prime_multiplicity_other[of p] by (intro sum.mono_neutral_cong_right) (auto simp: prime_elem_multiplicity_power_distrib prime_multiplicity_prime split: if_splits) finally show ?thesis by simp next case False hence "multiplicity p (fact n) = 0" using assms by (intro not_dvd_imp_multiplicity_0) (auto simp: prime_dvd_fact_iff) moreover from False have "legendre_aux (real n) p = 0" by (intro legendre_aux_eq_0) auto ultimately show ?thesis by simp qed text \ The following are simple and trivial lower and upper bounds for @{const legendre_aux}: \ lemma legendre_aux_ge: assumes "prime p" "k \ 1" shows "legendre_aux k p \ nat \k / p\" proof (cases "k \ p") case True have "(\m\{1}. nat \k / real p ^ m\) \ (\m | 0 < m \ real p ^ m \ k. nat \k / real p ^ m\)" using True finite_sum_legendre_aux[of p] assms by (intro sum_mono2) auto with assms True show ?thesis by (simp add: legendre_aux_def) next case False with assms have "k / p < 1" by (simp add: field_simps) hence "nat \k / p\ = 0" by simp with False show ?thesis by (simp add: legendre_aux_eq_0) qed lemma legendre_aux_less: assumes "prime p" "k \ 1" shows "legendre_aux k p < k / (p - 1)" proof - have "(\m. (k / p) * (1 / p) ^ m) sums ((k / p) * (1 / (1 - 1 / p)))" using assms prime_gt_1_nat[of p] by (intro sums_mult geometric_sums) (auto simp: field_simps) hence sums: "(\m. k / p ^ Suc m) sums (k / (p - 1))" using assms prime_gt_1_nat[of p] by (simp add: field_simps of_nat_diff) have "real (legendre_aux k p) = (\m\{0<..nat \log (real p) k\}. of_int \k / real p ^ m\)" using assms by (simp add: legendre_aux_altdef1) also have "\ = (\mlog (real p) k\. of_int \k / real p ^ Suc m\)" by (intro sum.reindex_bij_witness[of _ Suc "\i. i - 1"]) (auto simp flip: power_Suc) also have "\ \ (\mlog (real p) k\. k / real p ^ Suc m)" by (intro sum_mono) auto also have "\ < (\m. k / real p ^ Suc m)" using sums assms prime_gt_1_nat[of p] by (intro sum_less_suminf) (auto simp: sums_iff intro!: divide_pos_pos) also have "\ = k / (p - 1)" using sums by (simp add: sums_iff) finally show ?thesis using assms prime_gt_1_nat[of p] by (simp add: of_nat_diff) qed subsection \Main result\ text \ Now we move on to the main result: We fix two numbers \n\ and \k\ with the property in question and derive facts from that. The triangle number $T = n(n+1)/2$ is of particular importance here, so we introduce an abbreviation for it. \ context fixes k n :: nat and rhs T :: nat defines "rhs \ (\i (n * (n - 1)) div 2" assumes pos: "k > 0" "n > 0" assumes k_n: "fact k = rhs" begin text \ We can rewrite the right-hand side into a more convenient form: \ lemma rhs_altdef: "rhs = 2 ^ T * (\i=1..n. 2 ^ i - 1)" proof - have "rhs = (\i = 2 ^ (\iiiii=1..n. 2 ^ i - 1)" by (rule prod.reindex_bij_witness[of _ "\i. n - i" "\i. n - i"]) auto finally show ?thesis . qed text \ The multiplicity of 2 in the prime factorisation of the right-hand side is precisely \T\. \ lemma multiplicity_2_rhs [simp]: "multiplicity 2 rhs = T" proof - have nz: "2 ^ i - 1 \ (0 :: nat)" if "i \ 1" for i proof - from \i \ 1\ have "2 ^ 0 < (2 ^ i :: nat)" by (intro power_strict_increasing) auto thus ?thesis by simp qed have "multiplicity 2 rhs = T + multiplicity 2 (\i=1..n. 2 ^ i - 1 :: nat)" using nz by (simp add: rhs_altdef prime_elem_multiplicity_mult_distrib) also have "multiplicity 2 (\i=1..n. 2 ^ i - 1 :: nat) = 0" by (intro not_dvd_imp_multiplicity_0) (auto simp: prime_dvd_prod_iff) finally show ?thesis by simp qed text \ From Legendre's identities and the associated bounds, it can easily be seen that \\k/2\ \ T < k\: \ lemma k_gt_T: "k > T" proof - have "T = multiplicity 2 rhs" by simp also have "rhs = fact k" by (simp add: k_n) also have "multiplicity 2 (fact k :: nat) = legendre_aux k 2" by (simp add: multiplicity_prime_fact) also have "\ < k" using legendre_aux_less[of 2 k] pos by simp finally show ?thesis . qed lemma T_ge_half_k: "T \ k div 2" proof - have "k div 2 \ legendre_aux k 2" using legendre_aux_ge[of 2 k] pos by simp linarith? also have "\ = multiplicity 2 (fact k :: nat)" by (simp add: multiplicity_prime_fact) also have "\ = T" by (simp add: k_n) finally show "T \ k div 2" . qed text \ It can also be seen fairly easily that the right-hand side is strictly smaller than $2^{n^2}$: \ lemma rhs_less: "rhs < 2 ^ n\<^sup>2" proof - have "rhs = 2 ^ T * (\i=1..n. 2 ^ i - 1)" by (simp add: rhs_altdef) also have "(\i=1..n. 2 ^ i - 1 :: nat) < (\i=1..n. 2 ^ i)" - using pos by (intro prod_mono_strict) auto + using pos by (intro prod_mono_strict[of 1]) auto also have "\ = (\i=0..i. i - 1"]) (auto simp flip: power_Suc) also have "\ = 2 ^ n * 2 ^ (\i=0..i=0..2" by simp qed text \ It is clear that $2^{n^2} \leq 8^T$ and that $8^T < T!$ if $T$ is sufficiently big. In this case, `sufficiently big' means \T \ 20\ and thereby \n \ 7\. We can therefore conclude that \n\ must be less than 7. \ lemma n_less_7: "n < 7" proof (rule ccontr) assume "\n < 7" hence "n \ 7" by simp have "T \ (7 * 6) div 2" unfolding T_def using \n \ 7\ by (intro div_le_mono mult_mono) auto hence "T \ 21" by simp from \n \ 7\ have "(n * 2) div 2 \ T" unfolding T_def by (intro div_le_mono) auto hence "T \ n" by simp from \T \ 21\ have "sqrt (2 * pi * T) * (T / exp 1) ^ T \ fact T" using fact_bounds[of T] by simp have "fact T \ (fact k :: nat)" using k_gt_T by (intro fact_mono) (auto simp: T_def) also have "\ = rhs" by fact also have "rhs < 2 ^ n\<^sup>2" by (rule rhs_less) also have "n\<^sup>2 = 2 * T + n" by (cases "even n") (auto simp: T_def algebra_simps power2_eq_square) also have "\ \ 3 * T" using \T \ n\ by (simp add: T_def) also have "2 ^ (3 * T) = (8 ^ T :: nat)" by (simp add: power_mult) finally have "fact T < (8 ^ T :: nat)" by simp moreover have "fact T \ (8 ^ T :: nat)" by (rule fact_ge_power[of _ 20]) (use \T \ 21\ in \auto simp: fact_numeral\) ultimately show False by simp qed text \ We now only have 6 values for \n\ to check. Together with the bounds that we obtained on \k\, this only leaves a few combinations of \n\ and \k\ to check, and we do precisely that and find that \n = k = 1\ and \n = 2, k = 3\ are the only possible combinations. \ lemma n_k_in_set: "(n, k) \ {(1, 1), (2, 3)}" proof - define T' where "T' = (\n :: nat. n * (n - 1) div 2)" define A :: "(nat \ nat) set" where "A = (SIGMA n:{1..6}. {T' n<..2 * T' n + 1})" define P where "P = (\(n, k). fact k = (\i Set.filter P A" using k_n pos T_ge_half_k k_gt_T n_less_7 by (auto simp: A_def T'_def T_def Set.filter_def P_def rhs_def) also have "Set.filter P A = {(1, 1), (2, 3)}" by (simp add: P_def Set_filter_insert A_def atMost_nat_numeral atMost_Suc T'_def Sigma_insert greaterThanAtMost_nat_numeral atLeastAtMost_nat_numeral lessThan_nat_numeral fact_numeral cong: if_weak_cong) finally show ?thesis . qed end text \ Using this, deriving the final result is now trivial: \ theorem "{(n, k). n > 0 \ k > 0 \ fact k = (\i ?rhs" using n_k_in_set by blast show "?rhs \ ?lhs" by (auto simp: fact_numeral lessThan_nat_numeral) qed end \ No newline at end of file diff --git a/thys/Weighted_Arithmetic_Geometric_Mean/Weighted_Arithmetic_Geometric_Mean.thy b/thys/Weighted_Arithmetic_Geometric_Mean/Weighted_Arithmetic_Geometric_Mean.thy --- a/thys/Weighted_Arithmetic_Geometric_Mean/Weighted_Arithmetic_Geometric_Mean.thy +++ b/thys/Weighted_Arithmetic_Geometric_Mean/Weighted_Arithmetic_Geometric_Mean.thy @@ -1,454 +1,435 @@ section \The Weighted Arithmetic--Geometric Mean Inequality\ theory Weighted_Arithmetic_Geometric_Mean imports Complex_Main begin subsection \Auxiliary Facts\ lemma root_powr_inverse': "0 < n \ 0 \ x \ root n x = x powr (1/n)" by (cases "x = 0") (auto simp: root_powr_inverse) lemma powr_sum_distrib_real_right: assumes "a \ 0" shows "(\x\X. a powr e x :: real) = a powr (\x\X. e x)" using assms by (induction X rule: infinite_finite_induct) (auto simp: powr_add) lemma powr_sum_distrib_real_left: assumes "\x. x \ X \ a x \ 0" shows "(\x\X. a x powr e :: real) = (\x\X. a x) powr e" using assms by (induction X rule: infinite_finite_induct) (auto simp: powr_mult prod_nonneg) -lemma (in linordered_semidom) prod_mono_strict': - assumes "i \ A" - assumes "finite A" - assumes "\i. i \ A \ 0 \ f i \ f i \ g i" - assumes "\i. i \ A \ 0 < g i" - assumes "f i < g i" - shows "prod f A < prod g A" -proof - - have "prod f A = f i * prod f (A - {i})" - using assms by (intro prod.remove) - also have "\ \ f i * prod g (A - {i})" - using assms by (intro mult_left_mono prod_mono) auto - also have "\ < g i * prod g (A - {i})" - using assms by (intro mult_strict_right_mono prod_pos) auto - also have "\ = prod g A" - using assms by (intro prod.remove [symmetric]) - finally show ?thesis . -qed - lemma prod_ge_pointwise_le_imp_pointwise_eq: fixes f :: "'a \ real" assumes "finite X" assumes ge: "prod f X \ prod g X" assumes nonneg: "\x. x \ X \ f x \ 0" assumes pos: "\x. x \ X \ g x > 0" assumes le: "\x. x \ X \ f x \ g x" and x: "x \ X" shows "f x = g x" proof (rule ccontr) assume "f x \ g x" with le[of x] and x have "f x < g x" by auto hence "prod f X < prod g X" using x and le and nonneg and pos and \finite X\ - by (intro prod_mono_strict') auto + by (intro prod_mono_strict) auto with ge show False by simp qed lemma powr_right_real_eq_iff: assumes "a \ (0 :: real)" shows "a powr x = a powr y \ a = 0 \ a = 1 \ x = y" using assms by (auto simp: powr_def) lemma powr_left_real_eq_iff: assumes "a \ (0 :: real)" "b \ 0" "x \ 0" shows "a powr x = b powr x \ a = b" using assms by (auto simp: powr_def) lemma exp_real_eq_one_plus_iff: fixes x :: real shows "exp x = 1 + x \ x = 0" proof (cases "x = 0") case False define f :: "real \ real" where "f = (\x. exp x - 1 - x)" have deriv: "(f has_field_derivative (exp x - 1)) (at x)" for x by (auto simp: f_def intro!: derivative_eq_intros) have "\z. z>min x 0 \ z < max x 0 \ f (max x 0) - f (min x 0) = (max x 0 - min x 0) * (exp z - 1)" using MVT2[of "min x 0" "max x 0" f "\x. exp x - 1"] deriv False by (auto simp: min_def max_def) then obtain z where "z \ {min x 0<..The Inequality\ text \ We first prove the equality under the assumption that all the $a_i$ and $w_i$ are positive. \ lemma weighted_arithmetic_geometric_mean_pos: fixes a w :: "'a \ real" assumes "finite X" assumes pos1: "\x. x \ X \ a x > 0" assumes pos2: "\x. x \ X \ w x > 0" assumes sum_weights: "(\x\X. w x) = 1" shows "(\x\X. a x powr w x) \ (\x\X. w x * a x)" proof - note nonneg1 = less_imp_le[OF pos1] note nonneg2 = less_imp_le[OF pos2] define A where "A = (\x\X. w x * a x)" define r where "r = (\x. a x / A - 1)" from sum_weights have "X \ {}" by auto hence "A \ 0" unfolding A_def using nonneg1 nonneg2 pos1 pos2 \finite X\ by (subst sum_nonneg_eq_0_iff) force+ moreover from nonneg1 nonneg2 have "A \ 0" by (auto simp: A_def intro!: sum_nonneg) ultimately have "A > 0" by simp have "(\x\X. (1 + r x) powr w x) = (\x\X. (a x / A) powr w x)" by (simp add: r_def) also have "\ = (\x\X. a x powr w x) / (\x\X. A powr w x)" unfolding prod_dividef [symmetric] using assms pos2 \A > 0\ by (intro prod.cong powr_divide) (auto intro: less_imp_le) also have "(\x\X. A powr w x) = exp ((\x\X. w x) * ln A)" using \A > 0\ and \finite X\ by (simp add: powr_def exp_sum sum_distrib_right) also have "(\x\X. w x) = 1" by fact also have "exp (1 * ln A) = A" using \A > 0\ by simp finally have lhs: "(\x\X. (1 + r x) powr w x) = (\x\X. a x powr w x) / A" . have "(\x\X. exp (w x * r x)) = exp (\x\X. w x * r x)" using \finite X\ by (simp add: exp_sum) also have "(\x\X. w x * r x) = (\x\X. a x * w x) / A - 1" using \A > 0\ by (simp add: r_def algebra_simps sum_subtractf sum_divide_distrib sum_weights) also have "(\x\X. a x * w x) / A = 1" using \A > 0\ by (simp add: A_def mult.commute) finally have rhs: "(\x\X. exp (w x * r x)) = 1" by simp have "(\x\X. a x powr w x) / A = (\x\X. (1 + r x) powr w x)" by (fact lhs [symmetric]) also have "(\x\X. (1 + r x) powr w x) \ (\x\X. exp (w x * r x))" proof (intro prod_mono conjI) fix x assume x: "x \ X" have "1 + r x \ exp (r x)" by (rule exp_ge_add_one_self) hence "(1 + r x) powr w x \ exp (r x) powr w x" using nonneg1[of x] nonneg2[of x] x \A > 0\ by (intro powr_mono2) (auto simp: r_def field_simps) also have "\ = exp (w x * r x)" by (simp add: powr_def) finally show "(1 + r x) powr w x \ exp (w x * r x)" . qed auto also have "(\x\X. exp (w x * r x)) = 1" by (fact rhs) finally show "(\x\X. a x powr w x) \ A" using \A > 0\ by (simp add: field_simps) qed text \ We can now relax the positivity assumptions to non-negativity: if one of the $a_i$ is zero, the theorem becomes trivial (note that $0^0 = 0$ by convention for the real-valued power operator \<^term>\(powr) :: real \ real \ real\). Otherwise, we can simply remove all the indices that have weight 0 and apply the above auxiliary version of the theorem. \ theorem weighted_arithmetic_geometric_mean: fixes a w :: "'a \ real" assumes "finite X" assumes nonneg1: "\x. x \ X \ a x \ 0" assumes nonneg2: "\x. x \ X \ w x \ 0" assumes sum_weights: "(\x\X. w x) = 1" shows "(\x\X. a x powr w x) \ (\x\X. w x * a x)" proof (cases "\x\X. a x = 0") case True hence "(\x\X. a x powr w x) = 0" using \finite X\ by simp also have "\ \ (\x\X. w x * a x)" by (intro sum_nonneg mult_nonneg_nonneg assms) finally show ?thesis . next case False have "(\x\X-{x. w x = 0}. w x) = (\x\X. w x)" by (intro sum.mono_neutral_left assms) auto also have "\ = 1" by fact finally have sum_weights': "(\x\X-{x. w x = 0}. w x) = 1" . have "(\x\X. a x powr w x) = (\x\X-{x. w x = 0}. a x powr w x)" using \finite X\ False by (intro prod.mono_neutral_right) auto also have "\ \ (\x\X-{x. w x = 0}. w x * a x)" using assms False by (intro weighted_arithmetic_geometric_mean_pos sum_weights') (auto simp: order.strict_iff_order) also have "\ = (\x\X. w x * a x)" using \finite X\ by (intro sum.mono_neutral_left) auto finally show ?thesis . qed text \ We can derive the regular arithmetic/geometric mean inequality from this by simply setting all the weights to $\frac{1}{n}$: \ corollary arithmetic_geometric_mean: fixes a :: "'a \ real" assumes "finite X" defines "n \ card X" assumes nonneg: "\x. x \ X \ a x \ 0" shows "root n (\x\X. a x) \ (\x\X. a x) / n" proof (cases "X = {}") case False with assms have n: "n > 0" by auto have "(\x\X. a x powr (1 / n)) \ (\x\X. (1 / n) * a x)" using n assms by (intro weighted_arithmetic_geometric_mean) auto also have "(\x\X. a x powr (1 / n)) = (\x\X. a x) powr (1 / n)" using nonneg by (subst powr_sum_distrib_real_left) auto also have "\ = root n (\x\X. a x)" using \n > 0\ nonneg by (subst root_powr_inverse') (auto simp: prod_nonneg) also have "(\x\X. (1 / n) * a x) = (\x\X. a x) / n" by (subst sum_distrib_left [symmetric]) auto finally show ?thesis . qed (auto simp: n_def) subsection \The Equality Case\ text \ Next, we show that weighted arithmetic and geometric mean are equal if and only if all the $a_i$ are equal. We first prove the more difficult direction as a lemmas and again first assume positivity of all $a_i$ and $w_i$ and will relax this somewhat later. \ lemma weighted_arithmetic_geometric_mean_eq_iff_pos: fixes a w :: "'a \ real" assumes "finite X" assumes pos1: "\x. x \ X \ a x > 0" assumes pos2: "\x. x \ X \ w x > 0" assumes sum_weights: "(\x\X. w x) = 1" assumes eq: "(\x\X. a x powr w x) = (\x\X. w x * a x)" shows "\x\X. \y\X. a x = a y" proof - note nonneg1 = less_imp_le[OF pos1] note nonneg2 = less_imp_le[OF pos2] define A where "A = (\x\X. w x * a x)" define r where "r = (\x. a x / A - 1)" from sum_weights have "X \ {}" by auto hence "A \ 0" unfolding A_def using nonneg1 nonneg2 pos1 pos2 \finite X\ by (subst sum_nonneg_eq_0_iff) force+ moreover from nonneg1 nonneg2 have "A \ 0" by (auto simp: A_def intro!: sum_nonneg) ultimately have "A > 0" by simp have r_ge: "r x \ -1" if x: "x \ X" for x using \A > 0\ pos1[OF x] by (auto simp: r_def field_simps) have "(\x\X. (1 + r x) powr w x) = (\x\X. (a x / A) powr w x)" by (simp add: r_def) also have "\ = (\x\X. a x powr w x) / (\x\X. A powr w x)" unfolding prod_dividef [symmetric] using assms pos2 \A > 0\ by (intro prod.cong powr_divide) (auto intro: less_imp_le) also have "(\x\X. A powr w x) = exp ((\x\X. w x) * ln A)" using \A > 0\ and \finite X\ by (simp add: powr_def exp_sum sum_distrib_right) also have "(\x\X. w x) = 1" by fact also have "exp (1 * ln A) = A" using \A > 0\ by simp finally have lhs: "(\x\X. (1 + r x) powr w x) = (\x\X. a x powr w x) / A" . have "(\x\X. exp (w x * r x)) = exp (\x\X. w x * r x)" using \finite X\ by (simp add: exp_sum) also have "(\x\X. w x * r x) = (\x\X. a x * w x) / A - 1" using \A > 0\ by (simp add: r_def algebra_simps sum_subtractf sum_divide_distrib sum_weights) also have "(\x\X. a x * w x) / A = 1" using \A > 0\ by (simp add: A_def mult.commute) finally have rhs: "(\x\X. exp (w x * r x)) = 1" by simp have "a x = A" if x: "x \ X" for x proof - have "(1 + r x) powr w x = exp (w x * r x)" proof (rule prod_ge_pointwise_le_imp_pointwise_eq [where f = "\x. (1 + r x) powr w x" and g = "\x. exp (w x * r x)"]) show "(1 + r x) powr w x \ exp (w x * r x)" if x: "x \ X" for x proof - have "1 + r x \ exp (r x)" by (rule exp_ge_add_one_self) hence "(1 + r x) powr w x \ exp (r x) powr w x" using nonneg1[of x] nonneg2[of x] x \A > 0\ by (intro powr_mono2) (auto simp: r_def field_simps) also have "\ = exp (w x * r x)" by (simp add: powr_def) finally show "(1 + r x) powr w x \ exp (w x * r x)" . qed next show "(\x\X. (1 + r x) powr w x) \ (\x\X. exp (w x * r x))" proof - have "(\x\X. (1 + r x) powr w x) = (\x\X. a x powr w x) / A" by (fact lhs) also have "\ = 1" using \A \ 0\ by (simp add: eq A_def) also have "\ = (\x\X. exp (w x * r x))" by (simp add: rhs) finally show ?thesis by simp qed qed (use x \finite X\ in auto) also have "exp (w x * r x) = exp (r x) powr w x" by (simp add: powr_def) finally have "1 + r x = exp (r x)" using x pos2[of x] r_ge[of x] by (subst (asm) powr_left_real_eq_iff) auto hence "r x = 0" using exp_real_eq_one_plus_iff[of "r x"] by auto hence "a x = A" using \A > 0\ by (simp add: r_def field_simps) thus ?thesis by (simp add: ) qed thus "\x\X. \y\X. a x = a y" by auto qed text \ We can now show the full theorem and relax the positivity condition on the $a_i$ to non-negativity. This is possible because if some $a_i$ is zero and the two means coincide, then the product is obviously 0, but the sum can only be 0 if \<^term>\all\ the $a_i$ are 0. \ theorem weighted_arithmetic_geometric_mean_eq_iff: fixes a w :: "'a \ real" assumes "finite X" assumes nonneg1: "\x. x \ X \ a x \ 0" assumes pos2: "\x. x \ X \ w x > 0" assumes sum_weights: "(\x\X. w x) = 1" shows "(\x\X. a x powr w x) = (\x\X. w x * a x) \ X \ {} \ (\x\X. \y\X. a x = a y)" proof assume *: "X \ {} \ (\x\X. \y\X. a x = a y)" from * have "X \ {}" by blast from * obtain c where c: "\x. x \ X \ a x = c" "c \ 0" proof (cases "X = {}") case False then obtain x where "x \ X" by blast thus ?thesis using * that[of "a x"] nonneg1[of x] by metis next case True thus ?thesis using that[of 1] by auto qed have "(\x\X. a x powr w x) = (\x\X. c powr w x)" by (simp add: c) also have "\ = c" using assms c \X \ {}\ by (cases "c = 0") (auto simp: powr_sum_distrib_real_right) also have "\ = (\x\X. w x * a x)" using sum_weights by (simp add: c(1) flip: sum_distrib_left sum_distrib_right) finally show "(\x\X. a x powr w x) = (\x\X. w x * a x)" . next assume *: "(\x\X. a x powr w x) = (\x\X. w x * a x)" have "X \ {}" using * by auto moreover have "(\x\X. \y\X. a x = a y)" proof (cases "\x\X. a x = 0") case False with nonneg1 have pos1: "\x\X. a x > 0" by force thus ?thesis using weighted_arithmetic_geometric_mean_eq_iff_pos[of X a w] assms * by blast next case True hence "(\x\X. a x powr w x) = 0" using assms by auto with * have "(\x\X. w x * a x) = 0" by auto also have "?this \ (\x\X. w x * a x = 0)" using assms by (intro sum_nonneg_eq_0_iff mult_nonneg_nonneg) (auto intro: less_imp_le) finally have "(\x\X. a x = 0)" using pos2 by force thus ?thesis by auto qed ultimately show "X \ {} \ (\x\X. \y\X. a x = a y)" by blast qed text \ Again, we derive a version for the unweighted arithmetic/geometric mean. \ corollary arithmetic_geometric_mean_eq_iff: fixes a :: "'a \ real" assumes "finite X" defines "n \ card X" assumes nonneg: "\x. x \ X \ a x \ 0" shows "root n (\x\X. a x) = (\x\X. a x) / n \ (\x\X. \y\X. a x = a y)" proof (cases "X = {}") case False with assms have "n > 0" by auto have "(\x\X. a x powr (1 / n)) = (\x\X. (1 / n) * a x) \ X \ {} \ (\x\X. \y\X. a x = a y)" using assms False by (intro weighted_arithmetic_geometric_mean_eq_iff) auto also have "(\x\X. a x powr (1 / n)) = (\x\X. a x) powr (1 / n)" using nonneg by (subst powr_sum_distrib_real_left) auto also have "\ = root n (\x\X. a x)" using \n > 0\ nonneg by (subst root_powr_inverse') (auto simp: prod_nonneg) also have "(\x\X. (1 / n) * a x) = (\x\X. a x) / n" by (subst sum_distrib_left [symmetric]) auto finally show ?thesis using False by auto qed (auto simp: n_def) subsection \The Binary Version\ text \ For convenience, we also derive versions for only two numbers: \ corollary weighted_arithmetic_geometric_mean_binary: fixes w1 w2 x1 x2 :: real assumes "x1 \ 0" "x2 \ 0" "w1 \ 0" "w2 \ 0" "w1 + w2 = 1" shows "x1 powr w1 * x2 powr w2 \ w1 * x1 + w2 * x2" proof - let ?a = "\b. if b then x1 else x2" let ?w = "\b. if b then w1 else w2" from assms have "(\x\UNIV. ?a x powr ?w x) \ (\x\UNIV. ?w x * ?a x)" by (intro weighted_arithmetic_geometric_mean) (auto simp add: UNIV_bool) thus ?thesis by (simp add: UNIV_bool add_ac mult_ac) qed corollary weighted_arithmetic_geometric_mean_eq_iff_binary: fixes w1 w2 x1 x2 :: real assumes "x1 \ 0" "x2 \ 0" "w1 > 0" "w2 > 0" "w1 + w2 = 1" shows "x1 powr w1 * x2 powr w2 = w1 * x1 + w2 * x2 \ x1 = x2" proof - let ?a = "\b. if b then x1 else x2" let ?w = "\b. if b then w1 else w2" from assms have "(\x\UNIV. ?a x powr ?w x) = (\x\UNIV. ?w x * ?a x) \ (UNIV :: bool set) \ {} \ (\x\UNIV. \y\UNIV. ?a x = ?a y)" by (intro weighted_arithmetic_geometric_mean_eq_iff) (auto simp add: UNIV_bool) thus ?thesis by (auto simp: UNIV_bool add_ac mult_ac) qed corollary arithmetic_geometric_mean_binary: fixes x1 x2 :: real assumes "x1 \ 0" "x2 \ 0" shows "sqrt (x1 * x2) \ (x1 + x2) / 2" using weighted_arithmetic_geometric_mean_binary[of x1 x2 "1/2" "1/2"] assms by (simp add: powr_half_sqrt field_simps real_sqrt_mult) corollary arithmetic_geometric_mean_eq_iff_binary: fixes x1 x2 :: real assumes "x1 \ 0" "x2 \ 0" shows "sqrt (x1 * x2) = (x1 + x2) / 2 \ x1 = x2" using weighted_arithmetic_geometric_mean_eq_iff_binary[of x1 x2 "1/2" "1/2"] assms by (simp add: powr_half_sqrt field_simps real_sqrt_mult) end \ No newline at end of file