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

Function PyArray_CreateMultiSortedStridePerm

numpy/core/src/multiarray/shape.c:807–883  ·  view source on GitHub ↗

* Creates a sorted stride perm matching the KEEPORDER behavior * of the NpyIter object. Because this operates based on multiple * input strides, the 'stride' member of the npy_stride_sort_item * would be useless and we simply argsort a list of indices instead. * * The caller should have already validated that 'ndim' matches for * every array in the arrays list. */

Source from the content-addressed store, hash-verified

805 * every array in the arrays list.
806 */
807NPY_NO_EXPORT void
808PyArray_CreateMultiSortedStridePerm(int narrays, PyArrayObject **arrays,
809 int ndim, int *out_strideperm)
810{
811 int i0, i1, ipos, ax_j0, ax_j1, iarrays;
812
813 /* Initialize the strideperm values to the identity. */
814 for (i0 = 0; i0 < ndim; ++i0) {
815 out_strideperm[i0] = i0;
816 }
817
818 /*
819 * This is the same as the custom stable insertion sort in
820 * the NpyIter object, but sorting in the reverse order as
821 * in the iterator. The iterator sorts from smallest stride
822 * to biggest stride (Fortran order), whereas here we sort
823 * from biggest stride to smallest stride (C order).
824 */
825 for (i0 = 1; i0 < ndim; ++i0) {
826
827 ipos = i0;
828 ax_j0 = out_strideperm[i0];
829
830 for (i1 = i0 - 1; i1 >= 0; --i1) {
831 int ambig = 1, shouldswap = 0;
832
833 ax_j1 = out_strideperm[i1];
834
835 for (iarrays = 0; iarrays < narrays; ++iarrays) {
836 if (PyArray_SHAPE(arrays[iarrays])[ax_j0] != 1 &&
837 PyArray_SHAPE(arrays[iarrays])[ax_j1] != 1) {
838 if (s_intp_abs(PyArray_STRIDES(arrays[iarrays])[ax_j0]) <=
839 s_intp_abs(PyArray_STRIDES(arrays[iarrays])[ax_j1])) {
840 /*
841 * Set swap even if it's not ambiguous already,
842 * because in the case of conflicts between
843 * different operands, C-order wins.
844 */
845 shouldswap = 0;
846 }
847 else {
848 /* Only set swap if it's still ambiguous */
849 if (ambig) {
850 shouldswap = 1;
851 }
852 }
853
854 /*
855 * A comparison has been done, so it's
856 * no longer ambiguous
857 */
858 ambig = 0;
859 }
860 }
861 /*
862 * If the comparison was unambiguous, either shift
863 * 'ipos' to 'i1' or stop looking for an insertion point
864 */

Callers 1

Calls 3

PyArray_SHAPEFunction · 0.85
s_intp_absFunction · 0.85
PyArray_STRIDESFunction · 0.85

Tested by

no test coverage detected