Re: [Numpy-discussion] [C++-sig] Overloading sqrt(5.5)*myvector
Thanks for the suggestion. It hadn't occurred to me to try to override numpy as you suggest. However, when I try the code shown below as the start of a test of this scheme, I get the following error: Traceback (most recent call last): File "C:\Documents and Settings\Bruce\My Documents\0VPythonWork\vectors.py", line 24, in <module> numpy.float64.__mul__ = new_mul TypeError: can't set attributes of built-in/extension type 'numpy.float64' I'm copying this to the numpy discussion list, as maybe someone there will see where to go starting from your suggestion. Bruce Sherwood --------------- import numpy class vector(object): def __init__(self,x,y,z): self.data = [x,y,z] def __mul__(self,other): return vector(other*self.data[0], other*self.data[1], other*self.data[2]) __rmul__ = __mul__ def show(self): print self.data old_mul = numpy.float64.__mul__ def new_mul( self, other ): if isinstance( other, vector ): return other*self else: return old_mul( self, other ) numpy.float64.__mul__ = new_mul a = vector(1,2,3) a.show() b = 5*a b.show() c = a*7 c.show() Roman Yakovenko wrote:
On Dec 26, 2007 8:11 AM, Bruce Sherwood <Bruce_Sherwood@ncsu.edu> wrote:
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,
If I understand you right, than you can do something like this:
replace __mul__ method of numpy.float64 class:
old_mul = numpy.float64.__mul__
def new_mul( self, other ): if other isinstance( vector ): return other*self else: return old_mul( self, other )
numpy.float64.__mul__ = new_mul
HTH
Bruce Sherwood wrote:
Thanks for the suggestion. It hadn't occurred to me to try to override numpy as you suggest. However, when I try the code shown below as the start of a test of this scheme, I get the following error:
Traceback (most recent call last): File "C:\Documents and Settings\Bruce\My Documents\0VPythonWork\vectors.py", line 24, in <module> numpy.float64.__mul__ = new_mul TypeError: can't set attributes of built-in/extension type 'numpy.float64'
I'm copying this to the numpy discussion list, as maybe someone there will see where to go starting from your suggestion.
Like most (or all) builtin-types, the numpy float scalars do not permit replacing their methods from Python. I'm not familiar with vpython's vector. If you can make it "not look like an ndarray", then you should be able to just implement __rmul__ on vector. -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco
Thanks for the comment, which limits the range of possible solutions. The VPython vector class is implemented in C++, not in Python. I made up the simple test in my previous note to try out the solution that had been offered and which you have usefully ruled out. Here is the relevant part of the vector class, which indeed doesn't look like an ndarray: inline vector operator*( const double s) const throw() { return vector( s*x, s*y, s*z); } and here is the free function for right multiplication: inline vector operator*( const double& s, const vector& v) { return vector( s*v.x, s*v.y, s*v.z); } Maybe the unsolvable problem is in the Boost definitions: py::class_<vector>("vector", py::init< py::optional<double, double, double> >()) .def( self * double()) .def( double() * self) Left multiplication is fine, but right multiplication isn't. Bruce Sherwood Robert Kern wrote:
Bruce Sherwood wrote:
Thanks for the suggestion. It hadn't occurred to me to try to override numpy as you suggest. However, when I try the code shown below as the start of a test of this scheme, I get the following error:
Traceback (most recent call last): File "C:\Documents and Settings\Bruce\My Documents\0VPythonWork\vectors.py", line 24, in <module> numpy.float64.__mul__ = new_mul TypeError: can't set attributes of built-in/extension type 'numpy.float64'
I'm copying this to the numpy discussion list, as maybe someone there will see where to go starting from your suggestion.
Like most (or all) builtin-types, the numpy float scalars do not permit replacing their methods from Python.
I'm not familiar with vpython's vector. If you can make it "not look like an ndarray", then you should be able to just implement __rmul__ on vector.
I should have added: This structure worked with the older version of VPython which used Numeric, but it doesn't work in the beta version which uses numpy. Since I don't know enough about either numpy or Boost, I'm left guessing which subsystem is the source of my difficulties, and clueless about how to remedy them. Bruce Sherwood Bruce Sherwood wrote:
Thanks for the comment, which limits the range of possible solutions. The VPython vector class is implemented in C++, not in Python. I made up the simple test in my previous note to try out the solution that had been offered and which you have usefully ruled out. Here is the relevant part of the vector class, which indeed doesn't look like an ndarray:
inline vector operator*( const double s) const throw() { return vector( s*x, s*y, s*z); }
and here is the free function for right multiplication:
inline vector operator*( const double& s, const vector& v) { return vector( s*v.x, s*v.y, s*v.z); }
Maybe the unsolvable problem is in the Boost definitions:
py::class_<vector>("vector", py::init< py::optional<double, double, double> >()) .def( self * double()) .def( double() * self)
Left multiplication is fine, but right multiplication isn't.
Bruce Sherwood
Robert Kern wrote:
Bruce Sherwood wrote:
Thanks for the suggestion. It hadn't occurred to me to try to override numpy as you suggest. However, when I try the code shown below as the start of a test of this scheme, I get the following error:
Traceback (most recent call last): File "C:\Documents and Settings\Bruce\My Documents\0VPythonWork\vectors.py", line 24, in <module> numpy.float64.__mul__ = new_mul TypeError: can't set attributes of built-in/extension type 'numpy.float64'
I'm copying this to the numpy discussion list, as maybe someone there will see where to go starting from your suggestion.
Like most (or all) builtin-types, the numpy float scalars do not permit replacing their methods from Python.
I'm not familiar with vpython's vector. If you can make it "not look like an ndarray", then you should be able to just implement __rmul__ on vector.
_______________________________________________ Numpy-discussion mailing list Numpy-discussion@scipy.org http://projects.scipy.org/mailman/listinfo/numpy-discussion
Hi Bruce, I have to add that I don't know the answer to your question either, but I do know that it is solvable and that once the list experts return, enlightenment will soon follow. My confidence comes from knowing the Python internals for how left and right multiplication are performed. As long as the "left" __mul__ operator returns NotImplemented, then the __rmul__ method will be attempted (see http://docs.python.org/ref/numeric-types.html). Of course, I don't know how to declare such a beast in Boost, having never used it, but I'm sure it is possible. My intuition is that the first problem you need to solve is getting Boot to generate the appropriate __rmul__ method. The second problem, if it even exists, is ensuring that __mul__ returns NotImplemented. Best of luck, -Kevin On Dec 27, 2007 10:15 AM, Bruce Sherwood <Bruce_Sherwood@ncsu.edu> wrote:
I should have added: This structure worked with the older version of VPython which used Numeric, but it doesn't work in the beta version which uses numpy. Since I don't know enough about either numpy or Boost, I'm left guessing which subsystem is the source of my difficulties, and clueless about how to remedy them.
Bruce Sherwood
Thanks for the comment, which limits the range of possible solutions. The VPython vector class is implemented in C++, not in Python. I made up the simple test in my previous note to try out the solution that had been offered and which you have usefully ruled out. Here is the relevant part of the vector class, which indeed doesn't look like an ndarray:
inline vector operator*( const double s) const throw() { return vector( s*x, s*y, s*z); }
and here is the free function for right multiplication:
inline vector operator*( const double& s, const vector& v) { return vector( s*v.x, s*v.y, s*v.z); }
Maybe the unsolvable problem is in the Boost definitions:
py::class_<vector>("vector", py::init< py::optional<double, double, double> >()) .def( self * double()) .def( double() * self)
Left multiplication is fine, but right multiplication isn't.
Bruce Sherwood
Robert Kern wrote:
Bruce Sherwood wrote:
Thanks for the suggestion. It hadn't occurred to me to try to override numpy as you suggest. However, when I try the code shown below as the start of a test of this scheme, I get the following error:
Traceback (most recent call last): File "C:\Documents and Settings\Bruce\My Documents\0VPythonWork\vectors.py", line 24, in <module> numpy.float64.__mul__ = new_mul TypeError: can't set attributes of built-in/extension type ' numpy.float64'
I'm copying this to the numpy discussion list, as maybe someone there will see where to go starting from your suggestion.
Like most (or all) builtin-types, the numpy float scalars do not permit replacing their methods from Python.
I'm not familiar with vpython's vector. If you can make it "not look
Bruce Sherwood wrote: like an
ndarray", then you should be able to just implement __rmul__ on vector.
_______________________________________________ Numpy-discussion mailing list Numpy-discussion@scipy.org http://projects.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ Numpy-discussion mailing list Numpy-discussion@scipy.org http://projects.scipy.org/mailman/listinfo/numpy-discussion
I realized belatedly that I should upgrade from Boost 1.33 to 1.34. Alas, that didn't cure my problem. Bruce Sherwood Bruce Sherwood wrote:
I should have added: This structure worked with the older version of VPython which used Numeric, but it doesn't work in the beta version which uses numpy. Since I don't know enough about either numpy or Boost, I'm left guessing which subsystem is the source of my difficulties, and clueless about how to remedy them.
Bruce Sherwood
Bruce Sherwood wrote:
Thanks for the comment, which limits the range of possible solutions. The VPython vector class is implemented in C++, not in Python. I made up the simple test in my previous note to try out the solution that had been offered and which you have usefully ruled out. Here is the relevant part of the vector class, which indeed doesn't look like an ndarray:
inline vector operator*( const double s) const throw() { return vector( s*x, s*y, s*z); }
and here is the free function for right multiplication:
inline vector operator*( const double& s, const vector& v) { return vector( s*v.x, s*v.y, s*v.z); }
Maybe the unsolvable problem is in the Boost definitions:
py::class_<vector>("vector", py::init< py::optional<double, double, double> >()) .def( self * double()) .def( double() * self)
Left multiplication is fine, but right multiplication isn't.
Bruce Sherwood
Robert Kern wrote:
Bruce Sherwood wrote:
Thanks for the suggestion. It hadn't occurred to me to try to override numpy as you suggest. However, when I try the code shown below as the start of a test of this scheme, I get the following error:
Traceback (most recent call last): File "C:\Documents and Settings\Bruce\My Documents\0VPythonWork\vectors.py", line 24, in <module> numpy.float64.__mul__ = new_mul TypeError: can't set attributes of built-in/extension type 'numpy.float64'
I'm copying this to the numpy discussion list, as maybe someone there will see where to go starting from your suggestion.
Like most (or all) builtin-types, the numpy float scalars do not permit replacing their methods from Python.
I'm not familiar with vpython's vector. If you can make it "not look like an ndarray", then you should be able to just implement __rmul__ on vector.
_______________________________________________ Numpy-discussion mailing list Numpy-discussion@scipy.org http://projects.scipy.org/mailman/listinfo/numpy-discussion
_______________________________________________ Numpy-discussion mailing list Numpy-discussion@scipy.org http://projects.scipy.org/mailman/listinfo/numpy-discussion
participants (3)
-
Bruce Sherwood
-
Kevin Jacobs <jacobs@bioinformed.com>
-
Robert Kern