3729c8d7069ae84dcc2b79d8fa11d035301b7c6e
[platform/upstream/lapack.git] / SRC / zla_heamv.f
1 *> \brief \b ZLA_HEAMV computes a matrix-vector product using a Hermitian indefinite matrix to calculate error bounds.
2 *
3 *  =========== DOCUMENTATION ===========
4 *
5 * Online html documentation available at 
6 *            http://www.netlib.org/lapack/explore-html/ 
7 *
8 *> \htmlonly
9 *> Download ZLA_HEAMV + dependencies 
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zla_heamv.f"> 
11 *> [TGZ]</a> 
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zla_heamv.f"> 
13 *> [ZIP]</a> 
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zla_heamv.f"> 
15 *> [TXT]</a>
16 *> \endhtmlonly 
17 *
18 *  Definition:
19 *  ===========
20 *
21 *       SUBROUTINE ZLA_HEAMV( UPLO, N, ALPHA, A, LDA, X, INCX, BETA, Y,
22 *                             INCY )
23
24 *       .. Scalar Arguments ..
25 *       DOUBLE PRECISION   ALPHA, BETA
26 *       INTEGER            INCX, INCY, LDA, N, UPLO
27 *       ..
28 *       .. Array Arguments ..
29 *       COMPLEX*16         A( LDA, * ), X( * )
30 *       DOUBLE PRECISION   Y( * )
31 *       ..
32 *  
33 *
34 *> \par Purpose:
35 *  =============
36 *>
37 *> \verbatim
38 *>
39 *> ZLA_SYAMV  performs the matrix-vector operation
40 *>
41 *>         y := alpha*abs(A)*abs(x) + beta*abs(y),
42 *>
43 *> where alpha and beta are scalars, x and y are vectors and A is an
44 *> n by n symmetric matrix.
45 *>
46 *> This function is primarily used in calculating error bounds.
47 *> To protect against underflow during evaluation, components in
48 *> the resulting vector are perturbed away from zero by (N+1)
49 *> times the underflow threshold.  To prevent unnecessarily large
50 *> errors for block-structure embedded in general matrices,
51 *> "symbolically" zero components are not perturbed.  A zero
52 *> entry is considered "symbolic" if all multiplications involved
53 *> in computing that entry have at least one zero multiplicand.
54 *> \endverbatim
55 *
56 *  Arguments:
57 *  ==========
58 *
59 *> \param[in] UPLO
60 *> \verbatim
61 *>          UPLO is INTEGER
62 *>           On entry, UPLO specifies whether the upper or lower
63 *>           triangular part of the array A is to be referenced as
64 *>           follows:
65 *>
66 *>              UPLO = BLAS_UPPER   Only the upper triangular part of A
67 *>                                  is to be referenced.
68 *>
69 *>              UPLO = BLAS_LOWER   Only the lower triangular part of A
70 *>                                  is to be referenced.
71 *>
72 *>           Unchanged on exit.
73 *> \endverbatim
74 *>
75 *> \param[in] N
76 *> \verbatim
77 *>          N is INTEGER
78 *>           On entry, N specifies the number of columns of the matrix A.
79 *>           N must be at least zero.
80 *>           Unchanged on exit.
81 *> \endverbatim
82 *>
83 *> \param[in] ALPHA
84 *> \verbatim
85 *>          ALPHA is DOUBLE PRECISION .
86 *>           On entry, ALPHA specifies the scalar alpha.
87 *>           Unchanged on exit.
88 *> \endverbatim
89 *>
90 *> \param[in] A
91 *> \verbatim
92 *>          A is COMPLEX*16 array, DIMENSION ( LDA, n ).
93 *>           Before entry, the leading m by n part of the array A must
94 *>           contain the matrix of coefficients.
95 *>           Unchanged on exit.
96 *> \endverbatim
97 *>
98 *> \param[in] LDA
99 *> \verbatim
100 *>          LDA is INTEGER
101 *>           On entry, LDA specifies the first dimension of A as declared
102 *>           in the calling (sub) program. LDA must be at least
103 *>           max( 1, n ).
104 *>           Unchanged on exit.
105 *> \endverbatim
106 *>
107 *> \param[in] X
108 *> \verbatim
109 *>          X is COMPLEX*16 array, DIMENSION at least
110 *>           ( 1 + ( n - 1 )*abs( INCX ) )
111 *>           Before entry, the incremented array X must contain the
112 *>           vector x.
113 *>           Unchanged on exit.
114 *> \endverbatim
115 *>
116 *> \param[in] INCX
117 *> \verbatim
118 *>          INCX is INTEGER
119 *>           On entry, INCX specifies the increment for the elements of
120 *>           X. INCX must not be zero.
121 *>           Unchanged on exit.
122 *> \endverbatim
123 *>
124 *> \param[in] BETA
125 *> \verbatim
126 *>          BETA is DOUBLE PRECISION .
127 *>           On entry, BETA specifies the scalar beta. When BETA is
128 *>           supplied as zero then Y need not be set on input.
129 *>           Unchanged on exit.
130 *> \endverbatim
131 *>
132 *> \param[in,out] Y
133 *> \verbatim
134 *>          Y is DOUBLE PRECISION array, dimension
135 *>           ( 1 + ( n - 1 )*abs( INCY ) )
136 *>           Before entry with BETA non-zero, the incremented array Y
137 *>           must contain the vector y. On exit, Y is overwritten by the
138 *>           updated vector y.
139 *> \endverbatim
140 *>
141 *> \param[in] INCY
142 *> \verbatim
143 *>          INCY is INTEGER
144 *>           On entry, INCY specifies the increment for the elements of
145 *>           Y. INCY must not be zero.
146 *>           Unchanged on exit.
147 *> \endverbatim
148 *
149 *  Authors:
150 *  ========
151 *
152 *> \author Univ. of Tennessee 
153 *> \author Univ. of California Berkeley 
154 *> \author Univ. of Colorado Denver 
155 *> \author NAG Ltd. 
156 *
157 *> \date September 2012
158 *
159 *> \ingroup complex16HEcomputational
160 *
161 *> \par Further Details:
162 *  =====================
163 *>
164 *> \verbatim
165 *>
166 *>  Level 2 Blas routine.
167 *>
168 *>  -- Written on 22-October-1986.
169 *>     Jack Dongarra, Argonne National Lab.
170 *>     Jeremy Du Croz, Nag Central Office.
171 *>     Sven Hammarling, Nag Central Office.
172 *>     Richard Hanson, Sandia National Labs.
173 *>  -- Modified for the absolute-value product, April 2006
174 *>     Jason Riedy, UC Berkeley
175 *> \endverbatim
176 *>
177 *  =====================================================================
178       SUBROUTINE ZLA_HEAMV( UPLO, N, ALPHA, A, LDA, X, INCX, BETA, Y,
179      $                      INCY )
180 *
181 *  -- LAPACK computational routine (version 3.4.2) --
182 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
183 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
184 *     September 2012
185 *
186 *     .. Scalar Arguments ..
187       DOUBLE PRECISION   ALPHA, BETA
188       INTEGER            INCX, INCY, LDA, N, UPLO
189 *     ..
190 *     .. Array Arguments ..
191       COMPLEX*16         A( LDA, * ), X( * )
192       DOUBLE PRECISION   Y( * )
193 *     ..
194 *
195 *  =====================================================================
196 *
197 *     .. Parameters ..
198       DOUBLE PRECISION   ONE, ZERO
199       PARAMETER          ( ONE = 1.0D+0, ZERO = 0.0D+0 )
200 *     ..
201 *     .. Local Scalars ..
202       LOGICAL            SYMB_ZERO
203       DOUBLE PRECISION   TEMP, SAFE1
204       INTEGER            I, INFO, IY, J, JX, KX, KY
205       COMPLEX*16         ZDUM
206 *     ..
207 *     .. External Subroutines ..
208       EXTERNAL           XERBLA, DLAMCH
209       DOUBLE PRECISION   DLAMCH
210 *     ..
211 *     .. External Functions ..
212       EXTERNAL           ILAUPLO
213       INTEGER            ILAUPLO
214 *     ..
215 *     .. Intrinsic Functions ..
216       INTRINSIC          MAX, ABS, SIGN, REAL, DIMAG
217 *     ..
218 *     .. Statement Functions ..
219       DOUBLE PRECISION   CABS1
220 *     ..
221 *     .. Statement Function Definitions ..
222       CABS1( ZDUM ) = ABS( DBLE ( ZDUM ) ) + ABS( DIMAG ( ZDUM ) )
223 *     ..
224 *     .. Executable Statements ..
225 *
226 *     Test the input parameters.
227 *
228       INFO = 0
229       IF     ( UPLO.NE.ILAUPLO( 'U' ) .AND.
230      $         UPLO.NE.ILAUPLO( 'L' ) )THEN
231          INFO = 1
232       ELSE IF( N.LT.0 )THEN
233          INFO = 2
234       ELSE IF( LDA.LT.MAX( 1, N ) )THEN
235          INFO = 5
236       ELSE IF( INCX.EQ.0 )THEN
237          INFO = 7
238       ELSE IF( INCY.EQ.0 )THEN
239          INFO = 10
240       END IF
241       IF( INFO.NE.0 )THEN
242          CALL XERBLA( 'ZHEMV ', INFO )
243          RETURN
244       END IF
245 *
246 *     Quick return if possible.
247 *
248       IF( ( N.EQ.0 ).OR.( ( ALPHA.EQ.ZERO ).AND.( BETA.EQ.ONE ) ) )
249      $   RETURN
250 *
251 *     Set up the start points in  X  and  Y.
252 *
253       IF( INCX.GT.0 )THEN
254          KX = 1
255       ELSE
256          KX = 1 - ( N - 1 )*INCX
257       END IF
258       IF( INCY.GT.0 )THEN
259          KY = 1
260       ELSE
261          KY = 1 - ( N - 1 )*INCY
262       END IF
263 *
264 *     Set SAFE1 essentially to be the underflow threshold times the
265 *     number of additions in each row.
266 *
267       SAFE1 = DLAMCH( 'Safe minimum' )
268       SAFE1 = (N+1)*SAFE1
269 *
270 *     Form  y := alpha*abs(A)*abs(x) + beta*abs(y).
271 *
272 *     The O(N^2) SYMB_ZERO tests could be replaced by O(N) queries to
273 *     the inexact flag.  Still doesn't help change the iteration order
274 *     to per-column.
275 *
276       IY = KY
277       IF ( INCX.EQ.1 ) THEN
278          IF ( UPLO .EQ. ILAUPLO( 'U' ) ) THEN
279             DO I = 1, N
280                IF ( BETA .EQ. ZERO ) THEN
281                   SYMB_ZERO = .TRUE.
282                   Y( IY ) = 0.0D+0
283                ELSE IF ( Y( IY ) .EQ. ZERO ) THEN
284                   SYMB_ZERO = .TRUE.
285                ELSE
286                   SYMB_ZERO = .FALSE.
287                   Y( IY ) = BETA * ABS( Y( IY ) )
288                END IF
289                IF ( ALPHA .NE. ZERO ) THEN
290                   DO J = 1, I
291                      TEMP = CABS1( A( J, I ) )
292                      SYMB_ZERO = SYMB_ZERO .AND.
293      $                    ( X( J ) .EQ. ZERO .OR. TEMP .EQ. ZERO )
294
295                      Y( IY ) = Y( IY ) + ALPHA*CABS1( X( J ) )*TEMP
296                   END DO
297                   DO J = I+1, N
298                      TEMP = CABS1( A( I, J ) )
299                      SYMB_ZERO = SYMB_ZERO .AND.
300      $                    ( X( J ) .EQ. ZERO .OR. TEMP .EQ. ZERO )
301
302                      Y( IY ) = Y( IY ) + ALPHA*CABS1( X( J ) )*TEMP
303                   END DO
304                END IF
305
306                IF (.NOT.SYMB_ZERO)
307      $              Y( IY ) = Y( IY ) + SIGN( SAFE1, Y( IY ) )
308
309                IY = IY + INCY
310             END DO
311          ELSE
312             DO I = 1, N
313                IF ( BETA .EQ. ZERO ) THEN
314                   SYMB_ZERO = .TRUE.
315                   Y( IY ) = 0.0D+0
316                ELSE IF ( Y( IY ) .EQ. ZERO ) THEN
317                   SYMB_ZERO = .TRUE.
318                ELSE
319                   SYMB_ZERO = .FALSE.
320                   Y( IY ) = BETA * ABS( Y( IY ) )
321                END IF
322                IF ( ALPHA .NE. ZERO ) THEN
323                   DO J = 1, I
324                      TEMP = CABS1( A( I, J ) )
325                      SYMB_ZERO = SYMB_ZERO .AND.
326      $                    ( X( J ) .EQ. ZERO .OR. TEMP .EQ. ZERO )
327
328                      Y( IY ) = Y( IY ) + ALPHA*CABS1( X( J ) )*TEMP
329                   END DO
330                   DO J = I+1, N
331                      TEMP = CABS1( A( J, I ) )
332                      SYMB_ZERO = SYMB_ZERO .AND.
333      $                    ( X( J ) .EQ. ZERO .OR. TEMP .EQ. ZERO )
334
335                      Y( IY ) = Y( IY ) + ALPHA*CABS1( X( J ) )*TEMP
336                   END DO
337                END IF
338
339                IF (.NOT.SYMB_ZERO)
340      $              Y( IY ) = Y( IY ) + SIGN( SAFE1, Y( IY ) )
341
342                IY = IY + INCY
343             END DO
344          END IF
345       ELSE
346          IF ( UPLO .EQ. ILAUPLO( 'U' ) ) THEN
347             DO I = 1, N
348                IF ( BETA .EQ. ZERO ) THEN
349                   SYMB_ZERO = .TRUE.
350                   Y( IY ) = 0.0D+0
351                ELSE IF ( Y( IY ) .EQ. ZERO ) THEN
352                   SYMB_ZERO = .TRUE.
353                ELSE
354                   SYMB_ZERO = .FALSE.
355                   Y( IY ) = BETA * ABS( Y( IY ) )
356                END IF
357                JX = KX
358                IF ( ALPHA .NE. ZERO ) THEN
359                   DO J = 1, I
360                      TEMP = CABS1( A( J, I ) )
361                      SYMB_ZERO = SYMB_ZERO .AND.
362      $                    ( X( J ) .EQ. ZERO .OR. TEMP .EQ. ZERO )
363
364                      Y( IY ) = Y( IY ) + ALPHA*CABS1( X( JX ) )*TEMP
365                      JX = JX + INCX
366                   END DO
367                   DO J = I+1, N
368                      TEMP = CABS1( A( I, J ) )
369                      SYMB_ZERO = SYMB_ZERO .AND.
370      $                    ( X( J ) .EQ. ZERO .OR. TEMP .EQ. ZERO )
371
372                      Y( IY ) = Y( IY ) + ALPHA*CABS1( X( JX ) )*TEMP
373                      JX = JX + INCX
374                   END DO
375                END IF
376
377                IF ( .NOT.SYMB_ZERO )
378      $              Y( IY ) = Y( IY ) + SIGN( SAFE1, Y( IY ) )
379
380                IY = IY + INCY
381             END DO
382          ELSE
383             DO I = 1, N
384                IF ( BETA .EQ. ZERO ) THEN
385                   SYMB_ZERO = .TRUE.
386                   Y( IY ) = 0.0D+0
387                ELSE IF ( Y( IY ) .EQ. ZERO ) THEN
388                   SYMB_ZERO = .TRUE.
389                ELSE
390                   SYMB_ZERO = .FALSE.
391                   Y( IY ) = BETA * ABS( Y( IY ) )
392                END IF
393                JX = KX
394                IF ( ALPHA .NE. ZERO ) THEN
395                   DO J = 1, I
396                      TEMP = CABS1( A( I, J ) )
397                      SYMB_ZERO = SYMB_ZERO .AND.
398      $                    ( X( J ) .EQ. ZERO .OR. TEMP .EQ. ZERO )
399
400                      Y( IY ) = Y( IY ) + ALPHA*CABS1( X( JX ) )*TEMP
401                      JX = JX + INCX
402                   END DO
403                   DO J = I+1, N
404                      TEMP = CABS1( A( J, I ) )
405                      SYMB_ZERO = SYMB_ZERO .AND.
406      $                    ( X( J ) .EQ. ZERO .OR. TEMP .EQ. ZERO )
407
408                      Y( IY ) = Y( IY ) + ALPHA*CABS1( X( JX ) )*TEMP
409                      JX = JX + INCX
410                   END DO
411                END IF
412
413                IF ( .NOT.SYMB_ZERO )
414      $              Y( IY ) = Y( IY ) + SIGN( SAFE1, Y( IY ) )
415
416                IY = IY + INCY
417             END DO
418          END IF
419
420       END IF
421 *
422       RETURN
423 *
424 *     End of ZLA_HEAMV
425 *
426       END