Zulip Chat Archive

Stream: Is there code for X?

Topic: Rank of Matrix Multiplied by an Invertible Matrix


MohanadAhmed (Jun 06 2023 at 10:11):

Let AA and BB be two matrices, with A being invertible. The rank of BB is not affected by pre or post multiplication by AA. Is there code for this in mathlib? (or Mathlib4)

invertibleA    rank(AB)=rank(BA)=rank(B)\text{invertible} A \implies \text{rank}({AB}) = \text{rank}({BA}) = \text{rank}({B})

Eric Wieser (Jun 06 2023 at 10:15):

I don't think we have it, but it should follow without too much work either from docs#matrix.rank_mul_le_left, or by proving it about linear_equiv first then using matrix.to_lin

MohanadAhmed (Jun 06 2023 at 10:22):

I have a proof that seems like a lot more work than what you suggest. Any tips?

import data.complex.basic
import linear_algebra.matrix.nonsingular_inverse
import data.matrix.rank

variables {m n R: Type*}
variables [fintype m][fintype n][decidable_eq m][decidable_eq n]
variables [field R][decidable_eq R]

open matrix
open_locale matrix

lemma rank_mul_unit (A: matrix n n R)(B: matrix m n R) (hA: is_unit A.det):
  (BA).rank = B.rank := begin
  rw [matrix.rank, mul_vec_lin_mul, linear_map.range_comp_of_range_eq_top,  matrix.rank],
  rw linear_map.range_eq_top,
  intro x,
  use ((A⁻¹).mul_vec_lin ) x,
  rwa [mul_vec_lin_apply, mul_vec_lin_apply, mul_vec_mul_vec, mul_nonsing_inv, one_mul_vec],
end

lemma rank_mul_unit' (A: matrix m m R)(B: matrix m n R) (hA: is_unit A.det):
  (AB).rank = B.rank := begin
  have h: linear_map.ker ((AB).mul_vec_lin) = linear_map.ker (B.mul_vec_lin) ,
  { rw [mul_vec_lin_mul, linear_map.ker_comp_of_ker_eq_bot],
    rw linear_map.ker_eq_bot,
    simp_rw [function.injective, mul_vec_lin_apply],
    intros x y h,
    replace h := congr_arg (λ x, matrix.mul_vec (A⁻¹) x)  h,
    simp_rw [mul_vec_mul_vec, nonsing_inv_mul A hA, one_mul_vec] at h,
    exact h, },
  have hB := linear_map.finrank_range_add_finrank_ker ((B).mul_vec_lin),
  rw [ linear_map.finrank_range_add_finrank_ker ((AB).mul_vec_lin), h, add_left_inj] at hB,
  rw [matrix.rank, matrix.rank, hB],
end

Eric Wieser (Jun 06 2023 at 10:24):

Apply matrix.rank_mul_le_left twice and use antisymmetry?

MohanadAhmed (Jun 06 2023 at 11:29):

Related Question:
Islinear_ordered_field needed in rank_transpose, rank_transpose_mul_self?

Eric Wieser (Jun 06 2023 at 11:31):

No and maybe

Eric Wieser (Jun 06 2023 at 11:31):

There's another thread with a better proof of rank_transpose

Eric Wieser (Jun 06 2023 at 11:32):

rank_transpose_self is going to need @Jireh Loreaux's refactor of star_ordered_ring

Damiano Testa (Jun 06 2023 at 11:42):

MohanadAhmed said:

Related Question:
Islinear_ordered_field needed in rank_transpose, rank_transpose_mul_self?

Over C\mathbb{C}, the matrix (1ii1)\begin{pmatrix}1 & i \cr i & -1 \end{pmatrix} is symmetric and its square is zero. The rank goes from 1 to 0, so some assumption on the field is needed.

Damiano Testa (Jun 06 2023 at 14:37):

I think that Eric is referring to this proof.

With rank_transpose' from the previous link, you can prove rank_mul_unit' as follows:

lemma rank_mul_unit' (A: matrix m m R) (B: matrix m n R) (hA: is_unit A.det) :
  (AB).rank = B.rank :=
begin
  rw [ matrix.rank_transpose' B,  matrix.rank_transpose' (A  B), transpose_mul],
  apply rank_mul_unit,
  rwa det_transpose,
end

MohanadAhmed (Jun 07 2023 at 13:53):

Eric Wieser said:

rank_transpose_self is going to need Jireh Loreaux's refactor of star_ordered_ring

For Future Ref:


Last updated: Dec 20 2023 at 11:08 UTC