Zulip Chat Archive

Stream: maths

Topic: Matrix theorem proof


Anirudh Suresh (Mar 11 2025 at 00:20):

image.png
I am facing trouble proving this goal. Is there any tactic that will help me simplify this or is there any approach I can take to solve this?

Kevin Buzzard (Mar 11 2025 at 00:45):

This question would be much easier to answer if you posted a #mwe rather than a screenshot. Does ext then rw [Matrix.mul_apply] and then ring do something? I can't check because you didn't post a #mwe .

Eric Wieser (Mar 11 2025 at 00:46):

It looks to me like you're building docs#Matrix.mul_kronecker_mul the hard way?

Anirudh Suresh (Mar 11 2025 at 01:02):

Kevin Buzzard said:

This question would be much easier to answer if you posted a #mwe rather than a screenshot. Does ext then rw [Matrix.mul_apply] and then ring do something? I can't check because you didn't post a #mwe .

import Mathlib.Data.Vector
import Mathlib.Data.Complex.Basic
import Mathlib.Data.Real.Basic
import Mathlib.Data.Real.Sqrt
import Mathlib.Data.Matrix.Basic
import Mathlib.Data.Complex.Basic
open scoped Matrix
open ComplexConjugate


def tensor_product_2 {m n o p: } (A : Matrix (Fin m) (Fin n) ) (B : Matrix (Fin o) (Fin p) ) : Matrix (Fin (m*o)) (Fin (n*p))  :=
  Matrix.of (fun (i:Fin (m*o)) (j:Fin (n*p)) => A (Fin.ofNat' (i.val / o) (by {
    have h : 0 < m * o  := Fin.pos i
    simp [Nat.pos_of_mul_pos_left] at h
    cases h
    assumption
  }))
  (Fin.ofNat' (j.val / p) (by {
    have h : 0 < n*p  := Fin.pos j
    simp [Nat.pos_of_mul_pos_left] at h
    cases h
    assumption
  })) * B (Fin.ofNat' (i.val % o) (by {
    have h : 0 < m * o  := Fin.pos i
    simp [Nat.pos_of_mul_pos_left] at h
    cases h
    assumption
  })) (Fin.ofNat' (j.val % p) (by {
    have h : 0 < n*p  := Fin.pos j
    simp [Nat.pos_of_mul_pos_left] at h
    cases h
    assumption
  })))

infix:1024  "⊗" => tensor_product_2

