Comments (9)
In case it helps you, this diff was enough to get quaternion building and tests passing on NumPy 1 and 2:
diff --git a/__init__.py b/__init__.py
--- a/__init__.py
+++ b/__init__.py
@@ -780,8 +780,8 @@ def isclose(a, b, rtol=4*np.finfo(float)
result = np.less_equal(abs(x-y), atol + rtol * abs(y))
return result[()]
- x = np.array(a, copy=False, subok=True, ndmin=1)
- y = np.array(b, copy=False, subok=True, ndmin=1)
+ x = np.array(a, subok=True, ndmin=1)
+ y = np.array(b, subok=True, ndmin=1)
# Make sure y is an inexact type to avoid bad behavior on abs(MIN_INT).
# This will cause casting of x later. Also, make sure to allow subclasses
@@ -790,7 +790,7 @@ def isclose(a, b, rtol=4*np.finfo(float)
dt = np.result_type(y, 1.)
except TypeError:
dt = np.dtype(np.quaternion)
- y = np.array(y, dtype=dt, copy=False, subok=True)
+ y = np.array(y, dtype=dt, subok=True)
xfin = np.isfinite(x)
yfin = np.isfinite(y)
diff --git a/numpy_quaternion.c b/numpy_quaternion.c
--- a/numpy_quaternion.c
+++ b/numpy_quaternion.c
@@ -22,6 +22,12 @@ typedef npy_intp NPY_INTP_CONST;
typedef npy_intp const NPY_INTP_CONST;
#endif
+#if NPY_ABI_VERSION < 0x02000000
+#define PyArray_DescrProto PyArray_Descr
+#define PyDataType_ELSIZE(d) ((d)->elsize)
+#define PyDataType_GetArrFuncs(d) ((d)->f)
+#endif
+
// The following definitions, along with `#define NPY_PY3K 1`, can
// also be found in the header <numpy/npy_3kcompat.h>.
#if PY_MAJOR_VERSION >= 3
@@ -59,6 +65,7 @@ static PyTypeObject PyQuaternion_Type;
// built-in numpy data type. We will describe its features below.
PyArray_Descr* quaternion_descr;
+PyArray_DescrProto quaternion_proto = {PyObject_HEAD_INIT(NULL)};
static NPY_INLINE int
PyQuaternion_Check(PyObject* object) {
@@ -260,7 +267,7 @@ pyquaternion_##fake_name##_array_operato
} \
iternext = NpyIter_GetIterNext(iter, NULL); \
innerstride = NpyIter_GetInnerStrideArray(iter)[0]; \
- itemsize = NpyIter_GetDescrArray(iter)[1]->elsize; \
+ itemsize = PyDataType_ELSIZE(NpyIter_GetDescrArray(iter)[1]); \
innersizeptr = NpyIter_GetInnerLoopSizePtr(iter); \
dataptrarray = NpyIter_GetDataPtrArray(iter); \
if(PyArray_EquivTypes(PyArray_DESCR((PyArrayObject*) b), quaternion_descr)) { \
@@ -927,10 +934,10 @@ QUATERNION_nonzero (char *ip, PyArrayObj
else {
PyArray_Descr *descr;
descr = PyArray_DescrFromType(NPY_DOUBLE);
- descr->f->copyswap(&q.w, ip, !PyArray_ISNOTSWAPPED(ap), NULL);
- descr->f->copyswap(&q.x, ip+8, !PyArray_ISNOTSWAPPED(ap), NULL);
- descr->f->copyswap(&q.y, ip+16, !PyArray_ISNOTSWAPPED(ap), NULL);
- descr->f->copyswap(&q.z, ip+24, !PyArray_ISNOTSWAPPED(ap), NULL);
+ PyDataType_GetArrFuncs(descr)->copyswap(&q.w, ip, !PyArray_ISNOTSWAPPED(ap), NULL);
+ PyDataType_GetArrFuncs(descr)->copyswap(&q.x, ip+8, !PyArray_ISNOTSWAPPED(ap), NULL);
+ PyDataType_GetArrFuncs(descr)->copyswap(&q.y, ip+16, !PyArray_ISNOTSWAPPED(ap), NULL);
+ PyDataType_GetArrFuncs(descr)->copyswap(&q.z, ip+24, !PyArray_ISNOTSWAPPED(ap), NULL);
Py_DECREF(descr);
}
return (npy_bool) !quaternion_equal(q, zero);
@@ -942,7 +949,7 @@ QUATERNION_copyswap(quaternion *dst, qua
{
PyArray_Descr *descr;
descr = PyArray_DescrFromType(NPY_DOUBLE);
- descr->f->copyswapn(dst, sizeof(double), src, sizeof(double), 4, swap, NULL);
+ PyDataType_GetArrFuncs(descr)->copyswapn(dst, sizeof(double), src, sizeof(double), 4, swap, NULL);
Py_DECREF(descr);
}
@@ -953,10 +960,10 @@ QUATERNION_copyswapn(quaternion *dst, np
{
PyArray_Descr *descr;
descr = PyArray_DescrFromType(NPY_DOUBLE);
- descr->f->copyswapn(&dst->w, dstride, &src->w, sstride, n, swap, NULL);
- descr->f->copyswapn(&dst->x, dstride, &src->x, sstride, n, swap, NULL);
- descr->f->copyswapn(&dst->y, dstride, &src->y, sstride, n, swap, NULL);
- descr->f->copyswapn(&dst->z, dstride, &src->z, sstride, n, swap, NULL);
+ PyDataType_GetArrFuncs(descr)->copyswapn(&dst->w, dstride, &src->w, sstride, n, swap, NULL);
+ PyDataType_GetArrFuncs(descr)->copyswapn(&dst->x, dstride, &src->x, sstride, n, swap, NULL);
+ PyDataType_GetArrFuncs(descr)->copyswapn(&dst->y, dstride, &src->y, sstride, n, swap, NULL);
+ PyDataType_GetArrFuncs(descr)->copyswapn(&dst->z, dstride, &src->z, sstride, n, swap, NULL);
Py_DECREF(descr);
}
@@ -1481,28 +1488,29 @@ PyMODINIT_FUNC initnumpy_quaternion(void
_PyQuaternion_ArrFuncs.fillwithscalar = (PyArray_FillWithScalarFunc*)QUATERNION_fillwithscalar;
// The quaternion array descr
- quaternion_descr = PyObject_New(PyArray_Descr, &PyArrayDescr_Type);
- quaternion_descr->typeobj = &PyQuaternion_Type;
- quaternion_descr->kind = 'V';
- quaternion_descr->type = 'q';
- quaternion_descr->byteorder = '=';
- quaternion_descr->flags = NPY_NEEDS_PYAPI | NPY_USE_GETITEM | NPY_USE_SETITEM;
- quaternion_descr->type_num = 0; // assigned at registration
- quaternion_descr->elsize = quaternion_elsize;
- quaternion_descr->alignment = quaternion_alignment;
- quaternion_descr->subarray = NULL;
- quaternion_descr->fields = NULL;
- quaternion_descr->names = NULL;
- quaternion_descr->f = &_PyQuaternion_ArrFuncs;
- quaternion_descr->metadata = NULL;
- quaternion_descr->c_metadata = NULL;
+ Py_SET_TYPE(&quaternion_proto, &PyArrayDescr_Type);
+ quaternion_proto.typeobj = &PyQuaternion_Type;
+ quaternion_proto.kind = 'V';
+ quaternion_proto.type = 'q';
+ quaternion_proto.byteorder = '=';
+ quaternion_proto.flags = NPY_NEEDS_PYAPI | NPY_USE_GETITEM | NPY_USE_SETITEM;
+ quaternion_proto.type_num = 0; // assigned at registration
+ quaternion_proto.elsize = quaternion_elsize;
+ quaternion_proto.alignment = quaternion_alignment;
+ quaternion_proto.subarray = NULL;
+ quaternion_proto.fields = NULL;
+ quaternion_proto.names = NULL;
+ quaternion_proto.f = &_PyQuaternion_ArrFuncs;
+ quaternion_proto.metadata = NULL;
+ quaternion_proto.c_metadata = NULL;
Py_INCREF(&PyQuaternion_Type);
- quaternionNum = PyArray_RegisterDataType(quaternion_descr);
+ quaternionNum = PyArray_RegisterDataType(&quaternion_proto);
if (quaternionNum < 0) {
INITERROR;
}
+ quaternion_descr = PyArray_DescrFromType(quaternionNum);
register_cast_function(NPY_BOOL, quaternionNum, (PyArray_VectorUnaryFunc*)BOOL_to_quaternion);
register_cast_function(NPY_BYTE, quaternionNum, (PyArray_VectorUnaryFunc*)BYTE_to_quaternion);
(This doesn't include any of the setup.py changes, but I think you have them on your numpy2 branch.)
from quaternion.
Oh, thank you very much! I won't get a chance for another week or so, but I'll take a look at this ASAP!
from quaternion.
I started an effort in this direction, but it's very difficult. Will probably need help from some numpy devs.
from quaternion.
Now that Numpy 2+ is the official current release, finding a fix becomes urgent. I hope someone is able to help out. I have never done any programming with Numpy API, only use f2py.
from quaternion.
Unfortunately, because of how pip versioning works, I believe that only means that anyone with numpy 2 trying to install this package will just get the last version of this package that didn't include the restriction to numpy<2. But FWIW, I've added it now.
from quaternion.
See also quaternionic for a pure-python package I wrote that doesn't depend on numpy's C API.
from quaternion.
Until there is a solution for numpy 2.0.0 or higher, maybe add <2.0.0
to the requirements.txt file?
from quaternion.
For me, installing chainconsumer
, which does require numpy < 2
does the trick.
But, yes, I think also adding it to numpy-quaternion directly would be useful.
from quaternion.
You may be correct about that. Not sure how this can be fixed, there must be a way to modify past versions on PyPI - this would not be the first packages affected by incompatible changes of a dependent package. Rather, that must be the common case.
from quaternion.
Related Issues (20)
- None check fails HOT 1
- angular_velocity() output format HOT 2
- Euler angles are horrible, and so are quaternions HOT 2
- Documentation should clarify that the quaternions are defined using an active rotation convention HOT 2
- `np.sum` breaks in latest Numpy
- Object mode fallback deprecation in numba.jit
- Version number of latest release HOT 1
- Add a rotation example into the documentation HOT 1
- possible docstring error HOT 2
- add from_euler_angles equivalent for Tait-Bryan angles HOT 1
- slight improvement to "Why Euler angles are horrible"
- Identity decorator exception HOT 1
- Scalar quaternion objects are mutable HOT 1
- `cumprod()` with quaternions crashes HOT 5
- Computation Error: from euler angles to quaternion HOT 1
- Build problem on arm32v7 HOT 2
- allow np.float32 precision instead of default float64 or higher HOT 2
- quaternion dtype in cupy to benefit from GPU HOT 1
- Numpy 2.0.0 compatibility HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from quaternion.