ITensor / NDTensors.jl

A Julia package for n-dimensional sparse tensors.
Apache License 2.0
27 stars 7 forks source link

Generalize `contract` to accept any valid labels #5

Open emstoudenmire opened 4 years ago

emstoudenmire commented 4 years ago

The contract function, at least for the case of Dense tensors, currently only succeeds when the labels arguments obey certain conventions, as shown in the example code below. It would be good to generalize contract so that any valid labels (meaning distinct integers for non-contracted indices, and matching integers for contracted indices) would be accepted.

In this sample code, the call to contract making C1 succeeds, but the second call fails with the error shown below:

using NDTensors

let
  A = Tensor(2,3,4)
  B = Tensor(4,2)
  randn!(A)
  randn!(B)

  C1 = contract(A,(-1,1,2),B,(3,-1))
  @show C1[1,1,1] ≈ A[1,1,1]*B[1,1]+A[2,1,1]*B[1,2]

  C2 = contract(A,(1,2,3),B,(4,3))
  @show C2[1,1,1] ≈ A[1,1,1]*B[1,1]+A[2,1,1]*B[1,2]
end

The error:

[1] error(::String) at ./error.jl:33 [2] is_trivial_permutation(::NTuple{5,Int64}) at /mnt/home/mstoudenmire/.julia/packages/NDTensors/mBPTL/src/tupletools.jl:84 [3] contract!!(::Tensor{Float64,5,Dense{Float64,Array{Float64,1}},NTuple{5,Int64}}, ::NTuple{5,Int64}, ::Tensor{Float64,3,Dense{Float64,Array{Float64,1}},Tuple{Int64,Int64,Int64}}, ::Tuple{Int64,Int64,Int64}, ::Tensor{Float64,2,Dense{Float64,Array{Float64,1}},Tuple{Int64,Int64}}, ::Tuple{Int64,Int64}, ::Int64, ::Int64) at /mnt/home/mstoudenmire/.julia/packages/NDTensors/mBPTL/src/dense.jl:440 [4] contract!! at /mnt/home/mstoudenmire/.julia/packages/NDTensors/mBPTL/src/dense.jl:419 [inlined] [5] contract(::Tensor{Float64,3,Dense{Float64,Array{Float64,1}},Tuple{Int64,Int64,Int64}}, ::Tuple{Int64,Int64,Int64}, ::Tensor{Float64,2,Dense{Float64,Array{Float64,1}},Tuple{Int64,Int64}}, ::Tuple{Int64,Int64}, ::NTuple{5,Int64}) at /mnt/home/mstoudenmire/.julia/packages/NDTensors/mBPTL/src/dense.jl:407 [6] contract(::Tensor{Float64,3,Dense{Float64,Array{Float64,1}},Tuple{Int64,Int64,Int64}}, ::Tuple{Int64,Int64,Int64}, ::Tensor{Float64,2,Dense{Float64,Array{Float64,1}},Tuple{Int64,Int64}}, ::Tuple{Int64,Int64}) at /mnt/home/mstoudenmire/.julia/packages/NDTensors/mBPTL/src/dense.jl:404 [7] top-level scope at /mnt/home/mstoudenmire/ndtensors_test.jl:12

mtfishman commented 4 years ago

We could also generalize it to accept any collections of values that have equality defined, i.e. allow symbols or strings as well:

contract(A,(:a,:b,:c),B,(:d,:a))

We should be able to use set function for this, it should basically be setdiff(labelsA, labelsB).

emstoudenmire commented 4 years ago

Yes, it would be great to be able to use strings or symbols, etc. as well.

emstoudenmire commented 3 years ago

Finally, it would be good too if the labels were allowed to be Vectors as well as tuples. I think only tuples work in practice currently.