I am looking for compact numpy
code to produce the Levi-Civita tensor in any user-selected number of dimensions. Any ideas?
Asked
Active
Viewed 3,119 times
1

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 Answers
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

JGibs
- 11
- 1