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