Skip to content
This repository has been archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Cleaning linbox interface of Matrix_integer_dense
Browse files Browse the repository at this point in the history
  • Loading branch information
videlec committed May 1, 2017
1 parent cca8edf commit cccbe30
Show file tree
Hide file tree
Showing 6 changed files with 546 additions and 198 deletions.
1 change: 1 addition & 0 deletions src/doc/en/reference/libs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ to be aware of the modules described in this chapter.
sage/libs/singular/groebner_strategy
sage/libs/ppl
sage/libs/linbox/linbox
sage/libs/linbox/linbox_flint_interface
sage/libs/flint/flint
sage/libs/flint/fmpz_poly
sage/libs/flint/arith
Expand Down
35 changes: 35 additions & 0 deletions src/sage/libs/linbox/linbox.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

r"""
Linbox interface
The interface :class:`Linbox_integer_dense` to dense matrices is deprecated. One
would better use :mod:`~sage.libs.linbox.linbox_flint_interface`
"""

## NOTE: The sig_on()/sig_off() stuff can't go in here -- it has to be in the
Expand Down Expand Up @@ -83,17 +86,30 @@ cdef extern from "linbox/linbox-sage.h":
size_t nrows, size_t ncols)

cdef class Linbox_integer_dense:
r"""
.. WARNING::
deprecated class
"""
cdef set(self, mpz_t** matrix, size_t nrows, size_t ncols):
from sage.misc.superseded import deprecation
deprecation(111111, "sage.libs.linbox.linbox.Linbox_integer_dense is deprecated, use sage.libs.linbox.linbox_flint_interface instead")

self.nrows = nrows
self.ncols = ncols
self.matrix = matrix

def minpoly(self):
"""
Deprecated
OUTPUT:
coefficients of minpoly as a Python list
"""
from sage.misc.superseded import deprecation
deprecation(111111, "sage.libs.linbox.linbox.Linbox_integer_dense is deprecated, use sage.libs.linbox.linbox_flint_interface instead")

cdef mpz_t* poly
cdef size_t degree
verbose("using linbox poly comp")
Expand All @@ -113,10 +129,15 @@ cdef class Linbox_integer_dense:

def charpoly(self):
"""
Deprecated
OUTPUT:
coefficients of charpoly or minpoly as a Python list
"""
from sage.misc.superseded import deprecation
deprecation(111111, "sage.libs.linbox.linbox.Linbox_integer_dense is deprecated, use sage.libs.linbox.linbox_flint_interface instead")

cdef mpz_t* poly
cdef size_t degree
verbose("using linbox poly comp")
Expand All @@ -138,27 +159,41 @@ cdef class Linbox_integer_dense:
mpz_t **ans,
mpz_t **B,
size_t B_nr, size_t B_nc):
from sage.misc.superseded import deprecation
deprecation(111111, "sage.libs.linbox.linbox.Linbox_integer_dense is deprecated, use sage.libs.linbox.linbox_flint_interface instead")

cdef int e
e = linbox_integer_dense_matrix_matrix_multiply(ans, self.matrix, B, self.nrows, self.ncols, B_nc)
if e:
raise RuntimeError("error doing matrix matrix multiply over ZZ using linbox")


cdef unsigned long rank(self) except -1:
from sage.misc.superseded import deprecation
deprecation(111111, "sage.libs.linbox.linbox.Linbox_integer_dense is deprecated, use sage.libs.linbox.linbox_flint_interface instead")

return linbox_integer_dense_rank(self.matrix, self.nrows, self.ncols)

def det(self):
"""
Deprecated
OUTPUT:
determinant as a sage Integer
"""
from sage.misc.superseded import deprecation
deprecation(111111, "sage.libs.linbox.linbox.Linbox_integer_dense is deprecated, use sage.libs.linbox.linbox_flint_interface instead")

cdef Integer z
z = Integer()
linbox_integer_dense_det(z.value, self.matrix, self.nrows, self.ncols)
return z

def smithform(self):
from sage.misc.superseded import deprecation
deprecation(111111, "sage.libs.linbox.linbox.Linbox_integer_dense is deprecated, use sage.libs.linbox.linbox_flint_interface instead")

raise NotImplementedError
#cdef mpz_t* v
#linbox_integer_dense_smithform(&v, self.matrix, self.nrows, self.ncols)
Expand Down
16 changes: 16 additions & 0 deletions src/sage/libs/linbox/linbox_flint_interface.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from sage.libs.flint.types cimport fmpz_t, fmpz_mat_t, fmpz_poly_t

