LAPACK 3.3.0

dlags2.f

Go to the documentation of this file.
00001       SUBROUTINE DLAGS2( UPPER, A1, A2, A3, B1, B2, B3, CSU, SNU, CSV,
00002      $                   SNV, CSQ, SNQ )
00003 *
00004 *  -- LAPACK auxiliary routine (version 3.2) --
00005 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00006 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00007 *     November 2006
00008 *
00009 *     .. Scalar Arguments ..
00010       LOGICAL            UPPER
00011       DOUBLE PRECISION   A1, A2, A3, B1, B2, B3, CSQ, CSU, CSV, SNQ,
00012      $                   SNU, SNV
00013 *     ..
00014 *
00015 *  Purpose
00016 *  =======
00017 *
00018 *  DLAGS2 computes 2-by-2 orthogonal matrices U, V and Q, such
00019 *  that if ( UPPER ) then
00020 *
00021 *            U'*A*Q = U'*( A1 A2 )*Q = ( x  0  )
00022 *                        ( 0  A3 )     ( x  x  )
00023 *  and
00024 *            V'*B*Q = V'*( B1 B2 )*Q = ( x  0  )
00025 *                        ( 0  B3 )     ( x  x  )
00026 *
00027 *  or if ( .NOT.UPPER ) then
00028 *
00029 *            U'*A*Q = U'*( A1 0  )*Q = ( x  x  )
00030 *                        ( A2 A3 )     ( 0  x  )
00031 *  and
00032 *            V'*B*Q = V'*( B1 0  )*Q = ( x  x  )
00033 *                        ( B2 B3 )     ( 0  x  )
00034 *
00035 *  The rows of the transformed A and B are parallel, where
00036 *
00037 *    U = (  CSU  SNU ), V = (  CSV SNV ), Q = (  CSQ   SNQ )
00038 *        ( -SNU  CSU )      ( -SNV CSV )      ( -SNQ   CSQ )
00039 *
00040 *  Z' denotes the transpose of Z.
00041 *
00042 *
00043 *  Arguments
00044 *  =========
00045 *
00046 *  UPPER   (input) LOGICAL
00047 *          = .TRUE.: the input matrices A and B are upper triangular.
00048 *          = .FALSE.: the input matrices A and B are lower triangular.
00049 *
00050 *  A1      (input) DOUBLE PRECISION
00051 *  A2      (input) DOUBLE PRECISION
00052 *  A3      (input) DOUBLE PRECISION
00053 *          On entry, A1, A2 and A3 are elements of the input 2-by-2
00054 *          upper (lower) triangular matrix A.
00055 *
00056 *  B1      (input) DOUBLE PRECISION
00057 *  B2      (input) DOUBLE PRECISION
00058 *  B3      (input) DOUBLE PRECISION
00059 *          On entry, B1, B2 and B3 are elements of the input 2-by-2
00060 *          upper (lower) triangular matrix B.
00061 *
00062 *  CSU     (output) DOUBLE PRECISION
00063 *  SNU     (output) DOUBLE PRECISION
00064 *          The desired orthogonal matrix U.
00065 *
00066 *  CSV     (output) DOUBLE PRECISION
00067 *  SNV     (output) DOUBLE PRECISION
00068 *          The desired orthogonal matrix V.
00069 *
00070 *  CSQ     (output) DOUBLE PRECISION
00071 *  SNQ     (output) DOUBLE PRECISION
00072 *          The desired orthogonal matrix Q.
00073 *
00074 *  =====================================================================
00075 *
00076 *     .. Parameters ..
00077       DOUBLE PRECISION   ZERO
00078       PARAMETER          ( ZERO = 0.0D+0 )
00079 *     ..
00080 *     .. Local Scalars ..
00081       DOUBLE PRECISION   A, AUA11, AUA12, AUA21, AUA22, AVB11, AVB12,
00082      $                   AVB21, AVB22, B, C, CSL, CSR, D, R, S1, S2,
00083      $                   SNL, SNR, UA11, UA11R, UA12, UA21, UA22, UA22R,
00084      $                   VB11, VB11R, VB12, VB21, VB22, VB22R
00085 *     ..
00086 *     .. External Subroutines ..
00087       EXTERNAL           DLARTG, DLASV2
00088 *     ..
00089 *     .. Intrinsic Functions ..
00090       INTRINSIC          ABS
00091 *     ..
00092 *     .. Executable Statements ..
00093 *
00094       IF( UPPER ) THEN
00095 *
00096 *        Input matrices A and B are upper triangular matrices
00097 *
00098 *        Form matrix C = A*adj(B) = ( a b )
00099 *                                   ( 0 d )
00100 *
00101          A = A1*B3
00102          D = A3*B1
00103          B = A2*B1 - A1*B2
00104 *
00105 *        The SVD of real 2-by-2 triangular C
00106 *
00107 *         ( CSL -SNL )*( A B )*(  CSR  SNR ) = ( R 0 )
00108 *         ( SNL  CSL ) ( 0 D ) ( -SNR  CSR )   ( 0 T )
00109 *
00110          CALL DLASV2( A, B, D, S1, S2, SNR, CSR, SNL, CSL )
00111 *
00112          IF( ABS( CSL ).GE.ABS( SNL ) .OR. ABS( CSR ).GE.ABS( SNR ) )
00113      $        THEN
00114 *
00115 *           Compute the (1,1) and (1,2) elements of U'*A and V'*B,
00116 *           and (1,2) element of |U|'*|A| and |V|'*|B|.
00117 *
00118             UA11R = CSL*A1
00119             UA12 = CSL*A2 + SNL*A3
00120 *
00121             VB11R = CSR*B1
00122             VB12 = CSR*B2 + SNR*B3
00123 *
00124             AUA12 = ABS( CSL )*ABS( A2 ) + ABS( SNL )*ABS( A3 )
00125             AVB12 = ABS( CSR )*ABS( B2 ) + ABS( SNR )*ABS( B3 )
00126 *
00127 *           zero (1,2) elements of U'*A and V'*B
00128 *
00129             IF( ( ABS( UA11R )+ABS( UA12 ) ).NE.ZERO ) THEN
00130                IF( AUA12 / ( ABS( UA11R )+ABS( UA12 ) ).LE.AVB12 /
00131      $             ( ABS( VB11R )+ABS( VB12 ) ) ) THEN
00132                   CALL DLARTG( -UA11R, UA12, CSQ, SNQ, R )
00133                ELSE
00134                   CALL DLARTG( -VB11R, VB12, CSQ, SNQ, R )
00135                END IF
00136             ELSE
00137                CALL DLARTG( -VB11R, VB12, CSQ, SNQ, R )
00138             END IF
00139 *
00140             CSU = CSL
00141             SNU = -SNL
00142             CSV = CSR
00143             SNV = -SNR
00144 *
00145          ELSE
00146 *
00147 *           Compute the (2,1) and (2,2) elements of U'*A and V'*B,
00148 *           and (2,2) element of |U|'*|A| and |V|'*|B|.
00149 *
00150             UA21 = -SNL*A1
00151             UA22 = -SNL*A2 + CSL*A3
00152 *
00153             VB21 = -SNR*B1
00154             VB22 = -SNR*B2 + CSR*B3
00155 *
00156             AUA22 = ABS( SNL )*ABS( A2 ) + ABS( CSL )*ABS( A3 )
00157             AVB22 = ABS( SNR )*ABS( B2 ) + ABS( CSR )*ABS( B3 )
00158 *
00159 *           zero (2,2) elements of U'*A and V'*B, and then swap.
00160 *
00161             IF( ( ABS( UA21 )+ABS( UA22 ) ).NE.ZERO ) THEN
00162                IF( AUA22 / ( ABS( UA21 )+ABS( UA22 ) ).LE.AVB22 /
00163      $             ( ABS( VB21 )+ABS( VB22 ) ) ) THEN
00164                   CALL DLARTG( -UA21, UA22, CSQ, SNQ, R )
00165                ELSE
00166                   CALL DLARTG( -VB21, VB22, CSQ, SNQ, R )
00167                END IF
00168             ELSE
00169                CALL DLARTG( -VB21, VB22, CSQ, SNQ, R )
00170             END IF
00171 *
00172             CSU = SNL
00173             SNU = CSL
00174             CSV = SNR
00175             SNV = CSR
00176 *
00177          END IF
00178 *
00179       ELSE
00180 *
00181 *        Input matrices A and B are lower triangular matrices
00182 *
00183 *        Form matrix C = A*adj(B) = ( a 0 )
00184 *                                   ( c d )
00185 *
00186          A = A1*B3
00187          D = A3*B1
00188          C = A2*B3 - A3*B2
00189 *
00190 *        The SVD of real 2-by-2 triangular C
00191 *
00192 *         ( CSL -SNL )*( A 0 )*(  CSR  SNR ) = ( R 0 )
00193 *         ( SNL  CSL ) ( C D ) ( -SNR  CSR )   ( 0 T )
00194 *
00195          CALL DLASV2( A, C, D, S1, S2, SNR, CSR, SNL, CSL )
00196 *
00197          IF( ABS( CSR ).GE.ABS( SNR ) .OR. ABS( CSL ).GE.ABS( SNL ) )
00198      $        THEN
00199 *
00200 *           Compute the (2,1) and (2,2) elements of U'*A and V'*B,
00201 *           and (2,1) element of |U|'*|A| and |V|'*|B|.
00202 *
00203             UA21 = -SNR*A1 + CSR*A2
00204             UA22R = CSR*A3
00205 *
00206             VB21 = -SNL*B1 + CSL*B2
00207             VB22R = CSL*B3
00208 *
00209             AUA21 = ABS( SNR )*ABS( A1 ) + ABS( CSR )*ABS( A2 )
00210             AVB21 = ABS( SNL )*ABS( B1 ) + ABS( CSL )*ABS( B2 )
00211 *
00212 *           zero (2,1) elements of U'*A and V'*B.
00213 *
00214             IF( ( ABS( UA21 )+ABS( UA22R ) ).NE.ZERO ) THEN
00215                IF( AUA21 / ( ABS( UA21 )+ABS( UA22R ) ).LE.AVB21 /
00216      $             ( ABS( VB21 )+ABS( VB22R ) ) ) THEN
00217                   CALL DLARTG( UA22R, UA21, CSQ, SNQ, R )
00218                ELSE
00219                   CALL DLARTG( VB22R, VB21, CSQ, SNQ, R )
00220                END IF
00221             ELSE
00222                CALL DLARTG( VB22R, VB21, CSQ, SNQ, R )
00223             END IF
00224 *
00225             CSU = CSR
00226             SNU = -SNR
00227             CSV = CSL
00228             SNV = -SNL
00229 *
00230          ELSE
00231 *
00232 *           Compute the (1,1) and (1,2) elements of U'*A and V'*B,
00233 *           and (1,1) element of |U|'*|A| and |V|'*|B|.
00234 *
00235             UA11 = CSR*A1 + SNR*A2
00236             UA12 = SNR*A3
00237 *
00238             VB11 = CSL*B1 + SNL*B2
00239             VB12 = SNL*B3
00240 *
00241             AUA11 = ABS( CSR )*ABS( A1 ) + ABS( SNR )*ABS( A2 )
00242             AVB11 = ABS( CSL )*ABS( B1 ) + ABS( SNL )*ABS( B2 )
00243 *
00244 *           zero (1,1) elements of U'*A and V'*B, and then swap.
00245 *
00246             IF( ( ABS( UA11 )+ABS( UA12 ) ).NE.ZERO ) THEN
00247                IF( AUA11 / ( ABS( UA11 )+ABS( UA12 ) ).LE.AVB11 /
00248      $             ( ABS( VB11 )+ABS( VB12 ) ) ) THEN
00249                   CALL DLARTG( UA12, UA11, CSQ, SNQ, R )
00250                ELSE
00251                   CALL DLARTG( VB12, VB11, CSQ, SNQ, R )
00252                END IF
00253             ELSE
00254                CALL DLARTG( VB12, VB11, CSQ, SNQ, R )
00255             END IF
00256 *
00257             CSU = SNR
00258             SNU = CSR
00259             CSV = SNL
00260             SNV = CSL
00261 *
00262          END IF
00263 *
00264       END IF
00265 *
00266       RETURN
00267 *
00268 *     End of DLAGS2
00269 *
00270       END
 All Files Functions