src/HOL/Multivariate_Analysis/Euclidean_Space.thy
changeset 35150 082fa4bd403d
parent 35043 07dbdf60d5ad
child 35172 579dd5570f96
equal deleted inserted replaced
35138:ad213c602ec1 35150:082fa4bd403d
  2027 
  2027 
  2028 definition vector_matrix_mult :: "'a ^ 'm \<Rightarrow> ('a::semiring_1) ^'n^'m \<Rightarrow> 'a ^'n "  (infixl "v*" 70)
  2028 definition vector_matrix_mult :: "'a ^ 'm \<Rightarrow> ('a::semiring_1) ^'n^'m \<Rightarrow> 'a ^'n "  (infixl "v*" 70)
  2029   where "v v* m == (\<chi> j. setsum (\<lambda>i. ((m$i)$j) * (v$i)) (UNIV :: 'm set)) :: 'a^'n"
  2029   where "v v* m == (\<chi> j. setsum (\<lambda>i. ((m$i)$j) * (v$i)) (UNIV :: 'm set)) :: 'a^'n"
  2030 
  2030 
  2031 definition "(mat::'a::zero => 'a ^'n^'n) k = (\<chi> i j. if i = j then k else 0)"
  2031 definition "(mat::'a::zero => 'a ^'n^'n) k = (\<chi> i j. if i = j then k else 0)"
  2032 definition "(transp::'a^'n^'m \<Rightarrow> 'a^'m^'n) A = (\<chi> i j. ((A$j)$i))"
  2032 definition transpose where 
       
  2033   "(transpose::'a^'n^'m \<Rightarrow> 'a^'m^'n) A = (\<chi> i j. ((A$j)$i))"
  2033 definition "(row::'m => 'a ^'n^'m \<Rightarrow> 'a ^'n) i A = (\<chi> j. ((A$i)$j))"
  2034 definition "(row::'m => 'a ^'n^'m \<Rightarrow> 'a ^'n) i A = (\<chi> j. ((A$i)$j))"
  2034 definition "(column::'n =>'a^'n^'m =>'a^'m) j A = (\<chi> i. ((A$i)$j))"
  2035 definition "(column::'n =>'a^'n^'m =>'a^'m) j A = (\<chi> i. ((A$i)$j))"
  2035 definition "rows(A::'a^'n^'m) = { row i A | i. i \<in> (UNIV :: 'm set)}"
  2036 definition "rows(A::'a^'n^'m) = { row i A | i. i \<in> (UNIV :: 'm set)}"
  2036 definition "columns(A::'a^'n^'m) = { column i A | i. i \<in> (UNIV :: 'n set)}"
  2037 definition "columns(A::'a^'n^'m) = { column i A | i. i \<in> (UNIV :: 'n set)}"
  2037 
  2038 
  2069 lemma matrix_vector_mul_lid: "mat 1 *v x = (x::'a::semiring_1 ^ 'n)"
  2070 lemma matrix_vector_mul_lid: "mat 1 *v x = (x::'a::semiring_1 ^ 'n)"
  2070   apply (vector matrix_vector_mult_def mat_def)
  2071   apply (vector matrix_vector_mult_def mat_def)
  2071   by (simp add: cond_value_iff cond_application_beta
  2072   by (simp add: cond_value_iff cond_application_beta
  2072     setsum_delta' cong del: if_weak_cong)
  2073     setsum_delta' cong del: if_weak_cong)
  2073 
  2074 
  2074 lemma matrix_transp_mul: "transp(A ** B) = transp B ** transp (A::'a::comm_semiring_1^_^_)"
  2075 lemma matrix_transpose_mul: "transpose(A ** B) = transpose B ** transpose (A::'a::comm_semiring_1^_^_)"
  2075   by (simp add: matrix_matrix_mult_def transp_def Cart_eq mult_commute)
  2076   by (simp add: matrix_matrix_mult_def transpose_def Cart_eq mult_commute)
  2076 
  2077 
  2077 lemma matrix_eq:
  2078 lemma matrix_eq:
  2078   fixes A B :: "'a::semiring_1 ^ 'n ^ 'm"
  2079   fixes A B :: "'a::semiring_1 ^ 'n ^ 'm"
  2079   shows "A = B \<longleftrightarrow>  (\<forall>x. A *v x = B *v x)" (is "?lhs \<longleftrightarrow> ?rhs")
  2080   shows "A = B \<longleftrightarrow>  (\<forall>x. A *v x = B *v x)" (is "?lhs \<longleftrightarrow> ?rhs")
  2080   apply auto
  2081   apply auto
  2092 lemma dot_lmul_matrix: "((x::'a::comm_semiring_1 ^_) v* A) \<bullet> y = x \<bullet> (A *v y)"
  2093 lemma dot_lmul_matrix: "((x::'a::comm_semiring_1 ^_) v* A) \<bullet> y = x \<bullet> (A *v y)"
  2093   apply (simp add: dot_def matrix_vector_mult_def vector_matrix_mult_def setsum_left_distrib setsum_right_distrib mult_ac)
  2094   apply (simp add: dot_def matrix_vector_mult_def vector_matrix_mult_def setsum_left_distrib setsum_right_distrib mult_ac)
  2094   apply (subst setsum_commute)
  2095   apply (subst setsum_commute)
  2095   by simp
  2096   by simp
  2096 
  2097 
  2097 lemma transp_mat: "transp (mat n) = mat n"
  2098 lemma transpose_mat: "transpose (mat n) = mat n"
  2098   by (vector transp_def mat_def)
  2099   by (vector transpose_def mat_def)
  2099 
  2100 
  2100 lemma transp_transp: "transp(transp A) = A"
  2101 lemma transpose_transpose: "transpose(transpose A) = A"
  2101   by (vector transp_def)
  2102   by (vector transpose_def)
  2102 
  2103 
  2103 lemma row_transp:
  2104 lemma row_transpose:
  2104   fixes A:: "'a::semiring_1^_^_"
  2105   fixes A:: "'a::semiring_1^_^_"
  2105   shows "row i (transp A) = column i A"
  2106   shows "row i (transpose A) = column i A"
  2106   by (simp add: row_def column_def transp_def Cart_eq)
  2107   by (simp add: row_def column_def transpose_def Cart_eq)
  2107 
  2108 
  2108 lemma column_transp:
  2109 lemma column_transpose:
  2109   fixes A:: "'a::semiring_1^_^_"
  2110   fixes A:: "'a::semiring_1^_^_"
  2110   shows "column i (transp A) = row i A"
  2111   shows "column i (transpose A) = row i A"
  2111   by (simp add: row_def column_def transp_def Cart_eq)
  2112   by (simp add: row_def column_def transpose_def Cart_eq)
  2112 
  2113 
  2113 lemma rows_transp: "rows(transp (A::'a::semiring_1^_^_)) = columns A"
  2114 lemma rows_transpose: "rows(transpose (A::'a::semiring_1^_^_)) = columns A"
  2114 by (auto simp add: rows_def columns_def row_transp intro: set_ext)
  2115 by (auto simp add: rows_def columns_def row_transpose intro: set_ext)
  2115 
  2116 
  2116 lemma columns_transp: "columns(transp (A::'a::semiring_1^_^_)) = rows A" by (metis transp_transp rows_transp)
  2117 lemma columns_transpose: "columns(transpose (A::'a::semiring_1^_^_)) = rows A" by (metis transpose_transpose rows_transpose)
  2117 
  2118 
  2118 text{* Two sometimes fruitful ways of looking at matrix-vector multiplication. *}
  2119 text{* Two sometimes fruitful ways of looking at matrix-vector multiplication. *}
  2119 
  2120 
  2120 lemma matrix_mult_dot: "A *v x = (\<chi> i. A$i \<bullet> x)"
  2121 lemma matrix_mult_dot: "A *v x = (\<chi> i. A$i \<bullet> x)"
  2121   by (simp add: matrix_vector_mult_def dot_def)
  2122   by (simp add: matrix_vector_mult_def dot_def)
  2174   and lg: "linear (g::'a::comm_ring_1^'m \<Rightarrow> 'a^_)"
  2175   and lg: "linear (g::'a::comm_ring_1^'m \<Rightarrow> 'a^_)"
  2175   shows "matrix (g o f) = matrix g ** matrix f"
  2176   shows "matrix (g o f) = matrix g ** matrix f"
  2176   using lf lg linear_compose[OF lf lg] matrix_works[OF linear_compose[OF lf lg]]
  2177   using lf lg linear_compose[OF lf lg] matrix_works[OF linear_compose[OF lf lg]]
  2177   by (simp  add: matrix_eq matrix_works matrix_vector_mul_assoc[symmetric] o_def)
  2178   by (simp  add: matrix_eq matrix_works matrix_vector_mul_assoc[symmetric] o_def)
  2178 
  2179 
  2179 lemma matrix_vector_column:"(A::'a::comm_semiring_1^'n^_) *v x = setsum (\<lambda>i. (x$i) *s ((transp A)$i)) (UNIV:: 'n set)"
  2180 lemma matrix_vector_column:"(A::'a::comm_semiring_1^'n^_) *v x = setsum (\<lambda>i. (x$i) *s ((transpose A)$i)) (UNIV:: 'n set)"
  2180   by (simp add: matrix_vector_mult_def transp_def Cart_eq mult_commute)
  2181   by (simp add: matrix_vector_mult_def transpose_def Cart_eq mult_commute)
  2181 
  2182 
  2182 lemma adjoint_matrix: "adjoint(\<lambda>x. (A::'a::comm_ring_1^'n^'m) *v x) = (\<lambda>x. transp A *v x)"
  2183 lemma adjoint_matrix: "adjoint(\<lambda>x. (A::'a::comm_ring_1^'n^'m) *v x) = (\<lambda>x. transpose A *v x)"
  2183   apply (rule adjoint_unique[symmetric])
  2184   apply (rule adjoint_unique[symmetric])
  2184   apply (rule matrix_vector_mul_linear)
  2185   apply (rule matrix_vector_mul_linear)
  2185   apply (simp add: transp_def dot_def matrix_vector_mult_def setsum_left_distrib setsum_right_distrib)
  2186   apply (simp add: transpose_def dot_def matrix_vector_mult_def setsum_left_distrib setsum_right_distrib)
  2186   apply (subst setsum_commute)
  2187   apply (subst setsum_commute)
  2187   apply (auto simp add: mult_ac)
  2188   apply (auto simp add: mult_ac)
  2188   done
  2189   done
  2189 
  2190 
  2190 lemma matrix_adjoint: assumes lf: "linear (f :: 'a::comm_ring_1^'n \<Rightarrow> 'a ^'m)"
  2191 lemma matrix_adjoint: assumes lf: "linear (f :: 'a::comm_ring_1^'n \<Rightarrow> 'a ^'m)"
  2191   shows "matrix(adjoint f) = transp(matrix f)"
  2192   shows "matrix(adjoint f) = transpose(matrix f)"
  2192   apply (subst matrix_vector_mul[OF lf])
  2193   apply (subst matrix_vector_mul[OF lf])
  2193   unfolding adjoint_matrix matrix_of_matrix_vector_mul ..
  2194   unfolding adjoint_matrix matrix_of_matrix_vector_mul ..
  2194 
  2195 
  2195 subsection{* Interlude: Some properties of real sets *}
  2196 subsection{* Interlude: Some properties of real sets *}
  2196 
  2197 
  4315   from bilinear_eq[OF bf bg equalityD2[OF span_stdbasis] equalityD2[OF span_stdbasis] th] show ?thesis by (blast intro: ext)
  4316   from bilinear_eq[OF bf bg equalityD2[OF span_stdbasis] equalityD2[OF span_stdbasis] th] show ?thesis by (blast intro: ext)
  4316 qed
  4317 qed
  4317 
  4318 
  4318 (* Detailed theorems about left and right invertibility in general case.     *)
  4319 (* Detailed theorems about left and right invertibility in general case.     *)
  4319 
  4320 
  4320 lemma left_invertible_transp:
  4321 lemma left_invertible_transpose:
  4321   "(\<exists>(B). B ** transp (A) = mat (1::'a::comm_semiring_1)) \<longleftrightarrow> (\<exists>(B). A ** B = mat 1)"
  4322   "(\<exists>(B). B ** transpose (A) = mat (1::'a::comm_semiring_1)) \<longleftrightarrow> (\<exists>(B). A ** B = mat 1)"
  4322   by (metis matrix_transp_mul transp_mat transp_transp)
  4323   by (metis matrix_transpose_mul transpose_mat transpose_transpose)
  4323 
  4324 
  4324 lemma right_invertible_transp:
  4325 lemma right_invertible_transpose:
  4325   "(\<exists>(B). transp (A) ** B = mat (1::'a::comm_semiring_1)) \<longleftrightarrow> (\<exists>(B). B ** A = mat 1)"
  4326   "(\<exists>(B). transpose (A) ** B = mat (1::'a::comm_semiring_1)) \<longleftrightarrow> (\<exists>(B). B ** A = mat 1)"
  4326   by (metis matrix_transp_mul transp_mat transp_transp)
  4327   by (metis matrix_transpose_mul transpose_mat transpose_transpose)
  4327 
  4328 
  4328 lemma linear_injective_left_inverse:
  4329 lemma linear_injective_left_inverse:
  4329   assumes lf: "linear (f::real ^'n \<Rightarrow> real ^'m)" and fi: "inj f"
  4330   assumes lf: "linear (f::real ^'n \<Rightarrow> real ^'m)" and fi: "inj f"
  4330   shows "\<exists>g. linear g \<and> g o f = id"
  4331   shows "\<exists>g. linear g \<and> g o f = id"
  4331 proof-
  4332 proof-
  4436 qed
  4437 qed
  4437 
  4438 
  4438 lemma matrix_right_invertible_independent_rows:
  4439 lemma matrix_right_invertible_independent_rows:
  4439   fixes A :: "real^'n^'m"
  4440   fixes A :: "real^'n^'m"
  4440   shows "(\<exists>(B::real^'m^'n). A ** B = mat 1) \<longleftrightarrow> (\<forall>c. setsum (\<lambda>i. c i *s row i A) (UNIV :: 'm set) = 0 \<longrightarrow> (\<forall>i. c i = 0))"
  4441   shows "(\<exists>(B::real^'m^'n). A ** B = mat 1) \<longleftrightarrow> (\<forall>c. setsum (\<lambda>i. c i *s row i A) (UNIV :: 'm set) = 0 \<longrightarrow> (\<forall>i. c i = 0))"
  4441   unfolding left_invertible_transp[symmetric]
  4442   unfolding left_invertible_transpose[symmetric]
  4442     matrix_left_invertible_independent_columns
  4443     matrix_left_invertible_independent_columns
  4443   by (simp add: column_transp)
  4444   by (simp add: column_transpose)
  4444 
  4445 
  4445 lemma matrix_right_invertible_span_columns:
  4446 lemma matrix_right_invertible_span_columns:
  4446   "(\<exists>(B::real ^'n^'m). (A::real ^'m^'n) ** B = mat 1) \<longleftrightarrow> span (columns A) = UNIV" (is "?lhs = ?rhs")
  4447   "(\<exists>(B::real ^'n^'m). (A::real ^'m^'n) ** B = mat 1) \<longleftrightarrow> span (columns A) = UNIV" (is "?lhs = ?rhs")
  4447 proof-
  4448 proof-
  4448   let ?U = "UNIV :: 'm set"
  4449   let ?U = "UNIV :: 'm set"
  4504   ultimately show ?thesis by blast
  4505   ultimately show ?thesis by blast
  4505 qed
  4506 qed
  4506 
  4507 
  4507 lemma matrix_left_invertible_span_rows:
  4508 lemma matrix_left_invertible_span_rows:
  4508   "(\<exists>(B::real^'m^'n). B ** (A::real^'n^'m) = mat 1) \<longleftrightarrow> span (rows A) = UNIV"
  4509   "(\<exists>(B::real^'m^'n). B ** (A::real^'n^'m) = mat 1) \<longleftrightarrow> span (rows A) = UNIV"
  4509   unfolding right_invertible_transp[symmetric]
  4510   unfolding right_invertible_transpose[symmetric]
  4510   unfolding columns_transp[symmetric]
  4511   unfolding columns_transpose[symmetric]
  4511   unfolding matrix_right_invertible_span_columns
  4512   unfolding matrix_right_invertible_span_columns
  4512  ..
  4513  ..
  4513 
  4514 
  4514 (* An injective map real^'n->real^'n is also surjective.                       *)
  4515 (* An injective map real^'n->real^'n is also surjective.                       *)
  4515 
  4516 
  4726 
  4727 
  4727 definition "rowvector v = (\<chi> i j. (v$j))"
  4728 definition "rowvector v = (\<chi> i j. (v$j))"
  4728 
  4729 
  4729 definition "columnvector v = (\<chi> i j. (v$i))"
  4730 definition "columnvector v = (\<chi> i j. (v$i))"
  4730 
  4731 
  4731 lemma transp_columnvector:
  4732 lemma transpose_columnvector:
  4732  "transp(columnvector v) = rowvector v"
  4733  "transpose(columnvector v) = rowvector v"
  4733   by (simp add: transp_def rowvector_def columnvector_def Cart_eq)
  4734   by (simp add: transpose_def rowvector_def columnvector_def Cart_eq)
  4734 
  4735 
  4735 lemma transp_rowvector: "transp(rowvector v) = columnvector v"
  4736 lemma transpose_rowvector: "transpose(rowvector v) = columnvector v"
  4736   by (simp add: transp_def columnvector_def rowvector_def Cart_eq)
  4737   by (simp add: transpose_def columnvector_def rowvector_def Cart_eq)
  4737 
  4738 
  4738 lemma dot_rowvector_columnvector:
  4739 lemma dot_rowvector_columnvector:
  4739   "columnvector (A *v v) = A ** columnvector v"
  4740   "columnvector (A *v v) = A ** columnvector v"
  4740   by (vector columnvector_def matrix_matrix_mult_def matrix_vector_mult_def)
  4741   by (vector columnvector_def matrix_matrix_mult_def matrix_vector_mult_def)
  4741 
  4742 
  4743   by (vector matrix_matrix_mult_def rowvector_def columnvector_def dot_def)
  4744   by (vector matrix_matrix_mult_def rowvector_def columnvector_def dot_def)
  4744 
  4745 
  4745 lemma dot_matrix_vector_mul:
  4746 lemma dot_matrix_vector_mul:
  4746   fixes A B :: "real ^'n ^'n" and x y :: "real ^'n"
  4747   fixes A B :: "real ^'n ^'n" and x y :: "real ^'n"
  4747   shows "(A *v x) \<bullet> (B *v y) =
  4748   shows "(A *v x) \<bullet> (B *v y) =
  4748       (((rowvector x :: real^'n^1) ** ((transp A ** B) ** (columnvector y :: real ^1^'n)))$1)$1"
  4749       (((rowvector x :: real^'n^1) ** ((transpose A ** B) ** (columnvector y :: real ^1^'n)))$1)$1"
  4749 unfolding dot_matrix_product transp_columnvector[symmetric]
  4750 unfolding dot_matrix_product transpose_columnvector[symmetric]
  4750   dot_rowvector_columnvector matrix_transp_mul matrix_mul_assoc ..
  4751   dot_rowvector_columnvector matrix_transpose_mul matrix_mul_assoc ..
  4751 
  4752 
  4752 (* Infinity norm.                                                            *)
  4753 (* Infinity norm.                                                            *)
  4753 
  4754 
  4754 definition "infnorm (x::real^'n) = Sup {abs(x$i) |i. i\<in> (UNIV :: 'n set)}"
  4755 definition "infnorm (x::real^'n) = Sup {abs(x$i) |i. i\<in> (UNIV :: 'n set)}"
  4755 
  4756