Safe wrapper for the arithmetic-geometric mean (AGM) computation.
This function performs lightweight AGM computation with input validation, automatic ordering. Unlike the type-bound subroutine compute_real64 instead, this function does not retain intermediate calculation results, so they cannot be referenced later.
Note
x and y had opposite signs (x * y .lt. 0): returns NaNx or y is zero (x * y .eq. 0): returns 0| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| real(kind=real64), | intent(in) | :: | x | |||
| real(kind=real64), | intent(in) | :: | y |
| Type | Visibility | Attributes | Name | Initial | |||
|---|---|---|---|---|---|---|---|
| real(kind=real64), | private | :: | xy |
x * y |
elemental function arithmetic_geometric_mean_real64(x, y) result(agm) !! Safe wrapper for the arithmetic-geometric mean (AGM) computation. !! !! This function performs lightweight AGM computation !! with input validation, automatic ordering. !! Unlike the type-bound subroutine [[compute_real64]] instead, !! this function does not retain intermediate calculation results, !! so they cannot be referenced later. !! !! @note !! - If either input was NaN: returns NaN !! - If `x` and `y` had opposite signs (`x * y .lt. 0`): returns NaN !! - If either `x` or `y` is zero (`x * y .eq. 0`): returns 0 !! - Otherwise: computes AGM using the iterative kernel !! @endnote real(real64), intent(in) :: x, y real(real64) :: agm ! return value real(real64) :: xy !! x * y if ( ieee_unordered(x, y) ) then agm = ieee_value(agm, ieee_quiet_nan); return end if xy = x * y if ( xy .lt. 0.0_real64 ) then agm = ieee_value(agm, ieee_quiet_nan) else if ( xy .gt. 0.0_real64 ) then if (x .lt. y) then agm = arithmetic_geometric_mean_kernel( a = y, g = x ) else agm = arithmetic_geometric_mean_kernel( a = x, g = y ) end if else agm = 0.0_real64 end if end function arithmetic_geometric_mean_real64