Zulip Chat Archive
Stream: new members
Topic: Simp and matrix multiplication
Yakov Pechersky (Jun 17 2020 at 01:57):
I've been struggling to prove that a matrix multiplication does not commute. My ite
matrix definitions kept simp
lifying wrong. I think I figured out that there is an issue with what simp
does to matrix multiplication. It relies on pi.mul_apply
when it doesn't make sense in the context. Seems to also depend on whether *
or •
is used as the operation. Here is a mwe comparing the different simp
results depending on the precise statement to be proved:
import data.real.basic
import data.matrix.notation
import linear_algebra.matrix
example : ∃ (S : matrix (fin 2) (fin 2) ℝ) (T : matrix (fin 2) (fin 2) ℝ),
S * T ≠ T * S :=
begin
set X := (![![1, 0], ![0, 0]] : matrix (fin 2) (fin 2) ℝ),
set Y := (![![0, 1], ![0, 0]] : matrix (fin 2) (fin 2) ℝ),
have : X * Y ≠ Y * X,
{ have : (X • Y) (0 : fin 2) (0 : fin 2) ≠ (Y • X) (0 : fin 2) (0 : fin 2),
intros hx,
simp [matrix.mul_eq_mul] at hx, -- hx : (X * Y) 0 0 = (Y * X) 0 0
sorry,
-- the following example only works if linear_algebra.matrix is imported
have : (X • Y) (0 : fin 2) (0 : fin 2) ≠ (Y • X) (0 : fin 2) (0 : fin 2),
intros hx, -- we can try squeeze_simp, which suggests:
simp only [algebra.id.smul_eq_mul] at hx, -- hx : (X * Y) 0 0 = (Y * X) 0 0
sorry,
have : (X * Y) (0 : fin 2) (0 : fin 2) ≠ (Y * X) (0 : fin 2) (0 : fin 2),
intros hx, -- we can try squeeze_simp, which suggests instead
simp only [pi.mul_apply] at hx, -- hx : X 0 0 * Y 0 0 = Y 0 0 * X 0 0
sorry,
have : (X * Y) (0 : fin 2) (0 : fin 2) ≠ (Y * X) (0 : fin 2) (0 : fin 2),
intros hx, -- we can try simp, which uses pi.mul_apply
simp at hx, -- hx : X 0 0 * Y 0 0 = Y 0 0 * X 0 0
sorry,
},
sorry,
end
Yakov Pechersky (Jun 17 2020 at 02:25):
Even dsimp [matrix.mul]
splits is into a X 0 1 * Y 0 1
.
Yakov Pechersky (Jun 17 2020 at 02:30):
Is this an issue of a difference between \bu
and \cdot
?
Yakov Pechersky (Jun 17 2020 at 02:31):
I can't imagine that it is, since the latter two examples use *
directly.
Yakov Pechersky (Jun 17 2020 at 02:37):
norm_num
also expands it into a X 0 1 * Y 0 1
Yakov Pechersky (Jun 17 2020 at 02:47):
But for some reason, specifying matrix.mul
works:
have : matrix.mul X Y (0 : fin 2) (1 : fin 2) ≠ matrix.mul Y X (0 : fin 2) (1 : fin 2),
intros hx, -- specifying matrix.mul works
norm_num at hx -- solved
Yakov Pechersky (Jun 17 2020 at 02:48):
And on the top level, using *
works fine too.
import data.real.basic
import data.matrix.notation
example : ∃ (S : matrix (fin 2) (fin 2) ℝ) (T : matrix (fin 2) (fin 2) ℝ),
S * T ≠ T * S :=
begin
set X := (![![1, 0], ![0, 0]] : matrix (fin 2) (fin 2) ℝ),
set Y := (![![0, 1], ![0, 0]] : matrix (fin 2) (fin 2) ℝ),
use [X, Y],
intros h,
rw <-matrix.ext_iff at h,
specialize h 0 1,
norm_num at h,
exact h,
end
Johan Commelin (Jun 17 2020 at 04:07):
It seems that matrix.ext_iff
is stated in the "wrong" direction compared to the rest of the library.
Scott Morrison (Jun 17 2020 at 06:51):
You can also just use congr_fun
, rather than going via matrix.ext_iff
and specialize
:
import data.real.basic
import data.matrix.notation
variables {R : Type*} [ring R] [nonzero R]
example : ∃ (S : matrix (fin 2) (fin 2) R) (T : matrix (fin 2) (fin 2) R),
S * T ≠ T * S :=
begin
use [![![1, 0], ![0, 0]], ![![0, 1], ![0, 0]]],
intro h,
simpa using congr_fun (congr_fun h 0) 1,
end
Anne Baanen (Jun 17 2020 at 08:17):
Hmm, so simp
lemmas are stated in terms of matrix.mul
instead of *
, but somehow matrix.mul_eq_mul
doesn't fire to turn the *
into matrix.mul
Anne Baanen (Jun 17 2020 at 08:26):
Aha, (X * Y) i j
gets simplified to X i j * Y i j
, because X : fin 2 → fin 2 → ℝ
instead of X : matrix (fin 2) (fin 2) ℝ
, so it picks up the pointwise multiplication instance.
Anne Baanen (Jun 17 2020 at 08:29):
But giving explicit types doesn't work:
set X : matrix (fin 2) (fin 2) ℝ := ![![1, 0], ![0, 0]],
set Y : matrix (fin 2) (fin 2) ℝ := ![![0, 1], ![0, 0]],
gives a tactic state:
X : fin 1.succ → fin 2 → ℝ := ![![1, 0], ![0, 0]],
Y : fin 1.succ → fin 2 → ℝ := ![![0, 1], ![0, 0]]
⊢ ∃ (S T : matrix (fin 2) (fin 2) ℝ), S * T ≠ T * S
Anne Baanen (Jun 17 2020 at 08:38):
This seems like a bug in the set
tactic, because let
results in matrix (fin 2) (fin 2) ℝ
, after which simp
is able to reduce hx
to false
, what we want.
Anne Baanen (Jun 17 2020 at 08:41):
Weirdly, change matrix (fin 2) (fin 2) ℝ at X
fails:
match failed
state:
Y : fin 1.succ → fin 2 → ℝ := ![![0, 1], ![0, 0]]
⊢ let X : fin 1.succ → fin 2 → ℝ := ![![1, 0], ![0, 0]]
in ∃ (S T : matrix (fin 2) (fin 2) ℝ), S * T ≠ T * S
Bryan Gin-ge Chen (Jun 18 2020 at 18:48):
Anne Baanen said:
This seems like a bug in the
set
tactic, becauselet
results inmatrix (fin 2) (fin 2) ℝ
, after whichsimp
is able to reducehx
tofalse
, what we want.
Do you mind creating a tracking issue for this? I don't want this to get lost...
Anne Baanen (Jun 18 2020 at 21:08):
Done: #3111.
Last updated: Dec 20 2023 at 11:08 UTC