1

I am looking for compact numpy code to produce the Levi-Civita tensor in any user-selected number of dimensions. Any ideas?

bob.sacamento
  • 6,283
  • 10
  • 56
  • 115
  • Have you tried anything yet? You can post code here for people to look at and someone can help you work on it or fix it. – cmxu Jan 14 '20 at 20:26
  • `einsum` and `cross` related: https://stackoverflow.com/questions/20889514/special-tensor-contraction-in-python, https://stackoverflow.com/questions/20908754/how-to-speed-up-a-vector-cross-product-calculation. `sympy` related: https://stackoverflow.com/questions/46005704/levicivita-tensor-in-sympy-tensor-package – hpaulj Jan 14 '20 at 21:24
  • @cmxu What can I say? I tried a couple of algorithms I came up with myself, but the result was no good. Didn't see the point in wasting anyone's time with them. – bob.sacamento Jan 14 '20 at 22:23
  • That's not the kind of attitude that will generate much interest. Most of us are more interested in fixing things, and helping others work through problems. Yes, someone must have worked out general code for their own work, but they might not be hanging around SO today. – hpaulj Jan 14 '20 at 22:36

2 Answers2

1

From the sympy tensor functions:

In [13]: tensor_functions.eval_levicivita(x,y,z)                                                 
Out[13]: 
(-x + y)⋅(-x + z)⋅(-y + z)
──────────────────────────
            2    

def eval_levicivita(*args):
    """Evaluate Levi-Civita symbol."""
    from sympy import factorial
    n = len(args)
    return prod(
        prod(args[j] - args[i] for j in range(i + 1, n))
        / factorial(i) for i in range(n))
File:      /usr/local/lib/python3.6/dist-packages/sympy/functions/special/tensor_functions.py
Type:      function

For a reasonable number of dimensions the tensor size isn't that big, so I wouldn't worry about efficiency. For a start I'd try an iterative solution; it doesn't need to be fancy.

hpaulj
  • 221,503
  • 14
  • 230
  • 353
1

Using itertools

import numpy as np
import itertools
def levi_cevita_tensor(dim):   
    arr=np.zeros(tuple([dim for _ in range(dim)]))
    for x in itertools.permutations(tuple(range(dim))):
        mat = np.zeros((dim, dim), dtype=np.int32)
        for i, j in zip(range(dim), x):
            mat[i, j] = 1
        arr[x]=int(np.linalg.det(mat))
    return arr

https://en.wikipedia.org/wiki/Levi-Civita_symbol#Product

JGibs
  • 11
  • 1