Source code for clifford._conformal_layout

import numpy as np

from ._layout import Layout
from ._multivector import MultiVector


[docs]class ConformalLayout(Layout): r""" A layout for a conformal algebra, which adds extra constants and helpers. Typically these should be constructed via :func:`clifford.conformalize`. .. versionadded:: 1.2.0 Attributes ---------- ep : MultiVector The first added basis element, :math:`e_{+}`, usually with :math:`e_{+}^2 = +1` en : MultiVector The first added basis element, :math:`e_{-}`, usually with :math:`e_{-}^2 = -1` eo : MultiVector The null basis vector at the origin, :math:`e_o = 0.5(e_{-} - e_{+})` einf : MultiVector The null vector at infinity, :math:`e_\infty = e_{-} + e_{+}` E0 : MultiVector The minkowski subspace bivector, :math:`e_\infty \wedge e_o` I_base : MultiVector The pseudoscalar of the base ga, in cga layout """
[docs] def __init__(self, *args, layout=None, **kwargs): super().__init__(*args, **kwargs) self._base_layout = layout basis_vectors = self.basis_vectors added_keys = sorted(basis_vectors.keys())[-2:] ep, en = [basis_vectors[k] for k in added_keys] # setup null basis, and minkowski subspace bivector eo = .5 ^ (en - ep) einf = en + ep E0 = einf ^ eo I_base = self.pseudoScalar*E0 # helper properties self.ep = ep self.en = en self.eo = eo self.einf = einf self.E0 = E0 self.I_base = I_base
@classmethod def _from_base_layout(cls, layout, added_sig=[1, -1], **kw) -> 'ConformalLayout': """ helper to implement :func:`clifford.conformalize` """ sig_c = list(layout.sig) + added_sig return cls._from_sig(sig=sig_c, firstIdx=layout.firstIdx, layout=layout, **kw) # some convenience functions
[docs] def up(self, x: MultiVector) -> MultiVector: """ up-project a vector from GA to CGA """ try: if x.layout == self._base_layout: # vector is in original space, map it into conformal space old_val = x.value new_val = np.zeros(self.gaDims) new_val[:len(old_val)] = old_val x = self.MultiVector(value=new_val) except(AttributeError): # if x is a scalar it doesnt have layout but following # will still work pass # then up-project into a null vector return x + (.5 ^ ((x**2)*self.einf)) + self.eo
[docs] def homo(self, x: MultiVector) -> MultiVector: """ homogenize a CGA vector """ return x/(-x | self.einf)[()]
[docs] def down(self, x: MultiVector) -> MultiVector: """ down-project a vector from CGA to GA """ x_down = (self.homo(x) ^ self.E0)*self.E0 # new_val = x_down.value[:self.base_layout.gaDims] # create vector in self.base_layout (not cga) # x_down = self.base_layout.MultiVector(value=new_val) return x_down