Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/libs/linbox/linbox.pyx
4077 views
1
## NOTE: The sig_on()/sig_off() stuff can't go in here -- it has to be in the
2
## code that calls these functions. Otherwise strangely objects get left
3
## in an incorrect state.
4
5
from sage.rings.integer cimport Integer
6
from sage.misc.misc import verbose, get_verbose, cputime, UNAME
7
8
##########################################################################
9
## Dense matrices modulo p
10
##########################################################################
11
12
# LinBox bugs to address:
13
# * charpoly and minpoly don't work randomly
14
15
cdef extern from "linbox/linbox-sage.h":
16
void linbox_modn_dense_delete_array(mod_int *f)
17
18
int linbox_modn_dense_echelonize(unsigned long modulus,
19
mod_int **matrix, size_t nrows, size_t ncols)
20
void linbox_modn_dense_minpoly(unsigned long modulus, mod_int **mp, size_t* degree, size_t n,
21
mod_int **matrix, int do_minpoly)
22
23
int linbox_modn_dense_matrix_matrix_multiply(unsigned long modulus, mod_int **ans,
24
mod_int **A, mod_int **B,
25
size_t A_nr, size_t A_nc,
26
size_t B_nr, size_t B_nc)
27
28
int linbox_modn_dense_rank(unsigned long modulus,
29
mod_int** matrix, size_t nrows, size_t ncols)
30
31
mod_int linbox_modn_dense_det(mod_int modulus, mod_int** matrix, size_t nrows, size_t ncols)
32
33
34
cdef class Linbox_modn_dense:
35
def __init__(self):
36
self.matrix = <mod_int**> 0
37
38
def __dealloc__(self):
39
if self.matrix:
40
for i from 0 <= i < self.nrows:
41
sage_free(self.matrix[i])
42
sage_free(self.matrix)
43
44
cdef set(self, mod_int n, mod_int** matrix,
45
size_t nrows, size_t ncols):
46
self.n = n
47
self.nrows = nrows
48
self.ncols = ncols
49
self.matrix = matrix
50
51
cdef int echelonize(self):
52
cdef int r
53
r = linbox_modn_dense_echelonize(self.n, self.matrix,
54
self.nrows, self.ncols)
55
return r
56
57
def minpoly(self):
58
return self._poly(True)
59
60
def charpoly(self):
61
return self._poly(False)
62
63
def _poly(self, minpoly):
64
"""
65
INPUT:
66
as given
67
68
OUTPUT:
69
coefficients of charpoly or minpoly as a Python list
70
"""
71
cdef mod_int *f
72
cdef size_t degree
73
linbox_modn_dense_minpoly(self.n, &f, &degree,
74
self.nrows, self.matrix,
75
minpoly)
76
v = []
77
cdef Py_ssize_t i
78
for i from 0 <= i <= degree:
79
v.append(f[i])
80
linbox_modn_dense_delete_array(f)
81
return v
82
83
cdef matrix_matrix_multiply(self,
84
mod_int **ans,
85
mod_int **B,
86
size_t B_nr, size_t B_nc):
87
cdef int e
88
e = linbox_modn_dense_matrix_matrix_multiply(self.n, ans,
89
self.matrix, B,
90
self.nrows, self.ncols,
91
B_nr, B_nc)
92
if e:
93
raise RuntimeError, "error doing matrix matrix multiply modn using linbox"
94
95
96
cdef unsigned long rank(self) except -1:
97
cdef unsigned long r
98
r = linbox_modn_dense_rank(self.n, self.matrix, self.nrows, self.ncols)
99
return r
100
101
cpdef mod_int det(self) except -1:
102
cdef mod_int d
103
d = linbox_modn_dense_det(self.n, self.matrix, self.nrows, self.ncols)
104
return d
105
106
##########################################################################
107
## Sparse matrices modulo p.
108
##########################################################################
109
110
include '../../modules/vector_modn_sparse_c.pxi'
111
include '../../ext/stdsage.pxi'
112
113
cdef extern from "linbox/linbox-sage.h":
114
ctypedef struct vector_uint "std::vector<unsigned int>":
115
void (*push_back)(unsigned int)
116
int (*get "operator[]") (size_t i)
117
int (*size)()
118
119
int linbox_modn_sparse_matrix_rank(unsigned long modulus, size_t nrows, size_t ncols, void* rows, int reorder) #, int **pivots)
120
vector_uint linbox_modn_sparse_matrix_solve(unsigned long modulus, size_t numrows, size_t numcols, void *a, void *b, int method)
121
122
cdef class Linbox_modn_sparse:
123
cdef set(self, int modulus, size_t nrows, size_t ncols, c_vector_modint *rows):
124
self.rows = rows
125
self.nrows = nrows
126
self.ncols = ncols
127
self.modulus = modulus
128
129
cdef object rank(self, int gauss):
130
#cdef int *_pivots
131
cdef int r
132
r = linbox_modn_sparse_matrix_rank(self.modulus, self.nrows, self.ncols, self.rows, gauss)
133
134
#pivots = [_pivots[i] for i in range(r)]
135
#free(_pivots)
136
return r#, pivots
137
138
cdef void solve(self, c_vector_modint **x, c_vector_modint *b, int method):
139
"""
140
"""
141
cdef vector_uint X
142
X = linbox_modn_sparse_matrix_solve(self.modulus, self.nrows, self.ncols, self.rows, b, method)
143
144
for i from 0 <= i < X.size():
145
set_entry(x[0], i, X.get(i))
146
147
148
##########################################################################
149
## Sparse matrices over ZZ
150
##########################################################################
151
152
153
##########################################################################
154
## Dense matrices over ZZ
155
##########################################################################
156
157
cdef extern from "linbox/linbox-sage.h":
158
void linbox_integer_dense_minpoly_hacked(mpz_t* *minpoly, size_t* degree,
159
size_t n, mpz_t** matrix, int do_minpoly)
160
161
void linbox_integer_dense_minpoly(mpz_t* *minpoly, size_t* degree,
162
size_t n, mpz_t** matrix)
163
164
void linbox_integer_dense_charpoly(mpz_t* *charpoly, size_t* degree,
165
size_t n, mpz_t** matrix)
166
167
void linbox_integer_dense_delete_array(mpz_t* f)
168
169
int linbox_integer_dense_matrix_matrix_multiply(mpz_t** ans, mpz_t **A, mpz_t **B,
170
size_t A_nr, size_t A_nc, size_t B_nr, size_t B_nc)
171
172
unsigned long linbox_integer_dense_rank(mpz_t** matrix, size_t nrows,
173
size_t ncols)
174
175
void linbox_integer_dense_det(mpz_t ans, mpz_t** matrix,
176
size_t nrows, size_t ncols)
177
178
void linbox_integer_dense_smithform(mpz_t **v,
179
mpz_t **matrix,
180
size_t nrows, size_t ncols)
181
182
cdef class Linbox_integer_dense:
183
cdef set(self, mpz_t** matrix, size_t nrows, size_t ncols):
184
self.nrows = nrows
185
self.ncols = ncols
186
self.matrix = matrix
187
188
def minpoly(self):
189
return self._poly(True)
190
191
def charpoly(self):
192
return self._poly(False)
193
194
def _poly(self, do_minpoly):
195
"""
196
INPUT:
197
as given
198
199
OUTPUT:
200
coefficients of charpoly or minpoly as a Python list
201
"""
202
cdef mpz_t* poly
203
cdef size_t degree
204
verbose("using linbox poly comp")
205
if do_minpoly:
206
linbox_integer_dense_minpoly(&poly, &degree, self.nrows, self.matrix)
207
else:
208
linbox_integer_dense_charpoly(&poly, &degree, self.nrows, self.matrix)
209
verbose("computed poly -- now converting back to Sage")
210
211
v = []
212
cdef Integer k
213
cdef size_t n
214
for n from 0 <= n <= degree:
215
k = Integer()
216
mpz_set(k.value, poly[n])
217
mpz_clear(poly[n])
218
v.append(k)
219
linbox_integer_dense_delete_array(poly)
220
return v
221
222
cdef matrix_matrix_multiply(self,
223
mpz_t **ans,
224
mpz_t **B,
225
size_t B_nr, size_t B_nc):
226
cdef int e
227
e = linbox_integer_dense_matrix_matrix_multiply(ans,
228
self.matrix, B,
229
self.nrows, self.ncols,
230
B_nr, B_nc)
231
if e:
232
raise RuntimeError, "error doing matrix matrix multiply over ZZ using linbox"
233
234
235
cdef unsigned long rank(self) except -1:
236
return linbox_integer_dense_rank(self.matrix, self.nrows, self.ncols)
237
238
def det(self):
239
cdef Integer z
240
z = Integer()
241
linbox_integer_dense_det(z.value, self.matrix, self.nrows, self.ncols)
242
return z
243
244
def smithform(self):
245
raise NotImplementedError
246
#cdef mpz_t* v
247
#linbox_integer_dense_smithform(&v, self.matrix, self.nrows, self.ncols)
248
#z = []
249
#cdef Integer k
250
#cdef size_t n
251
#for n from 0 <= n < self.ncols:
252
# k = Integer()
253
# mpz_set(k.value, v[n])
254
# mpz_clear(v[n])
255
# z.append(k)
256
#linbox_integer_dense_delete_array(v)
257
#return z
258
259
260