[C++-sig] Re: regarding your post entitled " Numeric--factory function" onBoost.Python
Li Dongfeng
ldfwyn at 163.com
Mon Nov 1 16:41:00 CET 2004
Hi Faheem,
> boost::python::numeric::array arr(dim1,dim2);
--------------------------------------^^^^^^^^^
The problem with you code is the array constructor function usage.
That function cannot be called with two integers. See the numarray
(or Numeric) docs for correct usage.
I tested some solution but cannot reach an elegant one.
An elegant solution should use the numarray(or Numeric) API
directly to access the array contents in C++.
But I have only got a make-shift solution: use the boost::python
indexing suite. After you have used the indexing suite to map C++ vector
to Python sequence type, you can use a C++ vector as a python sequence
in C++ to initialize a numarray.array.
To map a C++ std::vector<double> to a Python sequence type named
``DoubleVec'', just make this boost.python extension:
------------------------
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>
#include <boost/python/implicit.hpp>
#include <boost/python/numeric.hpp>
#include <boost/python/tuple.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <vector>
BOOST_PYTHON_MODULE(_numpyext)
{
class_<std::vector<double> >("DoubleVec")
.def(vector_indexing_suite<std::vector<double> >());
}
---------------
Then in a C++ extension module, use:
---------------
// std::vector conversion to numarray.array
numeric::array vec2array_double(std::vector<double> x){
return numeric::array(x, "Float64");
}
BOOST_PYTHON_MODULE(_numpyext)
{
def("_cppvec2array", &vec2array_double);
}
---------------
this really works, the ``x'' in the numeric::array function call
is recognized by the numarray module constructor function ``array''
as a python sequence of type ``DoubleVec''.
This function is meant to return a array
in python, so in python we can wrap this function up:
-------------------
from _numpyext import _cppvec2array
def cpp2nar(x, shape=None):
"""Convert a C++ <std>vector to a numarray.array.
If shp is provided then reshape."""
xar = _cppvec2array(x)
if shape is not None:
xar.setshape(shape)
return xar
def nar2cpp(x, totype=None):
"""Convert a numarray.array to a 1D C++ std::vector.
xar should be a double type numarray.array
"""
xv = DoubleVec()
xv[:] = x.flat
xv.shape = x.shape
## C++ vector may not have a shape attribute,
## but we attach it in python.
## In C++ although we only use the data as one-dim,
## but when converting back to python we can
## use the shape infomation.
## return value is a C++ vector
return xv
--------------------------
We also give a conversion utility to convert numarray.array to C++ vector.
Below is a simple test with C++ extension and python wrapper:
----------------------------
// A test that vector indexing works.
std::vector<double> test_log(std::vector<double>& x){
std::vector<double>::iterator it;
for(it = x.begin(); it < x.end(); it++)
*it = log(*it);
return x;
}
BOOST_PYTHON_MODULE(_testnum)
{
def("test_log", test_log);
}
---------------------
--------------------
def test():
x = array([1, 4, 10.5, 100.0], shape=(2,2), type="Float64")
print x
xx = nar2cpp(x, totype="Float64") ## converted to C++ vector
yy = test_log(xx) ## done in C++ vector
y = cpp2nar(yy, shape=x.shape) ## back to numarray.array
print y
return
----------------------------
These code are not complete, they are simplified.
The includes and imports are omitted. You should
modify as you need. I have not use the module
in production use. I can send you the comple code
files if you like.
Cheers,
Li Dongfeng
ldfwyn at 163.com
2004-11-01
======= 2004-10-30 01:55:00 =======
>Dear Li Dongfeng,
>
>I saw your post on
>http://mail.python.org/pipermail/c++-sig/2004-August/007857.html I'm
>trying to do very similar things. Did you meet with any success with your
>efforts? In particular, I've had difficulty in creating a numeric array in
>C++ and passing it back to python. I get the impression that these factory
>functions have something to do with it, but I am not clear. Are these
>supposed to be used as constructors for arrays? Can you provide an
>example?
>
>A function like the following compiles without problems, but bombs when I
>try to use it. Can you help me?
>
>Thanks in advance. Faheem Mitha.
>
>****************************************************************************
>// Convert (C++) numeric matrix to (Python) Numarray numeric array.
>boost::python::object cppmat2pynumarr(Array2D<double> A)
>{
> int i, j;
> int dim1 = A.dim1();
> int dim2 = A.dim2();
>
> boost::python::numeric::array arr(dim1,dim2);
> for(i=0; i<dim1; i++)
> for(j=0; j<dim2; j++)
> arr[make_tuple(i,j)] = A[i][j];
> return arr;
>}
More information about the Cplusplus-sig
mailing list