495 |
495 |
496 lemma mat_0[simp]: "mat 0 = 0" by (vector mat_def) |
496 lemma mat_0[simp]: "mat 0 = 0" by (vector mat_def) |
497 lemma matrix_add_ldistrib: "(A ** (B + C)) = (A ** B) + (A ** C)" |
497 lemma matrix_add_ldistrib: "(A ** (B + C)) = (A ** B) + (A ** C)" |
498 by (vector matrix_matrix_mult_def sum.distrib[symmetric] field_simps) |
498 by (vector matrix_matrix_mult_def sum.distrib[symmetric] field_simps) |
499 |
499 |
500 lemma matrix_mul_lid: |
500 lemma matrix_mul_lid [simp]: |
501 fixes A :: "'a::semiring_1 ^ 'm ^ 'n" |
501 fixes A :: "'a::semiring_1 ^ 'm ^ 'n" |
502 shows "mat 1 ** A = A" |
502 shows "mat 1 ** A = A" |
503 apply (simp add: matrix_matrix_mult_def mat_def) |
503 apply (simp add: matrix_matrix_mult_def mat_def) |
504 apply vector |
504 apply vector |
505 apply (auto simp only: if_distrib cond_application_beta sum.delta'[OF finite] |
505 apply (auto simp only: if_distrib cond_application_beta sum.delta'[OF finite] |
506 mult_1_left mult_zero_left if_True UNIV_I) |
506 mult_1_left mult_zero_left if_True UNIV_I) |
507 done |
507 done |
508 |
508 |
509 |
509 |
510 lemma matrix_mul_rid: |
510 lemma matrix_mul_rid [simp]: |
511 fixes A :: "'a::semiring_1 ^ 'm ^ 'n" |
511 fixes A :: "'a::semiring_1 ^ 'm ^ 'n" |
512 shows "A ** mat 1 = A" |
512 shows "A ** mat 1 = A" |
513 apply (simp add: matrix_matrix_mult_def mat_def) |
513 apply (simp add: matrix_matrix_mult_def mat_def) |
514 apply vector |
514 apply vector |
515 apply (auto simp only: if_distrib cond_application_beta sum.delta[OF finite] |
515 apply (auto simp only: if_distrib cond_application_beta sum.delta[OF finite] |
558 apply (simp add: inner_vec_def matrix_vector_mult_def vector_matrix_mult_def sum_distrib_right sum_distrib_left ac_simps) |
558 apply (simp add: inner_vec_def matrix_vector_mult_def vector_matrix_mult_def sum_distrib_right sum_distrib_left ac_simps) |
559 apply (subst sum.swap) |
559 apply (subst sum.swap) |
560 apply simp |
560 apply simp |
561 done |
561 done |
562 |
562 |
563 lemma transpose_mat: "transpose (mat n) = mat n" |
563 lemma transpose_mat [simp]: "transpose (mat n) = mat n" |
564 by (vector transpose_def mat_def) |
564 by (vector transpose_def mat_def) |
565 |
565 |
566 lemma transpose_transpose: "transpose(transpose A) = A" |
566 lemma transpose_transpose: "transpose(transpose A) = A" |
567 by (vector transpose_def) |
567 by (vector transpose_def) |
568 |
568 |
569 lemma row_transpose: |
569 lemma row_transpose [simp]: |
570 fixes A:: "'a::semiring_1^_^_" |
570 fixes A:: "'a::semiring_1^_^_" |
571 shows "row i (transpose A) = column i A" |
571 shows "row i (transpose A) = column i A" |
572 by (simp add: row_def column_def transpose_def vec_eq_iff) |
572 by (simp add: row_def column_def transpose_def vec_eq_iff) |
573 |
573 |
574 lemma column_transpose: |
574 lemma column_transpose [simp]: |
575 fixes A:: "'a::semiring_1^_^_" |
575 fixes A:: "'a::semiring_1^_^_" |
576 shows "column i (transpose A) = row i A" |
576 shows "column i (transpose A) = row i A" |
577 by (simp add: row_def column_def transpose_def vec_eq_iff) |
577 by (simp add: row_def column_def transpose_def vec_eq_iff) |
578 |
578 |
579 lemma rows_transpose: "rows(transpose (A::'a::semiring_1^_^_)) = columns A" |
579 lemma rows_transpose: "rows(transpose (A::'a::semiring_1^_^_)) = columns A" |
580 by (auto simp add: rows_def columns_def row_transpose intro: set_eqI) |
580 by (auto simp add: rows_def columns_def row_transpose intro: set_eqI) |
581 |
581 |
582 lemma columns_transpose: "columns(transpose (A::'a::semiring_1^_^_)) = rows A" |
582 lemma columns_transpose: "columns(transpose (A::'a::semiring_1^_^_)) = rows A" |
583 by (metis transpose_transpose rows_transpose) |
583 by (metis transpose_transpose rows_transpose) |
584 |
584 |
|
585 lemma matrix_mult_transpose_dot_column: |
|
586 fixes A :: "real^'n^'n" |
|
587 shows "transpose A ** A = (\<chi> i j. (column i A) \<bullet> (column j A))" |
|
588 by (simp add: matrix_matrix_mult_def vec_eq_iff transpose_def column_def inner_vec_def) |
|
589 |
|
590 lemma matrix_mult_transpose_dot_row: |
|
591 fixes A :: "real^'n^'n" |
|
592 shows "A ** transpose A = (\<chi> i j. (row i A) \<bullet> (row j A))" |
|
593 by (simp add: matrix_matrix_mult_def vec_eq_iff transpose_def row_def inner_vec_def) |
|
594 |
585 text\<open>Two sometimes fruitful ways of looking at matrix-vector multiplication.\<close> |
595 text\<open>Two sometimes fruitful ways of looking at matrix-vector multiplication.\<close> |
586 |
596 |
587 lemma matrix_mult_dot: "A *v x = (\<chi> i. A$i \<bullet> x)" |
597 lemma matrix_mult_dot: "A *v x = (\<chi> i. A$i \<bullet> x)" |
588 by (simp add: matrix_vector_mult_def inner_vec_def) |
598 by (simp add: matrix_vector_mult_def inner_vec_def) |
589 |
599 |
590 lemma matrix_mult_vsum: |
600 lemma matrix_mult_sum: |
591 "(A::'a::comm_semiring_1^'n^'m) *v x = sum (\<lambda>i. (x$i) *s column i A) (UNIV:: 'n set)" |
601 "(A::'a::comm_semiring_1^'n^'m) *v x = sum (\<lambda>i. (x$i) *s column i A) (UNIV:: 'n set)" |
592 by (simp add: matrix_vector_mult_def vec_eq_iff column_def mult.commute) |
602 by (simp add: matrix_vector_mult_def vec_eq_iff column_def mult.commute) |
593 |
603 |
594 lemma vector_componentwise: |
604 lemma vector_componentwise: |
595 "(x::'a::ring_1^'n) = (\<chi> j. \<Sum>i\<in>UNIV. (x$i) * (axis i 1 :: 'a^'n) $ j)" |
605 "(x::'a::ring_1^'n) = (\<chi> j. \<Sum>i\<in>UNIV. (x$i) * (axis i 1 :: 'a^'n) $ j)" |
630 |
640 |
631 lemma matrix_vector_mul_linear: "linear(\<lambda>x. A *v (x::real ^ _))" |
641 lemma matrix_vector_mul_linear: "linear(\<lambda>x. A *v (x::real ^ _))" |
632 by (simp add: linear_iff matrix_vector_mult_def vec_eq_iff |
642 by (simp add: linear_iff matrix_vector_mult_def vec_eq_iff |
633 field_simps sum_distrib_left sum.distrib) |
643 field_simps sum_distrib_left sum.distrib) |
634 |
644 |
|
645 lemma matrix_vector_mult_add_distrib [algebra_simps]: |
|
646 fixes A :: "real^'n^'m" |
|
647 shows "A *v (x + y) = A *v x + A *v y" |
|
648 using matrix_vector_mul_linear [of A] by (simp add: linear_add) |
|
649 |
|
650 lemma matrix_vector_mult_diff_distrib [algebra_simps]: |
|
651 fixes A :: "real^'n^'m" |
|
652 shows "A *v (x - y) = A *v x - A *v y" |
|
653 using matrix_vector_mul_linear [of A] by (simp add: linear_diff) |
|
654 |
|
655 lemma matrix_vector_mult_scaleR[algebra_simps]: |
|
656 fixes A :: "real^'n^'m" |
|
657 shows "A *v (c *\<^sub>R x) = c *\<^sub>R (A *v x)" |
|
658 using linear_iff matrix_vector_mul_linear by blast |
|
659 |
|
660 lemma matrix_vector_mult_0_right [simp]: "A *v 0 = 0" |
|
661 by (simp add: matrix_vector_mult_def vec_eq_iff) |
|
662 |
|
663 lemma matrix_vector_mult_0 [simp]: "0 *v w = 0" |
|
664 by (simp add: matrix_vector_mult_def vec_eq_iff) |
|
665 |
|
666 lemma matrix_vector_mult_add_rdistrib [algebra_simps]: |
|
667 fixes A :: "real^'n^'m" |
|
668 shows "(A + B) *v x = (A *v x) + (B *v x)" |
|
669 by (simp add: vec_eq_iff inner_add_left matrix_vector_mul_component) |
|
670 |
|
671 lemma matrix_vector_mult_diff_rdistrib [algebra_simps]: |
|
672 fixes A :: "real^'n^'m" |
|
673 shows "(A - B) *v x = (A *v x) - (B *v x)" |
|
674 by (simp add: vec_eq_iff inner_diff_left matrix_vector_mul_component) |
|
675 |
635 lemma matrix_works: |
676 lemma matrix_works: |
636 assumes lf: "linear f" |
677 assumes lf: "linear f" |
637 shows "matrix f *v x = f (x::real ^ 'n)" |
678 shows "matrix f *v x = f (x::real ^ 'n)" |
638 apply (simp add: matrix_def matrix_vector_mult_def vec_eq_iff mult.commute) |
679 apply (simp add: matrix_def matrix_vector_mult_def vec_eq_iff mult.commute) |
639 by (simp add: linear_componentwise_expansion lf) |
680 by (simp add: linear_componentwise_expansion lf) |
640 |
681 |
641 lemma matrix_vector_mul: "linear f ==> f = (\<lambda>x. matrix f *v (x::real ^ 'n))" |
682 lemma matrix_vector_mul: "linear f ==> f = (\<lambda>x. matrix f *v (x::real ^ 'n))" |
642 by (simp add: ext matrix_works) |
683 by (simp add: ext matrix_works) |
643 |
684 |
644 lemma matrix_of_matrix_vector_mul: "matrix(\<lambda>x. A *v (x :: real ^ 'n)) = A" |
685 lemma matrix_of_matrix_vector_mul [simp]: "matrix(\<lambda>x. A *v (x :: real ^ 'n)) = A" |
645 by (simp add: matrix_eq matrix_vector_mul_linear matrix_works) |
686 by (simp add: matrix_eq matrix_vector_mul_linear matrix_works) |
646 |
687 |
647 lemma matrix_compose: |
688 lemma matrix_compose: |
648 assumes lf: "linear (f::real^'n \<Rightarrow> real^'m)" |
689 assumes lf: "linear (f::real^'n \<Rightarrow> real^'m)" |
649 and lg: "linear (g::real^'m \<Rightarrow> real^_)" |
690 and lg: "linear (g::real^'m \<Rightarrow> real^_)" |
766 { fix c i |
807 { fix c i |
767 assume c: "sum (\<lambda>i. c i *s column i A) ?U = 0" and i: "i \<in> ?U" |
808 assume c: "sum (\<lambda>i. c i *s column i A) ?U = 0" and i: "i \<in> ?U" |
768 let ?x = "\<chi> i. c i" |
809 let ?x = "\<chi> i. c i" |
769 have th0:"A *v ?x = 0" |
810 have th0:"A *v ?x = 0" |
770 using c |
811 using c |
771 unfolding matrix_mult_vsum vec_eq_iff |
812 unfolding matrix_mult_sum vec_eq_iff |
772 by auto |
813 by auto |
773 from k[rule_format, OF th0] i |
814 from k[rule_format, OF th0] i |
774 have "c i = 0" by (vector vec_eq_iff)} |
815 have "c i = 0" by (vector vec_eq_iff)} |
775 hence ?rhs by blast } |
816 hence ?rhs by blast } |
776 moreover |
817 moreover |
777 { assume H: ?rhs |
818 { assume H: ?rhs |
778 { fix x assume x: "A *v x = 0" |
819 { fix x assume x: "A *v x = 0" |
779 let ?c = "\<lambda>i. ((x$i ):: real)" |
820 let ?c = "\<lambda>i. ((x$i ):: real)" |
780 from H[rule_format, of ?c, unfolded matrix_mult_vsum[symmetric], OF x] |
821 from H[rule_format, of ?c, unfolded matrix_mult_sum[symmetric], OF x] |
781 have "x = 0" by vector } |
822 have "x = 0" by vector } |
782 } |
823 } |
783 ultimately show ?thesis unfolding matrix_left_invertible_ker by blast |
824 ultimately show ?thesis unfolding matrix_left_invertible_ker by blast |
784 qed |
825 qed |
785 |
826 |
796 span (columns A) = UNIV" (is "?lhs = ?rhs") |
837 span (columns A) = UNIV" (is "?lhs = ?rhs") |
797 proof - |
838 proof - |
798 let ?U = "UNIV :: 'm set" |
839 let ?U = "UNIV :: 'm set" |
799 have fU: "finite ?U" by simp |
840 have fU: "finite ?U" by simp |
800 have lhseq: "?lhs \<longleftrightarrow> (\<forall>y. \<exists>(x::real^'m). sum (\<lambda>i. (x$i) *s column i A) ?U = y)" |
841 have lhseq: "?lhs \<longleftrightarrow> (\<forall>y. \<exists>(x::real^'m). sum (\<lambda>i. (x$i) *s column i A) ?U = y)" |
801 unfolding matrix_right_invertible_surjective matrix_mult_vsum surj_def |
842 unfolding matrix_right_invertible_surjective matrix_mult_sum surj_def |
802 apply (subst eq_commute) |
843 apply (subst eq_commute) |
803 apply rule |
844 apply rule |
804 done |
845 done |
805 have rhseq: "?rhs \<longleftrightarrow> (\<forall>x. x \<in> span (columns A))" by blast |
846 have rhseq: "?rhs \<longleftrightarrow> (\<forall>x. x \<in> span (columns A))" by blast |
806 { assume h: ?lhs |
847 { assume h: ?lhs |
1000 fixes a :: "real^'n" |
1041 fixes a :: "real^'n" |
1001 shows "box a b = {x::real^'n. \<forall>i. a$i < x$i \<and> x$i < b$i}" |
1042 shows "box a b = {x::real^'n. \<forall>i. a$i < x$i \<and> x$i < b$i}" |
1002 and "cbox a b = {x::real^'n. \<forall>i. a$i \<le> x$i \<and> x$i \<le> b$i}" |
1043 and "cbox a b = {x::real^'n. \<forall>i. a$i \<le> x$i \<and> x$i \<le> b$i}" |
1003 by (auto simp add: set_eq_iff less_vec_def less_eq_vec_def mem_box Basis_vec_def inner_axis) |
1044 by (auto simp add: set_eq_iff less_vec_def less_eq_vec_def mem_box Basis_vec_def inner_axis) |
1004 |
1045 |
1005 lemma mem_interval_cart: |
1046 lemma mem_box_cart: |
1006 fixes a :: "real^'n" |
1047 fixes a :: "real^'n" |
1007 shows "x \<in> box a b \<longleftrightarrow> (\<forall>i. a$i < x$i \<and> x$i < b$i)" |
1048 shows "x \<in> box a b \<longleftrightarrow> (\<forall>i. a$i < x$i \<and> x$i < b$i)" |
1008 and "x \<in> cbox a b \<longleftrightarrow> (\<forall>i. a$i \<le> x$i \<and> x$i \<le> b$i)" |
1049 and "x \<in> cbox a b \<longleftrightarrow> (\<forall>i. a$i \<le> x$i \<and> x$i \<le> b$i)" |
1009 using interval_cart[of a b] by (auto simp add: set_eq_iff less_vec_def less_eq_vec_def) |
1050 using interval_cart[of a b] by (auto simp add: set_eq_iff less_vec_def less_eq_vec_def) |
1010 |
1051 |
1012 fixes a :: "real^'n" |
1053 fixes a :: "real^'n" |
1013 shows "(box a b = {} \<longleftrightarrow> (\<exists>i. b$i \<le> a$i))" (is ?th1) |
1054 shows "(box a b = {} \<longleftrightarrow> (\<exists>i. b$i \<le> a$i))" (is ?th1) |
1014 and "(cbox a b = {} \<longleftrightarrow> (\<exists>i. b$i < a$i))" (is ?th2) |
1055 and "(cbox a b = {} \<longleftrightarrow> (\<exists>i. b$i < a$i))" (is ?th2) |
1015 proof - |
1056 proof - |
1016 { fix i x assume as:"b$i \<le> a$i" and x:"x\<in>box a b" |
1057 { fix i x assume as:"b$i \<le> a$i" and x:"x\<in>box a b" |
1017 hence "a $ i < x $ i \<and> x $ i < b $ i" unfolding mem_interval_cart by auto |
1058 hence "a $ i < x $ i \<and> x $ i < b $ i" unfolding mem_box_cart by auto |
1018 hence "a$i < b$i" by auto |
1059 hence "a$i < b$i" by auto |
1019 hence False using as by auto } |
1060 hence False using as by auto } |
1020 moreover |
1061 moreover |
1021 { assume as:"\<forall>i. \<not> (b$i \<le> a$i)" |
1062 { assume as:"\<forall>i. \<not> (b$i \<le> a$i)" |
1022 let ?x = "(1/2) *\<^sub>R (a + b)" |
1063 let ?x = "(1/2) *\<^sub>R (a + b)" |
1023 { fix i |
1064 { fix i |
1024 have "a$i < b$i" using as[THEN spec[where x=i]] by auto |
1065 have "a$i < b$i" using as[THEN spec[where x=i]] by auto |
1025 hence "a$i < ((1/2) *\<^sub>R (a+b)) $ i" "((1/2) *\<^sub>R (a+b)) $ i < b$i" |
1066 hence "a$i < ((1/2) *\<^sub>R (a+b)) $ i" "((1/2) *\<^sub>R (a+b)) $ i < b$i" |
1026 unfolding vector_smult_component and vector_add_component |
1067 unfolding vector_smult_component and vector_add_component |
1027 by auto } |
1068 by auto } |
1028 hence "box a b \<noteq> {}" using mem_interval_cart(1)[of "?x" a b] by auto } |
1069 hence "box a b \<noteq> {}" using mem_box_cart(1)[of "?x" a b] by auto } |
1029 ultimately show ?th1 by blast |
1070 ultimately show ?th1 by blast |
1030 |
1071 |
1031 { fix i x assume as:"b$i < a$i" and x:"x\<in>cbox a b" |
1072 { fix i x assume as:"b$i < a$i" and x:"x\<in>cbox a b" |
1032 hence "a $ i \<le> x $ i \<and> x $ i \<le> b $ i" unfolding mem_interval_cart by auto |
1073 hence "a $ i \<le> x $ i \<and> x $ i \<le> b $ i" unfolding mem_box_cart by auto |
1033 hence "a$i \<le> b$i" by auto |
1074 hence "a$i \<le> b$i" by auto |
1034 hence False using as by auto } |
1075 hence False using as by auto } |
1035 moreover |
1076 moreover |
1036 { assume as:"\<forall>i. \<not> (b$i < a$i)" |
1077 { assume as:"\<forall>i. \<not> (b$i < a$i)" |
1037 let ?x = "(1/2) *\<^sub>R (a + b)" |
1078 let ?x = "(1/2) *\<^sub>R (a + b)" |
1038 { fix i |
1079 { fix i |
1039 have "a$i \<le> b$i" using as[THEN spec[where x=i]] by auto |
1080 have "a$i \<le> b$i" using as[THEN spec[where x=i]] by auto |
1040 hence "a$i \<le> ((1/2) *\<^sub>R (a+b)) $ i" "((1/2) *\<^sub>R (a+b)) $ i \<le> b$i" |
1081 hence "a$i \<le> ((1/2) *\<^sub>R (a+b)) $ i" "((1/2) *\<^sub>R (a+b)) $ i \<le> b$i" |
1041 unfolding vector_smult_component and vector_add_component |
1082 unfolding vector_smult_component and vector_add_component |
1042 by auto } |
1083 by auto } |
1043 hence "cbox a b \<noteq> {}" using mem_interval_cart(2)[of "?x" a b] by auto } |
1084 hence "cbox a b \<noteq> {}" using mem_box_cart(2)[of "?x" a b] by auto } |
1044 ultimately show ?th2 by blast |
1085 ultimately show ?th2 by blast |
1045 qed |
1086 qed |
1046 |
1087 |
1047 lemma interval_ne_empty_cart: |
1088 lemma interval_ne_empty_cart: |
1048 fixes a :: "real^'n" |
1089 fixes a :: "real^'n" |
1055 fixes a :: "real^'n" |
1096 fixes a :: "real^'n" |
1056 shows "(\<forall>i. a$i \<le> c$i \<and> d$i \<le> b$i) \<Longrightarrow> cbox c d \<subseteq> cbox a b" |
1097 shows "(\<forall>i. a$i \<le> c$i \<and> d$i \<le> b$i) \<Longrightarrow> cbox c d \<subseteq> cbox a b" |
1057 and "(\<forall>i. a$i < c$i \<and> d$i < b$i) \<Longrightarrow> cbox c d \<subseteq> box a b" |
1098 and "(\<forall>i. a$i < c$i \<and> d$i < b$i) \<Longrightarrow> cbox c d \<subseteq> box a b" |
1058 and "(\<forall>i. a$i \<le> c$i \<and> d$i \<le> b$i) \<Longrightarrow> box c d \<subseteq> cbox a b" |
1099 and "(\<forall>i. a$i \<le> c$i \<and> d$i \<le> b$i) \<Longrightarrow> box c d \<subseteq> cbox a b" |
1059 and "(\<forall>i. a$i \<le> c$i \<and> d$i \<le> b$i) \<Longrightarrow> box c d \<subseteq> box a b" |
1100 and "(\<forall>i. a$i \<le> c$i \<and> d$i \<le> b$i) \<Longrightarrow> box c d \<subseteq> box a b" |
1060 unfolding subset_eq[unfolded Ball_def] unfolding mem_interval_cart |
1101 unfolding subset_eq[unfolded Ball_def] unfolding mem_box_cart |
1061 by (auto intro: order_trans less_le_trans le_less_trans less_imp_le) (* BH: Why doesn't just "auto" work here? *) |
1102 by (auto intro: order_trans less_le_trans le_less_trans less_imp_le) (* BH: Why doesn't just "auto" work here? *) |
1062 |
1103 |
1063 lemma interval_sing: |
1104 lemma interval_sing: |
1064 fixes a :: "'a::linorder^'n" |
1105 fixes a :: "'a::linorder^'n" |
1065 shows "{a .. a} = {a} \<and> {a<..<a} = {}" |
1106 shows "{a .. a} = {a} \<and> {a<..<a} = {}" |