|
1 | 1 | # sage.doctest: optional - numpy |
| 2 | +# cython: fast_getattr=False |
| 3 | +# https://github.com/cython/cython/issues/6442 |
2 | 4 | r""" |
3 | 5 | Utility functions for numpy. |
4 | 6 | """ |
5 | 7 |
|
6 | 8 | cimport numpy as np |
7 | 9 | import numpy as np |
8 | | -from sage.libs.m4ri cimport * |
9 | | -from libc.stdint cimport uintptr_t |
10 | 10 |
|
11 | 11 |
|
12 | 12 | ctypedef fused numpy_integral: |
@@ -64,3 +64,72 @@ cpdef int set_mzd_from_numpy(uintptr_t entries_addr, Py_ssize_t degree, x) excep |
64 | 64 | mzd_write_bit(entries, 0, i, x_bool[i]) |
65 | 65 | return True |
66 | 66 | return False |
| 67 | + |
| 68 | + |
| 69 | +cpdef int _set_matrix_mod2_from_numpy_helper(Matrix_mod2_dense a, np.ndarray[numpy_integral, ndim=2] b) except -1: |
| 70 | + """ |
| 71 | + Internal function, helper for :func:`set_matrix_mod2_from_numpy`. |
| 72 | +
|
| 73 | + TESTS:: |
| 74 | +
|
| 75 | + sage: from sage.modules.numpy_util import _set_matrix_mod2_from_numpy_helper |
| 76 | + sage: import numpy as np |
| 77 | + sage: a = matrix(GF(2), 2, 3) |
| 78 | + sage: b = np.array([[1, 0, 1], [0, 1, 0]], dtype=np.int8) |
| 79 | + sage: _set_matrix_mod2_from_numpy_helper(a, b) |
| 80 | + 1 |
| 81 | + sage: a |
| 82 | + [1 0 1] |
| 83 | + [0 1 0] |
| 84 | + sage: _set_matrix_mod2_from_numpy_helper(a, np.array([[1, 0], [0, 1]], dtype=np.int8)) |
| 85 | + Traceback (most recent call last): |
| 86 | + ... |
| 87 | + ValueError: shape mismatch |
| 88 | + """ |
| 89 | + if not (a.nrows() == b.shape[0] and a.ncols() == b.shape[1]): |
| 90 | + raise ValueError("shape mismatch") |
| 91 | + for i in range(b.shape[0]): |
| 92 | + for j in range(b.shape[1]): |
| 93 | + a.set_unsafe_int(i, j, b[i, j] & 1) |
| 94 | + return True |
| 95 | + |
| 96 | + |
| 97 | +cpdef int set_matrix_mod2_from_numpy(Matrix_mod2_dense a, b) except -1: |
| 98 | + """ |
| 99 | + Try to set the entries of a matrix from a numpy array. |
| 100 | +
|
| 101 | + INPUT: |
| 102 | +
|
| 103 | + - ``a`` -- the destination matrix |
| 104 | + - ``b`` -- a numpy array, must have dimension 2 and the same shape as ``a`` |
| 105 | +
|
| 106 | + OUTPUT: ``True`` (when used as bool) if successful, ``False`` otherwise. May throw ``ValueError``. |
| 107 | +
|
| 108 | + The exact type of the return value is not guaranteed, in the actual current implementation |
| 109 | + it is ``1`` for success and ``0`` for failure. |
| 110 | +
|
| 111 | + TESTS:: |
| 112 | +
|
| 113 | + sage: from sage.modules.numpy_util import set_matrix_mod2_from_numpy |
| 114 | + sage: import numpy as np |
| 115 | + sage: a = matrix(GF(2), 2, 3) |
| 116 | + sage: b = np.array([[1, 0, 1], [0, 1, 0]], dtype=np.int8) |
| 117 | + sage: set_matrix_mod2_from_numpy(a, b) |
| 118 | + 1 |
| 119 | + sage: a |
| 120 | + [1 0 1] |
| 121 | + [0 1 0] |
| 122 | + sage: set_matrix_mod2_from_numpy(a, np.array([[1, 0], [0, 1]], dtype=np.int8)) |
| 123 | + Traceback (most recent call last): |
| 124 | + ... |
| 125 | + ValueError: shape mismatch |
| 126 | + sage: # unsupported type (may be supported in the future) |
| 127 | + sage: set_matrix_mod2_from_numpy(a, np.array([[1, 1, 0], [0, 1, 0]], dtype=np.float64)) |
| 128 | + 0 |
| 129 | + sage: set_matrix_mod2_from_numpy(a, np.array([1, 0, 0], dtype=np.int8)) # wrong number of dimensions |
| 130 | + 0 |
| 131 | + """ |
| 132 | + try: |
| 133 | + return (<object>_set_matrix_mod2_from_numpy_helper)(a, b) # https://github.com/cython/cython/issues/6588 |
| 134 | + except TypeError: |
| 135 | + return False |
0 commit comments