diff --git a/src/sage/matrix/matrix_integer_dense.pyx b/src/sage/matrix/matrix_integer_dense.pyx index 7fe211835cc..0c411a72382 100644 --- a/src/sage/matrix/matrix_integer_dense.pyx +++ b/src/sage/matrix/matrix_integer_dense.pyx @@ -1614,7 +1614,7 @@ cdef class Matrix_integer_dense(Matrix_dense): return self._mod_two() elif p < MAX_MODULUS_FLOAT: res_f = Matrix_modn_dense_float.__new__(Matrix_modn_dense_float, - matrix_space.MatrixSpace(IntegerModRing(p), self._nrows, self._ncols, sparse=False), None, None, None) + matrix_space.MatrixSpace(IntegerModRing(p), self._nrows, self._ncols, sparse=False), None, None, None, zeroed_alloc=False) for i from 0 <= i < self._nrows: res_row_f = res_f._matrix[i] for j from 0 <= j < self._ncols: @@ -1623,7 +1623,7 @@ cdef class Matrix_integer_dense(Matrix_dense): elif p < MAX_MODULUS_DOUBLE: res_d = Matrix_modn_dense_double.__new__(Matrix_modn_dense_double, - matrix_space.MatrixSpace(IntegerModRing(p), self._nrows, self._ncols, sparse=False), None, None, None) + matrix_space.MatrixSpace(IntegerModRing(p), self._nrows, self._ncols, sparse=False), None, None, None, zeroed_alloc=False) for i from 0 <= i < self._nrows: res_row_d = res_d._matrix[i] for j from 0 <= j < self._ncols: @@ -1649,11 +1649,11 @@ cdef class Matrix_integer_dense(Matrix_dense): if p < MAX_MODULUS_FLOAT: res.append( Matrix_modn_dense_float.__new__(Matrix_modn_dense_float, matrix_space.MatrixSpace(IntegerModRing(p), self._nrows, self._ncols, sparse=False), - None, None, None) ) + None, None, None, zeroed_alloc=False) ) elif p < MAX_MODULUS_DOUBLE: res.append( Matrix_modn_dense_double.__new__(Matrix_modn_dense_double, matrix_space.MatrixSpace(IntegerModRing(p), self._nrows, self._ncols, sparse=False), - None, None, None) ) + None, None, None, zeroed_alloc=False) ) else: raise ValueError("p=%d too big."%p) diff --git a/src/sage/matrix/matrix_modn_dense_template.pxi b/src/sage/matrix/matrix_modn_dense_template.pxi index ca3382859f5..93933d5765d 100644 --- a/src/sage/matrix/matrix_modn_dense_template.pxi +++ b/src/sage/matrix/matrix_modn_dense_template.pxi @@ -90,7 +90,7 @@ We test corner cases for multiplication:: from libc.stdint cimport uint64_t from cpython.bytes cimport * -from cysignals.memory cimport check_malloc, check_allocarray, sig_malloc, sig_free +from cysignals.memory cimport check_malloc, check_allocarray, check_calloc, sig_malloc, sig_free from cysignals.signals cimport sig_check, sig_on, sig_off from sage.libs.gmp.mpz cimport * @@ -123,7 +123,7 @@ from sage.structure.proof.proof import get_flag as get_proof_flag from sage.structure.richcmp cimport rich_to_bool from sage.misc.randstate cimport randstate, current_randstate import sage.matrix.matrix_space as matrix_space -from .args cimport MatrixArgs_init +from .args cimport SparseEntry, MatrixArgs_init from sage.cpython.string cimport char_to_str @@ -441,15 +441,18 @@ cpdef __matrix_from_rows_of_matrices(X): cdef class Matrix_modn_dense_template(Matrix_dense): - def __cinit__(self): + def __cinit__(self, *args, bint zeroed_alloc=True, **kwds): cdef long p = self._base_ring.characteristic() self.p = p if p >= MAX_MODULUS: raise OverflowError("p (=%s) must be < %s."%(p, MAX_MODULUS)) - self._entries = check_allocarray(self._nrows * self._ncols, sizeof(celement)) + if zeroed_alloc: + self._entries = check_calloc(self._nrows * self._ncols, sizeof(celement)) + else: + self._entries = check_allocarray(self._nrows * self._ncols, sizeof(celement)) + self._matrix = check_allocarray(self._nrows, sizeof(celement*)) - cdef unsigned int k cdef Py_ssize_t i k = 0 @@ -518,27 +521,28 @@ cdef class Matrix_modn_dense_template(Matrix_dense): """ ma = MatrixArgs_init(parent, entries) cdef long i, j - it = ma.iter(False) + it = ma.iter(convert=False, sparse=True) R = ma.base p = R.characteristic() - for i in range(ma.nrows): - v = self._matrix[i] - for j in range(ma.ncols): - x = next(it) - if type(x) is int: - tmp = (x) % p - v[j] = tmp + (tmp<0)*p - elif type(x) is IntegerMod_int and (x)._parent is R: - v[j] = (x).ivalue - elif type(x) is Integer: - if coerce: - v[j] = mpz_fdiv_ui((x).value, p) - else: - v[j] = mpz_get_ui((x).value) - elif coerce: - v[j] = R(x) + + for t in it: + se = t + x = se.entry + v = self._matrix[se.i] + if type(x) is int: + tmp = (x) % p + v[se.j] = tmp + (tmp<0)*p + elif type(x) is IntegerMod_int and (x)._parent is R: + v[se.j] = (x).ivalue + elif type(x) is Integer: + if coerce: + v[se.j] = mpz_fdiv_ui((x).value, p) else: - v[j] = x + v[se.j] = mpz_get_ui((x).value) + elif coerce: + v[se.j] = R(x) + else: + v[se.j] = x cdef long _hash_(self) except -1: """ @@ -786,7 +790,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): cdef Matrix_modn_dense_template M cdef celement p = self.p - M = self.__class__.__new__(self.__class__, self._parent,None,None,None) + M = self.__class__.__new__(self.__class__, self._parent,None,None,None, zeroed_alloc=False) sig_on() for i in range(self._nrows*self._ncols): @@ -825,7 +829,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): cdef celement p = self.p cdef celement a = left - M = self.__class__.__new__(self.__class__, self._parent,None,None,None) + M = self.__class__.__new__(self.__class__, self._parent,None,None,None,zeroed_alloc=False) sig_on() for i in range(self._nrows*self._ncols): @@ -844,7 +848,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): False """ cdef Matrix_modn_dense_template A - A = self.__class__.__new__(self.__class__, self._parent, 0, 0, 0) + A = self.__class__.__new__(self.__class__,self._parent,None,None,None,zeroed_alloc=False) memcpy(A._entries, self._entries, sizeof(celement)*self._nrows*self._ncols) if self._subdivisions is not None: A.subdivide(*self.subdivisions()) @@ -883,7 +887,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): cdef celement k, p cdef Matrix_modn_dense_template M - M = self.__class__.__new__(self.__class__, self._parent,None,None,None) + M = self.__class__.__new__(self.__class__, self._parent,None,None,None,zeroed_alloc=False) p = self.p cdef celement* other_ent = (right)._entries @@ -920,7 +924,7 @@ cdef class Matrix_modn_dense_template(Matrix_dense): cdef celement k, p cdef Matrix_modn_dense_template M - M = self.__class__.__new__(self.__class__, self._parent, None, None, None) + M = self.__class__.__new__(self.__class__, self._parent, None, None, None, zeroed_alloc=False) p = self.p cdef celement* other_ent = (right)._entries