Zulip Chat Archive

Stream: Is there code for X?

Topic: Complexification of a real vector space


Arien Malec (Dec 13 2023 at 18:30):

I assume this (Exercise 1B Problem 7) from Axler's Linear Algebra is a one liner in Mathlib, but what one liner is it?

Suppose 𝑉 is a real vector space.
β€’ The complexification of 𝑉, denoted by 𝑉𝐂 , equals 𝑉 Γ— 𝑉. An element of
𝑉𝐂 is an ordered pair( 𝑒,𝑣),where𝑒,𝑣 ∈ 𝑉, but we write this as 𝑒+𝑖𝑣.
β€’ Addition on 𝑉𝐂 is defined by
(𝑒1 +𝑖𝑣1)+(𝑒2 +𝑖𝑣2) = (𝑒1 +𝑒2)+𝑖(𝑣1 +𝑣2) for all 𝑒1,𝑣1,𝑒2,𝑣2 βˆˆπ‘‰.
β€’ Complex scalar multiplication on 𝑉𝐂 is defined by (π‘Ž+𝑏𝑖)(𝑒+𝑖𝑣) = (π‘Žπ‘’βˆ’π‘π‘£)+𝑖(π‘Žπ‘£+𝑏𝑒)
for all π‘Ž, 𝑏 ∈ 𝐑 and all 𝑒, 𝑣 ∈ 𝑉.
Prove that with the definitions of addition and scalar multiplication as above,
𝑉𝐂 is a complex vector space.

Eric Rodriguez (Dec 13 2023 at 18:48):

This will be done with the tensor product in mathlib

Arien Malec (Dec 13 2023 at 19:26):

Something like:

variable [Module ℝ V]
#synth Module ℝ (TensorProduct ℝ V V)

?

Eric Wieser (Dec 13 2023 at 20:07):

No, more like:

import Mathlib

variable {V} [AddCommGroup V] [Module ℝ V]
open scoped TensorProduct

#synth Module β„‚ (β„‚ βŠ—[ℝ] V)

Eric Wieser (Dec 13 2023 at 20:12):

You can then prove your first bullet point as

def prodEquivComplexTensor : V Γ— V ≃ β„‚ βŠ—[ℝ] V := sorry

and the second one as

theorem smul_def (c : β„‚) (a : V Γ— V) :
    c β€’ prodEquivComplexTensor b = prodEquivComplexTensor (c.re β€’ a.1 - c.im β€’ a.2, c.re β€’ a.1 + c.im β€’ a.2) := by
  sorry

Arien Malec (Dec 17 2023 at 02:58):

I've been beating my head against the first theorem without seeing any cracks in the armor -- any Mathlib theorems that simply or open up the proof.

Richard Copley (Dec 17 2023 at 03:35):

TensorProduct.prodLeft or TensorProduct.prodRight should help.

Arien Malec (Dec 17 2023 at 04:46):

I'm having trouble getting the right types in place.... prodLeft wants to distribute a product over a tensor product.

Richard Copley (Dec 17 2023 at 05:03):

Can you show β„‚ ≃ₗ[R] (ℝ Γ— ℝ)? (It's hard to guess exactly how far you've got.)

Arien Malec (Dec 17 2023 at 05:03):

huh... Nice idea...

Arien Malec (Dec 17 2023 at 05:05):

You can assume that I've been searching for relating things in Mathlib and trying to see if I can find a chain of structural decomposition to force fit.

Richard Copley (Dec 17 2023 at 05:08):

Then there's TensorProduct.rid and TensorProduct.lid.

Arien Malec (Feb 17 2024 at 19:49):

OK, coming back to this, I've done the brute force approach that Axler is looking for, by making a structure Vc with addition and multiplication as designated, and showing that it's a complex vector space.

(btw, when I look at introductions to complexification, the order of the tensor product is opposite to the (β„‚ βŠ—[ℝ] V) but rather (V βŠ—[ℝ] β„‚)?)

