1*> \brief \b ZPOEQUB
2*
3*  =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6*            http://www.netlib.org/lapack/explore-html/
7*
8*> \htmlonly
9*> Download ZPOEQUB + dependencies
10*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zpoequb.f">
11*> [TGZ]</a>
12*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zpoequb.f">
13*> [ZIP]</a>
14*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zpoequb.f">
15*> [TXT]</a>
16*> \endhtmlonly
17*
18*  Definition:
19*  ===========
20*
21*       SUBROUTINE ZPOEQUB( N, A, LDA, S, SCOND, AMAX, INFO )
22*
23*       .. Scalar Arguments ..
24*       INTEGER            INFO, LDA, N
25*       DOUBLE PRECISION   AMAX, SCOND
26*       ..
27*       .. Array Arguments ..
28*       COMPLEX*16         A( LDA, * )
29*       DOUBLE PRECISION   S( * )
30*       ..
31*
32*
33*> \par Purpose:
34*  =============
35*>
36*> \verbatim
37*>
38*> ZPOEQUB computes row and column scalings intended to equilibrate a
39*> Hermitian positive definite matrix A and reduce its condition number
40*> (with respect to the two-norm).  S contains the scale factors,
41*> S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
42*> elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This
43*> choice of S puts the condition number of B within a factor N of the
44*> smallest possible condition number over all possible diagonal
45*> scalings.
46*>
47*> This routine differs from ZPOEQU by restricting the scaling factors
48*> to a power of the radix.  Barring over- and underflow, scaling by
49*> these factors introduces no additional rounding errors.  However, the
50*> scaled diagonal entries are no longer approximately 1 but lie
51*> between sqrt(radix) and 1/sqrt(radix).
52*> \endverbatim
53*
54*  Arguments:
55*  ==========
56*
57*> \param[in] N
58*> \verbatim
59*>          N is INTEGER
60*>          The order of the matrix A.  N >= 0.
61*> \endverbatim
62*>
63*> \param[in] A
64*> \verbatim
65*>          A is COMPLEX*16 array, dimension (LDA,N)
66*>          The N-by-N Hermitian positive definite matrix whose scaling
67*>          factors are to be computed.  Only the diagonal elements of A
68*>          are referenced.
69*> \endverbatim
70*>
71*> \param[in] LDA
72*> \verbatim
73*>          LDA is INTEGER
74*>          The leading dimension of the array A.  LDA >= max(1,N).
75*> \endverbatim
76*>
77*> \param[out] S
78*> \verbatim
79*>          S is DOUBLE PRECISION array, dimension (N)
80*>          If INFO = 0, S contains the scale factors for A.
81*> \endverbatim
82*>
83*> \param[out] SCOND
84*> \verbatim
85*>          SCOND is DOUBLE PRECISION
86*>          If INFO = 0, S contains the ratio of the smallest S(i) to
87*>          the largest S(i).  If SCOND >= 0.1 and AMAX is neither too
88*>          large nor too small, it is not worth scaling by S.
89*> \endverbatim
90*>
91*> \param[out] AMAX
92*> \verbatim
93*>          AMAX is DOUBLE PRECISION
94*>          Absolute value of largest matrix element.  If AMAX is very
95*>          close to overflow or very close to underflow, the matrix
96*>          should be scaled.
97*> \endverbatim
98*>
99*> \param[out] INFO
100*> \verbatim
101*>          INFO is INTEGER
102*>          = 0:  successful exit
103*>          < 0:  if INFO = -i, the i-th argument had an illegal value
104*>          > 0:  if INFO = i, the i-th diagonal element is nonpositive.
105*> \endverbatim
106*
107*  Authors:
108*  ========
109*
110*> \author Univ. of Tennessee
111*> \author Univ. of California Berkeley
112*> \author Univ. of Colorado Denver
113*> \author NAG Ltd.
114*
115*> \ingroup complex16POcomputational
116*
117*  =====================================================================
118      SUBROUTINE ZPOEQUB( N, A, LDA, S, SCOND, AMAX, INFO )
119*
120*  -- LAPACK computational routine --
121*  -- LAPACK is a software package provided by Univ. of Tennessee,    --
122*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
123*
124*     .. Scalar Arguments ..
125      INTEGER            INFO, LDA, N
126      DOUBLE PRECISION   AMAX, SCOND
127*     ..
128*     .. Array Arguments ..
129      COMPLEX*16         A( LDA, * )
130      DOUBLE PRECISION   S( * )
131*     ..
132*
133*  =====================================================================
134*
135*     .. Parameters ..
136      DOUBLE PRECISION   ZERO, ONE
137      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
138*     ..
139*     .. Local Scalars ..
140      INTEGER            I
141      DOUBLE PRECISION   SMIN, BASE, TMP
142*     ..
143*     .. External Functions ..
144      DOUBLE PRECISION   DLAMCH
145      EXTERNAL           DLAMCH
146*     ..
147*     .. External Subroutines ..
148      EXTERNAL           XERBLA
149*     ..
150*     .. Intrinsic Functions ..
151      INTRINSIC          MAX, MIN, SQRT, LOG, INT, REAL, DIMAG
152*     ..
153*     .. Executable Statements ..
154*
155*     Test the input parameters.
156*
157*     Positive definite only performs 1 pass of equilibration.
158*
159      INFO = 0
160      IF( N.LT.0 ) THEN
161         INFO = -1
162      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
163         INFO = -3
164      END IF
165      IF( INFO.NE.0 ) THEN
166         CALL XERBLA( 'ZPOEQUB', -INFO )
167         RETURN
168      END IF
169*
170*     Quick return if possible.
171*
172      IF( N.EQ.0 ) THEN
173         SCOND = ONE
174         AMAX = ZERO
175         RETURN
176      END IF
177
178      BASE = DLAMCH( 'B' )
179      TMP = -0.5D+0 / LOG ( BASE )
180*
181*     Find the minimum and maximum diagonal elements.
182*
183      S( 1 ) = DBLE( A( 1, 1 ) )
184      SMIN = S( 1 )
185      AMAX = S( 1 )
186      DO 10 I = 2, N
187         S( I ) = DBLE( A( I, I ) )
188         SMIN = MIN( SMIN, S( I ) )
189         AMAX = MAX( AMAX, S( I ) )
190   10 CONTINUE
191*
192      IF( SMIN.LE.ZERO ) THEN
193*
194*        Find the first non-positive diagonal element and return.
195*
196         DO 20 I = 1, N
197            IF( S( I ).LE.ZERO ) THEN
198               INFO = I
199               RETURN
200            END IF
201   20    CONTINUE
202      ELSE
203*
204*        Set the scale factors to the reciprocals
205*        of the diagonal elements.
206*
207         DO 30 I = 1, N
208            S( I ) = BASE ** INT( TMP * LOG( S( I ) ) )
209   30    CONTINUE
210*
211*        Compute SCOND = min(S(I)) / max(S(I)).
212*
213         SCOND = SQRT( SMIN ) / SQRT( AMAX )
214      END IF
215*
216      RETURN
217*
218*     End of ZPOEQUB
219*
220      END
221