passagemath-linbox 10.6.43__cp313-cp313-macosx_13_0_arm64.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.
Files changed (75) hide show
  1. passagemath_linbox/.dylibs/libfflas.1.dylib +0 -0
  2. passagemath_linbox/.dylibs/libffpack.1.dylib +0 -0
  3. passagemath_linbox/.dylibs/libflint.22.0.dylib +0 -0
  4. passagemath_linbox/.dylibs/libgd.3.dylib +0 -0
  5. passagemath_linbox/.dylibs/libgfortran.5.dylib +0 -0
  6. passagemath_linbox/.dylibs/libgivaro.9.dylib +0 -0
  7. passagemath_linbox/.dylibs/libgmp.10.dylib +0 -0
  8. passagemath_linbox/.dylibs/libgmpxx.4.dylib +0 -0
  9. passagemath_linbox/.dylibs/libiml.0.dylib +0 -0
  10. passagemath_linbox/.dylibs/liblinbox.0.dylib +0 -0
  11. passagemath_linbox/.dylibs/libm4ri.1.dylib +0 -0
  12. passagemath_linbox/.dylibs/libm4rie.1.dylib +0 -0
  13. passagemath_linbox/.dylibs/libmpfr.6.dylib +0 -0
  14. passagemath_linbox/.dylibs/libopenblasp-r0.3.29.dylib +0 -0
  15. passagemath_linbox/.dylibs/libpng16.16.dylib +0 -0
  16. passagemath_linbox/.dylibs/libquadmath.0.dylib +0 -0
  17. passagemath_linbox/.dylibs/libz.1.3.1.dylib +0 -0
  18. passagemath_linbox/__init__.py +3 -0
  19. passagemath_linbox-10.6.43.dist-info/METADATA +100 -0
  20. passagemath_linbox-10.6.43.dist-info/RECORD +75 -0
  21. passagemath_linbox-10.6.43.dist-info/WHEEL +6 -0
  22. passagemath_linbox-10.6.43.dist-info/top_level.txt +3 -0
  23. sage/all__sagemath_linbox.py +2 -0
  24. sage/geometry/all__sagemath_linbox.py +1 -0
  25. sage/geometry/integral_points.pxi +1426 -0
  26. sage/geometry/integral_points_integer_dense.cpython-313-darwin.so +0 -0
  27. sage/geometry/integral_points_integer_dense.pyx +7 -0
  28. sage/libs/all__sagemath_linbox.py +1 -0
  29. sage/libs/iml.pxd +10 -0
  30. sage/libs/linbox/__init__.py +1 -0
  31. sage/libs/linbox/conversion.pxd +185 -0
  32. sage/libs/linbox/fflas.pxd +189 -0
  33. sage/libs/linbox/givaro.pxd +109 -0
  34. sage/libs/linbox/linbox.pxd +219 -0
  35. sage/libs/linbox/linbox_flint_interface.cpython-313-darwin.so +0 -0
  36. sage/libs/linbox/linbox_flint_interface.pxd +18 -0
  37. sage/libs/linbox/linbox_flint_interface.pyx +192 -0
  38. sage/libs/m4ri.pxd +198 -0
  39. sage/libs/m4rie.pxd +204 -0
  40. sage/matrix/all__sagemath_linbox.py +1 -0
  41. sage/matrix/matrix_cyclo_linbox.cpython-313-darwin.so +0 -0
  42. sage/matrix/matrix_cyclo_linbox.pyx +361 -0
  43. sage/matrix/matrix_gf2e_dense.cpython-313-darwin.so +0 -0
  44. sage/matrix/matrix_gf2e_dense.pxd +15 -0
  45. sage/matrix/matrix_gf2e_dense.pyx +1573 -0
  46. sage/matrix/matrix_integer_iml.cpython-313-darwin.so +0 -0
  47. sage/matrix/matrix_integer_iml.pyx +316 -0
  48. sage/matrix/matrix_integer_linbox.cpython-313-darwin.so +0 -0
  49. sage/matrix/matrix_integer_linbox.pxd +5 -0
  50. sage/matrix/matrix_integer_linbox.pyx +358 -0
  51. sage/matrix/matrix_integer_sparse_linbox.cpython-313-darwin.so +0 -0
  52. sage/matrix/matrix_integer_sparse_linbox.pyx +465 -0
  53. sage/matrix/matrix_mod2_dense.cpython-313-darwin.so +0 -0
  54. sage/matrix/matrix_mod2_dense.pxd +14 -0
  55. sage/matrix/matrix_mod2_dense.pyx +2789 -0
  56. sage/matrix/matrix_modn_dense_double.cpython-313-darwin.so +0 -0
  57. sage/matrix/matrix_modn_dense_double.pyx +179 -0
  58. sage/matrix/matrix_modn_dense_float.cpython-313-darwin.so +0 -0
  59. sage/matrix/matrix_modn_dense_float.pyx +154 -0
  60. sage/matrix/matrix_modn_sparse.cpython-313-darwin.so +0 -0
  61. sage/matrix/matrix_modn_sparse.pyx +871 -0
  62. sage/matrix/matrix_rational_linbox.cpython-313-darwin.so +0 -0
  63. sage/matrix/matrix_rational_linbox.pyx +36 -0
  64. sage/matrix/misc.cpython-313-darwin.so +0 -0
  65. sage/matrix/misc.pyx +418 -0
  66. sage/modules/all__sagemath_linbox.py +1 -0
  67. sage/modules/numpy_util.cpython-313-darwin.so +0 -0
  68. sage/modules/numpy_util.pxd +10 -0
  69. sage/modules/numpy_util.pyx +136 -0
  70. sage/modules/vector_mod2_dense.cpython-313-darwin.so +0 -0
  71. sage/modules/vector_mod2_dense.pxd +11 -0
  72. sage/modules/vector_mod2_dense.pyx +547 -0
  73. sage/rings/all__sagemath_linbox.py +1 -0
  74. sage/rings/finite_rings/all__sagemath_linbox.py +1 -0
  75. sage/rings/polynomial/all__sagemath_linbox.py +1 -0
