1 *> \brief \b DLA_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 DLA_GEAMV + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dla_geamv.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dla_geamv.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dla_geamv.f">
21 * SUBROUTINE DLA_GEAMV ( TRANS, M, N, ALPHA, A, LDA, X, INCX, BETA,
24 * .. Scalar Arguments ..
25 * DOUBLE PRECISION ALPHA, BETA
26 * INTEGER INCX, INCY, LDA, M, N, TRANS
28 * .. Array Arguments ..
29 * DOUBLE PRECISION A( LDA, * ), X( * ), Y( * )
38 *> DLA_GEAMV performs one of the matrix-vector operations
40 *> y := alpha*abs(A)*abs(x) + beta*abs(y),
41 *> or y := alpha*abs(A)**T*abs(x) + beta*abs(y),
43 *> where alpha and beta are scalars, x and y are vectors and A is an
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.
62 *> On entry, TRANS specifies the operation to be performed as
65 *> BLAS_NO_TRANS y := alpha*abs(A)*abs(x) + beta*abs(y)
66 *> BLAS_TRANS y := alpha*abs(A**T)*abs(x) + beta*abs(y)
67 *> BLAS_CONJ_TRANS y := alpha*abs(A**T)*abs(x) + beta*abs(y)
75 *> On entry, M specifies the number of rows of the matrix A.
76 *> M must be at least zero.
83 *> On entry, N specifies the number of columns of the matrix A.
84 *> N must be at least zero.
90 *> ALPHA is DOUBLE PRECISION
91 *> On entry, ALPHA specifies the scalar alpha.
97 *> A is DOUBLE PRECISION array of DIMENSION ( LDA, n )
98 *> Before entry, the leading m by n part of the array A must
99 *> contain the matrix of coefficients.
100 *> Unchanged on exit.
106 *> On entry, LDA specifies the first dimension of A as declared
107 *> in the calling (sub) program. LDA must be at least
109 *> Unchanged on exit.
114 *> X is DOUBLE PRECISION array, dimension
115 *> ( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n'
117 *> ( 1 + ( m - 1 )*abs( INCX ) ) otherwise.
118 *> Before entry, the incremented array X must contain the
120 *> Unchanged on exit.
126 *> On entry, INCX specifies the increment for the elements of
127 *> X. INCX must not be zero.
128 *> Unchanged on exit.
133 *> BETA is DOUBLE PRECISION
134 *> On entry, BETA specifies the scalar beta. When BETA is
135 *> supplied as zero then Y need not be set on input.
136 *> Unchanged on exit.
141 *> Y is DOUBLE PRECISION
142 *> Array of DIMENSION at least
143 *> ( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n'
145 *> ( 1 + ( n - 1 )*abs( INCY ) ) otherwise.
146 *> Before entry with BETA non-zero, the incremented array Y
147 *> must contain the vector y. On exit, Y is overwritten by the
154 *> On entry, INCY specifies the increment for the elements of
155 *> Y. INCY must not be zero.
156 *> Unchanged on exit.
158 *> Level 2 Blas routine.
164 *> \author Univ. of Tennessee
165 *> \author Univ. of California Berkeley
166 *> \author Univ. of Colorado Denver
169 *> \date September 2012
171 *> \ingroup doubleGEcomputational
173 * =====================================================================
174 SUBROUTINE DLA_GEAMV ( TRANS, M, N, ALPHA, A, LDA, X, INCX, BETA,
177 * -- LAPACK computational routine (version 3.4.2) --
178 * -- LAPACK is a software package provided by Univ. of Tennessee, --
179 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
182 * .. Scalar Arguments ..
183 DOUBLE PRECISION ALPHA, BETA
184 INTEGER INCX, INCY, LDA, M, N, TRANS
186 * .. Array Arguments ..
187 DOUBLE PRECISION A( LDA, * ), X( * ), Y( * )
190 * =====================================================================
193 DOUBLE PRECISION ONE, ZERO
194 PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )
196 * .. Local Scalars ..
198 DOUBLE PRECISION TEMP, SAFE1
199 INTEGER I, INFO, IY, J, JX, KX, KY, LENX, LENY
201 * .. External Subroutines ..
202 EXTERNAL XERBLA, DLAMCH
203 DOUBLE PRECISION DLAMCH
205 * .. External Functions ..
209 * .. Intrinsic Functions ..
210 INTRINSIC MAX, ABS, SIGN
212 * .. Executable Statements ..
214 * Test the input parameters.
217 IF ( .NOT.( ( TRANS.EQ.ILATRANS( 'N' ) )
218 $ .OR. ( TRANS.EQ.ILATRANS( 'T' ) )
219 $ .OR. ( TRANS.EQ.ILATRANS( 'C' )) ) ) THEN
221 ELSE IF( M.LT.0 )THEN
223 ELSE IF( N.LT.0 )THEN
225 ELSE IF( LDA.LT.MAX( 1, M ) )THEN
227 ELSE IF( INCX.EQ.0 )THEN
229 ELSE IF( INCY.EQ.0 )THEN
233 CALL XERBLA( 'DLA_GEAMV ', INFO )
237 * Quick return if possible.
239 IF( ( M.EQ.0 ).OR.( N.EQ.0 ).OR.
240 $ ( ( ALPHA.EQ.ZERO ).AND.( BETA.EQ.ONE ) ) )
243 * Set LENX and LENY, the lengths of the vectors x and y, and set
244 * up the start points in X and Y.
246 IF( TRANS.EQ.ILATRANS( 'N' ) )THEN
256 KX = 1 - ( LENX - 1 )*INCX
261 KY = 1 - ( LENY - 1 )*INCY
264 * Set SAFE1 essentially to be the underflow threshold times the
265 * number of additions in each row.
267 SAFE1 = DLAMCH( 'Safe minimum' )
270 * Form y := alpha*abs(A)*abs(x) + beta*abs(y).
272 * The O(M*N) SYMB_ZERO tests could be replaced by O(N) queries to
273 * the inexact flag. Still doesn't help change the iteration order
277 IF ( INCX.EQ.1 ) THEN
278 IF( TRANS.EQ.ILATRANS( 'N' ) )THEN
280 IF ( BETA .EQ. ZERO ) THEN
283 ELSE IF ( Y( IY ) .EQ. ZERO ) THEN
287 Y( IY ) = BETA * ABS( Y( IY ) )
289 IF ( ALPHA .NE. ZERO ) THEN
291 TEMP = ABS( A( I, J ) )
292 SYMB_ZERO = SYMB_ZERO .AND.
293 $ ( X( J ) .EQ. ZERO .OR. TEMP .EQ. ZERO )
295 Y( IY ) = Y( IY ) + ALPHA*ABS( X( J ) )*TEMP
299 IF ( .NOT.SYMB_ZERO )
300 $ Y( IY ) = Y( IY ) + SIGN( SAFE1, Y( IY ) )
306 IF ( BETA .EQ. ZERO ) THEN
309 ELSE IF ( Y( IY ) .EQ. ZERO ) THEN
313 Y( IY ) = BETA * ABS( Y( IY ) )
315 IF ( ALPHA .NE. ZERO ) THEN
317 TEMP = ABS( A( J, I ) )
318 SYMB_ZERO = SYMB_ZERO .AND.
319 $ ( X( J ) .EQ. ZERO .OR. TEMP .EQ. ZERO )
321 Y( IY ) = Y( IY ) + ALPHA*ABS( X( J ) )*TEMP
325 IF ( .NOT.SYMB_ZERO )
326 $ Y( IY ) = Y( IY ) + SIGN( SAFE1, Y( IY ) )
332 IF( TRANS.EQ.ILATRANS( 'N' ) )THEN
334 IF ( BETA .EQ. ZERO ) THEN
337 ELSE IF ( Y( IY ) .EQ. ZERO ) THEN
341 Y( IY ) = BETA * ABS( Y( IY ) )
343 IF ( ALPHA .NE. ZERO ) THEN
346 TEMP = ABS( A( I, J ) )
347 SYMB_ZERO = SYMB_ZERO .AND.
348 $ ( X( JX ) .EQ. ZERO .OR. TEMP .EQ. ZERO )
350 Y( IY ) = Y( IY ) + ALPHA*ABS( X( JX ) )*TEMP
356 $ Y( IY ) = Y( IY ) + SIGN( SAFE1, Y( IY ) )
362 IF ( BETA .EQ. ZERO ) THEN
365 ELSE IF ( Y( IY ) .EQ. ZERO ) THEN
369 Y( IY ) = BETA * ABS( Y( IY ) )
371 IF ( ALPHA .NE. ZERO ) THEN
374 TEMP = ABS( A( J, I ) )
375 SYMB_ZERO = SYMB_ZERO .AND.
376 $ ( X( JX ) .EQ. ZERO .OR. TEMP .EQ. ZERO )
378 Y( IY ) = Y( IY ) + ALPHA*ABS( X( JX ) )*TEMP
384 $ Y( IY ) = Y( IY ) + SIGN( SAFE1, Y( IY ) )