tuple creation in C extensions

Phil Austin phil at geog.ubc.ca
Sun Jun 11 13:46:13 EDT 2000


"Louis M. Pecora" <pecora at anvil.nrl.navy.mil> writes:

> In article <m33dml6p34.fsf at brant.geog.ubc.ca>, Phil Austin
> <phil at geog.ubc.ca> wrote:
> > If you're able to use the CXX extension, the sequence is:
> > 
> > Tuple t(2);
> > t[0]=Int(a);
> > t[1]=Int(b);
> > 
> > If the conversion fails, Int will throw an exception that
> > can be caught on the python side.
> 
> Phil,
> 
> What about reference counting for these CXX examples?

That's handled by the destructors for t, a, and b.  Here's
an example of a histogram extension I wrote recently that
takes a NumPy array and returns a dictionary with the bins
and counts.  I've also appended a session showing some
typical mistakes; CXX gives you quite  a bit of error checking
with minimal work

__________hist.cc_____________
#include"Python.h"
#include"arrayobject.h"
#include "CXX_Objects.h"
#include "CXX_Array.h"
#include "hist.hh"

using namespace Py;
using namespace std;

void inithist()
{
  static hist_module *hist = new hist_module;
}

static string hist_cc_ID=("$Id: hist.cc,v 1.3 2000/06/11 16:30:36 phil Exp phil $");


hist_module::hist_module(): ExtensionModule<hist_module>( "hist" )
{
  import_array();
  add_keyword_method("hist", &hist_module::ex_hist, 
		     "hist(data,max=max,min=min,numbins=numbins) -> dictionary");
  initialize( "documentation for the hist module" );

  Dict d( moduleDictionary() );
  d["rcsid"]=String(hist_cc_ID);
}

Object hist_module::ex_hist(const Tuple &args, const Dict &kws)
{
  args.verify_length(1);
  Array data(args[0]);
  if (data.species() != PyArray_FLOAT){
    throw ValueError("expecting float data");
  }
  float* dataPtr = (float*) data.to_C();
  int numbins = Int(kws["numbins"]);  
  float maxdata = Float(kws["max"]);  
  float mindata = Float(kws["min"]);  
  float binsize = (maxdata-mindata)/((float)numbins);
  Array outcounts(numbins,PyArray_INT);
  int* countPtr =(int*) outcounts.to_C();
  Array bincenters(numbins,PyArray_FLOAT);
  float* centerPtr = (float*) bincenters.to_C();
  Array binedges(numbins+1,PyArray_FLOAT);
  float* edgePtr = (float*) binedges.to_C();
  int  ibin;
  int lowcount=0;
  int highcount=0;
  int numpoints = data.dimension(1);
  for(int i = 0; i < numpoints; ++i){
    ibin = (int) ((*(dataPtr +i) - mindata) / binsize);
    if(ibin < 0){
      lowcount=lowcount + 1;
      continue;
    }
    if(ibin > (numbins - 1)){
      highcount = highcount + 1;
      continue;
    }
    *(countPtr + ibin) = *(countPtr + ibin) + 1;
  }
  for(int i = 0; i <= numbins; ++i){
    *(edgePtr + i) = mindata + (i*binsize);
  }
  for(int i = 0; i < numbins; ++i){
    *(centerPtr + i) = (*(edgePtr + i) + *(edgePtr + i + 1))/2.;
  }

  Dict retval;
  retval["edges"]=binedges;
  retval["centers"]=bincenters;
  retval["counts"]=outcounts;
  retval["lowcounts"]=Int(lowcount);
  retval["highcounts"]=Int(highcount);
  return retval;
}

_______hist.hh_______

#ifndef __hist__h
#define __hist__h

#include "Python.h"
#include "CXX_Objects.h"
#include "CXX_Extensions.h"

static std::string hist_h_ID=("$Id: hist.hh,v 1.1 2000/06/11 05:16:23 phil Exp $");

extern "C" void inithist();

class hist_module : public Py::ExtensionModule<hist_module>
{
public:
  hist_module();
  virtual ~hist_module() {}
private:
  Py::Object ex_hist (const Py::Tuple &args, const Py::Dict &kws);
};

#endif

_____demo  session______

>>> import  hist
>>> dir(hist)
['__doc__', '__file__', '__name__', 'hist', 'rcsid']
>>> hist.rcsid
'$Id: hist.cc,v 1.3 2000/06/11 16:30:36 phil Exp phil $'
>>> hist.hist.__doc__
'hist(data,max=max,min=min,numbins=numbins) -> dictionary'
>>> import Numeric
>>> import RandomArray
>>> myout=RandomArray.random((20000,))
>>> histout=hist.hist(myout.astype(Numeric.Float32),min=0.1,max= 1.,numbins=10)
>>> histout=hist.hist(myout,min=0.1,max= 1.,numbins=10)
Traceback (innermost last):
  File "<stdin>", line 1, in ?
ValueError: expecting float data
>>> histout=hist.hist(myout.astype(Numeric.Float32),min='oops',max= 1.,numbins=10)
Traceback (innermost last):
  File "<stdin>", line 1, in ?
ValueError: invalid literal for float(): oops
>>> histout=hist.hist(myout.astype(Numeric.Float32),minoops=0.1,max= 1.,numbins=10)
Traceback (innermost last):
  File "<stdin>", line 1, in ?
KeyError: min
>>> histout=hist.hist(min=0.1,max= 1.,numbins=10)
Traceback (innermost last):
  File "<stdin>", line 1, in ?
IndexError: Unexpected SeqBase<T> length.




More information about the Python-list mailing list