Difference between **(1/2), math.sqrt and cmath.sqrt?
Asked Answered
H

4

13

What is the difference between x**(1/2) , math.sqrt() and cmath.sqrt()?

Why does cmath.sqrt() get complex roots of a quadratic right alone? Should I use that for my square roots exclusively? What do they do in the background differently?

Herminiahermione answered 13/11, 2015 at 2:25 Comment(0)
A
17

If you look at the documentation for cmath and math respectively, you will find that:

  1. cmath "provides access to mathematical functions for complex numbers"
  2. math "functions cannot be used with complex numbers; use the functions of the same name from the cmath module if you require support for complex numbers."
  3. The (**) operator maps to the pow function, with the important difference that pow converts its arguments to float.

Hence, you may see different results with the three functions for same arguments, as demonstrated here. Please note that if the expression has a real solution, there will be no difference between the value returned by math.sqrt and the real part of the value returned by cmath.sqrt. However, you will get an error with math.sqrt if no real solution is available.

Edit: As @jermenkoo points out, there will be a difference in the value returned by (**) between Python 2 and 3 due to the difference in how the / operator works. However, if you directly use 0.5 instead of 1/2, that should not cause issues.

Admit answered 13/11, 2015 at 2:37 Comment(3)
All that effort, and you hide the interesting differences behind a link? 3**(1/2)==1, math.sqrt(3)==1.73205080757, and cmath.sqrt(3)==(1.73205080757+0j).Yeo
Yeah, to set up a playground for OP to test should they want toAdmit
@Teepeemm: the first one depends on the behaviour of / operator - in your case it does integer division and calculates 3**0 = 1. In Python 3 is calculates the correct result, 1.732....Stream
R
5

As an addition to the existing answers, one notable difference is when processing negative numbers:

>>> import math
>>> math.sqrt(-4)
Traceback (most recent call last):
  File "<string>", line 301, in runcode
  File "<interactive input>", line 1, in <module>
ValueError: math domain error

The sqrt function only works on positive values.

>>> (-4)**0.5
(1.2246467991473532e-16+2j)

The ** operator is able to return a complex number in that case (note the wierd rounding error where the real part should be zero)

import cmath
>>> cmath.sqrt(-4)
2j

cmath.sqrt returns the perfect complex value probably because, as opposed to **, sqrt is a specialized square root computation, not just a float pow function.

Ram answered 18/4, 2018 at 20:49 Comment(1)
this entails that [c]math.sqrt() is to be preferred over **0.5Merrell
C
3

** .5 and math.sqrt are going to be nearly identical.

** .5 is going to dispatch you to pow from the standard C library powhttps://hg.python.org/cpython/file/661195a92131/Objects/floatobject.c#l783 and math.sqrt will dispatch you to sqrt in the standard C library sqrt, both of which should have similar performance. A bigger difference would probably be caused by the difference between

from math import sqrt
sqrt(x)

vs

import math
math.sqrt(x)

just because of the lookup of sqrt in the math module.

cmath is different and will be slower. It is for math on complex numbers, which is why it's returning complex numbers. Note that difference between cmath and math is different than packages like cPickle and pickle.

Consistence answered 13/11, 2015 at 2:42 Comment(0)
A
0

Beside other answers, from the performance perspective, I think math.sqrt and i**(1/2) are roughly the same.

>>> import timeit
>>> import math
>>> 
>>> timeit.timeit(stmt=lambda: [i**(1/2) for i in range(100000)], number=100)
1.5627256259995193
>>> timeit.timeit(stmt=lambda: [math.sqrt(i) for i in range(100000)], number=100)
1.556340146000366
>>> 

But cmath.sqrt is a little slower than them:

>>> import cmath
>>> timeit.timeit(stmt=lambda: [cmath.sqrt(i) for i in range(100000)], number=100)
1.9145739509986015
Apprehensive answered 23/3, 2023 at 12:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.