From 5d646c586de50b571d2983b546a05899bf0c20c2 Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Tue, 15 Oct 2019 08:28:08 -0400 Subject: [PATCH] eja: add a new TrivialEJA class and some tests for it. --- mjo/eja/all.py | 1 + mjo/eja/eja_algebra.py | 92 +++++++++++++++++++++++++++++------------ mjo/eja/eja_element.py | 25 ++++++++++- mjo/eja/eja_operator.py | 10 ++++- 4 files changed, 100 insertions(+), 28 deletions(-) diff --git a/mjo/eja/all.py b/mjo/eja/all.py index 41618ee..4f1af10 100644 --- a/mjo/eja/all.py +++ b/mjo/eja/all.py @@ -7,5 +7,6 @@ from mjo.eja.eja_algebra import (ComplexHermitianEJA, QuaternionHermitianEJA, RealCartesianProductEJA, RealSymmetricEJA, + TrivialEJA, random_eja) diff --git a/mjo/eja/eja_algebra.py b/mjo/eja/eja_algebra.py index 725cd71..12207b7 100644 --- a/mjo/eja/eja_algebra.py +++ b/mjo/eja/eja_algebra.py @@ -363,7 +363,7 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule): SETUP:: - sage: from mjo.eja.eja_algebra import JordanSpinEJA + sage: from mjo.eja.eja_algebra import JordanSpinEJA, TrivialEJA EXAMPLES: @@ -377,6 +377,16 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule): sage: p(*xvec) t^2 - 2*t + 1 + By definition, the characteristic polynomial is a monic + degree-zero polynomial in a rank-zero algebra. Note that + Cayley-Hamilton is indeed satisfied since the polynomial + ``1`` evaluates to the identity element of the algebra on + any argument:: + + sage: J = TrivialEJA() + sage: J.characteristic_polynomial() + 1 + """ r = self.rank() n = self.dimension() @@ -434,7 +444,8 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule): SETUP:: - sage: from mjo.eja.eja_algebra import ComplexHermitianEJA + sage: from mjo.eja.eja_algebra import (ComplexHermitianEJA, + ....: TrivialEJA) EXAMPLES:: @@ -442,6 +453,12 @@ class FiniteDimensionalEuclideanJordanAlgebra(CombinatorialFreeModule): sage: J.is_trivial() False + :: + + sage: J = TrivialEJA() + sage: J.is_trivial() + True + """ return self.dimension() == 0 @@ -759,6 +776,11 @@ class KnownRankEJA(object): Beware, this will crash for "most instances" because the constructor below looks wrong. """ + if cls is TrivialEJA: + # The TrivialEJA class doesn't take an "n" argument because + # there's only one. + return cls(field) + n = ZZ.random_element(cls._max_test_case_size()) + 1 return cls(n, field, **kwargs) @@ -837,32 +859,10 @@ class RealCartesianProductEJA(FiniteDimensionalEuclideanJordanAlgebra, return x.to_vector().inner_product(y.to_vector()) -def random_eja(field=QQ): +def random_eja(field=QQ, nontrivial=False): """ Return a "random" finite-dimensional Euclidean Jordan Algebra. - ALGORITHM: - - For now, we choose a random natural number ``n`` (greater than zero) - and then give you back one of the following: - - * The cartesian product of the rational numbers ``n`` times; this is - ``QQ^n`` with the Hadamard product. - - * The Jordan spin algebra on ``QQ^n``. - - * The ``n``-by-``n`` rational symmetric matrices with the symmetric - product. - - * The ``n``-by-``n`` complex-rational Hermitian matrices embedded - in the space of ``2n``-by-``2n`` real symmetric matrices. - - * The ``n``-by-``n`` quaternion-rational Hermitian matrices embedded - in the space of ``4n``-by-``4n`` real symmetric matrices. - - Later this might be extended to return Cartesian products of the - EJAs above. - SETUP:: sage: from mjo.eja.eja_algebra import random_eja @@ -873,7 +873,10 @@ def random_eja(field=QQ): Euclidean Jordan algebra of dimension... """ - classname = choice(KnownRankEJA.__subclasses__()) + eja_classes = KnownRankEJA.__subclasses__() + if nontrivial: + eja_classes.remove(TrivialEJA) + classname = choice(eja_classes) return classname.random_instance(field=field) @@ -1839,3 +1842,40 @@ class JordanSpinEJA(FiniteDimensionalEuclideanJordanAlgebra, KnownRankEJA): """ return x.to_vector().inner_product(y.to_vector()) + + +class TrivialEJA(FiniteDimensionalEuclideanJordanAlgebra, KnownRankEJA): + """ + The trivial Euclidean Jordan algebra consisting of only a zero element. + + SETUP:: + + sage: from mjo.eja.eja_algebra import TrivialEJA + + EXAMPLES:: + + sage: J = TrivialEJA() + sage: J.dimension() + 0 + sage: J.zero() + 0 + sage: J.one() + 0 + sage: 7*J.one()*12*J.one() + 0 + sage: J.one().inner_product(J.one()) + 0 + sage: J.one().norm() + 0 + sage: J.one().subalgebra_generated_by() + Euclidean Jordan algebra of dimension 0 over Rational Field + sage: J.rank() + 0 + + """ + def __init__(self, field=QQ, **kwargs): + mult_table = [] + fdeja = super(TrivialEJA, self) + # The rank is zero using my definition, namely the dimension of the + # largest subalgebra generated by any element. + return fdeja.__init__(field, mult_table, rank=0, **kwargs) diff --git a/mjo/eja/eja_element.py b/mjo/eja/eja_element.py index bd45b17..166c9d2 100644 --- a/mjo/eja/eja_element.py +++ b/mjo/eja/eja_element.py @@ -731,15 +731,29 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement): sage: from mjo.eja.eja_algebra import (JordanSpinEJA, ....: RealSymmetricEJA, + ....: TrivialEJA, ....: random_eja) + EXAMPLES: + + Keeping in mind that the polynomial ``1`` evaluates the identity + element (also the zero element) of the trivial algebra, it is clear + that the polynomial ``1`` is the minimal polynomial of the only + element in a trivial algebra:: + + sage: J = TrivialEJA() + sage: J.one().minimal_polynomial() + 1 + sage: J.zero().minimal_polynomial() + 1 + TESTS: The minimal polynomial of the identity and zero elements are always the same:: sage: set_random_seed() - sage: J = random_eja() + sage: J = random_eja(nontrivial=True) sage: J.one().minimal_polynomial() t - 1 sage: J.zero().minimal_polynomial() @@ -1217,14 +1231,23 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement): """ Return my trace, the sum of my eigenvalues. + In a trivial algebra, however you want to look at it, the trace is + an empty sum for which we declare the result to be zero. + SETUP:: sage: from mjo.eja.eja_algebra import (JordanSpinEJA, ....: RealCartesianProductEJA, + ....: TrivialEJA, ....: random_eja) EXAMPLES:: + sage: J = TrivialEJA() + sage: J.zero().trace() + 0 + + :: sage: J = JordanSpinEJA(3) sage: x = sum(J.gens()) sage: x.trace() diff --git a/mjo/eja/eja_operator.py b/mjo/eja/eja_operator.py index c073bc4..2a0c9c4 100644 --- a/mjo/eja/eja_operator.py +++ b/mjo/eja/eja_operator.py @@ -438,7 +438,9 @@ class FiniteDimensionalEuclideanJordanAlgebraOperator(Map): SETUP:: - sage: from mjo.eja.eja_algebra import RealSymmetricEJA, random_eja + sage: from mjo.eja.eja_algebra import (RealSymmetricEJA, + ....: TrivialEJA, + ....: random_eja) EXAMPLES:: @@ -453,6 +455,12 @@ class FiniteDimensionalEuclideanJordanAlgebraOperator(Map): sage: x.operator().is_invertible() True + The zero operator is invertible in a trivial algebra:: + + sage: J = TrivialEJA() + sage: J.zero().operator().is_invertible() + True + TESTS: The identity operator is always invertible:: -- 2.43.2