X-Git-Url: http://gitweb.michael.orlitzky.com/?a=blobdiff_plain;f=mjo%2Feja%2Feja_element.py;h=9fa8176d112668d6fed446ba5c174c7ebf618fbc;hb=9d365c6cf3b52024817cd2e97b1061216094e3df;hp=c5f0e77599e821ba153726c519b9f8dc9f9c8532;hpb=93e7b502538bd416c11a81cd0b8f47c24e934691;p=sage.d.git diff --git a/mjo/eja/eja_element.py b/mjo/eja/eja_element.py index c5f0e77..9fa8176 100644 --- a/mjo/eja/eja_element.py +++ b/mjo/eja/eja_element.py @@ -2,11 +2,6 @@ from sage.matrix.constructor import matrix from sage.modules.free_module import VectorSpace from sage.modules.with_basis.indexed_element import IndexedFreeModuleElement -# TODO: make this unnecessary somehow. -from sage.misc.lazy_import import lazy_import -lazy_import('mjo.eja.eja_algebra', 'FiniteDimensionalEuclideanJordanAlgebra') -lazy_import('mjo.eja.eja_element_subalgebra', - 'FiniteDimensionalEuclideanJordanElementSubalgebra') from mjo.eja.eja_operator import FiniteDimensionalEuclideanJordanAlgebraOperator from mjo.eja.eja_utils import _mat2vec @@ -345,6 +340,8 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement): sage: from mjo.eja.eja_algebra import (JordanSpinEJA, ....: TrivialEJA, + ....: RealSymmetricEJA, + ....: ComplexHermitianEJA, ....: random_eja) EXAMPLES:: @@ -392,6 +389,37 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement): sage: x,y = J.random_elements(2) sage: (x*y).det() == x.det()*y.det() True + + The determinant in matrix algebras is just the usual determinant:: + + sage: set_random_seed() + sage: X = matrix.random(QQ,3) + sage: X = X + X.T + sage: J1 = RealSymmetricEJA(3) + sage: J2 = RealSymmetricEJA(3,field=QQ,orthonormalize=False) + sage: expected = X.det() + sage: actual1 = J1(X).det() + sage: actual2 = J2(X).det() + sage: actual1 == expected + True + sage: actual2 == expected + True + + :: + + sage: set_random_seed() + sage: J1 = ComplexHermitianEJA(3) + sage: J2 = ComplexHermitianEJA(3,field=QQ,orthonormalize=False) + sage: X = matrix.random(GaussianIntegers(),3) + sage: X = X + X.H + sage: expected = AA(X.det()) + sage: actual1 = J1(J1.real_embed(X)).det() + sage: actual2 = J2(J2.real_embed(X)).det() + sage: expected == actual1 + True + sage: expected == actual2 + True + """ P = self.parent() r = P.rank() @@ -507,6 +535,14 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement): if not self.is_invertible(): raise ValueError("element is not invertible") + if self.parent()._charpoly_coefficients.is_in_cache(): + # We can invert using our charpoly if it will be fast to + # compute. If the coefficients are cached, our rank had + # better be too! + r = self.parent().rank() + a = self.characteristic_polynomial().coefficients(sparse=False) + return (-1)**(r+1)*sum(a[i+1]*self**i for i in range(r))/self.det() + return (~self.quadratic_representation())(self) @@ -520,9 +556,14 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement): zero, but we need the characteristic polynomial for the determinant. The minimal polynomial is a lot easier to get, so we use Corollary 2 in Chapter V of Koecher to check - whether or not the paren't algebra's zero element is a root + whether or not the parent algebra's zero element is a root of this element's minimal polynomial. + That is... unless the coefficients of our algebra's + "characteristic polynomial of" function are already cached! + In that case, we just use the determinant (which will be fast + as a result). + Beware that we can't use the superclass method, because it relies on the algebra being associative. @@ -553,6 +594,11 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement): else: return False + if self.parent()._charpoly_coefficients.is_in_cache(): + # The determinant will be quicker than computing the minimal + # polynomial from scratch, most likely. + return (not self.det().is_zero()) + # In fact, we only need to know if the constant term is non-zero, # so we can pass in the field's zero element instead. zero = self.base_ring().zero() @@ -932,7 +978,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement): sage: n_max = RealSymmetricEJA._max_random_instance_size() sage: n = ZZ.random_element(1, n_max) sage: J1 = RealSymmetricEJA(n) - sage: J2 = RealSymmetricEJA(n,normalize_basis=False) + sage: J2 = RealSymmetricEJA(n,orthonormalize=False) sage: X = random_matrix(AA,n) sage: X = X*X.transpose() sage: x1 = J1(X) @@ -958,15 +1004,16 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement): - def natural_representation(self): + def to_matrix(self): """ - Return a more-natural representation of this element. + Return an (often more natural) representation of this element as a + matrix. - Every finite-dimensional Euclidean Jordan Algebra is a - direct sum of five simple algebras, four of which comprise - Hermitian matrices. This method returns the original - "natural" representation of this element as a Hermitian - matrix, if it has one. If not, you get the usual representation. + Every finite-dimensional Euclidean Jordan Algebra is a direct + sum of five simple algebras, four of which comprise Hermitian + matrices. This method returns a "natural" matrix + representation of this element as either a Hermitian matrix or + column vector. SETUP:: @@ -978,7 +1025,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement): sage: J = ComplexHermitianEJA(3) sage: J.one() e0 + e3 + e8 - sage: J.one().natural_representation() + sage: J.one().to_matrix() [1 0 0 0 0 0] [0 1 0 0 0 0] [0 0 1 0 0 0] @@ -991,7 +1038,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement): sage: J = QuaternionHermitianEJA(3) sage: J.one() e0 + e5 + e14 - sage: J.one().natural_representation() + sage: J.one().to_matrix() [1 0 0 0 0 0 0 0 0 0 0 0] [0 1 0 0 0 0 0 0 0 0 0 0] [0 0 1 0 0 0 0 0 0 0 0 0] @@ -1004,11 +1051,14 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement): [0 0 0 0 0 0 0 0 0 1 0 0] [0 0 0 0 0 0 0 0 0 0 1 0] [0 0 0 0 0 0 0 0 0 0 0 1] - """ - B = self.parent().natural_basis() - W = self.parent().natural_basis_space() - return W.linear_combination(zip(B,self.to_vector())) + B = self.parent().matrix_basis() + W = self.parent().matrix_space() + + # This is just a manual "from_vector()", but of course + # matrix spaces aren't vector spaces in sage, so they + # don't have a from_vector() method. + return W.linear_combination( zip(B, self.to_vector()) ) def norm(self): @@ -1309,6 +1359,7 @@ class FiniteDimensionalEuclideanJordanAlgebraElement(IndexedFreeModuleElement): True """ + from mjo.eja.eja_element_subalgebra import FiniteDimensionalEuclideanJordanElementSubalgebra return FiniteDimensionalEuclideanJordanElementSubalgebra(self, orthonormalize_basis)