• API
• FAQ
• Tools
• Trends
• Archive
SHARE
TWEET

# Numpy find first/last function for 1-D arrays

dpitch40 Jul 25th, 2012 554 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. #include "Python.h"
2. #include "Numeric/arrayobject.h"
3.
4. #define SEARCH_LOOP(OP, INC) { \
6.     if (*i OP value) { \
7.         return (void*)i; \
8.     } \
9. } \
10. return (void*)0; }
11.
12. #define SWITCH_ON_OP(TYPE, INC) { \
13. TYPE* i; \
14. switch (op) { \
15.     case EQ: \
16.         SEARCH_LOOP(==, INC) \
17.     case GT: \
18.         SEARCH_LOOP(>, INC) \
19.     case GTE: \
20.         SEARCH_LOOP(>=, INC) \
21.     case LT: \
22.         SEARCH_LOOP(<, INC) \
23.     case LTE: \
24.         SEARCH_LOOP(<=, INC) \
25.     case NEQ: \
26.         SEARCH_LOOP(!=, INC) \
27.     default: \
28.         return (void*)0; \
29.     } \
30. }
31.
32. #define SWITCH_ON_STRIDE(TYPE) { \
33.     if (stride > 0) \
34.     { \
35.         SWITCH_ON_OP(TYPE, i++) \
36.     } \
37.     else \
38.     { \
39.         SWITCH_ON_OP(TYPE, i--) \
40.     } \
41. }
42.
43. enum comp_operators {
44.     EQ,
45.     GT,
46.     GTE,
47.     LT,
48.     LTE,
49.     NEQ
50. };
51.
52. static void* array_find_byte(PyObject* searchval, void* start_addr, void* end_addr, int stride, int op) {
53.     char value = (char)(PyInt_AsLong(searchval));
54.     SWITCH_ON_STRIDE(char)
55. }
56.
57. static void* array_find_short(PyObject* searchval, void* start_addr, void* end_addr, int stride, int op) {
58.     short value = (short)(PyInt_AsLong(searchval));
59.     SWITCH_ON_STRIDE(short)
60. }
61.
62. static void* array_find_long(PyObject* searchval, void* start_addr, void* end_addr, int stride, int op) {
63.     long value = PyInt_AsLong(searchval);
64.     SWITCH_ON_STRIDE(long)
65. }
66.
67. static void* array_find_longlong(PyObject* searchval, void* start_addr, void* end_addr, int stride, int op) {
68.     long long value = PyLong_AsLongLong(searchval);
69.     SWITCH_ON_STRIDE(long long)
70. }
71.
72. static void* array_find_ubyte(PyObject* searchval, void* start_addr, void* end_addr, int stride, int op) {
73.     unsigned char value = (unsigned char)(PyInt_AsUnsignedLongMask(searchval));
74.     SWITCH_ON_STRIDE(unsigned char)
75. }
76.
77. static void* array_find_ushort(PyObject* searchval, void* start_addr, void* end_addr, int stride, int op) {
78.     unsigned short value = (unsigned short)(PyInt_AsUnsignedLongMask(searchval));
79.     SWITCH_ON_STRIDE(unsigned short)
80. }
81.
82. static void* array_find_ulong(PyObject* searchval, void* start_addr, void* end_addr, int stride, int op) {
83.     unsigned long value = PyInt_AsUnsignedLongMask(searchval);
84.     SWITCH_ON_STRIDE(unsigned long)
85. }
86.
87. static void* array_find_ulonglong(PyObject* searchval, void* start_addr, void* end_addr, int stride, int op) {
88.     unsigned long long value = PyLong_AsUnsignedLongLong(searchval);
89.     SWITCH_ON_STRIDE(unsigned long long)
90. }
91.
92. static void* array_find_float(PyObject* searchval, void* start_addr, void* end_addr, int stride, int op) {
93.     float value = (float)(PyFloat_AsDouble(searchval));
94.     SWITCH_ON_STRIDE(float)
95. }
96.
97. static void* array_find_double(PyObject* searchval, void* start_addr, void* end_addr, int stride, int op) {
98.     double value = PyFloat_AsDouble(searchval);
99.     SWITCH_ON_STRIDE(double)
100. }
101.
102. static void* array_find_eq_string(char* value, void* start_addr, void* end_addr, int stride, int elsize)
103. {
104.     char dest[elsize+1];
105.     dest[elsize] = '\0';
106.     void* i;
108.     {
109.         memcpy((void*)dest, i, elsize);
110.         if (strcmp(dest, value) == 0)
111.         {
112.             return i;
113.         }
114.     }
115.     return 0;
116. }
117.
118. static void* array_find_neq_string(char* value, void* start_addr, void* end_addr, int stride, int elsize)
119. {
120.     char dest[elsize+1];
121.     dest[elsize] = '\0';
122.     void* i;
124.     {
125.         memcpy((void*)dest, i, elsize);
126.         if (strcmp(dest, value) != 0)
127.         {
128.             return i;
129.         }
130.     }
131.     return 0;
132. }
133.
134. static void* array_find_string(PyObject* searchval, void* start_addr, void* end_addr, int stride, int op, int elsize) {
135.     char* value = PyString_AsString(searchval);
136.     if (op == NEQ)
137.     {
139.     }
140.     else
141.     {
143.     }
144. }
145.
146. static PyObject* multi_find(PyObject* self, PyObject* args, short direction)
147. {
148.     PyArrayObject* arr;
149.     PyObject* value;
150.     short eqtest;
151.     int start, end;
152.     if (!PyArg_ParseTuple(args, "O!Ohii", &PyArray_Type, &arr, &value, &eqtest, &start, &end))
153.     {
154.         return NULL;
155.     }
156.     char type = arr->descr->type;
157.     int elsize = arr->descr->elsize;
158.     int stride = arr->strides[0];
159.
163.     int dirstride = stride;
164.     void* temp;
165.
166.     if (stride > 0)
167.     {
170.     }
171.     else
172.     {
175.     }
176.
177.     if (!direction)
178.     {
180.         //Shift by one place so we read the same set of data backwards
182.         end_addr = temp - stride;
183.         dirstride = -1 * stride;
184.     }
185.
187.     switch (type)
188.     {
189.         case 'b':
191.             break;
192.         case 'h':
194.             break;
195.         case 'i':
197.             break;
198.         case 'l':
200.             break;
201.         case 'q':
203.             break;
204.         case 'B':
206.             break;
207.         case 'H':
209.             break;
210.         case 'I':
212.             break;
213.         case 'L':
215.             break;
216.         case 'Q':
218.             break;
219.         case 'f':
221.             break;
222.         case 'd':
224.             break;
225.         case 'S':
227.             break;
228.         default:
230.     }
231.
232.     // printf("%s\t%s\t%d\t%d\t%p\t%p\t%p\t%p\n", &(arr->descr->kind), &type, elsize, dirstride,
234.
235.     int dest_index;
237.     {
239.     }
240.     else
241.     {
242.         dest_index = -1;
243.     }
244.     return Py_BuildValue("i", dest_index);
245. }
246.
247. static char py_find_doc[] = "Finds the first index of the occurrence of a value in an array.";
248. static PyObject* py_find(PyObject* self, PyObject* args)
249. {
250.     return multi_find(self, args, 1);
251. }
252.
253. static char py_rfind_doc[] = "Finds the last index of the occurrence of a value in an array.";
254. static PyObject* py_rfind(PyObject* self, PyObject* args)
255. {
256.     return multi_find(self, args, 0);
257. }
258.
259. static PyMethodDef _npfindmethods[] = {
260.     {"np_find", py_find, METH_VARARGS, py_find_doc},
261.     {"np_rfind", py_rfind, METH_VARARGS, py_rfind_doc},
262.     {NULL, NULL, 0, NULL}
263. };
264.
265. void init_npfind(void)
266. {
267.     Py_InitModule("_npfind", _npfindmethods);
268.     import_array();
269. }
RAW Paste Data
Top