Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/modules/vector_modn_dense.pyx
8815 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
sage: K = GF(previous_prime(2^31))
65
sage: v = vector(K, [42]); type(v[0])
66
<type 'sage.rings.finite_rings.integer_mod.IntegerMod_int64'>
67
sage: ~v[0]
68
2096353084
69
70
sage: K = GF(next_prime(2^31))
71
sage: v = vector(K, [42]); type(v[0])
72
<type 'sage.rings.finite_rings.integer_mod.IntegerMod_gmp'>
73
sage: ~v[0]
74
1482786336
75
"""
76
77
###############################################################################
78
# Sage: System for Algebra and Geometry Experimentation
79
# Copyright (C) 2007 William Stein <[email protected]>
80
# Distributed under the terms of the GNU General Public License (GPL)
81
# http://www.gnu.org/licenses/
82
###############################################################################
83
84
include 'sage/ext/interrupt.pxi'
85
include 'sage/ext/stdsage.pxi'
86
87
from sage.rings.finite_rings.stdint cimport INTEGER_MOD_INT64_LIMIT
88
89
MAX_MODULUS = INTEGER_MOD_INT64_LIMIT
90
91
from sage.rings.finite_rings.integer_mod cimport (
92
IntegerMod_int, IntegerMod_int64,
93
IntegerMod_abstract, use_32bit_type)
94
95
cdef mod_int ivalue(IntegerMod_abstract x) except -1:
96
if PY_TYPE_CHECK_EXACT(x, IntegerMod_int):
97
return (<IntegerMod_int>x).ivalue
98
elif PY_TYPE_CHECK_EXACT(x, IntegerMod_int64):
99
return (<IntegerMod_int64>x).ivalue
100
else:
101
raise TypeError, "non-fixed size integer"
102
103
from sage.structure.element cimport Element, ModuleElement, RingElement, Vector
104
105
cimport free_module_element
106
from free_module_element import vector
107
108
cdef class Vector_modn_dense(free_module_element.FreeModuleElement):
109
cdef _new_c(self):
110
cdef Vector_modn_dense y
111
y = PY_NEW(Vector_modn_dense)
112
y._init(self._degree, self._parent, self._p)
113
return y
114
115
cdef bint is_dense_c(self):
116
return 1
117
118
cdef bint is_sparse_c(self):
119
return 0
120
121
def __copy__(self):
122
cdef Vector_modn_dense y
123
y = self._new_c()
124
cdef Py_ssize_t i
125
for i from 0 <= i < self._degree:
126
y._entries[i] = self._entries[i]
127
return y
128
129
cdef _init(self, Py_ssize_t degree, parent, mod_int p):
130
self._degree = degree
131
self._parent = parent
132
self._p = p
133
self._entries = <mod_int *> sage_malloc(sizeof(mod_int) * degree)
134
if self._entries == NULL:
135
raise MemoryError
136
137
def __cinit__(self, parent=None, x=None, coerce=True, copy=True):
138
self._entries = NULL
139
self._is_mutable = 1
140
if not parent is None:
141
self._init(parent.degree(), parent, parent.base_ring().order())
142
143
def __init__(self, parent, x, coerce=True, copy=True):
144
cdef Py_ssize_t i
145
cdef mod_int a, p
146
if isinstance(x, (list, tuple)):
147
if len(x) != self._degree:
148
raise TypeError("x must be a list of the right length")
149
if coerce:
150
R = parent.base_ring()
151
p = R.order()
152
for i from 0 <= i < self._degree:
153
a = int(R(x[i]))
154
self._entries[i] = a%p
155
else:
156
for i from 0 <= i < self._degree:
157
self._entries[i] = x[i]
158
return
159
if x != 0:
160
raise TypeError("can't initialize vector from nonzero non-list")
161
else:
162
for i from 0 <= i < self._degree:
163
self._entries[i] = 0
164
165
def __dealloc__(self):
166
cdef Py_ssize_t i
167
if self._entries:
168
sage_free(self._entries)
169
170
cdef int _cmp_c_impl(left, Element right) except -2:
171
"""
172
EXAMPLES:
173
sage: v = vector(GF(5), [0,0,0,0])
174
sage: v == 0
175
True
176
sage: v == 1
177
False
178
sage: v == v
179
True
180
sage: w = vector(GF(11), [1,0,0,0])
181
sage: w < v
182
True
183
sage: w > v
184
False
185
"""
186
cdef Py_ssize_t i
187
cdef mod_int l, r
188
for i from 0 <= i < left.degree():
189
l = left._entries[i]
190
r = (<Vector_modn_dense>right)._entries[i]
191
if l < r:
192
return -1
193
elif l > r:
194
return 1
195
return 0
196
# see sage/structure/element.pyx
197
def __richcmp__(left, right, int op):
198
"""
199
TEST::
200
201
sage: w = vector(GF(11), [-1,0,0,0])
202
sage: w == w
203
True
204
"""
205
return (<Element>left)._richcmp(right, op)
206
207
# __hash__ is not properly inherited if comparison is changed
208
def __hash__(self):
209
"""
210
TEST::
211
212
sage: w = vector(GF(11), [-1,0,0,0])
213
sage: w.set_immutable()
214
sage: isinstance(hash(w), int)
215
True
216
"""
217
return free_module_element.FreeModuleElement.__hash__(self)
218
219
def __len__(self):
220
return self._degree
221
222
def __setitem__(self, i, value):
223
if not self._is_mutable:
224
raise ValueError("vector is immutable; please change a copy instead (use copy())")
225
cdef Py_ssize_t k, d, n
226
if isinstance(i, slice):
227
start, stop = i.start, i.stop
228
d = self.degree()
229
R = self.base_ring()
230
n = 0
231
for k from start <= k < stop:
232
if k >= d:
233
return
234
if k >= 0:
235
self[k] = R(value[n])
236
n = n + 1
237
else:
238
if i < 0 or i >= self._degree:
239
raise IndexError
240
else:
241
self._entries[i] = ivalue(self.base_ring()(value))
242
243
def __getitem__(self, i):
244
"""
245
Returns `i`-th entry or slice of self.
246
247
EXAMPLES:
248
sage: R = Integers(7)
249
sage: v = vector(R, [1,2,3]); v
250
(1, 2, 3)
251
sage: v[0]
252
1
253
sage: v[2]
254
3
255
sage: v[-2]
256
2
257
sage: v[0:2]
258
(1, 2)
259
sage: v[5]
260
Traceback (most recent call last):
261
...
262
IndexError: index out of range
263
sage: v[-5]
264
Traceback (most recent call last):
265
...
266
IndexError: index out of range
267
"""
268
if isinstance(i, slice):
269
start, stop, step = i.indices(len(self))
270
return vector(self.base_ring(), self.list()[start:stop])
271
272
if i < 0:
273
i += self._degree
274
if i < 0 or i >= self._degree:
275
raise IndexError('index out of range')
276
cdef IntegerMod_int n
277
cdef IntegerMod_int64 m
278
279
if use_32bit_type(self._p):
280
n = IntegerMod_int.__new__(IntegerMod_int)
281
IntegerMod_abstract.__init__(n, self.base_ring())
282
n.ivalue = self._entries[i]
283
return n
284
else:
285
m = IntegerMod_int64.__new__(IntegerMod_int64)
286
IntegerMod_abstract.__init__(m, self.base_ring())
287
m.ivalue = self._entries[i]
288
return m
289
290
def __reduce__(self):
291
return unpickle_v1, (self._parent, self.list(), self._degree, self._p, self._is_mutable)
292
293
cpdef ModuleElement _add_(self, ModuleElement right):
294
cdef Vector_modn_dense z, r
295
r = right
296
z = self._new_c()
297
cdef Py_ssize_t i
298
for i from 0 <= i < self._degree:
299
z._entries[i] = (self._entries[i] + r._entries[i]) % self._p
300
return z
301
302
303
cpdef ModuleElement _sub_(self, ModuleElement right):
304
cdef Vector_modn_dense z, r
305
r = right
306
z = self._new_c()
307
cdef Py_ssize_t i
308
for i from 0 <= i < self._degree:
309
z._entries[i] = (self._p + self._entries[i] - r._entries[i]) % self._p
310
return z
311
312
cpdef Element _dot_product_(self, Vector right):
313
cdef Py_ssize_t i
314
cdef IntegerMod_int n
315
cdef Vector_modn_dense r = right
316
n = IntegerMod_int.__new__(IntegerMod_int)
317
IntegerMod_abstract.__init__(n, self.base_ring())
318
n.ivalue = 0
319
320
for i from 0 <= i < self._degree:
321
n.ivalue = (n.ivalue + self._entries[i] * r._entries[i]) % self._p
322
323
return n
324
325
cpdef Vector _pairwise_product_(self, Vector right):
326
"""
327
EXAMPLES:
328
sage: v = vector(Integers(8), [2,3]); w = vector(Integers(8), [2,5])
329
sage: v * w
330
3
331
sage: w * v
332
3
333
"""
334
cdef Vector_modn_dense z, r
335
r = right
336
z = self._new_c()
337
cdef Py_ssize_t i
338
for i from 0 <= i < self._degree:
339
z._entries[i] = (self._entries[i] * r._entries[i]) % self._p
340
return z
341
342
cpdef ModuleElement _rmul_(self, RingElement left):
343
cdef Vector_modn_dense z
344
345
cdef mod_int a = ivalue(left)
346
z = self._new_c()
347
cdef Py_ssize_t i
348
349
for i from 0 <= i < self._degree:
350
z._entries[i] = (self._entries[i] * a) % self._p
351
return z
352
353
cpdef ModuleElement _lmul_(self, RingElement right):
354
return self._rmul_(right)
355
356
cpdef ModuleElement _neg_(self):
357
cdef Vector_modn_dense z
358
z = self._new_c()
359
cdef Py_ssize_t i
360
for i from 0 <= i < self._degree:
361
if self._entries[i] > 0:
362
z._entries[i] = self._p - self._entries[i]
363
else:
364
z._entries[i] = 0
365
return z
366
367
def unpickle_v0(parent, entries, degree, p):
368
# If you think you want to change this function, don't.
369
# Instead make a new version with a name like
370
# make_FreeModuleElement_generic_dense_v1
371
# and changed the reduce method below.
372
cdef Vector_modn_dense v
373
v = PY_NEW(Vector_modn_dense)
374
v._init(degree, parent, p)
375
for i from 0 <= i < degree:
376
v._entries[i] = entries[i]
377
return v
378
379
def unpickle_v1(parent, entries, degree, p, is_mutable):
380
cdef Vector_modn_dense v
381
v = PY_NEW(Vector_modn_dense)
382
v._init(degree, parent, p)
383
for i from 0 <= i < degree:
384
v._entries[i] = entries[i]
385
v._is_mutable = is_mutable
386
return v
387
388