Boost logo

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