From 634dab08d886610e41dfd363a0a608a9405abe8e Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Fri, 2 Aug 2019 19:18:11 -0400 Subject: [PATCH] eja: move the element constructor into the parent algebra class. Instead of using the element's __init__(), we're now using the algebra's _element_constructor_() method that only gets called after the parent tries to coerce the argument and fails. This is somewhat cleaner because we don't have to handle the "usual" case. --- mjo/eja/eja_algebra.py | 62 +++++++++++++++++++++++++++++++++++++++++ mjo/eja/eja_element.py | 63 ------------------------------------------ 2 files changed, 62 insertions(+), 63 deletions(-) diff --git a/mjo/eja/eja_algebra.py b/mjo/eja/eja_algebra.py index c1d66dd..d06efb5 100644 --- a/mjo/eja/eja_algebra.py +++ b/mjo/eja/eja_algebra.py @@ -61,6 +61,68 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule): self.print_options(bracket='') + def _element_constructor_(self, elt): + """ + Construct an element of this algebra from its natural + representation. + + This gets called only after the parent element _call_ method + fails to find a coercion for the argument. + + SETUP:: + + sage: from mjo.eja.eja_algebra import (JordanSpinEJA, + ....: RealCartesianProductEJA, + ....: RealSymmetricEJA) + + EXAMPLES: + + The identity in `S^n` is converted to the identity in the EJA:: + + sage: J = RealSymmetricEJA(3) + sage: I = matrix.identity(QQ,3) + sage: J(I) == J.one() + True + + This skew-symmetric matrix can't be represented in the EJA:: + + sage: J = RealSymmetricEJA(3) + sage: A = matrix(QQ,3, lambda i,j: i-j) + sage: J(A) + Traceback (most recent call last): + ... + ArithmeticError: vector is not in free module + + TESTS: + + Ensure that we can convert any element of the two non-matrix + simple algebras (whose natural representations are their usual + vector representations) back and forth faithfully:: + + sage: set_random_seed() + sage: J = RealCartesianProductEJA(5) + sage: x = J.random_element() + sage: J(x.to_vector().column()) == x + True + sage: J = JordanSpinEJA(5) + sage: x = J.random_element() + sage: J(x.to_vector().column()) == x + True + + """ + natural_basis = self.natural_basis() + if elt not in natural_basis[0].matrix_space(): + raise ValueError("not a naturally-represented algebra element") + + # Thanks for nothing! Matrix spaces aren't vector + # spaces in Sage, so we have to figure out its + # natural-basis coordinates ourselves. + V = VectorSpace(elt.base_ring(), elt.nrows()*elt.ncols()) + W = V.span_of_basis( _mat2vec(s) for s in natural_basis ) + coords = W.coordinate_vector(_mat2vec(elt)) + return self.from_vector(coords) + + def _repr_(self): """ Return a string representation of ``self``. diff --git a/mjo/eja/eja_element.py b/mjo/eja/eja_element.py index fb19838..5b91424 100644 --- a/mjo/eja/eja_element.py +++ b/mjo/eja/eja_element.py @@ -25,69 +25,6 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement): dir(self.__class__) ) - def __init__(self, A, elt): - """ - - SETUP:: - - sage: from mjo.eja.eja_algebra import (RealSymmetricEJA, - ....: random_eja) - - EXAMPLES: - - The identity in `S^n` is converted to the identity in the EJA:: - - sage: J = RealSymmetricEJA(3) - sage: I = matrix.identity(QQ,3) - sage: J(I) == J.one() - True - - This skew-symmetric matrix can't be represented in the EJA:: - - sage: J = RealSymmetricEJA(3) - sage: A = matrix(QQ,3, lambda i,j: i-j) - sage: J(A) - Traceback (most recent call last): - ... - ArithmeticError: vector is not in free module - - TESTS: - - Ensure that we can convert any element of the parent's - underlying vector space back into an algebra element whose - vector representation is what we started with:: - - sage: set_random_seed() - sage: J = random_eja() - sage: v = J.vector_space().random_element() - sage: J(v).to_vector() == v - True - - """ - # Goal: if we're given a matrix, and if it lives in our - # parent algebra's "natural ambient space," convert it - # into an algebra element. - # - # The catch is, we make a recursive call after converting - # the given matrix into a vector that lives in the algebra. - # This we need to try the parent class initializer first, - # to avoid recursing forever if we're given something that - # already fits into the algebra, but also happens to live - # in the parent's "natural ambient space" (this happens with - # vectors in R^n). - ifme = super(FiniteDimensionalEuclideanJordanAlgebraElement, self) - try: - ifme.__init__(A, elt) - except ValueError: - natural_basis = A.natural_basis() - if elt in natural_basis[0].matrix_space(): - # Thanks for nothing! Matrix spaces aren't vector - # spaces in Sage, so we have to figure out its - # natural-basis coordinates ourselves. - V = VectorSpace(elt.base_ring(), elt.nrows()**2) - W = V.span( _mat2vec(s) for s in natural_basis ) - coords = W.coordinate_vector(_mat2vec(elt)) - ifme.__init__(A, coords) def __pow__(self, n): -- 2.44.2