Skip to content

Commit f3ffc03

Browse files
committed
Simplify the implementation of ReciprocalFrame
This is fewer lines and more comments
1 parent 3ab7892 commit f3ffc03

File tree

1 file changed

+27
-35
lines changed

1 file changed

+27
-35
lines changed

galgebra/ga.py

+27-35
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import warnings
55
import operator
66
import copy
7-
from itertools import combinations
7+
import itertools
88
import functools
99
from functools import reduce
1010
from typing import Tuple, TypeVar, Callable, Dict, Sequence
@@ -790,7 +790,7 @@ def indexes(self) -> GradedTuple[Tuple[int, ...]]:
790790
""" Index tuples of basis blades """
791791
basis_indexes = tuple(self.n_range)
792792
return GradedTuple(
793-
tuple(combinations(basis_indexes, i))
793+
tuple(itertools.combinations(basis_indexes, i))
794794
for i in range(len(basis_indexes) + 1)
795795
)
796796

@@ -1998,51 +1998,43 @@ def ReciprocalFrame(self, basis: Sequence[_mv.Mv], mode: str = 'norm') -> Tuple[
19981998
Arbitrary strings are interpreted as ``"append"``, but in
19991999
future will be an error
20002000
"""
2001-
dim = len(basis)
2002-
2003-
indexes = tuple(range(dim))
2004-
index = [()]
2005-
2006-
for i in indexes[-2:]:
2007-
index.append(tuple(combinations(indexes, i + 1)))
2008-
2009-
MFbasis = []
2010-
2011-
for igrade in index[-2:]:
2012-
grade = []
2013-
for iblade in igrade:
2014-
blade = self.mv(S(1), 'scalar')
2015-
for ibasis in iblade:
2016-
blade ^= basis[ibasis]
2017-
blade = blade.trigsimp()
2018-
grade.append(blade)
2019-
MFbasis.append(grade)
2020-
E = MFbasis[-1][0]
2021-
E_sq = trigsimp((E * E).scalar())
20222001

2023-
duals = copy.copy(MFbasis[-2])
2002+
def wedge_reduce(mvs):
2003+
""" wedge together a list of multivectors """
2004+
if not mvs:
2005+
return self.mv(S(1), 'scalar')
2006+
return functools.reduce(operator.xor, mvs).trigsimp()
2007+
2008+
E = wedge_reduce(basis)
2009+
2010+
# elements are such that `basis[i] ^ co_basis[i] == E`
2011+
co_basis = [
2012+
sign * wedge_reduce(basis_subset)
2013+
for sign, basis_subset in zip(
2014+
# alternating signs
2015+
itertools.cycle([S(1), S(-1)]),
2016+
# tuples with one basis missing
2017+
itertools.combinations(basis, len(basis) - 1),
2018+
)
2019+
]
20242020

2025-
duals.reverse()
2026-
sgn = S(1)
2027-
rbasis = []
2028-
for dual in duals:
2029-
recpv = (sgn * dual * E).trigsimp()
2030-
rbasis.append(recpv)
2031-
sgn = -sgn
2021+
# take the dual without normalization
2022+
r_basis = [(co_base * E).trigsimp() for co_base in co_basis]
20322023

2024+
# normalize
2025+
E_sq = trigsimp((E * E).scalar())
20332026
if mode == 'norm':
2034-
for i in range(dim):
2035-
rbasis[i] = rbasis[i] / E_sq
2027+
r_basis = [r_base / E_sq for r_base in r_basis]
20362028
else:
20372029
if mode != 'append':
20382030
# galgebra 0.5.0
20392031
warnings.warn(
20402032
"Mode {!r} not understood, falling back to {!r} but this "
20412033
"is deprecated".format(mode, 'append'),
20422034
DeprecationWarning, stacklevel=2)
2043-
rbasis.append(E_sq)
2035+
r_basis.append(E_sq)
20442036

2045-
return tuple(rbasis)
2037+
return tuple(r_basis)
20462038

20472039
def Mlt(self, *args, **kwargs):
20482040
return lt.Mlt(args[0], self, *args[1:], **kwargs)

0 commit comments

Comments
 (0)