diff options
author | Ganesh Kathiresan <ganesh3597@gmail.com> | 2020-11-13 12:02:03 +0530 |
---|---|---|
committer | Ganesh Kathiresan <ganesh3597@gmail.com> | 2020-11-13 12:02:03 +0530 |
commit | c85c44a8091dffc921ac81059280f99b9d4dc198 (patch) | |
tree | 46637412a020aba9f2e240d64017deb267000eae /numpy/core | |
parent | 0ce0ebd3b895678f2a59797564e17a0aedad6872 (diff) | |
download | numpy-c85c44a8091dffc921ac81059280f99b9d4dc198.tar.gz |
ENH: Added libdivide to timedelta
Diffstat (limited to 'numpy/core')
-rw-r--r-- | numpy/core/src/umath/loops.c.src | 87 |
1 files changed, 68 insertions, 19 deletions
diff --git a/numpy/core/src/umath/loops.c.src b/numpy/core/src/umath/loops.c.src index b37f4c427..a7c0cb365 100644 --- a/numpy/core/src/umath/loops.c.src +++ b/numpy/core/src/umath/loops.c.src @@ -862,7 +862,7 @@ NPY_NO_EXPORT void { BINARY_LOOP_BASE - if(!is2) { + if (!is2) { const @type@ in2 = *(@type@ *)ip2; /* Creating a divisor of 0 is treated as an error by libdivide */ @@ -1403,14 +1403,33 @@ TIMEDELTA_dm_m_multiply(char **args, npy_intp const *dimensions, npy_intp const NPY_NO_EXPORT void TIMEDELTA_mq_m_divide(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func)) { - BINARY_LOOP { - const npy_timedelta in1 = *(npy_timedelta *)ip1; + BINARY_LOOP_BASE + + if (!is2) { const npy_int64 in2 = *(npy_int64 *)ip2; - if (in1 == NPY_DATETIME_NAT || in2 == 0) { - *((npy_timedelta *)op1) = NPY_DATETIME_NAT; + + /* Creating a divisor of 0 is treated as an error by libdivide */ + struct libdivide_s64_t fast_d = in2 ? libdivide_s64_gen(in2) : (struct libdivide_s64_t){0}; + BINARY_LOOP_FIXED { + const npy_timedelta in1 = *(npy_timedelta *)ip1; + if (in1 == NPY_DATETIME_NAT || in2 == 0) { + *((npy_timedelta *)op1) = NPY_DATETIME_NAT; + } + else { + *((npy_timedelta *)op1) = libdivide_s64_do(in1, &fast_d);; + } } - else { - *((npy_timedelta *)op1) = in1 / in2; + } + else { + BINARY_LOOP_SLIDING { + const npy_timedelta in1 = *(npy_timedelta *)ip1; + const npy_int64 in2 = *(npy_int64 *)ip2; + if (in1 == NPY_DATETIME_NAT || in2 == 0) { + *((npy_timedelta *)op1) = NPY_DATETIME_NAT; + } + else { + *((npy_timedelta *)op1) = in1 / in2; + } } } } @@ -1482,23 +1501,53 @@ TIMEDELTA_mm_m_remainder(char **args, npy_intp const *dimensions, npy_intp const NPY_NO_EXPORT void TIMEDELTA_mm_q_floor_divide(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func)) { - BINARY_LOOP { - const npy_timedelta in1 = *(npy_timedelta *)ip1; + /* TODO: This code is similar to array floor divide*/ + BINARY_LOOP_BASE + + if (!is2) { const npy_timedelta in2 = *(npy_timedelta *)ip2; - if (in1 == NPY_DATETIME_NAT || in2 == NPY_DATETIME_NAT) { - npy_set_floatstatus_invalid(); - *((npy_int64 *)op1) = 0; - } - else if (in2 == 0) { - npy_set_floatstatus_divbyzero(); - *((npy_int64 *)op1) = 0; + + /* Creating a divisor of 0 is treated as an error by libdivide */ + struct libdivide_s64_t fast_d = in2 ? libdivide_s64_gen(in2) : (struct libdivide_s64_t){0}; + BINARY_LOOP_FIXED { + const npy_timedelta in1 = *(npy_timedelta *)ip1; + if (in1 == NPY_DATETIME_NAT || in2 == NPY_DATETIME_NAT) { + npy_set_floatstatus_invalid(); + *((npy_int64 *)op1) = 0; + } + else if (in2 == 0) { + npy_set_floatstatus_divbyzero(); + *((npy_int64 *)op1) = 0; + } + else { + *((npy_int64 *)op1) = libdivide_s64_do(in1, &fast_d); + + /* Negative quotients needs to be rounded down */ + if (((in1 > 0) != (in2 > 0)) && (*((npy_int64 *)op1) * in2 != in1)) { + *((npy_int64 *)op1) = *((npy_int64 *)op1) - 1; + } + } } - else { - if (((in1 > 0) != (in2 > 0)) && (in1 % in2 != 0)) { - *((npy_int64 *)op1) = in1/in2 - 1; + } + else { + BINARY_LOOP_SLIDING { + const npy_timedelta in1 = *(npy_timedelta *)ip1; + const npy_timedelta in2 = *(npy_timedelta *)ip2; + if (in1 == NPY_DATETIME_NAT || in2 == NPY_DATETIME_NAT) { + npy_set_floatstatus_invalid(); + *((npy_int64 *)op1) = 0; + } + else if (in2 == 0) { + npy_set_floatstatus_divbyzero(); + *((npy_int64 *)op1) = 0; } else { *((npy_int64 *)op1) = in1/in2; + + /* Negative quotients needs to be rounded down */ + if (((in1 > 0) != (in2 > 0)) && (*((npy_int64 *)op1) * in2 != in1)) { + *((npy_int64 *)op1) = *((npy_int64 *)op1) - 1; + } } } } |