Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/algebras/quatalg/quaternion_algebra_cython.pyx
4159 views
1
"""
2
Optimized Cython code needed by quaternion algebras.
3
4
This is a collection of miscellaneous routines that are in Cython for
5
speed purposes and are used by the quaternion algebra code. For
6
example, there are functions for quickly constructing an n x 4 matrix
7
from a list of n rational quaternions.
8
9
AUTHORS:
10
- William Stein
11
"""
12
13
########################################################################
14
# Copyright (C) 2009 William Stein <[email protected]>
15
#
16
# Distributed under the terms of the GNU General Public License (GPL)
17
#
18
# This code is distributed in the hope that it will be useful,
19
# but WITHOUT ANY WARRANTY; without even the implied warranty of
20
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21
# General Public License for more details.
22
#
23
# The full text of the GPL is available at:
24
#
25
# http://www.gnu.org/licenses/
26
########################################################################
27
28
29
include "../../ext/stdsage.pxi"
30
31
from sage.rings.integer_ring import ZZ
32
from sage.rings.rational_field import QQ
33
from sage.rings.integer cimport Integer
34
from sage.matrix.matrix_space import MatrixSpace
35
from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense
36
from sage.matrix.matrix_rational_dense cimport Matrix_rational_dense
37
38
from quaternion_algebra_element cimport QuaternionAlgebraElement_rational_field
39
40
from sage.libs.gmp.mpz cimport mpz_t, mpz_lcm, mpz_init, mpz_set, mpz_clear, mpz_init_set, mpz_mul, mpz_fdiv_q, mpz_cmp_si
41
from sage.libs.gmp.mpq cimport mpq_set_num, mpq_set_den, mpq_canonicalize
42
43
def integral_matrix_and_denom_from_rational_quaternions(v):
44
r"""
45
Given a list of rational quaternions, return matrix `A` over `\ZZ`
46
and denominator `d`, such that the rows of `(1/d)A` are the
47
entries of the quaternions.
48
49
INPUT:
50
- v -- a list of quaternions in a rational quaternion algebra
51
52
OUTPUT:
53
- a matrix over ZZ
54
- an integer (the common denominator)
55
56
EXAMPLES::
57
sage: A.<i,j,k>=QuaternionAlgebra(-4,-5)
58
sage: sage.algebras.quatalg.quaternion_algebra_cython.integral_matrix_and_denom_from_rational_quaternions([i/2,1/3+j+k])
59
(
60
[0 3 0 0]
61
[2 0 6 6], 6
62
)
63
"""
64
# This function is an optimized version of
65
# MatrixSpace(QQ,len(v),4)([x.coefficient_tuple() for x in v], coerce=False)._clear_denom
66
67
cdef Py_ssize_t i, n=len(v)
68
M = MatrixSpace(ZZ, n, 4)
69
cdef Matrix_integer_dense A = M.zero_matrix().__copy__()
70
if n == 0: return A
71
72
# Find least common multiple of the denominators
73
cdef QuaternionAlgebraElement_rational_field x
74
cdef Integer d = Integer()
75
# set denom to the denom of the first quaternion
76
x = v[0]; mpz_set(d.value, x.d)
77
for x in v[1:]:
78
mpz_lcm(d.value, d.value, x.d)
79
80
# Now fill in each row x of A, multiplying it by q = d/denom(x)
81
cdef mpz_t q
82
cdef mpz_t* row
83
mpz_init(q)
84
for i in range(n):
85
x = v[i]
86
mpz_fdiv_q(q, d.value, x.d)
87
mpz_mul(A._matrix[i][0], q, x.x)
88
mpz_mul(A._matrix[i][1], q, x.y)
89
mpz_mul(A._matrix[i][2], q, x.z)
90
mpz_mul(A._matrix[i][3], q, x.w)
91
mpz_clear(q)
92
return A, d
93
94
def rational_matrix_from_rational_quaternions(v):
95
"""
96
Return matrix over the rationals whose rows have entries the
97
coefficients of the rational quaternions in v.
98
99
INPUT:
100
- v -- a list of quaternions in a rational quaternion algebra
101
102
OUTPUT:
103
- a matrix over QQ
104
105
EXAMPLES::
106
sage: A.<i,j,k>=QuaternionAlgebra(-4,-5)
107
sage: sage.algebras.quatalg.quaternion_algebra_cython.rational_matrix_from_rational_quaternions([i/2,1/3+j+k])
108
[ 0 1/2 0 0]
109
[1/3 0 1 1]
110
"""
111
cdef Py_ssize_t i, j, n=len(v)
112
M = MatrixSpace(QQ, n, 4)
113
cdef Matrix_rational_dense A = M.zero_matrix().__copy__()
114
if n == 0: return A
115
116
cdef QuaternionAlgebraElement_rational_field x
117
for i in range(n):
118
x = v[i]
119
mpq_set_num(A._matrix[i][0], x.x)
120
mpq_set_num(A._matrix[i][1], x.y)
121
mpq_set_num(A._matrix[i][2], x.z)
122
mpq_set_num(A._matrix[i][3], x.w)
123
if mpz_cmp_si(x.d,1):
124
for j in range(4):
125
mpq_set_den(A._matrix[i][j], x.d)
126
mpq_canonicalize(A._matrix[i][j])
127
return A
128
129
def rational_quaternions_from_integral_matrix_and_denom(A, Matrix_integer_dense H, Integer d):
130
"""
131
Given an integral matrix and denominator, returns a list of rational quaternions.
132
133
INPUT:
134
- A -- rational quaternion algebra
135
- H -- matrix over the integers
136
- d -- integer
137
138
OUTPUT:
139
- list of H.nrows() elements of A
140
141
EXAMPLES::
142
143
sage: A.<i,j,k>=QuaternionAlgebra(-1,-2)
144
sage: f = sage.algebras.quatalg.quaternion_algebra_cython.rational_quaternions_from_integral_matrix_and_denom
145
sage: f(A, matrix([[1,2,3,4], [-1,2,-4,3]]), 3)
146
[1/3 + 2/3*i + j + 4/3*k, -1/3 + 2/3*i - 4/3*j + k]
147
"""
148
#
149
# This is an optimized version of the following interpreted Python code.
150
# H2 = H.change_ring(QQ)._rmul_(1/d)
151
# return [A(v.list()) for v in H2.rows()]
152
#
153
cdef QuaternionAlgebraElement_rational_field x
154
v = []
155
cdef Integer a, b
156
a = Integer(A.invariants()[0])
157
b = Integer(A.invariants()[1])
158
cdef Py_ssize_t i, j
159
for i in range(H.nrows()):
160
x = <QuaternionAlgebraElement_rational_field> PY_NEW(QuaternionAlgebraElement_rational_field)
161
x._parent = A
162
mpz_set(x.a, a.value)
163
mpz_set(x.b, b.value)
164
mpz_init_set(x.x, H._matrix[i][0])
165
mpz_init_set(x.y, H._matrix[i][1])
166
mpz_init_set(x.z, H._matrix[i][2])
167
mpz_init_set(x.w, H._matrix[i][3])
168
mpz_init_set(x.d, d.value)
169
# WARNING -- we do *not* canonicalize the entries in the quaternion. This is
170
# I think _not_ needed for quaternion_element.pyx
171
v.append(x)
172
return v
173
174
175
from sage.rings.rational_field import QQ
176
MS_16_4 = MatrixSpace(QQ,16,4)
177
178