Up to index of Isabelle/HOL/HOL-Complex/Cauchy
theory CauchySchwarz(* Title: The Cauchy-Schwarz Inequality ID: $Id: CauchySchwarz.thy,v 1.5 2007/06/13 20:14:38 makarius Exp $ Author: Benjamin Porter <Benjamin.Porter at gmail.com>, 2006 Maintainer: Benjamin Porter <Benjamin.Porter at gmail.com> *) header {* The Cauchy-Schwarz Inequality *} theory CauchySchwarz imports Complex_Main begin (*<*) (* Some basic results that don't need to be in the final doc ..*) lemmas real_sq = power2_eq_square [where 'a = real, symmetric] lemmas real_mult_wkorder = mult_nonneg_nonneg [where 'a = real] lemma real_add_mult_distrib2: fixes x::real shows "x*(y+z) = x*y + x*z" proof - have "x*(y+z) = (y+z)*x" by simp also have "… = y*x + z*x" by (rule real_add_mult_distrib) also have "… = x*y + x*z" by simp finally show ?thesis . qed lemma real_add_mult_distrib_ex: fixes x::real shows "(x+y)*(z+w) = x*z + y*z + x*w + y*w" proof - have "(x+y)*(z+w) = x*(z+w) + y*(z+w)" by (rule real_add_mult_distrib) also have "… = x*z + x*w + y*z + y*w" by (simp add: real_add_mult_distrib2) finally show ?thesis by simp qed lemma real_sub_mult_distrib_ex: fixes x::real shows "(x-y)*(z-w) = x*z - y*z - x*w + y*w" proof - have zw: "(z-w) = (z+ -w)" by simp have "(x-y)*(z-w) = (x + -y)*(z-w)" by simp also have "… = x*(z-w) + -y*(z-w)" by (rule real_add_mult_distrib) also from zw have "… = x*(z+ -w) + -y*(z+ -w)" apply - apply (erule subst) by simp also have "… = x*z + x*-w + -y*z + -y*-w" by (simp add: real_add_mult_distrib2) finally show ?thesis by simp qed lemma setsum_product_expand: fixes f::"nat => real" shows "(∑j∈{1..n}. f j)*(∑j∈{1..n}. g j) = (∑k∈{1..n}. (∑j∈{1..n}. f k * g j))" by (simp add: setsum_right_distrib setsum_left_distrib) (rule setsum_commute) lemmas real_sq_exp = power_mult_distrib [where 'a = real and ?n = 2] lemma real_diff_exp: fixes x::real shows "(x - y)^2 = x^2 + y^2 - 2*x*y" proof - have "(x - y)^2 = (x-y)*(x-y)" by (simp only: real_sq) also from real_sub_mult_distrib_ex have "… = x*x - x*y - y*x + y*y" by simp finally show ?thesis by (auto simp add: real_sq) qed lemma double_sum_equiv: fixes f::"nat => real" shows "(∑k∈{1..n}. (∑j∈{1..n}. f k * g j)) = (∑k∈{1..n}. (∑j∈{1..n}. f j * g k))" by (rule setsum_commute) (*>*) section {* Abstract *} text {* The following document presents a formalised proof of the Cauchy-Schwarz Inequality for the specific case of $R^n$. The system used is Isabelle/Isar. {\em Theorem:} Take $V$ to be some vector space possessing a norm and inner product, then for all $a,b \in V$ the following inequality holds: @{text "¦a·b¦ ≤ \<parallel>a\<parallel>*\<parallel>b\<parallel>"}. Specifically, in the Real case, the norm is the Euclidean length and the inner product is the standard dot product. *} section {* Formal Proof *} subsection {* Vector, Dot and Norm definitions. *} text {* This section presents definitions for a real vector type, a dot product function and a norm function. *} subsubsection {* Vector *} text {* We now define a vector type to be a tuple of (function, length). Where the function is of type @{typ "nat=>real"}. We also define some accessor functions and appropriate notation. *} types vector = "(nat=>real) * nat"; definition ith :: "vector => nat => real" ("((_)_)" [80,100] 100) where "ith v i = fst v i" definition vlen :: "vector => nat" where "vlen v = snd v" text {* Now to access the second element of some vector $v$ the syntax is $v_2$. *} subsubsection {* Dot and Norm *} text {* We now define the dot product and norm operations. *} definition dot :: "vector => vector => real" (infixr "·" 60) where "dot a b = (∑j∈{1..(vlen a)}. aj*bj)" definition norm :: "vector => real" ("\<parallel>_\<parallel>" 100) where "norm v = sqrt (∑j∈{1..(vlen v)}. vj^2)" notation (HTML output) "norm" ("||_||" 100) text {* Another definition of the norm is @{term "\<parallel>v\<parallel> = sqrt (v·v)"}. We show that our definition leads to this one. *} lemma norm_dot: "\<parallel>v\<parallel> = sqrt (v·v)" proof - have "sqrt (v·v) = sqrt (∑j∈{1..(vlen v)}. vj*vj)" unfolding dot_def by simp also with real_sq have "… = sqrt (∑j∈{1..(vlen v)}. vj^2)" by simp also have "… = \<parallel>v\<parallel>" unfolding norm_def by simp finally show ?thesis .. qed text {* A further important property is that the norm is never negative. *} lemma norm_pos: "\<parallel>v\<parallel> ≥ 0" proof - have "∀j. vj^2 ≥ 0" unfolding ith_def by auto hence "∀j∈{1..(vlen v)}. vj^2 ≥ 0" by simp with setsum_nonneg have "(∑j∈{1..(vlen v)}. vj^2) ≥ 0" . with real_sqrt_ge_zero have "sqrt (∑j∈{1..(vlen v)}. vj^2) ≥ 0" . thus ?thesis unfolding norm_def . qed text {* We now prove an intermediary lemma regarding double summation. *} lemma double_sum_aux: fixes f::"nat => real" shows "(∑k∈{1..n}. (∑j∈{1..n}. f k * g j)) = (∑k∈{1..n}. (∑j∈{1..n}. (f k * g j + f j * g k) / 2))" proof - have "2 * (∑k∈{1..n}. (∑j∈{1..n}. f k * g j)) = (∑k∈{1..n}. (∑j∈{1..n}. f k * g j)) + (∑k∈{1..n}. (∑j∈{1..n}. f k * g j))" by simp also have "… = (∑k∈{1..n}. (∑j∈{1..n}. f k * g j)) + (∑k∈{1..n}. (∑j∈{1..n}. f j * g k))" by (simp only: double_sum_equiv) also have "… = (∑k∈{1..n}. (∑j∈{1..n}. f k * g j + f j * g k))" by (auto simp add: setsum_addf) finally have "2 * (∑k∈{1..n}. (∑j∈{1..n}. f k * g j)) = (∑k∈{1..n}. (∑j∈{1..n}. f k * g j + f j * g k))" . hence "(∑k∈{1..n}. (∑j∈{1..n}. f k * g j)) = (∑k∈{1..n}. (∑j∈{1..n}. (f k * g j + f j * g k)))*(1/2)" by auto also have "… = (∑k∈{1..n}. (∑j∈{1..n}. (f k * g j + f j * g k)*(1/2)))" by (simp add: setsum_right_distrib real_mult_commute) finally show ?thesis by (auto simp add: inverse_eq_divide) qed text {* The final theorem can now be proven. It is a simple forward proof that uses properties of double summation and the preceding lemma. *} theorem CauchySchwarzReal: fixes x::vector assumes "vlen x = vlen y" shows "¦x·y¦ ≤ \<parallel>x\<parallel>*\<parallel>y\<parallel>" proof - have "0 ≤ ¦x·y¦" by simp moreover have "0 ≤ \<parallel>x\<parallel>*\<parallel>y\<parallel>" by (auto simp add: norm_pos intro: mult_nonneg_nonneg) moreover have "¦x·y¦^2 ≤ (\<parallel>x\<parallel>*\<parallel>y\<parallel>)^2" proof - txt {* We can rewrite the goal in the following form ...*} have "(\<parallel>x\<parallel>*\<parallel>y\<parallel>)^2 - ¦x·y¦^2 ≥ 0" proof - obtain n where nx: "n = vlen x" by simp with `vlen x = vlen y` have ny: "n = vlen y" by simp { txt {* Some preliminary simplification rules. *} have "∀j∈{1..n}. xj^2 ≥ 0" by simp hence "(∑j∈{1..n}. xj^2) ≥ 0" by (rule setsum_nonneg) hence xp: "(sqrt (∑j∈{1..n}. xj^2))^2 = (∑j∈{1..n}. xj^2)" by (rule real_sqrt_pow2) have "∀j∈{1..n}. yj^2 ≥ 0" by simp hence "(∑j∈{1..n}. yj^2) ≥ 0" by (rule setsum_nonneg) hence yp: "(sqrt (∑j∈{1..n}. yj^2))^2 = (∑j∈{1..n}. yj^2)" by (rule real_sqrt_pow2) txt {* The main result of this section is that @{text "(\<parallel>x\<parallel>*\<parallel>y\<parallel>)^2"} can be written as a double sum. *} have "(\<parallel>x\<parallel>*\<parallel>y\<parallel>)^2 = \<parallel>x\<parallel>^2 * \<parallel>y\<parallel>^2" by (simp add: real_sq_exp) also from nx ny have "… = (sqrt (∑j∈{1..n}. xj^2))^2 * (sqrt (∑j∈{1..n}. yj^2))^2" unfolding norm_def by auto also from xp yp have "… = (∑j∈{1..n}. xj^2)*(∑j∈{1..n}. yj^2)" by simp also from setsum_product_expand have "… = (∑k∈{1..n}. (∑j∈{1..n}. (xk^2)*(yj^2)))" . finally have "(\<parallel>x\<parallel>*\<parallel>y\<parallel>)^2 = (∑k∈{1..n}. (∑j∈{1..n}. (xk^2)*(yj^2)))" . } moreover { txt {* We also show that @{text "¦x·y¦^2"} can be expressed as a double sum.*} have "¦x·y¦^2 = (x·y)^2" by simp also from nx have "… = (∑j∈{1..n}. xj*yj)^2" unfolding dot_def by simp also from real_sq have "… = (∑j∈{1..n}. xj*yj)*(∑j∈{1..n}. xj*yj)" by simp also from setsum_product_expand have "… = (∑k∈{1..n}. (∑j∈{1..n}. (xk*yk)*(xj*yj)))" by simp finally have "¦x·y¦^2 = (∑k∈{1..n}. (∑j∈{1..n}. (xk*yk)*(xj*yj)))" . } txt {* We now manipulate the double sum expressions to get the required inequality. *} ultimately have "(\<parallel>x\<parallel>*\<parallel>y\<parallel>)^2 - ¦x·y¦^2 = (∑k∈{1..n}. (∑j∈{1..n}. (xk^2)*(yj^2))) - (∑k∈{1..n}. (∑j∈{1..n}. (xk*yk)*(xj*yj)))" by simp also have "… = (∑k∈{1..n}. (∑j∈{1..n}. ((xk^2*yj^2) + (xj^2*yk^2))/2)) - (∑k∈{1..n}. (∑j∈{1..n}. (xk*yk)*(xj*yj)))" by (simp only: double_sum_aux) also have "… = (∑k∈{1..n}. (∑j∈{1..n}. ((xk^2*yj^2) + (xj^2*yk^2))/2 - (xk*yk)*(xj*yj)))" by (auto simp add: setsum_subtractf) also have "… = (∑k∈{1..n}. (∑j∈{1..n}. (inverse 2)*2* (((xk^2*yj^2) + (xj^2*yk^2))*(1/2) - (xk*yk)*(xj*yj))))" by auto also have "… = (∑k∈{1..n}. (∑j∈{1..n}. (inverse 2)*(2* (((xk^2*yj^2) + (xj^2*yk^2))*(1/2) - (xk*yk)*(xj*yj)))))" by (simp only: real_mult_assoc) also have "… = (∑k∈{1..n}. (∑j∈{1..n}. (inverse 2)* ((((xk^2*yj^2) + (xj^2*yk^2))*2*(inverse 2) - 2*(xk*yk)*(xj*yj)))))" by (auto simp add: real_add_mult_distrib real_mult_assoc mult_ac) also have "… = (∑k∈{1..n}. (∑j∈{1..n}. (inverse 2)* ((((xk^2*yj^2) + (xj^2*yk^2)) - 2*(xk*yk)*(xj*yj)))))" by (simp only: real_mult_assoc, simp) also have "… = (inverse 2)*(∑k∈{1..n}. (∑j∈{1..n}. (((xk^2*yj^2) + (xj^2*yk^2)) - 2*(xk*yk)*(xj*yj))))" by (simp only: setsum_right_distrib) also have "… = (inverse 2)*(∑k∈{1..n}. (∑j∈{1..n}. (xk*yj - xj*yk)^2))" by (simp only: real_diff_exp real_sq_exp, auto simp add: mult_ac) also have "… ≥ 0" proof - { fix k::nat have "∀j∈{1..n}. (xk*yj - xj*yk)^2 ≥ 0" by simp hence "(∑j∈{1..n}. (xk*yj - xj*yk)^2) ≥ 0" by (rule setsum_nonneg) } hence "∀k∈{1..n}. (∑j∈{1..n}. (xk*yj - xj*yk)^2) ≥ 0" by simp hence "(∑k∈{1..n}. (∑j∈{1..n}. (xk*yj - xj*yk)^2)) ≥ 0" by (rule setsum_nonneg) thus ?thesis by simp qed finally show "(\<parallel>x\<parallel>*\<parallel>y\<parallel>)^2 - ¦x·y¦^2 ≥ 0" . qed thus ?thesis by simp qed ultimately show ?thesis by (rule real_sq_order) qed end
lemma real_sq:
a * a = a ^ 2
lemma real_mult_wkorder:
[| 0 ≤ a; 0 ≤ b |] ==> 0 ≤ a * b
lemma real_add_mult_distrib2:
x * (y + z) = x * y + x * z
lemma real_add_mult_distrib_ex:
(x + y) * (z + w) = x * z + y * z + x * w + y * w
lemma real_sub_mult_distrib_ex:
(x - y) * (z - w) = x * z - y * z - x * w + y * w
lemma setsum_product_expand:
setsum f {1..n} * setsum g {1..n} = (∑k = 1..n. ∑j = 1..n. f k * g j)
lemma real_sq_exp:
(a * b) ^ 2 = a ^ 2 * b ^ 2
lemma real_diff_exp:
(x - y) ^ 2 = x ^ 2 + y ^ 2 - 2 * x * y
lemma double_sum_equiv:
(∑k = 1..n. ∑j = 1..n. f k * g j) = (∑k = 1..n. ∑j = 1..n. f j * g k)
lemma norm_dot:
||v|| = sqrt (v · v)
lemma norm_pos:
0 ≤ ||v||
lemma double_sum_aux:
(∑k = 1..n. ∑j = 1..n. f k * g j) =
(∑k = 1..n. ∑j = 1..n. (f k * g j + f j * g k) / 2)
theorem CauchySchwarzReal:
vlen x = vlen y ==> ¦x · y¦ ≤ ||x|| * ||y||