From 25c8d48cc40b05ef9e8483e8fb1c526eb28a0941 Mon Sep 17 00:00:00 2001 From: Daniel Holden Date: Sat, 23 Feb 2013 11:57:20 +0000 Subject: [PATCH 1/2] Fixed compile bugs under Visual Studio --- numpy_quaternion.c | 5 ++- quaternion.c | 101 +++++++++++++++++++++++++++++++++++---------- quaternion.h | 1 + 3 files changed, 84 insertions(+), 23 deletions(-) diff --git a/numpy_quaternion.c b/numpy_quaternion.c index 31a5f2a..3695d84 100644 --- a/numpy_quaternion.c +++ b/numpy_quaternion.c @@ -308,7 +308,7 @@ QUATERNION_nonzero (char *ip, PyArrayObject *ap) descr->f->copyswap(&q.z, ip+24, !PyArray_ISNOTSWAPPED(ap), NULL); Py_DECREF(descr); } - return (npy_bool) !quaternion_equal(q, (quaternion) {0,0,0,0}); + return (npy_bool) !quaternion_equal(q, quaternion_new(0,0,0,0)); } static void @@ -480,7 +480,8 @@ BINARY_UFUNC(subtract, quaternion) BINARY_UFUNC(multiply, quaternion) BINARY_UFUNC(divide, quaternion) BINARY_UFUNC(power, quaternion) -BINARY_UFUNC(copysign, quaternion) +/* Some bug in the visual studio compiler means this must be expanded by hand */ +BINARY_GEN_UFUNC(copysign, copysign, quaternion, quaternion) BINARY_UFUNC(equal, npy_bool) BINARY_UFUNC(not_equal, npy_bool) BINARY_UFUNC(less, npy_bool) diff --git a/quaternion.c b/quaternion.c index fb14212..0576a3a 100644 --- a/quaternion.c +++ b/quaternion.c @@ -31,6 +31,68 @@ #define _QUAT_EPS 1e-6 +#ifndef isnan +static int +isnan(double var) +{ + volatile double d = var; + return d != d; +} +#endif + +#ifndef isinf +static int +isinf(double x) +{ + return !isnan(x) && isnan(x - x); +} +#endif + +#ifndef isfinite +static int +isfinite(double x) +{ + return !isinf(x); +} +#endif + +#ifndef copysign + +typedef union { + struct { + unsigned long hi; + unsigned long lo; + } i; + double d; +} hexdouble; + +static double +copysign(double x, double y) +{ + hexdouble hx, hy; + + hx.d = x; + hy.d = y; + + hx.i.hi &= 0x7fffffff; + hx.i.hi |= hy.i.hi & 0x80000000; + + return hx.d; +} + +#endif + +quaternion +quaternion_new(double w, double x, double y, double z) +{ + quaternion q; + q.w = w; + q.w = w; + q.w = w; + q.w = w; + return q; +} + int quaternion_isnonzero(quaternion q) { @@ -64,58 +126,55 @@ quaternion_absolute(quaternion q) quaternion quaternion_add(quaternion q1, quaternion q2) { - return (quaternion) { + return quaternion_new( q1.w+q2.w, q1.x+q2.x, q1.y+q2.y, - q1.z+q2.z, - }; + q1.z+q2.z); } quaternion quaternion_subtract(quaternion q1, quaternion q2) { - return (quaternion) { + return quaternion_new( q1.w-q2.w, q1.x-q2.x, q1.y-q2.y, - q1.z-q2.z, - }; + q1.z-q2.z); } quaternion quaternion_multiply(quaternion q1, quaternion q2) { - return (quaternion) { + return quaternion_new( q1.w*q2.w - q1.x*q2.x - q1.y*q2.y - q1.z*q2.z, q1.w*q2.x + q1.x*q2.w + q1.y*q2.z - q1.z*q2.y, q1.w*q2.y - q1.x*q2.z + q1.y*q2.w + q1.z*q2.x, - q1.w*q2.z + q1.x*q2.y - q1.y*q2.x + q1.z*q2.w, - }; + q1.w*q2.z + q1.x*q2.y - q1.y*q2.x + q1.z*q2.w); } quaternion quaternion_divide(quaternion q1, quaternion q2) { double s = q2.w*q2.w + q2.x*q2.x + q2.y*q2.y + q2.z*q2.z; - return (quaternion) { + return quaternion_new ( ( q1.w*q2.w + q1.x*q2.x + q1.y*q2.y + q1.z*q2.z) / s, (- q1.w*q2.x + q1.x*q2.w + q1.y*q2.z - q1.z*q2.y) / s, (- q1.w*q2.y - q1.x*q2.z + q1.y*q2.w + q1.z*q2.x) / s, (- q1.w*q2.z + q1.x*q2.y - q1.y*q2.x + q1.z*q2.w) / s - }; + ); } quaternion quaternion_multiply_scalar(quaternion q, double s) { - return (quaternion) {s*q.w, s*q.x, s*q.y, s*q.z}; + return quaternion_new(s*q.w, s*q.x, s*q.y, s*q.z); } quaternion quaternion_divide_scalar(quaternion q, double s) { - return (quaternion) {q.w/s, q.x/s, q.y/s, q.z/s}; + return quaternion_new(q.w/s, q.x/s, q.y/s, q.z/s); } quaternion @@ -126,9 +185,9 @@ quaternion_log(quaternion q) if (vnorm > _QUAT_EPS) { double m = sqrt(q.w*q.w + sumvsq); double s = acos(q.w/m) / vnorm; - return (quaternion) {log(m), s*q.x, s*q.y, s*q.z}; + return quaternion_new(log(m), s*q.x, s*q.y, s*q.z); } else { - return (quaternion) {0, 0, 0, 0}; + return quaternion_new(0, 0, 0, 0); } } @@ -139,9 +198,9 @@ quaternion_exp(quaternion q) if (vnorm > _QUAT_EPS) { double s = sin(vnorm) / vnorm; double e = exp(q.w); - return (quaternion) {e*cos(vnorm), e*s*q.x, e*s*q.y, e*s*q.z}; + return quaternion_new(e*cos(vnorm), e*s*q.x, e*s*q.y, e*s*q.z); } else { - return (quaternion) {exp(q.w), 0, 0, 0}; + return quaternion_new(exp(q.w), 0, 0, 0); } } @@ -160,24 +219,24 @@ quaternion_power_scalar(quaternion q, double p) quaternion quaternion_negative(quaternion q) { - return (quaternion) {-q.w, -q.x, -q.y, -q.z}; + return quaternion_new(-q.w, -q.x, -q.y, -q.z); } quaternion quaternion_conjugate(quaternion q) { - return (quaternion) {q.w, -q.x, -q.y, -q.z}; + return quaternion_new(q.w, -q.x, -q.y, -q.z); } quaternion quaternion_copysign(quaternion q1, quaternion q2) { - return (quaternion) { + return quaternion_new( copysign(q1.w, q2.w), copysign(q1.x, q2.x), copysign(q1.y, q2.y), copysign(q1.z, q2.z) - }; + ); } int diff --git a/quaternion.h b/quaternion.h index d889bc5..c1ab1ed 100644 --- a/quaternion.h +++ b/quaternion.h @@ -40,6 +40,7 @@ typedef struct { double z; } quaternion; +quaternion quaternion_new(double w, double x, double y, double z); int quaternion_isnonzero(quaternion q); int quaternion_isnan(quaternion q); int quaternion_isinf(quaternion q); From d73b837454c37f6fa5737f7dcb5ba944789949c7 Mon Sep 17 00:00:00 2001 From: Daniel Holden Date: Fri, 23 Aug 2013 13:24:42 +0100 Subject: [PATCH 2/2] Update quaternion.c --- quaternion.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/quaternion.c b/quaternion.c index 0576a3a..e95b253 100644 --- a/quaternion.c +++ b/quaternion.c @@ -87,9 +87,9 @@ quaternion_new(double w, double x, double y, double z) { quaternion q; q.w = w; - q.w = w; - q.w = w; - q.w = w; + q.x = x; + q.y = y; + q.z = z; return q; }