Path: blob/master/src/sage/modules/vector_rational_dense.pyx
8815 views
"""1Vectors with rational entries.23AUTHOR:45- William Stein (2007)6- Soroosh Yazdani (2007)78EXAMPLES::910sage: v = vector(QQ,[1,2,3,4,5])11sage: v12(1, 2, 3, 4, 5)13sage: 3*v14(3, 6, 9, 12, 15)15sage: v/216(1/2, 1, 3/2, 2, 5/2)17sage: -v18(-1, -2, -3, -4, -5)19sage: v - v20(0, 0, 0, 0, 0)21sage: v + v22(2, 4, 6, 8, 10)23sage: v * v24552526We make a large zero vector::2728sage: k = QQ^100000; k29Vector space of dimension 100000 over Rational Field30sage: v = k(0)31sage: v[:10]32(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)3334TESTS::3536sage: v = vector(QQ, [1,2/5,-3/8,4])37sage: loads(dumps(v)) == v38True39"""4041###############################################################################42# Sage: System for Algebra and Geometry Experimentation43# 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###############################################################################4748include 'sage/ext/interrupt.pxi'49include 'sage/ext/stdsage.pxi'5051from sage.structure.element cimport Element, ModuleElement, RingElement, Vector5253from sage.rings.integer cimport Integer54from sage.rings.rational cimport Rational5556cimport free_module_element57from free_module_element import vector5859cdef inline _Rational_from_mpq(mpq_t e):60cdef Rational z = PY_NEW(Rational)61mpq_set(z.value, e)62return z6364cdef class Vector_rational_dense(free_module_element.FreeModuleElement):65cdef bint is_dense_c(self):66return 167cdef bint is_sparse_c(self):68return 06970cdef _new_c(self):71cdef Vector_rational_dense y72y = PY_NEW(Vector_rational_dense)73y._init(self._degree, self._parent)74return y7576def __copy__(self):77cdef Vector_rational_dense y78y = self._new_c()79cdef Py_ssize_t i80for i from 0 <= i < self._degree:81mpq_init(y._entries[i])82mpq_set(y._entries[i], self._entries[i])83return y8485cdef _init(self, Py_ssize_t degree, parent):86self._degree = degree87self._parent = parent88self._entries = <mpq_t *> sage_malloc(sizeof(mpq_t) * degree)89if self._entries == NULL:90raise MemoryError9192def __cinit__(self, parent=None, x=None, coerce=True,copy=True):93self._entries = NULL94self._is_mutable = 195if not parent is None:96self._init(parent.degree(), parent)9798def __init__(self, parent, x, coerce=True, copy=True):99cdef Py_ssize_t i100cdef Rational z101# we have to do this to avoid a garbage collection error in dealloc102for i from 0 <= i < self._degree:103mpq_init(self._entries[i])104if isinstance(x, (list, tuple)):105if len(x) != self._degree:106raise TypeError("entries must be a list of length %s"%self._degree)107for i from 0 <= i < self._degree:108z = Rational(x[i])109mpq_set(self._entries[i], z.value)110return111if x != 0:112raise TypeError("can't initialize vector from nonzero non-list")113114def __dealloc__(self):115cdef Py_ssize_t i116if self._entries:117sig_on()118for i from 0 <= i < self._degree:119#print "clearing gmp's entry %s"%i120mpq_clear(self._entries[i])121sig_off()122#print "clearing python entries"123sage_free(self._entries)124125cdef int _cmp_c_impl(left, Element right) except -2:126"""127EXAMPLES::128129sage: v = vector(QQ, [0,0,0,0])130sage: v == 0131True132sage: v == 1133False134sage: v == v135True136sage: w = vector(QQ, [-1,3/2,0,0])137sage: w < v138True139sage: w > v140False141"""142cdef Py_ssize_t i143cdef int c144for i from 0 <= i < left.degree():145c = mpq_cmp(left._entries[i], (<Vector_rational_dense>right)._entries[i])146if c < 0:147return -1148elif c > 0:149return 1150return 0151152# see sage/structure/element.pyx153def __richcmp__(left, right, int op):154"""155TEST::156157sage: w = vector(QQ, [-1,0,0,0])158sage: w == w159True160"""161return (<Element>left)._richcmp(right, op)162163# __hash__ is not properly inherited if comparison is changed164def __hash__(self):165"""166TEST::167168sage: w = vector(QQ, [-1,0,0,0])169sage: w.set_immutable()170sage: isinstance(hash(w), int)171True172"""173return free_module_element.FreeModuleElement.__hash__(self)174175def __len__(self):176return self._degree177178def __setitem__(self, i, value):179if not self._is_mutable:180raise ValueError("vector is immutable; please change a copy instead (use copy())")181cdef Rational z182cdef Py_ssize_t k, d, n183if isinstance(i, slice):184start, stop = i.start, i.stop185d = self.degree()186R = self.base_ring()187n = 0188for k from start <= k < stop:189if k >= d:190return191if k >= 0:192self[k] = R(value[n])193n = n + 1194else:195if i < 0 or i >= self._degree:196raise IndexError197else:198z = Rational(value)199mpq_set(self._entries[i], z.value)200201def __getitem__(self, i):202"""203Returns `i`-th entry or slice of self.204205EXAMPLES::206207sage: v = vector([1/2,2/3,3/4]); v208(1/2, 2/3, 3/4)209sage: v[0]2101/2211sage: v[2]2123/4213sage: v[-2]2142/3215sage: v[5]216Traceback (most recent call last):217...218IndexError: index out of range219sage: v[-5]220Traceback (most recent call last):221...222IndexError: index out of range223"""224cdef Rational z = PY_NEW(Rational)225if isinstance(i, slice):226start, stop, step = i.indices(len(self))227return vector(self.base_ring(), self.list()[start:stop])228else:229if i < 0:230i += self._degree231if i < 0 or i >= self._degree:232raise IndexError('index out of range')233else:234mpq_set(z.value, self._entries[i])235return z236237def list(self,copy=True):238"""239The list of entries of the vector.240241INPUT:242243- ``copy``, ignored optional argument.244245EXAMPLES::246247sage: v = vector(QQ,[1,2,3,4])248sage: a = v.list(copy=False); a249[1, 2, 3, 4]250sage: a[0] = 0251sage: v252(1, 2, 3, 4)253"""254cdef int i255return [_Rational_from_mpq(self._entries[i]) for i in256xrange(self._degree)]257258def __reduce__(self):259return (unpickle_v1, (self._parent, self.list(), self._degree, self._is_mutable))260261cpdef ModuleElement _add_(self, ModuleElement right):262cdef Vector_rational_dense z, r263r = right264z = self._new_c()265cdef Py_ssize_t i266for i from 0 <= i < self._degree:267mpq_init(z._entries[i])268mpq_add(z._entries[i], self._entries[i], r._entries[i])269return z270271272cpdef ModuleElement _sub_(self, ModuleElement right):273cdef Vector_rational_dense z, r274r = right275z = self._new_c()276cdef Py_ssize_t i277for i from 0 <= i < self._degree:278mpq_init(z._entries[i])279mpq_sub(z._entries[i], self._entries[i], r._entries[i])280return z281282cpdef Element _dot_product_(self, Vector right):283"""284Dot product of dense vectors over the rationals.285286EXAMPLES::287288sage: v = vector(QQ, [1,2,-3]); w = vector(QQ,[4,3,2])289sage: v*w2904291sage: w*v2924293"""294cdef Vector_rational_dense r = right295cdef Rational z296z = PY_NEW(Rational)297cdef mpq_t t298mpq_init(t)299mpq_set_si(z.value, 0, 1)300cdef Py_ssize_t i301for i from 0 <= i < self._degree:302mpq_mul(t, self._entries[i], r._entries[i])303mpq_add(z.value, z.value, t)304mpq_clear(t)305return z306307308cpdef Vector _pairwise_product_(self, Vector right):309"""310EXAMPLES::311312sage: v = vector(QQ, [1,2,-3]); w = vector(QQ,[4,3,2])313sage: v.pairwise_product(w)314(4, 6, -6)315"""316cdef Vector_rational_dense z, r317r = right318z = self._new_c()319cdef Py_ssize_t i320for i from 0 <= i < self._degree:321mpq_init(z._entries[i])322mpq_mul(z._entries[i], self._entries[i], r._entries[i])323return z324325cpdef ModuleElement _rmul_(self, RingElement left):326cdef Vector_rational_dense z327cdef Rational a328if PY_TYPE_CHECK(left, Rational):329a = <Rational>left330elif PY_TYPE_CHECK(left, Integer):331a = <Rational>PY_NEW(Rational)332mpq_set_z(a.value, (<Integer>left).value)333else:334# should not happen335raise TypeError("Cannot convert %s to %s" % (type(left).__name__, Rational.__name__))336z = self._new_c()337cdef Py_ssize_t i338for i from 0 <= i < self._degree:339mpq_init(z._entries[i])340mpq_mul(z._entries[i], self._entries[i], a.value)341return z342343344cpdef ModuleElement _lmul_(self, RingElement right):345cdef Vector_rational_dense z346cdef Rational a347if PY_TYPE_CHECK(right, Rational):348a = <Rational>right349elif PY_TYPE_CHECK(right, Integer):350a = <Rational>PY_NEW(Rational)351mpq_set_z(a.value, (<Integer>right).value)352else:353# should not happen354raise TypeError("Cannot convert %s to %s" % (type(right).__name__, Rational.__name__))355z = self._new_c()356cdef Py_ssize_t i357for i from 0 <= i < self._degree:358mpq_init(z._entries[i])359mpq_mul(z._entries[i], self._entries[i], a.value)360return z361362cpdef ModuleElement _neg_(self):363cdef Vector_rational_dense z364z = self._new_c()365cdef Py_ssize_t i366for i from 0 <= i < self._degree:367mpq_init(z._entries[i])368mpq_neg(z._entries[i], self._entries[i])369return z370371372def unpickle_v0(parent, entries, degree):373# If you think you want to change this function, don't.374# Instead make a new version with a name like375# make_FreeModuleElement_generic_dense_v1376# and changed the reduce method below.377cdef Vector_rational_dense v378v = PY_NEW(Vector_rational_dense)379v._init(degree, parent)380cdef Rational z381for i from 0 <= i < degree:382z = Rational(entries[i])383mpq_init(v._entries[i])384mpq_set(v._entries[i], z.value)385return v386387def unpickle_v1(parent, entries, degree, is_mutable):388cdef Vector_rational_dense v389v = PY_NEW(Vector_rational_dense)390v._init(degree, parent)391cdef Rational z392for i from 0 <= i < degree:393z = Rational(entries[i])394mpq_init(v._entries[i])395mpq_set(v._entries[i], z.value)396v._is_mutable = is_mutable397return v398399400