Last active
June 16, 2022 00:52
-
-
Save GregTJ/4abd00509a26b224551d3bacc6c38033 to your computer and use it in GitHub Desktop.
Levi-Civita symbol in n-dimensions.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sparse | |
from typing import Tuple, Generator | |
def sjt_permutations(n: int) -> Generator[Tuple[int], None, None]: | |
"""An implementation of the Steinhaus–Johnson–Trotter | |
algorithm with Even's speedup for generating | |
permutations in order of alternating parity.""" | |
# Each element of the permutation is | |
# initialized with a direction. | |
# All elements face left initially. | |
yield tuple(p := list(range(n))), (parity := 1) | |
d = [0] + [-1] * (n - 1) | |
# While any element is still directional, | |
while any(d): | |
# get the greatest element with nonzero direction, | |
# its index, and the index of the element it faces. | |
c, i, j = max((p[i], i, i + j) for i, j in enumerate(d) if j) | |
# All undirected elements greater than c have | |
# their directions set to face toward c. | |
d = [d[k] or (p[k] > c) * ((i > k) * 2 - 1) for k in range(n)] | |
# Swap the directions and elements at indices i and j. | |
# If the swap puts element c at the start or end | |
# of the permutation, or if the next element in the same direction | |
# is greater than c, zero out c's direction instead. | |
d[i], d[j] = d[j], 0 if j in {0, n - 1} or p[j + d[i]] > c else d[i] | |
p[i], p[j] = p[j], p[i] | |
# Permutation parity alternates. | |
yield tuple(p), (parity := -parity) | |
def levi_civita(n: int) -> sparse.COO: | |
"""Generates the sparse Levi-Civita symbol in n-dimensions.""" | |
p, v = zip(*sjt_permutations(n)) | |
return sparse.COO(tuple(zip(*p)), v, shape=(n,) * n) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
levi_civita(3).todense() output: