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*> \date November 2013 259* 260*> \ingroup complex16OTHERcomputational 261* 262*> \par Further Details: 263* ===================== 264*> 265*> \verbatim 266*> 267*> The bidiagonal blocks B11, B12, B21, and B22 are represented 268*> implicitly by angles THETA(1), ..., THETA(Q) and PHI(1), ..., 269*> PHI(Q-1). B11 and B21 are upper bidiagonal, while B21 and B22 are 270*> lower bidiagonal. Every entry in each bidiagonal band is a product 271*> of a sine or cosine of a THETA with a sine or cosine of a PHI. See 272*> [1] or ZUNCSD for details. 273*> 274*> P1, P2, Q1, and Q2 are represented as products of elementary 275*> reflectors. See ZUNCSD for details on generating P1, P2, Q1, and Q2 276*> using ZUNGQR and ZUNGLQ. 277*> \endverbatim 278* 279*> \par References: 280* ================ 281*> 282*> [1] Brian D. Sutton. Computing the complete CS decomposition. Numer. 283*> Algorithms, 50(1):33-65, 2009. 284*> 285* ===================================================================== 286 SUBROUTINE ZUNBDB( TRANS, SIGNS, M, P, Q, X11, LDX11, X12, LDX12, 287 $ X21, LDX21, X22, LDX22, THETA, PHI, TAUP1, 288 $ TAUP2, TAUQ1, TAUQ2, WORK, LWORK, INFO ) 289* 290* -- LAPACK computational routine (version 3.5.0) -- 291* -- LAPACK is a software package provided by Univ. of Tennessee, -- 292* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- 293* November 2013 294* 295* .. Scalar Arguments .. 296 CHARACTER SIGNS, TRANS 297 INTEGER INFO, LDX11, LDX12, LDX21, LDX22, LWORK, M, P, 298 $ Q 299* .. 300* .. Array Arguments .. 301 DOUBLE PRECISION PHI( * ), THETA( * ) 302 COMPLEX*16 TAUP1( * ), TAUP2( * ), TAUQ1( * ), TAUQ2( * ), 303 $ WORK( * ), X11( LDX11, * ), X12( LDX12, * ), 304 $ X21( LDX21, * ), X22( LDX22, * ) 305* .. 306* 307* ==================================================================== 308* 309* .. Parameters .. 310 DOUBLE PRECISION REALONE 311 PARAMETER ( REALONE = 1.0D0 ) 312 COMPLEX*16 ONE 313 PARAMETER ( ONE = (1.0D0,0.0D0) ) 314* .. 315* .. Local Scalars .. 316 LOGICAL COLMAJOR, LQUERY 317 INTEGER I, LWORKMIN, LWORKOPT, PI1, QI1 318 DOUBLE PRECISION Z1, Z2, Z3, Z4 319* .. 320* .. External Subroutines .. 321 EXTERNAL ZAXPY, ZLARF, ZLARFGP, ZSCAL, XERBLA 322 EXTERNAL ZLACGV 323* 324* .. 325* .. External Functions .. 326 DOUBLE PRECISION DZNRM2 327 LOGICAL LSAME 328 EXTERNAL DZNRM2, LSAME 329* .. 330* .. Intrinsic Functions 331 INTRINSIC ATAN2, COS, MAX, MIN, SIN 332 INTRINSIC DCMPLX, DCONJG 333* .. 334* .. Executable Statements .. 335* 336* Test input arguments 337* 338 INFO = 0 339 COLMAJOR = .NOT. LSAME( TRANS, 'T' ) 340 IF( .NOT. LSAME( SIGNS, 'O' ) ) THEN 341 Z1 = REALONE 342 Z2 = REALONE 343 Z3 = REALONE 344 Z4 = REALONE 345 ELSE 346 Z1 = REALONE 347 Z2 = -REALONE 348 Z3 = REALONE 349 Z4 = -REALONE 350 END IF 351 LQUERY = LWORK .EQ. -1 352* 353 IF( M .LT. 0 ) THEN 354 INFO = -3 355 ELSE IF( P .LT. 0 .OR. P .GT. M ) THEN 356 INFO = -4 357 ELSE IF( Q .LT. 0 .OR. Q .GT. P .OR. Q .GT. M-P .OR. 358 $ Q .GT. M-Q ) THEN 359 INFO = -5 360 ELSE IF( COLMAJOR .AND. LDX11 .LT. MAX( 1, P ) ) THEN 361 INFO = -7 362 ELSE IF( .NOT.COLMAJOR .AND. LDX11 .LT. MAX( 1, Q ) ) THEN 363 INFO = -7 364 ELSE IF( COLMAJOR .AND. LDX12 .LT. MAX( 1, P ) ) THEN 365 INFO = -9 366 ELSE IF( .NOT.COLMAJOR .AND. LDX12 .LT. MAX( 1, M-Q ) ) THEN 367 INFO = -9 368 ELSE IF( COLMAJOR .AND. LDX21 .LT. MAX( 1, M-P ) ) THEN 369 INFO = -11 370 ELSE IF( .NOT.COLMAJOR .AND. LDX21 .LT. MAX( 1, Q ) ) THEN 371 INFO = -11 372 ELSE IF( COLMAJOR .AND. LDX22 .LT. MAX( 1, M-P ) ) THEN 373 INFO = -13 374 ELSE IF( .NOT.COLMAJOR .AND. LDX22 .LT. MAX( 1, M-Q ) ) THEN 375 INFO = -13 376 END IF 377* 378* Compute workspace 379* 380 IF( INFO .EQ. 0 ) THEN 381 LWORKOPT = M - Q 382 LWORKMIN = M - Q 383 WORK(1) = LWORKOPT 384 IF( LWORK .LT. LWORKMIN .AND. .NOT. LQUERY ) THEN 385 INFO = -21 386 END IF 387 END IF 388 IF( INFO .NE. 0 ) THEN 389 CALL XERBLA( 'xORBDB', -INFO ) 390 RETURN 391 ELSE IF( LQUERY ) THEN 392 RETURN 393 END IF 394* 395* Handle column-major and row-major separately 396* 397 IF( COLMAJOR ) THEN 398* 399* Reduce columns 1, ..., Q of X11, X12, X21, and X22 400* 401 DO I = 1, Q 402* 403 IF( I .EQ. 1 ) THEN 404 CALL ZSCAL( P-I+1, DCMPLX( Z1, 0.0D0 ), X11(I,I), 1 ) 405 ELSE 406 CALL ZSCAL( P-I+1, DCMPLX( Z1*COS(PHI(I-1)), 0.0D0 ), 407 $ X11(I,I), 1 ) 408 CALL ZAXPY( P-I+1, DCMPLX( -Z1*Z3*Z4*SIN(PHI(I-1)), 409 $ 0.0D0 ), X12(I,I-1), 1, X11(I,I), 1 ) 410 END IF 411 IF( I .EQ. 1 ) THEN 412 CALL ZSCAL( M-P-I+1, DCMPLX( Z2, 0.0D0 ), X21(I,I), 1 ) 413 ELSE 414 CALL ZSCAL( M-P-I+1, DCMPLX( Z2*COS(PHI(I-1)), 0.0D0 ), 415 $ X21(I,I), 1 ) 416 CALL ZAXPY( M-P-I+1, DCMPLX( -Z2*Z3*Z4*SIN(PHI(I-1)), 417 $ 0.0D0 ), X22(I,I-1), 1, X21(I,I), 1 ) 418 END IF 419* 420 THETA(I) = ATAN2( DZNRM2( M-P-I+1, X21(I,I), 1 ), 421 $ DZNRM2( P-I+1, X11(I,I), 1 ) ) 422* 423 IF( P .GT. I ) THEN 424 CALL ZLARFGP( P-I+1, X11(I,I), X11(I+1,I), 1, TAUP1(I) ) 425 ELSE IF ( P .EQ. I ) THEN 426 CALL ZLARFGP( P-I+1, X11(I,I), X11(I,I), 1, TAUP1(I) ) 427 END IF 428 X11(I,I) = ONE 429 IF ( M-P .GT. I ) THEN 430 CALL ZLARFGP( M-P-I+1, X21(I,I), X21(I+1,I), 1, 431 $ TAUP2(I) ) 432 ELSE IF ( M-P .EQ. I ) THEN 433 CALL ZLARFGP( M-P-I+1, X21(I,I), X21(I,I), 1, 434 $ TAUP2(I) ) 435 END IF 436 X21(I,I) = ONE 437* 438 IF ( Q .GT. I ) THEN 439 CALL ZLARF( 'L', P-I+1, Q-I, X11(I,I), 1, 440 $ DCONJG(TAUP1(I)), X11(I,I+1), LDX11, WORK ) 441 CALL ZLARF( 'L', M-P-I+1, Q-I, X21(I,I), 1, 442 $ DCONJG(TAUP2(I)), X21(I,I+1), LDX21, WORK ) 443 END IF 444 IF ( M-Q+1 .GT. I ) THEN 445 CALL ZLARF( 'L', P-I+1, M-Q-I+1, X11(I,I), 1, 446 $ DCONJG(TAUP1(I)), X12(I,I), LDX12, WORK ) 447 CALL ZLARF( 'L', M-P-I+1, M-Q-I+1, X21(I,I), 1, 448 $ DCONJG(TAUP2(I)), X22(I,I), LDX22, WORK ) 449 END IF 450* 451 IF( I .LT. Q ) THEN 452 CALL ZSCAL( Q-I, DCMPLX( -Z1*Z3*SIN(THETA(I)), 0.0D0 ), 453 $ X11(I,I+1), LDX11 ) 454 CALL ZAXPY( Q-I, DCMPLX( Z2*Z3*COS(THETA(I)), 0.0D0 ), 455 $ X21(I,I+1), LDX21, X11(I,I+1), LDX11 ) 456 END IF 457 CALL ZSCAL( M-Q-I+1, DCMPLX( -Z1*Z4*SIN(THETA(I)), 0.0D0 ), 458 $ X12(I,I), LDX12 ) 459 CALL ZAXPY( M-Q-I+1, DCMPLX( Z2*Z4*COS(THETA(I)), 0.0D0 ), 460 $ X22(I,I), LDX22, X12(I,I), LDX12 ) 461* 462 IF( I .LT. Q ) 463 $ PHI(I) = ATAN2( DZNRM2( Q-I, X11(I,I+1), LDX11 ), 464 $ DZNRM2( M-Q-I+1, X12(I,I), LDX12 ) ) 465* 466 IF( I .LT. Q ) THEN 467 CALL ZLACGV( Q-I, X11(I,I+1), LDX11 ) 468 IF ( I .EQ. Q-1 ) THEN 469 CALL ZLARFGP( Q-I, X11(I,I+1), X11(I,I+1), LDX11, 470 $ TAUQ1(I) ) 471 ELSE 472 CALL ZLARFGP( Q-I, X11(I,I+1), X11(I,I+2), LDX11, 473 $ TAUQ1(I) ) 474 END IF 475 X11(I,I+1) = ONE 476 END IF 477 IF ( M-Q+1 .GT. I ) THEN 478 CALL ZLACGV( M-Q-I+1, X12(I,I), LDX12 ) 479 IF ( M-Q .EQ. I ) THEN 480 CALL ZLARFGP( M-Q-I+1, X12(I,I), X12(I,I), LDX12, 481 $ TAUQ2(I) ) 482 ELSE 483 CALL ZLARFGP( M-Q-I+1, X12(I,I), X12(I,I+1), LDX12, 484 $ TAUQ2(I) ) 485 END IF 486 END IF 487 X12(I,I) = ONE 488* 489 IF( I .LT. Q ) THEN 490 CALL ZLARF( 'R', P-I, Q-I, X11(I,I+1), LDX11, TAUQ1(I), 491 $ X11(I+1,I+1), LDX11, WORK ) 492 CALL ZLARF( 'R', M-P-I, Q-I, X11(I,I+1), LDX11, TAUQ1(I), 493 $ X21(I+1,I+1), LDX21, WORK ) 494 END IF 495 IF ( P .GT. I ) THEN 496 CALL ZLARF( 'R', P-I, M-Q-I+1, X12(I,I), LDX12, TAUQ2(I), 497 $ X12(I+1,I), LDX12, WORK ) 498 END IF 499 IF ( M-P .GT. I ) THEN 500 CALL ZLARF( 'R', M-P-I, M-Q-I+1, X12(I,I), LDX12, 501 $ TAUQ2(I), X22(I+1,I), LDX22, WORK ) 502 END IF 503* 504 IF( I .LT. Q ) 505 $ CALL ZLACGV( Q-I, X11(I,I+1), LDX11 ) 506 CALL ZLACGV( M-Q-I+1, X12(I,I), LDX12 ) 507* 508 END DO 509* 510* Reduce columns Q + 1, ..., P of X12, X22 511* 512 DO I = Q + 1, P 513* 514 CALL ZSCAL( M-Q-I+1, DCMPLX( -Z1*Z4, 0.0D0 ), X12(I,I), 515 $ LDX12 ) 516 CALL ZLACGV( M-Q-I+1, X12(I,I), LDX12 ) 517 IF ( I .GE. M-Q ) THEN 518 CALL ZLARFGP( M-Q-I+1, X12(I,I), X12(I,I), LDX12, 519 $ TAUQ2(I) ) 520 ELSE 521 CALL ZLARFGP( M-Q-I+1, X12(I,I), X12(I,I+1), LDX12, 522 $ TAUQ2(I) ) 523 END IF 524 X12(I,I) = ONE 525* 526 IF ( P .GT. I ) THEN 527 CALL ZLARF( 'R', P-I, M-Q-I+1, X12(I,I), LDX12, TAUQ2(I), 528 $ X12(I+1,I), LDX12, WORK ) 529 END IF 530 IF( M-P-Q .GE. 1 ) 531 $ CALL ZLARF( 'R', M-P-Q, M-Q-I+1, X12(I,I), LDX12, 532 $ TAUQ2(I), X22(Q+1,I), LDX22, WORK ) 533* 534 CALL ZLACGV( M-Q-I+1, X12(I,I), LDX12 ) 535* 536 END DO 537* 538* Reduce columns P + 1, ..., M - Q of X12, X22 539* 540 DO I = 1, M - P - Q 541* 542 CALL ZSCAL( M-P-Q-I+1, DCMPLX( Z2*Z4, 0.0D0 ), 543 $ X22(Q+I,P+I), LDX22 ) 544 CALL ZLACGV( M-P-Q-I+1, X22(Q+I,P+I), LDX22 ) 545 CALL ZLARFGP( M-P-Q-I+1, X22(Q+I,P+I), X22(Q+I,P+I+1), 546 $ LDX22, TAUQ2(P+I) ) 547 X22(Q+I,P+I) = ONE 548 CALL ZLARF( 'R', M-P-Q-I, M-P-Q-I+1, X22(Q+I,P+I), LDX22, 549 $ TAUQ2(P+I), X22(Q+I+1,P+I), LDX22, WORK ) 550* 551 CALL ZLACGV( M-P-Q-I+1, X22(Q+I,P+I), LDX22 ) 552* 553 END DO 554* 555 ELSE 556* 557* Reduce columns 1, ..., Q of X11, X12, X21, X22 558* 559 DO I = 1, Q 560* 561 IF( I .EQ. 1 ) THEN 562 CALL ZSCAL( P-I+1, DCMPLX( Z1, 0.0D0 ), X11(I,I), 563 $ LDX11 ) 564 ELSE 565 CALL ZSCAL( P-I+1, DCMPLX( Z1*COS(PHI(I-1)), 0.0D0 ), 566 $ X11(I,I), LDX11 ) 567 CALL ZAXPY( P-I+1, DCMPLX( -Z1*Z3*Z4*SIN(PHI(I-1)), 568 $ 0.0D0 ), X12(I-1,I), LDX12, X11(I,I), LDX11 ) 569 END IF 570 IF( I .EQ. 1 ) THEN 571 CALL ZSCAL( M-P-I+1, DCMPLX( Z2, 0.0D0 ), X21(I,I), 572 $ LDX21 ) 573 ELSE 574 CALL ZSCAL( M-P-I+1, DCMPLX( Z2*COS(PHI(I-1)), 0.0D0 ), 575 $ X21(I,I), LDX21 ) 576 CALL ZAXPY( M-P-I+1, DCMPLX( -Z2*Z3*Z4*SIN(PHI(I-1)), 577 $ 0.0D0 ), X22(I-1,I), LDX22, X21(I,I), LDX21 ) 578 END IF 579* 580 THETA(I) = ATAN2( DZNRM2( M-P-I+1, X21(I,I), LDX21 ), 581 $ DZNRM2( P-I+1, X11(I,I), LDX11 ) ) 582* 583 CALL ZLACGV( P-I+1, X11(I,I), LDX11 ) 584 CALL ZLACGV( M-P-I+1, X21(I,I), LDX21 ) 585* 586 CALL ZLARFGP( P-I+1, X11(I,I), X11(I,I+1), LDX11, TAUP1(I) ) 587 X11(I,I) = ONE 588 IF ( I .EQ. M-P ) THEN 589 CALL ZLARFGP( M-P-I+1, X21(I,I), X21(I,I), LDX21, 590 $ TAUP2(I) ) 591 ELSE 592 CALL ZLARFGP( M-P-I+1, X21(I,I), X21(I,I+1), LDX21, 593 $ TAUP2(I) ) 594 END IF 595 X21(I,I) = ONE 596* 597 CALL ZLARF( 'R', Q-I, P-I+1, X11(I,I), LDX11, TAUP1(I), 598 $ X11(I+1,I), LDX11, WORK ) 599 CALL ZLARF( 'R', M-Q-I+1, P-I+1, X11(I,I), LDX11, TAUP1(I), 600 $ X12(I,I), LDX12, WORK ) 601 CALL ZLARF( 'R', Q-I, M-P-I+1, X21(I,I), LDX21, TAUP2(I), 602 $ X21(I+1,I), LDX21, WORK ) 603 CALL ZLARF( 'R', M-Q-I+1, M-P-I+1, X21(I,I), LDX21, 604 $ TAUP2(I), X22(I,I), LDX22, WORK ) 605* 606 CALL ZLACGV( P-I+1, X11(I,I), LDX11 ) 607 CALL ZLACGV( M-P-I+1, X21(I,I), LDX21 ) 608* 609 IF( I .LT. Q ) THEN 610 CALL ZSCAL( Q-I, DCMPLX( -Z1*Z3*SIN(THETA(I)), 0.0D0 ), 611 $ X11(I+1,I), 1 ) 612 CALL ZAXPY( Q-I, DCMPLX( Z2*Z3*COS(THETA(I)), 0.0D0 ), 613 $ X21(I+1,I), 1, X11(I+1,I), 1 ) 614 END IF 615 CALL ZSCAL( M-Q-I+1, DCMPLX( -Z1*Z4*SIN(THETA(I)), 0.0D0 ), 616 $ X12(I,I), 1 ) 617 CALL ZAXPY( M-Q-I+1, DCMPLX( Z2*Z4*COS(THETA(I)), 0.0D0 ), 618 $ X22(I,I), 1, X12(I,I), 1 ) 619* 620 IF( I .LT. Q ) 621 $ PHI(I) = ATAN2( DZNRM2( Q-I, X11(I+1,I), 1 ), 622 $ DZNRM2( M-Q-I+1, X12(I,I), 1 ) ) 623* 624 IF( I .LT. Q ) THEN 625 CALL ZLARFGP( Q-I, X11(I+1,I), X11(I+2,I), 1, TAUQ1(I) ) 626 X11(I+1,I) = ONE 627 END IF 628 CALL ZLARFGP( M-Q-I+1, X12(I,I), X12(I+1,I), 1, TAUQ2(I) ) 629 X12(I,I) = ONE 630* 631 IF( I .LT. Q ) THEN 632 CALL ZLARF( 'L', Q-I, P-I, X11(I+1,I), 1, 633 $ DCONJG(TAUQ1(I)), X11(I+1,I+1), LDX11, WORK ) 634 CALL ZLARF( 'L', Q-I, M-P-I, X11(I+1,I), 1, 635 $ DCONJG(TAUQ1(I)), X21(I+1,I+1), LDX21, WORK ) 636 END IF 637 CALL ZLARF( 'L', M-Q-I+1, P-I, X12(I,I), 1, 638 $ DCONJG(TAUQ2(I)), X12(I,I+1), LDX12, WORK ) 639 IF ( M-P .GT. I ) THEN 640 CALL ZLARF( 'L', M-Q-I+1, M-P-I, X12(I,I), 1, 641 $ DCONJG(TAUQ2(I)), X22(I,I+1), LDX22, WORK ) 642 END IF 643* 644 END DO 645* 646* Reduce columns Q + 1, ..., P of X12, X22 647* 648 DO I = Q + 1, P 649* 650 CALL ZSCAL( M-Q-I+1, DCMPLX( -Z1*Z4, 0.0D0 ), X12(I,I), 1 ) 651 CALL ZLARFGP( M-Q-I+1, X12(I,I), X12(I+1,I), 1, TAUQ2(I) ) 652 X12(I,I) = ONE 653* 654 IF ( P .GT. I ) THEN 655 CALL ZLARF( 'L', M-Q-I+1, P-I, X12(I,I), 1, 656 $ DCONJG(TAUQ2(I)), X12(I,I+1), LDX12, WORK ) 657 END IF 658 IF( M-P-Q .GE. 1 ) 659 $ CALL ZLARF( 'L', M-Q-I+1, M-P-Q, X12(I,I), 1, 660 $ DCONJG(TAUQ2(I)), X22(I,Q+1), LDX22, WORK ) 661* 662 END DO 663* 664* Reduce columns P + 1, ..., M - Q of X12, X22 665* 666 DO I = 1, M - P - Q 667* 668 CALL ZSCAL( M-P-Q-I+1, DCMPLX( Z2*Z4, 0.0D0 ), 669 $ X22(P+I,Q+I), 1 ) 670 CALL ZLARFGP( M-P-Q-I+1, X22(P+I,Q+I), X22(P+I+1,Q+I), 1, 671 $ TAUQ2(P+I) ) 672 X22(P+I,Q+I) = ONE 673* 674 IF ( M-P-Q .NE. I ) THEN 675 CALL ZLARF( 'L', M-P-Q-I+1, M-P-Q-I, X22(P+I,Q+I), 1, 676 $ DCONJG(TAUQ2(P+I)), X22(P+I,Q+I+1), LDX22, 677 $ WORK ) 678 END IF 679* 680 END DO 681* 682 END IF 683* 684 RETURN 685* 686* End of ZUNBDB 687* 688 END 689 690