({{, (RefLink[TensorContract, paclet:ref/TensorContract])[tensor,{{(Subscript[s, 11]),(Subscript[s, 12])},{(Subscript[s, 21]),(Subscript[s, 22])},…}] 
yields the contraction of tensor in the pairs {(Subscript[s, i1]),(Subscript[s, i2])} of slots.}})

OpenersNotesSection(Spacer1)Details

The first argument of (RefLink[TensorContract, paclet:ref/TensorContract])[tensor,pairs] can be any tensorial object, in particular explicit or symbolic arrays, or combinations like tensor products, transpositions, etc.

The slots (Subscript[s, ij]) must all be different positive integers, not larger than the rank of the contracted tensor.

The slots contracted in each pair must all have the same dimensions, but different pairs might be associated to different dimensions.

For a symbolic tensor in the first argument of (RefLink[TensorContract, paclet:ref/TensorContract]), the contractions in the second argument are sorted, after sorting the slots in each contraction.

(RefLink[TensorContract, paclet:ref/TensorContract])[tensor,{}] returns tensor.

OpenersPrimaryExamplesSection(Spacer1)Examples  (15)

OpenersExampleSection0(Spacer1)Basic Examples  (3)

Contract slots 2 and 3 of a rank-3 array:

TensorContract[{{{(Subscript[a, 1,1,1]),(Subscript[a, 1,1,2])},{(Subscript[a, 1,2,1]),(Subscript[a, 1,2,2])}},{{(Subscript[a, 2,1,1]),(Subscript[a, 2,1,2])},{(Subscript[a, 2,2,1]),(Subscript[a, 2,2,2])}}},{{2,3}}]

Perform several contractions in an array:

A=Array[Subscript[a,##]&,{2,3,2,3}];

TensorContract[A,{{1,3},{2,4}}]

A symbolic array of rank 3:

$Assumptions=A∈Arrays[{3,2,3}];

Slots 1 and 3 can be contracted:

TensorContract[A,{{1,3}}]

Slots 1 and 2 cannot be contracted:

TensorContract[A,{{1,2}}]

OpenersExampleSection1(Spacer1)Scope  (3)

Contractions of arrays:

A1={{{a,b},{b,c}},{{f,g},{h,i}}};
TensorContract[A1,{{2,3}}]

A2=SparseArray[A1];
TensorContract[A2,{{2,3}}]

A3=SymmetrizedArray[A1];
TensorContract[A3,{{2,3}}]

Contraction of symbolic arrays:

$Assumptions=A∈Arrays[{d1,d1,d2,d2}];

TensorContract[A,{{3,4},{2,1}}]

TensorDimensions[%]

Report invalid contractions for symbolic arrays:

TensorContract[A,{{1,3}}]

Combining successive contractions:

TensorContract[TensorContract[A,{{1,3}}],{{1,2}}]

OpenersExampleSection2(Spacer1)Generalizations & Extensions  (1)

With arrays it is possible to use contractions of more than two slots, using the function SymbolicTensors`ArrayContract:

A=Array[Subscript[a,##]&,{3,2,3,2,3}];

SymbolicTensors`ArrayContract[A,{{1,3,5}}]

It is also possible to specify an arbitrary head, generalizing the role of (RefLink[Plus, paclet:ref/Plus]):

SymbolicTensors`ArrayContract[A,{{1,3,5}},g]

The contraction can be performed in such a way that levels stay inside the contraction head g:

SymbolicTensors`ArrayContract[A,{{2,4}},g,4]

OpenersExampleSection4(Spacer1)Properties & Relations  (7)

Contraction of the first levels of an array is equivalent to (RefLink[Tr, paclet:ref/Tr]):

A=Array[a,{3,3,3}];

TensorContract[A,{{1,2}}]===Tr[A,Plus,2]

Contraction of a tensor product of arrays is equivalent to (RefLink[Dot, paclet:ref/Dot]) and (RefLink[Inner, paclet:ref/Inner]):

A=Array[a,{2,2,2}];
B=Array[b,{2,2}];
F=Array[f,{2,3,2}];

(RefLink[Inner, paclet:ref/Inner]) performs one contraction between two arrays:

TensorContract[A⊗B,{{3,4}}]===Inner[Times,A,B]

(RefLink[Dot, paclet:ref/Dot]) with n arguments performs n-1 contractions among them:

TensorContract[A⊗B⊗F,{{3,4},{5,6}}]===Expand@Dot[A,B,F]

Arbitrary contractions can be also performed with a combination of (RefLink[Transpose, paclet:ref/Transpose]) and (RefLink[Apply, paclet:ref/Apply]):

A=Array[a,{2,3,2,3,2}];

TensorContract[A,{{1,5},{2,4}}]===Apply[Plus,Transpose[A,{2,3,1,3,2}],2]

Contraction of antisymmetric pairs of array levels gives zero:

A=SymmetrizedArray[pos_:>a@@pos,{3,3,3,3},{Antisymmetric[{1,2}],Antisymmetric[{3,4}]}]

TensorContract[A,{{1,2}}]

Normal[%]

Since levels one and three are not an antisymmetric pair, the result is not zero:

TensorContract[A,{{1,3}}]

Normal[%]

Contraction of antisymmetric symbolic arrays gives zero:

$Assumptions=A∈Arrays[{3,3,3,3},Complexes,Antisymmetric[{1,2,3}]];

TensorContract[A,{{1,3}}]//TensorReduce

In other cases, the expression is canonicalized, moving contractions to the last possible slots:

TensorContract[A,{{2,4}}]//TensorReduce

(RefLink[TensorContract, paclet:ref/TensorContract])[tensor,{}] returns tensor, irrespectively of what tensor is.

TensorContract[I,{}]

(RefLink[TensorContract, paclet:ref/TensorContract]), in combination with (RefLink[TensorProduct, paclet:ref/TensorProduct]), can be used to implement (RefLink[Dot, paclet:ref/Dot]):

v = Array[x,{3}];
a= Array[y, {3,3,3}];
m = Array[z,{3,3}];

v.a.m==TensorContract[v⊗a⊗m,{{1,2},{4,5}}]//Simplify

OpenersExampleSection5(Spacer1)Possible Issues  (1)

Invalid contractions are reported:

$Assumptions=A∈Arrays[{d1,d2,d1}];

TensorContract[A,{{2,3}}]

The expression becomes inert then:

TensorRank[%]

({{DocumentationFooterIconsRelatedFunction.png, ({{See Also}, {(RefLink[Tr, paclet:ref/Tr])  ▪  (RefLink[Transpose, paclet:ref/Transpose])  ▪  (RefLink[Inner, paclet:ref/Inner])  ▪  (RefLink[TensorProduct, paclet:ref/TensorProduct])  ▪  (RefLink[Dot, paclet:ref/Dot])}})}})

({{DocumentationFooterIconsRelatedTutorial.png, ({{Tutorials}, {▪(RefLinkPlain[Symbolic Tensors, paclet:tutorial/SymbolicTensors])}, {▪(RefLinkPlain[Tensor Symmetries, paclet:tutorial/TensorSymmetries])}, {▪(RefLinkPlain[Symmetrized Arrays, paclet:tutorial/SymmetrizedArrays])}})}})

({{DocumentationFooterIconsRelatedGuide.png, ({{Related Guides}, {▪(RefLinkPlain[Symbolic Tensors, paclet:guide/SymbolicTensors])}})}})