Can someone help me to find a solution on how to calculate a cubic root of the negative number using python?
>>> math.pow(-3, float(1)/3)
nan
it does not work. Cubic root of the negative number is negative number. Any solutions?
A simple use of De Moivre's formula , is sufficient to show that the cube root of a value, regardless of sign, is a multi-valued function. That means, for any input value, there will be three solutions. Most of the solutions presented to far only return the principle root. A solution that returns all valid roots, and explicitly tests for non-complex special cases, is shown below.
import numpy
import math
def cuberoot( z ):
z = complex(z)
x = z.real
y = z.imag
mag = abs(z)
arg = math.atan2(y,x)
return [ mag**(1./3) * numpy.exp( 1j*(arg+2*n*math.pi)/3 ) for n in range(1,4) ]
Edit: As requested, in cases where it is inappropriate to have dependency on numpy, the following code does the same thing.
def cuberoot( z ):
z = complex(z)
x = z.real
y = z.imag
mag = abs(z)
arg = math.atan2(y,x)
resMag = mag**(1./3)
resArg = [ (arg+2*math.pi*n)/3. for n in range(1,4) ]
return [ resMag*(math.cos(a) + math.sin(a)*1j) for a in resArg ]
math.pow(abs(x),float(1)/3) * (1,-1)[x<0]
You could use:
-math.pow(3, float(1)/3)
Or more generally:
if x > 0:
return math.pow(x, float(1)/3)
elif x < 0:
return -math.pow(abs(x), float(1)/3)
else:
return 0
Taking the earlier answers and making it into a one-liner:
import math
def cubic_root(x):
return math.copysign(math.pow(abs(x), 1.0/3.0), x)
You can get the complete (all n roots) and more general (any sign, any power) solution using:
import cmath
x, t = -3., 3 # x**(1/t)
a = cmath.exp((1./t)*cmath.log(x))
p = cmath.exp(1j*2*cmath.pi*(1./t))
r = [a*(p**i) for i in range(t)]
Explanation: a is using the equation x u = exp(u*log(x)). This solution will then be one of the roots, and to get the others, rotate it in the complex plane by a (full rotation)/t.
You can also wrap the libm
library that offers a cbrt
(cube root) function:
from ctypes import *
libm = cdll.LoadLibrary('libm.so.6')
libm.cbrt.restype = c_double
libm.cbrt.argtypes = [c_double]
libm.cbrt(-8.0)
gives the expected
-2.0
The cubic root of a negative number is just the negative of the cubic root of the absolute value of that number.
ie x^(1/3) for x < 0 is the same as (-1)*(|x|)^(1/3)
Just make your number positive, and then perform cubic root.
You can use cbrt
from scipy.special
:
>>> from scipy.special import cbrt
>>> cbrt(-3)
-1.4422495703074083
This also works for arrays.
这也适用于 numpy 数组:
cbrt = lambda n: n/abs(n)*abs(n)**(1./3)
numpy
has an inbuilt cube root function cbrt
that handles negative numbers fine:
>>> import numpy as np
>>> np.cbrt(-8)
-2.0
This was added in version 1.10.0
(released 2015-10-06
).
Also works for numpy
array
/ list
inputs:
>>> np.cbrt([-8, 27])
array([-2., 3.])
Primitive solution:
def cubic_root(nr):
if nr<0:
return -math.pow(-nr, float(1)/3)
else:
return math.pow(nr, float(1)/3)
Probably massively non-pythonic, but it should work.
I just had a very similar problem and found the NumPy solution from this forum post .
In a nushell, we can use of the NumPy sign
and absolute
methods to help us out. Here is an example that has worked for me:
import numpy as np
x = np.array([-81,25])
print x
#>>> [-81 25]
xRoot5 = np.sign(x) * np.absolute(x)**(1.0/5.0)
print xRoot5
#>>> [-2.40822469 1.90365394]
print xRoot5**5
#>>> [-81. 25.]
So going back to the original cube root problem:
import numpy as np
y = -3.
np.sign(y) * np.absolute(y)**(1./3.)
#>>> -1.4422495703074083
I hope this helps.
For an arithmetic, calculator-like answer in Python 3:
>>> -3.0**(1/3)
-1.4422495703074083
or -3.0**(1./3)
in Python 2.
For the algebraic solution of x**3 + (0*x**2 + 0*x) + 3 = 0
use numpy:
>>> p = [1,0,0,3]
>>> numpy.roots(p)
[-3.0+0.j 1.5+2.59807621j 1.5-2.59807621j]
There is now math.cbrt
which handles negative roots seamlessly:
>>> import math
>>> math.cbrt(-3)
-1.4422495703074083
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.