@@ -0,0 +1,316 @@
1
+ # sage_setup: distribution = sagemath-linbox
2
+ # distutils: libraries = iml
3
+ # sage.doctest: needs sage.libs.flint sage.libs.linbox
4
+
5
+ from cysignals.signals cimport sig_check, sig_on, sig_str, sig_off
6
+ from cysignals.memory cimport sig_malloc, sig_free, check_allocarray
7
+
8
+ from sage.libs.flint.fmpz cimport *
9
+ from sage.libs.flint.fmpz_mat cimport *
10
+ from sage.libs.gmp.mpz cimport *
11
+ from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense
12
+ from sage.misc.verbose import verbose
13
+ from sage.rings.integer cimport Integer
14
+
15
+
16
+ ########## iml -- integer matrix library ###########
17
+ from sage.libs.iml cimport *
18
+
19
+
20
+ def _rational_kernel_iml(Matrix_integer_dense self):
21
+ """
22
+ Return the rational (left) kernel of this matrix.
23
+
24
+ OUTPUT:
25
+
26
+ A matrix ``K`` such that ``self * K = 0``, and the number of columns of
27
+ K equals the nullity of ``self``.
28
+
29
+ EXAMPLES::
30
+
31
+ sage: from sage.matrix.matrix_integer_iml import _rational_kernel_iml
32
+ sage: m = matrix(ZZ, 5, 5, [1+i+i^2 for i in range(25)])
33
+ sage: _rational_kernel_iml(m)
34
+ [ 1 3]
35
+ [-3 -8]
36
+ [ 3 6]
37
+ [-1 0]
38
+ [ 0 -1]
39
+
40
+ sage: V1 = _rational_kernel_iml(m).column_space().change_ring(QQ)
41
+ sage: V2 = m._rational_kernel_flint().column_space().change_ring(QQ)
42
+ sage: assert V1 == V2
43
+ """
44
+ if self._nrows == 0 or self._ncols == 0:
45
+ return self.matrix_space(self._ncols, 0).zero_matrix()
46
+
47
+ cdef long dim
48
+ cdef unsigned long i,j,k
49
+ cdef mpz_t *mp_N
50
+ time = verbose('computing null space of %s x %s matrix using IML' % (self._nrows, self._ncols))
51
+ cdef mpz_t * m = fmpz_mat_to_mpz_array(self._matrix)
52
+ sig_on()
53
+ dim = nullspaceMP(self._nrows, self._ncols, m, &mp_N)
54
+ sig_off()
55
+ # Now read the answer as a matrix.
56
+ cdef Matrix_integer_dense M
57
+ M = self._new(self._ncols, dim)
58
+ k = 0
59
+ for i in range(self._ncols):
60
+ for j in range(dim):
61
+ fmpz_set_mpz(fmpz_mat_entry(M._matrix, i, j), mp_N[k])
62
+ k += 1
63
+ mpz_array_clear(m, self._nrows * self._ncols)
64
+ mpz_array_clear(mp_N, dim * self._ncols)
65
+ verbose("finished computing null space", time)
66
+ return M
67
+
68
+
69
+ def _invert_iml(Matrix_integer_dense self, use_nullspace=False, check_invertible=True):
70
+ """
71
+ Invert this matrix using IML. The output matrix is an integer
72
+ matrix and a denominator.
73
+
74
+ INPUT:
75
+
76
+ - ``self`` -- an invertible matrix
77
+
78
+ - ``use_nullspace`` -- boolean (default: ``False``); whether to
79
+ use nullspace algorithm, which is slower, but doesn't require
80
+ checking that the matrix is invertible as a precondition
81
+
82
+ - ``check_invertible`` -- boolean (default: ``True``); whether to
83
+ check that the matrix is invertible
84
+
85
+ OUTPUT: `A`, `d` such that ``A*self == d``
86
+
87
+ - ``A`` -- a matrix over ZZ
88
+
89
+ - ``d`` -- integer
90
+
91
+ ALGORITHM: Uses IML's `p`-adic nullspace function.
92
+
93
+ EXAMPLES::
94
+
95
+ sage: from sage.matrix.matrix_integer_iml import _invert_iml
96
+ sage: a = matrix(ZZ,3,[1,2,5, 3,7,8, 2,2,1])
97
+ sage: b, d = _invert_iml(a); b,d
98
+ (
99
+ [ 9 -8 19]
100
+ [-13 9 -7]
101
+ [ 8 -2 -1], 23
102
+ )
103
+ sage: a*b
104
+ [23 0 0]
105
+ [ 0 23 0]
106
+ [ 0 0 23]
107
+
108
+ AUTHORS:
109
+
110
+ - William Stein
111
+ """
112
+ if self._nrows != self._ncols:
113
+ raise TypeError("self must be a square matrix.")
114
+
115
+ P = self.parent()
116
+ time = verbose('computing inverse of %s x %s matrix using IML' % (self._nrows, self._ncols))
117
+ if use_nullspace:
118
+ A = self.augment(P.identity_matrix())
119
+ K = A._rational_kernel_iml()
120
+ d = -K[self._nrows,0]
121
+ if K.ncols() != self._ncols or d == 0:
122
+ raise ZeroDivisionError("input matrix must be nonsingular")
123
+ B = K[:self._nrows]
124
+ verbose("finished computing inverse using IML", time)
125
+ return B, d
126
+ else:
127
+ if check_invertible and self.rank() != self._nrows:
128
+ raise ZeroDivisionError("input matrix must be nonsingular")
129
+ return _solve_iml(self, P.identity_matrix(), right=True)
130
+
131
+
132
+ def _solve_iml(Matrix_integer_dense self, Matrix_integer_dense B, right=True):
133
+ """
134
+ Let A equal ``self`` be a square matrix. Given B return an integer
135
+ matrix C and an integer d such that ``self`` ``C*A == d*B`` if right is
136
+ False or ``A*C == d*B`` if right is True.
137
+
138
+ OUTPUT:
139
+
140
+ - ``C`` -- integer matrix
141
+
142
+ - ``d`` -- integer denominator
143
+
144
+ EXAMPLES::
145
+
146
+ sage: from sage.matrix.matrix_integer_iml import _solve_iml
147
+ sage: A = matrix(ZZ,4,4,[0, 1, -2, -1, -1, 1, 0, 2, 2, 2, 2, -1, 0, 2, 2, 1])
148
+ sage: B = matrix(ZZ,3,4, [-1, 1, 1, 0, 2, 0, -2, -1, 0, -2, -2, -2])
149
+ sage: C, d = _solve_iml(A, B, right=False); C
150
+ [ 6 -18 -15 27]
151
+ [ 0 24 24 -36]
152
+ [ 4 -12 -6 -2]
153
+
154
+ ::
155
+
156
+ sage: d
157
+ 12
158
+
159
+ ::
160
+
161
+ sage: C*A == d*B
162
+ True
163
+
164
+ ::
165
+
166
+ sage: A = matrix(ZZ,4,4,[0, 1, -2, -1, -1, 1, 0, 2, 2, 2, 2, -1, 0, 2, 2, 1])
167
+ sage: B = matrix(ZZ,4,3, [-1, 1, 1, 0, 2, 0, -2, -1, 0, -2, -2, -2])
168
+ sage: C, d = _solve_iml(A, B)
169
+ sage: C
170
+ [ 12 40 28]
171
+ [-12 -4 -4]
172
+ [ -6 -25 -16]
173
+ [ 12 34 16]
174
+
175
+ ::
176
+
177
+ sage: d
178
+ 12
179
+
180
+ ::
181
+
182
+ sage: A*C == d*B
183
+ True
184
+
185
+ Test wrong dimensions::
186
+
187
+ sage: A = random_matrix(ZZ, 4, 4)
188
+ sage: B = random_matrix(ZZ, 2, 3)
189
+ sage: _solve_iml(B, A)
190
+ Traceback (most recent call last):
191
+ ...
192
+ ValueError: self must be a square matrix
193
+ sage: _solve_iml(A, B, right=False)
194
+ Traceback (most recent call last):
195
+ ...
196
+ ArithmeticError: B's number of columns must match self's number of rows
197
+ sage: _solve_iml(A, B, right=True)
198
+ Traceback (most recent call last):
199
+ ...
200
+ ArithmeticError: B's number of rows must match self's number of columns
201
+
202
+ Check that this can be interrupted properly (:issue:`15453`)::
203
+
204
+ sage: A = random_matrix(ZZ, 2000, 2000)
205
+ sage: B = random_matrix(ZZ, 2000, 2000)
206
+ sage: t0 = walltime()
207
+ sage: alarm(2); _solve_iml(A, B) # long time
208
+ Traceback (most recent call last):
209
+ ...
210
+ AlarmInterrupt
211
+ sage: t = walltime(t0)
212
+ sage: t < 10 or t
213
+ True
214
+
215
+ ALGORITHM: Uses IML.
216
+
217
+ AUTHORS:
218
+
219
+ - Martin Albrecht
220
+ """
221
+ cdef unsigned long i, j, k
222
+ cdef mpz_t *mp_N
223
+ cdef mpz_t mp_D
224
+ cdef Matrix_integer_dense M
225
+ cdef Integer D
226
+
227
+ if self._nrows != self._ncols:
228
+ # This is *required* by the IML function we call below.
229
+ raise ValueError("self must be a square matrix")
230
+
231
+ if self._nrows == 1:
232
+ return B, self[0,0]
233
+
234
+ cdef SOLU_POS solu_pos
235
+
236
+ if right:
237
+ if self._ncols != B._nrows:
238
+ raise ArithmeticError("B's number of rows must match self's number of columns")
239
+
240
+ n = self._ncols
241
+ m = B._ncols
242
+
243
+ P = self.matrix_space(n, m)
244
+ if self._nrows == 0 or self._ncols == 0:
245
+ return P.zero_matrix(), Integer(1)
246
+
247
+ if m == 0 or n == 0:
248
+ return self.new_matrix(nrows = n, ncols = m), Integer(1)
249
+
250
+ solu_pos = RightSolu
251
+
252
+ else: # left
253
+ if self._nrows != B._ncols:
254
+ raise ArithmeticError("B's number of columns must match self's number of rows")
255
+
256
+ n = self._ncols
257
+ m = B._nrows
258
+
259
+ P = self.matrix_space(m, n)
260
+ if self._nrows == 0 or self._ncols == 0:
261
+ return P.zero_matrix(), Integer(1)
262
+
263
+ if m == 0 or n == 0:
264
+ return self.new_matrix(nrows = m, ncols = n), Integer(1)
265
+
266
+ solu_pos = LeftSolu
267
+
268
+ sig_check()
269
+ verbose("Initializing mp_N and mp_D")
270
+ mp_N = <mpz_t *> sig_malloc( n * m * sizeof(mpz_t) )
271
+ for i in range(n * m):
272
+ mpz_init(mp_N[i])
273
+ mpz_init(mp_D)
274
+ verbose("Done with initializing mp_N and mp_D")
275
+ cdef mpz_t * mself = fmpz_mat_to_mpz_array(self._matrix)
276
+ cdef mpz_t * mB = fmpz_mat_to_mpz_array(B._matrix)
277
+ try:
278
+ verbose('Calling solver n = %s, m = %s' % (n,m))
279
+ sig_on()
280
+ nonsingSolvLlhsMM(solu_pos, n, m, mself, mB, mp_N, mp_D)
281
+ sig_off()
282
+ M = self._new(P.nrows(), P.ncols())
283
+ k = 0
284
+ for i from 0 <= i < M._nrows:
285
+ for j from 0 <= j < M._ncols:
286
+ fmpz_set_mpz(fmpz_mat_entry(M._matrix,i,j), mp_N[k])
287
+ k += 1
288
+ D = Integer.__new__(Integer)
289
+ mpz_set(D.value, mp_D)
290
+ return M, D
291
+ finally:
292
+ mpz_clear(mp_D)
293
+ mpz_array_clear(mself, self.nrows() * self.ncols())
294
+ mpz_array_clear(mB, B.nrows() * B.ncols())
295
+ mpz_array_clear(mp_N, n*m)
296
+
297
+
298
+ cdef inline mpz_t * fmpz_mat_to_mpz_array(fmpz_mat_t m) except? NULL:
299
+ cdef mpz_t * entries = <mpz_t *>check_allocarray(fmpz_mat_nrows(m), sizeof(mpz_t) * fmpz_mat_ncols(m))
300
+ cdef size_t i, j
301
+ cdef size_t k = 0
302
+ sig_on()
303
+ for i in range(fmpz_mat_nrows(m)):
304
+ for j in range(fmpz_mat_ncols(m)):
305
+ mpz_init(entries[k])
306
+ fmpz_get_mpz(entries[k], fmpz_mat_entry(m, i, j))
307
+ k += 1
308
+ sig_off()
309
+ return entries
310
+
311
+
312
+ cdef inline void mpz_array_clear(mpz_t * a, size_t length) noexcept:
313
+ cdef size_t i
314
+ for i in range(length):
315
+ mpz_clear(a[i])
316
+ sig_free(a)
@@ -0,0 +1,5 @@
1
+ # sage_setup: distribution = sagemath-linbox
2
+
3
+ from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense
4
+
5
+ cpdef _lift_crt(Matrix_integer_dense M, residues, moduli=*)
@@ -0,0 +1,358 @@
1
+ # sage_setup: distribution = sagemath-linbox
2
+ # sage.doctest: needs sage.libs.flint sage.libs.linbox
3
+
4
+ from cysignals.signals cimport sig_check, sig_on, sig_str, sig_off
5
+ from cysignals.memory cimport sig_malloc, sig_free, check_allocarray
6
+
7
+ import sage.matrix.matrix_space as matrix_space
8
+
9
+ from sage.arith.multi_modular cimport MultiModularBasis
10
+ from sage.ext.mod_int cimport *
11
+ from sage.ext.stdsage cimport PY_NEW
12
+ from sage.libs.flint.fmpz cimport *
13
+ from sage.libs.flint.fmpz_mat cimport *
14
+ from sage.libs.gmp.mpz cimport *
15
+ from sage.matrix.matrix_integer_dense cimport Matrix_integer_dense
16
+ from sage.matrix.matrix_modn_dense_float cimport Matrix_modn_dense_template
17
+ from sage.matrix.matrix_modn_dense_float cimport Matrix_modn_dense_float
18
+ from sage.matrix.matrix_modn_dense_double cimport Matrix_modn_dense_double
19
+ from sage.misc.timing import cputime
20
+ from sage.misc.verbose import verbose
21
+ from sage.rings.finite_rings.integer_mod_ring import IntegerModRing
22
+ from sage.rings.integer cimport Integer
23
+ from sage.rings.integer_ring import ZZ
24
+ from sage.rings.polynomial.polynomial_integer_dense_flint cimport Polynomial_integer_dense_flint
25
+ from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing
26
+
27
+ ######### linbox interface ##########
28
+ from sage.libs.linbox.linbox_flint_interface cimport *
29
+
30
+
31
+ def _multiply_linbox(Matrix_integer_dense self, Matrix_integer_dense right):
32
+ """
33
+ Multiply matrices over ZZ using linbox.
34
+
35
+ .. WARNING::
36
+
37
+ This is very slow right now, i.e., linbox is very slow.
38
+
39
+ EXAMPLES::
40
+
41
+ sage: from sage.matrix.matrix_integer_linbox import _multiply_linbox
42
+ sage: A = matrix(ZZ, 2, 3, range(6))
43
+ sage: A * A.transpose()
44
+ [ 5 14]
45
+ [14 50]
46
+ sage: _multiply_linbox(A, A.transpose())
47
+ [ 5 14]
48
+ [14 50]
49
+
50
+ TESTS:
51
+
52
+ This fixes a bug found in :issue:`17094`::
53
+
54
+ sage: A = identity_matrix(ZZ, 3)
55
+ sage: _multiply_linbox(A, A)
56
+ [1 0 0]
57
+ [0 1 0]
58
+ [0 0 1]
59
+ """
60
+ cdef Matrix_integer_dense ans
61
+ cdef Matrix_integer_dense left = <Matrix_integer_dense> self
62
+
63
+ ans = self._new(left._nrows, right._ncols)
64
+
65
+ sig_on()
66
+ linbox_fmpz_mat_mul(ans._matrix, left._matrix, right._matrix)
67
+ sig_off()
68
+
69
+ return ans
70
+
71
+
72
+ def _charpoly_linbox(Matrix_integer_dense self, var):
73
+ g = (<Polynomial_integer_dense_flint> PolynomialRing(ZZ, names=var).gen())._new()
74
+ sig_on()
75
+ linbox_fmpz_mat_charpoly(g._poly, self._matrix)
76
+ sig_off()
77
+ return g
78
+
79
+
80
+ def _minpoly_linbox(Matrix_integer_dense self, var):
81
+ g = (<Polynomial_integer_dense_flint> PolynomialRing(ZZ, names=var).gen())._new()
82
+ sig_on()
83
+ linbox_fmpz_mat_minpoly(g._poly, self._matrix)
84
+ sig_off()
85
+ return g
86
+
87
+
88
+ def _rank_linbox(Matrix_integer_dense self):
89
+ """
90
+ Compute the rank of this matrix using Linbox.
91
+
92
+ TESTS::
93
+
94
+ sage: from sage.matrix.matrix_integer_linbox import _rank_linbox
95
+ sage: _rank_linbox(matrix(ZZ, 4, 6, 0))
96
+ 0
97
+ sage: _rank_linbox(matrix(ZZ, 3, 4, range(12)))
98
+ 2
99
+ sage: _rank_linbox(matrix(ZZ, 5, 10, [1+i+i^2 for i in range(50)]))
100
+ 3
101
+ """
102
+ sig_on()
103
+ cdef size_t r = linbox_fmpz_mat_rank(self._matrix)
104
+ sig_off()
105
+ return Integer(r)
106
+
107
+
108
+ def _det_linbox(Matrix_integer_dense self):
109
+ """
110
+ Compute the determinant of this matrix using Linbox.
111
+
112
+ TESTS::
113
+
114
+ sage: from sage.matrix.matrix_integer_linbox import _det_linbox
115
+ sage: _det_linbox(matrix(ZZ, 0))
116
+ 1
117
+ """
118
+ if self._nrows != self._ncols:
119
+ raise ArithmeticError("self must be a square matrix")
120
+ if self._nrows == 0:
121
+ return ZZ.one()
122
+
123
+ cdef fmpz_t tmp
124
+ fmpz_init(tmp)
125
+ sig_on()
126
+ linbox_fmpz_mat_det(tmp, self._matrix)
127
+ sig_off()
128
+
129
+ cdef Integer ans = PY_NEW(Integer)
130
+ fmpz_get_mpz(ans.value, tmp)
131
+ fmpz_clear(tmp)
132
+ return ans
133
+
134
+
135
+ def _Matrix_modn_dense_float(Matrix_integer_dense self, mod_int p):
136
+ cdef Py_ssize_t i, j
137
+
138
+ cdef float* res_row_f
139
+ cdef Matrix_modn_dense_float res_f
140
+
141
+ res_f = Matrix_modn_dense_float.__new__(Matrix_modn_dense_float,
142
+ matrix_space.MatrixSpace(IntegerModRing(p), self._nrows, self._ncols, sparse=False), None, None, None, zeroed_alloc=False)
143
+ for i from 0 <= i < self._nrows:
144
+ res_row_f = res_f._matrix[i]
145
+ for j from 0 <= j < self._ncols:
146
+ res_row_f[j] = <float>fmpz_fdiv_ui(fmpz_mat_entry(self._matrix,i,j), p)
147
+ return res_f
148
+
149
+
150
+ def _Matrix_modn_dense_double(Matrix_integer_dense self, mod_int p):
151
+ cdef Py_ssize_t i, j
152
+
153
+ cdef double* res_row_d
154
+ cdef Matrix_modn_dense_double res_d
155
+
156
+ res_d = Matrix_modn_dense_double.__new__(Matrix_modn_dense_double,
157
+ matrix_space.MatrixSpace(IntegerModRing(p), self._nrows, self._ncols, sparse=False), None, None, None, zeroed_alloc=False)
158
+ for i from 0 <= i < self._nrows:
159
+ res_row_d = res_d._matrix[i]
160
+ for j from 0 <= j < self._ncols:
161
+ res_row_d[j] = <double>fmpz_fdiv_ui(fmpz_mat_entry(self._matrix,i,j), p)
162
+ return res_d
163
+
164
+
165
+ def _multiply_multi_modular(Matrix_integer_dense self, Matrix_integer_dense right):
166
+ """
167
+ Multiply this matrix by ``left`` using a multi modular algorithm.
168
+
169
+ EXAMPLES::
170
+
171
+ sage: M = Matrix(ZZ, 2, 3, range(5,11))
172
+ sage: N = Matrix(ZZ, 3, 2, range(15,21))
173
+ sage: M._multiply_multi_modular(N)
174
+ [310 328]
175
+ [463 490]
176
+ sage: M._multiply_multi_modular(-N)
177
+ [-310 -328]
178
+ [-463 -490]
179
+ """
180
+ cdef Integer h
181
+ cdef Matrix_integer_dense left = <Matrix_integer_dense>self
182
+ cdef Py_ssize_t i, k
183
+
184
+ nr = left._nrows
185
+ nc = right._ncols
186
+
187
+ cdef Matrix_integer_dense result
188
+
189
+ h = left.height() * right.height() * left.ncols()
190
+ verbose('multiplying matrices of height %s and %s' % (left.height(),
191
+ right.height()))
192
+ mm = MultiModularBasis(h)
193
+ res = left._reduce(mm)
194
+ res_right = right._reduce(mm)
195
+ k = len(mm)
196
+ for i in range(k): # yes, I could do this with zip, but to conserve memory...
197
+ t = cputime()
198
+ res[i] *= res_right[i]
199
+ verbose('multiplied matrices modulo a prime (%s/%s)' % (i+1, k), t)
200
+ result = left.new_matrix(nr,nc)
201
+ _lift_crt(result, res, mm) # changes result
202
+ return result
203
+
204
+
205
+ def _reduce(Matrix_integer_dense self, moduli):
206
+ from sage.matrix.matrix_modn_dense_float import MAX_MODULUS as MAX_MODULUS_FLOAT
207
+ from sage.matrix.matrix_modn_dense_double import MAX_MODULUS as MAX_MODULUS_DOUBLE
208
+
209
+ if isinstance(moduli, (int, Integer)):
210
+ return self._mod_int(moduli)
211
+ elif isinstance(moduli, list):
212
+ moduli = MultiModularBasis(moduli)
213
+
214
+ cdef MultiModularBasis mm
215
+ mm = moduli
216
+
217
+ res = []
218
+ for p in mm:
219
+ if p < MAX_MODULUS_FLOAT:
220
+ res.append( Matrix_modn_dense_float.__new__(Matrix_modn_dense_float,
221
+ matrix_space.MatrixSpace(IntegerModRing(p), self._nrows, self._ncols, sparse=False),
222
+ None, None, None, zeroed_alloc=False) )
223
+ elif p < MAX_MODULUS_DOUBLE:
224
+ res.append( Matrix_modn_dense_double.__new__(Matrix_modn_dense_double,
225
+ matrix_space.MatrixSpace(IntegerModRing(p), self._nrows, self._ncols, sparse=False),
226
+ None, None, None, zeroed_alloc=False) )
227
+ else:
228
+ raise ValueError("p=%d too big." % p)
229
+
230
+ cdef size_t i, k, n
231
+ cdef Py_ssize_t nr, nc
232
+ cdef mpz_t tmp
233
+ mpz_init(tmp)
234
+ n = len(mm)
235
+ nr = self._nrows
236
+ nc = self._ncols
237
+
238
+ cdef mod_int *entry_list
239
+ entry_list = <mod_int*>sig_malloc(sizeof(mod_int) * n)
240
+ if entry_list == NULL:
241
+ raise MemoryError("out of memory allocating multi-modular coefficient list")
242
+
243
+ sig_on()
244
+ for i from 0 <= i < nr:
245
+ for j from 0 <= j < nc:
246
+ self.get_unsafe_mpz(i,j,tmp)
247
+ mm.mpz_reduce(tmp, entry_list)
248
+ for k from 0 <= k < n:
249
+ if isinstance(res[k], Matrix_modn_dense_float):
250
+ (<Matrix_modn_dense_float>res[k])._matrix[i][j] = (<float>entry_list[k]) % (<Matrix_modn_dense_float>res[k]).p
251
+ else:
252
+ (<Matrix_modn_dense_double>res[k])._matrix[i][j] = (<double>entry_list[k]) % (<Matrix_modn_dense_double>res[k]).p
253
+ sig_off()
254
+ mpz_clear(tmp)
255
+ sig_free(entry_list)
256
+ return res
257
+
258
+
259
+ cpdef _lift_crt(Matrix_integer_dense M, residues, moduli=None):
260
+ """
261
+ INPUT:
262
+
263
+ - ``M`` -- a ``Matrix_integer_dense``; will be modified to hold
264
+ the output
265
+
266
+ - ``residues`` -- list of ``Matrix_modn_dense_template``; the
267
+ matrix to reconstruct modulo primes
268
+
269
+ OUTPUT: the matrix whose reductions modulo primes are the input ``residues``
270
+
271
+ TESTS::
272
+
273
+ sage: from sage.matrix.matrix_integer_linbox import _lift_crt
274
+ sage: T1 = Matrix(Zmod(5), 4, 4, [1, 4, 4, 0, 2, 0, 1, 4, 2, 0, 4, 1, 1, 4, 0, 3])
275
+ sage: T2 = Matrix(Zmod(7), 4, 4, [1, 4, 6, 0, 2, 0, 1, 2, 4, 0, 6, 6, 1, 6, 0, 5])
276
+ sage: T3 = Matrix(Zmod(11), 4, 4, [1, 4, 10, 0, 2, 0, 1, 9, 8, 0, 10, 6, 1, 10, 0, 9])
277
+ sage: _lift_crt(Matrix(ZZ, 4, 4), [T1, T2, T3])
278
+ [ 1 4 -1 0]
279
+ [ 2 0 1 9]
280
+ [-3 0 -1 6]
281
+ [ 1 -1 0 -2]
282
+
283
+ sage: from sage.arith.multi_modular import MultiModularBasis
284
+ sage: mm = MultiModularBasis([5,7,11])
285
+ sage: _lift_crt(Matrix(ZZ, 4, 4), [T1, T2, T3], mm)
286
+ [ 1 4 -1 0]
287
+ [ 2 0 1 9]
288
+ [-3 0 -1 6]
289
+ [ 1 -1 0 -2]
290
+
291
+ The modulus must be smaller than the maximum for the multi-modular
292
+ reconstruction (using ``mod_int``) and also smaller than the limit
293
+ for ``Matrix_modn_dense_double`` to be able to represent the
294
+ ``residues`` ::
295
+
296
+ sage: from sage.arith.multi_modular import MAX_MODULUS as MAX_multi_modular
297
+ sage: from sage.matrix.matrix_modn_dense_double import MAX_MODULUS as MAX_modn_dense_double
298
+ sage: MAX_MODULUS = min(MAX_multi_modular, MAX_modn_dense_double)
299
+ sage: p0 = previous_prime(MAX_MODULUS)
300
+ sage: p1 = previous_prime(p0)
301
+ sage: mmod = [matrix(GF(p0), [[-1, 0, 1, 0, 0, 1, 1, 0, 0, 0, p0-1, p0-2]]),
302
+ ....: matrix(GF(p1), [[-1, 0, 1, 0, 0, 1, 1, 0, 0, 0, p1-1, p1-2]])]
303
+ sage: _lift_crt(Matrix(ZZ, 1, 12), mmod)
304
+ [-1 0 1 0 0 1 1 0 0 0 -1 -2]
305
+ """
306
+
307
+ cdef size_t i, j, k
308
+ cdef Py_ssize_t nr, n
309
+ cdef mpz_t *tmp = <mpz_t *>sig_malloc(sizeof(mpz_t) * M._ncols)
310
+ n = len(residues)
311
+ if n == 0: # special case: obviously residues[0] wouldn't make sense here.
312
+ return M
313
+ nr = residues[0].nrows()
314
+ nc = residues[0].ncols()
315
+
316
+ if moduli is None:
317
+ moduli = MultiModularBasis([m.base_ring().order() for m in residues])
318
+ else:
319
+ if len(residues) != len(moduli):
320
+ raise IndexError("Number of residues (%s) does not match number of moduli (%s)" % (len(residues), len(moduli)))
321
+
322
+ cdef MultiModularBasis mm
323
+ mm = moduli
324
+
325
+ for b in residues:
326
+ if not (isinstance(b, Matrix_modn_dense_float) or
327
+ isinstance(b, Matrix_modn_dense_double)):
328
+ raise TypeError("Can only perform CRT on list of matrices mod n.")
329
+
330
+ cdef mod_int **row_list
331
+ row_list = <mod_int**>sig_malloc(sizeof(mod_int*) * n)
332
+ if row_list == NULL:
333
+ raise MemoryError("out of memory allocating multi-modular coefficient list")
334
+
335
+ sig_on()
336
+ for k in range(n):
337
+ row_list[k] = <mod_int *>sig_malloc(sizeof(mod_int) * nc)
338
+ if row_list[k] == NULL:
339
+ raise MemoryError("out of memory allocating multi-modular coefficient list")
340
+
341
+ for j in range(M._ncols):
342
+ mpz_init(tmp[j])
343
+
344
+ for i in range(nr):
345
+ for k in range(n):
346
+ (<Matrix_modn_dense_template>residues[k])._copy_row_to_mod_int_array(row_list[k],i)
347
+ mm.mpz_crt_vec(tmp, row_list, nc)
348
+ for j in range(nc):
349
+ M.set_unsafe_mpz(i,j,tmp[j])
350
+
351
+ for k in range(n):
352
+ sig_free(row_list[k])
353
+ for j in range(M._ncols):
354
+ mpz_clear(tmp[j])
355
+ sig_free(row_list)
356
+ sig_free(tmp)
357
+ sig_off()
358
+ return M