Path: blob/master/src/sage/modules/vector_integer_dense.pyx
8815 views
"""1Vectors with integer entries23AUTHOR:45- William Stein (2007)67EXAMPLES::89sage: v = vector(ZZ,[1,2,3,4,5])10sage: v11(1, 2, 3, 4, 5)12sage: 3*v13(3, 6, 9, 12, 15)14sage: v*715(7, 14, 21, 28, 35)16sage: -v17(-1, -2, -3, -4, -5)18sage: v - v19(0, 0, 0, 0, 0)20sage: v + v21(2, 4, 6, 8, 10)22sage: v * v # dot product.23552425We make a large zero vector::2627sage: k = ZZ^100000; k28Ambient free module of rank 100000 over the principal ideal domain Integer Ring29sage: v = k(0)30sage: v[:10]31(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)3233TESTS::3435sage: v = vector(ZZ, [1,2,3,4])36sage: loads(dumps(v)) == v37True38"""3940###############################################################################41# Sage: System for Algebra and Geometry Experimentation42# Copyright (C) 2007 William Stein <[email protected]>43# Distributed under the terms of the GNU General Public License (GPL)44# http://www.gnu.org/licenses/45###############################################################################4647include 'sage/ext/interrupt.pxi'48include 'sage/ext/stdsage.pxi'4950from sage.structure.element cimport Element, ModuleElement, RingElement, Vector5152from sage.rings.integer cimport Integer5354cimport free_module_element5556from free_module_element import vector5758cdef inline _Integer_from_mpz(mpz_t e):59cdef Integer z = PY_NEW(Integer)60mpz_set(z.value, e)61return z6263cdef class Vector_integer_dense(free_module_element.FreeModuleElement):64cdef _new_c(self):65cdef Vector_integer_dense y66y = PY_NEW(Vector_integer_dense)67y._init(self._degree, self._parent)68return y6970cdef bint is_dense_c(self):71return 172cdef bint is_sparse_c(self):73return 07475def __copy__(self):76cdef Vector_integer_dense y77y = self._new_c()78cdef Py_ssize_t i79for i from 0 <= i < self._degree:80mpz_init_set(y._entries[i], self._entries[i])81return y8283cdef _init(self, Py_ssize_t degree, parent):84self._degree = degree85self._parent = parent86self._is_mutable = 187self._entries = <mpz_t *> sage_malloc(sizeof(mpz_t) * degree)88if self._entries == NULL:89raise MemoryError9091def __cinit__(self, parent=None, x=None, coerce=True,copy=True):92self._entries = NULL93self._is_mutable = 194if not parent is None:95self._init(parent.degree(), parent)9697def __init__(self, parent, x, coerce=True, copy=True):98cdef Py_ssize_t i99cdef Integer z100# we have to do this to avoid a garbage collection error in dealloc101for i from 0 <= i < self._degree:102mpz_init(self._entries[i])103if isinstance(x, (list, tuple)):104if len(x) != self._degree:105raise TypeError("x must be a list of the right length")106for i from 0 <= i < self._degree:107z = Integer(x[i])108mpz_set(self._entries[i], z.value)109return110if x != 0:111raise TypeError("can't initialize vector from nonzero non-list")112113def __dealloc__(self):114cdef Py_ssize_t i115if self._entries:116for i from 0 <= i < self._degree:117mpz_clear(self._entries[i])118sage_free(self._entries)119120cdef int _cmp_c_impl(left, Element right) except -2:121"""122EXAMPLES::123124sage: v = vector(ZZ, [0,0,0,0])125sage: v == 0126True127sage: v == 1128False129sage: v == v130True131sage: w = vector(ZZ, [-1,0,0,0])132sage: w < v133True134sage: w > v135False136"""137cdef Py_ssize_t i138cdef int c139for i from 0 <= i < left.degree():140c = mpz_cmp(left._entries[i], (<Vector_integer_dense>right)._entries[i])141if c < 0:142return -1143elif c > 0:144return 1145return 0146147# see sage/structure/element.pyx148def __richcmp__(left, right, int op):149"""150TEST::151152sage: w = vector(ZZ, [-1,0,0,0])153sage: w == w154True155"""156return (<Element>left)._richcmp(right, op)157158# __hash__ is not properly inherited if comparison is changed159def __hash__(self):160"""161TEST::162163sage: w = vector(ZZ, [-1,0,0,0])164sage: w.set_immutable()165sage: isinstance(hash(w), int)166True167"""168return free_module_element.FreeModuleElement.__hash__(self)169170def __len__(self):171return self._degree172173def __setitem__(self, i, value):174"""175EXAMPLES::176177sage: v = vector([1,2,3]); v178(1, 2, 3)179sage: v[0] = 2180sage: v[1:3] = [1, 4]; v181(2, 1, 4)182"""183if not self._is_mutable:184raise ValueError("vector is immutable; please change a copy instead (use copy())")185cdef Integer z186cdef Py_ssize_t k, d, n187if isinstance(i, slice):188start, stop = i.start, i.stop189d = self.degree()190R = self.base_ring()191n = 0192for k from start <= k < stop:193if k >= d:194return195if k >= 0:196self[k] = R(value[n])197n = n + 1198else:199if i < 0 or i >= self._degree:200raise IndexError201else:202z = Integer(value)203mpz_set(self._entries[i], z.value)204205def __getitem__(self, i):206"""207Returns `i`-th entry or slice of self.208209EXAMPLES::210211sage: v = vector([1,2,3]); v212(1, 2, 3)213sage: v[0]2141215sage: v[-2]2162217sage: v[0:2]218(1, 2)219sage: v[5]220Traceback (most recent call last):221...222IndexError: index out of range223sage: v[-5]224Traceback (most recent call last):225...226IndexError: index out of range227"""228cdef Integer z = PY_NEW(Integer)229if isinstance(i, slice):230start, stop, step = i.indices(len(self))231return vector(self.base_ring(), self.list()[start:stop])232else:233if i < 0:234i += self._degree235if i < 0 or i >= self._degree:236raise IndexError('index out of range')237else:238mpz_set(z.value, self._entries[i])239return z240241def list(self,copy=True):242"""243The list of entries of the vector.244245INPUT:246247- ``copy``, ignored optional argument.248249EXAMPLES::250251sage: v = vector([1,2,3,4])252sage: a = v.list(copy=False); a253[1, 2, 3, 4]254sage: a[0] = 0255sage: v256(1, 2, 3, 4)257"""258cdef int i259return [_Integer_from_mpz(self._entries[i]) for i in260xrange(self._degree)]261262def __reduce__(self):263return (unpickle_v1, (self._parent, self.list(), self._degree, self._is_mutable))264265cpdef ModuleElement _add_(self, ModuleElement right):266cdef Vector_integer_dense z, r267r = right268z = self._new_c()269cdef Py_ssize_t i270for i from 0 <= i < self._degree:271mpz_init(z._entries[i])272mpz_add(z._entries[i], self._entries[i], r._entries[i])273return z274275276cpdef ModuleElement _sub_(self, ModuleElement right):277cdef Vector_integer_dense z, r278r = right279z = self._new_c()280cdef Py_ssize_t i281for i from 0 <= i < self._degree:282mpz_init(z._entries[i])283mpz_sub(z._entries[i], self._entries[i], r._entries[i])284return z285286cpdef Element _dot_product_(self, Vector right):287"""288Dot product of dense vectors over the integers.289290EXAMPLES::291292sage: v = vector(ZZ, [1,2,-3]); w = vector(ZZ,[4,3,2])293sage: v*w2944295sage: w*v2964297"""298cdef Vector_integer_dense r = right299cdef Integer z300z = PY_NEW(Integer)301cdef mpz_t t302mpz_init(t)303mpz_set_si(z.value, 0)304cdef Py_ssize_t i305for i from 0 <= i < self._degree:306mpz_mul(t, self._entries[i], r._entries[i])307mpz_add(z.value, z.value, t)308mpz_clear(t)309return z310311cpdef Vector _pairwise_product_(self, Vector right):312"""313EXAMPLES::314315sage: v = vector(ZZ, [1,2,-3]); w = vector(ZZ,[4,3,2])316sage: v.pairwise_product(w)317(4, 6, -6)318"""319cdef Vector_integer_dense z, r320r = right321z = self._new_c()322cdef Py_ssize_t i323for i from 0 <= i < self._degree:324mpz_init(z._entries[i])325mpz_mul(z._entries[i], self._entries[i], r._entries[i])326return z327328cpdef ModuleElement _rmul_(self, RingElement left):329cdef Vector_integer_dense z330cdef Integer a331a = left332z = self._new_c()333cdef Py_ssize_t i334for i from 0 <= i < self._degree:335mpz_init(z._entries[i])336mpz_mul(z._entries[i], self._entries[i], a.value)337return z338339cpdef ModuleElement _lmul_(self, RingElement right):340cdef Vector_integer_dense z341cdef Integer a342a = right343z = self._new_c()344cdef Py_ssize_t i345for i from 0 <= i < self._degree:346mpz_init(z._entries[i])347mpz_mul(z._entries[i], self._entries[i], a.value)348return z349350cpdef ModuleElement _neg_(self):351cdef Vector_integer_dense z352z = self._new_c()353cdef Py_ssize_t i354for i from 0 <= i < self._degree:355mpz_init(z._entries[i])356mpz_neg(z._entries[i], self._entries[i])357return z358359def _singular_(self, singular=None):360r"""361Return \Singular representation of this integer vector.362363INPUT:364365- singular -- \Singular interface instance (default: None)366367EXAMPLES::368369sage: A = random_matrix(ZZ,1,3)370sage: v = A.row(0)371sage: vs = singular(v); vs372-8,3732,3740375sage: vs.type()376'intvec'377"""378if singular is None:379from sage.interfaces.singular import singular as singular_default380singular = singular_default381382name = singular._next_var_name()383values = str(self.list())[1:-1]384singular.eval("intvec %s = %s"%(name, values))385386from sage.interfaces.singular import SingularElement387return SingularElement(singular, 'foobar', name, True)388389def unpickle_v0(parent, entries, degree):390# If you think you want to change this function, don't.391# Instead make a new version with a name like392# make_FreeModuleElement_generic_dense_v1393# and changed the reduce method below.394cdef Vector_integer_dense v395v = PY_NEW(Vector_integer_dense)396v._init(degree, parent)397cdef Integer z398for i from 0 <= i < degree:399z = Integer(entries[i])400mpz_init_set(v._entries[i], z.value)401return v402403def unpickle_v1(parent, entries, degree, is_mutable):404cdef Vector_integer_dense v405v = PY_NEW(Vector_integer_dense)406v._init(degree, parent)407cdef Integer z408for i from 0 <= i < degree:409z = Integer(entries[i])410mpz_init_set(v._entries[i], z.value)411v._is_mutable = is_mutable412return v413414415