Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagesmc
Path: blob/master/src/sage/modules/vector_integer_dense.pyx
8815 views
1
"""
2
Vectors with integer entries
3
4
AUTHOR:
5
6
- William Stein (2007)
7
8
EXAMPLES::
9
10
sage: v = vector(ZZ,[1,2,3,4,5])
11
sage: v
12
(1, 2, 3, 4, 5)
13
sage: 3*v
14
(3, 6, 9, 12, 15)
15
sage: v*7
16
(7, 14, 21, 28, 35)
17
sage: -v
18
(-1, -2, -3, -4, -5)
19
sage: v - v
20
(0, 0, 0, 0, 0)
21
sage: v + v
22
(2, 4, 6, 8, 10)
23
sage: v * v # dot product.
24
55
25
26
We make a large zero vector::
27
28
sage: k = ZZ^100000; k
29
Ambient free module of rank 100000 over the principal ideal domain Integer Ring
30
sage: v = k(0)
31
sage: v[:10]
32
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
33
34
TESTS::
35
36
sage: v = vector(ZZ, [1,2,3,4])
37
sage: loads(dumps(v)) == v
38
True
39
"""
40
41
###############################################################################
42
# Sage: System for Algebra and Geometry Experimentation
43
# Copyright (C) 2007 William Stein <[email protected]>
44
# Distributed under the terms of the GNU General Public License (GPL)
45
# http://www.gnu.org/licenses/
46
###############################################################################
47
48
include 'sage/ext/interrupt.pxi'
49
include 'sage/ext/stdsage.pxi'
50
51
from sage.structure.element cimport Element, ModuleElement, RingElement, Vector
52
53
from sage.rings.integer cimport Integer
54
55
cimport free_module_element
56
57
from free_module_element import vector
58
59
cdef inline _Integer_from_mpz(mpz_t e):
60
cdef Integer z = PY_NEW(Integer)
61
mpz_set(z.value, e)
62
return z
63
64
cdef class Vector_integer_dense(free_module_element.FreeModuleElement):
65
cdef _new_c(self):
66
cdef Vector_integer_dense y
67
y = PY_NEW(Vector_integer_dense)
68
y._init(self._degree, self._parent)
69
return y
70
71
cdef bint is_dense_c(self):
72
return 1
73
cdef bint is_sparse_c(self):
74
return 0
75
76
def __copy__(self):
77
cdef Vector_integer_dense y
78
y = self._new_c()
79
cdef Py_ssize_t i
80
for i from 0 <= i < self._degree:
81
mpz_init_set(y._entries[i], self._entries[i])
82
return y
83
84
cdef _init(self, Py_ssize_t degree, parent):
85
self._degree = degree
86
self._parent = parent
87
self._is_mutable = 1
88
self._entries = <mpz_t *> sage_malloc(sizeof(mpz_t) * degree)
89
if self._entries == NULL:
90
raise MemoryError
91
92
def __cinit__(self, parent=None, x=None, coerce=True,copy=True):
93
self._entries = NULL
94
self._is_mutable = 1
95
if not parent is None:
96
self._init(parent.degree(), parent)
97
98
def __init__(self, parent, x, coerce=True, copy=True):
99
cdef Py_ssize_t i
100
cdef Integer z
101
# we have to do this to avoid a garbage collection error in dealloc
102
for i from 0 <= i < self._degree:
103
mpz_init(self._entries[i])
104
if isinstance(x, (list, tuple)):
105
if len(x) != self._degree:
106
raise TypeError("x must be a list of the right length")
107
for i from 0 <= i < self._degree:
108
z = Integer(x[i])
109
mpz_set(self._entries[i], z.value)
110
return
111
if x != 0:
112
raise TypeError("can't initialize vector from nonzero non-list")
113
114
def __dealloc__(self):
115
cdef Py_ssize_t i
116
if self._entries:
117
for i from 0 <= i < self._degree:
118
mpz_clear(self._entries[i])
119
sage_free(self._entries)
120
121
cdef int _cmp_c_impl(left, Element right) except -2:
122
"""
123
EXAMPLES::
124
125
sage: v = vector(ZZ, [0,0,0,0])
126
sage: v == 0
127
True
128
sage: v == 1
129
False
130
sage: v == v
131
True
132
sage: w = vector(ZZ, [-1,0,0,0])
133
sage: w < v
134
True
135
sage: w > v
136
False
137
"""
138
cdef Py_ssize_t i
139
cdef int c
140
for i from 0 <= i < left.degree():
141
c = mpz_cmp(left._entries[i], (<Vector_integer_dense>right)._entries[i])
142
if c < 0:
143
return -1
144
elif c > 0:
145
return 1
146
return 0
147
148
# see sage/structure/element.pyx
149
def __richcmp__(left, right, int op):
150
"""
151
TEST::
152
153
sage: w = vector(ZZ, [-1,0,0,0])
154
sage: w == w
155
True
156
"""
157
return (<Element>left)._richcmp(right, op)
158
159
# __hash__ is not properly inherited if comparison is changed
160
def __hash__(self):
161
"""
162
TEST::
163
164
sage: w = vector(ZZ, [-1,0,0,0])
165
sage: w.set_immutable()
166
sage: isinstance(hash(w), int)
167
True
168
"""
169
return free_module_element.FreeModuleElement.__hash__(self)
170
171
def __len__(self):
172
return self._degree
173
174
def __setitem__(self, i, value):
175
"""
176
EXAMPLES::
177
178
sage: v = vector([1,2,3]); v
179
(1, 2, 3)
180
sage: v[0] = 2
181
sage: v[1:3] = [1, 4]; v
182
(2, 1, 4)
183
"""
184
if not self._is_mutable:
185
raise ValueError("vector is immutable; please change a copy instead (use copy())")
186
cdef Integer z
187
cdef Py_ssize_t k, d, n
188
if isinstance(i, slice):
189
start, stop = i.start, i.stop
190
d = self.degree()
191
R = self.base_ring()
192
n = 0
193
for k from start <= k < stop:
194
if k >= d:
195
return
196
if k >= 0:
197
self[k] = R(value[n])
198
n = n + 1
199
else:
200
if i < 0 or i >= self._degree:
201
raise IndexError
202
else:
203
z = Integer(value)
204
mpz_set(self._entries[i], z.value)
205
206
def __getitem__(self, i):
207
"""
208
Returns `i`-th entry or slice of self.
209
210
EXAMPLES::
211
212
sage: v = vector([1,2,3]); v
213
(1, 2, 3)
214
sage: v[0]
215
1
216
sage: v[-2]
217
2
218
sage: v[0:2]
219
(1, 2)
220
sage: v[5]
221
Traceback (most recent call last):
222
...
223
IndexError: index out of range
224
sage: v[-5]
225
Traceback (most recent call last):
226
...
227
IndexError: index out of range
228
"""
229
cdef Integer z = PY_NEW(Integer)
230
if isinstance(i, slice):
231
start, stop, step = i.indices(len(self))
232
return vector(self.base_ring(), self.list()[start:stop])
233
else:
234
if i < 0:
235
i += self._degree
236
if i < 0 or i >= self._degree:
237
raise IndexError('index out of range')
238
else:
239
mpz_set(z.value, self._entries[i])
240
return z
241
242
def list(self,copy=True):
243
"""
244
The list of entries of the vector.
245
246
INPUT:
247
248
- ``copy``, ignored optional argument.
249
250
EXAMPLES::
251
252
sage: v = vector([1,2,3,4])
253
sage: a = v.list(copy=False); a
254
[1, 2, 3, 4]
255
sage: a[0] = 0
256
sage: v
257
(1, 2, 3, 4)
258
"""
259
cdef int i
260
return [_Integer_from_mpz(self._entries[i]) for i in
261
xrange(self._degree)]
262
263
def __reduce__(self):
264
return (unpickle_v1, (self._parent, self.list(), self._degree, self._is_mutable))
265
266
cpdef ModuleElement _add_(self, ModuleElement right):
267
cdef Vector_integer_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
mpz_init(z._entries[i])
273
mpz_add(z._entries[i], self._entries[i], r._entries[i])
274
return z
275
276
277
cpdef ModuleElement _sub_(self, ModuleElement right):
278
cdef Vector_integer_dense z, r
279
r = right
280
z = self._new_c()
281
cdef Py_ssize_t i
282
for i from 0 <= i < self._degree:
283
mpz_init(z._entries[i])
284
mpz_sub(z._entries[i], self._entries[i], r._entries[i])
285
return z
286
287
cpdef Element _dot_product_(self, Vector right):
288
"""
289
Dot product of dense vectors over the integers.
290
291
EXAMPLES::
292
293
sage: v = vector(ZZ, [1,2,-3]); w = vector(ZZ,[4,3,2])
294
sage: v*w
295
4
296
sage: w*v
297
4
298
"""
299
cdef Vector_integer_dense r = right
300
cdef Integer z
301
z = PY_NEW(Integer)
302
cdef mpz_t t
303
mpz_init(t)
304
mpz_set_si(z.value, 0)
305
cdef Py_ssize_t i
306
for i from 0 <= i < self._degree:
307
mpz_mul(t, self._entries[i], r._entries[i])
308
mpz_add(z.value, z.value, t)
309
mpz_clear(t)
310
return z
311
312
cpdef Vector _pairwise_product_(self, Vector right):
313
"""
314
EXAMPLES::
315
316
sage: v = vector(ZZ, [1,2,-3]); w = vector(ZZ,[4,3,2])
317
sage: v.pairwise_product(w)
318
(4, 6, -6)
319
"""
320
cdef Vector_integer_dense z, r
321
r = right
322
z = self._new_c()
323
cdef Py_ssize_t i
324
for i from 0 <= i < self._degree:
325
mpz_init(z._entries[i])
326
mpz_mul(z._entries[i], self._entries[i], r._entries[i])
327
return z
328
329
cpdef ModuleElement _rmul_(self, RingElement left):
330
cdef Vector_integer_dense z
331
cdef Integer a
332
a = left
333
z = self._new_c()
334
cdef Py_ssize_t i
335
for i from 0 <= i < self._degree:
336
mpz_init(z._entries[i])
337
mpz_mul(z._entries[i], self._entries[i], a.value)
338
return z
339
340
cpdef ModuleElement _lmul_(self, RingElement right):
341
cdef Vector_integer_dense z
342
cdef Integer a
343
a = right
344
z = self._new_c()
345
cdef Py_ssize_t i
346
for i from 0 <= i < self._degree:
347
mpz_init(z._entries[i])
348
mpz_mul(z._entries[i], self._entries[i], a.value)
349
return z
350
351
cpdef ModuleElement _neg_(self):
352
cdef Vector_integer_dense z
353
z = self._new_c()
354
cdef Py_ssize_t i
355
for i from 0 <= i < self._degree:
356
mpz_init(z._entries[i])
357
mpz_neg(z._entries[i], self._entries[i])
358
return z
359
360
def _singular_(self, singular=None):
361
r"""
362
Return \Singular representation of this integer vector.
363
364
INPUT:
365
366
- singular -- \Singular interface instance (default: None)
367
368
EXAMPLES::
369
370
sage: A = random_matrix(ZZ,1,3)
371
sage: v = A.row(0)
372
sage: vs = singular(v); vs
373
-8,
374
2,
375
0
376
sage: vs.type()
377
'intvec'
378
"""
379
if singular is None:
380
from sage.interfaces.singular import singular as singular_default
381
singular = singular_default
382
383
name = singular._next_var_name()
384
values = str(self.list())[1:-1]
385
singular.eval("intvec %s = %s"%(name, values))
386
387
from sage.interfaces.singular import SingularElement
388
return SingularElement(singular, 'foobar', name, True)
389
390
def unpickle_v0(parent, entries, degree):
391
# If you think you want to change this function, don't.
392
# Instead make a new version with a name like
393
# make_FreeModuleElement_generic_dense_v1
394
# and changed the reduce method below.
395
cdef Vector_integer_dense v
396
v = PY_NEW(Vector_integer_dense)
397
v._init(degree, parent)
398
cdef Integer z
399
for i from 0 <= i < degree:
400
z = Integer(entries[i])
401
mpz_init_set(v._entries[i], z.value)
402
return v
403
404
def unpickle_v1(parent, entries, degree, is_mutable):
405
cdef Vector_integer_dense v
406
v = PY_NEW(Vector_integer_dense)
407
v._init(degree, parent)
408
cdef Integer z
409
for i from 0 <= i < degree:
410
z = Integer(entries[i])
411
mpz_init_set(v._entries[i], z.value)
412
v._is_mutable = is_mutable
413
return v
414
415