!DECK DNRM2 DOUBLE PRECISION FUNCTION DNRM2 (N, DX, INCX) !***BEGIN PROLOGUE DNRM2 !***PURPOSE Compute the Euclidean length (L2 norm) of a vector. !***LIBRARY SLATEC (BLAS) !***CATEGORY D1A3B !***TYPE DOUBLE PRECISION (SNRM2-S, DNRM2-D, SCNRM2-C) !***KEYWORDS BLAS, EUCLIDEAN LENGTH, EUCLIDEAN NORM, L2, ! LINEAR ALGEBRA, UNITARY, VECTOR !***AUTHOR Lawson, C. L., (JPL) ! Hanson, R. J., (SNLA) ! Kincaid, D. R., (U. of Texas) ! Krogh, F. T., (JPL) !***DESCRIPTION ! ! B L A S Subprogram ! Description of parameters ! ! --Input-- ! N number of elements in input vector(s) ! DX double precision vector with N elements ! INCX storage spacing between elements of DX ! ! --Output-- ! DNRM2 double precision result (zero if N .LE. 0) ! ! Euclidean norm of the N-vector stored in DX with storage ! increment INCX. ! If N .LE. 0, return with result = 0. ! If N .GE. 1, then INCX must be .GE. 1 ! ! Four phase method using two built-in constants that are ! hopefully applicable to all machines. ! CUTLO = maximum of SQRT(U/EPS) over all known machines. ! CUTHI = minimum of SQRT(V) over all known machines. ! where ! EPS = smallest no. such that EPS + 1. .GT. 1. ! U = smallest positive no. (underflow limit) ! V = largest no. (overflow limit) ! ! Brief outline of algorithm. ! ! Phase 1 scans zero components. ! move to phase 2 when a component is nonzero and .LE. CUTLO ! move to phase 3 when a component is .GT. CUTLO ! move to phase 4 when a component is .GE. CUTHI/M ! where M = N for X() real and M = 2*N for complex. ! ! Values for CUTLO and CUTHI. ! From the environmental parameters listed in the IMSL converter ! document the limiting values are as follows: ! CUTLO, S.P. U/EPS = 2**(-102) for Honeywell. Close seconds are ! Univac and DEC at 2**(-103) ! Thus CUTLO = 2**(-51) = 4.44089E-16 ! CUTHI, S.P. V = 2**127 for Univac, Honeywell, and DEC. ! Thus CUTHI = 2**(63.5) = 1.30438E19 ! CUTLO, D.P. U/EPS = 2**(-67) for Honeywell and DEC. ! Thus CUTLO = 2**(-33.5) = 8.23181D-11 ! CUTHI, D.P. same as S.P. CUTHI = 1.30438D19 ! DATA CUTLO, CUTHI /8.232D-11, 1.304D19/ ! DATA CUTLO, CUTHI /4.441E-16, 1.304E19/ ! !***REFERENCES C. L. Lawson, R. J. Hanson, D. R. Kincaid and F. T. ! Krogh, Basic linear algebra subprograms for Fortran ! usage, Algorithm No. 539, Transactions on Mathematical ! Software 5, 3 (September 1979), pp. 308-323. !***ROUTINES CALLED (NONE) !***REVISION HISTORY (YYMMDD) ! 791001 DATE WRITTEN ! 890531 Changed all specific intrinsics to generic. (WRB) ! 890831 Modified array declarations. (WRB) ! 890831 REVISION DATE from Version 3.2 ! 891214 Prologue converted to Version 4.0 format. (BAB) ! 920501 Reformatted the REFERENCES section. (WRB) !***END PROLOGUE DNRM2 INTEGER NEXT DOUBLE PRECISION DX(*), CUTLO, CUTHI, HITEST, SUM, XMAX, ZERO, & ONE SAVE CUTLO, CUTHI, ZERO, ONE DATA ZERO, ONE /0.0D0, 1.0D0/ ! DATA CUTLO, CUTHI /8.232D-11, 1.304D19/ !***FIRST EXECUTABLE STATEMENT DNRM2 IF (N .GT. 0) GO TO 10 DNRM2 = ZERO GO TO 300 ! 10 ASSIGN 30 TO NEXT SUM = ZERO NN = N * INCX ! ! BEGIN MAIN LOOP ! I = 1 20 GO TO NEXT,(30, 50, 70, 110) 30 IF (ABS(DX(I)) .GT. CUTLO) GO TO 85 ASSIGN 50 TO NEXT XMAX = ZERO ! ! PHASE 1. SUM IS ZERO ! 50 IF (DX(I) .EQ. ZERO) GO TO 200 IF (ABS(DX(I)) .GT. CUTLO) GO TO 85 ! ! PREPARE FOR PHASE 2. ! ASSIGN 70 TO NEXT GO TO 105 ! ! PREPARE FOR PHASE 4. ! 100 I = J ASSIGN 110 TO NEXT SUM = (SUM / DX(I)) / DX(I) 105 XMAX = ABS(DX(I)) GO TO 115 ! ! PHASE 2. SUM IS SMALL. ! SCALE TO AVOID DESTRUCTIVE UNDERFLOW. ! 70 IF (ABS(DX(I)) .GT. CUTLO) GO TO 75 ! ! COMMON CODE FOR PHASES 2 AND 4. ! IN PHASE 4 SUM IS LARGE. SCALE TO AVOID OVERFLOW. ! 110 IF (ABS(DX(I)) .LE. XMAX) GO TO 115 SUM = ONE + SUM * (XMAX / DX(I))**2 XMAX = ABS(DX(I)) GO TO 200 ! 115 SUM = SUM + (DX(I)/XMAX)**2 GO TO 200 ! ! PREPARE FOR PHASE 3. ! 75 SUM = (SUM * XMAX) * XMAX ! ! FOR REAL OR D.P. SET HITEST = CUTHI/N ! FOR COMPLEX SET HITEST = CUTHI/(2*N) ! 85 HITEST = CUTHI / N ! ! PHASE 3. SUM IS MID-RANGE. NO SCALING. ! DO 95 J = I,NN,INCX IF (ABS(DX(J)) .GE. HITEST) GO TO 100 95 SUM = SUM + DX(J)**2 DNRM2 = SQRT(SUM) GO TO 300 ! 200 CONTINUE I = I + INCX IF (I .LE. NN) GO TO 20 ! ! END OF MAIN LOOP. ! ! COMPUTE SQUARE ROOT AND ADJUST FOR SCALING. ! DNRM2 = XMAX * SQRT(SUM) 300 CONTINUE RETURN END