7
$\begingroup$

I am doing research in electromagnetics (a branch of physics) and I deal with complex numbers in my computing tasks (I use MATLAB). Let's say $z$ is a complex number. To calculate the square of the magnitude of $z$, which is $|z|^2$, I can use two different ways that are mathematically equivalent:

  • $|z|^2 = \operatorname{abs}(z)^2$
  • $|z|^2 = zz^*$

However, the outcomes of the two operations above are slightly different (numerically). The difference is usually in the last decimal point of the result, so practically this does not affect my computations. But I'm curious why this difference occurs. Now, the interesting thing is the following. I can also calculate $|z|^2$ as

  • $|z|^2 = \operatorname{real}(z)^2+\operatorname{imag}(z)^2$

and this computation equals the result of $|z|^2 = zz^*$. So, how is the absolute value function (abs) implemented (in MATLAB or elsewhere)? Why does it give a different result? Which one of the results is more accurate?

$\endgroup$
2
  • 4
    $\begingroup$ I think your expectations are backwards: you should be surprised when two different floating-point calculations of the same quantity produce exactly the same result, rather than be surprised when they're different. $\endgroup$
    – user15247
    Commented Jul 14, 2015 at 15:07
  • 1
    $\begingroup$ Related: squaring inherently reduces precision. If the value you think is x is really x*(1+e), then squaring it exactly gives you x^2 *(1 + 2*e+ e^2), i.e. the relative error (neglecting the e^2) is twice as large as that in the input. Plus the rounding error in the multiply itself, which is what you are discussing here. So, this difference between two ways of finding the mag-squared is still likely less than your +2*e term. $\endgroup$
    – greggo
    Commented Jul 14, 2015 at 16:10

1 Answer 1

7
$\begingroup$

At least in MATLAB, I believe abs(z) is implemented as sqrt(z*z'). The extra square-root and squaring operation reduces numerical precision.

>> z = randn + randn * i
z =
   0.5377 + 1.8339i

>> abs(z)^2 - z*z'
ans =
   4.4409e-16

>> abs(z)^2 - sqrt(z*z')^2
ans =
     0
$\endgroup$
1
  • 4
    $\begingroup$ With regular floating point, abs(z) should be done as hypot(z.re, z.im), which can be more accurate than sqrt(z*z'), but also won't underflow or underflow just because z*z' doesn't fit in the range of normals. But, if you square that, it's still a different calculation than z*z' , so getting a result which is different in the l.s. bit is not surprising. $\endgroup$
    – greggo
    Commented Jul 14, 2015 at 16:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.