OpenRadioss 2025.1.11
OpenRadioss project
Loading...
Searching...
No Matches
zunbdb.f
Go to the documentation of this file.
1*> \brief \b ZUNBDB
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> \htmlonly
9*> Download ZUNBDB + dependencies
10*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zunbdb.f">
11*> [TGZ]</a>
12*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zunbdb.f">
13*> [ZIP]</a>
14*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zunbdb.f">
15*> [TXT]</a>
16*> \endhtmlonly
17*
18* Definition:
19* ===========
20*
21* SUBROUTINE ZUNBDB( TRANS, SIGNS, M, P, Q, X11, LDX11, X12, LDX12,
22* X21, LDX21, X22, LDX22, THETA, PHI, TAUP1,
23* TAUP2, TAUQ1, TAUQ2, WORK, LWORK, INFO )
24*
25* .. Scalar Arguments ..
26* CHARACTER SIGNS, TRANS
27* INTEGER INFO, LDX11, LDX12, LDX21, LDX22, LWORK, M, P,
28* $ Q
29* ..
30* .. Array Arguments ..
31* DOUBLE PRECISION PHI( * ), THETA( * )
32* COMPLEX*16 TAUP1( * ), TAUP2( * ), TAUQ1( * ), TAUQ2( * ),
33* $ WORK( * ), X11( LDX11, * ), X12( LDX12, * ),
34* $ X21( LDX21, * ), X22( LDX22, * )
35* ..
36*
37*
38*> \par Purpose:
39* =============
40*>
41*> \verbatim
42*>
43*> ZUNBDB simultaneously bidiagonalizes the blocks of an M-by-M
44*> partitioned unitary matrix X:
45*>
46*> [ B11 | B12 0 0 ]
47*> [ X11 | X12 ] [ P1 | ] [ 0 | 0 -I 0 ] [ Q1 | ]**H
48*> X = [-----------] = [---------] [----------------] [---------] .
49*> [ X21 | X22 ] [ | P2 ] [ B21 | B22 0 0 ] [ | Q2 ]
50*> [ 0 | 0 0 I ]
51*>
52*> X11 is P-by-Q. Q must be no larger than P, M-P, or M-Q. (If this is
53*> not the case, then X must be transposed and/or permuted. This can be
54*> done in constant time using the TRANS and SIGNS options. See ZUNCSD
55*> for details.)
56*>
57*> The unitary matrices P1, P2, Q1, and Q2 are P-by-P, (M-P)-by-
58*> (M-P), Q-by-Q, and (M-Q)-by-(M-Q), respectively. They are
59*> represented implicitly by Householder vectors.
60*>
61*> B11, B12, B21, and B22 are Q-by-Q bidiagonal matrices represented
62*> implicitly by angles THETA, PHI.
63*> \endverbatim
64*
65* Arguments:
66* ==========
67*
68*> \param[in] TRANS
69*> \verbatim
70*> TRANS is CHARACTER
71*> = 'T': X, U1, U2, V1T, and V2T are stored in row-major
72*> order;
73*> otherwise: X, U1, U2, V1T, and V2T are stored in column-
74*> major order.
75*> \endverbatim
76*>
77*> \param[in] SIGNS
78*> \verbatim
79*> SIGNS is CHARACTER
80*> = 'O': The lower-left block is made nonpositive (the
81*> "other" convention);
82*> otherwise: The upper-right block is made nonpositive (the
83*> "default" convention).
84*> \endverbatim
85*>
86*> \param[in] M
87*> \verbatim
88*> M is INTEGER
89*> The number of rows and columns in X.
90*> \endverbatim
91*>
92*> \param[in] P
93*> \verbatim
94*> P is INTEGER
95*> The number of rows in X11 and X12. 0 <= P <= M.
96*> \endverbatim
97*>
98*> \param[in] Q
99*> \verbatim
100*> Q is INTEGER
101*> The number of columns in X11 and X21. 0 <= Q <=
102*> MIN(P,M-P,M-Q).
103*> \endverbatim
104*>
105*> \param[in,out] X11
106*> \verbatim
107*> X11 is COMPLEX*16 array, dimension (LDX11,Q)
108*> On entry, the top-left block of the unitary matrix to be
109*> reduced. On exit, the form depends on TRANS:
110*> If TRANS = 'N', then
111*> the columns of tril(X11) specify reflectors for P1,
112*> the rows of triu(X11,1) specify reflectors for Q1;
113*> else TRANS = 'T', and
114*> the rows of triu(X11) specify reflectors for P1,
115*> the columns of tril(X11,-1) specify reflectors for Q1.
116*> \endverbatim
117*>
118*> \param[in] LDX11
119*> \verbatim
120*> LDX11 is INTEGER
121*> The leading dimension of X11. If TRANS = 'N', then LDX11 >=
122*> P; else LDX11 >= Q.
123*> \endverbatim
124*>
125*> \param[in,out] X12
126*> \verbatim
127*> X12 is COMPLEX*16 array, dimension (LDX12,M-Q)
128*> On entry, the top-right block of the unitary matrix to
129*> be reduced. On exit, the form depends on TRANS:
130*> If TRANS = 'N', then
131*> the rows of triu(X12) specify the first P reflectors for
132*> Q2;
133*> else TRANS = 'T', and
134*> the columns of tril(X12) specify the first P reflectors
135*> for Q2.
136*> \endverbatim
137*>
138*> \param[in] LDX12
139*> \verbatim
140*> LDX12 is INTEGER
141*> The leading dimension of X12. If TRANS = 'N', then LDX12 >=
142*> P; else LDX11 >= M-Q.
143*> \endverbatim
144*>
145*> \param[in,out] X21
146*> \verbatim
147*> X21 is COMPLEX*16 array, dimension (LDX21,Q)
148*> On entry, the bottom-left block of the unitary matrix to
149*> be reduced. On exit, the form depends on TRANS:
150*> If TRANS = 'N', then
151*> the columns of tril(X21) specify reflectors for P2;
152*> else TRANS = 'T', and
153*> the rows of triu(X21) specify reflectors for P2.
154*> \endverbatim
155*>
156*> \param[in] LDX21
157*> \verbatim
158*> LDX21 is INTEGER
159*> The leading dimension of X21. If TRANS = 'N', then LDX21 >=
160*> M-P; else LDX21 >= Q.
161*> \endverbatim
162*>
163*> \param[in,out] X22
164*> \verbatim
165*> X22 is COMPLEX*16 array, dimension (LDX22,M-Q)
166*> On entry, the bottom-right block of the unitary matrix to
167*> be reduced. On exit, the form depends on TRANS:
168*> If TRANS = 'N', then
169*> the rows of triu(X22(Q+1:M-P,P+1:M-Q)) specify the last
170*> M-P-Q reflectors for Q2,
171*> else TRANS = 'T', and
172*> the columns of tril(X22(P+1:M-Q,Q+1:M-P)) specify the last
173*> M-P-Q reflectors for P2.
174*> \endverbatim
175*>
176*> \param[in] LDX22
177*> \verbatim
178*> LDX22 is INTEGER
179*> The leading dimension of X22. If TRANS = 'N', then LDX22 >=
180*> M-P; else LDX22 >= M-Q.
181*> \endverbatim
182*>
183*> \param[out] THETA
184*> \verbatim
185*> THETA is DOUBLE PRECISION array, dimension (Q)
186*> The entries of the bidiagonal blocks B11, B12, B21, B22 can
187*> be computed from the angles THETA and PHI. See Further
188*> Details.
189*> \endverbatim
190*>
191*> \param[out] PHI
192*> \verbatim
193*> PHI is DOUBLE PRECISION array, dimension (Q-1)
194*> The entries of the bidiagonal blocks B11, B12, B21, B22 can
195*> be computed from the angles THETA and PHI. See Further
196*> Details.
197*> \endverbatim
198*>
199*> \param[out] TAUP1
200*> \verbatim
201*> TAUP1 is COMPLEX*16 array, dimension (P)
202*> The scalar factors of the elementary reflectors that define
203*> P1.
204*> \endverbatim
205*>
206*> \param[out] TAUP2
207*> \verbatim
208*> TAUP2 is COMPLEX*16 array, dimension (M-P)
209*> The scalar factors of the elementary reflectors that define
210*> P2.
211*> \endverbatim
212*>
213*> \param[out] TAUQ1
214*> \verbatim
215*> TAUQ1 is COMPLEX*16 array, dimension (Q)
216*> The scalar factors of the elementary reflectors that define
217*> Q1.
218*> \endverbatim
219*>
220*> \param[out] TAUQ2
221*> \verbatim
222*> TAUQ2 is COMPLEX*16 array, dimension (M-Q)
223*> The scalar factors of the elementary reflectors that define
224*> Q2.
225*> \endverbatim
226*>
227*> \param[out] WORK
228*> \verbatim
229*> WORK is COMPLEX*16 array, dimension (LWORK)
230*> \endverbatim
231*>
232*> \param[in] LWORK
233*> \verbatim
234*> LWORK is INTEGER
235*> The dimension of the array WORK. LWORK >= M-Q.
236*>
237*> If LWORK = -1, then a workspace query is assumed; the routine
238*> only calculates the optimal size of the WORK array, returns
239*> this value as the first entry of the WORK array, and no error
240*> message related to LWORK is issued by XERBLA.
241*> \endverbatim
242*>
243*> \param[out] INFO
244*> \verbatim
245*> INFO is INTEGER
246*> = 0: successful exit.
247*> < 0: if INFO = -i, the i-th argument had an illegal value.
248*> \endverbatim
249*
250* Authors:
251* ========
252*
253*> \author Univ. of Tennessee
254*> \author Univ. of California Berkeley
255*> \author Univ. of Colorado Denver
256*> \author NAG Ltd.
257*
258*> \ingroup complex16OTHERcomputational
259*
260*> \par Further Details:
261* =====================
262*>
263*> \verbatim
264*>
265*> The bidiagonal blocks B11, B12, B21, and B22 are represented
266*> implicitly by angles THETA(1), ..., THETA(Q) and PHI(1), ...,
267*> PHI(Q-1). B11 and B21 are upper bidiagonal, while B21 and B22 are
268*> lower bidiagonal. Every entry in each bidiagonal band is a product
269*> of a sine or cosine of a THETA with a sine or cosine of a PHI. See
270*> [1] or ZUNCSD for details.
271*>
272*> P1, P2, Q1, and Q2 are represented as products of elementary
273*> reflectors. See ZUNCSD for details on generating P1, P2, Q1, and Q2
274*> using ZUNGQR and ZUNGLQ.
275*> \endverbatim
276*
277*> \par References:
278* ================
279*>
280*> [1] Brian D. Sutton. Computing the complete CS decomposition. Numer.
281*> Algorithms, 50(1):33-65, 2009.
282*>
283* =====================================================================
284 SUBROUTINE zunbdb( TRANS, SIGNS, M, P, Q, X11, LDX11, X12, LDX12,
285 $ X21, LDX21, X22, LDX22, THETA, PHI, TAUP1,
286 $ TAUP2, TAUQ1, TAUQ2, WORK, LWORK, INFO )
287*
288* -- LAPACK computational routine --
289* -- LAPACK is a software package provided by Univ. of Tennessee, --
290* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
291*
292* .. Scalar Arguments ..
293 CHARACTER SIGNS, TRANS
294 INTEGER INFO, LDX11, LDX12, LDX21, LDX22, LWORK, M, P,
295 $ q
296* ..
297* .. Array Arguments ..
298 DOUBLE PRECISION PHI( * ), THETA( * )
299 COMPLEX*16 TAUP1( * ), TAUP2( * ), TAUQ1( * ), TAUQ2( * ),
300 $ work( * ), x11( ldx11, * ), x12( ldx12, * ),
301 $ x21( ldx21, * ), x22( ldx22, * )
302* ..
303*
304* ====================================================================
305*
306* .. Parameters ..
307 DOUBLE PRECISION REALONE
308 PARAMETER ( REALONE = 1.0d0 )
309 COMPLEX*16 ONE
310 parameter( one = (1.0d0,0.0d0) )
311* ..
312* .. Local Scalars ..
313 LOGICAL COLMAJOR, LQUERY
314 INTEGER I, LWORKMIN, LWORKOPT
315 DOUBLE PRECISION Z1, Z2, Z3, Z4
316* ..
317* .. External Subroutines ..
318 EXTERNAL zaxpy, zlarf, zlarfgp, zscal, xerbla
319 EXTERNAL zlacgv
320*
321* ..
322* .. External Functions ..
323 DOUBLE PRECISION DZNRM2
324 LOGICAL LSAME
325 EXTERNAL dznrm2, lsame
326* ..
327* .. Intrinsic Functions
328 INTRINSIC atan2, cos, max, min, sin
329 INTRINSIC dcmplx, dconjg
330* ..
331* .. Executable Statements ..
332*
333* Test input arguments
334*
335 info = 0
336 colmajor = .NOT. lsame( trans, 'T' )
337 IF( .NOT. lsame( signs, 'O' ) ) THEN
338 z1 = realone
339 z2 = realone
340 z3 = realone
341 z4 = realone
342 ELSE
343 z1 = realone
344 z2 = -realone
345 z3 = realone
346 z4 = -realone
347 END IF
348 lquery = lwork .EQ. -1
349*
350 IF( m .LT. 0 ) THEN
351 info = -3
352 ELSE IF( p .LT. 0 .OR. p .GT. m ) THEN
353 info = -4
354 ELSE IF( q .LT. 0 .OR. q .GT. p .OR. q .GT. m-p .OR.
355 $ q .GT. m-q ) THEN
356 info = -5
357 ELSE IF( colmajor .AND. ldx11 .LT. max( 1, p ) ) THEN
358 info = -7
359 ELSE IF( .NOT.colmajor .AND. ldx11 .LT. max( 1, q ) ) THEN
360 info = -7
361 ELSE IF( colmajor .AND. ldx12 .LT. max( 1, p ) ) THEN
362 info = -9
363 ELSE IF( .NOT.colmajor .AND. ldx12 .LT. max( 1, m-q ) ) THEN
364 info = -9
365 ELSE IF( colmajor .AND. ldx21 .LT. max( 1, m-p ) ) THEN
366 info = -11
367 ELSE IF( .NOT.colmajor .AND. ldx21 .LT. max( 1, q ) ) THEN
368 info = -11
369 ELSE IF( colmajor .AND. ldx22 .LT. max( 1, m-p ) ) THEN
370 info = -13
371 ELSE IF( .NOT.colmajor .AND. ldx22 .LT. max( 1, m-q ) ) THEN
372 info = -13
373 END IF
374*
375* Compute workspace
376*
377 IF( info .EQ. 0 ) THEN
378 lworkopt = m - q
379 lworkmin = m - q
380 work(1) = lworkopt
381 IF( lwork .LT. lworkmin .AND. .NOT. lquery ) THEN
382 info = -21
383 END IF
384 END IF
385 IF( info .NE. 0 ) THEN
386 CALL xerbla( 'xORBDB', -info )
387 RETURN
388 ELSE IF( lquery ) THEN
389 RETURN
390 END IF
391*
392* Handle column-major and row-major separately
393*
394 IF( colmajor ) THEN
395*
396* Reduce columns 1, ..., Q of X11, X12, X21, and X22
397*
398 DO i = 1, q
399*
400 IF( i .EQ. 1 ) THEN
401 CALL zscal( p-i+1, dcmplx( z1, 0.0d0 ), x11(i,i), 1 )
402 ELSE
403 CALL zscal( p-i+1, dcmplx( z1*cos(phi(i-1)), 0.0d0 ),
404 $ x11(i,i), 1 )
405 CALL zaxpy( p-i+1, dcmplx( -z1*z3*z4*sin(phi(i-1)),
406 $ 0.0d0 ), x12(i,i-1), 1, x11(i,i), 1 )
407 END IF
408 IF( i .EQ. 1 ) THEN
409 CALL zscal( m-p-i+1, dcmplx( z2, 0.0d0 ), x21(i,i), 1 )
410 ELSE
411 CALL zscal( m-p-i+1, dcmplx( z2*cos(phi(i-1)), 0.0d0 ),
412 $ x21(i,i), 1 )
413 CALL zaxpy( m-p-i+1, dcmplx( -z2*z3*z4*sin(phi(i-1)),
414 $ 0.0d0 ), x22(i,i-1), 1, x21(i,i), 1 )
415 END IF
416*
417 theta(i) = atan2( dznrm2( m-p-i+1, x21(i,i), 1 ),
418 $ dznrm2( p-i+1, x11(i,i), 1 ) )
419*
420 IF( p .GT. i ) THEN
421 CALL zlarfgp( p-i+1, x11(i,i), x11(i+1,i), 1, taup1(i) )
422 ELSE IF ( p .EQ. i ) THEN
423 CALL zlarfgp( p-i+1, x11(i,i), x11(i,i), 1, taup1(i) )
424 END IF
425 x11(i,i) = one
426 IF ( m-p .GT. i ) THEN
427 CALL zlarfgp( m-p-i+1, x21(i,i), x21(i+1,i), 1,
428 $ taup2(i) )
429 ELSE IF ( m-p .EQ. i ) THEN
430 CALL zlarfgp( m-p-i+1, x21(i,i), x21(i,i), 1,
431 $ taup2(i) )
432 END IF
433 x21(i,i) = one
434*
435 IF ( q .GT. i ) THEN
436 CALL zlarf( 'L', p-i+1, q-i, x11(i,i), 1,
437 $ dconjg(taup1(i)), x11(i,i+1), ldx11, work )
438 CALL zlarf( 'l', M-P-I+1, Q-I, X21(I,I), 1,
439 $ DCONJG(TAUP2(I)), X21(I,I+1), LDX21, WORK )
440 END IF
441.GT. IF ( M-Q+1 I ) THEN
442 CALL ZLARF( 'l', P-I+1, M-Q-I+1, X11(I,I), 1,
443 $ DCONJG(TAUP1(I)), X12(I,I), LDX12, WORK )
444 CALL ZLARF( 'l', M-P-I+1, M-Q-I+1, X21(I,I), 1,
445 $ DCONJG(TAUP2(I)), X22(I,I), LDX22, WORK )
446 END IF
447*
448.LT. IF( I Q ) THEN
449 CALL ZSCAL( Q-I, DCMPLX( -Z1*Z3*SIN(THETA(I)), 0.0D0 ),
450 $ X11(I,I+1), LDX11 )
451 CALL ZAXPY( Q-I, DCMPLX( Z2*Z3*COS(THETA(I)), 0.0D0 ),
452 $ X21(I,I+1), LDX21, X11(I,I+1), LDX11 )
453 END IF
454 CALL ZSCAL( M-Q-I+1, DCMPLX( -Z1*Z4*SIN(THETA(I)), 0.0D0 ),
455 $ X12(I,I), LDX12 )
456 CALL ZAXPY( M-Q-I+1, DCMPLX( Z2*Z4*COS(THETA(I)), 0.0D0 ),
457 $ X22(I,I), LDX22, X12(I,I), LDX12 )
458*
459.LT. IF( I Q )
460 $ PHI(I) = ATAN2( DZNRM2( Q-I, X11(I,I+1), LDX11 ),
461 $ DZNRM2( M-Q-I+1, X12(I,I), LDX12 ) )
462*
463.LT. IF( I Q ) THEN
464 CALL ZLACGV( Q-I, X11(I,I+1), LDX11 )
465.EQ. IF ( I Q-1 ) THEN
466 CALL ZLARFGP( Q-I, X11(I,I+1), X11(I,I+1), LDX11,
467 $ TAUQ1(I) )
468 ELSE
469 CALL ZLARFGP( Q-I, X11(I,I+1), X11(I,I+2), LDX11,
470 $ TAUQ1(I) )
471 END IF
472 X11(I,I+1) = ONE
473 END IF
474.GT. IF ( M-Q+1 I ) THEN
475 CALL ZLACGV( M-Q-I+1, X12(I,I), LDX12 )
476.EQ. IF ( M-Q I ) THEN
477 CALL ZLARFGP( M-Q-I+1, X12(I,I), X12(I,I), LDX12,
478 $ TAUQ2(I) )
479 ELSE
480 CALL ZLARFGP( M-Q-I+1, X12(I,I), X12(I,I+1), LDX12,
481 $ TAUQ2(I) )
482 END IF
483 END IF
484 X12(I,I) = ONE
485*
486.LT. IF( I Q ) THEN
487 CALL ZLARF( 'r', P-I, Q-I, X11(I,I+1), LDX11, TAUQ1(I),
488 $ X11(I+1,I+1), LDX11, WORK )
489 CALL ZLARF( 'r', M-P-I, Q-I, X11(I,I+1), LDX11, TAUQ1(I),
490 $ X21(I+1,I+1), LDX21, WORK )
491 END IF
492.GT. IF ( P I ) THEN
493 CALL ZLARF( 'r', P-I, M-Q-I+1, X12(I,I), LDX12, TAUQ2(I),
494 $ X12(I+1,I), LDX12, WORK )
495 END IF
496.GT. IF ( M-P I ) THEN
497 CALL ZLARF( 'r', M-P-I, M-Q-I+1, X12(I,I), LDX12,
498 $ TAUQ2(I), X22(I+1,I), LDX22, WORK )
499 END IF
500*
501.LT. IF( I Q )
502 $ CALL ZLACGV( Q-I, X11(I,I+1), LDX11 )
503 CALL ZLACGV( M-Q-I+1, X12(I,I), LDX12 )
504*
505 END DO
506*
507* Reduce columns Q + 1, ..., P of X12, X22
508*
509 DO I = Q + 1, P
510*
511 CALL ZSCAL( M-Q-I+1, DCMPLX( -Z1*Z4, 0.0D0 ), X12(I,I),
512 $ LDX12 )
513 CALL ZLACGV( M-Q-I+1, X12(I,I), LDX12 )
514.GE. IF ( I M-Q ) THEN
515 CALL ZLARFGP( M-Q-I+1, X12(I,I), X12(I,I), LDX12,
516 $ TAUQ2(I) )
517 ELSE
518 CALL ZLARFGP( M-Q-I+1, X12(I,I), X12(I,I+1), LDX12,
519 $ TAUQ2(I) )
520 END IF
521 X12(I,I) = ONE
522*
523.GT. IF ( P I ) THEN
524 CALL ZLARF( 'r', P-I, M-Q-I+1, X12(I,I), LDX12, TAUQ2(I),
525 $ X12(I+1,I), LDX12, WORK )
526 END IF
527.GE. IF( M-P-Q 1 )
528 $ CALL ZLARF( 'r', M-P-Q, M-Q-I+1, X12(I,I), LDX12,
529 $ TAUQ2(I), X22(Q+1,I), LDX22, WORK )
530*
531 CALL ZLACGV( M-Q-I+1, X12(I,I), LDX12 )
532*
533 END DO
534*
535* Reduce columns P + 1, ..., M - Q of X12, X22
536*
537 DO I = 1, M - P - Q
538*
539 CALL ZSCAL( M-P-Q-I+1, DCMPLX( Z2*Z4, 0.0D0 ),
540 $ X22(Q+I,P+I), LDX22 )
541 CALL ZLACGV( M-P-Q-I+1, X22(Q+I,P+I), LDX22 )
542 CALL ZLARFGP( M-P-Q-I+1, X22(Q+I,P+I), X22(Q+I,P+I+1),
543 $ LDX22, TAUQ2(P+I) )
544 X22(Q+I,P+I) = ONE
545 CALL ZLARF( 'r', M-P-Q-I, M-P-Q-I+1, X22(Q+I,P+I), LDX22,
546 $ TAUQ2(P+I), X22(Q+I+1,P+I), LDX22, WORK )
547*
548 CALL ZLACGV( M-P-Q-I+1, X22(Q+I,P+I), LDX22 )
549*
550 END DO
551*
552 ELSE
553*
554* Reduce columns 1, ..., Q of X11, X12, X21, X22
555*
556 DO I = 1, Q
557*
558.EQ. IF( I 1 ) THEN
559 CALL ZSCAL( P-I+1, DCMPLX( Z1, 0.0D0 ), X11(I,I),
560 $ LDX11 )
561 ELSE
562 CALL ZSCAL( P-I+1, DCMPLX( Z1*COS(PHI(I-1)), 0.0D0 ),
563 $ X11(I,I), LDX11 )
564 CALL ZAXPY( P-I+1, DCMPLX( -Z1*Z3*Z4*SIN(PHI(I-1)),
565 $ 0.0D0 ), X12(I-1,I), LDX12, X11(I,I), LDX11 )
566 END IF
567.EQ. IF( I 1 ) THEN
568 CALL ZSCAL( M-P-I+1, DCMPLX( Z2, 0.0D0 ), X21(I,I),
569 $ LDX21 )
570 ELSE
571 CALL ZSCAL( M-P-I+1, DCMPLX( Z2*COS(PHI(I-1)), 0.0D0 ),
572 $ X21(I,I), LDX21 )
573 CALL ZAXPY( M-P-I+1, DCMPLX( -Z2*Z3*Z4*SIN(PHI(I-1)),
574 $ 0.0D0 ), X22(I-1,I), LDX22, X21(I,I), LDX21 )
575 END IF
576*
577 THETA(I) = ATAN2( DZNRM2( M-P-I+1, X21(I,I), LDX21 ),
578 $ DZNRM2( P-I+1, X11(I,I), LDX11 ) )
579*
580 CALL ZLACGV( P-I+1, X11(I,I), LDX11 )
581 CALL ZLACGV( M-P-I+1, X21(I,I), LDX21 )
582*
583 CALL ZLARFGP( P-I+1, X11(I,I), X11(I,I+1), LDX11, TAUP1(I) )
584 X11(I,I) = ONE
585.EQ. IF ( I M-P ) THEN
586 CALL ZLARFGP( M-P-I+1, X21(I,I), X21(I,I), LDX21,
587 $ TAUP2(I) )
588 ELSE
589 CALL ZLARFGP( M-P-I+1, X21(I,I), X21(I,I+1), LDX21,
590 $ TAUP2(I) )
591 END IF
592 X21(I,I) = ONE
593*
594 CALL ZLARF( 'r', Q-I, P-I+1, X11(I,I), LDX11, TAUP1(I),
595 $ X11(I+1,I), LDX11, WORK )
596 CALL ZLARF( 'r', M-Q-I+1, P-I+1, X11(I,I), LDX11, TAUP1(I),
597 $ X12(I,I), LDX12, WORK )
598 CALL ZLARF( 'r', Q-I, M-P-I+1, X21(I,I), LDX21, TAUP2(I),
599 $ X21(I+1,I), LDX21, WORK )
600 CALL ZLARF( 'r', M-Q-I+1, M-P-I+1, X21(I,I), LDX21,
601 $ TAUP2(I), X22(I,I), LDX22, WORK )
602*
603 CALL ZLACGV( P-I+1, X11(I,I), LDX11 )
604 CALL ZLACGV( M-P-I+1, X21(I,I), LDX21 )
605*
606.LT. IF( I Q ) THEN
607 CALL ZSCAL( Q-I, DCMPLX( -Z1*Z3*SIN(THETA(I)), 0.0D0 ),
608 $ X11(I+1,I), 1 )
609 CALL ZAXPY( Q-I, DCMPLX( Z2*Z3*COS(THETA(I)), 0.0D0 ),
610 $ X21(I+1,I), 1, X11(I+1,I), 1 )
611 END IF
612 CALL ZSCAL( M-Q-I+1, DCMPLX( -Z1*Z4*SIN(THETA(I)), 0.0D0 ),
613 $ X12(I,I), 1 )
614 CALL ZAXPY( M-Q-I+1, DCMPLX( Z2*Z4*COS(THETA(I)), 0.0D0 ),
615 $ X22(I,I), 1, X12(I,I), 1 )
616*
617.LT. IF( I Q )
618 $ PHI(I) = ATAN2( DZNRM2( Q-I, X11(I+1,I), 1 ),
619 $ DZNRM2( M-Q-I+1, X12(I,I), 1 ) )
620*
621.LT. IF( I Q ) THEN
622 CALL ZLARFGP( Q-I, X11(I+1,I), X11(I+2,I), 1, TAUQ1(I) )
623 X11(I+1,I) = ONE
624 END IF
625 CALL ZLARFGP( M-Q-I+1, X12(I,I), X12(I+1,I), 1, TAUQ2(I) )
626 X12(I,I) = ONE
627*
628.LT. IF( I Q ) THEN
629 CALL ZLARF( 'l', Q-I, P-I, X11(I+1,I), 1,
630 $ DCONJG(TAUQ1(I)), X11(I+1,I+1), LDX11, WORK )
631 CALL ZLARF( 'l', Q-I, M-P-I, X11(I+1,I), 1,
632 $ DCONJG(TAUQ1(I)), X21(I+1,I+1), LDX21, WORK )
633 END IF
634 CALL ZLARF( 'l', M-Q-I+1, P-I, X12(I,I), 1,
635 $ DCONJG(TAUQ2(I)), X12(I,I+1), LDX12, WORK )
636.GT. IF ( M-P I ) THEN
637 CALL ZLARF( 'l', M-Q-I+1, M-P-I, X12(I,I), 1,
638 $ DCONJG(TAUQ2(I)), X22(I,I+1), LDX22, WORK )
639 END IF
640*
641 END DO
642*
643* Reduce columns Q + 1, ..., P of X12, X22
644*
645 DO I = Q + 1, P
646*
647 CALL ZSCAL( M-Q-I+1, DCMPLX( -Z1*Z4, 0.0D0 ), X12(I,I), 1 )
648 CALL ZLARFGP( M-Q-I+1, X12(I,I), X12(I+1,I), 1, TAUQ2(I) )
649 X12(I,I) = ONE
650*
651.GT. IF ( P I ) THEN
652 CALL ZLARF( 'l', m-q-i+1, p-i, x12(i,i), 1,
653 $ dconjg(tauq2(i)), x12(i,i+1), ldx12, work )
654 END IF
655 IF( m-p-q .GE. 1 )
656 $ CALL zlarf( 'L', m-q-i+1, m-p-q, x12(i,i), 1,
657 $ dconjg(tauq2(i)), x22(i,q+1), ldx22, work )
658*
659 END DO
660*
661* Reduce columns P + 1, ..., M - Q of X12, X22
662*
663 DO i = 1, m - p - q
664*
665 CALL zscal( m-p-q-i+1, dcmplx( z2*z4, 0.0d0 ),
666 $ x22(p+i,q+i), 1 )
667 CALL zlarfgp( m-p-q-i+1, x22(p+i,q+i), x22(p+i+1,q+i), 1,
668 $ tauq2(p+i) )
669 x22(p+i,q+i) = one
670*
671 IF ( m-p-q .NE. i ) THEN
672 CALL zlarf( 'L', m-p-q-i+1, m-p-q-i, x22(p+i,q+i), 1,
673 $ dconjg(tauq2(p+i)), x22(p+i,q+i+1), ldx22,
674 $ work )
675 END IF
676*
677 END DO
678*
679 END IF
680*
681 RETURN
682*
683* End of ZUNBDB
684*
685 END
686
subroutine xerbla(srname, info)
XERBLA
Definition xerbla.f:60
subroutine zlarf(side, m, n, v, incv, tau, c, ldc, work)
ZLARF applies an elementary reflector to a general rectangular matrix.
Definition zlarf.f:128
subroutine zlarfgp(n, alpha, x, incx, tau)
ZLARFGP generates an elementary reflector (Householder matrix) with non-negative beta.
Definition zlarfgp.f:104
subroutine zlacgv(n, x, incx)
ZLACGV conjugates a complex vector.
Definition zlacgv.f:74
subroutine zunbdb(trans, signs, m, p, q, x11, ldx11, x12, ldx12, x21, ldx21, x22, ldx22, theta, phi, taup1, taup2, tauq1, tauq2, work, lwork, info)
ZUNBDB
Definition zunbdb.f:287
subroutine zaxpy(n, za, zx, incx, zy, incy)
ZAXPY
Definition zaxpy.f:88
subroutine zscal(n, za, zx, incx)
ZSCAL
Definition zscal.f:78
#define min(a, b)
Definition macros.h:20
#define max(a, b)
Definition macros.h:21