1 SUBROUTINE DLASR
( SIDE
, PIVOT
, DIRECT
, M
, N
, C
, S
, A
, LDA
)
3 * -- LAPACK auxiliary routine
(version
3.1) --
4 * Univ
. of Tennessee
, Univ
. of California Berkeley and NAG Ltd
..
7 * .. Scalar Arguments
..
8 CHARACTER DIRECT
, PIVOT
, SIDE
11 * .. Array Arguments
..
12 DOUBLE PRECISION A
( LDA
, * ), C
( * ), S
( * )
18 * DLASR applies a sequence of plane rotations
to a
real matrix A
,
19 * from either the left or the right
.
21 * When SIDE
= 'L', the transformation takes the form
25 * and when SIDE
= 'R', the transformation takes the form
29 * where P is an orthogonal matrix consisting of a sequence of z plane
30 * rotations
, with z
= M when SIDE
= 'L' and z
= N when SIDE
= 'R',
31 * and P**T is the transpose of P
.
33 * When DIRECT
= 'F' (Forward sequence
), then
35 * P
= P
(z
-1) * ... * P
(2) * P
(1)
37 * and when DIRECT
= 'B' (Backward sequence
), then
39 * P
= P
(1) * P
(2) * ... * P
(z
-1)
41 * where P
(k
) is a plane rotation matrix defined by the
2-by
-2 rotation
43 * R
(k
) = ( c
(k
) s
(k
) )
46 * When PIVOT
= 'V' (Variable pivot
), the rotation is performed
47 * for the plane
(k
,k
+1), i
.e
., P
(k
) has the form
58 * where R
(k
) appears as a rank
-2 modification
to the identity matrix in
59 * rows and columns k and k
+1.
61 * When PIVOT
= 'T' (Top pivot
), the rotation is performed
for the
62 * plane
(1,k
+1), so P
(k
) has the form
64 * P
(k
) = ( c
(k
) s
(k
) )
73 * where R
(k
) appears in rows and columns
1 and k
+1.
75 * Similarly
, when PIVOT
= 'B' (Bottom pivot
), the rotation is
76 * performed
for the plane
(k
,z
), giving P
(k
) the form
87 * where R
(k
) appears in rows and columns k and z
. The rotations are
88 * performed without ever forming P
(k
) explicitly
.
93 * SIDE
(input
) CHARACTER*1
94 * Specifies whether the plane rotation matrix P is applied
to
95 * A on the left or the right
.
96 * = 'L': Left
, compute A
:= P*A
97 * = 'R': Right
, compute A
:= A*P**T
99 * PIVOT
(input
) CHARACTER*1
100 * Specifies the plane
for which P
(k
) is a plane rotation
102 * = 'V': Variable pivot
, the plane
(k
,k
+1)
103 * = 'T': Top pivot
, the plane
(1,k
+1)
104 * = 'B': Bottom pivot
, the plane
(k
,z
)
106 * DIRECT
(input
) CHARACTER*1
107 * Specifies whether P is a forward or backward sequence of
109 * = 'F': Forward
, P
= P
(z
-1)*...*P
(2)*P
(1)
110 * = 'B': Backward
, P
= P
(1)*P
(2)*...*P
(z
-1)
113 * The number of rows of the matrix A
. If m
<= 1, an immediate
114 * return is effected
.
117 * The number of columns of the matrix A
. If n
<= 1, an
118 * immediate
return is effected
.
120 * C
(input
) DOUBLE PRECISION array
, dimension
121 * (M
-1) if SIDE
= 'L'
122 * (N
-1) if SIDE
= 'R'
123 * The cosines c
(k
) of the plane rotations
.
125 * S
(input
) DOUBLE PRECISION array
, dimension
126 * (M
-1) if SIDE
= 'L'
127 * (N
-1) if SIDE
= 'R'
128 * The sines s
(k
) of the plane rotations
. The
2-by
-2 plane
129 * rotation part of the matrix P
(k
), R
(k
), has the form
130 * R
(k
) = ( c
(k
) s
(k
) )
133 * A
(input
/output
) DOUBLE PRECISION array
, dimension (LDA
,N
)
134 * The M
-by
-N matrix A
. On exit
, A is overwritten by P*A
if
135 * SIDE
= 'R' or by A*P**T
if SIDE
= 'L'.
137 * LDA
(input
) INTEGER
138 * The leading
dimension of the array A
. LDA
>= max
(1,M
).
140 * =====================================================================
143 DOUBLE PRECISION ONE
, ZERO
144 PARAMETER ( ONE
= 1.0D
+0, ZERO
= 0.0D
+0 )
146 * .. Local Scalars
..
148 DOUBLE PRECISION CTEMP
, STEMP
, TEMP
150 * .. External Functions
..
154 * .. External Subroutines
..
157 * .. Intrinsic Functions
..
160 * .. Executable Statements
..
162 * Test the input parameters
165 IF( .NOT
.( LSAME
( SIDE
, 'L' ) .OR
. LSAME
( SIDE
, 'R' ) ) ) THEN
167 ELSE IF( .NOT
.( LSAME
( PIVOT
, 'V' ) .OR
. LSAME
( PIVOT
,
168 $
'T' ) .OR
. LSAME
( PIVOT
, 'B' ) ) ) THEN
170 ELSE IF( .NOT
.( LSAME
( DIRECT
, 'F' ) .OR
. LSAME
( DIRECT
, 'B' ) ) )
173 ELSE IF( M
.LT
.0 ) THEN
175 ELSE IF( N
.LT
.0 ) THEN
177 ELSE IF( LDA
.LT
.MAX
( 1, M
) ) THEN
181 CALL XERBLA
( 'DLASR ', INFO
)
185 * Quick
return if possible
187 IF( ( M
.EQ
.0 ) .OR
. ( N
.EQ
.0 ) )
189 IF( LSAME
( SIDE
, 'L' ) ) THEN
193 IF( LSAME
( PIVOT
, 'V' ) ) THEN
194 IF( LSAME
( DIRECT
, 'F' ) ) THEN
198 IF( ( CTEMP
.NE
.ONE
) .OR
. ( STEMP
.NE
.ZERO
) ) THEN
201 A
( J
+1, I
) = CTEMP*TEMP
- STEMP*A
( J
, I
)
202 A
( J
, I
) = STEMP*TEMP
+ CTEMP*A
( J
, I
)
206 ELSE IF( LSAME
( DIRECT
, 'B' ) ) THEN
207 DO 40 J
= M
- 1, 1, -1
210 IF( ( CTEMP
.NE
.ONE
) .OR
. ( STEMP
.NE
.ZERO
) ) THEN
213 A
( J
+1, I
) = CTEMP*TEMP
- STEMP*A
( J
, I
)
214 A
( J
, I
) = STEMP*TEMP
+ CTEMP*A
( J
, I
)
219 ELSE IF( LSAME
( PIVOT
, 'T' ) ) THEN
220 IF( LSAME
( DIRECT
, 'F' ) ) THEN
224 IF( ( CTEMP
.NE
.ONE
) .OR
. ( STEMP
.NE
.ZERO
) ) THEN
227 A
( J
, I
) = CTEMP*TEMP
- STEMP*A
( 1, I
)
228 A
( 1, I
) = STEMP*TEMP
+ CTEMP*A
( 1, I
)
232 ELSE IF( LSAME
( DIRECT
, 'B' ) ) THEN
236 IF( ( CTEMP
.NE
.ONE
) .OR
. ( STEMP
.NE
.ZERO
) ) THEN
239 A
( J
, I
) = CTEMP*TEMP
- STEMP*A
( 1, I
)
240 A
( 1, I
) = STEMP*TEMP
+ CTEMP*A
( 1, I
)
245 ELSE IF( LSAME
( PIVOT
, 'B' ) ) THEN
246 IF( LSAME
( DIRECT
, 'F' ) ) THEN
250 IF( ( CTEMP
.NE
.ONE
) .OR
. ( STEMP
.NE
.ZERO
) ) THEN
253 A
( J
, I
) = STEMP*A
( M
, I
) + CTEMP*TEMP
254 A
( M
, I
) = CTEMP*A
( M
, I
) - STEMP*TEMP
258 ELSE IF( LSAME
( DIRECT
, 'B' ) ) THEN
259 DO 120 J
= M
- 1, 1, -1
262 IF( ( CTEMP
.NE
.ONE
) .OR
. ( STEMP
.NE
.ZERO
) ) THEN
265 A
( J
, I
) = STEMP*A
( M
, I
) + CTEMP*TEMP
266 A
( M
, I
) = CTEMP*A
( M
, I
) - STEMP*TEMP
272 ELSE IF( LSAME
( SIDE
, 'R' ) ) THEN
276 IF( LSAME( PIVOT, 'V
' ) ) THEN
277 IF( LSAME( DIRECT, 'F
' ) ) THEN
281 IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
284 A( I, J+1 ) = CTEMP*TEMP - STEMP*A( I, J )
285 A( I, J ) = STEMP*TEMP + CTEMP*A( I, J )
289 ELSE IF( LSAME( DIRECT, 'B
' ) ) THEN
290 DO 160 J = N - 1, 1, -1
293 IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
296 A( I, J+1 ) = CTEMP*TEMP - STEMP*A( I, J )
297 A( I, J ) = STEMP*TEMP + CTEMP*A( I, J )
302 ELSE IF( LSAME( PIVOT, 'T
' ) ) THEN
303 IF( LSAME( DIRECT, 'F
' ) ) THEN
307 IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
310 A( I, J ) = CTEMP*TEMP - STEMP*A( I, 1 )
311 A( I, 1 ) = STEMP*TEMP + CTEMP*A( I, 1 )
315 ELSE IF( LSAME( DIRECT, 'B
' ) ) THEN
319 IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
322 A( I, J ) = CTEMP*TEMP - STEMP*A( I, 1 )
323 A( I, 1 ) = STEMP*TEMP + CTEMP*A( I, 1 )
328 ELSE IF( LSAME( PIVOT, 'B
' ) ) THEN
329 IF( LSAME( DIRECT, 'F
' ) ) THEN
333 IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
336 A( I, J ) = STEMP*A( I, N ) + CTEMP*TEMP
337 A( I, N ) = CTEMP*A( I, N ) - STEMP*TEMP
341 ELSE IF( LSAME( DIRECT, 'B
' ) ) THEN
342 DO 240 J = N - 1, 1, -1
345 IF( ( CTEMP.NE.ONE ) .OR. ( STEMP.NE.ZERO ) ) THEN
348 A( I, J ) = STEMP*A( I, N ) + CTEMP*TEMP
349 A( I, N ) = CTEMP*A( I, N ) - STEMP*TEMP