/* -*- c -*- */ /* The purpose of this module is to add faster math for array scalars that does not go through the ufunc machinery but still supports error-modes. NOT FINISHED */ #include "numpy/arrayobject.h" #include "numpy/ufuncobject.h" /* The general strategy is to 1) Make self the array scalar and "other" the other data-type 2) If both are the same data-type, then do a quick exit. 3) If other is another array scalar, then a) If it can be cast then cast and calculate b) Otherwise, return NotImplemented (or call the appropriate function on other... --- shortcut what Python will do anyway). 4) If other is a 0-d array -- Cast it to an array scalar and do #3 5) If other is a Python scalar -- Cast it to an array scalar and do #3 5) Go through the ufunc machinery for all other cases. */ #define _CREATE_SELF_OTHER(a, b, NAME) { \ if PyObject_IsScalar(a, NAME) { \ self = a; \ other = b; \ } \ else { \ self = b; \ other = a; \ if (!PyObject_IsScalar(self, @NAME@)) { \ Py_INCREF(Py_NotImplemented); \ return Py_NotImplemented; \ } \ } \ } /**begin repeat #name=byte,ubyte,short,ushort,int,uint,long,ulong,float,double,longdouble,cfloat,cdouble,clongdouble# #Name=Byte, Short, Int, Long, LongLong, UByte, UShort, UInt, ULong, ULongLong, Float, Double, LongDouble, CFloat, CDouble, CLongDouble# **/ static PyObject * @name@_add(PyObject *a, PyObject *b) { PyObject *self, *other, *arg3, *temp; _CREATE_SELF_OTHER(a, b, @NAME@); if PyObject_IsScalar(other, @NAME@) { arg3 = other; Py_INCREF(arg3); } else if ((temp = _object_to_scalar(other)) != NULL) { } } static PyObject * @name@_subtract(PyObject *a, PyObject *b) { } static PyObject * @name@_multiply(PyObject *a, PyObject *b) { } static PyObject * @name@_divide(PyObject *a, PyObject *b) { } static PyObject * @name@_remainder(PyObject *a, PyObject *b) { } static PyObject * @name@_divmod(PyObject *a, PyObject *b) { } static PyObject * @name@_power(PyObject *a, PyObject *b) { } static PyObject * @name@_negative(PyObject *a, PyObject *b) { } static PyObject * @name@_copy(PyObject *a, PyObject *b) { } static PyObject * @name@_absolute(PyObject *a, PyObject *b) { } static PyObject * @name@_nonzero_number(PyObject *a, PyObject *b) { } static PyObject * @name@_invert(PyObject *a, PyObject *b) { } static PyObject * @name@_lshift(PyObject *a, PyObject *b) { } static PyObject * @name@_rshift(PyObject *a, PyObject *b) { } static PyObject * @name@_and(PyObject *a, PyObject *b) { } static PyObject * @name@_xor(PyObject *a, PyObject *b) { } static PyObject * @name@_or(PyObject *a, PyObject *b) { } static PyObject * @name@_int(PyObject *a, PyObject *b) { } static PyObject * @name@_long(PyObject *a, PyObject *b) { } static PyObject * @name@_float(PyObject *a, PyObject *b) { } static PyObject * @name@_oct(PyObject *a, PyObject *b) { } static PyObject * @name@_hex(PyObject *a, PyObject *b) { } static PyObject * @name@_floor_divide(PyObject *a, PyObject *b) { } static PyObject * @name@_true_divide(PyObject *a, PyObject *b) { } #if PY_VERSION_HEX >= 0x02050000 static Py_ssize_t @name@_index(PyObject *a) { } #endif static PyObject* @name@_richcompare(PyObject *self, PyObject *other, int cmp_op) { } /**end repeat**/ /**begin repeat #name=byte,ubyte,short,ushort,int,uint,long,ulong,float,double,longdouble,cfloat,cdouble,clongdouble# **/ static PyNumberMethods @name@_as_number = { (binaryfunc)@name@_add, /*nb_add*/ (binaryfunc)@name@_subtract, /*nb_subtract*/ (binaryfunc)@name@_multiply, /*nb_multiply*/ (binaryfunc)@name@_divide, /*nb_divide*/ (binaryfunc)@name@_remainder, /*nb_remainder*/ (binaryfunc)@name@_divmod, /*nb_divmod*/ (ternaryfunc)@name@_power, /*nb_power*/ (unaryfunc)@name@_negative, (unaryfunc)@name@_copy, /*nb_pos*/ (unaryfunc)@name@_absolute, /*nb_abs*/ (inquiry)@name@_nonzero_number, /*nb_nonzero*/ (unaryfunc)@name@_invert, /*nb_invert*/ (binaryfunc)@name@_lshift, /*nb_lshift*/ (binaryfunc)@name@_rshift, /*nb_rshift*/ (binaryfunc)@name@_and, /*nb_and*/ (binaryfunc)@name@_xor, /*nb_xor*/ (binaryfunc)@name@_or, /*nb_or*/ 0, /*nb_coerce*/ (unaryfunc)@name@_int, /*nb_int*/ (unaryfunc)@name@_long, /*nb_long*/ (unaryfunc)@name@_float, /*nb_float*/ (unaryfunc)@name@_oct, /*nb_oct*/ (unaryfunc)@name@_hex, /*nb_hex*/ 0, /*inplace_add*/ 0, /*inplace_subtract*/ 0, /*inplace_multiply*/ 0, /*inplace_divide*/ 0, /*inplace_remainder*/ 0, /*inplace_power*/ 0, /*inplace_lshift*/ 0, /*inplace_rshift*/ 0, /*inplace_and*/ 0, /*inplace_xor*/ 0, /*inplace_or*/ (binaryfunc)@name@_floor_divide, /*nb_floor_divide*/ (binaryfunc)@name@_true_divide, /*nb_true_divide*/ 0, /*nb_inplace_floor_divide*/ 0, /*nb_inplace_true_divide*/ #if PY_VERSION_HEX >= 0x02050000 (lenfunc)@name@_index, /*nb_index*/ #endif }; static void add_scalarmath(void) { /**begin repeat #name=byte,ubyte,short,ushort,int,uint,long,ulong,float,double,longdouble,cfloat,cdouble,clongdouble# #NAME=Byte, Short, Int, Long, LongLong, UByte, UShort, UInt, ULong, ULongLong, Float, Double, LongDouble, CFloat, CDouble, CLongDouble# **/ PyArr@NAME@Type_Type.tp_as_number = @name@_as_number; PyArr@NAME@Type_Type.tp_richcompare = @name@_richcompare; /**end repeat**/ } static struct PyMethodDef methods[] = { {"alter_pyscalars", (PyCFunction) alter_pyscalars, METH_VARARGS , doc_alterpyscalars}, {NULL, NULL, 0} }; DL_EXPORT(void) initscalarmath(void) { PyObject *m; m = Py_initModule("scalarmath", methods); if (import_array() < 0) return; if (import_umath() < 0) return; add_scalarmath(); return; }