# set C <- A * B
cdef void linbox_fmpz_mat_mul(fmpz_mat_t C, fmpz_mat_t A, fmpz_mat_t B)

# set cp to the characteristic polynomial of A
cdef void linbox_fmpz_mat_charpoly(fmpz_poly_t cp, fmpz_mat_t A)

# set mp to the minimal polynomial of A
cdef void linbox_fmpz_mat_minpoly(fmpz_poly_t mp, fmpz_mat_t A)

# return the rank of A
cdef unsigned long linbox_fmpz_mat_rank(fmpz_mat_t A)

# set det to the determinant of A
cdef void linbox_fmpz_mat_det(fmpz_t det, fmpz_mat_t A)
240 changes: 240 additions & 0 deletions src/sage/libs/linbox/linbox_flint_interface.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
# distutils: extra_compile_args = LINBOX_CFLAGS
# distutils: libraries = LINBOX_LIBRARIES
# distutils: library_dirs = LINBOX_LIBDIR
# distutils: language = c++
r"""
Interface between flint matrices and linbox
This module only contains C++ code (and the interface is fully C
compatible). It basically contains what used to be in the LinBox
source code under interfaces/sage/linbox-Sage.C written by M. Albrecht
and C. Pernet. The functions available are:
- ``void linbox_fmpz_mat_mul(fmpz_mat_t C, fmpz_mat_t A, fmpz_mat_t B)``: set
``C`` to be the result of the multiplication ``A * B``
- ``void linbox_fmpz_mat_charpoly(fmpz_poly_t cp, fmpz_mat_t A)``: set ``cp``
to be the characteristic polynomial of the square matrix ``A``
- ``void linbox_fmpz_mat_minpoly(fmpz_poly_t mp, fmpz_mat_t A)``: set ``mp``
to be the minimal polynomial of the square matrix ``A``
- ``unsigned long linbox_fmpz_mat_rank(fmpz_mat_t A)``: return the rank of the
matrix ``A``
- ``void linbox_fmpz_mat_det(fmpz_t det, fmpz_mat_t A)``: set ``det`` to the
determinat of the square matrix ``A``
"""
#*****************************************************************************
# Copyright (C) 2007 Martin Albrecht
# Copyright (C) 2008 Clement Pernet
# Copyright (C) 2017 Vincent Delecroix
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 2 of the License, or
# (at your option) any later version.
# http://www.gnu.org/licenses/
#*****************************************************************************

from sage.libs.gmp.types cimport mpz_t, mpz_srcptr, mpz_ptr
from sage.libs.gmp.mpz cimport mpz_set
from sage.libs.flint.types cimport fmpz, fmpz_t
from sage.libs.flint.fmpz cimport fmpz_get_mpz, fmpz_set_mpz
from sage.libs.flint.fmpz_mat cimport fmpz_mat_entry, fmpz_mat_nrows, fmpz_mat_ncols
from sage.libs.flint.fmpz_poly cimport fmpz_poly_set_coeff_mpz, fmpz_poly_fit_length, _fmpz_poly_set_length

cdef extern from "givaro/givconfig.h":
pass
cdef extern from "linbox/linbox-config.h":
pass

cdef extern from "gmp++/gmp++.h":
cdef cppclass GivaroInteger "Givaro::Integer":
mpz_srcptr get_mpz()

cdef extern from "linbox/matrix/dense-matrix.h":
## template <class _Field>
## using DenseMatrix = BlasMatrix<_Field> ;
##
# indirect include from linbox/matrix/densematrix/blas-matrix.h
##
## template <class _Field, class _Storage>
## class BlasMatrix
cdef cppclass LinBoxIntegerDenseMatrix "LinBox::DenseMatrix<Givaro::ZRing<Givaro::Integer>>":
ctypedef GivaroIntegerRing Field
ctypedef GivaroInteger Element
size_t rowdim()
size_t coldim()
LinBoxIntegerDenseMatrix(Field &F, size_t m, size_t n)
void setEntry(size_t i, size_t j, Element &a)
Element &getEntry(size_t i, size_t j)

cdef extern from "givaro/zring.h":
cdef cppclass GivaroIntegerRing "Givaro::ZRing<Givaro::Integer>":
ctypedef GivaroInteger Element

cdef extern from "givaro/givspyinteger.h":
cdef cppclass GivaroSpyInteger "Givaro::SpyInteger":
mpz_ptr get_mpz(GivaroInteger& i)
mpz_srcptr get_mpz_const(const GivaroInteger& i)