The more mathy flavor of this is still beyond me. I think what @Eric Wieser is asking me for as a definition is the full Equiv structure? And I think we do this by mapping (fst,snd) = (1 βŠ—[ℝ] fst) + (i βŠ—[ℝ] snd) or something like that? And v βŠ—[ℝ] ⟨re, im⟩ to (re β€’ v, im β€’ v) or ???

I'm not even sure that's the right track, but if it is, I don't know the syntax to make it work?

Arien Malec (Feb 17 2024 at 19:51):

(current code at https://github.com/arienmalec/axler)

Eric Wieser (Feb 17 2024 at 21:23):

Arien Malec said:

(btw, when I look at introductions to complexification, the order of the tensor product is opposite to the (β„‚ βŠ—[ℝ] V) but rather (V βŠ—[ℝ] β„‚)?)

in mathlib V βŠ—[ℝ] β„‚ is not a β„‚-module, but β„‚ βŠ—[ℝ] V is. We can't have both without instance diamonds, and we picked the one that uses left-actions

Eric Wieser (Feb 17 2024 at 21:24):

Hopefully you can work out how to define the forward mapping. The trick with the reverse mapping is to use docs#TensorProduct.lift

Arien Malec (Feb 17 2024 at 22:13):

I think I figured out the forward mapping, but I'm swimming in a sea of notation. Like the difference between βŠ—β‚œ[ℝ] and βŠ—[ℝ] where the first is "The canonical function M β†’ N β†’ M βŠ— N."

Arien Malec (Feb 17 2024 at 22:13):

toFun p := match p with
  |  ⟨fst, snd⟩ =>  (⟨1, 0⟩ βŠ—β‚œ[ℝ] fst) + ⟨0,1⟩ βŠ—β‚œ[ℝ] snd

Jireh Loreaux (Feb 17 2024 at 22:17):

Arien, are you familiar with tensor products mathematically, aside from Lean?

The first one creates elementary tensors. The second one forms the tensor product of two modules, and this is spanned by elementary tensors.

Eric Wieser (Feb 17 2024 at 22:17):

The difference between A βŠ—[ℝ] B and a βŠ—β‚œ[ℝ] b is like the difference between Ξ± Γ— Ξ² and (a, b)

Eric Wieser (Feb 17 2024 at 22:17):

Note that for βŠ—β‚œ you can almost always drop the [R] too

Jireh Loreaux (Feb 17 2024 at 22:18):

(with the key distinction that unlike Prod, not every element can be written this way)

Eric Wieser (Feb 17 2024 at 22:18):

(and also unlike Prod, there is usually more than one way to write the same element)

Arien Malec (Feb 17 2024 at 22:24):

Jireh Loreaux said:

Arien, are you familiar with tensor products mathematically, aside from Lean?

The first one creates elementary tensors. The second one forms the tensor product of two modules, and this is spanned by elementary tensors.

Not at any level of detail, which is certainly part of the issue here. So elementary tensors are to tensor products as vectors are to vector spaces?

Eric Wieser (Feb 17 2024 at 22:24):

I think a mildly better analogy is "as basis vectors are to vectors spaces"; not every vector is a basis vector, just as not every tensor is elementary

Eric Wieser (Feb 17 2024 at 22:27):

It may also help to know that a tensor product of vector spaces has as a basis the elementary tensors of the bases of the spaces; if eie_i is a basis for EE and fif_i is a basis for FF then eiβŠ—fje_i \otimes f_j (note: two indices!) is a basis for EβŠ—FE \otimes F.

Arien Malec (Feb 18 2024 at 19:52):

Some syntax help, please --

Following the hint, I got to: invFun tp := TensorProduct.lift liftFun tp where the type signature for liftFun is β„‚ β†’β‚—[ℝ] V β†’β‚—[ℝ] (V Γ— V), and I think it wants to take a complex number and a vector, and produce a Prod in the form of the smul definition above. But from a syntax perspective, when I write:

def liftFun: β„‚ β†’β‚—[ℝ] V β†’β‚—[ℝ] (V Γ— V) where the type of toFun wants to be β„‚ β†’ V β†’β‚—[ℝ] V Γ— V not β„‚ β†’ V β†’ V Γ— V -- how do I write liftFun to be what I'm looking for?

(or, of course, if I'm completely off track....)

Arien Malec (Feb 18 2024 at 19:54):

(not sure how to get the unicode for R-linear maps to show up correctly.)

Eric Wieser (Feb 18 2024 at 20:02):

You probably want LinearMap.mk\_2

Eric Wieser (Feb 18 2024 at 20:03):

I think it would be easier to help you if you made a #mwe

Eric Wieser (Feb 18 2024 at 20:03):

Arien Malec said:

(not sure how to get the unicode for R-linear maps to show up correctly.)

I think you're referring to an Android bug; it looks fine on desktop

Arien Malec (Feb 18 2024 at 20:22):

Firefox bug apparently.

I seem to be missing an import somewhere, but hopefully this is close enough:

import Mathlib.Data.Real.Basic
import Mathlib.Data.Complex.Basic
import Mathlib.Algebra.Module.Basic
import Mathlib.Data.Complex.Module
import Mathlib.LinearAlgebra.TensorProduct


variable {V} [AddCommGroup V] [Module ℝ V]

open scoped TensorProduct

#synth Module β„‚ (β„‚ βŠ—[ℝ] V)

noncomputable def toFun (p: V Γ— V) : (β„‚ βŠ—[ℝ] V) := match p with
  |  ⟨fst, snd⟩ => ((⟨1, 0⟩: β„‚) βŠ—β‚œ[ℝ] fst) + (⟨0,1⟩: β„‚)  βŠ—β‚œ[ℝ] snd

def liftFun: β„‚ β†’β‚—[ℝ] V β†’β‚—[ℝ] (V Γ— V) where
  toFun := sorry
  map_add' := sorry
  map_smul' := sorry

def prodEquivComplexTensor: V Γ— V ≃ β„‚ βŠ—[ℝ] V where
  toFun p := toFun p
  invFun tp := TensorProduct.lift liftFun tp
  left_inv := sorry
  right_inv := sorry

Eric Wieser (Feb 18 2024 at 20:26):

Note that the final result is not as strong as the one you want to prove, and in fact you will find the stronger result easier!

Eric Wieser (Feb 18 2024 at 20:27):

You should be showing (V Γ— V) ≃ₗ[β„‚] (β„‚ βŠ—[ℝ] V)

Eric Wieser (Feb 18 2024 at 20:27):

And you will almost certainly want to do so with docs#LinearEquiv.ofLinear

Kevin Buzzard (Feb 18 2024 at 22:25):

Eric Wieser said:

You should be showing (V Γ— V) ≃ₗ[β„‚] (β„‚ βŠ—[ℝ] V)

Surely there is no C\mathbb{C}-module structure on VΓ—VV\times V if VV is a real vector space? You mean R\R-linear?

Kevin Buzzard (Feb 18 2024 at 22:29):

Arien your code is full of errors for me (on master and in the lean 4 playground). Are you missing some import/open/whatever?

Arien Malec (Feb 18 2024 at 22:41):

It's missing something but I'm not sure what. Perhaps a variable statement
earlier on in the file I extracted this from.

Arien Malec (Feb 18 2024 at 22:43):

I'll try to track down what's missing and repost.

Eric Wieser (Feb 18 2024 at 22:59):

import Mathlib.Data.Complex.Module

Eric Wieser (Feb 18 2024 at 22:59):

But note that import Mathlib is fine for most "I can't work this out" mwes

Eric Wieser (Feb 18 2024 at 22:59):

Reducing imports is only important for "i think there is a bug" mwes

Arien Malec (Feb 18 2024 at 23:23):

Fixed the MWE

Arien Malec (Feb 18 2024 at 23:27):

It would be fun, for certain values of fun, to work out the material in https://kconrad.math.uconn.edu/blurbs/linmultialg/complexification.pdf in Mathlib...

Eric Wieser (Feb 18 2024 at 23:46):

I spent quite a lot of work on complexifying clifford algebras a few months ago

Eric Wieser (Feb 18 2024 at 23:47):

Note that in mathlib, "complexification" is usually called baseChange

Eric Wieser (Feb 18 2024 at 23:48):

@loogle "baseChange"

loogle (Feb 18 2024 at 23:48):

:search: Submodule.baseChange, Submodule.baseChange_bot, and 171 more

Arien Malec (Feb 19 2024 at 01:03):

Mathlib makes hard things possible, and really easy things elegant and things in the middle are sometimes....

Arien Malec (Feb 19 2024 at 20:27):

I've gotten to:

import Mathlib.Data.Real.Basic
import Mathlib.Data.Complex.Basic
import Mathlib.Algebra.Module.Basic
import Mathlib.Data.Complex.Module
import Mathlib.LinearAlgebra.TensorProduct


variable {V} [AddCommGroup V] [Module ℝ V]

open scoped TensorProduct

#synth Module β„‚ (β„‚ βŠ—[ℝ] V)


noncomputable def toFun: V Γ— V β†’β‚—[ℝ] β„‚ βŠ—[ℝ] V where
  toFun p := match p with
  |  ⟨fst, snd⟩ => ((1: β„‚) βŠ—β‚œ[ℝ] fst) + Complex.I βŠ—β‚œ[ℝ] snd
  map_add' p1 p2 := by dsimp; simp [TensorProduct.tmul_add]; abel_nf
  map_smul' r p := by dsimp; simp [TensorProduct.tmul_smul]

noncomputable def invFun: β„‚ βŠ—[ℝ] V β†’β‚—[ℝ] V Γ— V where
  toFun tp := by sorry
  map_add' tp1 tp1 := by dsimp; sorry
  map_smul' r tp := by dsimp; sorry

but the definition of invFun eludes me. In particular, if I had a complex number and a vector, I could create a Prod but I'm not sure how to get these "out" of the product, if I'm thinking about that the right way.

Also, when I do theorem toFun_invFun_comp: LinearMap.comp toFun invFun = LinearMap.id := by sorry I get

typeclass instance problem is stuck, it is often due to metavariables
  AddCommMonoid (?m.21022 Γ— ?m.21022)

Which I assume means I need an instance for V Γ— V

Kevin Buzzard (Feb 19 2024 at 20:35):

noncomputable def invFun : β„‚ βŠ—[ℝ] V β†’β‚—[ℝ] V Γ— V := TensorProduct.lift {
  toFun := fun z ↦ {
    toFun := fun v ↦ (z.re β€’ v, z.im β€’ v)
    map_add' := sorry
    map_smul' := sorry
  }
  map_add' := sorry
  map_smul' := sorry
}

Eric Wieser (Feb 19 2024 at 21:04):

Eric Wieser said:

You probably want LinearMap.mk\_2

This would work too

Eric Wieser (Feb 19 2024 at 21:05):

Arien Malec said:

Also, when I do theorem toFun_invFun_comp: LinearMap.comp toFun invFun = LinearMap.id := by sorry I get

typeclass instance problem is stuck, it is often due to metavariables
  AddCommMonoid (?m.21022 Γ— ?m.21022)

Which I assume means I need an instance for V Γ— V

Lean is confused because you never told it you were talking about V

Arien Malec (Feb 19 2024 at 21:07):

Eric Wieser said:

Eric Wieser said:

You probably want LinearMap.mk\_2

This would work too

I'm sure but @Kevin Buzzard put the Don't Panic sticker on his.... (I looked at the sig for mk_2 but didn't grok it :-))

Eric Wieser (Feb 19 2024 at 21:08):

It takes a two-argument function, and four proofs

Eric Wieser (Feb 19 2024 at 21:09):

You could use by apply LinearMap.mk2 to have Lean grok it for you :)

Arien Malec (Feb 19 2024 at 21:11):

Eric Wieser said:

Arien Malec said:

Also, when I do theorem toFun_invFun_comp: LinearMap.comp toFun invFun = LinearMap.id := by sorry I get

typeclass instance problem is stuck, it is often due to metavariables
  AddCommMonoid (?m.21022 Γ— ?m.21022)

...

Lean is confused because you never told it you were talking about V

Ah, theorem toFun_invFun_comp: LinearMap.comp (@toFun V _ _) invFun = LinearMap.id := by sorry fixes it.

Eric Wieser (Feb 19 2024 at 21:12):

Using (V) instead of {V} above would be another solution

Kevin Buzzard (Feb 19 2024 at 21:17):

mk\2

Arien Malec (Feb 19 2024 at 21:32):

It turns out that works better -- the proofs for the plain lift version have complicated structures in them -- I'm sure there's a way around this, but this, despite the hackery, works:

noncomputable def invFun: β„‚ βŠ—[ℝ] V β†’β‚—[ℝ] V Γ— V :=
  TensorProduct.lift <| LinearMap.mkβ‚‚
  ℝ (fun z v ↦ (z.re β€’ v, z.im β€’ v))
    (by intros; ext <;> dsimp <;> rw [add_smul])
    (by intros; ext <;> dsimp <;> simp [mul_smul])
    (by intros; ext <;> dsimp <;> simp [smul_add])
    (by intros; ext <;> dsimp <;> rw [smul_comm])

Arien Malec (Feb 20 2024 at 01:30):

Here's where I've gotten:

import Mathlib.Data.Real.Basic
import Mathlib.Data.Complex.Basic
import Mathlib.Algebra.Module.Basic
import Mathlib.Data.Complex.Module
import Mathlib.LinearAlgebra.TensorProduct


variable {V} [AddCommGroup V] [Module ℝ V]

open scoped TensorProduct

#synth Module β„‚ (β„‚ βŠ—[ℝ] V)

noncomputable def toFun: V Γ— V β†’β‚—[ℝ] β„‚ βŠ—[ℝ] V where
  toFun p := match p with
  |  ⟨fst, snd⟩ => ((1: β„‚) βŠ—β‚œ[ℝ] fst) + Complex.I βŠ—β‚œ[ℝ] snd
  map_add' p1 p2 := by dsimp; simp [TensorProduct.tmul_add]; abel_nf
  map_smul' r p := by dsimp; simp [TensorProduct.tmul_smul]

noncomputable def invFun: β„‚ βŠ—[ℝ] V β†’β‚—[ℝ] V Γ— V :=
  TensorProduct.lift <| LinearMap.mkβ‚‚
  ℝ (fun z v ↦ (z.re β€’ v, z.im β€’ v))
    (by intros; ext <;> dsimp <;> rw [add_smul])
    (by intros; ext <;> dsimp <;> simp [mul_smul])
    (by intros; ext <;> dsimp <;> simp [smul_add])
    (by intros; ext <;> dsimp <;> rw [smul_comm])


theorem toFun_invFun_comp_eq_id: LinearMap.comp (@toFun V _ _) invFun = LinearMap.id := by
  simp only [toFun, invFun]; ext z v; dsimp; simp [TensorProduct.tmul_add, TensorProduct.smul_tmul]
  sorry

theorem invFun_toFun_comp_eq_id: LinearMap.comp invFun (@toFun V _ _) = LinearMap.id := by
  simp only [invFun, toFun]; sorry

def prodRLinearComplexTensor: (V Γ— V) ≃ₗ[ℝ] (β„‚ βŠ—[ℝ] V) := LinearEquiv.ofLinear toFun invFun toFun_invFun_comp_eq_id invFun_toFun_comp_eq_id

A few issues here:

  1. If I make the {V} explicit I get a world of hurt with errors like: typeclass instance problem is stuck, it is often due to metavariables RingHomCompTriple ?m.31917 (RingHom.id ℝ) (RingHom.id ℝ) and friends
  2. In toFun_invFun_comp_eq_id I get to a really nice goal state, but I can't get rw [←TensorProduct.add_tmul (z.re β€’ 1) (z.im β€’ Complex.I) v] to accept that the pattern exists; I've tried using @ and getting super explicit, but been unable to get a non barf state.
V: Type u_1
inst✝¹: AddCommGroup V
inst✝: Module ℝ V
z: β„‚
v: V
⊒ z.re β€’ 1 βŠ—β‚œ[ℝ] v + z.im β€’ Complex.I βŠ—β‚œ[ℝ] v = z βŠ—β‚œ[ℝ] v
  1. The proof state for invFun_toFun_comp_eq_id by contrast is a real mess that I don't have a clue how to fix...

  2. Most concerning, in prodRLinearComplexTensor I get the error:

compiler IR check failed at 'prodRLinearComplexTensor._rarg', error: unknown declaration 'toFun'

Arien Malec (Feb 20 2024 at 01:33):

BTW, when I clear this thicket, is it going to be easy to use the proofs to do simple things like prove:

def Rn_complexified_equiv {n: β„•}: (β„‚ βŠ—[ℝ] (Fin n β†’ ℝ)) ≃ₗ[ℝ] (Fin n β†’ β„‚) := sorry

?

Eric Wieser (Feb 20 2024 at 03:27):

1 is because you need to add a bunch of Vs everywhere

Eric Wieser (Feb 20 2024 at 03:29):

I would guess your problem in 2 is that the operators don't have the parenthesization you think they do, and you need to start with an associativity lemma

Eric Wieser (Feb 20 2024 at 03:30):

4 is asking you to add noncomputable

Eric Wieser (Feb 20 2024 at 03:30):

Regarding R^n; you will most likely have to do all the work again from scratch, but you should find it much easier once you know the tricks

Arien Malec (Feb 20 2024 at 03:41):

Eric Wieser said:

I would guess your problem in 2 is that the operators don't have the parenthesization you think they do, and you need to start with an associativity lemma

I see -- the issue is that z.re β€’ 1 βŠ—β‚œ[ℝ] v is seen as z.re β€’ (1 βŠ—β‚œ[ℝ] v)?

Eric Wieser (Feb 20 2024 at 03:43):

If you hover over the goal view, vscode will tell you

Eric Wieser (Feb 20 2024 at 03:44):

I'm afraid while I can remember many lemmas names, I am unreliable at remembering operator precedence

Arien Malec (Feb 20 2024 at 03:46):

It's rfl as it happens.

theorem toFun_invFun_comp_eq_id: LinearMap.comp (@toFun V _ _) invFun = LinearMap.id := by
  simp only [toFun, invFun]; ext z v; dsimp; simp [TensorProduct.tmul_add, TensorProduct.smul_tmul]
  have h1: (z.re β€’ (1: β„‚) βŠ—β‚œ[ℝ] v) = (z.re β€’ 1) βŠ—β‚œ[ℝ] v := rfl
  have h2: (z.im β€’ (Complex.I βŠ—β‚œ[ℝ] v)) = ((z.im β€’ Complex.I) βŠ—β‚œ[ℝ] v) := rfl
  rw [h1, h2, ←TensorProduct.add_tmul (z.re β€’ 1) (z.im β€’ Complex.I) v]
  simp only [Complex.real_smul, mul_one, Complex.re_add_im]

Eric Wieser (Feb 20 2024 at 03:49):

I recommend using by rw? to find the actual lemma name

Arien Malec (Feb 20 2024 at 03:55):

Wow! rw? is a thing! TensorProduct.smul_tmul'

Eric Wieser (Feb 20 2024 at 03:57):

Just to explain why I told you to build everything as linear maps: if you hadn't, and tried to prove the inverse as f (g x) = x instead of this comp version, your ext z w wouldn't have worked

Eric Wieser (Feb 20 2024 at 03:58):

You might find the proof even easier if you add attribute [ext] TensorProduct.ext' before your proof

Arien Malec (Feb 20 2024 at 15:53):

I'm down to invFun_toFun_comp_eq_id and I can't seem to make progress -- the first part of the goal state is:

TensorProduct.lift
        (LinearMap.mkβ‚‚ ℝ --- then lots of functions to structures

and I haven't found the way around -- somehow this all normalized out in toFun_inFun_comp_eq_id.

Eric Wieser (Feb 20 2024 at 15:54):

Can you share the full goal state, or an updated mwe?

Arien Malec (Feb 20 2024 at 15:55):

Uh, scratch that, somehow:

theorem invFun_toFun_comp_eq_id: LinearMap.comp invFun (@toFun V _ _) = LinearMap.id := by
  simp only [toFun]; apply LinearMap.ext; intro p; simp [invFun]

works where

theorem invFun_toFun_comp_eq_id: LinearMap.comp invFun (@toFun V _ _) = LinearMap.id := by
  simp only [toFun, invFun]; apply LinearMap.ext; intro p

was simp resistant

Arien Malec (Feb 20 2024 at 15:56):

Oh, that's not correct either -- I never tried the literally simplest tactic

Arien Malec (Feb 20 2024 at 15:58):

Now what do I do with my time? Oh, yeah, show the R^n C^n case.

Eric Wieser (Feb 20 2024 at 16:00):

Arien Malec said:

Now what do I do with my time? Oh, yeah, show the R^n C^n case.

This one should actually be easier, you should be able to compose isomorphisms already in mathlib

Arien Malec (Feb 20 2024 at 17:29):

Hmm. With your hints on baseChange, do I want something like docs#IsBaseChange.equiv ?

Eric Wieser (Feb 20 2024 at 17:45):

I think I'm wrong, the result I'm thinking of only exists for finitely supported functions, not general functions

Arien Malec (Feb 20 2024 at 17:46):

I'll go the hard way then.

Arien Malec (Feb 20 2024 at 17:46):

What would need to be in Mathlib for this to be trivial?

Eric Wieser (Feb 20 2024 at 17:47):

docs#TensorProduct.directSumLeft for Pi types

Eric Wieser (Feb 20 2024 at 17:47):

(probably over a Fintype index)

Eric Wieser (Feb 20 2024 at 17:48):

You'd combine that with the fact that β„‚ βŠ—[ℝ] ℝ and β„‚ are isomorphic, which Mathlib knows

Arien Malec (Feb 20 2024 at 18:30):

Oh, hey, we know docs#Complex.equivRealProd and now we know that (V Γ— V) ≃ₗ[ℝ] (β„‚ βŠ—[ℝ] V)

Arien Malec (Feb 20 2024 at 18:30):

Can these be combined in useful ways?

Eric Wieser (Feb 20 2024 at 18:31):

Yes, you could have used that to get the isomorphism instead of your approach, I think

Eric Wieser (Feb 20 2024 at 18:32):

@loogle TensorProduct, Prod

loogle (Feb 20 2024 at 18:32):

:search: TensorProduct.SMul.aux, TensorProduct.SMul.aux_of, and 68 more

Eric Wieser (Feb 20 2024 at 18:33):

docs#TensorProduct.prodLeft is what I was looking for

Arien Malec (Feb 20 2024 at 18:33):

I played with that for a bit but didn't find the path through....

Eric Wieser (Feb 20 2024 at 18:34):

You'll need docs#TensorProduct.congr too

Eric Wieser (Feb 20 2024 at 18:34):

And docs#TensorProduct.lid

Eric Wieser (Feb 20 2024 at 18:35):

And docs#LinearEquiv.prod


Last updated: May 02 2025 at 03:31 UTC