diff options
author | Travis Oliphant <oliphant@enthought.com> | 2005-10-19 21:55:49 +0000 |
---|---|---|
committer | Travis Oliphant <oliphant@enthought.com> | 2005-10-19 21:55:49 +0000 |
commit | 19cba66a6dce0b657c1ee7c36734c7e578e17036 (patch) | |
tree | 3c73b67e55d6b578e21c32401fb89dfa0a788cf2 | |
parent | 4ecebd345c59fccc0778231ea1f87577eeb437c4 (diff) | |
download | numpy-19cba66a6dce0b657c1ee7c36734c7e578e17036.tar.gz |
Allow array scalars in f2py conversions.
-rw-r--r-- | scipy/base/code_generators/generate_array_api.py | 6 | ||||
-rw-r--r-- | scipy/base/include/scipy/arrayobject.h | 3 | ||||
-rw-r--r-- | scipy/base/oldnumeric.py | 51 | ||||
-rw-r--r-- | scipy/base/src/scalartypes.inc.src | 23 | ||||
-rw-r--r-- | scipy/base/ufunclike.py | 37 | ||||
-rw-r--r-- | scipy/f2py2e/cfuncs.py | 53 |
6 files changed, 137 insertions, 36 deletions
diff --git a/scipy/base/code_generators/generate_array_api.py b/scipy/base/code_generators/generate_array_api.py index 24fc6ff88..b6d9b6633 100644 --- a/scipy/base/code_generators/generate_array_api.py +++ b/scipy/base/code_generators/generate_array_api.py @@ -88,6 +88,10 @@ objectapi_list = [ """, 'FromScalar', 'PyObject *, PyArray_Typecode *', 'PyObject *'), + (r"""Convert to c-type + """, + 'ScalarAsCtype', 'PyObject *, void *', 'void'), + (r"""Register Data type """, 'RegisterDataType', 'PyTypeObject *', 'int'), @@ -515,7 +519,7 @@ multiapi_list = [ types = ['Generic','Numeric','Integer','SignedInteger','UnsignedInteger', 'Inexact', - 'Floating', 'Complex', 'Flexible', 'Character', + 'Floating', 'ComplexFloating', 'Flexible', 'Character', 'Bool','Byte','Short','Int', 'Long', 'LongLong', 'UByte', 'UShort', 'UInt', 'ULong', 'ULongLong', 'Float', 'Double', 'LongDouble', 'CFloat', 'CDouble', 'CLongDouble', 'Object', 'String', 'Unicode', diff --git a/scipy/base/include/scipy/arrayobject.h b/scipy/base/include/scipy/arrayobject.h index 63d2bde0b..a252acc52 100644 --- a/scipy/base/include/scipy/arrayobject.h +++ b/scipy/base/include/scipy/arrayobject.h @@ -25,7 +25,8 @@ extern "C" { #define PY_FAIL 0 #define PY_SUCCEED 1 -#define NDARRAY_VERSION 0x0400 + /* Helpful to distinguish what is installed */ +#define NDARRAY_VERSION 0x0432 /* Some platforms don't define bool, long long, or long double. Handle that here. diff --git a/scipy/base/oldnumeric.py b/scipy/base/oldnumeric.py index fc930d7a6..817723c4d 100644 --- a/scipy/base/oldnumeric.py +++ b/scipy/base/oldnumeric.py @@ -5,6 +5,7 @@ import umath as um import numerictypes as nt from numeric import asarray, array, correlate, outer, concatenate import sys +_dt_ = nt.dtype2char #Use this to add a new axis to an array @@ -22,11 +23,11 @@ LittleEndian = (sys.byteorder == 'little') # backward compatible names from old Precision.py -Character = nt.string -UnsignedInt8 = nt.uint8 -UnsignedInt16 = nt.uint16 -UnsignedInt32 = nt.uint32 -UnsignedInt = nt.uint +Character = 'S1' +UnsignedInt8 = _dt_(nt.uint8) +UnsignedInt16 = _dt_(nt.uint16) +UnsignedInt32 = _dt_(nt.uint32) +UnsignedInt = _dt_(nt.uint) typecodes = {'Character':'S1', 'Integer':'bhilq', 'UnsignedInteger':'BHILQ', 'Float':'fdg', 'Complex':'FDG', 'AllInteger':'bBhHiIlLqQ', @@ -37,42 +38,42 @@ def sarray(a, dtype=None, copy=0): return array(a, dtype, copy) try: - UnsignedInt64 = nt.uint64 - UnsignedInt128 = nt.uint128 + UnsignedInt64 = _dt_(nt.uint64) + UnsignedInt128 = _dt_(nt.uint128) except AttributeError: pass -Int8 = nt.int8 -Int16 = nt.int16 -Int32 = nt.int32 +Int8 = _dt_(nt.int8) +Int16 = _dt_(nt.int16) +Int32 = _dt_(nt.int32) try: - Int64 = nt.int64 - Int128 = nt.int128 + Int64 = _dt_(nt.int64) + Int128 = _dt_(nt.int128) except AttributeError: pass -Int0 = nt.int -Int = nt.int -Float0 = nt.float -Float = nt.float -Complex0 = nt.complex -Complex = nt.complex -PyObject = nt.object +Int0 = _dt_(nt.int) +Int = _dt_(nt.int) +Float0 = _dt_(nt.float) +Float = _dt_(nt.float) +Complex0 = _dt_(nt.complex) +Complex = _dt_(nt.complex) +PyObject = _dt_(nt.object) -Float32 = nt.float32 -Float64 = nt.float64 +Float32 = _dt_(nt.float32) +Float64 = _dt_(nt.float64) try: - Float128 = nt.float128 + Float128 = _dt_(nt.float128) except AttributeError: pass -Complex32 = nt.complex64 -Complex64 = nt.complex128 +Complex32 = _dt_(nt.complex64) +Complex64 = _dt_(nt.complex128) try: - Complex128 = nt.complex256 + Complex128 = _dt_(nt.complex256) except AttributeError: pass diff --git a/scipy/base/src/scalartypes.inc.src b/scipy/base/src/scalartypes.inc.src index 5ddc08d64..aac82345f 100644 --- a/scipy/base/src/scalartypes.inc.src +++ b/scipy/base/src/scalartypes.inc.src @@ -39,6 +39,29 @@ typedef struct { char *obval; } PyVoidScalarObject; +/* no error checking is performed -- ctypeptr must be same type as scalar */ +static void +PyArray_ScalarAsCtype(PyObject *scalar, void *ctypeptr) +{ + PyArray_Typecode typecode; + PyArray_TypecodeFromScalar(scalar, &typecode); + + if (PyTypeNum_ISFLEXIBLE(typecode.type_num)) { + void **newptr = (void **)ctypeptr; + switch(typecode.type_num) { + case PyArray_STRING: + *newptr = (void *)PyString_AS_STRING(scalar); + case PyArray_UNICODE: + *newptr = (void *)PyUnicode_AS_DATA(scalar); + case PyArray_VOID: + *newptr = ((PyVoidScalarObject *)scalar)->obval; + } + } + memcpy(ctypeptr, &(((PyScalarObject *)scalar)->obval), + sizeof(typecode.itemsize)); + return; +} + /* 0-dim array from array-scalar object */ static PyObject * diff --git a/scipy/base/ufunclike.py b/scipy/base/ufunclike.py index 8ef479057..7ee7c6cc0 100644 --- a/scipy/base/ufunclike.py +++ b/scipy/base/ufunclike.py @@ -1,19 +1,23 @@ import numeric as _nx -from numeric import asarray, empty, empty_like, isinf, signbit +from numeric import asarray, empty, empty_like, isinf, signbit, zeros import umath -__all__ = ['fix','isneginf','isposinf','sign'] +__all__ = ['fix','isneginf','isposinf','sign','log2'] def fix(x, y=None): """ Round x to nearest integer towards zero. """ - x = asarray(x) + x = asarray(x) if y is None: y = _nx.floor(x) else: _nx.floor(x,y) - y[x<0] = y[x<0]+1 + if x.ndim == 0: + if (x<0): + y += 1 + else: + y[x<0] = y[x<0]+1 return y def isposinf(x, y=None): @@ -33,11 +37,26 @@ def sign(x, y=None): function: where x is less than 0 return -1, where x greater than 0, a=1, elsewhere a=0. """ - x = asarray(x) + x = asarray(x) if y is None: - y = empty(x.shape, dtype=_nx.int_) - y[x<0] = -1 - y[x>0] = 1 - y[x==0] = 0 + y = zeros(x.shape, dtype=_nx.int_) + if x.ndim == 0: + if x<0: + y -= 1 + elif x>0: + y += 1 + else: + y[x<0] = -1 + y[x>0] = 1 return y +_log2 = umath.log(2) +def log2(x, y=None): + x = asarray(x) + if y is None: + y = umath.log(x) + else: + res = umath.log(x,y) + y /= _log2 + return y + diff --git a/scipy/f2py2e/cfuncs.py b/scipy/f2py2e/cfuncs.py index 761410045..20609b182 100644 --- a/scipy/f2py2e/cfuncs.py +++ b/scipy/f2py2e/cfuncs.py @@ -875,6 +875,16 @@ needs['long_double_from_pyobj']=['double_from_pyobj','long_double'] cfuncs['long_double_from_pyobj']="""\ static int long_double_from_pyobj(long_double* v,PyObject *obj,const char *errmess) { \tdouble d=0; +\tif (PyArray_CheckScalar(obj)){ +\t\tif PyArray_IsScalar(obj, LongDouble) { +\t\t\tPyArray_ScalarAsCtype(obj, v); +\t\t\treturn 1; +\t\t} +\t\telse if (PyArray_Check(obj) && PyArray_TYPE(obj)==PyArray_LONGDOUBLE) { +\t\t\t(*v) = *((longdouble *)PyArray_DATA(obj)) +\t\t\treturn 1; +\t\t} +\t} \tif (double_from_pyobj(&d,obj,errmess)) { \t\t*v = (long_double)d; \t\treturn 1; @@ -938,6 +948,17 @@ needs['complex_long_double_from_pyobj']=['complex_long_double','long_double', cfuncs['complex_long_double_from_pyobj']="""\ static int complex_long_double_from_pyobj(complex_long_double* v,PyObject *obj,const char *errmess) { \tcomplex_double cd={0.0,0.0}; +\tif (PyArray_CheckScalar(obj)){ +\t\tif PyArray_IsScalar(obj, CLongDouble) { +\t\t\tPyArray_ScalarAsCtype(obj, v); +\t\t\treturn 1; +\t\t} +\t\telse if (PyArray_Check(obj) && PyArray_TYPE(obj)==PyArray_CLONGDOUBLE) { +\t\t\t(*v).r = ((clongdouble *)PyArray_DATA(obj))->real; +\t\t\t(*v).i = ((clongdouble *)PyArray_DATA(obj))->imag; +\t\t\treturn 1; +\t\t} +\t} \tif (complex_double_from_pyobj(&cd,obj,errmess)) { \t\t(*v).r = (long_double)cd.r; \t\t(*v).i = (long_double)cd.i; @@ -955,6 +976,38 @@ static int complex_double_from_pyobj(complex_double* v,PyObject *obj,const char \t\t(*v).r=c.real, (*v).i=c.imag; \t\treturn 1; \t} +\tif (PyArray_IsScalar(obj, ComplexFloating)) { +\t\tif (PyArray_IsScalar(obj, CFloat)) { +\t\t\tcfloat new; +\t\t\tPyArray_ScalarAsCtype(obj, &new); +\t\t\t(*v).r = (double)new.real; +\t\t\t(*v).i = (double)new.imag; +\t\t} +\t\telse if (PyArray_IsScalar(obj, CLongDouble)) { +\t\t\tclongdouble new; +\t\t\tPyArray_ScalarAsCtype(obj, &new); +\t\t\t(*v).r = (double)new.real; +\t\t\t(*v).i = (double)new.imag; +\t\t} +\t\telse { /* if (PyArray_IsScalar(obj, CDouble)) */ +\t\t\tPyArray_ScalarAsCtype(obj, v); +\t\t} +\t\treturn 1; +\t} +\tif (PyArray_CheckScalar(obj)) { /* 0-dim array or still array scalar */ +\t\tPyObject *arr; +\t\tPyArray_Typecode otype = {PyArray_CDOUBLE, sizeof(cdouble), 0}; +\t\tif (PyArray_Check(obj)) { +\t\t\tarr = PyArray_CastToType((PyArrayObject *)obj, &otype); +\t\t} +\t\telse { +\t\t\tarr = PyArray_FromScalar(obj, &otype); +\t\t} +\t\tif (arr==NULL) return 0; +\t\t(*v).r = ((cdouble *)PyArray_DATA(arr))->real; +\t\t(*v).i = ((cdouble *)PyArray_DATA(arr))->imag; +\t\treturn 1; +\t} \t/* Python does not provide PyNumber_Complex function :-( */ \t(*v).i=0.0; \tif (PyFloat_Check(obj)) { |