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
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
|
|
Binary file
|
|
@@ -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
|
|
Binary file
|
|
@@ -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=*)
|