- A+

Why running `std::abs`

over a big complex array is about 8 times slower than using `sqrt`

and `norm`

?

`#include <ctime> #include <cmath> #include <vector> #include <complex> #include <iostream> using namespace std; int main() { typedef complex<double> compd; vector<compd> arr(2e7); for (compd& c : arr) { c.real(rand()); c.imag(rand()); } double sm = 0; clock_t tm = clock(); for (const compd& c : arr) { sm += abs(c); } cout << sm << ' ' << clock() - tm << endl; // 5.01554e+011 - 1640 ms sm = 0; tm = clock(); for (const compd& c : arr) { sm += sqrt(norm(c)); } cout << sm << ' ' << clock() - tm << endl; // 5.01554e+011 - 154 sm = 0; tm = clock(); for (const compd& c : arr) { sm += hypot(c.real(), c.imag()); } cout << sm << ' ' << clock() - tm << endl; // 5.01554e+011 - 221 } `

I believe the two are not to be taken as identical in the strict sense.

From cppreference on `std::abs(std::complex)`

:

Errors and special cases are handled as if the function is implemented as

`std::hypot(std::real(z), std::imag(z))`

Also from cppreference on `std::norm(std::complex)`

:

The norm calculated by this function is also known as field norm or absolute square.

The Euclidean norm of a complex number is provided by

`std::abs`

, which is more costly to compute. In some situations, it may be replaced by`std::norm`

, for example, if`abs(z1) > abs(z2)`

then`norm(z1) > norm(z2)`

.

In short, there are cases where a different result is obtained from each function. Some of these may be found in `std::hypot`

. There the notes also mention the following:

`std::hypot(x, y)`

is equivalent to`std::abs(std::complex<double>(x,y))`

In general the accuracy of the result may be different (due to the usual floating point mess), and it seems the functions were designed in such a way to be as accurate as possible.