theorem mul_tensor {m n p q r s : }
  (A  : Matrix (Fin m) (Fin n) )
  (A' : Matrix (Fin n) (Fin p) )
  (B  : Matrix (Fin q) (Fin r) )
  (B' : Matrix (Fin r) (Fin s) ) :
  (tensor_product_2 A B) * (tensor_product_2 A' B') = tensor_product_2 (A * A') (B * B') :=
by{

}

Eric Wieser (Mar 11 2025 at 01:07):

You're making things very hard for yourself by using Matrix (Fin (m*o)) (Fin (n*p)) ℂ instead of Matrix (Fin m × Fin o) (Fin n × Fin p) ℂ.

Eric Wieser (Mar 11 2025 at 01:08):

Even if you're really sure you want the former, you'd have a much better time if you constructed it in terms of the latter, using docs#Matrix.reindex and a Equiv that you should be able to find with Loogle.

Anirudh Suresh (Mar 11 2025 at 01:13):

Yes but changing the index to tuples makes things really hard for me as well...especially if I would like to do multiple kronecker products which would result in a matrix with nested tuples as indices

Eric Wieser (Mar 11 2025 at 01:22):

Are you deliberately avoiding docs#Matrix.kronecker for pedagogical reasons ("I want to build some matrix theory from scratch as an exercise"), or just because you're finding the tuple indices inconvenient?

Anirudh Suresh (Mar 11 2025 at 01:26):

Eric Wieser said:

Are you deliberately avoiding docs#Matrix.kronecker for pedagogical reasons ("I want to build some matrix theory from scratch as an exercise"), or just because you're finding the tuple indices inconvenient?

im finding tuple indices inconvenient

Eric Wieser (Mar 11 2025 at 01:45):

Eric Wieser said:

Even if you're really sure you want the former, you'd have a much better time if you constructed it in terms of the latter [ docs#Matrix.kronecker ], using docs#Matrix.reindex and a Equiv that you should be able to find with Loogle.

I recommend doing this then

Anirudh Suresh (Mar 11 2025 at 01:56):

would it not be possible to prove this using my definition of tensor_product?

Eric Wieser (Mar 11 2025 at 10:44):

Sure, but you'd be redoing lots of work. Your function is a combination of two things already in mathlib. If you rebuild it that way rather than from scratch, you can reuse all the existing proofs about those things.

Kevin Buzzard (Mar 11 2025 at 10:49):

Your MWE is full of errors for me. If you click on the "view in lean 4 playground" link which Zulip has put on your code, you'll see what I see (I removed the first import because it doesn't exist but this didn't help)

Eric Wieser (Mar 11 2025 at 10:57):

Replacing Fin.ofNat' with Fin.mk fixes it

Eric Wieser (Mar 11 2025 at 10:57):

But you want to avoid messing around with / and % completely here

Eric Wieser (Mar 11 2025 at 10:58):

Eric Wieser said:

and a Equiv that you should be able to find with Loogle.

@Anirudh Suresh, were you able to find this? (I deliberately didn't find it for you to let you practice with Loogle)

Anirudh Suresh (Mar 16 2025 at 00:23):

Eric Wieser said:

Anirudh Suresh, were you able to find this? (I deliberately didn't find it for you to let you practice with Loogle)

I did find Equiv but how exctly would that make it possible to use the kronecker product defined in lean? It is difficult because kronecker product changes the matrix index type to tuple. Is there a way to avoid this?

Kevin Buzzard (Mar 16 2025 at 00:28):

Is there a way that you can be persuaded that thinking of matrices as being indexed by an arbitrary finite type is not a scary thing? Every finite type bijects with Fin n for some n and you can use this bijection if you want but it's often just a psychological crutch.

Kevin Buzzard (Mar 16 2025 at 00:34):

docs#Matrix.kronecker returns matrices indexed by a tuple, but docs#Matrix.submatrix and docs#Matrix.reindex let you change the indexing types, and this enables you to do all the number-theoretic Fin a × Fin b ≃ Fin (a * b) and the matrix-theoretic products completely independently, thus meaning that you only have to deal with one problem at a time.

Anirudh Suresh (Mar 17 2025 at 01:47):

This makes sense. However, I could not find an Equiv that allows to complete the definition.

import Mathlib.Data.Complex.Basic
import Mathlib.Data.Real.Basic
import Mathlib.Data.Real.Sqrt
import Mathlib.Data.Matrix.Basic
import Mathlib.Data.Complex.Basic
import Mathlib.Data.Matrix.Kronecker
open scoped Matrix
open ComplexConjugate



def tensor_product_2 {m n o p : } (A : Matrix (Fin m) (Fin n) )
  (B : Matrix (Fin o) (Fin p) ) : Matrix (Fin (m * o)) (Fin (n * p))  :=
Matrix.submatrix (Matrix.kronecker A B) (
  Matrix.reindex (

  ) ()
) (Matrix.reindex () ())

Aaron Liu (Mar 17 2025 at 01:48):

@loogle Fin, Equiv, Prod, HMul.hMul

loogle (Mar 17 2025 at 01:48):

:search: finProdFinEquiv, Nat.divModEquiv_symm_apply, and 5 more

Aaron Liu (Mar 17 2025 at 01:48):

It's docs#finProdFinEquiv

Aaron Liu (Mar 17 2025 at 01:51):

import Mathlib.Data.Complex.Basic
import Mathlib.Data.Matrix.Kronecker

example {m n o p : } (A : Matrix (Fin m) (Fin n) ) (B : Matrix (Fin o) (Fin p) ) :
    Matrix (Fin (m * o)) (Fin (n * p))  :=
  (Matrix.kronecker A B).reindex finProdFinEquiv finProdFinEquiv

Anirudh Suresh (Mar 17 2025 at 01:55):

Thanks this works!


Last updated: May 02 2025 at 03:31 UTC