35 |
35 |
36 text \<open>Definition of determinant.\<close> |
36 text \<open>Definition of determinant.\<close> |
37 |
37 |
38 definition det:: "'a::comm_ring_1^'n^'n \<Rightarrow> 'a" where |
38 definition det:: "'a::comm_ring_1^'n^'n \<Rightarrow> 'a" where |
39 "det A = |
39 "det A = |
40 sum (\<lambda>p. of_int (sign p) * setprod (\<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>A few general lemmas we need below.\<close> |
43 text \<open>A few general lemmas we need below.\<close> |
44 |
44 |
45 lemma setprod_permute: |
45 lemma prod_permute: |
46 assumes p: "p permutes S" |
46 assumes p: "p permutes S" |
47 shows "setprod f S = setprod (f \<circ> p) S" |
47 shows "prod f S = prod (f \<circ> p) S" |
48 using assms by (fact setprod.permute) |
48 using assms by (fact prod.permute) |
49 |
49 |
50 lemma setproduct_permute_nat_interval: |
50 lemma product_permute_nat_interval: |
51 fixes m n :: nat |
51 fixes m n :: nat |
52 shows "p permutes {m..n} \<Longrightarrow> setprod f {m..n} = setprod (f \<circ> p) {m..n}" |
52 shows "p permutes {m..n} \<Longrightarrow> prod f {m..n} = prod (f \<circ> p) {m..n}" |
53 by (blast intro!: setprod_permute) |
53 by (blast intro!: prod_permute) |
54 |
54 |
55 text \<open>Basic determinant properties.\<close> |
55 text \<open>Basic determinant properties.\<close> |
56 |
56 |
57 lemma det_transpose: "det (transpose A) = det (A::'a::comm_ring_1 ^'n^'n)" |
57 lemma det_transpose: "det (transpose A) = det (A::'a::comm_ring_1 ^'n^'n)" |
58 proof - |
58 proof - |
68 by (metis sign_inverse fU p mem_Collect_eq permutation_permutes) |
68 by (metis sign_inverse fU p mem_Collect_eq permutation_permutes) |
69 from permutes_inj[OF pU] |
69 from permutes_inj[OF pU] |
70 have pi: "inj_on p ?U" |
70 have pi: "inj_on p ?U" |
71 by (blast intro: subset_inj_on) |
71 by (blast intro: subset_inj_on) |
72 from permutes_image[OF pU] |
72 from permutes_image[OF pU] |
73 have "setprod (\<lambda>i. ?di (transpose A) i (inv p i)) ?U = |
73 have "prod (\<lambda>i. ?di (transpose A) i (inv p i)) ?U = |
74 setprod (\<lambda>i. ?di (transpose A) i (inv p i)) (p ` ?U)" |
74 prod (\<lambda>i. ?di (transpose A) i (inv p i)) (p ` ?U)" |
75 by simp |
75 by simp |
76 also have "\<dots> = setprod ((\<lambda>i. ?di (transpose A) i (inv p i)) \<circ> p) ?U" |
76 also have "\<dots> = prod ((\<lambda>i. ?di (transpose A) i (inv p i)) \<circ> p) ?U" |
77 unfolding setprod.reindex[OF pi] .. |
77 unfolding prod.reindex[OF pi] .. |
78 also have "\<dots> = setprod (\<lambda>i. ?di A i (p i)) ?U" |
78 also have "\<dots> = prod (\<lambda>i. ?di A i (p i)) ?U" |
79 proof - |
79 proof - |
80 { |
80 { |
81 fix i |
81 fix i |
82 assume i: "i \<in> ?U" |
82 assume i: "i \<in> ?U" |
83 from i permutes_inv_o[OF pU] permutes_in_image[OF pU] |
83 from i permutes_inv_o[OF pU] permutes_in_image[OF pU] |
84 have "((\<lambda>i. ?di (transpose A) i (inv p i)) \<circ> p) i = ?di A i (p i)" |
84 have "((\<lambda>i. ?di (transpose A) i (inv p i)) \<circ> p) i = ?di A i (p i)" |
85 unfolding transpose_def by (simp add: fun_eq_iff) |
85 unfolding transpose_def by (simp add: fun_eq_iff) |
86 } |
86 } |
87 then show "setprod ((\<lambda>i. ?di (transpose A) i (inv p i)) \<circ> p) ?U = |
87 then show "prod ((\<lambda>i. ?di (transpose A) i (inv p i)) \<circ> p) ?U = |
88 setprod (\<lambda>i. ?di A i (p i)) ?U" |
88 prod (\<lambda>i. ?di A i (p i)) ?U" |
89 by (auto intro: setprod.cong) |
89 by (auto intro: prod.cong) |
90 qed |
90 qed |
91 finally have "of_int (sign (inv p)) * (setprod (\<lambda>i. ?di (transpose A) i (inv p i)) ?U) = |
91 finally have "of_int (sign (inv p)) * (prod (\<lambda>i. ?di (transpose A) i (inv p i)) ?U) = |
92 of_int (sign p) * (setprod (\<lambda>i. ?di A i (p i)) ?U)" |
92 of_int (sign p) * (prod (\<lambda>i. ?di A i (p i)) ?U)" |
93 using sth by simp |
93 using sth by simp |
94 } |
94 } |
95 then show ?thesis |
95 then show ?thesis |
96 unfolding det_def |
96 unfolding det_def |
97 apply (subst sum_permutations_inverse) |
97 apply (subst sum_permutations_inverse) |
102 qed |
102 qed |
103 |
103 |
104 lemma det_lowerdiagonal: |
104 lemma det_lowerdiagonal: |
105 fixes A :: "'a::comm_ring_1^('n::{finite,wellorder})^('n::{finite,wellorder})" |
105 fixes A :: "'a::comm_ring_1^('n::{finite,wellorder})^('n::{finite,wellorder})" |
106 assumes ld: "\<And>i j. i < j \<Longrightarrow> A$i$j = 0" |
106 assumes ld: "\<And>i j. i < j \<Longrightarrow> A$i$j = 0" |
107 shows "det A = setprod (\<lambda>i. A$i$i) (UNIV:: 'n set)" |
107 shows "det A = prod (\<lambda>i. A$i$i) (UNIV:: 'n set)" |
108 proof - |
108 proof - |
109 let ?U = "UNIV:: 'n set" |
109 let ?U = "UNIV:: 'n set" |
110 let ?PU = "{p. p permutes ?U}" |
110 let ?PU = "{p. p permutes ?U}" |
111 let ?pp = "\<lambda>p. of_int (sign p) * setprod (\<lambda>i. A$i$p i) (UNIV :: 'n set)" |
111 let ?pp = "\<lambda>p. of_int (sign p) * prod (\<lambda>i. A$i$p i) (UNIV :: 'n set)" |
112 have fU: "finite ?U" |
112 have fU: "finite ?U" |
113 by simp |
113 by simp |
114 from finite_permutations[OF fU] have fPU: "finite ?PU" . |
114 from finite_permutations[OF fU] have fPU: "finite ?PU" . |
115 have id0: "{id} \<subseteq> ?PU" |
115 have id0: "{id} \<subseteq> ?PU" |
116 by (auto simp add: permutes_id) |
116 by (auto simp add: permutes_id) |
121 by blast+ |
121 by blast+ |
122 from permutes_natset_le[OF pU] pid obtain i where i: "p i > i" |
122 from permutes_natset_le[OF pU] pid obtain i where i: "p i > i" |
123 by (metis not_le) |
123 by (metis not_le) |
124 from ld[OF i] have ex:"\<exists>i \<in> ?U. A$i$p i = 0" |
124 from ld[OF i] have ex:"\<exists>i \<in> ?U. A$i$p i = 0" |
125 by blast |
125 by blast |
126 from setprod_zero[OF fU ex] have "?pp p = 0" |
126 from prod_zero[OF fU ex] have "?pp p = 0" |
127 by simp |
127 by simp |
128 } |
128 } |
129 then have p0: "\<forall>p \<in> ?PU - {id}. ?pp p = 0" |
129 then have p0: "\<forall>p \<in> ?PU - {id}. ?pp p = 0" |
130 by blast |
130 by blast |
131 from sum.mono_neutral_cong_left[OF fPU id0 p0] show ?thesis |
131 from sum.mono_neutral_cong_left[OF fPU id0 p0] show ?thesis |
133 qed |
133 qed |
134 |
134 |
135 lemma det_upperdiagonal: |
135 lemma det_upperdiagonal: |
136 fixes A :: "'a::comm_ring_1^'n::{finite,wellorder}^'n::{finite,wellorder}" |
136 fixes A :: "'a::comm_ring_1^'n::{finite,wellorder}^'n::{finite,wellorder}" |
137 assumes ld: "\<And>i j. i > j \<Longrightarrow> A$i$j = 0" |
137 assumes ld: "\<And>i j. i > j \<Longrightarrow> A$i$j = 0" |
138 shows "det A = setprod (\<lambda>i. A$i$i) (UNIV:: 'n set)" |
138 shows "det A = prod (\<lambda>i. A$i$i) (UNIV:: 'n set)" |
139 proof - |
139 proof - |
140 let ?U = "UNIV:: 'n set" |
140 let ?U = "UNIV:: 'n set" |
141 let ?PU = "{p. p permutes ?U}" |
141 let ?PU = "{p. p permutes ?U}" |
142 let ?pp = "(\<lambda>p. of_int (sign p) * setprod (\<lambda>i. A$i$p i) (UNIV :: 'n set))" |
142 let ?pp = "(\<lambda>p. of_int (sign p) * prod (\<lambda>i. A$i$p i) (UNIV :: 'n set))" |
143 have fU: "finite ?U" |
143 have fU: "finite ?U" |
144 by simp |
144 by simp |
145 from finite_permutations[OF fU] have fPU: "finite ?PU" . |
145 from finite_permutations[OF fU] have fPU: "finite ?PU" . |
146 have id0: "{id} \<subseteq> ?PU" |
146 have id0: "{id} \<subseteq> ?PU" |
147 by (auto simp add: permutes_id) |
147 by (auto simp add: permutes_id) |
152 by blast+ |
152 by blast+ |
153 from permutes_natset_ge[OF pU] pid obtain i where i: "p i < i" |
153 from permutes_natset_ge[OF pU] pid obtain i where i: "p i < i" |
154 by (metis not_le) |
154 by (metis not_le) |
155 from ld[OF i] have ex:"\<exists>i \<in> ?U. A$i$p i = 0" |
155 from ld[OF i] have ex:"\<exists>i \<in> ?U. A$i$p i = 0" |
156 by blast |
156 by blast |
157 from setprod_zero[OF fU ex] have "?pp p = 0" |
157 from prod_zero[OF fU ex] have "?pp p = 0" |
158 by simp |
158 by simp |
159 } |
159 } |
160 then have p0: "\<forall>p \<in> ?PU -{id}. ?pp p = 0" |
160 then have p0: "\<forall>p \<in> ?PU -{id}. ?pp p = 0" |
161 by blast |
161 by blast |
162 from sum.mono_neutral_cong_left[OF fPU id0 p0] show ?thesis |
162 from sum.mono_neutral_cong_left[OF fPU id0 p0] show ?thesis |
164 qed |
164 qed |
165 |
165 |
166 lemma det_diagonal: |
166 lemma det_diagonal: |
167 fixes A :: "'a::comm_ring_1^'n^'n" |
167 fixes A :: "'a::comm_ring_1^'n^'n" |
168 assumes ld: "\<And>i j. i \<noteq> j \<Longrightarrow> A$i$j = 0" |
168 assumes ld: "\<And>i j. i \<noteq> j \<Longrightarrow> A$i$j = 0" |
169 shows "det A = setprod (\<lambda>i. A$i$i) (UNIV::'n set)" |
169 shows "det A = prod (\<lambda>i. A$i$i) (UNIV::'n set)" |
170 proof - |
170 proof - |
171 let ?U = "UNIV:: 'n set" |
171 let ?U = "UNIV:: 'n set" |
172 let ?PU = "{p. p permutes ?U}" |
172 let ?PU = "{p. p permutes ?U}" |
173 let ?pp = "\<lambda>p. of_int (sign p) * setprod (\<lambda>i. A$i$p i) (UNIV :: 'n set)" |
173 let ?pp = "\<lambda>p. of_int (sign p) * prod (\<lambda>i. A$i$p i) (UNIV :: 'n set)" |
174 have fU: "finite ?U" by simp |
174 have fU: "finite ?U" by simp |
175 from finite_permutations[OF fU] have fPU: "finite ?PU" . |
175 from finite_permutations[OF fU] have fPU: "finite ?PU" . |
176 have id0: "{id} \<subseteq> ?PU" |
176 have id0: "{id} \<subseteq> ?PU" |
177 by (auto simp add: permutes_id) |
177 by (auto simp add: permutes_id) |
178 { |
178 { |
182 by simp |
182 by simp |
183 then obtain i where i: "p i \<noteq> i" |
183 then obtain i where i: "p i \<noteq> i" |
184 unfolding fun_eq_iff by auto |
184 unfolding fun_eq_iff by auto |
185 from ld [OF i [symmetric]] have ex:"\<exists>i \<in> ?U. A$i$p i = 0" |
185 from ld [OF i [symmetric]] have ex:"\<exists>i \<in> ?U. A$i$p i = 0" |
186 by blast |
186 by blast |
187 from setprod_zero [OF fU ex] have "?pp p = 0" |
187 from prod_zero [OF fU ex] have "?pp p = 0" |
188 by simp |
188 by simp |
189 } |
189 } |
190 then have p0: "\<forall>p \<in> ?PU - {id}. ?pp p = 0" |
190 then have p0: "\<forall>p \<in> ?PU - {id}. ?pp p = 0" |
191 by blast |
191 by blast |
192 from sum.mono_neutral_cong_left[OF fPU id0 p0] show ?thesis |
192 from sum.mono_neutral_cong_left[OF fPU id0 p0] show ?thesis |
202 fix i |
202 fix i |
203 assume i: "i \<in> ?U" |
203 assume i: "i \<in> ?U" |
204 have "?f i i = 1" |
204 have "?f i i = 1" |
205 using i by (vector mat_def) |
205 using i by (vector mat_def) |
206 } |
206 } |
207 then have th: "setprod (\<lambda>i. ?f i i) ?U = setprod (\<lambda>x. 1) ?U" |
207 then have th: "prod (\<lambda>i. ?f i i) ?U = prod (\<lambda>x. 1) ?U" |
208 by (auto intro: setprod.cong) |
208 by (auto intro: prod.cong) |
209 { |
209 { |
210 fix i j |
210 fix i j |
211 assume i: "i \<in> ?U" and j: "j \<in> ?U" and ij: "i \<noteq> j" |
211 assume i: "i \<in> ?U" and j: "j \<in> ?U" and ij: "i \<noteq> j" |
212 have "?f i j = 0" using i j ij |
212 have "?f i j = 0" using i j ij |
213 by (vector mat_def) |
213 by (vector mat_def) |
214 } |
214 } |
215 then have "det ?A = setprod (\<lambda>i. ?f i i) ?U" |
215 then have "det ?A = prod (\<lambda>i. ?f i i) ?U" |
216 using det_diagonal by blast |
216 using det_diagonal by blast |
217 also have "\<dots> = 1" |
217 also have "\<dots> = 1" |
218 unfolding th setprod.neutral_const .. |
218 unfolding th prod.neutral_const .. |
219 finally show ?thesis . |
219 finally show ?thesis . |
220 qed |
220 qed |
221 |
221 |
222 lemma det_0: "det (mat 0 :: 'a::comm_ring_1^'n^'n) = 0" |
222 lemma det_0: "det (mat 0 :: 'a::comm_ring_1^'n^'n) = 0" |
223 by (simp add: det_def setprod_zero) |
223 by (simp add: det_def prod_zero) |
224 |
224 |
225 lemma det_permute_rows: |
225 lemma det_permute_rows: |
226 fixes A :: "'a::comm_ring_1^'n^'n" |
226 fixes A :: "'a::comm_ring_1^'n^'n" |
227 assumes p: "p permutes (UNIV :: 'n::finite set)" |
227 assumes p: "p permutes (UNIV :: 'n::finite set)" |
228 shows "det (\<chi> i. A$p i :: 'a^'n^'n) = of_int (sign p) * det A" |
228 shows "det (\<chi> i. A$p i :: 'a^'n^'n) = of_int (sign p) * det A" |
238 from qPU have q: "q permutes ?U" |
238 from qPU have q: "q permutes ?U" |
239 by blast |
239 by blast |
240 from p q have pp: "permutation p" and qp: "permutation q" |
240 from p q have pp: "permutation p" and qp: "permutation q" |
241 by (metis fU permutation_permutes)+ |
241 by (metis fU permutation_permutes)+ |
242 from permutes_inv[OF p] have ip: "inv p permutes ?U" . |
242 from permutes_inv[OF p] have ip: "inv p permutes ?U" . |
243 have "setprod (\<lambda>i. A$p i$ (q \<circ> p) i) ?U = setprod ((\<lambda>i. A$p i$(q \<circ> p) i) \<circ> inv p) ?U" |
243 have "prod (\<lambda>i. A$p i$ (q \<circ> p) i) ?U = prod ((\<lambda>i. A$p i$(q \<circ> p) i) \<circ> inv p) ?U" |
244 by (simp only: setprod_permute[OF ip, symmetric]) |
244 by (simp only: prod_permute[OF ip, symmetric]) |
245 also have "\<dots> = setprod (\<lambda>i. A $ (p \<circ> inv p) i $ (q \<circ> (p \<circ> inv p)) i) ?U" |
245 also have "\<dots> = prod (\<lambda>i. A $ (p \<circ> inv p) i $ (q \<circ> (p \<circ> inv p)) i) ?U" |
246 by (simp only: o_def) |
246 by (simp only: o_def) |
247 also have "\<dots> = setprod (\<lambda>i. A$i$q i) ?U" |
247 also have "\<dots> = prod (\<lambda>i. A$i$q i) ?U" |
248 by (simp only: o_def permutes_inverses[OF p]) |
248 by (simp only: o_def permutes_inverses[OF p]) |
249 finally have thp: "setprod (\<lambda>i. A$p i$ (q \<circ> p) i) ?U = setprod (\<lambda>i. A$i$q i) ?U" |
249 finally have thp: "prod (\<lambda>i. A$p i$ (q \<circ> p) i) ?U = prod (\<lambda>i. A$i$q i) ?U" |
250 by blast |
250 by blast |
251 show "of_int (sign (q \<circ> p)) * setprod (\<lambda>i. A$ p i$ (q \<circ> p) i) ?U = |
251 show "of_int (sign (q \<circ> p)) * prod (\<lambda>i. A$ p i$ (q \<circ> p) i) ?U = |
252 of_int (sign p) * of_int (sign q) * setprod (\<lambda>i. A$i$q i) ?U" |
252 of_int (sign p) * of_int (sign q) * prod (\<lambda>i. A$i$q i) ?U" |
253 by (simp only: thp sign_compose[OF qp pp] mult.commute of_int_mult) |
253 by (simp only: thp sign_compose[OF qp pp] mult.commute of_int_mult) |
254 qed rule |
254 qed rule |
255 |
255 |
256 lemma det_permute_columns: |
256 lemma det_permute_columns: |
257 fixes A :: "'a::comm_ring_1^'n^'n" |
257 fixes A :: "'a::comm_ring_1^'n^'n" |
339 fix j |
339 fix j |
340 assume j: "j \<in> ?Uk" |
340 assume j: "j \<in> ?Uk" |
341 from j have "?f j $ p j = ?g j $ p j" and "?f j $ p j= ?h j $ p j" |
341 from j have "?f j $ p j = ?g j $ p j" and "?f j $ p j= ?h j $ p j" |
342 by simp_all |
342 by simp_all |
343 } |
343 } |
344 then have th1: "setprod (\<lambda>i. ?f i $ p i) ?Uk = setprod (\<lambda>i. ?g i $ p i) ?Uk" |
344 then have th1: "prod (\<lambda>i. ?f i $ p i) ?Uk = prod (\<lambda>i. ?g i $ p i) ?Uk" |
345 and th2: "setprod (\<lambda>i. ?f i $ p i) ?Uk = setprod (\<lambda>i. ?h i $ p i) ?Uk" |
345 and th2: "prod (\<lambda>i. ?f i $ p i) ?Uk = prod (\<lambda>i. ?h i $ p i) ?Uk" |
346 apply - |
346 apply - |
347 apply (rule setprod.cong, simp_all)+ |
347 apply (rule prod.cong, simp_all)+ |
348 done |
348 done |
349 have th3: "finite ?Uk" "k \<notin> ?Uk" |
349 have th3: "finite ?Uk" "k \<notin> ?Uk" |
350 by auto |
350 by auto |
351 have "setprod (\<lambda>i. ?f i $ p i) ?U = setprod (\<lambda>i. ?f i $ p i) (insert k ?Uk)" |
351 have "prod (\<lambda>i. ?f i $ p i) ?U = prod (\<lambda>i. ?f i $ p i) (insert k ?Uk)" |
352 unfolding kU[symmetric] .. |
352 unfolding kU[symmetric] .. |
353 also have "\<dots> = ?f k $ p k * setprod (\<lambda>i. ?f i $ p i) ?Uk" |
353 also have "\<dots> = ?f k $ p k * prod (\<lambda>i. ?f i $ p i) ?Uk" |
354 apply (rule setprod.insert) |
354 apply (rule prod.insert) |
355 apply simp |
355 apply simp |
356 apply blast |
356 apply blast |
357 done |
357 done |
358 also have "\<dots> = (a k $ p k * setprod (\<lambda>i. ?f i $ p i) ?Uk) + (b k$ p k * setprod (\<lambda>i. ?f i $ p i) ?Uk)" |
358 also have "\<dots> = (a k $ p k * prod (\<lambda>i. ?f i $ p i) ?Uk) + (b k$ p k * prod (\<lambda>i. ?f i $ p i) ?Uk)" |
359 by (simp add: field_simps) |
359 by (simp add: field_simps) |
360 also have "\<dots> = (a k $ p k * setprod (\<lambda>i. ?g i $ p i) ?Uk) + (b k$ p k * setprod (\<lambda>i. ?h i $ p i) ?Uk)" |
360 also have "\<dots> = (a k $ p k * prod (\<lambda>i. ?g i $ p i) ?Uk) + (b k$ p k * prod (\<lambda>i. ?h i $ p i) ?Uk)" |
361 by (metis th1 th2) |
361 by (metis th1 th2) |
362 also have "\<dots> = setprod (\<lambda>i. ?g i $ p i) (insert k ?Uk) + setprod (\<lambda>i. ?h i $ p i) (insert k ?Uk)" |
362 also have "\<dots> = prod (\<lambda>i. ?g i $ p i) (insert k ?Uk) + prod (\<lambda>i. ?h i $ p i) (insert k ?Uk)" |
363 unfolding setprod.insert[OF th3] by simp |
363 unfolding prod.insert[OF th3] by simp |
364 finally have "setprod (\<lambda>i. ?f i $ p i) ?U = setprod (\<lambda>i. ?g i $ p i) ?U + setprod (\<lambda>i. ?h i $ p i) ?U" |
364 finally have "prod (\<lambda>i. ?f i $ p i) ?U = prod (\<lambda>i. ?g i $ p i) ?U + prod (\<lambda>i. ?h i $ p i) ?U" |
365 unfolding kU[symmetric] . |
365 unfolding kU[symmetric] . |
366 then show "of_int (sign p) * setprod (\<lambda>i. ?f i $ p i) ?U = |
366 then show "of_int (sign p) * prod (\<lambda>i. ?f i $ p i) ?U = |
367 of_int (sign p) * setprod (\<lambda>i. ?g i $ p i) ?U + of_int (sign p) * setprod (\<lambda>i. ?h i $ p i) ?U" |
367 of_int (sign p) * prod (\<lambda>i. ?g i $ p i) ?U + of_int (sign p) * prod (\<lambda>i. ?h i $ p i) ?U" |
368 by (simp add: field_simps) |
368 by (simp add: field_simps) |
369 qed rule |
369 qed rule |
370 |
370 |
371 lemma det_row_mul: |
371 lemma det_row_mul: |
372 fixes a b :: "'n::finite \<Rightarrow> _ ^ 'n" |
372 fixes a b :: "'n::finite \<Rightarrow> _ ^ 'n" |
389 fix j |
389 fix j |
390 assume j: "j \<in> ?Uk" |
390 assume j: "j \<in> ?Uk" |
391 from j have "?f j $ p j = ?g j $ p j" |
391 from j have "?f j $ p j = ?g j $ p j" |
392 by simp |
392 by simp |
393 } |
393 } |
394 then have th1: "setprod (\<lambda>i. ?f i $ p i) ?Uk = setprod (\<lambda>i. ?g i $ p i) ?Uk" |
394 then have th1: "prod (\<lambda>i. ?f i $ p i) ?Uk = prod (\<lambda>i. ?g i $ p i) ?Uk" |
395 apply - |
395 apply - |
396 apply (rule setprod.cong) |
396 apply (rule prod.cong) |
397 apply simp_all |
397 apply simp_all |
398 done |
398 done |
399 have th3: "finite ?Uk" "k \<notin> ?Uk" |
399 have th3: "finite ?Uk" "k \<notin> ?Uk" |
400 by auto |
400 by auto |
401 have "setprod (\<lambda>i. ?f i $ p i) ?U = setprod (\<lambda>i. ?f i $ p i) (insert k ?Uk)" |
401 have "prod (\<lambda>i. ?f i $ p i) ?U = prod (\<lambda>i. ?f i $ p i) (insert k ?Uk)" |
402 unfolding kU[symmetric] .. |
402 unfolding kU[symmetric] .. |
403 also have "\<dots> = ?f k $ p k * setprod (\<lambda>i. ?f i $ p i) ?Uk" |
403 also have "\<dots> = ?f k $ p k * prod (\<lambda>i. ?f i $ p i) ?Uk" |
404 apply (rule setprod.insert) |
404 apply (rule prod.insert) |
405 apply simp |
405 apply simp |
406 apply blast |
406 apply blast |
407 done |
407 done |
408 also have "\<dots> = (c*s a k) $ p k * setprod (\<lambda>i. ?f i $ p i) ?Uk" |
408 also have "\<dots> = (c*s a k) $ p k * prod (\<lambda>i. ?f i $ p i) ?Uk" |
409 by (simp add: field_simps) |
409 by (simp add: field_simps) |
410 also have "\<dots> = c* (a k $ p k * setprod (\<lambda>i. ?g i $ p i) ?Uk)" |
410 also have "\<dots> = c* (a k $ p k * prod (\<lambda>i. ?g i $ p i) ?Uk)" |
411 unfolding th1 by (simp add: ac_simps) |
411 unfolding th1 by (simp add: ac_simps) |
412 also have "\<dots> = c* (setprod (\<lambda>i. ?g i $ p i) (insert k ?Uk))" |
412 also have "\<dots> = c* (prod (\<lambda>i. ?g i $ p i) (insert k ?Uk))" |
413 unfolding setprod.insert[OF th3] by simp |
413 unfolding prod.insert[OF th3] by simp |
414 finally have "setprod (\<lambda>i. ?f i $ p i) ?U = c* (setprod (\<lambda>i. ?g i $ p i) ?U)" |
414 finally have "prod (\<lambda>i. ?f i $ p i) ?U = c* (prod (\<lambda>i. ?g i $ p i) ?U)" |
415 unfolding kU[symmetric] . |
415 unfolding kU[symmetric] . |
416 then show "of_int (sign p) * setprod (\<lambda>i. ?f i $ p i) ?U = |
416 then show "of_int (sign p) * prod (\<lambda>i. ?f i $ p i) ?U = |
417 c * (of_int (sign p) * setprod (\<lambda>i. ?g i $ p i) ?U)" |
417 c * (of_int (sign p) * prod (\<lambda>i. ?g i $ p i) ?U)" |
418 by (simp add: field_simps) |
418 by (simp add: field_simps) |
419 qed rule |
419 qed rule |
420 |
420 |
421 lemma det_row_0: |
421 lemma det_row_0: |
422 fixes b :: "'n::finite \<Rightarrow> _ ^ 'n" |
422 fixes b :: "'n::finite \<Rightarrow> _ ^ 'n" |
642 shows "A ** B = (\<chi> i. sum (\<lambda>k. A$i$k *s B $ k) (UNIV :: 'n set))" |
642 shows "A ** B = (\<chi> i. sum (\<lambda>k. A$i$k *s B $ k) (UNIV :: 'n set))" |
643 by (vector matrix_matrix_mult_def sum_component) |
643 by (vector matrix_matrix_mult_def sum_component) |
644 |
644 |
645 lemma det_rows_mul: |
645 lemma det_rows_mul: |
646 "det((\<chi> i. c i *s a i)::'a::comm_ring_1^'n^'n) = |
646 "det((\<chi> i. c i *s a i)::'a::comm_ring_1^'n^'n) = |
647 setprod (\<lambda>i. c i) (UNIV:: 'n set) * det((\<chi> i. a i)::'a^'n^'n)" |
647 prod (\<lambda>i. c i) (UNIV:: 'n set) * det((\<chi> i. a i)::'a^'n^'n)" |
648 proof (simp add: det_def sum_distrib_left cong add: setprod.cong, rule sum.cong) |
648 proof (simp add: det_def sum_distrib_left cong add: prod.cong, rule sum.cong) |
649 let ?U = "UNIV :: 'n set" |
649 let ?U = "UNIV :: 'n set" |
650 let ?PU = "{p. p permutes ?U}" |
650 let ?PU = "{p. p permutes ?U}" |
651 fix p |
651 fix p |
652 assume pU: "p \<in> ?PU" |
652 assume pU: "p \<in> ?PU" |
653 let ?s = "of_int (sign p)" |
653 let ?s = "of_int (sign p)" |
654 from pU have p: "p permutes ?U" |
654 from pU have p: "p permutes ?U" |
655 by blast |
655 by blast |
656 have "setprod (\<lambda>i. c i * a i $ p i) ?U = setprod c ?U * setprod (\<lambda>i. a i $ p i) ?U" |
656 have "prod (\<lambda>i. c i * a i $ p i) ?U = prod c ?U * prod (\<lambda>i. a i $ p i) ?U" |
657 unfolding setprod.distrib .. |
657 unfolding prod.distrib .. |
658 then show "?s * (\<Prod>xa\<in>?U. c xa * a xa $ p xa) = |
658 then show "?s * (\<Prod>xa\<in>?U. c xa * a xa $ p xa) = |
659 setprod c ?U * (?s* (\<Prod>xa\<in>?U. a xa $ p xa))" |
659 prod c ?U * (?s* (\<Prod>xa\<in>?U. a xa $ p xa))" |
660 by (simp add: field_simps) |
660 by (simp add: field_simps) |
661 qed rule |
661 qed rule |
662 |
662 |
663 lemma det_mul: |
663 lemma det_mul: |
664 fixes A B :: "'a::linordered_idom^'n^'n" |
664 fixes A B :: "'a::linordered_idom^'n^'n" |
752 unfolding of_int_mult[symmetric] |
752 unfolding of_int_mult[symmetric] |
753 by (simp_all add: sign_idempotent) |
753 by (simp_all add: sign_idempotent) |
754 have ths: "?s q = ?s p * ?s (q \<circ> inv p)" |
754 have ths: "?s q = ?s p * ?s (q \<circ> inv p)" |
755 using pp pq permutation_inverse[OF pp] sign_inverse[OF pp] |
755 using pp pq permutation_inverse[OF pp] sign_inverse[OF pp] |
756 by (simp add: th00 ac_simps sign_idempotent sign_compose) |
756 by (simp add: th00 ac_simps sign_idempotent sign_compose) |
757 have th001: "setprod (\<lambda>i. B$i$ q (inv p i)) ?U = setprod ((\<lambda>i. B$i$ q (inv p i)) \<circ> p) ?U" |
757 have th001: "prod (\<lambda>i. B$i$ q (inv p i)) ?U = prod ((\<lambda>i. B$i$ q (inv p i)) \<circ> p) ?U" |
758 by (rule setprod_permute[OF p]) |
758 by (rule prod_permute[OF p]) |
759 have thp: "setprod (\<lambda>i. (\<chi> i. A$i$p i *s B$p i :: 'a^'n^'n) $i $ q i) ?U = |
759 have thp: "prod (\<lambda>i. (\<chi> i. A$i$p i *s B$p i :: 'a^'n^'n) $i $ q i) ?U = |
760 setprod (\<lambda>i. A$i$p i) ?U * setprod (\<lambda>i. B$i$ q (inv p i)) ?U" |
760 prod (\<lambda>i. A$i$p i) ?U * prod (\<lambda>i. B$i$ q (inv p i)) ?U" |
761 unfolding th001 setprod.distrib[symmetric] o_def permutes_inverses[OF p] |
761 unfolding th001 prod.distrib[symmetric] o_def permutes_inverses[OF p] |
762 apply (rule setprod.cong[OF refl]) |
762 apply (rule prod.cong[OF refl]) |
763 using permutes_in_image[OF q] |
763 using permutes_in_image[OF q] |
764 apply vector |
764 apply vector |
765 done |
765 done |
766 show "?s q * setprod (\<lambda>i. (((\<chi> i. A$i$p i *s B$p i) :: 'a^'n^'n)$i$q i)) ?U = |
766 show "?s q * prod (\<lambda>i. (((\<chi> i. A$i$p i *s B$p i) :: 'a^'n^'n)$i$q i)) ?U = |
767 ?s p * (setprod (\<lambda>i. A$i$p i) ?U) * (?s (q \<circ> inv p) * setprod (\<lambda>i. B$i$(q \<circ> inv p) i) ?U)" |
767 ?s p * (prod (\<lambda>i. A$i$p i) ?U) * (?s (q \<circ> inv p) * prod (\<lambda>i. B$i$(q \<circ> inv p) i) ?U)" |
768 using ths thp pp pq permutation_inverse[OF pp] sign_inverse[OF pp] |
768 using ths thp pp pq permutation_inverse[OF pp] sign_inverse[OF pp] |
769 by (simp add: sign_nz th00 field_simps sign_idempotent sign_compose) |
769 by (simp add: sign_nz th00 field_simps sign_idempotent sign_compose) |
770 qed rule |
770 qed rule |
771 } |
771 } |
772 then have th2: "sum (\<lambda>f. det (\<chi> i. A$i$f i *s B$f i)) ?PU = det A * det B" |
772 then have th2: "sum (\<lambda>f. det (\<chi> i. A$i$f i *s B$f i)) ?PU = det A * det B" |
1200 shows " orthogonal_matrix Q \<longleftrightarrow> rotation_matrix Q \<or> rotoinversion_matrix Q" |
1200 shows " orthogonal_matrix Q \<longleftrightarrow> rotation_matrix Q \<or> rotoinversion_matrix Q" |
1201 by (metis rotoinversion_matrix_def rotation_matrix_def det_orthogonal_matrix) |
1201 by (metis rotoinversion_matrix_def rotation_matrix_def det_orthogonal_matrix) |
1202 |
1202 |
1203 text \<open>Explicit formulas for low dimensions.\<close> |
1203 text \<open>Explicit formulas for low dimensions.\<close> |
1204 |
1204 |
1205 lemma setprod_neutral_const: "setprod f {(1::nat)..1} = f 1" |
1205 lemma prod_neutral_const: "prod f {(1::nat)..1} = f 1" |
1206 by simp |
1206 by simp |
1207 |
1207 |
1208 lemma setprod_2: "setprod f {(1::nat)..2} = f 1 * f 2" |
1208 lemma prod_2: "prod f {(1::nat)..2} = f 1 * f 2" |
1209 by (simp add: eval_nat_numeral atLeastAtMostSuc_conv mult.commute) |
1209 by (simp add: eval_nat_numeral atLeastAtMostSuc_conv mult.commute) |
1210 |
1210 |
1211 lemma setprod_3: "setprod f {(1::nat)..3} = f 1 * f 2 * f 3" |
1211 lemma prod_3: "prod f {(1::nat)..3} = f 1 * f 2 * f 3" |
1212 by (simp add: eval_nat_numeral atLeastAtMostSuc_conv mult.commute) |
1212 by (simp add: eval_nat_numeral atLeastAtMostSuc_conv mult.commute) |
1213 |
1213 |
1214 lemma det_1: "det (A::'a::comm_ring_1^1^1) = A$1$1" |
1214 lemma det_1: "det (A::'a::comm_ring_1^1^1) = A$1$1" |
1215 by (simp add: det_def of_nat_Suc sign_id) |
1215 by (simp add: det_def of_nat_Suc sign_id) |
1216 |
1216 |