LAPACK  3.9.0
LAPACK: Linear Algebra PACKage
ssyt21.f
Go to the documentation of this file.
1 *> \brief \b SSYT21
2 *
3 * =========== DOCUMENTATION ===========
4 *
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
7 *
8 * Definition:
9 * ===========
10 *
11 * SUBROUTINE SSYT21( ITYPE, UPLO, N, KBAND, A, LDA, D, E, U, LDU, V,
12 * LDV, TAU, WORK, RESULT )
13 *
14 * .. Scalar Arguments ..
15 * CHARACTER UPLO
16 * INTEGER ITYPE, KBAND, LDA, LDU, LDV, N
17 * ..
18 * .. Array Arguments ..
19 * REAL A( LDA, * ), D( * ), E( * ), RESULT( 2 ),
20 * $ TAU( * ), U( LDU, * ), V( LDV, * ), WORK( * )
21 * ..
22 *
23 *
24 *> \par Purpose:
25 * =============
26 *>
27 *> \verbatim
28 *>
29 *> SSYT21 generally checks a decomposition of the form
30 *>
31 *> A = U S U**T
32 *>
33 *> where **T means transpose, A is symmetric, U is orthogonal, and S is
34 *> diagonal (if KBAND=0) or symmetric tridiagonal (if KBAND=1).
35 *>
36 *> If ITYPE=1, then U is represented as a dense matrix; otherwise U is
37 *> expressed as a product of Householder transformations, whose vectors
38 *> are stored in the array "V" and whose scaling constants are in "TAU".
39 *> We shall use the letter "V" to refer to the product of Householder
40 *> transformations (which should be equal to U).
41 *>
42 *> Specifically, if ITYPE=1, then:
43 *>
44 *> RESULT(1) = | A - U S U**T | / ( |A| n ulp ) and
45 *> RESULT(2) = | I - U U**T | / ( n ulp )
46 *>
47 *> If ITYPE=2, then:
48 *>
49 *> RESULT(1) = | A - V S V**T | / ( |A| n ulp )
50 *>
51 *> If ITYPE=3, then:
52 *>
53 *> RESULT(1) = | I - V U**T | / ( n ulp )
54 *>
55 *> For ITYPE > 1, the transformation U is expressed as a product
56 *> V = H(1)...H(n-2), where H(j) = I - tau(j) v(j) v(j)**T and each
57 *> vector v(j) has its first j elements 0 and the remaining n-j elements
58 *> stored in V(j+1:n,j).
59 *> \endverbatim
60 *
61 * Arguments:
62 * ==========
63 *
64 *> \param[in] ITYPE
65 *> \verbatim
66 *> ITYPE is INTEGER
67 *> Specifies the type of tests to be performed.
68 *> 1: U expressed as a dense orthogonal matrix:
69 *> RESULT(1) = | A - U S U**T | / ( |A| n ulp ) and
70 *> RESULT(2) = | I - U U**T | / ( n ulp )
71 *>
72 *> 2: U expressed as a product V of Housholder transformations:
73 *> RESULT(1) = | A - V S V**T | / ( |A| n ulp )
74 *>
75 *> 3: U expressed both as a dense orthogonal matrix and
76 *> as a product of Housholder transformations:
77 *> RESULT(1) = | I - V U**T | / ( n ulp )
78 *> \endverbatim
79 *>
80 *> \param[in] UPLO
81 *> \verbatim
82 *> UPLO is CHARACTER
83 *> If UPLO='U', the upper triangle of A and V will be used and
84 *> the (strictly) lower triangle will not be referenced.
85 *> If UPLO='L', the lower triangle of A and V will be used and
86 *> the (strictly) upper triangle will not be referenced.
87 *> \endverbatim
88 *>
89 *> \param[in] N
90 *> \verbatim
91 *> N is INTEGER
92 *> The size of the matrix. If it is zero, SSYT21 does nothing.
93 *> It must be at least zero.
94 *> \endverbatim
95 *>
96 *> \param[in] KBAND
97 *> \verbatim
98 *> KBAND is INTEGER
99 *> The bandwidth of the matrix. It may only be zero or one.
100 *> If zero, then S is diagonal, and E is not referenced. If
101 *> one, then S is symmetric tri-diagonal.
102 *> \endverbatim
103 *>
104 *> \param[in] A
105 *> \verbatim
106 *> A is REAL array, dimension (LDA, N)
107 *> The original (unfactored) matrix. It is assumed to be
108 *> symmetric, and only the upper (UPLO='U') or only the lower
109 *> (UPLO='L') will be referenced.
110 *> \endverbatim
111 *>
112 *> \param[in] LDA
113 *> \verbatim
114 *> LDA is INTEGER
115 *> The leading dimension of A. It must be at least 1
116 *> and at least N.
117 *> \endverbatim
118 *>
119 *> \param[in] D
120 *> \verbatim
121 *> D is REAL array, dimension (N)
122 *> The diagonal of the (symmetric tri-) diagonal matrix.
123 *> \endverbatim
124 *>
125 *> \param[in] E
126 *> \verbatim
127 *> E is REAL array, dimension (N-1)
128 *> The off-diagonal of the (symmetric tri-) diagonal matrix.
129 *> E(1) is the (1,2) and (2,1) element, E(2) is the (2,3) and
130 *> (3,2) element, etc.
131 *> Not referenced if KBAND=0.
132 *> \endverbatim
133 *>
134 *> \param[in] U
135 *> \verbatim
136 *> U is REAL array, dimension (LDU, N)
137 *> If ITYPE=1 or 3, this contains the orthogonal matrix in
138 *> the decomposition, expressed as a dense matrix. If ITYPE=2,
139 *> then it is not referenced.
140 *> \endverbatim
141 *>
142 *> \param[in] LDU
143 *> \verbatim
144 *> LDU is INTEGER
145 *> The leading dimension of U. LDU must be at least N and
146 *> at least 1.
147 *> \endverbatim
148 *>
149 *> \param[in] V
150 *> \verbatim
151 *> V is REAL array, dimension (LDV, N)
152 *> If ITYPE=2 or 3, the columns of this array contain the
153 *> Householder vectors used to describe the orthogonal matrix
154 *> in the decomposition. If UPLO='L', then the vectors are in
155 *> the lower triangle, if UPLO='U', then in the upper
156 *> triangle.
157 *> *NOTE* If ITYPE=2 or 3, V is modified and restored. The
158 *> subdiagonal (if UPLO='L') or the superdiagonal (if UPLO='U')
159 *> is set to one, and later reset to its original value, during
160 *> the course of the calculation.
161 *> If ITYPE=1, then it is neither referenced nor modified.
162 *> \endverbatim
163 *>
164 *> \param[in] LDV
165 *> \verbatim
166 *> LDV is INTEGER
167 *> The leading dimension of V. LDV must be at least N and
168 *> at least 1.
169 *> \endverbatim
170 *>
171 *> \param[in] TAU
172 *> \verbatim
173 *> TAU is REAL array, dimension (N)
174 *> If ITYPE >= 2, then TAU(j) is the scalar factor of
175 *> v(j) v(j)**T in the Householder transformation H(j) of
176 *> the product U = H(1)...H(n-2)
177 *> If ITYPE < 2, then TAU is not referenced.
178 *> \endverbatim
179 *>
180 *> \param[out] WORK
181 *> \verbatim
182 *> WORK is REAL array, dimension (2*N**2)
183 *> \endverbatim
184 *>
185 *> \param[out] RESULT
186 *> \verbatim
187 *> RESULT is REAL array, dimension (2)
188 *> The values computed by the two tests described above. The
189 *> values are currently limited to 1/ulp, to avoid overflow.
190 *> RESULT(1) is always modified. RESULT(2) is modified only
191 *> if ITYPE=1.
192 *> \endverbatim
193 *
194 * Authors:
195 * ========
196 *
197 *> \author Univ. of Tennessee
198 *> \author Univ. of California Berkeley
199 *> \author Univ. of Colorado Denver
200 *> \author NAG Ltd.
201 *
202 *> \date December 2016
203 *
204 *> \ingroup single_eig
205 *
206 * =====================================================================
207  SUBROUTINE ssyt21( ITYPE, UPLO, N, KBAND, A, LDA, D, E, U, LDU, V,
208  $ LDV, TAU, WORK, RESULT )
209 *
210 * -- LAPACK test routine (version 3.7.0) --
211 * -- LAPACK is a software package provided by Univ. of Tennessee, --
212 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
213 * December 2016
214 *
215 * .. Scalar Arguments ..
216  CHARACTER UPLO
217  INTEGER ITYPE, KBAND, LDA, LDU, LDV, N
218 * ..
219 * .. Array Arguments ..
220  REAL A( LDA, * ), D( * ), E( * ), RESULT( 2 ),
221  $ tau( * ), u( ldu, * ), v( ldv, * ), work( * )
222 * ..
223 *
224 * =====================================================================
225 *
226 * .. Parameters ..
227  REAL ZERO, ONE, TEN
228  parameter( zero = 0.0e0, one = 1.0e0, ten = 10.0e0 )
229 * ..
230 * .. Local Scalars ..
231  LOGICAL LOWER
232  CHARACTER CUPLO
233  INTEGER IINFO, J, JCOL, JR, JROW
234  REAL ANORM, ULP, UNFL, VSAVE, WNORM
235 * ..
236 * .. External Functions ..
237  LOGICAL LSAME
238  REAL SLAMCH, SLANGE, SLANSY
239  EXTERNAL lsame, slamch, slange, slansy
240 * ..
241 * .. External Subroutines ..
242  EXTERNAL sgemm, slacpy, slarfy, slaset, sorm2l, sorm2r,
243  $ ssyr, ssyr2
244 * ..
245 * .. Intrinsic Functions ..
246  INTRINSIC max, min, real
247 * ..
248 * .. Executable Statements ..
249 *
250  result( 1 ) = zero
251  IF( itype.EQ.1 )
252  $ result( 2 ) = zero
253  IF( n.LE.0 )
254  $ RETURN
255 *
256  IF( lsame( uplo, 'U' ) ) THEN
257  lower = .false.
258  cuplo = 'U'
259  ELSE
260  lower = .true.
261  cuplo = 'L'
262  END IF
263 *
264  unfl = slamch( 'Safe minimum' )
265  ulp = slamch( 'Epsilon' )*slamch( 'Base' )
266 *
267 * Some Error Checks
268 *
269  IF( itype.LT.1 .OR. itype.GT.3 ) THEN
270  result( 1 ) = ten / ulp
271  RETURN
272  END IF
273 *
274 * Do Test 1
275 *
276 * Norm of A:
277 *
278  IF( itype.EQ.3 ) THEN
279  anorm = one
280  ELSE
281  anorm = max( slansy( '1', cuplo, n, a, lda, work ), unfl )
282  END IF
283 *
284 * Compute error matrix:
285 *
286  IF( itype.EQ.1 ) THEN
287 *
288 * ITYPE=1: error = A - U S U**T
289 *
290  CALL slaset( 'Full', n, n, zero, zero, work, n )
291  CALL slacpy( cuplo, n, n, a, lda, work, n )
292 *
293  DO 10 j = 1, n
294  CALL ssyr( cuplo, n, -d( j ), u( 1, j ), 1, work, n )
295  10 CONTINUE
296 *
297  IF( n.GT.1 .AND. kband.EQ.1 ) THEN
298  DO 20 j = 1, n - 1
299  CALL ssyr2( cuplo, n, -e( j ), u( 1, j ), 1, u( 1, j+1 ),
300  $ 1, work, n )
301  20 CONTINUE
302  END IF
303  wnorm = slansy( '1', cuplo, n, work, n, work( n**2+1 ) )
304 *
305  ELSE IF( itype.EQ.2 ) THEN
306 *
307 * ITYPE=2: error = V S V**T - A
308 *
309  CALL slaset( 'Full', n, n, zero, zero, work, n )
310 *
311  IF( lower ) THEN
312  work( n**2 ) = d( n )
313  DO 40 j = n - 1, 1, -1
314  IF( kband.EQ.1 ) THEN
315  work( ( n+1 )*( j-1 )+2 ) = ( one-tau( j ) )*e( j )
316  DO 30 jr = j + 2, n
317  work( ( j-1 )*n+jr ) = -tau( j )*e( j )*v( jr, j )
318  30 CONTINUE
319  END IF
320 *
321  vsave = v( j+1, j )
322  v( j+1, j ) = one
323  CALL slarfy( 'L', n-j, v( j+1, j ), 1, tau( j ),
324  $ work( ( n+1 )*j+1 ), n, work( n**2+1 ) )
325  v( j+1, j ) = vsave
326  work( ( n+1 )*( j-1 )+1 ) = d( j )
327  40 CONTINUE
328  ELSE
329  work( 1 ) = d( 1 )
330  DO 60 j = 1, n - 1
331  IF( kband.EQ.1 ) THEN
332  work( ( n+1 )*j ) = ( one-tau( j ) )*e( j )
333  DO 50 jr = 1, j - 1
334  work( j*n+jr ) = -tau( j )*e( j )*v( jr, j+1 )
335  50 CONTINUE
336  END IF
337 *
338  vsave = v( j, j+1 )
339  v( j, j+1 ) = one
340  CALL slarfy( 'U', j, v( 1, j+1 ), 1, tau( j ), work, n,
341  $ work( n**2+1 ) )
342  v( j, j+1 ) = vsave
343  work( ( n+1 )*j+1 ) = d( j+1 )
344  60 CONTINUE
345  END IF
346 *
347  DO 90 jcol = 1, n
348  IF( lower ) THEN
349  DO 70 jrow = jcol, n
350  work( jrow+n*( jcol-1 ) ) = work( jrow+n*( jcol-1 ) )
351  $ - a( jrow, jcol )
352  70 CONTINUE
353  ELSE
354  DO 80 jrow = 1, jcol
355  work( jrow+n*( jcol-1 ) ) = work( jrow+n*( jcol-1 ) )
356  $ - a( jrow, jcol )
357  80 CONTINUE
358  END IF
359  90 CONTINUE
360  wnorm = slansy( '1', cuplo, n, work, n, work( n**2+1 ) )
361 *
362  ELSE IF( itype.EQ.3 ) THEN
363 *
364 * ITYPE=3: error = U V**T - I
365 *
366  IF( n.LT.2 )
367  $ RETURN
368  CALL slacpy( ' ', n, n, u, ldu, work, n )
369  IF( lower ) THEN
370  CALL sorm2r( 'R', 'T', n, n-1, n-1, v( 2, 1 ), ldv, tau,
371  $ work( n+1 ), n, work( n**2+1 ), iinfo )
372  ELSE
373  CALL sorm2l( 'R', 'T', n, n-1, n-1, v( 1, 2 ), ldv, tau,
374  $ work, n, work( n**2+1 ), iinfo )
375  END IF
376  IF( iinfo.NE.0 ) THEN
377  result( 1 ) = ten / ulp
378  RETURN
379  END IF
380 *
381  DO 100 j = 1, n
382  work( ( n+1 )*( j-1 )+1 ) = work( ( n+1 )*( j-1 )+1 ) - one
383  100 CONTINUE
384 *
385  wnorm = slange( '1', n, n, work, n, work( n**2+1 ) )
386  END IF
387 *
388  IF( anorm.GT.wnorm ) THEN
389  result( 1 ) = ( wnorm / anorm ) / ( n*ulp )
390  ELSE
391  IF( anorm.LT.one ) THEN
392  result( 1 ) = ( min( wnorm, n*anorm ) / anorm ) / ( n*ulp )
393  ELSE
394  result( 1 ) = min( wnorm / anorm, real( n ) ) / ( n*ulp )
395  END IF
396  END IF
397 *
398 * Do Test 2
399 *
400 * Compute U U**T - I
401 *
402  IF( itype.EQ.1 ) THEN
403  CALL sgemm( 'N', 'C', n, n, n, one, u, ldu, u, ldu, zero, work,
404  $ n )
405 *
406  DO 110 j = 1, n
407  work( ( n+1 )*( j-1 )+1 ) = work( ( n+1 )*( j-1 )+1 ) - one
408  110 CONTINUE
409 *
410  result( 2 ) = min( slange( '1', n, n, work, n,
411  $ work( n**2+1 ) ), real( n ) ) / ( n*ulp )
412  END IF
413 *
414  RETURN
415 *
416 * End of SSYT21
417 *
418  END
sgemm
subroutine sgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
SGEMM
Definition: sgemm.f:189
ssyr2
subroutine ssyr2(UPLO, N, ALPHA, X, INCX, Y, INCY, A, LDA)
SSYR2
Definition: ssyr2.f:149
slacpy
subroutine slacpy(UPLO, M, N, A, LDA, B, LDB)
SLACPY copies all or part of one two-dimensional array to another.
Definition: slacpy.f:105
slaset
subroutine slaset(UPLO, M, N, ALPHA, BETA, A, LDA)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition: slaset.f:112
sorm2r
subroutine sorm2r(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, INFO)
SORM2R multiplies a general matrix by the orthogonal matrix from a QR factorization determined by sge...
Definition: sorm2r.f:161
ssyr
subroutine ssyr(UPLO, N, ALPHA, X, INCX, A, LDA)
SSYR
Definition: ssyr.f:134
slarfy
subroutine slarfy(UPLO, N, V, INCV, TAU, C, LDC, WORK)
SLARFY
Definition: slarfy.f:110
sorm2l
subroutine sorm2l(SIDE, TRANS, M, N, K, A, LDA, TAU, C, LDC, WORK, INFO)
SORM2L multiplies a general matrix by the orthogonal matrix from a QL factorization determined by sge...
Definition: sorm2l.f:161
ssyt21
subroutine ssyt21(ITYPE, UPLO, N, KBAND, A, LDA, D, E, U, LDU, V, LDV, TAU, WORK, RESULT)
SSYT21
Definition: ssyt21.f:209