3

I have found that in a dataset I am using I get different results depending on how I tell Matlab to compute the power. If I submit the command Xpow=abs(X).^2; vs. Xpow=X.*conj(X);, I get different results. The latter is much faster to compute, but most people in my field use the former.

My question is which is more likely to be closer to the true value and why?

This difference is small in the following example of X=rand(100, 100)+rand(100,100)*i; the error approximately 10^-15. But it's larger in my actual dataset, about 10^-9. Accuracy matters in my line of research so I would like to know which is closest to the true value.

horchler
  • 3,258
  • 2
  • 27
  • 41
NWalk
  • 33

1 Answers1

5

short answer: The second one will typically be both faster and more accurate, but the first one might be more practical.

long answer: Let $x = a+bi$ with $a$ and $b$ real numbers.

Then $abs(x)=\sqrt{a^2+b^2}$, so $abs(x)^2 = \sqrt{a^2 + b^2}^2$, whereas $x\cdot conj(x) = (a+bi)(a-bi)=a^2+b^2+(ab-ba)i$. You see that both expressions are sub-optimal, because they can be simplified to $a^2+b^2$. But

  1. It is easier for the compiler/interpreter to obtimize the second one, because often it known about the properties of $+-\cdot/$, but not about $\sqrt{\ }$.
  2. Even if it does not optimize, the $(ab-ba)$ part will always evaluate to $0$ exaclty without any rounding, so no precision is lost. On the other hand taking a square-root and squaring again is slow (roots are much slower than the basic arithmetic operations), and will certainly produce some rounding error (though it should be very small)
  3. The reason one might still want to use the first expression is typing. $abs(x)$ is a real number, so the compiler knows that $abs(x)^2$ is again a real number. On the other hand $x$ and $conj(x)$ are both complex numbers, so the compiler will deduce that $x\cdot conj(x)$ is again a complex number. It won't know that it is actually real (unless you do an explicit cast).
  4. Most languages provide a function "sqAbs" or similar which does precisely what you want without any of these problems. But I'm not familiar enough with matlab to help you there. If neccessary, you can write it yourself $sqAbs(x) = real(x)^2 + imag(x)^2$.
Simon
  • 5,161
  • Thanks. I get identical results using the conjugate as to using the real and imaginary parts as you suggest. Now to test to see which is faster. Thanks – NWalk Mar 21 '17 at 17:08
  • For the record, Matlab does have magic to deduce that variable*conj(variable) is real and optimize it (probably not (complicated_expression)*conj(complicated_expression), though, as far as I know). – Federico Poloni Apr 06 '20 at 17:43