|
Boost : |
From: Peter.Bienstman_at_[hidden]
Date: 2001-07-31 02:25:42
> I want to add a PyObject * method to deal with special Blitz Array
> (mathematical libray).
You'd better install Numerical Python first, it extends Python with
array capabilities.
This is a piece of code I wrote to convert Blitz arrays into
Numerical Python arrays. It is not very general, but rather tailored
to my own application.
cVector and cMatrix are typedefs for Blitz N*1 and N*N matrices. For
the vector, we take a copy of the data, for the matrix we leave Blitz
to manage to data. Also note that the arrays are in Fortran storage
order and that I play around with the strides when creating a NumPy
array, which uses C-storage order.
Peter
-------------------------------------
Peter Bienstman
Department of Information Technology
INTEC/IMEC - Ghent University
St.-Pietersnieuwstraat 41
B-9000 Gent - Belgium
E-mail: Peter.Bienstman_at_[hidden]
Tel: +32 9 264 3445
Fax: +32 9 264 3593
-------------------------------------
#include "boost/python/class_builder.hpp"
#include "arrayobject.h" // Numerical Python headers
using namespace boost::python;
//////////////////////////////////////////////////////////////////////
///////
//
// Functions convertion C++ objects to and from Python objects.
//
// Note on memory management: as the Blitz ref-counting system might
free
// data that is still in use in the Python environment, we have to
make
// a copy of the array data. However, we do this only for vectors. For
// matrices, the problem does not occur in practice and the copying
// would incur more overhead.
//
//////////////////////////////////////////////////////////////////////
///////
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
PyObject* to_python(cVector& c)
{
char* copy = (char*) malloc(c.rows()*sizeof(Complex));
memcpy(copy, c.data(), c.rows()*sizeof
(Complex));
int dim[1]; dim[0] = c.rows();
PyArrayObject* result = (PyArrayObject*)
PyArray_FromDimsAndData(1, dim, PyArray_CDOUBLE, copy);
return PyArray_Return(result);
}
PyObject* to_python(const cVector& c)
{return to_python(const_cast<cVector&>(c));}
cVector from_python(PyObject* o, type<const cVector&>)
{
if (!PyArray_Check(o))
{
PyErr_SetString(PyExc_ValueError, "expected numerical array.");
throw argument_error();
}
PyArrayObject* a = (PyArrayObject*) PyArray_Cast
((PyArrayObject*) o, PyArray_CDOUBLE);
if ( (a->nd != 1) || (a->dimensions[0] != global.N) )
{
PyErr_SetString(PyExc_ValueError, "array has wrong dimensions.");
throw argument_error();
}
return cVector((Complex*) a->data, global.N, neverDeleteData,
fortranArray);
}
PyObject* to_python(cMatrix& c)
{
int dim[2]; dim[0] = global.N; dim[1] = global.N;
PyArrayObject* result = (PyArrayObject*)
PyArray_FromDimsAndData(2, dim, PyArray_CDOUBLE, (char*) c.data
());
// Reflect Fortran storage orders.
int tmp = result->strides[0];
result->strides[0] = result->strides[1];
result->strides[1] = tmp;
return PyArray_Return(result);
}
BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE
BOOST_PYTHON_MODULE_INIT(camfr)
{
try
{
module_builder camfr("camfr");
import_array(); // Don't forget this!
....
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk