Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/matrix/matrix_modn_dense_double.pyx
8815 views
1
"""
2
Dense matrices over `\ZZ/n\ZZ` for `n < 2^{23}` using LinBox's ``Modular<double>``
3
4
AUTHORS:
5
- Burcin Erocal
6
- Martin Albrecht
7
"""
8
###############################################################################
9
# SAGE: Open Source Mathematical Software
10
# Copyright (C) 2011 Burcin Erocal <[email protected]>
11
# Copyright (C) 2011 Martin Albrecht <[email protected]>
12
# Distributed under the terms of the GNU General Public License (GPL),
13
# version 2 or any later version. The full text of the GPL is available at:
14
# http://www.gnu.org/licenses/
15
###############################################################################
16
17
include "sage/ext/stdsage.pxi"
18
include "sage/ext/interrupt.pxi"
19
20
from sage.rings.finite_rings.stdint cimport *
21
22
from sage.libs.linbox.echelonform cimport BlasMatrixDouble as BlasMatrix
23
from sage.libs.linbox.modular cimport ModDoubleField as ModField, ModDoubleFieldElement as ModFieldElement
24
from sage.libs.linbox.echelonform cimport EchelonFormDomainDouble as EchelonFormDomain
25
26
from sage.libs.linbox.fflas cimport ModDouble_fgemm as Mod_fgemm, ModDouble_fgemv as Mod_fgemv, \
27
ModDoubleDet as ModDet, \
28
ModDoubleRank as ModRank, ModDouble_echelon as Mod_echelon, \
29
ModDouble_applyp as Mod_applyp, \
30
ModDouble_MinPoly as Mod_MinPoly, \
31
ModDouble_CharPoly as Mod_CharPoly
32
33
# Limit for LinBox Modular<double>
34
MAX_MODULUS = 2**23
35
36
from sage.rings.finite_rings.integer_mod cimport IntegerMod_int64
37
38
include "matrix_modn_dense_template.pxi"
39
40
41
cdef class Matrix_modn_dense_double(Matrix_modn_dense_template):
42
r"""
43
Dense matrices over `\ZZ/n\ZZ` for `n < 2^{23}` using LinBox's ``Modular<double>``
44
45
These are matrices with integer entries mod ``n`` represented as
46
floating-point numbers in a 64-bit word for use with LinBox routines.
47
This allows for ``n`` up to `2^{23}`. The analogous
48
``Matrix_modn_dense_float`` class is used for smaller moduli.
49
50
Routines here are for the most basic access, see the
51
`matrix_modn_dense_template.pxi` file for higher-level routines.
52
"""
53
54
def __cinit__(self):
55
"""
56
The Cython constructor
57
58
TESTS::
59
60
sage: A = random_matrix(IntegerModRing(2^16), 4, 4)
61
sage: type(A[0,0])
62
<type 'sage.rings.finite_rings.integer_mod.IntegerMod_int64'>
63
"""
64
self._get_template = self._base_ring.zero()
65
# note that INTEGER_MOD_INT32_LIMIT is ceil(sqrt(2^31-1)) < 2^23
66
self._fits_int32 = ((<Matrix_modn_dense_template>self).p <= INTEGER_MOD_INT32_LIMIT)
67
68
cdef set_unsafe_int(self, Py_ssize_t i, Py_ssize_t j, int value):
69
r"""
70
Set the (i,j) entry of self to the int value.
71
72
EXAMPLE::
73
74
sage: A = random_matrix(GF(3016963), 4, 4); A
75
[ 220081 2824836 765701 2282256]
76
[1795330 767112 2967421 1373921]
77
[2757699 1142917 2720973 2877160]
78
[1674049 1341486 2641133 2173280]
79
sage: A[0,0] = 220082r; A
80
[ 220082 2824836 765701 2282256]
81
[1795330 767112 2967421 1373921]
82
[2757699 1142917 2720973 2877160]
83
[1674049 1341486 2641133 2173280]
84
sage: a = A[0,0]; a
85
220082
86
sage: ~a
87
2859358
88
89
sage: A = random_matrix(Integers(5099106), 4, 4); A
90
[2629491 1237101 2033003 3788106]
91
[4649912 1157595 4928315 4382585]
92
[4252686 978867 2601478 1759921]
93
[1303120 1860486 3405811 2203284]
94
sage: A[0,0] = 220082r; A
95
[ 220082 1237101 2033003 3788106]
96
[4649912 1157595 4928315 4382585]
97
[4252686 978867 2601478 1759921]
98
[1303120 1860486 3405811 2203284]
99
sage: a = A[0,0]; a
100
220082
101
sage: a*a
102
4777936
103
"""
104
self._matrix[i][j] = <double>value
105
106
cdef set_unsafe(self, Py_ssize_t i, Py_ssize_t j, x):
107
r"""
108
Set the (i,j) entry with no bounds-checking, or any other checks.
109
110
Assumes that `x` is in the base ring.
111
112
EXAMPLE::
113
114
sage: A = random_matrix(GF(3016963), 4, 4); A
115
[ 220081 2824836 765701 2282256]
116
[1795330 767112 2967421 1373921]
117
[2757699 1142917 2720973 2877160]
118
[1674049 1341486 2641133 2173280]
119
sage: K = A.base_ring()
120
sage: A[0,0] = K(220082); A
121
[ 220082 2824836 765701 2282256]
122
[1795330 767112 2967421 1373921]
123
[2757699 1142917 2720973 2877160]
124
[1674049 1341486 2641133 2173280]
125
sage: a = A[0,0]; a
126
220082
127
sage: ~a
128
2859358
129
130
sage: A = random_matrix(Integers(5099106), 4, 4); A
131
[2629491 1237101 2033003 3788106]
132
[4649912 1157595 4928315 4382585]
133
[4252686 978867 2601478 1759921]
134
[1303120 1860486 3405811 2203284]
135
sage: K = A.base_ring()
136
sage: A[0,0] = K(220081)
137
sage: a = A[0,0]; a
138
220081
139
sage: a*a
140
4337773
141
"""
142
if (<Matrix_modn_dense_double>self)._fits_int32:
143
self._matrix[i][j] = <double>(<IntegerMod_int>x).ivalue
144
else:
145
self._matrix[i][j] = <double>(<IntegerMod_int64>x).ivalue
146
147
cdef IntegerMod_abstract get_unsafe(self, Py_ssize_t i, Py_ssize_t j):
148
r"""
149
Return the (i,j) entry with no bounds-checking.
150
151
OUTPUT:
152
153
A :class:`sage.rings.finite_rings.integer_mod.IntegerMod_int`
154
or
155
:class:`sage.rings.finite_rings.integer_mod.IntegerMod_int64`
156
object, depending on the modulus.
157
158
EXAMPLE::
159
160
sage: A = random_matrix(GF(3016963), 4, 4); A
161
[ 220081 2824836 765701 2282256]
162
[1795330 767112 2967421 1373921]
163
[2757699 1142917 2720973 2877160]
164
[1674049 1341486 2641133 2173280]
165
sage: a = A[0,0]; a
166
220081
167
sage: ~a
168
697224
169
sage: K = A.base_ring()
170
sage: ~K(220081)
171
697224
172
173
sage: A = random_matrix(Integers(5099106), 4, 4); A
174
[2629491 1237101 2033003 3788106]
175
[4649912 1157595 4928315 4382585]
176
[4252686 978867 2601478 1759921]
177
[1303120 1860486 3405811 2203284]
178
sage: a = A[0,1]; a
179
1237101
180
sage: a*a
181
3803997
182
sage: K = A.base_ring()
183
sage: K(1237101)^2
184
3803997
185
"""
186
cdef Matrix_modn_dense_double _self = <Matrix_modn_dense_double>self
187
cdef double result = (<Matrix_modn_dense_template>self)._matrix[i][j]
188
if _self._fits_int32:
189
return (<IntegerMod_int>_self._get_template)._new_c(<int_fast32_t>result)
190
else:
191
return (<IntegerMod_int64>_self._get_template)._new_c(<int_fast64_t>result)
192
193