passagemath-linbox 10.6.32__cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of passagemath-linbox might be problematic. Click here for more details.
- passagemath_linbox-10.6.32.dist-info/METADATA +100 -0
- passagemath_linbox-10.6.32.dist-info/RECORD +73 -0
- passagemath_linbox-10.6.32.dist-info/WHEEL +6 -0
- passagemath_linbox-10.6.32.dist-info/top_level.txt +2 -0
- passagemath_linbox.libs/libfflas-d452d784.so.1.0.0 +0 -0
- passagemath_linbox.libs/libffpack-32579c9b.so.1.0.0 +0 -0
- passagemath_linbox.libs/libflint-66e12231.so.21.0.0 +0 -0
- passagemath_linbox.libs/libgd-76eb082b.so.3.0.11 +0 -0
- passagemath_linbox.libs/libgfortran-83c28eba.so.5.0.0 +0 -0
- passagemath_linbox.libs/libgivaro-fc554fc9.so.9.2.1 +0 -0
- passagemath_linbox.libs/libgmp-6e109695.so.10.5.0 +0 -0
- passagemath_linbox.libs/libgmpxx-ecb9d6e3.so.4.7.0 +0 -0
- passagemath_linbox.libs/libiml-aeb1d147.so.0.1.1 +0 -0
- passagemath_linbox.libs/liblinbox-f1d24fc1.so.0.0.0 +0 -0
- passagemath_linbox.libs/libm4ri-9da2b874.so.1.0.0 +0 -0
- passagemath_linbox.libs/libm4rie-cf8cc058.so.1.0.0 +0 -0
- passagemath_linbox.libs/libmpfr-82690d50.so.6.2.1 +0 -0
- passagemath_linbox.libs/libopenblasp-r0-6dcb67f9.3.29.so +0 -0
- passagemath_linbox.libs/libpng16-b4a91cd1.so.16.43.0 +0 -0
- passagemath_linbox.libs/libquadmath-2284e583.so.0.0.0 +0 -0
- sage/all__sagemath_linbox.py +2 -0
- sage/geometry/all__sagemath_linbox.py +1 -0
- sage/geometry/integral_points.pxi +1426 -0
- sage/geometry/integral_points_integer_dense.cpython-313-x86_64-linux-gnu.so +0 -0
- sage/geometry/integral_points_integer_dense.pyx +7 -0
- sage/libs/all__sagemath_linbox.py +1 -0
- sage/libs/iml.pxd +10 -0
- sage/libs/linbox/__init__.py +1 -0
- sage/libs/linbox/conversion.pxd +185 -0
- sage/libs/linbox/fflas.pxd +189 -0
- sage/libs/linbox/givaro.pxd +109 -0
- sage/libs/linbox/linbox.pxd +219 -0
- sage/libs/linbox/linbox_flint_interface.cpython-313-x86_64-linux-gnu.so +0 -0
- sage/libs/linbox/linbox_flint_interface.pxd +18 -0
- sage/libs/linbox/linbox_flint_interface.pyx +192 -0
- sage/libs/m4ri.pxd +198 -0
- sage/libs/m4rie.pxd +204 -0
- sage/matrix/all__sagemath_linbox.py +1 -0
- sage/matrix/matrix_cyclo_linbox.cpython-313-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_cyclo_linbox.pyx +361 -0
- sage/matrix/matrix_gf2e_dense.cpython-313-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_gf2e_dense.pxd +15 -0
- sage/matrix/matrix_gf2e_dense.pyx +1573 -0
- sage/matrix/matrix_integer_iml.cpython-313-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_integer_iml.pyx +316 -0
- sage/matrix/matrix_integer_linbox.cpython-313-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_integer_linbox.pxd +5 -0
- sage/matrix/matrix_integer_linbox.pyx +358 -0
- sage/matrix/matrix_integer_sparse_linbox.cpython-313-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_integer_sparse_linbox.pyx +465 -0
- sage/matrix/matrix_mod2_dense.cpython-313-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_mod2_dense.pxd +14 -0
- sage/matrix/matrix_mod2_dense.pyx +2789 -0
- sage/matrix/matrix_modn_dense_double.cpython-313-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_modn_dense_double.pyx +179 -0
- sage/matrix/matrix_modn_dense_float.cpython-313-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_modn_dense_float.pyx +154 -0
- sage/matrix/matrix_modn_sparse.cpython-313-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_modn_sparse.pyx +871 -0
- sage/matrix/matrix_rational_linbox.cpython-313-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_rational_linbox.pyx +36 -0
- sage/matrix/misc.cpython-313-x86_64-linux-gnu.so +0 -0
- sage/matrix/misc.pyx +418 -0
- sage/modules/all__sagemath_linbox.py +1 -0
- sage/modules/numpy_util.cpython-313-x86_64-linux-gnu.so +0 -0
- sage/modules/numpy_util.pxd +10 -0
- sage/modules/numpy_util.pyx +136 -0
- sage/modules/vector_mod2_dense.cpython-313-x86_64-linux-gnu.so +0 -0
- sage/modules/vector_mod2_dense.pxd +11 -0
- sage/modules/vector_mod2_dense.pyx +547 -0
- sage/rings/all__sagemath_linbox.py +1 -0
- sage/rings/finite_rings/all__sagemath_linbox.py +1 -0
- sage/rings/polynomial/all__sagemath_linbox.py +1 -0
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-linbox
|
|
2
|
+
# sage.doctest: needs sage.libs.flint sage.libs.linbox
|
|
3
|
+
|
|
4
|
+
from cpython.long cimport PyLong_FromSize_t
|
|
5
|
+
|
|
6
|
+
from cysignals.signals cimport sig_check, sig_on, sig_str, sig_off
|
|
7
|
+
|
|
8
|
+
from sage.ext.stdsage cimport PY_NEW
|
|
9
|
+
from sage.libs.flint.fmpz cimport *
|
|
10
|
+
from sage.libs.flint.fmpz_mat cimport *
|
|
11
|
+
from sage.libs.flint.fmpz_poly_sage cimport fmpz_poly_set_coeff_mpz
|
|
12
|
+
from sage.libs.flint.fmpz_poly cimport fmpz_poly_fit_length, _fmpz_poly_set_length
|
|
13
|
+
from sage.libs.gmp.mpz cimport *
|
|
14
|
+
from sage.matrix.matrix cimport Matrix
|
|
15
|
+
from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense
|
|
16
|
+
from sage.matrix.matrix_integer_sparse cimport Matrix_integer_sparse
|
|
17
|
+
from sage.modules.vector_integer_dense cimport Vector_integer_dense
|
|
18
|
+
from sage.rings.integer cimport Integer
|
|
19
|
+
from sage.rings.integer_ring import ZZ
|
|
20
|
+
from sage.rings.polynomial.polynomial_integer_dense_flint cimport Polynomial_integer_dense_flint
|
|
21
|
+
|
|
22
|
+
cimport sage.libs.linbox.givaro as givaro
|
|
23
|
+
cimport sage.libs.linbox.linbox as linbox
|
|
24
|
+
from sage.libs.linbox.conversion cimport (
|
|
25
|
+
new_linbox_vector_integer_dense,
|
|
26
|
+
new_sage_vector_integer_dense,
|
|
27
|
+
new_linbox_matrix_integer_sparse,
|
|
28
|
+
METHOD_DEFAULT, METHOD_DENSE_ELIMINATION,
|
|
29
|
+
METHOD_SPARSE_ELIMINATION, METHOD_BLACKBOX,
|
|
30
|
+
METHOD_WIEDEMANN, get_method)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _rank_linbox(Matrix_integer_sparse self):
|
|
34
|
+
r"""
|
|
35
|
+
Compute the rank using linbox.
|
|
36
|
+
|
|
37
|
+
The result is not cached contrarily to the method ``rank``.
|
|
38
|
+
|
|
39
|
+
EXAMPLES::
|
|
40
|
+
|
|
41
|
+
sage: from sage.matrix.matrix_integer_sparse_linbox import _rank_linbox
|
|
42
|
+
sage: M = MatrixSpace(ZZ, 3, sparse=True)
|
|
43
|
+
sage: m = M([1,0,1,0,2,0,2,0,2])
|
|
44
|
+
sage: _rank_linbox(m)
|
|
45
|
+
2
|
|
46
|
+
|
|
47
|
+
TESTS::
|
|
48
|
+
|
|
49
|
+
sage: _rank_linbox(MatrixSpace(ZZ, 0, 0, sparse=True)())
|
|
50
|
+
0
|
|
51
|
+
sage: _rank_linbox(MatrixSpace(ZZ, 1, 0, sparse=True)())
|
|
52
|
+
0
|
|
53
|
+
sage: _rank_linbox(MatrixSpace(ZZ, 0, 1, sparse=True)())
|
|
54
|
+
0
|
|
55
|
+
sage: _rank_linbox(MatrixSpace(ZZ, 1, 1, sparse=True)())
|
|
56
|
+
0
|
|
57
|
+
"""
|
|
58
|
+
if self._nrows == 0 or self._ncols == 0:
|
|
59
|
+
return 0
|
|
60
|
+
|
|
61
|
+
cdef givaro.ZRing givZZ
|
|
62
|
+
cdef linbox.SparseMatrix_integer * M = new_linbox_matrix_integer_sparse(givZZ, self)
|
|
63
|
+
cdef size_t r = 0
|
|
64
|
+
|
|
65
|
+
sig_on()
|
|
66
|
+
linbox.rank(r, M[0])
|
|
67
|
+
sig_off()
|
|
68
|
+
|
|
69
|
+
del M
|
|
70
|
+
|
|
71
|
+
return PyLong_FromSize_t(r)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _det_linbox(Matrix_integer_sparse self):
|
|
75
|
+
r"""
|
|
76
|
+
Return the determinant computed with LinBox.
|
|
77
|
+
|
|
78
|
+
.. NOTE::
|
|
79
|
+
|
|
80
|
+
This method is much slower than converting to a dense matrix and
|
|
81
|
+
computing the determinant there. There is not much point in making
|
|
82
|
+
it available. See :issue:`28318`.
|
|
83
|
+
|
|
84
|
+
EXAMPLES::
|
|
85
|
+
|
|
86
|
+
sage: from sage.matrix.matrix_integer_sparse_linbox import _det_linbox
|
|
87
|
+
sage: M = MatrixSpace(ZZ, 2, 2, sparse=True)
|
|
88
|
+
sage: _det_linbox(M([2,0,1,1]))
|
|
89
|
+
2
|
|
90
|
+
|
|
91
|
+
TESTS::
|
|
92
|
+
|
|
93
|
+
sage: _det_linbox(MatrixSpace(ZZ, 0, 0, sparse=True)())
|
|
94
|
+
1
|
|
95
|
+
sage: _det_linbox(MatrixSpace(ZZ, 1, 1, sparse=True)())
|
|
96
|
+
0
|
|
97
|
+
|
|
98
|
+
sage: m = diagonal_matrix(ZZ, [2] * 46)
|
|
99
|
+
sage: _det_linbox(m) == 2**46
|
|
100
|
+
True
|
|
101
|
+
|
|
102
|
+
sage: m = diagonal_matrix(ZZ, [3] * 100)
|
|
103
|
+
sage: _det_linbox(m) == 3**100
|
|
104
|
+
True
|
|
105
|
+
"""
|
|
106
|
+
if self._nrows != self._ncols:
|
|
107
|
+
raise ValueError("non square matrix")
|
|
108
|
+
|
|
109
|
+
if self._nrows == 0:
|
|
110
|
+
return Integer(1)
|
|
111
|
+
|
|
112
|
+
cdef givaro.ZRing givZZ
|
|
113
|
+
cdef linbox.SparseMatrix_integer * M = new_linbox_matrix_integer_sparse(givZZ, self)
|
|
114
|
+
cdef givaro.Integer D
|
|
115
|
+
|
|
116
|
+
sig_on()
|
|
117
|
+
linbox.det(D, M[0])
|
|
118
|
+
sig_off()
|
|
119
|
+
|
|
120
|
+
cdef Integer d = PY_NEW(Integer)
|
|
121
|
+
mpz_set(d.value, D.get_mpz_const())
|
|
122
|
+
|
|
123
|
+
del M
|
|
124
|
+
|
|
125
|
+
return d
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def _charpoly_linbox(Matrix_integer_sparse self, var='x'):
|
|
129
|
+
r"""
|
|
130
|
+
Compute the charpoly using LinBox.
|
|
131
|
+
|
|
132
|
+
EXAMPLES::
|
|
133
|
+
|
|
134
|
+
sage: from sage.matrix.matrix_integer_sparse_linbox import _charpoly_linbox
|
|
135
|
+
sage: m = matrix(ZZ, 2, [2,1,1,1], sparse=True)
|
|
136
|
+
sage: _charpoly_linbox(m)
|
|
137
|
+
x^2 - 3*x + 1
|
|
138
|
+
|
|
139
|
+
TESTS::
|
|
140
|
+
|
|
141
|
+
sage: _charpoly_linbox(matrix(ZZ, 0, 0, sparse=True))
|
|
142
|
+
1
|
|
143
|
+
sage: _charpoly_linbox(matrix(ZZ, 1, 1, sparse=True))
|
|
144
|
+
x
|
|
145
|
+
"""
|
|
146
|
+
cdef mpz_t tmp
|
|
147
|
+
if self._nrows != self._ncols:
|
|
148
|
+
raise ArithmeticError('only valid for square matrix')
|
|
149
|
+
|
|
150
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
151
|
+
R = PolynomialRing(ZZ, names=var)
|
|
152
|
+
|
|
153
|
+
# TODO: bug in LinBox (got SIGSEGV)
|
|
154
|
+
if self._nrows == 0:
|
|
155
|
+
return R.one()
|
|
156
|
+
|
|
157
|
+
cdef givaro.ZRing givZZ
|
|
158
|
+
cdef linbox.SparseMatrix_integer * M = new_linbox_matrix_integer_sparse(givZZ, self)
|
|
159
|
+
cdef linbox.DensePolynomial_integer * p = new linbox.DensePolynomial_integer(givZZ, <size_t> self._nrows)
|
|
160
|
+
cdef Polynomial_integer_dense_flint g = (<Polynomial_integer_dense_flint> R.gen())._new()
|
|
161
|
+
|
|
162
|
+
sig_on()
|
|
163
|
+
linbox.charpoly(p[0], M[0])
|
|
164
|
+
sig_off()
|
|
165
|
+
|
|
166
|
+
cdef size_t i
|
|
167
|
+
fmpz_poly_fit_length(g._poly, p.size())
|
|
168
|
+
for i in range(p.size()):
|
|
169
|
+
tmp = p[0][i].get_mpz_const()
|
|
170
|
+
fmpz_poly_set_coeff_mpz(g._poly, i, tmp)
|
|
171
|
+
_fmpz_poly_set_length(g._poly, p.size())
|
|
172
|
+
|
|
173
|
+
del M
|
|
174
|
+
del p
|
|
175
|
+
|
|
176
|
+
return g
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def _minpoly_linbox(Matrix_integer_sparse self, var='x'):
|
|
180
|
+
r"""
|
|
181
|
+
Compute the minpoly using LinBox.
|
|
182
|
+
|
|
183
|
+
EXAMPLES::
|
|
184
|
+
|
|
185
|
+
sage: from sage.matrix.matrix_integer_sparse_linbox import _minpoly_linbox
|
|
186
|
+
sage: m = matrix(ZZ, 2, [2,1,1,1], sparse=True)
|
|
187
|
+
sage: _minpoly_linbox(m)
|
|
188
|
+
x^2 - 3*x + 1
|
|
189
|
+
|
|
190
|
+
TESTS::
|
|
191
|
+
|
|
192
|
+
sage: _minpoly_linbox(matrix(ZZ, 0, 0, sparse=True))
|
|
193
|
+
1
|
|
194
|
+
sage: _minpoly_linbox(matrix(ZZ, 1, 1, sparse=True))
|
|
195
|
+
x
|
|
196
|
+
"""
|
|
197
|
+
if self._nrows != self._ncols:
|
|
198
|
+
raise ArithmeticError('only valid for square matrix')
|
|
199
|
+
|
|
200
|
+
from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
|
|
201
|
+
R = PolynomialRing(ZZ, names=var)
|
|
202
|
+
|
|
203
|
+
# TODO: bug in LinBox (got SIGSEGV)
|
|
204
|
+
if self._nrows == 0:
|
|
205
|
+
return R.one()
|
|
206
|
+
|
|
207
|
+
cdef givaro.ZRing givZZ
|
|
208
|
+
cdef linbox.SparseMatrix_integer * M = new_linbox_matrix_integer_sparse(givZZ, self)
|
|
209
|
+
cdef linbox.DensePolynomial_integer * p = new linbox.DensePolynomial_integer(givZZ, <size_t> self._nrows)
|
|
210
|
+
cdef Polynomial_integer_dense_flint g = (<Polynomial_integer_dense_flint> R.gen())._new()
|
|
211
|
+
|
|
212
|
+
sig_on()
|
|
213
|
+
linbox.minpoly(p[0], M[0])
|
|
214
|
+
sig_off()
|
|
215
|
+
|
|
216
|
+
cdef size_t i
|
|
217
|
+
cdef mpz_t tmp
|
|
218
|
+
fmpz_poly_fit_length(g._poly, p.size())
|
|
219
|
+
for i in range(p.size()):
|
|
220
|
+
tmp = p[0][i].get_mpz_const()
|
|
221
|
+
fmpz_poly_set_coeff_mpz(g._poly, i, tmp)
|
|
222
|
+
_fmpz_poly_set_length(g._poly, p.size())
|
|
223
|
+
|
|
224
|
+
del M
|
|
225
|
+
del p
|
|
226
|
+
|
|
227
|
+
return g
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
def _solve_vector_linbox(Matrix_integer_sparse self, v, algorithm=None):
|
|
231
|
+
r"""
|
|
232
|
+
Return a pair ``(a, d)`` so that ``d * b = m * a``.
|
|
233
|
+
|
|
234
|
+
If there is no solution a :exc:`ValueError` is raised.
|
|
235
|
+
|
|
236
|
+
INPUT:
|
|
237
|
+
|
|
238
|
+
- ``b`` -- dense integer vector
|
|
239
|
+
|
|
240
|
+
- ``algorithm`` -- (optional) either ``None``, ``'dense_elimination'``,
|
|
241
|
+
``'sparse_elimination'``, ``'wiedemann'`` or ``'blackbox'``
|
|
242
|
+
|
|
243
|
+
OUTPUT: a pair ``(a, d)`` consisting of
|
|
244
|
+
|
|
245
|
+
- ``a`` -- dense integer vector
|
|
246
|
+
|
|
247
|
+
- ``d`` -- integer
|
|
248
|
+
|
|
249
|
+
EXAMPLES::
|
|
250
|
+
|
|
251
|
+
sage: from sage.matrix.matrix_integer_sparse_linbox import _solve_vector_linbox
|
|
252
|
+
sage: m = matrix(ZZ, 4, sparse=True)
|
|
253
|
+
sage: m[0,0] = m[1,2] = m[2,0] = m[3,3] = 2
|
|
254
|
+
sage: m[0,2] = m[1,1] = -1
|
|
255
|
+
sage: m[2,3] = m[3,0] = -3
|
|
256
|
+
|
|
257
|
+
sage: b0 = vector((1,1,1,1))
|
|
258
|
+
sage: _solve_vector_linbox(m, b0)
|
|
259
|
+
((-1, -7, -3, -1), 1)
|
|
260
|
+
sage: _solve_vector_linbox(m, b0, 'dense_elimination')
|
|
261
|
+
((-1, -7, -3, -1), 1)
|
|
262
|
+
sage: _solve_vector_linbox(m, b0, 'sparse_elimination')
|
|
263
|
+
((-1, -7, -3, -1), 1)
|
|
264
|
+
sage: _solve_vector_linbox(m, b0, 'wiedemann')
|
|
265
|
+
((-1, -7, -3, -1), 1)
|
|
266
|
+
sage: _solve_vector_linbox(m, b0, 'blackbox')
|
|
267
|
+
((-1, -7, -3, -1), 1)
|
|
268
|
+
|
|
269
|
+
sage: b1 = vector((1,2,3,4))
|
|
270
|
+
sage: _solve_vector_linbox(m, b1)
|
|
271
|
+
((-18, -92, -41, -17), 5)
|
|
272
|
+
sage: _solve_vector_linbox(m, b1, 'dense_elimination')
|
|
273
|
+
((-18, -92, -41, -17), 5)
|
|
274
|
+
sage: _solve_vector_linbox(m, b1, 'sparse_elimination')
|
|
275
|
+
((-18, -92, -41, -17), 5)
|
|
276
|
+
sage: _solve_vector_linbox(m, b1, 'wiedemann')
|
|
277
|
+
((-18, -92, -41, -17), 5)
|
|
278
|
+
sage: _solve_vector_linbox(m, b1, 'blackbox')
|
|
279
|
+
((-18, -92, -41, -17), 5)
|
|
280
|
+
|
|
281
|
+
sage: a1, d1 = _solve_vector_linbox(m, b1)
|
|
282
|
+
sage: d1 * b1 == m * a1
|
|
283
|
+
True
|
|
284
|
+
|
|
285
|
+
TESTS::
|
|
286
|
+
|
|
287
|
+
sage: algos = ["default", "dense_elimination", "sparse_elimination",
|
|
288
|
+
....: "blackbox", "wiedemann"]
|
|
289
|
+
sage: for i in range(20):
|
|
290
|
+
....: dim = randint(1, 30)
|
|
291
|
+
....: M = MatrixSpace(ZZ, dim, sparse=True)
|
|
292
|
+
....: density = min(1, 4/dim)
|
|
293
|
+
....: m = M.random_element(density=density)
|
|
294
|
+
....: while m.rank() != dim:
|
|
295
|
+
....: m = M.random_element(density=density)
|
|
296
|
+
....: U = m.column_space().dense_module()
|
|
297
|
+
....: for algo in algos:
|
|
298
|
+
....: u, d = _solve_vector_linbox(m, U.zero(), algorithm=algo)
|
|
299
|
+
....: assert u.is_zero()
|
|
300
|
+
....: b = U.random_element()
|
|
301
|
+
....: x, d = _solve_vector_linbox(m, b, algorithm=algo)
|
|
302
|
+
....: assert m * x == d * b
|
|
303
|
+
"""
|
|
304
|
+
Vin = self.column_ambient_module(base_ring=None, sparse=False)
|
|
305
|
+
v = Vin(v)
|
|
306
|
+
|
|
307
|
+
if self._nrows == 0 or self._ncols == 0:
|
|
308
|
+
raise ValueError("not implemented for nrows=0 or ncols=0")
|
|
309
|
+
|
|
310
|
+
# LinBox "solve" is mostly broken for nonsquare or singular matrices.
|
|
311
|
+
# The conditions below could be removed once all LinBox issues has
|
|
312
|
+
# been solved.
|
|
313
|
+
if self._nrows != self._ncols or self.rank() != self._nrows:
|
|
314
|
+
raise ValueError("only available for full rank square matrices")
|
|
315
|
+
|
|
316
|
+
cdef givaro.ZRing givZZ
|
|
317
|
+
cdef linbox.SparseMatrix_integer * A = new_linbox_matrix_integer_sparse(givZZ, self)
|
|
318
|
+
cdef linbox.DenseVector_integer * b = new_linbox_vector_integer_dense(givZZ, v)
|
|
319
|
+
cdef linbox.DenseVector_integer * res = new linbox.DenseVector_integer(givZZ, <size_t> self._ncols)
|
|
320
|
+
cdef givaro.Integer D
|
|
321
|
+
|
|
322
|
+
method = get_method(algorithm)
|
|
323
|
+
|
|
324
|
+
sig_on()
|
|
325
|
+
if method == METHOD_DEFAULT:
|
|
326
|
+
linbox.solve(res[0], D, A[0], b[0])
|
|
327
|
+
elif method == METHOD_WIEDEMANN:
|
|
328
|
+
linbox.solve(res[0], D, A[0], b[0], linbox.Method.Wiedemann())
|
|
329
|
+
elif method == METHOD_DENSE_ELIMINATION:
|
|
330
|
+
linbox.solve(res[0], D, A[0], b[0], linbox.Method.DenseElimination())
|
|
331
|
+
elif method == METHOD_SPARSE_ELIMINATION:
|
|
332
|
+
linbox.solve(res[0], D, A[0], b[0], linbox.Method.SparseElimination())
|
|
333
|
+
elif method == METHOD_BLACKBOX:
|
|
334
|
+
linbox.solve(res[0], D, A[0], b[0], linbox.Method.Blackbox())
|
|
335
|
+
sig_off()
|
|
336
|
+
|
|
337
|
+
Vout = self.row_ambient_module(base_ring=None, sparse=False)
|
|
338
|
+
res_sage = new_sage_vector_integer_dense(Vout, res[0])
|
|
339
|
+
cdef Integer d = PY_NEW(Integer)
|
|
340
|
+
mpz_set(d.value, D.get_mpz_const())
|
|
341
|
+
|
|
342
|
+
del A
|
|
343
|
+
del b
|
|
344
|
+
del res
|
|
345
|
+
|
|
346
|
+
return (res_sage, d)
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
def _solve_matrix_linbox(Matrix_integer_sparse self, mat, algorithm=None):
|
|
350
|
+
r"""
|
|
351
|
+
Solve the equation ``A x = mat`` where ``A`` is this matrix.
|
|
352
|
+
|
|
353
|
+
EXAMPLES::
|
|
354
|
+
|
|
355
|
+
sage: from sage.matrix.matrix_integer_sparse_linbox import _solve_matrix_linbox
|
|
356
|
+
sage: m = matrix(ZZ, [[1,2],[1,0]], sparse=True)
|
|
357
|
+
sage: b = matrix(ZZ, 2, 4, [1,0,2,0,1,1,2,0], sparse=False)
|
|
358
|
+
sage: u, d = _solve_matrix_linbox(m, b)
|
|
359
|
+
sage: u
|
|
360
|
+
[ 1 2 2 0]
|
|
361
|
+
[ 0 -1 0 0]
|
|
362
|
+
sage: m * u == b * diagonal_matrix(d)
|
|
363
|
+
True
|
|
364
|
+
|
|
365
|
+
sage: u, d = _solve_matrix_linbox(m, [[1,3,4],[0,1,0]])
|
|
366
|
+
sage: u
|
|
367
|
+
[0 1 0]
|
|
368
|
+
[1 1 2]
|
|
369
|
+
sage: d
|
|
370
|
+
(2, 1, 1)
|
|
371
|
+
|
|
372
|
+
Test input::
|
|
373
|
+
|
|
374
|
+
sage: m = matrix(ZZ, [[1,2],[1,0]], sparse=True)
|
|
375
|
+
sage: b = matrix(ZZ, 3, 3, range(9))
|
|
376
|
+
sage: _solve_matrix_linbox(m, b)
|
|
377
|
+
Traceback (most recent call last):
|
|
378
|
+
...
|
|
379
|
+
ValueError: wrong matrix dimension
|
|
380
|
+
|
|
381
|
+
sage: _solve_matrix_linbox(m, [[1,1],[2,3]], algorithm='hop')
|
|
382
|
+
Traceback (most recent call last):
|
|
383
|
+
...
|
|
384
|
+
ValueError: unknown algorithm
|
|
385
|
+
|
|
386
|
+
TESTS::
|
|
387
|
+
|
|
388
|
+
sage: algos = ["default", "dense_elimination", "sparse_elimination",
|
|
389
|
+
....: "blackbox", "wiedemann"]
|
|
390
|
+
|
|
391
|
+
sage: for _ in range(10):
|
|
392
|
+
....: dim = randint(2, 10)
|
|
393
|
+
....: M = MatrixSpace(ZZ, dim, sparse=True)
|
|
394
|
+
....: m = M.random_element(density=min(1,10/dim))
|
|
395
|
+
....: while m.rank() != dim:
|
|
396
|
+
....: m = M.random_element(density=min(1,10/dim))
|
|
397
|
+
....: b = random_matrix(ZZ, dim, 7)
|
|
398
|
+
....: Mb = b.parent()
|
|
399
|
+
....: for algo in algos:
|
|
400
|
+
....: u, d = _solve_matrix_linbox(m, b, algo)
|
|
401
|
+
....: assert m * u == b * diagonal_matrix(d)
|
|
402
|
+
"""
|
|
403
|
+
if self._nrows == 0 or self._ncols == 0:
|
|
404
|
+
raise ValueError("not implemented for nrows=0 or ncols=0")
|
|
405
|
+
|
|
406
|
+
from sage.matrix.constructor import matrix
|
|
407
|
+
from sage.modules.free_module_element import vector
|
|
408
|
+
|
|
409
|
+
cdef Matrix_integer_dense B
|
|
410
|
+
if not isinstance(mat, Matrix):
|
|
411
|
+
B = <Matrix_integer_dense?> matrix(ZZ, mat, sparse=False)
|
|
412
|
+
else:
|
|
413
|
+
B = <Matrix_integer_dense?> mat.change_ring(ZZ).dense_matrix()
|
|
414
|
+
if B._nrows != self._nrows:
|
|
415
|
+
raise ValueError("wrong matrix dimension")
|
|
416
|
+
|
|
417
|
+
# LinBox "solve" is mostly broken for singular matrices. The
|
|
418
|
+
# conditions below could be removed once all LinBox issues
|
|
419
|
+
# have been solved.
|
|
420
|
+
if self._nrows != self._ncols or self.rank() != self._nrows:
|
|
421
|
+
raise ValueError("only available for full rank square matrices")
|
|
422
|
+
|
|
423
|
+
cdef givaro.ZRing givZZ
|
|
424
|
+
cdef linbox.SparseMatrix_integer * A = new_linbox_matrix_integer_sparse(givZZ, self)
|
|
425
|
+
cdef linbox.DenseVector_integer * b = new linbox.DenseVector_integer(givZZ, <size_t> self._nrows)
|
|
426
|
+
cdef linbox.DenseVector_integer * res = new linbox.DenseVector_integer(givZZ, <size_t> self._ncols)
|
|
427
|
+
cdef givaro.Integer D
|
|
428
|
+
|
|
429
|
+
cdef int algo = get_method(algorithm)
|
|
430
|
+
|
|
431
|
+
cdef Matrix_integer_dense X = matrix(ZZ, A.coldim(), B.ncols(), sparse=False) # solution
|
|
432
|
+
cdef Vector_integer_dense d = vector(ZZ, X.ncols(), sparse=False) # multipliers
|
|
433
|
+
|
|
434
|
+
sig_on()
|
|
435
|
+
cdef size_t i, j
|
|
436
|
+
for i in range(X.ncols()):
|
|
437
|
+
# set b to the i-th column of B
|
|
438
|
+
for j in range(A.coldim()):
|
|
439
|
+
fmpz_get_mpz(<mpz_t> b.getEntry(j).get_mpz(), fmpz_mat_entry(B._matrix, j, i))
|
|
440
|
+
|
|
441
|
+
# solve the current row
|
|
442
|
+
if algo == METHOD_DEFAULT:
|
|
443
|
+
linbox.solve(res[0], D, A[0], b[0])
|
|
444
|
+
elif algo == METHOD_DENSE_ELIMINATION:
|
|
445
|
+
linbox.solve(res[0], D, A[0], b[0], linbox.Method.DenseElimination())
|
|
446
|
+
elif algo == METHOD_SPARSE_ELIMINATION:
|
|
447
|
+
linbox.solve(res[0], D, A[0], b[0], linbox.Method.SparseElimination())
|
|
448
|
+
elif algo == METHOD_BLACKBOX:
|
|
449
|
+
linbox.solve(res[0], D, A[0], b[0], linbox.Method.Blackbox())
|
|
450
|
+
elif algo == METHOD_WIEDEMANN:
|
|
451
|
+
linbox.solve(res[0], D, A[0], b[0], linbox.Method.Wiedemann())
|
|
452
|
+
|
|
453
|
+
# set i-th column of X to be res
|
|
454
|
+
for j in range(A.coldim()):
|
|
455
|
+
fmpz_set_mpz(fmpz_mat_entry(X._matrix, j, i), res[0].getEntry(j).get_mpz())
|
|
456
|
+
|
|
457
|
+
# compute common gcd
|
|
458
|
+
mpz_set(d._entries[i], D.get_mpz_const())
|
|
459
|
+
sig_off()
|
|
460
|
+
|
|
461
|
+
del A
|
|
462
|
+
del b
|
|
463
|
+
del res
|
|
464
|
+
|
|
465
|
+
return X, d
|
|
Binary file
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-linbox
|
|
2
|
+
from sage.matrix.matrix_dense cimport Matrix_dense
|
|
3
|
+
from sage.libs.m4ri cimport *
|
|
4
|
+
|
|
5
|
+
cdef class Matrix_mod2_dense(Matrix_dense):
|
|
6
|
+
cdef mzd_t *_entries
|
|
7
|
+
cdef object _one
|
|
8
|
+
cdef object _zero
|
|
9
|
+
|
|
10
|
+
cpdef Matrix_mod2_dense _multiply_m4rm(Matrix_mod2_dense self, Matrix_mod2_dense right, int k)
|
|
11
|
+
cpdef Matrix_mod2_dense _multiply_strassen(Matrix_mod2_dense self, Matrix_mod2_dense right, int cutoff)
|
|
12
|
+
|
|
13
|
+
# For conversion to other systems
|
|
14
|
+
cpdef _export_as_string(self)
|