1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
     100
     101
     102
     103
     104
     105
     106
     107
     108
     109
     110
     111
     112
     113
     114
     115
     116
     117
     118
     119
     120
     121
     122
     123
     124
     125
     126
     127
     128
     129
     130
     131
     132
     133
     134
     135
     136
     137
     138
     139
     140
     141
     142
     143
     144
     145
     146
     147
     148
     149
     150
     151
     152
     153
     154
     155
     156
     157
     158
     159
     160
     161
     162
     163
     164
     165
     166
     167
     168
     169
     170
     171
     172
     173
     174
     175
     176
     177
     178
     179
     180
      SUBROUTINE CUNT01ROWCOLMNULDUWORKLWORKRWORK,
     $                   RESID )
*
*  -- LAPACK test routine (version 3.1) --
*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
*     November 2006
*
*     .. Scalar Arguments ..
      CHARACTER          ROWCOL
      INTEGER            LDULWORKMN
      REAL               RESID
*     ..
*     .. Array Arguments ..
      REAL               RWORK* )
      COMPLEX            ULDU* ), WORK* )
*     ..
*
*  Purpose
*  =======
*
*  CUNT01 checks that the matrix U is unitary by computing the ratio
*
*     RESID = norm( I - U*U' ) / ( n * EPS ), if ROWCOL = 'R',
*  or
*     RESID = norm( I - U'*U ) / ( m * EPS ), if ROWCOL = 'C'.
*
*  Alternatively, if there isn't sufficient workspace to form
*  I - U*U' or I - U'*U, the ratio is computed as
*
*     RESID = abs( I - U*U' ) / ( n * EPS ), if ROWCOL = 'R',
*  or
*     RESID = abs( I - U'*U ) / ( m * EPS ), if ROWCOL = 'C'.
*
*  where EPS is the machine precision.  ROWCOL is used only if m = n;
*  if m > n, ROWCOL is assumed to be 'C', and if m < n, ROWCOL is
*  assumed to be 'R'.
*
*  Arguments
*  =========
*
*  ROWCOL  (input) CHARACTER
*          Specifies whether the rows or columns of U should be checked
*          for orthogonality.  Used only if M = N.
*          = 'R':  Check for orthogonal rows of U
*          = 'C':  Check for orthogonal columns of U
*
*  M       (input) INTEGER
*          The number of rows of the matrix U.
*
*  N       (input) INTEGER
*          The number of columns of the matrix U.
*
*  U       (input) COMPLEX array, dimension (LDU,N)
*          The unitary matrix U.  U is checked for orthogonal columns
*          if m > n or if m = n and ROWCOL = 'C'.  U is checked for
*          orthogonal rows if m < n or if m = n and ROWCOL = 'R'.
*
*  LDU     (input) INTEGER
*          The leading dimension of the array U.  LDU >= max(1,M).
*
*  WORK    (workspace) COMPLEX array, dimension (LWORK)
*
*  LWORK   (input) INTEGER
*          The length of the array WORK.  For best performance, LWORK
*          should be at least N*N if ROWCOL = 'C' or M*M if
*          ROWCOL = 'R', but the test will be done even if LWORK is 0.
*
*  RWORK   (workspace) REAL array, dimension (min(M,N))
*          Used only if LWORK is large enough to use the Level 3 BLAS
*          code.
*
*  RESID   (output) REAL
*          RESID = norm( I - U * U' ) / ( n * EPS ), if ROWCOL = 'R', or
*          RESID = norm( I - U' * U ) / ( m * EPS ), if ROWCOL = 'C'.
*
*  =====================================================================
*
*     .. Parameters ..
      REAL               ZEROONE
      PARAMETER          ( ZERO = 0.0E+0ONE = 1.0E+0 )
*     ..
*     .. Local Scalars ..
      CHARACTER          TRANSU
      INTEGER            IJKLDWORKMNMIN
      REAL               EPS
      COMPLEX            TMPZDUM
*     ..
*     .. External Functions ..
      LOGICAL            LSAME
      REAL               CLANSYSLAMCH
      COMPLEX            CDOTC
      EXTERNAL           LSAMECLANSYSLAMCHCDOTC
*     ..
*     .. External Subroutines ..
      EXTERNAL           CHERKCLASET
*     ..
*     .. Intrinsic Functions ..
      INTRINSIC          ABSAIMAGCMPLXMAXMINREAL
*     ..
*     .. Statement Functions ..
      REAL               CABS1
*     ..
*     .. Statement Function definitions ..
      CABS1ZDUM ) = ABSREALZDUM ) ) + ABSAIMAGZDUM ) )
*     ..
*     .. Executable Statements ..
*
      RESID = ZERO
*
*     Quick return if possible
*
      IFM.LE.0 .OR. N.LE.0 )
     $   RETURN
*
      EPS = SLAMCH'Precision' )
      IFM.LT.N .OR. ( M.EQ.N .AND. LSAMEROWCOL'R' ) ) ) THEN
         TRANSU = 'N'
         K = N
      ELSE
         TRANSU = 'C'
         K = M
      END IF
      MNMIN = MINMN )
*
      IF( ( MNMIN+1 )*MNMIN.LE.LWORK ) THEN
         LDWORK = MNMIN
      ELSE
         LDWORK = 0
      END IF
      IFLDWORK.GT.0 ) THEN
*
*        Compute I - U*U' or I - U'*U.
*
         CALL CLASET'Upper'MNMINMNMINCMPLXZERO ),
     $                CMPLXONE ), WORKLDWORK )
         CALL CHERK'Upper'TRANSUMNMINK-ONEULDUONEWORK,
     $               LDWORK )
*
*        Compute norm( I - U*U' ) / ( K * EPS ) .
*
         RESID = CLANSY'1''Upper'MNMINWORKLDWORKRWORK )
         RESID = ( RESID / REALK ) ) / EPS
      ELSE IFTRANSU.EQ.'C' ) THEN
*
*        Find the maximum element in abs( I - U'*U ) / ( m * EPS )
*
         DO 20 J = 1N
            DO 10 I = 1J
               IFI.NE.J ) THEN
                  TMP = ZERO
               ELSE
                  TMP = ONE
               END IF
               TMP = TMP - CDOTCMU1I ), 1U1J ), 1 )
               RESID = MAXRESIDCABS1TMP ) )
   10       CONTINUE
   20    CONTINUE
         RESID = ( RESID / REALM ) ) / EPS
      ELSE
*
*        Find the maximum element in abs( I - U*U' ) / ( n * EPS )
*
         DO 40 J = 1M
            DO 30 I = 1J
               IFI.NE.J ) THEN
                  TMP = ZERO
               ELSE
                  TMP = ONE
               END IF
               TMP = TMP - CDOTCNUJ1 ), LDUUI1 ), LDU )
               RESID = MAXRESIDCABS1TMP ) )
   30       CONTINUE
   40    CONTINUE
         RESID = ( RESID / REALN ) ) / EPS
      END IF
      RETURN
*
*     End of CUNT01
*
      END