cdef extern from "givaro/givpoly1.h":
## template < typename T, typename A=std::allocator<T> >
## class givvector : public __GIV_STANDARD_VECTOR<T,A>
cdef cppclass givvector "Givaro::givvector" [T,ALLOCATOR=*]:
T& operator[](size_t i)
size_t size()

cdef extern from "linbox/ring/givaro-polynomial.h":
## template <class Domain, class StorageTag= Givaro::Dense>
## class GivPolynomialRing : public Givaro::Poly1FactorDom< Domain,StorageTag>
cdef cppclass LinBoxIntegerPolynomialRing "LinBox::GivPolynomialRing<Givaro::ZRing<Givaro::Integer>, Givaro::Dense>":
ctypedef givvector[GivaroInteger] Element
ctypedef givvector[GivaroInteger] Polynomial

cdef extern from "linbox/matrix/matrix-domain.h":
## template <class Field_ >
## class MatrixDomain : public MVProductDomain<Field_> {
cdef cppclass LinBoxIntegerDenseMatrixDomain "LinBox::MatrixDomain<Givaro::ZRing<Givaro::Integer>>":
LinBoxIntegerDenseMatrixDomain(GivaroIntegerRing&)
LinBoxIntegerDenseMatrix& mul(LinBoxIntegerDenseMatrix ans,
LinBoxIntegerDenseMatrix left,
LinBoxIntegerDenseMatrix right)

cdef extern from "linbox/solutions/charpoly.h":
## template<class Blackbox, class Polynomial>
## Polynomial &charpoly (Polynomial & P, const Blackbox & A)
LinBoxIntegerPolynomialRing.Element& LinBoxIntegerDense_charpoly "LinBox::charpoly" (LinBoxIntegerPolynomialRing.Element&, LinBoxIntegerDenseMatrix&)

cdef extern from "linbox/solutions/minpoly.h":
## template<class Polynomial, class Blackbox>
## Polynomial &minpoly (Polynomial & P, const Blackbox & A)
LinBoxIntegerPolynomialRing.Element& LinBoxIntegerDense_minpoly "LinBox::minpoly" (LinBoxIntegerPolynomialRing.Element&, LinBoxIntegerDenseMatrix&)

cdef extern from "linbox/solutions/rank.h":
## template <class Blackbox, class Method, class DomainCategory>
## inline unsigned long &rank (unsigned long &r, const Blackbox &A,
## const DomainCategory &tag, const Method &M);
unsigned long & LinBoxIntegerDense_rank "LinBox::rank" (unsigned long &, LinBoxIntegerDenseMatrix)

cdef extern from "linbox/solutions/det.h":
GivaroInteger& LinBoxIntegerDense_det "LinBox::det" (GivaroInteger&, LinBoxIntegerDenseMatrix)



###############################################################################
# end of LinBox declarations -- begining of the code #
###############################################################################


cdef GivaroSpyInteger spy

# set the entries of A from m (no allocation preformed)
# NOTE: this function is not part of the interface (ie the .pxd file) to keep the
# module C-compatible
cdef void fmpz_mat_get_linbox(LinBoxIntegerDenseMatrix * A, fmpz_mat_t m):
"Set the entries of A to m"
cdef size_t i,j
cdef GivaroInteger t

for i in range(fmpz_mat_nrows(m)):
for j in range(fmpz_mat_ncols(m)):
fmpz_get_mpz(<mpz_t> spy.get_mpz(t), fmpz_mat_entry(m, i, j))
A.setEntry(i, j, t)


# set the entries of m from A (no allocation performed)
# NOTE: this function is not part of the interface (ie the .pxd file) to keep the
# module C-compatible
cdef void fmpz_mat_set_linbox(fmpz_mat_t m, LinBoxIntegerDenseMatrix *A):
"Set the entries of m to A"
cdef size_t i,j
for i in range(A.rowdim()):
for j in range(A.coldim()):
fmpz_set_mpz(fmpz_mat_entry(m, i, j), <mpz_t> spy.get_mpz(A.getEntry(i, j)))


# set C <- A * B
cdef void linbox_fmpz_mat_mul(fmpz_mat_t C, fmpz_mat_t A, fmpz_mat_t B):
cdef GivaroIntegerRing ZZ
cdef LinBoxIntegerDenseMatrix *LBA
cdef LinBoxIntegerDenseMatrix *LBB
cdef LinBoxIntegerDenseMatrix *LBC

LBA = new LinBoxIntegerDenseMatrix(ZZ, fmpz_mat_nrows(A), fmpz_mat_ncols(A))
fmpz_mat_get_linbox(LBA, A)

