Skip to content

Commit

Permalink
Change isBlade to work on denegerate metrics
Browse files Browse the repository at this point in the history
```python
>>> import clifford
>>> layout, _ = clifford.Cl(3, 0, 1, firstIdx=0)
>>> locals().update(layout.blades)
>>> e0.isBlade()
True
>>> e0.isBlade(invertible=True)
False
```
  • Loading branch information
eric-wieser committed Oct 22, 2019
1 parent ffc69b6 commit 7ac05e0
Showing 1 changed file with 19 additions and 6 deletions.
25 changes: 19 additions & 6 deletions clifford/_multivector.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import numbers
import math
from typing import List, Set, Tuple
import operator

import numpy as np

Expand Down Expand Up @@ -651,33 +652,45 @@ def isScalar(self) -> bool:

return True

def isBlade(self) -> bool:
def isBlade(self, *, invertible=False) -> bool:
"""Returns true if multivector is a blade.
"""
if len(self.grades()) != 1:
return False

return self.isVersor()
return self.isVersor(invertible=invertible)

def isVersor(self) -> bool:
def isVersor(self, *, invertible=True) -> bool:
"""Returns true if multivector is a versor.
From Leo Dorsts GA for computer science section 21.5, definition from 7.6.4
"""
if invertible:
grade_cmp = operator.eq
else:
grade_cmp = operator.le # subset

Vhat = self.gradeInvol()
Vrev = ~self
Vinv = Vrev/(self*Vrev)[0]
mag = (self*Vrev)[()]
if mag != 0:
# not strictly necessary, just scales to make eps appropriate below
Vinv = Vrev / mag
elif invertible:
return False
else:
Vinv = Vrev

# Test if the versor inverse (~V)/(V * ~V) is truly the inverse of the
# multivector V
if grades_present(Vhat*Vinv, 0.000001) != {0}:
if not grade_cmp(grades_present(Vhat*Vinv, 0.000001), {0}):
return False
if not np.sum(np.abs((Vhat*Vinv).value - (Vinv*Vhat).value)) < 0.0001:
return False

# applying a versor (and hence an invertible blade) to a vector should
# not change the grade
if not all(
grades_present(Vhat*e*Vrev, 0.000001) == {1}
grade_cmp(grades_present(Vhat*e*Vrev, 0.000001), {1})
for e in cf.basis_vectors(self.layout).values()
):
return False
Expand Down

0 comments on commit 7ac05e0

Please sign in to comment.