MCPcopy Create free account
hub / github.com/numpy/numpy / npyiter_flip_negative_strides

Function npyiter_flip_negative_strides

numpy/core/src/multiarray/nditer_constr.c:2155–2234  ·  view source on GitHub ↗

* This function negates any strides in the iterator * which are negative. When iterating more than one * object, it only flips strides when they are all * negative or zero. */

Source from the content-addressed store, hash-verified

2153 * negative or zero.
2154 */
2155static void
2156npyiter_flip_negative_strides(NpyIter *iter)
2157{
2158 npy_uint32 itflags = NIT_ITFLAGS(iter);
2159 int idim, ndim = NIT_NDIM(iter);
2160 int iop, nop = NIT_NOP(iter);
2161
2162 npy_intp istrides, nstrides = NAD_NSTRIDES();
2163 NpyIter_AxisData *axisdata, *axisdata0;
2164 npy_intp *baseoffsets;
2165 npy_intp sizeof_axisdata = NIT_AXISDATA_SIZEOF(itflags, ndim, nop);
2166 int any_flipped = 0;
2167
2168 axisdata0 = axisdata = NIT_AXISDATA(iter);
2169 baseoffsets = NIT_BASEOFFSETS(iter);
2170 for (idim = 0; idim < ndim; ++idim, NIT_ADVANCE_AXISDATA(axisdata, 1)) {
2171 npy_intp *strides = NAD_STRIDES(axisdata);
2172 int any_negative = 0;
2173
2174 /*
2175 * Check the signs of all the operand strides.
2176 */
2177 for (iop = 0; iop < nop; ++iop) {
2178 if (strides[iop] < 0) {
2179 any_negative = 1;
2180 }
2181 else if (strides[iop] != 0) {
2182 break;
2183 }
2184 }
2185 /*
2186 * If at least one stride is negative and none are positive,
2187 * flip all the strides for this dimension.
2188 */
2189 if (any_negative && iop == nop) {
2190 npy_intp shapem1 = NAD_SHAPE(axisdata) - 1;
2191
2192 for (istrides = 0; istrides < nstrides; ++istrides) {
2193 npy_intp stride = strides[istrides];
2194
2195 /* Adjust the base pointers to start at the end */
2196 baseoffsets[istrides] += shapem1 * stride;
2197 /* Flip the stride */
2198 strides[istrides] = -stride;
2199 }
2200 /*
2201 * Make the perm entry negative so get_multi_index
2202 * knows it's flipped
2203 */
2204 NIT_PERM(iter)[idim] = -1-NIT_PERM(iter)[idim];
2205
2206 any_flipped = 1;
2207 }
2208 }
2209
2210 /*
2211 * If any strides were flipped, the base pointers were adjusted
2212 * in the first AXISDATA, and need to be copied to all the rest

Callers 1

NpyIter_AdvancedNewFunction · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected