NUMPY_API * Diagonal * * In NumPy versions prior to 1.7, this function always returned a copy of * the diagonal array. In 1.7, the code has been updated to compute a view * onto 'self', but it still copies this array before returning, as well as * setting the internal WARN_ON_WRITE flag. In a future version, it will * simply return a view onto self. */
| 2215 | * simply return a view onto self. |
| 2216 | */ |
| 2217 | NPY_NO_EXPORT PyObject * |
| 2218 | PyArray_Diagonal(PyArrayObject *self, int offset, int axis1, int axis2) |
| 2219 | { |
| 2220 | int i, idim, ndim = PyArray_NDIM(self); |
| 2221 | npy_intp *strides; |
| 2222 | npy_intp stride1, stride2, offset_stride; |
| 2223 | npy_intp *shape, dim1, dim2; |
| 2224 | |
| 2225 | char *data; |
| 2226 | npy_intp diag_size; |
| 2227 | PyArray_Descr *dtype; |
| 2228 | PyObject *ret; |
| 2229 | npy_intp ret_shape[NPY_MAXDIMS], ret_strides[NPY_MAXDIMS]; |
| 2230 | |
| 2231 | if (ndim < 2) { |
| 2232 | PyErr_SetString(PyExc_ValueError, |
| 2233 | "diag requires an array of at least two dimensions"); |
| 2234 | return NULL; |
| 2235 | } |
| 2236 | |
| 2237 | /* Handle negative axes with standard Python indexing rules */ |
| 2238 | if (check_and_adjust_axis_msg(&axis1, ndim, npy_ma_str_axis1) < 0) { |
| 2239 | return NULL; |
| 2240 | } |
| 2241 | if (check_and_adjust_axis_msg(&axis2, ndim, npy_ma_str_axis2) < 0) { |
| 2242 | return NULL; |
| 2243 | } |
| 2244 | if (axis1 == axis2) { |
| 2245 | PyErr_SetString(PyExc_ValueError, |
| 2246 | "axis1 and axis2 cannot be the same"); |
| 2247 | return NULL; |
| 2248 | } |
| 2249 | |
| 2250 | /* Get the shape and strides of the two axes */ |
| 2251 | shape = PyArray_SHAPE(self); |
| 2252 | dim1 = shape[axis1]; |
| 2253 | dim2 = shape[axis2]; |
| 2254 | strides = PyArray_STRIDES(self); |
| 2255 | stride1 = strides[axis1]; |
| 2256 | stride2 = strides[axis2]; |
| 2257 | |
| 2258 | /* Compute the data pointers and diag_size for the view */ |
| 2259 | data = PyArray_DATA(self); |
| 2260 | if (offset >= 0) { |
| 2261 | offset_stride = stride2; |
| 2262 | dim2 -= offset; |
| 2263 | } |
| 2264 | else { |
| 2265 | offset = -offset; |
| 2266 | offset_stride = stride1; |
| 2267 | dim1 -= offset; |
| 2268 | } |
| 2269 | diag_size = dim2 < dim1 ? dim2 : dim1; |
| 2270 | if (diag_size < 0) { |
| 2271 | diag_size = 0; |
| 2272 | } |
| 2273 | else { |
| 2274 | data += offset * offset_stride; |
no test coverage detected