JuanPablo
JuanPablo

Reputation: 24764

negative pow in python

I have this problem

>>> import math
>>> math.pow(-1.07,1.3)  
Traceback (most recent call last):  
  File "<stdin>", line 1, in <module>  
ValueError: math domain error

any suggestion ?

Upvotes: 7

Views: 22157

Answers (6)

Bimo
Bimo

Reputation: 6587

Powers of negative bases are complex numbers. Here's an example that explains how to fix it:

from numpy import *
t  = arange(-3, 3, 0.1)

for n in range(0,len(t)):
    T = t[n]
    x = (complex(-0.5,0))**T
    print(T, x)

Upvotes: 0

ncmathsadist
ncmathsadist

Reputation: 4891

Noninteger powers of complex (and negative) numbers involve an important subtlety. The exponential function is injective on the real line; i.e. exp(a) = exp(b) implies a = b. This is NOT so on the complex plane. Since exp(2*pi*i) = 1, the exponential function is 2*pi*i-periodic.

This leads to the problem: Which branch of the log function do we use? Said question is one of the central questions of complex analysis.

Python is responding intelligently to this situation. Unless you explicitly use its complex number constructor, you are going to be trafficking in reals. Since fractional powers of negatives are NEVER real, Python is appropriately throwing an exception.

Upvotes: 2

Captain Lepton
Captain Lepton

Reputation: 406

From the title of this post indicating that the power is negative, is it possible that you actually wanted 1.3-1.07 rather than -1.071.3?

Upvotes: 0

kennytm
kennytm

Reputation: 523274

(-1.07)1.3 will not be a real number, thus the Math domain error.

If you need a complex number, ab must be rewritten into eb ln a, e.g.

>>> import cmath
>>> cmath.exp(1.3 * cmath.log(-1.07))
(-0.6418264288034731-0.8833982926856789j)

If you just want to return NaN, catch that exception.

>>> import math
>>> def pow_with_nan(x, y):
...   try:
...     return math.pow(x, y)
...   except ValueError:
...     return float('nan')
...
>>> pow_with_nan(1.3, -1.07)   # 1.3 ** -1.07
0.755232399659047
>>> pow_with_nan(-1.07, 1.3)   # (-1.07) ** 1.3
nan

BTW, in Python usually the built-in a ** b is used for raising power, not math.pow(a, b).

>>> 1.3 ** -1.07
0.755232399659047
>>> (-1.07) ** 1.3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: negative number cannot be raised to a fractional power
>>> (-1.07+0j) ** 1.3
(-0.6418264288034731-0.8833982926856789j)

Upvotes: 24

Gabi Purcaru
Gabi Purcaru

Reputation: 31524

Don't use pow, and make the exponent complex (add 0j to it). Here is an example:

In [15]: (-1.07)**(1.3+0j)
Out[15]: (-0.64182642880347307-0.88339829268567893j)

No need for math functions :)

Upvotes: 9

alexyorke
alexyorke

Reputation: 4299

I am using python 2.5.4 and I get this:

>>> import math
>>> math.pow(-1.07,1.3)  
nan

What python version are you using?

Upvotes: 1

Related Questions