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