Re: Tensor Contraction
- To: mathgroup at smc.vnet.net
- Subject: [mg84553] Re: Tensor Contraction
- From: Carl Woll <carlw at wolfram.com>
- Date: Thu, 3 Jan 2008 20:28:15 -0500 (EST)
- References: <200801031034.FAA15837@smc.vnet.net>
Josh Burkart wrote: >Hello, > >I am having problems doing tensor contractions. I don't know of a standard way to do them in Mathematica, so I've been resorting to two methods. The first is clumsy and difficult for me to work with, and the second takes forever for some reason that escapes me and is also somewhat clumsy. > >The first is simply to use Dot[], which automatically contracts the last index of one tensor with the first index of another. This then involves judicious application of Transpose[], to get the right indices into place and then to put them back where they're supposed to be after applying Dot[]. It can also involve several applications of Dot[], depending on the number of contractions. I dislike this method since I can't really visualize what's happening; my (and I think the standard, in physics anyway) notation for tensor contraction is using the Einstein convention, for example something to the effect of (in latex) > >A^{\mu\nu}_{\sigma\rho} B^{\rho}_{\mu}, > >meaning contraction over \mu and \rho, leaving a two-index tensor with the ^\nu and _\sigma indices. This notation doesn't really "gel with" the Dot[] Transpose[] method. > > Why not use Flatten and Dot? The above example could be done using: Flatten[a, {{2},{3},{1,4}}] . Flatten[b, {{2,1}}] The {1,4} and {2,1} pieces mean contract index 1 of a with index 2 of b, and contract index 4 of a with index 1 of b. >The other method I've been using is to nest Sum[] inside of Table[], where the arguments of Sum[] are the indices to be summed over and the arguments of Table[] are the indices meant to remain in the resultant tensor. This tends to take a very long time, even when all I'm dealing with are (+/-)1's and 0's inside the tensor. It seems to me like it should be doing the same amount of calculation as the first method, but maybe I'm wrong and it's doing something superfluous a million times or something? For example, say I have two tensors which I name dtt and osp, 4-index and 2-index, respectively, and I want to perform the following contraction: > >dtt^{\mu\nu}_{\beta\alpha} dtt^{\rho\sigma}_{\nu\gamma} osp_{\mu\sigma}. > > I would do this in two steps, contracting dtt and dtt, and then contracting the result with osp. So: r1 = Flatten[dtt, {{1},{3},{4},{2}}] . Flatten[dtt, {{3},{1},{2},{4}}] producing an object with indices \mu \beta \alpha \rho \sigma \gamma. Then, contract r1 with osp: r2 = Flatten[r1, {{2},{3},{4},{6},{1,5}}] . Flatten[osp, {{1,2}}] If you want the order of indices of the final result to be \rho, \gamma, \alpha, and \beta, then you would use: r2 = Flatten[r1, {{4},{6},{3},{2},{1,5}}] . Flatten[osp] instead. One can use Flatten[osp] or Flatten[osp, {{1,2}}] as they do the same thing in this case. For your test case the above approach is a couple orders of magnitude quicker. Carl Woll Wolfram Research >This involves contraction/summation over the \mu, \nu, and \sigma indices, and results in a 4-index tensor with just the \rho, \gamma, \alpha, and \beta indices. Below is some code I've been using to do this contraction. The preliminary three functions which generate the tensors need not be scrutinized; each index goes from 1 to M inclusive; the last input, "F = ...", is where the contraction is being performed. On my system the contraction takes about 35 seconds, which is extremely excessive, given that the Dot[] Transpose[] method takes only a fraction of a second. > >------ >OrthosymplecticForm[p_Integer, Q_Integer?EvenQ] := > Join[PadRight[ > Join[PadLeft[-IdentityMatrix[p], {p, 2 p}], > PadRight[IdentityMatrix[p], {p, 2 p}]], {2 p, 2 p + Q}], > PadLeft[Join[PadLeft[IdentityMatrix[Q/2], {Q/2, Q}], > PadRight[IdentityMatrix[Q/2], {Q/2, Q}]], {Q, 2 p + Q}]]; > >DoubleTauFunction[a_, b_, c_, d_, p_, Q_] := > If[a != b || c != d, 0, If[a > 2 p && c > 2 p, -1, 1]]; > >DoubleTauTensor[p_, Q_] := > Table[DoubleTauFunction[a, b, c, d, p, Q], {a, 1, 2 p + Q}, {b, 1, > 2 p + Q}, {c, 1, 2 p + Q}, {d, 1, 2 p + Q}]; > >pp = 3; QQ = 4; >M = 2 pp + QQ; >dtt = DoubleTauTensor[pp, QQ]; >osp = OrthosymplecticForm[pp, QQ]; > >F = Table[ > Sum[dtt[[\[Mu], \[Beta], \[Nu], \[Alpha]]]* > dtt[[\[Rho], \[Nu], \[Sigma], \[Gamma]]]* > osp[[\[Mu], \[Sigma]]], {\[Mu], 1, M}, {\[Nu], 1, M}, {\[Sigma], > 1, M}], {\[Rho], 1, M}, {\[Gamma], 1, M}, {\[Alpha], 1, > M}, {\[Beta], 1, M}]; >------ > >So again, my questions are: 1) why does the Table[Sum[]] method take so long, and 2) are there better ways to do this? I've checked out some tensor calculus packages but haven't been too impressed. Also, more generally, when calculating using Mathematica, especially when doing numerics, I often notice that certain ways of doing things take absolutely inordinate amounts of time, while others take less time. I have little sense of which functions in Mathematica are most efficient for particular applications--any thing I should know? Any advice would be appreciated. > >Thanks, Josh B. > >
- References:
- Tensor Contraction
- From: Josh Burkart <jburkart@ucdavis.edu>
- Tensor Contraction