[C++-sig] Overloading sqrt(5.5)*myvector
Bruce Sherwood
Bruce_Sherwood at ncsu.edu
Wed Dec 26 07:11:58 CET 2007
Sorry to repeat myself and be insistent, but could someone please at
least comment on whether I'm doing anything obviously wrong, even if you
don't immediately have a solution to my serious problem? There was no
response to my question (see copy below) which I sent to both the numpy
and Boost mailing lists.
To the Boost experts: Is there something wrong, or something I
could/should change in how I'm trying to define to Boost the overloaded
multiplication of a numpy square root (or other numpy function) times my
own "vector" object? I'm seeing a huge performance hit in going from
Numeric to numpy because Numeric sqrt returned float whereas numpy sqrt
returns numpy.float64, so that the result is not one of my vector
objects. I don't have a problem with myvector*sqrt(5.5). Here is what I
currently am doing:
py::class_<vector>("vector", py::init< py::optional<double, double,
double> >())
.def( self * double())
.def( double() * self)
Desperately,
Bruce Sherwood
-------------------
I'm not sure whether this is a Numpy problem or a Boost problem, so I'm
posting to both communities. (I'm subscribed to both lists, but an
attempt to post yesterday to this Boost list seems never have gotten to
the archives, so I'm trying again. My apologies if this shows up twice
here.)
In old Numeric, type(sqrt(5.5)) was float, but in numpy, type(sqrt(5.5))
is numpy.float64. This leads to a big performance hit in calculations in
a beta version of VPython, using the VPython 3D "vector" class, compared
with the old version that used Numeric (VPython is a 3D graphics module
for Python; see vpython.org).
Operator overloading of the VPython vector class works fine for
vector*sqrt(5.5) but not for sqrt(5.5)*vector. The following free
function catches 5.5*vector but fails to catch sqrt(5.5)*vector, whose
type ends up as numpy.ndarray instead of the desired vector, with
concomitant slow conversions in later vector calculations:
inline vector
operator*( const double& s, const vector& v)
{ return vector( s*v.x, s*v.y, s*v.z); }
I've thrashed around on this, including trying to add this:
inline vector
operator*( const npy_float64& s, const vector& v)
{ return vector( s*v.x, s*v.y, s*v.z); }
But the compiler correctly complains that this is in conflict with the
version of double*vector, since in fact npy_float64 is actually double.
It's interesting and presumably meaningful to the knowledgeable (not me)
that vector*sqrt(5.5) yields a vector, even though the overloading
speaks of double, not a specifically numpy name:
inline vector
operator*( const double s) const throw()
{ return vector( s*x, s*y, s*z); }
VPython uses Boost, and the glue concerning vectors includes the following:
py::class_<vector>("vector", py::init< py::optional<double, double,
double> >())
.def( self * double())
.def( double() * self)
As far as I can understand from the Boost Python documentation, this is
the proper way to specify the left-hand and right-hand overloadings. But
do I have to add something like .def( npy_float64() * self)? Help would
be much appreciated.
Bruce Sherwood
More information about the Cplusplus-sig
mailing list