ENORM Function

public function ENORM(n, x)

Arguments

Type IntentOptional AttributesName
integer :: n
real(kind=dp) :: x(n)

Return Value real(kind=dp)


Contents

Source Code


Source Code

  real(dp) FUNCTION ENORM(n,x)

    !  Given an N-vector X, this function calculates the
    !  Euclidean norm of X.
    !
    !  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. The constants
    !  given here are suitable for every known computer.
    !
    !  The function statement is
    !
    !  real function enorm(n,x)
    !
    !  where
    !
    !  N is a positive integer input variable.
    !
    !  X is an input array of length N.
    !
    !  Argonne National Laboratory. Minpack project. March 1980.
    !  Burton S. Garbow, Kenneth E. Hillstrom, Jorge J. More

    IMPLICIT NONE

    INTEGER n,i

    real(dp) x(n)
    real(dp) agiant,floatn,one,rdwarf,rgiant,s1,s2,s3,xabs, &
         x1max,x3max,zero

    one = 1.0D0
    zero = 0.0D0
    rdwarf = 3.834d-20
    rgiant = 1.304d19

    s1 = zero
    s2 = zero
    s3 = zero
    x1max = zero
    x3max = zero
    floatn = dble(n)
    agiant = rgiant/floatn
    do i = 1, n
       xabs = abs(x(i))
       if ((xabs > rdwarf) .and. (xabs < agiant)) goto 70
       if (xabs <= rdwarf) goto 30

       !  Sum for large components.

       if (xabs <= x1max) goto 10
       s1 = one + s1*(x1max/xabs)**2
       x1max = xabs
       goto 20

10     continue
       s1 = s1 + (xabs/x1max)**2

20     continue
       goto 60

30     continue

       !  Sum for small components.

       if (xabs <= x3max) goto 40
       s3 = one + s3*(x3max/xabs)**2
       x3max = xabs
       goto 50

40     continue
       if (xabs  /=  zero) s3 = s3 + (xabs/x3max)**2

50     continue
60     continue
       goto 80

70     continue

       !  Sum for intermediate components.

       s2 = s2 + xabs**2

80     continue
    end do

    !  Calculation of norm.

    if (s1 == zero) goto 100
    enorm = x1max*sqrt(s1+(s2/x1max)/x1max)
    goto 130

100 continue
    if (s2 == zero) goto 110
    if (s2 >= x3max) &
         enorm = sqrt(s2*(one+(x3max/s2)*(x3max*s3)))
    if (s2 < x3max) &
         enorm = sqrt(x3max*((s2/x3max)+(x3max*s3)))
    goto 120
110 continue
    enorm = x3max*sqrt(s3)

120 continue
130 continue

    return
  end FUNCTION ENORM