217 shows "A ** A' = mat 1 \<longleftrightarrow> A' ** A = mat 1" |
217 shows "A ** A' = mat 1 \<longleftrightarrow> A' ** A = mat 1" |
218 proof - |
218 proof - |
219 { fix A A' :: "'a ^'n^'n" |
219 { fix A A' :: "'a ^'n^'n" |
220 assume AA': "A ** A' = mat 1" |
220 assume AA': "A ** A' = mat 1" |
221 have sA: "surj (( *v) A)" |
221 have sA: "surj (( *v) A)" |
222 unfolding surj_def |
222 using AA' matrix_right_invertible_surjective by auto |
223 apply clarify |
|
224 apply (rule_tac x="(A' *v y)" in exI) |
|
225 apply (simp add: matrix_vector_mul_assoc AA') |
|
226 done |
|
227 from vec.linear_surjective_isomorphism[OF matrix_vector_mul_linear_gen sA] |
223 from vec.linear_surjective_isomorphism[OF matrix_vector_mul_linear_gen sA] |
228 obtain f' :: "'a ^'n \<Rightarrow> 'a ^'n" |
224 obtain f' :: "'a ^'n \<Rightarrow> 'a ^'n" |
229 where f': "Vector_Spaces.linear ( *s) ( *s) f'" "\<forall>x. f' (A *v x) = x" "\<forall>x. A *v f' x = x" by blast |
225 where f': "Vector_Spaces.linear ( *s) ( *s) f'" "\<forall>x. f' (A *v x) = x" "\<forall>x. A *v f' x = x" by blast |
230 have th: "matrix f' ** A = mat 1" |
226 have th: "matrix f' ** A = mat 1" |
231 by (simp add: matrix_eq matrix_works[OF f'(1)] |
227 by (simp add: matrix_eq matrix_works[OF f'(1)] |
242 lemma invertible_left_inverse: |
238 lemma invertible_left_inverse: |
243 fixes A :: "'a::{field}^'n^'n" |
239 fixes A :: "'a::{field}^'n^'n" |
244 shows "invertible A \<longleftrightarrow> (\<exists>(B::'a^'n^'n). B ** A = mat 1)" |
240 shows "invertible A \<longleftrightarrow> (\<exists>(B::'a^'n^'n). B ** A = mat 1)" |
245 by (metis invertible_def matrix_left_right_inverse) |
241 by (metis invertible_def matrix_left_right_inverse) |
246 |
242 |
247 lemma invertible_right_inverse: |
243 lemma invertible_right_inverse: |
248 fixes A :: "'a::{field}^'n^'n" |
244 fixes A :: "'a::{field}^'n^'n" |
249 shows "invertible A \<longleftrightarrow> (\<exists>(B::'a^'n^'n). A** B = mat 1)" |
245 shows "invertible A \<longleftrightarrow> (\<exists>(B::'a^'n^'n). A** B = mat 1)" |
250 by (metis invertible_def matrix_left_right_inverse) |
246 by (metis invertible_def matrix_left_right_inverse) |
|
247 |
|
248 lemma invertible_mult: |
|
249 assumes inv_A: "invertible A" |
|
250 and inv_B: "invertible B" |
|
251 shows "invertible (A**B)" |
|
252 proof - |
|
253 obtain A' where AA': "A ** A' = mat 1" and A'A: "A' ** A = mat 1" |
|
254 using inv_A unfolding invertible_def by blast |
|
255 obtain B' where BB': "B ** B' = mat 1" and B'B: "B' ** B = mat 1" |
|
256 using inv_B unfolding invertible_def by blast |
|
257 show ?thesis |
|
258 proof (unfold invertible_def, rule exI[of _ "B'**A'"], rule conjI) |
|
259 have "A ** B ** (B' ** A') = A ** (B ** (B' ** A'))" |
|
260 using matrix_mul_assoc[of A B "(B' ** A')", symmetric] . |
|
261 also have "... = A ** (B ** B' ** A')" unfolding matrix_mul_assoc[of B "B'" "A'"] .. |
|
262 also have "... = A ** (mat 1 ** A')" unfolding BB' .. |
|
263 also have "... = A ** A'" unfolding matrix_mul_lid .. |
|
264 also have "... = mat 1" unfolding AA' .. |
|
265 finally show "A ** B ** (B' ** A') = mat (1::'a)" . |
|
266 have "B' ** A' ** (A ** B) = B' ** (A' ** (A ** B))" using matrix_mul_assoc[of B' A' "(A ** B)", symmetric] . |
|
267 also have "... = B' ** (A' ** A ** B)" unfolding matrix_mul_assoc[of A' A B] .. |
|
268 also have "... = B' ** (mat 1 ** B)" unfolding A'A .. |
|
269 also have "... = B' ** B" unfolding matrix_mul_lid .. |
|
270 also have "... = mat 1" unfolding B'B .. |
|
271 finally show "B' ** A' ** (A ** B) = mat 1" . |
|
272 qed |
|
273 qed |
|
274 |
|
275 lemma transpose_invertible: |
|
276 fixes A :: "real^'n^'n" |
|
277 assumes "invertible A" |
|
278 shows "invertible (transpose A)" |
|
279 by (meson assms invertible_def matrix_left_right_inverse right_invertible_transpose) |
|
280 |
|
281 lemma vector_matrix_mul_assoc: |
|
282 fixes v :: "('a::comm_semiring_1)^'n" |
|
283 shows "(v v* M) v* N = v v* (M ** N)" |
|
284 proof - |
|
285 from matrix_vector_mul_assoc |
|
286 have "transpose N *v (transpose M *v v) = (transpose N ** transpose M) *v v" by fast |
|
287 thus "(v v* M) v* N = v v* (M ** N)" |
|
288 by (simp add: matrix_transpose_mul [symmetric]) |
|
289 qed |
|
290 |
|
291 lemma matrix_scaleR_vector_ac: |
|
292 fixes A :: "real^('m::finite)^'n" |
|
293 shows "A *v (k *\<^sub>R v) = k *\<^sub>R A *v v" |
|
294 by (metis matrix_vector_mult_scaleR transpose_scalar vector_scaleR_matrix_ac vector_transpose_matrix) |
|
295 |
|
296 lemma scaleR_matrix_vector_assoc: |
|
297 fixes A :: "real^('m::finite)^'n" |
|
298 shows "k *\<^sub>R (A *v v) = k *\<^sub>R A *v v" |
|
299 by (metis matrix_scaleR_vector_ac matrix_vector_mult_scaleR) |
251 |
300 |
252 (*Finally, some interesting theorems and interpretations that don't appear in any file of the |
301 (*Finally, some interesting theorems and interpretations that don't appear in any file of the |
253 library.*) |
302 library.*) |
254 |
303 |
255 locale linear_first_finite_dimensional_vector_space = |
304 locale linear_first_finite_dimensional_vector_space = |