summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTravis Oliphant <oliphant@enthought.com>2005-10-19 21:55:49 +0000
committerTravis Oliphant <oliphant@enthought.com>2005-10-19 21:55:49 +0000
commit19cba66a6dce0b657c1ee7c36734c7e578e17036 (patch)
tree3c73b67e55d6b578e21c32401fb89dfa0a788cf2
parent4ecebd345c59fccc0778231ea1f87577eeb437c4 (diff)
downloadnumpy-19cba66a6dce0b657c1ee7c36734c7e578e17036.tar.gz
Allow array scalars in f2py conversions.
-rw-r--r--scipy/base/code_generators/generate_array_api.py6
-rw-r--r--scipy/base/include/scipy/arrayobject.h3
-rw-r--r--scipy/base/oldnumeric.py51
-rw-r--r--scipy/base/src/scalartypes.inc.src23
-rw-r--r--scipy/base/ufunclike.py37
-rw-r--r--scipy/f2py2e/cfuncs.py53
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)) {