Ticket #12290: trac12290_unique_matrix_space.patch

File trac12290_unique_matrix_space.patch, 15.8 KB (added by Simon King, 11 years ago)

Use UniqueRepresentation as a base class for matrix spaces.

  • doc/de/tutorial/tour_linalg.rst

    # HG changeset patch
    # User Simon King <simon.king@uni-jena.de>
    # Date 1326287788 -3600
    # Node ID 43af1b3c98f6850b5cab298fcb43984d2dc974e0
    # Parent  d4d91dfafc78415a41a64c36a8430c05366dbf40
    #12290: Use UniqueRepresentation on matrix spaces
    
    diff --git a/doc/de/tutorial/tour_linalg.rst b/doc/de/tutorial/tour_linalg.rst
    a b  
    237237    sage: M = MatrixSpace(QQ, 10,10, Sparse=True)
    238238    Traceback (most recent call last):
    239239    ...
    240     TypeError: MatrixSpace() got an unexpected keyword argument 'Sparse'
     240    TypeError: __classcall__() got an unexpected keyword argument 'Sparse'
  • doc/en/tutorial/tour_linalg.rst

    diff --git a/doc/en/tutorial/tour_linalg.rst b/doc/en/tutorial/tour_linalg.rst
    a b  
    234234    sage: M = MatrixSpace(QQ, 10,10, Sparse=True)
    235235    Traceback (most recent call last):
    236236    ...
    237     TypeError: MatrixSpace() got an unexpected keyword argument 'Sparse'
     237    TypeError: __classcall__() got an unexpected keyword argument 'Sparse'
  • doc/fr/tutorial/tour_linalg.rst

    diff --git a/doc/fr/tutorial/tour_linalg.rst b/doc/fr/tutorial/tour_linalg.rst
    a b  
    195195    sage: M = MatrixSpace(QQ, 10,10, Sparse=True)
    196196    Traceback (most recent call last):
    197197    ...
    198     TypeError: MatrixSpace() got an unexpected keyword argument 'Sparse'
     198    TypeError: __classcall__() got an unexpected keyword argument 'Sparse'
    199199
    200200Sage peut calculer des valeurs propres et des vecteurs propres :
    201201
  • doc/ru/tutorial/tour_linalg.rst

    diff --git a/doc/ru/tutorial/tour_linalg.rst b/doc/ru/tutorial/tour_linalg.rst
    a b  
    208208    sage: M = MatrixSpace(QQ, 10,10, Sparse=True)
    209209    Traceback (most recent call last):
    210210    ...
    211     TypeError: MatrixSpace() got an unexpected keyword argument 'Sparse'
     211    TypeError: __classcall__() got an unexpected keyword argument 'Sparse'
  • sage/crypto/block_cipher/miniaes.py

    diff --git a/sage/crypto/block_cipher/miniaes.py b/sage/crypto/block_cipher/miniaes.py
    a b  
    2727###########################################################################
    2828
    2929from sage.matrix.matrix_dense import Matrix_dense
    30 from sage.matrix.matrix_space import MatrixSpace, MatrixSpace_generic
     30from sage.matrix.matrix_space import MatrixSpace
    3131from sage.monoids.string_monoid import BinaryStrings
    3232from sage.monoids.string_monoid_element import StringMonoidElement
    3333from sage.rings.finite_rings.constructor import FiniteField
  • sage/matrix/matrix1.pyx

    diff --git a/sage/matrix/matrix1.pyx b/sage/matrix/matrix1.pyx
    a b  
    18521852        if sparse is None:
    18531853            sparse = self.is_sparse()
    18541854        base_ring = self._base_ring
    1855         try:
    1856             from sage.matrix.matrix_space import _cache
    1857             MS = _cache[base_ring, nrows, ncols, sparse]()
    1858         except KeyError:
    1859             MS = None
    1860         if MS is None:
    1861             return MatrixSpace(base_ring, nrows, ncols, sparse)
    1862         else:
    1863             return MS
     1855        return MatrixSpace(base_ring, nrows, ncols, sparse)
    18641856
    18651857    def new_matrix(self, nrows=None, ncols=None, entries=None,
    18661858                   coerce=True, copy=True, sparse=None):
  • sage/matrix/matrix2.pyx

    diff --git a/sage/matrix/matrix2.pyx b/sage/matrix/matrix2.pyx
    a b  
    569569
    570570        We illustrate various combinations of sparse and dense matrices.
    571571        Notice how if base rings are unequal, both operands must be sparse
    572         to get a sparse result.  When the base rings are equal, the left
    573         operand dictates the sparse/dense property of the result. This
    574         behavior is entirely a consequence of the coercion model.  ::
     572        to get a sparse result. ::
    575573
    576574            sage: A = matrix(ZZ, 5, range(30), sparse=False)
    577575            sage: B = matrix(ZZ, 5, range(30), sparse=True)
     
    582580            True
    583581            sage: A.elementwise_product(B).is_dense()
    584582            True
    585             sage: B.elementwise_product(A).is_sparse()
     583            sage: B.elementwise_product(A).is_dense()
    586584            True
    587585
    588586        TESTS:
  • sage/matrix/matrix_integer_2x2.pyx

    diff --git a/sage/matrix/matrix_integer_2x2.pyx b/sage/matrix/matrix_integer_2x2.pyx
    a b  
    1818
    1919cimport matrix
    2020
    21 from matrix_space import MatrixSpace_generic
     21from matrix_space import MatrixSpace
    2222from sage.misc.lazy_attribute import lazy_attribute
    2323
    24 class MatrixSpace_ZZ_2x2_class(MatrixSpace_generic):
     24class MatrixSpace_ZZ_2x2_class(MatrixSpace):
    2525    """
    2626    Return a space of 2x2 matrices over ZZ, whose elements are of
    2727    type sage.matrix.matrix_integer_2x2.Matrix_integer_2x2 instead of
     
    3535
    3636        sage: sage.matrix.matrix_integer_2x2.MatrixSpace_ZZ_2x2()
    3737        Space of 2x2 integer matrices
     38
     39    By trac ticket #12290, it is a unique parent::
     40
     41        sage: from sage.matrix.matrix_integer_2x2 import MatrixSpace_ZZ_2x2
     42        sage: MatrixSpace_ZZ_2x2() is MatrixSpace_ZZ_2x2()
     43        True
     44        sage: M = MatrixSpace_ZZ_2x2()
     45        sage: loads(dumps(M)) is M
     46        True
     47
    3848    """
     49    @staticmethod
     50    def __classcall__(cls):
     51        """
     52        EXAMPLES::
     53
     54            sage: from sage.matrix.matrix_integer_2x2 import MatrixSpace_ZZ_2x2
     55            sage: MatrixSpace_ZZ_2x2() is MatrixSpace_ZZ_2x2()  # indirect doctest
     56            True
     57
     58        """
     59        return super(MatrixSpace,cls).__classcall__(cls)
     60
    3961    def __init__(self):
    4062        """
    41         EXAMPLES:
     63        EXAMPLES::
     64
    4265            sage: sage.matrix.matrix_integer_2x2.MatrixSpace_ZZ_2x2()
    4366            Space of 2x2 integer matrices
    4467        """
    45         MatrixSpace_generic.__init__(self, ZZ, 2, 2, False)
     68        MatrixSpace.__init__(self, ZZ, 2, 2, False)
    4669
    47     def __reduce__(self):
    48         """
    49         Used for pickling.
    50 
    51         EXAMPLES::
    52 
    53             sage: M = sage.matrix.matrix_integer_2x2.MatrixSpace_ZZ_2x2()
    54             sage: M.__reduce__()
    55             (<built-in function MatrixSpace_ZZ_2x2>, ())
    56         """
    57         return MatrixSpace_ZZ_2x2, ()
    58    
    5970    def _repr_(self):
    6071        """
    6172        EXAMPLES::
     
    197208        mpz_clear(self.b)
    198209        mpz_clear(self.c)
    199210        mpz_clear(self.d)
    200        
     211
     212    def testit(self):
     213        print "testing",self._base_ring
     214
    201215    cdef set_unsafe(self, Py_ssize_t i, Py_ssize_t j, value):
    202216        mpz_set(self._entries[(i << 1) | j], (<Integer>value).value)
    203217
     
    316330            True
    317331            sage: n.is_mutable()
    318332            True
     333
     334        The following test against a bug fixed in trac ticket #12290::
     335
     336            sage: n.base_ring()
     337            Integer Ring
     338
    319339        """
    320340        cdef Matrix_integer_2x2 x
    321341        x = self._new_c()
     
    324344        mpz_set(x.c ,self.c)
    325345        mpz_set(x.d, self.d)
    326346        x._mutability = Mutability(False)
     347        x._base_ring = self._base_ring
    327348        if self._subdivisions is not None:
    328349            x.subdivide(*self.subdivisions())
    329350        return x
  • sage/matrix/matrix_space.py

    diff --git a/sage/matrix/matrix_space.py b/sage/matrix/matrix_space.py
    a b  
    6666# Sage imports
    6767import sage.structure.coerce
    6868import sage.structure.parent_gens as parent_gens
     69from sage.structure.unique_representation import UniqueRepresentation
    6970import sage.rings.ring as ring
    7071import sage.rings.rational_field as rational_field
    7172import sage.rings.integer_ring as integer_ring
     
    108109        False
    109110    """
    110111
    111     return isinstance(x, MatrixSpace_generic)
     112    return isinstance(x, MatrixSpace)
    112113
    113 _cache = {}
    114 def MatrixSpace(base_ring, nrows, ncols=None, sparse=False):
    115     """
    116     Create with the command
    117    
    118     MatrixSpace(base_ring , nrows [, ncols] [, sparse])
    119    
    120     The default value of the optional argument sparse is False. The
    121     default value of the optional argument ncols is nrows.
    122    
    123     INPUT:
    124    
    125    
    126     -  ``base_ring`` - a ring
    127    
    128     -  ``nrows`` - int, the number of rows
    129    
    130     -  ``ncols`` - (default nrows) int, the number of
    131        columns
    132    
    133     -  ``sparse`` - (default false) whether or not matrices
    134        are given a sparse representation
    135    
    136    
    137     OUTPUT: The unique space of all nrows x ncols matrices over
    138     base_ring.
    139    
    140     EXAMPLES::
    141    
    142         sage: MS = MatrixSpace(RationalField(),2)
    143         sage: MS.base_ring()
    144         Rational Field
    145         sage: MS.dimension()
    146         4
    147         sage: MS.dims()
    148         (2, 2)
    149         sage: B = MS.basis()
    150         sage: B
    151         [
    152         [1 0]  [0 1]  [0 0]  [0 0]
    153         [0 0], [0 0], [1 0], [0 1]
    154         ]
    155         sage: B[0]
    156         [1 0]
    157         [0 0]
    158         sage: B[1]
    159         [0 1]
    160         [0 0]
    161         sage: B[2]
    162         [0 0]
    163         [1 0]
    164         sage: B[3]
    165         [0 0]
    166         [0 1]
    167         sage: A = MS.matrix([1,2,3,4])
    168         sage: A
    169         [1 2]
    170         [3 4]
    171         sage: MS2 = MatrixSpace(RationalField(),2,3)
    172         sage: B = MS2.matrix([1,2,3,4,5,6])
    173         sage: A*B
    174         [ 9 12 15]
    175         [19 26 33]
    176    
    177     ::
    178    
    179         sage: M = MatrixSpace(ZZ, 10)
    180         sage: M
    181         Full MatrixSpace of 10 by 10 dense matrices over Integer Ring
    182         sage: loads(M.dumps()) == M
    183         True
    184     """
    185     if base_ring not in _Rings:
    186         raise TypeError("base_ring (=%s) must be a ring"%base_ring)
    187     if ncols is None: ncols = nrows
    188     nrows = int(nrows); ncols = int(ncols); sparse=bool(sparse)
    189     key = (base_ring, nrows, ncols, sparse)
    190     if _cache.has_key(key):
    191         M = _cache[key]()
    192         if not M is None: return M
    193114
    194     M = MatrixSpace_generic(base_ring, nrows, ncols, sparse)
    195 
    196     _cache[key] = weakref.ref(M)
    197     return M
    198 
    199 
    200    
    201 class MatrixSpace_generic(parent_gens.ParentWithGens):
     115class MatrixSpace(UniqueRepresentation, parent_gens.ParentWithGens):
    202116    """
    203117    The space of all nrows x ncols matrices over base_ring.
    204118   
     119    INPUT:
     120
     121    -  ``base_ring`` - a ring
     122    -  ``nrows`` - int, the number of rows
     123    -  ``ncols`` - (default nrows) int, the number of
     124       columns
     125    -  ``sparse`` - (default false) whether or not matrices
     126       are given a sparse representation
     127
    205128    EXAMPLES::
    206129   
    207130        sage: MatrixSpace(ZZ,10,5)
     
    226149    """
    227150    _no_generic_basering_coercion = True
    228151
     152    @staticmethod
     153    def __classcall__(cls, base_ring, nrows, ncols=None, sparse=False):
     154        """
     155        Create with the command
     156
     157        MatrixSpace(base_ring , nrows [, ncols] [, sparse])
     158
     159        The default value of the optional argument sparse is False. The
     160        default value of the optional argument ncols is nrows.
     161
     162        INPUT:
     163
     164        -  ``base_ring`` - a ring
     165        -  ``nrows`` - int, the number of rows
     166        -  ``ncols`` - (default nrows) int, the number of
     167           columns
     168        -  ``sparse`` - (default false) whether or not matrices
     169           are given a sparse representation
     170
     171
     172        OUTPUT:
     173           
     174        The unique space of all nrows x ncols matrices over base_ring.
     175   
     176        EXAMPLES::
     177
     178            sage: MS = MatrixSpace(RationalField(),2)
     179            sage: MS.base_ring()
     180            Rational Field
     181            sage: MS.dimension()
     182            4
     183            sage: MS.dims()
     184            (2, 2)
     185            sage: B = MS.basis()
     186            sage: B
     187            [
     188            [1 0]  [0 1]  [0 0]  [0 0]
     189            [0 0], [0 0], [1 0], [0 1]
     190            ]
     191            sage: B[0]
     192            [1 0]
     193            [0 0]
     194            sage: B[1]
     195            [0 1]
     196            [0 0]
     197            sage: B[2]
     198            [0 0]
     199            [1 0]
     200            sage: B[3]
     201            [0 0]
     202            [0 1]
     203            sage: A = MS.matrix([1,2,3,4])
     204            sage: A
     205            [1 2]
     206            [3 4]
     207            sage: MS2 = MatrixSpace(RationalField(),2,3)
     208            sage: B = MS2.matrix([1,2,3,4,5,6])
     209            sage: A*B
     210            [ 9 12 15]
     211            [19 26 33]
     212
     213        ::
     214
     215            sage: M = MatrixSpace(ZZ, 10)
     216            sage: M
     217            Full MatrixSpace of 10 by 10 dense matrices over Integer Ring
     218            sage: loads(M.dumps()) is M
     219            True
     220
     221        """
     222        if base_ring not in _Rings:
     223            raise TypeError("base_ring (=%s) must be a ring"%base_ring)
     224        if ncols is None: ncols = nrows
     225        nrows = int(nrows); ncols = int(ncols); sparse=bool(sparse)
     226        return super(MatrixSpace, cls).__classcall__(cls, base_ring, nrows, ncols, sparse)
     227
    229228    def __init__(self,  base_ring,             
    230229                        nrows,
    231230                        ncols=None,
     
    316315            ------------------------------------------------------------
    317316            The following tests failed: _test_category
    318317            sage: type(MS)
    319             <class 'sage.matrix.matrix_space.MatrixSpace_generic'>
     318            <class 'sage.matrix.matrix_space.MatrixSpace'>
    320319            sage: MS.full_category_initialisation()
    321320            sage: TestSuite(MS).run()
    322321            sage: type(MS)
    323             <class 'sage.matrix.matrix_space.MatrixSpace_generic_with_category'>
     322            <class 'sage.matrix.matrix_space.MatrixSpace_with_category'>
    324323
    325324        .. todo::
    326325
     
    340339                sage: MS = MatrixSpace(QQ,7)                      # todo: not implemented
    341340                sage: TestSuite(MS).run()                         # todo: not implemented
    342341        """
    343         if type(type(self)) is not type:
     342        if self.__dict__.get('_category_is_initialised'):
    344343            # Apparently the category is already taken care of.
    345344            return
    346345        category = self.category()
    347         self._category = None
     346        self._category_is_initialised = True
    348347        sage.structure.parent.Parent.__init__(self, category=category)
    349348
    350     def __reduce__(self):
    351         """
    352         EXAMPLES::
    353        
    354             sage: A = Mat(ZZ,5,7,sparse=True)
    355             sage: A
    356             Full MatrixSpace of 5 by 7 sparse matrices over Integer Ring
    357             sage: loads(dumps(A)) == A
    358             True
    359         """
    360         return MatrixSpace, (self.base_ring(), self.__nrows, self.__ncols, self.__is_sparse)
    361 
    362349    @lazy_attribute
    363350    def _copy_zero(self):
    364351        """
     
    667654                raise TypeError("no canonical coercion")
    668655        return self._coerce_try(x, self.base_ring())
    669656
    670     def __cmp__(self, other):
    671         """
    672         Compare this matrix space with other. Sparse and dense matrix
    673         spaces with otherwise the same parameters are considered equal.
    674        
    675         If other is not a matrix space, return something arbitrary but
    676         deterministic. Otherwise, compare based on base ring, then on
    677         number of rows and columns.
    678        
    679         EXAMPLES::
    680        
    681             sage: Mat(ZZ,1000) == Mat(QQ,1000)
    682             False
    683             sage: Mat(ZZ,10) == Mat(ZZ,10)
    684             True
    685             sage: Mat(ZZ,10, sparse=False) == Mat(ZZ,10, sparse=True)
    686             True
    687         """
    688         if isinstance(other, MatrixSpace_generic):
    689             return cmp((self.base_ring(), self.__nrows, self.__ncols),
    690                        (other.base_ring(), other.__nrows, other.__ncols))
    691         return cmp(type(self), type(other))
    692        
    693657    def _repr_(self):
    694658        """
    695659        Returns the string representation of a MatrixSpace
     
    13751339        if ncols is None:
    13761340            ncols = self.__ncols
    13771341        base = self._base
    1378         try:
    1379             MS = _cache[base,nrows,ncols,sparse]()
    1380         except KeyError:
    1381             MS = None
    1382         if MS is None:
    1383             return MatrixSpace(base, nrows, ncols, sparse=sparse)
    1384         else:
    1385             return MS
     1342        return MatrixSpace(base, nrows, ncols, sparse=sparse)
    13861343
    13871344    def ncols(self):
    13881345        """