简体   繁体   中英

Cubic root of the negative number on python

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]

New in Python 3.11

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM