arraykit 0.10.0__cp313-cp313-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
arraykit/tri_map.h ADDED
@@ -0,0 +1,8 @@
1
+ # ifndef ARRAYKIT_SRC_TRI_MAP_H_
2
+ # define ARRAYKIT_SRC_TRI_MAP_H_
3
+
4
+ # include "Python.h"
5
+
6
+ extern PyTypeObject TriMapType;
7
+
8
+ # endif /* ARRAYKIT_SRC_TRI_MAP_H_ */
arraykit/utilities.h ADDED
@@ -0,0 +1,321 @@
1
+ #ifndef ARRAYKIT_SRC_UTILITIES_H_
2
+ #define ARRAYKIT_SRC_UTILITIES_H_
3
+
4
+ # include "Python.h"
5
+ # include "stdbool.h"
6
+
7
+ # define NO_IMPORT_ARRAY
8
+ # define PY_ARRAY_UNIQUE_SYMBOL AK_ARRAY_API
9
+ # define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
10
+
11
+ # include "numpy/arrayobject.h"
12
+
13
+ static const size_t UCS4_SIZE = sizeof(Py_UCS4);
14
+
15
+ //------------------------------------------------------------------------------
16
+ // Macros
17
+ //------------------------------------------------------------------------------
18
+
19
+ // Given a PyObject, raise if not an array.
20
+ # define AK_CHECK_NUMPY_ARRAY(O) \
21
+ if (!PyArray_Check(O)) { \
22
+ return PyErr_Format(PyExc_TypeError, \
23
+ "Expected NumPy array, not %s.", \
24
+ Py_TYPE(O)->tp_name); \
25
+ }
26
+
27
+ // Given a PyObject, raise if not an array or is not one or two dimensional.
28
+ # define AK_CHECK_NUMPY_ARRAY_1D_2D(O) \
29
+ do { \
30
+ AK_CHECK_NUMPY_ARRAY(O) \
31
+ int ndim = PyArray_NDIM((PyArrayObject *)O); \
32
+ if (ndim != 1 && ndim != 2) { \
33
+ return PyErr_Format(PyExc_NotImplementedError,\
34
+ "Expected 1D or 2D array, not %i.", \
35
+ ndim); \
36
+ } \
37
+ } while (0)
38
+
39
+ // Given a PyObject, raise if not an array or is not two dimensional.
40
+ # define AK_CHECK_NUMPY_ARRAY_2D(O) \
41
+ do { \
42
+ AK_CHECK_NUMPY_ARRAY(O) \
43
+ int ndim = PyArray_NDIM((PyArrayObject *)O); \
44
+ if (ndim != 2) { \
45
+ return PyErr_Format(PyExc_NotImplementedError,\
46
+ "Expected a 2D array, not %i.", \
47
+ ndim); \
48
+ } \
49
+ } while (0)
50
+
51
+ # if defined __GNUC__ || defined __clang__
52
+ # define AK_LIKELY(X) __builtin_expect(!!(X), 1)
53
+ # define AK_UNLIKELY(X) __builtin_expect(!!(X), 0)
54
+ # else
55
+ # define AK_LIKELY(X) (!!(X))
56
+ # define AK_UNLIKELY(X) (!!(X))
57
+ # endif
58
+
59
+ // Placeholder of not implemented pathways / debugging.
60
+ # define AK_NOT_IMPLEMENTED(msg) \
61
+ do { \
62
+ PyErr_SetString(PyExc_NotImplementedError, msg);\
63
+ return NULL; \
64
+ } while (0)
65
+
66
+ # define _AK_DEBUG_BEGIN() \
67
+ do { \
68
+ fprintf(stderr, "--- %s: %i: %s: ", __FILE__, __LINE__, __FUNCTION__);
69
+
70
+ # define _AK_DEBUG_END() \
71
+ fprintf(stderr, "\n"); \
72
+ fflush(stderr); \
73
+ } while (0)
74
+
75
+ # define AK_DEBUG(msg) \
76
+ _AK_DEBUG_BEGIN(); \
77
+ fprintf(stderr, #msg); \
78
+ _AK_DEBUG_END()
79
+
80
+ # define AK_DEBUG_MSG_OBJ(msg, obj) \
81
+ _AK_DEBUG_BEGIN(); \
82
+ fprintf(stderr, #msg " "); \
83
+ PyObject_Print(obj, stderr, 0); \
84
+ _AK_DEBUG_END()
85
+
86
+ # define AK_DEBUG_MSG_REFCNT(msg, obj) \
87
+ _AK_DEBUG_BEGIN(); \
88
+ fprintf(stderr, #msg " ref count: "); \
89
+ PyObject_Print(PyLong_FromSsize_t(Py_REFCNT((PyObject*)obj)), stderr, 0); \
90
+ _AK_DEBUG_END()
91
+
92
+ # define AK_DEBUG_OBJ(obj) \
93
+ _AK_DEBUG_BEGIN(); \
94
+ fprintf(stderr, #obj " = "); \
95
+ PyObject_Print(obj, stderr, 0); \
96
+ _AK_DEBUG_END()
97
+
98
+ // Takes and returns a PyArrayObject, optionally copying a mutable array and setting it as immutable
99
+ static inline PyArrayObject *
100
+ AK_immutable_filter(PyArrayObject *a)
101
+ {
102
+ // https://numpy.org/devdocs/reference/c-api/array.html#array-flags
103
+ if (PyArray_FLAGS(a) & NPY_ARRAY_WRITEABLE) {
104
+ if ((a = (PyArrayObject *)PyArray_NewCopy(a, NPY_ANYORDER))) {
105
+ PyArray_CLEARFLAGS(a, NPY_ARRAY_WRITEABLE);
106
+ }
107
+ return a;
108
+ }
109
+ Py_INCREF(a);
110
+ return a;
111
+ }
112
+
113
+ // Returns NULL on error.
114
+ static inline PyArray_Descr *
115
+ AK_resolve_dtype(PyArray_Descr *d1, PyArray_Descr *d2)
116
+ {
117
+ if (PyArray_EquivTypes(d1, d2)) {
118
+ Py_INCREF(d1);
119
+ return d1;
120
+ }
121
+ if (PyDataType_ISOBJECT(d1) || PyDataType_ISOBJECT(d2)
122
+ || PyDataType_ISBOOL(d1) || PyDataType_ISBOOL(d2)
123
+ || (PyDataType_ISSTRING(d1) != PyDataType_ISSTRING(d2))
124
+ || ((PyDataType_ISDATETIME(d1) || PyDataType_ISDATETIME(d2))
125
+ // PyDataType_ISDATETIME matches NPY_DATETIME or NPY_TIMEDELTA, so
126
+ // we need to make sure we didn't get one of each:
127
+ && !PyArray_EquivTypenums(d1->type_num, d2->type_num)))
128
+ {
129
+ return PyArray_DescrFromType(NPY_OBJECT);
130
+ }
131
+ PyArray_Descr *d = PyArray_PromoteTypes(d1, d2);
132
+ if (!d) {
133
+ PyErr_Clear();
134
+ return PyArray_DescrFromType(NPY_OBJECT);
135
+ }
136
+ return d;
137
+ }
138
+
139
+ // Returns NULL on error. Returns a new reference.
140
+ static inline PyObject *
141
+ AK_build_pair_ssize_t(Py_ssize_t a, Py_ssize_t b)
142
+ {
143
+ PyObject* t = PyTuple_New(2);
144
+ if (t == NULL) {
145
+ return NULL;
146
+ }
147
+ PyObject* py_a = PyLong_FromSsize_t(a);
148
+ if (py_a == NULL) {
149
+ Py_DECREF(t);
150
+ return NULL;
151
+ }
152
+ PyObject* py_b = PyLong_FromSsize_t(b);
153
+ if (py_b == NULL) {
154
+ Py_DECREF(t);
155
+ Py_DECREF(py_a);
156
+ return NULL;
157
+ }
158
+ // steals refs
159
+ PyTuple_SET_ITEM(t, 0, py_a);
160
+ PyTuple_SET_ITEM(t, 1, py_b);
161
+ return t;
162
+ }
163
+
164
+ // Returns a new ref; returns NULL on error. Any start or stop less than 0 will be set to NULL.
165
+ static inline PyObject *
166
+ AK_build_slice(Py_ssize_t start, Py_ssize_t stop, Py_ssize_t step)
167
+ {
168
+ PyObject* py_start = NULL;
169
+ PyObject* py_stop = NULL;
170
+ PyObject* py_step = NULL;
171
+
172
+ if (start >= 0) {
173
+ py_start = PyLong_FromSsize_t(start);
174
+ if (py_start == NULL) {return NULL;}
175
+ }
176
+ if (stop >= 0) {
177
+ py_stop = PyLong_FromSsize_t(stop);
178
+ if (py_stop == NULL) {return NULL;}
179
+ }
180
+ // do not set a step if not necessary
181
+ if (step != 0 && step != 1) {
182
+ py_step = PyLong_FromSsize_t(step);
183
+ if (py_step == NULL) {return NULL;}
184
+ }
185
+
186
+ // might be NULL, let return
187
+ PyObject* new = PySlice_New(py_start, py_stop, py_step);
188
+
189
+ Py_XDECREF(py_start);
190
+ Py_XDECREF(py_stop);
191
+ Py_XDECREF(py_step);
192
+
193
+ return new;
194
+ }
195
+
196
+ // Utility function for converting slices; returns NULL on error; returns a new reference.
197
+ static inline PyObject *
198
+ AK_slice_to_ascending_slice(PyObject* slice, Py_ssize_t size)
199
+ {
200
+ Py_ssize_t step_count = -1;
201
+ Py_ssize_t start = 0;
202
+ Py_ssize_t stop = 0;
203
+ Py_ssize_t step = 0;
204
+
205
+ if (PySlice_Unpack(slice, &start, &stop, &step)) {
206
+ return NULL;
207
+ }
208
+ if (step > 0) {
209
+ Py_INCREF(slice);
210
+ return slice;
211
+ }
212
+ step_count = PySlice_AdjustIndices(
213
+ size,
214
+ &start,
215
+ &stop,
216
+ step);
217
+
218
+ // step will be negative; shift original start value down to find new start
219
+ return AK_build_slice(
220
+ start + (step * (step_count - 1)),
221
+ start + 1,
222
+ -step);
223
+ }
224
+
225
+ // Given a Boolean, contiguous 1D array, return the index positions in an int64 array. Through experimentation it has been verified that doing full-size allocation of memory provides the best performance at all scales. Using NpyIter, or using, bit masks does not improve performance over pointer arithmetic. Prescanning for all empty is very effective. Note that NumPy benefits from first counting the nonzeros, then allocating only enough data for the expexted number of indices.
226
+ static inline PyObject *
227
+ AK_nonzero_1d(PyArrayObject* array) {
228
+ PyObject* final;
229
+ npy_intp count_max = PyArray_SIZE(array);
230
+
231
+ if (count_max == 0) { // return empty array
232
+ npy_intp dims = {count_max};
233
+ final = PyArray_SimpleNew(1, &dims, NPY_INT64);
234
+ PyArray_CLEARFLAGS((PyArrayObject*)final, NPY_ARRAY_WRITEABLE);
235
+ return final;
236
+ }
237
+ lldiv_t size_div = lldiv((long long)count_max, 8); // quot, rem
238
+
239
+ Py_ssize_t count = 0;
240
+ // the maximum number of collected integers is equal to or less than count_max
241
+ Py_ssize_t capacity = count_max;
242
+ npy_int64* indices = (npy_int64*)malloc(sizeof(npy_int64) * capacity);
243
+
244
+ NPY_BEGIN_THREADS_DEF;
245
+ NPY_BEGIN_THREADS;
246
+
247
+ if (PyArray_IS_C_CONTIGUOUS(array)) {
248
+ npy_bool* p_start = (npy_bool*)PyArray_DATA(array);
249
+ npy_bool* p = p_start;
250
+ npy_bool* p_end = p + count_max;
251
+ npy_bool* p_end_roll = p_end - size_div.rem;
252
+
253
+ while (p < p_end_roll) {
254
+ if (*(npy_uint64*)p == 0) {
255
+ p += 8; // no true within this 8 byte roll region
256
+ continue;
257
+ }
258
+ if (*p) {indices[count++] = p - p_start;}
259
+ p++;
260
+ if (*p) {indices[count++] = p - p_start;}
261
+ p++;
262
+ if (*p) {indices[count++] = p - p_start;}
263
+ p++;
264
+ if (*p) {indices[count++] = p - p_start;}
265
+ p++;
266
+ if (*p) {indices[count++] = p - p_start;}
267
+ p++;
268
+ if (*p) {indices[count++] = p - p_start;}
269
+ p++;
270
+ if (*p) {indices[count++] = p - p_start;}
271
+ p++;
272
+ if (*p) {indices[count++] = p - p_start;}
273
+ p++;
274
+ }
275
+ while (p < p_end) {
276
+ if (*p) {indices[count++] = p - p_start;}
277
+ p++;
278
+ }
279
+ }
280
+ else {
281
+ npy_intp i = 0; // position within Boolean array
282
+ npy_intp i_end = count_max;
283
+ npy_intp i_end_roll = count_max - size_div.rem;
284
+ while (i < i_end_roll) {
285
+ if (*(npy_bool*)PyArray_GETPTR1(array, i)) {indices[count++] = i;}
286
+ i++;
287
+ if (*(npy_bool*)PyArray_GETPTR1(array, i)) {indices[count++] = i;}
288
+ i++;
289
+ if (*(npy_bool*)PyArray_GETPTR1(array, i)) {indices[count++] = i;}
290
+ i++;
291
+ if (*(npy_bool*)PyArray_GETPTR1(array, i)) {indices[count++] = i;}
292
+ i++;
293
+ if (*(npy_bool*)PyArray_GETPTR1(array, i)) {indices[count++] = i;}
294
+ i++;
295
+ if (*(npy_bool*)PyArray_GETPTR1(array, i)) {indices[count++] = i;}
296
+ i++;
297
+ if (*(npy_bool*)PyArray_GETPTR1(array, i)) {indices[count++] = i;}
298
+ i++;
299
+ if (*(npy_bool*)PyArray_GETPTR1(array, i)) {indices[count++] = i;}
300
+ i++;
301
+ }
302
+ while (i < i_end) {
303
+ if (*(npy_bool*)PyArray_GETPTR1(array, i)) {indices[count++] = i;}
304
+ i++;
305
+ }
306
+ }
307
+ NPY_END_THREADS;
308
+
309
+ npy_intp dims = {count};
310
+ final = PyArray_SimpleNewFromData(1, &dims, NPY_INT64, (void*)indices);
311
+ if (!final) {
312
+ free(indices);
313
+ return NULL;
314
+ }
315
+ // This ensures that the array frees the indices array; this has been tested by calling free(indices) and observing segfault
316
+ PyArray_ENABLEFLAGS((PyArrayObject*)final, NPY_ARRAY_OWNDATA);
317
+ PyArray_CLEARFLAGS((PyArrayObject*)final, NPY_ARRAY_WRITEABLE);
318
+ return final;
319
+ }
320
+
321
+ #endif /* ARRAYKIT_SRC_UTILITIES_H_ */
@@ -0,0 +1,37 @@
1
+
2
+ License
3
+ =============
4
+
5
+ MIT License
6
+
7
+ Copyright (c) 2012-2022 Christopher Ariza, Research Affiliates, others
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
26
+
27
+ IN NO EVENT SHALL RESEARCH AFFILATES, LLC (“RA”) BE LIABLE TO ANY PARTY FOR
28
+ DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
29
+ PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
30
+ RA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
+
32
+ RA SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
34
+ SOFTWARE AND ACCOMPANYING DOCUMENTATION OR TEXT, IF ANY, PROVIDED HEREUNDER IS
35
+ PROVIDED "AS IS". RA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
36
+ ENHANCEMENTS, OR MODIFICATIONS.
37
+
@@ -0,0 +1,32 @@
1
+ Metadata-Version: 2.1
2
+ Name: arraykit
3
+ Version: 0.10.0
4
+ Summary: Array utilities for StaticFrame
5
+ Home-page: https://github.com/static-frame/arraykit
6
+ Author: Christopher Ariza, Brandt Bucher, Charles Burkland
7
+ License: MIT
8
+ Keywords: numpy array
9
+ Classifier: Development Status :: 5 - Production/Stable
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Topic :: Software Development
12
+ Classifier: Programming Language :: C
13
+ Classifier: Programming Language :: Python :: Implementation :: CPython
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: MacOS :: MacOS X
16
+ Classifier: Operating System :: Microsoft :: Windows
17
+ Classifier: Operating System :: POSIX
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Programming Language :: Python :: 3.13
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.9
25
+ License-File: LICENSE.txt
26
+ Requires-Dist: numpy>=1.19.5
27
+
28
+ The ArrayKit library provides utilities for creating and transforming NumPy arrays, implementing performance-critical StaticFrame operations as Python C extensions.
29
+
30
+ Code: https://github.com/static-frame/arraykit
31
+
32
+ Packages: https://pypi.org/project/arraykit
@@ -0,0 +1,23 @@
1
+ arraykit/__init__.py,sha256=8EFKJx3Va5lqt6mMH2dIkSju6zjFnNn4Bs-0hLrEr5w,1710
2
+ arraykit/__init__.pyi,sha256=qqXGXVQapnRKukMKGZaCqm5tsTPBuS7Pxn9m_pumAVs,6423
3
+ arraykit/_arraykit.c,sha256=l0qZWOpFM1uhu5UNUCR-qi4kd8gnaTMn5ifq2V_DyQQ,4113
4
+ arraykit/_arraykit.cp313-win_amd64.pyd,sha256=kcO-PKvXnLUvwA-Tg-fjKMjkQEON4D7uPWqYBFyuErY,112128
5
+ arraykit/array_go.c,sha256=u9gRnVM8AejfHq6h1_fBCOcLb_Phloi2ch1TT57yH8k,7255
6
+ arraykit/array_go.h,sha256=D6qfN2Cb6lvb7S9lGEpKi6cOoBW86hzO1Uez4A9xhOQ,172
7
+ arraykit/array_to_tuple.c,sha256=QcBobwzJDAiM660Y7wQ04OGZXrnda2PWMAUL6syG9Q4,7898
8
+ arraykit/array_to_tuple.h,sha256=9OotdVKSH8_tJP2zwwhz6n3vciJsysTszG9N5lKI12w,418
9
+ arraykit/block_index.c,sha256=Q_Vef-ysdHmV9t7BaAXJjUp-S166IXRXNqrbE_-BpkU,45754
10
+ arraykit/block_index.h,sha256=oR-WgZsdD6Xl7HyeFcrvBJ-LtBQkcfwizVFo9SaWcKI,449
11
+ arraykit/delimited_to_arrays.c,sha256=9v01-E0EEkBalXFsgL7rLKt5QBgCeN7QhBqGaNEuRrw,101568
12
+ arraykit/delimited_to_arrays.h,sha256=IuXW5AUhMZ6SC5s6VaC16mIC1-4CpQks4AmCsI2W56I,527
13
+ arraykit/methods.c,sha256=r6Gt_asknpNYY34TsT3GqmkOhMiDWcP9DHBhqjyo2X8,33431
14
+ arraykit/methods.h,sha256=j0k5mAxhhhbyVpvv3vNAYr_sJ7D6IFRaqRYIktj9JX4,2386
15
+ arraykit/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
+ arraykit/tri_map.c,sha256=GDlUfInfKrPQL9iBIbfhtf91ziDWR-X2gYNf8XTqfQI,52709
17
+ arraykit/tri_map.h,sha256=8_wYUqQTM2fTkP3GSHfQB0e0O3OrUZzpKuoGUXEFCJE,168
18
+ arraykit/utilities.h,sha256=iv_oV3YuiOrNeCgweMkOzhL3Whdn8wM6fpas9Jw-3Cg,11417
19
+ arraykit-0.10.0.dist-info/LICENSE.txt,sha256=3t-z3TUy-ObAbtNww27zjhtD70pPtxLG-bSU0fUEk1k,1816
20
+ arraykit-0.10.0.dist-info/METADATA,sha256=7vWktSh_QaHym0Wia6UwfWG_h9i45u8CmqP1Ojh_02E,1334
21
+ arraykit-0.10.0.dist-info/WHEEL,sha256=4-iQBlRoDdX1wfPofc7KLWa5Cys4eZSgXs6GVU8fKlQ,101
22
+ arraykit-0.10.0.dist-info/top_level.txt,sha256=00W90765jXl-QEGzShY2mT-haT9R5aB_MiTmxrFaBhQ,9
23
+ arraykit-0.10.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (75.6.0)
3
+ Root-Is-Purelib: false
4
+ Tag: cp313-cp313-win_amd64
5
+
@@ -0,0 +1 @@
1
+ arraykit