src/HOL/Analysis/Determinants.thy
changeset 69720 be6634e99e09
parent 69683 8b3458ca0762
child 70136 f03a01a18c6e
equal deleted inserted replaced
69716:749aaeb40788 69720:be6634e99e09
    13 subsection  \<open>Trace\<close>
    13 subsection  \<open>Trace\<close>
    14 
    14 
    15 definition%important  trace :: "'a::semiring_1^'n^'n \<Rightarrow> 'a"
    15 definition%important  trace :: "'a::semiring_1^'n^'n \<Rightarrow> 'a"
    16   where "trace A = sum (\<lambda>i. ((A$i)$i)) (UNIV::'n set)"
    16   where "trace A = sum (\<lambda>i. ((A$i)$i)) (UNIV::'n set)"
    17 
    17 
    18 lemma%unimportant  trace_0: "trace (mat 0) = 0"
    18 lemma  trace_0: "trace (mat 0) = 0"
    19   by (simp add: trace_def mat_def)
    19   by (simp add: trace_def mat_def)
    20 
    20 
    21 lemma%unimportant  trace_I: "trace (mat 1 :: 'a::semiring_1^'n^'n) = of_nat(CARD('n))"
    21 lemma  trace_I: "trace (mat 1 :: 'a::semiring_1^'n^'n) = of_nat(CARD('n))"
    22   by (simp add: trace_def mat_def)
    22   by (simp add: trace_def mat_def)
    23 
    23 
    24 lemma%unimportant  trace_add: "trace ((A::'a::comm_semiring_1^'n^'n) + B) = trace A + trace B"
    24 lemma  trace_add: "trace ((A::'a::comm_semiring_1^'n^'n) + B) = trace A + trace B"
    25   by (simp add: trace_def sum.distrib)
    25   by (simp add: trace_def sum.distrib)
    26 
    26 
    27 lemma%unimportant  trace_sub: "trace ((A::'a::comm_ring_1^'n^'n) - B) = trace A - trace B"
    27 lemma  trace_sub: "trace ((A::'a::comm_ring_1^'n^'n) - B) = trace A - trace B"
    28   by (simp add: trace_def sum_subtractf)
    28   by (simp add: trace_def sum_subtractf)
    29 
    29 
    30 lemma%important  trace_mul_sym: "trace ((A::'a::comm_semiring_1^'n^'m) ** B) = trace (B**A)"
    30 lemma  trace_mul_sym: "trace ((A::'a::comm_semiring_1^'n^'m) ** B) = trace (B**A)"
    31   apply (simp add: trace_def matrix_matrix_mult_def)
    31   apply (simp add: trace_def matrix_matrix_mult_def)
    32   apply (subst sum.swap)
    32   apply (subst sum.swap)
    33   apply (simp add: mult.commute)
    33   apply (simp add: mult.commute)
    34   done
    34   done
    35 
    35 
    36 subsubsection  \<open>Definition of determinant\<close>
    36 subsubsection%important  \<open>Definition of determinant\<close>
    37 
    37 
    38 definition%important  det:: "'a::comm_ring_1^'n^'n \<Rightarrow> 'a" where
    38 definition%important  det:: "'a::comm_ring_1^'n^'n \<Rightarrow> 'a" where
    39   "det A =
    39   "det A =
    40     sum (\<lambda>p. of_int (sign p) * prod (\<lambda>i. A$i$p i) (UNIV :: 'n set))
    40     sum (\<lambda>p. of_int (sign p) * prod (\<lambda>i. A$i$p i) (UNIV :: 'n set))
    41       {p. p permutes (UNIV :: 'n set)}"
    41       {p. p permutes (UNIV :: 'n set)}"
    42 
    42 
    43 text \<open>Basic determinant properties\<close>
    43 text \<open>Basic determinant properties\<close>
    44 
    44 
    45 lemma%important  det_transpose [simp]: "det (transpose A) = det (A::'a::comm_ring_1 ^'n^'n)"
    45 lemma  det_transpose [simp]: "det (transpose A) = det (A::'a::comm_ring_1 ^'n^'n)"
    46 proof%unimportant -
    46 proof -
    47   let ?di = "\<lambda>A i j. A$i$j"
    47   let ?di = "\<lambda>A i j. A$i$j"
    48   let ?U = "(UNIV :: 'n set)"
    48   let ?U = "(UNIV :: 'n set)"
    49   have fU: "finite ?U" by simp
    49   have fU: "finite ?U" by simp
    50   {
    50   {
    51     fix p
    51     fix p
    78   then show ?thesis
    78   then show ?thesis
    79     unfolding det_def
    79     unfolding det_def
    80     by (subst sum_permutations_inverse) (blast intro: sum.cong)
    80     by (subst sum_permutations_inverse) (blast intro: sum.cong)
    81 qed
    81 qed
    82 
    82 
    83 lemma%unimportant  det_lowerdiagonal:
    83 lemma  det_lowerdiagonal:
    84   fixes A :: "'a::comm_ring_1^('n::{finite,wellorder})^('n::{finite,wellorder})"
    84   fixes A :: "'a::comm_ring_1^('n::{finite,wellorder})^('n::{finite,wellorder})"
    85   assumes ld: "\<And>i j. i < j \<Longrightarrow> A$i$j = 0"
    85   assumes ld: "\<And>i j. i < j \<Longrightarrow> A$i$j = 0"
    86   shows "det A = prod (\<lambda>i. A$i$i) (UNIV:: 'n set)"
    86   shows "det A = prod (\<lambda>i. A$i$i) (UNIV:: 'n set)"
    87 proof -
    87 proof -
    88   let ?U = "UNIV:: 'n set"
    88   let ?U = "UNIV:: 'n set"
   105   qed
   105   qed
   106   from sum.mono_neutral_cong_left[OF finite_permutations[OF fU] id0 p0] show ?thesis
   106   from sum.mono_neutral_cong_left[OF finite_permutations[OF fU] id0 p0] show ?thesis
   107     unfolding det_def by (simp add: sign_id)
   107     unfolding det_def by (simp add: sign_id)
   108 qed
   108 qed
   109 
   109 
   110 lemma%important  det_upperdiagonal:
   110 lemma  det_upperdiagonal:
   111   fixes A :: "'a::comm_ring_1^'n::{finite,wellorder}^'n::{finite,wellorder}"
   111   fixes A :: "'a::comm_ring_1^'n::{finite,wellorder}^'n::{finite,wellorder}"
   112   assumes ld: "\<And>i j. i > j \<Longrightarrow> A$i$j = 0"
   112   assumes ld: "\<And>i j. i > j \<Longrightarrow> A$i$j = 0"
   113   shows "det A = prod (\<lambda>i. A$i$i) (UNIV:: 'n set)"
   113   shows "det A = prod (\<lambda>i. A$i$i) (UNIV:: 'n set)"
   114 proof%unimportant -
   114 proof -
   115   let ?U = "UNIV:: 'n set"
   115   let ?U = "UNIV:: 'n set"
   116   let ?PU = "{p. p permutes ?U}"
   116   let ?PU = "{p. p permutes ?U}"
   117   let ?pp = "(\<lambda>p. of_int (sign p) * prod (\<lambda>i. A$i$p i) (UNIV :: 'n set))"
   117   let ?pp = "(\<lambda>p. of_int (sign p) * prod (\<lambda>i. A$i$p i) (UNIV :: 'n set))"
   118   have fU: "finite ?U"
   118   have fU: "finite ?U"
   119     by simp
   119     by simp
   132   qed
   132   qed
   133   from sum.mono_neutral_cong_left[OF finite_permutations[OF fU] id0 p0] show ?thesis
   133   from sum.mono_neutral_cong_left[OF finite_permutations[OF fU] id0 p0] show ?thesis
   134     unfolding det_def by (simp add: sign_id)
   134     unfolding det_def by (simp add: sign_id)
   135 qed
   135 qed
   136 
   136 
   137 lemma%important  det_diagonal:
   137 proposition  det_diagonal:
   138   fixes A :: "'a::comm_ring_1^'n^'n"
   138   fixes A :: "'a::comm_ring_1^'n^'n"
   139   assumes ld: "\<And>i j. i \<noteq> j \<Longrightarrow> A$i$j = 0"
   139   assumes ld: "\<And>i j. i \<noteq> j \<Longrightarrow> A$i$j = 0"
   140   shows "det A = prod (\<lambda>i. A$i$i) (UNIV::'n set)"
   140   shows "det A = prod (\<lambda>i. A$i$i) (UNIV::'n set)"
   141 proof%unimportant -
   141 proof -
   142   let ?U = "UNIV:: 'n set"
   142   let ?U = "UNIV:: 'n set"
   143   let ?PU = "{p. p permutes ?U}"
   143   let ?PU = "{p. p permutes ?U}"
   144   let ?pp = "\<lambda>p. of_int (sign p) * prod (\<lambda>i. A$i$p i) (UNIV :: 'n set)"
   144   let ?pp = "\<lambda>p. of_int (sign p) * prod (\<lambda>i. A$i$p i) (UNIV :: 'n set)"
   145   have fU: "finite ?U" by simp
   145   have fU: "finite ?U" by simp
   146   from finite_permutations[OF fU] have fPU: "finite ?PU" .
   146   from finite_permutations[OF fU] have fPU: "finite ?PU" .
   159   qed
   159   qed
   160   from sum.mono_neutral_cong_left[OF fPU id0 p0] show ?thesis
   160   from sum.mono_neutral_cong_left[OF fPU id0 p0] show ?thesis
   161     unfolding det_def by (simp add: sign_id)
   161     unfolding det_def by (simp add: sign_id)
   162 qed
   162 qed
   163 
   163 
   164 lemma%unimportant  det_I [simp]: "det (mat 1 :: 'a::comm_ring_1^'n^'n) = 1"
   164 lemma  det_I [simp]: "det (mat 1 :: 'a::comm_ring_1^'n^'n) = 1"
   165   by (simp add: det_diagonal mat_def)
   165   by (simp add: det_diagonal mat_def)
   166 
   166 
   167 lemma%unimportant  det_0 [simp]: "det (mat 0 :: 'a::comm_ring_1^'n^'n) = 0"
   167 lemma  det_0 [simp]: "det (mat 0 :: 'a::comm_ring_1^'n^'n) = 0"
   168   by (simp add: det_def prod_zero power_0_left)
   168   by (simp add: det_def prod_zero power_0_left)
   169 
   169 
   170 lemma%unimportant  det_permute_rows:
   170 lemma  det_permute_rows:
   171   fixes A :: "'a::comm_ring_1^'n^'n"
   171   fixes A :: "'a::comm_ring_1^'n^'n"
   172   assumes p: "p permutes (UNIV :: 'n::finite set)"
   172   assumes p: "p permutes (UNIV :: 'n::finite set)"
   173   shows "det (\<chi> i. A$p i :: 'a^'n^'n) = of_int (sign p) * det A"
   173   shows "det (\<chi> i. A$p i :: 'a^'n^'n) = of_int (sign p) * det A"
   174 proof -
   174 proof -
   175   let ?U = "UNIV :: 'n set"
   175   let ?U = "UNIV :: 'n set"
   202     apply (subst sum_permutations_compose_right[OF p])
   202     apply (subst sum_permutations_compose_right[OF p])
   203     apply (rule *)
   203     apply (rule *)
   204     done
   204     done
   205 qed
   205 qed
   206 
   206 
   207 lemma%important  det_permute_columns:
   207 lemma  det_permute_columns:
   208   fixes A :: "'a::comm_ring_1^'n^'n"
   208   fixes A :: "'a::comm_ring_1^'n^'n"
   209   assumes p: "p permutes (UNIV :: 'n set)"
   209   assumes p: "p permutes (UNIV :: 'n set)"
   210   shows "det(\<chi> i j. A$i$ p j :: 'a^'n^'n) = of_int (sign p) * det A"
   210   shows "det(\<chi> i j. A$i$ p j :: 'a^'n^'n) = of_int (sign p) * det A"
   211 proof%unimportant -
   211 proof -
   212   let ?Ap = "\<chi> i j. A$i$ p j :: 'a^'n^'n"
   212   let ?Ap = "\<chi> i j. A$i$ p j :: 'a^'n^'n"
   213   let ?At = "transpose A"
   213   let ?At = "transpose A"
   214   have "of_int (sign p) * det A = det (transpose (\<chi> i. transpose A $ p i))"
   214   have "of_int (sign p) * det A = det (transpose (\<chi> i. transpose A $ p i))"
   215     unfolding det_permute_rows[OF p, of ?At] det_transpose ..
   215     unfolding det_permute_rows[OF p, of ?At] det_transpose ..
   216   moreover
   216   moreover
   218     by (simp add: transpose_def vec_eq_iff)
   218     by (simp add: transpose_def vec_eq_iff)
   219   ultimately show ?thesis
   219   ultimately show ?thesis
   220     by simp
   220     by simp
   221 qed
   221 qed
   222 
   222 
   223 lemma%unimportant  det_identical_columns:
   223 lemma  det_identical_columns:
   224   fixes A :: "'a::comm_ring_1^'n^'n"
   224   fixes A :: "'a::comm_ring_1^'n^'n"
   225   assumes jk: "j \<noteq> k"
   225   assumes jk: "j \<noteq> k"
   226     and r: "column j A = column k A"
   226     and r: "column j A = column k A"
   227   shows "det A = 0"
   227   shows "det A = 0"
   228 proof -
   228 proof -
   298   also have "\<dots>= sum ?f ?S1 - sum ?f ?S1 " unfolding * by auto
   298   also have "\<dots>= sum ?f ?S1 - sum ?f ?S1 " unfolding * by auto
   299   also have "\<dots>= 0" by simp
   299   also have "\<dots>= 0" by simp
   300   finally show "det A = 0" by simp
   300   finally show "det A = 0" by simp
   301 qed
   301 qed
   302 
   302 
   303 lemma%unimportant  det_identical_rows:
   303 lemma  det_identical_rows:
   304   fixes A :: "'a::comm_ring_1^'n^'n"
   304   fixes A :: "'a::comm_ring_1^'n^'n"
   305   assumes ij: "i \<noteq> j" and r: "row i A = row j A"
   305   assumes ij: "i \<noteq> j" and r: "row i A = row j A"
   306   shows "det A = 0"
   306   shows "det A = 0"
   307   by (metis column_transpose det_identical_columns det_transpose ij r)
   307   by (metis column_transpose det_identical_columns det_transpose ij r)
   308 
   308 
   309 lemma%unimportant  det_zero_row:
   309 lemma  det_zero_row:
   310   fixes A :: "'a::{idom, ring_char_0}^'n^'n" and F :: "'b::{field}^'m^'m"
   310   fixes A :: "'a::{idom, ring_char_0}^'n^'n" and F :: "'b::{field}^'m^'m"
   311   shows "row i A = 0 \<Longrightarrow> det A = 0" and "row j F = 0 \<Longrightarrow> det F = 0"
   311   shows "row i A = 0 \<Longrightarrow> det A = 0" and "row j F = 0 \<Longrightarrow> det F = 0"
   312   by (force simp: row_def det_def vec_eq_iff sign_nz intro!: sum.neutral)+
   312   by (force simp: row_def det_def vec_eq_iff sign_nz intro!: sum.neutral)+
   313 
   313 
   314 lemma%unimportant  det_zero_column:
   314 lemma  det_zero_column:
   315   fixes A :: "'a::{idom, ring_char_0}^'n^'n" and F :: "'b::{field}^'m^'m"
   315   fixes A :: "'a::{idom, ring_char_0}^'n^'n" and F :: "'b::{field}^'m^'m"
   316   shows "column i A = 0 \<Longrightarrow> det A = 0" and "column j F = 0 \<Longrightarrow> det F = 0"
   316   shows "column i A = 0 \<Longrightarrow> det A = 0" and "column j F = 0 \<Longrightarrow> det F = 0"
   317   unfolding atomize_conj atomize_imp
   317   unfolding atomize_conj atomize_imp
   318   by (metis det_transpose det_zero_row row_transpose)
   318   by (metis det_transpose det_zero_row row_transpose)
   319 
   319 
   320 lemma%unimportant  det_row_add:
   320 lemma  det_row_add:
   321   fixes a b c :: "'n::finite \<Rightarrow> _ ^ 'n"
   321   fixes a b c :: "'n::finite \<Rightarrow> _ ^ 'n"
   322   shows "det((\<chi> i. if i = k then a i + b i else c i)::'a::comm_ring_1^'n^'n) =
   322   shows "det((\<chi> i. if i = k then a i + b i else c i)::'a::comm_ring_1^'n^'n) =
   323     det((\<chi> i. if i = k then a i else c i)::'a::comm_ring_1^'n^'n) +
   323     det((\<chi> i. if i = k then a i else c i)::'a::comm_ring_1^'n^'n) +
   324     det((\<chi> i. if i = k then b i else c i)::'a::comm_ring_1^'n^'n)"
   324     det((\<chi> i. if i = k then b i else c i)::'a::comm_ring_1^'n^'n)"
   325   unfolding det_def vec_lambda_beta sum.distrib[symmetric]
   325   unfolding det_def vec_lambda_beta sum.distrib[symmetric]
   356   then show "of_int (sign p) * prod (\<lambda>i. ?f i $ p i) ?U =
   356   then show "of_int (sign p) * prod (\<lambda>i. ?f i $ p i) ?U =
   357     of_int (sign p) * prod (\<lambda>i. ?g i $ p i) ?U + of_int (sign p) * prod (\<lambda>i. ?h i $ p i) ?U"
   357     of_int (sign p) * prod (\<lambda>i. ?g i $ p i) ?U + of_int (sign p) * prod (\<lambda>i. ?h i $ p i) ?U"
   358     by (simp add: field_simps)
   358     by (simp add: field_simps)
   359 qed auto
   359 qed auto
   360 
   360 
   361 lemma%unimportant  det_row_mul:
   361 lemma  det_row_mul:
   362   fixes a b :: "'n::finite \<Rightarrow> _ ^ 'n"
   362   fixes a b :: "'n::finite \<Rightarrow> _ ^ 'n"
   363   shows "det((\<chi> i. if i = k then c *s a i else b i)::'a::comm_ring_1^'n^'n) =
   363   shows "det((\<chi> i. if i = k then c *s a i else b i)::'a::comm_ring_1^'n^'n) =
   364     c * det((\<chi> i. if i = k then a i else b i)::'a::comm_ring_1^'n^'n)"
   364     c * det((\<chi> i. if i = k then a i else b i)::'a::comm_ring_1^'n^'n)"
   365   unfolding det_def vec_lambda_beta sum_distrib_left
   365   unfolding det_def vec_lambda_beta sum_distrib_left
   366 proof (rule sum.cong)
   366 proof (rule sum.cong)
   393     unfolding kU[symmetric] .
   393     unfolding kU[symmetric] .
   394   then show "of_int (sign p) * prod (\<lambda>i. ?f i $ p i) ?U = c * (of_int (sign p) * prod (\<lambda>i. ?g i $ p i) ?U)"
   394   then show "of_int (sign p) * prod (\<lambda>i. ?f i $ p i) ?U = c * (of_int (sign p) * prod (\<lambda>i. ?g i $ p i) ?U)"
   395     by (simp add: field_simps)
   395     by (simp add: field_simps)
   396 qed auto
   396 qed auto
   397 
   397 
   398 lemma%unimportant  det_row_0:
   398 lemma  det_row_0:
   399   fixes b :: "'n::finite \<Rightarrow> _ ^ 'n"
   399   fixes b :: "'n::finite \<Rightarrow> _ ^ 'n"
   400   shows "det((\<chi> i. if i = k then 0 else b i)::'a::comm_ring_1^'n^'n) = 0"
   400   shows "det((\<chi> i. if i = k then 0 else b i)::'a::comm_ring_1^'n^'n) = 0"
   401   using det_row_mul[of k 0 "\<lambda>i. 1" b]
   401   using det_row_mul[of k 0 "\<lambda>i. 1" b]
   402   apply simp
   402   apply simp
   403   apply (simp only: vector_smult_lzero)
   403   apply (simp only: vector_smult_lzero)
   404   done
   404   done
   405 
   405 
   406 lemma%important  det_row_operation:
   406 lemma  det_row_operation:
   407   fixes A :: "'a::{comm_ring_1}^'n^'n"
   407   fixes A :: "'a::{comm_ring_1}^'n^'n"
   408   assumes ij: "i \<noteq> j"
   408   assumes ij: "i \<noteq> j"
   409   shows "det (\<chi> k. if k = i then row i A + c *s row j A else row k A) = det A"
   409   shows "det (\<chi> k. if k = i then row i A + c *s row j A else row k A) = det A"
   410 proof%unimportant -
   410 proof -
   411   let ?Z = "(\<chi> k. if k = i then row j A else row k A) :: 'a ^'n^'n"
   411   let ?Z = "(\<chi> k. if k = i then row j A else row k A) :: 'a ^'n^'n"
   412   have th: "row i ?Z = row j ?Z" by (vector row_def)
   412   have th: "row i ?Z = row j ?Z" by (vector row_def)
   413   have th2: "((\<chi> k. if k = i then row i A else row k A) :: 'a^'n^'n) = A"
   413   have th2: "((\<chi> k. if k = i then row i A else row k A) :: 'a^'n^'n) = A"
   414     by (vector row_def)
   414     by (vector row_def)
   415   show ?thesis
   415   show ?thesis
   416     unfolding det_row_add [of i] det_row_mul[of i] det_identical_rows[OF ij th] th2
   416     unfolding det_row_add [of i] det_row_mul[of i] det_identical_rows[OF ij th] th2
   417     by simp
   417     by simp
   418 qed
   418 qed
   419 
   419 
   420 lemma%unimportant  det_row_span:
   420 lemma  det_row_span:
   421   fixes A :: "'a::{field}^'n^'n"
   421   fixes A :: "'a::{field}^'n^'n"
   422   assumes x: "x \<in> vec.span {row j A |j. j \<noteq> i}"
   422   assumes x: "x \<in> vec.span {row j A |j. j \<noteq> i}"
   423   shows "det (\<chi> k. if k = i then row i A + x else row k A) = det A"
   423   shows "det (\<chi> k. if k = i then row i A + x else row k A) = det A"
   424   using x
   424   using x
   425 proof (induction rule: vec.span_induct_alt)
   425 proof (induction rule: vec.span_induct_alt)
   447     unfolding thz step.IH det_row_mul[of i] det_row_add[of i] by simp
   447     unfolding thz step.IH det_row_mul[of i] det_row_add[of i] by simp
   448   then show ?case
   448   then show ?case
   449     unfolding scalar_mult_eq_scaleR .
   449     unfolding scalar_mult_eq_scaleR .
   450 qed
   450 qed
   451 
   451 
   452 lemma%unimportant  matrix_id [simp]: "det (matrix id) = 1"
   452 lemma  matrix_id [simp]: "det (matrix id) = 1"
   453   by (simp add: matrix_id_mat_1)
   453   by (simp add: matrix_id_mat_1)
   454 
   454 
   455 lemma%important  det_matrix_scaleR [simp]: "det (matrix (((*\<^sub>R) r)) :: real^'n^'n) = r ^ CARD('n::finite)"
   455 proposition  det_matrix_scaleR [simp]: "det (matrix (((*\<^sub>R) r)) :: real^'n^'n) = r ^ CARD('n::finite)"
   456   apply (subst det_diagonal)
   456   apply (subst det_diagonal)
   457    apply (auto simp: matrix_def mat_def)
   457    apply (auto simp: matrix_def mat_def)
   458   apply (simp add: cart_eq_inner_axis inner_axis_axis)
   458   apply (simp add: cart_eq_inner_axis inner_axis_axis)
   459   done
   459   done
   460 
   460 
   461 text \<open>
   461 text \<open>
   462   May as well do this, though it's a bit unsatisfactory since it ignores
   462   May as well do this, though it's a bit unsatisfactory since it ignores
   463   exact duplicates by considering the rows/columns as a set.
   463   exact duplicates by considering the rows/columns as a set.
   464 \<close>
   464 \<close>
   465 
   465 
   466 lemma%unimportant  det_dependent_rows:
   466 lemma  det_dependent_rows:
   467   fixes A:: "'a::{field}^'n^'n"
   467   fixes A:: "'a::{field}^'n^'n"
   468   assumes d: "vec.dependent (rows A)"
   468   assumes d: "vec.dependent (rows A)"
   469   shows "det A = 0"
   469   shows "det A = 0"
   470 proof -
   470 proof -
   471   let ?U = "UNIV :: 'n set"
   471   let ?U = "UNIV :: 'n set"
   489       by auto
   489       by auto
   490     from det_identical_rows[OF jk] show ?thesis .
   490     from det_identical_rows[OF jk] show ?thesis .
   491   qed
   491   qed
   492 qed
   492 qed
   493 
   493 
   494 lemma%unimportant  det_dependent_columns:
   494 lemma  det_dependent_columns:
   495   assumes d: "vec.dependent (columns (A::real^'n^'n))"
   495   assumes d: "vec.dependent (columns (A::real^'n^'n))"
   496   shows "det A = 0"
   496   shows "det A = 0"
   497   by (metis d det_dependent_rows rows_transpose det_transpose)
   497   by (metis d det_dependent_rows rows_transpose det_transpose)
   498 
   498 
   499 text \<open>Multilinearity and the multiplication formula\<close>
   499 text \<open>Multilinearity and the multiplication formula\<close>
   500 
   500 
   501 lemma%unimportant  Cart_lambda_cong: "(\<And>x. f x = g x) \<Longrightarrow> (vec_lambda f::'a^'n) = (vec_lambda g :: 'a^'n)"
   501 lemma  Cart_lambda_cong: "(\<And>x. f x = g x) \<Longrightarrow> (vec_lambda f::'a^'n) = (vec_lambda g :: 'a^'n)"
   502   by auto
   502   by auto
   503 
   503 
   504 lemma%unimportant  det_linear_row_sum:
   504 lemma  det_linear_row_sum:
   505   assumes fS: "finite S"
   505   assumes fS: "finite S"
   506   shows "det ((\<chi> i. if i = k then sum (a i) S else c i)::'a::comm_ring_1^'n^'n) =
   506   shows "det ((\<chi> i. if i = k then sum (a i) S else c i)::'a::comm_ring_1^'n^'n) =
   507     sum (\<lambda>j. det ((\<chi> i. if i = k then a  i j else c i)::'a^'n^'n)) S"
   507     sum (\<lambda>j. det ((\<chi> i. if i = k then a  i j else c i)::'a^'n^'n)) S"
   508   using fS  by (induct rule: finite_induct; simp add: det_row_0 det_row_add cong: if_cong)
   508   using fS  by (induct rule: finite_induct; simp add: det_row_0 det_row_add cong: if_cong)
   509 
   509 
   510 lemma%unimportant  finite_bounded_functions:
   510 lemma  finite_bounded_functions:
   511   assumes fS: "finite S"
   511   assumes fS: "finite S"
   512   shows "finite {f. (\<forall>i \<in> {1.. (k::nat)}. f i \<in> S) \<and> (\<forall>i. i \<notin> {1 .. k} \<longrightarrow> f i = i)}"
   512   shows "finite {f. (\<forall>i \<in> {1.. (k::nat)}. f i \<in> S) \<and> (\<forall>i. i \<notin> {1 .. k} \<longrightarrow> f i = i)}"
   513 proof (induct k)
   513 proof (induct k)
   514   case 0
   514   case 0
   515   have *: "{f. \<forall>i. f i = i} = {id}"
   515   have *: "{f. \<forall>i. f i = i} = {id}"
   530   show ?case
   530   show ?case
   531     by metis
   531     by metis
   532 qed
   532 qed
   533 
   533 
   534 
   534 
   535 lemma%important  det_linear_rows_sum_lemma:
   535 lemma  det_linear_rows_sum_lemma:
   536   assumes fS: "finite S"
   536   assumes fS: "finite S"
   537     and fT: "finite T"
   537     and fT: "finite T"
   538   shows "det ((\<chi> i. if i \<in> T then sum (a i) S else c i):: 'a::comm_ring_1^'n^'n) =
   538   shows "det ((\<chi> i. if i \<in> T then sum (a i) S else c i):: 'a::comm_ring_1^'n^'n) =
   539     sum (\<lambda>f. det((\<chi> i. if i \<in> T then a i (f i) else c i)::'a^'n^'n))
   539     sum (\<lambda>f. det((\<chi> i. if i \<in> T then a i (f i) else c i)::'a^'n^'n))
   540       {f. (\<forall>i \<in> T. f i \<in> S) \<and> (\<forall>i. i \<notin> T \<longrightarrow> f i = i)}"
   540       {f. (\<forall>i \<in> T. f i \<in> S) \<and> (\<forall>i. i \<notin> T \<longrightarrow> f i = i)}"
   541   using fT
   541   using fT
   542 proof%unimportant (induct T arbitrary: a c set: finite)
   542 proof (induct T arbitrary: a c set: finite)
   543   case empty
   543   case empty
   544   have th0: "\<And>x y. (\<chi> i. if i \<in> {} then x i else y i) = (\<chi> i. y i)"
   544   have th0: "\<And>x y. (\<chi> i. if i \<in> {} then x i else y i) = (\<chi> i. y i)"
   545     by vector
   545     by vector
   546   from empty.prems show ?case
   546   from empty.prems show ?case
   547     unfolding th0 by (simp add: eq_id_iff)
   547     unfolding th0 by (simp add: eq_id_iff)
   575     using \<open>z \<notin> T\<close>
   575     using \<open>z \<notin> T\<close>
   576     by (intro sum.reindex_bij_witness[where i="?k" and j="?h"])
   576     by (intro sum.reindex_bij_witness[where i="?k" and j="?h"])
   577        (auto intro!: cong[OF refl[of det]] simp: vec_eq_iff)
   577        (auto intro!: cong[OF refl[of det]] simp: vec_eq_iff)
   578 qed
   578 qed
   579 
   579 
   580 lemma%unimportant  det_linear_rows_sum:
   580 lemma  det_linear_rows_sum:
   581   fixes S :: "'n::finite set"
   581   fixes S :: "'n::finite set"
   582   assumes fS: "finite S"
   582   assumes fS: "finite S"
   583   shows "det (\<chi> i. sum (a i) S) =
   583   shows "det (\<chi> i. sum (a i) S) =
   584     sum (\<lambda>f. det (\<chi> i. a i (f i) :: 'a::comm_ring_1 ^ 'n^'n)) {f. \<forall>i. f i \<in> S}"
   584     sum (\<lambda>f. det (\<chi> i. a i (f i) :: 'a::comm_ring_1 ^ 'n^'n)) {f. \<forall>i. f i \<in> S}"
   585 proof -
   585 proof -
   587     by vector
   587     by vector
   588   from det_linear_rows_sum_lemma[OF fS, of "UNIV :: 'n set" a, unfolded th0, OF finite]
   588   from det_linear_rows_sum_lemma[OF fS, of "UNIV :: 'n set" a, unfolded th0, OF finite]
   589   show ?thesis by simp
   589   show ?thesis by simp
   590 qed
   590 qed
   591 
   591 
   592 lemma%unimportant  matrix_mul_sum_alt:
   592 lemma  matrix_mul_sum_alt:
   593   fixes A B :: "'a::comm_ring_1^'n^'n"
   593   fixes A B :: "'a::comm_ring_1^'n^'n"
   594   shows "A ** B = (\<chi> i. sum (\<lambda>k. A$i$k *s B $ k) (UNIV :: 'n set))"
   594   shows "A ** B = (\<chi> i. sum (\<lambda>k. A$i$k *s B $ k) (UNIV :: 'n set))"
   595   by (vector matrix_matrix_mult_def sum_component)
   595   by (vector matrix_matrix_mult_def sum_component)
   596 
   596 
   597 lemma%unimportant  det_rows_mul:
   597 lemma  det_rows_mul:
   598   "det((\<chi> i. c i *s a i)::'a::comm_ring_1^'n^'n) =
   598   "det((\<chi> i. c i *s a i)::'a::comm_ring_1^'n^'n) =
   599     prod (\<lambda>i. c i) (UNIV:: 'n set) * det((\<chi> i. a i)::'a^'n^'n)"
   599     prod (\<lambda>i. c i) (UNIV:: 'n set) * det((\<chi> i. a i)::'a^'n^'n)"
   600 proof (simp add: det_def sum_distrib_left cong add: prod.cong, rule sum.cong)
   600 proof (simp add: det_def sum_distrib_left cong add: prod.cong, rule sum.cong)
   601   let ?U = "UNIV :: 'n set"
   601   let ?U = "UNIV :: 'n set"
   602   let ?PU = "{p. p permutes ?U}"
   602   let ?PU = "{p. p permutes ?U}"
   610   then show "?s * (\<Prod>xa\<in>?U. c xa * a xa $ p xa) =
   610   then show "?s * (\<Prod>xa\<in>?U. c xa * a xa $ p xa) =
   611     prod c ?U * (?s* (\<Prod>xa\<in>?U. a xa $ p xa))"
   611     prod c ?U * (?s* (\<Prod>xa\<in>?U. a xa $ p xa))"
   612     by (simp add: field_simps)
   612     by (simp add: field_simps)
   613 qed rule
   613 qed rule
   614 
   614 
   615 lemma%important  det_mul:
   615 proposition  det_mul:
   616   fixes A B :: "'a::comm_ring_1^'n^'n"
   616   fixes A B :: "'a::comm_ring_1^'n^'n"
   617   shows "det (A ** B) = det A * det B"
   617   shows "det (A ** B) = det A * det B"
   618 proof%unimportant -
   618 proof -
   619   let ?U = "UNIV :: 'n set"
   619   let ?U = "UNIV :: 'n set"
   620   let ?F = "{f. (\<forall>i \<in> ?U. f i \<in> ?U) \<and> (\<forall>i. i \<notin> ?U \<longrightarrow> f i = i)}"
   620   let ?F = "{f. (\<forall>i \<in> ?U. f i \<in> ?U) \<and> (\<forall>i. i \<notin> ?U \<longrightarrow> f i = i)}"
   621   let ?PU = "{p. p permutes ?U}"
   621   let ?PU = "{p. p permutes ?U}"
   622   have "p \<in> ?F" if "p permutes ?U" for p
   622   have "p \<in> ?F" if "p permutes ?U" for p
   623     by simp
   623     by simp
   712 qed
   712 qed
   713 
   713 
   714 
   714 
   715 subsection \<open>Relation to invertibility\<close>
   715 subsection \<open>Relation to invertibility\<close>
   716 
   716 
   717 lemma%important  invertible_det_nz:
   717 proposition  invertible_det_nz:
   718   fixes A::"'a::{field}^'n^'n"
   718   fixes A::"'a::{field}^'n^'n"
   719   shows "invertible A \<longleftrightarrow> det A \<noteq> 0"
   719   shows "invertible A \<longleftrightarrow> det A \<noteq> 0"
   720 proof%unimportant (cases "invertible A")
   720 proof (cases "invertible A")
   721   case True
   721   case True
   722   then obtain B :: "'a^'n^'n" where B: "A ** B = mat 1"
   722   then obtain B :: "'a^'n^'n" where B: "A ** B = mat 1"
   723     unfolding invertible_right_inverse by blast
   723     unfolding invertible_right_inverse by blast
   724   then have "det (A ** B) = det (mat 1 :: 'a^'n^'n)"
   724   then have "det (A ** B) = det (mat 1 :: 'a^'n^'n)"
   725     by simp
   725     by simp
   746   then show ?thesis
   746   then show ?thesis
   747     by (simp add: False)
   747     by (simp add: False)
   748 qed
   748 qed
   749 
   749 
   750 
   750 
   751 lemma%unimportant  det_nz_iff_inj_gen:
   751 lemma  det_nz_iff_inj_gen:
   752   fixes f :: "'a::field^'n \<Rightarrow> 'a::field^'n"
   752   fixes f :: "'a::field^'n \<Rightarrow> 'a::field^'n"
   753   assumes "Vector_Spaces.linear (*s) (*s) f"
   753   assumes "Vector_Spaces.linear (*s) (*s) f"
   754   shows "det (matrix f) \<noteq> 0 \<longleftrightarrow> inj f"
   754   shows "det (matrix f) \<noteq> 0 \<longleftrightarrow> inj f"
   755 proof
   755 proof
   756   assume "det (matrix f) \<noteq> 0"
   756   assume "det (matrix f) \<noteq> 0"
   761   show "det (matrix f) \<noteq> 0"
   761   show "det (matrix f) \<noteq> 0"
   762     using vec.linear_injective_left_inverse [OF assms \<open>inj f\<close>]
   762     using vec.linear_injective_left_inverse [OF assms \<open>inj f\<close>]
   763     by (metis assms invertible_det_nz invertible_left_inverse matrix_compose_gen matrix_id_mat_1)
   763     by (metis assms invertible_det_nz invertible_left_inverse matrix_compose_gen matrix_id_mat_1)
   764 qed
   764 qed
   765 
   765 
   766 lemma%unimportant  det_nz_iff_inj:
   766 lemma  det_nz_iff_inj:
   767   fixes f :: "real^'n \<Rightarrow> real^'n"
   767   fixes f :: "real^'n \<Rightarrow> real^'n"
   768   assumes "linear f"
   768   assumes "linear f"
   769   shows "det (matrix f) \<noteq> 0 \<longleftrightarrow> inj f"
   769   shows "det (matrix f) \<noteq> 0 \<longleftrightarrow> inj f"
   770   using det_nz_iff_inj_gen[of f] assms
   770   using det_nz_iff_inj_gen[of f] assms
   771   unfolding linear_matrix_vector_mul_eq .
   771   unfolding linear_matrix_vector_mul_eq .
   772 
   772 
   773 lemma%unimportant  det_eq_0_rank:
   773 lemma  det_eq_0_rank:
   774   fixes A :: "real^'n^'n"
   774   fixes A :: "real^'n^'n"
   775   shows "det A = 0 \<longleftrightarrow> rank A < CARD('n)"
   775   shows "det A = 0 \<longleftrightarrow> rank A < CARD('n)"
   776   using invertible_det_nz [of A]
   776   using invertible_det_nz [of A]
   777   by (auto simp: matrix_left_invertible_injective invertible_left_inverse less_rank_noninjective)
   777   by (auto simp: matrix_left_invertible_injective invertible_left_inverse less_rank_noninjective)
   778 
   778 
   779 subsubsection  \<open>Invertibility of matrices and corresponding linear functions\<close>
   779 subsubsection%important  \<open>Invertibility of matrices and corresponding linear functions\<close>
   780 
   780 
   781 lemma%important  matrix_left_invertible_gen:
   781 lemma  matrix_left_invertible_gen:
   782   fixes f :: "'a::field^'m \<Rightarrow> 'a::field^'n"
   782   fixes f :: "'a::field^'m \<Rightarrow> 'a::field^'n"
   783   assumes "Vector_Spaces.linear (*s) (*s) f"
   783   assumes "Vector_Spaces.linear (*s) (*s) f"
   784   shows "((\<exists>B. B ** matrix f = mat 1) \<longleftrightarrow> (\<exists>g. Vector_Spaces.linear (*s) (*s) g \<and> g \<circ> f = id))"
   784   shows "((\<exists>B. B ** matrix f = mat 1) \<longleftrightarrow> (\<exists>g. Vector_Spaces.linear (*s) (*s) g \<and> g \<circ> f = id))"
   785 proof%unimportant safe
   785 proof safe
   786   fix B
   786   fix B
   787   assume 1: "B ** matrix f = mat 1"
   787   assume 1: "B ** matrix f = mat 1"
   788   show "\<exists>g. Vector_Spaces.linear (*s) (*s) g \<and> g \<circ> f = id"
   788   show "\<exists>g. Vector_Spaces.linear (*s) (*s) g \<and> g \<circ> f = id"
   789   proof (intro exI conjI)
   789   proof (intro exI conjI)
   790     show "Vector_Spaces.linear (*s) (*s) (\<lambda>y. B *v y)"
   790     show "Vector_Spaces.linear (*s) (*s) (\<lambda>y. B *v y)"
   799   then have "matrix g ** matrix f = mat 1"
   799   then have "matrix g ** matrix f = mat 1"
   800     by (metis assms matrix_compose_gen matrix_id_mat_1)
   800     by (metis assms matrix_compose_gen matrix_id_mat_1)
   801   then show "\<exists>B. B ** matrix f = mat 1" ..
   801   then show "\<exists>B. B ** matrix f = mat 1" ..
   802 qed
   802 qed
   803 
   803 
   804 lemma%unimportant  matrix_left_invertible:
   804 lemma  matrix_left_invertible:
   805   "linear f \<Longrightarrow> ((\<exists>B. B ** matrix f = mat 1) \<longleftrightarrow> (\<exists>g. linear g \<and> g \<circ> f = id))" for f::"real^'m \<Rightarrow> real^'n"
   805   "linear f \<Longrightarrow> ((\<exists>B. B ** matrix f = mat 1) \<longleftrightarrow> (\<exists>g. linear g \<and> g \<circ> f = id))" for f::"real^'m \<Rightarrow> real^'n"
   806   using matrix_left_invertible_gen[of f]
   806   using matrix_left_invertible_gen[of f]
   807   by (auto simp: linear_matrix_vector_mul_eq)
   807   by (auto simp: linear_matrix_vector_mul_eq)
   808 
   808 
   809 lemma%unimportant  matrix_right_invertible_gen:
   809 lemma  matrix_right_invertible_gen:
   810   fixes f :: "'a::field^'m \<Rightarrow> 'a^'n"
   810   fixes f :: "'a::field^'m \<Rightarrow> 'a^'n"
   811   assumes "Vector_Spaces.linear (*s) (*s) f"
   811   assumes "Vector_Spaces.linear (*s) (*s) f"
   812   shows "((\<exists>B. matrix f ** B = mat 1) \<longleftrightarrow> (\<exists>g. Vector_Spaces.linear (*s) (*s) g \<and> f \<circ> g = id))"
   812   shows "((\<exists>B. matrix f ** B = mat 1) \<longleftrightarrow> (\<exists>g. Vector_Spaces.linear (*s) (*s) g \<and> f \<circ> g = id))"
   813 proof safe
   813 proof safe
   814   fix B
   814   fix B
   827   then have "matrix f ** matrix g = mat 1"
   827   then have "matrix f ** matrix g = mat 1"
   828     by (metis assms matrix_compose_gen matrix_id_mat_1)
   828     by (metis assms matrix_compose_gen matrix_id_mat_1)
   829   then show "\<exists>B. matrix f ** B = mat 1" ..
   829   then show "\<exists>B. matrix f ** B = mat 1" ..
   830 qed
   830 qed
   831 
   831 
   832 lemma%unimportant  matrix_right_invertible:
   832 lemma  matrix_right_invertible:
   833   "linear f \<Longrightarrow> ((\<exists>B. matrix f ** B = mat 1) \<longleftrightarrow> (\<exists>g. linear g \<and> f \<circ> g = id))" for f::"real^'m \<Rightarrow> real^'n"
   833   "linear f \<Longrightarrow> ((\<exists>B. matrix f ** B = mat 1) \<longleftrightarrow> (\<exists>g. linear g \<and> f \<circ> g = id))" for f::"real^'m \<Rightarrow> real^'n"
   834   using matrix_right_invertible_gen[of f]
   834   using matrix_right_invertible_gen[of f]
   835   by (auto simp: linear_matrix_vector_mul_eq)
   835   by (auto simp: linear_matrix_vector_mul_eq)
   836 
   836 
   837 lemma%unimportant  matrix_invertible_gen:
   837 lemma  matrix_invertible_gen:
   838   fixes f :: "'a::field^'m \<Rightarrow> 'a::field^'n"
   838   fixes f :: "'a::field^'m \<Rightarrow> 'a::field^'n"
   839   assumes "Vector_Spaces.linear (*s) (*s) f"
   839   assumes "Vector_Spaces.linear (*s) (*s) f"
   840   shows  "invertible (matrix f) \<longleftrightarrow> (\<exists>g. Vector_Spaces.linear (*s) (*s) g \<and> f \<circ> g = id \<and> g \<circ> f = id)"
   840   shows  "invertible (matrix f) \<longleftrightarrow> (\<exists>g. Vector_Spaces.linear (*s) (*s) g \<and> f \<circ> g = id \<and> g \<circ> f = id)"
   841     (is "?lhs = ?rhs")
   841     (is "?lhs = ?rhs")
   842 proof
   842 proof
   845 next
   845 next
   846   assume ?rhs then show ?lhs
   846   assume ?rhs then show ?lhs
   847     by (metis assms invertible_def matrix_compose_gen matrix_id_mat_1)
   847     by (metis assms invertible_def matrix_compose_gen matrix_id_mat_1)
   848 qed
   848 qed
   849 
   849 
   850 lemma%unimportant  matrix_invertible:
   850 lemma  matrix_invertible:
   851   "linear f \<Longrightarrow> invertible (matrix f) \<longleftrightarrow> (\<exists>g. linear g \<and> f \<circ> g = id \<and> g \<circ> f = id)"
   851   "linear f \<Longrightarrow> invertible (matrix f) \<longleftrightarrow> (\<exists>g. linear g \<and> f \<circ> g = id \<and> g \<circ> f = id)"
   852   for f::"real^'m \<Rightarrow> real^'n"
   852   for f::"real^'m \<Rightarrow> real^'n"
   853   using matrix_invertible_gen[of f]
   853   using matrix_invertible_gen[of f]
   854   by (auto simp: linear_matrix_vector_mul_eq)
   854   by (auto simp: linear_matrix_vector_mul_eq)
   855 
   855 
   856 lemma%unimportant  invertible_eq_bij:
   856 lemma  invertible_eq_bij:
   857   fixes m :: "'a::field^'m^'n"
   857   fixes m :: "'a::field^'m^'n"
   858   shows "invertible m \<longleftrightarrow> bij ((*v) m)"
   858   shows "invertible m \<longleftrightarrow> bij ((*v) m)"
   859   using matrix_invertible_gen[OF matrix_vector_mul_linear_gen, of m, simplified matrix_of_matrix_vector_mul]
   859   using matrix_invertible_gen[OF matrix_vector_mul_linear_gen, of m, simplified matrix_of_matrix_vector_mul]
   860   by (metis bij_betw_def left_right_inverse_eq matrix_vector_mul_linear_gen o_bij
   860   by (metis bij_betw_def left_right_inverse_eq matrix_vector_mul_linear_gen o_bij
   861       vec.linear_injective_left_inverse vec.linear_surjective_right_inverse)
   861       vec.linear_injective_left_inverse vec.linear_surjective_right_inverse)
   862 
   862 
   863 
   863 
   864 subsection \<open>Cramer's rule\<close>
   864 subsection \<open>Cramer's rule\<close>
   865 
   865 
   866 lemma%important  cramer_lemma_transpose:
   866 lemma  cramer_lemma_transpose:
   867   fixes A:: "'a::{field}^'n^'n"
   867   fixes A:: "'a::{field}^'n^'n"
   868     and x :: "'a::{field}^'n"
   868     and x :: "'a::{field}^'n"
   869   shows "det ((\<chi> i. if i = k then sum (\<lambda>i. x$i *s row i A) (UNIV::'n set)
   869   shows "det ((\<chi> i. if i = k then sum (\<lambda>i. x$i *s row i A) (UNIV::'n set)
   870                              else row i A)::'a::{field}^'n^'n) = x$k * det A"
   870                              else row i A)::'a::{field}^'n^'n) = x$k * det A"
   871   (is "?lhs = ?rhs")
   871   (is "?lhs = ?rhs")
   872 proof%unimportant -
   872 proof -
   873   let ?U = "UNIV :: 'n set"
   873   let ?U = "UNIV :: 'n set"
   874   let ?Uk = "?U - {k}"
   874   let ?Uk = "?U - {k}"
   875   have U: "?U = insert k ?Uk"
   875   have U: "?U = insert k ?Uk"
   876     by blast
   876     by blast
   877   have kUk: "k \<notin> ?Uk"
   877   have kUk: "k \<notin> ?Uk"
   897     unfolding thd1
   897     unfolding thd1
   898     apply (simp add: field_simps)
   898     apply (simp add: field_simps)
   899     done
   899     done
   900 qed
   900 qed
   901 
   901 
   902 lemma%important  cramer_lemma:
   902 proposition  cramer_lemma:
   903   fixes A :: "'a::{field}^'n^'n"
   903   fixes A :: "'a::{field}^'n^'n"
   904   shows "det((\<chi> i j. if j = k then (A *v x)$i else A$i$j):: 'a::{field}^'n^'n) = x$k * det A"
   904   shows "det((\<chi> i j. if j = k then (A *v x)$i else A$i$j):: 'a::{field}^'n^'n) = x$k * det A"
   905 proof%unimportant -
   905 proof -
   906   let ?U = "UNIV :: 'n set"
   906   let ?U = "UNIV :: 'n set"
   907   have *: "\<And>c. sum (\<lambda>i. c i *s row i (transpose A)) ?U = sum (\<lambda>i. c i *s column i A) ?U"
   907   have *: "\<And>c. sum (\<lambda>i. c i *s row i (transpose A)) ?U = sum (\<lambda>i. c i *s column i A) ?U"
   908     by (auto intro: sum.cong)
   908     by (auto intro: sum.cong)
   909   show ?thesis
   909   show ?thesis
   910     unfolding matrix_mult_sum
   910     unfolding matrix_mult_sum
   914     apply (rule cong[OF refl[of det]])
   914     apply (rule cong[OF refl[of det]])
   915     apply (vector transpose_def column_def row_def)
   915     apply (vector transpose_def column_def row_def)
   916     done
   916     done
   917 qed
   917 qed
   918 
   918 
   919 lemma%important  cramer:
   919 proposition  cramer:
   920   fixes A ::"'a::{field}^'n^'n"
   920   fixes A ::"'a::{field}^'n^'n"
   921   assumes d0: "det A \<noteq> 0"
   921   assumes d0: "det A \<noteq> 0"
   922   shows "A *v x = b \<longleftrightarrow> x = (\<chi> k. det(\<chi> i j. if j=k then b$i else A$i$j) / det A)"
   922   shows "A *v x = b \<longleftrightarrow> x = (\<chi> k. det(\<chi> i j. if j=k then b$i else A$i$j) / det A)"
   923 proof%unimportant -
   923 proof -
   924   from d0 obtain B where B: "A ** B = mat 1" "B ** A = mat 1"
   924   from d0 obtain B where B: "A ** B = mat 1" "B ** A = mat 1"
   925     unfolding invertible_det_nz[symmetric] invertible_def
   925     unfolding invertible_det_nz[symmetric] invertible_def
   926     by blast
   926     by blast
   927   have "(A ** B) *v b = b"
   927   have "(A ** B) *v b = b"
   928     by (simp add: B)
   928     by (simp add: B)
   939   }
   939   }
   940   with xe show ?thesis
   940   with xe show ?thesis
   941     by auto
   941     by auto
   942 qed
   942 qed
   943 
   943 
   944 lemma%unimportant  det_1: "det (A::'a::comm_ring_1^1^1) = A$1$1"
   944 lemma  det_1: "det (A::'a::comm_ring_1^1^1) = A$1$1"
   945   by (simp add: det_def sign_id)
   945   by (simp add: det_def sign_id)
   946 
   946 
   947 lemma%unimportant  det_2: "det (A::'a::comm_ring_1^2^2) = A$1$1 * A$2$2 - A$1$2 * A$2$1"
   947 lemma  det_2: "det (A::'a::comm_ring_1^2^2) = A$1$1 * A$2$2 - A$1$2 * A$2$1"
   948 proof -
   948 proof -
   949   have f12: "finite {2::2}" "1 \<notin> {2::2}" by auto
   949   have f12: "finite {2::2}" "1 \<notin> {2::2}" by auto
   950   show ?thesis
   950   show ?thesis
   951     unfolding det_def UNIV_2
   951     unfolding det_def UNIV_2
   952     unfolding sum_over_permutations_insert[OF f12]
   952     unfolding sum_over_permutations_insert[OF f12]
   953     unfolding permutes_sing
   953     unfolding permutes_sing
   954     by (simp add: sign_swap_id sign_id swap_id_eq)
   954     by (simp add: sign_swap_id sign_id swap_id_eq)
   955 qed
   955 qed
   956 
   956 
   957 lemma%unimportant  det_3:
   957 lemma  det_3:
   958   "det (A::'a::comm_ring_1^3^3) =
   958   "det (A::'a::comm_ring_1^3^3) =
   959     A$1$1 * A$2$2 * A$3$3 +
   959     A$1$1 * A$2$2 * A$3$3 +
   960     A$1$2 * A$2$3 * A$3$1 +
   960     A$1$2 * A$2$3 * A$3$1 +
   961     A$1$3 * A$2$1 * A$3$2 -
   961     A$1$3 * A$2$1 * A$3$2 -
   962     A$1$1 * A$2$3 * A$3$2 -
   962     A$1$1 * A$2$3 * A$3$2 -
   974     unfolding sum_over_permutations_insert[OF f23]
   974     unfolding sum_over_permutations_insert[OF f23]
   975     unfolding permutes_sing
   975     unfolding permutes_sing
   976     by (simp add: sign_swap_id permutation_swap_id sign_compose sign_id swap_id_eq)
   976     by (simp add: sign_swap_id permutation_swap_id sign_compose sign_id swap_id_eq)
   977 qed
   977 qed
   978 
   978 
   979 lemma%important  det_orthogonal_matrix:
   979 proposition  det_orthogonal_matrix:
   980   fixes Q:: "'a::linordered_idom^'n^'n"
   980   fixes Q:: "'a::linordered_idom^'n^'n"
   981   assumes oQ: "orthogonal_matrix Q"
   981   assumes oQ: "orthogonal_matrix Q"
   982   shows "det Q = 1 \<or> det Q = - 1"
   982   shows "det Q = 1 \<or> det Q = - 1"
   983 proof%unimportant -
   983 proof -
   984   have "Q ** transpose Q = mat 1"
   984   have "Q ** transpose Q = mat 1"
   985     by (metis oQ orthogonal_matrix_def)
   985     by (metis oQ orthogonal_matrix_def)
   986   then have "det (Q ** transpose Q) = det (mat 1:: 'a^'n^'n)"
   986   then have "det (Q ** transpose Q) = det (mat 1:: 'a^'n^'n)"
   987     by simp
   987     by simp
   988   then have "det Q * det Q = 1"
   988   then have "det Q * det Q = 1"
   989     by (simp add: det_mul)
   989     by (simp add: det_mul)
   990   then show ?thesis
   990   then show ?thesis
   991     by (simp add: square_eq_1_iff)
   991     by (simp add: square_eq_1_iff)
   992 qed
   992 qed
   993 
   993 
   994 lemma%important  orthogonal_transformation_det [simp]:
   994 proposition  orthogonal_transformation_det [simp]:
   995   fixes f :: "real^'n \<Rightarrow> real^'n"
   995   fixes f :: "real^'n \<Rightarrow> real^'n"
   996   shows "orthogonal_transformation f \<Longrightarrow> \<bar>det (matrix f)\<bar> = 1"
   996   shows "orthogonal_transformation f \<Longrightarrow> \<bar>det (matrix f)\<bar> = 1"
   997   using%unimportant det_orthogonal_matrix orthogonal_transformation_matrix by fastforce
   997   using%unimportant det_orthogonal_matrix orthogonal_transformation_matrix by fastforce
   998 
   998 
   999 subsection  \<open>Rotation, reflection, rotoinversion\<close>
   999 subsection  \<open>Rotation, reflection, rotoinversion\<close>
  1000 
  1000 
  1001 definition%important  "rotation_matrix Q \<longleftrightarrow> orthogonal_matrix Q \<and> det Q = 1"
  1001 definition%important  "rotation_matrix Q \<longleftrightarrow> orthogonal_matrix Q \<and> det Q = 1"
  1002 definition%important  "rotoinversion_matrix Q \<longleftrightarrow> orthogonal_matrix Q \<and> det Q = - 1"
  1002 definition%important  "rotoinversion_matrix Q \<longleftrightarrow> orthogonal_matrix Q \<and> det Q = - 1"
  1003 
  1003 
  1004 lemma%important  orthogonal_rotation_or_rotoinversion:
  1004 lemma  orthogonal_rotation_or_rotoinversion:
  1005   fixes Q :: "'a::linordered_idom^'n^'n"
  1005   fixes Q :: "'a::linordered_idom^'n^'n"
  1006   shows " orthogonal_matrix Q \<longleftrightarrow> rotation_matrix Q \<or> rotoinversion_matrix Q"
  1006   shows " orthogonal_matrix Q \<longleftrightarrow> rotation_matrix Q \<or> rotoinversion_matrix Q"
  1007   by%unimportant (metis rotoinversion_matrix_def rotation_matrix_def det_orthogonal_matrix)
  1007   by (metis rotoinversion_matrix_def rotation_matrix_def det_orthogonal_matrix)
  1008 
  1008 
  1009 text\<open> Slightly stronger results giving rotation, but only in two or more dimensions\<close>
  1009 text\<open> Slightly stronger results giving rotation, but only in two or more dimensions\<close>
  1010 
  1010 
  1011 lemma%unimportant  rotation_matrix_exists_basis:
  1011 lemma  rotation_matrix_exists_basis:
  1012   fixes a :: "real^'n"
  1012   fixes a :: "real^'n"
  1013   assumes 2: "2 \<le> CARD('n)" and "norm a = 1"
  1013   assumes 2: "2 \<le> CARD('n)" and "norm a = 1"
  1014   obtains A where "rotation_matrix A" "A *v (axis k 1) = a"
  1014   obtains A where "rotation_matrix A" "A *v (axis k 1) = a"
  1015 proof -
  1015 proof -
  1016   obtain A where "orthogonal_matrix A" and A: "A *v (axis k 1) = a"
  1016   obtain A where "orthogonal_matrix A" and A: "A *v (axis k 1) = a"
  1047         using \<open>j \<noteq> k\<close> A by (simp add: matrix_vector_column axis_def scalar_mult_eq_scaleR if_distrib [of "\<lambda>z. z *\<^sub>R c" for c] cong: if_cong)
  1047         using \<open>j \<noteq> k\<close> A by (simp add: matrix_vector_column axis_def scalar_mult_eq_scaleR if_distrib [of "\<lambda>z. z *\<^sub>R c" for c] cong: if_cong)
  1048     qed
  1048     qed
  1049   qed
  1049   qed
  1050 qed
  1050 qed
  1051 
  1051 
  1052 lemma%unimportant  rotation_exists_1:
  1052 lemma  rotation_exists_1:
  1053   fixes a :: "real^'n"
  1053   fixes a :: "real^'n"
  1054   assumes "2 \<le> CARD('n)" "norm a = 1" "norm b = 1"
  1054   assumes "2 \<le> CARD('n)" "norm a = 1" "norm b = 1"
  1055   obtains f where "orthogonal_transformation f" "det(matrix f) = 1" "f a = b"
  1055   obtains f where "orthogonal_transformation f" "det(matrix f) = 1" "f a = b"
  1056 proof -
  1056 proof -
  1057   obtain k::'n where True
  1057   obtain k::'n where True
  1070       using AB unfolding orthogonal_matrix_def rotation_matrix_def
  1070       using AB unfolding orthogonal_matrix_def rotation_matrix_def
  1071       by (metis eq matrix_mul_rid matrix_vector_mul_assoc)
  1071       by (metis eq matrix_mul_rid matrix_vector_mul_assoc)
  1072   qed
  1072   qed
  1073 qed
  1073 qed
  1074 
  1074 
  1075 lemma%unimportant  rotation_exists:
  1075 lemma  rotation_exists:
  1076   fixes a :: "real^'n"
  1076   fixes a :: "real^'n"
  1077   assumes 2: "2 \<le> CARD('n)" and eq: "norm a = norm b"
  1077   assumes 2: "2 \<le> CARD('n)" and eq: "norm a = norm b"
  1078   obtains f where "orthogonal_transformation f" "det(matrix f) = 1" "f a = b"
  1078   obtains f where "orthogonal_transformation f" "det(matrix f) = 1" "f a = b"
  1079 proof (cases "a = 0 \<or> b = 0")
  1079 proof (cases "a = 0 \<or> b = 0")
  1080   case True
  1080   case True
  1092     using f' False
  1092     using f' False
  1093     by (simp add: eq scale)
  1093     by (simp add: eq scale)
  1094   with f show thesis ..
  1094   with f show thesis ..
  1095 qed
  1095 qed
  1096 
  1096 
  1097 lemma%unimportant  rotation_rightward_line:
  1097 lemma  rotation_rightward_line:
  1098   fixes a :: "real^'n"
  1098   fixes a :: "real^'n"
  1099   obtains f where "orthogonal_transformation f" "2 \<le> CARD('n) \<Longrightarrow> det(matrix f) = 1"
  1099   obtains f where "orthogonal_transformation f" "2 \<le> CARD('n) \<Longrightarrow> det(matrix f) = 1"
  1100                   "f(norm a *\<^sub>R axis k 1) = a"
  1100                   "f(norm a *\<^sub>R axis k 1) = a"
  1101 proof (cases "CARD('n) = 1")
  1101 proof (cases "CARD('n) = 1")
  1102   case True
  1102   case True