Attachment 'm4rie_for_sage.patch'
Download 1 # HG changeset patch
2 # User Martin Albrecht <martinralbrecht@googlemail.com>
3 # Date 1279639189 -3600
4 # Node ID cc88353e2acb2bdbe05178a09647ccb8d524f340
5 # Parent 96e2020790df6a5f4d413e65b111f0ec6e73fc2a
6 Matrices over GF(2^n)
7
8 diff -r 96e2020790df -r cc88353e2acb module_list.py
9 --- a/module_list.py Mon Jun 28 23:27:14 2010 +0100
10 +++ b/module_list.py Tue Jul 20 16:19:49 2010 +0100
11 @@ -785,6 +785,12 @@
12 libraries = ['gmp','m4ri', 'gd', 'png12', 'z'],
13 depends = [SAGE_ROOT + "/local/include/png.h", SAGE_ROOT + "/local/include/m4ri/m4ri.h"]),
14
15 + Extension('sage.matrix.matrix_mod2e_dense',
16 + sources = ['sage/matrix/matrix_mod2e_dense.pyx'],
17 + libraries = ['m4rie', 'm4ri', 'givaro', 'ntl', 'gmpxx', 'gmp', 'm', 'stdc++'],
18 + depends = [SAGE_ROOT + "/local/include/m4rie/m4rie.h"],
19 + language="c++"),
20 +
21 Extension('sage.matrix.matrix_modn_dense',
22 sources = ['sage/matrix/matrix_modn_dense.pyx'],
23 libraries = ['gmp']),
24 diff -r 96e2020790df -r cc88353e2acb sage/libs/m4rie.pxd
25 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26 +++ b/sage/libs/m4rie.pxd Tue Jul 20 16:19:49 2010 +0100
27 @@ -0,0 +1,110 @@
28 +##############################################################################
29 +# Copyright (C) 2010 Martin Albrecht <martinralbrecht@googlemail.com>
30 +# Distributed under the terms of the GNU General Public License (GPL)
31 +# The full text of the GPL is available at:
32 +# http://www.gnu.org/licenses/
33 +##############################################################################
34 +
35 +from sage.libs.m4ri cimport mzd_t, m4ri_word
36 +
37 +
38 +
39 +cdef extern from "m4rie/m4rie.h":
40 + ctypedef struct gf2e:
41 + m4ri_word **mul
42 + m4ri_word *inv
43 + size_t degree
44 +
45 + void gf2e_free(gf2e *ff)
46 +
47 +#cdef extern from "m4rie/gf2e_matrix.h":
48 + ctypedef struct mzed_t:
49 + mzd_t *x
50 + gf2e *finite_field
51 + int nrows
52 + int ncols
53 + int w
54 +
55 + ctypedef int const_int "const int"
56 + ctypedef size_t const_size_t "const size_t"
57 + ctypedef mzed_t const_mzed_t "const mzed_t"
58 +
59 + mzed_t *mzed_init(gf2e *, size_t m, size_t n)
60 +
61 + void mzed_free(mzed_t *)
62 +
63 + int mzed_read_elem(const_mzed_t *M, const_size_t row, const_size_t col)
64 +
65 + void mzed_write_elem(mzed_t *, const_size_t row, const_size_t col, const_int elem)
66 +
67 + mzed_t *mzed_copy(mzed_t *o, const_mzed_t *i)
68 +
69 + int mzed_cmp(mzed_t *l, mzed_t *r)
70 +
71 + mzed_t *mzed_randomize(mzed_t *)
72 +
73 + mzed_t *mzed_add(mzed_t *, mzed_t *, mzed_t *)
74 +
75 + size_t mzed_echelonize_naive(mzed_t *, size_t)
76 +
77 + void mzed_add_elem(mzed_t *a, const_size_t row, const_size_t col, const_int elem)
78 +
79 + 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)
80 +
81 + void mzed_rescale_row(mzed_t *A, size_t r, size_t c, m4ri_word *X)
82 +
83 + void mzed_row_swap(mzed_t *M, const_size_t rowa, const_size_t rowb)
84 +
85 + void mzed_copy_row(mzed_t* B, size_t i, const_mzed_t* A, size_t j)
86 +
87 + void mzed_col_swap(mzed_t *M, const_size_t cola, const_size_t colb)
88 +
89 + void mzed_row_add(mzed_t *M, const_size_t sourcerow, const_size_t destrow)
90 +
91 + size_t mzed_first_zero_row(mzed_t *A)
92 +
93 + int mzed_is_zero(mzed_t *A)
94 +
95 + void mzed_row_clear_offset(mzed_t *M, const_size_t row, const_size_t coloffset)
96 +
97 + mzed_t *mzed_concat(mzed_t *C, const_mzed_t *A, const_mzed_t *B)
98 +
99 + mzed_t *mzed_stack(mzed_t *C, const_mzed_t *A, const_mzed_t *B)
100 +
101 + mzed_t *mzed_submatrix(mzed_t *S, const_mzed_t *M, size_t lowr, size_t lowc, size_t highr, size_t highc)
102 +
103 + mzed_t *mzed_mul_naive(mzed_t *C, const_mzed_t *A, const_mzed_t *B, const_int clear)
104 +
105 + # TODO: not implemented yet in m4rie
106 + mzed_t *mzed_transpose(mzed_t *DST, const_mzed_t *A )
107 +
108 + void mzed_print(const_mzed_t *M)
109 +
110 + mzed_t *mzed_invert_travolta(mzed_t *A, mzed_t *B)
111 +
112 + # TODO: not implemented yet in m4rie
113 + double mzed_density(mzed_t *A, int res)
114 +
115 + # TODO: not implemented yet in m4rie
116 + double _mzed_density(mzed_t *A, int res, size_t r, size_t c)
117 +
118 +
119 +#cdef extern from "m4rie/travolta.h":
120 + size_t mzed_echelonize_travolta(mzed_t *, size_t)
121 +
122 + mzed_t *mzed_mul_travolta(mzed_t *, mzed_t *, mzed_t *)
123 +
124 +#cdef extern from "m4rie/echelonform.h":
125 + size_t mzed_echelonize(mzed_t *, size_t)
126 +
127 +cdef extern from "m4rie/finite_field_givaro.h":
128 + ctypedef struct M4RIE__FiniteField "M4RIE::FiniteField":
129 + int (* pol2log)(int r)
130 + int (* log2pol)(int r)
131 +
132 + gf2e *gf2e_init_givgfq(M4RIE__FiniteField *givgfq)
133 +
134 + int mzed_read_elem_log(const_mzed_t *a, const_size_t row, const_size_t col, M4RIE__FiniteField *ff)
135 + void mzed_write_elem_log(mzed_t *a, const_size_t row, const_size_t col, const_int elem, M4RIE__FiniteField *ff)
136 + void mzed_add_elem_log(mzed_t *a, const_size_t row, const_size_t col, const_int elem, M4RIE__FiniteField *ff)
137 +
138 diff -r 96e2020790df -r cc88353e2acb sage/libs/ntl/ntl_mat_GF2E.pyx
139 --- a/sage/libs/ntl/ntl_mat_GF2E.pyx Mon Jun 28 23:27:14 2010 +0100
140 +++ b/sage/libs/ntl/ntl_mat_GF2E.pyx Tue Jul 20 16:19:49 2010 +0100
141 @@ -619,3 +619,11 @@
142 mat_GF2E_kernel(X.x, self.x)
143 _sig_off
144 return X
145 +
146 + def randomize(self):
147 + cdef long i,j
148 + cdef GF2E_c tmp
149 + for i in xrange(self.x.NumRows()):
150 + for j in xrange(self.x.NumCols()):
151 + tmp = GF2E_random()
152 + mat_GF2E_setitem(&self.x, i, j, &tmp)
153 diff -r 96e2020790df -r cc88353e2acb sage/matrix/matrix_mod2_dense.pyx
154 --- a/sage/matrix/matrix_mod2_dense.pyx Mon Jun 28 23:27:14 2010 +0100
155 +++ b/sage/matrix/matrix_mod2_dense.pyx Tue Jul 20 16:19:49 2010 +0100
156 @@ -1127,7 +1127,7 @@
157 self._echelon_in_place_classical()
158 else:
159 raise ValueError, "no algorithm '%s'"%algorithm
160 -
161 +
162 def _pivots(self):
163 r"""
164 Returns the pivot columns of \code{self} if \code{self} is in
165 diff -r 96e2020790df -r cc88353e2acb sage/matrix/matrix_mod2e_dense.pxd
166 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
167 +++ b/sage/matrix/matrix_mod2e_dense.pxd Tue Jul 20 16:19:49 2010 +0100
168 @@ -0,0 +1,15 @@
169 +# choose: dense or sparse
170 +
171 +from sage.rings.finite_rings.element_givaro cimport GivaroGfq, Cache_givaro
172 +
173 +from sage.libs.m4rie cimport mzed_t
174 +
175 +cimport matrix_dense
176 +
177 +cdef class Matrix_mod2e_dense(matrix_dense.Matrix_dense):
178 + cdef mzed_t *_entries
179 + cdef Cache_givaro cc
180 + cdef object _one
181 + cdef object _zero
182 +
183 +
184 diff -r 96e2020790df -r cc88353e2acb sage/matrix/matrix_mod2e_dense.pyx
185 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
186 +++ b/sage/matrix/matrix_mod2e_dense.pyx Tue Jul 20 16:19:49 2010 +0100
187 @@ -0,0 +1,951 @@
188 +"""
189 +Dense matrices over GF(2^e) for 2 <= e <= 10 using the M4RIe library.
190 +
191 +m x n matrices over GF(2^e) are internally represented as m x (en)
192 +matrices over GF(2) which allows to reuse much of the existing
193 +machinery of M4RI.
194 +
195 +EXAMPLE::
196 +
197 + sage: K.<a> = GF(2^8)
198 + sage: A = random_matrix(K, 3,4)
199 + sage: A
200 + [ a^3 + a^2 + 1 a^7 + a^5 + a^4 + a + 1 a^7 + a^3 a^6 + a^4 + a]
201 + [ a^5 + a^4 + a^3 + a^2 + 1 a^7 + a^6 + a^5 + a^4 + a^3 + a a^5 + a^4 + a^3 + a a^6 + a^4 + a^2 + 1]
202 + [ a^6 + a^5 + a^4 + a^2 + a + 1 a^7 + a^5 + a^3 + a^2 + a + 1 a^7 + a^6 + a^3 + a^2 + a a^7 + a^5 + a^3 + a]
203 +
204 + sage: A.echelon_form()
205 + [ 1 0 0 a^7 + a^6 + a^2 + a]
206 + [ 0 1 0 a^6 + a^4 + a^3 + a^2]
207 + [ 0 0 1 a^6 + a^4 + a^3 + a^2 + a]
208 +
209 +AUTHOR:
210 + * Martin Albrecht <martinralbrecht@googlemail.com>
211 +
212 +TESTS::
213 +
214 + sage: sage: TestSuite(sage.matrix.matrix_mod2e_dense.Matrix_mod2e_dense).run(verbose=True)
215 + running ._test_pickling() . . . pass
216 +"""
217 +
218 +include "../ext/interrupt.pxi"
219 +include "../ext/cdefs.pxi"
220 +include '../ext/stdsage.pxi'
221 +include '../ext/random.pxi'
222 +
223 +cimport matrix_dense
224 +from sage.structure.element cimport Matrix, Vector
225 +from sage.structure.element cimport ModuleElement, Element
226 +
227 +#from sage.misc.functional import log
228 +#from sage.misc.misc import verbose, get_verbose, cputime
229 +
230 +from sage.rings.all import FiniteField as GF
231 +from sage.rings.finite_rings.element_givaro cimport FiniteField_givaroElement, GivRandom, GivRandomSeeded
232 +from sage.misc.randstate cimport randstate, current_randstate
233 +
234 +from sage.matrix.matrix_mod2_dense cimport Matrix_mod2_dense
235 +
236 +from sage.libs.m4ri cimport m4ri_word, mzd_copy
237 +from sage.libs.m4rie cimport *
238 +from sage.libs.m4rie cimport mzed_t, M4RIE__FiniteField
239 +
240 +
241 +
242 +# we must keep a copy of the internal finite field representation
243 +# around to avoid re-creating it over and over again. Furthermore,
244 +# M4RIE assumes pointer equivalence of identical fields.
245 +
246 +_givaro_cache = {}
247 +
248 +cdef class M4RIE_finite_field:
249 + """
250 + A thin wrapper around the M4RIE finite field class such that we
251 + can put it in a hash table. This class isn't meant for public
252 + consumption.
253 + """
254 + cdef gf2e *ff
255 +
256 + def __cinit__(self):
257 + """
258 + EXAMPLE::
259 +
260 + sage: from sage.matrix.matrix_mod2e_dense import M4RIE_finite_field
261 + sage: K = M4RIE_finite_field(); K
262 + <sage.matrix.matrix_mod2e_dense.M4RIE_finite_field object at 0x...>
263 + """
264 + pass
265 +
266 + def __dealloc__(self):
267 + """
268 + EXAMPLE::
269 +
270 + sage: from sage.matrix.matrix_mod2e_dense import M4RIE_finite_field
271 + sage: K = M4RIE_finite_field()
272 + sage: del K
273 + """
274 + if self.ff:
275 + gf2e_free(self.ff)
276 +
277 +cdef class Matrix_mod2e_dense(matrix_dense.Matrix_dense): # dense or sparse
278 + ########################################################################
279 + # LEVEL 1 functionality
280 + ########################################################################
281 + def __cinit__(self, parent, entries, copy, coerce, alloc=True):
282 + """
283 + Create new matrix over `GF(2^k)` for 2<=k<=10.
284 +
285 + EXAMPLES::
286 +
287 + sage: K.<a> = GF(2^4)
288 + sage: A = Matrix(K, 3, 4); A
289 + [0 0 0 0]
290 + [0 0 0 0]
291 + [0 0 0 0]
292 +
293 + sage: A.randomize(); A
294 + [ a^2 + 1 a^3 + a^2 + a a^3 + a + 1 a + 1]
295 + [ a + 1 a + 1 a^3 + a a^3 + a^2]
296 + [a^3 + a^2 + a a 1 a^3 + a + 1]
297 +
298 + sage: K.<a> = GF(2^3)
299 + sage: A = Matrix(K,3,4); A
300 + [0 0 0 0]
301 + [0 0 0 0]
302 + [0 0 0 0]
303 +
304 + sage: A.randomize(); A
305 + [a^2 + 1 0 a + 1 0]
306 + [ a a a + 1 a]
307 + [ 1 a^2 a^2 + a 0]
308 + """
309 + matrix_dense.Matrix_dense.__init__(self, parent)
310 +
311 + cdef M4RIE_finite_field FF
312 +
313 + R = parent.base_ring()
314 +
315 + self.cc = <Cache_givaro>R._cache
316 +
317 + if alloc and self._nrows and self._ncols:
318 + if self.cc in _givaro_cache:
319 + self._entries = mzed_init((<M4RIE_finite_field>_givaro_cache[self.cc]).ff, self._nrows, self._ncols)
320 + else:
321 + FF = PY_NEW(M4RIE_finite_field)
322 + FF.ff = gf2e_init_givgfq(<M4RIE__FiniteField*>self.cc.objectptr)
323 + self._entries = mzed_init(FF.ff, self._nrows, self._ncols)
324 + _givaro_cache[self.cc] = FF
325 +
326 + # cache elements
327 + self._zero = self._base_ring(0)
328 + self._one = self._base_ring(1)
329 +
330 + def __dealloc__(self):
331 + """
332 + TESTS::
333 +
334 + sage: K.<a> = GF(2^4)
335 + sage: A = Matrix(K, 1000, 1000)
336 + sage: del A
337 + sage: A = Matrix(K, 1000, 1000)
338 + sage: del A
339 + """
340 + if self._entries:
341 + mzed_free(self._entries)
342 + self._entries = NULL
343 +
344 + def __init__(self, parent, entries, copy, coerce):
345 + """
346 + EXAMPLE::
347 +
348 + sage: K.<a> = GF(2^4)
349 + sage: l = [K.random_element() for _ in range(3*4)]; l
350 + [a^2 + 1, a^3 + 1, 0, 0, a, a^3 + a + 1, a + 1, a + 1, a^2, a^3 + a + 1, a^3 + a, a^3 + a]
351 +
352 + sage: A = Matrix(K, 3, 4, l); A
353 + [ a^2 + 1 a^3 + 1 0 0]
354 + [ a a^3 + a + 1 a + 1 a + 1]
355 + [ a^2 a^3 + a + 1 a^3 + a a^3 + a]
356 +
357 + sage: A.list()
358 + [a^2 + 1, a^3 + 1, 0, 0, a, a^3 + a + 1, a + 1, a + 1, a^2, a^3 + a + 1, a^3 + a, a^3 + a]
359 +
360 + sage: l[0], A[0,0]
361 + (a^2 + 1, a^2 + 1)
362 +
363 + sage: A = Matrix(K, 3, 3, a); A
364 + [a 0 0]
365 + [0 a 0]
366 + [0 0 a]
367 + """
368 + cdef int i,j
369 + cdef FiniteField_givaroElement e
370 +
371 + if entries is None:
372 + return
373 +
374 + R = self.base_ring()
375 +
376 + # scalar ?
377 + if not isinstance(entries, list):
378 + if entries != 0:
379 + if self.nrows() != self.ncols():
380 + raise TypeError("self must be a square matrices for scalar assignment")
381 + for i in range(self.nrows()):
382 + self.set_unsafe(i,i, R(entries))
383 + return
384 +
385 + # all entries are given as a long list
386 + if len(entries) != self._nrows * self._ncols:
387 + raise IndexError("The vector of entries has the wrong length.")
388 +
389 + k = 0
390 +
391 + for i from 0 <= i < self._nrows:
392 + if PyErr_CheckSignals(): raise KeyboardInterrupt
393 + for j from 0 <= j < self._ncols:
394 + e = R(entries[k])
395 +
396 + mzed_write_elem_log(self._entries,i,j, e.element, <M4RIE__FiniteField*>self.cc.objectptr)
397 + k = k + 1
398 +
399 + cdef set_unsafe(self, Py_ssize_t i, Py_ssize_t j, value):
400 + """
401 + EXAMPLE::
402 +
403 + sage: K.<a> = GF(2^4)
404 + sage: A = Matrix(K,3,4,[K.random_element() for _ in range(3*4)]); A
405 + [ a^2 + 1 a^3 + 1 0 0]
406 + [ a a^3 + a + 1 a + 1 a + 1]
407 + [ a^2 a^3 + a + 1 a^3 + a a^3 + a]
408 +
409 + sage: A[0,0] = a
410 + sage: A
411 + [ a a^3 + 1 0 0]
412 + [ a a^3 + a + 1 a + 1 a + 1]
413 + [ a^2 a^3 + a + 1 a^3 + a a^3 + a]
414 + """
415 + mzed_write_elem_log(self._entries, i, j, (<FiniteField_givaroElement>value).element, <M4RIE__FiniteField*>self.cc.objectptr)
416 +
417 + cdef get_unsafe(self, Py_ssize_t i, Py_ssize_t j):
418 + """
419 + EXAMPLE::
420 +
421 + sage: K.<a> = GF(2^4)
422 + sage: A = random_matrix(K,3,4)
423 + sage: A[2,3]
424 + a^3 + a + 1
425 + sage: K.<a> = GF(2^3)
426 + sage: m,n = 3, 4
427 + sage: A = random_matrix(K,3,4); A
428 + [a^2 + 1 0 a + 1 0]
429 + [ a a a + 1 a]
430 + [ 1 a^2 a^2 + a 0]
431 + """
432 + cdef int r = mzed_read_elem_log(self._entries, i, j, <M4RIE__FiniteField*>self.cc.objectptr)
433 + return self.cc._new_c(r)
434 +
435 +
436 + cpdef ModuleElement _add_(self, ModuleElement right):
437 + """
438 + EXAMPLE::
439 +
440 + sage: K.<a> = GF(2^4)
441 + sage: A = random_matrix(K,3,4); A
442 + [ a^2 + 1 a^3 + a^2 + a a^3 + a + 1 a + 1]
443 + [ a + 1 a + 1 a^3 + a a^3 + a^2]
444 + [a^3 + a^2 + a a 1 a^3 + a + 1]
445 +
446 + sage: B = random_matrix(K,3,4); B
447 + [ a^3 + 1 0 a^3 0]
448 + [ a^3 + a a a^3 + a^2 + a a^3 + a]
449 + [ a^3 + a + 1 a^2 a^3 + a^2 + a + 1 a^2 + 1]
450 +
451 + sage: C = A + B; C # indirect doctest
452 + [ a^3 + a^2 a^3 + a^2 + a a + 1 a + 1]
453 + [ a^3 + 1 1 a^2 a^2 + a]
454 + [ a^2 + 1 a^2 + a a^3 + a^2 + a a^3 + a^2 + a]
455 + """
456 + cdef Matrix_mod2e_dense A
457 + A = Matrix_mod2e_dense.__new__(Matrix_mod2e_dense, self._parent, 0, 0, 0, alloc=False)
458 + if self._nrows == 0 or self._ncols == 0:
459 + return A
460 + A._entries = mzed_add(NULL, self._entries, (<Matrix_mod2e_dense>right)._entries)
461 +
462 + return A
463 +
464 + cpdef ModuleElement _sub_(self, ModuleElement right):
465 + """
466 + EXAMPLE::
467 +
468 + sage: from sage.matrix.matrix_mod2e_dense import Matrix_mod2e_dense
469 + sage: K.<a> = GF(2^4)
470 + sage: m,n = 3, 4
471 + sage: MS = MatrixSpace(K,m,n)
472 + sage: A = random_matrix(K,3,4); A
473 + [ a^2 + 1 a^3 + a^2 + a a^3 + a + 1 a + 1]
474 + [ a + 1 a + 1 a^3 + a a^3 + a^2]
475 + [a^3 + a^2 + a a 1 a^3 + a + 1]
476 +
477 + sage: B = random_matrix(K,3,4); B
478 + [ a^3 + 1 0 a^3 0]
479 + [ a^3 + a a a^3 + a^2 + a a^3 + a]
480 + [ a^3 + a + 1 a^2 a^3 + a^2 + a + 1 a^2 + 1]
481 +
482 + sage: C = A - B; C # indirect doctest
483 + [ a^3 + a^2 a^3 + a^2 + a a + 1 a + 1]
484 + [ a^3 + 1 1 a^2 a^2 + a]
485 + [ a^2 + 1 a^2 + a a^3 + a^2 + a a^3 + a^2 + a]
486 + """
487 + return self._add_(right)
488 +
489 + cdef Matrix _matrix_times_matrix_(self, Matrix right):
490 + """
491 + Matrix multiplication.
492 +
493 + EXAMPLES::
494 +
495 + sage: K.<a> = GF(2^2)
496 + sage: A = random_matrix(K, 50, 50)
497 + sage: B = random_matrix(K, 50, 50)
498 + sage: A*B == A._multiply_classical(B)
499 + True
500 +
501 + sage: K.<a> = GF(2^4)
502 + sage: A = random_matrix(K, 50, 50)
503 + sage: B = random_matrix(K, 50, 50)
504 + sage: A*B == A._multiply_classical(B)
505 + True
506 +
507 + sage: K.<a> = GF(2^8)
508 + sage: A = random_matrix(K, 50, 50)
509 + sage: B = random_matrix(K, 50, 50)
510 + sage: A*B == A._multiply_classical(B)
511 + True
512 +
513 + sage: K.<a> = GF(2^10)
514 + sage: A = random_matrix(K, 50, 50)
515 + sage: B = random_matrix(K, 50, 50)
516 + sage: A*B == A._multiply_classical(B)
517 + True
518 + """
519 + if self._ncols != right._nrows:
520 + raise ArithmeticError("left ncols must match right nrows")
521 +
522 + cdef Matrix_mod2e_dense ans
523 +
524 + ans = self.new_matrix(nrows = self.nrows(), ncols = right.ncols())
525 + if self._nrows == 0 or self._ncols == 0 or right._ncols == 0:
526 + return ans
527 + ans._entries = mzed_mul_travolta(ans._entries, self._entries, (<Matrix_mod2e_dense>right)._entries)
528 + return ans
529 +
530 + def __neg__(self):
531 + """
532 + EXAMPLE::
533 +
534 + sage: K.<a> = GF(2^4)
535 + sage: A = random_matrix(K, 3, 4); A
536 + [ a^2 + 1 a^3 + a^2 + a a^3 + a + 1 a + 1]
537 + [ a + 1 a + 1 a^3 + a a^3 + a^2]
538 + [a^3 + a^2 + a a 1 a^3 + a + 1]
539 +
540 + sage: -A
541 + [ a^2 + 1 a^3 + a^2 + a a^3 + a + 1 a + 1]
542 + [ a + 1 a + 1 a^3 + a a^3 + a^2]
543 + [a^3 + a^2 + a a 1 a^3 + a + 1]
544 + """
545 + return self.__copy__()
546 +
547 + def __richcmp__(Matrix self, right, int op): # always need for mysterious reasons.
548 + """
549 + EXAMPLE::
550 +
551 + sage: K.<a> = GF(2^4)
552 + sage: A = random_matrix(K,3,4)
553 + sage: B = copy(A)
554 + sage: A == B
555 + True
556 + sage: A[0,0] = a
557 + sage: A == B
558 + False
559 + """
560 + return self._richcmp(right, op)
561 +
562 + cdef int _cmp_c_impl(self, Element right) except -2:
563 + if self._nrows == 0 or self._ncols == 0:
564 + return 0
565 + return mzed_cmp(self._entries, (<Matrix_mod2e_dense>right)._entries)
566 +
567 + def __copy__(self):
568 + """
569 + EXAMPLE::
570 +
571 + sage: K.<a> = GF(2^4)
572 + sage: m,n = 3, 4
573 + sage: A = random_matrix(K,3,4); A
574 + [ a^2 + 1 a^3 + a^2 + a a^3 + a + 1 a + 1]
575 + [ a + 1 a + 1 a^3 + a a^3 + a^2]
576 + [a^3 + a^2 + a a 1 a^3 + a + 1]
577 +
578 + sage: A2 = copy(A); A2
579 + [ a^2 + 1 a^3 + a^2 + a a^3 + a + 1 a + 1]
580 + [ a + 1 a + 1 a^3 + a a^3 + a^2]
581 + [a^3 + a^2 + a a 1 a^3 + a + 1]
582 +
583 + sage: A[0,0] = 1
584 + sage: A2[0,0]
585 + a^2 + 1
586 + """
587 + cdef Matrix_mod2e_dense A
588 + A = Matrix_mod2e_dense.__new__(Matrix_mod2e_dense, self._parent, 0, 0, 0)
589 +
590 + if self._nrows and self._ncols:
591 + mzed_copy(A._entries, <const_mzed_t *>self._entries)
592 +
593 + return A
594 +
595 + def _list(self):
596 + """
597 + EXAMPLE::
598 +
599 + sage: K.<a> = GF(2^4)
600 + sage: m,n = 3, 4
601 + sage: A = random_matrix(K,3,4); A
602 + [ a^2 + 1 a^3 + a^2 + a a^3 + a + 1 a + 1]
603 + [ a + 1 a + 1 a^3 + a a^3 + a^2]
604 + [a^3 + a^2 + a a 1 a^3 + a + 1]
605 +
606 + sage: A.list() # indirect doctest
607 + [a^2 + 1, a^3 + a^2 + a, a^3 + a + 1, a + 1, a + 1, a + 1, a^3 + a, a^3 + a^2, a^3 + a^2 + a, a, 1, a^3 + a + 1]
608 + """
609 + cdef int i,j
610 + l = []
611 + for i from 0 <= i < self._nrows:
612 + for j from 0 <= j < self._ncols:
613 + l.append(self.get_unsafe(i,j))
614 + return l
615 +
616 + def randomize(self, density=1, nonzero=False):
617 + """
618 + EXAMPLE::
619 +
620 + sage: K.<a> = GF(2^4)
621 + sage: A = Matrix(K,3,3)
622 +
623 + sage: A.randomize(); A
624 + [ a^2 + 1 a^3 + a^2 + a a^3 + a + 1]
625 + [ a + 1 a + 1 a + 1]
626 + [ a^3 + a a^3 + a^2 a^3 + a^2 + a]
627 + """
628 + cdef Py_ssize_t i,j
629 + cdef int seed = current_randstate().c_random()
630 + cdef GivRandom generator = GivRandomSeeded(seed)
631 + cdef int res
632 +
633 + if self._ncols == 0 or self._nrows == 0:
634 + return
635 +
636 + if density !=1:
637 + raise NotImplementedError
638 + for i in range(self._nrows):
639 + for j in range(self._ncols):
640 + res = self.cc.objectptr.random(generator,res)
641 + mzed_write_elem_log(self._entries, i, j, res, <M4RIE__FiniteField*>self.cc.objectptr)
642 +
643 +
644 + def echelonize(self, algorithm='heuristic', reduced=True, **kwds):
645 + """
646 + EXAMPLE::
647 +
648 + sage: K.<a> = GF(2^4)
649 + sage: m,n = 3, 5
650 + sage: A = random_matrix(K, 3, 5); A
651 + [ a^2 + 1 a^3 + a^2 + a a^3 + a + 1 a + 1 a + 1]
652 + [ a + 1 a^3 + a a^3 + a^2 a^3 + a^2 + a a]
653 + [ 1 a^3 + a + 1 a^3 + a^2 a^3 + a^2 + 1 a^2]
654 +
655 + sage: A.echelonize(); A
656 + [ 1 0 0 a a]
657 + [ 0 1 0 a^2 + a + 1 a]
658 + [ 0 0 1 a a^3 + a^2 + 1]
659 +
660 + sage: K.<a> = GF(2^3)
661 + sage: m,n = 3, 5
662 + sage: MS = MatrixSpace(K,m,n)
663 + sage: A = random_matrix(K, 3, 5)
664 +
665 + sage: copy(A).echelon_form('travolta')
666 + [ 1 0 0 a^2 a^2 + 1]
667 + [ 0 1 0 a^2 1]
668 + [ 0 0 1 a^2 + a + 1 a + 1]
669 +
670 + sage: copy(A).echelon_form('naive');
671 + [ 1 0 0 a^2 a^2 + 1]
672 + [ 0 1 0 a^2 1]
673 + [ 0 0 1 a^2 + a + 1 a + 1]
674 +
675 + sage: copy(A).echelon_form('builtin');
676 + [ 1 0 0 a^2 a^2 + 1]
677 + [ 0 1 0 a^2 1]
678 + [ 0 0 1 a^2 + a + 1 a + 1]
679 + """
680 + if self._nrows == 0 or self._ncols == 0:
681 + self.cache('in_echelon_form',True)
682 + self.cache('rank', 0)
683 + self.cache('pivots', [])
684 + return self
685 + cdef int k, n, full
686 +
687 + full = int(reduced)
688 +
689 + x = self.fetch('in_echelon_form')
690 + if not x is None: return # already known to be in echelon form
691 +
692 + if algorithm == 'naive':
693 + self.check_mutability()
694 + self.clear_cache()
695 +
696 + _sig_on
697 + r = mzed_echelonize_naive(self._entries, full)
698 + _sig_off
699 +
700 + self.cache('in_echelon_form',True)
701 + self.cache('rank', r)
702 + self.cache('pivots', self._pivots())
703 +
704 + elif algorithm == 'travolta':
705 + self.check_mutability()
706 + self.clear_cache()
707 +
708 + _sig_on
709 + r = mzed_echelonize_travolta(self._entries, full)
710 + _sig_off
711 +
712 + self.cache('in_echelon_form',True)
713 + self.cache('rank', r)
714 + self.cache('pivots', self._pivots())
715 +
716 + elif algorithm == 'heuristic':
717 + self.check_mutability()
718 + self.clear_cache()
719 +
720 + _sig_on
721 + r = mzed_echelonize(self._entries, full)
722 + _sig_off
723 +
724 + self.cache('in_echelon_form',True)
725 + self.cache('rank', r)
726 + self.cache('pivots', self._pivots())
727 +
728 + elif algorithm == 'builtin':
729 + self._echelon_in_place_classical()
730 + else:
731 + raise ValueError, "no algorithm '%s'"%algorithm
732 +
733 + def _pivots(self):
734 + """
735 + EXAMPLE::
736 +
737 + sage: K.<a> = GF(2^8)
738 + sage: A = random_matrix(K, 15, 15)
739 + sage: A.pivots() # indirect doctest
740 + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
741 + """
742 + if not self.fetch('in_echelon_form'):
743 + raise ValueError("self must be in reduced row echelon form first.")
744 + pivots = []
745 + cdef Py_ssize_t i, j, nc
746 + nc = self._ncols
747 + i = 0
748 + while i < self._nrows:
749 + for j from i <= j < nc:
750 + if self.get_unsafe(i,j):
751 + pivots.append(j)
752 + i += 1
753 + break
754 + if j == nc:
755 + break
756 + return pivots
757 +
758 + def __invert__(self):
759 + """
760 + EXAMPLE::
761 +
762 + sage: K.<a> = GF(2^3)
763 + sage: A = random_matrix(K,3,3); A
764 + [ 0 a + 1 1]
765 + [a^2 + a a^2 + a a^2 + a]
766 + [ a a^2 + 1 a + 1]
767 +
768 + sage: B = ~A; B
769 + [ a^2 0 a^2 + 1]
770 + [a^2 + a + 1 a^2 a^2 + a + 1]
771 + [ a + 1 a^2 + a + 1 a]
772 +
773 + sage: A*B
774 + [1 0 0]
775 + [0 1 0]
776 + [0 0 1]
777 + """
778 + cdef Matrix_mod2e_dense A
779 + A = Matrix_mod2e_dense.__new__(Matrix_mod2e_dense, self._parent, 0, 0, 0)
780 +
781 + if self._nrows and self._nrows == self._ncols:
782 + mzed_invert_travolta(A._entries, self._entries)
783 +
784 + return A
785 +
786 + cdef rescale_row_c(self, Py_ssize_t row, multiple, Py_ssize_t start_col):
787 + """
788 + EXAMPLE::
789 +
790 + sage: K.<a> = GF(2^3)
791 + sage: A = random_matrix(K,3,3); A
792 + [ 0 a + 1 1]
793 + [a^2 + a a^2 + a a^2 + a]
794 + [ a a^2 + 1 a + 1]
795 +
796 + sage: A.rescale_row(0, a , 0); A
797 + [ 0 a^2 + a a]
798 + [a^2 + a a^2 + a a^2 + a]
799 + [ a a^2 + 1 a + 1]
800 +
801 + sage: A.rescale_row(0,0,0); A
802 + [ 0 0 0]
803 + [a^2 + a a^2 + a a^2 + a]
804 + [ a a^2 + 1 a + 1]
805 + """
806 + cdef m4ri_word x = <m4ri_word>(<M4RIE__FiniteField*>self.cc.objectptr).log2pol((<FiniteField_givaroElement>multiple).element)
807 + cdef m4ri_word *X = self._entries.finite_field.mul[x]
808 + mzed_rescale_row(self._entries, row, start_col, X)
809 +
810 +
811 + cdef add_multiple_of_row_c(self, Py_ssize_t row_to, Py_ssize_t row_from, multiple, Py_ssize_t start_col):
812 + """
813 + EXAMPLE::
814 +
815 + sage: K.<a> = GF(2^3)
816 + sage: A = random_matrix(K,3,3); A
817 + [ 0 a + 1 1]
818 + [a^2 + a a^2 + a a^2 + a]
819 + [ a a^2 + 1 a + 1]
820 +
821 + sage: A.add_multiple_of_row(0,1,a,0); A
822 + [a^2 + a + 1 a^2 a^2 + a]
823 + [ a^2 + a a^2 + a a^2 + a]
824 + [ a a^2 + 1 a + 1]
825 + """
826 +
827 + cdef m4ri_word x = <m4ri_word>(<M4RIE__FiniteField*>self.cc.objectptr).log2pol((<FiniteField_givaroElement>multiple).element)
828 + cdef m4ri_word *X = self._entries.finite_field.mul[x]
829 + mzed_add_multiple_of_row(self._entries, row_to, self._entries, row_from, X, start_col)
830 +
831 +
832 + cdef swap_rows_c(self, Py_ssize_t row1, Py_ssize_t row2):
833 + """
834 + EXAMPLE::
835 +
836 + sage: K.<a> = GF(2^3)
837 + sage: A = random_matrix(K,3,3)
838 + sage: A
839 + [ 0 a + 1 1]
840 + [a^2 + a a^2 + a a^2 + a]
841 + [ a a^2 + 1 a + 1]
842 +
843 + sage: A.swap_rows(0,1); A
844 + [a^2 + a a^2 + a a^2 + a]
845 + [ 0 a + 1 1]
846 + [ a a^2 + 1 a + 1]
847 +
848 + """
849 + mzed_row_swap(self._entries, row1, row2)
850 +
851 + cdef swap_columns_c(self, Py_ssize_t col1, Py_ssize_t col2):
852 + """
853 + EXAMPLE::
854 +
855 + sage: K.<a> = GF(2^3)
856 + sage: A = random_matrix(K,3,3)
857 + sage: A
858 + [ 0 a + 1 1]
859 + [a^2 + a a^2 + a a^2 + a]
860 + [ a a^2 + 1 a + 1]
861 +
862 + sage: A.swap_columns(0,1); A
863 + [ a + 1 0 1]
864 + [a^2 + a a^2 + a a^2 + a]
865 + [a^2 + 1 a a + 1]
866 +
867 + sage: A = random_matrix(K,4,16)
868 +
869 + sage: B = copy(A)
870 + sage: B.swap_columns(0,1)
871 + sage: B.swap_columns(0,1)
872 + sage: A == B
873 + True
874 +
875 + sage: A.swap_columns(0,15)
876 + sage: A.column(0) == B.column(15)
877 + True
878 + sage: A.swap_columns(14,15)
879 + sage: A.column(14) == B.column(0)
880 + True
881 + """
882 + mzed_col_swap(self._entries, col1, col2)
883 +
884 + def augment(self, Matrix_mod2e_dense right):
885 + """
886 + Augments ``self`` with ``right``.
887 +
888 + EXAMPLE::
889 +
890 + sage: K.<a> = GF(2^4)
891 + sage: MS = MatrixSpace(K,3,3)
892 + sage: A = random_matrix(K,3,3)
893 + sage: B = A.augment(MS(1)); B
894 + [ a^2 + 1 a^3 + a^2 + a a^3 + a + 1 1 0 0]
895 + [ a + 1 a + 1 a + 1 0 1 0]
896 + [ a^3 + a a^3 + a^2 a^3 + a^2 + a 0 0 1]
897 +
898 + sage: B.echelonize(); B
899 + [ 1 0 0 a^3 + a^2 + 1 a^3 + a^2 + 1 a^2 + a]
900 + [ 0 1 0 a^3 + 1 a^2 + 1 a^2 + 1]
901 + [ 0 0 1 a^2 a^2 + a a + 1]
902 +
903 + sage: C = B.matrix_from_columns([3,4,5]); C
904 + [a^3 + a^2 + 1 a^3 + a^2 + 1 a^2 + a]
905 + [ a^3 + 1 a^2 + 1 a^2 + 1]
906 + [ a^2 a^2 + a a + 1]
907 +
908 + sage: C == ~A
909 + True
910 +
911 + sage: C*A == MS(1)
912 + True
913 +
914 + TESTS::
915 +
916 + sage: K.<a> = GF(2^4)
917 + sage: A = random_matrix(K,2,3)
918 + sage: B = random_matrix(K,2,0)
919 + sage: A.augment(B)
920 + [a^3 + 1 0 a^3]
921 + [ 0 a^3 + a a]
922 +
923 + sage: B.augment(A)
924 + [a^3 + 1 0 a^3]
925 + [ 0 a^3 + a a]
926 +
927 + sage: M = Matrix(K, 0, 0, 0)
928 + sage: N = Matrix(K, 0, 19, 0)
929 + sage: W = M.augment(N)
930 + sage: W.ncols()
931 + 19
932 +
933 + sage: M = Matrix(K, 0, 1, 0)
934 + sage: N = Matrix(K, 0, 1, 0)
935 + sage: M.augment(N)
936 + []
937 + """
938 + cdef Matrix_mod2e_dense A
939 +
940 + if self._nrows != right._nrows:
941 + raise TypeError, "Both numbers of rows must match."
942 +
943 + if self._ncols == 0:
944 + return right.__copy__()
945 + if right._ncols == 0:
946 + return self.__copy__()
947 +
948 + A = self.new_matrix(ncols = self._ncols + right._ncols)
949 + if self._nrows == 0:
950 + return A
951 + A._entries = mzed_concat(A._entries, self._entries, right._entries)
952 + return A
953 +
954 + def stack(self, Matrix_mod2e_dense other):
955 + """
956 + Stack ``self`` on top of ``other``.
957 +
958 + EXAMPLE::
959 +
960 + sage: K.<a> = GF(2^4)
961 + sage: A = random_matrix(K,2,2); A
962 + [ a^2 + 1 a^3 + a^2 + a]
963 + [ a^3 + a + 1 a + 1]
964 +
965 + sage: B = random_matrix(K,2,2); B
966 + [a^3 + 1 0]
967 + [ a^3 0]
968 +
969 + sage: A.stack(B)
970 + [ a^2 + 1 a^3 + a^2 + a]
971 + [ a^3 + a + 1 a + 1]
972 + [ a^3 + 1 0]
973 + [ a^3 0]
974 +
975 + sage: B.stack(A)
976 + [ a^3 + 1 0]
977 + [ a^3 0]
978 + [ a^2 + 1 a^3 + a^2 + a]
979 + [ a^3 + a + 1 a + 1]
980 +
981 + TESTS::
982 +
983 + sage: A = random_matrix(K,0,3)
984 + sage: B = random_matrix(K,3,3)
985 + sage: A.stack(B)
986 + [ 0 a^3 + a^2 + a a^2 + 1]
987 + [ a^3 + a^2 a^2 + 1 a^2]
988 + [ a^3 + a^2 a a^3 + a^2 + 1]
989 +
990 + sage: B.stack(A)
991 + [ 0 a^3 + a^2 + a a^2 + 1]
992 + [ a^3 + a^2 a^2 + 1 a^2]
993 + [ a^3 + a^2 a a^3 + a^2 + 1]
994 +
995 + sage: M = Matrix(K, 0, 0, 0)
996 + sage: N = Matrix(K, 19, 0, 0)
997 + sage: W = M.stack(N)
998 + sage: W.nrows()
999 + 19
1000 + sage: M = Matrix(K, 1, 0, 0)
1001 + sage: N = Matrix(K, 1, 0, 0)
1002 + sage: M.stack(N)
1003 + []
1004 + """
1005 + if self._ncols != other._ncols:
1006 + raise TypeError, "Both numbers of columns must match."
1007 +
1008 + if self._nrows == 0:
1009 + return other.__copy__()
1010 + if other._nrows == 0:
1011 + return self.__copy__()
1012 +
1013 + cdef Matrix_mod2e_dense A
1014 + A = self.new_matrix(nrows = self._nrows + other._nrows)
1015 + if self._ncols == 0:
1016 + return A
1017 + A._entries = mzed_stack(A._entries, self._entries, other._entries)
1018 + return A
1019 +
1020 + def submatrix(self, lowr, lowc, nrows , ncols):
1021 + """
1022 + Return submatrix from the index lowr,lowc (inclusive) with
1023 + dimension nrows x ncols.
1024 +
1025 + INPUT:
1026 +
1027 + - ``lowr`` -- index of start row
1028 + - ``lowc`` -- index of start column
1029 + - ``nrows`` -- number of rows of submatrix
1030 + - ``ncols`` -- number of columns of submatrix
1031 +
1032 + EXAMPLES::
1033 +
1034 + sage: K.<a> = GF(2^10)
1035 + sage: A = random_matrix(K,200,200)
1036 + sage: A[0:2,0:2] == A.submatrix(0,0,2,2)
1037 + True
1038 + sage: A[0:100,0:100] == A.submatrix(0,0,100,100)
1039 + True
1040 + sage: A == A.submatrix(0,0,200,200)
1041 + True
1042 +
1043 + sage: A[1:3,1:3] == A.submatrix(1,1,2,2)
1044 + True
1045 + sage: A[1:100,1:100] == A.submatrix(1,1,99,99)
1046 + True
1047 + sage: A[1:200,1:200] == A.submatrix(1,1,199,199)
1048 + True
1049 + """
1050 + cdef int highr = lowr + nrows
1051 + cdef int highc = lowc + ncols
1052 +
1053 + if nrows <= 0 or ncols <= 0:
1054 + raise TypeError("Expected nrows, ncols to be > 0, but got %d,%d instead."%(nrows, ncols))
1055 +
1056 + if highc > self._entries.ncols:
1057 + raise TypeError("Expected highc <= self.ncols(), but got %d > %d instead."%(highc, self._entries.ncols))
1058 +
1059 + if highr > self._entries.nrows:
1060 + raise TypeError("Expected highr <= self.nrows(), but got %d > %d instead."%(highr, self._entries.nrows))
1061 +
1062 + if lowr < 0:
1063 + raise TypeError("Expected lowr >= 0, but got %d instead."%lowr)
1064 +
1065 + if lowc < 0:
1066 + raise TypeError("Expected lowc >= 0, but got %d instead."%lowc)
1067 +
1068 + cdef Matrix_mod2e_dense A = self.new_matrix(nrows = nrows, ncols = ncols)
1069 + if self._ncols == 0 or self._nrows == 0:
1070 + return A
1071 + A._entries = mzed_submatrix(A._entries, self._entries, lowr, lowc, highr, highc)
1072 + return A
1073 +
1074 + def rank(self):
1075 + """
1076 + Return the rank of this matrix.
1077 +
1078 + EXAMPLE::
1079 +
1080 + sage: K.<a> = GF(2^4)
1081 + sage: A = random_matrix(K, 1000, 1000)
1082 + sage: A.rank()
1083 + 1000
1084 +
1085 + sage: A = matrix(K, 10, 0)
1086 + sage: A.rank()
1087 + 0
1088 + """
1089 + x = self.fetch('rank')
1090 + if not x is None:
1091 + return x
1092 + if self._nrows == 0 or self._ncols == 0:
1093 + return 0
1094 + cdef mzed_t *A = mzed_copy(NULL, self._entries)
1095 +
1096 + cdef size_t r = mzed_echelonize(A, 0)
1097 + mzed_free(A)
1098 + self.cache('rank', r)
1099 + return r
1100 +
1101 + def __reduce__(self):
1102 + """
1103 + EXAMPLE::
1104 + sage: K.<a> = GF(2^8)
1105 + sage: A = random_matrix(K,70,70)
1106 + sage: f, s= A.__reduce__()
1107 + sage: from sage.matrix.matrix_mod2e_dense import unpickle_matrix_mod2e_dense_v0
1108 + sage: f == unpickle_matrix_mod2e_dense_v0
1109 + True
1110 + sage: f(*s) == A
1111 + True
1112 + """
1113 + from sage.matrix.matrix_space import MatrixSpace
1114 +
1115 + cdef Matrix_mod2_dense A
1116 + MS = MatrixSpace(GF(2), self._entries.x.nrows, self._entries.x.ncols)
1117 + A = Matrix_mod2_dense.__new__(Matrix_mod2_dense, MS, 0, 0, 0, alloc = False)
1118 + A._entries = mzd_copy( NULL, self._entries.x)
1119 + return unpickle_matrix_mod2e_dense_v0, (A, self.base_ring(), self.nrows(), self.ncols())
1120 +
1121 +def unpickle_matrix_mod2e_dense_v0(Matrix_mod2_dense a, base_ring, nrows, ncols):
1122 + """
1123 + EXAMPLE::
1124 + sage: K.<a> = GF(2^2)
1125 + sage: A = random_matrix(K,10,10)
1126 + sage: f, s= A.__reduce__()
1127 + sage: from sage.matrix.matrix_mod2e_dense import unpickle_matrix_mod2e_dense_v0
1128 + sage: f == unpickle_matrix_mod2e_dense_v0
1129 + True
1130 + sage: f(*s) == A
1131 + True
1132 + """
1133 + from sage.matrix.matrix_space import MatrixSpace
1134 +
1135 + MS = MatrixSpace(base_ring, nrows, ncols)
1136 + cdef Matrix_mod2e_dense A = Matrix_mod2e_dense.__new__(Matrix_mod2e_dense, MS, 0, 0, 0)
1137 + mzd_copy(A._entries.x, a._entries)
1138 + return A
1139 diff -r 96e2020790df -r cc88353e2acb sage/matrix/matrix_space.py
1140 --- a/sage/matrix/matrix_space.py Mon Jun 28 23:27:14 2010 +0100
1141 +++ b/sage/matrix/matrix_space.py Tue Jul 20 16:19:49 2010 +0100
1142 @@ -38,7 +38,7 @@
1143 import matrix_modn_sparse
1144
1145 import matrix_mod2_dense
1146 -#import matrix_mod2_sparse
1147 +import matrix_mod2e_dense
1148
1149 import matrix_integer_dense
1150 import matrix_integer_sparse
1151 @@ -851,6 +851,8 @@
1152 if R.order() == 2:
1153 return matrix_mod2_dense.Matrix_mod2_dense
1154 return matrix_modn_dense.Matrix_modn_dense
1155 + elif sage.rings.finite_rings.all.is_FiniteField(R) and R.characteristic() == 2 and R.order() <= 1024:
1156 + return matrix_mod2e_dense.Matrix_mod2e_dense
1157 elif sage.rings.polynomial.multi_polynomial_ring_generic.is_MPolynomialRing(R) and R.base_ring().is_field():
1158 return matrix_mpolynomial_dense.Matrix_mpolynomial_dense
1159 #elif isinstance(R, sage.rings.padics.padic_ring_capped_relative.pAdicRingCappedRelative):
1160 diff -r 96e2020790df -r cc88353e2acb sage/rings/finite_rings/element_givaro.pxd
1161 --- a/sage/rings/finite_rings/element_givaro.pxd Mon Jun 28 23:27:14 2010 +0100
1162 +++ b/sage/rings/finite_rings/element_givaro.pxd Tue Jul 20 16:19:49 2010 +0100
1163 @@ -78,6 +78,7 @@
1164 cpdef int characteristic(self)
1165 cpdef FiniteField_givaroElement gen(self)
1166 cpdef FiniteField_givaroElement element_from_data(self, e)
1167 + cdef FiniteField_givaroElement _new_c(self, int value)
1168
1169 cdef class FiniteField_givaro_iterator:
1170 cdef int iterator
1171 diff -r 96e2020790df -r cc88353e2acb sage/rings/finite_rings/element_givaro.pyx
1172 --- a/sage/rings/finite_rings/element_givaro.pyx Mon Jun 28 23:27:14 2010 +0100
1173 +++ b/sage/rings/finite_rings/element_givaro.pyx Tue Jul 20 16:19:49 2010 +0100
1174 @@ -771,6 +771,9 @@
1175 rep = 'int'
1176 return unpickle_Cache_givaro, (self.parent, p, k, self.parent.polynomial(), rep, self._has_array)
1177
1178 + cdef FiniteField_givaroElement _new_c(self, int value):
1179 + return make_FiniteField_givaroElement(self, value)
1180 +
1181
1182 def unpickle_Cache_givaro(parent, p, k, modulus, rep, cache):
1183 """
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.