![](https://secure.gravatar.com/avatar/9c9772ac67c2ef57a0e03cf8fcd55bc9.jpg?s=120&d=mm&r=g)
I am working on developing algorithms that are usually called with parameters that are Numeric arrays. We have the usual challenge though of trying to craft code that will gracefully accept both floats or arrays. Because of the often discussed problem with the handling of zero length arrays we expend some effort to ensure that we don't make calls on floats that only work on arrays and have ended up with a bunch of code like safe_len() that can be called with either. Today we have a related problem but now it is with performance (see code below). Numeric is faster than NumArray operating on smaller arrays but it is still relatively slow handling regular floats. We could add to the safe_ suite of functions the fast_ series but this still entails a significant performance hit and is not exactly elegant. The problem is larger than just handling sqrt so I would appreciate any feedback or suggestions on how best to proceed. Thanks, Duncan ================================================= def safe_len(a): # Return the length of the input array or 1 if it is a scalar try: safelen = len(a) except: safelen = 1 return safelen ================================================= from scipy import arange, sqrt from math import sqrt as csqrt import time # this is slower ... start_time = time.clock() for i in range(1000): a = sqrt(i) t1 = time.clock() - start_time # this is faster ... start_time = time.clock() for i in range(1000): a = csqrt(i) t2 = time.clock() - start_time print t1, t2, t1 / t2 C:\sqrt.py 0.0537227007132 0.00181048033684 68.6731754663 ================================================= from scipy import sqrt from math import sqrt as csqrt import types def fast_sqrt(arg): if type(arg) == types.FloatType: return csqrt(arg) else: return sqrt(arg)
![](https://secure.gravatar.com/avatar/ec366db3649cf13f4061b519193849d6.jpg?s=120&d=mm&r=g)
Duncan Child wrote:
I am working on developing algorithms that are usually called with parameters that are Numeric arrays. We have the usual challenge though of trying to craft code that will gracefully accept both floats or arrays. Because of the often discussed problem with the handling of zero length arrays we expend some effort to ensure that we don't make calls on floats that only work on arrays and have ended up with a bunch of code like safe_len() that can be called with either.
Today we have a related problem but now it is with performance (see code below). Numeric is faster than NumArray operating on smaller arrays but it is still relatively slow handling regular floats. We could add to the safe_ suite of functions the fast_ series but this still entails a significant performance hit and is not exactly elegant.
A potential solution to the performance problem, though not the elegance problem, might be Pyrex. An untested sketch: cdef extern from "Numeric/arrayobject.h": bool PyArray_Check(object x) cdef extern from "math.h": double sqrt(double x) import Numeric def fast_sqrt(object x): if PyArray_Check(x): return Numeric.sqrt(x) else: return sqrt(x) -- Robert Kern rkern@ucsd.edu "In the fields of hell where the grass grows high Are the graves of dreams allowed to die." -- Richard Harter
![](https://secure.gravatar.com/avatar/9c9772ac67c2ef57a0e03cf8fcd55bc9.jpg?s=120&d=mm&r=g)
Thanks for the suggestion Robert. If we ignore the elegance requirement then handling scalars as a special case in pure Python is an adequate approach. However, I am hoping that Numeric3 will allow us to write more elegant functions that perform well on both scalars and arrays. Regards, Duncan Robert Kern wrote:
Duncan Child wrote:
I am working on developing algorithms that are usually called with parameters that are Numeric arrays. We have the usual challenge though of trying to craft code that will gracefully accept both floats or arrays. Because of the often discussed problem with the handling of zero length arrays we expend some effort to ensure that we don't make calls on floats that only work on arrays and have ended up with a bunch of code like safe_len() that can be called with either.
Today we have a related problem but now it is with performance (see code below). Numeric is faster than NumArray operating on smaller arrays but it is still relatively slow handling regular floats. We could add to the safe_ suite of functions the fast_ series but this still entails a significant performance hit and is not exactly elegant.
A potential solution to the performance problem, though not the elegance problem, might be Pyrex.
An untested sketch:
cdef extern from "Numeric/arrayobject.h": bool PyArray_Check(object x)
cdef extern from "math.h": double sqrt(double x)
import Numeric
def fast_sqrt(object x): if PyArray_Check(x): return Numeric.sqrt(x) else: return sqrt(x)
participants (2)
-
Duncan Child
-
Robert Kern