Which matrix library in C++ for scipy
Hello, I'm wondering what C++ matrix library I should for future inclusion of code in scipy. What I want to do is to port a class that can do Parzen window or K-neighboors, and it uses my own matrix library. Should I use Blitz ++ ? Matthieu
Matthieu Brucher wrote:
Hello,
I'm wondering what C++ matrix library I should for future inclusion of code in scipy. What I want to do is to port a class that can do Parzen window or K-neighboors, and it uses my own matrix library. Should I use Blitz ++ ?
At this point, the best choice for myself has been using boost::python with boost::ublas. I also use boost::multi_array.
At this point, the best choice for myself has been using boost::python with boost::ublas. I also use boost::multi_array.
Does scipy depend on Boost ? In that case, I can use it. I posted a message in the user list some time ago about neighboors algorithms in Python, and I had a link to BioPython, based on C++. I could use it, but don't want to install BioPython, and I'm willing to contribute my own version - I have it for a long time, and as I'm migrating toward Python for my work, much more easy to use - to scipy. In that perspective, I don't want to have a dependency on something that is not already there, and in scipy and in my own C++ code - that works very well ;) -. Matthieu
Matthieu Brucher wrote:
At this point, the best choice for myself has been using boost::python with boost::ublas. I also use boost::multi_array.
Does scipy depend on Boost ? In that case, I can use it. I posted a message in the user list some time ago about neighboors algorithms in Python, and I had a link to BioPython, based on C++. I could use it, but don't want to install BioPython, and I'm willing to contribute my own version - I have it for a long time, and as I'm migrating toward Python for my work, much more easy to use - to scipy. In that perspective, I don't want to have a dependency on something that is not already there, and in scipy and in my own C++ code - that works very well ;) -.
scipy does certainly not depend on Boost. Blitz is used in weave, but I don't know if this is mandatory (and it includes the blitz library); I think that actually, a C++ compiler is not even mandatory. Maybe I am missing something, but why the need for a matrix library for basic neighbors algorithm ? David
scipy does certainly not depend on Boost. Blitz is used in weave, but I don't know if this is mandatory (and it includes the blitz library); I think that actually, a C++ compiler is not even mandatory. Maybe I am missing something, but why the need for a matrix library for basic neighbors algorithm ?
That's right, I do not have the utility for a fully-fludged matrix library, but basic stuff yes. For a neighbooring algorithm, I can use basic computations, norms, ... Yes, I could program them directly, but if there is already something in scipy, no use to do it again ;) Matthieu
Matthieu Brucher wrote:
scipy does certainly not depend on Boost. Blitz is used in weave, but I don't know if this is mandatory (and it includes the blitz library); I think that actually, a C++ compiler is not even mandatory. Maybe I am missing something, but why the need for a matrix library for basic neighbors algorithm ?
That's right, I do not have the utility for a fully-fludged matrix library, but basic stuff yes. For a neighbooring algorithm, I can use basic computations, norms, ... Yes, I could program them directly, but if there is already something in scipy, no use to do it again ;)
I don't think there is anything like that in scipy. Something which could be useful would be to have a C++ class which reflects a numpy array, for seamless integration between eg boost.python and numpy. But that would be quite a challenge to get it right, I think. David
David Cournapeau wrote:
Matthieu Brucher wrote:
scipy does certainly not depend on Boost. Blitz is used in weave, but I don't know if this is mandatory (and it includes the blitz library); I think that actually, a C++ compiler is not even mandatory. Maybe I am missing something, but why the need for a matrix library for basic neighbors algorithm ?
That's right, I do not have the utility for a fully-fludged matrix library, but basic stuff yes. For a neighbooring algorithm, I can use basic computations, norms, ... Yes, I could program them directly, but if there is already something in scipy, no use to do it again ;)
I don't think there is anything like that in scipy. Something which could be useful would be to have a C++ class which reflects a numpy array, for seamless integration between eg boost.python and numpy. But that would be quite a challenge to get it right, I think.
David
There is numerical interface in boost::python. I don't use this approach myself. Here's why. I write all basic algorithms in c++. I try to use modern, generic programming when writing them. There is AFAIK, no reasonable way to interface such code to numerical/numpy. The C interface to numpy is too low-level. IOW, I like writing in c++, and I don't want to have to write code at such a low-level interface as would be needed to interface to numpy. So my approach is: 1. Write c++ algorithms with generic interfaces (where feasible). 2. When it is not feasible to use generic container types, I use boost::ublas::{vector/matrix} explicitly. 3. The above c++ code is parametrized (templated) on the container types. 4. Explicit instantiations of (3) are then exposed to python, normally specifying ublas::{vector/matrix} as the input/output types. This doesn't, of course, directly interoperate with numpy. I can, however, convert between numpy arrays and ublas::matrix (which currently requires copying the data, unfortunately).
There is numerical interface in boost::python.
I don't use this approach myself. Here's why. I write all basic algorithms in c++. I try to use modern, generic programming when writing them.
Same for me ;) There is AFAIK, no reasonable way to interface such code to numerical/numpy.
The C interface to numpy is too low-level. IOW, I like writing in c++, and I don't want to have to write code at such a low-level interface as would be needed to interface to numpy.
So my approach is:
1. Write c++ algorithms with generic interfaces (where feasible). 2. When it is not feasible to use generic container types, I use boost::ublas::{vector/matrix} explicitly. 3. The above c++ code is parametrized (templated) on the container types. 4. Explicit instantiations of (3) are then exposed to python, normally specifying ublas::{vector/matrix} as the input/output types.
This doesn't, of course, directly interoperate with numpy. I can, however, convert between numpy arrays and ublas::matrix (which currently requires copying the data, unfortunately).
What I'm doing after the last thread I started on numpy (SWIG, boost.pythonor ctypes) is using ctypes, so I have my headers, I make a C/C++ bridge and I use ctypes. If you have a (good) boost.python/whatever example for template instantiation and use in Python then, I'm sure a lot of people will thank you for the rest of your life - and even after ;) - Matthieu
Matthieu Brucher wrote:
There is numerical interface in boost::python.
I don't use this approach myself. Here's why. I write all basic algorithms in c++. I try to use modern, generic programming when writing them.
Same for me ;)
There is AFAIK, no reasonable way to interface such code to numerical/numpy.
The C interface to numpy is too low-level. IOW, I like writing in c++, and I don't want to have to write code at such a low-level interface as would be needed to interface to numpy.
So my approach is:
1. Write c++ algorithms with generic interfaces (where feasible). 2. When it is not feasible to use generic container types, I use boost::ublas::{vector/matrix} explicitly. 3. The above c++ code is parametrized (templated) on the container types. 4. Explicit instantiations of (3) are then exposed to python, normally specifying ublas::{vector/matrix} as the input/output types.
This doesn't, of course, directly interoperate with numpy. I can, however, convert between numpy arrays and ublas::matrix (which currently requires copying the data, unfortunately).
What I'm doing after the last thread I started on numpy (SWIG, boost.pythonor ctypes) is using ctypes, so I have my headers, I make a C/C++ bridge and I use ctypes. If you have a (good) boost.python/whatever example for template instantiation and use in Python then, I'm sure a lot of people will thank you for the rest of your life - and even after ;) -
Matthieu
I've got loads of examples. Good is subjective. What kind of example would you like?
Matthieu Brucher wrote:
I've got loads of examples. Good is subjective. What kind of example would you like?
For instance a simple example with an array in input and another one in ouput :)
Matthieu
boost::python can expose class as well as functions, but since you are only asking for a (lowly) function, this is a simple example. First, generic c++ code for computing a difference of 1 sample: template<typename scalar_t> inline std::complex<scalar_t> diff_demod (std::complex<scalar_t> z1, std::complex<scalar_t> z2, scalar_t epsilon) { return z2 * std::conj (Limit2<std::complex<scalar_t> > (z1, epsilon)); } Now code which takes 2 input containers and applies the above, returning an output container: template<typename out_t, typename in1_t, typename in2_t, typename scalar_t> inline out_t diff_demod2 (in1_t const& in1, in2_t const& in2, scalar_t epsilon) { if (boost::size (in1) != boost::size (in2)) throw std::runtime_error ("diff_demod size mismatch"); out_t out (boost::size (in1)); typename boost::range_const_iterator<in1_t>::type i1 = boost::begin(in1); typename boost::range_const_iterator<in2_t>::type i2 = boost::begin(in2); typename boost::range_iterator<out_t>::type o = boost::begin(out); for (; i1 != boost::end (in1); ++i1, ++i2, ++o) *o = diff_demod (*i1, *i2, epsilon); return out; } Another variant: template<typename out_t, typename in_t, typename scalar_t> inline out_t diff_demod1 (in_t const& in, scalar_t epsilon) { out_t out (boost::size (in)); typename boost::range_const_iterator<in_t>::type i = boost::begin(in); typename boost::range_iterator<out_t>::type o = boost::begin(out); typename boost::range_value<in_t>::type prev = 0; for (; i != boost::end (in); ++i, ++o) { *o = diff_demod (prev, *i, epsilon); prev = *i; } return out; } Now expose this to python: BOOST_PYTHON_MODULE(limit) { def ("Limit", &Compute<ublas::vector<Complex>, ublas::vector<Complex>, double >, (arg ("in"), arg ("epsilon")=1e-6)); def ("DiffDemod2", &diff_demod2<ublas::vector<Complex>,ublas::vector<Complex>,ublas::vector<Complex>,double>, (arg ("in1"), arg ("in2"), arg ("epsilon")=1e-6)) ; def ("DiffDemod1", &diff_demod1<ublas::vector<Complex>,ublas::vector<Complex>,double>, (arg ("in"), arg ("epsilon")=1e-6)) ; }
Neal Becker wrote:
David Cournapeau wrote:
y, but if there is already something in scipy, no use to do it again ;) I don't think there is anything like that in scipy. Something which could be useful would be to have a C++ class which reflects a numpy array, for seamless integration between eg boost.python and numpy. But that would be quite a challenge to get it right, I think.
David
There is numerical interface in boost::python.
I don't use this approach myself. Here's why. I write all basic algorithms in c++. I try to use modern, generic programming when writing them. Well, I myself try to avoid C++ like the plague :) What I meant was to have a C++ class which reflect the numpy array, in a sensible manner. For example, "automatic" memory management (at least as automatic as it can get in C++), having the member functions of the C class reflected in C++. The C api of numpy already defines a class, reflected in python. The job would be to do the same in C++. Eg:
dtype d("float") narray A((5, 4), d), B((4, 5), d( narray C() C = dot(A, B) Of course, to do it right is difficult and would require someone who know both numpy and C++ very well. David
On 4/26/07, Neal Becker <ndbecker2@gmail.com> wrote:
So my approach is:
1. Write c++ algorithms with generic interfaces (where feasible). 2. When it is not feasible to use generic container types, I use boost::ublas::{vector/matrix} explicitly. 3. The above c++ code is parametrized (templated) on the container types. 4. Explicit instantiations of (3) are then exposed to python, normally specifying ublas::{vector/matrix} as the input/output types.
This doesn't, of course, directly interoperate with numpy. I can, however, convert between numpy arrays and ublas::matrix (which currently requires copying the data, unfortunately).
I'm curious (being a rather primitive C++ user) as to why you don't like/use/prefer Blitz++ for this particular use? Blitz arrays are fairly numpy-like in much of their behavior, and one can be instantiated out of a numpy array with minimal cost (copying only the striding info, not the actual data). That's what weave uses both for weave.blitz and for weave.inline when type_converters=blitz is passed. Thanks, f
Fernando Perez wrote:
On 4/26/07, Neal Becker <ndbecker2@gmail.com> wrote:
So my approach is:
1. Write c++ algorithms with generic interfaces (where feasible). 2. When it is not feasible to use generic container types, I use boost::ublas::{vector/matrix} explicitly. 3. The above c++ code is parametrized (templated) on the container types. 4. Explicit instantiations of (3) are then exposed to python, normally specifying ublas::{vector/matrix} as the input/output types.
This doesn't, of course, directly interoperate with numpy. I can, however, convert between numpy arrays and ublas::matrix (which currently requires copying the data, unfortunately).
I'm curious (being a rather primitive C++ user) as to why you don't like/use/prefer Blitz++ for this particular use? Blitz arrays are fairly numpy-like in much of their behavior, and one can be instantiated out of a numpy array with minimal cost (copying only the striding info, not the actual data). That's what weave uses both for weave.blitz and for weave.inline when type_converters=blitz is passed.
Thanks,
f
I did try to evaluate this some time back, and don't recall the reasoning - but it may be that it appears that blitz++ development has stopped, and I don't want to invest in something that is going to die. The last release is Oct 2005.
On 4/26/07, Neal Becker <ndbecker2@gmail.com> wrote:
Fernando Perez wrote:
I'm curious (being a rather primitive C++ user) as to why you don't like/use/prefer Blitz++ for this particular use? Blitz arrays are fairly numpy-like in much of their behavior, and one can be instantiated out of a numpy array with minimal cost (copying only the striding info, not the actual data). That's what weave uses both for weave.blitz and for weave.inline when type_converters=blitz is passed.
Thanks,
f
I did try to evaluate this some time back, and don't recall the reasoning - but it may be that it appears that blitz++ development has stopped, and I don't want to invest in something that is going to die. The last release is Oct 2005.
Fair enough. From a quick scan of their ML archives (I haven't been subscribed for a long time) it seems that there's still /some/ activity, but Blitz has indeed suffered for a long time from lack of solid development. Julian Cummings --the current maintainer-- does his best, but I have the feeling that this is a project that is mostly love-and-spare-time for him, so it understandably gets a small time slice allocation. It's unfortunate, I think, given how well some aspects of numpy arrays map to Blitz ones (esp. the no-copy part). It looks like an opportunity for a good C++ programmer looking for an interesting project to adopt and re-energize. Cheers, f
I don't think there is anything like that in scipy. Something which could be useful would be to have a C++ class which reflects a numpy array, for seamless integration between eg boost.python and numpy. But that would be quite a challenge to get it right, I think.
OK, that confirms what I thought - nothing is in scipy at the moment -. Well, I hope someone will have time and patience to make this bridge in the future ;) Matthieu
participants (4)
-
David Cournapeau
-
Fernando Perez
-
Matthieu Brucher
-
Neal Becker