524 "(transpose::'a^'n^'m \<Rightarrow> 'a^'m^'n) A = (\<chi> i j. ((A$j)$i))" |
528 "(transpose::'a^'n^'m \<Rightarrow> 'a^'m^'n) A = (\<chi> i j. ((A$j)$i))" |
525 definition "(row::'m => 'a ^'n^'m \<Rightarrow> 'a ^'n) i A = (\<chi> j. ((A$i)$j))" |
529 definition "(row::'m => 'a ^'n^'m \<Rightarrow> 'a ^'n) i A = (\<chi> j. ((A$i)$j))" |
526 definition "(column::'n =>'a^'n^'m =>'a^'m) j A = (\<chi> i. ((A$i)$j))" |
530 definition "(column::'n =>'a^'n^'m =>'a^'m) j A = (\<chi> i. ((A$i)$j))" |
527 definition "rows(A::'a^'n^'m) = { row i A | i. i \<in> (UNIV :: 'm set)}" |
531 definition "rows(A::'a^'n^'m) = { row i A | i. i \<in> (UNIV :: 'm set)}" |
528 definition "columns(A::'a^'n^'m) = { column i A | i. i \<in> (UNIV :: 'n set)}" |
532 definition "columns(A::'a^'n^'m) = { column i A | i. i \<in> (UNIV :: 'n set)}" |
|
533 |
|
534 lemma times0_left [simp]: "(0::'a::semiring_1^'n^'m) ** (A::'a ^'p^'n) = 0" |
|
535 by (simp add: matrix_matrix_mult_def zero_vec_def) |
|
536 |
|
537 lemma times0_right [simp]: "(A::'a::semiring_1^'n^'m) ** (0::'a ^'p^'n) = 0" |
|
538 by (simp add: matrix_matrix_mult_def zero_vec_def) |
529 |
539 |
530 lemma mat_0[simp]: "mat 0 = 0" by (vector mat_def) |
540 lemma mat_0[simp]: "mat 0 = 0" by (vector mat_def) |
531 lemma matrix_add_ldistrib: "(A ** (B + C)) = (A ** B) + (A ** C)" |
541 lemma matrix_add_ldistrib: "(A ** (B + C)) = (A ** B) + (A ** C)" |
532 by (vector matrix_matrix_mult_def sum.distrib[symmetric] field_simps) |
542 by (vector matrix_matrix_mult_def sum.distrib[symmetric] field_simps) |
533 |
543 |
559 apply (vector matrix_matrix_mult_def matrix_vector_mult_def |
569 apply (vector matrix_matrix_mult_def matrix_vector_mult_def |
560 sum_distrib_left sum_distrib_right mult.assoc) |
570 sum_distrib_left sum_distrib_right mult.assoc) |
561 apply (subst sum.swap) |
571 apply (subst sum.swap) |
562 apply simp |
572 apply simp |
563 done |
573 done |
|
574 |
|
575 lemma scalar_matrix_assoc: |
|
576 fixes A :: "real^'m^'n" |
|
577 shows "k *\<^sub>R (A ** B) = (k *\<^sub>R A) ** B" |
|
578 by (simp add: matrix_matrix_mult_def sum_distrib_left mult_ac vec_eq_iff) |
|
579 |
|
580 lemma matrix_scalar_ac: |
|
581 fixes A :: "real^'m^'n" |
|
582 shows "A ** (k *\<^sub>R B) = k *\<^sub>R A ** B" |
|
583 by (simp add: matrix_matrix_mult_def sum_distrib_left mult_ac vec_eq_iff) |
564 |
584 |
565 lemma matrix_vector_mul_lid [simp]: "mat 1 *v x = (x::'a::semiring_1 ^ 'n)" |
585 lemma matrix_vector_mul_lid [simp]: "mat 1 *v x = (x::'a::semiring_1 ^ 'n)" |
566 apply (vector matrix_vector_mult_def mat_def) |
586 apply (vector matrix_vector_mult_def mat_def) |
567 apply (simp add: if_distrib cond_application_beta sum.delta' cong del: if_weak_cong) |
587 apply (simp add: if_distrib cond_application_beta sum.delta' cong del: if_weak_cong) |
568 done |
588 done |
613 by (auto simp add: rows_def columns_def row_transpose intro: set_eqI) |
633 by (auto simp add: rows_def columns_def row_transpose intro: set_eqI) |
614 |
634 |
615 lemma columns_transpose [simp]: "columns(transpose (A::'a::semiring_1^_^_)) = rows A" |
635 lemma columns_transpose [simp]: "columns(transpose (A::'a::semiring_1^_^_)) = rows A" |
616 by (metis transpose_transpose rows_transpose) |
636 by (metis transpose_transpose rows_transpose) |
617 |
637 |
|
638 lemma transpose_scalar: "transpose (k *\<^sub>R A) = k *\<^sub>R transpose A" |
|
639 unfolding transpose_def |
|
640 by (simp add: vec_eq_iff) |
|
641 |
|
642 lemma transpose_iff [iff]: "transpose A = transpose B \<longleftrightarrow> A = B" |
|
643 by (metis transpose_transpose) |
|
644 |
618 lemma matrix_mult_transpose_dot_column: |
645 lemma matrix_mult_transpose_dot_column: |
619 fixes A :: "real^'n^'n" |
646 fixes A :: "real^'n^'n" |
620 shows "transpose A ** A = (\<chi> i j. (column i A) \<bullet> (column j A))" |
647 shows "transpose A ** A = (\<chi> i j. (column i A) \<bullet> (column j A))" |
621 by (simp add: matrix_matrix_mult_def vec_eq_iff transpose_def column_def inner_vec_def) |
648 by (simp add: matrix_matrix_mult_def vec_eq_iff transpose_def column_def inner_vec_def) |
622 |
649 |
759 lemma inj_matrix_vector_mult: |
786 lemma inj_matrix_vector_mult: |
760 fixes A::"'a::field^'n^'m" |
787 fixes A::"'a::field^'n^'m" |
761 assumes "invertible A" |
788 assumes "invertible A" |
762 shows "inj (( *v) A)" |
789 shows "inj (( *v) A)" |
763 by (metis assms inj_on_inverseI invertible_def matrix_vector_mul_assoc matrix_vector_mul_lid) |
790 by (metis assms inj_on_inverseI invertible_def matrix_vector_mul_assoc matrix_vector_mul_lid) |
|
791 |
|
792 lemma scalar_invertible: |
|
793 fixes A :: "real^'m^'n" |
|
794 assumes "k \<noteq> 0" and "invertible A" |
|
795 shows "invertible (k *\<^sub>R A)" |
|
796 proof - |
|
797 obtain A' where "A ** A' = mat 1" and "A' ** A = mat 1" |
|
798 using assms unfolding invertible_def by auto |
|
799 with `k \<noteq> 0` |
|
800 have "(k *\<^sub>R A) ** ((1/k) *\<^sub>R A') = mat 1" "((1/k) *\<^sub>R A') ** (k *\<^sub>R A) = mat 1" |
|
801 by (simp_all add: assms matrix_scalar_ac) |
|
802 thus "invertible (k *\<^sub>R A)" |
|
803 unfolding invertible_def by auto |
|
804 qed |
|
805 |
|
806 lemma scalar_invertible_iff: |
|
807 fixes A :: "real^'m^'n" |
|
808 assumes "k \<noteq> 0" and "invertible A" |
|
809 shows "invertible (k *\<^sub>R A) \<longleftrightarrow> k \<noteq> 0 \<and> invertible A" |
|
810 by (simp add: assms scalar_invertible) |
|
811 |
|
812 lemma vector_transpose_matrix [simp]: "x v* transpose A = A *v x" |
|
813 unfolding transpose_def vector_matrix_mult_def matrix_vector_mult_def |
|
814 by simp |
|
815 |
|
816 lemma transpose_matrix_vector [simp]: "transpose A *v x = x v* A" |
|
817 unfolding transpose_def vector_matrix_mult_def matrix_vector_mult_def |
|
818 by simp |
|
819 |
|
820 lemma vector_matrix_mul_rid: |
|
821 fixes v :: "('a::semiring_1)^'n" |
|
822 shows "v v* mat 1 = v" |
|
823 by (metis matrix_vector_mul_lid transpose_mat vector_transpose_matrix) |
|
824 |
|
825 lemma scalar_vector_matrix_assoc: |
|
826 fixes k :: real and x :: "real^'n" and A :: "real^'m^'n" |
|
827 shows "(k *\<^sub>R x) v* A = k *\<^sub>R (x v* A)" |
|
828 by (metis matrix_vector_mult_scaleR transpose_matrix_vector) |
|
829 |
|
830 lemma vector_scalar_matrix_ac: |
|
831 fixes k :: real and x :: "real^'n" and A :: "real^'m^'n" |
|
832 shows "x v* (k *\<^sub>R A) = k *\<^sub>R (x v* A)" |
|
833 proof - |
|
834 have "x v* (k *\<^sub>R A) = (k *\<^sub>R x) v* A" |
|
835 unfolding vector_matrix_mult_def |
|
836 by (simp add: algebra_simps) |
|
837 with scalar_vector_matrix_assoc |
|
838 show "x v* (k *\<^sub>R A) = k *\<^sub>R (x v* A)" |
|
839 by auto |
|
840 qed |
|
841 |
|
842 lemma vector_matrix_left_distrib: |
|
843 fixes x y :: "real^'n" and A :: "real^'m^'n" |
|
844 shows "(x + y) v* A = x v* A + y v* A" |
|
845 unfolding vector_matrix_mult_def |
|
846 by (simp add: algebra_simps sum.distrib vec_eq_iff) |
764 |
847 |
765 |
848 |
766 subsection\<open>Some bounds on components etc. relative to operator norm\<close> |
849 subsection\<open>Some bounds on components etc. relative to operator norm\<close> |
767 |
850 |
768 lemma norm_column_le_onorm: |
851 lemma norm_column_le_onorm: |
1073 shows "A ** A' = mat 1 \<longleftrightarrow> A' ** A = mat 1" |
1156 shows "A ** A' = mat 1 \<longleftrightarrow> A' ** A = mat 1" |
1074 proof - |
1157 proof - |
1075 { fix A A' :: "real ^'n^'n" |
1158 { fix A A' :: "real ^'n^'n" |
1076 assume AA': "A ** A' = mat 1" |
1159 assume AA': "A ** A' = mat 1" |
1077 have sA: "surj (( *v) A)" |
1160 have sA: "surj (( *v) A)" |
1078 unfolding surj_def |
1161 using AA' matrix_right_invertible_surjective by auto |
1079 apply clarify |
|
1080 apply (rule_tac x="(A' *v y)" in exI) |
|
1081 apply (simp add: matrix_vector_mul_assoc AA' matrix_vector_mul_lid) |
|
1082 done |
|
1083 from linear_surjective_isomorphism[OF matrix_vector_mul_linear sA] |
1162 from linear_surjective_isomorphism[OF matrix_vector_mul_linear sA] |
1084 obtain f' :: "real ^'n \<Rightarrow> real ^'n" |
1163 obtain f' :: "real ^'n \<Rightarrow> real ^'n" |
1085 where f': "linear f'" "\<forall>x. f' (A *v x) = x" "\<forall>x. A *v f' x = x" by blast |
1164 where f': "linear f'" "\<forall>x. f' (A *v x) = x" "\<forall>x. A *v f' x = x" by blast |
1086 have th: "matrix f' ** A = mat 1" |
1165 have th: "matrix f' ** A = mat 1" |
1087 by (simp add: matrix_eq matrix_works[OF f'(1)] |
1166 by (simp add: matrix_eq matrix_works[OF f'(1)] |
1092 hence "matrix f' ** A = A' ** A" by simp |
1171 hence "matrix f' ** A = A' ** A" by simp |
1093 hence "A' ** A = mat 1" by (simp add: th) |
1172 hence "A' ** A = mat 1" by (simp add: th) |
1094 } |
1173 } |
1095 then show ?thesis by blast |
1174 then show ?thesis by blast |
1096 qed |
1175 qed |
|
1176 |
|
1177 lemma invertible_mult: |
|
1178 fixes A B :: "real^'n^'n" |
|
1179 assumes "invertible A" and "invertible B" |
|
1180 shows "invertible (A ** B)" |
|
1181 by (metis (no_types, hide_lams) assms invertible_def matrix_left_right_inverse matrix_mul_assoc matrix_mul_lid) |
|
1182 |
|
1183 lemma transpose_invertible: |
|
1184 fixes A :: "real^'n^'n" |
|
1185 assumes "invertible A" |
|
1186 shows "invertible (transpose A)" |
|
1187 by (meson assms invertible_def matrix_left_right_inverse right_invertible_transpose) |
1097 |
1188 |
1098 text \<open>Considering an n-element vector as an n-by-1 or 1-by-n matrix.\<close> |
1189 text \<open>Considering an n-element vector as an n-by-1 or 1-by-n matrix.\<close> |
1099 |
1190 |
1100 definition "rowvector v = (\<chi> i j. (v$j))" |
1191 definition "rowvector v = (\<chi> i j. (v$j))" |
1101 |
1192 |