Hypot
Hypot is a mathematical function defined to calculate the length of the hypotenuse of a right-angle triangle. It was designed to avoid errors arising due to limited-precision calculations performed on computers.
Motivation and usage
Calculating the length of the hypotenuse of a triangle is possible using the square-root function on the sum of two squares, but hypot(x, y) avoids problems that occur when squaring very large or very small numbers.
The magnitude of the hypotenuse from (0, 0) to (x, y) can be calculated using
- [math]\displaystyle{ r = \sqrt{x^2 + y^2}. }[/math]
This operation is also known as Pythagorean addition.
However, the squares of very large or small values of x and y may exceed the range of machine precision when calculated on a computer, leading to an inaccurate result caused by arithmetic underflow and/or arithmetic overflow. The hypot function was designed to calculate the result without causing this problem.
The hypot function is often used together with the atan2 function to convert from Cartesian coordinates to polar coordinates:
- r = hypot(x, y),
- θ = atan2(y, x).
If either input is infinite, the result is infinite, i.e.
- hypot(x, ±∞) = hypot(±∞, x) = +∞
Because this is true for all possible values of x, including infinity, the IEEE 754 floating-point standard requires that this definition also applies if x is not a number (NaN).[1]
Implementation
The difficulty with the naive implementation is that x2 or y2 may overflow or underflow, unless the intermediate result is computed with extended precision. A common implementation technique is to exchange the values, if necessary, so that |x| ≥ |y|, and then use the equivalent form[2]
- [math]\displaystyle{ \begin{align} r &= \sqrt{x^2 + y^2} \\ &= \sqrt{x^2 \left( 1 + \left(\tfrac{y}{x}\right)^2\right)} \\ &= |x| \sqrt{1 + \left(\tfrac{y}{x}\right)^2} \left(= |x| + \frac{y}{|x|}\frac{y}{1 + \sqrt{1 + \left(\tfrac{y}{x}\right)^2 }}\right). \end{align} }[/math]
The computation of y/x cannot overflow unless both x and y are 0. If y/x underflows, the final result is equal to |x|, which is correct within the precision of the calculation. The square root is computed of a value between 1 and 2. Finally, the multiplication by |x| cannot underflow, and overflows only when the result is too large to represent.
This implementation has the downside that it requires an additional floating-point division, which can double the cost of the naive implementation, as multiplication and addition are typically far faster than division and square root.
More complex implementations avoid this by dividing the inputs into more cases:
- x ≫ y: hypot(x, y) = |x|, to within machine precision.
- x2 overflows: Multiply both x and y by a small scaling factor (e.g. 2−64 for IEEE single precision), use the naive algorithm which will now not overflow, and multiply the result by the (large) inverse (e.g. 264).
- y2 underflows: As above, but reverse the scaling factors to scale up the intermediate values.
- Otherwise: The naive algorithm is safe to use.
Additional techniques allow the result to be computed more accurately, e.g. to less than one ulp.[3]
Programming language support
The function is present in several programming languages:
- C99
- CSS[4]
- C++11[5]
- D (programming language)[6]
- Fortran 2008
- Julia (programming language)[7]
- Swift (programming language)
- Python (programming language)[8]
- Apple's PowerPC Numerics[9]
- MATLAB[10]
- Pascal[11]
- PHP[12]
- Java (programming language) (since version 1.5)[13]
- Kotlin[14]
- Ruby[15]
- Go[16]
- Rust[17]
- JavaScript (since ES2015)[18]
- Some C90 and C++ libraries have provided a hypot function.[19][20][21]
- Scala[22]
See also
- Alpha max plus beta min algorithm, a faster algorithm yielding an approximate result
References
- ↑ "Floating point exception tracking and NAN propagation". 2020-04-27. p. 6. https://www.agner.org/optimize/nan_propagation.pdf#page=6.
- ↑ In some situations, last form reduces calculation errors (in ULPs).
- ↑ Borges, Carlos F. (14 June 2019). "An Improved Algorithm for hypot(a,b)". arXiv:1904.09481 [math.NA].
- ↑ Cimpanu, Catalin. "CSS to get support for trigonometry functions" (in en). https://www.zdnet.com/article/css-to-get-support-for-trigonometry-functions/.
- ↑ http://www.cplusplus.com/reference/cmath/hypot/
- ↑ https://dlang.org/phobos/std_math.html#.hypot
- ↑ https://docs.julialang.org/en/v1/base/math/#Base.Math.hypot
- ↑ https://docs.python.org/3/library/math.html#math.hypot
- ↑ https://developer.apple.com/DOCUMENTATION/mac/PPCNumerics/PPCNumerics-141.html
- ↑ http://nl.mathworks.com/help/matlab/ref/hypot.html
- ↑ http://www.frameworkpascal.com/helphtml/hypot_func.htm
- ↑ http://www.php.net/hypot
- ↑ http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Math.html#hypot(double,%20double)
- ↑ "hypot - Kotlin Programming Language". https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.math/hypot.html.
- ↑ http://ruby-doc.org/core/Math.html#method-c-hypot
- ↑ http://golang.org/pkg/math/#Hypot
- ↑ https://doc.rust-lang.org/std/primitive.f64.html#method.hypot
- ↑ https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/hypot
- ↑ Single Unix Specification, Open Group, http://www.opengroup.org/onlinepubs/007908799/xsh/hypot.html
- ↑ IBM, ILE C/C++ Run-Time Library Functions, http://publib.boulder.ibm.com/infocenter/iadthelp/v7r0/index.jsp?topic=/com.ibm.etools.iseries.langref.doc/rzan5mst144.htm
- ↑ The GNU C Library, Mathematics, http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_17.html
- ↑ https://www.scala-lang.org/api/current/scala/math/index.html#hypot(x:Double,y:Double):Double