1 *> \brief \b CLA_GEAMV computes a matrix-vector product using a general matrix to calculate error bounds.
3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download CLA_GEAMV + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cla_geamv.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cla_geamv.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cla_geamv.f">
21 * SUBROUTINE CLA_GEAMV ( TRANS, M, N, ALPHA, A, LDA, X, INCX, BETA,
24 * .. Scalar Arguments ..
26 * INTEGER INCX, INCY, LDA, M, N
29 * .. Array Arguments ..
30 * COMPLEX A( LDA, * ), X( * )
40 *> CLA_GEAMV performs one of the matrix-vector operations
42 *> y := alpha*abs(A)*abs(x) + beta*abs(y),
43 *> or y := alpha*abs(A)**T*abs(x) + beta*abs(y),
45 *> where alpha and beta are scalars, x and y are vectors and A is an
48 *> This function is primarily used in calculating error bounds.
49 *> To protect against underflow during evaluation, components in
50 *> the resulting vector are perturbed away from zero by (N+1)
51 *> times the underflow threshold. To prevent unnecessarily large
52 *> errors for block-structure embedded in general matrices,
53 *> "symbolically" zero components are not perturbed. A zero
54 *> entry is considered "symbolic" if all multiplications involved
55 *> in computing that entry have at least one zero multiplicand.
64 *> On entry, TRANS specifies the operation to be performed as
67 *> BLAS_NO_TRANS y := alpha*abs(A)*abs(x) + beta*abs(y)
68 *> BLAS_TRANS y := alpha*abs(A**T)*abs(x) + beta*abs(y)
69 *> BLAS_CONJ_TRANS y := alpha*abs(A**T)*abs(x) + beta*abs(y)
77 *> On entry, M specifies the number of rows of the matrix A.
78 *> M must be at least zero.
85 *> On entry, N specifies the number of columns of the matrix A.
86 *> N must be at least zero.
93 *> On entry, ALPHA specifies the scalar alpha.
99 *> A is COMPLEX array, dimension (LDA,n)
100 *> Before entry, the leading m by n part of the array A must
101 *> contain the matrix of coefficients.
102 *> Unchanged on exit.
108 *> On entry, LDA specifies the first dimension of A as declared
109 *> in the calling (sub) program. LDA must be at least
111 *> Unchanged on exit.
116 *> X is COMPLEX array, dimension
117 *> ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n'
119 *> ( 1 + ( m - 1 )*abs( INCX ) ) otherwise.
120 *> Before entry, the incremented array X must contain the
122 *> Unchanged on exit.
128 *> On entry, INCX specifies the increment for the elements of
129 *> X. INCX must not be zero.
130 *> Unchanged on exit.
136 *> On entry, BETA specifies the scalar beta. When BETA is
137 *> supplied as zero then Y need not be set on input.
138 *> Unchanged on exit.
143 *> Y is REAL array, dimension
144 *> ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n'
146 *> ( 1 + ( n - 1 )*abs( INCY ) ) otherwise.
147 *> Before entry with BETA non-zero, the incremented array Y
148 *> must contain the vector y. On exit, Y is overwritten by the
155 *> On entry, INCY specifies the increment for the elements of
156 *> Y. INCY must not be zero.
157 *> Unchanged on exit.
159 *> Level 2 Blas routine.
165 *> \author Univ. of Tennessee
166 *> \author Univ. of California Berkeley
167 *> \author Univ. of Colorado Denver
170 *> \date September 2012
172 *> \ingroup complexGEcomputational
174 * =====================================================================
175 SUBROUTINE CLA_GEAMV ( TRANS, M, N, ALPHA, A, LDA, X, INCX, BETA,
178 * -- LAPACK computational routine (version 3.4.2) --
179 * -- LAPACK is a software package provided by Univ. of Tennessee, --
180 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
183 * .. Scalar Arguments ..
185 INTEGER INCX, INCY, LDA, M, N
188 * .. Array Arguments ..
189 COMPLEX A( LDA, * ), X( * )
193 * =====================================================================
197 PARAMETER ( ONE = 1.0E+0, ZERO = 0.0E+0 )
199 * .. Local Scalars ..
202 INTEGER I, INFO, IY, J, JX, KX, KY, LENX, LENY
205 * .. External Subroutines ..
206 EXTERNAL XERBLA, SLAMCH
209 * .. External Functions ..
213 * .. Intrinsic Functions ..
214 INTRINSIC MAX, ABS, REAL, AIMAG, SIGN
216 * .. Statement Functions ..
219 * .. Statement Function Definitions ..
220 CABS1( CDUM ) = ABS( REAL( CDUM ) ) + ABS( AIMAG( CDUM ) )
222 * .. Executable Statements ..
224 * Test the input parameters.
227 IF ( .NOT.( ( TRANS.EQ.ILATRANS( 'N' ) )
228 $ .OR. ( TRANS.EQ.ILATRANS( 'T' ) )
229 $ .OR. ( TRANS.EQ.ILATRANS( 'C' ) ) ) ) THEN
231 ELSE IF( M.LT.0 )THEN
233 ELSE IF( N.LT.0 )THEN
235 ELSE IF( LDA.LT.MAX( 1, M ) )THEN
237 ELSE IF( INCX.EQ.0 )THEN
239 ELSE IF( INCY.EQ.0 )THEN
243 CALL XERBLA( 'CLA_GEAMV ', INFO )
247 * Quick return if possible.
249 IF( ( M.EQ.0 ).OR.( N.EQ.0 ).OR.
250 $ ( ( ALPHA.EQ.ZERO ).AND.( BETA.EQ.ONE ) ) )
253 * Set LENX and LENY, the lengths of the vectors x and y, and set
254 * up the start points in X and Y.
256 IF( TRANS.EQ.ILATRANS( 'N' ) )THEN
266 KX = 1 - ( LENX - 1 )*INCX
271 KY = 1 - ( LENY - 1 )*INCY
274 * Set SAFE1 essentially to be the underflow threshold times the
275 * number of additions in each row.
277 SAFE1 = SLAMCH( 'Safe minimum' )
280 * Form y := alpha*abs(A)*abs(x) + beta*abs(y).
282 * The O(M*N) SYMB_ZERO tests could be replaced by O(N) queries to
283 * the inexact flag. Still doesn't help change the iteration order
287 IF ( INCX.EQ.1 ) THEN
288 IF( TRANS.EQ.ILATRANS( 'N' ) )THEN
290 IF ( BETA .EQ. 0.0 ) THEN
293 ELSE IF ( Y( IY ) .EQ. 0.0 ) THEN
297 Y( IY ) = BETA * ABS( Y( IY ) )
299 IF ( ALPHA .NE. 0.0 ) THEN
301 TEMP = CABS1( A( I, J ) )
302 SYMB_ZERO = SYMB_ZERO .AND.
303 $ ( X( J ) .EQ. ZERO .OR. TEMP .EQ. ZERO )
305 Y( IY ) = Y( IY ) + ALPHA*CABS1( X( J ) )*TEMP
309 IF ( .NOT.SYMB_ZERO ) Y( IY ) =
310 $ Y( IY ) + SIGN( SAFE1, Y( IY ) )
316 IF ( BETA .EQ. 0.0 ) THEN
319 ELSE IF ( Y( IY ) .EQ. 0.0 ) THEN
323 Y( IY ) = BETA * ABS( Y( IY ) )
325 IF ( ALPHA .NE. 0.0 ) THEN
327 TEMP = CABS1( A( J, I ) )
328 SYMB_ZERO = SYMB_ZERO .AND.
329 $ ( X( J ) .EQ. ZERO .OR. TEMP .EQ. ZERO )
331 Y( IY ) = Y( IY ) + ALPHA*CABS1( X( J ) )*TEMP
335 IF ( .NOT.SYMB_ZERO ) Y( IY ) =
336 $ Y( IY ) + SIGN( SAFE1, Y( IY ) )
342 IF( TRANS.EQ.ILATRANS( 'N' ) )THEN
344 IF ( BETA .EQ. 0.0 ) THEN
347 ELSE IF ( Y( IY ) .EQ. 0.0 ) THEN
351 Y( IY ) = BETA * ABS( Y( IY ) )
353 IF ( ALPHA .NE. 0.0 ) THEN
356 TEMP = CABS1( A( I, J ) )
357 SYMB_ZERO = SYMB_ZERO .AND.
358 $ ( X( JX ) .EQ. ZERO .OR. TEMP .EQ. ZERO )
360 Y( IY ) = Y( IY ) + ALPHA*CABS1( X( JX ) )*TEMP
365 IF ( .NOT.SYMB_ZERO ) Y( IY ) =
366 $ Y( IY ) + SIGN( SAFE1, Y( IY ) )
372 IF ( BETA .EQ. 0.0 ) THEN
375 ELSE IF ( Y( IY ) .EQ. 0.0 ) THEN
379 Y( IY ) = BETA * ABS( Y( IY ) )
381 IF ( ALPHA .NE. 0.0 ) THEN
384 TEMP = CABS1( A( J, I ) )
385 SYMB_ZERO = SYMB_ZERO .AND.
386 $ ( X( JX ) .EQ. ZERO .OR. TEMP .EQ. ZERO )
388 Y( IY ) = Y( IY ) + ALPHA*CABS1( X( JX ) )*TEMP
393 IF ( .NOT.SYMB_ZERO ) Y( IY ) =
394 $ Y( IY ) + SIGN( SAFE1, Y( IY ) )