Built with Alectryon, running Coq+SerAPI v8.19.0+0.19.3. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use ⌘ instead of Ctrl.
[Loading ML file number_string_notation_plugin.cmxs (using legacy method) ... done]
Require Import Types.Sigma.Require Import Spaces.List.Core Spaces.List.Theory Spaces.List.Paths.Require Import Algebra.Rings.Ring Algebra.Rings.ModuleAlgebra.Rings.CRing
Algebra.Rings.KroneckerDelta Algebra.Rings.Vector.Require Import abstract_algebra.Require Import WildCat.Core WildCat.Paths.Require Import Modalities.ReflectiveSubuniverse.Set Universe Minimization ToSet.(** * Matrices *)(** ** Definition *)DefinitionMatrix@{i} (R : Type@{i}) (m n : nat) : Type@{i}
:= Vector (Vector R n) m.Instanceistrunc_matrix (R : Type) k `{IsTrunc k.+2 R} m n
: IsTrunc k.+2 (Matrix R m n)
:= _.(** Building a matrix from a function that takes row and column indices. *)
R: Type m, n: nat M_fun: forallij : nat,
(i < m)%nat -> (j < n)%nat -> R
Matrix R m n
R: Type m, n: nat M_fun: forallij : nat,
(i < m)%nat -> (j < n)%nat -> R
Matrix R m n
R: Type m, n: nat M_fun: forallij : nat,
(i < m)%nat -> (j < n)%nat -> R
foralli : nat, (i < m)%nat -> Vector R n
R: Type m, n: nat M_fun: forallij : nat,
(i < m)%nat -> (j < n)%nat -> R i: nat Hi: (i < m)%nat
Vector R n
R: Type m, n: nat M_fun: forallij : nat,
(i < m)%nat -> (j < n)%nat -> R i: nat Hi: (i < m)%nat
foralli : nat, (i < n)%nat -> R
R: Type m, n: nat M_fun: forallij : nat,
(i < m)%nat -> (j < n)%nat -> R i: nat Hi: (i < m)%nat j: nat Hj: (j < n)%nat
R
exact (M_fun i j Hi Hj).Defined.(** The length conditions here are decidable so can be inferred in proofs. *)
R: Type m, n: nat l: list (list R) wf_row: length l = m wf_col: for_all (funrow : list R => length row = n)
l
Matrix R m n
R: Type m, n: nat l: list (list R) wf_row: length l = m wf_col: for_all (funrow : list R => length row = n)
l
Matrix R m n
R: Type m, n: nat l: list (list R) wf_row: length l = m wf_col: for_all (funrow : list R => length row = n)
l
list (Vector R n)
R: Type m, n: nat l: list (list R) wf_row: length l = m wf_col: for_all (funrow : list R => length row = n)
l
(funl : list (Vector R n) => length l = m) ?proj1
R: Type m, n: nat l: list (list R) wf_row: length l = m wf_col: for_all (funrow : list R => length row = n)
l
list (Vector R n)
R: Type m, n: nat l: list (list R) wf_row: length l = m wf_col: for_all (funrow : list R => length row = n)
l
list (list R)
R: Type m, n: nat l: list (list R) wf_row: length l = m wf_col: for_all (funrow : list R => length row = n)
l
for_all (funx : list R => length x = n) ?l
R: Type m, n: nat l: list (list R) wf_row: length l = m wf_col: for_all (funrow : list R => length row = n)
l
list (list R)
exact l.
R: Type m, n: nat l: list (list R) wf_row: length l = m wf_col: for_all (funrow : list R => length row = n)
l
for_all (funx : list R => length x = n) l
exact wf_col.
R: Type m, n: nat l: list (list R) wf_row: length l = m wf_col: for_all (funrow : list R => length row = n)
l
(funl : list (Vector R n) => length l = m)
(list_sigma (funx : list R => length x = n) l
wf_col)
by lhs napply length_list_sigma.Defined.Definitionentries@{i|} {R : Type@{i}} {m n} (M : Matrix R m n)
: list (list R)
:= list_map@{i i} pr1 (pr1 M).(** The entry at row [i] and column [j] of a matrix [M]. *)Definitionentry {R : Type} {mn} (M : Matrix R m n) (ij : nat)
{H1 : (i < m)%nat} {H2 : (j < n)%nat}
: R
:= Vector.entry (Vector.entry M i) j.(** Mapping a function on all the entries of a matrix. *)Definitionmatrix_map {RS : Type} {mn} (f : R -> S)
: Matrix R m n -> Matrix S m n
:= funM => Build_Matrix S m n (funij__ => f (entry M i j)).Definitionmatrix_map2 {RST : Type} {mn} (f : R -> S -> T)
: Matrix R m n -> Matrix S m n -> Matrix T m n
:= funMN => Build_Matrix T m n
(funij__ => f (entry M i j) (entry N i j)).(** The [(i, j)]-entry of [Build_Matrix R m n M_fun] is [M_fun i j]. *)
R: Type m, n: nat M_fun: forallij : nat,
(i < m)%nat -> (j < n)%nat -> R i, j: nat H1: (i < m)%nat H2: (j < n)%nat
entry (Build_Matrix R m n M_fun) i j = M_fun i j H1 H2
R: Type m, n: nat M_fun: forallij : nat,
(i < m)%nat -> (j < n)%nat -> R i, j: nat H1: (i < m)%nat H2: (j < n)%nat
entry (Build_Matrix R m n M_fun) i j = M_fun i j H1 H2
R: Type m, n: nat M_fun: forallij : nat,
(i < m)%nat -> (j < n)%nat -> R i, j: nat H1: (i < m)%nat H2: (j < n)%nat
Vector.entry
(Vector.entry (Build_Matrix R m n M_fun) i) j =
M_fun i j H1 H2
byrewrite2 entry_Build_Vector.Defined.(** Two matrices are equal if all their entries are equal. *)
R: Type m, n: nat M, N: Matrix R m n H: forall (ij : nat) (Hi : (i < m)%nat)
(Hj : (j < n)%nat), entry M i j = entry N i j
M = N
R: Type m, n: nat M, N: Matrix R m n H: forall (ij : nat) (Hi : (i < m)%nat)
(Hj : (j < n)%nat), entry M i j = entry N i j
M = N
R: Type m, n: nat M, N: Matrix R m n H: forall (ij : nat) (Hi : (i < m)%nat)
(Hj : (j < n)%nat), entry M i j = entry N i j
forall (i : nat) (H : (i < m)%nat),
Vector.entry M i = Vector.entry N i
R: Type m, n: nat M, N: Matrix R m n H: forall (ij : nat) (Hi : (i < m)%nat)
(Hj : (j < n)%nat), entry M i j = entry N i j i: nat Hi: (i < m)%nat
Vector.entry M i = Vector.entry N i
R: Type m, n: nat M, N: Matrix R m n H: forall (ij : nat) (Hi : (i < m)%nat)
(Hj : (j < n)%nat), entry M i j = entry N i j i: nat Hi: (i < m)%nat
forall (i0 : nat) (H : (i0 < n)%nat),
Vector.entry (Vector.entry M i) i0 =
Vector.entry (Vector.entry N i) i0
R: Type m, n: nat M, N: Matrix R m n H: forall (ij : nat) (Hi : (i < m)%nat)
(Hj : (j < n)%nat), entry M i j = entry N i j i: nat Hi: (i < m)%nat j: nat Hj: (j < n)%nat
Vector.entry (Vector.entry M i) j =
Vector.entry (Vector.entry N i) j
exact (H i j Hi Hj).Defined.(** ** Addition and module structure *)(** Here we define the abelian group of (n x m)-matrices over a ring. This follows from the abelian group structure of the underlying vectors. We are also able to derive a left module structure when the entries come from a left module. *)Definitionabgroup_matrix (A : AbGroup) (mn : nat) : AbGroup
:= abgroup_vector (abgroup_vector A n) m.Definitionmatrix_plus {A : AbGroup} {mn}
: Matrix A m n -> Matrix A m n -> Matrix A m n
:= @sg_op (abgroup_matrix A m n) _.Definitionmatrix_zero (A : AbGroup) mn : Matrix A m n
:= @mon_unit (abgroup_matrix A m n) _.Definitionmatrix_negate {A : AbGroup} {mn}
: Matrix A m n -> Matrix A m n
:= @negate (abgroup_matrix A m n) _.
A: AbGroup m, n: nat R: Ring H: IsLeftModule R A
IsLeftModule R (abgroup_matrix A m n)
A: AbGroup m, n: nat R: Ring H: IsLeftModule R A
IsLeftModule R (abgroup_matrix A m n)
A: AbGroup m, n: nat R: Ring H: IsLeftModule R A
IsLeftModule R (abgroup_vector A n)
A: AbGroup m, n: nat R: Ring H: IsLeftModule R A
IsLeftModule R A
exact _.Defined.(** As a special case, we get the left module of matrices over a ring. *)Instanceisleftmodule_abgroup_matrix (R : Ring) (mn : nat)
: IsLeftModule R (abgroup_matrix R m n)
:= _.Definitionmatrix_lact {R : Ring} {mn : nat} (r : R) (M : Matrix R m n)
: Matrix R m n
:= lact r M.(** ** Multiplication *)(** Matrix multiplication is defined such that the entry at row [i] and column [j] of the resulting matrix is the sum of the products of the corresponding entries from the [i]th row of the first matrix and the [j]th column of the second matrix. Matrices correspond to module homomorphisms between free modules of finite rank (think vector spaces), and matrix multiplication represents the composition of these homomorphisms. **)
R: Ring m, n, k: nat M: Matrix R m n N: Matrix R n k
Matrix R m k
R: Ring m, n, k: nat M: Matrix R m n N: Matrix R n k
Matrix R m k
R: Ring m, n, k: nat M: Matrix R m n N: Matrix R n k
forallij : nat, (i < m)%nat -> (j < k)%nat -> R
R: Ring m, n, k: nat M: Matrix R m n N: Matrix R n k i, j: nat Hi: (i < m)%nat Hj: (j < k)%nat
R
exact (ab_sum n (funkHk => entry M i k * entry N k j)).Defined.(** The identity matrix is the matrix with ones on the diagonal and zeros elsewhere. It acts as the multiplicative identity for matrix multiplication. We define it here using the [kronecker_delta] function which will make proving properties about it conceptually easier later. *)Definitionidentity_matrix (R : Ring@{i}) (n : nat) : Matrix R n n
:= Build_Matrix R n n (funij__ => kronecker_delta i j).(** This is the most general statement of associativity for matrix multiplication. *)
R: Ring m, n, p, q: nat M: Matrix R m n N: Matrix R n p P: Matrix R p q i, j: nat Hi: (i < m)%nat Hj: (j < q)%nat
entry (matrix_mult M (matrix_mult N P)) i j =
entry (matrix_mult (matrix_mult M N) P) i j
R: Ring m, n, p, q: nat M: Matrix R m n N: Matrix R n p P: Matrix R p q i, j: nat Hi: (i < m)%nat Hj: (j < q)%nat
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry M i k * entry (matrix_mult N P) k j) =
ab_sum p
(fun (k : nat) (Hk : (k < p)%nat) =>
entry (matrix_mult M N) i k * entry P k j)
R: Ring m, n, p, q: nat M: Matrix R m n N: Matrix R n p P: Matrix R p q i, j: nat Hi: (i < m)%nat Hj: (j < q)%nat
forall (k : nat) (Hk : (k < n)%nat),
entry M i k * entry (matrix_mult N P) k j = ?Goal k Hk
R: Ring m, n, p, q: nat M: Matrix R m n N: Matrix R n p P: Matrix R p q i, j: nat Hi: (i < m)%nat Hj: (j < q)%nat
ab_sum n ?Goal =
ab_sum p
(fun (k : nat) (Hk : (k < p)%nat) =>
entry (matrix_mult M N) i k * entry P k j)
R: Ring m, n, p, q: nat M: Matrix R m n N: Matrix R n p P: Matrix R p q i, j: nat Hi: (i < m)%nat Hj: (j < q)%nat
forall (k : nat) (Hk : (k < n)%nat),
entry M i k * entry (matrix_mult N P) k j = ?Goal k Hk
R: Ring m, n, p, q: nat M: Matrix R m n N: Matrix R n p P: Matrix R p q i, j: nat Hi: (i < m)%nat Hj: (j < q)%nat k: nat Hk: (k < n)%nat
entry M i k * entry (matrix_mult N P) k j = ?Goal k Hk
R: Ring m, n, p, q: nat M: Matrix R m n N: Matrix R n p P: Matrix R p q i, j: nat Hi: (i < m)%nat Hj: (j < q)%nat k: nat Hk: (k < n)%nat
entry M i k *
ab_sum p
(fun (k0 : nat) (Hk0 : (k0 < p)%nat) =>
entry N k k0 * entry P k0 j) = ?Goal k Hk
apply rng_sum_dist_l.
R: Ring m, n, p, q: nat M: Matrix R m n N: Matrix R n p P: Matrix R p q i, j: nat Hi: (i < m)%nat Hj: (j < q)%nat
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
ab_sum p
(fun (k0 : nat) (Hk0 : (k0 < p)%nat) =>
entry M i k *
(fun (k1 : nat) (Hk1 : (k1 < p)%nat) =>
entry N k k1 * entry P k1 j) k0 Hk0)) =
ab_sum p
(fun (k : nat) (Hk : (k < p)%nat) =>
entry (matrix_mult M N) i k * entry P k j)
R: Ring m, n, p, q: nat M: Matrix R m n N: Matrix R n p P: Matrix R p q i, j: nat Hi: (i < m)%nat Hj: (j < q)%nat
ab_sum p
(fun (j0 : nat) (Hj0 : (j0 < p)%nat) =>
ab_sum n
(fun (i0 : nat) (Hi0 : (i0 < n)%nat) =>
entry M i i0 * (entry N i0 j0 * entry P j0 j))) =
ab_sum p
(fun (k : nat) (Hk : (k < p)%nat) =>
entry (matrix_mult M N) i k * entry P k j)
R: Ring m, n, p, q: nat M: Matrix R m n N: Matrix R n p P: Matrix R p q i, j: nat Hi: (i < m)%nat Hj: (j < q)%nat
ab_sum p
(fun (j0 : nat) (Hj0 : (j0 < p)%nat) =>
ab_sum n
(fun (i0 : nat) (Hi0 : (i0 < n)%nat) =>
entry M i i0 * (entry N i0 j0 * entry P j0 j))) =
ab_sum p ?Goal
R: Ring m, n, p, q: nat M: Matrix R m n N: Matrix R n p P: Matrix R p q i, j: nat Hi: (i < m)%nat Hj: (j < q)%nat
forall (k : nat) (Hk : (k < p)%nat),
entry (matrix_mult M N) i k * entry P k j = ?Goal k Hk
R: Ring m, n, p, q: nat M: Matrix R m n N: Matrix R n p P: Matrix R p q i, j: nat Hi: (i < m)%nat Hj: (j < q)%nat
ab_sum p
(fun (j0 : nat) (Hj0 : (j0 < p)%nat) =>
ab_sum n
(fun (i0 : nat) (Hi0 : (i0 < n)%nat) =>
entry M i i0 * (entry N i0 j0 * entry P j0 j))) =
ab_sum p
(fun (k : nat) (Hk : (k < p)%nat) =>
ab_sum n
(fun (k0 : nat) (Hk0 : (k0 < n)%nat) =>
entry M i k0 * entry N k0 k) * entry P k j)
R: Ring m, n, p, q: nat M: Matrix R m n N: Matrix R n p P: Matrix R p q i, j: nat Hi: (i < m)%nat Hj: (j < q)%nat
forall (k : nat) (Hk : (k < p)%nat),
ab_sum n
(fun (i0 : nat) (Hi0 : (i0 < n)%nat) =>
entry M i i0 * (entry N i0 k * entry P k j)) =
ab_sum n
(fun (k0 : nat) (Hk0 : (k0 < n)%nat) =>
entry M i k0 * entry N k0 k) * entry P k j
R: Ring m, n, p, q: nat M: Matrix R m n N: Matrix R n p P: Matrix R p q i, j: nat Hi: (i < m)%nat Hj: (j < q)%nat k: nat Hk: (k < p)%nat
ab_sum n
(fun (i0 : nat) (Hi0 : (i0 < n)%nat) =>
entry M i i0 * (entry N i0 k * entry P k j)) =
ab_sum n
(fun (k0 : nat) (Hk0 : (k0 < n)%nat) =>
entry M i k0 * entry N k0 k) * entry P k j
R: Ring m, n, p, q: nat M: Matrix R m n N: Matrix R n p P: Matrix R p q i, j: nat Hi: (i < m)%nat Hj: (j < q)%nat k: nat Hk: (k < p)%nat
ab_sum n
(fun (i0 : nat) (Hi0 : (i0 < n)%nat) =>
entry M i i0 * (entry N i0 k * entry P k j)) =
ab_sum n
(fun (k0 : nat) (Hk0 : (k0 < n)%nat) =>
entry M i k0 * entry N k0 k * entry P k j)
R: Ring m, n, p, q: nat M: Matrix R m n N: Matrix R n p P: Matrix R p q i, j: nat Hi: (i < m)%nat Hj: (j < q)%nat k: nat Hk: (k < p)%nat
forall (k0 : nat) (Hk0 : (k0 < n)%nat),
entry M i k0 * (entry N k0 k * entry P k j) =
entry M i k0 * entry N k0 k * entry P k j
R: Ring m, n, p, q: nat M: Matrix R m n N: Matrix R n p P: Matrix R p q i, j: nat Hi: (i < m)%nat Hj: (j < q)%nat k: nat Hk: (k < p)%nat l: nat Hl: (l < n)%nat
entry M i l * (entry N l k * entry P k j) =
entry M i l * entry N l k * entry P k j
apply associativity.Defined.(** Matrix multiplication distributes over addition of matrices on the left. *)
R: Ring m, n, p: nat M: Matrix R m n N, P: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat
entry (matrix_mult M (matrix_plus N P)) i j =
entry
(matrix_plus (matrix_mult M N) (matrix_mult M P)) i
j
R: Ring m, n, p: nat M: Matrix R m n N, P: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry M i k * entry (matrix_plus N P) k j) =
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry M i k * entry N k j) +
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry M i k * entry P k j)
R: Ring m, n, p: nat M: Matrix R m n N, P: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry M i k * entry (matrix_plus N P) k j) =
sg_op
(ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry M i k * entry N k j))
(ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry M i k * entry P k j))
R: Ring m, n, p: nat M: Matrix R m n N, P: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry M i k * entry (matrix_plus N P) k j) =
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
sg_op (entry M i k * entry N k j)
(entry M i k * entry P k j))
R: Ring m, n, p: nat M: Matrix R m n N, P: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat
forall (k : nat) (Hk : (k < n)%nat),
entry M i k * entry (matrix_plus N P) k j =
sg_op (entry M i k * entry N k j)
(entry M i k * entry P k j)
R: Ring m, n, p: nat M: Matrix R m n N, P: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat k: nat Hk: (k < n)%nat
entry M i k * entry (matrix_plus N P) k j =
sg_op (entry M i k * entry N k j)
(entry M i k * entry P k j)
R: Ring m, n, p: nat M: Matrix R m n N, P: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat k: nat Hk: (k < n)%nat
entry M i k *
(Vector.entry (Vector.entry N k) j +
Vector.entry (Vector.entry P k) j) =
sg_op (entry M i k * entry N k j)
(entry M i k * entry P k j)
apply rng_dist_l.Defined.(** Matrix multiplication distributes over addition of matrices on the right. *)
R: Ring m, n, p: nat M, N: Matrix R m n P: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat
entry (matrix_mult (matrix_plus M N) P) i j =
entry
(matrix_plus (matrix_mult M P) (matrix_mult N P)) i
j
R: Ring m, n, p: nat M, N: Matrix R m n P: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry (matrix_plus M N) i k * entry P k j) =
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry M i k * entry P k j) +
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry N i k * entry P k j)
R: Ring m, n, p: nat M, N: Matrix R m n P: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry (matrix_plus M N) i k * entry P k j) =
sg_op
(ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry M i k * entry P k j))
(ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry N i k * entry P k j))
R: Ring m, n, p: nat M, N: Matrix R m n P: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry (matrix_plus M N) i k * entry P k j) =
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
sg_op (entry M i k * entry P k j)
(entry N i k * entry P k j))
R: Ring m, n, p: nat M, N: Matrix R m n P: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat
forall (k : nat) (Hk : (k < n)%nat),
entry (matrix_plus M N) i k * entry P k j =
sg_op (entry M i k * entry P k j)
(entry N i k * entry P k j)
R: Ring m, n, p: nat M, N: Matrix R m n P: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat k: nat Hk: (k < n)%nat
entry (matrix_plus M N) i k * entry P k j =
sg_op (entry M i k * entry P k j)
(entry N i k * entry P k j)
R: Ring m, n, p: nat M, N: Matrix R m n P: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat k: nat Hk: (k < n)%nat
(Vector.entry (Vector.entry M i) k +
Vector.entry (Vector.entry N i) k) * entry P k j =
sg_op (entry M i k * entry P k j)
(entry N i k * entry P k j)
apply rng_dist_r.Defined.(** The identity matrix acts as a left identity for matrix multiplication. *)
R: Ring m, n: nat
LeftIdentity matrix_mult (identity_matrix R m)
R: Ring m, n: nat
LeftIdentity matrix_mult (identity_matrix R m)
R: Ring m, n: nat M: Matrix R m n i, j: nat Hi: (i < m)%nat Hj: (j < n)%nat
entry (matrix_mult (identity_matrix R m) M) i j =
entry M i j
R: Ring m, n: nat M: Matrix R m n i, j: nat Hi: (i < m)%nat Hj: (j < n)%nat
ab_sum m
(fun (k : nat) (Hk : (k < m)%nat) =>
entry (identity_matrix R m) i k * entry M k j) =
entry M i j
R: Ring m, n: nat M: Matrix R m n i, j: nat Hi: (i < m)%nat Hj: (j < n)%nat
forall (k : nat) (Hk : (k < m)%nat),
entry (identity_matrix R m) i k * entry M k j =
?Goal k Hk
R: Ring m, n: nat M: Matrix R m n i, j: nat Hi: (i < m)%nat Hj: (j < n)%nat
ab_sum m ?Goal = entry M i j
R: Ring m, n: nat M: Matrix R m n i, j: nat Hi: (i < m)%nat Hj: (j < n)%nat
ab_sum m
(fun (k : nat) (Hk : (k < m)%nat) =>
kronecker_delta i k * entry M k j) = entry M i j
napply rng_sum_kronecker_delta_l.Defined.(** The identity matrix acts as a right identity for matrix multiplication. *)
R: Ring m, n: nat
RightIdentity matrix_mult (identity_matrix R n)
R: Ring m, n: nat
RightIdentity matrix_mult (identity_matrix R n)
R: Ring m, n: nat M: Matrix R m n i, j: nat Hi: (i < m)%nat Hj: (j < n)%nat
entry (matrix_mult M (identity_matrix R n)) i j =
entry M i j
R: Ring m, n: nat M: Matrix R m n i, j: nat Hi: (i < m)%nat Hj: (j < n)%nat
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry M i k * entry (identity_matrix R n) k j) =
entry M i j
R: Ring m, n: nat M: Matrix R m n i, j: nat Hi: (i < m)%nat Hj: (j < n)%nat
forall (k : nat) (Hk : (k < n)%nat),
entry M i k * entry (identity_matrix R n) k j =
?Goal k Hk
R: Ring m, n: nat M: Matrix R m n i, j: nat Hi: (i < m)%nat Hj: (j < n)%nat
ab_sum n ?Goal = entry M i j
R: Ring m, n: nat M: Matrix R m n i, j: nat Hi: (i < m)%nat Hj: (j < n)%nat
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry M i k * kronecker_delta k j) = entry M i j
napply rng_sum_kronecker_delta_r'.Defined.(** TODO: define this as an R-algebra. What is an R-algebra over a non-commutative right however? (Here we have a bimodule which might be important) *)(** Matrices over a ring form a (generally) non-commutative ring. *)
R: Ring n: nat
Ring
R: Ring n: nat
Ring
R: Ring n: nat
AbGroup
R: Ring n: nat
Mult ?R
R: Ring n: nat
One ?R
R: Ring n: nat
Associative mult
R: Ring n: nat
LeftDistribute mult plus
R: Ring n: nat
RightDistribute mult plus
R: Ring n: nat
LeftIdentity mult 1
R: Ring n: nat
RightIdentity mult 1
R: Ring n: nat
AbGroup
exact (abgroup_matrix R n n).
R: Ring n: nat
Mult (abgroup_matrix R n n)
exact matrix_mult.
R: Ring n: nat
One (abgroup_matrix R n n)
exact (identity_matrix R n).
R: Ring n: nat
Associative mult
exact (associative_matrix_mult R n n n n).
R: Ring n: nat
LeftDistribute mult plus
exact (left_distribute_matrix_mult R n n n).
R: Ring n: nat
RightDistribute mult plus
exact (right_distribute_matrix_mult R n n n).
R: Ring n: nat
LeftIdentity mult 1
exact (left_identity_matrix_mult R n n).
R: Ring n: nat
RightIdentity mult 1
exact (right_identity_matrix_mult R n n).Defined.(** Matrix multiplication on the right preserves scalar multiplication in the sense that [matrix_lact r (matrix_mult M N) = matrix_mult (matrix_lact r M) N] for [r] a ring element and [M] and [N] matrices of compatible sizes. *)
R: Ring m, n, p: nat r: R M: Matrix R m n N: Matrix R n p
matrix_lact r (matrix_mult M N) =
matrix_mult (matrix_lact r M) N
R: Ring m, n, p: nat r: R M: Matrix R m n N: Matrix R n p
forall (ij : nat) (Hi : (i < m)%nat)
(Hj : (j < p)%nat),
entry (matrix_lact r (matrix_mult M N)) i j =
entry (matrix_mult (matrix_lact r M) N) i j
R: Ring m, n, p: nat r: R M: Matrix R m n N: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat
entry (matrix_lact r (matrix_mult M N)) i j =
entry (matrix_mult (matrix_lact r M) N) i j
R: Ring m, n, p: nat r: R M: Matrix R m n N: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat
lact r
(ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry M i k * entry N k j)) =
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry (matrix_lact r M) i k * entry N k j)
R: Ring m, n, p: nat r: R M: Matrix R m n N: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
r * (entry M i k * entry N k j)) =
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry (matrix_lact r M) i k * entry N k j)
R: Ring m, n, p: nat r: R M: Matrix R m n N: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat
forall (k : nat) (Hk : (k < n)%nat),
(fun (k0 : nat) (Hk0 : (k0 < n)%nat) =>
r * (entry M i k0 * entry N k0 j)) k Hk =
(fun (k0 : nat) (Hk0 : (k0 < n)%nat) =>
entry (matrix_lact r M) i k0 * entry N k0 j) k Hk
R: Ring m, n, p: nat r: R M: Matrix R m n N: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat k: nat Hk: (k < n)%nat
r * (entry M i k * entry N k j) =
entry (vector_lact r M) i k * entry N k j
R: Ring m, n, p: nat r: R M: Matrix R m n N: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat k: nat Hk: (k < n)%nat
r * (entry M i k * entry N k j) =
lact r (Vector.entry (Vector.entry M i) k) *
entry N k j
snapply rng_mult_assoc.Defined.(** The same doesn't hold for the right matrix, since the ring is not commutative. However we could say an analagous statement for the right action. We haven't yet stated a definition of right module yet though. *)(** In a commutative ring, matrix multiplication over the ring and the opposite ring agree. *)
R: CRing m, n, p: nat M: Matrix R m n N: Matrix R n p
matrix_mult M N = matrix_mult M N
R: CRing m, n, p: nat M: Matrix R m n N: Matrix R n p
matrix_mult M N = matrix_mult M N
R: CRing m, n, p: nat M: Matrix R m n N: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat
entry (matrix_mult M N) i j =
entry (matrix_mult M N) i j
R: CRing m, n, p: nat M: Matrix R m n N: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry M i k * entry N k j) =
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry M i k * entry N k j)
R: CRing m, n, p: nat M: Matrix R m n N: Matrix R n p i, j: nat Hi: (i < m)%nat Hj: (j < p)%nat k: nat Hk: (k < n)%nat
entry M i k * entry N k j = entry M i k * entry N k j
apply rng_mult_comm.Defined.(** ** Transpose *)(** The transpose of a matrix is the matrix with the rows and columns swapped. *)Definitionmatrix_transpose {R : Type} {mn} : Matrix R m n -> Matrix R n m
:= funM => Build_Matrix R n m (funijH1H2 => entry M j i).(** Transposing a matrix is involutive. *)
R: Type m, n: nat M: Matrix R m n
matrix_transpose (matrix_transpose M) = M
R: Type m, n: nat M: Matrix R m n
matrix_transpose (matrix_transpose M) = M
R: Type m, n: nat M: Matrix R m n
forall (ij : nat) (Hi : (i < m)%nat)
(Hj : (j < n)%nat),
entry (matrix_transpose (matrix_transpose M)) i j =
entry M i j
R: Type m, n: nat M: Matrix R m n i, j: nat Hi: (i < m)%nat Hj: (j < n)%nat
entry (matrix_transpose (matrix_transpose M)) i j =
entry M i j
R: Type m, n: nat M: Matrix R m n i, j: nat Hi: (i < m)%nat Hj: (j < n)%nat
entry (matrix_transpose M) j i = entry M i j
napply entry_Build_Matrix.Defined.(** Transpose distributes over addition. *)
R: Ring m, n: nat M, N: Matrix R m n
matrix_transpose (matrix_plus M N) =
matrix_plus (matrix_transpose M) (matrix_transpose N)
R: Ring m, n: nat M, N: Matrix R m n
matrix_transpose (matrix_plus M N) =
matrix_plus (matrix_transpose M) (matrix_transpose N)
R: Ring m, n: nat M, N: Matrix R m n
forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < m)%nat),
entry (matrix_transpose (matrix_plus M N)) i j =
entry
(matrix_plus (matrix_transpose M)
(matrix_transpose N)) i j
R: Ring m, n: nat M, N: Matrix R m n i, j: nat Hi: (i < n)%nat Hj: (j < m)%nat
entry (matrix_transpose (matrix_plus M N)) i j =
entry
(matrix_plus (matrix_transpose M)
(matrix_transpose N)) i j
byrewrite !entry_Build_Matrix, !entry_Build_Vector.Defined.(** Transpose commutes with scalar multiplication. *)
R: Ring m, n: nat r: R M: Matrix R m n
matrix_transpose (matrix_lact r M) =
matrix_lact r (matrix_transpose M)
R: Ring m, n: nat r: R M: Matrix R m n
matrix_transpose (matrix_lact r M) =
matrix_lact r (matrix_transpose M)
R: Ring m, n: nat r: R M: Matrix R m n
forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < m)%nat),
entry (matrix_transpose (matrix_lact r M)) i j =
entry (matrix_lact r (matrix_transpose M)) i j
R: Ring m, n: nat r: R M: Matrix R m n i, j: nat Hi: (i < n)%nat Hj: (j < m)%nat
entry (matrix_transpose (matrix_lact r M)) i j =
entry (matrix_lact r (matrix_transpose M)) i j
byrewrite !entry_Build_Matrix, !entry_Build_Vector.Defined.(** The negation of a transposed matrix is the same as the transposed matrix of the negation. *)
R: Ring m, n: nat M: Matrix R m n
matrix_transpose (matrix_negate M) =
matrix_negate (matrix_transpose M)
R: Ring m, n: nat M: Matrix R m n
matrix_transpose (matrix_negate M) =
matrix_negate (matrix_transpose M)
R: Ring m, n: nat M: Matrix R m n
forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < m)%nat),
entry (matrix_transpose (matrix_negate M)) i j =
entry (matrix_negate (matrix_transpose M)) i j
R: Ring m, n: nat M: Matrix R m n i, j: nat Hi: (i < n)%nat Hj: (j < m)%nat
entry (matrix_transpose (matrix_negate M)) i j =
entry (matrix_negate (matrix_transpose M)) i j
byrewrite !entry_Build_Matrix, !entry_Build_Vector.Defined.(** Transpose distributes over multiplication when you reverse the ring multiplication. *)
R: Ring m, n, p: nat M: Matrix R m n N: Matrix R n p
matrix_transpose (matrix_mult M N) =
matrix_mult (matrix_transpose N) (matrix_transpose M)
R: Ring m, n, p: nat M: Matrix R m n N: Matrix R n p
matrix_transpose (matrix_mult M N) =
matrix_mult (matrix_transpose N) (matrix_transpose M)
R: Ring m, n, p: nat M: Matrix R m n N: Matrix R n p
forall (ij : nat) (Hi : (i < p)%nat)
(Hj : (j < m)%nat),
entry (matrix_transpose (matrix_mult M N)) i j =
entry
(matrix_mult (matrix_transpose N)
(matrix_transpose M)) i j
R: Ring m, n, p: nat M: Matrix R m n N: Matrix R n p i, j: nat Hi: (i < p)%nat Hj: (j < m)%nat
entry (matrix_transpose (matrix_mult M N)) i j =
entry
(matrix_mult (matrix_transpose N)
(matrix_transpose M)) i j
R: Ring m, n, p: nat M: Matrix R m n N: Matrix R n p i, j: nat Hi: (i < p)%nat Hj: (j < m)%nat
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry M j k * entry N k i) =
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry (matrix_transpose N) i k *
entry (matrix_transpose M) k j)
R: Ring m, n, p: nat M: Matrix R m n N: Matrix R n p i, j: nat Hi: (i < p)%nat Hj: (j < m)%nat
forall (k : nat) (Hk : (k < n)%nat),
entry M j k * entry N k i =
entry (matrix_transpose N) i k *
entry (matrix_transpose M) k j
R: Ring m, n, p: nat M: Matrix R m n N: Matrix R n p i, j: nat Hi: (i < p)%nat Hj: (j < m)%nat k: nat Hk: (k < n)%nat
entry M j k * entry N k i =
entry (matrix_transpose N) i k *
entry (matrix_transpose M) k j
R: Ring m, n, p: nat M: Matrix R m n N: Matrix R n p i, j: nat Hi: (i < p)%nat Hj: (j < m)%nat k: nat Hk: (k < n)%nat
entry M j k * entry N k i = entry N k i * entry M j k
reflexivity.Defined.(** When the ring is commutative, there is no need to reverse the multiplication. *)
R: CRing m, n, p: nat M: Matrix R m n N: Matrix R n p
matrix_transpose (matrix_mult M N) =
matrix_mult (matrix_transpose N) (matrix_transpose M)
R: CRing m, n, p: nat M: Matrix R m n N: Matrix R n p
matrix_transpose (matrix_mult M N) =
matrix_mult (matrix_transpose N) (matrix_transpose M)
R: CRing m, n, p: nat M: Matrix R m n N: Matrix R n p
matrix_mult (matrix_transpose N) (matrix_transpose M) =
matrix_mult (matrix_transpose N) (matrix_transpose M)
apply matrix_mult_rng_op.Defined.(** The transpose of the zero matrix is the zero matrix. *)
R: Ring m, n: nat
matrix_transpose (matrix_zero R m n) =
matrix_zero R n m
R: Ring m, n: nat
matrix_transpose (matrix_zero R m n) =
matrix_zero R n m
R: Ring m, n: nat
forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < m)%nat),
entry (matrix_transpose (matrix_zero R m n)) i j =
entry (matrix_zero R n m) i j
R: Ring m, n, i, j: nat Hi: (i < n)%nat Hj: (j < m)%nat
entry (matrix_transpose (matrix_zero R m n)) i j =
entry (matrix_zero R n m) i j
byrewrite !entry_Build_Matrix.Defined.(** The transpose of the identity matrix is the identity matrix. *)
R: Ring n: nat
matrix_transpose (identity_matrix R n) =
identity_matrix R n
R: Ring n: nat
matrix_transpose (identity_matrix R n) =
identity_matrix R n
R: Ring n: nat
forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
entry (matrix_transpose (identity_matrix R n)) i j =
entry (identity_matrix R n) i j
R: Ring n, i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
entry (matrix_transpose (identity_matrix R n)) i j =
entry (identity_matrix R n) i j
R: Ring n, i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
kronecker_delta j i = kronecker_delta i j
apply kronecker_delta_symm.Defined.(** ** Diagonal matrices *)(** A diagonal matrix is a matrix with zeros everywhere except on the diagonal. Its entries are given by a vector. *)
R: Ring n: nat v: Vector R n
Matrix R n n
R: Ring n: nat v: Vector R n
Matrix R n n
R: Ring n: nat v: Vector R n
forallij : nat, (i < n)%nat -> (j < n)%nat -> R
R: Ring n: nat v: Vector R n i, j: nat H1: (i < n)%nat H2: (j < n)%nat
R
exact (kronecker_delta i j * Vector.entry v i).Defined.(** Addition of diagonal matrices is the same as addition of the corresponding vectors. *)
R: Ring n: nat v, w: Vector R n
matrix_plus (matrix_diag v) (matrix_diag w) =
matrix_diag (vector_plus v w)
R: Ring n: nat v, w: Vector R n
matrix_plus (matrix_diag v) (matrix_diag w) =
matrix_diag (vector_plus v w)
R: Ring n: nat v, w: Vector R n
matrix_diag (vector_plus v w) =
matrix_plus (matrix_diag v) (matrix_diag w)
R: Ring n: nat v, w: Vector R n
forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
entry (matrix_diag (vector_plus v w)) i j =
entry (matrix_plus (matrix_diag v) (matrix_diag w)) i
j
R: Ring n: nat v, w: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
entry (matrix_diag (vector_plus v w)) i j =
entry (matrix_plus (matrix_diag v) (matrix_diag w)) i
j
R: Ring n: nat v, w: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
kronecker_delta i j *
(Vector.entry v i + Vector.entry w i) =
kronecker_delta i j * Vector.entry v i +
kronecker_delta i j * Vector.entry w i
napply rng_dist_l.Defined.(** Matrix multiplication of diagonal matrices is the same as multiplying the corresponding vectors pointwise. *)
R: Ring n: nat v, w: Vector R n
matrix_mult (matrix_diag v) (matrix_diag w) =
matrix_diag (vector_map2 mult v w)
R: Ring n: nat v, w: Vector R n
matrix_mult (matrix_diag v) (matrix_diag w) =
matrix_diag (vector_map2 mult v w)
R: Ring n: nat v, w: Vector R n
forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
entry (matrix_mult (matrix_diag v) (matrix_diag w)) i
j = entry (matrix_diag (vector_map2 mult v w)) i j
R: Ring n: nat v, w: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
entry (matrix_mult (matrix_diag v) (matrix_diag w)) i
j = entry (matrix_diag (vector_map2 mult v w)) i j
R: Ring n: nat v, w: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry (matrix_diag v) i k *
entry (matrix_diag w) k j) =
kronecker_delta i j *
Vector.entry (vector_map2 mult v w) i
R: Ring n: nat v, w: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
forall (k : nat) (Hk : (k < n)%nat),
entry (matrix_diag v) i k * entry (matrix_diag w) k j =
?Goal0 k Hk
R: Ring n: nat v, w: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
ab_sum n ?Goal0 =
kronecker_delta i j *
Vector.entry (vector_map2 mult v w) i
R: Ring n: nat v, w: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
forall (k : nat) (Hk : (k < n)%nat),
entry (matrix_diag v) i k * entry (matrix_diag w) k j =
?Goal0 k Hk
R: Ring n: nat v, w: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat k: nat Hk: (k < n)%nat
entry (matrix_diag v) i k * entry (matrix_diag w) k j =
?Goal k Hk
R: Ring n: nat v, w: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat k: nat Hk: (k < n)%nat
kronecker_delta i k * Vector.entry v i *
(kronecker_delta k j * Vector.entry w k) = ?Goal k Hk
R: Ring n: nat v, w: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat k: nat Hk: (k < n)%nat
kronecker_delta i k * Vector.entry v i *
kronecker_delta k j * Vector.entry w k = ?Goal k Hk
R: Ring n: nat v, w: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat k: nat Hk: (k < n)%nat
kronecker_delta i k *
(Vector.entry v i * kronecker_delta k j) *
Vector.entry w k = ?Goal k Hk
R: Ring n: nat v, w: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat k: nat Hk: (k < n)%nat
kronecker_delta i k *
(kronecker_delta k j * Vector.entry v i) *
Vector.entry w k = ?Goal k Hk
R: Ring n: nat v, w: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat k: nat Hk: (k < n)%nat
kronecker_delta i k *
(kronecker_delta k j *
(Vector.entry v i * Vector.entry w k)) = ?Goal k Hk
reflexivity.
R: Ring n: nat v, w: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
kronecker_delta i k *
(kronecker_delta k j *
(Vector.entry v i * Vector.entry w k))) =
kronecker_delta i j *
Vector.entry (vector_map2 mult v w) i
R: Ring n: nat v, w: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
kronecker_delta i j *
(Vector.entry v i * Vector.entry w i) =
kronecker_delta i j *
Vector.entry (vector_map2 mult v w) i
byrewrite entry_Build_Vector.Defined.(** The transpose of a diagonal matrix is the same diagonal matrix. *)
R: Ring n: nat v: Vector R n
matrix_transpose (matrix_diag v) = matrix_diag v
R: Ring n: nat v: Vector R n
matrix_transpose (matrix_diag v) = matrix_diag v
R: Ring n: nat v: Vector R n
forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
entry (matrix_transpose (matrix_diag v)) i j =
entry (matrix_diag v) i j
R: Ring n: nat v: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
entry (matrix_transpose (matrix_diag v)) i j =
entry (matrix_diag v) i j
R: Ring n: nat v: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
kronecker_delta j i * Vector.entry v j =
kronecker_delta i j * Vector.entry v i
R: Ring n: nat v: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
kronecker_delta i j * Vector.entry v j =
kronecker_delta i j * Vector.entry v i
R: Ring n: nat v: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
(if dec (i = j) then1else0) * Vector.entry v j =
(if dec (i = j) then1else0) * Vector.entry v i
R: Ring n: nat v: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat p: i = j
1 * Vector.entry v j = 1 * Vector.entry v i
R: Ring n: nat v: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat np: i <> j
0 * Vector.entry v j = 0 * Vector.entry v i
R: Ring n: nat v: Vector R n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat np: i <> j
0 * Vector.entry v j = 0 * Vector.entry v i
byrewrite !rng_mult_zero_l.Defined.(** The diagonal matrix construction is injective. *)
R: Ring n: nat
IsInjective matrix_diag
R: Ring n: nat
IsInjective matrix_diag
R: Ring n: nat v1, v2: Vector R n p: matrix_diag v1 = matrix_diag v2
v1 = v2
R: Ring n: nat v1, v2: Vector R n p: matrix_diag v1 = matrix_diag v2
forall (i : nat) (H : (i < n)%nat),
Vector.entry v1 i = Vector.entry v2 i
R: Ring n: nat v1, v2: Vector R n p: matrix_diag v1 = matrix_diag v2 i: nat Hi: (i < n)%nat
Vector.entry v1 i = Vector.entry v2 i
R: Ring n: nat v1, v2: Vector R n i: nat Hi: (i < n)%nat p: entry (matrix_diag v1) i i =
entry (matrix_diag v2) i i
Vector.entry v1 i = Vector.entry v2 i
R: Ring n: nat v1, v2: Vector R n i: nat Hi: (i < n)%nat p: kronecker_delta i i * Vector.entry v1 i =
kronecker_delta i i * Vector.entry v2 i
Vector.entry v1 i = Vector.entry v2 i
R: Ring n: nat v1, v2: Vector R n i: nat Hi: (i < n)%nat p: 1 * Vector.entry v1 i = 1 * Vector.entry v2 i
Vector.entry v1 i = Vector.entry v2 i
byrewrite2 rng_mult_one_l in p.Defined.(** A matrix is diagonal if it is equal to a diagonal matrix. *)ClassIsDiagonal@{i} {R : Ring@{i}} {n : nat} (M : Matrix R n n) : Type@{i} := {
isdiagonal_diag_vector : Vector R n;
isdiagonal_diag : M = matrix_diag isdiagonal_diag_vector;
}.Arguments isdiagonal_diag_vector {R n} M {_}.Arguments isdiagonal_diag {R n} M {_}.Definitionissig_IsDiagonal {R : Ring@{i}} {n : nat} {M : Matrix R n n}
: _ <~> IsDiagonal M
:= ltac:(issig).(** A matrix is diagonal in a unique way. *)
R: Ring n: nat M: Matrix R n n
IsHProp (IsDiagonal M)
R: Ring n: nat M: Matrix R n n
IsHProp (IsDiagonal M)
R: Ring n: nat M: Matrix R n n
forallxy : IsDiagonal M, x = y
R: Ring n: nat M: Matrix R n n x, y: IsDiagonal M
x = y
R: Ring n: nat M: Matrix R n n x, y: IsDiagonal M
issig_IsDiagonal^-1%equiv x =
issig_IsDiagonal^-1%equiv y
R: Ring n: nat M: Matrix R n n x, y: IsDiagonal M
isdiagonal_diag_vector M = isdiagonal_diag_vector M
R: Ring n: nat M: Matrix R n n x, y: IsDiagonal M
matrix_diag (isdiagonal_diag_vector M) =
matrix_diag (isdiagonal_diag_vector M)
exact ((isdiagonal_diag M)^ @ isdiagonal_diag M).Defined.(** The zero matrix is diagonal. *)
R: Ring n: nat
IsDiagonal (matrix_zero R n n)
R: Ring n: nat
IsDiagonal (matrix_zero R n n)
R: Ring n: nat
matrix_zero R n n = matrix_diag (vector_zero R n)
R: Ring n: nat
forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
entry (matrix_zero R n n) i j =
entry (matrix_diag (vector_zero R n)) i j
R: Ring n, i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
entry (matrix_zero R n n) i j =
entry (matrix_diag (vector_zero R n)) i j
R: Ring n, i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
0 = kronecker_delta i j * 0
byrewrite rng_mult_zero_r.Defined.(** The identity matrix is diagonal. *)
R: Ring n: nat
IsDiagonal (identity_matrix R n)
R: Ring n: nat
IsDiagonal (identity_matrix R n)
R: Ring n: nat
identity_matrix R n =
matrix_diag
(Build_Vector R n
(fun (i : nat) (_ : (i < n)%nat) => 1))
R: Ring n: nat
forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
entry (identity_matrix R n) i j =
entry
(matrix_diag
(Build_Vector R n
(fun (i0 : nat) (_ : (i0 < n)%nat) => 1))) i j
R: Ring n, i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
entry (identity_matrix R n) i j =
entry
(matrix_diag
(Build_Vector R n
(fun (i : nat) (_ : (i < n)%nat) => 1))) i j
R: Ring n, i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
kronecker_delta i j = kronecker_delta i j * 1
byrewrite rng_mult_one_r.Defined.(** The sum of two diagonal matrices is diagonal. *)
R: Ring n: nat M, N: Matrix R n n H: IsDiagonal M H0: IsDiagonal N
IsDiagonal (matrix_plus M N)
R: Ring n: nat M, N: Matrix R n n H: IsDiagonal M H0: IsDiagonal N
IsDiagonal (matrix_plus M N)
R: Ring n: nat M, N: Matrix R n n H: IsDiagonal M H0: IsDiagonal N
matrix_plus M N =
matrix_diag
(vector_plus (isdiagonal_diag_vector M)
(isdiagonal_diag_vector N))
R: Ring n: nat M, N: Matrix R n n H: IsDiagonal M H0: IsDiagonal N
apply matrix_diag_plus.Defined.(** The negative of a diagonal matrix is diagonal. *)
R: Ring n: nat M: Matrix R n n H: IsDiagonal M
IsDiagonal (matrix_negate M)
R: Ring n: nat M: Matrix R n n H: IsDiagonal M
IsDiagonal (matrix_negate M)
R: Ring n: nat M: Matrix R n n H: IsDiagonal M
matrix_negate M =
matrix_diag
(vector_neg R n (isdiagonal_diag_vector M))
R: Ring n: nat M: Matrix R n n H: IsDiagonal M
matrix_negate (matrix_diag (isdiagonal_diag_vector M)) =
matrix_diag
(vector_neg R n (isdiagonal_diag_vector M))
R: Ring n: nat M: Matrix R n n H: IsDiagonal M
forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
entry
(matrix_negate
(matrix_diag (isdiagonal_diag_vector M))) i j =
entry
(matrix_diag
(vector_neg R n (isdiagonal_diag_vector M))) i j
R: Ring n: nat M: Matrix R n n H: IsDiagonal M i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
entry
(matrix_negate
(matrix_diag (isdiagonal_diag_vector M))) i j =
entry
(matrix_diag
(vector_neg R n (isdiagonal_diag_vector M))) i j
R: Ring n: nat M: Matrix R n n H: IsDiagonal M i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
-
(kronecker_delta i j *
Vector.entry (isdiagonal_diag_vector M) i) =
kronecker_delta i j *
- Vector.entry (isdiagonal_diag_vector M) i
byrewrite rng_mult_negate_r.Defined.(** The product of two diagonal matrices is diagonal. *)
R: Ring n: nat M, N: Matrix R n n H: IsDiagonal M H0: IsDiagonal N
IsDiagonal (matrix_mult M N)
R: Ring n: nat M, N: Matrix R n n H: IsDiagonal M H0: IsDiagonal N
IsDiagonal (matrix_mult M N)
R: Ring n: nat M, N: Matrix R n n H: IsDiagonal M H0: IsDiagonal N
matrix_mult M N =
matrix_diag
(vector_map2 mult (isdiagonal_diag_vector M)
(isdiagonal_diag_vector N))
R: Ring n: nat M, N: Matrix R n n H: IsDiagonal M H0: IsDiagonal N
matrix_mult (matrix_diag (isdiagonal_diag_vector M))
(matrix_diag (isdiagonal_diag_vector N)) =
matrix_diag
(vector_map2 mult (isdiagonal_diag_vector M)
(isdiagonal_diag_vector N))
apply matrix_diag_mult.Defined.(** The transpose of a diagonal matrix is diagonal. *)
R: Ring n: nat M: Matrix R n n H: IsDiagonal M
IsDiagonal (matrix_transpose M)
R: Ring n: nat M: Matrix R n n H: IsDiagonal M
IsDiagonal (matrix_transpose M)
R: Ring n: nat M: Matrix R n n H: IsDiagonal M
matrix_transpose M =
matrix_diag (isdiagonal_diag_vector M)
R: Ring n: nat M: Matrix R n n H: IsDiagonal M
matrix_transpose
(matrix_diag (isdiagonal_diag_vector M)) =
matrix_diag (isdiagonal_diag_vector M)
apply matrix_transpose_diag.Defined.(** Given a square matrix, we can extract the diagonal as a vector. *)Definitionmatrix_diag_vector {R : Ring} {n : nat} (M : Matrix R n n)
: Vector R n
:= Build_Vector R n (funi_ => entry M i i).(** Diagonal matrices form a subring of the ring of square matrices. *)
R: Ring n: nat
Subring (matrix_ring R n)
R: Ring n: nat
Subring (matrix_ring R n)
R: Ring n: nat
forallx : matrix_ring R n, IsHProp (IsDiagonal x)
R: Ring n: nat
forallxy : matrix_ring R n,
IsDiagonal x -> IsDiagonal y -> IsDiagonal (x - y)
R: Ring n: nat
forallxy : matrix_ring R n,
IsDiagonal x -> IsDiagonal y -> IsDiagonal (x * y)
R: Ring n: nat
IsDiagonal 1
R: Ring n: nat
forallx : matrix_ring R n, IsHProp (IsDiagonal x)
intros; exact _.
R: Ring n: nat
forallxy : matrix_ring R n,
IsDiagonal x -> IsDiagonal y -> IsDiagonal (x - y)
R: Ring n: nat x, y: matrix_ring R n dx: IsDiagonal x dy: IsDiagonal y
IsDiagonal (x - y)
R: Ring n: nat x, y: matrix_ring R n dx: IsDiagonal x dy: IsDiagonal y
IsDiagonal (- y)
by napply isdiagonal_matrix_negate.
R: Ring n: nat
forallxy : matrix_ring R n,
IsDiagonal x -> IsDiagonal y -> IsDiagonal (x * y)
napply isdiagonal_matrix_mult.
R: Ring n: nat
IsDiagonal 1
napply isdiagonal_identity_matrix.Defined.(** ** Trace *)(** The trace of a square matrix is the sum of the diagonal entries. *)Definitionmatrix_trace {R : Ring} {n} (M : Matrix R n n) : R
:= ab_sum n (funiHi => entry M i i).(** The trace of a matrix preserves addition. *)
R: Ring n: nat M, N: Matrix R n n
matrix_trace (matrix_plus M N) =
matrix_trace M + matrix_trace N
R: Ring n: nat M, N: Matrix R n n
matrix_trace (matrix_plus M N) =
matrix_trace M + matrix_trace N
R: Ring n: nat M, N: Matrix R n n
ab_sum n
(fun (i : nat) (Hi : (i < n)%nat) =>
entry (matrix_plus M N) i i) =
ab_sum n
(fun (i : nat) (Hi : (i < n)%nat) => entry M i i) +
ab_sum n
(fun (i : nat) (Hi : (i < n)%nat) => entry N i i)
R: Ring n: nat M, N: Matrix R n n
forall (k : nat) (Hk : (k < n)%nat),
entry (matrix_plus M N) k k = ?Goal k Hk
R: Ring n: nat M, N: Matrix R n n
ab_sum n ?Goal =
ab_sum n
(fun (i : nat) (Hi : (i < n)%nat) => entry M i i) +
ab_sum n
(fun (i : nat) (Hi : (i < n)%nat) => entry N i i)
R: Ring n: nat M, N: Matrix R n n
forall (k : nat) (Hk : (k < n)%nat),
entry (matrix_plus M N) k k = ?Goal k Hk
R: Ring n: nat M, N: Matrix R n n i: nat Hi: (i < n)%nat
entry (matrix_plus M N) i i = ?Goal i Hi
byrewrite entry_Build_Matrix.
R: Ring n: nat M, N: Matrix R n n
ab_sum n
(fun (i : nat) (Hi : (i < n)%nat) =>
Vector.entry (Vector.entry M i) i +
Vector.entry (Vector.entry N i) i) =
ab_sum n
(fun (i : nat) (Hi : (i < n)%nat) => entry M i i) +
ab_sum n
(fun (i : nat) (Hi : (i < n)%nat) => entry N i i)
byrewrite ab_sum_plus.Defined.(** The trace of a matrix preserves scalar multiplication. *)
R: Ring n: nat r: R M: Matrix R n n
matrix_trace (matrix_lact r M) = r * matrix_trace M
R: Ring n: nat r: R M: Matrix R n n
matrix_trace (matrix_lact r M) = r * matrix_trace M
R: Ring n: nat r: R M: Matrix R n n
ab_sum n
(fun (i : nat) (Hi : (i < n)%nat) =>
entry (matrix_lact r M) i i) =
r *
ab_sum n
(fun (i : nat) (Hi : (i < n)%nat) => entry M i i)
R: Ring n: nat r: R M: Matrix R n n
ab_sum n
(fun (i : nat) (Hi : (i < n)%nat) =>
entry (matrix_lact r M) i i) =
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) => r * entry M k k)
R: Ring n: nat r: R M: Matrix R n n
forall (k : nat) (Hk : (k < n)%nat),
entry (matrix_lact r M) k k = r * entry M k k
R: Ring n: nat r: R M: Matrix R n n i: nat Hi: (i < n)%nat
entry (matrix_lact r M) i i = r * entry M i i
byrewrite entry_Build_Matrix.Defined.(** The trace of a matrix multiplication is the same as the trace of the reverse multiplication. This holds only in a commutative ring. *)
R: CRing m, n: nat M: Matrix R m n N: Matrix R n m
matrix_trace (matrix_mult M N) =
matrix_trace (matrix_mult N M)
R: CRing m, n: nat M: Matrix R m n N: Matrix R n m
matrix_trace (matrix_mult M N) =
matrix_trace (matrix_mult N M)
R: CRing m, n: nat M: Matrix R m n N: Matrix R n m
forall (k : nat) (Hk : (k < m)%nat),
entry (matrix_mult M N) k k = ?Goal k Hk
R: CRing m, n: nat M: Matrix R m n N: Matrix R n m
ab_sum m ?Goal = matrix_trace (matrix_mult N M)
R: CRing m, n: nat M: Matrix R m n N: Matrix R n m
forall (k : nat) (Hk : (k < m)%nat),
entry (matrix_mult M N) k k = ?Goal k Hk
R: CRing m, n: nat M: Matrix R m n N: Matrix R n m i: nat Hi: (i < m)%nat
entry (matrix_mult M N) i i = ?Goal i Hi
R: CRing m, n: nat M: Matrix R m n N: Matrix R n m i: nat Hi: (i < m)%nat
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry M i k * entry N k i) = ?Goal i Hi
R: CRing m, n: nat M: Matrix R m n N: Matrix R n m i: nat Hi: (i < m)%nat
forall (k : nat) (Hk : (k < n)%nat),
entry M i k * entry N k i = ?Goal0 k Hk
R: CRing m, n: nat M: Matrix R m n N: Matrix R n m i: nat Hi: (i < m)%nat j: nat Hj: (j < n)%nat
entry M i j * entry N j i = ?Goal0 j Hj
apply rng_mult_comm.
R: CRing m, n: nat M: Matrix R m n N: Matrix R n m
ab_sum m
(fun (i : nat) (Hi : (i < m)%nat) =>
ab_sum n
(fun (j : nat) (Hj : (j < n)%nat) =>
entry N j i * entry M i j)) =
matrix_trace (matrix_mult N M)
R: CRing m, n: nat M: Matrix R m n N: Matrix R n m
ab_sum n
(fun (j : nat) (Hj : (j < n)%nat) =>
ab_sum m
(fun (i : nat) (Hi : (i < m)%nat) =>
entry N j i * entry M i j)) =
matrix_trace (matrix_mult N M)
R: CRing m, n: nat M: Matrix R m n N: Matrix R n m
forall (k : nat) (Hk : (k < n)%nat),
ab_sum m
(fun (i : nat) (Hi : (i < m)%nat) =>
entry N k i * entry M i k) =
entry (matrix_mult N M) k k
R: CRing m, n: nat M: Matrix R m n N: Matrix R n m i: nat Hi: (i < n)%nat
ab_sum m
(fun (i0 : nat) (Hi0 : (i0 < m)%nat) =>
entry N i i0 * entry M i0 i) =
entry (matrix_mult N M) i i
R: CRing m, n: nat M: Matrix R m n N: Matrix R n m i: nat Hi: (i < n)%nat
ab_sum m
(fun (i0 : nat) (Hi0 : (i0 < m)%nat) =>
entry N i i0 * entry M i0 i) =
ab_sum m
(fun (k : nat) (Hk : (k < m)%nat) =>
entry N i k * entry M k i)
reflexivity.Defined.(** The trace of the transpose of a matrix is the same as the trace of the matrix. *)
R: Ring n: nat M: Matrix R n n
matrix_trace (matrix_transpose M) = matrix_trace M
R: Ring n: nat M: Matrix R n n
matrix_trace (matrix_transpose M) = matrix_trace M
R: Ring n: nat M: Matrix R n n
forall (k : nat) (Hk : (k < n)%nat),
entry (matrix_transpose M) k k = entry M k k
R: Ring n: nat M: Matrix R n n i: nat Hi: (i < n)%nat
entry (matrix_transpose M) i i = entry M i i
napply entry_Build_Matrix.Defined.(** ** Matrix minors *)Definitionskip (n : nat) : nat -> nat
:= funi => if dec (i < n)%nat then i else i.+1%nat.
n: nat
IsInjective (skip n)
n: nat
IsInjective (skip n)
n: nat
forallxy : nat, skip n x = skip n y -> x = y
n, x, y: nat p: skip n x = skip n y
x = y
n, x, y: nat p: (if dec (x < n)%nat then x else x.+1%nat) =
(if dec (y < n)%nat then y else y.+1%nat)
x = y
n, x, y: nat H: (x < n)%nat H': (y < n)%nat p: x = y
x = y
n, x, y: nat H: (x < n)%nat H': ~ (y < n)%nat p: x = y.+1%nat
x = y
n, x, y: nat H: ~ (x < n)%nat H': (y < n)%nat p: x.+1%nat = y
destruct (dec (k < i))%nat as [H''|H'']; exact _.Defined.Definitionmatrix_minor {R : Ring@{i}} {n : nat} (ij : nat)
{Hi : (i < n.+1)%nat} {Hj : (j < n.+1)%nat} (M : Matrix R n.+1 n.+1)
: Matrix R n n
:= Build_Matrix R n n (funkl__ => entry M (skip i k) (skip j l)).(** A minor of the zero matrix is again the zero matrix. *)
R: Ring n, i, j: nat Hi: (i < n.+1)%nat Hj: (j < n.+1)%nat
matrix_minor i j (matrix_zero R n.+1 n.+1) =
matrix_zero R n n
R: Ring n, i, j: nat Hi: (i < n.+1)%nat Hj: (j < n.+1)%nat
matrix_minor i j (matrix_zero R n.+1 n.+1) =
matrix_zero R n n
R: Ring n, i, j: nat Hi: (i < n.+1)%nat Hj: (j < n.+1)%nat
forall (i0j0 : nat) (Hi0 : (i0 < n)%nat)
(Hj0 : (j0 < n)%nat),
entry (matrix_minor i j (matrix_zero R n.+1 n.+1)) i0
j0 = entry (matrix_zero R n n) i0 j0
R: Ring n, i, j: nat Hi: (i < n.+1)%nat Hj: (j < n.+1)%nat k, l: nat Hk: (k < n)%nat Hl: (l < n)%nat
entry (matrix_minor i j (matrix_zero R n.+1 n.+1)) k l =
entry (matrix_zero R n n) k l
byrewrite !entry_Build_Matrix.Defined.
R: Ring n, i: nat Hi: (i < n.+1)%nat
matrix_minor i i (identity_matrix R n.+1) =
identity_matrix R n
R: Ring n, i: nat Hi: (i < n.+1)%nat
matrix_minor i i (identity_matrix R n.+1) =
identity_matrix R n
R: Ring n, i: nat Hi: (i < n.+1)%nat
forall (i0j : nat) (Hi0 : (i0 < n)%nat)
(Hj : (j < n)%nat),
entry (matrix_minor i i (identity_matrix R n.+1)) i0 j =
entry (identity_matrix R n) i0 j
R: Ring n, i: nat Hi: (i < n.+1)%nat j, k: nat Hj: (j < n)%nat Hk: (k < n)%nat
entry (matrix_minor i i (identity_matrix R n.+1)) j k =
entry (identity_matrix R n) j k
R: Ring n, i: nat Hi: (i < n.+1)%nat j, k: nat Hj: (j < n)%nat Hk: (k < n)%nat
kronecker_delta (skip i j) (skip i k) =
kronecker_delta j k
rapply kronecker_delta_map_inj.Defined.
R: Ring n, i, j: nat Hi: (i < n.+1)%nat Hj: (j < n.+1)%nat M, N: Matrix R n.+1 n.+1
matrix_minor i j (matrix_plus M N) =
matrix_plus (matrix_minor i j M) (matrix_minor i j N)
R: Ring n, i, j: nat Hi: (i < n.+1)%nat Hj: (j < n.+1)%nat M, N: Matrix R n.+1 n.+1
matrix_minor i j (matrix_plus M N) =
matrix_plus (matrix_minor i j M) (matrix_minor i j N)
R: Ring n, i, j: nat Hi: (i < n.+1)%nat Hj: (j < n.+1)%nat M, N: Matrix R n.+1 n.+1
forall (i0j0 : nat) (Hi0 : (i0 < n)%nat)
(Hj0 : (j0 < n)%nat),
entry (matrix_minor i j (matrix_plus M N)) i0 j0 =
entry
(matrix_plus (matrix_minor i j M)
(matrix_minor i j N)) i0 j0
R: Ring n, i, j: nat Hi: (i < n.+1)%nat Hj: (j < n.+1)%nat M, N: Matrix R n.+1 n.+1 k, l: nat Hk: (k < n)%nat Hl: (l < n)%nat
entry (matrix_minor i j (matrix_plus M N)) k l =
entry
(matrix_plus (matrix_minor i j M)
(matrix_minor i j N)) k l
R: Ring n, i, j: nat Hi: (i < n.+1)%nat Hj: (j < n.+1)%nat M: Matrix R n.+1 n.+1 k, l: nat Hk: (k < n)%nat Hl: (l < n)%nat
entry (matrix_minor j i (matrix_transpose M)) k l =
entry (matrix_transpose (matrix_minor i j M)) k l
byrewrite4 entry_Build_Matrix.Defined.(** ** Triangular matrices *)(** A matrix is upper triangular if all the entries below the diagonal are zero. *)ClassIsUpperTriangular@{i} {R : Ring@{i}} {n : nat} (M : Matrix@{i} R n n) : Type@{i}
:= upper_triangular
: merely@{i} (forallij (Hi : (i < n)%nat) (Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0).
R: Ring n: nat M: Matrix R n n
IsHProp (IsUpperTriangular M)
R: Ring n: nat M: Matrix R n n
IsHProp (IsUpperTriangular M)
apply istrunc_truncation@{i i}.Defined.(** A matrix is lower triangular if all the entries above the diagonal are zero. We define it as the transpose being upper triangular. *)ClassIsLowerTriangular {R : Ring@{i}} {n : nat} (M : Matrix@{i} R n n) : Type@{i}
:= upper_triangular_transpose :: IsUpperTriangular (matrix_transpose M).
R: Ring n: nat M: Matrix R n n
IsHProp (IsLowerTriangular M)
R: Ring n: nat M: Matrix R n n
IsHProp (IsLowerTriangular M)
apply istrunc_truncation@{i i}.Defined.(** The transpose of a matrix is lower triangular if and only if the matrix is upper triangular. *)
R: Ring n: nat M: Matrix R n n IsUpperTriangular0: IsUpperTriangular M
IsLowerTriangular (matrix_transpose M)
R: Ring n: nat M: Matrix R n n IsUpperTriangular0: IsUpperTriangular M
IsLowerTriangular (matrix_transpose M)
R: Ring n: nat M: Matrix R n n IsUpperTriangular0: IsUpperTriangular M
byrewrite matrix_transpose_transpose.Defined.(** The sum of two upper triangular matrices is upper triangular. *)
R: Ring n: nat M, N: Matrix R n n H1: IsUpperTriangular M H2: IsUpperTriangular N
IsUpperTriangular (matrix_plus M N)
R: Ring n: nat M, N: Matrix R n n H1: IsUpperTriangular M H2: IsUpperTriangular N
IsUpperTriangular (matrix_plus M N)
R: Ring n: nat M, N: Matrix R n n H1: IsUpperTriangular M H2: IsUpperTriangular N
merely
(forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry (matrix_plus M N) i j = 0)
(* We use [strip_reflections] rather than [strip_truncations] here and below because it generates fewer universe variables in some versions of Coq. *)
R: Ring n: nat M, N: Matrix R n n H2: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry N i j = 0 H1: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry M i j = 0
forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry (matrix_plus M N) i j = 0
R: Ring n: nat M, N: Matrix R n n H2: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry N i j = 0 H1: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry M i j = 0 i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat lt_i_j: (i < j)%nat
entry (matrix_plus M N) i j = 0
R: Ring n: nat M, N: Matrix R n n H2: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry N i j = 0 i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat H1: entry M i j = 0 lt_i_j: (i < j)%nat
entry (matrix_plus M N) i j = 0
R: Ring n: nat M, N: Matrix R n n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat H2: entry N i j = 0 H1: entry M i j = 0 lt_i_j: (i < j)%nat
entry (matrix_plus M N) i j = 0
R: Ring n: nat M, N: Matrix R n n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat H2: entry N i j = 0 H1: entry M i j = 0 lt_i_j: (i < j)%nat
Vector.entry (Vector.entry M i) j +
Vector.entry (Vector.entry N i) j = 0
R: Ring n: nat M, N: Matrix R n n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat H2: entry N i j = 0 H1: entry M i j = 0 lt_i_j: (i < j)%nat
entry M i j + entry N i j = 0
R: Ring n: nat M, N: Matrix R n n i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat H2: entry N i j = 0 H1: entry M i j = 0 lt_i_j: (i < j)%nat
0 + 0 = 0
byrewrite rng_plus_zero_l.Defined.(** The sum of two lower triangular matrices is lower triangular. *)
R: Ring n: nat M, N: Matrix R n n IsLowerTriangular0: IsLowerTriangular M IsLowerTriangular1: IsLowerTriangular N
IsLowerTriangular (matrix_plus M N)
R: Ring n: nat M, N: Matrix R n n IsLowerTriangular0: IsLowerTriangular M IsLowerTriangular1: IsLowerTriangular N
IsLowerTriangular (matrix_plus M N)
R: Ring n: nat M, N: Matrix R n n IsLowerTriangular0: IsLowerTriangular M IsLowerTriangular1: IsLowerTriangular N
IsUpperTriangular (matrix_transpose (matrix_plus M N))
R: Ring n: nat M, N: Matrix R n n IsLowerTriangular0: IsLowerTriangular M IsLowerTriangular1: IsLowerTriangular N
IsUpperTriangular
(matrix_plus (matrix_transpose M)
(matrix_transpose N))
byapply upper_triangular_plus.Defined.(** The negation of an upper triangular matrix is upper triangular. *)
R: Ring n: nat M: Matrix R n n H: IsUpperTriangular M
IsUpperTriangular (matrix_negate M)
R: Ring n: nat M: Matrix R n n H: IsUpperTriangular M
IsUpperTriangular (matrix_negate M)
R: Ring n: nat M: Matrix R n n H: IsUpperTriangular M
merely
(forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry (matrix_negate M) i j = 0)
R: Ring n: nat M: Matrix R n n H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0
forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry (matrix_negate M) i j = 0
R: Ring n: nat M: Matrix R n n H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0 i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat lt_i_j: (i < j)%nat
entry (matrix_negate M) i j = 0
R: Ring n: nat M: Matrix R n n H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0 i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat lt_i_j: (i < j)%nat
- Vector.entry (Vector.entry M i) j = 0
R: Ring n: nat M: Matrix R n n H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0 i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat lt_i_j: (i < j)%nat
Vector.entry (Vector.entry M i) j = 0
by napply H.Defined.(** The negation of a lower triangular matrix is lower triangular. *)
R: Ring n: nat M: Matrix R n n IsLowerTriangular0: IsLowerTriangular M
IsLowerTriangular (matrix_negate M)
R: Ring n: nat M: Matrix R n n IsLowerTriangular0: IsLowerTriangular M
IsLowerTriangular (matrix_negate M)
R: Ring n: nat M: Matrix R n n IsLowerTriangular0: IsLowerTriangular M
byapply upper_triangular_negate.Defined.(** The product of two upper triangular matrices is upper triangular. *)
R: Ring n: nat M, N: Matrix R n n H1: IsUpperTriangular M H2: IsUpperTriangular N
IsUpperTriangular (matrix_mult M N)
R: Ring n: nat M, N: Matrix R n n H1: IsUpperTriangular M H2: IsUpperTriangular N
IsUpperTriangular (matrix_mult M N)
R: Ring n: nat M, N: Matrix R n n H1: IsUpperTriangular M H2: IsUpperTriangular N
merely
(forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry (matrix_mult M N) i j = 0)
R: Ring n: nat M, N: Matrix R n n H2: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry N i j = 0 H1: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry M i j = 0
forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry (matrix_mult M N) i j = 0
R: Ring n: nat M, N: Matrix R n n H2: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry N i j = 0 H1: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry M i j = 0 i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat lt_i_j: (i < j)%nat
entry (matrix_mult M N) i j = 0
R: Ring n: nat M, N: Matrix R n n H2: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry N i j = 0 H1: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry M i j = 0 i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat lt_i_j: (i < j)%nat
ab_sum n
(fun (k : nat) (Hk : (k < n)%nat) =>
entry M i k * entry N k j) = 0
R: Ring n: nat M, N: Matrix R n n H2: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry N i j = 0 H1: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry M i j = 0 i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat lt_i_j: (i < j)%nat
forall (k : nat) (Hk : (k < n)%nat),
entry M i k * entry N k j = mon_unit
R: Ring n: nat M, N: Matrix R n n H2: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry N i j = 0 H1: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry M i j = 0 i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat lt_i_j: (i < j)%nat k: nat Hk: (k < n)%nat
entry M i k * entry N k j = mon_unit
R: Ring n: nat M, N: Matrix R n n H2: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry N i j = 0 H1: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry M i j = 0 i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat lt_i_j: (i < j)%nat k: nat Hk: (k < n)%nat leq_k_i: (k <= i)%nat
entry M i k * entry N k j = mon_unit
R: Ring n: nat M, N: Matrix R n n H2: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry N i j = 0 H1: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry M i j = 0 i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat lt_i_j: (i < j)%nat k: nat Hk: (k < n)%nat gt_k_i: ~ (k <= i)%nat
entry M i k * entry N k j = mon_unit
R: Ring n: nat M, N: Matrix R n n H2: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry N i j = 0 H1: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry M i j = 0 i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat lt_i_j: (i < j)%nat k: nat Hk: (k < n)%nat leq_k_i: (k <= i)%nat
entry M i k * entry N k j = mon_unit
R: Ring n: nat M, N: Matrix R n n H2: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry N i j = 0 H1: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry M i j = 0 i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat lt_i_j: (i < j)%nat k: nat Hk: (k < n)%nat leq_k_i: (k <= i)%nat
entry M i k * 0 = mon_unit
R: Ring n: nat M, N: Matrix R n n H2: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry N i j = 0 H1: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry M i j = 0 i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat lt_i_j: (i < j)%nat k: nat Hk: (k < n)%nat leq_k_i: (k <= i)%nat
(k < j)%nat
R: Ring n: nat M, N: Matrix R n n H2: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry N i j = 0 H1: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry M i j = 0 i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat lt_i_j: (i < j)%nat k: nat Hk: (k < n)%nat leq_k_i: (k <= i)%nat
(k < j)%nat
rapply lt_leq_lt_trans.
R: Ring n: nat M, N: Matrix R n n H2: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry N i j = 0 H1: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry M i j = 0 i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat lt_i_j: (i < j)%nat k: nat Hk: (k < n)%nat gt_k_i: ~ (k <= i)%nat
entry M i k * entry N k j = mon_unit
R: Ring n: nat M, N: Matrix R n n H2: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry N i j = 0 H1: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry M i j = 0 i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat lt_i_j: (i < j)%nat k: nat Hk: (k < n)%nat gt_k_i: (k > i)%nat
entry M i k * entry N k j = mon_unit
R: Ring n: nat M, N: Matrix R n n H2: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry N i j = 0 H1: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry M i j = 0 i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat lt_i_j: (i < j)%nat k: nat Hk: (k < n)%nat gt_k_i: (k > i)%nat
0 * entry N k j = mon_unit
R: Ring n: nat M, N: Matrix R n n H2: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry N i j = 0 H1: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry M i j = 0 i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat lt_i_j: (i < j)%nat k: nat Hk: (k < n)%nat gt_k_i: (k > i)%nat
(i < k)%nat
R: Ring n: nat M, N: Matrix R n n H2: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry N i j = 0 H1: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
(i < j)%nat -> entry M i j = 0 i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat lt_i_j: (i < j)%nat k: nat Hk: (k < n)%nat gt_k_i: (k > i)%nat
(i < k)%nat
assumption.Defined.(** The product of two lower triangular matrices is lower triangular. *)
R: Ring n: nat M, N: Matrix R n n H1: IsLowerTriangular M H2: IsLowerTriangular N
IsLowerTriangular (matrix_mult M N)
R: Ring n: nat M, N: Matrix R n n H1: IsLowerTriangular M H2: IsLowerTriangular N
IsLowerTriangular (matrix_mult M N)
R: Ring n: nat M, N: Matrix R n n H1: IsLowerTriangular M H2: IsLowerTriangular N
IsUpperTriangular (matrix_transpose (matrix_mult M N))
R: Ring n: nat M, N: Matrix R n n H1: IsLowerTriangular M H2: IsLowerTriangular N
apply upper_triangular_diag.Defined.(** Upper triangular matrices are a subring of the ring of matrices. *)
R: Ring n: nat
Subring (matrix_ring R n)
R: Ring n: nat
Subring (matrix_ring R n)
R: Ring n: nat
forallx : matrix_ring R n,
IsHProp (IsUpperTriangular x)
R: Ring n: nat
forallxy : matrix_ring R n,
IsUpperTriangular x ->
IsUpperTriangular y -> IsUpperTriangular (x - y)
R: Ring n: nat
forallxy : matrix_ring R n,
IsUpperTriangular x ->
IsUpperTriangular y -> IsUpperTriangular (x * y)
R: Ring n: nat
IsUpperTriangular 1
R: Ring n: nat
forallx : matrix_ring R n,
IsHProp (IsUpperTriangular x)
exact _.(* These can all be found by typeclass search, but being explicit makes this faster. *)
R: Ring n: nat
forallxy : matrix_ring R n,
IsUpperTriangular x ->
IsUpperTriangular y -> IsUpperTriangular (x - y)
intros x y ? ?; exact (upper_triangular_plus x (-y)).
R: Ring n: nat
forallxy : matrix_ring R n,
IsUpperTriangular x ->
IsUpperTriangular y -> IsUpperTriangular (x * y)
exact upper_triangular_mult.
R: Ring n: nat
IsUpperTriangular 1
exact upper_triangular_identity.Defined.(** Lower triangular matrices are a subring of the ring of matrices. *)
R: Ring n: nat
Subring (matrix_ring R n)
R: Ring n: nat
Subring (matrix_ring R n)
R: Ring n: nat
forallx : matrix_ring R n,
IsHProp (IsLowerTriangular x)
R: Ring n: nat
forallxy : matrix_ring R n,
IsLowerTriangular x ->
IsLowerTriangular y -> IsLowerTriangular (x - y)
R: Ring n: nat
forallxy : matrix_ring R n,
IsLowerTriangular x ->
IsLowerTriangular y -> IsLowerTriangular (x * y)
R: Ring n: nat
IsLowerTriangular 1
R: Ring n: nat
forallx : matrix_ring R n,
IsHProp (IsLowerTriangular x)
exact _.(* These can all be found by typeclass search, but being explicit makes this faster. *)
R: Ring n: nat
forallxy : matrix_ring R n,
IsLowerTriangular x ->
IsLowerTriangular y -> IsLowerTriangular (x - y)
intros x y ? ?; exact (lower_triangular_plus x (-y)).
R: Ring n: nat
forallxy : matrix_ring R n,
IsLowerTriangular x ->
IsLowerTriangular y -> IsLowerTriangular (x * y)
exact lower_triangular_mult.
R: Ring n: nat
IsLowerTriangular 1
exact lower_triangular_identity.Defined.(** ** Symmetric Matrices *)(** A matrix is symmetric when it is equal to its transpose. *)ClassIsSymmetric {R : Ring@{i}} {n : nat} (M : Matrix@{i} R n n) : Type@{i}
:= matrix_transpose_issymmetric : matrix_transpose M = M.Arguments matrix_transpose_issymmetric {R n} M {_}.(** The zero matrix is symmetric. *)Instanceissymmetric_matrix_zero {R : Ring@{i}} {n : nat}
: IsSymmetric (matrix_zero R n n)
:= matrix_transpose_zero.(** The identity matrix is symmetric. *)Instanceissymmetric_matrix_identity {R : Ring@{i}} {n : nat}
: IsSymmetric (identity_matrix R n)
:= matrix_transpose_identity.(** The sum of two symmetric matrices is symmetric. *)
R: Ring n: nat M, N: Matrix R n n IsSymmetric0: IsSymmetric M IsSymmetric1: IsSymmetric N
IsSymmetric (matrix_plus M N)
R: Ring n: nat M, N: Matrix R n n IsSymmetric0: IsSymmetric M IsSymmetric1: IsSymmetric N
IsSymmetric (matrix_plus M N)
R: Ring n: nat M, N: Matrix R n n IsSymmetric0: IsSymmetric M IsSymmetric1: IsSymmetric N
matrix_transpose (matrix_plus M N) = matrix_plus M N
R: Ring n: nat M, N: Matrix R n n IsSymmetric0: IsSymmetric M IsSymmetric1: IsSymmetric N
matrix_plus (matrix_transpose M) (matrix_transpose N) =
matrix_plus M N
f_ap.Defined.(** The negation of a symmetric matrix is symmetric. *)
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M
IsSymmetric (matrix_negate M)
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M
IsSymmetric (matrix_negate M)
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M
matrix_transpose (matrix_negate M) = matrix_negate M
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M
matrix_negate (matrix_transpose M) = matrix_negate M
f_ap.Defined.(** A scalar multiple of a symmetric matrix is symmetric. *)
R: Ring n: nat r: R M: Matrix R n n IsSymmetric0: IsSymmetric M
IsSymmetric (matrix_lact r M)
R: Ring n: nat r: R M: Matrix R n n IsSymmetric0: IsSymmetric M
IsSymmetric (matrix_lact r M)
R: Ring n: nat r: R M: Matrix R n n IsSymmetric0: IsSymmetric M
matrix_transpose (matrix_lact r M) = matrix_lact r M
R: Ring n: nat r: R M: Matrix R n n IsSymmetric0: IsSymmetric M
matrix_lact r (matrix_transpose M) = matrix_lact r M
f_ap.Defined.(** The transpose of a symmetric matrix is symmetric. *)
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M
IsSymmetric (matrix_transpose M)
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M
IsSymmetric (matrix_transpose M)
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M
matrix_transpose (matrix_transpose M) =
matrix_transpose M
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M
M = matrix_transpose M
bysymmetry.Defined.(** A symmetric upper triangular matrix is diagonal. *)
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M H: IsUpperTriangular M
IsDiagonal M
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M H: IsUpperTriangular M
IsDiagonal M
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M H: IsUpperTriangular M
M = matrix_diag (matrix_diag_vector M)
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M H: IsUpperTriangular M
forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat),
entry M i j =
entry (matrix_diag (matrix_diag_vector M)) i j
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M H: IsUpperTriangular M i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
entry M i j =
entry (matrix_diag (matrix_diag_vector M)) i j
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M H: IsUpperTriangular M i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat
entry M i j = kronecker_delta i j * entry M i i
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0
entry M i j = kronecker_delta i j * entry M i i
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0 p: i = j
entry M i j = kronecker_delta i j * entry M i i
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0 np: i <> j
entry M i j = kronecker_delta i j * entry M i i
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0 p: i = j
entry M i j = kronecker_delta i j * entry M i i
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M i: nat Hi, Hj: (i < n)%nat H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0
entry M i i = kronecker_delta i i * entry M i i
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M i: nat Hi, Hj: (i < n)%nat H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0
entry M i i = 1 * entry M i i
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M i: nat Hi, Hj: (i < n)%nat H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0
entry M i i = entry M i i
f_ap; apply path_ishprop.
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0 np: i <> j
entry M i j = kronecker_delta i j * entry M i i
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0 np: ((i < j)%nat + (i > j)%nat)%type
entry M i j = kronecker_delta i j * entry M i i
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0 l: (i < j)%nat
entry M i j = kronecker_delta i j * entry M i i
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0 l: (i > j)%nat
entry M i j = kronecker_delta i j * entry M i i
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0 l: (i < j)%nat
entry M i j = kronecker_delta i j * entry M i i
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0 l: (i < j)%nat
entry M i j = 0 * entry M i i
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0 l: (i < j)%nat
entry M i j = 0
byrewrite H.
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0 l: (i > j)%nat
entry M i j = kronecker_delta i j * entry M i i
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0 l: (i > j)%nat
entry M i j = 0 * entry M i i
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0 l: (i > j)%nat
entry M i j = 0
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0 l: (i > j)%nat
entry (matrix_transpose M) i j = 0
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M i, j: nat Hi: (i < n)%nat Hj: (j < n)%nat H: forall (ij : nat) (Hi : (i < n)%nat)
(Hj : (j < n)%nat), (i < j)%nat -> entry M i j = 0 l: (i > j)%nat
entry M j i = 0
byrewrite H.Defined.(** A symmetric lower triangular matrix is diagonal. *)
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M IsLowerTriangular0: IsLowerTriangular M
IsDiagonal M
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M IsLowerTriangular0: IsLowerTriangular M
IsDiagonal M
R: Ring n: nat M: Matrix R n n IsSymmetric0: IsSymmetric M IsLowerTriangular0: IsLowerTriangular M
IsDiagonal (matrix_transpose M)
rapply isdiagonal_upper_triangular_issymmetric.Defined.(** Note that symmetric matrices do not form a subring (or subalgebra) but they do form a submodule of the module of matrices. *)(** ** Skew-symmetric Matrices *)(** A matrix is skew-symmetric when it is equal to the negation of its transpose. *)ClassIsSkewSymmetric {R : Ring@{i}} {n : nat} (M : Matrix@{i} R n n) : Type@{i}
:= matrix_transpose_isskewsymmetric : matrix_transpose M = matrix_negate M.Arguments matrix_transpose_isskewsymmetric {R n} M {_}.(** The zero matrix is skew-symmetric. *)
R: Ring n: nat
IsSkewSymmetric (matrix_zero R n n)
R: Ring n: nat
IsSkewSymmetric (matrix_zero R n n)
R: Ring n: nat
matrix_transpose (matrix_zero R n n) =
matrix_negate (matrix_zero R n n)
R: Ring n: nat
matrix_zero R n n = matrix_negate (matrix_zero R n n)
R: Ring n: nat
matrix_negate (matrix_zero R n n) = matrix_zero R n n
napply (rng_negate_zero (A:=matrix_ring R n)).Defined.(** The negation of a skew-symmetric matrix is skew-symmetric. *)
R: Ring n: nat M: Matrix R n n IsSkewSymmetric0: IsSkewSymmetric M
IsSkewSymmetric (matrix_negate M)
R: Ring n: nat M: Matrix R n n IsSkewSymmetric0: IsSkewSymmetric M
IsSkewSymmetric (matrix_negate M)
R: Ring n: nat M: Matrix R n n IsSkewSymmetric0: IsSkewSymmetric M
matrix_transpose (matrix_negate M) =
matrix_negate (matrix_negate M)
R: Ring n: nat M: Matrix R n n IsSkewSymmetric0: IsSkewSymmetric M
matrix_negate (matrix_transpose M) =
matrix_negate (matrix_negate M)
f_ap.Defined.(** A scalar multiple of a skew-symmetric matrix is skew-symmetric. *)
R: Ring n: nat r: R M: Matrix R n n IsSkewSymmetric0: IsSkewSymmetric M
IsSkewSymmetric (matrix_lact r M)
R: Ring n: nat r: R M: Matrix R n n IsSkewSymmetric0: IsSkewSymmetric M
IsSkewSymmetric (matrix_lact r M)
R: Ring n: nat r: R M: Matrix R n n IsSkewSymmetric0: IsSkewSymmetric M
matrix_transpose (matrix_lact r M) =
matrix_negate (matrix_lact r M)
R: Ring n: nat r: R M: Matrix R n n IsSkewSymmetric0: IsSkewSymmetric M
matrix_lact r (matrix_transpose M) =
matrix_negate (matrix_lact r M)
R: Ring n: nat r: R M: Matrix R n n IsSkewSymmetric0: IsSkewSymmetric M
matrix_lact r (matrix_transpose M) = lact r (- M)
f_ap.Defined.(** The transpose of a skew-symmetric matrix is skew-symmetric. *)
R: Ring n: nat M: Matrix R n n IsSkewSymmetric0: IsSkewSymmetric M
IsSkewSymmetric (matrix_transpose M)
R: Ring n: nat M: Matrix R n n IsSkewSymmetric0: IsSkewSymmetric M
IsSkewSymmetric (matrix_transpose M)
R: Ring n: nat M: Matrix R n n IsSkewSymmetric0: IsSkewSymmetric M
matrix_transpose (matrix_transpose M) =
matrix_negate (matrix_transpose M)
R: Ring n: nat M: Matrix R n n IsSkewSymmetric0: IsSkewSymmetric M
matrix_transpose (matrix_transpose M) =
matrix_transpose (matrix_negate M)
f_ap.Defined.(** The sum of two skew-symmetric matrices is skew-symmetric. *)
R: Ring n: nat M, N: Matrix R n n IsSkewSymmetric0: IsSkewSymmetric M IsSkewSymmetric1: IsSkewSymmetric N
IsSkewSymmetric (matrix_plus M N)
R: Ring n: nat M, N: Matrix R n n IsSkewSymmetric0: IsSkewSymmetric M IsSkewSymmetric1: IsSkewSymmetric N
IsSkewSymmetric (matrix_plus M N)
R: Ring n: nat M, N: Matrix R n n IsSkewSymmetric0: IsSkewSymmetric M IsSkewSymmetric1: IsSkewSymmetric N
matrix_transpose (matrix_plus M N) =
matrix_negate (matrix_plus M N)
R: Ring n: nat M, N: Matrix R n n IsSkewSymmetric0: IsSkewSymmetric M IsSkewSymmetric1: IsSkewSymmetric N
matrix_plus (matrix_transpose M) (matrix_transpose N) =
matrix_negate (matrix_plus M N)
R: Ring n: nat M, N: Matrix R n n IsSkewSymmetric0: IsSkewSymmetric M IsSkewSymmetric1: IsSkewSymmetric N
matrix_plus (matrix_transpose M) (matrix_transpose N) =
sg_op (inv N) (inv M)
R: Ring n: nat M, N: Matrix R n n IsSkewSymmetric0: IsSkewSymmetric M IsSkewSymmetric1: IsSkewSymmetric N
matrix_plus (matrix_transpose M) (matrix_transpose N) =
sg_op (inv M) (inv N)
f_ap.Defined.(** Skew-symmetric matrices degenerate to symmetric matrices in rings with characteristic 2. In odd characteristic the module of matrices can be decomposed into the direct sum of symmetric and skew-symmetric matrices. *)SectionMatrixCat.(** The wild category [MatrixCat R] of [R]-valued matrices. This category has natural numbers as objects and m x n matrices as the arrows between [m] and [n]. *)DefinitionMatrixCat (R : Ring) := nat.#[export] Instanceisgraph_matrixcat {R : Ring} : IsGraph (MatrixCat R)
:= {| Hom := Matrix R |}.
R: Ring
Is01Cat (MatrixCat R)
R: Ring
Is01Cat (MatrixCat R)
R: Ring
foralla : MatrixCat R, a $-> a
R: Ring
forallabc : MatrixCat R,
(b $-> c) -> (a $-> b) -> a $-> c
R: Ring
foralla : MatrixCat R, a $-> a
exact (identity_matrix R).
R: Ring
forallabc : MatrixCat R,
(b $-> c) -> (a $-> b) -> a $-> c
R: Ring l, m, n: MatrixCat R M: m $-> n N: l $-> m
l $-> n
exact (matrix_mult N M).Defined.#[export] Instanceis2graph_matrixcat {R : Ring} : Is2Graph (MatrixCat R)
:= is2graph_paths _.(** [MatrixCat R] forms a strong 1-category. *)
R: Ring
Is1Cat_Strong (MatrixCat R)
R: Ring
Is1Cat_Strong (MatrixCat R)
R: Ring
forallab : MatrixCat R, Is01Cat (a $-> b)
R: Ring
forallab : MatrixCat R, Is0Gpd (a $-> b)
R: Ring
forall (abc : MatrixCat R) (g : b $-> c),
Is0Functor (cat_postcomp a g)
R: Ring
forall (abc : MatrixCat R) (f : a $-> b),
Is0Functor (cat_precomp c f)
R: Ring
forall (abcd : MatrixCat R) (f : a $-> b)
(g : b $-> c) (h : c $-> d),
h $o g $o f = h $o (g $o f)
R: Ring
forall (abcd : MatrixCat R) (f : a $-> b)
(g : b $-> c) (h : c $-> d),
h $o (g $o f) = h $o g $o f
R: Ring
forall (ab : MatrixCat R) (f : a $-> b),
Id b $o f = f
R: Ring
forall (ab : MatrixCat R) (f : a $-> b),
f $o Id a = f
(* Most of the structure comes from typeclasses in WildCat.Paths. *)
R: Ring
forall (abcd : MatrixCat R) (f : a $-> b)
(g : b $-> c) (h : c $-> d),
h $o g $o f = h $o (g $o f)
R: Ring
forall (abcd : MatrixCat R) (f : a $-> b)
(g : b $-> c) (h : c $-> d),
h $o (g $o f) = h $o g $o f
R: Ring
forall (ab : MatrixCat R) (f : a $-> b),
Id b $o f = f
R: Ring
forall (ab : MatrixCat R) (f : a $-> b),
f $o Id a = f
R: Ring
forall (abcd : MatrixCat R) (f : a $-> b)
(g : b $-> c) (h : c $-> d),
h $o g $o f = h $o (g $o f)
apply (associative_matrix_mult R).
R: Ring
forall (abcd : MatrixCat R) (f : a $-> b)
(g : b $-> c) (h : c $-> d),
h $o (g $o f) = h $o g $o f
R: Ring k, l, m, n: MatrixCat R M: k $-> l N: l $-> m P: m $-> n
P $o (N $o M) = P $o N $o M
R: Ring k, l, m, n: MatrixCat R M: k $-> l N: l $-> m P: m $-> n
P $o N $o M = P $o (N $o M)
apply (associative_matrix_mult R).
R: Ring
forall (ab : MatrixCat R) (f : a $-> b),
Id b $o f = f
apply right_identity_matrix_mult.
R: Ring
forall (ab : MatrixCat R) (f : a $-> b),
f $o Id a = f
apply left_identity_matrix_mult.Defined.(** TODO: Define [HasEquivs] for [MatrixCat]. *)EndMatrixCat.