Kingle
Kingle

Reputation: 504

Python double-asterisk ** power operator behaving unexpectedly

I've written a function to replace scipy.interp1d by approximating the relationship between two variables (elev and MaxQ) in order to speed up my code. The equation is a fourth order polynomial. I would like the function to be able to compute Q values for single inputs and for 1D array inputs. The function is shown below.

def CalculateMaxFlow(elev):
    size=np.shape(elev)
    if size==():
        if (elev>367.8): #minimum elev for flow             
            return -0.00028194553726719*elev**4+0.284027992763652*elev**3-80.3765236558431*elev**2+1900880.72298153
        else: return 0
    else:
        MaxQ=np.zeros(np.shape(elev)[0])
        for i in range(np.shape(elev)[0]):
            if (elev[i]>367.8): #4th order polynomial. Not exact but okay for speeding up code              
                MaxQ[i]= -0.00028194553726719*((elev[i])**4)+0.284027992763652*((elev[i])**3)-80.3765236558431*((elev[i])**2)+1900880.72298153
            else: MaxQ[i]= 0               
        return MaxQ

elev1=380
elev5a=380+np.zeros(5)
elev5b=np.asarray([380,380,380,380,380])

Q1=CalculateMaxFlow(elev1)
print("Q1:"+ str(Q1))
Q2=CalculateMaxFlow(elev5a)
print("Q2:"+str(Q2))
Q3=CalculateMaxFlow(elev5b)
print("Q3:"+str(Q3))

The answers are as follows:

Q1:746.828053304
Q2:[ 746.8280533  746.8280533  746.8280533  746.8280533  746.8280533]
Q3:[ 6055481.13713196  6055481.13713196  6055481.13713196  6055481.13713196 6055481.13713196]

Q1 and Q2 give me the answer I expect. For some reason, Q3 does not. I'm wondering why this is. The only difference I can see in my console between eleva and elevb is that a is a float64 and b is an int32. Why would this change the result of the equation? Why then, does the result for Q1 (which is an int) also work as expected?

Upvotes: 3

Views: 554

Answers (1)

user2357112
user2357112

Reputation: 281056

With Q3, elev[i] is a numpy.int32 instance, and elev[i]**4 overflows. With Q1, elev is a Python int, and elev**4 uses arbitrary-precision arithmetic.

Upvotes: 4

Related Questions