| #include <algorithm> |
| #include <cmath> |
| |
| extern "C" { |
| float slapy3_(float* x, float* y, float* z); |
| double dlapy3_(double* x, double* y, double* z); |
| } |
| |
| // Compute sqrt(x*x + y*y + z*z) taking care not to cause unnecessary overflow. |
| template <typename T> |
| T xlapy3(const T x, const T y, const T z) { |
| const T xabs = std::abs(x); |
| const T yabs = std::abs(y); |
| const T zabs = std::abs(z); |
| const T w = std::fmax(std::fmax(xabs, yabs), zabs); |
| |
| if (w == T(0)) { |
| // W can be zero for max(0,nan,0) adding all three entries together will |
| // make sure NaN will not disappear. |
| return (xabs + yabs + zabs); |
| } |
| |
| const T tx = xabs / w; |
| const T ty = yabs / w; |
| const T tz = zabs / w; |
| return w * std::sqrt(tx * tx + ty * ty + tz * tz); |
| } |
| |
| float slapy3_(float* x, float* y, float* z) { return xlapy3(*x, *y, *z); } |
| double dlapy3_(double* x, double* y, double* z) { return xlapy3(*x, *y, *z); } |