def isVersor(self) -> bool: """Returns true if multivector is a versor. From :cite:`ga4cs` section 21.5, definition from 7.6.4 """ Vhat = self.gradeInvol() Vrev = ~self Vinv = Vrev / (self * Vrev)[()] # Test if the versor inverse (~V)/(V * ~V) is truly the inverse of the # multivector V if (Vhat * Vinv).grades(eps=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((Vhat * e * Vrev).grades(eps=0.000001) == {1} for e in cf.basis_vectors(self.layout).values()): return False return True
def basis_vectors(self): return cf.basis_vectors(self)