DOUBLE PRECISION FUNCTION ZLA_PORPVGRW( UPLO, NCOLS, A, LDA, AF,
$ LDAF, WORK )
*
* -- LAPACK routine (version 3.2.2) --
* -- Contributed by James Demmel, Deaglan Halligan, Yozo Hida and --
* -- Jason Riedy of Univ. of California Berkeley. --
* -- June 2010 --
*
* -- LAPACK is a software package provided by Univ. of Tennessee, --
* -- Univ. of California Berkeley and NAG Ltd. --
*
IMPLICIT NONE
* ..
* .. Scalar Arguments ..
CHARACTER*1 UPLO
INTEGER NCOLS, LDA, LDAF
* ..
* .. Array Arguments ..
COMPLEX*16 A( LDA, * ), AF( LDAF, * )
DOUBLE PRECISION WORK( * )
* ..
*
* Purpose
* =======
*
* ZLA_PORPVGRW computes the reciprocal pivot growth factor
* norm(A)/norm(U). The "max absolute element" norm is used. If this is
* much less than 1, the stability of the LU factorization of the
* (equilibrated) matrix A could be poor. This also means that the
* solution X, estimated condition numbers, and error bounds could be
* unreliable.
*
* Arguments
* =========
*
* UPLO (input) CHARACTER*1
* = 'U': Upper triangle of A is stored;
* = 'L': Lower triangle of A is stored.
*
* NCOLS (input) INTEGER
* The number of columns of the matrix A. NCOLS >= 0.
*
* A (input) COMPLEX*16 array, dimension (LDA,N)
* On entry, the N-by-N matrix A.
*
* LDA (input) INTEGER
* The leading dimension of the array A. LDA >= max(1,N).
*
* AF (input) COMPLEX*16 array, dimension (LDAF,N)
* The triangular factor U or L from the Cholesky factorization
* A = U**T*U or A = L*L**T, as computed by ZPOTRF.
*
* LDAF (input) INTEGER
* The leading dimension of the array AF. LDAF >= max(1,N).
*
* WORK (input) COMPLEX*16 array, dimension (2*N)
*
* =====================================================================
*
* .. Local Scalars ..
INTEGER I, J
DOUBLE PRECISION AMAX, UMAX, RPVGRW
LOGICAL UPPER
COMPLEX*16 ZDUM
* ..
* .. External Functions ..
EXTERNAL LSAME, ZLASET
LOGICAL LSAME
* ..
* .. Intrinsic Functions ..
INTRINSIC ABS, MAX, MIN, REAL, DIMAG
* ..
* .. Statement Functions ..
DOUBLE PRECISION CABS1
* ..
* .. Statement Function Definitions ..
CABS1( ZDUM ) = ABS( DBLE( ZDUM ) ) + ABS( DIMAG( ZDUM ) )
* ..
* .. Executable Statements ..
UPPER = LSAME( 'Upper', UPLO )
*
* DPOTRF will have factored only the NCOLSxNCOLS leading minor, so
* we restrict the growth search to that minor and use only the first
* 2*NCOLS workspace entries.
*
RPVGRW = 1.0D+0
DO I = 1, 2*NCOLS
WORK( I ) = 0.0D+0
END DO
*
* Find the max magnitude entry of each column.
*
IF ( UPPER ) THEN
DO J = 1, NCOLS
DO I = 1, J
WORK( NCOLS+J ) =
$ MAX( CABS1( A( I, J ) ), WORK( NCOLS+J ) )
END DO
END DO
ELSE
DO J = 1, NCOLS
DO I = J, NCOLS
WORK( NCOLS+J ) =
$ MAX( CABS1( A( I, J ) ), WORK( NCOLS+J ) )
END DO
END DO
END IF
*
* Now find the max magnitude entry of each column of the factor in
* AF. No pivoting, so no permutations.
*
IF ( LSAME( 'Upper', UPLO ) ) THEN
DO J = 1, NCOLS
DO I = 1, J
WORK( J ) = MAX( CABS1( AF( I, J ) ), WORK( J ) )
END DO
END DO
ELSE
DO J = 1, NCOLS
DO I = J, NCOLS
WORK( J ) = MAX( CABS1( AF( I, J ) ), WORK( J ) )
END DO
END DO
END IF
*
* Compute the *inverse* of the max element growth factor. Dividing
* by zero would imply the largest entry of the factor's column is
* zero. Than can happen when either the column of A is zero or
* massive pivots made the factor underflow to zero. Neither counts
* as growth in itself, so simply ignore terms with zero
* denominators.
*
IF ( LSAME( 'Upper', UPLO ) ) THEN
DO I = 1, NCOLS
UMAX = WORK( I )
AMAX = WORK( NCOLS+I )
IF ( UMAX /= 0.0D+0 ) THEN
RPVGRW = MIN( AMAX / UMAX, RPVGRW )
END IF
END DO
ELSE
DO I = 1, NCOLS
UMAX = WORK( I )
AMAX = WORK( NCOLS+I )
IF ( UMAX /= 0.0D+0 ) THEN
RPVGRW = MIN( AMAX / UMAX, RPVGRW )
END IF
END DO
END IF
ZLA_PORPVGRW = RPVGRW
END