LAPACK 3.3.0
|
00001 SUBROUTINE DORT01( ROWCOL, M, N, U, LDU, WORK, LWORK, RESID ) 00002 * 00003 * -- LAPACK test routine (version 3.1) -- 00004 * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. 00005 * November 2006 00006 * 00007 * .. Scalar Arguments .. 00008 CHARACTER ROWCOL 00009 INTEGER LDU, LWORK, M, N 00010 DOUBLE PRECISION RESID 00011 * .. 00012 * .. Array Arguments .. 00013 DOUBLE PRECISION U( LDU, * ), WORK( * ) 00014 * .. 00015 * 00016 * Purpose 00017 * ======= 00018 * 00019 * DORT01 checks that the matrix U is orthogonal by computing the ratio 00020 * 00021 * RESID = norm( I - U*U' ) / ( n * EPS ), if ROWCOL = 'R', 00022 * or 00023 * RESID = norm( I - U'*U ) / ( m * EPS ), if ROWCOL = 'C'. 00024 * 00025 * Alternatively, if there isn't sufficient workspace to form 00026 * I - U*U' or I - U'*U, the ratio is computed as 00027 * 00028 * RESID = abs( I - U*U' ) / ( n * EPS ), if ROWCOL = 'R', 00029 * or 00030 * RESID = abs( I - U'*U ) / ( m * EPS ), if ROWCOL = 'C'. 00031 * 00032 * where EPS is the machine precision. ROWCOL is used only if m = n; 00033 * if m > n, ROWCOL is assumed to be 'C', and if m < n, ROWCOL is 00034 * assumed to be 'R'. 00035 * 00036 * Arguments 00037 * ========= 00038 * 00039 * ROWCOL (input) CHARACTER 00040 * Specifies whether the rows or columns of U should be checked 00041 * for orthogonality. Used only if M = N. 00042 * = 'R': Check for orthogonal rows of U 00043 * = 'C': Check for orthogonal columns of U 00044 * 00045 * M (input) INTEGER 00046 * The number of rows of the matrix U. 00047 * 00048 * N (input) INTEGER 00049 * The number of columns of the matrix U. 00050 * 00051 * U (input) DOUBLE PRECISION array, dimension (LDU,N) 00052 * The orthogonal matrix U. U is checked for orthogonal columns 00053 * if m > n or if m = n and ROWCOL = 'C'. U is checked for 00054 * orthogonal rows if m < n or if m = n and ROWCOL = 'R'. 00055 * 00056 * LDU (input) INTEGER 00057 * The leading dimension of the array U. LDU >= max(1,M). 00058 * 00059 * WORK (workspace) DOUBLE PRECISION array, dimension (LWORK) 00060 * 00061 * LWORK (input) INTEGER 00062 * The length of the array WORK. For best performance, LWORK 00063 * should be at least N*(N+1) if ROWCOL = 'C' or M*(M+1) if 00064 * ROWCOL = 'R', but the test will be done even if LWORK is 0. 00065 * 00066 * RESID (output) DOUBLE PRECISION 00067 * RESID = norm( I - U * U' ) / ( n * EPS ), if ROWCOL = 'R', or 00068 * RESID = norm( I - U' * U ) / ( m * EPS ), if ROWCOL = 'C'. 00069 * 00070 * ===================================================================== 00071 * 00072 * .. Parameters .. 00073 DOUBLE PRECISION ZERO, ONE 00074 PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 ) 00075 * .. 00076 * .. Local Scalars .. 00077 CHARACTER TRANSU 00078 INTEGER I, J, K, LDWORK, MNMIN 00079 DOUBLE PRECISION EPS, TMP 00080 * .. 00081 * .. External Functions .. 00082 LOGICAL LSAME 00083 DOUBLE PRECISION DDOT, DLAMCH, DLANSY 00084 EXTERNAL LSAME, DDOT, DLAMCH, DLANSY 00085 * .. 00086 * .. External Subroutines .. 00087 EXTERNAL DLASET, DSYRK 00088 * .. 00089 * .. Intrinsic Functions .. 00090 INTRINSIC ABS, DBLE, MAX, MIN 00091 * .. 00092 * .. Executable Statements .. 00093 * 00094 RESID = ZERO 00095 * 00096 * Quick return if possible 00097 * 00098 IF( M.LE.0 .OR. N.LE.0 ) 00099 $ RETURN 00100 * 00101 EPS = DLAMCH( 'Precision' ) 00102 IF( M.LT.N .OR. ( M.EQ.N .AND. LSAME( ROWCOL, 'R' ) ) ) THEN 00103 TRANSU = 'N' 00104 K = N 00105 ELSE 00106 TRANSU = 'T' 00107 K = M 00108 END IF 00109 MNMIN = MIN( M, N ) 00110 * 00111 IF( ( MNMIN+1 )*MNMIN.LE.LWORK ) THEN 00112 LDWORK = MNMIN 00113 ELSE 00114 LDWORK = 0 00115 END IF 00116 IF( LDWORK.GT.0 ) THEN 00117 * 00118 * Compute I - U*U' or I - U'*U. 00119 * 00120 CALL DLASET( 'Upper', MNMIN, MNMIN, ZERO, ONE, WORK, LDWORK ) 00121 CALL DSYRK( 'Upper', TRANSU, MNMIN, K, -ONE, U, LDU, ONE, WORK, 00122 $ LDWORK ) 00123 * 00124 * Compute norm( I - U*U' ) / ( K * EPS ) . 00125 * 00126 RESID = DLANSY( '1', 'Upper', MNMIN, WORK, LDWORK, 00127 $ WORK( LDWORK*MNMIN+1 ) ) 00128 RESID = ( RESID / DBLE( K ) ) / EPS 00129 ELSE IF( TRANSU.EQ.'T' ) THEN 00130 * 00131 * Find the maximum element in abs( I - U'*U ) / ( m * EPS ) 00132 * 00133 DO 20 J = 1, N 00134 DO 10 I = 1, J 00135 IF( I.NE.J ) THEN 00136 TMP = ZERO 00137 ELSE 00138 TMP = ONE 00139 END IF 00140 TMP = TMP - DDOT( M, U( 1, I ), 1, U( 1, J ), 1 ) 00141 RESID = MAX( RESID, ABS( TMP ) ) 00142 10 CONTINUE 00143 20 CONTINUE 00144 RESID = ( RESID / DBLE( M ) ) / EPS 00145 ELSE 00146 * 00147 * Find the maximum element in abs( I - U*U' ) / ( n * EPS ) 00148 * 00149 DO 40 J = 1, M 00150 DO 30 I = 1, J 00151 IF( I.NE.J ) THEN 00152 TMP = ZERO 00153 ELSE 00154 TMP = ONE 00155 END IF 00156 TMP = TMP - DDOT( N, U( J, 1 ), LDU, U( I, 1 ), LDU ) 00157 RESID = MAX( RESID, ABS( TMP ) ) 00158 30 CONTINUE 00159 40 CONTINUE 00160 RESID = ( RESID / DBLE( N ) ) / EPS 00161 END IF 00162 RETURN 00163 * 00164 * End of DORT01 00165 * 00166 END