Skip to content

Commit

Permalink
Simplify the implementation of ReciprocalFrame
Browse files Browse the repository at this point in the history
This is fewer lines and more comments
  • Loading branch information
eric-wieser committed May 6, 2020
1 parent 3ab7892 commit f3ffc03
Showing 1 changed file with 27 additions and 35 deletions.
62 changes: 27 additions & 35 deletions galgebra/ga.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import warnings
import operator
import copy
from itertools import combinations
import itertools
import functools
from functools import reduce
from typing import Tuple, TypeVar, Callable, Dict, Sequence
Expand Down Expand Up @@ -790,7 +790,7 @@ def indexes(self) -> GradedTuple[Tuple[int, ...]]:
""" Index tuples of basis blades """
basis_indexes = tuple(self.n_range)
return GradedTuple(
tuple(combinations(basis_indexes, i))
tuple(itertools.combinations(basis_indexes, i))
for i in range(len(basis_indexes) + 1)
)

Expand Down Expand Up @@ -1998,51 +1998,43 @@ def ReciprocalFrame(self, basis: Sequence[_mv.Mv], mode: str = 'norm') -> Tuple[
Arbitrary strings are interpreted as ``"append"``, but in
future will be an error
"""
dim = len(basis)

indexes = tuple(range(dim))
index = [()]

for i in indexes[-2:]:
index.append(tuple(combinations(indexes, i + 1)))

MFbasis = []

for igrade in index[-2:]:
grade = []
for iblade in igrade:
blade = self.mv(S(1), 'scalar')
for ibasis in iblade:
blade ^= basis[ibasis]
blade = blade.trigsimp()
grade.append(blade)
MFbasis.append(grade)
E = MFbasis[-1][0]
E_sq = trigsimp((E * E).scalar())

duals = copy.copy(MFbasis[-2])
def wedge_reduce(mvs):
""" wedge together a list of multivectors """
if not mvs:
return self.mv(S(1), 'scalar')
return functools.reduce(operator.xor, mvs).trigsimp()

E = wedge_reduce(basis)

# elements are such that `basis[i] ^ co_basis[i] == E`
co_basis = [
sign * wedge_reduce(basis_subset)
for sign, basis_subset in zip(
# alternating signs
itertools.cycle([S(1), S(-1)]),
# tuples with one basis missing
itertools.combinations(basis, len(basis) - 1),
)
]

duals.reverse()
sgn = S(1)
rbasis = []
for dual in duals:
recpv = (sgn * dual * E).trigsimp()
rbasis.append(recpv)
sgn = -sgn
# take the dual without normalization
r_basis = [(co_base * E).trigsimp() for co_base in co_basis]

# normalize
E_sq = trigsimp((E * E).scalar())
if mode == 'norm':
for i in range(dim):
rbasis[i] = rbasis[i] / E_sq
r_basis = [r_base / E_sq for r_base in r_basis]
else:
if mode != 'append':
# galgebra 0.5.0
warnings.warn(
"Mode {!r} not understood, falling back to {!r} but this "
"is deprecated".format(mode, 'append'),
DeprecationWarning, stacklevel=2)
rbasis.append(E_sq)
r_basis.append(E_sq)

return tuple(rbasis)
return tuple(r_basis)

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

0 comments on commit f3ffc03

Please sign in to comment.