Automatic float32 promotion in numexpr

418 views Asked by At

Consider the following NumPy array of dtype float32:

In [29]: x = numpy.arange(10, dtype=numpy.float32)

When I multiply it by 2 using pytables.Expr, I get a float32 array back:

In [30]: tables.Expr('x * 2').eval().dtype
Out[30]: dtype('float32')

Yet when I multiply it by 2.0, I get a float64 array back:

In [31]: tables.Expr('x * 2.0').eval().dtype
Out[31]: dtype('float64')

Is there any way to specify the floating-point literal in the above expression in a way that would not cause the result to be promoted to float64?

More generally, I have an expression using float32 arrays, and I want to ensure that the result is also of type float32 (I don't mind float64 being used for intermediate calculations, but I can't afford to store the results as float64). How do I do this?

1

There are 1 answers

0
talonmies On BEST ANSWER

I am pretty certain the pytables.Expr is based on Numexpr. The documentation for Numexpr notes the following about promotion in expressions:

In operations implying a scalar and an array, the normal rules of casting are used in Numexpr, in contrast with NumPy, where array types takes priority. For example, if 'a' is an array of type float32 and 'b' is an scalar of type float64 (or Python float type, which is equivalent), then 'a*b' returns a float64 in Numexpr, but a float32 in NumPy (i.e. array operands take priority in determining the result type). If you need to keep the result a float32, be sure you use a float32 scalar too.

So that is probably what is happening. The floating point constant is responsible for promotion to 64 bit floats, and the solution is to explicitly specify floating point constants as float32.