Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/sage/matrix/matrix0.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ cdef class Matrix(sage.structure.element.Matrix):
# Unsafe entry access
cdef set_unsafe(self, Py_ssize_t i, Py_ssize_t j, object x)
cdef get_unsafe(self, Py_ssize_t i, Py_ssize_t j)
cdef copy_from_unsafe(self, Py_ssize_t iDst, Py_ssize_t jDst, src, Py_ssize_t iSrc, Py_ssize_t jSrc)
cdef _coerce_element(self, x)
cdef bint get_is_zero_unsafe(self, Py_ssize_t i, Py_ssize_t j) except -1

Expand Down
8 changes: 8 additions & 0 deletions src/sage/matrix/matrix0.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,14 @@ cdef class Matrix(sage.structure.element.Matrix):
"""
raise NotImplementedError("this must be defined in the derived type.")

cdef copy_from_unsafe(self, Py_ssize_t iDst, Py_ssize_t jDst, src, Py_ssize_t iSrc, Py_ssize_t jSrc):
"""
Copy from one matrix to another. It is assumed ``src`` is the same type of matrix as ``self``, with the same base ring.

This is fast because it avoids the type conversion that often is necessary in ``get_unsafe`` and ``set_unsafe``.
"""
raise NotImplementedError("this must be defined in the derived type.")

cdef bint get_is_zero_unsafe(self, Py_ssize_t i, Py_ssize_t j) except -1:
"""
Return 1 if the entry ``(i, j)`` is zero, otherwise 0.
Expand Down
6 changes: 3 additions & 3 deletions src/sage/matrix/matrix1.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -2043,7 +2043,7 @@ cdef class Matrix(Matrix0):
if col < 0 or col >= self._ncols:
raise IndexError("column index out of range")
for i in range(self._nrows):
A.set_unsafe(i, j, self.get_unsafe(i, col))
A.copy_from_unsafe(i, j, self, i, col)
return A

def delete_columns(self, dcols, check=True):
Expand Down Expand Up @@ -2141,7 +2141,7 @@ cdef class Matrix(Matrix0):
if row < 0 or row >= self._nrows:
raise IndexError("row index out of range")
for j in range(self._ncols):
A.set_unsafe(i, j, self.get_unsafe(row, j))
A.copy_from_unsafe(i, j, self, row, j)
return A

def delete_rows(self, drows, check=True):
Expand Down Expand Up @@ -2268,7 +2268,7 @@ cdef class Matrix(Matrix0):
if row < 0 or row >= self._nrows:
raise IndexError("row index out of range")
for j, col in enumerate(columns):
A.set_unsafe(i, j, self.get_unsafe(row, col))
A.copy_from_unsafe(i, j, self, row, col)
return A

