PLASMA  2.4.5
PLASMA - Parallel Linear Algebra for Scalable Multi-core Architectures
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
zpot01.f
Go to the documentation of this file.
1  SUBROUTINE zpot01( UPLO, N, A, LDA, AFAC, LDAFAC, RWORK, RESID )
2 *
3 * -- LAPACK test routine (version 3.1) --
4 * Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
5 * November 2006
6 *
7 * .. Scalar Arguments ..
8  CHARACTER uplo
9  INTEGER lda, ldafac, n
10  DOUBLE PRECISION resid
11 * ..
12 * .. Array Arguments ..
13  DOUBLE PRECISION rwork( * )
14  COMPLEX*16 a( lda, * ), afac( ldafac, * )
15 * ..
16 *
17 * Purpose
18 * =======
19 *
20 * ZPOT01 reconstructs a Hermitian positive definite matrix A from
21 * its L*L' or U'*U factorization and computes the residual
22 * norm( L*L' - A ) / ( N * norm(A) * EPS ) or
23 * norm( U'*U - A ) / ( N * norm(A) * EPS ),
24 * where EPS is the machine epsilon, L' is the conjugate transpose of L,
25 * and U' is the conjugate transpose of U.
26 *
27 * Arguments
28 * ==========
29 *
30 * UPLO (input) CHARACTER*1
31 * Specifies whether the upper or lower triangular part of the
32 * Hermitian matrix A is stored:
33 * = 'U': Upper triangular
34 * = 'L': Lower triangular
35 *
36 * N (input) INTEGER
37 * The number of rows and columns of the matrix A. N >= 0.
38 *
39 * A (input) COMPLEX*16 array, dimension (LDA,N)
40 * The original Hermitian matrix A.
41 *
42 * LDA (input) INTEGER
43 * The leading dimension of the array A. LDA >= max(1,N)
44 *
45 * AFAC (input/output) COMPLEX*16 array, dimension (LDAFAC,N)
46 * On entry, the factor L or U from the L*L' or U'*U
47 * factorization of A.
48 * Overwritten with the reconstructed matrix, and then with the
49 * difference L*L' - A (or U'*U - A).
50 *
51 * LDAFAC (input) INTEGER
52 * The leading dimension of the array AFAC. LDAFAC >= max(1,N).
53 *
54 * RWORK (workspace) DOUBLE PRECISION array, dimension (N)
55 *
56 * RESID (output) DOUBLE PRECISION
57 * If UPLO = 'L', norm(L*L' - A) / ( N * norm(A) * EPS )
58 * If UPLO = 'U', norm(U'*U - A) / ( N * norm(A) * EPS )
59 *
60 * =====================================================================
61 *
62 * .. Parameters ..
63  DOUBLE PRECISION zero, one
64  parameter( zero = 0.0d+0, one = 1.0d+0 )
65 * ..
66 * .. Local Scalars ..
67  INTEGER i, j, k
68  DOUBLE PRECISION anorm, eps, tr
69  COMPLEX*16 tc
70 * ..
71 * .. External Functions ..
72  LOGICAL lsame
73  DOUBLE PRECISION dlamch, zlanhe
74  COMPLEX*16 zdotc
75  EXTERNAL lsame, dlamch, zlanhe, zdotc
76 * ..
77 * .. External Subroutines ..
78  EXTERNAL zher, zscal, ztrmv
79 * ..
80 * .. Intrinsic Functions ..
81  INTRINSIC dble, dimag
82 * ..
83 * .. Executable Statements ..
84 *
85 * Quick exit if N = 0.
86 *
87  IF( n.LE.0 ) THEN
88  resid = zero
89  return
90  END IF
91 *
92 * Exit with RESID = 1/EPS if ANORM = 0.
93 *
94  eps = dlamch( 'Epsilon' )
95  anorm = zlanhe( '1', uplo, n, a, lda, rwork )
96  IF( anorm.LE.zero ) THEN
97  resid = one / eps
98  return
99  END IF
100 *
101 * Check the imaginary parts of the diagonal elements and return with
102 * an error code if any are nonzero.
103 *
104  DO 10 j = 1, n
105  IF( dimag( afac( j, j ) ).NE.zero ) THEN
106  resid = one / eps
107  return
108  END IF
109  10 continue
110 *
111 * Compute the product U'*U, overwriting U.
112 *
113  IF( lsame( uplo, 'U' ) ) THEN
114  DO 20 k = n, 1, -1
115 *
116 * Compute the (K,K) element of the result.
117 *
118  tr = zdotc( k, afac( 1, k ), 1, afac( 1, k ), 1 )
119  afac( k, k ) = tr
120 *
121 * Compute the rest of column K.
122 *
123  CALL ztrmv( 'Upper', 'Conjugate', 'Non-unit', k-1, afac,
124  $ ldafac, afac( 1, k ), 1 )
125 *
126  20 continue
127 *
128 * Compute the product L*L', overwriting L.
129 *
130  ELSE
131  DO 30 k = n, 1, -1
132 *
133 * Add a multiple of column K of the factor L to each of
134 * columns K+1 through N.
135 *
136  IF( k+1.LE.n )
137  $ CALL zher( 'Lower', n-k, one, afac( k+1, k ), 1,
138  $ afac( k+1, k+1 ), ldafac )
139 *
140 * Scale column K by the diagonal element.
141 *
142  tc = afac( k, k )
143  CALL zscal( n-k+1, tc, afac( k, k ), 1 )
144 *
145  30 continue
146  END IF
147 *
148 * Compute the difference L*L' - A (or U'*U - A).
149 *
150  IF( lsame( uplo, 'U' ) ) THEN
151  DO 50 j = 1, n
152  DO 40 i = 1, j - 1
153  afac( i, j ) = afac( i, j ) - a( i, j )
154  40 continue
155  afac( j, j ) = afac( j, j ) - dble( a( j, j ) )
156  50 continue
157  ELSE
158  DO 70 j = 1, n
159  afac( j, j ) = afac( j, j ) - dble( a( j, j ) )
160  DO 60 i = j + 1, n
161  afac( i, j ) = afac( i, j ) - a( i, j )
162  60 continue
163  70 continue
164  END IF
165 *
166 * Compute norm( L*U - A ) / ( N * norm(A) * EPS )
167 *
168  resid = zlanhe( '1', uplo, n, afac, ldafac, rwork )
169 *
170  resid = ( ( resid / dble( n ) ) / anorm ) / eps
171 *
172  return
173 *
174 * End of ZPOT01
175 *
176  END