Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/modules/vector_integer_dense.pyx
4036 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 '../ext/interrupt.pxi'
49
include '../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
def __len__(self):
149
return self._degree
150
151
def __setitem__(self, i, value):
152
"""
153
EXAMPLES::
154
155
sage: v = vector([1,2,3]); v
156
(1, 2, 3)
157
sage: v[0] = 2
158
sage: v[1:3] = [1, 4]; v
159
(2, 1, 4)
160
"""
161
if not self._is_mutable:
162
raise ValueError("vector is immutable; please change a copy instead (use copy())")
163
cdef Integer z
164
cdef Py_ssize_t k, d, n
165
if isinstance(i, slice):
166
start, stop = i.start, i.stop
167
d = self.degree()
168
R = self.base_ring()
169
n = 0
170
for k from start <= k < stop:
171
if k >= d:
172
return
173
if k >= 0:
174
self[k] = R(value[n])
175
n = n + 1
176
else:
177
if i < 0 or i >= self._degree:
178
raise IndexError
179
else:
180
z = Integer(value)
181
mpz_set(self._entries[i], z.value)
182
183
def __getitem__(self, i):
184
"""
185
Returns `i`-th entry or slice of self.
186
187
EXAMPLES::
188
189
sage: v = vector([1,2,3]); v
190
(1, 2, 3)
191
sage: v[0]
192
1
193
sage: v[-2]
194
2
195
sage: v[0:2]
196
(1, 2)
197
sage: v[5]
198
Traceback (most recent call last):
199
...
200
IndexError: index out of range
201
sage: v[-5]
202
Traceback (most recent call last):
203
...
204
IndexError: index out of range
205
"""
206
cdef Integer z = PY_NEW(Integer)
207
if isinstance(i, slice):
208
start, stop, step = i.indices(len(self))
209
return vector(self.base_ring(), self.list()[start:stop])
210
else:
211
if i < 0:
212
i += self._degree
213
if i < 0 or i >= self._degree:
214
raise IndexError('index out of range')
215
else:
216
mpz_set(z.value, self._entries[i])
217
return z
218
219
def list(self,copy=True):
220
"""
221
The list of entries of the vector.
222
223
INPUT:
224
225
- ``copy``, ignored optional argument.
226
227
EXAMPLES::
228
229
sage: v = vector([1,2,3,4])
230
sage: a = v.list(copy=False); a
231
[1, 2, 3, 4]
232
sage: a[0] = 0
233
sage: v
234
(1, 2, 3, 4)
235
"""
236
cdef int i
237
return [_Integer_from_mpz(self._entries[i]) for i in
238
xrange(self._degree)]
239
240
def __reduce__(self):
241
return (unpickle_v1, (self._parent, self.list(), self._degree, self._is_mutable))
242
243
cpdef ModuleElement _add_(self, ModuleElement right):
244
cdef Vector_integer_dense z, r
245
r = right
246
z = self._new_c()
247
cdef Py_ssize_t i
248
for i from 0 <= i < self._degree:
249
mpz_init(z._entries[i])
250
mpz_add(z._entries[i], self._entries[i], r._entries[i])
251
return z
252
253
254
cpdef ModuleElement _sub_(self, ModuleElement right):
255
cdef Vector_integer_dense z, r
256
r = right
257
z = self._new_c()
258
cdef Py_ssize_t i
259
for i from 0 <= i < self._degree:
260
mpz_init(z._entries[i])
261
mpz_sub(z._entries[i], self._entries[i], r._entries[i])
262
return z
263
264
cpdef Element _dot_product_(self, Vector right):
265
"""
266
Dot product of dense vectors over the integers.
267
268
EXAMPLES::
269
270
sage: v = vector(ZZ, [1,2,-3]); w = vector(ZZ,[4,3,2])
271
sage: v*w
272
4
273
sage: w*v
274
4
275
"""
276
cdef Vector_integer_dense r = right
277
cdef Integer z
278
z = PY_NEW(Integer)
279
cdef mpz_t t
280
mpz_init(t)
281
mpz_set_si(z.value, 0)
282
cdef Py_ssize_t i
283
for i from 0 <= i < self._degree:
284
mpz_mul(t, self._entries[i], r._entries[i])
285
mpz_add(z.value, z.value, t)
286
mpz_clear(t)
287
return z
288
289
cpdef Vector _pairwise_product_(self, Vector right):
290
"""
291
EXAMPLES::
292
293
sage: v = vector(ZZ, [1,2,-3]); w = vector(ZZ,[4,3,2])
294
sage: v.pairwise_product(w)
295
(4, 6, -6)
296
"""
297
cdef Vector_integer_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
mpz_init(z._entries[i])
303
mpz_mul(z._entries[i], self._entries[i], r._entries[i])
304
return z
305
306
cpdef ModuleElement _rmul_(self, RingElement left):
307
cdef Vector_integer_dense z
308
cdef Integer a
309
a = left
310
z = self._new_c()
311
cdef Py_ssize_t i
312
for i from 0 <= i < self._degree:
313
mpz_init(z._entries[i])
314
mpz_mul(z._entries[i], self._entries[i], a.value)
315
return z
316
317
cpdef ModuleElement _lmul_(self, RingElement right):
318
cdef Vector_integer_dense z
319
cdef Integer a
320
a = right
321
z = self._new_c()
322
cdef Py_ssize_t i
323
for i from 0 <= i < self._degree:
324
mpz_init(z._entries[i])
325
mpz_mul(z._entries[i], self._entries[i], a.value)
326
return z
327
328
cpdef ModuleElement _neg_(self):
329
cdef Vector_integer_dense z
330
z = self._new_c()
331
cdef Py_ssize_t i
332
for i from 0 <= i < self._degree:
333
mpz_init(z._entries[i])
334
mpz_neg(z._entries[i], self._entries[i])
335
return z
336
337
def _singular_(self, singular=None):
338
r"""
339
Return \Singular representation of this integer vector.
340
341
INPUT:
342
343
- singular -- \Singular interface instance (default: None)
344
345
EXAMPLES::
346
347
sage: A = random_matrix(ZZ,1,3)
348
sage: v = A.row(0)
349
sage: vs = singular(v); vs
350
-8,
351
2,
352
0
353
sage: vs.type()
354
'intvec'
355
"""
356
if singular is None:
357
from sage.interfaces.singular import singular as singular_default
358
singular = singular_default
359
360
name = singular._next_var_name()
361
values = str(self.list())[1:-1]
362
singular.eval("intvec %s = %s"%(name, values))
363
364
from sage.interfaces.singular import SingularElement
365
return SingularElement(singular, 'foobar', name, True)
366
367
def unpickle_v0(parent, entries, degree):
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_integer_dense v
373
v = PY_NEW(Vector_integer_dense)
374
v._init(degree, parent)
375
cdef Integer z
376
for i from 0 <= i < degree:
377
z = Integer(entries[i])
378
mpz_init_set(v._entries[i], z.value)
379
return v
380
381
def unpickle_v1(parent, entries, degree, is_mutable):
382
cdef Vector_integer_dense v
383
v = PY_NEW(Vector_integer_dense)
384
v._init(degree, parent)
385
cdef Integer z
386
for i from 0 <= i < degree:
387
z = Integer(entries[i])
388
mpz_init_set(v._entries[i], z.value)
389
v._is_mutable = is_mutable
390
return v
391
392