def submatrix(self, Py_ssize_t row=0, Py_ssize_t col=0,
Expand Down
13 changes: 13 additions & 0 deletions src/sage/matrix/matrix_complex_ball_dense.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,19 @@ cdef class Matrix_complex_ball_dense(Matrix_dense):
acb_set(z.value, acb_mat_entry(self.value, i, j))
return z

cdef copy_from_unsafe(self, Py_ssize_t iDst, Py_ssize_t jDst, src, Py_ssize_t iSrc, Py_ssize_t jSrc):
"""
Copy the ``(iSrc, jSrc)`` entry of ``src`` into the ``(iDst, jDst)`` entry of this matrix.

.. warning::

This is very unsafe; it assumes ``iSrc``, ``jSrc``, ``iDst`` and ``jDst`` are in the right
range, and that ``src`` is a
Matrix_complex_ball_dense with the same base ring as ``self``.
"""
cdef Matrix_complex_ball_dense _src = <Matrix_complex_ball_dense> src
acb_set(acb_mat_entry(self.value, iDst, jDst), acb_mat_entry(_src.value, iSrc, jSrc))

cpdef _richcmp_(left, right, int op):
r"""
EXAMPLES::
Expand Down
12 changes: 12 additions & 0 deletions src/sage/matrix/matrix_cyclo_dense.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,18 @@ cdef class Matrix_cyclo_dense(Matrix_dense):

return x

cdef copy_from_unsafe(self, Py_ssize_t iDst, Py_ssize_t jDst, src, Py_ssize_t iSrc, Py_ssize_t jSrc):
"""
Copy the (iSrc,jSrc)-th entry of ``src`` to the (iDst,jDst)-th entry ``self``.

WARNING: As the name suggests, expect segfaults if iSrc,jSrc,iDst,jDst are out
of bounds!! This is for internal use only. This method assumes ``src`` is a Matrix_cyclo_dense with the same base ring as ``self``.
"""
cdef Matrix_cyclo_dense _src = src
cdef int a
for a in range(self._degree):
self._matrix.copy_from_unsafe(a, jDst + iDst*self._ncols, _src._matrix, a, jSrc + iSrc*_src._ncols)

cdef bint get_is_zero_unsafe(self, Py_ssize_t i, Py_ssize_t j) except -1:
r"""
Return 1 if the entry ``(i, j)`` is zero, otherwise 0.
Expand Down
4 changes: 2 additions & 2 deletions src/sage/matrix/matrix_dense.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ cdef class Matrix_dense(matrix.Matrix):
cdef Py_ssize_t i, j
for j from 0<= j < nc:
for i from 0<= i < nr:
trans.set_unsafe(j,i,self.get_unsafe(i,j))
trans.copy_from_unsafe(j, i, self, i, j)

if self._subdivisions is not None:
row_divs, col_divs = self.subdivisions()
Expand Down Expand Up @@ -183,7 +183,7 @@ cdef class Matrix_dense(matrix.Matrix):
rj -= 1
for i from 0 <= i < nr:
ri -= 1
atrans.set_unsafe(j, i, self.get_unsafe(ri, rj))
atrans.copy_from_unsafe(j, i, self, ri, rj)

if self._subdivisions is not None:
row_divs, col_divs = self.subdivisions()
Expand Down
4 changes: 4 additions & 0 deletions src/sage/matrix/matrix_gap.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,10 @@ cdef class Matrix_gap(Matrix_dense):
"""
self._libgap[i,j] = x

cdef copy_from_unsafe(self, Py_ssize_t iDst, Py_ssize_t jDst, src, Py_ssize_t iSrc, Py_ssize_t jSrc):
cdef Matrix_gap _src = <Matrix_gap>src
self._libgap[iDst,jDst] = _src._libgap[iSrc,jSrc]

cpdef _richcmp_(self, other, int op):
r"""
Compare ``self`` and ``right``.
Expand Down
4 changes: 4 additions & 0 deletions src/sage/matrix/matrix_generic_dense.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ cdef class Matrix_generic_dense(matrix_dense.Matrix_dense):
cdef get_unsafe(self, Py_ssize_t i, Py_ssize_t j):
return self._entries[i*self._ncols + j]

cdef copy_from_unsafe(self, Py_ssize_t iDst, Py_ssize_t jDst, src, Py_ssize_t iSrc, Py_ssize_t jSrc):
cdef Matrix_generic_dense _src = <Matrix_generic_dense>src
self._entries[iDst*self._ncols + jDst] = _src._entries[iSrc*_src._ncols + jSrc]

def _reverse_unsafe(self):
r"""
TESTS::
Expand Down
7 changes: 7 additions & 0 deletions src/sage/matrix/matrix_generic_sparse.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,13 @@ cdef class Matrix_generic_sparse(matrix_sparse.Matrix_sparse):
cdef get_unsafe(self, Py_ssize_t i, Py_ssize_t j):
return self._entries.get((i,j), self._zero)

cdef copy_from_unsafe(self, Py_ssize_t iDst, Py_ssize_t jDst, src, Py_ssize_t iSrc, Py_ssize_t jSrc):
cdef Matrix_generic_sparse _src = <Matrix_generic_sparse>src
if (iSrc,jSrc) in _src._entries:
self._entries[(iDst,jDst)] = _src._entries.get((iSrc, jSrc), _src._zero)
elif (iDst,jDst) in self._entries:
del self._entries[(iDst,jDst)]

cdef bint get_is_zero_unsafe(self, Py_ssize_t i, Py_ssize_t j) except -1:
"""
Return 1 if the entry ``(i, j)`` is zero, otherwise 0.
Expand Down
16 changes: 16 additions & 0 deletions src/sage/matrix/matrix_gf2e_dense.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ REFERENCES:
#*****************************************************************************

from cysignals.signals cimport sig_on, sig_off
from cpython.sequence cimport PySequence_Fast

cimport sage.matrix.matrix_dense as matrix_dense
from sage.structure.element cimport Matrix
Expand Down Expand Up @@ -284,6 +285,21 @@ cdef class Matrix_gf2e_dense(matrix_dense.Matrix_dense):
cdef Cache_base cache = <Cache_base> self._base_ring._cache
return cache.fetch_int(r)

cdef copy_from_unsafe(self, Py_ssize_t iDst, Py_ssize_t jDst, src, Py_ssize_t iSrc, Py_ssize_t jSrc):
"""
A[iDst,jDst] = B[iSrc,jSrc] without bound checks.

INPUT:

- ``iDst`` -- row index
- ``jDst`` -- column index
- ``src`` -- source matrix, assumed to be a Matrix_gf2e_dense, with same base ring
- ``iSrc`` -- row index
- ``jSrc`` -- column index
"""
cdef Matrix_gf2e_dense _src = <Matrix_gf2e_dense>src
mzed_write_elem(self._entries, iDst, jDst, mzed_read_elem(_src._entries, iSrc, jSrc))

cdef bint get_is_zero_unsafe(self, Py_ssize_t i, Py_ssize_t j) except -1:
r"""
Return 1 if the entry ``(i, j)`` is zero, otherwise 0.
Expand Down
7 changes: 7 additions & 0 deletions src/sage/matrix/matrix_gfpn_dense.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,13 @@ cdef class Matrix_gfpn_dense(Matrix_dense):
finally:
sig_off()

cdef copy_from_unsafe(self, Py_ssize_t iDst, Py_ssize_t jDst, src, Py_ssize_t iSrc, Py_ssize_t jSrc):
"""
Copies values without bound or type checking.
"""
cdef Matrix_gfpn_dense _src = <Matrix_gfpn_dense>src
FfInsert(FfGetPtr(self.Data.Data, iDst), jDst, FfExtract(MatGetPtr(_src.Data,iSrc), jSrc))

def randomize(self, density=None, nonzero=False, *args, **kwds):
"""
Fill the matrix with random values.
Expand Down
16 changes: 16 additions & 0 deletions src/sage/matrix/matrix_integer_dense.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,22 @@ cdef class Matrix_integer_dense(Matrix_dense):
"""
return fmpz_is_zero(fmpz_mat_entry(self._matrix, i,j))

cdef copy_from_unsafe(self, Py_ssize_t iDst, Py_ssize_t jDst, src, Py_ssize_t iSrc, Py_ssize_t jSrc):
"""Copy position iSrc,jSrc of ``src`` to position iDst,jDst of this matrix.

The object ``src`` must be of type ``Matrix_integer_dense`` and have the same base ring as ``self``.

INPUT:

- ``iDst`` -- row

- ``jDst`` -- column

- ``src`` -- must be Matrix_integer_dense! The value to set ``self[i,j]`` to.
"""
cdef Matrix_integer_dense _src = <Matrix_integer_dense> src
fmpz_set(fmpz_mat_entry(self._matrix, iDst, jDst), fmpz_mat_entry(_src._matrix, iSrc, jSrc))

def _pickle(self):
"""
EXAMPLES::
Expand Down
7 changes: 7 additions & 0 deletions src/sage/matrix/matrix_integer_sparse.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@ cdef class Matrix_integer_sparse(Matrix_sparse):
mpz_vector_get_entry(x.value, &self._matrix[i], j)
return x

cdef copy_from_unsafe(self, Py_ssize_t iDst, Py_ssize_t jDst, src, Py_ssize_t iSrc, Py_ssize_t jSrc):
cdef Integer x
x = Integer()
cdef Matrix_integer_sparse _src = <Matrix_integer_sparse> src
mpz_vector_get_entry(x.value, &_src._matrix[iSrc], jSrc)
mpz_vector_set_entry(&self._matrix[iDst], jDst, x.value)

cdef bint get_is_zero_unsafe(self, Py_ssize_t i, Py_ssize_t j) except -1:
"""
Return 1 if the entry ``(i, j)`` is zero, otherwise 0.
Expand Down
5 changes: 5 additions & 0 deletions src/sage/matrix/matrix_mod2_dense.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ TESTS::

from cysignals.memory cimport check_malloc, sig_free
from cysignals.signals cimport sig_on, sig_str, sig_off
from cpython.sequence cimport PySequence_Fast

cimport sage.matrix.matrix_dense as matrix_dense
from sage.matrix.args cimport SparseEntry, MatrixArgs_init, MA_ENTRIES_NDARRAY
Expand Down Expand Up @@ -360,6 +361,10 @@ cdef class Matrix_mod2_dense(matrix_dense.Matrix_dense): # dense or sparse
else:
return self._zero

cdef copy_from_unsafe(self, Py_ssize_t iDst, Py_ssize_t jDst, src, Py_ssize_t iSrc, Py_ssize_t jSrc):
cdef Matrix_mod2_dense _src = <Matrix_mod2_dense>src
mzd_write_bit(self._entries, iDst, jDst, mzd_read_bit(_src._entries, iSrc, jSrc))

def str(self, rep_mapping=None, zero=None, plus_one=None, minus_one=None,
*, unicode=False, shape=None, character_art=False,
left_border=None, right_border=None,
Expand Down
10 changes: 10 additions & 0 deletions src/sage/matrix/matrix_modn_dense_double.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,13 @@ cdef class Matrix_modn_dense_double(Matrix_modn_dense_template):
return (<IntegerMod_int>_self._get_template)._new_c(<int_fast32_t>result)
else:
return (<IntegerMod_int64>_self._get_template)._new_c(<int_fast64_t>result)

cdef copy_from_unsafe(self, Py_ssize_t iDst, Py_ssize_t jDst, src, Py_ssize_t iSrc, Py_ssize_t jSrc):
r"""
Copies the (iSrc,jSrc) entry of ``src`` to the (iDst,jDst) entry of ``self`` with no bounds-checking, or any other checks.

Assumes that ``src`` is a Matrix_modn_dense_double with the same base ring as ``self``.
"""
cdef Matrix_modn_dense_double _src = <Matrix_modn_dense_double>src
self._matrix[iDst][jDst] = _src._matrix[iSrc][jSrc]

9 changes: 9 additions & 0 deletions src/sage/matrix/matrix_modn_dense_float.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -151,3 +151,12 @@ cdef class Matrix_modn_dense_float(Matrix_modn_dense_template):
"""
cdef float result = (<Matrix_modn_dense_template>self)._matrix[i][j]
return (<Matrix_modn_dense_float>self)._get_template._new_c(<int_fast32_t>result)

cdef copy_from_unsafe(self, Py_ssize_t iDst, Py_ssize_t jDst, src, Py_ssize_t iSrc, Py_ssize_t jSrc):
"""
Copies the (iSrc,jSrc) entry of ``src`` to the (iDst,jDst) entry of ``self`` with no bounds-checking, or any other checks.

Assumes that ``src`` is a Matrix_modn_dense_float with the same base ring as ``self``.
"""
cdef Matrix_modn_dense_float _src = <Matrix_modn_dense_float>src
self._matrix[iDst][jDst] = _src._matrix[iSrc][jSrc]
4 changes: 4 additions & 0 deletions src/sage/matrix/matrix_modn_sparse.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ cdef class Matrix_modn_sparse(Matrix_sparse):
n.ivalue = get_entry(&self.rows[i], j)
return n

cdef copy_from_unsafe(self, Py_ssize_t iDst, Py_ssize_t jDst, src, Py_ssize_t iSrc, Py_ssize_t jSrc):
cdef Matrix_modn_sparse _src = <Matrix_modn_sparse>src
set_entry(&self.rows[iDst], jDst, get_entry(&_src.rows[iSrc], jSrc))

cdef bint get_is_zero_unsafe(self, Py_ssize_t i, Py_ssize_t j) except -1:
"""
Return 1 if the entry ``(i, j)`` is zero, otherwise 0.
Expand Down
10 changes: 10 additions & 0 deletions src/sage/matrix/matrix_numpy_dense.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,16 @@ cdef class Matrix_numpy_dense(Matrix_dense):
return self._sage_dtype(cnumpy.PyArray_GETITEM(self._matrix_numpy,
cnumpy.PyArray_GETPTR2(self._matrix_numpy, i, j)))

cdef copy_from_unsafe(self, Py_ssize_t iDst, Py_ssize_t jDst, src, Py_ssize_t iSrc, Py_ssize_t jSrc):
"""
Copy the (iDst,jDst) entry of ``src`` to the ``(iSrc,jSrc)`` entry of ``self`` without any bounds checking,
mutability checking, etc.

``src`` is assumed to be a Matrix_numpy_dense
"""
cdef Matrix_numpy_dense _src = <Matrix_numpy_dense>src
cnumpy.PyArray_SETITEM(self._matrix_numpy, cnumpy.PyArray_GETPTR2(self._matrix_numpy, iDst, jDst), cnumpy.PyArray_GETITEM(_src._matrix_numpy, cnumpy.PyArray_GETPTR2(_src._matrix_numpy, iSrc, jSrc)))

cdef Matrix_numpy_dense _new(self, int nrows=-1, int ncols=-1):
"""
Return a new uninitialized matrix with same parent as ``self``.
Expand Down
4 changes: 4 additions & 0 deletions src/sage/matrix/matrix_rational_dense.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,10 @@ cdef class Matrix_rational_dense(Matrix_dense):
fmpq_get_mpq(x.value, fmpq_mat_entry(self._matrix, i, j))
return x

cdef copy_from_unsafe(self, Py_ssize_t iDst, Py_ssize_t jDst, src, Py_ssize_t iSrc, Py_ssize_t jSrc):
cdef Matrix_rational_dense _src = <Matrix_rational_dense> src
fmpq_set(fmpq_mat_entry(self._matrix, iDst, jDst), fmpq_mat_entry(_src._matrix, iSrc, jSrc))

cdef bint get_is_zero_unsafe(self, Py_ssize_t i, Py_ssize_t j) except -1:
"""
Return 1 if the entry (i, j) is zero, otherwise 0.
Expand Down
7 changes: 7 additions & 0 deletions src/sage/matrix/matrix_rational_sparse.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ cdef class Matrix_rational_sparse(Matrix_sparse):
mpq_vector_get_entry(x.value, &self._matrix[i], j)
return x

cdef copy_from_unsafe(self, Py_ssize_t iDst, Py_ssize_t jDst, src, Py_ssize_t iSrc, Py_ssize_t jSrc):
cdef Rational x
x = Rational()
cdef Matrix_rational_sparse _src = <Matrix_rational_sparse> src
mpq_vector_get_entry(x.value, &_src._matrix[iSrc], jSrc)
mpq_vector_set_entry(&self._matrix[iDst], jDst, x.value)

cdef bint get_is_zero_unsafe(self, Py_ssize_t i, Py_ssize_t j) except -1:
"""
Return 1 if the entry ``(i, j)`` is zero, otherwise 0.
Expand Down
4 changes: 2 additions & 2 deletions src/sage/matrix/matrix_sparse.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ cdef class Matrix_sparse(matrix.Matrix):
for k from 0 <= k < len(nz):
i = get_ij(nz, k, 0)
j = get_ij(nz, k, 1)
A.set_unsafe(j,i,self.get_unsafe(i,j))
A.copy_from_unsafe(j, i, self, i, j)
if self._subdivisions is not None:
row_divs, col_divs = self.subdivisions()
A.subdivide(col_divs, row_divs)
Expand Down Expand Up @@ -464,7 +464,7 @@ cdef class Matrix_sparse(matrix.Matrix):
for k from 0 <= k < len(nz):
i = get_ij(nz, k, 0)
j = get_ij(nz, k, 1)
A.set_unsafe(self._ncols-j-1, self._nrows-i-1,self.get_unsafe(i,j))
A.copy_from_unsafe(self._ncols-j-1, self._nrows-i-1, self, i, j)
if self._subdivisions is not None:
row_divs, col_divs = self.subdivisions()
A.subdivide(list(reversed([self._ncols - t for t in col_divs])),
Expand Down
Loading