4

I have to sum: $$\frac{1}{2} x_{i,k} x_{j,\nu } g_{i,j,k,\mu }+\frac{1}{2} x_{i,k} x_{j,\mu } g_{i,j,k,\nu }+x_{i,l} x_{j,\nu } g_{i,j,l,\mu }+x_{i,\mu } x_{k,l} g_{i,k,l,\nu }$$

g and x are real antisymmetric tensors.

I have the following code to perform summation.

SumHeld /: MakeBoxes[SumHeld[expr_, ranges__], form_] := 
 MakeBoxes[Sum[expr, ranges], form]

SumHeld /: SyntaxInformation[ SumHeld] = {"LocalVariables" -> {"Table", {2, Infinity}}}; SumHeld /: c_?NumericQ SumHeld[rest_, range__] := SumHeld[c rest, range] IndexUnify[HoldPattern@Plus[sums : SumHeld[_, __] ..]] := Plus @@ With[{targetIndices = List @@ #[[-1, 2 ;;, 1]], sourceIndicesList = List @@@ #[[;; , 2 ;;, 1]]}, Function[{sum, sourceIndices}, sum /. Thread[ sourceIndices -> Take[targetIndices, Length@sourceIndices]]] @@@ Transpose@{#, sourceIndicesList}] &@ SortBy[Flatten /@ {sums}, Length]

SumTogether[HoldPattern@Plus[sums : SumHeld[_, sameRanges__] ..]] := SumHeld[Plus @@ {sums}[[;; , 1]], sameRanges] SumTogether[HoldPattern@Plus[sums : SumHeld[_, __] ..]] /; UnsameQ @@ {sums}[[;; , 2 ;;]] := Plus @@ SumTogether@*Plus @@@ GatherBy[{sums}, Rest]

SumHeld[expr_, {lst_List, dim_}] := (term |-> SumHeld[term, Sequence @@ Table[If[Count[term, patt, ∞] == 2, {patt, dim}, Nothing], {patt, lst}]]) /@ expr

It is simplifying to: $$\frac{3}{2} x_{i,l} x_{k,\nu } g_{i,k,l,\mu }+x_{i,\mu } x_{k,l} g_{i,k,l,\nu }+\frac{1}{2} x_{i,l} x_{k,\mu } g_{i,k,l,\nu }$$

by using the code:

 testl = 
 1/2 Subscript[g, i, j, k, ν] Subscript[x, i, k] Subscript[x, 
    j, μ] + 
  1/2 Subscript[g, i, j, k, μ] Subscript[x, i, k] Subscript[x, 
    j, ν] + 
  Subscript[g, i, j, l, μ] Subscript[x, i, l] Subscript[x, 
    j, ν] + 
  Subscript[g, i, k, l, ν] Subscript[x, i, μ] Subscript[x, k, 
    l]

1/2 Subscript[x, i, k] Subscript[x, j, ν] Subscript[g, i, j, k, μ] + 1/2 Subscript[x, i, k] Subscript[x, j, μ] Subscript[g, i, j, k, ν] + Subscript[x, i, l] Subscript[x, j, ν] Subscript[g, i, j, l, μ] + Subscript[x, i, μ] Subscript[x, k, l] Subscript[g, i, k, l, ν]

SumHeld[testl, {{i, j, k, l}, 5}];

% // IndexUnify;

% // SumTogether

But this can be further simplified as:

$$\frac{3}{2}x_{i,l}x_{k,\nu}g_{i,k,l,\mu}+x_{i,\mu}x_{k,l}g_{i,k,l,\nu}+\frac{1}{2}x_{i,l}x_{k,\mu}g_{i,k,l,\nu} =\frac{3}{2}x_{i,l}x_{k,\nu}g_{i,k,l,\mu}+x_{k,\mu}x_{i,l}g_{k,i,l,\nu}+\frac{1}{2}x_{i,l}x_{k,\mu}g_{i,k,l,\nu} =\frac{3}{2}x_{i,l}x_{k,\nu}g_{i,k,l,\mu}+x_{k,\mu}x_{i,l}g_{k,i,l,\nu}-\frac{1}{2}x_{i,l}x_{k,\mu}g_{k,i,l,\nu} =\frac{3}{2}x_{i,l}x_{k,\nu}g_{i,k,l,\mu}+\frac{1}{2}x_{k,\mu}x_{i,l}g_{k,i,l,\nu} $$

Is there any way to automatically do this?

xzczd
  • 65,995
  • 9
  • 163
  • 468
Jasmine
  • 1,225
  • 3
  • 10

1 Answers1

2

Here's my solution. First, make $x$ and $g$ antisymmetric with proper function definitions as I've done here:

Subscript[g, arg__] /; ! OrderedQ@{arg} := 
 Signature@{arg} Subscript[g, ##] & @@ Sort@{arg}
Subscript[x, arg__] /; ! OrderedQ@{arg} := 
 Signature@{arg} Subscript[x, ##] & @@ Sort@{arg}

Then define a function to rename the dummy indices. The underlying idea is similar with asd1dsa's IndexUnify, but I've sorted the indices so that the renaming will be done in a better way:

dummyunify[expr_Plus, 
  possibledummylst_] := (term |-> 
    Module[{indexlstold, indexlstnew, varlst = DeleteCases[List @@ term, _?AtomQ]}, 
     indexlstold = 
      DeleteDuplicates@
       Cases[SortBy[Last]@varlst, Alternatives @@ possibledummylst, ∞];
     indexlstnew = possibledummylst[[;; Length@indexlstold]];
     term /. Thread[indexlstold -> indexlstnew]]) /@ expr

Test:

dummyunify[testl, {i, j, k, l}]

$$\frac{1}{2} x_{i,j} x_{k,\mu } g_{i,j,k,\nu }-\frac{3}{2} x_{i,j} x_{k,\nu } g_{i,j,k,\mu }$$

xzczd
  • 65,995
  • 9
  • 163
  • 468