LBB = new LinBoxIntegerDenseMatrix(ZZ, fmpz_mat_nrows(B), fmpz_mat_ncols(B))
fmpz_mat_get_linbox(LBB, B)

LBC = new LinBoxIntegerDenseMatrix(ZZ, fmpz_mat_nrows(A), fmpz_mat_ncols(B))

cdef LinBoxIntegerDenseMatrixDomain * MD
MD = new LinBoxIntegerDenseMatrixDomain(ZZ)
MD.mul(LBC[0], LBA[0], LBB[0])
del MD

fmpz_mat_set_linbox(C, LBC)


# set p to the minpoly or the charpoly of A
cdef inline void linbox_fmpz_mat_poly(fmpz_poly_t p, fmpz_mat_t A, int minpoly):
cdef GivaroIntegerRing ZZ
cdef LinBoxIntegerDenseMatrix * LBA

LBA = new LinBoxIntegerDenseMatrix(ZZ, fmpz_mat_nrows(A), fmpz_mat_ncols(A))
fmpz_mat_get_linbox(LBA, A)

cdef LinBoxIntegerPolynomialRing.Element m_A
if minpoly:
LinBoxIntegerDense_minpoly(m_A, LBA[0])
else:
LinBoxIntegerDense_charpoly(m_A, LBA[0])

del LBA

fmpz_poly_fit_length(p, m_A.size())
_fmpz_poly_set_length(p, m_A.size())

cdef size_t i
for i in range(m_A.size()):
fmpz_poly_set_coeff_mpz(p, i, spy.get_mpz(m_A[i]))


# set cp to the characteristic polynomial of A
cdef void linbox_fmpz_mat_charpoly(fmpz_poly_t cp, fmpz_mat_t A):
linbox_fmpz_mat_poly(cp, A, False)


# set mp to the minimal polynomial of A
cdef void linbox_fmpz_mat_minpoly(fmpz_poly_t mp, fmpz_mat_t A):
linbox_fmpz_mat_poly(mp, A, True)


# return the rank of A
cdef unsigned long linbox_fmpz_mat_rank(fmpz_mat_t A):
cdef GivaroIntegerRing ZZ
cdef LinBoxIntegerDenseMatrix * LBA

LBA = new LinBoxIntegerDenseMatrix(ZZ, fmpz_mat_nrows(A), fmpz_mat_ncols(A))
fmpz_mat_get_linbox(LBA, A)
cdef unsigned long r = 0
LinBoxIntegerDense_rank(r, LBA[0])
del LBA
return r


# set det to the determinant of A
cdef void linbox_fmpz_mat_det(fmpz_t det, fmpz_mat_t A):
cdef GivaroIntegerRing ZZ
cdef LinBoxIntegerDenseMatrix * LBA

LBA = new LinBoxIntegerDenseMatrix(ZZ, fmpz_mat_nrows(A), fmpz_mat_ncols(A))
fmpz_mat_get_linbox(LBA, A)
cdef GivaroInteger d
LinBoxIntegerDense_det(d, LBA[0])
del LBA

fmpz_set_mpz(det, spy.get_mpz(d))

9 changes: 1 addition & 8 deletions src/sage/matrix/matrix_integer_dense.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,14 @@ from sage.ext.mod_int cimport *
ctypedef long* GEN

cdef class Matrix_integer_dense(Matrix_dense):
cdef fmpz_mat_t _matrix # Always initialized in __cinit__
cdef bint _initialized_mpz
cdef mpz_t * _entries # Only used if _initialized_mpz
cdef mpz_t ** _rows # Only used if _initialized_mpz
cdef fmpz_mat_t _matrix
cdef object _pivots
cdef int mpz_height(self, mpz_t height) except -1
cdef _mod_int_c(self, mod_int modulus)
cdef _mod_two(self)
cdef _pickle_version0(self)
cdef _unpickle_version0(self, data)
cpdef _export_as_string(self, int base=?)
cdef inline int _init_mpz(self) except -1
cdef int _init_mpz_impl(self) except -1
cdef inline int _init_linbox(self) except -1
cdef void _dealloc_mpz(self)
cdef void set_unsafe_mpz(self, Py_ssize_t i, Py_ssize_t j, const mpz_t value)
cdef void set_unsafe_si(self, Py_ssize_t i, Py_ssize_t j, long value)
cdef void set_unsafe_double(self, Py_ssize_t i, Py_ssize_t j, double value)
Expand Down
Loading

0 comments on commit cccbe30

Please sign in to comment.