SUBROUTINE CLASSQ( N, X, INCX, SCL, SUMSQ ) ! ! -- LAPACK auxiliary routine (version 2.0) -- ! Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., ! Courant Institute, Argonne National Lab, and Rice University ! October 31, 1992 ! 10-15-99: New version based on LAWN 126 (eca) ! ! .. Scalar Arguments .. INTEGER INCX, N REAL SCL, SUMSQ ! .. ! .. Array Arguments .. COMPLEX X( * ) ! .. ! ! Purpose ! ======= ! ! CLASSQ returns the values scl and ssq such that ! ! ( scl**2 )*ssq = x( 1 )**2 +...+ x( n )**2 + ( scale**2 )*sumsq, ! ! where x( i ) = abs( X( 1 + ( i - 1 )*INCX ) ). The value of sumsq is ! assumed to be non-negative and scl returns the value ! ! scl = max( scale, abs( real( x( i ) ) ), abs( aimag( x( i ) ) ) ), ! i ! ! scale and sumsq must be supplied in SCL and SUMSQ respectively. ! SCL and SUMSQ are overwritten by scl and ssq respectively. ! ! Arguments ! ========= ! ! N (input) INTEGER ! The number of elements to be used from the vector X. ! ! X (input) COMPLEX array, dimension (N) ! The vector x as described above. ! x( i ) = X( 1 + ( i - 1 )*INCX ), 1 <= i <= n. ! ! INCX (input) INTEGER ! The increment between successive values of the vector X. ! INCX > 0. ! ! SCL (input/output) REAL ! On entry, the value scale in the equation above. ! On exit, SCALE is overwritten with the value scl . ! ! SUMSQ (input/output) REAL ! On entry, the value sumsq in the equation above. ! On exit, SUMSQ is overwritten with the value ssq . ! ! ===================================================================== ! INTEGER I, IX, IX2 REAL CUTHI, CUTLO, HITEST, SMAX, SQMAX INTRINSIC ABS, MAX, REAL DATA CUTLO / 1.00104154759155046E-146 / DATA CUTHI / 9.48075190810917589E+153 / IF( N.LE.0 ) RETURN HITEST = CUTHI / REAL( 2*N+1 ) IF( SUMSQ.EQ.0.0 ) SCL = 1.0 IF( INCX.EQ.1 ) THEN ! ! Pass through once to find the maximum value in X. ! SMAX = 0.0 DO I = 1, N SMAX = MAX( SMAX, ABS(REAL(X(I))), ABS(AIMAG(X(I))) ) END DO SQMAX = MAX( SQRT( SUMSQ ), SMAX ) ! IF( SCL.EQ.1.0 .AND. SQMAX.GT.CUTLO .AND. SQMAX.LT.HITEST ) & THEN ! ! If SCL = 1.0 and SQMAX is greater than CUTLO and less than ! HITEST, no scaling should be needed. ! DO I = 1, N SUMSQ = SUMSQ + REAL(X(I))**2 + AIMAG(X(I))**2 END DO ELSE IF( SMAX.GT.0.0 ) THEN ! ! Scale by SQMAX if SCL = 1.0, otherwise scale by ! max( SQMAX, SCL ). ! IF( SCL.EQ.1.0 .OR. SCL.LT.SQMAX ) THEN SUMSQ = ( SUMSQ*( SCL / SQMAX ) )*( SCL / SQMAX ) SCL = SQMAX END IF ! ! Add the sum of squares of values of X scaled by SCL. ! DO I = 1, N SUMSQ = SUMSQ + ( REAL(X(I)) / SCL )**2 + & ( AIMAG(X(I)) / SCL )**2 END DO END IF ELSE ! ! Pass through once to find the maximum value in X. ! SMAX = 0.0 IX = 1 IF( INCX.LT.0 ) IX = 1 - (N-1)*INCX DO I = 1, N SMAX = MAX( SMAX, ABS(REAL(X(IX))), ABS(AIMAG(X(IX))) ) IX = IX + INCX END DO SQMAX = MAX( SQRT( SUMSQ ), SMAX ) ! IF( SCL.EQ.1.0 .AND. SQMAX.GT.CUTLO .AND. SQMAX.LT.HITEST ) & THEN ! ! If SCL = 1.0 and SQMAX is greater than CUTLO and less than ! HITEST, no scaling should be needed. ! IX = 1 IF( INCX.LT.0 ) IX = 1 - (N-1)*INCX DO I = 1, N SUMSQ = SUMSQ + REAL(X(IX))**2 + AIMAG(X(IX))**2 IX = IX + INCX END DO ELSE IF( SMAX.GT.0.0 ) THEN ! ! Scale by SQMAX if SCL = 1.0, otherwise scale by ! max( SQMAX, SCL ). ! IF( SCL.EQ.1.0 .OR. SCL.LT.SQMAX ) THEN SUMSQ = ( SUMSQ*( SCL / SQMAX ) )*( SCL / SQMAX ) SCL = SQMAX END IF ! ! Add the sum of squares of values of X scaled by SCL. ! IX = 1 IF( INCX.LT.0 ) IX = 1 - (N-1)*INCX DO I = 1, N SUMSQ = SUMSQ + ( REAL(X(IX)) / SCL )**2 + & ( AIMAG(X(IX)) / SCL )**2 IX = IX + INCX END DO END IF END IF RETURN END