Source code for clifford._frame

import itertools
from functools import reduce

import numpy as np

from ._mvarray import MVArray
from ._multivector import MultiVector
from .operator import op
from . import _settings


[docs]class Frame(MVArray): ''' A frame of vectors ''' def __new__(cls, input_array): if not np.all([k.grades() == {1} for k in input_array]): raise TypeError('Frames must be made from vectors') obj = MVArray.__new__(cls, input_array) return obj def __array_finalize__(self, obj): if obj is None: return @property def En(self) -> MultiVector: r''' Volume element for this frame, :math:`E_n = e_1 \wedge e_2 \wedge \cdots \wedge e_n` ''' return reduce(op, self) @property def inv(self) -> 'Frame': ''' The inverse frame of self ''' En = self.En # see D&L sec 4.3 vectors = [ (-1)**(k)*reduce(op, np.hstack([self[:k], self[k+1:]]))*En.inv() for k in range(len(self))] return Frame(vectors)
[docs] def is_innermorphic_to(self, other: 'Frame', eps: float = None) -> bool: ''' Is this frame *innermorphic* to other? *innermorphic* means both frames share the same inner-product between corresponding vectors. This implies that the two frames are related by an orthogonal transform. ''' # make iterable `pairs` of all index combos, without repeat pairs = list(itertools.combinations(range(len(self)), 2)) a, b = self, other if eps is None: eps = _settings._eps return np.array([ float((b[m]|b[n]) - (a[m]|a[n])) < eps for m, n in pairs ]).all()