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

Function solve_may_have_internal_overlap

numpy/core/src/common/mem_overlap.c:848–923  ·  view source on GitHub ↗

* Determine whether an array has internal overlap. * * Returns: 0 (no overlap), 1 (overlap), or < 0 (failed to solve). * * max_work and reasons for solver failures are as in solve_may_share_memory. */

Source from the content-addressed store, hash-verified

846 * max_work and reasons for solver failures are as in solve_may_share_memory.
847 */
848NPY_VISIBILITY_HIDDEN mem_overlap_t
849solve_may_have_internal_overlap(PyArrayObject *a, Py_ssize_t max_work)
850{
851 diophantine_term_t terms[NPY_MAXDIMS+1];
852 npy_int64 x[NPY_MAXDIMS+1];
853 unsigned int i, j, nterms;
854
855 if (PyArray_ISCONTIGUOUS(a)) {
856 /* Quick case */
857 return MEM_OVERLAP_NO;
858 }
859
860 /* The internal memory overlap problem is looking for two different
861 solutions to
862
863 sum(a*x) = b, 0 <= x[i] <= ub[i]
864
865 for any b. Equivalently,
866
867 sum(a*x0) - sum(a*x1) = 0
868
869 Mapping the coefficients on the left by x0'[i] = x0[i] if a[i] > 0
870 else ub[i]-x0[i] and opposite for x1, we have
871
872 sum(abs(a)*(x0' + x1')) = sum(abs(a)*ub)
873
874 Now, x0!=x1 if for some i we have x0'[i] + x1'[i] != ub[i].
875 We can now change variables to z[i] = x0'[i] + x1'[i] so the problem
876 becomes
877
878 sum(abs(a)*z) = sum(abs(a)*ub), 0 <= z[i] <= 2*ub[i], z != ub
879
880 This can be solved with solve_diophantine.
881 */
882
883 nterms = 0;
884 if (strides_to_terms(a, terms, &nterms, 0)) {
885 return MEM_OVERLAP_OVERFLOW;
886 }
887 if (PyArray_ITEMSIZE(a) > 1) {
888 terms[nterms].a = 1;
889 terms[nterms].ub = PyArray_ITEMSIZE(a) - 1;
890 ++nterms;
891 }
892
893 /* Get rid of zero coefficients and empty terms */
894 i = 0;
895 for (j = 0; j < nterms; ++j) {
896 if (terms[j].ub == 0) {
897 continue;
898 }
899 else if (terms[j].ub < 0) {
900 return MEM_OVERLAP_NO;
901 }
902 else if (terms[j].a == 0) {
903 return MEM_OVERLAP_YES;
904 }
905 if (i != j) {

Callers 1

npyiter_allocate_arraysFunction · 0.85

Calls 3

strides_to_termsFunction · 0.85
PyArray_ITEMSIZEFunction · 0.85
solve_diophantineFunction · 0.85

Tested by

no test coverage detected