From numpy-svn at scipy.org Fri Mar 2 11:49:04 2007
From: numpy-svn at scipy.org (numpy-svn at scipy.org)
Date: Fri, 2 Mar 2007 10:49:04 -0600 (CST)
Subject: [Numpy-svn] r3568 - trunk/numpy/distutils/fcompiler
Message-ID: <20070302164904.893D239C36B@new.scipy.org>
Author: pearu
Date: 2007-03-02 10:49:00 -0600 (Fri, 02 Mar 2007)
New Revision: 3568
Modified:
trunk/numpy/distutils/fcompiler/ibm.py
Log:
Applying info from Hans-Joachim Ehlers to improve xlf compiler support (on AIX using lslpp to determine compiler version).
Modified: trunk/numpy/distutils/fcompiler/ibm.py
===================================================================
--- trunk/numpy/distutils/fcompiler/ibm.py 2007-02-28 23:52:12 UTC (rev 3567)
+++ trunk/numpy/distutils/fcompiler/ibm.py 2007-03-02 16:49:00 UTC (rev 3568)
@@ -3,6 +3,7 @@
import sys
from numpy.distutils.fcompiler import FCompiler
+from numpy.distutils.exec_command import exec_command, find_executable
from distutils import log
class IbmFCompiler(FCompiler):
@@ -23,19 +24,18 @@
def get_version(self,*args,**kwds):
version = FCompiler.get_version(self,*args,**kwds)
- if version is None:
- # Let's try version_cmd without -qversion flag that
- # xlf versions <=8.x don't have.
- version_cmd = self.version_cmd
- orig_version_cmd = version_cmd[:]
- if '-qversion' in version_cmd:
- version_cmd.remove('-qversion')
- version = FCompiler.get_version(self,*args,**kwds)
- if version is None:
- version_cmd[:] = orig_version_cmd
+ if version is None and sys.platform.startswith('aix'):
+ # use lslpp to find out xlf version
+ lslpp = find_executable('lslpp')
+ xlf = find_executable('xlf')
+ if os.path.exists(xlf) and os.path.exists(lslpp):
+ s,o = exec_command(lslpp + ' -Lc xlfcmp')
+ m = re.search('xlfcmp:(?P\d+([.]\d+)+)', o)
+ if m: version = m.group('version')
xlf_dir = '/etc/opt/ibmcmp/xlf'
if version is None and os.path.isdir(xlf_dir):
+ # linux:
# If the output of xlf does not contain version info
# (that's the case with xlf 8.1, for instance) then
# let's try another method:
From numpy-svn at scipy.org Sun Mar 4 05:47:13 2007
From: numpy-svn at scipy.org (numpy-svn at scipy.org)
Date: Sun, 4 Mar 2007 04:47:13 -0600 (CST)
Subject: [Numpy-svn] r3569 - trunk/numpy/distutils
Message-ID: <20070304104713.6381C39C0C3@new.scipy.org>
Author: timl
Date: 2007-03-04 04:47:08 -0600 (Sun, 04 Mar 2007)
New Revision: 3569
Modified:
trunk/numpy/distutils/misc_util.py
Log:
add a delete flag to make_svn_version_py to allow the __svn_version.py to not be deleted
Modified: trunk/numpy/distutils/misc_util.py
===================================================================
--- trunk/numpy/distutils/misc_util.py 2007-03-02 16:49:00 UTC (rev 3568)
+++ trunk/numpy/distutils/misc_util.py 2007-03-04 10:47:08 UTC (rev 3569)
@@ -1304,7 +1304,7 @@
return version
- def make_svn_version_py(self):
+ def make_svn_version_py(self, delete=True):
""" Generate package __svn_version__.py file from SVN revision number,
it will be removed after python exits but will be available
when sdist, etc commands are executed.
@@ -1326,10 +1326,12 @@
import atexit
def rm_file(f=target,p=self.info):
- try: os.remove(f); p('removed '+f)
- except OSError: pass
- try: os.remove(f+'c'); p('removed '+f+'c')
- except OSError: pass
+ if delete:
+ try: os.remove(f); p('removed '+f)
+ except OSError: pass
+ try: os.remove(f+'c'); p('removed '+f+'c')
+ except OSError: pass
+
atexit.register(rm_file)
return target
From numpy-svn at scipy.org Mon Mar 5 01:04:06 2007
From: numpy-svn at scipy.org (numpy-svn at scipy.org)
Date: Mon, 5 Mar 2007 00:04:06 -0600 (CST)
Subject: [Numpy-svn] r3570 - trunk/numpy/testing
Message-ID: <20070305060406.6C3A839C096@new.scipy.org>
Author: timl
Date: 2007-03-05 00:03:54 -0600 (Mon, 05 Mar 2007)
New Revision: 3570
Modified:
trunk/numpy/testing/numpytest.py
Log:
fix bug with test_suite being called incorrectly
Modified: trunk/numpy/testing/numpytest.py
===================================================================
--- trunk/numpy/testing/numpytest.py 2007-03-04 10:47:08 UTC (rev 3569)
+++ trunk/numpy/testing/numpytest.py 2007-03-05 06:03:54 UTC (rev 3570)
@@ -398,7 +398,7 @@
mstr = self._module_str
suite_list = []
if hasattr(test_module,'test_suite'):
- suite_list.extend(test_module.test_suite(level)._tests)
+ suite_list.extend(test_module.test_suite._tests)
for name in dir(test_module):
obj = getattr(test_module, name)
if type(obj) is not type(unittest.TestCase) \
From numpy-svn at scipy.org Mon Mar 5 01:06:21 2007
From: numpy-svn at scipy.org (numpy-svn at scipy.org)
Date: Mon, 5 Mar 2007 00:06:21 -0600 (CST)
Subject: [Numpy-svn] r3571 - trunk/numpy/testing
Message-ID: <20070305060621.43D0E39C096@new.scipy.org>
Author: timl
Date: 2007-03-05 00:06:12 -0600 (Mon, 05 Mar 2007)
New Revision: 3571
Modified:
trunk/numpy/testing/numpytest.py
Log:
scratch that last one. my bad
Modified: trunk/numpy/testing/numpytest.py
===================================================================
--- trunk/numpy/testing/numpytest.py 2007-03-05 06:03:54 UTC (rev 3570)
+++ trunk/numpy/testing/numpytest.py 2007-03-05 06:06:12 UTC (rev 3571)
@@ -398,7 +398,7 @@
mstr = self._module_str
suite_list = []
if hasattr(test_module,'test_suite'):
- suite_list.extend(test_module.test_suite._tests)
+ suite_list.extend(test_module.test_suite(level)._tests)
for name in dir(test_module):
obj = getattr(test_module, name)
if type(obj) is not type(unittest.TestCase) \
From numpy-svn at scipy.org Wed Mar 7 14:12:30 2007
From: numpy-svn at scipy.org (numpy-svn at scipy.org)
Date: Wed, 7 Mar 2007 13:12:30 -0600 (CST)
Subject: [Numpy-svn] r3572 - trunk/numpy/linalg
Message-ID: <20070307191230.DE45A39C0A3@new.scipy.org>
Author: oliphant
Date: 2007-03-07 13:12:26 -0600 (Wed, 07 Mar 2007)
New Revision: 3572
Modified:
trunk/numpy/linalg/lapack_litemodule.c
Log:
Fix problem 64-bit linalg.qr problem.
Modified: trunk/numpy/linalg/lapack_litemodule.c
===================================================================
--- trunk/numpy/linalg/lapack_litemodule.c 2007-03-05 06:06:12 UTC (rev 3571)
+++ trunk/numpy/linalg/lapack_litemodule.c 2007-03-07 19:12:26 UTC (rev 3572)
@@ -520,7 +520,7 @@
int lda;
int info;
- TRY(PyArg_ParseTuple(args,"llOlOOll",&m,&n,&a,&lda,&tau,&work,&lwork,&info));
+ TRY(PyArg_ParseTuple(args,"iiOiOOii",&m,&n,&a,&lda,&tau,&work,&lwork,&info));
/* check objects and convert to right storage order */
TRY(check_object(a,PyArray_DOUBLE,"a","PyArray_DOUBLE","dgeqrf"));
@@ -531,7 +531,7 @@
FNAME(dgeqrf)(&m, &n, DDATA(a), &lda, DDATA(tau),
DDATA(work), &lwork, &info);
- return Py_BuildValue("{s:l,s:l,s:l,s:l,s:l,s:l}","dgeqrf_",
+ return Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i}","dgeqrf_",
lapack_lite_status__,"m",m,"n",n,"lda",lda,
"lwork",lwork,"info",info);
}
@@ -546,14 +546,14 @@
int lda;
int info;
- TRY(PyArg_ParseTuple(args,"lllOlOOll", &m, &n, &k, &a, &lda, &tau, &work, &lwork, &info));
+ TRY(PyArg_ParseTuple(args,"iiiOiOOii", &m, &n, &k, &a, &lda, &tau, &work, &lwork, &info));
TRY(check_object(a,PyArray_DOUBLE,"a","PyArray_DOUBLE","dorgqr"));
TRY(check_object(tau,PyArray_DOUBLE,"tau","PyArray_DOUBLE","dorgqr"));
TRY(check_object(work,PyArray_DOUBLE,"work","PyArray_DOUBLE","dorgqr"));
lapack_lite_status__ = \
FNAME(dorgqr)(&m, &n, &k, DDATA(a), &lda, DDATA(tau), DDATA(work), &lwork, &info);
- return Py_BuildValue("{s:l,s:l}","dorgqr_",lapack_lite_status__,
+ return Py_BuildValue("{s:i,s:i}","dorgqr_",lapack_lite_status__,
"info",info);
}
@@ -778,7 +778,7 @@
int lda;
int info;
- TRY(PyArg_ParseTuple(args,"lllOlOOll", &m, &n, &k, &a, &lda, &tau, &work, &lwork, &info));
+ TRY(PyArg_ParseTuple(args,"iiiOiOOii", &m, &n, &k, &a, &lda, &tau, &work, &lwork, &info));
TRY(check_object(a,PyArray_CDOUBLE,"a","PyArray_CDOUBLE","zungqr"));
TRY(check_object(tau,PyArray_CDOUBLE,"tau","PyArray_CDOUBLE","zungqr"));
TRY(check_object(work,PyArray_CDOUBLE,"work","PyArray_CDOUBLE","zungqr"));
@@ -788,7 +788,7 @@
FNAME(zungqr)(&m, &n, &k, ZDATA(a), &lda, ZDATA(tau), ZDATA(work),
&lwork, &info);
- return Py_BuildValue("{s:l,s:l}","zungqr_",lapack_lite_status__,
+ return Py_BuildValue("{s:i,s:i}","zungqr_",lapack_lite_status__,
"info",info);
}
From numpy-svn at scipy.org Mon Mar 12 13:07:28 2007
From: numpy-svn at scipy.org (numpy-svn at scipy.org)
Date: Mon, 12 Mar 2007 12:07:28 -0500 (CDT)
Subject: [Numpy-svn] r3573 - trunk/numpy/core/tests
Message-ID: <20070312170728.15DF339C032@new.scipy.org>
Author: stefan
Date: 2007-03-12 12:07:19 -0500 (Mon, 12 Mar 2007)
New Revision: 3573
Modified:
trunk/numpy/core/tests/test_regression.py
Log:
Add test for ticket #449.
Modified: trunk/numpy/core/tests/test_regression.py
===================================================================
--- trunk/numpy/core/tests/test_regression.py 2007-03-07 19:12:26 UTC (rev 3572)
+++ trunk/numpy/core/tests/test_regression.py 2007-03-12 17:07:19 UTC (rev 3573)
@@ -608,7 +608,7 @@
todivide = N.array([2.0, 0.5, 0.25])
assert_equal(N.subtract.reduce(tosubtract), -10)
assert_equal(N.divide.reduce(todivide), 16.0)
- assert_array_equal(N.subtract.accumulate(tosubtract),
+ assert_array_equal(N.subtract.accumulate(tosubtract),
N.array([0, -1, -3, -6, -10]))
assert_array_equal(N.divide.accumulate(todivide),
N.array([2., 4., 16.]))
@@ -622,6 +622,12 @@
self.failUnlessRaises(AssertionError,N.convolve,[],[1])
self.failUnlessRaises(AssertionError,N.convolve,[1],[])
+ def check_multidim_byteswap(self, level=rlevel):
+ """Ticket #449"""
+ r=N.array([(1,(0,1,2))], dtype="i2,3i2")
+ assert_array_equal(r.byteswap(),
+ N.array([(256,(0,256,512))],r.dtype))
+
def check_string_NULL(self, level=rlevel):
"""Changeset 3557"""
assert_equal(N.array("a\x00\x0b\x0c\x00").item(),
From numpy-svn at scipy.org Wed Mar 14 11:48:04 2007
From: numpy-svn at scipy.org (numpy-svn at scipy.org)
Date: Wed, 14 Mar 2007 10:48:04 -0500 (CDT)
Subject: [Numpy-svn] r3574 - trunk/numpy/doc/swig
Message-ID: <20070314154804.8416139C08E@new.scipy.org>
Author: wfspotz at sandia.gov
Date: 2007-03-14 10:47:12 -0500 (Wed, 14 Mar 2007)
New Revision: 3574
Added:
trunk/numpy/doc/swig/numpy_swig.html
trunk/numpy/doc/swig/numpy_swig.txt
Removed:
trunk/numpy/doc/swig/HelperFunctions.txt
Modified:
trunk/numpy/doc/swig/Makefile
trunk/numpy/doc/swig/README
trunk/numpy/doc/swig/Series.i
trunk/numpy/doc/swig/numpy.i
trunk/numpy/doc/swig/series.cxx
trunk/numpy/doc/swig/series.h
trunk/numpy/doc/swig/setup.py
trunk/numpy/doc/swig/testSeries.py
Log:
In numpy.i:
* I consolidated several macros
TYPEMAP_IN1
TYPEMAP_IN2
TYPEMAP_INPLACE1
TYPEMAP_INPLACE2
TYPEMAP_ARGOUT1
TYPEMAP_ARGOUT2
into a single macros, %numpy_typemaps(). This makes expanding the
typemaps for a given data type much easier.
* The %numpy_typemaps() macro is now expanded for::
signed char
unsigned char
short
unsigned short
int
unsigned int
long
unsigned long
long long
unsigned long long
float
double
PyObject
char
* I changed the ARGOUT typemaps to check for multiple output
arguments, and form a tuple if necessary.
* Updated the code to work with released numpy versions 0.9.6,
0.9.8, 1.0 and 1.0.1.
* Upgraded the dimension arrays to use type npy_intp.
I also added documentation: numpy_swig.txt is a numpy.i users guide in
restructured text format; numpy_swig.html is the same content in
HTML. The Makefile can produce this with 'make html', assuming
docutils is installed.
The series.h and series.cxx files have been refactored to use macros
to generate repetitive code for different types. All the supported
types have tests for all of the non-ARGOUT typemaps. ARGOUT typemap
tests still need to be written.
Deleted: trunk/numpy/doc/swig/HelperFunctions.txt
===================================================================
--- trunk/numpy/doc/swig/HelperFunctions.txt 2007-03-12 17:07:19 UTC (rev 3573)
+++ trunk/numpy/doc/swig/HelperFunctions.txt 2007-03-14 15:47:12 UTC (rev 3574)
@@ -1,104 +0,0 @@
-/***********************************************************************
- Helper functions from numpy.i, translated by John Hunter
-************************************************************************/
-
-#define is_array(a) ((a) && PyArray_Check((PyArrayObject *)a))
-#define array_type(a) (int)(((PyArrayObject *)a)->descr->type_num)
-#define array_dimensions(a) (((PyArrayObject *)a)->nd)
-#define array_size(a,i) (((PyArrayObject *)a)->dimensions[i])
-#define array_is_contiguous(a) (PyArray_ISCONTIGUOUS(a))
-
-/* Given a PyObject, return a string describing its type.
- */
-char* pytype_string(PyObject* py_obj)
-
-/* Given a Numeric typecode, return a string describing the type.
- */
-char* typecode_string(int typecode)
-
-/* Make sure input has correct numeric type. Allow character and byte
- * to match. Also allow int and long to match.
- */
-int type_match(int actual_type, int desired_type)
-
-/* Given a PyObject pointer, cast it to a PyArrayObject pointer if
- * legal. If not, set the python error string appropriately and
- * return NULL.
- */
-PyArrayObject* obj_to_array_no_conversion(PyObject* input, int typecode)
-
-/* Convert the given PyObject to a Numeric array with the given
- * typecode. On Success, return a valid PyArrayObject* with the
- * correct type. On failure, the python error string will be set and
- * the routine returns NULL.
- */
-PyArrayObject* obj_to_array_allow_conversion(PyObject* input, int typecode,
- int* is_new_object)
-
-/* Given a PyArrayObject, check to see if it is contiguous. If so,
- * return the input pointer and flag it as not a new object. If it is
- * not contiguous, create a new PyArrayObject using the original data,
- * flag it as a new object and return the pointer.
- */
-PyArrayObject* make_contiguous(PyArrayObject* ary, int* is_new_object,
- int min_dims, int max_dims)
-
-/* Convert a given PyObject to a contiguous PyArrayObject of the
- * specified type. If the input object is not a contiguous
- * PyArrayObject, a new one will be created and the new object flag
- * will be set.
- */
-PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject* input,
- int typecode,
- int* is_new_object)
-
-/* Test whether a python object is contiguous. If array is
- * contiguous, return 1. Otherwise, set the python error string and
- * return 0.
- */
-int require_contiguous(PyArrayObject* ary)
-
-/* Require the given PyArrayObject to have a specified number of
- * dimensions. If the array has the specified number of dimensions,
- * return 1. Otherwise, set the python error string and return 0.
- */
-int require_dimensions(PyArrayObject* ary, int exact_dimensions)
-
-/* Require the given PyArrayObject to have one of a list of specified
- * number of dimensions. If the array has one of the specified number
- * of dimensions, return 1. Otherwise, set the python error string
- * and return 0.
- */
-int require_dimensions_n(PyArrayObject* ary, int* exact_dimensions, int n)
-
-/* Require the given PyArrayObject to have a specified shape. If the
- * array has the specified shape, return 1. Otherwise, set the python
- * error string and return 0.
- */
-int require_size(PyArrayObject* ary, int* size, int n)
-
-/***********************************************************************
- Helper functions from Anna Omelchenko and Michel Sanner
-************************************************************************/
-
-/********************************************************************
- The following function tries to create a contiguous numeric array of type
- typecode from a Python object. Works for list, tuples and numeric arrays.
-
- obj: Numeric array , Python object
- typecode: data type PyArray_{ CHAR, UBYTE, SBYTE, SHORT, INT, LONG, FLOAT,
- DOUBLE, CFLOAT, CDOUBLE }
- expectnd: required number of dimensions. Used for checking. Ignored if <=0.
- expectdims: array of expected extends. Used for checking. Ignored if <=0.
-
- Raises ValueError exceptions if:
- - the PyArray_ContiguousFromObject fails
- - the array has a bad shape
- - the extent of a given dimension doesn't match the specified extent.
-If obj is a contiguous PyArrayObject then a reference is returned;
-If op is PyObject sequence object(list, tuple) then a new PyArrayObject is created
- and returned.
-********************************************************************/
-
-static PyArrayObject *contiguous_typed_array(PyObject *obj, int typecode,
- int expectnd, int *expectdims)
Modified: trunk/numpy/doc/swig/Makefile
===================================================================
--- trunk/numpy/doc/swig/Makefile 2007-03-12 17:07:19 UTC (rev 3573)
+++ trunk/numpy/doc/swig/Makefile 2007-03-14 15:47:12 UTC (rev 3574)
@@ -1,3 +1,4 @@
+# SWIG
INTERFACES = Series.i
WRAPPERS = $(INTERFACES:.i=_wrap.cxx)
PROXIES = $(INTERFACES:.i=.py )
@@ -2,2 +3,12 @@
+# ReStructured Text
+RST2HTML = rst2html.py
+RFLAGS = --generator --time --no-xml-declaration
+
+# Web pages that need to be made
+WEB_PAGES = numpy_swig.html
+
+# List all of the subdirectories here for recursive make
+SUBDIRS =
+
all: $(WRAPPERS) series.cxx series.h
@@ -8,7 +19,14 @@
%_wrap.cxx: %.i numpy.i series.h
swig -c++ -python $<
+html: $(WEB_PAGES)
+
+%.html: %.txt
+ $(RST2HTML) $(RFLAGS) $< $@
+
clean:
$(RM) -r build
$(RM) $(WRAPPERS)
$(RM) $(PROXIES)
+
+.PHONY : html clean
Modified: trunk/numpy/doc/swig/README
===================================================================
--- trunk/numpy/doc/swig/README 2007-03-12 17:07:19 UTC (rev 3573)
+++ trunk/numpy/doc/swig/README 2007-03-14 15:47:12 UTC (rev 3574)
@@ -1,16 +1,15 @@
Notes for the swig_numpy/new directory
======================================
-This set of files is for developing and testing file numpy.i, which
-is intended to be a set of typemaps for helping SWIG interface between
-C and C++ code that uses C arrays and the python module Numeric (also
-known informally as NumPy, also to be replaced in the future with
-scipy_core). It is ultimately hoped that numpy.i will be included
-as part of the SWIG and/or SciPy distribution(s).
+This set of files is for developing and testing file numpy.i, which is
+intended to be a set of typemaps for helping SWIG interface between C
+and C++ code that uses C arrays and the python module NumPy. It is
+ultimately hoped that numpy.i will be included as part of the SWIG
+distribution.
In the spirit of "writing your tests first", I will begin by
describing the tests, as they are a good example of what we are trying
-to do with numpy.i. The files related to testing are
+to do with numpy.i. The files related to testing are::
series.h
series.cxx
@@ -18,34 +17,34 @@
The series.h header file contains prototypes for functions that
illustrate the wrapping issues we wish to address. Right now, this
-consists of functions with argument signatures of the form
+consists of functions with argument signatures of the form::
(type* IN_ARRAY1, int DIM1)
(type* IN_ARRAY2, int DIM1, int DIM2)
(type* INPLACE_ARRAY1, int DIM1)
+ (type* INPLACE_ARRAY2, int DIM1, int DIM2)
which take a pointer to an array of type "type", whose length is
specified by the integer(s) DIM1 (and DIM2).
The objective for the IN_ARRAY signatures is for SWIG to generate
python wrappers that take a container that constitutes a valid
-argument to the Numeric.array constructor, and can be used to build an
+argument to the numpy array constructor, and can be used to build an
array of type "type". Currently, types "char", "unsigned char",
"signed char", "short", "int", "long", "float", "double" and
"PyObject" are supported, although only the types "short", "int",
"long", "float" and "double" are tested.
The objective for the INPLACE_ARRAY signatures is for SWIG to generate
-python wrappers that accept a Numeric array of any of the above-listed
+python wrappers that accept a numpy array of any of the above-listed
types.
The source file series.cxx contains the actual implementations of the
functions described in series.h. The python script testSeries.py
tests the resulting python wrappers using the unittest module.
-The SWIG interface file Series.i is used to generate the wrapper
-code. It is pretty short, but everything in it is important. The
-SWIG_FILE_WITH_INIT macro allows numpy.i to be used with multiple
+The SWIG interface file Series.i is used to generate the wrapper code.
+The SWIG_FILE_WITH_INIT macro allows numpy.i to be used with multiple
python modules. If it is specified, then the %init block found in
Series.i is required. The other things done in Series.i are the
inclusion of the series.h and numpy.i files, and the "%apply"
@@ -55,10 +54,10 @@
a _Series extension module and a Series python module. The Makefile
automates everything, setting up the dependencies, calling swig to
generate the wrappers, and calling setup.py to compile the wrapper
-code and generate the shared object. Targets "all" (default) and
-"clean" ar supported.
+code and generate the shared object. Targets "all" (default),
+"clean" and "html" (generate HTML documentation) are supported.
-To build and test the code, simply execute from the shell,
+To build and test the code, simply execute from the shell::
$ make
$ testSeries.py
@@ -66,57 +65,15 @@
================================================================================
ToDo
-====
+----
- * Tests for the (INPLACE_ARRAY2, DIM1, DIM2) nedd to be added to
- series.h, series.cxx and testSeries.py.
+ * Support for complex data types should be added. Currently swig
+ dies with a syntax error when the %numpy_typemaps macro isused
+ with complex types.
- * Support for complex data types should be added. Currently the
- macro substitution doesn't seem to like the two words you need to
- specify "complex double", etc.
-
- * ARGOUT typemaps need to be implemented and tested. I stalled on
- this because SWIG implements a new method for aggregating output
- arguments; it has changed from a tuple to a list and requires
- importing a different SWIG library file. I didn't particularly
- want to spend time trying to support both approaches, and I ended
- up not finishing a typemap for either.
-
-
-Notes Bill:
-
-The numpy.i file currently defines typemaps of the form
-
- (type* IN_ARRAY1, int DIM1)
- (type* IN_ARRAY2, int DIM1, int DIM2)
- (type* INPLACE_ARRAY1, int DIM1)
- (type* INPLACE_ARRAY2, int DIM1, int DIM2)
-
-and has the beginnings of typemaps of the form
-
- (type* ARGOUT_ARRAY[ANY])
- (type* ARGOUT_ARRAY[ANY][ANY])
-
-where "type" is almost any type supported by Numeric (I have had
-trouble with complex), the "1" suffix can be used with any dimension
-array as long as DIM1 reflects the total size, and the "2" suffix is
-for explicitly 2-dimensional arrays. IN_ARRAYs can be any reasonable
-container that can be used to construct a Numeric array.
-INPLACE_ARRAYs must be Numeric arrays.
-
-I hit a snag with the ARGOUT typemaps, because the swig libraries have
-changed and I did not know the best way to proceed. Basically, the old
-way produced a tuple on the LHS if needed and the new way produces a
-list. I forget why swig made the change, but the actual swig library
-file you import changed because of it and I didn't feel like spending
-time trying to support both approaches.
-
-So the ARGOUT typemaps need to be finished, functions that would use
-them need to be added to series.{h,cxx} and tests for the resulting
-python interface need to be added to testSeries.py.
-
-Most of the functions I deal with cannot use the ARGOUT typemaps
-anyway, because they usually involve input arrays that share the same
-dimension arguments as the output arrays, which will require a special
-approach. So I don't have a lot of motivation there . . . but it
-definitely needs to be done before any kind of release.
+ * Better ARGOUT typemaps need to be implemented and tested. I
+ stalled on this because SWIG implements a new method for
+ aggregating output arguments; it has changed from a tuple to a
+ list and requires importing a different SWIG library file. I
+ didn't particularly want to spend time trying to support both
+ approaches, and I ended up not finishing a typemap for either.
Modified: trunk/numpy/doc/swig/Series.i
===================================================================
--- trunk/numpy/doc/swig/Series.i 2007-03-12 17:07:19 UTC (rev 3573)
+++ trunk/numpy/doc/swig/Series.i 2007-03-14 15:47:12 UTC (rev 3574)
@@ -1,3 +1,4 @@
+// -*- c++ -*-
%module Series
%{
@@ -5,27 +6,124 @@
#include "series.h"
%}
-/* Get the Numeric typemaps */
+// Get the Numeric typemaps
%include "numpy.i"
%init %{
import_array();
%}
-/* Apply the Numeric typemaps for 1D input arrays */
-%apply (short* IN_ARRAY1, int DIM1) {(short* series, int size)};
-%apply (int* IN_ARRAY1, int DIM1) {(int* series, int size)};
-%apply (long* IN_ARRAY1, int DIM1) {(long* series, int size)};
-%apply (float* IN_ARRAY1, int DIM1) {(float* series, int size)};
-%apply (double* IN_ARRAY1, int DIM1) {(double* series, int size)};
+// Apply the Numeric typemaps for 1D input arrays
+%apply (signed char* IN_ARRAY1, int DIM1)
+ {(signed char* series, int size)};
+%apply (unsigned char* IN_ARRAY1, int DIM1)
+ {(unsigned char* series, int size)};
+%apply (short* IN_ARRAY1, int DIM1)
+ {(short* series, int size)};
+%apply (unsigned short* IN_ARRAY1, int DIM1)
+ {(unsigned short* series, int size)};
+%apply (int* IN_ARRAY1, int DIM1)
+ {(int* series, int size)};
+%apply (unsigned int* IN_ARRAY1, int DIM1)
+ {(unsigned int* series, int size)};
+%apply (long* IN_ARRAY1, int DIM1)
+ {(long* series, int size)};
+%apply (unsigned long* IN_ARRAY1, int DIM1)
+ {(unsigned long* series, int size)};
+%apply (long long* IN_ARRAY1, int DIM1)
+ {(long long* series, int size)};
+%apply (unsigned long long* IN_ARRAY1, int DIM1)
+ {(unsigned long long* series, int size)};
+%apply (float* IN_ARRAY1, int DIM1)
+ {(float* series, int size)};
+%apply (double* IN_ARRAY1, int DIM1)
+ {(double* series, int size)};
+%apply (long double* IN_ARRAY1, int DIM1)
+ {(long double* series, int size)};
-/* Apply the Numeric typemaps for 2D input arrays */
-%apply (int* IN_ARRAY2, int DIM1, int DIM2) {(int* matrix, int rows, int cols)};
-%apply (double* IN_ARRAY2, int DIM1, int DIM2) {(double* matrix, int rows, int cols)};
+// Apply the Numeric typemaps for 1D input/output arrays
+%apply (signed char* INPLACE_ARRAY1, int DIM1)
+ {(signed char* array, int size)};
+%apply (unsigned char* INPLACE_ARRAY1, int DIM1)
+ {(unsigned char* array, int size)};
+%apply (short* INPLACE_ARRAY1, int DIM1)
+ {(short* array, int size)};
+%apply (unsigned short* INPLACE_ARRAY1, int DIM1)
+ {(unsigned short* array, int size)};
+%apply (int* INPLACE_ARRAY1, int DIM1)
+ {(int* array, int size)};
+%apply (unsigned int* INPLACE_ARRAY1, int DIM1)
+ {(unsigned int* array, int size)};
+%apply (long* INPLACE_ARRAY1, int DIM1)
+ {(long* array, int size)};
+%apply (unsigned long* INPLACE_ARRAY1, int DIM1)
+ {(unsigned long* array, int size)};
+%apply (long long* INPLACE_ARRAY1, int DIM1)
+ {(long long* array, int size)};
+%apply (unsigned long long* INPLACE_ARRAY1, int DIM1)
+ {(unsigned long long* array, int size)};
+%apply (float* INPLACE_ARRAY1, int DIM1)
+ {(float* array, int size)};
+%apply (double* INPLACE_ARRAY1, int DIM1)
+ {(double* array, int size)};
+%apply (long double* INPLACE_ARRAY1, int DIM1)
+ {(long double* array, int size)};
-/* Apply the Numeric typemaps for 1D input/output arrays */
-%apply (int* INPLACE_ARRAY1, int DIM1) {(int* array, int size)};
-%apply (double* INPLACE_ARRAY1, int DIM1) {(double* array, int size)};
+// Apply the Numeric typemaps for 2D input arrays
+%apply (signed char* IN_ARRAY2, int DIM1, int DIM2)
+ {(signed char* matrix, int rows, int cols)};
+%apply (unsigned char* IN_ARRAY2, int DIM1, int DIM2)
+ {(unsigned char* matrix, int rows, int cols)};
+%apply (short* IN_ARRAY2, int DIM1, int DIM2)
+ {(short* matrix, int rows, int cols)};
+%apply (unsigned short* IN_ARRAY2, int DIM1, int DIM2)
+ {(unsigned short* matrix, int rows, int cols)};
+%apply (int* IN_ARRAY2, int DIM1, int DIM2)
+ {(int* matrix, int rows, int cols)};
+%apply (unsigned int* IN_ARRAY2, int DIM1, int DIM2)
+ {(unsigned int* matrix, int rows, int cols)};
+%apply (long* IN_ARRAY2, int DIM1, int DIM2)
+ {(long* matrix, int rows, int cols)};
+%apply (unsigned long* IN_ARRAY2, int DIM1, int DIM2)
+ {(unsigned long* matrix, int rows, int cols)};
+%apply (long long* IN_ARRAY2, int DIM1, int DIM2)
+ {(long long* matrix, int rows, int cols)};
+%apply (unsigned long long* IN_ARRAY2, int DIM1, int DIM2)
+ {(unsigned long long* matrix, int rows, int cols)};
+%apply (float* IN_ARRAY2, int DIM1, int DIM2)
+ {(float* matrix, int rows, int cols)};
+%apply (double* IN_ARRAY2, int DIM1, int DIM2)
+ {(double* matrix, int rows, int cols)};
+%apply (long double* IN_ARRAY2, int DIM1, int DIM2)
+ {(long double* matrix, int rows, int cols)};
-/* Include the header file to be wrapped */
+// Apply the Numeric typemaps for 2D input/output arrays
+%apply (signed char* INPLACE_ARRAY2, int DIM1, int DIM2)
+ {(signed char* array, int rows, int cols)};
+%apply (unsigned char* INPLACE_ARRAY2, int DIM1, int DIM2)
+ {(unsigned char* array, int rows, int cols)};
+%apply (short* INPLACE_ARRAY2, int DIM1, int DIM2)
+ {(short* array, int rows, int cols)};
+%apply (unsigned short* INPLACE_ARRAY2, int DIM1, int DIM2)
+ {(unsigned short* array, int rows, int cols)};
+%apply (int* INPLACE_ARRAY2, int DIM1, int DIM2)
+ {(int* array, int rows, int cols)};
+%apply (unsigned int* INPLACE_ARRAY2, int DIM1, int DIM2)
+ {(unsigned int* array, int rows, int cols)};
+%apply (long* INPLACE_ARRAY2, int DIM1, int DIM2)
+ {(long* array, int rows, int cols)};
+%apply (unsigned long* INPLACE_ARRAY2, int DIM1, int DIM2)
+ {(unsigned long* array, int rows, int cols)};
+%apply (long long* INPLACE_ARRAY2, int DIM1, int DIM2)
+ {(long long* array, int rows, int cols)};
+%apply (unsigned long long* INPLACE_ARRAY2, int DIM1, int DIM2)
+ {(unsigned long long* array, int rows, int cols)};
+%apply (float* INPLACE_ARRAY2, int DIM1, int DIM2)
+ {(float* array, int rows, int cols)};
+%apply (double* INPLACE_ARRAY2, int DIM1, int DIM2)
+ {(double* array, int rows, int cols)};
+%apply (long double* INPLACE_ARRAY2, int DIM1, int DIM2)
+ {(long double* array, int rows, int cols)};
+
+// Include the header file to be wrapped
%include "series.h"
Modified: trunk/numpy/doc/swig/numpy.i
===================================================================
--- trunk/numpy/doc/swig/numpy.i 2007-03-12 17:07:19 UTC (rev 3573)
+++ trunk/numpy/doc/swig/numpy.i 2007-03-14 15:47:12 UTC (rev 3574)
@@ -6,10 +6,11 @@
#include "stdio.h"
#include
-/* The following code originally appeared in enthought/kiva/agg/src/numeric.i,
- * author unknown. It was translated from C++ to C by John Hunter. Bill
- * Spotz has modified it slightly to fix some minor bugs, add some comments
- * and some functionality.
+/* The following code originally appeared in
+ * enthought/kiva/agg/src/numeric.i, author unknown. It was
+ * translated from C++ to C by John Hunter. Bill Spotz has modified
+ * it slightly to fix some minor bugs, upgrade to numpy (all
+ * versions), add some comments and some functionality.
*/
/* Macros to extract array attributes.
@@ -20,6 +21,37 @@
#define array_size(a,i) (((PyArrayObject *)a)->dimensions[i])
#define array_is_contiguous(a) (PyArray_ISCONTIGUOUS(a))
+/* Support older NumPy data type names
+*/
+#if NDARRAY_VERSION < 0x01000000
+#define NPY_BOOL PyArray_BOOL
+#define NPY_BYTE PyArray_BYTE
+#define NPY_UBYTE PyArray_UBYTE
+#define NPY_SHORT PyArray_SHORT
+#define NPY_USHORT PyArray_USHORT
+#define NPY_INT PyArray_INT
+#define NPY_UINT PyArray_UINT
+#define NPY_LONG PyArray_LONG
+#define NPY_ULONG PyArray_ULONG
+#define NPY_LONGLONG PyArray_LONGLONG
+#define NPY_ULONGLONG PyArray_ULONGLONG
+#define NPY_FLOAT PyArray_FLOAT
+#define NPY_DOUBLE PyArray_DOUBLE
+#define NPY_LONGDOUBLE PyArray_LONGDOUBLE
+#define NPY_CFLOAT PyArray_CFLOAT
+#define NPY_CDOUBLE PyArray_CDOUBLE
+#define NPY_CLONGDOUBLE PyArray_CLONGDOUBLE
+#define NPY_OBJECT PyArray_OBJECT
+#define NPY_STRING PyArray_STRING
+#define NPY_UNICODE PyArray_UNICODE
+#define NPY_VOID PyArray_VOID
+#define NPY_NTYPES PyArray_NTYPES
+#define NPY_NOTYPE PyArray_NOTYPE
+#define NPY_CHAR PyArray_CHAR
+#define NPY_USERDEF PyArray_USERDEF
+#define npy_intp intp
+#endif
+
/* Given a PyObject, return a string describing its type.
*/
char* pytype_string(PyObject* py_obj) {
@@ -38,13 +70,18 @@
return "unkown type";
}
-/* Given a Numeric typecode, return a string describing the type.
+/* Given a NumPy typecode, return a string describing the type.
*/
char* typecode_string(int typecode) {
- char* type_names[20] = {"char","unsigned byte","byte","short",
- "unsigned short","int","unsigned int","long",
- "float","double","complex float","complex double",
- "object","ntype","unkown"};
+ static char* type_names[24] = {"bool", "byte", "unsigned byte",
+ "short", "unsigned short", "int",
+ "unsigned int", "long", "unsigned long",
+ "long long", "unsigned long long",
+ "float", "double", "long double",
+ "complex float", "complex double",
+ "complex long double", "object",
+ "string", "unicode", "void", "ntypes",
+ "notype", "char"};
return type_names[typecode];
}
@@ -57,45 +94,43 @@
/* Given a PyObject pointer, cast it to a PyArrayObject pointer if
* legal. If not, set the python error string appropriately and
- * return NULL./
+ * return NULL.
*/
PyArrayObject* obj_to_array_no_conversion(PyObject* input, int typecode) {
PyArrayObject* ary = NULL;
- if (is_array(input) && (typecode == PyArray_NOTYPE ||
- PyArray_EquivTypenums(array_type(input),
- typecode))) {
- ary = (PyArrayObject*) input;
- }
- else if is_array(input) {
- char* desired_type = typecode_string(typecode);
- char* actual_type = typecode_string(array_type(input));
- PyErr_Format(PyExc_TypeError,
- "Array of type '%s' required. Array of type '%s' given",
- desired_type, actual_type);
- ary = NULL;
- }
- else {
- char * desired_type = typecode_string(typecode);
- char * actual_type = pytype_string(input);
- PyErr_Format(PyExc_TypeError,
- "Array of type '%s' required. A %s was given",
- desired_type, actual_type);
- ary = NULL;
- }
+ if (is_array(input) && (typecode == NPY_NOTYPE ||
+ type_match(array_type(input), typecode))) {
+ ary = (PyArrayObject*) input;
+ }
+ else if is_array(input) {
+ char* desired_type = typecode_string(typecode);
+ char* actual_type = typecode_string(array_type(input));
+ PyErr_Format(PyExc_TypeError,
+ "Array of type '%s' required. Array of type '%s' given",
+ desired_type, actual_type);
+ ary = NULL;
+ }
+ else {
+ char * desired_type = typecode_string(typecode);
+ char * actual_type = pytype_string(input);
+ PyErr_Format(PyExc_TypeError,
+ "Array of type '%s' required. A %s was given",
+ desired_type, actual_type);
+ ary = NULL;
+ }
return ary;
}
-/* Convert the given PyObject to a Numeric array with the given
+/* Convert the given PyObject to a NumPy array with the given
* typecode. On Success, return a valid PyArrayObject* with the
* correct type. On failure, the python error string will be set and
* the routine returns NULL.
*/
PyArrayObject* obj_to_array_allow_conversion(PyObject* input, int typecode,
- int* is_new_object)
-{
+ int* is_new_object) {
PyArrayObject* ary = NULL;
PyObject* py_obj;
- if (is_array(input) && (typecode == PyArray_NOTYPE || type_match(array_type(input),typecode))) {
+ if (is_array(input) && (typecode == NPY_NOTYPE || type_match(array_type(input),typecode))) {
ary = (PyArrayObject*) input;
*is_new_object = 0;
}
@@ -114,8 +149,7 @@
* flag it as a new object and return the pointer.
*/
PyArrayObject* make_contiguous(PyArrayObject* ary, int* is_new_object,
- int min_dims, int max_dims)
-{
+ int min_dims, int max_dims) {
PyArrayObject* result;
if (array_is_contiguous(ary)) {
result = ary;
@@ -216,7 +250,7 @@
* array has the specified shape, return 1. Otherwise, set the python
* error string and return 0.
*/
-int require_size(PyArrayObject* ary, int* size, int n) {
+int require_size(PyArrayObject* ary, npy_intp* size, int n) {
int i;
int success = 1;
int len;
@@ -253,236 +287,202 @@
}
return success;
}
-/* End John Hunter translation (with modifications by Bill Spotz) */
+/* End John Hunter translation (with modifications by Bill Spotz)
+ */
%}
-/* TYPEMAP_IN macros
+/* %numpy_typemaps() macro
*
- * This family of typemaps allows pure input C arguments of the form
+ * This macro defines a family of typemaps that allow pure input C
+ * arguments of the form
*
- * (type* IN_ARRAY1, int DIM1)
- * (type* IN_ARRAY2, int DIM1, int DIM2)
+ * (TYPE* IN_ARRAY1, int DIM1)
+ * (TYPE* IN_ARRAY2, int DIM1, int DIM2)
+ * (TYPE* INPLACE_ARRAY1, int DIM1)
+ * (TYPE* INPLACE_ARRAY2, int DIM1, int DIM2)
+ * (TYPE* ARGOUT_ARRAY1[ANY])
+ * (TYPE* ARGOUT_ARRAY2[ANY][ANY])
*
- * where "type" is any type supported by the Numeric module, to be
- * called in python with an argument list of a single array (or any
- * python object that can be passed to the Numeric.array constructor
- * to produce an arrayof te specified shape). This can be applied to
- * a existing functions using the %apply directive:
+ * where "TYPE" is any type supported by the NumPy module. In python,
+ * the dimensions will not need to be specified. The IN_ARRAYs can be
+ * a numpy array or any sequence that can be converted to a numpy
+ * array of the specified type. The INPLACE_ARRAYs must be numpy
+ * arrays of the appropriate type. The ARGOUT_ARRAYs will be returned
+ * as numpy arrays of the appropriate type.
+
+ * These typemaps can be applied to existing functions using the
+ * %apply directive:
*
- * %apply (double* IN_ARRAY1, int DIM1) {double* series, int length}
- * %apply (double* IN_ARRAY2, int DIM1, int DIM2) {double* mx, int rows, int cols}
+ * %apply (double* IN_ARRAY1, int DIM1) {double* series, int length};
* double sum(double* series, int length);
+ *
+ * %apply (double* IN_ARRAY2, int DIM1, int DIM2) {double* mx, int rows, int cols};
* double max(double* mx, int rows, int cols);
*
- * or with
+ * %apply (double* INPLACE_ARRAY1, int DIM1) {double* series, int length};
+ * void negate(double* series, int length);
*
+ * %apply (double* INPLACE_ARRAY2, int DIM1, int DIM2) {double* mx, int rows, int cols};
+ * void normalize(double* mx, int rows, int cols);
+ *
+ * %apply (double* ARGOUT_ARRAY1[ANY] {double series, int length};
+ * void negate(double* series, int length);
+ *
+ * %apply (double* ARGOUT_ARRAY2[ANY][ANY]) {double* mx, int rows, int cols};
+ * void normalize(double* mx, int rows, int cols);
+ *
+ * or directly with
+ *
* double sum(double* IN_ARRAY1, int DIM1);
* double max(double* IN_ARRAY2, int DIM1, int DIM2);
+ * void sum(double* INPLACE_ARRAY1, int DIM1);
+ * void sum(double* INPLACE_ARRAY2, int DIM1, int DIM2);
+ * void sum(double* ARGOUT_ARRAY1[ANY]);
+ * void sum(double* ARGOUT_ARRAY2[ANY][ANY]);
*/
-/* One dimensional input arrays */
-%define TYPEMAP_IN1(type,typecode)
-%typemap(in) (type* IN_ARRAY1, int DIM1)
- (PyArrayObject* array=NULL, int is_new_object) {
- int size[1] = {-1};
- array = obj_to_array_contiguous_allow_conversion($input, typecode, &is_new_object);
- if (!array || !require_dimensions(array,1) || !require_size(array,size,1)) SWIG_fail;
- $1 = (type*) array->data;
- $2 = array->dimensions[0];
+%define %numpy_typemaps(TYPE, TYPECODE)
+
+/* Typemap suite for (TYPE* IN_ARRAY1, int DIM1)
+ */
+%typemap(in) (TYPE* IN_ARRAY1, int DIM1)
+ (PyArrayObject* array=NULL, int is_new_object=0) {
+ array = obj_to_array_contiguous_allow_conversion($input, TYPECODE, &is_new_object);
+ npy_intp size[1] = {-1};
+ if (!array || !require_dimensions(array, 1) || !require_size(array, size, 1)) SWIG_fail;
+ $1 = (TYPE*) array->data;
+ $2 = (int) array->dimensions[0];
}
-%typemap(freearg) (type* IN_ARRAY1, int DIM1) {
+%typemap(freearg) (TYPE* IN_ARRAY1, int DIM1) {
if (is_new_object$argnum && array$argnum) Py_DECREF(array$argnum);
}
-%enddef
-/* Define concrete examples of the TYPEMAP_IN1 macros */
-TYPEMAP_IN1(char, PyArray_CHAR )
-TYPEMAP_IN1(unsigned char, PyArray_UBYTE )
-TYPEMAP_IN1(signed char, PyArray_SBYTE )
-TYPEMAP_IN1(short, PyArray_SHORT )
-TYPEMAP_IN1(int, PyArray_INT )
-TYPEMAP_IN1(long, PyArray_LONG )
-TYPEMAP_IN1(float, PyArray_FLOAT )
-TYPEMAP_IN1(double, PyArray_DOUBLE)
-TYPEMAP_IN1(PyObject, PyArray_OBJECT)
-
-#undef TYPEMAP_IN1
-
- /* Two dimensional input arrays */
-%define TYPEMAP_IN2(type,typecode)
- %typemap(in) (type* IN_ARRAY2, int DIM1, int DIM2)
- (PyArrayObject* array=NULL, int is_new_object) {
- int size[2] = {-1,-1};
- array = obj_to_array_contiguous_allow_conversion($input, typecode, &is_new_object);
- if (!array || !require_dimensions(array,2) || !require_size(array,size,1)) SWIG_fail;
- $1 = (type*) array->data;
- $2 = array->dimensions[0];
- $3 = array->dimensions[1];
+/* Typemap suite for (TYPE* IN_ARRAY2, int DIM1, int DIM2)
+ */
+%typemap(in) (TYPE* IN_ARRAY2, int DIM1, int DIM2)
+ (PyArrayObject* array=NULL, int is_new_object=0) {
+ array = obj_to_array_contiguous_allow_conversion($input, TYPECODE, &is_new_object);
+ npy_intp size[2] = {-1,-1};
+ if (!array || !require_dimensions(array, 2) || !require_size(array, size, 1)) SWIG_fail;
+ $1 = (TYPE*) array->data;
+ $2 = (int) array->dimensions[0];
+ $3 = (int) array->dimensions[1];
}
-%typemap(freearg) (type* IN_ARRAY2, int DIM1, int DIM2) {
+%typemap(freearg) (TYPE* IN_ARRAY2, int DIM1, int DIM2) {
if (is_new_object$argnum && array$argnum) Py_DECREF(array$argnum);
}
-%enddef
-/* Define concrete examples of the TYPEMAP_IN2 macros */
-TYPEMAP_IN2(char, PyArray_CHAR )
-TYPEMAP_IN2(unsigned char, PyArray_UBYTE )
-TYPEMAP_IN2(signed char, PyArray_SBYTE )
-TYPEMAP_IN2(short, PyArray_SHORT )
-TYPEMAP_IN2(int, PyArray_INT )
-TYPEMAP_IN2(long, PyArray_LONG )
-TYPEMAP_IN2(float, PyArray_FLOAT )
-TYPEMAP_IN2(double, PyArray_DOUBLE)
-TYPEMAP_IN2(PyObject, PyArray_OBJECT)
-
-#undef TYPEMAP_IN2
-
-/* TYPEMAP_INPLACE macros
- *
- * This family of typemaps allows input/output C arguments of the form
- *
- * (type* INPLACE_ARRAY1, int DIM1)
- * (type* INPLACE_ARRAY2, int DIM1, int DIM2)
- *
- * where "type" is any type supported by the Numeric module, to be
- * called in python with an argument list of a single contiguous
- * Numeric array. This can be applied to an existing function using
- * the %apply directive:
- *
- * %apply (double* INPLACE_ARRAY1, int DIM1) {double* series, int length}
- * %apply (double* INPLACE_ARRAY2, int DIM1, int DIM2) {double* mx, int rows, int cols}
- * void negate(double* series, int length);
- * void normalize(double* mx, int rows, int cols);
- *
- *
- * or with
- *
- * void sum(double* INPLACE_ARRAY1, int DIM1);
- * void sum(double* INPLACE_ARRAY2, int DIM1, int DIM2);
+/* Typemap suite for (TYPE* INPLACE_ARRAY1, int DIM1)
*/
-
- /* One dimensional input/output arrays */
-%define TYPEMAP_INPLACE1(type,typecode)
-%typemap(in) (type* INPLACE_ARRAY1, int DIM1) (PyArrayObject* temp=NULL) {
- int i;
- temp = obj_to_array_no_conversion($input,typecode);
+%typemap(in) (TYPE* INPLACE_ARRAY1, int DIM1) (PyArrayObject* temp=NULL) {
+ temp = obj_to_array_no_conversion($input, TYPECODE);
if (!temp || !require_contiguous(temp)) SWIG_fail;
- $1 = (type*) temp->data;
+ $1 = (TYPE*) temp->data;
$2 = 1;
- for (i=0; ind; ++i) $2 *= temp->dimensions[i];
+ for (int i=0; ind; ++i) $2 *= temp->dimensions[i];
}
-%enddef
-/* Define concrete examples of the TYPEMAP_INPLACE1 macro */
-TYPEMAP_INPLACE1(char, PyArray_CHAR )
-TYPEMAP_INPLACE1(unsigned char, PyArray_UBYTE )
-TYPEMAP_INPLACE1(signed char, PyArray_SBYTE )
-TYPEMAP_INPLACE1(short, PyArray_SHORT )
-TYPEMAP_INPLACE1(int, PyArray_INT )
-TYPEMAP_INPLACE1(long, PyArray_LONG )
-TYPEMAP_INPLACE1(float, PyArray_FLOAT )
-TYPEMAP_INPLACE1(double, PyArray_DOUBLE)
-TYPEMAP_INPLACE1(PyObject, PyArray_OBJECT)
-
-#undef TYPEMAP_INPLACE1
-
- /* Two dimensional input/output arrays */
-%define TYPEMAP_INPLACE2(type,typecode)
- %typemap(in) (type* INPLACE_ARRAY2, int DIM1, int DIM2) (PyArrayObject* temp=NULL) {
- temp = obj_to_array_no_conversion($input,typecode);
+/* Typemap suite for (TYPE* INPLACE_ARRAY2, int DIM1, int DIM2)
+ */
+%typemap(in) (TYPE* INPLACE_ARRAY2, int DIM1, int DIM2) (PyArrayObject* temp=NULL) {
+ temp = obj_to_array_no_conversion($input, TYPECODE);
if (!temp || !require_contiguous(temp)) SWIG_fail;
- $1 = (type*) temp->data;
- $2 = temp->dimensions[0];
- $3 = temp->dimensions[1];
+ $1 = (TYPE*) temp->data;
+ $2 = (int) temp->dimensions[0];
+ $3 = (int) temp->dimensions[1];
}
-%enddef
-/* Define concrete examples of the TYPEMAP_INPLACE2 macro */
-TYPEMAP_INPLACE2(char, PyArray_CHAR )
-TYPEMAP_INPLACE2(unsigned char, PyArray_UBYTE )
-TYPEMAP_INPLACE2(signed char, PyArray_SBYTE )
-TYPEMAP_INPLACE2(short, PyArray_SHORT )
-TYPEMAP_INPLACE2(int, PyArray_INT )
-TYPEMAP_INPLACE2(long, PyArray_LONG )
-TYPEMAP_INPLACE2(float, PyArray_FLOAT )
-TYPEMAP_INPLACE2(double, PyArray_DOUBLE)
-TYPEMAP_INPLACE2(PyObject, PyArray_OBJECT)
+/* Typemap suite for (TYPE ARGOUT_ARRAY1[ANY])
+ */
+%typemap(in,numinputs=0) (TYPE ARGOUT_ARRAY1[ANY]) {
+ $1 = (TYPE*) malloc($1_dim0*sizeof(TYPE));
+ if (!$1) {
+ PyErr_SetString(PyExc_RuntimeError, "Failed to allocate memory");
+ SWIG_fail;
+ }
+}
+%typemap(argout) (TYPE ARGOUT_ARRAY1[ANY]) {
+ PyObject * obj = NULL;
+ npy_intp dimensions[1] = { $1_dim0 };
+ PyObject* outArray = PyArray_FromDimsAndData(1, dimensions, TYPECODE, (char*)$1);
+ if ($result == Py_None) {
+ Py_DECREF($result);
+ $result = outArray;
+ }
+ else {
+ if (!PyTuple_Check($result)) $result = Py_BuildValue("(O)", $result);
+ obj = Py_Build_Value("(O)", outArray);
+ $result = PySequence_Concat($result, obj);
+ }
+}
-#undef TYPEMAP_INPLACE2
-
-/* TYPEMAP_ARGOUT macros
- *
- * This family of typemaps allows output C arguments of the form
- *
- * (type* ARGOUT_ARRAY[ANY])
- * (type* ARGOUT_ARRAY[ANY][ANY])
- *
- * where "type" is any type supported by the Numeric module, to be
- * called in python with an argument list of a single contiguous
- * Numeric array. This can be applied to an existing function using
- * the %apply directive:
- *
- * %apply (double* ARGOUT_ARRAY[ANY] {double series, int length}
- * %apply (double* ARGOUT_ARRAY[ANY][ANY]) {double* mx, int rows, int cols}
- * void negate(double* series, int length);
- * void normalize(double* mx, int rows, int cols);
- *
- *
- * or with
- *
- * void sum(double* ARGOUT_ARRAY[ANY]);
- * void sum(double* ARGOUT_ARRAY[ANY][ANY]);
+/* Typemap suite for (TYPE ARGOUT_ARRAY2[ANY][ANY])
*/
-
- /* One dimensional input/output arrays */
-%define TYPEMAP_ARGOUT1(type,typecode)
-%typemap(in,numinputs=0) type ARGOUT_ARRAY[ANY] {
- $1 = (type*) malloc($1_dim0*sizeof(type));
+%typemap(in,numinputs=0) (TYPE ARGOUT_ARRAY2[ANY][ANY]) {
+ $1 = (TYPE*) malloc($1_dim0 * $1_dim1 * sizeof(TYPE));
if (!$1) {
PyErr_SetString(PyExc_RuntimeError, "Failed to allocate memory");
SWIG_fail;
}
}
-%typemap(argout) ARGOUT_ARRAY[ANY] {
- int dimensions[1] = {$1_dim0};
- PyObject* outArray = PyArray_FromDimsAndData(1, dimensions, typecode, (char*)$1);
+%typemap(argout) (TYPE ARGOUT_ARRAY1[ANY][ANY]) {
+ PyObject * obj = NULL;
+ npy_intp dimensions[2] = { $1_dim0, $1_dim1 };
+ PyObject* outArray = PyArray_FromDimsAndData(1, dimensions, TYPECODE, (char*)$1);
+ if ($result == Py_None) {
+ Py_DECREF($result);
+ $result = outArray;
+ }
+ else {
+ if (!PyTuple_Check($result)) $result = Py_BuildValue("(O)", $result);
+ obj = Py_Build_Value("(O)", outArray);
+ $result = PySequence_Concat($result, obj);
+ }
}
-%enddef
-/* Define concrete examples of the TYPEMAP_ARGOUT1 macro */
-TYPEMAP_ARGOUT1(char, PyArray_CHAR )
-TYPEMAP_ARGOUT1(unsigned char, PyArray_UBYTE )
-TYPEMAP_ARGOUT1(signed char, PyArray_SBYTE )
-TYPEMAP_ARGOUT1(short, PyArray_SHORT )
-TYPEMAP_ARGOUT1(int, PyArray_INT )
-TYPEMAP_ARGOUT1(long, PyArray_LONG )
-TYPEMAP_ARGOUT1(float, PyArray_FLOAT )
-TYPEMAP_ARGOUT1(double, PyArray_DOUBLE)
-TYPEMAP_ARGOUT1(PyObject, PyArray_OBJECT)
+%enddef /* %numpy_typemaps() macro */
-#undef TYPEMAP_ARGOUT1
- /* Two dimensional input/output arrays */
-%define TYPEMAP_ARGOUT2(type,typecode)
- %typemap(in) (type* ARGOUT_ARRAY2, int DIM1, int DIM2) (PyArrayObject* temp=NULL) {
- temp = obj_to_array_no_conversion($input,typecode);
- if (!temp || !require_contiguous(temp)) SWIG_fail;
- $1 = (type*) temp->data;
- $2 = temp->dimensions[0];
- $3 = temp->dimensions[1];
-}
-%enddef
+/* Concrete instances of the %numpy_typemaps() macro: Each invocation
+ * below applies all of the typemaps above to the specified data type.
+ */
+%numpy_typemaps(signed char, NPY_BYTE ) /**/
+%numpy_typemaps(unsigned char, NPY_UBYTE ) /**/
+%numpy_typemaps(short, NPY_SHORT ) /**/
+%numpy_typemaps(unsigned short, NPY_USHORT ) /**/
+%numpy_typemaps(int, NPY_INT ) /**/
+%numpy_typemaps(unsigned int, NPY_UINT ) /**/
+%numpy_typemaps(long, NPY_LONG ) /**/
+%numpy_typemaps(unsigned long, NPY_ULONG ) /**/
+%numpy_typemaps(long long, NPY_LONGLONG ) /**/
+%numpy_typemaps(unsigned long long, NPY_ULONGLONG) /**/
+%numpy_typemaps(float, NPY_FLOAT ) /**/
+%numpy_typemaps(double, NPY_DOUBLE ) /**/
+%numpy_typemaps(PyObject, NPY_OBJECT )
+%numpy_typemaps(char, NPY_CHAR )
-/* Define concrete examples of the TYPEMAP_ARGOUT2 macro */
-TYPEMAP_ARGOUT2(char, PyArray_CHAR )
-TYPEMAP_ARGOUT2(unsigned char, PyArray_UBYTE )
-TYPEMAP_ARGOUT2(signed char, PyArray_SBYTE )
-TYPEMAP_ARGOUT2(short, PyArray_SHORT )
-TYPEMAP_ARGOUT2(int, PyArray_INT )
-TYPEMAP_ARGOUT2(long, PyArray_LONG )
-TYPEMAP_ARGOUT2(float, PyArray_FLOAT )
-TYPEMAP_ARGOUT2(double, PyArray_DOUBLE)
-TYPEMAP_ARGOUT2(PyObject, PyArray_OBJECT)
+/* ***************************************************************
+ * The follow macro expansion does not work, because C++ bool is 4
+ * bytes and NPY_BOOL is 1 byte
+ */
+/*%numpy_typemaps(bool, NPY_BOOL)
+ */
-#undef TYPEMAP_ARGOUT2
+/* ***************************************************************
+ * On my Mac, I get the following warning for this macro expansion:
+ * 'swig/python detected a memory leak of type 'long double *', no destructor found.'
+ */
+/*%numpy_typemaps(long double, NPY_LONGDOUBLE)
+ */
+
+/* ***************************************************************
+ * Swig complains about a syntax error for the following macros
+ * expansions:
+ */
+/*%numpy_typemaps(complex float, NPY_CFLOAT )
+ */
+/*%numpy_typemaps(complex double, NPY_CDOUBLE )
+ */
+/*%numpy_typemaps(complex long double, NPY_CLONGDOUBLE)
+ */
Added: trunk/numpy/doc/swig/numpy_swig.html
===================================================================
--- trunk/numpy/doc/swig/numpy_swig.html 2007-03-12 17:07:19 UTC (rev 3573)
+++ trunk/numpy/doc/swig/numpy_swig.html 2007-03-14 15:47:12 UTC (rev 3574)
@@ -0,0 +1,604 @@
+
+
+
+
+
+numpy.i: a SWIG Interface File for NumPy
+
+
+
+
+
+
+
numpy.i: a SWIG Interface File for NumPy
+
+
+
+
+Author: |
+Bill Spotz |
+Institution: | Sandia National Laboratories |
+
+Date: |
+10 March, 2007 |
+
+
+
+
+
The Simple Wrapper and Interface Generator (or SWIG) is a powerful tool for generating wrapper
+code for interfacing to a wide variety of scripting languages.
+SWIG can parse header files, and using only the code prototypes,
+create an interface to the target language. But SWIG is not
+omnipotent. For example, it cannot know from the prototype:
+
+double rms(double* seq, int n);
+
+
what exactly seq is. Is it a single value to be altered in-place?
+Is it an array, and if so what is its length? Is it input-only?
+Output-only? Input-output? SWIG cannot determine these details,
+and does not attempt to do so.
+
Making an educated guess, humans can conclude that this is probably a
+routine that takes an input-only array of length n of double
+values called seq and returns the root mean square. The default
+behavior of SWIG, however, will be to create a wrapper function
+that compiles, but is nearly impossible to use from the scripting
+language in the way the C routine was intended.
+
For python, the preferred way of handling
+contiguous (or technically, strided) blocks of homogeneous data is
+with the module NumPy, which provides full
+object-oriented access to arrays of data. Therefore, the most logical
+python interface for the rms function would be:
+
+def rms(seq):
+
+
where seq would be a NumPy array of double values, and its
+length n would be extracted from seq internally before being
+passed to the C routine. Even better, since NumPy supports
+construction of arrays from arbitrary python sequences, seq
+itself could be a nearly arbitrary sequence (so long as each element
+can be converted to a double) and the wrapper code would
+internally convert it to a NumPy array before extracting its data
+and length.
+
SWIG allows these types of conversions to be defined via a
+mechanism called typemaps. This document provides information on how
+to use numpy.i, a SWIG interface file that defines a series of
+typemaps intended to make the type of array-related conversions
+described above relatively simple to implement. For example, suppose
+that the rms function prototype defined above was in a header file
+named rms.h. To obtain the python interface discussed above, your
+SWIG interface file would need the following:
+
+%{
+#include "rms.h"
+%}
+%include "numpy.i"
+%apply (double* IN_ARRAY1, int DIM1) {(double* seq, int n)};
+%include "rms.h"
+
+
Typemaps are keyed off a list of one or more function arguments,
+either by type or by type and name. We will refer to such lists as
+signatures. One of the many typemaps defined by numpy.i is used
+above and has the signature (double* IN_ARRAY1, int DIM1). The
+argument names are intended to suggest that the double* argument
+is an input array of one dimension and that the int represents
+that dimension. This is precisely the pattern in the rms
+prototype.
+
Hopefully, no actual prototypes to be wrapped will have the names
+IN_ARRAY1 and DIM1. We use the %apply directive to apply
+the typemap for one-dimensional input arrays of type double to the
+actual prototype used by rms. Using numpy.i effectively,
+therefore, requires knowing what typemaps are available and what they
+do.
+
+
+
+
The numpy.i file is currently located in the numpy/docs/swig
+sub-directory under the numpy installation directory. Typically,
+you will want to copy it to the directory where you are developing
+your wrappers.
+
A simple module that only uses a single SWIG interface file should
+include the following:
+
+%{
+#define SWIG_FILE_WITH_INIT
+%}
+%include "numpy.i"
+%init %{
+import_array();
+%}
+
+
Only one interface file should call import_array(). If you have
+more than one SWIG interface file, then subsequent files should not
+#define SWIG_FILE_WITH_INIT and should not call
+import_array().
+
+
+
+
The typemap directives provided by numpy.i for arrays of different
+data types, say double and int, are identical to one another
+except for the C and NumPy type specifications. The typemaps are
+therefore implemented via a macro:
+
+%numpy_typemaps(TYPE, TYPECODE)
+
+
that can be invoked for appropriate (TYPE, TYPECODE) pairs. For
+example:
+
+%numpy_typemaps(double, NPY_DOUBLE)
+%numpy_typemaps(int, NPY_INT )
+
+
The numpy.i interface file uses the %numpy_typemaps macro to
+implement typemaps for the following C-types:
+
+
+- signed char
+- unsigned char
+- short
+- unsigned short
+- int
+- unsigned int
+- long
+- unsigned long
+- long long
+- unsigned long long
+- float
+- double
+- PyObject
+- char
+
+
+
Note that C++ type bool is not supported in the list above. NumPy
+bools are a single byte, while the C++ bool is four bytes (at
+least on my system). Therefore:
+
+%numpy_typemaps(bool, NPY_BOOL)
+
+
will result in typemaps that will produce code that reference
+improper data lengths. You can implement the following macro
+expansion:
+
+%numpy_typemaps(bool, NPY_UINT)
+
+
to fix the data length problem, and Input Arrays will work fine,
+but In-place Arrays will fail type-checking.
+
In the following descriptions, we reference a generic TYPE, which
+could be any of the C-types listed above.
+
+
+
Input arrays are defined as arrays of data that are passed into a
+routine but are not altered in-place or returned to the user. The
+python input array is therefore allowed to be almost any python
+sequence (such as a list) that can be converted to the requested type
+of array. The input array signatures are
+
+
+- (TYPE* IN_ARRAY1, int DIM1)
+- (TYPE* IN_ARRAY2, int DIM1, int DIM2)
+
+
+
+
+
+
In-place arrays are defined as arrays that are modified in-place. The
+input values may or may not be used, but the values at the time the
+function returns are significant. The provided python argument must
+therefore be a NumPy array of the required type. The in-place
+signatures are
+
+
+- (TYPE* INPLACE_ARRAY1, int DIM1)
+- (TYPE* INPLACE_ARRAY2, int DIM1, int DIM2)
+
+
+
+
+
+
Argout arrays are arrays that appear in the input arguments in C, but
+are in fact output arrays. This pattern occurs often when there is
+more than one output variable and the single return argument is
+therefore not sufficient. In python, the convential way to return
+multiple arguments is to pack them into a tuple and return the tuple.
+This is what the argout typemaps do. If a wrapped function that uses
+argout these argout typemaps has more than one return argument, they
+are so packed. The python user does not pass these arrays in, they
+simply get returned. The argout signatures are
+
+
+- (TYPE ARGOUT_ARRAY1[ANY])
+- (TYPE ARGOUT_ARRAY2[ANY][ANY])
+
+
+
+
+
+
+
The numpy.i file containes several macros and routines that it
+uses internally to build its typemaps. However, these functions may
+be useful elsewhere in your interface file.
+
+
+
+
+- is_array(a)
+- Evaluates as true if a is non-NULL and can be cast to a
+PyArrayObject*.
+- array_type(a)
+- Evaluates to the integer data type code of a, assuming a can
+be cast to a PyArrayObject*.
+- array_dimensions(a)
+- Evaluates to the integer number of dimensions of a, assuming
+a can be cast to a PyArrayObject*.
+- array_size(a,i)
+- Evaluates to the i-th dimension size of a, assuming a
+can be cast to a PyArrayObject*.
+- array_is_contiguous(a)
+- Evaluates as true if a is a contiguous array. Equivalent to
+(PyArray_ISCONTIGUOUS(a)).
+
+
+
+
+
+
+
+- char* pytype_string(PyObject* py_obj)
+- Given a PyObject*, return a string describing its type.
+- char* typecode_string(int typecode)
+- Given a NumPy integer typecode, return a string describing the type.
+- int type_match(int actual_type, int desired_type)
+- Make sure input has correct NumPy type. Allow character and
+byte to match. Also allow int and long to match.
+- PyArrayObject* obj_to_array_no_conversion(PyObject* input, int typecode)
+- Given a PyObject*, cast it to a PyArrayObject* if legal.
+If not, set the python error string appropriately and return
+NULL.
+- PyArrayObject* obj_to_array_allow_conversion(PyObject* input, int typecode, int* is_new_object)
+- Convert the given PyObject* to a NumPy array with the given
+typecode. On Success, return a valid PyArrayObject* with the
+correct type. On failure, the python error string will be set and
+the routine returns NULL.
+- PyArrayObject* make_contiguous(PyArrayObject* ary, int* is_new_object, int min_dims, int max_dims)
+- Given a PyArrayObject*, check to see if it is contiguous. If
+so, return the input pointer and flag it as not a new object. If
+it is not contiguous, create a new PyArrayObject* using the
+original data, flag it as a new object and return the pointer.
+- PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject* input, int typecode, int* is_new_object)
+- Convert a given PyObject* to a contiguous PyArrayObject*
+of the specified type. If the input object is not a contiguous
+PyArrayObject*, a new one will be created and the new object
+flag will be set.
+- int require_contiguous(PyArrayObject* ary)
+- Test whether a PyArrayObject* is contiguous. If array is
+contiguous, return 1. Otherwise, set the python error string and
+return 0.
+- int require_dimensions(PyArrayObject* ary, int exact_dimensions)
+- Require the given PyArrayObject* to have a specified number of
+dimensions. If the array has the specified number of dimensions,
+return 1. Otherwise, set the python error string and return 0.
+- int require_dimensions_n(PyArrayObject* ary, int* exact_dimensions, int n)
+- Require the given PyArrayObject* to have one of a list of
+specified number of dimensions. If the array has one of the
+specified number of dimensions, return 1. Otherwise, set the
+python error string and return 0.
+- int require_size(PyArrayObject* ary, int* size, int n)
+- Require the given PyArrayObject* to have a specified shape.
+If the array has the specified shape, return 1. Otherwise, set
+the python error string and return 0.
+- static PyArrayObject *contiguous_typed_array(PyObject *obj, int typecode, int expectnd, int *expectdims)
+- This function tries to create a contiguous NumPy array of type
+typecode from an arbitrary python object obj. This should
+work for any sequence object. The argument expectnd is the
+expected number of dimensions, ignored if <= 0. The argument
+expectdims is an array of expected dimensions, ignored if <=
+0. This routine raises a ValueError exception if the
+underlying PyArray_ContiguousFromObject routine fails, if the
+array has a bad shape, if the extent of a given dimension doesn't
+match the specified extent. If obj is a contiguous
+PyArrayObject* then a reference is returned; if obj is a
+python sequence, then a new PyArrayObject* is created and
+returned.
+
+
+
+
+
+
+
Many people have worked to glue SWIG and NumPy (and its
+predecessors Numeric and numarray) together. The effort to
+standardize this work into numpy.i began at the 2005 SciPy
+Conference with a conversation between Fernando Perez and myself.
+Fernando collected helper functions and typemaps from Michael Hunter,
+Anna Omelchenko and Michael Sanner. Their work has made this end
+result possible.
+
+
+
+
+
Added: trunk/numpy/doc/swig/numpy_swig.txt
===================================================================
--- trunk/numpy/doc/swig/numpy_swig.txt 2007-03-12 17:07:19 UTC (rev 3573)
+++ trunk/numpy/doc/swig/numpy_swig.txt 2007-03-14 15:47:12 UTC (rev 3574)
@@ -0,0 +1,319 @@
+========================================
+numpy.i: a SWIG Interface File for NumPy
+========================================
+
+:Author: Bill Spotz
+:Institution: Sandia National Laboratories
+:Date: 10 March, 2007
+
+Introduction
+============
+
+The Simple Wrapper and Interface Generator (or `SWIG
+`_) is a powerful tool for generating wrapper
+code for interfacing to a wide variety of scripting languages.
+`SWIG`_ can parse header files, and using only the code prototypes,
+create an interface to the target language. But `SWIG`_ is not
+omnipotent. For example, it cannot know from the prototype::
+
+ double rms(double* seq, int n);
+
+what exactly ``seq`` is. Is it a single value to be altered in-place?
+Is it an array, and if so what is its length? Is it input-only?
+Output-only? Input-output? `SWIG`_ cannot determine these details,
+and does not attempt to do so.
+
+Making an educated guess, humans can conclude that this is probably a
+routine that takes an input-only array of length ``n`` of ``double``
+values called ``seq`` and returns the root mean square. The default
+behavior of `SWIG`_, however, will be to create a wrapper function
+that compiles, but is nearly impossible to use from the scripting
+language in the way the C routine was intended.
+
+For `python `_, the preferred way of handling
+contiguous (or technically, *strided*) blocks of homogeneous data is
+with the module `NumPy `_, which provides full
+object-oriented access to arrays of data. Therefore, the most logical
+python interface for the ``rms`` function would be::
+
+ def rms(seq):
+
+where ``seq`` would be a `NumPy`_ array of ``double`` values, and its
+length ``n`` would be extracted from ``seq`` internally before being
+passed to the C routine. Even better, since `NumPy`_ supports
+construction of arrays from arbitrary `python`_ sequences, ``seq``
+itself could be a nearly arbitrary sequence (so long as each element
+can be converted to a ``double``) and the wrapper code would
+internally convert it to a `NumPy`_ array before extracting its data
+and length.
+
+`SWIG`_ allows these types of conversions to be defined via a
+mechanism called typemaps. This document provides information on how
+to use ``numpy.i``, a `SWIG`_ interface file that defines a series of
+typemaps intended to make the type of array-related conversions
+described above relatively simple to implement. For example, suppose
+that the ``rms`` function prototype defined above was in a header file
+named ``rms.h``. To obtain the python interface discussed above, your
+`SWIG`_ interface file would need the following::
+
+ %{
+ #include "rms.h"
+ %}
+ %include "numpy.i"
+ %apply (double* IN_ARRAY1, int DIM1) {(double* seq, int n)};
+ %include "rms.h"
+
+Typemaps are keyed off a list of one or more function arguments,
+either by type or by type and name. We will refer to such lists as
+*signatures*. One of the many typemaps defined by ``numpy.i`` is used
+above and has the signature ``(double* IN_ARRAY1, int DIM1)``. The
+argument names are intended to suggest that the ``double*`` argument
+is an input array of one dimension and that the ``int`` represents
+that dimension. This is precisely the pattern in the ``rms``
+prototype.
+
+Hopefully, no actual prototypes to be wrapped will have the names
+``IN_ARRAY1`` and ``DIM1``. We use the ``%apply`` directive to apply
+the typemap for one-dimensional input arrays of type ``double`` to the
+actual prototype used by ``rms``. Using ``numpy.i`` effectively,
+therefore, requires knowing what typemaps are available and what they
+do.
+
+Using numpy.i
+=============
+
+The ``numpy.i`` file is currently located in the ``numpy/docs/swig``
+sub-directory under the ``numpy`` installation directory. Typically,
+you will want to copy it to the directory where you are developing
+your wrappers.
+
+A simple module that only uses a single `SWIG`_ interface file should
+include the following::
+
+ %{
+ #define SWIG_FILE_WITH_INIT
+ %}
+ %include "numpy.i"
+ %init %{
+ import_array();
+ %}
+
+Only one interface file should call ``import_array()``. If you have
+more than one `SWIG`_ interface file, then subsequent files should not
+``#define SWIG_FILE_WITH_INIT`` and should not call
+``import_array()``.
+
+Available Typemaps
+==================
+
+The typemap directives provided by ``numpy.i`` for arrays of different
+data types, say ``double`` and ``int``, are identical to one another
+except for the C and `NumPy`_ type specifications. The typemaps are
+therefore implemented via a macro::
+
+ %numpy_typemaps(TYPE, TYPECODE)
+
+that can be invoked for appropriate ``(TYPE, TYPECODE)`` pairs. For
+example::
+
+ %numpy_typemaps(double, NPY_DOUBLE)
+ %numpy_typemaps(int, NPY_INT )
+
+The ``numpy.i`` interface file uses the ``%numpy_typemaps`` macro to
+implement typemaps for the following C-types:
+
+ * ``signed char``
+ * ``unsigned char``
+ * ``short``
+ * ``unsigned short``
+ * ``int``
+ * ``unsigned int``
+ * ``long``
+ * ``unsigned long``
+ * ``long long``
+ * ``unsigned long long``
+ * ``float``
+ * ``double``
+ * ``PyObject``
+ * ``char``
+
+Note that C++ type ``bool`` is not supported in the list above. NumPy
+bools are a single byte, while the C++ ``bool`` is four bytes (at
+least on my system). Therefore::
+
+ %numpy_typemaps(bool, NPY_BOOL)
+
+will result in typemaps that will produce code that reference
+improper data lengths. You can implement the following macro
+expansion::
+
+ %numpy_typemaps(bool, NPY_UINT)
+
+to fix the data length problem, and `Input Arrays`_ will work fine,
+but `In-place Arrays`_ will fail type-checking.
+
+In the following descriptions, we reference a generic ``TYPE``, which
+could be any of the C-types listed above.
+
+Input Arrays
+------------
+
+Input arrays are defined as arrays of data that are passed into a
+routine but are not altered in-place or returned to the user. The
+python input array is therefore allowed to be almost any python
+sequence (such as a list) that can be converted to the requested type
+of array. The input array signatures are
+
+ * ``(TYPE* IN_ARRAY1, int DIM1)``
+ * ``(TYPE* IN_ARRAY2, int DIM1, int DIM2)``
+
+In-place Arrays
+---------------
+
+In-place arrays are defined as arrays that are modified in-place. The
+input values may or may not be used, but the values at the time the
+function returns are significant. The provided python argument must
+therefore be a `NumPy`_ array of the required type. The in-place
+signatures are
+
+ * ``(TYPE* INPLACE_ARRAY1, int DIM1)``
+ * ``(TYPE* INPLACE_ARRAY2, int DIM1, int DIM2)``
+
+Argout Arrays
+-------------
+
+Argout arrays are arrays that appear in the input arguments in C, but
+are in fact output arrays. This pattern occurs often when there is
+more than one output variable and the single return argument is
+therefore not sufficient. In python, the convential way to return
+multiple arguments is to pack them into a tuple and return the tuple.
+This is what the argout typemaps do. If a wrapped function that uses
+argout these argout typemaps has more than one return argument, they
+are so packed. The python user does not pass these arrays in, they
+simply get returned. The argout signatures are
+
+ * ``(TYPE ARGOUT_ARRAY1[ANY])``
+ * ``(TYPE ARGOUT_ARRAY2[ANY][ANY])``
+
+Helper Functions
+================
+
+The ``numpy.i`` file containes several macros and routines that it
+uses internally to build its typemaps. However, these functions may
+be useful elsewhere in your interface file.
+
+Macros
+------
+
+ **is_array(a)**
+ Evaluates as true if ``a`` is non-``NULL`` and can be cast to a
+ ``PyArrayObject*``.
+
+ **array_type(a)**
+ Evaluates to the integer data type code of ``a``, assuming ``a`` can
+ be cast to a ``PyArrayObject*``.
+
+ **array_dimensions(a)**
+ Evaluates to the integer number of dimensions of ``a``, assuming
+ ``a`` can be cast to a ``PyArrayObject*``.
+
+ **array_size(a,i)**
+ Evaluates to the ``i``-th dimension size of ``a``, assuming ``a``
+ can be cast to a ``PyArrayObject*``.
+
+ **array_is_contiguous(a)**
+ Evaluates as true if ``a`` is a contiguous array. Equivalent to
+ ``(PyArray_ISCONTIGUOUS(a))``.
+
+Routines
+--------
+
+ **char* pytype_string(PyObject* py_obj)**
+ Given a ``PyObject*``, return a string describing its type.
+
+
+ **char* typecode_string(int typecode)**
+ Given a `NumPy`_ integer typecode, return a string describing the type.
+
+
+ **int type_match(int actual_type, int desired_type)**
+ Make sure input has correct `NumPy`_ type. Allow character and
+ byte to match. Also allow int and long to match.
+
+
+ **PyArrayObject* obj_to_array_no_conversion(PyObject* input, int typecode)**
+ Given a ``PyObject*``, cast it to a ``PyArrayObject*`` if legal.
+ If not, set the python error string appropriately and return
+ ``NULL``.
+
+
+ **PyArrayObject* obj_to_array_allow_conversion(PyObject* input, int typecode, int* is_new_object)**
+ Convert the given ``PyObject*`` to a `NumPy`_ array with the given
+ typecode. On Success, return a valid ``PyArrayObject*`` with the
+ correct type. On failure, the python error string will be set and
+ the routine returns ``NULL``.
+
+
+ **PyArrayObject* make_contiguous(PyArrayObject* ary, int* is_new_object, int min_dims, int max_dims)**
+ Given a ``PyArrayObject*``, check to see if it is contiguous. If
+ so, return the input pointer and flag it as not a new object. If
+ it is not contiguous, create a new ``PyArrayObject*`` using the
+ original data, flag it as a new object and return the pointer.
+
+
+ **PyArrayObject* obj_to_array_contiguous_allow_conversion(PyObject* input, int typecode, int* is_new_object)**
+ Convert a given ``PyObject*`` to a contiguous ``PyArrayObject*``
+ of the specified type. If the input object is not a contiguous
+ ``PyArrayObject*``, a new one will be created and the new object
+ flag will be set.
+
+
+ **int require_contiguous(PyArrayObject* ary)**
+ Test whether a ``PyArrayObject*`` is contiguous. If array is
+ contiguous, return 1. Otherwise, set the python error string and
+ return 0.
+
+
+ **int require_dimensions(PyArrayObject* ary, int exact_dimensions)**
+ Require the given ``PyArrayObject*`` to have a specified number of
+ dimensions. If the array has the specified number of dimensions,
+ return 1. Otherwise, set the python error string and return 0.
+
+
+ **int require_dimensions_n(PyArrayObject* ary, int* exact_dimensions, int n)**
+ Require the given ``PyArrayObject*`` to have one of a list of
+ specified number of dimensions. If the array has one of the
+ specified number of dimensions, return 1. Otherwise, set the
+ python error string and return 0.
+
+
+ **int require_size(PyArrayObject* ary, int* size, int n)**
+ Require the given ``PyArrayObject*`` to have a specified shape.
+ If the array has the specified shape, return 1. Otherwise, set
+ the python error string and return 0.
+
+
+ **static PyArrayObject *contiguous_typed_array(PyObject *obj, int typecode, int expectnd, int *expectdims)**
+ This function tries to create a contiguous `NumPy`_ array of type
+ typecode from an arbitrary python object ``obj``. This should
+ work for any sequence object. The argument ``expectnd`` is the
+ expected number of dimensions, ignored if <= 0. The argument
+ ``expectdims`` is an array of expected dimensions, ignored if <=
+ 0. This routine raises a ``ValueError`` exception if the
+ underlying ``PyArray_ContiguousFromObject`` routine fails, if the
+ array has a bad shape, if the extent of a given dimension doesn't
+ match the specified extent. If ``obj`` is a contiguous
+ ``PyArrayObject*`` then a reference is returned; if ``obj`` is a
+ python sequence, then a new ``PyArrayObject*`` is created and
+ returned.
+
+Acknowledgements
+================
+
+Many people have worked to glue `SWIG`_ and `NumPy`_ (and its
+predecessors Numeric and numarray) together. The effort to
+standardize this work into ``numpy.i`` began at the 2005 SciPy
+Conference with a conversation between Fernando Perez and myself.
+Fernando collected helper functions and typemaps from Michael Hunter,
+Anna Omelchenko and Michael Sanner. Their work has made this end
+result possible.
Modified: trunk/numpy/doc/swig/series.cxx
===================================================================
--- trunk/numpy/doc/swig/series.cxx 2007-03-12 17:07:19 UTC (rev 3573)
+++ trunk/numpy/doc/swig/series.cxx 2007-03-14 15:47:12 UTC (rev 3574)
@@ -3,143 +3,68 @@
#include
#include "series.h"
-// *** One Dimensional Arrays ***
-
-// Functions that take 1D arrays of type SHORT as input
-short shortSum(short* series, int size) {
- short result = 0;
- for (int i=0; i result) result = matrix[index]; \
+ } \
+ } \
+ return result; \
+} \
+\
+void SNAME ## Floor(TYPE * array, int rows, int cols, TYPE floor) { \
+ int i, j, index; \
+ for (j=0; j result) result = matrix[index];
- }
- }
- return result;
-}
-
-void intFloor(int* matrix, int rows, int cols, int floor) {
- int i, j, index;
- for (j=0; j result) result = matrix[index];
- }
- }
- return result;
-}
-
-void doubleFloor(double* matrix, int rows, int cols, double floor) {
- int i, j, index;
- for (j=0; j
Author: wfspotz at sandia.gov
Date: 2007-03-14 14:57:23 -0500 (Wed, 14 Mar 2007)
New Revision: 3575
Modified:
trunk/numpy/doc/swig/README
trunk/numpy/doc/swig/Series.i
trunk/numpy/doc/swig/numpy.i
trunk/numpy/doc/swig/numpy_swig.html
trunk/numpy/doc/swig/numpy_swig.txt
trunk/numpy/doc/swig/series.cxx
trunk/numpy/doc/swig/series.h
trunk/numpy/doc/swig/testSeries.py
Log:
Added typemap signatures where the dimensions come before the data pointer
Modified: trunk/numpy/doc/swig/README
===================================================================
--- trunk/numpy/doc/swig/README 2007-03-14 15:47:12 UTC (rev 3574)
+++ trunk/numpy/doc/swig/README 2007-03-14 19:57:23 UTC (rev 3575)
@@ -1,4 +1,4 @@
-Notes for the swig_numpy/new directory
+Notes for the numpy/doc/swig directory
======================================
This set of files is for developing and testing file numpy.i, which is
@@ -21,8 +21,12 @@
(type* IN_ARRAY1, int DIM1)
(type* IN_ARRAY2, int DIM1, int DIM2)
+ (int DIM1, type* IN_ARRAY1)``
+ (int DIM1, int DIM2, type* IN_ARRAY2)``
(type* INPLACE_ARRAY1, int DIM1)
(type* INPLACE_ARRAY2, int DIM1, int DIM2)
+ (int DIM1, type* INPLACE_ARRAY1)
+ (int DIM1, int DIM2, type* INPLACE_ARRAY2)
which take a pointer to an array of type "type", whose length is
specified by the integer(s) DIM1 (and DIM2).
@@ -30,10 +34,10 @@
The objective for the IN_ARRAY signatures is for SWIG to generate
python wrappers that take a container that constitutes a valid
argument to the numpy array constructor, and can be used to build an
-array of type "type". Currently, types "char", "unsigned char",
-"signed char", "short", "int", "long", "float", "double" and
-"PyObject" are supported, although only the types "short", "int",
-"long", "float" and "double" are tested.
+array of type "type". Currently, types "signed char", "unsigned
+char", "short", "unsigned short", "int", "unsigned int", "long",
+"unsigned long", "long long", "unsigned long long", "float", "double",
+"PyObject" and "char" are supported and tested.
The objective for the INPLACE_ARRAY signatures is for SWIG to generate
python wrappers that accept a numpy array of any of the above-listed
Modified: trunk/numpy/doc/swig/Series.i
===================================================================
--- trunk/numpy/doc/swig/Series.i 2007-03-14 15:47:12 UTC (rev 3574)
+++ trunk/numpy/doc/swig/Series.i 2007-03-14 19:57:23 UTC (rev 3575)
@@ -6,124 +6,38 @@
#include "series.h"
%}
-// Get the Numeric typemaps
+// Get the NumPy typemaps
%include "numpy.i"
%init %{
import_array();
%}
-// Apply the Numeric typemaps for 1D input arrays
-%apply (signed char* IN_ARRAY1, int DIM1)
- {(signed char* series, int size)};
-%apply (unsigned char* IN_ARRAY1, int DIM1)
- {(unsigned char* series, int size)};
-%apply (short* IN_ARRAY1, int DIM1)
- {(short* series, int size)};
-%apply (unsigned short* IN_ARRAY1, int DIM1)
- {(unsigned short* series, int size)};
-%apply (int* IN_ARRAY1, int DIM1)
- {(int* series, int size)};
-%apply (unsigned int* IN_ARRAY1, int DIM1)
- {(unsigned int* series, int size)};
-%apply (long* IN_ARRAY1, int DIM1)
- {(long* series, int size)};
-%apply (unsigned long* IN_ARRAY1, int DIM1)
- {(unsigned long* series, int size)};
-%apply (long long* IN_ARRAY1, int DIM1)
- {(long long* series, int size)};
-%apply (unsigned long long* IN_ARRAY1, int DIM1)
- {(unsigned long long* series, int size)};
-%apply (float* IN_ARRAY1, int DIM1)
- {(float* series, int size)};
-%apply (double* IN_ARRAY1, int DIM1)
- {(double* series, int size)};
-%apply (long double* IN_ARRAY1, int DIM1)
- {(long double* series, int size)};
+%define %apply_numpy_typemaps(TYPE)
-// Apply the Numeric typemaps for 1D input/output arrays
-%apply (signed char* INPLACE_ARRAY1, int DIM1)
- {(signed char* array, int size)};
-%apply (unsigned char* INPLACE_ARRAY1, int DIM1)
- {(unsigned char* array, int size)};
-%apply (short* INPLACE_ARRAY1, int DIM1)
- {(short* array, int size)};
-%apply (unsigned short* INPLACE_ARRAY1, int DIM1)
- {(unsigned short* array, int size)};
-%apply (int* INPLACE_ARRAY1, int DIM1)
- {(int* array, int size)};
-%apply (unsigned int* INPLACE_ARRAY1, int DIM1)
- {(unsigned int* array, int size)};
-%apply (long* INPLACE_ARRAY1, int DIM1)
- {(long* array, int size)};
-%apply (unsigned long* INPLACE_ARRAY1, int DIM1)
- {(unsigned long* array, int size)};
-%apply (long long* INPLACE_ARRAY1, int DIM1)
- {(long long* array, int size)};
-%apply (unsigned long long* INPLACE_ARRAY1, int DIM1)
- {(unsigned long long* array, int size)};
-%apply (float* INPLACE_ARRAY1, int DIM1)
- {(float* array, int size)};
-%apply (double* INPLACE_ARRAY1, int DIM1)
- {(double* array, int size)};
-%apply (long double* INPLACE_ARRAY1, int DIM1)
- {(long double* array, int size)};
+%apply (TYPE* IN_ARRAY1, int DIM1) {(TYPE* series, int size)};
+%apply (TYPE* IN_ARRAY2, int DIM1, int DIM2) {(TYPE* matrix, int rows, int cols)};
+%apply (TYPE* INPLACE_ARRAY1, int DIM1) {(TYPE* array, int size)};
+%apply (TYPE* INPLACE_ARRAY2, int DIM1, int DIM2) {(TYPE* array, int rows, int cols)};
+%apply (int DIM1, TYPE* IN_ARRAY1) {(int size, TYPE* series)};
+%apply (int DIM1, int DIM2, TYPE* IN_ARRAY2) {(int rows, int cols, TYPE* matrix)};
+%apply (int DIM1, TYPE* INPLACE_ARRAY1) {(int size, TYPE* array)};
+%apply (int DIM1, int DIM2, TYPE* INPLACE_ARRAY2) {(int rows, int cols, TYPE* array)};
-// Apply the Numeric typemaps for 2D input arrays
-%apply (signed char* IN_ARRAY2, int DIM1, int DIM2)
- {(signed char* matrix, int rows, int cols)};
-%apply (unsigned char* IN_ARRAY2, int DIM1, int DIM2)
- {(unsigned char* matrix, int rows, int cols)};
-%apply (short* IN_ARRAY2, int DIM1, int DIM2)
- {(short* matrix, int rows, int cols)};
-%apply (unsigned short* IN_ARRAY2, int DIM1, int DIM2)
- {(unsigned short* matrix, int rows, int cols)};
-%apply (int* IN_ARRAY2, int DIM1, int DIM2)
- {(int* matrix, int rows, int cols)};
-%apply (unsigned int* IN_ARRAY2, int DIM1, int DIM2)
- {(unsigned int* matrix, int rows, int cols)};
-%apply (long* IN_ARRAY2, int DIM1, int DIM2)
- {(long* matrix, int rows, int cols)};
-%apply (unsigned long* IN_ARRAY2, int DIM1, int DIM2)
- {(unsigned long* matrix, int rows, int cols)};
-%apply (long long* IN_ARRAY2, int DIM1, int DIM2)
- {(long long* matrix, int rows, int cols)};
-%apply (unsigned long long* IN_ARRAY2, int DIM1, int DIM2)
- {(unsigned long long* matrix, int rows, int cols)};
-%apply (float* IN_ARRAY2, int DIM1, int DIM2)
- {(float* matrix, int rows, int cols)};
-%apply (double* IN_ARRAY2, int DIM1, int DIM2)
- {(double* matrix, int rows, int cols)};
-%apply (long double* IN_ARRAY2, int DIM1, int DIM2)
- {(long double* matrix, int rows, int cols)};
+%enddef /* %apply_numpy_typemaps() macro */
-// Apply the Numeric typemaps for 2D input/output arrays
-%apply (signed char* INPLACE_ARRAY2, int DIM1, int DIM2)
- {(signed char* array, int rows, int cols)};
-%apply (unsigned char* INPLACE_ARRAY2, int DIM1, int DIM2)
- {(unsigned char* array, int rows, int cols)};
-%apply (short* INPLACE_ARRAY2, int DIM1, int DIM2)
- {(short* array, int rows, int cols)};
-%apply (unsigned short* INPLACE_ARRAY2, int DIM1, int DIM2)
- {(unsigned short* array, int rows, int cols)};
-%apply (int* INPLACE_ARRAY2, int DIM1, int DIM2)
- {(int* array, int rows, int cols)};
-%apply (unsigned int* INPLACE_ARRAY2, int DIM1, int DIM2)
- {(unsigned int* array, int rows, int cols)};
-%apply (long* INPLACE_ARRAY2, int DIM1, int DIM2)
- {(long* array, int rows, int cols)};
-%apply (unsigned long* INPLACE_ARRAY2, int DIM1, int DIM2)
- {(unsigned long* array, int rows, int cols)};
-%apply (long long* INPLACE_ARRAY2, int DIM1, int DIM2)
- {(long long* array, int rows, int cols)};
-%apply (unsigned long long* INPLACE_ARRAY2, int DIM1, int DIM2)
- {(unsigned long long* array, int rows, int cols)};
-%apply (float* INPLACE_ARRAY2, int DIM1, int DIM2)
- {(float* array, int rows, int cols)};
-%apply (double* INPLACE_ARRAY2, int DIM1, int DIM2)
- {(double* array, int rows, int cols)};
-%apply (long double* INPLACE_ARRAY2, int DIM1, int DIM2)
- {(long double* array, int rows, int cols)};
+%apply_numpy_typemaps(signed char )
+%apply_numpy_typemaps(unsigned char )
+%apply_numpy_typemaps(short )
+%apply_numpy_typemaps(unsigned short )
+%apply_numpy_typemaps(int )
+%apply_numpy_typemaps(unsigned int )
+%apply_numpy_typemaps(long )
+%apply_numpy_typemaps(unsigned long )
+%apply_numpy_typemaps(long long )
+%apply_numpy_typemaps(unsigned long long)
+%apply_numpy_typemaps(float )
+%apply_numpy_typemaps(double )
// Include the header file to be wrapped
%include "series.h"
Modified: trunk/numpy/doc/swig/numpy.i
===================================================================
--- trunk/numpy/doc/swig/numpy.i 2007-03-14 15:47:12 UTC (rev 3574)
+++ trunk/numpy/doc/swig/numpy.i 2007-03-14 19:57:23 UTC (rev 3575)
@@ -304,6 +304,10 @@
* (TYPE* ARGOUT_ARRAY1[ANY])
* (TYPE* ARGOUT_ARRAY2[ANY][ANY])
*
+ * (int DIM1, TYPE* IN_ARRAY1)
+ * (int DIM1, int DIM2, TYPE* IN_ARRAY2)
+ * (int DIM1, TYPE* INPLACE_ARRAY1)
+ *
* where "TYPE" is any type supported by the NumPy module. In python,
* the dimensions will not need to be specified. The IN_ARRAYs can be
* a numpy array or any sequence that can be converted to a numpy
@@ -314,32 +318,45 @@
* These typemaps can be applied to existing functions using the
* %apply directive:
*
- * %apply (double* IN_ARRAY1, int DIM1) {double* series, int length};
- * double sum(double* series, int length);
+ * %apply (double* IN_ARRAY1, int DIM1) {(double* series, int length)};
+ * double prod(double* series, int length);
*
- * %apply (double* IN_ARRAY2, int DIM1, int DIM2) {double* mx, int rows, int cols};
+ * %apply (double* IN_ARRAY2, int DIM1, int DIM2) {(double* mx, int rows, int cols)};
* double max(double* mx, int rows, int cols);
*
- * %apply (double* INPLACE_ARRAY1, int DIM1) {double* series, int length};
- * void negate(double* series, int length);
+ * %apply (double* INPLACE_ARRAY1, int DIM1) {(double* series, int length)};
+ * void ones(double* series, int length);
*
- * %apply (double* INPLACE_ARRAY2, int DIM1, int DIM2) {double* mx, int rows, int cols};
- * void normalize(double* mx, int rows, int cols);
+ * %apply (double* INPLACE_ARRAY2, int DIM1, int DIM2) {(double* mx, int rows, int cols)};
+ * void floor(double* mx, int rows, int cols);
*
- * %apply (double* ARGOUT_ARRAY1[ANY] {double series, int length};
+ * %apply (double* ARGOUT_ARRAY1[ANY] {(double series, int length)};
* void negate(double* series, int length);
*
- * %apply (double* ARGOUT_ARRAY2[ANY][ANY]) {double* mx, int rows, int cols};
+ * %apply (double* ARGOUT_ARRAY2[ANY][ANY]) {(double* mx, int rows, int cols)};
* void normalize(double* mx, int rows, int cols);
*
+ * %apply (int DIM1, double* IN_ARRAY1) {(int length, double* series)}
+ * double sum(int length, double* series)
+ *
+ * %apply (int DIM1, int DIM2, double* IN_ARRAY2) {(int rows, int cols, double* matrix)}
+ * double min(int length, double* series)
+ *
+ * %apply (int DIM1, double* INPLACE_ARRAY1) {(int length, double* series)}
+ * double zeros(int length, double* series)
+ *
* or directly with
*
- * double sum(double* IN_ARRAY1, int DIM1);
+ * double prod(double* IN_ARRAY1, int DIM1);
* double max(double* IN_ARRAY2, int DIM1, int DIM2);
- * void sum(double* INPLACE_ARRAY1, int DIM1);
- * void sum(double* INPLACE_ARRAY2, int DIM1, int DIM2);
- * void sum(double* ARGOUT_ARRAY1[ANY]);
- * void sum(double* ARGOUT_ARRAY2[ANY][ANY]);
+ * void ones(double* INPLACE_ARRAY1, int DIM1);
+ * void floor(double* INPLACE_ARRAY2, int DIM1, int DIM2);
+ * void negate(double* ARGOUT_ARRAY1[ANY]);
+ * void normalize(double* ARGOUT_ARRAY2[ANY][ANY]);
+ *
+ * double sum(int DIM1, double* IN_ARRAY1)
+ * double min(int DIM1, int DIM2, double* IN_ARRAY2)
+ * void zeros(int DIM1, double* INPLACE_ARRAY1)
*/
%define %numpy_typemaps(TYPE, TYPECODE)
@@ -441,6 +458,55 @@
}
}
+/* Typemap suite for (int DIM1, TYPE* IN_ARRAY1)
+ */
+%typemap(in) (int DIM1, TYPE* IN_ARRAY1)
+ (PyArrayObject* array=NULL, int is_new_object=0) {
+ array = obj_to_array_contiguous_allow_conversion($input, TYPECODE, &is_new_object);
+ npy_intp size[1] = {-1};
+ if (!array || !require_dimensions(array, 1) || !require_size(array, size, 1)) SWIG_fail;
+ $1 = (int) array->dimensions[0];
+ $2 = (TYPE*) array->data;
+}
+%typemap(freearg) (int DIM1, TYPE* IN_ARRAY1) {
+ if (is_new_object$argnum && array$argnum) Py_DECREF(array$argnum);
+}
+
+/* Typemap suite for (int DIM1, int DIM2, TYPE* IN_ARRAY2)
+ */
+%typemap(in) (int DIM1, int DIM2, TYPE* IN_ARRAY2)
+ (PyArrayObject* array=NULL, int is_new_object=0) {
+ array = obj_to_array_contiguous_allow_conversion($input, TYPECODE, &is_new_object);
+ npy_intp size[2] = {-1,-1};
+ if (!array || !require_dimensions(array, 2) || !require_size(array, size, 1)) SWIG_fail;
+ $1 = (int) array->dimensions[0];
+ $2 = (int) array->dimensions[1];
+ $3 = (TYPE*) array->data;
+}
+%typemap(freearg) (int DIM1, int DIM2, TYPE* IN_ARRAY2) {
+ if (is_new_object$argnum && array$argnum) Py_DECREF(array$argnum);
+}
+
+/* Typemap suite for (int DIM1, TYPE* INPLACE_ARRAY1)
+ */
+%typemap(in) (int DIM1, TYPE* INPLACE_ARRAY1) (PyArrayObject* temp=NULL) {
+ temp = obj_to_array_no_conversion($input, TYPECODE);
+ if (!temp || !require_contiguous(temp)) SWIG_fail;
+ $1 = 1;
+ for (int i=0; ind; ++i) $1 *= temp->dimensions[i];
+ $2 = (TYPE*) temp->data;
+}
+
+/* Typemap suite for (int DIM1, int DIM2, TYPE* INPLACE_ARRAY2)
+ */
+%typemap(in) (int DIM1, int DIM2, TYPE* INPLACE_ARRAY2) (PyArrayObject* temp=NULL) {
+ temp = obj_to_array_no_conversion($input, TYPECODE);
+ if (!temp || !require_contiguous(temp)) SWIG_fail;
+ $1 = (int) temp->dimensions[0];
+ $2 = (int) temp->dimensions[1];
+ $3 = (TYPE*) temp->data;
+}
+
%enddef /* %numpy_typemaps() macro */
Modified: trunk/numpy/doc/swig/numpy_swig.html
===================================================================
--- trunk/numpy/doc/swig/numpy_swig.html 2007-03-14 15:47:12 UTC (rev 3574)
+++ trunk/numpy/doc/swig/numpy_swig.html 2007-03-14 19:57:23 UTC (rev 3575)
@@ -351,9 +351,16 @@
SWIG interface file would need the following:
%{
+#define SWIG_FILE_WITH_INIT
#include "rms.h"
%}
+
%include "numpy.i"
+
+%init %{
+import_array();
+%}
+
%apply (double* IN_ARRAY1, int DIM1) {(double* seq, int n)};
%include "rms.h"
@@ -365,19 +372,30 @@
is an input array of one dimension and that the int represents
that dimension. This is precisely the pattern in the rms
prototype.
-Hopefully, no actual prototypes to be wrapped will have the names
+
Most likely, no actual prototypes to be wrapped will have the names
IN_ARRAY1 and DIM1. We use the %apply directive to apply
the typemap for one-dimensional input arrays of type double to the
actual prototype used by rms. Using numpy.i effectively,
therefore, requires knowing what typemaps are available and what they
do.
+Note that if the C function signature was in a different order:
+
+double rms(int n, double* seq);
+
+that SWIG would not match the typemap signature given above with
+the argument list for rms. Fortunately, numpy.i has a set of
+typemaps with the data pointer given last:
+
+%apply (int DIM1, double* IN_ARRAY1) {(int n, double* seq)};
+
The numpy.i file is currently located in the numpy/docs/swig
sub-directory under the numpy installation directory. Typically,
you will want to copy it to the directory where you are developing
-your wrappers.
+your wrappers. If it is ever adopted by
SWIG developers, then it
+will be installed in a standard place where
SWIG can find it.
A simple module that only uses a single SWIG interface file should
include the following:
@@ -389,17 +407,22 @@
import_array();
%}
-
Only one interface file should call import_array(). If you have
-more than one SWIG interface file, then subsequent files should not
-#define SWIG_FILE_WITH_INIT and should not call
-import_array().
+
Within a compiled python module, import_array() should only get
+called once. This could be in a C/C++ file that you have written and
+is linked to the module. If this is the case, then none of your
+interface files should #define SWIG_FILE_WITH_INIT or call
+import_array(). Or, this initialization call could be in a
+wrapper file generated by SWIG from an interface file that has the
+%init block as above. If this is the case, and you have more than
+one SWIG interface file, then only one interface file should
+#define SWIG_FILE_WITH_INIT and call import_array().
The typemap directives provided by numpy.i for arrays of different
data types, say double and int, are identical to one another
except for the C and NumPy type specifications. The typemaps are
-therefore implemented via a macro:
+therefore implemented (typically behind the scenes) via a macro:
%numpy_typemaps(TYPE, TYPECODE)
@@ -442,7 +465,7 @@
%numpy_typemaps(bool, NPY_UINT)
to fix the data length problem, and Input Arrays will work fine,
-but In-place Arrays will fail type-checking.
+but
In-place Arrays might fail type-checking.
In the following descriptions, we reference a generic TYPE, which
could be any of the C-types listed above.
@@ -456,6 +479,8 @@
- (TYPE* IN_ARRAY1, int DIM1)
- (TYPE* IN_ARRAY2, int DIM1, int DIM2)
+- (int DIM1, TYPE* IN_ARRAY1)
+- (int DIM1, int DIM2, TYPE* IN_ARRAY2)
@@ -470,6 +495,8 @@
- (TYPE* INPLACE_ARRAY1, int DIM1)
- (TYPE* INPLACE_ARRAY2, int DIM1, int DIM2)
+- (int DIM1, TYPE* INPLACE_ARRAY1)
+- (int DIM1, int DIM2, TYPE* INPLACE_ARRAY2)
@@ -481,9 +508,9 @@
therefore not sufficient. In python, the convential way to return
multiple arguments is to pack them into a tuple and return the tuple.
This is what the argout typemaps do. If a wrapped function that uses
-argout these argout typemaps has more than one return argument, they
-are so packed. The python user does not pass these arrays in, they
-simply get returned. The argout signatures are
+these argout typemaps has more than one return argument, they are so
+packed. The python user does not pass these arrays in, they simply
+get returned. The argout signatures are
- (TYPE ARGOUT_ARRAY1[ANY])
@@ -596,7 +623,7 @@
Modified: trunk/numpy/doc/swig/numpy_swig.txt
===================================================================
--- trunk/numpy/doc/swig/numpy_swig.txt 2007-03-14 15:47:12 UTC (rev 3574)
+++ trunk/numpy/doc/swig/numpy_swig.txt 2007-03-14 19:57:23 UTC (rev 3575)
@@ -57,9 +57,16 @@
`SWIG`_ interface file would need the following::
%{
+ #define SWIG_FILE_WITH_INIT
#include "rms.h"
%}
+
%include "numpy.i"
+
+ %init %{
+ import_array();
+ %}
+
%apply (double* IN_ARRAY1, int DIM1) {(double* seq, int n)};
%include "rms.h"
@@ -72,20 +79,31 @@
that dimension. This is precisely the pattern in the ``rms``
prototype.
-Hopefully, no actual prototypes to be wrapped will have the names
+Most likely, no actual prototypes to be wrapped will have the names
``IN_ARRAY1`` and ``DIM1``. We use the ``%apply`` directive to apply
the typemap for one-dimensional input arrays of type ``double`` to the
actual prototype used by ``rms``. Using ``numpy.i`` effectively,
therefore, requires knowing what typemaps are available and what they
do.
+Note that if the C function signature was in a different order::
+
+ double rms(int n, double* seq);
+
+that `SWIG`_ would not match the typemap signature given above with
+the argument list for ``rms``. Fortunately, ``numpy.i`` has a set of
+typemaps with the data pointer given last::
+
+ %apply (int DIM1, double* IN_ARRAY1) {(int n, double* seq)};
+
Using numpy.i
=============
The ``numpy.i`` file is currently located in the ``numpy/docs/swig``
sub-directory under the ``numpy`` installation directory. Typically,
you will want to copy it to the directory where you are developing
-your wrappers.
+your wrappers. If it is ever adopted by `SWIG`_ developers, then it
+will be installed in a standard place where `SWIG`_ can find it.
A simple module that only uses a single `SWIG`_ interface file should
include the following::
@@ -98,10 +116,15 @@
import_array();
%}
-Only one interface file should call ``import_array()``. If you have
-more than one `SWIG`_ interface file, then subsequent files should not
-``#define SWIG_FILE_WITH_INIT`` and should not call
-``import_array()``.
+Within a compiled python module, ``import_array()`` should only get
+called once. This could be in a C/C++ file that you have written and
+is linked to the module. If this is the case, then none of your
+interface files should ``#define SWIG_FILE_WITH_INIT`` or call
+``import_array()``. Or, this initialization call could be in a
+wrapper file generated by `SWIG`_ from an interface file that has the
+``%init`` block as above. If this is the case, and you have more than
+one `SWIG`_ interface file, then only one interface file should
+``#define SWIG_FILE_WITH_INIT`` and call ``import_array()``.
Available Typemaps
==================
@@ -109,7 +132,7 @@
The typemap directives provided by ``numpy.i`` for arrays of different
data types, say ``double`` and ``int``, are identical to one another
except for the C and `NumPy`_ type specifications. The typemaps are
-therefore implemented via a macro::
+therefore implemented (typically behind the scenes) via a macro::
%numpy_typemaps(TYPE, TYPECODE)
@@ -150,7 +173,7 @@
%numpy_typemaps(bool, NPY_UINT)
to fix the data length problem, and `Input Arrays`_ will work fine,
-but `In-place Arrays`_ will fail type-checking.
+but `In-place Arrays`_ might fail type-checking.
In the following descriptions, we reference a generic ``TYPE``, which
could be any of the C-types listed above.
@@ -166,6 +189,8 @@
* ``(TYPE* IN_ARRAY1, int DIM1)``
* ``(TYPE* IN_ARRAY2, int DIM1, int DIM2)``
+ * ``(int DIM1, TYPE* IN_ARRAY1)``
+ * ``(int DIM1, int DIM2, TYPE* IN_ARRAY2)``
In-place Arrays
---------------
@@ -178,6 +203,8 @@
* ``(TYPE* INPLACE_ARRAY1, int DIM1)``
* ``(TYPE* INPLACE_ARRAY2, int DIM1, int DIM2)``
+ * ``(int DIM1, TYPE* INPLACE_ARRAY1)``
+ * ``(int DIM1, int DIM2, TYPE* INPLACE_ARRAY2)``
Argout Arrays
-------------
@@ -188,9 +215,9 @@
therefore not sufficient. In python, the convential way to return
multiple arguments is to pack them into a tuple and return the tuple.
This is what the argout typemaps do. If a wrapped function that uses
-argout these argout typemaps has more than one return argument, they
-are so packed. The python user does not pass these arrays in, they
-simply get returned. The argout signatures are
+these argout typemaps has more than one return argument, they are so
+packed. The python user does not pass these arrays in, they simply
+get returned. The argout signatures are
* ``(TYPE ARGOUT_ARRAY1[ANY])``
* ``(TYPE ARGOUT_ARRAY2[ANY][ANY])``
Modified: trunk/numpy/doc/swig/series.cxx
===================================================================
--- trunk/numpy/doc/swig/series.cxx 2007-03-14 15:47:12 UTC (rev 3574)
+++ trunk/numpy/doc/swig/series.cxx 2007-03-14 19:57:23 UTC (rev 3575)
@@ -9,6 +9,10 @@
// void SNAMEOnes( TYPE * array, int size);
// TYPE SNAMEMax( TYPE * matrix, int rows, int cols);
// void SNAMEFloor(TYPE * array, int rows, int cols, TYPE floor);
+// TYPE SNAMESum( int size, TYPE * series);
+// void SNAMEZeros(int size, TYPE * array);
+// TYPE SNAMEMin( int rows, int cols, TYPE * matrix);
+// void SNAMECeil( int rows, int cols, TYPE * array, TYPE ceil);
//
// for any specified type TYPE (for example: short, unsigned int, long
// long, etc.) with given short name SNAME (for example: short, uint,
@@ -20,6 +24,10 @@
// * 1D in-place arrays
// * 2D input arrays
// * 2D in-place arrays
+// * 1D input arrays, data last
+// * 1D in-place arrays, data last
+// * 2D input arrays, data last
+// * 2D in-place arrays, data last
//
#define TEST_FUNCS(TYPE, SNAME) \
\
@@ -46,13 +54,45 @@
} \
\
void SNAME ## Floor(TYPE * array, int rows, int cols, TYPE floor) { \
- int i, j, index; \
- for (j=0; j ceil) array[index] = ceil; \
+ } \
+ } \
}
TEST_FUNCS(signed char , schar )
@@ -67,4 +107,3 @@
TEST_FUNCS(unsigned long long, ulongLong )
TEST_FUNCS(float , float )
TEST_FUNCS(double , double )
-TEST_FUNCS(long double , longDouble)
Modified: trunk/numpy/doc/swig/series.h
===================================================================
--- trunk/numpy/doc/swig/series.h 2007-03-14 15:47:12 UTC (rev 3574)
+++ trunk/numpy/doc/swig/series.h 2007-03-14 19:57:23 UTC (rev 3575)
@@ -8,6 +8,10 @@
// void SNAMEOnes( TYPE * array, int size);
// TYPE SNAMEMax( TYPE * matrix, int rows, int cols);
// void SNAMEFloor(TYPE * array, int rows, int cols, TYPE floor);
+// TYPE SNAMESum( int size, TYPE * series);
+// void SNAMEZeros(int size, TYPE * array);
+// TYPE SNAMEMin( int rows, int cols, TYPE * matrix);
+// void SNAMECeil( int rows, int cols, TYPE * array, TYPE ceil);
//
// for any specified type TYPE (for example: short, unsigned int, long
// long, etc.) with given short name SNAME (for example: short, uint,
@@ -19,13 +23,21 @@
// * 1D in-place arrays
// * 2D input arrays
// * 2D in-place arrays
+// * 1D input arrays, data last
+// * 1D in-place arrays, data last
+// * 2D input arrays, data last
+// * 2D in-place arrays, data last
//
#define TEST_FUNC_PROTOS(TYPE, SNAME) \
\
TYPE SNAME ## Prod( TYPE * series, int size); \
void SNAME ## Ones( TYPE * array, int size); \
TYPE SNAME ## Max( TYPE * matrix, int rows, int cols); \
-void SNAME ## Floor(TYPE * array, int rows, int cols, TYPE floor);
+void SNAME ## Floor(TYPE * array, int rows, int cols, TYPE floor); \
+TYPE SNAME ## Sum( int size, TYPE * series); \
+void SNAME ## Zeros(int size, TYPE * array); \
+TYPE SNAME ## Min( int rows, int cols, TYPE * matrix); \
+void SNAME ## Ceil( int rows, int cols, TYPE * array, TYPE ceil);
TEST_FUNC_PROTOS(signed char , schar )
TEST_FUNC_PROTOS(unsigned char , uchar )
@@ -39,6 +51,5 @@
TEST_FUNC_PROTOS(unsigned long long, ulongLong )
TEST_FUNC_PROTOS(float , float )
TEST_FUNC_PROTOS(double , double )
-TEST_FUNC_PROTOS(long double , longDouble)
#endif
Modified: trunk/numpy/doc/swig/testSeries.py
===================================================================
--- trunk/numpy/doc/swig/testSeries.py 2007-03-14 15:47:12 UTC (rev 3574)
+++ trunk/numpy/doc/swig/testSeries.py 2007-03-14 19:57:23 UTC (rev 3575)
@@ -25,450 +25,682 @@
####################################################
### Test functions that take arrays of type BYTE ###
def testScharProd(self):
- "Test the scharProd function"
+ "Test scharProd function"
self.assertEquals(Series.scharProd([1,2,3,4]), 24)
def testScharProdNonContainer(self):
- "Test the scharProd function with None"
+ "Test scharProd function with None"
self.assertRaises(TypeError, Series.scharProd, None)
def testScharOnes(self):
- "Test the scharOnes function"
+ "Test scharOnes function"
myArray = N.zeros(5,'b')
Series.scharOnes(myArray)
N.testing.assert_array_equal(myArray, N.array([1,1,1,1,1]))
def testScharMax(self):
- "Test the scharMax function"
+ "Test scharMax function"
matrix = [[-6,5,-4],[3,-2,1]]
self.assertEquals(Series.scharMax(matrix), 5)
def testScharMaxNonContainer(self):
- "Test the scharMax function with None"
+ "Test scharMax function with None"
self.assertRaises(TypeError, Series.scharMax, None)
def testScharMaxWrongDim(self):
- "Test the scharMax function with a 1D array"
+ "Test scharMax function with a 1D array"
self.assertRaises(TypeError, Series.scharMax, [0, -1, 2, -3])
def testScharFloor(self):
- "Test the scharFloor function"
+ "Test scharFloor function"
matrix = N.array([[10,-2],[-6,7]],'b')
Series.scharFloor(matrix,0)
N.testing.assert_array_equal(matrix, N.array([[10,0],[0,7]]))
+ def testScharSum(self):
+ "Test scharSum function"
+ self.assertEquals(Series.scharSum([-5,6,-7,8]), 2)
+
+ def testScharZeros(self):
+ "Test scharZeros function"
+ myArray = N.ones(5,'b')
+ Series.scharZeros(myArray)
+ N.testing.assert_array_equal(myArray, N.array([0,0,0,0,0]))
+
+ def testScharMin(self):
+ "Test scharMin function"
+ matrix = [[9,8],[7,6],[5,4]]
+ self.assertEquals(Series.scharMin(matrix), 4)
+
+ def testScharCeil(self):
+ "Test scharCeil function"
+ matrix = N.array([[10,-2],[-6,7]],'b')
+ Series.scharCeil(matrix,5)
+ N.testing.assert_array_equal(matrix, N.array([[5,-2],[-6,5]]))
+
#####################################################
### Test functions that take arrays of type UBYTE ###
def testUcharProd(self):
- "Test the ucharProd function"
+ "Test ucharProd function"
self.assertEquals(Series.ucharProd([1,2,3,4]), 24)
def testUcharProdNonContainer(self):
- "Test the ucharProd function with None"
+ "Test ucharProd function with None"
self.assertRaises(TypeError, Series.ucharProd, None)
def testUcharOnes(self):
- "Test the ucharOnes function"
+ "Test ucharOnes function"
myArray = N.zeros(5,'B')
Series.ucharOnes(myArray)
N.testing.assert_array_equal(myArray, N.array([1,1,1,1,1]))
def testUcharMax(self):
- "Test the ucharMax function"
+ "Test ucharMax function"
matrix = [[6,5,4],[3,2,1]]
self.assertEquals(Series.ucharMax(matrix), 6)
def testUcharMaxNonContainer(self):
- "Test the ucharMax function with None"
+ "Test ucharMax function with None"
self.assertRaises(TypeError, Series.ucharMax, None)
def testUcharMaxWrongDim(self):
- "Test the ucharMax function with a 1D array"
+ "Test ucharMax function with a 1D array"
self.assertRaises(TypeError, Series.ucharMax, [0, 1, 2, 3])
def testUcharFloor(self):
- "Test the ucharFloor function"
+ "Test ucharFloor function"
matrix = N.array([[10,2],[6,7]],'B')
Series.ucharFloor(matrix,7)
- N.testing.assert_array_equal(matrix, N.array([[10,0],[0,7]]))
+ N.testing.assert_array_equal(matrix, N.array([[10,7],[7,7]]))
+ def testUcharSum(self):
+ "Test ucharSum function"
+ self.assertEquals(Series.ucharSum([5,6,7,8]), 26)
+
+ def testUcharZeros(self):
+ "Test ucharZeros function"
+ myArray = N.ones(5,'B')
+ Series.ucharZeros(myArray)
+ N.testing.assert_array_equal(myArray, N.array([0,0,0,0,0]))
+
+ def testUcharMin(self):
+ "Test ucharMin function"
+ matrix = [[9,8],[7,6],[5,4]]
+ self.assertEquals(Series.ucharMin(matrix), 4)
+
+ def testUcharCeil(self):
+ "Test ucharCeil function"
+ matrix = N.array([[10,2],[6,7]],'B')
+ Series.ucharCeil(matrix,5)
+ N.testing.assert_array_equal(matrix, N.array([[5,2],[5,5]]))
+
#####################################################
### Test functions that take arrays of type SHORT ###
def testShortProd(self):
- "Test the shortProd function"
+ "Test shortProd function"
self.assertEquals(Series.shortProd([1,2,3,4]), 24)
def testShortProdNonContainer(self):
- "Test the shortProd function with None"
+ "Test shortProd function with None"
self.assertRaises(TypeError, Series.shortProd, None)
def testShortOnes(self):
- "Test the shortOnes function"
+ "Test shortOnes function"
myArray = N.zeros(5,'h')
Series.shortOnes(myArray)
N.testing.assert_array_equal(myArray, N.array([1,1,1,1,1]))
def testShortMax(self):
- "Test the shortMax function"
+ "Test shortMax function"
matrix = [[-6,5,-4],[3,-2,1]]
self.assertEquals(Series.shortMax(matrix), 5)
def testShortMaxNonContainer(self):
- "Test the shortMax function with None"
+ "Test shortMax function with None"
self.assertRaises(TypeError, Series.shortMax, None)
def testShortMaxWrongDim(self):
- "Test the shortMax function with a 1D array"
+ "Test shortMax function with a 1D array"
self.assertRaises(TypeError, Series.shortMax, [0, -1, 2, -3])
def testShortFloor(self):
- "Test the shortFloor function"
+ "Test shortFloor function"
matrix = N.array([[10,-2],[-6,7]],'h')
Series.shortFloor(matrix,0)
N.testing.assert_array_equal(matrix, N.array([[10,0],[0,7]]))
+ def testShortSum(self):
+ "Test shortSum function"
+ self.assertEquals(Series.shortSum([-5,6,-7,8]), 2)
+
+ def testShortZeros(self):
+ "Test shortZeros function"
+ myArray = N.ones(5,'h')
+ Series.shortZeros(myArray)
+ N.testing.assert_array_equal(myArray, N.array([0,0,0,0,0]))
+
+ def testShortMin(self):
+ "Test shortMin function"
+ matrix = [[9,8],[7,6],[5,4]]
+ self.assertEquals(Series.shortMin(matrix), 4)
+
+ def testShortCeil(self):
+ "Test shortCeil function"
+ matrix = N.array([[10,-2],[-6,7]],'h')
+ Series.shortCeil(matrix,5)
+ N.testing.assert_array_equal(matrix, N.array([[5,-2],[-6,5]]))
+
######################################################
### Test functions that take arrays of type USHORT ###
def testUshortProd(self):
- "Test the ushortProd function"
+ "Test ushortProd function"
self.assertEquals(Series.ushortProd([1,2,3,4]), 24)
def testUshortProdNonContainer(self):
- "Test the ushortProd function with None"
+ "Test ushortProd function with None"
self.assertRaises(TypeError, Series.ushortProd, None)
def testUshortOnes(self):
- "Test the ushortOnes function"
+ "Test ushortOnes function"
myArray = N.zeros(5,'H')
Series.ushortOnes(myArray)
N.testing.assert_array_equal(myArray, N.array([1,1,1,1,1]))
def testUshortMax(self):
- "Test the ushortMax function"
+ "Test ushortMax function"
matrix = [[6,5,4],[3,2,1]]
self.assertEquals(Series.ushortMax(matrix), 6)
def testUshortMaxNonContainer(self):
- "Test the ushortMax function with None"
+ "Test ushortMax function with None"
self.assertRaises(TypeError, Series.ushortMax, None)
def testUshortMaxWrongDim(self):
- "Test the ushortMax function with a 1D array"
+ "Test ushortMax function with a 1D array"
self.assertRaises(TypeError, Series.ushortMax, [0, 1, 2, 3])
def testUshortFloor(self):
- "Test the ushortFloor function"
+ "Test ushortFloor function"
matrix = N.array([[10,2],[6,7]],'H')
Series.ushortFloor(matrix,7)
- N.testing.assert_array_equal(matrix, N.array([[10,0],[0,7]]))
+ N.testing.assert_array_equal(matrix, N.array([[10,7],[7,7]]))
+ def testUshortSum(self):
+ "Test ushortSum function"
+ self.assertEquals(Series.ushortSum([5,6,7,8]), 26)
+
+ def testUshortZeros(self):
+ "Test ushortZeros function"
+ myArray = N.ones(5,'H')
+ Series.ushortZeros(myArray)
+ N.testing.assert_array_equal(myArray, N.array([0,0,0,0,0]))
+
+ def testUshortMin(self):
+ "Test ushortMin function"
+ matrix = [[9,8],[7,6],[5,4]]
+ self.assertEquals(Series.ushortMin(matrix), 4)
+
+ def testUshortCeil(self):
+ "Test ushortCeil function"
+ matrix = N.array([[10,2],[6,7]],'H')
+ Series.ushortCeil(matrix,5)
+ N.testing.assert_array_equal(matrix, N.array([[5,2],[5,5]]))
+
###################################################
### Test functions that take arrays of type INT ###
def testIntProd(self):
- "Test the intProd function"
+ "Test intProd function"
self.assertEquals(Series.intProd([1,2,3,4]), 24)
def testIntProdNonContainer(self):
- "Test the intProd function with None"
+ "Test intProd function with None"
self.assertRaises(TypeError, Series.intProd, None)
def testIntOnes(self):
- "Test the intOnes function"
+ "Test intOnes function"
myArray = N.zeros(5,'i')
Series.intOnes(myArray)
N.testing.assert_array_equal(myArray, N.array([1,1,1,1,1]))
def testIntMax(self):
- "Test the intMax function"
+ "Test intMax function"
matrix = [[-6,5,-4],[3,-2,1]]
self.assertEquals(Series.intMax(matrix), 5)
def testIntMaxNonContainer(self):
- "Test the intMax function with None"
+ "Test intMax function with None"
self.assertRaises(TypeError, Series.intMax, None)
def testIntMaxWrongDim(self):
- "Test the intMax function with a 1D array"
+ "Test intMax function with a 1D array"
self.assertRaises(TypeError, Series.intMax, [0, -1, 2, -3])
def testIntFloor(self):
- "Test the intFloor function"
+ "Test intFloor function"
matrix = N.array([[10,-2],[-6,7]],'i')
Series.intFloor(matrix,0)
N.testing.assert_array_equal(matrix, N.array([[10,0],[0,7]]))
+ def testIntSum(self):
+ "Test intSum function"
+ self.assertEquals(Series.intSum([-5,6,-7,8]), 2)
+
+ def testIntZeros(self):
+ "Test intZeros function"
+ myArray = N.ones(5,'i')
+ Series.intZeros(myArray)
+ N.testing.assert_array_equal(myArray, N.array([0,0,0,0,0]))
+
+ def testIntMin(self):
+ "Test intMin function"
+ matrix = [[9,8],[7,6],[5,4]]
+ self.assertEquals(Series.intMin(matrix), 4)
+
+ def testIntCeil(self):
+ "Test intCeil function"
+ matrix = N.array([[10,-2],[-6,7]],'i')
+ Series.intCeil(matrix,5)
+ N.testing.assert_array_equal(matrix, N.array([[5,-2],[-6,5]]))
+
####################################################
### Test functions that take arrays of type UINT ###
def testUintProd(self):
- "Test the uintProd function"
+ "Test uintProd function"
self.assertEquals(Series.uintProd([1,2,3,4]), 24)
def testUintProdNonContainer(self):
- "Test the uintProd function with None"
+ "Test uintProd function with None"
self.assertRaises(TypeError, Series.uintProd, None)
def testUintOnes(self):
- "Test the uintOnes function"
+ "Test uintOnes function"
myArray = N.zeros(5,'I')
Series.uintOnes(myArray)
N.testing.assert_array_equal(myArray, N.array([1,1,1,1,1]))
def testUintMax(self):
- "Test the uintMax function"
+ "Test uintMax function"
matrix = [[6,5,4],[3,2,1]]
self.assertEquals(Series.uintMax(matrix), 6)
def testUintMaxNonContainer(self):
- "Test the uintMax function with None"
+ "Test uintMax function with None"
self.assertRaises(TypeError, Series.uintMax, None)
def testUintMaxWrongDim(self):
- "Test the uintMax function with a 1D array"
+ "Test uintMax function with a 1D array"
self.assertRaises(TypeError, Series.uintMax, [0, 1, 2, 3])
def testUintFloor(self):
- "Test the uintFloor function"
+ "Test uintFloor function"
matrix = N.array([[10,2],[6,7]],'I')
Series.uintFloor(matrix,7)
- N.testing.assert_array_equal(matrix, N.array([[10,0],[0,7]]))
+ N.testing.assert_array_equal(matrix, N.array([[10,7],[7,7]]))
+ def testUintSum(self):
+ "Test uintSum function"
+ self.assertEquals(Series.uintSum([5,6,7,8]), 26)
+
+ def testUintZeros(self):
+ "Test uintZeros function"
+ myArray = N.ones(5,'I')
+ Series.uintZeros(myArray)
+ N.testing.assert_array_equal(myArray, N.array([0,0,0,0,0]))
+
+ def testUintMin(self):
+ "Test uintMin function"
+ matrix = [[9,8],[7,6],[5,4]]
+ self.assertEquals(Series.uintMin(matrix), 4)
+
+ def testUintCeil(self):
+ "Test uintCeil function"
+ matrix = N.array([[10,2],[6,7]],'I')
+ Series.uintCeil(matrix,5)
+ N.testing.assert_array_equal(matrix, N.array([[5,2],[5,5]]))
+
####################################################
### Test functions that take arrays of type LONG ###
def testLongProd(self):
- "Test the longProd function"
+ "Test longProd function"
self.assertEquals(Series.longProd([1,2,3,4]), 24)
def testLongProdNonContainer(self):
- "Test the longProd function with None"
+ "Test longProd function with None"
self.assertRaises(TypeError, Series.longProd, None)
def testLongOnes(self):
- "Test the longOnes function"
+ "Test longOnes function"
myArray = N.zeros(5,'l')
Series.longOnes(myArray)
N.testing.assert_array_equal(myArray, N.array([1,1,1,1,1]))
def testLongMax(self):
- "Test the longMax function"
+ "Test longMax function"
matrix = [[-6,5,-4],[3,-2,1]]
self.assertEquals(Series.longMax(matrix), 5)
def testLongMaxNonContainer(self):
- "Test the longMax function with None"
+ "Test longMax function with None"
self.assertRaises(TypeError, Series.longMax, None)
def testLongMaxWrongDim(self):
- "Test the longMax function with a 1D array"
+ "Test longMax function with a 1D array"
self.assertRaises(TypeError, Series.longMax, [0, -1, 2, -3])
def testLongFloor(self):
- "Test the longFloor function"
+ "Test longFloor function"
matrix = N.array([[10,-2],[-6,7]],'l')
Series.longFloor(matrix,0)
N.testing.assert_array_equal(matrix, N.array([[10,0],[0,7]]))
+ def testLongSum(self):
+ "Test longSum function"
+ self.assertEquals(Series.longSum([-5,6,-7,8]), 2)
+
+ def testLongZeros(self):
+ "Test longZeros function"
+ myArray = N.ones(5,'l')
+ Series.longZeros(myArray)
+ N.testing.assert_array_equal(myArray, N.array([0,0,0,0,0]))
+
+ def testLongMin(self):
+ "Test longMin function"
+ matrix = [[9,8],[7,6],[5,4]]
+ self.assertEquals(Series.longMin(matrix), 4)
+
+ def testLongCeil(self):
+ "Test longCeil function"
+ matrix = N.array([[10,-2],[-6,7]],'l')
+ Series.longCeil(matrix,5)
+ N.testing.assert_array_equal(matrix, N.array([[5,-2],[-6,5]]))
+
#####################################################
### Test functions that take arrays of type ULONG ###
def testUlongProd(self):
- "Test the ulongProd function"
+ "Test ulongProd function"
self.assertEquals(Series.ulongProd([1,2,3,4]), 24)
def testUlongProdNonContainer(self):
- "Test the ulongProd function with None"
+ "Test ulongProd function with None"
self.assertRaises(TypeError, Series.ulongProd, None)
def testUlongOnes(self):
- "Test the ulongOnes function"
+ "Test ulongOnes function"
myArray = N.zeros(5,'L')
Series.ulongOnes(myArray)
N.testing.assert_array_equal(myArray, N.array([1,1,1,1,1]))
def testUlongMax(self):
- "Test the ulongMax function"
+ "Test ulongMax function"
matrix = [[6,5,4],[3,2,1]]
self.assertEquals(Series.ulongMax(matrix), 6)
def testUlongMaxNonContainer(self):
- "Test the ulongMax function with None"
+ "Test ulongMax function with None"
self.assertRaises(TypeError, Series.ulongMax, None)
def testUlongMaxWrongDim(self):
- "Test the ulongMax function with a 1D array"
+ "Test ulongMax function with a 1D array"
self.assertRaises(TypeError, Series.ulongMax, [0, 1, 2, 3])
def testUlongFloor(self):
- "Test the ulongFloor function"
+ "Test ulongFloor function"
matrix = N.array([[10,2],[6,7]],'L')
Series.ulongFloor(matrix,7)
- N.testing.assert_array_equal(matrix, N.array([[10,0],[0,7]]))
+ N.testing.assert_array_equal(matrix, N.array([[10,7],[7,7]]))
+ def testUlongSum(self):
+ "Test ulongSum function"
+ self.assertEquals(Series.ulongSum([5,6,7,8]), 26)
+
+ def testUlongZeros(self):
+ "Test ulongZeros function"
+ myArray = N.ones(5,'L')
+ Series.ulongZeros(myArray)
+ N.testing.assert_array_equal(myArray, N.array([0,0,0,0,0]))
+
+ def testUlongMin(self):
+ "Test ulongMin function"
+ matrix = [[9,8],[7,6],[5,4]]
+ self.assertEquals(Series.ulongMin(matrix), 4)
+
+ def testUlongCeil(self):
+ "Test ulongCeil function"
+ matrix = N.array([[10,2],[6,7]],'L')
+ Series.ulongCeil(matrix,5)
+ N.testing.assert_array_equal(matrix, N.array([[5,2],[5,5]]))
+
########################################################
### Test functions that take arrays of type LONGLONG ###
def testLongLongProd(self):
- "Test the longLongProd function"
+ "Test longLongProd function"
self.assertEquals(Series.longLongProd([1,2,3,4]), 24)
def testLongLongProdNonContainer(self):
- "Test the longLongProd function with None"
+ "Test longLongProd function with None"
self.assertRaises(TypeError, Series.longLongProd, None)
def testLongLongOnes(self):
- "Test the longLongOnes function"
+ "Test longLongOnes function"
myArray = N.zeros(5,'q')
Series.longLongOnes(myArray)
N.testing.assert_array_equal(myArray, N.array([1,1,1,1,1]))
def testLongLongMax(self):
- "Test the longLongMax function"
+ "Test longLongMax function"
matrix = [[-6,5,-4],[3,-2,1]]
self.assertEquals(Series.longLongMax(matrix), 5)
def testLongLongMaxNonContainer(self):
- "Test the longLongMax function with None"
+ "Test longLongMax function with None"
self.assertRaises(TypeError, Series.longLongMax, None)
def testLongLongMaxWrongDim(self):
- "Test the longLongMax function with a 1D array"
+ "Test longLongMax function with a 1D array"
self.assertRaises(TypeError, Series.longLongMax, [0, -1, 2, -3])
def testLongLongFloor(self):
- "Test the longLongFloor function"
+ "Test longLongFloor function"
matrix = N.array([[10,-2],[-6,7]],'q')
Series.longLongFloor(matrix,0)
N.testing.assert_array_equal(matrix, N.array([[10,0],[0,7]]))
+ def testLongLongSum(self):
+ "Test longLongSum function"
+ self.assertEquals(Series.longLongSum([-5,6,-7,8]), 2)
+
+ def testLongLongZeros(self):
+ "Test longLongZeros function"
+ myArray = N.ones(5,'q')
+ Series.longLongZeros(myArray)
+ N.testing.assert_array_equal(myArray, N.array([0,0,0,0,0]))
+
+ def testLongLongMin(self):
+ "Test longLongMin function"
+ matrix = [[9,8],[7,6],[5,4]]
+ self.assertEquals(Series.longLongMin(matrix), 4)
+
+ def testLongLongCeil(self):
+ "Test longLongCeil function"
+ matrix = N.array([[10,-2],[-6,7]],'q')
+ Series.longLongCeil(matrix,5)
+ N.testing.assert_array_equal(matrix, N.array([[5,-2],[-6,5]]))
+
#########################################################
### Test functions that take arrays of type ULONGLONG ###
def testUlonglongProd(self):
- "Test the ulongLongProd function"
+ "Test ulongLongProd function"
self.assertEquals(Series.ulongLongProd([1,2,3,4]), 24)
def testUlongLongProdNonContainer(self):
- "Test the ulongLongProd function with None"
+ "Test ulongLongProd function with None"
self.assertRaises(TypeError, Series.ulongLongProd, None)
def testUlongLongOnes(self):
- "Test the ulongLongOnes function"
+ "Test ulongLongOnes function"
myArray = N.zeros(5,'Q')
Series.ulongLongOnes(myArray)
N.testing.assert_array_equal(myArray, N.array([1,1,1,1,1]))
def testUlongLongMax(self):
- "Test the ulongLongMax function"
+ "Test ulongLongMax function"
matrix = [[6,5,4],[3,2,1]]
self.assertEquals(Series.ulongLongMax(matrix), 6)
def testUlongLongMaxNonContainer(self):
- "Test the ulongLongMax function with None"
+ "Test ulongLongMax function with None"
self.assertRaises(TypeError, Series.ulongLongMax, None)
def testUlongLongMaxWrongDim(self):
- "Test the ulongLongMax function with a 1D array"
+ "Test ulongLongMax function with a 1D array"
self.assertRaises(TypeError, Series.ulongLongMax, [0, 1, 2, 3])
def testUlongLongFloor(self):
- "Test the ulongLongFloor function"
+ "Test ulongLongFloor function"
matrix = N.array([[10,2],[6,7]],'Q')
Series.ulongLongFloor(matrix,7)
- N.testing.assert_array_equal(matrix, N.array([[10,0],[0,7]]))
+ N.testing.assert_array_equal(matrix, N.array([[10,7],[7,7]]))
+ def testUlongLongSum(self):
+ "Test ulongLongSum function"
+ self.assertEquals(Series.ulongLongSum([5,6,7,8]), 26)
+
+ def testUlongLongZeros(self):
+ "Test ulongLongZeros function"
+ myArray = N.ones(5,'Q')
+ Series.ulongLongZeros(myArray)
+ N.testing.assert_array_equal(myArray, N.array([0,0,0,0,0]))
+
+ def testUlongLongMin(self):
+ "Test ulongLongMin function"
+ matrix = [[9,8],[7,6],[5,4]]
+ self.assertEquals(Series.ulongLongMin(matrix), 4)
+
+ def testUlongLongCeil(self):
+ "Test ulongLongCeil function"
+ matrix = N.array([[10,2],[6,7]],'Q')
+ Series.ulongLongCeil(matrix,5)
+ N.testing.assert_array_equal(matrix, N.array([[5,2],[5,5]]))
+
#####################################################
### Test functions that take arrays of type FLOAT ###
def testFloatProd(self):
- "Test the floatProd function (to 5 decimal places)"
+ "Test floatProd function (to 5 decimal places)"
self.assertAlmostEquals(Series.floatProd((1,2.718,3,4)), 32.616, 5)
def testFloatProdBadContainer(self):
- "Test the floatProd function with an invalid list"
+ "Test floatProd function with an invalid list"
self.assertRaises(BadListError, Series.floatProd, [3.14, "pi"])
def testFloatOnes(self):
- "Test the floatOnes function"
+ "Test floatOnes function"
myArray = N.zeros(5,'f')
Series.floatOnes(myArray)
N.testing.assert_array_equal(myArray, N.array([1.,1.,1.,1.,1.]))
def testFloatOnesNonArray(self):
- "Test the floatOnes function with a list"
+ "Test floatOnes function with a list"
self.assertRaises(TypeError, Series.floatOnes, [True, 0, 2.718, "pi"])
def testFloatMax(self):
- "Test the floatMax function"
+ "Test floatMax function"
matrix = [[-6,5,-4],[3.14,-2.718,1]]
self.assertEquals(Series.floatMax(matrix), 5.0)
def testFloatMaxNonContainer(self):
- "Test the floatMax function with None"
+ "Test floatMax function with None"
self.assertRaises(TypeError, Series.floatMax, None)
def testFloatMaxWrongDim(self):
- "Test the floatMax function with a 1D array"
+ "Test floatMax function with a 1D array"
self.assertRaises(TypeError, Series.floatMax, [0.0, -1, 2.718, -3.14])
def testFloatFloor(self):
- "Test the floatFloor function"
+ "Test floatFloor function"
matrix = N.array([[10,-2],[-6,7]],'f')
Series.floatFloor(matrix,0)
N.testing.assert_array_equal(matrix, N.array([[10,0],[0,7]]))
+ def testFloatSum(self):
+ "Test floatSum function"
+ self.assertEquals(Series.floatSum([-5,6,-7,8]), 2)
+
+ def testFloatZeros(self):
+ "Test floatZeros function"
+ myArray = N.ones(5,'f')
+ Series.floatZeros(myArray)
+ N.testing.assert_array_equal(myArray, N.array([0,0,0,0,0]))
+
+ def testFloatMin(self):
+ "Test floatMin function"
+ matrix = [[9,8],[7,6],[5,4]]
+ self.assertEquals(Series.floatMin(matrix), 4)
+
+ def testFloatCeil(self):
+ "Test floatCeil function"
+ matrix = N.array([[10,-2],[-6,7]],'f')
+ Series.floatCeil(matrix,5)
+ N.testing.assert_array_equal(matrix, N.array([[5,-2],[-6,5]]))
+
######################################################
### Test functions that take arrays of type DOUBLE ###
def testDoubleProd(self):
- "Test the doubleProd function"
+ "Test doubleProd function"
self.assertEquals(Series.doubleProd((1,2.718,3,4)), 32.616)
def testDoubleProdBadContainer(self):
- "Test the doubleProd function with an invalid list"
+ "Test doubleProd function with an invalid list"
self.assertRaises(BadListError, Series.doubleProd, [3.14, "pi"])
def testDoubleOnes(self):
- "Test the doubleOnes function"
+ "Test doubleOnes function"
myArray = N.zeros(5,'d')
Series.doubleOnes(myArray)
N.testing.assert_array_equal(myArray, N.array([1.,1.,1.,1.,1.]))
def testDoubleOnesNonArray(self):
- "Test the doubleOnes function with a list"
+ "Test doubleOnes function with a list"
self.assertRaises(TypeError, Series.doubleOnes, [True, 0, 2.718, "pi"])
def testDoubleMax(self):
- "Test the doubleMax function"
+ "Test doubleMax function"
matrix = [[-6,5,-4],[3.14,-2.718,1]]
self.assertEquals(Series.doubleMax(matrix), 5.0)
def testDoubleMaxNonContainer(self):
- "Test the doubleMax function with None"
+ "Test doubleMax function with None"
self.assertRaises(TypeError, Series.doubleMax, None)
def testDoubleMaxWrongDim(self):
- "Test the doubleMax function with a 1D array"
+ "Test doubleMax function with a 1D array"
self.assertRaises(TypeError, Series.doubleMax, [0.0, -1, 2.718, -3.14])
def testDoubleFloor(self):
- "Test the doubleFloor function"
+ "Test doubleFloor function"
matrix = N.array([[10,-2],[-6,7]],'d')
Series.doubleFloor(matrix,0)
N.testing.assert_array_equal(matrix, N.array([[10,0],[0,7]]))
- # ##########################################################
- # ### Test functions that take arrays of type LONGDOUBLE ###
- # def testLongDoubleProd(self):
- # "Test the longDoubleProd function"
- # self.assertEquals(Series.longDoubleProd((1,2.718,3,4)), 32.616)
+ def testDoubleSum(self):
+ "Test doubleSum function"
+ self.assertEquals(Series.doubleSum([-5,6,-7,8]), 2)
- # def testLongDoubleProdBadContainer(self):
- # "Test the longDoubleProd function with an invalid list"
- # self.assertRaises(BadListError, Series.longDoubleProd, [3.14, "pi"])
+ def testDoubleZeros(self):
+ "Test doubleZeros function"
+ myArray = N.ones(5,'d')
+ Series.doubleZeros(myArray)
+ N.testing.assert_array_equal(myArray, N.array([0,0,0,0,0]))
- # def testLongDoubleOnes(self):
- # "Test the longDoubleOnes function"
- # myArray = N.zeros(5,'g')
- # Series.longDoubleOnes(myArray)
- # N.testing.assert_array_equal(myArray, N.array([1.,1.,1.,1.,1.]))
+ def testDoubleMin(self):
+ "Test doubleMin function"
+ matrix = [[9,8],[7,6],[5,4]]
+ self.assertEquals(Series.doubleMin(matrix), 4)
- # def testLongDoubleOnesNonArray(self):
- # "Test the longDoubleOnes function with a list"
- # self.assertRaises(TypeError, Series.longDoubleOnes, [True, 0, 2.718, "pi"])
+ def testDoubleCeil(self):
+ "Test doubleCeil function"
+ matrix = N.array([[10,-2],[-6,7]],'d')
+ Series.doubleCeil(matrix,5)
+ N.testing.assert_array_equal(matrix, N.array([[5,-2],[-6,5]]))
######################################################################
From numpy-svn at scipy.org Wed Mar 14 16:15:35 2007
From: numpy-svn at scipy.org (numpy-svn at scipy.org)
Date: Wed, 14 Mar 2007 15:15:35 -0500 (CDT)
Subject: [Numpy-svn] r3576 - trunk/numpy/doc/swig
Message-ID: <20070314201535.10D7539C0A5@new.scipy.org>
Author: wfspotz at sandia.gov
Date: 2007-03-14 15:15:31 -0500 (Wed, 14 Mar 2007)
New Revision: 3576
Modified:
trunk/numpy/doc/swig/Makefile
trunk/numpy/doc/swig/README
trunk/numpy/doc/swig/testSeries.py
Log:
testSeries.py now prints numpy version; documentation updated
Modified: trunk/numpy/doc/swig/Makefile
===================================================================
--- trunk/numpy/doc/swig/Makefile 2007-03-14 19:57:23 UTC (rev 3575)
+++ trunk/numpy/doc/swig/Makefile 2007-03-14 20:15:31 UTC (rev 3576)
@@ -13,7 +13,7 @@
# List all of the subdirectories here for recursive make
SUBDIRS =
-all: $(WRAPPERS) series.cxx series.h
+all: $(WRAPPERS) series.cxx series.h html
./setup.py build
%_wrap.cxx: %.i numpy.i series.h
Modified: trunk/numpy/doc/swig/README
===================================================================
--- trunk/numpy/doc/swig/README 2007-03-14 19:57:23 UTC (rev 3575)
+++ trunk/numpy/doc/swig/README 2007-03-14 20:15:31 UTC (rev 3576)
@@ -72,7 +72,7 @@
----
* Support for complex data types should be added. Currently swig
- dies with a syntax error when the %numpy_typemaps macro isused
+ dies with a syntax error when the %numpy_typemaps macro is used
with complex types.
* Better ARGOUT typemaps need to be implemented and tested. I
Modified: trunk/numpy/doc/swig/testSeries.py
===================================================================
--- trunk/numpy/doc/swig/testSeries.py 2007-03-14 19:57:23 UTC (rev 3575)
+++ trunk/numpy/doc/swig/testSeries.py 2007-03-14 20:15:31 UTC (rev 3576)
@@ -711,6 +711,8 @@
suite.addTest(unittest.makeSuite(SeriesTestCase))
# Execute the test suite
- print "Testing Module Series\n"
+ print "Testing Module Series"
+ print "NumPy version", N.__version__
+ print
result = unittest.TextTestRunner(verbosity=2).run(suite)
sys.exit(len(result.errors) + len(result.failures))
From numpy-svn at scipy.org Wed Mar 14 17:07:11 2007
From: numpy-svn at scipy.org (numpy-svn at scipy.org)
Date: Wed, 14 Mar 2007 16:07:11 -0500 (CDT)
Subject: [Numpy-svn] r3577 - trunk/numpy/doc/swig
Message-ID: <20070314210711.6E67D39C0B7@new.scipy.org>
Author: wfspotz at sandia.gov
Date: 2007-03-14 16:07:05 -0500 (Wed, 14 Mar 2007)
New Revision: 3577
Added:
trunk/numpy/doc/swig/numpy_swig.pdf
Modified:
trunk/numpy/doc/swig/Makefile
trunk/numpy/doc/swig/numpy_swig.html
Log:
Added LaTeX/PDF documentation
Modified: trunk/numpy/doc/swig/Makefile
===================================================================
--- trunk/numpy/doc/swig/Makefile 2007-03-14 20:15:31 UTC (rev 3576)
+++ trunk/numpy/doc/swig/Makefile 2007-03-14 21:07:05 UTC (rev 3577)
@@ -5,28 +5,53 @@
# ReStructured Text
RST2HTML = rst2html.py
-RFLAGS = --generator --time --no-xml-declaration
+RST2LATEX = rst2latex.py
+RFLAGS = --generator --time
+HTML_FLAGS = --no-xml-declaration
+LATEX_FLAGS =
+LATEX = pdflatex
# Web pages that need to be made
WEB_PAGES = numpy_swig.html
+# LaTeX files that need to be made
+LATEX_FILES = numpy_swig.tex
+
+# PDF files that need to be made
+PDF_FILES = numpy_swig.pdf
+
# List all of the subdirectories here for recursive make
SUBDIRS =
-all: $(WRAPPERS) series.cxx series.h html
+all: $(WRAPPERS) series.cxx series.h
./setup.py build
+doc: html pdf
+
%_wrap.cxx: %.i numpy.i series.h
swig -c++ -python $<
html: $(WEB_PAGES)
%.html: %.txt
- $(RST2HTML) $(RFLAGS) $< $@
+ $(RST2HTML) $(RFLAGS) $(HTML_FLAGS) $< $@
+tex: $(LATEX_FILES)
+
+%.tex: %.txt
+ $(RST2LATEX) $(RFLAGS) $(LATEX_FLAGS) $< $@
+
+pdf: $(PDF_FILES)
+
+%.pdf: %.tex
+ $(LATEX) $<
+ $(LATEX) $<
+
clean:
$(RM) -r build
$(RM) $(WRAPPERS)
$(RM) $(PROXIES)
+ $(RM) $(LATEX_FILES)
+ $(RM) *.aux *.dvi *.log *.out *~
-.PHONY : html clean
+.PHONY : alll doc html tex pdf clean
Modified: trunk/numpy/doc/swig/numpy_swig.html
===================================================================
--- trunk/numpy/doc/swig/numpy_swig.html 2007-03-14 20:15:31 UTC (rev 3576)
+++ trunk/numpy/doc/swig/numpy_swig.html 2007-03-14 21:07:05 UTC (rev 3577)
@@ -623,7 +623,7 @@
Added: trunk/numpy/doc/swig/numpy_swig.pdf
===================================================================
--- trunk/numpy/doc/swig/numpy_swig.pdf 2007-03-14 20:15:31 UTC (rev 3576)
+++ trunk/numpy/doc/swig/numpy_swig.pdf 2007-03-14 21:07:05 UTC (rev 3577)
@@ -0,0 +1,1420 @@
+%PDF-1.4
+5 0 obj
+<< /S /GoTo /D (introduction.0) >>
+endobj
+8 0 obj
+(Introduction)
+endobj
+9 0 obj
+<< /S /GoTo /D (using-numpy-i.0) >>
+endobj
+12 0 obj
+(Using numpy.i)
+endobj
+13 0 obj
+<< /S /GoTo /D (available-typemaps.0) >>
+endobj
+16 0 obj
+(Available Typemaps)
+endobj
+17 0 obj
+<< /S /GoTo /D (input-arrays.1) >>
+endobj
+20 0 obj
+(Input Arrays)
+endobj
+21 0 obj
+<< /S /GoTo /D (in-place-arrays.1) >>
+endobj
+24 0 obj
+(In-place Arrays)
+endobj
+25 0 obj
+<< /S /GoTo /D (argout-arrays.1) >>
+endobj
+28 0 obj
+(Argout Arrays)
+endobj
+29 0 obj
+<< /S /GoTo /D (helper-functions.0) >>
+endobj
+32 0 obj
+(Helper Functions)
+endobj
+33 0 obj
+<< /S /GoTo /D (macros.1) >>
+endobj
+36 0 obj
+(Macros)
+endobj
+37 0 obj
+<< /S /GoTo /D (routines.1) >>
+endobj
+40 0 obj
+(Routines)
+endobj
+41 0 obj
+<< /S /GoTo /D (acknowledgements.0) >>
+endobj
+44 0 obj
+(Acknowledgements)
+endobj
+45 0 obj
+<< /S /GoTo /D [46 0 R /Fit ] >>
+endobj
+48 0 obj <<
+/Length 3630
+/Filter /FlateDecode
+>>
+stream
+x??ko??????E???R?7?~?4w?"???|h?bow?v??:?}?k???y?%jW.??Y????&O?:?O??nu????Zk?j{x??????W"?hm[m??????r?U]?????)oJ?
+Zh?c??q"?AZ??__???? ?Ja????Jh????w?????B????X?????^o????Fwz??hT???
+#???[?{?C?H????y?={???/???#?=??;????????o??z?h??ze5??=7%4/??`?VZZy'??P+kt?????x??\_???,e[i?J??A???iYw?%I*????O??o?3"?$L?Pm????? ?#?O?????Y?aT?LJt7?b7wI????S8??Md???{f???n??????x?M??,?yR?Y?j?h}???nX?W$?[????8????k??C???#?b?g??&???GhR?m??G???$d??Cg:~???7???V?????Y????u??K???)'?????B????f????? S??????!q?`a????h?G'B??????}fC?Y$Nxt?c?P?z"?[???f?f?V???qG? 2?'???`fm0????@*D???$C????
?|?????????]?>!??L????m???OX?A?A (????o??U??????u?.?X?o? 3?