Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/modules/vector_modn_dense.pyx
4045 views
1
"""
2
Vectors with integer mod n entries, with n small.
3
4
AUTHOR:
5
-- William Stein (2007)
6
7
EXAMPLES:
8
sage: v = vector(Integers(8),[1,2,3,4,5])
9
sage: type(v)
10
<type 'sage.modules.vector_modn_dense.Vector_modn_dense'>
11
sage: v
12
(1, 2, 3, 4, 5)
13
sage: 3*v
14
(3, 6, 1, 4, 7)
15
sage: v*7
16
(7, 6, 5, 4, 3)
17
sage: -v
18
(7, 6, 5, 4, 3)
19
sage: v - v
20
(0, 0, 0, 0, 0)
21
sage: v + v
22
(2, 4, 6, 0, 2)
23
sage: v * v
24
7
25
26
sage: v = vector(Integers(8),[1,2,3,4,5])
27
sage: u = vector(Integers(8),[1,2,3,4,4])
28
sage: v - u
29
(0, 0, 0, 0, 1)
30
sage: u - v
31
(0, 0, 0, 0, 7)
32
33
sage: v = vector((Integers(5)(1),2,3,4,4))
34
sage: u = vector((Integers(5)(1),2,3,4,3))
35
sage: v - u
36
(0, 0, 0, 0, 1)
37
sage: u - v
38
(0, 0, 0, 0, 4)
39
40
We make a large zero vector:
41
sage: k = Integers(8)^100000; k
42
Ambient free module of rank 100000 over Ring of integers modulo 8
43
sage: v = k(0)
44
sage: v[:10]
45
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
46
47
We multiply a vector by a matrix:
48
sage: a = (GF(97)^5)(range(5))
49
sage: m = matrix(GF(97),5,range(25))
50
sage: a*m
51
(53, 63, 73, 83, 93)
52
53
TESTS:
54
sage: v = vector(Integers(8), [1,2,3,4,5])
55
sage: loads(dumps(v)) == v
56
True
57
sage: v = vector(Integers(389), [1,2,3,4,5])
58
sage: loads(dumps(v)) == v
59
True
60
sage: v = vector(Integers(next_prime(10^20)), [1,2,3,4,5])
61
sage: loads(dumps(v)) == v
62
True
63
"""
64
65
###############################################################################
66
# Sage: System for Algebra and Geometry Experimentation
67
# Copyright (C) 2007 William Stein <[email protected]>
68
# Distributed under the terms of the GNU General Public License (GPL)
69
# http://www.gnu.org/licenses/
70
###############################################################################
71
72
include '../ext/interrupt.pxi'
73
include '../ext/stdsage.pxi'
74
75
from sage.rings.finite_rings.integer_mod cimport (IntegerMod_int, IntegerMod_int64,
76
IntegerMod_abstract, use_32bit_type)
77
78
cdef mod_int ivalue(IntegerMod_abstract x) except 18446744073709551615:
79
if PY_TYPE_CHECK_EXACT(x, IntegerMod_int):
80
return (<IntegerMod_int>x).ivalue
81
elif PY_TYPE_CHECK_EXACT(x, IntegerMod_int64):
82
return (<IntegerMod_int64>x).ivalue
83
else:
84
raise TypeError, "non-fixed size integer"
85
86
from sage.structure.element cimport Element, ModuleElement, RingElement, Vector
87
88
cimport free_module_element
89
from free_module_element import vector
90
91
from sage.ext.multi_modular import MAX_MODULUS
92
93
cdef class Vector_modn_dense(free_module_element.FreeModuleElement):
94
cdef _new_c(self):
95
cdef Vector_modn_dense y
96
y = PY_NEW(Vector_modn_dense)
97
y._init(self._degree, self._parent, self._p)
98
return y
99
100
cdef bint is_dense_c(self):
101
return 1
102
103
cdef bint is_sparse_c(self):
104
return 0
105
106
def __copy__(self):
107
cdef Vector_modn_dense y
108
y = self._new_c()
109
cdef Py_ssize_t i
110
for i from 0 <= i < self._degree:
111
y._entries[i] = self._entries[i]
112
return y
113
114
cdef _init(self, Py_ssize_t degree, parent, mod_int p):
115
self._degree = degree
116
self._parent = parent
117
self._p = p
118
self._entries = <mod_int *> sage_malloc(sizeof(mod_int) * degree)
119
if self._entries == NULL:
120
raise MemoryError
121
122
def __cinit__(self, parent=None, x=None, coerce=True, copy=True):
123
self._entries = NULL
124
self._is_mutable = 1
125
if not parent is None:
126
self._init(parent.degree(), parent, parent.base_ring().order())
127
128
def __init__(self, parent, x, coerce=True, copy=True):
129
cdef Py_ssize_t i
130
cdef mod_int a, p
131
if isinstance(x, (list, tuple)):
132
if len(x) != self._degree:
133
raise TypeError("x must be a list of the right length")
134
if coerce:
135
R = parent.base_ring()
136
p = R.order()
137
for i from 0 <= i < self._degree:
138
a = int(R(x[i]))
139
self._entries[i] = a%p
140
else:
141
for i from 0 <= i < self._degree:
142
self._entries[i] = x[i]
143
return
144
if x != 0:
145
raise TypeError("can't initialize vector from nonzero non-list")
146
else:
147
for i from 0 <= i < self._degree:
148
self._entries[i] = 0
149
150
def __dealloc__(self):
151
cdef Py_ssize_t i
152
if self._entries:
153
sage_free(self._entries)
154
155
cdef int _cmp_c_impl(left, Element right) except -2:
156
"""
157
EXAMPLES:
158
sage: v = vector(GF(5), [0,0,0,0])
159
sage: v == 0
160
True
161
sage: v == 1
162
False
163
sage: v == v
164
True
165
sage: w = vector(GF(11), [1,0,0,0])
166
sage: w < v
167
True
168
sage: w > v
169
False
170
"""
171
cdef Py_ssize_t i
172
cdef mod_int l, r
173
for i from 0 <= i < left.degree():
174
l = left._entries[i]
175
r = (<Vector_modn_dense>right)._entries[i]
176
if l < r:
177
return -1
178
elif l > r:
179
return 1
180
return 0
181
182
def __len__(self):
183
return self._degree
184
185
def __setitem__(self, i, value):
186
if not self._is_mutable:
187
raise ValueError("vector is immutable; please change a copy instead (use copy())")
188
cdef Py_ssize_t k, d, n
189
if isinstance(i, slice):
190
start, stop = i.start, i.stop
191
d = self.degree()
192
R = self.base_ring()
193
n = 0
194
for k from start <= k < stop:
195
if k >= d:
196
return
197
if k >= 0:
198
self[k] = R(value[n])
199
n = n + 1
200
else:
201
if i < 0 or i >= self._degree:
202
raise IndexError
203
else:
204
self._entries[i] = ivalue(self.base_ring()(value))
205
206
def __getitem__(self, i):
207
"""
208
Returns `i`-th entry or slice of self.
209
210
EXAMPLES:
211
sage: R = Integers(7)
212
sage: v = vector(R, [1,2,3]); v
213
(1, 2, 3)
214
sage: v[0]
215
1
216
sage: v[2]
217
3
218
sage: v[-2]
219
2
220
sage: v[0:2]
221
(1, 2)
222
sage: v[5]
223
Traceback (most recent call last):
224
...
225
IndexError: index out of range
226
sage: v[-5]
227
Traceback (most recent call last):
228
...
229
IndexError: index out of range
230
"""
231
if isinstance(i, slice):
232
start, stop, step = i.indices(len(self))
233
return vector(self.base_ring(), self.list()[start:stop])
234
235
if i < 0:
236
i += self._degree
237
if i < 0 or i >= self._degree:
238
raise IndexError('index out of range')
239
cdef IntegerMod_int n
240
cdef IntegerMod_int64 m
241
242
if use_32bit_type(self._p):
243
n = IntegerMod_int.__new__(IntegerMod_int)
244
IntegerMod_abstract.__init__(n, self.base_ring())
245
n.ivalue = self._entries[i]
246
return n
247
else:
248
m = IntegerMod_int64.__new__(IntegerMod_int64)
249
IntegerMod_abstract.__init__(m, self.base_ring())
250
m.ivalue = self._entries[i]
251
return m
252
253
def __reduce__(self):
254
return unpickle_v1, (self._parent, self.list(), self._degree, self._p, self._is_mutable)
255
256
cpdef ModuleElement _add_(self, ModuleElement right):
257
cdef Vector_modn_dense z, r
258
r = right
259
z = self._new_c()
260
cdef Py_ssize_t i
261
for i from 0 <= i < self._degree:
262
z._entries[i] = (self._entries[i] + r._entries[i]) % self._p
263
return z
264
265
266
cpdef ModuleElement _sub_(self, ModuleElement right):
267
cdef Vector_modn_dense z, r
268
r = right
269
z = self._new_c()
270
cdef Py_ssize_t i
271
for i from 0 <= i < self._degree:
272
z._entries[i] = (self._p + self._entries[i] - r._entries[i]) % self._p
273
return z
274
275
cpdef Element _dot_product_(self, Vector right):
276
cdef Py_ssize_t i
277
cdef IntegerMod_int n
278
cdef Vector_modn_dense r = right
279
n = IntegerMod_int.__new__(IntegerMod_int)
280
IntegerMod_abstract.__init__(n, self.base_ring())
281
n.ivalue = 0
282
283
for i from 0 <= i < self._degree:
284
n.ivalue = (n.ivalue + self._entries[i] * r._entries[i]) % self._p
285
286
return n
287
288
cpdef Vector _pairwise_product_(self, Vector right):
289
"""
290
EXAMPLES:
291
sage: v = vector(Integers(8), [2,3]); w = vector(Integers(8), [2,5])
292
sage: v * w
293
3
294
sage: w * v
295
3
296
"""
297
cdef Vector_modn_dense z, r
298
r = right
299
z = self._new_c()
300
cdef Py_ssize_t i
301
for i from 0 <= i < self._degree:
302
z._entries[i] = (self._entries[i] * r._entries[i]) % self._p
303
return z
304
305
cpdef ModuleElement _rmul_(self, RingElement left):
306
cdef Vector_modn_dense z
307
308
cdef mod_int a = ivalue(left)
309
z = self._new_c()
310
cdef Py_ssize_t i
311
312
for i from 0 <= i < self._degree:
313
z._entries[i] = (self._entries[i] * a) % self._p
314
return z
315
316
cpdef ModuleElement _lmul_(self, RingElement right):
317
return self._rmul_(right)
318
319
cpdef ModuleElement _neg_(self):
320
cdef Vector_modn_dense z
321
z = self._new_c()
322
cdef Py_ssize_t i
323
for i from 0 <= i < self._degree:
324
if self._entries[i] > 0:
325
z._entries[i] = self._p - self._entries[i]
326
else:
327
z._entries[i] = 0
328
return z
329
330
def unpickle_v0(parent, entries, degree, p):
331
# If you think you want to change this function, don't.
332
# Instead make a new version with a name like
333
# make_FreeModuleElement_generic_dense_v1
334
# and changed the reduce method below.
335
cdef Vector_modn_dense v
336
v = PY_NEW(Vector_modn_dense)
337
v._init(degree, parent, p)
338
for i from 0 <= i < degree:
339
v._entries[i] = entries[i]
340
return v
341
342
def unpickle_v1(parent, entries, degree, p, is_mutable):
343
cdef Vector_modn_dense v
344
v = PY_NEW(Vector_modn_dense)
345
v._init(degree, parent, p)
346
for i from 0 <= i < degree:
347
v._entries[i] = entries[i]
348
v._is_mutable = is_mutable
349
return v
350
351