Ticket #8939: trac_8939-matrix_template-4.4.2.patch

File trac_8939-matrix_template-4.4.2.patch, 22.2 KB (added by burcin, 12 years ago)

rebased to 4.4.2

  • module_list.py

    # HG changeset patch
    # User Burcin Erocal <burcin@erocal.org>
    # Date 1273461413 -7200
    # Node ID 988e4ecfbe2c7113e13427e244583479255fa355
    # Parent  3ccbcbec653486d7941972d9cd620ab486cfa7c6
    trac 8939: Add templated matrix classes for matrices over ZZ[x] and Z_p[x], using FLINT.
    
    diff --git a/module_list.py b/module_list.py
    a b  
    781781    Extension('sage.matrix.matrix_window_modn_dense',
    782782              sources = ['sage/matrix/matrix_window_modn_dense.pyx']),
    783783
     784    Extension('sage.matrix.matrix_ZZx_dense',
     785              sources = ['sage/matrix/matrix_ZZx_dense.pyx'],
     786              language = 'c++',
     787              libraries = ['flint'],
     788              include_dirs=debian_include_dirs + \
     789                      [SAGE_ROOT+'/local/include/FLINT/'],
     790              extra_compile_args=["-std=c99"]), \
     791
     792    Extension('sage.matrix.matrix_zmodpoly_dense',
     793              sources = ['sage/matrix/matrix_zmodpoly_dense.pyx'],
     794              #language = 'c++',
     795              libraries = ['flint'],
     796              include_dirs=debian_include_dirs + \
     797                      [SAGE_ROOT+'/local/include/FLINT/'],
     798              extra_compile_args=["-std=c99"]), \
     799
    784800    Extension('sage.matrix.misc',
    785801              sources = ['sage/matrix/misc.pyx'],
    786802              libraries=['mpfr','gmp']),
  • sage/libs/flint/fmpz_poly.pxi

    diff --git a/sage/libs/flint/fmpz_poly.pxi b/sage/libs/flint/fmpz_poly.pxi
    a b  
    33
    44cdef extern from "FLINT/fmpz_poly.h":
    55   
     6    ctypedef struct fmpz_poly_struct:
     7        pass
     8
    69    ctypedef void* fmpz_poly_t
    710   
    811    void fmpz_poly_init(fmpz_poly_t poly)
    912    void fmpz_poly_init2(fmpz_poly_t poly, unsigned long alloc, \
    1013            unsigned long limbs)
    1114    void fmpz_poly_realloc(fmpz_poly_t poly, unsigned long alloc)
     15
     16    void fmpz_poly_swap(fmpz_poly_t a, fmpz_poly_t b)
    1217   
    1318    void fmpz_poly_fit_length(fmpz_poly_t poly, unsigned long alloc)
    1419    void fmpz_poly_resize_limbs(fmpz_poly_t poly, unsigned long limbs)
     
    1924   
    2025    long fmpz_poly_degree(fmpz_poly_t poly)
    2126    unsigned long fmpz_poly_length(fmpz_poly_t poly)
     27    long fmpz_poly_max_bits(fmpz_poly_t poly)
    2228
    2329   
    2430    void fmpz_poly_set_length(fmpz_poly_t poly, unsigned long length)
  • new file sage/libs/flint/fmpz_poly_linkage.pxi

    diff --git a/sage/libs/flint/fmpz_poly_linkage.pxi b/sage/libs/flint/fmpz_poly_linkage.pxi
    new file mode 100644
    - +  
     1
     2cdef inline int celement_construct(fmpz_poly_t e, unsigned long parent) \
     3        except -2:
     4    fmpz_poly_init(e)
     5
     6cdef inline int celement_destruct(fmpz_poly_t e, unsigned long parent) \
     7        except -2:
     8    fmpz_poly_clear(e)
     9
     10cdef inline int celement_set(fmpz_poly_t a, fmpz_poly_t b,
     11        unsigned long parent) except -2:
     12    fmpz_poly_set(a, b)
     13
     14cdef inline int celement_swap(fmpz_poly_t a, fmpz_poly_t b) except -2:
     15    fmpz_poly_swap(a, b)
     16
     17cdef inline int celement_add(fmpz_poly_t res, fmpz_poly_t a, fmpz_poly_t b,
     18        unsigned long parent) except -2:
     19    fmpz_poly_add(res, a, b)
     20
     21cdef inline int celement_mul(fmpz_poly_t res, fmpz_poly_t a, fmpz_poly_t b,
     22        unsigned long parent) except -2:
     23    fmpz_poly_mul(res, a, b)
     24
     25cdef inline int celement_neg(fmpz_poly_t a, fmpz_poly_t b,
     26        unsigned long parent) except -2:
     27    fmpz_poly_neg(a, b)
     28
     29cdef inline int celement_invert(fmpz_poly_t a, fmpz_poly_t b,
     30        unsigned long parent) except -2:
     31    raise NotImplementedError, "this function shouldn't be called!!!"
     32
     33cdef inline bint celement_is_zero(fmpz_poly_t e, unsigned long parent):
     34    return fmpz_poly_length(e) == 0
     35
     36cdef inline long celement_len(fmpz_poly_t e, unsigned long parent):
     37    return fmpz_poly_length(e)
  • sage/libs/flint/zmod_poly_linkage.pxi

    diff --git a/sage/libs/flint/zmod_poly_linkage.pxi b/sage/libs/flint/zmod_poly_linkage.pxi
    a b  
    2020from sage.libs.flint.zmod_poly cimport *, zmod_poly_t
    2121from sage.libs.flint.long_extras cimport *
    2222
     23from sage.structure.factorization import Factorization
     24
    2325include "../../ext/stdsage.pxi"
    2426
    2527cdef inline celement *celement_new(unsigned long n):
  • new file sage/matrix/matrix_ZZx_dense.pxd

    diff --git a/sage/matrix/matrix_ZZx_dense.pxd b/sage/matrix/matrix_ZZx_dense.pxd
    new file mode 100644
    - +  
     1include "../ext/cdefs.pxi"
     2from sage.libs.flint.fmpz_poly cimport *
     3
     4ctypedef fmpz_poly_struct celement
     5
     6include "matrix_dense_template_header.pxi"
     7
     8cdef class Matrix_ZZx_dense(Matrix_dense_template):
     9    cpdef long _coeff_size(self)
  • new file sage/matrix/matrix_ZZx_dense.pyx

    diff --git a/sage/matrix/matrix_ZZx_dense.pyx b/sage/matrix/matrix_ZZx_dense.pyx
    new file mode 100644
    - +  
     1###############################################################################
     2#   Sage: Open Source Mathematical Software
     3#       Copyright (C) 2010 Burcin Erocal <burcin@erocal.org>
     4#  Distributed under the terms of the GNU General Public License (GPL),
     5#  version 2 or any later version.  The full text of the GPL is available at:
     6#                  http://www.gnu.org/licenses/
     7###############################################################################
     8
     9include "../ext/stdsage.pxi"
     10include "../ext/interrupt.pxi"
     11
     12from sage.rings.polynomial.polynomial_integer_dense_flint cimport \
     13        Polynomial_integer_dense_flint
     14
     15cdef void set_element_to_sage_element(fmpz_poly_t dest,
     16        Polynomial_integer_dense_flint el):
     17    fmpz_poly_set(dest, el.__poly)
     18
     19include "../libs/flint/fmpz_poly_linkage.pxi"
     20
     21include "matrix_dense_template.pxi"
     22
     23
     24cdef class Matrix_ZZx_dense(Matrix_dense_template):
     25    """
     26    TESTS::
     27
     28        sage: M = matrix(ZZ['x'], 3, range(9))
     29        sage: TestSuite(M).run() is None
     30        True
     31    """
     32    cdef set_unsafe(self, Py_ssize_t i, Py_ssize_t j, x):
     33        # no bounds or any other checks; assumes x is in self._base_ring
     34        cdef Polynomial_integer_dense_flint poly = x
     35        fmpz_poly_set(&self._matrix[i][j], poly.__poly)
     36
     37    cdef Polynomial_integer_dense_flint get_unsafe(self, Py_ssize_t i,
     38            Py_ssize_t j):
     39        # no checks
     40        cdef Polynomial_integer_dense_flint x = \
     41                PY_NEW(Polynomial_integer_dense_flint)
     42        x._parent = self._base_ring
     43        x._is_gen = 0
     44        fmpz_poly_init(x.__poly)
     45        fmpz_poly_set(x.__poly, &(<Matrix_ZZx_dense>self)._matrix[i][j])
     46        return x
     47
     48    cpdef long _coeff_size(self):
     49        """
     50        Returns the maximum number of bits required to store the coefficients
     51        of the polynomials in this matrix.
     52
     53        EXAMPLES::
     54
     55            sage: P.<x> = ZZ[]
     56            sage: M = Matrix(P, 2, 2)
     57            sage: M._coeff_size()
     58            1
     59            sage: M[0,0] = 2^5
     60            sage: M._coeff_size()
     61            7
     62            sage: M[0,0] = -(2^5)
     63            sage: M._coeff_size()
     64            7
     65
     66        TESTS::
     67
     68            sage: Matrix(P, 0, 0)._coeff_size()
     69            1
     70        """
     71        cdef long mbits = 0
     72        cdef Py_ssize_t i
     73        for i in range(self._nrows*self._ncols):
     74            mbits = max(mbits, abs(fmpz_poly_max_bits(&self._entries[i])))
     75        return mbits+1 # add 1 to account for negative values
  • new file sage/matrix/matrix_dense_template.pxi

    diff --git a/sage/matrix/matrix_dense_template.pxi b/sage/matrix/matrix_dense_template.pxi
    new file mode 100644
    - +  
     1###############################################################################
     2#   Sage: Open Source Mathematical Software
     3#       Copyright (C) 2010 Burcin Erocal <burcin@erocal.org>
     4#  Distributed under the terms of the GNU General Public License (GPL),
     5#  version 2 or any later version.  The full text of the GPL is available at:
     6#                  http://www.gnu.org/licenses/
     7###############################################################################
     8
     9from sage.structure.element cimport Element
     10
     11cdef class Matrix_dense_template(matrix_dense.Matrix_dense):
     12    """
     13    TESTS::
     14
     15        sage: M = matrix(GF(5)['x'],3,3,range(9))
     16        sage: type(M)
     17        <type 'sage.matrix.matrix_zmodpoly_dense.Matrix_zmodpoly_dense'>
     18        sage: loads(dumps(M))
     19        [0 1 2]
     20        [3 4 0]
     21        [1 2 3]
     22
     23        sage: N = matrix(ZZ['x'],3,3,range(9))
     24        sage: type(N)
     25        <type 'sage.matrix.matrix_ZZx_dense.Matrix_ZZx_dense'>
     26        sage: loads(dumps(N))
     27        [0 1 2]
     28        [3 4 5]
     29        [6 7 8]
     30
     31        sage: M == N
     32        True
     33    """
     34    def __new__(self, parent, entries, copy=True, coerce=True):
     35        """
     36        Allocate memory for the matrix.
     37
     38        TESTS::
     39
     40            sage: matrix(GF(5)['x'], 3, 4, range(12))
     41            [0 1 2 3]
     42            [4 0 1 2]
     43            [3 4 0 1]
     44            sage: matrix(ZZ['x'], 3, 4, range(12))
     45            [ 0  1  2  3]
     46            [ 4  5  6  7]
     47            [ 8  9 10 11]
     48        """
     49        self._nrows = parent.nrows()
     50        self._ncols = parent.ncols()
     51        self._modulus = parent.base_ring().characteristic()
     52
     53        # allocate space for the entries
     54        _sig_on
     55        self._entries = <celement*>sage_malloc(sizeof(celement)*
     56                (self._nrows * self._ncols))
     57        _sig_off
     58        if self._entries == NULL:
     59            raise MemoryError, "out of memory allocating a matrix"
     60
     61        # allocate an array of pointers to the rows
     62        self._matrix = <celement**>sage_malloc(sizeof(celement*)
     63                *self._nrows)
     64        if self._entries == NULL:
     65            raise MemoryError, "out of memory allocating a matrix"
     66
     67        cdef Py_ssize_t i
     68        for i in range(self._nrows*self._ncols):
     69            celement_construct(&self._entries[i], self._modulus)
     70
     71        cdef celement* crow = self._entries
     72        for i in range(self._nrows):
     73            self._matrix[i] = crow
     74            crow += self._ncols
     75
     76    def __init__(self, parent, entries, copy=True, coerce=True):
     77        """
     78        TESTS::
     79
     80            sage: Matrix(GF(5)['x'],3,range(9))
     81            [0 1 2]
     82            [3 4 0]
     83            [1 2 3]
     84            sage: Matrix(ZZ['x'],3,range(9))
     85            [0 1 2]
     86            [3 4 5]
     87            [6 7 8]
     88            sage: Matrix(GF(5)['x'],3,3,9)
     89            [4 0 0]
     90            [0 4 0]
     91            [0 0 4]
     92            sage: Matrix(ZZ['x'],3,3,9)
     93            [9 0 0]
     94            [0 9 0]
     95            [0 0 9]
     96        """
     97        cdef Py_ssize_t i
     98        matrix_dense.Matrix_dense.__init__(self, parent)
     99
     100        if entries == 0:
     101            pass
     102
     103        elif isinstance(entries, (list, tuple)):
     104            if len(entries) != self._nrows*self._ncols:
     105                raise ValueError, "entries has wrong length"
     106            i = 0
     107            for e in entries:
     108                if coerce: # the argument 'coerce' is meant to be convert
     109                    selement = self._base_ring(e)
     110                else:
     111                    selement = e
     112                set_element_to_sage_element(&self._entries[i], selement)
     113                i += 1
     114        else:
     115            if self._ncols != self._nrows:
     116                raise ValueError, "matrix is not square"
     117            if coerce:
     118                selement = self._base_ring.coerce(entries)
     119            else:
     120                selement = e
     121            for i in range(self._nrows):
     122                set_element_to_sage_element(&self._matrix[i][i], selement)
     123
     124    def __dealloc__(self):
     125        """
     126        TESTS::
     127
     128            sage: T = matrix(GF(5)['x'], 3, 4); T.randomize()
     129            sage: del T
     130
     131            sage: T = matrix(ZZ['x'], 3, 4); T.randomize()
     132            sage: del T
     133        """
     134        cdef Py_ssize_t i
     135        if self._entries != NULL:
     136            for i in range(self._ncols*self._nrows):
     137                celement_destruct(&self._entries[i], self._modulus)
     138            sage_free(self._entries)
     139        if self._matrix != NULL:
     140            sage_free(self._matrix)
     141
     142    def __richcmp__(left, right, int op):
     143        """
     144        EXAMPLES:
     145            sage: A = random_matrix(Integers(25)['x'],2)
     146            sage: cmp(A,A)
     147            0
     148            sage: cmp(A,A+1)
     149            -1
     150            sage: cmp(A+1,A)
     151            1
     152
     153            sage: A = random_matrix(ZZ['x'],2)
     154            sage: cmp(A,A)
     155            0
     156            sage: cmp(A,A+1)
     157            -1
     158            sage: cmp(A+1,A)
     159            1
     160        """
     161        return (<Element>left)._richcmp(right, op)
     162
     163    # polynomial matrix functions
     164    def degree(self, var=None):
     165        """
     166        Returns the degree (i.e., the maximal degree of the polynomials)
     167        of the given matrix.
     168
     169        EXAMPLES::
     170
     171            sage: P.<x> = ZZ[]
     172            sage: M = Matrix(P, 2, 2, [x, x+1, -1, 0]); M
     173            [    x x + 1]
     174            [   -1     0]
     175            sage: M.degree()
     176            1
     177            sage: M.matrix_from_rows_and_columns([1],[0,1]).degree()
     178            0
     179            sage: M.matrix_from_rows_and_columns([1],[1]).degree()
     180            -1
     181
     182        TESTS::
     183
     184            sage: P.<x> = ZZ[]
     185            sage: M = Matrix(P, 2, 3)
     186            sage: M.degree()
     187            -1
     188            sage: M[0,0] = 1; M.degree()
     189            0
     190            sage: M[0,1] = x; M.degree()
     191            1
     192            sage: Matrix(P, 0, 0).degree()
     193            -1
     194
     195        ::
     196
     197            sage: P.<x> = GF(5)[]
     198            sage: M = Matrix(P, 2, 3)
     199            sage: M.degree()
     200            -1
     201            sage: M[0,0] = 1; M.degree()
     202            0
     203            sage: M[0,1] = x; M.degree()
     204            1
     205            sage: Matrix(P, 0, 0).degree()
     206            -1
     207        """
     208        cdef Py_ssize_t i
     209        cdef long len = 0
     210        for i in range(self._nrows*self._ncols):
     211            len = max(len, celement_len(&self._entries[i], self._modulus))
     212        return len -1
     213
  • new file sage/matrix/matrix_dense_template_header.pxi

    diff --git a/sage/matrix/matrix_dense_template_header.pxi b/sage/matrix/matrix_dense_template_header.pxi
    new file mode 100644
    - +  
     1"""
     2Dense Matrix Template for C/C++ Library Interfaces
     3"""
     4
     5cimport matrix_dense
     6
     7cdef class Matrix_dense_template(matrix_dense.Matrix_dense):
     8    cdef celement* _entries
     9    cdef celement** _matrix
     10    cdef unsigned long _modulus
  • sage/matrix/matrix_generic_dense.pyx

    diff --git a/sage/matrix/matrix_generic_dense.pyx b/sage/matrix/matrix_generic_dense.pyx
    a b  
    3838
    3939    EXAMPLES::
    4040   
    41         sage: A = random_matrix(Integers(25)['x'],2); A
    42         [    x^2 + 12*x + 2   4*x^2 + 13*x + 8]
    43         [ 22*x^2 + 2*x + 17 19*x^2 + 22*x + 14]
     41        sage: A = random_matrix(QQbar['x'], 2); A
     42        [     -2*x^2 - 2      -2*x^2 - 1]
     43        [2*x^2 - 2*x + 1       x^2 + 2*x]
    4444        sage: type(A)
    4545        <type 'sage.matrix.matrix_generic_dense.Matrix_generic_dense'>
    4646        sage: TestSuite(A).run()
     
    117117    def _pickle(self):
    118118        """
    119119        EXAMPLES:
    120             sage: R.<x> = Integers(25)['x']; A = matrix(R, [1,x,x^3+1,2*x])
     120            sage: R.<x> = QQbar['x']; A = matrix(R, [1,x,x^3+1,2*x])
    121121            sage: A._pickle()
    122122            ([1, x, x^3 + 1, 2*x], 0)
    123123        """
     
    126126    def _unpickle(self, data, int version):
    127127        """
    128128        EXAMPLES:
    129             sage: R.<x> = Integers(25)['x']; A = matrix(R, [1,x,x^3+1,2*x]); B = A.parent()(0)
     129            sage: R.<x> = QQbar['x']; A = matrix(R, [1,x,x^3+1,2*x]); B = A.parent()(0)
    130130            sage: v = A._pickle()
    131131            sage: B._unpickle(v[0], v[1])
    132132            sage: B
     
    140140    def __richcmp__(matrix.Matrix self, right, int op):  # always need for mysterious reasons.
    141141        """
    142142        EXAMPLES:
    143             sage: A = random_matrix(Integers(25)['x'],2)
     143            sage: A = random_matrix(QQbar['x'],2)
    144144            sage: cmp(A,A)
    145145            0
    146146            sage: cmp(A,A+1)
     
    153153    def __hash__(self):
    154154        """
    155155        EXAMPLES:
    156             sage: A = random_matrix(Integers(25)['x'],2)
     156            sage: A = random_matrix(QQbar['x'],2)
    157157            sage: hash(A)
    158158            Traceback (most recent call last):
    159159            ...
    160160            TypeError: mutable matrices are unhashable
    161161            sage: A.set_immutable()
    162162            sage: hash(A)
    163             139665060168050560  # 64-bit
     163            -7334514792821593317 # 64-bit
    164164            -623270016           # 32-bit
    165165        """
    166166        return self._hash()
     
    296296        only, since this circumvents immutability.
    297297
    298298        EXAMPLES:
    299             sage: A = random_matrix(Integers(25)['x'],2); A.set_immutable()
     299            sage: A = random_matrix(QQbar['x'],2); A.set_immutable()
    300300            sage: A._list()[0] = 0
    301301            sage: A._list()[0]
    302302            0
  • sage/matrix/matrix_space.py

    diff --git a/sage/matrix/matrix_space.py b/sage/matrix/matrix_space.py
    a b  
    4848
    4949import matrix_mpolynomial_dense
    5050
     51import matrix_ZZx_dense
     52import matrix_zmodpoly_dense
     53
    5154#import padics.matrix_padic_capped_relative_dense
    5255
    5356## import matrix_cyclo_dense
     
    7578import sage.rings.integral_domain as integral_domain
    7679import sage.rings.number_field.all
    7780import sage.rings.finite_rings.integer_mod_ring
     81from sage.rings.polynomial import polynomial_ring, polynomial_zmod_flint, \
     82        polynomial_integer_dense_flint
    7883import sage.rings.polynomial.multi_polynomial_ring_generic
    7984import sage.misc.latex as latex
    8085#import sage.rings.real_double as real_double
     
    831836            <type 'sage.matrix.matrix_integer_sparse.Matrix_integer_sparse'>
    832837            sage: type(matrix(SR, 2, 2, 0))
    833838            <type 'sage.matrix.matrix_symbolic_dense.Matrix_symbolic_dense'>
     839            sage: type(Matrix(ZZ['x'],3,range(9)))
     840            <type 'sage.matrix.matrix_ZZx_dense.Matrix_ZZx_dense'>
     841            sage: type(Matrix(GF(5)['x'],3,range(9)))
     842            <type 'sage.matrix.matrix_zmodpoly_dense.Matrix_zmodpoly_dense'>
    834843        """
    835844        R = self.base_ring()
    836845        if self.is_dense():
     
    851860                if R.order() == 2:
    852861                    return matrix_mod2_dense.Matrix_mod2_dense
    853862                return matrix_modn_dense.Matrix_modn_dense
     863            elif isinstance(R, polynomial_ring.PolynomialRing_general):
     864                if R._polynomial_class is polynomial_integer_dense_flint.Polynomial_integer_dense_flint:
     865                    return matrix_ZZx_dense.Matrix_ZZx_dense
     866                elif R._polynomial_class is polynomial_zmod_flint.Polynomial_zmod_flint:
     867                    return matrix_zmodpoly_dense.Matrix_zmodpoly_dense
    854868            elif sage.rings.polynomial.multi_polynomial_ring_generic.is_MPolynomialRing(R) and R.base_ring().is_field():
    855869                return matrix_mpolynomial_dense.Matrix_mpolynomial_dense
    856870            #elif isinstance(R, sage.rings.padics.padic_ring_capped_relative.pAdicRingCappedRelative):
    857871            #    return padics.matrix_padic_capped_relative_dense
    858872            # the default     
    859             else:
    860                 from sage.symbolic.ring import SR   # causes circular imports
    861                 if R is SR:
    862                     import matrix_symbolic_dense
    863                     return matrix_symbolic_dense.Matrix_symbolic_dense
    864                 return matrix_generic_dense.Matrix_generic_dense
     873            from sage.symbolic.ring import SR   # causes circular imports
     874            if R is SR:
     875                import matrix_symbolic_dense
     876                return matrix_symbolic_dense.Matrix_symbolic_dense
     877            return matrix_generic_dense.Matrix_generic_dense
    865878       
    866879        else:           
    867880            if sage.rings.finite_rings.integer_mod_ring.is_IntegerModRing(R) and R.order() < matrix_modn_sparse.MAX_MODULUS:
  • new file sage/matrix/matrix_zmodpoly_dense.pxd

    diff --git a/sage/matrix/matrix_zmodpoly_dense.pxd b/sage/matrix/matrix_zmodpoly_dense.pxd
    new file mode 100644
    - +  
     1include "../ext/cdefs.pxi"
     2from sage.libs.flint.zmod_poly cimport *
     3
     4ctypedef zmod_poly_struct celement
     5
     6include "matrix_dense_template_header.pxi"
     7
     8cdef class Matrix_zmodpoly_dense(Matrix_dense_template):
     9    pass
  • new file sage/matrix/matrix_zmodpoly_dense.pyx

    diff --git a/sage/matrix/matrix_zmodpoly_dense.pyx b/sage/matrix/matrix_zmodpoly_dense.pyx
    new file mode 100644
    - +  
     1###############################################################################
     2#   Sage: Open Source Mathematical Software
     3#       Copyright (C) 2010 Burcin Erocal <burcin@erocal.org>
     4#  Distributed under the terms of the GNU General Public License (GPL),
     5#  version 2 or any later version.  The full text of the GPL is available at:
     6#                  http://www.gnu.org/licenses/
     7###############################################################################
     8
     9include "../ext/stdsage.pxi"
     10include "../ext/interrupt.pxi"
     11
     12
     13from sage.rings.polynomial.polynomial_zmod_flint cimport Polynomial_zmod_flint
     14
     15cdef void set_element_to_sage_element(zmod_poly_t dest,
     16        Polynomial_zmod_flint el):
     17    zmod_poly_set(dest, &el.x)
     18
     19include "../libs/flint/zmod_poly_linkage.pxi"
     20
     21include "matrix_dense_template.pxi"
     22
     23
     24cdef class Matrix_zmodpoly_dense(Matrix_dense_template):
     25    """
     26    TESTS::
     27
     28        sage: M = matrix(GF(5)['x'], 3, range(9))
     29        sage: TestSuite(M).run() is None
     30        True
     31    """
     32    cdef set_unsafe(self, Py_ssize_t i, Py_ssize_t j, x):
     33        # no bounds or any other checks; assumes x is in self._base_ring
     34        cdef Polynomial_zmod_flint poly = x
     35        zmod_poly_set(&self._matrix[i][j], &poly.x)
     36
     37    cdef Polynomial_zmod_flint get_unsafe(self, Py_ssize_t i, Py_ssize_t j):
     38        """
     39        TESTS::
     40
     41            sage: P.<x> = GF(31223)[]
     42            sage: M = Matrix(P,3,10)
     43            sage: M[1,1] =  17346*x^2 + 29488*x + 20815
     44            sage: M[1,1] *= x+1 # indirect doctest
     45            sage: M[1,1]
     46            17346*x^3 + 15611*x^2 + 19080*x + 20815
     47        """
     48        # no checks
     49        cdef Polynomial_zmod_flint res = PY_NEW(Polynomial_zmod_flint)
     50        zmod_poly_init(&res.x, (<Matrix_dense_template>self)._modulus)
     51        res._parent = self._base_ring
     52        res._is_gen = 0
     53        zmod_poly_set(&res.x, &(<Matrix_zmodpoly_dense>self)._matrix[i][j])
     54        return res