3
$Assumptions = 
 x \[Element] Matrices[{2*M, 2*M}, Reals, Antisymmetric[{1, 2}]]

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

p[arg__] /; ! OrderedQ@{arg} := Signature@{arg} p @@ Sort@{arg}
p[___, j_, j_, ___] = 0;

Format[p[arg__]] := Subscript[p, arg]
test1 = (4 *p[4, i, k, l] *x[2, i] *x[k, 2] *x[l, 3]) + (4* 
    p[1, j, k, l] *x[2, j]* x[k, 2]* x[l, 2]) + (p[1, 2, 3, i]* 
    x[1, i])

I want to implement the above in such a way that repeated indices only summed up just as in Einstein summation convention. Any way to do this? When I perform summation as:

Sum[test1, {i, 4}] // Expand

I am getting:

Subscript[p, 1, 2, 3, 4] Subscript[x, 1, 4] + 
 16 Subscript[p, 1, j, k, l] Subscript[x, 2, j] Subscript[x, 2, k]
   Subscript[x, 2, l] + 
 4 Subscript[p, 1, 4, k, l] Subscript[x, 1, 2] Subscript[x, 2, k]
   Subscript[x, 3, l] - 
 4 Subscript[p, 3, 4, k, l] Subscript[x, 2, 3] Subscript[x, 2, k]
   Subscript[x, 3, l]

But I want to use Einstein summation convention in which only repeated indices sums up. Is there a way that Mathematica to perform summation only for repeated indices only,not for constants.

Jasmine
  • 1,225
  • 3
  • 10

1 Answers1

5

You are admittedly probably better off using a package such as the one @qahtah mentioned in the comments or the package xAct, but just for fun, here is a way of defining a function EinsteinSum which does what you're looking for—unless I've misunderstood. If you have any questions about why this works the way it does, or if I've misunderstood what you're looking for, let me know! :)

Clear[EinsteinSum]

EinsteinSum[Times[a___, (p_Symbol)[x___, i_Symbol, y___], b___, (q_Symbol)[w___, i_Symbol, z___], c___]] := EinsteinSum[ a b c With[{ii = Unique["ii"]}, Sum[p[x, ii, y] q[w, ii, z], {ii, 4}]]]

EinsteinSum[Times[a_, b__]] := EinsteinSum[Expand[a b]] /; ! SameQ[a b, Expand[a b]]

EinsteinSum[Plus[a_, b__]] := Plus @@ (EinsteinSum /@ {a, b})

EinsteinSum[x_] := x

Test:

test1 = (4 *p[4, i, k, l] *x[2, i] *x[k, 2] *x[l, 3]) + (4* 
    p[1, j, k, l] *x[2, j]* x[k, 2]* x[l, 2]) + (p[1, 2, 3, i]* 
    x[1, i])

EinsteinSum[test1]

(* Output: a huge expanded form *)

thorimur
  • 9,010
  • 18
  • 32
  • There is a small issue. In my case $Assumptions = x [Element] Matrices[{2M, 2M}, Reals, Antisymmetric[{1, 2}]]; x[arg__] /; ! OrderedQ@{arg} := Signature@{arg} x @@ Sort@{arg} Format[x[arg__]] := Subscript[x, arg]; p[arg__] /; ! OrderedQ@{arg} := Signature@{arg} p @@ Sort@{arg} p[___, j_, j_, ___] = 0; Format[p[arg__]] := Subscript[p, arg] So I define them as test1 = (4 p[4, i, k, l] x[2, i] x[k, 2] x[l, 3]) + (4* p[1, j, k, l] x[2, j] x[k, 2]* x[l, 2]) + (p[1, 2, 3, i]* x[1, I]) So your code is not working! – Jasmine Jul 13 '21 at 06:27
  • Your code is great. But can you please let me know how it works in this case – Jasmine Jul 13 '21 at 06:29
  • I have edited my question – Jasmine Jul 13 '21 at 06:36
  • @Jasmine ahhh, I see! I've edited my answer, but I still think it falls a bit short because it doesn't take dimensions into account. let me see. – thorimur Jul 13 '21 at 06:50
  • It's working perfectly for 4 case. Great code – Jasmine Jul 13 '21 at 06:56
  • 1
    @Jasmine glad it helps! :) I think we might be able to leverage TensorContract and mathematica's usage of $Assumptions to make it a bit more general. if I have time I'd like to come back and improve it tomorrow! – thorimur Jul 13 '21 at 07:00
  • 1
    That's great. Mainly it would be of great help if we can sum only desired indices at a time. For example at first if I want to sum repeated 'i' only that would be great. Also what about a summation with restriction. ie, summing indices with restriction. eg: How to implement i<j summations. – Jasmine Jul 13 '21 at 07:03