RE: Contracting More Than One Level in Tensor Products
- To: mathgroup at smc.vnet.net
- Subject: [mg35845] RE: [mg35830] Contracting More Than One Level in Tensor Products
- From: "Wolf, Hartmut" <Hartmut.Wolf at t-systems.com>
- Date: Sat, 3 Aug 2002 00:16:39 -0400 (EDT)
- Sender: owner-wri-mathgroup at wolfram.com
> -----Original Message----- > From: David Park [mailto:djmp at earthlink.net] To: mathgroup at smc.vnet.net > Sent: Friday, August 02, 2002 8:43 AM > Subject: [mg35845] [mg35830] Contracting More Than One Level in Tensor Products > > > If we want to contract two tensor arrays S and T in > Mathematica we can write > S.T. We could also use the Inner product. This will contract > the last level > of S with the first level of T. > > I would like to know how to contract more than one pair of > levels. Suppose S > and T are 3rd order tensors and I want to contract the last > two levels of S > with the first two levels of T. How can I do that? > > Or suppose I wanted to contract all three levels. For example with... > > Smat = Array[S, {3, 3, 3}] > Tmat = Array[T, {3, 3, 3}] > > I would like to obtain the answer... > > Smat Transpose[Tmat, {3, 2, 1}] > Plus @@ Flatten[%] > > but by a more general method. That is, I would like to > contract any number > of adjacent levels in two tensors. > > Thanks for any guidance on this. > > David Park > djmp at earthlink.net > http://home.earthlink.net/~djmp/ > > Dear David, just to pass an idea (I haven't got the time to test it extensively, esp. not for performance). (1) define a tensor product TensorProduct[s_, t_] := Outer[List, s].List[t] This just maps S_a,b,c,... x T_u,v,w,... --> S_a,b,c,... T_u,v,w,... i.e. the result is one tensor. (2) define a function do contractions on (muliple) indices of a tensor Contract[tt_, inxs : {_, _} ..] := Nest[Tr[#, Plus, 2] &, Transpose[tt, Block[{x = Range[TensorRank[tt]]}, x[[Join[inxs, Delete[x, List /@ Join[inxs]]]]] = x; x] ], Length[{inxs}]] Now you man do different things: a = Array[A, {2, 3, 3, 2}]; Contract[a, {2, 3}] % // Dimensions Contract[a, {1, 4}] % // Dimensions Contract[a, {2, 3}, {1, 4}] Contract[a, {1, 4}, {2, 3}] Sum[Sum[a[[i, j, j, i]], {j, 3}], {i, 2}] s=Array[S,{2,2,3}] t=Array[T,{3,2,2}] r=s.t Dimensions[r] Contract[TensorProduct[s, t], {3, 4}] == r Contract[TensorProduct[s, t], {3, 4}, {1, 6}] % // Dimensions Needless to say that for production purposes tests for compatible tensor Dimensions have to be made prior. Also doing the trivial Transpose has to be avoided (on performance reasons). Perhaps for better performance you may mix this idea here with a application of Dot (to avoid TensorProduct and one nesting layer of Tr), but this makes more complicated coding (I haven't got the time to make it). The function to define the transpose prescription list is somewhat awkward, perhaps you will find something better. Anyways, I hope this is of some help. Yours, Hartmut