LAPACK  3.6.1
LAPACK: Linear Algebra PACKage
dlags2.f
Go to the documentation of this file.
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.
2 *
3 * =========== DOCUMENTATION ===========
4 *
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
7 *
8 *> \htmlonly
9 *> Download DLAGS2 + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlags2.f">
11 *> [TGZ]</a>
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlags2.f">
13 *> [ZIP]</a>
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlags2.f">
15 *> [TXT]</a>
16 *> \endhtmlonly
17 *
18 * Definition:
19 * ===========
20 *
21 * SUBROUTINE DLAGS2( UPPER, A1, A2, A3, B1, B2, B3, CSU, SNU, CSV,
22 * SNV, CSQ, SNQ )
23 *
24 * .. Scalar Arguments ..
25 * LOGICAL UPPER
26 * DOUBLE PRECISION A1, A2, A3, B1, B2, B3, CSQ, CSU, CSV, SNQ,
27 * $ SNU, SNV
28 * ..
29 *
30 *
31 *> \par Purpose:
32 * =============
33 *>
34 *> \verbatim
35 *>
36 *> DLAGS2 computes 2-by-2 orthogonal matrices U, V and Q, such
37 *> that if ( UPPER ) then
38 *>
39 *> U**T *A*Q = U**T *( A1 A2 )*Q = ( x 0 )
40 *> ( 0 A3 ) ( x x )
41 *> and
42 *> V**T*B*Q = V**T *( B1 B2 )*Q = ( x 0 )
43 *> ( 0 B3 ) ( x x )
44 *>
45 *> or if ( .NOT.UPPER ) then
46 *>
47 *> U**T *A*Q = U**T *( A1 0 )*Q = ( x x )
48 *> ( A2 A3 ) ( 0 x )
49 *> and
50 *> V**T*B*Q = V**T*( B1 0 )*Q = ( x x )
51 *> ( B2 B3 ) ( 0 x )
52 *>
53 *> The rows of the transformed A and B are parallel, where
54 *>
55 *> U = ( CSU SNU ), V = ( CSV SNV ), Q = ( CSQ SNQ )
56 *> ( -SNU CSU ) ( -SNV CSV ) ( -SNQ CSQ )
57 *>
58 *> Z**T denotes the transpose of Z.
59 *>
60 *> \endverbatim
61 *
62 * Arguments:
63 * ==========
64 *
65 *> \param[in] UPPER
66 *> \verbatim
67 *> UPPER is LOGICAL
68 *> = .TRUE.: the input matrices A and B are upper triangular.
69 *> = .FALSE.: the input matrices A and B are lower triangular.
70 *> \endverbatim
71 *>
72 *> \param[in] A1
73 *> \verbatim
74 *> A1 is DOUBLE PRECISION
75 *> \endverbatim
76 *>
77 *> \param[in] A2
78 *> \verbatim
79 *> A2 is DOUBLE PRECISION
80 *> \endverbatim
81 *>
82 *> \param[in] A3
83 *> \verbatim
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.
87 *> \endverbatim
88 *>
89 *> \param[in] B1
90 *> \verbatim
91 *> B1 is DOUBLE PRECISION
92 *> \endverbatim
93 *>
94 *> \param[in] B2
95 *> \verbatim
96 *> B2 is DOUBLE PRECISION
97 *> \endverbatim
98 *>
99 *> \param[in] B3
100 *> \verbatim
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.
104 *> \endverbatim
105 *>
106 *> \param[out] CSU
107 *> \verbatim
108 *> CSU is DOUBLE PRECISION
109 *> \endverbatim
110 *>
111 *> \param[out] SNU
112 *> \verbatim
113 *> SNU is DOUBLE PRECISION
114 *> The desired orthogonal matrix U.
115 *> \endverbatim
116 *>
117 *> \param[out] CSV
118 *> \verbatim
119 *> CSV is DOUBLE PRECISION
120 *> \endverbatim
121 *>
122 *> \param[out] SNV
123 *> \verbatim
124 *> SNV is DOUBLE PRECISION
125 *> The desired orthogonal matrix V.
126 *> \endverbatim
127 *>
128 *> \param[out] CSQ
129 *> \verbatim
130 *> CSQ is DOUBLE PRECISION
131 *> \endverbatim
132 *>
133 *> \param[out] SNQ
134 *> \verbatim
135 *> SNQ is DOUBLE PRECISION
136 *> The desired orthogonal matrix Q.
137 *> \endverbatim
138 *
139 * Authors:
140 * ========
141 *
142 *> \author Univ. of Tennessee
143 *> \author Univ. of California Berkeley
144 *> \author Univ. of Colorado Denver
145 *> \author NAG Ltd.
146 *
147 *> \date September 2012
148 *
149 *> \ingroup doubleOTHERauxiliary
150 *
151 * =====================================================================
152  SUBROUTINE dlags2( UPPER, A1, A2, A3, B1, B2, B3, CSU, SNU, CSV,
153  $ snv, csq, snq )
154 *
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..--
158 * September 2012
159 *
160 * .. Scalar Arguments ..
161  LOGICAL UPPER
162  DOUBLE PRECISION A1, A2, A3, B1, B2, B3, CSQ, CSU, CSV, SNQ,
163  $ snu, snv
164 * ..
165 *
166 * =====================================================================
167 *
168 * .. Parameters ..
169  DOUBLE PRECISION ZERO
170  parameter ( zero = 0.0d+0 )
171 * ..
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
177 * ..
178 * .. External Subroutines ..
179  EXTERNAL dlartg, dlasv2
180 * ..
181 * .. Intrinsic Functions ..
182  INTRINSIC abs
183 * ..
184 * .. Executable Statements ..
185 *
186  IF( upper ) THEN
187 *
188 * Input matrices A and B are upper triangular matrices
189 *
190 * Form matrix C = A*adj(B) = ( a b )
191 * ( 0 d )
192 *
193  a = a1*b3
194  d = a3*b1
195  b = a2*b1 - a1*b2
196 *
197 * The SVD of real 2-by-2 triangular C
198 *
199 * ( CSL -SNL )*( A B )*( CSR SNR ) = ( R 0 )
200 * ( SNL CSL ) ( 0 D ) ( -SNR CSR ) ( 0 T )
201 *
202  CALL dlasv2( a, b, d, s1, s2, snr, csr, snl, csl )
203 *
204  IF( abs( csl ).GE.abs( snl ) .OR. abs( csr ).GE.abs( snr ) )
205  $ THEN
206 *
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|.
209 *
210  ua11r = csl*a1
211  ua12 = csl*a2 + snl*a3
212 *
213  vb11r = csr*b1
214  vb12 = csr*b2 + snr*b3
215 *
216  aua12 = abs( csl )*abs( a2 ) + abs( snl )*abs( a3 )
217  avb12 = abs( csr )*abs( b2 ) + abs( snr )*abs( b3 )
218 *
219 * zero (1,2) elements of U**T *A and V**T *B
220 *
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 )
225  ELSE
226  CALL dlartg( -vb11r, vb12, csq, snq, r )
227  END IF
228  ELSE
229  CALL dlartg( -vb11r, vb12, csq, snq, r )
230  END IF
231 *
232  csu = csl
233  snu = -snl
234  csv = csr
235  snv = -snr
236 *
237  ELSE
238 *
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|.
241 *
242  ua21 = -snl*a1
243  ua22 = -snl*a2 + csl*a3
244 *
245  vb21 = -snr*b1
246  vb22 = -snr*b2 + csr*b3
247 *
248  aua22 = abs( snl )*abs( a2 ) + abs( csl )*abs( a3 )
249  avb22 = abs( snr )*abs( b2 ) + abs( csr )*abs( b3 )
250 *
251 * zero (2,2) elements of U**T*A and V**T*B, and then swap.
252 *
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 )
257  ELSE
258  CALL dlartg( -vb21, vb22, csq, snq, r )
259  END IF
260  ELSE
261  CALL dlartg( -vb21, vb22, csq, snq, r )
262  END IF
263 *
264  csu = snl
265  snu = csl
266  csv = snr
267  snv = csr
268 *
269  END IF
270 *
271  ELSE
272 *
273 * Input matrices A and B are lower triangular matrices
274 *
275 * Form matrix C = A*adj(B) = ( a 0 )
276 * ( c d )
277 *
278  a = a1*b3
279  d = a3*b1
280  c = a2*b3 - a3*b2
281 *
282 * The SVD of real 2-by-2 triangular C
283 *
284 * ( CSL -SNL )*( A 0 )*( CSR SNR ) = ( R 0 )
285 * ( SNL CSL ) ( C D ) ( -SNR CSR ) ( 0 T )
286 *
287  CALL dlasv2( a, c, d, s1, s2, snr, csr, snl, csl )
288 *
289  IF( abs( csr ).GE.abs( snr ) .OR. abs( csl ).GE.abs( snl ) )
290  $ THEN
291 *
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|.
294 *
295  ua21 = -snr*a1 + csr*a2
296  ua22r = csr*a3
297 *
298  vb21 = -snl*b1 + csl*b2
299  vb22r = csl*b3
300 *
301  aua21 = abs( snr )*abs( a1 ) + abs( csr )*abs( a2 )
302  avb21 = abs( snl )*abs( b1 ) + abs( csl )*abs( b2 )
303 *
304 * zero (2,1) elements of U**T *A and V**T *B.
305 *
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 )
310  ELSE
311  CALL dlartg( vb22r, vb21, csq, snq, r )
312  END IF
313  ELSE
314  CALL dlartg( vb22r, vb21, csq, snq, r )
315  END IF
316 *
317  csu = csr
318  snu = -snr
319  csv = csl
320  snv = -snl
321 *
322  ELSE
323 *
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|.
326 *
327  ua11 = csr*a1 + snr*a2
328  ua12 = snr*a3
329 *
330  vb11 = csl*b1 + snl*b2
331  vb12 = snl*b3
332 *
333  aua11 = abs( csr )*abs( a1 ) + abs( snr )*abs( a2 )
334  avb11 = abs( csl )*abs( b1 ) + abs( snl )*abs( b2 )
335 *
336 * zero (1,1) elements of U**T*A and V**T*B, and then swap.
337 *
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 )
342  ELSE
343  CALL dlartg( vb12, vb11, csq, snq, r )
344  END IF
345  ELSE
346  CALL dlartg( vb12, vb11, csq, snq, r )
347  END IF
348 *
349  csu = snr
350  snu = csr
351  csv = snl
352  snv = csl
353 *
354  END IF
355 *
356  END IF
357 *
358  RETURN
359 *
360 * End of DLAGS2
361 *
362  END
subroutine dlags2(UPPER, A1, A2, A3, B1, B2, B3, CSU, SNU, CSV, SNV, CSQ, SNQ)
DLAGS2 computes 2-by-2 orthogonal matrices U, V, and Q, and applies them to matrices A and B such tha...
Definition: dlags2.f:154
subroutine dlasv2(F, G, H, SSMIN, SSMAX, SNR, CSR, SNL, CSL)
DLASV2 computes the singular value decomposition of a 2-by-2 triangular matrix.
Definition: dlasv2.f:140
subroutine dlartg(F, G, CS, SN, R)
DLARTG generates a plane rotation with real cosine and real sine.
Definition: dlartg.f:99