1
/**
2
 * This module provides the inner loops for the clip ufunc
3
 */
4
#define _UMATHMODULE
5
#define _MULTIARRAYMODULE
6
#define NPY_NO_DEPRECATED_API NPY_API_VERSION
7

8
#include "Python.h"
9

10
#include "numpy/halffloat.h"
11
#include "numpy/npy_math.h"
12
#include "numpy/ndarraytypes.h"
13
#include "numpy/npy_common.h"
14
#include "numpy/utils.h"
15
#include "fast_loop_macros.h"
16

17
/*
18
 * Produce macros that perform nan/nat-propagating min and max
19
 */
20

21
/**begin repeat
22
 * #name = BOOL,
23
 *         BYTE, UBYTE, SHORT, USHORT, INT, UINT,
24
 *         LONG, ULONG, LONGLONG, ULONGLONG#
25
 */
26
#define _NPY_@name@_MIN(a, b) PyArray_MIN(a, b)
27
#define _NPY_@name@_MAX(a, b) PyArray_MAX(a, b)
28
/**end repeat**/
29

30
#define _NPY_HALF_MIN(a, b) (npy_half_isnan(a) || npy_half_le(a, b) ? (a) : (b))
31
#define _NPY_HALF_MAX(a, b) (npy_half_isnan(a) || npy_half_ge(a, b) ? (a) : (b))
32

33
/**begin repeat
34
 * #name = FLOAT, DOUBLE, LONGDOUBLE#
35
 */
36
#define _NPY_@name@_MIN(a, b) (npy_isnan(a) ? (a) : PyArray_MIN(a, b))
37
#define _NPY_@name@_MAX(a, b) (npy_isnan(a) ? (a) : PyArray_MAX(a, b))
38
/**end repeat**/
39

40
/**begin repeat
41
 * #name = CFLOAT, CDOUBLE, CLONGDOUBLE#
42
 */
43
#define _NPY_@name@_MIN(a, b) (npy_isnan((a).real) || npy_isnan((a).imag) || PyArray_CLT(a, b) ? (a) : (b))
44
#define _NPY_@name@_MAX(a, b) (npy_isnan((a).real) || npy_isnan((a).imag) || PyArray_CGT(a, b) ? (a) : (b))
45
/**end repeat**/
46

47
/**begin repeat
48
 * #name = DATETIME, TIMEDELTA#
49
 */
50
#define _NPY_@name@_MIN(a, b) ( \
51
    (a) == NPY_DATETIME_NAT ? (a) : \
52
    (b) == NPY_DATETIME_NAT ? (b) : \
53
    (a) < (b) ? (a) : (b) \
54
)
55
#define _NPY_@name@_MAX(a, b) ( \
56
    (a) == NPY_DATETIME_NAT ? (a) : \
57
    (b) == NPY_DATETIME_NAT ? (b) : \
58
    (a) > (b) ? (a) : (b) \
59
)
60
/**end repeat**/
61

62
/**begin repeat
63
 *
64
 * #name = BOOL,
65
 *         BYTE, UBYTE, SHORT, USHORT, INT, UINT,
66
 *         LONG, ULONG, LONGLONG, ULONGLONG,
67
 *         HALF, FLOAT, DOUBLE, LONGDOUBLE,
68
 *         CFLOAT, CDOUBLE, CLONGDOUBLE,
69
 *         DATETIME, TIMEDELTA#
70
 * #type = npy_bool,
71
 *         npy_byte, npy_ubyte, npy_short, npy_ushort, npy_int, npy_uint,
72
 *         npy_long, npy_ulong, npy_longlong, npy_ulonglong,
73
 *         npy_half, npy_float, npy_double, npy_longdouble,
74
 *         npy_cfloat, npy_cdouble, npy_clongdouble,
75
 *         npy_datetime, npy_timedelta#
76
 */
77

78
#define _NPY_CLIP(x, min, max) \
79
    _NPY_@name@_MIN(_NPY_@name@_MAX((x), (min)), (max))
80

81
NPY_NO_EXPORT void
82 1
@name@_clip(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
83
{
84 1
    if (steps[1] == 0 && steps[2] == 0) {
85
        /* min and max are constant throughout the loop, the most common case */
86
        /* NOTE: it may be possible to optimize these checks for nan */
87 1
        @type@ min_val = *(@type@ *)args[1];
88 1
        @type@ max_val = *(@type@ *)args[2];
89

90 1
        char *ip1 = args[0], *op1 = args[3];
91 1
        npy_intp is1 = steps[0], os1 = steps[3];
92 1
        npy_intp n = dimensions[0];
93

94
        /* contiguous, branch to let the compiler optimize */
95 1
        if (is1 == sizeof(@type@) && os1 == sizeof(@type@)) {
96 1
            for(npy_intp i = 0; i < n; i++, ip1 += is1, op1 += os1) {
97 1
                *(@type@ *)op1 = _NPY_CLIP(*(@type@ *)ip1, min_val, max_val);
98
            }
99
        }
100
        else {
101 1
            for(npy_intp i = 0; i < n; i++, ip1 += is1, op1 += os1) {
102 1
                *(@type@ *)op1 = _NPY_CLIP(*(@type@ *)ip1, min_val, max_val);
103
            }
104
        }
105
    }
106
    else {
107 1
        TERNARY_LOOP {
108 1
            *(@type@ *)op1 = _NPY_CLIP(*(@type@ *)ip1, *(@type@ *)ip2, *(@type@ *)ip3);
109
        }
110
    }
111 1
    npy_clear_floatstatus_barrier((char*)dimensions);
112 1
}
113

114
// clean up the macros we defined above
115
#undef _NPY_CLIP
116
#undef _NPY_@name@_MAX
117
#undef _NPY_@name@_MIN
118

119
/**end repeat**/

Read our documentation on viewing source code .

Loading