14
$\begingroup$

Here I'm not interested in accuracy (see 13614) but rather in raw speed. You'd think that for a complex machine-precision number z, calculating Abs[z]^2 should be faster than calculating Abs[z] because the latter requires a square root whereas the former does not. Yet it's not so:

s = RandomVariate[NormalDistribution[], {10^7, 2}].{1, I};
Developer`PackedArrayQ[s]
(* True *)
Abs[s]^2; // AbsoluteTiming // First
(* 0.083337 *)
Abs[s]; // AbsoluteTiming // First
(* 0.033179 *)

This indicates that Abs[z]^2 is really calculated by summing the squares of real and imaginary parts, taking a square root (for Abs[z]), and then re-squaring (for Abs[z]^2).

Is there a faster way to compute Abs[z]^2? Is there a hidden equivalent to the GSL's gsl_complex_abs2 function? The source code of this GSL function is simply to return Re[z]^2+Im[z]^2; no fancy tricks.

$\endgroup$
1
  • 1
    $\begingroup$ Here's an even slower way: (Re[#]^2 + Im[#]^2) & /@ s. And even slower still: Total[ReIm[#]^2] & /@ s $\endgroup$
    – bill s
    May 10, 2019 at 14:24

2 Answers 2

22
$\begingroup$

There's Internal`AbsSquare:

s = RandomVariate[NormalDistribution[], {10^7, 2}].{1, I};
foo = Internal`AbsSquare[s]; // AbsoluteTiming // First
murf = Abs[s]^2; // AbsoluteTiming // First
(*
  0.022909
  0.063441
*)

foo == murf
(*  True  *)
$\endgroup$
8
  • 1
    $\begingroup$ Ah yes precisely what I was looking for, many thanks Michael! Is there a repository of such tricks? $\endgroup$
    – Roman
    May 10, 2019 at 14:25
  • 1
    $\begingroup$ @Roman I was just looking. I thought there was a post about useful Internal` functions, but I couldn't find it just now. The context contains some useful numerical functions like Log1p and Expm1. Statistics`Library` also contains some nice, well-programmed functions. $\endgroup$
    – Michael E2
    May 10, 2019 at 14:31
  • 3
    $\begingroup$ @MichaelE2 mathematica.stackexchange.com/questions/805/… $\endgroup$
    – Chris K
    May 10, 2019 at 14:31
  • 1
    $\begingroup$ @ChrisK That must be it! Thanks. $\endgroup$
    – Michael E2
    May 10, 2019 at 14:32
  • 2
    $\begingroup$ @CATrevillian the Abs function likely operates by calling hypot which is safer but slower than just taking the square root of AbsSquare. AbsSquare, on the other hand, is likely expressed directly as re*re+im*im in assembly, or a vectorized version thereof: with the Compiler Explorer I find that all x86-64 compilers express this function as mulsd xmm0,xmm0; mulsd xmm1,xmm1; addsd xmm0, xmm1 even at -O3 level, which is a literal translation without frills or optimizations. $\endgroup$
    – Roman
    May 14, 2019 at 11:01
0
$\begingroup$

for v5.2, s Conjugate[s] is fast too, ref the pic:

enter image description here

$\endgroup$
5
  • 3
    $\begingroup$ On my computer, Re[s*Conjugate[s]] is about five to ten times slower than Internal`AbsSquare[s]. What is your $Version and what CPU do you have? $\endgroup$
    – Roman
    Jul 8, 2020 at 12:27
  • 1
    $\begingroup$ Hi, people here generally like users to post code as Mathematica code instead of just images or TeX, so they can copy-paste it. It makes it convenient for them and more likely they will engage with your posts. You may find this meta Q&A helpful. -- BTW, have you seen RandomVariate[NormalDistribution[], {10^7, 2}]? It's much faster on my machine. Ditto for RandomComplex[]. $\endgroup$
    – Michael E2
    Jul 8, 2020 at 12:48
  • $\begingroup$ @Roman Re[] is unnecessary, though it's very fast. My version is very old, it's v5.2. So there's no Internal`AbsSquare[]. $\endgroup$
    – infoage
    Jul 8, 2020 at 18:14
  • $\begingroup$ @MichaelE2 Thanks, man. My version is v5.2. This code is so simple that I had no motivation to paste text version at that moment. Sorry. $\endgroup$
    – infoage
    Jul 8, 2020 at 18:18
  • 1
    $\begingroup$ Maybe it's worth adding the version info to your answer. It turns out that I don't have the Statistics`NormalDistribution package (in V12.1.1), I suppose because it's been replaced by top-level statistics functions some versions ago. $\endgroup$
    – Michael E2
    Jul 8, 2020 at 19:08

Your Answer

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

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