1 *> \brief \b DLAGS2 computes 2-by-2 orthogonal matrices U, V, and Q, and applies them to matrices A and B such that the rows of the transformed A and B are parallel.
3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download DLAGS2 + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlags2.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlags2.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlags2.f">
21 * SUBROUTINE DLAGS2( UPPER, A1, A2, A3, B1, B2, B3, CSU, SNU, CSV,
24 * .. Scalar Arguments ..
26 * DOUBLE PRECISION A1, A2, A3, B1, B2, B3, CSQ, CSU, CSV, SNQ,
36 *> DLAGS2 computes 2-by-2 orthogonal matrices U, V and Q, such
37 *> that if ( UPPER ) then
39 *> U**T *A*Q = U**T *( A1 A2 )*Q = ( x 0 )
42 *> V**T*B*Q = V**T *( B1 B2 )*Q = ( x 0 )
45 *> or if ( .NOT.UPPER ) then
47 *> U**T *A*Q = U**T *( A1 0 )*Q = ( x x )
50 *> V**T*B*Q = V**T*( B1 0 )*Q = ( x x )
53 *> The rows of the transformed A and B are parallel, where
55 *> U = ( CSU SNU ), V = ( CSV SNV ), Q = ( CSQ SNQ )
56 *> ( -SNU CSU ) ( -SNV CSV ) ( -SNQ CSQ )
58 *> Z**T denotes the transpose of Z.
68 *> = .TRUE.: the input matrices A and B are upper triangular.
69 *> = .FALSE.: the input matrices A and B are lower triangular.
74 *> A1 is DOUBLE PRECISION
79 *> A2 is DOUBLE PRECISION
84 *> A3 is DOUBLE PRECISION
85 *> On entry, A1, A2 and A3 are elements of the input 2-by-2
86 *> upper (lower) triangular matrix A.
91 *> B1 is DOUBLE PRECISION
96 *> B2 is DOUBLE PRECISION
101 *> B3 is DOUBLE PRECISION
102 *> On entry, B1, B2 and B3 are elements of the input 2-by-2
103 *> upper (lower) triangular matrix B.
108 *> CSU is DOUBLE PRECISION
113 *> SNU is DOUBLE PRECISION
114 *> The desired orthogonal matrix U.
119 *> CSV is DOUBLE PRECISION
124 *> SNV is DOUBLE PRECISION
125 *> The desired orthogonal matrix V.
130 *> CSQ is DOUBLE PRECISION
135 *> SNQ is DOUBLE PRECISION
136 *> The desired orthogonal matrix Q.
142 *> \author Univ. of Tennessee
143 *> \author Univ. of California Berkeley
144 *> \author Univ. of Colorado Denver
147 *> \date September 2012
149 *> \ingroup doubleOTHERauxiliary
151 * =====================================================================
152 SUBROUTINE DLAGS2( UPPER, A1, A2, A3, B1, B2, B3, CSU, SNU, CSV,
155 * -- LAPACK auxiliary routine (version 3.4.2) --
156 * -- LAPACK is a software package provided by Univ. of Tennessee, --
157 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
160 * .. Scalar Arguments ..
162 DOUBLE PRECISION A1, A2, A3, B1, B2, B3, CSQ, CSU, CSV, SNQ,
166 * =====================================================================
169 DOUBLE PRECISION ZERO
170 PARAMETER ( ZERO = 0.0D+0 )
172 * .. Local Scalars ..
173 DOUBLE PRECISION A, AUA11, AUA12, AUA21, AUA22, AVB11, AVB12,
174 $ AVB21, AVB22, B, C, CSL, CSR, D, R, S1, S2,
175 $ SNL, SNR, UA11, UA11R, UA12, UA21, UA22, UA22R,
176 $ VB11, VB11R, VB12, VB21, VB22, VB22R
178 * .. External Subroutines ..
179 EXTERNAL DLARTG, DLASV2
181 * .. Intrinsic Functions ..
184 * .. Executable Statements ..
188 * Input matrices A and B are upper triangular matrices
190 * Form matrix C = A*adj(B) = ( a b )
197 * The SVD of real 2-by-2 triangular C
199 * ( CSL -SNL )*( A B )*( CSR SNR ) = ( R 0 )
200 * ( SNL CSL ) ( 0 D ) ( -SNR CSR ) ( 0 T )
202 CALL DLASV2( A, B, D, S1, S2, SNR, CSR, SNL, CSL )
204 IF( ABS( CSL ).GE.ABS( SNL ) .OR. ABS( CSR ).GE.ABS( SNR ) )
207 * Compute the (1,1) and (1,2) elements of U**T *A and V**T *B,
208 * and (1,2) element of |U|**T *|A| and |V|**T *|B|.
211 UA12 = CSL*A2 + SNL*A3
214 VB12 = CSR*B2 + SNR*B3
216 AUA12 = ABS( CSL )*ABS( A2 ) + ABS( SNL )*ABS( A3 )
217 AVB12 = ABS( CSR )*ABS( B2 ) + ABS( SNR )*ABS( B3 )
219 * zero (1,2) elements of U**T *A and V**T *B
221 IF( ( ABS( UA11R )+ABS( UA12 ) ).NE.ZERO ) THEN
222 IF( AUA12 / ( ABS( UA11R )+ABS( UA12 ) ).LE.AVB12 /
223 $ ( ABS( VB11R )+ABS( VB12 ) ) ) THEN
224 CALL DLARTG( -UA11R, UA12, CSQ, SNQ, R )
226 CALL DLARTG( -VB11R, VB12, CSQ, SNQ, R )
229 CALL DLARTG( -VB11R, VB12, CSQ, SNQ, R )
239 * Compute the (2,1) and (2,2) elements of U**T *A and V**T *B,
240 * and (2,2) element of |U|**T *|A| and |V|**T *|B|.
243 UA22 = -SNL*A2 + CSL*A3
246 VB22 = -SNR*B2 + CSR*B3
248 AUA22 = ABS( SNL )*ABS( A2 ) + ABS( CSL )*ABS( A3 )
249 AVB22 = ABS( SNR )*ABS( B2 ) + ABS( CSR )*ABS( B3 )
251 * zero (2,2) elements of U**T*A and V**T*B, and then swap.
253 IF( ( ABS( UA21 )+ABS( UA22 ) ).NE.ZERO ) THEN
254 IF( AUA22 / ( ABS( UA21 )+ABS( UA22 ) ).LE.AVB22 /
255 $ ( ABS( VB21 )+ABS( VB22 ) ) ) THEN
256 CALL DLARTG( -UA21, UA22, CSQ, SNQ, R )
258 CALL DLARTG( -VB21, VB22, CSQ, SNQ, R )
261 CALL DLARTG( -VB21, VB22, CSQ, SNQ, R )
273 * Input matrices A and B are lower triangular matrices
275 * Form matrix C = A*adj(B) = ( a 0 )
282 * The SVD of real 2-by-2 triangular C
284 * ( CSL -SNL )*( A 0 )*( CSR SNR ) = ( R 0 )
285 * ( SNL CSL ) ( C D ) ( -SNR CSR ) ( 0 T )
287 CALL DLASV2( A, C, D, S1, S2, SNR, CSR, SNL, CSL )
289 IF( ABS( CSR ).GE.ABS( SNR ) .OR. ABS( CSL ).GE.ABS( SNL ) )
292 * Compute the (2,1) and (2,2) elements of U**T *A and V**T *B,
293 * and (2,1) element of |U|**T *|A| and |V|**T *|B|.
295 UA21 = -SNR*A1 + CSR*A2
298 VB21 = -SNL*B1 + CSL*B2
301 AUA21 = ABS( SNR )*ABS( A1 ) + ABS( CSR )*ABS( A2 )
302 AVB21 = ABS( SNL )*ABS( B1 ) + ABS( CSL )*ABS( B2 )
304 * zero (2,1) elements of U**T *A and V**T *B.
306 IF( ( ABS( UA21 )+ABS( UA22R ) ).NE.ZERO ) THEN
307 IF( AUA21 / ( ABS( UA21 )+ABS( UA22R ) ).LE.AVB21 /
308 $ ( ABS( VB21 )+ABS( VB22R ) ) ) THEN
309 CALL DLARTG( UA22R, UA21, CSQ, SNQ, R )
311 CALL DLARTG( VB22R, VB21, CSQ, SNQ, R )
314 CALL DLARTG( VB22R, VB21, CSQ, SNQ, R )
324 * Compute the (1,1) and (1,2) elements of U**T *A and V**T *B,
325 * and (1,1) element of |U|**T *|A| and |V|**T *|B|.
327 UA11 = CSR*A1 + SNR*A2
330 VB11 = CSL*B1 + SNL*B2
333 AUA11 = ABS( CSR )*ABS( A1 ) + ABS( SNR )*ABS( A2 )
334 AVB11 = ABS( CSL )*ABS( B1 ) + ABS( SNL )*ABS( B2 )
336 * zero (1,1) elements of U**T*A and V**T*B, and then swap.
338 IF( ( ABS( UA11 )+ABS( UA12 ) ).NE.ZERO ) THEN
339 IF( AUA11 / ( ABS( UA11 )+ABS( UA12 ) ).LE.AVB11 /
340 $ ( ABS( VB11 )+ABS( VB12 ) ) ) THEN
341 CALL DLARTG( UA12, UA11, CSQ, SNQ, R )
343 CALL DLARTG( VB12, VB11, CSQ, SNQ, R )
346 CALL DLARTG( VB12, VB11, CSQ, SNQ, R )