passagemath-m4ri-m4rie 10.8.1rc0__cp312-cp312-win_amd64.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-m4ri-m4rie might be problematic. Click here for more details.
- passagemath_m4ri_m4rie/__init__.py +3 -0
- passagemath_m4ri_m4rie-10.8.1rc0.dist-info/DELVEWHEEL +2 -0
- passagemath_m4ri_m4rie-10.8.1rc0.dist-info/METADATA +107 -0
- passagemath_m4ri_m4rie-10.8.1rc0.dist-info/RECORD +31 -0
- passagemath_m4ri_m4rie-10.8.1rc0.dist-info/WHEEL +5 -0
- passagemath_m4ri_m4rie-10.8.1rc0.dist-info/top_level.txt +3 -0
- passagemath_m4ri_m4rie.libs/libgd-3-c61e7774529134604ac795e62efaf403.dll +0 -0
- passagemath_m4ri_m4rie.libs/libgmp-10-794009e46893ff9a2414ad67e43fe75c.dll +0 -0
- passagemath_m4ri_m4rie.libs/libiconv-2-ff31fa811f9c07cc7fdaa68c9e8bca3a.dll +0 -0
- passagemath_m4ri_m4rie.libs/libm4ri-2-9729666b38684339900e7e99b07c3429.dll +0 -0
- passagemath_m4ri_m4rie.libs/libm4rie-1-0fdffa6c128e9dab0da9764b26814f9c.dll +0 -0
- passagemath_m4ri_m4rie.libs/libpng16-16-435fb9547382c2a0ae933c65b9ae2dff.dll +0 -0
- passagemath_m4ri_m4rie.libs/zlib1-fc169cee00e737ab1f0556b1f633363b.dll +0 -0
- sage/all__sagemath_m4ri_m4rie.py +11 -0
- sage/libs/all__sagemath_m4ri_m4rie.py +1 -0
- sage/libs/m4ri.pxd +198 -0
- sage/libs/m4rie.pxd +206 -0
- sage/matrix/all__sagemath_m4ri_m4rie.py +1 -0
- sage/matrix/matrix_gf2e_dense.cp312-win_amd64.pyd +0 -0
- sage/matrix/matrix_gf2e_dense.pxd +14 -0
- sage/matrix/matrix_gf2e_dense.pyx +1749 -0
- sage/matrix/matrix_mod2_dense.cp312-win_amd64.pyd +0 -0
- sage/matrix/matrix_mod2_dense.pxd +14 -0
- sage/matrix/matrix_mod2_dense.pyx +2843 -0
- sage/modules/all__sagemath_m4ri_m4rie.py +1 -0
- sage/modules/numpy_util.cp312-win_amd64.pyd +0 -0
- sage/modules/numpy_util.pxd +10 -0
- sage/modules/numpy_util.pyx +136 -0
- sage/modules/vector_mod2_dense.cp312-win_amd64.pyd +0 -0
- sage/modules/vector_mod2_dense.pxd +11 -0
- sage/modules/vector_mod2_dense.pyx +547 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-m4ri-m4rie
|
|
Binary file
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-m4ri-m4rie
|
|
2
|
+
from libc.stdint cimport uintptr_t
|
|
3
|
+
from sage.libs.m4ri cimport *
|
|
4
|
+
from sage.matrix.matrix_mod2_dense cimport Matrix_mod2_dense
|
|
5
|
+
|
|
6
|
+
cpdef int set_matrix_mod2_from_numpy(Matrix_mod2_dense a, b) except -1
|
|
7
|
+
|
|
8
|
+
cpdef int set_mzd_from_numpy(uintptr_t entries_addr, Py_ssize_t degree, x) except -1
|
|
9
|
+
# Note: we don't actually need ``cimport`` to work, which means this header file is not used in practice
|
|
10
|
+
# neither do we need ``cpdef`` (``def`` is sufficient)
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-m4ri-m4rie
|
|
2
|
+
# sage.doctest: optional - numpy
|
|
3
|
+
# cython: fast_getattr=False
|
|
4
|
+
# https://github.com/cython/cython/issues/6442
|
|
5
|
+
r"""
|
|
6
|
+
Utility functions for numpy.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
cimport numpy as np
|
|
10
|
+
import numpy as np
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
ctypedef fused numpy_integral:
|
|
14
|
+
np.int8_t
|
|
15
|
+
np.int32_t
|
|
16
|
+
np.int64_t
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
cdef set_mzd_from_numpy_unsafe(mzd_t* entries, np.ndarray[numpy_integral, ndim=1] x):
|
|
20
|
+
"""
|
|
21
|
+
Internal function.
|
|
22
|
+
Caller are responsible for checking the two arrays have the same length.
|
|
23
|
+
"""
|
|
24
|
+
for i in range(len(x)):
|
|
25
|
+
mzd_write_bit(entries, 0, i, x[i] & 1)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
cpdef int set_mzd_from_numpy(uintptr_t entries_addr, Py_ssize_t degree, x) except -1:
|
|
29
|
+
"""
|
|
30
|
+
Set the entries in ``<mzd_t*>entries_addr`` from numpy array ``x``.
|
|
31
|
+
|
|
32
|
+
INPUT:
|
|
33
|
+
|
|
34
|
+
- ``entries_addr`` -- must be a ``mzd_t*`` casted to ``uintptr_t``; the casting
|
|
35
|
+
is necessary to pass it through Python boundary because of lazy import.
|
|
36
|
+
Do not pass arbitrary integer value here, will crash the program.
|
|
37
|
+
|
|
38
|
+
- ``degree`` -- the length of the array
|
|
39
|
+
|
|
40
|
+
- ``x`` -- a numpy array of integers or booleans, or any other object (in which
|
|
41
|
+
case this function will return ``False``)
|
|
42
|
+
|
|
43
|
+
OUTPUT: ``True`` if successful, ``False`` otherwise. May throw ``ValueError``.
|
|
44
|
+
"""
|
|
45
|
+
cdef Py_ssize_t i
|
|
46
|
+
cdef np.ndarray[np.npy_bool, ndim=1] x_bool
|
|
47
|
+
cdef mzd_t* entries = <mzd_t*>entries_addr
|
|
48
|
+
if isinstance(x, np.ndarray):
|
|
49
|
+
if x.ndim != 1:
|
|
50
|
+
raise ValueError("numpy array must have dimension 1")
|
|
51
|
+
if x.shape[0] != degree:
|
|
52
|
+
raise ValueError("numpy array must have the right length")
|
|
53
|
+
if x.dtype == np.int8:
|
|
54
|
+
set_mzd_from_numpy_unsafe(entries, <np.ndarray[np.int8_t, ndim=1]>x)
|
|
55
|
+
return True
|
|
56
|
+
if x.dtype == np.int32:
|
|
57
|
+
set_mzd_from_numpy_unsafe(entries, <np.ndarray[np.int32_t, ndim=1]>x)
|
|
58
|
+
return True
|
|
59
|
+
if x.dtype == np.int64:
|
|
60
|
+
set_mzd_from_numpy_unsafe(entries, <np.ndarray[np.int64_t, ndim=1]>x)
|
|
61
|
+
return True
|
|
62
|
+
if x.dtype == np.bool_:
|
|
63
|
+
x_bool = x
|
|
64
|
+
for i in range(degree):
|
|
65
|
+
mzd_write_bit(entries, 0, i, x_bool[i])
|
|
66
|
+
return True
|
|
67
|
+
return False
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
cpdef int _set_matrix_mod2_from_numpy_helper(Matrix_mod2_dense a, np.ndarray[numpy_integral, ndim=2] b) except -1:
|
|
71
|
+
"""
|
|
72
|
+
Internal function, helper for :func:`set_matrix_mod2_from_numpy`.
|
|
73
|
+
|
|
74
|
+
TESTS::
|
|
75
|
+
|
|
76
|
+
sage: from sage.modules.numpy_util import _set_matrix_mod2_from_numpy_helper
|
|
77
|
+
sage: import numpy as np
|
|
78
|
+
sage: a = matrix(GF(2), 2, 3)
|
|
79
|
+
sage: b = np.array([[1, 0, 1], [0, 1, 0]], dtype=np.int8)
|
|
80
|
+
sage: _set_matrix_mod2_from_numpy_helper(a, b)
|
|
81
|
+
1
|
|
82
|
+
sage: a
|
|
83
|
+
[1 0 1]
|
|
84
|
+
[0 1 0]
|
|
85
|
+
sage: _set_matrix_mod2_from_numpy_helper(a, np.array([[1, 0], [0, 1]], dtype=np.int8))
|
|
86
|
+
Traceback (most recent call last):
|
|
87
|
+
...
|
|
88
|
+
ValueError: shape mismatch
|
|
89
|
+
"""
|
|
90
|
+
if not (a.nrows() == b.shape[0] and a.ncols() == b.shape[1]):
|
|
91
|
+
raise ValueError("shape mismatch")
|
|
92
|
+
for i in range(b.shape[0]):
|
|
93
|
+
for j in range(b.shape[1]):
|
|
94
|
+
a.set_unsafe_int(i, j, b[i, j] & 1)
|
|
95
|
+
return True
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
cpdef int set_matrix_mod2_from_numpy(Matrix_mod2_dense a, b) except -1:
|
|
99
|
+
"""
|
|
100
|
+
Try to set the entries of a matrix from a numpy array.
|
|
101
|
+
|
|
102
|
+
INPUT:
|
|
103
|
+
|
|
104
|
+
- ``a`` -- the destination matrix
|
|
105
|
+
- ``b`` -- a numpy array, must have dimension 2 and the same shape as ``a``
|
|
106
|
+
|
|
107
|
+
OUTPUT: ``True`` (when used as bool) if successful, ``False`` otherwise. May throw ``ValueError``.
|
|
108
|
+
|
|
109
|
+
The exact type of the return value is not guaranteed, in the actual current implementation
|
|
110
|
+
it is ``1`` for success and ``0`` for failure.
|
|
111
|
+
|
|
112
|
+
TESTS::
|
|
113
|
+
|
|
114
|
+
sage: from sage.modules.numpy_util import set_matrix_mod2_from_numpy
|
|
115
|
+
sage: import numpy as np
|
|
116
|
+
sage: a = matrix(GF(2), 2, 3)
|
|
117
|
+
sage: b = np.array([[1, 0, 1], [0, 1, 0]], dtype=np.int8)
|
|
118
|
+
sage: set_matrix_mod2_from_numpy(a, b)
|
|
119
|
+
1
|
|
120
|
+
sage: a
|
|
121
|
+
[1 0 1]
|
|
122
|
+
[0 1 0]
|
|
123
|
+
sage: set_matrix_mod2_from_numpy(a, np.array([[1, 0], [0, 1]], dtype=np.int8))
|
|
124
|
+
Traceback (most recent call last):
|
|
125
|
+
...
|
|
126
|
+
ValueError: shape mismatch
|
|
127
|
+
sage: # unsupported type (may be supported in the future)
|
|
128
|
+
sage: set_matrix_mod2_from_numpy(a, np.array([[1, 1, 0], [0, 1, 0]], dtype=np.float64))
|
|
129
|
+
0
|
|
130
|
+
sage: set_matrix_mod2_from_numpy(a, np.array([1, 0, 0], dtype=np.int8)) # wrong number of dimensions
|
|
131
|
+
0
|
|
132
|
+
"""
|
|
133
|
+
try:
|
|
134
|
+
return (<object>_set_matrix_mod2_from_numpy_helper)(a, b) # https://github.com/cython/cython/issues/6588
|
|
135
|
+
except TypeError:
|
|
136
|
+
return False
|
|
Binary file
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-m4ri-m4rie
|
|
2
|
+
from sage.modules.free_module_element cimport FreeModuleElement
|
|
3
|
+
from sage.libs.m4ri cimport mzd_t
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
cdef class Vector_mod2_dense(FreeModuleElement):
|
|
7
|
+
cdef mzd_t* _entries
|
|
8
|
+
cdef object _base_ring
|
|
9
|
+
|
|
10
|
+
cdef _new_c(self)
|
|
11
|
+
cdef _init(self, Py_ssize_t degree, parent)
|
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-m4ri-m4rie
|
|
2
|
+
# distutils: libraries = M4RI_LIBRARIES GDLIB_LIBRARIES LIBPNG_LIBRARIES
|
|
3
|
+
# distutils: library_dirs = M4RI_LIBDIR GDLIB_LIBDIR LIBPNG_LIBDIR
|
|
4
|
+
# distutils: include_dirs = M4RI_INCDIR GDLIB_INCDIR LIBPNG_INCDIR
|
|
5
|
+
# distutils: extra_compile_args = M4RI_CFLAGS
|
|
6
|
+
|
|
7
|
+
r"""
|
|
8
|
+
Vectors with elements in `\GF{2}`
|
|
9
|
+
|
|
10
|
+
AUTHOR:
|
|
11
|
+
|
|
12
|
+
- Martin Albrecht (2009-12): initial implementation
|
|
13
|
+
- Thomas Feulner (2012-11): added :meth:`Vector_mod2_dense.hamming_weight`
|
|
14
|
+
|
|
15
|
+
EXAMPLES::
|
|
16
|
+
|
|
17
|
+
sage: VS = GF(2)^3
|
|
18
|
+
sage: e = VS.random_element()
|
|
19
|
+
sage: e.parent() is VS
|
|
20
|
+
True
|
|
21
|
+
sage: S = set(vector(v, immutable=True) for v in VS)
|
|
22
|
+
sage: S1 = set()
|
|
23
|
+
sage: while S != S1:
|
|
24
|
+
....: S1.add(vector(VS.random_element(), immutable=True))
|
|
25
|
+
|
|
26
|
+
TESTS::
|
|
27
|
+
|
|
28
|
+
sage: w = vector(GF(2), [-1,0,0,0])
|
|
29
|
+
sage: w.set_immutable()
|
|
30
|
+
sage: isinstance(hash(w), int)
|
|
31
|
+
True
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
# ****************************************************************************
|
|
35
|
+
# Copyright (C) 2009 Martin Albrecht <M.R.Albrecht@rhul.ac.uk>
|
|
36
|
+
#
|
|
37
|
+
# This program is free software: you can redistribute it and/or modify
|
|
38
|
+
# it under the terms of the GNU General Public License as published by
|
|
39
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
40
|
+
# (at your option) any later version.
|
|
41
|
+
# https://www.gnu.org/licenses/
|
|
42
|
+
# ****************************************************************************
|
|
43
|
+
|
|
44
|
+
from sage.rings.finite_rings.integer_mod cimport IntegerMod_int, IntegerMod_abstract
|
|
45
|
+
from sage.rings.integer cimport Integer
|
|
46
|
+
from sage.rings.rational cimport Rational
|
|
47
|
+
from sage.structure.element cimport Element, Vector
|
|
48
|
+
from sage.structure.richcmp cimport rich_to_bool
|
|
49
|
+
cimport sage.modules.free_module_element as free_module_element
|
|
50
|
+
from libc.stdint cimport uintptr_t
|
|
51
|
+
|
|
52
|
+
from sage.libs.m4ri cimport mzd_add, mzd_copy, mzd_cmp, mzd_free, mzd_init, mzd_set_ui, mzd_read_bit, mzd_row, mzd_write_bit, m4ri_word
|
|
53
|
+
|
|
54
|
+
cdef class Vector_mod2_dense(free_module_element.FreeModuleElement):
|
|
55
|
+
cdef _new_c(self):
|
|
56
|
+
"""
|
|
57
|
+
EXAMPLES::
|
|
58
|
+
|
|
59
|
+
sage: VS = VectorSpace(GF(2),3)
|
|
60
|
+
sage: VS([0,0,1])
|
|
61
|
+
(0, 0, 1)
|
|
62
|
+
sage: type(_)
|
|
63
|
+
<class 'sage.modules.vector_mod2_dense.Vector_mod2_dense'>
|
|
64
|
+
"""
|
|
65
|
+
cdef Vector_mod2_dense y
|
|
66
|
+
y = Vector_mod2_dense.__new__(Vector_mod2_dense)
|
|
67
|
+
y._init(self._degree, self._parent)
|
|
68
|
+
return y
|
|
69
|
+
|
|
70
|
+
cdef bint is_dense_c(self) noexcept:
|
|
71
|
+
"""
|
|
72
|
+
EXAMPLES::
|
|
73
|
+
|
|
74
|
+
sage: VS = VectorSpace(GF(2),3)
|
|
75
|
+
sage: VS([0,0,1]).is_dense()
|
|
76
|
+
True
|
|
77
|
+
"""
|
|
78
|
+
return 1
|
|
79
|
+
|
|
80
|
+
cdef bint is_sparse_c(self) noexcept:
|
|
81
|
+
"""
|
|
82
|
+
EXAMPLES::
|
|
83
|
+
|
|
84
|
+
sage: VS = VectorSpace(GF(2),3)
|
|
85
|
+
sage: VS([0,0,1]).is_sparse()
|
|
86
|
+
False
|
|
87
|
+
"""
|
|
88
|
+
return 0
|
|
89
|
+
|
|
90
|
+
def __copy__(self):
|
|
91
|
+
"""
|
|
92
|
+
EXAMPLES::
|
|
93
|
+
|
|
94
|
+
sage: VS = VectorSpace(GF(2),10^4)
|
|
95
|
+
sage: v = VS.random_element()
|
|
96
|
+
sage: w = copy(v)
|
|
97
|
+
sage: w == v
|
|
98
|
+
True
|
|
99
|
+
sage: v[:10] == w[:10]
|
|
100
|
+
True
|
|
101
|
+
sage: v[5] += 1
|
|
102
|
+
sage: v == w
|
|
103
|
+
False
|
|
104
|
+
"""
|
|
105
|
+
cdef Vector_mod2_dense y = self._new_c()
|
|
106
|
+
if self._degree:
|
|
107
|
+
mzd_copy(y._entries, self._entries)
|
|
108
|
+
return y
|
|
109
|
+
|
|
110
|
+
cdef _init(self, Py_ssize_t degree, parent):
|
|
111
|
+
"""
|
|
112
|
+
EXAMPLES::
|
|
113
|
+
|
|
114
|
+
sage: VS = VectorSpace(GF(2),3)
|
|
115
|
+
sage: VS([0,0,1])
|
|
116
|
+
(0, 0, 1)
|
|
117
|
+
sage: type(_)
|
|
118
|
+
<class 'sage.modules.vector_mod2_dense.Vector_mod2_dense'>
|
|
119
|
+
"""
|
|
120
|
+
self._degree = degree
|
|
121
|
+
self._parent = parent
|
|
122
|
+
self._base_ring = parent.base_ring()
|
|
123
|
+
self._entries = mzd_init(1, degree)
|
|
124
|
+
if self._entries == NULL:
|
|
125
|
+
raise MemoryError("Allocation of Vector_mod2_dense failed.")
|
|
126
|
+
|
|
127
|
+
def __cinit__(self, parent=None, x=None, coerce=True, copy=True):
|
|
128
|
+
"""
|
|
129
|
+
EXAMPLES::
|
|
130
|
+
|
|
131
|
+
sage: VS = VectorSpace(GF(2),3)
|
|
132
|
+
sage: VS((0,0,1/3))
|
|
133
|
+
(0, 0, 1)
|
|
134
|
+
sage: type(_)
|
|
135
|
+
<class 'sage.modules.vector_mod2_dense.Vector_mod2_dense'>
|
|
136
|
+
"""
|
|
137
|
+
self._entries = NULL
|
|
138
|
+
self._is_immutable = 0
|
|
139
|
+
if parent is not None:
|
|
140
|
+
self._init(parent.degree(), parent)
|
|
141
|
+
|
|
142
|
+
def __init__(self, parent, x, coerce=True, copy=True):
|
|
143
|
+
"""
|
|
144
|
+
EXAMPLES::
|
|
145
|
+
|
|
146
|
+
sage: VS = VectorSpace(GF(2),3)
|
|
147
|
+
sage: VS((0,0,1/3))
|
|
148
|
+
(0, 0, 1)
|
|
149
|
+
sage: type(_)
|
|
150
|
+
<class 'sage.modules.vector_mod2_dense.Vector_mod2_dense'>
|
|
151
|
+
sage: VS((0,0,int(3)))
|
|
152
|
+
(0, 0, 1)
|
|
153
|
+
sage: VS((0,0,3))
|
|
154
|
+
(0, 0, 1)
|
|
155
|
+
sage: VS((0,0,GF(2)(1)))
|
|
156
|
+
(0, 0, 1)
|
|
157
|
+
|
|
158
|
+
TESTS:
|
|
159
|
+
|
|
160
|
+
Check that issue :issue:`8601` is fixed::
|
|
161
|
+
|
|
162
|
+
sage: VS = VectorSpace(GF(2), 3)
|
|
163
|
+
sage: VS((-1,-2,-3))
|
|
164
|
+
(1, 0, 1)
|
|
165
|
+
sage: V = VectorSpace(GF(2), 2)
|
|
166
|
+
sage: V([1,3])
|
|
167
|
+
(1, 1)
|
|
168
|
+
sage: V([1,-3])
|
|
169
|
+
(1, 1)
|
|
170
|
+
|
|
171
|
+
Check integer overflow prior to :issue:`21746`::
|
|
172
|
+
|
|
173
|
+
sage: VS = VectorSpace(GF(2),1)
|
|
174
|
+
sage: VS([2**64])
|
|
175
|
+
(0)
|
|
176
|
+
sage: VS([3**100/5**100])
|
|
177
|
+
(1)
|
|
178
|
+
|
|
179
|
+
Check division error over rationals::
|
|
180
|
+
|
|
181
|
+
sage: V = VectorSpace(GF(2), 2)
|
|
182
|
+
sage: V([1/3, 3/4])
|
|
183
|
+
Traceback (most recent call last):
|
|
184
|
+
...
|
|
185
|
+
ZeroDivisionError: inverse does not exist
|
|
186
|
+
|
|
187
|
+
Check zero initialization::
|
|
188
|
+
|
|
189
|
+
sage: for _ in range(1,100):
|
|
190
|
+
....: assert VectorSpace(GF(2), randint(1,5000))(0).is_zero()
|
|
191
|
+
sage: (GF(2)**5)(1)
|
|
192
|
+
Traceback (most recent call last):
|
|
193
|
+
...
|
|
194
|
+
TypeError: can...t initialize vector from nonzero non-list
|
|
195
|
+
sage: (GF(2)**0).zero_vector()
|
|
196
|
+
()
|
|
197
|
+
|
|
198
|
+
Check construction from numpy arrays::
|
|
199
|
+
|
|
200
|
+
sage: # needs numpy
|
|
201
|
+
sage: import numpy
|
|
202
|
+
sage: VS = VectorSpace(GF(2),3)
|
|
203
|
+
sage: VS(numpy.array([0,-3,7], dtype=numpy.int8))
|
|
204
|
+
(0, 1, 1)
|
|
205
|
+
sage: VS(numpy.array([0,-3,7], dtype=numpy.int32))
|
|
206
|
+
(0, 1, 1)
|
|
207
|
+
sage: VS(numpy.array([0,-3,7], dtype=numpy.int64))
|
|
208
|
+
(0, 1, 1)
|
|
209
|
+
sage: VS(numpy.array([False,True,False], dtype=bool))
|
|
210
|
+
(0, 1, 0)
|
|
211
|
+
sage: VS(numpy.array([[1]]))
|
|
212
|
+
Traceback (most recent call last):
|
|
213
|
+
...
|
|
214
|
+
ValueError: numpy array must have dimension 1
|
|
215
|
+
sage: VS(numpy.array([1,2,3,4]))
|
|
216
|
+
Traceback (most recent call last):
|
|
217
|
+
...
|
|
218
|
+
ValueError: numpy array must have the right length
|
|
219
|
+
|
|
220
|
+
Make sure it's reasonably fast::
|
|
221
|
+
|
|
222
|
+
sage: # needs numpy
|
|
223
|
+
sage: import numpy
|
|
224
|
+
sage: VS = VectorSpace(GF(2),2*10^7)
|
|
225
|
+
sage: v = VS(numpy.random.randint(0, 1, size=VS.dimension())) # around 300ms
|
|
226
|
+
"""
|
|
227
|
+
try:
|
|
228
|
+
import numpy
|
|
229
|
+
except ImportError:
|
|
230
|
+
pass
|
|
231
|
+
else:
|
|
232
|
+
from .numpy_util import set_mzd_from_numpy
|
|
233
|
+
if set_mzd_from_numpy(<uintptr_t>self._entries, self._degree, x):
|
|
234
|
+
return
|
|
235
|
+
if isinstance(x, (list, tuple)):
|
|
236
|
+
if len(x) != self._degree:
|
|
237
|
+
raise TypeError("x must be a list of the right length")
|
|
238
|
+
for i in range(len(x)):
|
|
239
|
+
xi = x[i]
|
|
240
|
+
if isinstance(xi, (IntegerMod_int, int, Integer)):
|
|
241
|
+
# the if/else statement is because in some compilers, (-1)%2 is -1
|
|
242
|
+
mzd_write_bit(self._entries, 0, i, 1 if xi % 2 else 0)
|
|
243
|
+
elif isinstance(xi, Rational):
|
|
244
|
+
if not (xi.denominator() % 2):
|
|
245
|
+
raise ZeroDivisionError("inverse does not exist")
|
|
246
|
+
mzd_write_bit(self._entries, 0, i, 1 if (xi.numerator() % 2) else 0)
|
|
247
|
+
else:
|
|
248
|
+
mzd_write_bit(self._entries, 0, i, xi % 2)
|
|
249
|
+
elif x != 0:
|
|
250
|
+
raise TypeError("can't initialize vector from nonzero non-list")
|
|
251
|
+
elif self._degree:
|
|
252
|
+
mzd_set_ui(self._entries, 0)
|
|
253
|
+
|
|
254
|
+
def __dealloc__(self):
|
|
255
|
+
"""
|
|
256
|
+
EXAMPLES::
|
|
257
|
+
|
|
258
|
+
sage: VS = VectorSpace(GF(2),10^3)
|
|
259
|
+
sage: import gc
|
|
260
|
+
sage: for i in range(10):
|
|
261
|
+
....: v = VS.random_element()
|
|
262
|
+
....: del v
|
|
263
|
+
....: _ = gc.collect()
|
|
264
|
+
"""
|
|
265
|
+
if self._entries:
|
|
266
|
+
mzd_free(self._entries)
|
|
267
|
+
|
|
268
|
+
cpdef _richcmp_(left, right, int op):
|
|
269
|
+
"""
|
|
270
|
+
EXAMPLES::
|
|
271
|
+
|
|
272
|
+
sage: v = vector(GF(2), [0,0,0,0])
|
|
273
|
+
sage: v == 0
|
|
274
|
+
True
|
|
275
|
+
sage: v == 1
|
|
276
|
+
False
|
|
277
|
+
sage: v == v
|
|
278
|
+
True
|
|
279
|
+
sage: w = vector(GF(2), [1,0,0,0])
|
|
280
|
+
sage: w < v
|
|
281
|
+
False
|
|
282
|
+
sage: w > v
|
|
283
|
+
True
|
|
284
|
+
sage: w = vector(GF(2), [-1,0,0,0])
|
|
285
|
+
sage: w == w
|
|
286
|
+
True
|
|
287
|
+
"""
|
|
288
|
+
cdef int c
|
|
289
|
+
if left._degree == 0:
|
|
290
|
+
return rich_to_bool(op, 0)
|
|
291
|
+
c = mzd_cmp(left._entries, (<Vector_mod2_dense>right)._entries)
|
|
292
|
+
return rich_to_bool(op, c)
|
|
293
|
+
|
|
294
|
+
cdef get_unsafe(self, Py_ssize_t i):
|
|
295
|
+
"""
|
|
296
|
+
EXAMPLES::
|
|
297
|
+
|
|
298
|
+
sage: v = vector(GF(2), [1,2,3]); v
|
|
299
|
+
(1, 0, 1)
|
|
300
|
+
sage: v[0]
|
|
301
|
+
1
|
|
302
|
+
sage: v[2]
|
|
303
|
+
1
|
|
304
|
+
sage: v[-2]
|
|
305
|
+
0
|
|
306
|
+
sage: v[0:2]
|
|
307
|
+
(1, 0)
|
|
308
|
+
"""
|
|
309
|
+
return self._base_ring(mzd_read_bit(self._entries, 0, i))
|
|
310
|
+
|
|
311
|
+
cdef int set_unsafe(self, Py_ssize_t i, value) except -1:
|
|
312
|
+
"""
|
|
313
|
+
EXAMPLES::
|
|
314
|
+
|
|
315
|
+
sage: VS = VectorSpace(GF(2),4)
|
|
316
|
+
sage: v = VS.random_element()
|
|
317
|
+
sage: v[0] = 0; v[0]
|
|
318
|
+
0
|
|
319
|
+
sage: v[1:3] = [1, 1]; v[1:3]
|
|
320
|
+
(1, 1)
|
|
321
|
+
sage: v[3] = 0; v
|
|
322
|
+
(0, 1, 1, 0)
|
|
323
|
+
sage: v[4] = 0
|
|
324
|
+
Traceback (most recent call last):
|
|
325
|
+
...
|
|
326
|
+
IndexError: vector index out of range
|
|
327
|
+
"""
|
|
328
|
+
mzd_write_bit(self._entries, 0, i, value)
|
|
329
|
+
|
|
330
|
+
def __reduce__(self):
|
|
331
|
+
"""
|
|
332
|
+
EXAMPLES::
|
|
333
|
+
|
|
334
|
+
sage: VS = VectorSpace(GF(2),10^4)
|
|
335
|
+
sage: e = VS.random_element()
|
|
336
|
+
sage: loads(dumps(e)) == e
|
|
337
|
+
True
|
|
338
|
+
"""
|
|
339
|
+
return unpickle_v0, (self._parent, self.list(), self._degree,
|
|
340
|
+
self._is_immutable)
|
|
341
|
+
|
|
342
|
+
cpdef _add_(self, right):
|
|
343
|
+
"""
|
|
344
|
+
EXAMPLES::
|
|
345
|
+
|
|
346
|
+
sage: VS = VectorSpace(GF(2),10)
|
|
347
|
+
sage: e = VS([0,0,1,1,0,0,1,1,0,0])
|
|
348
|
+
sage: f = VS([0,1,0,1,0,1,0,1,0,1])
|
|
349
|
+
sage: e + f #indirect doctest
|
|
350
|
+
(0, 1, 1, 0, 0, 1, 1, 0, 0, 1)
|
|
351
|
+
"""
|
|
352
|
+
cdef Vector_mod2_dense z = self._new_c()
|
|
353
|
+
if self._degree:
|
|
354
|
+
mzd_add(z._entries, self._entries, (<Vector_mod2_dense>right)._entries)
|
|
355
|
+
return z
|
|
356
|
+
|
|
357
|
+
cpdef _sub_(self, right):
|
|
358
|
+
"""
|
|
359
|
+
EXAMPLES::
|
|
360
|
+
|
|
361
|
+
sage: VS = VectorSpace(GF(2),10)
|
|
362
|
+
sage: e = VS([0,0,1,1,0,0,1,1,0,0])
|
|
363
|
+
sage: f = VS([0,1,0,1,0,1,0,1,0,1])
|
|
364
|
+
sage: e - f #indirect doctest
|
|
365
|
+
(0, 1, 1, 0, 0, 1, 1, 0, 0, 1)
|
|
366
|
+
"""
|
|
367
|
+
cdef Vector_mod2_dense z = self._new_c()
|
|
368
|
+
if self._degree:
|
|
369
|
+
mzd_add(z._entries, self._entries, (<Vector_mod2_dense>right)._entries)
|
|
370
|
+
return z
|
|
371
|
+
|
|
372
|
+
cpdef int hamming_weight(self) noexcept:
|
|
373
|
+
"""
|
|
374
|
+
Return the number of positions ``i`` such that ``self[i] != 0``.
|
|
375
|
+
|
|
376
|
+
EXAMPLES::
|
|
377
|
+
|
|
378
|
+
sage: vector(GF(2), [1,1,0]).hamming_weight()
|
|
379
|
+
2
|
|
380
|
+
"""
|
|
381
|
+
cdef int i
|
|
382
|
+
cdef int res = 0
|
|
383
|
+
cdef m4ri_word *row = mzd_row(self._entries, 0)
|
|
384
|
+
for i in range(self._entries.width):
|
|
385
|
+
res += Integer(row[i]).popcount()
|
|
386
|
+
return res
|
|
387
|
+
|
|
388
|
+
cpdef _dot_product_(self, Vector right):
|
|
389
|
+
"""
|
|
390
|
+
EXAMPLES::
|
|
391
|
+
|
|
392
|
+
sage: VS = VectorSpace(GF(2),3)
|
|
393
|
+
sage: v = VS([1,1,1]); w = VS([0,0,0])
|
|
394
|
+
sage: v * w, w * v #indirect doctest
|
|
395
|
+
(0, 0)
|
|
396
|
+
sage: v = VS([1,1,1]); w = VS([0,1,0])
|
|
397
|
+
sage: v * w, w * v
|
|
398
|
+
(1, 1)
|
|
399
|
+
sage: v = VS([1,1,1]); w = VS([0,1,1])
|
|
400
|
+
sage: v * w, w * v
|
|
401
|
+
(0, 0)
|
|
402
|
+
sage: v = VS([1,1,1]); w = VS([1,1,1])
|
|
403
|
+
sage: v * w, w * v
|
|
404
|
+
(1, 1)
|
|
405
|
+
|
|
406
|
+
sage: VS = VectorSpace(GF(2),10^4)
|
|
407
|
+
sage: v = VS(0); w = VS(0)
|
|
408
|
+
sage: v[1337] = 1; w[1337] = 1
|
|
409
|
+
sage: v * w, w * v
|
|
410
|
+
(1, 1)
|
|
411
|
+
sage: v[9881] = 1; w[9881] = 1
|
|
412
|
+
sage: v * w, w * v
|
|
413
|
+
(0, 0)
|
|
414
|
+
sage: v[5172] = 1; w[6178] = 1
|
|
415
|
+
sage: v * w, w * v
|
|
416
|
+
(0, 0)
|
|
417
|
+
"""
|
|
418
|
+
cdef Py_ssize_t i
|
|
419
|
+
cdef IntegerMod_int n
|
|
420
|
+
cdef Vector_mod2_dense r = right
|
|
421
|
+
cdef m4ri_word tmp = 0
|
|
422
|
+
n = IntegerMod_int.__new__(IntegerMod_int)
|
|
423
|
+
IntegerMod_abstract.__init__(n, self.base_ring())
|
|
424
|
+
n.ivalue = 0
|
|
425
|
+
cdef m4ri_word *lrow = mzd_row(self._entries, 0)
|
|
426
|
+
cdef m4ri_word *rrow = mzd_row(r._entries, 0)
|
|
427
|
+
for i in range(self._entries.width):
|
|
428
|
+
tmp ^= lrow[i] & rrow[i]
|
|
429
|
+
|
|
430
|
+
for i in range(64):
|
|
431
|
+
n.ivalue ^= <int>(tmp & 1)
|
|
432
|
+
tmp = tmp >> 1
|
|
433
|
+
|
|
434
|
+
return n
|
|
435
|
+
|
|
436
|
+
cpdef _pairwise_product_(self, Vector right):
|
|
437
|
+
"""
|
|
438
|
+
EXAMPLES::
|
|
439
|
+
|
|
440
|
+
sage: VS = VectorSpace(GF(2),10)
|
|
441
|
+
sage: e = VS.random_element()
|
|
442
|
+
sage: f = VS.random_element()
|
|
443
|
+
sage: g = e.pairwise_product(f) #indirect doctest
|
|
444
|
+
sage: all(g[i] == e[i]*f[i] for i in range(10))
|
|
445
|
+
True
|
|
446
|
+
"""
|
|
447
|
+
cdef Vector_mod2_dense z, r
|
|
448
|
+
r = right
|
|
449
|
+
z = self._new_c()
|
|
450
|
+
cdef Py_ssize_t i
|
|
451
|
+
cdef m4ri_word *lrow = mzd_row(self._entries, 0)
|
|
452
|
+
cdef m4ri_word *rrow = mzd_row(r._entries, 0)
|
|
453
|
+
cdef m4ri_word *zrow = mzd_row(z._entries, 0)
|
|
454
|
+
for i in range(self._entries.width):
|
|
455
|
+
zrow[i] = (lrow[i] & rrow[i])
|
|
456
|
+
return z
|
|
457
|
+
|
|
458
|
+
cpdef _lmul_(self, Element left):
|
|
459
|
+
"""
|
|
460
|
+
EXAMPLES::
|
|
461
|
+
|
|
462
|
+
sage: VS = VectorSpace(GF(2),10)
|
|
463
|
+
sage: e = VS.random_element()
|
|
464
|
+
sage: 0 * e
|
|
465
|
+
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
466
|
+
sage: 1 * e == e
|
|
467
|
+
True
|
|
468
|
+
sage: 2 * e # indirect doctest
|
|
469
|
+
(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
470
|
+
|
|
471
|
+
::
|
|
472
|
+
|
|
473
|
+
sage: VS = VectorSpace(GF(2), 100)
|
|
474
|
+
sage: e = VS.random_element()
|
|
475
|
+
sage: e * 0 == 0 # indirect doctest
|
|
476
|
+
True
|
|
477
|
+
sage: e * 1 == e
|
|
478
|
+
True
|
|
479
|
+
sage: e * 2 == 0
|
|
480
|
+
True
|
|
481
|
+
"""
|
|
482
|
+
if left:
|
|
483
|
+
return self.__copy__()
|
|
484
|
+
return self._new_c()
|
|
485
|
+
|
|
486
|
+
cpdef _neg_(self):
|
|
487
|
+
"""
|
|
488
|
+
EXAMPLES::
|
|
489
|
+
|
|
490
|
+
sage: VS = VectorSpace(GF(2),10)
|
|
491
|
+
sage: e = VS.random_element()
|
|
492
|
+
sage: -e == e
|
|
493
|
+
True
|
|
494
|
+
"""
|
|
495
|
+
return self.__copy__()
|
|
496
|
+
|
|
497
|
+
def list(self, copy=True):
|
|
498
|
+
"""
|
|
499
|
+
Return a list of entries in ``self``.
|
|
500
|
+
|
|
501
|
+
INPUT:
|
|
502
|
+
|
|
503
|
+
- ``copy`` -- always ``True``
|
|
504
|
+
|
|
505
|
+
EXAMPLES::
|
|
506
|
+
|
|
507
|
+
sage: VS = VectorSpace(GF(2), 10)
|
|
508
|
+
sage: entries = [GF(2).random_element() for _ in range(10)]
|
|
509
|
+
sage: e = VS(entries)
|
|
510
|
+
sage: e.list() == entries
|
|
511
|
+
True
|
|
512
|
+
"""
|
|
513
|
+
cdef Py_ssize_t d = self._degree
|
|
514
|
+
cdef Py_ssize_t i
|
|
515
|
+
cdef list v = [0]*d
|
|
516
|
+
K = self.base_ring()
|
|
517
|
+
z = K.zero()
|
|
518
|
+
o = K.one()
|
|
519
|
+
cdef list switch = [z, o]
|
|
520
|
+
for i in range(d):
|
|
521
|
+
v[i] = switch[mzd_read_bit(self._entries, 0, i)]
|
|
522
|
+
return v
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
def unpickle_v0(parent, entries, degree, is_immutable):
|
|
526
|
+
"""
|
|
527
|
+
EXAMPLES::
|
|
528
|
+
|
|
529
|
+
sage: from sage.modules.vector_mod2_dense import unpickle_v0
|
|
530
|
+
sage: VS = VectorSpace(GF(2),10)
|
|
531
|
+
sage: unpickle_v0(VS, [0,1,2,3,4,5,6,7,8,9], 10, 0)
|
|
532
|
+
(0, 1, 0, 1, 0, 1, 0, 1, 0, 1)
|
|
533
|
+
"""
|
|
534
|
+
# If you think you want to change this function, don't.
|
|
535
|
+
cdef Vector_mod2_dense v
|
|
536
|
+
v = Vector_mod2_dense.__new__(Vector_mod2_dense)
|
|
537
|
+
v._init(degree, parent)
|
|
538
|
+
cdef int xi
|
|
539
|
+
|
|
540
|
+
for i in range(degree):
|
|
541
|
+
if isinstance(entries[i], (IntegerMod_int, int, Integer)):
|
|
542
|
+
xi = entries[i]
|
|
543
|
+
mzd_write_bit(v._entries, 0, i, xi % 2)
|
|
544
|
+
else:
|
|
545
|
+
mzd_write_bit(v._entries, 0, i, entries[i] % 2)
|
|
546
|
+
v._is_immutable = int(is_immutable)
|
|
547
|
+
return v
|