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 |