Path: blob/master/sage/algebras/quatalg/quaternion_algebra_cython.pyx
4159 views
"""1Optimized Cython code needed by quaternion algebras.23This is a collection of miscellaneous routines that are in Cython for4speed purposes and are used by the quaternion algebra code. For5example, there are functions for quickly constructing an n x 4 matrix6from a list of n rational quaternions.78AUTHORS:9- William Stein10"""1112########################################################################13# Copyright (C) 2009 William Stein <[email protected]>14#15# Distributed under the terms of the GNU General Public License (GPL)16#17# This code is distributed in the hope that it will be useful,18# but WITHOUT ANY WARRANTY; without even the implied warranty of19# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU20# General Public License for more details.21#22# The full text of the GPL is available at:23#24# http://www.gnu.org/licenses/25########################################################################262728include "../../ext/stdsage.pxi"2930from sage.rings.integer_ring import ZZ31from sage.rings.rational_field import QQ32from sage.rings.integer cimport Integer33from sage.matrix.matrix_space import MatrixSpace34from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense35from sage.matrix.matrix_rational_dense cimport Matrix_rational_dense3637from quaternion_algebra_element cimport QuaternionAlgebraElement_rational_field3839from 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_si40from sage.libs.gmp.mpq cimport mpq_set_num, mpq_set_den, mpq_canonicalize4142def integral_matrix_and_denom_from_rational_quaternions(v):43r"""44Given a list of rational quaternions, return matrix `A` over `\ZZ`45and denominator `d`, such that the rows of `(1/d)A` are the46entries of the quaternions.4748INPUT:49- v -- a list of quaternions in a rational quaternion algebra5051OUTPUT:52- a matrix over ZZ53- an integer (the common denominator)5455EXAMPLES::56sage: A.<i,j,k>=QuaternionAlgebra(-4,-5)57sage: sage.algebras.quatalg.quaternion_algebra_cython.integral_matrix_and_denom_from_rational_quaternions([i/2,1/3+j+k])58(59[0 3 0 0]60[2 0 6 6], 661)62"""63# This function is an optimized version of64# MatrixSpace(QQ,len(v),4)([x.coefficient_tuple() for x in v], coerce=False)._clear_denom6566cdef Py_ssize_t i, n=len(v)67M = MatrixSpace(ZZ, n, 4)68cdef Matrix_integer_dense A = M.zero_matrix().__copy__()69if n == 0: return A7071# Find least common multiple of the denominators72cdef QuaternionAlgebraElement_rational_field x73cdef Integer d = Integer()74# set denom to the denom of the first quaternion75x = v[0]; mpz_set(d.value, x.d)76for x in v[1:]:77mpz_lcm(d.value, d.value, x.d)7879# Now fill in each row x of A, multiplying it by q = d/denom(x)80cdef mpz_t q81cdef mpz_t* row82mpz_init(q)83for i in range(n):84x = v[i]85mpz_fdiv_q(q, d.value, x.d)86mpz_mul(A._matrix[i][0], q, x.x)87mpz_mul(A._matrix[i][1], q, x.y)88mpz_mul(A._matrix[i][2], q, x.z)89mpz_mul(A._matrix[i][3], q, x.w)90mpz_clear(q)91return A, d9293def rational_matrix_from_rational_quaternions(v):94"""95Return matrix over the rationals whose rows have entries the96coefficients of the rational quaternions in v.9798INPUT:99- v -- a list of quaternions in a rational quaternion algebra100101OUTPUT:102- a matrix over QQ103104EXAMPLES::105sage: A.<i,j,k>=QuaternionAlgebra(-4,-5)106sage: sage.algebras.quatalg.quaternion_algebra_cython.rational_matrix_from_rational_quaternions([i/2,1/3+j+k])107[ 0 1/2 0 0]108[1/3 0 1 1]109"""110cdef Py_ssize_t i, j, n=len(v)111M = MatrixSpace(QQ, n, 4)112cdef Matrix_rational_dense A = M.zero_matrix().__copy__()113if n == 0: return A114115cdef QuaternionAlgebraElement_rational_field x116for i in range(n):117x = v[i]118mpq_set_num(A._matrix[i][0], x.x)119mpq_set_num(A._matrix[i][1], x.y)120mpq_set_num(A._matrix[i][2], x.z)121mpq_set_num(A._matrix[i][3], x.w)122if mpz_cmp_si(x.d,1):123for j in range(4):124mpq_set_den(A._matrix[i][j], x.d)125mpq_canonicalize(A._matrix[i][j])126return A127128def rational_quaternions_from_integral_matrix_and_denom(A, Matrix_integer_dense H, Integer d):129"""130Given an integral matrix and denominator, returns a list of rational quaternions.131132INPUT:133- A -- rational quaternion algebra134- H -- matrix over the integers135- d -- integer136137OUTPUT:138- list of H.nrows() elements of A139140EXAMPLES::141142sage: A.<i,j,k>=QuaternionAlgebra(-1,-2)143sage: f = sage.algebras.quatalg.quaternion_algebra_cython.rational_quaternions_from_integral_matrix_and_denom144sage: f(A, matrix([[1,2,3,4], [-1,2,-4,3]]), 3)145[1/3 + 2/3*i + j + 4/3*k, -1/3 + 2/3*i - 4/3*j + k]146"""147#148# This is an optimized version of the following interpreted Python code.149# H2 = H.change_ring(QQ)._rmul_(1/d)150# return [A(v.list()) for v in H2.rows()]151#152cdef QuaternionAlgebraElement_rational_field x153v = []154cdef Integer a, b155a = Integer(A.invariants()[0])156b = Integer(A.invariants()[1])157cdef Py_ssize_t i, j158for i in range(H.nrows()):159x = <QuaternionAlgebraElement_rational_field> PY_NEW(QuaternionAlgebraElement_rational_field)160x._parent = A161mpz_set(x.a, a.value)162mpz_set(x.b, b.value)163mpz_init_set(x.x, H._matrix[i][0])164mpz_init_set(x.y, H._matrix[i][1])165mpz_init_set(x.z, H._matrix[i][2])166mpz_init_set(x.w, H._matrix[i][3])167mpz_init_set(x.d, d.value)168# WARNING -- we do *not* canonicalize the entries in the quaternion. This is169# I think _not_ needed for quaternion_element.pyx170v.append(x)171return v172173174from sage.rings.rational_field import QQ175MS_16_4 = MatrixSpace(QQ,16,4)176177178