Path: blob/master/src/sage/modules/vector_modn_dense.pyx
8815 views
"""1Vectors with integer mod n entries, with n small.23AUTHOR:4-- William Stein (2007)56EXAMPLES:7sage: v = vector(Integers(8),[1,2,3,4,5])8sage: type(v)9<type 'sage.modules.vector_modn_dense.Vector_modn_dense'>10sage: v11(1, 2, 3, 4, 5)12sage: 3*v13(3, 6, 1, 4, 7)14sage: v*715(7, 6, 5, 4, 3)16sage: -v17(7, 6, 5, 4, 3)18sage: v - v19(0, 0, 0, 0, 0)20sage: v + v21(2, 4, 6, 0, 2)22sage: v * v2372425sage: v = vector(Integers(8),[1,2,3,4,5])26sage: u = vector(Integers(8),[1,2,3,4,4])27sage: v - u28(0, 0, 0, 0, 1)29sage: u - v30(0, 0, 0, 0, 7)3132sage: v = vector((Integers(5)(1),2,3,4,4))33sage: u = vector((Integers(5)(1),2,3,4,3))34sage: v - u35(0, 0, 0, 0, 1)36sage: u - v37(0, 0, 0, 0, 4)3839We make a large zero vector:40sage: k = Integers(8)^100000; k41Ambient free module of rank 100000 over Ring of integers modulo 842sage: v = k(0)43sage: v[:10]44(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)4546We multiply a vector by a matrix:47sage: a = (GF(97)^5)(range(5))48sage: m = matrix(GF(97),5,range(25))49sage: a*m50(53, 63, 73, 83, 93)5152TESTS:53sage: v = vector(Integers(8), [1,2,3,4,5])54sage: loads(dumps(v)) == v55True56sage: v = vector(Integers(389), [1,2,3,4,5])57sage: loads(dumps(v)) == v58True59sage: v = vector(Integers(next_prime(10^20)), [1,2,3,4,5])60sage: loads(dumps(v)) == v61True6263sage: K = GF(previous_prime(2^31))64sage: v = vector(K, [42]); type(v[0])65<type 'sage.rings.finite_rings.integer_mod.IntegerMod_int64'>66sage: ~v[0]6720963530846869sage: K = GF(next_prime(2^31))70sage: v = vector(K, [42]); type(v[0])71<type 'sage.rings.finite_rings.integer_mod.IntegerMod_gmp'>72sage: ~v[0]73148278633674"""7576###############################################################################77# Sage: System for Algebra and Geometry Experimentation78# Copyright (C) 2007 William Stein <[email protected]>79# Distributed under the terms of the GNU General Public License (GPL)80# http://www.gnu.org/licenses/81###############################################################################8283include 'sage/ext/interrupt.pxi'84include 'sage/ext/stdsage.pxi'8586from sage.rings.finite_rings.stdint cimport INTEGER_MOD_INT64_LIMIT8788MAX_MODULUS = INTEGER_MOD_INT64_LIMIT8990from sage.rings.finite_rings.integer_mod cimport (91IntegerMod_int, IntegerMod_int64,92IntegerMod_abstract, use_32bit_type)9394cdef mod_int ivalue(IntegerMod_abstract x) except -1:95if PY_TYPE_CHECK_EXACT(x, IntegerMod_int):96return (<IntegerMod_int>x).ivalue97elif PY_TYPE_CHECK_EXACT(x, IntegerMod_int64):98return (<IntegerMod_int64>x).ivalue99else:100raise TypeError, "non-fixed size integer"101102from sage.structure.element cimport Element, ModuleElement, RingElement, Vector103104cimport free_module_element105from free_module_element import vector106107cdef class Vector_modn_dense(free_module_element.FreeModuleElement):108cdef _new_c(self):109cdef Vector_modn_dense y110y = PY_NEW(Vector_modn_dense)111y._init(self._degree, self._parent, self._p)112return y113114cdef bint is_dense_c(self):115return 1116117cdef bint is_sparse_c(self):118return 0119120def __copy__(self):121cdef Vector_modn_dense y122y = self._new_c()123cdef Py_ssize_t i124for i from 0 <= i < self._degree:125y._entries[i] = self._entries[i]126return y127128cdef _init(self, Py_ssize_t degree, parent, mod_int p):129self._degree = degree130self._parent = parent131self._p = p132self._entries = <mod_int *> sage_malloc(sizeof(mod_int) * degree)133if self._entries == NULL:134raise MemoryError135136def __cinit__(self, parent=None, x=None, coerce=True, copy=True):137self._entries = NULL138self._is_mutable = 1139if not parent is None:140self._init(parent.degree(), parent, parent.base_ring().order())141142def __init__(self, parent, x, coerce=True, copy=True):143cdef Py_ssize_t i144cdef mod_int a, p145if isinstance(x, (list, tuple)):146if len(x) != self._degree:147raise TypeError("x must be a list of the right length")148if coerce:149R = parent.base_ring()150p = R.order()151for i from 0 <= i < self._degree:152a = int(R(x[i]))153self._entries[i] = a%p154else:155for i from 0 <= i < self._degree:156self._entries[i] = x[i]157return158if x != 0:159raise TypeError("can't initialize vector from nonzero non-list")160else:161for i from 0 <= i < self._degree:162self._entries[i] = 0163164def __dealloc__(self):165cdef Py_ssize_t i166if self._entries:167sage_free(self._entries)168169cdef int _cmp_c_impl(left, Element right) except -2:170"""171EXAMPLES:172sage: v = vector(GF(5), [0,0,0,0])173sage: v == 0174True175sage: v == 1176False177sage: v == v178True179sage: w = vector(GF(11), [1,0,0,0])180sage: w < v181True182sage: w > v183False184"""185cdef Py_ssize_t i186cdef mod_int l, r187for i from 0 <= i < left.degree():188l = left._entries[i]189r = (<Vector_modn_dense>right)._entries[i]190if l < r:191return -1192elif l > r:193return 1194return 0195# see sage/structure/element.pyx196def __richcmp__(left, right, int op):197"""198TEST::199200sage: w = vector(GF(11), [-1,0,0,0])201sage: w == w202True203"""204return (<Element>left)._richcmp(right, op)205206# __hash__ is not properly inherited if comparison is changed207def __hash__(self):208"""209TEST::210211sage: w = vector(GF(11), [-1,0,0,0])212sage: w.set_immutable()213sage: isinstance(hash(w), int)214True215"""216return free_module_element.FreeModuleElement.__hash__(self)217218def __len__(self):219return self._degree220221def __setitem__(self, i, value):222if not self._is_mutable:223raise ValueError("vector is immutable; please change a copy instead (use copy())")224cdef Py_ssize_t k, d, n225if isinstance(i, slice):226start, stop = i.start, i.stop227d = self.degree()228R = self.base_ring()229n = 0230for k from start <= k < stop:231if k >= d:232return233if k >= 0:234self[k] = R(value[n])235n = n + 1236else:237if i < 0 or i >= self._degree:238raise IndexError239else:240self._entries[i] = ivalue(self.base_ring()(value))241242def __getitem__(self, i):243"""244Returns `i`-th entry or slice of self.245246EXAMPLES:247sage: R = Integers(7)248sage: v = vector(R, [1,2,3]); v249(1, 2, 3)250sage: v[0]2511252sage: v[2]2533254sage: v[-2]2552256sage: v[0:2]257(1, 2)258sage: v[5]259Traceback (most recent call last):260...261IndexError: index out of range262sage: v[-5]263Traceback (most recent call last):264...265IndexError: index out of range266"""267if isinstance(i, slice):268start, stop, step = i.indices(len(self))269return vector(self.base_ring(), self.list()[start:stop])270271if i < 0:272i += self._degree273if i < 0 or i >= self._degree:274raise IndexError('index out of range')275cdef IntegerMod_int n276cdef IntegerMod_int64 m277278if use_32bit_type(self._p):279n = IntegerMod_int.__new__(IntegerMod_int)280IntegerMod_abstract.__init__(n, self.base_ring())281n.ivalue = self._entries[i]282return n283else:284m = IntegerMod_int64.__new__(IntegerMod_int64)285IntegerMod_abstract.__init__(m, self.base_ring())286m.ivalue = self._entries[i]287return m288289def __reduce__(self):290return unpickle_v1, (self._parent, self.list(), self._degree, self._p, self._is_mutable)291292cpdef ModuleElement _add_(self, ModuleElement right):293cdef Vector_modn_dense z, r294r = right295z = self._new_c()296cdef Py_ssize_t i297for i from 0 <= i < self._degree:298z._entries[i] = (self._entries[i] + r._entries[i]) % self._p299return z300301302cpdef ModuleElement _sub_(self, ModuleElement right):303cdef Vector_modn_dense z, r304r = right305z = self._new_c()306cdef Py_ssize_t i307for i from 0 <= i < self._degree:308z._entries[i] = (self._p + self._entries[i] - r._entries[i]) % self._p309return z310311cpdef Element _dot_product_(self, Vector right):312cdef Py_ssize_t i313cdef IntegerMod_int n314cdef Vector_modn_dense r = right315n = IntegerMod_int.__new__(IntegerMod_int)316IntegerMod_abstract.__init__(n, self.base_ring())317n.ivalue = 0318319for i from 0 <= i < self._degree:320n.ivalue = (n.ivalue + self._entries[i] * r._entries[i]) % self._p321322return n323324cpdef Vector _pairwise_product_(self, Vector right):325"""326EXAMPLES:327sage: v = vector(Integers(8), [2,3]); w = vector(Integers(8), [2,5])328sage: v * w3293330sage: w * v3313332"""333cdef Vector_modn_dense z, r334r = right335z = self._new_c()336cdef Py_ssize_t i337for i from 0 <= i < self._degree:338z._entries[i] = (self._entries[i] * r._entries[i]) % self._p339return z340341cpdef ModuleElement _rmul_(self, RingElement left):342cdef Vector_modn_dense z343344cdef mod_int a = ivalue(left)345z = self._new_c()346cdef Py_ssize_t i347348for i from 0 <= i < self._degree:349z._entries[i] = (self._entries[i] * a) % self._p350return z351352cpdef ModuleElement _lmul_(self, RingElement right):353return self._rmul_(right)354355cpdef ModuleElement _neg_(self):356cdef Vector_modn_dense z357z = self._new_c()358cdef Py_ssize_t i359for i from 0 <= i < self._degree:360if self._entries[i] > 0:361z._entries[i] = self._p - self._entries[i]362else:363z._entries[i] = 0364return z365366def unpickle_v0(parent, entries, degree, p):367# If you think you want to change this function, don't.368# Instead make a new version with a name like369# make_FreeModuleElement_generic_dense_v1370# and changed the reduce method below.371cdef Vector_modn_dense v372v = PY_NEW(Vector_modn_dense)373v._init(degree, parent, p)374for i from 0 <= i < degree:375v._entries[i] = entries[i]376return v377378def unpickle_v1(parent, entries, degree, p, is_mutable):379cdef Vector_modn_dense v380v = PY_NEW(Vector_modn_dense)381v._init(degree, parent, p)382for i from 0 <= i < degree:383v._entries[i] = entries[i]384v._is_mutable = is_mutable385return v386387388