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
sage/libs/m4rie.pxd ADDED
@@ -0,0 +1,204 @@
1
+ # sage_setup: distribution = sagemath-linbox
2
+ # distutils: extra_compile_args = -std=c++14
3
+ ##############################################################################
4
+ # Copyright (C) 2010 Martin Albrecht <martinralbrecht@googlemail.com>
5
+ # Distributed under the terms of the GNU General Public License (GPL)
6
+ # The full text of the GPL is available at:
7
+ # http://www.gnu.org/licenses/
8
+ ##############################################################################
9
+
10
+ from sage.libs.m4ri cimport mzd_t, m4ri_word
11
+
12
+
13
+ cdef extern from "m4rie/m4rie.h":
14
+ ctypedef struct gf2e:
15
+ int degree
16
+ m4ri_word minpoly
17
+
18
+ m4ri_word *pow_gen
19
+ m4ri_word *red
20
+
21
+ m4ri_word (*inv)(gf2e *ff, m4ri_word a)
22
+ m4ri_word (*mul)(gf2e *ff, m4ri_word a, m4ri_word b)
23
+
24
+ gf2e *gf2e_init(m4ri_word minpoly)
25
+ void gf2e_free(gf2e *ff)
26
+
27
+ #cdef extern from "m4rie/mzed.h":
28
+ ctypedef struct mzed_t:
29
+ mzd_t *x
30
+ gf2e *finite_field
31
+ int nrows
32
+ int ncols
33
+ int w
34
+
35
+ ctypedef int const_int "const int"
36
+ ctypedef size_t const_size_t "const size_t"
37
+ ctypedef mzed_t const_mzed_t "const mzed_t"
38
+
39
+ mzed_t *mzed_init(gf2e *, size_t m, size_t n)
40
+
41
+ void mzed_free(mzed_t *)
42
+
43
+ int mzed_read_elem(const_mzed_t *M, const_size_t row, const_size_t col)
44
+
45
+ void mzed_write_elem(mzed_t *, const_size_t row, const_size_t col, const_int elem)
46
+
47
+ void mzed_set_ui(mzed_t *A, m4ri_word value)
48
+
49
+ mzed_t *mzed_copy(mzed_t *o, const_mzed_t *i)
50
+
51
+ int mzed_cmp(mzed_t *l, mzed_t *r)
52
+
53
+ mzed_t *mzed_randomize(mzed_t *)
54
+
55
+ mzed_t *mzed_add(mzed_t *, mzed_t *, mzed_t *)
56
+
57
+ size_t mzed_echelonize_naive(mzed_t *, size_t)
58
+
59
+ void mzed_add_elem(mzed_t *a, const_size_t row, const_size_t col, const_int elem)
60
+
61
+ void mzed_add_multiple_of_row(mzed_t *A, size_t ar, mzed_t *B, size_t br, m4ri_word x, size_t start_col)
62
+
63
+ void mzed_rescale_row(mzed_t *A, size_t r, size_t c, m4ri_word x)
64
+
65
+ void mzed_row_swap(mzed_t *M, const_size_t rowa, const_size_t rowb)
66
+
67
+ void mzed_copy_row(mzed_t* B, size_t i, const_mzed_t* A, size_t j)
68
+
69
+ void mzed_col_swap(mzed_t *M, const_size_t cola, const_size_t colb)
70
+
71
+ void mzed_row_add(mzed_t *M, const_size_t sourcerow, const_size_t destrow)
72
+
73
+ size_t mzed_first_zero_row(mzed_t *A)
74
+
75
+ int mzed_is_zero(mzed_t *A)
76
+
77
+ void mzed_row_clear_offset(mzed_t *M, const_size_t row, const_size_t coloffset)
78
+
79
+ mzed_t *mzed_concat(mzed_t *C, const_mzed_t *A, const_mzed_t *B)
80
+
81
+ mzed_t *mzed_stack(mzed_t *C, const_mzed_t *A, const_mzed_t *B)
82
+
83
+ mzed_t *mzed_submatrix(mzed_t *S, const_mzed_t *M, size_t lowr, size_t lowc, size_t highr, size_t highc)
84
+
85
+ mzed_t *mzed_mul(mzed_t *C, const_mzed_t *A, const_mzed_t *B)
86
+
87
+ mzed_t *mzed_mul_naive(mzed_t *C, const_mzed_t *A, const_mzed_t *B)
88
+
89
+ mzed_t *mzed_mul_scalar(mzed_t *C, m4ri_word a, const_mzed_t *B)
90
+
91
+ # TODO: not implemented yet in m4rie
92
+ mzed_t *mzed_transpose(mzed_t *DST, const_mzed_t *A )
93
+
94
+ void mzed_print(const_mzed_t *M)
95
+
96
+ mzed_t *mzed_invert_newton_john(mzed_t *A, mzed_t *B)
97
+
98
+ # TODO: not implemented yet in m4rie
99
+ double mzed_density(mzed_t *A, int res)
100
+
101
+ # TODO: not implemented yet in m4rie
102
+ double _mzed_density(mzed_t *A, int res, size_t r, size_t c)
103
+
104
+ #cdef extern from "m4rie/newton_john.h":
105
+ size_t mzed_echelonize_newton_john(mzed_t *, size_t)
106
+
107
+ mzed_t *mzed_mul_newton_john(mzed_t *, mzed_t *, mzed_t *)
108
+
109
+ #cdef extern from "m4rie/echelonform.h":
110
+ size_t mzed_echelonize(mzed_t *, size_t)
111
+
112
+ size_t mzed_echelonize_ple(mzed_t *, size_t)
113
+
114
+ #cdef extern from "m4rie/strassen.h":
115
+ mzed_t *mzed_mul_strassen(mzed_t *, mzed_t *, mzed_t *, size_t cutoff)
116
+
117
+ size_t _mzed_strassen_cutoff(mzed_t *C, mzed_t *A, mzed_t *B)
118
+
119
+ #cdef extern from "m4rie/mzd_slice.h":
120
+
121
+ int __M4RIE_MAX_KARATSUBA_DEGREE
122
+
123
+ ctypedef struct mzd_slice_t:
124
+ mzd_t *x[16]
125
+ gf2e *finite_field
126
+ int nrows
127
+ int ncols
128
+ int depth
129
+
130
+ mzd_slice_t *mzd_slice_init(gf2e *ff, size_t m, size_t n)
131
+
132
+ void mzd_slice_free(mzd_slice_t *A)
133
+
134
+ mzed_t *mzed_cling(mzed_t *A, mzd_slice_t *Z)
135
+
136
+ mzd_slice_t *mzed_slice(mzd_slice_t *A, mzed_t *Z)
137
+
138
+ mzd_slice_t *mzd_slice_concat(mzd_slice_t *C, mzd_slice_t *A, mzd_slice_t *B)
139
+
140
+ mzd_slice_t *mzd_slice_stack(mzd_slice_t *C, mzd_slice_t *A, mzd_slice_t *B)
141
+
142
+ mzd_slice_t *mzd_slice_submatrix(mzd_slice_t *S, mzd_slice_t *A, size_t lowr, size_t lowc, size_t highr, size_t highc)
143
+
144
+ mzd_slice_t *mzd_slice_init_window(mzd_slice_t *A, size_t lowr, size_t lowc, size_t highr, size_t highc)
145
+
146
+ void mzd_slice_free_window(mzd_slice_t *A)
147
+
148
+ mzd_slice_t *_mzd_slice_add(mzd_slice_t *C, mzd_slice_t *A, mzd_slice_t *B)
149
+
150
+ mzd_slice_t *mzd_slice_add(mzd_slice_t *C, mzd_slice_t *A, mzd_slice_t *B)
151
+
152
+ void mzd_slice_randomize(mzd_slice_t *A)
153
+
154
+ mzd_slice_t *mzd_slice_copy(mzd_slice_t *B, mzd_slice_t *A)
155
+
156
+ void mzd_slice_set_ui(mzd_slice_t *A, m4ri_word value)
157
+
158
+ m4ri_word mzd_slice_read_elem(mzd_slice_t *A, size_t row, size_t col)
159
+
160
+ void mzd_slice_add_elem(mzd_slice_t *A, size_t row, size_t col, m4ri_word elem)
161
+
162
+ void mzd_slice_write_elem(mzd_slice_t *A, size_t row, size_t col, m4ri_word elem)
163
+
164
+ int mzd_slice_cmp(mzd_slice_t *A, mzd_slice_t *B)
165
+
166
+ int mzd_slice_is_zero(mzd_slice_t *A)
167
+
168
+ void mzd_slice_rescale_row(mzd_slice_t *A, size_t r, size_t c, m4ri_word x)
169
+
170
+ void mzd_slice_row_swap(mzd_slice_t *A, size_t rowa, size_t rowb)
171
+
172
+ void mzd_slice_copy_row(mzd_slice_t* B, size_t i, mzd_slice_t* A, size_t j)
173
+
174
+ void mzd_slice_col_swap(mzd_slice_t *A, size_t cola, size_t colb)
175
+
176
+ void mzd_slice_row_add(mzd_slice_t *A, size_t sourcerow, size_t destrow)
177
+
178
+ void mzd_slice_row_clear_offset(mzd_slice_t *A, size_t row, size_t coloffset)
179
+
180
+ void mzd_slice_print(mzd_slice_t *A)
181
+
182
+ mzd_slice_t *_mzed_slice2(mzd_slice_t *A, mzed_t *Z)
183
+
184
+ mzd_slice_t *mzed_slice2(mzd_slice_t *A, mzed_t *Z)
185
+
186
+ mzd_slice_t *_mzed_slice4(mzd_slice_t *A, mzed_t *Z)
187
+
188
+ mzed_t *_mzed_cling2(mzed_t *A, mzd_slice_t *Z)
189
+
190
+ mzed_t* mzed_cling2(mzed_t *A, mzd_slice_t *Z)
191
+
192
+ mzed_t *_mzed_cling4(mzed_t *A, mzd_slice_t *Z)
193
+
194
+ mzed_t* mzed_cling4(mzed_t *A, mzd_slice_t *Z)
195
+
196
+ mzed_t *mzed_mul_karatsuba(mzed_t *C, mzed_t *A, mzed_t *B)
197
+
198
+ mzed_t *mzed_addmul_karatsuba(mzed_t *C, mzed_t *A, mzed_t *B)
199
+
200
+ mzed_t *_mzed_mul_karatsuba(mzed_t *C, mzed_t *A, mzed_t *B)
201
+
202
+ mzd_slice_t *_mzd_slice_mul_karatsuba2(mzd_slice_t *C, mzd_slice_t *A, mzd_slice_t *B)
203
+
204
+ mzd_slice_t *_mzd_slice_mul_karatsuba3(mzd_slice_t *C, mzd_slice_t *A, mzd_slice_t *B)
@@ -0,0 +1 @@
1
+ # sage_setup: distribution = sagemath-linbox
@@ -0,0 +1,361 @@
1
+ # sage_setup: distribution = sagemath-linbox
2
+ # sage.doctest: needs sage.libs.flint sage.libs.linbox
3
+
4
+ from sage.arith.misc import previous_prime
5
+ from sage.libs.flint.fmpq cimport fmpq_is_zero, fmpq_set_mpq, fmpq_canonicalise
6
+ from sage.libs.flint.fmpq_mat cimport fmpq_mat_entry_num, fmpq_mat_entry_den, fmpq_mat_entry
7
+ from sage.libs.flint.fmpz cimport fmpz_init, fmpz_clear, fmpz_set_mpz, fmpz_one, fmpz_get_mpz, fmpz_add, fmpz_mul, fmpz_sub, fmpz_mul_si, fmpz_mul_si, fmpz_mul_si, fmpz_divexact, fmpz_lcm
8
+ from sage.libs.gmp.types cimport mpz_t
9
+ from sage.matrix.constructor import matrix
10
+ from sage.matrix.matrix_cyclo_dense cimport Matrix_cyclo_dense
11
+ from sage.matrix.matrix_integer_linbox cimport _lift_crt
12
+ from sage.matrix.matrix_rational_dense cimport Matrix_rational_dense
13
+ from sage.matrix.matrix_space import MatrixSpace
14
+ from sage.matrix.misc_flint import matrix_integer_dense_rational_reconstruction
15
+ from sage.misc.verbose import verbose
16
+ from sage.rings.integer_ring import ZZ
17
+ from sage.rings.rational_field import QQ
18
+ from sage.structure.element cimport Matrix as baseMatrix
19
+ from sage.structure.proof.proof import get_flag as get_proof_flag
20
+
21
+ from sage.matrix.matrix_modn_dense_double import MAX_MODULUS as MAX_MODULUS_modn_dense_double
22
+ from sage.arith.multi_modular import MAX_MODULUS as MAX_MODULUS_multi_modular
23
+ MAX_MODULUS = min(MAX_MODULUS_modn_dense_double, MAX_MODULUS_multi_modular)
24
+
25
+ # parameters for tuning
26
+ echelon_primes_increment = 15
27
+ echelon_verbose_level = 1
28
+
29
+
30
+ cpdef _matrix_times_matrix_(Matrix_cyclo_dense self, baseMatrix right):
31
+ """
32
+ Return the product of two cyclotomic dense matrices.
33
+
34
+ INPUT:
35
+
36
+ - ``self``, ``right`` -- cyclotomic dense matrices with compatible
37
+ parents (same base ring, and compatible dimensions for matrix
38
+ multiplication)
39
+
40
+ OUTPUT: cyclotomic dense matrix
41
+
42
+ ALGORITHM:
43
+
44
+ Use a multimodular algorithm that involves multiplying the two matrices
45
+ modulo split primes.
46
+
47
+ EXAMPLES::
48
+
49
+ sage: W.<z> = CyclotomicField(5)
50
+ sage: A = matrix(3, 3, [1,z,z^2,z^3,z^4,2/3*z,-3*z,z,2+z]); B = matrix(3, 3, [-1,2*z,3*z^2,5*z+1,z^4,1/3*z,2-z,3-z,5-z])
51
+ sage: A*B
52
+ [ -z^3 + 7*z^2 + z - 1 -z^3 + 3*z^2 + 2*z + 1 -z^3 + 25/3*z^2]
53
+ [-2*z^3 - 5/3*z^2 + 1/3*z + 4 -z^3 - 8/3*z^2 - 2 -2/3*z^2 + 10/3*z + 10/3]
54
+ [ 4*z^2 + 4*z + 4 -7*z^2 + z + 7 -9*z^3 - 2/3*z^2 + 3*z + 10]
55
+
56
+ Verify that the answer above is consistent with what the
57
+ generic sparse matrix multiply gives (which is a different
58
+ implementation).::
59
+
60
+ sage: A*B == A.sparse_matrix()*B.sparse_matrix()
61
+ True
62
+
63
+ sage: N1 = Matrix(CyclotomicField(6), 1, [1])
64
+ sage: cf6 = CyclotomicField(6) ; z6 = cf6.0
65
+ sage: N2 = Matrix(CyclotomicField(6), 1, 5, [0,1,z6,-z6,-z6+1])
66
+ sage: N1*N2
67
+ [ 0 1 zeta6 -zeta6 -zeta6 + 1]
68
+ sage: N1 = Matrix(CyclotomicField(6), 1, [-1])
69
+ sage: N1*N2
70
+ [ 0 -1 -zeta6 zeta6 zeta6 - 1]
71
+
72
+ Verify that a degenerate case bug reported at :issue:`5974` is fixed.
73
+
74
+ sage: K.<zeta6>=CyclotomicField(6); matrix(K,1,2) * matrix(K,2,[0, 1, 0, -2*zeta6, 0, 0, 1, -2*zeta6 + 1])
75
+ [0 0 0 0]
76
+
77
+ TESTS:
78
+
79
+ This is from :issue:`8666`::
80
+
81
+ sage: K.<zeta4> = CyclotomicField(4)
82
+ sage: m = matrix(K, [125])
83
+ sage: n = matrix(K, [186])
84
+ sage: m*n
85
+ [23250]
86
+ sage: (-m)*n
87
+ [-23250]
88
+ """
89
+ A, denom_self = self._matrix._clear_denom()
90
+ B, denom_right = (<Matrix_cyclo_dense>right)._matrix._clear_denom()
91
+
92
+ # conservative but correct estimate: 2 is there to account for the
93
+ # sign of the entries
94
+ bound = 1 + 2 * A.height() * B.height() * self._ncols
95
+
96
+ n = self._base_ring._n()
97
+ p = previous_prime(MAX_MODULUS)
98
+ prod = 1
99
+ v = []
100
+ while prod <= bound:
101
+ while (n >= 2 and p % n != 1) or denom_self % p == 0 or denom_right % p == 0:
102
+ if p == 2:
103
+ raise RuntimeError("we ran out of primes in matrix multiplication.")
104
+ p = previous_prime(p)
105
+ prod *= p
106
+ Amodp, _ = self._reductions(p)
107
+ Bmodp, _ = right._reductions(p)
108
+ _, S = self._reduction_matrix(p)
109
+ X = Amodp[0]._matrix_from_rows_of_matrices([Amodp[i] * Bmodp[i] for i in range(len(Amodp))])
110
+ v.append(S*X)
111
+ p = previous_prime(p)
112
+ M = matrix(ZZ, self._base_ring.degree(), self._nrows*right.ncols())
113
+ _lift_crt(M, v)
114
+ d = denom_self * denom_right
115
+ if d == 1:
116
+ M = M.change_ring(QQ)
117
+ else:
118
+ M = (1/d)*M
119
+ cdef Matrix_cyclo_dense C = Matrix_cyclo_dense.__new__(Matrix_cyclo_dense,
120
+ MatrixSpace(self._base_ring, self._nrows, right.ncols()),
121
+ None, None, None)
122
+ C._matrix = M
123
+ return C
124
+
125
+
126
+ def _charpoly_multimodular(Matrix_cyclo_dense self, var='x', proof=None):
127
+ """
128
+ Compute the characteristic polynomial of ``self`` using a
129
+ multimodular algorithm.
130
+
131
+ INPUT:
132
+
133
+ - ``proof`` -- boolean (default: global flag); if ``False``, compute
134
+ using primes `p_i` until the lift modulo all primes up to `p_i` is
135
+ the same as the lift modulo all primes up to `p_{i+3}` or the bound
136
+ is reached
137
+
138
+ EXAMPLES::
139
+
140
+ sage: K.<z> = CyclotomicField(3)
141
+ sage: A = matrix(3, [-z, 2*z + 1, 1/2*z + 2, 1, -1/2, 2*z + 2, -2*z - 2, -2*z - 2, 2*z - 1])
142
+ sage: A._charpoly_multimodular()
143
+ x^3 + (-z + 3/2)*x^2 + (17/2*z + 9/2)*x - 9/2*z - 23/2
144
+ sage: A._charpoly_multimodular('T')
145
+ T^3 + (-z + 3/2)*T^2 + (17/2*z + 9/2)*T - 9/2*z - 23/2
146
+ sage: A._charpoly_multimodular('T', proof=False)
147
+ T^3 + (-z + 3/2)*T^2 + (17/2*z + 9/2)*T - 9/2*z - 23/2
148
+
149
+ TESTS:
150
+
151
+ We test a degenerate case::
152
+
153
+ sage: A = matrix(CyclotomicField(1),2,[1,2,3,4]); A.charpoly()
154
+ x^2 - 5*x - 2
155
+ """
156
+ cdef Matrix_cyclo_dense A
157
+ A = Matrix_cyclo_dense.__new__(Matrix_cyclo_dense, self.parent(),
158
+ None, None, None)
159
+
160
+ proof = get_proof_flag(proof, "linear_algebra")
161
+
162
+ n = self._base_ring._n()
163
+ p = previous_prime(MAX_MODULUS)
164
+ prod = 1
165
+ v = []
166
+ # A, denom = self._matrix._clear_denom()
167
+ # TODO: this might be stupidly slow
168
+ denom = self._matrix.denominator()
169
+ A._matrix = <Matrix_rational_dense>(denom*self._matrix)
170
+ bound = A._charpoly_bound()
171
+ L_last = 0
172
+ while prod <= bound:
173
+ while (n >= 2 and p % n != 1) or denom % p == 0:
174
+ if p == 2:
175
+ raise RuntimeError("we ran out of primes in multimodular charpoly algorithm.")
176
+ p = previous_prime(p)
177
+
178
+ X = A._charpoly_mod(p)
179
+ v.append(X)
180
+ prod *= p
181
+ p = previous_prime(p)
182
+
183
+ # if we've used enough primes as determined by bound, or
184
+ # if we've used 3 primes, we check to see if the result is
185
+ # the same.
186
+ if prod >= bound or (not proof and (len(v) % 3 == 0)):
187
+ M = matrix(ZZ, self._base_ring.degree(), self._nrows+1)
188
+ L = _lift_crt(M, v)
189
+ if not proof and L == L_last:
190
+ break
191
+ L_last = L
192
+
193
+ # Now each column of L encodes a coefficient of the output polynomial,
194
+ # with column 0 being the constant coefficient.
195
+ K = self.base_ring()
196
+ R = K[var]
197
+ coeffs = [K(w.list()) for w in L.columns()]
198
+ f = R(coeffs)
199
+
200
+ # Rescale to account for denominator, if necessary
201
+ if denom != 1:
202
+ x = R.gen()
203
+ f = f(x * denom) * (1 / (denom**f.degree()))
204
+
205
+ return f
206
+
207
+
208
+ def _echelon_form_multimodular(Matrix_cyclo_dense self, num_primes=10, height_guess=None):
209
+ """
210
+ Use a multimodular algorithm to find the echelon form of ``self``.
211
+
212
+ INPUT:
213
+
214
+ - ``num_primes`` -- number of primes to work modulo
215
+
216
+ - ``height_guess`` -- guess for the height of the echelon form of self
217
+
218
+ OUTPUT: matrix in reduced row echelon form
219
+
220
+ EXAMPLES::
221
+
222
+ sage: W.<z> = CyclotomicField(3)
223
+ sage: A = matrix(W, 2, 3, [1+z, 2/3, 9*z+7, -3 + 4*z, z, -7*z]); A
224
+ [ z + 1 2/3 9*z + 7]
225
+ [4*z - 3 z -7*z]
226
+ sage: A._echelon_form_multimodular(10)
227
+ [ 1 0 -192/97*z - 361/97]
228
+ [ 0 1 1851/97*z + 1272/97]
229
+
230
+ TESTS:
231
+
232
+ We test a degenerate case::
233
+
234
+ sage: A = matrix(CyclotomicField(5),0); A
235
+ []
236
+ sage: A._echelon_form_multimodular(10)
237
+ []
238
+ sage: A.pivots()
239
+ ()
240
+
241
+ sage: A = matrix(CyclotomicField(13), 2, 3, [5, 1, 2, 46307, 46307*4, 46307])
242
+ sage: A._echelon_form_multimodular()
243
+ [ 1 0 7/19]
244
+ [ 0 1 3/19]
245
+ """
246
+ cdef Matrix_cyclo_dense res
247
+ cdef bint is_square
248
+
249
+ verbose("entering _echelon_form_multimodular",
250
+ level=echelon_verbose_level)
251
+
252
+ denom = self._matrix.denominator()
253
+ A = denom * self
254
+
255
+ # This bound is chosen somewhat arbitrarily. Changing it affects the
256
+ # runtime, not the correctness of the result.
257
+ if height_guess is None:
258
+ height_guess = (A.coefficient_bound() + 100) * 1000000
259
+
260
+ # This is all setup to keep track of various data
261
+ # in the loop below.
262
+ p = previous_prime(MAX_MODULUS)
263
+ found = 0
264
+ prod = 1
265
+ n = self._base_ring._n()
266
+ height_bound = self._ncols * height_guess * A.coefficient_bound() + 1
267
+ mod_p_ech_ls = []
268
+ max_pivots = tuple()
269
+ is_square = self._nrows == self._ncols
270
+
271
+ verbose("using height bound %s" % height_bound,
272
+ level=echelon_verbose_level)
273
+
274
+ while True:
275
+ # Generate primes to use, and find echelon form
276
+ # modulo those primes.
277
+ while found < num_primes or prod <= height_bound:
278
+ if (n == 1) or p % n == 1:
279
+ try:
280
+ mod_p_ech, piv_ls = A._echelon_form_one_prime(p)
281
+ except ValueError:
282
+ # This means that we chose a prime which divides
283
+ # the denominator of the echelon form of self, so
284
+ # just skip it and continue
285
+ p = previous_prime(p)
286
+ continue
287
+ # if we have the identity, just return it, and
288
+ # we're done.
289
+ if is_square and len(piv_ls) == self._nrows:
290
+ self.cache('pivots', tuple(range(self._nrows)))
291
+ return self.parent().identity_matrix()
292
+ if piv_ls > max_pivots:
293
+ mod_p_ech_ls = [mod_p_ech]
294
+ max_pivots = piv_ls
295
+ # add this to the list of primes
296
+ prod = p
297
+ found = 1
298
+ elif piv_ls == max_pivots:
299
+ mod_p_ech_ls.append(mod_p_ech)
300
+ # add this to the list of primes
301
+ prod *= p
302
+ found += 1
303
+ else:
304
+ # this means that the rank profile mod this
305
+ # prime is worse than those that came before,
306
+ # so we just loop
307
+ p = previous_prime(p)
308
+ continue
309
+
310
+ p = previous_prime(p)
311
+
312
+ if found > num_primes:
313
+ num_primes = found
314
+
315
+ verbose("computed echelon form mod %s primes" % num_primes,
316
+ level=echelon_verbose_level)
317
+ verbose("current product of primes used: %s" % prod,
318
+ level=echelon_verbose_level)
319
+
320
+ # Use CRT to lift back to ZZ
321
+ mat_over_ZZ = matrix(ZZ, self._base_ring.degree(),
322
+ self._nrows * self._ncols)
323
+ _lift_crt(mat_over_ZZ, mod_p_ech_ls)
324
+ # note: saving the CRT intermediate MultiModularBasis does
325
+ # not seem to affect the runtime at all
326
+
327
+ # Attempt to use rational reconstruction to find
328
+ # our echelon form
329
+ try:
330
+ verbose("attempting rational reconstruction ...",
331
+ level=echelon_verbose_level)
332
+ res = Matrix_cyclo_dense.__new__(Matrix_cyclo_dense,
333
+ self.parent(),
334
+ None, None, None)
335
+ res._matrix = <Matrix_rational_dense>matrix_integer_dense_rational_reconstruction(mat_over_ZZ, prod)
336
+
337
+ except ValueError:
338
+ # If a ValueError is raised here, it means that the
339
+ # rational reconstruction failed. In this case, add
340
+ # on a few more primes, and try again.
341
+
342
+ num_primes += echelon_primes_increment
343
+ verbose("rational reconstruction failed, trying with %s primes"%num_primes, level=echelon_verbose_level)
344
+ continue
345
+
346
+ verbose("rational reconstruction succeeded with %s primes!"%num_primes, level=echelon_verbose_level)
347
+
348
+ if ((res * res.denominator()).coefficient_bound() *
349
+ self.coefficient_bound() * self.ncols()) > prod:
350
+ # In this case, we don't know the result to sufficient
351
+ # "precision" (here precision is just the modulus,
352
+ # prod) to guarantee its correctness, so loop.
353
+
354
+ num_primes += echelon_primes_increment
355
+ verbose("height not sufficient to determine echelon form",
356
+ level=echelon_verbose_level)
357
+ continue
358
+
359
+ verbose("found echelon form with %s primes, whose product is %s"%(num_primes, prod), level=echelon_verbose_level)
360
+ self.cache('pivots', max_pivots)
361
+ return res
@@ -0,0 +1,15 @@
1
+ # sage_setup: distribution = sagemath-linbox
2
+ from sage.libs.m4rie cimport mzed_t
3
+ from sage.libs.m4ri cimport m4ri_word
4
+ from sage.matrix.matrix_dense cimport Matrix_dense
5
+
6
+
7
+ cdef class Matrix_gf2e_dense(Matrix_dense):
8
+ cdef mzed_t *_entries
9
+ cdef object _one
10
+ cdef object _zero
11
+ cdef m4ri_word _zero_word # m4ri_word representation of _zero
12
+
13
+ cpdef Matrix_gf2e_dense _multiply_newton_john(Matrix_gf2e_dense self, Matrix_gf2e_dense right)
14
+ cpdef Matrix_gf2e_dense _multiply_karatsuba(Matrix_gf2e_dense self, Matrix_gf2e_dense right)
15
+ cpdef Matrix_gf2e_dense _multiply_strassen(Matrix_gf2e_dense self, Matrix_gf2e_dense right, cutoff=*)