Path: blob/master/src/sage/matrix/matrix_modn_dense_double.pyx
8815 views
"""1Dense matrices over `\ZZ/n\ZZ` for `n < 2^{23}` using LinBox's ``Modular<double>``23AUTHORS:4- Burcin Erocal5- Martin Albrecht6"""7###############################################################################8# SAGE: Open Source Mathematical Software9# Copyright (C) 2011 Burcin Erocal <[email protected]>10# Copyright (C) 2011 Martin Albrecht <[email protected]>11# Distributed under the terms of the GNU General Public License (GPL),12# version 2 or any later version. The full text of the GPL is available at:13# http://www.gnu.org/licenses/14###############################################################################1516include "sage/ext/stdsage.pxi"17include "sage/ext/interrupt.pxi"1819from sage.rings.finite_rings.stdint cimport *2021from sage.libs.linbox.echelonform cimport BlasMatrixDouble as BlasMatrix22from sage.libs.linbox.modular cimport ModDoubleField as ModField, ModDoubleFieldElement as ModFieldElement23from sage.libs.linbox.echelonform cimport EchelonFormDomainDouble as EchelonFormDomain2425from sage.libs.linbox.fflas cimport ModDouble_fgemm as Mod_fgemm, ModDouble_fgemv as Mod_fgemv, \26ModDoubleDet as ModDet, \27ModDoubleRank as ModRank, ModDouble_echelon as Mod_echelon, \28ModDouble_applyp as Mod_applyp, \29ModDouble_MinPoly as Mod_MinPoly, \30ModDouble_CharPoly as Mod_CharPoly3132# Limit for LinBox Modular<double>33MAX_MODULUS = 2**233435from sage.rings.finite_rings.integer_mod cimport IntegerMod_int643637include "matrix_modn_dense_template.pxi"383940cdef class Matrix_modn_dense_double(Matrix_modn_dense_template):41r"""42Dense matrices over `\ZZ/n\ZZ` for `n < 2^{23}` using LinBox's ``Modular<double>``4344These are matrices with integer entries mod ``n`` represented as45floating-point numbers in a 64-bit word for use with LinBox routines.46This allows for ``n`` up to `2^{23}`. The analogous47``Matrix_modn_dense_float`` class is used for smaller moduli.4849Routines here are for the most basic access, see the50`matrix_modn_dense_template.pxi` file for higher-level routines.51"""5253def __cinit__(self):54"""55The Cython constructor5657TESTS::5859sage: A = random_matrix(IntegerModRing(2^16), 4, 4)60sage: type(A[0,0])61<type 'sage.rings.finite_rings.integer_mod.IntegerMod_int64'>62"""63self._get_template = self._base_ring.zero()64# note that INTEGER_MOD_INT32_LIMIT is ceil(sqrt(2^31-1)) < 2^2365self._fits_int32 = ((<Matrix_modn_dense_template>self).p <= INTEGER_MOD_INT32_LIMIT)6667cdef set_unsafe_int(self, Py_ssize_t i, Py_ssize_t j, int value):68r"""69Set the (i,j) entry of self to the int value.7071EXAMPLE::7273sage: A = random_matrix(GF(3016963), 4, 4); A74[ 220081 2824836 765701 2282256]75[1795330 767112 2967421 1373921]76[2757699 1142917 2720973 2877160]77[1674049 1341486 2641133 2173280]78sage: A[0,0] = 220082r; A79[ 220082 2824836 765701 2282256]80[1795330 767112 2967421 1373921]81[2757699 1142917 2720973 2877160]82[1674049 1341486 2641133 2173280]83sage: a = A[0,0]; a8422008285sage: ~a8628593588788sage: A = random_matrix(Integers(5099106), 4, 4); A89[2629491 1237101 2033003 3788106]90[4649912 1157595 4928315 4382585]91[4252686 978867 2601478 1759921]92[1303120 1860486 3405811 2203284]93sage: A[0,0] = 220082r; A94[ 220082 1237101 2033003 3788106]95[4649912 1157595 4928315 4382585]96[4252686 978867 2601478 1759921]97[1303120 1860486 3405811 2203284]98sage: a = A[0,0]; a99220082100sage: a*a1014777936102"""103self._matrix[i][j] = <double>value104105cdef set_unsafe(self, Py_ssize_t i, Py_ssize_t j, x):106r"""107Set the (i,j) entry with no bounds-checking, or any other checks.108109Assumes that `x` is in the base ring.110111EXAMPLE::112113sage: A = random_matrix(GF(3016963), 4, 4); A114[ 220081 2824836 765701 2282256]115[1795330 767112 2967421 1373921]116[2757699 1142917 2720973 2877160]117[1674049 1341486 2641133 2173280]118sage: K = A.base_ring()119sage: A[0,0] = K(220082); A120[ 220082 2824836 765701 2282256]121[1795330 767112 2967421 1373921]122[2757699 1142917 2720973 2877160]123[1674049 1341486 2641133 2173280]124sage: a = A[0,0]; a125220082126sage: ~a1272859358128129sage: A = random_matrix(Integers(5099106), 4, 4); A130[2629491 1237101 2033003 3788106]131[4649912 1157595 4928315 4382585]132[4252686 978867 2601478 1759921]133[1303120 1860486 3405811 2203284]134sage: K = A.base_ring()135sage: A[0,0] = K(220081)136sage: a = A[0,0]; a137220081138sage: a*a1394337773140"""141if (<Matrix_modn_dense_double>self)._fits_int32:142self._matrix[i][j] = <double>(<IntegerMod_int>x).ivalue143else:144self._matrix[i][j] = <double>(<IntegerMod_int64>x).ivalue145146cdef IntegerMod_abstract get_unsafe(self, Py_ssize_t i, Py_ssize_t j):147r"""148Return the (i,j) entry with no bounds-checking.149150OUTPUT:151152A :class:`sage.rings.finite_rings.integer_mod.IntegerMod_int`153or154:class:`sage.rings.finite_rings.integer_mod.IntegerMod_int64`155object, depending on the modulus.156157EXAMPLE::158159sage: A = random_matrix(GF(3016963), 4, 4); A160[ 220081 2824836 765701 2282256]161[1795330 767112 2967421 1373921]162[2757699 1142917 2720973 2877160]163[1674049 1341486 2641133 2173280]164sage: a = A[0,0]; a165220081166sage: ~a167697224168sage: K = A.base_ring()169sage: ~K(220081)170697224171172sage: A = random_matrix(Integers(5099106), 4, 4); A173[2629491 1237101 2033003 3788106]174[4649912 1157595 4928315 4382585]175[4252686 978867 2601478 1759921]176[1303120 1860486 3405811 2203284]177sage: a = A[0,1]; a1781237101179sage: a*a1803803997181sage: K = A.base_ring()182sage: K(1237101)^21833803997184"""185cdef Matrix_modn_dense_double _self = <Matrix_modn_dense_double>self186cdef double result = (<Matrix_modn_dense_template>self)._matrix[i][j]187if _self._fits_int32:188return (<IntegerMod_int>_self._get_template)._new_c(<int_fast32_t>result)189else:190return (<IntegerMod_int64>_self._get_template)._new_c(<int_fast64_t>result)191192193