]> gitweb.michael.orlitzky.com - sage.d.git/blob - mjo/eja/euclidean_jordan_algebra.py
eja: implement my own algebra subclass.
[sage.d.git] / mjo / eja / euclidean_jordan_algebra.py
1 """
2 Euclidean Jordan Algebras. These are formally-real Jordan Algebras;
3 specifically those where u^2 + v^2 = 0 implies that u = v = 0. They
4 are used in optimization, and have some additional nice methods beyond
5 what can be supported in a general Jordan Algebra.
6 """
7
8 from sage.structure.unique_representation import UniqueRepresentation
9 from sage.algebras.finite_dimensional_algebras.finite_dimensional_algebra import FiniteDimensionalAlgebra
10
11 class FiniteDimensionalEuclideanJordanAlgebra(FiniteDimensionalAlgebra):
12 @staticmethod
13 def __classcall__(cls, field, mult_table, names='e', category=None):
14 fda = super(FiniteDimensionalEuclideanJordanAlgebra, cls)
15 return fda.__classcall_private__(cls,
16 field,
17 mult_table,
18 names,
19 category)
20
21 def __init__(self, field, mult_table, names='e', category=None):
22 fda = super(FiniteDimensionalEuclideanJordanAlgebra, self)
23 fda.__init__(field, mult_table, names, category)
24
25
26 def _repr_(self):
27 """
28 Return a string representation of ``self``.
29 """
30 return "Euclidean Jordan algebra of degree {} over {}".format(self.degree(), self.base_ring())
31
32
33
34 def eja_rn(dimension, field=QQ):
35 """
36 Return the Euclidean Jordan Algebra corresponding to the set
37 `R^n` under the Hadamard product.
38
39 EXAMPLES:
40
41 This multiplication table can be verified by hand::
42
43 sage: J = eja_rn(3)
44 sage: e0,e1,e2 = J.gens()
45 sage: e0*e0
46 e0
47 sage: e0*e1
48 0
49 sage: e0*e2
50 0
51 sage: e1*e1
52 e1
53 sage: e1*e2
54 0
55 sage: e2*e2
56 e2
57
58 """
59 # The FiniteDimensionalAlgebra constructor takes a list of
60 # matrices, the ith representing right multiplication by the ith
61 # basis element in the vector space. So if e_1 = (1,0,0), then
62 # right (Hadamard) multiplication of x by e_1 picks out the first
63 # component of x; and likewise for the ith basis element e_i.
64 Qs = [ matrix(field, dimension, dimension, lambda k,j: 1*(k == j == i))
65 for i in xrange(dimension) ]
66
67 # Assuming associativity is wrong here, but it works to
68 # temporarily trick the Jordan algebra constructor into using the
69 # multiplication table.
70 return FiniteDimensionalEuclideanJordanAlgebra(field,Qs)
71
72
73 def eja_ln(dimension, field=QQ):
74 """
75 Return the Jordan algebra corresponding to the Lorentz "ice cream"
76 cone of the given ``dimension``.
77
78 EXAMPLES:
79
80 This multiplication table can be verified by hand::
81
82 sage: J = eja_ln(4)
83 sage: e0,e1,e2,e3 = J.gens()
84 sage: e0*e0
85 e0
86 sage: e0*e1
87 e1
88 sage: e0*e2
89 e2
90 sage: e0*e3
91 e3
92 sage: e1*e2
93 0
94 sage: e1*e3
95 0
96 sage: e2*e3
97 0
98
99 In one dimension, this is the reals under multiplication::
100
101 sage: J1 = eja_ln(1)
102 sage: J2 = eja_rn(1)
103 sage: J1 == J2
104 True
105
106 """
107 Qs = []
108 id_matrix = identity_matrix(field,dimension)
109 for i in xrange(dimension):
110 ei = id_matrix.column(i)
111 Qi = zero_matrix(field,dimension)
112 Qi.set_row(0, ei)
113 Qi.set_column(0, ei)
114 Qi += diagonal_matrix(dimension, [ei[0]]*dimension)
115 # The addition of the diagonal matrix adds an extra ei[0] in the
116 # upper-left corner of the matrix.
117 Qi[0,0] = Qi[0,0] * ~field(2)
118 Qs.append(Qi)
119
120 return FiniteDimensionalEuclideanJordanAlgebra(field,Qs)