Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

# 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 

determinant 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, fmpz_poly_one 

  

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_ptr get_mpz() 

mpz_srcptr get_mpz_const() 

  

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 "linbox/polynomial/dense-polynomial.h": 

## template<class Field> 

## class DensePolynomial : public Givaro::Poly1FactorDom<Field, Givaro::Dense>::Element 

cdef cppclass LinBoxIntegerDensePolynomial "LinBox::DensePolynomial<Givaro::ZRing<Givaro::Integer> >": 

ctypedef GivaroIntegerRing BaseRing 

ctypedef GivaroInteger BaseRingElement 

LinBoxIntegerDensePolynomial(BaseRing &F) 

LinBoxIntegerDensePolynomial(BaseRing &F, size_t s) 

BaseRingElement& operator[](size_t i) 

size_t size() 

  

cdef extern from "linbox/ring/polynomial-ring.h": 

## template <class BaseRing, class StorageTag= Givaro::Dense> 

## class PolynomialRing : public Givaro::Poly1FactorDom<BaseRing,StorageTag> 

cdef cppclass LinBoxIntegerPolynomialRing "LinBox::PolynomialRing<Givaro::ZRing<Givaro::Integer>, Givaro::Dense>": 

ctypedef LinBoxIntegerDensePolynomial Element 

ctypedef LinBoxIntegerDensePolynomial 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 # 

############################################################################### 

  

  

# set the entries of A from m (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_get_linbox(LinBoxIntegerDenseMatrix& A, fmpz_mat_t 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(t.get_mpz(), 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): 

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), A.getEntry(i, j).get_mpz_const()) 

  

  

# set the entries of the polynomial p from q (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_poly_set_linbox(fmpz_poly_t p, LinBoxIntegerPolynomialRing.Element& q): 

cdef size_t i 

  

fmpz_poly_fit_length(p, q.size()) 

  

for i in range(q.size()): 

fmpz_poly_set_coeff_mpz(p, i, q[i].get_mpz_const()) 

  

_fmpz_poly_set_length(p, q.size()) 

  

  

# 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 

cdef LinBoxIntegerDenseMatrixDomain * MD 

  

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

fmpz_mat_get_linbox(LBA[0], A) 

  

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

fmpz_mat_get_linbox(LBB[0], B) 

  

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

  

MD = new LinBoxIntegerDenseMatrixDomain(ZZ) 

MD.mul(LBC[0], LBA[0], LBB[0]) 

  

del MD 

  

fmpz_mat_set_linbox(C, LBC[0]) 

  

  

# set cp to the characteristic polynomial of A 

cdef void linbox_fmpz_mat_charpoly(fmpz_poly_t cp, fmpz_mat_t A): 

cdef GivaroIntegerRing ZZ 

cdef LinBoxIntegerDenseMatrix * LBA 

cdef LinBoxIntegerDensePolynomial * m_A 

  

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

fmpz_mat_get_linbox(LBA[0], A) 

m_A = new LinBoxIntegerDensePolynomial(ZZ, fmpz_mat_nrows(A)) 

LinBoxIntegerDense_charpoly(m_A[0], LBA[0]) 

fmpz_poly_set_linbox(cp, m_A[0]) 

  

del LBA 

del m_A 

  

  

# set mp to the minimal polynomial of A 

cdef void linbox_fmpz_mat_minpoly(fmpz_poly_t mp, fmpz_mat_t A): 

cdef GivaroIntegerRing ZZ 

cdef LinBoxIntegerDenseMatrix * LBA 

cdef LinBoxIntegerDensePolynomial * m_A 

  

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

m_A = new LinBoxIntegerDensePolynomial(ZZ) 

fmpz_mat_get_linbox(LBA[0], A) 

LinBoxIntegerDense_minpoly(m_A[0], LBA[0]) 

fmpz_poly_set_linbox(mp, m_A[0]) 

  

del LBA 

del m_A 

  

  

# return the rank of A 

cdef unsigned long linbox_fmpz_mat_rank(fmpz_mat_t A): 

cdef GivaroIntegerRing ZZ 

cdef LinBoxIntegerDenseMatrix * LBA 

cdef unsigned long r = 0 

  

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

fmpz_mat_get_linbox(LBA[0], A) 

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 

cdef GivaroInteger d 

  

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

fmpz_mat_get_linbox(LBA[0], A) 

LinBoxIntegerDense_det(d, LBA[0]) 

fmpz_set_mpz(det, d.get_mpz_const()) 

  

del LBA