Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 8535b76

Browse files
committed
feat(linear_algebra/matrix/rank): generalize to rings (#18748)
This addresses a TODO comment. To achieve this we generalize `submodule.finrank_le`, `submodule.finrank_quotient_le`, and `finrank_le_finrank_of_injective` from vector spaces to free modules, and add a new lemma `linear_map.finrank_range_le`.
1 parent 2efd242 commit 8535b76

File tree

4 files changed

+77
-47
lines changed

4 files changed

+77
-47
lines changed

src/data/matrix/rank.lean

Lines changed: 39 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ This definition does not depend on the choice of basis, see `matrix.rank_eq_finr
2020
## TODO
2121
2222
* Show that `matrix.rank` is equal to the row-rank and column-rank
23-
* Generalize away from fields
2423
2524
-/
2625

@@ -30,77 +29,88 @@ namespace matrix
3029

3130
open finite_dimensional
3231

33-
variables {m n o K : Type*} [m_fin : fintype m] [fintype n] [fintype o]
34-
variables [decidable_eq n] [decidable_eq o] [field K]
35-
variables (A : matrix m n K)
32+
variables {m n o R : Type*} [m_fin : fintype m] [fintype n] [fintype o]
33+
variables [decidable_eq n] [decidable_eq o] [comm_ring R]
3634

3735
/-- The rank of a matrix is the rank of its image. -/
38-
noncomputable def rank : ℕ := finrank K A.to_lin'.range
36+
noncomputable def rank (A : matrix m n R) : ℕ := finrank R A.to_lin'.range
3937

40-
@[simp] lemma rank_one : rank (1 : matrix n n K) = fintype.card n :=
38+
@[simp] lemma rank_one [strong_rank_condition R] : rank (1 : matrix n n R) = fintype.card n :=
4139
by rw [rank, to_lin'_one, linear_map.range_id, finrank_top, finrank_pi]
4240

43-
@[simp] lemma rank_zero : rank (0 : matrix n n K) = 0 :=
41+
@[simp] lemma rank_zero [nontrivial R] : rank (0 : matrix m n R) = 0 :=
4442
by rw [rank, linear_equiv.map_zero, linear_map.range_zero, finrank_bot]
4543

46-
lemma rank_le_card_width : A.rank ≤ fintype.card n :=
44+
lemma rank_le_card_width [strong_rank_condition R] (A : matrix m n R) : A.rank ≤ fintype.card n :=
4745
begin
48-
convert le_of_add_le_left (A.to_lin'.finrank_range_add_finrank_ker).le,
49-
exact (finrank_pi K).symm,
46+
haveI : module.finite R (n → R) := module.finite.pi,
47+
haveI : module.free R (n → R) := module.free.pi _ _,
48+
exact A.to_lin'.finrank_range_le.trans_eq (finrank_pi _)
5049
end
5150

52-
lemma rank_le_width {m n : ℕ} (A : matrix (fin m) (fin n) K) : A.rank ≤ n :=
51+
lemma rank_le_width [strong_rank_condition R] {m n : ℕ} (A : matrix (fin m) (fin n) R) :
52+
A.rank ≤ n :=
5353
A.rank_le_card_width.trans $ (fintype.card_fin n).le
5454

55-
lemma rank_mul_le (B : matrix n o K) : (A ⬝ B).rank ≤ A.rank :=
55+
lemma rank_mul_le [strong_rank_condition R] (A : matrix m n R) (B : matrix n o R) :
56+
(A ⬝ B).rank ≤ A.rank :=
5657
begin
57-
refine linear_map.finrank_le_finrank_of_injective (submodule.of_le_injective _),
58-
rw [to_lin'_mul],
59-
exact linear_map.range_comp_le_range _ _,
58+
rw [rank, rank, to_lin'_mul],
59+
refine cardinal.to_nat_le_of_le_of_lt_aleph_0 _ (linear_map.rank_comp_le1 _ _),
60+
rw [←cardinal.lift_lt_aleph_0],
61+
have := lift_rank_range_le A.to_lin',
62+
rw [rank_fun', cardinal.lift_nat_cast] at this,
63+
exact this.trans_lt (cardinal.nat_lt_aleph_0 (fintype.card n)),
6064
end
6165

62-
lemma rank_unit (A : (matrix n n K)ˣ) :
63-
(A : matrix n n K).rank = fintype.card n :=
66+
lemma rank_unit [strong_rank_condition R] (A : (matrix n n R)ˣ) :
67+
(A : matrix n n R).rank = fintype.card n :=
6468
begin
6569
refine le_antisymm (rank_le_card_width A) _,
66-
have := rank_mul_le (A : matrix n n K) (↑A⁻¹ : matrix n n K),
70+
have := rank_mul_le (A : matrix n n R) (↑A⁻¹ : matrix n n R),
6771
rwa [← mul_eq_mul, ← units.coe_mul, mul_inv_self, units.coe_one, rank_one] at this,
6872
end
6973

70-
lemma rank_of_is_unit (A : matrix n n K) (h : is_unit A) :
74+
lemma rank_of_is_unit [strong_rank_condition R] (A : matrix n n R) (h : is_unit A) :
7175
A.rank = fintype.card n :=
7276
by { obtain ⟨A, rfl⟩ := h, exact rank_unit A }
7377

7478
include m_fin
7579

7680
lemma rank_eq_finrank_range_to_lin
7781
{M₁ M₂ : Type*} [add_comm_group M₁] [add_comm_group M₂]
78-
[module K M₁] [module K M₂] (v₁ : basis m K M₁) (v₂ : basis n K M₂) :
79-
A.rank = finrank K (to_lin v₂ v₁ A).range :=
82+
[module R M₁] [module R M₂] (A : matrix m n R) (v₁ : basis m R M₁) (v₂ : basis n R M₂) :
83+
A.rank = finrank R (to_lin v₂ v₁ A).range :=
8084
begin
81-
let e₁ := (pi.basis_fun K m).equiv v₁ (equiv.refl _),
82-
let e₂ := (pi.basis_fun K n).equiv v₂ (equiv.refl _),
83-
have range_e₂ : (e₂ : (n → K) →ₗ[K] M₂).range = ⊤,
85+
let e₁ := (pi.basis_fun R m).equiv v₁ (equiv.refl _),
86+
let e₂ := (pi.basis_fun R n).equiv v₂ (equiv.refl _),
87+
have range_e₂ : (e₂ : (n → R) →ₗ[R] M₂).range = ⊤,
8488
{ rw linear_map.range_eq_top, exact e₂.surjective },
8589
refine linear_equiv.finrank_eq (e₁.of_submodules _ _ _),
8690
rw [← linear_map.range_comp, ← linear_map.range_comp_of_range_eq_top (to_lin v₂ v₁ A) range_e₂],
8791
congr' 1,
8892
apply linear_map.pi_ext', rintro i, apply linear_map.ext_ring,
89-
have aux₁ := to_lin_self (pi.basis_fun K n) (pi.basis_fun K m) A i,
90-
have aux₂ := basis.equiv_apply (pi.basis_fun K n) i v₂,
93+
have aux₁ := to_lin_self (pi.basis_fun R n) (pi.basis_fun R m) A i,
94+
have aux₂ := basis.equiv_apply (pi.basis_fun R n) i v₂,
9195
rw [to_lin_eq_to_lin'] at aux₁,
9296
rw [pi.basis_fun_apply, linear_map.coe_std_basis] at aux₁ aux₂,
9397
simp only [linear_map.comp_apply, e₁, e₂, linear_equiv.coe_coe, equiv.refl_apply, aux₁, aux₂,
9498
linear_map.coe_single, to_lin_self, linear_equiv.map_sum, linear_equiv.map_smul,
9599
basis.equiv_apply],
96100
end
97101

98-
lemma rank_le_card_height : A.rank ≤ fintype.card m :=
99-
(submodule.finrank_le _).trans (finrank_pi K).le
102+
lemma rank_le_card_height [strong_rank_condition R] (A : matrix m n R) :
103+
A.rank ≤ fintype.card m :=
104+
begin
105+
haveI : module.finite R (m → R) := module.finite.pi,
106+
haveI : module.free R (m → R) := module.free.pi _ _,
107+
exact (submodule.finrank_le _).trans (finrank_pi R).le
108+
end
100109

101110
omit m_fin
102111

103-
lemma rank_le_height {m n : ℕ} (A : matrix (fin m) (fin n) K) : A.rank ≤ m :=
112+
lemma rank_le_height [strong_rank_condition R] {m n : ℕ} (A : matrix (fin m) (fin n) R) :
113+
A.rank ≤ m :=
104114
A.rank_le_card_height.trans $ (fintype.card_fin m).le
105115

106116
end matrix

src/linear_algebra/finite_dimensional.lean

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -696,17 +696,6 @@ begin
696696
exact submodule.finite_dimensional_finset_sup _ _,
697697
end
698698

699-
/-- The dimension of a submodule is bounded by the dimension of the ambient space. -/
700-
lemma finrank_le [finite_dimensional K V] (s : submodule K V) : finrank K s ≤ finrank K V :=
701-
by simpa only [cardinal.nat_cast_le, ←finrank_eq_rank] using
702-
s.subtype.rank_le_of_injective (injective_subtype s)
703-
704-
/-- The dimension of a quotient is bounded by the dimension of the ambient space. -/
705-
lemma finrank_quotient_le [finite_dimensional K V] (s : submodule K V) :
706-
finrank K (V ⧸ s) ≤ finrank K V :=
707-
by simpa only [cardinal.nat_cast_le, ←finrank_eq_rank] using
708-
(mkq s).rank_le_of_surjective (surjective_quot_mk _)
709-
710699
/-- In a finite-dimensional vector space, the dimensions of a submodule and of the corresponding
711700
quotient add up to the dimension of the space. -/
712701
theorem finrank_quotient_add_finrank [finite_dimensional K V] (s : submodule K V) :
@@ -1014,13 +1003,6 @@ lemma ker_eq_bot_iff_range_eq_top_of_finrank_eq_finrank [finite_dimensional K V]
10141003
f.ker = ⊥ ↔ f.range = ⊤ :=
10151004
by rw [range_eq_top, ker_eq_bot, injective_iff_surjective_of_finrank_eq_finrank H]
10161005

1017-
theorem finrank_le_finrank_of_injective [finite_dimensional K V] [finite_dimensional K V₂]
1018-
{f : V →ₗ[K] V₂} (hf : function.injective f) : finrank K V ≤ finrank K V₂ :=
1019-
calc finrank K V
1020-
= finrank K f.range + finrank K f.ker : (finrank_range_add_finrank_ker f).symm
1021-
... = finrank K f.range : by rw [ker_eq_bot.2 hf, finrank_bot, add_zero]
1022-
... ≤ finrank K V₂ : submodule.finrank_le _
1023-
10241006
/-- Given a linear map `f` between two vector spaces with the same dimension, if
10251007
`ker f = ⊥` then `linear_equiv_of_injective` is the induced isomorphism
10261008
between the two vector spaces. -/

src/linear_algebra/finrank.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ begin
8585
exact n.zero_le },
8686
end
8787

88+
lemma finrank_le_finrank_of_rank_le_rank
89+
(h : lift.{v'} (module.rank K V) ≤ cardinal.lift.{v} (module.rank K V₂))
90+
(h' : module.rank K V₂ < ℵ₀) :
91+
finrank K V ≤ finrank K V₂ :=
92+
by simpa only [to_nat_lift] using to_nat_le_of_le_of_lt_aleph_0 (lift_lt_aleph_0.mpr h') h
93+
8894
section
8995
variables [nontrivial K] [no_zero_smul_divisors K V]
9096

src/linear_algebra/free_module/finite/rank.lean

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,35 @@ by { simp [finrank] }
111111
end comm_ring
112112

113113
end finite_dimensional
114+
115+
section
116+
open finite_dimensional
117+
118+
variables {R M N}
119+
variables [ring R] [strong_rank_condition R]
120+
variables [add_comm_group M] [module R M]
121+
variables [add_comm_group N] [module R N]
122+
123+
lemma linear_map.finrank_le_finrank_of_injective
124+
[module.free R N] [module.finite R N] {f : M →ₗ[R] N} (hf : function.injective f) :
125+
finrank R M ≤ finrank R N :=
126+
finrank_le_finrank_of_rank_le_rank
127+
(linear_map.lift_rank_le_of_injective _ hf) (rank_lt_aleph_0 _ _)
128+
129+
lemma linear_map.finrank_range_le [module.free R M] [module.finite R M] (f : M →ₗ[R] N) :
130+
finrank R f.range ≤ finrank R M :=
131+
finrank_le_finrank_of_rank_le_rank (lift_rank_range_le f) (rank_lt_aleph_0 _ _)
132+
133+
/-- The dimension of a submodule is bounded by the dimension of the ambient space. -/
134+
lemma submodule.finrank_le [module.free R M] [module.finite R M] (s : submodule R M) :
135+
finrank R s ≤ finrank R M :=
136+
by simpa only [cardinal.to_nat_lift] using to_nat_le_of_le_of_lt_aleph_0
137+
(rank_lt_aleph_0 _ _) (rank_submodule_le s)
138+
139+
/-- The dimension of a quotient is bounded by the dimension of the ambient space. -/
140+
lemma submodule.finrank_quotient_le [module.free R M] [module.finite R M] (s : submodule R M) :
141+
finrank R (M ⧸ s) ≤ finrank R M :=
142+
by simpa only [cardinal.to_nat_lift] using to_nat_le_of_le_of_lt_aleph_0
143+
(rank_lt_aleph_0 _ _) ((submodule.mkq s).rank_le_of_surjective (surjective_quot_mk _))
144+
145+
end

0 commit comments

Comments
 (0)