@@ -25,6 +25,8 @@ def matrix (m : Type u) (n : Type u') [fintype m] [fintype n] (α : Type v) : Ty
25
25
m → n → α
26
26
27
27
variables {l m n o : Type *} [fintype l] [fintype m] [fintype n] [fintype o]
28
+ variables {m' : o → Type *} [∀ i, fintype (m' i)]
29
+ variables {n' : o → Type *} [∀ i, fintype (n' i)]
28
30
variables {α : Type v}
29
31
30
32
namespace matrix
@@ -1123,9 +1125,12 @@ section has_zero
1123
1125
1124
1126
variables [has_zero α]
1125
1127
1126
- /-- `matrix.block_diagonal M` turns `M : o → matrix m n α'` into a
1127
- `m × o`-by`n × o` block matrix which has the entries of `M` along the diagonal
1128
- and zero elsewhere. -/
1128
+ /-- `matrix.block_diagonal M` turns a homogenously-indexed collection of matrices
1129
+ `M : o → matrix m n α'` into a `m × o`-by-`n × o` block matrix which has the entries of `M` along
1130
+ the diagonal and zero elsewhere.
1131
+
1132
+ See also `matrix.block_diagonal'` if the matrices may not have the same size everywhere.
1133
+ -/
1129
1134
def block_diagonal : matrix (m × o) (n × o) α
1130
1135
| ⟨i, k⟩ ⟨j, k'⟩ := if k = k' then M k i j else 0
1131
1136
@@ -1143,7 +1148,7 @@ lemma block_diagonal_apply_ne (i j) {k k'} (h : k ≠ k') :
1143
1148
if_neg h
1144
1149
1145
1150
@[simp] lemma block_diagonal_transpose :
1146
- (block_diagonal M)ᵀ = ( block_diagonal (λ k, (M k)ᵀ) ) :=
1151
+ (block_diagonal M)ᵀ = block_diagonal (λ k, (M k)ᵀ) :=
1147
1152
begin
1148
1153
ext,
1149
1154
simp only [transpose_apply, block_diagonal_apply, eq_comm],
@@ -1157,16 +1162,16 @@ end
1157
1162
by { ext, simp [block_diagonal_apply] }
1158
1163
1159
1164
@[simp] lemma block_diagonal_diagonal [decidable_eq m] (d : o → m → α) :
1160
- ( block_diagonal (λ k, diagonal (d k) )) = diagonal (λ ik, d ik.2 ik.1 ) :=
1165
+ block_diagonal (λ k, diagonal (d k)) = diagonal (λ ik, d ik.2 ik.1 ) :=
1161
1166
begin
1162
1167
ext ⟨i, k⟩ ⟨j, k'⟩,
1163
1168
simp only [block_diagonal_apply, diagonal],
1164
1169
split_ifs; finish
1165
1170
end
1166
1171
1167
1172
@[simp] lemma block_diagonal_one [decidable_eq m] [has_one α] :
1168
- ( block_diagonal (1 : o → matrix m m α) ) = 1 :=
1169
- show ( block_diagonal (λ (_ : o), diagonal (λ (_ : m), (1 : α) ))) = diagonal (λ _, 1 ),
1173
+ block_diagonal (1 : o → matrix m m α) = 1 :=
1174
+ show block_diagonal (λ (_ : o), diagonal (λ (_ : m), (1 : α))) = diagonal (λ _, 1 ),
1170
1175
by rw [block_diagonal_diagonal]
1171
1176
1172
1177
end has_zero
@@ -1191,8 +1196,8 @@ end
1191
1196
block_diagonal (M - N) = block_diagonal M - block_diagonal N :=
1192
1197
by simp [sub_eq_add_neg]
1193
1198
1194
- @[simp] lemma block_diagonal_mul {p : Type *} [fintype p] [semiring α]
1195
- (N : o → matrix n p α) : block_diagonal (λ k, M k ⬝ N k) = block_diagonal M ⬝ block_diagonal N :=
1199
+ @[simp] lemma block_diagonal_mul {p : Type *} [fintype p] [semiring α] (N : o → matrix n p α) :
1200
+ block_diagonal (λ k, M k ⬝ N k) = block_diagonal M ⬝ block_diagonal N :=
1196
1201
begin
1197
1202
ext ⟨i, k⟩ ⟨j, k'⟩,
1198
1203
simp only [block_diagonal_apply, mul_apply, ← finset.univ_product_univ, finset.sum_product],
@@ -1205,6 +1210,114 @@ by { ext, simp only [block_diagonal_apply, pi.smul_apply, smul_apply], split_ifs
1205
1210
1206
1211
end block_diagonal
1207
1212
1213
+ section block_diagonal'
1214
+
1215
+ variables (M N : Π i, matrix (m' i) (n' i) α) [decidable_eq o]
1216
+
1217
+ section has_zero
1218
+
1219
+ variables [has_zero α]
1220
+
1221
+ /-- `matrix.block_diagonal' M` turns `M : Π i, matrix (m i) (n i) α` into a
1222
+ `Σ i, m i`-by-`Σ i, n i` block matrix which has the entries of `M` along the diagonal
1223
+ and zero elsewhere.
1224
+
1225
+ This is the dependently-typed version of `matrix.block_diagonal`. -/
1226
+ def block_diagonal' : matrix (Σ i, m' i) (Σ i, n' i) α
1227
+ | ⟨k, i⟩ ⟨k', j⟩ := if h : k = k' then M k i (cast (congr_arg n' h.symm) j) else 0
1228
+
1229
+ lemma block_diagonal'_eq_block_diagonal (M : o → matrix m n α) {k k'} (i j) :
1230
+ block_diagonal M (i, k) (j, k') = block_diagonal' M ⟨k, i⟩ ⟨k', j⟩ :=
1231
+ rfl
1232
+
1233
+ lemma block_diagonal'_minor_eq_block_diagonal (M : o → matrix m n α) :
1234
+ (block_diagonal' M).minor (prod.to_sigma ∘ prod.swap) (prod.to_sigma ∘ prod.swap) =
1235
+ block_diagonal M :=
1236
+ matrix.ext $ λ ⟨k, i⟩ ⟨k', j⟩, rfl
1237
+
1238
+ lemma block_diagonal'_apply (ik jk) :
1239
+ block_diagonal' M ik jk = if h : ik.1 = jk.1 then
1240
+ M ik.1 ik.2 (cast (congr_arg n' h.symm) jk.2 ) else 0 :=
1241
+ by { cases ik, cases jk, refl }
1242
+
1243
+ @[simp]
1244
+ lemma block_diagonal'_apply_eq (k i j) :
1245
+ block_diagonal' M ⟨k, i⟩ ⟨k, j⟩ = M k i j :=
1246
+ dif_pos rfl
1247
+
1248
+ lemma block_diagonal'_apply_ne {k k'} (i j) (h : k ≠ k') :
1249
+ block_diagonal' M ⟨k, i⟩ ⟨k', j⟩ = 0 :=
1250
+ dif_neg h
1251
+
1252
+ @[simp] lemma block_diagonal'_transpose :
1253
+ (block_diagonal' M)ᵀ = block_diagonal' (λ k, (M k)ᵀ) :=
1254
+ begin
1255
+ ext ⟨ii, ix⟩ ⟨ji, jx⟩,
1256
+ simp only [transpose_apply, block_diagonal'_apply, eq_comm],
1257
+ dsimp only,
1258
+ split_ifs with h₁ h₂ h₂,
1259
+ { subst h₁, refl, },
1260
+ { exact (h₂ h₁.symm).elim },
1261
+ { exact (h₁ h₂.symm).elim },
1262
+ { refl }
1263
+ end
1264
+
1265
+ @[simp] lemma block_diagonal'_zero :
1266
+ block_diagonal' (0 : Π i, matrix (m' i) (n' i) α) = 0 :=
1267
+ by { ext, simp [block_diagonal'_apply] }
1268
+
1269
+ @[simp] lemma block_diagonal'_diagonal [∀ i, decidable_eq (m' i)] (d : Π i, m' i → α) :
1270
+ block_diagonal' (λ k, diagonal (d k)) = diagonal (λ ik, d ik.1 ik.2 ) :=
1271
+ begin
1272
+ ext ⟨i, k⟩ ⟨j, k'⟩,
1273
+ simp only [block_diagonal'_apply, diagonal],
1274
+ split_ifs; finish
1275
+ end
1276
+
1277
+ @[simp] lemma block_diagonal'_one [∀ i, decidable_eq (m' i)] [has_one α] :
1278
+ block_diagonal' (1 : Π i, matrix (m' i) (m' i) α) = 1 :=
1279
+ show block_diagonal' (λ (i : o), diagonal (λ (_ : m' i), (1 : α))) = diagonal (λ _, 1 ),
1280
+ by rw [block_diagonal'_diagonal]
1281
+
1282
+ end has_zero
1283
+
1284
+ @[simp] lemma block_diagonal'_add [add_monoid α] :
1285
+ block_diagonal' (M + N) = block_diagonal' M + block_diagonal' N :=
1286
+ begin
1287
+ ext,
1288
+ simp only [block_diagonal'_apply, add_apply],
1289
+ split_ifs; simp
1290
+ end
1291
+
1292
+ @[simp] lemma block_diagonal'_neg [add_group α] :
1293
+ block_diagonal' (-M) = - block_diagonal' M :=
1294
+ begin
1295
+ ext,
1296
+ simp only [block_diagonal'_apply, neg_apply],
1297
+ split_ifs; simp
1298
+ end
1299
+
1300
+ @[simp] lemma block_diagonal'_sub [add_group α] :
1301
+ block_diagonal' (M - N) = block_diagonal' M - block_diagonal' N :=
1302
+ by simp [sub_eq_add_neg]
1303
+
1304
+ @[simp] lemma block_diagonal'_mul {p : o → Type *} [Π i, fintype (p i)] [semiring α]
1305
+ (N : Π i, matrix (n' i) (p i) α) :
1306
+ block_diagonal' (λ k, M k ⬝ N k) = block_diagonal' M ⬝ block_diagonal' N :=
1307
+ begin
1308
+ ext ⟨k, i⟩ ⟨k', j⟩,
1309
+ simp only [block_diagonal'_apply, mul_apply, ← finset.univ_sigma_univ, finset.sum_sigma],
1310
+ rw fintype.sum_eq_single k,
1311
+ { split_ifs; simp },
1312
+ { intros j' hj', exact finset.sum_eq_zero (λ _ _, by rw [dif_neg hj'.symm, zero_mul]) },
1313
+ end
1314
+
1315
+ @[simp] lemma block_diagonal'_smul {R : Type *} [semiring R] [add_comm_monoid α] [semimodule R α]
1316
+ (x : R) : block_diagonal' (x • M) = x • block_diagonal' M :=
1317
+ by { ext, simp only [block_diagonal'_apply, pi.smul_apply, smul_apply], split_ifs; simp }
1318
+
1319
+ end block_diagonal'
1320
+
1208
1321
end matrix
1209
1322
1210
1323
namespace ring_hom
0 commit comments