Ticket #8276: trac-8276-MatrixSpace_one-review.patch

File trac-8276-MatrixSpace_one-review.patch, 10.2 KB (added by mraum, 11 years ago)

First reviewed patch

  • sage/matrix/constructor.py

    # HG changeset patch
    # User Florent Hivert <Florent.Hivert@univ-rouen.fr>
    # Date 1266429253 -3600
    # Node ID 875d385920904fb995babb0f749a6db2de4f324a
    # Parent  42933e668e77a37fd1e960aeaeecfe91df96b530
    #8276: MatrixSpace.one(), .identity_matrix() and .zero_matrix() are now immutable.
    Added Necessary call to copy in various files.
    
    diff --git a/sage/matrix/constructor.py b/sage/matrix/constructor.py
    a b from sage.rings.complex_double import CD 
    2727from sage.rings.integer_ring import ZZ
    2828from sage.misc.misc_c import running_total
    2929from matrix import is_Matrix
     30from copy import copy
    3031
    3132import sage.categories.pushout
    3233
    def random_matrix(R, nrows, ncols=None,  
    782783    """
    783784    if ncols is None:
    784785        ncols = nrows
    785     A = matrix_space.MatrixSpace(R, nrows, ncols, sparse=sparse).zero_matrix()
     786    A = copy(matrix_space.MatrixSpace(R, nrows, ncols, sparse=sparse).zero_matrix())
    786787    if density is None:
    787788        A.randomize(density=float(1), nonzero=False, *args, **kwds)
    788789    else:
  • sage/matrix/matrix0.pyx

    diff --git a/sage/matrix/matrix0.pyx b/sage/matrix/matrix0.pyx
    a b cdef class Matrix(sage.structure.element 
    34373437        cpdef RingElement x
    34383438        x = self._base_ring(left)
    34393439        cdef Matrix ans
    3440         ans = self._parent.zero_matrix()
     3440        ans = self._parent.zero_matrix().__copy__()
    34413441        for r from 0 <= r < self._nrows:
    34423442            for c from 0 <= c < self._ncols:
    34433443                ans.set_unsafe(r, c, x._mul_(<RingElement>self.get_unsafe(r, c)))
    cdef class Matrix(sage.structure.element 
    34803480        cpdef RingElement x
    34813481        x = self._base_ring(right)
    34823482        cdef Matrix ans
    3483         ans = self._parent.zero_matrix()
     3483        ans = self._parent.zero_matrix().__copy__()
    34843484        for r from 0 <= r < self._nrows:
    34853485            for c from 0 <= c < self._ncols:
    34863486                ans.set_unsafe(r, c, (<RingElement>self.get_unsafe(r, c))._mul_(x))
  • sage/matrix/matrix_mod2_dense.pyx

    diff --git a/sage/matrix/matrix_mod2_dense.pyx b/sage/matrix/matrix_mod2_dense.pyx
    a b cdef class Matrix_mod2_dense(matrix_dens 
    281281            sage: B = random_matrix(GF(2),3,3)
    282282            sage: A < B
    283283            True
    284             sage: A = MatrixSpace(GF(2),3,3)(1)
    285             sage: B = MatrixSpace(GF(2),3,3)(1)
     284            sage: A = MatrixSpace(GF(2),3,3).one()
     285            sage: B = copy(MatrixSpace(GF(2),3,3).one())
    286286            sage: B[0,1] = 1
    287287            sage: A < B
    288288            True
  • sage/matrix/matrix_rational_dense.pyx

    diff --git a/sage/matrix/matrix_rational_dense.pyx b/sage/matrix/matrix_rational_dense.pyx
    a b cdef class Matrix_rational_dense(matrix_ 
    25462546       
    25472547            sage: x = matrix(QQ,2,0); y= matrix(QQ,0,2); x*y
    25482548            [0 0]
    2549             [0 0] 
     2549            [0 0]
     2550            sage: matrix(ZZ, 0, 0)*matrix(QQ, 0, 5)
     2551            []
    25502552        """
    25512553        if self._ncols != right._nrows:
    25522554            raise ArithmeticError, "self must be a square matrix"
    25532555        if not self._ncols*self._nrows or not right._ncols*right._nrows:
    25542556            # pari doesn't work in case of 0 rows or columns
    25552557            # This case is easy, since the answer must be the 0 matrix.
    2556             return self.matrix_space(self._nrows, right._ncols).zero_matrix()
     2558            return self.matrix_space(self._nrows, right._ncols).zero_matrix().__copy__()
    25572559        cdef PariInstance P = sage.libs.pari.gen.pari
    25582560        _sig_on
    25592561        cdef GEN M = gmul(pari_GEN(self), pari_GEN(right))
  • sage/matrix/matrix_rational_sparse.pyx

    diff --git a/sage/matrix/matrix_rational_sparse.pyx b/sage/matrix/matrix_rational_sparse.pyx
    a b cdef class Matrix_rational_sparse(matrix 
    447447        self.mpz_denom(D.value)
    448448       
    449449        MZ = sage.matrix.matrix_space.MatrixSpace(ZZ, self._nrows, self._ncols, sparse=True)
    450         A = MZ.zero_matrix()
     450        A = MZ.zero_matrix().__copy__()
    451451
    452452        mpz_init(t)
    453453        _sig_on
    cdef class Matrix_rational_sparse(matrix 
    609609        cdef Matrix_rational_dense B
    610610        cdef mpq_vector* v
    611611
    612         B = self.matrix_space(sparse=False).zero_matrix()
     612        B = self.matrix_space(sparse=False).zero_matrix().__copy__()
    613613        for i from 0 <= i < self._nrows:
    614614            v = &(self._matrix[i])
    615615            for j from 0 <= j < v.num_nonzero:
  • sage/matrix/matrix_space.py

    diff --git a/sage/matrix/matrix_space.py b/sage/matrix/matrix_space.py
    a b class MatrixSpace_generic(parent_gens.Pa 
    346347            entries = 0
    347348
    348349        if entries == 0 and hasattr(self, '__zero_matrix'):
    349             return self.zero_matrix()
     350            if copy:
     351                return self.zero_matrix().__copy__()
     352            else:
     353                return self.zero_matrix()
    350354
    351355        if isinstance(entries, (list, tuple)) and len(entries) > 0 and \
    352356           sage.modules.free_module_element.is_FreeModuleElement(entries[0]):
    class MatrixSpace_generic(parent_gens.Pa 
    884888            [0 0], [0 0], [1 0], [0 1]
    885889            ]
    886890        """
    887         v = [self.zero_matrix() for _ in range(self.dimension())]
     891        v = [self.zero_matrix().__copy__() for _ in range(self.dimension())]
    888892        one = self.base_ring()(1)
    889893        i = 0
    890894        for r in range(self.__nrows):
    class MatrixSpace_generic(parent_gens.Pa 
    918922            (4, 6)
    919923        """
    920924        return (self.__nrows, self.__ncols)
    921        
     925
     926    from sage.misc.cachefunc import cached_method
     927    @cached_method
    922928    def identity_matrix(self):
    923929        """
    924         Create an identity matrix in self. (Must be a space of square
    925         matrices).
    926        
     930        Returns the identity matrix in ``self``.
     931
     932        ``self`` must be a space of square
     933        matrices. The returned matrix is immutable. Please use ``copy`` if
     934        you want a modified copy.
     935
    927936        EXAMPLES::
    928        
     937
    929938            sage: MS1 = MatrixSpace(ZZ,4)
    930939            sage: MS2 = MatrixSpace(QQ,3,4)
    931940            sage: I = MS1.identity_matrix()
    class MatrixSpace_generic(parent_gens.Pa 
    938947            Traceback (most recent call last):
    939948            ...
    940949            TypeError: self must be a space of square matrices
     950
     951        TESTS::
     952
     953            sage: MS1.one()[1,2] = 3
     954            Traceback (most recent call last):
     955            ...
     956            ValueError: matrix is immutable; please change a copy instead (i.e., use copy(M) to change a copy of M).
    941957        """
    942958        if self.__nrows != self.__ncols:
    943959            raise TypeError, "self must be a space of square matrices"
    944         A = self(0)
     960        A = self.zero_matrix().__copy__()
    945961        for i in xrange(self.__nrows):
    946962            A[i,i] = 1
     963        A.set_immutable()
    947964        return A
    948        
     965
     966    one = identity_matrix
     967   
    949968    def is_dense(self):
    950969        """
    951970        Returns True if matrices in self are dense and False otherwise.
    class MatrixSpace_generic(parent_gens.Pa 
    10051024            return self.__basis[n]
    10061025        r = n // self.__ncols
    10071026        c = n - (r * self.__ncols)
    1008         z = self.zero_matrix()
     1027        z = self.zero_matrix().__copy__()
    10091028        z[r,c] = 1
    10101029        return z
    10111030
    10121031    def zero_matrix(self):
    10131032        """
    1014         Return the zero matrix.
     1033        Returns the zero matrix in ``self``.
     1034
     1035        ``self`` must be a space of square matrices. The returned matrix is
     1036        immutable. Please use ``copy`` if you want a modified copy.
     1037
     1038        EXAMPLES::
     1039
     1040            sage: MatrixSpace(GF(7),2,4).zero_matrix()
     1041            [0 0 0 0]
     1042            [0 0 0 0]
     1043
     1044        TESTS::
     1045
     1046            sage: MM = MatrixSpace(RDF,0,0,sparse=False); mat = MM.zero_matrix()
     1047            sage: copy(mat)
     1048            []
    10151049        """
    10161050        try:
    10171051            z = self.__zero_matrix
    10181052        except AttributeError:
    10191053            z = self(0)
     1054            z.set_immutable()
    10201055            self.__zero_matrix = z
    1021         return z.__copy__()
     1056        return z
    10221057   
    10231058    def ngens(self):
    10241059        """
    class MatrixSpace_generic(parent_gens.Pa 
    10311066            20000
    10321067        """
    10331068        return self.dimension()
    1034  
     1069
    10351070    def matrix(self, x=0, coerce=True, copy=True, rows=True):
    10361071        """
    10371072        Create a matrix in self. The entries can be specified either as a
    class MatrixSpace_generic(parent_gens.Pa 
    10561091        if isinstance(x, (types.GeneratorType, xrange)):
    10571092            x = list(x)
    10581093        elif isinstance(x, (int, integer.Integer)) and x==1:
    1059             return self.identity_matrix()
     1094            return self.identity_matrix().__copy__()
    10601095        if matrix.is_Matrix(x):
    10611096            if x.parent() is self:
    10621097                if x.is_immutable():
    class MatrixSpace_generic(parent_gens.Pa 
    12241262            [      2       1 2*a + 1]
    12251263            [      a       2       2]
    12261264        """
    1227         Z = self.zero_matrix()
     1265        Z = self.zero_matrix().__copy__()
    12281266        if density is None:
    12291267            Z.randomize(density=float(1), nonzero=kwds.pop('nonzero', False), \
    12301268                *args, **kwds)
  • sage/matrix/symplectic_basis.py

    diff --git a/sage/matrix/symplectic_basis.py b/sage/matrix/symplectic_basis.py
    a b def _inplace_move_to_positive_pivot(G, r 
    7272        [-16   0   0  -4]
    7373        [  0   0   0   0]
    7474        [ -2   4   0   0]
    75         sage: B = E.parent()(1); G = E.__copy__()
     75        sage: B = copy(E.parent().one()); G = copy(E)
    7676        sage: _inplace_move_to_positive_pivot(G, 0, 3, B, 0)
    7777        sage: E[0, 3] == G[0, 1]
    7878        True
    def symplectic_basis_over_field(M): 
    263263    for i in range(n):
    264264        if not E[i, i].is_zero():
    265265            raise ValueError, "Can only find symplectic bases for alternating matrices"
    266     B = E.parent()(1)
     266    B = E.parent().one().__copy__()
    267267
    268268    zeroes = []
    269269    es = []
    def symplectic_basis_over_ZZ(M): 
    465465    for i in range(n):
    466466        if not E[i, i].is_zero():
    467467            raise ValueError, "Can only find symplectic bases for alternating matrices"
    468     B = E.parent()(1)
     468    B = E.parent().one().__copy__()
    469469
    470470    zeroes = []
    471471    ps = []