(* Title: HOL/Analysis/Linear_Algebra.thy Author: Amine Chaieb, University of Cambridge *)
section‹Elementary Linear Algebra on Euclidean Spaces›
theory Linear_Algebra imports
Euclidean_Space "HOL-Library.Infinite_Set" begin
lemma linear_simps: assumes"bounded_linear f" shows "f (a + b) = f a + f b" "f (a - b) = f a - f b" "f 0 = 0" "f (- a) = - f a" "f (s *🪙R v) = s *🪙R (f v)" proof - interpret f: bounded_linear f by fact show"f (a + b) = f a + f b"by (rule f.add) show"f (a - b) = f a - f b"by (rule f.diff) show"f 0 = 0"by (rule f.zero) show"f (- a) = - f a"by (rule f.neg) show"f (s *🪙R v) = s *🪙R (f v)"by (rule f.scale) qed
lemma finite_Atleast_Atmost_nat[simp]: "finite {f x |x. x ∈ (UNIV::'a::finite set)}" using finite finite_image_set by blast
lemma substdbasis_expansion_unique: includes inner_syntax assumes d: "d ⊆ Basis" shows"(∑i∈d. f i *🪙R i) = (x::'a::euclidean_space) ⟷ (∀i∈Basis. (i ∈ d ⟶ f i = x ∙ i) ∧ (i ∉ d ⟶ x ∙ i = 0))" proof - have *: "∧x a b P. x * (if P then a else b) = (if P then x * a else x * b)" by auto have **: "finite d" by (auto intro: finite_subset[OF assms]) have ***: "∧i. i ∈ Basis ==> (∑i∈d. f i *🪙R i) ∙ i = (∑x∈d. if x = i then f x else 0)" using d by (auto intro!: sum.cong simp: inner_Basis inner_sum_left) show ?thesis unfolding euclidean_eq_iff[where 'a='a] by (auto simp: sum.delta[OF **] ***) qed
lemma subset_translation_eq [simp]: fixes a :: "'a::real_vector"shows"(+) a ` s ⊆ (+) a ` t ⟷ s ⊆ t" by auto
lemma translate_inj_on: fixes A :: "'a::ab_group_add set" shows"inj_on (λx. a + x) A" unfolding inj_on_def by auto
lemma translation_assoc: fixes a b :: "'a::ab_group_add" shows"(λx. b + x) ` ((λx. a + x) ` S) = (λx. (a + b) + x) ` S" by auto
lemma translation_invert: fixes a :: "'a::ab_group_add" assumes"(λx. a + x) ` A = (λx. a + x) ` B" shows"A = B" using assms translation_assoc by fastforce
lemma translation_galois: fixes a :: "'a::ab_group_add" shows"T = ((λx. a + x) ` S) ⟷ S = ((λx. (- a) + x) ` T)" by (metis add.right_inverse group_cancel.rule0 translation_invert translation_assoc)
lemma translation_inverse_subset: assumes"((λx. - a + x) ` V) ≤ (S :: 'n::ab_group_add set)" shows"V ≤ ((λx. a + x) ` S)" by (metis assms subset_image_iff translation_galois)
subsection🍋‹tag unimportant›‹More interesting properties of the norm›
unbundle inner_syntax
text‹Equality of vectors in terms of 🍋‹(∙)›products.›
lemma linear_componentwise: fixes f:: "'a::euclidean_space ==> 'b::real_inner" assumes lf: "linear f" shows"(f x) ∙ j = (∑i∈Basis. (x∙i) * (f i∙j))" (is"?lhs = ?rhs") proof - interpret linear f by fact have"?rhs = (∑i∈Basis. (x∙i) *🪙R (f i))∙j" by (simp add: inner_sum_left) thenshow ?thesis by (simp add: euclidean_representation sum[symmetric] scale[symmetric]) qed
lemma vector_eq: "x = y ⟷ x ∙ x = x ∙ y ∧ y ∙ y = x ∙ x" by (metis (no_types, opaque_lifting) inner_commute inner_diff_right inner_eq_zero_iff right_minus_eq)
lemma norm_triangle_half_r: "norm (y - x1) < e/2 ==> norm (y - x2) < e/2 ==> norm (x1 - x2) < e" using dist_triangle_half_r unfolding dist_norm[symmetric] by auto
lemma abs_triangle_half_l: fixes y :: "'a::linordered_field" assumes"abs (x - y) < e/2"and"abs (x' - y) < e/2" shows"abs (x - x') < e" using assms by linarith
lemma sum_clauses: shows"sum f {} = 0" and"finite S ==> sum f (insert x S) = (if x ∈ S then sum f S else f x + sum f S)" by (auto simp add: insert_absorb)
lemma vector_eq_ldot: "(∀x. x ∙ y = x ∙ z) ⟷ y = z"and vector_eq_rdot: "(∀z. x ∙ z = y ∙ z) ⟷ x = y" by (metis inner_commute vector_eq)+
subsection‹Substandard Basis›
lemma ex_card: assumes"n ≤ card A" shows"∃S⊆A. card S = n" by (meson assms obtain_subset_with_card_n)
lemma subspace_substandard: "subspace {x::'a::euclidean_space. (∀i∈Basis. P i ⟶ x∙i = 0)}" by (auto simp: subspace_def inner_add_left)
lemma dim_substandard: assumes d: "d ⊆ Basis" shows"dim {x::'a::euclidean_space. ∀i∈Basis. i ∉ d ⟶ x∙i = 0} = card d" (is"dim ?A = _") proof (rule dim_unique) from d show"d ⊆ ?A" by (auto simp: inner_Basis) from d show"independent d" by (rule independent_mono [OF independent_Basis]) have"x ∈ span d"if"∀i∈Basis. i ∉ d ⟶ x ∙ i = 0"for x proof - have"finite d" by (rule finite_subset [OF d finite_Basis]) thenhave"(∑i∈d. (x ∙ i) *🪙R i) ∈ span d" by (simp add: span_sum span_clauses) alsohave"(∑i∈d. (x ∙ i) *🪙R i) = (∑i∈Basis. (x ∙ i) *🪙R i)" by (rule sum.mono_neutral_cong_left [OF finite_Basis d]) (auto simp: that) finallyshow"x ∈ span d" by (simp only: euclidean_representation) qed thenshow"?A ⊆ span d"by auto qed simp
subsection‹Orthogonality›
definition🍋‹tag important› (in real_inner) "orthogonal x y ⟷ x ∙ y = 0"
context real_inner begin
lemma orthogonal_self: "orthogonal x x ⟷ x = 0" by (simp add: orthogonal_def)
lemma orthogonal_clauses: "orthogonal a 0" "orthogonal a x ==> orthogonal a (c *🪙R x)" "orthogonal a x ==> orthogonal a (- x)" "orthogonal a x ==> orthogonal a y ==> orthogonal a (x + y)" "orthogonal a x ==> orthogonal a y ==> orthogonal a (x - y)" "orthogonal 0 a" "orthogonal x a ==> orthogonal (c *🪙R x) a" "orthogonal x a ==> orthogonal (- x) a" "orthogonal x a ==> orthogonal y a ==> orthogonal (x + y) a" "orthogonal x a ==> orthogonal y a ==> orthogonal (x - y) a" unfolding orthogonal_def inner_add inner_diff by auto
end
lemma orthogonal_commute: "orthogonal x y ⟷ orthogonal y x" by (simp add: orthogonal_def inner_commute)
lemma pairwise_ortho_scaleR: "pairwise (λi j. orthogonal (f i) (g j)) B ==> pairwise (λi j. orthogonal (a i *🪙R f i) (a j *🪙R g j)) B" by (auto simp: pairwise_def orthogonal_clauses)
lemma orthogonal_rvsum: "[finite s; ∧y. y ∈ s ==> orthogonal x (f y)]==> orthogonal x (sum f s)" by (induction s rule: finite_induct) (auto simp: orthogonal_clauses)
lemma orthogonal_lvsum: "[finite s; ∧x. x ∈ s ==> orthogonal (f x) y]==> orthogonal (sum f s) y" by (induction s rule: finite_induct) (auto simp: orthogonal_clauses)
lemma norm_add_Pythagorean: assumes"orthogonal a b" shows"(norm (a + b))🪙2 = (norm a)🪙2 + (norm b)🪙2" proof - from assms have"(a - (0 - b)) ∙ (a - (0 - b)) = a ∙ a - (0 - b ∙ b)" by (simp add: algebra_simps orthogonal_def inner_commute) thenshow ?thesis by (simp add: power2_norm_eq_inner) qed
lemma norm_sum_Pythagorean: assumes"finite I""pairwise (λi j. orthogonal (f i) (f j)) I" shows"(norm (sum f I))🪙2 = (∑i∈I. (norm (f i))🪙2)" using assms proof (induction I rule: finite_induct) case empty thenshow ?caseby simp next case (insert x I) thenhave"orthogonal (f x) (sum f I)" by (metis pairwise_insert orthogonal_rvsum) with insert show ?case by (simp add: pairwise_insert norm_add_Pythagorean) qed
subsection‹Orthogonality of a transformation›
definition🍋‹tag important›"orthogonal_transformation f ⟷ linear f ∧ (∀v w. f v∙ f w = v ∙ w)"
lemma🍋‹tag unimportant› orthogonal_transformation: "orthogonal_transformation f ⟷ linear f ∧ (∀v. norm (f v) = norm v)" by (smt (verit, ccfv_threshold) dot_norm linear_add norm_eq_sqrt_inner orthogonal_transformation_def)
lemma🍋‹tag unimportant› orthogonal_transformation_scaleR: "orthogonal_transformation f ==> f (c *🪙R v) = c *🪙R f v" by (simp add: linear_iff orthogonal_transformation_def)
lemma🍋‹tag unimportant› orthogonal_transformation_linear: "orthogonal_transformation f ==> linear f" by (simp add: orthogonal_transformation_def)
lemma🍋‹tag unimportant› orthogonal_transformation_inj: "orthogonal_transformation f ==> inj f" unfolding orthogonal_transformation_def inj_on_def by (metis vector_eq)
lemma🍋‹tag unimportant› orthogonal_transformation_surj: "orthogonal_transformation f ==> surj f" for f :: "'a::euclidean_space ==> 'a::euclidean_space" by (simp add: linear_injective_imp_surjective orthogonal_transformation_inj orthogonal_transformation_linear)
lemma🍋‹tag unimportant› orthogonal_transformation_bij: "orthogonal_transformation f ==> bij f" for f :: "'a::euclidean_space ==> 'a::euclidean_space" by (simp add: bij_def orthogonal_transformation_inj orthogonal_transformation_surj)
lemma🍋‹tag unimportant› orthogonal_transformation_inv: "orthogonal_transformation f ==> orthogonal_transformation (inv f)" for f :: "'a::euclidean_space ==> 'a::euclidean_space" by (metis (no_types, opaque_lifting) bijection.inv_right bijection_def inj_linear_imp_inv_linear orthogonal_transformation orthogonal_transformation_bij orthogonal_transformation_inj)
lemma🍋‹tag unimportant› orthogonal_transformation_norm: "orthogonal_transformation f ==> norm (f x) = norm x" by (metis orthogonal_transformation)
subsection‹Bilinear functions›
definition🍋‹tag important›
bilinear :: "('a::real_vector ==> 'b::real_vector ==> 'c::real_vector) ==> bool"where "bilinear f ⟷ (∀x. linear (λy. f x y)) ∧ (∀y. linear (λx. f x y))"
lemma bilinear_ladd: "bilinear h ==> h (x + y) z = h x z + h y z" by (simp add: bilinear_def linear_iff)
lemma bilinear_radd: "bilinear h ==> h x (y + z) = h x y + h x z" by (simp add: bilinear_def linear_iff)
lemma bilinear_lmul: "bilinear h ==> h (c *🪙R x) y = c *🪙R h x y" by (simp add: bilinear_def linear_iff)
lemma bilinear_rmul: "bilinear h ==> h x (c *🪙R y) = c *🪙R h x y" by (simp add: bilinear_def linear_iff)
lemma bilinear_lneg: "bilinear h ==> h (- x) y = - h x y" by (drule bilinear_lmul [of _ "- 1"]) simp
lemma bilinear_rneg: "bilinear h ==> h x (- y) = - h x y" by (drule bilinear_rmul [of _ _ "- 1"]) simp
lemma (in ab_group_add) eq_add_iff: "x = x + y ⟷ y = 0" using add_left_imp_eq[of x y 0] by auto
lemma bilinear_lzero: assumes"bilinear h" shows"h 0 x = 0" using bilinear_ladd [OF assms, of 0 0 x] by (simp add: eq_add_iff field_simps)
lemma bilinear_rzero: assumes"bilinear h" shows"h x 0 = 0" using bilinear_radd [OF assms, of x 0 0 ] by (simp add: eq_add_iff field_simps)
lemma bilinear_lsub: "bilinear h ==> h (x - y) z = h x z - h y z" using bilinear_ladd [of h x "- y"] by (simp add: bilinear_lneg)
lemma bilinear_rsub: "bilinear h ==> h z (x - y) = h z x - h z y" using bilinear_radd [of h _ x "- y"] by (simp add: bilinear_rneg)
lemma bilinear_sum: assumes"bilinear h" shows"h (sum f S) (sum g T) = sum (λ(i,j). h (f i) (g j)) (S × T) " proof - interpret l: linear "λx. h x y"for y using assms by (simp add: bilinear_def) interpret r: linear "λy. h x y"for x using assms by (simp add: bilinear_def) have"h (sum f S) (sum g T) = sum (λx. h (f x) (sum g T)) S" by (simp add: l.sum) alsohave"… = sum (λx. sum (λy. h (f x) (g y)) T) S" by (rule sum.cong) (simp_all add: r.sum) finallyshow ?thesis unfolding sum.cartesian_product . qed
subsection‹Adjoints›
definition🍋‹tag important› adjoint :: "(('a::real_inner) ==> ('b::real_inner)) ==> 'b ==> 'a"where "adjoint f = (SOME f'. ∀x y. f x ∙ y = x ∙ f' y)"
lemma adjoint_unique: assumes"∀x y. inner (f x) y = inner x (g y)" shows"adjoint f = g" unfolding adjoint_def proof (rule some_equality) show"∀x y. inner (f x) y = inner x (g y)" by (rule assms) next fix h assume"∀x y. inner (f x) y = inner x (h y)" thenshow"h = g" by (metis assms ext vector_eq_ldot) qed
lemma adjoint_works: fixes f :: "'n::euclidean_space ==> 'm::euclidean_space" assumes lf: "linear f" shows"x ∙ adjoint f y = f x ∙ y" proof - interpret linear f by fact have"∀y. ∃w. ∀x. f x ∙ y = x ∙ w" proof (intro allI exI) fix y :: "'m"and x let ?w = "(∑i∈Basis. (f i ∙ y) *🪙R i) :: 'n" have"f x ∙ y = f (∑i∈Basis. (x ∙ i) *🪙R i) ∙ y" by (simp add: euclidean_representation) alsohave"… = (∑i∈Basis. (x ∙ i) *🪙R f i) ∙ y" by (simp add: sum scale) finallyshow"f x ∙ y = x ∙ ?w" by (simp add: inner_sum_left inner_sum_right mult.commute) qed thenshow ?thesis unfolding adjoint_def choice_iff by (intro someI2_ex[where Q="λf'. x ∙ f' y = f x ∙ y"]) auto qed
lemma adjoint_clauses: fixes f :: "'n::euclidean_space ==> 'm::euclidean_space" assumes lf: "linear f" shows"x ∙ adjoint f y = f x ∙ y" and"adjoint f y ∙ x = y ∙ f x" by (simp_all add: adjoint_works[OF lf] inner_commute)
lemma representation_euclidean_space: "representation Basis x = (λb. if b ∈ Basis then inner x b else 0)" proof (rule representation_eqI) have"(∑b | (if b ∈ Basis then inner x b else 0) ≠ 0. (if b ∈ Basis then inner x b else 0) *🪙R b) = (∑b∈Basis. inner x b *🪙R b)" by (intro sum.mono_neutral_cong_left) auto alsohave"… = x" by (simp add: euclidean_representation) finallyshow"(∑b | (if b ∈ Basis then inner x b else 0) ≠ 0. (if b ∈ Basis then inner x b else 0) *🪙R b) = x" . qed (insert independent_Basis span_Basis, auto split: if_splits)
subsection🍋‹tag unimportant›‹Linearity and Bilinearity continued›
lemma linear_bounded: fixes f :: "'a::euclidean_space ==> 'b::real_normed_vector" assumes lf: "linear f" shows"∃B. ∀x. norm (f x) ≤ B * norm x" proof interpret linear f by fact let ?B = "∑b∈Basis. norm (f b)" show"∀x. norm (f x) ≤ ?B * norm x" proof fix x :: 'a let ?g = "λb. (x ∙ b) *🪙R f b" have"norm (f x) = norm (f (∑b∈Basis. (x ∙ b) *🪙R b))" unfolding euclidean_representation .. alsohave"… = norm (sum ?g Basis)" by (simp add: sum scale) finallyhave th0: "norm (f x) = norm (sum ?g Basis)" . have th: "norm (?g i) ≤ norm (f i) * norm x"if"i ∈ Basis"for i proof - from Basis_le_norm[OF that, of x] show"norm (?g i) ≤ norm (f i) * norm x" unfolding norm_scaleR by (metis mult.commute mult_left_mono norm_ge_zero) qed from sum_norm_le[of _ ?g, OF th] show"norm (f x) ≤ ?B * norm x" by (simp add: sum_distrib_right th0) qed qed
lemma linear_conv_bounded_linear: fixes f :: "'a::euclidean_space ==> 'b::real_normed_vector" shows"linear f ⟷ bounded_linear f" by (metis mult.commute bounded_linear_axioms.intro bounded_linear_def linear_bounded)
lemma linear_bounded_pos: fixes f :: "'a::euclidean_space ==> 'b::real_normed_vector" assumes lf: "linear f" obtains B where"B > 0""∧x. norm (f x) ≤ B * norm x" by (metis bounded_linear.pos_bounded lf linear_linear mult.commute)
lemma linear_invertible_bounded_below_pos: fixes f :: "'a::real_normed_vector ==> 'b::euclidean_space" assumes"linear f""linear g"and gf: "g ∘ f = id" obtains B where"B > 0""∧x. B * norm x ≤ norm(f x)" proof - obtain B where"B > 0"and B: "∧x. norm (g x) ≤ B * norm x" using linear_bounded_pos [OF ‹linear g›] by blast show thesis proof show"0 < 1/B" by (simp add: ‹B > 0›) show"1/B * norm x ≤ norm (f x)"for x by (smt (verit, ccfv_SIG) B ‹0 🚫› gf comp_apply divide_inverse id_apply inverse_eq_divide
less_divide_eq mult.commute) qed qed
lemma linear_inj_bounded_below_pos: fixes f :: "'a::real_normed_vector ==> 'b::euclidean_space" assumes"linear f""inj f" obtains B where"B > 0""∧x. B * norm x ≤ norm(f x)" using linear_injective_left_inverse [OF assms]
linear_invertible_bounded_below_pos assms by blast
lemma bounded_linearI': fixes f ::"'a::euclidean_space ==> 'b::real_normed_vector" assumes"∧x y. f (x + y) = f x + f y" and"∧c x. f (c *🪙R x) = c *🪙R f x" shows"bounded_linear f" using assms linearI linear_conv_bounded_linear by blast
lemma bilinear_bounded: fixes h :: "'m::euclidean_space ==> 'n::euclidean_space ==> 'k::real_normed_vector" assumes bh: "bilinear h" shows"∃B. ∀x y. norm (h x y) ≤ B * norm x * norm y" proof (clarify intro!: exI[of _ "∑i∈Basis. ∑j∈Basis. norm (h i j)"]) fix x :: 'm fix y :: 'n have"norm (h x y) = norm (h (sum (λi. (x ∙ i) *🪙R i) Basis) (sum (λi. (y ∙ i) *🪙R i) Basis))" by (simp add: euclidean_representation) alsohave"… = norm (sum (λ (i,j). h ((x ∙ i) *🪙R i) ((y ∙ j) *🪙R j)) (Basis × Basis))" unfolding bilinear_sum[OF bh] .. finallyhave th: "norm (h x y) = …" . have"∧i j. [i ∈ Basis; j ∈ Basis] ==>∣x ∙ i∣ * (∣y ∙ j∣ * norm (h i j)) ≤ norm x * (norm y * norm (h i j))" by (auto simp add: zero_le_mult_iff Basis_le_norm mult_mono) thenshow"norm (h x y) ≤ (∑i∈Basis. ∑j∈Basis. norm (h i j)) * norm x * norm y" unfolding sum_distrib_right th sum.cartesian_product by (clarsimp simp add: bilinear_rmul[OF bh] bilinear_lmul[OF bh]
field_simps simp del: scaleR_scaleR intro!: sum_norm_le) qed
lemma bilinear_conv_bounded_bilinear: fixes h :: "'a::euclidean_space ==> 'b::euclidean_space ==> 'c::real_normed_vector" shows"bilinear h ⟷ bounded_bilinear h" proof assume"bilinear h" show"bounded_bilinear h" proof fix x y z show"h (x + y) z = h x z + h y z" using‹bilinear h›unfolding bilinear_def linear_iff by simp next fix x y z show"h x (y + z) = h x y + h x z" using‹bilinear h›unfolding bilinear_def linear_iff by simp next show"h (scaleR r x) y = scaleR r (h x y)""h x (scaleR r y) = scaleR r (h x y)"for r x y using‹bilinear h›unfolding bilinear_def linear_iff by simp_all next have"∃B. ∀x y. norm (h x y) ≤ B * norm x * norm y" using‹bilinear h›by (rule bilinear_bounded) thenshow"∃K. ∀x y. norm (h x y) ≤ norm x * norm y * K" by (simp add: ac_simps) qed next assume"bounded_bilinear h" theninterpret h: bounded_bilinear h . show"bilinear h" unfolding bilinear_def linear_conv_bounded_linear using h.bounded_linear_left h.bounded_linear_right by simp qed
lemma bilinear_bounded_pos: fixes h :: "'a::euclidean_space ==> 'b::euclidean_space ==> 'c::real_normed_vector" assumes bh: "bilinear h" shows"∃B > 0. ∀x y. norm (h x y) ≤ B * norm x * norm y" by (metis mult.assoc bh bilinear_conv_bounded_bilinear bounded_bilinear.pos_bounded mult.commute)
lemma bounded_linear_imp_has_derivative: "bounded_linear f ==> (f has_derivative f) net" by (auto simp add: has_derivative_def linear_diff linear_linear linear_def
dest: bounded_linear.linear)
lemma linear_imp_has_derivative: fixes f :: "'a::euclidean_space ==> 'b::real_normed_vector" shows"linear f ==> (f has_derivative f) net" by (simp add: bounded_linear_imp_has_derivative linear_conv_bounded_linear)
lemma bounded_linear_imp_differentiable: "bounded_linear f ==> f differentiable net" using bounded_linear_imp_has_derivative differentiable_def by blast
lemma linear_imp_differentiable: fixes f :: "'a::euclidean_space ==> 'b::real_normed_vector" shows"linear f ==> f differentiable net" by (metis linear_imp_has_derivative differentiable_def)
lemma bounded_linear_representation: fixes B :: "'a :: euclidean_space set" assumes"independent B""span B = UNIV" shows"bounded_linear (λv. representation B v b)" proof - have"Vector_Spaces.linear (*🪙R) (*) (λv. representation B v b)" by (rule real_vector.linear_representation) fact+ thenhave"linear (λv. representation B v b)" unfolding linear_def real_scaleR_def [abs_def] . thus ?thesis by (simp add: linear_conv_bounded_linear) qed
subsection🍋‹tag unimportant›‹We continue›
lemma independent_bound: fixes S :: "'a::euclidean_space set" shows"independent S ==> finite S ∧ card S ≤ DIM('a)" by (metis dim_subset_UNIV finiteI_independent dim_span_eq_card_independent)
corollary🍋‹tag unimportant› independent_card_le: fixes S :: "'a::euclidean_space set" assumes"independent S" shows"card S ≤ DIM('a)" using assms independent_bound by auto
lemma dependent_biggerset: fixes S :: "'a::euclidean_space set" shows"(finite S ==> card S > DIM('a)) ==> dependent S" by (metis independent_bound not_less)
text‹Picking an orthogonal replacement for a spanning set.›
lemma vector_sub_project_orthogonal: fixes b x :: "'a::euclidean_space" shows"b ∙ (x - ((b ∙ x) / (b ∙ b)) *🪙R b) = 0" unfolding inner_simps by auto
lemma pairwise_orthogonal_insert: assumes"pairwise orthogonal S" and"∧y. y ∈ S ==> orthogonal x y" shows"pairwise orthogonal (insert x S)" using assms by (auto simp: pairwise_def orthogonal_commute)
lemma basis_orthogonal: fixes B :: "'a::real_inner set" assumes fB: "finite B" shows"∃C. finite C ∧ card C ≤ card B ∧ span C = span B ∧ pairwise orthogonal C"
(is" ∃C. ?P B C") using fB proof (induct rule: finite_induct) case empty thenshow ?case using pairwise_empty by blast next case (insert a B) note fB = ‹finite B›and aB = ‹a ∉ B› from‹∃C. finite C ∧ card C ≤ card B ∧ span C = span B ∧ pairwise orthogonal C› obtain C where C: "finite C""card C ≤ card B" "span C = span B""pairwise orthogonal C"by blast let ?a = "a - sum (λx. (x ∙ a / (x ∙ x)) *🪙R x) C" let ?C = "insert ?a C" from C(1) have fC: "finite ?C" by simp have cC: "card ?C ≤ card (insert a B)" using C aB card_insert_if local.insert(1) by fastforce
{ fix x k have th0: "∧(a::'a) b c. a - (b - c) = c + (a - b)" by (simp add: field_simps) have"x - k *🪙R (a - (∑x∈C. (x ∙ a / (x ∙ x)) *🪙R x)) ∈ span C ⟷ x - k *🪙R a ∈ span C" unfolding scaleR_right_diff_distrib th0 by (intro span_add_eq span_scale span_sum span_base)
} thenhave SC: "span ?C = span (insert a B)" unfolding set_eq_iff span_breakdown_eq C(3)[symmetric] by auto
{ fix y assume yC: "y ∈ C" thenhave Cy: "C = insert y (C - {y})" by blast have fth: "finite (C - {y})" using C by simp have"y ≠ 0 ==>∀x∈C - {y}. x ∙ a * (x ∙ y) / (x ∙ x) = 0" using‹pairwise orthogonal C› by (metis Cy DiffE div_0 insertCI mult_zero_right orthogonal_def pairwise_insert) thenhave"orthogonal ?a y" unfolding orthogonal_def unfolding inner_diff inner_sum_left right_minus_eq unfolding sum.remove [OF ‹finite C›‹y ∈ C›] by (auto simp add: sum.neutral inner_commute[of y a])
} with‹pairwise orthogonal C›have CPO: "pairwise orthogonal ?C" by (rule pairwise_orthogonal_insert) from fC cC SC CPO have"?P (insert a B) ?C" by blast thenshow ?caseby blast qed
lemma orthogonal_basis_exists: fixes V :: "('a::euclidean_space) set" shows"∃B. independent B ∧ B ⊆ span V ∧ V ⊆ span B ∧ (card B = dim V) ∧ pairwise orthogonal B" proof - from basis_exists[of V] obtain B where
B: "B ⊆ V""independent B""V ⊆ span B""card B = dim V" by force from B have fB: "finite B""card B = dim V" using independent_bound by auto from basis_orthogonal[OF fB(1)] obtain C where
C: "finite C""card C ≤ card B""span C = span B""pairwise orthogonal C" by blast from C B have CSV: "C ⊆ span V" by (metis span_superset span_mono subset_trans) from span_mono[OF B(3)] C have SVC: "span V ⊆ span C" by (simp add: span_span) from C fB have"card C ≤ dim V" by simp moreoverhave"dim V ≤ card C" using span_card_ge_dim[OF CSV SVC C(1)] by simp ultimatelyhave"card C = dim V" using C(1) by simp with C B CSV show ?thesis by (metis SVC card_eq_dim dim_span) qed
text‹Low-dimensional subset is in a hyperplane (weak orthogonal complement).›
lemma span_not_UNIV_orthogonal: fixes S :: "'a::euclidean_space set" assumes sU: "span S ≠ UNIV" shows"∃a::'a. a ≠ 0 ∧ (∀x ∈ span S. a ∙ x = 0)" proof - from sU obtain a where a: "a ∉ span S" by blast from orthogonal_basis_exists obtain B where
B: "independent B""B ⊆ span S""S ⊆ span B""card B = dim S""pairwise orthogonal B" by blast from B have fB: "finite B""card B = dim S" using independent_bound by auto have sSB: "span S = span B" by (simp add: B span_eq) let ?a = "a - sum (λb. (a ∙ b / (b ∙ b)) *🪙R b) B" have"sum (λb. (a ∙ b / (b ∙ b)) *🪙R b) B ∈ span S" by (simp add: sSB span_base span_mul span_sum) with a have a0:"?a ≠ 0" by auto have"?a ∙ x = 0"if"x∈span B"for x proof (rule span_induct [OF that]) show"subspace {x. ?a ∙ x = 0}" by (auto simp add: subspace_def inner_add) next
{ fix x assume x: "x ∈ B" from x have B': "B = insert x (B - {x})" by blast have fth: "finite (B - {x})" using fB by simp have"(∑b∈B - {x}. a ∙ b * (b ∙ x) / (b ∙ b)) = 0"if"x ≠ 0" by (smt (verit) B' B(5) DiffD2 divide_eq_0_iff inner_real_def inner_zero_right insertCI orthogonal_def pairwise_insert sum.neutral) thenhave"?a ∙ x = 0" apply (subst B') using fB fth unfolding sum_clauses(2)[OF fth] by (auto simp add: inner_add_left inner_diff_left inner_sum_left)
} thenshow"?a ∙ x = 0"if"x ∈ B"for x using that by blast qed with a0 sSB show ?thesis by blast qed
lemma span_not_univ_subset_hyperplane: fixes S :: "'a::euclidean_space set" assumes SU: "span S ≠ UNIV" shows"∃ a. a ≠0 ∧ span S ⊆ {x. a ∙ x = 0}" using span_not_UNIV_orthogonal[OF SU] by auto
lemma lowdim_subset_hyperplane: fixes S :: "'a::euclidean_space set" assumes d: "dim S < DIM('a)" shows"∃a::'a. a ≠ 0 ∧ span S ⊆ {x. a ∙ x = 0}" using d dim_eq_full nless_le span_not_univ_subset_hyperplane by blast
lemma linear_eq_stdbasis: fixes f :: "'a::euclidean_space ==> _" assumes lf: "linear f" and lg: "linear g" and fg: "∧b. b ∈ Basis ==> f b = g b" shows"f = g" using linear_eq_on_span[OF lf lg, of Basis] fg by auto
text‹Similar results for bilinear functions.›
lemma bilinear_eq: assumes bf: "bilinear f" and bg: "bilinear g" and SB: "S ⊆ span B" and TC: "T ⊆ span C" and"x∈S""y∈T" and fg: "∧x y. [x ∈ B; y∈ C]==> f x y = g x y" shows"f x y = g x y" proof - let ?P = "{x. ∀y∈ span C. f x y = g x y}" from bf bg have sp: "subspace ?P" unfolding bilinear_def linear_iff subspace_def bf bg by (auto simp add: span_zero bilinear_lzero[OF bf] bilinear_lzero[OF bg]
span_add Ball_def
intro: bilinear_ladd[OF bf]) have sfg: "∧x. x ∈ B ==> subspace {a. f x a = g x a}" by (auto simp: subspace_def bf bg bilinear_rzero bilinear_radd bilinear_rmul) have"∀y∈ span C. f x y = g x y"if"x ∈ span B"for x using span_induct [OF that sp] fg sfg span_induct by blast thenshow ?thesis using SB TC assms by auto qed
lemma bilinear_eq_stdbasis: fixes f :: "'a::euclidean_space ==> 'b::euclidean_space ==> _" assumes bf: "bilinear f" and bg: "bilinear g" and fg: "∧i j. i ∈ Basis ==> j ∈ Basis ==> f i j = g i j" shows"f = g" using bilinear_eq[OF bf bg equalityD2[OF span_Basis] equalityD2[OF span_Basis]] fg by blast
lemma infnorm_set_image: fixes x :: "'a::euclidean_space" shows"{∣x ∙ i∣ |i. i ∈ Basis} = (λi. ∣x ∙ i∣) ` Basis" by blast
lemma infnorm_Max: fixes x :: "'a::euclidean_space" shows"infnorm x = Max ((λi. ∣x ∙ i∣) ` Basis)" by (simp add: infnorm_def infnorm_set_image cSup_eq_Max)
lemma infnorm_set_lemma: fixes x :: "'a::euclidean_space" shows"finite {∣x ∙ i∣ |i. i ∈ Basis}" and"{∣x ∙ i∣ |i. i ∈ Basis} ≠ {}" unfolding infnorm_set_image by auto
lemma infnorm_pos_le: fixes x :: "'a::euclidean_space" shows"0 ≤ infnorm x" by (simp add: infnorm_Max Max_ge_iff ex_in_conv)
lemma infnorm_triangle: fixes x :: "'a::euclidean_space" shows"infnorm (x + y) ≤ infnorm x + infnorm y" proof - have *: "∧a b c d :: real. ∣a∣≤ c ==>∣b∣≤ d ==>∣a + b∣≤ c + d" by simp show ?thesis by (auto simp: infnorm_Max inner_add_left intro!: *) qed
lemma infnorm_eq_0: fixes x :: "'a::euclidean_space" shows"infnorm x = 0 ⟷ x = 0" proof - have"infnorm x ≤ 0 ⟷ x = 0" unfolding infnorm_Max by (simp add: euclidean_all_zero_iff) thenshow ?thesis using infnorm_pos_le[of x] by simp qed
lemma infnorm_0: "infnorm 0 = 0" by (simp add: infnorm_eq_0)
lemma infnorm_pos_lt: "infnorm x > 0 ⟷ x ≠ 0" using infnorm_pos_le[of x] infnorm_eq_0[of x] by arith
text‹Prove that it differs only up to a bound from Euclidean norm.›
lemma infnorm_le_norm: "infnorm x ≤ norm x" by (simp add: Basis_le_norm infnorm_Max)
lemma norm_le_infnorm: fixes x :: "'a::euclidean_space" shows"norm x ≤ sqrt DIM('a) * infnorm x" unfolding norm_eq_sqrt_inner id_def proof (rule real_le_lsqrt) show"sqrt DIM('a) * infnorm x ≥ 0" by (simp add: zero_le_mult_iff infnorm_pos_le) have"x ∙ x ≤ (∑b∈Basis. x ∙ b * (x ∙ b))" by (metis euclidean_inner order_refl) alsohave"…≤ DIM('a) * ∣infnorm x∣🪙2" by (rule sum_bounded_above) (metis Basis_le_infnorm abs_le_square_iff power2_eq_square real_abs_infnorm) alsohave"…≤ (sqrt DIM('a) * infnorm x)🪙2" by (simp add: power_mult_distrib) finallyshow"x ∙ x ≤ (sqrt DIM('a) * infnorm x)🪙2" . qed
lemma tendsto_infnorm [tendsto_intros]: assumes"(f ---> a) F" shows"((λx. infnorm (f x)) ---> infnorm a) F" proof (rule tendsto_compose [OF LIM_I assms]) fix r :: real assume"r > 0" thenshow"∃s>0. ∀x. x ≠ a ∧ norm (x - a) < s ⟶ norm (infnorm x - infnorm a) < r" by (metis real_norm_def le_less_trans absdiff_infnorm infnorm_le_norm) qed
text‹Equality in Cauchy-Schwarz and triangle inequalities.›
lemma norm_cauchy_schwarz_eq: "x ∙ y = norm x * norm y ⟷ norm x *🪙R y = norm y *??R x"
(is"?lhs ⟷ ?rhs") proof (cases "x=0") case True thenshow ?thesis by auto next case False from inner_eq_zero_iff[of "norm y *🪙R x - norm x *🪙R y"] have"?rhs ⟷ (norm y * (norm y * norm x * norm x - norm x * (x ∙ y)) - norm x * (norm y * (y ∙ x) - norm x * norm y * norm y) = 0)" using False unfolding inner_simps by (auto simp add: power2_norm_eq_inner[symmetric] power2_eq_square inner_commute field_simps) alsohave"…⟷ (2 * norm x * norm y * (norm x * norm y - x ∙ y) = 0)" using False by (simp add: field_simps inner_commute) alsohave"…⟷ ?lhs" using False by auto finallyshow ?thesis by metis qed
lemma norm_cauchy_schwarz_abs_eq: "∣x ∙ y∣ = norm x * norm y ⟷ norm x *🪙R y = norm y *🪙R x ∨ norm x *🪙R y = - norm y *🪙R x" using norm_cauchy_schwarz_eq [symmetric, of x y] using norm_cauchy_schwarz_eq [symmetric, of "-x" y] Cauchy_Schwarz_ineq2 [of x y] by auto
lemma norm_triangle_eq: fixes x y :: "'a::real_inner" shows"norm (x + y) = norm x + norm y ⟷ norm x *🪙R y = norm y *🪙R x" proof (cases "x = 0 ∨ y = 0") case True thenshow ?thesis by force next case False thenhave n: "norm x > 0""norm y > 0" by auto have"norm (x + y) = norm x + norm y ⟷ (norm (x + y))🪙2 = (norm x + norm y)🪙2" by simp alsohave"…⟷ norm x *🪙R y = norm y *🪙R x" by (smt (verit, best) dot_norm inner_real_def inner_simps norm_cauchy_schwarz_eq power2_eq_square) finallyshow ?thesis . qed
lemma dist_triangle_eq: fixes x y z :: "'a::real_inner" shows"dist x z = dist x y + dist y z ⟷ norm (x - y) *🪙R (y - z) = norm (y - z) *🪙R (x - y)" by (metis (no_types, lifting) add_diff_eq diff_add_cancel dist_norm norm_triangle_eq)
subsection‹Collinearity›
definition🍋‹tag important› collinear :: "'a::real_vector set ==> bool" where"collinear S ⟷ (∃u. ∀x ∈ S. ∀ y ∈ S. ∃c. x - y = c *🪙R u)"
lemma collinear_alt: "collinear S ⟷ (∃u v. ∀x ∈ S. ∃c. x = u + c *🪙R v)" (is"?lhs = ?rhs") proof assume ?lhs thenshow ?rhs unfolding collinear_def by (metis add.commute diff_add_cancel) next assume ?rhs thenobtain u v where *: "∧x. x ∈ S ==>∃c. x = u + c *🪙R v" by auto have"∃c. x - y = c *🪙R v"if"x ∈ S""y ∈ S"for x y by (metis *[OF ‹x ∈ S›] *[OF ‹y ∈ S›] scaleR_left.diff add_diff_cancel_left) thenshow ?lhs using collinear_def by blast qed
lemma collinear: fixes S :: "'a::{perfect_space,real_vector} set" shows"collinear S ⟷ (∃u. u ≠ 0 ∧ (∀x ∈ S. ∀ y ∈ S. ∃c. x - y = c *🪙R u))" proof - have"∃v. v ≠ 0 ∧ (∀x∈S. ∀y∈S. ∃c. x - y = c *🪙R v)" if"∀x∈S. ∀y∈S. ∃c. x - y = c *🪙R u""u=0"for u proof - have"∀x∈S. ∀y∈S. x = y" using that by auto moreover obtain v::'a where"v ≠ 0" using UNIV_not_singleton [of 0] by auto ultimatelyhave"∀x∈S. ∀y∈S. ∃c. x - y = c *🪙R v" by auto thenshow ?thesis using‹v ≠ 0›by blast qed thenshow ?thesis by (metis collinear_def) qed
lemma collinear_subset: "[collinear T; S ⊆ T]==> collinear S" by (meson collinear_def subsetCE)
lemma collinear_empty [iff]: "collinear {}" by (simp add: collinear_def)
lemma collinear_sing [iff]: "collinear {x}" by (simp add: collinear_def)
lemma collinear_lemma: "collinear {0, x, y} ⟷ x = 0 ∨ y = 0 ∨ (∃c. y = c *🪙R x)"
(is"?lhs ⟷ ?rhs") proof (cases "x = 0 ∨ y = 0") case True thenshow ?thesis by (auto simp: insert_commute) next case False show ?thesis proof assume h: "?lhs" thenobtain u where u: "∀ x∈ {0,x,y}. ∀y∈ {0,x,y}. ∃c. x - y = c *🪙R u" unfolding collinear_def by blast from u[rule_format, of x 0] u[rule_format, of y 0] obtain cx and cy where
cx: "x = cx *🪙R u"and cy: "y = cy *🪙R u" by auto from cx cy False have cx0: "cx ≠ 0"and cy0: "cy ≠ 0"by auto let ?d = "cy / cx" from cx cy cx0 have"y = ?d *🪙R x" by simp thenshow ?rhs using False by blast next assume h: "?rhs" thenobtain c where c: "y = c *🪙R x" using False by blast show ?lhs apply (simp add: collinear_def c) by (metis (mono_tags, lifting) scaleR_left.minus scaleR_left_diff_distrib scaleR_one) qed qed
lemma collinear_scaleR_iff: "collinear {0, α *🪙R w, β *🪙R z} ⟷ collinear {0,w,z} ∨ α=0 ∨ β=0"
(is"?lhs = ?rhs") proof (cases "α=0 ∨ β=0") case False thenhave"(∃c. β *🪙R z = (c * α) *🪙R w) = (∃c. z = c *🪙R w)" by (metis mult.commute scaleR_scaleR vector_fraction_eq_iff) thenshow ?thesis by (auto simp add: collinear_lemma) qed (auto simp: collinear_lemma)
lemma norm_cauchy_schwarz_equal: "∣x ∙ y∣ = norm x * norm y ⟷ collinear {0, x, y}" proof (cases "x=0") case True thenshow ?thesis by (auto simp: insert_commute) next case False thenhave nnz: "norm x ≠ 0" by auto show ?thesis proof assume"∣x ∙ y∣ = norm x * norm y" thenshow"collinear {0, x, y}" unfolding norm_cauchy_schwarz_abs_eq collinear_lemma by (meson eq_vector_fraction_iff nnz) next assume"collinear {0, x, y}" with False show"∣x ∙ y∣ = norm x * norm y" unfolding norm_cauchy_schwarz_abs_eq collinear_lemma by (auto simp: abs_if) qed qed
lemma norm_triangle_eq_imp_collinear: fixes x y :: "'a::real_inner" assumes"norm (x + y) = norm x + norm y" shows"collinear{0,x,y}" using assms norm_cauchy_schwarz_abs_eq norm_cauchy_schwarz_equal norm_triangle_eq by blast
subsection‹Properties of special hyperplanes›
lemma subspace_hyperplane: "subspace {x. a ∙ x = 0}" by (simp add: subspace_def inner_right_distrib)
lemma subspace_hyperplane2: "subspace {x. x ∙ a = 0}" by (simp add: inner_commute inner_right_distrib subspace_def)
lemma special_hyperplane_span: fixes S :: "'n::euclidean_space set" assumes"k ∈ Basis" shows"{x. k ∙ x = 0} = span (Basis - {k})" proof - have *: "x ∈ span (Basis - {k})"if"k ∙ x = 0"for x proof - have"x = (∑b∈Basis. (x ∙ b) *🪙R b)" by (simp add: euclidean_representation) alsohave"… = (∑b ∈ Basis - {k}. (x ∙ b) *🪙R b)" by (auto simp: sum.remove [of _ k] inner_commute assms that) finallyhave"x = (∑b∈Basis - {k}. (x ∙ b) *🪙R b)" . thenshow ?thesis by (simp add: span_finite) qed show ?thesis apply (rule span_subspace [symmetric]) using assms apply (auto simp: inner_not_same_Basis intro: * subspace_hyperplane) done qed
lemma dim_special_hyperplane: fixes k :: "'n::euclidean_space" shows"k ∈ Basis ==> dim {x. k ∙ x = 0} = DIM('n) - 1" by (metis Diff_subset card_Diff_singleton indep_card_eq_dim_span independent_substdbasis special_hyperplane_span)
proposition dim_hyperplane: fixes a :: "'a::euclidean_space" assumes"a ≠ 0" shows"dim {x. a ∙ x = 0} = DIM('a) - 1" proof - have span0: "span {x. a ∙ x = 0} = {x. a ∙ x = 0}" by (rule span_unique) (auto simp: subspace_hyperplane) thenobtain B where"independent B" and Bsub: "B ⊆ {x. a ∙ x = 0}" and subspB: "{x. a ∙ x = 0} ⊆ span B" and card0: "(card B = dim {x. a ∙ x = 0})" and ortho: "pairwise orthogonal B" using orthogonal_basis_exists by metis with assms have"a ∉ span B" by (metis (mono_tags, lifting) span_eq inner_eq_zero_iff mem_Collect_eq span0) thenhave ind: "independent (insert a B)" by (simp add: ‹independent B› independent_insert) have"finite B" using‹independent B› independent_bound by blast have"UNIV ⊆ span (insert a B)" prooffix y::'a obtain r z where"y = r *🪙R a + z""a ∙ z = 0" by (metis add.commute diff_add_cancel vector_sub_project_orthogonal) thenshow"y ∈ span (insert a B)" by (metis (mono_tags, lifting) Bsub add_diff_cancel_left'
mem_Collect_eq span0 span_breakdown_eq span_eq subspB) qed thenhave"DIM('a) = dim(insert a B)" by (metis independent_Basis span_Basis dim_eq_card top.extremum_uniqueI) thenshow ?thesis by (metis One_nat_def ‹a ∉ span B›‹finite B› card0 card_insert_disjoint
diff_Suc_Suc diff_zero dim_eq_card_independent ind span_base) qed
lemma lowdim_eq_hyperplane: fixes S :: "'a::euclidean_space set" assumes"dim S = DIM('a) - 1" obtains a where"a ≠ 0"and"span S = {x. a ∙ x = 0}" proof - obtain b where b: "b ≠ 0""span S ⊆ {a. b ∙ a = 0}" by (metis DIM_positive assms diff_less zero_less_one lowdim_subset_hyperplane) thenshow ?thesis by (metis assms dim_hyperplane dim_span dim_subset subspace_dim_equal subspace_hyperplane subspace_span that) qed
lemma dim_eq_hyperplane: fixes S :: "'n::euclidean_space set" shows"dim S = DIM('n) - 1 ⟷ (∃a. a ≠ 0 ∧ span S = {x. a ∙ x = 0})" by (metis One_nat_def dim_hyperplane dim_span lowdim_eq_hyperplane)
subsection‹ Orthogonal bases and Gram-Schmidt process›
lemma pairwise_orthogonal_independent: assumes"pairwise orthogonal S"and"0 ∉ S" shows"independent S" proof - have 0: "∧x y. [x ≠ y; x ∈ S; y ∈ S]==> x ∙ y = 0" using assms by (simp add: pairwise_def orthogonal_def) have"False"if"a ∈ S"and a: "a ∈ span (S - {a})"for a proof - obtain T U where"T ⊆ S - {a}""a = (∑v∈T. U v *🪙R v)" using a by (force simp: span_explicit) thenhave"a ∙ a = a ∙ (∑v∈T. U v *🪙R v)" by simp alsohave"… = 0" apply (simp add: inner_sum_right) by (smt (verit) "0" DiffE ‹T ⊆ S - {a}› in_mono insertCI mult_not_zero sum.neutral that(1)) finallyshow ?thesis using‹0 ∉ S›‹a ∈ S›by auto qed thenshow ?thesis by (force simp: dependent_def) qed
lemma pairwise_orthogonal_imp_finite: fixes S :: "'a::euclidean_space set" assumes"pairwise orthogonal S" shows"finite S" by (metis Set.set_insert assms finite_insert independent_bound pairwise_insert
pairwise_orthogonal_independent)
lemma subspace_orthogonal_to_vector: "subspace {y. orthogonal x y}" by (simp add: subspace_def orthogonal_clauses)
lemma subspace_orthogonal_to_vectors: "subspace {y. ∀x ∈ S. orthogonal x y}" by (simp add: subspace_def orthogonal_clauses)
lemma orthogonal_to_span: assumes a: "a ∈ span S"and x: "∧y. y ∈ S ==> orthogonal x y" shows"orthogonal x a" by (metis a orthogonal_clauses(1,2,4)
span_induct_alt x)
proposition Gram_Schmidt_step: fixes S :: "'a::euclidean_space set" assumes S: "pairwise orthogonal S"and x: "x ∈ span S" shows"orthogonal x (a - (∑b∈S. (b ∙ a / (b ∙ b)) *🪙R b))" proof - have"finite S" by (simp add: S pairwise_orthogonal_imp_finite) have"orthogonal (a - (∑b∈S. (b ∙ a / (b ∙ b)) *🪙R b)) x" if"x ∈ S"for x proof - have"a ∙ x = (∑y∈S. if y = x then y ∙ a else 0)" by (simp add: ‹finite S› inner_commute that) alsohave"… = (∑b∈S. b ∙ a * (b ∙ x) / (b ∙ b))" apply (rule sum.cong [OF refl], simp) by (meson S orthogonal_def pairwise_def that) finallyshow ?thesis by (simp add: orthogonal_def algebra_simps inner_sum_left) qed thenshow ?thesis using orthogonal_to_span orthogonal_commute x by blast qed
lemma orthogonal_extension_aux: fixes S :: "'a::euclidean_space set" assumes"finite T""finite S""pairwise orthogonal S" shows"∃U. pairwise orthogonal (S ∪ U) ∧ span (S ∪ U) = span (S ∪ T)" using assms proof (induction arbitrary: S) case empty thenshow ?case by simp (metis sup_bot_right) next case (insert a T) have 0: "∧x y. [x ≠ y; x ∈ S; y ∈ S]==> x ∙ y = 0" using insert by (simp add: pairwise_def orthogonal_def)
define a' where"a' = a - (∑b∈S. (b ∙ a / (b ∙ b)) *🪙R b)" obtain U where orthU: "pairwise orthogonal (S ∪ insert a' U)" and spanU: "span (insert a' S ∪ U) = span (insert a' S ∪ T)" by (rule exE [OF insert.IH [of "insert a' S"]])
(auto simp: Gram_Schmidt_step a'_def insert.prems orthogonal_commute
pairwise_orthogonal_insert span_clauses) have orthS: "∧x. x ∈ S ==> a' ∙ x = 0" using Gram_Schmidt_step a'_def insert.prems orthogonal_commute orthogonal_def span_base by blast have"span (S ∪ insert a' U) = span (insert a' (S ∪ T))" using spanU by simp alsohave"… = span (insert a (S ∪ T))" by (simp add: a'_def span_neg span_sum span_base span_mul eq_span_insert_eq) alsohave"… = span (S ∪ insert a T)" by simp finallyshow ?case using orthU by blast qed
proposition orthogonal_extension: fixes S :: "'a::euclidean_space set" assumes S: "pairwise orthogonal S" obtains U where"pairwise orthogonal (S ∪ U)""span (S ∪ U) = span (S ∪ T)" proof - obtain B where"finite B""span B = span T" using basis_subspace_exists [of "span T"] subspace_span by metis with orthogonal_extension_aux [of B S] obtain U where"pairwise orthogonal (S ∪ U)""span (S ∪ U) = span (S ∪ B)" using assms pairwise_orthogonal_imp_finite by auto with‹span B = span T›show ?thesis by (rule_tac U=U in that) (auto simp: span_Un) qed
corollary🍋‹tag unimportant› orthogonal_extension_strong: fixes S :: "'a::euclidean_space set" assumes S: "pairwise orthogonal S" obtains U where"U ∩ (insert 0 S) = {}""pairwise orthogonal (S ∪ U)" "span (S ∪ U) = span (S ∪ T)" proof - obtain U where U: "pairwise orthogonal (S ∪ U)""span (S ∪ U) = span (S ∪ T)" using orthogonal_extension assms by blast moreoverhave"pairwise orthogonal (S ∪ (U - insert 0 S))" by (smt (verit, best) Un_Diff_Int Un_iff U pairwise_def) ultimatelyshow ?thesis by (metis Diff_disjoint Un_Diff_cancel Un_insert_left inf_commute span_insert_0 that) qed
subsection‹Decomposing a vector into parts in orthogonal subspaces›
text‹existence of orthonormal basis for a subspace.›
lemma orthogonal_spanningset_subspace: fixes S :: "'a :: euclidean_space set" assumes"subspace S" obtains B where"B ⊆ S""pairwise orthogonal B""span B = S" by (metis assms basis_orthogonal basis_subspace_exists span_eq)
lemma orthogonal_basis_subspace: fixes S :: "'a :: euclidean_space set" assumes"subspace S" obtains B where"0 ∉ B""B ⊆ S""pairwise orthogonal B""independent B" "card B = dim S""span B = S" by (metis assms dependent_zero orthogonal_basis_exists span_eq span_eq_iff)
proposition orthonormal_basis_subspace: fixes S :: "'a :: euclidean_space set" assumes"subspace S" obtains B where"B ⊆ S""pairwise orthogonal B" and"∧x. x ∈ B ==> norm x = 1" and"independent B""card B = dim S""span B = S" proof - obtain B where"0 ∉ B""B ⊆ S" and orth: "pairwise orthogonal B" and"independent B""card B = dim S""span B = S" by (blast intro: orthogonal_basis_subspace [OF assms]) have 1: "(λx. x /🪙R norm x) ` B ⊆ S" using‹span B = S› span_superset span_mul by fastforce have 2: "pairwise orthogonal ((λx. x /🪙R norm x) ` B)" using orth by (force simp: pairwise_def orthogonal_clauses) have 3: "∧x. x ∈ (λx. x /🪙R norm x) ` B ==> norm x = 1" by (metis (no_types, lifting) ‹0 ∉ B› image_iff norm_sgn sgn_div_norm) have 4: "independent ((λx. x /🪙R norm x) ` B)" by (metis "2""3" norm_zero pairwise_orthogonal_independent zero_neq_one) have"inj_on (λx. x /🪙R norm x) B" proof fix x y assume"x ∈ B""y ∈ B""x /🪙R norm x = y /🪙R norm y" moreoverhave"∧i. i ∈ B ==> norm (i /🪙R norm i) = 1" using 3 by blast ultimatelyshow"x = y" by (metis norm_eq_1 orth orthogonal_clauses(7) orthogonal_commute orthogonal_def pairwise_def zero_neq_one) qed thenhave 5: "card ((λx. x /🪙R norm x) ` B) = dim S" by (metis ‹card B = dim S› card_image) have 6: "span ((λx. x /🪙R norm x) ` B) = S" by (metis "1""4""5" assms card_eq_dim independent_imp_finite span_subspace) show ?thesis by (rule that [OF 1 2 3 4 5 6]) qed
proposition🍋‹tag unimportant› orthogonal_to_subspace_exists_gen: fixes S :: "'a :: euclidean_space set" assumes"span S ⊂ span T" obtains x where"x ≠ 0""x ∈ span T""∧y. y ∈ span S ==> orthogonal x y" proof - obtain B where"B ⊆ span S"and orthB: "pairwise orthogonal B" and"∧x. x ∈ B ==> norm x = 1" and"independent B""card B = dim S""span B = span S" by (metis dim_span orthonormal_basis_subspace subspace_span) with assms obtain u where spanBT: "span B ⊆ span T"and"u ∉ span B""u ∈ span T" by auto obtain C where orthBC: "pairwise orthogonal (B ∪ C)"and spanBC: "span (B ∪ C) = span (B ∪ {u})" by (blast intro: orthogonal_extension [OF orthB]) show thesis proof (cases "C ⊆ insert 0 B") case True thenhave"C ⊆ span B" using span_eq by (metis span_insert_0 subset_trans) moreoverhave"u ∈ span (B ∪ C)" using‹span (B ∪ C) = span (B ∪ {u})› span_superset by force ultimatelyshow ?thesis using True ‹u ∉ span B› by (metis Un_insert_left span_insert_0 sup.orderE) next case False thenobtain x where"x ∈ C""x ≠ 0""x ∉ B" by blast thenhave"x ∈ span T" by (smt (verit, ccfv_SIG) Set.set_insert ‹u ∈ span T› empty_subsetI insert_subset
le_sup_iff spanBC spanBT span_mono span_span span_superset subset_trans) moreoverhave"orthogonal x y"if"y ∈ span B"for y using that proof (rule span_induct) show"subspace {a. orthogonal x a}" by (simp add: subspace_orthogonal_to_vector) show"∧b. b ∈ B ==> orthogonal x b" by (metis Un_iff ‹x ∈ C›‹x ∉ B› orthBC pairwise_def) qed ultimatelyshow ?thesis using‹x ≠ 0› that ‹span B = span S›by auto qed qed
corollary🍋‹tag unimportant› orthogonal_to_subspace_exists: fixes S :: "'a :: euclidean_space set" assumes"dim S < DIM('a)" obtains x where"x ≠ 0""∧y. y ∈ span S ==> orthogonal x y" proof - have"span S ⊂ UNIV" by (metis assms dim_eq_full order_less_imp_not_less top.not_eq_extremum) with orthogonal_to_subspace_exists_gen [of S UNIV] that show ?thesis by (auto) qed
corollary🍋‹tag unimportant› orthogonal_to_vector_exists: fixes x :: "'a :: euclidean_space" assumes"2 ≤ DIM('a)" obtains y where"y ≠ 0""orthogonal x y" proof - have"dim {x} < DIM('a)" using assms by auto thenshow thesis by (rule orthogonal_to_subspace_exists) (simp add: orthogonal_commute span_base that) qed
proposition🍋‹tag unimportant› orthogonal_subspace_decomp_exists: fixes S :: "'a :: euclidean_space set" obtains y z where"y ∈ span S" and"∧w. w ∈ span S ==> orthogonal z w" and"x = y + z" proof - obtain T where"0 ∉ T""T ⊆ span S""pairwise orthogonal T""independent T" "card T = dim (span S)""span T = span S" using orthogonal_basis_subspace subspace_span by blast let ?a = "∑b∈T. (b ∙ x / (b ∙ b)) *🪙R b" have orth: "orthogonal (x - ?a) w"if"w ∈ span S"for w by (simp add: Gram_Schmidt_step ‹pairwise orthogonal T›‹span T = span S›
orthogonal_commute that) with that[of ?a "x-?a"] ‹T ⊆ span S›show ?thesis by (simp add: span_mul span_sum subsetD) qed
lemma orthogonal_subspace_decomp_unique: fixes S :: "'a :: euclidean_space set" assumes"x + y = x' + y'" and ST: "x ∈ span S""x' ∈ span S""y ∈ span T""y' ∈ span T" and orth: "∧a b. [a ∈ S; b ∈ T]==> orthogonal a b" shows"x = x' ∧ y = y'" proof - have"x + y - y' = x'" by (simp add: assms) moreoverhave"∧a b. [a ∈ span S; b ∈ span T]==> orthogonal a b" by (meson orth orthogonal_commute orthogonal_to_span) ultimatelyhave"0 = x' - x" using assms by (metis add.commute add_diff_cancel_right' diff_right_commute orthogonal_self span_diff) with assms show ?thesis by auto qed
lemma vector_in_orthogonal_spanningset: fixes a :: "'a::euclidean_space" obtains S where"a ∈ S""pairwise orthogonal S""span S = UNIV" by (metis UnI1 Un_UNIV_right insertI1 orthogonal_extension pairwise_singleton span_UNIV)
lemma vector_in_orthogonal_basis: fixes a :: "'a::euclidean_space" assumes"a ≠ 0" obtains S where"a ∈ S""0 ∉ S""pairwise orthogonal S""independent S""finite S" "span S = UNIV""card S = DIM('a)" proof - obtain S where S: "a ∈ S""pairwise orthogonal S""span S = UNIV" using vector_in_orthogonal_spanningset . show thesis proof show"pairwise orthogonal (S - {0})" using pairwise_mono S(2) by blast show"independent (S - {0})" by (simp add: ‹pairwise orthogonal (S - {0})› pairwise_orthogonal_independent) show"finite (S - {0})" using‹independent (S - {0})› independent_imp_finite by blast show"card (S - {0}) = DIM('a)" using span_delete_0 [of S] S by (simp add: ‹independent (S - {0})› indep_card_eq_dim_span) qed (use S ‹a ≠ 0›in auto) qed
lemma vector_in_orthonormal_basis: fixes a :: "'a::euclidean_space" assumes"norm a = 1" obtains S where"a ∈ S""pairwise orthogonal S""∧x. x ∈ S ==> norm x = 1" "independent S""card S = DIM('a)""span S = UNIV" proof - have"a ≠ 0" using assms by auto thenobtain S where"a ∈ S""0 ∉ S""finite S" and S: "pairwise orthogonal S""independent S""span S = UNIV""card S = DIM('a)" by (metis vector_in_orthogonal_basis) let ?S = "(λx. x /🪙R norm x) ` S" show thesis proof show"a ∈ ?S" using‹a ∈ S› assms image_iff by fastforce next show"pairwise orthogonal ?S" using‹pairwise orthogonal S›by (auto simp: pairwise_def orthogonal_def) show"∧x. x ∈ (λx. x /🪙R norm x) ` S ==> norm x = 1" using‹0 ∉ S›by (auto simp: field_split_simps) thenshow ind: "independent ?S" by (metis ‹pairwise orthogonal ((λx. x /🪙R norm x) ` S)› norm_zero pairwise_orthogonal_independent zero_neq_one) have"inj_on (λx. x /🪙R norm x) S" unfolding inj_on_def by (metis (full_types) S(1) ‹0 ∉ S› inverse_nonzero_iff_nonzero norm_eq_zero orthogonal_scaleR orthogonal_self pairwise_def) thenshow"card ?S = DIM('a)" by (simp add: card_image S) thenshow"span ?S = UNIV" by (metis ind dim_eq_card dim_eq_full) qed qed
proposition dim_orthogonal_sum: fixes A :: "'a::euclidean_space set" assumes"∧x y. [x ∈ A; y ∈ B]==> x ∙ y = 0" shows"dim(A ∪ B) = dim A + dim B" proof - have 1: "∧x y. [x ∈ span A; y ∈ B]==> x ∙ y = 0" by (erule span_induct [OF _ subspace_hyperplane2]; simp add: assms) have"∧x y. [x ∈ span A; y ∈ span B]==> x ∙ y = 0" using 1 by (simp add: span_induct [OF _ subspace_hyperplane]) thenhave 0: "∧x y. [x ∈ span A; y ∈ span B]==> x ∙ y = 0" by simp have"dim(A ∪ B) = dim (span (A ∪ B))" by (simp) alsohave"span (A ∪ B) = ((λ(a, b). a + b) ` (span A × span B))" by (auto simp add: span_Un image_def) alsohave"dim … = dim {x + y |x y. x ∈ span A ∧ y ∈ span B}" by (auto intro!: arg_cong [where f=dim]) alsohave"… = dim {x + y |x y. x ∈ span A ∧ y ∈ span B} + dim(span A ∩ span B)" by (auto dest: 0) alsohave"… = dim A + dim B" using dim_sums_Int by fastforce finallyshow ?thesis . qed
lemma dim_subspace_orthogonal_to_vectors: fixes A :: "'a::euclidean_space set" assumes"subspace A""subspace B""A ⊆ B" shows"dim {y ∈ B. ∀x ∈ A. orthogonal x y} + dim A = dim B" proof - have"dim (span ({y ∈ B. ∀x∈A. orthogonal x y} ∪ A)) = dim (span B)" proof (rule arg_cong [where f=dim, OF subset_antisym]) show"span ({y ∈ B. ∀x∈A. orthogonal x y} ∪ A) ⊆ span B" by (simp add: ‹A ⊆ B› Collect_restrict span_mono) next have *: "x ∈ span ({y ∈ B. ∀x∈A. orthogonal x y} ∪ A)" if"x ∈ B"for x proof - obtain y z where"x = y + z""y ∈ span A"and orth: "∧w. w ∈ span A ==> orthogonal z w" using orthogonal_subspace_decomp_exists [of A x] that by auto moreover have"y ∈ span B" using‹y ∈ span A› assms(3) span_mono by blast ultimatelyhave"z ∈ B ∧ (∀x. x ∈ A ⟶ orthogonal x z)" using assms by (metis orthogonal_commute span_add_eq span_eq_iff that) thenhave z: "z ∈ span {y ∈ B. ∀x∈A. orthogonal x y}" by (simp add: span_base) thenshow ?thesis by (smt (verit, best) ‹x = y + z›‹y ∈ span A› le_sup_iff span_add_eq span_subspace_induct
span_superset subset_iff subspace_span) qed show"span B ⊆ span ({y ∈ B. ∀x∈A. orthogonal x y} ∪ A)" by (rule span_minimal) (auto intro: * span_minimal) qed thenshow ?thesis by (metis (no_types, lifting) dim_orthogonal_sum dim_span mem_Collect_eq
orthogonal_commute orthogonal_def) qed
subsection‹Linear functions are (uniformly) continuous on any set›
subsection🍋‹tag unimportant›‹Topological properties of linear functions›
lemma linear_lim_0: assumes"bounded_linear f" shows"(f ---> 0) (at (0))" proof - interpret f: bounded_linear f by fact have"(f ---> f 0) (at 0)" using tendsto_ident_at by (rule f.tendsto) thenshow ?thesis unfolding f.zero . qed
lemma linear_continuous_at: "bounded_linear f ==>continuous (at a) f" by (simp add: bounded_linear.isUCont isUCont_isCont)
lemma linear_continuous_within: "bounded_linear f ==> continuous (at x within s) f" using continuous_at_imp_continuous_at_within linear_continuous_at by blast
lemma linear_continuous_on: "bounded_linear f ==> continuous_on s f" using continuous_at_imp_continuous_on[of s f] using linear_continuous_at[of f] by auto
lemma Lim_linear: fixes f :: "'a::euclidean_space ==> 'b::euclidean_space"and h :: "'b ==> 'c::real_normed_vector" assumes"(f ---> l) F""linear h" shows"((λx. h(f x)) ---> h l) F" proof - obtain B where B: "B > 0""∧x. norm (h x) ≤ B * norm x" using linear_bounded_pos [OF ‹linear h›] by blast show ?thesis unfolding tendsto_iff by (simp add: assms bounded_linear.tendsto linear_linear tendstoD) qed
lemma linear_continuous_compose: fixes f :: "'a::euclidean_space ==> 'b::euclidean_space"and g :: "'b ==> 'c::real_normed_vector" assumes"continuous F f""linear g" shows"continuous F (λx. g(f x))" using assms unfolding continuous_def by (rule Lim_linear)
lemma linear_continuous_on_compose: fixes f :: "'a::euclidean_space ==> 'b::euclidean_space"and g :: "'b ==> 'c::real_normed_vector" assumes"continuous_on S f""linear g" shows"continuous_on S (λx. g(f x))" using assms by (simp add: continuous_on_eq_continuous_within linear_continuous_compose)
text‹Also bilinear functions, in composition form›
lemma bilinear_continuous_compose: fixes h :: "'a::euclidean_space ==> 'b::euclidean_space ==> 'c::real_normed_vector" assumes"continuous F f""continuous F g""bilinear h" shows"continuous F (λx. h (f x) (g x))" using assms bilinear_conv_bounded_bilinear bounded_bilinear.continuous by blast
lemma bilinear_continuous_on_compose: fixes h :: "'a::euclidean_space ==> 'b::euclidean_space ==> 'c::real_normed_vector" and f :: "'d::t2_space ==> 'a" assumes"continuous_on S f""continuous_on S g""bilinear h" shows"continuous_on S (λx. h (f x) (g x))" using assms by (simp add: continuous_on_eq_continuous_within bilinear_continuous_compose)
end
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.48 Sekunden
(vorverarbeitet am 2026-04-27)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.