LAPACK 3.3.0
|
00001 SUBROUTINE ZGET54( N, A, LDA, B, LDB, S, LDS, T, LDT, U, LDU, V, 00002 $ LDV, WORK, RESULT ) 00003 * 00004 * -- LAPACK test routine (version 3.1) -- 00005 * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. 00006 * November 2006 00007 * 00008 * .. Scalar Arguments .. 00009 INTEGER LDA, LDB, LDS, LDT, LDU, LDV, N 00010 DOUBLE PRECISION RESULT 00011 * .. 00012 * .. Array Arguments .. 00013 COMPLEX*16 A( LDA, * ), B( LDB, * ), S( LDS, * ), 00014 $ T( LDT, * ), U( LDU, * ), V( LDV, * ), 00015 $ WORK( * ) 00016 * .. 00017 * 00018 * Purpose 00019 * ======= 00020 * 00021 * ZGET54 checks a generalized decomposition of the form 00022 * 00023 * A = U*S*V' and B = U*T* V' 00024 * 00025 * where ' means conjugate transpose and U and V are unitary. 00026 * 00027 * Specifically, 00028 * 00029 * RESULT = ||( A - U*S*V', B - U*T*V' )|| / (||( A, B )||*n*ulp ) 00030 * 00031 * Arguments 00032 * ========= 00033 * 00034 * N (input) INTEGER 00035 * The size of the matrix. If it is zero, DGET54 does nothing. 00036 * It must be at least zero. 00037 * 00038 * A (input) COMPLEX*16 array, dimension (LDA, N) 00039 * The original (unfactored) matrix A. 00040 * 00041 * LDA (input) INTEGER 00042 * The leading dimension of A. It must be at least 1 00043 * and at least N. 00044 * 00045 * B (input) COMPLEX*16 array, dimension (LDB, N) 00046 * The original (unfactored) matrix B. 00047 * 00048 * LDB (input) INTEGER 00049 * The leading dimension of B. It must be at least 1 00050 * and at least N. 00051 * 00052 * S (input) COMPLEX*16 array, dimension (LDS, N) 00053 * The factored matrix S. 00054 * 00055 * LDS (input) INTEGER 00056 * The leading dimension of S. It must be at least 1 00057 * and at least N. 00058 * 00059 * T (input) COMPLEX*16 array, dimension (LDT, N) 00060 * The factored matrix T. 00061 * 00062 * LDT (input) INTEGER 00063 * The leading dimension of T. It must be at least 1 00064 * and at least N. 00065 * 00066 * U (input) COMPLEX*16 array, dimension (LDU, N) 00067 * The orthogonal matrix on the left-hand side in the 00068 * decomposition. 00069 * 00070 * LDU (input) INTEGER 00071 * The leading dimension of U. LDU must be at least N and 00072 * at least 1. 00073 * 00074 * V (input) COMPLEX*16 array, dimension (LDV, N) 00075 * The orthogonal matrix on the left-hand side in the 00076 * decomposition. 00077 * 00078 * LDV (input) INTEGER 00079 * The leading dimension of V. LDV must be at least N and 00080 * at least 1. 00081 * 00082 * WORK (workspace) COMPLEX*16 array, dimension (3*N**2) 00083 * 00084 * RESULT (output) DOUBLE PRECISION 00085 * The value RESULT, It is currently limited to 1/ulp, to 00086 * avoid overflow. Errors are flagged by RESULT=10/ulp. 00087 * 00088 * ===================================================================== 00089 * 00090 * .. Parameters .. 00091 DOUBLE PRECISION ZERO, ONE 00092 PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 ) 00093 COMPLEX*16 CZERO, CONE 00094 PARAMETER ( CZERO = ( 0.0D+0, 0.0D+0 ), 00095 $ CONE = ( 1.0D+0, 0.0D+0 ) ) 00096 * .. 00097 * .. Local Scalars .. 00098 DOUBLE PRECISION ABNORM, ULP, UNFL, WNORM 00099 * .. 00100 * .. Local Arrays .. 00101 DOUBLE PRECISION DUM( 1 ) 00102 * .. 00103 * .. External Functions .. 00104 DOUBLE PRECISION DLAMCH, ZLANGE 00105 EXTERNAL DLAMCH, ZLANGE 00106 * .. 00107 * .. External Subroutines .. 00108 EXTERNAL ZGEMM, ZLACPY 00109 * .. 00110 * .. Intrinsic Functions .. 00111 INTRINSIC DBLE, MAX, MIN 00112 * .. 00113 * .. Executable Statements .. 00114 * 00115 RESULT = ZERO 00116 IF( N.LE.0 ) 00117 $ RETURN 00118 * 00119 * Constants 00120 * 00121 UNFL = DLAMCH( 'Safe minimum' ) 00122 ULP = DLAMCH( 'Epsilon' )*DLAMCH( 'Base' ) 00123 * 00124 * compute the norm of (A,B) 00125 * 00126 CALL ZLACPY( 'Full', N, N, A, LDA, WORK, N ) 00127 CALL ZLACPY( 'Full', N, N, B, LDB, WORK( N*N+1 ), N ) 00128 ABNORM = MAX( ZLANGE( '1', N, 2*N, WORK, N, DUM ), UNFL ) 00129 * 00130 * Compute W1 = A - U*S*V', and put in the array WORK(1:N*N) 00131 * 00132 CALL ZLACPY( ' ', N, N, A, LDA, WORK, N ) 00133 CALL ZGEMM( 'N', 'N', N, N, N, CONE, U, LDU, S, LDS, CZERO, 00134 $ WORK( N*N+1 ), N ) 00135 * 00136 CALL ZGEMM( 'N', 'C', N, N, N, -CONE, WORK( N*N+1 ), N, V, LDV, 00137 $ CONE, WORK, N ) 00138 * 00139 * Compute W2 = B - U*T*V', and put in the workarray W(N*N+1:2*N*N) 00140 * 00141 CALL ZLACPY( ' ', N, N, B, LDB, WORK( N*N+1 ), N ) 00142 CALL ZGEMM( 'N', 'N', N, N, N, CONE, U, LDU, T, LDT, CZERO, 00143 $ WORK( 2*N*N+1 ), N ) 00144 * 00145 CALL ZGEMM( 'N', 'C', N, N, N, -CONE, WORK( 2*N*N+1 ), N, V, LDV, 00146 $ CONE, WORK( N*N+1 ), N ) 00147 * 00148 * Compute norm(W)/ ( ulp*norm((A,B)) ) 00149 * 00150 WNORM = ZLANGE( '1', N, 2*N, WORK, N, DUM ) 00151 * 00152 IF( ABNORM.GT.WNORM ) THEN 00153 RESULT = ( WNORM / ABNORM ) / ( 2*N*ULP ) 00154 ELSE 00155 IF( ABNORM.LT.ONE ) THEN 00156 RESULT = ( MIN( WNORM, 2*N*ABNORM ) / ABNORM ) / ( 2*N*ULP ) 00157 ELSE 00158 RESULT = MIN( WNORM / ABNORM, DBLE( 2*N ) ) / ( 2*N*ULP ) 00159 END IF 00160 END IF 00161 * 00162 RETURN 00163 * 00164 * End of ZGET54 00165 * 00166 END