src/HOL/Analysis/Starlike.thy
changeset 69675 880ab0f27ddf
parent 69661 a03a63b81f44
child 69676 56acd449da41
equal deleted inserted replaced
69674:fc252acb7100 69675:880ab0f27ddf
  5466 lemma aff_dim_halfspace_ge:
  5466 lemma aff_dim_halfspace_ge:
  5467   fixes a :: "'a::euclidean_space"
  5467   fixes a :: "'a::euclidean_space"
  5468   shows "aff_dim {x. a \<bullet> x \<ge> r} =
  5468   shows "aff_dim {x. a \<bullet> x \<ge> r} =
  5469         (if a = 0 \<and> r > 0 then -1 else DIM('a))"
  5469         (if a = 0 \<and> r > 0 then -1 else DIM('a))"
  5470 using aff_dim_halfspace_le [of "-a" "-r"] by simp
  5470 using aff_dim_halfspace_le [of "-a" "-r"] by simp
  5471 
       
  5472 subsection\<open>Properties of special hyperplanes\<close>
       
  5473 
       
  5474 lemma subspace_hyperplane: "subspace {x. a \<bullet> x = 0}"
       
  5475   by (simp add: subspace_def inner_right_distrib)
       
  5476 
       
  5477 lemma subspace_hyperplane2: "subspace {x. x \<bullet> a = 0}"
       
  5478   by (simp add: inner_commute inner_right_distrib subspace_def)
       
  5479 
       
  5480 lemma special_hyperplane_span:
       
  5481   fixes S :: "'n::euclidean_space set"
       
  5482   assumes "k \<in> Basis"
       
  5483   shows "{x. k \<bullet> x = 0} = span (Basis - {k})"
       
  5484 proof -
       
  5485   have *: "x \<in> span (Basis - {k})" if "k \<bullet> x = 0" for x
       
  5486   proof -
       
  5487     have "x = (\<Sum>b\<in>Basis. (x \<bullet> b) *\<^sub>R b)"
       
  5488       by (simp add: euclidean_representation)
       
  5489     also have "... = (\<Sum>b \<in> Basis - {k}. (x \<bullet> b) *\<^sub>R b)"
       
  5490       by (auto simp: sum.remove [of _ k] inner_commute assms that)
       
  5491     finally have "x = (\<Sum>b\<in>Basis - {k}. (x \<bullet> b) *\<^sub>R b)" .
       
  5492     then show ?thesis
       
  5493       by (simp add: span_finite)
       
  5494   qed
       
  5495   show ?thesis
       
  5496     apply (rule span_subspace [symmetric])
       
  5497     using assms
       
  5498     apply (auto simp: inner_not_same_Basis intro: * subspace_hyperplane)
       
  5499     done
       
  5500 qed
       
  5501 
       
  5502 lemma dim_special_hyperplane:
       
  5503   fixes k :: "'n::euclidean_space"
       
  5504   shows "k \<in> Basis \<Longrightarrow> dim {x. k \<bullet> x = 0} = DIM('n) - 1"
       
  5505 apply (simp add: special_hyperplane_span)
       
  5506 apply (rule dim_unique [OF subset_refl])
       
  5507 apply (auto simp: independent_substdbasis)
       
  5508 apply (metis member_remove remove_def span_base)
       
  5509 done
       
  5510 
       
  5511 proposition dim_hyperplane:
       
  5512   fixes a :: "'a::euclidean_space"
       
  5513   assumes "a \<noteq> 0"
       
  5514     shows "dim {x. a \<bullet> x = 0} = DIM('a) - 1"
       
  5515 proof -
       
  5516   have span0: "span {x. a \<bullet> x = 0} = {x. a \<bullet> x = 0}"
       
  5517     by (rule span_unique) (auto simp: subspace_hyperplane)
       
  5518   then obtain B where "independent B"
       
  5519               and Bsub: "B \<subseteq> {x. a \<bullet> x = 0}"
       
  5520               and subspB: "{x. a \<bullet> x = 0} \<subseteq> span B"
       
  5521               and card0: "(card B = dim {x. a \<bullet> x = 0})"
       
  5522               and ortho: "pairwise orthogonal B"
       
  5523     using orthogonal_basis_exists by metis
       
  5524   with assms have "a \<notin> span B"
       
  5525     by (metis (mono_tags, lifting) span_eq inner_eq_zero_iff mem_Collect_eq span0)
       
  5526   then have ind: "independent (insert a B)"
       
  5527     by (simp add: \<open>independent B\<close> independent_insert)
       
  5528   have "finite B"
       
  5529     using \<open>independent B\<close> independent_bound by blast
       
  5530   have "UNIV \<subseteq> span (insert a B)"
       
  5531   proof fix y::'a
       
  5532     obtain r z where z: "y = r *\<^sub>R a + z" "a \<bullet> z = 0"
       
  5533       apply (rule_tac r="(a \<bullet> y) / (a \<bullet> a)" and z = "y - ((a \<bullet> y) / (a \<bullet> a)) *\<^sub>R a" in that)
       
  5534       using assms
       
  5535       by (auto simp: algebra_simps)
       
  5536     show "y \<in> span (insert a B)"
       
  5537       by (metis (mono_tags, lifting) z Bsub span_eq_iff
       
  5538          add_diff_cancel_left' mem_Collect_eq span0 span_breakdown_eq span_subspace subspB)
       
  5539   qed
       
  5540   then have dima: "DIM('a) = dim(insert a B)"
       
  5541     by (metis independent_Basis span_Basis dim_eq_card top.extremum_uniqueI)
       
  5542   then show ?thesis
       
  5543     by (metis (mono_tags, lifting) Bsub Diff_insert_absorb \<open>a \<notin> span B\<close> ind card0
       
  5544         card_Diff_singleton dim_span indep_card_eq_dim_span insertI1 subsetCE
       
  5545         subspB)
       
  5546 qed
       
  5547 
       
  5548 lemma lowdim_eq_hyperplane:
       
  5549   fixes S :: "'a::euclidean_space set"
       
  5550   assumes "dim S = DIM('a) - 1"
       
  5551   obtains a where "a \<noteq> 0" and "span S = {x. a \<bullet> x = 0}"
       
  5552 proof -
       
  5553   have dimS: "dim S < DIM('a)"
       
  5554     by (simp add: assms)
       
  5555   then obtain b where b: "b \<noteq> 0" "span S \<subseteq> {a. b \<bullet> a = 0}"
       
  5556     using lowdim_subset_hyperplane [of S] by fastforce
       
  5557   show ?thesis
       
  5558     apply (rule that[OF b(1)])
       
  5559     apply (rule subspace_dim_equal)
       
  5560     by (auto simp: assms b dim_hyperplane dim_span subspace_hyperplane
       
  5561         subspace_span)
       
  5562 qed
       
  5563 
       
  5564 lemma dim_eq_hyperplane:
       
  5565   fixes S :: "'n::euclidean_space set"
       
  5566   shows "dim S = DIM('n) - 1 \<longleftrightarrow> (\<exists>a. a \<noteq> 0 \<and> span S = {x. a \<bullet> x = 0})"
       
  5567 by (metis One_nat_def dim_hyperplane dim_span lowdim_eq_hyperplane)
       
  5568 
  5471 
  5569 proposition aff_dim_eq_hyperplane:
  5472 proposition aff_dim_eq_hyperplane:
  5570   fixes S :: "'a::euclidean_space set"
  5473   fixes S :: "'a::euclidean_space set"
  5571   shows "aff_dim S = DIM('a) - 1 \<longleftrightarrow> (\<exists>a b. a \<noteq> 0 \<and> affine hull S = {x. a \<bullet> x = b})"
  5474   shows "aff_dim S = DIM('a) - 1 \<longleftrightarrow> (\<exists>a b. a \<noteq> 0 \<and> affine hull S = {x. a \<bullet> x = b})"
  5572 proof (cases "S = {}")
  5475 proof (cases "S = {}")
  6434 lemma aff_dim_lt_full:
  6337 lemma aff_dim_lt_full:
  6435   fixes S :: "'a::euclidean_space set"
  6338   fixes S :: "'a::euclidean_space set"
  6436   shows "aff_dim S < DIM('a) \<longleftrightarrow> (affine hull S \<noteq> UNIV)"
  6339   shows "aff_dim S < DIM('a) \<longleftrightarrow> (affine hull S \<noteq> UNIV)"
  6437 by (metis (no_types) aff_dim_affine_hull aff_dim_le_DIM aff_dim_UNIV affine_hull_UNIV less_le)
  6340 by (metis (no_types) aff_dim_affine_hull aff_dim_le_DIM aff_dim_UNIV affine_hull_UNIV less_le)
  6438 
  6341 
  6439 
       
  6440 subsection\<open> Orthogonal bases, Gram-Schmidt process, and related theorems\<close>
       
  6441 
       
  6442 lemma pairwise_orthogonal_independent:
       
  6443   assumes "pairwise orthogonal S" and "0 \<notin> S"
       
  6444     shows "independent S"
       
  6445 proof -
       
  6446   have 0: "\<And>x y. \<lbrakk>x \<noteq> y; x \<in> S; y \<in> S\<rbrakk> \<Longrightarrow> x \<bullet> y = 0"
       
  6447     using assms by (simp add: pairwise_def orthogonal_def)
       
  6448   have "False" if "a \<in> S" and a: "a \<in> span (S - {a})" for a
       
  6449   proof -
       
  6450     obtain T U where "T \<subseteq> S - {a}" "a = (\<Sum>v\<in>T. U v *\<^sub>R v)"
       
  6451       using a by (force simp: span_explicit)
       
  6452     then have "a \<bullet> a = a \<bullet> (\<Sum>v\<in>T. U v *\<^sub>R v)"
       
  6453       by simp
       
  6454     also have "... = 0"
       
  6455       apply (simp add: inner_sum_right)
       
  6456       apply (rule comm_monoid_add_class.sum.neutral)
       
  6457       by (metis "0" DiffE \<open>T \<subseteq> S - {a}\<close> mult_not_zero singletonI subsetCE \<open>a \<in> S\<close>)
       
  6458     finally show ?thesis
       
  6459       using \<open>0 \<notin> S\<close> \<open>a \<in> S\<close> by auto
       
  6460   qed
       
  6461   then show ?thesis
       
  6462     by (force simp: dependent_def)
       
  6463 qed
       
  6464 
       
  6465 lemma pairwise_orthogonal_imp_finite:
       
  6466   fixes S :: "'a::euclidean_space set"
       
  6467   assumes "pairwise orthogonal S"
       
  6468     shows "finite S"
       
  6469 proof -
       
  6470   have "independent (S - {0})"
       
  6471     apply (rule pairwise_orthogonal_independent)
       
  6472      apply (metis Diff_iff assms pairwise_def)
       
  6473     by blast
       
  6474   then show ?thesis
       
  6475     by (meson independent_imp_finite infinite_remove)
       
  6476 qed
       
  6477 
       
  6478 lemma subspace_orthogonal_to_vector: "subspace {y. orthogonal x y}"
       
  6479   by (simp add: subspace_def orthogonal_clauses)
       
  6480 
       
  6481 lemma subspace_orthogonal_to_vectors: "subspace {y. \<forall>x \<in> S. orthogonal x y}"
       
  6482   by (simp add: subspace_def orthogonal_clauses)
       
  6483 
       
  6484 lemma orthogonal_to_span:
       
  6485   assumes a: "a \<in> span S" and x: "\<And>y. y \<in> S \<Longrightarrow> orthogonal x y"
       
  6486     shows "orthogonal x a"
       
  6487   by (metis a orthogonal_clauses(1,2,4)
       
  6488       span_induct_alt x)
       
  6489 
       
  6490 proposition Gram_Schmidt_step:
       
  6491   fixes S :: "'a::euclidean_space set"
       
  6492   assumes S: "pairwise orthogonal S" and x: "x \<in> span S"
       
  6493     shows "orthogonal x (a - (\<Sum>b\<in>S. (b \<bullet> a / (b \<bullet> b)) *\<^sub>R b))"
       
  6494 proof -
       
  6495   have "finite S"
       
  6496     by (simp add: S pairwise_orthogonal_imp_finite)
       
  6497   have "orthogonal (a - (\<Sum>b\<in>S. (b \<bullet> a / (b \<bullet> b)) *\<^sub>R b)) x"
       
  6498        if "x \<in> S" for x
       
  6499   proof -
       
  6500     have "a \<bullet> x = (\<Sum>y\<in>S. if y = x then y \<bullet> a else 0)"
       
  6501       by (simp add: \<open>finite S\<close> inner_commute sum.delta that)
       
  6502     also have "... =  (\<Sum>b\<in>S. b \<bullet> a * (b \<bullet> x) / (b \<bullet> b))"
       
  6503       apply (rule sum.cong [OF refl], simp)
       
  6504       by (meson S orthogonal_def pairwise_def that)
       
  6505    finally show ?thesis
       
  6506      by (simp add: orthogonal_def algebra_simps inner_sum_left)
       
  6507   qed
       
  6508   then show ?thesis
       
  6509     using orthogonal_to_span orthogonal_commute x by blast
       
  6510 qed
       
  6511 
       
  6512 
       
  6513 lemma orthogonal_extension_aux:
       
  6514   fixes S :: "'a::euclidean_space set"
       
  6515   assumes "finite T" "finite S" "pairwise orthogonal S"
       
  6516     shows "\<exists>U. pairwise orthogonal (S \<union> U) \<and> span (S \<union> U) = span (S \<union> T)"
       
  6517 using assms
       
  6518 proof (induction arbitrary: S)
       
  6519   case empty then show ?case
       
  6520     by simp (metis sup_bot_right)
       
  6521 next
       
  6522   case (insert a T)
       
  6523   have 0: "\<And>x y. \<lbrakk>x \<noteq> y; x \<in> S; y \<in> S\<rbrakk> \<Longrightarrow> x \<bullet> y = 0"
       
  6524     using insert by (simp add: pairwise_def orthogonal_def)
       
  6525   define a' where "a' = a - (\<Sum>b\<in>S. (b \<bullet> a / (b \<bullet> b)) *\<^sub>R b)"
       
  6526   obtain U where orthU: "pairwise orthogonal (S \<union> insert a' U)"
       
  6527              and spanU: "span (insert a' S \<union> U) = span (insert a' S \<union> T)"
       
  6528     by (rule exE [OF insert.IH [of "insert a' S"]])
       
  6529       (auto simp: Gram_Schmidt_step a'_def insert.prems orthogonal_commute
       
  6530         pairwise_orthogonal_insert span_clauses)
       
  6531   have orthS: "\<And>x. x \<in> S \<Longrightarrow> a' \<bullet> x = 0"
       
  6532     apply (simp add: a'_def)
       
  6533     using Gram_Schmidt_step [OF \<open>pairwise orthogonal S\<close>]
       
  6534     apply (force simp: orthogonal_def inner_commute span_superset [THEN subsetD])
       
  6535     done
       
  6536   have "span (S \<union> insert a' U) = span (insert a' (S \<union> T))"
       
  6537     using spanU by simp
       
  6538   also have "... = span (insert a (S \<union> T))"
       
  6539     apply (rule eq_span_insert_eq)
       
  6540     apply (simp add: a'_def span_neg span_sum span_base span_mul)
       
  6541     done
       
  6542   also have "... = span (S \<union> insert a T)"
       
  6543     by simp
       
  6544   finally show ?case
       
  6545     by (rule_tac x="insert a' U" in exI) (use orthU in auto)
       
  6546 qed
       
  6547 
       
  6548 
       
  6549 proposition orthogonal_extension:
       
  6550   fixes S :: "'a::euclidean_space set"
       
  6551   assumes S: "pairwise orthogonal S"
       
  6552   obtains U where "pairwise orthogonal (S \<union> U)" "span (S \<union> U) = span (S \<union> T)"
       
  6553 proof -
       
  6554   obtain B where "finite B" "span B = span T"
       
  6555     using basis_subspace_exists [of "span T"] subspace_span by metis
       
  6556   with orthogonal_extension_aux [of B S]
       
  6557   obtain U where "pairwise orthogonal (S \<union> U)" "span (S \<union> U) = span (S \<union> B)"
       
  6558     using assms pairwise_orthogonal_imp_finite by auto
       
  6559   with \<open>span B = span T\<close> show ?thesis
       
  6560     by (rule_tac U=U in that) (auto simp: span_Un)
       
  6561 qed
       
  6562 
       
  6563 corollary%unimportant orthogonal_extension_strong:
       
  6564   fixes S :: "'a::euclidean_space set"
       
  6565   assumes S: "pairwise orthogonal S"
       
  6566   obtains U where "U \<inter> (insert 0 S) = {}" "pairwise orthogonal (S \<union> U)"
       
  6567                   "span (S \<union> U) = span (S \<union> T)"
       
  6568 proof -
       
  6569   obtain U where "pairwise orthogonal (S \<union> U)" "span (S \<union> U) = span (S \<union> T)"
       
  6570     using orthogonal_extension assms by blast
       
  6571   then show ?thesis
       
  6572     apply (rule_tac U = "U - (insert 0 S)" in that)
       
  6573       apply blast
       
  6574      apply (force simp: pairwise_def)
       
  6575     apply (metis Un_Diff_cancel Un_insert_left span_redundant span_zero)
       
  6576     done
       
  6577 qed
       
  6578 
       
  6579 subsection\<open>Decomposing a vector into parts in orthogonal subspaces\<close>
       
  6580 
       
  6581 text\<open>existence of orthonormal basis for a subspace.\<close>
       
  6582 
       
  6583 lemma orthogonal_spanningset_subspace:
       
  6584   fixes S :: "'a :: euclidean_space set"
       
  6585   assumes "subspace S"
       
  6586   obtains B where "B \<subseteq> S" "pairwise orthogonal B" "span B = S"
       
  6587 proof -
       
  6588   obtain B where "B \<subseteq> S" "independent B" "S \<subseteq> span B" "card B = dim S"
       
  6589     using basis_exists by blast
       
  6590   with orthogonal_extension [of "{}" B]
       
  6591   show ?thesis
       
  6592     by (metis Un_empty_left assms pairwise_empty span_superset span_subspace that)
       
  6593 qed
       
  6594 
       
  6595 lemma orthogonal_basis_subspace:
       
  6596   fixes S :: "'a :: euclidean_space set"
       
  6597   assumes "subspace S"
       
  6598   obtains B where "0 \<notin> B" "B \<subseteq> S" "pairwise orthogonal B" "independent B"
       
  6599                   "card B = dim S" "span B = S"
       
  6600 proof -
       
  6601   obtain B where "B \<subseteq> S" "pairwise orthogonal B" "span B = S"
       
  6602     using assms orthogonal_spanningset_subspace by blast
       
  6603   then show ?thesis
       
  6604     apply (rule_tac B = "B - {0}" in that)
       
  6605     apply (auto simp: indep_card_eq_dim_span pairwise_subset pairwise_orthogonal_independent elim: pairwise_subset)
       
  6606     done
       
  6607 qed
       
  6608 
       
  6609 proposition orthonormal_basis_subspace:
       
  6610   fixes S :: "'a :: euclidean_space set"
       
  6611   assumes "subspace S"
       
  6612   obtains B where "B \<subseteq> S" "pairwise orthogonal B"
       
  6613               and "\<And>x. x \<in> B \<Longrightarrow> norm x = 1"
       
  6614               and "independent B" "card B = dim S" "span B = S"
       
  6615 proof -
       
  6616   obtain B where "0 \<notin> B" "B \<subseteq> S"
       
  6617              and orth: "pairwise orthogonal B"
       
  6618              and "independent B" "card B = dim S" "span B = S"
       
  6619     by (blast intro: orthogonal_basis_subspace [OF assms])
       
  6620   have 1: "(\<lambda>x. x /\<^sub>R norm x) ` B \<subseteq> S"
       
  6621     using \<open>span B = S\<close> span_superset span_mul by fastforce
       
  6622   have 2: "pairwise orthogonal ((\<lambda>x. x /\<^sub>R norm x) ` B)"
       
  6623     using orth by (force simp: pairwise_def orthogonal_clauses)
       
  6624   have 3: "\<And>x. x \<in> (\<lambda>x. x /\<^sub>R norm x) ` B \<Longrightarrow> norm x = 1"
       
  6625     by (metis (no_types, lifting) \<open>0 \<notin> B\<close> image_iff norm_sgn sgn_div_norm)
       
  6626   have 4: "independent ((\<lambda>x. x /\<^sub>R norm x) ` B)"
       
  6627     by (metis "2" "3" norm_zero pairwise_orthogonal_independent zero_neq_one)
       
  6628   have "inj_on (\<lambda>x. x /\<^sub>R norm x) B"
       
  6629   proof
       
  6630     fix x y
       
  6631     assume "x \<in> B" "y \<in> B" "x /\<^sub>R norm x = y /\<^sub>R norm y"
       
  6632     moreover have "\<And>i. i \<in> B \<Longrightarrow> norm (i /\<^sub>R norm i) = 1"
       
  6633       using 3 by blast
       
  6634     ultimately show "x = y"
       
  6635       by (metis norm_eq_1 orth orthogonal_clauses(7) orthogonal_commute orthogonal_def pairwise_def zero_neq_one)
       
  6636   qed
       
  6637   then have 5: "card ((\<lambda>x. x /\<^sub>R norm x) ` B) = dim S"
       
  6638     by (metis \<open>card B = dim S\<close> card_image)
       
  6639   have 6: "span ((\<lambda>x. x /\<^sub>R norm x) ` B) = S"
       
  6640     by (metis "1" "4" "5" assms card_eq_dim independent_finite span_subspace)
       
  6641   show ?thesis
       
  6642     by (rule that [OF 1 2 3 4 5 6])
       
  6643 qed
       
  6644 
       
  6645 
       
  6646 proposition%unimportant orthogonal_to_subspace_exists_gen:
       
  6647   fixes S :: "'a :: euclidean_space set"
       
  6648   assumes "span S \<subset> span T"
       
  6649   obtains x where "x \<noteq> 0" "x \<in> span T" "\<And>y. y \<in> span S \<Longrightarrow> orthogonal x y"
       
  6650 proof -
       
  6651   obtain B where "B \<subseteq> span S" and orthB: "pairwise orthogonal B"
       
  6652              and "\<And>x. x \<in> B \<Longrightarrow> norm x = 1"
       
  6653              and "independent B" "card B = dim S" "span B = span S"
       
  6654     by (rule orthonormal_basis_subspace [of "span S", OF subspace_span])
       
  6655       (auto simp: dim_span)
       
  6656   with assms obtain u where spanBT: "span B \<subseteq> span T" and "u \<notin> span B" "u \<in> span T"
       
  6657     by auto
       
  6658   obtain C where orthBC: "pairwise orthogonal (B \<union> C)" and spanBC: "span (B \<union> C) = span (B \<union> {u})"
       
  6659     by (blast intro: orthogonal_extension [OF orthB])
       
  6660   show thesis
       
  6661   proof (cases "C \<subseteq> insert 0 B")
       
  6662     case True
       
  6663     then have "C \<subseteq> span B"
       
  6664       using span_eq
       
  6665       by (metis span_insert_0 subset_trans)
       
  6666     moreover have "u \<in> span (B \<union> C)"
       
  6667       using \<open>span (B \<union> C) = span (B \<union> {u})\<close> span_superset by force
       
  6668     ultimately show ?thesis
       
  6669       using True \<open>u \<notin> span B\<close>
       
  6670       by (metis Un_insert_left span_insert_0 sup.orderE)
       
  6671   next
       
  6672     case False
       
  6673     then obtain x where "x \<in> C" "x \<noteq> 0" "x \<notin> B"
       
  6674       by blast
       
  6675     then have "x \<in> span T"
       
  6676       by (metis (no_types, lifting) Un_insert_right Un_upper2 \<open>u \<in> span T\<close> spanBT spanBC
       
  6677           \<open>u \<in> span T\<close> insert_subset span_superset span_mono
       
  6678           span_span subsetCE subset_trans sup_bot.comm_neutral)
       
  6679     moreover have "orthogonal x y" if "y \<in> span B" for y
       
  6680       using that
       
  6681     proof (rule span_induct)
       
  6682       show "subspace {a. orthogonal x a}"
       
  6683         by (simp add: subspace_orthogonal_to_vector)
       
  6684       show "\<And>b. b \<in> B \<Longrightarrow> orthogonal x b"
       
  6685         by (metis Un_iff \<open>x \<in> C\<close> \<open>x \<notin> B\<close> orthBC pairwise_def)
       
  6686     qed
       
  6687     ultimately show ?thesis
       
  6688       using \<open>x \<noteq> 0\<close> that \<open>span B = span S\<close> by auto
       
  6689   qed
       
  6690 qed
       
  6691 
       
  6692 corollary%unimportant orthogonal_to_subspace_exists:
       
  6693   fixes S :: "'a :: euclidean_space set"
       
  6694   assumes "dim S < DIM('a)"
       
  6695   obtains x where "x \<noteq> 0" "\<And>y. y \<in> span S \<Longrightarrow> orthogonal x y"
       
  6696 proof -
       
  6697 have "span S \<subset> UNIV"
       
  6698   by (metis (mono_tags) UNIV_I assms inner_eq_zero_iff less_le lowdim_subset_hyperplane
       
  6699       mem_Collect_eq top.extremum_strict top.not_eq_extremum)
       
  6700   with orthogonal_to_subspace_exists_gen [of S UNIV] that show ?thesis
       
  6701     by (auto simp: span_UNIV)
       
  6702 qed
       
  6703 
       
  6704 corollary%unimportant orthogonal_to_vector_exists:
       
  6705   fixes x :: "'a :: euclidean_space"
       
  6706   assumes "2 \<le> DIM('a)"
       
  6707   obtains y where "y \<noteq> 0" "orthogonal x y"
       
  6708 proof -
       
  6709   have "dim {x} < DIM('a)"
       
  6710     using assms by auto
       
  6711   then show thesis
       
  6712     by (rule orthogonal_to_subspace_exists) (simp add: orthogonal_commute span_base that)
       
  6713 qed
       
  6714 
       
  6715 proposition%unimportant orthogonal_subspace_decomp_exists:
       
  6716   fixes S :: "'a :: euclidean_space set"
       
  6717   obtains y z
       
  6718   where "y \<in> span S"
       
  6719     and "\<And>w. w \<in> span S \<Longrightarrow> orthogonal z w"
       
  6720     and "x = y + z"
       
  6721 proof -
       
  6722   obtain T where "0 \<notin> T" "T \<subseteq> span S" "pairwise orthogonal T" "independent T"
       
  6723     "card T = dim (span S)" "span T = span S"
       
  6724     using orthogonal_basis_subspace subspace_span by blast
       
  6725   let ?a = "\<Sum>b\<in>T. (b \<bullet> x / (b \<bullet> b)) *\<^sub>R b"
       
  6726   have orth: "orthogonal (x - ?a) w" if "w \<in> span S" for w
       
  6727     by (simp add: Gram_Schmidt_step \<open>pairwise orthogonal T\<close> \<open>span T = span S\<close>
       
  6728         orthogonal_commute that)
       
  6729   show ?thesis
       
  6730     apply (rule_tac y = "?a" and z = "x - ?a" in that)
       
  6731       apply (meson \<open>T \<subseteq> span S\<close> span_scale span_sum subsetCE)
       
  6732      apply (fact orth, simp)
       
  6733     done
       
  6734 qed
       
  6735 
       
  6736 lemma orthogonal_subspace_decomp_unique:
       
  6737   fixes S :: "'a :: euclidean_space set"
       
  6738   assumes "x + y = x' + y'"
       
  6739       and ST: "x \<in> span S" "x' \<in> span S" "y \<in> span T" "y' \<in> span T"
       
  6740       and orth: "\<And>a b. \<lbrakk>a \<in> S; b \<in> T\<rbrakk> \<Longrightarrow> orthogonal a b"
       
  6741   shows "x = x' \<and> y = y'"
       
  6742 proof -
       
  6743   have "x + y - y' = x'"
       
  6744     by (simp add: assms)
       
  6745   moreover have "\<And>a b. \<lbrakk>a \<in> span S; b \<in> span T\<rbrakk> \<Longrightarrow> orthogonal a b"
       
  6746     by (meson orth orthogonal_commute orthogonal_to_span)
       
  6747   ultimately have "0 = x' - x"
       
  6748     by (metis (full_types) add_diff_cancel_left' ST diff_right_commute orthogonal_clauses(10) orthogonal_clauses(5) orthogonal_self)
       
  6749   with assms show ?thesis by auto
       
  6750 qed
       
  6751 
       
  6752 lemma vector_in_orthogonal_spanningset:
       
  6753   fixes a :: "'a::euclidean_space"
       
  6754   obtains S where "a \<in> S" "pairwise orthogonal S" "span S = UNIV"
       
  6755   by (metis UNIV_I Un_iff empty_iff insert_subset orthogonal_extension pairwise_def
       
  6756       pairwise_orthogonal_insert span_UNIV subsetI subset_antisym)
       
  6757 
       
  6758 lemma vector_in_orthogonal_basis:
       
  6759   fixes a :: "'a::euclidean_space"
       
  6760   assumes "a \<noteq> 0"
       
  6761   obtains S where "a \<in> S" "0 \<notin> S" "pairwise orthogonal S" "independent S" "finite S"
       
  6762                   "span S = UNIV" "card S = DIM('a)"
       
  6763 proof -
       
  6764   obtain S where S: "a \<in> S" "pairwise orthogonal S" "span S = UNIV"
       
  6765     using vector_in_orthogonal_spanningset .
       
  6766   show thesis
       
  6767   proof
       
  6768     show "pairwise orthogonal (S - {0})"
       
  6769       using pairwise_mono S(2) by blast
       
  6770     show "independent (S - {0})"
       
  6771       by (simp add: \<open>pairwise orthogonal (S - {0})\<close> pairwise_orthogonal_independent)
       
  6772     show "finite (S - {0})"
       
  6773       using \<open>independent (S - {0})\<close> independent_finite by blast
       
  6774     show "card (S - {0}) = DIM('a)"
       
  6775       using span_delete_0 [of S] S
       
  6776       by (simp add: \<open>independent (S - {0})\<close> indep_card_eq_dim_span dim_UNIV)
       
  6777   qed (use S \<open>a \<noteq> 0\<close> in auto)
       
  6778 qed
       
  6779 
       
  6780 lemma vector_in_orthonormal_basis:
       
  6781   fixes a :: "'a::euclidean_space"
       
  6782   assumes "norm a = 1"
       
  6783   obtains S where "a \<in> S" "pairwise orthogonal S" "\<And>x. x \<in> S \<Longrightarrow> norm x = 1"
       
  6784     "independent S" "card S = DIM('a)" "span S = UNIV"
       
  6785 proof -
       
  6786   have "a \<noteq> 0"
       
  6787     using assms by auto
       
  6788   then obtain S where "a \<in> S" "0 \<notin> S" "finite S"
       
  6789           and S: "pairwise orthogonal S" "independent S" "span S = UNIV" "card S = DIM('a)"
       
  6790     by (metis vector_in_orthogonal_basis)
       
  6791   let ?S = "(\<lambda>x. x /\<^sub>R norm x) ` S"
       
  6792   show thesis
       
  6793   proof
       
  6794     show "a \<in> ?S"
       
  6795       using \<open>a \<in> S\<close> assms image_iff by fastforce
       
  6796   next
       
  6797     show "pairwise orthogonal ?S"
       
  6798       using \<open>pairwise orthogonal S\<close> by (auto simp: pairwise_def orthogonal_def)
       
  6799     show "\<And>x. x \<in> (\<lambda>x. x /\<^sub>R norm x) ` S \<Longrightarrow> norm x = 1"
       
  6800       using \<open>0 \<notin> S\<close> by (auto simp: divide_simps)
       
  6801     then show "independent ?S"
       
  6802       by (metis \<open>pairwise orthogonal ((\<lambda>x. x /\<^sub>R norm x) ` S)\<close> norm_zero pairwise_orthogonal_independent zero_neq_one)
       
  6803     have "inj_on (\<lambda>x. x /\<^sub>R norm x) S"
       
  6804       unfolding inj_on_def
       
  6805       by (metis (full_types) S(1) \<open>0 \<notin> S\<close> inverse_nonzero_iff_nonzero norm_eq_zero orthogonal_scaleR orthogonal_self pairwise_def)
       
  6806     then show "card ?S = DIM('a)"
       
  6807       by (simp add: card_image S)
       
  6808     show "span ?S = UNIV"
       
  6809       by (metis (no_types) \<open>0 \<notin> S\<close> \<open>finite S\<close> \<open>span S = UNIV\<close>
       
  6810           field_class.field_inverse_zero inverse_inverse_eq less_irrefl span_image_scale
       
  6811           zero_less_norm_iff)
       
  6812   qed
       
  6813 qed
       
  6814 
       
  6815 proposition dim_orthogonal_sum:
       
  6816   fixes A :: "'a::euclidean_space set"
       
  6817   assumes "\<And>x y. \<lbrakk>x \<in> A; y \<in> B\<rbrakk> \<Longrightarrow> x \<bullet> y = 0"
       
  6818     shows "dim(A \<union> B) = dim A + dim B"
       
  6819 proof -
       
  6820   have 1: "\<And>x y. \<lbrakk>x \<in> span A; y \<in> B\<rbrakk> \<Longrightarrow> x \<bullet> y = 0"
       
  6821     by (erule span_induct [OF _ subspace_hyperplane2]; simp add: assms)
       
  6822   have "\<And>x y. \<lbrakk>x \<in> span A; y \<in> span B\<rbrakk> \<Longrightarrow> x \<bullet> y = 0"
       
  6823     using 1 by (simp add: span_induct [OF _ subspace_hyperplane])
       
  6824   then have 0: "\<And>x y. \<lbrakk>x \<in> span A; y \<in> span B\<rbrakk> \<Longrightarrow> x \<bullet> y = 0"
       
  6825     by simp
       
  6826   have "dim(A \<union> B) = dim (span (A \<union> B))"
       
  6827     by (simp add: dim_span)
       
  6828   also have "span (A \<union> B) = ((\<lambda>(a, b). a + b) ` (span A \<times> span B))"
       
  6829     by (auto simp add: span_Un image_def)
       
  6830   also have "dim \<dots> = dim {x + y |x y. x \<in> span A \<and> y \<in> span B}"
       
  6831     by (auto intro!: arg_cong [where f=dim])
       
  6832   also have "... = dim {x + y |x y. x \<in> span A \<and> y \<in> span B} + dim(span A \<inter> span B)"
       
  6833     by (auto simp: dest: 0)
       
  6834   also have "... = dim (span A) + dim (span B)"
       
  6835     by (rule dim_sums_Int) (auto simp: subspace_span)
       
  6836   also have "... = dim A + dim B"
       
  6837     by (simp add: dim_span)
       
  6838   finally show ?thesis .
       
  6839 qed
       
  6840 
       
  6841 lemma dim_subspace_orthogonal_to_vectors:
       
  6842   fixes A :: "'a::euclidean_space set"
       
  6843   assumes "subspace A" "subspace B" "A \<subseteq> B"
       
  6844     shows "dim {y \<in> B. \<forall>x \<in> A. orthogonal x y} + dim A = dim B"
       
  6845 proof -
       
  6846   have "dim (span ({y \<in> B. \<forall>x\<in>A. orthogonal x y} \<union> A)) = dim (span B)"
       
  6847   proof (rule arg_cong [where f=dim, OF subset_antisym])
       
  6848     show "span ({y \<in> B. \<forall>x\<in>A. orthogonal x y} \<union> A) \<subseteq> span B"
       
  6849       by (simp add: \<open>A \<subseteq> B\<close> Collect_restrict span_mono)
       
  6850   next
       
  6851     have *: "x \<in> span ({y \<in> B. \<forall>x\<in>A. orthogonal x y} \<union> A)"
       
  6852          if "x \<in> B" for x
       
  6853     proof -
       
  6854       obtain y z where "x = y + z" "y \<in> span A" and orth: "\<And>w. w \<in> span A \<Longrightarrow> orthogonal z w"
       
  6855         using orthogonal_subspace_decomp_exists [of A x] that by auto
       
  6856       have "y \<in> span B"
       
  6857         using \<open>y \<in> span A\<close> assms(3) span_mono by blast
       
  6858       then have "z \<in> {a \<in> B. \<forall>x. x \<in> A \<longrightarrow> orthogonal x a}"
       
  6859         apply simp
       
  6860         using \<open>x = y + z\<close> assms(1) assms(2) orth orthogonal_commute span_add_eq
       
  6861           span_eq_iff that by blast
       
  6862       then have z: "z \<in> span {y \<in> B. \<forall>x\<in>A. orthogonal x y}"
       
  6863         by (meson span_superset subset_iff)
       
  6864       then show ?thesis
       
  6865         apply (auto simp: span_Un image_def  \<open>x = y + z\<close> \<open>y \<in> span A\<close>)
       
  6866         using \<open>y \<in> span A\<close> add.commute by blast
       
  6867     qed
       
  6868     show "span B \<subseteq> span ({y \<in> B. \<forall>x\<in>A. orthogonal x y} \<union> A)"
       
  6869       by (rule span_minimal)
       
  6870         (auto intro: * span_minimal simp: subspace_span)
       
  6871   qed
       
  6872   then show ?thesis
       
  6873     by (metis (no_types, lifting) dim_orthogonal_sum dim_span mem_Collect_eq
       
  6874         orthogonal_commute orthogonal_def)
       
  6875 qed
       
  6876 
       
  6877 lemma aff_dim_openin:
  6342 lemma aff_dim_openin:
  6878   fixes S :: "'a::euclidean_space set"
  6343   fixes S :: "'a::euclidean_space set"
  6879   assumes ope: "openin (subtopology euclidean T) S" and "affine T" "S \<noteq> {}"
  6344   assumes ope: "openin (subtopology euclidean T) S" and "affine T" "S \<noteq> {}"
  6880   shows "aff_dim S = aff_dim T"
  6345   shows "aff_dim S = aff_dim T"
  6881 proof -
  6346 proof -