11
$\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
    $\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 at 14:24
17
$\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$
  • 1
    $\begingroup$ Ah yes precisely what I was looking for, many thanks Michael! Is there a repository of such tricks? $\endgroup$ – Roman May 10 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 at 14:31
  • 2
    $\begingroup$ @MichaelE2 mathematica.stackexchange.com/questions/805/… $\endgroup$ – Chris K May 10 at 14:31
  • 1
    $\begingroup$ @ChrisK That must be it! Thanks. $\endgroup$ – Michael E2 May 10 at 14:32
  • 1
    $\begingroup$ @CATrevillian I would have thought it was in the MKL (Intel Math Kernel Library), but I didn't find it there. I guess I don't know. $\endgroup$ – Michael E2 May 11 at 3:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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