Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(LinearAlgebra/DirectSum/Finsupp) : tensor products of finsupp functions #10824

Closed
wants to merge 68 commits into from
Closed
Show file tree
Hide file tree
Changes from 41 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
d8e50fc
generalize to CommSemiring / AddCommMonoid
Feb 21, 2024
fa4cb7e
generalize to CommSemiring / AddCommMonoid
Feb 21, 2024
53ee15d
add finsupp_sum_tmul and 3 variants
Feb 21, 2024
d55ac1e
revert
Feb 21, 2024
2f1ebe7
rename (temp)
Feb 21, 2024
c28b2e6
something working
Feb 21, 2024
2320a61
lint 100
Feb 21, 2024
1fdd0aa
revert the generalization (-> AddCommGroup/CommSemiring in the initia…
Feb 21, 2024
d76a5a9
rename following EW's suggestion
Feb 21, 2024
423a61d
namespace TensorProduct
Feb 21, 2024
2efdc69
add docstring
Feb 21, 2024
98b197b
update Mathlib.lean
Feb 21, 2024
7f13321
update Mathlib.lean
Feb 21, 2024
aa3eaf6
better inferface for polynomial (via finsuppScalarLeft)
Feb 22, 2024
3e12239
add letI in RingTheory/Flat/Basic
Feb 22, 2024
8458d4e
adjust `simp` to make Lie/TensorProduct compile
Feb 22, 2024
e259731
remove useless import
Feb 22, 2024
2e74096
Merge branch 'master' into ACL/FinsuppTensorProd
eric-wieser Feb 23, 2024
19af3b0
re-add variable
Feb 23, 2024
d26f775
remove multiplicativity (doesn't work yet)
Feb 23, 2024
660e471
Update Mathlib/LinearAlgebra/DirectSum/Finsupp.lean
AntoineChambert-Loir Feb 23, 2024
65e6c20
add finsuppScalarRight
Feb 23, 2024
a7b0441
add TensorProduct of MonoidAlgebra
Feb 23, 2024
8af8487
add docstring
Feb 23, 2024
4f65f96
add docstrings for definitions
Feb 23, 2024
b1742d9
lint100
Feb 23, 2024
85b2839
update Mathlib.lean
Feb 23, 2024
3fb1a0a
add "todo" note
Feb 23, 2024
c375537
do the construction in the other directions (using AlgebraTensorProduct)
Feb 24, 2024
e296050
small progress
Feb 24, 2024
ef9a571
delete garbage
Feb 24, 2024
6c74740
remove bad "end"
Feb 24, 2024
d9ce8e2
Algebra for MvPolynomial
Feb 24, 2024
ec42703
cleanup
Feb 25, 2024
d7c43b0
cleanup
Feb 25, 2024
32d9c2e
move files
Feb 25, 2024
417d963
adjust Mathlib.lean
Feb 25, 2024
337b52a
equiv for polynomial
Feb 25, 2024
5a5f1a9
shorten some lines; review-dog
Feb 25, 2024
cdc4ef9
linter 100
Feb 25, 2024
5112ca4
dedup namespace
Feb 25, 2024
47a6c00
Merge branch 'master' into ACL/FinsuppTensorProd
Feb 29, 2024
746bb43
Do what review dog suggests
AntoineChambert-Loir Feb 29, 2024
20c8b2d
generalize Monoid to MulOneClass
Feb 29, 2024
1665702
add docstrings
Feb 29, 2024
f0a5d8b
add docstrings
Feb 29, 2024
fc8f0d1
one more doctring
Feb 29, 2024
0e751b9
yet another docstring
Feb 29, 2024
d3ade35
docstring : change i to iota (3 lines)
Feb 29, 2024
87d6d87
lint 100
Feb 29, 2024
cdfd7b1
remove unused equiv
Feb 29, 2024
91c0278
Merge branch 'master' into ACL/FinsuppTensorProd
Mar 13, 2024
c2496b2
Update Mathlib/Algebra/Lie/TensorProduct.lean
AntoineChambert-Loir Mar 13, 2024
02e19a6
change import in 3 files
Mar 13, 2024
073c214
correct badly formed import line
Mar 13, 2024
47be110
import lines were still wrong…
Mar 13, 2024
119763f
that should be good…
Mar 13, 2024
c16067f
generalize one universe
AntoineChambert-Loir Mar 21, 2024
845bb95
add MvPolynomial.lcoeff
AntoineChambert-Loir Mar 21, 2024
8004cfc
add lemmas
AntoineChambert-Loir Mar 21, 2024
de94570
indent correctly
AntoineChambert-Loir Mar 21, 2024
cfa238f
correct the unfinished proof
AntoineChambert-Loir Mar 21, 2024
aa4b9a4
Merge branch 'master' into ACL/FinsuppTensorProd
AntoineChambert-Loir Apr 9, 2024
f3d3ee2
adjust MvPolynomial to merged version of finsupptensorprod
AntoineChambert-Loir Apr 9, 2024
df63d70
mv two lemmas to Data/Finsupp
AntoineChambert-Loir Apr 9, 2024
8d31f5d
add explicit arguments
AntoineChambert-Loir Apr 9, 2024
f1719b8
Replace noisy `simp?`
ocfnash Apr 10, 2024
c724436
Merge branch 'master' into ACL/FinsuppTensorProd
AntoineChambert-Loir Apr 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Mathlib.lean
Original file line number Diff line number Diff line change
Expand Up @@ -3336,6 +3336,9 @@ import Mathlib.RingTheory.Subring.Pointwise
import Mathlib.RingTheory.Subsemiring.Basic
import Mathlib.RingTheory.Subsemiring.Pointwise
import Mathlib.RingTheory.TensorProduct
import Mathlib.RingTheory.TensorProduct.MonoidAlgebra
import Mathlib.LinearAlgebra.TensorProduct.MvPolynomial
import Mathlib.LinearAlgebra.TensorProduct.Polynomial
AntoineChambert-Loir marked this conversation as resolved.
Show resolved Hide resolved
import Mathlib.RingTheory.Trace
import Mathlib.RingTheory.UniqueFactorizationDomain
import Mathlib.RingTheory.Valuation.Basic
Expand Down
8 changes: 2 additions & 6 deletions Mathlib/Algebra/Lie/TensorProduct.lean
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,7 @@ instance lieRingModule : LieRingModule L (M ⊗[R] N) where
hasBracketAux ⁅x, y⁆ + (hasBracketAux y).comp (hasBracketAux x) by
simp only [← LinearMap.add_apply]; rw [← LinearMap.comp_apply, this]; rfl
ext m n
simp only [hasBracketAux, LieRing.of_associative_ring_bracket, LinearMap.mul_apply, mk_apply,
LinearMap.lTensor_sub, LinearMap.compr₂_apply, Function.comp_apply, LinearMap.coe_comp,
LinearMap.rTensor_tmul, LieHom.map_lie, toEndomorphism_apply_apply, LinearMap.add_apply,
LinearMap.map_add, LinearMap.rTensor_sub, LinearMap.sub_apply, LinearMap.lTensor_tmul]
simp [hasBracketAux, LieRing.of_associative_ring_bracket]
abel
#align tensor_product.lie_module.lie_ring_module TensorProduct.LieModule.lieRingModule

Expand Down Expand Up @@ -96,8 +93,7 @@ def lift : (M →ₗ[R] N →ₗ[R] P) ≃ₗ⁅R,L⁆ M ⊗[R] N →ₗ[R] P :=
{ TensorProduct.lift.equiv R M N P with
map_lie' := fun {x f} => by
ext m n
simp only [mk_apply, LinearMap.compr₂_apply, lie_tmul_right, LinearMap.sub_apply,
lift.equiv_apply, LinearEquiv.toFun_eq_coe, LieHom.lie_apply, LinearMap.map_add]
simp
AntoineChambert-Loir marked this conversation as resolved.
Show resolved Hide resolved
abel }
#align tensor_product.lie_module.lift TensorProduct.LieModule.lift

Expand Down
221 changes: 213 additions & 8 deletions Mathlib/LinearAlgebra/DirectSum/Finsupp.lean
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/-
Copyright (c) 2019 Johannes Hölzl. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Johannes Hölzl
Authors: Johannes Hölzl, Antoine Chambert-Loir
-/
import Mathlib.Algebra.DirectSum.Finsupp
import Mathlib.LinearAlgebra.Finsupp
Expand All @@ -12,29 +12,234 @@ import Mathlib.LinearAlgebra.DirectSum.TensorProduct
/-!
# Results on finitely supported functions.

The tensor product of `ι →₀ M` and `κ →₀ N` is linearly equivalent to `(ι × κ) →₀ (M ⊗ N)`.
* `TensorProduct.finsuppLeft`, the tensor product of `ι →₀ M` and `N`
is linearly equivalent to `ι →₀ M ⊗[R] N`

* `TensorProduct.finsuppScalarLeft`, the tensor product of `ι →₀ R` and `N`
is linearly equivalent to `ι →₀ N`

* `TensorProduct.finsuppRight`, the tensor product of `M` and `ι →₀ N`
is linearly equivalent to `ι →₀ M ⊗[R] N`

* `TensorProduct.finsuppScalarRight`, the tensor product of `M` and `ι →₀ R`
is linearly equivalent to `ι →₀ N`


* `TensorProduct.finsuppLeft'`, if `M` is an `S`-module,
then the tensor product of `ι →₀ M` and `N` is `S`-linearly equivalent
to `ι →₀ M ⊗[R] N`

* `finsuppTensorFinsupp`, the tensor product of `ι →₀ M` and `κ →₀ N`
is linearly equivalent to `(ι × κ) →₀ (M ⊗ N)`.

## Case of MvPolynomial

These functions apply to `MvPolynomial`, one can define
```
noncomputable def MvPolynomial.rTensor' :
MvPolynomial σ S ⊗[R] N ≃ₗ[S] (σ →₀ ℕ) →₀ (S ⊗[R] N) :=
TensorProduct.finsuppLeft'

noncomputable def MvPolynomial.rTensor :
MvPolynomial σ R ⊗[R] N ≃ₗ[R] (σ →₀ ℕ) →₀ N :=
TensorProduct.finsuppScalarLeft
```

## Case of `Polynomial`

`Polynomial` is a structure containing a `Finsupp`, so these functions
can't be applied directly to `Polynomial`.

Some linear equivs need to be added to mathlib for that.

## TODO

* generalize to `MonoidAlgebra`, `AlgHom `

* reprove `TensorProduct.finsuppLeft'` using existing heterobasic version of `TensorProduct.congr`
-/


universe u v w

noncomputable section

open DirectSum
open DirectSum TensorProduct

open Set LinearMap Submodule

section TensorProduct

open TensorProduct
variable {R : Type*} [CommSemiring R]
{M : Type*} [AddCommMonoid M] [Module R M]
{N : Type*} [AddCommMonoid N] [Module R N]

namespace TensorProduct

variable {ι : Type*} [DecidableEq ι]

/-- The tensor product of `i →₀ M` and `N` is linearly equivalent to `i →₀ M ⊗[R] N` -/
AntoineChambert-Loir marked this conversation as resolved.
Show resolved Hide resolved
noncomputable def finsuppLeft :
(ι →₀ M) ⊗[R] N ≃ₗ[R] ι →₀ (M ⊗[R] N) :=
(congr (finsuppLEquivDirectSum R M ι) (LinearEquiv.refl R N)).trans
((directSumLeft R (fun _ : ι => M) N).trans
(finsuppLEquivDirectSum R (M ⊗[R] N) ι).symm)

lemma finsuppLeft_apply_tmul (p : ι →₀ M) (n : N) :
finsuppLeft (p ⊗ₜ[R] n) = p.sum (fun i m ↦ Finsupp.single i (m ⊗ₜ[R] n)) := by
simp only [finsuppLeft, LinearEquiv.trans_apply, congr_tmul, LinearEquiv.refl_apply]
conv_lhs => rw [← Finsupp.sum_single p]
rw [LinearEquiv.symm_apply_eq]
simp only [map_finsupp_sum]
simp only [finsuppLEquivDirectSum_single]
rw [← LinearEquiv.eq_symm_apply]
simp only [map_finsupp_sum]
simp only [directSumLeft_symm_lof_tmul]
simp only [Finsupp.sum, sum_tmul]

lemma finsuppLeft_apply_tmul_apply (p : ι →₀ M) (n : N) (i : ι) :
finsuppLeft (p ⊗ₜ[R] n) i = p i ⊗ₜ[R] n := by
acmepjz marked this conversation as resolved.
Show resolved Hide resolved
rw [finsuppLeft_apply_tmul]
simp only [Finsupp.sum_apply]
conv_rhs => rw [← Finsupp.single_eq_same (a := i) (b := p i ⊗ₜ[R] n)]
apply Finsupp.sum_eq_single i
· exact fun _ _ ↦ Finsupp.single_eq_of_ne
· intro _
simp

lemma finsuppLeft_symm_apply_single (i : ι) (m : M) (n : N) :
finsuppLeft.symm (Finsupp.single i (m ⊗ₜ[R] n)) =
Finsupp.single i m ⊗ₜ[R] n := by
simp [finsuppLeft, Finsupp.lsum]

open TensorProduct
/-- The tensor product of `M` and `i →₀ N` is linearly equivalent to `i →₀ M ⊗[R] N` -/
AntoineChambert-Loir marked this conversation as resolved.
Show resolved Hide resolved
noncomputable def finsuppRight :
M ⊗[R] (ι →₀ N) ≃ₗ[R] ι →₀ (M ⊗[R] N) :=
(congr (LinearEquiv.refl R M) (finsuppLEquivDirectSum R N ι)).trans
((directSumRight R M (fun _ : ι => N)).trans
(finsuppLEquivDirectSum R (M ⊗[R] N) ι).symm)

lemma finsuppRight_apply_tmul (m : M) (p : ι →₀ N) :
finsuppRight (m ⊗ₜ[R] p) = p.sum (fun i n ↦ Finsupp.single i (m ⊗ₜ[R] n)) := by
simp [finsuppRight]
conv_lhs => rw [← Finsupp.sum_single p]
rw [LinearEquiv.symm_apply_eq]
simp only [map_finsupp_sum]
simp only [finsuppLEquivDirectSum_single]
rw [← LinearEquiv.eq_symm_apply]
simp only [map_finsupp_sum]
simp only [directSumRight_symm_lof_tmul]
simp only [Finsupp.sum, tmul_sum]

lemma finsuppRight_symm_apply_single (i : ι) (m : M) (n : N) :
finsuppRight.symm (Finsupp.single i (m ⊗ₜ[R] n)) =
m ⊗ₜ[R] Finsupp.single i n := by
simp [finsuppRight, Finsupp.lsum]

variable {S : Type*} [CommSemiring S] [Algebra R S]
[Module S M] [IsScalarTower R S M]

lemma finsuppLeft_smul' (s : S) (t : (ι →₀ M) ⊗[R] N) :
finsuppLeft (s • t) = s • finsuppLeft t := by
induction t using TensorProduct.induction_on with
| zero => simp
| add x y hx hy =>
simp only [AddHom.toFun_eq_coe, coe_toAddHom, LinearEquiv.coe_coe, RingHom.id_apply] at hx hy ⊢
simp only [smul_add, map_add, hx, hy]
| tmul p n =>
simp only [smul_tmul', finsuppLeft_apply_tmul]
rw [Finsupp.smul_sum]
simp only [Finsupp.smul_single]
apply Finsupp.sum_smul_index'
simp

/-- When `M` is also an `S`-module, then `TensorProduct.finsuppLeft R M N``
is an `S`-linear equiv -/
noncomputable def finsuppLeft' :
(ι →₀ M) ⊗[R] N ≃ₗ[S] ι →₀ (M ⊗[R] N) := {
finsuppLeft with
map_smul' := finsuppLeft_smul' }

lemma finsuppLeft'_apply (x : (ι →₀ M) ⊗[R] N) :
finsuppLeft' (S := S) x = finsuppLeft x :=
rfl

/- -- TODO : reprove using the existing heterobasic lemmas
noncomputable example :
(ι →₀ M) ⊗[R] N ≃ₗ[S] ι →₀ (M ⊗[R] N) := by
have f : (⨁ (i₁ : ι), M) ⊗[R] N ≃ₗ[S] ⨁ (i : ι), M ⊗[R] N := sorry
exact (AlgebraTensorModule.congr
(finsuppLEquivDirectSum S M ι) (LinearEquiv.refl R N)).trans
(f.trans (finsuppLEquivDirectSum S (M ⊗[R] N) ι).symm) -/

/-- The tensor product of `i →₀ R` and `N` is linearly equivalent to `i →₀ N` -/
AntoineChambert-Loir marked this conversation as resolved.
Show resolved Hide resolved
noncomputable def finsuppScalarLeft :
(ι →₀ R) ⊗[R] N ≃ₗ[R] ι →₀ N :=
finsuppLeft.trans (Finsupp.mapRange.linearEquiv (TensorProduct.lid R N))

lemma finsuppScalarLeft_apply_tmul_apply (p : ι →₀ R) (n : N) (i : ι) :
finsuppScalarLeft (p ⊗ₜ[R] n) i = (p i) • n := by
simp only [finsuppScalarLeft, LinearEquiv.trans_apply, finsuppLeft_apply_tmul,
Finsupp.mapRange.linearEquiv_apply, Finsupp.mapRange.linearMap_apply, LinearEquiv.coe_coe,
Finsupp.mapRange_apply, Finsupp.sum_apply]
apply symm
rw [← LinearEquiv.symm_apply_eq, lid_symm_apply]
rw [Finsupp.sum_eq_single i (fun _ _ => Finsupp.single_eq_of_ne) (fun _ => by simp)]
simp only [Finsupp.single_eq_same]
rw [tmul_smul, smul_tmul', smul_eq_mul, mul_one]

lemma finsuppScalarLeft_apply_tmul (p : ι →₀ R) (n : N) :
finsuppScalarLeft (p ⊗ₜ[R] n) = p.sum (fun i m ↦ Finsupp.single i (m • n)) := by
ext i
rw [finsuppScalarLeft_apply_tmul_apply]
simp only [Finsupp.sum_apply]
rw [Finsupp.sum_eq_single i (fun _ _ => Finsupp.single_eq_of_ne) (fun _ => by simp)]
simp only [Finsupp.single_eq_same]

lemma finsuppScalarLeft_symm_apply_single (i : ι) (n : N) :
finsuppScalarLeft.symm (Finsupp.single i n) =
(Finsupp.single i 1) ⊗ₜ[R] n := by
simp [finsuppScalarLeft, finsuppLeft_symm_apply_single]

/-- The tensor product of `M` and `ι →₀ R` is linearly equivalent to `ι →₀ N` -/
noncomputable def finsuppScalarRight :
M ⊗[R] (ι →₀ R) ≃ₗ[R] ι →₀ M :=
finsuppRight.trans (Finsupp.mapRange.linearEquiv (TensorProduct.rid R M))

lemma finsuppScalarRight_apply_tmul_apply (m : M) (p : ι →₀ R) (i : ι) :
finsuppScalarRight (m ⊗ₜ[R] p) i = (p i) • m := by
simp only [finsuppScalarRight, LinearEquiv.trans_apply, finsuppRight_apply_tmul,
Finsupp.mapRange.linearEquiv_apply, Finsupp.mapRange.linearMap_apply, LinearEquiv.coe_coe,
Finsupp.mapRange_apply, Finsupp.sum_apply]
apply symm
rw [← LinearEquiv.symm_apply_eq, rid_symm_apply]
rw [Finsupp.sum_eq_single i (fun _ _ => Finsupp.single_eq_of_ne) (fun _ => by simp)]
simp only [Finsupp.single_eq_same]
rw [smul_tmul, smul_eq_mul, mul_one]

lemma finsuppScalarRight_apply_tmul (m : M) (p : ι →₀ R) :
finsuppScalarRight (m ⊗ₜ[R] p) = p.sum (fun i n ↦ Finsupp.single i (n • m)) := by
ext i
rw [finsuppScalarRight_apply_tmul_apply]
simp only [Finsupp.sum_apply]
rw [Finsupp.sum_eq_single i (fun _ _ => Finsupp.single_eq_of_ne) (fun _ => by simp)]
simp only [Finsupp.single_eq_same]

lemma finsuppScalarRight_symm_apply_single (i : ι) (m : M) :
finsuppScalarRight.symm (Finsupp.single i m) =
m ⊗ₜ[R] (Finsupp.single i 1) := by
simp [finsuppScalarRight, finsuppRight_symm_apply_single]

end TensorProduct

end TensorProduct

open scoped Classical in
-- `noncomputable` is a performance workaround for mathlib4#7103
/-- The tensor product of `ι →₀ M` and `κ →₀ N` is linearly equivalent to `(ι × κ) →₀ (M ⊗ N)`. -/
noncomputable def finsuppTensorFinsupp (R M N ι κ : Sort _) [CommSemiring R] [AddCommMonoid M]
[Module R M] [AddCommMonoid N] [Module R N] : (ι →₀ M) ⊗[R] (κ →₀ N) ≃ₗ[R] ι × κ →₀ M ⊗[R] N :=
noncomputable def finsuppTensorFinsupp (R M N ι κ : Sort _)
[CommSemiring R] [AddCommMonoid M] [Module R M] [AddCommMonoid N] [Module R N] :
(ι →₀ M) ⊗[R] (κ →₀ N) ≃ₗ[R] ι × κ →₀ M ⊗[R] N :=
TensorProduct.congr (finsuppLEquivDirectSum R M ι) (finsuppLEquivDirectSum R N κ) ≪≫ₗ
((TensorProduct.directSum R (fun _ : ι => M) fun _ : κ => N) ≪≫ₗ
(finsuppLEquivDirectSum R (M ⊗[R] N) (ι × κ)).symm)
Expand Down Expand Up @@ -103,4 +308,4 @@ theorem finsuppTensorFinsupp'_single_tmul_single (a : α) (b : β) (r₁ r₂ :
aesop (add norm [Finsupp.single_apply])
#align finsupp_tensor_finsupp'_single_tmul_single finsuppTensorFinsupp'_single_tmul_single

end TensorProduct
end
Loading
Loading