Revision: 4655
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=4655&view=rev
Author: jdh2358
Date: 2007-12-06 12:01:48 -0800 (Thu, 06 Dec 2007)
Log Message:
-----------
added pyrex simple sum demo
Modified Paths:
--------------
trunk/py4science/examples/lotka_volterra.py
Added Paths:
-----------
trunk/py4science/examples/pyrex/
trunk/py4science/examples/pyrex/Makefile
trunk/py4science/examples/pyrex/c_numpy.pxd
trunk/py4science/examples/pyrex/c_python.pxd
trunk/py4science/examples/pyrex/numpyx.pyx
trunk/py4science/examples/pyrex/run_test.py
trunk/py4science/examples/pyrex/setup.py
trunk/py4science/examples/pyrex/sums.pyx
trunk/py4science/examples/pyrex/sums_test.py
Modified: trunk/py4science/examples/lotka_volterra.py
===================================================================
--- trunk/py4science/examples/lotka_volterra.py 2007-12-06 19:18:49 UTC (rev
4654)
+++ trunk/py4science/examples/lotka_volterra.py 2007-12-06 20:01:48 UTC (rev
4655)
@@ -34,24 +34,22 @@
f = y[:,1] # extract the foxes vector
p.figure()
-p.plot(t, r, label='rabbits')
-p.plot(t, f, label='foxes')
+p.subplots_adjust(hspace=0.3)
+p.subplot(211)
+p.plot(t, r, color='blue', label='rabbits', lw=2)
+p.plot(t, f, color='green', label='foxes', lw=2)
p.xlabel('time (years)')
p.ylabel('population')
-p.title('population trajectories')
+p.title('population trajectories and phase plane')
p.grid()
p.legend()
-p.savefig('lotka_volterra.png', dpi=150)
-p.savefig('lotka_volterra.eps')
-p.figure()
-p.plot(r, f)
+p.subplot(212, aspect='equal')
+p.plot(r, f, 'k', lw=2)
p.xlabel('rabbits')
p.ylabel('foxes')
-p.title('phase plane')
-
# make a direction field plot with quiver
rmax = 1.1 * r.max()
fmax = 1.1 * f.max()
@@ -65,13 +63,13 @@
dR = dr(R, F)
dF = df(R, F)
-p.contour(R, F, dR, levels=[0], linewidths=3, colors='black')
-p.contour(R, F, dF, levels=[0], linewidths=3, colors='black')
+CSR = p.contour(R, F, dR, levels=[0], linewidths=3, colors='blue')
+CSF = p.contour(R, F, dF, levels=[0], linewidths=3, colors='green')
+
p.ylabel('foxes')
-p.title('trajectory, direction field and null clines')
-p.savefig('lotka_volterra_pplane.png', dpi=150)
-p.savefig('lotka_volterra_pplane.eps')
+p.savefig('lotka_volterra.png', dpi=150)
+p.savefig('lotka_volterra.eps')
p.show()
Added: trunk/py4science/examples/pyrex/Makefile
===================================================================
--- trunk/py4science/examples/pyrex/Makefile (rev 0)
+++ trunk/py4science/examples/pyrex/Makefile 2007-12-06 20:01:48 UTC (rev
4655)
@@ -0,0 +1,9 @@
+all:
+ python setup.py build_ext --inplace
+
+test: all
+ python sums_test.py
+
+.PHONY: clean
+clean:
+ rm -rf *~ *.so *.c *.o build
Added: trunk/py4science/examples/pyrex/c_numpy.pxd
===================================================================
--- trunk/py4science/examples/pyrex/c_numpy.pxd (rev 0)
+++ trunk/py4science/examples/pyrex/c_numpy.pxd 2007-12-06 20:01:48 UTC (rev
4655)
@@ -0,0 +1,125 @@
+# :Author: Travis Oliphant
+
+cdef extern from "numpy/arrayobject.h":
+
+ cdef enum NPY_TYPES:
+ NPY_BOOL
+ NPY_BYTE
+ NPY_UBYTE
+ NPY_SHORT
+ NPY_USHORT
+ NPY_INT
+ NPY_UINT
+ NPY_LONG
+ NPY_ULONG
+ NPY_LONGLONG
+ NPY_ULONGLONG
+ NPY_FLOAT
+ NPY_DOUBLE
+ NPY_LONGDOUBLE
+ NPY_CFLOAT
+ NPY_CDOUBLE
+ NPY_CLONGDOUBLE
+ NPY_OBJECT
+ NPY_STRING
+ NPY_UNICODE
+ NPY_VOID
+ NPY_NTYPES
+ NPY_NOTYPE
+
+ cdef enum requirements:
+ NPY_CONTIGUOUS
+ NPY_FORTRAN
+ NPY_OWNDATA
+ NPY_FORCECAST
+ NPY_ENSURECOPY
+ NPY_ENSUREARRAY
+ NPY_ELEMENTSTRIDES
+ NPY_ALIGNED
+ NPY_NOTSWAPPED
+ NPY_WRITEABLE
+ NPY_UPDATEIFCOPY
+ NPY_ARR_HAS_DESCR
+
+ NPY_BEHAVED
+ NPY_BEHAVED_NS
+ NPY_CARRAY
+ NPY_CARRAY_RO
+ NPY_FARRAY
+ NPY_FARRAY_RO
+ NPY_DEFAULT
+
+ NPY_IN_ARRAY
+ NPY_OUT_ARRAY
+ NPY_INOUT_ARRAY
+ NPY_IN_FARRAY
+ NPY_OUT_FARRAY
+ NPY_INOUT_FARRAY
+
+ NPY_UPDATE_ALL
+
+ cdef enum defines:
+ # Note: as of Pyrex 0.9.5, enums are type-checked more strictly, so
this
+ # can't be used as an integer.
+ NPY_MAXDIMS
+
+ ctypedef struct npy_cdouble:
+ double real
+ double imag
+
+ ctypedef struct npy_cfloat:
+ double real
+ double imag
+
+ ctypedef int npy_intp
+
+ ctypedef extern class numpy.dtype [object PyArray_Descr]:
+ cdef int type_num, elsize, alignment
+ cdef char type, kind, byteorder, hasobject
+ cdef object fields, typeobj
+
+ ctypedef extern class numpy.ndarray [object PyArrayObject]:
+ cdef char *data
+ cdef int nd
+ cdef npy_intp *dimensions
+ cdef npy_intp *strides
+ cdef object base
+ cdef dtype descr
+ cdef int flags
+
+ ctypedef extern class numpy.flatiter [object PyArrayIterObject]:
+ cdef int nd_m1
+ cdef npy_intp index, size
+ cdef ndarray ao
+ cdef char *dataptr
+
+ ctypedef extern class numpy.broadcast [object PyArrayMultiIterObject]:
+ cdef int numiter
+ cdef npy_intp size, index
+ cdef int nd
+ # These next two should be arrays of [NPY_MAXITER], but that is
+ # difficult to cleanly specify in Pyrex. Fortunately, it doesn't
matter.
+ cdef npy_intp *dimensions
+ cdef void **iters
+
+ object PyArray_ZEROS(int ndims, npy_intp* dims, NPY_TYPES type_num, int
fortran)
+ object PyArray_EMPTY(int ndims, npy_intp* dims, NPY_TYPES type_num, int
fortran)
+ dtype PyArray_DescrFromTypeNum(NPY_TYPES type_num)
+ object PyArray_SimpleNew(int ndims, npy_intp* dims, NPY_TYPES type_num)
+ int PyArray_Check(object obj)
+ object PyArray_ContiguousFromAny(object obj, NPY_TYPES type,
+ int mindim, int maxdim)
+ npy_intp PyArray_SIZE(ndarray arr)
+ npy_intp PyArray_NBYTES(ndarray arr)
+ void *PyArray_DATA(ndarray arr)
+ object PyArray_FromAny(object obj, dtype newtype, int mindim, int maxdim,
+ int requirements, object context)
+ object PyArray_FROMANY(object obj, NPY_TYPES type_num, int min,
+ int max, int requirements)
+ object PyArray_NewFromDescr(object subtype, dtype newtype, int nd,
+ npy_intp* dims, npy_intp* strides, void* data,
+ int flags, object parent)
+
+ void PyArray_ITER_NEXT(flatiter it)
+
+ void import_array()
Added: trunk/py4science/examples/pyrex/c_python.pxd
===================================================================
--- trunk/py4science/examples/pyrex/c_python.pxd
(rev 0)
+++ trunk/py4science/examples/pyrex/c_python.pxd 2007-12-06 20:01:48 UTC
(rev 4655)
@@ -0,0 +1,20 @@
+# -*- Mode: Python -*- Not really, but close enough
+
+# Expose as much of the Python C API as we need here
+
+cdef extern from "stdlib.h":
+ ctypedef int size_t
+
+cdef extern from "Python.h":
+ ctypedef int Py_intptr_t
+ void* PyMem_Malloc(size_t)
+ void* PyMem_Realloc(void *p, size_t n)
+ void PyMem_Free(void *p)
+ char* PyString_AsString(object string)
+ object PyString_FromString(char *v)
+ object PyString_InternFromString(char *v)
+ int PyErr_CheckSignals()
+ object PyFloat_FromDouble(double v)
+ void Py_XINCREF(object o)
+ void Py_XDECREF(object o)
+ void Py_CLEAR(object o) # use instead of decref
Added: trunk/py4science/examples/pyrex/numpyx.pyx
===================================================================
--- trunk/py4science/examples/pyrex/numpyx.pyx (rev 0)
+++ trunk/py4science/examples/pyrex/numpyx.pyx 2007-12-06 20:01:48 UTC (rev
4655)
@@ -0,0 +1,128 @@
+# -*- Mode: Python -*- Not really, but close enough
+
+cimport c_python
+cimport c_numpy
+import numpy
+
+# Numpy must be initialized
+c_numpy.import_array()
+
+def print_array_info(c_numpy.ndarray arr):
+ cdef int i
+
+ print '-='*10
+ print 'printing array info for ndarray at
0x%0lx'%(<c_python.Py_intptr_t>arr,)
+ print 'print number of dimensions:',arr.nd
+ print 'address of strides: 0x%0lx'%(<c_python.Py_intptr_t>arr.strides,)
+ print 'strides:'
+ for i from 0<=i<arr.nd:
+ # print each stride
+ print ' stride %d:'%i,<c_python.Py_intptr_t>arr.strides[i]
+ print 'memory dump:'
+ print_elements( arr.data, arr.strides, arr.dimensions,
+ arr.nd, sizeof(double), arr.dtype )
+ print '-='*10
+ print
+
+
+
+def sum_elements(c_numpy.ndarray arr):
+ cdef int i
+ cdef double x, val
+
+ x = 0.
+ val = 0.
+ for i from 0<=i<arr.dimensions[0]:
+ val = (<double*>(arr.data + i*arr.strides[0]))[0]
+ x = x + val
+
+ return x
+
+
+def scale_elements(int N):
+ cdef int i
+ cdef double x, val
+
+ x = 0.
+ val = 0.
+ for i from 0<=i<N:
+ val = 2.5 * i
+ x = x + val
+ return x
+
+
+cdef print_elements(char *data,
+ c_python.Py_intptr_t* strides,
+ c_python.Py_intptr_t* dimensions,
+ int nd,
+ int elsize,
+ object dtype):
+ cdef c_python.Py_intptr_t i,j
+ cdef void* elptr
+
+ if dtype not in [numpy.dtype(numpy.object_),
+ numpy.dtype(numpy.float64)]:
+ print ' print_elements() not (yet) implemented for dtype
%s'%dtype.name
+ return
+
+ if nd ==0:
+ if dtype==numpy.dtype(numpy.object_):
+ elptr = (<void**>data)[0] #[0] dereferences pointer in Pyrex
+ print ' ',<object>elptr
+ elif dtype==numpy.dtype(numpy.float64):
+ print ' ',(<double*>data)[0]
+ elif nd == 1:
+ for i from 0<=i<dimensions[0]:
+ if dtype==numpy.dtype(numpy.object_):
+ elptr = (<void**>data)[0]
+ print ' ',<object>elptr
+ elif dtype==numpy.dtype(numpy.float64):
+ print ' ',(<double*>data)[0]
+ data = data + strides[0]
+ else:
+ for i from 0<=i<dimensions[0]:
+ print_elements(data, strides+1, dimensions+1, nd-1, elsize, dtype)
+ data = data + strides[0]
+
+
+def test_methods(c_numpy.ndarray arr):
+ """Test a few attribute accesses for an array.
+
+ This illustrates how the pyrex-visible object is in practice a strange
+ hybrid of the C PyArrayObject struct and the python object. Some
+ properties (like .nd) are visible here but not in python, while others
+ like flags behave very differently: in python flags appears as a separate,
+ object while here we see the raw int holding the bit pattern.
+
+ This makes sense when we think of how pyrex resolves arr.foo: if foo is
+ listed as a field in the c_numpy.ndarray struct description, it will be
+ directly accessed as a C variable without going through Python at all.
+ This is why for arr.flags, we see the actual int which holds all the flags
+ as bit fields. However, for any other attribute not listed in the struct,
+ it simply forwards the attribute lookup to python at runtime, just like
+ python would (which means that AttributeError can be raised for
+ non-existent attributes, for example)."""
+
+ print 'arr.any() :',arr.any()
+ print 'arr.nd :',arr.nd
+ print 'arr.flags :',arr.flags
+
+def test():
+ """this function is pure Python"""
+ arr1 = numpy.array(-1e-30,dtype=numpy.float64)
+ arr2 = numpy.array([1.0,2.0,3.0],dtype=numpy.float64)
+
+ arr3 = numpy.arange(9,dtype=numpy.float64)
+ arr3.shape = 3,3
+
+ four = 4
+ arr4 = numpy.array(['one','two',3,four],dtype=numpy.object_)
+
+ arr5 = numpy.array([1,2,3]) # int types not (yet) supported by
print_elements
+
+ for arr in [arr1,arr2,arr3,arr4,arr5]:
+ print_array_info(arr)
+
+
+ arr = numpy.arange(10.0)
+ print 'sum el', sum_elements(arr)
Added: trunk/py4science/examples/pyrex/run_test.py
===================================================================
--- trunk/py4science/examples/pyrex/run_test.py (rev 0)
+++ trunk/py4science/examples/pyrex/run_test.py 2007-12-06 20:01:48 UTC (rev
4655)
@@ -0,0 +1,3 @@
+#!/usr/bin/env python
+from numpyx import test
+test()
Property changes on: trunk/py4science/examples/pyrex/run_test.py
___________________________________________________________________
Name: svn:executable
+ *
Added: trunk/py4science/examples/pyrex/setup.py
===================================================================
--- trunk/py4science/examples/pyrex/setup.py (rev 0)
+++ trunk/py4science/examples/pyrex/setup.py 2007-12-06 20:01:48 UTC (rev
4655)
@@ -0,0 +1,42 @@
+#!/usr/bin/env python
+"""Install file for example on how to use Pyrex with Numpy.
+
+For more details, see:
+http://www.scipy.org/Cookbook/Pyrex_and_NumPy
+http://www.scipy.org/Cookbook/ArrayStruct_and_Pyrex
+"""
+
+from distutils.core import setup
+from distutils.extension import Extension
+
+# Make this usable by people who don't have pyrex installed (I've committed
+# the generated C sources to SVN).
+try:
+ from Pyrex.Distutils import build_ext
+ has_pyrex = True
+except ImportError:
+ has_pyrex = False
+
+import numpy
+
+# Define a pyrex-based extension module, using the generated sources if pyrex
+# is not available.
+if has_pyrex:
+ pyx_sources = ['sums.pyx']
+ cmdclass = {'build_ext': build_ext}
+else:
+ pyx_sources = ['numpyx.c']
+ cmdclass = {}
+
+
+pyx_ext = Extension('sums',
+ pyx_sources,
+ include_dirs = [numpy.get_include()])
+
+# Call the routine which does the real work
+setup(name = 'sums',
+ description = 'Small example on using Pyrex to write a Numpy extension',
+ url = 'http://www.scipy.org/Cookbook/Pyrex_and_NumPy',
+ ext_modules = [pyx_ext],
+ cmdclass = cmdclass,
+ )
Added: trunk/py4science/examples/pyrex/sums.pyx
===================================================================
--- trunk/py4science/examples/pyrex/sums.pyx (rev 0)
+++ trunk/py4science/examples/pyrex/sums.pyx 2007-12-06 20:01:48 UTC (rev
4655)
@@ -0,0 +1,39 @@
+# -*- Mode: Python -*- Not really, but close enough
+
+cimport c_python
+cimport c_numpy
+import numpy
+
+# Numpy must be initialized
+c_numpy.import_array()
+
+def sum_elements(c_numpy.ndarray arr):
+ cdef int i
+ cdef double x, val
+
+ x = 0.
+ val = 0.
+ for i from 0<=i<arr.dimensions[0]:
+ val = (<double*>(arr.data + i*arr.strides[0]))[0]
+ x = x + val
+
+ return x
+
+
+
+def sum_elements2(c_numpy.ndarray arr):
+ cdef int i
+ cdef double x, val
+
+ arr = numpy.asarray(arr, numpy.float_)
+
+ if arr.nd!=1:
+ raise RuntimeError('only 1D arrays supported; found
shape=%s'%str(arr.shape))
+ assert(arr.nd==1)
+ x = 0.
+ val = 0.
+ for i from 0<=i<arr.dimensions[0]:
+ val = (<double*>(arr.data + i*arr.strides[0]))[0]
+ x = x + val
+
+ return x
Added: trunk/py4science/examples/pyrex/sums_test.py
===================================================================
--- trunk/py4science/examples/pyrex/sums_test.py
(rev 0)
+++ trunk/py4science/examples/pyrex/sums_test.py 2007-12-06 20:01:48 UTC
(rev 4655)
@@ -0,0 +1,29 @@
+import numpy
+import sums
+
+def sumpy(arr):
+
+ total = 0.
+ for val in x:
+ total += val
+ return total
+
+x = numpy.arange(10)
+y = numpy.random.rand(10,10)
+
+print 'sum(x)', sums.sum_elements(x)
+print 'sum2(x)', sums.sum_elements2(x)
+print 'sum(y)', sums.sum_elements(y)
+#print 'sum2(y)', sums.sum_elements2(y)
+
+x = numpy.arange(1e6)
+import time
+start = time.time()
+s1 = sums.sum_elements2(x)
+now = time.time()
+print 'pyrex time', now - start
+
+start = time.time()
+s1 = sumpy(x)
+now = time.time()
+print 'python time', now - start
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
SF.Net email is sponsored by:
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins