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

Reply via email to