File:  [local] / rpl / lapack / lapack / zlags2.f
Revision 1.8: download - view: text, annotated - select for diffs - revision graph
Fri Jul 22 07:38:17 2011 UTC (12 years, 9 months ago) by bertrand
Branches: MAIN
CVS tags: rpl-4_1_3, rpl-4_1_2, rpl-4_1_1, HEAD
En route vers la 4.4.1.

    1:       SUBROUTINE ZLAGS2( UPPER, A1, A2, A3, B1, B2, B3, CSU, SNU, CSV,
    2:      $                   SNV, CSQ, SNQ )
    3: *
    4: *  -- LAPACK auxiliary routine (version 3.3.1) --
    5: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
    6: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
    7: *  -- April 2011                                                      --
    8: *
    9: *     .. Scalar Arguments ..
   10:       LOGICAL            UPPER
   11:       DOUBLE PRECISION   A1, A3, B1, B3, CSQ, CSU, CSV
   12:       COMPLEX*16         A2, B2, SNQ, SNU, SNV
   13: *     ..
   14: *
   15: *  Purpose
   16: *  =======
   17: *
   18: *  ZLAGS2 computes 2-by-2 unitary matrices U, V and Q, such
   19: *  that if ( UPPER ) then
   20: *
   21: *            U**H *A*Q = U**H *( A1 A2 )*Q = ( x  0  )
   22: *                              ( 0  A3 )     ( x  x  )
   23: *  and
   24: *            V**H*B*Q = V**H *( B1 B2 )*Q = ( x  0  )
   25: *                             ( 0  B3 )     ( x  x  )
   26: *
   27: *  or if ( .NOT.UPPER ) then
   28: *
   29: *            U**H *A*Q = U**H *( A1 0  )*Q = ( x  x  )
   30: *                              ( A2 A3 )     ( 0  x  )
   31: *  and
   32: *            V**H *B*Q = V**H *( B1 0  )*Q = ( x  x  )
   33: *                              ( B2 B3 )     ( 0  x  )
   34: *  where
   35: *
   36: *    U = (   CSU    SNU ), V = (  CSV    SNV ),
   37: *        ( -SNU**H  CSU )      ( -SNV**H CSV )
   38: *
   39: *    Q = (   CSQ    SNQ )
   40: *        ( -SNQ**H  CSQ )
   41: *
   42: *  The rows of the transformed A and B are parallel. Moreover, if the
   43: *  input 2-by-2 matrix A is not zero, then the transformed (1,1) entry
   44: *  of A is not zero. If the input matrices A and B are both not zero,
   45: *  then the transformed (2,2) element of B is not zero, except when the
   46: *  first rows of input A and B are parallel and the second rows are
   47: *  zero.
   48: *
   49: *  Arguments
   50: *  =========
   51: *
   52: *  UPPER   (input) LOGICAL
   53: *          = .TRUE.: the input matrices A and B are upper triangular.
   54: *          = .FALSE.: the input matrices A and B are lower triangular.
   55: *
   56: *  A1      (input) DOUBLE PRECISION
   57: *  A2      (input) COMPLEX*16
   58: *  A3      (input) DOUBLE PRECISION
   59: *          On entry, A1, A2 and A3 are elements of the input 2-by-2
   60: *          upper (lower) triangular matrix A.
   61: *
   62: *  B1      (input) DOUBLE PRECISION
   63: *  B2      (input) COMPLEX*16
   64: *  B3      (input) DOUBLE PRECISION
   65: *          On entry, B1, B2 and B3 are elements of the input 2-by-2
   66: *          upper (lower) triangular matrix B.
   67: *
   68: *  CSU     (output) DOUBLE PRECISION
   69: *  SNU     (output) COMPLEX*16
   70: *          The desired unitary matrix U.
   71: *
   72: *  CSV     (output) DOUBLE PRECISION
   73: *  SNV     (output) COMPLEX*16
   74: *          The desired unitary matrix V.
   75: *
   76: *  CSQ     (output) DOUBLE PRECISION
   77: *  SNQ     (output) COMPLEX*16
   78: *          The desired unitary matrix Q.
   79: *
   80: *  =====================================================================
   81: *
   82: *     .. Parameters ..
   83:       DOUBLE PRECISION   ZERO, ONE
   84:       PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
   85: *     ..
   86: *     .. Local Scalars ..
   87:       DOUBLE PRECISION   A, AUA11, AUA12, AUA21, AUA22, AVB12, AVB11, 
   88:      $                   AVB21, AVB22, CSL, CSR, D, FB, FC, S1, S2, 
   89:      $                   SNL, SNR, UA11R, UA22R, VB11R, VB22R
   90:       COMPLEX*16         B, C, D1, R, T, UA11, UA12, UA21, UA22, VB11,
   91:      $                   VB12, VB21, VB22
   92: *     ..
   93: *     .. External Subroutines ..
   94:       EXTERNAL           DLASV2, ZLARTG
   95: *     ..
   96: *     .. Intrinsic Functions ..
   97:       INTRINSIC          ABS, DBLE, DCMPLX, DCONJG, DIMAG
   98: *     ..
   99: *     .. Statement Functions ..
  100:       DOUBLE PRECISION   ABS1
  101: *     ..
  102: *     .. Statement Function definitions ..
  103:       ABS1( T ) = ABS( DBLE( T ) ) + ABS( DIMAG( T ) )
  104: *     ..
  105: *     .. Executable Statements ..
  106: *
  107:       IF( UPPER ) THEN
  108: *
  109: *        Input matrices A and B are upper triangular matrices
  110: *
  111: *        Form matrix C = A*adj(B) = ( a b )
  112: *                                   ( 0 d )
  113: *
  114:          A = A1*B3
  115:          D = A3*B1
  116:          B = A2*B1 - A1*B2
  117:          FB = ABS( B )
  118: *
  119: *        Transform complex 2-by-2 matrix C to real matrix by unitary
  120: *        diagonal matrix diag(1,D1).
  121: *
  122:          D1 = ONE
  123:          IF( FB.NE.ZERO )
  124:      $      D1 = B / FB
  125: *
  126: *        The SVD of real 2 by 2 triangular C
  127: *
  128: *         ( CSL -SNL )*( A B )*(  CSR  SNR ) = ( R 0 )
  129: *         ( SNL  CSL ) ( 0 D ) ( -SNR  CSR )   ( 0 T )
  130: *
  131:          CALL DLASV2( A, FB, D, S1, S2, SNR, CSR, SNL, CSL )
  132: *
  133:          IF( ABS( CSL ).GE.ABS( SNL ) .OR. ABS( CSR ).GE.ABS( SNR ) )
  134:      $        THEN
  135: *
  136: *           Compute the (1,1) and (1,2) elements of U**H *A and V**H *B,
  137: *           and (1,2) element of |U|**H *|A| and |V|**H *|B|.
  138: *
  139:             UA11R = CSL*A1
  140:             UA12 = CSL*A2 + D1*SNL*A3
  141: *
  142:             VB11R = CSR*B1
  143:             VB12 = CSR*B2 + D1*SNR*B3
  144: *
  145:             AUA12 = ABS( CSL )*ABS1( A2 ) + ABS( SNL )*ABS( A3 )
  146:             AVB12 = ABS( CSR )*ABS1( B2 ) + ABS( SNR )*ABS( B3 )
  147: *
  148: *           zero (1,2) elements of U**H *A and V**H *B
  149: *
  150:             IF( ( ABS( UA11R )+ABS1( UA12 ) ).EQ.ZERO ) THEN
  151:                CALL ZLARTG( -DCMPLX( VB11R ), DCONJG( VB12 ), CSQ, SNQ,
  152:      $                      R )
  153:             ELSE IF( ( ABS( VB11R )+ABS1( VB12 ) ).EQ.ZERO ) THEN
  154:                CALL ZLARTG( -DCMPLX( UA11R ), DCONJG( UA12 ), CSQ, SNQ,
  155:      $                      R )
  156:             ELSE IF( AUA12 / ( ABS( UA11R )+ABS1( UA12 ) ).LE.AVB12 /
  157:      $               ( ABS( VB11R )+ABS1( VB12 ) ) ) THEN
  158:                CALL ZLARTG( -DCMPLX( UA11R ), DCONJG( UA12 ), CSQ, SNQ,
  159:      $                      R )
  160:             ELSE
  161:                CALL ZLARTG( -DCMPLX( VB11R ), DCONJG( VB12 ), CSQ, SNQ,
  162:      $                      R )
  163:             END IF
  164: *
  165:             CSU = CSL
  166:             SNU = -D1*SNL
  167:             CSV = CSR
  168:             SNV = -D1*SNR
  169: *
  170:          ELSE
  171: *
  172: *           Compute the (2,1) and (2,2) elements of U**H *A and V**H *B,
  173: *           and (2,2) element of |U|**H *|A| and |V|**H *|B|.
  174: *
  175:             UA21 = -DCONJG( D1 )*SNL*A1
  176:             UA22 = -DCONJG( D1 )*SNL*A2 + CSL*A3
  177: *
  178:             VB21 = -DCONJG( D1 )*SNR*B1
  179:             VB22 = -DCONJG( D1 )*SNR*B2 + CSR*B3
  180: *
  181:             AUA22 = ABS( SNL )*ABS1( A2 ) + ABS( CSL )*ABS( A3 )
  182:             AVB22 = ABS( SNR )*ABS1( B2 ) + ABS( CSR )*ABS( B3 )
  183: *
  184: *           zero (2,2) elements of U**H *A and V**H *B, and then swap.
  185: *
  186:             IF( ( ABS1( UA21 )+ABS1( UA22 ) ).EQ.ZERO ) THEN
  187:                CALL ZLARTG( -DCONJG( VB21 ), DCONJG( VB22 ), CSQ, SNQ,
  188:      $                      R )
  189:             ELSE IF( ( ABS1( VB21 )+ABS( VB22 ) ).EQ.ZERO ) THEN
  190:                CALL ZLARTG( -DCONJG( UA21 ), DCONJG( UA22 ), CSQ, SNQ,
  191:      $                      R )
  192:             ELSE IF( AUA22 / ( ABS1( UA21 )+ABS1( UA22 ) ).LE.AVB22 /
  193:      $               ( ABS1( VB21 )+ABS1( VB22 ) ) ) THEN
  194:                CALL ZLARTG( -DCONJG( UA21 ), DCONJG( UA22 ), CSQ, SNQ,
  195:      $                      R )
  196:             ELSE
  197:                CALL ZLARTG( -DCONJG( VB21 ), DCONJG( VB22 ), CSQ, SNQ,
  198:      $                      R )
  199:             END IF
  200: *
  201:             CSU = SNL
  202:             SNU = D1*CSL
  203:             CSV = SNR
  204:             SNV = D1*CSR
  205: *
  206:          END IF
  207: *
  208:       ELSE
  209: *
  210: *        Input matrices A and B are lower triangular matrices
  211: *
  212: *        Form matrix C = A*adj(B) = ( a 0 )
  213: *                                   ( c d )
  214: *
  215:          A = A1*B3
  216:          D = A3*B1
  217:          C = A2*B3 - A3*B2
  218:          FC = ABS( C )
  219: *
  220: *        Transform complex 2-by-2 matrix C to real matrix by unitary
  221: *        diagonal matrix diag(d1,1).
  222: *
  223:          D1 = ONE
  224:          IF( FC.NE.ZERO )
  225:      $      D1 = C / FC
  226: *
  227: *        The SVD of real 2 by 2 triangular C
  228: *
  229: *         ( CSL -SNL )*( A 0 )*(  CSR  SNR ) = ( R 0 )
  230: *         ( SNL  CSL ) ( C D ) ( -SNR  CSR )   ( 0 T )
  231: *
  232:          CALL DLASV2( A, FC, D, S1, S2, SNR, CSR, SNL, CSL )
  233: *
  234:          IF( ABS( CSR ).GE.ABS( SNR ) .OR. ABS( CSL ).GE.ABS( SNL ) )
  235:      $        THEN
  236: *
  237: *           Compute the (2,1) and (2,2) elements of U**H *A and V**H *B,
  238: *           and (2,1) element of |U|**H *|A| and |V|**H *|B|.
  239: *
  240:             UA21 = -D1*SNR*A1 + CSR*A2
  241:             UA22R = CSR*A3
  242: *
  243:             VB21 = -D1*SNL*B1 + CSL*B2
  244:             VB22R = CSL*B3
  245: *
  246:             AUA21 = ABS( SNR )*ABS( A1 ) + ABS( CSR )*ABS1( A2 )
  247:             AVB21 = ABS( SNL )*ABS( B1 ) + ABS( CSL )*ABS1( B2 )
  248: *
  249: *           zero (2,1) elements of U**H *A and V**H *B.
  250: *
  251:             IF( ( ABS1( UA21 )+ABS( UA22R ) ).EQ.ZERO ) THEN
  252:                CALL ZLARTG( DCMPLX( VB22R ), VB21, CSQ, SNQ, R )
  253:             ELSE IF( ( ABS1( VB21 )+ABS( VB22R ) ).EQ.ZERO ) THEN
  254:                CALL ZLARTG( DCMPLX( UA22R ), UA21, CSQ, SNQ, R )
  255:             ELSE IF( AUA21 / ( ABS1( UA21 )+ABS( UA22R ) ).LE.AVB21 /
  256:      $               ( ABS1( VB21 )+ABS( VB22R ) ) ) THEN
  257:                CALL ZLARTG( DCMPLX( UA22R ), UA21, CSQ, SNQ, R )
  258:             ELSE
  259:                CALL ZLARTG( DCMPLX( VB22R ), VB21, CSQ, SNQ, R )
  260:             END IF
  261: *
  262:             CSU = CSR
  263:             SNU = -DCONJG( D1 )*SNR
  264:             CSV = CSL
  265:             SNV = -DCONJG( D1 )*SNL
  266: *
  267:          ELSE
  268: *
  269: *           Compute the (1,1) and (1,2) elements of U**H *A and V**H *B,
  270: *           and (1,1) element of |U|**H *|A| and |V|**H *|B|.
  271: *
  272:             UA11 = CSR*A1 + DCONJG( D1 )*SNR*A2
  273:             UA12 = DCONJG( D1 )*SNR*A3
  274: *
  275:             VB11 = CSL*B1 + DCONJG( D1 )*SNL*B2
  276:             VB12 = DCONJG( D1 )*SNL*B3
  277: *
  278:             AUA11 = ABS( CSR )*ABS( A1 ) + ABS( SNR )*ABS1( A2 )
  279:             AVB11 = ABS( CSL )*ABS( B1 ) + ABS( SNL )*ABS1( B2 )
  280: *
  281: *           zero (1,1) elements of U**H *A and V**H *B, and then swap.
  282: *
  283:             IF( ( ABS1( UA11 )+ABS1( UA12 ) ).EQ.ZERO ) THEN
  284:                CALL ZLARTG( VB12, VB11, CSQ, SNQ, R )
  285:             ELSE IF( ( ABS1( VB11 )+ABS1( VB12 ) ).EQ.ZERO ) THEN
  286:                CALL ZLARTG( UA12, UA11, CSQ, SNQ, R )
  287:             ELSE IF( AUA11 / ( ABS1( UA11 )+ABS1( UA12 ) ).LE.AVB11 /
  288:      $               ( ABS1( VB11 )+ABS1( VB12 ) ) ) THEN
  289:                CALL ZLARTG( UA12, UA11, CSQ, SNQ, R )
  290:             ELSE
  291:                CALL ZLARTG( VB12, VB11, CSQ, SNQ, R )
  292:             END IF
  293: *
  294:             CSU = SNR
  295:             SNU = DCONJG( D1 )*CSR
  296:             CSV = SNL
  297:             SNV = DCONJG( D1 )*CSL
  298: *
  299:          END IF
  300: *
  301:       END IF
  302: *
  303:       RETURN
  304: *
  305: *     End of ZLAGS2
  306: *
  307:       END

CVSweb interface <joel.bertrand@systella.fr>