ENORM2 computes the Euclidean norm of a vector.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer(kind=4) | :: | n | ||||
real(kind=8) | :: | x(n) |
function enorm2 ( n, x ) !*****************************************************************************80 ! !! ENORM2 computes the Euclidean norm of a vector. ! ! Discussion: ! ! This routine was named ENORM. It has been renamed "ENORM2", ! and a simplified routine has been substituted. ! ! The Euclidean norm is computed by accumulating the sum of ! squares in three different sums. The sums of squares for the ! small and large components are scaled so that no overflows ! occur. Non-destructive underflows are permitted. Underflows ! and overflows do not occur in the computation of the unscaled ! sum of squares for the intermediate components. ! ! The definitions of small, intermediate and large components ! depend on two constants, RDWARF and RGIANT. The main ! restrictions on these constants are that RDWARF^2 not ! underflow and RGIANT^2 not overflow. ! ! Licensing: ! ! This code may freely be copied, modified, and used for any purpose. ! ! Modified: ! ! 06 April 2010 ! ! Author: ! ! Original FORTRAN77 version by Jorge More, Burton Garbow, Kenneth Hillstrom. ! FORTRAN90 version by John Burkardt. ! ! Reference: ! ! Jorge More, Burton Garbow, Kenneth Hillstrom, ! User Guide for MINPACK-1 ! Argonne National Laboratory, ! Argonne, Illinois. ! ! Parameters: ! ! Input, integer ( kind = 4 ) N, is the length of the vector. ! ! Input, real ( kind = 8 ) X(N), the vector whose norm is desired. ! ! Output, real ( kind = 8 ) ENORM2, the Euclidean norm of the vector. ! implicit none integer ( kind = 4 ) n real ( kind = 8 ) agiant real ( kind = 8 ) enorm2 integer ( kind = 4 ) i real ( kind = 8 ) rdwarf real ( kind = 8 ) rgiant real ( kind = 8 ) s1 real ( kind = 8 ) s2 real ( kind = 8 ) s3 real ( kind = 8 ) x(n) real ( kind = 8 ) xabs real ( kind = 8 ) x1max real ( kind = 8 ) x3max rdwarf = sqrt ( tiny ( rdwarf ) ) rgiant = sqrt ( huge ( rgiant ) ) s1 = 0.0D+00 s2 = 0.0D+00 s3 = 0.0D+00 x1max = 0.0D+00 x3max = 0.0D+00 agiant = rgiant / real ( n, kind = 8 ) do i = 1, n xabs = abs ( x(i) ) if ( xabs <= rdwarf ) then if ( x3max < xabs ) then s3 = 1.0D+00 + s3 * ( x3max / xabs ) ** 2 x3max = xabs else if ( xabs /= 0.0D+00 ) then s3 = s3 + ( xabs / x3max ) ** 2 end if else if ( agiant <= xabs ) then if ( x1max < xabs ) then s1 = 1.0D+00 + s1 * ( x1max / xabs ) ** 2 x1max = xabs else s1 = s1 + ( xabs / x1max ) ** 2 end if else s2 = s2 + xabs ** 2 end if end do ! ! Calculation of norm. ! if ( s1 /= 0.0D+00 ) then enorm2 = x1max * sqrt ( s1 + ( s2 / x1max ) / x1max ) else if ( s2 /= 0.0D+00 ) then if ( x3max <= s2 ) then enorm2 = sqrt ( s2 * ( 1.0D+00 + ( x3max / s2 ) * ( x3max * s3 ) ) ) else enorm2 = sqrt ( x3max * ( ( s2 / x3max ) + ( x3max * s3 ) ) ) end if else enorm2 = x3max * sqrt ( s3 ) end if return endfunction enorm2