Closed
Description
Currently, outer product tensor contractions are broken:
julia> using TensorAlgebra: contract
julia> contract(randn(2, 2), ("i", "j"), randn(2, 2), ("k", "l"))
MethodError: no method matching output_axes(::typeof(contract), ::TensorAlgebra.BlockedPermutation{2, (2, 2), NTuple{4, Int64}}, ::Matrix{Float64}, ::TensorAlgebra.BlockedPermutation{1, (2,), Tuple{Int64, Int64}}, ::Matrix{Float64}, ::TensorAlgebra.BlockedPermutation{1, (2,), Tuple{Int64, Int64}}, ::Bool)
The function `output_axes` exists, but no method is defined for this combination of argument types.
Closest candidates are:
output_axes(::typeof(contract), ::TensorAlgebra.BlockedPermutation{0}, ::AbstractArray, ::TensorAlgebra.BlockedPermutation{1}, ::AbstractArray, ::TensorAlgebra.BlockedPermutation{1}, ::Number)
@ TensorAlgebra ~/.julia/packages/TensorAlgebra/WrWQd/src/contract/allocate_output.jl:23
output_axes(::typeof(contract), ::TensorAlgebra.BlockedPermutation{1}, ::AbstractArray, ::TensorAlgebra.BlockedPermutation{2}, ::AbstractArray, ::TensorAlgebra.BlockedPermutation{1}, ::Number)
@ TensorAlgebra ~/.julia/packages/TensorAlgebra/WrWQd/src/contract/allocate_output.jl:55
output_axes(::typeof(contract), ::TensorAlgebra.BlockedPermutation{2}, ::AbstractArray, ::TensorAlgebra.BlockedPermutation{2}, ::AbstractArray, ::TensorAlgebra.BlockedPermutation{2}, ::Number)
@ TensorAlgebra ~/.julia/packages/TensorAlgebra/WrWQd/src/contract/allocate_output.jl:5
...
Stacktrace:
[1] allocate_output(::typeof(contract), biperm_dest::TensorAlgebra.BlockedPermutation{2, (2, 2), NTuple{4, Int64}}, a1::Matrix{Float64}, biperm1::TensorAlgebra.BlockedPermutation{1, (2,), Tuple{Int64, Int64}}, a2::Matrix{Float64}, biperm2::TensorAlgebra.BlockedPermutation{1, (2,), Tuple{Int64, Int64}}, α::Bool)
@ TensorAlgebra ~/.julia/packages/TensorAlgebra/WrWQd/src/contract/allocate_output.jl:81
[2] contract(alg::TensorAlgebra.Matricize, biperm_dest::TensorAlgebra.BlockedPermutation{2, (2, 2), NTuple{4, Int64}}, a1::Matrix{Float64}, biperm1::TensorAlgebra.BlockedPermutation{1, (2,), Tuple{Int64, Int64}}, a2::Matrix{Float64}, biperm2::TensorAlgebra.BlockedPermutation{1, (2,), Tuple{Int64, Int64}}, α::Bool; kwargs::@Kwargs{})
@ TensorAlgebra ~/.julia/packages/TensorAlgebra/WrWQd/src/contract/contract.jl:121
[3] contract(alg::TensorAlgebra.Matricize, biperm_dest::TensorAlgebra.BlockedPermutation{2, (2, 2), NTuple{4, Int64}}, a1::Matrix{Float64}, biperm1::TensorAlgebra.BlockedPermutation{1, (2,), Tuple{Int64, Int64}}, a2::Matrix{Float64}, biperm2::TensorAlgebra.BlockedPermutation{1, (2,), Tuple{Int64, Int64}}, α::Bool)
@ TensorAlgebra ~/.julia/packages/TensorAlgebra/WrWQd/src/contract/contract.jl:111
[4] contract(alg::TensorAlgebra.Matricize, labels_dest::NTuple{4, String}, a1::Matrix{Float64}, labels1::Tuple{String, String}, a2::Matrix{Float64}, labels2::Tuple{String, String}, α::Bool; kwargs::@Kwargs{})
@ TensorAlgebra ~/.julia/packages/TensorAlgebra/WrWQd/src/contract/contract.jl:92
[5] contract(alg::TensorAlgebra.Matricize, labels_dest::NTuple{4, String}, a1::Matrix{Float64}, labels1::Tuple{String, String}, a2::Matrix{Float64}, labels2::Tuple{String, String}, α::Bool)
@ TensorAlgebra ~/.julia/packages/TensorAlgebra/WrWQd/src/contract/contract.jl:81
[6] contract(alg::TensorAlgebra.Matricize, a1::Matrix{Float64}, labels1::Tuple{String, String}, a2::Matrix{Float64}, labels2::Tuple{String, String}, α::Bool; kwargs::@Kwargs{})
@ TensorAlgebra ~/.julia/packages/TensorAlgebra/WrWQd/src/contract/contract.jl:49
[7] contract
@ ~/.julia/packages/TensorAlgebra/WrWQd/src/contract/contract.jl:39 [inlined]
[8] #contract#27
@ ~/.julia/packages/TensorAlgebra/WrWQd/src/contract/contract.jl:36 [inlined]
[9] contract
@ ~/.julia/packages/TensorAlgebra/WrWQd/src/contract/contract.jl:27 [inlined]
[10] contract(a1::Matrix{Float64}, labels1::Tuple{String, String}, a2::Matrix{Float64}, labels2::Tuple{String, String})
@ TensorAlgebra ~/.julia/packages/TensorAlgebra/WrWQd/src/contract/contract.jl:27
[11] top-level scope
@ REPL[4]:1
(as mentioned in #1 but I'm starting a new issue for visibility and discussion).
This should probably be written in terms of a lower level function devoted to performing tensor/outer products.
TensorOperations.jl calls this tensorproduct(...), and TensorCore.jl calls this tensor(...), with a unicode alias ⊗
. In NDTensors.jl, we call it outer(...).
Right now, I'm torn between the names tensorproduct
, outerproduct
, and outer
.